vrshoot

changeset 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children e7ca128b8713
files .hgignore Makefile libs/anim/anim.c libs/anim/anim.h libs/anim/config.h libs/anim/dynarr.c libs/anim/dynarr.h libs/anim/track.c libs/anim/track.h libs/assimp/3DSConverter.cpp libs/assimp/3DSHelper.h libs/assimp/3DSLoader.cpp libs/assimp/3DSLoader.h libs/assimp/ACLoader.cpp libs/assimp/ACLoader.h libs/assimp/ASELoader.cpp libs/assimp/ASELoader.h libs/assimp/ASEParser.cpp libs/assimp/ASEParser.h libs/assimp/Assimp.cpp libs/assimp/AssimpCExport.cpp libs/assimp/AssimpPCH.cpp libs/assimp/AssimpPCH.h libs/assimp/B3DImporter.cpp libs/assimp/B3DImporter.h libs/assimp/BVHLoader.cpp libs/assimp/BVHLoader.h libs/assimp/BaseImporter.cpp libs/assimp/BaseImporter.h libs/assimp/BaseProcess.cpp libs/assimp/BaseProcess.h libs/assimp/BlenderDNA.cpp libs/assimp/BlenderDNA.h libs/assimp/BlenderDNA.inl libs/assimp/BlenderIntermediate.h libs/assimp/BlenderLoader.cpp libs/assimp/BlenderLoader.h libs/assimp/BlenderModifier.cpp libs/assimp/BlenderModifier.h libs/assimp/BlenderScene.cpp libs/assimp/BlenderScene.h libs/assimp/BlenderSceneGen.h libs/assimp/BlobIOSystem.h libs/assimp/ByteSwap.h libs/assimp/CInterfaceIOWrapper.h libs/assimp/CMakeLists.txt libs/assimp/COBLoader.cpp libs/assimp/COBLoader.h libs/assimp/COBScene.h libs/assimp/CSMLoader.cpp libs/assimp/CSMLoader.h libs/assimp/CalcTangentsProcess.cpp libs/assimp/CalcTangentsProcess.h libs/assimp/ColladaExporter.cpp libs/assimp/ColladaExporter.h libs/assimp/ColladaHelper.h libs/assimp/ColladaLoader.cpp libs/assimp/ColladaLoader.h libs/assimp/ColladaParser.cpp libs/assimp/ColladaParser.h libs/assimp/ComputeUVMappingProcess.cpp libs/assimp/ComputeUVMappingProcess.h libs/assimp/ConvertToLHProcess.cpp libs/assimp/ConvertToLHProcess.h libs/assimp/ConvertUTF/ConvertUTF.c libs/assimp/ConvertUTF/ConvertUTF.h libs/assimp/DXFHelper.h libs/assimp/DXFLoader.cpp libs/assimp/DXFLoader.h libs/assimp/DeboneProcess.cpp libs/assimp/DeboneProcess.h libs/assimp/DefaultIOStream.cpp libs/assimp/DefaultIOStream.h libs/assimp/DefaultIOSystem.cpp libs/assimp/DefaultIOSystem.h libs/assimp/DefaultLogger.cpp libs/assimp/DefaultProgressHandler.h libs/assimp/Exceptional.h libs/assimp/Exporter.cpp libs/assimp/FBXAnimation.cpp libs/assimp/FBXBinaryTokenizer.cpp libs/assimp/FBXCompileConfig.h libs/assimp/FBXConverter.cpp libs/assimp/FBXConverter.h libs/assimp/FBXDeformer.cpp libs/assimp/FBXDocument.cpp libs/assimp/FBXDocument.h libs/assimp/FBXDocumentUtil.cpp libs/assimp/FBXDocumentUtil.h libs/assimp/FBXImportSettings.h libs/assimp/FBXImporter.cpp libs/assimp/FBXImporter.h libs/assimp/FBXMaterial.cpp libs/assimp/FBXMeshGeometry.cpp libs/assimp/FBXModel.cpp libs/assimp/FBXNodeAttribute.cpp libs/assimp/FBXParser.cpp libs/assimp/FBXParser.h libs/assimp/FBXProperties.cpp libs/assimp/FBXProperties.h libs/assimp/FBXTokenizer.cpp libs/assimp/FBXTokenizer.h libs/assimp/FBXUtil.cpp libs/assimp/FBXUtil.h libs/assimp/FileLogStream.h libs/assimp/FileSystemFilter.h libs/assimp/FindDegenerates.cpp libs/assimp/FindDegenerates.h libs/assimp/FindInstancesProcess.cpp libs/assimp/FindInstancesProcess.h libs/assimp/FindInvalidDataProcess.cpp libs/assimp/FindInvalidDataProcess.h libs/assimp/FixNormalsStep.cpp libs/assimp/FixNormalsStep.h libs/assimp/GenFaceNormalsProcess.cpp libs/assimp/GenFaceNormalsProcess.h libs/assimp/GenVertexNormalsProcess.cpp libs/assimp/GenVertexNormalsProcess.h libs/assimp/GenericProperty.h libs/assimp/HMPFileData.h libs/assimp/HMPLoader.cpp libs/assimp/HMPLoader.h libs/assimp/HalfLifeFileData.h libs/assimp/Hash.h libs/assimp/IFCBoolean.cpp libs/assimp/IFCCurve.cpp libs/assimp/IFCGeometry.cpp libs/assimp/IFCLoader.cpp libs/assimp/IFCLoader.h libs/assimp/IFCMaterial.cpp libs/assimp/IFCOpenings.cpp libs/assimp/IFCProfile.cpp libs/assimp/IFCReaderGen.cpp libs/assimp/IFCReaderGen.h libs/assimp/IFCUtil.cpp libs/assimp/IFCUtil.h libs/assimp/IFF.h libs/assimp/Importer.cpp libs/assimp/Importer.h libs/assimp/ImporterRegistry.cpp libs/assimp/ImproveCacheLocality.cpp libs/assimp/ImproveCacheLocality.h libs/assimp/JoinVerticesProcess.cpp libs/assimp/JoinVerticesProcess.h libs/assimp/LWOAnimation.cpp libs/assimp/LWOAnimation.h libs/assimp/LWOBLoader.cpp libs/assimp/LWOFileData.h libs/assimp/LWOLoader.cpp libs/assimp/LWOLoader.h libs/assimp/LWOMaterial.cpp libs/assimp/LWSLoader.cpp libs/assimp/LWSLoader.h libs/assimp/LimitBoneWeightsProcess.cpp libs/assimp/LimitBoneWeightsProcess.h libs/assimp/LineSplitter.h libs/assimp/LogAux.h libs/assimp/MD2FileData.h libs/assimp/MD2Loader.cpp libs/assimp/MD2Loader.h libs/assimp/MD2NormalTable.h libs/assimp/MD3FileData.h libs/assimp/MD3Loader.cpp libs/assimp/MD3Loader.h libs/assimp/MD4FileData.h libs/assimp/MD5Loader.cpp libs/assimp/MD5Loader.h libs/assimp/MD5Parser.cpp libs/assimp/MD5Parser.h libs/assimp/MDCFileData.h libs/assimp/MDCLoader.cpp libs/assimp/MDCLoader.h libs/assimp/MDCNormalTable.h libs/assimp/MDLDefaultColorMap.h libs/assimp/MDLFileData.h libs/assimp/MDLLoader.cpp libs/assimp/MDLLoader.h libs/assimp/MDLMaterialLoader.cpp libs/assimp/MS3DLoader.cpp libs/assimp/MS3DLoader.h libs/assimp/MakeVerboseFormat.cpp libs/assimp/MakeVerboseFormat.h libs/assimp/MaterialSystem.cpp libs/assimp/MaterialSystem.h libs/assimp/MemoryIOWrapper.h libs/assimp/NDOLoader.cpp libs/assimp/NDOLoader.h libs/assimp/NFFLoader.cpp libs/assimp/NFFLoader.h libs/assimp/OFFLoader.cpp libs/assimp/OFFLoader.h libs/assimp/ObjExporter.cpp libs/assimp/ObjExporter.h libs/assimp/ObjFileData.h libs/assimp/ObjFileImporter.cpp libs/assimp/ObjFileImporter.h libs/assimp/ObjFileMtlImporter.cpp libs/assimp/ObjFileMtlImporter.h libs/assimp/ObjFileParser.cpp libs/assimp/ObjFileParser.h libs/assimp/ObjTools.h libs/assimp/OgreImporter.cpp libs/assimp/OgreImporter.hpp libs/assimp/OgreMaterial.cpp libs/assimp/OgreMesh.cpp libs/assimp/OgreSkeleton.cpp libs/assimp/OgreXmlHelper.hpp libs/assimp/OptimizeGraph.cpp libs/assimp/OptimizeGraph.h libs/assimp/OptimizeMeshes.cpp libs/assimp/OptimizeMeshes.h libs/assimp/ParsingUtils.h libs/assimp/PlyExporter.cpp libs/assimp/PlyExporter.h libs/assimp/PlyLoader.cpp libs/assimp/PlyLoader.h libs/assimp/PlyParser.cpp libs/assimp/PlyParser.h libs/assimp/PolyTools.h libs/assimp/PostStepRegistry.cpp libs/assimp/PretransformVertices.cpp libs/assimp/PretransformVertices.h libs/assimp/ProcessHelper.cpp libs/assimp/ProcessHelper.h libs/assimp/Profiler.h libs/assimp/Q3BSPFileData.h libs/assimp/Q3BSPFileImporter.cpp libs/assimp/Q3BSPFileImporter.h libs/assimp/Q3BSPFileParser.cpp libs/assimp/Q3BSPFileParser.h libs/assimp/Q3BSPZipArchive.cpp libs/assimp/Q3BSPZipArchive.h libs/assimp/Q3DLoader.cpp libs/assimp/Q3DLoader.h libs/assimp/RawLoader.cpp libs/assimp/RawLoader.h libs/assimp/RemoveComments.cpp libs/assimp/RemoveComments.h libs/assimp/RemoveRedundantMaterials.cpp libs/assimp/RemoveRedundantMaterials.h libs/assimp/RemoveVCProcess.cpp libs/assimp/RemoveVCProcess.h libs/assimp/SGSpatialSort.cpp libs/assimp/SGSpatialSort.h libs/assimp/SMDLoader.cpp libs/assimp/SMDLoader.h libs/assimp/STLExporter.cpp libs/assimp/STLExporter.h libs/assimp/STLLoader.cpp libs/assimp/STLLoader.h libs/assimp/SceneCombiner.cpp libs/assimp/SceneCombiner.h libs/assimp/ScenePreprocessor.cpp libs/assimp/ScenePreprocessor.h libs/assimp/ScenePrivate.h libs/assimp/SkeletonMeshBuilder.cpp libs/assimp/SkeletonMeshBuilder.h libs/assimp/SmoothingGroups.h libs/assimp/SmoothingGroups.inl libs/assimp/SortByPTypeProcess.cpp libs/assimp/SortByPTypeProcess.h libs/assimp/SpatialSort.cpp libs/assimp/SpatialSort.h libs/assimp/SplitByBoneCountProcess.cpp libs/assimp/SplitByBoneCountProcess.h libs/assimp/SplitLargeMeshes.cpp libs/assimp/SplitLargeMeshes.h libs/assimp/StandardShapes.cpp libs/assimp/StandardShapes.h libs/assimp/StdOStreamLogStream.h libs/assimp/StreamReader.h libs/assimp/StringComparison.h libs/assimp/Subdivision.cpp libs/assimp/Subdivision.h libs/assimp/TargetAnimation.cpp libs/assimp/TargetAnimation.h libs/assimp/TerragenLoader.cpp libs/assimp/TerragenLoader.h libs/assimp/TextureTransform.cpp libs/assimp/TextureTransform.h libs/assimp/TinyFormatter.h libs/assimp/TriangulateProcess.cpp libs/assimp/TriangulateProcess.h libs/assimp/UnrealLoader.cpp libs/assimp/UnrealLoader.h libs/assimp/ValidateDataStructure.cpp libs/assimp/ValidateDataStructure.h libs/assimp/Vertex.h libs/assimp/VertexTriangleAdjacency.cpp libs/assimp/VertexTriangleAdjacency.h libs/assimp/Win32DebugLogStream.h libs/assimp/XFileHelper.h libs/assimp/XFileImporter.cpp libs/assimp/XFileImporter.h libs/assimp/XFileParser.cpp libs/assimp/XFileParser.h libs/assimp/XGLLoader.cpp libs/assimp/XGLLoader.h libs/assimp/assbin_chunks.h libs/assimp/assimp/Compiler/poppack1.h libs/assimp/assimp/Compiler/pushpack1.h libs/assimp/assimp/DefaultLogger.hpp libs/assimp/assimp/Exporter.hpp libs/assimp/assimp/IOStream.hpp libs/assimp/assimp/IOSystem.hpp libs/assimp/assimp/Importer.hpp libs/assimp/assimp/LogStream.hpp libs/assimp/assimp/Logger.hpp libs/assimp/assimp/NullLogger.hpp libs/assimp/assimp/ProgressHandler.hpp libs/assimp/assimp/ai_assert.h libs/assimp/assimp/anim.h libs/assimp/assimp/camera.h libs/assimp/assimp/cexport.h libs/assimp/assimp/cfileio.h libs/assimp/assimp/cimport.h libs/assimp/assimp/color4.h libs/assimp/assimp/color4.inl libs/assimp/assimp/config.h libs/assimp/assimp/defs.h libs/assimp/assimp/importerdesc.h libs/assimp/assimp/light.h libs/assimp/assimp/material.h libs/assimp/assimp/material.inl libs/assimp/assimp/matrix3x3.h libs/assimp/assimp/matrix3x3.inl libs/assimp/assimp/matrix4x4.h libs/assimp/assimp/matrix4x4.inl libs/assimp/assimp/mesh.h libs/assimp/assimp/metadata.h libs/assimp/assimp/postprocess.h libs/assimp/assimp/quaternion.h libs/assimp/assimp/quaternion.inl libs/assimp/assimp/scene.h libs/assimp/assimp/texture.h libs/assimp/assimp/types.h libs/assimp/assimp/vector2.h libs/assimp/assimp/vector2.inl libs/assimp/assimp/vector3.h libs/assimp/assimp/vector3.inl libs/assimp/assimp/version.h libs/assimp/boost/LICENSE_1_0.txt libs/assimp/boost/foreach.hpp libs/assimp/boost/format.hpp libs/assimp/boost/lexical_cast.hpp libs/assimp/boost/make_shared.hpp libs/assimp/boost/math/common_factor_rt.hpp libs/assimp/boost/noncopyable.hpp libs/assimp/boost/pointer_cast.hpp libs/assimp/boost/scoped_array.hpp libs/assimp/boost/scoped_ptr.hpp libs/assimp/boost/shared_array.hpp libs/assimp/boost/shared_ptr.hpp libs/assimp/boost/static_assert.hpp libs/assimp/boost/timer.hpp libs/assimp/boost/tuple/tuple.hpp libs/assimp/fast_atof.h libs/assimp/irrXML/CXMLReaderImpl.h libs/assimp/irrXML/heapsort.h libs/assimp/irrXML/irrArray.h libs/assimp/irrXML/irrString.h libs/assimp/irrXML/irrTypes.h libs/assimp/irrXML/irrXML.cpp libs/assimp/irrXML/irrXML.h libs/assimp/irrXMLWrapper.h libs/assimp/pstdint.h libs/assimp/qnan.h libs/assimp/revision.h libs/drawtext/drawgl.c libs/drawtext/drawtext.h libs/drawtext/drawtext_impl.h libs/drawtext/font.c libs/drawtext/utf8.c libs/ft2static/freetype/config/ftconfig.h libs/ft2static/freetype/config/ftheader.h libs/ft2static/freetype/config/ftmodule.h libs/ft2static/freetype/config/ftoption.h libs/ft2static/freetype/config/ftstdlib.h libs/ft2static/freetype/freetype.h libs/ft2static/freetype/ftadvanc.h libs/ft2static/freetype/ftbbox.h libs/ft2static/freetype/ftbdf.h libs/ft2static/freetype/ftbitmap.h libs/ft2static/freetype/ftcache.h libs/ft2static/freetype/ftchapters.h libs/ft2static/freetype/ftcid.h libs/ft2static/freetype/fterrdef.h libs/ft2static/freetype/fterrors.h libs/ft2static/freetype/ftgasp.h libs/ft2static/freetype/ftglyph.h libs/ft2static/freetype/ftgxval.h libs/ft2static/freetype/ftgzip.h libs/ft2static/freetype/ftimage.h libs/ft2static/freetype/ftincrem.h libs/ft2static/freetype/ftlcdfil.h libs/ft2static/freetype/ftlist.h libs/ft2static/freetype/ftlzw.h libs/ft2static/freetype/ftmac.h libs/ft2static/freetype/ftmm.h libs/ft2static/freetype/ftmodapi.h libs/ft2static/freetype/ftmoderr.h libs/ft2static/freetype/ftotval.h libs/ft2static/freetype/ftoutln.h libs/ft2static/freetype/ftpfr.h libs/ft2static/freetype/ftrender.h libs/ft2static/freetype/ftsizes.h libs/ft2static/freetype/ftsnames.h libs/ft2static/freetype/ftstroke.h libs/ft2static/freetype/ftsynth.h libs/ft2static/freetype/ftsystem.h libs/ft2static/freetype/fttrigon.h libs/ft2static/freetype/fttypes.h libs/ft2static/freetype/ftwinfnt.h libs/ft2static/freetype/ftxf86.h libs/ft2static/freetype/internal/autohint.h libs/ft2static/freetype/internal/ftcalc.h libs/ft2static/freetype/internal/ftdebug.h libs/ft2static/freetype/internal/ftdriver.h libs/ft2static/freetype/internal/ftgloadr.h libs/ft2static/freetype/internal/ftmemory.h libs/ft2static/freetype/internal/ftobjs.h libs/ft2static/freetype/internal/ftpic.h libs/ft2static/freetype/internal/ftrfork.h libs/ft2static/freetype/internal/ftserv.h libs/ft2static/freetype/internal/ftstream.h libs/ft2static/freetype/internal/fttrace.h libs/ft2static/freetype/internal/ftvalid.h libs/ft2static/freetype/internal/internal.h libs/ft2static/freetype/internal/pcftypes.h libs/ft2static/freetype/internal/psaux.h libs/ft2static/freetype/internal/pshints.h libs/ft2static/freetype/internal/services/svbdf.h libs/ft2static/freetype/internal/services/svcid.h libs/ft2static/freetype/internal/services/svgldict.h libs/ft2static/freetype/internal/services/svgxval.h libs/ft2static/freetype/internal/services/svkern.h libs/ft2static/freetype/internal/services/svmm.h libs/ft2static/freetype/internal/services/svotval.h libs/ft2static/freetype/internal/services/svpfr.h libs/ft2static/freetype/internal/services/svpostnm.h libs/ft2static/freetype/internal/services/svpscmap.h libs/ft2static/freetype/internal/services/svpsinfo.h libs/ft2static/freetype/internal/services/svsfnt.h libs/ft2static/freetype/internal/services/svttcmap.h libs/ft2static/freetype/internal/services/svtteng.h libs/ft2static/freetype/internal/services/svttglyf.h libs/ft2static/freetype/internal/services/svwinfnt.h libs/ft2static/freetype/internal/services/svxf86nm.h libs/ft2static/freetype/internal/sfnt.h libs/ft2static/freetype/internal/t1types.h libs/ft2static/freetype/internal/tttypes.h libs/ft2static/freetype/t1tables.h libs/ft2static/freetype/ttnameid.h libs/ft2static/freetype/tttables.h libs/ft2static/freetype/tttags.h libs/ft2static/freetype/ttunpat.h libs/ft2static/ft2build.h libs/ft2static/libFreetype2.a libs/imago/conv.c libs/imago/file_jpeg.c libs/imago/file_png.c libs/imago/file_ppm.c libs/imago/file_rgbe.c libs/imago/ftype_module.c libs/imago/ftype_module.h libs/imago/imago2.c libs/imago/imago2.h libs/imago/imago_gl.c libs/imago/modules.c libs/kissfft/COPYING libs/kissfft/README libs/kissfft/_kiss_fft_guts.h libs/kissfft/kiss_fft.c libs/kissfft/kiss_fft.h libs/kissfft/kiss_fftr.c libs/kissfft/kiss_fftr.h libs/libjpeg/README libs/libjpeg/cderror.h libs/libjpeg/jcapimin.c libs/libjpeg/jcapistd.c libs/libjpeg/jccoefct.c libs/libjpeg/jccolor.c libs/libjpeg/jcdctmgr.c libs/libjpeg/jchuff.c libs/libjpeg/jchuff.h libs/libjpeg/jcinit.c libs/libjpeg/jcmainct.c libs/libjpeg/jcmarker.c libs/libjpeg/jcmaster.c libs/libjpeg/jcomapi.c libs/libjpeg/jconfig.h libs/libjpeg/jcparam.c libs/libjpeg/jcphuff.c libs/libjpeg/jcprepct.c libs/libjpeg/jcsample.c libs/libjpeg/jctrans.c libs/libjpeg/jdapimin.c libs/libjpeg/jdapistd.c libs/libjpeg/jdatadst.c libs/libjpeg/jdatasrc.c libs/libjpeg/jdcoefct.c libs/libjpeg/jdcolor.c libs/libjpeg/jdct.h libs/libjpeg/jddctmgr.c libs/libjpeg/jdhuff.c libs/libjpeg/jdhuff.h libs/libjpeg/jdinput.c libs/libjpeg/jdmainct.c libs/libjpeg/jdmarker.c libs/libjpeg/jdmaster.c libs/libjpeg/jdmerge.c libs/libjpeg/jdphuff.c libs/libjpeg/jdpostct.c libs/libjpeg/jdsample.c libs/libjpeg/jdtrans.c libs/libjpeg/jerror.c libs/libjpeg/jerror.h libs/libjpeg/jfdctflt.c libs/libjpeg/jfdctfst.c libs/libjpeg/jfdctint.c libs/libjpeg/jidctflt.c libs/libjpeg/jidctfst.c libs/libjpeg/jidctint.c libs/libjpeg/jidctred.c libs/libjpeg/jinclude.h libs/libjpeg/jmemmgr.c libs/libjpeg/jmemnobs.c libs/libjpeg/jmemsys.h libs/libjpeg/jmorecfg.h libs/libjpeg/jpegint.h libs/libjpeg/jpeglib.h libs/libjpeg/jquant1.c libs/libjpeg/jquant2.c libs/libjpeg/jutils.c libs/libjpeg/jversion.h libs/libpng/LICENSE libs/libpng/png.c libs/libpng/png.h libs/libpng/pngconf.h libs/libpng/pngerror.c libs/libpng/pnggccrd.c libs/libpng/pngget.c libs/libpng/pngmem.c libs/libpng/pngpread.c libs/libpng/pngread.c libs/libpng/pngrio.c libs/libpng/pngrtran.c libs/libpng/pngrutil.c libs/libpng/pngset.c libs/libpng/pngtrans.c libs/libpng/pngvcrd.c libs/libpng/pngwio.c libs/libpng/pngwrite.c libs/libpng/pngwtran.c libs/libpng/pngwutil.c libs/ogg/AUTHORS libs/ogg/COPYING libs/ogg/bitwise.c libs/ogg/framing.c libs/ogg/ogg.h libs/ogg/os_types.h libs/psys/pattr.c libs/psys/pattr.h libs/psys/pstrack.c libs/psys/pstrack.h libs/psys/psys.c libs/psys/psys.h libs/psys/rndval.c libs/psys/rndval.h libs/vmath/basis.cc libs/vmath/basis.h libs/vmath/basis_c.c libs/vmath/geom.c libs/vmath/geom.h libs/vmath/matrix.cc libs/vmath/matrix.h libs/vmath/matrix.inl libs/vmath/matrix_c.c libs/vmath/quat.cc libs/vmath/quat.h libs/vmath/quat.inl libs/vmath/quat_c.c libs/vmath/ray.cc libs/vmath/ray.h libs/vmath/ray.inl libs/vmath/ray_c.c libs/vmath/sphvec.cc libs/vmath/sphvec.h libs/vmath/vector.cc libs/vmath/vector.h libs/vmath/vector.inl libs/vmath/vmath.c libs/vmath/vmath.h libs/vmath/vmath.inl libs/vmath/vmath_config.h libs/vmath/vmath_types.h libs/vorbis/AUTHORS libs/vorbis/COPYING libs/vorbis/analysis.c libs/vorbis/backends.h libs/vorbis/bitrate.c libs/vorbis/bitrate.h libs/vorbis/block.c libs/vorbis/books/coupled/res_books_51.h libs/vorbis/books/coupled/res_books_stereo.h libs/vorbis/books/floor/floor_books.h libs/vorbis/books/uncoupled/res_books_uncoupled.h libs/vorbis/codebook.c libs/vorbis/codebook.h libs/vorbis/codec.h libs/vorbis/codec_internal.h libs/vorbis/envelope.c libs/vorbis/envelope.h libs/vorbis/floor0.c libs/vorbis/floor1.c libs/vorbis/highlevel.h libs/vorbis/info.c libs/vorbis/lookup.c libs/vorbis/lookup.h libs/vorbis/lookup_data.h libs/vorbis/lpc.c libs/vorbis/lpc.h libs/vorbis/lsp.c libs/vorbis/lsp.h libs/vorbis/mapping0.c libs/vorbis/masking.h libs/vorbis/mdct.c libs/vorbis/mdct.h libs/vorbis/misc.h libs/vorbis/modes/floor_all.h libs/vorbis/modes/psych_11.h libs/vorbis/modes/psych_16.h libs/vorbis/modes/psych_44.h libs/vorbis/modes/psych_8.h libs/vorbis/modes/residue_16.h libs/vorbis/modes/residue_44.h libs/vorbis/modes/residue_44p51.h libs/vorbis/modes/residue_44u.h libs/vorbis/modes/residue_8.h libs/vorbis/modes/setup_11.h libs/vorbis/modes/setup_16.h libs/vorbis/modes/setup_22.h libs/vorbis/modes/setup_32.h libs/vorbis/modes/setup_44.h libs/vorbis/modes/setup_44p51.h libs/vorbis/modes/setup_44u.h libs/vorbis/modes/setup_8.h libs/vorbis/modes/setup_X.h libs/vorbis/os.h libs/vorbis/psy.c libs/vorbis/psy.h libs/vorbis/registry.c libs/vorbis/registry.h libs/vorbis/res0.c libs/vorbis/scales.h libs/vorbis/sharedbook.c libs/vorbis/smallft.c libs/vorbis/smallft.h libs/vorbis/synthesis.c libs/vorbis/vorbisenc.c libs/vorbis/vorbisenc.h libs/vorbis/vorbisfile.c libs/vorbis/vorbisfile.h libs/vorbis/window.c libs/vorbis/window.h libs/zlib/LICENSE libs/zlib/adler32.c libs/zlib/compress.c libs/zlib/crc32.c libs/zlib/crc32.h libs/zlib/deflate.c libs/zlib/deflate.h libs/zlib/gzio.c libs/zlib/infback.c libs/zlib/inffast.c libs/zlib/inffast.h libs/zlib/inffixed.h libs/zlib/inflate.c libs/zlib/inflate.h libs/zlib/inftrees.c libs/zlib/inftrees.h libs/zlib/trees.c libs/zlib/trees.h libs/zlib/uncompr.c libs/zlib/zconf.h libs/zlib/zlib.h libs/zlib/zutil.c libs/zlib/zutil.h sdr/color.p.glsl sdr/color.v.glsl sdr/default.p.glsl sdr/default.v.glsl sdr/font.p.glsl sdr/font.v.glsl src/assload.cc src/assload.h src/audio/audio.cc src/audio/audio.h src/audio/openal.h src/audio/ovstream.cc src/audio/ovstream.h src/audio/stream.cc src/audio/stream.h src/curve.cc src/curve.h src/datapath.cc src/datapath.h src/dataset.h src/dataset.inl src/enemy.cc src/enemy.h src/game.cc src/game.h src/geom.cc src/geom.h src/gfxutil.cc src/gfxutil.h src/image.cc src/image.h src/input.cc src/input.h src/ios/app_delegate.h src/ios/app_delegate.m src/ios/glview.h src/ios/glview.mm src/ios/main.m src/level.cc src/level.h src/logger.cc src/logger.h src/main_glut.cc src/material.cc src/material.h src/mesh.cc src/mesh.h src/meshgen.cc src/meshgen.h src/object.cc src/object.h src/opengl.cc src/opengl.h src/psyspp.cc src/psyspp.h src/scene.cc src/scene.h src/scr_debug.cc src/scr_debug.h src/scr_game.cc src/scr_game.h src/scr_overlay.cc src/scr_overlay.h src/screen.cc src/screen.h src/sdrman.cc src/sdrman.h src/shader.cc src/shader.h src/texgen.cc src/texgen.h src/texman.cc src/texman.h src/texture.cc src/texture.h src/timer.cc src/timer.h src/unistate.cc src/unistate.h src/vccompat/stdint.h src/xform_node.cc src/xform_node.h
diffstat 770 files changed, 316239 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,3 @@
     1.4 +\.o$
     1.5 +\.d$
     1.6 +\.swp$
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/Makefile	Sat Feb 01 19:58:19 2014 +0200
     2.3 @@ -0,0 +1,60 @@
     2.4 +csrc = $(wildcard src/*.c) \
     2.5 +	   $(wildcard libs/vmath/*.c) \
     2.6 +	   $(wildcard libs/anim/*.c) \
     2.7 +	   $(wildcard libs/imago/*.c) \
     2.8 +	   $(wildcard libs/drawtext/*.c) \
     2.9 +	   $(wildcard libs/ogg/*.c) \
    2.10 +	   $(wildcard libs/vorbis/*.c) \
    2.11 +	   $(wildcard libs/psys/*.c) \
    2.12 +	   $(wildcard libs/kissfft/*.c)
    2.13 +
    2.14 +ccsrc = $(wildcard src/*.cc) \
    2.15 +		$(wildcard src/audio/*.cc) \
    2.16 +		$(wildcard libs/vmath/*.cc)
    2.17 +
    2.18 +obj = $(ccsrc:.cc=.o) $(csrc:.c=.o)
    2.19 +dep = $(obj:.o=.d)
    2.20 +bin = candyshoot
    2.21 +
    2.22 +USE_ASSIMP = true
    2.23 +
    2.24 +ifeq ($(USE_ASSIMP), true)
    2.25 +	libs_cflags_ai = `pkg-config --cflags assimp` -DUSE_ASSIMP
    2.26 +	libs_ldflags_ai = `pkg-config --libs assimp`
    2.27 +endif
    2.28 +
    2.29 +libs_cflags = -Isrc -Ilibs -Ilibs/imago -Ilibs/drawtext -Ilibs/vorbis -Ilibs/kissfft \
    2.30 +			  `pkg-config --cflags freetype2` $(libs_cflags_ai)
    2.31 +libs_ldflags = -lz -lpng -ljpeg `pkg-config --libs freetype2` \
    2.32 +			   $(libs_ldflags_ai)
    2.33 +
    2.34 +
    2.35 +CC = clang
    2.36 +CXX = clang++
    2.37 +CFLAGS = -pedantic -Wall -g $(libs_cflags)
    2.38 +CXXFLAGS = $(CFLAGS)
    2.39 +LDFLAGS = $(libgl) $(libal) -lpthread -lm -ldl $(libs_ldflags)
    2.40 +
    2.41 +ifeq ($(shell uname -s), Darwin)
    2.42 +	libgl = -framework OpenGL -framework GLUT -lGLEW
    2.43 +	libal = -framework OpenAL
    2.44 +else
    2.45 +	libgl = -lGL -lGLU -lglut -lGLEW
    2.46 +	libal = -lopenal
    2.47 +endif
    2.48 +
    2.49 +
    2.50 +$(bin): $(obj)
    2.51 +	$(CXX) -o $@ $(obj) $(LDFLAGS)
    2.52 +
    2.53 +-include $(dep)
    2.54 +
    2.55 +%.d: %.c
    2.56 +	@$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
    2.57 +
    2.58 +%.d: %.cc
    2.59 +	@$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@
    2.60 +
    2.61 +.PHONY: clean
    2.62 +clean:
    2.63 +	rm -f $(obj) $(bin)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/libs/anim/anim.c	Sat Feb 01 19:58:19 2014 +0200
     3.3 @@ -0,0 +1,532 @@
     3.4 +#include <stdlib.h>
     3.5 +#include <limits.h>
     3.6 +#include <assert.h>
     3.7 +#include "anim.h"
     3.8 +#include "dynarr.h"
     3.9 +
    3.10 +#define ROT_USE_SLERP
    3.11 +
    3.12 +static void invalidate_cache(struct anm_node *node);
    3.13 +
    3.14 +int anm_init_node(struct anm_node *node)
    3.15 +{
    3.16 +	int i, j;
    3.17 +	static const float defaults[] = {
    3.18 +		0.0f, 0.0f, 0.0f,		/* default position */
    3.19 +		0.0f, 0.0f, 0.0f, 1.0f,	/* default rotation quat */
    3.20 +		1.0f, 1.0f, 1.0f		/* default scale factor */
    3.21 +	};
    3.22 +
    3.23 +	memset(node, 0, sizeof *node);
    3.24 +
    3.25 +	/* initialize thread-local matrix cache */
    3.26 +	pthread_key_create(&node->cache_key, 0);
    3.27 +	pthread_mutex_init(&node->cache_list_lock, 0);
    3.28 +
    3.29 +	for(i=0; i<ANM_NUM_TRACKS; i++) {
    3.30 +		if(anm_init_track(node->tracks + i) == -1) {
    3.31 +			for(j=0; j<i; j++) {
    3.32 +				anm_destroy_track(node->tracks + i);
    3.33 +			}
    3.34 +		}
    3.35 +		anm_set_track_default(node->tracks + i, defaults[i]);
    3.36 +	}
    3.37 +	return 0;
    3.38 +}
    3.39 +
    3.40 +void anm_destroy_node(struct anm_node *node)
    3.41 +{
    3.42 +	int i;
    3.43 +	free(node->name);
    3.44 +
    3.45 +	for(i=0; i<ANM_NUM_TRACKS; i++) {
    3.46 +		anm_destroy_track(node->tracks + i);
    3.47 +	}
    3.48 +
    3.49 +	/* destroy thread-specific cache */
    3.50 +	pthread_key_delete(node->cache_key);
    3.51 +
    3.52 +	while(node->cache_list) {
    3.53 +		struct mat_cache *tmp = node->cache_list;
    3.54 +		node->cache_list = tmp->next;
    3.55 +		free(tmp);
    3.56 +	}
    3.57 +}
    3.58 +
    3.59 +void anm_destroy_node_tree(struct anm_node *tree)
    3.60 +{
    3.61 +	struct anm_node *c, *tmp;
    3.62 +
    3.63 +	if(!tree) return;
    3.64 +
    3.65 +	c = tree->child;
    3.66 +	while(c) {
    3.67 +		tmp = c;
    3.68 +		c = c->next;
    3.69 +
    3.70 +		anm_destroy_node_tree(tmp);
    3.71 +	}
    3.72 +	anm_destroy_node(tree);
    3.73 +}
    3.74 +
    3.75 +struct anm_node *anm_create_node(void)
    3.76 +{
    3.77 +	struct anm_node *n;
    3.78 +
    3.79 +	if((n = malloc(sizeof *n))) {
    3.80 +		if(anm_init_node(n) == -1) {
    3.81 +			free(n);
    3.82 +			return 0;
    3.83 +		}
    3.84 +	}
    3.85 +	return n;
    3.86 +}
    3.87 +
    3.88 +void anm_free_node(struct anm_node *node)
    3.89 +{
    3.90 +	anm_destroy_node(node);
    3.91 +	free(node);
    3.92 +}
    3.93 +
    3.94 +void anm_free_node_tree(struct anm_node *tree)
    3.95 +{
    3.96 +	struct anm_node *c, *tmp;
    3.97 +
    3.98 +	if(!tree) return;
    3.99 +
   3.100 +	c = tree->child;
   3.101 +	while(c) {
   3.102 +		tmp = c;
   3.103 +		c = c->next;
   3.104 +
   3.105 +		anm_free_node_tree(tmp);
   3.106 +	}
   3.107 +
   3.108 +	anm_free_node(tree);
   3.109 +}
   3.110 +
   3.111 +int anm_set_node_name(struct anm_node *node, const char *name)
   3.112 +{
   3.113 +	char *str;
   3.114 +
   3.115 +	if(!(str = malloc(strlen(name) + 1))) {
   3.116 +		return -1;
   3.117 +	}
   3.118 +	strcpy(str, name);
   3.119 +	free(node->name);
   3.120 +	node->name = str;
   3.121 +	return 0;
   3.122 +}
   3.123 +
   3.124 +const char *anm_get_node_name(struct anm_node *node)
   3.125 +{
   3.126 +	return node->name ? node->name : "";
   3.127 +}
   3.128 +
   3.129 +void anm_set_interpolator(struct anm_node *node, enum anm_interpolator in)
   3.130 +{
   3.131 +	int i;
   3.132 +
   3.133 +	for(i=0; i<ANM_NUM_TRACKS; i++) {
   3.134 +		anm_set_track_interpolator(node->tracks + i, in);
   3.135 +	}
   3.136 +	invalidate_cache(node);
   3.137 +}
   3.138 +
   3.139 +void anm_set_extrapolator(struct anm_node *node, enum anm_extrapolator ex)
   3.140 +{
   3.141 +	int i;
   3.142 +
   3.143 +	for(i=0; i<ANM_NUM_TRACKS; i++) {
   3.144 +		anm_set_track_extrapolator(node->tracks + i, ex);
   3.145 +	}
   3.146 +	invalidate_cache(node);
   3.147 +}
   3.148 +
   3.149 +void anm_link_node(struct anm_node *p, struct anm_node *c)
   3.150 +{
   3.151 +	c->next = p->child;
   3.152 +	p->child = c;
   3.153 +
   3.154 +	c->parent = p;
   3.155 +	invalidate_cache(c);
   3.156 +}
   3.157 +
   3.158 +int anm_unlink_node(struct anm_node *p, struct anm_node *c)
   3.159 +{
   3.160 +	struct anm_node *iter;
   3.161 +
   3.162 +	if(p->child == c) {
   3.163 +		p->child = c->next;
   3.164 +		c->next = 0;
   3.165 +		invalidate_cache(c);
   3.166 +		return 0;
   3.167 +	}
   3.168 +
   3.169 +	iter = p->child;
   3.170 +	while(iter->next) {
   3.171 +		if(iter->next == c) {
   3.172 +			iter->next = c->next;
   3.173 +			c->next = 0;
   3.174 +			invalidate_cache(c);
   3.175 +			return 0;
   3.176 +		}
   3.177 +	}
   3.178 +	return -1;
   3.179 +}
   3.180 +
   3.181 +void anm_clear(struct anm_node *node)
   3.182 +{
   3.183 +	int i;
   3.184 +
   3.185 +	for(i=0; i<ANM_NUM_TRACKS; i++) {
   3.186 +		anm_clear_track(&node->tracks[i]);
   3.187 +	}
   3.188 +	invalidate_cache(node);
   3.189 +}
   3.190 +
   3.191 +void anm_set_position(struct anm_node *node, vec3_t pos, anm_time_t tm)
   3.192 +{
   3.193 +	anm_set_value(node->tracks + ANM_TRACK_POS_X, tm, pos.x);
   3.194 +	anm_set_value(node->tracks + ANM_TRACK_POS_Y, tm, pos.y);
   3.195 +	anm_set_value(node->tracks + ANM_TRACK_POS_Z, tm, pos.z);
   3.196 +	invalidate_cache(node);
   3.197 +}
   3.198 +
   3.199 +vec3_t anm_get_node_position(struct anm_node *node, anm_time_t tm)
   3.200 +{
   3.201 +	vec3_t v;
   3.202 +	v.x = anm_get_value(node->tracks + ANM_TRACK_POS_X, tm);
   3.203 +	v.y = anm_get_value(node->tracks + ANM_TRACK_POS_Y, tm);
   3.204 +	v.z = anm_get_value(node->tracks + ANM_TRACK_POS_Z, tm);
   3.205 +	return v;
   3.206 +}
   3.207 +
   3.208 +void anm_set_rotation(struct anm_node *node, quat_t rot, anm_time_t tm)
   3.209 +{
   3.210 +	anm_set_value(node->tracks + ANM_TRACK_ROT_X, tm, rot.x);
   3.211 +	anm_set_value(node->tracks + ANM_TRACK_ROT_Y, tm, rot.y);
   3.212 +	anm_set_value(node->tracks + ANM_TRACK_ROT_Z, tm, rot.z);
   3.213 +	anm_set_value(node->tracks + ANM_TRACK_ROT_W, tm, rot.w);
   3.214 +	invalidate_cache(node);
   3.215 +}
   3.216 +
   3.217 +quat_t anm_get_node_rotation(struct anm_node *node, anm_time_t tm)
   3.218 +{
   3.219 +#ifndef ROT_USE_SLERP
   3.220 +	quat_t q;
   3.221 +	q.x = anm_get_value(node->tracks + ANM_TRACK_ROT_X, tm);
   3.222 +	q.y = anm_get_value(node->tracks + ANM_TRACK_ROT_Y, tm);
   3.223 +	q.z = anm_get_value(node->tracks + ANM_TRACK_ROT_Z, tm);
   3.224 +	q.w = anm_get_value(node->tracks + ANM_TRACK_ROT_W, tm);
   3.225 +	return q;
   3.226 +#else
   3.227 +	int idx0, idx1, last_idx;
   3.228 +	anm_time_t tstart, tend;
   3.229 +	float t, dt;
   3.230 +	struct anm_track *track_x, *track_y, *track_z, *track_w;
   3.231 +	quat_t q, q1, q2;
   3.232 +
   3.233 +	track_x = node->tracks + ANM_TRACK_ROT_X;
   3.234 +	track_y = node->tracks + ANM_TRACK_ROT_Y;
   3.235 +	track_z = node->tracks + ANM_TRACK_ROT_Z;
   3.236 +	track_w = node->tracks + ANM_TRACK_ROT_W;
   3.237 +
   3.238 +	if(!track_x->count) {
   3.239 +		q.x = track_x->def_val;
   3.240 +		q.y = track_y->def_val;
   3.241 +		q.z = track_z->def_val;
   3.242 +		q.w = track_w->def_val;
   3.243 +		return q;
   3.244 +	}
   3.245 +
   3.246 +	last_idx = track_x->count - 1;
   3.247 +
   3.248 +	tstart = track_x->keys[0].time;
   3.249 +	tend = track_x->keys[last_idx].time;
   3.250 +
   3.251 +	if(tstart == tend) {
   3.252 +		q.x = track_x->keys[0].val;
   3.253 +		q.y = track_y->keys[0].val;
   3.254 +		q.z = track_z->keys[0].val;
   3.255 +		q.w = track_w->keys[0].val;
   3.256 +		return q;
   3.257 +	}
   3.258 +
   3.259 +	tm = anm_remap_time(track_x, tm, tstart, tend);
   3.260 +
   3.261 +	idx0 = anm_get_key_interval(track_x, tm);
   3.262 +	assert(idx0 >= 0 && idx0 < track_x->count);
   3.263 +	idx1 = idx0 + 1;
   3.264 +
   3.265 +	if(idx0 == last_idx) {
   3.266 +		q.x = track_x->keys[idx0].val;
   3.267 +		q.y = track_y->keys[idx0].val;
   3.268 +		q.z = track_z->keys[idx0].val;
   3.269 +		q.w = track_w->keys[idx0].val;
   3.270 +		return q;
   3.271 +	}
   3.272 +
   3.273 +	dt = (float)(track_x->keys[idx1].time - track_x->keys[idx0].time);
   3.274 +	t = (float)(tm - track_x->keys[idx0].time) / dt;
   3.275 +
   3.276 +	q1.x = track_x->keys[idx0].val;
   3.277 +	q1.y = track_y->keys[idx0].val;
   3.278 +	q1.z = track_z->keys[idx0].val;
   3.279 +	q1.w = track_w->keys[idx0].val;
   3.280 +
   3.281 +	q2.x = track_x->keys[idx1].val;
   3.282 +	q2.y = track_y->keys[idx1].val;
   3.283 +	q2.z = track_z->keys[idx1].val;
   3.284 +	q2.w = track_w->keys[idx1].val;
   3.285 +
   3.286 +	/*q1 = quat_normalize(q1);
   3.287 +	q2 = quat_normalize(q2);*/
   3.288 +
   3.289 +	return quat_slerp(q1, q2, t);
   3.290 +#endif
   3.291 +}
   3.292 +
   3.293 +void anm_set_scaling(struct anm_node *node, vec3_t scl, anm_time_t tm)
   3.294 +{
   3.295 +	anm_set_value(node->tracks + ANM_TRACK_SCL_X, tm, scl.x);
   3.296 +	anm_set_value(node->tracks + ANM_TRACK_SCL_Y, tm, scl.y);
   3.297 +	anm_set_value(node->tracks + ANM_TRACK_SCL_Z, tm, scl.z);
   3.298 +	invalidate_cache(node);
   3.299 +}
   3.300 +
   3.301 +vec3_t anm_get_node_scaling(struct anm_node *node, anm_time_t tm)
   3.302 +{
   3.303 +	vec3_t v;
   3.304 +	v.x = anm_get_value(node->tracks + ANM_TRACK_SCL_X, tm);
   3.305 +	v.y = anm_get_value(node->tracks + ANM_TRACK_SCL_Y, tm);
   3.306 +	v.z = anm_get_value(node->tracks + ANM_TRACK_SCL_Z, tm);
   3.307 +	return v;
   3.308 +}
   3.309 +
   3.310 +
   3.311 +vec3_t anm_get_position(struct anm_node *node, anm_time_t tm)
   3.312 +{
   3.313 +	mat4_t xform;
   3.314 +	vec3_t pos = {0.0, 0.0, 0.0};
   3.315 +
   3.316 +	if(!node->parent) {
   3.317 +		return anm_get_node_position(node, tm);
   3.318 +	}
   3.319 +
   3.320 +	anm_get_matrix(node, xform, tm);
   3.321 +	return v3_transform(pos, xform);
   3.322 +}
   3.323 +
   3.324 +quat_t anm_get_rotation(struct anm_node *node, anm_time_t tm)
   3.325 +{
   3.326 +	quat_t rot, prot;
   3.327 +	rot = anm_get_node_rotation(node, tm);
   3.328 +
   3.329 +	if(!node->parent) {
   3.330 +		return rot;
   3.331 +	}
   3.332 +
   3.333 +	prot = anm_get_rotation(node->parent, tm);
   3.334 +	return quat_mul(prot, rot);
   3.335 +}
   3.336 +
   3.337 +vec3_t anm_get_scaling(struct anm_node *node, anm_time_t tm)
   3.338 +{
   3.339 +	vec3_t s, ps;
   3.340 +	s = anm_get_node_scaling(node, tm);
   3.341 +
   3.342 +	if(!node->parent) {
   3.343 +		return s;
   3.344 +	}
   3.345 +
   3.346 +	ps = anm_get_scaling(node->parent, tm);
   3.347 +	return v3_mul(s, ps);
   3.348 +}
   3.349 +
   3.350 +void anm_set_pivot(struct anm_node *node, vec3_t piv)
   3.351 +{
   3.352 +	node->pivot = piv;
   3.353 +}
   3.354 +
   3.355 +vec3_t anm_get_pivot(struct anm_node *node)
   3.356 +{
   3.357 +	return node->pivot;
   3.358 +}
   3.359 +
   3.360 +void anm_get_node_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm)
   3.361 +{
   3.362 +	int i;
   3.363 +	mat4_t rmat;
   3.364 +	vec3_t pos, scale;
   3.365 +	quat_t rot;
   3.366 +
   3.367 +	pos = anm_get_node_position(node, tm);
   3.368 +	rot = anm_get_node_rotation(node, tm);
   3.369 +	scale = anm_get_node_scaling(node, tm);
   3.370 +
   3.371 +	m4_set_translation(mat, node->pivot.x, node->pivot.y, node->pivot.z);
   3.372 +
   3.373 +	quat_to_mat4(rmat, rot);
   3.374 +	for(i=0; i<3; i++) {
   3.375 +		mat[i][0] = rmat[i][0];
   3.376 +		mat[i][1] = rmat[i][1];
   3.377 +		mat[i][2] = rmat[i][2];
   3.378 +	}
   3.379 +	/* this loop is equivalent to: m4_mult(mat, mat, rmat); */
   3.380 +
   3.381 +	mat[0][0] *= scale.x; mat[0][1] *= scale.y; mat[0][2] *= scale.z; mat[0][3] += pos.x;
   3.382 +	mat[1][0] *= scale.x; mat[1][1] *= scale.y; mat[1][2] *= scale.z; mat[1][3] += pos.y;
   3.383 +	mat[2][0] *= scale.x; mat[2][1] *= scale.y; mat[2][2] *= scale.z; mat[2][3] += pos.z;
   3.384 +
   3.385 +	m4_translate(mat, -node->pivot.x, -node->pivot.y, -node->pivot.z);
   3.386 +
   3.387 +	/* that's basically: pivot * rotation * translation * scaling * -pivot */
   3.388 +}
   3.389 +
   3.390 +void anm_get_node_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm)
   3.391 +{
   3.392 +	mat4_t tmp;
   3.393 +	anm_get_node_matrix(node, tmp, tm);
   3.394 +	m4_inverse(mat, tmp);
   3.395 +}
   3.396 +
   3.397 +void anm_eval_node(struct anm_node *node, anm_time_t tm)
   3.398 +{
   3.399 +	anm_get_node_matrix(node, node->matrix, tm);
   3.400 +}
   3.401 +
   3.402 +void anm_eval(struct anm_node *node, anm_time_t tm)
   3.403 +{
   3.404 +	struct anm_node *c;
   3.405 +
   3.406 +	anm_eval_node(node, tm);
   3.407 +
   3.408 +	if(node->parent) {
   3.409 +		/* due to post-order traversal, the parent matrix is already evaluated */
   3.410 +		m4_mult(node->matrix, node->parent->matrix, node->matrix);
   3.411 +	}
   3.412 +
   3.413 +	/* recersively evaluate all children */
   3.414 +	c = node->child;
   3.415 +	while(c) {
   3.416 +		anm_eval(c, tm);
   3.417 +		c = c->next;
   3.418 +	}
   3.419 +}
   3.420 +
   3.421 +void anm_get_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm)
   3.422 +{
   3.423 +	struct mat_cache *cache = pthread_getspecific(node->cache_key);
   3.424 +	if(!cache) {
   3.425 +		cache = malloc(sizeof *cache);
   3.426 +		assert(cache);
   3.427 +
   3.428 +		pthread_mutex_lock(&node->cache_list_lock);
   3.429 +		cache->next = node->cache_list;
   3.430 +		node->cache_list = cache;
   3.431 +		pthread_mutex_unlock(&node->cache_list_lock);
   3.432 +
   3.433 +		cache->time = ANM_TIME_INVAL;
   3.434 +		cache->inv_time = ANM_TIME_INVAL;
   3.435 +		pthread_setspecific(node->cache_key, cache);
   3.436 +	}
   3.437 +
   3.438 +	if(cache->time != tm) {
   3.439 +		anm_get_node_matrix(node, cache->matrix, tm);
   3.440 +
   3.441 +		if(node->parent) {
   3.442 +			mat4_t parent_mat;
   3.443 +
   3.444 +			anm_get_matrix(node->parent, parent_mat, tm);
   3.445 +			m4_mult(cache->matrix, parent_mat, cache->matrix);
   3.446 +		}
   3.447 +		cache->time = tm;
   3.448 +	}
   3.449 +	m4_copy(mat, cache->matrix);
   3.450 +}
   3.451 +
   3.452 +void anm_get_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm)
   3.453 +{
   3.454 +	struct mat_cache *cache = pthread_getspecific(node->cache_key);
   3.455 +	if(!cache) {
   3.456 +		cache = malloc(sizeof *cache);
   3.457 +		assert(cache);
   3.458 +
   3.459 +		pthread_mutex_lock(&node->cache_list_lock);
   3.460 +		cache->next = node->cache_list;
   3.461 +		node->cache_list = cache;
   3.462 +		pthread_mutex_unlock(&node->cache_list_lock);
   3.463 +
   3.464 +		cache->inv_time = ANM_TIME_INVAL;
   3.465 +		cache->inv_time = ANM_TIME_INVAL;
   3.466 +		pthread_setspecific(node->cache_key, cache);
   3.467 +	}
   3.468 +
   3.469 +	if(cache->inv_time != tm) {
   3.470 +		anm_get_matrix(node, mat, tm);
   3.471 +		m4_inverse(cache->inv_matrix, mat);
   3.472 +		cache->inv_time = tm;
   3.473 +	}
   3.474 +	m4_copy(mat, cache->inv_matrix);
   3.475 +}
   3.476 +
   3.477 +anm_time_t anm_get_start_time(struct anm_node *node)
   3.478 +{
   3.479 +	int i;
   3.480 +	struct anm_node *c;
   3.481 +	anm_time_t res = LONG_MAX;
   3.482 +
   3.483 +	for(i=0; i<ANM_NUM_TRACKS; i++) {
   3.484 +		if(node->tracks[i].count) {
   3.485 +			anm_time_t tm = node->tracks[i].keys[0].time;
   3.486 +			if(tm < res) {
   3.487 +				res = tm;
   3.488 +			}
   3.489 +		}
   3.490 +	}
   3.491 +
   3.492 +	c = node->child;
   3.493 +	while(c) {
   3.494 +		anm_time_t tm = anm_get_start_time(c);
   3.495 +		if(tm < res) {
   3.496 +			res = tm;
   3.497 +		}
   3.498 +		c = c->next;
   3.499 +	}
   3.500 +	return res;
   3.501 +}
   3.502 +
   3.503 +anm_time_t anm_get_end_time(struct anm_node *node)
   3.504 +{
   3.505 +	int i;
   3.506 +	struct anm_node *c;
   3.507 +	anm_time_t res = LONG_MIN;
   3.508 +
   3.509 +	for(i=0; i<ANM_NUM_TRACKS; i++) {
   3.510 +		if(node->tracks[i].count) {
   3.511 +			anm_time_t tm = node->tracks[i].keys[node->tracks[i].count - 1].time;
   3.512 +			if(tm > res) {
   3.513 +				res = tm;
   3.514 +			}
   3.515 +		}
   3.516 +	}
   3.517 +
   3.518 +	c = node->child;
   3.519 +	while(c) {
   3.520 +		anm_time_t tm = anm_get_end_time(c);
   3.521 +		if(tm > res) {
   3.522 +			res = tm;
   3.523 +		}
   3.524 +		c = c->next;
   3.525 +	}
   3.526 +	return res;
   3.527 +}
   3.528 +
   3.529 +static void invalidate_cache(struct anm_node *node)
   3.530 +{
   3.531 +	struct mat_cache *cache = pthread_getspecific(node->cache_key);
   3.532 +	if(cache) {
   3.533 +	   cache->time = cache->inv_time = ANM_TIME_INVAL;
   3.534 +	}
   3.535 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/libs/anim/anim.h	Sat Feb 01 19:58:19 2014 +0200
     4.3 @@ -0,0 +1,132 @@
     4.4 +#ifndef LIBANIM_H_
     4.5 +#define LIBANIM_H_
     4.6 +
     4.7 +#include "config.h"
     4.8 +
     4.9 +#include <pthread.h>
    4.10 +
    4.11 +#include <vmath/vector.h>
    4.12 +#include <vmath/quat.h>
    4.13 +#include <vmath/matrix.h>
    4.14 +#include "track.h"
    4.15 +
    4.16 +enum {
    4.17 +	ANM_TRACK_POS_X,
    4.18 +	ANM_TRACK_POS_Y,
    4.19 +	ANM_TRACK_POS_Z,
    4.20 +
    4.21 +	ANM_TRACK_ROT_X,
    4.22 +	ANM_TRACK_ROT_Y,
    4.23 +	ANM_TRACK_ROT_Z,
    4.24 +	ANM_TRACK_ROT_W,
    4.25 +
    4.26 +	ANM_TRACK_SCL_X,
    4.27 +	ANM_TRACK_SCL_Y,
    4.28 +	ANM_TRACK_SCL_Z,
    4.29 +
    4.30 +	ANM_NUM_TRACKS
    4.31 +};
    4.32 +
    4.33 +struct anm_node {
    4.34 +	char *name;
    4.35 +
    4.36 +	struct anm_track tracks[ANM_NUM_TRACKS];
    4.37 +	vec3_t pivot;
    4.38 +
    4.39 +	/* matrix cache */
    4.40 +	struct mat_cache {
    4.41 +		mat4_t matrix, inv_matrix;
    4.42 +		anm_time_t time, inv_time;
    4.43 +		struct mat_cache *next;
    4.44 +	} *cache_list;
    4.45 +	pthread_key_t cache_key;
    4.46 +	pthread_mutex_t cache_list_lock;
    4.47 +
    4.48 +	/* matrix calculated by anm_eval functions (no locking, meant as a pre-pass) */
    4.49 +	mat4_t matrix;
    4.50 +
    4.51 +	struct anm_node *parent;
    4.52 +	struct anm_node *child;
    4.53 +	struct anm_node *next;
    4.54 +};
    4.55 +
    4.56 +#ifdef __cplusplus
    4.57 +extern "C" {
    4.58 +#endif
    4.59 +
    4.60 +/* node constructor and destructor */
    4.61 +int anm_init_node(struct anm_node *node);
    4.62 +void anm_destroy_node(struct anm_node *node);
    4.63 +
    4.64 +/* recursively destroy an animation node tree */
    4.65 +void anm_destroy_node_tree(struct anm_node *tree);
    4.66 +
    4.67 +/* helper functions to allocate/construct and destroy/free with
    4.68 + * a single call. They call anm_init_node and anm_destroy_node
    4.69 + * internally.
    4.70 + */
    4.71 +struct anm_node *anm_create_node(void);
    4.72 +void anm_free_node(struct anm_node *node);
    4.73 +
    4.74 +/* recursively destroy and free the nodes of a node tree */
    4.75 +void anm_free_node_tree(struct anm_node *tree);
    4.76 +
    4.77 +int anm_set_node_name(struct anm_node *node, const char *name);
    4.78 +const char *anm_get_node_name(struct anm_node *node);
    4.79 +
    4.80 +void anm_set_interpolator(struct anm_node *node, enum anm_interpolator in);
    4.81 +void anm_set_extrapolator(struct anm_node *node, enum anm_extrapolator ex);
    4.82 +
    4.83 +/* link and unlink nodes with parent/child relations */
    4.84 +void anm_link_node(struct anm_node *parent, struct anm_node *child);
    4.85 +int anm_unlink_node(struct anm_node *parent, struct anm_node *child);
    4.86 +
    4.87 +void anm_clear(struct anm_node *node);
    4.88 +
    4.89 +void anm_set_position(struct anm_node *node, vec3_t pos, anm_time_t tm);
    4.90 +vec3_t anm_get_node_position(struct anm_node *node, anm_time_t tm);
    4.91 +
    4.92 +void anm_set_rotation(struct anm_node *node, quat_t rot, anm_time_t tm);
    4.93 +quat_t anm_get_node_rotation(struct anm_node *node, anm_time_t tm);
    4.94 +
    4.95 +void anm_set_scaling(struct anm_node *node, vec3_t scl, anm_time_t tm);
    4.96 +vec3_t anm_get_node_scaling(struct anm_node *node, anm_time_t tm);
    4.97 +
    4.98 +/* these three return the full p/r/s taking hierarchy into account */
    4.99 +vec3_t anm_get_position(struct anm_node *node, anm_time_t tm);
   4.100 +quat_t anm_get_rotation(struct anm_node *node, anm_time_t tm);
   4.101 +vec3_t anm_get_scaling(struct anm_node *node, anm_time_t tm);
   4.102 +
   4.103 +void anm_set_pivot(struct anm_node *node, vec3_t pivot);
   4.104 +vec3_t anm_get_pivot(struct anm_node *node);
   4.105 +
   4.106 +/* those return the start and end times of the whole tree */
   4.107 +anm_time_t anm_get_start_time(struct anm_node *node);
   4.108 +anm_time_t anm_get_end_time(struct anm_node *node);
   4.109 +
   4.110 +/* these calculate the matrix and inverse matrix of this node alone */
   4.111 +void anm_get_node_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm);
   4.112 +void anm_get_node_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm);
   4.113 +
   4.114 +/* ---- top-down matrix calculation interface ---- */
   4.115 +
   4.116 +/* calculate and set the matrix of this node */
   4.117 +void anm_eval_node(struct anm_node *node, anm_time_t tm);
   4.118 +/* calculate and set the matrix of this node and all its children recursively */
   4.119 +void anm_eval(struct anm_node *node, anm_time_t tm);
   4.120 +
   4.121 +
   4.122 +/* ---- bottom-up lazy matrix calculation interface ---- */
   4.123 +
   4.124 +/* These calculate the matrix and inverse matrix of this node taking hierarchy
   4.125 + * into account. The results are cached in thread-specific storage and returned
   4.126 + * if there's no change in time or tracks from the last query...
   4.127 + */
   4.128 +void anm_get_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm);
   4.129 +void anm_get_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm);
   4.130 +
   4.131 +#ifdef __cplusplus
   4.132 +}
   4.133 +#endif
   4.134 +
   4.135 +#endif	/* LIBANIM_H_ */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/libs/anim/config.h	Sat Feb 01 19:58:19 2014 +0200
     5.3 @@ -0,0 +1,6 @@
     5.4 +#ifndef ANIM_CONFIG_H_
     5.5 +#define ANIM_CONFIG_H_
     5.6 +
     5.7 +#undef ANIM_THREAD_SAFE
     5.8 +
     5.9 +#endif	/* ANIM_CONFIG_H_ */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/libs/anim/dynarr.c	Sat Feb 01 19:58:19 2014 +0200
     6.3 @@ -0,0 +1,122 @@
     6.4 +#include <stdio.h>
     6.5 +#include <stdlib.h>
     6.6 +#include <string.h>
     6.7 +#include "dynarr.h"
     6.8 +
     6.9 +/* The array descriptor keeps auxilliary information needed to manipulate
    6.10 + * the dynamic array. It's allocated adjacent to the array buffer.
    6.11 + */
    6.12 +struct arrdesc {
    6.13 +	int nelem, szelem;
    6.14 +	int max_elem;
    6.15 +	int bufsz;	/* not including the descriptor */
    6.16 +};
    6.17 +
    6.18 +#define DESC(x)		((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc)))
    6.19 +
    6.20 +void *dynarr_alloc(int elem, int szelem)
    6.21 +{
    6.22 +	struct arrdesc *desc;
    6.23 +
    6.24 +	if(!(desc = malloc(elem * szelem + sizeof *desc))) {
    6.25 +		return 0;
    6.26 +	}
    6.27 +	desc->nelem = desc->max_elem = elem;
    6.28 +	desc->szelem = szelem;
    6.29 +	desc->bufsz = elem * szelem;
    6.30 +	return (char*)desc + sizeof *desc;
    6.31 +}
    6.32 +
    6.33 +void dynarr_free(void *da)
    6.34 +{
    6.35 +	if(da) {
    6.36 +		free(DESC(da));
    6.37 +	}
    6.38 +}
    6.39 +
    6.40 +void *dynarr_resize(void *da, int elem)
    6.41 +{
    6.42 +	int newsz;
    6.43 +	void *tmp;
    6.44 +	struct arrdesc *desc;
    6.45 +
    6.46 +	if(!da) return 0;
    6.47 +	desc = DESC(da);
    6.48 +
    6.49 +	newsz = desc->szelem * elem;
    6.50 +
    6.51 +	if(!(tmp = realloc(desc, newsz + sizeof *desc))) {
    6.52 +		return 0;
    6.53 +	}
    6.54 +	desc = tmp;
    6.55 +
    6.56 +	desc->nelem = desc->max_elem = elem;
    6.57 +	desc->bufsz = newsz;
    6.58 +	return (char*)desc + sizeof *desc;
    6.59 +}
    6.60 +
    6.61 +int dynarr_empty(void *da)
    6.62 +{
    6.63 +	return DESC(da)->nelem ? 0 : 1;
    6.64 +}
    6.65 +
    6.66 +int dynarr_size(void *da)
    6.67 +{
    6.68 +	return DESC(da)->nelem;
    6.69 +}
    6.70 +
    6.71 +
    6.72 +/* stack semantics */
    6.73 +void *dynarr_push(void *da, void *item)
    6.74 +{
    6.75 +	struct arrdesc *desc;
    6.76 +	int nelem;
    6.77 +
    6.78 +	desc = DESC(da);
    6.79 +	nelem = desc->nelem;
    6.80 +
    6.81 +	if(nelem >= desc->max_elem) {
    6.82 +		/* need to resize */
    6.83 +		struct arrdesc *tmp;
    6.84 +		int newsz = desc->max_elem ? desc->max_elem * 2 : 1;
    6.85 +
    6.86 +		if(!(tmp = dynarr_resize(da, newsz))) {
    6.87 +			fprintf(stderr, "failed to resize\n");
    6.88 +			return da;
    6.89 +		}
    6.90 +		da = tmp;
    6.91 +		desc = DESC(da);
    6.92 +		desc->nelem = nelem;
    6.93 +	}
    6.94 +
    6.95 +	memcpy((char*)da + desc->nelem++ * desc->szelem, item, desc->szelem);
    6.96 +	return da;
    6.97 +}
    6.98 +
    6.99 +void *dynarr_pop(void *da)
   6.100 +{
   6.101 +	struct arrdesc *desc;
   6.102 +	int nelem;
   6.103 +
   6.104 +	desc = DESC(da);
   6.105 +	nelem = desc->nelem;
   6.106 +
   6.107 +	if(!nelem) return da;
   6.108 +
   6.109 +	if(nelem <= desc->max_elem / 3) {
   6.110 +		/* reclaim space */
   6.111 +		struct arrdesc *tmp;
   6.112 +		int newsz = desc->max_elem / 2;
   6.113 +
   6.114 +		if(!(tmp = dynarr_resize(da, newsz))) {
   6.115 +			fprintf(stderr, "failed to resize\n");
   6.116 +			return da;
   6.117 +		}
   6.118 +		da = tmp;
   6.119 +		desc = DESC(da);
   6.120 +		desc->nelem = nelem;
   6.121 +	}
   6.122 +	desc->nelem--;
   6.123 +
   6.124 +	return da;
   6.125 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/libs/anim/dynarr.h	Sat Feb 01 19:58:19 2014 +0200
     7.3 @@ -0,0 +1,16 @@
     7.4 +#ifndef DYNARR_H_
     7.5 +#define DYNARR_H_
     7.6 +
     7.7 +void *dynarr_alloc(int elem, int szelem);
     7.8 +void dynarr_free(void *da);
     7.9 +void *dynarr_resize(void *da, int elem);
    7.10 +
    7.11 +int dynarr_empty(void *da);
    7.12 +int dynarr_size(void *da);
    7.13 +
    7.14 +/* stack semantics */
    7.15 +void *dynarr_push(void *da, void *item);
    7.16 +void *dynarr_pop(void *da);
    7.17 +
    7.18 +
    7.19 +#endif	/* DYNARR_H_ */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/libs/anim/track.c	Sat Feb 01 19:58:19 2014 +0200
     8.3 @@ -0,0 +1,331 @@
     8.4 +#include <stdio.h>
     8.5 +#include <stdlib.h>
     8.6 +#include <string.h>
     8.7 +#include <assert.h>
     8.8 +#include "track.h"
     8.9 +#include "dynarr.h"
    8.10 +
    8.11 +static int keycmp(const void *a, const void *b);
    8.12 +static int find_prev_key(struct anm_keyframe *arr, int start, int end, anm_time_t tm);
    8.13 +
    8.14 +static float interp_step(float v0, float v1, float v2, float v3, float t);
    8.15 +static float interp_linear(float v0, float v1, float v2, float v3, float t);
    8.16 +static float interp_cubic(float v0, float v1, float v2, float v3, float t);
    8.17 +
    8.18 +static anm_time_t remap_extend(anm_time_t tm, anm_time_t start, anm_time_t end);
    8.19 +static anm_time_t remap_clamp(anm_time_t tm, anm_time_t start, anm_time_t end);
    8.20 +static anm_time_t remap_repeat(anm_time_t tm, anm_time_t start, anm_time_t end);
    8.21 +static anm_time_t remap_pingpong(anm_time_t tm, anm_time_t start, anm_time_t end);
    8.22 +
    8.23 +/* XXX keep this in sync with enum anm_interpolator at track.h */
    8.24 +static float (*interp[])(float, float, float, float, float) = {
    8.25 +	interp_step,
    8.26 +	interp_linear,
    8.27 +	interp_cubic,
    8.28 +	0
    8.29 +};
    8.30 +
    8.31 +/* XXX keep this in sync with enum anm_extrapolator at track.h */
    8.32 +static anm_time_t (*remap_time[])(anm_time_t, anm_time_t, anm_time_t) = {
    8.33 +	remap_extend,
    8.34 +	remap_clamp,
    8.35 +	remap_repeat,
    8.36 +	remap_pingpong,
    8.37 +	0
    8.38 +};
    8.39 +
    8.40 +int anm_init_track(struct anm_track *track)
    8.41 +{
    8.42 +	memset(track, 0, sizeof *track);
    8.43 +
    8.44 +	if(!(track->keys = dynarr_alloc(0, sizeof *track->keys))) {
    8.45 +		return -1;
    8.46 +	}
    8.47 +	track->interp = ANM_INTERP_LINEAR;
    8.48 +	track->extrap = ANM_EXTRAP_CLAMP;
    8.49 +	return 0;
    8.50 +}
    8.51 +
    8.52 +void anm_destroy_track(struct anm_track *track)
    8.53 +{
    8.54 +	dynarr_free(track->keys);
    8.55 +}
    8.56 +
    8.57 +struct anm_track *anm_create_track(void)
    8.58 +{
    8.59 +	struct anm_track *track;
    8.60 +
    8.61 +	if((track = malloc(sizeof *track))) {
    8.62 +		if(anm_init_track(track) == -1) {
    8.63 +			free(track);
    8.64 +			return 0;
    8.65 +		}
    8.66 +	}
    8.67 +	return track;
    8.68 +}
    8.69 +
    8.70 +void anm_free_track(struct anm_track *track)
    8.71 +{
    8.72 +	anm_destroy_track(track);
    8.73 +	free(track);
    8.74 +}
    8.75 +
    8.76 +void anm_copy_track(struct anm_track *dest, const struct anm_track *src)
    8.77 +{
    8.78 +	free(dest->name);
    8.79 +	if(dest->keys) {
    8.80 +		dynarr_free(dest->keys);
    8.81 +	}
    8.82 +
    8.83 +	if(src->name) {
    8.84 +		dest->name = malloc(strlen(src->name) + 1);
    8.85 +		strcpy(dest->name, src->name);
    8.86 +	}
    8.87 +
    8.88 +	dest->count = src->count;
    8.89 +	dest->keys = dynarr_alloc(src->count, sizeof *dest->keys);
    8.90 +	memcpy(dest->keys, src->keys, src->count * sizeof *dest->keys);
    8.91 +
    8.92 +	dest->def_val = src->def_val;
    8.93 +	dest->interp = src->interp;
    8.94 +	dest->extrap = src->extrap;
    8.95 +}
    8.96 +
    8.97 +void anm_clear_track(struct anm_track *track)
    8.98 +{
    8.99 +	if(track->keys) {
   8.100 +		dynarr_free(track->keys);
   8.101 +	}
   8.102 +	track->keys = 0;
   8.103 +	track->count = 0;
   8.104 +
   8.105 +	if(!(track->keys = dynarr_alloc(0, sizeof *track->keys))) {
   8.106 +		fprintf(stderr, "anm_clear_track failed to allocate zero-length keyframe track\n");
   8.107 +	}
   8.108 +	assert(track->keys);
   8.109 +}
   8.110 +
   8.111 +int anm_set_track_name(struct anm_track *track, const char *name)
   8.112 +{
   8.113 +	char *tmp;
   8.114 +
   8.115 +	if(!(tmp = malloc(strlen(name) + 1))) {
   8.116 +		return -1;
   8.117 +	}
   8.118 +	free(track->name);
   8.119 +	track->name = tmp;
   8.120 +	return 0;
   8.121 +}
   8.122 +
   8.123 +const char *anm_get_track_name(struct anm_track *track)
   8.124 +{
   8.125 +	return track->name;
   8.126 +}
   8.127 +
   8.128 +void anm_set_track_interpolator(struct anm_track *track, enum anm_interpolator in)
   8.129 +{
   8.130 +	track->interp = in;
   8.131 +}
   8.132 +
   8.133 +void anm_set_track_extrapolator(struct anm_track *track, enum anm_extrapolator ex)
   8.134 +{
   8.135 +	track->extrap = ex;
   8.136 +}
   8.137 +
   8.138 +anm_time_t anm_remap_time(struct anm_track *track, anm_time_t tm, anm_time_t start, anm_time_t end)
   8.139 +{
   8.140 +	return remap_time[track->extrap](tm, start, end);
   8.141 +}
   8.142 +
   8.143 +void anm_set_track_default(struct anm_track *track, float def)
   8.144 +{
   8.145 +	track->def_val = def;
   8.146 +}
   8.147 +
   8.148 +int anm_set_keyframe(struct anm_track *track, struct anm_keyframe *key)
   8.149 +{
   8.150 +	int idx = anm_get_key_interval(track, key->time);
   8.151 +
   8.152 +	/* if we got a valid keyframe index, compare them... */
   8.153 +	if(idx >= 0 && idx < track->count && keycmp(key, track->keys + idx) == 0) {
   8.154 +		/* ... it's the same key, just update the value */
   8.155 +		track->keys[idx].val = key->val;
   8.156 +	} else {
   8.157 +		/* ... it's a new key, add it and re-sort them */
   8.158 +		void *tmp;
   8.159 +		if(!(tmp = dynarr_push(track->keys, key))) {
   8.160 +			return -1;
   8.161 +		}
   8.162 +		track->keys = tmp;
   8.163 +		/* TODO lazy qsort */
   8.164 +		qsort(track->keys, ++track->count, sizeof *track->keys, keycmp);
   8.165 +	}
   8.166 +	return 0;
   8.167 +}
   8.168 +
   8.169 +static int keycmp(const void *a, const void *b)
   8.170 +{
   8.171 +	return ((struct anm_keyframe*)a)->time - ((struct anm_keyframe*)b)->time;
   8.172 +}
   8.173 +
   8.174 +struct anm_keyframe *anm_get_keyframe(struct anm_track *track, int idx)
   8.175 +{
   8.176 +	if(idx < 0 || idx >= track->count) {
   8.177 +		return 0;
   8.178 +	}
   8.179 +	return track->keys + idx;
   8.180 +}
   8.181 +
   8.182 +int anm_get_key_interval(struct anm_track *track, anm_time_t tm)
   8.183 +{
   8.184 +	int last;
   8.185 +
   8.186 +	if(!track->count || tm < track->keys[0].time) {
   8.187 +		return -1;
   8.188 +	}
   8.189 +
   8.190 +	last = track->count - 1;
   8.191 +	if(tm > track->keys[last].time) {
   8.192 +		return last;
   8.193 +	}
   8.194 +
   8.195 +	return find_prev_key(track->keys, 0, last, tm);
   8.196 +}
   8.197 +
   8.198 +static int find_prev_key(struct anm_keyframe *arr, int start, int end, anm_time_t tm)
   8.199 +{
   8.200 +	int mid;
   8.201 +
   8.202 +	if(end - start <= 1) {
   8.203 +		return start;
   8.204 +	}
   8.205 +
   8.206 +	mid = (start + end) / 2;
   8.207 +	if(tm < arr[mid].time) {
   8.208 +		return find_prev_key(arr, start, mid, tm);
   8.209 +	}
   8.210 +	if(tm > arr[mid].time) {
   8.211 +		return find_prev_key(arr, mid, end, tm);
   8.212 +	}
   8.213 +	return mid;
   8.214 +}
   8.215 +
   8.216 +int anm_set_value(struct anm_track *track, anm_time_t tm, float val)
   8.217 +{
   8.218 +	struct anm_keyframe key;
   8.219 +	key.time = tm;
   8.220 +	key.val = val;
   8.221 +
   8.222 +	return anm_set_keyframe(track, &key);
   8.223 +}
   8.224 +
   8.225 +float anm_get_value(struct anm_track *track, anm_time_t tm)
   8.226 +{
   8.227 +	int idx0, idx1, last_idx;
   8.228 +	anm_time_t tstart, tend;
   8.229 +	float t, dt;
   8.230 +	float v0, v1, v2, v3;
   8.231 +
   8.232 +	if(!track->count) {
   8.233 +		return track->def_val;
   8.234 +	}
   8.235 +
   8.236 +	last_idx = track->count - 1;
   8.237 +
   8.238 +	tstart = track->keys[0].time;
   8.239 +	tend = track->keys[last_idx].time;
   8.240 +
   8.241 +	if(tstart == tend) {
   8.242 +		return track->keys[0].val;
   8.243 +	}
   8.244 +
   8.245 +	tm = remap_time[track->extrap](tm, tstart, tend);
   8.246 +
   8.247 +	idx0 = anm_get_key_interval(track, tm);
   8.248 +	assert(idx0 >= 0 && idx0 < track->count);
   8.249 +	idx1 = idx0 + 1;
   8.250 +
   8.251 +	if(idx0 == last_idx) {
   8.252 +		return track->keys[idx0].val;
   8.253 +	}
   8.254 +
   8.255 +	dt = (float)(track->keys[idx1].time - track->keys[idx0].time);
   8.256 +	t = (float)(tm - track->keys[idx0].time) / dt;
   8.257 +
   8.258 +	v1 = track->keys[idx0].val;
   8.259 +	v2 = track->keys[idx1].val;
   8.260 +
   8.261 +	/* get the neigboring values to allow for cubic interpolation */
   8.262 +	v0 = idx0 > 0 ? track->keys[idx0 - 1].val : v1;
   8.263 +	v3 = idx1 < last_idx ? track->keys[idx1 + 1].val : v2;
   8.264 +
   8.265 +	return interp[track->interp](v0, v1, v2, v3, t);
   8.266 +}
   8.267 +
   8.268 +
   8.269 +static float interp_step(float v0, float v1, float v2, float v3, float t)
   8.270 +{
   8.271 +	return v1;
   8.272 +}
   8.273 +
   8.274 +static float interp_linear(float v0, float v1, float v2, float v3, float t)
   8.275 +{
   8.276 +	return v1 + (v2 - v1) * t;
   8.277 +}
   8.278 +
   8.279 +static float interp_cubic(float a, float b, float c, float d, float t)
   8.280 +{
   8.281 +	float x, y, z, w;
   8.282 +	float tsq = t * t;
   8.283 +
   8.284 +	x = -a + 3.0 * b - 3.0 * c + d;
   8.285 +	y = 2.0 * a - 5.0 * b + 4.0 * c - d;
   8.286 +	z = c - a;
   8.287 +	w = 2.0 * b;
   8.288 +
   8.289 +	return 0.5 * (x * tsq * t + y * tsq + z * t + w);
   8.290 +}
   8.291 +
   8.292 +static anm_time_t remap_extend(anm_time_t tm, anm_time_t start, anm_time_t end)
   8.293 +{
   8.294 +	return remap_repeat(tm, start, end);
   8.295 +}
   8.296 +
   8.297 +static anm_time_t remap_clamp(anm_time_t tm, anm_time_t start, anm_time_t end)
   8.298 +{
   8.299 +	if(start == end) {
   8.300 +		return start;
   8.301 +	}
   8.302 +	return tm < start ? start : (tm >= end ? end - 1 : tm);
   8.303 +}
   8.304 +
   8.305 +static anm_time_t remap_repeat(anm_time_t tm, anm_time_t start, anm_time_t end)
   8.306 +{
   8.307 +	anm_time_t x, interv = end - start;
   8.308 +
   8.309 +	if(interv == 0) {
   8.310 +		return start;
   8.311 +	}
   8.312 +
   8.313 +	x = (tm - start) % interv;
   8.314 +	if(x < 0) {
   8.315 +		x += interv;
   8.316 +	}
   8.317 +	return x + start;
   8.318 +
   8.319 +	/*if(tm < start) {
   8.320 +		while(tm < start) {
   8.321 +			tm += interv;
   8.322 +		}
   8.323 +		return tm;
   8.324 +	}
   8.325 +	return (tm - start) % interv + start;*/
   8.326 +}
   8.327 +
   8.328 +static anm_time_t remap_pingpong(anm_time_t tm, anm_time_t start, anm_time_t end)
   8.329 +{
   8.330 +	anm_time_t interv = end - start;
   8.331 +	anm_time_t x = remap_repeat(tm, start, end + interv);
   8.332 +
   8.333 +	return x > end ? end + interv - x : x;
   8.334 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/libs/anim/track.h	Sat Feb 01 19:58:19 2014 +0200
     9.3 @@ -0,0 +1,103 @@
     9.4 +/* An animation track defines the values of a single scalar over time
     9.5 + * and supports various interpolation and extrapolation modes.
     9.6 + */
     9.7 +#ifndef LIBANIM_TRACK_H_
     9.8 +#define LIBANIM_TRACK_H_
     9.9 +
    9.10 +#include <limits.h>
    9.11 +#include "config.h"
    9.12 +
    9.13 +enum anm_interpolator {
    9.14 +	ANM_INTERP_STEP,
    9.15 +	ANM_INTERP_LINEAR,
    9.16 +	ANM_INTERP_CUBIC
    9.17 +};
    9.18 +
    9.19 +enum anm_extrapolator {
    9.20 +	ANM_EXTRAP_EXTEND,	/* extend to infinity */
    9.21 +	ANM_EXTRAP_CLAMP,	/* clamp to last value */
    9.22 +	ANM_EXTRAP_REPEAT,	/* repeat motion */
    9.23 +	ANM_EXTRAP_PINGPONG	/* repeat with mirroring */
    9.24 +};
    9.25 +
    9.26 +typedef long anm_time_t;
    9.27 +#define ANM_TIME_INVAL	LONG_MIN
    9.28 +
    9.29 +#define ANM_SEC2TM(x)	((anm_time_t)((x) * 1000))
    9.30 +#define ANM_MSEC2TM(x)	((anm_time_t)(x))
    9.31 +#define ANM_TM2SEC(x)	((x) / 1000.0)
    9.32 +#define ANM_TM2MSEC(x)	(x)
    9.33 +
    9.34 +struct anm_keyframe {
    9.35 +	anm_time_t time;
    9.36 +	float val;
    9.37 +};
    9.38 +
    9.39 +struct anm_track {
    9.40 +	char *name;
    9.41 +	int count;
    9.42 +	struct anm_keyframe *keys;
    9.43 +
    9.44 +	float def_val;
    9.45 +
    9.46 +	enum anm_interpolator interp;
    9.47 +	enum anm_extrapolator extrap;
    9.48 +};
    9.49 +
    9.50 +#ifdef __cplusplus
    9.51 +extern "C" {
    9.52 +#endif
    9.53 +
    9.54 +/* track constructor and destructor */
    9.55 +int anm_init_track(struct anm_track *track);
    9.56 +void anm_destroy_track(struct anm_track *track);
    9.57 +
    9.58 +/* helper functions that use anm_init_track and anm_destroy_track internally */
    9.59 +struct anm_track *anm_create_track(void);
    9.60 +void anm_free_track(struct anm_track *track);
    9.61 +
    9.62 +/* copies track src to dest
    9.63 + * XXX: dest must have been initialized first
    9.64 + */
    9.65 +void anm_copy_track(struct anm_track *dest, const struct anm_track *src);
    9.66 +
    9.67 +void anm_clear_track(struct anm_track *track);
    9.68 +
    9.69 +int anm_set_track_name(struct anm_track *track, const char *name);
    9.70 +const char *anm_get_track_name(struct anm_track *track);
    9.71 +
    9.72 +void anm_set_track_interpolator(struct anm_track *track, enum anm_interpolator in);
    9.73 +void anm_set_track_extrapolator(struct anm_track *track, enum anm_extrapolator ex);
    9.74 +
    9.75 +anm_time_t anm_remap_time(struct anm_track *track, anm_time_t tm, anm_time_t start, anm_time_t end);
    9.76 +
    9.77 +void anm_set_track_default(struct anm_track *track, float def);
    9.78 +
    9.79 +/* set or update a keyframe */
    9.80 +int anm_set_keyframe(struct anm_track *track, struct anm_keyframe *key);
    9.81 +
    9.82 +/* get the idx-th keyframe, returns null if it doesn't exist */
    9.83 +struct anm_keyframe *anm_get_keyframe(struct anm_track *track, int idx);
    9.84 +
    9.85 +/* Finds the 0-based index of the intra-keyframe interval which corresponds
    9.86 + * to the specified time. If the time falls exactly onto the N-th keyframe
    9.87 + * the function returns N.
    9.88 + *
    9.89 + * Special cases:
    9.90 + * - if the time is before the first keyframe -1 is returned.
    9.91 + * - if the time is after the last keyframe, the index of the last keyframe
    9.92 + *   is returned.
    9.93 + */
    9.94 +int anm_get_key_interval(struct anm_track *track, anm_time_t tm);
    9.95 +
    9.96 +int anm_set_value(struct anm_track *track, anm_time_t tm, float val);
    9.97 +
    9.98 +/* evaluates and returns the value of the track for a particular time */
    9.99 +float anm_get_value(struct anm_track *track, anm_time_t tm);
   9.100 +
   9.101 +#ifdef __cplusplus
   9.102 +}
   9.103 +#endif
   9.104 +
   9.105 +
   9.106 +#endif	/* LIBANIM_TRACK_H_ */
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/libs/assimp/3DSConverter.cpp	Sat Feb 01 19:58:19 2014 +0200
    10.3 @@ -0,0 +1,841 @@
    10.4 +/*
    10.5 +---------------------------------------------------------------------------
    10.6 +Open Asset Import Library (assimp)
    10.7 +---------------------------------------------------------------------------
    10.8 +
    10.9 +Copyright (c) 2006-2012, assimp team
   10.10 +
   10.11 +All rights reserved.
   10.12 +
   10.13 +Redistribution and use of this software in source and binary forms, 
   10.14 +with or without modification, are permitted provided that the following 
   10.15 +conditions are met:
   10.16 +
   10.17 +* Redistributions of source code must retain the above
   10.18 +  copyright notice, this list of conditions and the
   10.19 +  following disclaimer.
   10.20 +
   10.21 +* Redistributions in binary form must reproduce the above
   10.22 +  copyright notice, this list of conditions and the
   10.23 +  following disclaimer in the documentation and/or other
   10.24 +  materials provided with the distribution.
   10.25 +
   10.26 +* Neither the name of the assimp team, nor the names of its
   10.27 +  contributors may be used to endorse or promote products
   10.28 +  derived from this software without specific prior
   10.29 +  written permission of the assimp team.
   10.30 +
   10.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   10.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   10.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   10.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   10.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   10.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   10.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   10.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   10.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   10.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   10.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   10.42 +---------------------------------------------------------------------------
   10.43 +*/
   10.44 +
   10.45 +/** @file Implementation of the 3ds importer class */
   10.46 +
   10.47 +#include "AssimpPCH.h"
   10.48 +#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
   10.49 +
   10.50 +// internal headers
   10.51 +#include "3DSLoader.h"
   10.52 +#include "TargetAnimation.h"
   10.53 +
   10.54 +using namespace Assimp;
   10.55 +
   10.56 +// ------------------------------------------------------------------------------------------------
   10.57 +// Setup final material indices, generae a default material if necessary
   10.58 +void Discreet3DSImporter::ReplaceDefaultMaterial()
   10.59 +{
   10.60 +	
   10.61 +	// Try to find an existing material that matches the
   10.62 +	// typical default material setting:
   10.63 +	// - no textures
   10.64 +	// - diffuse color (in grey!)
   10.65 +	// NOTE: This is here to workaround the fact that some
   10.66 +	// exporters are writing a default material, too.
   10.67 +	unsigned int idx = 0xcdcdcdcd;
   10.68 +	for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
   10.69 +	{
   10.70 +		std::string s = mScene->mMaterials[i].mName;
   10.71 +		for (std::string::iterator it = s.begin(); it != s.end(); ++it)
   10.72 +			*it = ::tolower(*it);
   10.73 +
   10.74 +		if (std::string::npos == s.find("default"))continue;
   10.75 +
   10.76 +		if (mScene->mMaterials[i].mDiffuse.r !=
   10.77 +			mScene->mMaterials[i].mDiffuse.g ||
   10.78 +			mScene->mMaterials[i].mDiffuse.r !=
   10.79 +			mScene->mMaterials[i].mDiffuse.b)continue;
   10.80 +
   10.81 +		if (mScene->mMaterials[i].sTexDiffuse.mMapName.length()   != 0	||
   10.82 +			mScene->mMaterials[i].sTexBump.mMapName.length()      != 0	|| 
   10.83 +			mScene->mMaterials[i].sTexOpacity.mMapName.length()   != 0	||
   10.84 +			mScene->mMaterials[i].sTexEmissive.mMapName.length()  != 0	||
   10.85 +			mScene->mMaterials[i].sTexSpecular.mMapName.length()  != 0	||
   10.86 +			mScene->mMaterials[i].sTexShininess.mMapName.length() != 0 )
   10.87 +		{
   10.88 +			continue;
   10.89 +		}
   10.90 +		idx = i;
   10.91 +	}
   10.92 +	if (0xcdcdcdcd == idx)idx = (unsigned int)mScene->mMaterials.size();
   10.93 +
   10.94 +	// now iterate through all meshes and through all faces and
   10.95 +	// find all faces that are using the default material
   10.96 +	unsigned int cnt = 0;
   10.97 +	for (std::vector<D3DS::Mesh>::iterator
   10.98 +		i =  mScene->mMeshes.begin();
   10.99 +		i != mScene->mMeshes.end();++i)
  10.100 +	{
  10.101 +		for (std::vector<unsigned int>::iterator
  10.102 +			a =  (*i).mFaceMaterials.begin();
  10.103 +			a != (*i).mFaceMaterials.end();++a)
  10.104 +		{
  10.105 +			// NOTE: The additional check seems to be necessary,
  10.106 +			// some exporters seem to generate invalid data here
  10.107 +			if (0xcdcdcdcd == (*a))
  10.108 +			{
  10.109 +				(*a) = idx;
  10.110 +				++cnt;
  10.111 +			}
  10.112 +			else if ( (*a) >= mScene->mMaterials.size())
  10.113 +			{
  10.114 +				(*a) = idx;
  10.115 +				DefaultLogger::get()->warn("Material index overflow in 3DS file. Using default material");
  10.116 +				++cnt;
  10.117 +			}
  10.118 +		}
  10.119 +	}
  10.120 +	if (cnt && idx == mScene->mMaterials.size())
  10.121 +	{
  10.122 +		// We need to create our own default material
  10.123 +		D3DS::Material sMat;
  10.124 +		sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f);
  10.125 +		sMat.mName = "%%%DEFAULT";
  10.126 +		mScene->mMaterials.push_back(sMat);
  10.127 +
  10.128 +		DefaultLogger::get()->info("3DS: Generating default material");
  10.129 +	}
  10.130 +}
  10.131 +
  10.132 +// ------------------------------------------------------------------------------------------------
  10.133 +// Check whether all indices are valid. Otherwise we'd crash before the validation step is reached
  10.134 +void Discreet3DSImporter::CheckIndices(D3DS::Mesh& sMesh)
  10.135 +{
  10.136 +	for (std::vector< D3DS::Face >::iterator i =  sMesh.mFaces.begin(); i != sMesh.mFaces.end();++i)
  10.137 +	{
  10.138 +		// check whether all indices are in range
  10.139 +		for (unsigned int a = 0; a < 3;++a)
  10.140 +		{
  10.141 +			if ((*i).mIndices[a] >= sMesh.mPositions.size())
  10.142 +			{
  10.143 +				DefaultLogger::get()->warn("3DS: Vertex index overflow)");
  10.144 +				(*i).mIndices[a] = (uint32_t)sMesh.mPositions.size()-1;
  10.145 +			}
  10.146 +			if ( !sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size())
  10.147 +			{
  10.148 +				DefaultLogger::get()->warn("3DS: Texture coordinate index overflow)");
  10.149 +				(*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size()-1;
  10.150 +			}
  10.151 +		}
  10.152 +	}
  10.153 +}
  10.154 +
  10.155 +// ------------------------------------------------------------------------------------------------
  10.156 +// Generate out unique verbose format representation
  10.157 +void Discreet3DSImporter::MakeUnique(D3DS::Mesh& sMesh)
  10.158 +{
  10.159 +	// TODO: really necessary? I don't think. Just a waste of memory and time
  10.160 +	// to do it now in a separate buffer. 
  10.161 +
  10.162 +	// Allocate output storage
  10.163 +	std::vector<aiVector3D> vNew  (sMesh.mFaces.size() * 3);
  10.164 +	std::vector<aiVector3D> vNew2;
  10.165 +	if (sMesh.mTexCoords.size())
  10.166 +		vNew2.resize(sMesh.mFaces.size() * 3);
  10.167 +
  10.168 +	for (unsigned int i = 0, base = 0; i < sMesh.mFaces.size();++i)
  10.169 +	{
  10.170 +		D3DS::Face& face = sMesh.mFaces[i];
  10.171 +
  10.172 +		// Positions
  10.173 +		for (unsigned int a = 0; a < 3;++a,++base)
  10.174 +		{
  10.175 +			vNew[base] = sMesh.mPositions[face.mIndices[a]];
  10.176 +			if (sMesh.mTexCoords.size())
  10.177 +				vNew2[base] = sMesh.mTexCoords[face.mIndices[a]];
  10.178 +
  10.179 +			face.mIndices[a] = base;
  10.180 +		}
  10.181 +	}
  10.182 +	sMesh.mPositions = vNew;
  10.183 +	sMesh.mTexCoords = vNew2;
  10.184 +}
  10.185 +
  10.186 +// ------------------------------------------------------------------------------------------------
  10.187 +// Convert a 3DS texture to texture keys in an aiMaterial
  10.188 +void CopyTexture(aiMaterial& mat, D3DS::Texture& texture, aiTextureType type)
  10.189 +{
  10.190 +	// Setup the texture name
  10.191 +	aiString tex;
  10.192 +	tex.Set( texture.mMapName);
  10.193 +	mat.AddProperty( &tex, AI_MATKEY_TEXTURE(type,0));
  10.194 +
  10.195 +	// Setup the texture blend factor
  10.196 +	if (is_not_qnan(texture.mTextureBlend))
  10.197 +		mat.AddProperty<float>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
  10.198 +
  10.199 +	// Setup the texture mapping mode
  10.200 +	mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
  10.201 +	mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0));
  10.202 +
  10.203 +	// Mirroring - double the scaling values 
  10.204 +	// FIXME: this is not really correct ...
  10.205 +	if (texture.mMapMode == aiTextureMapMode_Mirror)
  10.206 +	{
  10.207 +		texture.mScaleU *= 2.f;
  10.208 +		texture.mScaleV *= 2.f;
  10.209 +		texture.mOffsetU /= 2.f;
  10.210 +		texture.mOffsetV /= 2.f;
  10.211 +	}
  10.212 +	
  10.213 +	// Setup texture UV transformations
  10.214 +	mat.AddProperty<float>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
  10.215 +}
  10.216 +
  10.217 +// ------------------------------------------------------------------------------------------------
  10.218 +// Convert a 3DS material to an aiMaterial
  10.219 +void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
  10.220 +	aiMaterial& mat)
  10.221 +{
  10.222 +	// NOTE: Pass the background image to the viewer by bypassing the
  10.223 +	// material system. This is an evil hack, never do it again!
  10.224 +	if (0 != mBackgroundImage.length() && bHasBG)
  10.225 +	{
  10.226 +		aiString tex;
  10.227 +		tex.Set( mBackgroundImage);
  10.228 +		mat.AddProperty( &tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
  10.229 +
  10.230 +		// Be sure this is only done for the first material
  10.231 +		mBackgroundImage = std::string("");
  10.232 +	}
  10.233 +
  10.234 +	// At first add the base ambient color of the scene to the material
  10.235 +	oldMat.mAmbient.r += mClrAmbient.r;
  10.236 +	oldMat.mAmbient.g += mClrAmbient.g;
  10.237 +	oldMat.mAmbient.b += mClrAmbient.b;
  10.238 +
  10.239 +	aiString name;
  10.240 +	name.Set( oldMat.mName);
  10.241 +	mat.AddProperty( &name, AI_MATKEY_NAME);
  10.242 +
  10.243 +	// Material colors
  10.244 +	mat.AddProperty( &oldMat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
  10.245 +	mat.AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
  10.246 +	mat.AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
  10.247 +	mat.AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
  10.248 +
  10.249 +	// Phong shininess and shininess strength
  10.250 +	if (D3DS::Discreet3DS::Phong == oldMat.mShading || 
  10.251 +		D3DS::Discreet3DS::Metal == oldMat.mShading)
  10.252 +	{
  10.253 +		if (!oldMat.mSpecularExponent || !oldMat.mShininessStrength)
  10.254 +		{
  10.255 +			oldMat.mShading = D3DS::Discreet3DS::Gouraud;
  10.256 +		}
  10.257 +		else
  10.258 +		{
  10.259 +			mat.AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
  10.260 +			mat.AddProperty( &oldMat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
  10.261 +		}
  10.262 +	}
  10.263 +
  10.264 +	// Opacity
  10.265 +	mat.AddProperty<float>( &oldMat.mTransparency,1,AI_MATKEY_OPACITY);
  10.266 +
  10.267 +	// Bump height scaling
  10.268 +	mat.AddProperty<float>( &oldMat.mBumpHeight,1,AI_MATKEY_BUMPSCALING);
  10.269 +
  10.270 +	// Two sided rendering?
  10.271 +	if (oldMat.mTwoSided)
  10.272 +	{
  10.273 +		int i = 1;
  10.274 +		mat.AddProperty<int>(&i,1,AI_MATKEY_TWOSIDED);
  10.275 +	}
  10.276 +
  10.277 +	// Shading mode
  10.278 +	aiShadingMode eShading = aiShadingMode_NoShading;
  10.279 +	switch (oldMat.mShading)
  10.280 +	{
  10.281 +		case D3DS::Discreet3DS::Flat:
  10.282 +			eShading = aiShadingMode_Flat; break;
  10.283 +
  10.284 +		// I don't know what "Wire" shading should be,
  10.285 +		// assume it is simple lambertian diffuse shading
  10.286 +		case D3DS::Discreet3DS::Wire:
  10.287 +			{
  10.288 +				// Set the wireframe flag
  10.289 +				unsigned int iWire = 1;
  10.290 +				mat.AddProperty<int>( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME);
  10.291 +			}
  10.292 +
  10.293 +		case D3DS::Discreet3DS::Gouraud:
  10.294 +			eShading = aiShadingMode_Gouraud; break;
  10.295 +
  10.296 +		// assume cook-torrance shading for metals.
  10.297 +		case D3DS::Discreet3DS::Phong :
  10.298 +			eShading = aiShadingMode_Phong; break;
  10.299 +
  10.300 +		case D3DS::Discreet3DS::Metal :
  10.301 +			eShading = aiShadingMode_CookTorrance; break;
  10.302 +
  10.303 +			// FIX to workaround a warning with GCC 4 who complained
  10.304 +			// about a missing case Blinn: here - Blinn isn't a valid
  10.305 +			// value in the 3DS Loader, it is just needed for ASE
  10.306 +		case D3DS::Discreet3DS::Blinn :
  10.307 +			eShading = aiShadingMode_Blinn; break;
  10.308 +	}
  10.309 +	mat.AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
  10.310 +
  10.311 +	// DIFFUSE texture
  10.312 +	if( oldMat.sTexDiffuse.mMapName.length() > 0)
  10.313 +		CopyTexture(mat,oldMat.sTexDiffuse, aiTextureType_DIFFUSE);
  10.314 +
  10.315 +	// SPECULAR texture
  10.316 +	if( oldMat.sTexSpecular.mMapName.length() > 0)
  10.317 +		CopyTexture(mat,oldMat.sTexSpecular, aiTextureType_SPECULAR);
  10.318 +
  10.319 +	// OPACITY texture
  10.320 +	if( oldMat.sTexOpacity.mMapName.length() > 0)
  10.321 +		CopyTexture(mat,oldMat.sTexOpacity, aiTextureType_OPACITY);
  10.322 +
  10.323 +	// EMISSIVE texture
  10.324 +	if( oldMat.sTexEmissive.mMapName.length() > 0)
  10.325 +		CopyTexture(mat,oldMat.sTexEmissive, aiTextureType_EMISSIVE);
  10.326 +
  10.327 +	// BUMP texture
  10.328 +	if( oldMat.sTexBump.mMapName.length() > 0)
  10.329 +		CopyTexture(mat,oldMat.sTexBump, aiTextureType_HEIGHT);
  10.330 +
  10.331 +	// SHININESS texture
  10.332 +	if( oldMat.sTexShininess.mMapName.length() > 0)
  10.333 +		CopyTexture(mat,oldMat.sTexShininess, aiTextureType_SHININESS);
  10.334 +
  10.335 +	// REFLECTION texture
  10.336 +	if( oldMat.sTexReflective.mMapName.length() > 0)
  10.337 +		CopyTexture(mat,oldMat.sTexReflective, aiTextureType_REFLECTION);
  10.338 +
  10.339 +	// Store the name of the material itself, too
  10.340 +	if( oldMat.mName.length())	{
  10.341 +		aiString tex;
  10.342 +		tex.Set( oldMat.mName);
  10.343 +		mat.AddProperty( &tex, AI_MATKEY_NAME);
  10.344 +	}
  10.345 +}
  10.346 +
  10.347 +// ------------------------------------------------------------------------------------------------
  10.348 +// Split meshes by their materials and generate output aiMesh'es
  10.349 +void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut)
  10.350 +{
  10.351 +	std::vector<aiMesh*> avOutMeshes;
  10.352 +	avOutMeshes.reserve(mScene->mMeshes.size() * 2);
  10.353 +
  10.354 +	unsigned int iFaceCnt = 0,num = 0;
  10.355 +	aiString name;
  10.356 +
  10.357 +	// we need to split all meshes by their materials
  10.358 +	for (std::vector<D3DS::Mesh>::iterator i =  mScene->mMeshes.begin(); i != mScene->mMeshes.end();++i)	{
  10.359 +		boost::scoped_array< std::vector<unsigned int> > aiSplit(new std::vector<unsigned int>[mScene->mMaterials.size()]);
  10.360 +
  10.361 +		name.length = ASSIMP_itoa10(name.data,num++);
  10.362 +
  10.363 +		unsigned int iNum = 0;
  10.364 +		for (std::vector<unsigned int>::const_iterator a =  (*i).mFaceMaterials.begin();
  10.365 +			a != (*i).mFaceMaterials.end();++a,++iNum)
  10.366 +		{
  10.367 +			aiSplit[*a].push_back(iNum);
  10.368 +		}
  10.369 +		// now generate submeshes
  10.370 +		for (unsigned int p = 0; p < mScene->mMaterials.size();++p)
  10.371 +		{
  10.372 +			if (aiSplit[p].empty())	{
  10.373 +				continue;
  10.374 +			}
  10.375 +			aiMesh* meshOut = new aiMesh();
  10.376 +			meshOut->mName = name;
  10.377 +			meshOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
  10.378 +
  10.379 +			// be sure to setup the correct material index
  10.380 +			meshOut->mMaterialIndex = p;
  10.381 +
  10.382 +			// use the color data as temporary storage
  10.383 +			meshOut->mColors[0] = (aiColor4D*)(&*i);
  10.384 +			avOutMeshes.push_back(meshOut);
  10.385 +
  10.386 +			// convert vertices
  10.387 +			meshOut->mNumFaces = (unsigned int)aiSplit[p].size();
  10.388 +			meshOut->mNumVertices = meshOut->mNumFaces*3;
  10.389 +
  10.390 +			// allocate enough storage for faces
  10.391 +			meshOut->mFaces = new aiFace[meshOut->mNumFaces];
  10.392 +			iFaceCnt += meshOut->mNumFaces;
  10.393 +
  10.394 +			meshOut->mVertices = new aiVector3D[meshOut->mNumVertices];
  10.395 +			meshOut->mNormals  = new aiVector3D[meshOut->mNumVertices];
  10.396 +			if ((*i).mTexCoords.size())
  10.397 +			{
  10.398 +				meshOut->mTextureCoords[0] = new aiVector3D[meshOut->mNumVertices];
  10.399 +			}
  10.400 +			for (unsigned int q = 0, base = 0; q < aiSplit[p].size();++q)
  10.401 +			{
  10.402 +				register unsigned int index = aiSplit[p][q];
  10.403 +				aiFace& face = meshOut->mFaces[q];
  10.404 +
  10.405 +				face.mIndices = new unsigned int[3];
  10.406 +				face.mNumIndices = 3;
  10.407 +
  10.408 +				for (unsigned int a = 0; a < 3;++a,++base)
  10.409 +				{
  10.410 +					unsigned int idx = (*i).mFaces[index].mIndices[a];
  10.411 +					meshOut->mVertices[base]  = (*i).mPositions[idx];
  10.412 +					meshOut->mNormals [base]  = (*i).mNormals[idx];
  10.413 +
  10.414 +					if ((*i).mTexCoords.size())
  10.415 +						meshOut->mTextureCoords[0][base] = (*i).mTexCoords[idx];
  10.416 +
  10.417 +					face.mIndices[a] = base;
  10.418 +				}
  10.419 +			}
  10.420 +		}
  10.421 +	}
  10.422 +
  10.423 +	// Copy them to the output array
  10.424 +	pcOut->mNumMeshes = (unsigned int)avOutMeshes.size();
  10.425 +	pcOut->mMeshes = new aiMesh*[pcOut->mNumMeshes]();
  10.426 +	for (unsigned int a = 0; a < pcOut->mNumMeshes;++a) {
  10.427 +		pcOut->mMeshes[a] = avOutMeshes[a];
  10.428 +	}
  10.429 +
  10.430 +	// We should have at least one face here
  10.431 +	if (!iFaceCnt) {
  10.432 +		throw DeadlyImportError("No faces loaded. The mesh is empty");
  10.433 +	}
  10.434 +}
  10.435 +
  10.436 +// ------------------------------------------------------------------------------------------------
  10.437 +// Add a node to the scenegraph and setup its final transformation
  10.438 +void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
  10.439 +	D3DS::Node* pcIn, aiMatrix4x4& /*absTrafo*/)
  10.440 +{
  10.441 +	std::vector<unsigned int> iArray;
  10.442 +	iArray.reserve(3);
  10.443 +
  10.444 +	aiMatrix4x4 abs;
  10.445 +
  10.446 +	// Find all meshes with the same name as the node
  10.447 +	for (unsigned int a = 0; a < pcSOut->mNumMeshes;++a)
  10.448 +	{
  10.449 +		const D3DS::Mesh* pcMesh = (const D3DS::Mesh*)pcSOut->mMeshes[a]->mColors[0];
  10.450 +		ai_assert(NULL != pcMesh);
  10.451 +
  10.452 +		if (pcIn->mName == pcMesh->mName)
  10.453 +			iArray.push_back(a);
  10.454 +	}
  10.455 +	if (!iArray.empty())
  10.456 +	{
  10.457 +		// The matrix should be identical for all meshes with the 
  10.458 +		// same name. It HAS to be identical for all meshes .....
  10.459 +		D3DS::Mesh* imesh = ((D3DS::Mesh*)pcSOut->mMeshes[iArray[0]]->mColors[0]);
  10.460 +
  10.461 +		// Compute the inverse of the transformation matrix to move the
  10.462 +		// vertices back to their relative and local space
  10.463 +		aiMatrix4x4 mInv = imesh->mMat, mInvTransposed = imesh->mMat;
  10.464 +		mInv.Inverse();mInvTransposed.Transpose();
  10.465 +		aiVector3D pivot = pcIn->vPivot;
  10.466 +
  10.467 +		pcOut->mNumMeshes = (unsigned int)iArray.size();
  10.468 +		pcOut->mMeshes = new unsigned int[iArray.size()];
  10.469 +		for (unsigned int i = 0;i < iArray.size();++i)	{
  10.470 +			const unsigned int iIndex = iArray[i];
  10.471 +			aiMesh* const mesh = pcSOut->mMeshes[iIndex];
  10.472 +
  10.473 +			// Transform the vertices back into their local space
  10.474 +			// fixme: consider computing normals after this, so we don't need to transform them
  10.475 +			const aiVector3D* const pvEnd = mesh->mVertices+mesh->mNumVertices;
  10.476 +			aiVector3D* pvCurrent = mesh->mVertices, *t2 = mesh->mNormals;
  10.477 +
  10.478 +			for (;pvCurrent != pvEnd;++pvCurrent,++t2) {
  10.479 +				*pvCurrent = mInv * (*pvCurrent);
  10.480 +				*t2 = mInvTransposed * (*t2);
  10.481 +			}
  10.482 +
  10.483 +			// Handle negative transformation matrix determinant -> invert vertex x
  10.484 +			if (imesh->mMat.Determinant() < 0.0f)
  10.485 +			{
  10.486 +				/* we *must* have normals */
  10.487 +				for (pvCurrent = mesh->mVertices,t2 = mesh->mNormals;pvCurrent != pvEnd;++pvCurrent,++t2) {
  10.488 +					pvCurrent->x *= -1.f;
  10.489 +					t2->x *= -1.f;
  10.490 +				}
  10.491 +				DefaultLogger::get()->info("3DS: Flipping mesh X-Axis");
  10.492 +			}
  10.493 +
  10.494 +			// Handle pivot point
  10.495 +			if(pivot.x || pivot.y || pivot.z)
  10.496 +			{
  10.497 +				for (pvCurrent = mesh->mVertices;pvCurrent != pvEnd;++pvCurrent)	{
  10.498 +					*pvCurrent -= pivot;	
  10.499 +				}
  10.500 +			}
  10.501 +
  10.502 +			// Setup the mesh index
  10.503 +			pcOut->mMeshes[i] = iIndex;
  10.504 +		}
  10.505 +	}
  10.506 +
  10.507 +	// Setup the name of the node
  10.508 +	pcOut->mName.Set(pcIn->mName);
  10.509 +
  10.510 +	// Now build the transformation matrix of the node
  10.511 +	// ROTATION
  10.512 +	if (pcIn->aRotationKeys.size()){
  10.513 +
  10.514 +		// FIX to get to Assimp's quaternion conventions
  10.515 +		for (std::vector<aiQuatKey>::iterator it = pcIn->aRotationKeys.begin(); it != pcIn->aRotationKeys.end(); ++it) {
  10.516 +			(*it).mValue.w *= -1.f;
  10.517 +		}
  10.518 +
  10.519 +		pcOut->mTransformation = aiMatrix4x4( pcIn->aRotationKeys[0].mValue.GetMatrix() );
  10.520 +	}
  10.521 +	else if (pcIn->aCameraRollKeys.size()) 
  10.522 +	{
  10.523 +		aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(- pcIn->aCameraRollKeys[0].mValue),
  10.524 +			pcOut->mTransformation);
  10.525 +	}
  10.526 +
  10.527 +	// SCALING
  10.528 +	aiMatrix4x4& m = pcOut->mTransformation;
  10.529 +	if (pcIn->aScalingKeys.size())
  10.530 +	{
  10.531 +		const aiVector3D& v = pcIn->aScalingKeys[0].mValue;
  10.532 +		m.a1 *= v.x; m.b1 *= v.x; m.c1 *= v.x;
  10.533 +		m.a2 *= v.y; m.b2 *= v.y; m.c2 *= v.y;
  10.534 +		m.a3 *= v.z; m.b3 *= v.z; m.c3 *= v.z;
  10.535 +	}
  10.536 +
  10.537 +	// TRANSLATION
  10.538 +	if (pcIn->aPositionKeys.size())
  10.539 +	{
  10.540 +		const aiVector3D& v = pcIn->aPositionKeys[0].mValue;
  10.541 +		m.a4 += v.x;
  10.542 +		m.b4 += v.y;
  10.543 +		m.c4 += v.z;
  10.544 +	}
  10.545 +
  10.546 +	// Generate animation channels for the node
  10.547 +	if (pcIn->aPositionKeys.size()  > 1  || pcIn->aRotationKeys.size()   > 1 ||
  10.548 +		pcIn->aScalingKeys.size()   > 1  || pcIn->aCameraRollKeys.size() > 1 ||
  10.549 +		pcIn->aTargetPositionKeys.size() > 1)
  10.550 +	{
  10.551 +		aiAnimation* anim = pcSOut->mAnimations[0];
  10.552 +		ai_assert(NULL != anim);
  10.553 +
  10.554 +		if (pcIn->aCameraRollKeys.size() > 1)
  10.555 +		{
  10.556 +			DefaultLogger::get()->debug("3DS: Converting camera roll track ...");
  10.557 +
  10.558 +			// Camera roll keys - in fact they're just rotations
  10.559 +			// around the camera's z axis. The angles are given
  10.560 +			// in degrees (and they're clockwise).
  10.561 +			pcIn->aRotationKeys.resize(pcIn->aCameraRollKeys.size());
  10.562 +			for (unsigned int i = 0; i < pcIn->aCameraRollKeys.size();++i)
  10.563 +			{
  10.564 +				aiQuatKey&  q = pcIn->aRotationKeys[i];
  10.565 +				aiFloatKey& f = pcIn->aCameraRollKeys[i];
  10.566 +
  10.567 +				q.mTime  = f.mTime;
  10.568 +
  10.569 +				// FIX to get to Assimp quaternion conventions
  10.570 +				q.mValue = aiQuaternion(0.f,0.f,AI_DEG_TO_RAD( /*-*/ f.mValue));
  10.571 +			}
  10.572 +		}
  10.573 +#if 0
  10.574 +		if (pcIn->aTargetPositionKeys.size() > 1)
  10.575 +		{
  10.576 +			DefaultLogger::get()->debug("3DS: Converting target track ...");
  10.577 +
  10.578 +			// Camera or spot light - need to convert the separate
  10.579 +			// target position channel to our representation
  10.580 +			TargetAnimationHelper helper;
  10.581 +
  10.582 +			if (pcIn->aPositionKeys.empty())
  10.583 +			{
  10.584 +				// We can just pass zero here ...
  10.585 +				helper.SetFixedMainAnimationChannel(aiVector3D());
  10.586 +			}
  10.587 +			else  helper.SetMainAnimationChannel(&pcIn->aPositionKeys);
  10.588 +			helper.SetTargetAnimationChannel(&pcIn->aTargetPositionKeys);
  10.589 +
  10.590 +			// Do the conversion
  10.591 +			std::vector<aiVectorKey> distanceTrack;
  10.592 +			helper.Process(&distanceTrack);
  10.593 +
  10.594 +			// Now add a new node as child, name it <ourName>.Target
  10.595 +			// and assign the distance track to it. This is that the
  10.596 +			// information where the target is and how it moves is
  10.597 +			// not lost
  10.598 +			D3DS::Node* nd = new D3DS::Node();
  10.599 +			pcIn->push_back(nd);
  10.600 +
  10.601 +			nd->mName = pcIn->mName + ".Target";
  10.602 +
  10.603 +			aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
  10.604 +			nda->mNodeName.Set(nd->mName);
  10.605 +
  10.606 +			nda->mNumPositionKeys = (unsigned int)distanceTrack.size();
  10.607 +			nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
  10.608 +			::memcpy(nda->mPositionKeys,&distanceTrack[0],
  10.609 +				sizeof(aiVectorKey)*nda->mNumPositionKeys);
  10.610 +		}
  10.611 +#endif
  10.612 +
  10.613 +		// Cameras or lights define their transformation in their parent node and in the
  10.614 +		// corresponding light or camera chunks. However, we read and process the latter
  10.615 +		// to to be able to return valid cameras/lights even if no scenegraph is given.
  10.616 +		for (unsigned int n = 0; n < pcSOut->mNumCameras;++n)	{
  10.617 +			if (pcSOut->mCameras[n]->mName == pcOut->mName) {
  10.618 +				pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f,0.f,1.f);
  10.619 +			}
  10.620 +		}
  10.621 +		for (unsigned int n = 0; n < pcSOut->mNumLights;++n)	{
  10.622 +			if (pcSOut->mLights[n]->mName == pcOut->mName) {
  10.623 +				pcSOut->mLights[n]->mDirection = aiVector3D(0.f,0.f,1.f);
  10.624 +			}
  10.625 +		}
  10.626 +
  10.627 +		// Allocate a new node anim and setup its name
  10.628 +		aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
  10.629 +		nda->mNodeName.Set(pcIn->mName);
  10.630 +
  10.631 +		// POSITION keys
  10.632 +		if (pcIn->aPositionKeys.size()  > 0)
  10.633 +		{
  10.634 +			nda->mNumPositionKeys = (unsigned int)pcIn->aPositionKeys.size();
  10.635 +			nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
  10.636 +			::memcpy(nda->mPositionKeys,&pcIn->aPositionKeys[0],
  10.637 +				sizeof(aiVectorKey)*nda->mNumPositionKeys);
  10.638 +		}
  10.639 +
  10.640 +		// ROTATION keys
  10.641 +		if (pcIn->aRotationKeys.size()  > 0)
  10.642 +		{
  10.643 +			nda->mNumRotationKeys = (unsigned int)pcIn->aRotationKeys.size();
  10.644 +			nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
  10.645 +
  10.646 +			// Rotations are quaternion offsets
  10.647 +			aiQuaternion abs;
  10.648 +			for (unsigned int n = 0; n < nda->mNumRotationKeys;++n)
  10.649 +			{
  10.650 +				const aiQuatKey& q = pcIn->aRotationKeys[n];
  10.651 +
  10.652 +				abs = (n ? abs * q.mValue : q.mValue);
  10.653 +				nda->mRotationKeys[n].mTime  = q.mTime;
  10.654 +				nda->mRotationKeys[n].mValue = abs.Normalize();
  10.655 +			}
  10.656 +		}
  10.657 +
  10.658 +		// SCALING keys
  10.659 +		if (pcIn->aScalingKeys.size()  > 0)
  10.660 +		{
  10.661 +			nda->mNumScalingKeys = (unsigned int)pcIn->aScalingKeys.size();
  10.662 +			nda->mScalingKeys = new aiVectorKey[nda->mNumScalingKeys];
  10.663 +			::memcpy(nda->mScalingKeys,&pcIn->aScalingKeys[0],
  10.664 +				sizeof(aiVectorKey)*nda->mNumScalingKeys);
  10.665 +		}
  10.666 +	}
  10.667 +
  10.668 +	// Allocate storage for children 
  10.669 +	pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
  10.670 +	pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
  10.671 +
  10.672 +	// Recursively process all children
  10.673 +	const unsigned int size = pcIn->mChildren.size();
  10.674 +	for (unsigned int i = 0; i < size;++i)
  10.675 +	{
  10.676 +		pcOut->mChildren[i] = new aiNode();
  10.677 +		pcOut->mChildren[i]->mParent = pcOut;
  10.678 +		AddNodeToGraph(pcSOut,pcOut->mChildren[i],pcIn->mChildren[i],abs);
  10.679 +	}
  10.680 +}
  10.681 +
  10.682 +// ------------------------------------------------------------------------------------------------
  10.683 +// Find out how many node animation channels we'll have finally
  10.684 +void CountTracks(D3DS::Node* node, unsigned int& cnt)
  10.685 +{
  10.686 +	//////////////////////////////////////////////////////////////////////////////
  10.687 +	// We will never generate more than one channel for a node, so
  10.688 +	// this is rather easy here.
  10.689 +
  10.690 +	if (node->aPositionKeys.size()  > 1  || node->aRotationKeys.size()   > 1   ||
  10.691 +		node->aScalingKeys.size()   > 1  || node->aCameraRollKeys.size() > 1 ||
  10.692 +		node->aTargetPositionKeys.size()  > 1)
  10.693 +	{
  10.694 +		++cnt;
  10.695 +
  10.696 +		// account for the additional channel for the camera/spotlight target position
  10.697 +		if (node->aTargetPositionKeys.size()  > 1)++cnt;
  10.698 +	}
  10.699 +
  10.700 +	// Recursively process all children
  10.701 +	for (unsigned int i = 0; i < node->mChildren.size();++i)
  10.702 +		CountTracks(node->mChildren[i],cnt);
  10.703 +}
  10.704 +
  10.705 +// ------------------------------------------------------------------------------------------------
  10.706 +// Generate the output node graph
  10.707 +void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
  10.708 +{
  10.709 +	pcOut->mRootNode = new aiNode();
  10.710 +	if (0 == mRootNode->mChildren.size())
  10.711 +	{
  10.712 +		//////////////////////////////////////////////////////////////////////////////
  10.713 +		// It seems the file is so messed up that it has not even a hierarchy.
  10.714 +		// generate a flat hiearachy which looks like this:
  10.715 +		//
  10.716 +		//                ROOT_NODE
  10.717 +		//                   |
  10.718 +		//   ----------------------------------------
  10.719 +		//   |       |       |            |         |  
  10.720 +		// MESH_0  MESH_1  MESH_2  ...  MESH_N    CAMERA_0 ....
  10.721 +		//
  10.722 +		DefaultLogger::get()->warn("No hierarchy information has been found in the file. ");
  10.723 +
  10.724 +		pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes + 
  10.725 +			mScene->mCameras.size() + mScene->mLights.size();
  10.726 +
  10.727 +		pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mRootNode->mNumChildren ];
  10.728 +		pcOut->mRootNode->mName.Set("<3DSDummyRoot>");
  10.729 +
  10.730 +		// Build dummy nodes for all meshes
  10.731 +		unsigned int a = 0;
  10.732 +		for (unsigned int i = 0; i < pcOut->mNumMeshes;++i,++a)
  10.733 +		{
  10.734 +			aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
  10.735 +			pcNode->mParent = pcOut->mRootNode;
  10.736 +			pcNode->mMeshes = new unsigned int[1];
  10.737 +			pcNode->mMeshes[0] = i;
  10.738 +			pcNode->mNumMeshes = 1;
  10.739 +
  10.740 +			// Build a name for the node
  10.741 +			pcNode->mName.length = sprintf(pcNode->mName.data,"3DSMesh_%i",i);	
  10.742 +		}
  10.743 +
  10.744 +		// Build dummy nodes for all cameras
  10.745 +		for (unsigned int i = 0; i < (unsigned int )mScene->mCameras.size();++i,++a)
  10.746 +		{
  10.747 +			aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
  10.748 +			pcNode->mParent = pcOut->mRootNode;
  10.749 +
  10.750 +			// Build a name for the node
  10.751 +			pcNode->mName = mScene->mCameras[i]->mName;
  10.752 +		}
  10.753 +
  10.754 +		// Build dummy nodes for all lights
  10.755 +		for (unsigned int i = 0; i < (unsigned int )mScene->mLights.size();++i,++a)
  10.756 +		{
  10.757 +			aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
  10.758 +			pcNode->mParent = pcOut->mRootNode;
  10.759 +
  10.760 +			// Build a name for the node
  10.761 +			pcNode->mName = mScene->mLights[i]->mName;
  10.762 +		}
  10.763 +	}
  10.764 +	else
  10.765 +	{
  10.766 +		// First of all: find out how many scaling, rotation and translation
  10.767 +		// animation tracks we'll have afterwards
  10.768 +		unsigned int numChannel = 0;
  10.769 +		CountTracks(mRootNode,numChannel);
  10.770 +
  10.771 +		if (numChannel)
  10.772 +		{
  10.773 +			// Allocate a primary animation channel
  10.774 +			pcOut->mNumAnimations = 1;
  10.775 +			pcOut->mAnimations    = new aiAnimation*[1];
  10.776 +			aiAnimation* anim     = pcOut->mAnimations[0] = new aiAnimation();
  10.777 +
  10.778 +			anim->mName.Set("3DSMasterAnim");
  10.779 +
  10.780 +			// Allocate enough storage for all node animation channels, 
  10.781 +			// but don't set the mNumChannels member - we'll use it to
  10.782 +			// index into the array
  10.783 +			anim->mChannels = new aiNodeAnim*[numChannel];
  10.784 +		}
  10.785 +
  10.786 +		aiMatrix4x4 m;
  10.787 +		AddNodeToGraph(pcOut,  pcOut->mRootNode, mRootNode,m);
  10.788 +	}
  10.789 +
  10.790 +	// We used the first vertex color set to store some emporary values so we need to cleanup here
  10.791 +	for (unsigned int a = 0; a < pcOut->mNumMeshes;++a)
  10.792 +		pcOut->mMeshes[a]->mColors[0] = NULL;
  10.793 +
  10.794 +	pcOut->mRootNode->mTransformation = aiMatrix4x4(
  10.795 +		1.f,0.f,0.f,0.f,
  10.796 +		0.f,0.f,1.f,0.f,
  10.797 +		0.f,-1.f,0.f,0.f,
  10.798 +		0.f,0.f,0.f,1.f) * pcOut->mRootNode->mTransformation;
  10.799 +
  10.800 +	// If the root node is unnamed name it "<3DSRoot>"
  10.801 +	if (::strstr( pcOut->mRootNode->mName.data, "UNNAMED" ) ||
  10.802 +		(pcOut->mRootNode->mName.data[0] == '$' && pcOut->mRootNode->mName.data[1] == '$') )
  10.803 +	{
  10.804 +		pcOut->mRootNode->mName.Set("<3DSRoot>");
  10.805 +	}
  10.806 +}
  10.807 +
  10.808 +// ------------------------------------------------------------------------------------------------
  10.809 +// Convert all meshes in the scene and generate the final output scene.
  10.810 +void Discreet3DSImporter::ConvertScene(aiScene* pcOut)
  10.811 +{
  10.812 +	// Allocate enough storage for all output materials
  10.813 +	pcOut->mNumMaterials = (unsigned int)mScene->mMaterials.size();
  10.814 +	pcOut->mMaterials    = new aiMaterial*[pcOut->mNumMaterials];
  10.815 +
  10.816 +	//  ... and convert the 3DS materials to aiMaterial's
  10.817 +	for (unsigned int i = 0; i < pcOut->mNumMaterials;++i)
  10.818 +	{
  10.819 +		aiMaterial* pcNew = new aiMaterial();
  10.820 +		ConvertMaterial(mScene->mMaterials[i],*pcNew);
  10.821 +		pcOut->mMaterials[i] = pcNew;
  10.822 +	}
  10.823 +
  10.824 +	// Generate the output mesh list
  10.825 +	ConvertMeshes(pcOut);
  10.826 +
  10.827 +	// Now copy all light sources to the output scene
  10.828 +	pcOut->mNumLights = (unsigned int)mScene->mLights.size();
  10.829 +	if (pcOut->mNumLights)
  10.830 +	{
  10.831 +		pcOut->mLights = new aiLight*[pcOut->mNumLights];
  10.832 +		::memcpy(pcOut->mLights,&mScene->mLights[0],sizeof(void*)*pcOut->mNumLights);
  10.833 +	}
  10.834 +
  10.835 +	// Now copy all cameras to the output scene
  10.836 +	pcOut->mNumCameras = (unsigned int)mScene->mCameras.size();
  10.837 +	if (pcOut->mNumCameras)
  10.838 +	{
  10.839 +		pcOut->mCameras = new aiCamera*[pcOut->mNumCameras];
  10.840 +		::memcpy(pcOut->mCameras,&mScene->mCameras[0],sizeof(void*)*pcOut->mNumCameras);
  10.841 +	}
  10.842 +}
  10.843 +
  10.844 +#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/libs/assimp/3DSHelper.h	Sat Feb 01 19:58:19 2014 +0200
    11.3 @@ -0,0 +1,577 @@
    11.4 +/*
    11.5 +Open Asset Import Library (assimp)
    11.6 +----------------------------------------------------------------------
    11.7 +
    11.8 +Copyright (c) 2006-2012, assimp team
    11.9 +All rights reserved.
   11.10 +
   11.11 +Redistribution and use of this software in source and binary forms, 
   11.12 +with or without modification, are permitted provided that the 
   11.13 +following conditions are met:
   11.14 +
   11.15 +* Redistributions of source code must retain the above
   11.16 +  copyright notice, this list of conditions and the
   11.17 +  following disclaimer.
   11.18 +
   11.19 +* Redistributions in binary form must reproduce the above
   11.20 +  copyright notice, this list of conditions and the
   11.21 +  following disclaimer in the documentation and/or other
   11.22 +  materials provided with the distribution.
   11.23 +
   11.24 +* Neither the name of the assimp team, nor the names of its
   11.25 +  contributors may be used to endorse or promote products
   11.26 +  derived from this software without specific prior
   11.27 +  written permission of the assimp team.
   11.28 +
   11.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   11.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   11.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   11.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   11.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   11.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   11.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   11.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   11.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   11.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   11.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   11.40 +
   11.41 +----------------------------------------------------------------------
   11.42 +*/
   11.43 +
   11.44 +/** @file Defines helper data structures for the import of 3DS files */
   11.45 +
   11.46 +#ifndef AI_3DSFILEHELPER_H_INC
   11.47 +#define AI_3DSFILEHELPER_H_INC
   11.48 +
   11.49 +
   11.50 +#include "SpatialSort.h"
   11.51 +#include "SmoothingGroups.h"
   11.52 +
   11.53 +namespace Assimp	{
   11.54 +namespace D3DS	{
   11.55 +
   11.56 +#include "assimp/Compiler/pushpack1.h"
   11.57 +
   11.58 +// ---------------------------------------------------------------------------
   11.59 +/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
   11.60 +*  and data structures.
   11.61 +*/
   11.62 +class Discreet3DS
   11.63 +{
   11.64 +private:
   11.65 +	inline Discreet3DS() {}
   11.66 +
   11.67 +public:
   11.68 +
   11.69 +	//! data structure for a single chunk in a .3ds file
   11.70 +	struct Chunk
   11.71 +	{
   11.72 +		uint16_t	Flag;
   11.73 +		uint32_t	Size;
   11.74 +	} PACK_STRUCT;
   11.75 +
   11.76 +
   11.77 +	//! Used for shading field in material3ds structure
   11.78 +	//! From AutoDesk 3ds SDK
   11.79 +	typedef enum
   11.80 +	{
   11.81 +		// translated to gouraud shading with wireframe active
   11.82 +		Wire = 0x0,
   11.83 +
   11.84 +		// if this material is set, no vertex normals will
   11.85 +		// be calculated for the model. Face normals + gouraud
   11.86 +		Flat = 0x1,
   11.87 +
   11.88 +		// standard gouraud shading
   11.89 +		Gouraud = 0x2,
   11.90 +
   11.91 +		// phong shading
   11.92 +		Phong = 0x3,
   11.93 +
   11.94 +		// cooktorrance or anistropic phong shading ...
   11.95 +		// the exact meaning is unknown, if you know it
   11.96 +		// feel free to tell me ;-)
   11.97 +		Metal = 0x4,
   11.98 +
   11.99 +		// required by the ASE loader
  11.100 +		Blinn = 0x5
  11.101 +	} shadetype3ds;
  11.102 +
  11.103 +	// Flags for animated keys
  11.104 +	enum
  11.105 +	{
  11.106 +		KEY_USE_TENS         = 0x1,
  11.107 +		KEY_USE_CONT         = 0x2,
  11.108 +		KEY_USE_BIAS         = 0x4,
  11.109 +		KEY_USE_EASE_TO      = 0x8,
  11.110 +		KEY_USE_EASE_FROM    = 0x10
  11.111 +	} ;
  11.112 +
  11.113 +	enum 
  11.114 +	{
  11.115 +
  11.116 +		// ********************************************************************
  11.117 +		// Basic chunks which can be found everywhere in the file
  11.118 +		CHUNK_VERSION	= 0x0002,
  11.119 +		CHUNK_RGBF      = 0x0010,		// float4 R; float4 G; float4 B
  11.120 +		CHUNK_RGBB      = 0x0011,		// int1 R; int1 G; int B
  11.121 +
  11.122 +		// Linear color values (gamma = 2.2?)
  11.123 +		CHUNK_LINRGBF      = 0x0013,	// float4 R; float4 G; float4 B
  11.124 +		CHUNK_LINRGBB      = 0x0012,	// int1 R; int1 G; int B
  11.125 +
  11.126 +		CHUNK_PERCENTW	= 0x0030,		// int2   percentage
  11.127 +		CHUNK_PERCENTF	= 0x0031,		// float4  percentage
  11.128 +		// ********************************************************************
  11.129 +
  11.130 +		// Prj master chunk
  11.131 +		CHUNK_PRJ       = 0xC23D,
  11.132 +
  11.133 +		// MDLI master chunk
  11.134 +		CHUNK_MLI       = 0x3DAA,
  11.135 +
  11.136 +		// Primary main chunk of the .3ds file
  11.137 +		CHUNK_MAIN      = 0x4D4D,
  11.138 +
  11.139 +		// Mesh main chunk
  11.140 +		CHUNK_OBJMESH   = 0x3D3D,
  11.141 +
  11.142 +		// Specifies the background color of the .3ds file
  11.143 +		// This is passed through the material system for
  11.144 +		// viewing purposes.
  11.145 +		CHUNK_BKGCOLOR  = 0x1200,
  11.146 +
  11.147 +		// Specifies the ambient base color of the scene.
  11.148 +		// This is added to all materials in the file
  11.149 +		CHUNK_AMBCOLOR  = 0x2100,
  11.150 +
  11.151 +		// Specifies the background image for the whole scene
  11.152 +		// This value is passed through the material system
  11.153 +		// to the viewer 
  11.154 +		CHUNK_BIT_MAP   = 0x1100,
  11.155 +		CHUNK_BIT_MAP_EXISTS  = 0x1101,
  11.156 +
  11.157 +		// ********************************************************************
  11.158 +		// Viewport related stuff. Ignored
  11.159 +		CHUNK_DEFAULT_VIEW = 0x3000,
  11.160 +		CHUNK_VIEW_TOP = 0x3010,
  11.161 +		CHUNK_VIEW_BOTTOM = 0x3020,
  11.162 +		CHUNK_VIEW_LEFT = 0x3030,
  11.163 +		CHUNK_VIEW_RIGHT = 0x3040,
  11.164 +		CHUNK_VIEW_FRONT = 0x3050,
  11.165 +		CHUNK_VIEW_BACK = 0x3060,
  11.166 +		CHUNK_VIEW_USER = 0x3070,
  11.167 +		CHUNK_VIEW_CAMERA = 0x3080,
  11.168 +		// ********************************************************************
  11.169 +
  11.170 +		// Mesh chunks
  11.171 +		CHUNK_OBJBLOCK  = 0x4000,
  11.172 +		CHUNK_TRIMESH   = 0x4100,
  11.173 +		CHUNK_VERTLIST  = 0x4110,
  11.174 +		CHUNK_VERTFLAGS = 0x4111,
  11.175 +		CHUNK_FACELIST  = 0x4120,
  11.176 +		CHUNK_FACEMAT   = 0x4130,
  11.177 +		CHUNK_MAPLIST   = 0x4140,
  11.178 +		CHUNK_SMOOLIST  = 0x4150,
  11.179 +		CHUNK_TRMATRIX  = 0x4160,
  11.180 +		CHUNK_MESHCOLOR = 0x4165,
  11.181 +		CHUNK_TXTINFO   = 0x4170,
  11.182 +		CHUNK_LIGHT     = 0x4600,
  11.183 +		CHUNK_CAMERA    = 0x4700,
  11.184 +		CHUNK_HIERARCHY = 0x4F00,
  11.185 +
  11.186 +		// Specifies the global scaling factor. This is applied
  11.187 +		// to the root node's transformation matrix
  11.188 +		CHUNK_MASTER_SCALE    = 0x0100,
  11.189 +
  11.190 +		// ********************************************************************
  11.191 +		// Material chunks
  11.192 +		CHUNK_MAT_MATERIAL  = 0xAFFF,
  11.193 +
  11.194 +			// asciiz containing the name of the material
  11.195 +			CHUNK_MAT_MATNAME   = 0xA000, 
  11.196 +			CHUNK_MAT_AMBIENT   = 0xA010, // followed by color chunk
  11.197 +			CHUNK_MAT_DIFFUSE   = 0xA020, // followed by color chunk
  11.198 +			CHUNK_MAT_SPECULAR  = 0xA030, // followed by color chunk
  11.199 +
  11.200 +			// Specifies the shininess of the material
  11.201 +			// followed by percentage chunk
  11.202 +			CHUNK_MAT_SHININESS  = 0xA040, 
  11.203 +			CHUNK_MAT_SHININESS_PERCENT  = 0xA041 ,
  11.204 +
  11.205 +			// Specifies the shading mode to be used
  11.206 +			// followed by a short
  11.207 +			CHUNK_MAT_SHADING  = 0xA100, 
  11.208 +
  11.209 +			// NOTE: Emissive color (self illumination) seems not
  11.210 +			// to be a color but a single value, type is unknown.
  11.211 +			// Make the parser accept both of them.
  11.212 +			// followed by percentage chunk (?)
  11.213 +			CHUNK_MAT_SELF_ILLUM = 0xA080,  
  11.214 +
  11.215 +			// Always followed by percentage chunk	(?)
  11.216 +			CHUNK_MAT_SELF_ILPCT = 0xA084,  
  11.217 +
  11.218 +			// Always followed by percentage chunk
  11.219 +			CHUNK_MAT_TRANSPARENCY = 0xA050, 
  11.220 +
  11.221 +			// Diffuse texture channel 0 
  11.222 +			CHUNK_MAT_TEXTURE   = 0xA200,
  11.223 +
  11.224 +			// Contains opacity information for each texel
  11.225 +			CHUNK_MAT_OPACMAP = 0xA210,
  11.226 +
  11.227 +			// Contains a reflection map to be used to reflect
  11.228 +			// the environment. This is partially supported.
  11.229 +			CHUNK_MAT_REFLMAP = 0xA220,
  11.230 +
  11.231 +			// Self Illumination map (emissive colors)
  11.232 +			CHUNK_MAT_SELFIMAP = 0xA33d,	
  11.233 +
  11.234 +			// Bumpmap. Not specified whether it is a heightmap
  11.235 +			// or a normal map. Assme it is a heightmap since
  11.236 +			// artist normally prefer this format.
  11.237 +			CHUNK_MAT_BUMPMAP = 0xA230,
  11.238 +
  11.239 +			// Specular map. Seems to influence the specular color
  11.240 +			CHUNK_MAT_SPECMAP = 0xA204,
  11.241 +
  11.242 +			// Holds shininess data. 
  11.243 +			CHUNK_MAT_MAT_SHINMAP = 0xA33C,
  11.244 +
  11.245 +			// Scaling in U/V direction.
  11.246 +			// (need to gen separate UV coordinate set 
  11.247 +			// and do this by hand)
  11.248 +			CHUNK_MAT_MAP_USCALE 	  = 0xA354,
  11.249 +			CHUNK_MAT_MAP_VSCALE 	  = 0xA356,
  11.250 +
  11.251 +			// Translation in U/V direction.
  11.252 +			// (need to gen separate UV coordinate set 
  11.253 +			// and do this by hand)
  11.254 +			CHUNK_MAT_MAP_UOFFSET 	  = 0xA358,
  11.255 +			CHUNK_MAT_MAP_VOFFSET 	  = 0xA35a,
  11.256 +
  11.257 +			// UV-coordinates rotation around the z-axis
  11.258 +			// Assumed to be in radians.
  11.259 +			CHUNK_MAT_MAP_ANG = 0xA35C,
  11.260 +
  11.261 +			// Tiling flags for 3DS files
  11.262 +			CHUNK_MAT_MAP_TILING = 0xa351,
  11.263 +
  11.264 +			// Specifies the file name of a texture
  11.265 +			CHUNK_MAPFILE   = 0xA300,
  11.266 +
  11.267 +			// Specifies whether a materail requires two-sided rendering
  11.268 +			CHUNK_MAT_TWO_SIDE = 0xA081,  
  11.269 +		// ********************************************************************
  11.270 +
  11.271 +		// Main keyframer chunk. Contains translation/rotation/scaling data
  11.272 +		CHUNK_KEYFRAMER		= 0xB000,
  11.273 +
  11.274 +		// Supported sub chunks
  11.275 +		CHUNK_TRACKINFO		= 0xB002,
  11.276 +		CHUNK_TRACKOBJNAME  = 0xB010,
  11.277 +		CHUNK_TRACKDUMMYOBJNAME  = 0xB011,
  11.278 +		CHUNK_TRACKPIVOT    = 0xB013,
  11.279 +		CHUNK_TRACKPOS      = 0xB020,
  11.280 +		CHUNK_TRACKROTATE   = 0xB021,
  11.281 +		CHUNK_TRACKSCALE    = 0xB022,
  11.282 +
  11.283 +		// ********************************************************************
  11.284 +		// Keyframes for various other stuff in the file
  11.285 +		// Partially ignored
  11.286 +		CHUNK_AMBIENTKEY    = 0xB001,
  11.287 +		CHUNK_TRACKMORPH    = 0xB026,
  11.288 +		CHUNK_TRACKHIDE     = 0xB029,
  11.289 +		CHUNK_OBJNUMBER     = 0xB030,
  11.290 +		CHUNK_TRACKCAMERA	= 0xB003,
  11.291 +		CHUNK_TRACKFOV		= 0xB023,
  11.292 +		CHUNK_TRACKROLL		= 0xB024,
  11.293 +		CHUNK_TRACKCAMTGT	= 0xB004,
  11.294 +		CHUNK_TRACKLIGHT	= 0xB005,
  11.295 +		CHUNK_TRACKLIGTGT	= 0xB006,
  11.296 +		CHUNK_TRACKSPOTL	= 0xB007,
  11.297 +		CHUNK_FRAMES		= 0xB008,
  11.298 +		// ********************************************************************
  11.299 +
  11.300 +		// light sub-chunks
  11.301 +		CHUNK_DL_OFF                 = 0x4620,
  11.302 +		CHUNK_DL_OUTER_RANGE         = 0x465A,
  11.303 +		CHUNK_DL_INNER_RANGE         = 0x4659,
  11.304 +		CHUNK_DL_MULTIPLIER          = 0x465B,
  11.305 +		CHUNK_DL_EXCLUDE             = 0x4654,
  11.306 +		CHUNK_DL_ATTENUATE           = 0x4625,
  11.307 +		CHUNK_DL_SPOTLIGHT           = 0x4610,
  11.308 +
  11.309 +		// camera sub-chunks
  11.310 +		CHUNK_CAM_RANGES             = 0x4720
  11.311 +	};
  11.312 +};
  11.313 +
  11.314 +// ---------------------------------------------------------------------------
  11.315 +/** Helper structure representing a 3ds mesh face */
  11.316 +struct Face : public FaceWithSmoothingGroup
  11.317 +{
  11.318 +};
  11.319 +
  11.320 +// ---------------------------------------------------------------------------
  11.321 +/** Helper structure representing a texture */
  11.322 +struct Texture
  11.323 +{
  11.324 +	//! Default constructor
  11.325 +	Texture()
  11.326 +		: mOffsetU	(0.0f)
  11.327 +		, mOffsetV	(0.0f)
  11.328 +		, mScaleU	(1.0f)
  11.329 +		, mScaleV	(1.0f)
  11.330 +		, mRotation	(0.0f)
  11.331 +		, mMapMode	(aiTextureMapMode_Wrap)
  11.332 +		, iUVSrc	(0)
  11.333 +	{
  11.334 +		mTextureBlend = get_qnan();
  11.335 +	}
  11.336 +
  11.337 +	//! Specifies the blend factor for the texture
  11.338 +	float mTextureBlend;
  11.339 +
  11.340 +	//! Specifies the filename of the texture
  11.341 +	std::string mMapName;
  11.342 +
  11.343 +	//! Specifies texture coordinate offsets/scaling/rotations
  11.344 +	float mOffsetU;
  11.345 +	float mOffsetV;
  11.346 +	float mScaleU;
  11.347 +	float mScaleV;
  11.348 +	float mRotation;
  11.349 +
  11.350 +	//! Specifies the mapping mode to be used for the texture
  11.351 +	aiTextureMapMode mMapMode;
  11.352 +
  11.353 +	//! Used internally
  11.354 +	bool bPrivate;
  11.355 +	int iUVSrc;
  11.356 +};
  11.357 +
  11.358 +#include "assimp/Compiler/poppack1.h"
  11.359 +
  11.360 +// ---------------------------------------------------------------------------
  11.361 +/** Helper structure representing a 3ds material */
  11.362 +struct Material
  11.363 +{
  11.364 +	//! Default constructor. Builds a default name for the material
  11.365 +	Material()
  11.366 +		: 
  11.367 +	mDiffuse			(0.6f,0.6f,0.6f), // FIX ... we won't want object to be black
  11.368 +	mSpecularExponent	(0.0f),
  11.369 +	mShininessStrength	(1.0f),
  11.370 +	mShading(Discreet3DS::Gouraud),
  11.371 +	mTransparency		(1.0f),
  11.372 +	mBumpHeight			(1.0f),
  11.373 +	mTwoSided			(false)
  11.374 +	{
  11.375 +		static int iCnt = 0;
  11.376 +		
  11.377 +		char szTemp[128];
  11.378 +		sprintf(szTemp,"UNNAMED_%i",iCnt++);
  11.379 +		mName = szTemp;
  11.380 +	}
  11.381 +
  11.382 +	//! Name of the material
  11.383 +	std::string mName;
  11.384 +	//! Diffuse color of the material
  11.385 +	aiColor3D mDiffuse;
  11.386 +	//! Specular exponent
  11.387 +	float mSpecularExponent;
  11.388 +	//! Shininess strength, in percent
  11.389 +	float mShininessStrength;
  11.390 +	//! Specular color of the material
  11.391 +	aiColor3D mSpecular;
  11.392 +	//! Ambient color of the material
  11.393 +	aiColor3D mAmbient;
  11.394 +	//! Shading type to be used
  11.395 +	Discreet3DS::shadetype3ds mShading;
  11.396 +	//! Opacity of the material
  11.397 +	float mTransparency;
  11.398 +	//! Diffuse texture channel
  11.399 +	Texture sTexDiffuse;
  11.400 +	//! Opacity texture channel
  11.401 +	Texture sTexOpacity;
  11.402 +	//! Specular texture channel
  11.403 +	Texture sTexSpecular;
  11.404 +	//! Reflective texture channel
  11.405 +	Texture sTexReflective;
  11.406 +	//! Bump texture channel
  11.407 +	Texture sTexBump;
  11.408 +	//! Emissive texture channel
  11.409 +	Texture sTexEmissive;
  11.410 +	//! Shininess texture channel
  11.411 +	Texture sTexShininess;
  11.412 +	//! Scaling factor for the bump values
  11.413 +	float mBumpHeight;
  11.414 +	//! Emissive color
  11.415 +	aiColor3D mEmissive;
  11.416 +	//! Ambient texture channel
  11.417 +	//! (used by the ASE format)
  11.418 +	Texture sTexAmbient;
  11.419 +	//! True if the material must be rendered from two sides
  11.420 +	bool mTwoSided;
  11.421 +};
  11.422 +
  11.423 +// ---------------------------------------------------------------------------
  11.424 +/** Helper structure to represent a 3ds file mesh */
  11.425 +struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
  11.426 +{
  11.427 +	//! Default constructor
  11.428 +	Mesh()
  11.429 +	{
  11.430 +		static int iCnt = 0;
  11.431 +		
  11.432 +		// Generate a default name for the mesh
  11.433 +		char szTemp[128];
  11.434 +		::sprintf(szTemp,"UNNAMED_%i",iCnt++);
  11.435 +		mName = szTemp;
  11.436 +	}
  11.437 +
  11.438 +	//! Name of the mesh
  11.439 +	std::string mName;
  11.440 +
  11.441 +	//! Texture coordinates
  11.442 +	std::vector<aiVector3D> mTexCoords;
  11.443 +
  11.444 +	//! Face materials
  11.445 +	std::vector<unsigned int> mFaceMaterials;
  11.446 +
  11.447 +	//! Local transformation matrix
  11.448 +	aiMatrix4x4 mMat;
  11.449 +};
  11.450 +
  11.451 +// ---------------------------------------------------------------------------
  11.452 +/** Float key - quite similar to aiVectorKey and aiQuatKey. Both are in the
  11.453 +    C-API, so it would be difficult to make them a template. */
  11.454 +struct aiFloatKey 
  11.455 +{
  11.456 +	double mTime;      ///< The time of this key
  11.457 +	float mValue;	///< The value of this key
  11.458 +
  11.459 +#ifdef __cplusplus
  11.460 +
  11.461 +	// time is not compared
  11.462 +	bool operator == (const aiFloatKey& o) const
  11.463 +		{return o.mValue == this->mValue;}
  11.464 +
  11.465 +	bool operator != (const aiFloatKey& o) const
  11.466 +		{return o.mValue != this->mValue;}
  11.467 +
  11.468 +	// Only time is compared. This operator is defined
  11.469 +	// for use with std::sort
  11.470 +	bool operator < (const aiFloatKey& o) const
  11.471 +		{return mTime < o.mTime;}
  11.472 +
  11.473 +	bool operator > (const aiFloatKey& o) const
  11.474 +		{return mTime < o.mTime;}
  11.475 +
  11.476 +#endif
  11.477 +};
  11.478 +
  11.479 +// ---------------------------------------------------------------------------
  11.480 +/** Helper structure to represent a 3ds file node */
  11.481 +struct Node
  11.482 +{
  11.483 +	Node()
  11.484 +
  11.485 +		:	mHierarchyPos		(0)
  11.486 +		,	mHierarchyIndex		(0)
  11.487 +
  11.488 +	{
  11.489 +		static int iCnt = 0;
  11.490 +		
  11.491 +		// Generate a default name for the node
  11.492 +		char szTemp[128];
  11.493 +		::sprintf(szTemp,"UNNAMED_%i",iCnt++);
  11.494 +		mName = szTemp;
  11.495 +
  11.496 +		aRotationKeys.reserve (20);
  11.497 +		aPositionKeys.reserve (20);
  11.498 +		aScalingKeys.reserve  (20);
  11.499 +	}
  11.500 +
  11.501 +	~Node()
  11.502 +	{
  11.503 +		for (unsigned int i = 0; i < mChildren.size();++i)
  11.504 +			delete mChildren[i];
  11.505 +	}
  11.506 +
  11.507 +	//! Pointer to the parent node
  11.508 +	Node* mParent;
  11.509 +
  11.510 +	//! Holds all child nodes
  11.511 +	std::vector<Node*> mChildren;
  11.512 +
  11.513 +	//! Name of the node
  11.514 +	std::string mName;
  11.515 +
  11.516 +	//! Dummy nodes: real name to be combined with the $$$DUMMY 
  11.517 +	std::string mDummyName;
  11.518 +
  11.519 +	//! Position of the node in the hierarchy (tree depth)
  11.520 +	int16_t mHierarchyPos;
  11.521 +
  11.522 +	//! Index of the node
  11.523 +	int16_t mHierarchyIndex;
  11.524 +
  11.525 +	//! Rotation keys loaded from the file
  11.526 +	std::vector<aiQuatKey> aRotationKeys;
  11.527 +
  11.528 +	//! Position keys loaded from the file
  11.529 +	std::vector<aiVectorKey> aPositionKeys;
  11.530 +
  11.531 +	//! Scaling keys loaded from the file
  11.532 +	std::vector<aiVectorKey> aScalingKeys;
  11.533 +
  11.534 +
  11.535 +	// For target lights (spot lights and directional lights):
  11.536 +	// The position of the target
  11.537 +	std::vector< aiVectorKey > aTargetPositionKeys;
  11.538 +
  11.539 +	// For cameras: the camera roll angle
  11.540 +	std::vector< aiFloatKey > aCameraRollKeys;
  11.541 +
  11.542 +	//! Pivot position loaded from the file
  11.543 +	aiVector3D vPivot;
  11.544 +
  11.545 +	//! Add a child node, setup the right parent node for it
  11.546 +	//! \param pc Node to be 'adopted'
  11.547 +	inline Node& push_back(Node* pc)
  11.548 +	{
  11.549 +		mChildren.push_back(pc);
  11.550 +		pc->mParent = this;
  11.551 +		return *this;
  11.552 +	}
  11.553 +};
  11.554 +// ---------------------------------------------------------------------------
  11.555 +/** Helper structure analogue to aiScene */
  11.556 +struct Scene
  11.557 +{
  11.558 +	//! List of all materials loaded
  11.559 +	//! NOTE: 3ds references materials globally
  11.560 +	std::vector<Material> mMaterials;
  11.561 +
  11.562 +	//! List of all meshes loaded
  11.563 +	std::vector<Mesh> mMeshes;
  11.564 +
  11.565 +	//! List of all cameras loaded
  11.566 +	std::vector<aiCamera*> mCameras;
  11.567 +
  11.568 +	//! List of all lights loaded
  11.569 +	std::vector<aiLight*> mLights;
  11.570 +
  11.571 +	//! Pointer to the root node of the scene
  11.572 +	// --- moved to main class
  11.573 +	// Node* pcRootNode;
  11.574 +};
  11.575 +
  11.576 +
  11.577 +} // end of namespace D3DS
  11.578 +} // end of namespace Assimp
  11.579 +
  11.580 +#endif // AI_XFILEHELPER_H_INC
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/libs/assimp/3DSLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
    12.3 @@ -0,0 +1,1392 @@
    12.4 +/*
    12.5 +---------------------------------------------------------------------------
    12.6 +Open Asset Import Library (assimp)
    12.7 +---------------------------------------------------------------------------
    12.8 +
    12.9 +Copyright (c) 2006-2012, assimp team
   12.10 +
   12.11 +All rights reserved.
   12.12 +
   12.13 +Redistribution and use of this software in source and binary forms, 
   12.14 +with or without modification, are permitted provided that the following 
   12.15 +conditions are met:
   12.16 +
   12.17 +* Redistributions of source code must retain the above
   12.18 +  copyright notice, this list of conditions and the
   12.19 +  following disclaimer.
   12.20 +
   12.21 +* Redistributions in binary form must reproduce the above
   12.22 +  copyright notice, this list of conditions and the
   12.23 +  following disclaimer in the documentation and/or other
   12.24 +  materials provided with the distribution.
   12.25 +
   12.26 +* Neither the name of the assimp team, nor the names of its
   12.27 +  contributors may be used to endorse or promote products
   12.28 +  derived from this software without specific prior
   12.29 +  written permission of the assimp team.
   12.30 +
   12.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   12.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   12.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   12.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   12.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   12.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   12.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   12.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   12.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   12.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   12.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   12.42 +---------------------------------------------------------------------------
   12.43 +*/
   12.44 +
   12.45 +/** @file  3DSLoader.cpp
   12.46 + *  @brief Implementation of the 3ds importer class
   12.47 + *
   12.48 + *  http://www.the-labs.com/Blender/3DS-details.html
   12.49 + */
   12.50 +
   12.51 +#include "AssimpPCH.h"
   12.52 +#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
   12.53 +
   12.54 +// internal headers
   12.55 +#include "3DSLoader.h"
   12.56 +
   12.57 +using namespace Assimp;
   12.58 +
   12.59 +static const aiImporterDesc desc = {
   12.60 +	"Discreet 3DS Importer",
   12.61 +	"",
   12.62 +	"",
   12.63 +	"Limited animation support",
   12.64 +	aiImporterFlags_SupportBinaryFlavour,
   12.65 +	0,
   12.66 +	0,
   12.67 +	0,
   12.68 +	0,
   12.69 +	"3ds prj" 
   12.70 +};
   12.71 +
   12.72 +		
   12.73 +// ------------------------------------------------------------------------------------------------
   12.74 +// Begins a new parsing block
   12.75 +// - Reads the current chunk and validates it
   12.76 +// - computes its length
   12.77 +#define ASSIMP_3DS_BEGIN_CHUNK()                                         \
   12.78 +	while (true) {                                                       \
   12.79 +	if (stream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)){ \
   12.80 +		return;                                                          \
   12.81 +	}                                                                    \
   12.82 +	Discreet3DS::Chunk chunk;                                            \
   12.83 +	ReadChunk(&chunk);                                                   \
   12.84 +	int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk);	             \
   12.85 +	const int oldReadLimit = stream->GetReadLimit();                     \
   12.86 +	stream->SetReadLimit(stream->GetCurrentPos() + chunkSize);           \
   12.87 +	
   12.88 +
   12.89 +// ------------------------------------------------------------------------------------------------
   12.90 +// End a parsing block
   12.91 +// Must follow at the end of each parsing block, reset chunk end marker to previous value
   12.92 +#define ASSIMP_3DS_END_CHUNK()                  \
   12.93 +	stream->SkipToReadLimit();                  \
   12.94 +	stream->SetReadLimit(oldReadLimit);         \
   12.95 +	if (stream->GetRemainingSizeToLimit() == 0) \
   12.96 +		return;                                 \
   12.97 +	}
   12.98 +
   12.99 +// ------------------------------------------------------------------------------------------------
  12.100 +// Constructor to be privately used by Importer
  12.101 +Discreet3DSImporter::Discreet3DSImporter()
  12.102 +{}
  12.103 +
  12.104 +// ------------------------------------------------------------------------------------------------
  12.105 +// Destructor, private as well 
  12.106 +Discreet3DSImporter::~Discreet3DSImporter()
  12.107 +{}
  12.108 +
  12.109 +// ------------------------------------------------------------------------------------------------
  12.110 +// Returns whether the class can handle the format of the given file. 
  12.111 +bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  12.112 +{
  12.113 +	std::string extension = GetExtension(pFile);
  12.114 +	if(extension == "3ds" || extension == "prj" ) {
  12.115 +		return true;
  12.116 +	}
  12.117 +	if (!extension.length() || checkSig) {
  12.118 +		uint16_t token[3];
  12.119 +		token[0] = 0x4d4d;
  12.120 +		token[1] = 0x3dc2;
  12.121 +		//token[2] = 0x3daa;
  12.122 +		return CheckMagicToken(pIOHandler,pFile,token,2,0,2);
  12.123 +	}
  12.124 +	return false;
  12.125 +}
  12.126 +
  12.127 +// ------------------------------------------------------------------------------------------------
  12.128 +// Loader registry entry
  12.129 +const aiImporterDesc* Discreet3DSImporter::GetInfo () const
  12.130 +{
  12.131 +	return &desc;
  12.132 +}
  12.133 +
  12.134 +// ------------------------------------------------------------------------------------------------
  12.135 +// Setup configuration properties
  12.136 +void Discreet3DSImporter::SetupProperties(const Importer* /*pImp*/)
  12.137 +{
  12.138 +	// nothing to be done for the moment
  12.139 +}
  12.140 +
  12.141 +// ------------------------------------------------------------------------------------------------
  12.142 +// Imports the given file into the given scene structure. 
  12.143 +void Discreet3DSImporter::InternReadFile( const std::string& pFile, 
  12.144 +	aiScene* pScene, IOSystem* pIOHandler)
  12.145 +{
  12.146 +	StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
  12.147 +	this->stream = &stream;
  12.148 +
  12.149 +	// We should have at least one chunk
  12.150 +	if (stream.GetRemainingSize() < 16) {
  12.151 +		throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile);
  12.152 +	}
  12.153 +
  12.154 +	// Allocate our temporary 3DS representation
  12.155 +	mScene = new D3DS::Scene();
  12.156 +
  12.157 +	// Initialize members
  12.158 +	mLastNodeIndex             = -1;
  12.159 +	mCurrentNode               = new D3DS::Node();
  12.160 +	mRootNode                  = mCurrentNode;
  12.161 +	mRootNode->mHierarchyPos   = -1;
  12.162 +	mRootNode->mHierarchyIndex = -1;
  12.163 +	mRootNode->mParent         = NULL;
  12.164 +	mMasterScale               = 1.0f;
  12.165 +	mBackgroundImage           = "";
  12.166 +	bHasBG                     = false;
  12.167 +	bIsPrj                     = false;
  12.168 +
  12.169 +	// Parse the file
  12.170 +	ParseMainChunk();
  12.171 +
  12.172 +	// Process all meshes in the file. First check whether all
  12.173 +	// face indices haev valid values. The generate our 
  12.174 +	// internal verbose representation. Finally compute normal
  12.175 +	// vectors from the smoothing groups we read from the
  12.176 +	// file.
  12.177 +	for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(),
  12.178 +		 end = mScene->mMeshes.end(); i != end;++i)	{
  12.179 +		CheckIndices(*i);
  12.180 +		MakeUnique  (*i);
  12.181 +		ComputeNormalsWithSmoothingsGroups<D3DS::Face>(*i);
  12.182 +	}
  12.183 +
  12.184 +	// Replace all occurences of the default material with a
  12.185 +	// valid material. Generate it if no material containing
  12.186 +	// DEFAULT in its name has been found in the file
  12.187 +	ReplaceDefaultMaterial();
  12.188 +
  12.189 +	// Convert the scene from our internal representation to an
  12.190 +	// aiScene object. This involves copying all meshes, lights
  12.191 +	// and cameras to the scene
  12.192 +	ConvertScene(pScene);
  12.193 +
  12.194 +	// Generate the node graph for the scene. This is a little bit
  12.195 +	// tricky since we'll need to split some meshes into submeshes
  12.196 +	GenerateNodeGraph(pScene);
  12.197 +
  12.198 +	// Now apply the master scaling factor to the scene
  12.199 +	ApplyMasterScale(pScene);
  12.200 +
  12.201 +	// Delete our internal scene representation and the root
  12.202 +	// node, so the whole hierarchy will follow
  12.203 +	delete mRootNode;
  12.204 +	delete mScene;
  12.205 +
  12.206 +	AI_DEBUG_INVALIDATE_PTR(mRootNode);
  12.207 +	AI_DEBUG_INVALIDATE_PTR(mScene);
  12.208 +	AI_DEBUG_INVALIDATE_PTR(this->stream);
  12.209 +}
  12.210 +
  12.211 +// ------------------------------------------------------------------------------------------------
  12.212 +// Applies a master-scaling factor to the imported scene
  12.213 +void Discreet3DSImporter::ApplyMasterScale(aiScene* pScene)
  12.214 +{
  12.215 +	// There are some 3DS files with a zero scaling factor
  12.216 +	if (!mMasterScale)mMasterScale = 1.0f;
  12.217 +	else mMasterScale = 1.0f / mMasterScale;
  12.218 +
  12.219 +	// Construct an uniform scaling matrix and multiply with it
  12.220 +	pScene->mRootNode->mTransformation *= aiMatrix4x4( 
  12.221 +		mMasterScale,0.0f, 0.0f, 0.0f,
  12.222 +		0.0f, mMasterScale,0.0f, 0.0f,
  12.223 +		0.0f, 0.0f, mMasterScale,0.0f,
  12.224 +		0.0f, 0.0f, 0.0f, 1.0f);
  12.225 +
  12.226 +	// Check whether a scaling track is assigned to the root node.
  12.227 +}
  12.228 +
  12.229 +// ------------------------------------------------------------------------------------------------
  12.230 +// Reads a new chunk from the file
  12.231 +void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk* pcOut)
  12.232 +{
  12.233 +	ai_assert(pcOut != NULL);
  12.234 +
  12.235 +	pcOut->Flag = stream->GetI2();
  12.236 +	pcOut->Size = stream->GetI4();
  12.237 +
  12.238 +	if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize())
  12.239 +		throw DeadlyImportError("Chunk is too large");
  12.240 +	
  12.241 +	if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit())
  12.242 +		DefaultLogger::get()->error("3DS: Chunk overflow");
  12.243 +}
  12.244 +
  12.245 +// ------------------------------------------------------------------------------------------------
  12.246 +// Skip a chunk
  12.247 +void Discreet3DSImporter::SkipChunk()
  12.248 +{
  12.249 +	Discreet3DS::Chunk psChunk;
  12.250 +	ReadChunk(&psChunk);
  12.251 +	
  12.252 +	stream->IncPtr(psChunk.Size-sizeof(Discreet3DS::Chunk));
  12.253 +	return;
  12.254 +}
  12.255 +
  12.256 +// ------------------------------------------------------------------------------------------------
  12.257 +// Process the primary chunk of the file
  12.258 +void Discreet3DSImporter::ParseMainChunk()
  12.259 +{
  12.260 +	ASSIMP_3DS_BEGIN_CHUNK();
  12.261 +
  12.262 +	// get chunk type
  12.263 +	switch (chunk.Flag)
  12.264 +	{
  12.265 +	
  12.266 +	case Discreet3DS::CHUNK_PRJ:
  12.267 +		bIsPrj = true;
  12.268 +	case Discreet3DS::CHUNK_MAIN:
  12.269 +		ParseEditorChunk();
  12.270 +		break;
  12.271 +	};
  12.272 +
  12.273 +	ASSIMP_3DS_END_CHUNK();
  12.274 +	// recursively continue processing this hierarchy level
  12.275 +	return ParseMainChunk();
  12.276 +}
  12.277 +
  12.278 +// ------------------------------------------------------------------------------------------------
  12.279 +void Discreet3DSImporter::ParseEditorChunk()
  12.280 +{
  12.281 +	ASSIMP_3DS_BEGIN_CHUNK();
  12.282 +
  12.283 +	// get chunk type
  12.284 +	switch (chunk.Flag)
  12.285 +	{
  12.286 +	case Discreet3DS::CHUNK_OBJMESH:
  12.287 +
  12.288 +		ParseObjectChunk();
  12.289 +		break;
  12.290 +
  12.291 +	// NOTE: In several documentations in the internet this
  12.292 +	// chunk appears at different locations
  12.293 +	case Discreet3DS::CHUNK_KEYFRAMER:
  12.294 +
  12.295 +		ParseKeyframeChunk();
  12.296 +		break;
  12.297 +
  12.298 +	case Discreet3DS::CHUNK_VERSION:
  12.299 +		{
  12.300 +		// print the version number
  12.301 +		char buff[10];
  12.302 +		ASSIMP_itoa10(buff,stream->GetI2());
  12.303 +		DefaultLogger::get()->info(std::string("3DS file format version: ") + buff);
  12.304 +		}
  12.305 +		break;
  12.306 +	};
  12.307 +	ASSIMP_3DS_END_CHUNK();
  12.308 +}
  12.309 +
  12.310 +// ------------------------------------------------------------------------------------------------
  12.311 +void Discreet3DSImporter::ParseObjectChunk()
  12.312 +{
  12.313 +	ASSIMP_3DS_BEGIN_CHUNK();
  12.314 +
  12.315 +	// get chunk type
  12.316 +	switch (chunk.Flag)
  12.317 +	{
  12.318 +	case Discreet3DS::CHUNK_OBJBLOCK:
  12.319 +		{
  12.320 +		unsigned int cnt = 0;
  12.321 +		const char* sz = (const char*)stream->GetPtr();
  12.322 +
  12.323 +		// Get the name of the geometry object
  12.324 +		while (stream->GetI1())++cnt;
  12.325 +		ParseChunk(sz,cnt);
  12.326 +		}
  12.327 +		break;
  12.328 +
  12.329 +	case Discreet3DS::CHUNK_MAT_MATERIAL:
  12.330 +
  12.331 +		// Add a new material to the list
  12.332 +		mScene->mMaterials.push_back(D3DS::Material());
  12.333 +		ParseMaterialChunk();
  12.334 +		break;
  12.335 +
  12.336 +	case Discreet3DS::CHUNK_AMBCOLOR:
  12.337 +
  12.338 +		// This is the ambient base color of the scene.
  12.339 +		// We add it to the ambient color of all materials
  12.340 +		ParseColorChunk(&mClrAmbient,true);
  12.341 +		if (is_qnan(mClrAmbient.r))
  12.342 +		{
  12.343 +			// We failed to read the ambient base color.
  12.344 +			DefaultLogger::get()->error("3DS: Failed to read ambient base color");
  12.345 +			mClrAmbient.r = mClrAmbient.g = mClrAmbient.b = 0.0f;
  12.346 +		}
  12.347 +		break;
  12.348 +
  12.349 +	case Discreet3DS::CHUNK_BIT_MAP:
  12.350 +		{
  12.351 +		// Specifies the background image. The string should already be 
  12.352 +		// properly 0 terminated but we need to be sure
  12.353 +		unsigned int cnt = 0;
  12.354 +		const char* sz = (const char*)stream->GetPtr();
  12.355 +		while (stream->GetI1())++cnt;
  12.356 +		mBackgroundImage = std::string(sz,cnt);
  12.357 +		}
  12.358 +		break;
  12.359 +
  12.360 +	case Discreet3DS::CHUNK_BIT_MAP_EXISTS:
  12.361 +		bHasBG = true;
  12.362 +		break;
  12.363 +
  12.364 +	case Discreet3DS::CHUNK_MASTER_SCALE:
  12.365 +		// Scene master scaling factor
  12.366 +		mMasterScale = stream->GetF4();
  12.367 +		break;
  12.368 +	};
  12.369 +	ASSIMP_3DS_END_CHUNK();
  12.370 +}
  12.371 +
  12.372 +// ------------------------------------------------------------------------------------------------
  12.373 +void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
  12.374 +{
  12.375 +	ASSIMP_3DS_BEGIN_CHUNK();
  12.376 +
  12.377 +	// IMPLEMENTATION NOTE;
  12.378 +	// Cameras or lights define their transformation in their parent node and in the
  12.379 +	// corresponding light or camera chunks. However, we read and process the latter
  12.380 +	// to to be able to return valid cameras/lights even if no scenegraph is given.
  12.381 +
  12.382 +	// get chunk type
  12.383 +	switch (chunk.Flag)
  12.384 +	{
  12.385 +	case Discreet3DS::CHUNK_TRIMESH:
  12.386 +		{
  12.387 +		// this starts a new triangle mesh
  12.388 +		mScene->mMeshes.push_back(D3DS::Mesh());
  12.389 +		D3DS::Mesh& m = mScene->mMeshes.back();
  12.390 +
  12.391 +		// Setup the name of the mesh
  12.392 +		m.mName = std::string(name, num);
  12.393 +
  12.394 +		// Read mesh chunks
  12.395 +		ParseMeshChunk();
  12.396 +		}
  12.397 +		break;
  12.398 +
  12.399 +	case Discreet3DS::CHUNK_LIGHT:	
  12.400 +		{
  12.401 +		// This starts a new light
  12.402 +		aiLight* light = new aiLight();
  12.403 +		mScene->mLights.push_back(light);
  12.404 +
  12.405 +		light->mName.Set(std::string(name, num));
  12.406 +
  12.407 +		// First read the position of the light
  12.408 +		light->mPosition.x = stream->GetF4();
  12.409 +		light->mPosition.y = stream->GetF4();
  12.410 +		light->mPosition.z = stream->GetF4();
  12.411 +
  12.412 +		light->mColorDiffuse = aiColor3D(1.f,1.f,1.f);
  12.413 +
  12.414 +		// Now check for further subchunks
  12.415 +		if (!bIsPrj) /* fixme */
  12.416 +			ParseLightChunk();
  12.417 +
  12.418 +		// The specular light color is identical the the diffuse light color. The ambient light color
  12.419 +		// is equal to the ambient base color of the whole scene.
  12.420 +		light->mColorSpecular = light->mColorDiffuse;
  12.421 +		light->mColorAmbient  = mClrAmbient;
  12.422 +
  12.423 +		if (light->mType == aiLightSource_UNDEFINED)
  12.424 +		{
  12.425 +			// It must be a point light
  12.426 +			light->mType = aiLightSource_POINT;
  12.427 +		}}
  12.428 +		break;
  12.429 +
  12.430 +	case Discreet3DS::CHUNK_CAMERA:
  12.431 +		{
  12.432 +		// This starts a new camera
  12.433 +		aiCamera* camera = new aiCamera();
  12.434 +		mScene->mCameras.push_back(camera);
  12.435 +		camera->mName.Set(std::string(name, num));
  12.436 +
  12.437 +		// First read the position of the camera
  12.438 +		camera->mPosition.x = stream->GetF4();
  12.439 +		camera->mPosition.y = stream->GetF4();
  12.440 +		camera->mPosition.z = stream->GetF4();
  12.441 +
  12.442 +		// Then the camera target
  12.443 +		camera->mLookAt.x = stream->GetF4() - camera->mPosition.x;
  12.444 +		camera->mLookAt.y = stream->GetF4() - camera->mPosition.y;
  12.445 +		camera->mLookAt.z = stream->GetF4() - camera->mPosition.z;
  12.446 +		float len = camera->mLookAt.Length();
  12.447 +		if (len < 1e-5f) {
  12.448 +			
  12.449 +			// There are some files with lookat == position. Don't know why or whether it's ok or not.
  12.450 +			DefaultLogger::get()->error("3DS: Unable to read proper camera look-at vector");
  12.451 +			camera->mLookAt = aiVector3D(0.f,1.f,0.f);
  12.452 +
  12.453 +		}
  12.454 +		else camera->mLookAt /= len;
  12.455 +
  12.456 +		// And finally - the camera rotation angle, in counter clockwise direction 
  12.457 +		const float angle =  AI_DEG_TO_RAD( stream->GetF4() );
  12.458 +		aiQuaternion quat(camera->mLookAt,angle);
  12.459 +		camera->mUp = quat.GetMatrix() * aiVector3D(0.f,1.f,0.f);
  12.460 +
  12.461 +		// Read the lense angle
  12.462 +		camera->mHorizontalFOV = AI_DEG_TO_RAD ( stream->GetF4() );
  12.463 +		if (camera->mHorizontalFOV < 0.001f)  {
  12.464 +			camera->mHorizontalFOV = AI_DEG_TO_RAD(45.f);
  12.465 +		}
  12.466 +
  12.467 +		// Now check for further subchunks 
  12.468 +		if (!bIsPrj) /* fixme */ {
  12.469 +			ParseCameraChunk();
  12.470 +		}}
  12.471 +		break;
  12.472 +	};
  12.473 +	ASSIMP_3DS_END_CHUNK();
  12.474 +}
  12.475 +
  12.476 +// ------------------------------------------------------------------------------------------------
  12.477 +void Discreet3DSImporter::ParseLightChunk()
  12.478 +{
  12.479 +	ASSIMP_3DS_BEGIN_CHUNK();
  12.480 +	aiLight* light = mScene->mLights.back();
  12.481 +
  12.482 +	// get chunk type
  12.483 +	switch (chunk.Flag)
  12.484 +	{
  12.485 +	case Discreet3DS::CHUNK_DL_SPOTLIGHT:
  12.486 +		// Now we can be sure that the light is a spot light
  12.487 +		light->mType = aiLightSource_SPOT;
  12.488 +
  12.489 +		// We wouldn't need to normalize here, but we do it
  12.490 +		light->mDirection.x = stream->GetF4() - light->mPosition.x;
  12.491 +		light->mDirection.y = stream->GetF4() - light->mPosition.y;
  12.492 +		light->mDirection.z = stream->GetF4() - light->mPosition.z;
  12.493 +		light->mDirection.Normalize();
  12.494 +
  12.495 +		// Now the hotspot and falloff angles - in degrees
  12.496 +		light->mAngleInnerCone = AI_DEG_TO_RAD( stream->GetF4() );
  12.497 +
  12.498 +		// FIX: the falloff angle is just an offset
  12.499 +		light->mAngleOuterCone = light->mAngleInnerCone+AI_DEG_TO_RAD( stream->GetF4() );
  12.500 +		break; 
  12.501 +
  12.502 +		// intensity multiplier
  12.503 +	case Discreet3DS::CHUNK_DL_MULTIPLIER:
  12.504 +		light->mColorDiffuse = light->mColorDiffuse * stream->GetF4();
  12.505 +		break;
  12.506 +
  12.507 +		// light color
  12.508 +	case Discreet3DS::CHUNK_RGBF:
  12.509 +	case Discreet3DS::CHUNK_LINRGBF:
  12.510 +		light->mColorDiffuse.r *= stream->GetF4();
  12.511 +		light->mColorDiffuse.g *= stream->GetF4();
  12.512 +		light->mColorDiffuse.b *= stream->GetF4();
  12.513 +		break;
  12.514 +
  12.515 +		// light attenuation
  12.516 +	case Discreet3DS::CHUNK_DL_ATTENUATE: 
  12.517 +		light->mAttenuationLinear = stream->GetF4();
  12.518 +		break;
  12.519 +	};
  12.520 +
  12.521 +	ASSIMP_3DS_END_CHUNK();
  12.522 +}
  12.523 +
  12.524 +// ------------------------------------------------------------------------------------------------
  12.525 +void Discreet3DSImporter::ParseCameraChunk()
  12.526 +{
  12.527 +	ASSIMP_3DS_BEGIN_CHUNK();
  12.528 +	aiCamera* camera = mScene->mCameras.back();
  12.529 +
  12.530 +	// get chunk type
  12.531 +	switch (chunk.Flag)
  12.532 +	{
  12.533 +		// near and far clip plane
  12.534 +	case Discreet3DS::CHUNK_CAM_RANGES:
  12.535 +		camera->mClipPlaneNear = stream->GetF4();
  12.536 +		camera->mClipPlaneFar  = stream->GetF4();
  12.537 +		break;
  12.538 +	}
  12.539 +
  12.540 +	ASSIMP_3DS_END_CHUNK();
  12.541 +}
  12.542 +
  12.543 +// ------------------------------------------------------------------------------------------------
  12.544 +void Discreet3DSImporter::ParseKeyframeChunk()
  12.545 +{
  12.546 +	ASSIMP_3DS_BEGIN_CHUNK();
  12.547 +
  12.548 +	// get chunk type
  12.549 +	switch (chunk.Flag)
  12.550 +	{
  12.551 +	case Discreet3DS::CHUNK_TRACKCAMTGT:
  12.552 +	case Discreet3DS::CHUNK_TRACKSPOTL:
  12.553 +	case Discreet3DS::CHUNK_TRACKCAMERA:
  12.554 +	case Discreet3DS::CHUNK_TRACKINFO:
  12.555 +	case Discreet3DS::CHUNK_TRACKLIGHT:
  12.556 +	case Discreet3DS::CHUNK_TRACKLIGTGT:
  12.557 +
  12.558 +		// this starts a new mesh hierarchy chunk
  12.559 +		ParseHierarchyChunk(chunk.Flag);
  12.560 +		break;
  12.561 +	};
  12.562 +
  12.563 +	ASSIMP_3DS_END_CHUNK();
  12.564 +}
  12.565 +
  12.566 +// ------------------------------------------------------------------------------------------------
  12.567 +// Little helper function for ParseHierarchyChunk
  12.568 +void Discreet3DSImporter::InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent)
  12.569 +{
  12.570 +	if (!pcCurrent)	{
  12.571 +		mRootNode->push_back(pcNode);
  12.572 +		return;
  12.573 +	}
  12.574 +
  12.575 +	if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos)	{
  12.576 +		if(pcCurrent->mParent) {
  12.577 +			pcCurrent->mParent->push_back(pcNode);
  12.578 +		}
  12.579 +		else pcCurrent->push_back(pcNode);
  12.580 +		return;
  12.581 +	}
  12.582 +	return InverseNodeSearch(pcNode,pcCurrent->mParent);
  12.583 +}
  12.584 +
  12.585 +// ------------------------------------------------------------------------------------------------
  12.586 +// Find a node with a specific name in the import hierarchy
  12.587 +D3DS::Node* FindNode(D3DS::Node* root, const std::string& name)
  12.588 +{
  12.589 +	if (root->mName == name)
  12.590 +		return root;
  12.591 +	for (std::vector<D3DS::Node*>::iterator it = root->mChildren.begin();it != root->mChildren.end(); ++it)	{
  12.592 +		D3DS::Node* nd;
  12.593 +		if (( nd = FindNode(*it,name)))
  12.594 +			return nd;
  12.595 +	}
  12.596 +	return NULL;
  12.597 +}
  12.598 +
  12.599 +// ------------------------------------------------------------------------------------------------
  12.600 +// Binary predicate for std::unique()
  12.601 +template <class T>
  12.602 +bool KeyUniqueCompare(const T& first, const T& second)
  12.603 +{
  12.604 +	return first.mTime == second.mTime;
  12.605 +}
  12.606 +
  12.607 +// ------------------------------------------------------------------------------------------------
  12.608 +// Skip some additional import data.
  12.609 +void Discreet3DSImporter::SkipTCBInfo()
  12.610 +{
  12.611 +	unsigned int flags = stream->GetI2();
  12.612 +
  12.613 +	if (!flags)	{
  12.614 +		// Currently we can't do anything with these values. They occur
  12.615 +		// quite rare, so it wouldn't be worth the effort implementing
  12.616 +		// them. 3DS ist not really suitable for complex animations,
  12.617 +		// so full support is not required.
  12.618 +		DefaultLogger::get()->warn("3DS: Skipping TCB animation info");
  12.619 +	}
  12.620 +
  12.621 +	if (flags & Discreet3DS::KEY_USE_TENS) {
  12.622 +		stream->IncPtr(4);
  12.623 +	}
  12.624 +	if (flags & Discreet3DS::KEY_USE_BIAS) {
  12.625 +		stream->IncPtr(4);
  12.626 +	}
  12.627 +	if (flags & Discreet3DS::KEY_USE_CONT) {
  12.628 +		stream->IncPtr(4);
  12.629 +	}
  12.630 +	if (flags & Discreet3DS::KEY_USE_EASE_FROM) {
  12.631 +		stream->IncPtr(4);
  12.632 +	}
  12.633 +	if (flags & Discreet3DS::KEY_USE_EASE_TO) {
  12.634 +		stream->IncPtr(4);
  12.635 +	}
  12.636 +}
  12.637 +
  12.638 +// ------------------------------------------------------------------------------------------------
  12.639 +// Read hierarchy and keyframe info
  12.640 +void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
  12.641 +{
  12.642 +	ASSIMP_3DS_BEGIN_CHUNK();
  12.643 +
  12.644 +	// get chunk type
  12.645 +	switch (chunk.Flag)
  12.646 +	{
  12.647 +	case Discreet3DS::CHUNK_TRACKOBJNAME:
  12.648 +
  12.649 +		// This is the name of the object to which the track applies. The chunk also
  12.650 +		// defines the position of this object in the hierarchy.
  12.651 +		{
  12.652 +
  12.653 +		// First of all: get the name of the object
  12.654 +		unsigned int cnt = 0;
  12.655 +		const char* sz = (const char*)stream->GetPtr();
  12.656 +
  12.657 +		while (stream->GetI1())++cnt;
  12.658 +		std::string name = std::string(sz,cnt);
  12.659 +
  12.660 +		// Now find out whether we have this node already (target animation channels 
  12.661 +		// are stored with a separate object ID)
  12.662 +		D3DS::Node* pcNode = FindNode(mRootNode,name);
  12.663 +		if (pcNode)
  12.664 +		{
  12.665 +			// Make this node the current node
  12.666 +			mCurrentNode = pcNode;
  12.667 +			break;	
  12.668 +		}
  12.669 +		pcNode = new D3DS::Node();
  12.670 +		pcNode->mName = name;
  12.671 +
  12.672 +		// There are two unknown values which we can safely ignore
  12.673 +		stream->IncPtr(4);
  12.674 +
  12.675 +		// Now read the hierarchy position of the object
  12.676 +		uint16_t hierarchy = stream->GetI2() + 1;
  12.677 +		pcNode->mHierarchyPos   = hierarchy;
  12.678 +		pcNode->mHierarchyIndex = mLastNodeIndex;
  12.679 +
  12.680 +		// And find a proper position in the graph for it
  12.681 +		if (mCurrentNode && mCurrentNode->mHierarchyPos == hierarchy)	{
  12.682 +
  12.683 +			// add to the parent of the last touched node
  12.684 +			mCurrentNode->mParent->push_back(pcNode);
  12.685 +			mLastNodeIndex++;	
  12.686 +		}
  12.687 +		else if(hierarchy >= mLastNodeIndex)	{
  12.688 +
  12.689 +			// place it at the current position in the hierarchy
  12.690 +			mCurrentNode->push_back(pcNode);
  12.691 +			mLastNodeIndex = hierarchy;
  12.692 +		}
  12.693 +		else	{
  12.694 +			// need to go back to the specified position in the hierarchy.
  12.695 +			InverseNodeSearch(pcNode,mCurrentNode);
  12.696 +			mLastNodeIndex++;	
  12.697 +		}
  12.698 +		// Make this node the current node
  12.699 +		mCurrentNode = pcNode;
  12.700 +		}
  12.701 +		break;
  12.702 +
  12.703 +	case Discreet3DS::CHUNK_TRACKDUMMYOBJNAME:
  12.704 +
  12.705 +		// This is the "real" name of a $$$DUMMY object
  12.706 +		{
  12.707 +			const char* sz = (const char*) stream->GetPtr();
  12.708 +			while (stream->GetI1());
  12.709 +
  12.710 +			// If object name is DUMMY, take this one instead
  12.711 +			if (mCurrentNode->mName == "$$$DUMMY")	{
  12.712 +				//DefaultLogger::get()->warn("3DS: Skipping dummy object name for non-dummy object");
  12.713 +				mCurrentNode->mName = std::string(sz);
  12.714 +				break;
  12.715 +			}
  12.716 +		}
  12.717 +		break;
  12.718 +
  12.719 +	case Discreet3DS::CHUNK_TRACKPIVOT:
  12.720 +
  12.721 +		if ( Discreet3DS::CHUNK_TRACKINFO != parent) 
  12.722 +		{
  12.723 +			DefaultLogger::get()->warn("3DS: Skipping pivot subchunk for non usual object");
  12.724 +			break;
  12.725 +		}
  12.726 +
  12.727 +		// Pivot = origin of rotation and scaling
  12.728 +		mCurrentNode->vPivot.x = stream->GetF4();
  12.729 +		mCurrentNode->vPivot.y = stream->GetF4();
  12.730 +		mCurrentNode->vPivot.z = stream->GetF4();
  12.731 +		break;
  12.732 +
  12.733 +
  12.734 +		// ////////////////////////////////////////////////////////////////////
  12.735 +		// POSITION KEYFRAME
  12.736 +	case Discreet3DS::CHUNK_TRACKPOS:
  12.737 +		{
  12.738 +		stream->IncPtr(10);
  12.739 +		const unsigned int numFrames = stream->GetI4();
  12.740 +		bool sortKeys = false;
  12.741 +
  12.742 +		// This could also be meant as the target position for
  12.743 +		// (targeted) lights and cameras
  12.744 +		std::vector<aiVectorKey>* l;
  12.745 +		if ( Discreet3DS::CHUNK_TRACKCAMTGT == parent || Discreet3DS::CHUNK_TRACKLIGTGT == parent)	{
  12.746 +			l = & mCurrentNode->aTargetPositionKeys;
  12.747 +		}
  12.748 +		else l = & mCurrentNode->aPositionKeys;
  12.749 +
  12.750 +		l->reserve(numFrames);
  12.751 +		for (unsigned int i = 0; i < numFrames;++i)	{
  12.752 +			const unsigned int fidx = stream->GetI4();
  12.753 +
  12.754 +			// Setup a new position key
  12.755 +			aiVectorKey v;
  12.756 +			v.mTime = (double)fidx;
  12.757 +
  12.758 +			SkipTCBInfo();
  12.759 +			v.mValue.x = stream->GetF4();
  12.760 +			v.mValue.y = stream->GetF4();
  12.761 +			v.mValue.z = stream->GetF4();
  12.762 +
  12.763 +			// check whether we'll need to sort the keys
  12.764 +			if (!l->empty() && v.mTime <= l->back().mTime)
  12.765 +				sortKeys = true;
  12.766 +
  12.767 +			// Add the new keyframe to the list
  12.768 +			l->push_back(v);
  12.769 +		}
  12.770 +
  12.771 +		// Sort all keys with ascending time values and remove duplicates?
  12.772 +		if (sortKeys)	{
  12.773 +			std::stable_sort(l->begin(),l->end());
  12.774 +			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
  12.775 +		}}
  12.776 +
  12.777 +		break;
  12.778 +
  12.779 +		// ////////////////////////////////////////////////////////////////////
  12.780 +		// CAMERA ROLL KEYFRAME
  12.781 +	case Discreet3DS::CHUNK_TRACKROLL:
  12.782 +		{
  12.783 +		// roll keys are accepted for cameras only
  12.784 +		if (parent != Discreet3DS::CHUNK_TRACKCAMERA)	{
  12.785 +			DefaultLogger::get()->warn("3DS: Ignoring roll track for non-camera object");
  12.786 +			break;
  12.787 +		}
  12.788 +		bool sortKeys = false;
  12.789 +		std::vector<aiFloatKey>* l = &mCurrentNode->aCameraRollKeys;
  12.790 +
  12.791 +		stream->IncPtr(10);
  12.792 +		const unsigned int numFrames = stream->GetI4();
  12.793 +		l->reserve(numFrames);
  12.794 +		for (unsigned int i = 0; i < numFrames;++i)	{
  12.795 +			const unsigned int fidx = stream->GetI4();
  12.796 +
  12.797 +			// Setup a new position key
  12.798 +			aiFloatKey v;
  12.799 +			v.mTime = (double)fidx;
  12.800 +
  12.801 +			// This is just a single float 
  12.802 +			SkipTCBInfo();
  12.803 +			v.mValue = stream->GetF4();
  12.804 +
  12.805 +			// Check whether we'll need to sort the keys
  12.806 +			if (!l->empty() && v.mTime <= l->back().mTime)
  12.807 +				sortKeys = true;
  12.808 +
  12.809 +			// Add the new keyframe to the list
  12.810 +			l->push_back(v);
  12.811 +		}
  12.812 +
  12.813 +		// Sort all keys with ascending time values and remove duplicates?
  12.814 +		if (sortKeys)	{
  12.815 +			std::stable_sort(l->begin(),l->end());
  12.816 +			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiFloatKey>), l->end() );
  12.817 +		}}
  12.818 +		break;
  12.819 +
  12.820 +
  12.821 +		// ////////////////////////////////////////////////////////////////////
  12.822 +		// CAMERA FOV KEYFRAME
  12.823 +	case Discreet3DS::CHUNK_TRACKFOV:
  12.824 +		{
  12.825 +			DefaultLogger::get()->error("3DS: Skipping FOV animation track. "
  12.826 +				"This is not supported");
  12.827 +		}
  12.828 +		break;
  12.829 +
  12.830 +
  12.831 +		// ////////////////////////////////////////////////////////////////////
  12.832 +		// ROTATION KEYFRAME
  12.833 +	case Discreet3DS::CHUNK_TRACKROTATE:
  12.834 +		{
  12.835 +		stream->IncPtr(10);
  12.836 +		const unsigned int numFrames = stream->GetI4();
  12.837 +
  12.838 +		bool sortKeys = false;
  12.839 +		std::vector<aiQuatKey>* l = &mCurrentNode->aRotationKeys;
  12.840 +		l->reserve(numFrames);
  12.841 +
  12.842 +		for (unsigned int i = 0; i < numFrames;++i)	{
  12.843 +			const unsigned int fidx = stream->GetI4();
  12.844 +			SkipTCBInfo();
  12.845 +
  12.846 +			aiQuatKey v;
  12.847 +			v.mTime = (double)fidx;
  12.848 +
  12.849 +			// The rotation keyframe is given as an axis-angle pair
  12.850 +			const float rad = stream->GetF4();
  12.851 +			aiVector3D axis;
  12.852 +			axis.x = stream->GetF4();
  12.853 +			axis.y = stream->GetF4();
  12.854 +			axis.z = stream->GetF4();
  12.855 +
  12.856 +			if (!axis.x && !axis.y && !axis.z)
  12.857 +				axis.y = 1.f;
  12.858 +
  12.859 +			// Construct a rotation quaternion from the axis-angle pair
  12.860 +			v.mValue = aiQuaternion(axis,rad);
  12.861 +
  12.862 +			// Check whether we'll need to sort the keys
  12.863 +			if (!l->empty() && v.mTime <= l->back().mTime)
  12.864 +				sortKeys = true;
  12.865 +
  12.866 +			// add the new keyframe to the list
  12.867 +			l->push_back(v);
  12.868 +		}
  12.869 +		// Sort all keys with ascending time values and remove duplicates?
  12.870 +		if (sortKeys)	{
  12.871 +			std::stable_sort(l->begin(),l->end());
  12.872 +			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiQuatKey>), l->end() );
  12.873 +		}}
  12.874 +		break;
  12.875 +
  12.876 +		// ////////////////////////////////////////////////////////////////////
  12.877 +		// SCALING KEYFRAME
  12.878 +	case Discreet3DS::CHUNK_TRACKSCALE:
  12.879 +		{
  12.880 +		stream->IncPtr(10);
  12.881 +		const unsigned int numFrames = stream->GetI2();
  12.882 +		stream->IncPtr(2);
  12.883 +
  12.884 +		bool sortKeys = false;
  12.885 +		std::vector<aiVectorKey>* l = &mCurrentNode->aScalingKeys;
  12.886 +		l->reserve(numFrames);
  12.887 +
  12.888 +		for (unsigned int i = 0; i < numFrames;++i)	{
  12.889 +			const unsigned int fidx = stream->GetI4();
  12.890 +			SkipTCBInfo();
  12.891 +
  12.892 +			// Setup a new key
  12.893 +			aiVectorKey v;
  12.894 +			v.mTime = (double)fidx;
  12.895 +
  12.896 +			// ... and read its value
  12.897 +			v.mValue.x = stream->GetF4();
  12.898 +			v.mValue.y = stream->GetF4();
  12.899 +			v.mValue.z = stream->GetF4();
  12.900 +
  12.901 +			// check whether we'll need to sort the keys
  12.902 +			if (!l->empty() && v.mTime <= l->back().mTime)
  12.903 +				sortKeys = true;
  12.904 +			
  12.905 +			// Remove zero-scalings on singular axes - they've been reported to be there erroneously in some strange files
  12.906 +			if (!v.mValue.x) v.mValue.x = 1.f;
  12.907 +			if (!v.mValue.y) v.mValue.y = 1.f;
  12.908 +			if (!v.mValue.z) v.mValue.z = 1.f;
  12.909 +
  12.910 +			l->push_back(v);
  12.911 +		}
  12.912 +		// Sort all keys with ascending time values and remove duplicates?
  12.913 +		if (sortKeys)	{
  12.914 +			std::stable_sort(l->begin(),l->end());
  12.915 +			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
  12.916 +		}}
  12.917 +		break;
  12.918 +	};
  12.919 +
  12.920 +	ASSIMP_3DS_END_CHUNK();
  12.921 +}
  12.922 +
  12.923 +// ------------------------------------------------------------------------------------------------
  12.924 +// Read a face chunk - it contains smoothing groups and material assignments
  12.925 +void Discreet3DSImporter::ParseFaceChunk()
  12.926 +{
  12.927 +	ASSIMP_3DS_BEGIN_CHUNK();
  12.928 +
  12.929 +	// Get the mesh we're currently working on
  12.930 +	D3DS::Mesh& mMesh = mScene->mMeshes.back();
  12.931 +
  12.932 +	// Get chunk type
  12.933 +	switch (chunk.Flag)
  12.934 +	{
  12.935 +	case Discreet3DS::CHUNK_SMOOLIST:
  12.936 +		{
  12.937 +		// This is the list of smoothing groups - a bitfield for every face. 
  12.938 +		// Up to 32 smoothing groups assigned to a single face.
  12.939 +		unsigned int num = chunkSize/4, m = 0;
  12.940 +		for (std::vector<D3DS::Face>::iterator i =  mMesh.mFaces.begin(); m != num;++i, ++m)	{
  12.941 +			// nth bit is set for nth smoothing group
  12.942 +			(*i).iSmoothGroup = stream->GetI4();
  12.943 +		}}
  12.944 +		break;
  12.945 +
  12.946 +	case Discreet3DS::CHUNK_FACEMAT:
  12.947 +		{
  12.948 +		// at fist an asciiz with the material name
  12.949 +		const char* sz = (const char*)stream->GetPtr();
  12.950 +		while (stream->GetI1());
  12.951 +
  12.952 +		// find the index of the material
  12.953 +		unsigned int idx = 0xcdcdcdcd, cnt = 0;
  12.954 +		for (std::vector<D3DS::Material>::const_iterator i =  mScene->mMaterials.begin();i != mScene->mMaterials.end();++i,++cnt)	{
  12.955 +			// use case independent comparisons. hopefully it will work.
  12.956 +			if ((*i).mName.length() && !ASSIMP_stricmp(sz, (*i).mName.c_str()))	{
  12.957 +				idx = cnt;
  12.958 +				break;
  12.959 +			}
  12.960 +		}
  12.961 +		if (0xcdcdcdcd == idx)	{
  12.962 +			DefaultLogger::get()->error(std::string("3DS: Unknown material: ") + sz);
  12.963 +		}
  12.964 +
  12.965 +		// Now continue and read all material indices
  12.966 +		cnt = (uint16_t)stream->GetI2();
  12.967 +		for (unsigned int i = 0; i < cnt;++i)	{
  12.968 +			unsigned int fidx = (uint16_t)stream->GetI2();
  12.969 +
  12.970 +			// check range
  12.971 +			if (fidx >= mMesh.mFaceMaterials.size())	{
  12.972 +				DefaultLogger::get()->error("3DS: Invalid face index in face material list");
  12.973 +			}
  12.974 +			else mMesh.mFaceMaterials[fidx] = idx;
  12.975 +		}}
  12.976 +		break;
  12.977 +	};
  12.978 +	ASSIMP_3DS_END_CHUNK();
  12.979 +}
  12.980 +
  12.981 +// ------------------------------------------------------------------------------------------------
  12.982 +// Read a mesh chunk. Here's the actual mesh data
  12.983 +void Discreet3DSImporter::ParseMeshChunk()
  12.984 +{
  12.985 +	ASSIMP_3DS_BEGIN_CHUNK();
  12.986 +
  12.987 +	// Get the mesh we're currently working on
  12.988 +	D3DS::Mesh& mMesh = mScene->mMeshes.back();
  12.989 +
  12.990 +	// get chunk type
  12.991 +	switch (chunk.Flag)
  12.992 +	{
  12.993 +	case Discreet3DS::CHUNK_VERTLIST:
  12.994 +		{
  12.995 +		// This is the list of all vertices in the current mesh
  12.996 +		int num = (int)(uint16_t)stream->GetI2();
  12.997 +		mMesh.mPositions.reserve(num);
  12.998 +		while (num-- > 0)	{
  12.999 +			aiVector3D v;
 12.1000 +			v.x = stream->GetF4();
 12.1001 +			v.y = stream->GetF4();
 12.1002 +			v.z = stream->GetF4();
 12.1003 +			mMesh.mPositions.push_back(v);
 12.1004 +		}}
 12.1005 +		break;
 12.1006 +	case Discreet3DS::CHUNK_TRMATRIX:
 12.1007 +		{
 12.1008 +		// This is the RLEATIVE transformation matrix of the current mesh. Vertices are
 12.1009 +		// pretransformed by this matrix wonder.
 12.1010 +		mMesh.mMat.a1 = stream->GetF4();
 12.1011 +		mMesh.mMat.b1 = stream->GetF4();
 12.1012 +		mMesh.mMat.c1 = stream->GetF4();
 12.1013 +		mMesh.mMat.a2 = stream->GetF4();
 12.1014 +		mMesh.mMat.b2 = stream->GetF4();
 12.1015 +		mMesh.mMat.c2 = stream->GetF4();
 12.1016 +		mMesh.mMat.a3 = stream->GetF4();
 12.1017 +		mMesh.mMat.b3 = stream->GetF4();
 12.1018 +		mMesh.mMat.c3 = stream->GetF4();
 12.1019 +		mMesh.mMat.a4 = stream->GetF4();
 12.1020 +		mMesh.mMat.b4 = stream->GetF4();
 12.1021 +		mMesh.mMat.c4 = stream->GetF4();
 12.1022 +		}
 12.1023 +		break;
 12.1024 +
 12.1025 +	case Discreet3DS::CHUNK_MAPLIST:
 12.1026 +		{
 12.1027 +		// This is the list of all UV coords in the current mesh
 12.1028 +		int num = (int)(uint16_t)stream->GetI2();
 12.1029 +		mMesh.mTexCoords.reserve(num);
 12.1030 +		while (num-- > 0)	{
 12.1031 +			aiVector3D v;
 12.1032 +			v.x = stream->GetF4();
 12.1033 +			v.y = stream->GetF4();
 12.1034 +			mMesh.mTexCoords.push_back(v);
 12.1035 +		}}
 12.1036 +		break;
 12.1037 +
 12.1038 +	case Discreet3DS::CHUNK_FACELIST:
 12.1039 +		{
 12.1040 +		// This is the list of all faces in the current mesh
 12.1041 +		int num = (int)(uint16_t)stream->GetI2();
 12.1042 +		mMesh.mFaces.reserve(num);
 12.1043 +		while (num-- > 0)	{
 12.1044 +			// 3DS faces are ALWAYS triangles
 12.1045 +			mMesh.mFaces.push_back(D3DS::Face());
 12.1046 +			D3DS::Face& sFace = mMesh.mFaces.back();
 12.1047 +
 12.1048 +			sFace.mIndices[0] = (uint16_t)stream->GetI2();
 12.1049 +			sFace.mIndices[1] = (uint16_t)stream->GetI2();
 12.1050 +			sFace.mIndices[2] = (uint16_t)stream->GetI2();
 12.1051 +
 12.1052 +			stream->IncPtr(2); // skip edge visibility flag
 12.1053 +		}
 12.1054 +
 12.1055 +		// Resize the material array (0xcdcdcdcd marks the default material; so if a face is 
 12.1056 +		// not referenced by a material, $$DEFAULT will be assigned to it)
 12.1057 +		mMesh.mFaceMaterials.resize(mMesh.mFaces.size(),0xcdcdcdcd);
 12.1058 +
 12.1059 +		// Larger 3DS files could have multiple FACE chunks here
 12.1060 +		chunkSize = stream->GetRemainingSizeToLimit();
 12.1061 +		if ( chunkSize > (int) sizeof(Discreet3DS::Chunk ) )
 12.1062 +			ParseFaceChunk();
 12.1063 +		}
 12.1064 +		break;
 12.1065 +	};
 12.1066 +	ASSIMP_3DS_END_CHUNK();
 12.1067 +}
 12.1068 +
 12.1069 +// ------------------------------------------------------------------------------------------------
 12.1070 +// Read a 3DS material chunk
 12.1071 +void Discreet3DSImporter::ParseMaterialChunk()
 12.1072 +{
 12.1073 +	ASSIMP_3DS_BEGIN_CHUNK();
 12.1074 +	switch (chunk.Flag)
 12.1075 +	{
 12.1076 +	case Discreet3DS::CHUNK_MAT_MATNAME:
 12.1077 +
 12.1078 +		{
 12.1079 +		// The material name string is already zero-terminated, but we need to be sure ...
 12.1080 +		const char* sz = (const char*)stream->GetPtr();
 12.1081 +		unsigned int cnt = 0;
 12.1082 +		while (stream->GetI1())
 12.1083 +			++cnt;
 12.1084 +
 12.1085 +		if (!cnt)	{
 12.1086 +			// This may not be, we use the default name instead
 12.1087 +			DefaultLogger::get()->error("3DS: Empty material name");
 12.1088 +		}
 12.1089 +		else mScene->mMaterials.back().mName = std::string(sz,cnt);
 12.1090 +		}
 12.1091 +		break;
 12.1092 +
 12.1093 +	case Discreet3DS::CHUNK_MAT_DIFFUSE:
 12.1094 +		{
 12.1095 +		// This is the diffuse material color
 12.1096 +		aiColor3D* pc = &mScene->mMaterials.back().mDiffuse;
 12.1097 +		ParseColorChunk(pc);
 12.1098 +		if (is_qnan(pc->r))	{
 12.1099 +			// color chunk is invalid. Simply ignore it
 12.1100 +			DefaultLogger::get()->error("3DS: Unable to read DIFFUSE chunk");
 12.1101 +			pc->r = pc->g = pc->b = 1.0f;
 12.1102 +		}}
 12.1103 +		break;
 12.1104 +
 12.1105 +	case Discreet3DS::CHUNK_MAT_SPECULAR:
 12.1106 +		{
 12.1107 +		// This is the specular material color
 12.1108 +		aiColor3D* pc = &mScene->mMaterials.back().mSpecular;
 12.1109 +		ParseColorChunk(pc);
 12.1110 +		if (is_qnan(pc->r))	{
 12.1111 +			// color chunk is invalid. Simply ignore it
 12.1112 +			DefaultLogger::get()->error("3DS: Unable to read SPECULAR chunk");
 12.1113 +			pc->r = pc->g = pc->b = 1.0f;
 12.1114 +		}}
 12.1115 +		break;
 12.1116 +
 12.1117 +	case Discreet3DS::CHUNK_MAT_AMBIENT:
 12.1118 +		{
 12.1119 +		// This is the ambient material color
 12.1120 +		aiColor3D* pc = &mScene->mMaterials.back().mAmbient;
 12.1121 +		ParseColorChunk(pc);
 12.1122 +		if (is_qnan(pc->r))	{
 12.1123 +			// color chunk is invalid. Simply ignore it
 12.1124 +			DefaultLogger::get()->error("3DS: Unable to read AMBIENT chunk");
 12.1125 +			pc->r = pc->g = pc->b = 0.0f;
 12.1126 +		}}
 12.1127 +		break;
 12.1128 +
 12.1129 +	case Discreet3DS::CHUNK_MAT_SELF_ILLUM:
 12.1130 +		{
 12.1131 +		// This is the emissive material color
 12.1132 +		aiColor3D* pc = &mScene->mMaterials.back().mEmissive;
 12.1133 +		ParseColorChunk(pc);
 12.1134 +		if (is_qnan(pc->r))	{
 12.1135 +			// color chunk is invalid. Simply ignore it
 12.1136 +			DefaultLogger::get()->error("3DS: Unable to read EMISSIVE chunk");
 12.1137 +			pc->r = pc->g = pc->b = 0.0f;
 12.1138 +		}}
 12.1139 +		break;
 12.1140 +
 12.1141 +	case Discreet3DS::CHUNK_MAT_TRANSPARENCY:
 12.1142 +		{
 12.1143 +		// This is the material's transparency
 12.1144 +		float* pcf = &mScene->mMaterials.back().mTransparency;
 12.1145 +		*pcf = ParsePercentageChunk();
 12.1146 +
 12.1147 +		// NOTE: transparency, not opacity
 12.1148 +		if (is_qnan(*pcf))
 12.1149 +			*pcf = 1.0f;
 12.1150 +		else *pcf = 1.0f - *pcf * (float)0xFFFF / 100.0f;
 12.1151 +		}
 12.1152 +		break;
 12.1153 +
 12.1154 +	case Discreet3DS::CHUNK_MAT_SHADING:
 12.1155 +		// This is the material shading mode
 12.1156 +		mScene->mMaterials.back().mShading = (D3DS::Discreet3DS::shadetype3ds)stream->GetI2();
 12.1157 +		break;
 12.1158 +
 12.1159 +	case Discreet3DS::CHUNK_MAT_TWO_SIDE:
 12.1160 +		// This is the two-sided flag
 12.1161 +		mScene->mMaterials.back().mTwoSided = true;
 12.1162 +		break;
 12.1163 +
 12.1164 +	case Discreet3DS::CHUNK_MAT_SHININESS:
 12.1165 +		{ // This is the shininess of the material
 12.1166 +		float* pcf = &mScene->mMaterials.back().mSpecularExponent;
 12.1167 +		*pcf = ParsePercentageChunk();
 12.1168 +		if (is_qnan(*pcf))
 12.1169 +			*pcf = 0.0f;
 12.1170 +		else *pcf *= (float)0xFFFF;
 12.1171 +		}
 12.1172 +		break;
 12.1173 +
 12.1174 +	case Discreet3DS::CHUNK_MAT_SHININESS_PERCENT:
 12.1175 +		{ // This is the shininess strength of the material
 12.1176 +		float* pcf = &mScene->mMaterials.back().mShininessStrength;
 12.1177 +		*pcf = ParsePercentageChunk();
 12.1178 +		if (is_qnan(*pcf))
 12.1179 +			*pcf = 0.0f;
 12.1180 +		else *pcf *= (float)0xffff / 100.0f;
 12.1181 +		}
 12.1182 +		break;
 12.1183 +
 12.1184 +	case Discreet3DS::CHUNK_MAT_SELF_ILPCT:
 12.1185 +		{ // This is the self illumination strength of the material
 12.1186 +		float f = ParsePercentageChunk();
 12.1187 +		if (is_qnan(f))
 12.1188 +			f = 0.0f;
 12.1189 +		else f *= (float)0xFFFF / 100.0f;
 12.1190 +		mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f);
 12.1191 +		}
 12.1192 +		break;
 12.1193 +
 12.1194 +	// Parse texture chunks
 12.1195 +	case Discreet3DS::CHUNK_MAT_TEXTURE:
 12.1196 +		// Diffuse texture
 12.1197 +		ParseTextureChunk(&mScene->mMaterials.back().sTexDiffuse);
 12.1198 +		break;
 12.1199 +	case Discreet3DS::CHUNK_MAT_BUMPMAP:
 12.1200 +		// Height map
 12.1201 +		ParseTextureChunk(&mScene->mMaterials.back().sTexBump);
 12.1202 +		break;
 12.1203 +	case Discreet3DS::CHUNK_MAT_OPACMAP:
 12.1204 +		// Opacity texture
 12.1205 +		ParseTextureChunk(&mScene->mMaterials.back().sTexOpacity);
 12.1206 +		break;
 12.1207 +	case Discreet3DS::CHUNK_MAT_MAT_SHINMAP:
 12.1208 +		// Shininess map
 12.1209 +		ParseTextureChunk(&mScene->mMaterials.back().sTexShininess);
 12.1210 +		break;
 12.1211 +	case Discreet3DS::CHUNK_MAT_SPECMAP:
 12.1212 +		// Specular map
 12.1213 +		ParseTextureChunk(&mScene->mMaterials.back().sTexSpecular);
 12.1214 +		break;
 12.1215 +	case Discreet3DS::CHUNK_MAT_SELFIMAP:
 12.1216 +		// Self-illumination (emissive) map
 12.1217 +		ParseTextureChunk(&mScene->mMaterials.back().sTexEmissive);
 12.1218 +		break;
 12.1219 +	case Discreet3DS::CHUNK_MAT_REFLMAP:
 12.1220 +		// Reflection map
 12.1221 +		ParseTextureChunk(&mScene->mMaterials.back().sTexReflective);
 12.1222 +		break;
 12.1223 +	};
 12.1224 +	ASSIMP_3DS_END_CHUNK();
 12.1225 +}
 12.1226 +
 12.1227 +// ------------------------------------------------------------------------------------------------
 12.1228 +void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
 12.1229 +{
 12.1230 +	ASSIMP_3DS_BEGIN_CHUNK();
 12.1231 +
 12.1232 +	// get chunk type
 12.1233 +	switch (chunk.Flag)
 12.1234 +	{
 12.1235 +	case Discreet3DS::CHUNK_MAPFILE:
 12.1236 +		{
 12.1237 +		// The material name string is already zero-terminated, but we need to be sure ...
 12.1238 +		const char* sz = (const char*)stream->GetPtr();
 12.1239 +		unsigned int cnt = 0;
 12.1240 +		while (stream->GetI1())
 12.1241 +			++cnt;
 12.1242 +		pcOut->mMapName = std::string(sz,cnt);
 12.1243 +		}
 12.1244 +		break;
 12.1245 +
 12.1246 +
 12.1247 +	case Discreet3DS::CHUNK_PERCENTF:
 12.1248 +		// Manually parse the blend factor
 12.1249 +		pcOut->mTextureBlend = stream->GetF4();
 12.1250 +		break;
 12.1251 +
 12.1252 +	case Discreet3DS::CHUNK_PERCENTW:
 12.1253 +		// Manually parse the blend factor
 12.1254 +		pcOut->mTextureBlend = (float)((uint16_t)stream->GetI2()) / 100.0f;
 12.1255 +		break;
 12.1256 +
 12.1257 +	case Discreet3DS::CHUNK_MAT_MAP_USCALE:
 12.1258 +		// Texture coordinate scaling in the U direction
 12.1259 +		pcOut->mScaleU = stream->GetF4();
 12.1260 +		if (0.0f == pcOut->mScaleU)
 12.1261 +		{
 12.1262 +			DefaultLogger::get()->warn("Texture coordinate scaling in the x direction is zero. Assuming 1.");
 12.1263 +			pcOut->mScaleU = 1.0f;
 12.1264 +		}
 12.1265 +		break;
 12.1266 +	case Discreet3DS::CHUNK_MAT_MAP_VSCALE:
 12.1267 +		// Texture coordinate scaling in the V direction
 12.1268 +		pcOut->mScaleV = stream->GetF4();
 12.1269 +		if (0.0f == pcOut->mScaleV)
 12.1270 +		{
 12.1271 +			DefaultLogger::get()->warn("Texture coordinate scaling in the y direction is zero. Assuming 1.");
 12.1272 +			pcOut->mScaleV = 1.0f;
 12.1273 +		}
 12.1274 +		break;
 12.1275 +
 12.1276 +	case Discreet3DS::CHUNK_MAT_MAP_UOFFSET:
 12.1277 +		// Texture coordinate offset in the U direction
 12.1278 +		pcOut->mOffsetU = -stream->GetF4();
 12.1279 +		break;
 12.1280 +
 12.1281 +	case Discreet3DS::CHUNK_MAT_MAP_VOFFSET:
 12.1282 +		// Texture coordinate offset in the V direction
 12.1283 +		pcOut->mOffsetV = stream->GetF4();
 12.1284 +		break;
 12.1285 +
 12.1286 +	case Discreet3DS::CHUNK_MAT_MAP_ANG:
 12.1287 +		// Texture coordinate rotation, CCW in DEGREES
 12.1288 +		pcOut->mRotation = -AI_DEG_TO_RAD( stream->GetF4() );
 12.1289 +		break;
 12.1290 +
 12.1291 +	case Discreet3DS::CHUNK_MAT_MAP_TILING:
 12.1292 +		{
 12.1293 +		const uint16_t iFlags = stream->GetI2();
 12.1294 +
 12.1295 +		// Get the mapping mode (for both axes)
 12.1296 +		if (iFlags & 0x2u)
 12.1297 +			pcOut->mMapMode = aiTextureMapMode_Mirror;
 12.1298 +		
 12.1299 +		else if (iFlags & 0x10u)
 12.1300 +			pcOut->mMapMode = aiTextureMapMode_Decal;
 12.1301 +		
 12.1302 +		// wrapping in all remaining cases
 12.1303 +		else pcOut->mMapMode = aiTextureMapMode_Wrap;
 12.1304 +		}
 12.1305 +		break;
 12.1306 +	};
 12.1307 +
 12.1308 +	ASSIMP_3DS_END_CHUNK();
 12.1309 +}
 12.1310 +
 12.1311 +// ------------------------------------------------------------------------------------------------
 12.1312 +// Read a percentage chunk
 12.1313 +float Discreet3DSImporter::ParsePercentageChunk()
 12.1314 +{
 12.1315 +	Discreet3DS::Chunk chunk;
 12.1316 +	ReadChunk(&chunk);
 12.1317 +
 12.1318 +	if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag)
 12.1319 +		return stream->GetF4();
 12.1320 +	else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag)
 12.1321 +		return (float)((uint16_t)stream->GetI2()) / (float)0xFFFF;
 12.1322 +	return get_qnan();
 12.1323 +}
 12.1324 +
 12.1325 +// ------------------------------------------------------------------------------------------------
 12.1326 +// Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color
 12.1327 +void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
 12.1328 +	bool acceptPercent)
 12.1329 +{
 12.1330 +	ai_assert(out != NULL);
 12.1331 +
 12.1332 +	// error return value
 12.1333 +	const float qnan = get_qnan();
 12.1334 +	static const aiColor3D clrError = aiColor3D(qnan,qnan,qnan);
 12.1335 +
 12.1336 +	Discreet3DS::Chunk chunk;
 12.1337 +	ReadChunk(&chunk);
 12.1338 +	const unsigned int diff = chunk.Size - sizeof(Discreet3DS::Chunk);
 12.1339 +
 12.1340 +	bool bGamma = false;
 12.1341 +
 12.1342 +	// Get the type of the chunk
 12.1343 +	switch(chunk.Flag)
 12.1344 +	{
 12.1345 +	case Discreet3DS::CHUNK_LINRGBF:
 12.1346 +		bGamma = true;
 12.1347 +
 12.1348 +	case Discreet3DS::CHUNK_RGBF:
 12.1349 +		if (sizeof(float) * 3 > diff)	{
 12.1350 +			*out = clrError;
 12.1351 +			return;
 12.1352 +		}
 12.1353 +		out->r = stream->GetF4();
 12.1354 +		out->g = stream->GetF4();
 12.1355 +		out->b = stream->GetF4();
 12.1356 +		break;
 12.1357 +
 12.1358 +	case Discreet3DS::CHUNK_LINRGBB:
 12.1359 +		bGamma = true;
 12.1360 +	case Discreet3DS::CHUNK_RGBB:
 12.1361 +		if (sizeof(char) * 3 > diff)	{
 12.1362 +			*out = clrError;
 12.1363 +			return;
 12.1364 +		}
 12.1365 +		out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
 12.1366 +		out->g = (float)(uint8_t)stream->GetI1() / 255.0f;
 12.1367 +		out->b = (float)(uint8_t)stream->GetI1() / 255.0f;
 12.1368 +		break;
 12.1369 +
 12.1370 +	// Percentage chunks are accepted, too.
 12.1371 +	case Discreet3DS::CHUNK_PERCENTF:
 12.1372 +		if (acceptPercent && 4 <= diff)	{
 12.1373 +			out->g = out->b = out->r = stream->GetF4();
 12.1374 +			break;
 12.1375 +		}
 12.1376 +		*out = clrError;
 12.1377 +		return;
 12.1378 +
 12.1379 +	case Discreet3DS::CHUNK_PERCENTW:
 12.1380 +		if (acceptPercent && 1 <= diff)	{
 12.1381 +			out->g = out->b = out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
 12.1382 +			break;
 12.1383 +		}
 12.1384 +		*out = clrError;
 12.1385 +		return;
 12.1386 +
 12.1387 +	default:
 12.1388 +		stream->IncPtr(diff);
 12.1389 +		// Skip unknown chunks, hope this won't cause any problems.
 12.1390 +		return ParseColorChunk(out,acceptPercent);
 12.1391 +	};
 12.1392 +	(void)bGamma;
 12.1393 +}
 12.1394 +
 12.1395 +#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/libs/assimp/3DSLoader.h	Sat Feb 01 19:58:19 2014 +0200
    13.3 @@ -0,0 +1,280 @@
    13.4 +
    13.5 +/*
    13.6 +Open Asset Import Library (assimp)
    13.7 +----------------------------------------------------------------------
    13.8 +
    13.9 +Copyright (c) 2006-2012, assimp team
   13.10 +All rights reserved.
   13.11 +
   13.12 +Redistribution and use of this software in source and binary forms, 
   13.13 +with or without modification, are permitted provided that the 
   13.14 +following conditions are met:
   13.15 +
   13.16 +* Redistributions of source code must retain the above
   13.17 +  copyright notice, this list of conditions and the
   13.18 +  following disclaimer.
   13.19 +
   13.20 +* Redistributions in binary form must reproduce the above
   13.21 +  copyright notice, this list of conditions and the
   13.22 +  following disclaimer in the documentation and/or other
   13.23 +  materials provided with the distribution.
   13.24 +
   13.25 +* Neither the name of the assimp team, nor the names of its
   13.26 +  contributors may be used to endorse or promote products
   13.27 +  derived from this software without specific prior
   13.28 +  written permission of the assimp team.
   13.29 +
   13.30 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   13.31 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   13.32 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   13.33 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   13.34 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   13.35 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   13.36 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   13.37 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   13.38 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   13.39 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   13.40 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   13.41 +
   13.42 +----------------------------------------------------------------------
   13.43 +*/
   13.44 +
   13.45 +/** @file  3DSLoader.h
   13.46 + *  @brief 3DS File format loader
   13.47 + */
   13.48 +#ifndef AI_3DSIMPORTER_H_INC
   13.49 +#define AI_3DSIMPORTER_H_INC
   13.50 +
   13.51 +#include "BaseImporter.h"
   13.52 +#include "assimp/types.h"
   13.53 +
   13.54 +#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
   13.55 +
   13.56 +struct aiNode;
   13.57 +#include "3DSHelper.h"
   13.58 +
   13.59 +namespace Assimp	{
   13.60 +
   13.61 +
   13.62 +using namespace D3DS;
   13.63 +
   13.64 +// ---------------------------------------------------------------------------------
   13.65 +/** Importer class for 3D Studio r3 and r4 3DS files
   13.66 + */
   13.67 +class Discreet3DSImporter : public BaseImporter
   13.68 +{
   13.69 +public:
   13.70 +
   13.71 +	Discreet3DSImporter();
   13.72 +	~Discreet3DSImporter();
   13.73 +
   13.74 +public:
   13.75 +
   13.76 +	// -------------------------------------------------------------------
   13.77 +	/** Returns whether the class can handle the format of the given file. 
   13.78 +	 * See BaseImporter::CanRead() for details.	
   13.79 +	 */
   13.80 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
   13.81 +		bool checkSig) const;
   13.82 +
   13.83 +	// -------------------------------------------------------------------
   13.84 +	/** Called prior to ReadFile().
   13.85 +	 * The function is a request to the importer to update its configuration
   13.86 +	 * basing on the Importer's configuration property list.
   13.87 +	 */
   13.88 +	void SetupProperties(const Importer* pImp);
   13.89 +
   13.90 +protected:
   13.91 +
   13.92 +	// -------------------------------------------------------------------
   13.93 +	/** Return importer meta information.
   13.94 +	 * See #BaseImporter::GetInfo for the details
   13.95 +	 */
   13.96 +	const aiImporterDesc* GetInfo () const;
   13.97 +
   13.98 +	// -------------------------------------------------------------------
   13.99 +	/** Imports the given file into the given scene structure. 
  13.100 +	 * See BaseImporter::InternReadFile() for details
  13.101 +	 */
  13.102 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  13.103 +		IOSystem* pIOHandler);
  13.104 +
  13.105 +	// -------------------------------------------------------------------
  13.106 +	/** Converts a temporary material to the outer representation 
  13.107 +	 */
  13.108 +	void ConvertMaterial(D3DS::Material& p_cMat,
  13.109 +		aiMaterial& p_pcOut);
  13.110 +
  13.111 +	// -------------------------------------------------------------------
  13.112 +	/** Read a chunk
  13.113 +	 *
  13.114 +	 *  @param pcOut Receives the current chunk
  13.115 +	 */
  13.116 +	void ReadChunk(Discreet3DS::Chunk* pcOut);
  13.117 +
  13.118 +	// -------------------------------------------------------------------
  13.119 +	/** Parse a percentage chunk. mCurrent will point to the next
  13.120 +	* chunk behind afterwards. If no percentage chunk is found
  13.121 +	* QNAN is returned.
  13.122 +	*/
  13.123 +	float ParsePercentageChunk();
  13.124 +
  13.125 +	// -------------------------------------------------------------------
  13.126 +	/** Parse a color chunk. mCurrent will point to the next
  13.127 +	* chunk behind afterwards. If no color chunk is found
  13.128 +	* QNAN is returned in all members.
  13.129 +	*/
  13.130 +	void ParseColorChunk(aiColor3D* p_pcOut,
  13.131 +		bool p_bAcceptPercent = true);
  13.132 +
  13.133 +
  13.134 +	// -------------------------------------------------------------------
  13.135 +	/** Skip a chunk in the file
  13.136 +	*/
  13.137 +	void SkipChunk();
  13.138 +
  13.139 +	// -------------------------------------------------------------------
  13.140 +	/** Generate the nodegraph
  13.141 +	*/
  13.142 +	void GenerateNodeGraph(aiScene* pcOut);
  13.143 +
  13.144 +	// -------------------------------------------------------------------
  13.145 +	/** Parse a main top-level chunk in the file
  13.146 +	*/
  13.147 +	void ParseMainChunk();
  13.148 +
  13.149 +	// -------------------------------------------------------------------
  13.150 +	/** Parse a top-level chunk in the file
  13.151 +	*/
  13.152 +	void ParseChunk(const char* name, unsigned int num);
  13.153 +
  13.154 +	// -------------------------------------------------------------------
  13.155 +	/** Parse a top-level editor chunk in the file
  13.156 +	*/
  13.157 +	void ParseEditorChunk();
  13.158 +
  13.159 +	// -------------------------------------------------------------------
  13.160 +	/** Parse a top-level object chunk in the file
  13.161 +	*/
  13.162 +	void ParseObjectChunk();
  13.163 +
  13.164 +	// -------------------------------------------------------------------
  13.165 +	/** Parse a material chunk in the file
  13.166 +	*/
  13.167 +	void ParseMaterialChunk();
  13.168 +
  13.169 +	// -------------------------------------------------------------------
  13.170 +	/** Parse a mesh chunk in the file
  13.171 +	*/
  13.172 +	void ParseMeshChunk();
  13.173 +
  13.174 +	// -------------------------------------------------------------------
  13.175 +	/** Parse a light chunk in the file
  13.176 +	*/
  13.177 +	void ParseLightChunk();
  13.178 +
  13.179 +	// -------------------------------------------------------------------
  13.180 +	/** Parse a camera chunk in the file
  13.181 +	*/
  13.182 +	void ParseCameraChunk();
  13.183 +
  13.184 +	// -------------------------------------------------------------------
  13.185 +	/** Parse a face list chunk in the file
  13.186 +	*/
  13.187 +	void ParseFaceChunk();
  13.188 +
  13.189 +	// -------------------------------------------------------------------
  13.190 +	/** Parse a keyframe chunk in the file
  13.191 +	*/
  13.192 +	void ParseKeyframeChunk();
  13.193 +
  13.194 +	// -------------------------------------------------------------------
  13.195 +	/** Parse a hierarchy chunk in the file
  13.196 +	*/
  13.197 +	void ParseHierarchyChunk(uint16_t parent);
  13.198 +
  13.199 +	// -------------------------------------------------------------------
  13.200 +	/** Parse a texture chunk in the file
  13.201 +	*/
  13.202 +	void ParseTextureChunk(D3DS::Texture* pcOut);
  13.203 +
  13.204 +	// -------------------------------------------------------------------
  13.205 +	/** Convert the meshes in the file
  13.206 +	*/
  13.207 +	void ConvertMeshes(aiScene* pcOut);
  13.208 +
  13.209 +	// -------------------------------------------------------------------
  13.210 +	/** Replace the default material in the scene
  13.211 +	*/
  13.212 +	void ReplaceDefaultMaterial();
  13.213 +
  13.214 +	// -------------------------------------------------------------------
  13.215 +	/** Convert the whole scene
  13.216 +	*/
  13.217 +	void ConvertScene(aiScene* pcOut);
  13.218 +
  13.219 +	// -------------------------------------------------------------------
  13.220 +	/** generate unique vertices for a mesh
  13.221 +	*/
  13.222 +	void MakeUnique(D3DS::Mesh& sMesh);
  13.223 +
  13.224 +	// -------------------------------------------------------------------
  13.225 +	/** Add a node to the node graph
  13.226 +	*/
  13.227 +	void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
  13.228 +		aiMatrix4x4& absTrafo);
  13.229 +
  13.230 +	// -------------------------------------------------------------------
  13.231 +	/** Search for a node in the graph.
  13.232 +	* Called recursively
  13.233 +	*/
  13.234 +	void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
  13.235 +
  13.236 +	// -------------------------------------------------------------------
  13.237 +	/** Apply the master scaling factor to the mesh
  13.238 +	*/
  13.239 +	void ApplyMasterScale(aiScene* pScene);
  13.240 +
  13.241 +	// -------------------------------------------------------------------
  13.242 +	/** Clamp all indices in the file to a valid range
  13.243 +	*/
  13.244 +	void CheckIndices(D3DS::Mesh& sMesh);
  13.245 +
  13.246 +	// -------------------------------------------------------------------
  13.247 +	/** Skip the TCB info in a track key
  13.248 +	*/
  13.249 +	void SkipTCBInfo();
  13.250 +
  13.251 +protected:
  13.252 +
  13.253 +	/** Stream to read from */
  13.254 +	StreamReaderLE* stream;
  13.255 +
  13.256 +	/** Last touched node index */
  13.257 +	short mLastNodeIndex;
  13.258 +
  13.259 +	/** Current node, root node */
  13.260 +	D3DS::Node* mCurrentNode, *mRootNode;
  13.261 +
  13.262 +	/** Scene under construction */
  13.263 +	D3DS::Scene* mScene;
  13.264 +
  13.265 +	/** Ambient base color of the scene */
  13.266 +	aiColor3D mClrAmbient;
  13.267 +
  13.268 +	/** Master scaling factor of the scene */
  13.269 +	float mMasterScale;
  13.270 +
  13.271 +	/** Path to the background image of the scene */
  13.272 +	std::string mBackgroundImage;
  13.273 +	bool bHasBG;
  13.274 +
  13.275 +	/** true if PRJ file */
  13.276 +	bool bIsPrj;
  13.277 +};
  13.278 +
  13.279 +#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
  13.280 +
  13.281 +} // end of namespace Assimp
  13.282 +
  13.283 +#endif // AI_3DSIMPORTER_H_INC
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/libs/assimp/ACLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
    14.3 @@ -0,0 +1,866 @@
    14.4 +
    14.5 +/*
    14.6 +---------------------------------------------------------------------------
    14.7 +Open Asset Import Library (assimp)
    14.8 +---------------------------------------------------------------------------
    14.9 +
   14.10 +Copyright (c) 2006-2012, assimp team
   14.11 +
   14.12 +All rights reserved.
   14.13 +
   14.14 +Redistribution and use of this software in source and binary forms, 
   14.15 +with or without modification, are permitted provided that the following 
   14.16 +conditions are met:
   14.17 +
   14.18 +* Redistributions of source code must retain the above
   14.19 +  copyright notice, this list of conditions and the
   14.20 +  following disclaimer.
   14.21 +
   14.22 +* Redistributions in binary form must reproduce the above
   14.23 +  copyright notice, this list of conditions and the
   14.24 +  following disclaimer in the documentation and/or other
   14.25 +  materials provided with the distribution.
   14.26 +
   14.27 +* Neither the name of the assimp team, nor the names of its
   14.28 +  contributors may be used to endorse or promote products
   14.29 +  derived from this software without specific prior
   14.30 +  written permission of the assimp team.
   14.31 +
   14.32 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   14.33 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   14.34 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   14.35 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   14.36 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   14.37 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   14.38 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   14.39 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   14.40 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   14.41 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   14.42 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   14.43 +---------------------------------------------------------------------------
   14.44 +*/
   14.45 +
   14.46 +/** @file Implementation of the AC3D importer class */
   14.47 +
   14.48 +#include "AssimpPCH.h"
   14.49 +
   14.50 +#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
   14.51 +
   14.52 +// internal headers
   14.53 +#include "ACLoader.h"
   14.54 +#include "ParsingUtils.h"
   14.55 +#include "fast_atof.h"
   14.56 +#include "Subdivision.h"
   14.57 +
   14.58 +using namespace Assimp;
   14.59 +
   14.60 +static const aiImporterDesc desc = {
   14.61 +	"AC3D Importer",
   14.62 +	"",
   14.63 +	"",
   14.64 +	"",
   14.65 +	aiImporterFlags_SupportTextFlavour,
   14.66 +	0,
   14.67 +	0,
   14.68 +	0,
   14.69 +	0,
   14.70 +	"ac acc ac3d"
   14.71 +};
   14.72 +
   14.73 +// ------------------------------------------------------------------------------------------------
   14.74 +// skip to the next token
   14.75 +#define AI_AC_SKIP_TO_NEXT_TOKEN() \
   14.76 +	if (!SkipSpaces(&buffer)) \
   14.77 +	{ \
   14.78 +		DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL"); \
   14.79 +		continue; \
   14.80 +	} 
   14.81 +
   14.82 +// ------------------------------------------------------------------------------------------------
   14.83 +// read a string (may be enclosed in double quotation marks). buffer must point to "
   14.84 +#define AI_AC_GET_STRING(out) \
   14.85 +	++buffer; \
   14.86 +	const char* sz = buffer; \
   14.87 +	while ('\"' != *buffer) \
   14.88 +	{ \
   14.89 +		if (IsLineEnd( *buffer )) \
   14.90 +		{ \
   14.91 +			DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL in string"); \
   14.92 +			out = "ERROR"; \
   14.93 +			break; \
   14.94 +		} \
   14.95 +		++buffer; \
   14.96 +	} \
   14.97 +	if (IsLineEnd( *buffer ))continue; \
   14.98 +	out = std::string(sz,(unsigned int)(buffer-sz)); \
   14.99 +	++buffer;
  14.100 +
  14.101 +
  14.102 +// ------------------------------------------------------------------------------------------------
  14.103 +// read 1 to n floats prefixed with an optional predefined identifier 
  14.104 +#define AI_AC_CHECKED_LOAD_FLOAT_ARRAY(name,name_length,num,out) \
  14.105 +	AI_AC_SKIP_TO_NEXT_TOKEN(); \
  14.106 +	if (name_length) \
  14.107 +	{ \
  14.108 +		if (strncmp(buffer,name,name_length) || !IsSpace(buffer[name_length])) \
  14.109 +		{ \
  14.110 +			DefaultLogger::get()->error("AC3D: Unexpexted token. " name " was expected."); \
  14.111 +			continue; \
  14.112 +		} \
  14.113 +		buffer += name_length+1; \
  14.114 +	} \
  14.115 +	for (unsigned int i = 0; i < num;++i) \
  14.116 +	{ \
  14.117 +		AI_AC_SKIP_TO_NEXT_TOKEN(); \
  14.118 +		buffer = fast_atoreal_move<float>(buffer,((float*)out)[i]); \
  14.119 +	}
  14.120 +
  14.121 +
  14.122 +// ------------------------------------------------------------------------------------------------
  14.123 +// Constructor to be privately used by Importer
  14.124 +AC3DImporter::AC3DImporter()
  14.125 +{
  14.126 +	// nothing to be done here
  14.127 +}
  14.128 +
  14.129 +// ------------------------------------------------------------------------------------------------
  14.130 +// Destructor, private as well 
  14.131 +AC3DImporter::~AC3DImporter()
  14.132 +{
  14.133 +	// nothing to be done here
  14.134 +}
  14.135 +
  14.136 +// ------------------------------------------------------------------------------------------------
  14.137 +// Returns whether the class can handle the format of the given file. 
  14.138 +bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  14.139 +{
  14.140 +	std::string extension = GetExtension(pFile);
  14.141 +
  14.142 +	// fixme: are acc and ac3d *really* used? Some sources say they are
  14.143 +	if(extension == "ac" || extension == "ac3d" || extension == "acc") {
  14.144 +		return true;
  14.145 +	}
  14.146 +	if (!extension.length() || checkSig) {
  14.147 +		uint32_t token = AI_MAKE_MAGIC("AC3D");
  14.148 +		return CheckMagicToken(pIOHandler,pFile,&token,1,0);
  14.149 +	}
  14.150 +	return false;
  14.151 +}
  14.152 +
  14.153 +// ------------------------------------------------------------------------------------------------
  14.154 +// Loader meta information
  14.155 +const aiImporterDesc* AC3DImporter::GetInfo () const
  14.156 +{
  14.157 +	return &desc;
  14.158 +}
  14.159 +
  14.160 +// ------------------------------------------------------------------------------------------------
  14.161 +// Get a pointer to the next line from the file
  14.162 +bool AC3DImporter::GetNextLine( )
  14.163 +{
  14.164 +	SkipLine(&buffer); 
  14.165 +	return SkipSpaces(&buffer);
  14.166 +}
  14.167 +
  14.168 +// ------------------------------------------------------------------------------------------------
  14.169 +// Parse an object section in an AC file
  14.170 +void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
  14.171 +{
  14.172 +	if (!TokenMatch(buffer,"OBJECT",6))
  14.173 +		return;
  14.174 +
  14.175 +	SkipSpaces(&buffer);
  14.176 +
  14.177 +	++mNumMeshes;
  14.178 +
  14.179 +	objects.push_back(Object());
  14.180 +	Object& obj = objects.back();
  14.181 +
  14.182 +	aiLight* light = NULL;
  14.183 +	if (!ASSIMP_strincmp(buffer,"light",5))
  14.184 +	{
  14.185 +		// This is a light source. Add it to the list
  14.186 +		mLights->push_back(light = new aiLight());
  14.187 +
  14.188 +		// Return a point light with no attenuation
  14.189 +		light->mType = aiLightSource_POINT;
  14.190 +		light->mColorDiffuse = light->mColorSpecular = aiColor3D(1.f,1.f,1.f);
  14.191 +		light->mAttenuationConstant = 1.f;
  14.192 +
  14.193 +		// Generate a default name for both the light source and the node
  14.194 +		// FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version.
  14.195 +		light->mName.length = ::sprintf(light->mName.data,"ACLight_%i",static_cast<unsigned int>(mLights->size())-1);
  14.196 +		obj.name = std::string( light->mName.data );
  14.197 +
  14.198 +		DefaultLogger::get()->debug("AC3D: Light source encountered");
  14.199 +		obj.type = Object::Light;
  14.200 +	}
  14.201 +	else if (!ASSIMP_strincmp(buffer,"group",5))
  14.202 +	{
  14.203 +		obj.type = Object::Group;
  14.204 +	}
  14.205 +	else if (!ASSIMP_strincmp(buffer,"world",5))
  14.206 +	{
  14.207 +		obj.type = Object::World;
  14.208 +	}
  14.209 +	else obj.type = Object::Poly;
  14.210 +	while (GetNextLine())
  14.211 +	{
  14.212 +		if (TokenMatch(buffer,"kids",4))
  14.213 +		{
  14.214 +			SkipSpaces(&buffer);
  14.215 +			unsigned int num = strtoul10(buffer,&buffer);
  14.216 +			GetNextLine();
  14.217 +			if (num)
  14.218 +			{
  14.219 +				// load the children of this object recursively
  14.220 +				obj.children.reserve(num);
  14.221 +				for (unsigned int i = 0; i < num; ++i)
  14.222 +					LoadObjectSection(obj.children);
  14.223 +			}
  14.224 +			return;
  14.225 +		}
  14.226 +		else if (TokenMatch(buffer,"name",4))
  14.227 +		{
  14.228 +			SkipSpaces(&buffer);
  14.229 +			AI_AC_GET_STRING(obj.name);
  14.230 +
  14.231 +			// If this is a light source, we'll also need to store
  14.232 +			// the name of the node in it.
  14.233 +			if (light)
  14.234 +			{
  14.235 +				light->mName.Set(obj.name);
  14.236 +			}
  14.237 +		}
  14.238 +		else if (TokenMatch(buffer,"texture",7))
  14.239 +		{
  14.240 +			SkipSpaces(&buffer);
  14.241 +			AI_AC_GET_STRING(obj.texture);
  14.242 +		}
  14.243 +		else if (TokenMatch(buffer,"texrep",6))
  14.244 +		{
  14.245 +			SkipSpaces(&buffer);
  14.246 +			AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texRepeat);
  14.247 +			if (!obj.texRepeat.x || !obj.texRepeat.y)
  14.248 +				obj.texRepeat = aiVector2D (1.f,1.f);
  14.249 +		}
  14.250 +		else if (TokenMatch(buffer,"texoff",6))
  14.251 +		{
  14.252 +			SkipSpaces(&buffer);
  14.253 +			AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texOffset);
  14.254 +		}
  14.255 +		else if (TokenMatch(buffer,"rot",3))
  14.256 +		{
  14.257 +			SkipSpaces(&buffer);
  14.258 +			AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,9,&obj.rotation);
  14.259 +		}
  14.260 +		else if (TokenMatch(buffer,"loc",3))
  14.261 +		{
  14.262 +			SkipSpaces(&buffer);
  14.263 +			AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&obj.translation);
  14.264 +		}
  14.265 +		else if (TokenMatch(buffer,"subdiv",6))
  14.266 +		{
  14.267 +			SkipSpaces(&buffer);
  14.268 +			obj.subDiv = strtoul10(buffer,&buffer);
  14.269 +		}
  14.270 +		else if (TokenMatch(buffer,"crease",6))
  14.271 +		{
  14.272 +			SkipSpaces(&buffer);
  14.273 +			obj.crease = fast_atof(buffer);
  14.274 +		}
  14.275 +		else if (TokenMatch(buffer,"numvert",7))
  14.276 +		{
  14.277 +			SkipSpaces(&buffer);
  14.278 +
  14.279 +			unsigned int t = strtoul10(buffer,&buffer);
  14.280 +			obj.vertices.reserve(t);
  14.281 +			for (unsigned int i = 0; i < t;++i)
  14.282 +			{
  14.283 +				if (!GetNextLine())
  14.284 +				{
  14.285 +					DefaultLogger::get()->error("AC3D: Unexpected EOF: not all vertices have been parsed yet");
  14.286 +					break;
  14.287 +				}
  14.288 +				else if (!IsNumeric(*buffer))
  14.289 +				{
  14.290 +					DefaultLogger::get()->error("AC3D: Unexpected token: not all vertices have been parsed yet");
  14.291 +					--buffer; // make sure the line is processed a second time
  14.292 +					break;
  14.293 +				}
  14.294 +				obj.vertices.push_back(aiVector3D());
  14.295 +				aiVector3D& v = obj.vertices.back();
  14.296 +				AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&v.x);
  14.297 +			}
  14.298 +		}
  14.299 +		else if (TokenMatch(buffer,"numsurf",7))
  14.300 +		{
  14.301 +			SkipSpaces(&buffer);
  14.302 +			
  14.303 +			bool Q3DWorkAround = false;
  14.304 +
  14.305 +			const unsigned int t = strtoul10(buffer,&buffer);
  14.306 +			obj.surfaces.reserve(t);
  14.307 +			for (unsigned int i = 0; i < t;++i)
  14.308 +			{
  14.309 +				GetNextLine();
  14.310 +				if (!TokenMatch(buffer,"SURF",4))
  14.311 +				{
  14.312 +					// FIX: this can occur for some files - Quick 3D for 
  14.313 +					// example writes no surf chunks
  14.314 +					if (!Q3DWorkAround)
  14.315 +					{
  14.316 +						DefaultLogger::get()->warn("AC3D: SURF token was expected");
  14.317 +						DefaultLogger::get()->debug("Continuing with Quick3D Workaround enabled");
  14.318 +					}
  14.319 +					--buffer; // make sure the line is processed a second time
  14.320 +					// break; --- see fix notes above
  14.321 +
  14.322 +					Q3DWorkAround = true;
  14.323 +				}
  14.324 +				SkipSpaces(&buffer);
  14.325 +				obj.surfaces.push_back(Surface());
  14.326 +				Surface& surf = obj.surfaces.back();
  14.327 +				surf.flags = strtoul_cppstyle(buffer);
  14.328 +			
  14.329 +				while (1)
  14.330 +				{
  14.331 +					if(!GetNextLine())
  14.332 +					{
  14.333 +						DefaultLogger::get()->error("AC3D: Unexpected EOF: surface is incomplete");
  14.334 +						break;
  14.335 +					}
  14.336 +					if (TokenMatch(buffer,"mat",3))
  14.337 +					{
  14.338 +						SkipSpaces(&buffer);
  14.339 +						surf.mat = strtoul10(buffer);
  14.340 +					}
  14.341 +					else if (TokenMatch(buffer,"refs",4))
  14.342 +					{
  14.343 +						// --- see fix notes above
  14.344 +						if (Q3DWorkAround)
  14.345 +						{
  14.346 +							if (!surf.entries.empty())
  14.347 +							{
  14.348 +								buffer -= 6;
  14.349 +								break;
  14.350 +							}
  14.351 +						}
  14.352 +
  14.353 +						SkipSpaces(&buffer);
  14.354 +						const unsigned int m = strtoul10(buffer);
  14.355 +						surf.entries.reserve(m);
  14.356 +
  14.357 +						obj.numRefs += m;
  14.358 +
  14.359 +						for (unsigned int k = 0; k < m; ++k)
  14.360 +						{
  14.361 +							if(!GetNextLine())
  14.362 +							{
  14.363 +								DefaultLogger::get()->error("AC3D: Unexpected EOF: surface references are incomplete");
  14.364 +								break;
  14.365 +							}
  14.366 +							surf.entries.push_back(Surface::SurfaceEntry());
  14.367 +							Surface::SurfaceEntry& entry = surf.entries.back();
  14.368 +
  14.369 +							entry.first = strtoul10(buffer,&buffer);
  14.370 +							SkipSpaces(&buffer);
  14.371 +							AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&entry.second);
  14.372 +						}
  14.373 +					}
  14.374 +					else 
  14.375 +					{
  14.376 +
  14.377 +						--buffer; // make sure the line is processed a second time
  14.378 +						break;
  14.379 +					}
  14.380 +				}
  14.381 +			}
  14.382 +		}
  14.383 +	}
  14.384 +	DefaultLogger::get()->error("AC3D: Unexpected EOF: \'kids\' line was expected");
  14.385 +}
  14.386 +
  14.387 +// ------------------------------------------------------------------------------------------------
  14.388 +// Convert a material from AC3DImporter::Material to aiMaterial
  14.389 +void AC3DImporter::ConvertMaterial(const Object& object,
  14.390 +	const Material& matSrc,
  14.391 +	aiMaterial& matDest)
  14.392 +{
  14.393 +	aiString s;
  14.394 +
  14.395 +	if (matSrc.name.length())
  14.396 +	{
  14.397 +		s.Set(matSrc.name);
  14.398 +		matDest.AddProperty(&s,AI_MATKEY_NAME);
  14.399 +	}
  14.400 +	if (object.texture.length())
  14.401 +	{
  14.402 +		s.Set(object.texture);
  14.403 +		matDest.AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
  14.404 +
  14.405 +		// UV transformation
  14.406 +		if (1.f != object.texRepeat.x || 1.f != object.texRepeat.y ||
  14.407 +			object.texOffset.x        || object.texOffset.y)
  14.408 +		{
  14.409 +			aiUVTransform transform;
  14.410 +			transform.mScaling = object.texRepeat;
  14.411 +			transform.mTranslation = object.texOffset;
  14.412 +			matDest.AddProperty(&transform,1,AI_MATKEY_UVTRANSFORM_DIFFUSE(0));
  14.413 +		}
  14.414 +	}
  14.415 +
  14.416 +	matDest.AddProperty<aiColor3D>(&matSrc.rgb,1, AI_MATKEY_COLOR_DIFFUSE);
  14.417 +	matDest.AddProperty<aiColor3D>(&matSrc.amb,1, AI_MATKEY_COLOR_AMBIENT);
  14.418 +	matDest.AddProperty<aiColor3D>(&matSrc.emis,1,AI_MATKEY_COLOR_EMISSIVE);
  14.419 +	matDest.AddProperty<aiColor3D>(&matSrc.spec,1,AI_MATKEY_COLOR_SPECULAR);
  14.420 +
  14.421 +	int n;
  14.422 +	if (matSrc.shin)
  14.423 +	{
  14.424 +		n = aiShadingMode_Phong;
  14.425 +		matDest.AddProperty<float>(&matSrc.shin,1,AI_MATKEY_SHININESS);
  14.426 +	}
  14.427 +	else n = aiShadingMode_Gouraud;
  14.428 +	matDest.AddProperty<int>(&n,1,AI_MATKEY_SHADING_MODEL);
  14.429 +
  14.430 +	float f = 1.f - matSrc.trans;
  14.431 +	matDest.AddProperty<float>(&f,1,AI_MATKEY_OPACITY);
  14.432 +}
  14.433 +
  14.434 +// ------------------------------------------------------------------------------------------------
  14.435 +// Converts the loaded data to the internal verbose representation
  14.436 +aiNode* AC3DImporter::ConvertObjectSection(Object& object,
  14.437 +	std::vector<aiMesh*>& meshes,
  14.438 +	std::vector<aiMaterial*>& outMaterials,
  14.439 +	const std::vector<Material>& materials,
  14.440 +	aiNode* parent)
  14.441 +{
  14.442 +	aiNode* node = new aiNode();
  14.443 +	node->mParent = parent;
  14.444 +	if (object.vertices.size())
  14.445 +	{
  14.446 +		if (!object.surfaces.size() || !object.numRefs)
  14.447 +		{
  14.448 +			/* " An object with 7 vertices (no surfaces, no materials defined). 
  14.449 +			     This is a good way of getting point data into AC3D. 
  14.450 +			     The Vertex->create convex-surface/object can be used on these
  14.451 +			     vertices to 'wrap' a 3d shape around them "
  14.452 +				 (http://www.opencity.info/html/ac3dfileformat.html)
  14.453 +
  14.454 +				 therefore: if no surfaces are defined return point data only
  14.455 +			 */
  14.456 +
  14.457 +			DefaultLogger::get()->info("AC3D: No surfaces defined in object definition, "
  14.458 +				"a point list is returned");
  14.459 +
  14.460 +			meshes.push_back(new aiMesh());
  14.461 +			aiMesh* mesh = meshes.back();
  14.462 +
  14.463 +			mesh->mNumFaces = mesh->mNumVertices = (unsigned int)object.vertices.size();
  14.464 +			aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
  14.465 +			aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
  14.466 +
  14.467 +			for (unsigned int i = 0; i < mesh->mNumVertices;++i,++faces,++verts)
  14.468 +			{
  14.469 +				*verts = object.vertices[i];
  14.470 +				faces->mNumIndices = 1;
  14.471 +				faces->mIndices = new unsigned int[1];
  14.472 +				faces->mIndices[0] = i;
  14.473 +			}
  14.474 +
  14.475 +			// use the primary material in this case. this should be the
  14.476 +			// default material if all objects of the file contain points
  14.477 +			// and no faces.
  14.478 +			mesh->mMaterialIndex = 0;
  14.479 +			outMaterials.push_back(new aiMaterial());
  14.480 +			ConvertMaterial(object, materials[0], *outMaterials.back());
  14.481 +		}
  14.482 +		else
  14.483 +		{
  14.484 +			// need to generate one or more meshes for this object.
  14.485 +			// find out how many different materials we have
  14.486 +			typedef std::pair< unsigned int, unsigned int > IntPair;
  14.487 +			typedef std::vector< IntPair > MatTable;
  14.488 +			MatTable needMat(materials.size(),IntPair(0,0));
  14.489 +
  14.490 +			std::vector<Surface>::iterator it,end = object.surfaces.end();
  14.491 +			std::vector<Surface::SurfaceEntry>::iterator it2,end2;
  14.492 +
  14.493 +			for (it = object.surfaces.begin(); it != end; ++it)
  14.494 +			{
  14.495 +				register unsigned int idx = (*it).mat;
  14.496 +				if (idx >= needMat.size())
  14.497 +				{
  14.498 +					DefaultLogger::get()->error("AC3D: material index is out of range");
  14.499 +					idx = 0;
  14.500 +				}
  14.501 +				if ((*it).entries.empty())
  14.502 +				{
  14.503 +					DefaultLogger::get()->warn("AC3D: surface her zero vertex references");
  14.504 +				}
  14.505 +
  14.506 +				// validate all vertex indices to make sure we won't crash here
  14.507 +				for (it2  = (*it).entries.begin(),
  14.508 +					 end2 = (*it).entries.end(); it2 != end2; ++it2)
  14.509 +				{
  14.510 +					if ((*it2).first >= object.vertices.size())
  14.511 +					{
  14.512 +						DefaultLogger::get()->warn("AC3D: Invalid vertex reference");
  14.513 +						(*it2).first = 0;
  14.514 +					}
  14.515 +				}
  14.516 +
  14.517 +				if (!needMat[idx].first)++node->mNumMeshes;
  14.518 +
  14.519 +				switch ((*it).flags & 0xf)
  14.520 +				{
  14.521 +					// closed line
  14.522 +				case 0x1:
  14.523 +
  14.524 +					needMat[idx].first  += (unsigned int)(*it).entries.size();
  14.525 +					needMat[idx].second += (unsigned int)(*it).entries.size()<<1u;
  14.526 +					break;
  14.527 +
  14.528 +					// unclosed line
  14.529 +				case 0x2:
  14.530 +
  14.531 +					needMat[idx].first  += (unsigned int)(*it).entries.size()-1;
  14.532 +					needMat[idx].second += ((unsigned int)(*it).entries.size()-1)<<1u;
  14.533 +					break;
  14.534 +
  14.535 +					// 0 == polygon, else unknown
  14.536 +				default:
  14.537 +
  14.538 +					if ((*it).flags & 0xf)
  14.539 +					{
  14.540 +						DefaultLogger::get()->warn("AC3D: The type flag of a surface is unknown");
  14.541 +						(*it).flags &= ~(0xf);
  14.542 +					}
  14.543 +
  14.544 +					// the number of faces increments by one, the number
  14.545 +					// of vertices by surface.numref.
  14.546 +					needMat[idx].first++;
  14.547 +					needMat[idx].second += (unsigned int)(*it).entries.size();
  14.548 +				};
  14.549 +			}
  14.550 +			unsigned int* pip = node->mMeshes = new unsigned int[node->mNumMeshes];
  14.551 +			unsigned int mat = 0;
  14.552 +			const size_t oldm = meshes.size();
  14.553 +			for (MatTable::const_iterator cit = needMat.begin(), cend = needMat.end();
  14.554 +				cit != cend; ++cit, ++mat)
  14.555 +			{
  14.556 +				if (!(*cit).first)continue;
  14.557 +
  14.558 +				// allocate a new aiMesh object
  14.559 +				*pip++ = (unsigned int)meshes.size();
  14.560 +				aiMesh* mesh = new aiMesh();
  14.561 +				meshes.push_back(mesh);
  14.562 +
  14.563 +				mesh->mMaterialIndex = (unsigned int)outMaterials.size();
  14.564 +				outMaterials.push_back(new aiMaterial());
  14.565 +				ConvertMaterial(object, materials[mat], *outMaterials.back());
  14.566 +
  14.567 +				// allocate storage for vertices and normals
  14.568 +				mesh->mNumFaces = (*cit).first;
  14.569 +				aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
  14.570 +
  14.571 +				mesh->mNumVertices = (*cit).second;
  14.572 +				aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
  14.573 +				unsigned int cur = 0;
  14.574 +
  14.575 +				// allocate UV coordinates, but only if the texture name for the
  14.576 +				// surface is not empty
  14.577 +				aiVector3D* uv = NULL;
  14.578 +				if(object.texture.length())
  14.579 +				{
  14.580 +					uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
  14.581 +					mesh->mNumUVComponents[0] = 2;
  14.582 +				}
  14.583 +
  14.584 +				for (it = object.surfaces.begin(); it != end; ++it)
  14.585 +				{
  14.586 +					if (mat == (*it).mat)
  14.587 +					{
  14.588 +						const Surface& src = *it;
  14.589 +
  14.590 +						// closed polygon
  14.591 +						unsigned int type = (*it).flags & 0xf; 
  14.592 +						if (!type)
  14.593 +						{
  14.594 +							aiFace& face = *faces++;
  14.595 +							if((face.mNumIndices = (unsigned int)src.entries.size()))
  14.596 +							{
  14.597 +								face.mIndices = new unsigned int[face.mNumIndices];
  14.598 +								for (unsigned int i = 0; i < face.mNumIndices;++i,++vertices)
  14.599 +								{
  14.600 +									const Surface::SurfaceEntry& entry = src.entries[i];
  14.601 +									face.mIndices[i] = cur++;
  14.602 +
  14.603 +									// copy vertex positions
  14.604 +									*vertices = object.vertices[entry.first] + object.translation;
  14.605 +
  14.606 +
  14.607 +									// copy texture coordinates 
  14.608 +									if (uv)
  14.609 +									{
  14.610 +										uv->x =  entry.second.x;
  14.611 +										uv->y =  entry.second.y;
  14.612 +										++uv;
  14.613 +									}
  14.614 +								}
  14.615 +							}
  14.616 +						}
  14.617 +						else
  14.618 +						{
  14.619 +							
  14.620 +							it2  = (*it).entries.begin();
  14.621 +
  14.622 +							// either a closed or an unclosed line
  14.623 +							register unsigned int tmp = (unsigned int)(*it).entries.size();
  14.624 +							if (0x2 == type)--tmp;
  14.625 +							for (unsigned int m = 0; m < tmp;++m)
  14.626 +							{
  14.627 +								aiFace& face = *faces++;
  14.628 +
  14.629 +								face.mNumIndices = 2;
  14.630 +								face.mIndices = new unsigned int[2];
  14.631 +								face.mIndices[0] = cur++;
  14.632 +								face.mIndices[1] = cur++;
  14.633 +
  14.634 +								// copy vertex positions
  14.635 +								*vertices++ = object.vertices[(*it2).first];
  14.636 +								
  14.637 +								// copy texture coordinates 
  14.638 +								if (uv)
  14.639 +								{
  14.640 +									uv->x =  (*it2).second.x;
  14.641 +									uv->y =  (*it2).second.y;
  14.642 +									++uv;
  14.643 +								}
  14.644 +
  14.645 +
  14.646 +								if (0x1 == type && tmp-1 == m)
  14.647 +								{
  14.648 +									// if this is a closed line repeat its beginning now
  14.649 +									it2  = (*it).entries.begin();
  14.650 +								}
  14.651 +								else ++it2;
  14.652 +
  14.653 +								// second point
  14.654 +								*vertices++ = object.vertices[(*it2).first];
  14.655 +
  14.656 +								if (uv)
  14.657 +								{
  14.658 +									uv->x =  (*it2).second.x;
  14.659 +									uv->y =  (*it2).second.y;
  14.660 +									++uv;
  14.661 +								}
  14.662 +							}
  14.663 +						}
  14.664 +					}
  14.665 +				}
  14.666 +			}
  14.667 +
  14.668 +			// Now apply catmull clark subdivision if necessary. We split meshes into
  14.669 +			// materials which is not done by AC3D during smoothing, so we need to
  14.670 +			// collect all meshes using the same material group.
  14.671 +			if (object.subDiv)	{
  14.672 +				if (configEvalSubdivision) {
  14.673 +					boost::scoped_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
  14.674 +					DefaultLogger::get()->info("AC3D: Evaluating subdivision surface: "+object.name);
  14.675 +
  14.676 +					std::vector<aiMesh*> cpy(meshes.size()-oldm,NULL);
  14.677 +					div->Subdivide(&meshes[oldm],cpy.size(),&cpy.front(),object.subDiv,true);
  14.678 +					std::copy(cpy.begin(),cpy.end(),meshes.begin()+oldm);
  14.679 +
  14.680 +					// previous meshes are deleted vy Subdivide().
  14.681 +				}
  14.682 +				else {
  14.683 +					DefaultLogger::get()->info("AC3D: Letting the subdivision surface untouched due to my configuration: "
  14.684 +						+object.name);
  14.685 +				}
  14.686 +			}
  14.687 +		}
  14.688 +	}
  14.689 +
  14.690 +	if (object.name.length())
  14.691 +		node->mName.Set(object.name);
  14.692 +	else
  14.693 +	{
  14.694 +		// generate a name depending on the type of the node
  14.695 +		switch (object.type)
  14.696 +		{
  14.697 +		case Object::Group:
  14.698 +			node->mName.length = ::sprintf(node->mName.data,"ACGroup_%i",groups++);
  14.699 +			break;
  14.700 +		case Object::Poly:
  14.701 +			node->mName.length = ::sprintf(node->mName.data,"ACPoly_%i",polys++);
  14.702 +			break;
  14.703 +		case Object::Light:
  14.704 +			node->mName.length = ::sprintf(node->mName.data,"ACLight_%i",lights++);
  14.705 +			break;
  14.706 +
  14.707 +			// there shouldn't be more than one world, but we don't care
  14.708 +		case Object::World: 
  14.709 +			node->mName.length = ::sprintf(node->mName.data,"ACWorld_%i",worlds++);
  14.710 +			break;
  14.711 +		}
  14.712 +	}
  14.713 +
  14.714 +
  14.715 +	// setup the local transformation matrix of the object
  14.716 +	// compute the transformation offset to the parent node
  14.717 +	node->mTransformation = aiMatrix4x4 ( object.rotation );
  14.718 +
  14.719 +	if (object.type == Object::Group || !object.numRefs)
  14.720 +	{
  14.721 +		node->mTransformation.a4 = object.translation.x;
  14.722 +		node->mTransformation.b4 = object.translation.y;
  14.723 +		node->mTransformation.c4 = object.translation.z;
  14.724 +	}
  14.725 +
  14.726 +	// add children to the object
  14.727 +	if (object.children.size())
  14.728 +	{
  14.729 +		node->mNumChildren = (unsigned int)object.children.size();
  14.730 +		node->mChildren = new aiNode*[node->mNumChildren];
  14.731 +		for (unsigned int i = 0; i < node->mNumChildren;++i)
  14.732 +		{
  14.733 +			node->mChildren[i] = ConvertObjectSection(object.children[i],meshes,outMaterials,materials,node);
  14.734 +		}
  14.735 +	}
  14.736 +
  14.737 +	return node;
  14.738 +}
  14.739 +
  14.740 +// ------------------------------------------------------------------------------------------------
  14.741 +void AC3DImporter::SetupProperties(const Importer* pImp)
  14.742 +{
  14.743 +	configSplitBFCull = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL,1) ? true : false;
  14.744 +	configEvalSubdivision =  pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION,1) ? true : false;
  14.745 +}
  14.746 +
  14.747 +// ------------------------------------------------------------------------------------------------
  14.748 +// Imports the given file into the given scene structure. 
  14.749 +void AC3DImporter::InternReadFile( const std::string& pFile, 
  14.750 +	aiScene* pScene, IOSystem* pIOHandler)
  14.751 +{
  14.752 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
  14.753 +
  14.754 +	// Check whether we can read from the file
  14.755 +	if( file.get() == NULL)
  14.756 +		throw DeadlyImportError( "Failed to open AC3D file " + pFile + ".");
  14.757 +
  14.758 +	// allocate storage and copy the contents of the file to a memory buffer
  14.759 +	std::vector<char> mBuffer2;
  14.760 +	TextFileToBuffer(file.get(),mBuffer2);
  14.761 +
  14.762 +	buffer = &mBuffer2[0];
  14.763 +	mNumMeshes = 0;
  14.764 +
  14.765 +	lights = polys = worlds = groups = 0;
  14.766 +
  14.767 +	if (::strncmp(buffer,"AC3D",4)) {
  14.768 +		throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found");
  14.769 +	}
  14.770 +
  14.771 +	// print the file format version to the console
  14.772 +	unsigned int version = HexDigitToDecimal( buffer[4] );
  14.773 +	char msg[3];
  14.774 +	ASSIMP_itoa10(msg,3,version);
  14.775 +	DefaultLogger::get()->info(std::string("AC3D file format version: ") + msg);
  14.776 +
  14.777 +	std::vector<Material> materials;
  14.778 +	materials.reserve(5);
  14.779 +
  14.780 +	std::vector<Object> rootObjects;
  14.781 +	rootObjects.reserve(5);
  14.782 +
  14.783 +	std::vector<aiLight*> lights;
  14.784 +	mLights = & lights;
  14.785 +
  14.786 +	while (GetNextLine())
  14.787 +	{
  14.788 +		if (TokenMatch(buffer,"MATERIAL",8))
  14.789 +		{
  14.790 +			materials.push_back(Material());
  14.791 +			Material& mat = materials.back();
  14.792 +
  14.793 +			// manually parse the material ... sscanf would use the buldin atof ...
  14.794 +			// Format: (name) rgb %f %f %f  amb %f %f %f  emis %f %f %f  spec %f %f %f  shi %d  trans %f
  14.795 +
  14.796 +			AI_AC_SKIP_TO_NEXT_TOKEN();
  14.797 +			if ('\"' == *buffer)
  14.798 +			{
  14.799 +				AI_AC_GET_STRING(mat.name);
  14.800 +				AI_AC_SKIP_TO_NEXT_TOKEN();
  14.801 +			}
  14.802 +
  14.803 +			AI_AC_CHECKED_LOAD_FLOAT_ARRAY("rgb",3,3,&mat.rgb);
  14.804 +			AI_AC_CHECKED_LOAD_FLOAT_ARRAY("amb",3,3,&mat.amb);
  14.805 +			AI_AC_CHECKED_LOAD_FLOAT_ARRAY("emis",4,3,&mat.emis);
  14.806 +			AI_AC_CHECKED_LOAD_FLOAT_ARRAY("spec",4,3,&mat.spec);
  14.807 +			AI_AC_CHECKED_LOAD_FLOAT_ARRAY("shi",3,1,&mat.shin);
  14.808 +			AI_AC_CHECKED_LOAD_FLOAT_ARRAY("trans",5,1,&mat.trans);
  14.809 +		}
  14.810 +		LoadObjectSection(rootObjects);
  14.811 +	}
  14.812 +
  14.813 +	if (rootObjects.empty() || !mNumMeshes)
  14.814 +	{
  14.815 +		throw DeadlyImportError("AC3D: No meshes have been loaded");
  14.816 +	}
  14.817 +	if (materials.empty())
  14.818 +	{
  14.819 +		DefaultLogger::get()->warn("AC3D: No material has been found");
  14.820 +		materials.push_back(Material());
  14.821 +	}
  14.822 +
  14.823 +	mNumMeshes += (mNumMeshes>>2u) + 1;
  14.824 +	std::vector<aiMesh*> meshes;
  14.825 +	meshes.reserve(mNumMeshes);
  14.826 +
  14.827 +	std::vector<aiMaterial*> omaterials;
  14.828 +	materials.reserve(mNumMeshes);
  14.829 +
  14.830 +	// generate a dummy root if there are multiple objects on the top layer
  14.831 +	Object* root;
  14.832 +	if (1 == rootObjects.size())
  14.833 +		root = &rootObjects[0];
  14.834 +	else
  14.835 +	{
  14.836 +		root = new Object();
  14.837 +	}
  14.838 +
  14.839 +	// now convert the imported stuff to our output data structure
  14.840 +	pScene->mRootNode = ConvertObjectSection(*root,meshes,omaterials,materials);
  14.841 +	if (1 != rootObjects.size())delete root;
  14.842 +
  14.843 +	if (!::strncmp( pScene->mRootNode->mName.data, "Node", 4))
  14.844 +		pScene->mRootNode->mName.Set("<AC3DWorld>");
  14.845 +
  14.846 +	// copy meshes
  14.847 +	if (meshes.empty())
  14.848 +	{
  14.849 +		throw DeadlyImportError("An unknown error occured during converting");
  14.850 +	}
  14.851 +	pScene->mNumMeshes = (unsigned int)meshes.size();
  14.852 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
  14.853 +	::memcpy(pScene->mMeshes,&meshes[0],pScene->mNumMeshes*sizeof(void*));
  14.854 +
  14.855 +	// copy materials
  14.856 +	pScene->mNumMaterials = (unsigned int)omaterials.size();
  14.857 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
  14.858 +	::memcpy(pScene->mMaterials,&omaterials[0],pScene->mNumMaterials*sizeof(void*));
  14.859 +
  14.860 +	// copy lights
  14.861 +	pScene->mNumLights = (unsigned int)lights.size();
  14.862 +	if (lights.size())
  14.863 +	{
  14.864 +		pScene->mLights = new aiLight*[lights.size()];
  14.865 +		::memcpy(pScene->mLights,&lights[0],lights.size()*sizeof(void*));
  14.866 +	}
  14.867 +}
  14.868 +
  14.869 +#endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/libs/assimp/ACLoader.h	Sat Feb 01 19:58:19 2014 +0200
    15.3 @@ -0,0 +1,267 @@
    15.4 +/*
    15.5 +Open Asset Import Library (assimp)
    15.6 +----------------------------------------------------------------------
    15.7 +
    15.8 +Copyright (c) 2006-2012, assimp team
    15.9 +All rights reserved.
   15.10 +
   15.11 +Redistribution and use of this software in source and binary forms, 
   15.12 +with or without modification, are permitted provided that the 
   15.13 +following conditions are met:
   15.14 +
   15.15 +* Redistributions of source code must retain the above
   15.16 +  copyright notice, this list of conditions and the
   15.17 +  following disclaimer.
   15.18 +
   15.19 +* Redistributions in binary form must reproduce the above
   15.20 +  copyright notice, this list of conditions and the
   15.21 +  following disclaimer in the documentation and/or other
   15.22 +  materials provided with the distribution.
   15.23 +
   15.24 +* Neither the name of the assimp team, nor the names of its
   15.25 +  contributors may be used to endorse or promote products
   15.26 +  derived from this software without specific prior
   15.27 +  written permission of the assimp team.
   15.28 +
   15.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   15.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   15.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   15.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   15.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   15.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   15.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   15.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   15.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   15.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   15.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   15.40 +
   15.41 +----------------------------------------------------------------------
   15.42 +*/
   15.43 +
   15.44 +/** @file  ACLoader.h
   15.45 + *  @brief Declaration of the .ac importer class.
   15.46 + */
   15.47 +#ifndef AI_AC3DLOADER_H_INCLUDED
   15.48 +#define AI_AC3DLOADER_H_INCLUDED
   15.49 +
   15.50 +#include <vector>
   15.51 +
   15.52 +#include "BaseImporter.h"
   15.53 +#include "assimp/types.h"
   15.54 +
   15.55 +namespace Assimp	{
   15.56 +
   15.57 +// ---------------------------------------------------------------------------
   15.58 +/** AC3D (*.ac) importer class
   15.59 +*/
   15.60 +class AC3DImporter : public BaseImporter
   15.61 +{
   15.62 +public:
   15.63 +	AC3DImporter();
   15.64 +	~AC3DImporter();
   15.65 +
   15.66 +
   15.67 +
   15.68 +	// Represents an AC3D material
   15.69 +	struct Material
   15.70 +	{
   15.71 +		Material()
   15.72 +			:	rgb		(0.6f,0.6f,0.6f)
   15.73 +			,	spec	(1.f,1.f,1.f)
   15.74 +			,	shin	(0.f)
   15.75 +			,	trans	(0.f)
   15.76 +		{}
   15.77 +
   15.78 +		// base color of the material
   15.79 +		aiColor3D rgb;
   15.80 +
   15.81 +		// ambient color of the material
   15.82 +		aiColor3D amb;
   15.83 +
   15.84 +		// emissive color of the material
   15.85 +		aiColor3D emis;
   15.86 +
   15.87 +		// specular color of the material
   15.88 +		aiColor3D spec;
   15.89 +
   15.90 +		// shininess exponent
   15.91 +		float shin;
   15.92 +
   15.93 +		// transparency. 0 == opaque
   15.94 +		float trans;
   15.95 +
   15.96 +		// name of the material. optional.
   15.97 +		std::string name;
   15.98 +	};
   15.99 +
  15.100 +	// Represents an AC3D surface
  15.101 +	struct Surface
  15.102 +	{
  15.103 +		Surface()
  15.104 +			:	mat		(0)
  15.105 +			,	flags	(0)
  15.106 +		{}
  15.107 +
  15.108 +		unsigned int mat,flags;
  15.109 +
  15.110 +		typedef std::pair<unsigned int, aiVector2D > SurfaceEntry;
  15.111 +		std::vector< SurfaceEntry > entries;
  15.112 +	};
  15.113 +
  15.114 +	// Represents an AC3D object
  15.115 +	struct Object
  15.116 +	{
  15.117 +		Object()
  15.118 +			:	type	(World)
  15.119 +			,	name( "" )
  15.120 +			,	children()
  15.121 +			,	texture( "" )
  15.122 +			,	texRepeat( 1.f, 1.f )
  15.123 +			,	texOffset( 0.0f, 0.0f )
  15.124 +			,	rotation()
  15.125 +			,	translation()
  15.126 +			,	vertices()
  15.127 +			,	surfaces()
  15.128 +			,	numRefs (0)
  15.129 +			,	subDiv	(0)                
  15.130 +		{}
  15.131 +
  15.132 +		// Type description
  15.133 +		enum Type
  15.134 +		{
  15.135 +			World = 0x0,
  15.136 +			Poly  = 0x1,
  15.137 +			Group = 0x2,
  15.138 +			Light = 0x4
  15.139 +		} type;
  15.140 +
  15.141 +		// name of the object
  15.142 +		std::string name;
  15.143 +
  15.144 +		// object children
  15.145 +		std::vector<Object> children;
  15.146 +
  15.147 +		// texture to be assigned to all surfaces of the object
  15.148 +		std::string texture;
  15.149 +
  15.150 +		// texture repat factors (scaling for all coordinates)
  15.151 +		aiVector2D texRepeat, texOffset;
  15.152 +
  15.153 +		// rotation matrix
  15.154 +		aiMatrix3x3 rotation;
  15.155 +
  15.156 +		// translation vector
  15.157 +		aiVector3D translation;
  15.158 +
  15.159 +		// vertices
  15.160 +		std::vector<aiVector3D> vertices;
  15.161 +
  15.162 +		// surfaces
  15.163 +		std::vector<Surface> surfaces;
  15.164 +
  15.165 +		// number of indices (= num verts in verbose format)
  15.166 +		unsigned int numRefs;
  15.167 +
  15.168 +		// number of subdivisions to be performed on the 
  15.169 +		// imported data
  15.170 +		unsigned int subDiv;
  15.171 +
  15.172 +		// max angle limit for smoothing
  15.173 +		float crease;
  15.174 +	};
  15.175 +
  15.176 +
  15.177 +public:
  15.178 +
  15.179 +	// -------------------------------------------------------------------
  15.180 +	/** Returns whether the class can handle the format of the given file. 
  15.181 +	 * See BaseImporter::CanRead() for details.
  15.182 +	 */
  15.183 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  15.184 +		bool checkSig) const;
  15.185 +
  15.186 +protected:
  15.187 +
  15.188 +	// -------------------------------------------------------------------
  15.189 +	/** Return importer meta information.
  15.190 +	 * See #BaseImporter::GetInfo for the details */
  15.191 +	const aiImporterDesc* GetInfo () const;
  15.192 +
  15.193 +	// -------------------------------------------------------------------
  15.194 +	/** Imports the given file into the given scene structure. 
  15.195 +	 * See BaseImporter::InternReadFile() for details*/
  15.196 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  15.197 +		IOSystem* pIOHandler);
  15.198 +
  15.199 +	// -------------------------------------------------------------------
  15.200 +	/** Called prior to ReadFile().
  15.201 +	* The function is a request to the importer to update its configuration
  15.202 +	* basing on the Importer's configuration property list.*/
  15.203 +	void SetupProperties(const Importer* pImp);
  15.204 +
  15.205 +private:
  15.206 +
  15.207 +	// -------------------------------------------------------------------
  15.208 +	/** Get the next line from the file.
  15.209 +	 *  @return false if the end of the file was reached*/
  15.210 +	bool GetNextLine();
  15.211 +
  15.212 +	// -------------------------------------------------------------------
  15.213 +	/** Load the object section. This method is called recursively to
  15.214 +	 *  load subobjects, the method returns after a 'kids 0' was 
  15.215 +	 *  encountered.
  15.216 +	 *  @objects List of output objects*/
  15.217 +	void LoadObjectSection(std::vector<Object>& objects);
  15.218 +
  15.219 +	// -------------------------------------------------------------------
  15.220 +	/** Convert all objects into meshes and nodes.
  15.221 +	 *  @param object Current object to work on
  15.222 +	 *  @param meshes Pointer to the list of output meshes
  15.223 +	 *  @param outMaterials List of output materials
  15.224 +	 *  @param materials Material list
  15.225 +	 *  @param Scenegraph node for the object */
  15.226 +	aiNode* ConvertObjectSection(Object& object,
  15.227 +		std::vector<aiMesh*>& meshes,
  15.228 +		std::vector<aiMaterial*>& outMaterials,
  15.229 +		const std::vector<Material>& materials,
  15.230 +		aiNode* parent = NULL);
  15.231 +
  15.232 +	// -------------------------------------------------------------------
  15.233 +	/** Convert a material
  15.234 +	 *  @param object Current object
  15.235 +	 *  @param matSrc Source material description
  15.236 +	 *  @param matDest Destination material to be filled */
  15.237 +	void ConvertMaterial(const Object& object,
  15.238 +		const Material& matSrc,
  15.239 +		aiMaterial& matDest);
  15.240 +
  15.241 +private:
  15.242 +
  15.243 +
  15.244 +	// points to the next data line
  15.245 +	const char* buffer;
  15.246 +
  15.247 +	// Configuration option: if enabled, up to two meshes
  15.248 +	// are generated per material: those faces who have 
  15.249 +	// their bf cull flags set are separated.
  15.250 +	bool configSplitBFCull;
  15.251 +
  15.252 +	// Configuration switch: subdivision surfaces are only
  15.253 +	// evaluated if the value is true.
  15.254 +	bool configEvalSubdivision;
  15.255 +
  15.256 +	// counts how many objects we have in the tree.
  15.257 +	// basing on this information we can find a
  15.258 +	// good estimate how many meshes we'll have in the final scene.
  15.259 +	unsigned int mNumMeshes;
  15.260 +
  15.261 +	// current list of light sources
  15.262 +	std::vector<aiLight*>* mLights;
  15.263 +
  15.264 +	// name counters
  15.265 +	unsigned int lights, groups, polys, worlds;
  15.266 +};
  15.267 +
  15.268 +} // end of namespace Assimp
  15.269 +
  15.270 +#endif // AI_AC3DIMPORTER_H_INC
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/libs/assimp/ASELoader.cpp	Sat Feb 01 19:58:19 2014 +0200
    16.3 @@ -0,0 +1,1317 @@
    16.4 +/*
    16.5 +---------------------------------------------------------------------------
    16.6 +Open Asset Import Library (assimp)
    16.7 +---------------------------------------------------------------------------
    16.8 +
    16.9 +Copyright (c) 2006-2012, assimp team
   16.10 +
   16.11 +All rights reserved.
   16.12 +
   16.13 +Redistribution and use of this software in source and binary forms, 
   16.14 +with or without modification, are permitted provided that the following 
   16.15 +conditions are met:
   16.16 +
   16.17 +* Redistributions of source code must retain the above
   16.18 +  copyright notice, this list of conditions and the
   16.19 +  following disclaimer.
   16.20 +
   16.21 +* Redistributions in binary form must reproduce the above
   16.22 +  copyright notice, this list of conditions and the
   16.23 +  following disclaimer in the documentation and/or other
   16.24 +  materials provided with the distribution.
   16.25 +
   16.26 +* Neither the name of the assimp team, nor the names of its
   16.27 +  contributors may be used to endorse or promote products
   16.28 +  derived from this software without specific prior
   16.29 +  written permission of the assimp team.
   16.30 +
   16.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   16.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   16.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   16.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   16.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   16.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   16.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   16.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   16.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   16.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   16.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   16.42 +---------------------------------------------------------------------------
   16.43 +*/
   16.44 +
   16.45 +/** @file  ASELoader.cpp
   16.46 + *  @brief Implementation of the ASE importer class
   16.47 + */
   16.48 +
   16.49 +#include "AssimpPCH.h"
   16.50 +#include "assimp/config.h"
   16.51 +#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
   16.52 +
   16.53 +// internal headers
   16.54 +#include "ASELoader.h"
   16.55 +#include "StringComparison.h"
   16.56 +#include "SkeletonMeshBuilder.h"
   16.57 +#include "TargetAnimation.h"
   16.58 +
   16.59 +// utilities
   16.60 +#include "fast_atof.h"
   16.61 +
   16.62 +using namespace Assimp;
   16.63 +using namespace Assimp::ASE;
   16.64 +
   16.65 +static const aiImporterDesc desc = {
   16.66 +	"ASE Importer",
   16.67 +	"",
   16.68 +	"",
   16.69 +	"Similar to 3DS but text-encoded",
   16.70 +	aiImporterFlags_SupportTextFlavour,
   16.71 +	0,
   16.72 +	0,
   16.73 +	0,
   16.74 +	0,
   16.75 +	"ase ask" 
   16.76 +};
   16.77 +
   16.78 +// ------------------------------------------------------------------------------------------------
   16.79 +// Constructor to be privately used by Importer
   16.80 +ASEImporter::ASEImporter()
   16.81 +: noSkeletonMesh()
   16.82 +{}
   16.83 +
   16.84 +// ------------------------------------------------------------------------------------------------
   16.85 +// Destructor, private as well 
   16.86 +ASEImporter::~ASEImporter()
   16.87 +{}
   16.88 +
   16.89 +// ------------------------------------------------------------------------------------------------
   16.90 +// Returns whether the class can handle the format of the given file. 
   16.91 +bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
   16.92 +{
   16.93 +	// check file extension 
   16.94 +	const std::string extension = GetExtension(pFile);
   16.95 +	
   16.96 +	if( extension == "ase" || extension == "ask")
   16.97 +		return true;
   16.98 +
   16.99 +	if ((!extension.length() || cs) && pIOHandler) {
  16.100 +		const char* tokens[] = {"*3dsmax_asciiexport"};
  16.101 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
  16.102 +	}
  16.103 +	return false;
  16.104 +}
  16.105 +
  16.106 +// ------------------------------------------------------------------------------------------------
  16.107 +// Loader meta information
  16.108 +const aiImporterDesc* ASEImporter::GetInfo () const
  16.109 +{
  16.110 +	return &desc;
  16.111 +}
  16.112 +
  16.113 +// ------------------------------------------------------------------------------------------------
  16.114 +// Setup configuration options
  16.115 +void ASEImporter::SetupProperties(const Importer* pImp)
  16.116 +{
  16.117 +	configRecomputeNormals = (pImp->GetPropertyInteger(
  16.118 +		AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS,1) ? true : false);
  16.119 +
  16.120 +	noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
  16.121 +}
  16.122 +
  16.123 +// ------------------------------------------------------------------------------------------------
  16.124 +// Imports the given file into the given scene structure. 
  16.125 +void ASEImporter::InternReadFile( const std::string& pFile, 
  16.126 +	aiScene* pScene, IOSystem* pIOHandler)
  16.127 +{
  16.128 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
  16.129 +
  16.130 +	// Check whether we can read from the file
  16.131 +	if( file.get() == NULL) {
  16.132 +		throw DeadlyImportError( "Failed to open ASE file " + pFile + ".");
  16.133 +	}
  16.134 +
  16.135 +	// Allocate storage and copy the contents of the file to a memory buffer
  16.136 +	std::vector<char> mBuffer2;
  16.137 +	TextFileToBuffer(file.get(),mBuffer2);
  16.138 +
  16.139 +	this->mBuffer = &mBuffer2[0];
  16.140 +	this->pcScene = pScene;
  16.141 +
  16.142 +	// ------------------------------------------------------------------
  16.143 +	// Guess the file format by looking at the extension
  16.144 +	// ASC is considered to be the older format 110,
  16.145 +	// ASE is the actual version 200 (that is currently written by max)
  16.146 +	// ------------------------------------------------------------------
  16.147 +	unsigned int defaultFormat;
  16.148 +	std::string::size_type s = pFile.length()-1;
  16.149 +	switch (pFile.c_str()[s])	{
  16.150 +
  16.151 +	case 'C':
  16.152 +	case 'c':
  16.153 +		defaultFormat = AI_ASE_OLD_FILE_FORMAT;
  16.154 +		break;
  16.155 +	default:
  16.156 +		defaultFormat = AI_ASE_NEW_FILE_FORMAT;
  16.157 +	};
  16.158 +
  16.159 +	// Construct an ASE parser and parse the file
  16.160 +	ASE::Parser parser(mBuffer,defaultFormat);
  16.161 +	mParser = &parser;
  16.162 +	mParser->Parse();
  16.163 +
  16.164 +	//------------------------------------------------------------------
  16.165 +	// Check whether we god at least one mesh. If we did - generate
  16.166 +	// materials and copy meshes. 
  16.167 +	// ------------------------------------------------------------------
  16.168 +	if ( !mParser->m_vMeshes.empty())	{
  16.169 +
  16.170 +		// If absolutely no material has been loaded from the file
  16.171 +		// we need to generate a default material
  16.172 +		GenerateDefaultMaterial();
  16.173 +
  16.174 +		// process all meshes
  16.175 +		bool tookNormals = false;
  16.176 +		std::vector<aiMesh*> avOutMeshes;
  16.177 +		avOutMeshes.reserve(mParser->m_vMeshes.size()*2);
  16.178 +		for (std::vector<ASE::Mesh>::iterator i =  mParser->m_vMeshes.begin();i != mParser->m_vMeshes.end();++i)	{
  16.179 +			if ((*i).bSkip) {
  16.180 +				continue;
  16.181 +			}
  16.182 +			BuildUniqueRepresentation(*i);
  16.183 +
  16.184 +			// Need to generate proper vertex normals if necessary
  16.185 +			if(GenerateNormals(*i)) {
  16.186 +				tookNormals = true;
  16.187 +			}
  16.188 +
  16.189 +			// Convert all meshes to aiMesh objects
  16.190 +			ConvertMeshes(*i,avOutMeshes);
  16.191 +		}
  16.192 +		if (tookNormals)	{
  16.193 +			DefaultLogger::get()->debug("ASE: Taking normals from the file. Use "
  16.194 +				"the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS setting if you "
  16.195 +				"experience problems");
  16.196 +		}
  16.197 +
  16.198 +		// Now build the output mesh list. Remove dummies
  16.199 +		pScene->mNumMeshes = (unsigned int)avOutMeshes.size();
  16.200 +		aiMesh** pp = pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
  16.201 +		for (std::vector<aiMesh*>::const_iterator i =  avOutMeshes.begin();i != avOutMeshes.end();++i) {
  16.202 +			if (!(*i)->mNumFaces) {
  16.203 +				continue;
  16.204 +			}
  16.205 +			*pp++ = *i;
  16.206 +		}
  16.207 +		pScene->mNumMeshes = (unsigned int)(pp - pScene->mMeshes);
  16.208 +
  16.209 +		// Build final material indices (remove submaterials and setup
  16.210 +		// the final list)
  16.211 +		BuildMaterialIndices();
  16.212 +	}
  16.213 +
  16.214 +	// ------------------------------------------------------------------
  16.215 +	// Copy all scene graph nodes - lights, cameras, dummies and meshes
  16.216 +	// into one huge list.
  16.217 +	//------------------------------------------------------------------
  16.218 +	std::vector<BaseNode*> nodes;
  16.219 +	nodes.reserve(mParser->m_vMeshes.size() +mParser->m_vLights.size()
  16.220 +		+ mParser->m_vCameras.size() + mParser->m_vDummies.size());
  16.221 +
  16.222 +	// Lights
  16.223 +	for (std::vector<ASE::Light>::iterator it = mParser->m_vLights.begin(), 
  16.224 +		 end = mParser->m_vLights.end();it != end; ++it)nodes.push_back(&(*it));
  16.225 +	// Cameras
  16.226 +	for (std::vector<ASE::Camera>::iterator it = mParser->m_vCameras.begin(), 
  16.227 +		 end = mParser->m_vCameras.end();it != end; ++it)nodes.push_back(&(*it));
  16.228 +	// Meshes
  16.229 +	for (std::vector<ASE::Mesh>::iterator it = mParser->m_vMeshes.begin(),
  16.230 +		end = mParser->m_vMeshes.end();it != end; ++it)nodes.push_back(&(*it));
  16.231 +	// Dummies
  16.232 +	for (std::vector<ASE::Dummy>::iterator it = mParser->m_vDummies.begin(),
  16.233 +		end = mParser->m_vDummies.end();it != end; ++it)nodes.push_back(&(*it));
  16.234 +
  16.235 +	// build the final node graph
  16.236 +	BuildNodes(nodes);
  16.237 +
  16.238 +	// build output animations
  16.239 +	BuildAnimations(nodes);
  16.240 +
  16.241 +	// build output cameras
  16.242 +	BuildCameras();
  16.243 +
  16.244 +	// build output lights
  16.245 +	BuildLights();
  16.246 +
  16.247 +	// ------------------------------------------------------------------
  16.248 +	// If we have no meshes use the SkeletonMeshBuilder helper class
  16.249 +	// to build a mesh for the animation skeleton
  16.250 +	// FIXME: very strange results
  16.251 +	// ------------------------------------------------------------------
  16.252 +	if (!pScene->mNumMeshes)	{
  16.253 +		pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
  16.254 +		if (!noSkeletonMesh) {
  16.255 +			SkeletonMeshBuilder skeleton(pScene);
  16.256 +		}
  16.257 +	}
  16.258 +}
  16.259 +// ------------------------------------------------------------------------------------------------
  16.260 +void ASEImporter::GenerateDefaultMaterial()
  16.261 +{
  16.262 +	ai_assert(NULL != mParser);
  16.263 +
  16.264 +	bool bHas = false;
  16.265 +	for (std::vector<ASE::Mesh>::iterator i =  mParser->m_vMeshes.begin();i != mParser->m_vMeshes.end();++i) {
  16.266 +		if ((*i).bSkip)continue;
  16.267 +		if (ASE::Face::DEFAULT_MATINDEX == (*i).iMaterialIndex)	{
  16.268 +			(*i).iMaterialIndex = (unsigned int)mParser->m_vMaterials.size();
  16.269 +			bHas = true;
  16.270 +		}
  16.271 +	}
  16.272 +	if (bHas || mParser->m_vMaterials.empty())	{
  16.273 +		// add a simple material without submaterials to the parser's list
  16.274 +		mParser->m_vMaterials.push_back ( ASE::Material() );
  16.275 +		ASE::Material& mat = mParser->m_vMaterials.back();
  16.276 +
  16.277 +		mat.mDiffuse  = aiColor3D(0.6f,0.6f,0.6f);
  16.278 +		mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
  16.279 +		mat.mAmbient  = aiColor3D(0.05f,0.05f,0.05f);
  16.280 +		mat.mShading  = Discreet3DS::Gouraud;
  16.281 +		mat.mName     = AI_DEFAULT_MATERIAL_NAME;
  16.282 +	}
  16.283 +}
  16.284 +
  16.285 +// ------------------------------------------------------------------------------------------------
  16.286 +void ASEImporter::BuildAnimations(const std::vector<BaseNode*>& nodes)
  16.287 +{
  16.288 +	// check whether we have at least one mesh which has animations
  16.289 +	std::vector<ASE::BaseNode*>::const_iterator i =  nodes.begin();
  16.290 +	unsigned int iNum = 0;
  16.291 +	for (;i != nodes.end();++i)	{
  16.292 +
  16.293 +		// TODO: Implement Bezier & TCB support
  16.294 +		if ((*i)->mAnim.mPositionType != ASE::Animation::TRACK)	{
  16.295 +			DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. "
  16.296 +				"This is not supported.");
  16.297 +		}
  16.298 +		if ((*i)->mAnim.mRotationType != ASE::Animation::TRACK)	{
  16.299 +			DefaultLogger::get()->warn("ASE: Rotation controller uses Bezier/TCB keys. "
  16.300 +				"This is not supported.");
  16.301 +		}
  16.302 +		if ((*i)->mAnim.mScalingType != ASE::Animation::TRACK)	{
  16.303 +			DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. "
  16.304 +				"This is not supported.");
  16.305 +		}
  16.306 +
  16.307 +		// We compare against 1 here - firstly one key is not
  16.308 +		// really an animation and secondly MAX writes dummies
  16.309 +		// that represent the node transformation.
  16.310 +		if ((*i)->mAnim.akeyPositions.size()>1 || (*i)->mAnim.akeyRotations.size()>1 || (*i)->mAnim.akeyScaling.size()>1){
  16.311 +			++iNum;
  16.312 +		}
  16.313 +		if ((*i)->mTargetAnim.akeyPositions.size() > 1 && is_not_qnan( (*i)->mTargetPosition.x )) {
  16.314 +			++iNum;
  16.315 +		}
  16.316 +	}
  16.317 +	if (iNum)	{
  16.318 +		// Generate a new animation channel and setup everything for it
  16.319 +		pcScene->mNumAnimations = 1;
  16.320 +		pcScene->mAnimations    = new aiAnimation*[1];
  16.321 +		aiAnimation* pcAnim     = pcScene->mAnimations[0] = new aiAnimation();
  16.322 +		pcAnim->mNumChannels    = iNum;
  16.323 +		pcAnim->mChannels       = new aiNodeAnim*[iNum];
  16.324 +		pcAnim->mTicksPerSecond = mParser->iFrameSpeed * mParser->iTicksPerFrame;
  16.325 +
  16.326 +		iNum = 0;
  16.327 +		
  16.328 +		// Now iterate through all meshes and collect all data we can find
  16.329 +		for (i =  nodes.begin();i != nodes.end();++i)	{
  16.330 +
  16.331 +			ASE::BaseNode* me = *i;
  16.332 +			if ( me->mTargetAnim.akeyPositions.size() > 1 && is_not_qnan( me->mTargetPosition.x ))	{
  16.333 +				// Generate an extra channel for the camera/light target.
  16.334 +				// BuildNodes() does also generate an extra node, named
  16.335 +				// <baseName>.Target.
  16.336 +				aiNodeAnim* nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
  16.337 +				nd->mNodeName.Set(me->mName + ".Target");
  16.338 +
  16.339 +				// If there is no input position channel we will need
  16.340 +				// to supply the default position from the node's
  16.341 +				// local transformation matrix.
  16.342 +				/*TargetAnimationHelper helper;
  16.343 +				if (me->mAnim.akeyPositions.empty())
  16.344 +				{
  16.345 +					aiMatrix4x4& mat = (*i)->mTransform;
  16.346 +					helper.SetFixedMainAnimationChannel(aiVector3D(
  16.347 +						mat.a4, mat.b4, mat.c4));
  16.348 +				}
  16.349 +				else helper.SetMainAnimationChannel (&me->mAnim.akeyPositions);
  16.350 +				helper.SetTargetAnimationChannel (&me->mTargetAnim.akeyPositions);
  16.351 +				
  16.352 +				helper.Process(&me->mTargetAnim.akeyPositions);*/
  16.353 +
  16.354 +				// Allocate the key array and fill it
  16.355 +				nd->mNumPositionKeys = (unsigned int) me->mTargetAnim.akeyPositions.size();
  16.356 +				nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
  16.357 +
  16.358 +				::memcpy(nd->mPositionKeys,&me->mTargetAnim.akeyPositions[0],
  16.359 +					nd->mNumPositionKeys * sizeof(aiVectorKey));
  16.360 +			}
  16.361 +
  16.362 +			if (me->mAnim.akeyPositions.size() > 1 || me->mAnim.akeyRotations.size() > 1 || me->mAnim.akeyScaling.size() > 1)	{
  16.363 +				// Begin a new node animation channel for this node
  16.364 +				aiNodeAnim* nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
  16.365 +				nd->mNodeName.Set(me->mName);
  16.366 +
  16.367 +				// copy position keys
  16.368 +				if (me->mAnim.akeyPositions.size() > 1 )
  16.369 +				{
  16.370 +					// Allocate the key array and fill it
  16.371 +					nd->mNumPositionKeys = (unsigned int) me->mAnim.akeyPositions.size();
  16.372 +					nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
  16.373 +
  16.374 +					::memcpy(nd->mPositionKeys,&me->mAnim.akeyPositions[0],
  16.375 +						nd->mNumPositionKeys * sizeof(aiVectorKey));
  16.376 +				}
  16.377 +				// copy rotation keys
  16.378 +				if (me->mAnim.akeyRotations.size() > 1 )	{
  16.379 +					// Allocate the key array and fill it
  16.380 +					nd->mNumRotationKeys = (unsigned int) me->mAnim.akeyRotations.size();
  16.381 +					nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
  16.382 +
  16.383 +					// --------------------------------------------------------------------
  16.384 +					// Rotation keys are offsets to the previous keys.
  16.385 +					// We have the quaternion representations of all 
  16.386 +					// of them, so we just need to concatenate all
  16.387 +					// (unit-length) quaternions to get the absolute
  16.388 +					// rotations.
  16.389 +					// Rotation keys are ABSOLUTE for older files
  16.390 +					// --------------------------------------------------------------------
  16.391 +
  16.392 +					aiQuaternion cur;
  16.393 +					for (unsigned int a = 0; a < nd->mNumRotationKeys;++a)	{
  16.394 +						aiQuatKey q = me->mAnim.akeyRotations[a];
  16.395 +
  16.396 +						if (mParser->iFileFormat > 110)	{
  16.397 +							cur = (a ? cur*q.mValue : q.mValue);
  16.398 +							q.mValue = cur.Normalize();
  16.399 +						}
  16.400 +						nd->mRotationKeys[a] = q; 
  16.401 +
  16.402 +						// need this to get to Assimp quaternion conventions
  16.403 +						nd->mRotationKeys[a].mValue.w *= -1.f;
  16.404 +					}
  16.405 +				}
  16.406 +				// copy scaling keys
  16.407 +				if (me->mAnim.akeyScaling.size() > 1 )	{
  16.408 +					// Allocate the key array and fill it
  16.409 +					nd->mNumScalingKeys = (unsigned int) me->mAnim.akeyScaling.size();
  16.410 +					nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
  16.411 +
  16.412 +					::memcpy(nd->mScalingKeys,&me->mAnim.akeyScaling[0],
  16.413 +						nd->mNumScalingKeys * sizeof(aiVectorKey));
  16.414 +				}
  16.415 +			}
  16.416 +		}
  16.417 +	}
  16.418 +}
  16.419 +
  16.420 +// ------------------------------------------------------------------------------------------------
  16.421 +// Build output cameras
  16.422 +void ASEImporter::BuildCameras()
  16.423 +{
  16.424 +	if (!mParser->m_vCameras.empty())	{
  16.425 +		pcScene->mNumCameras = (unsigned int)mParser->m_vCameras.size();
  16.426 +		pcScene->mCameras = new aiCamera*[pcScene->mNumCameras];
  16.427 +
  16.428 +		for (unsigned int i = 0; i < pcScene->mNumCameras;++i)	{
  16.429 +			aiCamera* out = pcScene->mCameras[i] = new aiCamera();
  16.430 +			ASE::Camera& in = mParser->m_vCameras[i];
  16.431 +
  16.432 +			// copy members
  16.433 +			out->mClipPlaneFar  = in.mFar;
  16.434 +			out->mClipPlaneNear = (in.mNear ? in.mNear : 0.1f); 
  16.435 +			out->mHorizontalFOV = in.mFOV;
  16.436 +
  16.437 +			out->mName.Set(in.mName);
  16.438 +		}
  16.439 +	}
  16.440 +}
  16.441 +
  16.442 +// ------------------------------------------------------------------------------------------------
  16.443 +// Build output lights
  16.444 +void ASEImporter::BuildLights()
  16.445 +{
  16.446 +	if (!mParser->m_vLights.empty())	{
  16.447 +		pcScene->mNumLights = (unsigned int)mParser->m_vLights.size();
  16.448 +		pcScene->mLights    = new aiLight*[pcScene->mNumLights];
  16.449 +
  16.450 +		for (unsigned int i = 0; i < pcScene->mNumLights;++i)	{
  16.451 +			aiLight* out = pcScene->mLights[i] = new aiLight();
  16.452 +			ASE::Light& in = mParser->m_vLights[i];
  16.453 +
  16.454 +			// The direction is encoded in the transformation matrix of the node. 
  16.455 +			// In 3DS MAX the light source points into negative Z direction if 
  16.456 +			// the node transformation is the identity. 
  16.457 +			out->mDirection = aiVector3D(0.f,0.f,-1.f);
  16.458 +
  16.459 +			out->mName.Set(in.mName);
  16.460 +			switch (in.mLightType)
  16.461 +			{
  16.462 +			case ASE::Light::TARGET:
  16.463 +				out->mType = aiLightSource_SPOT;
  16.464 +				out->mAngleInnerCone = AI_DEG_TO_RAD(in.mAngle);
  16.465 +				out->mAngleOuterCone = (in.mFalloff ? AI_DEG_TO_RAD(in.mFalloff) : out->mAngleInnerCone);
  16.466 +				break;
  16.467 +
  16.468 +			case ASE::Light::DIRECTIONAL:
  16.469 +				out->mType = aiLightSource_DIRECTIONAL;
  16.470 +				break;
  16.471 +
  16.472 +			default:
  16.473 +			//case ASE::Light::OMNI:
  16.474 +				out->mType = aiLightSource_POINT;
  16.475 +				break;
  16.476 +			};
  16.477 +			out->mColorDiffuse = out->mColorSpecular = in.mColor * in.mIntensity;
  16.478 +		}
  16.479 +	}
  16.480 +}
  16.481 +
  16.482 +// ------------------------------------------------------------------------------------------------
  16.483 +void ASEImporter::AddNodes(const std::vector<BaseNode*>& nodes,
  16.484 +	aiNode* pcParent,const char* szName)
  16.485 +{
  16.486 +	aiMatrix4x4 m;
  16.487 +	AddNodes(nodes,pcParent,szName,m);
  16.488 +}
  16.489 +
  16.490 +// ------------------------------------------------------------------------------------------------
  16.491 +// Add meshes to a given node
  16.492 +void ASEImporter::AddMeshes(const ASE::BaseNode* snode,aiNode* node)
  16.493 +{
  16.494 +	for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)	{
  16.495 +		// Get the name of the mesh (the mesh instance has been temporarily stored in the third vertex color)
  16.496 +		const aiMesh* pcMesh  = pcScene->mMeshes[i];
  16.497 +		const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2];
  16.498 +
  16.499 +		if (mesh == snode) {
  16.500 +			++node->mNumMeshes;
  16.501 +		}
  16.502 +	}
  16.503 +
  16.504 +	if(node->mNumMeshes)	{
  16.505 +		node->mMeshes = new unsigned int[node->mNumMeshes];
  16.506 +		for (unsigned int i = 0, p = 0; i < pcScene->mNumMeshes;++i)	{
  16.507 +
  16.508 +			const aiMesh* pcMesh  = pcScene->mMeshes[i];
  16.509 +			const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2];
  16.510 +			if (mesh == snode)	{
  16.511 +				node->mMeshes[p++] = i;
  16.512 +
  16.513 +				// Transform all vertices of the mesh back into their local space -> 
  16.514 +				// at the moment they are pretransformed
  16.515 +				aiMatrix4x4 m  = mesh->mTransform;
  16.516 +				m.Inverse();
  16.517 +
  16.518 +				aiVector3D* pvCurPtr = pcMesh->mVertices;
  16.519 +				const aiVector3D* pvEndPtr = pvCurPtr + pcMesh->mNumVertices;
  16.520 +				while (pvCurPtr != pvEndPtr)	{
  16.521 +					*pvCurPtr = m * (*pvCurPtr);
  16.522 +					pvCurPtr++;
  16.523 +				}
  16.524 +
  16.525 +				// Do the same for the normal vectors, if we have them.
  16.526 +				// As always, inverse transpose.
  16.527 +				if (pcMesh->mNormals)	{
  16.528 +					aiMatrix3x3 m3 = aiMatrix3x3( mesh->mTransform );
  16.529 +					m3.Transpose();
  16.530 +
  16.531 +					pvCurPtr = pcMesh->mNormals;
  16.532 +					pvEndPtr = pvCurPtr + pcMesh->mNumVertices;
  16.533 +					while (pvCurPtr != pvEndPtr)	{
  16.534 +						*pvCurPtr = m3 * (*pvCurPtr);
  16.535 +						pvCurPtr++;
  16.536 +					}
  16.537 +				}
  16.538 +			}
  16.539 +		}
  16.540 +	}
  16.541 +}
  16.542 +
  16.543 +// ------------------------------------------------------------------------------------------------
  16.544 +// Add child nodes to a given parent node
  16.545 +void ASEImporter::AddNodes (const std::vector<BaseNode*>& nodes,
  16.546 +	aiNode* pcParent, const char* szName,
  16.547 +	const aiMatrix4x4& mat)
  16.548 +{
  16.549 +	const size_t len = szName ? ::strlen(szName) : 0;
  16.550 +	ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
  16.551 +
  16.552 +	// Receives child nodes for the pcParent node
  16.553 +	std::vector<aiNode*> apcNodes;
  16.554 +
  16.555 +	// Now iterate through all nodes in the scene and search for one
  16.556 +	// which has *us* as parent.
  16.557 +	for (std::vector<BaseNode*>::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) {
  16.558 +		const BaseNode* snode = *it;
  16.559 +		if (szName)	{
  16.560 +			if (len != snode->mParent.length() || ::strcmp(szName,snode->mParent.c_str()))
  16.561 +				continue;
  16.562 +		}
  16.563 +		else if (snode->mParent.length())
  16.564 +			continue;
  16.565 +
  16.566 +		(*it)->mProcessed = true;
  16.567 +
  16.568 +		// Allocate a new node and add it to the output data structure
  16.569 +		apcNodes.push_back(new aiNode());
  16.570 +		aiNode* node = apcNodes.back();
  16.571 +
  16.572 +		node->mName.Set((snode->mName.length() ? snode->mName.c_str() : "Unnamed_Node"));
  16.573 +		node->mParent = pcParent;
  16.574 +
  16.575 +		// Setup the transformation matrix of the node
  16.576 +		aiMatrix4x4 mParentAdjust  = mat;
  16.577 +		mParentAdjust.Inverse();
  16.578 +		node->mTransformation = mParentAdjust*snode->mTransform;
  16.579 +
  16.580 +		// Add sub nodes - prevent stack overflow due to recursive parenting
  16.581 +		if (node->mName != node->mParent->mName) {
  16.582 +			AddNodes(nodes,node,node->mName.data,snode->mTransform);
  16.583 +		}
  16.584 +
  16.585 +		// Further processing depends on the type of the node
  16.586 +		if (snode->mType == ASE::BaseNode::Mesh)	{
  16.587 +			// If the type of this node is "Mesh" we need to search
  16.588 +			// the list of output meshes in the data structure for
  16.589 +			// all those that belonged to this node once. This is
  16.590 +			// slightly inconvinient here and a better solution should
  16.591 +			// be used when this code is refactored next.
  16.592 +			AddMeshes(snode,node);
  16.593 +		}
  16.594 +		else if (is_not_qnan( snode->mTargetPosition.x ))	{
  16.595 +			// If this is a target camera or light we generate a small
  16.596 +			// child node which marks the position of the camera
  16.597 +			// target (the direction information is contained in *this*
  16.598 +			// node's animation track but the exact target position
  16.599 +			// would be lost otherwise)
  16.600 +			if (!node->mNumChildren)	{
  16.601 +				node->mChildren = new aiNode*[1];
  16.602 +			}
  16.603 +
  16.604 +			aiNode* nd = new aiNode();
  16.605 +
  16.606 +			nd->mName.Set ( snode->mName + ".Target" );
  16.607 +
  16.608 +			nd->mTransformation.a4 = snode->mTargetPosition.x - snode->mTransform.a4;
  16.609 +			nd->mTransformation.b4 = snode->mTargetPosition.y - snode->mTransform.b4;
  16.610 +			nd->mTransformation.c4 = snode->mTargetPosition.z - snode->mTransform.c4;
  16.611 +
  16.612 +			nd->mParent = node;
  16.613 +
  16.614 +			// The .Target node is always the first child node 
  16.615 +			for (unsigned int m = 0; m < node->mNumChildren;++m)
  16.616 +				node->mChildren[m+1] = node->mChildren[m]; 
  16.617 +		
  16.618 +			node->mChildren[0] = nd;
  16.619 +			node->mNumChildren++;
  16.620 +
  16.621 +			// What we did is so great, it is at least worth a debug message
  16.622 +			DefaultLogger::get()->debug("ASE: Generating separate target node ("+snode->mName+")");
  16.623 +		}
  16.624 +	}
  16.625 +
  16.626 +	// Allocate enough space for the child nodes
  16.627 +	// We allocate one slot more  in case this is a target camera/light
  16.628 +	pcParent->mNumChildren = (unsigned int)apcNodes.size();
  16.629 +	if (pcParent->mNumChildren)	{
  16.630 +		pcParent->mChildren = new aiNode*[apcNodes.size()+1 /* PLUS ONE !!! */];
  16.631 +
  16.632 +		// now build all nodes for our nice new children
  16.633 +		for (unsigned int p = 0; p < apcNodes.size();++p)
  16.634 +			pcParent->mChildren[p] = apcNodes[p];
  16.635 +	}
  16.636 +	return;
  16.637 +}
  16.638 +
  16.639 +// ------------------------------------------------------------------------------------------------
  16.640 +// Build the output node graph
  16.641 +void ASEImporter::BuildNodes(std::vector<BaseNode*>& nodes)	{
  16.642 +	ai_assert(NULL != pcScene);
  16.643 +
  16.644 +	// allocate the one and only root node
  16.645 +	aiNode* root = pcScene->mRootNode = new aiNode();
  16.646 +	root->mName.Set("<ASERoot>");
  16.647 +
  16.648 +	// Setup the coordinate system transformation
  16.649 +	pcScene->mRootNode->mNumChildren = 1;
  16.650 +	pcScene->mRootNode->mChildren = new aiNode*[1];
  16.651 +	aiNode* ch = pcScene->mRootNode->mChildren[0] = new aiNode();
  16.652 +	ch->mParent = root;
  16.653 +
  16.654 +	// Change the transformation matrix of all nodes
  16.655 +	for (std::vector<BaseNode*>::iterator it = nodes.begin(), end = nodes.end();it != end; ++it)	{
  16.656 +		aiMatrix4x4& m = (*it)->mTransform;
  16.657 +		m.Transpose(); // row-order vs column-order
  16.658 +	}
  16.659 +
  16.660 +	// add all nodes
  16.661 +	AddNodes(nodes,ch,NULL);
  16.662 +
  16.663 +	// now iterate through al nodes and find those that have not yet
  16.664 +	// been added to the nodegraph (= their parent could not be recognized)
  16.665 +	std::vector<const BaseNode*> aiList;
  16.666 +	for (std::vector<BaseNode*>::iterator it = nodes.begin(), end = nodes.end();it != end; ++it)	{
  16.667 +		if ((*it)->mProcessed) {
  16.668 +			continue;
  16.669 +		}
  16.670 +
  16.671 +		// check whether our parent is known
  16.672 +		bool bKnowParent = false;
  16.673 +		
  16.674 +		// search the list another time, starting *here* and try to find out whether
  16.675 +		// there is a node that references *us* as a parent
  16.676 +		for (std::vector<BaseNode*>::const_iterator it2 = nodes.begin();it2 != end; ++it2) {
  16.677 +			if (it2 == it) {
  16.678 +				continue;
  16.679 +			}
  16.680 +
  16.681 +			if ((*it2)->mName == (*it)->mParent)	{
  16.682 +				bKnowParent = true;
  16.683 +				break;
  16.684 +			}
  16.685 +		}
  16.686 +		if (!bKnowParent)	{
  16.687 +			aiList.push_back(*it);
  16.688 +		}
  16.689 +	}
  16.690 +
  16.691 +	// Are there ane orphaned nodes?
  16.692 +	if (!aiList.empty())	{
  16.693 +		std::vector<aiNode*> apcNodes;
  16.694 +		apcNodes.reserve(aiList.size() + pcScene->mRootNode->mNumChildren);
  16.695 +
  16.696 +		for (unsigned int i = 0; i < pcScene->mRootNode->mNumChildren;++i)
  16.697 +			apcNodes.push_back(pcScene->mRootNode->mChildren[i]);
  16.698 +
  16.699 +		delete[] pcScene->mRootNode->mChildren;
  16.700 +		for (std::vector<const BaseNode*>::/*const_*/iterator i =  aiList.begin();i != aiList.end();++i)	{
  16.701 +			const ASE::BaseNode* src = *i;
  16.702 +
  16.703 +			// The parent is not known, so we can assume that we must add 
  16.704 +			// this node to the root node of the whole scene
  16.705 +			aiNode* pcNode = new aiNode();
  16.706 +			pcNode->mParent = pcScene->mRootNode;
  16.707 +			pcNode->mName.Set(src->mName);
  16.708 +			AddMeshes(src,pcNode);
  16.709 +			AddNodes(nodes,pcNode,pcNode->mName.data);
  16.710 +			apcNodes.push_back(pcNode);
  16.711 +		}
  16.712 +
  16.713 +		// Regenerate our output array
  16.714 +		pcScene->mRootNode->mChildren = new aiNode*[apcNodes.size()];
  16.715 +		for (unsigned int i = 0; i < apcNodes.size();++i)
  16.716 +			pcScene->mRootNode->mChildren[i] = apcNodes[i];
  16.717 +
  16.718 +		pcScene->mRootNode->mNumChildren = (unsigned int)apcNodes.size();
  16.719 +	}
  16.720 +
  16.721 +	// Reset the third color set to NULL - we used this field to store a temporary pointer
  16.722 +	for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
  16.723 +		pcScene->mMeshes[i]->mColors[2] = NULL;
  16.724 +
  16.725 +	// The root node should not have at least one child or the file is valid
  16.726 +	if (!pcScene->mRootNode->mNumChildren) {
  16.727 +		throw DeadlyImportError("ASE: No nodes loaded. The file is either empty or corrupt");
  16.728 +	}
  16.729 +	
  16.730 +	// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
  16.731 +	pcScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
  16.732 +		0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
  16.733 +}
  16.734 +
  16.735 +// ------------------------------------------------------------------------------------------------
  16.736 +// Convert the imported data to the internal verbose representation
  16.737 +void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)	{
  16.738 +	// allocate output storage
  16.739 +	std::vector<aiVector3D> mPositions;
  16.740 +	std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
  16.741 +	std::vector<aiColor4D>  mVertexColors;
  16.742 +	std::vector<aiVector3D> mNormals;
  16.743 +	std::vector<BoneVertex> mBoneVertices;
  16.744 +
  16.745 +	unsigned int iSize = (unsigned int)mesh.mFaces.size() * 3;
  16.746 +	mPositions.resize(iSize);
  16.747 +
  16.748 +	// optional texture coordinates
  16.749 +	for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)	{
  16.750 +		if (!mesh.amTexCoords[i].empty())	{
  16.751 +			amTexCoords[i].resize(iSize);
  16.752 +		}
  16.753 +	}
  16.754 +	// optional vertex colors
  16.755 +	if (!mesh.mVertexColors.empty())	{
  16.756 +		mVertexColors.resize(iSize);
  16.757 +	}
  16.758 +
  16.759 +	// optional vertex normals (vertex normals can simply be copied)
  16.760 +	if (!mesh.mNormals.empty())	{
  16.761 +		mNormals.resize(iSize);
  16.762 +	}
  16.763 +	// bone vertices. There is no need to change the bone list
  16.764 +	if (!mesh.mBoneVertices.empty())	{
  16.765 +		mBoneVertices.resize(iSize);
  16.766 +	}
  16.767 +
  16.768 +	// iterate through all faces in the mesh
  16.769 +	unsigned int iCurrent = 0, fi = 0;
  16.770 +	for (std::vector<ASE::Face>::iterator i =  mesh.mFaces.begin();i != mesh.mFaces.end();++i,++fi)	{
  16.771 +		for (unsigned int n = 0; n < 3;++n,++iCurrent)
  16.772 +		{
  16.773 +			mPositions[iCurrent] = mesh.mPositions[(*i).mIndices[n]];
  16.774 +
  16.775 +			// add texture coordinates
  16.776 +			for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)	{
  16.777 +				if (mesh.amTexCoords[c].empty())break;
  16.778 +				amTexCoords[c][iCurrent] = mesh.amTexCoords[c][(*i).amUVIndices[c][n]];
  16.779 +			}
  16.780 +			// add vertex colors
  16.781 +			if (!mesh.mVertexColors.empty())	{
  16.782 +				mVertexColors[iCurrent] = mesh.mVertexColors[(*i).mColorIndices[n]];
  16.783 +			}
  16.784 +			// add normal vectors
  16.785 +			if (!mesh.mNormals.empty())	{
  16.786 +				mNormals[iCurrent] = mesh.mNormals[fi*3+n];
  16.787 +				mNormals[iCurrent].Normalize();
  16.788 +			}
  16.789 +
  16.790 +			// handle bone vertices
  16.791 +			if ((*i).mIndices[n] < mesh.mBoneVertices.size())	{
  16.792 +				// (sometimes this will cause bone verts to be duplicated
  16.793 +				//  however, I' quite sure Schrompf' JoinVerticesStep
  16.794 +				//  will fix that again ...)
  16.795 +				mBoneVertices[iCurrent] =  mesh.mBoneVertices[(*i).mIndices[n]];
  16.796 +			}
  16.797 +			(*i).mIndices[n] = iCurrent;
  16.798 +		}
  16.799 +	}
  16.800 +
  16.801 +	// replace the old arrays
  16.802 +	mesh.mNormals = mNormals;
  16.803 +	mesh.mPositions = mPositions;
  16.804 +	mesh.mVertexColors = mVertexColors;
  16.805 +
  16.806 +	for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
  16.807 +		mesh.amTexCoords[c] = amTexCoords[c];
  16.808 +}
  16.809 +
  16.810 +// ------------------------------------------------------------------------------------------------
  16.811 +// Copy a texture from the ASE structs to the output material
  16.812 +void CopyASETexture(aiMaterial& mat, ASE::Texture& texture, aiTextureType type)
  16.813 +{
  16.814 +	// Setup the texture name
  16.815 +	aiString tex;
  16.816 +	tex.Set( texture.mMapName);
  16.817 +	mat.AddProperty( &tex, AI_MATKEY_TEXTURE(type,0));
  16.818 +
  16.819 +	// Setup the texture blend factor
  16.820 +	if (is_not_qnan(texture.mTextureBlend))
  16.821 +		mat.AddProperty<float>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
  16.822 +
  16.823 +	// Setup texture UV transformations
  16.824 +	mat.AddProperty<float>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
  16.825 +}
  16.826 +
  16.827 +// ------------------------------------------------------------------------------------------------
  16.828 +// Convert from ASE material to output material
  16.829 +void ASEImporter::ConvertMaterial(ASE::Material& mat)
  16.830 +{
  16.831 +	// LARGE TODO: Much code her is copied from 3DS ... join them maybe?
  16.832 +
  16.833 +	// Allocate the output material
  16.834 +	mat.pcInstance = new aiMaterial();
  16.835 +
  16.836 +	// At first add the base ambient color of the
  16.837 +	// scene to	the material
  16.838 +	mat.mAmbient.r += mParser->m_clrAmbient.r;
  16.839 +	mat.mAmbient.g += mParser->m_clrAmbient.g;
  16.840 +	mat.mAmbient.b += mParser->m_clrAmbient.b;
  16.841 +
  16.842 +	aiString name;
  16.843 +	name.Set( mat.mName);
  16.844 +	mat.pcInstance->AddProperty( &name, AI_MATKEY_NAME);
  16.845 +
  16.846 +	// material colors
  16.847 +	mat.pcInstance->AddProperty( &mat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
  16.848 +	mat.pcInstance->AddProperty( &mat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
  16.849 +	mat.pcInstance->AddProperty( &mat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
  16.850 +	mat.pcInstance->AddProperty( &mat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
  16.851 +
  16.852 +	// shininess
  16.853 +	if (0.0f != mat.mSpecularExponent && 0.0f != mat.mShininessStrength)
  16.854 +	{
  16.855 +		mat.pcInstance->AddProperty( &mat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
  16.856 +		mat.pcInstance->AddProperty( &mat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
  16.857 +	}
  16.858 +	// If there is no shininess, we can disable phong lighting
  16.859 +	else if (D3DS::Discreet3DS::Metal == mat.mShading ||
  16.860 +		D3DS::Discreet3DS::Phong == mat.mShading ||
  16.861 +		D3DS::Discreet3DS::Blinn == mat.mShading)
  16.862 +	{
  16.863 +		mat.mShading = D3DS::Discreet3DS::Gouraud;
  16.864 +	}
  16.865 +
  16.866 +	// opacity
  16.867 +	mat.pcInstance->AddProperty<float>( &mat.mTransparency,1,AI_MATKEY_OPACITY);
  16.868 +
  16.869 +	// Two sided rendering?
  16.870 +	if (mat.mTwoSided)
  16.871 +	{
  16.872 +		int i = 1;
  16.873 +		mat.pcInstance->AddProperty<int>(&i,1,AI_MATKEY_TWOSIDED);
  16.874 +	}
  16.875 +
  16.876 +	// shading mode
  16.877 +	aiShadingMode eShading = aiShadingMode_NoShading;
  16.878 +	switch (mat.mShading)
  16.879 +	{
  16.880 +		case D3DS::Discreet3DS::Flat:
  16.881 +			eShading = aiShadingMode_Flat; break;
  16.882 +		case D3DS::Discreet3DS::Phong :
  16.883 +			eShading = aiShadingMode_Phong; break;
  16.884 +		case D3DS::Discreet3DS::Blinn :
  16.885 +			eShading = aiShadingMode_Blinn; break;
  16.886 +
  16.887 +			// I don't know what "Wire" shading should be,
  16.888 +			// assume it is simple lambertian diffuse (L dot N) shading
  16.889 +		case D3DS::Discreet3DS::Wire:
  16.890 +			{
  16.891 +				// set the wireframe flag
  16.892 +				unsigned int iWire = 1;
  16.893 +				mat.pcInstance->AddProperty<int>( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME);
  16.894 +			}
  16.895 +		case D3DS::Discreet3DS::Gouraud:
  16.896 +			eShading = aiShadingMode_Gouraud; break;
  16.897 +		case D3DS::Discreet3DS::Metal :
  16.898 +			eShading = aiShadingMode_CookTorrance; break;
  16.899 +	}
  16.900 +	mat.pcInstance->AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
  16.901 +
  16.902 +	// DIFFUSE texture
  16.903 +	if( mat.sTexDiffuse.mMapName.length() > 0)
  16.904 +		CopyASETexture(*mat.pcInstance,mat.sTexDiffuse, aiTextureType_DIFFUSE);
  16.905 +
  16.906 +	// SPECULAR texture
  16.907 +	if( mat.sTexSpecular.mMapName.length() > 0)
  16.908 +		CopyASETexture(*mat.pcInstance,mat.sTexSpecular, aiTextureType_SPECULAR);
  16.909 +
  16.910 +	// AMBIENT texture
  16.911 +	if( mat.sTexAmbient.mMapName.length() > 0)
  16.912 +		CopyASETexture(*mat.pcInstance,mat.sTexAmbient, aiTextureType_AMBIENT);
  16.913 +
  16.914 +	// OPACITY texture
  16.915 +	if( mat.sTexOpacity.mMapName.length() > 0)
  16.916 +		CopyASETexture(*mat.pcInstance,mat.sTexOpacity, aiTextureType_OPACITY);
  16.917 +
  16.918 +	// EMISSIVE texture
  16.919 +	if( mat.sTexEmissive.mMapName.length() > 0)
  16.920 +		CopyASETexture(*mat.pcInstance,mat.sTexEmissive, aiTextureType_EMISSIVE);
  16.921 +
  16.922 +	// BUMP texture
  16.923 +	if( mat.sTexBump.mMapName.length() > 0)
  16.924 +		CopyASETexture(*mat.pcInstance,mat.sTexBump, aiTextureType_HEIGHT);
  16.925 +
  16.926 +	// SHININESS texture
  16.927 +	if( mat.sTexShininess.mMapName.length() > 0)
  16.928 +		CopyASETexture(*mat.pcInstance,mat.sTexShininess, aiTextureType_SHININESS);
  16.929 +
  16.930 +	// store the name of the material itself, too
  16.931 +	if( mat.mName.length() > 0)	{
  16.932 +		aiString tex;tex.Set( mat.mName);
  16.933 +		mat.pcInstance->AddProperty( &tex, AI_MATKEY_NAME);
  16.934 +	}
  16.935 +	return;
  16.936 +}
  16.937 +
  16.938 +// ------------------------------------------------------------------------------------------------
  16.939 +// Build output meshes
  16.940 +void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMeshes)
  16.941 +{
  16.942 +	// validate the material index of the mesh
  16.943 +	if (mesh.iMaterialIndex >= mParser->m_vMaterials.size())	{
  16.944 +		mesh.iMaterialIndex = (unsigned int)mParser->m_vMaterials.size()-1;
  16.945 +		DefaultLogger::get()->warn("Material index is out of range");
  16.946 +	}
  16.947 +
  16.948 +	// If the material the mesh is assigned to is consisting of submeshes, split it
  16.949 +	if (!mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials.empty())	{
  16.950 +		std::vector<ASE::Material> vSubMaterials = mParser->
  16.951 +			m_vMaterials[mesh.iMaterialIndex].avSubMaterials;
  16.952 +
  16.953 +		std::vector<unsigned int>* aiSplit = new std::vector<unsigned int>[vSubMaterials.size()];
  16.954 +
  16.955 +		// build a list of all faces per submaterial
  16.956 +		for (unsigned int i = 0; i < mesh.mFaces.size();++i)	{
  16.957 +			// check range
  16.958 +			if (mesh.mFaces[i].iMaterial >= vSubMaterials.size()) {
  16.959 +				DefaultLogger::get()->warn("Submaterial index is out of range");
  16.960 +
  16.961 +				// use the last material instead
  16.962 +				aiSplit[vSubMaterials.size()-1].push_back(i);
  16.963 +			}
  16.964 +			else aiSplit[mesh.mFaces[i].iMaterial].push_back(i);
  16.965 +		}
  16.966 +
  16.967 +		// now generate submeshes
  16.968 +		for (unsigned int p = 0; p < vSubMaterials.size();++p)	{
  16.969 +			if (!aiSplit[p].empty())	{
  16.970 +
  16.971 +				aiMesh* p_pcOut = new aiMesh();
  16.972 +				p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
  16.973 +
  16.974 +				// let the sub material index
  16.975 +				p_pcOut->mMaterialIndex = p;
  16.976 +
  16.977 +				// we will need this material
  16.978 +				mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials[p].bNeed = true;
  16.979 +
  16.980 +				// store the real index here ... color channel 3
  16.981 +				p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
  16.982 +
  16.983 +				// store a pointer to the mesh in color channel 2
  16.984 +				p_pcOut->mColors[2] = (aiColor4D*) &mesh;
  16.985 +				avOutMeshes.push_back(p_pcOut);
  16.986 +
  16.987 +				// convert vertices
  16.988 +				p_pcOut->mNumVertices = (unsigned int)aiSplit[p].size()*3;
  16.989 +				p_pcOut->mNumFaces = (unsigned int)aiSplit[p].size();
  16.990 +
  16.991 +				// receive output vertex weights
  16.992 +				std::vector<std::pair<unsigned int, float> > *avOutputBones = NULL;
  16.993 +				if (!mesh.mBones.empty())	{
  16.994 +					avOutputBones = new std::vector<std::pair<unsigned int, float> >[mesh.mBones.size()];
  16.995 +				}
  16.996 +				
  16.997 +				// allocate enough storage for faces
  16.998 +				p_pcOut->mFaces = new aiFace[p_pcOut->mNumFaces];
  16.999 +
 16.1000 +				unsigned int iBase = 0,iIndex;
 16.1001 +				if (p_pcOut->mNumVertices)	{
 16.1002 +					p_pcOut->mVertices = new aiVector3D[p_pcOut->mNumVertices];
 16.1003 +					p_pcOut->mNormals  = new aiVector3D[p_pcOut->mNumVertices];
 16.1004 +					for (unsigned int q = 0; q < aiSplit[p].size();++q)	{
 16.1005 +
 16.1006 +						iIndex = aiSplit[p][q];
 16.1007 +
 16.1008 +						p_pcOut->mFaces[q].mIndices = new unsigned int[3];
 16.1009 +						p_pcOut->mFaces[q].mNumIndices = 3;
 16.1010 +
 16.1011 +						for (unsigned int t = 0; t < 3;++t, ++iBase)	{
 16.1012 +							const uint32_t iIndex2 = mesh.mFaces[iIndex].mIndices[t];
 16.1013 +
 16.1014 +							p_pcOut->mVertices[iBase] = mesh.mPositions [iIndex2];
 16.1015 +							p_pcOut->mNormals [iBase] = mesh.mNormals   [iIndex2];
 16.1016 +
 16.1017 +							// convert bones, if existing
 16.1018 +							if (!mesh.mBones.empty()) {
 16.1019 +								// check whether there is a vertex weight for this vertex index
 16.1020 +								if (iIndex2 < mesh.mBoneVertices.size())	{
 16.1021 +
 16.1022 +									for (std::vector<std::pair<int,float> >::const_iterator
 16.1023 +										blubb =  mesh.mBoneVertices[iIndex2].mBoneWeights.begin();
 16.1024 +										blubb != mesh.mBoneVertices[iIndex2].mBoneWeights.end();++blubb)	{
 16.1025 +
 16.1026 +										// NOTE: illegal cases have already been filtered out
 16.1027 +										avOutputBones[(*blubb).first].push_back(std::pair<unsigned int, float>(
 16.1028 +											iBase,(*blubb).second));
 16.1029 +									}
 16.1030 +								}
 16.1031 +							}
 16.1032 +							p_pcOut->mFaces[q].mIndices[t] = iBase;
 16.1033 +						}
 16.1034 +					}
 16.1035 +				}
 16.1036 +				// convert texture coordinates (up to AI_MAX_NUMBER_OF_TEXTURECOORDS sets supported)
 16.1037 +				for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
 16.1038 +					if (!mesh.amTexCoords[c].empty())
 16.1039 +					{
 16.1040 +						p_pcOut->mTextureCoords[c] = new aiVector3D[p_pcOut->mNumVertices];
 16.1041 +						iBase = 0;
 16.1042 +						for (unsigned int q = 0; q < aiSplit[p].size();++q)	{
 16.1043 +							iIndex = aiSplit[p][q];
 16.1044 +							for (unsigned int t = 0; t < 3;++t)	{
 16.1045 +								p_pcOut->mTextureCoords[c][iBase++] = mesh.amTexCoords[c][mesh.mFaces[iIndex].mIndices[t]];
 16.1046 +							}
 16.1047 +						}
 16.1048 +						// Setup the number of valid vertex components
 16.1049 +						p_pcOut->mNumUVComponents[c] = mesh.mNumUVComponents[c];
 16.1050 +					}
 16.1051 +				}
 16.1052 +
 16.1053 +				// Convert vertex colors (only one set supported)
 16.1054 +				if (!mesh.mVertexColors.empty()){
 16.1055 +					p_pcOut->mColors[0] = new aiColor4D[p_pcOut->mNumVertices];
 16.1056 +					iBase = 0;
 16.1057 +					for (unsigned int q = 0; q < aiSplit[p].size();++q)	{
 16.1058 +						iIndex = aiSplit[p][q];
 16.1059 +						for (unsigned int t = 0; t < 3;++t)	{
 16.1060 +							p_pcOut->mColors[0][iBase++] = mesh.mVertexColors[mesh.mFaces[iIndex].mIndices[t]];
 16.1061 +						}
 16.1062 +					}
 16.1063 +				}
 16.1064 +				// Copy bones
 16.1065 +				if (!mesh.mBones.empty())	{
 16.1066 +					p_pcOut->mNumBones = 0;
 16.1067 +					for (unsigned int mrspock = 0; mrspock < mesh.mBones.size();++mrspock)
 16.1068 +						if (!avOutputBones[mrspock].empty())p_pcOut->mNumBones++;
 16.1069 +
 16.1070 +					p_pcOut->mBones = new aiBone* [ p_pcOut->mNumBones ];
 16.1071 +					aiBone** pcBone = p_pcOut->mBones;
 16.1072 +					for (unsigned int mrspock = 0; mrspock < mesh.mBones.size();++mrspock)
 16.1073 +					{
 16.1074 +						if (!avOutputBones[mrspock].empty())	{
 16.1075 +							// we will need this bone. add it to the output mesh and
 16.1076 +							// add all per-vertex weights
 16.1077 +							aiBone* pc = *pcBone = new aiBone();
 16.1078 +							pc->mName.Set(mesh.mBones[mrspock].mName);
 16.1079 +
 16.1080 +							pc->mNumWeights = (unsigned int)avOutputBones[mrspock].size();
 16.1081 +							pc->mWeights = new aiVertexWeight[pc->mNumWeights];
 16.1082 +
 16.1083 +							for (unsigned int captainkirk = 0; captainkirk < pc->mNumWeights;++captainkirk)
 16.1084 +							{
 16.1085 +								const std::pair<unsigned int,float>& ref = avOutputBones[mrspock][captainkirk];
 16.1086 +								pc->mWeights[captainkirk].mVertexId = ref.first;
 16.1087 +								pc->mWeights[captainkirk].mWeight = ref.second;
 16.1088 +							}
 16.1089 +							++pcBone;
 16.1090 +						}
 16.1091 +					}
 16.1092 +					// delete allocated storage
 16.1093 +					delete[] avOutputBones;
 16.1094 +				}
 16.1095 +			}
 16.1096 +		}
 16.1097 +		// delete storage
 16.1098 +		delete[] aiSplit;
 16.1099 +	}
 16.1100 +	else
 16.1101 +	{
 16.1102 +		// Otherwise we can simply copy the data to one output mesh
 16.1103 +		// This codepath needs less memory and uses fast memcpy()s
 16.1104 +		// to do the actual copying. So I think it is worth the 
 16.1105 +		// effort here.
 16.1106 +
 16.1107 +		aiMesh* p_pcOut = new aiMesh();
 16.1108 +		p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 16.1109 +
 16.1110 +		// set an empty sub material index
 16.1111 +		p_pcOut->mMaterialIndex = ASE::Face::DEFAULT_MATINDEX;
 16.1112 +		mParser->m_vMaterials[mesh.iMaterialIndex].bNeed = true;
 16.1113 +
 16.1114 +		// store the real index here ... in color channel 3
 16.1115 +		p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
 16.1116 +
 16.1117 +		// store a pointer to the mesh in color channel 2
 16.1118 +		p_pcOut->mColors[2] = (aiColor4D*) &mesh;
 16.1119 +		avOutMeshes.push_back(p_pcOut);
 16.1120 +
 16.1121 +		// If the mesh hasn't faces or vertices, there are two cases
 16.1122 +		// possible: 1. the model is invalid. 2. This is a dummy
 16.1123 +		// helper object which we are going to remove later ...
 16.1124 +		if (mesh.mFaces.empty() || mesh.mPositions.empty())	{
 16.1125 +			return;
 16.1126 +		}
 16.1127 +
 16.1128 +		// convert vertices
 16.1129 +		p_pcOut->mNumVertices = (unsigned int)mesh.mPositions.size();
 16.1130 +		p_pcOut->mNumFaces = (unsigned int)mesh.mFaces.size();
 16.1131 +
 16.1132 +		// allocate enough storage for faces
 16.1133 +		p_pcOut->mFaces = new aiFace[p_pcOut->mNumFaces];
 16.1134 +
 16.1135 +		// copy vertices
 16.1136 +		p_pcOut->mVertices = new aiVector3D[mesh.mPositions.size()];
 16.1137 +		memcpy(p_pcOut->mVertices,&mesh.mPositions[0],
 16.1138 +			mesh.mPositions.size() * sizeof(aiVector3D));
 16.1139 +
 16.1140 +		// copy normals
 16.1141 +		p_pcOut->mNormals = new aiVector3D[mesh.mNormals.size()];
 16.1142 +		memcpy(p_pcOut->mNormals,&mesh.mNormals[0],
 16.1143 +			mesh.mNormals.size() * sizeof(aiVector3D));
 16.1144 +
 16.1145 +		// copy texture coordinates
 16.1146 +		for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)	{
 16.1147 +			if (!mesh.amTexCoords[c].empty())	{
 16.1148 +				p_pcOut->mTextureCoords[c] = new aiVector3D[mesh.amTexCoords[c].size()];
 16.1149 +				memcpy(p_pcOut->mTextureCoords[c],&mesh.amTexCoords[c][0],
 16.1150 +					mesh.amTexCoords[c].size() * sizeof(aiVector3D));
 16.1151 +
 16.1152 +				// setup the number of valid vertex components
 16.1153 +				p_pcOut->mNumUVComponents[c] = mesh.mNumUVComponents[c];
 16.1154 +			}
 16.1155 +		}
 16.1156 +
 16.1157 +		// copy vertex colors
 16.1158 +		if (!mesh.mVertexColors.empty())	{
 16.1159 +			p_pcOut->mColors[0] = new aiColor4D[mesh.mVertexColors.size()];
 16.1160 +			memcpy(p_pcOut->mColors[0],&mesh.mVertexColors[0],
 16.1161 +				mesh.mVertexColors.size() * sizeof(aiColor4D));
 16.1162 +		}
 16.1163 +
 16.1164 +		// copy faces
 16.1165 +		for (unsigned int iFace = 0; iFace < p_pcOut->mNumFaces;++iFace)	{
 16.1166 +			p_pcOut->mFaces[iFace].mNumIndices = 3;
 16.1167 +			p_pcOut->mFaces[iFace].mIndices = new unsigned int[3];
 16.1168 +
 16.1169 +			// copy indices 
 16.1170 +			p_pcOut->mFaces[iFace].mIndices[0] = mesh.mFaces[iFace].mIndices[0];
 16.1171 +			p_pcOut->mFaces[iFace].mIndices[1] = mesh.mFaces[iFace].mIndices[1];
 16.1172 +			p_pcOut->mFaces[iFace].mIndices[2] = mesh.mFaces[iFace].mIndices[2];
 16.1173 +		}
 16.1174 +
 16.1175 +		// copy vertex bones
 16.1176 +		if (!mesh.mBones.empty() && !mesh.mBoneVertices.empty())	{
 16.1177 +			std::vector<std::vector<aiVertexWeight> > avBonesOut( mesh.mBones.size() );
 16.1178 +
 16.1179 +			// find all vertex weights for this bone
 16.1180 +			unsigned int quak = 0;
 16.1181 +			for (std::vector<BoneVertex>::const_iterator harrypotter =  mesh.mBoneVertices.begin();
 16.1182 +				harrypotter != mesh.mBoneVertices.end();++harrypotter,++quak)	{
 16.1183 +
 16.1184 +				for (std::vector<std::pair<int,float> >::const_iterator
 16.1185 +					ronaldweasley  = (*harrypotter).mBoneWeights.begin();
 16.1186 +					ronaldweasley != (*harrypotter).mBoneWeights.end();++ronaldweasley)
 16.1187 +				{
 16.1188 +					aiVertexWeight weight;
 16.1189 +					weight.mVertexId = quak;
 16.1190 +					weight.mWeight = (*ronaldweasley).second;
 16.1191 +					avBonesOut[(*ronaldweasley).first].push_back(weight);
 16.1192 +				}
 16.1193 +			}
 16.1194 +
 16.1195 +			// now build a final bone list
 16.1196 +			p_pcOut->mNumBones = 0;
 16.1197 +			for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size();++jfkennedy)
 16.1198 +				if (!avBonesOut[jfkennedy].empty())p_pcOut->mNumBones++;
 16.1199 +
 16.1200 +			p_pcOut->mBones = new aiBone*[p_pcOut->mNumBones];
 16.1201 +			aiBone** pcBone = p_pcOut->mBones;
 16.1202 +			for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size();++jfkennedy)	{
 16.1203 +				if (!avBonesOut[jfkennedy].empty())	{
 16.1204 +					aiBone* pc = *pcBone = new aiBone();
 16.1205 +					pc->mName.Set(mesh.mBones[jfkennedy].mName);
 16.1206 +					pc->mNumWeights = (unsigned int)avBonesOut[jfkennedy].size();
 16.1207 +					pc->mWeights = new aiVertexWeight[pc->mNumWeights];
 16.1208 +					::memcpy(pc->mWeights,&avBonesOut[jfkennedy][0],
 16.1209 +						sizeof(aiVertexWeight) * pc->mNumWeights);
 16.1210 +					++pcBone;
 16.1211 +				}
 16.1212 +			}
 16.1213 +		}
 16.1214 +	}
 16.1215 +}
 16.1216 +
 16.1217 +// ------------------------------------------------------------------------------------------------
 16.1218 +// Setup proper material indices and build output materials
 16.1219 +void ASEImporter::BuildMaterialIndices()
 16.1220 +{
 16.1221 +	ai_assert(NULL != pcScene);
 16.1222 +
 16.1223 +	// iterate through all materials and check whether we need them
 16.1224 +	for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat)
 16.1225 +	{
 16.1226 +		ASE::Material& mat = mParser->m_vMaterials[iMat];
 16.1227 +		if (mat.bNeed)	{
 16.1228 +			// Convert it to the aiMaterial layout
 16.1229 +			ConvertMaterial(mat);
 16.1230 +			++pcScene->mNumMaterials;
 16.1231 +		}
 16.1232 +		for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size();++iSubMat)
 16.1233 +		{
 16.1234 +			ASE::Material& submat = mat.avSubMaterials[iSubMat];
 16.1235 +			if (submat.bNeed)	{
 16.1236 +				// Convert it to the aiMaterial layout
 16.1237 +				ConvertMaterial(submat);
 16.1238 +				++pcScene->mNumMaterials;
 16.1239 +			}
 16.1240 +		}
 16.1241 +	}
 16.1242 +
 16.1243 +	// allocate the output material array
 16.1244 +	pcScene->mMaterials = new aiMaterial*[pcScene->mNumMaterials];
 16.1245 +	D3DS::Material** pcIntMaterials = new D3DS::Material*[pcScene->mNumMaterials];
 16.1246 +
 16.1247 +	unsigned int iNum = 0;
 16.1248 +	for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat) {
 16.1249 +		ASE::Material& mat = mParser->m_vMaterials[iMat];
 16.1250 +		if (mat.bNeed)
 16.1251 +		{
 16.1252 +			ai_assert(NULL != mat.pcInstance);
 16.1253 +			pcScene->mMaterials[iNum] = mat.pcInstance;
 16.1254 +
 16.1255 +			// Store the internal material, too
 16.1256 +			pcIntMaterials[iNum] = &mat;
 16.1257 +
 16.1258 +			// Iterate through all meshes and search for one which is using
 16.1259 +			// this top-level material index
 16.1260 +			for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes;++iMesh)
 16.1261 +			{
 16.1262 +				aiMesh* mesh = pcScene->mMeshes[iMesh];
 16.1263 +				if (ASE::Face::DEFAULT_MATINDEX == mesh->mMaterialIndex &&
 16.1264 +					iMat == (uintptr_t)mesh->mColors[3])
 16.1265 +				{
 16.1266 +					mesh->mMaterialIndex = iNum;
 16.1267 +					mesh->mColors[3] = NULL;
 16.1268 +				}
 16.1269 +			}
 16.1270 +			iNum++;
 16.1271 +		}
 16.1272 +		for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size();++iSubMat)	{
 16.1273 +			ASE::Material& submat = mat.avSubMaterials[iSubMat];
 16.1274 +			if (submat.bNeed)	{
 16.1275 +				ai_assert(NULL != submat.pcInstance);
 16.1276 +				pcScene->mMaterials[iNum] = submat.pcInstance;
 16.1277 +
 16.1278 +				// Store the internal material, too
 16.1279 +				pcIntMaterials[iNum] = &submat;
 16.1280 +
 16.1281 +				// Iterate through all meshes and search for one which is using
 16.1282 +				// this sub-level material index
 16.1283 +				for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes;++iMesh)	{
 16.1284 +					aiMesh* mesh = pcScene->mMeshes[iMesh];
 16.1285 +
 16.1286 +					if (iSubMat == mesh->mMaterialIndex && iMat == (uintptr_t)mesh->mColors[3])	{
 16.1287 +						mesh->mMaterialIndex = iNum;
 16.1288 +						mesh->mColors[3]     = NULL;
 16.1289 +					}
 16.1290 +				}
 16.1291 +				iNum++;
 16.1292 +			}
 16.1293 +		}
 16.1294 +	}
 16.1295 +
 16.1296 +	// Dekete our temporary array
 16.1297 +	delete[] pcIntMaterials;
 16.1298 +}
 16.1299 +
 16.1300 +// ------------------------------------------------------------------------------------------------
 16.1301 +// Generate normal vectors basing on smoothing groups
 16.1302 +bool ASEImporter::GenerateNormals(ASE::Mesh& mesh)	{
 16.1303 +
 16.1304 +	if (!mesh.mNormals.empty() && !configRecomputeNormals)
 16.1305 +	{
 16.1306 +		// Check whether there are only uninitialized normals. If there are
 16.1307 +		// some, skip all normals from the file and compute them on our own
 16.1308 +		for (std::vector<aiVector3D>::const_iterator qq =  mesh.mNormals.begin();qq != mesh.mNormals.end();++qq) {
 16.1309 +			if ((*qq).x || (*qq).y || (*qq).z)
 16.1310 +			{
 16.1311 +				return true;
 16.1312 +			}
 16.1313 +		}
 16.1314 +	}
 16.1315 +	// The array is reused.
 16.1316 +	ComputeNormalsWithSmoothingsGroups<ASE::Face>(mesh);
 16.1317 +	return false;
 16.1318 +}
 16.1319 +
 16.1320 +#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/libs/assimp/ASELoader.h	Sat Feb 01 19:58:19 2014 +0200
    17.3 @@ -0,0 +1,205 @@
    17.4 +/*
    17.5 +Open Asset Import Library (assimp)
    17.6 +----------------------------------------------------------------------
    17.7 +
    17.8 +Copyright (c) 2006-2012, assimp team
    17.9 +All rights reserved.
   17.10 +
   17.11 +Redistribution and use of this software in source and binary forms, 
   17.12 +with or without modification, are permitted provided that the 
   17.13 +following conditions are met:
   17.14 +
   17.15 +* Redistributions of source code must retain the above
   17.16 +  copyright notice, this list of conditions and the
   17.17 +  following disclaimer.
   17.18 +
   17.19 +* Redistributions in binary form must reproduce the above
   17.20 +  copyright notice, this list of conditions and the
   17.21 +  following disclaimer in the documentation and/or other
   17.22 +  materials provided with the distribution.
   17.23 +
   17.24 +* Neither the name of the assimp team, nor the names of its
   17.25 +  contributors may be used to endorse or promote products
   17.26 +  derived from this software without specific prior
   17.27 +  written permission of the assimp team.
   17.28 +
   17.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   17.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   17.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   17.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   17.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   17.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   17.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   17.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   17.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   17.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   17.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   17.40 +
   17.41 +----------------------------------------------------------------------
   17.42 +*/
   17.43 +
   17.44 +/** @file  ASELoader.h
   17.45 + *  @brief Definition of the .ASE importer class.
   17.46 + */
   17.47 +#ifndef AI_ASELOADER_H_INCLUDED
   17.48 +#define AI_ASELOADER_H_INCLUDED
   17.49 +
   17.50 +#include "BaseImporter.h"
   17.51 +#include "assimp/types.h"
   17.52 +
   17.53 +struct aiNode;
   17.54 +#include "ASEParser.h"
   17.55 +
   17.56 +namespace Assimp {
   17.57 +
   17.58 +
   17.59 +// --------------------------------------------------------------------------------
   17.60 +/** Importer class for the 3DS ASE ASCII format.
   17.61 + *
   17.62 + */
   17.63 +class ASEImporter : public BaseImporter	{
   17.64 +public:
   17.65 +	ASEImporter();
   17.66 +	~ASEImporter();
   17.67 +
   17.68 +
   17.69 +public:
   17.70 +
   17.71 +	// -------------------------------------------------------------------
   17.72 +	/** Returns whether the class can handle the format of the given file. 
   17.73 +	 * See BaseImporter::CanRead() for details.	
   17.74 +	 */
   17.75 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
   17.76 +		bool checkSig) const;
   17.77 +
   17.78 +protected:
   17.79 +
   17.80 +	// -------------------------------------------------------------------
   17.81 +	/** Return importer meta information.
   17.82 +	 * See #BaseImporter::GetInfo for the details
   17.83 +	 */
   17.84 +	const aiImporterDesc* GetInfo () const;
   17.85 +
   17.86 +
   17.87 +	// -------------------------------------------------------------------
   17.88 +	/** Imports the given file into the given scene structure. 
   17.89 +	* See BaseImporter::InternReadFile() for details
   17.90 +	*/
   17.91 +	void InternReadFile( const std::string& pFile, aiScene* pScene,
   17.92 +		IOSystem* pIOHandler);
   17.93 +
   17.94 +
   17.95 +	// -------------------------------------------------------------------
   17.96 +	/** Called prior to ReadFile().
   17.97 +	* The function is a request to the importer to update its configuration
   17.98 +	* basing on the Importer's configuration property list.
   17.99 +	*/
  17.100 +	void SetupProperties(const Importer* pImp);
  17.101 +
  17.102 +
  17.103 +private:
  17.104 +
  17.105 +	// -------------------------------------------------------------------
  17.106 +	/** Generate normal vectors basing on smoothing groups
  17.107 +	 * (in some cases the normal are already contained in the file)
  17.108 +	 * \param mesh Mesh to work on
  17.109 +	 * \return false if the normals have been recomputed
  17.110 +	 */
  17.111 +	bool GenerateNormals(ASE::Mesh& mesh);
  17.112 +
  17.113 +
  17.114 +	// -------------------------------------------------------------------
  17.115 +	/** Create valid vertex/normal/UV/color/face lists.
  17.116 +	 *  All elements are unique, faces have only one set of indices
  17.117 +	 *  after this step occurs.
  17.118 +	 * \param mesh Mesh to work on
  17.119 +	 */
  17.120 +	void BuildUniqueRepresentation(ASE::Mesh& mesh);
  17.121 +
  17.122 +
  17.123 +	/** Create one-material-per-mesh meshes ;-)
  17.124 +	 * \param mesh Mesh to work with
  17.125 +	 *  \param Receives the list of all created meshes
  17.126 +	 */
  17.127 +	void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut);
  17.128 +
  17.129 +
  17.130 +	// -------------------------------------------------------------------
  17.131 +	/** Convert a material to a aiMaterial object
  17.132 +	 * \param mat Input material
  17.133 +	 */
  17.134 +	void ConvertMaterial(ASE::Material& mat);
  17.135 +
  17.136 +
  17.137 +	// -------------------------------------------------------------------
  17.138 +	/** Setup the final material indices for each mesh
  17.139 +	 */
  17.140 +	void BuildMaterialIndices();
  17.141 +
  17.142 +
  17.143 +	// -------------------------------------------------------------------
  17.144 +	/** Build the node graph
  17.145 +	 */
  17.146 +	void BuildNodes(std::vector<ASE::BaseNode*>& nodes);
  17.147 +
  17.148 +
  17.149 +	// -------------------------------------------------------------------
  17.150 +	/** Build output cameras
  17.151 +	 */
  17.152 +	void BuildCameras();
  17.153 +
  17.154 +
  17.155 +	// -------------------------------------------------------------------
  17.156 +	/** Build output lights
  17.157 +	 */
  17.158 +	void BuildLights();
  17.159 +
  17.160 +
  17.161 +	// -------------------------------------------------------------------
  17.162 +	/** Build output animations
  17.163 +	 */
  17.164 +	void BuildAnimations(const std::vector<ASE::BaseNode*>& nodes);
  17.165 +
  17.166 +
  17.167 +	// -------------------------------------------------------------------
  17.168 +	/** Add sub nodes to a node
  17.169 +	 *  \param pcParent parent node to be filled
  17.170 +	 *  \param szName Name of the parent node
  17.171 +	 *  \param matrix Current transform
  17.172 +	 */
  17.173 +	void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
  17.174 +		aiNode* pcParent,const char* szName);
  17.175 +
  17.176 +	void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
  17.177 +		aiNode* pcParent,const char* szName,
  17.178 +		const aiMatrix4x4& matrix);
  17.179 +
  17.180 +	void AddMeshes(const ASE::BaseNode* snode,aiNode* node);
  17.181 +
  17.182 +	// -------------------------------------------------------------------
  17.183 +	/** Generate a default material and add it to the parser's list
  17.184 +	 *  Called if no material has been found in the file (rare for ASE,
  17.185 +	 *  but not impossible)
  17.186 +	 */
  17.187 +	void GenerateDefaultMaterial();
  17.188 +
  17.189 +protected:
  17.190 +
  17.191 +	/** Parser instance */
  17.192 +	ASE::Parser* mParser;
  17.193 +
  17.194 +	/** Buffer to hold the loaded file */
  17.195 +	char* mBuffer;
  17.196 +
  17.197 +	/** Scene to be filled */
  17.198 +	aiScene* pcScene;
  17.199 +
  17.200 +	/** Config options: Recompute the normals in every case - WA
  17.201 +	    for 3DS Max broken ASE normal export */
  17.202 +	bool configRecomputeNormals;
  17.203 +	bool noSkeletonMesh;
  17.204 +};
  17.205 +
  17.206 +} // end of namespace Assimp
  17.207 +
  17.208 +#endif // AI_3DSIMPORTER_H_INC
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/libs/assimp/ASEParser.cpp	Sat Feb 01 19:58:19 2014 +0200
    18.3 @@ -0,0 +1,2153 @@
    18.4 +/*
    18.5 +---------------------------------------------------------------------------
    18.6 +Open Asset Import Library (assimp)
    18.7 +---------------------------------------------------------------------------
    18.8 +
    18.9 +Copyright (c) 2006-2012, assimp team
   18.10 +
   18.11 +All rights reserved.
   18.12 +
   18.13 +Redistribution and use of this software in source and binary forms, 
   18.14 +with or without modification, are permitted provided that the following 
   18.15 +conditions are met:
   18.16 +
   18.17 +* Redistributions of source code must retain the above
   18.18 +  copyright notice, this list of conditions and the
   18.19 +  following disclaimer.
   18.20 +
   18.21 +* Redistributions in binary form must reproduce the above
   18.22 +  copyright notice, this list of conditions and the
   18.23 +  following disclaimer in the documentation and/or other
   18.24 +  materials provided with the distribution.
   18.25 +
   18.26 +* Neither the name of the assimp team, nor the names of its
   18.27 +  contributors may be used to endorse or promote products
   18.28 +  derived from this software without specific prior
   18.29 +  written permission of the assimp team.
   18.30 +
   18.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   18.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   18.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   18.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   18.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   18.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   18.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   18.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   18.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   18.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   18.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   18.42 +---------------------------------------------------------------------------
   18.43 +*/
   18.44 +
   18.45 +/** @file  ASEParser.cpp
   18.46 + *  @brief Implementation of the ASE parser class 
   18.47 + */
   18.48 +
   18.49 +#include "AssimpPCH.h"
   18.50 +#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
   18.51 +
   18.52 +// internal headers
   18.53 +#include "TextureTransform.h"
   18.54 +#include "ASELoader.h"
   18.55 +#include "MaterialSystem.h"
   18.56 +#include "fast_atof.h"
   18.57 +
   18.58 +using namespace Assimp;
   18.59 +using namespace Assimp::ASE;
   18.60 +
   18.61 +
   18.62 +// ------------------------------------------------------------------------------------------------
   18.63 +// Begin an ASE parsing function
   18.64 +
   18.65 +#define AI_ASE_PARSER_INIT() \
   18.66 +	int iDepth = 0;
   18.67 +
   18.68 +// ------------------------------------------------------------------------------------------------
   18.69 +// Handle a "top-level" section in the file. EOF is no error in this case.
   18.70 +
   18.71 +#define AI_ASE_HANDLE_TOP_LEVEL_SECTION() \
   18.72 +	else if ('{' == *filePtr)iDepth++; \
   18.73 +	else if ('}' == *filePtr) \
   18.74 +	{ \
   18.75 +		if (0 == --iDepth) \
   18.76 +		{ \
   18.77 +			++filePtr; \
   18.78 +			SkipToNextToken(); \
   18.79 +			return; \
   18.80 +		} \
   18.81 +	} \
   18.82 +	else if ('\0' == *filePtr) \
   18.83 +	{ \
   18.84 +		return; \
   18.85 +	} \
   18.86 +	if(IsLineEnd(*filePtr) && !bLastWasEndLine) \
   18.87 +	{ \
   18.88 +		++iLineNumber; \
   18.89 +		bLastWasEndLine = true; \
   18.90 +	} else bLastWasEndLine = false; \
   18.91 +	++filePtr; 
   18.92 +
   18.93 +// ------------------------------------------------------------------------------------------------
   18.94 +// Handle a nested section in the file. EOF is an error in this case
   18.95 +// @param level "Depth" of the section
   18.96 +// @param msg Full name of the section (including the asterisk)
   18.97 +
   18.98 +#define AI_ASE_HANDLE_SECTION(level, msg) \
   18.99 +	if ('{' == *filePtr)iDepth++; \
  18.100 +	else if ('}' == *filePtr) \
  18.101 +	{ \
  18.102 +		if (0 == --iDepth) \
  18.103 +		{ \
  18.104 +			++filePtr; \
  18.105 +			SkipToNextToken(); \
  18.106 +			return; \
  18.107 +		} \
  18.108 +	} \
  18.109 +	else if ('\0' == *filePtr) \
  18.110 +	{ \
  18.111 +		LogError("Encountered unexpected EOL while parsing a " msg \
  18.112 +		" chunk (Level " level ")"); \
  18.113 +	} \
  18.114 +	if(IsLineEnd(*filePtr) && !bLastWasEndLine) \
  18.115 +		{ \
  18.116 +		++iLineNumber; \
  18.117 +		bLastWasEndLine = true; \
  18.118 +	} else bLastWasEndLine = false; \
  18.119 +	++filePtr; 
  18.120 +
  18.121 +// ------------------------------------------------------------------------------------------------
  18.122 +Parser::Parser (const char* szFile, unsigned int fileFormatDefault)
  18.123 +{
  18.124 +	ai_assert(NULL != szFile);
  18.125 +	filePtr = szFile;
  18.126 +	iFileFormat = fileFormatDefault;
  18.127 +
  18.128 +	// make sure that the color values are invalid
  18.129 +	m_clrBackground.r = get_qnan();
  18.130 +	m_clrAmbient.r    = get_qnan();
  18.131 +
  18.132 +	// setup some default values
  18.133 +	iLineNumber = 0;
  18.134 +	iFirstFrame = 0;
  18.135 +	iLastFrame = 0;
  18.136 +	iFrameSpeed = 30;        // use 30 as default value for this property
  18.137 +	iTicksPerFrame = 1;      // use 1 as default value for this property
  18.138 +	bLastWasEndLine = false; // need to handle \r\n seqs due to binary file mapping
  18.139 +}
  18.140 +
  18.141 +// ------------------------------------------------------------------------------------------------
  18.142 +void Parser::LogWarning(const char* szWarn)
  18.143 +{
  18.144 +	ai_assert(NULL != szWarn);
  18.145 +
  18.146 +	char szTemp[1024];
  18.147 +#if _MSC_VER >= 1400
  18.148 +	sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
  18.149 +#else
  18.150 +	snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
  18.151 +#endif
  18.152 +
  18.153 +	// output the warning to the logger ...
  18.154 +	DefaultLogger::get()->warn(szTemp);
  18.155 +}
  18.156 +
  18.157 +// ------------------------------------------------------------------------------------------------
  18.158 +void Parser::LogInfo(const char* szWarn)
  18.159 +{
  18.160 +	ai_assert(NULL != szWarn);
  18.161 +
  18.162 +	char szTemp[1024];
  18.163 +#if _MSC_VER >= 1400
  18.164 +	sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
  18.165 +#else
  18.166 +	snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
  18.167 +#endif
  18.168 +
  18.169 +	// output the information to the logger ...
  18.170 +	DefaultLogger::get()->info(szTemp);
  18.171 +}
  18.172 +
  18.173 +// ------------------------------------------------------------------------------------------------
  18.174 +void Parser::LogError(const char* szWarn)
  18.175 +{
  18.176 +	ai_assert(NULL != szWarn);
  18.177 +
  18.178 +	char szTemp[1024];
  18.179 +#if _MSC_VER >= 1400
  18.180 +	sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
  18.181 +#else
  18.182 +	snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
  18.183 +#endif
  18.184 +
  18.185 +	// throw an exception
  18.186 +	throw DeadlyImportError(szTemp);
  18.187 +}
  18.188 +
  18.189 +// ------------------------------------------------------------------------------------------------
  18.190 +bool Parser::SkipToNextToken()
  18.191 +{
  18.192 +	while (true)
  18.193 +	{
  18.194 +		char me = *filePtr;
  18.195 +
  18.196 +		// increase the line number counter if necessary
  18.197 +		if (IsLineEnd(me) && !bLastWasEndLine)
  18.198 +		{
  18.199 +			++iLineNumber;
  18.200 +			bLastWasEndLine = true;
  18.201 +		}
  18.202 +		else bLastWasEndLine = false;
  18.203 +		if ('*' == me || '}' == me || '{' == me)return true;
  18.204 +		if ('\0' == me)return false;
  18.205 +
  18.206 +		++filePtr;
  18.207 +	}
  18.208 +}
  18.209 +
  18.210 +// ------------------------------------------------------------------------------------------------
  18.211 +bool Parser::SkipSection()
  18.212 +{
  18.213 +	// must handle subsections ...
  18.214 +	int iCnt = 0;
  18.215 +	while (true)
  18.216 +	{
  18.217 +		if ('}' == *filePtr)
  18.218 +		{
  18.219 +			--iCnt;
  18.220 +			if (0 == iCnt)
  18.221 +			{
  18.222 +				// go to the next valid token ...
  18.223 +				++filePtr;
  18.224 +				SkipToNextToken();
  18.225 +				return true;
  18.226 +			}
  18.227 +		}
  18.228 +		else if ('{' == *filePtr)
  18.229 +		{
  18.230 +			++iCnt;
  18.231 +		}
  18.232 +		else if ('\0' == *filePtr)
  18.233 +		{
  18.234 +			LogWarning("Unable to parse block: Unexpected EOF, closing bracket \'}\' was expected [#1]");	
  18.235 +			return false;
  18.236 +		}
  18.237 +		else if(IsLineEnd(*filePtr))++iLineNumber;
  18.238 +		++filePtr;
  18.239 +	}
  18.240 +}
  18.241 +
  18.242 +// ------------------------------------------------------------------------------------------------
  18.243 +void Parser::Parse()
  18.244 +{
  18.245 +	AI_ASE_PARSER_INIT();
  18.246 +	while (true)
  18.247 +	{
  18.248 +		if ('*' == *filePtr)
  18.249 +		{
  18.250 +			++filePtr;
  18.251 +
  18.252 +			// Version should be 200. Validate this ...
  18.253 +			if (TokenMatch(filePtr,"3DSMAX_ASCIIEXPORT",18))
  18.254 +			{
  18.255 +				unsigned int fmt;
  18.256 +				ParseLV4MeshLong(fmt);
  18.257 +
  18.258 +				if (fmt > 200)
  18.259 +				{
  18.260 +					LogWarning("Unknown file format version: *3DSMAX_ASCIIEXPORT should \
  18.261 +							   be <= 200");
  18.262 +				}
  18.263 +				// *************************************************************
  18.264 +				// - fmt will be 0 if we're unable to read the version number
  18.265 +				// there are some faulty files without a version number ...
  18.266 +				// in this case we'll guess the exact file format by looking
  18.267 +				// at the file extension (ASE, ASK, ASC)
  18.268 +				// *************************************************************
  18.269 +
  18.270 +				if (fmt)iFileFormat = fmt;
  18.271 +				continue;
  18.272 +			}
  18.273 +			// main scene information
  18.274 +			if (TokenMatch(filePtr,"SCENE",5))
  18.275 +			{
  18.276 +				ParseLV1SceneBlock();
  18.277 +				continue;
  18.278 +			}
  18.279 +			// "group" - no implementation yet, in facte
  18.280 +			// we're just ignoring them for the moment
  18.281 +			if (TokenMatch(filePtr,"GROUP",5)) 
  18.282 +			{
  18.283 +				Parse();
  18.284 +				continue;
  18.285 +			}
  18.286 +			// material list
  18.287 +			if (TokenMatch(filePtr,"MATERIAL_LIST",13)) 
  18.288 +			{
  18.289 +				ParseLV1MaterialListBlock();
  18.290 +				continue;
  18.291 +			}
  18.292 +			// geometric object (mesh)
  18.293 +			if (TokenMatch(filePtr,"GEOMOBJECT",10)) 
  18.294 +				
  18.295 +			{
  18.296 +				m_vMeshes.push_back(Mesh());
  18.297 +				ParseLV1ObjectBlock(m_vMeshes.back());
  18.298 +				continue;
  18.299 +			}
  18.300 +			// helper object = dummy in the hierarchy
  18.301 +			if (TokenMatch(filePtr,"HELPEROBJECT",12)) 
  18.302 +				
  18.303 +			{
  18.304 +				m_vDummies.push_back(Dummy());
  18.305 +				ParseLV1ObjectBlock(m_vDummies.back());
  18.306 +				continue;
  18.307 +			}
  18.308 +			// light object
  18.309 +			if (TokenMatch(filePtr,"LIGHTOBJECT",11)) 
  18.310 +				
  18.311 +			{
  18.312 +				m_vLights.push_back(Light());
  18.313 +				ParseLV1ObjectBlock(m_vLights.back());
  18.314 +				continue;
  18.315 +			}
  18.316 +			// camera object
  18.317 +			if (TokenMatch(filePtr,"CAMERAOBJECT",12)) 
  18.318 +			{
  18.319 +				m_vCameras.push_back(Camera());
  18.320 +				ParseLV1ObjectBlock(m_vCameras.back());
  18.321 +				continue;
  18.322 +			}
  18.323 +			// comment - print it on the console
  18.324 +			if (TokenMatch(filePtr,"COMMENT",7)) 
  18.325 +			{
  18.326 +				std::string out = "<unknown>";
  18.327 +				ParseString(out,"*COMMENT");
  18.328 +				LogInfo(("Comment: " + out).c_str());
  18.329 +				continue;
  18.330 +			}
  18.331 +			// ASC bone weights
  18.332 +			if (AI_ASE_IS_OLD_FILE_FORMAT() && TokenMatch(filePtr,"MESH_SOFTSKINVERTS",18)) 
  18.333 +			{
  18.334 +				ParseLV1SoftSkinBlock();
  18.335 +			}
  18.336 +		}
  18.337 +		AI_ASE_HANDLE_TOP_LEVEL_SECTION();
  18.338 +	}
  18.339 +	return;
  18.340 +}
  18.341 +
  18.342 +// ------------------------------------------------------------------------------------------------
  18.343 +void Parser::ParseLV1SoftSkinBlock()
  18.344 +{
  18.345 +	// TODO: fix line counting here
  18.346 +
  18.347 +	// **************************************************************
  18.348 +	// The soft skin block is formatted differently. There are no
  18.349 +	// nested sections supported and the single elements aren't
  18.350 +	// marked by keywords starting with an asterisk.
  18.351 +
  18.352 +	/** 
  18.353 +	FORMAT BEGIN
  18.354 +
  18.355 +	*MESH_SOFTSKINVERTS {
  18.356 +	<nodename>
  18.357 +	<number of vertices>
  18.358 +
  18.359 +	[for <number of vertices> times:]
  18.360 +		<number of weights>	[for <number of weights> times:] <bone name> <weight>
  18.361 +	}
  18.362 +
  18.363 +	FORMAT END 
  18.364 +	*/
  18.365 +	// **************************************************************
  18.366 +	while (true)
  18.367 +	{
  18.368 +		if (*filePtr == '}'      )	{++filePtr;return;}
  18.369 +		else if (*filePtr == '\0')	return;
  18.370 +		else if (*filePtr == '{' )	++filePtr;
  18.371 +
  18.372 +		else // if (!IsSpace(*filePtr) && !IsLineEnd(*filePtr))
  18.373 +		{
  18.374 +			ASE::Mesh* curMesh		= NULL;
  18.375 +			unsigned int numVerts	= 0;
  18.376 +
  18.377 +			const char* sz = filePtr;
  18.378 +			while (!IsSpaceOrNewLine(*filePtr))++filePtr;
  18.379 +
  18.380 +			const unsigned int diff = (unsigned int)(filePtr-sz);
  18.381 +			if (diff)
  18.382 +			{
  18.383 +				std::string name = std::string(sz,diff);
  18.384 +				for (std::vector<ASE::Mesh>::iterator it = m_vMeshes.begin();
  18.385 +					it != m_vMeshes.end(); ++it)
  18.386 +				{
  18.387 +					if ((*it).mName == name)
  18.388 +					{
  18.389 +						curMesh = & (*it);
  18.390 +						break;
  18.391 +					}
  18.392 +				}
  18.393 +				if (!curMesh)
  18.394 +				{
  18.395 +					LogWarning("Encountered unknown mesh in *MESH_SOFTSKINVERTS section");
  18.396 +
  18.397 +					// Skip the mesh data - until we find a new mesh
  18.398 +					// or the end of the *MESH_SOFTSKINVERTS section
  18.399 +					while (true)
  18.400 +					{
  18.401 +						SkipSpacesAndLineEnd(&filePtr);
  18.402 +						if (*filePtr == '}')
  18.403 +							{++filePtr;return;}
  18.404 +						else if (!IsNumeric(*filePtr))
  18.405 +							break;
  18.406 +
  18.407 +						SkipLine(&filePtr);
  18.408 +					}
  18.409 +				}
  18.410 +				else
  18.411 +				{
  18.412 +					SkipSpacesAndLineEnd(&filePtr);
  18.413 +					ParseLV4MeshLong(numVerts);
  18.414 +
  18.415 +					// Reserve enough storage
  18.416 +					curMesh->mBoneVertices.reserve(numVerts);
  18.417 +
  18.418 +					for (unsigned int i = 0; i < numVerts;++i)
  18.419 +					{
  18.420 +						SkipSpacesAndLineEnd(&filePtr);
  18.421 +						unsigned int numWeights;
  18.422 +						ParseLV4MeshLong(numWeights);
  18.423 +
  18.424 +						curMesh->mBoneVertices.push_back(ASE::BoneVertex());
  18.425 +						ASE::BoneVertex& vert = curMesh->mBoneVertices.back();
  18.426 +
  18.427 +						// Reserve enough storage
  18.428 +						vert.mBoneWeights.reserve(numWeights);
  18.429 +
  18.430 +						for (unsigned int w = 0; w < numWeights;++w)
  18.431 +						{
  18.432 +							std::string bone;
  18.433 +							ParseString(bone,"*MESH_SOFTSKINVERTS.Bone");
  18.434 +
  18.435 +							// Find the bone in the mesh's list
  18.436 +							std::pair<int,float> me;
  18.437 +							me.first = -1;
  18.438 +							
  18.439 +							for (unsigned int n = 0; n < curMesh->mBones.size();++n)
  18.440 +							{
  18.441 +								if (curMesh->mBones[n].mName == bone)
  18.442 +								{
  18.443 +									me.first = n;
  18.444 +									break;
  18.445 +								}
  18.446 +							}
  18.447 +							if (-1 == me.first)
  18.448 +							{
  18.449 +								// We don't have this bone yet, so add it to the list
  18.450 +								me.first = (int)curMesh->mBones.size();
  18.451 +								curMesh->mBones.push_back(ASE::Bone(bone));
  18.452 +							}
  18.453 +							ParseLV4MeshFloat( me.second );
  18.454 +
  18.455 +							// Add the new bone weight to list
  18.456 +							vert.mBoneWeights.push_back(me);
  18.457 +						}
  18.458 +					}
  18.459 +				}
  18.460 +			}
  18.461 +		}
  18.462 +		++filePtr;
  18.463 +		SkipSpacesAndLineEnd(&filePtr);
  18.464 +	}
  18.465 +}
  18.466 +
  18.467 +// ------------------------------------------------------------------------------------------------
  18.468 +void Parser::ParseLV1SceneBlock()
  18.469 +{
  18.470 +	AI_ASE_PARSER_INIT();
  18.471 +	while (true)
  18.472 +	{
  18.473 +		if ('*' == *filePtr)
  18.474 +		{
  18.475 +			++filePtr;
  18.476 +			if (TokenMatch(filePtr,"SCENE_BACKGROUND_STATIC",23)) 
  18.477 +				
  18.478 +			{
  18.479 +				// parse a color triple and assume it is really the bg color
  18.480 +				ParseLV4MeshFloatTriple( &m_clrBackground.r );
  18.481 +				continue;
  18.482 +			}
  18.483 +			if (TokenMatch(filePtr,"SCENE_AMBIENT_STATIC",20)) 
  18.484 +				
  18.485 +			{
  18.486 +				// parse a color triple and assume it is really the bg color
  18.487 +				ParseLV4MeshFloatTriple( &m_clrAmbient.r );
  18.488 +				continue;
  18.489 +			}
  18.490 +			if (TokenMatch(filePtr,"SCENE_FIRSTFRAME",16)) 
  18.491 +			{
  18.492 +				ParseLV4MeshLong(iFirstFrame);
  18.493 +				continue;
  18.494 +			}
  18.495 +			if (TokenMatch(filePtr,"SCENE_LASTFRAME",15))
  18.496 +			{
  18.497 +				ParseLV4MeshLong(iLastFrame);
  18.498 +				continue;
  18.499 +			}
  18.500 +			if (TokenMatch(filePtr,"SCENE_FRAMESPEED",16)) 
  18.501 +			{
  18.502 +				ParseLV4MeshLong(iFrameSpeed);
  18.503 +				continue;
  18.504 +			}
  18.505 +			if (TokenMatch(filePtr,"SCENE_TICKSPERFRAME",19))
  18.506 +			{
  18.507 +				ParseLV4MeshLong(iTicksPerFrame);
  18.508 +				continue;
  18.509 +			}
  18.510 +		}
  18.511 +		AI_ASE_HANDLE_TOP_LEVEL_SECTION();
  18.512 +	}
  18.513 +}
  18.514 +
  18.515 +// ------------------------------------------------------------------------------------------------
  18.516 +void Parser::ParseLV1MaterialListBlock()
  18.517 +{
  18.518 +	AI_ASE_PARSER_INIT();
  18.519 +
  18.520 +	unsigned int iMaterialCount = 0;
  18.521 +	unsigned int iOldMaterialCount = (unsigned int)m_vMaterials.size();
  18.522 +	while (true)
  18.523 +	{
  18.524 +		if ('*' == *filePtr)
  18.525 +		{
  18.526 +			++filePtr;
  18.527 +			if (TokenMatch(filePtr,"MATERIAL_COUNT",14))
  18.528 +			{
  18.529 +				ParseLV4MeshLong(iMaterialCount);
  18.530 +
  18.531 +				// now allocate enough storage to hold all materials
  18.532 +				m_vMaterials.resize(iOldMaterialCount+iMaterialCount);
  18.533 +				continue;
  18.534 +			}
  18.535 +			if (TokenMatch(filePtr,"MATERIAL",8))
  18.536 +			{
  18.537 +				unsigned int iIndex = 0;
  18.538 +				ParseLV4MeshLong(iIndex);
  18.539 +
  18.540 +				if (iIndex >= iMaterialCount)
  18.541 +				{
  18.542 +					LogWarning("Out of range: material index is too large");
  18.543 +					iIndex = iMaterialCount-1;
  18.544 +				}
  18.545 +
  18.546 +				// get a reference to the material
  18.547 +				Material& sMat = m_vMaterials[iIndex+iOldMaterialCount];
  18.548 +				// parse the material block
  18.549 +				ParseLV2MaterialBlock(sMat);
  18.550 +				continue;
  18.551 +			}
  18.552 +		}
  18.553 +		AI_ASE_HANDLE_TOP_LEVEL_SECTION();
  18.554 +	}
  18.555 +}
  18.556 +
  18.557 +// ------------------------------------------------------------------------------------------------
  18.558 +void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
  18.559 +{
  18.560 +	AI_ASE_PARSER_INIT();
  18.561 +
  18.562 +	unsigned int iNumSubMaterials = 0;
  18.563 +	while (true)
  18.564 +	{
  18.565 +		if ('*' == *filePtr)
  18.566 +		{
  18.567 +			++filePtr;
  18.568 +			if (TokenMatch(filePtr,"MATERIAL_NAME",13))
  18.569 +			{
  18.570 +				if (!ParseString(mat.mName,"*MATERIAL_NAME"))
  18.571 +					SkipToNextToken();
  18.572 +				continue;
  18.573 +			}
  18.574 +			// ambient material color
  18.575 +			if (TokenMatch(filePtr,"MATERIAL_AMBIENT",16))
  18.576 +			{
  18.577 +				ParseLV4MeshFloatTriple(&mat.mAmbient.r);
  18.578 +				continue;
  18.579 +			}
  18.580 +			// diffuse material color
  18.581 +			if (TokenMatch(filePtr,"MATERIAL_DIFFUSE",16) )
  18.582 +			{
  18.583 +				ParseLV4MeshFloatTriple(&mat.mDiffuse.r);
  18.584 +				continue;
  18.585 +			}
  18.586 +			// specular material color
  18.587 +			if (TokenMatch(filePtr,"MATERIAL_SPECULAR",17))
  18.588 +			{
  18.589 +				ParseLV4MeshFloatTriple(&mat.mSpecular.r);
  18.590 +				continue;
  18.591 +			}
  18.592 +			// material shading type
  18.593 +			if (TokenMatch(filePtr,"MATERIAL_SHADING",16))
  18.594 +			{
  18.595 +				if (TokenMatch(filePtr,"Blinn",5))
  18.596 +				{
  18.597 +					mat.mShading = Discreet3DS::Blinn;
  18.598 +				}
  18.599 +				else if (TokenMatch(filePtr,"Phong",5))
  18.600 +				{
  18.601 +					mat.mShading = Discreet3DS::Phong;
  18.602 +				}
  18.603 +				else if (TokenMatch(filePtr,"Flat",4))
  18.604 +				{
  18.605 +					mat.mShading = Discreet3DS::Flat;
  18.606 +				}
  18.607 +				else if (TokenMatch(filePtr,"Wire",4))
  18.608 +				{
  18.609 +					mat.mShading = Discreet3DS::Wire;
  18.610 +				}
  18.611 +				else
  18.612 +				{
  18.613 +					// assume gouraud shading
  18.614 +					mat.mShading = Discreet3DS::Gouraud;
  18.615 +					SkipToNextToken();
  18.616 +				}
  18.617 +				continue;
  18.618 +			}
  18.619 +			// material transparency
  18.620 +			if (TokenMatch(filePtr,"MATERIAL_TRANSPARENCY",21))
  18.621 +			{
  18.622 +				ParseLV4MeshFloat(mat.mTransparency);
  18.623 +				mat.mTransparency = 1.0f - mat.mTransparency;continue;
  18.624 +			}
  18.625 +			// material self illumination
  18.626 +			if (TokenMatch(filePtr,"MATERIAL_SELFILLUM",18))
  18.627 +			{
  18.628 +				float f = 0.0f;
  18.629 +				ParseLV4MeshFloat(f);
  18.630 +
  18.631 +				mat.mEmissive.r = f;
  18.632 +				mat.mEmissive.g = f;
  18.633 +				mat.mEmissive.b = f;
  18.634 +				continue;
  18.635 +			}
  18.636 +			// material shininess
  18.637 +			if (TokenMatch(filePtr,"MATERIAL_SHINE",14) )
  18.638 +			{
  18.639 +				ParseLV4MeshFloat(mat.mSpecularExponent);
  18.640 +				mat.mSpecularExponent *= 15;
  18.641 +				continue;
  18.642 +			}
  18.643 +			// two-sided material
  18.644 +			if (TokenMatch(filePtr,"MATERIAL_TWOSIDED",17) )
  18.645 +			{
  18.646 +				mat.mTwoSided = true;
  18.647 +				continue;
  18.648 +			}
  18.649 +			// material shininess strength
  18.650 +			if (TokenMatch(filePtr,"MATERIAL_SHINESTRENGTH",22))
  18.651 +			{
  18.652 +				ParseLV4MeshFloat(mat.mShininessStrength);
  18.653 +				continue;
  18.654 +			}
  18.655 +			// diffuse color map
  18.656 +			if (TokenMatch(filePtr,"MAP_DIFFUSE",11))
  18.657 +			{
  18.658 +				// parse the texture block
  18.659 +				ParseLV3MapBlock(mat.sTexDiffuse);
  18.660 +				continue;
  18.661 +			}
  18.662 +			// ambient color map
  18.663 +			if (TokenMatch(filePtr,"MAP_AMBIENT",11))
  18.664 +			{
  18.665 +				// parse the texture block
  18.666 +				ParseLV3MapBlock(mat.sTexAmbient);
  18.667 +				continue;
  18.668 +			}
  18.669 +			// specular color map
  18.670 +			if (TokenMatch(filePtr,"MAP_SPECULAR",12))
  18.671 +			{
  18.672 +				// parse the texture block
  18.673 +				ParseLV3MapBlock(mat.sTexSpecular);
  18.674 +				continue;
  18.675 +			}
  18.676 +			// opacity map
  18.677 +			if (TokenMatch(filePtr,"MAP_OPACITY",11))
  18.678 +			{
  18.679 +				// parse the texture block
  18.680 +				ParseLV3MapBlock(mat.sTexOpacity);
  18.681 +				continue;
  18.682 +			}
  18.683 +			// emissive map
  18.684 +			if (TokenMatch(filePtr,"MAP_SELFILLUM",13))
  18.685 +			{
  18.686 +				// parse the texture block
  18.687 +				ParseLV3MapBlock(mat.sTexEmissive);
  18.688 +				continue;
  18.689 +			}
  18.690 +			// bump map
  18.691 +			if (TokenMatch(filePtr,"MAP_BUMP",8))
  18.692 +			{
  18.693 +				// parse the texture block
  18.694 +				ParseLV3MapBlock(mat.sTexBump);
  18.695 +			}
  18.696 +			// specular/shininess map
  18.697 +			if (TokenMatch(filePtr,"MAP_SHINESTRENGTH",17))
  18.698 +			{
  18.699 +				// parse the texture block
  18.700 +				ParseLV3MapBlock(mat.sTexShininess);
  18.701 +				continue;
  18.702 +			}
  18.703 +			// number of submaterials
  18.704 +			if (TokenMatch(filePtr,"NUMSUBMTLS",10))
  18.705 +			{
  18.706 +				ParseLV4MeshLong(iNumSubMaterials);
  18.707 +
  18.708 +				// allocate enough storage
  18.709 +				mat.avSubMaterials.resize(iNumSubMaterials);
  18.710 +			}
  18.711 +			// submaterial chunks
  18.712 +			if (TokenMatch(filePtr,"SUBMATERIAL",11))
  18.713 +			{
  18.714 +			
  18.715 +				unsigned int iIndex = 0;
  18.716 +				ParseLV4MeshLong(iIndex);
  18.717 +
  18.718 +				if (iIndex >= iNumSubMaterials)
  18.719 +				{
  18.720 +					LogWarning("Out of range: submaterial index is too large");
  18.721 +					iIndex = iNumSubMaterials-1;
  18.722 +				}
  18.723 +
  18.724 +				// get a reference to the material
  18.725 +				Material& sMat = mat.avSubMaterials[iIndex];
  18.726 +
  18.727 +				// parse the material block
  18.728 +				ParseLV2MaterialBlock(sMat);
  18.729 +				continue;
  18.730 +			}
  18.731 +		}
  18.732 +		AI_ASE_HANDLE_SECTION("2","*MATERIAL");
  18.733 +	}
  18.734 +}
  18.735 +
  18.736 +// ------------------------------------------------------------------------------------------------
  18.737 +void Parser::ParseLV3MapBlock(Texture& map)
  18.738 +{
  18.739 +	AI_ASE_PARSER_INIT();
  18.740 +
  18.741 +	// ***********************************************************
  18.742 +	// *BITMAP should not be there if *MAP_CLASS is not BITMAP,
  18.743 +	// but we need to expect that case ... if the path is
  18.744 +	// empty the texture won't be used later.
  18.745 +	// ***********************************************************
  18.746 +	bool parsePath = true; 
  18.747 +	while (true)
  18.748 +	{
  18.749 +		if ('*' == *filePtr)
  18.750 +		{
  18.751 +			++filePtr;
  18.752 +			// type of map
  18.753 +			if (TokenMatch(filePtr,"MAP_CLASS" ,9))
  18.754 +			{
  18.755 +				std::string temp;
  18.756 +				if(!ParseString(temp,"*MAP_CLASS"))
  18.757 +					SkipToNextToken();
  18.758 +				if (temp != "Bitmap" && temp != "Normal Bump")
  18.759 +				{
  18.760 +					DefaultLogger::get()->warn("ASE: Skipping unknown map type: " + temp);
  18.761 +					parsePath = false; 
  18.762 +				}
  18.763 +				continue;
  18.764 +			}
  18.765 +			// path to the texture
  18.766 +			if (parsePath && TokenMatch(filePtr,"BITMAP" ,6))
  18.767 +			{
  18.768 +				if(!ParseString(map.mMapName,"*BITMAP"))
  18.769 +					SkipToNextToken();
  18.770 +
  18.771 +				if (map.mMapName == "None")
  18.772 +				{
  18.773 +					// Files with 'None' as map name are produced by
  18.774 +					// an Maja to ASE exporter which name I forgot ..
  18.775 +					DefaultLogger::get()->warn("ASE: Skipping invalid map entry");
  18.776 +					map.mMapName = "";
  18.777 +				}
  18.778 +
  18.779 +				continue;
  18.780 +			}
  18.781 +			// offset on the u axis
  18.782 +			if (TokenMatch(filePtr,"UVW_U_OFFSET" ,12))
  18.783 +			{
  18.784 +				ParseLV4MeshFloat(map.mOffsetU);
  18.785 +				continue;
  18.786 +			}
  18.787 +			// offset on the v axis
  18.788 +			if (TokenMatch(filePtr,"UVW_V_OFFSET" ,12))
  18.789 +			{
  18.790 +				ParseLV4MeshFloat(map.mOffsetV);
  18.791 +				continue;
  18.792 +			}
  18.793 +			// tiling on the u axis
  18.794 +			if (TokenMatch(filePtr,"UVW_U_TILING" ,12))
  18.795 +			{
  18.796 +				ParseLV4MeshFloat(map.mScaleU);
  18.797 +				continue;
  18.798 +			}
  18.799 +			// tiling on the v axis
  18.800 +			if (TokenMatch(filePtr,"UVW_V_TILING" ,12))
  18.801 +			{
  18.802 +				ParseLV4MeshFloat(map.mScaleV);
  18.803 +				continue;
  18.804 +			}
  18.805 +			// rotation around the z-axis
  18.806 +			if (TokenMatch(filePtr,"UVW_ANGLE" ,9))
  18.807 +			{
  18.808 +				ParseLV4MeshFloat(map.mRotation);
  18.809 +				continue;
  18.810 +			}
  18.811 +			// map blending factor
  18.812 +			if (TokenMatch(filePtr,"MAP_AMOUNT" ,10))
  18.813 +			{
  18.814 +				ParseLV4MeshFloat(map.mTextureBlend);
  18.815 +				continue;
  18.816 +			}
  18.817 +		}
  18.818 +		AI_ASE_HANDLE_SECTION("3","*MAP_XXXXXX");
  18.819 +	}
  18.820 +	return;
  18.821 +}
  18.822 +
  18.823 +// ------------------------------------------------------------------------------------------------
  18.824 +bool Parser::ParseString(std::string& out,const char* szName)
  18.825 +{
  18.826 +	char szBuffer[1024];
  18.827 +	if (!SkipSpaces(&filePtr))
  18.828 +	{
  18.829 +
  18.830 +		sprintf(szBuffer,"Unable to parse %s block: Unexpected EOL",szName);
  18.831 +		LogWarning(szBuffer);
  18.832 +		return false;
  18.833 +	}
  18.834 +	// there must be '"'
  18.835 +	if ('\"' != *filePtr)
  18.836 +	{
  18.837 +
  18.838 +		sprintf(szBuffer,"Unable to parse %s block: Strings are expected "
  18.839 +			"to be enclosed in double quotation marks",szName);
  18.840 +		LogWarning(szBuffer);
  18.841 +		return false;
  18.842 +	}
  18.843 +	++filePtr;
  18.844 +	const char* sz = filePtr;
  18.845 +	while (true)
  18.846 +	{
  18.847 +		if ('\"' == *sz)break;
  18.848 +		else if ('\0' == *sz)
  18.849 +		{			
  18.850 +			sprintf(szBuffer,"Unable to parse %s block: Strings are expected to "
  18.851 +				"be enclosed in double quotation marks but EOF was reached before "
  18.852 +				"a closing quotation mark was encountered",szName);
  18.853 +			LogWarning(szBuffer);
  18.854 +			return false;
  18.855 +		}
  18.856 +		sz++;
  18.857 +	}
  18.858 +	out = std::string(filePtr,(uintptr_t)sz-(uintptr_t)filePtr);
  18.859 +	filePtr = sz+1;
  18.860 +	return true;
  18.861 +}
  18.862 +
  18.863 +// ------------------------------------------------------------------------------------------------
  18.864 +void Parser::ParseLV1ObjectBlock(ASE::BaseNode& node)
  18.865 +{
  18.866 +	AI_ASE_PARSER_INIT();
  18.867 +	while (true)
  18.868 +	{
  18.869 +		if ('*' == *filePtr)
  18.870 +		{
  18.871 +			++filePtr;
  18.872 +
  18.873 +			// first process common tokens such as node name and transform
  18.874 +			// name of the mesh/node
  18.875 +			if (TokenMatch(filePtr,"NODE_NAME" ,9))
  18.876 +			{
  18.877 +				if(!ParseString(node.mName,"*NODE_NAME"))
  18.878 +					SkipToNextToken();
  18.879 +				continue;
  18.880 +			}
  18.881 +			// name of the parent of the node
  18.882 +			if (TokenMatch(filePtr,"NODE_PARENT" ,11) )
  18.883 +			{
  18.884 +				if(!ParseString(node.mParent,"*NODE_PARENT"))
  18.885 +					SkipToNextToken();
  18.886 +				continue;
  18.887 +			}
  18.888 +			// transformation matrix of the node
  18.889 +			if (TokenMatch(filePtr,"NODE_TM" ,7))
  18.890 +			{
  18.891 +				ParseLV2NodeTransformBlock(node);
  18.892 +				continue;
  18.893 +			}
  18.894 +			// animation data of the node
  18.895 +			if (TokenMatch(filePtr,"TM_ANIMATION" ,12))
  18.896 +			{
  18.897 +				ParseLV2AnimationBlock(node);
  18.898 +				continue;
  18.899 +			}
  18.900 +
  18.901 +			if (node.mType == BaseNode::Light)
  18.902 +			{
  18.903 +				// light settings
  18.904 +				if (TokenMatch(filePtr,"LIGHT_SETTINGS" ,14))
  18.905 +				{
  18.906 +					ParseLV2LightSettingsBlock((ASE::Light&)node);
  18.907 +					continue;
  18.908 +				}
  18.909 +				// type of the light source
  18.910 +				if (TokenMatch(filePtr,"LIGHT_TYPE" ,10))
  18.911 +				{
  18.912 +					if (!ASSIMP_strincmp("omni",filePtr,4))
  18.913 +					{
  18.914 +						((ASE::Light&)node).mLightType = ASE::Light::OMNI;
  18.915 +					}
  18.916 +					else if (!ASSIMP_strincmp("target",filePtr,6))
  18.917 +					{
  18.918 +						((ASE::Light&)node).mLightType = ASE::Light::TARGET;
  18.919 +					}
  18.920 +					else if (!ASSIMP_strincmp("free",filePtr,4))
  18.921 +					{
  18.922 +						((ASE::Light&)node).mLightType = ASE::Light::FREE;
  18.923 +					}
  18.924 +					else if (!ASSIMP_strincmp("directional",filePtr,11))
  18.925 +					{
  18.926 +						((ASE::Light&)node).mLightType = ASE::Light::DIRECTIONAL;
  18.927 +					}
  18.928 +					else
  18.929 +					{
  18.930 +						LogWarning("Unknown kind of light source");
  18.931 +					}
  18.932 +					continue;
  18.933 +				}
  18.934 +			}
  18.935 +			else if (node.mType == BaseNode::Camera)
  18.936 +			{
  18.937 +				// Camera settings
  18.938 +				if (TokenMatch(filePtr,"CAMERA_SETTINGS" ,15))
  18.939 +				{
  18.940 +					ParseLV2CameraSettingsBlock((ASE::Camera&)node);
  18.941 +					continue;
  18.942 +				}
  18.943 +				else if (TokenMatch(filePtr,"CAMERA_TYPE" ,11))
  18.944 +				{
  18.945 +					if (!ASSIMP_strincmp("target",filePtr,6))
  18.946 +					{
  18.947 +						((ASE::Camera&)node).mCameraType = ASE::Camera::TARGET;
  18.948 +					}
  18.949 +					else if (!ASSIMP_strincmp("free",filePtr,4))
  18.950 +					{
  18.951 +						((ASE::Camera&)node).mCameraType = ASE::Camera::FREE;
  18.952 +					}
  18.953 +					else
  18.954 +					{
  18.955 +						LogWarning("Unknown kind of camera");
  18.956 +					}
  18.957 +					continue;
  18.958 +				}
  18.959 +			}
  18.960 +			else if (node.mType == BaseNode::Mesh)
  18.961 +			{
  18.962 +				// mesh data
  18.963 +				// FIX: Older files use MESH_SOFTSKIN
  18.964 +				if (TokenMatch(filePtr,"MESH" ,4) || 
  18.965 +					TokenMatch(filePtr,"MESH_SOFTSKIN",13))
  18.966 +				{
  18.967 +					ParseLV2MeshBlock((ASE::Mesh&)node);
  18.968 +					continue;
  18.969 +				}
  18.970 +				// mesh material index
  18.971 +				if (TokenMatch(filePtr,"MATERIAL_REF" ,12))
  18.972 +				{
  18.973 +					ParseLV4MeshLong(((ASE::Mesh&)node).iMaterialIndex);
  18.974 +					continue;
  18.975 +				}
  18.976 +			}
  18.977 +		}
  18.978 +		AI_ASE_HANDLE_TOP_LEVEL_SECTION();
  18.979 +	}
  18.980 +	return;
  18.981 +}
  18.982 +
  18.983 +// ------------------------------------------------------------------------------------------------
  18.984 +void Parser::ParseLV2CameraSettingsBlock(ASE::Camera& camera)
  18.985 +{
  18.986 +	AI_ASE_PARSER_INIT();
  18.987 +	while (true)
  18.988 +	{
  18.989 +		if ('*' == *filePtr)
  18.990 +		{
  18.991 +			++filePtr;
  18.992 +			if (TokenMatch(filePtr,"CAMERA_NEAR" ,11))
  18.993 +			{
  18.994 +				ParseLV4MeshFloat(camera.mNear);
  18.995 +				continue;
  18.996 +			}
  18.997 +			if (TokenMatch(filePtr,"CAMERA_FAR" ,10))
  18.998 +			{
  18.999 +				ParseLV4MeshFloat(camera.mFar);
 18.1000 +				continue;
 18.1001 +			}
 18.1002 +			if (TokenMatch(filePtr,"CAMERA_FOV" ,10))
 18.1003 +			{
 18.1004 +				ParseLV4MeshFloat(camera.mFOV);
 18.1005 +				continue;
 18.1006 +			}
 18.1007 +		}
 18.1008 +		AI_ASE_HANDLE_SECTION("2","CAMERA_SETTINGS");
 18.1009 +	}
 18.1010 +	return;
 18.1011 +}
 18.1012 +
 18.1013 +// ------------------------------------------------------------------------------------------------
 18.1014 +void Parser::ParseLV2LightSettingsBlock(ASE::Light& light)
 18.1015 +{
 18.1016 +	AI_ASE_PARSER_INIT();
 18.1017 +	while (true)
 18.1018 +	{
 18.1019 +		if ('*' == *filePtr)
 18.1020 +		{
 18.1021 +			++filePtr;
 18.1022 +			if (TokenMatch(filePtr,"LIGHT_COLOR" ,11))
 18.1023 +			{
 18.1024 +				ParseLV4MeshFloatTriple(&light.mColor.r);
 18.1025 +				continue;
 18.1026 +			}
 18.1027 +			if (TokenMatch(filePtr,"LIGHT_INTENS" ,12))
 18.1028 +			{
 18.1029 +				ParseLV4MeshFloat(light.mIntensity);
 18.1030 +				continue;
 18.1031 +			}
 18.1032 +			if (TokenMatch(filePtr,"LIGHT_HOTSPOT" ,13))
 18.1033 +			{
 18.1034 +				ParseLV4MeshFloat(light.mAngle);
 18.1035 +				continue;
 18.1036 +			}
 18.1037 +			if (TokenMatch(filePtr,"LIGHT_FALLOFF" ,13))
 18.1038 +			{
 18.1039 +				ParseLV4MeshFloat(light.mFalloff);
 18.1040 +				continue;
 18.1041 +			}
 18.1042 +		}
 18.1043 +		AI_ASE_HANDLE_SECTION("2","LIGHT_SETTINGS");
 18.1044 +	}
 18.1045 +	return;
 18.1046 +}
 18.1047 +
 18.1048 +// ------------------------------------------------------------------------------------------------
 18.1049 +void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
 18.1050 +{
 18.1051 +	AI_ASE_PARSER_INIT();
 18.1052 +
 18.1053 +	ASE::Animation* anim = &mesh.mAnim;
 18.1054 +	while (true)
 18.1055 +	{
 18.1056 +		if ('*' == *filePtr)
 18.1057 +		{
 18.1058 +			++filePtr;
 18.1059 +			if (TokenMatch(filePtr,"NODE_NAME" ,9))
 18.1060 +			{
 18.1061 +				std::string temp;
 18.1062 +				if(!ParseString(temp,"*NODE_NAME"))
 18.1063 +					SkipToNextToken();
 18.1064 +
 18.1065 +				// If the name of the node contains .target it 
 18.1066 +				// represents an animated camera or spot light
 18.1067 +				// target.
 18.1068 +				if (std::string::npos != temp.find(".Target"))
 18.1069 +				{
 18.1070 +					if  ((mesh.mType != BaseNode::Camera || ((ASE::Camera&)mesh).mCameraType != ASE::Camera::TARGET)  &&
 18.1071 +						( mesh.mType != BaseNode::Light  || ((ASE::Light&)mesh).mLightType   != ASE::Light::TARGET))
 18.1072 +					{   
 18.1073 +
 18.1074 +						DefaultLogger::get()->error("ASE: Found target animation channel "
 18.1075 +							"but the node is neither a camera nor a spot light");
 18.1076 +						anim = NULL;
 18.1077 +					}
 18.1078 +					else anim = &mesh.mTargetAnim;
 18.1079 +				}
 18.1080 +				continue;
 18.1081 +			}
 18.1082 +
 18.1083 +			// position keyframes
 18.1084 +			if (TokenMatch(filePtr,"CONTROL_POS_TRACK"  ,17)  ||
 18.1085 +				TokenMatch(filePtr,"CONTROL_POS_BEZIER" ,18)  ||
 18.1086 +				TokenMatch(filePtr,"CONTROL_POS_TCB"    ,15))
 18.1087 +			{
 18.1088 +				if (!anim)SkipSection();
 18.1089 +				else ParseLV3PosAnimationBlock(*anim);
 18.1090 +				continue;
 18.1091 +			}
 18.1092 +			// scaling keyframes
 18.1093 +			if (TokenMatch(filePtr,"CONTROL_SCALE_TRACK"  ,19) ||
 18.1094 +				TokenMatch(filePtr,"CONTROL_SCALE_BEZIER" ,20) ||
 18.1095 +				TokenMatch(filePtr,"CONTROL_SCALE_TCB"    ,17))
 18.1096 +			{
 18.1097 +				if (!anim || anim == &mesh.mTargetAnim)
 18.1098 +				{
 18.1099 +					// Target animation channels may have no rotation channels
 18.1100 +					DefaultLogger::get()->error("ASE: Ignoring scaling channel in target animation");
 18.1101 +					SkipSection();
 18.1102 +				}
 18.1103 +				else ParseLV3ScaleAnimationBlock(*anim);
 18.1104 +				continue;
 18.1105 +			}
 18.1106 +			// rotation keyframes
 18.1107 +			if (TokenMatch(filePtr,"CONTROL_ROT_TRACK"  ,17) ||
 18.1108 +				TokenMatch(filePtr,"CONTROL_ROT_BEZIER" ,18) ||
 18.1109 +				TokenMatch(filePtr,"CONTROL_ROT_TCB"    ,15))
 18.1110 +			{
 18.1111 +				if (!anim || anim == &mesh.mTargetAnim)
 18.1112 +				{
 18.1113 +					// Target animation channels may have no rotation channels
 18.1114 +					DefaultLogger::get()->error("ASE: Ignoring rotation channel in target animation");
 18.1115 +					SkipSection();
 18.1116 +				}
 18.1117 +				else ParseLV3RotAnimationBlock(*anim);
 18.1118 +				continue;
 18.1119 +			}
 18.1120 +		}
 18.1121 +		AI_ASE_HANDLE_SECTION("2","TM_ANIMATION");
 18.1122 +	}
 18.1123 +}
 18.1124 +// ------------------------------------------------------------------------------------------------
 18.1125 +void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation& anim)
 18.1126 +{
 18.1127 +	AI_ASE_PARSER_INIT();
 18.1128 +	unsigned int iIndex;
 18.1129 +
 18.1130 +	while (true)
 18.1131 +	{
 18.1132 +		if ('*' == *filePtr)
 18.1133 +		{
 18.1134 +			++filePtr;
 18.1135 +
 18.1136 +			bool b = false;
 18.1137 +
 18.1138 +			// For the moment we're just reading the three floats -
 18.1139 +			// we ignore the ádditional information for bezier's and TCBs
 18.1140 +
 18.1141 +			// simple scaling keyframe
 18.1142 +			if (TokenMatch(filePtr,"CONTROL_SCALE_SAMPLE" ,20))
 18.1143 +			{
 18.1144 +				b = true;
 18.1145 +				anim.mScalingType = ASE::Animation::TRACK;
 18.1146 +			}
 18.1147 +
 18.1148 +			// Bezier scaling keyframe
 18.1149 +			if (TokenMatch(filePtr,"CONTROL_BEZIER_SCALE_KEY" ,24))
 18.1150 +			{
 18.1151 +				b = true;
 18.1152 +				anim.mScalingType = ASE::Animation::BEZIER;
 18.1153 +			}
 18.1154 +			// TCB scaling keyframe
 18.1155 +			if (TokenMatch(filePtr,"CONTROL_TCB_SCALE_KEY" ,21))
 18.1156 +			{
 18.1157 +				b = true;
 18.1158 +				anim.mScalingType = ASE::Animation::TCB;
 18.1159 +			}
 18.1160 +			if (b)
 18.1161 +			{
 18.1162 +				anim.akeyScaling.push_back(aiVectorKey());
 18.1163 +				aiVectorKey& key = anim.akeyScaling.back();
 18.1164 +				ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
 18.1165 +				key.mTime = (double)iIndex;
 18.1166 +			}
 18.1167 +		}
 18.1168 +		AI_ASE_HANDLE_SECTION("3","*CONTROL_POS_TRACK");
 18.1169 +	}
 18.1170 +}
 18.1171 +// ------------------------------------------------------------------------------------------------
 18.1172 +void Parser::ParseLV3PosAnimationBlock(ASE::Animation& anim)
 18.1173 +{
 18.1174 +	AI_ASE_PARSER_INIT();
 18.1175 +	unsigned int iIndex;
 18.1176 +	while (true)
 18.1177 +	{
 18.1178 +		if ('*' == *filePtr)
 18.1179 +		{
 18.1180 +			++filePtr;
 18.1181 +			
 18.1182 +			bool b = false;
 18.1183 +
 18.1184 +			// For the moment we're just reading the three floats -
 18.1185 +			// we ignore the ádditional information for bezier's and TCBs
 18.1186 +
 18.1187 +			// simple scaling keyframe
 18.1188 +			if (TokenMatch(filePtr,"CONTROL_POS_SAMPLE" ,18))
 18.1189 +			{
 18.1190 +				b = true;
 18.1191 +				anim.mPositionType = ASE::Animation::TRACK;
 18.1192 +			}
 18.1193 +
 18.1194 +			// Bezier scaling keyframe
 18.1195 +			if (TokenMatch(filePtr,"CONTROL_BEZIER_POS_KEY" ,22))
 18.1196 +			{
 18.1197 +				b = true;
 18.1198 +				anim.mPositionType = ASE::Animation::BEZIER;
 18.1199 +			}
 18.1200 +			// TCB scaling keyframe
 18.1201 +			if (TokenMatch(filePtr,"CONTROL_TCB_POS_KEY" ,19))
 18.1202 +			{
 18.1203 +				b = true;
 18.1204 +				anim.mPositionType = ASE::Animation::TCB;
 18.1205 +			}
 18.1206 +			if (b)
 18.1207 +			{
 18.1208 +				anim.akeyPositions.push_back(aiVectorKey());
 18.1209 +				aiVectorKey& key = anim.akeyPositions.back();
 18.1210 +				ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
 18.1211 +				key.mTime = (double)iIndex;
 18.1212 +			}
 18.1213 +		}
 18.1214 +		AI_ASE_HANDLE_SECTION("3","*CONTROL_POS_TRACK");
 18.1215 +	}
 18.1216 +}
 18.1217 +// ------------------------------------------------------------------------------------------------
 18.1218 +void Parser::ParseLV3RotAnimationBlock(ASE::Animation& anim)
 18.1219 +{
 18.1220 +	AI_ASE_PARSER_INIT();
 18.1221 +	unsigned int iIndex;
 18.1222 +	while (true)
 18.1223 +	{
 18.1224 +		if ('*' == *filePtr)
 18.1225 +		{
 18.1226 +			++filePtr;
 18.1227 +
 18.1228 +			bool b = false;
 18.1229 +
 18.1230 +			// For the moment we're just reading the  floats -
 18.1231 +			// we ignore the ádditional information for bezier's and TCBs
 18.1232 +
 18.1233 +			// simple scaling keyframe
 18.1234 +			if (TokenMatch(filePtr,"CONTROL_ROT_SAMPLE" ,18))
 18.1235 +			{
 18.1236 +				b = true;
 18.1237 +				anim.mRotationType = ASE::Animation::TRACK;
 18.1238 +			}
 18.1239 +
 18.1240 +			// Bezier scaling keyframe
 18.1241 +			if (TokenMatch(filePtr,"CONTROL_BEZIER_ROT_KEY" ,22))
 18.1242 +			{
 18.1243 +				b = true;
 18.1244 +				anim.mRotationType = ASE::Animation::BEZIER;
 18.1245 +			}
 18.1246 +			// TCB scaling keyframe
 18.1247 +			if (TokenMatch(filePtr,"CONTROL_TCB_ROT_KEY" ,19))
 18.1248 +			{
 18.1249 +				b = true;
 18.1250 +				anim.mRotationType = ASE::Animation::TCB;
 18.1251 +			}
 18.1252 +			if (b)
 18.1253 +			{
 18.1254 +				anim.akeyRotations.push_back(aiQuatKey());
 18.1255 +				aiQuatKey& key = anim.akeyRotations.back();
 18.1256 +				aiVector3D v;float f;
 18.1257 +				ParseLV4MeshFloatTriple(&v.x,iIndex);
 18.1258 +				ParseLV4MeshFloat(f);
 18.1259 +				key.mTime = (double)iIndex;
 18.1260 +				key.mValue = aiQuaternion(v,f);
 18.1261 +			}
 18.1262 +		}
 18.1263 +		AI_ASE_HANDLE_SECTION("3","*CONTROL_ROT_TRACK");
 18.1264 +	}
 18.1265 +}
 18.1266 +// ------------------------------------------------------------------------------------------------
 18.1267 +void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode& mesh)
 18.1268 +{
 18.1269 +	AI_ASE_PARSER_INIT();
 18.1270 +	int mode   = 0; 
 18.1271 +	while (true)
 18.1272 +	{
 18.1273 +		if ('*' == *filePtr)
 18.1274 +		{
 18.1275 +			++filePtr;
 18.1276 +			// name of the node
 18.1277 +			if (TokenMatch(filePtr,"NODE_NAME" ,9))
 18.1278 +			{
 18.1279 +				std::string temp;
 18.1280 +				if(!ParseString(temp,"*NODE_NAME"))
 18.1281 +					SkipToNextToken();
 18.1282 +
 18.1283 +				std::string::size_type s;
 18.1284 +				if (temp == mesh.mName)
 18.1285 +				{
 18.1286 +					mode = 1;
 18.1287 +				}
 18.1288 +				else if (std::string::npos != (s = temp.find(".Target")) &&
 18.1289 +					mesh.mName == temp.substr(0,s))
 18.1290 +				{
 18.1291 +					// This should be either a target light or a target camera
 18.1292 +					if ( (mesh.mType == BaseNode::Light &&  ((ASE::Light&)mesh) .mLightType  == ASE::Light::TARGET) ||
 18.1293 +						 (mesh.mType == BaseNode::Camera && ((ASE::Camera&)mesh).mCameraType == ASE::Camera::TARGET))
 18.1294 +					{
 18.1295 +						mode = 2;
 18.1296 +					}
 18.1297 +					else DefaultLogger::get()->error("ASE: Ignoring target transform, "
 18.1298 +						"this is no spot light or target camera");
 18.1299 +				}
 18.1300 +				else
 18.1301 +				{
 18.1302 +					DefaultLogger::get()->error("ASE: Unknown node transformation: " + temp);
 18.1303 +					// mode = 0
 18.1304 +				}
 18.1305 +				continue;
 18.1306 +			}
 18.1307 +			if (mode)
 18.1308 +			{
 18.1309 +				// fourth row of the transformation matrix - and also the 
 18.1310 +				// only information here that is interesting for targets
 18.1311 +				if (TokenMatch(filePtr,"TM_ROW3" ,7))
 18.1312 +				{
 18.1313 +					ParseLV4MeshFloatTriple((mode == 1 ? mesh.mTransform[3] : &mesh.mTargetPosition.x));
 18.1314 +					continue;
 18.1315 +				}
 18.1316 +				if (mode == 1)
 18.1317 +				{
 18.1318 +					// first row of the transformation matrix
 18.1319 +					if (TokenMatch(filePtr,"TM_ROW0" ,7))
 18.1320 +					{
 18.1321 +						ParseLV4MeshFloatTriple(mesh.mTransform[0]);
 18.1322 +						continue;
 18.1323 +					}
 18.1324 +					// second row of the transformation matrix
 18.1325 +					if (TokenMatch(filePtr,"TM_ROW1" ,7))
 18.1326 +					{
 18.1327 +						ParseLV4MeshFloatTriple(mesh.mTransform[1]);
 18.1328 +						continue;
 18.1329 +					}
 18.1330 +					// third row of the transformation matrix
 18.1331 +					if (TokenMatch(filePtr,"TM_ROW2" ,7))
 18.1332 +					{
 18.1333 +						ParseLV4MeshFloatTriple(mesh.mTransform[2]);
 18.1334 +						continue;
 18.1335 +					}
 18.1336 +					// inherited position axes
 18.1337 +					if (TokenMatch(filePtr,"INHERIT_POS" ,11))
 18.1338 +					{
 18.1339 +						unsigned int aiVal[3];
 18.1340 +						ParseLV4MeshLongTriple(aiVal);
 18.1341 +
 18.1342 +						for (unsigned int i = 0; i < 3;++i)
 18.1343 +							mesh.inherit.abInheritPosition[i] = aiVal[i] != 0;
 18.1344 +						continue;
 18.1345 +					}
 18.1346 +					// inherited rotation axes
 18.1347 +					if (TokenMatch(filePtr,"INHERIT_ROT" ,11))
 18.1348 +					{
 18.1349 +						unsigned int aiVal[3];
 18.1350 +						ParseLV4MeshLongTriple(aiVal);
 18.1351 +
 18.1352 +						for (unsigned int i = 0; i < 3;++i)
 18.1353 +							mesh.inherit.abInheritRotation[i] = aiVal[i] != 0;
 18.1354 +						continue;
 18.1355 +					}
 18.1356 +					// inherited scaling axes
 18.1357 +					if (TokenMatch(filePtr,"INHERIT_SCL" ,11))
 18.1358 +					{
 18.1359 +						unsigned int aiVal[3];
 18.1360 +						ParseLV4MeshLongTriple(aiVal);
 18.1361 +
 18.1362 +						for (unsigned int i = 0; i < 3;++i)
 18.1363 +							mesh.inherit.abInheritScaling[i] = aiVal[i] != 0;
 18.1364 +						continue;
 18.1365 +					}
 18.1366 +				}
 18.1367 +			}
 18.1368 +		}
 18.1369 +		AI_ASE_HANDLE_SECTION("2","*NODE_TM");
 18.1370 +	}
 18.1371 +	return;
 18.1372 +}
 18.1373 +// ------------------------------------------------------------------------------------------------
 18.1374 +void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
 18.1375 +{
 18.1376 +	AI_ASE_PARSER_INIT();
 18.1377 +
 18.1378 +	unsigned int iNumVertices = 0;
 18.1379 +	unsigned int iNumFaces = 0;
 18.1380 +	unsigned int iNumTVertices = 0;
 18.1381 +	unsigned int iNumTFaces = 0;
 18.1382 +	unsigned int iNumCVertices = 0;
 18.1383 +	unsigned int iNumCFaces = 0;
 18.1384 +	while (true)
 18.1385 +	{
 18.1386 +		if ('*' == *filePtr)
 18.1387 +		{
 18.1388 +			++filePtr;
 18.1389 +			// Number of vertices in the mesh
 18.1390 +			if (TokenMatch(filePtr,"MESH_NUMVERTEX" ,14))
 18.1391 +			{
 18.1392 +				ParseLV4MeshLong(iNumVertices);
 18.1393 +				continue;
 18.1394 +			}
 18.1395 +			// Number of texture coordinates in the mesh
 18.1396 +			if (TokenMatch(filePtr,"MESH_NUMTVERTEX" ,15))
 18.1397 +			{
 18.1398 +				ParseLV4MeshLong(iNumTVertices);
 18.1399 +				continue;
 18.1400 +			}
 18.1401 +			// Number of vertex colors in the mesh
 18.1402 +			if (TokenMatch(filePtr,"MESH_NUMCVERTEX" ,15))
 18.1403 +			{
 18.1404 +				ParseLV4MeshLong(iNumCVertices);
 18.1405 +				continue;
 18.1406 +			}
 18.1407 +			// Number of regular faces in the mesh
 18.1408 +			if (TokenMatch(filePtr,"MESH_NUMFACES" ,13))
 18.1409 +			{
 18.1410 +				ParseLV4MeshLong(iNumFaces);
 18.1411 +				continue;
 18.1412 +			}
 18.1413 +			// Number of UVWed faces in the mesh
 18.1414 +			if (TokenMatch(filePtr,"MESH_NUMTVFACES" ,15))
 18.1415 +			{
 18.1416 +				ParseLV4MeshLong(iNumTFaces);
 18.1417 +				continue;
 18.1418 +			}
 18.1419 +			// Number of colored faces in the mesh
 18.1420 +			if (TokenMatch(filePtr,"MESH_NUMCVFACES" ,15))
 18.1421 +			{
 18.1422 +				ParseLV4MeshLong(iNumCFaces);
 18.1423 +				continue;
 18.1424 +			}
 18.1425 +			// mesh vertex list block
 18.1426 +			if (TokenMatch(filePtr,"MESH_VERTEX_LIST" ,16))
 18.1427 +			{
 18.1428 +				ParseLV3MeshVertexListBlock(iNumVertices,mesh);
 18.1429 +				continue;
 18.1430 +			}
 18.1431 +			// mesh face list block
 18.1432 +			if (TokenMatch(filePtr,"MESH_FACE_LIST" ,14))
 18.1433 +			{
 18.1434 +				ParseLV3MeshFaceListBlock(iNumFaces,mesh);
 18.1435 +				continue;
 18.1436 +			}
 18.1437 +			// mesh texture vertex list block
 18.1438 +			if (TokenMatch(filePtr,"MESH_TVERTLIST" ,14))
 18.1439 +			{
 18.1440 +				ParseLV3MeshTListBlock(iNumTVertices,mesh);
 18.1441 +				continue;
 18.1442 +			}
 18.1443 +			// mesh texture face block
 18.1444 +			if (TokenMatch(filePtr,"MESH_TFACELIST" ,14))
 18.1445 +			{
 18.1446 +				ParseLV3MeshTFaceListBlock(iNumTFaces,mesh);
 18.1447 +				continue;
 18.1448 +			}
 18.1449 +			// mesh color vertex list block
 18.1450 +			if (TokenMatch(filePtr,"MESH_CVERTLIST" ,14))
 18.1451 +			{
 18.1452 +				ParseLV3MeshCListBlock(iNumCVertices,mesh);
 18.1453 +				continue;
 18.1454 +			}
 18.1455 +			// mesh color face block
 18.1456 +			if (TokenMatch(filePtr,"MESH_CFACELIST" ,14))
 18.1457 +			{
 18.1458 +				ParseLV3MeshCFaceListBlock(iNumCFaces,mesh);
 18.1459 +				continue;
 18.1460 +			}
 18.1461 +			// mesh normals
 18.1462 +			if (TokenMatch(filePtr,"MESH_NORMALS" ,12))
 18.1463 +			{
 18.1464 +				ParseLV3MeshNormalListBlock(mesh);
 18.1465 +				continue;
 18.1466 +			}
 18.1467 +			// another mesh UV channel ...
 18.1468 +			if (TokenMatch(filePtr,"MESH_MAPPINGCHANNEL" ,19))
 18.1469 +			{
 18.1470 +
 18.1471 +				unsigned int iIndex = 0;
 18.1472 +				ParseLV4MeshLong(iIndex);
 18.1473 +
 18.1474 +				if (iIndex < 2)
 18.1475 +				{
 18.1476 +					LogWarning("Mapping channel has an invalid index. Skipping UV channel");
 18.1477 +					// skip it ...
 18.1478 +					SkipSection();
 18.1479 +				}
 18.1480 +				if (iIndex > AI_MAX_NUMBER_OF_TEXTURECOORDS)
 18.1481 +				{
 18.1482 +					LogWarning("Too many UV channels specified. Skipping channel ..");
 18.1483 +					// skip it ...
 18.1484 +					SkipSection();
 18.1485 +				}
 18.1486 +				else
 18.1487 +				{
 18.1488 +					// parse the mapping channel
 18.1489 +					ParseLV3MappingChannel(iIndex-1,mesh);
 18.1490 +				}
 18.1491 +				continue;
 18.1492 +			}
 18.1493 +			// mesh animation keyframe. Not supported
 18.1494 +			if (TokenMatch(filePtr,"MESH_ANIMATION" ,14))
 18.1495 +			{
 18.1496 +				
 18.1497 +				LogWarning("Found *MESH_ANIMATION element in ASE/ASK file. "
 18.1498 +					"Keyframe animation is not supported by Assimp, this element "
 18.1499 +					"will be ignored");
 18.1500 +				//SkipSection();
 18.1501 +				continue;
 18.1502 +			}
 18.1503 +			if (TokenMatch(filePtr,"MESH_WEIGHTS" ,12))
 18.1504 +			{
 18.1505 +				ParseLV3MeshWeightsBlock(mesh);continue;
 18.1506 +			}
 18.1507 +		}
 18.1508 +		AI_ASE_HANDLE_SECTION("2","*MESH");
 18.1509 +	}
 18.1510 +	return;
 18.1511 +}
 18.1512 +// ------------------------------------------------------------------------------------------------
 18.1513 +void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
 18.1514 +{
 18.1515 +	AI_ASE_PARSER_INIT();
 18.1516 +
 18.1517 +	unsigned int iNumVertices = 0, iNumBones = 0;
 18.1518 +	while (true)
 18.1519 +	{
 18.1520 +		if ('*' == *filePtr)
 18.1521 +		{
 18.1522 +			++filePtr;
 18.1523 +
 18.1524 +			// Number of bone vertices ...
 18.1525 +			if (TokenMatch(filePtr,"MESH_NUMVERTEX" ,14))
 18.1526 +			{
 18.1527 +				ParseLV4MeshLong(iNumVertices);
 18.1528 +				continue;
 18.1529 +			}
 18.1530 +			// Number of bones
 18.1531 +			if (TokenMatch(filePtr,"MESH_NUMBONE" ,11))
 18.1532 +			{
 18.1533 +				ParseLV4MeshLong(iNumBones);
 18.1534 +				continue;
 18.1535 +			}
 18.1536 +			// parse the list of bones
 18.1537 +			if (TokenMatch(filePtr,"MESH_BONE_LIST" ,14))
 18.1538 +			{
 18.1539 +				ParseLV4MeshBones(iNumBones,mesh);
 18.1540 +				continue;
 18.1541 +			}
 18.1542 +			// parse the list of bones vertices
 18.1543 +			if (TokenMatch(filePtr,"MESH_BONE_VERTEX_LIST" ,21) )
 18.1544 +			{
 18.1545 +				ParseLV4MeshBonesVertices(iNumVertices,mesh);
 18.1546 +				continue;
 18.1547 +			}
 18.1548 +		}
 18.1549 +		AI_ASE_HANDLE_SECTION("3","*MESH_WEIGHTS");
 18.1550 +	}
 18.1551 +	return;
 18.1552 +}
 18.1553 +// ------------------------------------------------------------------------------------------------
 18.1554 +void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh)
 18.1555 +{
 18.1556 +	AI_ASE_PARSER_INIT();
 18.1557 +	mesh.mBones.resize(iNumBones);
 18.1558 +	while (true)
 18.1559 +	{
 18.1560 +		if ('*' == *filePtr)
 18.1561 +		{
 18.1562 +			++filePtr;
 18.1563 +
 18.1564 +			// Mesh bone with name ...
 18.1565 +			if (TokenMatch(filePtr,"MESH_BONE_NAME" ,16))
 18.1566 +			{
 18.1567 +				// parse an index ...
 18.1568 +				if(SkipSpaces(&filePtr))
 18.1569 +				{
 18.1570 +					unsigned int iIndex = strtoul10(filePtr,&filePtr);
 18.1571 +					if (iIndex >= iNumBones)
 18.1572 +					{
 18.1573 +						LogWarning("Bone index is out of bounds");
 18.1574 +						continue;
 18.1575 +					}
 18.1576 +					if (!ParseString(mesh.mBones[iIndex].mName,"*MESH_BONE_NAME"))						
 18.1577 +						SkipToNextToken();
 18.1578 +					continue;
 18.1579 +				}
 18.1580 +			}
 18.1581 +		}
 18.1582 +		AI_ASE_HANDLE_SECTION("3","*MESH_BONE_LIST");
 18.1583 +	}
 18.1584 +}
 18.1585 +// ------------------------------------------------------------------------------------------------
 18.1586 +void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices,ASE::Mesh& mesh)
 18.1587 +{
 18.1588 +	AI_ASE_PARSER_INIT();
 18.1589 +	mesh.mBoneVertices.resize(iNumVertices);
 18.1590 +	while (true)
 18.1591 +	{
 18.1592 +		if ('*' == *filePtr)
 18.1593 +		{
 18.1594 +			++filePtr;
 18.1595 +
 18.1596 +			// Mesh bone vertex
 18.1597 +			if (TokenMatch(filePtr,"MESH_BONE_VERTEX" ,16))
 18.1598 +			{
 18.1599 +				// read the vertex index
 18.1600 +				unsigned int iIndex = strtoul10(filePtr,&filePtr);
 18.1601 +				if (iIndex >= mesh.mPositions.size())
 18.1602 +				{
 18.1603 +					iIndex = (unsigned int)mesh.mPositions.size()-1;
 18.1604 +					LogWarning("Bone vertex index is out of bounds. Using the largest valid "
 18.1605 +						"bone vertex index instead");
 18.1606 +				}
 18.1607 +
 18.1608 +				// --- ignored
 18.1609 +				float afVert[3];
 18.1610 +				ParseLV4MeshFloatTriple(afVert);
 18.1611 +
 18.1612 +				std::pair<int,float> pairOut;
 18.1613 +				while (true)
 18.1614 +				{
 18.1615 +					// first parse the bone index ...
 18.1616 +					if (!SkipSpaces(&filePtr))break;
 18.1617 +					pairOut.first = strtoul10(filePtr,&filePtr);
 18.1618 +
 18.1619 +					// then parse the vertex weight
 18.1620 +					if (!SkipSpaces(&filePtr))break;
 18.1621 +					filePtr = fast_atoreal_move<float>(filePtr,pairOut.second);
 18.1622 +
 18.1623 +					// -1 marks unused entries
 18.1624 +					if (-1 != pairOut.first)
 18.1625 +					{
 18.1626 +						mesh.mBoneVertices[iIndex].mBoneWeights.push_back(pairOut);
 18.1627 +					}
 18.1628 +				}
 18.1629 +				continue;
 18.1630 +			}
 18.1631 +		}
 18.1632 +		AI_ASE_HANDLE_SECTION("4","*MESH_BONE_VERTEX");
 18.1633 +	}
 18.1634 +	return;
 18.1635 +}
 18.1636 +// ------------------------------------------------------------------------------------------------
 18.1637 +void Parser::ParseLV3MeshVertexListBlock(
 18.1638 +	unsigned int iNumVertices, ASE::Mesh& mesh)
 18.1639 +{
 18.1640 +	AI_ASE_PARSER_INIT();
 18.1641 +
 18.1642 +	// allocate enough storage in the array
 18.1643 +	mesh.mPositions.resize(iNumVertices);
 18.1644 +	while (true)
 18.1645 +	{
 18.1646 +		if ('*' == *filePtr)
 18.1647 +		{
 18.1648 +			++filePtr;
 18.1649 +
 18.1650 +			// Vertex entry
 18.1651 +			if (TokenMatch(filePtr,"MESH_VERTEX" ,11))
 18.1652 +			{
 18.1653 +				
 18.1654 +				aiVector3D vTemp;
 18.1655 +				unsigned int iIndex;
 18.1656 +				ParseLV4MeshFloatTriple(&vTemp.x,iIndex);
 18.1657 +
 18.1658 +				if (iIndex >= iNumVertices)
 18.1659 +				{
 18.1660 +					LogWarning("Invalid vertex index. It will be ignored");
 18.1661 +				}
 18.1662 +				else mesh.mPositions[iIndex] = vTemp;
 18.1663 +				continue;
 18.1664 +			}
 18.1665 +		}
 18.1666 +		AI_ASE_HANDLE_SECTION("3","*MESH_VERTEX_LIST");
 18.1667 +	}
 18.1668 +	return;
 18.1669 +}
 18.1670 +// ------------------------------------------------------------------------------------------------
 18.1671 +void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
 18.1672 +{
 18.1673 +	AI_ASE_PARSER_INIT();
 18.1674 +
 18.1675 +	// allocate enough storage in the face array
 18.1676 +	mesh.mFaces.resize(iNumFaces);
 18.1677 +	while (true)
 18.1678 +	{
 18.1679 +		if ('*' == *filePtr)
 18.1680 +		{
 18.1681 +			++filePtr;
 18.1682 +
 18.1683 +			// Face entry
 18.1684 +			if (TokenMatch(filePtr,"MESH_FACE" ,9))
 18.1685 +			{
 18.1686 +
 18.1687 +				ASE::Face mFace;
 18.1688 +				ParseLV4MeshFace(mFace);
 18.1689 +
 18.1690 +				if (mFace.iFace >= iNumFaces)
 18.1691 +				{
 18.1692 +					LogWarning("Face has an invalid index. It will be ignored");
 18.1693 +				}
 18.1694 +				else mesh.mFaces[mFace.iFace] = mFace;
 18.1695 +				continue;
 18.1696 +			}
 18.1697 +		}
 18.1698 +		AI_ASE_HANDLE_SECTION("3","*MESH_FACE_LIST");
 18.1699 +	}
 18.1700 +	return;
 18.1701 +}
 18.1702 +// ------------------------------------------------------------------------------------------------
 18.1703 +void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
 18.1704 +	ASE::Mesh& mesh, unsigned int iChannel)
 18.1705 +{
 18.1706 +	AI_ASE_PARSER_INIT();
 18.1707 +
 18.1708 +	// allocate enough storage in the array
 18.1709 +	mesh.amTexCoords[iChannel].resize(iNumVertices);
 18.1710 +	while (true)
 18.1711 +	{
 18.1712 +		if ('*' == *filePtr)
 18.1713 +		{
 18.1714 +			++filePtr;
 18.1715 +
 18.1716 +			// Vertex entry
 18.1717 +			if (TokenMatch(filePtr,"MESH_TVERT" ,10))
 18.1718 +			{
 18.1719 +				aiVector3D vTemp;
 18.1720 +				unsigned int iIndex;
 18.1721 +				ParseLV4MeshFloatTriple(&vTemp.x,iIndex);
 18.1722 +
 18.1723 +				if (iIndex >= iNumVertices)
 18.1724 +				{
 18.1725 +					LogWarning("Tvertex has an invalid index. It will be ignored");
 18.1726 +				}
 18.1727 +				else mesh.amTexCoords[iChannel][iIndex] = vTemp;
 18.1728 +
 18.1729 +				if (0.0f != vTemp.z)
 18.1730 +				{
 18.1731 +					// we need 3 coordinate channels
 18.1732 +					mesh.mNumUVComponents[iChannel] = 3;
 18.1733 +				}
 18.1734 +				continue;
 18.1735 +			}
 18.1736 +		}
 18.1737 +		AI_ASE_HANDLE_SECTION("3","*MESH_TVERT_LIST");
 18.1738 +	}
 18.1739 +	return;
 18.1740 +}
 18.1741 +// ------------------------------------------------------------------------------------------------
 18.1742 +void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
 18.1743 +	ASE::Mesh& mesh, unsigned int iChannel)
 18.1744 +{
 18.1745 +	AI_ASE_PARSER_INIT();
 18.1746 +	while (true)
 18.1747 +	{
 18.1748 +		if ('*' == *filePtr)
 18.1749 +		{
 18.1750 +			++filePtr;
 18.1751 +
 18.1752 +			// Face entry
 18.1753 +			if (TokenMatch(filePtr,"MESH_TFACE" ,10))
 18.1754 +			{
 18.1755 +				unsigned int aiValues[3];
 18.1756 +				unsigned int iIndex = 0;
 18.1757 +
 18.1758 +				ParseLV4MeshLongTriple(aiValues,iIndex);
 18.1759 +				if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size())
 18.1760 +				{
 18.1761 +					LogWarning("UV-Face has an invalid index. It will be ignored");
 18.1762 +				}
 18.1763 +				else
 18.1764 +				{
 18.1765 +					// copy UV indices
 18.1766 +					mesh.mFaces[iIndex].amUVIndices[iChannel][0] = aiValues[0];
 18.1767 +					mesh.mFaces[iIndex].amUVIndices[iChannel][1] = aiValues[1];
 18.1768 +					mesh.mFaces[iIndex].amUVIndices[iChannel][2] = aiValues[2];
 18.1769 +				}
 18.1770 +				continue;
 18.1771 +			}
 18.1772 +		}
 18.1773 +		AI_ASE_HANDLE_SECTION("3","*MESH_TFACE_LIST");
 18.1774 +	}
 18.1775 +	return;
 18.1776 +}
 18.1777 +// ------------------------------------------------------------------------------------------------
 18.1778 +void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
 18.1779 +{
 18.1780 +	AI_ASE_PARSER_INIT();
 18.1781 +
 18.1782 +	unsigned int iNumTVertices = 0;
 18.1783 +	unsigned int iNumTFaces = 0;
 18.1784 +	while (true)
 18.1785 +	{
 18.1786 +		if ('*' == *filePtr)
 18.1787 +		{
 18.1788 +			++filePtr;
 18.1789 +
 18.1790 +			// Number of texture coordinates in the mesh
 18.1791 +			if (TokenMatch(filePtr,"MESH_NUMTVERTEX" ,15))
 18.1792 +			{
 18.1793 +				ParseLV4MeshLong(iNumTVertices);
 18.1794 +				continue;
 18.1795 +			}
 18.1796 +			// Number of UVWed faces in the mesh
 18.1797 +			if (TokenMatch(filePtr,"MESH_NUMTVFACES" ,15))
 18.1798 +			{
 18.1799 +				ParseLV4MeshLong(iNumTFaces);
 18.1800 +				continue;
 18.1801 +			}
 18.1802 +			// mesh texture vertex list block
 18.1803 +			if (TokenMatch(filePtr,"MESH_TVERTLIST" ,14))
 18.1804 +			{
 18.1805 +				ParseLV3MeshTListBlock(iNumTVertices,mesh,iChannel);
 18.1806 +				continue;
 18.1807 +			}
 18.1808 +			// mesh texture face block
 18.1809 +			if (TokenMatch(filePtr,"MESH_TFACELIST" ,14))
 18.1810 +			{
 18.1811 +				ParseLV3MeshTFaceListBlock(iNumTFaces,mesh, iChannel);
 18.1812 +				continue;
 18.1813 +			}
 18.1814 +		}
 18.1815 +		AI_ASE_HANDLE_SECTION("3","*MESH_MAPPING_CHANNEL");
 18.1816 +	}
 18.1817 +	return;
 18.1818 +}
 18.1819 +// ------------------------------------------------------------------------------------------------
 18.1820 +void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh)
 18.1821 +{
 18.1822 +	AI_ASE_PARSER_INIT();
 18.1823 +
 18.1824 +	// allocate enough storage in the array
 18.1825 +	mesh.mVertexColors.resize(iNumVertices);
 18.1826 +	while (true)
 18.1827 +	{
 18.1828 +		if ('*' == *filePtr)
 18.1829 +		{
 18.1830 +			++filePtr;
 18.1831 +
 18.1832 +			// Vertex entry
 18.1833 +			if (TokenMatch(filePtr,"MESH_VERTCOL" ,12))
 18.1834 +			{
 18.1835 +				aiColor4D vTemp;
 18.1836 +				vTemp.a = 1.0f;
 18.1837 +				unsigned int iIndex;
 18.1838 +				ParseLV4MeshFloatTriple(&vTemp.r,iIndex);
 18.1839 +
 18.1840 +				if (iIndex >= iNumVertices)
 18.1841 +				{
 18.1842 +					LogWarning("Vertex color has an invalid index. It will be ignored");
 18.1843 +				}
 18.1844 +				else mesh.mVertexColors[iIndex] = vTemp;
 18.1845 +				continue;
 18.1846 +			}
 18.1847 +		}
 18.1848 +		AI_ASE_HANDLE_SECTION("3","*MESH_CVERTEX_LIST");
 18.1849 +	}
 18.1850 +	return;
 18.1851 +}
 18.1852 +// ------------------------------------------------------------------------------------------------
 18.1853 +void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
 18.1854 +{
 18.1855 +	AI_ASE_PARSER_INIT();
 18.1856 +	while (true)
 18.1857 +	{
 18.1858 +		if ('*' == *filePtr)
 18.1859 +		{
 18.1860 +			++filePtr;
 18.1861 +
 18.1862 +			// Face entry
 18.1863 +			if (TokenMatch(filePtr,"MESH_CFACE" ,11))
 18.1864 +			{
 18.1865 +				unsigned int aiValues[3];
 18.1866 +				unsigned int iIndex = 0;
 18.1867 +
 18.1868 +				ParseLV4MeshLongTriple(aiValues,iIndex);
 18.1869 +				if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size())
 18.1870 +				{
 18.1871 +					LogWarning("UV-Face has an invalid index. It will be ignored");
 18.1872 +				}
 18.1873 +				else
 18.1874 +				{
 18.1875 +					// copy color indices
 18.1876 +					mesh.mFaces[iIndex].mColorIndices[0] = aiValues[0];
 18.1877 +					mesh.mFaces[iIndex].mColorIndices[1] = aiValues[1];
 18.1878 +					mesh.mFaces[iIndex].mColorIndices[2] = aiValues[2];
 18.1879 +				}
 18.1880 +				continue;
 18.1881 +			}
 18.1882 +		}
 18.1883 +		AI_ASE_HANDLE_SECTION("3","*MESH_CFACE_LIST");
 18.1884 +	}
 18.1885 +	return;
 18.1886 +}
 18.1887 +// ------------------------------------------------------------------------------------------------
 18.1888 +void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
 18.1889 +{
 18.1890 +	AI_ASE_PARSER_INIT();
 18.1891 +
 18.1892 +	// Allocate enough storage for the normals
 18.1893 +	sMesh.mNormals.resize(sMesh.mFaces.size()*3,aiVector3D( 0.f, 0.f, 0.f ));
 18.1894 +	unsigned int index, faceIdx = UINT_MAX;
 18.1895 +
 18.1896 +	// FIXME: rewrite this and find out how to interpret the normals
 18.1897 +	// correctly. This is crap.
 18.1898 +
 18.1899 +	// Smooth the vertex and face normals together. The result
 18.1900 +	// will be edgy then, but otherwise everything would be soft ...
 18.1901 +	while (true)	{
 18.1902 +		if ('*' == *filePtr)	{
 18.1903 +			++filePtr;
 18.1904 +			if (faceIdx != UINT_MAX && TokenMatch(filePtr,"MESH_VERTEXNORMAL",17))	{
 18.1905 +				aiVector3D vNormal;
 18.1906 +				ParseLV4MeshFloatTriple(&vNormal.x,index);
 18.1907 +				if (faceIdx >=  sMesh.mFaces.size())
 18.1908 +					continue;
 18.1909 +					
 18.1910 +				// Make sure we assign it to the correct face
 18.1911 +				const ASE::Face& face = sMesh.mFaces[faceIdx];
 18.1912 +				if (index == face.mIndices[0])
 18.1913 +					index = 0;
 18.1914 +				else if (index == face.mIndices[1])
 18.1915 +					index = 1;
 18.1916 +				else if (index == face.mIndices[2])
 18.1917 +					index = 2;
 18.1918 +				else	{
 18.1919 +					DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_VERTEXNORMAL section");
 18.1920 +					continue;
 18.1921 +				}
 18.1922 +				// We'll renormalize later
 18.1923 +				sMesh.mNormals[faceIdx*3+index] += vNormal;
 18.1924 +				continue;
 18.1925 +			}
 18.1926 +			if (TokenMatch(filePtr,"MESH_FACENORMAL",15))	{
 18.1927 +				aiVector3D vNormal;
 18.1928 +				ParseLV4MeshFloatTriple(&vNormal.x,faceIdx);
 18.1929 +
 18.1930 +				if (faceIdx >= sMesh.mFaces.size())	{
 18.1931 +					DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_FACENORMAL section");
 18.1932 +					continue;
 18.1933 +				}
 18.1934 +
 18.1935 +				// We'll renormalize later
 18.1936 +				sMesh.mNormals[faceIdx*3] += vNormal;
 18.1937 +				sMesh.mNormals[faceIdx*3+1] += vNormal;
 18.1938 +				sMesh.mNormals[faceIdx*3+2] += vNormal;
 18.1939 +				continue;
 18.1940 +			}
 18.1941 +		}
 18.1942 +		AI_ASE_HANDLE_SECTION("3","*MESH_NORMALS");
 18.1943 +	}
 18.1944 +	return;
 18.1945 +}
 18.1946 +// ------------------------------------------------------------------------------------------------
 18.1947 +void Parser::ParseLV4MeshFace(ASE::Face& out)
 18.1948 +{	
 18.1949 +	// skip spaces and tabs
 18.1950 +	if(!SkipSpaces(&filePtr))
 18.1951 +	{
 18.1952 +		LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL [#1]");
 18.1953 +		SkipToNextToken();
 18.1954 +		return;
 18.1955 +	}
 18.1956 +
 18.1957 +	// parse the face index
 18.1958 +	out.iFace = strtoul10(filePtr,&filePtr);
 18.1959 +
 18.1960 +	// next character should be ':'
 18.1961 +	if(!SkipSpaces(&filePtr))
 18.1962 +	{
 18.1963 +		// FIX: there are some ASE files which haven't got : here ....
 18.1964 +		LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. \':\' expected [#2]");
 18.1965 +		SkipToNextToken();
 18.1966 +		return;
 18.1967 +	}
 18.1968 +	// FIX: There are some ASE files which haven't got ':' here 
 18.1969 +	if(':' == *filePtr)++filePtr;
 18.1970 +
 18.1971 +	// Parse all mesh indices
 18.1972 +	for (unsigned int i = 0; i < 3;++i)
 18.1973 +	{
 18.1974 +		unsigned int iIndex = 0;
 18.1975 +		if(!SkipSpaces(&filePtr))
 18.1976 +		{
 18.1977 +			LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL");
 18.1978 +			SkipToNextToken();
 18.1979 +			return;
 18.1980 +		}
 18.1981 +		switch (*filePtr)
 18.1982 +		{
 18.1983 +		case 'A':
 18.1984 +		case 'a':
 18.1985 +			break;
 18.1986 +		case 'B':
 18.1987 +		case 'b':
 18.1988 +			iIndex = 1;
 18.1989 +			break;
 18.1990 +		case 'C':
 18.1991 +		case 'c':
 18.1992 +			iIndex = 2;
 18.1993 +			break;
 18.1994 +		default: 
 18.1995 +			LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. "
 18.1996 +				"A,B or C expected [#3]");
 18.1997 +			SkipToNextToken();
 18.1998 +			return;
 18.1999 +		};
 18.2000 +		++filePtr;
 18.2001 +
 18.2002 +		// next character should be ':'
 18.2003 +		if(!SkipSpaces(&filePtr) || ':' != *filePtr)
 18.2004 +		{
 18.2005 +			LogWarning("Unable to parse *MESH_FACE Element: "
 18.2006 +				"Unexpected EOL. \':\' expected [#2]");
 18.2007 +			SkipToNextToken();
 18.2008 +			return;
 18.2009 +		}
 18.2010 +
 18.2011 +		++filePtr;
 18.2012 +		if(!SkipSpaces(&filePtr))
 18.2013 +		{
 18.2014 +			LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. "
 18.2015 +				"Vertex index ecpected [#4]");
 18.2016 +			SkipToNextToken();
 18.2017 +			return;
 18.2018 +		}
 18.2019 +		out.mIndices[iIndex] = strtoul10(filePtr,&filePtr);
 18.2020 +	}
 18.2021 +
 18.2022 +	// now we need to skip the AB, BC, CA blocks. 
 18.2023 +	while (true)
 18.2024 +	{
 18.2025 +		if ('*' == *filePtr)break;
 18.2026 +		if (IsLineEnd(*filePtr))
 18.2027 +		{
 18.2028 +			//iLineNumber++;
 18.2029 +			return;
 18.2030 +		}
 18.2031 +		filePtr++;
 18.2032 +	}
 18.2033 +
 18.2034 +	// parse the smoothing group of the face
 18.2035 +	if (TokenMatch(filePtr,"*MESH_SMOOTHING",15))
 18.2036 +	{
 18.2037 +		if(!SkipSpaces(&filePtr))
 18.2038 +		{
 18.2039 +			LogWarning("Unable to parse *MESH_SMOOTHING Element: "
 18.2040 +				"Unexpected EOL. Smoothing group(s) expected [#5]");
 18.2041 +			SkipToNextToken();
 18.2042 +			return;
 18.2043 +		}
 18.2044 +		
 18.2045 +		// Parse smoothing groups until we don't anymore see commas
 18.2046 +		// FIX: There needn't always be a value, sad but true
 18.2047 +		while (true)
 18.2048 +		{
 18.2049 +			if (*filePtr < '9' && *filePtr >= '0')
 18.2050 +			{
 18.2051 +				out.iSmoothGroup |= (1 << strtoul10(filePtr,&filePtr));
 18.2052 +			}
 18.2053 +			SkipSpaces(&filePtr);
 18.2054 +			if (',' != *filePtr)
 18.2055 +			{
 18.2056 +				break;
 18.2057 +			}
 18.2058 +			++filePtr;
 18.2059 +			SkipSpaces(&filePtr);
 18.2060 +		}
 18.2061 +	}
 18.2062 +
 18.2063 +	// *MESH_MTLID  is optional, too
 18.2064 +	while (true)
 18.2065 +	{
 18.2066 +		if ('*' == *filePtr)break;
 18.2067 +		if (IsLineEnd(*filePtr))
 18.2068 +		{
 18.2069 +			return;
 18.2070 +		}
 18.2071 +		filePtr++;
 18.2072 +	}
 18.2073 +
 18.2074 +	if (TokenMatch(filePtr,"*MESH_MTLID",11))
 18.2075 +	{
 18.2076 +		if(!SkipSpaces(&filePtr))
 18.2077 +		{
 18.2078 +			LogWarning("Unable to parse *MESH_MTLID Element: Unexpected EOL. "
 18.2079 +				"Material index expected [#6]");
 18.2080 +			SkipToNextToken();
 18.2081 +			return;
 18.2082 +		}
 18.2083 +		out.iMaterial = strtoul10(filePtr,&filePtr);
 18.2084 +	}
 18.2085 +	return;
 18.2086 +}
 18.2087 +// ------------------------------------------------------------------------------------------------
 18.2088 +void Parser::ParseLV4MeshLongTriple(unsigned int* apOut)
 18.2089 +{
 18.2090 +	ai_assert(NULL != apOut);
 18.2091 +
 18.2092 +	for (unsigned int i = 0; i < 3;++i)
 18.2093 +		ParseLV4MeshLong(apOut[i]);
 18.2094 +}
 18.2095 +// ------------------------------------------------------------------------------------------------
 18.2096 +void Parser::ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut)
 18.2097 +{
 18.2098 +	ai_assert(NULL != apOut);
 18.2099 +
 18.2100 +	// parse the index
 18.2101 +	ParseLV4MeshLong(rIndexOut);
 18.2102 +
 18.2103 +	// parse the three others
 18.2104 +	ParseLV4MeshLongTriple(apOut);
 18.2105 +}
 18.2106 +// ------------------------------------------------------------------------------------------------
 18.2107 +void Parser::ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut)
 18.2108 +{
 18.2109 +	ai_assert(NULL != apOut);
 18.2110 +
 18.2111 +	// parse the index
 18.2112 +	ParseLV4MeshLong(rIndexOut);
 18.2113 +	
 18.2114 +	// parse the three others
 18.2115 +	ParseLV4MeshFloatTriple(apOut);
 18.2116 +}
 18.2117 +// ------------------------------------------------------------------------------------------------
 18.2118 +void Parser::ParseLV4MeshFloatTriple(float* apOut)
 18.2119 +{
 18.2120 +	ai_assert(NULL != apOut);
 18.2121 +
 18.2122 +	for (unsigned int i = 0; i < 3;++i)
 18.2123 +		ParseLV4MeshFloat(apOut[i]);
 18.2124 +}
 18.2125 +// ------------------------------------------------------------------------------------------------
 18.2126 +void Parser::ParseLV4MeshFloat(float& fOut)
 18.2127 +{
 18.2128 +	// skip spaces and tabs
 18.2129 +	if(!SkipSpaces(&filePtr))
 18.2130 +	{
 18.2131 +		// LOG 
 18.2132 +		LogWarning("Unable to parse float: unexpected EOL [#1]");
 18.2133 +		fOut = 0.0f;
 18.2134 +		++iLineNumber;
 18.2135 +		return;
 18.2136 +	}
 18.2137 +	// parse the first float
 18.2138 +	filePtr = fast_atoreal_move<float>(filePtr,fOut);
 18.2139 +}
 18.2140 +// ------------------------------------------------------------------------------------------------
 18.2141 +void Parser::ParseLV4MeshLong(unsigned int& iOut)
 18.2142 +{
 18.2143 +	// Skip spaces and tabs
 18.2144 +	if(!SkipSpaces(&filePtr))
 18.2145 +	{
 18.2146 +		// LOG 
 18.2147 +		LogWarning("Unable to parse long: unexpected EOL [#1]");
 18.2148 +		iOut = 0;
 18.2149 +		++iLineNumber;
 18.2150 +		return;
 18.2151 +	}
 18.2152 +	// parse the value
 18.2153 +	iOut = strtoul10(filePtr,&filePtr);
 18.2154 +}
 18.2155 +
 18.2156 +#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/libs/assimp/ASEParser.h	Sat Feb 01 19:58:19 2014 +0200
    19.3 @@ -0,0 +1,669 @@
    19.4 +/*
    19.5 +Open Asset Import Library (assimp)
    19.6 +----------------------------------------------------------------------
    19.7 +
    19.8 +Copyright (c) 2006-2012, assimp team
    19.9 +All rights reserved.
   19.10 +
   19.11 +Redistribution and use of this software in source and binary forms, 
   19.12 +with or without modification, are permitted provided that the 
   19.13 +following conditions are met:
   19.14 +
   19.15 +* Redistributions of source code must retain the above
   19.16 +  copyright notice, this list of conditions and the
   19.17 +  following disclaimer.
   19.18 +
   19.19 +* Redistributions in binary form must reproduce the above
   19.20 +  copyright notice, this list of conditions and the
   19.21 +  following disclaimer in the documentation and/or other
   19.22 +  materials provided with the distribution.
   19.23 +
   19.24 +* Neither the name of the assimp team, nor the names of its
   19.25 +  contributors may be used to endorse or promote products
   19.26 +  derived from this software without specific prior
   19.27 +  written permission of the assimp team.
   19.28 +
   19.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   19.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   19.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   19.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   19.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   19.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   19.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   19.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   19.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   19.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   19.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   19.40 +
   19.41 +----------------------------------------------------------------------
   19.42 +*/
   19.43 +
   19.44 +
   19.45 +/** @file Defines the helper data structures for importing ASE files  */
   19.46 +#ifndef AI_ASEFILEHELPER_H_INC
   19.47 +#define AI_ASEFILEHELPER_H_INC
   19.48 +
   19.49 +// STL/CRT headers
   19.50 +#include <string>
   19.51 +#include <vector>
   19.52 +#include <list>
   19.53 +
   19.54 +// public ASSIMP headers
   19.55 +#include "assimp/types.h"
   19.56 +#include "assimp/mesh.h"
   19.57 +#include "assimp/anim.h"
   19.58 +
   19.59 +// for some helper routines like IsSpace()
   19.60 +#include "ParsingUtils.h"
   19.61 +#include "qnan.h"
   19.62 +
   19.63 +// ASE is quite similar to 3ds. We can reuse some structures
   19.64 +#include "3DSLoader.h"
   19.65 +
   19.66 +namespace Assimp	{
   19.67 +namespace ASE	{
   19.68 +
   19.69 +using namespace D3DS;
   19.70 +
   19.71 +// ---------------------------------------------------------------------------
   19.72 +/** Helper structure representing an ASE material */
   19.73 +struct Material : public D3DS::Material
   19.74 +{
   19.75 +	//! Default constructor
   19.76 +	Material() : pcInstance(NULL), bNeed (false)
   19.77 +	{}
   19.78 +
   19.79 +	//! Contains all sub materials of this material
   19.80 +	std::vector<Material> avSubMaterials;
   19.81 +
   19.82 +	//! aiMaterial object
   19.83 +	aiMaterial* pcInstance;
   19.84 +
   19.85 +	//! Can we remove this material?
   19.86 +	bool bNeed;
   19.87 +};
   19.88 +
   19.89 +// ---------------------------------------------------------------------------
   19.90 +/** Helper structure to represent an ASE file face */
   19.91 +struct Face : public FaceWithSmoothingGroup
   19.92 +{
   19.93 +	//! Default constructor. Initializes everything with 0
   19.94 +	Face()
   19.95 +	{
   19.96 +		mColorIndices[0] = mColorIndices[1] = mColorIndices[2] = 0;
   19.97 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
   19.98 +		{
   19.99 +			amUVIndices[i][0] = amUVIndices[i][1] = amUVIndices[i][2] = 0;
  19.100 +		}
  19.101 +
  19.102 +		iMaterial = DEFAULT_MATINDEX;
  19.103 +		iFace = 0;
  19.104 +	}
  19.105 +
  19.106 +	//! special value to indicate that no material index has
  19.107 +	//! been assigned to a face. The default material index
  19.108 +	//! will replace this value later.
  19.109 +	static const unsigned int DEFAULT_MATINDEX = 0xFFFFFFFF;
  19.110 +
  19.111 +
  19.112 +
  19.113 +	//! Indices into each list of texture coordinates
  19.114 +	unsigned int amUVIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS][3];
  19.115 +
  19.116 +	//! Index into the list of vertex colors
  19.117 +	unsigned int mColorIndices[3];
  19.118 +
  19.119 +	//! (Sub)Material index to be assigned to this face
  19.120 +	unsigned int iMaterial;
  19.121 +
  19.122 +	//! Index of the face. It is not specified whether it is
  19.123 +	//! a requirement of the file format that all faces are
  19.124 +	//! written in sequential order, so we have to expect this case
  19.125 +	unsigned int iFace;
  19.126 +};
  19.127 +
  19.128 +// ---------------------------------------------------------------------------
  19.129 +/** Helper structure to represent an ASE file bone */
  19.130 +struct Bone
  19.131 +{
  19.132 +	//! Constructor
  19.133 +	Bone()
  19.134 +	{
  19.135 +		static int iCnt = 0;
  19.136 +		
  19.137 +		// Generate a default name for the bone
  19.138 +		char szTemp[128];
  19.139 +		::sprintf(szTemp,"UNNAMED_%i",iCnt++);
  19.140 +		mName = szTemp;
  19.141 +	}
  19.142 +
  19.143 +	//! Construction from an existing name
  19.144 +	Bone( const std::string& name)
  19.145 +		:	mName	(name)
  19.146 +	{}
  19.147 +
  19.148 +	//! Name of the bone
  19.149 +	std::string mName;
  19.150 +};
  19.151 +
  19.152 +// ---------------------------------------------------------------------------
  19.153 +/** Helper structure to represent an ASE file bone vertex */
  19.154 +struct BoneVertex
  19.155 +{
  19.156 +	//! Bone and corresponding vertex weight.
  19.157 +	//! -1 for unrequired bones ....
  19.158 +	std::vector<std::pair<int,float> > mBoneWeights;
  19.159 +
  19.160 +	//! Position of the bone vertex.
  19.161 +	//! MUST be identical to the vertex position
  19.162 +	//aiVector3D mPosition;
  19.163 +};
  19.164 +
  19.165 +// ---------------------------------------------------------------------------
  19.166 +/** Helper structure to represent an ASE file animation */
  19.167 +struct Animation
  19.168 +{
  19.169 +	enum Type
  19.170 +	{
  19.171 +		TRACK   = 0x0,
  19.172 +		BEZIER  = 0x1,
  19.173 +		TCB		= 0x2
  19.174 +	} mRotationType, mScalingType, mPositionType;
  19.175 +
  19.176 +	Animation()
  19.177 +		:	mRotationType	(TRACK)
  19.178 +		,	mScalingType	(TRACK)
  19.179 +		,	mPositionType	(TRACK)
  19.180 +	{}
  19.181 +
  19.182 +	//! List of track rotation keyframes
  19.183 +	std::vector< aiQuatKey > akeyRotations;
  19.184 +
  19.185 +	//! List of track position keyframes
  19.186 +	std::vector< aiVectorKey > akeyPositions;
  19.187 +
  19.188 +	//! List of track scaling keyframes
  19.189 +	std::vector< aiVectorKey > akeyScaling;
  19.190 +
  19.191 +};
  19.192 +
  19.193 +// ---------------------------------------------------------------------------
  19.194 +/** Helper structure to represent the inheritance information of an ASE node */
  19.195 +struct InheritanceInfo
  19.196 +{
  19.197 +	//! Default constructor
  19.198 +	InheritanceInfo()
  19.199 +	{
  19.200 +		// set the inheritance flag for all axes by default to true
  19.201 +		for (unsigned int i = 0; i < 3;++i)
  19.202 +			abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
  19.203 +	}
  19.204 +
  19.205 +	//! Inherit the parent's position?, axis order is x,y,z
  19.206 +	bool abInheritPosition[3];
  19.207 +
  19.208 +	//! Inherit the parent's rotation?, axis order is x,y,z
  19.209 +	bool abInheritRotation[3];
  19.210 +
  19.211 +	//! Inherit the parent's scaling?, axis order is x,y,z
  19.212 +	bool abInheritScaling[3];
  19.213 +};
  19.214 +
  19.215 +// ---------------------------------------------------------------------------
  19.216 +/** Represents an ASE file node. Base class for mesh, light and cameras */
  19.217 +struct BaseNode
  19.218 +{
  19.219 +	enum Type {Light, Camera, Mesh, Dummy} mType;
  19.220 +
  19.221 +	//! Constructor. Creates a default name for the node
  19.222 +	BaseNode(Type _mType)
  19.223 +		: mType			(_mType)
  19.224 +		, mProcessed	(false)
  19.225 +	{
  19.226 +		// generate a default name for the  node
  19.227 +		static int iCnt = 0;
  19.228 +		char szTemp[128]; // should be sufficiently large
  19.229 +		::sprintf(szTemp,"UNNAMED_%i",iCnt++);
  19.230 +		mName = szTemp;
  19.231 +
  19.232 +		// Set mTargetPosition to qnan
  19.233 +		const float qnan = get_qnan();
  19.234 +		mTargetPosition.x = qnan;
  19.235 +	}
  19.236 +
  19.237 +	//! Name of the mesh
  19.238 +	std::string mName;
  19.239 +
  19.240 +	//! Name of the parent of the node
  19.241 +	//! "" if there is no parent ...
  19.242 +	std::string mParent;
  19.243 +
  19.244 +	//! Transformation matrix of the node
  19.245 +	aiMatrix4x4 mTransform;
  19.246 +
  19.247 +	//! Target position (target lights and cameras)
  19.248 +	aiVector3D mTargetPosition;
  19.249 +
  19.250 +	//! Specifies which axes transformations a node inherits
  19.251 +	//! from its parent ...
  19.252 +	InheritanceInfo inherit;
  19.253 +
  19.254 +	//! Animation channels for the node
  19.255 +	Animation mAnim;
  19.256 +
  19.257 +	//! Needed for lights and cameras: target animation channel
  19.258 +	//! Should contain position keys only.
  19.259 +	Animation mTargetAnim;
  19.260 +
  19.261 +	bool mProcessed;
  19.262 +};
  19.263 +
  19.264 +// ---------------------------------------------------------------------------
  19.265 +/** Helper structure to represent an ASE file mesh */
  19.266 +struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode
  19.267 +{
  19.268 +	//! Constructor.
  19.269 +	Mesh() 
  19.270 +		: BaseNode	(BaseNode::Mesh)
  19.271 +		, bSkip		(false)
  19.272 +	{
  19.273 +		// use 2 texture vertex components by default
  19.274 +		for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
  19.275 +			this->mNumUVComponents[c] = 2;
  19.276 +
  19.277 +		// setup the default material index by default
  19.278 +		iMaterialIndex = Face::DEFAULT_MATINDEX;
  19.279 +	}
  19.280 +
  19.281 +	//! List of all texture coordinate sets
  19.282 +	std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
  19.283 +
  19.284 +	//! List of all vertex color sets.
  19.285 +	std::vector<aiColor4D> mVertexColors;
  19.286 +
  19.287 +	//! List of all bone vertices
  19.288 +	std::vector<BoneVertex> mBoneVertices;
  19.289 +
  19.290 +	//! List of all bones
  19.291 +	std::vector<Bone> mBones;
  19.292 +
  19.293 +	//! Material index of the mesh
  19.294 +	unsigned int iMaterialIndex;
  19.295 +
  19.296 +	//! Number of vertex components for each UVW set
  19.297 +	unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
  19.298 +
  19.299 +	//! used internally
  19.300 +	bool bSkip;
  19.301 +};
  19.302 +
  19.303 +// ---------------------------------------------------------------------------
  19.304 +/** Helper structure to represent an ASE light source */
  19.305 +struct Light : public BaseNode
  19.306 +{
  19.307 +	enum LightType
  19.308 +	{
  19.309 +		OMNI,
  19.310 +		TARGET,
  19.311 +		FREE,
  19.312 +		DIRECTIONAL
  19.313 +	};
  19.314 +
  19.315 +	//! Constructor. 
  19.316 +	Light() 
  19.317 +		: BaseNode	 (BaseNode::Light)
  19.318 +		, mLightType (OMNI)
  19.319 +		, mColor	 (1.f,1.f,1.f)
  19.320 +		, mIntensity (1.f) // light is white by default
  19.321 +		, mAngle	 (45.f)
  19.322 +		, mFalloff	 (0.f)
  19.323 +	{	
  19.324 +	}
  19.325 +
  19.326 +	LightType mLightType;
  19.327 +	aiColor3D mColor;
  19.328 +	float mIntensity;
  19.329 +	float mAngle; // in degrees
  19.330 +	float mFalloff;
  19.331 +};
  19.332 +
  19.333 +// ---------------------------------------------------------------------------
  19.334 +/** Helper structure to represent an ASE camera */
  19.335 +struct Camera : public BaseNode
  19.336 +{
  19.337 +	enum CameraType
  19.338 +	{
  19.339 +		FREE,
  19.340 +		TARGET
  19.341 +	};
  19.342 +
  19.343 +	//! Constructor
  19.344 +	Camera() 
  19.345 +		: BaseNode	  (BaseNode::Camera)
  19.346 +		, mFOV        (0.75f)   // in radians
  19.347 +		, mNear       (0.1f) 
  19.348 +		, mFar        (1000.f)  // could be zero
  19.349 +		, mCameraType (FREE)
  19.350 +	{
  19.351 +	}
  19.352 +
  19.353 +	float mFOV, mNear, mFar;
  19.354 +	CameraType mCameraType;
  19.355 +};
  19.356 +
  19.357 +// ---------------------------------------------------------------------------
  19.358 +/** Helper structure to represent an ASE helper object (dummy) */
  19.359 +struct Dummy : public BaseNode
  19.360 +{
  19.361 +	//! Constructor
  19.362 +	Dummy() 
  19.363 +		: BaseNode	(BaseNode::Dummy)
  19.364 +	{
  19.365 +	}
  19.366 +};
  19.367 +
  19.368 +// Parameters to Parser::Parse()
  19.369 +#define AI_ASE_NEW_FILE_FORMAT 200
  19.370 +#define AI_ASE_OLD_FILE_FORMAT 110
  19.371 +
  19.372 +// Internally we're a little bit more tolerant
  19.373 +#define AI_ASE_IS_NEW_FILE_FORMAT()	(iFileFormat >= 200)
  19.374 +#define AI_ASE_IS_OLD_FILE_FORMAT()	(iFileFormat < 200)
  19.375 +
  19.376 +// -------------------------------------------------------------------------------
  19.377 +/** \brief Class to parse ASE files
  19.378 + */
  19.379 +class Parser
  19.380 +{
  19.381 +
  19.382 +private:
  19.383 +
  19.384 +	Parser() {}
  19.385 +
  19.386 +public:
  19.387 +
  19.388 +	// -------------------------------------------------------------------
  19.389 +	//! Construct a parser from a given input file which is
  19.390 +	//! guaranted to be terminated with zero.
  19.391 +	//! @param szFile Input file
  19.392 +	//! @param fileFormatDefault Assumed file format version. If the
  19.393 +	//!   file format is specified in the file the new value replaces
  19.394 +	//!   the default value.
  19.395 +	Parser (const char* szFile, unsigned int fileFormatDefault);
  19.396 +
  19.397 +	// -------------------------------------------------------------------
  19.398 +	//! Parses the file into the parsers internal representation
  19.399 +	void Parse();
  19.400 +
  19.401 +
  19.402 +private:
  19.403 +
  19.404 +	// -------------------------------------------------------------------
  19.405 +	//! Parse the *SCENE block in a file
  19.406 +	void ParseLV1SceneBlock();
  19.407 +
  19.408 +	// -------------------------------------------------------------------
  19.409 +	//! Parse the *MESH_SOFTSKINVERTS block in a file
  19.410 +	void ParseLV1SoftSkinBlock();
  19.411 +
  19.412 +	// -------------------------------------------------------------------
  19.413 +	//! Parse the *MATERIAL_LIST block in a file
  19.414 +	void ParseLV1MaterialListBlock();
  19.415 +
  19.416 +	// -------------------------------------------------------------------
  19.417 +	//! Parse a *<xxx>OBJECT block in a file
  19.418 +	//! \param mesh Node to be filled
  19.419 +	void ParseLV1ObjectBlock(BaseNode& mesh);
  19.420 +
  19.421 +	// -------------------------------------------------------------------
  19.422 +	//! Parse a *MATERIAL blocks in a material list
  19.423 +	//! \param mat Material structure to be filled
  19.424 +	void ParseLV2MaterialBlock(Material& mat);
  19.425 +
  19.426 +	// -------------------------------------------------------------------
  19.427 +	//! Parse a *NODE_TM block in a file
  19.428 +	//! \param mesh Node (!) object to be filled
  19.429 +	void ParseLV2NodeTransformBlock(BaseNode& mesh);
  19.430 +
  19.431 +	// -------------------------------------------------------------------
  19.432 +	//! Parse a *TM_ANIMATION block in a file
  19.433 +	//! \param mesh Mesh object to be filled
  19.434 +	void ParseLV2AnimationBlock(BaseNode& mesh);
  19.435 +	void ParseLV3PosAnimationBlock(ASE::Animation& anim);
  19.436 +	void ParseLV3ScaleAnimationBlock(ASE::Animation& anim);
  19.437 +	void ParseLV3RotAnimationBlock(ASE::Animation& anim);
  19.438 +
  19.439 +	// -------------------------------------------------------------------
  19.440 +	//! Parse a *MESH block in a file
  19.441 +	//! \param mesh Mesh object to be filled
  19.442 +	void ParseLV2MeshBlock(Mesh& mesh);
  19.443 +
  19.444 +	// -------------------------------------------------------------------
  19.445 +	//! Parse a *LIGHT_SETTINGS block in a file
  19.446 +	//! \param light Light object to be filled
  19.447 +	void ParseLV2LightSettingsBlock(Light& light);
  19.448 +
  19.449 +	// -------------------------------------------------------------------
  19.450 +	//! Parse a *CAMERA_SETTINGS block in a file
  19.451 +	//! \param cam Camera object to be filled
  19.452 +	void ParseLV2CameraSettingsBlock(Camera& cam);
  19.453 +
  19.454 +	// -------------------------------------------------------------------
  19.455 +	//! Parse the *MAP_XXXXXX blocks in a material
  19.456 +	//! \param map Texture structure to be filled
  19.457 +	void ParseLV3MapBlock(Texture& map);
  19.458 +
  19.459 +	// -------------------------------------------------------------------
  19.460 +	//! Parse a *MESH_VERTEX_LIST block in a file
  19.461 +	//! \param iNumVertices Value of *MESH_NUMVERTEX, if present.
  19.462 +	//! Otherwise zero. This is used to check the consistency of the file.
  19.463 +	//! A warning is sent to the logger if the validations fails.
  19.464 +	//! \param mesh Mesh object to be filled
  19.465 +	void ParseLV3MeshVertexListBlock(
  19.466 +		unsigned int iNumVertices,Mesh& mesh);
  19.467 +
  19.468 +	// -------------------------------------------------------------------
  19.469 +	//! Parse a *MESH_FACE_LIST block in a file
  19.470 +	//! \param iNumFaces Value of *MESH_NUMFACES, if present.
  19.471 +	//! Otherwise zero. This is used to check the consistency of the file.
  19.472 +	//! A warning is sent to the logger if the validations fails.
  19.473 +	//! \param mesh Mesh object to be filled
  19.474 +	void ParseLV3MeshFaceListBlock(
  19.475 +		unsigned int iNumFaces,Mesh& mesh);
  19.476 +
  19.477 +	// -------------------------------------------------------------------
  19.478 +	//! Parse a *MESH_TVERT_LIST block in a file
  19.479 +	//! \param iNumVertices Value of *MESH_NUMTVERTEX, if present.
  19.480 +	//! Otherwise zero. This is used to check the consistency of the file.
  19.481 +	//! A warning is sent to the logger if the validations fails.
  19.482 +	//! \param mesh Mesh object to be filled
  19.483 +	//! \param iChannel Output UVW channel
  19.484 +	void ParseLV3MeshTListBlock(
  19.485 +		unsigned int iNumVertices,Mesh& mesh, unsigned int iChannel = 0);
  19.486 +
  19.487 +	// -------------------------------------------------------------------
  19.488 +	//! Parse a *MESH_TFACELIST block in a file
  19.489 +	//! \param iNumFaces Value of *MESH_NUMTVFACES, if present.
  19.490 +	//! Otherwise zero. This is used to check the consistency of the file.
  19.491 +	//! A warning is sent to the logger if the validations fails.
  19.492 +	//! \param mesh Mesh object to be filled
  19.493 +	//! \param iChannel Output UVW channel
  19.494 +	void ParseLV3MeshTFaceListBlock(
  19.495 +		unsigned int iNumFaces,Mesh& mesh, unsigned int iChannel = 0);
  19.496 +
  19.497 +	// -------------------------------------------------------------------
  19.498 +	//! Parse an additional mapping channel 
  19.499 +	//! (specified via *MESH_MAPPINGCHANNEL)
  19.500 +	//! \param iChannel Channel index to be filled
  19.501 +	//! \param mesh Mesh object to be filled
  19.502 +	void ParseLV3MappingChannel(
  19.503 +		unsigned int iChannel, Mesh& mesh);
  19.504 +
  19.505 +	// -------------------------------------------------------------------
  19.506 +	//! Parse a *MESH_CVERTLIST block in a file
  19.507 +	//! \param iNumVertices Value of *MESH_NUMCVERTEX, if present.
  19.508 +	//! Otherwise zero. This is used to check the consistency of the file.
  19.509 +	//! A warning is sent to the logger if the validations fails.
  19.510 +	//! \param mesh Mesh object to be filled
  19.511 +	void ParseLV3MeshCListBlock(
  19.512 +		unsigned int iNumVertices, Mesh& mesh);
  19.513 +
  19.514 +	// -------------------------------------------------------------------
  19.515 +	//! Parse a *MESH_CFACELIST block in a file
  19.516 +	//! \param iNumFaces Value of *MESH_NUMCVFACES, if present.
  19.517 +	//! Otherwise zero. This is used to check the consistency of the file.
  19.518 +	//! A warning is sent to the logger if the validations fails.
  19.519 +	//! \param mesh Mesh object to be filled
  19.520 +	void ParseLV3MeshCFaceListBlock(
  19.521 +		unsigned int iNumFaces, Mesh& mesh);
  19.522 +
  19.523 +	// -------------------------------------------------------------------
  19.524 +	//! Parse a *MESH_NORMALS block in a file
  19.525 +	//! \param mesh Mesh object to be filled
  19.526 +	void ParseLV3MeshNormalListBlock(Mesh& mesh);
  19.527 +
  19.528 +	// -------------------------------------------------------------------
  19.529 +	//! Parse a *MESH_WEIGHTSblock in a file
  19.530 +	//! \param mesh Mesh object to be filled
  19.531 +	void ParseLV3MeshWeightsBlock(Mesh& mesh);
  19.532 +
  19.533 +	// -------------------------------------------------------------------
  19.534 +	//! Parse the bone list of a file
  19.535 +	//! \param mesh Mesh object to be filled
  19.536 +	//! \param iNumBones Number of bones in the mesh
  19.537 +	void ParseLV4MeshBones(unsigned int iNumBones,Mesh& mesh);
  19.538 +
  19.539 +	// -------------------------------------------------------------------
  19.540 +	//! Parse the bone vertices list of a file
  19.541 +	//! \param mesh Mesh object to be filled
  19.542 +	//! \param iNumVertices Number of vertices to be parsed
  19.543 +	void ParseLV4MeshBonesVertices(unsigned int iNumVertices,Mesh& mesh);
  19.544 +
  19.545 +	// -------------------------------------------------------------------
  19.546 +	//! Parse a *MESH_FACE block in a file
  19.547 +	//! \param out receive the face data
  19.548 +	void ParseLV4MeshFace(ASE::Face& out);
  19.549 +
  19.550 +	// -------------------------------------------------------------------
  19.551 +	//! Parse a *MESH_VERT block in a file
  19.552 +	//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL  ...)
  19.553 +	//! \param apOut Output buffer (3 floats)
  19.554 +	//! \param rIndexOut Output index
  19.555 +	void ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut);
  19.556 +
  19.557 +	// -------------------------------------------------------------------
  19.558 +	//! Parse a *MESH_VERT block in a file
  19.559 +	//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL  ...)
  19.560 +	//! \param apOut Output buffer (3 floats)
  19.561 +	void ParseLV4MeshFloatTriple(float* apOut);
  19.562 +
  19.563 +	// -------------------------------------------------------------------
  19.564 +	//! Parse a *MESH_TFACE block in a file
  19.565 +	//! (also works for MESH_CFACE)
  19.566 +	//! \param apOut Output buffer (3 ints)
  19.567 +	//! \param rIndexOut Output index
  19.568 +	void ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut);
  19.569 +
  19.570 +	// -------------------------------------------------------------------
  19.571 +	//! Parse a *MESH_TFACE block in a file
  19.572 +	//! (also works for MESH_CFACE)
  19.573 +	//! \param apOut Output buffer (3 ints)
  19.574 +	void ParseLV4MeshLongTriple(unsigned int* apOut);
  19.575 +
  19.576 +	// -------------------------------------------------------------------
  19.577 +	//! Parse a single float element 
  19.578 +	//! \param fOut Output float
  19.579 +	void ParseLV4MeshFloat(float& fOut);
  19.580 +
  19.581 +	// -------------------------------------------------------------------
  19.582 +	//! Parse a single int element 
  19.583 +	//! \param iOut Output integer
  19.584 +	void ParseLV4MeshLong(unsigned int& iOut);
  19.585 +
  19.586 +	// -------------------------------------------------------------------
  19.587 +	//! Skip everything to the next: '*' or '\0'
  19.588 +	bool SkipToNextToken();
  19.589 +
  19.590 +	// -------------------------------------------------------------------
  19.591 +	//! Skip the current section until the token after the closing }.
  19.592 +	//! This function handles embedded subsections correctly
  19.593 +	bool SkipSection();
  19.594 +
  19.595 +	// -------------------------------------------------------------------
  19.596 +	//! Output a warning to the logger
  19.597 +	//! \param szWarn Warn message
  19.598 +	void LogWarning(const char* szWarn);
  19.599 +
  19.600 +	// -------------------------------------------------------------------
  19.601 +	//! Output a message to the logger
  19.602 +	//! \param szWarn Message
  19.603 +	void LogInfo(const char* szWarn);
  19.604 +
  19.605 +	// -------------------------------------------------------------------
  19.606 +	//! Output an error to the logger
  19.607 +	//! \param szWarn Error message
  19.608 +	void LogError(const char* szWarn);
  19.609 +
  19.610 +	// -------------------------------------------------------------------
  19.611 +	//! Parse a string, enclosed in double quotation marks
  19.612 +	//! \param out Output string
  19.613 +	//! \param szName Name of the enclosing element -> used in error
  19.614 +	//! messages.
  19.615 +	//! \return false if an error occured
  19.616 +	bool ParseString(std::string& out,const char* szName);
  19.617 +
  19.618 +public:
  19.619 +
  19.620 +	//! Pointer to current data
  19.621 +	const char* filePtr;
  19.622 +
  19.623 +	//! background color to be passed to the viewer
  19.624 +	//! QNAN if none was found
  19.625 +	aiColor3D m_clrBackground;
  19.626 +
  19.627 +	//! Base ambient color to be passed to all materials
  19.628 +	//! QNAN if none was found
  19.629 +	aiColor3D m_clrAmbient;
  19.630 +
  19.631 +	//! List of all materials found in the file
  19.632 +	std::vector<Material> m_vMaterials;
  19.633 +
  19.634 +	//! List of all meshes found in the file
  19.635 +	std::vector<Mesh> m_vMeshes;
  19.636 +
  19.637 +	//! List of all dummies found in the file
  19.638 +	std::vector<Dummy> m_vDummies;
  19.639 +
  19.640 +	//! List of all lights found in the file
  19.641 +	std::vector<Light> m_vLights;
  19.642 +
  19.643 +	//! List of all cameras found in the file
  19.644 +	std::vector<Camera> m_vCameras;
  19.645 +
  19.646 +	//! Current line in the file
  19.647 +	unsigned int iLineNumber;
  19.648 +
  19.649 +	//! First frame
  19.650 +	unsigned int iFirstFrame;
  19.651 +
  19.652 +	//! Last frame
  19.653 +	unsigned int iLastFrame;
  19.654 +
  19.655 +	//! Frame speed - frames per second
  19.656 +	unsigned int iFrameSpeed;
  19.657 +
  19.658 +	//! Ticks per frame
  19.659 +	unsigned int iTicksPerFrame;
  19.660 +
  19.661 +	//! true if the last character read was an end-line character
  19.662 +	bool bLastWasEndLine;
  19.663 +
  19.664 +	//! File format version
  19.665 +	unsigned int iFileFormat;
  19.666 +};
  19.667 +
  19.668 +
  19.669 +} // Namespace ASE
  19.670 +} // Namespace ASSIMP
  19.671 +
  19.672 +#endif // !! include guard
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/libs/assimp/Assimp.cpp	Sat Feb 01 19:58:19 2014 +0200
    20.3 @@ -0,0 +1,593 @@
    20.4 +/*
    20.5 +---------------------------------------------------------------------------
    20.6 +Open Asset Import Library (assimp)
    20.7 +---------------------------------------------------------------------------
    20.8 +
    20.9 +Copyright (c) 2006-2012, assimp team
   20.10 +
   20.11 +All rights reserved.
   20.12 +
   20.13 +Redistribution and use of this software in source and binary forms, 
   20.14 +with or without modification, are permitted provided that the following 
   20.15 +conditions are met:
   20.16 +
   20.17 +* Redistributions of source code must retain the above
   20.18 +  copyright notice, this list of conditions and the
   20.19 +  following disclaimer.
   20.20 +
   20.21 +* Redistributions in binary form must reproduce the above
   20.22 +  copyright notice, this list of conditions and the
   20.23 +  following disclaimer in the documentation and/or other
   20.24 +  materials provided with the distribution.
   20.25 +
   20.26 +* Neither the name of the assimp team, nor the names of its
   20.27 +  contributors may be used to endorse or promote products
   20.28 +  derived from this software without specific prior
   20.29 +  written permission of the assimp team.
   20.30 +
   20.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   20.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   20.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   20.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   20.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   20.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   20.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   20.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   20.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   20.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   20.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   20.42 +---------------------------------------------------------------------------
   20.43 +*/
   20.44 +/** @file  Assimp.cpp
   20.45 + *  @brief Implementation of the Plain-C API
   20.46 + */
   20.47 +
   20.48 +#include "AssimpPCH.h"
   20.49 +#include "assimp/cimport.h"
   20.50 +
   20.51 +#include "GenericProperty.h"
   20.52 +#include "CInterfaceIOWrapper.h"
   20.53 +#include "Importer.h"
   20.54 +
   20.55 +// ------------------------------------------------------------------------------------------------
   20.56 +#ifdef AI_C_THREADSAFE
   20.57 +#	include <boost/thread/thread.hpp>
   20.58 +#	include <boost/thread/mutex.hpp>
   20.59 +#endif
   20.60 +// ------------------------------------------------------------------------------------------------
   20.61 +using namespace Assimp;
   20.62 +
   20.63 +namespace Assimp
   20.64 +{
   20.65 +	// underlying structure for aiPropertyStore
   20.66 +	typedef BatchLoader::PropertyMap PropertyMap;
   20.67 +
   20.68 +	/** Stores the LogStream objects for all active C log streams */
   20.69 +	struct mpred {
   20.70 +		bool operator  () (const aiLogStream& s0, const aiLogStream& s1) const  {
   20.71 +			return s0.callback<s1.callback&&s0.user<s1.user;
   20.72 +		}
   20.73 +	};
   20.74 +	typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap;
   20.75 +
   20.76 +	/** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */
   20.77 +	typedef std::list<Assimp::LogStream*> PredefLogStreamMap;
   20.78 +
   20.79 +	/** Local storage of all active log streams */
   20.80 +	static LogStreamMap gActiveLogStreams;
   20.81 +
   20.82 +	/** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */
   20.83 +	static PredefLogStreamMap gPredefinedStreams;
   20.84 +
   20.85 +	/** Error message of the last failed import process */
   20.86 +	static std::string gLastErrorString;
   20.87 +
   20.88 +	/** Verbose logging active or not? */
   20.89 +	static aiBool gVerboseLogging = false;
   20.90 +}
   20.91 +
   20.92 +
   20.93 +#ifdef AI_C_THREADSAFE
   20.94 +/** Global mutex to manage the access to the logstream map */
   20.95 +static boost::mutex gLogStreamMutex;
   20.96 +#endif
   20.97 +
   20.98 +
   20.99 +// ------------------------------------------------------------------------------------------------
  20.100 +// Custom LogStream implementation for the C-API
  20.101 +class LogToCallbackRedirector : public LogStream
  20.102 +{
  20.103 +public:
  20.104 +	LogToCallbackRedirector(const aiLogStream& s) 
  20.105 +		: stream (s)	{
  20.106 +			ai_assert(NULL != s.callback);
  20.107 +	}
  20.108 +
  20.109 +	~LogToCallbackRedirector()	{
  20.110 +#ifdef AI_C_THREADSAFE
  20.111 +		boost::mutex::scoped_lock lock(gLogStreamMutex);
  20.112 +#endif
  20.113 +		// (HACK) Check whether the 'stream.user' pointer points to a
  20.114 +		// custom LogStream allocated by #aiGetPredefinedLogStream.
  20.115 +		// In this case, we need to delete it, too. Of course, this 
  20.116 +		// might cause strange problems, but the chance is quite low.
  20.117 +
  20.118 +		PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(), 
  20.119 +			gPredefinedStreams.end(), (Assimp::LogStream*)stream.user);
  20.120 +
  20.121 +		if (it != gPredefinedStreams.end()) {
  20.122 +			delete *it;
  20.123 +			gPredefinedStreams.erase(it);
  20.124 +		}
  20.125 +	}
  20.126 +
  20.127 +	/** @copydoc LogStream::write */
  20.128 +	void write(const char* message)	{
  20.129 +		stream.callback(message,stream.user);
  20.130 +	}
  20.131 +
  20.132 +private:
  20.133 +	aiLogStream stream;
  20.134 +};
  20.135 +
  20.136 +// ------------------------------------------------------------------------------------------------
  20.137 +void ReportSceneNotFoundError()
  20.138 +{
  20.139 +	DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
  20.140 +		"The C-API does not accept scenes produced by the C++ API and vice versa");
  20.141 +
  20.142 +	assert(false);
  20.143 +}
  20.144 +
  20.145 +// ------------------------------------------------------------------------------------------------
  20.146 +// Reads the given file and returns its content. 
  20.147 +const aiScene* aiImportFile( const char* pFile, unsigned int pFlags)
  20.148 +{
  20.149 +	return aiImportFileEx(pFile,pFlags,NULL);
  20.150 +}
  20.151 +
  20.152 +// ------------------------------------------------------------------------------------------------
  20.153 +const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags,  aiFileIO* pFS)
  20.154 +{
  20.155 +	return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL);
  20.156 +}
  20.157 +
  20.158 +// ------------------------------------------------------------------------------------------------
  20.159 +const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags, 
  20.160 +	aiFileIO* pFS,
  20.161 +	const aiPropertyStore* props)
  20.162 +{
  20.163 +	ai_assert(NULL != pFile);
  20.164 +
  20.165 +	const aiScene* scene = NULL;
  20.166 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.167 +
  20.168 +	// create an Importer for this file
  20.169 +	Assimp::Importer* imp = new Assimp::Importer();
  20.170 +
  20.171 +	// copy properties
  20.172 +	if(props) {
  20.173 +		const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
  20.174 +		ImporterPimpl* pimpl = imp->Pimpl();
  20.175 +		pimpl->mIntProperties = pp->ints;
  20.176 +		pimpl->mFloatProperties = pp->floats;
  20.177 +		pimpl->mStringProperties = pp->strings;
  20.178 +	}
  20.179 +	// setup a custom IO system if necessary
  20.180 +	if (pFS)	{
  20.181 +		imp->SetIOHandler( new CIOSystemWrapper (pFS) );
  20.182 +	}
  20.183 +
  20.184 +	// and have it read the file
  20.185 +	scene = imp->ReadFile( pFile, pFlags);
  20.186 +
  20.187 +	// if succeeded, store the importer in the scene and keep it alive
  20.188 +	if( scene)	{
  20.189 +		ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
  20.190 +		priv->mOrigImporter = imp;
  20.191 +	} 
  20.192 +	else	{
  20.193 +		// if failed, extract error code and destroy the import
  20.194 +		gLastErrorString = imp->GetErrorString();
  20.195 +		delete imp;
  20.196 +	}
  20.197 +
  20.198 +	// return imported data. If the import failed the pointer is NULL anyways
  20.199 +	ASSIMP_END_EXCEPTION_REGION(const aiScene*);
  20.200 +	return scene;
  20.201 +}
  20.202 +
  20.203 +// ------------------------------------------------------------------------------------------------
  20.204 +const aiScene* aiImportFileFromMemory( 
  20.205 +	const char* pBuffer,
  20.206 +	unsigned int pLength,
  20.207 +	unsigned int pFlags,
  20.208 +	const char* pHint)
  20.209 +{
  20.210 +	return aiImportFileFromMemoryWithProperties(pBuffer, pLength, pFlags, pHint, NULL);
  20.211 +}
  20.212 +
  20.213 +// ------------------------------------------------------------------------------------------------
  20.214 +const aiScene* aiImportFileFromMemoryWithProperties( 
  20.215 +	const char* pBuffer,
  20.216 +	unsigned int pLength,
  20.217 +	unsigned int pFlags,
  20.218 +	const char* pHint,
  20.219 +	const aiPropertyStore* props)
  20.220 +{
  20.221 +	ai_assert(NULL != pBuffer && 0 != pLength);
  20.222 +
  20.223 +	const aiScene* scene = NULL;
  20.224 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.225 +
  20.226 +	// create an Importer for this file
  20.227 +	Assimp::Importer* imp = new Assimp::Importer();
  20.228 +
  20.229 +	// copy properties
  20.230 +	if(props) {
  20.231 +		const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
  20.232 +		ImporterPimpl* pimpl = imp->Pimpl();
  20.233 +		pimpl->mIntProperties = pp->ints;
  20.234 +		pimpl->mFloatProperties = pp->floats;
  20.235 +		pimpl->mStringProperties = pp->strings;
  20.236 +	}
  20.237 +
  20.238 +	// and have it read the file from the memory buffer
  20.239 +	scene = imp->ReadFileFromMemory( pBuffer, pLength, pFlags,pHint);
  20.240 +
  20.241 +	// if succeeded, store the importer in the scene and keep it alive
  20.242 +	if( scene)	{
  20.243 +		 ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
  20.244 +		 priv->mOrigImporter = imp;
  20.245 +	} 
  20.246 +	else	{
  20.247 +		// if failed, extract error code and destroy the import
  20.248 +		gLastErrorString = imp->GetErrorString();
  20.249 +		delete imp;
  20.250 +	}
  20.251 +	// return imported data. If the import failed the pointer is NULL anyways
  20.252 +	ASSIMP_END_EXCEPTION_REGION(const aiScene*);
  20.253 +	return scene;
  20.254 +}
  20.255 +
  20.256 +// ------------------------------------------------------------------------------------------------
  20.257 +// Releases all resources associated with the given import process. 
  20.258 +void aiReleaseImport( const aiScene* pScene)
  20.259 +{
  20.260 +	if (!pScene) {
  20.261 +		return;
  20.262 +	}
  20.263 +
  20.264 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.265 +	
  20.266 +	// find the importer associated with this data
  20.267 +	const ScenePrivateData* priv = ScenePriv(pScene);
  20.268 +	if( !priv || !priv->mOrigImporter)	{
  20.269 +		delete pScene;
  20.270 +	}
  20.271 +	else {
  20.272 +		// deleting the Importer also deletes the scene
  20.273 +		// Note: the reason that this is not written as 'delete priv->mOrigImporter'
  20.274 +		// is a suspected bug in gcc 4.4+ (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52339)
  20.275 +		Importer* importer = priv->mOrigImporter;
  20.276 +		delete importer;
  20.277 +	}
  20.278 +	
  20.279 +	ASSIMP_END_EXCEPTION_REGION(void);
  20.280 +}
  20.281 +
  20.282 +// ------------------------------------------------------------------------------------------------
  20.283 +ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
  20.284 +	unsigned int pFlags)
  20.285 +{
  20.286 +	const aiScene* sc = NULL;
  20.287 +	
  20.288 +
  20.289 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.290 +
  20.291 +	// find the importer associated with this data
  20.292 +	const ScenePrivateData* priv = ScenePriv(pScene);
  20.293 +	if( !priv || !priv->mOrigImporter)	{
  20.294 +		ReportSceneNotFoundError();
  20.295 +		return NULL;
  20.296 +	}
  20.297 +
  20.298 +	sc = priv->mOrigImporter->ApplyPostProcessing(pFlags);
  20.299 +
  20.300 +	if (!sc) {
  20.301 +		aiReleaseImport(pScene);
  20.302 +		return NULL;
  20.303 +	}
  20.304 +
  20.305 +	ASSIMP_END_EXCEPTION_REGION(const aiScene*);
  20.306 +	return sc;
  20.307 +}
  20.308 +
  20.309 +// ------------------------------------------------------------------------------------------------
  20.310 +void CallbackToLogRedirector (const char* msg, char* dt)
  20.311 +{
  20.312 +	ai_assert(NULL != msg && NULL != dt);
  20.313 +	LogStream* s = (LogStream*)dt;
  20.314 +
  20.315 +	s->write(msg);
  20.316 +}
  20.317 +
  20.318 +// ------------------------------------------------------------------------------------------------
  20.319 +ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file)
  20.320 +{
  20.321 +	aiLogStream sout;
  20.322 +
  20.323 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.324 +	LogStream* stream = LogStream::createDefaultStream(pStream,file);
  20.325 +	if (!stream) {
  20.326 +		sout.callback = NULL;
  20.327 +		sout.user = NULL;
  20.328 +	}
  20.329 +	else {
  20.330 +		sout.callback = &CallbackToLogRedirector;
  20.331 +		sout.user = (char*)stream;
  20.332 +	}
  20.333 +	gPredefinedStreams.push_back(stream);
  20.334 +	ASSIMP_END_EXCEPTION_REGION(aiLogStream);
  20.335 +	return sout;
  20.336 +}
  20.337 +
  20.338 +// ------------------------------------------------------------------------------------------------
  20.339 +ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
  20.340 +{
  20.341 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.342 +
  20.343 +#ifdef AI_C_THREADSAFE
  20.344 +	boost::mutex::scoped_lock lock(gLogStreamMutex);
  20.345 +#endif
  20.346 +
  20.347 +	LogStream* lg = new LogToCallbackRedirector(*stream);
  20.348 +	gActiveLogStreams[*stream] = lg;
  20.349 +
  20.350 +	if (DefaultLogger::isNullLogger()) {
  20.351 +		DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
  20.352 +	}
  20.353 +	DefaultLogger::get()->attachStream(lg);
  20.354 +	ASSIMP_END_EXCEPTION_REGION(void);
  20.355 +}
  20.356 +
  20.357 +// ------------------------------------------------------------------------------------------------
  20.358 +ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
  20.359 +{
  20.360 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.361 +
  20.362 +#ifdef AI_C_THREADSAFE
  20.363 +	boost::mutex::scoped_lock lock(gLogStreamMutex);
  20.364 +#endif
  20.365 +	// find the logstream associated with this data
  20.366 +	LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
  20.367 +	// it should be there... else the user is playing fools with us
  20.368 +	if( it == gActiveLogStreams.end())	{
  20.369 +		return AI_FAILURE;
  20.370 +	}
  20.371 +	DefaultLogger::get()->detatchStream( it->second );
  20.372 +	delete it->second;
  20.373 +
  20.374 +	gActiveLogStreams.erase( it);
  20.375 +
  20.376 +	if (gActiveLogStreams.empty()) {
  20.377 +		DefaultLogger::kill();
  20.378 +	}
  20.379 +	ASSIMP_END_EXCEPTION_REGION(aiReturn);
  20.380 +	return AI_SUCCESS;
  20.381 +}
  20.382 +
  20.383 +// ------------------------------------------------------------------------------------------------
  20.384 +ASSIMP_API void aiDetachAllLogStreams(void)
  20.385 +{
  20.386 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.387 +#ifdef AI_C_THREADSAFE
  20.388 +	boost::mutex::scoped_lock lock(gLogStreamMutex);
  20.389 +#endif
  20.390 +	for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
  20.391 +		DefaultLogger::get()->detatchStream( it->second );
  20.392 +		delete it->second;
  20.393 +	}
  20.394 +	gActiveLogStreams.clear();
  20.395 +	DefaultLogger::kill();
  20.396 +	ASSIMP_END_EXCEPTION_REGION(void);
  20.397 +}
  20.398 +
  20.399 +// ------------------------------------------------------------------------------------------------
  20.400 +ASSIMP_API void aiEnableVerboseLogging(aiBool d)
  20.401 +{
  20.402 +	if (!DefaultLogger::isNullLogger()) {
  20.403 +		DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
  20.404 +	}
  20.405 +	gVerboseLogging = d;
  20.406 +}
  20.407 +
  20.408 +// ------------------------------------------------------------------------------------------------
  20.409 +// Returns the error text of the last failed import process. 
  20.410 +const char* aiGetErrorString()
  20.411 +{
  20.412 +	return gLastErrorString.c_str();
  20.413 +}
  20.414 +
  20.415 +// ------------------------------------------------------------------------------------------------
  20.416 +// Returns the error text of the last failed import process. 
  20.417 +aiBool aiIsExtensionSupported(const char* szExtension)
  20.418 +{
  20.419 +	ai_assert(NULL != szExtension);
  20.420 +	aiBool candoit=AI_FALSE;
  20.421 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.422 +
  20.423 +	// FIXME: no need to create a temporary Importer instance just for that .. 
  20.424 +	Assimp::Importer tmp;
  20.425 +	candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE;
  20.426 +
  20.427 +	ASSIMP_END_EXCEPTION_REGION(aiBool);
  20.428 +	return candoit;
  20.429 +}
  20.430 +
  20.431 +// ------------------------------------------------------------------------------------------------
  20.432 +// Get a list of all file extensions supported by ASSIMP
  20.433 +void aiGetExtensionList(aiString* szOut)
  20.434 +{
  20.435 +	ai_assert(NULL != szOut);
  20.436 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.437 +
  20.438 +	// FIXME: no need to create a temporary Importer instance just for that .. 
  20.439 +	Assimp::Importer tmp;
  20.440 +	tmp.GetExtensionList(*szOut);
  20.441 +
  20.442 +	ASSIMP_END_EXCEPTION_REGION(void);
  20.443 +}
  20.444 +
  20.445 +// ------------------------------------------------------------------------------------------------
  20.446 +// Get the memory requirements for a particular import.
  20.447 +void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
  20.448 +	C_STRUCT aiMemoryInfo* in)
  20.449 +{
  20.450 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.451 +
  20.452 +	// find the importer associated with this data
  20.453 +	const ScenePrivateData* priv = ScenePriv(pIn);
  20.454 +	if( !priv || !priv->mOrigImporter)	{
  20.455 +		ReportSceneNotFoundError();
  20.456 +		return;
  20.457 +	}
  20.458 +
  20.459 +	return priv->mOrigImporter->GetMemoryRequirements(*in);
  20.460 +	ASSIMP_END_EXCEPTION_REGION(void);
  20.461 +}
  20.462 +
  20.463 +// ------------------------------------------------------------------------------------------------
  20.464 +ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void)
  20.465 +{
  20.466 +	return reinterpret_cast<aiPropertyStore*>( new PropertyMap() );
  20.467 +}
  20.468 +
  20.469 +
  20.470 +// ------------------------------------------------------------------------------------------------
  20.471 +ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p)
  20.472 +{
  20.473 +	delete reinterpret_cast<PropertyMap*>(p);
  20.474 +}
  20.475 +
  20.476 +// ------------------------------------------------------------------------------------------------
  20.477 +// Importer::SetPropertyInteger
  20.478 +ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore* p, const char* szName, int value)
  20.479 +{
  20.480 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.481 +	PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
  20.482 +	SetGenericProperty<int>(pp->ints,szName,value,NULL);
  20.483 +	ASSIMP_END_EXCEPTION_REGION(void);
  20.484 +}
  20.485 +
  20.486 +// ------------------------------------------------------------------------------------------------
  20.487 +// Importer::SetPropertyFloat
  20.488 +ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, float value)
  20.489 +{
  20.490 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.491 +	PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
  20.492 +	SetGenericProperty<float>(pp->floats,szName,value,NULL);
  20.493 +	ASSIMP_END_EXCEPTION_REGION(void);
  20.494 +}
  20.495 +
  20.496 +// ------------------------------------------------------------------------------------------------
  20.497 +// Importer::SetPropertyString
  20.498 +ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName,
  20.499 +	const C_STRUCT aiString* st)
  20.500 +{
  20.501 +	if (!st) {
  20.502 +		return;
  20.503 +	}
  20.504 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  20.505 +	PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
  20.506 +	SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str()),NULL);
  20.507 +	ASSIMP_END_EXCEPTION_REGION(void);
  20.508 +}
  20.509 +
  20.510 +// ------------------------------------------------------------------------------------------------
  20.511 +// Rotation matrix to quaternion
  20.512 +ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
  20.513 +{
  20.514 +	ai_assert(NULL != quat && NULL != mat);
  20.515 +	*quat = aiQuaternion(*mat);
  20.516 +}
  20.517 +
  20.518 +// ------------------------------------------------------------------------------------------------
  20.519 +// Matrix decomposition
  20.520 +ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
  20.521 +	aiQuaternion* rotation,
  20.522 +	aiVector3D* position)
  20.523 +{
  20.524 +	ai_assert(NULL != rotation && NULL != position && NULL != scaling && NULL != mat);
  20.525 +	mat->Decompose(*scaling,*rotation,*position);
  20.526 +}
  20.527 +
  20.528 +// ------------------------------------------------------------------------------------------------
  20.529 +// Matrix transpose
  20.530 +ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3* mat)
  20.531 +{
  20.532 +	ai_assert(NULL != mat);
  20.533 +	mat->Transpose();
  20.534 +}
  20.535 +
  20.536 +// ------------------------------------------------------------------------------------------------
  20.537 +ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat)
  20.538 +{
  20.539 +	ai_assert(NULL != mat);
  20.540 +	mat->Transpose();
  20.541 +}
  20.542 +
  20.543 +// ------------------------------------------------------------------------------------------------
  20.544 +// Vector transformation
  20.545 +ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec, 
  20.546 +	const aiMatrix3x3* mat)
  20.547 +{
  20.548 +	ai_assert(NULL != mat && NULL != vec);
  20.549 +	*vec *= (*mat);
  20.550 +}
  20.551 +
  20.552 +// ------------------------------------------------------------------------------------------------
  20.553 +ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec, 
  20.554 +	const aiMatrix4x4* mat)
  20.555 +{
  20.556 +	ai_assert(NULL != mat && NULL != vec);
  20.557 +	*vec *= (*mat);
  20.558 +}
  20.559 +
  20.560 +// ------------------------------------------------------------------------------------------------
  20.561 +// Matrix multiplication
  20.562 +ASSIMP_API void aiMultiplyMatrix4(
  20.563 +	aiMatrix4x4* dst, 
  20.564 +	const aiMatrix4x4* src)
  20.565 +{
  20.566 +	ai_assert(NULL != dst && NULL != src);
  20.567 +	*dst = (*dst) * (*src);
  20.568 +}
  20.569 +
  20.570 +// ------------------------------------------------------------------------------------------------
  20.571 +ASSIMP_API void aiMultiplyMatrix3(
  20.572 +	aiMatrix3x3* dst, 
  20.573 +	const aiMatrix3x3* src)
  20.574 +{
  20.575 +	ai_assert(NULL != dst && NULL != src);
  20.576 +	*dst = (*dst) * (*src);
  20.577 +}
  20.578 +
  20.579 +// ------------------------------------------------------------------------------------------------
  20.580 +// Matrix identity
  20.581 +ASSIMP_API void aiIdentityMatrix3(
  20.582 +	aiMatrix3x3* mat)
  20.583 +{
  20.584 +	ai_assert(NULL != mat);
  20.585 +	*mat = aiMatrix3x3();
  20.586 +}
  20.587 +
  20.588 +// ------------------------------------------------------------------------------------------------
  20.589 +ASSIMP_API void aiIdentityMatrix4(
  20.590 +	aiMatrix4x4* mat)
  20.591 +{
  20.592 +	ai_assert(NULL != mat);
  20.593 +	*mat = aiMatrix4x4();
  20.594 +}
  20.595 +
  20.596 +
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/libs/assimp/AssimpCExport.cpp	Sat Feb 01 19:58:19 2014 +0200
    21.3 @@ -0,0 +1,115 @@
    21.4 +/*
    21.5 +---------------------------------------------------------------------------
    21.6 +Open Asset Import Library (assimp)
    21.7 +---------------------------------------------------------------------------
    21.8 +
    21.9 +Copyright (c) 2006-2012, assimp team
   21.10 +
   21.11 +All rights reserved.
   21.12 +
   21.13 +Redistribution and use of this software in source and binary forms, 
   21.14 +with or without modification, are permitted provided that the following 
   21.15 +conditions are met:
   21.16 +
   21.17 +* Redistributions of source code must retain the above
   21.18 +  copyright notice, this list of conditions and the
   21.19 +  following disclaimer.
   21.20 +
   21.21 +* Redistributions in binary form must reproduce the above
   21.22 +  copyright notice, this list of conditions and the
   21.23 +  following disclaimer in the documentation and/or other
   21.24 +  materials provided with the distribution.
   21.25 +
   21.26 +* Neither the name of the assimp team, nor the names of its
   21.27 +  contributors may be used to endorse or promote products
   21.28 +  derived from this software without specific prior
   21.29 +  written permission of the assimp team.
   21.30 +
   21.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   21.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   21.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   21.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   21.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   21.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   21.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   21.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   21.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   21.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   21.42 +---------------------------------------------------------------------------
   21.43 +*/
   21.44 +
   21.45 +/** @file AssimpCExport.cpp
   21.46 +Assimp C export interface. See Exporter.cpp for some notes.
   21.47 +*/
   21.48 +
   21.49 +#include "AssimpPCH.h"
   21.50 +
   21.51 +#ifndef ASSIMP_BUILD_NO_EXPORT
   21.52 +#include "CInterfaceIOWrapper.h" 
   21.53 +#include "SceneCombiner.h"
   21.54 +
   21.55 +using namespace Assimp;
   21.56 +
   21.57 +// ------------------------------------------------------------------------------------------------
   21.58 +ASSIMP_API size_t aiGetExportFormatCount(void)
   21.59 +{
   21.60 +	return Exporter().GetExportFormatCount();
   21.61 +}
   21.62 +
   21.63 +
   21.64 +// ------------------------------------------------------------------------------------------------
   21.65 +ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex)
   21.66 +{
   21.67 +	return Exporter().GetExportFormatDescription(pIndex);
   21.68 +}
   21.69 +
   21.70 +// ------------------------------------------------------------------------------------------------
   21.71 +ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
   21.72 +{
   21.73 +	if (!pOut || !pIn) {
   21.74 +		return;
   21.75 +	}
   21.76 +
   21.77 +	SceneCombiner::CopyScene(pOut,pIn,true);
   21.78 +}
   21.79 +
   21.80 +// ------------------------------------------------------------------------------------------------
   21.81 +ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing )
   21.82 +{
   21.83 +	return ::aiExportSceneEx(pScene,pFormatId,pFileName,NULL,pPreprocessing);
   21.84 +}
   21.85 +
   21.86 +
   21.87 +// ------------------------------------------------------------------------------------------------
   21.88 +ASSIMP_API aiReturn aiExportSceneEx( const aiScene* pScene, const char* pFormatId, const char* pFileName, aiFileIO* pIO, unsigned int pPreprocessing )
   21.89 +{
   21.90 +	Exporter exp;
   21.91 +
   21.92 +	if (pIO) {
   21.93 +		exp.SetIOHandler(new CIOSystemWrapper(pIO));
   21.94 +	}
   21.95 +	return exp.Export(pScene,pFormatId,pFileName,pPreprocessing);
   21.96 +}
   21.97 +
   21.98 +
   21.99 +// ------------------------------------------------------------------------------------------------
  21.100 +ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing  )
  21.101 +{
  21.102 +	Exporter exp;
  21.103 +	if (!exp.ExportToBlob(pScene,pFormatId,pPreprocessing)) {
  21.104 +		return NULL;
  21.105 +	}
  21.106 +	const aiExportDataBlob* blob = exp.GetOrphanedBlob();
  21.107 +	ai_assert(blob);
  21.108 +
  21.109 +	return blob;
  21.110 +}
  21.111 +
  21.112 +// ------------------------------------------------------------------------------------------------
  21.113 +ASSIMP_API C_STRUCT void aiReleaseExportBlob( const aiExportDataBlob* pData )
  21.114 +{
  21.115 +	delete pData;
  21.116 +}
  21.117 +
  21.118 +#endif // !ASSIMP_BUILD_NO_EXPORT
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/libs/assimp/AssimpPCH.cpp	Sat Feb 01 19:58:19 2014 +0200
    22.3 @@ -0,0 +1,132 @@
    22.4 +
    22.5 +// Actually just a dummy, used by the compiler to build the precompiled header.
    22.6 +
    22.7 +#include "AssimpPCH.h"
    22.8 +#include "assimp/version.h"
    22.9 +
   22.10 +// --------------------------------------------------------------------------------
   22.11 +// Legal information string - dont't remove this.
   22.12 +static const char* LEGAL_INFORMATION =
   22.13 +
   22.14 +"Open Asset Import Library (Assimp).\n"
   22.15 +"A free C/C++ library to import various 3D file formats into applications\n\n"
   22.16 +
   22.17 +"(c) 2008-2010, assimp team\n"
   22.18 +"License under the terms and conditions of the 3-clause BSD license\n"
   22.19 +"http://assimp.sourceforge.net\n"
   22.20 +;
   22.21 +
   22.22 +// ------------------------------------------------------------------------------------------------
   22.23 +// Get legal string
   22.24 +ASSIMP_API const char*  aiGetLegalString  ()	{
   22.25 +	return LEGAL_INFORMATION;
   22.26 +}
   22.27 +
   22.28 +// ------------------------------------------------------------------------------------------------
   22.29 +// Get Assimp minor version
   22.30 +ASSIMP_API unsigned int aiGetVersionMinor ()	{
   22.31 +	return 0;
   22.32 +}
   22.33 +
   22.34 +// ------------------------------------------------------------------------------------------------
   22.35 +// Get Assimp major version
   22.36 +ASSIMP_API unsigned int aiGetVersionMajor ()	{
   22.37 +	return 3;
   22.38 +}
   22.39 +
   22.40 +// ------------------------------------------------------------------------------------------------
   22.41 +// Get flags used for compilation
   22.42 +ASSIMP_API unsigned int aiGetCompileFlags ()	{
   22.43 +
   22.44 +	unsigned int flags = 0;
   22.45 +
   22.46 +#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
   22.47 +	flags |= ASSIMP_CFLAGS_NOBOOST;
   22.48 +#endif
   22.49 +#ifdef ASSIMP_BUILD_SINGLETHREADED
   22.50 +	flags |= ASSIMP_CFLAGS_SINGLETHREADED;
   22.51 +#endif
   22.52 +#ifdef ASSIMP_BUILD_DEBUG
   22.53 +	flags |= ASSIMP_CFLAGS_DEBUG;
   22.54 +#endif
   22.55 +#ifdef ASSIMP_BUILD_DLL_EXPORT
   22.56 +	flags |= ASSIMP_CFLAGS_SHARED;
   22.57 +#endif
   22.58 +#ifdef _STLPORT_VERSION
   22.59 +	flags |= ASSIMP_CFLAGS_STLPORT;
   22.60 +#endif
   22.61 +
   22.62 +	return flags;
   22.63 +}
   22.64 +
   22.65 +// include current build revision, which is even updated from time to time -- :-)
   22.66 +#include "revision.h"
   22.67 +
   22.68 +// ------------------------------------------------------------------------------------------------
   22.69 +ASSIMP_API unsigned int aiGetVersionRevision ()
   22.70 +{
   22.71 +	return SVNRevision;
   22.72 +}
   22.73 +
   22.74 +// ------------------------------------------------------------------------------------------------
   22.75 +aiScene::aiScene()
   22.76 +	: mFlags()
   22.77 +	, mRootNode()
   22.78 +	, mNumMeshes()
   22.79 +	, mMeshes()
   22.80 +	, mNumMaterials()
   22.81 +	, mMaterials()
   22.82 +	, mNumAnimations()
   22.83 +	, mAnimations()
   22.84 +	, mNumTextures()
   22.85 +	, mTextures()
   22.86 +	, mNumLights()
   22.87 +	, mLights()
   22.88 +	, mNumCameras()
   22.89 +	, mCameras()
   22.90 +	, mPrivate(new Assimp::ScenePrivateData())
   22.91 +	{
   22.92 +	}
   22.93 +
   22.94 +// ------------------------------------------------------------------------------------------------
   22.95 +aiScene::~aiScene()
   22.96 +{
   22.97 +	// delete all sub-objects recursively
   22.98 +	delete mRootNode;
   22.99 +
  22.100 +	// To make sure we won't crash if the data is invalid it's
  22.101 +	// much better to check whether both mNumXXX and mXXX are
  22.102 +	// valid instead of relying on just one of them.
  22.103 +	if (mNumMeshes && mMeshes) 
  22.104 +		for( unsigned int a = 0; a < mNumMeshes; a++)
  22.105 +			delete mMeshes[a];
  22.106 +	delete [] mMeshes;
  22.107 +
  22.108 +	if (mNumMaterials && mMaterials) 
  22.109 +		for( unsigned int a = 0; a < mNumMaterials; a++)
  22.110 +			delete mMaterials[a];
  22.111 +	delete [] mMaterials;
  22.112 +
  22.113 +	if (mNumAnimations && mAnimations) 
  22.114 +		for( unsigned int a = 0; a < mNumAnimations; a++)
  22.115 +			delete mAnimations[a];
  22.116 +	delete [] mAnimations;
  22.117 +
  22.118 +	if (mNumTextures && mTextures) 
  22.119 +		for( unsigned int a = 0; a < mNumTextures; a++)
  22.120 +			delete mTextures[a];
  22.121 +	delete [] mTextures;
  22.122 +
  22.123 +	if (mNumLights && mLights) 
  22.124 +		for( unsigned int a = 0; a < mNumLights; a++)
  22.125 +			delete mLights[a];
  22.126 +	delete [] mLights;
  22.127 +
  22.128 +	if (mNumCameras && mCameras) 
  22.129 +		for( unsigned int a = 0; a < mNumCameras; a++)
  22.130 +			delete mCameras[a];
  22.131 +	delete [] mCameras;
  22.132 +
  22.133 +	delete static_cast<Assimp::ScenePrivateData*>( mPrivate );
  22.134 +}
  22.135 +
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/libs/assimp/AssimpPCH.h	Sat Feb 01 19:58:19 2014 +0200
    23.3 @@ -0,0 +1,162 @@
    23.4 +/*
    23.5 +---------------------------------------------------------------------------
    23.6 +Open Asset Import Library (assimp)
    23.7 +---------------------------------------------------------------------------
    23.8 +
    23.9 +Copyright (c) 2006-2012, assimp team
   23.10 +
   23.11 +All rights reserved.
   23.12 +
   23.13 +Redistribution and use of this software in source and binary forms, 
   23.14 +with or without modification, are permitted provided that the following 
   23.15 +conditions are met:
   23.16 +
   23.17 +* Redistributions of source code must retain the above
   23.18 +  copyright notice, this list of conditions and the
   23.19 +  following disclaimer.
   23.20 +
   23.21 +* Redistributions in binary form must reproduce the above
   23.22 +  copyright notice, this list of conditions and the
   23.23 +  following disclaimer in the documentation and/or other
   23.24 +  materials provided with the distribution.
   23.25 +
   23.26 +* Neither the name of the assimp team, nor the names of its
   23.27 +  contributors may be used to endorse or promote products
   23.28 +  derived from this software without specific prior
   23.29 +  written permission of the assimp team.
   23.30 +
   23.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   23.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   23.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   23.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   23.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   23.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   23.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   23.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   23.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   23.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   23.42 +---------------------------------------------------------------------------
   23.43 +*/
   23.44 +
   23.45 +/** @file AssimpPCH.h
   23.46 + *  PCH master include. Every unit in Assimp has to include it.
   23.47 + */
   23.48 +
   23.49 +#ifndef ASSIMP_PCH_INCLUDED
   23.50 +#define ASSIMP_PCH_INCLUDED
   23.51 +#define ASSIMP_INTERNAL_BUILD
   23.52 +
   23.53 +// ----------------------------------------------------------------------------------------
   23.54 +/* General compile config taken from defs.h. It is important that the user compiles
   23.55 + * using exactly the same settings in defs.h. Settings in AssimpPCH.h may differ,
   23.56 + * they won't affect the public API.
   23.57 + */
   23.58 +#include "assimp/defs.h"
   23.59 +
   23.60 +// Include our stdint.h replacement header for MSVC, take the global header for gcc/mingw
   23.61 +#if defined( _MSC_VER) && (_MSC_VER < 1600)
   23.62 +#	include "pstdint.h"
   23.63 +#else
   23.64 +#	include <stdint.h>
   23.65 +#endif
   23.66 +
   23.67 +/* Undefine the min/max macros defined by some platform headers (namely Windows.h) to 
   23.68 + * avoid obvious conflicts with std::min() and std::max(). 
   23.69 + */
   23.70 +#undef min
   23.71 +#undef max
   23.72 +
   23.73 +/* Concatenate two tokens after evaluating them
   23.74 + */
   23.75 +#define _AI_CONCAT(a,b)  a ## b
   23.76 +#define  AI_CONCAT(a,b)  _AI_CONCAT(a,b)
   23.77 +
   23.78 +/* Helper macro to set a pointer to NULL in debug builds
   23.79 + */
   23.80 +#if (defined _DEBUG)
   23.81 +#	define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
   23.82 +#else
   23.83 +#	define AI_DEBUG_INVALIDATE_PTR(x)
   23.84 +#endif
   23.85 +
   23.86 +/* Beginning with MSVC8 some C string manipulation functions are mapped to their _safe_
   23.87 + * counterparts (e.g. _itoa_s). This avoids a lot of trouble with deprecation warnings.
   23.88 + */
   23.89 +#if _MSC_VER >= 1400 && !(defined _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES)
   23.90 +#	define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
   23.91 +#endif
   23.92 +
   23.93 +/* size_t to unsigned int, possible loss of data. The compiler is right with his warning
   23.94 + * but this loss of data won't be a problem for us. So shut up, little boy.
   23.95 + */
   23.96 +#ifdef _MSC_VER
   23.97 +#	pragma warning (disable : 4267)
   23.98 +#endif
   23.99 +
  23.100 +// ----------------------------------------------------------------------------------------
  23.101 +/* Actually that's not required for MSVC. It is included somewhere in the deeper parts of
  23.102 + * the MSVC STL but it's necessary for proper build with STLport.
  23.103 + */
  23.104 +#include <ctype.h>
  23.105 +
  23.106 +// Runtime/STL headers
  23.107 +#include <vector>
  23.108 +#include <list>
  23.109 +#include <map>
  23.110 +#include <set>
  23.111 +#include <string>
  23.112 +#include <sstream>
  23.113 +#include <iomanip>
  23.114 +#include <cassert>
  23.115 +#include <stack>
  23.116 +#include <queue>
  23.117 +#include <iostream>
  23.118 +#include <algorithm>
  23.119 +#include <numeric>
  23.120 +#include <new>
  23.121 +#include <cstdio>
  23.122 +#include <limits.h>
  23.123 +#include <memory>
  23.124 +
  23.125 +// Boost headers
  23.126 +#include <boost/pointer_cast.hpp>
  23.127 +#include <boost/scoped_ptr.hpp>
  23.128 +#include <boost/scoped_array.hpp>
  23.129 +#include <boost/shared_ptr.hpp>
  23.130 +#include <boost/shared_array.hpp>
  23.131 +#include <boost/make_shared.hpp>
  23.132 +#include <boost/format.hpp>
  23.133 +#include <boost/foreach.hpp>
  23.134 +#include <boost/static_assert.hpp>
  23.135 +#include <boost/lexical_cast.hpp>
  23.136 +
  23.137 +// Public ASSIMP headers
  23.138 +#include "assimp/DefaultLogger.hpp"
  23.139 +#include "assimp/IOStream.hpp"
  23.140 +#include "assimp/IOSystem.hpp"
  23.141 +#include "assimp/scene.h"
  23.142 +#include "assimp/importerdesc.h"
  23.143 +#include "assimp/postprocess.h"
  23.144 +#include "assimp/Importer.hpp"
  23.145 +#include "assimp/Exporter.hpp"
  23.146 +
  23.147 +// Internal utility headers
  23.148 +#include "BaseImporter.h"
  23.149 +#include "StringComparison.h"
  23.150 +#include "StreamReader.h"
  23.151 +#include "qnan.h"
  23.152 +#include "ScenePrivate.h" 
  23.153 +
  23.154 +
  23.155 +// We need those constants, workaround for any platforms where nobody defined them yet
  23.156 +#if (!defined SIZE_MAX)
  23.157 +#	define SIZE_MAX (~((size_t)0))
  23.158 +#endif
  23.159 +
  23.160 +#if (!defined UINT_MAX)
  23.161 +#	define UINT_MAX (~((unsigned int)0))
  23.162 +#endif
  23.163 +
  23.164 +
  23.165 +#endif // !! ASSIMP_PCH_INCLUDED
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/libs/assimp/B3DImporter.cpp	Sat Feb 01 19:58:19 2014 +0200
    24.3 @@ -0,0 +1,687 @@
    24.4 +/*
    24.5 +---------------------------------------------------------------------------
    24.6 +Open Asset Import Library (assimp)
    24.7 +---------------------------------------------------------------------------
    24.8 +
    24.9 +Copyright (c) 2006-2012, assimp team
   24.10 +
   24.11 +All rights reserved.
   24.12 +
   24.13 +Redistribution and use of this software in source and binary forms, 
   24.14 +with or without modification, are permitted provided that the following 
   24.15 +conditions are met:
   24.16 +
   24.17 +* Redistributions of source code must retain the above
   24.18 +  copyright notice, this list of conditions and the
   24.19 +  following disclaimer.
   24.20 +
   24.21 +* Redistributions in binary form must reproduce the above
   24.22 +  copyright notice, this list of conditions and the
   24.23 +  following disclaimer in the documentation and/or other
   24.24 +  materials provided with the distribution.
   24.25 +
   24.26 +* Neither the name of the assimp team, nor the names of its
   24.27 +  contributors may be used to endorse or promote products
   24.28 +  derived from this software without specific prior
   24.29 +  written permission of the assimp team.
   24.30 +
   24.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   24.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   24.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   24.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   24.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   24.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   24.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   24.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   24.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   24.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   24.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24.42 +---------------------------------------------------------------------------
   24.43 +*/
   24.44 +
   24.45 +/** @file  B3DImporter.cpp
   24.46 + *  @brief Implementation of the b3d importer class
   24.47 + */
   24.48 +
   24.49 +#include "AssimpPCH.h"
   24.50 +#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
   24.51 +
   24.52 +// internal headers
   24.53 +#include "B3DImporter.h"
   24.54 +#include "TextureTransform.h"
   24.55 +#include "ConvertToLHProcess.h"
   24.56 +
   24.57 +using namespace Assimp;
   24.58 +using namespace std;
   24.59 +
   24.60 +static const aiImporterDesc desc = {
   24.61 +	"BlitzBasic 3D Importer",
   24.62 +	"",
   24.63 +	"",
   24.64 +	"http://www.blitzbasic.com/",
   24.65 +	aiImporterFlags_SupportBinaryFlavour,
   24.66 +	0,
   24.67 +	0,
   24.68 +	0,
   24.69 +	0,
   24.70 +	"b3d" 
   24.71 +};
   24.72 +
   24.73 +// (fixme, Aramis) quick workaround to get rid of all those signed to unsigned warnings
   24.74 +#ifdef _MSC_VER 
   24.75 +#	pragma warning (disable: 4018)
   24.76 +#endif
   24.77 +
   24.78 +//#define DEBUG_B3D
   24.79 +
   24.80 +// ------------------------------------------------------------------------------------------------
   24.81 +bool B3DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const{
   24.82 +
   24.83 +	size_t pos=pFile.find_last_of( '.' );
   24.84 +	if( pos==string::npos ) return false;
   24.85 +
   24.86 +	string ext=pFile.substr( pos+1 );
   24.87 +	if( ext.size()!=3 ) return false;
   24.88 +
   24.89 +	return (ext[0]=='b' || ext[0]=='B') && (ext[1]=='3') && (ext[2]=='d' || ext[2]=='D');
   24.90 +}
   24.91 +
   24.92 +// ------------------------------------------------------------------------------------------------
   24.93 +// Loader meta information
   24.94 +const aiImporterDesc* B3DImporter::GetInfo () const
   24.95 +{
   24.96 +	return &desc;
   24.97 +}
   24.98 +
   24.99 +#ifdef DEBUG_B3D
  24.100 +	extern "C"{ void _stdcall AllocConsole(); }
  24.101 +#endif
  24.102 +// ------------------------------------------------------------------------------------------------
  24.103 +void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler){
  24.104 +
  24.105 +#ifdef DEBUG_B3D
  24.106 +	AllocConsole();
  24.107 +	freopen( "conin$","r",stdin );
  24.108 +	freopen( "conout$","w",stdout );
  24.109 +	freopen( "conout$","w",stderr );
  24.110 +	cout<<"Hello world from the B3DImporter!"<<endl;
  24.111 +#endif
  24.112 +
  24.113 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
  24.114 +
  24.115 +	// Check whether we can read from the file
  24.116 +	if( file.get() == NULL)
  24.117 +		throw DeadlyImportError( "Failed to open B3D file " + pFile + ".");
  24.118 +
  24.119 +	// check whether the .b3d file is large enough to contain
  24.120 +	// at least one chunk.
  24.121 +	size_t fileSize = file->FileSize();
  24.122 +	if( fileSize<8 ) throw DeadlyImportError( "B3D File is too small.");
  24.123 +
  24.124 +	_pos=0;
  24.125 +	_buf.resize( fileSize );
  24.126 +	file->Read( &_buf[0],1,fileSize );
  24.127 +	_stack.clear();
  24.128 +
  24.129 +	ReadBB3D( pScene );
  24.130 +}
  24.131 +
  24.132 +// ------------------------------------------------------------------------------------------------
  24.133 +void B3DImporter::Oops(){
  24.134 +	throw DeadlyImportError( "B3D Importer - INTERNAL ERROR" );
  24.135 +}
  24.136 +
  24.137 +// ------------------------------------------------------------------------------------------------
  24.138 +void B3DImporter::Fail( string str ){
  24.139 +#ifdef DEBUG_B3D
  24.140 +	cout<<"Error in B3D file data: "<<str<<endl;
  24.141 +#endif
  24.142 +	throw DeadlyImportError( "B3D Importer - error in B3D file data: "+str );
  24.143 +}
  24.144 +
  24.145 +// ------------------------------------------------------------------------------------------------
  24.146 +int B3DImporter::ReadByte(){
  24.147 +	if( _pos<_buf.size() ) return _buf[_pos++];
  24.148 +	Fail( "EOF" );
  24.149 +	return 0;
  24.150 +}
  24.151 +
  24.152 +// ------------------------------------------------------------------------------------------------
  24.153 +int B3DImporter::ReadInt(){
  24.154 +	if( _pos+4<=_buf.size() ){
  24.155 +		int n=*(int*)&_buf[_pos];
  24.156 +		_pos+=4;
  24.157 +		return n;
  24.158 +	}
  24.159 +	Fail( "EOF" );
  24.160 +	return 0;
  24.161 +}
  24.162 +
  24.163 +// ------------------------------------------------------------------------------------------------
  24.164 +float B3DImporter::ReadFloat(){
  24.165 +	if( _pos+4<=_buf.size() ){
  24.166 +		float n=*(float*)&_buf[_pos];
  24.167 +		_pos+=4;
  24.168 +		return n;
  24.169 +	}
  24.170 +	Fail( "EOF" );
  24.171 +	return 0.0f;
  24.172 +}
  24.173 +
  24.174 +// ------------------------------------------------------------------------------------------------
  24.175 +aiVector2D B3DImporter::ReadVec2(){
  24.176 +	float x=ReadFloat();
  24.177 +	float y=ReadFloat();
  24.178 +	return aiVector2D( x,y );
  24.179 +}
  24.180 +
  24.181 +// ------------------------------------------------------------------------------------------------
  24.182 +aiVector3D B3DImporter::ReadVec3(){
  24.183 +	float x=ReadFloat();
  24.184 +	float y=ReadFloat();
  24.185 +	float z=ReadFloat();
  24.186 +	return aiVector3D( x,y,z );
  24.187 +}
  24.188 +
  24.189 +// ------------------------------------------------------------------------------------------------
  24.190 +aiQuaternion B3DImporter::ReadQuat(){
  24.191 +	// (aramis_acg) Fix to adapt the loader to changed quat orientation
  24.192 +	float w=-ReadFloat();
  24.193 +	float x=ReadFloat();
  24.194 +	float y=ReadFloat();
  24.195 +	float z=ReadFloat();
  24.196 +	return aiQuaternion( w,x,y,z );
  24.197 +}
  24.198 +
  24.199 +// ------------------------------------------------------------------------------------------------
  24.200 +string B3DImporter::ReadString(){
  24.201 +	string str;
  24.202 +	while( _pos<_buf.size() ){
  24.203 +		char c=(char)ReadByte();
  24.204 +		if( !c ) return str;
  24.205 +		str+=c;
  24.206 +	}
  24.207 +	Fail( "EOF" );
  24.208 +	return string();
  24.209 +}
  24.210 +
  24.211 +// ------------------------------------------------------------------------------------------------
  24.212 +string B3DImporter::ReadChunk(){
  24.213 +	string tag;
  24.214 +	for( int i=0;i<4;++i ){
  24.215 +		tag+=char( ReadByte() );
  24.216 +	}
  24.217 +#ifdef DEBUG_B3D
  24.218 +//	cout<<"ReadChunk:"<<tag<<endl;
  24.219 +#endif
  24.220 +	unsigned sz=(unsigned)ReadInt();
  24.221 +	_stack.push_back( _pos+sz );
  24.222 +	return tag;
  24.223 +}
  24.224 +
  24.225 +// ------------------------------------------------------------------------------------------------
  24.226 +void B3DImporter::ExitChunk(){
  24.227 +	_pos=_stack.back();
  24.228 +	_stack.pop_back();
  24.229 +}
  24.230 +
  24.231 +// ------------------------------------------------------------------------------------------------
  24.232 +unsigned B3DImporter::ChunkSize(){
  24.233 +	return _stack.back()-_pos;
  24.234 +}
  24.235 +// ------------------------------------------------------------------------------------------------
  24.236 +
  24.237 +template<class T>
  24.238 +T *B3DImporter::to_array( const vector<T> &v ){
  24.239 +	if( !v.size() ) return 0;
  24.240 +	T *p=new T[v.size()];
  24.241 +	for( size_t i=0;i<v.size();++i ){
  24.242 +		p[i]=v[i];
  24.243 +	}
  24.244 +	return p;
  24.245 +}
  24.246 +
  24.247 +// ------------------------------------------------------------------------------------------------
  24.248 +void B3DImporter::ReadTEXS(){
  24.249 +	while( ChunkSize() ){
  24.250 +		string name=ReadString();
  24.251 +		/*int flags=*/ReadInt();
  24.252 +		/*int blend=*/ReadInt();
  24.253 +		/*aiVector2D pos=*/ReadVec2();
  24.254 +		/*aiVector2D scale=*/ReadVec2();
  24.255 +		/*float rot=*/ReadFloat();
  24.256 +
  24.257 +		_textures.push_back( name );
  24.258 +	}
  24.259 +}
  24.260 +
  24.261 +// ------------------------------------------------------------------------------------------------
  24.262 +void B3DImporter::ReadBRUS(){
  24.263 +	int n_texs=ReadInt();
  24.264 +	if( n_texs<0 || n_texs>8 ){
  24.265 +		Fail( "Bad texture count" );
  24.266 +	}
  24.267 +	while( ChunkSize() ){
  24.268 +		string name=ReadString();
  24.269 +		aiVector3D color=ReadVec3();
  24.270 +		float alpha=ReadFloat();
  24.271 +		float shiny=ReadFloat();
  24.272 +		/*int blend=**/ReadInt();
  24.273 +		int fx=ReadInt();
  24.274 +
  24.275 +		aiMaterial *mat=new aiMaterial;
  24.276 +		_materials.push_back( mat );
  24.277 +		
  24.278 +		// Name
  24.279 +		aiString ainame( name );
  24.280 +		mat->AddProperty( &ainame,AI_MATKEY_NAME );
  24.281 +		
  24.282 +		// Diffuse color 
  24.283 +		mat->AddProperty( &color,1,AI_MATKEY_COLOR_DIFFUSE );
  24.284 +
  24.285 +		// Opacity
  24.286 +		mat->AddProperty( &alpha,1,AI_MATKEY_OPACITY );
  24.287 +
  24.288 +		// Specular color
  24.289 +		aiColor3D speccolor( shiny,shiny,shiny );
  24.290 +		mat->AddProperty( &speccolor,1,AI_MATKEY_COLOR_SPECULAR );
  24.291 +		
  24.292 +		// Specular power
  24.293 +		float specpow=shiny*128;
  24.294 +		mat->AddProperty( &specpow,1,AI_MATKEY_SHININESS );
  24.295 +		
  24.296 +		// Double sided
  24.297 +		if( fx & 0x10 ){
  24.298 +			int i=1; 
  24.299 +			mat->AddProperty( &i,1,AI_MATKEY_TWOSIDED );
  24.300 +		} 		
  24.301 +
  24.302 +		//Textures
  24.303 +		for( int i=0;i<n_texs;++i ){
  24.304 +			int texid=ReadInt();
  24.305 +			if( texid<-1 || (texid>=0 && texid>=static_cast<int>(_textures.size())) ){
  24.306 +				Fail( "Bad texture id" );
  24.307 +			}
  24.308 +			if( i==0 && texid>=0 ){
  24.309 +				aiString texname( _textures[texid] );
  24.310 +				mat->AddProperty( &texname,AI_MATKEY_TEXTURE_DIFFUSE(0) );
  24.311 +			}
  24.312 +		}
  24.313 +	}
  24.314 +}
  24.315 +
  24.316 +// ------------------------------------------------------------------------------------------------
  24.317 +void B3DImporter::ReadVRTS(){
  24.318 +	_vflags=ReadInt();
  24.319 +	_tcsets=ReadInt();
  24.320 +	_tcsize=ReadInt();
  24.321 +	if( _tcsets<0 || _tcsets>4 || _tcsize<0 || _tcsize>4 ){
  24.322 +		Fail( "Bad texcoord data" );
  24.323 +	}
  24.324 +
  24.325 +	int sz=12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4);
  24.326 +	int n_verts=ChunkSize()/sz;
  24.327 +
  24.328 +	int v0=_vertices.size();
  24.329 +	_vertices.resize( v0+n_verts );
  24.330 +
  24.331 +	for( int i=0;i<n_verts;++i ){
  24.332 +		Vertex &v=_vertices[v0+i];
  24.333 +
  24.334 +		memset( v.bones,0,sizeof(v.bones) );
  24.335 +		memset( v.weights,0,sizeof(v.weights) );
  24.336 +
  24.337 +		v.vertex=ReadVec3();
  24.338 +
  24.339 +		if( _vflags & 1 ) v.normal=ReadVec3();
  24.340 +
  24.341 +		if( _vflags & 2 ) ReadQuat();	//skip v 4bytes...
  24.342 +
  24.343 +		for( int i=0;i<_tcsets;++i ){
  24.344 +			float t[4]={0,0,0,0};
  24.345 +			for( int j=0;j<_tcsize;++j ){
  24.346 +				t[j]=ReadFloat();
  24.347 +			}
  24.348 +			t[1]=1-t[1];
  24.349 +			if( !i ) v.texcoords=aiVector3D( t[0],t[1],t[2] );
  24.350 +		}
  24.351 +	}
  24.352 +}
  24.353 +
  24.354 +// ------------------------------------------------------------------------------------------------
  24.355 +void B3DImporter::ReadTRIS( int v0 ){
  24.356 +	int matid=ReadInt();
  24.357 +	if( matid==-1 ){
  24.358 +		matid=0;
  24.359 +	}else if( matid<0 || matid>=(int)_materials.size() ){
  24.360 +#ifdef DEBUG_B3D
  24.361 +		cout<<"material id="<<matid<<endl;
  24.362 +#endif
  24.363 +		Fail( "Bad material id" );
  24.364 +	}
  24.365 +
  24.366 +	aiMesh *mesh=new aiMesh;
  24.367 +	_meshes.push_back( mesh );
  24.368 +
  24.369 +	mesh->mMaterialIndex=matid;
  24.370 +	mesh->mNumFaces=0;
  24.371 +	mesh->mPrimitiveTypes=aiPrimitiveType_TRIANGLE;
  24.372 +
  24.373 +	int n_tris=ChunkSize()/12;
  24.374 +	aiFace *face=mesh->mFaces=new aiFace[n_tris];
  24.375 +
  24.376 +	for( int i=0;i<n_tris;++i ){
  24.377 +		int i0=ReadInt()+v0;
  24.378 +		int i1=ReadInt()+v0;
  24.379 +		int i2=ReadInt()+v0;
  24.380 +		if( i0<0 || i0>=(int)_vertices.size() || i1<0 || i1>=(int)_vertices.size() || i2<0 || i2>=(int)_vertices.size() ){
  24.381 +#ifdef DEBUG_B3D
  24.382 +			cout<<"Bad triangle index: i0="<<i0<<", i1="<<i1<<", i2="<<i2<<endl;
  24.383 +#endif
  24.384 +			Fail( "Bad triangle index" );
  24.385 +			continue;
  24.386 +		}
  24.387 +		face->mNumIndices=3;
  24.388 +		face->mIndices=new unsigned[3];
  24.389 +		face->mIndices[0]=i0;
  24.390 +		face->mIndices[1]=i1;
  24.391 +		face->mIndices[2]=i2;
  24.392 +		++mesh->mNumFaces;
  24.393 +		++face;
  24.394 +	}
  24.395 +}
  24.396 +
  24.397 +// ------------------------------------------------------------------------------------------------
  24.398 +void B3DImporter::ReadMESH(){
  24.399 +	/*int matid=*/ReadInt();
  24.400 +
  24.401 +	int v0=_vertices.size();
  24.402 +
  24.403 +	while( ChunkSize() ){
  24.404 +		string t=ReadChunk();
  24.405 +		if( t=="VRTS" ){
  24.406 +			ReadVRTS();
  24.407 +		}else if( t=="TRIS" ){
  24.408 +			ReadTRIS( v0 );
  24.409 +		}
  24.410 +		ExitChunk();
  24.411 +	}
  24.412 +}
  24.413 +
  24.414 +// ------------------------------------------------------------------------------------------------
  24.415 +void B3DImporter::ReadBONE( int id ){
  24.416 +	while( ChunkSize() ){
  24.417 +		int vertex=ReadInt();
  24.418 +		float weight=ReadFloat();
  24.419 +		if( vertex<0 || vertex>=(int)_vertices.size() ){
  24.420 +			Fail( "Bad vertex index" );
  24.421 +		}
  24.422 +
  24.423 +		Vertex &v=_vertices[vertex];
  24.424 +		int i;
  24.425 +		for( i=0;i<4;++i ){
  24.426 +			if( !v.weights[i] ){
  24.427 +				v.bones[i]=id;
  24.428 +				v.weights[i]=weight;
  24.429 +				break;
  24.430 +			}
  24.431 +		}
  24.432 +#ifdef DEBUG_B3D
  24.433 +		if( i==4 ){
  24.434 +			cout<<"Too many bone weights"<<endl;
  24.435 +		}
  24.436 +#endif
  24.437 +	}
  24.438 +}
  24.439 +
  24.440 +// ------------------------------------------------------------------------------------------------
  24.441 +void B3DImporter::ReadKEYS( aiNodeAnim *nodeAnim ){
  24.442 +	vector<aiVectorKey> trans,scale;
  24.443 +	vector<aiQuatKey> rot;
  24.444 +	int flags=ReadInt();
  24.445 +	while( ChunkSize() ){
  24.446 +		int frame=ReadInt();
  24.447 +		if( flags & 1 ){
  24.448 +			trans.push_back( aiVectorKey( frame,ReadVec3() ) );
  24.449 +		}
  24.450 +		if( flags & 2 ){
  24.451 +			scale.push_back( aiVectorKey( frame,ReadVec3() ) );
  24.452 +		}
  24.453 +		if( flags & 4 ){
  24.454 +			rot.push_back( aiQuatKey( frame,ReadQuat() ) );
  24.455 +		}
  24.456 +	}
  24.457 +
  24.458 +	if( flags & 1 ){
  24.459 +		nodeAnim->mNumPositionKeys=trans.size();
  24.460 +		nodeAnim->mPositionKeys=to_array( trans );
  24.461 +	}
  24.462 +
  24.463 +	if( flags & 2 ){
  24.464 +		nodeAnim->mNumScalingKeys=scale.size();
  24.465 +		nodeAnim->mScalingKeys=to_array( scale );
  24.466 +	}
  24.467 +
  24.468 +	if( flags & 4 ){
  24.469 +		nodeAnim->mNumRotationKeys=rot.size();
  24.470 +		nodeAnim->mRotationKeys=to_array( rot );
  24.471 +	}
  24.472 +}
  24.473 +
  24.474 +// ------------------------------------------------------------------------------------------------
  24.475 +void B3DImporter::ReadANIM(){
  24.476 +	/*int flags=*/ReadInt();
  24.477 +	int frames=ReadInt();
  24.478 +	float fps=ReadFloat();
  24.479 +
  24.480 +	aiAnimation *anim=new aiAnimation;
  24.481 +	_animations.push_back( anim );
  24.482 +
  24.483 +	anim->mDuration=frames;
  24.484 +	anim->mTicksPerSecond=fps;
  24.485 +}
  24.486 +
  24.487 +// ------------------------------------------------------------------------------------------------
  24.488 +aiNode *B3DImporter::ReadNODE( aiNode *parent ){
  24.489 +
  24.490 +	string name=ReadString();
  24.491 +	aiVector3D t=ReadVec3();
  24.492 +	aiVector3D s=ReadVec3();
  24.493 +	aiQuaternion r=ReadQuat();
  24.494 +
  24.495 +	aiMatrix4x4 trans,scale,rot;
  24.496 +
  24.497 +	aiMatrix4x4::Translation( t,trans );
  24.498 +	aiMatrix4x4::Scaling( s,scale );
  24.499 +	rot=aiMatrix4x4( r.GetMatrix() );
  24.500 +
  24.501 +	aiMatrix4x4 tform=trans * rot * scale;
  24.502 +
  24.503 +	int nodeid=_nodes.size();
  24.504 +
  24.505 +	aiNode *node=new aiNode( name );
  24.506 +	_nodes.push_back( node );
  24.507 +
  24.508 +	node->mParent=parent;
  24.509 +	node->mTransformation=tform;
  24.510 +
  24.511 +	aiNodeAnim *nodeAnim=0;
  24.512 +	vector<unsigned> meshes;
  24.513 +	vector<aiNode*> children;
  24.514 +
  24.515 +	while( ChunkSize() ){
  24.516 +		string t=ReadChunk();
  24.517 +		if( t=="MESH" ){
  24.518 +			int n=_meshes.size();
  24.519 +			ReadMESH();
  24.520 +			for( int i=n;i<(int)_meshes.size();++i ){
  24.521 +				meshes.push_back( i );
  24.522 +			}
  24.523 +		}else if( t=="BONE" ){
  24.524 +			ReadBONE( nodeid );
  24.525 +		}else if( t=="ANIM" ){
  24.526 +			ReadANIM();
  24.527 +		}else if( t=="KEYS" ){
  24.528 +			if( !nodeAnim ){
  24.529 +				nodeAnim=new aiNodeAnim;
  24.530 +				_nodeAnims.push_back( nodeAnim );
  24.531 +				nodeAnim->mNodeName=node->mName;
  24.532 +			}
  24.533 +			ReadKEYS( nodeAnim );
  24.534 +		}else if( t=="NODE" ){
  24.535 +			aiNode *child=ReadNODE( node );
  24.536 +			children.push_back( child );
  24.537 +		}
  24.538 +		ExitChunk();
  24.539 +	}
  24.540 +
  24.541 +	node->mNumMeshes=meshes.size();
  24.542 +	node->mMeshes=to_array( meshes );
  24.543 +
  24.544 +	node->mNumChildren=children.size();
  24.545 +	node->mChildren=to_array( children );
  24.546 +
  24.547 +	return node;
  24.548 +}
  24.549 +
  24.550 +// ------------------------------------------------------------------------------------------------
  24.551 +void B3DImporter::ReadBB3D( aiScene *scene ){
  24.552 +
  24.553 +	_textures.clear();
  24.554 +	_materials.size();
  24.555 +
  24.556 +	_vertices.clear();
  24.557 +	_meshes.clear();
  24.558 +
  24.559 +	_nodes.clear();
  24.560 +	_nodeAnims.clear();
  24.561 +	_animations.clear();
  24.562 +
  24.563 +	string t=ReadChunk();
  24.564 +	if( t=="BB3D" ){
  24.565 +		int version=ReadInt();
  24.566 +		
  24.567 +		if (!DefaultLogger::isNullLogger()) {
  24.568 +			char dmp[128];
  24.569 +			sprintf(dmp,"B3D file format version: %i",version);
  24.570 +			DefaultLogger::get()->info(dmp);
  24.571 +		}
  24.572 +
  24.573 +		while( ChunkSize() ){
  24.574 +			string t=ReadChunk();
  24.575 +			if( t=="TEXS" ){
  24.576 +				ReadTEXS();
  24.577 +			}else if( t=="BRUS" ){
  24.578 +				ReadBRUS();
  24.579 +			}else if( t=="NODE" ){
  24.580 +				ReadNODE( 0 );
  24.581 +			}
  24.582 +			ExitChunk();
  24.583 +		}
  24.584 +	}
  24.585 +	ExitChunk();
  24.586 +
  24.587 +	if( !_nodes.size() ) Fail( "No nodes" );
  24.588 +
  24.589 +	if( !_meshes.size() ) Fail( "No meshes" );
  24.590 +
  24.591 +	//Fix nodes/meshes/bones
  24.592 +	for(size_t i=0;i<_nodes.size();++i ){
  24.593 +		aiNode *node=_nodes[i];
  24.594 +
  24.595 +		for( size_t j=0;j<node->mNumMeshes;++j ){
  24.596 +			aiMesh *mesh=_meshes[node->mMeshes[j]];
  24.597 +
  24.598 +			int n_tris=mesh->mNumFaces;
  24.599 +			int n_verts=mesh->mNumVertices=n_tris * 3;
  24.600 +
  24.601 +			aiVector3D *mv=mesh->mVertices=new aiVector3D[ n_verts ],*mn=0,*mc=0;
  24.602 +			if( _vflags & 1 ) mn=mesh->mNormals=new aiVector3D[ n_verts ];
  24.603 +			if( _tcsets ) mc=mesh->mTextureCoords[0]=new aiVector3D[ n_verts ];
  24.604 +
  24.605 +			aiFace *face=mesh->mFaces;
  24.606 +
  24.607 +			vector< vector<aiVertexWeight> > vweights( _nodes.size() );
  24.608 +
  24.609 +			for( int i=0;i<n_verts;i+=3 ){
  24.610 +				for( int j=0;j<3;++j ){
  24.611 +					Vertex &v=_vertices[face->mIndices[j]];
  24.612 +
  24.613 +					*mv++=v.vertex;
  24.614 +					if( mn ) *mn++=v.normal;
  24.615 +					if( mc ) *mc++=v.texcoords;
  24.616 +
  24.617 +					face->mIndices[j]=i+j;
  24.618 +
  24.619 +					for( int k=0;k<4;++k ){
  24.620 +						if( !v.weights[k] ) break;
  24.621 +
  24.622 +						int bone=v.bones[k];
  24.623 +						float weight=v.weights[k];
  24.624 +
  24.625 +						vweights[bone].push_back( aiVertexWeight(i+j,weight) );
  24.626 +					}
  24.627 +				}
  24.628 +				++face;
  24.629 +			}
  24.630 +
  24.631 +			vector<aiBone*> bones;
  24.632 +			for(size_t i=0;i<vweights.size();++i ){
  24.633 +				vector<aiVertexWeight> &weights=vweights[i];
  24.634 +				if( !weights.size() ) continue;
  24.635 +
  24.636 +				aiBone *bone=new aiBone;
  24.637 +				bones.push_back( bone );
  24.638 +
  24.639 +				aiNode *bnode=_nodes[i];
  24.640 +
  24.641 +				bone->mName=bnode->mName;
  24.642 +				bone->mNumWeights=weights.size();
  24.643 +				bone->mWeights=to_array( weights );
  24.644 +
  24.645 +				aiMatrix4x4 mat=bnode->mTransformation;
  24.646 +				while( bnode->mParent ){
  24.647 +					bnode=bnode->mParent;
  24.648 +					mat=bnode->mTransformation * mat;
  24.649 +				}
  24.650 +				bone->mOffsetMatrix=mat.Inverse();
  24.651 +			}
  24.652 +			mesh->mNumBones=bones.size();
  24.653 +			mesh->mBones=to_array( bones );
  24.654 +		}
  24.655 +	}
  24.656 +
  24.657 +	//nodes
  24.658 +	scene->mRootNode=_nodes[0];
  24.659 +
  24.660 +	//material
  24.661 +	if( !_materials.size() ){
  24.662 +		_materials.push_back( new aiMaterial );
  24.663 +	}
  24.664 +	scene->mNumMaterials=_materials.size();
  24.665 +	scene->mMaterials=to_array( _materials );
  24.666 +	
  24.667 +	//meshes
  24.668 +	scene->mNumMeshes=_meshes.size();
  24.669 +	scene->mMeshes=to_array( _meshes );
  24.670 +
  24.671 +	//animations
  24.672 +	if( _animations.size()==1 && _nodeAnims.size() ){
  24.673 +
  24.674 +		aiAnimation *anim=_animations.back();
  24.675 +		anim->mNumChannels=_nodeAnims.size();
  24.676 +		anim->mChannels=to_array( _nodeAnims );
  24.677 +
  24.678 +		scene->mNumAnimations=_animations.size();
  24.679 +		scene->mAnimations=to_array( _animations );
  24.680 +	}
  24.681 +
  24.682 +	// convert to RH
  24.683 +	MakeLeftHandedProcess makeleft;
  24.684 +	makeleft.Execute( scene );
  24.685 +
  24.686 +	FlipWindingOrderProcess flip;
  24.687 +	flip.Execute( scene );
  24.688 +}
  24.689 +
  24.690 +#endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/libs/assimp/B3DImporter.h	Sat Feb 01 19:58:19 2014 +0200
    25.3 @@ -0,0 +1,126 @@
    25.4 +
    25.5 +/*
    25.6 +Open Asset Import Library (assimp)
    25.7 +----------------------------------------------------------------------
    25.8 +
    25.9 +Copyright (c) 2006-2012, assimp team
   25.10 +All rights reserved.
   25.11 +
   25.12 +Redistribution and use of this software in source and binary forms, 
   25.13 +with or without modification, are permitted provided that the 
   25.14 +following conditions are met:
   25.15 +
   25.16 +* Redistributions of source code must retain the above
   25.17 +  copyright notice, this list of conditions and the
   25.18 +  following disclaimer.
   25.19 +
   25.20 +* Redistributions in binary form must reproduce the above
   25.21 +  copyright notice, this list of conditions and the
   25.22 +  following disclaimer in the documentation and/or other
   25.23 +  materials provided with the distribution.
   25.24 +
   25.25 +* Neither the name of the assimp team, nor the names of its
   25.26 +  contributors may be used to endorse or promote products
   25.27 +  derived from this software without specific prior
   25.28 +  written permission of the assimp team.
   25.29 +
   25.30 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   25.31 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   25.32 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   25.33 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   25.34 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   25.35 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   25.36 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   25.37 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   25.38 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   25.39 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   25.40 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25.41 +
   25.42 +----------------------------------------------------------------------
   25.43 +*/
   25.44 +
   25.45 +/** @file Definition of the .b3d importer class. */
   25.46 +
   25.47 +#ifndef AI_B3DIMPORTER_H_INC
   25.48 +#define AI_B3DIMPORTER_H_INC
   25.49 +
   25.50 +#include "assimp/types.h"
   25.51 +#include "assimp/mesh.h"
   25.52 +#include "assimp/material.h"
   25.53 +
   25.54 +#include <string>
   25.55 +#include <vector>
   25.56 +
   25.57 +namespace Assimp{
   25.58 +
   25.59 +class B3DImporter : public BaseImporter{
   25.60 +public:
   25.61 +
   25.62 +	virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
   25.63 +
   25.64 +protected:
   25.65 +
   25.66 +	virtual const aiImporterDesc* GetInfo () const;
   25.67 +	virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
   25.68 +
   25.69 +private:
   25.70 +
   25.71 +	int ReadByte();
   25.72 +	int ReadInt();
   25.73 +	float ReadFloat();
   25.74 +	aiVector2D ReadVec2();
   25.75 +	aiVector3D ReadVec3();
   25.76 +	aiQuaternion ReadQuat();
   25.77 +	std::string ReadString();
   25.78 +	std::string ReadChunk();
   25.79 +	void ExitChunk();
   25.80 +	unsigned ChunkSize();
   25.81 +
   25.82 +	template<class T>
   25.83 +	T *to_array( const std::vector<T> &v );
   25.84 +
   25.85 +	struct Vertex{
   25.86 +		aiVector3D vertex;
   25.87 +		aiVector3D normal;
   25.88 +		aiVector3D texcoords;
   25.89 +		unsigned char bones[4];
   25.90 +		float weights[4];
   25.91 +	};
   25.92 +
   25.93 +	void Oops();
   25.94 +	void Fail( std::string str );
   25.95 +
   25.96 +	void ReadTEXS();
   25.97 +	void ReadBRUS();
   25.98 +
   25.99 +	void ReadVRTS();
  25.100 +	void ReadTRIS( int v0 );
  25.101 +	void ReadMESH();
  25.102 +	void ReadBONE( int id );
  25.103 +	void ReadKEYS( aiNodeAnim *nodeAnim );
  25.104 +	void ReadANIM();
  25.105 +
  25.106 +	aiNode *ReadNODE( aiNode *parent );
  25.107 +
  25.108 +	void ReadBB3D( aiScene *scene );
  25.109 +
  25.110 +	unsigned _pos;
  25.111 +//	unsigned _size;
  25.112 +	std::vector<unsigned char> _buf;
  25.113 +	std::vector<unsigned> _stack;
  25.114 +	
  25.115 +	std::vector<std::string> _textures;
  25.116 +	std::vector<aiMaterial*> _materials;
  25.117 +
  25.118 +	int _vflags,_tcsets,_tcsize;
  25.119 +	std::vector<Vertex> _vertices;
  25.120 +
  25.121 +	std::vector<aiNode*> _nodes;
  25.122 +	std::vector<aiMesh*> _meshes;
  25.123 +	std::vector<aiNodeAnim*> _nodeAnims;
  25.124 +	std::vector<aiAnimation*> _animations;
  25.125 +};
  25.126 +
  25.127 +}
  25.128 +
  25.129 +#endif
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/libs/assimp/BVHLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
    26.3 @@ -0,0 +1,534 @@
    26.4 +/** Implementation of the BVH loader */
    26.5 +/*
    26.6 +---------------------------------------------------------------------------
    26.7 +Open Asset Import Library (assimp)
    26.8 +---------------------------------------------------------------------------
    26.9 +
   26.10 +Copyright (c) 2006-2012, assimp team
   26.11 +
   26.12 +All rights reserved.
   26.13 +
   26.14 +Redistribution and use of this software in source and binary forms, 
   26.15 +with or without modification, are permitted provided that the following 
   26.16 +conditions are met:
   26.17 +
   26.18 +* Redistributions of source code must retain the above
   26.19 +copyright notice, this list of conditions and the
   26.20 +following disclaimer.
   26.21 +
   26.22 +* Redistributions in binary form must reproduce the above
   26.23 +copyright notice, this list of conditions and the
   26.24 +following disclaimer in the documentation and/or other
   26.25 +materials provided with the distribution.
   26.26 +
   26.27 +* Neither the name of the assimp team, nor the names of its
   26.28 +contributors may be used to endorse or promote products
   26.29 +derived from this software without specific prior
   26.30 +written permission of the assimp team.
   26.31 +
   26.32 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   26.33 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   26.34 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   26.35 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   26.36 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   26.37 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   26.38 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   26.39 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   26.40 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   26.41 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   26.42 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26.43 +---------------------------------------------------------------------------
   26.44 +*/
   26.45 +
   26.46 +#include "AssimpPCH.h"
   26.47 +#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
   26.48 +
   26.49 +#include "BVHLoader.h"
   26.50 +#include "fast_atof.h"
   26.51 +#include "SkeletonMeshBuilder.h"
   26.52 +
   26.53 +using namespace Assimp;
   26.54 +
   26.55 +static const aiImporterDesc desc = {
   26.56 +	"BVH Importer (MoCap)",
   26.57 +	"",
   26.58 +	"",
   26.59 +	"",
   26.60 +	aiImporterFlags_SupportTextFlavour,
   26.61 +	0,
   26.62 +	0,
   26.63 +	0,
   26.64 +	0,
   26.65 +	"bvh"
   26.66 +};
   26.67 +
   26.68 +// ------------------------------------------------------------------------------------------------
   26.69 +// Constructor to be privately used by Importer
   26.70 +BVHLoader::BVHLoader()
   26.71 +: noSkeletonMesh()
   26.72 +{}
   26.73 +
   26.74 +// ------------------------------------------------------------------------------------------------
   26.75 +// Destructor, private as well
   26.76 +BVHLoader::~BVHLoader()
   26.77 +{}
   26.78 +
   26.79 +// ------------------------------------------------------------------------------------------------
   26.80 +// Returns whether the class can handle the format of the given file. 
   26.81 +bool BVHLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
   26.82 +{
   26.83 +	// check file extension 
   26.84 +	const std::string extension = GetExtension(pFile);
   26.85 +	
   26.86 +	if( extension == "bvh")
   26.87 +		return true;
   26.88 +
   26.89 +	if ((!extension.length() || cs) && pIOHandler) {
   26.90 +		const char* tokens[] = {"HIERARCHY"};
   26.91 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
   26.92 +	}
   26.93 +	return false;
   26.94 +}
   26.95 +
   26.96 +// ------------------------------------------------------------------------------------------------
   26.97 +void BVHLoader::SetupProperties(const Importer* pImp)
   26.98 +{
   26.99 +	noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
  26.100 +}
  26.101 +
  26.102 +// ------------------------------------------------------------------------------------------------
  26.103 +// Loader meta information
  26.104 +const aiImporterDesc* BVHLoader::GetInfo () const
  26.105 +{
  26.106 +	return &desc;
  26.107 +}
  26.108 +
  26.109 +// ------------------------------------------------------------------------------------------------
  26.110 +// Imports the given file into the given scene structure. 
  26.111 +void BVHLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
  26.112 +{
  26.113 +	mFileName = pFile;
  26.114 +
  26.115 +	// read file into memory
  26.116 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
  26.117 +	if( file.get() == NULL)
  26.118 +		throw DeadlyImportError( "Failed to open file " + pFile + ".");
  26.119 +
  26.120 +	size_t fileSize = file->FileSize();
  26.121 +	if( fileSize == 0)
  26.122 +		throw DeadlyImportError( "File is too small.");
  26.123 +
  26.124 +	mBuffer.resize( fileSize);
  26.125 +	file->Read( &mBuffer.front(), 1, fileSize);
  26.126 +
  26.127 +	// start reading
  26.128 +	mReader = mBuffer.begin();
  26.129 +	mLine = 1;
  26.130 +	ReadStructure( pScene);
  26.131 +
  26.132 +	if (!noSkeletonMesh) {
  26.133 +		// build a dummy mesh for the skeleton so that we see something at least
  26.134 +		SkeletonMeshBuilder meshBuilder( pScene);
  26.135 +	}
  26.136 +
  26.137 +	// construct an animation from all the motion data we read
  26.138 +	CreateAnimation( pScene);
  26.139 +}
  26.140 +
  26.141 +// ------------------------------------------------------------------------------------------------
  26.142 +// Reads the file
  26.143 +void BVHLoader::ReadStructure( aiScene* pScene)
  26.144 +{
  26.145 +	// first comes hierarchy
  26.146 +	std::string header = GetNextToken();
  26.147 +	if( header != "HIERARCHY")
  26.148 +		ThrowException( "Expected header string \"HIERARCHY\".");
  26.149 +	ReadHierarchy( pScene);
  26.150 +
  26.151 +	// then comes the motion data
  26.152 +	std::string motion = GetNextToken();
  26.153 +	if( motion != "MOTION")
  26.154 +		ThrowException( "Expected beginning of motion data \"MOTION\".");
  26.155 +	ReadMotion( pScene);
  26.156 +}
  26.157 +
  26.158 +// ------------------------------------------------------------------------------------------------
  26.159 +// Reads the hierarchy
  26.160 +void BVHLoader::ReadHierarchy( aiScene* pScene)
  26.161 +{
  26.162 +	std::string root = GetNextToken();
  26.163 +	if( root != "ROOT")
  26.164 +		ThrowException( "Expected root node \"ROOT\".");
  26.165 +
  26.166 +	// Go read the hierarchy from here
  26.167 +	pScene->mRootNode = ReadNode();
  26.168 +}
  26.169 +
  26.170 +// ------------------------------------------------------------------------------------------------
  26.171 +// Reads a node and recursively its childs and returns the created node;
  26.172 +aiNode* BVHLoader::ReadNode()
  26.173 +{
  26.174 +	// first token is name
  26.175 +	std::string nodeName = GetNextToken();
  26.176 +	if( nodeName.empty() || nodeName == "{")
  26.177 +		ThrowException( boost::str( boost::format( "Expected node name, but found \"%s\".") % nodeName));
  26.178 +
  26.179 +	// then an opening brace should follow
  26.180 +	std::string openBrace = GetNextToken();
  26.181 +	if( openBrace != "{")
  26.182 +		ThrowException( boost::str( boost::format( "Expected opening brace \"{\", but found \"%s\".") % openBrace));
  26.183 +
  26.184 +	// Create a node
  26.185 +	aiNode* node = new aiNode( nodeName);
  26.186 +	std::vector<aiNode*> childNodes;
  26.187 +
  26.188 +	// and create an bone entry for it
  26.189 +	mNodes.push_back( Node( node));
  26.190 +	Node& internNode = mNodes.back();
  26.191 +
  26.192 +	// now read the node's contents
  26.193 +	while( 1)
  26.194 +	{
  26.195 +		std::string token = GetNextToken();
  26.196 +
  26.197 +		// node offset to parent node
  26.198 +		if( token == "OFFSET")
  26.199 +			ReadNodeOffset( node);
  26.200 +		else if( token == "CHANNELS")
  26.201 +			ReadNodeChannels( internNode);
  26.202 +		else if( token == "JOINT")
  26.203 +		{
  26.204 +			// child node follows
  26.205 +			aiNode* child = ReadNode();
  26.206 +			child->mParent = node;
  26.207 +			childNodes.push_back( child);
  26.208 +		} 
  26.209 +		else if( token == "End")
  26.210 +		{
  26.211 +			// The real symbol is "End Site". Second part comes in a separate token
  26.212 +			std::string siteToken = GetNextToken();
  26.213 +			if( siteToken != "Site")
  26.214 +				ThrowException( boost::str( boost::format( "Expected \"End Site\" keyword, but found \"%s %s\".") % token % siteToken));
  26.215 +
  26.216 +			aiNode* child = ReadEndSite( nodeName);
  26.217 +			child->mParent = node;
  26.218 +			childNodes.push_back( child);
  26.219 +		} 
  26.220 +		else if( token == "}")
  26.221 +		{
  26.222 +			// we're done with that part of the hierarchy
  26.223 +			break;
  26.224 +		} else
  26.225 +		{
  26.226 +			// everything else is a parse error
  26.227 +			ThrowException( boost::str( boost::format( "Unknown keyword \"%s\".") % token));
  26.228 +		}
  26.229 +	}
  26.230 +
  26.231 +	// add the child nodes if there are any
  26.232 +	if( childNodes.size() > 0)
  26.233 +	{
  26.234 +		node->mNumChildren = childNodes.size();
  26.235 +		node->mChildren = new aiNode*[node->mNumChildren];
  26.236 +		std::copy( childNodes.begin(), childNodes.end(), node->mChildren);
  26.237 +	}
  26.238 +
  26.239 +	// and return the sub-hierarchy we built here
  26.240 +	return node;
  26.241 +}
  26.242 +
  26.243 +// ------------------------------------------------------------------------------------------------
  26.244 +// Reads an end node and returns the created node.
  26.245 +aiNode* BVHLoader::ReadEndSite( const std::string& pParentName)
  26.246 +{
  26.247 +	// check opening brace
  26.248 +	std::string openBrace = GetNextToken();
  26.249 +	if( openBrace != "{")
  26.250 +		ThrowException( boost::str( boost::format( "Expected opening brace \"{\", but found \"%s\".") % openBrace));
  26.251 +
  26.252 +	// Create a node
  26.253 +	aiNode* node = new aiNode( "EndSite_" + pParentName);
  26.254 +
  26.255 +	// now read the node's contents. Only possible entry is "OFFSET"
  26.256 +	while( 1)
  26.257 +	{
  26.258 +		std::string token = GetNextToken();
  26.259 +
  26.260 +		// end node's offset
  26.261 +		if( token == "OFFSET")
  26.262 +		{
  26.263 +			ReadNodeOffset( node);
  26.264 +		} 
  26.265 +		else if( token == "}")
  26.266 +		{
  26.267 +			// we're done with the end node
  26.268 +			break;
  26.269 +		} else
  26.270 +		{
  26.271 +			// everything else is a parse error
  26.272 +			ThrowException( boost::str( boost::format( "Unknown keyword \"%s\".") % token));
  26.273 +		}
  26.274 +	}
  26.275 +
  26.276 +	// and return the sub-hierarchy we built here
  26.277 +	return node;
  26.278 +}
  26.279 +// ------------------------------------------------------------------------------------------------
  26.280 +// Reads a node offset for the given node
  26.281 +void BVHLoader::ReadNodeOffset( aiNode* pNode)
  26.282 +{
  26.283 +	// Offset consists of three floats to read
  26.284 +	aiVector3D offset;
  26.285 +	offset.x = GetNextTokenAsFloat();
  26.286 +	offset.y = GetNextTokenAsFloat();
  26.287 +	offset.z = GetNextTokenAsFloat();
  26.288 +
  26.289 +	// build a transformation matrix from it
  26.290 +	pNode->mTransformation = aiMatrix4x4( 1.0f, 0.0f, 0.0f, offset.x, 0.0f, 1.0f, 0.0f, offset.y,
  26.291 +		0.0f, 0.0f, 1.0f, offset.z, 0.0f, 0.0f, 0.0f, 1.0f);
  26.292 +}
  26.293 +
  26.294 +// ------------------------------------------------------------------------------------------------
  26.295 +// Reads the animation channels for the given node
  26.296 +void BVHLoader::ReadNodeChannels( BVHLoader::Node& pNode)
  26.297 +{
  26.298 +	// number of channels. Use the float reader because we're lazy
  26.299 +	float numChannelsFloat = GetNextTokenAsFloat();
  26.300 +	unsigned int numChannels = (unsigned int) numChannelsFloat;
  26.301 +
  26.302 +	for( unsigned int a = 0; a < numChannels; a++)
  26.303 +	{
  26.304 +		std::string channelToken = GetNextToken();
  26.305 +
  26.306 +		if( channelToken == "Xposition")
  26.307 +			pNode.mChannels.push_back( Channel_PositionX);
  26.308 +		else if( channelToken == "Yposition")
  26.309 +			pNode.mChannels.push_back( Channel_PositionY);
  26.310 +		else if( channelToken == "Zposition")
  26.311 +			pNode.mChannels.push_back( Channel_PositionZ);
  26.312 +		else if( channelToken == "Xrotation")
  26.313 +			pNode.mChannels.push_back( Channel_RotationX);
  26.314 +		else if( channelToken == "Yrotation")
  26.315 +			pNode.mChannels.push_back( Channel_RotationY);
  26.316 +		else if( channelToken == "Zrotation")
  26.317 +			pNode.mChannels.push_back( Channel_RotationZ);
  26.318 +		else
  26.319 +			ThrowException( boost::str( boost::format( "Invalid channel specifier \"%s\".") % channelToken));
  26.320 +	}
  26.321 +}
  26.322 +
  26.323 +// ------------------------------------------------------------------------------------------------
  26.324 +// Reads the motion data
  26.325 +void BVHLoader::ReadMotion( aiScene* /*pScene*/)
  26.326 +{
  26.327 +	// Read number of frames
  26.328 +	std::string tokenFrames = GetNextToken();
  26.329 +	if( tokenFrames != "Frames:")
  26.330 +		ThrowException( boost::str( boost::format( "Expected frame count \"Frames:\", but found \"%s\".") % tokenFrames));
  26.331 +
  26.332 +	float numFramesFloat = GetNextTokenAsFloat();
  26.333 +	mAnimNumFrames = (unsigned int) numFramesFloat;
  26.334 +
  26.335 +	// Read frame duration
  26.336 +	std::string tokenDuration1 = GetNextToken();
  26.337 +	std::string tokenDuration2 = GetNextToken();
  26.338 +	if( tokenDuration1 != "Frame" || tokenDuration2 != "Time:")
  26.339 +		ThrowException( boost::str( boost::format( "Expected frame duration \"Frame Time:\", but found \"%s %s\".") % tokenDuration1 % tokenDuration2));
  26.340 +
  26.341 +	mAnimTickDuration = GetNextTokenAsFloat();
  26.342 +
  26.343 +	// resize value vectors for each node
  26.344 +	for( std::vector<Node>::iterator it = mNodes.begin(); it != mNodes.end(); ++it)
  26.345 +		it->mChannelValues.reserve( it->mChannels.size() * mAnimNumFrames);
  26.346 +
  26.347 +	// now read all the data and store it in the corresponding node's value vector
  26.348 +	for( unsigned int frame = 0; frame < mAnimNumFrames; ++frame)
  26.349 +	{
  26.350 +		// on each line read the values for all nodes
  26.351 +		for( std::vector<Node>::iterator it = mNodes.begin(); it != mNodes.end(); ++it)
  26.352 +		{
  26.353 +			// get as many values as the node has channels
  26.354 +			for( unsigned int c = 0; c < it->mChannels.size(); ++c)
  26.355 +				it->mChannelValues.push_back( GetNextTokenAsFloat());
  26.356 +		}
  26.357 +
  26.358 +		// after one frame worth of values for all nodes there should be a newline, but we better don't rely on it
  26.359 +	}
  26.360 +}
  26.361 +
  26.362 +// ------------------------------------------------------------------------------------------------
  26.363 +// Retrieves the next token
  26.364 +std::string BVHLoader::GetNextToken()
  26.365 +{
  26.366 +	// skip any preceeding whitespace
  26.367 +	while( mReader != mBuffer.end())
  26.368 +	{
  26.369 +		if( !isspace( *mReader))
  26.370 +			break;
  26.371 +
  26.372 +		// count lines
  26.373 +		if( *mReader == '\n')
  26.374 +			mLine++;
  26.375 +
  26.376 +		++mReader;
  26.377 +	}
  26.378 +
  26.379 +	// collect all chars till the next whitespace. BVH is easy in respect to that.
  26.380 +	std::string token;
  26.381 +	while( mReader != mBuffer.end())
  26.382 +	{
  26.383 +		if( isspace( *mReader))
  26.384 +			break;
  26.385 +
  26.386 +		token.push_back( *mReader);
  26.387 +		++mReader;
  26.388 +
  26.389 +		// little extra logic to make sure braces are counted correctly
  26.390 +		if( token == "{" || token == "}")
  26.391 +			break;
  26.392 +	}
  26.393 +
  26.394 +	// empty token means end of file, which is just fine
  26.395 +	return token;
  26.396 +}
  26.397 +
  26.398 +// ------------------------------------------------------------------------------------------------
  26.399 +// Reads the next token as a float
  26.400 +float BVHLoader::GetNextTokenAsFloat()
  26.401 +{
  26.402 +	std::string token = GetNextToken();
  26.403 +	if( token.empty())
  26.404 +		ThrowException( "Unexpected end of file while trying to read a float");
  26.405 +
  26.406 +	// check if the float is valid by testing if the atof() function consumed every char of the token
  26.407 +	const char* ctoken = token.c_str();
  26.408 +	float result = 0.0f;
  26.409 +	ctoken = fast_atoreal_move<float>( ctoken, result);
  26.410 +
  26.411 +	if( ctoken != token.c_str() + token.length())
  26.412 +		ThrowException( boost::str( boost::format( "Expected a floating point number, but found \"%s\".") % token));
  26.413 +
  26.414 +	return result;
  26.415 +}
  26.416 +
  26.417 +// ------------------------------------------------------------------------------------------------
  26.418 +// Aborts the file reading with an exception
  26.419 +void BVHLoader::ThrowException( const std::string& pError)
  26.420 +{
  26.421 +	throw DeadlyImportError( boost::str( boost::format( "%s:%d - %s") % mFileName % mLine % pError));
  26.422 +}
  26.423 +
  26.424 +// ------------------------------------------------------------------------------------------------
  26.425 +// Constructs an animation for the motion data and stores it in the given scene
  26.426 +void BVHLoader::CreateAnimation( aiScene* pScene)
  26.427 +{
  26.428 +	// create the animation
  26.429 +	pScene->mNumAnimations = 1;
  26.430 +	pScene->mAnimations = new aiAnimation*[1];
  26.431 +	aiAnimation* anim = new aiAnimation;
  26.432 +	pScene->mAnimations[0] = anim;
  26.433 +
  26.434 +	// put down the basic parameters
  26.435 +	anim->mName.Set( "Motion");
  26.436 +	anim->mTicksPerSecond = 1.0 / double( mAnimTickDuration);
  26.437 +	anim->mDuration = double( mAnimNumFrames - 1);
  26.438 +
  26.439 +	// now generate the tracks for all nodes
  26.440 +	anim->mNumChannels = mNodes.size();
  26.441 +	anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
  26.442 +
  26.443 +	// FIX: set the array elements to NULL to ensure proper deletion if an exception is thrown
  26.444 +	for (unsigned int i = 0; i < anim->mNumChannels;++i)
  26.445 +		anim->mChannels[i] = NULL;
  26.446 +
  26.447 +	for( unsigned int a = 0; a < anim->mNumChannels; a++)
  26.448 +	{
  26.449 +		const Node& node = mNodes[a];
  26.450 +		const std::string nodeName = std::string( node.mNode->mName.data );
  26.451 +		aiNodeAnim* nodeAnim = new aiNodeAnim;
  26.452 +		anim->mChannels[a] = nodeAnim;
  26.453 +		nodeAnim->mNodeName.Set( nodeName);
  26.454 +
  26.455 +		// translational part, if given
  26.456 +		if( node.mChannels.size() == 6)
  26.457 +		{
  26.458 +			nodeAnim->mNumPositionKeys = mAnimNumFrames;
  26.459 +			nodeAnim->mPositionKeys = new aiVectorKey[mAnimNumFrames];
  26.460 +			aiVectorKey* poskey = nodeAnim->mPositionKeys;
  26.461 +			for( unsigned int fr = 0; fr < mAnimNumFrames; ++fr)
  26.462 +			{
  26.463 +				poskey->mTime = double( fr);
  26.464 +
  26.465 +				// Now compute all translations in the right order
  26.466 +				for( unsigned int channel = 0; channel < 3; ++channel)
  26.467 +				{
  26.468 +					switch( node.mChannels[channel])
  26.469 +					{	
  26.470 +					case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
  26.471 +					case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
  26.472 +					case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
  26.473 +					default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
  26.474 +					}
  26.475 +				}
  26.476 +				++poskey;
  26.477 +			}
  26.478 +		} else
  26.479 +		{
  26.480 +			// if no translation part is given, put a default sequence
  26.481 +			aiVector3D nodePos( node.mNode->mTransformation.a4, node.mNode->mTransformation.b4, node.mNode->mTransformation.c4);
  26.482 +			nodeAnim->mNumPositionKeys = 1;
  26.483 +			nodeAnim->mPositionKeys = new aiVectorKey[1];
  26.484 +			nodeAnim->mPositionKeys[0].mTime = 0.0;
  26.485 +			nodeAnim->mPositionKeys[0].mValue = nodePos;
  26.486 +		}
  26.487 +
  26.488 +		// rotation part. Always present. First find value offsets
  26.489 +		{
  26.490 +			unsigned int rotOffset  = 0;
  26.491 +			if( node.mChannels.size() == 6)
  26.492 +			{
  26.493 +				// Offset all further calculations
  26.494 +				rotOffset = 3;
  26.495 +			} 
  26.496 +
  26.497 +			// Then create the number of rotation keys
  26.498 +			nodeAnim->mNumRotationKeys = mAnimNumFrames;
  26.499 +			nodeAnim->mRotationKeys = new aiQuatKey[mAnimNumFrames];
  26.500 +			aiQuatKey* rotkey = nodeAnim->mRotationKeys;
  26.501 +			for( unsigned int fr = 0; fr < mAnimNumFrames; ++fr)
  26.502 +			{
  26.503 +				aiMatrix4x4 temp;
  26.504 +				aiMatrix3x3 rotMatrix;
  26.505 +
  26.506 +				for( unsigned int channel = 0; channel < 3; ++channel)
  26.507 +				{
  26.508 +					// translate ZXY euler angels into a quaternion
  26.509 +					const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
  26.510 +
  26.511 +					// Compute rotation transformations in the right order
  26.512 +					switch (node.mChannels[rotOffset+channel]) 
  26.513 +					{
  26.514 +					case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
  26.515 +					case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp);	break;
  26.516 +					case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
  26.517 +					default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
  26.518 +					}
  26.519 +				}
  26.520 +
  26.521 +				rotkey->mTime = double( fr);
  26.522 +				rotkey->mValue = aiQuaternion( rotMatrix);
  26.523 +				++rotkey;
  26.524 +			}
  26.525 +		}
  26.526 +
  26.527 +		// scaling part. Always just a default track
  26.528 +		{
  26.529 +			nodeAnim->mNumScalingKeys = 1;
  26.530 +			nodeAnim->mScalingKeys = new aiVectorKey[1];
  26.531 +			nodeAnim->mScalingKeys[0].mTime = 0.0;
  26.532 +			nodeAnim->mScalingKeys[0].mValue.Set( 1.0f, 1.0f, 1.0f);
  26.533 +		}
  26.534 +	}
  26.535 +}
  26.536 +
  26.537 +#endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/libs/assimp/BVHLoader.h	Sat Feb 01 19:58:19 2014 +0200
    27.3 @@ -0,0 +1,169 @@
    27.4 +/** Defines the BHV motion capturing loader class */
    27.5 +
    27.6 +/*
    27.7 +Open Asset Import Library (assimp)
    27.8 +----------------------------------------------------------------------
    27.9 +
   27.10 +Copyright (c) 2006-2012, assimp team
   27.11 +All rights reserved.
   27.12 +
   27.13 +Redistribution and use of this software in source and binary forms, 
   27.14 +with or without modification, are permitted provided that the 
   27.15 +following conditions are met:
   27.16 +
   27.17 +* Redistributions of source code must retain the above
   27.18 +copyright notice, this list of conditions and the
   27.19 +following disclaimer.
   27.20 +
   27.21 +* Redistributions in binary form must reproduce the above
   27.22 +copyright notice, this list of conditions and the
   27.23 +following disclaimer in the documentation and/or other
   27.24 +materials provided with the distribution.
   27.25 +
   27.26 +* Neither the name of the assimp team, nor the names of its
   27.27 +contributors may be used to endorse or promote products
   27.28 +derived from this software without specific prior
   27.29 +written permission of the assimp team.
   27.30 +
   27.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   27.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   27.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   27.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   27.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   27.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   27.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   27.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   27.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   27.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27.42 +
   27.43 +----------------------------------------------------------------------
   27.44 +*/
   27.45 +
   27.46 +/** @file BVHLoader.h
   27.47 + *  @brief Biovision BVH import
   27.48 + */
   27.49 +
   27.50 +#ifndef AI_BVHLOADER_H_INC
   27.51 +#define AI_BVHLOADER_H_INC
   27.52 +
   27.53 +#include "BaseImporter.h"
   27.54 +
   27.55 +namespace Assimp
   27.56 +{
   27.57 +
   27.58 +// --------------------------------------------------------------------------------
   27.59 +/** Loader class to read Motion Capturing data from a .bvh file. 
   27.60 + *
   27.61 + * This format only contains a hierarchy of joints and a series of keyframes for
   27.62 + * the hierarchy. It contains no actual mesh data, but we generate a dummy mesh
   27.63 + * inside the loader just to be able to see something.
   27.64 +*/
   27.65 +class BVHLoader : public BaseImporter
   27.66 +{
   27.67 +
   27.68 +	/** Possible animation channels for which the motion data holds the values */
   27.69 +	enum ChannelType
   27.70 +	{
   27.71 +		Channel_PositionX,
   27.72 +		Channel_PositionY,
   27.73 +		Channel_PositionZ,
   27.74 +		Channel_RotationX,
   27.75 +		Channel_RotationY,
   27.76 +		Channel_RotationZ
   27.77 +	};
   27.78 +
   27.79 +	/** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */
   27.80 +	struct Node
   27.81 +	{
   27.82 +		const aiNode* mNode;
   27.83 +		std::vector<ChannelType> mChannels;
   27.84 +		std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
   27.85 +
   27.86 +		Node() { }
   27.87 +		Node( const aiNode* pNode) : mNode( pNode) { }
   27.88 +	};
   27.89 +
   27.90 +public:
   27.91 +
   27.92 +	BVHLoader();
   27.93 +	~BVHLoader();
   27.94 +
   27.95 +public:
   27.96 +	/** Returns whether the class can handle the format of the given file. 
   27.97 +	 * See BaseImporter::CanRead() for details.	*/
   27.98 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const;
   27.99 +
  27.100 +	void SetupProperties(const Importer* pImp);
  27.101 +	const aiImporterDesc* GetInfo () const;
  27.102 +
  27.103 +protected:
  27.104 +
  27.105 +
  27.106 +	/** Imports the given file into the given scene structure. 
  27.107 +	 * See BaseImporter::InternReadFile() for details
  27.108 +	 */
  27.109 +	void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
  27.110 +
  27.111 +protected:
  27.112 +	/** Reads the file */
  27.113 +	void ReadStructure( aiScene* pScene);
  27.114 +
  27.115 +	/** Reads the hierarchy */
  27.116 +	void ReadHierarchy( aiScene* pScene);
  27.117 +
  27.118 +	/** Reads a node and recursively its childs and returns the created node. */
  27.119 +	aiNode* ReadNode();
  27.120 +
  27.121 +	/** Reads an end node and returns the created node. */
  27.122 +	aiNode* ReadEndSite( const std::string& pParentName);
  27.123 +
  27.124 +	/** Reads a node offset for the given node */
  27.125 +	void ReadNodeOffset( aiNode* pNode);
  27.126 +
  27.127 +	/** Reads the animation channels into the given node */
  27.128 +	void ReadNodeChannels( BVHLoader::Node& pNode);
  27.129 +
  27.130 +	/** Reads the motion data */
  27.131 +	void ReadMotion( aiScene* pScene);
  27.132 +
  27.133 +	/** Retrieves the next token */
  27.134 +	std::string GetNextToken();
  27.135 +
  27.136 +	/** Reads the next token as a float */
  27.137 +	float GetNextTokenAsFloat();
  27.138 +
  27.139 +	/** Aborts the file reading with an exception */
  27.140 +	void ThrowException( const std::string& pError);
  27.141 +
  27.142 +	/** Constructs an animation for the motion data and stores it in the given scene */
  27.143 +	void CreateAnimation( aiScene* pScene);
  27.144 +
  27.145 +protected:
  27.146 +	/** Filename, for a verbose error message */
  27.147 +	std::string mFileName;
  27.148 +
  27.149 +	/** Buffer to hold the loaded file */
  27.150 +	std::vector<char> mBuffer;
  27.151 +
  27.152 +	/** Next char to read from the buffer */
  27.153 +	std::vector<char>::const_iterator mReader;
  27.154 +
  27.155 +	/** Current line, for error messages */
  27.156 +	unsigned int mLine;
  27.157 +
  27.158 +	/** Collected list of nodes. Will be bones of the dummy mesh some day, addressed by their array index.
  27.159 +	* Also contain the motion data for the node's channels
  27.160 +	*/
  27.161 +	std::vector<Node> mNodes;
  27.162 +
  27.163 +	/** basic Animation parameters */
  27.164 +	float mAnimTickDuration;
  27.165 +	unsigned int mAnimNumFrames;
  27.166 +
  27.167 +	bool noSkeletonMesh;
  27.168 +};
  27.169 +
  27.170 +} // end of namespace Assimp
  27.171 +
  27.172 +#endif // AI_BVHLOADER_H_INC
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/libs/assimp/BaseImporter.cpp	Sat Feb 01 19:58:19 2014 +0200
    28.3 @@ -0,0 +1,560 @@
    28.4 +/*
    28.5 +---------------------------------------------------------------------------
    28.6 +Open Asset Import Library (assimp)
    28.7 +---------------------------------------------------------------------------
    28.8 +
    28.9 +Copyright (c) 2006-2012, assimp team
   28.10 +
   28.11 +All rights reserved.
   28.12 +
   28.13 +Redistribution and use of this software in source and binary forms, 
   28.14 +with or without modification, are permitted provided that the following 
   28.15 +conditions are met:
   28.16 +
   28.17 +* Redistributions of source code must retain the above
   28.18 +  copyright notice, this list of conditions and the
   28.19 +  following disclaimer.
   28.20 +
   28.21 +* Redistributions in binary form must reproduce the above
   28.22 +  copyright notice, this list of conditions and the
   28.23 +  following disclaimer in the documentation and/or other
   28.24 +  materials provided with the distribution.
   28.25 +
   28.26 +* Neither the name of the assimp team, nor the names of its
   28.27 +  contributors may be used to endorse or promote products
   28.28 +  derived from this software without specific prior
   28.29 +  written permission of the assimp team.
   28.30 +
   28.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   28.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   28.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   28.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   28.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   28.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   28.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   28.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   28.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   28.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   28.42 +---------------------------------------------------------------------------
   28.43 +*/
   28.44 +
   28.45 +/** @file  BaseImporter.cpp
   28.46 + *  @brief Implementation of BaseImporter 
   28.47 + */
   28.48 +
   28.49 +#include "AssimpPCH.h"
   28.50 +#include "BaseImporter.h"
   28.51 +#include "FileSystemFilter.h"
   28.52 +
   28.53 +#include "Importer.h"
   28.54 +
   28.55 +using namespace Assimp;
   28.56 +
   28.57 +// ------------------------------------------------------------------------------------------------
   28.58 +// Constructor to be privately used by Importer
   28.59 +BaseImporter::BaseImporter()
   28.60 +: progress()
   28.61 +{
   28.62 +	// nothing to do here
   28.63 +}
   28.64 +
   28.65 +// ------------------------------------------------------------------------------------------------
   28.66 +// Destructor, private as well
   28.67 +BaseImporter::~BaseImporter()
   28.68 +{
   28.69 +	// nothing to do here
   28.70 +}
   28.71 +
   28.72 +// ------------------------------------------------------------------------------------------------
   28.73 +// Imports the given file and returns the imported data.
   28.74 +aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler)
   28.75 +{
   28.76 +	progress = pImp->GetProgressHandler();
   28.77 +	ai_assert(progress);
   28.78 +
   28.79 +	// Gather configuration properties for this run
   28.80 +	SetupProperties( pImp );
   28.81 +
   28.82 +	// Construct a file system filter to improve our success ratio at reading external files
   28.83 +	FileSystemFilter filter(pFile,pIOHandler);
   28.84 +
   28.85 +	// create a scene object to hold the data
   28.86 +	ScopeGuard<aiScene> sc(new aiScene());
   28.87 +
   28.88 +	// dispatch importing
   28.89 +	try
   28.90 +	{
   28.91 +		InternReadFile( pFile, sc, &filter);
   28.92 +
   28.93 +	} catch( const std::exception& err )	{
   28.94 +		// extract error description
   28.95 +		mErrorText = err.what();
   28.96 +		DefaultLogger::get()->error(mErrorText);
   28.97 +		return NULL;
   28.98 +	}
   28.99 +
  28.100 +	// return what we gathered from the import. 
  28.101 +	sc.dismiss();
  28.102 +	return sc;
  28.103 +}
  28.104 +
  28.105 +// ------------------------------------------------------------------------------------------------
  28.106 +void BaseImporter::SetupProperties(const Importer* /*pImp*/)
  28.107 +{
  28.108 +	// the default implementation does nothing
  28.109 +}
  28.110 +
  28.111 +// ------------------------------------------------------------------------------------------------
  28.112 +void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
  28.113 +{
  28.114 +	const aiImporterDesc* desc = GetInfo();
  28.115 +	ai_assert(desc != NULL);
  28.116 +
  28.117 +	const char* ext = desc->mFileExtensions;
  28.118 +	ai_assert(ext != NULL);
  28.119 +
  28.120 +	const char* last = ext;
  28.121 +	do {
  28.122 +		if (!*ext || *ext == ' ') {
  28.123 +			extensions.insert(std::string(last,ext-last));
  28.124 +			ai_assert(ext-last > 0);
  28.125 +			last = ext;
  28.126 +			while(*last == ' ') {
  28.127 +				++last;
  28.128 +			}
  28.129 +		}
  28.130 +	}
  28.131 +	while(*ext++);
  28.132 +}
  28.133 +
  28.134 +// ------------------------------------------------------------------------------------------------
  28.135 +/*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler,
  28.136 +	const std::string&	pFile,
  28.137 +	const char**		tokens, 
  28.138 +	unsigned int		numTokens,
  28.139 +	unsigned int		searchBytes /* = 200 */,
  28.140 +	bool				tokensSol /* false */)
  28.141 +{
  28.142 +	ai_assert(NULL != tokens && 0 != numTokens && 0 != searchBytes);
  28.143 +	if (!pIOHandler)
  28.144 +		return false;
  28.145 +
  28.146 +	boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
  28.147 +	if (pStream.get() )	{
  28.148 +		// read 200 characters from the file
  28.149 +		boost::scoped_array<char> _buffer (new char[searchBytes+1 /* for the '\0' */]);
  28.150 +		char* buffer = _buffer.get();
  28.151 +
  28.152 +		const unsigned int read = pStream->Read(buffer,1,searchBytes);
  28.153 +		if (!read)
  28.154 +			return false;
  28.155 +
  28.156 +		for (unsigned int i = 0; i < read;++i)
  28.157 +			buffer[i] = ::tolower(buffer[i]);
  28.158 +
  28.159 +		// It is not a proper handling of unicode files here ...
  28.160 +		// ehm ... but it works in most cases.
  28.161 +		char* cur = buffer,*cur2 = buffer,*end = &buffer[read];
  28.162 +		while (cur != end)	{
  28.163 +			if (*cur)
  28.164 +				*cur2++ = *cur;
  28.165 +			++cur;
  28.166 +		}
  28.167 +		*cur2 = '\0';
  28.168 +
  28.169 +		for (unsigned int i = 0; i < numTokens;++i)	{
  28.170 +			ai_assert(NULL != tokens[i]);
  28.171 +
  28.172 +
  28.173 +			const char* r = strstr(buffer,tokens[i]);
  28.174 +			if (!r) 
  28.175 +				continue;
  28.176 +			// We got a match, either we don't care where it is, or it happens to
  28.177 +			// be in the beginning of the file / line
  28.178 +			if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
  28.179 +				DefaultLogger::get()->debug(std::string("Found positive match for header keyword: ") + tokens[i]);
  28.180 +				return true;
  28.181 +			}
  28.182 +		}
  28.183 +	}
  28.184 +	return false;
  28.185 +}
  28.186 +
  28.187 +// ------------------------------------------------------------------------------------------------
  28.188 +// Simple check for file extension
  28.189 +/*static*/ bool BaseImporter::SimpleExtensionCheck (const std::string& pFile, 
  28.190 +	const char* ext0,
  28.191 +	const char* ext1,
  28.192 +	const char* ext2)
  28.193 +{
  28.194 +	std::string::size_type pos = pFile.find_last_of('.');
  28.195 +
  28.196 +	// no file extension - can't read
  28.197 +	if( pos == std::string::npos)
  28.198 +		return false;
  28.199 +	
  28.200 +	const char* ext_real = & pFile[ pos+1 ];
  28.201 +	if( !ASSIMP_stricmp(ext_real,ext0) )
  28.202 +		return true;
  28.203 +
  28.204 +	// check for other, optional, file extensions
  28.205 +	if (ext1 && !ASSIMP_stricmp(ext_real,ext1))
  28.206 +		return true;
  28.207 +
  28.208 +	if (ext2 && !ASSIMP_stricmp(ext_real,ext2))
  28.209 +		return true;
  28.210 +
  28.211 +	return false;
  28.212 +}
  28.213 +
  28.214 +// ------------------------------------------------------------------------------------------------
  28.215 +// Get file extension from path
  28.216 +/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile)
  28.217 +{
  28.218 +	std::string::size_type pos = pFile.find_last_of('.');
  28.219 +
  28.220 +	// no file extension at all
  28.221 +	if( pos == std::string::npos)
  28.222 +		return "";
  28.223 +
  28.224 +	std::string ret = pFile.substr(pos+1);
  28.225 +	std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
  28.226 +	return ret;
  28.227 +}
  28.228 +
  28.229 +// ------------------------------------------------------------------------------------------------
  28.230 +// Check for magic bytes at the beginning of the file.
  28.231 +/* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile, 
  28.232 +	const void* _magic, unsigned int num, unsigned int offset, unsigned int size)
  28.233 +{
  28.234 +	ai_assert(size <= 16 && _magic);
  28.235 +
  28.236 +	if (!pIOHandler) {
  28.237 +		return false;
  28.238 +	}
  28.239 +	union {
  28.240 +		const char* magic;
  28.241 +		const uint16_t* magic_u16;
  28.242 +		const uint32_t* magic_u32;
  28.243 +	};
  28.244 +	magic = reinterpret_cast<const char*>(_magic);
  28.245 +	boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
  28.246 +	if (pStream.get() )	{
  28.247 +
  28.248 +		// skip to offset
  28.249 +		pStream->Seek(offset,aiOrigin_SET);
  28.250 +
  28.251 +		// read 'size' characters from the file
  28.252 +		union {
  28.253 +			char data[16];
  28.254 +			uint16_t data_u16[8];
  28.255 +			uint32_t data_u32[4];
  28.256 +		};
  28.257 +		if(size != pStream->Read(data,1,size)) {
  28.258 +			return false;
  28.259 +		}
  28.260 +
  28.261 +		for (unsigned int i = 0; i < num; ++i) {
  28.262 +			// also check against big endian versions of tokens with size 2,4
  28.263 +			// that's just for convinience, the chance that we cause conflicts
  28.264 +			// is quite low and it can save some lines and prevent nasty bugs
  28.265 +			if (2 == size) {
  28.266 +				uint16_t rev = *magic_u16; 
  28.267 +				ByteSwap::Swap(&rev);
  28.268 +				if (data_u16[0] == *magic_u16 || data_u16[0] == rev) {
  28.269 +					return true;
  28.270 +				}
  28.271 +			}
  28.272 +			else if (4 == size) {
  28.273 +				uint32_t rev = *magic_u32;
  28.274 +				ByteSwap::Swap(&rev);
  28.275 +				if (data_u32[0] == *magic_u32 || data_u32[0] == rev) {
  28.276 +					return true;
  28.277 +				}
  28.278 +			}
  28.279 +			else {
  28.280 +				// any length ... just compare
  28.281 +				if(!memcmp(magic,data,size)) {
  28.282 +					return true;
  28.283 +				}
  28.284 +			}
  28.285 +			magic += size;
  28.286 +		}
  28.287 +	}
  28.288 +	return false;
  28.289 +}
  28.290 +
  28.291 +#include "ConvertUTF/ConvertUTF.h"
  28.292 +
  28.293 +// ------------------------------------------------------------------------------------------------
  28.294 +void ReportResult(ConversionResult res)
  28.295 +{
  28.296 +	if(res == sourceExhausted) {
  28.297 +		DefaultLogger::get()->error("Source ends with incomplete character sequence, transformation to UTF-8 fails");
  28.298 +	}
  28.299 +	else if(res == sourceIllegal) {
  28.300 +		DefaultLogger::get()->error("Source contains illegal character sequence, transformation to UTF-8 fails");
  28.301 +	}
  28.302 +}
  28.303 +
  28.304 +// ------------------------------------------------------------------------------------------------
  28.305 +// Convert to UTF8 data
  28.306 +void BaseImporter::ConvertToUTF8(std::vector<char>& data)
  28.307 +{
  28.308 +	ConversionResult result;
  28.309 +	if(data.size() < 8) {
  28.310 +		throw DeadlyImportError("File is too small");
  28.311 +	}
  28.312 +
  28.313 +	// UTF 8 with BOM
  28.314 +	if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) {
  28.315 +		DefaultLogger::get()->debug("Found UTF-8 BOM ...");
  28.316 +
  28.317 +		std::copy(data.begin()+3,data.end(),data.begin());
  28.318 +		data.resize(data.size()-3);
  28.319 +		return;
  28.320 +	}
  28.321 +
  28.322 +	// UTF 32 BE with BOM
  28.323 +	if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
  28.324 +	
  28.325 +		// swap the endianess ..
  28.326 +		for(uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) {
  28.327 +			AI_SWAP4P(p);
  28.328 +		}
  28.329 +	}
  28.330 +	
  28.331 +	// UTF 32 LE with BOM
  28.332 +	if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
  28.333 +		DefaultLogger::get()->debug("Found UTF-32 BOM ...");
  28.334 +
  28.335 +		const uint32_t* sstart = (uint32_t*)&data.front()+1, *send = (uint32_t*)&data.back()+1;
  28.336 +		char* dstart,*dend;
  28.337 +		std::vector<char> output;
  28.338 +		do {
  28.339 +			output.resize(output.size()?output.size()*3/2:data.size()/2);
  28.340 +			dstart = &output.front(),dend = &output.back()+1;
  28.341 +
  28.342 +			result = ConvertUTF32toUTF8((const UTF32**)&sstart,(const UTF32*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
  28.343 +		} while(result == targetExhausted);
  28.344 +
  28.345 +		ReportResult(result);
  28.346 +
  28.347 +		// copy to output buffer. 
  28.348 +		const size_t outlen = (size_t)(dstart-&output.front());
  28.349 +		data.assign(output.begin(),output.begin()+outlen);
  28.350 +		return;
  28.351 +	}
  28.352 +
  28.353 +	// UTF 16 BE with BOM
  28.354 +	if(*((uint16_t*)&data.front()) == 0xFFFE) {
  28.355 +	
  28.356 +		// swap the endianess ..
  28.357 +		for(uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) {
  28.358 +			ByteSwap::Swap2(p);
  28.359 +		}
  28.360 +	}
  28.361 +	
  28.362 +	// UTF 16 LE with BOM
  28.363 +	if(*((uint16_t*)&data.front()) == 0xFEFF) {
  28.364 +		DefaultLogger::get()->debug("Found UTF-16 BOM ...");
  28.365 +
  28.366 +		const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)(&data.back()+1);
  28.367 +		char* dstart,*dend;
  28.368 +		std::vector<char> output;
  28.369 +		do {
  28.370 +			output.resize(output.size()?output.size()*3/2:data.size()*3/4);
  28.371 +			dstart = &output.front(),dend = &output.back()+1;
  28.372 +
  28.373 +			result = ConvertUTF16toUTF8((const UTF16**)&sstart,(const UTF16*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
  28.374 +		} while(result == targetExhausted);
  28.375 +
  28.376 +		ReportResult(result);
  28.377 +
  28.378 +		// copy to output buffer.
  28.379 +		const size_t outlen = (size_t)(dstart-&output.front());
  28.380 +		data.assign(output.begin(),output.begin()+outlen);
  28.381 +		return;
  28.382 +	}
  28.383 +}
  28.384 +
  28.385 +// ------------------------------------------------------------------------------------------------
  28.386 +void BaseImporter::TextFileToBuffer(IOStream* stream,
  28.387 +	std::vector<char>& data)
  28.388 +{
  28.389 +	ai_assert(NULL != stream);
  28.390 +
  28.391 +	const size_t fileSize = stream->FileSize();
  28.392 +	if(!fileSize) {
  28.393 +		throw DeadlyImportError("File is empty");
  28.394 +	}
  28.395 +
  28.396 +	data.reserve(fileSize+1); 
  28.397 +	data.resize(fileSize); 
  28.398 +	if(fileSize != stream->Read( &data[0], 1, fileSize)) {
  28.399 +		throw DeadlyImportError("File read error");
  28.400 +	}
  28.401 +
  28.402 +	ConvertToUTF8(data);
  28.403 +
  28.404 +	// append a binary zero to simplify string parsing
  28.405 +	data.push_back(0);
  28.406 +}
  28.407 +
  28.408 +// ------------------------------------------------------------------------------------------------
  28.409 +namespace Assimp
  28.410 +{
  28.411 +	// Represents an import request
  28.412 +	struct LoadRequest
  28.413 +	{
  28.414 +		LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id)
  28.415 +			: file(_file), flags(_flags), refCnt(1),scene(NULL), loaded(false), id(_id)
  28.416 +		{
  28.417 +			if (_map)
  28.418 +				map = *_map;
  28.419 +		}
  28.420 +
  28.421 +		const std::string file;
  28.422 +		unsigned int flags;
  28.423 +		unsigned int refCnt;
  28.424 +		aiScene* scene;
  28.425 +		bool loaded;
  28.426 +		BatchLoader::PropertyMap map;
  28.427 +		unsigned int id;
  28.428 +
  28.429 +		bool operator== (const std::string& f) {
  28.430 +			return file == f;
  28.431 +		}
  28.432 +	};
  28.433 +}
  28.434 +
  28.435 +// ------------------------------------------------------------------------------------------------
  28.436 +// BatchLoader::pimpl data structure
  28.437 +struct Assimp::BatchData
  28.438 +{
  28.439 +	BatchData()
  28.440 +		:	next_id(0xffff)
  28.441 +	{}
  28.442 +
  28.443 +	// IO system to be used for all imports
  28.444 +	IOSystem* pIOSystem;
  28.445 +
  28.446 +	// Importer used to load all meshes
  28.447 +	Importer* pImporter;
  28.448 +
  28.449 +	// List of all imports
  28.450 +	std::list<LoadRequest> requests;
  28.451 +
  28.452 +	// Base path
  28.453 +	std::string pathBase;
  28.454 +
  28.455 +	// Id for next item
  28.456 +	unsigned int next_id;
  28.457 +};
  28.458 +
  28.459 +// ------------------------------------------------------------------------------------------------
  28.460 +BatchLoader::BatchLoader(IOSystem* pIO)
  28.461 +{
  28.462 +	ai_assert(NULL != pIO);
  28.463 +
  28.464 +	data = new BatchData();
  28.465 +	data->pIOSystem = pIO;
  28.466 +
  28.467 +	data->pImporter = new Importer();
  28.468 +	data->pImporter->SetIOHandler(data->pIOSystem);
  28.469 +}
  28.470 +
  28.471 +// ------------------------------------------------------------------------------------------------
  28.472 +BatchLoader::~BatchLoader()
  28.473 +{
  28.474 +	// delete all scenes wthat have not been polled by the user
  28.475 +	for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it)	{
  28.476 +
  28.477 +		delete (*it).scene;
  28.478 +	}
  28.479 +	data->pImporter->SetIOHandler(NULL); /* get pointer back into our posession */
  28.480 +	delete data->pImporter;
  28.481 +	delete data;
  28.482 +}
  28.483 +
  28.484 +
  28.485 +// ------------------------------------------------------------------------------------------------
  28.486 +unsigned int BatchLoader::AddLoadRequest	(const std::string& file,
  28.487 +	unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
  28.488 +{
  28.489 +	ai_assert(!file.empty());
  28.490 +	
  28.491 +	// check whether we have this loading request already
  28.492 +	std::list<LoadRequest>::iterator it;
  28.493 +	for (it = data->requests.begin();it != data->requests.end(); ++it)	{
  28.494 +
  28.495 +		// Call IOSystem's path comparison function here
  28.496 +		if (data->pIOSystem->ComparePaths((*it).file,file))	{
  28.497 +
  28.498 +			if (map) {
  28.499 +				if (!((*it).map == *map))
  28.500 +					continue;
  28.501 +			}
  28.502 +			else if (!(*it).map.empty())
  28.503 +				continue;
  28.504 +
  28.505 +			(*it).refCnt++;
  28.506 +			return (*it).id;
  28.507 +		}
  28.508 +	}
  28.509 +
  28.510 +	// no, we don't have it. So add it to the queue ...
  28.511 +	data->requests.push_back(LoadRequest(file,steps,map,data->next_id));
  28.512 +	return data->next_id++;
  28.513 +}
  28.514 +
  28.515 +// ------------------------------------------------------------------------------------------------
  28.516 +aiScene* BatchLoader::GetImport		(unsigned int which)
  28.517 +{
  28.518 +	for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it)	{
  28.519 +
  28.520 +		if ((*it).id == which && (*it).loaded)	{
  28.521 +
  28.522 +			aiScene* sc = (*it).scene;
  28.523 +			if (!(--(*it).refCnt))	{
  28.524 +				data->requests.erase(it);
  28.525 +			}
  28.526 +			return sc;
  28.527 +		}
  28.528 +	}
  28.529 +	return NULL;
  28.530 +}
  28.531 +
  28.532 +// ------------------------------------------------------------------------------------------------
  28.533 +void BatchLoader::LoadAll()
  28.534 +{
  28.535 +	// no threaded implementation for the moment
  28.536 +	for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it)	{
  28.537 +		// force validation in debug builds
  28.538 +		unsigned int pp = (*it).flags;
  28.539 +#ifdef _DEBUG
  28.540 +		pp |= aiProcess_ValidateDataStructure;
  28.541 +#endif
  28.542 +		// setup config properties if necessary
  28.543 +		ImporterPimpl* pimpl = data->pImporter->Pimpl();
  28.544 +		pimpl->mFloatProperties  = (*it).map.floats;
  28.545 +		pimpl->mIntProperties    = (*it).map.ints;
  28.546 +		pimpl->mStringProperties = (*it).map.strings;
  28.547 +
  28.548 +		if (!DefaultLogger::isNullLogger())
  28.549 +		{
  28.550 +			DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
  28.551 +			DefaultLogger::get()->info("File: " + (*it).file);
  28.552 +		}
  28.553 +		data->pImporter->ReadFile((*it).file,pp);
  28.554 +		(*it).scene = data->pImporter->GetOrphanedScene();
  28.555 +		(*it).loaded = true;
  28.556 +
  28.557 +		DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
  28.558 +	}
  28.559 +}
  28.560 +
  28.561 +
  28.562 +
  28.563 +
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/libs/assimp/BaseImporter.h	Sat Feb 01 19:58:19 2014 +0200
    29.3 @@ -0,0 +1,359 @@
    29.4 +/*
    29.5 +Open Asset Import Library (assimp)
    29.6 +----------------------------------------------------------------------
    29.7 +
    29.8 +Copyright (c) 2006-2012, assimp team
    29.9 +All rights reserved.
   29.10 +
   29.11 +Redistribution and use of this software in source and binary forms, 
   29.12 +with or without modification, are permitted provided that the 
   29.13 +following conditions are met:
   29.14 +
   29.15 +* Redistributions of source code must retain the above
   29.16 +  copyright notice, this list of conditions and the
   29.17 +  following disclaimer.
   29.18 +
   29.19 +* Redistributions in binary form must reproduce the above
   29.20 +  copyright notice, this list of conditions and the
   29.21 +  following disclaimer in the documentation and/or other
   29.22 +  materials provided with the distribution.
   29.23 +
   29.24 +* Neither the name of the assimp team, nor the names of its
   29.25 +  contributors may be used to endorse or promote products
   29.26 +  derived from this software without specific prior
   29.27 +  written permission of the assimp team.
   29.28 +
   29.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   29.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   29.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   29.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   29.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   29.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   29.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   29.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   29.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   29.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   29.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   29.40 +
   29.41 +----------------------------------------------------------------------
   29.42 +*/
   29.43 +
   29.44 +/** @file Definition of the base class for all importer worker classes. */
   29.45 +#ifndef INCLUDED_AI_BASEIMPORTER_H
   29.46 +#define INCLUDED_AI_BASEIMPORTER_H
   29.47 +
   29.48 +#include "Exceptional.h"
   29.49 +
   29.50 +#include <string>
   29.51 +#include <map>
   29.52 +#include <vector>
   29.53 +#include "assimp/types.h"
   29.54 +
   29.55 +struct aiScene;
   29.56 +
   29.57 +namespace Assimp	{
   29.58 +
   29.59 +class IOSystem;
   29.60 +class Importer;
   29.61 +class BaseImporter;
   29.62 +class BaseProcess;
   29.63 +class SharedPostProcessInfo;
   29.64 +class IOStream;
   29.65 +
   29.66 +// utility to do char4 to uint32 in a portable manner
   29.67 +#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
   29.68 +	(string[1] << 16) + (string[2] << 8) + string[3]))
   29.69 +
   29.70 +// ---------------------------------------------------------------------------
   29.71 +template <typename T>
   29.72 +struct ScopeGuard
   29.73 +{
   29.74 +	ScopeGuard(T* obj) : obj(obj), mdismiss() {}
   29.75 +	~ScopeGuard () throw() {
   29.76 +		if (!mdismiss) {
   29.77 +			delete obj;
   29.78 +		}
   29.79 +		obj = NULL;
   29.80 +	} 
   29.81 +
   29.82 +	T* dismiss() {
   29.83 +		mdismiss=true;
   29.84 +		return obj;
   29.85 +	}
   29.86 +
   29.87 +	operator T*() {
   29.88 +		return obj;
   29.89 +	}
   29.90 +
   29.91 +	T* operator -> () {
   29.92 +		return obj;
   29.93 +	}
   29.94 +
   29.95 +private:
   29.96 +	T* obj;
   29.97 +	bool mdismiss;
   29.98 +};
   29.99 +
  29.100 +
  29.101 +
  29.102 +// ---------------------------------------------------------------------------
  29.103 +/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface 
  29.104 + *  for all importer worker classes.
  29.105 + *
  29.106 + * The interface defines two functions: CanRead() is used to check if the 
  29.107 + * importer can handle the format of the given file. If an implementation of 
  29.108 + * this function returns true, the importer then calls ReadFile() which 
  29.109 + * imports the given file. ReadFile is not overridable, it just calls 
  29.110 + * InternReadFile() and catches any ImportErrorException that might occur.
  29.111 + */
  29.112 +class BaseImporter
  29.113 +{
  29.114 +	friend class Importer;
  29.115 +
  29.116 +public:
  29.117 +
  29.118 +	/** Constructor to be privately used by #Importer */
  29.119 +	BaseImporter();
  29.120 +
  29.121 +	/** Destructor, private as well */
  29.122 +	virtual ~BaseImporter();
  29.123 +
  29.124 +public:
  29.125 +	// -------------------------------------------------------------------
  29.126 +	/** Returns whether the class can handle the format of the given file.
  29.127 +	 *
  29.128 +	 * The implementation should be as quick as possible. A check for
  29.129 +	 * the file extension is enough. If no suitable loader is found with
  29.130 +	 * this strategy, CanRead() is called again, the 'checkSig' parameter
  29.131 +	 * set to true this time. Now the implementation is expected to
  29.132 +	 * perform a full check of the file structure, possibly searching the
  29.133 +	 * first bytes of the file for magic identifiers or keywords.
  29.134 +	 *
  29.135 +	 * @param pFile Path and file name of the file to be examined.
  29.136 +	 * @param pIOHandler The IO handler to use for accessing any file.
  29.137 +	 * @param checkSig Set to true if this method is called a second time.
  29.138 +	 *   This time, the implementation may take more time to examine the
  29.139 +	 *   contents of the file to be loaded for magic bytes, keywords, etc
  29.140 +	 *   to be able to load files with unknown/not existent file extensions.
  29.141 +	 * @return true if the class can read this file, false if not.
  29.142 +	 */
  29.143 +	virtual bool CanRead( 
  29.144 +		const std::string& pFile, 
  29.145 +		IOSystem* pIOHandler, 
  29.146 +		bool checkSig
  29.147 +		) const = 0;
  29.148 +
  29.149 +	// -------------------------------------------------------------------
  29.150 +	/** Imports the given file and returns the imported data.
  29.151 +	 * If the import succeeds, ownership of the data is transferred to 
  29.152 +	 * the caller. If the import fails, NULL is returned. The function
  29.153 +	 * takes care that any partially constructed data is destroyed
  29.154 +	 * beforehand.
  29.155 +	 *
  29.156 +	 * @param pImp #Importer object hosting this loader.
  29.157 +	 * @param pFile Path of the file to be imported. 
  29.158 +	 * @param pIOHandler IO-Handler used to open this and possible other files.
  29.159 +	 * @return The imported data or NULL if failed. If it failed a 
  29.160 +	 * human-readable error description can be retrieved by calling 
  29.161 +	 * GetErrorText()
  29.162 +	 *
  29.163 +	 * @note This function is not intended to be overridden. Implement 
  29.164 +	 * InternReadFile() to do the import. If an exception is thrown somewhere 
  29.165 +	 * in InternReadFile(), this function will catch it and transform it into
  29.166 +	 *  a suitable response to the caller.
  29.167 +	 */
  29.168 +	aiScene* ReadFile(
  29.169 +		const Importer* pImp, 
  29.170 +		const std::string& pFile, 
  29.171 +		IOSystem* pIOHandler
  29.172 +		);
  29.173 +
  29.174 +	// -------------------------------------------------------------------
  29.175 +	/** Returns the error description of the last error that occured. 
  29.176 +	 * @return A description of the last error that occured. An empty
  29.177 +	 * string if there was no error.
  29.178 +	 */
  29.179 +	const std::string& GetErrorText() const {
  29.180 +		return mErrorText;
  29.181 +	}
  29.182 +
  29.183 +	// -------------------------------------------------------------------
  29.184 +	/** Called prior to ReadFile().
  29.185 +	 * The function is a request to the importer to update its configuration
  29.186 +	 * basing on the Importer's configuration property list.
  29.187 +	 * @param pImp Importer instance
  29.188 +	 */
  29.189 +	virtual void SetupProperties(
  29.190 +		const Importer* pImp
  29.191 +		);
  29.192 +
  29.193 +	
  29.194 +	// -------------------------------------------------------------------
  29.195 +	/** Called by #Importer::GetImporterInfo to get a description of 
  29.196 +	 *  some loader features. Importers must provide this information. */
  29.197 +	virtual const aiImporterDesc* GetInfo() const = 0;
  29.198 +
  29.199 +
  29.200 +
  29.201 +	// -------------------------------------------------------------------
  29.202 +	/** Called by #Importer::GetExtensionList for each loaded importer.
  29.203 +	 *  Take the extension list contained in the structure returned by
  29.204 +	 *  #GetInfo and insert all file extensions into the given set.
  29.205 +	 *  @param extension set to collect file extensions in*/
  29.206 +	void GetExtensionList(std::set<std::string>& extensions);
  29.207 +
  29.208 +protected:
  29.209 +
  29.210 +	// -------------------------------------------------------------------
  29.211 +	/** Imports the given file into the given scene structure. The 
  29.212 +	 * function is expected to throw an ImportErrorException if there is 
  29.213 +	 * an error. If it terminates normally, the data in aiScene is 
  29.214 +	 * expected to be correct. Override this function to implement the 
  29.215 +	 * actual importing.
  29.216 +	 * <br>
  29.217 +	 *  The output scene must meet the following requirements:<br>
  29.218 +	 * <ul>
  29.219 +	 * <li>At least a root node must be there, even if its only purpose
  29.220 +	 *     is to reference one mesh.</li>
  29.221 +	 * <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives
  29.222 +	 *   in the mesh are determined automatically in this case.</li>
  29.223 +	 * <li>the vertex data is stored in a pseudo-indexed "verbose" format.
  29.224 +	 *   In fact this means that every vertex that is referenced by
  29.225 +	 *   a face is unique. Or the other way round: a vertex index may
  29.226 +	 *   not occur twice in a single aiMesh.</li>
  29.227 +	 * <li>aiAnimation::mDuration may be -1. Assimp determines the length
  29.228 +	 *   of the animation automatically in this case as the length of
  29.229 +	 *   the longest animation channel.</li>
  29.230 +	 * <li>aiMesh::mBitangents may be NULL if tangents and normals are
  29.231 +	 *   given. In this case bitangents are computed as the cross product
  29.232 +	 *   between normal and tangent.</li>
  29.233 +	 * <li>There needn't be a material. If none is there a default material
  29.234 +	 *   is generated. However, it is recommended practice for loaders
  29.235 +	 *   to generate a default material for yourself that matches the
  29.236 +	 *   default material setting for the file format better than Assimp's
  29.237 +	 *   generic default material. Note that default materials *should*
  29.238 +	 *   be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded
  29.239 +	 *   or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy) 
  29.240 +	 *   texture. </li>
  29.241 +	 * </ul>
  29.242 +	 * If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul>
  29.243 +	 * <li> at least one mesh must be there</li>
  29.244 +	 * <li> there may be no meshes with 0 vertices or faces</li>
  29.245 +	 * </ul>
  29.246 +	 * This won't be checked (except by the validation step): Assimp will
  29.247 +	 * crash if one of the conditions is not met!
  29.248 +	 *
  29.249 +	 * @param pFile Path of the file to be imported.
  29.250 +	 * @param pScene The scene object to hold the imported data.
  29.251 +	 * NULL is not a valid parameter.
  29.252 +	 * @param pIOHandler The IO handler to use for any file access.
  29.253 +	 * NULL is not a valid parameter. */
  29.254 +	virtual void InternReadFile( 
  29.255 +		const std::string& pFile, 
  29.256 +		aiScene* pScene, 
  29.257 +		IOSystem* pIOHandler
  29.258 +		) = 0;
  29.259 +
  29.260 +public: // static utilities
  29.261 +
  29.262 +	// -------------------------------------------------------------------
  29.263 +	/** A utility for CanRead().
  29.264 +	 *
  29.265 +	 *  The function searches the header of a file for a specific token
  29.266 +	 *  and returns true if this token is found. This works for text
  29.267 +	 *  files only. There is a rudimentary handling of UNICODE files.
  29.268 +	 *  The comparison is case independent.
  29.269 +	 *
  29.270 +	 *  @param pIOSystem IO System to work with
  29.271 +	 *  @param file File name of the file
  29.272 +	 *  @param tokens List of tokens to search for
  29.273 +	 *  @param numTokens Size of the token array
  29.274 +	 *  @param searchBytes Number of bytes to be searched for the tokens.
  29.275 +	 */
  29.276 +	static bool SearchFileHeaderForToken(
  29.277 +		IOSystem* pIOSystem, 
  29.278 +		const std::string&	file,
  29.279 +		const char** tokens, 
  29.280 +		unsigned int numTokens,
  29.281 +		unsigned int searchBytes = 200,
  29.282 +		bool tokensSol = false);
  29.283 +
  29.284 +	// -------------------------------------------------------------------
  29.285 +	/** @brief Check whether a file has a specific file extension
  29.286 +	 *  @param pFile Input file
  29.287 +	 *  @param ext0 Extension to check for. Lowercase characters only, no dot!
  29.288 +	 *  @param ext1 Optional second extension
  29.289 +	 *  @param ext2 Optional third extension
  29.290 +	 *  @note Case-insensitive
  29.291 +	 */
  29.292 +	static bool SimpleExtensionCheck (
  29.293 +		const std::string& pFile, 
  29.294 +		const char* ext0,
  29.295 +		const char* ext1 = NULL,
  29.296 +		const char* ext2 = NULL);
  29.297 +
  29.298 +	// -------------------------------------------------------------------
  29.299 +	/** @brief Extract file extension from a string
  29.300 +	 *  @param pFile Input file
  29.301 +	 *  @return Extension without trailing dot, all lowercase
  29.302 +	 */
  29.303 +	static std::string GetExtension (
  29.304 +		const std::string& pFile);
  29.305 +
  29.306 +	// -------------------------------------------------------------------
  29.307 +	/** @brief Check whether a file starts with one or more magic tokens
  29.308 +	 *  @param pFile Input file
  29.309 +	 *  @param pIOHandler IO system to be used
  29.310 +	 *  @param magic n magic tokens
  29.311 +	 *  @params num Size of magic
  29.312 +	 *  @param offset Offset from file start where tokens are located
  29.313 +	 *  @param Size of one token, in bytes. Maximally 16 bytes.
  29.314 +	 *  @return true if one of the given tokens was found
  29.315 +	 *
  29.316 +	 *  @note For convinence, the check is also performed for the
  29.317 +	 *  byte-swapped variant of all tokens (big endian). Only for
  29.318 +	 *  tokens of size 2,4.
  29.319 +	 */
  29.320 +	static bool CheckMagicToken(
  29.321 +		IOSystem* pIOHandler, 
  29.322 +		const std::string& pFile, 
  29.323 +		const void* magic,
  29.324 +		unsigned int num,
  29.325 +		unsigned int offset = 0,
  29.326 +		unsigned int size   = 4);
  29.327 +
  29.328 +	// -------------------------------------------------------------------
  29.329 +	/** An utility for all text file loaders. It converts a file to our
  29.330 +	 *   UTF8 character set. Errors are reported, but ignored.
  29.331 +	 *
  29.332 +	 *  @param data File buffer to be converted to UTF8 data. The buffer 
  29.333 +	 *  is resized as appropriate. */
  29.334 +	static void ConvertToUTF8(
  29.335 +		std::vector<char>& data);
  29.336 +
  29.337 +	// -------------------------------------------------------------------
  29.338 +	/** Utility for text file loaders which copies the contents of the
  29.339 +	 *  file into a memory buffer and converts it to our UTF8
  29.340 +	 *  representation.
  29.341 +	 *  @param stream Stream to read from. 
  29.342 +	 *  @param data Output buffer to be resized and filled with the
  29.343 +	 *   converted text file data. The buffer is terminated with
  29.344 +	 *   a binary 0. */
  29.345 +	static void TextFileToBuffer(
  29.346 +		IOStream* stream,
  29.347 +		std::vector<char>& data);
  29.348 +
  29.349 +protected:
  29.350 +
  29.351 +	/** Error description in case there was one. */
  29.352 +	std::string mErrorText;
  29.353 +
  29.354 +	/** Currently set progress handler */
  29.355 +	ProgressHandler* progress;
  29.356 +};
  29.357 +
  29.358 +
  29.359 +
  29.360 +} // end of namespace Assimp
  29.361 +
  29.362 +#endif // AI_BASEIMPORTER_H_INC
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/libs/assimp/BaseProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
    30.3 @@ -0,0 +1,105 @@
    30.4 +/*
    30.5 +---------------------------------------------------------------------------
    30.6 +Open Asset Import Library (assimp)
    30.7 +---------------------------------------------------------------------------
    30.8 +
    30.9 +Copyright (c) 2006-2012, assimp team
   30.10 +
   30.11 +All rights reserved.
   30.12 +
   30.13 +Redistribution and use of this software in source and binary forms, 
   30.14 +with or without modification, are permitted provided that the following 
   30.15 +conditions are met:
   30.16 +
   30.17 +* Redistributions of source code must retain the above
   30.18 +  copyright notice, this list of conditions and the
   30.19 +  following disclaimer.
   30.20 +
   30.21 +* Redistributions in binary form must reproduce the above
   30.22 +  copyright notice, this list of conditions and the
   30.23 +  following disclaimer in the documentation and/or other
   30.24 +  materials provided with the distribution.
   30.25 +
   30.26 +* Neither the name of the assimp team, nor the names of its
   30.27 +  contributors may be used to endorse or promote products
   30.28 +  derived from this software without specific prior
   30.29 +  written permission of the assimp team.
   30.30 +
   30.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   30.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   30.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   30.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   30.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   30.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   30.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   30.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   30.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   30.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   30.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   30.42 +---------------------------------------------------------------------------
   30.43 +*/
   30.44 +
   30.45 +/** @file Implementation of BaseProcess */
   30.46 +
   30.47 +#include "AssimpPCH.h"
   30.48 +#include "BaseImporter.h"
   30.49 +#include "BaseProcess.h"
   30.50 +
   30.51 +#include "Importer.h"
   30.52 +
   30.53 +using namespace Assimp;
   30.54 +
   30.55 +// ------------------------------------------------------------------------------------------------
   30.56 +// Constructor to be privately used by Importer
   30.57 +BaseProcess::BaseProcess()
   30.58 +: shared()
   30.59 +, progress()
   30.60 +{
   30.61 +}
   30.62 +
   30.63 +// ------------------------------------------------------------------------------------------------
   30.64 +// Destructor, private as well
   30.65 +BaseProcess::~BaseProcess()
   30.66 +{
   30.67 +	// nothing to do here
   30.68 +}
   30.69 +
   30.70 +// ------------------------------------------------------------------------------------------------
   30.71 +void BaseProcess::ExecuteOnScene( Importer* pImp)
   30.72 +{
   30.73 +	ai_assert(NULL != pImp && NULL != pImp->Pimpl()->mScene);
   30.74 +
   30.75 +	progress = pImp->GetProgressHandler();
   30.76 +	ai_assert(progress);
   30.77 +
   30.78 +	SetupProperties( pImp );
   30.79 +
   30.80 +	// catch exceptions thrown inside the PostProcess-Step
   30.81 +	try
   30.82 +	{
   30.83 +		Execute(pImp->Pimpl()->mScene);
   30.84 +
   30.85 +	} catch( const std::exception& err )	{
   30.86 +
   30.87 +		// extract error description
   30.88 +		pImp->Pimpl()->mErrorString = err.what();
   30.89 +		DefaultLogger::get()->error(pImp->Pimpl()->mErrorString);
   30.90 +
   30.91 +		// and kill the partially imported data
   30.92 +		delete pImp->Pimpl()->mScene;
   30.93 +		pImp->Pimpl()->mScene = NULL;
   30.94 +	}
   30.95 +}
   30.96 +
   30.97 +// ------------------------------------------------------------------------------------------------
   30.98 +void BaseProcess::SetupProperties(const Importer* /*pImp*/)
   30.99 +{
  30.100 +	// the default implementation does nothing
  30.101 +}
  30.102 +
  30.103 +// ------------------------------------------------------------------------------------------------
  30.104 +bool BaseProcess::RequireVerboseFormat() const
  30.105 +{
  30.106 +	return true;
  30.107 +}
  30.108 +
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/libs/assimp/BaseProcess.h	Sat Feb 01 19:58:19 2014 +0200
    31.3 @@ -0,0 +1,294 @@
    31.4 +/*
    31.5 +Open Asset Import Library (assimp)
    31.6 +----------------------------------------------------------------------
    31.7 +
    31.8 +Copyright (c) 2006-2012, assimp team
    31.9 +All rights reserved.
   31.10 +
   31.11 +Redistribution and use of this software in source and binary forms, 
   31.12 +with or without modification, are permitted provided that the 
   31.13 +following conditions are met:
   31.14 +
   31.15 +* Redistributions of source code must retain the above
   31.16 +  copyright notice, this list of conditions and the
   31.17 +  following disclaimer.
   31.18 +
   31.19 +* Redistributions in binary form must reproduce the above
   31.20 +  copyright notice, this list of conditions and the
   31.21 +  following disclaimer in the documentation and/or other
   31.22 +  materials provided with the distribution.
   31.23 +
   31.24 +* Neither the name of the assimp team, nor the names of its
   31.25 +  contributors may be used to endorse or promote products
   31.26 +  derived from this software without specific prior
   31.27 +  written permission of the assimp team.
   31.28 +
   31.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   31.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   31.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   31.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   31.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   31.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   31.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   31.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   31.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   31.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   31.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31.40 +
   31.41 +----------------------------------------------------------------------
   31.42 +*/
   31.43 +
   31.44 +/** @file Base class of all import post processing steps */
   31.45 +#ifndef INCLUDED_AI_BASEPROCESS_H
   31.46 +#define INCLUDED_AI_BASEPROCESS_H
   31.47 +
   31.48 +#include <map>
   31.49 +
   31.50 +#include "assimp/types.h"
   31.51 +#include "GenericProperty.h"
   31.52 +
   31.53 +struct aiScene;
   31.54 +
   31.55 +namespace Assimp	{
   31.56 +
   31.57 +class Importer;
   31.58 +
   31.59 +// ---------------------------------------------------------------------------
   31.60 +/** Helper class to allow post-processing steps to interact with each other.
   31.61 + *
   31.62 + *  The class maintains a simple property list that can be used by pp-steps
   31.63 + *  to provide additional information to other steps. This is primarily
   31.64 + *  intended for cross-step optimizations.
   31.65 + */
   31.66 +class SharedPostProcessInfo
   31.67 +{
   31.68 +public:
   31.69 +
   31.70 +	struct Base
   31.71 +	{
   31.72 +		virtual ~Base()
   31.73 +		{}
   31.74 +	};
   31.75 +
   31.76 +	//! Represents data that is allocated on the heap, thus needs to be deleted
   31.77 +	template <typename T>
   31.78 +	struct THeapData : public Base
   31.79 +	{
   31.80 +		THeapData(T* in)
   31.81 +			: data (in)
   31.82 +		{}
   31.83 +
   31.84 +		~THeapData()
   31.85 +		{
   31.86 +			delete data;
   31.87 +		}
   31.88 +		T* data;
   31.89 +	};
   31.90 +
   31.91 +	//! Represents static, by-value data not allocated on the heap
   31.92 +	template <typename T>
   31.93 +	struct TStaticData : public Base
   31.94 +	{
   31.95 +		TStaticData(T in)
   31.96 +			: data (in)
   31.97 +		{}
   31.98 +
   31.99 +		~TStaticData()
  31.100 +		{}
  31.101 +
  31.102 +		T data;
  31.103 +	};
  31.104 +
  31.105 +	// some typedefs for cleaner code
  31.106 +	typedef unsigned int KeyType;
  31.107 +	typedef std::map<KeyType, Base*>  PropertyMap;
  31.108 +
  31.109 +public:
  31.110 +
  31.111 +	//! Destructor
  31.112 +	~SharedPostProcessInfo()	
  31.113 +	{
  31.114 +		Clean();
  31.115 +	}
  31.116 +
  31.117 +	//! Remove all stored properties from the table
  31.118 +	void Clean()
  31.119 +	{
  31.120 +		// invoke the virtual destructor for all stored properties
  31.121 +		for (PropertyMap::iterator it = pmap.begin(), end = pmap.end();
  31.122 +			 it != end; ++it)
  31.123 +		{
  31.124 +			delete (*it).second;
  31.125 +		}
  31.126 +		pmap.clear();
  31.127 +	}
  31.128 +
  31.129 +	//! Add a heap property to the list
  31.130 +	template <typename T>
  31.131 +	void AddProperty( const char* name, T* in ){
  31.132 +		AddProperty(name,(Base*)new THeapData<T>(in));
  31.133 +	}
  31.134 +
  31.135 +	//! Add a static by-value property to the list
  31.136 +	template <typename T>
  31.137 +	void AddProperty( const char* name, T in ){
  31.138 +		AddProperty(name,(Base*)new TStaticData<T>(in));
  31.139 +	}
  31.140 +
  31.141 +
  31.142 +	//! Get a heap property
  31.143 +	template <typename T>
  31.144 +	bool GetProperty( const char* name, T*& out ) const
  31.145 +	{
  31.146 +		THeapData<T>* t = (THeapData<T>*)GetPropertyInternal(name);
  31.147 +		if(!t)
  31.148 +		{
  31.149 +			out = NULL;
  31.150 +			return false;
  31.151 +		}
  31.152 +		out = t->data;
  31.153 +		return true;
  31.154 +	}
  31.155 +
  31.156 +	//! Get a static, by-value property
  31.157 +	template <typename T>
  31.158 +	bool GetProperty( const char* name, T& out ) const
  31.159 +	{
  31.160 +		TStaticData<T>* t = (TStaticData<T>*)GetPropertyInternal(name);
  31.161 +		if(!t)return false;
  31.162 +		out = t->data;
  31.163 +		return true;
  31.164 +	}
  31.165 +
  31.166 +	//! Remove a property of a specific type
  31.167 +	void RemoveProperty( const char* name)	{
  31.168 +		SetGenericPropertyPtr<Base>(pmap,name,NULL);
  31.169 +	}
  31.170 +
  31.171 +private:
  31.172 +
  31.173 +	void AddProperty( const char* name, Base* data)	{
  31.174 +		SetGenericPropertyPtr<Base>(pmap,name,data);
  31.175 +	}
  31.176 +
  31.177 +	Base* GetPropertyInternal( const char* name) const	{
  31.178 +		return GetGenericProperty<Base*>(pmap,name,NULL);
  31.179 +	}
  31.180 +
  31.181 +private:
  31.182 +
  31.183 +	//! Map of all stored properties
  31.184 +	PropertyMap pmap;
  31.185 +};
  31.186 +
  31.187 +#if 0
  31.188 +
  31.189 +// ---------------------------------------------------------------------------
  31.190 +/** @brief Represents a dependency table for a postprocessing steps.
  31.191 + *
  31.192 + *  For future use.
  31.193 + */
  31.194 + struct PPDependencyTable 
  31.195 + {
  31.196 +	 unsigned int execute_me_before_these;
  31.197 +	 unsigned int execute_me_after_these;
  31.198 +	 unsigned int only_if_these_are_not_specified;
  31.199 +	 unsigned int mutually_exclusive_with;
  31.200 + };
  31.201 +
  31.202 +#endif
  31.203 +
  31.204 +
  31.205 +#define AI_SPP_SPATIAL_SORT "$Spat"
  31.206 +
  31.207 +// ---------------------------------------------------------------------------
  31.208 +/** The BaseProcess defines a common interface for all post processing steps.
  31.209 + * A post processing step is run after a successful import if the caller
  31.210 + * specified the corresponding flag when calling ReadFile(). 
  31.211 + * Enum #aiPostProcessSteps defines which flags are available. 
  31.212 + * After a successful import the Importer iterates over its internal array 
  31.213 + * of processes and calls IsActive() on each process to evaluate if the step 
  31.214 + * should be executed. If the function returns true, the class' Execute() 
  31.215 + * function is called subsequently.
  31.216 + */
  31.217 +class ASSIMP_API_WINONLY BaseProcess 
  31.218 +{
  31.219 +	friend class Importer;
  31.220 +
  31.221 +public:
  31.222 +
  31.223 +	/** Constructor to be privately used by Importer */
  31.224 +	BaseProcess();
  31.225 +
  31.226 +	/** Destructor, private as well */
  31.227 +	virtual ~BaseProcess();
  31.228 +
  31.229 +public:
  31.230 +
  31.231 +	// -------------------------------------------------------------------
  31.232 +	/** Returns whether the processing step is present in the given flag.
  31.233 +	 * @param pFlags The processing flags the importer was called with. A
  31.234 +	 *   bitwise combination of #aiPostProcessSteps.
  31.235 +	 * @return true if the process is present in this flag fields, 
  31.236 +	 *   false if not.
  31.237 +	*/
  31.238 +	virtual bool IsActive( unsigned int pFlags) const = 0;
  31.239 +
  31.240 +	// -------------------------------------------------------------------
  31.241 +	/** Check whether this step expects its input vertex data to be 
  31.242 +	 *  in verbose format. */
  31.243 +	virtual bool RequireVerboseFormat() const;
  31.244 +
  31.245 +	// -------------------------------------------------------------------
  31.246 +	/** Executes the post processing step on the given imported data.
  31.247 +	* The function deletes the scene if the postprocess step fails (
  31.248 +	* the object pointer will be set to NULL).
  31.249 +	* @param pImp Importer instance (pImp->mScene must be valid)
  31.250 +	*/
  31.251 +	void ExecuteOnScene( Importer* pImp);
  31.252 +
  31.253 +	// -------------------------------------------------------------------
  31.254 +	/** Called prior to ExecuteOnScene().
  31.255 +	* The function is a request to the process to update its configuration
  31.256 +	* basing on the Importer's configuration property list.
  31.257 +	*/
  31.258 +	virtual void SetupProperties(const Importer* pImp);
  31.259 +
  31.260 +	// -------------------------------------------------------------------
  31.261 +	/** Executes the post processing step on the given imported data.
  31.262 +	* A process should throw an ImportErrorException* if it fails.
  31.263 +	* This method must be implemented by deriving classes.
  31.264 +	* @param pScene The imported data to work at.
  31.265 +	*/
  31.266 +	virtual void Execute( aiScene* pScene) = 0;
  31.267 +
  31.268 +
  31.269 +	// -------------------------------------------------------------------
  31.270 +	/** Assign a new SharedPostProcessInfo to the step. This object
  31.271 +	 *  allows multiple postprocess steps to share data.
  31.272 +	 * @param sh May be NULL
  31.273 +	*/
  31.274 +	inline void SetSharedData(SharedPostProcessInfo* sh)	{
  31.275 +		shared = sh;
  31.276 +	}
  31.277 +
  31.278 +	// -------------------------------------------------------------------
  31.279 +	/** Get the shared data that is assigned to the step.
  31.280 +	*/
  31.281 +	inline SharedPostProcessInfo* GetSharedData()	{
  31.282 +		return shared;
  31.283 +	}
  31.284 +
  31.285 +protected:
  31.286 +
  31.287 +	/** See the doc of #SharedPostProcessInfo for more details */
  31.288 +	SharedPostProcessInfo* shared;
  31.289 +
  31.290 +	/** Currently active progress handler */
  31.291 +	ProgressHandler* progress;
  31.292 +};
  31.293 +
  31.294 +
  31.295 +} // end of namespace Assimp
  31.296 +
  31.297 +#endif // AI_BASEPROCESS_H_INC
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/libs/assimp/BlenderDNA.cpp	Sat Feb 01 19:58:19 2014 +0200
    32.3 @@ -0,0 +1,372 @@
    32.4 +/*
    32.5 +Open Asset Import Library (assimp)
    32.6 +----------------------------------------------------------------------
    32.7 +
    32.8 +Copyright (c) 2006-2012, assimp team
    32.9 +All rights reserved.
   32.10 +
   32.11 +Redistribution and use of this software in source and binary forms, 
   32.12 +with or without modification, are permitted provided that the 
   32.13 +following conditions are met:
   32.14 +
   32.15 +* Redistributions of source code must retain the above
   32.16 +  copyright notice, this list of conditions and the
   32.17 +  following disclaimer.
   32.18 +
   32.19 +* Redistributions in binary form must reproduce the above
   32.20 +  copyright notice, this list of conditions and the
   32.21 +  following disclaimer in the documentation and/or other
   32.22 +  materials provided with the distribution.
   32.23 +
   32.24 +* Neither the name of the assimp team, nor the names of its
   32.25 +  contributors may be used to endorse or promote products
   32.26 +  derived from this software without specific prior
   32.27 +  written permission of the assimp team.
   32.28 +
   32.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   32.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   32.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   32.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   32.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   32.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   32.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   32.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   32.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   32.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   32.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32.40 +
   32.41 +----------------------------------------------------------------------
   32.42 +*/
   32.43 +
   32.44 +/** @file  BlenderDNA.cpp
   32.45 + *  @brief Implementation of the Blender `DNA`, that is its own
   32.46 + *    serialized set of data structures.
   32.47 + */
   32.48 +#include "AssimpPCH.h"
   32.49 +
   32.50 +#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
   32.51 +#include "BlenderDNA.h"
   32.52 +#include "StreamReader.h"
   32.53 +#include "fast_atof.h"
   32.54 +
   32.55 +using namespace Assimp;
   32.56 +using namespace Assimp::Blender;
   32.57 +using namespace Assimp::Formatter;
   32.58 +
   32.59 +#define for_each BOOST_FOREACH
   32.60 +bool match4(StreamReaderAny& stream, const char* string) {
   32.61 +	char tmp[] = { 
   32.62 +		(stream).GetI1(), 
   32.63 +		(stream).GetI1(),  
   32.64 +		(stream).GetI1(), 
   32.65 +		(stream).GetI1()
   32.66 +	};
   32.67 +	return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
   32.68 +}
   32.69 +
   32.70 +struct Type {
   32.71 +	size_t size;
   32.72 +	std::string name;
   32.73 +};
   32.74 +
   32.75 +// ------------------------------------------------------------------------------------------------
   32.76 +void DNAParser :: Parse () 
   32.77 +{
   32.78 +	StreamReaderAny& stream = *db.reader.get();
   32.79 +	DNA& dna = db.dna;
   32.80 +
   32.81 +	if(!match4(stream,"SDNA")) {
   32.82 +		throw DeadlyImportError("BlenderDNA: Expected SDNA chunk");
   32.83 +	}
   32.84 +
   32.85 +	// name dictionary
   32.86 +	if(!match4(stream,"NAME")) {
   32.87 +		throw DeadlyImportError("BlenderDNA: Expected NAME field");
   32.88 +	}
   32.89 +	
   32.90 +	std::vector<std::string> names (stream.GetI4());
   32.91 +	for_each(std::string& s, names) {
   32.92 +		while (char c = stream.GetI1()) {
   32.93 +			s += c;
   32.94 +		}
   32.95 +	}
   32.96 +
   32.97 +	// type dictionary
   32.98 +	for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
   32.99 +	if(!match4(stream,"TYPE")) {
  32.100 +		throw DeadlyImportError("BlenderDNA: Expected TYPE field");
  32.101 +	}
  32.102 +	
  32.103 +	std::vector<Type> types (stream.GetI4());
  32.104 +	for_each(Type& s, types) {
  32.105 +		while (char c = stream.GetI1()) {
  32.106 +			s.name += c;
  32.107 +		}
  32.108 +	}
  32.109 +
  32.110 +	// type length dictionary
  32.111 +	for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
  32.112 +	if(!match4(stream,"TLEN")) {
  32.113 +		throw DeadlyImportError("BlenderDNA: Expected TLEN field");
  32.114 +	}
  32.115 +	
  32.116 +	for_each(Type& s, types) {
  32.117 +		s.size = stream.GetI2();
  32.118 +	}
  32.119 +
  32.120 +	// structures dictionary
  32.121 +	for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
  32.122 +	if(!match4(stream,"STRC")) {
  32.123 +		throw DeadlyImportError("BlenderDNA: Expected STRC field");
  32.124 +	}
  32.125 +
  32.126 +	size_t end = stream.GetI4(), fields = 0;
  32.127 +
  32.128 +	dna.structures.reserve(end);
  32.129 +	for(size_t i = 0; i != end; ++i) {
  32.130 +		
  32.131 +		uint16_t n = stream.GetI2();
  32.132 +		if (n >= types.size()) {
  32.133 +			throw DeadlyImportError((format(),
  32.134 +				"BlenderDNA: Invalid type index in structure name" ,n, 
  32.135 +				" (there are only ", types.size(), " entries)"
  32.136 +			));
  32.137 +		}
  32.138 +
  32.139 +		// maintain separate indexes
  32.140 +		dna.indices[types[n].name] = dna.structures.size();
  32.141 +
  32.142 +		dna.structures.push_back(Structure());
  32.143 +		Structure& s = dna.structures.back();
  32.144 +		s.name  = types[n].name;
  32.145 +		//s.index = dna.structures.size()-1;
  32.146 +
  32.147 +		n = stream.GetI2();
  32.148 +		s.fields.reserve(n);
  32.149 +
  32.150 +		size_t offset = 0;
  32.151 +		for (size_t m = 0; m < n; ++m, ++fields) {
  32.152 +
  32.153 +			uint16_t j = stream.GetI2();
  32.154 +			if (j >= types.size()) {
  32.155 +				throw DeadlyImportError((format(), 
  32.156 +					"BlenderDNA: Invalid type index in structure field ", j, 
  32.157 +					" (there are only ", types.size(), " entries)"
  32.158 +				));
  32.159 +			}
  32.160 +			s.fields.push_back(Field());
  32.161 +			Field& f = s.fields.back();
  32.162 +			f.offset = offset;
  32.163 +
  32.164 +			f.type = types[j].name;
  32.165 +			f.size = types[j].size;
  32.166 +
  32.167 +			j = stream.GetI2();
  32.168 +			if (j >= names.size()) {
  32.169 +				throw DeadlyImportError((format(), 
  32.170 +					"BlenderDNA: Invalid name index in structure field ", j, 
  32.171 +					" (there are only ", names.size(), " entries)"
  32.172 +				));
  32.173 +			}
  32.174 +
  32.175 +			f.name = names[j];
  32.176 +			f.flags = 0u;
  32.177 +			
  32.178 +			// pointers always specify the size of the pointee instead of their own.
  32.179 +			// The pointer asterisk remains a property of the lookup name.
  32.180 +			if (f.name[0] == '*') {
  32.181 +				f.size = db.i64bit ? 8 : 4;
  32.182 +				f.flags |= FieldFlag_Pointer;
  32.183 +			}
  32.184 +
  32.185 +			// arrays, however, specify the size of a single element so we
  32.186 +			// need to parse the (possibly multi-dimensional) array declaration
  32.187 +			// in order to obtain the actual size of the array in the file.
  32.188 +			// Also we need to alter the lookup name to include no array
  32.189 +			// brackets anymore or size fixup won't work (if our size does 
  32.190 +			// not match the size read from the DNA).
  32.191 +			if (*f.name.rbegin() == ']') {
  32.192 +				const std::string::size_type rb = f.name.find('[');
  32.193 +				if (rb == std::string::npos) {
  32.194 +					throw DeadlyImportError((format(), 
  32.195 +						"BlenderDNA: Encountered invalid array declaration ",
  32.196 +						f.name
  32.197 +					));
  32.198 +				}
  32.199 +
  32.200 +				f.flags |= FieldFlag_Array; 
  32.201 +				DNA::ExtractArraySize(f.name,f.array_sizes);
  32.202 +				f.name = f.name.substr(0,rb);
  32.203 +
  32.204 +				f.size *= f.array_sizes[0] * f.array_sizes[1];
  32.205 +			}
  32.206 +
  32.207 +			// maintain separate indexes
  32.208 +			s.indices[f.name] = s.fields.size()-1;
  32.209 +			offset += f.size;
  32.210 +		}
  32.211 +		s.size = offset;
  32.212 +	}
  32.213 +
  32.214 +	DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(),
  32.215 +		" structures with totally ",fields," fields"));
  32.216 +
  32.217 +#ifdef ASSIMP_BUILD_BLENDER_DEBUG
  32.218 +	dna.DumpToFile();
  32.219 +#endif
  32.220 +
  32.221 +	dna.AddPrimitiveStructures();
  32.222 +	dna.RegisterConverters();
  32.223 +}
  32.224 +
  32.225 +
  32.226 +#ifdef ASSIMP_BUILD_BLENDER_DEBUG
  32.227 +
  32.228 +#include <fstream>
  32.229 +// ------------------------------------------------------------------------------------------------
  32.230 +void DNA :: DumpToFile()
  32.231 +{
  32.232 +	// we dont't bother using the VFS here for this is only for debugging.
  32.233 +	// (and all your bases are belong to us).
  32.234 +
  32.235 +	std::ofstream f("dna.txt");
  32.236 +	if (f.fail()) {
  32.237 +		DefaultLogger::get()->error("Could not dump dna to dna.txt");
  32.238 +		return;
  32.239 +	}
  32.240 +	f << "Field format: type name offset size" << "\n";
  32.241 +	f << "Structure format: name size" << "\n";
  32.242 +
  32.243 +	for_each(const Structure& s, structures) {
  32.244 +		f << s.name << " " << s.size << "\n\n";
  32.245 +		for_each(const Field& ff, s.fields) {
  32.246 +			f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl;
  32.247 +		}
  32.248 +		f << std::endl;
  32.249 +	}
  32.250 +	DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt");
  32.251 +}
  32.252 +#endif
  32.253 +
  32.254 +// ------------------------------------------------------------------------------------------------
  32.255 +/*static*/ void  DNA :: ExtractArraySize(
  32.256 +	const std::string& out, 
  32.257 +	size_t array_sizes[2]
  32.258 +)
  32.259 +{
  32.260 +	array_sizes[0] = array_sizes[1] = 1;
  32.261 +	std::string::size_type pos = out.find('[');
  32.262 +	if (pos++ == std::string::npos) {
  32.263 +		return;
  32.264 +	}
  32.265 +	array_sizes[0] = strtoul10(&out[pos]);
  32.266 +
  32.267 +	pos = out.find('[',pos);
  32.268 +	if (pos++ == std::string::npos) {
  32.269 +		return;
  32.270 +	}
  32.271 +	array_sizes[1] = strtoul10(&out[pos]);
  32.272 +}
  32.273 +
  32.274 +// ------------------------------------------------------------------------------------------------
  32.275 +boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
  32.276 +	const Structure& structure,
  32.277 +	const FileDatabase& db
  32.278 +) const 
  32.279 +{
  32.280 +	std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
  32.281 +	if (it == converters.end()) {
  32.282 +		return boost::shared_ptr< ElemBase >();
  32.283 +	}
  32.284 +
  32.285 +	boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
  32.286 +	(structure.*((*it).second.second))(ret,db);
  32.287 +	
  32.288 +	return ret;
  32.289 +}
  32.290 +
  32.291 +// ------------------------------------------------------------------------------------------------
  32.292 +DNA::FactoryPair DNA :: GetBlobToStructureConverter(
  32.293 +	const Structure& structure,
  32.294 +	const FileDatabase& /*db*/
  32.295 +) const 
  32.296 +{
  32.297 +	std::map<std::string,  FactoryPair>::const_iterator it = converters.find(structure.name);
  32.298 +	return it == converters.end() ? FactoryPair() : (*it).second;
  32.299 +}
  32.300 +
  32.301 +// basing on http://www.blender.org/development/architecture/notes-on-sdna/
  32.302 +// ------------------------------------------------------------------------------------------------
  32.303 +void DNA :: AddPrimitiveStructures()
  32.304 +{
  32.305 +	// NOTE: these are just dummies. Their presence enforces
  32.306 +	// Structure::Convert<target_type> to be called on these
  32.307 +	// empty structures. These converters are special 
  32.308 +	// overloads which scan the name of the structure and
  32.309 +	// perform the required data type conversion if one
  32.310 +	// of these special names is found in the structure
  32.311 +	// in question.
  32.312 +
  32.313 +	indices["int"] = structures.size();
  32.314 +	structures.push_back( Structure() );
  32.315 +	structures.back().name = "int";
  32.316 +	structures.back().size = 4;
  32.317 +
  32.318 +	indices["short"] = structures.size();
  32.319 +	structures.push_back( Structure() );
  32.320 +	structures.back().name = "short";
  32.321 +	structures.back().size = 2;
  32.322 +
  32.323 +
  32.324 +	indices["char"] = structures.size();
  32.325 +	structures.push_back( Structure() );
  32.326 +	structures.back().name = "char";
  32.327 +	structures.back().size = 1;
  32.328 +
  32.329 +
  32.330 +	indices["float"] = structures.size();
  32.331 +	structures.push_back( Structure() );
  32.332 +	structures.back().name = "float";
  32.333 +	structures.back().size = 4;
  32.334 +
  32.335 +
  32.336 +	indices["double"] = structures.size();
  32.337 +	structures.push_back( Structure() );
  32.338 +	structures.back().name = "double";
  32.339 +	structures.back().size = 8;
  32.340 +
  32.341 +	// no long, seemingly.
  32.342 +}
  32.343 +
  32.344 +// ------------------------------------------------------------------------------------------------
  32.345 +void SectionParser :: Next()
  32.346 +{
  32.347 +	stream.SetCurrentPos(current.start + current.size);
  32.348 +
  32.349 +	const char tmp[] = {
  32.350 +		stream.GetI1(),
  32.351 +		stream.GetI1(),
  32.352 +		stream.GetI1(),
  32.353 +		stream.GetI1()
  32.354 +	};
  32.355 +	current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
  32.356 +
  32.357 +	current.size = stream.GetI4();
  32.358 +	current.address.val = ptr64 ? stream.GetU8() : stream.GetU4();
  32.359 +
  32.360 +	current.dna_index = stream.GetI4();
  32.361 +	current.num = stream.GetI4();
  32.362 +
  32.363 +	current.start = stream.GetCurrentPos();
  32.364 +	if (stream.GetRemainingSizeToLimit() < current.size) {
  32.365 +		throw DeadlyImportError("BLEND: invalid size of file block");
  32.366 +	}
  32.367 +
  32.368 +#ifdef ASSIMP_BUILD_BLENDER_DEBUG
  32.369 +	DefaultLogger::get()->debug(current.id);
  32.370 +#endif
  32.371 +}
  32.372 +
  32.373 +
  32.374 +
  32.375 +#endif
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/libs/assimp/BlenderDNA.h	Sat Feb 01 19:58:19 2014 +0200
    33.3 @@ -0,0 +1,798 @@
    33.4 +/*
    33.5 +Open Asset Import Library (assimp)
    33.6 +----------------------------------------------------------------------
    33.7 +
    33.8 +Copyright (c) 2006-2012, assimp team
    33.9 +All rights reserved.
   33.10 +
   33.11 +Redistribution and use of this software in source and binary forms, 
   33.12 +with or without modification, are permitted provided that the 
   33.13 +following conditions are met:
   33.14 +
   33.15 +* Redistributions of source code must retain the above
   33.16 +  copyright notice, this list of conditions and the
   33.17 +  following disclaimer.
   33.18 +
   33.19 +* Redistributions in binary form must reproduce the above
   33.20 +  copyright notice, this list of conditions and the
   33.21 +  following disclaimer in the documentation and/or other
   33.22 +  materials provided with the distribution.
   33.23 +
   33.24 +* Neither the name of the assimp team, nor the names of its
   33.25 +  contributors may be used to endorse or promote products
   33.26 +  derived from this software without specific prior
   33.27 +  written permission of the assimp team.
   33.28 +
   33.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   33.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   33.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   33.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   33.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   33.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   33.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   33.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   33.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   33.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   33.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33.40 +
   33.41 +----------------------------------------------------------------------
   33.42 +*/
   33.43 +
   33.44 +/** @file  BlenderDNA.h
   33.45 + *  @brief Blender `DNA` (file format specification embedded in 
   33.46 + *    blend file itself) loader.
   33.47 + */
   33.48 +#ifndef INCLUDED_AI_BLEND_DNA_H
   33.49 +#define INCLUDED_AI_BLEND_DNA_H
   33.50 +
   33.51 +#include "BaseImporter.h"
   33.52 +#include "TinyFormatter.h"
   33.53 +
   33.54 +// enable verbose log output. really verbose, so be careful.
   33.55 +#ifdef _DEBUG
   33.56 +#	define ASSIMP_BUILD_BLENDER_DEBUG
   33.57 +#endif
   33.58 +
   33.59 +// #define ASSIMP_BUILD_BLENDER_NO_STATS
   33.60 +
   33.61 +namespace Assimp	{
   33.62 +	template <bool,bool> class StreamReader;
   33.63 +	typedef StreamReader<true,true> StreamReaderAny;
   33.64 +
   33.65 +	namespace Blender {
   33.66 +		class  FileDatabase;
   33.67 +		struct FileBlockHead;
   33.68 +
   33.69 +		template <template <typename> class TOUT>
   33.70 +		class ObjectCache;
   33.71 +
   33.72 +// -------------------------------------------------------------------------------
   33.73 +/** Exception class used by the blender loader to selectively catch exceptions
   33.74 + *  thrown in its own code (DeadlyImportErrors thrown in general utility
   33.75 + *  functions are untouched then). If such an exception is not caught by
   33.76 + *  the loader itself, it will still be caught by Assimp due to its
   33.77 + *  ancestry. */
   33.78 +// -------------------------------------------------------------------------------
   33.79 +struct Error : DeadlyImportError
   33.80 +{
   33.81 +	Error (const std::string& s)
   33.82 +		: DeadlyImportError(s)
   33.83 +	{}
   33.84 +};
   33.85 +
   33.86 +// -------------------------------------------------------------------------------
   33.87 +/** The only purpose of this structure is to feed a virtual dtor into its
   33.88 + *  descendents. It serves as base class for all data structure fields. */
   33.89 +// -------------------------------------------------------------------------------
   33.90 +struct ElemBase 
   33.91 +{
   33.92 +	virtual ~ElemBase() {}
   33.93 +
   33.94 +	/** Type name of the element. The type 
   33.95 +	 * string points is the `c_str` of the `name` attribute of the 
   33.96 +	 * corresponding `Structure`, that is, it is only valid as long 
   33.97 +	 * as the DNA is not modified. The dna_type is only set if the
   33.98 +	 * data type is not static, i.e. a boost::shared_ptr<ElemBase>
   33.99 +	 * in the scene description would have its type resolved 
  33.100 +	 * at runtime, so this member is always set. */
  33.101 +	const char* dna_type;
  33.102 +};
  33.103 +
  33.104 +
  33.105 +// -------------------------------------------------------------------------------
  33.106 +/** Represents a generic pointer to a memory location, which can be either 32
  33.107 + *  or 64 bits. These pointers are loaded from the BLEND file and finally
  33.108 + *  fixed to point to the real, converted representation of the objects 
  33.109 + *  they used to point to.*/
  33.110 +// -------------------------------------------------------------------------------
  33.111 +struct Pointer
  33.112 +{
  33.113 +	Pointer() : val() {}
  33.114 +	uint64_t val;
  33.115 +};
  33.116 +
  33.117 +// -------------------------------------------------------------------------------
  33.118 +/** Represents a generic offset within a BLEND file */
  33.119 +// -------------------------------------------------------------------------------
  33.120 +struct FileOffset
  33.121 +{
  33.122 +	FileOffset() : val() {}
  33.123 +	uint64_t val;
  33.124 +};
  33.125 +
  33.126 +// -------------------------------------------------------------------------------
  33.127 +/** Dummy derivate of std::vector to be able to use it in templates simultaenously
  33.128 + *  with boost::shared_ptr, which takes only one template argument 
  33.129 + *  while std::vector takes three. Also we need to provide some special member
  33.130 + *  functions of shared_ptr */
  33.131 +// -------------------------------------------------------------------------------
  33.132 +template <typename T>
  33.133 +class vector : public std::vector<T>
  33.134 +{
  33.135 +public:
  33.136 +	using std::vector<T>::resize;
  33.137 +	using std::vector<T>::empty;
  33.138 +
  33.139 +	void reset() {
  33.140 +		resize(0);
  33.141 +	}
  33.142 +
  33.143 +	operator bool () const {
  33.144 +		return !empty();
  33.145 +	}
  33.146 +};
  33.147 +
  33.148 +// -------------------------------------------------------------------------------
  33.149 +/** Mixed flags for use in #Field */
  33.150 +// -------------------------------------------------------------------------------
  33.151 +enum FieldFlags 
  33.152 +{
  33.153 +	FieldFlag_Pointer = 0x1,
  33.154 +	FieldFlag_Array   = 0x2
  33.155 +};
  33.156 +
  33.157 +// -------------------------------------------------------------------------------
  33.158 +/** Represents a single member of a data structure in a BLEND file */
  33.159 +// -------------------------------------------------------------------------------
  33.160 +struct Field 
  33.161 +{	
  33.162 +	std::string name;
  33.163 +	std::string type;
  33.164 +
  33.165 +	size_t size;
  33.166 +	size_t offset;
  33.167 +
  33.168 +	/** Size of each array dimension. For flat arrays,
  33.169 +	 *  the second dimension is set to 1. */
  33.170 +	size_t array_sizes[2];
  33.171 +
  33.172 +	/** Any of the #FieldFlags enumerated values */
  33.173 +	unsigned int flags;
  33.174 +};
  33.175 +
  33.176 +// -------------------------------------------------------------------------------
  33.177 +/** Range of possible behaviours for fields absend in the input file. Some are
  33.178 + *  mission critical so we need them, while others can silently be default
  33.179 + *  initialized and no animations are harmed. */
  33.180 +// -------------------------------------------------------------------------------
  33.181 +enum ErrorPolicy 
  33.182 +{
  33.183 +	/** Substitute default value and ignore */
  33.184 +	ErrorPolicy_Igno,
  33.185 +	/** Substitute default value and write to log */
  33.186 +	ErrorPolicy_Warn,
  33.187 +	/** Substitute a massive error message and crash the whole matrix. Its time for another zion */
  33.188 +	ErrorPolicy_Fail
  33.189 +};
  33.190 +
  33.191 +#ifdef ASSIMP_BUILD_BLENDER_DEBUG
  33.192 +#	define ErrorPolicy_Igno ErrorPolicy_Warn
  33.193 +#endif
  33.194 +
  33.195 +// -------------------------------------------------------------------------------
  33.196 +/** Represents a data structure in a BLEND file. A Structure defines n fields
  33.197 + *  and their locatios and encodings the input stream. Usually, every
  33.198 + *  Structure instance pertains to one equally-named data structure in the
  33.199 + *  BlenderScene.h header. This class defines various utilities to map a
  33.200 + *  binary `blob` read from the file to such a structure instance with
  33.201 + *  meaningful contents. */
  33.202 +// -------------------------------------------------------------------------------
  33.203 +class Structure 
  33.204 +{
  33.205 +	template <template <typename> class> friend class ObjectCache;
  33.206 +
  33.207 +public:
  33.208 +
  33.209 +	Structure()
  33.210 +		:	cache_idx(-1)
  33.211 +	{}
  33.212 +
  33.213 +public:
  33.214 +
  33.215 +	// publicly accessible members
  33.216 +	std::string name;
  33.217 +	vector< Field > fields;
  33.218 +	std::map<std::string, size_t> indices;
  33.219 +
  33.220 +	size_t size;
  33.221 +
  33.222 +public:
  33.223 +
  33.224 +	// --------------------------------------------------------
  33.225 +	/** Access a field of the structure by its canonical name. The pointer version
  33.226 +	 *  returns NULL on failure while the reference version raises an import error. */
  33.227 +	inline const Field& operator [] (const std::string& ss) const;
  33.228 +	inline const Field* Get (const std::string& ss) const;
  33.229 +
  33.230 +	// --------------------------------------------------------
  33.231 +	/** Access a field of the structure by its index */
  33.232 +	inline const Field& operator [] (const size_t i) const;
  33.233 +
  33.234 +	// --------------------------------------------------------
  33.235 +	inline bool operator== (const Structure& other) const {
  33.236 +		return name == other.name; // name is meant to be an unique identifier
  33.237 +	}
  33.238 +
  33.239 +	// --------------------------------------------------------
  33.240 +	inline bool operator!= (const Structure& other) const {
  33.241 +		return name != other.name;
  33.242 +	}
  33.243 +
  33.244 +public:
  33.245 +
  33.246 +	// --------------------------------------------------------
  33.247 +	/** Try to read an instance of the structure from the stream
  33.248 +	 *  and attempt to convert to `T`. This is done by
  33.249 +	 *  an appropriate specialization. If none is available,
  33.250 +	 *  a compiler complain is the result.
  33.251 +	 *  @param dest Destination value to be written
  33.252 +	 *  @param db File database, including input stream. */
  33.253 +	template <typename T> inline void Convert (T& dest,
  33.254 +		const FileDatabase& db) const;
  33.255 +
  33.256 +
  33.257 +
  33.258 +	// --------------------------------------------------------
  33.259 +	// generic converter
  33.260 +	template <typename T>
  33.261 +	void Convert(boost::shared_ptr<ElemBase> in,const FileDatabase& db) const;
  33.262 +
  33.263 +	// --------------------------------------------------------
  33.264 +	// generic allocator
  33.265 +	template <typename T> boost::shared_ptr<ElemBase> Allocate() const;
  33.266 +
  33.267 +
  33.268 +
  33.269 +	// --------------------------------------------------------
  33.270 +	// field parsing for 1d arrays
  33.271 +	template <int error_policy, typename T, size_t M>
  33.272 +	void ReadFieldArray(T (& out)[M], const char* name, 
  33.273 +		const FileDatabase& db) const;
  33.274 +
  33.275 +	// --------------------------------------------------------
  33.276 +	// field parsing for 2d arrays
  33.277 +	template <int error_policy, typename T, size_t M, size_t N>
  33.278 +	void ReadFieldArray2(T (& out)[M][N], const char* name,
  33.279 +		const FileDatabase& db) const;
  33.280 +
  33.281 +	// --------------------------------------------------------
  33.282 +	// field parsing for pointer or dynamic array types 
  33.283 +	// (boost::shared_ptr or boost::shared_array)
  33.284 +	template <int error_policy, template <typename> class TOUT, typename T>
  33.285 +	void ReadFieldPtr(TOUT<T>& out, const char* name, 
  33.286 +		const FileDatabase& db) const;
  33.287 +
  33.288 +	// --------------------------------------------------------
  33.289 +	// field parsing for static arrays of pointer or dynamic
  33.290 +	// array types (boost::shared_ptr[] or boost::shared_array[])
  33.291 +	template <int error_policy, template <typename> class TOUT, typename T, size_t N>
  33.292 +	void ReadFieldPtr(TOUT<T> (&out)[N], const char* name, 
  33.293 +		const FileDatabase& db) const;
  33.294 +
  33.295 +	// --------------------------------------------------------
  33.296 +	// field parsing for `normal` values
  33.297 +	template <int error_policy, typename T>
  33.298 +	void ReadField(T& out, const char* name, 
  33.299 +		const FileDatabase& db) const;
  33.300 +
  33.301 +private:
  33.302 +
  33.303 +	// --------------------------------------------------------
  33.304 +	template <template <typename> class TOUT, typename T>
  33.305 +	void ResolvePointer(TOUT<T>& out, const Pointer & ptrval, 
  33.306 +		const FileDatabase& db, const Field& f) const;
  33.307 +
  33.308 +	// --------------------------------------------------------
  33.309 +	template <template <typename> class TOUT, typename T>
  33.310 +	void ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, 
  33.311 +		const FileDatabase& db, const Field& f) const;
  33.312 +
  33.313 +	// --------------------------------------------------------
  33.314 +	void ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, 
  33.315 +		const FileDatabase& db, const Field& f) const;
  33.316 +
  33.317 +	// --------------------------------------------------------
  33.318 +	inline const FileBlockHead* LocateFileBlockForAddress(
  33.319 +		const Pointer & ptrval,
  33.320 +		const FileDatabase& db) const;
  33.321 +
  33.322 +private:
  33.323 +
  33.324 +	// ------------------------------------------------------------------------------
  33.325 +	template <typename T> T* _allocate(boost::shared_ptr<T>& out, size_t& s) const {
  33.326 +		out = boost::shared_ptr<T>(new T());
  33.327 +		s = 1;
  33.328 +		return out.get();
  33.329 +	}
  33.330 +
  33.331 +	template <typename T> T* _allocate(vector<T>& out, size_t& s) const {
  33.332 +		out.resize(s);
  33.333 +		return s ? &out.front() : NULL;
  33.334 +	}
  33.335 +
  33.336 +	// --------------------------------------------------------
  33.337 +	template <int error_policy>
  33.338 +	struct _defaultInitializer {
  33.339 +
  33.340 +		template <typename T, unsigned int N>
  33.341 +		void operator ()(T (& out)[N], const char* = NULL) {
  33.342 +			for (unsigned int i = 0; i < N; ++i) {
  33.343 +				out[i] = T(); 
  33.344 +			}
  33.345 +		}
  33.346 +
  33.347 +		template <typename T, unsigned int N, unsigned int M>
  33.348 +		void operator ()(T (& out)[N][M], const char* = NULL) {
  33.349 +			for (unsigned int i = 0; i < N; ++i) {
  33.350 +				for (unsigned int j = 0; j < M; ++j) {
  33.351 +					out[i][j] = T(); 
  33.352 +				}
  33.353 +			}
  33.354 +		}
  33.355 +
  33.356 +		template <typename T>
  33.357 +		void operator ()(T& out, const char* = NULL) {
  33.358 +			out = T();
  33.359 +		}
  33.360 +	};
  33.361 +
  33.362 +private:
  33.363 +
  33.364 +	mutable size_t cache_idx;
  33.365 +};
  33.366 +
  33.367 +// --------------------------------------------------------
  33.368 +template <>  struct Structure :: _defaultInitializer<ErrorPolicy_Warn> {
  33.369 +
  33.370 +	template <typename T>
  33.371 +	void operator ()(T& out, const char* reason = "<add reason>") {
  33.372 +		DefaultLogger::get()->warn(reason);
  33.373 +
  33.374 +		// ... and let the show go on
  33.375 +		_defaultInitializer<0 /*ErrorPolicy_Igno*/>()(out);
  33.376 +	}
  33.377 +};
  33.378 +
  33.379 +template <> struct Structure :: _defaultInitializer<ErrorPolicy_Fail> {
  33.380 +
  33.381 +	template <typename T>
  33.382 +	void operator ()(T& /*out*/,const char* = "") {
  33.383 +		// obviously, it is crucial that _DefaultInitializer is used 
  33.384 +		// only from within a catch clause.
  33.385 +		throw;
  33.386 +	}
  33.387 +};
  33.388 +
  33.389 +// -------------------------------------------------------------------------------------------------------
  33.390 +template <> inline void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out, 
  33.391 +	const Pointer & ptrval, 
  33.392 +	const FileDatabase& db, 
  33.393 +	const Field& f
  33.394 +	) const;
  33.395 +
  33.396 +
  33.397 +// -------------------------------------------------------------------------------
  33.398 +/** Represents the full data structure information for a single BLEND file.
  33.399 + *  This data is extracted from the DNA1 chunk in the file.
  33.400 + *  #DNAParser does the reading and represents currently the only place where 
  33.401 + *  DNA is altered.*/
  33.402 +// -------------------------------------------------------------------------------
  33.403 +class DNA
  33.404 +{
  33.405 +public:
  33.406 +
  33.407 +	typedef void (Structure::*ConvertProcPtr) (
  33.408 +		boost::shared_ptr<ElemBase> in, 
  33.409 +		const FileDatabase&
  33.410 +	) const;
  33.411 +
  33.412 +	typedef boost::shared_ptr<ElemBase> (
  33.413 +		Structure::*AllocProcPtr) () const;
  33.414 +	
  33.415 +	typedef std::pair< AllocProcPtr, ConvertProcPtr > FactoryPair;
  33.416 +
  33.417 +public:
  33.418 +
  33.419 +	std::map<std::string, FactoryPair > converters;
  33.420 +	vector<Structure > structures;
  33.421 +	std::map<std::string, size_t> indices;
  33.422 +
  33.423 +public:
  33.424 +
  33.425 +	// --------------------------------------------------------
  33.426 +	/** Access a structure by its canonical name, the pointer version returns NULL on failure 
  33.427 +	  * while the reference version raises an error. */
  33.428 +	inline const Structure& operator [] (const std::string& ss) const;
  33.429 +	inline const Structure* Get (const std::string& ss) const;
  33.430 +
  33.431 +	// --------------------------------------------------------
  33.432 +	/** Access a structure by its index */
  33.433 +	inline const Structure& operator [] (const size_t i) const;
  33.434 +
  33.435 +public:
  33.436 +
  33.437 +	// --------------------------------------------------------
  33.438 +	/** Add structure definitions for all the primitive types,
  33.439 +	 *  i.e. integer, short, char, float */
  33.440 +	void AddPrimitiveStructures();
  33.441 +
  33.442 +	// --------------------------------------------------------
  33.443 +	/** Fill the @c converters member with converters for all 
  33.444 +	 *  known data types. The implementation of this method is
  33.445 +	 *  in BlenderScene.cpp and is machine-generated.
  33.446 +	 *  Converters are used to quickly handle objects whose
  33.447 +	 *  exact data type is a runtime-property and not yet 
  33.448 +	 *  known at compile time (consier Object::data).*/
  33.449 +	void RegisterConverters();
  33.450 +
  33.451 +
  33.452 +	// --------------------------------------------------------
  33.453 +	/** Take an input blob from the stream, interpret it according to 
  33.454 +	 *  a its structure name and convert it to the intermediate
  33.455 +	 *  representation. 
  33.456 +	 *  @param structure Destination structure definition
  33.457 +	 *  @param db File database.
  33.458 +	 *  @return A null pointer if no appropriate converter is available.*/
  33.459 +	boost::shared_ptr< ElemBase > ConvertBlobToStructure(
  33.460 +		const Structure& structure,
  33.461 +		const FileDatabase& db
  33.462 +		) const;
  33.463 +
  33.464 +	// --------------------------------------------------------
  33.465 +	/** Find a suitable conversion function for a given Structure.
  33.466 +	 *  Such a converter function takes a blob from the input 
  33.467 +	 *  stream, reads as much as it needs, and builds up a
  33.468 +	 *  complete object in intermediate representation.
  33.469 +	 *  @param structure Destination structure definition
  33.470 +	 *  @param db File database.
  33.471 +	 *  @return A null pointer in .first if no appropriate converter is available.*/
  33.472 +	FactoryPair GetBlobToStructureConverter(
  33.473 +		const Structure& structure,
  33.474 +		const FileDatabase& db
  33.475 +		) const;
  33.476 +
  33.477 +
  33.478 +#ifdef ASSIMP_BUILD_BLENDER_DEBUG
  33.479 +	// --------------------------------------------------------
  33.480 +	/** Dump the DNA to a text file. This is for debugging purposes. 
  33.481 +	 *  The output file is `dna.txt` in the current working folder*/
  33.482 +	void DumpToFile();
  33.483 +#endif
  33.484 +
  33.485 +	// --------------------------------------------------------
  33.486 +	/** Extract array dimensions from a C array declaration, such
  33.487 +	 *  as `...[4][6]`. Returned string would be `...[][]`.
  33.488 +	 *  @param out
  33.489 +	 *  @param array_sizes Receive maximally two array dimensions,
  33.490 +	 *    the second element is set to 1 if the array is flat.
  33.491 +	 *    Both are set to 1 if the input is not an array.
  33.492 +	 *  @throw DeadlyImportError if more than 2 dimensions are
  33.493 +	 *    encountered. */
  33.494 +	static void ExtractArraySize(
  33.495 +		const std::string& out, 
  33.496 +		size_t array_sizes[2]
  33.497 +	);
  33.498 +};
  33.499 +
  33.500 +// special converters for primitive types
  33.501 +template <> inline void Structure :: Convert<int>		(int& dest,const FileDatabase& db) const;
  33.502 +template <> inline void Structure :: Convert<short>		(short& dest,const FileDatabase& db) const;
  33.503 +template <> inline void Structure :: Convert<char>		(char& dest,const FileDatabase& db) const;
  33.504 +template <> inline void Structure :: Convert<float>		(float& dest,const FileDatabase& db) const;
  33.505 +template <> inline void Structure :: Convert<double>	(double& dest,const FileDatabase& db) const;
  33.506 +template <> inline void Structure :: Convert<Pointer>	(Pointer& dest,const FileDatabase& db) const;
  33.507 +
  33.508 +// -------------------------------------------------------------------------------
  33.509 +/** Describes a master file block header. Each master file sections holds n
  33.510 + *  elements of a certain SDNA structure (or otherwise unspecified data). */
  33.511 +// -------------------------------------------------------------------------------
  33.512 +struct FileBlockHead 
  33.513 +{
  33.514 +	// points right after the header of the file block
  33.515 +	StreamReaderAny::pos start;
  33.516 +
  33.517 +	std::string id;
  33.518 +	size_t size;
  33.519 +
  33.520 +	// original memory address of the data
  33.521 +	Pointer address;
  33.522 +
  33.523 +	// index into DNA
  33.524 +	unsigned int dna_index;
  33.525 +
  33.526 +	// number of structure instances to follow
  33.527 +	size_t num;
  33.528 +
  33.529 +
  33.530 +
  33.531 +	// file blocks are sorted by address to quickly locate specific memory addresses
  33.532 +	bool operator < (const FileBlockHead& o) const {
  33.533 +		return address.val < o.address.val;
  33.534 +	}
  33.535 +
  33.536 +	// for std::upper_bound
  33.537 +	operator const Pointer& () const {
  33.538 +		return address;
  33.539 +	}
  33.540 +};
  33.541 +
  33.542 +// for std::upper_bound
  33.543 +inline bool operator< (const Pointer& a, const Pointer& b) {
  33.544 +	return a.val < b.val;
  33.545 +}
  33.546 +
  33.547 +// -------------------------------------------------------------------------------
  33.548 +/** Utility to read all master file blocks in turn. */
  33.549 +// -------------------------------------------------------------------------------
  33.550 +class SectionParser 
  33.551 +{
  33.552 +public:
  33.553 +
  33.554 +	// --------------------------------------------------------
  33.555 +	/** @param stream Inout stream, must point to the 
  33.556 +	 *  first section in the file. Call Next() once
  33.557 +	 *  to have it read. 
  33.558 +	 *  @param ptr64 Pointer size in file is 64 bits? */
  33.559 +	SectionParser(StreamReaderAny& stream,bool ptr64)
  33.560 +		: stream(stream)
  33.561 +		, ptr64(ptr64)
  33.562 +	{
  33.563 +		current.size = current.start = 0;
  33.564 +	}
  33.565 +
  33.566 +public:
  33.567 +
  33.568 +	// --------------------------------------------------------
  33.569 +	const FileBlockHead& GetCurrent() const {
  33.570 +		return current;
  33.571 +	}
  33.572 +	
  33.573 +
  33.574 +public:
  33.575 +
  33.576 +	// --------------------------------------------------------
  33.577 +	/** Advance to the next section. 
  33.578 +	 *  @throw DeadlyImportError if the last chunk was passed. */
  33.579 +	void Next();
  33.580 +
  33.581 +public:
  33.582 +
  33.583 +	FileBlockHead current;
  33.584 +	StreamReaderAny& stream;
  33.585 +	bool ptr64;
  33.586 +};
  33.587 +
  33.588 +
  33.589 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  33.590 +// -------------------------------------------------------------------------------
  33.591 +/** Import statistics, i.e. number of file blocks read*/
  33.592 +// -------------------------------------------------------------------------------
  33.593 +class Statistics {
  33.594 +
  33.595 +public:
  33.596 +
  33.597 +	Statistics () 
  33.598 +		: fields_read		()
  33.599 +		, pointers_resolved	()
  33.600 +		, cache_hits		()
  33.601 +//		, blocks_read		()
  33.602 +		, cached_objects	()
  33.603 +	{}
  33.604 +
  33.605 +public:
  33.606 +
  33.607 +	/** total number of fields we read */
  33.608 +	unsigned int fields_read;
  33.609 +
  33.610 +	/** total number of resolved pointers */
  33.611 +	unsigned int pointers_resolved;
  33.612 +
  33.613 +	/** number of pointers resolved from the cache */
  33.614 +	unsigned int cache_hits;
  33.615 +
  33.616 +	/** number of blocks (from  FileDatabase::entries) 
  33.617 +	  we did actually read from. */
  33.618 +	// unsigned int blocks_read;
  33.619 +
  33.620 +	/** objects in FileData::cache */
  33.621 +	unsigned int cached_objects;
  33.622 +};
  33.623 +#endif
  33.624 +
  33.625 +// -------------------------------------------------------------------------------
  33.626 +/** The object cache - all objects addressed by pointers are added here. This
  33.627 + *  avoids circular references and avoids object duplication. */
  33.628 +// -------------------------------------------------------------------------------
  33.629 +template <template <typename> class TOUT>
  33.630 +class ObjectCache 
  33.631 +{
  33.632 +public:
  33.633 +
  33.634 +	typedef std::map< Pointer, TOUT<ElemBase> > StructureCache;
  33.635 +
  33.636 +public:
  33.637 +
  33.638 +	ObjectCache(const FileDatabase& db)
  33.639 +		: db(db)
  33.640 +	{
  33.641 +		// currently there are only ~400 structure records per blend file.
  33.642 +		// we read only a small part of them and don't cache objects
  33.643 +		// which we don't need, so this should suffice.
  33.644 +		caches.reserve(64);
  33.645 +	}
  33.646 +
  33.647 +public:
  33.648 +
  33.649 +	// --------------------------------------------------------
  33.650 +	/** Check whether a specific item is in the cache.
  33.651 +	 *  @param s Data type of the item
  33.652 +	 *  @param out Output pointer. Unchanged if the
  33.653 +	 *   cache doens't know the item yet.
  33.654 +	 *  @param ptr Item address to look for. */
  33.655 +	template <typename T> void get (
  33.656 +		const Structure& s, 
  33.657 +		TOUT<T>& out, 
  33.658 +		const Pointer& ptr) const;
  33.659 +
  33.660 +	// --------------------------------------------------------
  33.661 +	/** Add an item to the cache after the item has 
  33.662 +	 * been fully read. Do not insert anything that
  33.663 +	 * may be faulty or might cause the loading
  33.664 +	 * to abort. 
  33.665 +	 *  @param s Data type of the item
  33.666 +	 *  @param out Item to insert into the cache
  33.667 +	 *  @param ptr address (cache key) of the item. */
  33.668 +	template <typename T> void set 
  33.669 +		(const Structure& s, 
  33.670 +		const TOUT<T>& out, 
  33.671 +		const Pointer& ptr);
  33.672 +
  33.673 +private:
  33.674 +
  33.675 +	mutable vector<StructureCache> caches;
  33.676 +	const FileDatabase& db;
  33.677 +};
  33.678 +
  33.679 +// -------------------------------------------------------------------------------
  33.680 +// -------------------------------------------------------------------------------
  33.681 +template <> class ObjectCache<Blender::vector> 
  33.682 +{
  33.683 +public:
  33.684 +
  33.685 +	ObjectCache(const FileDatabase&) {}
  33.686 +
  33.687 +	template <typename T> void get(const Structure&, vector<T>&, const Pointer&) {}
  33.688 +	template <typename T> void set(const Structure&, const vector<T>&, const Pointer&) {}
  33.689 +};
  33.690 +
  33.691 +#ifdef _MSC_VER
  33.692 +#	pragma warning(disable:4355)
  33.693 +#endif
  33.694 +
  33.695 +// -------------------------------------------------------------------------------
  33.696 +/** Memory representation of a full BLEND file and all its dependencies. The
  33.697 + *  output aiScene is constructed from an instance of this data structure. */
  33.698 +// -------------------------------------------------------------------------------
  33.699 +class FileDatabase 
  33.700 +{
  33.701 +	template <template <typename> class TOUT> friend class ObjectCache;
  33.702 +
  33.703 +public:
  33.704 +
  33.705 +
  33.706 +	FileDatabase()
  33.707 +		: _cacheArrays(*this)
  33.708 +		, _cache(*this)
  33.709 +		, next_cache_idx()
  33.710 +	{} 
  33.711 +
  33.712 +public:
  33.713 +
  33.714 +	// publicly accessible fields
  33.715 +	bool i64bit;
  33.716 +	bool little;
  33.717 +
  33.718 +	DNA dna;
  33.719 +	boost::shared_ptr< StreamReaderAny > reader;
  33.720 +	vector< FileBlockHead > entries;
  33.721 +
  33.722 +public:
  33.723 +
  33.724 +	Statistics& stats() const {
  33.725 +		return _stats;
  33.726 +	}
  33.727 +
  33.728 +	// For all our templates to work on both shared_ptr's and vector's
  33.729 +	// using the same code, a dummy cache for arrays is provided. Actually,
  33.730 +	// arrays of objects are never cached because we can't easily 
  33.731 +	// ensure their proper destruction.
  33.732 +	template <typename T>
  33.733 +	ObjectCache<boost::shared_ptr>& cache(boost::shared_ptr<T>& /*in*/) const {
  33.734 +		return _cache;
  33.735 +	}
  33.736 +
  33.737 +	template <typename T>
  33.738 +	ObjectCache<vector>& cache(vector<T>& /*in*/) const {
  33.739 +		return _cacheArrays;
  33.740 +	}
  33.741 +
  33.742 +private:
  33.743 +
  33.744 +	
  33.745 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  33.746 +	mutable Statistics _stats;
  33.747 +#endif
  33.748 +
  33.749 +	mutable ObjectCache<vector> _cacheArrays;
  33.750 +	mutable ObjectCache<boost::shared_ptr> _cache;
  33.751 +
  33.752 +	mutable size_t next_cache_idx;
  33.753 +};
  33.754 +
  33.755 +#ifdef _MSC_VER
  33.756 +#	pragma warning(default:4355)
  33.757 +#endif
  33.758 +
  33.759 +// -------------------------------------------------------------------------------
  33.760 +/** Factory to extract a #DNA from the DNA1 file block in a BLEND file. */
  33.761 +// -------------------------------------------------------------------------------
  33.762 +class DNAParser 
  33.763 +{
  33.764 +
  33.765 +public:
  33.766 +
  33.767 +	/** Bind the parser to a empty DNA and an input stream */
  33.768 +	DNAParser(FileDatabase& db)
  33.769 +		: db(db)
  33.770 +	{}
  33.771 +
  33.772 +public:
  33.773 +
  33.774 +	// --------------------------------------------------------
  33.775 +	/** Locate the DNA in the file and parse it. The input
  33.776 +	 *  stream is expected to point to the beginning of the DN1
  33.777 +	 *  chunk at the time this method is called and is
  33.778 +	 *  undefined afterwards.
  33.779 +	 *  @throw DeadlyImportError if the DNA cannot be read.
  33.780 +	 *  @note The position of the stream pointer is undefined
  33.781 +	 *    afterwards.*/
  33.782 +	void Parse ();
  33.783 +
  33.784 +public:
  33.785 +
  33.786 +	/** Obtain a reference to the extracted DNA information */
  33.787 +	const Blender::DNA& GetDNA() const {
  33.788 +		return db.dna;
  33.789 +	}
  33.790 +
  33.791 +private:
  33.792 +
  33.793 +	FileDatabase& db;
  33.794 +};
  33.795 +
  33.796 +	} // end Blend
  33.797 +} // end Assimp
  33.798 +
  33.799 +#include "BlenderDNA.inl"
  33.800 +
  33.801 +#endif
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/libs/assimp/BlenderDNA.inl	Sat Feb 01 19:58:19 2014 +0200
    34.3 @@ -0,0 +1,706 @@
    34.4 +/*
    34.5 +Open Asset Import Library (assimp)
    34.6 +----------------------------------------------------------------------
    34.7 +
    34.8 +Copyright (c) 2006-2012, assimp team
    34.9 +All rights reserved.
   34.10 +
   34.11 +Redistribution and use of this software in source and binary forms, 
   34.12 +with or without modification, are permitted provided that the 
   34.13 +following conditions are met:
   34.14 +
   34.15 +* Redistributions of source code must retain the above
   34.16 +  copyright notice, this list of conditions and the
   34.17 +  following disclaimer.
   34.18 +
   34.19 +* Redistributions in binary form must reproduce the above
   34.20 +  copyright notice, this list of conditions and the
   34.21 +  following disclaimer in the documentation and/or other
   34.22 +  materials provided with the distribution.
   34.23 +
   34.24 +* Neither the name of the assimp team, nor the names of its
   34.25 +  contributors may be used to endorse or promote products
   34.26 +  derived from this software without specific prior
   34.27 +  written permission of the assimp team.
   34.28 +
   34.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   34.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   34.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   34.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   34.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   34.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   34.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   34.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   34.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   34.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   34.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   34.40 +
   34.41 +----------------------------------------------------------------------
   34.42 +*/
   34.43 +
   34.44 +/** @file  BlenderDNA.inl
   34.45 + *  @brief Blender `DNA` (file format specification embedded in 
   34.46 + *    blend file itself) loader.
   34.47 + */
   34.48 +#ifndef INCLUDED_AI_BLEND_DNA_INL
   34.49 +#define INCLUDED_AI_BLEND_DNA_INL
   34.50 +
   34.51 +namespace Assimp	{
   34.52 +	namespace Blender {
   34.53 +
   34.54 +//--------------------------------------------------------------------------------
   34.55 +const Field& Structure :: operator [] (const std::string& ss) const
   34.56 +{
   34.57 +	std::map<std::string, size_t>::const_iterator it = indices.find(ss);
   34.58 +	if (it == indices.end()) {
   34.59 +		throw Error((Formatter::format(),
   34.60 +			"BlendDNA: Did not find a field named `",ss,"` in structure `",name,"`"
   34.61 +			));
   34.62 +	}
   34.63 +
   34.64 +	return fields[(*it).second];
   34.65 +}
   34.66 +
   34.67 +//--------------------------------------------------------------------------------
   34.68 +const Field* Structure :: Get (const std::string& ss) const
   34.69 +{
   34.70 +	std::map<std::string, size_t>::const_iterator it = indices.find(ss);
   34.71 +	return it == indices.end() ? NULL : &fields[(*it).second];
   34.72 +}
   34.73 +
   34.74 +//--------------------------------------------------------------------------------
   34.75 +const Field& Structure :: operator [] (const size_t i) const 
   34.76 +{
   34.77 +	if (i >= fields.size()) {
   34.78 +		throw Error((Formatter::format(),
   34.79 +			"BlendDNA: There is no field with index `",i,"` in structure `",name,"`"
   34.80 +			));
   34.81 +	}
   34.82 +
   34.83 +	return fields[i];
   34.84 +}
   34.85 +
   34.86 +//--------------------------------------------------------------------------------
   34.87 +template <typename T> boost::shared_ptr<ElemBase> Structure :: Allocate() const 
   34.88 +{
   34.89 +	return boost::shared_ptr<T>(new T()); 
   34.90 +}
   34.91 +
   34.92 +//--------------------------------------------------------------------------------
   34.93 +template <typename T> void Structure :: Convert(
   34.94 +	boost::shared_ptr<ElemBase> in,
   34.95 +	const FileDatabase& db) const 
   34.96 +{
   34.97 +	Convert<T> (*static_cast<T*> ( in.get() ),db);
   34.98 +}
   34.99 +
  34.100 +//--------------------------------------------------------------------------------
  34.101 +template <int error_policy, typename T, size_t M>
  34.102 +void Structure :: ReadFieldArray(T (& out)[M], const char* name, const FileDatabase& db) const
  34.103 +{
  34.104 +	const StreamReaderAny::pos old = db.reader->GetCurrentPos();
  34.105 +	try {
  34.106 +		const Field& f = (*this)[name];
  34.107 +		const Structure& s = db.dna[f.type];
  34.108 +
  34.109 +		// is the input actually an array?
  34.110 +		if (!(f.flags & FieldFlag_Array)) {
  34.111 +			throw Error((Formatter::format(),"Field `",name,"` of structure `",
  34.112 +				this->name,"` ought to be an array of size ",M
  34.113 +				));
  34.114 +		}
  34.115 +
  34.116 +		db.reader->IncPtr(f.offset);
  34.117 +
  34.118 +		// size conversions are always allowed, regardless of error_policy
  34.119 +		unsigned int i = 0;
  34.120 +		for(; i < std::min(f.array_sizes[0],M); ++i) {
  34.121 +			s.Convert(out[i],db);
  34.122 +		}
  34.123 +		for(; i < M; ++i) {
  34.124 +			_defaultInitializer<ErrorPolicy_Igno>()(out[i]);
  34.125 +		}
  34.126 +	}
  34.127 +	catch (const Error& e) {
  34.128 +		_defaultInitializer<error_policy>()(out,e.what());
  34.129 +	}
  34.130 +
  34.131 +	// and recover the previous stream position
  34.132 +	db.reader->SetCurrentPos(old);
  34.133 +
  34.134 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  34.135 +	++db.stats().fields_read;
  34.136 +#endif
  34.137 +}
  34.138 +
  34.139 +//--------------------------------------------------------------------------------
  34.140 +template <int error_policy, typename T, size_t M, size_t N>
  34.141 +void Structure :: ReadFieldArray2(T (& out)[M][N], const char* name, const FileDatabase& db) const
  34.142 +{
  34.143 +	const StreamReaderAny::pos old = db.reader->GetCurrentPos();
  34.144 +	try {
  34.145 +		const Field& f = (*this)[name];
  34.146 +		const Structure& s = db.dna[f.type];
  34.147 +
  34.148 +		// is the input actually an array?
  34.149 +		if (!(f.flags & FieldFlag_Array)) {
  34.150 +			throw Error((Formatter::format(),"Field `",name,"` of structure `",
  34.151 +				this->name,"` ought to be an array of size ",M,"*",N
  34.152 +				));
  34.153 +		}
  34.154 +
  34.155 +		db.reader->IncPtr(f.offset);
  34.156 +
  34.157 +		// size conversions are always allowed, regardless of error_policy
  34.158 +		unsigned int i = 0;
  34.159 +		for(; i < std::min(f.array_sizes[0],M); ++i) {
  34.160 +			unsigned int j = 0;
  34.161 +			for(; j < std::min(f.array_sizes[1],N); ++j) {
  34.162 +				s.Convert(out[i][j],db);
  34.163 +			}
  34.164 +			for(; j < N; ++j) {
  34.165 +				_defaultInitializer<ErrorPolicy_Igno>()(out[i][j]);
  34.166 +			}
  34.167 +		}
  34.168 +		for(; i < M; ++i) {
  34.169 +			_defaultInitializer<ErrorPolicy_Igno>()(out[i]);
  34.170 +		}
  34.171 +	}
  34.172 +	catch (const Error& e) {
  34.173 +		_defaultInitializer<error_policy>()(out,e.what());
  34.174 +	}
  34.175 +
  34.176 +	// and recover the previous stream position
  34.177 +	db.reader->SetCurrentPos(old);
  34.178 +
  34.179 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  34.180 +	++db.stats().fields_read;
  34.181 +#endif
  34.182 +}
  34.183 +
  34.184 +//--------------------------------------------------------------------------------
  34.185 +template <int error_policy, template <typename> class TOUT, typename T>
  34.186 +void Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabase& db) const
  34.187 +{
  34.188 +	const StreamReaderAny::pos old = db.reader->GetCurrentPos();
  34.189 +	Pointer ptrval;
  34.190 +	const Field* f;
  34.191 +	try {
  34.192 +		f = &(*this)[name];
  34.193 +
  34.194 +		// sanity check, should never happen if the genblenddna script is right
  34.195 +		if (!(f->flags & FieldFlag_Pointer)) {
  34.196 +			throw Error((Formatter::format(),"Field `",name,"` of structure `",
  34.197 +				this->name,"` ought to be a pointer"));
  34.198 +		}
  34.199 +
  34.200 +		db.reader->IncPtr(f->offset);
  34.201 +		Convert(ptrval,db);
  34.202 +		// actually it is meaningless on which Structure the Convert is called
  34.203 +		// because the `Pointer` argument triggers a special implementation.
  34.204 +	}
  34.205 +	catch (const Error& e) {
  34.206 +		_defaultInitializer<error_policy>()(out,e.what());
  34.207 +
  34.208 +		out.reset();
  34.209 +		return;
  34.210 +	}
  34.211 +
  34.212 +	// resolve the pointer and load the corresponding structure
  34.213 +	ResolvePointer(out,ptrval,db,*f);
  34.214 +
  34.215 +	// and recover the previous stream position
  34.216 +	db.reader->SetCurrentPos(old);
  34.217 +
  34.218 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  34.219 +	++db.stats().fields_read;
  34.220 +#endif
  34.221 +}
  34.222 +
  34.223 +//--------------------------------------------------------------------------------
  34.224 +template <int error_policy, template <typename> class TOUT, typename T, size_t N>
  34.225 +void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name, 
  34.226 +	const FileDatabase& db) const
  34.227 +{
  34.228 +	// XXX see if we can reduce this to call to the 'normal' ReadFieldPtr
  34.229 +	const StreamReaderAny::pos old = db.reader->GetCurrentPos();
  34.230 +	Pointer ptrval[N];
  34.231 +	const Field* f;
  34.232 +	try {
  34.233 +		f = &(*this)[name];
  34.234 +
  34.235 +		// sanity check, should never happen if the genblenddna script is right
  34.236 +		if ((FieldFlag_Pointer|FieldFlag_Pointer) != (f->flags & (FieldFlag_Pointer|FieldFlag_Pointer))) {
  34.237 +			throw Error((Formatter::format(),"Field `",name,"` of structure `",
  34.238 +				this->name,"` ought to be a pointer AND an array"));
  34.239 +		}
  34.240 +
  34.241 +		db.reader->IncPtr(f->offset);
  34.242 +
  34.243 +		size_t i = 0;
  34.244 +		for(; i < std::min(f->array_sizes[0],N); ++i) {
  34.245 +			Convert(ptrval[i],db);
  34.246 +		}
  34.247 +		for(; i < N; ++i) {
  34.248 +			_defaultInitializer<ErrorPolicy_Igno>()(ptrval[i]);
  34.249 +		}
  34.250 +
  34.251 +		// actually it is meaningless on which Structure the Convert is called
  34.252 +		// because the `Pointer` argument triggers a special implementation.
  34.253 +	}
  34.254 +	catch (const Error& e) {
  34.255 +		_defaultInitializer<error_policy>()(out,e.what());
  34.256 +		for(size_t i = 0; i < N; ++i) {
  34.257 +			out[i].reset();
  34.258 +		}
  34.259 +		return;
  34.260 +	}
  34.261 +	for(size_t i = 0; i < N; ++i) {
  34.262 +		// resolve the pointer and load the corresponding structure
  34.263 +		ResolvePointer(out[i],ptrval[i],db,*f);
  34.264 +	}
  34.265 +
  34.266 +	// and recover the previous stream position
  34.267 +	db.reader->SetCurrentPos(old);
  34.268 +
  34.269 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  34.270 +	++db.stats().fields_read;
  34.271 +#endif
  34.272 +}
  34.273 +
  34.274 +//--------------------------------------------------------------------------------
  34.275 +template <int error_policy, typename T>
  34.276 +void Structure :: ReadField(T& out, const char* name, const FileDatabase& db) const
  34.277 +{
  34.278 +	const StreamReaderAny::pos old = db.reader->GetCurrentPos();
  34.279 +	try {
  34.280 +		const Field& f = (*this)[name];
  34.281 +		// find the structure definition pertaining to this field
  34.282 +		const Structure& s = db.dna[f.type];
  34.283 +
  34.284 +		db.reader->IncPtr(f.offset);
  34.285 +		s.Convert(out,db);
  34.286 +	}
  34.287 +	catch (const Error& e) {
  34.288 +		_defaultInitializer<error_policy>()(out,e.what());
  34.289 +	}
  34.290 +
  34.291 +	// and recover the previous stream position
  34.292 +	db.reader->SetCurrentPos(old);
  34.293 +
  34.294 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  34.295 +	++db.stats().fields_read;
  34.296 +#endif
  34.297 +}
  34.298 +
  34.299 +
  34.300 +//--------------------------------------------------------------------------------
  34.301 +template <template <typename> class TOUT, typename T>
  34.302 +void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const 
  34.303 +{
  34.304 +	out.reset();
  34.305 +	if (!ptrval.val) { 
  34.306 +		return;
  34.307 +	}
  34.308 +	const Structure& s = db.dna[f.type];
  34.309 +	// find the file block the pointer is pointing to
  34.310 +	const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
  34.311 +
  34.312 +	// also determine the target type from the block header
  34.313 +	// and check if it matches the type which we expect.
  34.314 +	const Structure& ss = db.dna[block->dna_index];
  34.315 +	if (ss != s) {
  34.316 +		throw Error((Formatter::format(),"Expected target to be of type `",s.name,
  34.317 +			"` but seemingly it is a `",ss.name,"` instead"
  34.318 +			));
  34.319 +	}
  34.320 +
  34.321 +	// try to retrieve the object from the cache
  34.322 +	db.cache(out).get(s,out,ptrval); 
  34.323 +	if (out) {
  34.324 +		return;
  34.325 +	}
  34.326 +
  34.327 +	// seek to this location, but save the previous stream pointer.
  34.328 +	const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
  34.329 +	db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
  34.330 +	// FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
  34.331 +	// I really ought to improve StreamReader to work with 64 bit indices exclusively.
  34.332 +
  34.333 +	// continue conversion after allocating the required storage
  34.334 +	size_t num = block->size / ss.size; 
  34.335 +	T* o = _allocate(out,num);
  34.336 +
  34.337 +	// cache the object before we convert it to avoid cyclic recursion.
  34.338 +	db.cache(out).set(s,out,ptrval); 
  34.339 +
  34.340 +	for (size_t i = 0; i < num; ++i,++o) {
  34.341 +		s.Convert(*o,db);
  34.342 +	}
  34.343 +
  34.344 +	db.reader->SetCurrentPos(pold);
  34.345 +
  34.346 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  34.347 +	if(out) {
  34.348 +		++db.stats().pointers_resolved;
  34.349 +	}
  34.350 +#endif
  34.351 +}
  34.352 +
  34.353 +//--------------------------------------------------------------------------------
  34.354 +inline void Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, const FileDatabase& db, const Field& /*f*/) const
  34.355 +{
  34.356 +	// Currently used exclusively by PackedFile::data to represent
  34.357 +	// a simple offset into the mapped BLEND file. 
  34.358 +	out.reset();
  34.359 +	if (!ptrval.val) { 
  34.360 +		return;
  34.361 +	}
  34.362 +
  34.363 +	// find the file block the pointer is pointing to
  34.364 +	const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
  34.365 +
  34.366 +	out =  boost::shared_ptr< FileOffset > (new FileOffset());
  34.367 +	out->val = block->start+ static_cast<size_t>((ptrval.val - block->address.val) );
  34.368 +}
  34.369 +
  34.370 +//--------------------------------------------------------------------------------
  34.371 +template <template <typename> class TOUT, typename T>
  34.372 +void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const 
  34.373 +{
  34.374 +	// This is a function overload, not a template specialization. According to
  34.375 +	// the partial ordering rules, it should be selected by the compiler
  34.376 +	// for array-of-pointer inputs, i.e. Object::mats.
  34.377 +
  34.378 +	out.reset();
  34.379 +	if (!ptrval.val) { 
  34.380 +		return;
  34.381 +	}
  34.382 +
  34.383 +	// find the file block the pointer is pointing to
  34.384 +	const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
  34.385 +	const size_t num = block->size / (db.i64bit?8:4); 
  34.386 +
  34.387 +	// keep the old stream position
  34.388 +	const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
  34.389 +	db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
  34.390 +
  34.391 +	// allocate raw storage for the array
  34.392 +	out.resize(num);
  34.393 +	for (size_t i = 0; i< num; ++i) {
  34.394 +		Pointer val;
  34.395 +		Convert(val,db);
  34.396 +
  34.397 +		// and resolve the pointees
  34.398 +		ResolvePointer(out[i],val,db,f); 
  34.399 +	}
  34.400 +
  34.401 +	db.reader->SetCurrentPos(pold);
  34.402 +}
  34.403 +
  34.404 +//--------------------------------------------------------------------------------
  34.405 +template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out, 
  34.406 +	const Pointer & ptrval, 
  34.407 +	const FileDatabase& db, 
  34.408 +	const Field& /*f*/
  34.409 +) const 
  34.410 +{
  34.411 +	// Special case when the data type needs to be determined at runtime.
  34.412 +	// Less secure than in the `strongly-typed` case.
  34.413 +
  34.414 +	out.reset();
  34.415 +	if (!ptrval.val) { 
  34.416 +		return;
  34.417 +	}
  34.418 +
  34.419 +	// find the file block the pointer is pointing to
  34.420 +	const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
  34.421 +
  34.422 +	// determine the target type from the block header
  34.423 +	const Structure& s = db.dna[block->dna_index];
  34.424 +
  34.425 +	// try to retrieve the object from the cache
  34.426 +	db.cache(out).get(s,out,ptrval); 
  34.427 +	if (out) {
  34.428 +		return;
  34.429 +	}
  34.430 +
  34.431 +	// seek to this location, but save the previous stream pointer.
  34.432 +	const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
  34.433 +	db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
  34.434 +	// FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
  34.435 +	// I really ought to improve StreamReader to work with 64 bit indices exclusively.
  34.436 +
  34.437 +	// continue conversion after allocating the required storage
  34.438 +	DNA::FactoryPair builders = db.dna.GetBlobToStructureConverter(s,db);
  34.439 +	if (!builders.first) {
  34.440 +		// this might happen if DNA::RegisterConverters hasn't been called so far
  34.441 +		// or if the target type is not contained in `our` DNA.
  34.442 +		out.reset();
  34.443 +		DefaultLogger::get()->warn((Formatter::format(),
  34.444 +			"Failed to find a converter for the `",s.name,"` structure"
  34.445 +			));
  34.446 +		return;
  34.447 +	}
  34.448 +
  34.449 +	// allocate the object hull
  34.450 +	out = (s.*builders.first)();
  34.451 +	
  34.452 +	// cache the object immediately to prevent infinite recursion in a 
  34.453 +	// circular list with a single element (i.e. a self-referencing element).
  34.454 +	db.cache(out).set(s,out,ptrval);
  34.455 +
  34.456 +	// and do the actual conversion
  34.457 +	(s.*builders.second)(out,db);
  34.458 +	db.reader->SetCurrentPos(pold);
  34.459 +	
  34.460 +	// store a pointer to the name string of the actual type
  34.461 +	// in the object itself. This allows the conversion code
  34.462 +	// to perform additional type checking.
  34.463 +	out->dna_type = s.name.c_str();
  34.464 +
  34.465 +	
  34.466 +
  34.467 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  34.468 +	++db.stats().pointers_resolved;
  34.469 +#endif
  34.470 +}
  34.471 +
  34.472 +//--------------------------------------------------------------------------------
  34.473 +const FileBlockHead* Structure :: LocateFileBlockForAddress(const Pointer & ptrval, const FileDatabase& db) const 
  34.474 +{
  34.475 +	// the file blocks appear in list sorted by
  34.476 +	// with ascending base addresses so we can run a 
  34.477 +	// binary search to locate the pointee quickly.
  34.478 +
  34.479 +	// NOTE: Blender seems to distinguish between side-by-side
  34.480 +	// data (stored in the same data block) and far pointers,
  34.481 +	// which are only used for structures starting with an ID.
  34.482 +	// We don't need to make this distinction, our algorithm
  34.483 +	// works regardless where the data is stored.
  34.484 +	vector<FileBlockHead>::const_iterator it = std::lower_bound(db.entries.begin(),db.entries.end(),ptrval);
  34.485 +	if (it == db.entries.end()) {
  34.486 +		// this is crucial, pointers may not be invalid.
  34.487 +		// this is either a corrupted file or an attempted attack.
  34.488 +		throw DeadlyImportError((Formatter::format(),"Failure resolving pointer 0x",
  34.489 +			std::hex,ptrval.val,", no file block falls into this address range"
  34.490 +			));
  34.491 +	}
  34.492 +	if (ptrval.val >= (*it).address.val + (*it).size) {
  34.493 +		throw DeadlyImportError((Formatter::format(),"Failure resolving pointer 0x",
  34.494 +			std::hex,ptrval.val,", nearest file block starting at 0x",
  34.495 +			(*it).address.val," ends at 0x",
  34.496 +			(*it).address.val + (*it).size
  34.497 +			));
  34.498 +	}
  34.499 +	return &*it;
  34.500 +}
  34.501 +
  34.502 +// ------------------------------------------------------------------------------------------------
  34.503 +// NOTE: The MSVC debugger keeps showing up this annoying `a cast to a smaller data type has 
  34.504 +// caused a loss of data`-warning. Avoid this warning by a masking with an appropriate bitmask.
  34.505 +
  34.506 +template <typename T> struct signless;
  34.507 +template <> struct signless<char> {typedef unsigned char type;};
  34.508 +template <> struct signless<short> {typedef unsigned short type;};
  34.509 +template <> struct signless<int> {typedef unsigned int type;};
  34.510 +
  34.511 +template <typename T>
  34.512 +struct static_cast_silent {	
  34.513 +	template <typename V>
  34.514 +	T operator()(V in) {
  34.515 +		return static_cast<T>(in & static_cast<typename signless<T>::type>(-1));
  34.516 +	}
  34.517 +};
  34.518 +
  34.519 +template <> struct static_cast_silent<float> {
  34.520 +	template <typename V> float  operator()(V in) {
  34.521 +		return static_cast<float> (in);
  34.522 +	}
  34.523 +};
  34.524 +
  34.525 +template <> struct static_cast_silent<double> {
  34.526 +	template <typename V> double operator()(V in) {
  34.527 +		return static_cast<double>(in);
  34.528 +	}
  34.529 +};
  34.530 +
  34.531 +// ------------------------------------------------------------------------------------------------
  34.532 +template <typename T> inline void ConvertDispatcher(T& out, const Structure& in,const FileDatabase& db) 
  34.533 +{
  34.534 +	if (in.name == "int") {
  34.535 +		out = static_cast_silent<T>()(db.reader->GetU4());
  34.536 +	}
  34.537 +	else if (in.name == "short") {
  34.538 +		out = static_cast_silent<T>()(db.reader->GetU2());
  34.539 +	}
  34.540 +	else if (in.name == "char") {
  34.541 +		out = static_cast_silent<T>()(db.reader->GetU1());
  34.542 +	}
  34.543 +	else if (in.name == "float") {
  34.544 +		out = static_cast<T>(db.reader->GetF4());
  34.545 +	}
  34.546 +	else if (in.name == "double") {
  34.547 +		out = static_cast<T>(db.reader->GetF8());
  34.548 +	}
  34.549 +	else {
  34.550 +		throw DeadlyImportError("Unknown source for conversion to primitive data type: "+in.name);
  34.551 +	}
  34.552 +}
  34.553 +
  34.554 +// ------------------------------------------------------------------------------------------------
  34.555 +template <> inline void Structure :: Convert<int>    (int& dest,const FileDatabase& db) const
  34.556 +{
  34.557 +	ConvertDispatcher(dest,*this,db);
  34.558 +}
  34.559 +
  34.560 +// ------------------------------------------------------------------------------------------------
  34.561 +template <> inline void Structure :: Convert<short>  (short& dest,const FileDatabase& db) const
  34.562 +{
  34.563 +	// automatic rescaling from short to float and vice versa (seems to be used by normals)
  34.564 +	if (name == "float") {
  34.565 +		dest = static_cast<short>(db.reader->GetF4() * 32767.f);
  34.566 +		//db.reader->IncPtr(-4);
  34.567 +		return;
  34.568 +	}
  34.569 +	else if (name == "double") {
  34.570 +		dest = static_cast<short>(db.reader->GetF8() * 32767.);
  34.571 +		//db.reader->IncPtr(-8);
  34.572 +		return;
  34.573 +	}
  34.574 +	ConvertDispatcher(dest,*this,db);
  34.575 +}
  34.576 +
  34.577 +// ------------------------------------------------------------------------------------------------
  34.578 +template <> inline void Structure :: Convert<char>   (char& dest,const FileDatabase& db) const
  34.579 +{
  34.580 +	// automatic rescaling from char to float and vice versa (seems useful for RGB colors)
  34.581 +	if (name == "float") {
  34.582 +		dest = static_cast<char>(db.reader->GetF4() * 255.f);
  34.583 +		return;
  34.584 +	}
  34.585 +	else if (name == "double") {
  34.586 +		dest = static_cast<char>(db.reader->GetF8() * 255.f);
  34.587 +		return;
  34.588 +	}
  34.589 +	ConvertDispatcher(dest,*this,db);
  34.590 +}
  34.591 +
  34.592 +// ------------------------------------------------------------------------------------------------
  34.593 +template <> inline void Structure :: Convert<float>  (float& dest,const FileDatabase& db) const
  34.594 +{
  34.595 +	// automatic rescaling from char to float and vice versa (seems useful for RGB colors)
  34.596 +	if (name == "char") {
  34.597 +		dest = db.reader->GetI1() / 255.f;
  34.598 +		return;
  34.599 +	}
  34.600 +	// automatic rescaling from short to float and vice versa (used by normals)
  34.601 +	else if (name == "short") {
  34.602 +		dest = db.reader->GetI2() / 32767.f;
  34.603 +		return;
  34.604 +	}
  34.605 +	ConvertDispatcher(dest,*this,db);
  34.606 +}
  34.607 +
  34.608 +// ------------------------------------------------------------------------------------------------
  34.609 +template <> inline void Structure :: Convert<double> (double& dest,const FileDatabase& db) const
  34.610 +{
  34.611 +	if (name == "char") {
  34.612 +		dest = db.reader->GetI1() / 255.;
  34.613 +		return;
  34.614 +	}
  34.615 +	else if (name == "short") {
  34.616 +		dest = db.reader->GetI2() / 32767.;
  34.617 +		return;
  34.618 +	}
  34.619 +	ConvertDispatcher(dest,*this,db);
  34.620 +}
  34.621 +
  34.622 +// ------------------------------------------------------------------------------------------------
  34.623 +template <> inline void Structure :: Convert<Pointer> (Pointer& dest,const FileDatabase& db) const
  34.624 +{
  34.625 +	if (db.i64bit) {
  34.626 +		dest.val = db.reader->GetU8();
  34.627 +		//db.reader->IncPtr(-8);
  34.628 +		return;
  34.629 +	}
  34.630 +	dest.val = db.reader->GetU4();
  34.631 +	//db.reader->IncPtr(-4);
  34.632 +}
  34.633 +
  34.634 +//--------------------------------------------------------------------------------
  34.635 +const Structure& DNA :: operator [] (const std::string& ss) const
  34.636 +{
  34.637 +	std::map<std::string, size_t>::const_iterator it = indices.find(ss);
  34.638 +	if (it == indices.end()) {
  34.639 +		throw Error((Formatter::format(),
  34.640 +			"BlendDNA: Did not find a structure named `",ss,"`"
  34.641 +			));
  34.642 +	}
  34.643 +
  34.644 +	return structures[(*it).second];
  34.645 +}
  34.646 +
  34.647 +//--------------------------------------------------------------------------------
  34.648 +const Structure* DNA :: Get (const std::string& ss) const
  34.649 +{
  34.650 +	std::map<std::string, size_t>::const_iterator it = indices.find(ss);
  34.651 +	return it == indices.end() ? NULL : &structures[(*it).second];
  34.652 +}
  34.653 +
  34.654 +//--------------------------------------------------------------------------------
  34.655 +const Structure& DNA :: operator [] (const size_t i) const 
  34.656 +{
  34.657 +	if (i >= structures.size()) {
  34.658 +		throw Error((Formatter::format(),
  34.659 +			"BlendDNA: There is no structure with index `",i,"`"
  34.660 +			));
  34.661 +	}
  34.662 +
  34.663 +	return structures[i];
  34.664 +}
  34.665 +
  34.666 +//--------------------------------------------------------------------------------
  34.667 +template <template <typename> class TOUT> template <typename T> void ObjectCache<TOUT> :: get (
  34.668 +	const Structure& s, 
  34.669 +	TOUT<T>& out, 
  34.670 +	const Pointer& ptr
  34.671 +) const {
  34.672 +
  34.673 +	if(s.cache_idx == static_cast<size_t>(-1)) {
  34.674 +		s.cache_idx = db.next_cache_idx++;
  34.675 +		caches.resize(db.next_cache_idx);
  34.676 +		return;
  34.677 +	}
  34.678 +
  34.679 +	typename StructureCache::const_iterator it = caches[s.cache_idx].find(ptr);
  34.680 +	if (it != caches[s.cache_idx].end()) {
  34.681 +		out = boost::static_pointer_cast<T>( (*it).second );
  34.682 +
  34.683 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  34.684 +		++db.stats().cache_hits;
  34.685 +#endif
  34.686 +	}
  34.687 +	// otherwise, out remains untouched
  34.688 +}
  34.689 +
  34.690 +
  34.691 +//--------------------------------------------------------------------------------
  34.692 +template <template <typename> class TOUT> template <typename T> void ObjectCache<TOUT> :: set (
  34.693 +	const Structure& s, 
  34.694 +	const TOUT<T>& out,
  34.695 +	const Pointer& ptr
  34.696 +) {
  34.697 +	if(s.cache_idx == static_cast<size_t>(-1)) {
  34.698 +		s.cache_idx = db.next_cache_idx++;
  34.699 +		caches.resize(db.next_cache_idx);
  34.700 +	}
  34.701 +	caches[s.cache_idx][ptr] = boost::static_pointer_cast<ElemBase>( out ); 
  34.702 +
  34.703 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  34.704 +	++db.stats().cached_objects;
  34.705 +#endif
  34.706 +}
  34.707 +
  34.708 +}}
  34.709 +#endif
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/libs/assimp/BlenderIntermediate.h	Sat Feb 01 19:58:19 2014 +0200
    35.3 @@ -0,0 +1,183 @@
    35.4 +/*
    35.5 +Open Asset Import Library (assimp)
    35.6 +----------------------------------------------------------------------
    35.7 +
    35.8 +Copyright (c) 2006-2012, assimp team
    35.9 +All rights reserved.
   35.10 +
   35.11 +Redistribution and use of this software in source and binary forms, 
   35.12 +with or without modification, are permitted provided that the 
   35.13 +following conditions are met:
   35.14 +
   35.15 +* Redistributions of source code must retain the above
   35.16 +  copyright notice, this list of conditions and the
   35.17 +  following disclaimer.
   35.18 +
   35.19 +* Redistributions in binary form must reproduce the above
   35.20 +  copyright notice, this list of conditions and the
   35.21 +  following disclaimer in the documentation and/or other
   35.22 +  materials provided with the distribution.
   35.23 +
   35.24 +* Neither the name of the assimp team, nor the names of its
   35.25 +  contributors may be used to endorse or promote products
   35.26 +  derived from this software without specific prior
   35.27 +  written permission of the assimp team.
   35.28 +
   35.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   35.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   35.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   35.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   35.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   35.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   35.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   35.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   35.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   35.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   35.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35.40 +
   35.41 +----------------------------------------------------------------------
   35.42 +*/
   35.43 +
   35.44 +/** @file  BlenderIntermediate.h
   35.45 + *  @brief Internal utility structures for the BlenderLoader. It also serves
   35.46 + *    as master include file for the whole (internal) Blender subsystem.
   35.47 + */
   35.48 +#ifndef INCLUDED_AI_BLEND_INTERMEDIATE_H
   35.49 +#define INCLUDED_AI_BLEND_INTERMEDIATE_H
   35.50 +
   35.51 +#include "BlenderLoader.h"
   35.52 +#include "BlenderDNA.h"
   35.53 +#include "BlenderScene.h"
   35.54 +#include "BlenderSceneGen.h"
   35.55 +
   35.56 +#define for_each(x,y) BOOST_FOREACH(x,y)
   35.57 +
   35.58 +namespace Assimp {
   35.59 +namespace Blender {
   35.60 +
   35.61 +	// --------------------------------------------------------------------
   35.62 +	/** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
   35.63 +	// --------------------------------------------------------------------
   35.64 +	template <template <typename,typename> class TCLASS, typename T>
   35.65 +	struct TempArray	{
   35.66 +		typedef TCLASS< T*,std::allocator<T*> > mywrap;
   35.67 +
   35.68 +		TempArray() {
   35.69 +		}
   35.70 +
   35.71 +		~TempArray () {
   35.72 +			for_each(T* elem, arr) {
   35.73 +				delete elem;
   35.74 +			}
   35.75 +		}
   35.76 +
   35.77 +		void dismiss() {
   35.78 +			arr.clear();
   35.79 +		}
   35.80 +
   35.81 +		mywrap* operator -> () {
   35.82 +			return &arr;
   35.83 +		}
   35.84 +
   35.85 +		operator mywrap& () {
   35.86 +			return arr;
   35.87 +		}
   35.88 +
   35.89 +		operator const mywrap& () const {
   35.90 +			return arr;
   35.91 +		}
   35.92 +
   35.93 +		mywrap& get () {
   35.94 +			return arr;
   35.95 +		}
   35.96 +
   35.97 +		const mywrap& get () const {
   35.98 +			return arr;
   35.99 +		}
  35.100 +
  35.101 +		T* operator[] (size_t idx) const {
  35.102 +			return arr[idx];
  35.103 +		}
  35.104 +
  35.105 +		T*& operator[] (size_t idx) {
  35.106 +			return arr[idx];
  35.107 +		}
  35.108 +
  35.109 +	private:
  35.110 +		// no copy semantics
  35.111 +		void operator= (const TempArray&)  {
  35.112 +		}
  35.113 +
  35.114 +		TempArray(const TempArray& arr) {
  35.115 +		}
  35.116 +
  35.117 +	private:
  35.118 +		mywrap arr;
  35.119 +	};
  35.120 +	
  35.121 +#ifdef _MSC_VER
  35.122 +#	pragma warning(disable:4351)
  35.123 +#endif
  35.124 +	// --------------------------------------------------------------------
  35.125 +	/** ConversionData acts as intermediate storage location for
  35.126 +	 *  the various ConvertXXX routines in BlenderImporter.*/
  35.127 +	// --------------------------------------------------------------------
  35.128 +	struct ConversionData	
  35.129 +	{
  35.130 +		ConversionData(const FileDatabase& db)
  35.131 +			: sentinel_cnt()
  35.132 +			, next_texture()
  35.133 +			, db(db)
  35.134 +		{}
  35.135 +
  35.136 +		std::set<const Object*> objects;
  35.137 +
  35.138 +		TempArray <std::vector, aiMesh> meshes;
  35.139 +		TempArray <std::vector, aiCamera> cameras;
  35.140 +		TempArray <std::vector, aiLight> lights;
  35.141 +		TempArray <std::vector, aiMaterial> materials;
  35.142 +		TempArray <std::vector, aiTexture> textures;
  35.143 +
  35.144 +		// set of all materials referenced by at least one mesh in the scene
  35.145 +		std::deque< boost::shared_ptr< Material > > materials_raw;
  35.146 +
  35.147 +		// counter to name sentinel textures inserted as substitutes for procedural textures.
  35.148 +		unsigned int sentinel_cnt;
  35.149 +
  35.150 +		// next texture ID for each texture type, respectively
  35.151 +		unsigned int next_texture[aiTextureType_UNKNOWN+1];
  35.152 +
  35.153 +		// original file data
  35.154 +		const FileDatabase& db;
  35.155 +	};
  35.156 +#ifdef _MSC_VER
  35.157 +#	pragma warning(default:4351)
  35.158 +#endif
  35.159 +
  35.160 +// ------------------------------------------------------------------------------------------------
  35.161 +inline const char* GetTextureTypeDisplayString(Tex::Type t)
  35.162 +{
  35.163 +	switch (t)	{
  35.164 +	case Tex::Type_CLOUDS		:  return  "Clouds";			
  35.165 +	case Tex::Type_WOOD			:  return  "Wood";			
  35.166 +	case Tex::Type_MARBLE		:  return  "Marble";			
  35.167 +	case Tex::Type_MAGIC		:  return  "Magic";		
  35.168 +	case Tex::Type_BLEND		:  return  "Blend";			
  35.169 +	case Tex::Type_STUCCI		:  return  "Stucci";			
  35.170 +	case Tex::Type_NOISE		:  return  "Noise";			
  35.171 +	case Tex::Type_PLUGIN		:  return  "Plugin";			
  35.172 +	case Tex::Type_MUSGRAVE		:  return  "Musgrave";		
  35.173 +	case Tex::Type_VORONOI		:  return  "Voronoi";			
  35.174 +	case Tex::Type_DISTNOISE	:  return  "DistortedNoise";	
  35.175 +	case Tex::Type_ENVMAP		:  return  "EnvMap";	
  35.176 +	case Tex::Type_IMAGE		:  return  "Image";	
  35.177 +	default: 
  35.178 +		break;
  35.179 +	}
  35.180 +	return "<Unknown>";
  35.181 +}
  35.182 +
  35.183 +} // ! Blender
  35.184 +} // ! Assimp
  35.185 +
  35.186 +#endif // ! INCLUDED_AI_BLEND_INTERMEDIATE_H
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/libs/assimp/BlenderLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
    36.3 @@ -0,0 +1,1086 @@
    36.4 +
    36.5 +/*
    36.6 +Open Asset Import Library (assimp)
    36.7 +----------------------------------------------------------------------
    36.8 +
    36.9 +Copyright (c) 2006-2012, assimp team
   36.10 +All rights reserved.
   36.11 +
   36.12 +Redistribution and use of this software in source and binary forms, 
   36.13 +with or without modification, are permitted provided that the 
   36.14 +following conditions are met:
   36.15 +
   36.16 +* Redistributions of source code must retain the above
   36.17 +  copyright notice, this list of conditions and the
   36.18 +  following disclaimer.
   36.19 +
   36.20 +* Redistributions in binary form must reproduce the above
   36.21 +  copyright notice, this list of conditions and the
   36.22 +  following disclaimer in the documentation and/or other
   36.23 +  materials provided with the distribution.
   36.24 +
   36.25 +* Neither the name of the assimp team, nor the names of its
   36.26 +  contributors may be used to endorse or promote products
   36.27 +  derived from this software without specific prior
   36.28 +  written permission of the assimp team.
   36.29 +
   36.30 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   36.31 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   36.32 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   36.33 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   36.34 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   36.35 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   36.36 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   36.37 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   36.38 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   36.39 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   36.40 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   36.41 +
   36.42 +----------------------------------------------------------------------
   36.43 +*/
   36.44 +
   36.45 +/** @file  BlenderLoader.cpp
   36.46 + *  @brief Implementation of the Blender3D importer class.
   36.47 + */
   36.48 +#include "AssimpPCH.h"
   36.49 +
   36.50 +//#define ASSIMP_BUILD_NO_COMPRESSED_BLEND
   36.51 +// Uncomment this to disable support for (gzip)compressed .BLEND files
   36.52 +
   36.53 +#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
   36.54 +
   36.55 +#include "BlenderIntermediate.h"
   36.56 +#include "BlenderModifier.h"
   36.57 +
   36.58 +#include "StreamReader.h"
   36.59 +#include "MemoryIOWrapper.h"
   36.60 +
   36.61 +// zlib is needed for compressed blend files 
   36.62 +#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
   36.63 +#	ifdef ASSIMP_BUILD_NO_OWN_ZLIB
   36.64 +#		include <zlib.h>
   36.65 +#	else
   36.66 +#		include "../contrib/zlib/zlib.h"
   36.67 +#	endif
   36.68 +#endif
   36.69 +
   36.70 +namespace Assimp {
   36.71 +	template<> const std::string LogFunctions<BlenderImporter>::log_prefix = "BLEND: ";
   36.72 +}
   36.73 +
   36.74 +using namespace Assimp;
   36.75 +using namespace Assimp::Blender;
   36.76 +using namespace Assimp::Formatter;
   36.77 +
   36.78 +static const aiImporterDesc blenderDesc = {
   36.79 +	"Blender 3D Importer \nhttp://www.blender3d.org",
   36.80 +	"",
   36.81 +	"",
   36.82 +	"No animation support yet",
   36.83 +	aiImporterFlags_SupportBinaryFlavour,
   36.84 +	0,
   36.85 +	0,
   36.86 +	2,
   36.87 +	50,
   36.88 +	"blend"
   36.89 +};
   36.90 +
   36.91 +
   36.92 +// ------------------------------------------------------------------------------------------------
   36.93 +// Constructor to be privately used by Importer
   36.94 +BlenderImporter::BlenderImporter()
   36.95 +: modifier_cache(new BlenderModifierShowcase())
   36.96 +{}
   36.97 +
   36.98 +// ------------------------------------------------------------------------------------------------
   36.99 +// Destructor, private as well 
  36.100 +BlenderImporter::~BlenderImporter()
  36.101 +{
  36.102 +	delete modifier_cache;
  36.103 +}
  36.104 +
  36.105 +// ------------------------------------------------------------------------------------------------
  36.106 +// Returns whether the class can handle the format of the given file. 
  36.107 +bool BlenderImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  36.108 +{
  36.109 +	const std::string& extension = GetExtension(pFile);
  36.110 +	if (extension == "blend") {
  36.111 +		return true;
  36.112 +	}
  36.113 +
  36.114 +	else if ((!extension.length() || checkSig) && pIOHandler)	{
  36.115 +		// note: this won't catch compressed files
  36.116 +		const char* tokens[] = {"BLENDER"};
  36.117 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
  36.118 +	}
  36.119 +	return false;
  36.120 +}
  36.121 +
  36.122 +// ------------------------------------------------------------------------------------------------
  36.123 +// List all extensions handled by this loader
  36.124 +void BlenderImporter::GetExtensionList(std::set<std::string>& app) 
  36.125 +{
  36.126 +	app.insert("blend");
  36.127 +}
  36.128 +
  36.129 +// ------------------------------------------------------------------------------------------------
  36.130 +// Loader registry entry
  36.131 +const aiImporterDesc* BlenderImporter::GetInfo () const
  36.132 +{
  36.133 +	return &blenderDesc;
  36.134 +}
  36.135 +
  36.136 +// ------------------------------------------------------------------------------------------------
  36.137 +// Setup configuration properties for the loader
  36.138 +void BlenderImporter::SetupProperties(const Importer* /*pImp*/)
  36.139 +{
  36.140 +	// nothing to be done for the moment
  36.141 +}
  36.142 +
  36.143 +struct free_it
  36.144 +{
  36.145 +	free_it(void* free) : free(free) {}
  36.146 +	~free_it() {
  36.147 +		::free(this->free);
  36.148 +	}
  36.149 +
  36.150 +	void* free;
  36.151 +};
  36.152 +
  36.153 +// ------------------------------------------------------------------------------------------------
  36.154 +// Imports the given file into the given scene structure. 
  36.155 +void BlenderImporter::InternReadFile( const std::string& pFile, 
  36.156 +	aiScene* pScene, IOSystem* pIOHandler)
  36.157 +{
  36.158 +#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
  36.159 +	Bytef* dest = NULL;
  36.160 +	free_it free_it_really(dest);
  36.161 +#endif
  36.162 +
  36.163 +	FileDatabase file; 
  36.164 +	boost::shared_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
  36.165 +	if (!stream) {
  36.166 +		ThrowException("Could not open file for reading");
  36.167 +	}
  36.168 +
  36.169 +	char magic[8] = {0};
  36.170 +	stream->Read(magic,7,1);
  36.171 +	if (strcmp(magic,"BLENDER")) {
  36.172 +		// Check for presence of the gzip header. If yes, assume it is a
  36.173 +		// compressed blend file and try uncompressing it, else fail. This is to
  36.174 +		// avoid uncompressing random files which our loader might end up with.
  36.175 +#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
  36.176 +		ThrowException("BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?");
  36.177 +#else
  36.178 +
  36.179 +		if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
  36.180 +			ThrowException("BLENDER magic bytes are missing, couldn't find GZIP header either");
  36.181 +		}
  36.182 +
  36.183 +		LogDebug("Found no BLENDER magic word but a GZIP header, might be a compressed file");
  36.184 +		if (magic[2] != 8) {
  36.185 +			ThrowException("Unsupported GZIP compression method");
  36.186 +		}
  36.187 +
  36.188 +		// http://www.gzip.org/zlib/rfc-gzip.html#header-trailer
  36.189 +		stream->Seek(0L,aiOrigin_SET);
  36.190 +		boost::shared_ptr<StreamReaderLE> reader = boost::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
  36.191 +
  36.192 +		// build a zlib stream
  36.193 +		z_stream zstream;
  36.194 +		zstream.opaque = Z_NULL;
  36.195 +		zstream.zalloc = Z_NULL;
  36.196 +		zstream.zfree  = Z_NULL;
  36.197 +		zstream.data_type = Z_BINARY;
  36.198 +
  36.199 +		// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
  36.200 +		inflateInit2(&zstream, 16+MAX_WBITS);
  36.201 +
  36.202 +		zstream.next_in   = reinterpret_cast<Bytef*>( reader->GetPtr() );
  36.203 +		zstream.avail_in  = reader->GetRemainingSize();
  36.204 +
  36.205 +		size_t total = 0l;
  36.206 +
  36.207 +		// and decompress the data .... do 1k chunks in the hope that we won't kill the stack
  36.208 +#define MYBLOCK 1024
  36.209 +		Bytef block[MYBLOCK];
  36.210 +		int ret;
  36.211 +		do {
  36.212 +			zstream.avail_out = MYBLOCK;
  36.213 +			zstream.next_out = block;
  36.214 +			ret = inflate(&zstream, Z_NO_FLUSH);
  36.215 +
  36.216 +			if (ret != Z_STREAM_END && ret != Z_OK) {
  36.217 +				ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .BLEND file");
  36.218 +			}
  36.219 +			const size_t have = MYBLOCK - zstream.avail_out;
  36.220 +			total += have;
  36.221 +			dest = reinterpret_cast<Bytef*>( realloc(dest,total) );
  36.222 +			memcpy(dest + total - have,block,have);
  36.223 +		} 
  36.224 +		while (ret != Z_STREAM_END);
  36.225 +
  36.226 +		// terminate zlib
  36.227 +		inflateEnd(&zstream);
  36.228 +
  36.229 +		// replace the input stream with a memory stream
  36.230 +		stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(dest),total)); 
  36.231 +
  36.232 +		// .. and retry
  36.233 +		stream->Read(magic,7,1);
  36.234 +		if (strcmp(magic,"BLENDER")) {
  36.235 +			ThrowException("Found no BLENDER magic word in decompressed GZIP file");
  36.236 +		}
  36.237 +#endif
  36.238 +	}
  36.239 +
  36.240 +	file.i64bit = (stream->Read(magic,1,1),magic[0]=='-');
  36.241 +	file.little = (stream->Read(magic,1,1),magic[0]=='v');
  36.242 +
  36.243 +	stream->Read(magic,3,1);
  36.244 +	magic[3] = '\0';
  36.245 +
  36.246 +	LogInfo((format(),"Blender version is ",magic[0],".",magic+1,
  36.247 +		" (64bit: ",file.i64bit?"true":"false",
  36.248 +		", little endian: ",file.little?"true":"false",")"
  36.249 +	));
  36.250 +
  36.251 +	ParseBlendFile(file,stream);
  36.252 +
  36.253 +	Scene scene;
  36.254 +	ExtractScene(scene,file);
  36.255 +
  36.256 +	ConvertBlendFile(pScene,scene,file);
  36.257 +}
  36.258 +
  36.259 +// ------------------------------------------------------------------------------------------------
  36.260 +void BlenderImporter::ParseBlendFile(FileDatabase& out, boost::shared_ptr<IOStream> stream) 
  36.261 +{
  36.262 +	out.reader = boost::shared_ptr<StreamReaderAny>(new StreamReaderAny(stream,out.little));
  36.263 +
  36.264 +	DNAParser dna_reader(out);
  36.265 +	const DNA* dna = NULL;
  36.266 +
  36.267 +	out.entries.reserve(128); { // even small BLEND files tend to consist of many file blocks
  36.268 +		SectionParser parser(*out.reader.get(),out.i64bit);
  36.269 +
  36.270 +		// first parse the file in search for the DNA and insert all other sections into the database
  36.271 +		while ((parser.Next(),1)) {
  36.272 +			const FileBlockHead& head = parser.GetCurrent();
  36.273 +
  36.274 +			if (head.id == "ENDB") {
  36.275 +				break; // only valid end of the file
  36.276 +			}
  36.277 +			else if (head.id == "DNA1") {
  36.278 +				dna_reader.Parse();
  36.279 +				dna = &dna_reader.GetDNA();
  36.280 +				continue;
  36.281 +			}
  36.282 +
  36.283 +			out.entries.push_back(head);
  36.284 +		}
  36.285 +	}
  36.286 +	if (!dna) {
  36.287 +		ThrowException("SDNA not found");
  36.288 +	}
  36.289 +
  36.290 +	std::sort(out.entries.begin(),out.entries.end());
  36.291 +}
  36.292 +
  36.293 +// ------------------------------------------------------------------------------------------------
  36.294 +void BlenderImporter::ExtractScene(Scene& out, const FileDatabase& file) 
  36.295 +{
  36.296 +	const FileBlockHead* block = NULL;
  36.297 +	std::map<std::string,size_t>::const_iterator it = file.dna.indices.find("Scene");
  36.298 +	if (it == file.dna.indices.end()) {
  36.299 +		ThrowException("There is no `Scene` structure record");
  36.300 +	}
  36.301 +
  36.302 +	const Structure& ss = file.dna.structures[(*it).second];
  36.303 +
  36.304 +	// we need a scene somewhere to start with. 
  36.305 +	for_each(const FileBlockHead& bl,file.entries) {
  36.306 +
  36.307 +		// Fix: using the DNA index is more reliable to locate scenes
  36.308 +		//if (bl.id == "SC") {
  36.309 +
  36.310 +		if (bl.dna_index == (*it).second) {
  36.311 +			block = &bl;
  36.312 +			break;
  36.313 +		}
  36.314 +	}
  36.315 +
  36.316 +	if (!block) {
  36.317 +		ThrowException("There is not a single `Scene` record to load");
  36.318 +	}
  36.319 +
  36.320 +	file.reader->SetCurrentPos(block->start);
  36.321 +	ss.Convert(out,file);
  36.322 +
  36.323 +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
  36.324 +	DefaultLogger::get()->info((format(),
  36.325 +		"(Stats) Fields read: "	,file.stats().fields_read,
  36.326 +		", pointers resolved: "	,file.stats().pointers_resolved,  
  36.327 +		", cache hits: "        ,file.stats().cache_hits,  
  36.328 +		", cached objects: "	,file.stats().cached_objects
  36.329 +	));
  36.330 +#endif
  36.331 +}
  36.332 +
  36.333 +// ------------------------------------------------------------------------------------------------
  36.334 +void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in,const FileDatabase& file) 
  36.335 +{
  36.336 +	ConversionData conv(file);
  36.337 +
  36.338 +	// FIXME it must be possible to take the hierarchy directly from
  36.339 +	// the file. This is terrible. Here, we're first looking for
  36.340 +	// all objects which don't have parent objects at all -
  36.341 +	std::deque<const Object*> no_parents;
  36.342 +	for (boost::shared_ptr<Base> cur = boost::static_pointer_cast<Base> ( in.base.first ); cur; cur = cur->next) {
  36.343 +		if (cur->object) {
  36.344 +			if(!cur->object->parent) {
  36.345 +				no_parents.push_back(cur->object.get());
  36.346 +			}
  36.347 +			else conv.objects.insert(cur->object.get());
  36.348 +		}
  36.349 +	}
  36.350 +	for (boost::shared_ptr<Base> cur = in.basact; cur; cur = cur->next) {
  36.351 +		if (cur->object) {
  36.352 +			if(cur->object->parent) {
  36.353 +				conv.objects.insert(cur->object.get());
  36.354 +			}
  36.355 +		}
  36.356 +	}
  36.357 +
  36.358 +	if (no_parents.empty()) {
  36.359 +		ThrowException("Expected at least one object with no parent");
  36.360 +	}
  36.361 +
  36.362 +	aiNode* root = out->mRootNode = new aiNode("<BlenderRoot>");
  36.363 +
  36.364 +	root->mNumChildren = static_cast<unsigned int>(no_parents.size());
  36.365 +	root->mChildren = new aiNode*[root->mNumChildren]();
  36.366 +	for (unsigned int i = 0; i < root->mNumChildren; ++i) {
  36.367 +		root->mChildren[i] = ConvertNode(in, no_parents[i], conv, aiMatrix4x4());	
  36.368 +		root->mChildren[i]->mParent = root;
  36.369 +	}
  36.370 +
  36.371 +	BuildMaterials(conv);
  36.372 +
  36.373 +	if (conv.meshes->size()) {
  36.374 +		out->mMeshes = new aiMesh*[out->mNumMeshes = static_cast<unsigned int>( conv.meshes->size() )];
  36.375 +		std::copy(conv.meshes->begin(),conv.meshes->end(),out->mMeshes);
  36.376 +		conv.meshes.dismiss();
  36.377 +	}
  36.378 +
  36.379 +	if (conv.lights->size()) {
  36.380 +		out->mLights = new aiLight*[out->mNumLights = static_cast<unsigned int>( conv.lights->size() )];
  36.381 +		std::copy(conv.lights->begin(),conv.lights->end(),out->mLights);
  36.382 +		conv.lights.dismiss();
  36.383 +	}
  36.384 +
  36.385 +	if (conv.cameras->size()) {
  36.386 +		out->mCameras = new aiCamera*[out->mNumCameras = static_cast<unsigned int>( conv.cameras->size() )];
  36.387 +		std::copy(conv.cameras->begin(),conv.cameras->end(),out->mCameras);
  36.388 +		conv.cameras.dismiss();
  36.389 +	}
  36.390 +
  36.391 +	if (conv.materials->size()) {
  36.392 +		out->mMaterials = new aiMaterial*[out->mNumMaterials = static_cast<unsigned int>( conv.materials->size() )];
  36.393 +		std::copy(conv.materials->begin(),conv.materials->end(),out->mMaterials);
  36.394 +		conv.materials.dismiss();
  36.395 +	}
  36.396 +
  36.397 +	if (conv.textures->size()) {
  36.398 +		out->mTextures = new aiTexture*[out->mNumTextures = static_cast<unsigned int>( conv.textures->size() )];
  36.399 +		std::copy(conv.textures->begin(),conv.textures->end(),out->mTextures);
  36.400 +		conv.textures.dismiss();
  36.401 +	}
  36.402 +
  36.403 +	// acknowledge that the scene might come out incomplete
  36.404 +	// by Assimps definition of `complete`: blender scenes
  36.405 +	// can consist of thousands of cameras or lights with
  36.406 +	// not a single mesh between them.
  36.407 +	if (!out->mNumMeshes) {
  36.408 +		out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
  36.409 +	}
  36.410 +}
  36.411 +
  36.412 +// ------------------------------------------------------------------------------------------------
  36.413 +void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const MTex* tex, const Image* img, ConversionData& conv_data)
  36.414 +{
  36.415 +	(void)mat; (void)tex; (void)conv_data;
  36.416 +	aiString name;
  36.417 +
  36.418 +	// check if the file contents are bundled with the BLEND file
  36.419 +	if (img->packedfile) {
  36.420 +		name.data[0] = '*';
  36.421 +		name.length = 1+ ASSIMP_itoa10(name.data+1,MAXLEN-1,conv_data.textures->size());
  36.422 +
  36.423 +		conv_data.textures->push_back(new aiTexture());
  36.424 +		aiTexture* tex = conv_data.textures->back();
  36.425 +
  36.426 +		// usually 'img->name' will be the original file name of the embedded textures,
  36.427 +		// so we can extract the file extension from it.
  36.428 +		const size_t nlen = strlen( img->name );
  36.429 +		const char* s = img->name+nlen, *e = s;
  36.430 +
  36.431 +		while (s >= img->name && *s != '.')--s;
  36.432 +
  36.433 +		tex->achFormatHint[0] = s+1>e ? '\0' : ::tolower( s[1] );
  36.434 +		tex->achFormatHint[1] = s+2>e ? '\0' : ::tolower( s[2] );
  36.435 +		tex->achFormatHint[2] = s+3>e ? '\0' : ::tolower( s[3] );
  36.436 +		tex->achFormatHint[3] = '\0';
  36.437 +
  36.438 +		// tex->mHeight = 0;
  36.439 +		tex->mWidth = img->packedfile->size;
  36.440 +		uint8_t* ch = new uint8_t[tex->mWidth];
  36.441 +
  36.442 +		conv_data.db.reader->SetCurrentPos(static_cast<size_t>( img->packedfile->data->val));
  36.443 +		conv_data.db.reader->CopyAndAdvance(ch,tex->mWidth);
  36.444 +
  36.445 +		tex->pcData = reinterpret_cast<aiTexel*>(ch);
  36.446 +
  36.447 +		LogInfo("Reading embedded texture, original file was "+std::string(img->name));
  36.448 +	}
  36.449 +	else {
  36.450 +		name = aiString( img->name );
  36.451 +	}
  36.452 +	out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
  36.453 +		conv_data.next_texture[aiTextureType_DIFFUSE]++)
  36.454 +	);
  36.455 +}
  36.456 +
  36.457 +// ------------------------------------------------------------------------------------------------
  36.458 +void BlenderImporter::AddSentinelTexture(aiMaterial* out, const Material* mat, const MTex* tex, ConversionData& conv_data)
  36.459 +{
  36.460 +	(void)mat; (void)tex; (void)conv_data;
  36.461 +
  36.462 +	aiString name;
  36.463 +	name.length = sprintf(name.data, "Procedural,num=%i,type=%s",conv_data.sentinel_cnt++,
  36.464 +		GetTextureTypeDisplayString(tex->tex->type)
  36.465 +	);
  36.466 +	out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
  36.467 +		conv_data.next_texture[aiTextureType_DIFFUSE]++)
  36.468 +	);
  36.469 +}
  36.470 +
  36.471 +// ------------------------------------------------------------------------------------------------
  36.472 +void BlenderImporter::ResolveTexture(aiMaterial* out, const Material* mat, const MTex* tex, ConversionData& conv_data)
  36.473 +{
  36.474 +	const Tex* rtex = tex->tex.get();
  36.475 +	if(!rtex || !rtex->type) {
  36.476 +		return;
  36.477 +	}
  36.478 +	
  36.479 +	// We can't support most of the texture types because they're mostly procedural.
  36.480 +	// These are substituted by a dummy texture.
  36.481 +	const char* dispnam = "";
  36.482 +	switch( rtex->type ) 
  36.483 +	{
  36.484 +			// these are listed in blender's UI
  36.485 +		case Tex::Type_CLOUDS		:  
  36.486 +		case Tex::Type_WOOD			:  
  36.487 +		case Tex::Type_MARBLE		:  
  36.488 +		case Tex::Type_MAGIC		: 
  36.489 +		case Tex::Type_BLEND		:  
  36.490 +		case Tex::Type_STUCCI		: 
  36.491 +		case Tex::Type_NOISE		: 
  36.492 +		case Tex::Type_PLUGIN		: 
  36.493 +		case Tex::Type_MUSGRAVE		:  
  36.494 +		case Tex::Type_VORONOI		:  
  36.495 +		case Tex::Type_DISTNOISE	:  
  36.496 +		case Tex::Type_ENVMAP		:  
  36.497 +
  36.498 +			// these do no appear in the UI, why?
  36.499 +		case Tex::Type_POINTDENSITY	:  
  36.500 +		case Tex::Type_VOXELDATA	: 
  36.501 +
  36.502 +			LogWarn(std::string("Encountered a texture with an unsupported type: ")+dispnam);
  36.503 +			AddSentinelTexture(out, mat, tex, conv_data);
  36.504 +			break;
  36.505 +
  36.506 +		case Tex::Type_IMAGE		:
  36.507 +			if (!rtex->ima) {
  36.508 +				LogError("A texture claims to be an Image, but no image reference is given");
  36.509 +				break;
  36.510 +			}
  36.511 +			ResolveImage(out, mat, tex, rtex->ima.get(),conv_data);
  36.512 +			break;
  36.513 +
  36.514 +		default:
  36.515 +			ai_assert(false);
  36.516 +	};
  36.517 +}
  36.518 +
  36.519 +// ------------------------------------------------------------------------------------------------
  36.520 +void BlenderImporter::BuildMaterials(ConversionData& conv_data) 
  36.521 +{
  36.522 +	conv_data.materials->reserve(conv_data.materials_raw.size());
  36.523 +
  36.524 +	// add a default material if necessary
  36.525 +	unsigned int index = static_cast<unsigned int>( -1 );
  36.526 +	for_each( aiMesh* mesh, conv_data.meshes.get() ) {
  36.527 +		if (mesh->mMaterialIndex == static_cast<unsigned int>( -1 )) {
  36.528 +
  36.529 +			if (index == static_cast<unsigned int>( -1 )) {
  36.530 +
  36.531 +				// ok, we need to add a dedicated default material for some poor material-less meshes
  36.532 +				boost::shared_ptr<Material> p(new Material());
  36.533 +				strcpy( p->id.name+2, AI_DEFAULT_MATERIAL_NAME );
  36.534 +
  36.535 +				p->r = p->g = p->b = 0.6f;
  36.536 +				p->specr = p->specg = p->specb = 0.6f;
  36.537 +				p->ambr = p->ambg = p->ambb = 0.0f;
  36.538 +				p->mirr = p->mirg = p->mirb = 0.0f;
  36.539 +				p->emit = 0.f;
  36.540 +				p->alpha = 0.f;
  36.541 +
  36.542 +				// XXX add more / or add default c'tor to Material
  36.543 +
  36.544 +				index = static_cast<unsigned int>( conv_data.materials_raw.size() );
  36.545 +				conv_data.materials_raw.push_back(p);
  36.546 +
  36.547 +				LogInfo("Adding default material ...");
  36.548 +			}
  36.549 +			mesh->mMaterialIndex = index;
  36.550 +		}
  36.551 +	}
  36.552 +
  36.553 +	for_each(boost::shared_ptr<Material> mat, conv_data.materials_raw) {
  36.554 +
  36.555 +		// reset per material global counters
  36.556 +		for (size_t i = 0; i < sizeof(conv_data.next_texture)/sizeof(conv_data.next_texture[0]);++i) {
  36.557 +			conv_data.next_texture[i] = 0 ;
  36.558 +		}
  36.559 +	
  36.560 +		aiMaterial* mout = new aiMaterial();
  36.561 +		conv_data.materials->push_back(mout);
  36.562 +
  36.563 +		// set material name
  36.564 +		aiString name = aiString(mat->id.name+2); // skip over the name prefix 'MA'
  36.565 +		mout->AddProperty(&name,AI_MATKEY_NAME);
  36.566 +
  36.567 +
  36.568 +		// basic material colors
  36.569 +		aiColor3D col(mat->r,mat->g,mat->b);
  36.570 +		if (mat->r || mat->g || mat->b ) {
  36.571 +			
  36.572 +			// Usually, zero diffuse color means no diffuse color at all in the equation.
  36.573 +			// So we omit this member to express this intent.
  36.574 +			mout->AddProperty(&col,1,AI_MATKEY_COLOR_DIFFUSE);
  36.575 +
  36.576 +			if (mat->emit) {
  36.577 +				aiColor3D emit_col(mat->emit * mat->r, mat->emit * mat->g, mat->emit * mat->b) ;
  36.578 +				mout->AddProperty(&emit_col, 1, AI_MATKEY_COLOR_EMISSIVE) ;
  36.579 +			}
  36.580 +		}
  36.581 +
  36.582 +		col = aiColor3D(mat->specr,mat->specg,mat->specb);
  36.583 +		mout->AddProperty(&col,1,AI_MATKEY_COLOR_SPECULAR);
  36.584 +
  36.585 +		// is hardness/shininess set?
  36.586 +		if( mat->har ) {
  36.587 +			const float har = mat->har;
  36.588 +			mout->AddProperty(&har,1,AI_MATKEY_SHININESS);
  36.589 +		}
  36.590 +
  36.591 +		col = aiColor3D(mat->ambr,mat->ambg,mat->ambb);
  36.592 +		mout->AddProperty(&col,1,AI_MATKEY_COLOR_AMBIENT);
  36.593 +
  36.594 +		col = aiColor3D(mat->mirr,mat->mirg,mat->mirb);
  36.595 +		mout->AddProperty(&col,1,AI_MATKEY_COLOR_REFLECTIVE);
  36.596 +
  36.597 +		for(size_t i = 0; i < sizeof(mat->mtex) / sizeof(mat->mtex[0]); ++i) {
  36.598 +			if (!mat->mtex[i]) {
  36.599 +				continue;
  36.600 +			}
  36.601 +
  36.602 +			ResolveTexture(mout,mat.get(),mat->mtex[i].get(),conv_data);
  36.603 +		}
  36.604 +	}
  36.605 +}
  36.606 +
  36.607 +// ------------------------------------------------------------------------------------------------
  36.608 +void BlenderImporter::CheckActualType(const ElemBase* dt, const char* check)
  36.609 +{
  36.610 +	ai_assert(dt);
  36.611 +	if (strcmp(dt->dna_type,check)) {
  36.612 +		ThrowException((format(),
  36.613 +			"Expected object at ",std::hex,dt," to be of type `",check, 
  36.614 +			"`, but it claims to be a `",dt->dna_type,"`instead"
  36.615 +		));
  36.616 +	}
  36.617 +}
  36.618 +
  36.619 +// ------------------------------------------------------------------------------------------------
  36.620 +void BlenderImporter::NotSupportedObjectType(const Object* obj, const char* type)
  36.621 +{
  36.622 +	LogWarn((format(), "Object `",obj->id.name,"` - type is unsupported: `",type, "`, skipping" ));
  36.623 +}
  36.624 +
  36.625 +// ------------------------------------------------------------------------------------------------
  36.626 +void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, const Mesh* mesh,
  36.627 +	ConversionData& conv_data, TempArray<std::vector,aiMesh>&  temp
  36.628 +	) 
  36.629 +{
  36.630 +	typedef std::pair<const int,size_t> MyPair;
  36.631 +	if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) {
  36.632 +		return;
  36.633 +	}
  36.634 +
  36.635 +	// some sanity checks
  36.636 +	if (static_cast<size_t> ( mesh->totface ) > mesh->mface.size() ){
  36.637 +		ThrowException("Number of faces is larger than the corresponding array");
  36.638 +	}
  36.639 +
  36.640 +	if (static_cast<size_t> ( mesh->totvert ) > mesh->mvert.size()) {
  36.641 +		ThrowException("Number of vertices is larger than the corresponding array");
  36.642 +	}
  36.643 +
  36.644 +	if (static_cast<size_t> ( mesh->totloop ) > mesh->mloop.size()) {
  36.645 +		ThrowException("Number of vertices is larger than the corresponding array");
  36.646 +	}
  36.647 +
  36.648 +	// collect per-submesh numbers
  36.649 +	std::map<int,size_t> per_mat;
  36.650 +	std::map<int,size_t> per_mat_verts;
  36.651 +	for (int i = 0; i < mesh->totface; ++i) {
  36.652 +
  36.653 +		const MFace& mf = mesh->mface[i];
  36.654 +		per_mat[ mf.mat_nr ]++;
  36.655 +		per_mat_verts[ mf.mat_nr ] += mf.v4?4:3;
  36.656 +	}
  36.657 +
  36.658 +	for (int i = 0; i < mesh->totpoly; ++i) {
  36.659 +		const MPoly& mp = mesh->mpoly[i];
  36.660 +		per_mat[ mp.mat_nr ]++;
  36.661 +		per_mat_verts[ mp.mat_nr ] += mp.totloop;
  36.662 +	}
  36.663 +
  36.664 +	// ... and allocate the corresponding meshes
  36.665 +	const size_t old = temp->size();
  36.666 +	temp->reserve(temp->size() + per_mat.size());
  36.667 +
  36.668 +	std::map<size_t,size_t> mat_num_to_mesh_idx;
  36.669 +	for_each(MyPair& it, per_mat) {
  36.670 +
  36.671 +		mat_num_to_mesh_idx[it.first] = temp->size();
  36.672 +		temp->push_back(new aiMesh());
  36.673 +
  36.674 +		aiMesh* out = temp->back();
  36.675 +		out->mVertices = new aiVector3D[per_mat_verts[it.first]];
  36.676 +		out->mNormals  = new aiVector3D[per_mat_verts[it.first]];
  36.677 +
  36.678 +		//out->mNumFaces = 0
  36.679 +		//out->mNumVertices = 0
  36.680 +		out->mFaces = new aiFace[it.second]();
  36.681 +
  36.682 +		// all submeshes created from this mesh are named equally. this allows
  36.683 +		// curious users to recover the original adjacency.
  36.684 +		out->mName = aiString(mesh->id.name+2);  
  36.685 +			// skip over the name prefix 'ME'
  36.686 +
  36.687 +		// resolve the material reference and add this material to the set of
  36.688 +		// output materials. The (temporary) material index is the index 
  36.689 +		// of the material entry within the list of resolved materials.
  36.690 +		if (mesh->mat) {
  36.691 +
  36.692 +			if (static_cast<size_t> ( it.first ) >= mesh->mat.size() ) {
  36.693 +				ThrowException("Material index is out of range");
  36.694 +			}
  36.695 +
  36.696 +			boost::shared_ptr<Material> mat = mesh->mat[it.first];
  36.697 +			const std::deque< boost::shared_ptr<Material> >::iterator has = std::find(
  36.698 +					conv_data.materials_raw.begin(),
  36.699 +					conv_data.materials_raw.end(),mat
  36.700 +			);
  36.701 +
  36.702 +			if (has != conv_data.materials_raw.end()) {
  36.703 +				out->mMaterialIndex = static_cast<unsigned int>( std::distance(conv_data.materials_raw.begin(),has));
  36.704 +			}
  36.705 +			else {
  36.706 +				out->mMaterialIndex = static_cast<unsigned int>( conv_data.materials_raw.size() );
  36.707 +				conv_data.materials_raw.push_back(mat);
  36.708 +			}
  36.709 +		}
  36.710 +		else out->mMaterialIndex = static_cast<unsigned int>( -1 );
  36.711 +	}
  36.712 +
  36.713 +	for (int i = 0; i < mesh->totface; ++i) {
  36.714 +
  36.715 +		const MFace& mf = mesh->mface[i];
  36.716 +
  36.717 +		aiMesh* const out = temp[ mat_num_to_mesh_idx[ mf.mat_nr ] ];
  36.718 +		aiFace& f = out->mFaces[out->mNumFaces++];
  36.719 +
  36.720 +		f.mIndices = new unsigned int[ f.mNumIndices = mf.v4?4:3 ];
  36.721 +		aiVector3D* vo = out->mVertices + out->mNumVertices;
  36.722 +		aiVector3D* vn = out->mNormals + out->mNumVertices;
  36.723 +
  36.724 +		// XXX we can't fold this easily, because we are restricted
  36.725 +		// to the member names from the BLEND file (v1,v2,v3,v4) 
  36.726 +		// which are assigned by the genblenddna.py script and
  36.727 +		// cannot be changed without breaking the entire
  36.728 +		// import process.
  36.729 +
  36.730 +		if (mf.v1 >= mesh->totvert) {
  36.731 +			ThrowException("Vertex index v1 out of range");
  36.732 +		}
  36.733 +		const MVert* v = &mesh->mvert[mf.v1];
  36.734 +		vo->x = v->co[0];
  36.735 +		vo->y = v->co[1];
  36.736 +		vo->z = v->co[2];
  36.737 +		vn->x = v->no[0];
  36.738 +		vn->y = v->no[1];
  36.739 +		vn->z = v->no[2];
  36.740 +		f.mIndices[0] = out->mNumVertices++;
  36.741 +		++vo;
  36.742 +		++vn;
  36.743 +
  36.744 +		//	if (f.mNumIndices >= 2) {
  36.745 +		if (mf.v2 >= mesh->totvert) {
  36.746 +			ThrowException("Vertex index v2 out of range");
  36.747 +		}
  36.748 +		v = &mesh->mvert[mf.v2];
  36.749 +		vo->x = v->co[0];
  36.750 +		vo->y = v->co[1];
  36.751 +		vo->z = v->co[2];
  36.752 +		vn->x = v->no[0];
  36.753 +		vn->y = v->no[1];
  36.754 +		vn->z = v->no[2];
  36.755 +		f.mIndices[1] = out->mNumVertices++;
  36.756 +		++vo;
  36.757 +		++vn;
  36.758 +
  36.759 +		if (mf.v3 >= mesh->totvert) {
  36.760 +			ThrowException("Vertex index v3 out of range");
  36.761 +		}
  36.762 +		//	if (f.mNumIndices >= 3) {
  36.763 +		v = &mesh->mvert[mf.v3];
  36.764 +		vo->x = v->co[0];
  36.765 +		vo->y = v->co[1];
  36.766 +		vo->z = v->co[2];
  36.767 +		vn->x = v->no[0];
  36.768 +		vn->y = v->no[1];
  36.769 +		vn->z = v->no[2];
  36.770 +		f.mIndices[2] = out->mNumVertices++;
  36.771 +		++vo;
  36.772 +		++vn;
  36.773 +
  36.774 +		if (mf.v4 >= mesh->totvert) {
  36.775 +			ThrowException("Vertex index v4 out of range");
  36.776 +		}
  36.777 +		//	if (f.mNumIndices >= 4) {
  36.778 +		if (mf.v4) {
  36.779 +			v = &mesh->mvert[mf.v4];
  36.780 +			vo->x = v->co[0];
  36.781 +			vo->y = v->co[1];
  36.782 +			vo->z = v->co[2];
  36.783 +			vn->x = v->no[0];
  36.784 +			vn->y = v->no[1];
  36.785 +			vn->z = v->no[2];
  36.786 +			f.mIndices[3] = out->mNumVertices++;
  36.787 +			++vo;
  36.788 +			++vn;
  36.789 +
  36.790 +			out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
  36.791 +		}
  36.792 +		else out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  36.793 +
  36.794 +		//	}
  36.795 +		//	}
  36.796 +		//	}
  36.797 +	}
  36.798 +
  36.799 +	for (int i = 0; i < mesh->totpoly; ++i) {
  36.800 +		
  36.801 +		const MPoly& mf = mesh->mpoly[i];
  36.802 +		
  36.803 +		aiMesh* const out = temp[ mat_num_to_mesh_idx[ mf.mat_nr ] ];
  36.804 +		aiFace& f = out->mFaces[out->mNumFaces++];
  36.805 +		
  36.806 +		f.mIndices = new unsigned int[ f.mNumIndices = mf.totloop ];
  36.807 +		aiVector3D* vo = out->mVertices + out->mNumVertices;
  36.808 +		aiVector3D* vn = out->mNormals + out->mNumVertices;
  36.809 +		
  36.810 +		// XXX we can't fold this easily, because we are restricted
  36.811 +		// to the member names from the BLEND file (v1,v2,v3,v4)
  36.812 +		// which are assigned by the genblenddna.py script and
  36.813 +		// cannot be changed without breaking the entire
  36.814 +		// import process.
  36.815 +		for (int j = 0;j < mf.totloop; ++j)
  36.816 +		{
  36.817 +			const MLoop& loop = mesh->mloop[mf.loopstart + j];
  36.818 +
  36.819 +			if (loop.v >= mesh->totvert) {
  36.820 +				ThrowException("Vertex index out of range");
  36.821 +			}
  36.822 +
  36.823 +			const MVert& v = mesh->mvert[loop.v];
  36.824 +			
  36.825 +			vo->x = v.co[0];
  36.826 +			vo->y = v.co[1];
  36.827 +			vo->z = v.co[2];
  36.828 +			vn->x = v.no[0];
  36.829 +			vn->y = v.no[1];
  36.830 +			vn->z = v.no[2];
  36.831 +			f.mIndices[j] = out->mNumVertices++;
  36.832 +			
  36.833 +			++vo;
  36.834 +			++vn;
  36.835 +			
  36.836 +		}
  36.837 +		if (mf.totloop == 3)
  36.838 +		{
  36.839 +			out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  36.840 +		}
  36.841 +		else
  36.842 +		{
  36.843 +			out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
  36.844 +		}
  36.845 +	}
  36.846 +	
  36.847 +	// collect texture coordinates, they're stored in a separate per-face buffer
  36.848 +	if (mesh->mtface || mesh->mloopuv) {
  36.849 +		if (mesh->totface > static_cast<int> ( mesh->mtface.size())) {
  36.850 +			ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)");
  36.851 +		}
  36.852 +		for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
  36.853 +			ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
  36.854 +
  36.855 +			(*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
  36.856 +			(*it)->mNumFaces = (*it)->mNumVertices = 0;
  36.857 +		}
  36.858 +
  36.859 +		for (int i = 0; i < mesh->totface; ++i) {
  36.860 +			const MTFace* v = &mesh->mtface[i];
  36.861 +
  36.862 +			aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
  36.863 +			const aiFace& f = out->mFaces[out->mNumFaces++];
  36.864 +			
  36.865 +			aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
  36.866 +			for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
  36.867 +				vo->x = v->uv[i][0];
  36.868 +				vo->y = v->uv[i][1];
  36.869 +			}
  36.870 +		}
  36.871 +		
  36.872 +		for (int i = 0; i < mesh->totpoly; ++i) {
  36.873 +			const MPoly& v = mesh->mpoly[i];
  36.874 +			aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
  36.875 +			const aiFace& f = out->mFaces[out->mNumFaces++];
  36.876 +			
  36.877 +			aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
  36.878 +			for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
  36.879 +				const MLoopUV& uv = mesh->mloopuv[v.loopstart + j];
  36.880 +				vo->x = uv.uv[0];
  36.881 +				vo->y = uv.uv[1];
  36.882 +			}
  36.883 +			
  36.884 +		}
  36.885 +	}
  36.886 +
  36.887 +	// collect texture coordinates, old-style (marked as deprecated in current blender sources)
  36.888 +	if (mesh->tface) {
  36.889 +		if (mesh->totface > static_cast<int> ( mesh->tface.size())) {
  36.890 +			ThrowException("Number of faces is larger than the corresponding UV face array (#2)");
  36.891 +		}
  36.892 +		for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
  36.893 +			ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
  36.894 +
  36.895 +			(*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
  36.896 +			(*it)->mNumFaces = (*it)->mNumVertices = 0;
  36.897 +		}
  36.898 +
  36.899 +		for (int i = 0; i < mesh->totface; ++i) {
  36.900 +			const TFace* v = &mesh->tface[i];
  36.901 +
  36.902 +			aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
  36.903 +			const aiFace& f = out->mFaces[out->mNumFaces++];
  36.904 +			
  36.905 +			aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
  36.906 +			for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
  36.907 +				vo->x = v->uv[i][0];
  36.908 +				vo->y = v->uv[i][1];
  36.909 +			}
  36.910 +		}
  36.911 +	}
  36.912 +
  36.913 +	// collect vertex colors, stored separately as well
  36.914 +	if (mesh->mcol || mesh->mloopcol) {
  36.915 +		if (mesh->totface > static_cast<int> ( (mesh->mcol.size()/4)) ) {
  36.916 +			ThrowException("Number of faces is larger than the corresponding color face array");
  36.917 +		}
  36.918 +		for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
  36.919 +			ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
  36.920 +
  36.921 +			(*it)->mColors[0] = new aiColor4D[(*it)->mNumVertices];
  36.922 +			(*it)->mNumFaces = (*it)->mNumVertices = 0;
  36.923 +		}
  36.924 +
  36.925 +		for (int i = 0; i < mesh->totface; ++i) {
  36.926 +
  36.927 +			aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
  36.928 +			const aiFace& f = out->mFaces[out->mNumFaces++];
  36.929 +			
  36.930 +			aiColor4D* vo = &out->mColors[0][out->mNumVertices];
  36.931 +			for (unsigned int n = 0; n < f.mNumIndices; ++n, ++vo,++out->mNumVertices) {
  36.932 +				const MCol* col = &mesh->mcol[(i<<2)+n];
  36.933 +
  36.934 +				vo->r = col->r;
  36.935 +				vo->g = col->g;
  36.936 +				vo->b = col->b;
  36.937 +				vo->a = col->a;
  36.938 +			}
  36.939 +			for (unsigned int n = f.mNumIndices; n < 4; ++n);
  36.940 +		}
  36.941 +		
  36.942 +		for (int i = 0; i < mesh->totpoly; ++i) {
  36.943 +			const MPoly& v = mesh->mpoly[i];
  36.944 +			aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
  36.945 +			const aiFace& f = out->mFaces[out->mNumFaces++];
  36.946 +			
  36.947 +			aiColor4D* vo = &out->mColors[0][out->mNumVertices];
  36.948 +			for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
  36.949 +				const MLoopCol& col = mesh->mloopcol[v.loopstart + j];
  36.950 +				vo->r = col.r;
  36.951 +				vo->g = col.g;
  36.952 +				vo->b = col.b;
  36.953 +				vo->a = col.a;
  36.954 +			}
  36.955 +			
  36.956 +		}
  36.957 +
  36.958 +	}
  36.959 +
  36.960 +	return;
  36.961 +}
  36.962 +
  36.963 +// ------------------------------------------------------------------------------------------------
  36.964 +aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* /*obj*/, const Camera* /*mesh*/, ConversionData& /*conv_data*/)
  36.965 +{
  36.966 +	ScopeGuard<aiCamera> out(new aiCamera());
  36.967 +
  36.968 +	return NULL ; //out.dismiss();
  36.969 +}
  36.970 +
  36.971 +// ------------------------------------------------------------------------------------------------
  36.972 +aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* /*obj*/, const Lamp* /*mesh*/, ConversionData& /*conv_data*/)
  36.973 +{
  36.974 +	ScopeGuard<aiLight> out(new aiLight());
  36.975 +
  36.976 +	return NULL ; //out.dismiss();
  36.977 +}
  36.978 +
  36.979 +// ------------------------------------------------------------------------------------------------
  36.980 +aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data, const aiMatrix4x4& parentTransform)
  36.981 +{
  36.982 +	std::deque<const Object*> children;
  36.983 +	for(std::set<const Object*>::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) {
  36.984 +		const Object* object = *it;
  36.985 +		if (object->parent == obj) {
  36.986 +			children.push_back(object);
  36.987 +
  36.988 +			conv_data.objects.erase(it++);
  36.989 +			continue;
  36.990 +		}
  36.991 +		++it;
  36.992 +	}
  36.993 +
  36.994 +	ScopeGuard<aiNode> node(new aiNode(obj->id.name+2)); // skip over the name prefix 'OB'
  36.995 +	if (obj->data) {
  36.996 +		switch (obj->type)
  36.997 +		{
  36.998 +		case Object :: Type_EMPTY:
  36.999 +			break; // do nothing
 36.1000 +
 36.1001 +
 36.1002 +			// supported object types
 36.1003 +		case Object :: Type_MESH: {
 36.1004 +			const size_t old = conv_data.meshes->size();
 36.1005 +
 36.1006 +			CheckActualType(obj->data.get(),"Mesh");
 36.1007 +			ConvertMesh(in,obj,static_cast<const Mesh*>(obj->data.get()),conv_data,conv_data.meshes);
 36.1008 +
 36.1009 +			if (conv_data.meshes->size() > old) {
 36.1010 +				node->mMeshes = new unsigned int[node->mNumMeshes = static_cast<unsigned int>(conv_data.meshes->size()-old)];
 36.1011 +				for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
 36.1012 +					node->mMeshes[i] = i + old;
 36.1013 +				}
 36.1014 +			}}
 36.1015 +			break;
 36.1016 +		case Object :: Type_LAMP: {
 36.1017 +			CheckActualType(obj->data.get(),"Lamp");
 36.1018 +			aiLight* mesh = ConvertLight(in,obj,static_cast<const Lamp*>(
 36.1019 +				obj->data.get()),conv_data);
 36.1020 +
 36.1021 +			if (mesh) {
 36.1022 +				conv_data.lights->push_back(mesh);
 36.1023 +			}}
 36.1024 +			break;
 36.1025 +		case Object :: Type_CAMERA: {
 36.1026 +			CheckActualType(obj->data.get(),"Camera");
 36.1027 +			aiCamera* mesh = ConvertCamera(in,obj,static_cast<const Camera*>(
 36.1028 +				obj->data.get()),conv_data);
 36.1029 +
 36.1030 +			if (mesh) {
 36.1031 +				conv_data.cameras->push_back(mesh);
 36.1032 +			}}
 36.1033 +			break;
 36.1034 +
 36.1035 +
 36.1036 +			// unsupported object types / log, but do not break
 36.1037 +		case Object :: Type_CURVE:
 36.1038 +			NotSupportedObjectType(obj,"Curve");
 36.1039 +			break;
 36.1040 +		case Object :: Type_SURF:
 36.1041 +			NotSupportedObjectType(obj,"Surface");
 36.1042 +			break;
 36.1043 +		case Object :: Type_FONT:
 36.1044 +			NotSupportedObjectType(obj,"Font");
 36.1045 +			break;
 36.1046 +		case Object :: Type_MBALL:
 36.1047 +			NotSupportedObjectType(obj,"MetaBall");
 36.1048 +			break;
 36.1049 +		case Object :: Type_WAVE:
 36.1050 +			NotSupportedObjectType(obj,"Wave");
 36.1051 +			break;
 36.1052 +		case Object :: Type_LATTICE:
 36.1053 +			NotSupportedObjectType(obj,"Lattice");
 36.1054 +			break;
 36.1055 +
 36.1056 +			// invalid or unknown type
 36.1057 +		default:
 36.1058 +			break;
 36.1059 +		}
 36.1060 +	}
 36.1061 +
 36.1062 +	for(unsigned int x = 0; x < 4; ++x) {
 36.1063 +		for(unsigned int y = 0; y < 4; ++y) {
 36.1064 +			node->mTransformation[y][x] = obj->obmat[x][y];
 36.1065 +		}
 36.1066 +	}
 36.1067 +
 36.1068 +	aiMatrix4x4 m = parentTransform;
 36.1069 +	m = m.Inverse();
 36.1070 +
 36.1071 +	node->mTransformation = m*node->mTransformation;
 36.1072 +	
 36.1073 +	if (children.size()) {
 36.1074 +		node->mNumChildren = static_cast<unsigned int>(children.size());
 36.1075 +		aiNode** nd = node->mChildren = new aiNode*[node->mNumChildren]();
 36.1076 +		for_each (const Object* nobj,children) {
 36.1077 +			*nd = ConvertNode(in,nobj,conv_data,node->mTransformation * parentTransform);
 36.1078 +			(*nd++)->mParent = node;
 36.1079 +		}
 36.1080 +	}
 36.1081 +
 36.1082 +	// apply modifiers
 36.1083 +	modifier_cache->ApplyModifiers(*node,conv_data,in,*obj);
 36.1084 +
 36.1085 +	return node.dismiss();
 36.1086 +}
 36.1087 +
 36.1088 +
 36.1089 +#endif
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/libs/assimp/BlenderLoader.h	Sat Feb 01 19:58:19 2014 +0200
    37.3 @@ -0,0 +1,223 @@
    37.4 +/*
    37.5 +Open Asset Import Library (assimp)
    37.6 +----------------------------------------------------------------------
    37.7 +
    37.8 +Copyright (c) 2006-2012, assimp team
    37.9 +All rights reserved.
   37.10 +
   37.11 +Redistribution and use of this software in source and binary forms, 
   37.12 +with or without modification, are permitted provided that the 
   37.13 +following conditions are met:
   37.14 +
   37.15 +* Redistributions of source code must retain the above
   37.16 +  copyright notice, this list of conditions and the
   37.17 +  following disclaimer.
   37.18 +
   37.19 +* Redistributions in binary form must reproduce the above
   37.20 +  copyright notice, this list of conditions and the
   37.21 +  following disclaimer in the documentation and/or other
   37.22 +  materials provided with the distribution.
   37.23 +
   37.24 +* Neither the name of the assimp team, nor the names of its
   37.25 +  contributors may be used to endorse or promote products
   37.26 +  derived from this software without specific prior
   37.27 +  written permission of the assimp team.
   37.28 +
   37.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   37.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   37.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   37.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   37.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   37.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   37.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   37.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   37.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   37.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   37.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   37.40 +
   37.41 +----------------------------------------------------------------------
   37.42 +*/
   37.43 +
   37.44 +/** @file  BlenderLoader.h
   37.45 + *  @brief Declaration of the Blender 3D (*.blend) importer class.
   37.46 + */
   37.47 +#ifndef INCLUDED_AI_BLEND_LOADER_H
   37.48 +#define INCLUDED_AI_BLEND_LOADER_H
   37.49 +
   37.50 +#include "BaseImporter.h"
   37.51 +#include "LogAux.h"
   37.52 +
   37.53 +namespace Assimp	{
   37.54 +	
   37.55 +	// TinyFormatter.h
   37.56 +	namespace Formatter {
   37.57 +		template <typename T,typename TR, typename A> class basic_formatter;
   37.58 +		typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
   37.59 +	}
   37.60 +
   37.61 +	// BlenderDNA.h
   37.62 +	namespace Blender {
   37.63 +		class  FileDatabase;
   37.64 +		struct ElemBase;
   37.65 +	}
   37.66 +
   37.67 +	// BlenderScene.h
   37.68 +	namespace Blender {
   37.69 +		struct Scene;
   37.70 +		struct Object;
   37.71 +		struct Mesh;
   37.72 +		struct Camera;
   37.73 +		struct Lamp;
   37.74 +		struct MTex;
   37.75 +		struct Image;
   37.76 +		struct Material;
   37.77 +	}
   37.78 +
   37.79 +	// BlenderIntermediate.h
   37.80 +	namespace Blender {
   37.81 +		struct ConversionData;
   37.82 +		template <template <typename,typename> class TCLASS, typename T> struct TempArray;
   37.83 +	}
   37.84 +
   37.85 +	// BlenderModifier.h
   37.86 +	namespace Blender {
   37.87 +		class BlenderModifierShowcase;
   37.88 +		class BlenderModifier;
   37.89 +	}
   37.90 +
   37.91 +
   37.92 +
   37.93 +// -------------------------------------------------------------------------------------------
   37.94 +/** Load blenders official binary format. The actual file structure (the `DNA` how they
   37.95 + *  call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
   37.96 + *  conversion from intermediate format to aiScene. */
   37.97 +// -------------------------------------------------------------------------------------------
   37.98 +class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
   37.99 +{
  37.100 +public:
  37.101 +	BlenderImporter();
  37.102 +	~BlenderImporter();
  37.103 +
  37.104 +
  37.105 +public:
  37.106 +
  37.107 +	// --------------------
  37.108 +	bool CanRead( const std::string& pFile, 
  37.109 +		IOSystem* pIOHandler,
  37.110 +		bool checkSig
  37.111 +	) const;
  37.112 +
  37.113 +protected:
  37.114 +
  37.115 +	// --------------------
  37.116 +	const aiImporterDesc* GetInfo () const;
  37.117 +
  37.118 +	// --------------------
  37.119 +	void GetExtensionList(std::set<std::string>& app);
  37.120 +
  37.121 +	// --------------------
  37.122 +	void SetupProperties(const Importer* pImp);
  37.123 +
  37.124 +	// --------------------
  37.125 +	void InternReadFile( const std::string& pFile, 
  37.126 +		aiScene* pScene, 
  37.127 +		IOSystem* pIOHandler
  37.128 +	);
  37.129 +
  37.130 +	// --------------------
  37.131 +	void ParseBlendFile(Blender::FileDatabase& out, 
  37.132 +		boost::shared_ptr<IOStream> stream
  37.133 +	);
  37.134 +
  37.135 +	// --------------------
  37.136 +	void ExtractScene(Blender::Scene& out, 
  37.137 +		const Blender::FileDatabase& file
  37.138 +	); 
  37.139 +
  37.140 +	// --------------------
  37.141 +	void ConvertBlendFile(aiScene* out,
  37.142 +		const Blender::Scene& in,
  37.143 +		const Blender::FileDatabase& file
  37.144 +	);
  37.145 +
  37.146 +private:
  37.147 +
  37.148 +	// --------------------
  37.149 +	aiNode* ConvertNode(const Blender::Scene& in, 
  37.150 +		const Blender::Object* obj, 
  37.151 +		Blender::ConversionData& conv_info,
  37.152 +		const aiMatrix4x4& parentTransform
  37.153 +	); 
  37.154 +
  37.155 +	// --------------------
  37.156 +	void ConvertMesh(const Blender::Scene& in, 
  37.157 +		const Blender::Object* obj, 
  37.158 +		const Blender::Mesh* mesh, 
  37.159 +		Blender::ConversionData& conv_data,
  37.160 +		Blender::TempArray<std::vector,aiMesh>& temp
  37.161 +	); 
  37.162 +
  37.163 +	// --------------------
  37.164 +	aiLight* ConvertLight(const Blender::Scene& in, 
  37.165 +		const Blender::Object* obj, 
  37.166 +		const Blender::Lamp* mesh, 
  37.167 +		Blender::ConversionData& conv_data
  37.168 +	); 
  37.169 +
  37.170 +	// --------------------
  37.171 +	aiCamera* ConvertCamera(const Blender::Scene& in, 
  37.172 +		const Blender::Object* obj, 
  37.173 +		const Blender::Camera* mesh, 
  37.174 +		Blender::ConversionData& conv_data
  37.175 +	); 
  37.176 +
  37.177 +	// --------------------
  37.178 +	void BuildMaterials(
  37.179 +		Blender::ConversionData& conv_data
  37.180 +	) ;
  37.181 +
  37.182 +	// --------------------
  37.183 +	void ResolveTexture(
  37.184 +		aiMaterial* out, 
  37.185 +		const Blender::Material* mat, 
  37.186 +		const Blender::MTex* tex,
  37.187 +		Blender::ConversionData& conv_data
  37.188 +	);
  37.189 +
  37.190 +	// --------------------
  37.191 +	void ResolveImage(
  37.192 +		aiMaterial* out, 
  37.193 +		const Blender::Material* mat, 
  37.194 +		const Blender::MTex* tex, 
  37.195 +		const Blender::Image* img,
  37.196 +		Blender::ConversionData& conv_data
  37.197 +	);
  37.198 +
  37.199 +	void AddSentinelTexture(
  37.200 +		aiMaterial* out, 
  37.201 +		const Blender::Material* mat,
  37.202 +		const Blender::MTex* tex, 
  37.203 +		Blender::ConversionData& conv_data
  37.204 +	);
  37.205 +
  37.206 +private: // static stuff, mostly logging and error reporting.
  37.207 +
  37.208 +	// --------------------
  37.209 +	static void CheckActualType(const Blender::ElemBase* dt, 
  37.210 +		const char* check
  37.211 +	);
  37.212 +
  37.213 +	// --------------------
  37.214 +	static void NotSupportedObjectType(const Blender::Object* obj, 
  37.215 +		const char* type
  37.216 +	);
  37.217 +
  37.218 +
  37.219 +private:
  37.220 +
  37.221 +	Blender::BlenderModifierShowcase* modifier_cache;
  37.222 +
  37.223 +}; // !class BlenderImporter
  37.224 +
  37.225 +} // end of namespace Assimp
  37.226 +#endif // AI_UNREALIMPORTER_H_INC
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/libs/assimp/BlenderModifier.cpp	Sat Feb 01 19:58:19 2014 +0200
    38.3 @@ -0,0 +1,315 @@
    38.4 +/*
    38.5 +Open Asset Import Library (assimp)
    38.6 +----------------------------------------------------------------------
    38.7 +
    38.8 +Copyright (c) 2006-2012, assimp team
    38.9 +All rights reserved.
   38.10 +
   38.11 +Redistribution and use of this software in source and binary forms, 
   38.12 +with or without modification, are permitted provided that the 
   38.13 +following conditions are met:
   38.14 +
   38.15 +* Redistributions of source code must retain the above
   38.16 +  copyright notice, this list of conditions and the
   38.17 +  following disclaimer.
   38.18 +
   38.19 +* Redistributions in binary form must reproduce the above
   38.20 +  copyright notice, this list of conditions and the
   38.21 +  following disclaimer in the documentation and/or other
   38.22 +  materials provided with the distribution.
   38.23 +
   38.24 +* Neither the name of the assimp team, nor the names of its
   38.25 +  contributors may be used to endorse or promote products
   38.26 +  derived from this software without specific prior
   38.27 +  written permission of the assimp team.
   38.28 +
   38.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   38.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   38.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   38.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   38.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   38.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   38.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   38.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   38.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   38.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   38.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   38.40 +
   38.41 +----------------------------------------------------------------------
   38.42 +*/
   38.43 +
   38.44 +/** @file  BlenderModifier.cpp
   38.45 + *  @brief Implementation of some blender modifiers (i.e subdivision, mirror).
   38.46 + */
   38.47 +#include "AssimpPCH.h"
   38.48 +
   38.49 +#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
   38.50 +#include "BlenderModifier.h"
   38.51 +#include "SceneCombiner.h"
   38.52 +#include "Subdivision.h"
   38.53 +
   38.54 +#include <functional>
   38.55 +
   38.56 +using namespace Assimp;
   38.57 +using namespace Assimp::Blender;
   38.58 +
   38.59 +template <typename T> BlenderModifier* god() {
   38.60 +	return new T();
   38.61 +}
   38.62 +
   38.63 +// add all available modifiers here
   38.64 +typedef BlenderModifier* (*fpCreateModifier)();
   38.65 +static const fpCreateModifier creators[] = {
   38.66 +		&god<BlenderModifier_Mirror>,
   38.67 +		&god<BlenderModifier_Subdivision>,
   38.68 +
   38.69 +		NULL // sentinel
   38.70 +};
   38.71 +
   38.72 +// ------------------------------------------------------------------------------------------------
   38.73 +// just testing out some new macros to simplify logging
   38.74 +#define ASSIMP_LOG_WARN_F(string,...)\
   38.75 +	DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
   38.76 +
   38.77 +#define ASSIMP_LOG_ERROR_F(string,...)\
   38.78 +	DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
   38.79 +
   38.80 +#define ASSIMP_LOG_DEBUG_F(string,...)\
   38.81 +	DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
   38.82 +
   38.83 +#define ASSIMP_LOG_INFO_F(string,...)\
   38.84 +	DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
   38.85 +
   38.86 +
   38.87 +#define ASSIMP_LOG_WARN(string)\
   38.88 +	DefaultLogger::get()->warn(string)
   38.89 +
   38.90 +#define ASSIMP_LOG_ERROR(string)\
   38.91 +	DefaultLogger::get()->error(string)
   38.92 +
   38.93 +#define ASSIMP_LOG_DEBUG(string)\
   38.94 +	DefaultLogger::get()->debug(string)
   38.95 +
   38.96 +#define ASSIMP_LOG_INFO(string)\
   38.97 +	DefaultLogger::get()->info(string)
   38.98 +
   38.99 +
  38.100 +// ------------------------------------------------------------------------------------------------
  38.101 +struct SharedModifierData : ElemBase
  38.102 +{
  38.103 +	ModifierData modifier;
  38.104 +};
  38.105 +
  38.106 +// ------------------------------------------------------------------------------------------------
  38.107 +void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object ) 
  38.108 +{
  38.109 +	size_t cnt = 0u, ful = 0u;
  38.110 +
  38.111 +	// NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
  38.112 +	// we're allowed to dereference the pointers without risking to crash. We might still be
  38.113 +	// invoking UB btw - we're assuming that the ModifierData member of the respective modifier
  38.114 +	// structures is at offset sizeof(vftable) with no padding.
  38.115 +	const SharedModifierData* cur = boost::static_pointer_cast<const SharedModifierData> ( orig_object.modifiers.first.get() );
  38.116 +	for (; cur; cur =  boost::static_pointer_cast<const SharedModifierData> ( cur->modifier.next.get() ), ++ful) {
  38.117 +		ai_assert(cur->dna_type);
  38.118 +
  38.119 +		const Structure* s = conv_data.db.dna.Get( cur->dna_type );
  38.120 +		if (!s) {
  38.121 +			ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type);
  38.122 +			continue;
  38.123 +		}
  38.124 +
  38.125 +		// this is a common trait of all XXXMirrorData structures in BlenderDNA
  38.126 +		const Field* f = s->Get("modifier");
  38.127 +		if (!f || f->offset != 0) {
  38.128 +			ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0");
  38.129 +			continue;
  38.130 +		}
  38.131 +
  38.132 +		s = conv_data.db.dna.Get( f->type );
  38.133 +		if (!s || s->name != "ModifierData") {
  38.134 +			ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member");
  38.135 +			continue;
  38.136 +		}
  38.137 +
  38.138 +		// now, we can be sure that we should be fine to dereference *cur* as
  38.139 +		// ModifierData (with the above note).
  38.140 +		const ModifierData& dat = cur->modifier;
  38.141 +
  38.142 +		const fpCreateModifier* curgod = creators;
  38.143 +		std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end();
  38.144 +
  38.145 +		for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly
  38.146 +			if (curmod == endmod) {
  38.147 +				cached_modifiers->push_back((*curgod)());
  38.148 +
  38.149 +				endmod = cached_modifiers->end();
  38.150 +				curmod = endmod-1;
  38.151 +			}
  38.152 +
  38.153 +			BlenderModifier* const modifier = *curmod;
  38.154 +			if(modifier->IsActive(dat)) {
  38.155 +				modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object);
  38.156 +				cnt++;
  38.157 +
  38.158 +				curgod = NULL;
  38.159 +				break;
  38.160 +			}
  38.161 +		}
  38.162 +		if (curgod) {
  38.163 +			ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name);
  38.164 +		}
  38.165 +	}
  38.166 +
  38.167 +	// Even though we managed to resolve some or all of the modifiers on this
  38.168 +	// object, we still can't say whether our modifier implementations were
  38.169 +	// able to fully do their job.
  38.170 +	if (ful) {
  38.171 +		ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name,
  38.172 +			"`, check log messages above for errors");
  38.173 +	}
  38.174 +}
  38.175 +
  38.176 +
  38.177 +
  38.178 +// ------------------------------------------------------------------------------------------------
  38.179 +bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
  38.180 +{
  38.181 +	return modin.type == ModifierData::eModifierType_Mirror;
  38.182 +}
  38.183 +
  38.184 +// ------------------------------------------------------------------------------------------------
  38.185 +void  BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data,  const ElemBase& orig_modifier, 
  38.186 +	const Scene& /*in*/,
  38.187 +	const Object& orig_object ) 
  38.188 +{
  38.189 +	// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
  38.190 +	const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier);
  38.191 +	ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
  38.192 +
  38.193 +	conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes);
  38.194 +
  38.195 +	// XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ...
  38.196 +
  38.197 +	// take all input meshes and clone them
  38.198 +	for (unsigned int i = 0; i < out.mNumMeshes; ++i) {
  38.199 +		aiMesh* mesh;
  38.200 +		SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]);
  38.201 +
  38.202 +		const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f;
  38.203 +		const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
  38.204 +		const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f;
  38.205 +
  38.206 +		if (mir.mirror_ob) {
  38.207 +			const aiVector3D center( mir.mirror_ob->obmat[3][0],mir.mirror_ob->obmat[3][1],mir.mirror_ob->obmat[3][2] );
  38.208 +			for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
  38.209 +				aiVector3D& v = mesh->mVertices[i];
  38.210 +		
  38.211 +				v.x = center.x + xs*(center.x - v.x);
  38.212 +				v.y = center.y + ys*(center.y - v.y);
  38.213 +				v.z = center.z + zs*(center.z - v.z);
  38.214 +			}
  38.215 +		}
  38.216 +		else {
  38.217 +			for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
  38.218 +				aiVector3D& v = mesh->mVertices[i];
  38.219 +				v.x *= xs;v.y *= ys;v.z *= zs;
  38.220 +			}
  38.221 +		}
  38.222 +
  38.223 +		if (mesh->mNormals) {
  38.224 +			for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
  38.225 +				aiVector3D& v = mesh->mNormals[i];
  38.226 +				v.x *= xs;v.y *= ys;v.z *= zs;
  38.227 +			}
  38.228 +		}
  38.229 +
  38.230 +		if (mesh->mTangents) {
  38.231 +			for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
  38.232 +				aiVector3D& v = mesh->mTangents[i];
  38.233 +				v.x *= xs;v.y *= ys;v.z *= zs;
  38.234 +			}
  38.235 +		}
  38.236 +
  38.237 +		if (mesh->mBitangents) {
  38.238 +			for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
  38.239 +				aiVector3D& v = mesh->mBitangents[i];
  38.240 +				v.x *= xs;v.y *= ys;v.z *= zs;
  38.241 +			}
  38.242 +		}
  38.243 +
  38.244 +		const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f;
  38.245 +		const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
  38.246 +
  38.247 +		for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
  38.248 +			for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
  38.249 +				aiVector3D& v = mesh->mTextureCoords[n][i];
  38.250 +				v.x *= us;v.y *= vs;
  38.251 +			}
  38.252 +		}
  38.253 +
  38.254 +		conv_data.meshes->push_back(mesh);
  38.255 +	}
  38.256 +	unsigned int* nind = new unsigned int[out.mNumMeshes*2];
  38.257 +
  38.258 +	std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind);
  38.259 +	std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes,
  38.260 +		std::bind1st(std::plus< unsigned int >(),out.mNumMeshes));
  38.261 +
  38.262 +	delete[] out.mMeshes;
  38.263 +	out.mMeshes = nind;
  38.264 +	out.mNumMeshes *= 2;
  38.265 +
  38.266 +	ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `",
  38.267 +		orig_object.id.name,"`");
  38.268 +}
  38.269 +
  38.270 +
  38.271 +
  38.272 +
  38.273 +// ------------------------------------------------------------------------------------------------
  38.274 +bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
  38.275 +{
  38.276 +	return modin.type == ModifierData::eModifierType_Subsurf;
  38.277 +}
  38.278 +
  38.279 +// ------------------------------------------------------------------------------------------------
  38.280 +void  BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data,  const ElemBase& orig_modifier, 
  38.281 +	const Scene& /*in*/,
  38.282 +	const Object& orig_object ) 
  38.283 +{
  38.284 +	// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
  38.285 +	const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier);
  38.286 +	ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
  38.287 +
  38.288 +	Subdivider::Algorithm algo;
  38.289 +	switch (mir.subdivType) 
  38.290 +	{
  38.291 +	case SubsurfModifierData::TYPE_CatmullClarke:
  38.292 +		algo = Subdivider::CATMULL_CLARKE;
  38.293 +		break;
  38.294 +
  38.295 +	case SubsurfModifierData::TYPE_Simple:
  38.296 +		ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke");
  38.297 +		algo = Subdivider::CATMULL_CLARKE;
  38.298 +		break;
  38.299 +
  38.300 +	default:
  38.301 +		ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType);
  38.302 +		return;
  38.303 +	};
  38.304 +
  38.305 +	boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo));
  38.306 +	ai_assert(subd);
  38.307 +
  38.308 +	aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
  38.309 +	boost::scoped_array<aiMesh*> tempmeshes(new aiMesh*[out.mNumMeshes]());
  38.310 +
  38.311 +	subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
  38.312 +	std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
  38.313 +
  38.314 +	ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
  38.315 +		orig_object.id.name,"`");
  38.316 +}
  38.317 +
  38.318 +#endif
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/libs/assimp/BlenderModifier.h	Sat Feb 01 19:58:19 2014 +0200
    39.3 @@ -0,0 +1,155 @@
    39.4 +/*
    39.5 +Open Asset Import Library (assimp)
    39.6 +----------------------------------------------------------------------
    39.7 +
    39.8 +Copyright (c) 2006-2012, assimp team
    39.9 +All rights reserved.
   39.10 +
   39.11 +Redistribution and use of this software in source and binary forms, 
   39.12 +with or without modification, are permitted provided that the 
   39.13 +following conditions are met:
   39.14 +
   39.15 +* Redistributions of source code must retain the above
   39.16 +  copyright notice, this list of conditions and the
   39.17 +  following disclaimer.
   39.18 +
   39.19 +* Redistributions in binary form must reproduce the above
   39.20 +  copyright notice, this list of conditions and the
   39.21 +  following disclaimer in the documentation and/or other
   39.22 +  materials provided with the distribution.
   39.23 +
   39.24 +* Neither the name of the assimp team, nor the names of its
   39.25 +  contributors may be used to endorse or promote products
   39.26 +  derived from this software without specific prior
   39.27 +  written permission of the assimp team.
   39.28 +
   39.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   39.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   39.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   39.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   39.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   39.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   39.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   39.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   39.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   39.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   39.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   39.40 +
   39.41 +----------------------------------------------------------------------
   39.42 +*/
   39.43 +
   39.44 +/** @file  BlenderModifier.h
   39.45 + *  @brief Declare dedicated helper classes to simulate some blender modifiers (i.e. mirror)
   39.46 + */
   39.47 +#ifndef INCLUDED_AI_BLEND_MODIFIER_H
   39.48 +#define INCLUDED_AI_BLEND_MODIFIER_H
   39.49 +
   39.50 +#include "BlenderIntermediate.h"
   39.51 +#include "TinyFormatter.h"
   39.52 +namespace Assimp {
   39.53 +	namespace Blender {
   39.54 +
   39.55 +// -------------------------------------------------------------------------------------------
   39.56 +/** Dummy base class for all blender modifiers. Modifiers are reused between imports, so
   39.57 + *  they should be stateless and not try to cache model data. */
   39.58 +// -------------------------------------------------------------------------------------------
   39.59 +class BlenderModifier 
   39.60 +{
   39.61 +public:
   39.62 +
   39.63 +	virtual ~BlenderModifier() {
   39.64 +	}
   39.65 +
   39.66 +public:
   39.67 +
   39.68 +	// --------------------
   39.69 +	/** Check if *this* modifier is active, given a ModifierData& block.*/
   39.70 +	virtual bool IsActive( const ModifierData& /*modin*/) {
   39.71 +		return false;
   39.72 +	}
   39.73 +
   39.74 +	// --------------------
   39.75 +	/** Apply the modifier to a given output node. The original data used
   39.76 +	 *  to construct the node is given as well. Not called unless IsActive()
   39.77 +	 *  was called and gave positive response. */
   39.78 +	virtual void DoIt(aiNode& /*out*/,
   39.79 +		ConversionData& /*conv_data*/,
   39.80 +		const ElemBase& orig_modifier, 
   39.81 +		const Scene& /*in*/,
   39.82 +		const Object& /*orig_object*/
   39.83 +	) {
   39.84 +		DefaultLogger::get()->warn((Formatter::format("This modifier is not supported, skipping: "),orig_modifier.dna_type));
   39.85 +		return;
   39.86 +	}
   39.87 +};
   39.88 +
   39.89 +
   39.90 +// -------------------------------------------------------------------------------------------
   39.91 +/** Manage all known modifiers and instance and apply them if necessary */
   39.92 +// -------------------------------------------------------------------------------------------
   39.93 +class BlenderModifierShowcase
   39.94 +{
   39.95 +public:
   39.96 +
   39.97 +	// --------------------
   39.98 +	/** Apply all requested modifiers provided we support them. */
   39.99 +	void ApplyModifiers(aiNode& out,
  39.100 +		ConversionData& conv_data, 
  39.101 +		const Scene& in, 
  39.102 +		const Object& orig_object 
  39.103 +	);
  39.104 +
  39.105 +private:
  39.106 +
  39.107 +	TempArray< std::vector,BlenderModifier > cached_modifiers;
  39.108 +};
  39.109 +
  39.110 +
  39.111 +
  39.112 +
  39.113 +
  39.114 +// MODIFIERS
  39.115 +
  39.116 +
  39.117 +
  39.118 +// -------------------------------------------------------------------------------------------
  39.119 +/** Mirror modifier. Status: implemented. */
  39.120 +// -------------------------------------------------------------------------------------------
  39.121 +class BlenderModifier_Mirror : public BlenderModifier
  39.122 +{
  39.123 +public:
  39.124 +
  39.125 +	// --------------------
  39.126 +	virtual bool IsActive( const ModifierData& modin);
  39.127 +	
  39.128 +	// --------------------
  39.129 +	virtual void DoIt(aiNode& out, 
  39.130 +		ConversionData& conv_data,  
  39.131 +		const ElemBase& orig_modifier, 
  39.132 +		const Scene& in, 
  39.133 +		const Object& orig_object 
  39.134 +	) ;
  39.135 +};
  39.136 +
  39.137 +// -------------------------------------------------------------------------------------------
  39.138 +/** Subdivision modifier. Status: dummy. */
  39.139 +// -------------------------------------------------------------------------------------------
  39.140 +class BlenderModifier_Subdivision : public BlenderModifier
  39.141 +{
  39.142 +public:
  39.143 +
  39.144 +	// --------------------
  39.145 +	virtual bool IsActive( const ModifierData& modin);
  39.146 +	
  39.147 +	// --------------------
  39.148 +	virtual void DoIt(aiNode& out, 
  39.149 +		ConversionData& conv_data,  
  39.150 +		const ElemBase& orig_modifier, 
  39.151 +		const Scene& in, 
  39.152 +		const Object& orig_object 
  39.153 +	) ;
  39.154 +};
  39.155 +
  39.156 +
  39.157 +}}
  39.158 +#endif // !INCLUDED_AI_BLEND_MODIFIER_H
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/libs/assimp/BlenderScene.cpp	Sat Feb 01 19:58:19 2014 +0200
    40.3 @@ -0,0 +1,694 @@
    40.4 +/*
    40.5 +Open Asset Import Library (ASSIMP)
    40.6 +----------------------------------------------------------------------
    40.7 +
    40.8 +Copyright (c) 2006-2010, ASSIMP Development Team
    40.9 +All rights reserved.
   40.10 +
   40.11 +Redistribution and use of this software in source and binary forms, 
   40.12 +with or without modification, are permitted provided that the 
   40.13 +following conditions are met:
   40.14 +
   40.15 +* Redistributions of source code must retain the above
   40.16 +  copyright notice, this list of conditions and the
   40.17 +  following disclaimer.
   40.18 +
   40.19 +* Redistributions in binary form must reproduce the above
   40.20 +  copyright notice, this list of conditions and the
   40.21 +  following disclaimer in the documentation and/or other
   40.22 +  materials provided with the distribution.
   40.23 +
   40.24 +* Neither the name of the ASSIMP team, nor the names of its
   40.25 +  contributors may be used to endorse or promote products
   40.26 +  derived from this software without specific prior
   40.27 +  written permission of the ASSIMP Development Team.
   40.28 +
   40.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   40.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   40.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   40.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   40.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   40.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   40.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   40.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   40.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   40.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   40.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   40.40 +
   40.41 +----------------------------------------------------------------------
   40.42 +*/
   40.43 +
   40.44 +/** @file  BlenderScene.cpp
   40.45 + *  @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
   40.46 + */
   40.47 +#include "AssimpPCH.h"
   40.48 +#ifndef AI_BUILD_NO_BLEND_IMPORTER
   40.49 +
   40.50 +#include "BlenderDNA.h"
   40.51 +#include "BlenderScene.h"
   40.52 +#include "BlenderSceneGen.h"
   40.53 +
   40.54 +using namespace Assimp;
   40.55 +using namespace Assimp::Blender;
   40.56 +
   40.57 +//--------------------------------------------------------------------------------
   40.58 +template <> void Structure :: Convert<Object> (
   40.59 +    Object& dest,
   40.60 +    const FileDatabase& db
   40.61 +    ) const
   40.62 +{ 
   40.63 +
   40.64 +    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
   40.65 +    ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
   40.66 +    ReadFieldArray2<ErrorPolicy_Warn>(dest.obmat,"obmat",db);
   40.67 +    ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
   40.68 +    ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
   40.69 +    {
   40.70 +        boost::shared_ptr<Object> parent;
   40.71 +        ReadFieldPtr<ErrorPolicy_Warn>(parent,"*parent",db);
   40.72 +        dest.parent = parent.get();
   40.73 +    }
   40.74 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.track,"*track",db);
   40.75 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy,"*proxy",db);
   40.76 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy_from,"*proxy_from",db);
   40.77 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy_group,"*proxy_group",db);
   40.78 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.dup_group,"*dup_group",db);
   40.79 +    ReadFieldPtr<ErrorPolicy_Fail>(dest.data,"*data",db);
   40.80 +    ReadField<ErrorPolicy_Igno>(dest.modifiers,"modifiers",db);
   40.81 +
   40.82 +	db.reader->IncPtr(size);
   40.83 +}
   40.84 +
   40.85 +//--------------------------------------------------------------------------------
   40.86 +template <> void Structure :: Convert<Group> (
   40.87 +    Group& dest,
   40.88 +    const FileDatabase& db
   40.89 +    ) const
   40.90 +{ 
   40.91 +
   40.92 +    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
   40.93 +    ReadField<ErrorPolicy_Igno>(dest.layer,"layer",db);
   40.94 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.gobject,"*gobject",db);
   40.95 +
   40.96 +	db.reader->IncPtr(size);
   40.97 +}
   40.98 +
   40.99 +//--------------------------------------------------------------------------------
  40.100 +template <> void Structure :: Convert<MTex> (
  40.101 +    MTex& dest,
  40.102 +    const FileDatabase& db
  40.103 +    ) const
  40.104 +{ 
  40.105 +
  40.106 +    ReadField<ErrorPolicy_Igno>((int&)dest.blendtype,"blendtype",db);
  40.107 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.object,"*object",db);
  40.108 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.tex,"*tex",db);
  40.109 +    ReadFieldArray<ErrorPolicy_Igno>(dest.uvname,"uvname",db);
  40.110 +    ReadField<ErrorPolicy_Igno>((int&)dest.projx,"projx",db);
  40.111 +    ReadField<ErrorPolicy_Igno>((int&)dest.projy,"projy",db);
  40.112 +    ReadField<ErrorPolicy_Igno>((int&)dest.projz,"projz",db);
  40.113 +    ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
  40.114 +    ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
  40.115 +    ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
  40.116 +    ReadField<ErrorPolicy_Igno>(dest.rot,"rot",db);
  40.117 +    ReadField<ErrorPolicy_Igno>(dest.texflag,"texflag",db);
  40.118 +    ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
  40.119 +    ReadField<ErrorPolicy_Igno>(dest.pmapto,"pmapto",db);
  40.120 +    ReadField<ErrorPolicy_Igno>(dest.pmaptoneg,"pmaptoneg",db);
  40.121 +    ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
  40.122 +    ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
  40.123 +    ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
  40.124 +    ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
  40.125 +    ReadField<ErrorPolicy_Igno>(dest.colspecfac,"colspecfac",db);
  40.126 +    ReadField<ErrorPolicy_Igno>(dest.mirrfac,"mirrfac",db);
  40.127 +    ReadField<ErrorPolicy_Igno>(dest.alphafac,"alphafac",db);
  40.128 +    ReadField<ErrorPolicy_Igno>(dest.difffac,"difffac",db);
  40.129 +    ReadField<ErrorPolicy_Igno>(dest.specfac,"specfac",db);
  40.130 +    ReadField<ErrorPolicy_Igno>(dest.emitfac,"emitfac",db);
  40.131 +    ReadField<ErrorPolicy_Igno>(dest.hardfac,"hardfac",db);
  40.132 +
  40.133 +	db.reader->IncPtr(size);
  40.134 +}
  40.135 +
  40.136 +//--------------------------------------------------------------------------------
  40.137 +template <> void Structure :: Convert<TFace> (
  40.138 +    TFace& dest,
  40.139 +    const FileDatabase& db
  40.140 +    ) const
  40.141 +{ 
  40.142 +
  40.143 +    ReadFieldArray2<ErrorPolicy_Fail>(dest.uv,"uv",db);
  40.144 +    ReadFieldArray<ErrorPolicy_Fail>(dest.col,"col",db);
  40.145 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.146 +    ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
  40.147 +    ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
  40.148 +    ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
  40.149 +
  40.150 +	db.reader->IncPtr(size);
  40.151 +}
  40.152 +
  40.153 +//--------------------------------------------------------------------------------
  40.154 +template <> void Structure :: Convert<SubsurfModifierData> (
  40.155 +    SubsurfModifierData& dest,
  40.156 +    const FileDatabase& db
  40.157 +    ) const
  40.158 +{ 
  40.159 +
  40.160 +    ReadField<ErrorPolicy_Fail>(dest.modifier,"modifier",db);
  40.161 +    ReadField<ErrorPolicy_Warn>(dest.subdivType,"subdivType",db);
  40.162 +    ReadField<ErrorPolicy_Fail>(dest.levels,"levels",db);
  40.163 +    ReadField<ErrorPolicy_Igno>(dest.renderLevels,"renderLevels",db);
  40.164 +    ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
  40.165 +
  40.166 +	db.reader->IncPtr(size);
  40.167 +}
  40.168 +
  40.169 +//--------------------------------------------------------------------------------
  40.170 +template <> void Structure :: Convert<MFace> (
  40.171 +    MFace& dest,
  40.172 +    const FileDatabase& db
  40.173 +    ) const
  40.174 +{ 
  40.175 +
  40.176 +    ReadField<ErrorPolicy_Fail>(dest.v1,"v1",db);
  40.177 +    ReadField<ErrorPolicy_Fail>(dest.v2,"v2",db);
  40.178 +    ReadField<ErrorPolicy_Fail>(dest.v3,"v3",db);
  40.179 +    ReadField<ErrorPolicy_Fail>(dest.v4,"v4",db);
  40.180 +    ReadField<ErrorPolicy_Fail>(dest.mat_nr,"mat_nr",db);
  40.181 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.182 +
  40.183 +	db.reader->IncPtr(size);
  40.184 +}
  40.185 +
  40.186 +//--------------------------------------------------------------------------------
  40.187 +template <> void Structure :: Convert<Lamp> (
  40.188 +    Lamp& dest,
  40.189 +    const FileDatabase& db
  40.190 +    ) const
  40.191 +{ 
  40.192 +
  40.193 +    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
  40.194 +    ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
  40.195 +    ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
  40.196 +    ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
  40.197 +    ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
  40.198 +    ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
  40.199 +    ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
  40.200 +    ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
  40.201 +    ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
  40.202 +    ReadField<ErrorPolicy_Igno>(dest.energy,"energy",db);
  40.203 +    ReadField<ErrorPolicy_Igno>(dest.dist,"dist",db);
  40.204 +    ReadField<ErrorPolicy_Igno>(dest.spotsize,"spotsize",db);
  40.205 +    ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
  40.206 +    ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
  40.207 +    ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
  40.208 +    ReadField<ErrorPolicy_Igno>((int&)dest.falloff_type,"falloff_type",db);
  40.209 +    ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
  40.210 +
  40.211 +	db.reader->IncPtr(size);
  40.212 +}
  40.213 +
  40.214 +//--------------------------------------------------------------------------------
  40.215 +template <> void Structure :: Convert<MDeformWeight> (
  40.216 +    MDeformWeight& dest,
  40.217 +    const FileDatabase& db
  40.218 +    ) const
  40.219 +{ 
  40.220 +
  40.221 +    ReadField<ErrorPolicy_Fail>(dest.def_nr,"def_nr",db);
  40.222 +    ReadField<ErrorPolicy_Fail>(dest.weight,"weight",db);
  40.223 +
  40.224 +	db.reader->IncPtr(size);
  40.225 +}
  40.226 +
  40.227 +//--------------------------------------------------------------------------------
  40.228 +template <> void Structure :: Convert<PackedFile> (
  40.229 +    PackedFile& dest,
  40.230 +    const FileDatabase& db
  40.231 +    ) const
  40.232 +{ 
  40.233 +
  40.234 +    ReadField<ErrorPolicy_Warn>(dest.size,"size",db);
  40.235 +    ReadField<ErrorPolicy_Warn>(dest.seek,"seek",db);
  40.236 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.data,"*data",db);
  40.237 +
  40.238 +	db.reader->IncPtr(size);
  40.239 +}
  40.240 +
  40.241 +//--------------------------------------------------------------------------------
  40.242 +template <> void Structure :: Convert<Base> (
  40.243 +    Base& dest,
  40.244 +    const FileDatabase& db
  40.245 +    ) const
  40.246 +{ 
  40.247 +
  40.248 +    {
  40.249 +        boost::shared_ptr<Base> prev;
  40.250 +        ReadFieldPtr<ErrorPolicy_Warn>(prev,"*prev",db);
  40.251 +        dest.prev = prev.get();
  40.252 +    }
  40.253 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.next,"*next",db);
  40.254 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.object,"*object",db);
  40.255 +
  40.256 +	db.reader->IncPtr(size);
  40.257 +}
  40.258 +
  40.259 +//--------------------------------------------------------------------------------
  40.260 +template <> void Structure :: Convert<MTFace> (
  40.261 +    MTFace& dest,
  40.262 +    const FileDatabase& db
  40.263 +    ) const
  40.264 +{ 
  40.265 +
  40.266 +    ReadFieldArray2<ErrorPolicy_Fail>(dest.uv,"uv",db);
  40.267 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.268 +    ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
  40.269 +    ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
  40.270 +    ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
  40.271 +
  40.272 +	db.reader->IncPtr(size);
  40.273 +}
  40.274 +
  40.275 +//--------------------------------------------------------------------------------
  40.276 +template <> void Structure :: Convert<Material> (
  40.277 +    Material& dest,
  40.278 +    const FileDatabase& db
  40.279 +    ) const
  40.280 +{ 
  40.281 +
  40.282 +    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
  40.283 +    ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
  40.284 +    ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
  40.285 +    ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
  40.286 +    ReadField<ErrorPolicy_Warn>(dest.specr,"specr",db);
  40.287 +    ReadField<ErrorPolicy_Warn>(dest.specg,"specg",db);
  40.288 +    ReadField<ErrorPolicy_Warn>(dest.specb,"specb",db);
  40.289 +    ReadField<ErrorPolicy_Igno>(dest.har,"har",db);
  40.290 +    ReadField<ErrorPolicy_Warn>(dest.ambr,"ambr",db);
  40.291 +    ReadField<ErrorPolicy_Warn>(dest.ambg,"ambg",db);
  40.292 +    ReadField<ErrorPolicy_Warn>(dest.ambb,"ambb",db);
  40.293 +    ReadField<ErrorPolicy_Igno>(dest.mirr,"mirr",db);
  40.294 +    ReadField<ErrorPolicy_Igno>(dest.mirg,"mirg",db);
  40.295 +    ReadField<ErrorPolicy_Igno>(dest.mirb,"mirb",db);
  40.296 +    ReadField<ErrorPolicy_Warn>(dest.emit,"emit",db);
  40.297 +    ReadField<ErrorPolicy_Warn>(dest.alpha,"alpha",db);
  40.298 +    ReadField<ErrorPolicy_Igno>(dest.ref,"ref",db);
  40.299 +    ReadField<ErrorPolicy_Igno>(dest.translucency,"translucency",db);
  40.300 +    ReadField<ErrorPolicy_Igno>(dest.roughness,"roughness",db);
  40.301 +    ReadField<ErrorPolicy_Igno>(dest.darkness,"darkness",db);
  40.302 +    ReadField<ErrorPolicy_Igno>(dest.refrac,"refrac",db);
  40.303 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.group,"*group",db);
  40.304 +    ReadField<ErrorPolicy_Warn>(dest.diff_shader,"diff_shader",db);
  40.305 +    ReadField<ErrorPolicy_Warn>(dest.spec_shader,"spec_shader",db);
  40.306 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.mtex,"*mtex",db);
  40.307 +
  40.308 +	db.reader->IncPtr(size);
  40.309 +}
  40.310 +
  40.311 +//--------------------------------------------------------------------------------
  40.312 +template <> void Structure :: Convert<MTexPoly> (
  40.313 +    MTexPoly& dest,
  40.314 +    const FileDatabase& db
  40.315 +    ) const
  40.316 +{ 
  40.317 +
  40.318 +    {
  40.319 +        boost::shared_ptr<Image> tpage;
  40.320 +        ReadFieldPtr<ErrorPolicy_Igno>(tpage,"*tpage",db);
  40.321 +        dest.tpage = tpage.get();
  40.322 +    }
  40.323 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.324 +    ReadField<ErrorPolicy_Igno>(dest.transp,"transp",db);
  40.325 +    ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
  40.326 +    ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
  40.327 +    ReadField<ErrorPolicy_Igno>(dest.pad,"pad",db);
  40.328 +
  40.329 +	db.reader->IncPtr(size);
  40.330 +}
  40.331 +
  40.332 +//--------------------------------------------------------------------------------
  40.333 +template <> void Structure :: Convert<Mesh> (
  40.334 +    Mesh& dest,
  40.335 +    const FileDatabase& db
  40.336 +    ) const
  40.337 +{ 
  40.338 +
  40.339 +    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
  40.340 +    ReadField<ErrorPolicy_Fail>(dest.totface,"totface",db);
  40.341 +    ReadField<ErrorPolicy_Fail>(dest.totedge,"totedge",db);
  40.342 +    ReadField<ErrorPolicy_Fail>(dest.totvert,"totvert",db);
  40.343 +    ReadField<ErrorPolicy_Igno>(dest.totloop,"totloop",db);
  40.344 +    ReadField<ErrorPolicy_Igno>(dest.totpoly,"totpoly",db);
  40.345 +    ReadField<ErrorPolicy_Igno>(dest.subdiv,"subdiv",db);
  40.346 +    ReadField<ErrorPolicy_Igno>(dest.subdivr,"subdivr",db);
  40.347 +    ReadField<ErrorPolicy_Igno>(dest.subsurftype,"subsurftype",db);
  40.348 +    ReadField<ErrorPolicy_Igno>(dest.smoothresh,"smoothresh",db);
  40.349 +    ReadFieldPtr<ErrorPolicy_Fail>(dest.mface,"*mface",db);
  40.350 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.mtface,"*mtface",db);
  40.351 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.tface,"*tface",db);
  40.352 +    ReadFieldPtr<ErrorPolicy_Fail>(dest.mvert,"*mvert",db);
  40.353 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.medge,"*medge",db);
  40.354 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.mloop,"*mloop",db);
  40.355 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.mloopuv,"*mloopuv",db);
  40.356 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.mloopcol,"*mloopcol",db);
  40.357 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.mpoly,"*mpoly",db);
  40.358 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.mtpoly,"*mtpoly",db);
  40.359 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.dvert,"*dvert",db);
  40.360 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db);
  40.361 +    ReadFieldPtr<ErrorPolicy_Fail>(dest.mat,"**mat",db);
  40.362 +
  40.363 +	db.reader->IncPtr(size);
  40.364 +}
  40.365 +
  40.366 +//--------------------------------------------------------------------------------
  40.367 +template <> void Structure :: Convert<MDeformVert> (
  40.368 +    MDeformVert& dest,
  40.369 +    const FileDatabase& db
  40.370 +    ) const
  40.371 +{ 
  40.372 +
  40.373 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.dw,"*dw",db);
  40.374 +    ReadField<ErrorPolicy_Igno>(dest.totweight,"totweight",db);
  40.375 +
  40.376 +	db.reader->IncPtr(size);
  40.377 +}
  40.378 +
  40.379 +//--------------------------------------------------------------------------------
  40.380 +template <> void Structure :: Convert<World> (
  40.381 +    World& dest,
  40.382 +    const FileDatabase& db
  40.383 +    ) const
  40.384 +{ 
  40.385 +
  40.386 +    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
  40.387 +
  40.388 +	db.reader->IncPtr(size);
  40.389 +}
  40.390 +
  40.391 +//--------------------------------------------------------------------------------
  40.392 +template <> void Structure :: Convert<MLoopCol> (
  40.393 +    MLoopCol& dest,
  40.394 +    const FileDatabase& db
  40.395 +    ) const
  40.396 +{ 
  40.397 +
  40.398 +    ReadField<ErrorPolicy_Igno>(dest.r,"r",db);
  40.399 +    ReadField<ErrorPolicy_Igno>(dest.g,"g",db);
  40.400 +    ReadField<ErrorPolicy_Igno>(dest.b,"b",db);
  40.401 +    ReadField<ErrorPolicy_Igno>(dest.a,"a",db);
  40.402 +
  40.403 +	db.reader->IncPtr(size);
  40.404 +}
  40.405 +
  40.406 +//--------------------------------------------------------------------------------
  40.407 +template <> void Structure :: Convert<MVert> (
  40.408 +    MVert& dest,
  40.409 +    const FileDatabase& db
  40.410 +    ) const
  40.411 +{ 
  40.412 +
  40.413 +    ReadFieldArray<ErrorPolicy_Fail>(dest.co,"co",db);
  40.414 +    ReadFieldArray<ErrorPolicy_Fail>(dest.no,"no",db);
  40.415 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.416 +    ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
  40.417 +    ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
  40.418 +
  40.419 +	db.reader->IncPtr(size);
  40.420 +}
  40.421 +
  40.422 +//--------------------------------------------------------------------------------
  40.423 +template <> void Structure :: Convert<MEdge> (
  40.424 +    MEdge& dest,
  40.425 +    const FileDatabase& db
  40.426 +    ) const
  40.427 +{ 
  40.428 +
  40.429 +    ReadField<ErrorPolicy_Fail>(dest.v1,"v1",db);
  40.430 +    ReadField<ErrorPolicy_Fail>(dest.v2,"v2",db);
  40.431 +    ReadField<ErrorPolicy_Igno>(dest.crease,"crease",db);
  40.432 +    ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
  40.433 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.434 +
  40.435 +	db.reader->IncPtr(size);
  40.436 +}
  40.437 +
  40.438 +//--------------------------------------------------------------------------------
  40.439 +template <> void Structure :: Convert<MLoopUV> (
  40.440 +    MLoopUV& dest,
  40.441 +    const FileDatabase& db
  40.442 +    ) const
  40.443 +{ 
  40.444 +
  40.445 +    ReadFieldArray<ErrorPolicy_Igno>(dest.uv,"uv",db);
  40.446 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.447 +
  40.448 +	db.reader->IncPtr(size);
  40.449 +}
  40.450 +
  40.451 +//--------------------------------------------------------------------------------
  40.452 +template <> void Structure :: Convert<GroupObject> (
  40.453 +    GroupObject& dest,
  40.454 +    const FileDatabase& db
  40.455 +    ) const
  40.456 +{ 
  40.457 +
  40.458 +    ReadFieldPtr<ErrorPolicy_Fail>(dest.prev,"*prev",db);
  40.459 +    ReadFieldPtr<ErrorPolicy_Fail>(dest.next,"*next",db);
  40.460 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.ob,"*ob",db);
  40.461 +
  40.462 +	db.reader->IncPtr(size);
  40.463 +}
  40.464 +
  40.465 +//--------------------------------------------------------------------------------
  40.466 +template <> void Structure :: Convert<ListBase> (
  40.467 +    ListBase& dest,
  40.468 +    const FileDatabase& db
  40.469 +    ) const
  40.470 +{ 
  40.471 +
  40.472 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.first,"*first",db);
  40.473 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.last,"*last",db);
  40.474 +
  40.475 +	db.reader->IncPtr(size);
  40.476 +}
  40.477 +
  40.478 +//--------------------------------------------------------------------------------
  40.479 +template <> void Structure :: Convert<MLoop> (
  40.480 +    MLoop& dest,
  40.481 +    const FileDatabase& db
  40.482 +    ) const
  40.483 +{ 
  40.484 +
  40.485 +    ReadField<ErrorPolicy_Igno>(dest.v,"v",db);
  40.486 +    ReadField<ErrorPolicy_Igno>(dest.e,"e",db);
  40.487 +
  40.488 +	db.reader->IncPtr(size);
  40.489 +}
  40.490 +
  40.491 +//--------------------------------------------------------------------------------
  40.492 +template <> void Structure :: Convert<ModifierData> (
  40.493 +    ModifierData& dest,
  40.494 +    const FileDatabase& db
  40.495 +    ) const
  40.496 +{ 
  40.497 +
  40.498 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.next,"*next",db);
  40.499 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.prev,"*prev",db);
  40.500 +    ReadField<ErrorPolicy_Igno>(dest.type,"type",db);
  40.501 +    ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
  40.502 +    ReadFieldArray<ErrorPolicy_Igno>(dest.name,"name",db);
  40.503 +
  40.504 +	db.reader->IncPtr(size);
  40.505 +}
  40.506 +
  40.507 +//--------------------------------------------------------------------------------
  40.508 +template <> void Structure :: Convert<ID> (
  40.509 +    ID& dest,
  40.510 +    const FileDatabase& db
  40.511 +    ) const
  40.512 +{ 
  40.513 +
  40.514 +    ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
  40.515 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.516 +
  40.517 +	db.reader->IncPtr(size);
  40.518 +}
  40.519 +
  40.520 +//--------------------------------------------------------------------------------
  40.521 +template <> void Structure :: Convert<MCol> (
  40.522 +    MCol& dest,
  40.523 +    const FileDatabase& db
  40.524 +    ) const
  40.525 +{ 
  40.526 +
  40.527 +    ReadField<ErrorPolicy_Fail>(dest.r,"r",db);
  40.528 +    ReadField<ErrorPolicy_Fail>(dest.g,"g",db);
  40.529 +    ReadField<ErrorPolicy_Fail>(dest.b,"b",db);
  40.530 +    ReadField<ErrorPolicy_Fail>(dest.a,"a",db);
  40.531 +
  40.532 +	db.reader->IncPtr(size);
  40.533 +}
  40.534 +
  40.535 +//--------------------------------------------------------------------------------
  40.536 +template <> void Structure :: Convert<MPoly> (
  40.537 +    MPoly& dest,
  40.538 +    const FileDatabase& db
  40.539 +    ) const
  40.540 +{ 
  40.541 +
  40.542 +    ReadField<ErrorPolicy_Igno>(dest.loopstart,"loopstart",db);
  40.543 +    ReadField<ErrorPolicy_Igno>(dest.totloop,"totloop",db);
  40.544 +    ReadField<ErrorPolicy_Igno>(dest.mat_nr,"mat_nr",db);
  40.545 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.546 +
  40.547 +	db.reader->IncPtr(size);
  40.548 +}
  40.549 +
  40.550 +//--------------------------------------------------------------------------------
  40.551 +template <> void Structure :: Convert<Scene> (
  40.552 +    Scene& dest,
  40.553 +    const FileDatabase& db
  40.554 +    ) const
  40.555 +{ 
  40.556 +
  40.557 +    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
  40.558 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.camera,"*camera",db);
  40.559 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.world,"*world",db);
  40.560 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.basact,"*basact",db);
  40.561 +    ReadField<ErrorPolicy_Igno>(dest.base,"base",db);
  40.562 +
  40.563 +	db.reader->IncPtr(size);
  40.564 +}
  40.565 +
  40.566 +//--------------------------------------------------------------------------------
  40.567 +template <> void Structure :: Convert<Library> (
  40.568 +    Library& dest,
  40.569 +    const FileDatabase& db
  40.570 +    ) const
  40.571 +{ 
  40.572 +
  40.573 +    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
  40.574 +    ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
  40.575 +    ReadFieldArray<ErrorPolicy_Fail>(dest.filename,"filename",db);
  40.576 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.parent,"*parent",db);
  40.577 +
  40.578 +	db.reader->IncPtr(size);
  40.579 +}
  40.580 +
  40.581 +//--------------------------------------------------------------------------------
  40.582 +template <> void Structure :: Convert<Tex> (
  40.583 +    Tex& dest,
  40.584 +    const FileDatabase& db
  40.585 +    ) const
  40.586 +{ 
  40.587 +
  40.588 +    ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
  40.589 +    ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
  40.590 +
  40.591 +	db.reader->IncPtr(size);
  40.592 +}
  40.593 +
  40.594 +//--------------------------------------------------------------------------------
  40.595 +template <> void Structure :: Convert<Camera> (
  40.596 +    Camera& dest,
  40.597 +    const FileDatabase& db
  40.598 +    ) const
  40.599 +{ 
  40.600 +
  40.601 +    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
  40.602 +    ReadField<ErrorPolicy_Warn>((int&)dest.type,"type",db);
  40.603 +    ReadField<ErrorPolicy_Warn>((int&)dest.flag,"flag",db);
  40.604 +    ReadField<ErrorPolicy_Warn>(dest.angle,"angle",db);
  40.605 +
  40.606 +	db.reader->IncPtr(size);
  40.607 +}
  40.608 +
  40.609 +//--------------------------------------------------------------------------------
  40.610 +template <> void Structure :: Convert<MirrorModifierData> (
  40.611 +    MirrorModifierData& dest,
  40.612 +    const FileDatabase& db
  40.613 +    ) const
  40.614 +{ 
  40.615 +
  40.616 +    ReadField<ErrorPolicy_Fail>(dest.modifier,"modifier",db);
  40.617 +    ReadField<ErrorPolicy_Igno>(dest.axis,"axis",db);
  40.618 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.619 +    ReadField<ErrorPolicy_Igno>(dest.tolerance,"tolerance",db);
  40.620 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.mirror_ob,"*mirror_ob",db);
  40.621 +
  40.622 +	db.reader->IncPtr(size);
  40.623 +}
  40.624 +
  40.625 +//--------------------------------------------------------------------------------
  40.626 +template <> void Structure :: Convert<Image> (
  40.627 +    Image& dest,
  40.628 +    const FileDatabase& db
  40.629 +    ) const
  40.630 +{ 
  40.631 +
  40.632 +    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
  40.633 +    ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
  40.634 +    ReadField<ErrorPolicy_Igno>(dest.ok,"ok",db);
  40.635 +    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
  40.636 +    ReadField<ErrorPolicy_Igno>(dest.source,"source",db);
  40.637 +    ReadField<ErrorPolicy_Igno>(dest.type,"type",db);
  40.638 +    ReadField<ErrorPolicy_Igno>(dest.pad,"pad",db);
  40.639 +    ReadField<ErrorPolicy_Igno>(dest.pad1,"pad1",db);
  40.640 +    ReadField<ErrorPolicy_Igno>(dest.lastframe,"lastframe",db);
  40.641 +    ReadField<ErrorPolicy_Igno>(dest.tpageflag,"tpageflag",db);
  40.642 +    ReadField<ErrorPolicy_Igno>(dest.totbind,"totbind",db);
  40.643 +    ReadField<ErrorPolicy_Igno>(dest.xrep,"xrep",db);
  40.644 +    ReadField<ErrorPolicy_Igno>(dest.yrep,"yrep",db);
  40.645 +    ReadField<ErrorPolicy_Igno>(dest.twsta,"twsta",db);
  40.646 +    ReadField<ErrorPolicy_Igno>(dest.twend,"twend",db);
  40.647 +    ReadFieldPtr<ErrorPolicy_Igno>(dest.packedfile,"*packedfile",db);
  40.648 +    ReadField<ErrorPolicy_Igno>(dest.lastupdate,"lastupdate",db);
  40.649 +    ReadField<ErrorPolicy_Igno>(dest.lastused,"lastused",db);
  40.650 +    ReadField<ErrorPolicy_Igno>(dest.animspeed,"animspeed",db);
  40.651 +    ReadField<ErrorPolicy_Igno>(dest.gen_x,"gen_x",db);
  40.652 +    ReadField<ErrorPolicy_Igno>(dest.gen_y,"gen_y",db);
  40.653 +    ReadField<ErrorPolicy_Igno>(dest.gen_type,"gen_type",db);
  40.654 +
  40.655 +	db.reader->IncPtr(size);
  40.656 +}
  40.657 +
  40.658 +//--------------------------------------------------------------------------------
  40.659 +void DNA::RegisterConverters() {
  40.660 +
  40.661 +    converters["Object"] = DNA::FactoryPair( &Structure::Allocate<Object>, &Structure::Convert<Object> );
  40.662 +    converters["Group"] = DNA::FactoryPair( &Structure::Allocate<Group>, &Structure::Convert<Group> );
  40.663 +    converters["MTex"] = DNA::FactoryPair( &Structure::Allocate<MTex>, &Structure::Convert<MTex> );
  40.664 +    converters["TFace"] = DNA::FactoryPair( &Structure::Allocate<TFace>, &Structure::Convert<TFace> );
  40.665 +    converters["SubsurfModifierData"] = DNA::FactoryPair( &Structure::Allocate<SubsurfModifierData>, &Structure::Convert<SubsurfModifierData> );
  40.666 +    converters["MFace"] = DNA::FactoryPair( &Structure::Allocate<MFace>, &Structure::Convert<MFace> );
  40.667 +    converters["Lamp"] = DNA::FactoryPair( &Structure::Allocate<Lamp>, &Structure::Convert<Lamp> );
  40.668 +    converters["MDeformWeight"] = DNA::FactoryPair( &Structure::Allocate<MDeformWeight>, &Structure::Convert<MDeformWeight> );
  40.669 +    converters["PackedFile"] = DNA::FactoryPair( &Structure::Allocate<PackedFile>, &Structure::Convert<PackedFile> );
  40.670 +    converters["Base"] = DNA::FactoryPair( &Structure::Allocate<Base>, &Structure::Convert<Base> );
  40.671 +    converters["MTFace"] = DNA::FactoryPair( &Structure::Allocate<MTFace>, &Structure::Convert<MTFace> );
  40.672 +    converters["Material"] = DNA::FactoryPair( &Structure::Allocate<Material>, &Structure::Convert<Material> );
  40.673 +    converters["MTexPoly"] = DNA::FactoryPair( &Structure::Allocate<MTexPoly>, &Structure::Convert<MTexPoly> );
  40.674 +    converters["Mesh"] = DNA::FactoryPair( &Structure::Allocate<Mesh>, &Structure::Convert<Mesh> );
  40.675 +    converters["MDeformVert"] = DNA::FactoryPair( &Structure::Allocate<MDeformVert>, &Structure::Convert<MDeformVert> );
  40.676 +    converters["World"] = DNA::FactoryPair( &Structure::Allocate<World>, &Structure::Convert<World> );
  40.677 +    converters["MLoopCol"] = DNA::FactoryPair( &Structure::Allocate<MLoopCol>, &Structure::Convert<MLoopCol> );
  40.678 +    converters["MVert"] = DNA::FactoryPair( &Structure::Allocate<MVert>, &Structure::Convert<MVert> );
  40.679 +    converters["MEdge"] = DNA::FactoryPair( &Structure::Allocate<MEdge>, &Structure::Convert<MEdge> );
  40.680 +    converters["MLoopUV"] = DNA::FactoryPair( &Structure::Allocate<MLoopUV>, &Structure::Convert<MLoopUV> );
  40.681 +    converters["GroupObject"] = DNA::FactoryPair( &Structure::Allocate<GroupObject>, &Structure::Convert<GroupObject> );
  40.682 +    converters["ListBase"] = DNA::FactoryPair( &Structure::Allocate<ListBase>, &Structure::Convert<ListBase> );
  40.683 +    converters["MLoop"] = DNA::FactoryPair( &Structure::Allocate<MLoop>, &Structure::Convert<MLoop> );
  40.684 +    converters["ModifierData"] = DNA::FactoryPair( &Structure::Allocate<ModifierData>, &Structure::Convert<ModifierData> );
  40.685 +    converters["ID"] = DNA::FactoryPair( &Structure::Allocate<ID>, &Structure::Convert<ID> );
  40.686 +    converters["MCol"] = DNA::FactoryPair( &Structure::Allocate<MCol>, &Structure::Convert<MCol> );
  40.687 +    converters["MPoly"] = DNA::FactoryPair( &Structure::Allocate<MPoly>, &Structure::Convert<MPoly> );
  40.688 +    converters["Scene"] = DNA::FactoryPair( &Structure::Allocate<Scene>, &Structure::Convert<Scene> );
  40.689 +    converters["Library"] = DNA::FactoryPair( &Structure::Allocate<Library>, &Structure::Convert<Library> );
  40.690 +    converters["Tex"] = DNA::FactoryPair( &Structure::Allocate<Tex>, &Structure::Convert<Tex> );
  40.691 +    converters["Camera"] = DNA::FactoryPair( &Structure::Allocate<Camera>, &Structure::Convert<Camera> );
  40.692 +    converters["MirrorModifierData"] = DNA::FactoryPair( &Structure::Allocate<MirrorModifierData>, &Structure::Convert<MirrorModifierData> );
  40.693 +    converters["Image"] = DNA::FactoryPair( &Structure::Allocate<Image>, &Structure::Convert<Image> );
  40.694 +}
  40.695 +
  40.696 +
  40.697 +#endif
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/libs/assimp/BlenderScene.h	Sat Feb 01 19:58:19 2014 +0200
    41.3 @@ -0,0 +1,725 @@
    41.4 +/*
    41.5 +Open Asset Import Library (assimp)
    41.6 +----------------------------------------------------------------------
    41.7 +
    41.8 +Copyright (c) 2006-2012, assimp team
    41.9 +All rights reserved.
   41.10 +
   41.11 +Redistribution and use of this software in source and binary forms, 
   41.12 +with or without modification, are permitted provided that the 
   41.13 +following conditions are met:
   41.14 +
   41.15 +* Redistributions of source code must retain the above
   41.16 +  copyright notice, this list of conditions and the
   41.17 +  following disclaimer.
   41.18 +
   41.19 +* Redistributions in binary form must reproduce the above
   41.20 +  copyright notice, this list of conditions and the
   41.21 +  following disclaimer in the documentation and/or other
   41.22 +  materials provided with the distribution.
   41.23 +
   41.24 +* Neither the name of the assimp team, nor the names of its
   41.25 +  contributors may be used to endorse or promote products
   41.26 +  derived from this software without specific prior
   41.27 +  written permission of the assimp team.
   41.28 +
   41.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   41.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   41.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   41.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   41.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   41.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   41.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   41.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   41.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   41.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   41.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   41.40 +
   41.41 +----------------------------------------------------------------------
   41.42 +*/
   41.43 +
   41.44 +/** @file  BlenderScene.h
   41.45 + *  @brief Intermediate representation of a BLEND scene.
   41.46 + */
   41.47 +#ifndef INCLUDED_AI_BLEND_SCENE_H
   41.48 +#define INCLUDED_AI_BLEND_SCENE_H
   41.49 +
   41.50 +namespace Assimp	{
   41.51 +	namespace Blender {
   41.52 +
   41.53 +// Minor parts of this file are extracts from blender data structures,
   41.54 +// declared in the ./source/blender/makesdna directory.
   41.55 +// Stuff that is not used by Assimp is commented.
   41.56 +
   41.57 +
   41.58 +// NOTE
   41.59 +// this file serves as input data to the `./scripts/genblenddna.py`
   41.60 +// script. This script generates the actual binding code to read a
   41.61 +// blender file with a possibly different DNA into our structures.
   41.62 +// Only `struct` declarations are considered and the following 
   41.63 +// rules must be obeyed in order for the script to work properly:
   41.64 +//
   41.65 +// * C++ style comments only
   41.66 +//
   41.67 +// * Structures may include the primitive types char, int, short,
   41.68 +//   float, double. Signedness specifiers are not allowed on 
   41.69 +//	 integers. Enum types are allowed, but they must have been
   41.70 +//   defined in this header.
   41.71 +//
   41.72 +// * Structures may aggregate other structures, unless not defined
   41.73 +//   in this header.
   41.74 +//
   41.75 +// * Pointers to other structures or primitive types are allowed.
   41.76 +//   No references or double pointers or arrays of pointers.
   41.77 +//   A pointer to a T is normally written as boost::shared_ptr, while a
   41.78 +//   pointer to an array of elements is written as boost::
   41.79 +//   shared_array. To avoid cyclic pointers, use raw pointers in
   41.80 +//   one direction.
   41.81 +//
   41.82 +// * Arrays can have maximally two-dimensions. Any non-pointer
   41.83 +//   type can form them.
   41.84 +//
   41.85 +// * Multiple fields can be declare in a single line (i.e `int a,b;`)
   41.86 +//   provided they are neither pointers nor arrays.
   41.87 +//
   41.88 +// * One of WARN, FAIL can be appended to the declaration (
   41.89 +//   prior to the semiolon to specifiy the error handling policy if
   41.90 +//   this field is missing in the input DNA). If none of those
   41.91 +//   is specified the default policy is to subtitute a default
   41.92 +//   value for the field.
   41.93 +//
   41.94 +
   41.95 +#define WARN // warn if field is missing, substitute default value
   41.96 +#define FAIL // fail the import if the field does not exist
   41.97 +
   41.98 +struct Object;
   41.99 +struct MTex;
  41.100 +struct Image;
  41.101 +
  41.102 +#define AI_BLEND_MESH_MAX_VERTS 2000000000L
  41.103 +
  41.104 +// -------------------------------------------------------------------------------
  41.105 +struct ID : ElemBase {
  41.106 +
  41.107 +	char name[24] WARN; 
  41.108 +	short flag;
  41.109 +};
  41.110 +
  41.111 +// -------------------------------------------------------------------------------
  41.112 +struct ListBase : ElemBase {
  41.113 +    
  41.114 +	boost::shared_ptr<ElemBase> first;
  41.115 +	boost::shared_ptr<ElemBase> last;
  41.116 +};
  41.117 +
  41.118 +
  41.119 +// -------------------------------------------------------------------------------
  41.120 +struct PackedFile : ElemBase {
  41.121 +     int size WARN;
  41.122 +     int seek WARN;
  41.123 +	 boost::shared_ptr< FileOffset > data WARN;
  41.124 +};
  41.125 +
  41.126 +// -------------------------------------------------------------------------------
  41.127 +struct GroupObject : ElemBase {
  41.128 +	
  41.129 +	boost::shared_ptr<GroupObject> prev,next FAIL;
  41.130 +	boost::shared_ptr<Object> ob;
  41.131 +};
  41.132 +
  41.133 +// -------------------------------------------------------------------------------
  41.134 +struct Group : ElemBase {
  41.135 +	ID id FAIL;
  41.136 +	int layer;
  41.137 +
  41.138 +	boost::shared_ptr<GroupObject> gobject;
  41.139 +};
  41.140 +
  41.141 +// -------------------------------------------------------------------------------
  41.142 +struct World : ElemBase {
  41.143 +	ID id FAIL;
  41.144 +	
  41.145 +};
  41.146 +
  41.147 +// -------------------------------------------------------------------------------
  41.148 +struct MVert : ElemBase {
  41.149 +	float co[3] FAIL;
  41.150 +	float no[3] FAIL;
  41.151 +	char flag;
  41.152 +	int mat_nr WARN;
  41.153 +	int bweight;
  41.154 +};
  41.155 +
  41.156 +// -------------------------------------------------------------------------------
  41.157 +struct MEdge : ElemBase {
  41.158 +      int v1, v2 FAIL;
  41.159 +      char crease, bweight;
  41.160 +      short flag;
  41.161 +};
  41.162 +
  41.163 +// -------------------------------------------------------------------------------
  41.164 +struct MLoop : ElemBase {
  41.165 +	int v, e;
  41.166 +};
  41.167 +
  41.168 +// -------------------------------------------------------------------------------
  41.169 +struct MLoopUV : ElemBase {
  41.170 +	float uv[2];
  41.171 +	int flag;
  41.172 +};
  41.173 +
  41.174 +// -------------------------------------------------------------------------------
  41.175 +// Note that red and blue are not swapped, as with MCol
  41.176 +struct MLoopCol : ElemBase {
  41.177 +	char r, g, b, a;
  41.178 +};
  41.179 +
  41.180 +// -------------------------------------------------------------------------------
  41.181 +struct MPoly : ElemBase {
  41.182 +	int loopstart;
  41.183 +	int totloop;
  41.184 +	short mat_nr;
  41.185 +	char flag;
  41.186 +};
  41.187 +
  41.188 +// -------------------------------------------------------------------------------
  41.189 +struct MTexPoly : ElemBase {
  41.190 +	Image* tpage;
  41.191 +	char flag, transp;
  41.192 +	short mode, tile, pad;
  41.193 +};
  41.194 +
  41.195 +// -------------------------------------------------------------------------------
  41.196 +struct MCol : ElemBase {
  41.197 +	char r,g,b,a FAIL;
  41.198 +};
  41.199 +
  41.200 +// -------------------------------------------------------------------------------
  41.201 +struct MFace : ElemBase {
  41.202 +	int v1,v2,v3,v4 FAIL;
  41.203 +	int mat_nr FAIL;
  41.204 +	char flag;
  41.205 +};
  41.206 +
  41.207 +// -------------------------------------------------------------------------------
  41.208 +struct TFace : ElemBase {
  41.209 +	float uv[4][2] FAIL;
  41.210 +	int col[4] FAIL;
  41.211 +	char flag;
  41.212 +	short mode;
  41.213 +	short tile;
  41.214 +	short unwrap;
  41.215 +};
  41.216 +
  41.217 +// -------------------------------------------------------------------------------
  41.218 +struct MTFace : ElemBase {
  41.219 +
  41.220 +	float uv[4][2] FAIL;
  41.221 +	char flag;
  41.222 +	short mode;
  41.223 +	short tile;
  41.224 +	short unwrap;
  41.225 +
  41.226 +	// boost::shared_ptr<Image> tpage;
  41.227 +};
  41.228 +
  41.229 +// -------------------------------------------------------------------------------
  41.230 +struct MDeformWeight : ElemBase  {
  41.231 +      int    def_nr FAIL;
  41.232 +      float  weight FAIL;
  41.233 +};
  41.234 +
  41.235 +// -------------------------------------------------------------------------------
  41.236 +struct MDeformVert : ElemBase  {
  41.237 +
  41.238 +	vector<MDeformWeight> dw WARN;
  41.239 +	int totweight;
  41.240 +};
  41.241 +
  41.242 +// -------------------------------------------------------------------------------
  41.243 +struct Material : ElemBase {
  41.244 +	ID id FAIL;
  41.245 +
  41.246 +	float r,g,b WARN;
  41.247 +	float specr,specg,specb WARN;
  41.248 +	short har;
  41.249 +	float ambr,ambg,ambb WARN;
  41.250 +	float mirr,mirg,mirb;
  41.251 +	float emit WARN;
  41.252 +	float alpha WARN;
  41.253 +	float ref;
  41.254 +	float translucency;
  41.255 +	float roughness;
  41.256 +	float darkness;
  41.257 +	float refrac;
  41.258 +
  41.259 +	boost::shared_ptr<Group> group;
  41.260 +
  41.261 +	short diff_shader WARN;
  41.262 +	short spec_shader WARN;
  41.263 +
  41.264 +	boost::shared_ptr<MTex> mtex[18];
  41.265 +};
  41.266 +
  41.267 +// -------------------------------------------------------------------------------
  41.268 +struct Mesh : ElemBase {
  41.269 +	ID id FAIL;
  41.270 +
  41.271 +	int totface FAIL;
  41.272 +	int totedge FAIL;
  41.273 +	int totvert FAIL;
  41.274 +	int totloop;
  41.275 +	int totpoly;
  41.276 +
  41.277 +	short subdiv;
  41.278 +	short subdivr;
  41.279 +	short subsurftype;
  41.280 +	short smoothresh;
  41.281 +
  41.282 +	vector<MFace> mface FAIL;
  41.283 +	vector<MTFace> mtface;
  41.284 +	vector<TFace> tface;
  41.285 +	vector<MVert> mvert FAIL;
  41.286 +	vector<MEdge> medge WARN;
  41.287 +	vector<MLoop> mloop;
  41.288 +	vector<MLoopUV> mloopuv;
  41.289 +	vector<MLoopCol> mloopcol;
  41.290 +	vector<MPoly> mpoly;
  41.291 +	vector<MTexPoly> mtpoly;
  41.292 +	vector<MDeformVert> dvert;
  41.293 +	vector<MCol> mcol;
  41.294 +
  41.295 +	vector< boost::shared_ptr<Material> > mat FAIL;
  41.296 +};
  41.297 +
  41.298 +// -------------------------------------------------------------------------------
  41.299 +struct Library : ElemBase {
  41.300 +	ID id FAIL;
  41.301 +	
  41.302 +	char name[240] WARN;
  41.303 +	char filename[240] FAIL;
  41.304 +	boost::shared_ptr<Library> parent WARN;
  41.305 +};
  41.306 +
  41.307 +// -------------------------------------------------------------------------------
  41.308 +struct Camera : ElemBase {
  41.309 +	enum Type {
  41.310 +		  Type_PERSP	=	0
  41.311 +		 ,Type_ORTHO	=	1
  41.312 +	};
  41.313 +
  41.314 +	ID id FAIL;
  41.315 +
  41.316 +	// struct AnimData *adt;  
  41.317 +
  41.318 +	Type type,flag WARN;
  41.319 +	float angle WARN;
  41.320 +	//float passepartalpha, angle;
  41.321 +	//float clipsta, clipend;
  41.322 +	//float lens, ortho_scale, drawsize;
  41.323 +	//float shiftx, shifty;
  41.324 +
  41.325 +	//float YF_dofdist, YF_aperture;
  41.326 +	//short YF_bkhtype, YF_bkhbias;
  41.327 +	//float YF_bkhrot;
  41.328 +};
  41.329 +
  41.330 +
  41.331 +// -------------------------------------------------------------------------------
  41.332 +struct Lamp : ElemBase {
  41.333 +
  41.334 +	enum FalloffType {
  41.335 +		 FalloffType_Constant	= 0x0
  41.336 +		,FalloffType_InvLinear	= 0x1
  41.337 +		,FalloffType_InvSquare	= 0x2
  41.338 +		//,FalloffType_Curve	= 0x3
  41.339 +		//,FalloffType_Sliders	= 0x4
  41.340 +	};
  41.341 +
  41.342 +	enum Type {
  41.343 +		 Type_Local			= 0x0
  41.344 +		,Type_Sun			= 0x1
  41.345 +		,Type_Spot			= 0x2
  41.346 +		,Type_Hemi			= 0x3
  41.347 +		,Type_Area			= 0x4
  41.348 +		//,Type_YFPhoton	= 0x5
  41.349 +	};
  41.350 +
  41.351 +      ID id FAIL;
  41.352 +      //AnimData *adt;  
  41.353 +      
  41.354 +      Type type FAIL;
  41.355 +	  short flags;
  41.356 +
  41.357 +      //int mode;
  41.358 +      
  41.359 +      short colormodel, totex;
  41.360 +      float r,g,b,k WARN;
  41.361 +      //float shdwr, shdwg, shdwb;
  41.362 +      
  41.363 +      float energy, dist, spotsize, spotblend;
  41.364 +      //float haint;
  41.365 +         
  41.366 +      float att1, att2; 
  41.367 +      //struct CurveMapping *curfalloff;
  41.368 +      FalloffType falloff_type;
  41.369 +      
  41.370 +      //float clipsta, clipend, shadspotsize;
  41.371 +      //float bias, soft, compressthresh;
  41.372 +      //short bufsize, samp, buffers, filtertype;
  41.373 +      //char bufflag, buftype;
  41.374 +      
  41.375 +      //short ray_samp, ray_sampy, ray_sampz;
  41.376 +      //short ray_samp_type;
  41.377 +      //short area_shape;
  41.378 +	  //float area_size, area_sizey, area_sizez;
  41.379 +	  //float adapt_thresh;
  41.380 +	  //short ray_samp_method;
  41.381 +
  41.382 +	  //short texact, shadhalostep;
  41.383 +
  41.384 +	  //short sun_effect_type;
  41.385 +	  //short skyblendtype;
  41.386 +	  //float horizon_brightness;
  41.387 +	  //float spread;
  41.388 +	  float sun_brightness;
  41.389 +	  //float sun_size;
  41.390 +	  //float backscattered_light;
  41.391 +	  //float sun_intensity;
  41.392 +	  //float atm_turbidity;
  41.393 +	  //float atm_inscattering_factor;
  41.394 +	  //float atm_extinction_factor;
  41.395 +	  //float atm_distance_factor;
  41.396 +	  //float skyblendfac;
  41.397 +	  //float sky_exposure;
  41.398 +	  //short sky_colorspace;
  41.399 +
  41.400 +	  // int YF_numphotons, YF_numsearch;
  41.401 +	  // short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad;
  41.402 +	  // float YF_causticblur, YF_ltradius;
  41.403 +
  41.404 +	  // float YF_glowint, YF_glowofs;
  41.405 +      // short YF_glowtype, YF_pad2;
  41.406 +      
  41.407 +      //struct Ipo *ipo;                    
  41.408 +      //struct MTex *mtex[18];              
  41.409 +      // short pr_texture;
  41.410 +      
  41.411 +      //struct PreviewImage *preview;
  41.412 +};
  41.413 +
  41.414 +// -------------------------------------------------------------------------------
  41.415 +struct ModifierData : ElemBase  {
  41.416 +	enum ModifierType {
  41.417 +      eModifierType_None = 0,
  41.418 +      eModifierType_Subsurf,
  41.419 +      eModifierType_Lattice,
  41.420 +      eModifierType_Curve,
  41.421 +      eModifierType_Build,
  41.422 +      eModifierType_Mirror,
  41.423 +      eModifierType_Decimate,
  41.424 +      eModifierType_Wave,
  41.425 +      eModifierType_Armature,
  41.426 +      eModifierType_Hook,
  41.427 +      eModifierType_Softbody,
  41.428 +      eModifierType_Boolean,
  41.429 +      eModifierType_Array,
  41.430 +      eModifierType_EdgeSplit,
  41.431 +      eModifierType_Displace,
  41.432 +      eModifierType_UVProject,
  41.433 +      eModifierType_Smooth,
  41.434 +      eModifierType_Cast,
  41.435 +      eModifierType_MeshDeform,
  41.436 +      eModifierType_ParticleSystem,
  41.437 +      eModifierType_ParticleInstance,
  41.438 +      eModifierType_Explode,
  41.439 +      eModifierType_Cloth,
  41.440 +      eModifierType_Collision,
  41.441 +      eModifierType_Bevel,
  41.442 +      eModifierType_Shrinkwrap,
  41.443 +      eModifierType_Fluidsim,
  41.444 +      eModifierType_Mask,
  41.445 +      eModifierType_SimpleDeform,
  41.446 +      eModifierType_Multires,
  41.447 +      eModifierType_Surface,
  41.448 +      eModifierType_Smoke,
  41.449 +      eModifierType_ShapeKey
  41.450 +	};
  41.451 +
  41.452 +	boost::shared_ptr<ElemBase> next WARN;
  41.453 +	boost::shared_ptr<ElemBase> prev WARN;
  41.454 +
  41.455 +	int type, mode;
  41.456 +	char name[32];
  41.457 +};
  41.458 +
  41.459 +// -------------------------------------------------------------------------------
  41.460 +struct SubsurfModifierData : ElemBase  {
  41.461 +
  41.462 +	enum Type {
  41.463 +		
  41.464 +		TYPE_CatmullClarke = 0x0,
  41.465 +		TYPE_Simple = 0x1
  41.466 +	};
  41.467 +
  41.468 +	enum Flags {
  41.469 +		// some omitted
  41.470 +		FLAGS_SubsurfUV		=1<<3
  41.471 +	};
  41.472 +
  41.473 +	ModifierData modifier FAIL;
  41.474 +	short subdivType WARN;
  41.475 +	short levels FAIL;
  41.476 +	short renderLevels ;
  41.477 +	short flags;
  41.478 +};
  41.479 +
  41.480 +// -------------------------------------------------------------------------------
  41.481 +struct MirrorModifierData : ElemBase {
  41.482 +
  41.483 +	enum Flags {
  41.484 +		Flags_CLIPPING      =1<<0,
  41.485 +		Flags_MIRROR_U      =1<<1,
  41.486 +		Flags_MIRROR_V      =1<<2,
  41.487 +		Flags_AXIS_X        =1<<3,
  41.488 +		Flags_AXIS_Y        =1<<4,
  41.489 +		Flags_AXIS_Z        =1<<5,
  41.490 +		Flags_VGROUP        =1<<6
  41.491 +	};
  41.492 +
  41.493 +	ModifierData modifier FAIL;
  41.494 +
  41.495 +	short axis, flag;
  41.496 +	float tolerance;
  41.497 +	boost::shared_ptr<Object> mirror_ob;
  41.498 +};
  41.499 +
  41.500 +// -------------------------------------------------------------------------------
  41.501 +struct Object : ElemBase  {
  41.502 +	ID id FAIL;
  41.503 +
  41.504 +	enum Type {
  41.505 +		 Type_EMPTY		=	0
  41.506 +		,Type_MESH		=	1
  41.507 +		,Type_CURVE		=	2
  41.508 +		,Type_SURF		=   3
  41.509 +		,Type_FONT		=   4
  41.510 +		,Type_MBALL		=	5
  41.511 +
  41.512 +		,Type_LAMP		=	10
  41.513 +		,Type_CAMERA	=   11
  41.514 +
  41.515 +		,Type_WAVE		=   21
  41.516 +		,Type_LATTICE	=   22
  41.517 +	};
  41.518 +
  41.519 +	Type type FAIL;
  41.520 +	float obmat[4][4] WARN;
  41.521 +	float parentinv[4][4] WARN;
  41.522 +	char parsubstr[32] WARN;
  41.523 +	
  41.524 +	Object* parent WARN;
  41.525 +	boost::shared_ptr<Object> track WARN;
  41.526 +
  41.527 +	boost::shared_ptr<Object> proxy,proxy_from,proxy_group WARN;
  41.528 +	boost::shared_ptr<Group> dup_group WARN;
  41.529 +	boost::shared_ptr<ElemBase> data FAIL;
  41.530 +
  41.531 +	ListBase modifiers;
  41.532 +};
  41.533 +
  41.534 +
  41.535 +// -------------------------------------------------------------------------------
  41.536 +struct Base : ElemBase {
  41.537 +	Base* prev WARN;
  41.538 +	boost::shared_ptr<Base> next WARN;
  41.539 +	boost::shared_ptr<Object> object WARN;
  41.540 +};
  41.541 +
  41.542 +// -------------------------------------------------------------------------------
  41.543 +struct Scene : ElemBase {
  41.544 +	ID id FAIL;
  41.545 +
  41.546 +	boost::shared_ptr<Object> camera WARN;
  41.547 +	boost::shared_ptr<World> world WARN;
  41.548 +	boost::shared_ptr<Base> basact WARN;
  41.549 +
  41.550 +	ListBase base;
  41.551 +};
  41.552 +
  41.553 +
  41.554 +// -------------------------------------------------------------------------------
  41.555 +struct Image : ElemBase {
  41.556 +	ID id FAIL;
  41.557 +
  41.558 +	char name[240] WARN;               
  41.559 +
  41.560 +	//struct anim *anim;
  41.561 +
  41.562 +	short ok, flag;
  41.563 +	short source, type, pad, pad1;
  41.564 +	int lastframe;
  41.565 +
  41.566 +	short tpageflag, totbind;
  41.567 +	short xrep, yrep;
  41.568 +	short twsta, twend;
  41.569 +	//unsigned int bindcode;  
  41.570 +	//unsigned int *repbind; 
  41.571 +
  41.572 +	boost::shared_ptr<PackedFile> packedfile;
  41.573 +	//struct PreviewImage * preview;
  41.574 +
  41.575 +	float lastupdate;
  41.576 +	int lastused;
  41.577 +	short animspeed;
  41.578 +
  41.579 +	short gen_x, gen_y, gen_type; 
  41.580 +};
  41.581 +
  41.582 +// -------------------------------------------------------------------------------
  41.583 +struct Tex : ElemBase {
  41.584 +
  41.585 +	// actually, the only texture type we support is Type_IMAGE
  41.586 +	enum Type {
  41.587 +		 Type_CLOUDS		= 1
  41.588 +		,Type_WOOD			= 2
  41.589 +		,Type_MARBLE		= 3
  41.590 +		,Type_MAGIC			= 4
  41.591 +		,Type_BLEND			= 5
  41.592 +		,Type_STUCCI		= 6
  41.593 +		,Type_NOISE			= 7
  41.594 +		,Type_IMAGE			= 8
  41.595 +		,Type_PLUGIN		= 9
  41.596 +		,Type_ENVMAP		= 10
  41.597 +		,Type_MUSGRAVE		= 11
  41.598 +		,Type_VORONOI		= 12
  41.599 +		,Type_DISTNOISE		= 13
  41.600 +		,Type_POINTDENSITY	= 14
  41.601 +		,Type_VOXELDATA		= 15
  41.602 +	};
  41.603 +
  41.604 +	ID id FAIL;
  41.605 +	// AnimData *adt; 
  41.606 +
  41.607 +	//float noisesize, turbul;
  41.608 +	//float bright, contrast, rfac, gfac, bfac;
  41.609 +	//float filtersize;
  41.610 +
  41.611 +	//float mg_H, mg_lacunarity, mg_octaves, mg_offset, mg_gain;
  41.612 +	//float dist_amount, ns_outscale;
  41.613 +
  41.614 +	//float vn_w1;
  41.615 +	//float vn_w2;
  41.616 +	//float vn_w3;
  41.617 +	//float vn_w4;
  41.618 +	//float vn_mexp;
  41.619 +	//short vn_distm, vn_coltype;
  41.620 +
  41.621 +	//short noisedepth, noisetype;
  41.622 +	//short noisebasis, noisebasis2;
  41.623 +
  41.624 +	//short imaflag, flag;
  41.625 +	Type type FAIL;
  41.626 +	//short stype;
  41.627 +
  41.628 +	//float cropxmin, cropymin, cropxmax, cropymax;
  41.629 +	//int texfilter;
  41.630 +	//int afmax;  
  41.631 +	//short xrepeat, yrepeat;
  41.632 +	//short extend;
  41.633 +
  41.634 +	//short fie_ima;
  41.635 +	//int len;
  41.636 +	//int frames, offset, sfra;
  41.637 +
  41.638 +	//float checkerdist, nabla;
  41.639 +	//float norfac;
  41.640 +
  41.641 +	//ImageUser iuser;
  41.642 +
  41.643 +	//bNodeTree *nodetree;
  41.644 +	//Ipo *ipo;                  
  41.645 +	boost::shared_ptr<Image> ima WARN;
  41.646 +	//PluginTex *plugin;
  41.647 +	//ColorBand *coba;
  41.648 +	//EnvMap *env;
  41.649 +	//PreviewImage * preview;
  41.650 +	//PointDensity *pd;
  41.651 +	//VoxelData *vd;
  41.652 +
  41.653 +	//char use_nodes;
  41.654 +};
  41.655 +
  41.656 +// -------------------------------------------------------------------------------
  41.657 +struct MTex : ElemBase {
  41.658 +
  41.659 +	enum Projection {
  41.660 +		 Proj_N = 0
  41.661 +		,Proj_X = 1
  41.662 +		,Proj_Y = 2
  41.663 +		,Proj_Z = 3
  41.664 +	};
  41.665 +
  41.666 +	enum Flag {
  41.667 +		 Flag_RGBTOINT		= 0x1
  41.668 +		,Flag_STENCIL		= 0x2
  41.669 +		,Flag_NEGATIVE		= 0x4
  41.670 +		,Flag_ALPHAMIX		= 0x8
  41.671 +		,Flag_VIEWSPACE		= 0x10
  41.672 +	};
  41.673 +
  41.674 +	enum BlendType {
  41.675 +		 BlendType_BLEND			= 0
  41.676 +		,BlendType_MUL				= 1
  41.677 +		,BlendType_ADD				= 2
  41.678 +		,BlendType_SUB				= 3
  41.679 +		,BlendType_DIV				= 4
  41.680 +		,BlendType_DARK				= 5
  41.681 +		,BlendType_DIFF				= 6
  41.682 +		,BlendType_LIGHT			= 7
  41.683 +		,BlendType_SCREEN			= 8
  41.684 +		,BlendType_OVERLAY			= 9
  41.685 +		,BlendType_BLEND_HUE		= 10
  41.686 +		,BlendType_BLEND_SAT		= 11
  41.687 +		,BlendType_BLEND_VAL		= 12
  41.688 +		,BlendType_BLEND_COLOR		= 13
  41.689 +	};
  41.690 +
  41.691 +	// short texco, mapto, maptoneg;
  41.692 +
  41.693 +	BlendType blendtype;
  41.694 +	boost::shared_ptr<Object> object;
  41.695 +	boost::shared_ptr<Tex> tex;
  41.696 +	char uvname[32];
  41.697 +
  41.698 +	Projection projx,projy,projz;
  41.699 +	char mapping;
  41.700 +	float ofs[3], size[3], rot;
  41.701 +
  41.702 +	int texflag;
  41.703 +	short colormodel, pmapto, pmaptoneg;
  41.704 +	//short normapspace, which_output;
  41.705 +	//char brush_map_mode;
  41.706 +	float r,g,b,k WARN;
  41.707 +	//float def_var, rt;
  41.708 +
  41.709 +	//float colfac, varfac;
  41.710 +
  41.711 +	//float norfac, dispfac, warpfac;
  41.712 +	float colspecfac, mirrfac, alphafac;
  41.713 +	float difffac, specfac, emitfac, hardfac;
  41.714 +	//float raymirrfac, translfac, ambfac;
  41.715 +	//float colemitfac, colreflfac, coltransfac;
  41.716 +	//float densfac, scatterfac, reflfac;
  41.717 +
  41.718 +	//float timefac, lengthfac, clumpfac;
  41.719 +	//float kinkfac, roughfac, padensfac;
  41.720 +	//float lifefac, sizefac, ivelfac, pvelfac;
  41.721 +	//float shadowfac;
  41.722 +	//float zenupfac, zendownfac, blendfac;
  41.723 +};
  41.724 +
  41.725 +
  41.726 +	}
  41.727 +}
  41.728 +#endif
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/libs/assimp/BlenderSceneGen.h	Sat Feb 01 19:58:19 2014 +0200
    42.3 @@ -0,0 +1,253 @@
    42.4 +/*
    42.5 +Open Asset Import Library (ASSIMP)
    42.6 +----------------------------------------------------------------------
    42.7 +
    42.8 +Copyright (c) 2006-2010, ASSIMP Development Team
    42.9 +All rights reserved.
   42.10 +
   42.11 +Redistribution and use of this software in source and binary forms, 
   42.12 +with or without modification, are permitted provided that the 
   42.13 +following conditions are met:
   42.14 +
   42.15 +* Redistributions of source code must retain the above
   42.16 +  copyright notice, this list of conditions and the
   42.17 +  following disclaimer.
   42.18 +
   42.19 +* Redistributions in binary form must reproduce the above
   42.20 +  copyright notice, this list of conditions and the
   42.21 +  following disclaimer in the documentation and/or other
   42.22 +  materials provided with the distribution.
   42.23 +
   42.24 +* Neither the name of the ASSIMP team, nor the names of its
   42.25 +  contributors may be used to endorse or promote products
   42.26 +  derived from this software without specific prior
   42.27 +  written permission of the ASSIMP Development Team.
   42.28 +
   42.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   42.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   42.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   42.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   42.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   42.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   42.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   42.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   42.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   42.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   42.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   42.40 +
   42.41 +----------------------------------------------------------------------
   42.42 +*/
   42.43 +
   42.44 +/** @file  BlenderSceneGen.h
   42.45 + *  @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
   42.46 + */
   42.47 +#ifndef INCLUDED_AI_BLEND_SCENEGEN_H
   42.48 +#define INCLUDED_AI_BLEND_SCENEGEN_H
   42.49 +
   42.50 +namespace Assimp	{
   42.51 +	namespace Blender {
   42.52 +
   42.53 +
   42.54 +template <> void Structure :: Convert<Object> (
   42.55 +    Object& dest,
   42.56 +    const FileDatabase& db
   42.57 +    ) const
   42.58 +;
   42.59 +
   42.60 +template <> void Structure :: Convert<Group> (
   42.61 +    Group& dest,
   42.62 +    const FileDatabase& db
   42.63 +    ) const
   42.64 +;
   42.65 +
   42.66 +template <> void Structure :: Convert<MTex> (
   42.67 +    MTex& dest,
   42.68 +    const FileDatabase& db
   42.69 +    ) const
   42.70 +;
   42.71 +
   42.72 +template <> void Structure :: Convert<TFace> (
   42.73 +    TFace& dest,
   42.74 +    const FileDatabase& db
   42.75 +    ) const
   42.76 +;
   42.77 +
   42.78 +template <> void Structure :: Convert<SubsurfModifierData> (
   42.79 +    SubsurfModifierData& dest,
   42.80 +    const FileDatabase& db
   42.81 +    ) const
   42.82 +;
   42.83 +
   42.84 +template <> void Structure :: Convert<MFace> (
   42.85 +    MFace& dest,
   42.86 +    const FileDatabase& db
   42.87 +    ) const
   42.88 +;
   42.89 +
   42.90 +template <> void Structure :: Convert<Lamp> (
   42.91 +    Lamp& dest,
   42.92 +    const FileDatabase& db
   42.93 +    ) const
   42.94 +;
   42.95 +
   42.96 +template <> void Structure :: Convert<MDeformWeight> (
   42.97 +    MDeformWeight& dest,
   42.98 +    const FileDatabase& db
   42.99 +    ) const
  42.100 +;
  42.101 +
  42.102 +template <> void Structure :: Convert<PackedFile> (
  42.103 +    PackedFile& dest,
  42.104 +    const FileDatabase& db
  42.105 +    ) const
  42.106 +;
  42.107 +
  42.108 +template <> void Structure :: Convert<Base> (
  42.109 +    Base& dest,
  42.110 +    const FileDatabase& db
  42.111 +    ) const
  42.112 +;
  42.113 +
  42.114 +template <> void Structure :: Convert<MTFace> (
  42.115 +    MTFace& dest,
  42.116 +    const FileDatabase& db
  42.117 +    ) const
  42.118 +;
  42.119 +
  42.120 +template <> void Structure :: Convert<Material> (
  42.121 +    Material& dest,
  42.122 +    const FileDatabase& db
  42.123 +    ) const
  42.124 +;
  42.125 +
  42.126 +template <> void Structure :: Convert<MTexPoly> (
  42.127 +    MTexPoly& dest,
  42.128 +    const FileDatabase& db
  42.129 +    ) const
  42.130 +;
  42.131 +
  42.132 +template <> void Structure :: Convert<Mesh> (
  42.133 +    Mesh& dest,
  42.134 +    const FileDatabase& db
  42.135 +    ) const
  42.136 +;
  42.137 +
  42.138 +template <> void Structure :: Convert<MDeformVert> (
  42.139 +    MDeformVert& dest,
  42.140 +    const FileDatabase& db
  42.141 +    ) const
  42.142 +;
  42.143 +
  42.144 +template <> void Structure :: Convert<World> (
  42.145 +    World& dest,
  42.146 +    const FileDatabase& db
  42.147 +    ) const
  42.148 +;
  42.149 +
  42.150 +template <> void Structure :: Convert<MLoopCol> (
  42.151 +    MLoopCol& dest,
  42.152 +    const FileDatabase& db
  42.153 +    ) const
  42.154 +;
  42.155 +
  42.156 +template <> void Structure :: Convert<MVert> (
  42.157 +    MVert& dest,
  42.158 +    const FileDatabase& db
  42.159 +    ) const
  42.160 +;
  42.161 +
  42.162 +template <> void Structure :: Convert<MEdge> (
  42.163 +    MEdge& dest,
  42.164 +    const FileDatabase& db
  42.165 +    ) const
  42.166 +;
  42.167 +
  42.168 +template <> void Structure :: Convert<MLoopUV> (
  42.169 +    MLoopUV& dest,
  42.170 +    const FileDatabase& db
  42.171 +    ) const
  42.172 +;
  42.173 +
  42.174 +template <> void Structure :: Convert<GroupObject> (
  42.175 +    GroupObject& dest,
  42.176 +    const FileDatabase& db
  42.177 +    ) const
  42.178 +;
  42.179 +
  42.180 +template <> void Structure :: Convert<ListBase> (
  42.181 +    ListBase& dest,
  42.182 +    const FileDatabase& db
  42.183 +    ) const
  42.184 +;
  42.185 +
  42.186 +template <> void Structure :: Convert<MLoop> (
  42.187 +    MLoop& dest,
  42.188 +    const FileDatabase& db
  42.189 +    ) const
  42.190 +;
  42.191 +
  42.192 +template <> void Structure :: Convert<ModifierData> (
  42.193 +    ModifierData& dest,
  42.194 +    const FileDatabase& db
  42.195 +    ) const
  42.196 +;
  42.197 +
  42.198 +template <> void Structure :: Convert<ID> (
  42.199 +    ID& dest,
  42.200 +    const FileDatabase& db
  42.201 +    ) const
  42.202 +;
  42.203 +
  42.204 +template <> void Structure :: Convert<MCol> (
  42.205 +    MCol& dest,
  42.206 +    const FileDatabase& db
  42.207 +    ) const
  42.208 +;
  42.209 +
  42.210 +template <> void Structure :: Convert<MPoly> (
  42.211 +    MPoly& dest,
  42.212 +    const FileDatabase& db
  42.213 +    ) const
  42.214 +;
  42.215 +
  42.216 +template <> void Structure :: Convert<Scene> (
  42.217 +    Scene& dest,
  42.218 +    const FileDatabase& db
  42.219 +    ) const
  42.220 +;
  42.221 +
  42.222 +template <> void Structure :: Convert<Library> (
  42.223 +    Library& dest,
  42.224 +    const FileDatabase& db
  42.225 +    ) const
  42.226 +;
  42.227 +
  42.228 +template <> void Structure :: Convert<Tex> (
  42.229 +    Tex& dest,
  42.230 +    const FileDatabase& db
  42.231 +    ) const
  42.232 +;
  42.233 +
  42.234 +template <> void Structure :: Convert<Camera> (
  42.235 +    Camera& dest,
  42.236 +    const FileDatabase& db
  42.237 +    ) const
  42.238 +;
  42.239 +
  42.240 +template <> void Structure :: Convert<MirrorModifierData> (
  42.241 +    MirrorModifierData& dest,
  42.242 +    const FileDatabase& db
  42.243 +    ) const
  42.244 +;
  42.245 +
  42.246 +template <> void Structure :: Convert<Image> (
  42.247 +    Image& dest,
  42.248 +    const FileDatabase& db
  42.249 +    ) const
  42.250 +;
  42.251 +
  42.252 +
  42.253 +	}
  42.254 +}
  42.255 +
  42.256 +#endif
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/libs/assimp/BlobIOSystem.h	Sat Feb 01 19:58:19 2014 +0200
    43.3 @@ -0,0 +1,326 @@
    43.4 +/*
    43.5 +---------------------------------------------------------------------------
    43.6 +Open Asset Import Library (assimp)
    43.7 +---------------------------------------------------------------------------
    43.8 +
    43.9 +Copyright (c) 2006-2012, assimp team
   43.10 +
   43.11 +All rights reserved.
   43.12 +
   43.13 +Redistribution and use of this software in source and binary forms, 
   43.14 +with or without modification, are permitted provided that the following 
   43.15 +conditions are met:
   43.16 +
   43.17 +* Redistributions of source code must retain the above
   43.18 +  copyright notice, this list of conditions and the
   43.19 +  following disclaimer.
   43.20 +
   43.21 +* Redistributions in binary form must reproduce the above
   43.22 +  copyright notice, this list of conditions and the
   43.23 +  following disclaimer in the documentation and/or other
   43.24 +  materials provided with the distribution.
   43.25 +
   43.26 +* Neither the name of the assimp team, nor the names of its
   43.27 +  contributors may be used to endorse or promote products
   43.28 +  derived from this software without specific prior
   43.29 +  written permission of the assimp team.
   43.30 +
   43.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   43.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   43.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   43.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   43.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   43.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   43.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   43.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   43.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   43.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   43.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   43.42 +---------------------------------------------------------------------------
   43.43 +*/
   43.44 +
   43.45 +/** @file Provides cheat implementations for IOSystem and IOStream to
   43.46 + *  redirect exporter output to a blob chain.*/
   43.47 +
   43.48 +#ifndef AI_BLOBIOSYSTEM_H_INCLUDED
   43.49 +#define AI_BLOBIOSYSTEM_H_INCLUDED
   43.50 +
   43.51 +namespace Assimp	{
   43.52 +	class BlobIOSystem;
   43.53 +
   43.54 +// --------------------------------------------------------------------------------------------
   43.55 +/** Redirect IOStream to a blob */
   43.56 +// --------------------------------------------------------------------------------------------
   43.57 +class BlobIOStream : public IOStream
   43.58 +{
   43.59 +public:
   43.60 +
   43.61 +	BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096)
   43.62 +		: buffer()
   43.63 +		, cur_size()
   43.64 +		, file_size()
   43.65 +		, cursor()
   43.66 +		, initial(initial)
   43.67 +		, file(file)
   43.68 +		, creator(creator)
   43.69 +	{
   43.70 +	}
   43.71 +
   43.72 +
   43.73 +	virtual ~BlobIOStream();
   43.74 +
   43.75 +public:
   43.76 +
   43.77 +	// -------------------------------------------------------------------
   43.78 +	aiExportDataBlob* GetBlob()
   43.79 +	{
   43.80 +		aiExportDataBlob* blob = new aiExportDataBlob();
   43.81 +		blob->size = file_size;
   43.82 +		blob->data = buffer;
   43.83 +
   43.84 +		buffer = NULL;
   43.85 +
   43.86 +		return blob;
   43.87 +	}
   43.88 +
   43.89 +
   43.90 +public:
   43.91 +
   43.92 +
   43.93 +	// -------------------------------------------------------------------
   43.94 +    virtual size_t Read(void* pvBuffer, 
   43.95 +		size_t pSize, 
   43.96 +		size_t pCount) 
   43.97 +	{
   43.98 +		return 0;
   43.99 +	}
  43.100 +
  43.101 +	// -------------------------------------------------------------------
  43.102 +    virtual size_t Write(const void* pvBuffer, 
  43.103 +		size_t pSize,
  43.104 +		size_t pCount) 
  43.105 +	{
  43.106 +		pSize *= pCount;
  43.107 +		if (cursor + pSize > cur_size) {
  43.108 +			Grow(cursor + pSize);
  43.109 +		}
  43.110 +
  43.111 +		memcpy(buffer+cursor, pvBuffer, pSize);
  43.112 +		cursor += pSize;
  43.113 +
  43.114 +		file_size = std::max(file_size,cursor);
  43.115 +		return pCount; 
  43.116 +	}
  43.117 +
  43.118 +	// -------------------------------------------------------------------
  43.119 +	virtual aiReturn Seek(size_t pOffset,
  43.120 +		aiOrigin pOrigin)
  43.121 +	{
  43.122 +		switch(pOrigin) 
  43.123 +		{
  43.124 +		case aiOrigin_CUR:
  43.125 +			cursor += pOffset;
  43.126 +
  43.127 +		case aiOrigin_END:
  43.128 +			cursor = file_size - pOffset;
  43.129 +
  43.130 +		case aiOrigin_SET:
  43.131 +			cursor = pOffset;
  43.132 +			break;
  43.133 +
  43.134 +		default:
  43.135 +			return AI_FAILURE;
  43.136 +		}
  43.137 +
  43.138 +		if (cursor > file_size) {
  43.139 +			Grow(cursor);
  43.140 +		}
  43.141 +
  43.142 +		file_size = std::max(cursor,file_size);
  43.143 +		return AI_SUCCESS;
  43.144 +	}
  43.145 +
  43.146 +	// -------------------------------------------------------------------
  43.147 +    virtual size_t Tell() const
  43.148 +	{
  43.149 +		return cursor;
  43.150 +	}
  43.151 +
  43.152 +	// -------------------------------------------------------------------
  43.153 +	virtual size_t FileSize() const
  43.154 +	{
  43.155 +		return file_size;
  43.156 +	}
  43.157 +
  43.158 +	// -------------------------------------------------------------------
  43.159 +	virtual void Flush() 
  43.160 +	{
  43.161 +		// ignore
  43.162 +	}
  43.163 +
  43.164 +
  43.165 +
  43.166 +private:
  43.167 +
  43.168 +	// -------------------------------------------------------------------
  43.169 +	void Grow(size_t need = 0) 
  43.170 +	{
  43.171 +		// 1.5 and phi are very heap-friendly growth factors (the first
  43.172 +		// allows for frequent re-use of heap blocks, the second
  43.173 +		// forms a fibonacci sequence with similar characteristics -
  43.174 +		// since this heavily depends on the heap implementation 
  43.175 +		// and other factors as well, i'll just go with 1.5 since
  43.176 +		// it is quicker to compute).
  43.177 +		size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
  43.178 +
  43.179 +		const uint8_t* const old = buffer;
  43.180 +		buffer = new uint8_t[new_size];
  43.181 +
  43.182 +		if (old) {
  43.183 +			memcpy(buffer,old,cur_size);
  43.184 +			delete[] old;
  43.185 +		}
  43.186 +
  43.187 +		cur_size = new_size;
  43.188 +	}
  43.189 +
  43.190 +private:
  43.191 +
  43.192 +	uint8_t* buffer;
  43.193 +	size_t cur_size,file_size, cursor, initial;
  43.194 +
  43.195 +	const std::string file;
  43.196 +	BlobIOSystem* const creator;
  43.197 +};
  43.198 +
  43.199 +
  43.200 +#define AI_BLOBIO_MAGIC "$blobfile"
  43.201 +
  43.202 +// --------------------------------------------------------------------------------------------
  43.203 +/** Redirect IOSystem to a blob */
  43.204 +// --------------------------------------------------------------------------------------------
  43.205 +class BlobIOSystem : public IOSystem
  43.206 +{
  43.207 +
  43.208 +	friend class BlobIOStream;
  43.209 +	typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
  43.210 +
  43.211 +public:
  43.212 +
  43.213 +	BlobIOSystem()
  43.214 +	{
  43.215 +	}
  43.216 +
  43.217 +	virtual ~BlobIOSystem()
  43.218 +	{
  43.219 +		BOOST_FOREACH(BlobEntry& blobby, blobs) {
  43.220 +			delete blobby.second;
  43.221 +		}
  43.222 +	}
  43.223 +
  43.224 +public:
  43.225 +
  43.226 +	// -------------------------------------------------------------------
  43.227 +	const char* GetMagicFileName() const 
  43.228 +	{
  43.229 +		return AI_BLOBIO_MAGIC;
  43.230 +	}
  43.231 +
  43.232 +
  43.233 +	// -------------------------------------------------------------------
  43.234 +	aiExportDataBlob* GetBlobChain()
  43.235 +	{
  43.236 +		// one must be the master
  43.237 +		aiExportDataBlob* master = NULL, *cur;
  43.238 +		BOOST_FOREACH(const BlobEntry& blobby, blobs) {
  43.239 +			if (blobby.first == AI_BLOBIO_MAGIC) {
  43.240 +				master = blobby.second;
  43.241 +				break;
  43.242 +			}
  43.243 +		}
  43.244 +		if (!master) {
  43.245 +			DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly.");
  43.246 +			return NULL;
  43.247 +		}
  43.248 +
  43.249 +		master->name.Set("");
  43.250 +
  43.251 +		cur = master;
  43.252 +		BOOST_FOREACH(const BlobEntry& blobby, blobs) {
  43.253 +			if (blobby.second == master) {
  43.254 +				continue;
  43.255 +			}
  43.256 +
  43.257 +			cur->next = blobby.second;
  43.258 +			cur = cur->next;
  43.259 +
  43.260 +			// extract the file extension from the file written
  43.261 +			const std::string::size_type s = blobby.first.find_first_of('.');
  43.262 +			cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1));
  43.263 +		}
  43.264 +
  43.265 +		// give up blob ownership
  43.266 +		blobs.clear();
  43.267 +		return master;
  43.268 +	}
  43.269 +
  43.270 +public:
  43.271 +
  43.272 +	// -------------------------------------------------------------------
  43.273 +	virtual bool Exists( const char* pFile) const {
  43.274 +		return created.find(std::string(pFile)) != created.end();
  43.275 +	}
  43.276 +
  43.277 +
  43.278 +	// -------------------------------------------------------------------
  43.279 +	virtual char getOsSeparator() const {
  43.280 +		return '/';
  43.281 +	}
  43.282 +
  43.283 +
  43.284 +	// -------------------------------------------------------------------
  43.285 +	virtual IOStream* Open(const char* pFile,
  43.286 +		const char* pMode)
  43.287 +	{
  43.288 +		if (pMode[0] != 'w') {
  43.289 +			return NULL;
  43.290 +		}
  43.291 +
  43.292 +		created.insert(std::string(pFile));
  43.293 +		return new BlobIOStream(this,std::string(pFile));
  43.294 +	}
  43.295 +
  43.296 +	// -------------------------------------------------------------------
  43.297 +	virtual void Close( IOStream* pFile) 
  43.298 +	{
  43.299 +		delete pFile;
  43.300 +	}
  43.301 +
  43.302 +private:
  43.303 +
  43.304 +	// -------------------------------------------------------------------
  43.305 +	void OnDestruct(const std::string& filename, BlobIOStream* child) 
  43.306 +	{	
  43.307 +		// we don't know in which the files are closed, so we
  43.308 +		// can't reliably say that the first must be the master 
  43.309 +		// file ...
  43.310 +		blobs.push_back( BlobEntry(filename,child->GetBlob()) );
  43.311 +	}
  43.312 +
  43.313 +private:
  43.314 +	std::set<std::string> created;
  43.315 +	std::vector< BlobEntry > blobs;
  43.316 +};
  43.317 +
  43.318 +
  43.319 +// --------------------------------------------------------------------------------------------
  43.320 +BlobIOStream :: ~BlobIOStream() 
  43.321 +{
  43.322 +	creator->OnDestruct(file,this);
  43.323 +	delete[] buffer;
  43.324 +}
  43.325 +
  43.326 +	
  43.327 +} // end Assimp
  43.328 +
  43.329 +#endif
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/libs/assimp/ByteSwap.h	Sat Feb 01 19:58:19 2014 +0200
    44.3 @@ -0,0 +1,285 @@
    44.4 +/*
    44.5 +Open Asset Import Library (assimp)
    44.6 +----------------------------------------------------------------------
    44.7 +
    44.8 +Copyright (c) 2006-2012, assimp team
    44.9 +All rights reserved.
   44.10 +
   44.11 +Redistribution and use of this software in source and binary forms, 
   44.12 +with or without modification, are permitted provided that the 
   44.13 +following conditions are met:
   44.14 +
   44.15 +* Redistributions of source code must retain the above
   44.16 +  copyright notice, this list of conditions and the
   44.17 +  following disclaimer.
   44.18 +
   44.19 +* Redistributions in binary form must reproduce the above
   44.20 +  copyright notice, this list of conditions and the
   44.21 +  following disclaimer in the documentation and/or other
   44.22 +  materials provided with the distribution.
   44.23 +
   44.24 +* Neither the name of the assimp team, nor the names of its
   44.25 +  contributors may be used to endorse or promote products
   44.26 +  derived from this software without specific prior
   44.27 +  written permission of the assimp team.
   44.28 +
   44.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   44.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   44.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   44.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   44.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   44.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   44.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   44.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   44.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   44.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   44.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   44.40 +
   44.41 +----------------------------------------------------------------------
   44.42 +*/
   44.43 +
   44.44 +/** @file Helper class tp perform various byte oder swappings 
   44.45 +   (e.g. little to big endian) */
   44.46 +#ifndef AI_BYTESWAP_H_INC
   44.47 +#define AI_BYTESWAP_H_INC
   44.48 +
   44.49 +#include "assimp/ai_assert.h"
   44.50 +#include "assimp/types.h"
   44.51 +
   44.52 +#if _MSC_VER >= 1400 
   44.53 +#include <stdlib.h>
   44.54 +#endif
   44.55 +
   44.56 +namespace Assimp	{
   44.57 +// --------------------------------------------------------------------------------------
   44.58 +/** Defines some useful byte order swap routines.
   44.59 + * 
   44.60 + * This is required to read big-endian model formats on little-endian machines,
   44.61 + * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
   44.62 +// --------------------------------------------------------------------------------------
   44.63 +class ByteSwap
   44.64 +{
   44.65 +	ByteSwap() {}
   44.66 +
   44.67 +public:
   44.68 +
   44.69 +	// ----------------------------------------------------------------------
   44.70 +	/** Swap two bytes of data
   44.71 +	 *  @param[inout] _szOut A void* to save the reintcasts for the caller. */
   44.72 +	static inline void Swap2(void* _szOut)
   44.73 +	{
   44.74 +		ai_assert(_szOut);
   44.75 +
   44.76 +#if _MSC_VER >= 1400
   44.77 +		uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
   44.78 +		*szOut = _byteswap_ushort(*szOut);
   44.79 +#else
   44.80 +		uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
   44.81 +		std::swap(szOut[0],szOut[1]);
   44.82 +#endif
   44.83 +	}
   44.84 +
   44.85 +	// ----------------------------------------------------------------------
   44.86 +	/** Swap four bytes of data
   44.87 +	 *  @param[inout] _szOut A void* to save the reintcasts for the caller. */
   44.88 +	static inline void Swap4(void* _szOut)
   44.89 +	{
   44.90 +		ai_assert(_szOut);
   44.91 +
   44.92 +#if _MSC_VER >= 1400
   44.93 +		uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
   44.94 +		*szOut = _byteswap_ulong(*szOut);
   44.95 +#else
   44.96 +		uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
   44.97 +		std::swap(szOut[0],szOut[3]);
   44.98 +		std::swap(szOut[1],szOut[2]);
   44.99 +#endif
  44.100 +	}
  44.101 +
  44.102 +	// ----------------------------------------------------------------------
  44.103 +	/** Swap eight bytes of data
  44.104 +	 *  @param[inout] _szOut A void* to save the reintcasts for the caller. */
  44.105 +	static inline void Swap8(void* _szOut)
  44.106 +	{
  44.107 +	ai_assert(_szOut);
  44.108 +
  44.109 +#if _MSC_VER >= 1400
  44.110 +		uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
  44.111 +		*szOut = _byteswap_uint64(*szOut);
  44.112 +#else
  44.113 +		uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
  44.114 +		std::swap(szOut[0],szOut[7]);
  44.115 +		std::swap(szOut[1],szOut[6]);
  44.116 +		std::swap(szOut[2],szOut[5]);
  44.117 +		std::swap(szOut[3],szOut[4]);
  44.118 +#endif
  44.119 +	}
  44.120 +
  44.121 +	// ----------------------------------------------------------------------
  44.122 +	/** ByteSwap a float. Not a joke.
  44.123 +	 *  @param[inout] fOut ehm. .. */
  44.124 +	static inline void Swap(float* fOut) {
  44.125 +		Swap4(fOut);
  44.126 +	}
  44.127 +
  44.128 +	// ----------------------------------------------------------------------
  44.129 +	/** ByteSwap a double. Not a joke.
  44.130 +	 *  @param[inout] fOut ehm. .. */
  44.131 +	static inline void Swap(double* fOut) {
  44.132 +		Swap8(fOut);
  44.133 +	}
  44.134 +
  44.135 +
  44.136 +	// ----------------------------------------------------------------------
  44.137 +	/** ByteSwap an int16t. Not a joke.
  44.138 +	 *  @param[inout] fOut ehm. .. */
  44.139 +	static inline void Swap(int16_t* fOut) {
  44.140 +		Swap2(fOut);
  44.141 +	}
  44.142 +
  44.143 +	static inline void Swap(uint16_t* fOut) {
  44.144 +		Swap2(fOut);
  44.145 +	}
  44.146 +
  44.147 +	// ----------------------------------------------------------------------
  44.148 +	/** ByteSwap an int32t. Not a joke.
  44.149 +	 *  @param[inout] fOut ehm. .. */
  44.150 +	static inline void Swap(int32_t* fOut){
  44.151 +		Swap4(fOut);
  44.152 +	}
  44.153 +
  44.154 +	static inline void Swap(uint32_t* fOut){
  44.155 +		Swap4(fOut);
  44.156 +	}
  44.157 +
  44.158 +	// ----------------------------------------------------------------------
  44.159 +	/** ByteSwap an int64t. Not a joke.
  44.160 +	 *  @param[inout] fOut ehm. .. */
  44.161 +	static inline void Swap(int64_t* fOut) {
  44.162 +		Swap8(fOut);
  44.163 +	}
  44.164 +
  44.165 +	static inline void Swap(uint64_t* fOut) {
  44.166 +		Swap8(fOut);
  44.167 +	}
  44.168 +
  44.169 +	// ----------------------------------------------------------------------
  44.170 +	//! Templatized ByteSwap
  44.171 +	//! \returns param tOut as swapped
  44.172 +	template<typename Type> 
  44.173 +	static inline Type Swapped(Type tOut)
  44.174 +	{
  44.175 +		return _swapper<Type,sizeof(Type)>()(tOut);
  44.176 +	}
  44.177 +
  44.178 +private:
  44.179 +
  44.180 +	template <typename T, size_t size> struct _swapper;
  44.181 +};
  44.182 +
  44.183 +template <typename T> struct ByteSwap::_swapper<T,2> {
  44.184 +	T operator() (T tOut) {
  44.185 +		Swap2(&tOut); 
  44.186 +		return tOut;
  44.187 +	}
  44.188 +};
  44.189 +
  44.190 +template <typename T> struct ByteSwap::_swapper<T,4> {
  44.191 +	T operator() (T tOut) {
  44.192 +		Swap4(&tOut); 
  44.193 +		return tOut;
  44.194 +	}
  44.195 +};
  44.196 +
  44.197 +template <typename T> struct ByteSwap::_swapper<T,8> {
  44.198 +	T operator() (T tOut) {
  44.199 +		Swap8(&tOut); 
  44.200 +		return tOut;
  44.201 +	}
  44.202 +};
  44.203 +
  44.204 +
  44.205 +// --------------------------------------------------------------------------------------
  44.206 +// ByteSwap macros for BigEndian/LittleEndian support 
  44.207 +// --------------------------------------------------------------------------------------
  44.208 +#if (defined AI_BUILD_BIG_ENDIAN)
  44.209 +#	define AI_LE(t)	(t)
  44.210 +#	define AI_BE(t) ByteSwap::Swapped(t)
  44.211 +#	define AI_LSWAP2(p)
  44.212 +#	define AI_LSWAP4(p)
  44.213 +#	define AI_LSWAP8(p)
  44.214 +#	define AI_LSWAP2P(p)
  44.215 +#	define AI_LSWAP4P(p)
  44.216 +#	define AI_LSWAP8P(p)
  44.217 +#	define LE_NCONST const
  44.218 +#	define AI_SWAP2(p) ByteSwap::Swap2(&(p))
  44.219 +#	define AI_SWAP4(p) ByteSwap::Swap4(&(p))
  44.220 +#	define AI_SWAP8(p) ByteSwap::Swap8(&(p))
  44.221 +#	define AI_SWAP2P(p) ByteSwap::Swap2((p))
  44.222 +#	define AI_SWAP4P(p) ByteSwap::Swap4((p))
  44.223 +#	define AI_SWAP8P(p) ByteSwap::Swap8((p))
  44.224 +#	define BE_NCONST
  44.225 +#else
  44.226 +#	define AI_BE(t)	(t)
  44.227 +#	define AI_LE(t) ByteSwap::Swapped(t)
  44.228 +#	define AI_SWAP2(p)
  44.229 +#	define AI_SWAP4(p)
  44.230 +#	define AI_SWAP8(p)
  44.231 +#	define AI_SWAP2P(p)
  44.232 +#	define AI_SWAP4P(p)
  44.233 +#	define AI_SWAP8P(p)
  44.234 +#	define BE_NCONST const
  44.235 +#	define AI_LSWAP2(p)		ByteSwap::Swap2(&(p))
  44.236 +#	define AI_LSWAP4(p)		ByteSwap::Swap4(&(p))
  44.237 +#	define AI_LSWAP8(p)		ByteSwap::Swap8(&(p))
  44.238 +#	define AI_LSWAP2P(p)	ByteSwap::Swap2((p))
  44.239 +#	define AI_LSWAP4P(p)	ByteSwap::Swap4((p))
  44.240 +#	define AI_LSWAP8P(p)	ByteSwap::Swap8((p))
  44.241 +#	define LE_NCONST
  44.242 +#endif
  44.243 +
  44.244 +
  44.245 +namespace Intern {
  44.246 +
  44.247 +// --------------------------------------------------------------------------------------------
  44.248 +template <typename T, bool doit>
  44.249 +struct ByteSwapper	{
  44.250 +	void operator() (T* inout) {
  44.251 +		ByteSwap::Swap(inout);
  44.252 +	}
  44.253 +};
  44.254 +
  44.255 +template <typename T> 
  44.256 +struct ByteSwapper<T,false>	{
  44.257 +	void operator() (T*) {
  44.258 +	}
  44.259 +};
  44.260 +
  44.261 +// --------------------------------------------------------------------------------------------
  44.262 +template <bool SwapEndianess, typename T, bool RuntimeSwitch>
  44.263 +struct Getter {
  44.264 +	void operator() (T* inout, bool le) {
  44.265 +#ifdef AI_BUILD_BIG_ENDIAN
  44.266 +		le =  le;
  44.267 +#else
  44.268 +		le =  !le;
  44.269 +#endif
  44.270 +		if (le) {
  44.271 +			ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
  44.272 +		}
  44.273 +		else ByteSwapper<T,false> () (inout);
  44.274 +	}
  44.275 +};
  44.276 +
  44.277 +template <bool SwapEndianess, typename T> 
  44.278 +struct Getter<SwapEndianess,T,false> {
  44.279 +
  44.280 +	void operator() (T* inout, bool /*le*/) {
  44.281 +		// static branch
  44.282 +		ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
  44.283 +	}
  44.284 +};
  44.285 +} // end Intern
  44.286 +} // end Assimp
  44.287 +
  44.288 +#endif //!! AI_BYTESWAP_H_INC
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/libs/assimp/CInterfaceIOWrapper.h	Sat Feb 01 19:58:19 2014 +0200
    45.3 @@ -0,0 +1,158 @@
    45.4 +/*
    45.5 +---------------------------------------------------------------------------
    45.6 +Open Asset Import Library (assimp)
    45.7 +---------------------------------------------------------------------------
    45.8 +
    45.9 +Copyright (c) 2006-2012, assimp team
   45.10 +
   45.11 +All rights reserved.
   45.12 +
   45.13 +Redistribution and use of this software in source and binary forms, 
   45.14 +with or without modification, are permitted provided that the following 
   45.15 +conditions are met:
   45.16 +
   45.17 +* Redistributions of source code must retain the above
   45.18 +  copyright notice, this list of conditions and the
   45.19 +  following disclaimer.
   45.20 +
   45.21 +* Redistributions in binary form must reproduce the above
   45.22 +  copyright notice, this list of conditions and the
   45.23 +  following disclaimer in the documentation and/or other
   45.24 +  materials provided with the distribution.
   45.25 +
   45.26 +* Neither the name of the assimp team, nor the names of its
   45.27 +  contributors may be used to endorse or promote products
   45.28 +  derived from this software without specific prior
   45.29 +  written permission of the assimp team.
   45.30 +
   45.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   45.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   45.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   45.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   45.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   45.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   45.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   45.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   45.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   45.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   45.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   45.42 +---------------------------------------------------------------------------
   45.43 +*/
   45.44 +
   45.45 +/** @file aiFileIO -> IOSystem wrapper*/
   45.46 +
   45.47 +#ifndef AI_CIOSYSTEM_H_INCLUDED
   45.48 +#define AI_CIOSYSTEM_H_INCLUDED
   45.49 +
   45.50 +#include "assimp/cfileio.h"
   45.51 +
   45.52 +namespace Assimp	{
   45.53 +	
   45.54 +// ------------------------------------------------------------------------------------------------
   45.55 +// Custom IOStream implementation for the C-API
   45.56 +class CIOStreamWrapper : public IOStream
   45.57 +{
   45.58 +	friend class CIOSystemWrapper;
   45.59 +public:
   45.60 +
   45.61 +	CIOStreamWrapper(aiFile* pFile)
   45.62 +		: mFile(pFile)
   45.63 +	{}
   45.64 +
   45.65 +	// ...................................................................
   45.66 +	size_t Read(void* pvBuffer, 
   45.67 +		size_t pSize, 
   45.68 +		size_t pCount
   45.69 +	){
   45.70 +		// need to typecast here as C has no void*
   45.71 +		return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
   45.72 +	}
   45.73 +
   45.74 +	// ...................................................................
   45.75 +	size_t Write(const void* pvBuffer, 
   45.76 +		size_t pSize,
   45.77 +		size_t pCount
   45.78 +	){
   45.79 +		// need to typecast here as C has no void*
   45.80 +		return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
   45.81 +	}
   45.82 +
   45.83 +	// ...................................................................
   45.84 +	aiReturn Seek(size_t pOffset,
   45.85 +		aiOrigin pOrigin
   45.86 +	){
   45.87 +		return mFile->SeekProc(mFile,pOffset,pOrigin);
   45.88 +	}
   45.89 +
   45.90 +	// ...................................................................
   45.91 +	size_t Tell(void) const {
   45.92 +		return mFile->TellProc(mFile);
   45.93 +	}
   45.94 +
   45.95 +	// ...................................................................
   45.96 +	size_t	FileSize() const {
   45.97 +		return mFile->FileSizeProc(mFile);
   45.98 +	}
   45.99 +
  45.100 +	// ...................................................................
  45.101 +	void Flush () {
  45.102 +		return mFile->FlushProc(mFile);
  45.103 +	}
  45.104 +
  45.105 +private:
  45.106 +	aiFile* mFile;
  45.107 +};
  45.108 +
  45.109 +// ------------------------------------------------------------------------------------------------
  45.110 +// Custom IOStream implementation for the C-API
  45.111 +class CIOSystemWrapper : public IOSystem
  45.112 +{
  45.113 +public:
  45.114 +	CIOSystemWrapper(aiFileIO* pFile)
  45.115 +		: mFileSystem(pFile)
  45.116 +	{}
  45.117 +
  45.118 +	// ...................................................................
  45.119 +	bool Exists( const char* pFile) const {
  45.120 +		aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");		
  45.121 +		if (p){
  45.122 +			mFileSystem->CloseProc(mFileSystem,p);
  45.123 +			return true;
  45.124 +		}
  45.125 +		return false;
  45.126 +	}
  45.127 +
  45.128 +	// ...................................................................
  45.129 +	char getOsSeparator() const {
  45.130 +#ifndef _WIN32
  45.131 +		return '/';
  45.132 +#else
  45.133 +		return '\\';
  45.134 +#endif
  45.135 +	}
  45.136 +
  45.137 +	// ...................................................................
  45.138 +	IOStream* Open(const char* pFile,const char* pMode = "rb") {
  45.139 +		aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
  45.140 +		if (!p) {
  45.141 +			return NULL;
  45.142 +		}
  45.143 +		return new CIOStreamWrapper(p);
  45.144 +	}
  45.145 +
  45.146 +	// ...................................................................
  45.147 +	void Close( IOStream* pFile) {
  45.148 +		if (!pFile) {
  45.149 +			return;
  45.150 +		}
  45.151 +		mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
  45.152 +		delete pFile;
  45.153 +	}
  45.154 +private:
  45.155 +	aiFileIO* mFileSystem;
  45.156 +};
  45.157 +
  45.158 +}
  45.159 +
  45.160 +#endif
  45.161 +
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/libs/assimp/CMakeLists.txt	Sat Feb 01 19:58:19 2014 +0200
    46.3 @@ -0,0 +1,720 @@
    46.4 +# Listing and grouping of all the source files.
    46.5 +# 1) Set the file lists for each component
    46.6 +# 2) Create a Source Group for each component, for IDE project orginization
    46.7 +# 3) Add libassimp using the file lists (eliminates duplication of file names between
    46.8 +#    source groups and library command)
    46.9 +#
   46.10 +SET( HEADER_PATH ../include/assimp )
   46.11 +
   46.12 +SET( COMPILER_HEADERS
   46.13 +	${HEADER_PATH}/Compiler/pushpack1.h
   46.14 +	${HEADER_PATH}/Compiler/poppack1.h
   46.15 +	pstdint.h
   46.16 +)
   46.17 +SOURCE_GROUP( Compiler FILES ${COMPILER_HEADERS})
   46.18 +
   46.19 +SET( PUBLIC_HEADERS
   46.20 +	${HEADER_PATH}/anim.h
   46.21 +	${HEADER_PATH}/ai_assert.h
   46.22 +	${HEADER_PATH}/camera.h
   46.23 +	${HEADER_PATH}/color4.h
   46.24 +	${HEADER_PATH}/color4.inl
   46.25 +	${HEADER_PATH}/config.h
   46.26 +	${HEADER_PATH}/defs.h
   46.27 +	${HEADER_PATH}/cfileio.h
   46.28 +	${HEADER_PATH}/light.h
   46.29 +	${HEADER_PATH}/material.h
   46.30 +	${HEADER_PATH}/material.inl
   46.31 +	${HEADER_PATH}/matrix3x3.h
   46.32 +	${HEADER_PATH}/matrix3x3.inl
   46.33 +	${HEADER_PATH}/matrix4x4.h
   46.34 +	${HEADER_PATH}/matrix4x4.inl
   46.35 +	${HEADER_PATH}/mesh.h
   46.36 +	${HEADER_PATH}/postprocess.h
   46.37 +	${HEADER_PATH}/quaternion.h
   46.38 +	${HEADER_PATH}/quaternion.inl
   46.39 +	${HEADER_PATH}/scene.h
   46.40 +	${HEADER_PATH}/metadata.h
   46.41 +	${HEADER_PATH}/texture.h
   46.42 +	${HEADER_PATH}/types.h
   46.43 +	${HEADER_PATH}/vector2.h
   46.44 +	${HEADER_PATH}/vector2.inl
   46.45 +	${HEADER_PATH}/vector3.h
   46.46 +	${HEADER_PATH}/vector3.inl
   46.47 +	${HEADER_PATH}/version.h
   46.48 +	${HEADER_PATH}/cimport.h
   46.49 +	${HEADER_PATH}/importerdesc.h
   46.50 +	${HEADER_PATH}/Importer.hpp
   46.51 +	${HEADER_PATH}/DefaultLogger.hpp
   46.52 +	${HEADER_PATH}/ProgressHandler.hpp
   46.53 +	${HEADER_PATH}/IOStream.hpp
   46.54 +	${HEADER_PATH}/IOSystem.hpp
   46.55 +	${HEADER_PATH}/Logger.hpp
   46.56 +	${HEADER_PATH}/LogStream.hpp
   46.57 +	${HEADER_PATH}/NullLogger.hpp
   46.58 +	${HEADER_PATH}/cexport.h
   46.59 +	${HEADER_PATH}/Exporter.hpp
   46.60 +)
   46.61 +
   46.62 +SET( Core_SRCS
   46.63 +	Assimp.cpp
   46.64 +)
   46.65 +
   46.66 +SET( Boost_SRCS
   46.67 +	BoostWorkaround/boost/math/common_factor_rt.hpp
   46.68 +	BoostWorkaround/boost/foreach.hpp
   46.69 +	BoostWorkaround/boost/format.hpp
   46.70 +	BoostWorkaround/boost/scoped_array.hpp
   46.71 +	BoostWorkaround/boost/scoped_ptr.hpp
   46.72 +	BoostWorkaround/boost/shared_array.hpp
   46.73 +	BoostWorkaround/boost/shared_ptr.hpp
   46.74 +	BoostWorkaround/boost/make_shared.hpp
   46.75 +	BoostWorkaround/boost/static_assert.hpp
   46.76 +	BoostWorkaround/boost/tuple/tuple.hpp
   46.77 +)
   46.78 +SOURCE_GROUP(Boost FILES ${Boost_SRCS})
   46.79 +
   46.80 +SET( Logging_SRCS
   46.81 +	${HEADER_PATH}/DefaultLogger.hpp
   46.82 +	${HEADER_PATH}/IOStream.hpp
   46.83 +	${HEADER_PATH}/LogStream.hpp
   46.84 +	${HEADER_PATH}/Logger.hpp
   46.85 +	${HEADER_PATH}/NullLogger.hpp
   46.86 +	Win32DebugLogStream.h
   46.87 +	DefaultLogger.cpp
   46.88 +	FileLogStream.h
   46.89 +)
   46.90 +SOURCE_GROUP(Logging FILES ${Logging_SRCS})
   46.91 +
   46.92 +SET( Common_SRCS
   46.93 +	fast_atof.h
   46.94 +	qnan.h
   46.95 +	BaseImporter.cpp
   46.96 +	BaseImporter.h
   46.97 +	BaseProcess.cpp
   46.98 +	BaseProcess.h
   46.99 +	Importer.h
  46.100 +	ScenePrivate.h
  46.101 +	PostStepRegistry.cpp
  46.102 +	ImporterRegistry.cpp
  46.103 +	ByteSwap.h
  46.104 +	DefaultProgressHandler.h
  46.105 +	DefaultIOStream.cpp
  46.106 +	DefaultIOStream.h
  46.107 +	DefaultIOSystem.cpp
  46.108 +	DefaultIOSystem.h
  46.109 +	CInterfaceIOWrapper.h
  46.110 +	Hash.h
  46.111 +	Importer.cpp
  46.112 +	IFF.h
  46.113 +	ParsingUtils.h
  46.114 +	StdOStreamLogStream.h
  46.115 +	StreamReader.h
  46.116 +	StringComparison.h
  46.117 +	SGSpatialSort.cpp
  46.118 +	SGSpatialSort.h
  46.119 +	VertexTriangleAdjacency.cpp
  46.120 +	VertexTriangleAdjacency.h
  46.121 +	GenericProperty.h
  46.122 +	SpatialSort.cpp
  46.123 +	SpatialSort.h
  46.124 +	SceneCombiner.cpp
  46.125 +	SceneCombiner.h
  46.126 +	ScenePreprocessor.cpp
  46.127 +	ScenePreprocessor.h
  46.128 +	SkeletonMeshBuilder.cpp
  46.129 +	SkeletonMeshBuilder.h
  46.130 +	SplitByBoneCountProcess.cpp
  46.131 +	SplitByBoneCountProcess.h
  46.132 +	SmoothingGroups.h
  46.133 +	StandardShapes.cpp
  46.134 +	StandardShapes.h
  46.135 +	TargetAnimation.cpp
  46.136 +	TargetAnimation.h
  46.137 +	RemoveComments.cpp
  46.138 +	RemoveComments.h
  46.139 +	Subdivision.cpp
  46.140 +	Subdivision.h
  46.141 +	Vertex.h
  46.142 +	LineSplitter.h
  46.143 +	TinyFormatter.h
  46.144 +	Profiler.h
  46.145 +	LogAux.h
  46.146 +)
  46.147 +SOURCE_GROUP(Common FILES ${Common_SRCS})
  46.148 +
  46.149 +SET( 3DS_SRCS
  46.150 +	3DSConverter.cpp
  46.151 +	3DSHelper.h
  46.152 +	3DSLoader.cpp
  46.153 +	3DSLoader.h
  46.154 +)
  46.155 +SOURCE_GROUP(3DS FILES ${3DS_SRCS})
  46.156 +
  46.157 +SET( AC_SRCS
  46.158 +	ACLoader.cpp
  46.159 +	ACLoader.h
  46.160 +)
  46.161 +SOURCE_GROUP( AC FILES ${AC_SRCS})
  46.162 +
  46.163 +SET( ASE_SRCS
  46.164 +	ASELoader.cpp
  46.165 +	ASELoader.h
  46.166 +	ASEParser.cpp
  46.167 +	ASEParser.h
  46.168 +)
  46.169 +SOURCE_GROUP( ASE FILES ${ASE_SRCS})
  46.170 +
  46.171 +SET( B3D_SRCS
  46.172 +	B3DImporter.cpp
  46.173 +	B3DImporter.h
  46.174 +)
  46.175 +SOURCE_GROUP( B3D FILES ${B3D_SRCS})
  46.176 +
  46.177 +SET( BVH_SRCS
  46.178 +	BVHLoader.cpp
  46.179 +	BVHLoader.h
  46.180 +)
  46.181 +SOURCE_GROUP( BVH FILES ${BVH_SRCS})
  46.182 +
  46.183 +SET( Collada_SRCS
  46.184 +	ColladaHelper.h
  46.185 +	ColladaLoader.cpp
  46.186 +	ColladaLoader.h
  46.187 +	ColladaParser.cpp
  46.188 +	ColladaParser.h
  46.189 +	ColladaExporter.h
  46.190 +	ColladaExporter.cpp
  46.191 +)
  46.192 +SOURCE_GROUP( Collada FILES ${Collada_SRCS})
  46.193 +
  46.194 +SET( DXF_SRCS
  46.195 +	DXFLoader.cpp
  46.196 +	DXFLoader.h
  46.197 +	DXFHelper.h
  46.198 +)
  46.199 +SOURCE_GROUP( DXF FILES ${DXF_SRCS})
  46.200 +
  46.201 +SET( CSM_SRCS
  46.202 +	CSMLoader.cpp
  46.203 +	CSMLoader.h
  46.204 +)
  46.205 +SOURCE_GROUP( CSM FILES ${CSM_SRCS})
  46.206 +
  46.207 +SET( HMP_SRCS
  46.208 +	HMPFileData.h
  46.209 +	HMPLoader.cpp
  46.210 +	HMPLoader.h
  46.211 +	HalfLifeFileData.h
  46.212 +)
  46.213 +SOURCE_GROUP( HMP FILES ${HMP_SRCS})
  46.214 +
  46.215 +SET( Irr_SRCS
  46.216 +	IRRLoader.cpp
  46.217 +	IRRLoader.h
  46.218 +	IRRMeshLoader.cpp
  46.219 +	IRRMeshLoader.h
  46.220 +	IRRShared.cpp
  46.221 +	IRRShared.h
  46.222 +)
  46.223 +SOURCE_GROUP( Irr FILES ${Irr_SRCS})
  46.224 +
  46.225 +SET( LWO_SRCS
  46.226 +	LWOAnimation.cpp
  46.227 +	LWOAnimation.h
  46.228 +	LWOBLoader.cpp
  46.229 +	LWOFileData.h
  46.230 +	LWOLoader.cpp
  46.231 +	LWOLoader.h
  46.232 +	LWOMaterial.cpp
  46.233 +)
  46.234 +SOURCE_GROUP( LWO FILES ${LWO_SRCS})
  46.235 +
  46.236 +SET( LWS_SRCS
  46.237 +	LWSLoader.cpp
  46.238 +	LWSLoader.h
  46.239 +)
  46.240 +SOURCE_GROUP( LWS FILES ${LWS_SRCS})
  46.241 +
  46.242 +
  46.243 +
  46.244 +SET( MD2_SRCS
  46.245 +	MD2FileData.h
  46.246 +	MD2Loader.cpp
  46.247 +	MD2Loader.h
  46.248 +	MD2NormalTable.h
  46.249 +)
  46.250 +SOURCE_GROUP( MD2 FILES ${MD2_SRCS})
  46.251 +
  46.252 +SET( MD3_SRCS
  46.253 +	MD3FileData.h
  46.254 +	MD3Loader.cpp
  46.255 +	MD3Loader.h
  46.256 +)
  46.257 +SOURCE_GROUP( MD3 FILES ${MD3_SRCS})
  46.258 +
  46.259 +SET( MD5_SRCS
  46.260 +	MD5Loader.cpp
  46.261 +	MD5Loader.h
  46.262 +	MD5Parser.cpp
  46.263 +	MD5Parser.h
  46.264 +)
  46.265 +SOURCE_GROUP( MD5 FILES ${MD5_SRCS})
  46.266 +
  46.267 +SET( MDC_SRCS
  46.268 +	MDCFileData.h
  46.269 +	MDCLoader.cpp
  46.270 +	MDCLoader.h
  46.271 +	MDCNormalTable.h
  46.272 +)
  46.273 +SOURCE_GROUP( MDC FILES ${MDC_SRCS})
  46.274 +
  46.275 +SET( MDL_SRCS
  46.276 +	MDLDefaultColorMap.h
  46.277 +	MDLFileData.h
  46.278 +	MDLLoader.cpp
  46.279 +	MDLLoader.h
  46.280 +	MDLMaterialLoader.cpp
  46.281 +)
  46.282 +SOURCE_GROUP( MDL FILES ${MDL_SRCS})
  46.283 +
  46.284 +SET( MaterialSystem_SRCS
  46.285 +	MaterialSystem.cpp
  46.286 +	MaterialSystem.h
  46.287 +)
  46.288 +SOURCE_GROUP( MaterialSystem FILES ${MaterialSystem_SRCS})
  46.289 +
  46.290 +SET( NFF_SRCS
  46.291 +	NFFLoader.cpp
  46.292 +	NFFLoader.h
  46.293 +)
  46.294 +SOURCE_GROUP( NFF FILES ${NFF_SRCS})
  46.295 +
  46.296 +SET( NDO_SRCS
  46.297 +	NDOLoader.cpp
  46.298 +	NDOLoader.h
  46.299 +)
  46.300 +SOURCE_GROUP( NDO FILES ${NDO_SRCS})
  46.301 +
  46.302 +SET( OFFFormat_SRCS
  46.303 +	OFFLoader.cpp
  46.304 +	OFFLoader.h
  46.305 +)
  46.306 +SOURCE_GROUP( OFFFormat FILES ${OFFFormat_SRCS})
  46.307 +
  46.308 +SET( Obj_SRCS
  46.309 +	ObjFileData.h
  46.310 +	ObjFileImporter.cpp
  46.311 +	ObjFileImporter.h
  46.312 +	ObjFileMtlImporter.cpp
  46.313 +	ObjFileMtlImporter.h
  46.314 +	ObjFileParser.cpp
  46.315 +	ObjFileParser.h
  46.316 +	ObjTools.h
  46.317 +	
  46.318 +	ObjExporter.h
  46.319 +	ObjExporter.cpp
  46.320 +)
  46.321 +SOURCE_GROUP( Obj FILES ${Obj_SRCS})
  46.322 +
  46.323 +SET( Ogre_SRCS
  46.324 +	OgreImporter.hpp
  46.325 +	OgreXmlHelper.hpp
  46.326 +	OgreImporter.cpp
  46.327 +	OgreMaterial.cpp
  46.328 +	OgreMesh.cpp
  46.329 +	OgreSkeleton.cpp
  46.330 +)
  46.331 +SOURCE_GROUP( Ogre FILES ${Ogre_SRCS})
  46.332 +
  46.333 +SET( Ply_SRCS
  46.334 +	PlyLoader.cpp
  46.335 +	PlyLoader.h
  46.336 +	PlyParser.cpp
  46.337 +	PlyParser.h
  46.338 +	PlyExporter.cpp
  46.339 +	PlyExporter.h
  46.340 +)
  46.341 +SOURCE_GROUP( Ply FILES ${Ply_SRCS})
  46.342 +
  46.343 +SET(MS3D_SRCS
  46.344 +	MS3DLoader.cpp
  46.345 +	MS3DLoader.h
  46.346 +)
  46.347 +SOURCE_GROUP( MS3D FILES ${MS3D_SRCS})
  46.348 +
  46.349 +SET(COB_SRCS
  46.350 +	COBLoader.cpp
  46.351 +	COBLoader.h
  46.352 +	COBScene.h
  46.353 +)
  46.354 +SOURCE_GROUP( COB FILES ${COB_SRCS})
  46.355 +
  46.356 +SET(BLENDER_SRCS
  46.357 +	BlenderLoader.cpp
  46.358 +	BlenderLoader.h
  46.359 +	BlenderDNA.cpp
  46.360 +	BlenderDNA.h
  46.361 +	BlenderDNA.inl
  46.362 +	BlenderScene.cpp
  46.363 +	BlenderScene.h
  46.364 +	BlenderSceneGen.h
  46.365 +	BlenderIntermediate.h
  46.366 +	BlenderModifier.h
  46.367 +	BlenderModifier.cpp
  46.368 +)
  46.369 +SOURCE_GROUP( BLENDER FILES ${BLENDER_SRCS})
  46.370 +
  46.371 +SET(IFC_SRCS
  46.372 +	IFCLoader.cpp
  46.373 +	IFCLoader.h
  46.374 +	IFCReaderGen.cpp
  46.375 +	IFCReaderGen.h
  46.376 +	IFCUtil.h
  46.377 +	IFCUtil.cpp
  46.378 +	IFCGeometry.cpp
  46.379 +	IFCMaterial.cpp
  46.380 +	IFCProfile.cpp
  46.381 +	IFCCurve.cpp
  46.382 +	IFCBoolean.cpp
  46.383 +	IFCOpenings.cpp
  46.384 +	STEPFile.h
  46.385 +	STEPFileReader.h
  46.386 +	STEPFileReader.cpp
  46.387 +	STEPFileEncoding.cpp
  46.388 +	STEPFileEncoding.h
  46.389 +)
  46.390 +SOURCE_GROUP( IFC FILES ${IFC_SRCS})
  46.391 +
  46.392 +SET( XGL_SRCS
  46.393 +	XGLLoader.cpp
  46.394 +	XGLLoader.h
  46.395 +)
  46.396 +SOURCE_GROUP( XGL FILES ${XGL_SRCS})
  46.397 +
  46.398 +
  46.399 +SET(FBX_SRCS
  46.400 +	FBXImporter.cpp
  46.401 +	FBXCompileConfig.h
  46.402 +	FBXImporter.h
  46.403 +	FBXParser.cpp
  46.404 +	FBXParser.h
  46.405 +	FBXTokenizer.cpp
  46.406 +	FBXTokenizer.h
  46.407 +	FBXImportSettings.h
  46.408 +	FBXConverter.h
  46.409 +	FBXConverter.cpp
  46.410 +	FBXUtil.h
  46.411 +	FBXUtil.cpp
  46.412 +	FBXDocument.h
  46.413 +	FBXDocument.cpp
  46.414 +	FBXProperties.h
  46.415 +	FBXProperties.cpp
  46.416 +	FBXMeshGeometry.cpp
  46.417 +	FBXMaterial.cpp
  46.418 +	FBXModel.cpp
  46.419 +	FBXAnimation.cpp
  46.420 +	FBXNodeAttribute.cpp
  46.421 +	FBXDeformer.cpp
  46.422 +	FBXBinaryTokenizer.cpp
  46.423 +	FBXDocumentUtil.cpp
  46.424 +)
  46.425 +SOURCE_GROUP( FBX FILES ${FBX_SRCS})
  46.426 +
  46.427 +
  46.428 +SET( PostProcessing_SRCS
  46.429 +	CalcTangentsProcess.cpp
  46.430 +	CalcTangentsProcess.h
  46.431 +	ComputeUVMappingProcess.cpp
  46.432 +	ComputeUVMappingProcess.h
  46.433 +	ConvertToLHProcess.cpp
  46.434 +	ConvertToLHProcess.h
  46.435 +	FindDegenerates.cpp
  46.436 +	FindDegenerates.h
  46.437 +	FindInstancesProcess.cpp
  46.438 +	FindInstancesProcess.h
  46.439 +	FindInvalidDataProcess.cpp
  46.440 +	FindInvalidDataProcess.h
  46.441 +	FixNormalsStep.cpp
  46.442 +	FixNormalsStep.h
  46.443 +	GenFaceNormalsProcess.cpp
  46.444 +	GenFaceNormalsProcess.h
  46.445 +	GenVertexNormalsProcess.cpp
  46.446 +	GenVertexNormalsProcess.h
  46.447 +	PretransformVertices.cpp
  46.448 +	PretransformVertices.h
  46.449 +	ImproveCacheLocality.cpp
  46.450 +	ImproveCacheLocality.h
  46.451 +	JoinVerticesProcess.cpp
  46.452 +	JoinVerticesProcess.h
  46.453 +	LimitBoneWeightsProcess.cpp
  46.454 +	LimitBoneWeightsProcess.h
  46.455 +	RemoveRedundantMaterials.cpp
  46.456 +	RemoveRedundantMaterials.h
  46.457 +	RemoveVCProcess.cpp
  46.458 +	RemoveVCProcess.h
  46.459 +	SortByPTypeProcess.cpp
  46.460 +	SortByPTypeProcess.h
  46.461 +	SplitLargeMeshes.cpp
  46.462 +	SplitLargeMeshes.h
  46.463 +	TerragenLoader.cpp
  46.464 +	TerragenLoader.h
  46.465 +	TextureTransform.cpp
  46.466 +	TextureTransform.h
  46.467 +	TriangulateProcess.cpp
  46.468 +	TriangulateProcess.h
  46.469 +	ValidateDataStructure.cpp
  46.470 +	ValidateDataStructure.h
  46.471 +	OptimizeGraph.cpp
  46.472 +	OptimizeGraph.h
  46.473 +	OptimizeMeshes.cpp
  46.474 +	OptimizeMeshes.h
  46.475 +	DeboneProcess.cpp
  46.476 +	DeboneProcess.h
  46.477 +	ProcessHelper.h
  46.478 +	ProcessHelper.cpp
  46.479 +	PolyTools.h
  46.480 +	MakeVerboseFormat.cpp
  46.481 +	MakeVerboseFormat.h
  46.482 +)
  46.483 +SOURCE_GROUP( PostProcessing FILES ${PostProcessing_SRCS})
  46.484 +
  46.485 +SET( Q3D_SRCS
  46.486 +	Q3DLoader.cpp
  46.487 +	Q3DLoader.h
  46.488 +)
  46.489 +SOURCE_GROUP( Q3D FILES ${Q3D_SRCS})
  46.490 +
  46.491 +SET( Q3BSP_SRCS
  46.492 +	Q3BSPFileData.h
  46.493 +	Q3BSPFileParser.h
  46.494 +	Q3BSPFileParser.cpp
  46.495 +	Q3BSPFileImporter.h
  46.496 +	Q3BSPFileImporter.cpp
  46.497 +	Q3BSPZipArchive.h
  46.498 +	Q3BSPZipArchive.cpp
  46.499 +)
  46.500 +SOURCE_GROUP( Q3BSP FILES ${Q3BSP_SRCS})
  46.501 +
  46.502 +SET( Raw_SRCS
  46.503 +	RawLoader.cpp
  46.504 +	RawLoader.h
  46.505 +)
  46.506 +SOURCE_GROUP( Raw FILES ${Raw_SRCS})
  46.507 +
  46.508 +SET( SMD_SRCS
  46.509 +	SMDLoader.cpp
  46.510 +	SMDLoader.h
  46.511 +)
  46.512 +SOURCE_GROUP( SMD FILES ${SMD_SRCS})
  46.513 +
  46.514 +SET( STL_SRCS
  46.515 +	STLLoader.cpp
  46.516 +	STLLoader.h
  46.517 +	STLExporter.h
  46.518 +	STLExporter.cpp
  46.519 +)
  46.520 +SOURCE_GROUP( STL FILES ${STL_SRCS})
  46.521 +
  46.522 +SET( Unreal_SRCS
  46.523 +	UnrealLoader.cpp
  46.524 +	UnrealLoader.h
  46.525 +)
  46.526 +SOURCE_GROUP( Unreal FILES ${Unreal_SRCS})
  46.527 +
  46.528 +SET( XFile_SRCS
  46.529 +	XFileHelper.h
  46.530 +	XFileImporter.cpp
  46.531 +	XFileImporter.h
  46.532 +	XFileParser.cpp
  46.533 +	XFileParser.h
  46.534 +)
  46.535 +SOURCE_GROUP( XFile FILES ${XFile_SRCS})
  46.536 +
  46.537 +SET( Exporter_SRCS
  46.538 +	Exporter.cpp
  46.539 +	AssimpCExport.cpp
  46.540 +	BlobIOSystem.h
  46.541 +)
  46.542 +SOURCE_GROUP( Exporter FILES ${Exporter_SRCS})
  46.543 +
  46.544 +SET( Extra_SRCS
  46.545 +	MD4FileData.h
  46.546 +)
  46.547 +SOURCE_GROUP( Extra FILES ${Extra_SRCS})
  46.548 +
  46.549 +SET( IrrXML_SRCS
  46.550 +	irrXMLWrapper.h
  46.551 +	../contrib/irrXML/CXMLReaderImpl.h
  46.552 +	../contrib/irrXML/heapsort.h
  46.553 +	../contrib/irrXML/irrArray.h
  46.554 +	../contrib/irrXML/irrString.h
  46.555 +	../contrib/irrXML/irrTypes.h
  46.556 +	../contrib/irrXML/irrXML.cpp
  46.557 +	../contrib/irrXML/irrXML.h
  46.558 +)
  46.559 +SOURCE_GROUP( IrrXML FILES ${IrrXML_SRCS})
  46.560 +
  46.561 +SET( ConvertUTF_SRCS
  46.562 +	../contrib/ConvertUTF/ConvertUTF.h
  46.563 +	../contrib/ConvertUTF/ConvertUTF.c
  46.564 +)
  46.565 +SOURCE_GROUP( ConvertUTF FILES ${ConvertUTF_SRCS})
  46.566 +
  46.567 +SET( Clipper_SRCS 
  46.568 +	../contrib/clipper/clipper.hpp
  46.569 +	../contrib/clipper/clipper.cpp
  46.570 +)
  46.571 +SOURCE_GROUP( Clipper FILES ${Clipper_SRCS})
  46.572 +
  46.573 +
  46.574 +SET( Poly2Tri_SRCS 
  46.575 +	../contrib/poly2tri/poly2tri/common/shapes.cc
  46.576 +	../contrib/poly2tri/poly2tri/common/shapes.h
  46.577 +	../contrib/poly2tri/poly2tri/common/utils.h
  46.578 +	../contrib/poly2tri/poly2tri/sweep/advancing_front.h
  46.579 +	../contrib/poly2tri/poly2tri/sweep/advancing_front.cc
  46.580 +	../contrib/poly2tri/poly2tri/sweep/cdt.cc
  46.581 +	../contrib/poly2tri/poly2tri/sweep/cdt.h
  46.582 +	../contrib/poly2tri/poly2tri/sweep/sweep.cc
  46.583 +	../contrib/poly2tri/poly2tri/sweep/sweep.h
  46.584 +	../contrib/poly2tri/poly2tri/sweep/sweep_context.cc
  46.585 +	../contrib/poly2tri/poly2tri/sweep/sweep_context.h
  46.586 +)
  46.587 +SOURCE_GROUP( Poly2Tri FILES ${Poly2Tri_SRCS})
  46.588 +
  46.589 +SET( unzip_SRCS
  46.590 +	../contrib/unzip/crypt.h
  46.591 +	../contrib/unzip/ioapi.c
  46.592 +	../contrib/unzip/ioapi.h
  46.593 +	../contrib/unzip/unzip.c
  46.594 +	../contrib/unzip/unzip.h
  46.595 +)
  46.596 +SOURCE_GROUP( unzip FILES ${unzip_SRCS})
  46.597 +
  46.598 +
  46.599 +# VC2010 fixes
  46.600 +if(MSVC10)
  46.601 +	OPTION( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF )
  46.602 +	if( VC10_STDINT_FIX )
  46.603 +		ADD_DEFINITIONS( -D_STDINT )
  46.604 +	endif( VC10_STDINT_FIX )
  46.605 +endif(MSVC10)
  46.606 +
  46.607 +ADD_DEFINITIONS( -DASSIMP_BUILD_DLL_EXPORT )
  46.608 +
  46.609 +if ( MSVC )
  46.610 +	ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
  46.611 +	ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
  46.612 +endif ( MSVC )
  46.613 +
  46.614 +if (UNZIP_FOUND)
  46.615 +	SET (unzip_compile_SRCS "")
  46.616 +else (UNZIP_FOUND)
  46.617 +	SET (unzip_compile_SRCS ${unzip_SRCS})
  46.618 +endif (UNZIP_FOUND)
  46.619 +
  46.620 +SET( assimp_src
  46.621 +	# Assimp Files
  46.622 +	${Core_SRCS}
  46.623 +	${Common_SRCS}
  46.624 +	${Logging_SRCS}
  46.625 +	${Exporter_SRCS}
  46.626 +	${PostProcessing_SRCS}
  46.627 +
  46.628 +	# Model Support
  46.629 +	${3DS_SRCS}
  46.630 +	${AC_SRCS}
  46.631 +	${ASE_SRCS}
  46.632 +	${B3D_SRCS}
  46.633 +	${BVH_SRCS}
  46.634 +	${Collada_SRCS}
  46.635 +	${DXF_SRCS}
  46.636 +	${CSM_SRCS}
  46.637 +	${HMP_SRCS}
  46.638 +	${Irr_SRCS}
  46.639 +	${LWO_SRCS}
  46.640 +	${LWS_SRCS}
  46.641 +	${MD2_SRCS}
  46.642 +	${MD3_SRCS}
  46.643 +	${MD5_SRCS}
  46.644 +	${MDC_SRCS}
  46.645 +	${MDL_SRCS}
  46.646 +	${MaterialSystem_SRCS}
  46.647 +	${NFF_SRCS}
  46.648 +	${OFFFormat_SRCS}
  46.649 +	${Obj_SRCS}
  46.650 +	${Ogre_SRCS}
  46.651 +	${Ply_SRCS}
  46.652 +	${Q3D_SRCS}
  46.653 +	${Q3BSP_SRCS}
  46.654 +	${Raw_SRCS}
  46.655 +	${SMD_SRCS}
  46.656 +	${STL_SRCS}
  46.657 +	${Unreal_SRCS}
  46.658 +	${XFile_SRCS}
  46.659 +	${Extra_SRCS}
  46.660 +	${MS3D_SRCS}
  46.661 +	${COB_SRCS}
  46.662 +	${BLENDER_SRCS}
  46.663 +	${NDO_SRCS}
  46.664 +	${IFC_SRCS}
  46.665 +	${XGL_SRCS}
  46.666 +	${FBX_SRCS}
  46.667 +	
  46.668 +	# Third-party libraries
  46.669 +	${IrrXML_SRCS}
  46.670 +	${ConvertUTF_SRCS}
  46.671 +	${unzip_compile_SRCS}
  46.672 +	${Poly2Tri_SRCS}
  46.673 +	${Clipper_SRCS}
  46.674 +	# Necessary to show the headers in the project when using the VC++ generator:
  46.675 +	${Boost_SRCS}
  46.676 +
  46.677 +	${PUBLIC_HEADERS}
  46.678 +	${COMPILER_HEADERS}
  46.679 +)
  46.680 +
  46.681 +ADD_MSVC_PRECOMPILED_HEADER("AssimpPCH.h" "AssimpPCH.cpp" assimp_src)
  46.682 +
  46.683 +IF ( ASSIMP_BUILD_STATIC_LIB )
  46.684 +	ADD_LIBRARY( assimp STATIC
  46.685 +		${assimp_src}
  46.686 +	)
  46.687 +ELSE ( ASSIMP_BUILD_STATIC_LIB )
  46.688 +	ADD_LIBRARY( assimp SHARED
  46.689 +		${assimp_src}
  46.690 +	)
  46.691 +ENDIF ( ASSIMP_BUILD_STATIC_LIB )
  46.692 +
  46.693 +SET_PROPERTY(TARGET assimp PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
  46.694 +
  46.695 +TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES})
  46.696 +SET_TARGET_PROPERTIES( assimp PROPERTIES
  46.697 +	VERSION ${ASSIMP_VERSION}
  46.698 +	SOVERSION ${ASSIMP_SOVERSION} # use full version 
  46.699 +    OUTPUT_NAME assimp${ASSIMP_LIBRARY_SUFFIX}
  46.700 +)
  46.701 +# Build against external unzip, or add ../contrib/unzip so
  46.702 +# assimp can #include "unzip.h"
  46.703 +if (UNZIP_FOUND)
  46.704 +	INCLUDE_DIRECTORIES(${UNZIP_INCLUDE_DIRS})
  46.705 +	TARGET_LINK_LIBRARIES(assimp ${UNZIP_LIBRARIES})
  46.706 +else (UNZIP_FOUND)
  46.707 +	INCLUDE_DIRECTORIES("../contrib/unzip")
  46.708 +endif (UNZIP_FOUND)
  46.709 +
  46.710 +INSTALL( TARGETS assimp DESTINATION ${ASSIMP_LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT})
  46.711 +INSTALL( FILES ${PUBLIC_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp COMPONENT assimp-dev)
  46.712 +INSTALL( FILES ${COMPILER_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp/Compiler COMPONENT assimp-dev)
  46.713 +
  46.714 +if(MSVC AND ASSIMP_INSTALL_PDB)
  46.715 +	install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${ASSIMP_DEBUG_POSTFIX}.pdb
  46.716 +		DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
  46.717 +		CONFIGURATIONS Debug
  46.718 +	)
  46.719 +	install(FILES ${Assimp_BINARY_DIR}/code/RelWithDebInfo/assimp.pdb
  46.720 +		DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
  46.721 +		CONFIGURATIONS RelWithDebInfo
  46.722 +	)
  46.723 +endif ()
  46.724 \ No newline at end of file
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/libs/assimp/COBLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
    47.3 @@ -0,0 +1,1291 @@
    47.4 +/*
    47.5 +Open Asset Import Library (assimp)
    47.6 +----------------------------------------------------------------------
    47.7 +
    47.8 +Copyright (c) 2006-2012, assimp team
    47.9 +All rights reserved.
   47.10 +
   47.11 +Redistribution and use of this software in source and binary forms, 
   47.12 +with or without modification, are permitted provided that the 
   47.13 +following conditions are met:
   47.14 +
   47.15 +* Redistributions of source code must retain the above
   47.16 +  copyright notice, this list of conditions and the
   47.17 +  following disclaimer.
   47.18 +
   47.19 +* Redistributions in binary form must reproduce the above
   47.20 +  copyright notice, this list of conditions and the
   47.21 +  following disclaimer in the documentation and/or other
   47.22 +  materials provided with the distribution.
   47.23 +
   47.24 +* Neither the name of the assimp team, nor the names of its
   47.25 +  contributors may be used to endorse or promote products
   47.26 +  derived from this software without specific prior
   47.27 +  written permission of the assimp team.
   47.28 +
   47.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   47.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   47.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   47.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   47.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   47.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   47.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   47.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   47.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   47.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   47.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   47.40 +
   47.41 +----------------------------------------------------------------------
   47.42 +*/
   47.43 +
   47.44 +/** @file  COBLoader.cpp
   47.45 + *  @brief Implementation of the TrueSpace COB/SCN importer class.
   47.46 + */
   47.47 +#include "AssimpPCH.h"
   47.48 +
   47.49 +#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
   47.50 +#include "COBLoader.h"
   47.51 +#include "COBScene.h"
   47.52 +
   47.53 +#include "StreamReader.h"
   47.54 +#include "ParsingUtils.h"
   47.55 +#include "fast_atof.h"
   47.56 +
   47.57 +#include "LineSplitter.h"
   47.58 +#include "TinyFormatter.h"
   47.59 +
   47.60 +using namespace Assimp;
   47.61 +using namespace Assimp::COB;
   47.62 +using namespace Assimp::Formatter;
   47.63 +
   47.64 +#define for_each BOOST_FOREACH
   47.65 +
   47.66 +
   47.67 +static const float units[] = {
   47.68 +	1000.f,
   47.69 +	100.f,
   47.70 +	1.f,
   47.71 +	0.001f,
   47.72 +	1.f/0.0254f,
   47.73 +	1.f/0.3048f,
   47.74 +	1.f/0.9144f,
   47.75 +	1.f/1609.344f
   47.76 +};	
   47.77 +
   47.78 +static const aiImporterDesc desc = {
   47.79 +	"TrueSpace Object Importer",
   47.80 +	"",
   47.81 +	"",
   47.82 +	"little-endian files only",
   47.83 +	aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour,
   47.84 +	0,
   47.85 +	0,
   47.86 +	0,
   47.87 +	0,
   47.88 +	"cob scn"
   47.89 +};
   47.90 +
   47.91 +
   47.92 +// ------------------------------------------------------------------------------------------------
   47.93 +// Constructor to be privately used by Importer
   47.94 +COBImporter::COBImporter()
   47.95 +{}
   47.96 +
   47.97 +// ------------------------------------------------------------------------------------------------
   47.98 +// Destructor, private as well 
   47.99 +COBImporter::~COBImporter()
  47.100 +{}
  47.101 +
  47.102 +// ------------------------------------------------------------------------------------------------
  47.103 +// Returns whether the class can handle the format of the given file. 
  47.104 +bool COBImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  47.105 +{
  47.106 +	const std::string& extension = GetExtension(pFile);
  47.107 +	if (extension == "cob" || extension == "scn") {
  47.108 +		return true;
  47.109 +	}
  47.110 +
  47.111 +	else if ((!extension.length() || checkSig) && pIOHandler)	{
  47.112 +		const char* tokens[] = {"Caligary"};
  47.113 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
  47.114 +	}
  47.115 +	return false;
  47.116 +}
  47.117 +
  47.118 +// ------------------------------------------------------------------------------------------------
  47.119 +// Loader meta information
  47.120 +const aiImporterDesc* COBImporter::GetInfo () const
  47.121 +{
  47.122 +	return &desc;
  47.123 +}
  47.124 +
  47.125 +// ------------------------------------------------------------------------------------------------
  47.126 +// Setup configuration properties for the loader
  47.127 +void COBImporter::SetupProperties(const Importer* /*pImp*/)
  47.128 +{
  47.129 +	// nothing to be done for the moment
  47.130 +}
  47.131 +
  47.132 +// ------------------------------------------------------------------------------------------------
  47.133 +/*static*/ void COBImporter::ThrowException(const std::string& msg)
  47.134 +{
  47.135 +	throw DeadlyImportError("COB: "+msg);
  47.136 +}
  47.137 +
  47.138 +// ------------------------------------------------------------------------------------------------
  47.139 +// Imports the given file into the given scene structure. 
  47.140 +void COBImporter::InternReadFile( const std::string& pFile, 
  47.141 +	aiScene* pScene, IOSystem* pIOHandler)
  47.142 +{
  47.143 +	COB::Scene scene;
  47.144 +	boost::scoped_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) );
  47.145 +
  47.146 +	// check header
  47.147 +	char head[32];
  47.148 +	stream->CopyAndAdvance(head,32);
  47.149 +	if (strncmp(head,"Caligari ",9)) {
  47.150 +		ThrowException("Could not found magic id: `Caligari`");
  47.151 +	}
  47.152 +
  47.153 +	DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
  47.154 +	void (COBImporter::* load)(Scene&,StreamReaderLE*)= head[15]=='A'?&COBImporter::ReadAsciiFile:&COBImporter::ReadBinaryFile;
  47.155 +	if (head[16]!='L') {
  47.156 +		ThrowException("File is big-endian, which is not supported");
  47.157 +	}
  47.158 +	
  47.159 +	// load data into intermediate structures
  47.160 +	(this->*load)(scene,stream.get());
  47.161 +	if(scene.nodes.empty()) {
  47.162 +		ThrowException("No nodes loaded");
  47.163 +	}
  47.164 +
  47.165 +	// sort faces by material indices
  47.166 +	for_each(boost::shared_ptr< Node >& n,scene.nodes) {
  47.167 +		if (n->type == Node::TYPE_MESH) {
  47.168 +			Mesh& mesh = (Mesh&)(*n.get());
  47.169 +			for_each(Face& f,mesh.faces) {
  47.170 +				mesh.temp_map[f.material].push_back(&f);
  47.171 +			}
  47.172 +		} 
  47.173 +	}
  47.174 +
  47.175 +	// count meshes
  47.176 +	for_each(boost::shared_ptr< Node >& n,scene.nodes) {
  47.177 +		if (n->type == Node::TYPE_MESH) {
  47.178 +			Mesh& mesh = (Mesh&)(*n.get());
  47.179 +			if (mesh.vertex_positions.size() && mesh.texture_coords.size()) {
  47.180 +				pScene->mNumMeshes += mesh.temp_map.size();
  47.181 +			}
  47.182 +		} 
  47.183 +	}
  47.184 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
  47.185 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes]();
  47.186 +	pScene->mNumMeshes = 0;
  47.187 +
  47.188 +	// count lights and cameras
  47.189 +	for_each(boost::shared_ptr< Node >& n,scene.nodes) {
  47.190 +		if (n->type == Node::TYPE_LIGHT) {
  47.191 +			++pScene->mNumLights;
  47.192 +		}
  47.193 +		else if (n->type == Node::TYPE_CAMERA) {
  47.194 +			++pScene->mNumCameras;
  47.195 +		}
  47.196 +	}
  47.197 +
  47.198 +	if (pScene->mNumLights) {
  47.199 +		pScene->mLights  = new aiLight*[pScene->mNumLights]();
  47.200 +	}
  47.201 +	if (pScene->mNumCameras) {
  47.202 +		pScene->mCameras = new aiCamera*[pScene->mNumCameras]();
  47.203 +	}
  47.204 +	pScene->mNumLights = pScene->mNumCameras = 0;
  47.205 +
  47.206 +	// resolve parents by their IDs and build the output graph
  47.207 +	boost::scoped_ptr<Node> root(new Group());
  47.208 +	for(size_t n = 0; n < scene.nodes.size(); ++n) {
  47.209 +		const Node& nn = *scene.nodes[n].get();
  47.210 +		if(nn.parent_id==0) {
  47.211 +			root->temp_children.push_back(&nn);
  47.212 +		}
  47.213 +
  47.214 +		for(size_t m = n; m < scene.nodes.size(); ++m) {
  47.215 +			const Node& mm = *scene.nodes[m].get();
  47.216 +			if (mm.parent_id == nn.id) {
  47.217 +				nn.temp_children.push_back(&mm);
  47.218 +			}
  47.219 +		}
  47.220 +	}
  47.221 +
  47.222 +	pScene->mRootNode = BuildNodes(*root.get(),scene,pScene);
  47.223 +}
  47.224 +
  47.225 +// ------------------------------------------------------------------------------------------------
  47.226 +void ConvertTexture(boost::shared_ptr< Texture > tex, aiMaterial* out, aiTextureType type)
  47.227 +{
  47.228 +	const aiString path( tex->path );
  47.229 +	out->AddProperty(&path,AI_MATKEY_TEXTURE(type,0));
  47.230 +	out->AddProperty(&tex->transform,1,AI_MATKEY_UVTRANSFORM(type,0));
  47.231 +}
  47.232 +
  47.233 +// ------------------------------------------------------------------------------------------------
  47.234 +aiNode* COBImporter::BuildNodes(const Node& root,const Scene& scin,aiScene* fill)
  47.235 +{
  47.236 +	aiNode* nd = new aiNode();
  47.237 +	nd->mName.Set(root.name);
  47.238 +	nd->mTransformation = root.transform;
  47.239 +
  47.240 +	// Note to everybody believing Voodoo is appropriate here:
  47.241 +	// I know polymorphism, run as fast as you can ;-)
  47.242 +	if (Node::TYPE_MESH == root.type) {
  47.243 +		const Mesh& ndmesh = (const Mesh&)(root);
  47.244 +		if (ndmesh.vertex_positions.size() && ndmesh.texture_coords.size()) {
  47.245 +
  47.246 +			typedef std::pair<unsigned int,Mesh::FaceRefList> Entry;
  47.247 +			for_each(const Entry& reflist,ndmesh.temp_map) {
  47.248 +				{	// create mesh
  47.249 +					size_t n = 0;
  47.250 +					for_each(Face* f, reflist.second) {
  47.251 +						n += f->indices.size();
  47.252 +					}
  47.253 +					if (!n) {
  47.254 +						continue;
  47.255 +					}
  47.256 +					aiMesh* outmesh = fill->mMeshes[fill->mNumMeshes++] = new aiMesh();
  47.257 +					++nd->mNumMeshes;
  47.258 +
  47.259 +					outmesh->mVertices = new aiVector3D[n];
  47.260 +					outmesh->mTextureCoords[0] = new aiVector3D[n];
  47.261 +
  47.262 +					outmesh->mFaces = new aiFace[reflist.second.size()]();
  47.263 +					for_each(Face* f, reflist.second) {
  47.264 +						if (f->indices.empty()) {
  47.265 +							continue;
  47.266 +						}
  47.267 +
  47.268 +						aiFace& fout = outmesh->mFaces[outmesh->mNumFaces++];
  47.269 +						fout.mIndices = new unsigned int[f->indices.size()];
  47.270 +
  47.271 +						for_each(VertexIndex& v, f->indices) {
  47.272 +							if (v.pos_idx >= ndmesh.vertex_positions.size()) {
  47.273 +								ThrowException("Position index out of range");
  47.274 +							}
  47.275 +							if (v.uv_idx >= ndmesh.texture_coords.size()) {
  47.276 +								ThrowException("UV index out of range");
  47.277 +							}
  47.278 +							outmesh->mVertices[outmesh->mNumVertices] = ndmesh.vertex_positions[ v.pos_idx ]; 
  47.279 +							outmesh->mTextureCoords[0][outmesh->mNumVertices] = aiVector3D( 
  47.280 +								ndmesh.texture_coords[ v.uv_idx ].x,
  47.281 +								ndmesh.texture_coords[ v.uv_idx ].y,
  47.282 +								0.f
  47.283 +							);
  47.284 +
  47.285 +							fout.mIndices[fout.mNumIndices++] = outmesh->mNumVertices++;
  47.286 +						}
  47.287 +					}
  47.288 +					outmesh->mMaterialIndex = fill->mNumMaterials;
  47.289 +				}{	// create material
  47.290 +					const Material* min = NULL;
  47.291 +					for_each(const Material& m, scin.materials) {
  47.292 +						if (m.parent_id == ndmesh.id && m.matnum == reflist.first) {
  47.293 +							min = &m;
  47.294 +							break;
  47.295 +						}
  47.296 +					}
  47.297 +					boost::scoped_ptr<const Material> defmat;
  47.298 +					if(!min) {
  47.299 +						DefaultLogger::get()->debug(format()<<"Could not resolve material index "
  47.300 +							<<reflist.first<<" - creating default material for this slot");
  47.301 +
  47.302 +						defmat.reset(min=new Material());
  47.303 +					}
  47.304 +
  47.305 +					aiMaterial* mat = new aiMaterial();
  47.306 +					fill->mMaterials[fill->mNumMaterials++] = mat;
  47.307 +
  47.308 +					const aiString s(format("#mat_")<<fill->mNumMeshes<<"_"<<min->matnum);
  47.309 +					mat->AddProperty(&s,AI_MATKEY_NAME);
  47.310 +
  47.311 +					if(int tmp = ndmesh.draw_flags & Mesh::WIRED ? 1 : 0) {
  47.312 +						mat->AddProperty(&tmp,1,AI_MATKEY_ENABLE_WIREFRAME);
  47.313 +					}
  47.314 +
  47.315 +					{	int shader;
  47.316 +						switch(min->shader) 
  47.317 +						{
  47.318 +						case Material::FLAT:
  47.319 +							shader = aiShadingMode_Gouraud;
  47.320 +							break;
  47.321 +
  47.322 +						case Material::PHONG:
  47.323 +							shader = aiShadingMode_Phong;
  47.324 +							break;
  47.325 +
  47.326 +						case Material::METAL:
  47.327 +							shader = aiShadingMode_CookTorrance;
  47.328 +							break;
  47.329 +
  47.330 +						default:
  47.331 +							ai_assert(false); // shouldn't be here
  47.332 +						}
  47.333 +						mat->AddProperty(&shader,1,AI_MATKEY_SHADING_MODEL);
  47.334 +						if(shader != aiShadingMode_Gouraud) {
  47.335 +							mat->AddProperty(&min->exp,1,AI_MATKEY_SHININESS);
  47.336 +						}
  47.337 +					}
  47.338 +
  47.339 +					mat->AddProperty(&min->ior,1,AI_MATKEY_REFRACTI);
  47.340 +					mat->AddProperty(&min->rgb,1,AI_MATKEY_COLOR_DIFFUSE);
  47.341 +
  47.342 +					aiColor3D c = aiColor3D(min->rgb)*min->ks;
  47.343 +					mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
  47.344 +
  47.345 +					c = aiColor3D(min->rgb)*min->ka;
  47.346 +					mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT);
  47.347 +
  47.348 +					// convert textures if some exist.
  47.349 +					if(min->tex_color) {
  47.350 +						ConvertTexture(min->tex_color,mat,aiTextureType_DIFFUSE);
  47.351 +					}
  47.352 +					if(min->tex_env) {
  47.353 +						ConvertTexture(min->tex_env  ,mat,aiTextureType_UNKNOWN);
  47.354 +					}
  47.355 +					if(min->tex_bump) {
  47.356 +						ConvertTexture(min->tex_bump ,mat,aiTextureType_HEIGHT);
  47.357 +					}
  47.358 +				}
  47.359 +			}
  47.360 +		}
  47.361 +	}
  47.362 +	else if (Node::TYPE_LIGHT == root.type) {
  47.363 +		const Light& ndlight = (const Light&)(root);
  47.364 +		aiLight* outlight = fill->mLights[fill->mNumLights++] = new aiLight();
  47.365 +		
  47.366 +		outlight->mName.Set(ndlight.name);
  47.367 +		outlight->mColorDiffuse = outlight->mColorAmbient = outlight->mColorSpecular = ndlight.color;
  47.368 +
  47.369 +		outlight->mAngleOuterCone = AI_DEG_TO_RAD(ndlight.angle);
  47.370 +		outlight->mAngleInnerCone = AI_DEG_TO_RAD(ndlight.inner_angle);
  47.371 +
  47.372 +		// XXX
  47.373 +		outlight->mType = ndlight.ltype==Light::SPOT ? aiLightSource_SPOT : aiLightSource_DIRECTIONAL;
  47.374 +	}
  47.375 +	else if (Node::TYPE_CAMERA == root.type) {
  47.376 +		const Camera& ndcam = (const Camera&)(root);
  47.377 +		aiCamera* outcam = fill->mCameras[fill->mNumCameras++] = new aiCamera();
  47.378 +
  47.379 +		outcam->mName.Set(ndcam.name);
  47.380 +	}
  47.381 +
  47.382 +	// add meshes
  47.383 +	if (nd->mNumMeshes) { // mMeshes must be NULL if count is 0
  47.384 +		nd->mMeshes = new unsigned int[nd->mNumMeshes];
  47.385 +		for(unsigned int i = 0; i < nd->mNumMeshes;++i) {
  47.386 +			nd->mMeshes[i] = fill->mNumMeshes-i-1;
  47.387 +		}
  47.388 +	}
  47.389 +
  47.390 +	// add children recursively
  47.391 +	nd->mChildren = new aiNode*[root.temp_children.size()]();
  47.392 +	for_each(const Node* n, root.temp_children) {
  47.393 +		(nd->mChildren[nd->mNumChildren++] = BuildNodes(*n,scin,fill))->mParent = nd;
  47.394 +	}
  47.395 +
  47.396 +	return nd;
  47.397 +}
  47.398 +
  47.399 +// ------------------------------------------------------------------------------------------------
  47.400 +// Read an ASCII file into the given scene data structure
  47.401 +void COBImporter::ReadAsciiFile(Scene& out, StreamReaderLE* stream)
  47.402 +{
  47.403 +	ChunkInfo ci;
  47.404 +	for(LineSplitter splitter(*stream);splitter;++splitter) {
  47.405 +
  47.406 +		// add all chunks to be recognized here. /else ../ omitted intentionally.
  47.407 +		if (splitter.match_start("PolH ")) {
  47.408 +			ReadChunkInfo_Ascii(ci,splitter);
  47.409 +			ReadPolH_Ascii(out,splitter,ci);
  47.410 +		}
  47.411 +		if (splitter.match_start("BitM ")) {
  47.412 +			ReadChunkInfo_Ascii(ci,splitter);
  47.413 +			ReadBitM_Ascii(out,splitter,ci);
  47.414 +		}
  47.415 +		if (splitter.match_start("Mat1 ")) {
  47.416 +			ReadChunkInfo_Ascii(ci,splitter);
  47.417 +			ReadMat1_Ascii(out,splitter,ci);
  47.418 +		}
  47.419 +		if (splitter.match_start("Grou ")) {
  47.420 +			ReadChunkInfo_Ascii(ci,splitter);
  47.421 +			ReadGrou_Ascii(out,splitter,ci);
  47.422 +		}
  47.423 +		if (splitter.match_start("Lght ")) {
  47.424 +			ReadChunkInfo_Ascii(ci,splitter);
  47.425 +			ReadLght_Ascii(out,splitter,ci);
  47.426 +		}
  47.427 +		if (splitter.match_start("Came ")) {
  47.428 +			ReadChunkInfo_Ascii(ci,splitter);
  47.429 +			ReadCame_Ascii(out,splitter,ci);
  47.430 +		}
  47.431 +		if (splitter.match_start("Bone ")) {
  47.432 +			ReadChunkInfo_Ascii(ci,splitter);
  47.433 +			ReadBone_Ascii(out,splitter,ci);
  47.434 +		}
  47.435 +		if (splitter.match_start("Chan ")) {
  47.436 +			ReadChunkInfo_Ascii(ci,splitter);
  47.437 +			ReadChan_Ascii(out,splitter,ci);
  47.438 +		}
  47.439 +		if (splitter.match_start("Unit ")) {
  47.440 +			ReadChunkInfo_Ascii(ci,splitter);
  47.441 +			ReadUnit_Ascii(out,splitter,ci);
  47.442 +		}
  47.443 +		if (splitter.match_start("END ")) {
  47.444 +			// we don't need this, but I guess there is a reason this
  47.445 +			// chunk has been implemented into COB for.
  47.446 +			return;
  47.447 +		}
  47.448 +	}
  47.449 +}
  47.450 +
  47.451 +// ------------------------------------------------------------------------------------------------
  47.452 +void COBImporter::ReadChunkInfo_Ascii(ChunkInfo& out, const LineSplitter& splitter)
  47.453 +{
  47.454 +	const char* all_tokens[8];
  47.455 +	splitter.get_tokens(all_tokens);
  47.456 +
  47.457 +	out.version = (all_tokens[1][1]-'0')*100+(all_tokens[1][3]-'0')*10+(all_tokens[1][4]-'0');
  47.458 +	out.id	= strtoul10(all_tokens[3]);
  47.459 +	out.parent_id = strtoul10(all_tokens[5]);
  47.460 +	out.size = strtol10(all_tokens[7]);
  47.461 +}
  47.462 +
  47.463 +// ------------------------------------------------------------------------------------------------
  47.464 +void COBImporter::UnsupportedChunk_Ascii(LineSplitter& splitter, const ChunkInfo& nfo, const char* name)
  47.465 +{
  47.466 +	const std::string error = format("Encountered unsupported chunk: ") <<  name <<
  47.467 +		" [version: "<<nfo.version<<", size: "<<nfo.size<<"]";
  47.468 +
  47.469 +	// we can recover if the chunk size was specified.
  47.470 +	if(nfo.size != static_cast<unsigned int>(-1)) {
  47.471 +		DefaultLogger::get()->error(error);
  47.472 +
  47.473 +		// (HACK) - our current position in the stream is the beginning of the
  47.474 +		// head line of the next chunk. That's fine, but the caller is going
  47.475 +		// to call ++ on `splitter`, which we need to swallow to avoid 
  47.476 +		// missing the next line.
  47.477 +		splitter.get_stream().IncPtr(nfo.size);
  47.478 +		splitter.swallow_next_increment();
  47.479 +	}
  47.480 +	else ThrowException(error);
  47.481 +}
  47.482 +
  47.483 +// ------------------------------------------------------------------------------------------------
  47.484 +void COBImporter::LogWarn_Ascii(const LineSplitter& splitter, const format& message)	{
  47.485 +	LogWarn_Ascii(message << " [at line "<< splitter.get_index()<<"]");
  47.486 +}
  47.487 +
  47.488 +// ------------------------------------------------------------------------------------------------
  47.489 +void COBImporter::LogError_Ascii(const LineSplitter& splitter, const format& message)	{
  47.490 +	LogError_Ascii(message << " [at line "<< splitter.get_index()<<"]");
  47.491 +}
  47.492 +
  47.493 +// ------------------------------------------------------------------------------------------------
  47.494 +void COBImporter::LogInfo_Ascii(const LineSplitter& splitter, const format& message)	{
  47.495 +	LogInfo_Ascii(message << " [at line "<< splitter.get_index()<<"]");
  47.496 +}
  47.497 +
  47.498 +// ------------------------------------------------------------------------------------------------
  47.499 +void COBImporter::LogDebug_Ascii(const LineSplitter& splitter, const format& message)	{
  47.500 +	LogDebug_Ascii(message << " [at line "<< splitter.get_index()<<"]");
  47.501 +}
  47.502 +
  47.503 +// ------------------------------------------------------------------------------------------------
  47.504 +void COBImporter::LogWarn_Ascii(const Formatter::format& message)	{
  47.505 +	DefaultLogger::get()->warn(std::string("COB: ")+=message);
  47.506 +}
  47.507 +
  47.508 +// ------------------------------------------------------------------------------------------------
  47.509 +void COBImporter::LogError_Ascii(const Formatter::format& message)	{
  47.510 +	DefaultLogger::get()->error(std::string("COB: ")+=message);
  47.511 +}
  47.512 +
  47.513 +// ------------------------------------------------------------------------------------------------
  47.514 +void COBImporter::LogInfo_Ascii(const Formatter::format& message)	{
  47.515 +	DefaultLogger::get()->info(std::string("COB: ")+=message);
  47.516 +}
  47.517 +
  47.518 +// ------------------------------------------------------------------------------------------------
  47.519 +void COBImporter::LogDebug_Ascii(const Formatter::format& message)	{
  47.520 +	DefaultLogger::get()->debug(std::string("COB: ")+=message);
  47.521 +}
  47.522 +
  47.523 +// ------------------------------------------------------------------------------------------------
  47.524 +void COBImporter::ReadBasicNodeInfo_Ascii(Node& msh, LineSplitter& splitter, const ChunkInfo& /*nfo*/)
  47.525 +{
  47.526 +	for(;splitter;++splitter) {
  47.527 +		if (splitter.match_start("Name")) {
  47.528 +			msh.name = std::string(splitter[1]);
  47.529 +
  47.530 +			// make nice names by merging the dupe count
  47.531 +			std::replace(msh.name.begin(),msh.name.end(),
  47.532 +				',','_');
  47.533 +		}
  47.534 +		else if (splitter.match_start("Transform")) {
  47.535 +			for(unsigned int y = 0; y < 4 && ++splitter; ++y) {
  47.536 +				const char* s = splitter->c_str();
  47.537 +				for(unsigned int x = 0; x < 4; ++x) {
  47.538 +					SkipSpaces(&s);
  47.539 +					msh.transform[y][x] = fast_atof(&s);
  47.540 +				}
  47.541 +			}
  47.542 +			// we need the transform chunk, so we won't return until we have it.
  47.543 +			return;
  47.544 +		}
  47.545 +	}
  47.546 +}
  47.547 +
  47.548 +// ------------------------------------------------------------------------------------------------
  47.549 +template <typename T>
  47.550 +void COBImporter::ReadFloat3Tuple_Ascii(T& fill, const char** in) 
  47.551 +{
  47.552 +	const char* rgb = *in;
  47.553 +	for(unsigned int i = 0; i < 3; ++i) {
  47.554 +		SkipSpaces(&rgb);
  47.555 +		if (*rgb == ',')++rgb;
  47.556 +		SkipSpaces(&rgb);
  47.557 +		
  47.558 +		fill[i] = fast_atof(&rgb);
  47.559 +	}
  47.560 +	*in = rgb;
  47.561 +}
  47.562 +
  47.563 +// ------------------------------------------------------------------------------------------------
  47.564 +void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
  47.565 +{
  47.566 +	if(nfo.version > 8) {
  47.567 +		return UnsupportedChunk_Ascii(splitter,nfo,"Mat1");
  47.568 +	}
  47.569 +
  47.570 +	++splitter;
  47.571 +	if (!splitter.match_start("mat# ")) {
  47.572 +		LogWarn_Ascii(splitter,format()<<
  47.573 +			"Expected `mat#` line in `Mat1` chunk "<<nfo.id);
  47.574 +		return;
  47.575 +	}
  47.576 +
  47.577 +	out.materials.push_back(Material());
  47.578 +	Material& mat = out.materials.back();
  47.579 +	mat = nfo;
  47.580 +
  47.581 +	mat.matnum = strtoul10(splitter[1]);
  47.582 +	++splitter;
  47.583 +
  47.584 +	if (!splitter.match_start("shader: ")) {
  47.585 +		LogWarn_Ascii(splitter,format()<<
  47.586 +			"Expected `mat#` line in `Mat1` chunk "<<nfo.id);
  47.587 +		return;
  47.588 +	}
  47.589 +	std::string shader = std::string(splitter[1]);
  47.590 +	shader = shader.substr(0,shader.find_first_of(" \t"));
  47.591 +
  47.592 +	if (shader == "metal") {
  47.593 +		mat.shader = Material::METAL;
  47.594 +	}
  47.595 +	else if (shader == "phong") {
  47.596 +		mat.shader = Material::PHONG;
  47.597 +	}
  47.598 +	else if (shader != "flat") {
  47.599 +		LogWarn_Ascii(splitter,format()<<
  47.600 +			"Unknown value for `shader` in `Mat1` chunk "<<nfo.id);
  47.601 +	}
  47.602 +
  47.603 +	++splitter;
  47.604 +	if (!splitter.match_start("rgb ")) {
  47.605 +		LogWarn_Ascii(splitter,format()<<
  47.606 +			"Expected `rgb` line in `Mat1` chunk "<<nfo.id);
  47.607 +	}
  47.608 +
  47.609 +	const char* rgb = splitter[1];
  47.610 +	ReadFloat3Tuple_Ascii(mat.rgb,&rgb);
  47.611 +
  47.612 +	++splitter;
  47.613 +	if (!splitter.match_start("alpha ")) {
  47.614 +		LogWarn_Ascii(splitter,format()<<
  47.615 +			"Expected `alpha` line in `Mat1` chunk "<<nfo.id);
  47.616 +	}
  47.617 +
  47.618 +	const char* tokens[10];
  47.619 +	splitter.get_tokens(tokens);
  47.620 +
  47.621 +	mat.alpha	= fast_atof( tokens[1] );
  47.622 +	mat.ka		= fast_atof( tokens[3] );
  47.623 +	mat.ks		= fast_atof( tokens[5] );
  47.624 +	mat.exp		= fast_atof( tokens[7] );
  47.625 +	mat.ior		= fast_atof( tokens[9] );
  47.626 +}
  47.627 +
  47.628 +// ------------------------------------------------------------------------------------------------
  47.629 +void COBImporter::ReadUnit_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
  47.630 +{
  47.631 +	if(nfo.version > 1) {
  47.632 +		return UnsupportedChunk_Ascii(splitter,nfo,"Unit");
  47.633 +	}
  47.634 +	++splitter;
  47.635 +	if (!splitter.match_start("Units ")) {
  47.636 +		LogWarn_Ascii(splitter,format()<<
  47.637 +			"Expected `Units` line in `Unit` chunk "<<nfo.id);
  47.638 +		return;
  47.639 +	}
  47.640 +
  47.641 +	// parent chunks preceede their childs, so we should have the
  47.642 +	// corresponding chunk already.
  47.643 +	for_each(boost::shared_ptr< Node >& nd, out.nodes) {
  47.644 +		if (nd->id == nfo.parent_id) {
  47.645 +			const unsigned int t=strtoul10(splitter[1]);
  47.646 +		
  47.647 +			nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
  47.648 +				LogWarn_Ascii(splitter,format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
  47.649 +				,1.f):units[t];
  47.650 +			return;
  47.651 +		}
  47.652 +	}
  47.653 +	LogWarn_Ascii(splitter,format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
  47.654 +		<<nfo.parent_id<<" which does not exist");
  47.655 +}
  47.656 +
  47.657 +// ------------------------------------------------------------------------------------------------
  47.658 +void COBImporter::ReadChan_Ascii(Scene& /*out*/, LineSplitter& splitter, const ChunkInfo& nfo)
  47.659 +{
  47.660 +	if(nfo.version > 8) {
  47.661 +		return UnsupportedChunk_Ascii(splitter,nfo,"Chan");
  47.662 +	}
  47.663 +}
  47.664 +
  47.665 +// ------------------------------------------------------------------------------------------------
  47.666 +void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
  47.667 +{
  47.668 +	if(nfo.version > 8) {
  47.669 +		return UnsupportedChunk_Ascii(splitter,nfo,"Lght");
  47.670 +	}
  47.671 +
  47.672 +	out.nodes.push_back(boost::shared_ptr<Light>(new Light()));
  47.673 +	Light& msh = (Light&)(*out.nodes.back().get());
  47.674 +	msh = nfo;
  47.675 +
  47.676 +	ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
  47.677 +
  47.678 +	if (splitter.match_start("Infinite ")) {
  47.679 +		msh.ltype = Light::INFINITE;
  47.680 +	}
  47.681 +	else if (splitter.match_start("Local ")) {
  47.682 +		msh.ltype = Light::LOCAL;
  47.683 +	}
  47.684 +	else if (splitter.match_start("Spot ")) {
  47.685 +		msh.ltype = Light::SPOT;
  47.686 +	}
  47.687 +	else {
  47.688 +		LogWarn_Ascii(splitter,format()<<
  47.689 +			"Unknown kind of light source in `Lght` chunk "<<nfo.id<<" : "<<*splitter);
  47.690 +		msh.ltype = Light::SPOT;
  47.691 +	}
  47.692 +	
  47.693 +	++splitter;
  47.694 +	if (!splitter.match_start("color ")) {
  47.695 +		LogWarn_Ascii(splitter,format()<<
  47.696 +			"Expected `color` line in `Lght` chunk "<<nfo.id);
  47.697 +	}
  47.698 +
  47.699 +	const char* rgb = splitter[1];
  47.700 +	ReadFloat3Tuple_Ascii(msh.color ,&rgb);
  47.701 +
  47.702 +	SkipSpaces(&rgb);
  47.703 +	if (strncmp(rgb,"cone angle",10)) {
  47.704 +		LogWarn_Ascii(splitter,format()<<
  47.705 +			"Expected `cone angle` entity in `color` line in `Lght` chunk "<<nfo.id);
  47.706 +	}
  47.707 +	SkipSpaces(rgb+10,&rgb);
  47.708 +	msh.angle = fast_atof(&rgb);
  47.709 +
  47.710 +	SkipSpaces(&rgb);
  47.711 +	if (strncmp(rgb,"inner angle",11)) {
  47.712 +		LogWarn_Ascii(splitter,format()<<
  47.713 +			"Expected `inner angle` entity in `color` line in `Lght` chunk "<<nfo.id);
  47.714 +	}
  47.715 +	SkipSpaces(rgb+11,&rgb);
  47.716 +	msh.inner_angle = fast_atof(&rgb);
  47.717 +
  47.718 +	// skip the rest for we can't handle this kind of physically-based lighting information.
  47.719 +}
  47.720 +
  47.721 +// ------------------------------------------------------------------------------------------------
  47.722 +void COBImporter::ReadCame_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
  47.723 +{
  47.724 +	if(nfo.version > 2) {
  47.725 +		return UnsupportedChunk_Ascii(splitter,nfo,"Came");
  47.726 +	}
  47.727 +
  47.728 +	out.nodes.push_back(boost::shared_ptr<Camera>(new Camera()));
  47.729 +	Camera& msh = (Camera&)(*out.nodes.back().get());
  47.730 +	msh = nfo;
  47.731 +
  47.732 +	ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
  47.733 +
  47.734 +	// skip the next line, we don't know this differenciation between a
  47.735 +	// standard camera and a panoramic camera.
  47.736 +	++splitter;
  47.737 +}
  47.738 +
  47.739 +// ------------------------------------------------------------------------------------------------
  47.740 +void COBImporter::ReadBone_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
  47.741 +{
  47.742 +	if(nfo.version > 5) {
  47.743 +		return UnsupportedChunk_Ascii(splitter,nfo,"Bone");
  47.744 +	}
  47.745 +
  47.746 +	out.nodes.push_back(boost::shared_ptr<Bone>(new Bone()));
  47.747 +	Bone& msh = (Bone&)(*out.nodes.back().get());
  47.748 +	msh = nfo;
  47.749 +
  47.750 +	ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
  47.751 +
  47.752 +	// TODO
  47.753 +}
  47.754 +
  47.755 +// ------------------------------------------------------------------------------------------------
  47.756 +void COBImporter::ReadGrou_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
  47.757 +{
  47.758 +	if(nfo.version > 1) {
  47.759 +		return UnsupportedChunk_Ascii(splitter,nfo,"Grou");
  47.760 +	}
  47.761 +
  47.762 +	out.nodes.push_back(boost::shared_ptr<Group>(new Group()));
  47.763 +	Group& msh = (Group&)(*out.nodes.back().get());
  47.764 +	msh = nfo;
  47.765 +
  47.766 +	ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
  47.767 +}
  47.768 +
  47.769 +// ------------------------------------------------------------------------------------------------
  47.770 +void COBImporter::ReadPolH_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
  47.771 +{
  47.772 +	if(nfo.version > 8) {
  47.773 +		return UnsupportedChunk_Ascii(splitter,nfo,"PolH");
  47.774 +	}
  47.775 +
  47.776 +	out.nodes.push_back(boost::shared_ptr<Mesh>(new Mesh()));
  47.777 +	Mesh& msh = (Mesh&)(*out.nodes.back().get());
  47.778 +	msh = nfo;
  47.779 +
  47.780 +	ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
  47.781 +
  47.782 +	// the chunk has a fixed order of components, but some are not interesting of us so
  47.783 +	// we're just looking for keywords in arbitrary order. The end of the chunk is
  47.784 +	// either the last `Face` or the `DrawFlags` attribute, depending on the format ver.
  47.785 +	for(;splitter;++splitter) {
  47.786 +		if (splitter.match_start("World Vertices")) {
  47.787 +			const unsigned int cnt = strtoul10(splitter[2]);
  47.788 +			msh.vertex_positions.resize(cnt);
  47.789 +
  47.790 +			for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
  47.791 +				const char* s = splitter->c_str();
  47.792 +
  47.793 +				aiVector3D& v = msh.vertex_positions[cur]; 
  47.794 +
  47.795 +				SkipSpaces(&s);
  47.796 +				v.x = fast_atof(&s);
  47.797 +				SkipSpaces(&s);
  47.798 +				v.y = fast_atof(&s);
  47.799 +				SkipSpaces(&s);
  47.800 +				v.z = fast_atof(&s);
  47.801 +			}
  47.802 +		}
  47.803 +		else if (splitter.match_start("Texture Vertices")) {
  47.804 +			const unsigned int cnt = strtoul10(splitter[2]);
  47.805 +			msh.texture_coords.resize(cnt);
  47.806 +
  47.807 +			for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
  47.808 +				const char* s = splitter->c_str();
  47.809 +
  47.810 +				aiVector2D& v = msh.texture_coords[cur]; 
  47.811 +
  47.812 +				SkipSpaces(&s);
  47.813 +				v.x = fast_atof(&s);
  47.814 +				SkipSpaces(&s);
  47.815 +				v.y = fast_atof(&s);
  47.816 +			}
  47.817 +		}
  47.818 +		else if (splitter.match_start("Faces")) {
  47.819 +			const unsigned int cnt = strtoul10(splitter[1]);
  47.820 +			msh.faces.reserve(cnt);
  47.821 +
  47.822 +			for(unsigned int cur = 0; cur < cnt && ++splitter ;++cur) {
  47.823 +				if (splitter.match_start("Hole")) {
  47.824 +					LogWarn_Ascii(splitter,"Skipping unsupported `Hole` line");
  47.825 +					continue;
  47.826 +				}
  47.827 +
  47.828 +				if (!splitter.match_start("Face")) {
  47.829 +					ThrowException("Expected Face line");
  47.830 +				}
  47.831 +
  47.832 +				msh.faces.push_back(Face());
  47.833 +				Face& face = msh.faces.back();
  47.834 +
  47.835 +				face.indices.resize(strtoul10(splitter[2]));
  47.836 +				face.flags = strtoul10(splitter[4]);
  47.837 +				face.material = strtoul10(splitter[6]);
  47.838 +
  47.839 +				const char* s = (++splitter)->c_str();
  47.840 +				for(size_t i = 0; i < face.indices.size(); ++i) {
  47.841 +					if(!SkipSpaces(&s)) {
  47.842 +						ThrowException("Expected EOL token in Face entry");
  47.843 +					}
  47.844 +					if ('<' != *s++) {
  47.845 +						ThrowException("Expected < token in Face entry");
  47.846 +					}
  47.847 +					face.indices[i].pos_idx = strtoul10(s,&s);
  47.848 +					if (',' != *s++) {
  47.849 +						ThrowException("Expected , token in Face entry");
  47.850 +					}
  47.851 +					face.indices[i].uv_idx = strtoul10(s,&s);
  47.852 +					if ('>' != *s++) {
  47.853 +						ThrowException("Expected < token in Face entry");
  47.854 +					}
  47.855 +				}
  47.856 +			}
  47.857 +			if (nfo.version <= 4) {
  47.858 +				break;
  47.859 +			}
  47.860 +		}
  47.861 +		else if (splitter.match_start("DrawFlags")) {
  47.862 +			msh.draw_flags = strtoul10(splitter[1]);
  47.863 +			break;
  47.864 +		}
  47.865 +	}
  47.866 +}
  47.867 +
  47.868 +// ------------------------------------------------------------------------------------------------
  47.869 +void COBImporter::ReadBitM_Ascii(Scene& /*out*/, LineSplitter& splitter, const ChunkInfo& nfo)
  47.870 +{
  47.871 +	if(nfo.version > 1) {
  47.872 +		return UnsupportedChunk_Ascii(splitter,nfo,"BitM");
  47.873 +	}
  47.874 +/*
  47.875 +	"\nThumbNailHdrSize %ld"
  47.876 +	"\nThumbHeader: %02hx 02hx %02hx "
  47.877 +	"\nColorBufSize %ld"		
  47.878 +	"\nColorBufZipSize %ld"		
  47.879 +	"\nZippedThumbnail: %02hx 02hx %02hx "
  47.880 +*/
  47.881 +
  47.882 +	const unsigned int head = strtoul10((++splitter)[1]);
  47.883 +	if (head != sizeof(Bitmap::BitmapHeader)) {
  47.884 +		LogWarn_Ascii(splitter,"Unexpected ThumbNailHdrSize, skipping this chunk");
  47.885 +		return;
  47.886 +	}
  47.887 +
  47.888 +	/*union {
  47.889 +		Bitmap::BitmapHeader data;
  47.890 +		char opaq[sizeof Bitmap::BitmapHeader()];
  47.891 +	};*/
  47.892 +//	ReadHexOctets(opaq,head,(++splitter)[1]);
  47.893 +}
  47.894 +
  47.895 +// ------------------------------------------------------------------------------------------------
  47.896 +void COBImporter::ReadString_Binary(std::string& out, StreamReaderLE& reader)
  47.897 +{
  47.898 +	out.resize( reader.GetI2());
  47.899 +	for_each(char& c,out) {
  47.900 +		c = reader.GetI1();
  47.901 +	}
  47.902 +}
  47.903 +
  47.904 +// ------------------------------------------------------------------------------------------------
  47.905 +void COBImporter::ReadBasicNodeInfo_Binary(Node& msh, StreamReaderLE& reader, const ChunkInfo& /*nfo*/)
  47.906 +{
  47.907 +	const unsigned int dupes = reader.GetI2();
  47.908 +	ReadString_Binary(msh.name,reader);
  47.909 +
  47.910 +	msh.name = format(msh.name)<<'_'<<dupes;
  47.911 +
  47.912 +	// skip local axes for the moment
  47.913 +	reader.IncPtr(48);
  47.914 +
  47.915 +	msh.transform = aiMatrix4x4();
  47.916 +	for(unsigned int y = 0; y < 3; ++y) {
  47.917 +		for(unsigned int x =0; x < 4; ++x) {
  47.918 +			msh.transform[y][x] = reader.GetF4();
  47.919 +		}
  47.920 +	}
  47.921 +}
  47.922 +
  47.923 +// ------------------------------------------------------------------------------------------------
  47.924 +void COBImporter::UnsupportedChunk_Binary( StreamReaderLE& reader, const ChunkInfo& nfo, const char* name)
  47.925 +{
  47.926 +	const std::string error = format("Encountered unsupported chunk: ") <<  name <<
  47.927 +		" [version: "<<nfo.version<<", size: "<<nfo.size<<"]";
  47.928 +
  47.929 +	// we can recover if the chunk size was specified.
  47.930 +	if(nfo.size != static_cast<unsigned int>(-1)) {
  47.931 +		DefaultLogger::get()->error(error);
  47.932 +		reader.IncPtr(nfo.size);
  47.933 +	}
  47.934 +	else ThrowException(error);
  47.935 +}
  47.936 +
  47.937 +// ------------------------------------------------------------------------------------------------
  47.938 +// tiny utility guard to aid me at staying within chunk boundaries.
  47.939 +class chunk_guard {
  47.940 +
  47.941 +public:
  47.942 +
  47.943 +	chunk_guard(const COB::ChunkInfo& nfo, StreamReaderLE& reader)
  47.944 +		: nfo(nfo)
  47.945 +		, reader(reader)
  47.946 +		, cur(reader.GetCurrentPos())
  47.947 +	{
  47.948 +	}
  47.949 +
  47.950 +	~chunk_guard() {
  47.951 +		// don't do anything if the size is not given
  47.952 +		if(nfo.size != static_cast<unsigned int>(-1)) {
  47.953 +			reader.IncPtr(static_cast<int>(nfo.size)-reader.GetCurrentPos()+cur);
  47.954 +		}
  47.955 +	}
  47.956 +
  47.957 +private:
  47.958 +
  47.959 +	const COB::ChunkInfo& nfo;
  47.960 +	StreamReaderLE& reader;
  47.961 +	long cur;
  47.962 +};
  47.963 +
  47.964 +// ------------------------------------------------------------------------------------------------
  47.965 +void COBImporter::ReadBinaryFile(Scene& out, StreamReaderLE* reader)
  47.966 +{
  47.967 +	while(1) {
  47.968 +		std::string type;
  47.969 +		 type += reader -> GetI1()
  47.970 +		,type += reader -> GetI1()
  47.971 +		,type += reader -> GetI1()
  47.972 +		,type += reader -> GetI1()
  47.973 +		;
  47.974 +
  47.975 +		ChunkInfo nfo;
  47.976 +		nfo.version  = reader -> GetI2()*10;
  47.977 +		nfo.version += reader -> GetI2();
  47.978 +
  47.979 +		nfo.id = reader->GetI4();
  47.980 +		nfo.parent_id = reader->GetI4();
  47.981 +		nfo.size = reader->GetI4();
  47.982 +
  47.983 +		if (type == "PolH") {
  47.984 +			ReadPolH_Binary(out,*reader,nfo);
  47.985 +		}
  47.986 +		else if (type == "BitM") {
  47.987 +			ReadBitM_Binary(out,*reader,nfo);
  47.988 +		}
  47.989 +		else if (type == "Grou") {
  47.990 +			ReadGrou_Binary(out,*reader,nfo);
  47.991 +		}
  47.992 +		else if (type == "Lght") {
  47.993 +			ReadLght_Binary(out,*reader,nfo);
  47.994 +		}
  47.995 +		else if (type == "Came") {
  47.996 +			ReadCame_Binary(out,*reader,nfo);
  47.997 +		}
  47.998 +		else if (type == "Mat1") {
  47.999 +			ReadMat1_Binary(out,*reader,nfo);
 47.1000 +		}
 47.1001 +	/*	else if (type == "Bone") {
 47.1002 +			ReadBone_Binary(out,*reader,nfo);
 47.1003 +		}
 47.1004 +		else if (type == "Chan") {
 47.1005 +			ReadChan_Binary(out,*reader,nfo);
 47.1006 +		}*/
 47.1007 +		else if (type == "Unit") {
 47.1008 +			ReadUnit_Binary(out,*reader,nfo);
 47.1009 +		}
 47.1010 +		else if (type == "OLay") {
 47.1011 +			// ignore layer index silently.
 47.1012 +			if(nfo.size != static_cast<unsigned int>(-1) ) {
 47.1013 +				reader->IncPtr(nfo.size);
 47.1014 +			}
 47.1015 +			else return UnsupportedChunk_Binary(*reader,nfo,type.c_str());
 47.1016 +		}
 47.1017 +		else if (type == "END ") {
 47.1018 +			return;
 47.1019 +		}
 47.1020 +		else UnsupportedChunk_Binary(*reader,nfo,type.c_str());
 47.1021 +	}
 47.1022 +}
 47.1023 +
 47.1024 +// ------------------------------------------------------------------------------------------------
 47.1025 +void COBImporter::ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
 47.1026 +{
 47.1027 +	if(nfo.version > 8) {
 47.1028 +		return UnsupportedChunk_Binary(reader,nfo,"PolH");
 47.1029 +	}
 47.1030 +	const chunk_guard cn(nfo,reader);
 47.1031 +
 47.1032 +	out.nodes.push_back(boost::shared_ptr<Mesh>(new Mesh()));
 47.1033 +	Mesh& msh = (Mesh&)(*out.nodes.back().get());
 47.1034 +	msh = nfo;
 47.1035 +
 47.1036 +	ReadBasicNodeInfo_Binary(msh,reader,nfo);
 47.1037 +
 47.1038 +	msh.vertex_positions.resize(reader.GetI4());
 47.1039 +	for_each(aiVector3D& v,msh.vertex_positions) {
 47.1040 +		v.x = reader.GetF4();
 47.1041 +		v.y = reader.GetF4();
 47.1042 +		v.z = reader.GetF4();
 47.1043 +	}
 47.1044 +
 47.1045 +	msh.texture_coords.resize(reader.GetI4());
 47.1046 +	for_each(aiVector2D& v,msh.texture_coords) {
 47.1047 +		v.x = reader.GetF4();
 47.1048 +		v.y = reader.GetF4();
 47.1049 +	}
 47.1050 +
 47.1051 +	const size_t numf = reader.GetI4();
 47.1052 +	msh.faces.reserve(numf);
 47.1053 +	for(size_t i = 0; i < numf; ++i) {
 47.1054 +		// XXX backface culling flag is 0x10 in flags
 47.1055 +
 47.1056 +		// hole?
 47.1057 +		bool hole;
 47.1058 +		if ((hole = (reader.GetI1() & 0x08) != 0)) {
 47.1059 +			// XXX Basically this should just work fine - then triangulator
 47.1060 +			// should output properly triangulated data even for polygons
 47.1061 +			// with holes. Test data specific to COB is needed to confirm it.
 47.1062 +			if (msh.faces.empty()) {
 47.1063 +				ThrowException(format("A hole is the first entity in the `PolH` chunk with id ") << nfo.id);
 47.1064 +			}	
 47.1065 +		}
 47.1066 +		else msh.faces.push_back(Face());
 47.1067 +		Face& f = msh.faces.back();
 47.1068 +
 47.1069 +		const size_t num = reader.GetI2();
 47.1070 +		f.indices.reserve(f.indices.size() + num);
 47.1071 +
 47.1072 +		if(!hole) {
 47.1073 +			f.material = reader.GetI2();
 47.1074 +			f.flags = 0;
 47.1075 +		}
 47.1076 +
 47.1077 +		for(size_t x = 0; x < num; ++x) {
 47.1078 +			f.indices.push_back(VertexIndex());
 47.1079 +
 47.1080 +			VertexIndex& v = f.indices.back();
 47.1081 +			v.pos_idx = reader.GetI4();
 47.1082 +			v.uv_idx = reader.GetI4();
 47.1083 +		}
 47.1084 +
 47.1085 +		if(hole) {
 47.1086 +			std::reverse(f.indices.rbegin(),f.indices.rbegin()+num);
 47.1087 +		}
 47.1088 +	}
 47.1089 +	if (nfo.version>4) {
 47.1090 +		msh.draw_flags = reader.GetI4();	
 47.1091 +	}
 47.1092 +	nfo.version>5 && nfo.version<8 ? reader.GetI4() : 0;
 47.1093 +}
 47.1094 +
 47.1095 +// ------------------------------------------------------------------------------------------------
 47.1096 +void COBImporter::ReadBitM_Binary(COB::Scene& /*out*/, StreamReaderLE& reader, const ChunkInfo& nfo)
 47.1097 +{
 47.1098 +	if(nfo.version > 1) {
 47.1099 +		return UnsupportedChunk_Binary(reader,nfo,"BitM");
 47.1100 +	}
 47.1101 +
 47.1102 +	const chunk_guard cn(nfo,reader);
 47.1103 +
 47.1104 +	const uint32_t len = reader.GetI4();
 47.1105 +	reader.IncPtr(len);
 47.1106 +
 47.1107 +	reader.GetI4();
 47.1108 +	reader.IncPtr(reader.GetI4());
 47.1109 +}
 47.1110 +
 47.1111 +// ------------------------------------------------------------------------------------------------
 47.1112 +void COBImporter::ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
 47.1113 +{
 47.1114 +	if(nfo.version > 8) {
 47.1115 +		return UnsupportedChunk_Binary(reader,nfo,"Mat1");
 47.1116 +	}
 47.1117 +
 47.1118 +	const chunk_guard cn(nfo,reader);
 47.1119 +
 47.1120 +	out.materials.push_back(Material());
 47.1121 +	Material& mat = out.materials.back();
 47.1122 +	mat = nfo;
 47.1123 +
 47.1124 +	mat.matnum = reader.GetI2();
 47.1125 +	switch(reader.GetI1()) {
 47.1126 +		case 'f':
 47.1127 +			mat.type = Material::FLAT;
 47.1128 +			break;
 47.1129 +		case 'p':
 47.1130 +			mat.type = Material::PHONG;
 47.1131 +			break;
 47.1132 +		case 'm':
 47.1133 +			mat.type = Material::METAL;
 47.1134 +			break;
 47.1135 +		default:
 47.1136 +			LogError_Ascii(format("Unrecognized shader type in `Mat1` chunk with id ")<<nfo.id);
 47.1137 +			mat.type = Material::FLAT;
 47.1138 +	}
 47.1139 +
 47.1140 +	switch(reader.GetI1()) {
 47.1141 +		case 'f':
 47.1142 +			mat.autofacet = Material::FACETED;
 47.1143 +			break;
 47.1144 +		case 'a':
 47.1145 +			mat.autofacet = Material::AUTOFACETED;
 47.1146 +			break;
 47.1147 +		case 's':
 47.1148 +			mat.autofacet = Material::SMOOTH;
 47.1149 +			break;
 47.1150 +		default:
 47.1151 +			LogError_Ascii(format("Unrecognized faceting mode in `Mat1` chunk with id ")<<nfo.id);
 47.1152 +			mat.autofacet = Material::FACETED;
 47.1153 +	}
 47.1154 +	mat.autofacet_angle = static_cast<float>(reader.GetI1());
 47.1155 +
 47.1156 +	mat.rgb.r = reader.GetF4();
 47.1157 +	mat.rgb.g = reader.GetF4();
 47.1158 +	mat.rgb.b = reader.GetF4();
 47.1159 +
 47.1160 +	mat.alpha = reader.GetF4();
 47.1161 +	mat.ka    = reader.GetF4();
 47.1162 +	mat.ks    = reader.GetF4();
 47.1163 +	mat.exp   = reader.GetF4();
 47.1164 +	mat.ior   = reader.GetF4();
 47.1165 +
 47.1166 +	char id[2];
 47.1167 +	id[0] = reader.GetI1(),id[1] = reader.GetI1();
 47.1168 +
 47.1169 +	if (id[0] == 'e' && id[1] == ':') {
 47.1170 +		mat.tex_env.reset(new Texture());
 47.1171 +
 47.1172 +		reader.GetI1();
 47.1173 +		ReadString_Binary(mat.tex_env->path,reader);
 47.1174 +
 47.1175 +		// advance to next texture-id
 47.1176 +		id[0] = reader.GetI1(),id[1] = reader.GetI1();
 47.1177 +	}
 47.1178 +
 47.1179 +	if (id[0] == 't' && id[1] == ':') {
 47.1180 +		mat.tex_color.reset(new Texture());
 47.1181 +
 47.1182 +		reader.GetI1();
 47.1183 +		ReadString_Binary(mat.tex_color->path,reader);
 47.1184 +
 47.1185 +		mat.tex_color->transform.mTranslation.x = reader.GetF4();
 47.1186 +		mat.tex_color->transform.mTranslation.y = reader.GetF4();
 47.1187 +
 47.1188 +		mat.tex_color->transform.mScaling.x = reader.GetF4();
 47.1189 +		mat.tex_color->transform.mScaling.y = reader.GetF4();
 47.1190 +
 47.1191 +		// advance to next texture-id
 47.1192 +		id[0] = reader.GetI1(),id[1] = reader.GetI1();
 47.1193 +	}
 47.1194 +
 47.1195 +	if (id[0] == 'b' && id[1] == ':') {
 47.1196 +		mat.tex_bump.reset(new Texture());
 47.1197 +
 47.1198 +		reader.GetI1();
 47.1199 +		ReadString_Binary(mat.tex_bump->path,reader);
 47.1200 +
 47.1201 +		mat.tex_bump->transform.mTranslation.x = reader.GetF4();
 47.1202 +		mat.tex_bump->transform.mTranslation.y = reader.GetF4();
 47.1203 +
 47.1204 +		mat.tex_bump->transform.mScaling.x = reader.GetF4();
 47.1205 +		mat.tex_bump->transform.mScaling.y = reader.GetF4();
 47.1206 +
 47.1207 +		// skip amplitude for I don't know its purpose.
 47.1208 +		reader.GetF4();
 47.1209 +	}
 47.1210 +	reader.IncPtr(-2);
 47.1211 +}
 47.1212 +
 47.1213 +// ------------------------------------------------------------------------------------------------
 47.1214 +void COBImporter::ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
 47.1215 +{
 47.1216 +	if(nfo.version > 2) {
 47.1217 +		return UnsupportedChunk_Binary(reader,nfo,"Came");
 47.1218 +	}
 47.1219 +
 47.1220 +	const chunk_guard cn(nfo,reader);
 47.1221 +
 47.1222 +	out.nodes.push_back(boost::shared_ptr<Camera>(new Camera()));
 47.1223 +	Camera& msh = (Camera&)(*out.nodes.back().get());
 47.1224 +	msh = nfo;
 47.1225 +
 47.1226 +	ReadBasicNodeInfo_Binary(msh,reader,nfo);
 47.1227 +
 47.1228 +	// the rest is not interesting for us, so we skip over it.
 47.1229 +	if(nfo.version > 1) {
 47.1230 +		if (reader.GetI2()==512) {
 47.1231 +			reader.IncPtr(42);
 47.1232 +		}
 47.1233 +	}
 47.1234 +}
 47.1235 +
 47.1236 +// ------------------------------------------------------------------------------------------------
 47.1237 +void COBImporter::ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
 47.1238 +{
 47.1239 +	if(nfo.version > 2) {
 47.1240 +		return UnsupportedChunk_Binary(reader,nfo,"Lght");
 47.1241 +	}
 47.1242 +
 47.1243 +	const chunk_guard cn(nfo,reader);
 47.1244 +
 47.1245 +	out.nodes.push_back(boost::shared_ptr<Light>(new Light()));
 47.1246 +	Light& msh = (Light&)(*out.nodes.back().get());
 47.1247 +	msh = nfo;
 47.1248 +
 47.1249 +	ReadBasicNodeInfo_Binary(msh,reader,nfo);
 47.1250 +}
 47.1251 +
 47.1252 +// ------------------------------------------------------------------------------------------------
 47.1253 +void COBImporter::ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
 47.1254 +{
 47.1255 +	if(nfo.version > 2) {
 47.1256 +		return UnsupportedChunk_Binary(reader,nfo,"Grou");
 47.1257 +	}
 47.1258 +
 47.1259 +	const chunk_guard cn(nfo,reader);
 47.1260 +
 47.1261 +	out.nodes.push_back(boost::shared_ptr<Group>(new Group()));
 47.1262 +	Group& msh = (Group&)(*out.nodes.back().get());
 47.1263 +	msh = nfo;
 47.1264 +
 47.1265 +	ReadBasicNodeInfo_Binary(msh,reader,nfo);
 47.1266 +}
 47.1267 +
 47.1268 +// ------------------------------------------------------------------------------------------------
 47.1269 +void COBImporter::ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
 47.1270 +{
 47.1271 +	 if(nfo.version > 1) {
 47.1272 +		return UnsupportedChunk_Binary(reader,nfo,"Unit");
 47.1273 +	}
 47.1274 +
 47.1275 +	 const chunk_guard cn(nfo,reader);
 47.1276 +
 47.1277 +	// parent chunks preceede their childs, so we should have the
 47.1278 +	// corresponding chunk already.
 47.1279 +	for_each(boost::shared_ptr< Node >& nd, out.nodes) {
 47.1280 +		if (nd->id == nfo.parent_id) {
 47.1281 +			const unsigned int t=reader.GetI2();
 47.1282 +			nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
 47.1283 +				LogWarn_Ascii(format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
 47.1284 +				,1.f):units[t];
 47.1285 +
 47.1286 +			return;
 47.1287 +		}
 47.1288 +	}
 47.1289 +	LogWarn_Ascii(format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
 47.1290 +		<<nfo.parent_id<<" which does not exist");
 47.1291 +}
 47.1292 +
 47.1293 +
 47.1294 +#endif
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/libs/assimp/COBLoader.h	Sat Feb 01 19:58:19 2014 +0200
    48.3 @@ -0,0 +1,170 @@
    48.4 +/*
    48.5 +Open Asset Import Library (assimp)
    48.6 +----------------------------------------------------------------------
    48.7 +
    48.8 +Copyright (c) 2006-2012, assimp team
    48.9 +All rights reserved.
   48.10 +
   48.11 +Redistribution and use of this software in source and binary forms, 
   48.12 +with or without modification, are permitted provided that the 
   48.13 +following conditions are met:
   48.14 +
   48.15 +* Redistributions of source code must retain the above
   48.16 +  copyright notice, this list of conditions and the
   48.17 +  following disclaimer.
   48.18 +
   48.19 +* Redistributions in binary form must reproduce the above
   48.20 +  copyright notice, this list of conditions and the
   48.21 +  following disclaimer in the documentation and/or other
   48.22 +  materials provided with the distribution.
   48.23 +
   48.24 +* Neither the name of the assimp team, nor the names of its
   48.25 +  contributors may be used to endorse or promote products
   48.26 +  derived from this software without specific prior
   48.27 +  written permission of the assimp team.
   48.28 +
   48.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   48.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   48.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   48.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   48.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   48.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   48.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   48.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   48.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   48.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   48.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   48.40 +
   48.41 +----------------------------------------------------------------------
   48.42 +*/
   48.43 +
   48.44 +/** @file  COBLoader.h
   48.45 + *  @brief Declaration of the TrueSpace (*.cob,*.scn) importer class.
   48.46 + */
   48.47 +#ifndef INCLUDED_AI_COB_LOADER_H
   48.48 +#define INCLUDED_AI_COB_LOADER_H
   48.49 +
   48.50 +#include "BaseImporter.h"
   48.51 +namespace Assimp	{
   48.52 +	class LineSplitter;
   48.53 +	
   48.54 +	// TinyFormatter.h
   48.55 +	namespace Formatter {
   48.56 +		template <typename T,typename TR, typename A> class basic_formatter;
   48.57 +		typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
   48.58 +	}
   48.59 +
   48.60 +	// COBScene.h
   48.61 +	namespace COB {
   48.62 +		struct ChunkInfo;
   48.63 +		struct Node;
   48.64 +		struct Scene;
   48.65 +	}
   48.66 +
   48.67 +// -------------------------------------------------------------------------------------------
   48.68 +/** Importer class to load TrueSpace files (cob,scn) up to v6. 
   48.69 + *
   48.70 + *  Currently relatively limited, loads only ASCII files and needs more test coverage. */
   48.71 +// -------------------------------------------------------------------------------------------
   48.72 +class COBImporter : public BaseImporter
   48.73 +{
   48.74 +public:
   48.75 +	COBImporter();
   48.76 +	~COBImporter();
   48.77 +
   48.78 +
   48.79 +public:
   48.80 +
   48.81 +	// --------------------
   48.82 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
   48.83 +		bool checkSig) const;
   48.84 +
   48.85 +protected:
   48.86 +
   48.87 +	// --------------------
   48.88 +	const aiImporterDesc* GetInfo () const;
   48.89 +
   48.90 +	// --------------------
   48.91 +	void SetupProperties(const Importer* pImp);
   48.92 +
   48.93 +	// --------------------
   48.94 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
   48.95 +		IOSystem* pIOHandler);
   48.96 +
   48.97 +private:
   48.98 +
   48.99 +	// -------------------------------------------------------------------
  48.100 +	/** Prepend 'COB: ' and throw msg.*/
  48.101 +	static void ThrowException(const std::string& msg);
  48.102 +
  48.103 +	// -------------------------------------------------------------------
  48.104 +	/** @brief Read from an ascii scene/object file
  48.105 +	 *  @param out Receives output data.
  48.106 +	 *  @param stream Stream to read from. */
  48.107 +	void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream);
  48.108 +
  48.109 +	// -------------------------------------------------------------------
  48.110 +	/** @brief Read from a binary scene/object file
  48.111 +	 *  @param out Receives output data.
  48.112 +	 *  @param stream Stream to read from.  */
  48.113 +	void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
  48.114 +
  48.115 +
  48.116 +private:
  48.117 +
  48.118 +	// Conversion to Assimp output format
  48.119 +
  48.120 +	aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
  48.121 +
  48.122 +private:
  48.123 +
  48.124 +	// ASCII file support
  48.125 +
  48.126 +	void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
  48.127 +	void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter);
  48.128 +	void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo);
  48.129 +	template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
  48.130 +
  48.131 +	void ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
  48.132 +	void ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
  48.133 +	void ReadMat1_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
  48.134 +	void ReadGrou_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
  48.135 +	void ReadBone_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
  48.136 +	void ReadCame_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
  48.137 +	void ReadLght_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
  48.138 +	void ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
  48.139 +	void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
  48.140 +
  48.141 +
  48.142 +	// ASCII file logging stuff to add proper line numbers to messages
  48.143 +
  48.144 +	static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message);
  48.145 +	static void LogError_Ascii(const LineSplitter& splitter, const Formatter::format& message);
  48.146 +	static void LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message);
  48.147 +	static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message);
  48.148 +
  48.149 +	static void LogWarn_Ascii  (const Formatter::format& message);
  48.150 +	static void LogError_Ascii (const Formatter::format& message);
  48.151 +	static void LogInfo_Ascii  (const Formatter::format& message);
  48.152 +	static void LogDebug_Ascii (const Formatter::format& message);
  48.153 +
  48.154 +
  48.155 +	// Binary file support
  48.156 +
  48.157 +	void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);
  48.158 +	void ReadString_Binary(std::string& out, StreamReaderLE& reader);
  48.159 +	void ReadBasicNodeInfo_Binary(COB::Node& msh, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
  48.160 +
  48.161 +	void ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
  48.162 +	void ReadBitM_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
  48.163 +	void ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
  48.164 +	void ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
  48.165 +	void ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
  48.166 +	void ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
  48.167 +	void ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
  48.168 +
  48.169 +
  48.170 +}; // !class COBImporter
  48.171 +
  48.172 +} // end of namespace Assimp
  48.173 +#endif // AI_UNREALIMPORTER_H_INC
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/libs/assimp/COBScene.h	Sat Feb 01 19:58:19 2014 +0200
    49.3 @@ -0,0 +1,271 @@
    49.4 +/*
    49.5 +Open Asset Import Library (assimp)
    49.6 +----------------------------------------------------------------------
    49.7 +
    49.8 +Copyright (c) 2006-2012, assimp team
    49.9 +All rights reserved.
   49.10 +
   49.11 +Redistribution and use of this software in source and binary forms, 
   49.12 +with or without modification, are permitted provided that the 
   49.13 +following conditions are met:
   49.14 +
   49.15 +* Redistributions of source code must retain the above
   49.16 +copyright notice, this list of conditions and the
   49.17 +following disclaimer.
   49.18 +
   49.19 +* Redistributions in binary form must reproduce the above
   49.20 +copyright notice, this list of conditions and the
   49.21 +following disclaimer in the documentation and/or other
   49.22 +materials provided with the distribution.
   49.23 +
   49.24 +* Neither the name of the assimp team, nor the names of its
   49.25 +contributors may be used to endorse or promote products
   49.26 +derived from this software without specific prior
   49.27 +written permission of the assimp team.
   49.28 +
   49.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   49.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   49.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   49.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   49.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   49.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   49.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   49.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   49.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   49.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   49.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   49.40 +
   49.41 +----------------------------------------------------------------------
   49.42 +*/
   49.43 +
   49.44 +/** @file  COBScene.h
   49.45 +*  @brief Utilities for the COB importer.
   49.46 +*/
   49.47 +#ifndef INCLUDED_AI_COB_SCENE_H
   49.48 +#define INCLUDED_AI_COB_SCENE_H
   49.49 +
   49.50 +#include <boost/shared_ptr.hpp>
   49.51 +#include "BaseImporter.h"
   49.52 +
   49.53 +namespace Assimp	{
   49.54 +	namespace COB {
   49.55 +
   49.56 +// ------------------
   49.57 +/** Represents a single vertex index in a face */
   49.58 +struct VertexIndex
   49.59 +{
   49.60 +	// intentionally uninitialized
   49.61 +	unsigned int pos_idx,uv_idx;
   49.62 +};
   49.63 +
   49.64 +// ------------------
   49.65 +/** COB Face data structure */
   49.66 +struct Face
   49.67 +{
   49.68 +	// intentionally uninitialized
   49.69 +	unsigned int material, flags;
   49.70 +	std::vector<VertexIndex> indices;
   49.71 +};
   49.72 +
   49.73 +// ------------------
   49.74 +/** COB chunk header information */
   49.75 +struct ChunkInfo
   49.76 +{
   49.77 +	enum {NO_SIZE=UINT_MAX};
   49.78 +
   49.79 +	ChunkInfo ()
   49.80 +		:	id        (0)
   49.81 +		,	parent_id (0)
   49.82 +		,	version	  (0)
   49.83 +		,	size	  (NO_SIZE)
   49.84 +	{}
   49.85 +
   49.86 +	// Id of this chunk, unique within file
   49.87 +	unsigned int id;
   49.88 +
   49.89 +	// and the corresponding parent
   49.90 +	unsigned int parent_id;
   49.91 +
   49.92 +	// version. v1.23 becomes 123
   49.93 +	unsigned int version;
   49.94 +
   49.95 +	// chunk size in bytes, only relevant for binary files
   49.96 +	// NO_SIZE is also valid.
   49.97 +	unsigned int size;
   49.98 +};
   49.99 +
  49.100 +// ------------------
  49.101 +/** A node in the scenegraph */
  49.102 +struct Node : public ChunkInfo
  49.103 +{
  49.104 +	enum Type {
  49.105 +		TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
  49.106 +	};
  49.107 +
  49.108 +	virtual ~Node() {}
  49.109 +	Node(Type type) : type(type), unit_scale(1.f){}
  49.110 +
  49.111 +	Type type;
  49.112 +
  49.113 +	// used during resolving
  49.114 +	typedef std::deque<const Node*> ChildList;
  49.115 +	mutable ChildList temp_children;
  49.116 +
  49.117 +	// unique name
  49.118 +	std::string name;
  49.119 +
  49.120 +	// local mesh transformation
  49.121 +	aiMatrix4x4 transform;
  49.122 +
  49.123 +	// scaling for this node to get to the metric system
  49.124 +	float unit_scale;
  49.125 +};
  49.126 +
  49.127 +// ------------------
  49.128 +/** COB Mesh data structure */
  49.129 +struct Mesh : public Node
  49.130 +{
  49.131 +	using ChunkInfo::operator=;
  49.132 +	enum DrawFlags {
  49.133 +		SOLID = 0x1,
  49.134 +		TRANS = 0x2,
  49.135 +		WIRED = 0x4,
  49.136 +		BBOX  = 0x8,
  49.137 +		HIDE  = 0x10
  49.138 +	};
  49.139 +
  49.140 +	Mesh() 
  49.141 +		: Node(TYPE_MESH)
  49.142 +		, draw_flags(SOLID) 
  49.143 +	{}
  49.144 +
  49.145 +	// vertex elements
  49.146 +	std::vector<aiVector2D> texture_coords;
  49.147 +	std::vector<aiVector3D> vertex_positions;
  49.148 +
  49.149 +	// face data
  49.150 +	std::vector<Face> faces;
  49.151 +
  49.152 +	// misc. drawing flags
  49.153 +	unsigned int draw_flags;
  49.154 +
  49.155 +	// used during resolving
  49.156 +	typedef std::deque<Face*> FaceRefList;
  49.157 +	typedef std::map< unsigned int,FaceRefList > TempMap;
  49.158 +	TempMap temp_map;
  49.159 +};
  49.160 +
  49.161 +// ------------------
  49.162 +/** COB Group data structure */
  49.163 +struct Group : public Node
  49.164 +{
  49.165 +	using ChunkInfo::operator=;
  49.166 +	Group() : Node(TYPE_GROUP) {}
  49.167 +};
  49.168 +
  49.169 +// ------------------
  49.170 +/** COB Bone data structure */
  49.171 +struct Bone : public Node
  49.172 +{
  49.173 +	using ChunkInfo::operator=;
  49.174 +	Bone() : Node(TYPE_BONE) {}
  49.175 +};
  49.176 +
  49.177 +// ------------------
  49.178 +/** COB Light data structure */
  49.179 +struct Light : public Node
  49.180 +{
  49.181 +	enum LightType {
  49.182 +		SPOT,LOCAL,INFINITE
  49.183 +	};
  49.184 +
  49.185 +	using ChunkInfo::operator=;
  49.186 +	Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {}
  49.187 +
  49.188 +	aiColor3D color;
  49.189 +	float angle,inner_angle;
  49.190 +
  49.191 +	LightType ltype;
  49.192 +};
  49.193 +
  49.194 +// ------------------
  49.195 +/** COB Camera data structure */
  49.196 +struct Camera : public Node
  49.197 +{
  49.198 +	using ChunkInfo::operator=;
  49.199 +	Camera() : Node(TYPE_CAMERA) {}
  49.200 +};
  49.201 +
  49.202 +// ------------------
  49.203 +/** COB Texture data structure */
  49.204 +struct Texture
  49.205 +{
  49.206 +	std::string path;
  49.207 +	aiUVTransform transform;
  49.208 +};
  49.209 +
  49.210 +// ------------------
  49.211 +/** COB Material data structure */
  49.212 +struct Material : ChunkInfo
  49.213 +{
  49.214 +	using ChunkInfo::operator=;
  49.215 +	enum Shader {
  49.216 +		FLAT,PHONG,METAL
  49.217 +	};
  49.218 +
  49.219 +	enum AutoFacet {
  49.220 +		FACETED,AUTOFACETED,SMOOTH
  49.221 +	};
  49.222 +
  49.223 +	Material() : alpha(),exp(),ior(),ka(),ks(1.f),
  49.224 +		matnum(UINT_MAX),
  49.225 +		shader(FLAT),autofacet(FACETED),
  49.226 +		autofacet_angle()
  49.227 +	{}
  49.228 +
  49.229 +	std::string type;
  49.230 +
  49.231 +	aiColor3D rgb;
  49.232 +	float alpha, exp, ior,ka,ks;
  49.233 +
  49.234 +	unsigned int matnum;
  49.235 +	Shader shader; 
  49.236 +
  49.237 +	AutoFacet autofacet;
  49.238 +	float autofacet_angle;
  49.239 +
  49.240 +	boost::shared_ptr<Texture> tex_env,tex_bump,tex_color;
  49.241 +};
  49.242 +
  49.243 +// ------------------
  49.244 +/** Embedded bitmap, for instance for the thumbnail image */
  49.245 +struct Bitmap : ChunkInfo
  49.246 +{
  49.247 +	Bitmap() : orig_size() {}
  49.248 +	struct BitmapHeader 
  49.249 +	{
  49.250 +	};
  49.251 +
  49.252 +	BitmapHeader head;
  49.253 +	size_t orig_size;
  49.254 +	std::vector<char> buff_zipped;
  49.255 +};
  49.256 +
  49.257 +typedef std::deque< boost::shared_ptr<Node> > NodeList;
  49.258 +typedef std::vector< Material > MaterialList;
  49.259 +
  49.260 +// ------------------
  49.261 +/** Represents a master COB scene, even if we loaded just a single COB file */
  49.262 +struct Scene
  49.263 +{
  49.264 +	NodeList nodes;
  49.265 +	MaterialList materials;
  49.266 +
  49.267 +	// becomes *0 later
  49.268 +	Bitmap thumbnail;
  49.269 +};
  49.270 +
  49.271 +	} // end COB
  49.272 +} // end Assimp
  49.273 +
  49.274 +#endif
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/libs/assimp/CSMLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
    50.3 @@ -0,0 +1,299 @@
    50.4 +/*
    50.5 +---------------------------------------------------------------------------
    50.6 +Open Asset Import Library (assimp)
    50.7 +---------------------------------------------------------------------------
    50.8 +
    50.9 +Copyright (c) 2006-2012, assimp team
   50.10 +
   50.11 +All rights reserved.
   50.12 +
   50.13 +Redistribution and use of this software in source and binary forms, 
   50.14 +with or without modification, are permitted provided that the following 
   50.15 +conditions are met:
   50.16 +
   50.17 +* Redistributions of source code must retain the above
   50.18 +  copyright notice, this list of conditions and the
   50.19 +  following disclaimer.
   50.20 +
   50.21 +* Redistributions in binary form must reproduce the above
   50.22 +  copyright notice, this list of conditions and the
   50.23 +  following disclaimer in the documentation and/or other
   50.24 +  materials provided with the distribution.
   50.25 +
   50.26 +* Neither the name of the assimp team, nor the names of its
   50.27 +  contributors may be used to endorse or promote products
   50.28 +  derived from this software without specific prior
   50.29 +  written permission of the assimp team.
   50.30 +
   50.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   50.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   50.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   50.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   50.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   50.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   50.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   50.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   50.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   50.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   50.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   50.42 +---------------------------------------------------------------------------
   50.43 +*/
   50.44 +
   50.45 +/** @file  CSMLoader.cpp
   50.46 + *  Implementation of the CSM importer class.
   50.47 + */
   50.48 +
   50.49 +#include "AssimpPCH.h"
   50.50 +
   50.51 +#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
   50.52 +
   50.53 +#include "CSMLoader.h"
   50.54 +#include "SkeletonMeshBuilder.h"
   50.55 +#include "ParsingUtils.h"
   50.56 +#include "fast_atof.h"
   50.57 +
   50.58 +using namespace Assimp;
   50.59 +
   50.60 +static const aiImporterDesc desc = {
   50.61 +	"CharacterStudio Motion Importer (MoCap)",
   50.62 +	"",
   50.63 +	"",
   50.64 +	"",
   50.65 +	aiImporterFlags_SupportTextFlavour,
   50.66 +	0,
   50.67 +	0,
   50.68 +	0,
   50.69 +	0,
   50.70 +	"csm" 
   50.71 +};
   50.72 +
   50.73 +
   50.74 +// ------------------------------------------------------------------------------------------------
   50.75 +// Constructor to be privately used by Importer
   50.76 +CSMImporter::CSMImporter()
   50.77 +: noSkeletonMesh()
   50.78 +{}
   50.79 +
   50.80 +// ------------------------------------------------------------------------------------------------
   50.81 +// Destructor, private as well 
   50.82 +CSMImporter::~CSMImporter()
   50.83 +{}
   50.84 +
   50.85 +// ------------------------------------------------------------------------------------------------
   50.86 +// Returns whether the class can handle the format of the given file. 
   50.87 +bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
   50.88 +{
   50.89 +	// check file extension 
   50.90 +	const std::string extension = GetExtension(pFile);
   50.91 +	
   50.92 +	if( extension == "csm")
   50.93 +		return true;
   50.94 +
   50.95 +	if ((checkSig || !extension.length()) && pIOHandler) {
   50.96 +		const char* tokens[] = {"$Filename"};
   50.97 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
   50.98 +	}
   50.99 +	return false;
  50.100 +}
  50.101 +
  50.102 +// ------------------------------------------------------------------------------------------------
  50.103 +// Build a string of all file extensions supported
  50.104 +const aiImporterDesc* CSMImporter::GetInfo () const
  50.105 +{
  50.106 +	return &desc;
  50.107 +}
  50.108 +
  50.109 +// ------------------------------------------------------------------------------------------------
  50.110 +// Setup configuration properties for the loader
  50.111 +void CSMImporter::SetupProperties(const Importer* pImp)
  50.112 +{
  50.113 +	noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
  50.114 +}
  50.115 +
  50.116 +// ------------------------------------------------------------------------------------------------
  50.117 +// Imports the given file into the given scene structure. 
  50.118 +void CSMImporter::InternReadFile( const std::string& pFile, 
  50.119 +	aiScene* pScene, IOSystem* pIOHandler)
  50.120 +{
  50.121 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
  50.122 +
  50.123 +	// Check whether we can read from the file
  50.124 +	if( file.get() == NULL) {
  50.125 +		throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
  50.126 +	}
  50.127 +
  50.128 +	// allocate storage and copy the contents of the file to a memory buffer
  50.129 +	std::vector<char> mBuffer2;
  50.130 +	TextFileToBuffer(file.get(),mBuffer2);
  50.131 +	const char* buffer = &mBuffer2[0];
  50.132 +
  50.133 +	aiAnimation* anim = new aiAnimation();
  50.134 +	int first = 0, last = 0x00ffffff;
  50.135 +
  50.136 +	// now process the file and look out for '$' sections
  50.137 +	while (1)	{
  50.138 +		SkipSpaces(&buffer);
  50.139 +		if ('\0' == *buffer)
  50.140 +			break;
  50.141 +
  50.142 +		if ('$'  == *buffer)	{
  50.143 +			++buffer;
  50.144 +			if (TokenMatchI(buffer,"firstframe",10))	{
  50.145 +				SkipSpaces(&buffer);
  50.146 +				first = strtol10(buffer,&buffer);
  50.147 +			}
  50.148 +			else if (TokenMatchI(buffer,"lastframe",9))		{
  50.149 +				SkipSpaces(&buffer);
  50.150 +				last = strtol10(buffer,&buffer);
  50.151 +			}
  50.152 +			else if (TokenMatchI(buffer,"rate",4))	{
  50.153 +				SkipSpaces(&buffer);
  50.154 +				float d;
  50.155 +				buffer = fast_atoreal_move<float>(buffer,d);
  50.156 +				anim->mTicksPerSecond = d;
  50.157 +			}
  50.158 +			else if (TokenMatchI(buffer,"order",5))	{
  50.159 +				std::vector< aiNodeAnim* > anims_temp;
  50.160 +				anims_temp.reserve(30);
  50.161 +				while (1)	{
  50.162 +					SkipSpaces(&buffer);
  50.163 +					if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
  50.164 +						break; // next section
  50.165 +
  50.166 +					// Construct a new node animation channel and setup its name
  50.167 +					anims_temp.push_back(new aiNodeAnim());
  50.168 +					aiNodeAnim* nda = anims_temp.back();
  50.169 +
  50.170 +					char* ot = nda->mNodeName.data;
  50.171 +					while (!IsSpaceOrNewLine(*buffer))
  50.172 +						*ot++ = *buffer++;
  50.173 +
  50.174 +					*ot = '\0';
  50.175 +					nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data);
  50.176 +				}
  50.177 +
  50.178 +				anim->mNumChannels = anims_temp.size();
  50.179 +				if (!anim->mNumChannels)
  50.180 +					throw DeadlyImportError("CSM: Empty $order section");
  50.181 +
  50.182 +				// copy over to the output animation
  50.183 +				anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
  50.184 +				::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
  50.185 +			}
  50.186 +			else if (TokenMatchI(buffer,"points",6))	{
  50.187 +				if (!anim->mNumChannels)
  50.188 +					throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
  50.189 +
  50.190 +				// If we know how many frames we'll read, we can preallocate some storage
  50.191 +				unsigned int alloc = 100;
  50.192 +				if (last != 0x00ffffff)
  50.193 +				{
  50.194 +					alloc = last-first;
  50.195 +					alloc += alloc>>2u; // + 25%
  50.196 +					for (unsigned int i = 0; i < anim->mNumChannels;++i)
  50.197 +						anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
  50.198 +				}
  50.199 +
  50.200 +				unsigned int filled = 0;
  50.201 +
  50.202 +				// Now read all point data.
  50.203 +				while (1)	{
  50.204 +					SkipSpaces(&buffer);
  50.205 +					if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$'))	{
  50.206 +						break; // next section
  50.207 +					}
  50.208 +
  50.209 +					// read frame
  50.210 +					const int frame = ::strtoul10(buffer,&buffer);
  50.211 +					last  = std::max(frame,last);
  50.212 +					first = std::min(frame,last);
  50.213 +					for (unsigned int i = 0; i < anim->mNumChannels;++i)	{
  50.214 +
  50.215 +						aiNodeAnim* s = anim->mChannels[i];
  50.216 +						if (s->mNumPositionKeys == alloc)	{ /* need to reallocate? */
  50.217 +
  50.218 +							aiVectorKey* old = s->mPositionKeys;
  50.219 +							s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
  50.220 +							::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
  50.221 +							delete[] old;
  50.222 +						}
  50.223 +
  50.224 +						// read x,y,z
  50.225 +						if(!SkipSpacesAndLineEnd(&buffer))
  50.226 +							throw DeadlyImportError("CSM: Unexpected EOF occured reading sample x coord");
  50.227 +
  50.228 +						if (TokenMatchI(buffer, "DROPOUT", 7))	{
  50.229 +							// seems this is invalid marker data; at least the doc says it's possible
  50.230 +							DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)");
  50.231 +						}
  50.232 +						else	{
  50.233 +							aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
  50.234 +							sub->mTime = (double)frame;
  50.235 +							buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
  50.236 +
  50.237 +							if(!SkipSpacesAndLineEnd(&buffer))
  50.238 +								throw DeadlyImportError("CSM: Unexpected EOF occured reading sample y coord");
  50.239 +							buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
  50.240 +
  50.241 +							if(!SkipSpacesAndLineEnd(&buffer))
  50.242 +								throw DeadlyImportError("CSM: Unexpected EOF occured reading sample z coord");
  50.243 +							buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
  50.244 +
  50.245 +							++s->mNumPositionKeys;
  50.246 +						}
  50.247 +					}
  50.248 +
  50.249 +					// update allocation granularity
  50.250 +					if (filled == alloc)
  50.251 +						alloc *= 2;
  50.252 +
  50.253 +					++filled;
  50.254 +				}
  50.255 +				// all channels must be complete in order to continue safely.
  50.256 +				for (unsigned int i = 0; i < anim->mNumChannels;++i)	{
  50.257 +
  50.258 +					if (!anim->mChannels[i]->mNumPositionKeys)
  50.259 +						throw DeadlyImportError("CSM: Invalid marker track");
  50.260 +				}
  50.261 +			}
  50.262 +		}
  50.263 +		else	{
  50.264 +			// advance to the next line
  50.265 +			SkipLine(&buffer);
  50.266 +		}
  50.267 +	}
  50.268 +
  50.269 +	// Setup a proper animation duration
  50.270 +	anim->mDuration = last - std::min( first, 0 );
  50.271 +
  50.272 +	// build a dummy root node with the tiny markers as children
  50.273 +	pScene->mRootNode = new aiNode();
  50.274 +	pScene->mRootNode->mName.Set("$CSM_DummyRoot");
  50.275 +
  50.276 +	pScene->mRootNode->mNumChildren = anim->mNumChannels;
  50.277 +	pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
  50.278 +
  50.279 +	for (unsigned int i = 0; i < anim->mNumChannels;++i)	{
  50.280 +		aiNodeAnim* na = anim->mChannels[i]; 
  50.281 +
  50.282 +		aiNode* nd  = pScene->mRootNode->mChildren[i] = new aiNode();
  50.283 +		nd->mName   = anim->mChannels[i]->mNodeName;
  50.284 +		nd->mParent = pScene->mRootNode;
  50.285 +
  50.286 +		aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation);
  50.287 +	}
  50.288 +
  50.289 +	// Store the one and only animation in the scene
  50.290 +	pScene->mAnimations    = new aiAnimation*[pScene->mNumAnimations=1];
  50.291 +	pScene->mAnimations[0] = anim;
  50.292 +	anim->mName.Set("$CSM_MasterAnim");
  50.293 +
  50.294 +	// mark the scene as incomplete and run SkeletonMeshBuilder on it
  50.295 +	pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
  50.296 +	
  50.297 +	if (!noSkeletonMesh) {
  50.298 +		SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true);
  50.299 +	}
  50.300 +}
  50.301 +
  50.302 +#endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/libs/assimp/CSMLoader.h	Sat Feb 01 19:58:19 2014 +0200
    51.3 @@ -0,0 +1,88 @@
    51.4 +/*
    51.5 +Open Asset Import Library (assimp)
    51.6 +----------------------------------------------------------------------
    51.7 +
    51.8 +Copyright (c) 2006-2012, assimp team
    51.9 +All rights reserved.
   51.10 +
   51.11 +Redistribution and use of this software in source and binary forms, 
   51.12 +with or without modification, are permitted provided that the 
   51.13 +following conditions are met:
   51.14 +
   51.15 +* Redistributions of source code must retain the above
   51.16 +  copyright notice, this list of conditions and the
   51.17 +  following disclaimer.
   51.18 +
   51.19 +* Redistributions in binary form must reproduce the above
   51.20 +  copyright notice, this list of conditions and the
   51.21 +  following disclaimer in the documentation and/or other
   51.22 +  materials provided with the distribution.
   51.23 +
   51.24 +* Neither the name of the assimp team, nor the names of its
   51.25 +  contributors may be used to endorse or promote products
   51.26 +  derived from this software without specific prior
   51.27 +  written permission of the assimp team.
   51.28 +
   51.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   51.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   51.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   51.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   51.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   51.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   51.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   51.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   51.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   51.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   51.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   51.40 +
   51.41 +----------------------------------------------------------------------
   51.42 +*/
   51.43 +
   51.44 +/** @file CSMLoader.h
   51.45 + *  Declaration of the CharacterStudio Motion importer class.
   51.46 + */
   51.47 +#ifndef INCLUDED_AI_CSM_LOADER_H
   51.48 +#define INCLUDED_AI_CSM_LOADER_H
   51.49 +namespace Assimp	{
   51.50 +
   51.51 +// ---------------------------------------------------------------------------
   51.52 +/** Importer class to load MOCAPs in CharacterStudio Motion format.
   51.53 + *
   51.54 + *  A very rudimentary loader for the moment. No support for the hierarchy,
   51.55 + *  every marker is returned as child of root.
   51.56 + *
   51.57 + *  Link to file format specification:
   51.58 + *  <max_8_dvd>\samples\Motion\Docs\CSM.rtf
   51.59 +*/
   51.60 +class CSMImporter : public BaseImporter
   51.61 +{
   51.62 +public:
   51.63 +	CSMImporter();
   51.64 +	~CSMImporter();
   51.65 +
   51.66 +
   51.67 +public:
   51.68 +	// -------------------------------------------------------------------
   51.69 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, 
   51.70 +		bool checkSig) const;
   51.71 +
   51.72 +protected:
   51.73 +
   51.74 +	// -------------------------------------------------------------------
   51.75 +	const aiImporterDesc* GetInfo () const;
   51.76 +
   51.77 +	// -------------------------------------------------------------------
   51.78 +	void SetupProperties(const Importer* pImp);
   51.79 +
   51.80 +	// -------------------------------------------------------------------
   51.81 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
   51.82 +		IOSystem* pIOHandler);
   51.83 +
   51.84 +private:
   51.85 +
   51.86 +	bool noSkeletonMesh;
   51.87 +
   51.88 +}; // end of class CSMImporter
   51.89 +} // end of namespace Assimp
   51.90 +#endif // AI_AC3DIMPORTER_H_INC
   51.91 +
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/libs/assimp/CalcTangentsProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
    52.3 @@ -0,0 +1,292 @@
    52.4 +/*
    52.5 +---------------------------------------------------------------------------
    52.6 +Open Asset Import Library (assimp)
    52.7 +---------------------------------------------------------------------------
    52.8 +
    52.9 +Copyright (c) 2006-2012, assimp team
   52.10 +
   52.11 +All rights reserved.
   52.12 +
   52.13 +Redistribution and use of this software in source and binary forms, 
   52.14 +with or without modification, are permitted provided that the following 
   52.15 +conditions are met:
   52.16 +
   52.17 +* Redistributions of source code must retain the above
   52.18 +  copyright notice, this list of conditions and the
   52.19 +  following disclaimer.
   52.20 +
   52.21 +* Redistributions in binary form must reproduce the above
   52.22 +  copyright notice, this list of conditions and the
   52.23 +  following disclaimer in the documentation and/or other
   52.24 +  materials provided with the distribution.
   52.25 +
   52.26 +* Neither the name of the assimp team, nor the names of its
   52.27 +  contributors may be used to endorse or promote products
   52.28 +  derived from this software without specific prior
   52.29 +  written permission of the assimp team.
   52.30 +
   52.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   52.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   52.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   52.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   52.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   52.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   52.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   52.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   52.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   52.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   52.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   52.42 +---------------------------------------------------------------------------
   52.43 +*/
   52.44 +
   52.45 +/** @file Implementation of the post processing step to calculate 
   52.46 + *  tangents and bitangents for all imported meshes
   52.47 + */
   52.48 +
   52.49 +#include "AssimpPCH.h"
   52.50 +
   52.51 +// internal headers
   52.52 +#include "CalcTangentsProcess.h"
   52.53 +#include "ProcessHelper.h"
   52.54 +#include "TinyFormatter.h"
   52.55 +
   52.56 +using namespace Assimp;
   52.57 +
   52.58 +// ------------------------------------------------------------------------------------------------
   52.59 +// Constructor to be privately used by Importer
   52.60 +CalcTangentsProcess::CalcTangentsProcess()
   52.61 +{
   52.62 +	this->configMaxAngle = AI_DEG_TO_RAD(45.f);
   52.63 +}
   52.64 +
   52.65 +// ------------------------------------------------------------------------------------------------
   52.66 +// Destructor, private as well
   52.67 +CalcTangentsProcess::~CalcTangentsProcess()
   52.68 +{
   52.69 +	// nothing to do here
   52.70 +}
   52.71 +
   52.72 +// ------------------------------------------------------------------------------------------------
   52.73 +// Returns whether the processing step is present in the given flag field.
   52.74 +bool CalcTangentsProcess::IsActive( unsigned int pFlags) const
   52.75 +{
   52.76 +	return (pFlags & aiProcess_CalcTangentSpace) != 0;
   52.77 +}
   52.78 +
   52.79 +// ------------------------------------------------------------------------------------------------
   52.80 +// Executes the post processing step on the given imported data.
   52.81 +void CalcTangentsProcess::SetupProperties(const Importer* pImp)
   52.82 +{
   52.83 +	// get the current value of the property
   52.84 +	configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45.f);
   52.85 +	configMaxAngle = std::max(std::min(configMaxAngle,45.0f),0.0f);
   52.86 +	configMaxAngle = AI_DEG_TO_RAD(configMaxAngle);
   52.87 +
   52.88 +	configSourceUV = pImp->GetPropertyInteger(AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX,0);
   52.89 +}
   52.90 +
   52.91 +// ------------------------------------------------------------------------------------------------
   52.92 +// Executes the post processing step on the given imported data.
   52.93 +void CalcTangentsProcess::Execute( aiScene* pScene)
   52.94 +{
   52.95 +	DefaultLogger::get()->debug("CalcTangentsProcess begin");
   52.96 +
   52.97 +	bool bHas = false;
   52.98 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
   52.99 +		if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
  52.100 +
  52.101 +	if (bHas)DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated");
  52.102 +	else DefaultLogger::get()->debug("CalcTangentsProcess finished");
  52.103 +}
  52.104 +
  52.105 +// ------------------------------------------------------------------------------------------------
  52.106 +// Calculates tangents and bitangents for the given mesh
  52.107 +bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
  52.108 +{
  52.109 +	// we assume that the mesh is still in the verbose vertex format where each face has its own set
  52.110 +	// of vertices and no vertices are shared between faces. Sadly I don't know any quick test to 
  52.111 +	// assert() it here.
  52.112 +    //assert( must be verbose, dammit);
  52.113 +
  52.114 +	if (pMesh->mTangents) // thisimplies that mBitangents is also there
  52.115 +		return false;
  52.116 +
  52.117 +	// If the mesh consists of lines and/or points but not of
  52.118 +	// triangles or higher-order polygons the normal vectors
  52.119 +	// are undefined.
  52.120 +	if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
  52.121 +	{
  52.122 +		DefaultLogger::get()->info("Tangents are undefined for line and point meshes");
  52.123 +		return false;
  52.124 +	}
  52.125 +
  52.126 +	// what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement
  52.127 +	if( pMesh->mNormals == NULL)
  52.128 +	{
  52.129 +		DefaultLogger::get()->error("Failed to compute tangents; need normals");
  52.130 +		return false;
  52.131 +	}
  52.132 +	if( configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV] )
  52.133 +	{
  52.134 +		DefaultLogger::get()->error((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV));
  52.135 +		return false;
  52.136 +	}
  52.137 +	 
  52.138 +	const float angleEpsilon = 0.9999f;
  52.139 +
  52.140 +	std::vector<bool> vertexDone( pMesh->mNumVertices, false);
  52.141 +	const float qnan = get_qnan();
  52.142 +
  52.143 +	// create space for the tangents and bitangents
  52.144 +	pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
  52.145 +	pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
  52.146 +
  52.147 +	const aiVector3D* meshPos = pMesh->mVertices;
  52.148 +	const aiVector3D* meshNorm = pMesh->mNormals;
  52.149 +	const aiVector3D* meshTex = pMesh->mTextureCoords[configSourceUV];
  52.150 +	aiVector3D* meshTang = pMesh->mTangents;
  52.151 +	aiVector3D* meshBitang = pMesh->mBitangents;
  52.152 +	
  52.153 +	// calculate the tangent and bitangent for every face
  52.154 +	for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
  52.155 +	{
  52.156 +		const aiFace& face = pMesh->mFaces[a];
  52.157 +		if (face.mNumIndices < 3)
  52.158 +		{
  52.159 +			// There are less than three indices, thus the tangent vector
  52.160 +			// is not defined. We are finished with these vertices now,
  52.161 +			// their tangent vectors are set to qnan.
  52.162 +			for (unsigned int i = 0; i < face.mNumIndices;++i)
  52.163 +			{
  52.164 +				register unsigned int idx = face.mIndices[i];
  52.165 +				vertexDone  [idx] = true;
  52.166 +				meshTang    [idx] = aiVector3D(qnan);
  52.167 +				meshBitang  [idx] = aiVector3D(qnan);
  52.168 +			}
  52.169 +
  52.170 +			continue;
  52.171 +		}
  52.172 +
  52.173 +		// triangle or polygon... we always use only the first three indices. A polygon
  52.174 +		// is supposed to be planar anyways....
  52.175 +		// FIXME: (thom) create correct calculation for multi-vertex polygons maybe?
  52.176 +		const unsigned int p0 = face.mIndices[0], p1 = face.mIndices[1], p2 = face.mIndices[2];
  52.177 +
  52.178 +		// position differences p1->p2 and p1->p3
  52.179 +		aiVector3D v = meshPos[p1] - meshPos[p0], w = meshPos[p2] - meshPos[p0];
  52.180 +
  52.181 +		// texture offset p1->p2 and p1->p3
  52.182 +		float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y;
  52.183 +        float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y;
  52.184 +		float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;
  52.185 +
  52.186 +		// tangent points in the direction where to positive X axis of the texture coords would point in model space
  52.187 +		// bitangents points along the positive Y axis of the texture coords, respectively
  52.188 +		aiVector3D tangent, bitangent;
  52.189 +		tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
  52.190 +        tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
  52.191 +        tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
  52.192 +        bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
  52.193 +        bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
  52.194 +        bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
  52.195 +
  52.196 +		// store for every vertex of that face
  52.197 +		for( unsigned int b = 0; b < face.mNumIndices; b++)
  52.198 +		{
  52.199 +			unsigned int p = face.mIndices[b];
  52.200 +
  52.201 +			// project tangent and bitangent into the plane formed by the vertex' normal
  52.202 +			aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
  52.203 +			aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
  52.204 +			localTangent.Normalize(); localBitangent.Normalize();
  52.205 +
  52.206 +			// and write it into the mesh.
  52.207 +			meshTang[p] = localTangent;
  52.208 +			meshBitang[p] = localBitangent;
  52.209 +		}
  52.210 +    }
  52.211 +
  52.212 +
  52.213 +	// create a helper to quickly find locally close vertices among the vertex array
  52.214 +	// FIX: check whether we can reuse the SpatialSort of a previous step
  52.215 +	SpatialSort* vertexFinder = NULL;
  52.216 +	SpatialSort  _vertexFinder;
  52.217 +	float posEpsilon;
  52.218 +	if (shared)
  52.219 +	{
  52.220 +		std::vector<std::pair<SpatialSort,float> >* avf;
  52.221 +		shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
  52.222 +		if (avf)
  52.223 +		{
  52.224 +			std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
  52.225 +			vertexFinder = &blubb.first;
  52.226 +			posEpsilon = blubb.second;;
  52.227 +		}
  52.228 +	}
  52.229 +	if (!vertexFinder)
  52.230 +	{
  52.231 +		_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
  52.232 +		vertexFinder = &_vertexFinder;
  52.233 +		posEpsilon = ComputePositionEpsilon(pMesh);
  52.234 +	}
  52.235 +	std::vector<unsigned int> verticesFound;
  52.236 +
  52.237 +	const float fLimit = cosf(configMaxAngle); 
  52.238 +	std::vector<unsigned int> closeVertices;
  52.239 +
  52.240 +	// in the second pass we now smooth out all tangents and bitangents at the same local position 
  52.241 +	// if they are not too far off.
  52.242 +	for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
  52.243 +	{
  52.244 +		if( vertexDone[a])
  52.245 +			continue;
  52.246 +
  52.247 +		const aiVector3D& origPos = pMesh->mVertices[a];
  52.248 +		const aiVector3D& origNorm = pMesh->mNormals[a];
  52.249 +		const aiVector3D& origTang = pMesh->mTangents[a];
  52.250 +		const aiVector3D& origBitang = pMesh->mBitangents[a];
  52.251 +		closeVertices.clear();
  52.252 +
  52.253 +		// find all vertices close to that position
  52.254 +		vertexFinder->FindPositions( origPos, posEpsilon, verticesFound);
  52.255 +
  52.256 +		closeVertices.reserve (verticesFound.size()+5);
  52.257 +		closeVertices.push_back( a);
  52.258 +
  52.259 +		// look among them for other vertices sharing the same normal and a close-enough tangent/bitangent
  52.260 +		for( unsigned int b = 0; b < verticesFound.size(); b++)
  52.261 +		{
  52.262 +			unsigned int idx = verticesFound[b];
  52.263 +			if( vertexDone[idx])
  52.264 +				continue;
  52.265 +			if( meshNorm[idx] * origNorm < angleEpsilon)
  52.266 +				continue;
  52.267 +			if(  meshTang[idx] * origTang < fLimit)
  52.268 +				continue;
  52.269 +			if( meshBitang[idx] * origBitang < fLimit)
  52.270 +				continue;
  52.271 +
  52.272 +			// it's similar enough -> add it to the smoothing group
  52.273 +			closeVertices.push_back( idx);
  52.274 +			vertexDone[idx] = true;
  52.275 +		}
  52.276 +
  52.277 +		// smooth the tangents and bitangents of all vertices that were found to be close enough
  52.278 +		aiVector3D smoothTangent( 0, 0, 0), smoothBitangent( 0, 0, 0);
  52.279 +		for( unsigned int b = 0; b < closeVertices.size(); ++b)
  52.280 +		{
  52.281 +			smoothTangent += meshTang[ closeVertices[b] ];
  52.282 +			smoothBitangent += meshBitang[ closeVertices[b] ];
  52.283 +		}
  52.284 +		smoothTangent.Normalize();
  52.285 +		smoothBitangent.Normalize();
  52.286 +
  52.287 +		// and write it back into all affected tangents
  52.288 +		for( unsigned int b = 0; b < closeVertices.size(); ++b)
  52.289 +		{
  52.290 +			meshTang[ closeVertices[b] ] = smoothTangent;
  52.291 +			meshBitang[ closeVertices[b] ] = smoothBitangent;
  52.292 +		}
  52.293 +	}
  52.294 +	return true;
  52.295 +}
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/libs/assimp/CalcTangentsProcess.h	Sat Feb 01 19:58:19 2014 +0200
    53.3 @@ -0,0 +1,115 @@
    53.4 +/*
    53.5 +Open Asset Import Library (assimp)
    53.6 +----------------------------------------------------------------------
    53.7 +
    53.8 +Copyright (c) 2006-2012, assimp team
    53.9 +All rights reserved.
   53.10 +
   53.11 +Redistribution and use of this software in source and binary forms, 
   53.12 +with or without modification, are permitted provided that the 
   53.13 +following conditions are met:
   53.14 +
   53.15 +* Redistributions of source code must retain the above
   53.16 +  copyright notice, this list of conditions and the
   53.17 +  following disclaimer.
   53.18 +
   53.19 +* Redistributions in binary form must reproduce the above
   53.20 +  copyright notice, this list of conditions and the
   53.21 +  following disclaimer in the documentation and/or other
   53.22 +  materials provided with the distribution.
   53.23 +
   53.24 +* Neither the name of the assimp team, nor the names of its
   53.25 +  contributors may be used to endorse or promote products
   53.26 +  derived from this software without specific prior
   53.27 +  written permission of the assimp team.
   53.28 +
   53.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   53.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   53.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   53.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   53.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   53.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   53.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   53.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   53.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   53.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   53.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   53.40 +
   53.41 +----------------------------------------------------------------------
   53.42 +*/
   53.43 +
   53.44 +
   53.45 +/** @file Defines a post processing step to calculate tangents and 
   53.46 +    bitangents on all imported meshes.*/
   53.47 +#ifndef AI_CALCTANGENTSPROCESS_H_INC
   53.48 +#define AI_CALCTANGENTSPROCESS_H_INC
   53.49 +
   53.50 +#include "BaseProcess.h"
   53.51 +
   53.52 +struct aiMesh;
   53.53 +
   53.54 +namespace Assimp
   53.55 +{
   53.56 +
   53.57 +// ---------------------------------------------------------------------------
   53.58 +/** The CalcTangentsProcess calculates the tangent and bitangent for any vertex
   53.59 + * of all meshes. It is expected to be run before the JoinVerticesProcess runs
   53.60 + * because the joining of vertices also considers tangents and bitangents for 
   53.61 + * uniqueness.
   53.62 + */
   53.63 +class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess
   53.64 +{
   53.65 +public:
   53.66 +
   53.67 +	CalcTangentsProcess();
   53.68 +	~CalcTangentsProcess();
   53.69 +
   53.70 +public:
   53.71 +	// -------------------------------------------------------------------
   53.72 +	/** Returns whether the processing step is present in the given flag.
   53.73 +	* @param pFlags The processing flags the importer was called with.
   53.74 +	*   A bitwise combination of #aiPostProcessSteps.
   53.75 +	* @return true if the process is present in this flag fields,
   53.76 +	*   false if not.
   53.77 +	*/
   53.78 +	bool IsActive( unsigned int pFlags) const;
   53.79 +
   53.80 +	// -------------------------------------------------------------------
   53.81 +	/** Called prior to ExecuteOnScene().
   53.82 +	* The function is a request to the process to update its configuration
   53.83 +	* basing on the Importer's configuration property list.
   53.84 +	*/
   53.85 +	void SetupProperties(const Importer* pImp);
   53.86 +
   53.87 +
   53.88 +	// setter for configMaxAngle
   53.89 +	inline void SetMaxSmoothAngle(float f)
   53.90 +	{
   53.91 +		configMaxAngle =f;
   53.92 +	}
   53.93 +
   53.94 +protected:
   53.95 +
   53.96 +	// -------------------------------------------------------------------
   53.97 +	/** Calculates tangents and bitangents for a specific mesh.
   53.98 +	* @param pMesh The mesh to process.
   53.99 +	* @param meshIndex Index of the mesh
  53.100 +	*/
  53.101 +	bool ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
  53.102 +
  53.103 +	// -------------------------------------------------------------------
  53.104 +	/** Executes the post processing step on the given imported data.
  53.105 +	* @param pScene The imported data to work at.
  53.106 +	*/
  53.107 +	void Execute( aiScene* pScene);
  53.108 +
  53.109 +private:
  53.110 +
  53.111 +	/** Configuration option: maximum smoothing angle, in radians*/
  53.112 +	float configMaxAngle;
  53.113 +	unsigned int configSourceUV;
  53.114 +};
  53.115 +
  53.116 +} // end of namespace Assimp
  53.117 +
  53.118 +#endif // AI_CALCTANGENTSPROCESS_H_INC
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/libs/assimp/ColladaExporter.cpp	Sat Feb 01 19:58:19 2014 +0200
    54.3 @@ -0,0 +1,609 @@
    54.4 +/*
    54.5 +Open Asset Import Library (assimp)
    54.6 +----------------------------------------------------------------------
    54.7 +
    54.8 +Copyright (c) 2006-2012, assimp team
    54.9 +All rights reserved.
   54.10 +
   54.11 +Redistribution and use of this software in source and binary forms, 
   54.12 +with or without modification, are permitted provided that the 
   54.13 +following conditions are met:
   54.14 +
   54.15 +* Redistributions of source code must retain the above
   54.16 +  copyright notice, this list of conditions and the
   54.17 +  following disclaimer.
   54.18 +
   54.19 +* Redistributions in binary form must reproduce the above
   54.20 +  copyright notice, this list of conditions and the
   54.21 +  following disclaimer in the documentation and/or other
   54.22 +  materials provided with the distribution.
   54.23 +
   54.24 +* Neither the name of the assimp team, nor the names of its
   54.25 +  contributors may be used to endorse or promote products
   54.26 +  derived from this software without specific prior
   54.27 +  written permission of the assimp team.
   54.28 +
   54.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   54.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   54.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   54.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   54.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   54.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   54.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   54.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   54.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   54.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   54.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   54.40 +
   54.41 +----------------------------------------------------------------------
   54.42 +*/
   54.43 +
   54.44 +#include "AssimpPCH.h"
   54.45 +
   54.46 +#ifndef ASSIMP_BUILD_NO_EXPORT
   54.47 +#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
   54.48 +#include "ColladaExporter.h"
   54.49 +
   54.50 +using namespace Assimp;
   54.51 +
   54.52 +namespace Assimp
   54.53 +{
   54.54 +
   54.55 +// ------------------------------------------------------------------------------------------------
   54.56 +// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
   54.57 +void ExportSceneCollada(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
   54.58 +{
   54.59 +	// invoke the exporter 
   54.60 +	ColladaExporter iDoTheExportThing( pScene);
   54.61 +
   54.62 +	// we're still here - export successfully completed. Write result to the given IOSYstem
   54.63 +	boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
   54.64 +	if(outfile == NULL) {
   54.65 +		throw DeadlyExportError("could not open output .dae file: " + std::string(pFile));
   54.66 +	}
   54.67 +
   54.68 +	// XXX maybe use a small wrapper around IOStream that behaves like std::stringstream in order to avoid the extra copy.
   54.69 +	outfile->Write( iDoTheExportThing.mOutput.str().c_str(), static_cast<size_t>(iDoTheExportThing.mOutput.tellp()),1);
   54.70 +}
   54.71 +
   54.72 +} // end of namespace Assimp
   54.73 +
   54.74 +
   54.75 +// ------------------------------------------------------------------------------------------------
   54.76 +// Constructor for a specific scene to export
   54.77 +ColladaExporter::ColladaExporter( const aiScene* pScene)
   54.78 +{
   54.79 +	// make sure that all formatting happens using the standard, C locale and not the user's current locale
   54.80 +	mOutput.imbue( std::locale("C") );
   54.81 +
   54.82 +	mScene = pScene;
   54.83 +
   54.84 +	// set up strings
   54.85 +	endstr = "\n"; 
   54.86 +
   54.87 +	// start writing
   54.88 +	WriteFile();
   54.89 +}
   54.90 +
   54.91 +// ------------------------------------------------------------------------------------------------
   54.92 +// Starts writing the contents
   54.93 +void ColladaExporter::WriteFile()
   54.94 +{
   54.95 +	// write the DTD
   54.96 +	mOutput << "<?xml version=\"1.0\"?>" << endstr;
   54.97 +	// COLLADA element start
   54.98 +	mOutput << "<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">" << endstr;
   54.99 +	PushTag();
  54.100 +
  54.101 +	WriteHeader();
  54.102 +
  54.103 +  WriteMaterials();
  54.104 +	WriteGeometryLibrary();
  54.105 +
  54.106 +	WriteSceneLibrary();
  54.107 +
  54.108 +	// useless Collada fu at the end, just in case we haven't had enough indirections, yet. 
  54.109 +	mOutput << startstr << "<scene>" << endstr;
  54.110 +	PushTag();
  54.111 +	mOutput << startstr << "<instance_visual_scene url=\"#myScene\" />" << endstr;
  54.112 +	PopTag();
  54.113 +	mOutput << startstr << "</scene>" << endstr;
  54.114 +	PopTag();
  54.115 +	mOutput << "</COLLADA>" << endstr;
  54.116 +}
  54.117 +
  54.118 +// ------------------------------------------------------------------------------------------------
  54.119 +// Writes the asset header
  54.120 +void ColladaExporter::WriteHeader()
  54.121 +{
  54.122 +	// Dummy stuff. Nobody actually cares for it anyways
  54.123 +	mOutput << startstr << "<asset>" << endstr;
  54.124 +	PushTag();
  54.125 +	mOutput << startstr << "<contributor>" << endstr;
  54.126 +	PushTag();
  54.127 +	mOutput << startstr << "<author>Someone</author>" << endstr;
  54.128 +	mOutput << startstr << "<authoring_tool>Assimp Collada Exporter</authoring_tool>" << endstr;
  54.129 +	PopTag();
  54.130 +	mOutput << startstr << "</contributor>" << endstr;
  54.131 +  mOutput << startstr << "<created>2000-01-01T23:59:59</created>" << endstr;
  54.132 +  mOutput << startstr << "<modified>2000-01-01T23:59:59</modified>" << endstr;
  54.133 +	mOutput << startstr << "<unit name=\"centimeter\" meter=\"0.01\" />" << endstr;
  54.134 +	mOutput << startstr << "<up_axis>Y_UP</up_axis>" << endstr;
  54.135 +	PopTag();
  54.136 +	mOutput << startstr << "</asset>" << endstr;
  54.137 +}
  54.138 +
  54.139 +// ------------------------------------------------------------------------------------------------
  54.140 +// Reads a single surface entry from the given material keys
  54.141 +void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex)
  54.142 +{
  54.143 +  if( pSrcMat->GetTextureCount( pTexture) > 0 )
  54.144 +  {
  54.145 +    aiString texfile;
  54.146 +    unsigned int uvChannel = 0;
  54.147 +    pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel);
  54.148 +    poSurface.texture = texfile.C_Str();
  54.149 +    poSurface.channel = uvChannel;
  54.150 +  } else
  54.151 +  {
  54.152 +    if( pKey )
  54.153 +      pSrcMat->Get( pKey, pType, pIndex, poSurface.color);
  54.154 +  }
  54.155 +}
  54.156 +
  54.157 +// ------------------------------------------------------------------------------------------------
  54.158 +// Writes an image entry for the given surface
  54.159 +void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd)
  54.160 +{
  54.161 +  if( !pSurface.texture.empty() )
  54.162 +  {
  54.163 +    mOutput << startstr << "<image id=\"" << pNameAdd << "\">" << endstr;
  54.164 +    PushTag(); 
  54.165 +    mOutput << startstr << "<init_from>";
  54.166 +    for( std::string::const_iterator it = pSurface.texture.begin(); it != pSurface.texture.end(); ++it )
  54.167 +    {
  54.168 +      if( isalnum( *it) || *it == '_' || *it == '.' || *it == '/' || *it == '\\' )
  54.169 +        mOutput << *it;
  54.170 +      else
  54.171 +        mOutput << '%' << std::hex << size_t( (unsigned char) *it) << std::dec;
  54.172 +    }
  54.173 +    mOutput << "</init_from>" << endstr;
  54.174 +    PopTag();
  54.175 +    mOutput << startstr << "</image>" << endstr;
  54.176 +  }
  54.177 +}
  54.178 +
  54.179 +// ------------------------------------------------------------------------------------------------
  54.180 +// Writes a color-or-texture entry into an effect definition
  54.181 +void ColladaExporter::WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName)
  54.182 +{
  54.183 +  mOutput << startstr << "<" << pTypeName << ">" << endstr;
  54.184 +  PushTag();
  54.185 +  if( pSurface.texture.empty() )
  54.186 +  {
  54.187 +    mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << "   " << pSurface.color.g << "   " << pSurface.color.b << "   " << pSurface.color.a << "</color>" << endstr;
  54.188 +  } else
  54.189 +  {
  54.190 +    mOutput << startstr << "<texture texture=\"" << pImageName << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
  54.191 +  }
  54.192 +  PopTag();
  54.193 +  mOutput << startstr << "</" << pTypeName << ">" << endstr;
  54.194 +}
  54.195 +
  54.196 +// ------------------------------------------------------------------------------------------------
  54.197 +// Writes the two parameters necessary for referencing a texture in an effect entry
  54.198 +void ColladaExporter::WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName)
  54.199 +{
  54.200 +  // if surface is a texture, write out the sampler and the surface parameters necessary to reference the texture
  54.201 +  if( !pSurface.texture.empty() )
  54.202 +  {
  54.203 +    mOutput << startstr << "<newparam sid=\"" << pMatName << "-" << pTypeName << "-surface\">" << endstr;
  54.204 +    PushTag();
  54.205 +    mOutput << startstr << "<surface type=\"2D\">" << endstr;
  54.206 +    PushTag();
  54.207 +    mOutput << startstr << "<init_from>" << pMatName << "-" << pTypeName << "-image</init_from>" << endstr;
  54.208 +    PopTag();
  54.209 +    mOutput << startstr << "</surface>" << endstr;
  54.210 +    PopTag();
  54.211 +    mOutput << startstr << "</newparam>" << endstr;
  54.212 +
  54.213 +    mOutput << startstr << "<newparam sid=\"" << pMatName << "-" << pTypeName << "-sampler\">" << endstr;
  54.214 +    PushTag();
  54.215 +    mOutput << startstr << "<sampler2D>" << endstr;
  54.216 +    PushTag();
  54.217 +    mOutput << startstr << "<source>" << pMatName << "-" << pTypeName << "-surface</source>" << endstr;
  54.218 +    PopTag();
  54.219 +    mOutput << startstr << "</sampler2D>" << endstr;
  54.220 +    PopTag();
  54.221 +    mOutput << startstr << "</newparam>" << endstr;
  54.222 +  }
  54.223 +}
  54.224 +
  54.225 +// ------------------------------------------------------------------------------------------------
  54.226 +// Writes the material setup
  54.227 +void ColladaExporter::WriteMaterials()
  54.228 +{
  54.229 +  materials.resize( mScene->mNumMaterials);
  54.230 +
  54.231 +  /// collect all materials from the scene
  54.232 +  size_t numTextures = 0;
  54.233 +  for( size_t a = 0; a < mScene->mNumMaterials; ++a )
  54.234 +  {
  54.235 +    const aiMaterial* mat = mScene->mMaterials[a];
  54.236 +
  54.237 +    aiString name;
  54.238 +    if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS )
  54.239 +      name = "mat";
  54.240 +    materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + name.C_Str();
  54.241 +    for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it )
  54.242 +      if( !isalnum( *it) )
  54.243 +        *it = '_';
  54.244 +
  54.245 +    ReadMaterialSurface( materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
  54.246 +    if( !materials[a].ambient.texture.empty() ) numTextures++;
  54.247 +    ReadMaterialSurface( materials[a].diffuse, mat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE);
  54.248 +    if( !materials[a].diffuse.texture.empty() ) numTextures++;
  54.249 +    ReadMaterialSurface( materials[a].specular, mat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR);
  54.250 +    if( !materials[a].specular.texture.empty() ) numTextures++;
  54.251 +    ReadMaterialSurface( materials[a].emissive, mat, aiTextureType_EMISSIVE, AI_MATKEY_COLOR_EMISSIVE);
  54.252 +    if( !materials[a].emissive.texture.empty() ) numTextures++;
  54.253 +    ReadMaterialSurface( materials[a].reflective, mat, aiTextureType_REFLECTION, AI_MATKEY_COLOR_REFLECTIVE);
  54.254 +    if( !materials[a].reflective.texture.empty() ) numTextures++;
  54.255 +    ReadMaterialSurface( materials[a].normal, mat, aiTextureType_NORMALS, NULL, 0, 0);
  54.256 +    if( !materials[a].normal.texture.empty() ) numTextures++;
  54.257 +
  54.258 +    mat->Get( AI_MATKEY_SHININESS, materials[a].shininess);
  54.259 +  }
  54.260 +
  54.261 +  // output textures if present
  54.262 +  if( numTextures > 0 )
  54.263 +  {
  54.264 +    mOutput << startstr << "<library_images>" << endstr; 
  54.265 +    PushTag();
  54.266 +    for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
  54.267 +    { 
  54.268 +      const Material& mat = *it;
  54.269 +      WriteImageEntry( mat.ambient, mat.name + "-ambient-image");
  54.270 +      WriteImageEntry( mat.diffuse, mat.name + "-diffuse-image");
  54.271 +      WriteImageEntry( mat.specular, mat.name + "-specular-image");
  54.272 +      WriteImageEntry( mat.emissive, mat.name + "-emissive-image");
  54.273 +      WriteImageEntry( mat.reflective, mat.name + "-reflective-image");
  54.274 +      WriteImageEntry( mat.normal, mat.name + "-normal-image");
  54.275 +    }
  54.276 +    PopTag();
  54.277 +    mOutput << startstr << "</library_images>" << endstr;
  54.278 +  }
  54.279 +
  54.280 +  // output effects - those are the actual carriers of information
  54.281 +  if( !materials.empty() )
  54.282 +  {
  54.283 +    mOutput << startstr << "<library_effects>" << endstr;
  54.284 +    PushTag();
  54.285 +    for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
  54.286 +    {
  54.287 +      const Material& mat = *it;
  54.288 +      // this is so ridiculous it must be right
  54.289 +      mOutput << startstr << "<effect id=\"" << mat.name << "-fx\" name=\"" << mat.name << "\">" << endstr;
  54.290 +      PushTag();
  54.291 +      mOutput << startstr << "<profile_COMMON>" << endstr;
  54.292 +      PushTag();
  54.293 +
  54.294 +      // write sampler- and surface params for the texture entries
  54.295 +      WriteTextureParamEntry( mat.emissive, "emissive", mat.name);
  54.296 +      WriteTextureParamEntry( mat.ambient, "ambient", mat.name);
  54.297 +      WriteTextureParamEntry( mat.diffuse, "diffuse", mat.name);
  54.298 +      WriteTextureParamEntry( mat.specular, "specular", mat.name);
  54.299 +      WriteTextureParamEntry( mat.reflective, "reflective", mat.name);
  54.300 +
  54.301 +      mOutput << startstr << "<technique sid=\"standard\">" << endstr;
  54.302 +      PushTag();
  54.303 +      mOutput << startstr << "<phong>" << endstr;
  54.304 +      PushTag();
  54.305 +
  54.306 +      WriteTextureColorEntry( mat.emissive, "emission", mat.name + "-emissive-sampler");
  54.307 +      WriteTextureColorEntry( mat.ambient, "ambient", mat.name + "-ambient-sampler");
  54.308 +      WriteTextureColorEntry( mat.diffuse, "diffuse", mat.name + "-diffuse-sampler");
  54.309 +      WriteTextureColorEntry( mat.specular, "specular", mat.name + "-specular-sampler");
  54.310 +
  54.311 +      mOutput << startstr << "<shininess>" << endstr;
  54.312 +      PushTag();
  54.313 +      mOutput << startstr << "<float sid=\"shininess\">" << mat.shininess << "</float>" << endstr;
  54.314 +      PopTag();
  54.315 +      mOutput << startstr << "</shininess>" << endstr;
  54.316 +
  54.317 +      WriteTextureColorEntry( mat.reflective, "reflective", mat.name + "-reflective-sampler");
  54.318 +
  54.319 +  // deactivated because the Collada spec PHONG model does not allow other textures.
  54.320 +  //    if( !mat.normal.texture.empty() )
  54.321 +  //      WriteTextureColorEntry( mat.normal, "bump", mat.name + "-normal-sampler");
  54.322 +
  54.323 +
  54.324 +      PopTag();
  54.325 +      mOutput << startstr << "</phong>" << endstr;
  54.326 +      PopTag();
  54.327 +      mOutput << startstr << "</technique>" << endstr;
  54.328 +      PopTag();
  54.329 +      mOutput << startstr << "</profile_COMMON>" << endstr;
  54.330 +      PopTag();
  54.331 +      mOutput << startstr << "</effect>" << endstr;
  54.332 +    }
  54.333 +    PopTag();
  54.334 +    mOutput << startstr << "</library_effects>" << endstr;
  54.335 +
  54.336 +    // write materials - they're just effect references
  54.337 +    mOutput << startstr << "<library_materials>" << endstr;
  54.338 +    PushTag();
  54.339 +    for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
  54.340 +    {
  54.341 +      const Material& mat = *it;
  54.342 +      mOutput << startstr << "<material id=\"" << mat.name << "\" name=\"" << mat.name << "\">" << endstr;
  54.343 +      PushTag();
  54.344 +      mOutput << startstr << "<instance_effect url=\"#" << mat.name << "-fx\"/>" << endstr;
  54.345 +      PopTag();
  54.346 +      mOutput << startstr << "</material>" << endstr;
  54.347 +    }
  54.348 +    PopTag();
  54.349 +    mOutput << startstr << "</library_materials>" << endstr;
  54.350 +  }
  54.351 +}
  54.352 +
  54.353 +// ------------------------------------------------------------------------------------------------
  54.354 +// Writes the geometry library
  54.355 +void ColladaExporter::WriteGeometryLibrary()
  54.356 +{
  54.357 +	mOutput << startstr << "<library_geometries>" << endstr;
  54.358 +	PushTag();
  54.359 +
  54.360 +	for( size_t a = 0; a < mScene->mNumMeshes; ++a)
  54.361 +		WriteGeometry( a);
  54.362 +
  54.363 +	PopTag();
  54.364 +	mOutput << startstr << "</library_geometries>" << endstr;
  54.365 +}
  54.366 +
  54.367 +// ------------------------------------------------------------------------------------------------
  54.368 +// Writes the given mesh
  54.369 +void ColladaExporter::WriteGeometry( size_t pIndex)
  54.370 +{
  54.371 +	const aiMesh* mesh = mScene->mMeshes[pIndex];
  54.372 +	std::string idstr = GetMeshId( pIndex);
  54.373 +
  54.374 +  if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
  54.375 +    return;
  54.376 +
  54.377 +	// opening tag
  54.378 +	mOutput << startstr << "<geometry id=\"" << idstr << "\" name=\"" << idstr << "_name\" >" << endstr;
  54.379 +	PushTag();
  54.380 +
  54.381 +	mOutput << startstr << "<mesh>" << endstr;
  54.382 +	PushTag();
  54.383 +
  54.384 +	// Positions
  54.385 +	WriteFloatArray( idstr + "-positions", FloatType_Vector, (float*) mesh->mVertices, mesh->mNumVertices);
  54.386 +	// Normals, if any
  54.387 +	if( mesh->HasNormals() )
  54.388 +		WriteFloatArray( idstr + "-normals", FloatType_Vector, (float*) mesh->mNormals, mesh->mNumVertices);
  54.389 +
  54.390 +	// texture coords
  54.391 +	for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a)
  54.392 +	{
  54.393 +		if( mesh->HasTextureCoords( a) )
  54.394 +		{
  54.395 +			WriteFloatArray( idstr + "-tex" + boost::lexical_cast<std::string> (a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
  54.396 +				(float*) mesh->mTextureCoords[a], mesh->mNumVertices);
  54.397 +		}
  54.398 +	}
  54.399 +
  54.400 +	// vertex colors
  54.401 +	for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a)
  54.402 +	{
  54.403 +		if( mesh->HasVertexColors( a) )
  54.404 +			WriteFloatArray( idstr + "-color" + boost::lexical_cast<std::string> (a), FloatType_Color, (float*) mesh->mColors[a], mesh->mNumVertices);
  54.405 +	}
  54.406 +
  54.407 +	// assemble vertex structure
  54.408 +	mOutput << startstr << "<vertices id=\"" << idstr << "-vertices" << "\">" << endstr;
  54.409 +	PushTag();
  54.410 +	mOutput << startstr << "<input semantic=\"POSITION\" source=\"#" << idstr << "-positions\" />" << endstr;
  54.411 +	if( mesh->HasNormals() )
  54.412 +		mOutput << startstr << "<input semantic=\"NORMAL\" source=\"#" << idstr << "-normals\" />" << endstr;
  54.413 +	for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
  54.414 +	{
  54.415 +		if( mesh->HasTextureCoords( a) )
  54.416 +			mOutput << startstr << "<input semantic=\"TEXCOORD\" source=\"#" << idstr << "-tex" << a << "\" " /*<< "set=\"" << a << "\"" */ << " />" << endstr;
  54.417 +	}
  54.418 +	for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
  54.419 +	{
  54.420 +		if( mesh->HasVertexColors( a) )
  54.421 +			mOutput << startstr << "<input semantic=\"COLOR\" source=\"#" << idstr << "-color" << a << "\" " /*<< set=\"" << a << "\"" */ << " />" << endstr;
  54.422 +	}
  54.423 +	
  54.424 +	PopTag();
  54.425 +	mOutput << startstr << "</vertices>" << endstr;
  54.426 +
  54.427 +	// write face setup
  54.428 +	mOutput << startstr << "<polylist count=\"" << mesh->mNumFaces << "\" material=\"theresonlyone\">" << endstr;
  54.429 +	PushTag();
  54.430 +	mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstr << "-vertices\" />" << endstr;
  54.431 +	
  54.432 +	mOutput << startstr << "<vcount>";
  54.433 +	for( size_t a = 0; a < mesh->mNumFaces; ++a )
  54.434 +		mOutput << mesh->mFaces[a].mNumIndices << " ";
  54.435 +	mOutput << "</vcount>" << endstr;
  54.436 +	
  54.437 +	mOutput << startstr << "<p>";
  54.438 +	for( size_t a = 0; a < mesh->mNumFaces; ++a )
  54.439 +	{
  54.440 +		const aiFace& face = mesh->mFaces[a];
  54.441 +		for( size_t b = 0; b < face.mNumIndices; ++b )
  54.442 +			mOutput << face.mIndices[b] << " ";
  54.443 +	}
  54.444 +	mOutput << "</p>" << endstr;
  54.445 +	PopTag();
  54.446 +	mOutput << startstr << "</polylist>" << endstr;
  54.447 +
  54.448 +	// closing tags
  54.449 +	PopTag();
  54.450 +	mOutput << startstr << "</mesh>" << endstr;
  54.451 +	PopTag();
  54.452 +	mOutput << startstr << "</geometry>" << endstr;
  54.453 +}
  54.454 +
  54.455 +// ------------------------------------------------------------------------------------------------
  54.456 +// Writes a float array of the given type
  54.457 +void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataType pType, const float* pData, size_t pElementCount)
  54.458 +{
  54.459 +	size_t floatsPerElement = 0;
  54.460 +	switch( pType )
  54.461 +	{
  54.462 +		case FloatType_Vector: floatsPerElement = 3; break;
  54.463 +		case FloatType_TexCoord2: floatsPerElement = 2; break;
  54.464 +		case FloatType_TexCoord3: floatsPerElement = 3; break;
  54.465 +		case FloatType_Color: floatsPerElement = 3; break;
  54.466 +		default:
  54.467 +			return;
  54.468 +	}
  54.469 +
  54.470 +	std::string arrayId = pIdString + "-array";
  54.471 +
  54.472 +	mOutput << startstr << "<source id=\"" << pIdString << "\" name=\"" << pIdString << "\">" << endstr;
  54.473 +	PushTag();
  54.474 +
  54.475 +	// source array
  54.476 +	mOutput << startstr << "<float_array id=\"" << arrayId << "\" count=\"" << pElementCount * floatsPerElement << "\"> ";
  54.477 +	PushTag();
  54.478 +
  54.479 +	if( pType == FloatType_TexCoord2 )
  54.480 +	{
  54.481 +		for( size_t a = 0; a < pElementCount; ++a )
  54.482 +		{
  54.483 +			mOutput << pData[a*3+0] << " ";
  54.484 +			mOutput << pData[a*3+1] << " ";
  54.485 +		}
  54.486 +	} 
  54.487 +	else if( pType == FloatType_Color )
  54.488 +	{
  54.489 +		for( size_t a = 0; a < pElementCount; ++a )
  54.490 +		{
  54.491 +			mOutput << pData[a*4+0] << " ";
  54.492 +			mOutput << pData[a*4+1] << " ";
  54.493 +			mOutput << pData[a*4+2] << " ";
  54.494 +		}
  54.495 +	}
  54.496 +	else
  54.497 +	{
  54.498 +		for( size_t a = 0; a < pElementCount * floatsPerElement; ++a )
  54.499 +			mOutput << pData[a] << " ";
  54.500 +	}
  54.501 +	mOutput << "</float_array>" << endstr; 
  54.502 +	PopTag();
  54.503 +
  54.504 +	// the usual Collada fun. Let's bloat it even more!
  54.505 +	mOutput << startstr << "<technique_common>" << endstr;
  54.506 +	PushTag();
  54.507 +	mOutput << startstr << "<accessor count=\"" << pElementCount << "\" offset=\"0\" source=\"#" << arrayId << "\" stride=\"" << floatsPerElement << "\">" << endstr;
  54.508 +	PushTag();
  54.509 +
  54.510 +	switch( pType )
  54.511 +	{
  54.512 +		case FloatType_Vector:
  54.513 +			mOutput << startstr << "<param name=\"X\" type=\"float\" />" << endstr;
  54.514 +			mOutput << startstr << "<param name=\"Y\" type=\"float\" />" << endstr;
  54.515 +			mOutput << startstr << "<param name=\"Z\" type=\"float\" />" << endstr;
  54.516 +			break;
  54.517 +
  54.518 +		case FloatType_TexCoord2:
  54.519 +			mOutput << startstr << "<param name=\"S\" type=\"float\" />" << endstr;
  54.520 +			mOutput << startstr << "<param name=\"T\" type=\"float\" />" << endstr;
  54.521 +			break;
  54.522 +
  54.523 +		case FloatType_TexCoord3:
  54.524 +			mOutput << startstr << "<param name=\"S\" type=\"float\" />" << endstr;
  54.525 +			mOutput << startstr << "<param name=\"T\" type=\"float\" />" << endstr;
  54.526 +			mOutput << startstr << "<param name=\"P\" type=\"float\" />" << endstr;
  54.527 +			break;
  54.528 +
  54.529 +		case FloatType_Color:
  54.530 +			mOutput << startstr << "<param name=\"R\" type=\"float\" />" << endstr;
  54.531 +			mOutput << startstr << "<param name=\"G\" type=\"float\" />" << endstr;
  54.532 +			mOutput << startstr << "<param name=\"B\" type=\"float\" />" << endstr;
  54.533 +			break;
  54.534 +	}
  54.535 +
  54.536 +	PopTag();
  54.537 +	mOutput << startstr << "</accessor>" << endstr;
  54.538 +	PopTag();
  54.539 +	mOutput << startstr << "</technique_common>" << endstr;
  54.540 +	PopTag();
  54.541 +	mOutput << startstr << "</source>" << endstr;
  54.542 +}
  54.543 +
  54.544 +// ------------------------------------------------------------------------------------------------
  54.545 +// Writes the scene library
  54.546 +void ColladaExporter::WriteSceneLibrary()
  54.547 +{
  54.548 +	mOutput << startstr << "<library_visual_scenes>" << endstr;
  54.549 +	PushTag();
  54.550 +	mOutput << startstr << "<visual_scene id=\"myScene\" name=\"myScene\">" << endstr;
  54.551 +	PushTag();
  54.552 +
  54.553 +	// start recursive write at the root node
  54.554 +	WriteNode( mScene->mRootNode);
  54.555 +
  54.556 +	PopTag();
  54.557 +	mOutput << startstr << "</visual_scene>" << endstr;
  54.558 +	PopTag();
  54.559 +	mOutput << startstr << "</library_visual_scenes>" << endstr;
  54.560 +}
  54.561 +
  54.562 +// ------------------------------------------------------------------------------------------------
  54.563 +// Recursively writes the given node
  54.564 +void ColladaExporter::WriteNode( const aiNode* pNode)
  54.565 +{
  54.566 +	mOutput << startstr << "<node id=\"" << pNode->mName.data << "\" name=\"" << pNode->mName.data << "\">" << endstr;
  54.567 +	PushTag();
  54.568 +
  54.569 +	// write transformation - we can directly put the matrix there
  54.570 +	// TODO: (thom) decompose into scale - rot - quad to allow adressing it by animations afterwards
  54.571 +	const aiMatrix4x4& mat = pNode->mTransformation;
  54.572 +	mOutput << startstr << "<matrix>";
  54.573 +	mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " ";
  54.574 +	mOutput << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << " ";
  54.575 +	mOutput << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << " ";
  54.576 +	mOutput << mat.d1 << " " << mat.d2 << " " << mat.d3 << " " << mat.d4;
  54.577 +	mOutput << "</matrix>" << endstr;
  54.578 +
  54.579 +	// instance every geometry
  54.580 +	for( size_t a = 0; a < pNode->mNumMeshes; ++a )
  54.581 +	{
  54.582 +		const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]];
  54.583 +    // do not instanciate mesh if empty. I wonder how this could happen
  54.584 +    if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
  54.585 +      continue;
  54.586 +
  54.587 +		mOutput << startstr << "<instance_geometry url=\"#" << GetMeshId( pNode->mMeshes[a]) << "\">" << endstr;
  54.588 +		PushTag();
  54.589 +    mOutput << startstr << "<bind_material>" << endstr;
  54.590 +    PushTag();
  54.591 +    mOutput << startstr << "<technique_common>" << endstr;
  54.592 +    PushTag();
  54.593 +    mOutput << startstr << "<instance_material symbol=\"theresonlyone\" target=\"#" << materials[mesh->mMaterialIndex].name << "\" />" << endstr;
  54.594 +		PopTag();
  54.595 +    mOutput << startstr << "</technique_common>" << endstr;
  54.596 +    PopTag();
  54.597 +    mOutput << startstr << "</bind_material>" << endstr;
  54.598 +    PopTag();
  54.599 +		mOutput << startstr << "</instance_geometry>" << endstr;
  54.600 +	}
  54.601 +
  54.602 +	// recurse into subnodes
  54.603 +	for( size_t a = 0; a < pNode->mNumChildren; ++a )
  54.604 +		WriteNode( pNode->mChildren[a]);
  54.605 +
  54.606 +	PopTag();
  54.607 +	mOutput << startstr << "</node>" << endstr;
  54.608 +}
  54.609 +
  54.610 +#endif
  54.611 +#endif
  54.612 +
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/libs/assimp/ColladaExporter.h	Sat Feb 01 19:58:19 2014 +0200
    55.3 @@ -0,0 +1,147 @@
    55.4 +/*
    55.5 +Open Asset Import Library (assimp)
    55.6 +----------------------------------------------------------------------
    55.7 +
    55.8 +Copyright (c) 2006-2012, assimp team
    55.9 +All rights reserved.
   55.10 +
   55.11 +Redistribution and use of this software in source and binary forms, 
   55.12 +with or without modification, are permitted provided that the 
   55.13 +following conditions are met:
   55.14 +
   55.15 +* Redistributions of source code must retain the above
   55.16 +  copyright notice, this list of conditions and the
   55.17 +  following disclaimer.
   55.18 +
   55.19 +* Redistributions in binary form must reproduce the above
   55.20 +  copyright notice, this list of conditions and the
   55.21 +  following disclaimer in the documentation and/or other
   55.22 +  materials provided with the distribution.
   55.23 +
   55.24 +* Neither the name of the assimp team, nor the names of its
   55.25 +  contributors may be used to endorse or promote products
   55.26 +  derived from this software without specific prior
   55.27 +  written permission of the assimp team.
   55.28 +
   55.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   55.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   55.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   55.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   55.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   55.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   55.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   55.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   55.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   55.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   55.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   55.40 +
   55.41 +----------------------------------------------------------------------
   55.42 +*/
   55.43 +
   55.44 +/** @file ColladaExporter.h
   55.45 + * Declares the exporter class to write a scene to a Collada file
   55.46 + */
   55.47 +#ifndef AI_COLLADAEXPORTER_H_INC
   55.48 +#define AI_COLLADAEXPORTER_H_INC
   55.49 +
   55.50 +#include "assimp/ai_assert.h"
   55.51 +#include <sstream>
   55.52 +
   55.53 +struct aiScene;
   55.54 +struct aiNode;
   55.55 +
   55.56 +namespace Assimp	
   55.57 +{
   55.58 +
   55.59 +/// Helper class to export a given scene to a Collada file. Just for my personal
   55.60 +/// comfort when implementing it.
   55.61 +class ColladaExporter
   55.62 +{
   55.63 +public:
   55.64 +	/// Constructor for a specific scene to export
   55.65 +	ColladaExporter( const aiScene* pScene);
   55.66 +
   55.67 +protected:
   55.68 +	/// Starts writing the contents
   55.69 +	void WriteFile();
   55.70 +
   55.71 +	/// Writes the asset header
   55.72 +	void WriteHeader();
   55.73 +
   55.74 +  /// Writes the material setup
   55.75 +  void WriteMaterials();
   55.76 +
   55.77 +	/// Writes the geometry library
   55.78 +	void WriteGeometryLibrary();
   55.79 +
   55.80 +	/// Writes the given mesh
   55.81 +	void WriteGeometry( size_t pIndex);
   55.82 +
   55.83 +	enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color };
   55.84 +
   55.85 +	/// Writes a float array of the given type
   55.86 +	void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const float* pData, size_t pElementCount);
   55.87 +
   55.88 +	/// Writes the scene library
   55.89 +	void WriteSceneLibrary();
   55.90 +
   55.91 +	/// Recursively writes the given node
   55.92 +	void WriteNode( const aiNode* pNode);
   55.93 +
   55.94 +	/// Enters a new xml element, which increases the indentation
   55.95 +	void PushTag() { startstr.append( "  "); }
   55.96 +	/// Leaves an element, decreasing the indentation
   55.97 +	void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); }
   55.98 +
   55.99 +	/// Creates a mesh ID for the given mesh
  55.100 +	std::string GetMeshId( size_t pIndex) const { return std::string( "meshId" ) + boost::lexical_cast<std::string> (pIndex); }
  55.101 +
  55.102 +public:
  55.103 +	/// Stringstream to write all output into
  55.104 +	std::stringstream mOutput;
  55.105 +
  55.106 +protected:
  55.107 +	/// The scene to be written
  55.108 +	const aiScene* mScene;
  55.109 +
  55.110 +	/// current line start string, contains the current indentation for simple stream insertion
  55.111 +	std::string startstr;
  55.112 +	/// current line end string for simple stream insertion
  55.113 +	std::string endstr;
  55.114 +
  55.115 +  // pair of color and texture - texture precedences color
  55.116 +  struct Surface 
  55.117 +  { 
  55.118 +    aiColor4D color; 
  55.119 +    std::string texture; 
  55.120 +    size_t channel; 
  55.121 +    Surface() { channel = 0; }
  55.122 +  };
  55.123 +
  55.124 +  // summarize a material in an convinient way. 
  55.125 +  struct Material
  55.126 +  {
  55.127 +    std::string name;
  55.128 +    Surface ambient, diffuse, specular, emissive, reflective, normal;
  55.129 +    float shininess; /// specular exponent
  55.130 +
  55.131 +    Material() { shininess = 16.0f; }
  55.132 +  };
  55.133 +
  55.134 +  std::vector<Material> materials;
  55.135 +
  55.136 +protected:
  55.137 +  /// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
  55.138 +  /// Reads a single surface entry from the given material keys
  55.139 +  void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex);
  55.140 +  /// Writes an image entry for the given surface
  55.141 +  void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd);
  55.142 +  /// Writes the two parameters necessary for referencing a texture in an effect entry
  55.143 +  void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName);
  55.144 +  /// Writes a color-or-texture entry into an effect definition
  55.145 +  void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName);
  55.146 +};
  55.147 +
  55.148 +}
  55.149 +
  55.150 +#endif // !! AI_COLLADAEXPORTER_H_INC
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/libs/assimp/ColladaHelper.h	Sat Feb 01 19:58:19 2014 +0200
    56.3 @@ -0,0 +1,602 @@
    56.4 +/** Helper structures for the Collada loader */
    56.5 +
    56.6 +/*
    56.7 +Open Asset Import Library (assimp)
    56.8 +----------------------------------------------------------------------
    56.9 +
   56.10 +Copyright (c) 2006-2012, assimp team
   56.11 +All rights reserved.
   56.12 +
   56.13 +Redistribution and use of this software in source and binary forms, 
   56.14 +with or without modification, are permitted provided that the 
   56.15 +following conditions are met:
   56.16 +
   56.17 +* Redistributions of source code must retain the above
   56.18 +copyright notice, this list of conditions and the
   56.19 +following disclaimer.
   56.20 +
   56.21 +* Redistributions in binary form must reproduce the above
   56.22 +copyright notice, this list of conditions and the
   56.23 +following disclaimer in the documentation and/or other
   56.24 +materials provided with the distribution.
   56.25 +
   56.26 +* Neither the name of the assimp team, nor the names of its
   56.27 +contributors may be used to endorse or promote products
   56.28 +derived from this software without specific prior
   56.29 +written permission of the assimp team.
   56.30 +
   56.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   56.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   56.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   56.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   56.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   56.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   56.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   56.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   56.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   56.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   56.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   56.42 +
   56.43 +----------------------------------------------------------------------
   56.44 +*/
   56.45 +
   56.46 +#ifndef AI_COLLADAHELPER_H_INC
   56.47 +#define AI_COLLADAHELPER_H_INC
   56.48 +
   56.49 +namespace Assimp	{
   56.50 +namespace Collada		{
   56.51 +
   56.52 +/** Collada file versions which evolved during the years ... */
   56.53 +enum FormatVersion
   56.54 +{
   56.55 +	FV_1_5_n,
   56.56 +	FV_1_4_n,
   56.57 +	FV_1_3_n
   56.58 +};
   56.59 +
   56.60 +
   56.61 +/** Transformation types that can be applied to a node */
   56.62 +enum TransformType
   56.63 +{
   56.64 +	TF_LOOKAT,
   56.65 +	TF_ROTATE,
   56.66 +	TF_TRANSLATE,
   56.67 +	TF_SCALE,
   56.68 +	TF_SKEW,
   56.69 +	TF_MATRIX
   56.70 +};
   56.71 +
   56.72 +/** Different types of input data to a vertex or face */
   56.73 +enum InputType
   56.74 +{
   56.75 +	IT_Invalid,
   56.76 +	IT_Vertex,  // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
   56.77 +	IT_Position,
   56.78 +	IT_Normal,
   56.79 +	IT_Texcoord,
   56.80 +	IT_Color,
   56.81 +	IT_Tangent,
   56.82 +	IT_Bitangent
   56.83 +};
   56.84 +
   56.85 +/** Contains all data for one of the different transformation types */
   56.86 +struct Transform
   56.87 +{
   56.88 +	std::string mID;  ///< SID of the transform step, by which anim channels address their target node
   56.89 +	TransformType mType;
   56.90 +	float f[16]; ///< Interpretation of data depends on the type of the transformation 
   56.91 +};
   56.92 +
   56.93 +/** A collada camera. */
   56.94 +struct Camera
   56.95 +{
   56.96 +	Camera()
   56.97 +		:	mOrtho  (false)
   56.98 +		,	mHorFov (10e10f)
   56.99 +		,	mVerFov (10e10f)
  56.100 +		,	mAspect (10e10f)
  56.101 +		,	mZNear  (0.1f)
  56.102 +		,	mZFar   (1000.f)
  56.103 +	{}
  56.104 +
  56.105 +	// Name of camera
  56.106 +	std::string mName;
  56.107 +
  56.108 +	// True if it is an orthografic camera
  56.109 +	bool mOrtho;
  56.110 +
  56.111 +	//! Horizontal field of view in degrees
  56.112 +	float mHorFov;
  56.113 +
  56.114 +	//! Vertical field of view in degrees
  56.115 +	float mVerFov;
  56.116 +
  56.117 +	//! Screen aspect
  56.118 +	float mAspect;
  56.119 +
  56.120 +	//! Near& far z
  56.121 +	float mZNear, mZFar;
  56.122 +};
  56.123 +
  56.124 +#define aiLightSource_AMBIENT 0xdeaddead
  56.125 +#define ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET 1e9f
  56.126 +
  56.127 +/** A collada light source. */
  56.128 +struct Light
  56.129 +{	
  56.130 +	Light()
  56.131 +		:	mAttConstant     (1.f)
  56.132 +		,	mAttLinear       (0.f)
  56.133 +		,	mAttQuadratic    (0.f)
  56.134 +		,	mFalloffAngle    (180.f)
  56.135 +		,	mFalloffExponent (0.f)
  56.136 +		,	mPenumbraAngle	 (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
  56.137 +		,	mOuterAngle		 (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
  56.138 +		,	mIntensity		 (1.f)
  56.139 +	{}
  56.140 +
  56.141 +	//! Type of the light source aiLightSourceType + ambient
  56.142 +	unsigned int mType;
  56.143 +
  56.144 +	//! Color of the light
  56.145 +	aiColor3D mColor;
  56.146 +
  56.147 +	//! Light attenuation
  56.148 +	float mAttConstant,mAttLinear,mAttQuadratic;
  56.149 +
  56.150 +	//! Spot light falloff
  56.151 +	float mFalloffAngle;
  56.152 +	float mFalloffExponent;
  56.153 +
  56.154 +	// -----------------------------------------------------
  56.155 +	// FCOLLADA extension from here
  56.156 +
  56.157 +	//! ... related stuff from maja and max extensions
  56.158 +	float mPenumbraAngle;
  56.159 +	float mOuterAngle;
  56.160 +
  56.161 +	//! Common light intensity
  56.162 +	float mIntensity;
  56.163 +};
  56.164 +
  56.165 +/** Short vertex index description */
  56.166 +struct InputSemanticMapEntry
  56.167 +{
  56.168 +	InputSemanticMapEntry()
  56.169 +		:	mSet	(0)
  56.170 +	{}
  56.171 +
  56.172 +	//! Index of set, optional
  56.173 +	unsigned int mSet;
  56.174 +
  56.175 +	//! Name of referenced vertex input
  56.176 +	InputType mType;
  56.177 +};
  56.178 +
  56.179 +/** Table to map from effect to vertex input semantics */
  56.180 +struct SemanticMappingTable
  56.181 +{
  56.182 +	//! Name of material
  56.183 +	std::string mMatName;
  56.184 +
  56.185 +	//! List of semantic map commands, grouped by effect semantic name
  56.186 +	std::map<std::string, InputSemanticMapEntry> mMap;
  56.187 +
  56.188 +	//! For std::find
  56.189 +	bool operator == (const std::string& s) const {
  56.190 +		return s == mMatName;
  56.191 +	}
  56.192 +};
  56.193 +
  56.194 +/** A reference to a mesh inside a node, including materials assigned to the various subgroups.
  56.195 + * The ID refers to either a mesh or a controller which specifies the mesh
  56.196 + */
  56.197 +struct MeshInstance
  56.198 +{
  56.199 +	///< ID of the mesh or controller to be instanced
  56.200 +	std::string mMeshOrController;
  56.201 +
  56.202 +	///< Map of materials by the subgroup ID they're applied to
  56.203 +	std::map<std::string, SemanticMappingTable> mMaterials;
  56.204 +};
  56.205 +
  56.206 +/** A reference to a camera inside a node*/
  56.207 +struct CameraInstance
  56.208 +{
  56.209 +	 ///< ID of the camera
  56.210 +	std::string mCamera;
  56.211 +};
  56.212 +
  56.213 +/** A reference to a light inside a node*/
  56.214 +struct LightInstance
  56.215 +{
  56.216 +	 ///< ID of the camera
  56.217 +	std::string mLight;
  56.218 +};
  56.219 +
  56.220 +/** A reference to a node inside a node*/
  56.221 +struct NodeInstance
  56.222 +{
  56.223 +	 ///< ID of the node
  56.224 +	std::string mNode;
  56.225 +};
  56.226 +
  56.227 +/** A node in a scene hierarchy */
  56.228 +struct Node
  56.229 +{
  56.230 +	std::string mName;
  56.231 +	std::string mID;
  56.232 +  std::string mSID;
  56.233 +	Node* mParent;
  56.234 +	std::vector<Node*> mChildren;
  56.235 +
  56.236 +	/** Operations in order to calculate the resulting transformation to parent. */
  56.237 +	std::vector<Transform> mTransforms;
  56.238 +
  56.239 +	/** Meshes at this node */
  56.240 +	std::vector<MeshInstance> mMeshes;    
  56.241 +
  56.242 +	/** Lights at this node */
  56.243 +	std::vector<LightInstance> mLights;  
  56.244 +
  56.245 +	/** Cameras at this node */
  56.246 +	std::vector<CameraInstance> mCameras; 
  56.247 +
  56.248 +	/** Node instances at this node */
  56.249 +	std::vector<NodeInstance> mNodeInstances;
  56.250 +
  56.251 +	/** Rootnodes: Name of primary camera, if any */
  56.252 +	std::string mPrimaryCamera;
  56.253 +
  56.254 +	//! Constructor. Begin with a zero parent
  56.255 +	Node() { 
  56.256 +		mParent = NULL;
  56.257 +	}
  56.258 +
  56.259 +	//! Destructor: delete all children subsequently
  56.260 +	~Node() { 
  56.261 +		for( std::vector<Node*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) 
  56.262 +			delete *it; 
  56.263 +	}
  56.264 +};
  56.265 +
  56.266 +/** Data source array: either floats or strings */
  56.267 +struct Data
  56.268 +{
  56.269 +	bool mIsStringArray;
  56.270 +	std::vector<float> mValues;
  56.271 +	std::vector<std::string> mStrings;
  56.272 +};
  56.273 +
  56.274 +/** Accessor to a data array */
  56.275 +struct Accessor
  56.276 +{
  56.277 +	size_t mCount;   // in number of objects
  56.278 +	size_t mSize;    // size of an object, in elements (floats or strings, mostly 1)
  56.279 +	size_t mOffset;  // in number of values
  56.280 +	size_t mStride;  // Stride in number of values
  56.281 +	std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore. 
  56.282 +	size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, thats XYZ, for a color RGBA and so on.
  56.283 +						  // For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
  56.284 +	std::string mSource;   // URL of the source array
  56.285 +	mutable const Data* mData; // Pointer to the source array, if resolved. NULL else
  56.286 +
  56.287 +	Accessor() 
  56.288 +	{ 
  56.289 +		mCount = 0; mSize = 0; mOffset = 0; mStride = 0; mData = NULL; 
  56.290 +		mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
  56.291 +	}
  56.292 +};
  56.293 +
  56.294 +/** A single face in a mesh */
  56.295 +struct Face
  56.296 +{
  56.297 +	std::vector<size_t> mIndices;
  56.298 +};
  56.299 +
  56.300 +/** An input channel for mesh data, referring to a single accessor */
  56.301 +struct InputChannel
  56.302 +{
  56.303 +	InputType mType;      // Type of the data
  56.304 +	size_t mIndex;		  // Optional index, if multiple sets of the same data type are given
  56.305 +	size_t mOffset;       // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
  56.306 +	std::string mAccessor; // ID of the accessor where to read the actual values from.
  56.307 +	mutable const Accessor* mResolved; // Pointer to the accessor, if resolved. NULL else
  56.308 +
  56.309 +	InputChannel() { mType = IT_Invalid; mIndex = 0; mOffset = 0; mResolved = NULL; }
  56.310 +};
  56.311 +
  56.312 +/** Subset of a mesh with a certain material */
  56.313 +struct SubMesh
  56.314 +{
  56.315 +	std::string mMaterial; ///< subgroup identifier
  56.316 +	size_t mNumFaces; ///< number of faces in this submesh
  56.317 +};
  56.318 +
  56.319 +/** Contains data for a single mesh */
  56.320 +struct Mesh
  56.321 +{
  56.322 +	Mesh()
  56.323 +	{
  56.324 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
  56.325 +			mNumUVComponents[i] = 2;
  56.326 +	}
  56.327 +
  56.328 +	// just to check if there's some sophisticated addressing involved...
  56.329 +	// which we don't support, and therefore should warn about.
  56.330 +	std::string mVertexID; 
  56.331 +
  56.332 +	// Vertex data addressed by vertex indices
  56.333 +	std::vector<InputChannel> mPerVertexData; 
  56.334 +
  56.335 +	// actual mesh data, assembled on encounter of a <p> element. Verbose format, not indexed
  56.336 +	std::vector<aiVector3D> mPositions;
  56.337 +	std::vector<aiVector3D> mNormals;
  56.338 +	std::vector<aiVector3D> mTangents;
  56.339 +	std::vector<aiVector3D> mBitangents;
  56.340 +	std::vector<aiVector3D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
  56.341 +	std::vector<aiColor4D>  mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
  56.342 +
  56.343 +	unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
  56.344 +
  56.345 +	// Faces. Stored are only the number of vertices for each face.
  56.346 +	// 1 == point, 2 == line, 3 == triangle, 4+ == poly
  56.347 +	std::vector<size_t> mFaceSize;
  56.348 +	
  56.349 +	// Position indices for all faces in the sequence given in mFaceSize - 
  56.350 +	// necessary for bone weight assignment
  56.351 +	std::vector<size_t> mFacePosIndices;
  56.352 +
  56.353 +	// Submeshes in this mesh, each with a given material
  56.354 +	std::vector<SubMesh> mSubMeshes;
  56.355 +};
  56.356 +
  56.357 +/** Which type of primitives the ReadPrimitives() function is going to read */
  56.358 +enum PrimitiveType
  56.359 +{
  56.360 +	Prim_Invalid,
  56.361 +	Prim_Lines,
  56.362 +	Prim_LineStrip,
  56.363 +	Prim_Triangles,
  56.364 +	Prim_TriStrips,
  56.365 +	Prim_TriFans,
  56.366 +	Prim_Polylist,
  56.367 +	Prim_Polygon
  56.368 +};
  56.369 +
  56.370 +/** A skeleton controller to deform a mesh with the use of joints */
  56.371 +struct Controller
  56.372 +{
  56.373 +	// the URL of the mesh deformed by the controller.
  56.374 +	std::string mMeshId; 
  56.375 +
  56.376 +	// accessor URL of the joint names
  56.377 +	std::string mJointNameSource;
  56.378 +
  56.379 +  ///< The bind shape matrix, as array of floats. I'm not sure what this matrix actually describes, but it can't be ignored in all cases
  56.380 +  float mBindShapeMatrix[16];
  56.381 +
  56.382 +	// accessor URL of the joint inverse bind matrices
  56.383 +	std::string mJointOffsetMatrixSource;
  56.384 +
  56.385 +	// input channel: joint names. 
  56.386 +	InputChannel mWeightInputJoints;
  56.387 +	// input channel: joint weights
  56.388 +	InputChannel mWeightInputWeights;
  56.389 +
  56.390 +	// Number of weights per vertex.
  56.391 +	std::vector<size_t> mWeightCounts;
  56.392 +
  56.393 +	// JointIndex-WeightIndex pairs for all vertices
  56.394 +	std::vector< std::pair<size_t, size_t> > mWeights;
  56.395 +};
  56.396 +
  56.397 +/** A collada material. Pretty much the only member is a reference to an effect. */
  56.398 +struct Material
  56.399 +{
  56.400 +	std::string mEffect;
  56.401 +};
  56.402 +
  56.403 +/** Type of the effect param */
  56.404 +enum ParamType
  56.405 +{
  56.406 +	Param_Sampler,
  56.407 +	Param_Surface
  56.408 +};
  56.409 +
  56.410 +/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */
  56.411 +struct EffectParam
  56.412 +{
  56.413 +	ParamType mType;
  56.414 +	std::string mReference; // to which other thing the param is referring to. 
  56.415 +};
  56.416 +
  56.417 +/** Shading type supported by the standard effect spec of Collada */
  56.418 +enum ShadeType
  56.419 +{
  56.420 +	Shade_Invalid,
  56.421 +	Shade_Constant,
  56.422 +	Shade_Lambert,
  56.423 +	Shade_Phong,
  56.424 +	Shade_Blinn
  56.425 +};
  56.426 +
  56.427 +/** Represents a texture sampler in collada */
  56.428 +struct Sampler
  56.429 +{
  56.430 +	Sampler()
  56.431 +		:	mWrapU		(true)
  56.432 +		,	mWrapV		(true)
  56.433 +		,	mMirrorU	()
  56.434 +		,	mMirrorV	()
  56.435 +		,	mOp			(aiTextureOp_Multiply)
  56.436 +		,	mUVId		(UINT_MAX)
  56.437 +		,	mWeighting  (1.f)
  56.438 +		,	mMixWithPrevious (1.f)
  56.439 +	{}
  56.440 +
  56.441 +	/** Name of image reference
  56.442 +	 */
  56.443 +	std::string mName;
  56.444 +
  56.445 +	/** Wrap U?
  56.446 +	 */
  56.447 +	bool mWrapU;
  56.448 +
  56.449 +	/** Wrap V?
  56.450 +	 */
  56.451 +	bool mWrapV;
  56.452 +
  56.453 +	/** Mirror U?
  56.454 +	 */
  56.455 +	bool mMirrorU;
  56.456 +
  56.457 +	/** Mirror V?
  56.458 +	 */
  56.459 +	bool mMirrorV;
  56.460 +
  56.461 +	/** Blend mode
  56.462 +	 */
  56.463 +	aiTextureOp mOp;
  56.464 +
  56.465 +	/** UV transformation
  56.466 +	 */
  56.467 +	aiUVTransform mTransform;
  56.468 +
  56.469 +	/** Name of source UV channel
  56.470 +	 */
  56.471 +	std::string mUVChannel;
  56.472 +
  56.473 +	/** Resolved UV channel index or UINT_MAX if not known
  56.474 +	 */
  56.475 +	unsigned int mUVId;
  56.476 +
  56.477 +	// OKINO/MAX3D extensions from here
  56.478 +	// -------------------------------------------------------
  56.479 +
  56.480 +	/** Weighting factor
  56.481 +	 */
  56.482 +	float mWeighting;
  56.483 +
  56.484 +	/** Mixing factor from OKINO
  56.485 +	 */
  56.486 +	float mMixWithPrevious;
  56.487 +};
  56.488 +
  56.489 +/** A collada effect. Can contain about anything according to the Collada spec,
  56.490 +    but we limit our version to a reasonable subset. */
  56.491 +struct Effect
  56.492 +{
  56.493 +	// Shading mode
  56.494 +	ShadeType mShadeType;
  56.495 +
  56.496 +	// Colors
  56.497 +	aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular,
  56.498 +		mTransparent, mReflective;
  56.499 +
  56.500 +	// Textures
  56.501 +	Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular,
  56.502 +		mTexTransparent, mTexBump, mTexReflective;
  56.503 +
  56.504 +	// Scalar factory
  56.505 +	float mShininess, mRefractIndex, mReflectivity;
  56.506 +	float mTransparency;
  56.507 +
  56.508 +	// local params referring to each other by their SID
  56.509 +	typedef std::map<std::string, Collada::EffectParam> ParamLibrary;
  56.510 +	ParamLibrary mParams;
  56.511 +
  56.512 +	// MAX3D extensions
  56.513 +	// ---------------------------------------------------------
  56.514 +	// Double-sided?
  56.515 +	bool mDoubleSided, mWireframe, mFaceted;
  56.516 +	
  56.517 +	Effect()
  56.518 +		: mShadeType    (Shade_Phong)
  56.519 +		, mEmissive		( 0, 0, 0, 1)
  56.520 +		, mAmbient		( 0.1f, 0.1f, 0.1f, 1)
  56.521 +		, mDiffuse		( 0.6f, 0.6f, 0.6f, 1)
  56.522 +		, mSpecular		( 0.4f, 0.4f, 0.4f, 1)
  56.523 +		, mTransparent	( 0, 0, 0, 1)
  56.524 +		, mShininess    (10.0f)
  56.525 +		, mRefractIndex (1.f)
  56.526 +		, mReflectivity (1.f)
  56.527 +		, mTransparency (0.f)
  56.528 +		, mDoubleSided	(false)
  56.529 +		, mWireframe    (false)
  56.530 +		, mFaceted      (false)
  56.531 +	{ 
  56.532 +	}
  56.533 +};
  56.534 +
  56.535 +/** An image, meaning texture */
  56.536 +struct Image
  56.537 +{
  56.538 +	std::string mFileName;
  56.539 +
  56.540 +	/** If image file name is zero, embedded image data
  56.541 +	 */
  56.542 +	std::vector<uint8_t> mImageData;
  56.543 +
  56.544 +	/** If image file name is zero, file format of
  56.545 +	 *  embedded image data.
  56.546 +	 */
  56.547 +	std::string mEmbeddedFormat;
  56.548 +
  56.549 +};
  56.550 +
  56.551 +/** An animation channel. */
  56.552 +struct AnimationChannel
  56.553 +{
  56.554 +	/** URL of the data to animate. Could be about anything, but we support only the 
  56.555 +	 * "NodeID/TransformID.SubElement" notation 
  56.556 +	 */
  56.557 +	std::string mTarget;
  56.558 +
  56.559 +	/** Source URL of the time values. Collada calls them "input". Meh. */
  56.560 +	std::string mSourceTimes;
  56.561 +	/** Source URL of the value values. Collada calls them "output". */
  56.562 +	std::string mSourceValues;
  56.563 +};
  56.564 +
  56.565 +/** An animation. Container for 0-x animation channels or 0-x animations */
  56.566 +struct Animation
  56.567 +{
  56.568 +	/** Anim name */
  56.569 +	std::string mName;
  56.570 +
  56.571 +	/** the animation channels, if any */
  56.572 +	std::vector<AnimationChannel> mChannels;
  56.573 +
  56.574 +	/** the sub-animations, if any */
  56.575 +	std::vector<Animation*> mSubAnims;
  56.576 +
  56.577 +	/** Destructor */
  56.578 +	~Animation()
  56.579 +	{
  56.580 +		for( std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
  56.581 +			delete *it;
  56.582 +	}
  56.583 +};
  56.584 +
  56.585 +/** Description of a collada animation channel which has been determined to affect the current node */
  56.586 +struct ChannelEntry
  56.587 +{
  56.588 +	const Collada::AnimationChannel* mChannel; ///> the source channel
  56.589 +	std::string mTransformId;   // the ID of the transformation step of the node which is influenced
  56.590 +	size_t mTransformIndex; // Index into the node's transform chain to apply the channel to
  56.591 +	size_t mSubElement; // starting index inside the transform data
  56.592 +
  56.593 +	// resolved data references
  56.594 +	const Collada::Accessor* mTimeAccessor; ///> Collada accessor to the time values
  56.595 +	const Collada::Data* mTimeData; ///> Source data array for the time values
  56.596 +	const Collada::Accessor* mValueAccessor; ///> Collada accessor to the key value values
  56.597 +	const Collada::Data* mValueData; ///> Source datat array for the key value values
  56.598 +
  56.599 +	ChannelEntry() { mChannel = NULL; mSubElement = 0; }
  56.600 +};
  56.601 +
  56.602 +} // end of namespace Collada
  56.603 +} // end of namespace Assimp
  56.604 +
  56.605 +#endif // AI_COLLADAHELPER_H_INC
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/libs/assimp/ColladaLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
    57.3 @@ -0,0 +1,1559 @@
    57.4 +/*
    57.5 +---------------------------------------------------------------------------
    57.6 +Open Asset Import Library (assimp)
    57.7 +---------------------------------------------------------------------------
    57.8 +
    57.9 +Copyright (c) 2006-2012, assimp team
   57.10 +
   57.11 +All rights reserved.
   57.12 +
   57.13 +Redistribution and use of this software in source and binary forms, 
   57.14 +with or without modification, are permitted provided that the following 
   57.15 +conditions are met:
   57.16 +
   57.17 +* Redistributions of source code must retain the above
   57.18 +copyright notice, this list of conditions and the
   57.19 +following disclaimer.
   57.20 +
   57.21 +* Redistributions in binary form must reproduce the above
   57.22 +copyright notice, this list of conditions and the
   57.23 +following disclaimer in the documentation and/or other
   57.24 +materials provided with the distribution.
   57.25 +
   57.26 +* Neither the name of the assimp team, nor the names of its
   57.27 +contributors may be used to endorse or promote products
   57.28 +derived from this software without specific prior
   57.29 +written permission of the assimp team.
   57.30 +
   57.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   57.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   57.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   57.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   57.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   57.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   57.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   57.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   57.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   57.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   57.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   57.42 +---------------------------------------------------------------------------
   57.43 +*/
   57.44 +
   57.45 +/** @file Implementation of the Collada loader */
   57.46 +
   57.47 +#include "AssimpPCH.h"
   57.48 +#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
   57.49 +
   57.50 +#include "assimp/anim.h"
   57.51 +#include "ColladaLoader.h"
   57.52 +#include "ColladaParser.h"
   57.53 +
   57.54 +#include "fast_atof.h"
   57.55 +#include "ParsingUtils.h"
   57.56 +#include "SkeletonMeshBuilder.h"
   57.57 +
   57.58 +#include "time.h"
   57.59 +
   57.60 +using namespace Assimp;
   57.61 +
   57.62 +static const aiImporterDesc desc = {
   57.63 +	"Collada Importer",
   57.64 +	"",
   57.65 +	"",
   57.66 +	"http://collada.org",
   57.67 +	aiImporterFlags_SupportTextFlavour,
   57.68 +	1,
   57.69 +	3,
   57.70 +	1,
   57.71 +	5,
   57.72 +	"dae" 
   57.73 +};
   57.74 +
   57.75 +
   57.76 +// ------------------------------------------------------------------------------------------------
   57.77 +// Constructor to be privately used by Importer
   57.78 +ColladaLoader::ColladaLoader()
   57.79 +: noSkeletonMesh()
   57.80 +{}
   57.81 +
   57.82 +// ------------------------------------------------------------------------------------------------
   57.83 +// Destructor, private as well
   57.84 +ColladaLoader::~ColladaLoader()
   57.85 +{}
   57.86 +
   57.87 +// ------------------------------------------------------------------------------------------------
   57.88 +// Returns whether the class can handle the format of the given file. 
   57.89 +bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
   57.90 +{
   57.91 +	// check file extension 
   57.92 +	std::string extension = GetExtension(pFile);
   57.93 +	
   57.94 +	if( extension == "dae")
   57.95 +		return true;
   57.96 +
   57.97 +	// XML - too generic, we need to open the file and search for typical keywords
   57.98 +	if( extension == "xml" || !extension.length() || checkSig)	{
   57.99 +		/*  If CanRead() is called in order to check whether we
  57.100 +		 *  support a specific file extension in general pIOHandler
  57.101 +		 *  might be NULL and it's our duty to return true here.
  57.102 +		 */
  57.103 +		if (!pIOHandler)return true;
  57.104 +		const char* tokens[] = {"collada"};
  57.105 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
  57.106 +	}
  57.107 +	return false;
  57.108 +}
  57.109 +
  57.110 +// ------------------------------------------------------------------------------------------------
  57.111 +void ColladaLoader::SetupProperties(const Importer* pImp)
  57.112 +{
  57.113 +	noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
  57.114 +}
  57.115 +
  57.116 +
  57.117 +// ------------------------------------------------------------------------------------------------
  57.118 +// Get file extension list
  57.119 +const aiImporterDesc* ColladaLoader::GetInfo () const
  57.120 +{
  57.121 +	return &desc;
  57.122 +}
  57.123 +
  57.124 +// ------------------------------------------------------------------------------------------------
  57.125 +// Imports the given file into the given scene structure. 
  57.126 +void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
  57.127 +{
  57.128 +	mFileName = pFile;
  57.129 +
  57.130 +	// clean all member arrays - just for safety, it should work even if we did not
  57.131 +	mMeshIndexByID.clear();
  57.132 +	mMaterialIndexByName.clear();
  57.133 +	mMeshes.clear();
  57.134 +	newMats.clear();
  57.135 +	mLights.clear();
  57.136 +	mCameras.clear();
  57.137 +	mTextures.clear();
  57.138 +
  57.139 +	// parse the input file
  57.140 +	ColladaParser parser( pIOHandler, pFile);
  57.141 +
  57.142 +	if( !parser.mRootNode)
  57.143 +		throw DeadlyImportError( "Collada: File came out empty. Something is wrong here.");
  57.144 +
  57.145 +	// reserve some storage to avoid unnecessary reallocs
  57.146 +	newMats.reserve(parser.mMaterialLibrary.size()*2);
  57.147 +	mMeshes.reserve(parser.mMeshLibrary.size()*2);
  57.148 +
  57.149 +	mCameras.reserve(parser.mCameraLibrary.size());
  57.150 +	mLights.reserve(parser.mLightLibrary.size());
  57.151 +
  57.152 +	// create the materials first, for the meshes to find
  57.153 +	BuildMaterials( parser, pScene);
  57.154 +
  57.155 +	// build the node hierarchy from it
  57.156 +	pScene->mRootNode = BuildHierarchy( parser, parser.mRootNode);
  57.157 +
  57.158 +	// ... then fill the materials with the now adjusted settings
  57.159 +	FillMaterials(parser, pScene);
  57.160 +
  57.161 +        // Apply unitsize scale calculation
  57.162 +        pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0,  0,  0, 
  57.163 +                                                          0,  parser.mUnitSize,  0,  0,
  57.164 +                                                          0,  0,  parser.mUnitSize,  0,
  57.165 +                                                          0,  0,  0,  1);
  57.166 +
  57.167 +        // Convert to Y_UP, if different orientation
  57.168 +	if( parser.mUpDirection == ColladaParser::UP_X)
  57.169 +		pScene->mRootNode->mTransformation *= aiMatrix4x4( 
  57.170 +			 0, -1,  0,  0, 
  57.171 +			 1,  0,  0,  0,
  57.172 +			 0,  0,  1,  0,
  57.173 +			 0,  0,  0,  1);
  57.174 +	else if( parser.mUpDirection == ColladaParser::UP_Z)
  57.175 +		pScene->mRootNode->mTransformation *= aiMatrix4x4( 
  57.176 +			 1,  0,  0,  0, 
  57.177 +			 0,  0,  1,  0,
  57.178 +			 0, -1,  0,  0,
  57.179 +			 0,  0,  0,  1);
  57.180 +
  57.181 +	// store all meshes
  57.182 +	StoreSceneMeshes( pScene);
  57.183 +
  57.184 +	// store all materials
  57.185 +	StoreSceneMaterials( pScene);
  57.186 +
  57.187 +	// store all lights
  57.188 +	StoreSceneLights( pScene);
  57.189 +
  57.190 +	// store all cameras
  57.191 +	StoreSceneCameras( pScene);
  57.192 +
  57.193 +	// store all animations
  57.194 +	StoreAnimations( pScene, parser);
  57.195 +
  57.196 +
  57.197 +	// If no meshes have been loaded, it's probably just an animated skeleton.
  57.198 +	if (!pScene->mNumMeshes) {
  57.199 +	
  57.200 +		if (!noSkeletonMesh) {
  57.201 +			SkeletonMeshBuilder hero(pScene);
  57.202 +		}
  57.203 +		pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
  57.204 +	}
  57.205 +}
  57.206 +
  57.207 +// ------------------------------------------------------------------------------------------------
  57.208 +// Recursively constructs a scene node for the given parser node and returns it.
  57.209 +aiNode* ColladaLoader::BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode)
  57.210 +{
  57.211 +	// create a node for it
  57.212 +	aiNode* node = new aiNode();
  57.213 +
  57.214 +	// find a name for the new node. It's more complicated than you might think
  57.215 +	node->mName.Set( FindNameForNode( pNode));
  57.216 +
  57.217 +	// calculate the transformation matrix for it
  57.218 +	node->mTransformation = pParser.CalculateResultTransform( pNode->mTransforms);
  57.219 +
  57.220 +	// now resolve node instances
  57.221 +	std::vector<const Collada::Node*> instances;
  57.222 +	ResolveNodeInstances(pParser,pNode,instances);
  57.223 +
  57.224 +	// add children. first the *real* ones
  57.225 +	node->mNumChildren = pNode->mChildren.size()+instances.size();
  57.226 +	node->mChildren = new aiNode*[node->mNumChildren];
  57.227 +
  57.228 +	for( size_t a = 0; a < pNode->mChildren.size(); a++)
  57.229 +	{
  57.230 +		node->mChildren[a] = BuildHierarchy( pParser, pNode->mChildren[a]);
  57.231 +		node->mChildren[a]->mParent = node;
  57.232 +	}
  57.233 +
  57.234 +	// ... and finally the resolved node instances
  57.235 +	for( size_t a = 0; a < instances.size(); a++)
  57.236 +	{
  57.237 +		node->mChildren[pNode->mChildren.size() + a] = BuildHierarchy( pParser, instances[a]);
  57.238 +		node->mChildren[pNode->mChildren.size() + a]->mParent = node;
  57.239 +	}
  57.240 +
  57.241 +	// construct meshes
  57.242 +	BuildMeshesForNode( pParser, pNode, node);
  57.243 +
  57.244 +	// construct cameras
  57.245 +	BuildCamerasForNode(pParser, pNode, node);
  57.246 +
  57.247 +	// construct lights
  57.248 +	BuildLightsForNode(pParser, pNode, node);
  57.249 +	return node;
  57.250 +}
  57.251 +
  57.252 +// ------------------------------------------------------------------------------------------------
  57.253 +// Resolve node instances
  57.254 +void ColladaLoader::ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
  57.255 +	std::vector<const Collada::Node*>& resolved)
  57.256 +{
  57.257 +	// reserve enough storage
  57.258 +	resolved.reserve(pNode->mNodeInstances.size());
  57.259 +
  57.260 +	// ... and iterate through all nodes to be instanced as children of pNode
  57.261 +	for (std::vector<Collada::NodeInstance>::const_iterator it = pNode->mNodeInstances.begin(),
  57.262 +		 end = pNode->mNodeInstances.end(); it != end; ++it)
  57.263 +	{
  57.264 +		// find the corresponding node in the library
  57.265 +		const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find((*it).mNode);
  57.266 +		const Collada::Node* nd = itt == pParser.mNodeLibrary.end() ? NULL : (*itt).second;
  57.267 +
  57.268 +		// FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632
  57.269 +		// need to check for both name and ID to catch all. To avoid breaking valid files,
  57.270 +		// the workaround is only enabled when the first attempt to resolve the node has failed.
  57.271 +		if (!nd) {
  57.272 +			nd = FindNode(pParser.mRootNode,(*it).mNode);
  57.273 +		}
  57.274 +		if (!nd) 
  57.275 +			DefaultLogger::get()->error("Collada: Unable to resolve reference to instanced node " + (*it).mNode);
  57.276 +		
  57.277 +		else {
  57.278 +			//	attach this node to the list of children
  57.279 +			resolved.push_back(nd);
  57.280 +		}
  57.281 +	}
  57.282 +}
  57.283 +
  57.284 +// ------------------------------------------------------------------------------------------------
  57.285 +// Resolve UV channels
  57.286 +void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
  57.287 +	 const Collada::SemanticMappingTable& table)
  57.288 +{
  57.289 +	std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
  57.290 +	if (it != table.mMap.end()) {
  57.291 +		if (it->second.mType != Collada::IT_Texcoord)
  57.292 +			DefaultLogger::get()->error("Collada: Unexpected effect input mapping");
  57.293 +
  57.294 +		sampler.mUVId = it->second.mSet;
  57.295 +	}
  57.296 +}
  57.297 +
  57.298 +// ------------------------------------------------------------------------------------------------
  57.299 +// Builds lights for the given node and references them
  57.300 +void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
  57.301 +{
  57.302 +	BOOST_FOREACH( const Collada::LightInstance& lid, pNode->mLights)
  57.303 +	{
  57.304 +		// find the referred light
  57.305 +		ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find( lid.mLight);
  57.306 +		if( srcLightIt == pParser.mLightLibrary.end())
  57.307 +		{
  57.308 +			DefaultLogger::get()->warn("Collada: Unable to find light for ID \"" + lid.mLight + "\". Skipping.");
  57.309 +			continue;
  57.310 +		}
  57.311 +		const Collada::Light* srcLight = &srcLightIt->second;
  57.312 +		if (srcLight->mType == aiLightSource_AMBIENT) {
  57.313 +			DefaultLogger::get()->error("Collada: Skipping ambient light for the moment");
  57.314 +			continue;
  57.315 +		}
  57.316 +		
  57.317 +		// now fill our ai data structure
  57.318 +		aiLight* out = new aiLight();
  57.319 +		out->mName = pTarget->mName;
  57.320 +		out->mType = (aiLightSourceType)srcLight->mType;
  57.321 +
  57.322 +		// collada lights point in -Z by default, rest is specified in node transform
  57.323 +		out->mDirection = aiVector3D(0.f,0.f,-1.f);
  57.324 +
  57.325 +		out->mAttenuationConstant = srcLight->mAttConstant;
  57.326 +		out->mAttenuationLinear = srcLight->mAttLinear;
  57.327 +		out->mAttenuationQuadratic = srcLight->mAttQuadratic;
  57.328 +
  57.329 +		// collada doesn't differenciate between these color types
  57.330 +		out->mColorDiffuse = out->mColorSpecular = out->mColorAmbient = srcLight->mColor*srcLight->mIntensity;
  57.331 +
  57.332 +		// convert falloff angle and falloff exponent in our representation, if given
  57.333 +		if (out->mType == aiLightSource_SPOT) {
  57.334 +			
  57.335 +			out->mAngleInnerCone = AI_DEG_TO_RAD( srcLight->mFalloffAngle );
  57.336 +
  57.337 +			// ... some extension magic. 
  57.338 +			if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f))
  57.339 +			{
  57.340 +				// ... some deprecation magic. 
  57.341 +				if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f))
  57.342 +				{
  57.343 +					// Need to rely on falloff_exponent. I don't know how to interpret it, so I need to guess ....
  57.344 +					// epsilon chosen to be 0.1
  57.345 +					out->mAngleOuterCone = AI_DEG_TO_RAD (acos(pow(0.1f,1.f/srcLight->mFalloffExponent))+
  57.346 +						srcLight->mFalloffAngle);
  57.347 +				}
  57.348 +				else {
  57.349 +					out->mAngleOuterCone = out->mAngleInnerCone + AI_DEG_TO_RAD(  srcLight->mPenumbraAngle );
  57.350 +					if (out->mAngleOuterCone < out->mAngleInnerCone)
  57.351 +						std::swap(out->mAngleInnerCone,out->mAngleOuterCone);
  57.352 +				}
  57.353 +			}
  57.354 +			else out->mAngleOuterCone = AI_DEG_TO_RAD(  srcLight->mOuterAngle );
  57.355 +		}
  57.356 +
  57.357 +		// add to light list
  57.358 +		mLights.push_back(out);
  57.359 +	}
  57.360 +}
  57.361 +
  57.362 +// ------------------------------------------------------------------------------------------------
  57.363 +// Builds cameras for the given node and references them
  57.364 +void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
  57.365 +{
  57.366 +	BOOST_FOREACH( const Collada::CameraInstance& cid, pNode->mCameras)
  57.367 +	{
  57.368 +		// find the referred light
  57.369 +		ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find( cid.mCamera);
  57.370 +		if( srcCameraIt == pParser.mCameraLibrary.end())
  57.371 +		{
  57.372 +			DefaultLogger::get()->warn("Collada: Unable to find camera for ID \"" + cid.mCamera + "\". Skipping.");
  57.373 +			continue;
  57.374 +		}
  57.375 +		const Collada::Camera* srcCamera = &srcCameraIt->second;
  57.376 +
  57.377 +		// orthographic cameras not yet supported in Assimp
  57.378 +		if (srcCamera->mOrtho) {
  57.379 +			DefaultLogger::get()->warn("Collada: Orthographic cameras are not supported.");
  57.380 +		}
  57.381 +
  57.382 +		// now fill our ai data structure
  57.383 +		aiCamera* out = new aiCamera();
  57.384 +		out->mName = pTarget->mName;
  57.385 +
  57.386 +		// collada cameras point in -Z by default, rest is specified in node transform
  57.387 +		out->mLookAt = aiVector3D(0.f,0.f,-1.f);
  57.388 +
  57.389 +		// near/far z is already ok
  57.390 +		out->mClipPlaneFar = srcCamera->mZFar;
  57.391 +		out->mClipPlaneNear = srcCamera->mZNear;
  57.392 +
  57.393 +		// ... but for the rest some values are optional 
  57.394 +		// and we need to compute the others in any combination. 
  57.395 +		 if (srcCamera->mAspect != 10e10f)
  57.396 +			out->mAspect = srcCamera->mAspect;
  57.397 +
  57.398 +		if (srcCamera->mHorFov != 10e10f) {
  57.399 +			out->mHorizontalFOV = srcCamera->mHorFov; 
  57.400 +
  57.401 +			if (srcCamera->mVerFov != 10e10f && srcCamera->mAspect == 10e10f) {
  57.402 +				out->mAspect = tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) /
  57.403 +                    tan(AI_DEG_TO_RAD(srcCamera->mVerFov));
  57.404 +			}
  57.405 +		}
  57.406 +		else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f)	{
  57.407 +			out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(atan(srcCamera->mAspect *
  57.408 +                tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f)));
  57.409 +		}
  57.410 +
  57.411 +		// Collada uses degrees, we use radians
  57.412 +		out->mHorizontalFOV = AI_DEG_TO_RAD(out->mHorizontalFOV);
  57.413 +
  57.414 +		// add to camera list
  57.415 +		mCameras.push_back(out);
  57.416 +	}
  57.417 +}
  57.418 +
  57.419 +// ------------------------------------------------------------------------------------------------
  57.420 +// Builds meshes for the given node and references them
  57.421 +void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
  57.422 +{
  57.423 +	// accumulated mesh references by this node
  57.424 +	std::vector<size_t> newMeshRefs;
  57.425 +	newMeshRefs.reserve(pNode->mMeshes.size());
  57.426 +
  57.427 +	// add a mesh for each subgroup in each collada mesh
  57.428 +	BOOST_FOREACH( const Collada::MeshInstance& mid, pNode->mMeshes)
  57.429 +	{
  57.430 +		const Collada::Mesh* srcMesh = NULL;
  57.431 +		const Collada::Controller* srcController = NULL;
  57.432 +
  57.433 +		// find the referred mesh
  57.434 +		ColladaParser::MeshLibrary::const_iterator srcMeshIt = pParser.mMeshLibrary.find( mid.mMeshOrController);
  57.435 +		if( srcMeshIt == pParser.mMeshLibrary.end())
  57.436 +		{
  57.437 +			// if not found in the mesh-library, it might also be a controller referring to a mesh
  57.438 +			ColladaParser::ControllerLibrary::const_iterator srcContrIt = pParser.mControllerLibrary.find( mid.mMeshOrController);
  57.439 +			if( srcContrIt != pParser.mControllerLibrary.end())
  57.440 +			{
  57.441 +				srcController = &srcContrIt->second;
  57.442 +				srcMeshIt = pParser.mMeshLibrary.find( srcController->mMeshId);
  57.443 +				if( srcMeshIt != pParser.mMeshLibrary.end())
  57.444 +					srcMesh = srcMeshIt->second;
  57.445 +			}
  57.446 +
  57.447 +			if( !srcMesh)
  57.448 +			{
  57.449 +				DefaultLogger::get()->warn( boost::str( boost::format( "Collada: Unable to find geometry for ID \"%s\". Skipping.") % mid.mMeshOrController));
  57.450 +				continue;
  57.451 +			}
  57.452 +		} else
  57.453 +		{
  57.454 +			// ID found in the mesh library -> direct reference to an unskinned mesh
  57.455 +			srcMesh = srcMeshIt->second;
  57.456 +		}
  57.457 +
  57.458 +		// build a mesh for each of its subgroups
  57.459 +		size_t vertexStart = 0, faceStart = 0;
  57.460 +		for( size_t sm = 0; sm < srcMesh->mSubMeshes.size(); ++sm)
  57.461 +		{
  57.462 +			const Collada::SubMesh& submesh = srcMesh->mSubMeshes[sm];
  57.463 +			if( submesh.mNumFaces == 0)
  57.464 +				continue;
  57.465 +
  57.466 +			// find material assigned to this submesh
  57.467 +			std::string meshMaterial;
  57.468 +			std::map<std::string, Collada::SemanticMappingTable >::const_iterator meshMatIt = mid.mMaterials.find( submesh.mMaterial);
  57.469 +
  57.470 +			const Collada::SemanticMappingTable* table = NULL;
  57.471 +			if( meshMatIt != mid.mMaterials.end())
  57.472 +			{
  57.473 +				table = &meshMatIt->second;
  57.474 +				meshMaterial = table->mMatName;
  57.475 +			}
  57.476 +			else 
  57.477 +			{
  57.478 +				DefaultLogger::get()->warn( boost::str( boost::format( "Collada: No material specified for subgroup <%s> in geometry <%s>.") % submesh.mMaterial % mid.mMeshOrController));
  57.479 +				if( !mid.mMaterials.empty() )
  57.480 +					meshMaterial = mid.mMaterials.begin()->second.mMatName;
  57.481 +			}
  57.482 +
  57.483 +			// OK ... here the *real* fun starts ... we have the vertex-input-to-effect-semantic-table
  57.484 +			// given. The only mapping stuff which we do actually support is the UV channel.
  57.485 +			std::map<std::string, size_t>::const_iterator matIt = mMaterialIndexByName.find( meshMaterial);
  57.486 +			unsigned int matIdx;
  57.487 +			if( matIt != mMaterialIndexByName.end())
  57.488 +				matIdx = matIt->second;
  57.489 +			else
  57.490 +				matIdx = 0;
  57.491 +
  57.492 +			if (table && !table->mMap.empty() ) {
  57.493 +				std::pair<Collada::Effect*, aiMaterial*>&  mat = newMats[matIdx];
  57.494 +
  57.495 +				// Iterate through all texture channels assigned to the effect and
  57.496 +				// check whether we have mapping information for it.
  57.497 +				ApplyVertexToEffectSemanticMapping(mat.first->mTexDiffuse,    *table);
  57.498 +				ApplyVertexToEffectSemanticMapping(mat.first->mTexAmbient,    *table);
  57.499 +				ApplyVertexToEffectSemanticMapping(mat.first->mTexSpecular,   *table);
  57.500 +				ApplyVertexToEffectSemanticMapping(mat.first->mTexEmissive,   *table);
  57.501 +				ApplyVertexToEffectSemanticMapping(mat.first->mTexTransparent,*table);
  57.502 +				ApplyVertexToEffectSemanticMapping(mat.first->mTexBump,       *table);
  57.503 +			}
  57.504 +
  57.505 +			// built lookup index of the Mesh-Submesh-Material combination
  57.506 +			ColladaMeshIndex index( mid.mMeshOrController, sm, meshMaterial);
  57.507 +
  57.508 +			// if we already have the mesh at the library, just add its index to the node's array
  57.509 +			std::map<ColladaMeshIndex, size_t>::const_iterator dstMeshIt = mMeshIndexByID.find( index);
  57.510 +			if( dstMeshIt != mMeshIndexByID.end())	{
  57.511 +				newMeshRefs.push_back( dstMeshIt->second);
  57.512 +			} 
  57.513 +			else
  57.514 +			{
  57.515 +				// else we have to add the mesh to the collection and store its newly assigned index at the node
  57.516 +				aiMesh* dstMesh = CreateMesh( pParser, srcMesh, submesh, srcController, vertexStart, faceStart);
  57.517 +
  57.518 +				// store the mesh, and store its new index in the node
  57.519 +				newMeshRefs.push_back( mMeshes.size());
  57.520 +				mMeshIndexByID[index] = mMeshes.size();
  57.521 +				mMeshes.push_back( dstMesh);
  57.522 +				vertexStart += dstMesh->mNumVertices; faceStart += submesh.mNumFaces;
  57.523 +
  57.524 +				// assign the material index
  57.525 +				dstMesh->mMaterialIndex = matIdx;
  57.526 +        dstMesh->mName = mid.mMeshOrController;			
  57.527 +      }
  57.528 +		}
  57.529 +	}
  57.530 +
  57.531 +	// now place all mesh references we gathered in the target node
  57.532 +	pTarget->mNumMeshes = newMeshRefs.size();
  57.533 +	if( newMeshRefs.size())
  57.534 +	{
  57.535 +		pTarget->mMeshes = new unsigned int[pTarget->mNumMeshes];
  57.536 +		std::copy( newMeshRefs.begin(), newMeshRefs.end(), pTarget->mMeshes);
  57.537 +	}
  57.538 +}
  57.539 +
  57.540 +// ------------------------------------------------------------------------------------------------
  57.541 +// Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh
  57.542 +aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh, 
  57.543 +	const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace)
  57.544 +{
  57.545 +	aiMesh* dstMesh = new aiMesh;
  57.546 +
  57.547 +	// count the vertices addressed by its faces
  57.548 +	const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace,
  57.549 +		pSrcMesh->mFaceSize.begin() + pStartFace + pSubMesh.mNumFaces, 0);
  57.550 +
  57.551 +	// copy positions
  57.552 +	dstMesh->mNumVertices = numVertices;
  57.553 +	dstMesh->mVertices = new aiVector3D[numVertices];
  57.554 +	std::copy( pSrcMesh->mPositions.begin() + pStartVertex, pSrcMesh->mPositions.begin() + 
  57.555 +		pStartVertex + numVertices, dstMesh->mVertices);
  57.556 +
  57.557 +	// normals, if given. HACK: (thom) Due to the glorious Collada spec we never 
  57.558 +	// know if we have the same number of normals as there are positions. So we 
  57.559 +	// also ignore any vertex attribute if it has a different count
  57.560 +	if( pSrcMesh->mNormals.size() >= pStartVertex + numVertices)
  57.561 +	{
  57.562 +		dstMesh->mNormals = new aiVector3D[numVertices];
  57.563 +		std::copy( pSrcMesh->mNormals.begin() + pStartVertex, pSrcMesh->mNormals.begin() +
  57.564 +			pStartVertex + numVertices, dstMesh->mNormals);
  57.565 +	}
  57.566 +
  57.567 +	// tangents, if given. 
  57.568 +	if( pSrcMesh->mTangents.size() >= pStartVertex + numVertices)
  57.569 +	{
  57.570 +		dstMesh->mTangents = new aiVector3D[numVertices];
  57.571 +		std::copy( pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() + 
  57.572 +			pStartVertex + numVertices, dstMesh->mTangents);
  57.573 +	}
  57.574 +
  57.575 +	// bitangents, if given. 
  57.576 +	if( pSrcMesh->mBitangents.size() >= pStartVertex + numVertices)
  57.577 +	{
  57.578 +		dstMesh->mBitangents = new aiVector3D[numVertices];
  57.579 +		std::copy( pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() + 
  57.580 +			pStartVertex + numVertices, dstMesh->mBitangents);
  57.581 +	}
  57.582 +
  57.583 +	// same for texturecoords, as many as we have
  57.584 +	// empty slots are not allowed, need to pack and adjust UV indexes accordingly
  57.585 +	for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
  57.586 +	{
  57.587 +		if( pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices)
  57.588 +		{
  57.589 +			dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
  57.590 +			for( size_t b = 0; b < numVertices; ++b)
  57.591 +				dstMesh->mTextureCoords[real][b] = pSrcMesh->mTexCoords[a][pStartVertex+b];
  57.592 +			
  57.593 +			dstMesh->mNumUVComponents[real] = pSrcMesh->mNumUVComponents[a];
  57.594 +			++real;
  57.595 +		}
  57.596 +	}
  57.597 +
  57.598 +	// same for vertex colors, as many as we have. again the same packing to avoid empty slots
  57.599 +	for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
  57.600 +	{
  57.601 +		if( pSrcMesh->mColors[a].size() >= pStartVertex + numVertices)
  57.602 +		{
  57.603 +			dstMesh->mColors[real] = new aiColor4D[numVertices];
  57.604 +			std::copy( pSrcMesh->mColors[a].begin() + pStartVertex, pSrcMesh->mColors[a].begin() + pStartVertex + numVertices,dstMesh->mColors[real]);
  57.605 +			++real;
  57.606 +		}
  57.607 +	}
  57.608 +
  57.609 +	// create faces. Due to the fact that each face uses unique vertices, we can simply count up on each vertex
  57.610 +	size_t vertex = 0;
  57.611 +	dstMesh->mNumFaces = pSubMesh.mNumFaces;
  57.612 +	dstMesh->mFaces = new aiFace[dstMesh->mNumFaces];
  57.613 +	for( size_t a = 0; a < dstMesh->mNumFaces; ++a)
  57.614 +	{
  57.615 +		size_t s = pSrcMesh->mFaceSize[ pStartFace + a];
  57.616 +		aiFace& face = dstMesh->mFaces[a];
  57.617 +		face.mNumIndices = s;
  57.618 +		face.mIndices = new unsigned int[s];
  57.619 +		for( size_t b = 0; b < s; ++b)
  57.620 +			face.mIndices[b] = vertex++;
  57.621 +	}
  57.622 +
  57.623 +	// create bones if given
  57.624 +	if( pSrcController)
  57.625 +	{
  57.626 +		// refuse if the vertex count does not match
  57.627 +//		if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
  57.628 +//			throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
  57.629 +
  57.630 +		// resolve references - joint names
  57.631 +		const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
  57.632 +		const Collada::Data& jointNames = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointNamesAcc.mSource);
  57.633 +		// joint offset matrices
  57.634 +		const Collada::Accessor& jointMatrixAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointOffsetMatrixSource);
  57.635 +		const Collada::Data& jointMatrices = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointMatrixAcc.mSource);
  57.636 +		// joint vertex_weight name list - should refer to the same list as the joint names above. If not, report and reconsider
  57.637 +		const Collada::Accessor& weightNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mWeightInputJoints.mAccessor);
  57.638 +		if( &weightNamesAcc != &jointNamesAcc)
  57.639 +			throw DeadlyImportError( "Temporary implementational lazyness. If you read this, please report to the author.");
  57.640 +		// vertex weights
  57.641 +		const Collada::Accessor& weightsAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mWeightInputWeights.mAccessor);
  57.642 +		const Collada::Data& weights = pParser.ResolveLibraryReference( pParser.mDataLibrary, weightsAcc.mSource);
  57.643 +
  57.644 +		if( !jointNames.mIsStringArray || jointMatrices.mIsStringArray || weights.mIsStringArray)
  57.645 +			throw DeadlyImportError( "Data type mismatch while resolving mesh joints");
  57.646 +		// sanity check: we rely on the vertex weights always coming as pairs of BoneIndex-WeightIndex
  57.647 +		if( pSrcController->mWeightInputJoints.mOffset != 0 || pSrcController->mWeightInputWeights.mOffset != 1)
  57.648 +			throw DeadlyImportError( "Unsupported vertex_weight addressing scheme. ");
  57.649 +
  57.650 +		// create containers to collect the weights for each bone
  57.651 +		size_t numBones = jointNames.mStrings.size();
  57.652 +		std::vector<std::vector<aiVertexWeight> > dstBones( numBones);
  57.653 +
  57.654 +		// build a temporary array of pointers to the start of each vertex's weights
  57.655 +		typedef std::vector< std::pair<size_t, size_t> > IndexPairVector;
  57.656 +		std::vector<IndexPairVector::const_iterator> weightStartPerVertex;
  57.657 +		weightStartPerVertex.resize(pSrcController->mWeightCounts.size(),pSrcController->mWeights.end());
  57.658 +
  57.659 +		IndexPairVector::const_iterator pit = pSrcController->mWeights.begin();
  57.660 +		for( size_t a = 0; a < pSrcController->mWeightCounts.size(); ++a)
  57.661 +		{
  57.662 +			weightStartPerVertex[a] = pit;
  57.663 +			pit += pSrcController->mWeightCounts[a];
  57.664 +		}
  57.665 +
  57.666 +		// now for each vertex put the corresponding vertex weights into each bone's weight collection
  57.667 +		for( size_t a = pStartVertex; a < pStartVertex + numVertices; ++a)
  57.668 +		{
  57.669 +			// which position index was responsible for this vertex? that's also the index by which
  57.670 +			// the controller assigns the vertex weights
  57.671 +			size_t orgIndex = pSrcMesh->mFacePosIndices[a];
  57.672 +			// find the vertex weights for this vertex
  57.673 +			IndexPairVector::const_iterator iit = weightStartPerVertex[orgIndex];
  57.674 +			size_t pairCount = pSrcController->mWeightCounts[orgIndex];
  57.675 +
  57.676 +			for( size_t b = 0; b < pairCount; ++b, ++iit)
  57.677 +			{
  57.678 +				size_t jointIndex = iit->first;
  57.679 +				size_t vertexIndex = iit->second;
  57.680 +
  57.681 +				float weight = ReadFloat( weightsAcc, weights, vertexIndex, 0);
  57.682 +
  57.683 +				// one day I gonna kill that XSI Collada exporter
  57.684 +				if( weight > 0.0f)
  57.685 +				{
  57.686 +					aiVertexWeight w;
  57.687 +					w.mVertexId = a - pStartVertex;
  57.688 +					w.mWeight = weight;
  57.689 +					dstBones[jointIndex].push_back( w);
  57.690 +				}
  57.691 +			}
  57.692 +		}
  57.693 +
  57.694 +		// count the number of bones which influence vertices of the current submesh
  57.695 +		size_t numRemainingBones = 0;
  57.696 +		for( std::vector<std::vector<aiVertexWeight> >::const_iterator it = dstBones.begin(); it != dstBones.end(); ++it)
  57.697 +			if( it->size() > 0)
  57.698 +				numRemainingBones++;
  57.699 +
  57.700 +		// create bone array and copy bone weights one by one
  57.701 +		dstMesh->mNumBones = numRemainingBones;
  57.702 +		dstMesh->mBones = new aiBone*[numRemainingBones];
  57.703 +		size_t boneCount = 0;
  57.704 +		for( size_t a = 0; a < numBones; ++a)
  57.705 +		{
  57.706 +			// omit bones without weights
  57.707 +			if( dstBones[a].size() == 0)
  57.708 +				continue;
  57.709 +
  57.710 +			// create bone with its weights
  57.711 +			aiBone* bone = new aiBone;
  57.712 +			bone->mName = ReadString( jointNamesAcc, jointNames, a);
  57.713 +			bone->mOffsetMatrix.a1 = ReadFloat( jointMatrixAcc, jointMatrices, a, 0);
  57.714 +			bone->mOffsetMatrix.a2 = ReadFloat( jointMatrixAcc, jointMatrices, a, 1);
  57.715 +			bone->mOffsetMatrix.a3 = ReadFloat( jointMatrixAcc, jointMatrices, a, 2);
  57.716 +			bone->mOffsetMatrix.a4 = ReadFloat( jointMatrixAcc, jointMatrices, a, 3);
  57.717 +			bone->mOffsetMatrix.b1 = ReadFloat( jointMatrixAcc, jointMatrices, a, 4);
  57.718 +			bone->mOffsetMatrix.b2 = ReadFloat( jointMatrixAcc, jointMatrices, a, 5);
  57.719 +			bone->mOffsetMatrix.b3 = ReadFloat( jointMatrixAcc, jointMatrices, a, 6);
  57.720 +			bone->mOffsetMatrix.b4 = ReadFloat( jointMatrixAcc, jointMatrices, a, 7);
  57.721 +			bone->mOffsetMatrix.c1 = ReadFloat( jointMatrixAcc, jointMatrices, a, 8);
  57.722 +			bone->mOffsetMatrix.c2 = ReadFloat( jointMatrixAcc, jointMatrices, a, 9);
  57.723 +			bone->mOffsetMatrix.c3 = ReadFloat( jointMatrixAcc, jointMatrices, a, 10);
  57.724 +			bone->mOffsetMatrix.c4 = ReadFloat( jointMatrixAcc, jointMatrices, a, 11);
  57.725 +			bone->mNumWeights = dstBones[a].size();
  57.726 +			bone->mWeights = new aiVertexWeight[bone->mNumWeights];
  57.727 +			std::copy( dstBones[a].begin(), dstBones[a].end(), bone->mWeights);
  57.728 +
  57.729 +			// apply bind shape matrix to offset matrix
  57.730 +			aiMatrix4x4 bindShapeMatrix;
  57.731 +			bindShapeMatrix.a1 = pSrcController->mBindShapeMatrix[0];
  57.732 +			bindShapeMatrix.a2 = pSrcController->mBindShapeMatrix[1];
  57.733 +			bindShapeMatrix.a3 = pSrcController->mBindShapeMatrix[2];
  57.734 +			bindShapeMatrix.a4 = pSrcController->mBindShapeMatrix[3];
  57.735 +			bindShapeMatrix.b1 = pSrcController->mBindShapeMatrix[4];
  57.736 +			bindShapeMatrix.b2 = pSrcController->mBindShapeMatrix[5];
  57.737 +			bindShapeMatrix.b3 = pSrcController->mBindShapeMatrix[6];
  57.738 +			bindShapeMatrix.b4 = pSrcController->mBindShapeMatrix[7];
  57.739 +			bindShapeMatrix.c1 = pSrcController->mBindShapeMatrix[8];
  57.740 +			bindShapeMatrix.c2 = pSrcController->mBindShapeMatrix[9];
  57.741 +			bindShapeMatrix.c3 = pSrcController->mBindShapeMatrix[10];
  57.742 +			bindShapeMatrix.c4 = pSrcController->mBindShapeMatrix[11];
  57.743 +			bindShapeMatrix.d1 = pSrcController->mBindShapeMatrix[12];
  57.744 +			bindShapeMatrix.d2 = pSrcController->mBindShapeMatrix[13];
  57.745 +			bindShapeMatrix.d3 = pSrcController->mBindShapeMatrix[14];
  57.746 +			bindShapeMatrix.d4 = pSrcController->mBindShapeMatrix[15];
  57.747 +			bone->mOffsetMatrix *= bindShapeMatrix;
  57.748 +
  57.749 +			// HACK: (thom) Some exporters address the bone nodes by SID, others address them by ID or even name.
  57.750 +			// Therefore I added a little name replacement here: I search for the bone's node by either name, ID or SID,
  57.751 +			// and replace the bone's name by the node's name so that the user can use the standard
  57.752 +			// find-by-name method to associate nodes with bones.
  57.753 +			const Collada::Node* bnode = FindNode( pParser.mRootNode, bone->mName.data);
  57.754 +			if( !bnode)
  57.755 +				bnode = FindNodeBySID( pParser.mRootNode, bone->mName.data);
  57.756 +
  57.757 +			// assign the name that we would have assigned for the source node
  57.758 +			if( bnode)
  57.759 +				bone->mName.Set( FindNameForNode( bnode));
  57.760 +			else
  57.761 +				DefaultLogger::get()->warn( boost::str( boost::format( "ColladaLoader::CreateMesh(): could not find corresponding node for joint \"%s\".") % bone->mName.data));
  57.762 +
  57.763 +			// and insert bone
  57.764 +			dstMesh->mBones[boneCount++] = bone;
  57.765 +		}
  57.766 +	}
  57.767 +
  57.768 +	return dstMesh;
  57.769 +}
  57.770 +
  57.771 +// ------------------------------------------------------------------------------------------------
  57.772 +// Stores all meshes in the given scene
  57.773 +void ColladaLoader::StoreSceneMeshes( aiScene* pScene)
  57.774 +{
  57.775 +	pScene->mNumMeshes = mMeshes.size();
  57.776 +	if( mMeshes.size() > 0)
  57.777 +	{
  57.778 +		pScene->mMeshes = new aiMesh*[mMeshes.size()];
  57.779 +		std::copy( mMeshes.begin(), mMeshes.end(), pScene->mMeshes);
  57.780 +		mMeshes.clear();
  57.781 +	}
  57.782 +}
  57.783 +
  57.784 +// ------------------------------------------------------------------------------------------------
  57.785 +// Stores all cameras in the given scene
  57.786 +void ColladaLoader::StoreSceneCameras( aiScene* pScene)
  57.787 +{
  57.788 +	pScene->mNumCameras = mCameras.size();
  57.789 +	if( mCameras.size() > 0)
  57.790 +	{
  57.791 +		pScene->mCameras = new aiCamera*[mCameras.size()];
  57.792 +		std::copy( mCameras.begin(), mCameras.end(), pScene->mCameras);
  57.793 +		mCameras.clear();
  57.794 +	}
  57.795 +}
  57.796 +
  57.797 +// ------------------------------------------------------------------------------------------------
  57.798 +// Stores all lights in the given scene
  57.799 +void ColladaLoader::StoreSceneLights( aiScene* pScene)
  57.800 +{
  57.801 +	pScene->mNumLights = mLights.size();
  57.802 +	if( mLights.size() > 0)
  57.803 +	{
  57.804 +		pScene->mLights = new aiLight*[mLights.size()];
  57.805 +		std::copy( mLights.begin(), mLights.end(), pScene->mLights);
  57.806 +		mLights.clear();
  57.807 +	}
  57.808 +}
  57.809 +
  57.810 +// ------------------------------------------------------------------------------------------------
  57.811 +// Stores all textures in the given scene
  57.812 +void ColladaLoader::StoreSceneTextures( aiScene* pScene)
  57.813 +{
  57.814 +	pScene->mNumTextures = mTextures.size();
  57.815 +	if( mTextures.size() > 0)
  57.816 +	{
  57.817 +		pScene->mTextures = new aiTexture*[mTextures.size()];
  57.818 +		std::copy( mTextures.begin(), mTextures.end(), pScene->mTextures);
  57.819 +		mTextures.clear();
  57.820 +	}
  57.821 +}
  57.822 +
  57.823 +// ------------------------------------------------------------------------------------------------
  57.824 +// Stores all materials in the given scene
  57.825 +void ColladaLoader::StoreSceneMaterials( aiScene* pScene)
  57.826 +{
  57.827 +	pScene->mNumMaterials = newMats.size();
  57.828 +
  57.829 +	if (newMats.size() > 0) {
  57.830 +		pScene->mMaterials = new aiMaterial*[newMats.size()];
  57.831 +		for (unsigned int i = 0; i < newMats.size();++i)
  57.832 +			pScene->mMaterials[i] = newMats[i].second;
  57.833 +
  57.834 +		newMats.clear();
  57.835 +	}
  57.836 +}
  57.837 +
  57.838 +// ------------------------------------------------------------------------------------------------
  57.839 +// Stores all animations 
  57.840 +void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser)
  57.841 +{
  57.842 +	// recursivly collect all animations from the collada scene
  57.843 +	StoreAnimations( pScene, pParser, &pParser.mAnims, "");
  57.844 +
  57.845 +	// catch special case: many animations with the same length, each affecting only a single node.
  57.846 +	// we need to unite all those single-node-anims to a proper combined animation
  57.847 +	for( size_t a = 0; a < mAnims.size(); ++a)
  57.848 +	{
  57.849 +		aiAnimation* templateAnim = mAnims[a];
  57.850 +		if( templateAnim->mNumChannels == 1)
  57.851 +		{
  57.852 +			// search for other single-channel-anims with the same duration
  57.853 +			std::vector<size_t> collectedAnimIndices;
  57.854 +			for( size_t b = a+1; b < mAnims.size(); ++b)
  57.855 +			{
  57.856 +				aiAnimation* other = mAnims[b];
  57.857 +				if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration && other->mTicksPerSecond == templateAnim->mTicksPerSecond )
  57.858 +					collectedAnimIndices.push_back( b);
  57.859 +			}
  57.860 +
  57.861 +			// if there are other animations which fit the template anim, combine all channels into a single anim
  57.862 +			if( !collectedAnimIndices.empty() )
  57.863 +			{
  57.864 +				aiAnimation* combinedAnim = new aiAnimation();
  57.865 +				combinedAnim->mName = aiString( std::string( "combinedAnim_") + char( '0' + a));
  57.866 +				combinedAnim->mDuration = templateAnim->mDuration;
  57.867 +				combinedAnim->mTicksPerSecond = templateAnim->mTicksPerSecond;
  57.868 +				combinedAnim->mNumChannels = collectedAnimIndices.size() + 1;
  57.869 +				combinedAnim->mChannels = new aiNodeAnim*[combinedAnim->mNumChannels];
  57.870 +				// add the template anim as first channel by moving its aiNodeAnim to the combined animation
  57.871 +				combinedAnim->mChannels[0] = templateAnim->mChannels[0];
  57.872 +				templateAnim->mChannels[0] = NULL;
  57.873 +				delete templateAnim;
  57.874 +				// combined animation replaces template animation in the anim array
  57.875 +				mAnims[a] = combinedAnim;
  57.876 +
  57.877 +				// move the memory of all other anims to the combined anim and erase them from the source anims
  57.878 +				for( size_t b = 0; b < collectedAnimIndices.size(); ++b)
  57.879 +				{
  57.880 +					aiAnimation* srcAnimation = mAnims[collectedAnimIndices[b]];
  57.881 +					combinedAnim->mChannels[1 + b] = srcAnimation->mChannels[0];
  57.882 +					srcAnimation->mChannels[0] = NULL;
  57.883 +					delete srcAnimation;
  57.884 +				}
  57.885 +
  57.886 +				// in a second go, delete all the single-channel-anims that we've stripped from their channels
  57.887 +				// back to front to preserve indices - you know, removing an element from a vector moves all elements behind the removed one
  57.888 +				while( !collectedAnimIndices.empty() )
  57.889 +				{
  57.890 +					mAnims.erase( mAnims.begin() + collectedAnimIndices.back());
  57.891 +					collectedAnimIndices.pop_back();
  57.892 +				}
  57.893 +			}
  57.894 +		}
  57.895 +	}
  57.896 +
  57.897 +	// now store all anims in the scene
  57.898 +	if( !mAnims.empty())
  57.899 +	{
  57.900 +		pScene->mNumAnimations = mAnims.size();
  57.901 +		pScene->mAnimations = new aiAnimation*[mAnims.size()];
  57.902 +		std::copy( mAnims.begin(), mAnims.end(), pScene->mAnimations);
  57.903 +	}
  57.904 +}
  57.905 +
  57.906 +// ------------------------------------------------------------------------------------------------
  57.907 +// Constructs the animations for the given source anim 
  57.908 +void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string pPrefix)
  57.909 +{
  57.910 +	std::string animName = pPrefix.empty() ? pSrcAnim->mName : pPrefix + "_" + pSrcAnim->mName;
  57.911 +
  57.912 +	// create nested animations, if given
  57.913 +	for( std::vector<Collada::Animation*>::const_iterator it = pSrcAnim->mSubAnims.begin(); it != pSrcAnim->mSubAnims.end(); ++it)
  57.914 +		StoreAnimations( pScene, pParser, *it, animName);
  57.915 +
  57.916 +	// create animation channels, if any
  57.917 +	if( !pSrcAnim->mChannels.empty())
  57.918 +		CreateAnimation( pScene, pParser, pSrcAnim, animName);
  57.919 +}
  57.920 +
  57.921 +// ------------------------------------------------------------------------------------------------
  57.922 +// Constructs the animation for the given source anim
  57.923 +void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName)
  57.924 +{
  57.925 +	// collect a list of animatable nodes
  57.926 +	std::vector<const aiNode*> nodes;
  57.927 +	CollectNodes( pScene->mRootNode, nodes);
  57.928 +
  57.929 +	std::vector<aiNodeAnim*> anims;
  57.930 +	for( std::vector<const aiNode*>::const_iterator nit = nodes.begin(); nit != nodes.end(); ++nit)
  57.931 +	{
  57.932 +		// find all the collada anim channels which refer to the current node
  57.933 +		std::vector<Collada::ChannelEntry> entries;
  57.934 +		std::string nodeName = (*nit)->mName.data;
  57.935 +
  57.936 +		// find the collada node corresponding to the aiNode
  57.937 +		const Collada::Node* srcNode = FindNode( pParser.mRootNode, nodeName);
  57.938 +//		ai_assert( srcNode != NULL);
  57.939 +		if( !srcNode)
  57.940 +			continue;
  57.941 +
  57.942 +		// now check all channels if they affect the current node
  57.943 +		for( std::vector<Collada::AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
  57.944 +			cit != pSrcAnim->mChannels.end(); ++cit)
  57.945 +		{
  57.946 +			const Collada::AnimationChannel& srcChannel = *cit;
  57.947 +			Collada::ChannelEntry entry;
  57.948 +
  57.949 +			// we expect the animation target to be of type "nodeName/transformID.subElement". Ignore all others
  57.950 +			// find the slash that separates the node name - there should be only one
  57.951 +			std::string::size_type slashPos = srcChannel.mTarget.find( '/');
  57.952 +			if( slashPos == std::string::npos)
  57.953 +				continue;
  57.954 +			if( srcChannel.mTarget.find( '/', slashPos+1) != std::string::npos)
  57.955 +				continue;
  57.956 +			std::string targetID = srcChannel.mTarget.substr( 0, slashPos);
  57.957 +			if( targetID != srcNode->mID)
  57.958 +				continue;
  57.959 +
  57.960 +			// find the dot that separates the transformID - there should be only one or zero
  57.961 +			std::string::size_type dotPos = srcChannel.mTarget.find( '.');
  57.962 +			if( dotPos != std::string::npos)
  57.963 +			{
  57.964 +				if( srcChannel.mTarget.find( '.', dotPos+1) != std::string::npos)
  57.965 +					continue;
  57.966 +
  57.967 +				entry.mTransformId = srcChannel.mTarget.substr( slashPos+1, dotPos - slashPos - 1);
  57.968 +
  57.969 +				std::string subElement = srcChannel.mTarget.substr( dotPos+1);
  57.970 +				if( subElement == "ANGLE")
  57.971 +					entry.mSubElement = 3; // last number in an Axis-Angle-Transform is the angle
  57.972 +				else if( subElement == "X")
  57.973 +					entry.mSubElement = 0;
  57.974 +				else if( subElement == "Y")
  57.975 +					entry.mSubElement = 1;
  57.976 +				else if( subElement == "Z")
  57.977 +					entry.mSubElement = 2;
  57.978 +				else 
  57.979 +					DefaultLogger::get()->warn( boost::str( boost::format( "Unknown anim subelement <%s>. Ignoring") % subElement));
  57.980 +			} else
  57.981 +			{
  57.982 +				// no subelement following, transformId is remaining string
  57.983 +				entry.mTransformId = srcChannel.mTarget.substr( slashPos+1);
  57.984 +			}
  57.985 +
  57.986 +			// determine which transform step is affected by this channel
  57.987 +			entry.mTransformIndex = SIZE_MAX;
  57.988 +			for( size_t a = 0; a < srcNode->mTransforms.size(); ++a)
  57.989 +				if( srcNode->mTransforms[a].mID == entry.mTransformId)
  57.990 +					entry.mTransformIndex = a;
  57.991 +
  57.992 +			if( entry.mTransformIndex == SIZE_MAX) {
  57.993 +				continue;
  57.994 +			}
  57.995 +
  57.996 +			entry.mChannel = &(*cit);
  57.997 +			entries.push_back( entry);
  57.998 +		}
  57.999 +
 57.1000 +		// if there's no channel affecting the current node, we skip it
 57.1001 +		if( entries.empty())
 57.1002 +			continue;
 57.1003 +
 57.1004 +		// resolve the data pointers for all anim channels. Find the minimum time while we're at it
 57.1005 +		float startTime = 1e20f, endTime = -1e20f;
 57.1006 +		for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
 57.1007 +		{
 57.1008 +			Collada::ChannelEntry& e = *it;
 57.1009 +			e.mTimeAccessor = &pParser.ResolveLibraryReference( pParser.mAccessorLibrary, e.mChannel->mSourceTimes);
 57.1010 +			e.mTimeData = &pParser.ResolveLibraryReference( pParser.mDataLibrary, e.mTimeAccessor->mSource);
 57.1011 +			e.mValueAccessor = &pParser.ResolveLibraryReference( pParser.mAccessorLibrary, e.mChannel->mSourceValues);
 57.1012 +			e.mValueData = &pParser.ResolveLibraryReference( pParser.mDataLibrary, e.mValueAccessor->mSource);
 57.1013 +
 57.1014 +			// time count and value count must match
 57.1015 +			if( e.mTimeAccessor->mCount != e.mValueAccessor->mCount)
 57.1016 +				throw DeadlyImportError( boost::str( boost::format( "Time count / value count mismatch in animation channel \"%s\".") % e.mChannel->mTarget));
 57.1017 +
 57.1018 +      if( e.mTimeAccessor->mCount > 0 )
 57.1019 +      {
 57.1020 +			  // find bounding times
 57.1021 +			  startTime = std::min( startTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, 0, 0));
 57.1022 +  			endTime = std::max( endTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, e.mTimeAccessor->mCount-1, 0));
 57.1023 +      }
 57.1024 +		}
 57.1025 +
 57.1026 +    std::vector<aiMatrix4x4> resultTrafos;
 57.1027 +    if( !entries.empty() && entries.front().mTimeAccessor->mCount > 0 )
 57.1028 +    {
 57.1029 +		  // create a local transformation chain of the node's transforms
 57.1030 +		  std::vector<Collada::Transform> transforms = srcNode->mTransforms;
 57.1031 +
 57.1032 +		  // now for every unique point in time, find or interpolate the key values for that time
 57.1033 +		  // and apply them to the transform chain. Then the node's present transformation can be calculated.
 57.1034 +		  float time = startTime;
 57.1035 +		  while( 1)
 57.1036 +		  {
 57.1037 +			  for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
 57.1038 +			  {
 57.1039 +				  Collada::ChannelEntry& e = *it;
 57.1040 +
 57.1041 +				  // find the keyframe behind the current point in time
 57.1042 +				  size_t pos = 0;
 57.1043 +				  float postTime = 0.f;
 57.1044 +				  while( 1)
 57.1045 +				  {
 57.1046 +					  if( pos >= e.mTimeAccessor->mCount)
 57.1047 +						  break;
 57.1048 +					  postTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
 57.1049 +					  if( postTime >= time)
 57.1050 +						  break;
 57.1051 +					  ++pos;
 57.1052 +				  }
 57.1053 +
 57.1054 +				  pos = std::min( pos, e.mTimeAccessor->mCount-1);
 57.1055 +
 57.1056 +				  // read values from there
 57.1057 +				  float temp[16];
 57.1058 +				  for( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
 57.1059 +					  temp[c] = ReadFloat( *e.mValueAccessor, *e.mValueData, pos, c);
 57.1060 +
 57.1061 +				  // if not exactly at the key time, interpolate with previous value set
 57.1062 +				  if( postTime > time && pos > 0)
 57.1063 +				  {
 57.1064 +					  float preTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos-1, 0);
 57.1065 +					  float factor = (time - postTime) / (preTime - postTime);
 57.1066 +
 57.1067 +					  for( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
 57.1068 +					  {
 57.1069 +						  float v = ReadFloat( *e.mValueAccessor, *e.mValueData, pos-1, c);
 57.1070 +						  temp[c] += (v - temp[c]) * factor;
 57.1071 +					  }
 57.1072 +				  }
 57.1073 +
 57.1074 +				  // Apply values to current transformation
 57.1075 +				  std::copy( temp, temp + e.mValueAccessor->mSize, transforms[e.mTransformIndex].f + e.mSubElement);
 57.1076 +			  }
 57.1077 +
 57.1078 +			  // Calculate resulting transformation
 57.1079 +			  aiMatrix4x4 mat = pParser.CalculateResultTransform( transforms);
 57.1080 +
 57.1081 +			  // out of lazyness: we store the time in matrix.d4
 57.1082 +			  mat.d4 = time;
 57.1083 +			  resultTrafos.push_back( mat);
 57.1084 +
 57.1085 +			  // find next point in time to evaluate. That's the closest frame larger than the current in any channel
 57.1086 +			  float nextTime = 1e20f;
 57.1087 +			  for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
 57.1088 +			  {
 57.1089 +				  Collada::ChannelEntry& e = *it;
 57.1090 +
 57.1091 +				  // find the next time value larger than the current
 57.1092 +				  size_t pos = 0;
 57.1093 +				  while( pos < e.mTimeAccessor->mCount)
 57.1094 +				  {
 57.1095 +					  float t = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
 57.1096 +					  if( t > time)
 57.1097 +					  {
 57.1098 +						  nextTime = std::min( nextTime, t);
 57.1099 +						  break;
 57.1100 +					  }
 57.1101 +					  ++pos;
 57.1102 +				  }
 57.1103 +			  }
 57.1104 +
 57.1105 +			  // no more keys on any channel after the current time -> we're done
 57.1106 +			  if( nextTime > 1e19)
 57.1107 +				  break;
 57.1108 +
 57.1109 +			  // else construct next keyframe at this following time point
 57.1110 +			  time = nextTime;
 57.1111 +		  }
 57.1112 +    }
 57.1113 +
 57.1114 +		// there should be some keyframes, but we aren't that fixated on valid input data
 57.1115 +//		ai_assert( resultTrafos.size() > 0);
 57.1116 +
 57.1117 +		// build an animation channel for the given node out of these trafo keys
 57.1118 +    if( !resultTrafos.empty() )
 57.1119 +    {
 57.1120 +		  aiNodeAnim* dstAnim = new aiNodeAnim;
 57.1121 +		  dstAnim->mNodeName = nodeName;
 57.1122 +		  dstAnim->mNumPositionKeys = resultTrafos.size();
 57.1123 +		  dstAnim->mNumRotationKeys= resultTrafos.size();
 57.1124 +		  dstAnim->mNumScalingKeys = resultTrafos.size();
 57.1125 +		  dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()];
 57.1126 +		  dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()];
 57.1127 +		  dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()];
 57.1128 +
 57.1129 +		  for( size_t a = 0; a < resultTrafos.size(); ++a)
 57.1130 +		  {
 57.1131 +			  aiMatrix4x4 mat = resultTrafos[a];
 57.1132 +			  double time = double( mat.d4); // remember? time is stored in mat.d4
 57.1133 +        mat.d4 = 1.0f;
 57.1134 +
 57.1135 +			  dstAnim->mPositionKeys[a].mTime = time;
 57.1136 +			  dstAnim->mRotationKeys[a].mTime = time;
 57.1137 +			  dstAnim->mScalingKeys[a].mTime = time;
 57.1138 +			  mat.Decompose( dstAnim->mScalingKeys[a].mValue, dstAnim->mRotationKeys[a].mValue, dstAnim->mPositionKeys[a].mValue);
 57.1139 +		  }
 57.1140 +
 57.1141 +		  anims.push_back( dstAnim);
 57.1142 +    } else
 57.1143 +    {
 57.1144 +      DefaultLogger::get()->warn( "Collada loader: found empty animation channel, ignored. Please check your exporter.");
 57.1145 +    }
 57.1146 +	}
 57.1147 +
 57.1148 +	if( !anims.empty())
 57.1149 +	{
 57.1150 +		aiAnimation* anim = new aiAnimation;
 57.1151 +		anim->mName.Set( pName);
 57.1152 +		anim->mNumChannels = anims.size();
 57.1153 +		anim->mChannels = new aiNodeAnim*[anims.size()];
 57.1154 +		std::copy( anims.begin(), anims.end(), anim->mChannels);
 57.1155 +		anim->mDuration = 0.0f;
 57.1156 +		for( size_t a = 0; a < anims.size(); ++a)
 57.1157 +		{
 57.1158 +			anim->mDuration = std::max( anim->mDuration, anims[a]->mPositionKeys[anims[a]->mNumPositionKeys-1].mTime);
 57.1159 +			anim->mDuration = std::max( anim->mDuration, anims[a]->mRotationKeys[anims[a]->mNumRotationKeys-1].mTime);
 57.1160 +			anim->mDuration = std::max( anim->mDuration, anims[a]->mScalingKeys[anims[a]->mNumScalingKeys-1].mTime);
 57.1161 +		}
 57.1162 +		anim->mTicksPerSecond = 1;
 57.1163 +		mAnims.push_back( anim);
 57.1164 +	}
 57.1165 +}
 57.1166 +
 57.1167 +// ------------------------------------------------------------------------------------------------
 57.1168 +// Add a texture to a material structure
 57.1169 +void ColladaLoader::AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
 57.1170 +	const Collada::Effect& effect,
 57.1171 +	const Collada::Sampler& sampler,
 57.1172 +	aiTextureType type, unsigned int idx)
 57.1173 +{
 57.1174 +	// first of all, basic file name
 57.1175 +	const aiString name = FindFilenameForEffectTexture( pParser, effect, sampler.mName );
 57.1176 +	mat.AddProperty( &name, _AI_MATKEY_TEXTURE_BASE, type, idx );
 57.1177 +
 57.1178 +	// mapping mode
 57.1179 +	int map = aiTextureMapMode_Clamp;
 57.1180 +	if (sampler.mWrapU)
 57.1181 +		map = aiTextureMapMode_Wrap;
 57.1182 +	if (sampler.mWrapU && sampler.mMirrorU)
 57.1183 +		map = aiTextureMapMode_Mirror;
 57.1184 +
 57.1185 +	mat.AddProperty( &map, 1, _AI_MATKEY_MAPPINGMODE_U_BASE, type, idx);
 57.1186 +
 57.1187 +	map = aiTextureMapMode_Clamp;
 57.1188 +	if (sampler.mWrapV)
 57.1189 +		map = aiTextureMapMode_Wrap;
 57.1190 +	if (sampler.mWrapV && sampler.mMirrorV)
 57.1191 +		map = aiTextureMapMode_Mirror;
 57.1192 +
 57.1193 +	mat.AddProperty( &map, 1, _AI_MATKEY_MAPPINGMODE_V_BASE, type, idx);
 57.1194 +
 57.1195 +	// UV transformation
 57.1196 +	mat.AddProperty(&sampler.mTransform, 1,
 57.1197 +		_AI_MATKEY_UVTRANSFORM_BASE, type, idx);
 57.1198 +
 57.1199 +	// Blend mode
 57.1200 +	mat.AddProperty((int*)&sampler.mOp , 1,
 57.1201 +		_AI_MATKEY_TEXBLEND_BASE, type, idx);
 57.1202 +
 57.1203 +	// Blend factor
 57.1204 +	mat.AddProperty((float*)&sampler.mWeighting , 1,
 57.1205 +		_AI_MATKEY_TEXBLEND_BASE, type, idx);
 57.1206 +
 57.1207 +	// UV source index ... if we didn't resolve the mapping, it is actually just 
 57.1208 +	// a guess but it works in most cases. We search for the frst occurence of a
 57.1209 +	// number in the channel name. We assume it is the zero-based index into the
 57.1210 +	// UV channel array of all corresponding meshes. It could also be one-based
 57.1211 +	// for some exporters, but we won't care of it unless someone complains about.
 57.1212 +	if (sampler.mUVId != UINT_MAX)
 57.1213 +		map = sampler.mUVId;
 57.1214 +	else {
 57.1215 +		map = -1;
 57.1216 +		for (std::string::const_iterator it = sampler.mUVChannel.begin();it != sampler.mUVChannel.end(); ++it){
 57.1217 +			if (IsNumeric(*it)) {
 57.1218 +				map = strtoul10(&(*it));
 57.1219 +				break;
 57.1220 +			}
 57.1221 +		}
 57.1222 +		if (-1 == map) {
 57.1223 +			DefaultLogger::get()->warn("Collada: unable to determine UV channel for texture");
 57.1224 +			map = 0;
 57.1225 +		}
 57.1226 +	}
 57.1227 +	mat.AddProperty(&map,1,_AI_MATKEY_UVWSRC_BASE,type,idx);
 57.1228 +}
 57.1229 +
 57.1230 +// ------------------------------------------------------------------------------------------------
 57.1231 +// Fills materials from the collada material definitions
 57.1232 +void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pScene*/)
 57.1233 +{
 57.1234 +	for (std::vector<std::pair<Collada::Effect*, aiMaterial*> >::iterator it = newMats.begin(),
 57.1235 +		end = newMats.end(); it != end; ++it)
 57.1236 +	{
 57.1237 +		aiMaterial&  mat = (aiMaterial&)*it->second; 
 57.1238 +		Collada::Effect& effect = *it->first;
 57.1239 +
 57.1240 +		// resolve shading mode
 57.1241 +		int shadeMode;
 57.1242 +		if (effect.mFaceted) /* fixme */
 57.1243 +			shadeMode = aiShadingMode_Flat;
 57.1244 +		else {
 57.1245 +			switch( effect.mShadeType)
 57.1246 +			{
 57.1247 +			case Collada::Shade_Constant: 
 57.1248 +				shadeMode = aiShadingMode_NoShading; 
 57.1249 +				break;
 57.1250 +			case Collada::Shade_Lambert:
 57.1251 +				shadeMode = aiShadingMode_Gouraud; 
 57.1252 +				break;
 57.1253 +			case Collada::Shade_Blinn: 
 57.1254 +				shadeMode = aiShadingMode_Blinn;
 57.1255 +				break;
 57.1256 +			case Collada::Shade_Phong: 
 57.1257 +				shadeMode = aiShadingMode_Phong; 
 57.1258 +				break;
 57.1259 +
 57.1260 +			default:
 57.1261 +				DefaultLogger::get()->warn("Collada: Unrecognized shading mode, using gouraud shading");
 57.1262 +				shadeMode = aiShadingMode_Gouraud; 
 57.1263 +				break;
 57.1264 +			}
 57.1265 +		}
 57.1266 +		mat.AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
 57.1267 +
 57.1268 +		// double-sided?
 57.1269 +		shadeMode = effect.mDoubleSided;
 57.1270 +		mat.AddProperty<int>( &shadeMode, 1, AI_MATKEY_TWOSIDED);
 57.1271 +
 57.1272 +		// wireframe?
 57.1273 +		shadeMode = effect.mWireframe;
 57.1274 +		mat.AddProperty<int>( &shadeMode, 1, AI_MATKEY_ENABLE_WIREFRAME);
 57.1275 +
 57.1276 +		// add material colors
 57.1277 +		mat.AddProperty( &effect.mAmbient, 1,AI_MATKEY_COLOR_AMBIENT);
 57.1278 +		mat.AddProperty( &effect.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
 57.1279 +		mat.AddProperty( &effect.mSpecular, 1,AI_MATKEY_COLOR_SPECULAR);
 57.1280 +		mat.AddProperty( &effect.mEmissive, 1,	AI_MATKEY_COLOR_EMISSIVE);
 57.1281 +		mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT);
 57.1282 +		mat.AddProperty( &effect.mReflective, 1, AI_MATKEY_COLOR_REFLECTIVE);
 57.1283 +
 57.1284 +		// scalar properties
 57.1285 +		mat.AddProperty( &effect.mShininess, 1, AI_MATKEY_SHININESS);
 57.1286 +		mat.AddProperty( &effect.mReflectivity, 1, AI_MATKEY_REFLECTIVITY);
 57.1287 +		mat.AddProperty( &effect.mRefractIndex, 1, AI_MATKEY_REFRACTI);
 57.1288 +
 57.1289 +		// transparency, a very hard one. seemingly not all files are following the
 57.1290 +		// specification here .. but we can trick.
 57.1291 +		if (effect.mTransparency >= 0.f && effect.mTransparency < 1.f) {
 57.1292 +			effect.mTransparency = 1.f- effect.mTransparency;
 57.1293 +			mat.AddProperty( &effect.mTransparency, 1, AI_MATKEY_OPACITY );
 57.1294 +			mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT );
 57.1295 +		}
 57.1296 +
 57.1297 +		// add textures, if given
 57.1298 +		if( !effect.mTexAmbient.mName.empty()) 
 57.1299 +			 /* It is merely a lightmap */
 57.1300 +			AddTexture( mat, pParser, effect, effect.mTexAmbient, aiTextureType_LIGHTMAP);
 57.1301 +
 57.1302 +		if( !effect.mTexEmissive.mName.empty())
 57.1303 +			AddTexture( mat, pParser, effect, effect.mTexEmissive, aiTextureType_EMISSIVE);
 57.1304 +
 57.1305 +		if( !effect.mTexSpecular.mName.empty())
 57.1306 +			AddTexture( mat, pParser, effect, effect.mTexSpecular, aiTextureType_SPECULAR);
 57.1307 +
 57.1308 +		if( !effect.mTexDiffuse.mName.empty())
 57.1309 +			AddTexture( mat, pParser, effect, effect.mTexDiffuse, aiTextureType_DIFFUSE);
 57.1310 +
 57.1311 +		if( !effect.mTexBump.mName.empty())
 57.1312 +			AddTexture( mat, pParser, effect, effect.mTexBump, aiTextureType_NORMALS);
 57.1313 +
 57.1314 +		if( !effect.mTexTransparent.mName.empty())
 57.1315 +			AddTexture( mat, pParser, effect, effect.mTexTransparent, aiTextureType_OPACITY);
 57.1316 +
 57.1317 +		if( !effect.mTexReflective.mName.empty())
 57.1318 +			AddTexture( mat, pParser, effect, effect.mTexReflective, aiTextureType_REFLECTION);
 57.1319 +	}
 57.1320 +}
 57.1321 +
 57.1322 +// ------------------------------------------------------------------------------------------------
 57.1323 +// Constructs materials from the collada material definitions
 57.1324 +void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
 57.1325 +{
 57.1326 +	newMats.reserve(pParser.mMaterialLibrary.size());
 57.1327 +
 57.1328 +	for( ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin(); matIt != pParser.mMaterialLibrary.end(); ++matIt)
 57.1329 +	{
 57.1330 +		const Collada::Material& material = matIt->second;
 57.1331 +		// a material is only a reference to an effect
 57.1332 +		ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find( material.mEffect);
 57.1333 +		if( effIt == pParser.mEffectLibrary.end())
 57.1334 +			continue;
 57.1335 +		Collada::Effect& effect = effIt->second;
 57.1336 +
 57.1337 +		// create material
 57.1338 +		aiMaterial* mat = new aiMaterial;
 57.1339 +		aiString name( matIt->first);
 57.1340 +		mat->AddProperty(&name,AI_MATKEY_NAME);
 57.1341 +
 57.1342 +		// store the material
 57.1343 +		mMaterialIndexByName[matIt->first] = newMats.size();
 57.1344 +		newMats.push_back( std::pair<Collada::Effect*, aiMaterial*>( &effect,mat) );
 57.1345 +	}
 57.1346 +	// ScenePreprocessor generates a default material automatically if none is there.
 57.1347 +	// All further code here in this loader works well without a valid material so
 57.1348 +	// we can safely let it to ScenePreprocessor.
 57.1349 +#if 0
 57.1350 +	if( newMats.size() == 0)
 57.1351 +	{
 57.1352 +		aiMaterial* mat = new aiMaterial;
 57.1353 +		aiString name( AI_DEFAULT_MATERIAL_NAME );
 57.1354 +		mat->AddProperty( &name, AI_MATKEY_NAME);
 57.1355 +
 57.1356 +		const int shadeMode = aiShadingMode_Phong;
 57.1357 +		mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
 57.1358 +		aiColor4D colAmbient( 0.2f, 0.2f, 0.2f, 1.0f), colDiffuse( 0.8f, 0.8f, 0.8f, 1.0f), colSpecular( 0.5f, 0.5f, 0.5f, 0.5f);
 57.1359 +		mat->AddProperty( &colAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
 57.1360 +		mat->AddProperty( &colDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
 57.1361 +		mat->AddProperty( &colSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
 57.1362 +		const float specExp = 5.0f;
 57.1363 +		mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS);
 57.1364 +	}
 57.1365 +#endif
 57.1366 +}
 57.1367 +
 57.1368 +// ------------------------------------------------------------------------------------------------
 57.1369 +// Resolves the texture name for the given effect texture entry
 57.1370 +aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser,
 57.1371 +	const Collada::Effect& pEffect, const std::string& pName)
 57.1372 +{
 57.1373 +	// recurse through the param references until we end up at an image
 57.1374 +	std::string name = pName;
 57.1375 +	while( 1)
 57.1376 +	{
 57.1377 +		// the given string is a param entry. Find it
 57.1378 +		Collada::Effect::ParamLibrary::const_iterator it = pEffect.mParams.find( name);
 57.1379 +		// if not found, we're at the end of the recursion. The resulting string should be the image ID
 57.1380 +		if( it == pEffect.mParams.end())
 57.1381 +			break;
 57.1382 +
 57.1383 +		// else recurse on
 57.1384 +		name = it->second.mReference;
 57.1385 +	}
 57.1386 +
 57.1387 +	// find the image referred by this name in the image library of the scene
 57.1388 +	ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
 57.1389 +	if( imIt == pParser.mImageLibrary.end()) 
 57.1390 +	{
 57.1391 +		throw DeadlyImportError( boost::str( boost::format( 
 57.1392 +			"Collada: Unable to resolve effect texture entry \"%s\", ended up at ID \"%s\".") % pName % name));
 57.1393 +	}
 57.1394 +
 57.1395 +	aiString result;
 57.1396 +
 57.1397 +	// if this is an embedded texture image setup an aiTexture for it
 57.1398 +	if (imIt->second.mFileName.empty()) 
 57.1399 +	{
 57.1400 +		if (imIt->second.mImageData.empty())  {
 57.1401 +			throw DeadlyImportError("Collada: Invalid texture, no data or file reference given");
 57.1402 +		}
 57.1403 +
 57.1404 +		aiTexture* tex = new aiTexture();
 57.1405 +
 57.1406 +		// setup format hint
 57.1407 +		if (imIt->second.mEmbeddedFormat.length() > 3) {
 57.1408 +			DefaultLogger::get()->warn("Collada: texture format hint is too long, truncating to 3 characters");
 57.1409 +		}
 57.1410 +		strncpy(tex->achFormatHint,imIt->second.mEmbeddedFormat.c_str(),3);
 57.1411 +
 57.1412 +		// and copy texture data
 57.1413 +		tex->mHeight = 0;
 57.1414 +		tex->mWidth = imIt->second.mImageData.size();
 57.1415 +		tex->pcData = (aiTexel*)new char[tex->mWidth];
 57.1416 +		memcpy(tex->pcData,&imIt->second.mImageData[0],tex->mWidth);
 57.1417 +
 57.1418 +		// setup texture reference string
 57.1419 +		result.data[0] = '*';
 57.1420 +		result.length = 1 + ASSIMP_itoa10(result.data+1,MAXLEN-1,mTextures.size());
 57.1421 +
 57.1422 +		// and add this texture to the list
 57.1423 +		mTextures.push_back(tex);
 57.1424 +	}
 57.1425 +	else 
 57.1426 +	{
 57.1427 +		result.Set( imIt->second.mFileName );
 57.1428 +		ConvertPath(result);
 57.1429 +	}
 57.1430 +	return result;
 57.1431 +}
 57.1432 +
 57.1433 +// ------------------------------------------------------------------------------------------------
 57.1434 +// Convert a path read from a collada file to the usual representation
 57.1435 +void ColladaLoader::ConvertPath (aiString& ss)
 57.1436 +{
 57.1437 +	// TODO: collada spec, p 22. Handle URI correctly.
 57.1438 +	// For the moment we're just stripping the file:// away to make it work.
 57.1439 +	// Windoes doesn't seem to be able to find stuff like
 57.1440 +	// 'file://..\LWO\LWO2\MappingModes\earthSpherical.jpg'
 57.1441 +	if (0 == strncmp(ss.data,"file://",7)) 
 57.1442 +	{
 57.1443 +		ss.length -= 7;
 57.1444 +		memmove(ss.data,ss.data+7,ss.length);
 57.1445 +		ss.data[ss.length] = '\0';
 57.1446 +	}
 57.1447 +
 57.1448 +  // Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes... 
 57.1449 +  // I need to filter it without destroying linux paths starting with "/somewhere"
 57.1450 +  if( ss.data[0] == '/' && isalpha( ss.data[1]) && ss.data[2] == ':' )
 57.1451 +  {
 57.1452 +    ss.length--;
 57.1453 +    memmove( ss.data, ss.data+1, ss.length);
 57.1454 +    ss.data[ss.length] = 0;
 57.1455 +  }
 57.1456 +
 57.1457 +  // find and convert all %xy special chars
 57.1458 +  char* out = ss.data;
 57.1459 +  for( const char* it = ss.data; it != ss.data + ss.length; /**/ )
 57.1460 +  {
 57.1461 +    if( *it == '%' && (it + 3) < ss.data + ss.length )
 57.1462 +    {
 57.1463 +      // separate the number to avoid dragging in chars from behind into the parsing
 57.1464 +      char mychar[3] = { it[1], it[2], 0 };
 57.1465 +      size_t nbr = strtoul16( mychar);
 57.1466 +      it += 3;
 57.1467 +      *out++ = (char)(nbr & 0xFF);
 57.1468 +    } else
 57.1469 +    {
 57.1470 +      *out++ = *it++;
 57.1471 +    }
 57.1472 +  }
 57.1473 +
 57.1474 +  // adjust length and terminator of the shortened string
 57.1475 +  *out = 0;
 57.1476 +  ss.length = (ptrdiff_t) (out - ss.data);
 57.1477 +}
 57.1478 +
 57.1479 +// ------------------------------------------------------------------------------------------------
 57.1480 +// Reads a float value from an accessor and its data array.
 57.1481 +float ColladaLoader::ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const
 57.1482 +{
 57.1483 +	// FIXME: (thom) Test for data type here in every access? For the moment, I leave this to the caller
 57.1484 +	size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
 57.1485 +	ai_assert( pos < pData.mValues.size());
 57.1486 +	return pData.mValues[pos];
 57.1487 +}
 57.1488 +
 57.1489 +// ------------------------------------------------------------------------------------------------
 57.1490 +// Reads a string value from an accessor and its data array.
 57.1491 +const std::string& ColladaLoader::ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const
 57.1492 +{
 57.1493 +	size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset;
 57.1494 +	ai_assert( pos < pData.mStrings.size());
 57.1495 +	return pData.mStrings[pos];
 57.1496 +}
 57.1497 +
 57.1498 +// ------------------------------------------------------------------------------------------------
 57.1499 +// Collects all nodes into the given array
 57.1500 +void ColladaLoader::CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const
 57.1501 +{
 57.1502 +	poNodes.push_back( pNode);
 57.1503 +
 57.1504 +	for( size_t a = 0; a < pNode->mNumChildren; ++a)
 57.1505 +		CollectNodes( pNode->mChildren[a], poNodes);
 57.1506 +}
 57.1507 +
 57.1508 +// ------------------------------------------------------------------------------------------------
 57.1509 +// Finds a node in the collada scene by the given name
 57.1510 +const Collada::Node* ColladaLoader::FindNode( const Collada::Node* pNode, const std::string& pName) const
 57.1511 +{
 57.1512 +	if( pNode->mName == pName || pNode->mID == pName)
 57.1513 +		return pNode;
 57.1514 +
 57.1515 +	for( size_t a = 0; a < pNode->mChildren.size(); ++a)
 57.1516 +	{
 57.1517 +		const Collada::Node* node = FindNode( pNode->mChildren[a], pName);
 57.1518 +		if( node)
 57.1519 +			return node;
 57.1520 +	}
 57.1521 +
 57.1522 +	return NULL;
 57.1523 +}
 57.1524 +
 57.1525 +// ------------------------------------------------------------------------------------------------
 57.1526 +// Finds a node in the collada scene by the given SID
 57.1527 +const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const
 57.1528 +{
 57.1529 +  if( pNode->mSID == pSID)
 57.1530 +    return pNode;
 57.1531 +
 57.1532 +  for( size_t a = 0; a < pNode->mChildren.size(); ++a)
 57.1533 +  {
 57.1534 +    const Collada::Node* node = FindNodeBySID( pNode->mChildren[a], pSID);
 57.1535 +    if( node)
 57.1536 +      return node;
 57.1537 +  }
 57.1538 +
 57.1539 +  return NULL;
 57.1540 +}
 57.1541 +
 57.1542 +// ------------------------------------------------------------------------------------------------
 57.1543 +// Finds a proper name for a node derived from the collada-node's properties
 57.1544 +std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode) const
 57.1545 +{
 57.1546 +	// now setup the name of the node. We take the name if not empty, otherwise the collada ID
 57.1547 +	// FIX: Workaround for XSI calling the instanced visual scene 'untitled' by default.
 57.1548 +	if (!pNode->mName.empty() && pNode->mName != "untitled")
 57.1549 +		return pNode->mName;
 57.1550 +	else if (!pNode->mID.empty())
 57.1551 +		return pNode->mID;
 57.1552 +	else if (!pNode->mSID.empty())
 57.1553 +    return pNode->mSID;
 57.1554 +  else
 57.1555 +	{
 57.1556 +		// No need to worry. Unnamed nodes are no problem at all, except
 57.1557 +		// if cameras or lights need to be assigned to them.
 57.1558 +    return boost::str( boost::format( "$ColladaAutoName$_%d") % clock());
 57.1559 +	}
 57.1560 +}
 57.1561 +
 57.1562 +#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/libs/assimp/ColladaLoader.h	Sat Feb 01 19:58:19 2014 +0200
    58.3 @@ -0,0 +1,241 @@
    58.4 +/** Defines the collada loader class */
    58.5 +
    58.6 +/*
    58.7 +Open Asset Import Library (assimp)
    58.8 +----------------------------------------------------------------------
    58.9 +
   58.10 +Copyright (c) 2006-2012, assimp team
   58.11 +All rights reserved.
   58.12 +
   58.13 +Redistribution and use of this software in source and binary forms, 
   58.14 +with or without modification, are permitted provided that the 
   58.15 +following conditions are met:
   58.16 +
   58.17 +* Redistributions of source code must retain the above
   58.18 +copyright notice, this list of conditions and the
   58.19 +following disclaimer.
   58.20 +
   58.21 +* Redistributions in binary form must reproduce the above
   58.22 +copyright notice, this list of conditions and the
   58.23 +following disclaimer in the documentation and/or other
   58.24 +materials provided with the distribution.
   58.25 +
   58.26 +* Neither the name of the assimp team, nor the names of its
   58.27 +contributors may be used to endorse or promote products
   58.28 +derived from this software without specific prior
   58.29 +written permission of the assimp team.
   58.30 +
   58.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   58.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   58.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   58.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   58.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   58.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   58.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   58.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   58.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   58.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   58.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   58.42 +
   58.43 +----------------------------------------------------------------------
   58.44 +*/
   58.45 +
   58.46 +#ifndef AI_COLLADALOADER_H_INC
   58.47 +#define AI_COLLADALOADER_H_INC
   58.48 +
   58.49 +#include "BaseImporter.h"
   58.50 +#include "ColladaParser.h"
   58.51 +
   58.52 +namespace Assimp
   58.53 +{
   58.54 +
   58.55 +struct ColladaMeshIndex
   58.56 +{
   58.57 +	std::string mMeshID;
   58.58 +	size_t mSubMesh;
   58.59 +	std::string mMaterial;
   58.60 +	ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial) 
   58.61 +		: mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial)
   58.62 +	{   }
   58.63 +
   58.64 +	bool operator < (const ColladaMeshIndex& p) const
   58.65 +	{
   58.66 +		if( mMeshID == p.mMeshID) 
   58.67 +		{
   58.68 +			if( mSubMesh == p.mSubMesh)
   58.69 +				return mMaterial < p.mMaterial;
   58.70 +			else 
   58.71 +				return mSubMesh < p.mSubMesh;
   58.72 +		} else
   58.73 +		{
   58.74 +			return mMeshID < p.mMeshID;
   58.75 +		}
   58.76 +	}
   58.77 +};
   58.78 +
   58.79 +/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
   58.80 + * more useless stuff, so I limited the data to what I think is useful for games. 
   58.81 +*/
   58.82 +class ColladaLoader : public BaseImporter
   58.83 +{
   58.84 +public:
   58.85 +	ColladaLoader();
   58.86 +	~ColladaLoader();
   58.87 +
   58.88 +
   58.89 +public:
   58.90 +	/** Returns whether the class can handle the format of the given file. 
   58.91 +	 * See BaseImporter::CanRead() for details.	*/
   58.92 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
   58.93 +
   58.94 +protected:
   58.95 +	/** Return importer meta information.
   58.96 +	 * See #BaseImporter::GetInfo for the details
   58.97 +	 */
   58.98 +	const aiImporterDesc* GetInfo () const;
   58.99 +
  58.100 +	void SetupProperties(const Importer* pImp);
  58.101 +
  58.102 +	/** Imports the given file into the given scene structure. 
  58.103 +	 * See BaseImporter::InternReadFile() for details
  58.104 +	 */
  58.105 +	void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
  58.106 +
  58.107 +	/** Recursively constructs a scene node for the given parser node and returns it. */
  58.108 +	aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
  58.109 +
  58.110 +	/** Resolve node instances */
  58.111 +	void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
  58.112 +		std::vector<const Collada::Node*>& resolved);
  58.113 +
  58.114 +	/** Builds meshes for the given node and references them */
  58.115 +	void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode, 
  58.116 +		aiNode* pTarget);
  58.117 +
  58.118 +	/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
  58.119 +	aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh, 
  58.120 +		const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace);
  58.121 +
  58.122 +	/** Builds cameras for the given node and references them */
  58.123 +	void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode, 
  58.124 +		aiNode* pTarget);
  58.125 +
  58.126 +	/** Builds lights for the given node and references them */
  58.127 +	void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode, 
  58.128 +		aiNode* pTarget);
  58.129 +
  58.130 +	/** Stores all meshes in the given scene */
  58.131 +	void StoreSceneMeshes( aiScene* pScene);
  58.132 +
  58.133 +	/** Stores all materials in the given scene */
  58.134 +	void StoreSceneMaterials( aiScene* pScene);
  58.135 +
  58.136 +	/** Stores all lights in the given scene */
  58.137 +	void StoreSceneLights( aiScene* pScene);
  58.138 +
  58.139 +	/** Stores all cameras in the given scene */
  58.140 +	void StoreSceneCameras( aiScene* pScene);
  58.141 +
  58.142 +	/** Stores all textures in the given scene */
  58.143 +	void StoreSceneTextures( aiScene* pScene);
  58.144 +
  58.145 +	/** Stores all animations 
  58.146 +	 * @param pScene target scene to store the anims
  58.147 +	 */
  58.148 +	void StoreAnimations( aiScene* pScene, const ColladaParser& pParser);
  58.149 +
  58.150 +	/** Stores all animations for the given source anim and its nested child animations
  58.151 +	 * @param pScene target scene to store the anims
  58.152 +	 * @param pSrcAnim the source animation to process
  58.153 +	 * @param pPrefix Prefix to the name in case of nested animations
  58.154 +	 */
  58.155 +	void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string pPrefix);
  58.156 +
  58.157 +	/** Constructs the animation for the given source anim */
  58.158 +	void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName);
  58.159 +	
  58.160 +	/** Constructs materials from the collada material definitions */
  58.161 +	void BuildMaterials( ColladaParser& pParser, aiScene* pScene);
  58.162 +
  58.163 +	/** Fill materials from the collada material definitions */
  58.164 +	void FillMaterials( const ColladaParser& pParser, aiScene* pScene);
  58.165 +
  58.166 +	/** Resolve UV channel mappings*/
  58.167 +	void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
  58.168 +		const Collada::SemanticMappingTable& table);
  58.169 +
  58.170 +	/** Add a texture and all of its sampling properties to a material*/
  58.171 +	void AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
  58.172 +		const Collada::Effect& effect,
  58.173 +		const Collada::Sampler& sampler,
  58.174 +		aiTextureType type, unsigned int idx = 0);
  58.175 +
  58.176 +	/** Resolves the texture name for the given effect texture entry */
  58.177 +	aiString FindFilenameForEffectTexture( const ColladaParser& pParser, 
  58.178 +		const Collada::Effect& pEffect, const std::string& pName);
  58.179 +
  58.180 +	/** Converts a path read from a collada file to the usual representation */
  58.181 +	void ConvertPath( aiString& ss);
  58.182 +
  58.183 +	/** Reads a float value from an accessor and its data array.
  58.184 +	 * @param pAccessor The accessor to use for reading
  58.185 +	 * @param pData The data array to read from
  58.186 +	 * @param pIndex The index of the element to retrieve
  58.187 +	 * @param pOffset Offset into the element, for multipart elements such as vectors or matrices
  58.188 +	 * @return the specified value
  58.189 +	 */
  58.190 +	float ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const;
  58.191 +
  58.192 +	/** Reads a string value from an accessor and its data array.
  58.193 +	 * @param pAccessor The accessor to use for reading
  58.194 +	 * @param pData The data array to read from
  58.195 +	 * @param pIndex The index of the element to retrieve
  58.196 +	 * @return the specified value
  58.197 +	 */
  58.198 +	const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const;
  58.199 +
  58.200 +	/** Recursively collects all nodes into the given array */
  58.201 +	void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const;
  58.202 +
  58.203 +	/** Finds a node in the collada scene by the given name */
  58.204 +	const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const;
  58.205 +	/** Finds a node in the collada scene by the given SID */
  58.206 +	const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const;
  58.207 +
  58.208 +	/** Finds a proper name for a node derived from the collada-node's properties */
  58.209 +	std::string FindNameForNode( const Collada::Node* pNode) const;
  58.210 +
  58.211 +protected:
  58.212 +	/** Filename, for a verbose error message */
  58.213 +	std::string mFileName;
  58.214 +
  58.215 +	/** Which mesh-material compound was stored under which mesh ID */
  58.216 +	std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
  58.217 +
  58.218 +	/** Which material was stored under which index in the scene */
  58.219 +	std::map<std::string, size_t> mMaterialIndexByName;
  58.220 +
  58.221 +	/** Accumulated meshes for the target scene */
  58.222 +	std::vector<aiMesh*> mMeshes;
  58.223 +
  58.224 +	/** Temporary material list */
  58.225 +	std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats;
  58.226 +
  58.227 +	/** Temporary camera list */
  58.228 +	std::vector<aiCamera*> mCameras;
  58.229 +
  58.230 +	/** Temporary light list */
  58.231 +	std::vector<aiLight*> mLights;
  58.232 +
  58.233 +	/** Temporary texture list */
  58.234 +	std::vector<aiTexture*> mTextures;
  58.235 +
  58.236 +	/** Accumulated animations for the target scene */
  58.237 +	std::vector<aiAnimation*> mAnims;
  58.238 +
  58.239 +	bool noSkeletonMesh;
  58.240 +};
  58.241 +
  58.242 +} // end of namespace Assimp
  58.243 +
  58.244 +#endif // AI_COLLADALOADER_H_INC
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/libs/assimp/ColladaParser.cpp	Sat Feb 01 19:58:19 2014 +0200
    59.3 @@ -0,0 +1,2823 @@
    59.4 +/*
    59.5 +---------------------------------------------------------------------------
    59.6 +Open Asset Import Library (assimp)
    59.7 +---------------------------------------------------------------------------
    59.8 +
    59.9 +Copyright (c) 2006-2012, assimp team
   59.10 +
   59.11 +All rights reserved.
   59.12 +
   59.13 +Redistribution and use of this software in source and binary forms, 
   59.14 +with or without modification, are permitted provided that the following 
   59.15 +conditions are met:
   59.16 +
   59.17 +* Redistributions of source code must retain the above
   59.18 +copyright notice, this list of conditions and the
   59.19 +following disclaimer.
   59.20 +
   59.21 +* Redistributions in binary form must reproduce the above
   59.22 +copyright notice, this list of conditions and the
   59.23 +following disclaimer in the documentation and/or other
   59.24 +materials provided with the distribution.
   59.25 +
   59.26 +* Neither the name of the assimp team, nor the names of its
   59.27 +contributors may be used to endorse or promote products
   59.28 +derived from this software without specific prior
   59.29 +written permission of the assimp team.
   59.30 +
   59.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   59.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   59.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   59.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   59.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   59.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   59.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   59.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   59.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   59.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   59.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   59.42 +---------------------------------------------------------------------------
   59.43 +*/
   59.44 +
   59.45 +/** @file ColladaParser.cpp
   59.46 + *  @brief Implementation of the Collada parser helper
   59.47 + */
   59.48 +
   59.49 +#include "AssimpPCH.h"
   59.50 +#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
   59.51 +
   59.52 +#include "ColladaParser.h"
   59.53 +#include "fast_atof.h"
   59.54 +#include "ParsingUtils.h"
   59.55 +
   59.56 +using namespace Assimp;
   59.57 +using namespace Assimp::Collada;
   59.58 +
   59.59 +// ------------------------------------------------------------------------------------------------
   59.60 +// Constructor to be privately used by Importer
   59.61 +ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
   59.62 +	: mFileName( pFile)
   59.63 +{
   59.64 +	mRootNode = NULL;
   59.65 +	mUnitSize = 1.0f;
   59.66 +	mUpDirection = UP_Z;
   59.67 +
   59.68 +	// We assume the newest file format by default
   59.69 +	mFormat = FV_1_5_n;
   59.70 +
   59.71 +  // open the file
   59.72 +  boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
   59.73 +  if( file.get() == NULL)
   59.74 +    throw DeadlyImportError( "Failed to open file " + pFile + ".");
   59.75 +
   59.76 +	// generate a XML reader for it
   59.77 +  boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
   59.78 +	mReader = irr::io::createIrrXMLReader( mIOWrapper.get());
   59.79 +	if( !mReader)
   59.80 +		ThrowException( "Collada: Unable to open file.");
   59.81 +
   59.82 +	// start reading
   59.83 +	ReadContents();
   59.84 +}
   59.85 +
   59.86 +// ------------------------------------------------------------------------------------------------
   59.87 +// Destructor, private as well
   59.88 +ColladaParser::~ColladaParser()
   59.89 +{
   59.90 +	delete mReader;
   59.91 +	for( NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it)
   59.92 +		delete it->second;
   59.93 +	for( MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it)
   59.94 +		delete it->second;
   59.95 +}
   59.96 +
   59.97 +// ------------------------------------------------------------------------------------------------
   59.98 +// Read bool from text contents of current element
   59.99 +bool ColladaParser::ReadBoolFromTextContent()
  59.100 +{
  59.101 +	const char* cur = GetTextContent();
  59.102 +	return (!ASSIMP_strincmp(cur,"true",4) || '0' != *cur);
  59.103 +}
  59.104 +
  59.105 +// ------------------------------------------------------------------------------------------------
  59.106 +// Read float from text contents of current element
  59.107 +float ColladaParser::ReadFloatFromTextContent()
  59.108 +{
  59.109 +	const char* cur = GetTextContent();
  59.110 +	return fast_atof(cur);
  59.111 +}
  59.112 +
  59.113 +// ------------------------------------------------------------------------------------------------
  59.114 +// Reads the contents of the file
  59.115 +void ColladaParser::ReadContents()
  59.116 +{
  59.117 +	while( mReader->read())
  59.118 +	{
  59.119 +		// handle the root element "COLLADA"
  59.120 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
  59.121 +		{
  59.122 +			if( IsElement( "COLLADA"))
  59.123 +			{
  59.124 +				// check for 'version' attribute
  59.125 +				const int attrib = TestAttribute("version");
  59.126 +				if (attrib != -1) {
  59.127 +					const char* version = mReader->getAttributeValue(attrib);
  59.128 +					
  59.129 +					if (!::strncmp(version,"1.5",3)) {
  59.130 +						mFormat =  FV_1_5_n;
  59.131 +						DefaultLogger::get()->debug("Collada schema version is 1.5.n");
  59.132 +					}
  59.133 +					else if (!::strncmp(version,"1.4",3)) {
  59.134 +						mFormat =  FV_1_4_n;
  59.135 +						DefaultLogger::get()->debug("Collada schema version is 1.4.n");
  59.136 +					}
  59.137 +					else if (!::strncmp(version,"1.3",3)) {
  59.138 +						mFormat =  FV_1_3_n;
  59.139 +						DefaultLogger::get()->debug("Collada schema version is 1.3.n");
  59.140 +					}
  59.141 +				}
  59.142 +
  59.143 +				ReadStructure();
  59.144 +			} else
  59.145 +			{
  59.146 +				DefaultLogger::get()->debug( boost::str( boost::format( "Ignoring global element <%s>.") % mReader->getNodeName()));
  59.147 +				SkipElement();
  59.148 +			}
  59.149 +		} else
  59.150 +		{
  59.151 +			// skip everything else silently
  59.152 +		}
  59.153 +	}
  59.154 +}
  59.155 +
  59.156 +// ------------------------------------------------------------------------------------------------
  59.157 +// Reads the structure of the file
  59.158 +void ColladaParser::ReadStructure()
  59.159 +{
  59.160 +	while( mReader->read())
  59.161 +	{
  59.162 +		// beginning of elements
  59.163 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
  59.164 +		{
  59.165 +			if( IsElement( "asset"))
  59.166 +				ReadAssetInfo();
  59.167 +			else if( IsElement( "library_animations"))
  59.168 +				ReadAnimationLibrary();
  59.169 +			else if( IsElement( "library_controllers"))
  59.170 +				ReadControllerLibrary();
  59.171 +			else if( IsElement( "library_images"))
  59.172 +				ReadImageLibrary();
  59.173 +			else if( IsElement( "library_materials"))
  59.174 +				ReadMaterialLibrary();
  59.175 +			else if( IsElement( "library_effects"))
  59.176 +				ReadEffectLibrary();
  59.177 +			else if( IsElement( "library_geometries"))
  59.178 +				ReadGeometryLibrary();
  59.179 +			else if( IsElement( "library_visual_scenes"))
  59.180 +				ReadSceneLibrary();
  59.181 +			else if( IsElement( "library_lights"))
  59.182 +				ReadLightLibrary();
  59.183 +			else if( IsElement( "library_cameras"))
  59.184 +				ReadCameraLibrary();
  59.185 +			else if( IsElement( "library_nodes"))
  59.186 +				ReadSceneNode(NULL); /* some hacking to reuse this piece of code */
  59.187 +			else if( IsElement( "scene"))
  59.188 +				ReadScene();
  59.189 +			else
  59.190 +				SkipElement();
  59.191 +		} 
  59.192 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) 
  59.193 +		{
  59.194 +			break;
  59.195 +		}
  59.196 +	}
  59.197 +}
  59.198 +
  59.199 +// ------------------------------------------------------------------------------------------------
  59.200 +// Reads asset informations such as coordinate system informations and legal blah
  59.201 +void ColladaParser::ReadAssetInfo()
  59.202 +{
  59.203 +	if( mReader->isEmptyElement())
  59.204 +		return;
  59.205 +
  59.206 +	while( mReader->read())
  59.207 +	{
  59.208 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
  59.209 +		{
  59.210 +			if( IsElement( "unit"))
  59.211 +			{
  59.212 +				// read unit data from the element's attributes
  59.213 +				const int attrIndex = TestAttribute( "meter");
  59.214 +				if (attrIndex == -1) {
  59.215 +					mUnitSize = 1.f;
  59.216 +				}
  59.217 +				else {
  59.218 +					mUnitSize = mReader->getAttributeValueAsFloat( attrIndex);
  59.219 +				}
  59.220 +
  59.221 +				// consume the trailing stuff
  59.222 +				if( !mReader->isEmptyElement())
  59.223 +					SkipElement();
  59.224 +			} 
  59.225 +			else if( IsElement( "up_axis"))
  59.226 +			{
  59.227 +				// read content, strip whitespace, compare
  59.228 +				const char* content = GetTextContent();
  59.229 +				if( strncmp( content, "X_UP", 4) == 0)
  59.230 +					mUpDirection = UP_X;
  59.231 +				else if( strncmp( content, "Y_UP", 4) == 0)
  59.232 +					mUpDirection = UP_Y;
  59.233 +				else
  59.234 +					mUpDirection = UP_Z;
  59.235 +
  59.236 +				// check element end
  59.237 +				TestClosing( "up_axis");
  59.238 +			} else
  59.239 +			{
  59.240 +				SkipElement();
  59.241 +			}
  59.242 +		} 
  59.243 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
  59.244 +		{
  59.245 +			if( strcmp( mReader->getNodeName(), "asset") != 0)
  59.246 +				ThrowException( "Expected end of <asset> element.");
  59.247 +
  59.248 +			break;
  59.249 +		}
  59.250 +	}
  59.251 +}
  59.252 +
  59.253 +// ------------------------------------------------------------------------------------------------
  59.254 +// Reads the animation library
  59.255 +void ColladaParser::ReadAnimationLibrary()
  59.256 +{
  59.257 +	if (mReader->isEmptyElement())
  59.258 +		return;
  59.259 +
  59.260 +	while( mReader->read())
  59.261 +	{
  59.262 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
  59.263 +		{
  59.264 +			if( IsElement( "animation"))
  59.265 +			{
  59.266 +				// delegate the reading. Depending on the inner elements it will be a container or a anim channel
  59.267 +				ReadAnimation( &mAnims);
  59.268 +			} else
  59.269 +			{
  59.270 +				// ignore the rest
  59.271 +				SkipElement();
  59.272 +			}
  59.273 +		}
  59.274 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) 
  59.275 +		{
  59.276 +			if( strcmp( mReader->getNodeName(), "library_animations") != 0)
  59.277 +				ThrowException( "Expected end of <library_animations> element.");
  59.278 +
  59.279 +			break;
  59.280 +		}
  59.281 +	}
  59.282 +}
  59.283 +
  59.284 +// ------------------------------------------------------------------------------------------------
  59.285 +// Reads an animation into the given parent structure
  59.286 +void ColladaParser::ReadAnimation( Collada::Animation* pParent)
  59.287 +{
  59.288 +	if( mReader->isEmptyElement())
  59.289 +		return;
  59.290 +
  59.291 +	// an <animation> element may be a container for grouping sub-elements or an animation channel
  59.292 +	// this is the channel collection by ID, in case it has channels
  59.293 +	typedef std::map<std::string, AnimationChannel> ChannelMap;
  59.294 +	ChannelMap channels;
  59.295 +	// this is the anim container in case we're a container
  59.296 +	Animation* anim = NULL;
  59.297 +
  59.298 +	// optional name given as an attribute
  59.299 +	std::string animName;
  59.300 +	int indexName = TestAttribute( "name");
  59.301 +	int indexID = TestAttribute( "id");
  59.302 +	if( indexName >= 0)
  59.303 +		animName = mReader->getAttributeValue( indexName);
  59.304 +	else if( indexID >= 0)
  59.305 +		animName = mReader->getAttributeValue( indexID);
  59.306 +	else
  59.307 +		animName = "animation";
  59.308 +
  59.309 +	while( mReader->read())
  59.310 +	{
  59.311 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
  59.312 +		{
  59.313 +			// we have subanimations
  59.314 +			if( IsElement( "animation"))
  59.315 +			{
  59.316 +				// create container from our element
  59.317 +				if( !anim)
  59.318 +				{
  59.319 +					anim = new Animation;
  59.320 +					anim->mName = animName;
  59.321 +					pParent->mSubAnims.push_back( anim);
  59.322 +				}
  59.323 +
  59.324 +				// recurse into the subelement
  59.325 +				ReadAnimation( anim);
  59.326 +			} 
  59.327 +			else if( IsElement( "source"))
  59.328 +			{
  59.329 +				// possible animation data - we'll never know. Better store it
  59.330 +				ReadSource();
  59.331 +			} 
  59.332 +			else if( IsElement( "sampler"))
  59.333 +			{
  59.334 +				// read the ID to assign the corresponding collada channel afterwards.
  59.335 +				int indexID = GetAttribute( "id");
  59.336 +				std::string id = mReader->getAttributeValue( indexID);
  59.337 +				ChannelMap::iterator newChannel = channels.insert( std::make_pair( id, AnimationChannel())).first;
  59.338 +
  59.339 +				// have it read into a channel
  59.340 +				ReadAnimationSampler( newChannel->second);
  59.341 +			} 
  59.342 +			else if( IsElement( "channel"))
  59.343 +			{
  59.344 +				// the binding element whose whole purpose is to provide the target to animate
  59.345 +				// Thanks, Collada! A directly posted information would have been too simple, I guess.
  59.346 +				// Better add another indirection to that! Can't have enough of those.
  59.347 +				int indexTarget = GetAttribute( "target");
  59.348 +				int indexSource = GetAttribute( "source");
  59.349 +				const char* sourceId = mReader->getAttributeValue( indexSource);
  59.350 +				if( sourceId[0] == '#')
  59.351 +					sourceId++;
  59.352 +				ChannelMap::iterator cit = channels.find( sourceId);
  59.353 +				if( cit != channels.end())
  59.354 +					cit->second.mTarget = mReader->getAttributeValue( indexTarget);
  59.355 +
  59.356 +				if( !mReader->isEmptyElement())
  59.357 +					SkipElement();
  59.358 +			} 
  59.359 +			else
  59.360 +			{
  59.361 +				// ignore the rest
  59.362 +				SkipElement();
  59.363 +			}
  59.364 +		}
  59.365 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) 
  59.366 +		{
  59.367 +			if( strcmp( mReader->getNodeName(), "animation") != 0)
  59.368 +				ThrowException( "Expected end of <animation> element.");
  59.369 +
  59.370 +			break;
  59.371 +		}
  59.372 +	}
  59.373 +
  59.374 +	// it turned out to have channels - add them
  59.375 +	if( !channels.empty())
  59.376 +	{
  59.377 +		// special filtering for stupid exporters packing each channel into a separate animation
  59.378 +		if( channels.size() == 1)
  59.379 +		{
  59.380 +			pParent->mChannels.push_back( channels.begin()->second);
  59.381 +		} else
  59.382 +		{
  59.383 +			// else create the animation, if not done yet, and store the channels
  59.384 +			if( !anim)
  59.385 +			{
  59.386 +				anim = new Animation;
  59.387 +				anim->mName = animName;
  59.388 +				pParent->mSubAnims.push_back( anim);
  59.389 +			}
  59.390 +			for( ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it)
  59.391 +				anim->mChannels.push_back( it->second);
  59.392 +		}
  59.393 +	}
  59.394 +}
  59.395 +
  59.396 +// ------------------------------------------------------------------------------------------------
  59.397 +// Reads an animation sampler into the given anim channel
  59.398 +void ColladaParser::ReadAnimationSampler( Collada::AnimationChannel& pChannel)
  59.399 +{
  59.400 +	while( mReader->read())
  59.401 +	{
  59.402 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
  59.403 +		{
  59.404 +			if( IsElement( "input"))
  59.405 +			{
  59.406 +				int indexSemantic = GetAttribute( "semantic");
  59.407 +				const char* semantic = mReader->getAttributeValue( indexSemantic);
  59.408 +				int indexSource = GetAttribute( "source");
  59.409 +				const char* source = mReader->getAttributeValue( indexSource);
  59.410 +				if( source[0] != '#')
  59.411 +					ThrowException( "Unsupported URL format");
  59.412 +				source++;
  59.413 +				
  59.414 +				if( strcmp( semantic, "INPUT") == 0)
  59.415 +					pChannel.mSourceTimes = source;
  59.416 +				else if( strcmp( semantic, "OUTPUT") == 0)
  59.417 +					pChannel.mSourceValues = source;
  59.418 +
  59.419 +				if( !mReader->isEmptyElement())
  59.420 +					SkipElement();
  59.421 +			} 
  59.422 +			else
  59.423 +			{
  59.424 +				// ignore the rest
  59.425 +				SkipElement();
  59.426 +			}
  59.427 +		}
  59.428 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) 
  59.429 +		{
  59.430 +			if( strcmp( mReader->getNodeName(), "sampler") != 0)
  59.431 +				ThrowException( "Expected end of <sampler> element.");
  59.432 +
  59.433 +			break;
  59.434 +		}
  59.435 +	}
  59.436 +}
  59.437 +
  59.438 +// ------------------------------------------------------------------------------------------------
  59.439 +// Reads the skeleton controller library
  59.440 +void ColladaParser::ReadControllerLibrary()
  59.441 +{
  59.442 +	if (mReader->isEmptyElement())
  59.443 +		return;
  59.444 +
  59.445 +	while( mReader->read())
  59.446 +	{
  59.447 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
  59.448 +		{
  59.449 +			if( IsElement( "controller"))
  59.450 +			{
  59.451 +				// read ID. Ask the spec if it's neccessary or optional... you might be surprised.
  59.452 +				int attrID = GetAttribute( "id");
  59.453 +				std::string id = mReader->getAttributeValue( attrID);
  59.454 +
  59.455 +				// create an entry and store it in the library under its ID
  59.456 +				mControllerLibrary[id] = Controller();
  59.457 +
  59.458 +				// read on from there
  59.459 +				ReadController( mControllerLibrary[id]);
  59.460 +			} else
  59.461 +			{
  59.462 +				// ignore the rest
  59.463 +				SkipElement();
  59.464 +			}
  59.465 +		}
  59.466 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) 
  59.467 +		{
  59.468 +			if( strcmp( mReader->getNodeName(), "library_controllers") != 0)
  59.469 +				ThrowException( "Expected end of <library_controllers> element.");
  59.470 +
  59.471 +			break;
  59.472 +		}
  59.473 +	}
  59.474 +}
  59.475 +
  59.476 +// ------------------------------------------------------------------------------------------------
  59.477 +// Reads a controller into the given mesh structure
  59.478 +void ColladaParser::ReadController( Collada::Controller& pController)
  59.479 +{
  59.480 +	while( mReader->read())
  59.481 +	{
  59.482 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
  59.483 +		{
  59.484 +			// two types of controllers: "skin" and "morph". Only the first one is relevant, we skip the other
  59.485 +			if( IsElement( "morph"))
  59.486 +			{
  59.487 +				// should skip everything inside, so there's no danger of catching elements inbetween
  59.488 +				SkipElement();
  59.489 +			} 
  59.490 +			else if( IsElement( "skin"))
  59.491 +			{
  59.492 +				// read the mesh it refers to. According to the spec this could also be another
  59.493 +				// controller, but I refuse to implement every single idea they've come up with
  59.494 +				int sourceIndex = GetAttribute( "source");
  59.495 +				pController.mMeshId = mReader->getAttributeValue( sourceIndex) + 1;
  59.496 +			} 
  59.497 +			else if( IsElement( "bind_shape_matrix"))
  59.498 +			{
  59.499 +				// content is 16 floats to define a matrix... it seems to be important for some models
  59.500 +	      const char* content = GetTextContent();
  59.501 +
  59.502 +	      // read the 16 floats
  59.503 +	      for( unsigned int a = 0; a < 16; a++)
  59.504 +	      {
  59.505 +		      // read a number
  59.506 +          content = fast_atoreal_move<float>( content, pController.mBindShapeMatrix[a]);
  59.507 +		      // skip whitespace after it
  59.508 +		      SkipSpacesAndLineEnd( &content);
  59.509 +	      }
  59.510 +
  59.511 +        TestClosing( "bind_shape_matrix");
  59.512 +			} 
  59.513 +			else if( IsElement( "source"))
  59.514 +			{
  59.515 +				// data array - we have specialists to handle this
  59.516 +				ReadSource();
  59.517 +			} 
  59.518 +			else if( IsElement( "joints"))
  59.519 +			{
  59.520 +				ReadControllerJoints( pController);
  59.521 +			}
  59.522 +			else if( IsElement( "vertex_weights"))
  59.523 +			{
  59.524 +				ReadControllerWeights( pController);
  59.525 +			}
  59.526 +			else
  59.527 +			{
  59.528 +				// ignore the rest
  59.529 +				SkipElement();
  59.530 +			}
  59.531 +		}
  59.532 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) 
  59.533 +		{
  59.534 +			if( strcmp( mReader->getNodeName(), "controller") == 0)
  59.535 +				break;
  59.536 +			else if( strcmp( mReader->getNodeName(), "skin") != 0)
  59.537 +				ThrowException( "Expected end of <controller> element.");
  59.538 +		}
  59.539 +	}
  59.540 +}
  59.541 +
  59.542 +// ------------------------------------------------------------------------------------------------
  59.543 +// Reads the joint definitions for the given controller
  59.544 +void ColladaParser::ReadControllerJoints( Collada::Controller& pController)
  59.545 +{
  59.546 +	while( mReader->read())
  59.547 +	{
  59.548 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
  59.549 +		{
  59.550 +			// Input channels for joint data. Two possible semantics: "JOINT" and "INV_BIND_MATRIX"
  59.551 +			if( IsElement( "input"))
  59.552 +			{
  59.553 +				int indexSemantic = GetAttribute( "semantic");
  59.554 +				const char* attrSemantic = mReader->getAttributeValue( indexSemantic);
  59.555 +				int indexSource = GetAttribute( "source");
  59.556 +				const char* attrSource = mReader->getAttributeValue( indexSource);
  59.557 +
  59.558 +				// local URLS always start with a '#'. We don't support global URLs
  59.559 +				if( attrSource[0] != '#')
  59.560 +					ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\" in source attribute of <joints> data <input> element") % attrSource));
  59.561 +				attrSource++;
  59.562 +
  59.563 +				// parse source URL to corresponding source
  59.564 +				if( strcmp( attrSemantic, "JOINT") == 0)
  59.565 +					pController.mJointNameSource = attrSource;
  59.566 +				else if( strcmp( attrSemantic, "INV_BIND_MATRIX") == 0)
  59.567 +					pController.mJointOffsetMatrixSource = attrSource;
  59.568 +				else
  59.569 +					ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in <joints> data <input> element") % attrSemantic));
  59.570 +
  59.571 +				// skip inner data, if present
  59.572 +				if( !mReader->isEmptyElement())
  59.573 +					SkipElement();
  59.574 +			}
  59.575 +			else
  59.576 +			{
  59.577 +				// ignore the rest
  59.578 +				SkipElement();
  59.579 +			}
  59.580 +		}
  59.581 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) 
  59.582 +		{
  59.583 +			if( strcmp( mReader->getNodeName(), "joints") != 0)
  59.584 +				ThrowException( "Expected end of <joints> element.");
  59.585 +
  59.586 +			break;
  59.587 +		}
  59.588 +	}
  59.589 +}
  59.590 +
  59.591 +// ------------------------------------------------------------------------------------------------
  59.592 +// Reads the joint weights for the given controller
  59.593 +void ColladaParser::ReadControllerWeights( Collada::Controller& pController)
  59.594 +{
  59.595 +	// read vertex count from attributes and resize the array accordingly
  59.596 +	int indexCount = GetAttribute( "count");
  59.597 +	size_t vertexCount = (size_t) mReader->getAttributeValueAsInt( indexCount);
  59.598 +	pController.mWeightCounts.resize( vertexCount);
  59.599 +
  59.600 +	while( mReader->read())
  59.601 +	{
  59.602 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
  59.603 +		{
  59.604 +			// Input channels for weight data. Two possible semantics: "JOINT" and "WEIGHT"
  59.605 +			if( IsElement( "input") && vertexCount > 0 )
  59.606 +			{
  59.607 +				InputChannel channel;
  59.608 +
  59.609 +				int indexSemantic = GetAttribute( "semantic");
  59.610 +				const char* attrSemantic = mReader->getAttributeValue( indexSemantic);
  59.611 +				int indexSource = GetAttribute( "source");
  59.612 +				const char* attrSource = mReader->getAttributeValue( indexSource);
  59.613 +				int indexOffset = TestAttribute( "offset");
  59.614 +				if( indexOffset >= 0)
  59.615 +					channel.mOffset = mReader->getAttributeValueAsInt( indexOffset);
  59.616 +
  59.617 +				// local URLS always start with a '#'. We don't support global URLs
  59.618 +				if( attrSource[0] != '#')
  59.619 +					ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\" in source attribute of <vertex_weights> data <input> element") % attrSource));
  59.620 +				channel.mAccessor = attrSource + 1;
  59.621 +
  59.622 +				// parse source URL to corresponding source
  59.623 +				if( strcmp( attrSemantic, "JOINT") == 0)
  59.624 +					pController.mWeightInputJoints = channel;
  59.625 +				else if( strcmp( attrSemantic, "WEIGHT") == 0)
  59.626 +					pController.mWeightInputWeights = channel;
  59.627 +				else
  59.628 +					ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in <vertex_weights> data <input> element") % attrSemantic));
  59.629 +
  59.630 +				// skip inner data, if present
  59.631 +				if( !mReader->isEmptyElement())
  59.632 +					SkipElement();
  59.633 +			}
  59.634 +			else if( IsElement( "vcount") && vertexCount > 0 )
  59.635 +			{
  59.636 +				// read weight count per vertex
  59.637 +				const char* text = GetTextContent();
  59.638 +				size_t numWeights = 0;
  59.639 +				for( std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it)
  59.640 +				{
  59.641 +					if( *text == 0)
  59.642 +						ThrowException( "Out of data while reading <vcount>");
  59.643 +
  59.644 +					*it = strtoul10( text, &text);
  59.645 +					numWeights += *it;
  59.646 +					SkipSpacesAndLineEnd( &text);
  59.647 +				}
  59.648 +
  59.649 +				TestClosing( "vcount");
  59.650 +
  59.651 +				// reserve weight count 
  59.652 +				pController.mWeights.resize( numWeights);
  59.653 +			}
  59.654 +			else if( IsElement( "v") && vertexCount > 0 )
  59.655 +			{
  59.656 +				// read JointIndex - WeightIndex pairs
  59.657 +				const char* text = GetTextContent();
  59.658 +
  59.659 +				for( std::vector< std::pair<size_t, size_t> >::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it)
  59.660 +				{
  59.661 +					if( *text == 0)
  59.662 +						ThrowException( "Out of data while reading <vertex_weights>");
  59.663 +					it->first = strtoul10( text, &text);
  59.664 +					SkipSpacesAndLineEnd( &text);
  59.665 +					if( *text == 0)
  59.666 +						ThrowException( "Out of data while reading <vertex_weights>");
  59.667 +					it->second = strtoul10( text, &text);
  59.668 +					SkipSpacesAndLineEnd( &text);
  59.669 +				}
  59.670 +
  59.671 +				TestClosing( "v");
  59.672 +			}
  59.673 +			else
  59.674 +			{
  59.675 +				// ignore the rest
  59.676 +				SkipElement();
  59.677 +			}
  59.678 +		}
  59.679 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) 
  59.680 +		{
  59.681 +			if( strcmp( mReader->getNodeName(), "vertex_weights") != 0)
  59.682 +				ThrowException( "Expected end of <vertex_weights> element.");
  59.683 +
  59.684 +			break;
  59.685 +		}
  59.686 +	}
  59.687 +}
  59.688 +
  59.689 +// ------------------------------------------------------------------------------------------------
  59.690 +// Reads the image library contents
  59.691 +void ColladaParser::ReadImageLibrary()
  59.692 +{
  59.693 +	if( mReader->isEmptyElement())
  59.694 +		return;
  59.695 +
  59.696 +	while( mReader->read())
  59.697 +	{
  59.698 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
  59.699 +			if( IsElement( "image"))
  59.700 +			{
  59.701 +				// read ID. Another entry which is "optional" by design but obligatory in reality
  59.702 +				int attrID = GetAttribute( "id");
  59.703 +				std::string id = mReader->getAttributeValue( attrID);
  59.704 +
  59.705 +				// create an entry and store it in the library under its ID
  59.706 +				mImageLibrary[id] = Image();
  59.707 +
  59.708 +				// read on from there
  59.709 +				ReadImage( mImageLibrary[id]);
  59.710 +			} else
  59.711 +			{
  59.712 +				// ignore the rest
  59.713 +				SkipElement();
  59.714 +			}
  59.715 +		}
  59.716 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
  59.717 +			if( strcmp( mReader->getNodeName(), "library_images") != 0)
  59.718 +				ThrowException( "Expected end of <library_images> element.");
  59.719 +
  59.720 +			break;
  59.721 +		}
  59.722 +	}
  59.723 +}
  59.724 +
  59.725 +// ------------------------------------------------------------------------------------------------
  59.726 +// Reads an image entry into the given image
  59.727 +void ColladaParser::ReadImage( Collada::Image& pImage)
  59.728 +{
  59.729 +	while( mReader->read())
  59.730 +	{
  59.731 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT){
  59.732 +			// Need to run different code paths here, depending on the Collada XSD version
  59.733 +			if (IsElement("image")) {
  59.734 +                SkipElement();
  59.735 +            }
  59.736 +			else if(  IsElement( "init_from"))
  59.737 +			{
  59.738 +				if (mFormat == FV_1_4_n) 
  59.739 +				{
  59.740 +					// FIX: C4D exporter writes empty <init_from/> tags
  59.741 +					if (!mReader->isEmptyElement()) {
  59.742 +						// element content is filename - hopefully
  59.743 +						const char* sz = TestTextContent();
  59.744 +						if (sz)pImage.mFileName = sz;
  59.745 +						TestClosing( "init_from");
  59.746 +					}
  59.747 +					if (!pImage.mFileName.length()) {
  59.748 +						pImage.mFileName = "unknown_texture";
  59.749 +					}
  59.750 +				}
  59.751 +				else if (mFormat == FV_1_5_n) 
  59.752 +				{
  59.753 +					// make sure we skip over mip and array initializations, which
  59.754 +					// we don't support, but which could confuse the loader if 
  59.755 +					// they're not skipped.
  59.756 +					int attrib = TestAttribute("array_index");
  59.757 +					if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) {
  59.758 +						DefaultLogger::get()->warn("Collada: Ignoring texture array index");
  59.759 +						continue;
  59.760 +					}
  59.761 +
  59.762 +					attrib = TestAttribute("mip_index");
  59.763 +					if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) {
  59.764 +						DefaultLogger::get()->warn("Collada: Ignoring MIP map layer");
  59.765 +						continue;
  59.766 +					}
  59.767 +
  59.768 +					// TODO: correctly jump over cube and volume maps?
  59.769 +				}
  59.770 +			}
  59.771 +			else if (mFormat == FV_1_5_n) 
  59.772 +			{
  59.773 +				if( IsElement( "ref"))
  59.774 +				{
  59.775 +					// element content is filename - hopefully
  59.776 +					const char* sz = TestTextContent();
  59.777 +					if (sz)pImage.mFileName = sz;
  59.778 +					TestClosing( "ref");
  59.779 +				} 
  59.780 +				else if( IsElement( "hex") && !pImage.mFileName.length())
  59.781 +				{
  59.782 +					// embedded image. get format
  59.783 +					const int attrib = TestAttribute("format");
  59.784 +					if (-1 == attrib) 
  59.785 +						DefaultLogger::get()->warn("Collada: Unknown image file format");
  59.786 +					else pImage.mEmbeddedFormat = mReader->getAttributeValue(attrib);
  59.787 +
  59.788 +					const char* data = GetTextContent();
  59.789 +
  59.790 +					// hexadecimal-encoded binary octets. First of all, find the
  59.791 +					// required buffer size to reserve enough storage.
  59.792 +					const char* cur = data;
  59.793 +					while (!IsSpaceOrNewLine(*cur)) cur++;
  59.794 +
  59.795 +					const unsigned int size = (unsigned int)(cur-data) * 2;
  59.796 +					pImage.mImageData.resize(size);
  59.797 +					for (unsigned int i = 0; i < size;++i) 
  59.798 +						pImage.mImageData[i] = HexOctetToDecimal(data+(i<<1));
  59.799 +
  59.800 +					TestClosing( "hex");
  59.801 +				} 
  59.802 +			}
  59.803 +			else	
  59.804 +			{
  59.805 +				// ignore the rest
  59.806 +				SkipElement();
  59.807 +			}
  59.808 +		}
  59.809 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
  59.810 +			if( strcmp( mReader->getNodeName(), "image") == 0)
  59.811 +				break;
  59.812 +		}
  59.813 +	}
  59.814 +}
  59.815 +
  59.816 +// ------------------------------------------------------------------------------------------------
  59.817 +// Reads the material library
  59.818 +void ColladaParser::ReadMaterialLibrary()
  59.819 +{
  59.820 +	if( mReader->isEmptyElement())
  59.821 +		return;
  59.822 +
  59.823 +	while( mReader->read())
  59.824 +	{
  59.825 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
  59.826 +		{
  59.827 +			if( IsElement( "material"))
  59.828 +			{
  59.829 +				// read ID. By now you propably know my opinion about this "specification"
  59.830 +				int attrID = GetAttribute( "id");
  59.831 +				std::string id = mReader->getAttributeValue( attrID);
  59.832 +
  59.833 +				// create an entry and store it in the library under its ID
  59.834 +				ReadMaterial(mMaterialLibrary[id] = Material());
  59.835 +			} else
  59.836 +			{
  59.837 +				// ignore the rest
  59.838 +				SkipElement();
  59.839 +			}
  59.840 +		}
  59.841 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) 
  59.842 +		{
  59.843 +			if( strcmp( mReader->getNodeName(), "library_materials") != 0)
  59.844 +				ThrowException( "Expected end of <library_materials> element.");
  59.845 +
  59.846 +			break;
  59.847 +		}
  59.848 +	}
  59.849 +}
  59.850 +
  59.851 +// ------------------------------------------------------------------------------------------------
  59.852 +// Reads the light library
  59.853 +void ColladaParser::ReadLightLibrary()
  59.854 +{
  59.855 +	if( mReader->isEmptyElement())
  59.856 +		return;
  59.857 +
  59.858 +	while( mReader->read())
  59.859 +	{
  59.860 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
  59.861 +			if( IsElement( "light"))
  59.862 +			{
  59.863 +				// read ID. By now you propably know my opinion about this "specification"
  59.864 +				int attrID = GetAttribute( "id");
  59.865 +				std::string id = mReader->getAttributeValue( attrID);
  59.866 +
  59.867 +				// create an entry and store it in the library under its ID
  59.868 +				ReadLight(mLightLibrary[id] = Light());
  59.869 +
  59.870 +			} else
  59.871 +			{
  59.872 +				// ignore the rest
  59.873 +				SkipElement();
  59.874 +			}
  59.875 +		}
  59.876 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)	{
  59.877 +			if( strcmp( mReader->getNodeName(), "library_lights") != 0)
  59.878 +				ThrowException( "Expected end of <library_lights> element.");
  59.879 +
  59.880 +			break;
  59.881 +		}
  59.882 +	}
  59.883 +}
  59.884 +
  59.885 +// ------------------------------------------------------------------------------------------------
  59.886 +// Reads the camera library
  59.887 +void ColladaParser::ReadCameraLibrary()
  59.888 +{
  59.889 +	if( mReader->isEmptyElement())
  59.890 +		return;
  59.891 +
  59.892 +	while( mReader->read())
  59.893 +	{
  59.894 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
  59.895 +			if( IsElement( "camera"))
  59.896 +			{
  59.897 +				// read ID. By now you propably know my opinion about this "specification"
  59.898 +				int attrID = GetAttribute( "id");
  59.899 +				std::string id = mReader->getAttributeValue( attrID);
  59.900 +
  59.901 +				// create an entry and store it in the library under its ID
  59.902 +				Camera& cam = mCameraLibrary[id]; 
  59.903 +				attrID = TestAttribute( "name");
  59.904 +				if (attrID != -1) 
  59.905 +					cam.mName = mReader->getAttributeValue( attrID);
  59.906 +
  59.907 +				ReadCamera(cam);
  59.908 +
  59.909 +			} else
  59.910 +			{
  59.911 +				// ignore the rest
  59.912 +				SkipElement();
  59.913 +			}
  59.914 +		}
  59.915 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)	{
  59.916 +			if( strcmp( mReader->getNodeName(), "library_cameras") != 0)
  59.917 +				ThrowException( "Expected end of <library_cameras> element.");
  59.918 +
  59.919 +			break;
  59.920 +		}
  59.921 +	}
  59.922 +}
  59.923 +
  59.924 +// ------------------------------------------------------------------------------------------------
  59.925 +// Reads a material entry into the given material
  59.926 +void ColladaParser::ReadMaterial( Collada::Material& pMaterial)
  59.927 +{
  59.928 +	while( mReader->read())
  59.929 +	{
  59.930 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
  59.931 +			if (IsElement("material")) {
  59.932 +                SkipElement();
  59.933 +            }
  59.934 +			else if( IsElement( "instance_effect"))
  59.935 +			{
  59.936 +				// referred effect by URL
  59.937 +				int attrUrl = GetAttribute( "url");
  59.938 +				const char* url = mReader->getAttributeValue( attrUrl);
  59.939 +				if( url[0] != '#')
  59.940 +					ThrowException( "Unknown reference format");
  59.941 +
  59.942 +				pMaterial.mEffect = url+1;
  59.943 +
  59.944 +				SkipElement();
  59.945 +			} else
  59.946 +			{
  59.947 +				// ignore the rest
  59.948 +				SkipElement();
  59.949 +			}
  59.950 +		}
  59.951 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
  59.952 +			if( strcmp( mReader->getNodeName(), "material") != 0)
  59.953 +				ThrowException( "Expected end of <material> element.");
  59.954 +
  59.955 +			break;
  59.956 +		}
  59.957 +	}
  59.958 +}
  59.959 +
  59.960 +// ------------------------------------------------------------------------------------------------
  59.961 +// Reads a light entry into the given light
  59.962 +void ColladaParser::ReadLight( Collada::Light& pLight)
  59.963 +{
  59.964 +	while( mReader->read())
  59.965 +	{
  59.966 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
  59.967 +            if (IsElement("light")) {
  59.968 +                SkipElement();
  59.969 +            }
  59.970 +			else if (IsElement("spot")) {
  59.971 +				pLight.mType = aiLightSource_SPOT;
  59.972 +			}
  59.973 +			else if (IsElement("ambient")) {
  59.974 +				pLight.mType = aiLightSource_AMBIENT;
  59.975 +			}
  59.976 +			else if (IsElement("directional")) {
  59.977 +				pLight.mType = aiLightSource_DIRECTIONAL;
  59.978 +			}
  59.979 +			else if (IsElement("point")) {
  59.980 +				pLight.mType = aiLightSource_POINT;
  59.981 +			}
  59.982 +			else if (IsElement("color")) {
  59.983 +				// text content contains 3 floats
  59.984 +				const char* content = GetTextContent();
  59.985 +				  
  59.986 +				content = fast_atoreal_move<float>( content, (float&)pLight.mColor.r);
  59.987 +				SkipSpacesAndLineEnd( &content);
  59.988 +				
  59.989 +				content = fast_atoreal_move<float>( content, (float&)pLight.mColor.g);
  59.990 +				SkipSpacesAndLineEnd( &content);
  59.991 +
  59.992 +				content = fast_atoreal_move<float>( content, (float&)pLight.mColor.b);
  59.993 +				SkipSpacesAndLineEnd( &content);
  59.994 +
  59.995 +				TestClosing( "color");
  59.996 +			}
  59.997 +			else if (IsElement("constant_attenuation")) {
  59.998 +				pLight.mAttConstant = ReadFloatFromTextContent();
  59.999 +				TestClosing("constant_attenuation");
 59.1000 +			}
 59.1001 +			else if (IsElement("linear_attenuation")) {
 59.1002 +				pLight.mAttLinear = ReadFloatFromTextContent();
 59.1003 +				TestClosing("linear_attenuation");
 59.1004 +			}
 59.1005 +			else if (IsElement("quadratic_attenuation")) {
 59.1006 +				pLight.mAttQuadratic = ReadFloatFromTextContent();
 59.1007 +				TestClosing("quadratic_attenuation");
 59.1008 +			}
 59.1009 +			else if (IsElement("falloff_angle")) {
 59.1010 +				pLight.mFalloffAngle = ReadFloatFromTextContent();
 59.1011 +				TestClosing("falloff_angle");
 59.1012 +			}
 59.1013 +			else if (IsElement("falloff_exponent")) {
 59.1014 +				pLight.mFalloffExponent = ReadFloatFromTextContent();
 59.1015 +				TestClosing("falloff_exponent");
 59.1016 +			}
 59.1017 +			// FCOLLADA extensions 
 59.1018 +			// -------------------------------------------------------
 59.1019 +			else if (IsElement("outer_cone")) {
 59.1020 +				pLight.mOuterAngle = ReadFloatFromTextContent();
 59.1021 +				TestClosing("outer_cone");
 59.1022 +			}
 59.1023 +			// ... and this one is even deprecated
 59.1024 +			else if (IsElement("penumbra_angle")) {
 59.1025 +				pLight.mPenumbraAngle = ReadFloatFromTextContent();
 59.1026 +				TestClosing("penumbra_angle");
 59.1027 +			}
 59.1028 +			else if (IsElement("intensity")) {
 59.1029 +				pLight.mIntensity = ReadFloatFromTextContent();
 59.1030 +				TestClosing("intensity");
 59.1031 +			}
 59.1032 +			else if (IsElement("falloff")) {
 59.1033 +				pLight.mOuterAngle = ReadFloatFromTextContent();
 59.1034 +				TestClosing("falloff");
 59.1035 +			}
 59.1036 +			else if (IsElement("hotspot_beam")) {
 59.1037 +				pLight.mFalloffAngle = ReadFloatFromTextContent();
 59.1038 +				TestClosing("hotspot_beam");
 59.1039 +			}
 59.1040 +		}
 59.1041 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
 59.1042 +			if( strcmp( mReader->getNodeName(), "light") == 0)
 59.1043 +				break;
 59.1044 +		}
 59.1045 +	}
 59.1046 +}
 59.1047 +
 59.1048 +// ------------------------------------------------------------------------------------------------
 59.1049 +// Reads a camera entry into the given light
 59.1050 +void ColladaParser::ReadCamera( Collada::Camera& pCamera)
 59.1051 +{
 59.1052 +	while( mReader->read())
 59.1053 +	{
 59.1054 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
 59.1055 +			if (IsElement("camera")) {
 59.1056 +                SkipElement();
 59.1057 +            }
 59.1058 +			else if (IsElement("orthographic")) {
 59.1059 +				pCamera.mOrtho = true;
 59.1060 +			}
 59.1061 +			else if (IsElement("xfov") || IsElement("xmag")) {
 59.1062 +				pCamera.mHorFov = ReadFloatFromTextContent();
 59.1063 +				TestClosing((pCamera.mOrtho ? "xmag" : "xfov"));
 59.1064 +			}
 59.1065 +			else if (IsElement("yfov") || IsElement("ymag")) {
 59.1066 +				pCamera.mVerFov = ReadFloatFromTextContent();
 59.1067 +				TestClosing((pCamera.mOrtho ? "ymag" : "yfov"));
 59.1068 +			}
 59.1069 +			else if (IsElement("aspect_ratio")) {
 59.1070 +				pCamera.mAspect = ReadFloatFromTextContent();
 59.1071 +				TestClosing("aspect_ratio");
 59.1072 +			}
 59.1073 +			else if (IsElement("znear")) {
 59.1074 +				pCamera.mZNear = ReadFloatFromTextContent();
 59.1075 +				TestClosing("znear");
 59.1076 +			}
 59.1077 +			else if (IsElement("zfar")) {
 59.1078 +				pCamera.mZFar = ReadFloatFromTextContent();
 59.1079 +				TestClosing("zfar");
 59.1080 +			}
 59.1081 +		}
 59.1082 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
 59.1083 +			if( strcmp( mReader->getNodeName(), "camera") == 0)
 59.1084 +				break;
 59.1085 +		}
 59.1086 +	}
 59.1087 +}
 59.1088 +
 59.1089 +// ------------------------------------------------------------------------------------------------
 59.1090 +// Reads the effect library
 59.1091 +void ColladaParser::ReadEffectLibrary()
 59.1092 +{
 59.1093 +	if (mReader->isEmptyElement()) {
 59.1094 +		return;
 59.1095 +	}
 59.1096 +
 59.1097 +	while( mReader->read())
 59.1098 +	{
 59.1099 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
 59.1100 +			if( IsElement( "effect"))
 59.1101 +			{
 59.1102 +				// read ID. Do I have to repeat my ranting about "optional" attributes?
 59.1103 +				int attrID = GetAttribute( "id");
 59.1104 +				std::string id = mReader->getAttributeValue( attrID);
 59.1105 +
 59.1106 +				// create an entry and store it in the library under its ID
 59.1107 +				mEffectLibrary[id] = Effect();
 59.1108 +				// read on from there
 59.1109 +				ReadEffect( mEffectLibrary[id]);
 59.1110 +			} else
 59.1111 +			{
 59.1112 +				// ignore the rest
 59.1113 +				SkipElement();
 59.1114 +			}
 59.1115 +		}
 59.1116 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
 59.1117 +			if( strcmp( mReader->getNodeName(), "library_effects") != 0)
 59.1118 +				ThrowException( "Expected end of <library_effects> element.");
 59.1119 +
 59.1120 +			break;
 59.1121 +		}
 59.1122 +	}
 59.1123 +}
 59.1124 +
 59.1125 +// ------------------------------------------------------------------------------------------------
 59.1126 +// Reads an effect entry into the given effect
 59.1127 +void ColladaParser::ReadEffect( Collada::Effect& pEffect)
 59.1128 +{
 59.1129 +	// for the moment we don't support any other type of effect.
 59.1130 +	while( mReader->read())
 59.1131 +	{
 59.1132 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
 59.1133 +		{
 59.1134 +			if( IsElement( "profile_COMMON"))
 59.1135 +				ReadEffectProfileCommon( pEffect);
 59.1136 +			else
 59.1137 +				SkipElement();
 59.1138 +		}
 59.1139 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) 
 59.1140 +		{
 59.1141 +			if( strcmp( mReader->getNodeName(), "effect") != 0)
 59.1142 +				ThrowException( "Expected end of <effect> element.");
 59.1143 +
 59.1144 +			break;
 59.1145 +		}
 59.1146 +	}
 59.1147 +}
 59.1148 +
 59.1149 +// ------------------------------------------------------------------------------------------------
 59.1150 +// Reads an COMMON effect profile
 59.1151 +void ColladaParser::ReadEffectProfileCommon( Collada::Effect& pEffect)
 59.1152 +{
 59.1153 +	while( mReader->read())
 59.1154 +	{
 59.1155 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
 59.1156 +		{
 59.1157 +			if( IsElement( "newparam"))	{
 59.1158 +				// save ID
 59.1159 +				int attrSID = GetAttribute( "sid");
 59.1160 +				std::string sid = mReader->getAttributeValue( attrSID);
 59.1161 +				pEffect.mParams[sid] = EffectParam();
 59.1162 +				ReadEffectParam( pEffect.mParams[sid]);
 59.1163 +			} 
 59.1164 +			else if( IsElement( "technique") || IsElement( "extra"))
 59.1165 +			{
 59.1166 +				// just syntactic sugar
 59.1167 +			}
 59.1168 +
 59.1169 +			/* Shading modes */
 59.1170 +			else if( IsElement( "phong"))
 59.1171 +				pEffect.mShadeType = Shade_Phong;
 59.1172 +			else if( IsElement( "constant"))
 59.1173 +				pEffect.mShadeType = Shade_Constant;
 59.1174 +			else if( IsElement( "lambert"))
 59.1175 +				pEffect.mShadeType = Shade_Lambert;
 59.1176 +			else if( IsElement( "blinn"))
 59.1177 +				pEffect.mShadeType = Shade_Blinn;
 59.1178 +
 59.1179 +			/* Color + texture properties */
 59.1180 +			else if( IsElement( "emission"))
 59.1181 +				ReadEffectColor( pEffect.mEmissive, pEffect.mTexEmissive);
 59.1182 +			else if( IsElement( "ambient"))
 59.1183 +				ReadEffectColor( pEffect.mAmbient, pEffect.mTexAmbient);
 59.1184 +			else if( IsElement( "diffuse"))
 59.1185 +				ReadEffectColor( pEffect.mDiffuse, pEffect.mTexDiffuse);
 59.1186 +			else if( IsElement( "specular"))
 59.1187 +				ReadEffectColor( pEffect.mSpecular, pEffect.mTexSpecular);
 59.1188 +			else if( IsElement( "reflective")) {
 59.1189 +				ReadEffectColor( pEffect.mReflective, pEffect.mTexReflective);
 59.1190 +			}
 59.1191 +			else if( IsElement( "transparent")) {
 59.1192 +				ReadEffectColor( pEffect.mTransparent,pEffect.mTexTransparent);
 59.1193 +			}
 59.1194 +			else if( IsElement( "shininess"))
 59.1195 +				ReadEffectFloat( pEffect.mShininess);
 59.1196 +			else if( IsElement( "reflectivity"))
 59.1197 +				ReadEffectFloat( pEffect.mReflectivity);
 59.1198 +
 59.1199 +			/* Single scalar properties */
 59.1200 +			else if( IsElement( "transparency"))
 59.1201 +				ReadEffectFloat( pEffect.mTransparency);
 59.1202 +			else if( IsElement( "index_of_refraction"))
 59.1203 +				ReadEffectFloat( pEffect.mRefractIndex);
 59.1204 +
 59.1205 +			// GOOGLEEARTH/OKINO extensions 
 59.1206 +			// -------------------------------------------------------
 59.1207 +			else if( IsElement( "double_sided"))
 59.1208 +				pEffect.mDoubleSided = ReadBoolFromTextContent();
 59.1209 +
 59.1210 +			// FCOLLADA extensions
 59.1211 +			// -------------------------------------------------------
 59.1212 +			else if( IsElement( "bump")) {
 59.1213 +				aiColor4D dummy;
 59.1214 +				ReadEffectColor( dummy,pEffect.mTexBump);
 59.1215 +			}
 59.1216 +
 59.1217 +			// MAX3D extensions
 59.1218 +			// -------------------------------------------------------
 59.1219 +			else if( IsElement( "wireframe"))	{
 59.1220 +				pEffect.mWireframe = ReadBoolFromTextContent();
 59.1221 +				TestClosing( "wireframe");
 59.1222 +			}
 59.1223 +			else if( IsElement( "faceted"))	{
 59.1224 +				pEffect.mFaceted = ReadBoolFromTextContent();
 59.1225 +				TestClosing( "faceted");
 59.1226 +			}
 59.1227 +			else 
 59.1228 +			{
 59.1229 +				// ignore the rest
 59.1230 +				SkipElement();
 59.1231 +			}
 59.1232 +		}
 59.1233 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
 59.1234 +			if( strcmp( mReader->getNodeName(), "profile_COMMON") == 0)
 59.1235 +			{
 59.1236 +				break;
 59.1237 +			} 
 59.1238 +		}
 59.1239 +	}
 59.1240 +}
 59.1241 +
 59.1242 +// ------------------------------------------------------------------------------------------------
 59.1243 +// Read texture wrapping + UV transform settings from a profile==Maya chunk
 59.1244 +void ColladaParser::ReadSamplerProperties( Sampler& out )
 59.1245 +{
 59.1246 +	if (mReader->isEmptyElement()) {
 59.1247 +		return;
 59.1248 +	}
 59.1249 +
 59.1250 +	while( mReader->read())
 59.1251 +	{
 59.1252 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
 59.1253 +
 59.1254 +			// MAYA extensions
 59.1255 +			// -------------------------------------------------------
 59.1256 +			if( IsElement( "wrapU"))		{
 59.1257 +				out.mWrapU = ReadBoolFromTextContent();
 59.1258 +				TestClosing( "wrapU");
 59.1259 +			}
 59.1260 +			else if( IsElement( "wrapV"))	{
 59.1261 +				out.mWrapV = ReadBoolFromTextContent();
 59.1262 +				TestClosing( "wrapV");
 59.1263 +			}
 59.1264 +			else if( IsElement( "mirrorU"))		{
 59.1265 +				out.mMirrorU = ReadBoolFromTextContent();
 59.1266 +				TestClosing( "mirrorU");
 59.1267 +			}
 59.1268 +			else if( IsElement( "mirrorV"))	{
 59.1269 +				out.mMirrorV = ReadBoolFromTextContent();
 59.1270 +				TestClosing( "mirrorV");
 59.1271 +			}
 59.1272 +			else if( IsElement( "repeatU"))	{
 59.1273 +				out.mTransform.mScaling.x = ReadFloatFromTextContent();
 59.1274 +				TestClosing( "repeatU");
 59.1275 +			}
 59.1276 +			else if( IsElement( "repeatV"))	{
 59.1277 +				out.mTransform.mScaling.y = ReadFloatFromTextContent();
 59.1278 +				TestClosing( "repeatV");
 59.1279 +			}
 59.1280 +			else if( IsElement( "offsetU"))	{
 59.1281 +				out.mTransform.mTranslation.x = ReadFloatFromTextContent();
 59.1282 +				TestClosing( "offsetU");
 59.1283 +			}
 59.1284 +			else if( IsElement( "offsetV"))	{
 59.1285 +				out.mTransform.mTranslation.y = ReadFloatFromTextContent();
 59.1286 +				TestClosing( "offsetV");
 59.1287 +			}
 59.1288 +			else if( IsElement( "rotateUV"))	{
 59.1289 +				out.mTransform.mRotation = ReadFloatFromTextContent();
 59.1290 +				TestClosing( "rotateUV");
 59.1291 +			}
 59.1292 +			else if( IsElement( "blend_mode"))	{
 59.1293 +				
 59.1294 +				const char* sz = GetTextContent();
 59.1295 +				// http://www.feelingsoftware.com/content/view/55/72/lang,en/
 59.1296 +				// NONE, OVER, IN, OUT, ADD, SUBTRACT, MULTIPLY, DIFFERENCE, LIGHTEN, DARKEN, SATURATE, DESATURATE and ILLUMINATE
 59.1297 +				if (0 == ASSIMP_strincmp(sz,"ADD",3)) 
 59.1298 +					out.mOp = aiTextureOp_Add;
 59.1299 +
 59.1300 +				else if (0 == ASSIMP_strincmp(sz,"SUBTRACT",8)) 
 59.1301 +					out.mOp = aiTextureOp_Subtract;
 59.1302 +
 59.1303 +				else if (0 == ASSIMP_strincmp(sz,"MULTIPLY",8)) 
 59.1304 +					out.mOp = aiTextureOp_Multiply;
 59.1305 +
 59.1306 +				else  {
 59.1307 +					DefaultLogger::get()->warn("Collada: Unsupported MAYA texture blend mode");
 59.1308 +				}
 59.1309 +				TestClosing( "blend_mode");
 59.1310 +			}
 59.1311 +			// OKINO extensions
 59.1312 +			// -------------------------------------------------------
 59.1313 +			else if( IsElement( "weighting"))	{
 59.1314 +				out.mWeighting = ReadFloatFromTextContent();
 59.1315 +				TestClosing( "weighting");
 59.1316 +			}
 59.1317 +			else if( IsElement( "mix_with_previous_layer"))	{
 59.1318 +				out.mMixWithPrevious = ReadFloatFromTextContent();
 59.1319 +				TestClosing( "mix_with_previous_layer");
 59.1320 +			}
 59.1321 +			// MAX3D extensions
 59.1322 +			// -------------------------------------------------------
 59.1323 +			else if( IsElement( "amount"))	{
 59.1324 +				out.mWeighting = ReadFloatFromTextContent();
 59.1325 +				TestClosing( "amount");
 59.1326 +			}
 59.1327 +		}
 59.1328 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
 59.1329 +			if( strcmp( mReader->getNodeName(), "technique") == 0)
 59.1330 +				break;
 59.1331 +		}
 59.1332 +	}
 59.1333 +}
 59.1334 +
 59.1335 +// ------------------------------------------------------------------------------------------------
 59.1336 +// Reads an effect entry containing a color or a texture defining that color
 59.1337 +void ColladaParser::ReadEffectColor( aiColor4D& pColor, Sampler& pSampler)
 59.1338 +{
 59.1339 +	if (mReader->isEmptyElement())
 59.1340 +		return;
 59.1341 +
 59.1342 +	// Save current element name
 59.1343 +	const std::string curElem = mReader->getNodeName();
 59.1344 +
 59.1345 +	while( mReader->read())
 59.1346 +	{
 59.1347 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
 59.1348 +			if( IsElement( "color"))
 59.1349 +			{
 59.1350 +				// text content contains 4 floats
 59.1351 +				const char* content = GetTextContent(); 
 59.1352 +
 59.1353 +				content = fast_atoreal_move<float>( content, (float&)pColor.r);
 59.1354 +				SkipSpacesAndLineEnd( &content);
 59.1355 +
 59.1356 +				content = fast_atoreal_move<float>( content, (float&)pColor.g);
 59.1357 +				SkipSpacesAndLineEnd( &content);
 59.1358 +
 59.1359 +				content = fast_atoreal_move<float>( content, (float&)pColor.b);
 59.1360 +				SkipSpacesAndLineEnd( &content);
 59.1361 +
 59.1362 +				content = fast_atoreal_move<float>( content, (float&)pColor.a);
 59.1363 +				SkipSpacesAndLineEnd( &content);
 59.1364 +				TestClosing( "color");
 59.1365 +			} 
 59.1366 +			else if( IsElement( "texture"))
 59.1367 +			{
 59.1368 +				// get name of source textur/sampler
 59.1369 +				int attrTex = GetAttribute( "texture");
 59.1370 +				pSampler.mName = mReader->getAttributeValue( attrTex);
 59.1371 +
 59.1372 +				// get name of UV source channel. Specification demands it to be there, but some exporters
 59.1373 +				// don't write it. It will be the default UV channel in case it's missing.
 59.1374 +				attrTex = TestAttribute( "texcoord");
 59.1375 +				if( attrTex >= 0 )
 59.1376 +	  				pSampler.mUVChannel = mReader->getAttributeValue( attrTex);
 59.1377 +				//SkipElement();
 59.1378 +			}
 59.1379 +			else if( IsElement( "technique"))
 59.1380 +			{
 59.1381 +				const int _profile = GetAttribute( "profile");
 59.1382 +				const char* profile = mReader->getAttributeValue( _profile );
 59.1383 +
 59.1384 +				// Some extensions are quite useful ... ReadSamplerProperties processes
 59.1385 +				// several extensions in MAYA, OKINO and MAX3D profiles.
 59.1386 +				if (!::strcmp(profile,"MAYA") || !::strcmp(profile,"MAX3D") || !::strcmp(profile,"OKINO"))
 59.1387 +				{
 59.1388 +					// get more information on this sampler
 59.1389 +					ReadSamplerProperties(pSampler);
 59.1390 +				}
 59.1391 +				else SkipElement();
 59.1392 +			}
 59.1393 +			else if( !IsElement( "extra"))
 59.1394 +			{
 59.1395 +				// ignore the rest
 59.1396 +				SkipElement();
 59.1397 +			}
 59.1398 +		}
 59.1399 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){
 59.1400 +			if (mReader->getNodeName() == curElem)
 59.1401 +				break;
 59.1402 +		}
 59.1403 +	}
 59.1404 +}
 59.1405 +
 59.1406 +// ------------------------------------------------------------------------------------------------
 59.1407 +// Reads an effect entry containing a float
 59.1408 +void ColladaParser::ReadEffectFloat( float& pFloat)
 59.1409 +{
 59.1410 +	while( mReader->read())
 59.1411 +	{
 59.1412 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT){
 59.1413 +			if( IsElement( "float"))
 59.1414 +			{
 59.1415 +				// text content contains a single floats
 59.1416 +				const char* content = GetTextContent();
 59.1417 +				content = fast_atoreal_move<float>( content, pFloat);
 59.1418 +				SkipSpacesAndLineEnd( &content);
 59.1419 +
 59.1420 +				TestClosing( "float");
 59.1421 +			} else
 59.1422 +			{
 59.1423 +				// ignore the rest
 59.1424 +				SkipElement();
 59.1425 +			}
 59.1426 +		}
 59.1427 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){
 59.1428 +			break;
 59.1429 +		}
 59.1430 +	}
 59.1431 +}
 59.1432 +
 59.1433 +// ------------------------------------------------------------------------------------------------
 59.1434 +// Reads an effect parameter specification of any kind 
 59.1435 +void ColladaParser::ReadEffectParam( Collada::EffectParam& pParam)
 59.1436 +{
 59.1437 +	while( mReader->read())
 59.1438 +	{
 59.1439 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
 59.1440 +			if( IsElement( "surface"))
 59.1441 +			{
 59.1442 +				// image ID given inside <init_from> tags
 59.1443 +				TestOpening( "init_from");
 59.1444 +				const char* content = GetTextContent();
 59.1445 +				pParam.mType = Param_Surface;
 59.1446 +				pParam.mReference = content;
 59.1447 +				TestClosing( "init_from");
 59.1448 +
 59.1449 +				// don't care for remaining stuff
 59.1450 +				SkipElement( "surface");
 59.1451 +			} 
 59.1452 +			else if( IsElement( "sampler2D"))
 59.1453 +			{
 59.1454 +				// surface ID is given inside <source> tags
 59.1455 +				TestOpening( "source");
 59.1456 +				const char* content = GetTextContent();
 59.1457 +				pParam.mType = Param_Sampler;
 59.1458 +				pParam.mReference = content;
 59.1459 +				TestClosing( "source");
 59.1460 +
 59.1461 +				// don't care for remaining stuff
 59.1462 +				SkipElement( "sampler2D");
 59.1463 +			} else
 59.1464 +			{
 59.1465 +				// ignore unknown element
 59.1466 +				SkipElement();
 59.1467 +			}
 59.1468 +		}
 59.1469 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
 59.1470 +			break;
 59.1471 +		}
 59.1472 +	}
 59.1473 +}
 59.1474 +
 59.1475 +// ------------------------------------------------------------------------------------------------
 59.1476 +// Reads the geometry library contents
 59.1477 +void ColladaParser::ReadGeometryLibrary()
 59.1478 +{
 59.1479 +	if( mReader->isEmptyElement())
 59.1480 +		return;
 59.1481 +
 59.1482 +	while( mReader->read())
 59.1483 +	{
 59.1484 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
 59.1485 +		{
 59.1486 +			if( IsElement( "geometry"))
 59.1487 +			{
 59.1488 +				// read ID. Another entry which is "optional" by design but obligatory in reality
 59.1489 +				int indexID = GetAttribute( "id");
 59.1490 +				std::string id = mReader->getAttributeValue( indexID);
 59.1491 +
 59.1492 +				// TODO: (thom) support SIDs
 59.1493 +				// ai_assert( TestAttribute( "sid") == -1);
 59.1494 +
 59.1495 +				// create a mesh and store it in the library under its ID
 59.1496 +				Mesh* mesh = new Mesh;
 59.1497 +				mMeshLibrary[id] = mesh;
 59.1498 +
 59.1499 +				// read on from there
 59.1500 +				ReadGeometry( mesh);
 59.1501 +			} else
 59.1502 +			{
 59.1503 +				// ignore the rest
 59.1504 +				SkipElement();
 59.1505 +			}
 59.1506 +		}
 59.1507 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
 59.1508 +		{
 59.1509 +			if( strcmp( mReader->getNodeName(), "library_geometries") != 0)
 59.1510 +				ThrowException( "Expected end of <library_geometries> element.");
 59.1511 +
 59.1512 +			break;
 59.1513 +		}
 59.1514 +	}
 59.1515 +}
 59.1516 +
 59.1517 +// ------------------------------------------------------------------------------------------------
 59.1518 +// Reads a geometry from the geometry library.
 59.1519 +void ColladaParser::ReadGeometry( Collada::Mesh* pMesh)
 59.1520 +{
 59.1521 +	if( mReader->isEmptyElement())
 59.1522 +		return;
 59.1523 +
 59.1524 +	while( mReader->read())
 59.1525 +	{
 59.1526 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
 59.1527 +		{
 59.1528 +			if( IsElement( "mesh"))
 59.1529 +			{
 59.1530 +				// read on from there
 59.1531 +				ReadMesh( pMesh);
 59.1532 +			} else
 59.1533 +			{
 59.1534 +				// ignore the rest
 59.1535 +				SkipElement();
 59.1536 +			}
 59.1537 +		}
 59.1538 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
 59.1539 +		{
 59.1540 +			if( strcmp( mReader->getNodeName(), "geometry") != 0)
 59.1541 +				ThrowException( "Expected end of <geometry> element.");
 59.1542 +
 59.1543 +			break;
 59.1544 +		}
 59.1545 +	}
 59.1546 +}
 59.1547 +
 59.1548 +// ------------------------------------------------------------------------------------------------
 59.1549 +// Reads a mesh from the geometry library
 59.1550 +void ColladaParser::ReadMesh( Mesh* pMesh)
 59.1551 +{
 59.1552 +	if( mReader->isEmptyElement())
 59.1553 +		return;
 59.1554 +
 59.1555 +	while( mReader->read())
 59.1556 +	{
 59.1557 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
 59.1558 +		{
 59.1559 +			if( IsElement( "source"))
 59.1560 +			{
 59.1561 +				// we have professionals dealing with this
 59.1562 +				ReadSource();
 59.1563 +			}
 59.1564 +			else if( IsElement( "vertices"))
 59.1565 +			{
 59.1566 +				// read per-vertex mesh data
 59.1567 +				ReadVertexData( pMesh);
 59.1568 +			}
 59.1569 +			else if( IsElement( "triangles") || IsElement( "lines") || IsElement( "linestrips")
 59.1570 +				|| IsElement( "polygons") || IsElement( "polylist") || IsElement( "trifans") || IsElement( "tristrips")) 
 59.1571 +			{
 59.1572 +				// read per-index mesh data and faces setup
 59.1573 +				ReadIndexData( pMesh);
 59.1574 +			} else
 59.1575 +			{
 59.1576 +				// ignore the rest
 59.1577 +				SkipElement();
 59.1578 +			}
 59.1579 +		}
 59.1580 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
 59.1581 +		{
 59.1582 +			if( strcmp( mReader->getNodeName(), "technique_common") == 0)
 59.1583 +			{
 59.1584 +				// end of another meaningless element - read over it
 59.1585 +			} 
 59.1586 +			else if( strcmp( mReader->getNodeName(), "mesh") == 0)
 59.1587 +			{
 59.1588 +				// end of <mesh> element - we're done here
 59.1589 +				break;
 59.1590 +			} else
 59.1591 +			{
 59.1592 +				// everything else should be punished
 59.1593 +				ThrowException( "Expected end of <mesh> element.");
 59.1594 +			}
 59.1595 +		}
 59.1596 +	}
 59.1597 +}
 59.1598 +
 59.1599 +// ------------------------------------------------------------------------------------------------
 59.1600 +// Reads a source element 
 59.1601 +void ColladaParser::ReadSource()
 59.1602 +{
 59.1603 +	int indexID = GetAttribute( "id");
 59.1604 +	std::string sourceID = mReader->getAttributeValue( indexID);
 59.1605 +
 59.1606 +	while( mReader->read())
 59.1607 +	{
 59.1608 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
 59.1609 +		{
 59.1610 +			if( IsElement( "float_array") || IsElement( "IDREF_array") || IsElement( "Name_array"))
 59.1611 +			{
 59.1612 +				ReadDataArray();
 59.1613 +			}
 59.1614 +			else if( IsElement( "technique_common"))
 59.1615 +			{
 59.1616 +				// I don't care for your profiles 
 59.1617 +			}
 59.1618 +			else if( IsElement( "accessor"))
 59.1619 +			{
 59.1620 +				ReadAccessor( sourceID);
 59.1621 +			} else
 59.1622 +			{
 59.1623 +				// ignore the rest
 59.1624 +				SkipElement();
 59.1625 +			}
 59.1626 +		}
 59.1627 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
 59.1628 +		{
 59.1629 +			if( strcmp( mReader->getNodeName(), "source") == 0)
 59.1630 +			{
 59.1631 +				// end of <source> - we're done
 59.1632 +				break;
 59.1633 +			}
 59.1634 +			else if( strcmp( mReader->getNodeName(), "technique_common") == 0)
 59.1635 +			{
 59.1636 +				// end of another meaningless element - read over it
 59.1637 +			} else
 59.1638 +			{
 59.1639 +				// everything else should be punished
 59.1640 +				ThrowException( "Expected end of <source> element.");
 59.1641 +			}
 59.1642 +		}
 59.1643 +	}
 59.1644 +}
 59.1645 +
 59.1646 +// ------------------------------------------------------------------------------------------------
 59.1647 +// Reads a data array holding a number of floats, and stores it in the global library
 59.1648 +void ColladaParser::ReadDataArray()
 59.1649 +{
 59.1650 +	std::string elmName = mReader->getNodeName();
 59.1651 +	bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array");
 59.1652 +  bool isEmptyElement = mReader->isEmptyElement();
 59.1653 +
 59.1654 +	// read attributes
 59.1655 +	int indexID = GetAttribute( "id");
 59.1656 +	std::string id = mReader->getAttributeValue( indexID);
 59.1657 +	int indexCount = GetAttribute( "count");
 59.1658 +	unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( indexCount);
 59.1659 +	if (count == 0) { return; } // some exporters write empty data arrays with count="0"
 59.1660 +	const char* content = TestTextContent();
 59.1661 +
 59.1662 +  // read values and store inside an array in the data library
 59.1663 +  mDataLibrary[id] = Data();
 59.1664 +  Data& data = mDataLibrary[id];
 59.1665 +  data.mIsStringArray = isStringArray;
 59.1666 +
 59.1667 +  // some exporters write empty data arrays, but we need to conserve them anyways because others might reference them
 59.1668 +  if (content) 
 59.1669 +  { 
 59.1670 +		if( isStringArray)
 59.1671 +		{
 59.1672 +			data.mStrings.reserve( count);
 59.1673 +			std::string s;
 59.1674 +
 59.1675 +			for( unsigned int a = 0; a < count; a++)
 59.1676 +			{
 59.1677 +				if( *content == 0)
 59.1678 +					ThrowException( "Expected more values while reading IDREF_array contents.");
 59.1679 +
 59.1680 +				s.clear();
 59.1681 +				while( !IsSpaceOrNewLine( *content))
 59.1682 +					s += *content++;
 59.1683 +				data.mStrings.push_back( s);
 59.1684 +
 59.1685 +				SkipSpacesAndLineEnd( &content);
 59.1686 +			}
 59.1687 +		} else
 59.1688 +		{
 59.1689 +			data.mValues.reserve( count);
 59.1690 +
 59.1691 +			for( unsigned int a = 0; a < count; a++)
 59.1692 +			{
 59.1693 +				if( *content == 0)
 59.1694 +					ThrowException( "Expected more values while reading float_array contents.");
 59.1695 +
 59.1696 +				float value;
 59.1697 +				// read a number
 59.1698 +				content = fast_atoreal_move<float>( content, value);
 59.1699 +				data.mValues.push_back( value);
 59.1700 +				// skip whitespace after it
 59.1701 +				SkipSpacesAndLineEnd( &content);
 59.1702 +			}
 59.1703 +		}
 59.1704 +	}
 59.1705 +
 59.1706 +  // test for closing tag
 59.1707 +  if( !isEmptyElement )
 59.1708 +    TestClosing( elmName.c_str());
 59.1709 +}
 59.1710 +
 59.1711 +// ------------------------------------------------------------------------------------------------
 59.1712 +// Reads an accessor and stores it in the global library
 59.1713 +void ColladaParser::ReadAccessor( const std::string& pID)
 59.1714 +{
 59.1715 +	// read accessor attributes
 59.1716 +	int attrSource = GetAttribute( "source");
 59.1717 +	const char* source = mReader->getAttributeValue( attrSource);
 59.1718 +	if( source[0] != '#')
 59.1719 +		ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\" in source attribute of <accessor> element.") % source));
 59.1720 +	int attrCount = GetAttribute( "count");
 59.1721 +	unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( attrCount);
 59.1722 +	int attrOffset = TestAttribute( "offset");
 59.1723 +	unsigned int offset = 0;
 59.1724 +	if( attrOffset > -1)
 59.1725 +		offset = (unsigned int) mReader->getAttributeValueAsInt( attrOffset);
 59.1726 +	int attrStride = TestAttribute( "stride");
 59.1727 +	unsigned int stride = 1;
 59.1728 +	if( attrStride > -1)
 59.1729 +		stride = (unsigned int) mReader->getAttributeValueAsInt( attrStride);
 59.1730 +
 59.1731 +	// store in the library under the given ID
 59.1732 +	mAccessorLibrary[pID] = Accessor();
 59.1733 +	Accessor& acc = mAccessorLibrary[pID];
 59.1734 +	acc.mCount = count;
 59.1735 +	acc.mOffset = offset;
 59.1736 +	acc.mStride = stride;
 59.1737 +	acc.mSource = source+1; // ignore the leading '#'
 59.1738 +	acc.mSize = 0; // gets incremented with every param
 59.1739 +
 59.1740 +	// and read the components
 59.1741 +	while( mReader->read())
 59.1742 +	{
 59.1743 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
 59.1744 +		{
 59.1745 +			if( IsElement( "param"))
 59.1746 +			{
 59.1747 +				// read data param
 59.1748 +				int attrName = TestAttribute( "name");
 59.1749 +				std::string name;
 59.1750 +				if( attrName > -1)
 59.1751 +				{
 59.1752 +					name = mReader->getAttributeValue( attrName);
 59.1753 +
 59.1754 +					// analyse for common type components and store it's sub-offset in the corresponding field
 59.1755 +
 59.1756 +					/* Cartesian coordinates */
 59.1757 +					if( name == "X") acc.mSubOffset[0] = acc.mParams.size();
 59.1758 +					else if( name == "Y") acc.mSubOffset[1] = acc.mParams.size();
 59.1759 +					else if( name == "Z") acc.mSubOffset[2] = acc.mParams.size();
 59.1760 +
 59.1761 +					/* RGBA colors */
 59.1762 +					else if( name == "R") acc.mSubOffset[0] = acc.mParams.size();
 59.1763 +					else if( name == "G") acc.mSubOffset[1] = acc.mParams.size();
 59.1764 +					else if( name == "B") acc.mSubOffset[2] = acc.mParams.size();
 59.1765 +					else if( name == "A") acc.mSubOffset[3] = acc.mParams.size();
 59.1766 +
 59.1767 +					/* UVWQ (STPQ) texture coordinates */
 59.1768 +					else if( name == "S") acc.mSubOffset[0] = acc.mParams.size();
 59.1769 +					else if( name == "T") acc.mSubOffset[1] = acc.mParams.size();
 59.1770 +					else if( name == "P") acc.mSubOffset[2] = acc.mParams.size();
 59.1771 +				//	else if( name == "Q") acc.mSubOffset[3] = acc.mParams.size(); 
 59.1772 +					/* 4D uv coordinates are not supported in Assimp */
 59.1773 +
 59.1774 +					/* Generic extra data, interpreted as UV data, too*/
 59.1775 +					else if( name == "U") acc.mSubOffset[0] = acc.mParams.size();
 59.1776 +					else if( name == "V") acc.mSubOffset[1] = acc.mParams.size();
 59.1777 +					//else
 59.1778 +					//	DefaultLogger::get()->warn( boost::str( boost::format( "Unknown accessor parameter \"%s\". Ignoring data channel.") % name));
 59.1779 +				}
 59.1780 +
 59.1781 +				// read data type
 59.1782 +				int attrType = TestAttribute( "type");
 59.1783 +				if( attrType > -1)
 59.1784 +				{
 59.1785 +					// for the moment we only distinguish between a 4x4 matrix and anything else. 
 59.1786 +					// TODO: (thom) I don't have a spec here at work. Check if there are other multi-value types
 59.1787 +					// which should be tested for here.
 59.1788 +					std::string type = mReader->getAttributeValue( attrType);
 59.1789 +					if( type == "float4x4")
 59.1790 +						acc.mSize += 16;
 59.1791 +					else 
 59.1792 +						acc.mSize += 1;
 59.1793 +				}
 59.1794 +
 59.1795 +				acc.mParams.push_back( name);
 59.1796 +
 59.1797 +				// skip remaining stuff of this element, if any
 59.1798 +				SkipElement();
 59.1799 +			} else
 59.1800 +			{
 59.1801 +				ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <accessor>") % mReader->getNodeName()));
 59.1802 +			}
 59.1803 +		} 
 59.1804 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
 59.1805 +		{
 59.1806 +			if( strcmp( mReader->getNodeName(), "accessor") != 0)
 59.1807 +				ThrowException( "Expected end of <accessor> element.");
 59.1808 +			break;
 59.1809 +		}
 59.1810 +	}
 59.1811 +}
 59.1812 +
 59.1813 +// ------------------------------------------------------------------------------------------------
 59.1814 +// Reads input declarations of per-vertex mesh data into the given mesh
 59.1815 +void ColladaParser::ReadVertexData( Mesh* pMesh)
 59.1816 +{
 59.1817 +	// extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about
 59.1818 +	int attrID= GetAttribute( "id");
 59.1819 +	pMesh->mVertexID = mReader->getAttributeValue( attrID);
 59.1820 +
 59.1821 +	// a number of <input> elements
 59.1822 +	while( mReader->read())
 59.1823 +	{
 59.1824 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
 59.1825 +		{
 59.1826 +			if( IsElement( "input"))
 59.1827 +			{
 59.1828 +				ReadInputChannel( pMesh->mPerVertexData);
 59.1829 +			} else
 59.1830 +			{
 59.1831 +				ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <vertices>") % mReader->getNodeName()));
 59.1832 +			}
 59.1833 +		} 
 59.1834 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
 59.1835 +		{
 59.1836 +			if( strcmp( mReader->getNodeName(), "vertices") != 0)
 59.1837 +				ThrowException( "Expected end of <vertices> element.");
 59.1838 +
 59.1839 +			break;
 59.1840 +		}
 59.1841 +	}
 59.1842 +}
 59.1843 +
 59.1844 +// ------------------------------------------------------------------------------------------------
 59.1845 +// Reads input declarations of per-index mesh data into the given mesh
 59.1846 +void ColladaParser::ReadIndexData( Mesh* pMesh)
 59.1847 +{
 59.1848 +	std::vector<size_t> vcount;
 59.1849 +	std::vector<InputChannel> perIndexData;
 59.1850 +
 59.1851 +	// read primitive count from the attribute
 59.1852 +	int attrCount = GetAttribute( "count");
 59.1853 +	size_t numPrimitives = (size_t) mReader->getAttributeValueAsInt( attrCount);
 59.1854 +
 59.1855 +	// material subgroup 
 59.1856 +	int attrMaterial = TestAttribute( "material");
 59.1857 +	SubMesh subgroup;
 59.1858 +	if( attrMaterial > -1)
 59.1859 +		subgroup.mMaterial = mReader->getAttributeValue( attrMaterial);
 59.1860 +	subgroup.mNumFaces = numPrimitives;
 59.1861 +	pMesh->mSubMeshes.push_back( subgroup);
 59.1862 +
 59.1863 +	// distinguish between polys and triangles
 59.1864 +	std::string elementName = mReader->getNodeName();
 59.1865 +	PrimitiveType primType = Prim_Invalid;
 59.1866 +	if( IsElement( "lines"))
 59.1867 +		primType = Prim_Lines;
 59.1868 +	else if( IsElement( "linestrips"))
 59.1869 +		primType = Prim_LineStrip;
 59.1870 +	else if( IsElement( "polygons"))
 59.1871 +		primType = Prim_Polygon;
 59.1872 +	else if( IsElement( "polylist"))
 59.1873 +		primType = Prim_Polylist;
 59.1874 +	else if( IsElement( "triangles"))
 59.1875 +		primType = Prim_Triangles;
 59.1876 +	else if( IsElement( "trifans"))
 59.1877 +		primType = Prim_TriFans;
 59.1878 +	else if( IsElement( "tristrips"))
 59.1879 +		primType = Prim_TriStrips;
 59.1880 +
 59.1881 +	ai_assert( primType != Prim_Invalid);
 59.1882 +
 59.1883 +	// also a number of <input> elements, but in addition a <p> primitive collection and propably index counts for all primitives
 59.1884 +	while( mReader->read())
 59.1885 +	{
 59.1886 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
 59.1887 +		{
 59.1888 +			if( IsElement( "input"))
 59.1889 +			{
 59.1890 +				ReadInputChannel( perIndexData);
 59.1891 +			} 
 59.1892 +			else if( IsElement( "vcount"))
 59.1893 +			{
 59.1894 +				if( !mReader->isEmptyElement())
 59.1895 +				{
 59.1896 +					if (numPrimitives)	// It is possible to define a mesh without any primitives
 59.1897 +					{
 59.1898 +						// case <polylist> - specifies the number of indices for each polygon
 59.1899 +						const char* content = GetTextContent();
 59.1900 +						vcount.reserve( numPrimitives);
 59.1901 +						for( unsigned int a = 0; a < numPrimitives; a++)
 59.1902 +						{
 59.1903 +							if( *content == 0)
 59.1904 +								ThrowException( "Expected more values while reading <vcount> contents.");
 59.1905 +							// read a number
 59.1906 +							vcount.push_back( (size_t) strtoul10( content, &content));
 59.1907 +							// skip whitespace after it
 59.1908 +							SkipSpacesAndLineEnd( &content);
 59.1909 +						}
 59.1910 +					}
 59.1911 +
 59.1912 +					TestClosing( "vcount");
 59.1913 +				}
 59.1914 +			}
 59.1915 +			else if( IsElement( "p"))
 59.1916 +			{
 59.1917 +				if( !mReader->isEmptyElement())
 59.1918 +				{
 59.1919 +					// now here the actual fun starts - these are the indices to construct the mesh data from
 59.1920 +					ReadPrimitives( pMesh, perIndexData, numPrimitives, vcount, primType);
 59.1921 +				}
 59.1922 +			} else
 59.1923 +			{
 59.1924 +				ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <%s>") % mReader->getNodeName() % elementName));
 59.1925 +			}
 59.1926 +		} 
 59.1927 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
 59.1928 +		{
 59.1929 +			if( mReader->getNodeName() != elementName)
 59.1930 +				ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % elementName));
 59.1931 +
 59.1932 +			break;
 59.1933 +		}
 59.1934 +	}
 59.1935 +}
 59.1936 +
 59.1937 +// ------------------------------------------------------------------------------------------------
 59.1938 +// Reads a single input channel element and stores it in the given array, if valid 
 59.1939 +void ColladaParser::ReadInputChannel( std::vector<InputChannel>& poChannels)
 59.1940 +{
 59.1941 +	InputChannel channel;
 59.1942 +	
 59.1943 +	// read semantic
 59.1944 +	int attrSemantic = GetAttribute( "semantic");
 59.1945 +	std::string semantic = mReader->getAttributeValue( attrSemantic);
 59.1946 +	channel.mType = GetTypeForSemantic( semantic);
 59.1947 +
 59.1948 +	// read source
 59.1949 +	int attrSource = GetAttribute( "source");
 59.1950 +	const char* source = mReader->getAttributeValue( attrSource);
 59.1951 +	if( source[0] != '#')
 59.1952 +		ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\" in source attribute of <input> element.") % source));
 59.1953 +	channel.mAccessor = source+1; // skipping the leading #, hopefully the remaining text is the accessor ID only
 59.1954 +
 59.1955 +	// read index offset, if per-index <input>
 59.1956 +	int attrOffset = TestAttribute( "offset");
 59.1957 +	if( attrOffset > -1)
 59.1958 +		channel.mOffset = mReader->getAttributeValueAsInt( attrOffset);
 59.1959 +
 59.1960 +	// read set if texture coordinates
 59.1961 +	if(channel.mType == IT_Texcoord || channel.mType == IT_Color){
 59.1962 +		int attrSet = TestAttribute("set");
 59.1963 +		if(attrSet > -1){
 59.1964 +			attrSet = mReader->getAttributeValueAsInt( attrSet);
 59.1965 +			if(attrSet < 0)
 59.1966 +				ThrowException( boost::str( boost::format( "Invalid index \"%i\" in set attribute of <input> element") % (attrSet)));
 59.1967 +			
 59.1968 +			channel.mIndex = attrSet;
 59.1969 +		}
 59.1970 +	}
 59.1971 +
 59.1972 +	// store, if valid type
 59.1973 +	if( channel.mType != IT_Invalid)
 59.1974 +		poChannels.push_back( channel);
 59.1975 +
 59.1976 +	// skip remaining stuff of this element, if any
 59.1977 +	SkipElement();
 59.1978 +}
 59.1979 +
 59.1980 +// ------------------------------------------------------------------------------------------------
 59.1981 +// Reads a <p> primitive index list and assembles the mesh data into the given mesh
 59.1982 +void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels, 
 59.1983 +	size_t pNumPrimitives, const std::vector<size_t>& pVCount, PrimitiveType pPrimType)
 59.1984 +{
 59.1985 +	// determine number of indices coming per vertex 
 59.1986 +	// find the offset index for all per-vertex channels
 59.1987 +	size_t numOffsets = 1;
 59.1988 +	size_t perVertexOffset = SIZE_MAX; // invalid value
 59.1989 +	BOOST_FOREACH( const InputChannel& channel, pPerIndexChannels)
 59.1990 +	{
 59.1991 +		numOffsets = std::max( numOffsets, channel.mOffset+1);
 59.1992 +		if( channel.mType == IT_Vertex)
 59.1993 +			perVertexOffset = channel.mOffset;
 59.1994 +	}
 59.1995 +
 59.1996 +	// determine the expected number of indices 
 59.1997 +	size_t expectedPointCount = 0;
 59.1998 +	switch( pPrimType)
 59.1999 +	{
 59.2000 +		case Prim_Polylist:
 59.2001 +		{
 59.2002 +			BOOST_FOREACH( size_t i, pVCount)
 59.2003 +				expectedPointCount += i;
 59.2004 +			break;
 59.2005 +		}
 59.2006 +		case Prim_Lines:
 59.2007 +			expectedPointCount = 2 * pNumPrimitives;
 59.2008 +			break;
 59.2009 +		case Prim_Triangles:
 59.2010 +			expectedPointCount = 3 * pNumPrimitives;
 59.2011 +			break;
 59.2012 +		default:
 59.2013 +			// other primitive types don't state the index count upfront... we need to guess
 59.2014 +			break;
 59.2015 +	}
 59.2016 +
 59.2017 +	// and read all indices into a temporary array
 59.2018 +	std::vector<size_t> indices;
 59.2019 +	if( expectedPointCount > 0)
 59.2020 +		indices.reserve( expectedPointCount * numOffsets);
 59.2021 +
 59.2022 +	if (pNumPrimitives > 0)	// It is possible to not contain any indicies
 59.2023 +	{
 59.2024 +		const char* content = GetTextContent();
 59.2025 +		while( *content != 0)
 59.2026 +		{
 59.2027 +			// read a value. 
 59.2028 +			// Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways.
 59.2029 +			int value = std::max( 0, strtol10( content, &content));
 59.2030 +			indices.push_back( size_t( value));
 59.2031 +			// skip whitespace after it
 59.2032 +			SkipSpacesAndLineEnd( &content);
 59.2033 +		}
 59.2034 +	}
 59.2035 +
 59.2036 +	// complain if the index count doesn't fit
 59.2037 +	if( expectedPointCount > 0 && indices.size() != expectedPointCount * numOffsets)
 59.2038 +		ThrowException( "Expected different index count in <p> element.");
 59.2039 +	else if( expectedPointCount == 0 && (indices.size() % numOffsets) != 0)
 59.2040 +		ThrowException( "Expected different index count in <p> element.");
 59.2041 +
 59.2042 +	// find the data for all sources
 59.2043 +  for( std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)
 59.2044 +	{
 59.2045 +    InputChannel& input = *it;
 59.2046 +		if( input.mResolved)
 59.2047 +			continue;
 59.2048 +
 59.2049 +		// find accessor
 59.2050 +		input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor);
 59.2051 +		// resolve accessor's data pointer as well, if neccessary
 59.2052 +		const Accessor* acc = input.mResolved;
 59.2053 +		if( !acc->mData)
 59.2054 +			acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource);
 59.2055 +	}
 59.2056 +	// and the same for the per-index channels
 59.2057 +  for( std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it)
 59.2058 +  {
 59.2059 +    InputChannel& input = *it;
 59.2060 +		if( input.mResolved)
 59.2061 +			continue;
 59.2062 +
 59.2063 +		// ignore vertex pointer, it doesn't refer to an accessor
 59.2064 +		if( input.mType == IT_Vertex)
 59.2065 +		{
 59.2066 +			// warn if the vertex channel does not refer to the <vertices> element in the same mesh
 59.2067 +			if( input.mAccessor != pMesh->mVertexID)
 59.2068 +				ThrowException( "Unsupported vertex referencing scheme.");
 59.2069 +			continue;
 59.2070 +		}
 59.2071 +
 59.2072 +		// find accessor
 59.2073 +		input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor);
 59.2074 +		// resolve accessor's data pointer as well, if neccessary
 59.2075 +		const Accessor* acc = input.mResolved;
 59.2076 +		if( !acc->mData)
 59.2077 +			acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource);
 59.2078 +	}
 59.2079 +
 59.2080 +
 59.2081 +	// now assemble vertex data according to those indices
 59.2082 +	std::vector<size_t>::const_iterator idx = indices.begin();
 59.2083 +
 59.2084 +	// For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
 59.2085 +	size_t numPrimitives = pNumPrimitives;
 59.2086 +	if( pPrimType == Prim_TriFans || pPrimType == Prim_Polygon)
 59.2087 +		numPrimitives = 1;
 59.2088 +
 59.2089 +	pMesh->mFaceSize.reserve( numPrimitives);
 59.2090 +	pMesh->mFacePosIndices.reserve( indices.size() / numOffsets);
 59.2091 +
 59.2092 +	for( size_t a = 0; a < numPrimitives; a++)
 59.2093 +	{
 59.2094 +		// determine number of points for this primitive
 59.2095 +		size_t numPoints = 0;
 59.2096 +		switch( pPrimType)
 59.2097 +		{
 59.2098 +			case Prim_Lines:
 59.2099 +				numPoints = 2; 
 59.2100 +				break;
 59.2101 +			case Prim_Triangles: 
 59.2102 +				numPoints = 3; 
 59.2103 +				break;
 59.2104 +			case Prim_Polylist: 
 59.2105 +				numPoints = pVCount[a];
 59.2106 +				break;
 59.2107 +			case Prim_TriFans: 
 59.2108 +			case Prim_Polygon:
 59.2109 +				numPoints = indices.size() / numOffsets; 
 59.2110 +				break;
 59.2111 +			default:
 59.2112 +				// LineStrip and TriStrip not supported due to expected index unmangling
 59.2113 +				ThrowException( "Unsupported primitive type.");
 59.2114 +				break;
 59.2115 +		}
 59.2116 +
 59.2117 +		// store the face size to later reconstruct the face from
 59.2118 +		pMesh->mFaceSize.push_back( numPoints);
 59.2119 +
 59.2120 +		// gather that number of vertices
 59.2121 +		for( size_t b = 0; b < numPoints; b++)
 59.2122 +		{
 59.2123 +			// read all indices for this vertex. Yes, in a hacky local array
 59.2124 +			ai_assert( numOffsets < 20 && perVertexOffset < 20);
 59.2125 +			size_t vindex[20];
 59.2126 +			for( size_t offsets = 0; offsets < numOffsets; ++offsets)
 59.2127 +				vindex[offsets] = *idx++;
 59.2128 +
 59.2129 +			// extract per-vertex channels using the global per-vertex offset
 59.2130 +      for( std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)
 59.2131 +        ExtractDataObjectFromChannel( *it, vindex[perVertexOffset], pMesh);
 59.2132 +			// and extract per-index channels using there specified offset
 59.2133 +      for( std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it)
 59.2134 +				ExtractDataObjectFromChannel( *it, vindex[it->mOffset], pMesh);
 59.2135 +
 59.2136 +			// store the vertex-data index for later assignment of bone vertex weights
 59.2137 +			pMesh->mFacePosIndices.push_back( vindex[perVertexOffset]);
 59.2138 +		}
 59.2139 +	}
 59.2140 +
 59.2141 +
 59.2142 +	// if I ever get my hands on that guy who invented this steaming pile of indirection...
 59.2143 +	TestClosing( "p");
 59.2144 +}
 59.2145 +
 59.2146 +// ------------------------------------------------------------------------------------------------
 59.2147 +// Extracts a single object from an input channel and stores it in the appropriate mesh data array 
 59.2148 +void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, size_t pLocalIndex, Mesh* pMesh)
 59.2149 +{
 59.2150 +	// ignore vertex referrer - we handle them that separate
 59.2151 +	if( pInput.mType == IT_Vertex)
 59.2152 +		return;
 59.2153 +
 59.2154 +	const Accessor& acc = *pInput.mResolved;
 59.2155 +	if( pLocalIndex >= acc.mCount)
 59.2156 +		ThrowException( boost::str( boost::format( "Invalid data index (%d/%d) in primitive specification") % pLocalIndex % acc.mCount));
 59.2157 +
 59.2158 +	// get a pointer to the start of the data object referred to by the accessor and the local index
 59.2159 +	const float* dataObject = &(acc.mData->mValues[0]) + acc.mOffset + pLocalIndex* acc.mStride;
 59.2160 +
 59.2161 +	// assemble according to the accessors component sub-offset list. We don't care, yet,
 59.2162 +	// what kind of object exactly we're extracting here
 59.2163 +	float obj[4];
 59.2164 +	for( size_t c = 0; c < 4; ++c)
 59.2165 +		obj[c] = dataObject[acc.mSubOffset[c]];
 59.2166 +
 59.2167 +	// now we reinterpret it according to the type we're reading here
 59.2168 +	switch( pInput.mType)
 59.2169 +	{
 59.2170 +		case IT_Position: // ignore all position streams except 0 - there can be only one position
 59.2171 +			if( pInput.mIndex == 0)
 59.2172 +				pMesh->mPositions.push_back( aiVector3D( obj[0], obj[1], obj[2])); 
 59.2173 +			else 
 59.2174 +				DefaultLogger::get()->error("Collada: just one vertex position stream supported");
 59.2175 +			break;
 59.2176 +		case IT_Normal: 
 59.2177 +			// pad to current vertex count if necessary
 59.2178 +			if( pMesh->mNormals.size() < pMesh->mPositions.size()-1)
 59.2179 +				pMesh->mNormals.insert( pMesh->mNormals.end(), pMesh->mPositions.size() - pMesh->mNormals.size() - 1, aiVector3D( 0, 1, 0));
 59.2180 +
 59.2181 +			// ignore all normal streams except 0 - there can be only one normal
 59.2182 +			if( pInput.mIndex == 0)
 59.2183 +				pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2])); 
 59.2184 +			else 
 59.2185 +				DefaultLogger::get()->error("Collada: just one vertex normal stream supported");
 59.2186 +			break;
 59.2187 +		case IT_Tangent: 
 59.2188 +			// pad to current vertex count if necessary
 59.2189 +			if( pMesh->mTangents.size() < pMesh->mPositions.size()-1)
 59.2190 +				pMesh->mTangents.insert( pMesh->mTangents.end(), pMesh->mPositions.size() - pMesh->mTangents.size() - 1, aiVector3D( 1, 0, 0));
 59.2191 +
 59.2192 +			// ignore all tangent streams except 0 - there can be only one tangent
 59.2193 +			if( pInput.mIndex == 0)
 59.2194 +				pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); 
 59.2195 +			else 
 59.2196 +				DefaultLogger::get()->error("Collada: just one vertex tangent stream supported");
 59.2197 +			break;
 59.2198 +		case IT_Bitangent: 
 59.2199 +			// pad to current vertex count if necessary
 59.2200 +			if( pMesh->mBitangents.size() < pMesh->mPositions.size()-1)
 59.2201 +				pMesh->mBitangents.insert( pMesh->mBitangents.end(), pMesh->mPositions.size() - pMesh->mBitangents.size() - 1, aiVector3D( 0, 0, 1));
 59.2202 +
 59.2203 +			// ignore all bitangent streams except 0 - there can be only one bitangent
 59.2204 +			if( pInput.mIndex == 0)
 59.2205 +				pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); 
 59.2206 +			else 
 59.2207 +				DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported");
 59.2208 +			break;
 59.2209 +		case IT_Texcoord: 
 59.2210 +			// up to 4 texture coord sets are fine, ignore the others
 59.2211 +			if( pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) 
 59.2212 +			{
 59.2213 +				// pad to current vertex count if necessary
 59.2214 +				if( pMesh->mTexCoords[pInput.mIndex].size() < pMesh->mPositions.size()-1)
 59.2215 +					pMesh->mTexCoords[pInput.mIndex].insert( pMesh->mTexCoords[pInput.mIndex].end(), 
 59.2216 +						pMesh->mPositions.size() - pMesh->mTexCoords[pInput.mIndex].size() - 1, aiVector3D( 0, 0, 0));
 59.2217 +
 59.2218 +				pMesh->mTexCoords[pInput.mIndex].push_back( aiVector3D( obj[0], obj[1], obj[2]));
 59.2219 +				if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */
 59.2220 +					pMesh->mNumUVComponents[pInput.mIndex]=3;
 59.2221 +			}	else 
 59.2222 +			{
 59.2223 +				DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping.");
 59.2224 +			}
 59.2225 +			break;
 59.2226 +		case IT_Color: 
 59.2227 +			// up to 4 color sets are fine, ignore the others
 59.2228 +			if( pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS)
 59.2229 +			{
 59.2230 +				// pad to current vertex count if necessary
 59.2231 +				if( pMesh->mColors[pInput.mIndex].size() < pMesh->mPositions.size()-1)
 59.2232 +					pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(), 
 59.2233 +						pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1));
 59.2234 +
 59.2235 +				aiColor4D result(0, 0, 0, 1);
 59.2236 +				for (size_t i = 0; i < pInput.mResolved->mSize; ++i)
 59.2237 +				{
 59.2238 +					result[i] = obj[pInput.mResolved->mSubOffset[i]];
 59.2239 +				}
 59.2240 +				pMesh->mColors[pInput.mIndex].push_back(result); 
 59.2241 +			} else 
 59.2242 +			{
 59.2243 +				DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping.");
 59.2244 +			}
 59.2245 +
 59.2246 +			break;
 59.2247 +		default:
 59.2248 +			// IT_Invalid and IT_Vertex 
 59.2249 +			ai_assert(false && "shouldn't ever get here");
 59.2250 +	}
 59.2251 +}
 59.2252 +
 59.2253 +// ------------------------------------------------------------------------------------------------
 59.2254 +// Reads the library of node hierarchies and scene parts
 59.2255 +void ColladaParser::ReadSceneLibrary()
 59.2256 +{
 59.2257 +	if( mReader->isEmptyElement())
 59.2258 +		return;
 59.2259 +
 59.2260 +	while( mReader->read())
 59.2261 +	{
 59.2262 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
 59.2263 +		{
 59.2264 +			// a visual scene - generate root node under its ID and let ReadNode() do the recursive work
 59.2265 +			if( IsElement( "visual_scene"))
 59.2266 +			{
 59.2267 +				// read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then?
 59.2268 +				int indexID = GetAttribute( "id");
 59.2269 +				const char* attrID = mReader->getAttributeValue( indexID);
 59.2270 +
 59.2271 +				// read name if given. 
 59.2272 +				int indexName = TestAttribute( "name");
 59.2273 +				const char* attrName = "unnamed";
 59.2274 +				if( indexName > -1)
 59.2275 +					attrName = mReader->getAttributeValue( indexName);
 59.2276 +
 59.2277 +				// create a node and store it in the library under its ID
 59.2278 +				Node* node = new Node;
 59.2279 +				node->mID = attrID;
 59.2280 +				node->mName = attrName;
 59.2281 +				mNodeLibrary[node->mID] = node;
 59.2282 +
 59.2283 +				ReadSceneNode( node);
 59.2284 +			} else
 59.2285 +			{
 59.2286 +				// ignore the rest
 59.2287 +				SkipElement();
 59.2288 +			}
 59.2289 +		}
 59.2290 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
 59.2291 +		{
 59.2292 +			if( strcmp( mReader->getNodeName(), "library_visual_scenes") == 0)
 59.2293 +				//ThrowException( "Expected end of \"library_visual_scenes\" element.");
 59.2294 +
 59.2295 +			break;
 59.2296 +		}
 59.2297 +	}
 59.2298 +}
 59.2299 +
 59.2300 +// ------------------------------------------------------------------------------------------------
 59.2301 +// Reads a scene node's contents including children and stores it in the given node
 59.2302 +void ColladaParser::ReadSceneNode( Node* pNode)
 59.2303 +{
 59.2304 +	// quit immediately on <bla/> elements
 59.2305 +	if( mReader->isEmptyElement())
 59.2306 +		return;
 59.2307 +
 59.2308 +	while( mReader->read())
 59.2309 +	{
 59.2310 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 
 59.2311 +		{
 59.2312 +			if( IsElement( "node"))
 59.2313 +			{
 59.2314 +				Node* child = new Node;
 59.2315 +				int attrID = TestAttribute( "id");
 59.2316 +				if( attrID > -1)
 59.2317 +					child->mID = mReader->getAttributeValue( attrID);
 59.2318 +				int attrSID = TestAttribute( "sid");
 59.2319 +				if( attrSID > -1)
 59.2320 +					child->mSID = mReader->getAttributeValue( attrSID);
 59.2321 +
 59.2322 +				int attrName = TestAttribute( "name");
 59.2323 +				if( attrName > -1)
 59.2324 +					child->mName = mReader->getAttributeValue( attrName);
 59.2325 +
 59.2326 +				// TODO: (thom) support SIDs
 59.2327 +				// ai_assert( TestAttribute( "sid") == -1);
 59.2328 +
 59.2329 +				if (pNode) 
 59.2330 +				{
 59.2331 +					pNode->mChildren.push_back( child);
 59.2332 +					child->mParent = pNode;
 59.2333 +				}
 59.2334 +				else 
 59.2335 +				{
 59.2336 +					// no parent node given, probably called from <library_nodes> element.
 59.2337 +					// create new node in node library
 59.2338 +					mNodeLibrary[child->mID] = child;
 59.2339 +				}
 59.2340 +
 59.2341 +				// read on recursively from there
 59.2342 +				ReadSceneNode( child);
 59.2343 +				continue;
 59.2344 +			}
 59.2345 +			// For any further stuff we need a valid node to work on
 59.2346 +			else if (!pNode)
 59.2347 +				continue;
 59.2348 +
 59.2349 +			if( IsElement( "lookat"))
 59.2350 +				ReadNodeTransformation( pNode, TF_LOOKAT);
 59.2351 +			else if( IsElement( "matrix"))
 59.2352 +				ReadNodeTransformation( pNode, TF_MATRIX);
 59.2353 +			else if( IsElement( "rotate"))
 59.2354 +				ReadNodeTransformation( pNode, TF_ROTATE);
 59.2355 +			else if( IsElement( "scale"))
 59.2356 +				ReadNodeTransformation( pNode, TF_SCALE);
 59.2357 +			else if( IsElement( "skew"))
 59.2358 +				ReadNodeTransformation( pNode, TF_SKEW);
 59.2359 +			else if( IsElement( "translate"))
 59.2360 +				ReadNodeTransformation( pNode, TF_TRANSLATE);
 59.2361 +			else if( IsElement( "render") && pNode->mParent == NULL && 0 == pNode->mPrimaryCamera.length())
 59.2362 +			{
 59.2363 +				// ... scene evaluation or, in other words, postprocessing pipeline,
 59.2364 +				// or, again in other words, a turing-complete description how to
 59.2365 +				// render a Collada scene. The only thing that is interesting for
 59.2366 +				// us is the primary camera.
 59.2367 +				int attrId = TestAttribute("camera_node");
 59.2368 +				if (-1 != attrId) 
 59.2369 +				{
 59.2370 +					const char* s = mReader->getAttributeValue(attrId);
 59.2371 +					if (s[0] != '#')
 59.2372 +						DefaultLogger::get()->error("Collada: Unresolved reference format of camera");
 59.2373 +					else 
 59.2374 +						pNode->mPrimaryCamera = s+1;
 59.2375 +				}
 59.2376 +			}
 59.2377 +			else if( IsElement( "instance_node")) 
 59.2378 +			{
 59.2379 +				// find the node in the library
 59.2380 +				int attrID = TestAttribute( "url");
 59.2381 +				if( attrID != -1) 
 59.2382 +				{
 59.2383 +					const char* s = mReader->getAttributeValue(attrID);
 59.2384 +					if (s[0] != '#')
 59.2385 +						DefaultLogger::get()->error("Collada: Unresolved reference format of node");
 59.2386 +					else 
 59.2387 +					{
 59.2388 +						pNode->mNodeInstances.push_back(NodeInstance());
 59.2389 +						pNode->mNodeInstances.back().mNode = s+1;
 59.2390 +					}
 59.2391 +				}
 59.2392 +			} 
 59.2393 +			else if( IsElement( "instance_geometry") || IsElement( "instance_controller"))
 59.2394 +			{
 59.2395 +				// Reference to a mesh or controller, with possible material associations
 59.2396 +				ReadNodeGeometry( pNode);
 59.2397 +			}
 59.2398 +			else if( IsElement( "instance_light")) 
 59.2399 +			{
 59.2400 +				// Reference to a light, name given in 'url' attribute
 59.2401 +				int attrID = TestAttribute("url");
 59.2402 +				if (-1 == attrID)
 59.2403 +					DefaultLogger::get()->warn("Collada: Expected url attribute in <instance_light> element");
 59.2404 +				else 
 59.2405 +				{
 59.2406 +					const char* url = mReader->getAttributeValue( attrID);
 59.2407 +					if( url[0] != '#')
 59.2408 +						ThrowException( "Unknown reference format in <instance_light> element");
 59.2409 +
 59.2410 +					pNode->mLights.push_back(LightInstance());
 59.2411 +					pNode->mLights.back().mLight = url+1;
 59.2412 +				}
 59.2413 +			}
 59.2414 +			else if( IsElement( "instance_camera")) 
 59.2415 +			{
 59.2416 +				// Reference to a camera, name given in 'url' attribute
 59.2417 +				int attrID = TestAttribute("url");
 59.2418 +				if (-1 == attrID)
 59.2419 +					DefaultLogger::get()->warn("Collada: Expected url attribute in <instance_camera> element");
 59.2420 +				else 
 59.2421 +				{
 59.2422 +					const char* url = mReader->getAttributeValue( attrID);
 59.2423 +					if( url[0] != '#')
 59.2424 +						ThrowException( "Unknown reference format in <instance_camera> element");
 59.2425 +
 59.2426 +					pNode->mCameras.push_back(CameraInstance());
 59.2427 +					pNode->mCameras.back().mCamera = url+1;
 59.2428 +				}
 59.2429 +			}
 59.2430 +			else
 59.2431 +			{
 59.2432 +				// skip everything else for the moment
 59.2433 +				SkipElement();
 59.2434 +			}
 59.2435 +		} 
 59.2436 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
 59.2437 +			break;
 59.2438 +		}
 59.2439 +	}
 59.2440 +}
 59.2441 +
 59.2442 +// ------------------------------------------------------------------------------------------------
 59.2443 +// Reads a node transformation entry of the given type and adds it to the given node's transformation list.
 59.2444 +void ColladaParser::ReadNodeTransformation( Node* pNode, TransformType pType)
 59.2445 +{
 59.2446 +	if( mReader->isEmptyElement())
 59.2447 +		return;
 59.2448 +
 59.2449 +	std::string tagName = mReader->getNodeName();
 59.2450 +
 59.2451 +	Transform tf;
 59.2452 +	tf.mType = pType;
 59.2453 +	
 59.2454 +	// read SID
 59.2455 +	int indexSID = TestAttribute( "sid");
 59.2456 +	if( indexSID >= 0)
 59.2457 +		tf.mID = mReader->getAttributeValue( indexSID);
 59.2458 +
 59.2459 +	// how many parameters to read per transformation type
 59.2460 +	static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
 59.2461 +	const char* content = GetTextContent();
 59.2462 +
 59.2463 +	// read as many parameters and store in the transformation
 59.2464 +	for( unsigned int a = 0; a < sNumParameters[pType]; a++)
 59.2465 +	{
 59.2466 +		// read a number
 59.2467 +		content = fast_atoreal_move<float>( content, tf.f[a]);
 59.2468 +		// skip whitespace after it
 59.2469 +		SkipSpacesAndLineEnd( &content);
 59.2470 +	}
 59.2471 +
 59.2472 +	// place the transformation at the queue of the node
 59.2473 +	pNode->mTransforms.push_back( tf);
 59.2474 +
 59.2475 +	// and consume the closing tag
 59.2476 +	TestClosing( tagName.c_str());
 59.2477 +}
 59.2478 +
 59.2479 +// ------------------------------------------------------------------------------------------------
 59.2480 +// Processes bind_vertex_input and bind elements
 59.2481 +void ColladaParser::ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl)
 59.2482 +{
 59.2483 +	while( mReader->read())
 59.2484 +	{
 59.2485 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)	{
 59.2486 +			if( IsElement( "bind_vertex_input"))
 59.2487 +			{
 59.2488 +				Collada::InputSemanticMapEntry vn;
 59.2489 +
 59.2490 +				// effect semantic
 59.2491 +				int n = GetAttribute("semantic");
 59.2492 +				std::string s = mReader->getAttributeValue(n);
 59.2493 +
 59.2494 +				// input semantic
 59.2495 +				n = GetAttribute("input_semantic");
 59.2496 +				vn.mType = GetTypeForSemantic( mReader->getAttributeValue(n) );
 59.2497 +				
 59.2498 +				// index of input set
 59.2499 +				n = TestAttribute("input_set");
 59.2500 +				if (-1 != n)
 59.2501 +					vn.mSet = mReader->getAttributeValueAsInt(n);
 59.2502 +
 59.2503 +				tbl.mMap[s] = vn;
 59.2504 +			} 
 59.2505 +			else if( IsElement( "bind")) {
 59.2506 +				DefaultLogger::get()->warn("Collada: Found unsupported <bind> element");
 59.2507 +			}
 59.2508 +		} 
 59.2509 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)	{
 59.2510 +			if( strcmp( mReader->getNodeName(), "instance_material") == 0)
 59.2511 +				break;
 59.2512 +		} 
 59.2513 +	}
 59.2514 +}
 59.2515 +
 59.2516 +// ------------------------------------------------------------------------------------------------
 59.2517 +// Reads a mesh reference in a node and adds it to the node's mesh list
 59.2518 +void ColladaParser::ReadNodeGeometry( Node* pNode)
 59.2519 +{
 59.2520 +	// referred mesh is given as an attribute of the <instance_geometry> element
 59.2521 +	int attrUrl = GetAttribute( "url");
 59.2522 +	const char* url = mReader->getAttributeValue( attrUrl);
 59.2523 +	if( url[0] != '#')
 59.2524 +		ThrowException( "Unknown reference format");
 59.2525 +	
 59.2526 +	Collada::MeshInstance instance;
 59.2527 +	instance.mMeshOrController = url+1; // skipping the leading #
 59.2528 +
 59.2529 +	if( !mReader->isEmptyElement())
 59.2530 +	{
 59.2531 +		// read material associations. Ignore additional elements inbetween
 59.2532 +		while( mReader->read())
 59.2533 +		{
 59.2534 +			if( mReader->getNodeType() == irr::io::EXN_ELEMENT)	
 59.2535 +			{
 59.2536 +				if( IsElement( "instance_material"))
 59.2537 +				{
 59.2538 +					// read ID of the geometry subgroup and the target material
 59.2539 +					int attrGroup = GetAttribute( "symbol");
 59.2540 +					std::string group = mReader->getAttributeValue( attrGroup);
 59.2541 +					int attrMaterial = GetAttribute( "target");
 59.2542 +					const char* urlMat = mReader->getAttributeValue( attrMaterial);
 59.2543 +					Collada::SemanticMappingTable s;
 59.2544 +					if( urlMat[0] == '#')
 59.2545 +						urlMat++;
 59.2546 +
 59.2547 +					s.mMatName = urlMat;
 59.2548 +
 59.2549 +					// resolve further material details + THIS UGLY AND NASTY semantic mapping stuff
 59.2550 +					if( !mReader->isEmptyElement())
 59.2551 +						ReadMaterialVertexInputBinding(s);
 59.2552 +
 59.2553 +					// store the association
 59.2554 +					instance.mMaterials[group] = s;
 59.2555 +				} 
 59.2556 +			} 
 59.2557 +			else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)	
 59.2558 +			{
 59.2559 +				if( strcmp( mReader->getNodeName(), "instance_geometry") == 0 
 59.2560 +					|| strcmp( mReader->getNodeName(), "instance_controller") == 0)
 59.2561 +					break;
 59.2562 +			} 
 59.2563 +		}
 59.2564 +	}
 59.2565 +
 59.2566 +	// store it
 59.2567 +	pNode->mMeshes.push_back( instance);
 59.2568 +}
 59.2569 +
 59.2570 +// ------------------------------------------------------------------------------------------------
 59.2571 +// Reads the collada scene
 59.2572 +void ColladaParser::ReadScene()
 59.2573 +{
 59.2574 +	if( mReader->isEmptyElement())
 59.2575 +		return;
 59.2576 +
 59.2577 +	while( mReader->read())
 59.2578 +	{
 59.2579 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT)	{
 59.2580 +			if( IsElement( "instance_visual_scene"))
 59.2581 +			{
 59.2582 +				// should be the first and only occurence
 59.2583 +				if( mRootNode)
 59.2584 +					ThrowException( "Invalid scene containing multiple root nodes in <instance_visual_scene> element");
 59.2585 +
 59.2586 +				// read the url of the scene to instance. Should be of format "#some_name"
 59.2587 +				int urlIndex = GetAttribute( "url");
 59.2588 +				const char* url = mReader->getAttributeValue( urlIndex);
 59.2589 +				if( url[0] != '#')
 59.2590 +					ThrowException( "Unknown reference format in <instance_visual_scene> element");
 59.2591 +
 59.2592 +				// find the referred scene, skip the leading # 
 59.2593 +				NodeLibrary::const_iterator sit = mNodeLibrary.find( url+1);
 59.2594 +				if( sit == mNodeLibrary.end())
 59.2595 +					ThrowException( "Unable to resolve visual_scene reference \"" + std::string(url) + "\" in <instance_visual_scene> element.");
 59.2596 +				mRootNode = sit->second;
 59.2597 +			} else	{
 59.2598 +				SkipElement();
 59.2599 +			}
 59.2600 +		} 
 59.2601 +		else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){
 59.2602 +			break;
 59.2603 +		} 
 59.2604 +	}
 59.2605 +}
 59.2606 +
 59.2607 +// ------------------------------------------------------------------------------------------------
 59.2608 +// Aborts the file reading with an exception
 59.2609 +void ColladaParser::ThrowException( const std::string& pError) const
 59.2610 +{
 59.2611 +	throw DeadlyImportError( boost::str( boost::format( "Collada: %s - %s") % mFileName % pError));
 59.2612 +}
 59.2613 +
 59.2614 +// ------------------------------------------------------------------------------------------------
 59.2615 +// Skips all data until the end node of the current element
 59.2616 +void ColladaParser::SkipElement()
 59.2617 +{
 59.2618 +	// nothing to skip if it's an <element />
 59.2619 +	if( mReader->isEmptyElement())
 59.2620 +		return;
 59.2621 +
 59.2622 +	// reroute
 59.2623 +	SkipElement( mReader->getNodeName());
 59.2624 +}
 59.2625 +
 59.2626 +// ------------------------------------------------------------------------------------------------
 59.2627 +// Skips all data until the end node of the given element
 59.2628 +void ColladaParser::SkipElement( const char* pElement)
 59.2629 +{
 59.2630 +	// copy the current node's name because it'a pointer to the reader's internal buffer, 
 59.2631 +	// which is going to change with the upcoming parsing 
 59.2632 +	std::string element = pElement;
 59.2633 +	while( mReader->read())
 59.2634 +	{
 59.2635 +		if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
 59.2636 +			if( mReader->getNodeName() == element)
 59.2637 +				break;
 59.2638 +	}
 59.2639 +}
 59.2640 +
 59.2641 +// ------------------------------------------------------------------------------------------------
 59.2642 +// Tests for an opening element of the given name, throws an exception if not found
 59.2643 +void ColladaParser::TestOpening( const char* pName)
 59.2644 +{
 59.2645 +	// read element start
 59.2646 +	if( !mReader->read())
 59.2647 +		ThrowException( boost::str( boost::format( "Unexpected end of file while beginning of <%s> element.") % pName));
 59.2648 +	// whitespace in front is ok, just read again if found
 59.2649 +	if( mReader->getNodeType() == irr::io::EXN_TEXT)
 59.2650 +		if( !mReader->read())
 59.2651 +			ThrowException( boost::str( boost::format( "Unexpected end of file while reading beginning of <%s> element.") % pName));
 59.2652 +
 59.2653 +	if( mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp( mReader->getNodeName(), pName) != 0)
 59.2654 +		ThrowException( boost::str( boost::format( "Expected start of <%s> element.") % pName));
 59.2655 +}
 59.2656 +
 59.2657 +// ------------------------------------------------------------------------------------------------
 59.2658 +// Tests for the closing tag of the given element, throws an exception if not found
 59.2659 +void ColladaParser::TestClosing( const char* pName)
 59.2660 +{
 59.2661 +	// check if we're already on the closing tag and return right away
 59.2662 +	if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END && strcmp( mReader->getNodeName(), pName) == 0)
 59.2663 +		return;
 59.2664 +
 59.2665 +	// if not, read some more
 59.2666 +	if( !mReader->read())
 59.2667 +		ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of <%s> element.") % pName));
 59.2668 +	// whitespace in front is ok, just read again if found
 59.2669 +	if( mReader->getNodeType() == irr::io::EXN_TEXT)
 59.2670 +		if( !mReader->read())
 59.2671 +			ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of <%s> element.") % pName));
 59.2672 +
 59.2673 +	// but this has the be the closing tag, or we're lost
 59.2674 +	if( mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp( mReader->getNodeName(), pName) != 0)
 59.2675 +		ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % pName));
 59.2676 +}
 59.2677 +
 59.2678 +// ------------------------------------------------------------------------------------------------
 59.2679 +// Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes
 59.2680 +int ColladaParser::GetAttribute( const char* pAttr) const
 59.2681 +{
 59.2682 +	int index = TestAttribute( pAttr);
 59.2683 +	if( index != -1)
 59.2684 +		return index;
 59.2685 +
 59.2686 +	// attribute not found -> throw an exception
 59.2687 +	ThrowException( boost::str( boost::format( "Expected attribute \"%s\" for element <%s>.") % pAttr % mReader->getNodeName()));
 59.2688 +	return -1;
 59.2689 +}
 59.2690 +
 59.2691 +// ------------------------------------------------------------------------------------------------
 59.2692 +// Tests the present element for the presence of one attribute, returns its index or throws an exception if not found
 59.2693 +int ColladaParser::TestAttribute( const char* pAttr) const
 59.2694 +{
 59.2695 +	for( int a = 0; a < mReader->getAttributeCount(); a++)
 59.2696 +		if( strcmp( mReader->getAttributeName( a), pAttr) == 0)
 59.2697 +			return a;
 59.2698 +
 59.2699 +	return -1;
 59.2700 +}
 59.2701 +
 59.2702 +// ------------------------------------------------------------------------------------------------
 59.2703 +// Reads the text contents of an element, throws an exception if not given. Skips leading whitespace.
 59.2704 +const char* ColladaParser::GetTextContent()
 59.2705 +{
 59.2706 +	const char* sz = TestTextContent();
 59.2707 +	if(!sz) {
 59.2708 +		ThrowException( "Invalid contents in element \"n\".");
 59.2709 +	}
 59.2710 +	return sz;
 59.2711 +}
 59.2712 +
 59.2713 +// ------------------------------------------------------------------------------------------------
 59.2714 +// Reads the text contents of an element, returns NULL if not given. Skips leading whitespace.
 59.2715 +const char* ColladaParser::TestTextContent()
 59.2716 +{
 59.2717 +	// present node should be the beginning of an element
 59.2718 +	if( mReader->getNodeType() != irr::io::EXN_ELEMENT || mReader->isEmptyElement())
 59.2719 +		return NULL;
 59.2720 +
 59.2721 +	// read contents of the element
 59.2722 +	if( !mReader->read() )
 59.2723 +		return NULL;
 59.2724 +	if( mReader->getNodeType() != irr::io::EXN_TEXT)
 59.2725 +		return NULL;
 59.2726 +
 59.2727 +	// skip leading whitespace
 59.2728 +	const char* text = mReader->getNodeData();
 59.2729 +	SkipSpacesAndLineEnd( &text);
 59.2730 +
 59.2731 +	return text;
 59.2732 +}
 59.2733 +
 59.2734 +// ------------------------------------------------------------------------------------------------
 59.2735 +// Calculates the resulting transformation fromm all the given transform steps
 59.2736 +aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector<Transform>& pTransforms) const
 59.2737 +{
 59.2738 +	aiMatrix4x4 res;
 59.2739 +
 59.2740 +	for( std::vector<Transform>::const_iterator it = pTransforms.begin(); it != pTransforms.end(); ++it)
 59.2741 +	{
 59.2742 +		const Transform& tf = *it;
 59.2743 +		switch( tf.mType)
 59.2744 +		{
 59.2745 +			case TF_LOOKAT:
 59.2746 +      {
 59.2747 +        aiVector3D pos( tf.f[0], tf.f[1], tf.f[2]);
 59.2748 +        aiVector3D dstPos( tf.f[3], tf.f[4], tf.f[5]);
 59.2749 +        aiVector3D up = aiVector3D( tf.f[6], tf.f[7], tf.f[8]).Normalize();
 59.2750 +        aiVector3D dir = aiVector3D( dstPos - pos).Normalize();
 59.2751 +        aiVector3D right = (dir ^ up).Normalize();
 59.2752 +
 59.2753 +        res *= aiMatrix4x4( 
 59.2754 +          right.x, up.x, -dir.x, pos.x, 
 59.2755 +          right.y, up.y, -dir.y, pos.y,
 59.2756 +          right.z, up.z, -dir.z, pos.z,
 59.2757 +          0, 0, 0, 1);
 59.2758 +				break;
 59.2759 +      }
 59.2760 +			case TF_ROTATE:
 59.2761 +			{
 59.2762 +				aiMatrix4x4 rot;
 59.2763 +				float angle = tf.f[3] * float( AI_MATH_PI) / 180.0f;
 59.2764 +				aiVector3D axis( tf.f[0], tf.f[1], tf.f[2]);
 59.2765 +				aiMatrix4x4::Rotation( angle, axis, rot);
 59.2766 +				res *= rot;
 59.2767 +				break;
 59.2768 +			}
 59.2769 +			case TF_TRANSLATE:
 59.2770 +			{
 59.2771 +				aiMatrix4x4 trans;
 59.2772 +				aiMatrix4x4::Translation( aiVector3D( tf.f[0], tf.f[1], tf.f[2]), trans);
 59.2773 +				res *= trans;
 59.2774 +				break;
 59.2775 +			}
 59.2776 +			case TF_SCALE:
 59.2777 +			{
 59.2778 +				aiMatrix4x4 scale( tf.f[0], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[1], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[2], 0.0f, 
 59.2779 +					0.0f, 0.0f, 0.0f, 1.0f);
 59.2780 +				res *= scale;
 59.2781 +				break;
 59.2782 +			}
 59.2783 +			case TF_SKEW:
 59.2784 +				// TODO: (thom)
 59.2785 +				ai_assert( false);
 59.2786 +				break;
 59.2787 +			case TF_MATRIX:
 59.2788 +			{
 59.2789 +				aiMatrix4x4 mat( tf.f[0], tf.f[1], tf.f[2], tf.f[3], tf.f[4], tf.f[5], tf.f[6], tf.f[7],
 59.2790 +					tf.f[8], tf.f[9], tf.f[10], tf.f[11], tf.f[12], tf.f[13], tf.f[14], tf.f[15]);
 59.2791 +				res *= mat;
 59.2792 +				break;
 59.2793 +			}
 59.2794 +			default: 
 59.2795 +				ai_assert( false);
 59.2796 +				break;
 59.2797 +		}
 59.2798 +	}
 59.2799 +
 59.2800 +	return res;
 59.2801 +}
 59.2802 +
 59.2803 +// ------------------------------------------------------------------------------------------------
 59.2804 +// Determines the input data type for the given semantic string
 59.2805 +Collada::InputType ColladaParser::GetTypeForSemantic( const std::string& pSemantic)
 59.2806 +{
 59.2807 +	if( pSemantic == "POSITION")
 59.2808 +		return IT_Position;
 59.2809 +	else if( pSemantic == "TEXCOORD")
 59.2810 +		return IT_Texcoord;
 59.2811 +	else if( pSemantic == "NORMAL")
 59.2812 +		return IT_Normal;
 59.2813 +	else if( pSemantic == "COLOR")
 59.2814 +		return IT_Color;
 59.2815 +	else if( pSemantic == "VERTEX")
 59.2816 +		return IT_Vertex;
 59.2817 +	else if( pSemantic == "BINORMAL" || pSemantic ==  "TEXBINORMAL")
 59.2818 +		return IT_Bitangent;
 59.2819 +	else if( pSemantic == "TANGENT" || pSemantic == "TEXTANGENT")
 59.2820 +		return IT_Tangent;
 59.2821 +
 59.2822 +	DefaultLogger::get()->warn( boost::str( boost::format( "Unknown vertex input type \"%s\". Ignoring.") % pSemantic));
 59.2823 +	return IT_Invalid;
 59.2824 +}
 59.2825 +
 59.2826 +#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/libs/assimp/ColladaParser.h	Sat Feb 01 19:58:19 2014 +0200
    60.3 @@ -0,0 +1,341 @@
    60.4 +/*
    60.5 +Open Asset Import Library (assimp)
    60.6 +----------------------------------------------------------------------
    60.7 +
    60.8 +Copyright (c) 2006-2012, assimp team
    60.9 +All rights reserved.
   60.10 +
   60.11 +Redistribution and use of this software in source and binary forms, 
   60.12 +with or without modification, are permitted provided that the 
   60.13 +following conditions are met:
   60.14 +
   60.15 +* Redistributions of source code must retain the above
   60.16 +copyright notice, this list of conditions and the
   60.17 +following disclaimer.
   60.18 +
   60.19 +* Redistributions in binary form must reproduce the above
   60.20 +copyright notice, this list of conditions and the
   60.21 +following disclaimer in the documentation and/or other
   60.22 +materials provided with the distribution.
   60.23 +
   60.24 +* Neither the name of the assimp team, nor the names of its
   60.25 +contributors may be used to endorse or promote products
   60.26 +derived from this software without specific prior
   60.27 +written permission of the assimp team.
   60.28 +
   60.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   60.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   60.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   60.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   60.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   60.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   60.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   60.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   60.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   60.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   60.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   60.40 +
   60.41 +----------------------------------------------------------------------
   60.42 +*/
   60.43 +
   60.44 +/** @file ColladaParser.h
   60.45 + *  @brief Defines the parser helper class for the collada loader 
   60.46 + */
   60.47 +
   60.48 +#ifndef AI_COLLADAPARSER_H_INC
   60.49 +#define AI_COLLADAPARSER_H_INC
   60.50 +
   60.51 +#include "irrXMLWrapper.h"
   60.52 +#include "ColladaHelper.h"
   60.53 +
   60.54 +namespace Assimp
   60.55 +{
   60.56 +
   60.57 +// ------------------------------------------------------------------------------------------
   60.58 +/** Parser helper class for the Collada loader. 
   60.59 + *
   60.60 + *  Does all the XML reading and builds internal data structures from it, 
   60.61 + *  but leaves the resolving of all the references to the loader.
   60.62 +*/
   60.63 +class ColladaParser
   60.64 +{
   60.65 +	friend class ColladaLoader;
   60.66 +
   60.67 +protected:
   60.68 +	/** Constructor from XML file */
   60.69 +	ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
   60.70 +
   60.71 +	/** Destructor */
   60.72 +	~ColladaParser();
   60.73 +
   60.74 +	/** Reads the contents of the file */
   60.75 +	void ReadContents();
   60.76 +
   60.77 +	/** Reads the structure of the file */
   60.78 +	void ReadStructure();
   60.79 +
   60.80 +	/** Reads asset informations such as coordinate system informations and legal blah */
   60.81 +	void ReadAssetInfo();
   60.82 +
   60.83 +	/** Reads the animation library */
   60.84 +	void ReadAnimationLibrary();
   60.85 +
   60.86 +	/** Reads an animation into the given parent structure */
   60.87 +	void ReadAnimation( Collada::Animation* pParent);
   60.88 +
   60.89 +	/** Reads an animation sampler into the given anim channel */
   60.90 +	void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
   60.91 +
   60.92 +	/** Reads the skeleton controller library */
   60.93 +	void ReadControllerLibrary();
   60.94 +
   60.95 +	/** Reads a controller into the given mesh structure */
   60.96 +	void ReadController( Collada::Controller& pController);
   60.97 +
   60.98 +	/** Reads the joint definitions for the given controller */
   60.99 +	void ReadControllerJoints( Collada::Controller& pController);
  60.100 +
  60.101 +	/** Reads the joint weights for the given controller */
  60.102 +	void ReadControllerWeights( Collada::Controller& pController);
  60.103 +
  60.104 +	/** Reads the image library contents */
  60.105 +	void ReadImageLibrary();
  60.106 +
  60.107 +	/** Reads an image entry into the given image */
  60.108 +	void ReadImage( Collada::Image& pImage);
  60.109 +
  60.110 +	/** Reads the material library */
  60.111 +	void ReadMaterialLibrary();
  60.112 +
  60.113 +	/** Reads a material entry into the given material */
  60.114 +	void ReadMaterial( Collada::Material& pMaterial);
  60.115 +
  60.116 +	/** Reads the camera library */
  60.117 +	void ReadCameraLibrary();
  60.118 +
  60.119 +	/** Reads a camera entry into the given camera */
  60.120 +	void ReadCamera( Collada::Camera& pCamera);
  60.121 +
  60.122 +	/** Reads the light library */
  60.123 +	void ReadLightLibrary();
  60.124 +
  60.125 +	/** Reads a light entry into the given light */
  60.126 +	void ReadLight( Collada::Light& pLight);
  60.127 +
  60.128 +	/** Reads the effect library */
  60.129 +	void ReadEffectLibrary();
  60.130 +
  60.131 +	/** Reads an effect entry into the given effect*/
  60.132 +	void ReadEffect( Collada::Effect& pEffect);
  60.133 +
  60.134 +	/** Reads an COMMON effect profile */
  60.135 +	void ReadEffectProfileCommon( Collada::Effect& pEffect);
  60.136 +
  60.137 +	/** Read sampler properties */
  60.138 +	void ReadSamplerProperties( Collada::Sampler& pSampler);
  60.139 +
  60.140 +	/** Reads an effect entry containing a color or a texture defining that color */
  60.141 +	void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
  60.142 +
  60.143 +	/** Reads an effect entry containing a float */
  60.144 +	void ReadEffectFloat( float& pFloat);
  60.145 +
  60.146 +	/** Reads an effect parameter specification of any kind */
  60.147 +	void ReadEffectParam( Collada::EffectParam& pParam);
  60.148 +
  60.149 +	/** Reads the geometry library contents */
  60.150 +	void ReadGeometryLibrary();
  60.151 +
  60.152 +	/** Reads a geometry from the geometry library. */
  60.153 +	void ReadGeometry( Collada::Mesh* pMesh);
  60.154 +
  60.155 +	/** Reads a mesh from the geometry library */
  60.156 +	void ReadMesh( Collada::Mesh* pMesh);
  60.157 +
  60.158 +	/** Reads a source element - a combination of raw data and an accessor defining 
  60.159 +	 * things that should not be redefinable. Yes, that's another rant.
  60.160 +	 */
  60.161 +	void ReadSource();
  60.162 +
  60.163 +	/** Reads a data array holding a number of elements, and stores it in the global library.
  60.164 +	 * Currently supported are array of floats and arrays of strings.
  60.165 +	 */
  60.166 +	void ReadDataArray();
  60.167 +
  60.168 +	/** Reads an accessor and stores it in the global library under the given ID - 
  60.169 +	 * accessors use the ID of the parent <source> element
  60.170 +	 */
  60.171 +	void ReadAccessor( const std::string& pID);
  60.172 +
  60.173 +	/** Reads input declarations of per-vertex mesh data into the given mesh */
  60.174 +	void ReadVertexData( Collada::Mesh* pMesh);
  60.175 +
  60.176 +	/** Reads input declarations of per-index mesh data into the given mesh */
  60.177 +	void ReadIndexData( Collada::Mesh* pMesh);
  60.178 +
  60.179 +	/** Reads a single input channel element and stores it in the given array, if valid */
  60.180 +	void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
  60.181 +
  60.182 +	/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
  60.183 +	void ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels, 
  60.184 +		size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
  60.185 +
  60.186 +	/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
  60.187 +	void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
  60.188 +
  60.189 +	/** Reads the library of node hierarchies and scene parts */
  60.190 +	void ReadSceneLibrary();
  60.191 +
  60.192 +	/** Reads a scene node's contents including children and stores it in the given node */
  60.193 +	void ReadSceneNode( Collada::Node* pNode);
  60.194 +
  60.195 +	/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
  60.196 +	void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
  60.197 +
  60.198 +	/** Reads a mesh reference in a node and adds it to the node's mesh list */
  60.199 +	void ReadNodeGeometry( Collada::Node* pNode);
  60.200 +
  60.201 +	/** Reads the collada scene */
  60.202 +	void ReadScene();
  60.203 +
  60.204 +	// Processes bind_vertex_input and bind elements
  60.205 +	void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
  60.206 +
  60.207 +protected:
  60.208 +	/** Aborts the file reading with an exception */
  60.209 +	void ThrowException( const std::string& pError) const;
  60.210 +
  60.211 +	/** Skips all data until the end node of the current element */
  60.212 +	void SkipElement();
  60.213 +
  60.214 +	/** Skips all data until the end node of the given element */
  60.215 +	void SkipElement( const char* pElement);
  60.216 +
  60.217 +	/** Compares the current xml element name to the given string and returns true if equal */
  60.218 +	bool IsElement( const char* pName) const;
  60.219 +
  60.220 +	/** Tests for the opening tag of the given element, throws an exception if not found */
  60.221 +	void TestOpening( const char* pName);
  60.222 +
  60.223 +	/** Tests for the closing tag of the given element, throws an exception if not found */
  60.224 +	void TestClosing( const char* pName);
  60.225 +
  60.226 +	/** Checks the present element for the presence of the attribute, returns its index 
  60.227 +	    or throws an exception if not found */
  60.228 +	int GetAttribute( const char* pAttr) const;
  60.229 +
  60.230 +	/** Returns the index of the named attribute or -1 if not found. Does not throw,
  60.231 +	    therefore useful for optional attributes */
  60.232 +	int TestAttribute( const char* pAttr) const;
  60.233 +
  60.234 +	/** Reads the text contents of an element, throws an exception if not given. 
  60.235 +	    Skips leading whitespace. */
  60.236 +	const char* GetTextContent();
  60.237 +
  60.238 +	/** Reads the text contents of an element, returns NULL if not given.
  60.239 +	    Skips leading whitespace. */
  60.240 +	const char* TestTextContent();
  60.241 +
  60.242 +	/** Reads a single bool from current text content */
  60.243 +	bool ReadBoolFromTextContent();
  60.244 +
  60.245 +	/** Reads a single float from current text content */
  60.246 +	float ReadFloatFromTextContent();
  60.247 +
  60.248 +	/** Calculates the resulting transformation from all the given transform steps */
  60.249 +	aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
  60.250 +
  60.251 +	/** Determines the input data type for the given semantic string */
  60.252 +	Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
  60.253 +
  60.254 +	/** Finds the item in the given library by its reference, throws if not found */
  60.255 +	template <typename Type> const Type& ResolveLibraryReference(
  60.256 +		const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
  60.257 +
  60.258 +protected:
  60.259 +	/** Filename, for a verbose error message */
  60.260 +	std::string mFileName;
  60.261 +
  60.262 +	/** XML reader, member for everyday use */
  60.263 +	irr::io::IrrXMLReader* mReader;
  60.264 +
  60.265 +	/** All data arrays found in the file by ID. Might be referred to by actually 
  60.266 +	    everyone. Collada, you are a steaming pile of indirection. */
  60.267 +	typedef std::map<std::string, Collada::Data> DataLibrary;
  60.268 +	DataLibrary mDataLibrary;
  60.269 +
  60.270 +	/** Same for accessors which define how the data in a data array is accessed. */
  60.271 +	typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
  60.272 +	AccessorLibrary mAccessorLibrary;
  60.273 +
  60.274 +	/** Mesh library: mesh by ID */
  60.275 +	typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
  60.276 +	MeshLibrary mMeshLibrary;
  60.277 +
  60.278 +	/** node library: root node of the hierarchy part by ID */
  60.279 +	typedef std::map<std::string, Collada::Node*> NodeLibrary;
  60.280 +	NodeLibrary mNodeLibrary;
  60.281 +
  60.282 +	/** Image library: stores texture properties by ID */
  60.283 +	typedef std::map<std::string, Collada::Image> ImageLibrary;
  60.284 +	ImageLibrary mImageLibrary;
  60.285 +
  60.286 +	/** Effect library: surface attributes by ID */
  60.287 +	typedef std::map<std::string, Collada::Effect> EffectLibrary;
  60.288 +	EffectLibrary mEffectLibrary;
  60.289 +
  60.290 +	/** Material library: surface material by ID */
  60.291 +	typedef std::map<std::string, Collada::Material> MaterialLibrary;
  60.292 +	MaterialLibrary mMaterialLibrary;
  60.293 +
  60.294 +	/** Light library: surface light by ID */
  60.295 +	typedef std::map<std::string, Collada::Light> LightLibrary;
  60.296 +	LightLibrary mLightLibrary;
  60.297 +
  60.298 +	/** Camera library: surface material by ID */
  60.299 +	typedef std::map<std::string, Collada::Camera> CameraLibrary;
  60.300 +	CameraLibrary mCameraLibrary;
  60.301 +
  60.302 +	/** Controller library: joint controllers by ID */
  60.303 +	typedef std::map<std::string, Collada::Controller> ControllerLibrary;
  60.304 +	ControllerLibrary mControllerLibrary;
  60.305 +
  60.306 +	/** Pointer to the root node. Don't delete, it just points to one of 
  60.307 +	    the nodes in the node library. */
  60.308 +	Collada::Node* mRootNode;
  60.309 +
  60.310 +	/** Root animation container */
  60.311 +	Collada::Animation mAnims;
  60.312 +
  60.313 +	/** Size unit: how large compared to a meter */
  60.314 +	float mUnitSize;
  60.315 +
  60.316 +	/** Which is the up vector */
  60.317 +	enum { UP_X, UP_Y, UP_Z } mUpDirection;
  60.318 +
  60.319 +	/** Collada file format version */
  60.320 +	Collada::FormatVersion mFormat;
  60.321 +};
  60.322 +
  60.323 +// ------------------------------------------------------------------------------------------------
  60.324 +// Check for element match
  60.325 +inline bool ColladaParser::IsElement( const char* pName) const
  60.326 +{
  60.327 +	ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); 
  60.328 +	return ::strcmp( mReader->getNodeName(), pName) == 0; 
  60.329 +}
  60.330 +
  60.331 +// ------------------------------------------------------------------------------------------------
  60.332 +// Finds the item in the given library by its reference, throws if not found
  60.333 +template <typename Type> 
  60.334 +const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const
  60.335 +{
  60.336 +	typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
  60.337 +	if( it == pLibrary.end())
  60.338 +		ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL));
  60.339 +	return it->second;
  60.340 +}
  60.341 +
  60.342 +} // end of namespace Assimp
  60.343 +
  60.344 +#endif // AI_COLLADAPARSER_H_INC
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/libs/assimp/ComputeUVMappingProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
    61.3 @@ -0,0 +1,504 @@
    61.4 +/*
    61.5 +Open Asset Import Library (assimp)
    61.6 +----------------------------------------------------------------------
    61.7 +
    61.8 +Copyright (c) 2006-2012, assimp team
    61.9 +All rights reserved.
   61.10 +
   61.11 +Redistribution and use of this software in source and binary forms, 
   61.12 +with or without modification, are permitted provided that the 
   61.13 +following conditions are met:
   61.14 +
   61.15 +* Redistributions of source code must retain the above
   61.16 +  copyright notice, this list of conditions and the
   61.17 +  following disclaimer.
   61.18 +
   61.19 +* Redistributions in binary form must reproduce the above
   61.20 +  copyright notice, this list of conditions and the
   61.21 +  following disclaimer in the documentation and/or other
   61.22 +  materials provided with the distribution.
   61.23 +
   61.24 +* Neither the name of the assimp team, nor the names of its
   61.25 +  contributors may be used to endorse or promote products
   61.26 +  derived from this software without specific prior
   61.27 +  written permission of the assimp team.
   61.28 +
   61.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   61.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   61.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   61.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   61.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   61.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   61.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   61.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   61.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   61.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   61.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   61.40 +
   61.41 +----------------------------------------------------------------------
   61.42 +*/
   61.43 +
   61.44 +/** @file GenUVCoords step */
   61.45 +
   61.46 +
   61.47 +#include "AssimpPCH.h"
   61.48 +#include "ComputeUVMappingProcess.h"
   61.49 +#include "ProcessHelper.h"
   61.50 +
   61.51 +using namespace Assimp;
   61.52 +
   61.53 +namespace {
   61.54 +
   61.55 +	const static aiVector3D base_axis_y(0.f,1.f,0.f);
   61.56 +	const static aiVector3D base_axis_x(1.f,0.f,0.f);
   61.57 +	const static aiVector3D base_axis_z(0.f,0.f,1.f);
   61.58 +	const static float angle_epsilon = 0.95f;
   61.59 +}
   61.60 +
   61.61 +// ------------------------------------------------------------------------------------------------
   61.62 +// Constructor to be privately used by Importer
   61.63 +ComputeUVMappingProcess::ComputeUVMappingProcess()
   61.64 +{
   61.65 +	// nothing to do here
   61.66 +}
   61.67 +
   61.68 +// ------------------------------------------------------------------------------------------------
   61.69 +// Destructor, private as well
   61.70 +ComputeUVMappingProcess::~ComputeUVMappingProcess()
   61.71 +{
   61.72 +	// nothing to do here
   61.73 +}
   61.74 +
   61.75 +// ------------------------------------------------------------------------------------------------
   61.76 +// Returns whether the processing step is present in the given flag field.
   61.77 +bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const
   61.78 +{
   61.79 +	return	(pFlags & aiProcess_GenUVCoords) != 0;
   61.80 +}
   61.81 +
   61.82 +// ------------------------------------------------------------------------------------------------
   61.83 +// Check whether a ray intersects a plane and find the intersection point
   61.84 +inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
   61.85 +	const aiVector3D& planeNormal, aiVector3D& pos)
   61.86 +{
   61.87 +	const float b = planeNormal * (planePos - ray.pos);
   61.88 +	float h = ray.dir * planeNormal;
   61.89 +    if ((h < 10e-5f && h > -10e-5f) || (h = b/h) < 0)
   61.90 +		return false;
   61.91 +
   61.92 +    pos = ray.pos + (ray.dir * h);
   61.93 +    return true;
   61.94 +}
   61.95 +
   61.96 +// ------------------------------------------------------------------------------------------------
   61.97 +// Find the first empty UV channel in a mesh
   61.98 +inline unsigned int FindEmptyUVChannel (aiMesh* mesh)
   61.99 +{
  61.100 +	for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m)
  61.101 +		if (!mesh->mTextureCoords[m])return m;
  61.102 +	
  61.103 +	DefaultLogger::get()->error("Unable to compute UV coordinates, no free UV slot found");
  61.104 +	return UINT_MAX;
  61.105 +}
  61.106 +
  61.107 +// ------------------------------------------------------------------------------------------------
  61.108 +// Try to remove UV seams
  61.109 +void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
  61.110 +{
  61.111 +	// TODO: just a very rough algorithm. I think it could be done
  61.112 +	// much easier, but I don't know how and am currently too tired to 
  61.113 +	// to think about a better solution. 
  61.114 +
  61.115 +	const static float LOWER_LIMIT = 0.1f;
  61.116 +	const static float UPPER_LIMIT = 0.9f;
  61.117 +
  61.118 +	const static float LOWER_EPSILON = 10e-3f;
  61.119 +	const static float UPPER_EPSILON = 1.f-10e-3f;
  61.120 +
  61.121 +	for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx)
  61.122 +	{
  61.123 +		const aiFace& face = mesh->mFaces[fidx];
  61.124 +		if (face.mNumIndices < 3) continue; // triangles and polygons only, please
  61.125 +
  61.126 +		unsigned int small = face.mNumIndices, large = small;
  61.127 +		bool zero = false, one = false, round_to_zero = false;
  61.128 +
  61.129 +		// Check whether this face lies on a UV seam. We can just guess,
  61.130 +		// but the assumption that a face with at least one very small
  61.131 +		// on the one side and one very large U coord on the other side 
  61.132 +		// lies on a UV seam should work for most cases.
  61.133 +		for (unsigned int n = 0; n < face.mNumIndices;++n)
  61.134 +		{
  61.135 +			if (out[face.mIndices[n]].x < LOWER_LIMIT)
  61.136 +			{
  61.137 +				small = n;
  61.138 +
  61.139 +				// If we have a U value very close to 0 we can't
  61.140 +				// round the others to 0, too.
  61.141 +				if (out[face.mIndices[n]].x <= LOWER_EPSILON)
  61.142 +					zero = true;
  61.143 +				else round_to_zero = true;
  61.144 +			}
  61.145 +			if (out[face.mIndices[n]].x > UPPER_LIMIT)
  61.146 +			{
  61.147 +				large = n;
  61.148 +
  61.149 +				// If we have a U value very close to 1 we can't
  61.150 +				// round the others to 1, too.
  61.151 +				if (out[face.mIndices[n]].x >= UPPER_EPSILON)
  61.152 +					one = true;
  61.153 +			}
  61.154 +		}
  61.155 +		if (small != face.mNumIndices && large != face.mNumIndices)
  61.156 +		{
  61.157 +			for (unsigned int n = 0; n < face.mNumIndices;++n)
  61.158 +			{
  61.159 +				// If the u value is over the upper limit and no other u 
  61.160 +				// value of that face is 0, round it to 0
  61.161 +				if (out[face.mIndices[n]].x > UPPER_LIMIT && !zero)
  61.162 +					out[face.mIndices[n]].x = 0.f;
  61.163 +
  61.164 +				// If the u value is below the lower limit and no other u 
  61.165 +				// value of that face is 1, round it to 1
  61.166 +				else if (out[face.mIndices[n]].x < LOWER_LIMIT && !one)
  61.167 +					out[face.mIndices[n]].x = 1.f;
  61.168 +
  61.169 +				// The face contains both 0 and 1 as UV coords. This can occur
  61.170 +				// for faces which have an edge that lies directly on the seam.
  61.171 +				// Due to numerical inaccuracies one U coord becomes 0, the
  61.172 +				// other 1. But we do still have a third UV coord to determine 
  61.173 +				// to which side we must round to.
  61.174 +				else if (one && zero)
  61.175 +				{
  61.176 +					if (round_to_zero && out[face.mIndices[n]].x >=  UPPER_EPSILON)
  61.177 +						out[face.mIndices[n]].x = 0.f;
  61.178 +					else if (!round_to_zero && out[face.mIndices[n]].x <= LOWER_EPSILON)
  61.179 +						out[face.mIndices[n]].x = 1.f;
  61.180 +				}
  61.181 +			}
  61.182 +		}
  61.183 +	}
  61.184 +}
  61.185 +
  61.186 +// ------------------------------------------------------------------------------------------------
  61.187 +void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
  61.188 +{
  61.189 +	aiVector3D center, min, max;
  61.190 +	FindMeshCenter(mesh, center, min, max);
  61.191 +
  61.192 +	// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
  61.193 +	// currently the mapping axis will always be one of x,y,z, except if the
  61.194 +	// PretransformVertices step is used (it transforms the meshes into worldspace, 
  61.195 +	// thus changing the mapping axis)
  61.196 +	if (axis * base_axis_x >= angle_epsilon)	{
  61.197 +
  61.198 +		// For each point get a normalized projection vector in the sphere,
  61.199 +		// get its longitude and latitude and map them to their respective
  61.200 +		// UV axes. Problems occur around the poles ... unsolvable.
  61.201 +		//
  61.202 +		// The spherical coordinate system looks like this:
  61.203 +		// x = cos(lon)*cos(lat)
  61.204 +		// y = sin(lon)*cos(lat)
  61.205 +		// z = sin(lat)
  61.206 +		// 
  61.207 +		// Thus we can derive:
  61.208 +		// lat  = arcsin (z)
  61.209 +		// lon  = arctan (y/x)
  61.210 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.211 +			const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
  61.212 +			out[pnt] = aiVector3D((atan2 (diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
  61.213 +				(asin  (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
  61.214 +		}
  61.215 +	}
  61.216 +	else if (axis * base_axis_y >= angle_epsilon)	{
  61.217 +		// ... just the same again
  61.218 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.219 +			const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
  61.220 +			out[pnt] = aiVector3D((atan2 (diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
  61.221 +				(asin  (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
  61.222 +		}
  61.223 +	}
  61.224 +	else if (axis * base_axis_z >= angle_epsilon)	{
  61.225 +		// ... just the same again
  61.226 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.227 +			const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
  61.228 +			out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
  61.229 +				(asin  (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
  61.230 +		}
  61.231 +	}
  61.232 +	// slower code path in case the mapping axis is not one of the coordinate system axes
  61.233 +	else	{
  61.234 +		aiMatrix4x4 mTrafo;
  61.235 +		aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
  61.236 +
  61.237 +		// again the same, except we're applying a transformation now
  61.238 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.239 +			const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize();
  61.240 +			out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
  61.241 +				(asin  (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
  61.242 +		}
  61.243 +	}
  61.244 +	
  61.245 +	
  61.246 +	// Now find and remove UV seams. A seam occurs if a face has a tcoord
  61.247 +	// close to zero on the one side, and a tcoord close to one on the
  61.248 +	// other side.
  61.249 +	RemoveUVSeams(mesh,out);
  61.250 +}
  61.251 +
  61.252 +// ------------------------------------------------------------------------------------------------
  61.253 +void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
  61.254 +{
  61.255 +	aiVector3D center, min, max;
  61.256 +
  61.257 +	// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
  61.258 +	// currently the mapping axis will always be one of x,y,z, except if the
  61.259 +	// PretransformVertices step is used (it transforms the meshes into worldspace, 
  61.260 +	// thus changing the mapping axis)
  61.261 +	if (axis * base_axis_x >= angle_epsilon)	{
  61.262 +		FindMeshCenter(mesh, center, min, max);
  61.263 +		const float diff = max.x - min.x;
  61.264 +
  61.265 +		// If the main axis is 'z', the z coordinate of a point 'p' is mapped 
  61.266 +		// directly to the texture V axis. The other axis is derived from
  61.267 +		// the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where
  61.268 +		// 'c' is the center point of the mesh.
  61.269 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.270 +			const aiVector3D& pos = mesh->mVertices[pnt];
  61.271 +			aiVector3D& uv  = out[pnt];
  61.272 +
  61.273 +			uv.y = (pos.x - min.x) / diff;
  61.274 +			uv.x = (atan2 ( pos.z - center.z, pos.y - center.y) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
  61.275 +		}
  61.276 +	}
  61.277 +	else if (axis * base_axis_y >= angle_epsilon)	{
  61.278 +		FindMeshCenter(mesh, center, min, max);
  61.279 +		const float diff = max.y - min.y;
  61.280 +
  61.281 +		// just the same ...
  61.282 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.283 +			const aiVector3D& pos = mesh->mVertices[pnt];
  61.284 +			aiVector3D& uv  = out[pnt];
  61.285 +
  61.286 +			uv.y = (pos.y - min.y) / diff;
  61.287 +			uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
  61.288 +		}
  61.289 +	}
  61.290 +	else if (axis * base_axis_z >= angle_epsilon)	{
  61.291 +		FindMeshCenter(mesh, center, min, max);
  61.292 +		const float diff = max.z - min.z;
  61.293 +
  61.294 +		// just the same ...
  61.295 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.296 +			const aiVector3D& pos = mesh->mVertices[pnt];
  61.297 +			aiVector3D& uv  = out[pnt];
  61.298 +
  61.299 +			uv.y = (pos.z - min.z) / diff;
  61.300 +			uv.x = (atan2 ( pos.y - center.y, pos.x - center.x) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
  61.301 +		}
  61.302 +	}
  61.303 +	// slower code path in case the mapping axis is not one of the coordinate system axes
  61.304 +	else {
  61.305 +		aiMatrix4x4 mTrafo;
  61.306 +		aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
  61.307 +		FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
  61.308 +		const float diff = max.y - min.y;
  61.309 +
  61.310 +		// again the same, except we're applying a transformation now
  61.311 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt){
  61.312 +			const aiVector3D pos = mTrafo* mesh->mVertices[pnt];
  61.313 +			aiVector3D& uv  = out[pnt];
  61.314 +
  61.315 +			uv.y = (pos.y - min.y) / diff;
  61.316 +			uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
  61.317 +		}
  61.318 +	}
  61.319 +
  61.320 +	// Now find and remove UV seams. A seam occurs if a face has a tcoord
  61.321 +	// close to zero on the one side, and a tcoord close to one on the
  61.322 +	// other side.
  61.323 +	RemoveUVSeams(mesh,out);
  61.324 +}
  61.325 +
  61.326 +// ------------------------------------------------------------------------------------------------
  61.327 +void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
  61.328 +{
  61.329 +	float diffu,diffv;
  61.330 +	aiVector3D center, min, max;
  61.331 +
  61.332 +	// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
  61.333 +	// currently the mapping axis will always be one of x,y,z, except if the
  61.334 +	// PretransformVertices step is used (it transforms the meshes into worldspace, 
  61.335 +	// thus changing the mapping axis)
  61.336 +	if (axis * base_axis_x >= angle_epsilon)	{
  61.337 +		FindMeshCenter(mesh, center, min, max);
  61.338 +		diffu = max.z - min.z;
  61.339 +		diffv = max.y - min.y;
  61.340 +
  61.341 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.342 +			const aiVector3D& pos = mesh->mVertices[pnt];
  61.343 +			out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv,0.f);
  61.344 +		}
  61.345 +	}
  61.346 +	else if (axis * base_axis_y >= angle_epsilon)	{
  61.347 +		FindMeshCenter(mesh, center, min, max);
  61.348 +		diffu = max.x - min.x;
  61.349 +		diffv = max.z - min.z;
  61.350 +
  61.351 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.352 +			const aiVector3D& pos = mesh->mVertices[pnt];
  61.353 +			out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.f);
  61.354 +		}
  61.355 +	}
  61.356 +	else if (axis * base_axis_z >= angle_epsilon)	{
  61.357 +		FindMeshCenter(mesh, center, min, max);
  61.358 +		diffu = max.y - min.y;
  61.359 +		diffv = max.z - min.z;
  61.360 +
  61.361 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.362 +			const aiVector3D& pos = mesh->mVertices[pnt];
  61.363 +			out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.f);
  61.364 +		}
  61.365 +	}
  61.366 +	// slower code path in case the mapping axis is not one of the coordinate system axes
  61.367 +	else
  61.368 +	{
  61.369 +		aiMatrix4x4 mTrafo;
  61.370 +		aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
  61.371 +		FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
  61.372 +		diffu = max.x - min.x;
  61.373 +		diffv = max.z - min.z;
  61.374 +
  61.375 +		// again the same, except we're applying a transformation now
  61.376 +		for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)	{
  61.377 +			const aiVector3D pos = mTrafo * mesh->mVertices[pnt];
  61.378 +			out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.f);
  61.379 +		}
  61.380 +	}
  61.381 +
  61.382 +	// shouldn't be necessary to remove UV seams ...
  61.383 +}
  61.384 +
  61.385 +// ------------------------------------------------------------------------------------------------
  61.386 +void ComputeUVMappingProcess::ComputeBoxMapping(aiMesh* /*mesh*/, aiVector3D* /*out*/)
  61.387 +{
  61.388 +	DefaultLogger::get()->error("Mapping type currently not implemented");
  61.389 +}
  61.390 +
  61.391 +// ------------------------------------------------------------------------------------------------
  61.392 +void ComputeUVMappingProcess::Execute( aiScene* pScene) 
  61.393 +{
  61.394 +	DefaultLogger::get()->debug("GenUVCoordsProcess begin");
  61.395 +	char buffer[1024];
  61.396 +
  61.397 +	if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
  61.398 +		throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
  61.399 +
  61.400 +	std::list<MappingInfo> mappingStack;
  61.401 +
  61.402 +	/*  Iterate through all materials and search for non-UV mapped textures
  61.403 +	 */
  61.404 +	for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
  61.405 +	{
  61.406 +		mappingStack.clear();
  61.407 +		aiMaterial* mat = pScene->mMaterials[i];
  61.408 +		for (unsigned int a = 0; a < mat->mNumProperties;++a)
  61.409 +		{
  61.410 +			aiMaterialProperty* prop = mat->mProperties[a];
  61.411 +			if (!::strcmp( prop->mKey.data, "$tex.mapping"))
  61.412 +			{
  61.413 +				aiTextureMapping& mapping = *((aiTextureMapping*)prop->mData);
  61.414 +				if (aiTextureMapping_UV != mapping)
  61.415 +				{
  61.416 +					if (!DefaultLogger::isNullLogger())
  61.417 +					{
  61.418 +						sprintf(buffer, "Found non-UV mapped texture (%s,%i). Mapping type: %s",
  61.419 +							TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
  61.420 +							MappingTypeToString(mapping));
  61.421 +
  61.422 +						DefaultLogger::get()->info(buffer);
  61.423 +					}
  61.424 +
  61.425 +					if (aiTextureMapping_OTHER == mapping)
  61.426 +						continue;
  61.427 +
  61.428 +					MappingInfo info (mapping);
  61.429 +
  61.430 +					// Get further properties - currently only the major axis
  61.431 +					for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)
  61.432 +					{
  61.433 +						aiMaterialProperty* prop2 = mat->mProperties[a2];
  61.434 +						if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
  61.435 +							continue;
  61.436 +
  61.437 +						if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis"))	{
  61.438 +							info.axis = *((aiVector3D*)prop2->mData);
  61.439 +							break;
  61.440 +						}
  61.441 +					}
  61.442 +
  61.443 +					unsigned int idx;
  61.444 +
  61.445 +					// Check whether we have this mapping mode already
  61.446 +					std::list<MappingInfo>::iterator it = std::find (mappingStack.begin(),mappingStack.end(), info);
  61.447 +					if (mappingStack.end() != it)
  61.448 +					{
  61.449 +						idx = (*it).uv;
  61.450 +					}
  61.451 +					else
  61.452 +					{
  61.453 +						/*  We have found a non-UV mapped texture. Now
  61.454 +						*   we need to find all meshes using this material
  61.455 +						*   that we can compute UV channels for them.
  61.456 +						*/
  61.457 +						for (unsigned int m = 0; m < pScene->mNumMeshes;++m)
  61.458 +						{
  61.459 +							aiMesh* mesh = pScene->mMeshes[m];
  61.460 +							unsigned int outIdx;
  61.461 +							if ( mesh->mMaterialIndex != i || ( outIdx = FindEmptyUVChannel(mesh) ) == UINT_MAX ||
  61.462 +								!mesh->mNumVertices)
  61.463 +							{
  61.464 +								continue;
  61.465 +							}
  61.466 +
  61.467 +							// Allocate output storage
  61.468 +							aiVector3D* p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices];
  61.469 +
  61.470 +							switch (mapping)
  61.471 +							{
  61.472 +							case aiTextureMapping_SPHERE:
  61.473 +								ComputeSphereMapping(mesh,info.axis,p);
  61.474 +								break;
  61.475 +							case aiTextureMapping_CYLINDER:
  61.476 +								ComputeCylinderMapping(mesh,info.axis,p);
  61.477 +								break;
  61.478 +							case aiTextureMapping_PLANE:
  61.479 +								ComputePlaneMapping(mesh,info.axis,p);
  61.480 +								break;
  61.481 +							case aiTextureMapping_BOX:
  61.482 +								ComputeBoxMapping(mesh,p);
  61.483 +								break;
  61.484 +							default:
  61.485 +								ai_assert(false);
  61.486 +							}
  61.487 +							if (m && idx != outIdx)
  61.488 +							{
  61.489 +								DefaultLogger::get()->warn("UV index mismatch. Not all meshes assigned to "
  61.490 +									"this material have equal numbers of UV channels. The UV index stored in  "
  61.491 +									"the material structure does therefore not apply for all meshes. ");
  61.492 +							}
  61.493 +							idx = outIdx;
  61.494 +						}
  61.495 +						info.uv = idx;
  61.496 +						mappingStack.push_back(info);
  61.497 +					}
  61.498 +
  61.499 +					// Update the material property list
  61.500 +					mapping = aiTextureMapping_UV;
  61.501 +					((aiMaterial*)mat)->AddProperty(&idx,1,AI_MATKEY_UVWSRC(prop->mSemantic,prop->mIndex));
  61.502 +				}
  61.503 +			}
  61.504 +		}
  61.505 +	}
  61.506 +	DefaultLogger::get()->debug("GenUVCoordsProcess finished");
  61.507 +}
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/libs/assimp/ComputeUVMappingProcess.h	Sat Feb 01 19:58:19 2014 +0200
    62.3 @@ -0,0 +1,144 @@
    62.4 +/*
    62.5 +Open Asset Import Library (assimp)
    62.6 +----------------------------------------------------------------------
    62.7 +
    62.8 +Copyright (c) 2006-2012, assimp team
    62.9 +All rights reserved.
   62.10 +
   62.11 +Redistribution and use of this software in source and binary forms, 
   62.12 +with or without modification, are permitted provided that the 
   62.13 +following conditions are met:
   62.14 +
   62.15 +* Redistributions of source code must retain the above
   62.16 +  copyright notice, this list of conditions and the
   62.17 +  following disclaimer.
   62.18 +
   62.19 +* Redistributions in binary form must reproduce the above
   62.20 +  copyright notice, this list of conditions and the
   62.21 +  following disclaimer in the documentation and/or other
   62.22 +  materials provided with the distribution.
   62.23 +
   62.24 +* Neither the name of the assimp team, nor the names of its
   62.25 +  contributors may be used to endorse or promote products
   62.26 +  derived from this software without specific prior
   62.27 +  written permission of the assimp team.
   62.28 +
   62.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   62.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   62.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   62.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   62.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   62.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   62.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   62.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   62.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   62.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   62.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   62.40 +
   62.41 +----------------------------------------------------------------------
   62.42 +*/
   62.43 +
   62.44 +/** @file Defines a post processing step to compute UV coordinates
   62.45 +  from abstract mappings, such as box or spherical*/
   62.46 +#ifndef AI_COMPUTEUVMAPPING_H_INC
   62.47 +#define AI_COMPUTEUVMAPPING_H_INC
   62.48 +
   62.49 +#include "BaseProcess.h"
   62.50 +#include "assimp/mesh.h"
   62.51 +
   62.52 +class ComputeUVMappingTest;
   62.53 +namespace Assimp
   62.54 +	{
   62.55 +
   62.56 +// ---------------------------------------------------------------------------
   62.57 +/** ComputeUVMappingProcess - converts special mappings, such as spherical,
   62.58 + *  cylindrical or boxed to proper UV coordinates for rendering.
   62.59 +*/
   62.60 +class ComputeUVMappingProcess : public BaseProcess
   62.61 +{
   62.62 +public:
   62.63 +	ComputeUVMappingProcess();
   62.64 +	~ComputeUVMappingProcess();
   62.65 +
   62.66 +public:
   62.67 +
   62.68 +	// -------------------------------------------------------------------
   62.69 +	/** Returns whether the processing step is present in the given flag field.
   62.70 +	* @param pFlags The processing flags the importer was called with. A bitwise
   62.71 +	*   combination of #aiPostProcessSteps.
   62.72 +	* @return true if the process is present in this flag fields, false if not.
   62.73 +	*/
   62.74 +	bool IsActive( unsigned int pFlags) const;
   62.75 +
   62.76 +	// -------------------------------------------------------------------
   62.77 +	/** Executes the post processing step on the given imported data.
   62.78 +	* At the moment a process is not supposed to fail.
   62.79 +	* @param pScene The imported data to work at.
   62.80 +	*/
   62.81 +	void Execute( aiScene* pScene);
   62.82 +
   62.83 +protected:
   62.84 +
   62.85 +	// -------------------------------------------------------------------
   62.86 +	/** Computes spherical UV coordinates for a mesh
   62.87 +	 *
   62.88 +	 *  @param mesh Mesh to be processed
   62.89 +	 *  @param axis Main axis
   62.90 +	 *  @param out Receives output UV coordinates
   62.91 +	*/
   62.92 +	void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis,
   62.93 +		aiVector3D* out);
   62.94 +
   62.95 +	// -------------------------------------------------------------------
   62.96 +	/** Computes cylindrical UV coordinates for a mesh
   62.97 +	 *
   62.98 +	 *  @param mesh Mesh to be processed
   62.99 +	 *  @param axis Main axis
  62.100 +	 *  @param out Receives output UV coordinates
  62.101 +	*/
  62.102 +	void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis,
  62.103 +		aiVector3D* out);
  62.104 +
  62.105 +	// -------------------------------------------------------------------
  62.106 +	/** Computes planar UV coordinates for a mesh
  62.107 +	 *
  62.108 +	 *  @param mesh Mesh to be processed
  62.109 +	 *  @param axis Main axis
  62.110 +	 *  @param out Receives output UV coordinates
  62.111 +	*/
  62.112 +	void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, 
  62.113 +		aiVector3D* out);
  62.114 +
  62.115 +	// -------------------------------------------------------------------
  62.116 +	/** Computes cubic UV coordinates for a mesh
  62.117 +	 *
  62.118 +	 *  @param mesh Mesh to be processed
  62.119 +	 *  @param out Receives output UV coordinates
  62.120 +	*/
  62.121 +	void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out);
  62.122 +
  62.123 +private:
  62.124 +
  62.125 +	// temporary structure to describe a mapping
  62.126 +	struct MappingInfo
  62.127 +	{
  62.128 +		MappingInfo(aiTextureMapping _type)
  62.129 +			: type	(_type)
  62.130 +			, axis	(0.f,1.f,0.f)
  62.131 +			, uv	(0u)
  62.132 +		{}
  62.133 +
  62.134 +		aiTextureMapping type;
  62.135 +		aiVector3D axis;
  62.136 +		unsigned int uv;
  62.137 +
  62.138 +		bool operator== (const MappingInfo& other)
  62.139 +		{
  62.140 +			return type == other.type && axis == other.axis;
  62.141 +		}
  62.142 +	};
  62.143 +};
  62.144 +
  62.145 +} // end of namespace Assimp
  62.146 +
  62.147 +#endif // AI_COMPUTEUVMAPPING_H_INC
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/libs/assimp/ConvertToLHProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
    63.3 @@ -0,0 +1,318 @@
    63.4 +/*
    63.5 +---------------------------------------------------------------------------
    63.6 +Open Asset Import Library (assimp)
    63.7 +---------------------------------------------------------------------------
    63.8 +
    63.9 +Copyright (c) 2006-2012, assimp team
   63.10 +
   63.11 +All rights reserved.
   63.12 +
   63.13 +Redistribution and use of this software in source and binary forms, 
   63.14 +with or without modification, are permitted provided that the following 
   63.15 +conditions are met:
   63.16 +
   63.17 +* Redistributions of source code must retain the above
   63.18 +  copyright notice, this list of conditions and the
   63.19 +  following disclaimer.
   63.20 +
   63.21 +* Redistributions in binary form must reproduce the above
   63.22 +  copyright notice, this list of conditions and the
   63.23 +  following disclaimer in the documentation and/or other
   63.24 +  materials provided with the distribution.
   63.25 +
   63.26 +* Neither the name of the assimp team, nor the names of its
   63.27 +  contributors may be used to endorse or promote products
   63.28 +  derived from this software without specific prior
   63.29 +  written permission of the assimp team.
   63.30 +
   63.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   63.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   63.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   63.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   63.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   63.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   63.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   63.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   63.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   63.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   63.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   63.42 +---------------------------------------------------------------------------
   63.43 +*/
   63.44 +
   63.45 +/** @file  MakeLeftHandedProcess.cpp
   63.46 + *  @brief Implementation of the post processing step to convert all
   63.47 + *  imported data to a left-handed coordinate system.
   63.48 + *
   63.49 + *  Face order & UV flip are also implemented here, for the sake of a
   63.50 + *  better location.
   63.51 + */
   63.52 +
   63.53 +#include "AssimpPCH.h"
   63.54 +#include "ConvertToLHProcess.h"
   63.55 +
   63.56 +using namespace Assimp;
   63.57 +
   63.58 +#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
   63.59 +
   63.60 +// ------------------------------------------------------------------------------------------------
   63.61 +// Constructor to be privately used by Importer
   63.62 +MakeLeftHandedProcess::MakeLeftHandedProcess()
   63.63 +{}
   63.64 +
   63.65 +// ------------------------------------------------------------------------------------------------
   63.66 +// Destructor, private as well
   63.67 +MakeLeftHandedProcess::~MakeLeftHandedProcess()
   63.68 +{}
   63.69 +
   63.70 +// ------------------------------------------------------------------------------------------------
   63.71 +// Returns whether the processing step is present in the given flag field.
   63.72 +bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const
   63.73 +{
   63.74 +	return 0 != (pFlags & aiProcess_MakeLeftHanded);
   63.75 +}
   63.76 +
   63.77 +// ------------------------------------------------------------------------------------------------
   63.78 +// Executes the post processing step on the given imported data.
   63.79 +void MakeLeftHandedProcess::Execute( aiScene* pScene)
   63.80 +{
   63.81 +	// Check for an existent root node to proceed
   63.82 +	ai_assert(pScene->mRootNode != NULL);
   63.83 +	DefaultLogger::get()->debug("MakeLeftHandedProcess begin");
   63.84 +
   63.85 +	// recursively convert all the nodes 
   63.86 +	ProcessNode( pScene->mRootNode, aiMatrix4x4());
   63.87 +
   63.88 +	// process the meshes accordingly
   63.89 +	for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
   63.90 +		ProcessMesh( pScene->mMeshes[a]);
   63.91 +
   63.92 +	// process the materials accordingly
   63.93 +	for( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
   63.94 +		ProcessMaterial( pScene->mMaterials[a]);
   63.95 +
   63.96 +	// transform all animation channels as well
   63.97 +	for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
   63.98 +	{
   63.99 +		aiAnimation* anim = pScene->mAnimations[a];
  63.100 +		for( unsigned int b = 0; b < anim->mNumChannels; b++)
  63.101 +		{
  63.102 +			aiNodeAnim* nodeAnim = anim->mChannels[b];
  63.103 +			ProcessAnimation( nodeAnim);
  63.104 +		}
  63.105 +	}
  63.106 +	DefaultLogger::get()->debug("MakeLeftHandedProcess finished");
  63.107 +}
  63.108 +
  63.109 +// ------------------------------------------------------------------------------------------------
  63.110 +// Recursively converts a node, all of its children and all of its meshes
  63.111 +void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation)
  63.112 +{
  63.113 +	// mirror all base vectors at the local Z axis
  63.114 +	pNode->mTransformation.c1 = -pNode->mTransformation.c1;
  63.115 +	pNode->mTransformation.c2 = -pNode->mTransformation.c2;
  63.116 +	pNode->mTransformation.c3 = -pNode->mTransformation.c3;
  63.117 +	pNode->mTransformation.c4 = -pNode->mTransformation.c4;
  63.118 +
  63.119 +	// now invert the Z axis again to keep the matrix determinant positive.
  63.120 +	// The local meshes will be inverted accordingly so that the result should look just fine again.
  63.121 +	pNode->mTransformation.a3 = -pNode->mTransformation.a3;
  63.122 +	pNode->mTransformation.b3 = -pNode->mTransformation.b3;
  63.123 +	pNode->mTransformation.c3 = -pNode->mTransformation.c3;
  63.124 +	pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
  63.125 +
  63.126 +	// continue for all children
  63.127 +	for( size_t a = 0; a < pNode->mNumChildren; ++a)
  63.128 +		ProcessNode( pNode->mChildren[a], pParentGlobalRotation * pNode->mTransformation);
  63.129 +}
  63.130 +
  63.131 +// ------------------------------------------------------------------------------------------------
  63.132 +// Converts a single mesh to left handed coordinates. 
  63.133 +void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
  63.134 +{
  63.135 +	// mirror positions, normals and stuff along the Z axis
  63.136 +	for( size_t a = 0; a < pMesh->mNumVertices; ++a)
  63.137 +	{
  63.138 +		pMesh->mVertices[a].z *= -1.0f;
  63.139 +		if( pMesh->HasNormals())
  63.140 +			pMesh->mNormals[a].z *= -1.0f;
  63.141 +		if( pMesh->HasTangentsAndBitangents())
  63.142 +		{
  63.143 +			pMesh->mTangents[a].z *= -1.0f;
  63.144 +			pMesh->mBitangents[a].z *= -1.0f;
  63.145 +		}
  63.146 +	}
  63.147 +
  63.148 +	// mirror offset matrices of all bones
  63.149 +	for( size_t a = 0; a < pMesh->mNumBones; ++a)
  63.150 +	{
  63.151 +		aiBone* bone = pMesh->mBones[a];
  63.152 +		bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3;
  63.153 +		bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3;
  63.154 +		bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3;
  63.155 +		bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1;
  63.156 +		bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2;
  63.157 +		bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4;
  63.158 +	}
  63.159 +
  63.160 +	// mirror bitangents as well as they're derived from the texture coords
  63.161 +	if( pMesh->HasTangentsAndBitangents())
  63.162 +	{
  63.163 +		for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
  63.164 +			pMesh->mBitangents[a] *= -1.0f;
  63.165 +	}
  63.166 +}
  63.167 +
  63.168 +// ------------------------------------------------------------------------------------------------
  63.169 +// Converts a single material to left handed coordinates. 
  63.170 +void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
  63.171 +{
  63.172 +	aiMaterial* mat = (aiMaterial*)_mat;
  63.173 +	for (unsigned int a = 0; a < mat->mNumProperties;++a)	{
  63.174 +		aiMaterialProperty* prop = mat->mProperties[a];
  63.175 +
  63.176 +		// Mapping axis for UV mappings?
  63.177 +		if (!::strcmp( prop->mKey.data, "$tex.mapaxis"))	{
  63.178 +			ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */ 
  63.179 +			aiVector3D* pff = (aiVector3D*)prop->mData;
  63.180 +
  63.181 +			pff->z *= -1.f;
  63.182 +		}
  63.183 +	}
  63.184 +}
  63.185 +
  63.186 +// ------------------------------------------------------------------------------------------------
  63.187 +// Converts the given animation to LH coordinates. 
  63.188 +void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim) 
  63.189 +{ 
  63.190 +	// position keys 
  63.191 +	for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++) 
  63.192 +		pAnim->mPositionKeys[a].mValue.z *= -1.0f; 
  63.193 +
  63.194 +	// rotation keys 
  63.195 +	for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++) 
  63.196 +	{ 
  63.197 +		/* That's the safe version, but the float errors add up. So we try the short version instead 
  63.198 +		aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix(); 
  63.199 +		rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3; 
  63.200 +		rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2; 
  63.201 +		aiQuaternion rotquat( rotmat); 
  63.202 +		pAnim->mRotationKeys[a].mValue = rotquat; 
  63.203 +		*/ 
  63.204 +		pAnim->mRotationKeys[a].mValue.x *= -1.0f; 
  63.205 +		pAnim->mRotationKeys[a].mValue.y *= -1.0f; 
  63.206 +	} 
  63.207 +} 
  63.208 +
  63.209 +#endif // !!  ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
  63.210 +#ifndef  ASSIMP_BUILD_NO_FLIPUVS_PROCESS
  63.211 +// # FlipUVsProcess
  63.212 +
  63.213 +// ------------------------------------------------------------------------------------------------
  63.214 +// Constructor to be privately used by Importer
  63.215 +FlipUVsProcess::FlipUVsProcess()
  63.216 +{}
  63.217 +
  63.218 +// ------------------------------------------------------------------------------------------------
  63.219 +// Destructor, private as well
  63.220 +FlipUVsProcess::~FlipUVsProcess()
  63.221 +{}
  63.222 +
  63.223 +// ------------------------------------------------------------------------------------------------
  63.224 +// Returns whether the processing step is present in the given flag field.
  63.225 +bool FlipUVsProcess::IsActive( unsigned int pFlags) const
  63.226 +{
  63.227 +	return 0 != (pFlags & aiProcess_FlipUVs);
  63.228 +}
  63.229 +
  63.230 +// ------------------------------------------------------------------------------------------------
  63.231 +// Executes the post processing step on the given imported data.
  63.232 +void FlipUVsProcess::Execute( aiScene* pScene)
  63.233 +{
  63.234 +	DefaultLogger::get()->debug("FlipUVsProcess begin");
  63.235 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
  63.236 +		ProcessMesh(pScene->mMeshes[i]);
  63.237 +
  63.238 +	for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
  63.239 +		ProcessMaterial(pScene->mMaterials[i]);
  63.240 +	DefaultLogger::get()->debug("FlipUVsProcess finished");
  63.241 +}
  63.242 +
  63.243 +// ------------------------------------------------------------------------------------------------
  63.244 +// Converts a single material 
  63.245 +void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
  63.246 +{
  63.247 +	aiMaterial* mat = (aiMaterial*)_mat;
  63.248 +	for (unsigned int a = 0; a < mat->mNumProperties;++a)	{
  63.249 +		aiMaterialProperty* prop = mat->mProperties[a];
  63.250 +
  63.251 +		// UV transformation key?
  63.252 +		if (!::strcmp( prop->mKey.data, "$tex.uvtrafo"))	{
  63.253 +			ai_assert( prop->mDataLength >= sizeof(aiUVTransform));  /* something is wrong with the validation if we end up here */
  63.254 +			aiUVTransform* uv = (aiUVTransform*)prop->mData;
  63.255 +
  63.256 +			// just flip it, that's everything
  63.257 +			uv->mTranslation.y *= -1.f;
  63.258 +			uv->mRotation *= -1.f;
  63.259 +		}
  63.260 +	}
  63.261 +}
  63.262 +
  63.263 +// ------------------------------------------------------------------------------------------------
  63.264 +// Converts a single mesh 
  63.265 +void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
  63.266 +{
  63.267 +	// mirror texture y coordinate
  63.268 +	for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)	{
  63.269 +		if( !pMesh->HasTextureCoords( a))
  63.270 +			break;
  63.271 +
  63.272 +		for( unsigned int b = 0; b < pMesh->mNumVertices; b++)
  63.273 +			pMesh->mTextureCoords[a][b].y = 1.0f - pMesh->mTextureCoords[a][b].y;
  63.274 +	}
  63.275 +}
  63.276 +
  63.277 +#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
  63.278 +#ifndef  ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
  63.279 +// # FlipWindingOrderProcess
  63.280 +
  63.281 +// ------------------------------------------------------------------------------------------------
  63.282 +// Constructor to be privately used by Importer
  63.283 +FlipWindingOrderProcess::FlipWindingOrderProcess()
  63.284 +{}
  63.285 +
  63.286 +// ------------------------------------------------------------------------------------------------
  63.287 +// Destructor, private as well
  63.288 +FlipWindingOrderProcess::~FlipWindingOrderProcess()
  63.289 +{}
  63.290 +
  63.291 +// ------------------------------------------------------------------------------------------------
  63.292 +// Returns whether the processing step is present in the given flag field.
  63.293 +bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
  63.294 +{
  63.295 +	return 0 != (pFlags & aiProcess_FlipWindingOrder);
  63.296 +}
  63.297 +
  63.298 +// ------------------------------------------------------------------------------------------------
  63.299 +// Executes the post processing step on the given imported data.
  63.300 +void FlipWindingOrderProcess::Execute( aiScene* pScene)
  63.301 +{
  63.302 +	DefaultLogger::get()->debug("FlipWindingOrderProcess begin");
  63.303 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
  63.304 +		ProcessMesh(pScene->mMeshes[i]);
  63.305 +	DefaultLogger::get()->debug("FlipWindingOrderProcess finished");
  63.306 +}
  63.307 +
  63.308 +// ------------------------------------------------------------------------------------------------
  63.309 +// Converts a single mesh 
  63.310 +void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
  63.311 +{
  63.312 +	// invert the order of all faces in this mesh
  63.313 +	for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
  63.314 +	{
  63.315 +		aiFace& face = pMesh->mFaces[a];
  63.316 +		for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
  63.317 +			std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
  63.318 +	}
  63.319 +}
  63.320 +
  63.321 +#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/libs/assimp/ConvertToLHProcess.h	Sat Feb 01 19:58:19 2014 +0200
    64.3 @@ -0,0 +1,166 @@
    64.4 +/*
    64.5 +Open Asset Import Library (assimp)
    64.6 +----------------------------------------------------------------------
    64.7 +
    64.8 +Copyright (c) 2006-2012, assimp team
    64.9 +All rights reserved.
   64.10 +
   64.11 +Redistribution and use of this software in source and binary forms, 
   64.12 +with or without modification, are permitted provided that the 
   64.13 +following conditions are met:
   64.14 +
   64.15 +* Redistributions of source code must retain the above
   64.16 +  copyright notice, this list of conditions and the
   64.17 +  following disclaimer.
   64.18 +
   64.19 +* Redistributions in binary form must reproduce the above
   64.20 +  copyright notice, this list of conditions and the
   64.21 +  following disclaimer in the documentation and/or other
   64.22 +  materials provided with the distribution.
   64.23 +
   64.24 +* Neither the name of the assimp team, nor the names of its
   64.25 +  contributors may be used to endorse or promote products
   64.26 +  derived from this software without specific prior
   64.27 +  written permission of the assimp team.
   64.28 +
   64.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   64.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   64.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   64.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   64.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   64.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   64.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   64.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   64.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   64.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   64.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   64.40 +
   64.41 +----------------------------------------------------------------------
   64.42 +*/
   64.43 +
   64.44 +/** @file  MakeLeftHandedProcess.h
   64.45 + *  @brief Defines a bunch of post-processing steps to handle
   64.46 + *    coordinate system conversions.
   64.47 + *
   64.48 + *  - LH to RH
   64.49 + *  - UV origin upper-left to lower-left
   64.50 + *  - face order cw to ccw 
   64.51 + */
   64.52 +#ifndef AI_CONVERTTOLHPROCESS_H_INC
   64.53 +#define AI_CONVERTTOLHPROCESS_H_INC
   64.54 +
   64.55 +#include "assimp/types.h"
   64.56 +#include "BaseProcess.h"
   64.57 +
   64.58 +struct aiMesh;
   64.59 +struct aiNodeAnim;
   64.60 +
   64.61 +namespace Assimp	{
   64.62 +
   64.63 +// -----------------------------------------------------------------------------------
   64.64 +/** @brief The MakeLeftHandedProcess converts all imported data to a left-handed
   64.65 + *   coordinate system. 
   64.66 + *
   64.67 + * This implies a mirroring of the Z axis of the coordinate system. But to keep 
   64.68 + * transformation matrices free from reflections we shift the reflection to other
   64.69 + * places. We mirror the meshes and adapt the rotations.
   64.70 + *
   64.71 + * @note RH-LH and LH-RH is the same, so this class can be used for both
   64.72 + */
   64.73 +class MakeLeftHandedProcess : public BaseProcess
   64.74 +{
   64.75 +	
   64.76 +
   64.77 +public:
   64.78 +	MakeLeftHandedProcess();
   64.79 +	~MakeLeftHandedProcess();
   64.80 +
   64.81 +	// -------------------------------------------------------------------
   64.82 +	bool IsActive( unsigned int pFlags) const;
   64.83 +
   64.84 +	// -------------------------------------------------------------------
   64.85 +	void Execute( aiScene* pScene);
   64.86 +
   64.87 +protected:
   64.88 +
   64.89 +	// -------------------------------------------------------------------
   64.90 +	/** Recursively converts a node and all of its children
   64.91 +	 */
   64.92 +	void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation);
   64.93 +
   64.94 +	// -------------------------------------------------------------------
   64.95 +	/** Converts a single mesh to left handed coordinates. 
   64.96 +	 * This means that positions, normals and tangents are mirrored at
   64.97 +	 * the local Z axis and the order of all faces are inverted.
   64.98 +	 * @param pMesh The mesh to convert.
   64.99 +	 */
  64.100 +	void ProcessMesh( aiMesh* pMesh);
  64.101 +
  64.102 +	// -------------------------------------------------------------------
  64.103 +	/** Converts a single material to left-handed coordinates
  64.104 +	 * @param pMat Material to convert
  64.105 +	 */
  64.106 +	void ProcessMaterial( aiMaterial* pMat);
  64.107 +
  64.108 +	// -------------------------------------------------------------------
  64.109 +	/** Converts the given animation to LH coordinates. 
  64.110 +	 * The rotation and translation keys are transformed, the scale keys
  64.111 +	 * work in local space and can therefore be left untouched.
  64.112 +	 * @param pAnim The bone animation to transform
  64.113 +	 */
  64.114 +	void ProcessAnimation( aiNodeAnim* pAnim);
  64.115 +};
  64.116 +
  64.117 +
  64.118 +// ---------------------------------------------------------------------------
  64.119 +/** Postprocessing step to flip the face order of the imported data
  64.120 + */
  64.121 +class FlipWindingOrderProcess : public BaseProcess
  64.122 +{
  64.123 +	friend class Importer;
  64.124 +
  64.125 +public:
  64.126 +	/** Constructor to be privately used by Importer */
  64.127 +	FlipWindingOrderProcess();
  64.128 +
  64.129 +	/** Destructor, private as well */
  64.130 +	~FlipWindingOrderProcess();
  64.131 +
  64.132 +	// -------------------------------------------------------------------
  64.133 +	bool IsActive( unsigned int pFlags) const;
  64.134 +
  64.135 +	// -------------------------------------------------------------------
  64.136 +	void Execute( aiScene* pScene);
  64.137 +
  64.138 +protected:
  64.139 +	void ProcessMesh( aiMesh* pMesh);
  64.140 +};
  64.141 +
  64.142 +// ---------------------------------------------------------------------------
  64.143 +/** Postprocessing step to flip the UV coordinate system of the import data
  64.144 + */
  64.145 +class FlipUVsProcess : public BaseProcess
  64.146 +{
  64.147 +	friend class Importer;
  64.148 +
  64.149 +public:
  64.150 +	/** Constructor to be privately used by Importer */
  64.151 +	FlipUVsProcess();
  64.152 +
  64.153 +	/** Destructor, private as well */
  64.154 +	~FlipUVsProcess();
  64.155 +
  64.156 +	// -------------------------------------------------------------------
  64.157 +	bool IsActive( unsigned int pFlags) const;
  64.158 +
  64.159 +	// -------------------------------------------------------------------
  64.160 +	void Execute( aiScene* pScene);
  64.161 +
  64.162 +protected:
  64.163 +	void ProcessMesh( aiMesh* pMesh);
  64.164 +	void ProcessMaterial( aiMaterial* mat);
  64.165 +};
  64.166 +
  64.167 +} // end of namespace Assimp
  64.168 +
  64.169 +#endif // AI_CONVERTTOLHPROCESS_H_INC
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/libs/assimp/ConvertUTF/ConvertUTF.c	Sat Feb 01 19:58:19 2014 +0200
    65.3 @@ -0,0 +1,539 @@
    65.4 +/*
    65.5 + * Copyright 2001-2004 Unicode, Inc.
    65.6 + * 
    65.7 + * Disclaimer
    65.8 + * 
    65.9 + * This source code is provided as is by Unicode, Inc. No claims are
   65.10 + * made as to fitness for any particular purpose. No warranties of any
   65.11 + * kind are expressed or implied. The recipient agrees to determine
   65.12 + * applicability of information provided. If this file has been
   65.13 + * purchased on magnetic or optical media from Unicode, Inc., the
   65.14 + * sole remedy for any claim will be exchange of defective media
   65.15 + * within 90 days of receipt.
   65.16 + * 
   65.17 + * Limitations on Rights to Redistribute This Code
   65.18 + * 
   65.19 + * Unicode, Inc. hereby grants the right to freely use the information
   65.20 + * supplied in this file in the creation of products supporting the
   65.21 + * Unicode Standard, and to make copies of this file in any form
   65.22 + * for internal or external distribution as long as this notice
   65.23 + * remains attached.
   65.24 + */
   65.25 +
   65.26 +/* ---------------------------------------------------------------------
   65.27 +
   65.28 +    Conversions between UTF32, UTF-16, and UTF-8. Source code file.
   65.29 +    Author: Mark E. Davis, 1994.
   65.30 +    Rev History: Rick McGowan, fixes & updates May 2001.
   65.31 +    Sept 2001: fixed const & error conditions per
   65.32 +	mods suggested by S. Parent & A. Lillich.
   65.33 +    June 2002: Tim Dodd added detection and handling of incomplete
   65.34 +	source sequences, enhanced error detection, added casts
   65.35 +	to eliminate compiler warnings.
   65.36 +    July 2003: slight mods to back out aggressive FFFE detection.
   65.37 +    Jan 2004: updated switches in from-UTF8 conversions.
   65.38 +    Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
   65.39 +
   65.40 +    See the header file "ConvertUTF.h" for complete documentation.
   65.41 +
   65.42 +------------------------------------------------------------------------ */
   65.43 +
   65.44 +
   65.45 +#include "ConvertUTF.h"
   65.46 +#ifdef CVTUTF_DEBUG
   65.47 +#include <stdio.h>
   65.48 +#endif
   65.49 +
   65.50 +static const int halfShift  = 10; /* used for shifting by 10 bits */
   65.51 +
   65.52 +static const UTF32 halfBase = 0x0010000UL;
   65.53 +static const UTF32 halfMask = 0x3FFUL;
   65.54 +
   65.55 +#define UNI_SUR_HIGH_START  (UTF32)0xD800
   65.56 +#define UNI_SUR_HIGH_END    (UTF32)0xDBFF
   65.57 +#define UNI_SUR_LOW_START   (UTF32)0xDC00
   65.58 +#define UNI_SUR_LOW_END     (UTF32)0xDFFF
   65.59 +#define false	   0
   65.60 +#define true	    1
   65.61 +
   65.62 +/* --------------------------------------------------------------------- */
   65.63 +
   65.64 +ConversionResult ConvertUTF32toUTF16 (
   65.65 +	const UTF32** sourceStart, const UTF32* sourceEnd, 
   65.66 +	UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
   65.67 +    ConversionResult result = conversionOK;
   65.68 +    const UTF32* source = *sourceStart;
   65.69 +    UTF16* target = *targetStart;
   65.70 +    while (source < sourceEnd) {
   65.71 +	UTF32 ch;
   65.72 +	if (target >= targetEnd) {
   65.73 +	    result = targetExhausted; break;
   65.74 +	}
   65.75 +	ch = *source++;
   65.76 +	if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
   65.77 +	    /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
   65.78 +	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
   65.79 +		if (flags == strictConversion) {
   65.80 +		    --source; /* return to the illegal value itself */
   65.81 +		    result = sourceIllegal;
   65.82 +		    break;
   65.83 +		} else {
   65.84 +		    *target++ = UNI_REPLACEMENT_CHAR;
   65.85 +		}
   65.86 +	    } else {
   65.87 +		*target++ = (UTF16)ch; /* normal case */
   65.88 +	    }
   65.89 +	} else if (ch > UNI_MAX_LEGAL_UTF32) {
   65.90 +	    if (flags == strictConversion) {
   65.91 +		result = sourceIllegal;
   65.92 +	    } else {
   65.93 +		*target++ = UNI_REPLACEMENT_CHAR;
   65.94 +	    }
   65.95 +	} else {
   65.96 +	    /* target is a character in range 0xFFFF - 0x10FFFF. */
   65.97 +	    if (target + 1 >= targetEnd) {
   65.98 +		--source; /* Back up source pointer! */
   65.99 +		result = targetExhausted; break;
  65.100 +	    }
  65.101 +	    ch -= halfBase;
  65.102 +	    *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
  65.103 +	    *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
  65.104 +	}
  65.105 +    }
  65.106 +    *sourceStart = source;
  65.107 +    *targetStart = target;
  65.108 +    return result;
  65.109 +}
  65.110 +
  65.111 +/* --------------------------------------------------------------------- */
  65.112 +
  65.113 +ConversionResult ConvertUTF16toUTF32 (
  65.114 +	const UTF16** sourceStart, const UTF16* sourceEnd, 
  65.115 +	UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
  65.116 +    ConversionResult result = conversionOK;
  65.117 +    const UTF16* source = *sourceStart;
  65.118 +    UTF32* target = *targetStart;
  65.119 +    UTF32 ch, ch2;
  65.120 +    while (source < sourceEnd) {
  65.121 +	const UTF16* oldSource = source; /*  In case we have to back up because of target overflow. */
  65.122 +	ch = *source++;
  65.123 +	/* If we have a surrogate pair, convert to UTF32 first. */
  65.124 +	if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
  65.125 +	    /* If the 16 bits following the high surrogate are in the source buffer... */
  65.126 +	    if (source < sourceEnd) {
  65.127 +		ch2 = *source;
  65.128 +		/* If it's a low surrogate, convert to UTF32. */
  65.129 +		if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
  65.130 +		    ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
  65.131 +			+ (ch2 - UNI_SUR_LOW_START) + halfBase;
  65.132 +		    ++source;
  65.133 +		} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
  65.134 +		    --source; /* return to the illegal value itself */
  65.135 +		    result = sourceIllegal;
  65.136 +		    break;
  65.137 +		}
  65.138 +	    } else { /* We don't have the 16 bits following the high surrogate. */
  65.139 +		--source; /* return to the high surrogate */
  65.140 +		result = sourceExhausted;
  65.141 +		break;
  65.142 +	    }
  65.143 +	} else if (flags == strictConversion) {
  65.144 +	    /* UTF-16 surrogate values are illegal in UTF-32 */
  65.145 +	    if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
  65.146 +		--source; /* return to the illegal value itself */
  65.147 +		result = sourceIllegal;
  65.148 +		break;
  65.149 +	    }
  65.150 +	}
  65.151 +	if (target >= targetEnd) {
  65.152 +	    source = oldSource; /* Back up source pointer! */
  65.153 +	    result = targetExhausted; break;
  65.154 +	}
  65.155 +	*target++ = ch;
  65.156 +    }
  65.157 +    *sourceStart = source;
  65.158 +    *targetStart = target;
  65.159 +#ifdef CVTUTF_DEBUG
  65.160 +if (result == sourceIllegal) {
  65.161 +    fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
  65.162 +    fflush(stderr);
  65.163 +}
  65.164 +#endif
  65.165 +    return result;
  65.166 +}
  65.167 +
  65.168 +/* --------------------------------------------------------------------- */
  65.169 +
  65.170 +/*
  65.171 + * Index into the table below with the first byte of a UTF-8 sequence to
  65.172 + * get the number of trailing bytes that are supposed to follow it.
  65.173 + * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
  65.174 + * left as-is for anyone who may want to do such conversion, which was
  65.175 + * allowed in earlier algorithms.
  65.176 + */
  65.177 +static const char trailingBytesForUTF8[256] = {
  65.178 +    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  65.179 +    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  65.180 +    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  65.181 +    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  65.182 +    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  65.183 +    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  65.184 +    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  65.185 +    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
  65.186 +};
  65.187 +
  65.188 +/*
  65.189 + * Magic values subtracted from a buffer value during UTF8 conversion.
  65.190 + * This table contains as many values as there might be trailing bytes
  65.191 + * in a UTF-8 sequence.
  65.192 + */
  65.193 +static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 
  65.194 +		     0x03C82080UL, 0xFA082080UL, 0x82082080UL };
  65.195 +
  65.196 +/*
  65.197 + * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
  65.198 + * into the first byte, depending on how many bytes follow.  There are
  65.199 + * as many entries in this table as there are UTF-8 sequence types.
  65.200 + * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
  65.201 + * for *legal* UTF-8 will be 4 or fewer bytes total.
  65.202 + */
  65.203 +static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
  65.204 +
  65.205 +/* --------------------------------------------------------------------- */
  65.206 +
  65.207 +/* The interface converts a whole buffer to avoid function-call overhead.
  65.208 + * Constants have been gathered. Loops & conditionals have been removed as
  65.209 + * much as possible for efficiency, in favor of drop-through switches.
  65.210 + * (See "Note A" at the bottom of the file for equivalent code.)
  65.211 + * If your compiler supports it, the "isLegalUTF8" call can be turned
  65.212 + * into an inline function.
  65.213 + */
  65.214 +
  65.215 +/* --------------------------------------------------------------------- */
  65.216 +
  65.217 +ConversionResult ConvertUTF16toUTF8 (
  65.218 +	const UTF16** sourceStart, const UTF16* sourceEnd, 
  65.219 +	UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
  65.220 +    ConversionResult result = conversionOK;
  65.221 +    const UTF16* source = *sourceStart;
  65.222 +    UTF8* target = *targetStart;
  65.223 +    while (source < sourceEnd) {
  65.224 +	UTF32 ch;
  65.225 +	unsigned short bytesToWrite = 0;
  65.226 +	const UTF32 byteMask = 0xBF;
  65.227 +	const UTF32 byteMark = 0x80; 
  65.228 +	const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
  65.229 +	ch = *source++;
  65.230 +	/* If we have a surrogate pair, convert to UTF32 first. */
  65.231 +	if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
  65.232 +	    /* If the 16 bits following the high surrogate are in the source buffer... */
  65.233 +	    if (source < sourceEnd) {
  65.234 +		UTF32 ch2 = *source;
  65.235 +		/* If it's a low surrogate, convert to UTF32. */
  65.236 +		if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
  65.237 +		    ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
  65.238 +			+ (ch2 - UNI_SUR_LOW_START) + halfBase;
  65.239 +		    ++source;
  65.240 +		} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
  65.241 +		    --source; /* return to the illegal value itself */
  65.242 +		    result = sourceIllegal;
  65.243 +		    break;
  65.244 +		}
  65.245 +	    } else { /* We don't have the 16 bits following the high surrogate. */
  65.246 +		--source; /* return to the high surrogate */
  65.247 +		result = sourceExhausted;
  65.248 +		break;
  65.249 +	    }
  65.250 +	} else if (flags == strictConversion) {
  65.251 +	    /* UTF-16 surrogate values are illegal in UTF-32 */
  65.252 +	    if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
  65.253 +		--source; /* return to the illegal value itself */
  65.254 +		result = sourceIllegal;
  65.255 +		break;
  65.256 +	    }
  65.257 +	}
  65.258 +	/* Figure out how many bytes the result will require */
  65.259 +	if (ch < (UTF32)0x80) {	     bytesToWrite = 1;
  65.260 +	} else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
  65.261 +	} else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
  65.262 +	} else if (ch < (UTF32)0x110000) {  bytesToWrite = 4;
  65.263 +	} else {			    bytesToWrite = 3;
  65.264 +					    ch = UNI_REPLACEMENT_CHAR;
  65.265 +	}
  65.266 +
  65.267 +	target += bytesToWrite;
  65.268 +	if (target > targetEnd) {
  65.269 +	    source = oldSource; /* Back up source pointer! */
  65.270 +	    target -= bytesToWrite; result = targetExhausted; break;
  65.271 +	}
  65.272 +	switch (bytesToWrite) { /* note: everything falls through. */
  65.273 +	    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
  65.274 +	    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
  65.275 +	    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
  65.276 +	    case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
  65.277 +	}
  65.278 +	target += bytesToWrite;
  65.279 +    }
  65.280 +    *sourceStart = source;
  65.281 +    *targetStart = target;
  65.282 +    return result;
  65.283 +}
  65.284 +
  65.285 +/* --------------------------------------------------------------------- */
  65.286 +
  65.287 +/*
  65.288 + * Utility routine to tell whether a sequence of bytes is legal UTF-8.
  65.289 + * This must be called with the length pre-determined by the first byte.
  65.290 + * If not calling this from ConvertUTF8to*, then the length can be set by:
  65.291 + *  length = trailingBytesForUTF8[*source]+1;
  65.292 + * and the sequence is illegal right away if there aren't that many bytes
  65.293 + * available.
  65.294 + * If presented with a length > 4, this returns false.  The Unicode
  65.295 + * definition of UTF-8 goes up to 4-byte sequences.
  65.296 + */
  65.297 +
  65.298 +static Boolean isLegalUTF8(const UTF8 *source, int length) {
  65.299 +    UTF8 a;
  65.300 +    const UTF8 *srcptr = source+length;
  65.301 +    switch (length) {
  65.302 +    default: return false;
  65.303 +	/* Everything else falls through when "true"... */
  65.304 +    case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
  65.305 +    case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
  65.306 +    case 2: if ((a = (*--srcptr)) > 0xBF) return false;
  65.307 +
  65.308 +	switch (*source) {
  65.309 +	    /* no fall-through in this inner switch */
  65.310 +	    case 0xE0: if (a < 0xA0) return false; break;
  65.311 +	    case 0xED: if (a > 0x9F) return false; break;
  65.312 +	    case 0xF0: if (a < 0x90) return false; break;
  65.313 +	    case 0xF4: if (a > 0x8F) return false; break;
  65.314 +	    default:   if (a < 0x80) return false;
  65.315 +	}
  65.316 +
  65.317 +    case 1: if (*source >= 0x80 && *source < 0xC2) return false;
  65.318 +    }
  65.319 +    if (*source > 0xF4) return false;
  65.320 +    return true;
  65.321 +}
  65.322 +
  65.323 +/* --------------------------------------------------------------------- */
  65.324 +
  65.325 +/*
  65.326 + * Exported function to return whether a UTF-8 sequence is legal or not.
  65.327 + * This is not used here; it's just exported.
  65.328 + */
  65.329 +Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
  65.330 +    int length = trailingBytesForUTF8[*source]+1;
  65.331 +    if (source+length > sourceEnd) {
  65.332 +	return false;
  65.333 +    }
  65.334 +    return isLegalUTF8(source, length);
  65.335 +}
  65.336 +
  65.337 +/* --------------------------------------------------------------------- */
  65.338 +
  65.339 +ConversionResult ConvertUTF8toUTF16 (
  65.340 +	const UTF8** sourceStart, const UTF8* sourceEnd, 
  65.341 +	UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
  65.342 +    ConversionResult result = conversionOK;
  65.343 +    const UTF8* source = *sourceStart;
  65.344 +    UTF16* target = *targetStart;
  65.345 +    while (source < sourceEnd) {
  65.346 +	UTF32 ch = 0;
  65.347 +	unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
  65.348 +	if (source + extraBytesToRead >= sourceEnd) {
  65.349 +	    result = sourceExhausted; break;
  65.350 +	}
  65.351 +	/* Do this check whether lenient or strict */
  65.352 +	if (! isLegalUTF8(source, extraBytesToRead+1)) {
  65.353 +	    result = sourceIllegal;
  65.354 +	    break;
  65.355 +	}
  65.356 +	/*
  65.357 +	 * The cases all fall through. See "Note A" below.
  65.358 +	 */
  65.359 +	switch (extraBytesToRead) {
  65.360 +	    case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
  65.361 +	    case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
  65.362 +	    case 3: ch += *source++; ch <<= 6;
  65.363 +	    case 2: ch += *source++; ch <<= 6;
  65.364 +	    case 1: ch += *source++; ch <<= 6;
  65.365 +	    case 0: ch += *source++;
  65.366 +	}
  65.367 +	ch -= offsetsFromUTF8[extraBytesToRead];
  65.368 +
  65.369 +	if (target >= targetEnd) {
  65.370 +	    source -= (extraBytesToRead+1); /* Back up source pointer! */
  65.371 +	    result = targetExhausted; break;
  65.372 +	}
  65.373 +	if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
  65.374 +	    /* UTF-16 surrogate values are illegal in UTF-32 */
  65.375 +	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
  65.376 +		if (flags == strictConversion) {
  65.377 +		    source -= (extraBytesToRead+1); /* return to the illegal value itself */
  65.378 +		    result = sourceIllegal;
  65.379 +		    break;
  65.380 +		} else {
  65.381 +		    *target++ = UNI_REPLACEMENT_CHAR;
  65.382 +		}
  65.383 +	    } else {
  65.384 +		*target++ = (UTF16)ch; /* normal case */
  65.385 +	    }
  65.386 +	} else if (ch > UNI_MAX_UTF16) {
  65.387 +	    if (flags == strictConversion) {
  65.388 +		result = sourceIllegal;
  65.389 +		source -= (extraBytesToRead+1); /* return to the start */
  65.390 +		break; /* Bail out; shouldn't continue */
  65.391 +	    } else {
  65.392 +		*target++ = UNI_REPLACEMENT_CHAR;
  65.393 +	    }
  65.394 +	} else {
  65.395 +	    /* target is a character in range 0xFFFF - 0x10FFFF. */
  65.396 +	    if (target + 1 >= targetEnd) {
  65.397 +		source -= (extraBytesToRead+1); /* Back up source pointer! */
  65.398 +		result = targetExhausted; break;
  65.399 +	    }
  65.400 +	    ch -= halfBase;
  65.401 +	    *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
  65.402 +	    *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
  65.403 +	}
  65.404 +    }
  65.405 +    *sourceStart = source;
  65.406 +    *targetStart = target;
  65.407 +    return result;
  65.408 +}
  65.409 +
  65.410 +/* --------------------------------------------------------------------- */
  65.411 +
  65.412 +ConversionResult ConvertUTF32toUTF8 (
  65.413 +	const UTF32** sourceStart, const UTF32* sourceEnd, 
  65.414 +	UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
  65.415 +    ConversionResult result = conversionOK;
  65.416 +    const UTF32* source = *sourceStart;
  65.417 +    UTF8* target = *targetStart;
  65.418 +    while (source < sourceEnd) {
  65.419 +	UTF32 ch;
  65.420 +	unsigned short bytesToWrite = 0;
  65.421 +	const UTF32 byteMask = 0xBF;
  65.422 +	const UTF32 byteMark = 0x80; 
  65.423 +	ch = *source++;
  65.424 +	if (flags == strictConversion ) {
  65.425 +	    /* UTF-16 surrogate values are illegal in UTF-32 */
  65.426 +	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
  65.427 +		--source; /* return to the illegal value itself */
  65.428 +		result = sourceIllegal;
  65.429 +		break;
  65.430 +	    }
  65.431 +	}
  65.432 +	/*
  65.433 +	 * Figure out how many bytes the result will require. Turn any
  65.434 +	 * illegally large UTF32 things (> Plane 17) into replacement chars.
  65.435 +	 */
  65.436 +	if (ch < (UTF32)0x80) {	     bytesToWrite = 1;
  65.437 +	} else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
  65.438 +	} else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
  65.439 +	} else if (ch <= UNI_MAX_LEGAL_UTF32) {  bytesToWrite = 4;
  65.440 +	} else {			    bytesToWrite = 3;
  65.441 +					    ch = UNI_REPLACEMENT_CHAR;
  65.442 +					    result = sourceIllegal;
  65.443 +	}
  65.444 +	
  65.445 +	target += bytesToWrite;
  65.446 +	if (target > targetEnd) {
  65.447 +	    --source; /* Back up source pointer! */
  65.448 +	    target -= bytesToWrite; result = targetExhausted; break;
  65.449 +	}
  65.450 +	switch (bytesToWrite) { /* note: everything falls through. */
  65.451 +	    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
  65.452 +	    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
  65.453 +	    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
  65.454 +	    case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
  65.455 +	}
  65.456 +	target += bytesToWrite;
  65.457 +    }
  65.458 +    *sourceStart = source;
  65.459 +    *targetStart = target;
  65.460 +    return result;
  65.461 +}
  65.462 +
  65.463 +/* --------------------------------------------------------------------- */
  65.464 +
  65.465 +ConversionResult ConvertUTF8toUTF32 (
  65.466 +	const UTF8** sourceStart, const UTF8* sourceEnd, 
  65.467 +	UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
  65.468 +    ConversionResult result = conversionOK;
  65.469 +    const UTF8* source = *sourceStart;
  65.470 +    UTF32* target = *targetStart;
  65.471 +    while (source < sourceEnd) {
  65.472 +	UTF32 ch = 0;
  65.473 +	unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
  65.474 +	if (source + extraBytesToRead >= sourceEnd) {
  65.475 +	    result = sourceExhausted; break;
  65.476 +	}
  65.477 +	/* Do this check whether lenient or strict */
  65.478 +	if (! isLegalUTF8(source, extraBytesToRead+1)) {
  65.479 +	    result = sourceIllegal;
  65.480 +	    break;
  65.481 +	}
  65.482 +	/*
  65.483 +	 * The cases all fall through. See "Note A" below.
  65.484 +	 */
  65.485 +	switch (extraBytesToRead) {
  65.486 +	    case 5: ch += *source++; ch <<= 6;
  65.487 +	    case 4: ch += *source++; ch <<= 6;
  65.488 +	    case 3: ch += *source++; ch <<= 6;
  65.489 +	    case 2: ch += *source++; ch <<= 6;
  65.490 +	    case 1: ch += *source++; ch <<= 6;
  65.491 +	    case 0: ch += *source++;
  65.492 +	}
  65.493 +	ch -= offsetsFromUTF8[extraBytesToRead];
  65.494 +
  65.495 +	if (target >= targetEnd) {
  65.496 +	    source -= (extraBytesToRead+1); /* Back up the source pointer! */
  65.497 +	    result = targetExhausted; break;
  65.498 +	}
  65.499 +	if (ch <= UNI_MAX_LEGAL_UTF32) {
  65.500 +	    /*
  65.501 +	     * UTF-16 surrogate values are illegal in UTF-32, and anything
  65.502 +	     * over Plane 17 (> 0x10FFFF) is illegal.
  65.503 +	     */
  65.504 +	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
  65.505 +		if (flags == strictConversion) {
  65.506 +		    source -= (extraBytesToRead+1); /* return to the illegal value itself */
  65.507 +		    result = sourceIllegal;
  65.508 +		    break;
  65.509 +		} else {
  65.510 +		    *target++ = UNI_REPLACEMENT_CHAR;
  65.511 +		}
  65.512 +	    } else {
  65.513 +		*target++ = ch;
  65.514 +	    }
  65.515 +	} else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
  65.516 +	    result = sourceIllegal;
  65.517 +	    *target++ = UNI_REPLACEMENT_CHAR;
  65.518 +	}
  65.519 +    }
  65.520 +    *sourceStart = source;
  65.521 +    *targetStart = target;
  65.522 +    return result;
  65.523 +}
  65.524 +
  65.525 +/* ---------------------------------------------------------------------
  65.526 +
  65.527 +    Note A.
  65.528 +    The fall-through switches in UTF-8 reading code save a
  65.529 +    temp variable, some decrements & conditionals.  The switches
  65.530 +    are equivalent to the following loop:
  65.531 +	{
  65.532 +	    int tmpBytesToRead = extraBytesToRead+1;
  65.533 +	    do {
  65.534 +		ch += *source++;
  65.535 +		--tmpBytesToRead;
  65.536 +		if (tmpBytesToRead) ch <<= 6;
  65.537 +	    } while (tmpBytesToRead > 0);
  65.538 +	}
  65.539 +    In UTF-8 writing code, the switches on "bytesToWrite" are
  65.540 +    similarly unrolled loops.
  65.541 +
  65.542 +   --------------------------------------------------------------------- */
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/libs/assimp/ConvertUTF/ConvertUTF.h	Sat Feb 01 19:58:19 2014 +0200
    66.3 @@ -0,0 +1,151 @@
    66.4 +/*
    66.5 + * Copyright 2001-2004 Unicode, Inc.
    66.6 + * 
    66.7 + * Disclaimer
    66.8 + * 
    66.9 + * This source code is provided as is by Unicode, Inc. No claims are
   66.10 + * made as to fitness for any particular purpose. No warranties of any
   66.11 + * kind are expressed or implied. The recipient agrees to determine
   66.12 + * applicability of information provided. If this file has been
   66.13 + * purchased on magnetic or optical media from Unicode, Inc., the
   66.14 + * sole remedy for any claim will be exchange of defective media
   66.15 + * within 90 days of receipt.
   66.16 + * 
   66.17 + * Limitations on Rights to Redistribute This Code
   66.18 + * 
   66.19 + * Unicode, Inc. hereby grants the right to freely use the information
   66.20 + * supplied in this file in the creation of products supporting the
   66.21 + * Unicode Standard, and to make copies of this file in any form
   66.22 + * for internal or external distribution as long as this notice
   66.23 + * remains attached.
   66.24 + */
   66.25 +#ifndef CONVERTUTF_H
   66.26 +#define CONVERTUTF_H
   66.27 +/* ---------------------------------------------------------------------
   66.28 +
   66.29 +    Conversions between UTF32, UTF-16, and UTF-8.  Header file.
   66.30 +
   66.31 +    Several funtions are included here, forming a complete set of
   66.32 +    conversions between the three formats.  UTF-7 is not included
   66.33 +    here, but is handled in a separate source file.
   66.34 +
   66.35 +    Each of these routines takes pointers to input buffers and output
   66.36 +    buffers.  The input buffers are const.
   66.37 +
   66.38 +    Each routine converts the text between *sourceStart and sourceEnd,
   66.39 +    putting the result into the buffer between *targetStart and
   66.40 +    targetEnd. Note: the end pointers are *after* the last item: e.g. 
   66.41 +    *(sourceEnd - 1) is the last item.
   66.42 +
   66.43 +    The return result indicates whether the conversion was successful,
   66.44 +    and if not, whether the problem was in the source or target buffers.
   66.45 +    (Only the first encountered problem is indicated.)
   66.46 +
   66.47 +    After the conversion, *sourceStart and *targetStart are both
   66.48 +    updated to point to the end of last text successfully converted in
   66.49 +    the respective buffers.
   66.50 +
   66.51 +    Input parameters:
   66.52 +	sourceStart - pointer to a pointer to the source buffer.
   66.53 +		The contents of this are modified on return so that
   66.54 +		it points at the next thing to be converted.
   66.55 +	targetStart - similarly, pointer to pointer to the target buffer.
   66.56 +	sourceEnd, targetEnd - respectively pointers to the ends of the
   66.57 +		two buffers, for overflow checking only.
   66.58 +
   66.59 +    These conversion functions take a ConversionFlags argument. When this
   66.60 +    flag is set to strict, both irregular sequences and isolated surrogates
   66.61 +    will cause an error.  When the flag is set to lenient, both irregular
   66.62 +    sequences and isolated surrogates are converted.
   66.63 +
   66.64 +    Whether the flag is strict or lenient, all illegal sequences will cause
   66.65 +    an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
   66.66 +    or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
   66.67 +    must check for illegal sequences.
   66.68 +
   66.69 +    When the flag is set to lenient, characters over 0x10FFFF are converted
   66.70 +    to the replacement character; otherwise (when the flag is set to strict)
   66.71 +    they constitute an error.
   66.72 +
   66.73 +    Output parameters:
   66.74 +	The value "sourceIllegal" is returned from some routines if the input
   66.75 +	sequence is malformed.  When "sourceIllegal" is returned, the source
   66.76 +	value will point to the illegal value that caused the problem. E.g.,
   66.77 +	in UTF-8 when a sequence is malformed, it points to the start of the
   66.78 +	malformed sequence.  
   66.79 +
   66.80 +    Author: Mark E. Davis, 1994.
   66.81 +    Rev History: Rick McGowan, fixes & updates May 2001.
   66.82 +		 Fixes & updates, Sept 2001.
   66.83 +
   66.84 +------------------------------------------------------------------------ */
   66.85 +
   66.86 +/* ---------------------------------------------------------------------
   66.87 +    The following 4 definitions are compiler-specific.
   66.88 +    The C standard does not guarantee that wchar_t has at least
   66.89 +    16 bits, so wchar_t is no less portable than unsigned short!
   66.90 +    All should be unsigned values to avoid sign extension during
   66.91 +    bit mask & shift operations.
   66.92 +------------------------------------------------------------------------ */
   66.93 +
   66.94 +typedef unsigned long	UTF32;	/* at least 32 bits */
   66.95 +typedef unsigned short	UTF16;	/* at least 16 bits */
   66.96 +typedef unsigned char	UTF8;	/* typically 8 bits */
   66.97 +typedef unsigned char	Boolean; /* 0 or 1 */
   66.98 +
   66.99 +/* Some fundamental constants */
  66.100 +#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
  66.101 +#define UNI_MAX_BMP (UTF32)0x0000FFFF
  66.102 +#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
  66.103 +#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
  66.104 +#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
  66.105 +
  66.106 +typedef enum {
  66.107 +	conversionOK, 		/* conversion successful */
  66.108 +	sourceExhausted,	/* partial character in source, but hit end */
  66.109 +	targetExhausted,	/* insuff. room in target for conversion */
  66.110 +	sourceIllegal		/* source sequence is illegal/malformed */
  66.111 +} ConversionResult;
  66.112 +
  66.113 +typedef enum {
  66.114 +	strictConversion = 0,
  66.115 +	lenientConversion
  66.116 +} ConversionFlags;
  66.117 +
  66.118 +/* This is for C++ and does no harm in C */
  66.119 +#ifdef __cplusplus
  66.120 +extern "C" {
  66.121 +#endif
  66.122 +
  66.123 +ConversionResult ConvertUTF8toUTF16 (
  66.124 +		const UTF8** sourceStart, const UTF8* sourceEnd, 
  66.125 +		UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
  66.126 +
  66.127 +ConversionResult ConvertUTF16toUTF8 (
  66.128 +		const UTF16** sourceStart, const UTF16* sourceEnd, 
  66.129 +		UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
  66.130 +		
  66.131 +ConversionResult ConvertUTF8toUTF32 (
  66.132 +		const UTF8** sourceStart, const UTF8* sourceEnd, 
  66.133 +		UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
  66.134 +
  66.135 +ConversionResult ConvertUTF32toUTF8 (
  66.136 +		const UTF32** sourceStart, const UTF32* sourceEnd, 
  66.137 +		UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
  66.138 +		
  66.139 +ConversionResult ConvertUTF16toUTF32 (
  66.140 +		const UTF16** sourceStart, const UTF16* sourceEnd, 
  66.141 +		UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
  66.142 +
  66.143 +ConversionResult ConvertUTF32toUTF16 (
  66.144 +		const UTF32** sourceStart, const UTF32* sourceEnd, 
  66.145 +		UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
  66.146 +
  66.147 +Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
  66.148 +
  66.149 +#ifdef __cplusplus
  66.150 +}
  66.151 +#endif
  66.152 +
  66.153 +/* --------------------------------------------------------------------- */
  66.154 +#endif  // CONVERTUTF_H
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/libs/assimp/DXFHelper.h	Sat Feb 01 19:58:19 2014 +0200
    67.3 @@ -0,0 +1,230 @@
    67.4 +/*
    67.5 +Open Asset Import Library (assimp)
    67.6 +----------------------------------------------------------------------
    67.7 +
    67.8 +Copyright (c) 2006-2012, assimp team
    67.9 +All rights reserved.
   67.10 +
   67.11 +Redistribution and use of this software in source and binary forms, 
   67.12 +with or without modification, are permitted provided that the 
   67.13 +following conditions are met:
   67.14 +
   67.15 +* Redistributions of source code must retain the above
   67.16 +  copyright notice, this list of conditions and the
   67.17 +  following disclaimer.
   67.18 +
   67.19 +* Redistributions in binary form must reproduce the above
   67.20 +  copyright notice, this list of conditions and the
   67.21 +  following disclaimer in the documentation and/or other
   67.22 +  materials provided with the distribution.
   67.23 +
   67.24 +* Neither the name of the assimp team, nor the names of its
   67.25 +  contributors may be used to endorse or promote products
   67.26 +  derived from this software without specific prior
   67.27 +  written permission of the assimp team.
   67.28 +
   67.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   67.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   67.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   67.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   67.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   67.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   67.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   67.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   67.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   67.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   67.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   67.40 +
   67.41 +----------------------------------------------------------------------
   67.42 +*/
   67.43 +
   67.44 +/** @file  DXFHelper.h 
   67.45 + *  @brief Internal utilities for the DXF loader.
   67.46 + */
   67.47 +
   67.48 +#ifndef INCLUDED_DXFHELPER_H
   67.49 +#define INCLUDED_DXFHELPER_H
   67.50 +
   67.51 +#include "LineSplitter.h"
   67.52 +#include "TinyFormatter.h"
   67.53 +#include "StreamReader.h"
   67.54 +
   67.55 +namespace Assimp {
   67.56 +	namespace DXF {
   67.57 +
   67.58 +
   67.59 +// read pairs of lines, parse group code and value and provide utilities
   67.60 +// to convert the data to the target data type.
   67.61 +class LineReader
   67.62 +{
   67.63 +
   67.64 +public:
   67.65 +
   67.66 +	LineReader(StreamReaderLE& reader)
   67.67 +		 // do NOT skip empty lines. In DXF files, they count as valid data.
   67.68 +		: splitter(reader,false,true)
   67.69 +		, end()
   67.70 +	{
   67.71 +	}
   67.72 +
   67.73 +public:
   67.74 +
   67.75 +
   67.76 +	// -----------------------------------------
   67.77 +	bool Is(int gc, const char* what) const {
   67.78 +		return groupcode == gc && !strcmp(what,value.c_str());
   67.79 +	}
   67.80 +
   67.81 +	// -----------------------------------------
   67.82 +	bool Is(int gc) const {
   67.83 +		return groupcode == gc;
   67.84 +	}
   67.85 +
   67.86 +	// -----------------------------------------
   67.87 +	int GroupCode() const {
   67.88 +		return groupcode;
   67.89 +	}
   67.90 +
   67.91 +	// -----------------------------------------
   67.92 +	const std::string& Value() const {
   67.93 +		return value;
   67.94 +	}
   67.95 +
   67.96 +	// -----------------------------------------
   67.97 +	bool End() const {
   67.98 +		return !((bool)*this);
   67.99 +	}
  67.100 +
  67.101 +public:
  67.102 +
  67.103 +	// -----------------------------------------
  67.104 +	unsigned int ValueAsUnsignedInt() const {
  67.105 +		return strtoul10(value.c_str());
  67.106 +	}
  67.107 +
  67.108 +	// -----------------------------------------
  67.109 +	int ValueAsSignedInt() const {
  67.110 +		return strtol10(value.c_str());
  67.111 +	}
  67.112 +
  67.113 +	// -----------------------------------------
  67.114 +	float ValueAsFloat() const {
  67.115 +		return fast_atof(value.c_str());
  67.116 +	}
  67.117 +
  67.118 +public:
  67.119 +
  67.120 +	// -----------------------------------------
  67.121 +	/** pseudo-iterator increment to advance to the next (groupcode/value) pair */
  67.122 +	LineReader& operator++() {
  67.123 +		if (end) {
  67.124 +			if (end == 1) {
  67.125 +				++end;
  67.126 +			}
  67.127 +			return *this;
  67.128 +		}
  67.129 +
  67.130 +		try {
  67.131 +			groupcode = strtol10(splitter->c_str());
  67.132 +			splitter++;
  67.133 +
  67.134 +			value = *splitter;
  67.135 +			splitter++;
  67.136 +
  67.137 +			// automatically skip over {} meta blocks (these are for application use
  67.138 +			// and currently not relevant for Assimp).
  67.139 +			if (value.length() && value[0] == '{') {
  67.140 +
  67.141 +				size_t cnt = 0;
  67.142 +				for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++);
  67.143 +
  67.144 +				splitter++;
  67.145 +				DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
  67.146 +			}
  67.147 +		} catch(std::logic_error&) {
  67.148 +			ai_assert(!splitter);
  67.149 +		}
  67.150 +		if (!splitter) {
  67.151 +			end = 1;
  67.152 +		}
  67.153 +		return *this;
  67.154 +	}
  67.155 +
  67.156 +	// -----------------------------------------
  67.157 +	LineReader& operator++(int) {
  67.158 +		return ++(*this);
  67.159 +	}
  67.160 +
  67.161 +
  67.162 +	// -----------------------------------------
  67.163 +	operator bool() const {
  67.164 +		return end <= 1;
  67.165 +	}
  67.166 +
  67.167 +private:
  67.168 +
  67.169 +	LineSplitter splitter;
  67.170 +	int groupcode;
  67.171 +	std::string value;
  67.172 +	int end;
  67.173 +};
  67.174 +
  67.175 +
  67.176 +
  67.177 +// represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed.
  67.178 +struct PolyLine
  67.179 +{
  67.180 +	PolyLine()
  67.181 +		: flags()
  67.182 +	{}
  67.183 +	
  67.184 +	std::vector<aiVector3D> positions;
  67.185 +	std::vector<aiColor4D>  colors;
  67.186 +	std::vector<unsigned int> indices;
  67.187 +	std::vector<unsigned int> counts;
  67.188 +	unsigned int flags;
  67.189 +
  67.190 +	std::string layer;
  67.191 +	std::string desc;
  67.192 +};
  67.193 +
  67.194 +
  67.195 +// reference to a BLOCK. Specifies its own coordinate system.
  67.196 +struct InsertBlock
  67.197 +{
  67.198 +	InsertBlock()
  67.199 +		: scale(1.f,1.f,1.f)
  67.200 +		, angle()
  67.201 +	{}
  67.202 +
  67.203 +	aiVector3D pos;
  67.204 +	aiVector3D scale;
  67.205 +	float angle;
  67.206 +
  67.207 +	std::string name;
  67.208 +};
  67.209 +
  67.210 +
  67.211 +// keeps track of all geometry in a single BLOCK.
  67.212 +struct Block
  67.213 +{
  67.214 +	std::vector< boost::shared_ptr<PolyLine> > lines;
  67.215 +	std::vector<InsertBlock> insertions;
  67.216 +
  67.217 +	std::string name;
  67.218 +	aiVector3D base;
  67.219 +};
  67.220 +
  67.221 +
  67.222 +struct FileData
  67.223 +{
  67.224 +	// note: the LAST block always contains the stuff from ENTITIES.
  67.225 +	std::vector<Block> blocks;
  67.226 +};
  67.227 +
  67.228 +
  67.229 +
  67.230 +
  67.231 +
  67.232 +}}
  67.233 +#endif
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/libs/assimp/DXFLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
    68.3 @@ -0,0 +1,913 @@
    68.4 +/*
    68.5 +---------------------------------------------------------------------------
    68.6 +Open Asset Import Library (assimp)
    68.7 +---------------------------------------------------------------------------
    68.8 +
    68.9 +Copyright (c) 2006-2012, assimp team
   68.10 +
   68.11 +All rights reserved.
   68.12 +
   68.13 +Redistribution and use of this software in source and binary forms, 
   68.14 +with or without modification, are permitted provided that the following 
   68.15 +conditions are met:
   68.16 +
   68.17 +* Redistributions of source code must retain the above
   68.18 +  copyright notice, this list of conditions and the
   68.19 +  following disclaimer.
   68.20 +
   68.21 +* Redistributions in binary form must reproduce the above
   68.22 +  copyright notice, this list of conditions and the
   68.23 +  following disclaimer in the documentation and/or other
   68.24 +  materials provided with the distribution.
   68.25 +
   68.26 +* Neither the name of the assimp team, nor the names of its
   68.27 +  contributors may be used to endorse or promote products
   68.28 +  derived from this software without specific prior
   68.29 +  written permission of the assimp team.
   68.30 +
   68.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   68.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   68.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   68.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   68.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   68.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   68.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   68.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   68.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   68.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   68.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   68.42 +---------------------------------------------------------------------------
   68.43 +*/
   68.44 +
   68.45 +/** @file  DXFLoader.cpp
   68.46 + *  @brief Implementation of the DXF importer class
   68.47 + */
   68.48 +
   68.49 +#include "AssimpPCH.h"
   68.50 +#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
   68.51 +
   68.52 +#include "DXFLoader.h"
   68.53 +#include "ParsingUtils.h"
   68.54 +#include "ConvertToLHProcess.h"
   68.55 +#include "fast_atof.h"
   68.56 +
   68.57 +#include "DXFHelper.h"
   68.58 +
   68.59 +using namespace Assimp;
   68.60 +
   68.61 +// AutoCAD Binary DXF<CR><LF><SUB><NULL> 
   68.62 +#define AI_DXF_BINARY_IDENT ("AutoCAD Binary DXF\r\n\x1a\0")
   68.63 +#define AI_DXF_BINARY_IDENT_LEN (24)
   68.64 +
   68.65 +// default vertex color that all uncolored vertices will receive
   68.66 +#define AI_DXF_DEFAULT_COLOR aiColor4D(0.6f,0.6f,0.6f,0.6f)
   68.67 +
   68.68 +// color indices for DXF - 16 are supported, the table is 
   68.69 +// taken directly from the DXF spec.
   68.70 +static aiColor4D g_aclrDxfIndexColors[] =
   68.71 +{
   68.72 +	aiColor4D (0.6f, 0.6f, 0.6f, 1.0f),
   68.73 +	aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
   68.74 +	aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
   68.75 +	aiColor4D (0.0f, 0.0f, 1.0f, 1.0f), // blue
   68.76 +	aiColor4D (0.3f, 1.0f, 0.3f, 1.0f), // light green
   68.77 +	aiColor4D (0.3f, 0.3f, 1.0f, 1.0f), // light blue
   68.78 +	aiColor4D (1.0f, 0.3f, 0.3f, 1.0f), // light red
   68.79 +	aiColor4D (1.0f, 0.0f, 1.0f, 1.0f), // pink
   68.80 +	aiColor4D (1.0f, 0.6f, 0.0f, 1.0f), // orange
   68.81 +	aiColor4D (0.6f, 0.3f, 0.0f, 1.0f), // dark orange
   68.82 +	aiColor4D (1.0f, 1.0f, 0.0f, 1.0f), // yellow
   68.83 +	aiColor4D (0.3f, 0.3f, 0.3f, 1.0f), // dark gray
   68.84 +	aiColor4D (0.8f, 0.8f, 0.8f, 1.0f), // light gray
   68.85 +	aiColor4D (0.0f, 00.f, 0.0f, 1.0f), // black
   68.86 +	aiColor4D (1.0f, 1.0f, 1.0f, 1.0f), // white
   68.87 +	aiColor4D (0.6f, 0.0f, 1.0f, 1.0f)  // violet
   68.88 +};
   68.89 +#define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
   68.90 +#define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC"
   68.91 +
   68.92 +
   68.93 +static const aiImporterDesc desc = {
   68.94 +	"Drawing Interchange Format (DXF) Importer",
   68.95 +	"",
   68.96 +	"",
   68.97 +	"",
   68.98 +	aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport,
   68.99 +	0,
  68.100 +	0,
  68.101 +	0,
  68.102 +	0,
  68.103 +	"dxf" 
  68.104 +};
  68.105 +
  68.106 +// ------------------------------------------------------------------------------------------------
  68.107 +// Constructor to be privately used by Importer
  68.108 +DXFImporter::DXFImporter()
  68.109 +{}
  68.110 +
  68.111 +// ------------------------------------------------------------------------------------------------
  68.112 +// Destructor, private as well 
  68.113 +DXFImporter::~DXFImporter()
  68.114 +{}
  68.115 +
  68.116 +// ------------------------------------------------------------------------------------------------
  68.117 +// Returns whether the class can handle the format of the given file. 
  68.118 +bool DXFImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
  68.119 +{
  68.120 +	return SimpleExtensionCheck(pFile,"dxf");
  68.121 +}
  68.122 +
  68.123 +// ------------------------------------------------------------------------------------------------
  68.124 +// Get a list of all supported file extensions
  68.125 +const aiImporterDesc* DXFImporter::GetInfo () const
  68.126 +{
  68.127 +	return &desc;
  68.128 +}
  68.129 +
  68.130 +// ------------------------------------------------------------------------------------------------
  68.131 +// Imports the given file into the given scene structure. 
  68.132 +void DXFImporter::InternReadFile( const std::string& pFile, 
  68.133 +	aiScene* pScene, 
  68.134 +	IOSystem* pIOHandler)
  68.135 +{
  68.136 +	boost::shared_ptr<IOStream> file = boost::shared_ptr<IOStream>( pIOHandler->Open( pFile) );
  68.137 +	
  68.138 +	// Check whether we can read the file
  68.139 +	if( file.get() == NULL) {
  68.140 +		throw DeadlyImportError( "Failed to open DXF file " + pFile + "");
  68.141 +	}
  68.142 +
  68.143 +	// check whether this is a binaray DXF file - we can't read binary DXF files :-(
  68.144 +	char buff[AI_DXF_BINARY_IDENT_LEN+1] = {0};
  68.145 +	file->Read(buff,AI_DXF_BINARY_IDENT_LEN,1);
  68.146 +
  68.147 +	if (!strncmp(AI_DXF_BINARY_IDENT,buff,AI_DXF_BINARY_IDENT_LEN)) {
  68.148 +		throw DeadlyImportError("DXF: Binary files are not supported at the moment");
  68.149 +	}
  68.150 +
  68.151 +	// DXF files can grow very large, so read them via the StreamReader,
  68.152 +	// which will choose a suitable strategy.
  68.153 +	file->Seek(0,aiOrigin_SET);
  68.154 +	StreamReaderLE stream( file );
  68.155 +	
  68.156 +	DXF::LineReader reader (stream);
  68.157 +	DXF::FileData output;
  68.158 +
  68.159 +	// now get all lines of the file and process top-level sections
  68.160 +	bool eof = false;
  68.161 +	while(!reader.End()) {
  68.162 +
  68.163 +		// blocks table - these 'build blocks' are later (in ENTITIES)
  68.164 +		// referenced an included via INSERT statements.
  68.165 +		if (reader.Is(2,"BLOCKS")) {
  68.166 +			ParseBlocks(reader,output);
  68.167 +			continue;
  68.168 +		}
  68.169 +	
  68.170 +		// primary entity table
  68.171 +		if (reader.Is(2,"ENTITIES")) {
  68.172 +			ParseEntities(reader,output);
  68.173 +			continue;
  68.174 +		}
  68.175 +
  68.176 +		// skip unneeded sections entirely to avoid any problems with them 
  68.177 +		// alltogether.
  68.178 +		else if (reader.Is(2,"CLASSES") || reader.Is(2,"TABLES")) {
  68.179 +			SkipSection(reader);
  68.180 +			continue;
  68.181 +		}
  68.182 +
  68.183 +		else if (reader.Is(2,"HEADER")) {
  68.184 +			ParseHeader(reader,output);
  68.185 +			continue;
  68.186 +		}
  68.187 +
  68.188 +		// comments
  68.189 +		else if (reader.Is(999)) {
  68.190 +			DefaultLogger::get()->info("DXF Comment: " + reader.Value());
  68.191 +		}
  68.192 +
  68.193 +		// don't read past the official EOF sign
  68.194 +		else if (reader.Is(0,"EOF")) {
  68.195 +			eof = true;
  68.196 +			break;
  68.197 +		}
  68.198 +
  68.199 +		++reader;
  68.200 +	}
  68.201 +	if (!eof) {
  68.202 +		DefaultLogger::get()->warn("DXF: EOF reached, but did not encounter DXF EOF marker");
  68.203 +	}
  68.204 +
  68.205 +	ConvertMeshes(pScene,output);
  68.206 +
  68.207 +	// Now rotate the whole scene by 90 degrees around the x axis to convert from AutoCAD's to Assimp's coordinate system
  68.208 +	pScene->mRootNode->mTransformation = aiMatrix4x4(
  68.209 +		1.f,0.f,0.f,0.f,
  68.210 +		0.f,0.f,1.f,0.f,
  68.211 +		0.f,-1.f,0.f,0.f,
  68.212 +		0.f,0.f,0.f,1.f) * pScene->mRootNode->mTransformation;
  68.213 +}
  68.214 +
  68.215 +// ------------------------------------------------------------------------------------------------
  68.216 +void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output)
  68.217 +{
  68.218 +	// the process of resolving all the INSERT statements can grow the
  68.219 +	// polycount excessively, so log the original number.
  68.220 +	// XXX Option to import blocks as separate nodes?
  68.221 +	if (!DefaultLogger::isNullLogger()) {
  68.222 +
  68.223 +		unsigned int vcount = 0, icount = 0;
  68.224 +		BOOST_FOREACH (const DXF::Block& bl, output.blocks) {
  68.225 +			BOOST_FOREACH (boost::shared_ptr<const DXF::PolyLine> pl, bl.lines) {
  68.226 +				vcount += pl->positions.size();
  68.227 +				icount += pl->counts.size();
  68.228 +			}
  68.229 +		}
  68.230 +
  68.231 +		DefaultLogger::get()->debug((Formatter::format("DXF: Unexpanded polycount is "),
  68.232 +			icount,", vertex count is ",vcount
  68.233 +		));
  68.234 +	}
  68.235 +
  68.236 +	if (! output.blocks.size()  ) {
  68.237 +		throw DeadlyImportError("DXF: no data blocks loaded");
  68.238 +	}
  68.239 +
  68.240 +	DXF::Block* entities = 0;
  68.241 +	
  68.242 +	// index blocks by name
  68.243 +	DXF::BlockMap blocks_by_name;
  68.244 +	BOOST_FOREACH (DXF::Block& bl, output.blocks) {
  68.245 +		blocks_by_name[bl.name] = &bl;
  68.246 +		if ( !entities && bl.name == AI_DXF_ENTITIES_MAGIC_BLOCK ) {
  68.247 +			entities = &bl;
  68.248 +		}
  68.249 +	}
  68.250 +
  68.251 +	if (!entities) {
  68.252 +		throw DeadlyImportError("DXF: no ENTITIES data block loaded");
  68.253 +	}
  68.254 +
  68.255 +	typedef std::map<std::string, unsigned int> LayerMap;
  68.256 +
  68.257 +	LayerMap layers;
  68.258 +	std::vector< std::vector< const DXF::PolyLine*> > corr;
  68.259 +
  68.260 +	// now expand all block references in the primary ENTITIES block
  68.261 +	// XXX this involves heavy memory copying, consider a faster solution for future versions.
  68.262 +	ExpandBlockReferences(*entities,blocks_by_name);
  68.263 +
  68.264 +	unsigned int cur = 0;
  68.265 +	BOOST_FOREACH (boost::shared_ptr<const DXF::PolyLine> pl, entities->lines) {
  68.266 +		if (pl->positions.size()) {
  68.267 +
  68.268 +			std::map<std::string, unsigned int>::iterator it = layers.find(pl->layer);
  68.269 +			if (it == layers.end()) {
  68.270 +				++pScene->mNumMeshes;
  68.271 +
  68.272 +				layers[pl->layer] = cur++;
  68.273 +
  68.274 +				std::vector< const DXF::PolyLine* > pv;
  68.275 +				pv.push_back(&*pl);
  68.276 +
  68.277 +				corr.push_back(pv);
  68.278 +			}
  68.279 +			else {
  68.280 +				corr[(*it).second].push_back(&*pl);
  68.281 +			}
  68.282 +		}
  68.283 +	}
  68.284 +
  68.285 +	if (!pScene->mNumMeshes) {
  68.286 +		throw DeadlyImportError("DXF: this file contains no 3d data");
  68.287 +	}
  68.288 +
  68.289 +	pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ] ();
  68.290 +
  68.291 +	BOOST_FOREACH(const LayerMap::value_type& elem, layers){
  68.292 +		aiMesh* const mesh =  pScene->mMeshes[elem.second] = new aiMesh();
  68.293 +		mesh->mName.Set(elem.first);
  68.294 +
  68.295 +		unsigned int cvert = 0,cface = 0;
  68.296 +		BOOST_FOREACH(const DXF::PolyLine* pl, corr[elem.second]){
  68.297 +			// sum over all faces since we need to 'verbosify' them.
  68.298 +			cvert += std::accumulate(pl->counts.begin(),pl->counts.end(),0); 
  68.299 +			cface += pl->counts.size();
  68.300 +		}
  68.301 +
  68.302 +		aiVector3D* verts = mesh->mVertices = new aiVector3D[cvert];
  68.303 +		aiColor4D* colors = mesh->mColors[0] = new aiColor4D[cvert];
  68.304 +		aiFace* faces = mesh->mFaces = new aiFace[cface];
  68.305 +
  68.306 +		mesh->mNumVertices = cvert;
  68.307 +		mesh->mNumFaces = cface;
  68.308 +
  68.309 +		unsigned int prims = 0;
  68.310 +		unsigned int overall_indices = 0;
  68.311 +		BOOST_FOREACH(const DXF::PolyLine* pl, corr[elem.second]){
  68.312 +
  68.313 +			std::vector<unsigned int>::const_iterator it = pl->indices.begin();
  68.314 +			BOOST_FOREACH(unsigned int facenumv,pl->counts) {
  68.315 +				aiFace& face = *faces++;
  68.316 +				face.mIndices = new unsigned int[face.mNumIndices = facenumv];
  68.317 +
  68.318 +				for (unsigned int i = 0; i < facenumv; ++i) {
  68.319 +					face.mIndices[i] = overall_indices++;
  68.320 +
  68.321 +					ai_assert(pl->positions.size() == pl->colors.size());
  68.322 +					if (*it >= pl->positions.size()) {
  68.323 +						throw DeadlyImportError("DXF: vertex index out of bounds");
  68.324 +					}
  68.325 +
  68.326 +					*verts++ = pl->positions[*it];
  68.327 +					*colors++ = pl->colors[*it++];
  68.328 +				}
  68.329 +
  68.330 +				// set primitive flags now, this saves the extra pass in ScenePreprocessor.
  68.331 +				switch(face.mNumIndices) {
  68.332 +					case 1:
  68.333 +						prims |= aiPrimitiveType_POINT;
  68.334 +						break;
  68.335 +					case 2:
  68.336 +						prims |= aiPrimitiveType_LINE;
  68.337 +						break;
  68.338 +					case 3:
  68.339 +						prims |= aiPrimitiveType_TRIANGLE;
  68.340 +						break;
  68.341 +					default:
  68.342 +						prims |= aiPrimitiveType_POLYGON;
  68.343 +						break;
  68.344 +				}
  68.345 +			}
  68.346 +		}
  68.347 +
  68.348 +		mesh->mPrimitiveTypes = prims;
  68.349 +		mesh->mMaterialIndex = 0;
  68.350 +	}
  68.351 +
  68.352 +	GenerateHierarchy(pScene,output);
  68.353 +	GenerateMaterials(pScene,output);
  68.354 +}
  68.355 +
  68.356 +
  68.357 +// ------------------------------------------------------------------------------------------------
  68.358 +void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& blocks_by_name)
  68.359 +{
  68.360 +	BOOST_FOREACH (const DXF::InsertBlock& insert, bl.insertions) {
  68.361 +
  68.362 +		// first check if the referenced blocks exists ...
  68.363 +		const DXF::BlockMap::const_iterator it = blocks_by_name.find(insert.name);
  68.364 +		if (it == blocks_by_name.end()) {
  68.365 +			DefaultLogger::get()->error((Formatter::format("DXF: Failed to resolve block reference: "),
  68.366 +				insert.name,"; skipping"
  68.367 +			));
  68.368 +			continue;
  68.369 +		}
  68.370 +
  68.371 +		// XXX this would be the place to implement recursive expansion if needed.
  68.372 +		const DXF::Block& bl_src = *(*it).second;
  68.373 +		
  68.374 +		BOOST_FOREACH (boost::shared_ptr<const DXF::PolyLine> pl_in, bl_src.lines) {
  68.375 +			boost::shared_ptr<DXF::PolyLine> pl_out = boost::shared_ptr<DXF::PolyLine>(new DXF::PolyLine(*pl_in));
  68.376 +
  68.377 +			if (bl_src.base.Length() || insert.scale.x!=1.f || insert.scale.y!=1.f || insert.scale.z!=1.f || insert.angle || insert.pos.Length()) {
  68.378 +				// manual coordinate system transformation
  68.379 +				// XXX order
  68.380 +				aiMatrix4x4 trafo, tmp;
  68.381 +				aiMatrix4x4::Translation(-bl_src.base,trafo);
  68.382 +				trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
  68.383 +				trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
  68.384 +
  68.385 +				// XXX rotation currently ignored - I didn't find an appropriate sample model.
  68.386 +				if (insert.angle != 0.f) {
  68.387 +					DefaultLogger::get()->warn("DXF: BLOCK rotation not currently implemented");
  68.388 +				}
  68.389 +
  68.390 +				BOOST_FOREACH (aiVector3D& v, pl_out->positions) {
  68.391 +					v *= trafo;
  68.392 +				}
  68.393 +			}
  68.394 +
  68.395 +			bl.lines.push_back(pl_out);
  68.396 +		}
  68.397 +	}
  68.398 +}
  68.399 +
  68.400 +
  68.401 +// ------------------------------------------------------------------------------------------------
  68.402 +void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/)
  68.403 +{
  68.404 +	// generate an almost-white default material. Reason:
  68.405 +	// the default vertex color is GREY, so we are
  68.406 +	// already at Assimp's usual default color.
  68.407 +	// generate a default material
  68.408 +	aiMaterial* pcMat = new aiMaterial();
  68.409 +	aiString s;
  68.410 +	s.Set(AI_DEFAULT_MATERIAL_NAME);
  68.411 +	pcMat->AddProperty(&s, AI_MATKEY_NAME);
  68.412 +
  68.413 +	aiColor4D clrDiffuse(0.9f,0.9f,0.9f,1.0f);
  68.414 +	pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
  68.415 +
  68.416 +	clrDiffuse = aiColor4D(1.0f,1.0f,1.0f,1.0f);
  68.417 +	pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
  68.418 +
  68.419 +	clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f);
  68.420 +	pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
  68.421 +
  68.422 +	pScene->mNumMaterials = 1;
  68.423 +	pScene->mMaterials = new aiMaterial*[1];
  68.424 +	pScene->mMaterials[0] = pcMat;
  68.425 +}
  68.426 +
  68.427 +
  68.428 +// ------------------------------------------------------------------------------------------------
  68.429 +void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/)
  68.430 +{
  68.431 +	// generate the output scene graph, which is just the root node with a single child for each layer.
  68.432 +	pScene->mRootNode = new aiNode();
  68.433 +	pScene->mRootNode->mName.Set("<DXF_ROOT>");
  68.434 +
  68.435 +	if (1 == pScene->mNumMeshes)	{
  68.436 +		pScene->mRootNode->mMeshes = new unsigned int[ pScene->mRootNode->mNumMeshes = 1 ];
  68.437 +		pScene->mRootNode->mMeshes[0] = 0;
  68.438 +	}
  68.439 +	else
  68.440 +	{
  68.441 +		pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren = pScene->mNumMeshes ];
  68.442 +		for (unsigned int m = 0; m < pScene->mRootNode->mNumChildren;++m)	{
  68.443 +			aiNode* p = pScene->mRootNode->mChildren[m] = new aiNode();
  68.444 +			p->mName = pScene->mMeshes[m]->mName;
  68.445 +
  68.446 +			p->mMeshes = new unsigned int[p->mNumMeshes = 1];
  68.447 +			p->mMeshes[0] = m;
  68.448 +			p->mParent = pScene->mRootNode;
  68.449 +		}
  68.450 +	}
  68.451 +}
  68.452 +
  68.453 +
  68.454 +// ------------------------------------------------------------------------------------------------
  68.455 +void DXFImporter::SkipSection(DXF::LineReader& reader)
  68.456 +{	
  68.457 +	for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++);
  68.458 +}
  68.459 +
  68.460 +
  68.461 +// ------------------------------------------------------------------------------------------------
  68.462 +void DXFImporter::ParseHeader(DXF::LineReader& reader, DXF::FileData& /*output*/)
  68.463 +{	
  68.464 +	for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++);
  68.465 +}
  68.466 +
  68.467 +
  68.468 +// ------------------------------------------------------------------------------------------------
  68.469 +void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output)
  68.470 +{	
  68.471 +	while( !reader.End() && !reader.Is(0,"ENDSEC")) {
  68.472 +		if (reader.Is(0,"BLOCK")) {
  68.473 +			ParseBlock(++reader,output);
  68.474 +			continue;
  68.475 +		}
  68.476 +		++reader;
  68.477 +	}
  68.478 +
  68.479 +	DefaultLogger::get()->debug((Formatter::format("DXF: got "),
  68.480 +		output.blocks.size()," entries in BLOCKS"
  68.481 +	));
  68.482 +}
  68.483 +
  68.484 +
  68.485 +// ------------------------------------------------------------------------------------------------
  68.486 +void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output)
  68.487 +{	
  68.488 +	// push a new block onto the stack.
  68.489 +	output.blocks.push_back( DXF::Block() );
  68.490 +	DXF::Block& block = output.blocks.back();
  68.491 +
  68.492 +	while( !reader.End() && !reader.Is(0,"ENDBLK")) {
  68.493 +
  68.494 +		switch(reader.GroupCode()) {
  68.495 +			case 2:
  68.496 +				block.name = reader.Value();
  68.497 +				break;
  68.498 +
  68.499 +			case 10:
  68.500 +				block.base.x = reader.ValueAsFloat();
  68.501 +				break;
  68.502 +			case 20:
  68.503 +				block.base.y = reader.ValueAsFloat();
  68.504 +				break;
  68.505 +			case 30:
  68.506 +				block.base.z = reader.ValueAsFloat();
  68.507 +				break;
  68.508 +		}
  68.509 +
  68.510 +		if (reader.Is(0,"POLYLINE")) {
  68.511 +			ParsePolyLine(++reader,output);
  68.512 +			continue;
  68.513 +		}
  68.514 +
  68.515 +		// XXX is this a valid case?
  68.516 +		if (reader.Is(0,"INSERT")) {
  68.517 +			DefaultLogger::get()->warn("DXF: INSERT within a BLOCK not currently supported; skipping");
  68.518 +			for( ;!reader.End() && !reader.Is(0,"ENDBLK"); ++reader);
  68.519 +			break;
  68.520 +		}
  68.521 +
  68.522 +		else if (reader.Is(0,"3DFACE") || reader.Is(0,"LINE") || reader.Is(0,"3DLINE")) {
  68.523 +			//http://sourceforge.net/tracker/index.php?func=detail&aid=2970566&group_id=226462&atid=1067632
  68.524 +			Parse3DFace(++reader, output);
  68.525 +			continue;
  68.526 +		}
  68.527 +		++reader;
  68.528 +	}
  68.529 +}
  68.530 +
  68.531 +
  68.532 +// ------------------------------------------------------------------------------------------------
  68.533 +void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
  68.534 +{	
  68.535 +	// push a new block onto the stack.
  68.536 +	output.blocks.push_back( DXF::Block() );
  68.537 +	DXF::Block& block = output.blocks.back();
  68.538 +
  68.539 +	block.name = AI_DXF_ENTITIES_MAGIC_BLOCK;
  68.540 +
  68.541 +	while( !reader.End() && !reader.Is(0,"ENDSEC")) {
  68.542 +		if (reader.Is(0,"POLYLINE")) {
  68.543 +			ParsePolyLine(++reader,output);
  68.544 +			continue;
  68.545 +		}
  68.546 +
  68.547 +		else if (reader.Is(0,"INSERT")) {
  68.548 +			ParseInsertion(++reader,output);
  68.549 +			continue;
  68.550 +		}
  68.551 +
  68.552 +		else if (reader.Is(0,"3DFACE") || reader.Is(0,"LINE") || reader.Is(0,"3DLINE")) {
  68.553 +			//http://sourceforge.net/tracker/index.php?func=detail&aid=2970566&group_id=226462&atid=1067632
  68.554 +			Parse3DFace(++reader, output);
  68.555 +			continue;
  68.556 +		}
  68.557 +
  68.558 +		++reader;
  68.559 +	}
  68.560 +
  68.561 +	DefaultLogger::get()->debug((Formatter::format("DXF: got "),
  68.562 +		block.lines.size()," polylines and ", block.insertions.size() ," inserted blocks in ENTITIES"
  68.563 +	));
  68.564 +}
  68.565 +
  68.566 +
  68.567 +void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output)
  68.568 +{	
  68.569 +	output.blocks.back().insertions.push_back( DXF::InsertBlock() );
  68.570 +	DXF::InsertBlock& bl = output.blocks.back().insertions.back();
  68.571 +
  68.572 +	while( !reader.End() && !reader.Is(0)) {
  68.573 +
  68.574 +		switch(reader.GroupCode()) 
  68.575 +		{
  68.576 +			// name of referenced block
  68.577 +		case 2:
  68.578 +			bl.name = reader.Value();
  68.579 +			break;
  68.580 +
  68.581 +			// translation
  68.582 +		case 10:
  68.583 +			bl.pos.x = reader.ValueAsFloat();
  68.584 +			break;
  68.585 +		case 20:
  68.586 +			bl.pos.y = reader.ValueAsFloat();
  68.587 +			break;
  68.588 +		case 30:
  68.589 +			bl.pos.z = reader.ValueAsFloat();
  68.590 +			break;
  68.591 +
  68.592 +			// scaling
  68.593 +		case 41:
  68.594 +			bl.scale.x = reader.ValueAsFloat();
  68.595 +			break;
  68.596 +		case 42:
  68.597 +			bl.scale.y = reader.ValueAsFloat();
  68.598 +			break;
  68.599 +		case 43:
  68.600 +			bl.scale.z = reader.ValueAsFloat();
  68.601 +			break;
  68.602 +
  68.603 +			// rotation angle
  68.604 +		case 50:
  68.605 +			bl.angle = reader.ValueAsFloat();
  68.606 +			break;
  68.607 +		}
  68.608 +		reader++;
  68.609 +	}
  68.610 +}
  68.611 +
  68.612 +#define DXF_POLYLINE_FLAG_CLOSED		0x1
  68.613 +#define DXF_POLYLINE_FLAG_3D_POLYLINE	0x8
  68.614 +#define DXF_POLYLINE_FLAG_3D_POLYMESH	0x10
  68.615 +#define DXF_POLYLINE_FLAG_POLYFACEMESH	0x40
  68.616 +
  68.617 +// ------------------------------------------------------------------------------------------------
  68.618 +void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
  68.619 +{
  68.620 +	output.blocks.back().lines.push_back( boost::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() ) );
  68.621 +	DXF::PolyLine& line = *output.blocks.back().lines.back();
  68.622 +
  68.623 +	unsigned int iguess = 0, vguess = 0;
  68.624 +	while( !reader.End() && !reader.Is(0,"ENDSEC")) {
  68.625 +	
  68.626 +		if (reader.Is(0,"VERTEX")) {
  68.627 +			ParsePolyLineVertex(++reader,line);
  68.628 +			if (reader.Is(0,"SEQEND")) {
  68.629 +				break;
  68.630 +			}
  68.631 +			continue;
  68.632 +		}
  68.633 +
  68.634 +		switch(reader.GroupCode())	
  68.635 +		{
  68.636 +		// flags --- important that we know whether it is a 
  68.637 +		// polyface mesh or 'just' a line.
  68.638 +		case 70:
  68.639 +			if (!line.flags)	{
  68.640 +				line.flags = reader.ValueAsSignedInt();
  68.641 +			}
  68.642 +			break;
  68.643 +
  68.644 +		// optional number of vertices
  68.645 +		case 71:
  68.646 +			vguess = reader.ValueAsSignedInt();
  68.647 +			line.positions.reserve(vguess);
  68.648 +			break;
  68.649 +
  68.650 +		// optional number of faces
  68.651 +		case 72:
  68.652 +			iguess = reader.ValueAsSignedInt();
  68.653 +			line.indices.reserve(iguess);
  68.654 +			break;
  68.655 +
  68.656 +		// 8 specifies the layer on which this line is placed on
  68.657 +		case 8:
  68.658 +			line.layer = reader.Value();
  68.659 +			break;
  68.660 +		}
  68.661 +
  68.662 +		reader++;
  68.663 +	}
  68.664 +
  68.665 +	//if (!(line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH))	{
  68.666 +	//	DefaultLogger::get()->warn((Formatter::format("DXF: polyline not currently supported: "),line.flags));
  68.667 +	//	output.blocks.back().lines.pop_back();
  68.668 +	//	return;
  68.669 +	//}
  68.670 +
  68.671 +	if (vguess && line.positions.size() != vguess) {
  68.672 +		DefaultLogger::get()->warn((Formatter::format("DXF: unexpected vertex count in polymesh: "),
  68.673 +			line.positions.size(),", expected ", vguess
  68.674 +		));
  68.675 +	}
  68.676 +
  68.677 +	if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH ) {
  68.678 +		if (line.positions.size() < 3 || line.indices.size() < 3)	{
  68.679 +				DefaultLogger::get()->warn("DXF: not enough vertices for polymesh; ignoring");
  68.680 +				output.blocks.back().lines.pop_back();
  68.681 +				return;
  68.682 +		}
  68.683 +
  68.684 +		// if these numbers are wrong, parsing might have gone wild. 
  68.685 +		// however, the docs state that applications are not required
  68.686 +		// to set the 71 and 72 fields, respectively, to valid values.
  68.687 +		// So just fire a warning.
  68.688 +		if (iguess && line.counts.size() != iguess) {
  68.689 +			DefaultLogger::get()->warn((Formatter::format("DXF: unexpected face count in polymesh: "),
  68.690 +				line.counts.size(),", expected ", iguess
  68.691 +			));
  68.692 +		}
  68.693 +	}
  68.694 +	else if (!line.indices.size() && !line.counts.size()) {
  68.695 +		// a polyline - so there are no indices yet.
  68.696 +		size_t guess = line.positions.size() + (line.flags & DXF_POLYLINE_FLAG_CLOSED ? 1 : 0);
  68.697 +		line.indices.reserve(guess);
  68.698 +
  68.699 +		line.counts.reserve(guess/2);
  68.700 +		for (unsigned int i = 0; i < line.positions.size()/2; ++i) {
  68.701 +			line.indices.push_back(i*2);
  68.702 +			line.indices.push_back(i*2+1);
  68.703 +			line.counts.push_back(2);
  68.704 +		}
  68.705 +
  68.706 +		// closed polyline?
  68.707 +		if (line.flags & DXF_POLYLINE_FLAG_CLOSED) {
  68.708 +			line.indices.push_back(line.positions.size()-1);
  68.709 +			line.indices.push_back(0);
  68.710 +			line.counts.push_back(2);
  68.711 +		}
  68.712 +	}
  68.713 +}
  68.714 +
  68.715 +#define DXF_VERTEX_FLAG_PART_OF_POLYFACE 0x80
  68.716 +#define DXF_VERTEX_FLAG_HAS_POSITIONS 0x40
  68.717 +
  68.718 +// ------------------------------------------------------------------------------------------------
  68.719 +void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& line)
  68.720 +{
  68.721 +	unsigned int cnti = 0, flags = 0;
  68.722 +	unsigned int indices[4];
  68.723 +
  68.724 +	aiVector3D out;
  68.725 +	aiColor4D clr = AI_DXF_DEFAULT_COLOR;
  68.726 +
  68.727 +	while( !reader.End() ) {
  68.728 +
  68.729 +		if (reader.Is(0)) { // SEQEND or another VERTEX
  68.730 +			break;
  68.731 +		}
  68.732 +
  68.733 +		switch (reader.GroupCode())
  68.734 +		{
  68.735 +		case 8:
  68.736 +				// layer to which the vertex belongs to - assume that
  68.737 +				// this is always the layer the top-level polyline
  68.738 +				// entity resides on as well.
  68.739 +				if(reader.Value() != line.layer) {
  68.740 +					DefaultLogger::get()->warn("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set");
  68.741 +				}
  68.742 +				break;
  68.743 +
  68.744 +		case 70:
  68.745 +				flags = reader.ValueAsUnsignedInt();
  68.746 +				break;
  68.747 +
  68.748 +		// VERTEX COORDINATES
  68.749 +		case 10: out.x = reader.ValueAsFloat();break;
  68.750 +		case 20: out.y = reader.ValueAsFloat();break;
  68.751 +		case 30: out.z = reader.ValueAsFloat();break;
  68.752 +
  68.753 +		// POLYFACE vertex indices
  68.754 +		case 71: 
  68.755 +		case 72:
  68.756 +		case 73:
  68.757 +		case 74: 
  68.758 +			if (cnti == 4) {
  68.759 +				DefaultLogger::get()->warn("DXF: more than 4 indices per face not supported; ignoring");
  68.760 +				break;
  68.761 +			}
  68.762 +			indices[cnti++] = reader.ValueAsUnsignedInt();
  68.763 +			break;
  68.764 +
  68.765 +		// color
  68.766 +		case 62: 
  68.767 +			clr = g_aclrDxfIndexColors[reader.ValueAsUnsignedInt() % AI_DXF_NUM_INDEX_COLORS]; 
  68.768 +			break;
  68.769 +		};
  68.770 +	
  68.771 +		reader++;
  68.772 +	}
  68.773 +	
  68.774 +	if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH && !(flags & DXF_VERTEX_FLAG_PART_OF_POLYFACE)) {
  68.775 +		DefaultLogger::get()->warn("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set");
  68.776 +	}
  68.777 +
  68.778 +	if (cnti) {
  68.779 +		line.counts.push_back(cnti);
  68.780 +		for (unsigned int i = 0; i < cnti; ++i) {
  68.781 +			// IMPORTANT NOTE: POLYMESH indices are ONE-BASED
  68.782 +			if (indices[i] == 0) {
  68.783 +				DefaultLogger::get()->warn("DXF: invalid vertex index, indices are one-based.");
  68.784 +				--line.counts.back();
  68.785 +				continue;
  68.786 +			}
  68.787 +			line.indices.push_back(indices[i]-1);
  68.788 +		}
  68.789 +	}
  68.790 +	else {
  68.791 +		line.positions.push_back(out);
  68.792 +		line.colors.push_back(clr);
  68.793 +	}
  68.794 +}
  68.795 +
  68.796 +// ------------------------------------------------------------------------------------------------
  68.797 +void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
  68.798 +{
  68.799 +	// (note) this is also used for for parsing line entities, so we
  68.800 +	// must handle the vertex_count == 2 case as well.
  68.801 +
  68.802 +	output.blocks.back().lines.push_back( boost::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() )  );
  68.803 +	DXF::PolyLine& line = *output.blocks.back().lines.back();
  68.804 +
  68.805 +	aiVector3D vip[4];
  68.806 +	aiColor4D  clr = AI_DXF_DEFAULT_COLOR;
  68.807 +	
  68.808 +	bool b[4] = {false,false,false,false};
  68.809 +	while( !reader.End() ) {
  68.810 +
  68.811 +		// next entity with a groupcode == 0 is probably already the next vertex or polymesh entity
  68.812 +		if (reader.GroupCode() == 0) {
  68.813 +			break;
  68.814 +		}
  68.815 +		switch (reader.GroupCode())	
  68.816 +		{
  68.817 +
  68.818 +		// 8 specifies the layer
  68.819 +		case 8:	
  68.820 +			line.layer = reader.Value();
  68.821 +			break;
  68.822 +
  68.823 +		// x position of the first corner
  68.824 +		case 10: vip[0].x = reader.ValueAsFloat();
  68.825 +			b[2] = true;
  68.826 +			break;
  68.827 +
  68.828 +		// y position of the first corner
  68.829 +		case 20: vip[0].y = reader.ValueAsFloat();
  68.830 +			b[2] = true;
  68.831 +			break;
  68.832 +
  68.833 +		// z position of the first corner
  68.834 +		case 30: vip[0].z = reader.ValueAsFloat();
  68.835 +			b[2] = true;
  68.836 +			break;
  68.837 +
  68.838 +		// x position of the second corner
  68.839 +		case 11: vip[1].x = reader.ValueAsFloat();
  68.840 +			b[3] = true;
  68.841 +			break;
  68.842 +
  68.843 +		// y position of the second corner
  68.844 +		case 21: vip[1].y = reader.ValueAsFloat();
  68.845 +			b[3] = true;
  68.846 +			break;
  68.847 +
  68.848 +		// z position of the second corner
  68.849 +		case 31: vip[1].z = reader.ValueAsFloat();
  68.850 +			b[3] = true;
  68.851 +			break;
  68.852 +
  68.853 +		// x position of the third corner
  68.854 +		case 12: vip[2].x = reader.ValueAsFloat();
  68.855 +			b[0] = true;
  68.856 +			break;
  68.857 +
  68.858 +		// y position of the third corner
  68.859 +		case 22: vip[2].y = reader.ValueAsFloat();
  68.860 +			b[0] = true;
  68.861 +			break;
  68.862 +
  68.863 +		// z position of the third corner
  68.864 +		case 32: vip[2].z = reader.ValueAsFloat();
  68.865 +			b[0] = true;
  68.866 +			break;
  68.867 +
  68.868 +		// x position of the fourth corner
  68.869 +		case 13: vip[3].x = reader.ValueAsFloat();
  68.870 +			b[1] = true;
  68.871 +			break;
  68.872 +
  68.873 +		// y position of the fourth corner
  68.874 +		case 23: vip[3].y = reader.ValueAsFloat();
  68.875 +			b[1] = true;
  68.876 +			break;
  68.877 +
  68.878 +		// z position of the fourth corner
  68.879 +		case 33: vip[3].z = reader.ValueAsFloat();
  68.880 +			b[1] = true;
  68.881 +			break;
  68.882 +
  68.883 +		// color
  68.884 +		case 62: 
  68.885 +			clr = g_aclrDxfIndexColors[reader.ValueAsUnsignedInt() % AI_DXF_NUM_INDEX_COLORS]; 
  68.886 +			break;
  68.887 +		};
  68.888 +
  68.889 +		++reader;
  68.890 +	}
  68.891 +
  68.892 +	// the fourth corner may even be identical to the third,
  68.893 +	// in this case we treat it as if it didn't exist.
  68.894 +	if (vip[3] == vip[2]) {
  68.895 +		b[1] = false;
  68.896 +	}
  68.897 +	
  68.898 +	// sanity checks to see if we got something meaningful
  68.899 +	if ((b[1] && !b[0]) || !b[2] || !b[3]) {
  68.900 +		DefaultLogger::get()->warn("DXF: unexpected vertex setup in 3DFACE/LINE/FACE entity; ignoring");
  68.901 +		output.blocks.back().lines.pop_back();
  68.902 +		return;
  68.903 +	}
  68.904 +
  68.905 +	const unsigned int cnt = (2+(b[0]?1:0)+(b[1]?1:0));
  68.906 +	line.counts.push_back(cnt);
  68.907 +
  68.908 +	for (unsigned int i = 0; i < cnt; ++i) {
  68.909 +		line.indices.push_back(line.positions.size());
  68.910 +		line.positions.push_back(vip[i]);
  68.911 +		line.colors.push_back(clr);
  68.912 +	}
  68.913 +}
  68.914 +
  68.915 +#endif // !! ASSIMP_BUILD_NO_DXF_IMPORTER
  68.916 +
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/libs/assimp/DXFLoader.h	Sat Feb 01 19:58:19 2014 +0200
    69.3 @@ -0,0 +1,152 @@
    69.4 +/*
    69.5 +Open Asset Import Library (assimp)
    69.6 +----------------------------------------------------------------------
    69.7 +
    69.8 +Copyright (c) 2006-2012, assimp team
    69.9 +All rights reserved.
   69.10 +
   69.11 +Redistribution and use of this software in source and binary forms, 
   69.12 +with or without modification, are permitted provided that the 
   69.13 +following conditions are met:
   69.14 +
   69.15 +* Redistributions of source code must retain the above
   69.16 +  copyright notice, this list of conditions and the
   69.17 +  following disclaimer.
   69.18 +
   69.19 +* Redistributions in binary form must reproduce the above
   69.20 +  copyright notice, this list of conditions and the
   69.21 +  following disclaimer in the documentation and/or other
   69.22 +  materials provided with the distribution.
   69.23 +
   69.24 +* Neither the name of the assimp team, nor the names of its
   69.25 +  contributors may be used to endorse or promote products
   69.26 +  derived from this software without specific prior
   69.27 +  written permission of the assimp team.
   69.28 +
   69.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   69.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   69.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   69.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   69.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   69.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   69.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   69.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   69.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   69.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   69.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   69.40 +
   69.41 +----------------------------------------------------------------------
   69.42 +*/
   69.43 +
   69.44 +/** @file  DXFLoader.h 
   69.45 + *  @brief Declaration of the .dxf importer class.
   69.46 + */
   69.47 +#ifndef AI_DXFLOADER_H_INCLUDED
   69.48 +#define AI_DXFLOADER_H_INCLUDED
   69.49 +
   69.50 +#include "BaseImporter.h"
   69.51 +
   69.52 +namespace Assimp	{
   69.53 +	namespace DXF {
   69.54 +	
   69.55 +		class LineReader;
   69.56 +		struct FileData;
   69.57 +		struct PolyLine;
   69.58 +		struct Block;
   69.59 +		struct InsertBlock;
   69.60 +
   69.61 +		typedef std::map<std::string, const DXF::Block*> BlockMap;
   69.62 +	}
   69.63 +
   69.64 +
   69.65 +// ---------------------------------------------------------------------------
   69.66 +/** DXF importer implementation.
   69.67 + *
   69.68 +*/
   69.69 +class DXFImporter : public BaseImporter
   69.70 +{
   69.71 +public:
   69.72 +	DXFImporter();
   69.73 +	~DXFImporter();
   69.74 +
   69.75 +
   69.76 +
   69.77 +public:
   69.78 +
   69.79 +	// -------------------------------------------------------------------
   69.80 +	/** Returns whether the class can handle the format of the given file. 
   69.81 +	* See BaseImporter::CanRead() for details.	*/
   69.82 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, 
   69.83 +		bool checkSig) const;
   69.84 +
   69.85 +protected:
   69.86 +
   69.87 +	// -------------------------------------------------------------------
   69.88 +	/** Return importer meta information.
   69.89 +	 * See #BaseImporter::GetInfo for the details*/
   69.90 +	const aiImporterDesc* GetInfo () const;
   69.91 +
   69.92 +	// -------------------------------------------------------------------
   69.93 +	/** Imports the given file into the given scene structure. 
   69.94 +	 * See BaseImporter::InternReadFile() for details */
   69.95 +	void InternReadFile( const std::string& pFile, 
   69.96 +		aiScene* pScene, 
   69.97 +		IOSystem* pIOHandler);
   69.98 +
   69.99 +private:
  69.100 +
  69.101 +	// -----------------------------------------------------
  69.102 +	void SkipSection(DXF::LineReader& reader);
  69.103 +
  69.104 +	// -----------------------------------------------------
  69.105 +	void ParseHeader(DXF::LineReader& reader,
  69.106 +		DXF::FileData& output);
  69.107 +
  69.108 +	// -----------------------------------------------------
  69.109 +	void ParseEntities(DXF::LineReader& reader,
  69.110 +		DXF::FileData& output);
  69.111 +
  69.112 +	// -----------------------------------------------------
  69.113 +	void ParseBlocks(DXF::LineReader& reader, 
  69.114 +		DXF::FileData& output);
  69.115 +
  69.116 +	// -----------------------------------------------------
  69.117 +	void ParseBlock(DXF::LineReader& reader, 
  69.118 +		DXF::FileData& output);
  69.119 +
  69.120 +	// -----------------------------------------------------
  69.121 +	void ParseInsertion(DXF::LineReader& reader, 
  69.122 +		DXF::FileData& output);
  69.123 +
  69.124 +	// -----------------------------------------------------
  69.125 +	void ParsePolyLine(DXF::LineReader& reader, 
  69.126 +		DXF::FileData& output);
  69.127 +
  69.128 +	// -----------------------------------------------------
  69.129 +	void ParsePolyLineVertex(DXF::LineReader& reader, 
  69.130 +		DXF::PolyLine& line);
  69.131 +
  69.132 +	// -----------------------------------------------------
  69.133 +	void Parse3DFace(DXF::LineReader& reader, 
  69.134 +		DXF::FileData& output);
  69.135 +
  69.136 +	// -----------------------------------------------------
  69.137 +	void ConvertMeshes(aiScene* pScene, 
  69.138 +		DXF::FileData& output);
  69.139 +
  69.140 +	// -----------------------------------------------------
  69.141 +	void GenerateHierarchy(aiScene* pScene, 
  69.142 +		DXF::FileData& output);
  69.143 +
  69.144 +	// -----------------------------------------------------
  69.145 +	void GenerateMaterials(aiScene* pScene, 
  69.146 +		DXF::FileData& output);
  69.147 +
  69.148 +	// -----------------------------------------------------
  69.149 +	void ExpandBlockReferences(DXF::Block& bl,
  69.150 +		const DXF::BlockMap& blocks_by_name);
  69.151 +};
  69.152 +
  69.153 +} // end of namespace Assimp
  69.154 +
  69.155 +#endif // AI_3DSIMPORTER_H_INC
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/libs/assimp/DeboneProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
    70.3 @@ -0,0 +1,464 @@
    70.4 +									 /*
    70.5 +Open Asset Import Library (assimp)
    70.6 +----------------------------------------------------------------------
    70.7 +
    70.8 +Copyright (c) 2006-2012, assimp team
    70.9 +All rights reserved.
   70.10 +
   70.11 +Redistribution and use of this software in source and binary forms, 
   70.12 +with or without modification, are permitted provided that the 
   70.13 +following conditions are met:
   70.14 +
   70.15 +* Redistributions of source code must retain the above
   70.16 +  copyright notice, this list of conditions and the
   70.17 +  following disclaimer.
   70.18 +
   70.19 +* Redistributions in binary form must reproduce the above
   70.20 +  copyright notice, this list of conditions and the
   70.21 +  following disclaimer in the documentation and/or other
   70.22 +  materials provided with the distribution.
   70.23 +
   70.24 +* Neither the name of the assimp team, nor the names of its
   70.25 +  contributors may be used to endorse or promote products
   70.26 +  derived from this software without specific prior
   70.27 +  written permission of the assimp team.
   70.28 +
   70.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   70.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   70.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   70.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   70.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   70.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   70.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   70.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   70.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   70.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   70.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   70.40 +
   70.41 +----------------------------------------------------------------------
   70.42 +*/
   70.43 +
   70.44 +/// @file DeboneProcess.cpp
   70.45 +/** Implementation of the DeboneProcess post processing step */
   70.46 +
   70.47 +#include "AssimpPCH.h"
   70.48 +
   70.49 +// internal headers of the post-processing framework
   70.50 +#include "ProcessHelper.h"
   70.51 +#include "DeboneProcess.h"
   70.52 +
   70.53 +
   70.54 +using namespace Assimp;
   70.55 +
   70.56 +// ------------------------------------------------------------------------------------------------
   70.57 +// Constructor to be privately used by Importer
   70.58 +DeboneProcess::DeboneProcess()
   70.59 +{
   70.60 +	mNumBones = 0;
   70.61 +	mNumBonesCanDoWithout = 0;
   70.62 +
   70.63 +	mThreshold = AI_DEBONE_THRESHOLD;
   70.64 +	mAllOrNone = false;
   70.65 +}
   70.66 +
   70.67 +// ------------------------------------------------------------------------------------------------
   70.68 +// Destructor, private as well
   70.69 +DeboneProcess::~DeboneProcess()
   70.70 +{
   70.71 +	// nothing to do here
   70.72 +}
   70.73 +
   70.74 +// ------------------------------------------------------------------------------------------------
   70.75 +// Returns whether the processing step is present in the given flag field.
   70.76 +bool DeboneProcess::IsActive( unsigned int pFlags) const
   70.77 +{
   70.78 +	return (pFlags & aiProcess_Debone) != 0;
   70.79 +}
   70.80 +
   70.81 +// ------------------------------------------------------------------------------------------------
   70.82 +// Executes the post processing step on the given imported data.
   70.83 +void DeboneProcess::SetupProperties(const Importer* pImp)
   70.84 +{	
   70.85 +	// get the current value of the property
   70.86 +	mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false;
   70.87 +	mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD);
   70.88 +}
   70.89 +
   70.90 +// ------------------------------------------------------------------------------------------------
   70.91 +// Executes the post processing step on the given imported data.
   70.92 +void DeboneProcess::Execute( aiScene* pScene)
   70.93 +{
   70.94 +	DefaultLogger::get()->debug("DeboneProcess begin");
   70.95 +
   70.96 +	if(!pScene->mNumMeshes) {
   70.97 +		return;
   70.98 +	}
   70.99 +
  70.100 +	std::vector<bool> splitList(pScene->mNumMeshes); 
  70.101 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
  70.102 +		splitList[a] = ConsiderMesh( pScene->mMeshes[a] );
  70.103 +	}
  70.104 +
  70.105 +	int numSplits = 0; 
  70.106 +
  70.107 +	if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones))	{
  70.108 +		for(unsigned int a = 0; a < pScene->mNumMeshes; a++)	{
  70.109 +			if(splitList[a]) {
  70.110 +				numSplits++;
  70.111 +			}
  70.112 +		}
  70.113 +	}
  70.114 +
  70.115 +	if(numSplits)	{
  70.116 +		// we need to do something. Let's go.
  70.117 +		mSubMeshIndices.clear();
  70.118 +		mSubMeshIndices.resize(pScene->mNumMeshes);
  70.119 +
  70.120 +		// build a new array of meshes for the scene
  70.121 +		std::vector<aiMesh*> meshes;
  70.122 +
  70.123 +		for(unsigned int a=0;a<pScene->mNumMeshes;a++)
  70.124 +		{
  70.125 +			aiMesh* srcMesh = pScene->mMeshes[a];
  70.126 +
  70.127 +			std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes;
  70.128 +
  70.129 +			if(splitList[a]) { 
  70.130 +				SplitMesh(srcMesh,newMeshes);
  70.131 +			}
  70.132 +
  70.133 +			// mesh was split
  70.134 +			if(!newMeshes.empty())	{				
  70.135 +				unsigned int out = 0, in = srcMesh->mNumBones;				
  70.136 +
  70.137 +				// store new meshes and indices of the new meshes
  70.138 +				for(unsigned int b=0;b<newMeshes.size();b++)	{						
  70.139 +					const aiString *find = newMeshes[b].second?&newMeshes[b].second->mName:0;
  70.140 +
  70.141 +					aiNode *theNode = find?pScene->mRootNode->FindNode(*find):0;
  70.142 +					std::pair<unsigned int,aiNode*> push_pair(meshes.size(),theNode);
  70.143 +
  70.144 +					mSubMeshIndices[a].push_back(push_pair);
  70.145 +					meshes.push_back(newMeshes[b].first);
  70.146 +
  70.147 +					out+=newMeshes[b].first->mNumBones;
  70.148 +				}
  70.149 +						   
  70.150 +				if(!DefaultLogger::isNullLogger()) {
  70.151 +					char buffer[1024];
  70.152 +					::sprintf(buffer,"Removed %i bones. Input bones: %i. Output bones: %i",in-out,in,out);
  70.153 +					DefaultLogger::get()->info(buffer);
  70.154 +				}
  70.155 +
  70.156 +				// and destroy the source mesh. It should be completely contained inside the new submeshes
  70.157 +				delete srcMesh;
  70.158 +			}
  70.159 +			else	{
  70.160 +				// Mesh is kept unchanged - store it's new place in the mesh array
  70.161 +				mSubMeshIndices[a].push_back(std::pair<unsigned int,aiNode*>(meshes.size(),(aiNode*)0));
  70.162 +				meshes.push_back(srcMesh);
  70.163 +			}
  70.164 +		}	
  70.165 +			
  70.166 +		// rebuild the scene's mesh array
  70.167 +		pScene->mNumMeshes = meshes.size();
  70.168 +		delete [] pScene->mMeshes;
  70.169 +		pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
  70.170 +		std::copy( meshes.begin(), meshes.end(), pScene->mMeshes);
  70.171 +
  70.172 +		// recurse through all nodes and translate the node's mesh indices to fit the new mesh array
  70.173 +		UpdateNode( pScene->mRootNode);
  70.174 +	}
  70.175 +
  70.176 +	DefaultLogger::get()->debug("DeboneProcess end");
  70.177 +}
  70.178 +
  70.179 +// ------------------------------------------------------------------------------------------------
  70.180 +// Counts bones total/removable in a given mesh.
  70.181 +bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
  70.182 +{
  70.183 +	if(!pMesh->HasBones()) {
  70.184 +		return false;
  70.185 +	}
  70.186 +
  70.187 +	bool split = false;
  70.188 +
  70.189 +	//interstitial faces not permitted
  70.190 +	bool isInterstitialRequired = false;
  70.191 +
  70.192 +	std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
  70.193 +	std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
  70.194 +
  70.195 +	const unsigned int cUnowned = UINT_MAX;
  70.196 +	const unsigned int cCoowned = UINT_MAX-1;
  70.197 +
  70.198 +	for(unsigned int i=0;i<pMesh->mNumBones;i++)	{
  70.199 +		for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++)	{
  70.200 +			float w = pMesh->mBones[i]->mWeights[j].mWeight;
  70.201 +
  70.202 +			if(w==0.0f) {
  70.203 +				continue;
  70.204 +			}
  70.205 +
  70.206 +			unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
  70.207 +			if(w>=mThreshold)	{
  70.208 +
  70.209 +				if(vertexBones[vid]!=cUnowned)	{
  70.210 +					if(vertexBones[vid]==i) //double entry
  70.211 +					{
  70.212 +						DefaultLogger::get()->warn("Encountered double entry in bone weights");					
  70.213 +					}
  70.214 +					else //TODO: track attraction in order to break tie
  70.215 +					{
  70.216 +						vertexBones[vid] = cCoowned;
  70.217 +					}
  70.218 +				}
  70.219 +				else vertexBones[vid] = i;			
  70.220 +			}
  70.221 +
  70.222 +			if(!isBoneNecessary[i]) {
  70.223 +				isBoneNecessary[i] = w<mThreshold;
  70.224 +			}
  70.225 +		}
  70.226 +
  70.227 +		if(!isBoneNecessary[i])  {
  70.228 +			isInterstitialRequired = true;
  70.229 +		}
  70.230 +	}
  70.231 +
  70.232 +	if(isInterstitialRequired) {
  70.233 +		for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
  70.234 +			unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
  70.235 +
  70.236 +			for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
  70.237 +				unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
  70.238 +
  70.239 +				if(v!=w)	{
  70.240 +					if(v<pMesh->mNumBones) isBoneNecessary[v] = true; 
  70.241 +					if(w<pMesh->mNumBones) isBoneNecessary[w] = true; 
  70.242 +				}
  70.243 +			}
  70.244 +		}
  70.245 +	}
  70.246 +
  70.247 +	for(unsigned int i=0;i<pMesh->mNumBones;i++)	{
  70.248 +		if(!isBoneNecessary[i])	{
  70.249 +			mNumBonesCanDoWithout++; 
  70.250 +			split = true;
  70.251 +		}
  70.252 +		
  70.253 +		mNumBones++;
  70.254 +	}
  70.255 +	return split;
  70.256 +}
  70.257 +
  70.258 +// ------------------------------------------------------------------------------------------------
  70.259 +// Splits the given mesh by bone count.
  70.260 +void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const
  70.261 +{
  70.262 +	// same deal here as ConsiderMesh basically
  70.263 +
  70.264 +	std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
  70.265 +	std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
  70.266 +
  70.267 +	const unsigned int cUnowned = UINT_MAX;
  70.268 +	const unsigned int cCoowned = UINT_MAX-1;
  70.269 +
  70.270 +	for(unsigned int i=0;i<pMesh->mNumBones;i++)	{
  70.271 +		for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++)	{
  70.272 +			float w = pMesh->mBones[i]->mWeights[j].mWeight;
  70.273 +
  70.274 +			if(w==0.0f) {
  70.275 +				continue;
  70.276 +			}
  70.277 +
  70.278 +			unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
  70.279 +
  70.280 +			if(w>=mThreshold) {
  70.281 +				if(vertexBones[vid]!=cUnowned)  {
  70.282 +					if(vertexBones[vid]==i) //double entry
  70.283 +					{
  70.284 +						//DefaultLogger::get()->warn("Encountered double entry in bone weights");					
  70.285 +					}
  70.286 +					else //TODO: track attraction in order to break tie
  70.287 +					{
  70.288 +						vertexBones[vid] = cCoowned;
  70.289 +					}
  70.290 +				}
  70.291 +				else vertexBones[vid] = i;			
  70.292 +			}
  70.293 +
  70.294 +			if(!isBoneNecessary[i]) {
  70.295 +				isBoneNecessary[i] = w<mThreshold;
  70.296 +			}
  70.297 +		}
  70.298 +	}
  70.299 +
  70.300 +	unsigned int nFacesUnowned = 0;
  70.301 +
  70.302 +	std::vector<unsigned int> faceBones(pMesh->mNumFaces,UINT_MAX);
  70.303 +	std::vector<unsigned int> facesPerBone(pMesh->mNumBones,0);
  70.304 +
  70.305 +	for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
  70.306 +		unsigned int nInterstitial = 1;
  70.307 +
  70.308 +		unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
  70.309 +
  70.310 +		for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
  70.311 +			unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
  70.312 +
  70.313 +			if(v!=w)	{
  70.314 +				if(v<pMesh->mNumBones) isBoneNecessary[v] = true; 
  70.315 +				if(w<pMesh->mNumBones) isBoneNecessary[w] = true; 
  70.316 +			}
  70.317 +			else nInterstitial++;
  70.318 +		}
  70.319 +
  70.320 +		if(v<pMesh->mNumBones &&nInterstitial==pMesh->mFaces[i].mNumIndices)	{				
  70.321 +			faceBones[i] = v; //primitive belongs to bone #v
  70.322 +			facesPerBone[v]++;
  70.323 +		}
  70.324 +		else nFacesUnowned++; 
  70.325 +	}
  70.326 +
  70.327 +	// invalidate any "cojoined" faces
  70.328 +	for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
  70.329 +		if(faceBones[i]<pMesh->mNumBones&&isBoneNecessary[faceBones[i]]) 
  70.330 +		{
  70.331 +			ai_assert(facesPerBone[faceBones[i]]>0);
  70.332 +			facesPerBone[faceBones[i]]--; 
  70.333 +			
  70.334 +			nFacesUnowned++; 
  70.335 +			faceBones[i] = cUnowned; 
  70.336 +		}
  70.337 +	}
  70.338 +
  70.339 +	if(nFacesUnowned) {	 	
  70.340 +		std::vector<unsigned int> subFaces;
  70.341 +
  70.342 +		for(unsigned int i=0;i<pMesh->mNumFaces;i++)	{
  70.343 +			if(faceBones[i]==cUnowned) {
  70.344 +				subFaces.push_back(i);
  70.345 +			}
  70.346 +		}
  70.347 +
  70.348 +		aiMesh *baseMesh = MakeSubmesh(pMesh,subFaces,0);
  70.349 +		std::pair<aiMesh*,const aiBone*> push_pair(baseMesh,(const aiBone*)0);
  70.350 +
  70.351 +		poNewMeshes.push_back(push_pair);
  70.352 +	}
  70.353 +
  70.354 +	for(unsigned int i=0;i<pMesh->mNumBones;i++) {			
  70.355 +
  70.356 +		if(!isBoneNecessary[i]&&facesPerBone[i]>0)	{				
  70.357 +			std::vector<unsigned int> subFaces;
  70.358 +
  70.359 +			for(unsigned int j=0;j<pMesh->mNumFaces;j++)	{
  70.360 +				if(faceBones[j]==i) {
  70.361 +					subFaces.push_back(j);
  70.362 +				}
  70.363 +			}
  70.364 +
  70.365 +			unsigned int f = AI_SUBMESH_FLAGS_SANS_BONES;
  70.366 +			aiMesh *subMesh =MakeSubmesh(pMesh,subFaces,f);
  70.367 +
  70.368 +			//Lifted from PretransformVertices.cpp
  70.369 +			ApplyTransform(subMesh,pMesh->mBones[i]->mOffsetMatrix);
  70.370 +			std::pair<aiMesh*,const aiBone*> push_pair(subMesh,pMesh->mBones[i]);
  70.371 +
  70.372 +			poNewMeshes.push_back(push_pair);		
  70.373 +		}
  70.374 +	}
  70.375 +}
  70.376 +
  70.377 +// ------------------------------------------------------------------------------------------------
  70.378 +// Recursively updates the node's mesh list to account for the changed mesh list
  70.379 +void DeboneProcess::UpdateNode(aiNode* pNode) const
  70.380 +{
  70.381 +	// rebuild the node's mesh index list
  70.382 +	
  70.383 +	std::vector<unsigned int> newMeshList;
  70.384 +
  70.385 +	// this will require two passes
  70.386 +
  70.387 +	unsigned int m = pNode->mNumMeshes, n = mSubMeshIndices.size();
  70.388 +	
  70.389 +	// first pass, look for meshes which have not moved
  70.390 +
  70.391 +	for(unsigned int a=0;a<m;a++)	{
  70.392 +
  70.393 +		unsigned int srcIndex = pNode->mMeshes[a];
  70.394 +		const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex];
  70.395 +		unsigned int nSubmeshes = subMeshes.size();
  70.396 +
  70.397 +		for(unsigned int b=0;b<nSubmeshes;b++) {
  70.398 +			if(!subMeshes[b].second) {
  70.399 +				newMeshList.push_back(subMeshes[b].first);
  70.400 +			}
  70.401 +		}
  70.402 +	}
  70.403 +
  70.404 +	// second pass, collect deboned meshes 
  70.405 +
  70.406 +	for(unsigned int a=0;a<n;a++)
  70.407 +	{
  70.408 +		const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a];
  70.409 +		unsigned int nSubmeshes = subMeshes.size();
  70.410 +
  70.411 +		for(unsigned int b=0;b<nSubmeshes;b++) {
  70.412 +			if(subMeshes[b].second == pNode)	{
  70.413 +				newMeshList.push_back(subMeshes[b].first);
  70.414 +			}
  70.415 +		}
  70.416 +	}
  70.417 +
  70.418 +	if( pNode->mNumMeshes > 0 )	{
  70.419 +		delete [] pNode->mMeshes; pNode->mMeshes = NULL;
  70.420 +	}
  70.421 +
  70.422 +	pNode->mNumMeshes = newMeshList.size();
  70.423 +
  70.424 +	if(pNode->mNumMeshes)	{
  70.425 +		pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
  70.426 +		std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
  70.427 +	}
  70.428 +
  70.429 +	// do that also recursively for all children
  70.430 +	for( unsigned int a = 0; a < pNode->mNumChildren; ++a )	{
  70.431 +		UpdateNode( pNode->mChildren[a]);
  70.432 +	}
  70.433 +}
  70.434 +
  70.435 +// ------------------------------------------------------------------------------------------------
  70.436 +// Apply the node transformation to a mesh
  70.437 +void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const
  70.438 +{
  70.439 +	// Check whether we need to transform the coordinates at all
  70.440 +	if (!mat.IsIdentity()) {
  70.441 +		
  70.442 +		if (mesh->HasPositions()) {
  70.443 +			for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
  70.444 +				mesh->mVertices[i] = mat * mesh->mVertices[i];
  70.445 +			}
  70.446 +		}
  70.447 +		if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
  70.448 +			aiMatrix4x4 mWorldIT = mat;
  70.449 +			mWorldIT.Inverse().Transpose();
  70.450 +
  70.451 +			// TODO: implement Inverse() for aiMatrix3x3
  70.452 +			aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
  70.453 +
  70.454 +			if (mesh->HasNormals()) {
  70.455 +				for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
  70.456 +					mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
  70.457 +				}
  70.458 +			}
  70.459 +			if (mesh->HasTangentsAndBitangents()) {
  70.460 +				for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
  70.461 +					mesh->mTangents[i]   = (m * mesh->mTangents[i]).Normalize();
  70.462 +					mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
  70.463 +				}
  70.464 +			}
  70.465 +		}
  70.466 +	}
  70.467 +}
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/libs/assimp/DeboneProcess.h	Sat Feb 01 19:58:19 2014 +0200
    71.3 @@ -0,0 +1,132 @@
    71.4 +				   /*
    71.5 +Open Asset Import Library (assimp)
    71.6 +----------------------------------------------------------------------
    71.7 +
    71.8 +Copyright (c) 2006-2012, assimp team
    71.9 +All rights reserved.
   71.10 +
   71.11 +Redistribution and use of this software in source and binary forms, 
   71.12 +with or without modification, are permitted provided that the 
   71.13 +following conditions are met:
   71.14 +
   71.15 +* Redistributions of source code must retain the above
   71.16 +  copyright notice, this list of conditions and the
   71.17 +  following disclaimer.
   71.18 +
   71.19 +* Redistributions in binary form must reproduce the above
   71.20 +  copyright notice, this list of conditions and the
   71.21 +  following disclaimer in the documentation and/or other
   71.22 +  materials provided with the distribution.
   71.23 +
   71.24 +* Neither the name of the assimp team, nor the names of its
   71.25 +  contributors may be used to endorse or promote products
   71.26 +  derived from this software without specific prior
   71.27 +  written permission of the assimp team.
   71.28 +
   71.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   71.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   71.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   71.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   71.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   71.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   71.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   71.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   71.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   71.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   71.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   71.40 +
   71.41 +----------------------------------------------------------------------
   71.42 +*/
   71.43 +
   71.44 +/** Defines a post processing step to limit the number of bones affecting a single vertex. */
   71.45 +#ifndef AI_DEBONEPROCESS_H_INC
   71.46 +#define AI_DEBONEPROCESS_H_INC
   71.47 +
   71.48 +#include <vector>
   71.49 +#include <utility>
   71.50 +#include "BaseProcess.h"
   71.51 +
   71.52 +#include "assimp/mesh.h"
   71.53 +#include "assimp/scene.h"
   71.54 +
   71.55 +class DeboneTest;
   71.56 +
   71.57 +namespace Assimp
   71.58 +{
   71.59 +
   71.60 +#if (!defined AI_DEBONE_THRESHOLD)
   71.61 +#	define AI_DEBONE_THRESHOLD	1.0f
   71.62 +#endif // !! AI_DEBONE_THRESHOLD
   71.63 +
   71.64 +// ---------------------------------------------------------------------------
   71.65 +/** This post processing step removes bones nearly losslessly or according to 
   71.66 +* a configured threshold. In order to remove the bone, the primitives affected by
   71.67 +* the bone are split from the mesh. The split off (new) mesh is boneless. At any 
   71.68 +* point in time, bones without affect upon a given mesh are to be removed.
   71.69 +*/
   71.70 +class DeboneProcess : public BaseProcess
   71.71 +{
   71.72 +public:
   71.73 +
   71.74 +	DeboneProcess();
   71.75 +	~DeboneProcess();
   71.76 +
   71.77 +public:
   71.78 +	// -------------------------------------------------------------------
   71.79 +	/** Returns whether the processing step is present in the given flag.
   71.80 +	* @param pFlags The processing flags the importer was called with. 
   71.81 +	*   A bitwise combination of #aiPostProcessSteps.
   71.82 +	* @return true if the process is present in this flag fields, 
   71.83 +	*   false if not.
   71.84 +	*/
   71.85 +	bool IsActive( unsigned int pFlags) const;
   71.86 +
   71.87 +	// -------------------------------------------------------------------
   71.88 +	/** Called prior to ExecuteOnScene().
   71.89 +	* The function is a request to the process to update its configuration
   71.90 +	* basing on the Importer's configuration property list.
   71.91 +	*/
   71.92 +	void SetupProperties(const Importer* pImp);
   71.93 +
   71.94 +protected:
   71.95 +		
   71.96 +	// -------------------------------------------------------------------
   71.97 +	/** Executes the post processing step on the given imported data.
   71.98 +	* At the moment a process is not supposed to fail.
   71.99 +	* @param pScene The imported data to work at.
  71.100 +	*/
  71.101 +	void Execute( aiScene* pScene);
  71.102 +
  71.103 +	// -------------------------------------------------------------------
  71.104 +	/** Counts bones total/removable in a given mesh.
  71.105 +	* @param pMesh The mesh to process.
  71.106 +	*/
  71.107 +	bool ConsiderMesh( const aiMesh* pMesh);
  71.108 +
  71.109 +	/// Splits the given mesh by bone count.
  71.110 +	/// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.
  71.111 +	/// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary.
  71.112 +	void SplitMesh(const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const;
  71.113 +
  71.114 +	/// Recursively updates the node's mesh list to account for the changed mesh list
  71.115 +	void UpdateNode(aiNode* pNode) const;
  71.116 +
  71.117 +	// -------------------------------------------------------------------
  71.118 +	// Apply transformation to a mesh 
  71.119 +	void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const;
  71.120 +
  71.121 +public:
  71.122 +	/** Number of bones present in the scene. */
  71.123 +	unsigned int mNumBones;
  71.124 +	unsigned int mNumBonesCanDoWithout;
  71.125 +
  71.126 +	float mThreshold;
  71.127 +	bool mAllOrNone;
  71.128 +
  71.129 +	/// Per mesh index: Array of indices of the new submeshes.
  71.130 +	std::vector< std::vector< std::pair< unsigned int,aiNode* > > > mSubMeshIndices;
  71.131 +};
  71.132 +
  71.133 +} // end of namespace Assimp
  71.134 +
  71.135 +#endif // AI_DEBONEPROCESS_H_INC
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/libs/assimp/DefaultIOStream.cpp	Sat Feb 01 19:58:19 2014 +0200
    72.3 @@ -0,0 +1,139 @@
    72.4 +/*
    72.5 +---------------------------------------------------------------------------
    72.6 +Open Asset Import Library (assimp)
    72.7 +---------------------------------------------------------------------------
    72.8 +
    72.9 +Copyright (c) 2006-2012, assimp team
   72.10 +
   72.11 +All rights reserved.
   72.12 +
   72.13 +Redistribution and use of this software in source and binary forms, 
   72.14 +with or without modification, are permitted provided that the following 
   72.15 +conditions are met:
   72.16 +
   72.17 +* Redistributions of source code must retain the above
   72.18 +  copyright notice, this list of conditions and the
   72.19 +  following disclaimer.
   72.20 +
   72.21 +* Redistributions in binary form must reproduce the above
   72.22 +  copyright notice, this list of conditions and the
   72.23 +  following disclaimer in the documentation and/or other
   72.24 +  materials provided with the distribution.
   72.25 +
   72.26 +* Neither the name of the assimp team, nor the names of its
   72.27 +  contributors may be used to endorse or promote products
   72.28 +  derived from this software without specific prior
   72.29 +  written permission of the assimp team.
   72.30 +
   72.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   72.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   72.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   72.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   72.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   72.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   72.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   72.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   72.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   72.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   72.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   72.42 +---------------------------------------------------------------------------
   72.43 +*/
   72.44 +/** @file  DefaultIOStream.cpp
   72.45 + *  @brief Default File I/O implementation for #Importer 
   72.46 + */
   72.47 +
   72.48 +#include "AssimpPCH.h"
   72.49 +
   72.50 +#include "DefaultIOStream.h"
   72.51 +#include <sys/types.h> 
   72.52 +#include <sys/stat.h> 
   72.53 +
   72.54 +using namespace Assimp;
   72.55 +
   72.56 +// ----------------------------------------------------------------------------------
   72.57 +DefaultIOStream::~DefaultIOStream()
   72.58 +{
   72.59 +	if (mFile) {
   72.60 +		::fclose(mFile);
   72.61 +	}
   72.62 +}
   72.63 +
   72.64 +// ----------------------------------------------------------------------------------
   72.65 +size_t DefaultIOStream::Read(void* pvBuffer, 
   72.66 +	size_t pSize, 
   72.67 +	size_t pCount)
   72.68 +{
   72.69 +	ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
   72.70 +	return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0);
   72.71 +}
   72.72 +
   72.73 +// ----------------------------------------------------------------------------------
   72.74 +size_t DefaultIOStream::Write(const void* pvBuffer, 
   72.75 +	size_t pSize,
   72.76 +	size_t pCount)
   72.77 +{
   72.78 +	ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
   72.79 +	return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0);
   72.80 +}
   72.81 +
   72.82 +// ----------------------------------------------------------------------------------
   72.83 +aiReturn DefaultIOStream::Seek(size_t pOffset,
   72.84 +	 aiOrigin pOrigin)
   72.85 +{
   72.86 +	if (!mFile) {
   72.87 +		return AI_FAILURE;
   72.88 +	}
   72.89 +
   72.90 +	// Just to check whether our enum maps one to one with the CRT constants
   72.91 +	BOOST_STATIC_ASSERT(aiOrigin_CUR == SEEK_CUR && 
   72.92 +		aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET);
   72.93 +
   72.94 +	// do the seek
   72.95 +	return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE);
   72.96 +}
   72.97 +
   72.98 +// ----------------------------------------------------------------------------------
   72.99 +size_t DefaultIOStream::Tell() const
  72.100 +{
  72.101 +	if (!mFile) {
  72.102 +		return 0;
  72.103 +	}
  72.104 +	return ::ftell(mFile);
  72.105 +}
  72.106 +
  72.107 +// ----------------------------------------------------------------------------------
  72.108 +size_t DefaultIOStream::FileSize() const
  72.109 +{
  72.110 +	if (! mFile || mFilename.empty()) {
  72.111 +		return 0;
  72.112 +	}
  72.113 +	
  72.114 +	if (SIZE_MAX == cachedSize) {
  72.115 +
  72.116 +		// TODO: Is that really faster if we're already owning a handle to the file?
  72.117 +#if defined _WIN32 && !defined __GNUC__
  72.118 +		struct __stat64 fileStat; 
  72.119 +		int err = _stat64(  mFilename.c_str(), &fileStat ); 
  72.120 +		if (0 != err) 
  72.121 +			return 0; 
  72.122 +		cachedSize = (size_t) (fileStat.st_size); 
  72.123 +#else
  72.124 +		struct stat fileStat; 
  72.125 +		int err = stat(mFilename.c_str(), &fileStat ); 
  72.126 +		if (0 != err) 
  72.127 +			return 0; 
  72.128 +		cachedSize = (size_t) (fileStat.st_size); 
  72.129 +#endif
  72.130 +	}
  72.131 +	return cachedSize;
  72.132 +}
  72.133 +
  72.134 +// ----------------------------------------------------------------------------------
  72.135 +void DefaultIOStream::Flush()
  72.136 +{
  72.137 +	if (mFile) {
  72.138 +		::fflush(mFile);
  72.139 +	}
  72.140 +}
  72.141 +
  72.142 +// ----------------------------------------------------------------------------------
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/libs/assimp/DefaultIOStream.h	Sat Feb 01 19:58:19 2014 +0200
    73.3 @@ -0,0 +1,133 @@
    73.4 +/*
    73.5 +Open Asset Import Library (assimp)
    73.6 +----------------------------------------------------------------------
    73.7 +
    73.8 +Copyright (c) 2006-2012, assimp team
    73.9 +All rights reserved.
   73.10 +
   73.11 +Redistribution and use of this software in source and binary forms, 
   73.12 +with or without modification, are permitted provided that the 
   73.13 +following conditions are met:
   73.14 +
   73.15 +* Redistributions of source code must retain the above
   73.16 +  copyright notice, this list of conditions and the
   73.17 +  following disclaimer.
   73.18 +
   73.19 +* Redistributions in binary form must reproduce the above
   73.20 +  copyright notice, this list of conditions and the
   73.21 +  following disclaimer in the documentation and/or other
   73.22 +  materials provided with the distribution.
   73.23 +
   73.24 +* Neither the name of the assimp team, nor the names of its
   73.25 +  contributors may be used to endorse or promote products
   73.26 +  derived from this software without specific prior
   73.27 +  written permission of the assimp team.
   73.28 +
   73.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   73.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   73.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   73.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   73.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   73.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   73.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   73.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   73.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   73.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   73.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   73.40 +
   73.41 +----------------------------------------------------------------------
   73.42 +*/
   73.43 +
   73.44 +/** @file Default file I/O using fXXX()-family of functions */
   73.45 +#ifndef AI_DEFAULTIOSTREAM_H_INC
   73.46 +#define AI_DEFAULTIOSTREAM_H_INC
   73.47 +
   73.48 +#include <stdio.h>
   73.49 +#include "assimp/IOStream.hpp"
   73.50 +
   73.51 +namespace Assimp	{
   73.52 +
   73.53 +// ----------------------------------------------------------------------------------
   73.54 +//!	@class	DefaultIOStream
   73.55 +//!	@brief	Default IO implementation, use standard IO operations
   73.56 +//! @note   An instance of this class can exist without a valid file handle
   73.57 +//!         attached to it. All calls fail, but the instance can nevertheless be
   73.58 +//!         used with no restrictions.
   73.59 +class DefaultIOStream : public IOStream
   73.60 +{
   73.61 +	friend class DefaultIOSystem;
   73.62 +
   73.63 +protected:
   73.64 +	DefaultIOStream ();
   73.65 +	DefaultIOStream (FILE* pFile, const std::string &strFilename);
   73.66 +
   73.67 +public:
   73.68 +	/** Destructor public to allow simple deletion to close the file. */
   73.69 +	~DefaultIOStream ();
   73.70 +
   73.71 +	// -------------------------------------------------------------------
   73.72 +	// Read from stream
   73.73 +    size_t Read(void* pvBuffer, 
   73.74 +		size_t pSize, 
   73.75 +		size_t pCount);
   73.76 +
   73.77 +
   73.78 +	// -------------------------------------------------------------------
   73.79 +	// Write to stream
   73.80 +    size_t Write(const void* pvBuffer, 
   73.81 +		size_t pSize,
   73.82 +		size_t pCount);
   73.83 +
   73.84 +	// -------------------------------------------------------------------
   73.85 +	// Seek specific position
   73.86 +	aiReturn Seek(size_t pOffset,
   73.87 +		aiOrigin pOrigin);
   73.88 +
   73.89 +	// -------------------------------------------------------------------
   73.90 +	// Get current seek position
   73.91 +    size_t Tell() const;
   73.92 +
   73.93 +	// -------------------------------------------------------------------
   73.94 +	// Get size of file
   73.95 +	size_t FileSize() const;
   73.96 +
   73.97 +	// -------------------------------------------------------------------
   73.98 +	// Flush file contents
   73.99 +	void Flush();
  73.100 +
  73.101 +private:
  73.102 +	//!	File datastructure, using clib
  73.103 +	FILE* mFile;
  73.104 +	//!	Filename
  73.105 +	std::string	mFilename;
  73.106 +
  73.107 +	//! Cached file size
  73.108 +	mutable size_t cachedSize;
  73.109 +};
  73.110 +
  73.111 +
  73.112 +// ----------------------------------------------------------------------------------
  73.113 +inline DefaultIOStream::DefaultIOStream () : 
  73.114 +	mFile		(NULL), 
  73.115 +	mFilename	(""),
  73.116 +	cachedSize	(SIZE_MAX)
  73.117 +{
  73.118 +	// empty
  73.119 +}
  73.120 +
  73.121 +
  73.122 +// ----------------------------------------------------------------------------------
  73.123 +inline DefaultIOStream::DefaultIOStream (FILE* pFile, 
  73.124 +		const std::string &strFilename) :
  73.125 +	mFile(pFile), 
  73.126 +	mFilename(strFilename),
  73.127 +	cachedSize	(SIZE_MAX)
  73.128 +{
  73.129 +	// empty
  73.130 +}
  73.131 +// ----------------------------------------------------------------------------------
  73.132 +
  73.133 +} // ns assimp
  73.134 +
  73.135 +#endif //!!AI_DEFAULTIOSTREAM_H_INC
  73.136 +
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/libs/assimp/DefaultIOSystem.cpp	Sat Feb 01 19:58:19 2014 +0200
    74.3 @@ -0,0 +1,167 @@
    74.4 +/*
    74.5 +---------------------------------------------------------------------------
    74.6 +Open Asset Import Library (assimp)
    74.7 +---------------------------------------------------------------------------
    74.8 +
    74.9 +Copyright (c) 2006-2012, assimp team
   74.10 +
   74.11 +All rights reserved.
   74.12 +
   74.13 +Redistribution and use of this software in source and binary forms, 
   74.14 +with or without modification, are permitted provided that the following 
   74.15 +conditions are met:
   74.16 +
   74.17 +* Redistributions of source code must retain the above
   74.18 +  copyright notice, this list of conditions and the
   74.19 +  following disclaimer.
   74.20 +
   74.21 +* Redistributions in binary form must reproduce the above
   74.22 +  copyright notice, this list of conditions and the
   74.23 +  following disclaimer in the documentation and/or other
   74.24 +  materials provided with the distribution.
   74.25 +
   74.26 +* Neither the name of the assimp team, nor the names of its
   74.27 +  contributors may be used to endorse or promote products
   74.28 +  derived from this software without specific prior
   74.29 +  written permission of the assimp team.
   74.30 +
   74.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   74.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   74.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   74.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   74.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   74.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   74.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   74.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   74.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   74.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   74.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   74.42 +---------------------------------------------------------------------------
   74.43 +*/
   74.44 +/** @file Default implementation of IOSystem using the standard C file functions */
   74.45 +
   74.46 +#include "AssimpPCH.h"
   74.47 +
   74.48 +#include <stdlib.h>
   74.49 +#include "DefaultIOSystem.h"
   74.50 +#include "DefaultIOStream.h"
   74.51 +
   74.52 +#ifdef __unix__
   74.53 +#include <sys/param.h>
   74.54 +#include <stdlib.h>
   74.55 +#endif
   74.56 +
   74.57 +using namespace Assimp;
   74.58 +
   74.59 +// ------------------------------------------------------------------------------------------------
   74.60 +// Constructor. 
   74.61 +DefaultIOSystem::DefaultIOSystem()
   74.62 +{
   74.63 +	// nothing to do here
   74.64 +}
   74.65 +
   74.66 +// ------------------------------------------------------------------------------------------------
   74.67 +// Destructor. 
   74.68 +DefaultIOSystem::~DefaultIOSystem()
   74.69 +{
   74.70 +	// nothing to do here
   74.71 +}
   74.72 +
   74.73 +// ------------------------------------------------------------------------------------------------
   74.74 +// Tests for the existence of a file at the given path.
   74.75 +bool DefaultIOSystem::Exists( const char* pFile) const
   74.76 +{
   74.77 +	FILE* file = ::fopen( pFile, "rb");
   74.78 +	if( !file)
   74.79 +		return false;
   74.80 +
   74.81 +	::fclose( file);
   74.82 +	return true;
   74.83 +}
   74.84 +
   74.85 +// ------------------------------------------------------------------------------------------------
   74.86 +// Open a new file with a given path.
   74.87 +IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
   74.88 +{
   74.89 +	ai_assert(NULL != strFile);
   74.90 +	ai_assert(NULL != strMode);
   74.91 +
   74.92 +	FILE* file = ::fopen( strFile, strMode);
   74.93 +	if( NULL == file) 
   74.94 +		return NULL;
   74.95 +
   74.96 +	return new DefaultIOStream(file, (std::string) strFile);
   74.97 +}
   74.98 +
   74.99 +// ------------------------------------------------------------------------------------------------
  74.100 +// Closes the given file and releases all resources associated with it.
  74.101 +void DefaultIOSystem::Close( IOStream* pFile)
  74.102 +{
  74.103 +	delete pFile;
  74.104 +}
  74.105 +
  74.106 +// ------------------------------------------------------------------------------------------------
  74.107 +// Returns the operation specific directory separator
  74.108 +char DefaultIOSystem::getOsSeparator() const
  74.109 +{
  74.110 +#ifndef _WIN32
  74.111 +	return '/';
  74.112 +#else
  74.113 +	return '\\';
  74.114 +#endif
  74.115 +}
  74.116 +
  74.117 +// ------------------------------------------------------------------------------------------------
  74.118 +// IOSystem default implementation (ComparePaths isn't a pure virtual function)
  74.119 +bool IOSystem::ComparePaths (const char* one, const char* second) const
  74.120 +{
  74.121 +	return !ASSIMP_stricmp(one,second);
  74.122 +}
  74.123 +
  74.124 +// maximum path length
  74.125 +// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html 
  74.126 +#ifdef PATH_MAX
  74.127 +#	define PATHLIMIT PATH_MAX
  74.128 +#else
  74.129 +#	define PATHLIMIT 4096
  74.130 +#endif
  74.131 +
  74.132 +// ------------------------------------------------------------------------------------------------
  74.133 +// Convert a relative path into an absolute path
  74.134 +inline void MakeAbsolutePath (const char* in, char* _out)
  74.135 +{
  74.136 +	ai_assert(in && _out);
  74.137 +	char* ret;
  74.138 +#ifdef _WIN32
  74.139 +	ret = ::_fullpath(_out, in,PATHLIMIT);
  74.140 +#else
  74.141 +    	// use realpath
  74.142 +    	ret = realpath(in, _out);
  74.143 +#endif  
  74.144 +	if(!ret) {
  74.145 +		// preserve the input path, maybe someone else is able to fix
  74.146 +		// the path before it is accessed (e.g. our file system filter)
  74.147 +		DefaultLogger::get()->warn("Invalid path: "+std::string(in));
  74.148 +		strcpy(_out,in);
  74.149 +	}  
  74.150 +}
  74.151 +
  74.152 +// ------------------------------------------------------------------------------------------------
  74.153 +// DefaultIOSystem's more specialized implementation
  74.154 +bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
  74.155 +{
  74.156 +	// chances are quite good both paths are formatted identically,
  74.157 +	// so we can hopefully return here already
  74.158 +	if( !ASSIMP_stricmp(one,second) )
  74.159 +		return true;
  74.160 +
  74.161 +	char temp1[PATHLIMIT];
  74.162 +	char temp2[PATHLIMIT];
  74.163 +	
  74.164 +	MakeAbsolutePath (one, temp1);
  74.165 +	MakeAbsolutePath (second, temp2);
  74.166 +
  74.167 +	return !ASSIMP_stricmp(temp1,temp2);
  74.168 +}
  74.169 +
  74.170 +#undef PATHLIMIT
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/libs/assimp/DefaultIOSystem.h	Sat Feb 01 19:58:19 2014 +0200
    75.3 @@ -0,0 +1,83 @@
    75.4 +/*
    75.5 +Open Asset Import Library (assimp)
    75.6 +----------------------------------------------------------------------
    75.7 +
    75.8 +Copyright (c) 2006-2012, assimp team
    75.9 +All rights reserved.
   75.10 +
   75.11 +Redistribution and use of this software in source and binary forms, 
   75.12 +with or without modification, are permitted provided that the 
   75.13 +following conditions are met:
   75.14 +
   75.15 +* Redistributions of source code must retain the above
   75.16 +  copyright notice, this list of conditions and the
   75.17 +  following disclaimer.
   75.18 +
   75.19 +* Redistributions in binary form must reproduce the above
   75.20 +  copyright notice, this list of conditions and the
   75.21 +  following disclaimer in the documentation and/or other
   75.22 +  materials provided with the distribution.
   75.23 +
   75.24 +* Neither the name of the assimp team, nor the names of its
   75.25 +  contributors may be used to endorse or promote products
   75.26 +  derived from this software without specific prior
   75.27 +  written permission of the assimp team.
   75.28 +
   75.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   75.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   75.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   75.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   75.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   75.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   75.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   75.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   75.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   75.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   75.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   75.40 +
   75.41 +----------------------------------------------------------------------
   75.42 +*/
   75.43 +
   75.44 +/** @file Default implementation of IOSystem using the standard C file functions */
   75.45 +#ifndef AI_DEFAULTIOSYSTEM_H_INC
   75.46 +#define AI_DEFAULTIOSYSTEM_H_INC
   75.47 +
   75.48 +#include "assimp/IOSystem.hpp"
   75.49 +
   75.50 +namespace Assimp	{
   75.51 +
   75.52 +// ---------------------------------------------------------------------------
   75.53 +/** Default implementation of IOSystem using the standard C file functions */
   75.54 +class DefaultIOSystem : public IOSystem
   75.55 +{
   75.56 +public:
   75.57 +	/** Constructor. */
   75.58 +    DefaultIOSystem();
   75.59 +
   75.60 +	/** Destructor. */
   75.61 +	~DefaultIOSystem();
   75.62 +
   75.63 +	// -------------------------------------------------------------------
   75.64 +	/** Tests for the existence of a file at the given path. */
   75.65 +	bool Exists( const char* pFile) const;
   75.66 +
   75.67 +	// -------------------------------------------------------------------
   75.68 +	/** Returns the directory separator. */
   75.69 +	char getOsSeparator() const;
   75.70 +
   75.71 +	// -------------------------------------------------------------------
   75.72 +	/** Open a new file with a given path. */
   75.73 +	IOStream* Open( const char* pFile, const char* pMode = "rb");
   75.74 +
   75.75 +	// -------------------------------------------------------------------
   75.76 +	/** Closes the given file and releases all resources associated with it. */
   75.77 +	void Close( IOStream* pFile);
   75.78 +
   75.79 +	// -------------------------------------------------------------------
   75.80 +	/** Compare two paths */
   75.81 +	bool ComparePaths (const char* one, const char* second) const;
   75.82 +};
   75.83 +
   75.84 +} //!ns Assimp
   75.85 +
   75.86 +#endif //AI_DEFAULTIOSYSTEM_H_INC
    76.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.2 +++ b/libs/assimp/DefaultLogger.cpp	Sat Feb 01 19:58:19 2014 +0200
    76.3 @@ -0,0 +1,423 @@
    76.4 +/*
    76.5 +---------------------------------------------------------------------------
    76.6 +Open Asset Import Library (assimp)
    76.7 +---------------------------------------------------------------------------
    76.8 +
    76.9 +Copyright (c) 2006-2012, assimp team
   76.10 +
   76.11 +All rights reserved.
   76.12 +
   76.13 +Redistribution and use of this software in source and binary forms, 
   76.14 +with or without modification, are permitted provided that the following 
   76.15 +conditions are met:
   76.16 +
   76.17 +* Redistributions of source code must retain the above
   76.18 +  copyright notice, this list of conditions and the
   76.19 +  following disclaimer.
   76.20 +
   76.21 +* Redistributions in binary form must reproduce the above
   76.22 +  copyright notice, this list of conditions and the
   76.23 +  following disclaimer in the documentation and/or other
   76.24 +  materials provided with the distribution.
   76.25 +
   76.26 +* Neither the name of the assimp team, nor the names of its
   76.27 +  contributors may be used to endorse or promote products
   76.28 +  derived from this software without specific prior
   76.29 +  written permission of the assimp team.
   76.30 +
   76.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   76.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   76.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   76.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   76.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   76.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   76.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   76.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   76.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   76.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   76.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   76.42 +---------------------------------------------------------------------------
   76.43 +*/
   76.44 +
   76.45 +/** @file  DefaultLogger.cpp
   76.46 + *  @brief Implementation of DefaultLogger (and Logger)
   76.47 + */
   76.48 +
   76.49 +#include "AssimpPCH.h"
   76.50 +#include "DefaultIOSystem.h"
   76.51 +
   76.52 +// Default log streams
   76.53 +#include "Win32DebugLogStream.h"
   76.54 +#include "StdOStreamLogStream.h"
   76.55 +#include "FileLogStream.h"
   76.56 +
   76.57 +#ifndef ASSIMP_BUILD_SINGLETHREADED
   76.58 +#	include <boost/thread/thread.hpp>
   76.59 +#	include <boost/thread/mutex.hpp>
   76.60 +
   76.61 +boost::mutex loggerMutex;
   76.62 +#endif
   76.63 +
   76.64 +namespace Assimp	{
   76.65 +
   76.66 +// ----------------------------------------------------------------------------------
   76.67 +NullLogger DefaultLogger::s_pNullLogger;
   76.68 +Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;
   76.69 +
   76.70 +static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
   76.71 +
   76.72 +// ----------------------------------------------------------------------------------
   76.73 +// Represents a log-stream + its error severity
   76.74 +struct LogStreamInfo
   76.75 +{
   76.76 +	unsigned int m_uiErrorSeverity;
   76.77 +	LogStream *m_pStream;
   76.78 +
   76.79 +	// Constructor
   76.80 +	LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) :
   76.81 +		m_uiErrorSeverity( uiErrorSev ),
   76.82 +		m_pStream( pStream )
   76.83 +	{
   76.84 +		// empty
   76.85 +	}
   76.86 +	
   76.87 +	// Destructor
   76.88 +	~LogStreamInfo()
   76.89 +	{
   76.90 +		delete m_pStream;
   76.91 +	}
   76.92 +};
   76.93 +
   76.94 +// ----------------------------------------------------------------------------------
   76.95 +// Construct a default log stream
   76.96 +LogStream* LogStream::createDefaultStream(aiDefaultLogStream	streams,
   76.97 +	const char* name /*= "AssimpLog.txt"*/,
   76.98 +	IOSystem* io		    /*= NULL*/)
   76.99 +{
  76.100 +	switch (streams)	
  76.101 +	{
  76.102 +		// This is a platform-specific feature
  76.103 +	case aiDefaultLogStream_DEBUGGER:
  76.104 +#ifdef WIN32
  76.105 +		return new Win32DebugLogStream();
  76.106 +#else
  76.107 +		return NULL;
  76.108 +#endif
  76.109 +
  76.110 +		// Platform-independent default streams
  76.111 +	case aiDefaultLogStream_STDERR:
  76.112 +		return new StdOStreamLogStream(std::cerr);
  76.113 +	case aiDefaultLogStream_STDOUT:
  76.114 +		return new StdOStreamLogStream(std::cout);
  76.115 +	case aiDefaultLogStream_FILE:
  76.116 +		return (name && *name ? new FileLogStream(name,io) : NULL);
  76.117 +	default:
  76.118 +		// We don't know this default log stream, so raise an assertion
  76.119 +		ai_assert(false);
  76.120 +
  76.121 +	};
  76.122 +
  76.123 +	// For compilers without dead code path detection
  76.124 +	return NULL;
  76.125 +}
  76.126 +
  76.127 +// ----------------------------------------------------------------------------------
  76.128 +//	Creates the only singleton instance
  76.129 +Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
  76.130 +	LogSeverity severity                       /*= NORMAL*/,
  76.131 +	unsigned int defStreams                    /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
  76.132 +	IOSystem* io		                       /*= NULL*/)
  76.133 +{
  76.134 +	// enter the mutex here to avoid concurrency problems
  76.135 +#ifndef ASSIMP_BUILD_SINGLETHREADED
  76.136 +	boost::mutex::scoped_lock lock(loggerMutex);
  76.137 +#endif
  76.138 +
  76.139 +	if (m_pLogger && !isNullLogger() )
  76.140 +		delete m_pLogger;
  76.141 +
  76.142 +	m_pLogger = new DefaultLogger( severity );
  76.143 +
  76.144 +	// Attach default log streams
  76.145 +	// Stream the log to the MSVC debugger?
  76.146 +	if (defStreams & aiDefaultLogStream_DEBUGGER)
  76.147 +		m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));
  76.148 +
  76.149 +	// Stream the log to COUT?
  76.150 +	if (defStreams & aiDefaultLogStream_STDOUT)
  76.151 +		m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));
  76.152 +
  76.153 +	// Stream the log to CERR?
  76.154 +	if (defStreams & aiDefaultLogStream_STDERR)
  76.155 +		 m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));
  76.156 +	
  76.157 +	// Stream the log to a file
  76.158 +	if (defStreams & aiDefaultLogStream_FILE && name && *name)
  76.159 +		m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));
  76.160 +
  76.161 +	return m_pLogger;
  76.162 +}
  76.163 +
  76.164 +// ----------------------------------------------------------------------------------
  76.165 +void Logger::debug(const char* message)	{
  76.166 +
  76.167 +	// SECURITY FIX: otherwise it's easy to produce overruns since
  76.168 +	// sometimes importers will include data from the input file
  76.169 +	// (i.e. node names) in their messages.
  76.170 +	if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
  76.171 +		ai_assert(false);
  76.172 +		return;
  76.173 +	}
  76.174 +	return OnDebug(message);
  76.175 +}
  76.176 +
  76.177 +// ----------------------------------------------------------------------------------
  76.178 +void Logger::info(const char* message)	{
  76.179 +	
  76.180 +	// SECURITY FIX: see above
  76.181 +	if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
  76.182 +		ai_assert(false);
  76.183 +		return;
  76.184 +	}
  76.185 +	return OnInfo(message);
  76.186 +}
  76.187 +	
  76.188 +// ----------------------------------------------------------------------------------
  76.189 +void Logger::warn(const char* message)	{
  76.190 +	
  76.191 +	// SECURITY FIX: see above
  76.192 +	if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
  76.193 +		ai_assert(false);
  76.194 +		return;
  76.195 +	}
  76.196 +	return OnWarn(message);
  76.197 +}
  76.198 +
  76.199 +// ----------------------------------------------------------------------------------
  76.200 +void Logger::error(const char* message)	{
  76.201 +	
  76.202 +	// SECURITY FIX: see above
  76.203 +	if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
  76.204 +		ai_assert(false);
  76.205 +		return;
  76.206 +	}
  76.207 +	return OnError(message);
  76.208 +}
  76.209 +
  76.210 +// ----------------------------------------------------------------------------------
  76.211 +void DefaultLogger::set( Logger *logger )
  76.212 +{
  76.213 +	// enter the mutex here to avoid concurrency problems
  76.214 +#ifndef ASSIMP_BUILD_SINGLETHREADED
  76.215 +	boost::mutex::scoped_lock lock(loggerMutex);
  76.216 +#endif
  76.217 +
  76.218 +	if (!logger)logger = &s_pNullLogger;
  76.219 +	if (m_pLogger && !isNullLogger() )
  76.220 +		delete m_pLogger;
  76.221 +
  76.222 +	DefaultLogger::m_pLogger = logger;
  76.223 +}
  76.224 +
  76.225 +// ----------------------------------------------------------------------------------
  76.226 +bool DefaultLogger::isNullLogger()
  76.227 +{
  76.228 +	return m_pLogger == &s_pNullLogger;
  76.229 +}
  76.230 +
  76.231 +// ----------------------------------------------------------------------------------
  76.232 +//	Singleton getter
  76.233 +Logger *DefaultLogger::get()
  76.234 +{
  76.235 +	return m_pLogger;
  76.236 +}
  76.237 +
  76.238 +// ----------------------------------------------------------------------------------
  76.239 +//	Kills the only instance
  76.240 +void DefaultLogger::kill()
  76.241 +{
  76.242 +	// enter the mutex here to avoid concurrency problems
  76.243 +#ifndef ASSIMP_BUILD_SINGLETHREADED
  76.244 +	boost::mutex::scoped_lock lock(loggerMutex);
  76.245 +#endif
  76.246 +
  76.247 +	if (m_pLogger == &s_pNullLogger)return;
  76.248 +	delete m_pLogger;
  76.249 +	m_pLogger = &s_pNullLogger;
  76.250 +}
  76.251 +
  76.252 +// ----------------------------------------------------------------------------------
  76.253 +//	Debug message
  76.254 +void DefaultLogger::OnDebug( const char* message )
  76.255 +{
  76.256 +	if ( m_Severity == Logger::NORMAL )
  76.257 +		return;
  76.258 +
  76.259 +	char msg[MAX_LOG_MESSAGE_LENGTH*2];
  76.260 +	::sprintf(msg,"Debug, T%i: %s", GetThreadID(), message );
  76.261 +
  76.262 +	WriteToStreams( msg, Logger::Debugging );
  76.263 +}
  76.264 +
  76.265 +// ----------------------------------------------------------------------------------
  76.266 +//	Logs an info
  76.267 +void DefaultLogger::OnInfo( const char* message )
  76.268 +{
  76.269 +	char msg[MAX_LOG_MESSAGE_LENGTH*2];
  76.270 +	::sprintf(msg,"Info,  T%i: %s", GetThreadID(), message );
  76.271 +
  76.272 +	WriteToStreams( msg , Logger::Info );
  76.273 +}
  76.274 +
  76.275 +// ----------------------------------------------------------------------------------
  76.276 +//	Logs a warning
  76.277 +void DefaultLogger::OnWarn( const char* message )
  76.278 +{
  76.279 +	char msg[MAX_LOG_MESSAGE_LENGTH*2];
  76.280 +	::sprintf(msg,"Warn,  T%i: %s", GetThreadID(), message );
  76.281 +
  76.282 +	WriteToStreams( msg, Logger::Warn );
  76.283 +}
  76.284 +
  76.285 +// ----------------------------------------------------------------------------------
  76.286 +//	Logs an error
  76.287 +void DefaultLogger::OnError( const char* message )
  76.288 +{
  76.289 +	char msg[MAX_LOG_MESSAGE_LENGTH*2];
  76.290 +	::sprintf(msg,"Error, T%i: %s", GetThreadID(), message );
  76.291 +
  76.292 +	WriteToStreams( msg, Logger::Err );
  76.293 +}
  76.294 +
  76.295 +// ----------------------------------------------------------------------------------
  76.296 +//	Will attach a new stream
  76.297 +bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
  76.298 +{
  76.299 +	if (!pStream)
  76.300 +		return false;
  76.301 +
  76.302 +	if (0 == severity)	{
  76.303 +		severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
  76.304 +	}
  76.305 +
  76.306 +	for ( StreamIt it = m_StreamArray.begin();
  76.307 +		it != m_StreamArray.end();
  76.308 +		++it )
  76.309 +	{
  76.310 +		if ( (*it)->m_pStream == pStream )
  76.311 +		{
  76.312 +			(*it)->m_uiErrorSeverity |= severity;
  76.313 +			return true;
  76.314 +		}
  76.315 +	}
  76.316 +	
  76.317 +	LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
  76.318 +	m_StreamArray.push_back( pInfo );
  76.319 +	return true;
  76.320 +}
  76.321 +
  76.322 +// ----------------------------------------------------------------------------------
  76.323 +//	Detatch a stream
  76.324 +bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
  76.325 +{
  76.326 +	if (!pStream)
  76.327 +		return false;
  76.328 +
  76.329 +	if (0 == severity)	{
  76.330 +		severity = SeverityAll;
  76.331 +	}
  76.332 +	
  76.333 +	for ( StreamIt it = m_StreamArray.begin();
  76.334 +		it != m_StreamArray.end();
  76.335 +		++it )
  76.336 +	{
  76.337 +		if ( (*it)->m_pStream == pStream )
  76.338 +		{
  76.339 +			(*it)->m_uiErrorSeverity &= ~severity;
  76.340 +			if ( (*it)->m_uiErrorSeverity == 0 )
  76.341 +			{
  76.342 +				// don't delete the underlying stream 'cause the caller gains ownership again
  76.343 +				(**it).m_pStream = NULL;
  76.344 +				delete *it;
  76.345 +				m_StreamArray.erase( it );
  76.346 +				break;
  76.347 +			}
  76.348 +			return true;
  76.349 +		}
  76.350 +	}
  76.351 +	return false;
  76.352 +}
  76.353 +
  76.354 +// ----------------------------------------------------------------------------------
  76.355 +//	Constructor
  76.356 +DefaultLogger::DefaultLogger(LogSeverity severity) 
  76.357 +
  76.358 +	:	Logger	( severity )
  76.359 +	,	noRepeatMsg	(false)
  76.360 +	,	lastLen( 0 )
  76.361 +{
  76.362 +	lastMsg[0] = '\0';
  76.363 +}
  76.364 +
  76.365 +// ----------------------------------------------------------------------------------
  76.366 +//	Destructor
  76.367 +DefaultLogger::~DefaultLogger()
  76.368 +{
  76.369 +	for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
  76.370 +		// also frees the underlying stream, we are its owner.
  76.371 +		delete *it;
  76.372 +	}
  76.373 +}
  76.374 +
  76.375 +// ----------------------------------------------------------------------------------
  76.376 +//	Writes message to stream
  76.377 +void DefaultLogger::WriteToStreams(const char *message, 
  76.378 +	ErrorSeverity ErrorSev )
  76.379 +{
  76.380 +	ai_assert(NULL != message);
  76.381 +
  76.382 +	// Check whether this is a repeated message
  76.383 +	if (! ::strncmp( message,lastMsg, lastLen-1))
  76.384 +	{
  76.385 +		if (!noRepeatMsg)
  76.386 +		{
  76.387 +			noRepeatMsg = true;
  76.388 +			message = "Skipping one or more lines with the same contents\n";
  76.389 +		}
  76.390 +		else return;
  76.391 +	}
  76.392 +	else
  76.393 +	{
  76.394 +		// append a new-line character to the message to be printed
  76.395 +		lastLen = ::strlen(message);
  76.396 +		::memcpy(lastMsg,message,lastLen+1);
  76.397 +		::strcat(lastMsg+lastLen,"\n");
  76.398 +
  76.399 +		message = lastMsg;
  76.400 +		noRepeatMsg = false;
  76.401 +		++lastLen;
  76.402 +	}
  76.403 +	for ( ConstStreamIt it = m_StreamArray.begin();
  76.404 +		it != m_StreamArray.end();
  76.405 +		++it)
  76.406 +	{
  76.407 +		if ( ErrorSev & (*it)->m_uiErrorSeverity )
  76.408 +			(*it)->m_pStream->write( message);
  76.409 +	}
  76.410 +}
  76.411 +
  76.412 +// ----------------------------------------------------------------------------------
  76.413 +//	Returns thread id, if not supported only a zero will be returned.
  76.414 +unsigned int DefaultLogger::GetThreadID()
  76.415 +{
  76.416 +	// fixme: we can get this value via boost::threads
  76.417 +#ifdef WIN32
  76.418 +	return (unsigned int)::GetCurrentThreadId();
  76.419 +#else
  76.420 +	return 0; // not supported
  76.421 +#endif
  76.422 +}
  76.423 +
  76.424 +// ----------------------------------------------------------------------------------
  76.425 +
  76.426 +} // !namespace Assimp
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/libs/assimp/DefaultProgressHandler.h	Sat Feb 01 19:58:19 2014 +0200
    77.3 @@ -0,0 +1,64 @@
    77.4 +/*
    77.5 +Open Asset Import Library (assimp)
    77.6 +----------------------------------------------------------------------
    77.7 +
    77.8 +Copyright (c) 2006-2012, assimp team
    77.9 +All rights reserved.
   77.10 +
   77.11 +Redistribution and use of this software in source and binary forms, 
   77.12 +with or without modification, are permitted provided that the 
   77.13 +following conditions are met:
   77.14 +
   77.15 +* Redistributions of source code must retain the above
   77.16 +  copyright notice, this list of conditions and the
   77.17 +  following disclaimer.
   77.18 +
   77.19 +* Redistributions in binary form must reproduce the above
   77.20 +  copyright notice, this list of conditions and the
   77.21 +  following disclaimer in the documentation and/or other
   77.22 +  materials provided with the distribution.
   77.23 +
   77.24 +* Neither the name of the assimp team, nor the names of its
   77.25 +  contributors may be used to endorse or promote products
   77.26 +  derived from this software without specific prior
   77.27 +  written permission of the assimp team.
   77.28 +
   77.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   77.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   77.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   77.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   77.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   77.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   77.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   77.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   77.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   77.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   77.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   77.40 +
   77.41 +----------------------------------------------------------------------
   77.42 +*/
   77.43 +
   77.44 +/** @file ProgressHandler.hpp
   77.45 + *  @brief Abstract base class 'ProgressHandler'.
   77.46 + */
   77.47 +#ifndef INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
   77.48 +#define INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
   77.49 +
   77.50 +#include "assimp/ProgressHandler.hpp"
   77.51 +namespace Assimp	{
   77.52 +
   77.53 +// ------------------------------------------------------------------------------------
   77.54 +/** @brief Internal default implementation of the #ProgressHandler interface. */
   77.55 +class DefaultProgressHandler 
   77.56 +	: public ProgressHandler	{
   77.57 +
   77.58 +	
   77.59 +	virtual bool Update(float /*percentage*/) {
   77.60 +		return false;
   77.61 +	}
   77.62 +
   77.63 +
   77.64 +}; // !class DefaultProgressHandler 
   77.65 +} // Namespace Assimp
   77.66 +
   77.67 +#endif
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/libs/assimp/Exceptional.h	Sat Feb 01 19:58:19 2014 +0200
    78.3 @@ -0,0 +1,124 @@
    78.4 +/*
    78.5 +Open Asset Import Library (assimp)
    78.6 +----------------------------------------------------------------------
    78.7 +
    78.8 +Copyright (c) 2006-2008, assimp team
    78.9 +All rights reserved.
   78.10 +
   78.11 +Redistribution and use of this software in source and binary forms, 
   78.12 +with or without modification, are permitted provided that the 
   78.13 +following conditions are met:
   78.14 +
   78.15 +* Redistributions of source code must retain the above
   78.16 +  copyright notice, this list of conditions and the
   78.17 +  following disclaimer.
   78.18 +
   78.19 +* Redistributions in binary form must reproduce the above
   78.20 +  copyright notice, this list of conditions and the
   78.21 +  following disclaimer in the documentation and/or other
   78.22 +  materials provided with the distribution.
   78.23 +
   78.24 +* Neither the name of the assimp team, nor the names of its
   78.25 +  contributors may be used to endorse or promote products
   78.26 +  derived from this software without specific prior
   78.27 +  written permission of the assimp team.
   78.28 +
   78.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   78.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   78.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   78.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   78.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   78.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   78.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   78.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   78.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   78.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   78.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   78.40 +
   78.41 +----------------------------------------------------------------------
   78.42 +*/
   78.43 +
   78.44 +#ifndef INCLUDED_EXCEPTIONAL_H
   78.45 +#define INCLUDED_EXCEPTIONAL_H
   78.46 +
   78.47 +#include <stdexcept>
   78.48 +using std::runtime_error;
   78.49 +
   78.50 +#ifdef _MSC_VER
   78.51 +#	pragma warning(disable : 4275)
   78.52 +#endif
   78.53 +
   78.54 +// ---------------------------------------------------------------------------
   78.55 +/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an 
   78.56 + *  unrecoverable error occurs while importing. Loading APIs return
   78.57 + *  NULL instead of a valid aiScene then.  */
   78.58 +class DeadlyImportError
   78.59 +	: public runtime_error
   78.60 +{
   78.61 +public:
   78.62 +	/** Constructor with arguments */
   78.63 +	explicit DeadlyImportError( const std::string& pErrorText)
   78.64 +		: runtime_error(pErrorText)
   78.65 +	{
   78.66 +	}
   78.67 +
   78.68 +private:
   78.69 +};
   78.70 +
   78.71 +typedef DeadlyImportError DeadlyExportError;
   78.72 +
   78.73 +#ifdef _MSC_VER
   78.74 +#	pragma warning(default : 4275)
   78.75 +#endif
   78.76 +
   78.77 +// ---------------------------------------------------------------------------
   78.78 +template <typename T>
   78.79 +struct ExceptionSwallower	{
   78.80 +	T operator ()() const {
   78.81 +		return T();
   78.82 +	}
   78.83 +};
   78.84 +
   78.85 +// ---------------------------------------------------------------------------
   78.86 +template <typename T>
   78.87 +struct ExceptionSwallower<T*>	{
   78.88 +	T* operator ()() const {
   78.89 +		return NULL;
   78.90 +	}
   78.91 +};
   78.92 +
   78.93 +// ---------------------------------------------------------------------------
   78.94 +template <>
   78.95 +struct ExceptionSwallower<aiReturn>	{
   78.96 +	aiReturn operator ()() const {
   78.97 +		try {
   78.98 +			throw;
   78.99 +		}
  78.100 +		catch (std::bad_alloc&) {
  78.101 +			return aiReturn_OUTOFMEMORY;
  78.102 +		}
  78.103 +		catch (...) {
  78.104 +			return aiReturn_FAILURE;
  78.105 +		}
  78.106 +	}
  78.107 +};
  78.108 +
  78.109 +// ---------------------------------------------------------------------------
  78.110 +template <>
  78.111 +struct ExceptionSwallower<void>	{
  78.112 +	void operator ()() const {
  78.113 +		return;
  78.114 +	}
  78.115 +};
  78.116 +
  78.117 +#define ASSIMP_BEGIN_EXCEPTION_REGION()\
  78.118 +{\
  78.119 +	try {
  78.120 +
  78.121 +#define ASSIMP_END_EXCEPTION_REGION(type)\
  78.122 +	} catch(...) {\
  78.123 +		return ExceptionSwallower<type>()();\
  78.124 +	}\
  78.125 +}
  78.126 +
  78.127 +#endif // INCLUDED_EXCEPTIONAL_H
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/libs/assimp/Exporter.cpp	Sat Feb 01 19:58:19 2014 +0200
    79.3 @@ -0,0 +1,414 @@
    79.4 +/*
    79.5 +---------------------------------------------------------------------------
    79.6 +Open Asset Import Library (assimp)
    79.7 +---------------------------------------------------------------------------
    79.8 +
    79.9 +Copyright (c) 2006-2012, assimp team
   79.10 +
   79.11 +All rights reserved.
   79.12 +
   79.13 +Redistribution and use of this software in source and binary forms, 
   79.14 +with or without modification, are permitted provided that the following 
   79.15 +conditions are met:
   79.16 +
   79.17 +* Redistributions of source code must retain the above
   79.18 +  copyright notice, this list of conditions and the
   79.19 +  following disclaimer.
   79.20 +
   79.21 +* Redistributions in binary form must reproduce the above
   79.22 +  copyright notice, this list of conditions and the
   79.23 +  following disclaimer in the documentation and/or other
   79.24 +  materials provided with the distribution.
   79.25 +
   79.26 +* Neither the name of the assimp team, nor the names of its
   79.27 +  contributors may be used to endorse or promote products
   79.28 +  derived from this software without specific prior
   79.29 +  written permission of the assimp team.
   79.30 +
   79.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   79.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   79.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   79.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   79.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   79.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   79.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   79.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   79.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   79.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   79.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   79.42 +---------------------------------------------------------------------------
   79.43 +*/
   79.44 +
   79.45 +/** @file Exporter.cpp
   79.46 +
   79.47 +Assimp export interface. While it's public interface bears many similarities
   79.48 +to the import interface (in fact, it is largely symmetric), the internal
   79.49 +implementations differs a lot. Exporters are considered stateless and are
   79.50 +simple callbacks which we maintain in a global list along with their
   79.51 +description strings.
   79.52 +
   79.53 +Here we implement only the C++ interface (Assimp::Exporter).
   79.54 +*/
   79.55 +
   79.56 +#include "AssimpPCH.h"
   79.57 +
   79.58 +#ifndef ASSIMP_BUILD_NO_EXPORT
   79.59 +
   79.60 +#include "DefaultIOSystem.h"
   79.61 +#include "BlobIOSystem.h" 
   79.62 +#include "SceneCombiner.h" 
   79.63 +#include "BaseProcess.h" 
   79.64 +#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
   79.65 +
   79.66 +#include "MakeVerboseFormat.h"
   79.67 +#include "ConvertToLHProcess.h"
   79.68 +
   79.69 +namespace Assimp {
   79.70 +
   79.71 +// PostStepRegistry.cpp
   79.72 +void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
   79.73 +
   79.74 +// ------------------------------------------------------------------------------------------------
   79.75 +// Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype
   79.76 +void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
   79.77 +void ExportSceneObj(const char*,IOSystem*, const aiScene*);
   79.78 +void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
   79.79 +void ExportScenePly(const char*,IOSystem*, const aiScene*);
   79.80 +void ExportScene3DS(const char*, IOSystem*, const aiScene*) {}
   79.81 +
   79.82 +// ------------------------------------------------------------------------------------------------
   79.83 +// global array of all export formats which Assimp supports in its current build
   79.84 +Exporter::ExportFormatEntry gExporters[] = 
   79.85 +{
   79.86 +#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
   79.87 +	Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada),
   79.88 +#endif
   79.89 +
   79.90 +#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
   79.91 +	Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj, 
   79.92 +		aiProcess_GenNormals | aiProcess_PreTransformVertices),
   79.93 +#endif
   79.94 +
   79.95 +#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
   79.96 +	Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL, 
   79.97 +		aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
   79.98 +	),
   79.99 +#endif
  79.100 +
  79.101 +#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
  79.102 +	Exporter::ExportFormatEntry( "ply", "Stanford Polygon Library", "ply" , &ExportScenePly, 
  79.103 +		aiProcess_PreTransformVertices
  79.104 +	),
  79.105 +#endif
  79.106 +
  79.107 +//#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
  79.108 +//	ExportFormatEntry( "3ds", "Autodesk 3DS (legacy format)", "3ds" , &ExportScene3DS),
  79.109 +//#endif
  79.110 +};
  79.111 +
  79.112 +#define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0]))
  79.113 +
  79.114 +
  79.115 +class ExporterPimpl {
  79.116 +public:
  79.117 +
  79.118 +	ExporterPimpl()
  79.119 +		: blob()
  79.120 +		, mIOSystem(new Assimp::DefaultIOSystem())
  79.121 +		, mIsDefaultIOHandler(true)
  79.122 +	{
  79.123 +		GetPostProcessingStepInstanceList(mPostProcessingSteps);
  79.124 +
  79.125 +		// grab all builtin exporters
  79.126 +		mExporters.resize(ASSIMP_NUM_EXPORTERS);
  79.127 +		std::copy(gExporters,gExporters+ASSIMP_NUM_EXPORTERS,mExporters.begin());
  79.128 +	}
  79.129 +
  79.130 +	~ExporterPimpl() 
  79.131 +	{
  79.132 +		delete blob;
  79.133 +
  79.134 +		// Delete all post-processing plug-ins
  79.135 +		for( unsigned int a = 0; a < mPostProcessingSteps.size(); a++) {
  79.136 +			delete mPostProcessingSteps[a];
  79.137 +		}
  79.138 +	}
  79.139 +
  79.140 +public:
  79.141 +		
  79.142 +	aiExportDataBlob* blob;
  79.143 +	boost::shared_ptr< Assimp::IOSystem > mIOSystem;
  79.144 +	bool mIsDefaultIOHandler;
  79.145 +
  79.146 +	/** Post processing steps we can apply at the imported data. */
  79.147 +	std::vector< BaseProcess* > mPostProcessingSteps;
  79.148 +
  79.149 +	/** Last fatal export error */
  79.150 +	std::string mError;
  79.151 +
  79.152 +	/** Exporters, this includes those registered using #Assimp::Exporter::RegisterExporter */
  79.153 +	std::vector<Exporter::ExportFormatEntry> mExporters;
  79.154 +};
  79.155 +
  79.156 +
  79.157 +} // end of namespace Assimp
  79.158 +
  79.159 +
  79.160 +
  79.161 +
  79.162 +
  79.163 +using namespace Assimp;
  79.164 +
  79.165 +
  79.166 +// ------------------------------------------------------------------------------------------------
  79.167 +Exporter :: Exporter() 
  79.168 +: pimpl(new ExporterPimpl())
  79.169 +{
  79.170 +}
  79.171 +
  79.172 +
  79.173 +// ------------------------------------------------------------------------------------------------
  79.174 +Exporter :: ~Exporter()
  79.175 +{
  79.176 +	FreeBlob();
  79.177 +}
  79.178 +
  79.179 +
  79.180 +// ------------------------------------------------------------------------------------------------
  79.181 +void Exporter :: SetIOHandler( IOSystem* pIOHandler)
  79.182 +{
  79.183 +	pimpl->mIsDefaultIOHandler = !pIOHandler;
  79.184 +	pimpl->mIOSystem.reset(pIOHandler);
  79.185 +}
  79.186 +
  79.187 +
  79.188 +// ------------------------------------------------------------------------------------------------
  79.189 +IOSystem* Exporter :: GetIOHandler() const
  79.190 +{
  79.191 +	return pimpl->mIOSystem.get();
  79.192 +}
  79.193 +
  79.194 +
  79.195 +// ------------------------------------------------------------------------------------------------
  79.196 +bool Exporter :: IsDefaultIOHandler() const
  79.197 +{
  79.198 +	return pimpl->mIsDefaultIOHandler;
  79.199 +}
  79.200 +
  79.201 +
  79.202 +// ------------------------------------------------------------------------------------------------
  79.203 +const aiExportDataBlob* Exporter :: ExportToBlob(  const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing )
  79.204 +{
  79.205 +	if (pimpl->blob) {
  79.206 +		delete pimpl->blob;
  79.207 +		pimpl->blob = NULL;
  79.208 +	}
  79.209 +
  79.210 +
  79.211 +	boost::shared_ptr<IOSystem> old = pimpl->mIOSystem;
  79.212 +
  79.213 +	BlobIOSystem* blobio = new BlobIOSystem();
  79.214 +	pimpl->mIOSystem = boost::shared_ptr<IOSystem>( blobio );
  79.215 +
  79.216 +	if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
  79.217 +		pimpl->mIOSystem = old;
  79.218 +		return NULL;
  79.219 +	}
  79.220 +
  79.221 +	pimpl->blob = blobio->GetBlobChain();
  79.222 +	pimpl->mIOSystem = old;
  79.223 +
  79.224 +	return pimpl->blob;
  79.225 +}
  79.226 +
  79.227 +
  79.228 +// ------------------------------------------------------------------------------------------------
  79.229 +aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing )
  79.230 +{
  79.231 +	ASSIMP_BEGIN_EXCEPTION_REGION();
  79.232 +
  79.233 +	pimpl->mError = "";
  79.234 +	for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
  79.235 +		const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i];
  79.236 +		if (!strcmp(exp.mDescription.id,pFormatId)) {
  79.237 +
  79.238 +			try {
  79.239 +
  79.240 +				// Always create a full copy of the scene. We might optimize this one day, 
  79.241 +				// but for now it is the most pragmatic way.
  79.242 +				aiScene* scenecopy_tmp;
  79.243 +				SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
  79.244 +
  79.245 +				std::auto_ptr<aiScene> scenecopy(scenecopy_tmp);
  79.246 +				const ScenePrivateData* const priv = ScenePriv(pScene);
  79.247 +
  79.248 +				// steps that are not idempotent, i.e. we might need to run them again, usually to get back to the
  79.249 +				// original state before the step was applied first. When checking which steps we don't need
  79.250 +				// to run, those are excluded.
  79.251 +				const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded;
  79.252 +
  79.253 +				// Erase all pp steps that were already applied to this scene
  79.254 +				unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv 
  79.255 +					? (priv->mPPStepsApplied & ~nonIdempotentSteps)
  79.256 +					: 0u);
  79.257 +
  79.258 +				// If no extra postprocessing was specified, and we obtained this scene from an
  79.259 +				// Assimp importer, apply the reverse steps automatically.
  79.260 +				if (!pPreprocessing && priv) {
  79.261 +					pp |= (nonIdempotentSteps & priv->mPPStepsApplied);
  79.262 +				}
  79.263 +
  79.264 +				// If the input scene is not in verbose format, but there is at least postprocessing step that relies on it,
  79.265 +				// we need to run the MakeVerboseFormat step first.
  79.266 +				if (scenecopy->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
  79.267 +					
  79.268 +					bool verbosify = false;
  79.269 +					for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
  79.270 +						BaseProcess* const p = pimpl->mPostProcessingSteps[a];
  79.271 +
  79.272 +						if (p->IsActive(pp) && p->RequireVerboseFormat()) {
  79.273 +							verbosify = true;
  79.274 +							break;
  79.275 +						}
  79.276 +					}
  79.277 +
  79.278 +					if (verbosify || (exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
  79.279 +						DefaultLogger::get()->debug("export: Scene data not in verbose format, applying MakeVerboseFormat step first");
  79.280 +
  79.281 +						MakeVerboseFormatProcess proc;
  79.282 +						proc.Execute(scenecopy.get());
  79.283 +					}
  79.284 +				}
  79.285 +
  79.286 +				if (pp) {
  79.287 +					// the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout
  79.288 +					{
  79.289 +						FlipWindingOrderProcess step;
  79.290 +						if (step.IsActive(pp)) {
  79.291 +							step.Execute(scenecopy.get());
  79.292 +						}
  79.293 +					}
  79.294 +					
  79.295 +					{
  79.296 +						FlipUVsProcess step;
  79.297 +						if (step.IsActive(pp)) {
  79.298 +							step.Execute(scenecopy.get());
  79.299 +						}
  79.300 +					}
  79.301 +
  79.302 +					{
  79.303 +						MakeLeftHandedProcess step;
  79.304 +						if (step.IsActive(pp)) {
  79.305 +							step.Execute(scenecopy.get());
  79.306 +						}
  79.307 +					}
  79.308 +
  79.309 +					// dispatch other processes
  79.310 +					for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
  79.311 +						BaseProcess* const p = pimpl->mPostProcessingSteps[a];
  79.312 +
  79.313 +						if (p->IsActive(pp) 
  79.314 +							&& !dynamic_cast<FlipUVsProcess*>(p) 
  79.315 +							&& !dynamic_cast<FlipWindingOrderProcess*>(p) 
  79.316 +							&& !dynamic_cast<MakeLeftHandedProcess*>(p)) {
  79.317 +
  79.318 +							p->Execute(scenecopy.get());
  79.319 +						}
  79.320 +					}
  79.321 +					ScenePrivateData* const privOut = ScenePriv(scenecopy.get());
  79.322 +					ai_assert(privOut);
  79.323 +
  79.324 +					privOut->mPPStepsApplied |= pp;
  79.325 +				}
  79.326 +
  79.327 +				exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get());
  79.328 +			}
  79.329 +			catch (DeadlyExportError& err) {
  79.330 +				pimpl->mError = err.what();
  79.331 +				return AI_FAILURE;
  79.332 +			}
  79.333 +			return AI_SUCCESS;
  79.334 +		}
  79.335 +	}
  79.336 +
  79.337 +	pimpl->mError = std::string("Found no exporter to handle this file format: ") + pFormatId;
  79.338 +	ASSIMP_END_EXCEPTION_REGION(aiReturn);
  79.339 +	return AI_FAILURE;
  79.340 +}
  79.341 +
  79.342 +
  79.343 +// ------------------------------------------------------------------------------------------------
  79.344 +const char* Exporter :: GetErrorString() const
  79.345 +{
  79.346 +	return pimpl->mError.c_str();
  79.347 +}
  79.348 +
  79.349 +
  79.350 +// ------------------------------------------------------------------------------------------------
  79.351 +void Exporter :: FreeBlob( )
  79.352 +{
  79.353 +	delete pimpl->blob;
  79.354 +	pimpl->blob = NULL;
  79.355 +
  79.356 +	pimpl->mError = "";
  79.357 +}
  79.358 +
  79.359 +
  79.360 +// ------------------------------------------------------------------------------------------------
  79.361 +const aiExportDataBlob* Exporter :: GetBlob() const 
  79.362 +{
  79.363 +	return pimpl->blob;
  79.364 +}
  79.365 +
  79.366 +
  79.367 +// ------------------------------------------------------------------------------------------------
  79.368 +const aiExportDataBlob* Exporter :: GetOrphanedBlob() const 
  79.369 +{
  79.370 +	const aiExportDataBlob* tmp = pimpl->blob;
  79.371 +	pimpl->blob = NULL;
  79.372 +	return tmp;
  79.373 +}
  79.374 +
  79.375 +
  79.376 +// ------------------------------------------------------------------------------------------------
  79.377 +size_t Exporter :: GetExportFormatCount() const 
  79.378 +{
  79.379 +	return pimpl->mExporters.size();
  79.380 +}
  79.381 +
  79.382 +// ------------------------------------------------------------------------------------------------
  79.383 +const aiExportFormatDesc* Exporter :: GetExportFormatDescription( size_t pIndex ) const 
  79.384 +{
  79.385 +	if (pIndex >= GetExportFormatCount()) {
  79.386 +		return NULL;
  79.387 +	}
  79.388 +
  79.389 +	return &pimpl->mExporters[pIndex].mDescription;
  79.390 +}
  79.391 +
  79.392 +// ------------------------------------------------------------------------------------------------
  79.393 +aiReturn Exporter :: RegisterExporter(const ExportFormatEntry& desc)
  79.394 +{
  79.395 +	BOOST_FOREACH(const ExportFormatEntry& e, pimpl->mExporters) {
  79.396 +		if (!strcmp(e.mDescription.id,desc.mDescription.id)) {
  79.397 +			return aiReturn_FAILURE;
  79.398 +		}
  79.399 +	}
  79.400 +
  79.401 +	pimpl->mExporters.push_back(desc);
  79.402 +	return aiReturn_SUCCESS;
  79.403 +}
  79.404 +
  79.405 +
  79.406 +// ------------------------------------------------------------------------------------------------
  79.407 +void Exporter :: UnregisterExporter(const char* id)
  79.408 +{
  79.409 +	for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin(); it != pimpl->mExporters.end(); ++it) {
  79.410 +		if (!strcmp((*it).mDescription.id,id)) {
  79.411 +			pimpl->mExporters.erase(it);
  79.412 +			break;
  79.413 +		}
  79.414 +	}
  79.415 +}
  79.416 +
  79.417 +#endif // !ASSIMP_BUILD_NO_EXPORT
    80.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.2 +++ b/libs/assimp/FBXAnimation.cpp	Sat Feb 01 19:58:19 2014 +0200
    80.3 @@ -0,0 +1,313 @@
    80.4 +/*
    80.5 +Open Asset Import Library (assimp)
    80.6 +----------------------------------------------------------------------
    80.7 +
    80.8 +Copyright (c) 2006-2012, assimp team
    80.9 +All rights reserved.
   80.10 +
   80.11 +Redistribution and use of this software in source and binary forms, 
   80.12 +with or without modification, are permitted provided that the 
   80.13 +following conditions are met:
   80.14 +
   80.15 +* Redistributions of source code must retain the above
   80.16 +  copyright notice, this list of conditions and the
   80.17 +  following disclaimer.
   80.18 +
   80.19 +* Redistributions in binary form must reproduce the above
   80.20 +  copyright notice, this list of conditions and the
   80.21 +  following disclaimer in the documentation and/or other
   80.22 +  materials provided with the distribution.
   80.23 +
   80.24 +* Neither the name of the assimp team, nor the names of its
   80.25 +  contributors may be used to endorse or promote products
   80.26 +  derived from this software without specific prior
   80.27 +  written permission of the assimp team.
   80.28 +
   80.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   80.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   80.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   80.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   80.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   80.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   80.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   80.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   80.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   80.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   80.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   80.40 +
   80.41 +----------------------------------------------------------------------
   80.42 +*/
   80.43 +
   80.44 +/** @file  FBXAnimation.cpp
   80.45 + *  @brief Assimp::FBX::AnimationCurve, Assimp::FBX::AnimationCurveNode, 
   80.46 + *         Assimp::FBX::AnimationLayer, Assimp::FBX::AnimationStack 
   80.47 + */
   80.48 +#include "AssimpPCH.h"
   80.49 +
   80.50 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   80.51 +
   80.52 +#include "FBXParser.h"
   80.53 +#include "FBXDocument.h"
   80.54 +#include "FBXImporter.h"
   80.55 +#include "FBXImportSettings.h"
   80.56 +#include "FBXDocumentUtil.h"
   80.57 +#include "FBXProperties.h"
   80.58 +
   80.59 +namespace Assimp {
   80.60 +namespace FBX {
   80.61 +
   80.62 +	using namespace Util;
   80.63 +
   80.64 +// ------------------------------------------------------------------------------------------------
   80.65 +AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc)
   80.66 +: Object(id, element, name)
   80.67 +{
   80.68 +	const Scope& sc = GetRequiredScope(element);
   80.69 +	const Element& KeyTime = GetRequiredElement(sc,"KeyTime");
   80.70 +	const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat");
   80.71 +
   80.72 +	ParseVectorDataArray(keys, KeyTime);
   80.73 +	ParseVectorDataArray(values, KeyValueFloat);
   80.74 +
   80.75 +	if(keys.size() != values.size()) {
   80.76 +		DOMError("the number of key times does not match the number of keyframe values",&KeyTime);
   80.77 +	}
   80.78 +	
   80.79 +	// check if the key times are well-ordered
   80.80 +	if(!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) {
   80.81 +		DOMError("the keyframes are not in ascending order",&KeyTime);
   80.82 +	}
   80.83 +
   80.84 +	const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"];
   80.85 +	if(KeyAttrDataFloat) {
   80.86 +		ParseVectorDataArray(attributes, *KeyAttrDataFloat);
   80.87 +	}
   80.88 +
   80.89 +	const Element* KeyAttrFlags = sc["KeyAttrFlags"];
   80.90 +	if(KeyAttrFlags) {
   80.91 +		ParseVectorDataArray(flags, *KeyAttrFlags);
   80.92 +	}
   80.93 +}
   80.94 +
   80.95 +
   80.96 +// ------------------------------------------------------------------------------------------------
   80.97 +AnimationCurve::~AnimationCurve()
   80.98 +{
   80.99 +
  80.100 +}
  80.101 +
  80.102 +
  80.103 +// ------------------------------------------------------------------------------------------------
  80.104 +AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc, 
  80.105 +	const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/)
  80.106 +: Object(id, element, name)
  80.107 +, target()
  80.108 +, doc(doc)
  80.109 +{
  80.110 +	const Scope& sc = GetRequiredScope(element);
  80.111 +	
  80.112 +	// find target node
  80.113 +	const char* whitelist[] = {"Model","NodeAttribute"};
  80.114 +	const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
  80.115 +
  80.116 +	BOOST_FOREACH(const Connection* con, conns) {
  80.117 +
  80.118 +		// link should go for a property
  80.119 +		if (!con->PropertyName().length()) {
  80.120 +			continue;
  80.121 +		}
  80.122 +
  80.123 +		if(target_prop_whitelist) {
  80.124 +			const char* const s = con->PropertyName().c_str();
  80.125 +			bool ok = false;
  80.126 +			for (size_t i = 0; i < whitelist_size; ++i) {
  80.127 +				if (!strcmp(s, target_prop_whitelist[i])) {
  80.128 +					ok = true;
  80.129 +					break;
  80.130 +				}
  80.131 +			}
  80.132 +
  80.133 +			if (!ok) {
  80.134 +				throw std::range_error("AnimationCurveNode target property is not in whitelist");
  80.135 +			}
  80.136 +		}
  80.137 +
  80.138 +		const Object* const ob = con->DestinationObject();
  80.139 +		if(!ob) {
  80.140 +			DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element);
  80.141 +			continue;
  80.142 +		}
  80.143 +
  80.144 +		// XXX support constraints as DOM class
  80.145 +		//ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob));
  80.146 +		target = ob; 
  80.147 +		if(!target) {
  80.148 +			continue;
  80.149 +		}
  80.150 +
  80.151 +		prop = con->PropertyName();
  80.152 +		break;
  80.153 +	}
  80.154 +
  80.155 +	if(!target) {
  80.156 +		DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element);
  80.157 +	}
  80.158 +
  80.159 +	props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
  80.160 +}
  80.161 +
  80.162 +
  80.163 +// ------------------------------------------------------------------------------------------------
  80.164 +AnimationCurveNode::~AnimationCurveNode()
  80.165 +{
  80.166 +
  80.167 +}
  80.168 +
  80.169 +
  80.170 +// ------------------------------------------------------------------------------------------------
  80.171 +const AnimationCurveMap& AnimationCurveNode::Curves() const
  80.172 +{
  80.173 +	if(curves.empty()) {
  80.174 +		// resolve attached animation curves
  80.175 +		const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
  80.176 +
  80.177 +		BOOST_FOREACH(const Connection* con, conns) {
  80.178 +
  80.179 +			// link should go for a property
  80.180 +			if (!con->PropertyName().length()) {
  80.181 +				continue;
  80.182 +			}
  80.183 +
  80.184 +			const Object* const ob = con->SourceObject();
  80.185 +			if(!ob) {
  80.186 +				DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element);
  80.187 +				continue;
  80.188 +			}
  80.189 +
  80.190 +			const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob);
  80.191 +			if(!anim) {
  80.192 +				DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element);
  80.193 +				continue;
  80.194 +			}
  80.195 +
  80.196 +			curves[con->PropertyName()] = anim;
  80.197 +		}
  80.198 +	}
  80.199 +
  80.200 +	return curves;
  80.201 +}
  80.202 +
  80.203 +
  80.204 +// ------------------------------------------------------------------------------------------------
  80.205 +AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc)
  80.206 +: Object(id, element, name)
  80.207 +, doc(doc)
  80.208 +{
  80.209 +	const Scope& sc = GetRequiredScope(element);
  80.210 +
  80.211 +	// note: the props table here bears little importance and is usually absent
  80.212 +	props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true);
  80.213 +}
  80.214 +
  80.215 +
  80.216 +// ------------------------------------------------------------------------------------------------
  80.217 +AnimationLayer::~AnimationLayer()
  80.218 +{
  80.219 +
  80.220 +}
  80.221 +
  80.222 +
  80.223 +// ------------------------------------------------------------------------------------------------
  80.224 +AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/, 
  80.225 +	size_t whitelist_size /*= 0*/) const
  80.226 +{
  80.227 +	AnimationCurveNodeList nodes;
  80.228 +
  80.229 +	// resolve attached animation nodes
  80.230 +	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode");
  80.231 +	nodes.reserve(conns.size());
  80.232 +
  80.233 +	BOOST_FOREACH(const Connection* con, conns) {
  80.234 +
  80.235 +		// link should not go to a property
  80.236 +		if (con->PropertyName().length()) {
  80.237 +			continue;
  80.238 +		}
  80.239 +
  80.240 +		const Object* const ob = con->SourceObject();
  80.241 +		if(!ob) {
  80.242 +			DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element);
  80.243 +			continue;
  80.244 +		}
  80.245 +
  80.246 +		const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob);
  80.247 +		if(!anim) {
  80.248 +			DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element);
  80.249 +			continue;
  80.250 +		}
  80.251 +
  80.252 +		if(target_prop_whitelist) {
  80.253 +			const char* s = anim->TargetProperty().c_str();
  80.254 +			bool ok = false;
  80.255 +			for (size_t i = 0; i < whitelist_size; ++i) {
  80.256 +				if (!strcmp(s, target_prop_whitelist[i])) {
  80.257 +					ok = true;
  80.258 +					break;
  80.259 +				}
  80.260 +			}
  80.261 +			if(!ok) {
  80.262 +				continue;
  80.263 +			}
  80.264 +		}
  80.265 +		nodes.push_back(anim);
  80.266 +	}
  80.267 +
  80.268 +	return nodes; // pray for NRVO
  80.269 +}
  80.270 +
  80.271 +// ------------------------------------------------------------------------------------------------
  80.272 +AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc)
  80.273 +: Object(id, element, name)
  80.274 +{
  80.275 +	const Scope& sc = GetRequiredScope(element);
  80.276 +
  80.277 +	// note: we don't currently use any of these properties so we shouldn't bother if it is missing
  80.278 +	props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true);
  80.279 +
  80.280 +	// resolve attached animation layers
  80.281 +	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer");
  80.282 +	layers.reserve(conns.size());
  80.283 +
  80.284 +	BOOST_FOREACH(const Connection* con, conns) {
  80.285 +
  80.286 +		// link should not go to a property
  80.287 +		if (con->PropertyName().length()) {
  80.288 +			continue;
  80.289 +		}
  80.290 +
  80.291 +		const Object* const ob = con->SourceObject();
  80.292 +		if(!ob) {
  80.293 +			DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element);
  80.294 +			continue;
  80.295 +		}
  80.296 +
  80.297 +		const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob);
  80.298 +		if(!anim) {
  80.299 +			DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element);
  80.300 +			continue;
  80.301 +		}
  80.302 +		layers.push_back(anim);
  80.303 +	}
  80.304 +}
  80.305 +
  80.306 +
  80.307 +// ------------------------------------------------------------------------------------------------
  80.308 +AnimationStack::~AnimationStack()
  80.309 +{
  80.310 +
  80.311 +}
  80.312 +
  80.313 +} //!FBX
  80.314 +} //!Assimp
  80.315 +
  80.316 +#endif
    81.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.2 +++ b/libs/assimp/FBXBinaryTokenizer.cpp	Sat Feb 01 19:58:19 2014 +0200
    81.3 @@ -0,0 +1,397 @@
    81.4 +/*
    81.5 +Open Asset Import Library (assimp)
    81.6 +----------------------------------------------------------------------
    81.7 +
    81.8 +Copyright (c) 2006-2012, assimp team
    81.9 +All rights reserved.
   81.10 +
   81.11 +Redistribution and use of this software in source and binary forms, 
   81.12 +with or without modification, are permitted provided that the 
   81.13 +following conditions are met:
   81.14 +
   81.15 +* Redistributions of source code must retain the above
   81.16 +  copyright notice, this list of conditions and the
   81.17 +  following disclaimer.
   81.18 +
   81.19 +* Redistributions in binary form must reproduce the above
   81.20 +  copyright notice, this list of conditions and the
   81.21 +  following disclaimer in the documentation and/or other
   81.22 +  materials provided with the distribution.
   81.23 +
   81.24 +* Neither the name of the assimp team, nor the names of its
   81.25 +  contributors may be used to endorse or promote products
   81.26 +  derived from this software without specific prior
   81.27 +  written permission of the assimp team.
   81.28 +
   81.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   81.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   81.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   81.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   81.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   81.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   81.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   81.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   81.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   81.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   81.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   81.40 +
   81.41 +----------------------------------------------------------------------
   81.42 +*/
   81.43 +/** @file  FBXBinaryTokenizer.cpp
   81.44 + *  @brief Implementation of a fake lexer for binary fbx files -
   81.45 + *    we emit tokens so the parser needs almost no special handling
   81.46 + *    for binary files.
   81.47 + */
   81.48 +#include "AssimpPCH.h"
   81.49 +
   81.50 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   81.51 +
   81.52 +#include "FBXTokenizer.h"
   81.53 +#include "FBXUtil.h"
   81.54 +
   81.55 +namespace Assimp {
   81.56 +namespace FBX {
   81.57 +
   81.58 +
   81.59 +// ------------------------------------------------------------------------------------------------
   81.60 +Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
   81.61 +	: sbegin(sbegin)
   81.62 +	, send(send)
   81.63 +	, type(type)
   81.64 +	, line(offset)
   81.65 +	, column(BINARY_MARKER)
   81.66 +#ifdef DEBUG
   81.67 +	, contents(sbegin, static_cast<size_t>(send-sbegin))
   81.68 +#endif
   81.69 +{
   81.70 +	ai_assert(sbegin);
   81.71 +	ai_assert(send);
   81.72 +
   81.73 +	// binary tokens may have zero length because they are sometimes dummies
   81.74 +	// inserted by TokenizeBinary()
   81.75 +	ai_assert(send >= sbegin);
   81.76 +}
   81.77 +
   81.78 +
   81.79 +namespace {
   81.80 +
   81.81 +// ------------------------------------------------------------------------------------------------
   81.82 +// signal tokenization error, this is always unrecoverable. Throws DeadlyImportError.
   81.83 +void TokenizeError(const std::string& message, unsigned int offset)
   81.84 +{
   81.85 +	throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset));
   81.86 +}
   81.87 +
   81.88 +
   81.89 +// ------------------------------------------------------------------------------------------------
   81.90 +uint32_t Offset(const char* begin, const char* cursor)
   81.91 +{
   81.92 +	ai_assert(begin <= cursor);
   81.93 +	return static_cast<unsigned int>(cursor - begin);
   81.94 +}
   81.95 +
   81.96 +
   81.97 +// ------------------------------------------------------------------------------------------------
   81.98 +void TokenizeError(const std::string& message, const char* begin, const char* cursor)
   81.99 +{
  81.100 +	TokenizeError(message, Offset(begin, cursor));
  81.101 +}
  81.102 +
  81.103 +
  81.104 +// ------------------------------------------------------------------------------------------------
  81.105 +uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
  81.106 +{
  81.107 +	if(Offset(cursor, end) < 4) {
  81.108 +		TokenizeError("cannot ReadWord, out of bounds",input, cursor);
  81.109 +	} 
  81.110 +
  81.111 +	uint32_t word = *reinterpret_cast<const uint32_t*>(cursor);
  81.112 +	AI_SWAP4(word);
  81.113 +
  81.114 +	cursor += 4;
  81.115 +
  81.116 +	return word;
  81.117 +}
  81.118 +
  81.119 +
  81.120 +// ------------------------------------------------------------------------------------------------
  81.121 +uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
  81.122 +{
  81.123 +	if(Offset(cursor, end) < 1) {
  81.124 +		TokenizeError("cannot ReadByte, out of bounds",input, cursor);
  81.125 +	} 
  81.126 +
  81.127 +	uint8_t word = *reinterpret_cast<const uint8_t*>(cursor);
  81.128 +	++cursor;
  81.129 +
  81.130 +	return word;
  81.131 +}
  81.132 +
  81.133 +
  81.134 +// ------------------------------------------------------------------------------------------------
  81.135 +unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end, 
  81.136 +	bool long_length = false,
  81.137 +	bool allow_null = false)
  81.138 +{
  81.139 +	const uint32_t len_len = long_length ? 4 : 1;
  81.140 +	if(Offset(cursor, end) < len_len) {
  81.141 +		TokenizeError("cannot ReadString, out of bounds reading length",input, cursor);
  81.142 +	} 
  81.143 +
  81.144 +	const uint32_t length = long_length ? ReadWord(input, cursor, end) : ReadByte(input, cursor, end);
  81.145 +
  81.146 +	if (Offset(cursor, end) < length) {
  81.147 +		TokenizeError("cannot ReadString, length is out of bounds",input, cursor);
  81.148 +	}
  81.149 +
  81.150 +	sbegin_out = cursor;
  81.151 +	cursor += length;
  81.152 +
  81.153 +	send_out = cursor;
  81.154 +
  81.155 +	if(!allow_null) {
  81.156 +		for (unsigned int i = 0; i < length; ++i) {
  81.157 +			if(sbegin_out[i] == '\0') {
  81.158 +				TokenizeError("failed ReadString, unexpected NUL character in string",input, cursor);
  81.159 +			}
  81.160 +		}
  81.161 +	}
  81.162 +
  81.163 +	return length;
  81.164 +}
  81.165 +
  81.166 +
  81.167 +
  81.168 +// ------------------------------------------------------------------------------------------------
  81.169 +void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end)
  81.170 +{
  81.171 +	if(Offset(cursor, end) < 1) {
  81.172 +		TokenizeError("cannot ReadData, out of bounds reading length",input, cursor);
  81.173 +	} 
  81.174 +
  81.175 +	const char type = *cursor;
  81.176 +	sbegin_out = cursor++;
  81.177 +
  81.178 +	switch(type)
  81.179 +	{
  81.180 +		// 16 bit int
  81.181 +	case 'Y':
  81.182 +		cursor += 2;
  81.183 +		break;
  81.184 +
  81.185 +		// 1 bit bool flag (yes/no)
  81.186 +	case 'C':
  81.187 +		cursor += 1;
  81.188 +		break;
  81.189 +
  81.190 +		// 32 bit int
  81.191 +	case 'I':
  81.192 +		// <- fall thru
  81.193 +
  81.194 +		// float
  81.195 +	case 'F':
  81.196 +		cursor += 4;
  81.197 +		break;
  81.198 +
  81.199 +		// double
  81.200 +	case 'D':
  81.201 +		cursor += 8;
  81.202 +		break;
  81.203 +
  81.204 +		// 64 bit int
  81.205 +	case 'L':
  81.206 +		cursor += 8;
  81.207 +		break;
  81.208 +
  81.209 +		// note: do not write cursor += ReadWord(...cursor) as this would be UB
  81.210 +
  81.211 +		// raw binary data
  81.212 +	case 'R':	
  81.213 +	{
  81.214 +		const uint32_t length = ReadWord(input, cursor, end);
  81.215 +		cursor += length;
  81.216 +		break;
  81.217 +	}
  81.218 +
  81.219 +	case 'b': 
  81.220 +		// TODO: what is the 'b' type code? Right now we just skip over it /
  81.221 +		// take the full range we could get
  81.222 +		cursor = end;
  81.223 +		break;
  81.224 +
  81.225 +		// array of *
  81.226 +	case 'f':
  81.227 +	case 'd':
  81.228 +	case 'l':
  81.229 +	case 'i':	{
  81.230 +	
  81.231 +		const uint32_t length = ReadWord(input, cursor, end);
  81.232 +		const uint32_t encoding = ReadWord(input, cursor, end);
  81.233 +
  81.234 +		const uint32_t comp_len = ReadWord(input, cursor, end);
  81.235 +
  81.236 +		// compute length based on type and check against the stored value
  81.237 +		if(encoding == 0) {
  81.238 +			uint32_t stride;
  81.239 +			switch(type)
  81.240 +			{
  81.241 +			case 'f':
  81.242 +			case 'i':
  81.243 +				stride = 4;
  81.244 +				break;
  81.245 +
  81.246 +			case 'd':
  81.247 +			case 'l':
  81.248 +				stride = 8;
  81.249 +				break;
  81.250 +
  81.251 +			default:
  81.252 +				ai_assert(false);
  81.253 +			};
  81.254 +			if(length * stride != comp_len) {
  81.255 +				TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor);
  81.256 +			}
  81.257 +		}
  81.258 +		// zip/deflate algorithm (encoding==1)? take given length. anything else? die
  81.259 +		else if (encoding != 1) {			
  81.260 +			TokenizeError("cannot ReadData, unknown encoding",input, cursor);
  81.261 +		}
  81.262 +		cursor += comp_len;
  81.263 +		break;
  81.264 +	}
  81.265 +
  81.266 +		// string
  81.267 +	case 'S': {
  81.268 +		const char* sb, *se;
  81.269 +		// 0 characters can legally happen in such strings
  81.270 +		ReadString(sb, se, input, cursor, end, true, true);
  81.271 +		break;
  81.272 +	}
  81.273 +	default:
  81.274 +		TokenizeError("cannot ReadData, unexpected type code: " + std::string(&type, 1),input, cursor);
  81.275 +	}
  81.276 +
  81.277 +	if(cursor > end) {
  81.278 +		TokenizeError("cannot ReadData, the remaining size is too small for the data type: " + std::string(&type, 1),input, cursor);
  81.279 +	} 
  81.280 +
  81.281 +	// the type code is contained in the returned range
  81.282 +	send_out = cursor;
  81.283 +}
  81.284 +
  81.285 +
  81.286 +// ------------------------------------------------------------------------------------------------
  81.287 +bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end)
  81.288 +{
  81.289 +	// the first word contains the offset at which this block ends
  81.290 +	const uint32_t end_offset = ReadWord(input, cursor, end);
  81.291 +	
  81.292 +	// we may get 0 if reading reached the end of the file -
  81.293 +	// fbx files have a mysterious extra footer which I don't know 
  81.294 +	// how to extract any information from, but at least it always 
  81.295 +	// starts with a 0.
  81.296 +	if(!end_offset) {
  81.297 +		return false;
  81.298 +	}
  81.299 +
  81.300 +	if(end_offset > Offset(input, end)) {
  81.301 +		TokenizeError("block offset is out of range",input, cursor);
  81.302 +	}
  81.303 +	else if(end_offset < Offset(input, cursor)) {
  81.304 +		TokenizeError("block offset is negative out of range",input, cursor);
  81.305 +	}
  81.306 +
  81.307 +	// the second data word contains the number of properties in the scope
  81.308 +	const uint32_t prop_count = ReadWord(input, cursor, end);
  81.309 +
  81.310 +	// the third data word contains the length of the property list
  81.311 +	const uint32_t prop_length = ReadWord(input, cursor, end);
  81.312 +
  81.313 +	// now comes the name of the scope/key
  81.314 +	const char* sbeg, *send;
  81.315 +	ReadString(sbeg, send, input, cursor, end);
  81.316 +
  81.317 +	output_tokens.push_back(new_Token(sbeg, send, TokenType_KEY, Offset(input, cursor) ));
  81.318 +
  81.319 +	// now come the individual properties
  81.320 +	const char* begin_cursor = cursor;
  81.321 +	for (unsigned int i = 0; i < prop_count; ++i) {
  81.322 +		ReadData(sbeg, send, input, cursor, begin_cursor + prop_length);
  81.323 +
  81.324 +		output_tokens.push_back(new_Token(sbeg, send, TokenType_DATA, Offset(input, cursor) ));
  81.325 +
  81.326 +		if(i != prop_count-1) {
  81.327 +			output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_COMMA, Offset(input, cursor) ));
  81.328 +		}
  81.329 +	}
  81.330 +
  81.331 +	if (Offset(begin_cursor, cursor) != prop_length) {
  81.332 +		TokenizeError("property length not reached, something is wrong",input, cursor);
  81.333 +	}
  81.334 +
  81.335 +	// at the end of each nested block, there is a NUL record to indicate
  81.336 +	// that the sub-scope exists (i.e. to distinguish between P: and P : {})
  81.337 +	// this NUL record is 13 bytes long.
  81.338 +#define BLOCK_SENTINEL_LENGTH 13
  81.339 +
  81.340 +	if (Offset(input, cursor) < end_offset) {
  81.341 +
  81.342 +		if (end_offset - Offset(input, cursor) < BLOCK_SENTINEL_LENGTH) {
  81.343 +			TokenizeError("insufficient padding bytes at block end",input, cursor);
  81.344 +		}
  81.345 +
  81.346 +		output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_OPEN_BRACKET, Offset(input, cursor) ));
  81.347 +
  81.348 +		// XXX this is vulnerable to stack overflowing ..
  81.349 +		while(Offset(input, cursor) < end_offset - BLOCK_SENTINEL_LENGTH) {
  81.350 +			ReadScope(output_tokens, input, cursor, input + end_offset - BLOCK_SENTINEL_LENGTH);
  81.351 +		}
  81.352 +		output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
  81.353 +
  81.354 +		for (unsigned int i = 0; i < BLOCK_SENTINEL_LENGTH; ++i) {
  81.355 +			if(cursor[i] != '\0') {
  81.356 +				TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor);
  81.357 +			}
  81.358 +		}
  81.359 +		cursor += BLOCK_SENTINEL_LENGTH;
  81.360 +	}
  81.361 +
  81.362 +	if (Offset(input, cursor) != end_offset) {
  81.363 +		TokenizeError("scope length not reached, something is wrong",input, cursor);
  81.364 +	}
  81.365 +
  81.366 +	return true;
  81.367 +}
  81.368 +
  81.369 +
  81.370 +}
  81.371 +
  81.372 +// ------------------------------------------------------------------------------------------------
  81.373 +void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length)
  81.374 +{
  81.375 +	ai_assert(input);
  81.376 +
  81.377 +	if(length < 0x1b) {
  81.378 +		TokenizeError("file is too short",0);
  81.379 +	}
  81.380 +
  81.381 +	if (strncmp(input,"Kaydara FBX Binary",18)) {
  81.382 +		TokenizeError("magic bytes not found",0);
  81.383 +	}
  81.384 +
  81.385 +
  81.386 +	//uint32_t offset = 0x1b;
  81.387 +
  81.388 +	const char* cursor = input + 0x1b;
  81.389 +
  81.390 +	while (cursor < input + length) {
  81.391 +		if(!ReadScope(output_tokens, input, cursor, input + length)) {
  81.392 +			break;
  81.393 +		}
  81.394 +	}
  81.395 +}
  81.396 +
  81.397 +} // !FBX
  81.398 +} // !Assimp
  81.399 +
  81.400 +#endif
  81.401 \ No newline at end of file
    82.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.2 +++ b/libs/assimp/FBXCompileConfig.h	Sat Feb 01 19:58:19 2014 +0200
    82.3 @@ -0,0 +1,66 @@
    82.4 +/*
    82.5 +Open Asset Import Library (assimp)
    82.6 +----------------------------------------------------------------------
    82.7 +
    82.8 +Copyright (c) 2006-2012, assimp team
    82.9 +All rights reserved.
   82.10 +
   82.11 +Redistribution and use of this software in source and binary forms, 
   82.12 +with or without modification, are permitted provided that the 
   82.13 +following conditions are met:
   82.14 +
   82.15 +* Redistributions of source code must retain the above
   82.16 +  copyright notice, this list of conditions and the
   82.17 +  following disclaimer.
   82.18 +
   82.19 +* Redistributions in binary form must reproduce the above
   82.20 +  copyright notice, this list of conditions and the
   82.21 +  following disclaimer in the documentation and/or other
   82.22 +  materials provided with the distribution.
   82.23 +
   82.24 +* Neither the name of the assimp team, nor the names of its
   82.25 +  contributors may be used to endorse or promote products
   82.26 +  derived from this software without specific prior
   82.27 +  written permission of the assimp team.
   82.28 +
   82.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   82.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   82.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   82.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   82.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   82.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   82.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   82.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   82.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   82.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   82.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   82.40 +
   82.41 +----------------------------------------------------------------------
   82.42 +*/
   82.43 +
   82.44 +/** @file  FBXCompileConfig.h
   82.45 + *  @brief FBX importer compile-time switches
   82.46 + */
   82.47 +#ifndef INCLUDED_AI_FBX_COMPILECONFIG_H
   82.48 +#define INCLUDED_AI_FBX_COMPILECONFIG_H
   82.49 +
   82.50 +//
   82.51 +#if _MSC_VER > 1500 || (defined __GNUC___)
   82.52 +#	define ASSIMP_FBX_USE_UNORDERED_MULTIMAP
   82.53 +#	else
   82.54 +#	define fbx_unordered_map map
   82.55 +#	define fbx_unordered_multimap multimap
   82.56 +#endif
   82.57 +
   82.58 +#ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP
   82.59 +#	include <unordered_map>
   82.60 +#	if _MSC_VER > 1600
   82.61 +#		define fbx_unordered_map unordered_map
   82.62 +#		define fbx_unordered_multimap unordered_multimap
   82.63 +#	else
   82.64 +#		define fbx_unordered_map tr1::unordered_map
   82.65 +#		define fbx_unordered_multimap tr1::unordered_multimap
   82.66 +#	endif
   82.67 +#endif
   82.68 +
   82.69 +#endif
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/libs/assimp/FBXConverter.cpp	Sat Feb 01 19:58:19 2014 +0200
    83.3 @@ -0,0 +1,2750 @@
    83.4 +/*
    83.5 +Open Asset Import Library (assimp)
    83.6 +----------------------------------------------------------------------
    83.7 +
    83.8 +Copyright (c) 2006-2012, assimp team
    83.9 +All rights reserved.
   83.10 +
   83.11 +Redistribution and use of this software in source and binary forms, 
   83.12 +with or without modification, are permitted provided that the 
   83.13 +following conditions are met:
   83.14 +
   83.15 +* Redistributions of source code must retain the above
   83.16 +  copyright notice, this list of conditions and the
   83.17 +  following disclaimer.
   83.18 +
   83.19 +* Redistributions in binary form must reproduce the above
   83.20 +  copyright notice, this list of conditions and the
   83.21 +  following disclaimer in the documentation and/or other
   83.22 +  materials provided with the distribution.
   83.23 +
   83.24 +* Neither the name of the assimp team, nor the names of its
   83.25 +  contributors may be used to endorse or promote products
   83.26 +  derived from this software without specific prior
   83.27 +  written permission of the assimp team.
   83.28 +
   83.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   83.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   83.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   83.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   83.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   83.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   83.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   83.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   83.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   83.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   83.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   83.40 +
   83.41 +----------------------------------------------------------------------
   83.42 +*/
   83.43 +
   83.44 +/** @file  FBXConverter.cpp
   83.45 + *  @brief Implementation of the FBX DOM -> aiScene converter
   83.46 + */
   83.47 +#include "AssimpPCH.h"
   83.48 +
   83.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   83.50 +
   83.51 +#include <iterator>
   83.52 +#include <boost/tuple/tuple.hpp>
   83.53 +
   83.54 +#include "FBXParser.h"
   83.55 +#include "FBXConverter.h"
   83.56 +#include "FBXDocument.h"
   83.57 +#include "FBXUtil.h"
   83.58 +#include "FBXProperties.h"
   83.59 +#include "FBXImporter.h"
   83.60 +
   83.61 +namespace Assimp {
   83.62 +namespace FBX {
   83.63 +
   83.64 +	using namespace Util;
   83.65 +
   83.66 +
   83.67 +#define MAGIC_NODE_TAG "_$AssimpFbx$"
   83.68 +#define MAGIC_NULL_TAG "_$AssimpFbxNull$"
   83.69 +
   83.70 +#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
   83.71 +
   83.72 +	// XXX vc9's debugger won't step into anonymous namespaces
   83.73 +//namespace {
   83.74 +
   83.75 +/** Dummy class to encapsulate the conversion process */
   83.76 +class Converter
   83.77 +{
   83.78 +public:
   83.79 +
   83.80 +	/** the different parts that make up the final local transformation of a fbx node */
   83.81 +	enum TransformationComp
   83.82 +	{
   83.83 +		TransformationComp_Translation = 0,
   83.84 +		TransformationComp_RotationOffset,
   83.85 +		TransformationComp_RotationPivot,
   83.86 +		TransformationComp_PreRotation,
   83.87 +		TransformationComp_Rotation,
   83.88 +		TransformationComp_PostRotation,
   83.89 +		TransformationComp_RotationPivotInverse,
   83.90 +		TransformationComp_ScalingOffset,
   83.91 +		TransformationComp_ScalingPivot,
   83.92 +		TransformationComp_Scaling,
   83.93 +		TransformationComp_ScalingPivotInverse,
   83.94 +
   83.95 +		TransformationComp_MAXIMUM
   83.96 +	};
   83.97 +
   83.98 +
   83.99 +
  83.100 +public:
  83.101 +
  83.102 +	Converter(aiScene* out, const Document& doc)
  83.103 +		: defaultMaterialIndex()
  83.104 +		, out(out) 
  83.105 +		, doc(doc)
  83.106 +	{
  83.107 +		// animations need to be converted first since this will
  83.108 +		// populate the node_anim_chain_bits map, which is needed
  83.109 +		// to determine which nodes need to be generated.
  83.110 +		ConvertAnimations();
  83.111 +		ConvertRootNode();
  83.112 +
  83.113 +		if(doc.Settings().readAllMaterials) {
  83.114 +			// unfortunately this means we have to evaluate all objects
  83.115 +			BOOST_FOREACH(const ObjectMap::value_type& v,doc.Objects()) {
  83.116 +
  83.117 +				const Object* ob = v.second->Get();
  83.118 +				if(!ob) {
  83.119 +					continue;
  83.120 +				}
  83.121 +
  83.122 +				const Material* mat = dynamic_cast<const Material*>(ob);
  83.123 +				if(mat) {
  83.124 +
  83.125 +					if (materials_converted.find(mat) == materials_converted.end()) {
  83.126 +						ConvertMaterial(*mat);
  83.127 +					}
  83.128 +				}
  83.129 +			}
  83.130 +		}
  83.131 +
  83.132 +		TransferDataToScene();
  83.133 +
  83.134 +		// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
  83.135 +		// to make sure the scene passes assimp's validation. FBX files
  83.136 +		// need not contain geometry (i.e. camera animations, raw armatures).
  83.137 +		if (out->mNumMeshes == 0) {
  83.138 +			out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
  83.139 +		}
  83.140 +	}
  83.141 +
  83.142 +
  83.143 +	~Converter()
  83.144 +	{
  83.145 +		std::for_each(meshes.begin(),meshes.end(),Util::delete_fun<aiMesh>());
  83.146 +		std::for_each(materials.begin(),materials.end(),Util::delete_fun<aiMaterial>());
  83.147 +		std::for_each(animations.begin(),animations.end(),Util::delete_fun<aiAnimation>());
  83.148 +		std::for_each(lights.begin(),lights.end(),Util::delete_fun<aiLight>());
  83.149 +		std::for_each(cameras.begin(),cameras.end(),Util::delete_fun<aiCamera>());
  83.150 +	}
  83.151 +
  83.152 +
  83.153 +private:
  83.154 +
  83.155 +	// ------------------------------------------------------------------------------------------------
  83.156 +	// find scene root and trigger recursive scene conversion
  83.157 +	void ConvertRootNode() 
  83.158 +	{
  83.159 +		out->mRootNode = new aiNode();
  83.160 +		out->mRootNode->mName.Set("RootNode");
  83.161 +
  83.162 +		// root has ID 0
  83.163 +		ConvertNodes(0L, *out->mRootNode);
  83.164 +	}
  83.165 +
  83.166 +
  83.167 +	// ------------------------------------------------------------------------------------------------
  83.168 +	// collect and assign child nodes
  83.169 +	void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4())
  83.170 +	{
  83.171 +		const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
  83.172 +
  83.173 +		std::vector<aiNode*> nodes;
  83.174 +		nodes.reserve(conns.size());
  83.175 +
  83.176 +		std::vector<aiNode*> nodes_chain;
  83.177 +
  83.178 +		try {
  83.179 +			BOOST_FOREACH(const Connection* con, conns) {
  83.180 +
  83.181 +				// ignore object-property links
  83.182 +				if(con->PropertyName().length()) {
  83.183 +					continue;
  83.184 +				}
  83.185 +
  83.186 +				const Object* const object = con->SourceObject();
  83.187 +				if(!object) {
  83.188 +					FBXImporter::LogWarn("failed to convert source object for Model link");
  83.189 +					continue;
  83.190 +				}
  83.191 +
  83.192 +				const Model* const model = dynamic_cast<const Model*>(object);
  83.193 +
  83.194 +				if(model) {
  83.195 +					nodes_chain.clear();
  83.196 +
  83.197 +					aiMatrix4x4 new_abs_transform = parent_transform;
  83.198 +
  83.199 +					// even though there is only a single input node, the design of
  83.200 +					// assimp (or rather: the complicated transformation chain that
  83.201 +					// is employed by fbx) means that we may need multiple aiNode's
  83.202 +					// to represent a fbx node's transformation.
  83.203 +					GenerateTransformationNodeChain(*model,nodes_chain);
  83.204 +
  83.205 +					ai_assert(nodes_chain.size());
  83.206 +
  83.207 +					const std::string& original_name = FixNodeName(model->Name());
  83.208 +
  83.209 +					// check if any of the nodes in the chain has the name the fbx node
  83.210 +					// is supposed to have. If there is none, add another node to 
  83.211 +					// preserve the name - people might have scripts etc. that rely
  83.212 +					// on specific node names.
  83.213 +					aiNode* name_carrier = NULL;
  83.214 +					BOOST_FOREACH(aiNode* prenode, nodes_chain) {
  83.215 +						if ( !strcmp(prenode->mName.C_Str(), original_name.c_str()) ) {
  83.216 +							name_carrier = prenode;
  83.217 +							break;
  83.218 +						}
  83.219 +					}
  83.220 +
  83.221 +					if(!name_carrier) {
  83.222 +						nodes_chain.push_back(new aiNode(original_name));
  83.223 +						name_carrier = nodes_chain.back();
  83.224 +					}
  83.225 +
  83.226 +					// link all nodes in a row
  83.227 +					aiNode* last_parent = &parent;
  83.228 +					BOOST_FOREACH(aiNode* prenode, nodes_chain) {
  83.229 +						ai_assert(prenode);
  83.230 +
  83.231 +						if(last_parent != &parent) {
  83.232 +							last_parent->mNumChildren = 1;
  83.233 +							last_parent->mChildren = new aiNode*[1];
  83.234 +							last_parent->mChildren[0] = prenode;
  83.235 +						}
  83.236 +
  83.237 +						prenode->mParent = last_parent;
  83.238 +						last_parent = prenode;
  83.239 +
  83.240 +						new_abs_transform *= prenode->mTransformation;
  83.241 +					}
  83.242 +
  83.243 +					// attach geometry
  83.244 +					ConvertModel(*model, *nodes_chain.back(), new_abs_transform);
  83.245 +
  83.246 +					// attach sub-nodes
  83.247 +					ConvertNodes(model->ID(), *nodes_chain.back(), new_abs_transform);
  83.248 +
  83.249 +					if(doc.Settings().readLights) {
  83.250 +						ConvertLights(*model);
  83.251 +					}
  83.252 +
  83.253 +					if(doc.Settings().readCameras) {
  83.254 +						ConvertCameras(*model);
  83.255 +					}
  83.256 +
  83.257 +					// preserve the info that a node was marked as Null node
  83.258 +					// in the original file.
  83.259 +					if(model->IsNull()) {
  83.260 +						const std::string& new_name = original_name + MAGIC_NULL_TAG;
  83.261 +						RenameNode(original_name, new_name);
  83.262 +						name_carrier->mName.Set( new_name.c_str() );
  83.263 +					}
  83.264 +
  83.265 +					nodes.push_back(nodes_chain.front());	
  83.266 +					nodes_chain.clear();
  83.267 +				}
  83.268 +			}
  83.269 +
  83.270 +			if(nodes.size()) {
  83.271 +				parent.mChildren = new aiNode*[nodes.size()]();
  83.272 +				parent.mNumChildren = static_cast<unsigned int>(nodes.size());
  83.273 +
  83.274 +				std::swap_ranges(nodes.begin(),nodes.end(),parent.mChildren);
  83.275 +			}
  83.276 +		} 
  83.277 +		catch(std::exception&)	{
  83.278 +			Util::delete_fun<aiNode> deleter;
  83.279 +			std::for_each(nodes.begin(),nodes.end(),deleter);
  83.280 +			std::for_each(nodes_chain.begin(),nodes_chain.end(),deleter);
  83.281 +		}
  83.282 +	}
  83.283 +
  83.284 +
  83.285 +	// ------------------------------------------------------------------------------------------------
  83.286 +	void ConvertLights(const Model& model)
  83.287 +	{
  83.288 +		const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
  83.289 +		BOOST_FOREACH(const NodeAttribute* attr, node_attrs) {
  83.290 +			const Light* const light = dynamic_cast<const Light*>(attr);
  83.291 +			if(light) {
  83.292 +				ConvertLight(model, *light);
  83.293 +			}
  83.294 +		}
  83.295 +	}
  83.296 +
  83.297 +
  83.298 +	// ------------------------------------------------------------------------------------------------
  83.299 +	void ConvertCameras(const Model& model)
  83.300 +	{
  83.301 +		const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
  83.302 +		BOOST_FOREACH(const NodeAttribute* attr, node_attrs) {
  83.303 +			const Camera* const cam = dynamic_cast<const Camera*>(attr);
  83.304 +			if(cam) {
  83.305 +				ConvertCamera(model, *cam);
  83.306 +			}
  83.307 +		}
  83.308 +	}
  83.309 +
  83.310 +
  83.311 +	// ------------------------------------------------------------------------------------------------
  83.312 +	void ConvertLight(const Model& model, const Light& light)
  83.313 +	{
  83.314 +		lights.push_back(new aiLight());
  83.315 +		aiLight* const out_light = lights.back();
  83.316 +
  83.317 +		out_light->mName.Set(FixNodeName(model.Name()));
  83.318 +
  83.319 +		const float intensity = light.Intensity();
  83.320 +		const aiVector3D& col = light.Color();
  83.321 +
  83.322 +		out_light->mColorDiffuse = aiColor3D(col.x,col.y,col.z);
  83.323 +		out_light->mColorDiffuse.r *= intensity;
  83.324 +		out_light->mColorDiffuse.g *= intensity;
  83.325 +		out_light->mColorDiffuse.b *= intensity;
  83.326 +
  83.327 +		out_light->mColorSpecular = out_light->mColorDiffuse;
  83.328 +
  83.329 +		switch(light.LightType())
  83.330 +		{
  83.331 +		case Light::Type_Point:
  83.332 +			out_light->mType = aiLightSource_POINT;
  83.333 +			break;
  83.334 +
  83.335 +		case Light::Type_Directional:
  83.336 +			out_light->mType = aiLightSource_DIRECTIONAL;
  83.337 +			break;
  83.338 +
  83.339 +		case Light::Type_Spot:
  83.340 +			out_light->mType = aiLightSource_SPOT;
  83.341 +			out_light->mAngleOuterCone = AI_DEG_TO_RAD(light.OuterAngle());
  83.342 +			out_light->mAngleInnerCone = AI_DEG_TO_RAD(light.InnerAngle());
  83.343 +			break;
  83.344 +
  83.345 +		case Light::Type_Area:
  83.346 +			FBXImporter::LogWarn("cannot represent area light, set to UNDEFINED");
  83.347 +			out_light->mType = aiLightSource_UNDEFINED;
  83.348 +			break;
  83.349 +
  83.350 +		case Light::Type_Volume:
  83.351 +			FBXImporter::LogWarn("cannot represent volume light, set to UNDEFINED");
  83.352 +			out_light->mType = aiLightSource_UNDEFINED;
  83.353 +			break;
  83.354 +		default:
  83.355 +			ai_assert(false);
  83.356 +		}
  83.357 +
  83.358 +		// XXX: how to best convert the near and far decay ranges?
  83.359 +		switch(light.DecayType())
  83.360 +		{
  83.361 +		case Light::Decay_None:
  83.362 +			out_light->mAttenuationConstant = 1.0f;
  83.363 +			break;
  83.364 +		case Light::Decay_Linear:
  83.365 +			out_light->mAttenuationLinear = 1.0f;
  83.366 +			break;
  83.367 +		case Light::Decay_Quadratic:
  83.368 +			out_light->mAttenuationQuadratic = 1.0f;
  83.369 +			break;
  83.370 +		case Light::Decay_Cubic:
  83.371 +			FBXImporter::LogWarn("cannot represent cubic attenuation, set to Quadratic");
  83.372 +			out_light->mAttenuationQuadratic = 1.0f;
  83.373 +			break;
  83.374 +		default:
  83.375 +			ai_assert(false);
  83.376 +		}
  83.377 +	}
  83.378 +
  83.379 +
  83.380 +	// ------------------------------------------------------------------------------------------------
  83.381 +	void ConvertCamera(const Model& model, const Camera& cam)
  83.382 +	{
  83.383 +		cameras.push_back(new aiCamera());
  83.384 +		aiCamera* const out_camera = cameras.back();
  83.385 +
  83.386 +		out_camera->mName.Set(FixNodeName(model.Name()));
  83.387 +
  83.388 +		out_camera->mAspect = cam.AspectWidth();
  83.389 +		out_camera->mPosition = cam.Position();
  83.390 +		out_camera->mLookAt = cam.InterestPosition() - out_camera->mPosition;
  83.391 +
  83.392 +		out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView());
  83.393 +	}
  83.394 +
  83.395 +
  83.396 +	// ------------------------------------------------------------------------------------------------
  83.397 +	// this returns unified names usable within assimp identifiers (i.e. no space characters -
  83.398 +	// while these would be allowed, they are a potential trouble spot so better not use them).
  83.399 +	const char* NameTransformationComp(TransformationComp comp)
  83.400 +	{
  83.401 +		switch(comp)
  83.402 +		{
  83.403 +		case TransformationComp_Translation:
  83.404 +			return "Translation";
  83.405 +		case TransformationComp_RotationOffset:
  83.406 +			return "RotationOffset";
  83.407 +		case TransformationComp_RotationPivot:
  83.408 +			return "RotationPivot";
  83.409 +		case TransformationComp_PreRotation:
  83.410 +			return "PreRotation";
  83.411 +		case TransformationComp_Rotation:
  83.412 +			return "Rotation";
  83.413 +		case TransformationComp_PostRotation:
  83.414 +			return "PostRotation";
  83.415 +		case TransformationComp_RotationPivotInverse:
  83.416 +			return "RotationPivotInverse";
  83.417 +		case TransformationComp_ScalingOffset:
  83.418 +			return "ScalingOffset";
  83.419 +		case TransformationComp_ScalingPivot:
  83.420 +			return "ScalingPivot";
  83.421 +		case TransformationComp_Scaling:
  83.422 +			return "Scaling";
  83.423 +		case TransformationComp_ScalingPivotInverse:
  83.424 +			return "ScalingPivotInverse";
  83.425 +		case TransformationComp_MAXIMUM: // this is to silence compiler warnings
  83.426 +			break;
  83.427 +		}
  83.428 +
  83.429 +		ai_assert(false);
  83.430 +		return NULL;
  83.431 +	}
  83.432 +
  83.433 +
  83.434 +	// ------------------------------------------------------------------------------------------------
  83.435 +	// note: this returns the REAL fbx property names
  83.436 +	const char* NameTransformationCompProperty(TransformationComp comp)
  83.437 +	{
  83.438 +		switch(comp)
  83.439 +		{
  83.440 +		case TransformationComp_Translation:
  83.441 +			return "Lcl Translation";
  83.442 +		case TransformationComp_RotationOffset:
  83.443 +			return "RotationOffset";
  83.444 +		case TransformationComp_RotationPivot:
  83.445 +			return "RotationPivot";
  83.446 +		case TransformationComp_PreRotation:
  83.447 +			return "PreRotation";
  83.448 +		case TransformationComp_Rotation:
  83.449 +			return "Lcl Rotation";
  83.450 +		case TransformationComp_PostRotation:
  83.451 +			return "PostRotation";
  83.452 +		case TransformationComp_RotationPivotInverse:
  83.453 +			return "RotationPivotInverse";
  83.454 +		case TransformationComp_ScalingOffset:
  83.455 +			return "ScalingOffset";
  83.456 +		case TransformationComp_ScalingPivot:
  83.457 +			return "ScalingPivot";
  83.458 +		case TransformationComp_Scaling:
  83.459 +			return "Lcl Scaling";
  83.460 +		case TransformationComp_ScalingPivotInverse:
  83.461 +			return "ScalingPivotInverse";
  83.462 +		case TransformationComp_MAXIMUM: // this is to silence compiler warnings
  83.463 +			break;
  83.464 +		}
  83.465 +
  83.466 +		ai_assert(false);
  83.467 +		return NULL;
  83.468 +	}
  83.469 +
  83.470 +
  83.471 +	// ------------------------------------------------------------------------------------------------
  83.472 +	aiVector3D TransformationCompDefaultValue(TransformationComp comp)
  83.473 +	{
  83.474 +		// XXX a neat way to solve the never-ending special cases for scaling 
  83.475 +		// would be to do everything in log space!
  83.476 +		return comp == TransformationComp_Scaling ? aiVector3D(1.f,1.f,1.f) : aiVector3D();
  83.477 +	}
  83.478 +
  83.479 +
  83.480 +	// ------------------------------------------------------------------------------------------------
  83.481 +	void GetRotationMatrix(Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out)
  83.482 +	{
  83.483 +		if(mode == Model::RotOrder_SphericXYZ) {
  83.484 +			FBXImporter::LogError("Unsupported RotationMode: SphericXYZ");
  83.485 +			out = aiMatrix4x4();
  83.486 +			return;
  83.487 +		}
  83.488 +
  83.489 +		const float angle_epsilon = 1e-6f;
  83.490 +
  83.491 +		out = aiMatrix4x4();
  83.492 +
  83.493 +		bool is_id[3] = { true, true, true };
  83.494 +
  83.495 +		aiMatrix4x4 temp[3];
  83.496 +		if(fabs(rotation.z) > angle_epsilon) {
  83.497 +			aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(rotation.z),temp[2]);
  83.498 +			is_id[2] = false;
  83.499 +		}
  83.500 +		if(fabs(rotation.y) > angle_epsilon) {
  83.501 +			aiMatrix4x4::RotationY(AI_DEG_TO_RAD(rotation.y),temp[1]);
  83.502 +			is_id[1] = false;
  83.503 +		}
  83.504 +		if(fabs(rotation.x) > angle_epsilon) {
  83.505 +			aiMatrix4x4::RotationX(AI_DEG_TO_RAD(rotation.x),temp[0]);
  83.506 +			is_id[0] = false;
  83.507 +		}
  83.508 +
  83.509 +		int order[3] = {-1, -1, -1};
  83.510 +
  83.511 +		// note: rotation order is inverted since we're left multiplying as is usual in assimp
  83.512 +		switch(mode)
  83.513 +		{
  83.514 +		case Model::RotOrder_EulerXYZ:
  83.515 +			order[0] = 2;
  83.516 +			order[1] = 1;
  83.517 +			order[2] = 0;
  83.518 +			break;
  83.519 +
  83.520 +		case Model::RotOrder_EulerXZY: 
  83.521 +			order[0] = 1;
  83.522 +			order[1] = 2;
  83.523 +			order[2] = 0;
  83.524 +			break;
  83.525 +
  83.526 +		case Model::RotOrder_EulerYZX:
  83.527 +			order[0] = 0;
  83.528 +			order[1] = 2;
  83.529 +			order[2] = 1;
  83.530 +			break;
  83.531 +
  83.532 +		case Model::RotOrder_EulerYXZ: 
  83.533 +			order[0] = 2;
  83.534 +			order[1] = 0;
  83.535 +			order[2] = 1;
  83.536 +			break;
  83.537 +
  83.538 +		case Model::RotOrder_EulerZXY: 
  83.539 +			order[0] = 1;
  83.540 +			order[1] = 0;
  83.541 +			order[2] = 2;
  83.542 +			break;
  83.543 +
  83.544 +		case Model::RotOrder_EulerZYX:
  83.545 +			order[0] = 0;
  83.546 +			order[1] = 1;
  83.547 +			order[2] = 2;
  83.548 +			break;
  83.549 +
  83.550 +			default:
  83.551 +				ai_assert(false);
  83.552 +		}
  83.553 +
  83.554 +		if(!is_id[order[0]]) {
  83.555 +			out = temp[order[0]];
  83.556 +		}
  83.557 +
  83.558 +		if(!is_id[order[1]]) {
  83.559 +			out = out * temp[order[1]];
  83.560 +		}
  83.561 +
  83.562 +		if(!is_id[order[2]]) {
  83.563 +			out = out * temp[order[2]];
  83.564 +		}
  83.565 +	}
  83.566 +
  83.567 +
  83.568 +	// ------------------------------------------------------------------------------------------------
  83.569 +	/** checks if a node has more than just scaling, rotation and translation components */
  83.570 +	bool NeedsComplexTransformationChain(const Model& model)
  83.571 +	{
  83.572 +		const PropertyTable& props = model.Props();
  83.573 +		bool ok;
  83.574 +
  83.575 +		const float zero_epsilon = 1e-6f;
  83.576 +		for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
  83.577 +			const TransformationComp comp = static_cast<TransformationComp>(i);
  83.578 +
  83.579 +			if(comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || 
  83.580 +				comp == TransformationComp_Translation) {
  83.581 +
  83.582 +				continue;
  83.583 +			}
  83.584 +
  83.585 +			const aiVector3D& v = PropertyGet<aiVector3D>(props,NameTransformationCompProperty(comp),ok);
  83.586 +			if(ok && v.SquareLength() > zero_epsilon) {
  83.587 +				return true;
  83.588 +			}
  83.589 +		}
  83.590 +
  83.591 +		return false;
  83.592 +	}
  83.593 +
  83.594 +
  83.595 +	// ------------------------------------------------------------------------------------------------
  83.596 +	// note: name must be a FixNodeName() result
  83.597 +	std::string NameTransformationChainNode(const std::string& name, TransformationComp comp)
  83.598 +	{
  83.599 +		return name + std::string(MAGIC_NODE_TAG) + "_" + NameTransformationComp(comp);
  83.600 +	}
  83.601 +
  83.602 +
  83.603 +	// ------------------------------------------------------------------------------------------------
  83.604 +	/** note: memory for output_nodes will be managed by the caller */
  83.605 +	void GenerateTransformationNodeChain(const Model& model, 
  83.606 +		std::vector<aiNode*>& output_nodes)
  83.607 +	{
  83.608 +		const PropertyTable& props = model.Props();
  83.609 +		const Model::RotOrder rot = model.RotationOrder();
  83.610 +
  83.611 +		bool ok;
  83.612 +
  83.613 +		aiMatrix4x4 chain[TransformationComp_MAXIMUM];
  83.614 +		std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4());
  83.615 +		
  83.616 +		// generate transformation matrices for all the different transformation components
  83.617 +		const float zero_epsilon = 1e-6f;
  83.618 +		bool is_complex = false;
  83.619 +
  83.620 +		const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props,"PreRotation",ok);
  83.621 +		if(ok && PreRotation.SquareLength() > zero_epsilon) {
  83.622 +			is_complex = true;
  83.623 +
  83.624 +			GetRotationMatrix(rot, PreRotation, chain[TransformationComp_PreRotation]);
  83.625 +		}
  83.626 +
  83.627 +		const aiVector3D& PostRotation = PropertyGet<aiVector3D>(props,"PostRotation",ok);
  83.628 +		if(ok && PostRotation.SquareLength() > zero_epsilon) {
  83.629 +			is_complex = true;
  83.630 +			
  83.631 +			GetRotationMatrix(rot, PostRotation, chain[TransformationComp_PostRotation]);
  83.632 +		}
  83.633 +
  83.634 +		const aiVector3D& RotationPivot = PropertyGet<aiVector3D>(props,"RotationPivot",ok);
  83.635 +		if(ok && RotationPivot.SquareLength() > zero_epsilon) {
  83.636 +			is_complex = true;
  83.637 +			
  83.638 +			aiMatrix4x4::Translation(RotationPivot,chain[TransformationComp_RotationPivot]);
  83.639 +			aiMatrix4x4::Translation(-RotationPivot,chain[TransformationComp_RotationPivotInverse]);
  83.640 +		}
  83.641 +
  83.642 +		const aiVector3D& RotationOffset = PropertyGet<aiVector3D>(props,"RotationOffset",ok);
  83.643 +		if(ok && RotationOffset.SquareLength() > zero_epsilon) {
  83.644 +			is_complex = true;
  83.645 +
  83.646 +			aiMatrix4x4::Translation(RotationOffset,chain[TransformationComp_RotationOffset]);
  83.647 +		}
  83.648 +
  83.649 +		const aiVector3D& ScalingOffset = PropertyGet<aiVector3D>(props,"ScalingOffset",ok);
  83.650 +		if(ok && ScalingOffset.SquareLength() > zero_epsilon) {
  83.651 +			is_complex = true;
  83.652 +			
  83.653 +			aiMatrix4x4::Translation(ScalingOffset,chain[TransformationComp_ScalingOffset]);
  83.654 +		}
  83.655 +
  83.656 +		const aiVector3D& ScalingPivot = PropertyGet<aiVector3D>(props,"ScalingPivot",ok);
  83.657 +		if(ok && ScalingPivot.SquareLength() > zero_epsilon) {
  83.658 +			is_complex = true;
  83.659 +
  83.660 +			aiMatrix4x4::Translation(ScalingPivot,chain[TransformationComp_ScalingPivot]);
  83.661 +			aiMatrix4x4::Translation(-ScalingPivot,chain[TransformationComp_ScalingPivotInverse]);
  83.662 +		}
  83.663 +
  83.664 +		const aiVector3D& Translation = PropertyGet<aiVector3D>(props,"Lcl Translation",ok);
  83.665 +		if(ok && Translation.SquareLength() > zero_epsilon) {
  83.666 +			aiMatrix4x4::Translation(Translation,chain[TransformationComp_Translation]);
  83.667 +		}
  83.668 +
  83.669 +		const aiVector3D& Scaling = PropertyGet<aiVector3D>(props,"Lcl Scaling",ok);
  83.670 +		if(ok && fabs(Scaling.SquareLength()-1.0f) > zero_epsilon) {
  83.671 +			aiMatrix4x4::Scaling(Scaling,chain[TransformationComp_Scaling]);
  83.672 +		}
  83.673 +
  83.674 +		const aiVector3D& Rotation = PropertyGet<aiVector3D>(props,"Lcl Rotation",ok);
  83.675 +		if(ok && Rotation.SquareLength() > zero_epsilon) {
  83.676 +			GetRotationMatrix(rot, Rotation, chain[TransformationComp_Rotation]);
  83.677 +		}
  83.678 +
  83.679 +		// is_complex needs to be consistent with NeedsComplexTransformationChain()
  83.680 +		// or the interplay between this code and the animation converter would
  83.681 +		// not be guaranteed.
  83.682 +		ai_assert(NeedsComplexTransformationChain(model) == is_complex);
  83.683 +
  83.684 +		const std::string& name = FixNodeName(model.Name());
  83.685 +
  83.686 +		// now, if we have more than just Translation, Scaling and Rotation,
  83.687 +		// we need to generate a full node chain to accommodate for assimp's
  83.688 +		// lack to express pivots and offsets.
  83.689 +		if(is_complex && doc.Settings().preservePivots) {
  83.690 +			FBXImporter::LogInfo("generating full transformation chain for node: " + name);
  83.691 +
  83.692 +			// query the anim_chain_bits dictionary to find out which chain elements
  83.693 +			// have associated node animation channels. These can not be dropped 
  83.694 +			// even if they have identity transform in bind pose.
  83.695 +			NodeAnimBitMap::const_iterator it = node_anim_chain_bits.find(name);
  83.696 +			const unsigned int anim_chain_bitmask = (it == node_anim_chain_bits.end() ? 0 : (*it).second);
  83.697 +
  83.698 +			unsigned int bit = 0x1;
  83.699 +			for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) {
  83.700 +				const TransformationComp comp = static_cast<TransformationComp>(i);
  83.701 +				
  83.702 +				if (chain[i].IsIdentity() && (anim_chain_bitmask & bit) == 0) {
  83.703 +					continue;
  83.704 +				}
  83.705 +
  83.706 +				aiNode* nd = new aiNode();
  83.707 +				output_nodes.push_back(nd);
  83.708 +				
  83.709 +				nd->mName.Set(NameTransformationChainNode(name, comp));
  83.710 +				nd->mTransformation = chain[i];
  83.711 +			}
  83.712 +
  83.713 +			ai_assert(output_nodes.size());
  83.714 +			return;
  83.715 +		}
  83.716 +
  83.717 +		// else, we can just multiply the matrices together
  83.718 +		aiNode* nd = new aiNode();
  83.719 +		output_nodes.push_back(nd);
  83.720 +
  83.721 +		nd->mName.Set(name);
  83.722 +
  83.723 +		for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
  83.724 +			nd->mTransformation = nd->mTransformation * chain[i];
  83.725 +		}
  83.726 +	}
  83.727 +
  83.728 +
  83.729 +	// ------------------------------------------------------------------------------------------------
  83.730 +	void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform)
  83.731 +	{
  83.732 +		const std::vector<const Geometry*>& geos = model.GetGeometry();
  83.733 +
  83.734 +		std::vector<unsigned int> meshes;
  83.735 +		meshes.reserve(geos.size());
  83.736 +
  83.737 +		BOOST_FOREACH(const Geometry* geo, geos) {
  83.738 +
  83.739 +			const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
  83.740 +			if(mesh) {
  83.741 +				const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform);
  83.742 +				std::copy(indices.begin(),indices.end(),std::back_inserter(meshes) );
  83.743 +			}
  83.744 +			else {
  83.745 +				FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name());
  83.746 +			}
  83.747 +		}
  83.748 +
  83.749 +		if(meshes.size()) {
  83.750 +			nd.mMeshes = new unsigned int[meshes.size()]();
  83.751 +			nd.mNumMeshes = static_cast<unsigned int>(meshes.size());
  83.752 +
  83.753 +			std::swap_ranges(meshes.begin(),meshes.end(),nd.mMeshes);
  83.754 +		}
  83.755 +	}
  83.756 +
  83.757 +
  83.758 +	// ------------------------------------------------------------------------------------------------
  83.759 +	// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
  83.760 +	std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh,const Model& model, 
  83.761 +		const aiMatrix4x4& node_global_transform)
  83.762 +	{
  83.763 +		std::vector<unsigned int> temp; 
  83.764 +
  83.765 +		MeshMap::const_iterator it = meshes_converted.find(&mesh);
  83.766 +		if (it != meshes_converted.end()) {
  83.767 +			std::copy((*it).second.begin(),(*it).second.end(),std::back_inserter(temp));
  83.768 +			return temp;
  83.769 +		}
  83.770 +
  83.771 +		const std::vector<aiVector3D>& vertices = mesh.GetVertices();
  83.772 +		const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
  83.773 +		if(vertices.empty() || faces.empty()) {
  83.774 +			FBXImporter::LogWarn("ignoring empty geometry: " + mesh.Name());
  83.775 +			return temp;
  83.776 +		}
  83.777 +
  83.778 +		// one material per mesh maps easily to aiMesh. Multiple material 
  83.779 +		// meshes need to be split.
  83.780 +		const MatIndexArray& mindices = mesh.GetMaterialIndices();
  83.781 +		if (doc.Settings().readMaterials && !mindices.empty()) {
  83.782 +			const MatIndexArray::value_type base = mindices[0];
  83.783 +			BOOST_FOREACH(MatIndexArray::value_type index, mindices) {
  83.784 +				if(index != base) {
  83.785 +					return ConvertMeshMultiMaterial(mesh, model, node_global_transform);
  83.786 +				}
  83.787 +			}
  83.788 +		}
  83.789 +
  83.790 +		// faster codepath, just copy the data
  83.791 +		temp.push_back(ConvertMeshSingleMaterial(mesh, model, node_global_transform));
  83.792 +		return temp;
  83.793 +	}
  83.794 +
  83.795 +
  83.796 +	// ------------------------------------------------------------------------------------------------
  83.797 +	aiMesh* SetupEmptyMesh(const MeshGeometry& mesh)
  83.798 +	{
  83.799 +		aiMesh* const out_mesh = new aiMesh();
  83.800 +		meshes.push_back(out_mesh);
  83.801 +		meshes_converted[&mesh].push_back(static_cast<unsigned int>(meshes.size()-1));
  83.802 +
  83.803 +		// set name
  83.804 +		std::string name = mesh.Name();
  83.805 +		if (name.substr(0,10) == "Geometry::") {
  83.806 +			name = name.substr(10);
  83.807 +		}
  83.808 +
  83.809 +		if(name.length()) {
  83.810 +			out_mesh->mName.Set(name);
  83.811 +		}
  83.812 +
  83.813 +		return out_mesh;
  83.814 +	}
  83.815 +
  83.816 +
  83.817 +	// ------------------------------------------------------------------------------------------------
  83.818 +	unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model, 
  83.819 +		const aiMatrix4x4& node_global_transform)	
  83.820 +	{
  83.821 +		const MatIndexArray& mindices = mesh.GetMaterialIndices();
  83.822 +		aiMesh* const out_mesh = SetupEmptyMesh(mesh); 
  83.823 +
  83.824 +		const std::vector<aiVector3D>& vertices = mesh.GetVertices();
  83.825 +		const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
  83.826 +
  83.827 +		// copy vertices
  83.828 +		out_mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
  83.829 +		out_mesh->mVertices = new aiVector3D[vertices.size()];
  83.830 +		std::copy(vertices.begin(),vertices.end(),out_mesh->mVertices);
  83.831 +
  83.832 +		// generate dummy faces
  83.833 +		out_mesh->mNumFaces = static_cast<unsigned int>(faces.size());
  83.834 +		aiFace* fac = out_mesh->mFaces = new aiFace[faces.size()]();
  83.835 +
  83.836 +		unsigned int cursor = 0;
  83.837 +		BOOST_FOREACH(unsigned int pcount, faces) {
  83.838 +			aiFace& f = *fac++;
  83.839 +			f.mNumIndices = pcount;
  83.840 +			f.mIndices = new unsigned int[pcount];
  83.841 +			switch(pcount) 
  83.842 +			{
  83.843 +			case 1:
  83.844 +				out_mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
  83.845 +				break;
  83.846 +			case 2:
  83.847 +				out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
  83.848 +				break;
  83.849 +			case 3:
  83.850 +				out_mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  83.851 +				break;
  83.852 +			default:
  83.853 +				out_mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
  83.854 +				break;
  83.855 +			}
  83.856 +			for (unsigned int i = 0; i < pcount; ++i) {
  83.857 +				f.mIndices[i] = cursor++;
  83.858 +			}
  83.859 +		}
  83.860 +
  83.861 +		// copy normals
  83.862 +		const std::vector<aiVector3D>& normals = mesh.GetNormals();
  83.863 +		if(normals.size()) {
  83.864 +			ai_assert(normals.size() == vertices.size());
  83.865 +
  83.866 +			out_mesh->mNormals = new aiVector3D[vertices.size()];
  83.867 +			std::copy(normals.begin(),normals.end(),out_mesh->mNormals);
  83.868 +		}
  83.869 +
  83.870 +		// copy tangents - assimp requires both tangents and bitangents (binormals)
  83.871 +		// to be present, or neither of them. Compute binormals from normals
  83.872 +		// and tangents if needed.
  83.873 +		const std::vector<aiVector3D>& tangents = mesh.GetTangents();
  83.874 +		const std::vector<aiVector3D>* binormals = &mesh.GetBinormals();
  83.875 +
  83.876 +		if(tangents.size()) {
  83.877 +			std::vector<aiVector3D> tempBinormals;
  83.878 +			if (!binormals->size()) {
  83.879 +				if (normals.size()) {
  83.880 +					tempBinormals.resize(normals.size());
  83.881 +					for (unsigned int i = 0; i < tangents.size(); ++i) {
  83.882 +						tempBinormals[i] = normals[i] ^ tangents[i];
  83.883 +					}
  83.884 +
  83.885 +					binormals = &tempBinormals;
  83.886 +				}
  83.887 +				else {
  83.888 +					binormals = NULL;	
  83.889 +				}
  83.890 +			}
  83.891 +
  83.892 +			if(binormals) {
  83.893 +				ai_assert(tangents.size() == vertices.size() && binormals->size() == vertices.size());
  83.894 +
  83.895 +				out_mesh->mTangents = new aiVector3D[vertices.size()];
  83.896 +				std::copy(tangents.begin(),tangents.end(),out_mesh->mTangents);
  83.897 +
  83.898 +				out_mesh->mBitangents = new aiVector3D[vertices.size()];
  83.899 +				std::copy(binormals->begin(),binormals->end(),out_mesh->mBitangents);
  83.900 +			}
  83.901 +		}
  83.902 +
  83.903 +		// copy texture coords
  83.904 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
  83.905 +			const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords(i);
  83.906 +			if(uvs.empty()) {
  83.907 +				break;
  83.908 +			}
  83.909 +
  83.910 +			aiVector3D* out_uv = out_mesh->mTextureCoords[i] = new aiVector3D[vertices.size()];
  83.911 +			BOOST_FOREACH(const aiVector2D& v, uvs) {
  83.912 +				*out_uv++ = aiVector3D(v.x,v.y,0.0f);
  83.913 +			}
  83.914 +
  83.915 +			out_mesh->mNumUVComponents[i] = 2;
  83.916 +		}
  83.917 +
  83.918 +		// copy vertex colors
  83.919 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
  83.920 +			const std::vector<aiColor4D>& colors = mesh.GetVertexColors(i);
  83.921 +			if(colors.empty()) {
  83.922 +				break;
  83.923 +			}
  83.924 +
  83.925 +			out_mesh->mColors[i] = new aiColor4D[vertices.size()];
  83.926 +			std::copy(colors.begin(),colors.end(),out_mesh->mColors[i]);
  83.927 +		}
  83.928 +
  83.929 +		if(!doc.Settings().readMaterials || mindices.empty()) {
  83.930 +			FBXImporter::LogError("no material assigned to mesh, setting default material");
  83.931 +			out_mesh->mMaterialIndex = GetDefaultMaterial();
  83.932 +		}
  83.933 +		else {
  83.934 +			ConvertMaterialForMesh(out_mesh,model,mesh,mindices[0]);
  83.935 +		}
  83.936 +
  83.937 +		if(doc.Settings().readWeights && mesh.DeformerSkin() != NULL) {
  83.938 +			ConvertWeights(out_mesh, model, mesh, node_global_transform, NO_MATERIAL_SEPARATION);
  83.939 +		}
  83.940 +
  83.941 +		return static_cast<unsigned int>(meshes.size() - 1);
  83.942 +	}
  83.943 +
  83.944 +
  83.945 +	// ------------------------------------------------------------------------------------------------
  83.946 +	std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, 
  83.947 +		const aiMatrix4x4& node_global_transform)	
  83.948 +	{
  83.949 +		const MatIndexArray& mindices = mesh.GetMaterialIndices();
  83.950 +		ai_assert(mindices.size());
  83.951 +	
  83.952 +		std::set<MatIndexArray::value_type> had;
  83.953 +		std::vector<unsigned int> indices;
  83.954 +
  83.955 +		BOOST_FOREACH(MatIndexArray::value_type index, mindices) {
  83.956 +			if(had.find(index) == had.end()) {
  83.957 +
  83.958 +				indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, node_global_transform));
  83.959 +				had.insert(index);
  83.960 +			}
  83.961 +		}
  83.962 +
  83.963 +		return indices;
  83.964 +	}
  83.965 +
  83.966 +
  83.967 +	// ------------------------------------------------------------------------------------------------
  83.968 +	unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, 
  83.969 +		MatIndexArray::value_type index, 
  83.970 +		const aiMatrix4x4& node_global_transform)	
  83.971 +	{
  83.972 +		aiMesh* const out_mesh = SetupEmptyMesh(mesh);
  83.973 +
  83.974 +		const MatIndexArray& mindices = mesh.GetMaterialIndices();
  83.975 +		const std::vector<aiVector3D>& vertices = mesh.GetVertices();
  83.976 +		const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
  83.977 +
  83.978 +		const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != NULL;
  83.979 +
  83.980 +		unsigned int count_faces = 0;
  83.981 +		unsigned int count_vertices = 0;
  83.982 +
  83.983 +		// count faces
  83.984 +		std::vector<unsigned int>::const_iterator itf = faces.begin();
  83.985 +		for(MatIndexArray::const_iterator it = mindices.begin(), 
  83.986 +			end = mindices.end(); it != end; ++it, ++itf) 
  83.987 +		{	
  83.988 +			if ((*it) != index) {
  83.989 +				continue;
  83.990 +			}
  83.991 +			++count_faces;
  83.992 +			count_vertices += *itf;
  83.993 +		}
  83.994 +
  83.995 +		ai_assert(count_faces);
  83.996 +		ai_assert(count_vertices);
  83.997 +
  83.998 +		// mapping from output indices to DOM indexing, needed to resolve weights
  83.999 +		std::vector<unsigned int> reverseMapping;
 83.1000 +
 83.1001 +		if (process_weights) {
 83.1002 +			reverseMapping.resize(count_vertices);
 83.1003 +		}
 83.1004 +
 83.1005 +		// allocate output data arrays, but don't fill them yet
 83.1006 +		out_mesh->mNumVertices = count_vertices;
 83.1007 +		out_mesh->mVertices = new aiVector3D[count_vertices];
 83.1008 +
 83.1009 +		out_mesh->mNumFaces = count_faces;
 83.1010 +		aiFace* fac = out_mesh->mFaces = new aiFace[count_faces]();
 83.1011 +
 83.1012 +
 83.1013 +		// allocate normals
 83.1014 +		const std::vector<aiVector3D>& normals = mesh.GetNormals();
 83.1015 +		if(normals.size()) {
 83.1016 +			ai_assert(normals.size() == vertices.size());
 83.1017 +			out_mesh->mNormals = new aiVector3D[vertices.size()];
 83.1018 +		}
 83.1019 +
 83.1020 +		// allocate tangents, binormals. 
 83.1021 +		const std::vector<aiVector3D>& tangents = mesh.GetTangents();
 83.1022 +		const std::vector<aiVector3D>* binormals = &mesh.GetBinormals();
 83.1023 +
 83.1024 +		if(tangents.size()) {
 83.1025 +			std::vector<aiVector3D> tempBinormals;
 83.1026 +			if (!binormals->size()) {
 83.1027 +				if (normals.size()) {
 83.1028 +					// XXX this computes the binormals for the entire mesh, not only 
 83.1029 +					// the part for which we need them.
 83.1030 +					tempBinormals.resize(normals.size());
 83.1031 +					for (unsigned int i = 0; i < tangents.size(); ++i) {
 83.1032 +						tempBinormals[i] = normals[i] ^ tangents[i];
 83.1033 +					}
 83.1034 +
 83.1035 +					binormals = &tempBinormals;
 83.1036 +				}
 83.1037 +				else {
 83.1038 +					binormals = NULL;	
 83.1039 +				}
 83.1040 +			}
 83.1041 +
 83.1042 +			if(binormals) {
 83.1043 +				ai_assert(tangents.size() == vertices.size() && binormals->size() == vertices.size());
 83.1044 +
 83.1045 +				out_mesh->mTangents = new aiVector3D[vertices.size()];
 83.1046 +				out_mesh->mBitangents = new aiVector3D[vertices.size()];
 83.1047 +			}
 83.1048 +		}
 83.1049 +
 83.1050 +		// allocate texture coords
 83.1051 +		unsigned int num_uvs = 0;
 83.1052 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i, ++num_uvs) {
 83.1053 +			const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords(i);
 83.1054 +			if(uvs.empty()) {
 83.1055 +				break;
 83.1056 +			}
 83.1057 +
 83.1058 +			out_mesh->mTextureCoords[i] = new aiVector3D[vertices.size()];
 83.1059 +			out_mesh->mNumUVComponents[i] = 2;
 83.1060 +		}
 83.1061 +
 83.1062 +		// allocate vertex colors
 83.1063 +		unsigned int num_vcs = 0;
 83.1064 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i, ++num_vcs) {
 83.1065 +			const std::vector<aiColor4D>& colors = mesh.GetVertexColors(i);
 83.1066 +			if(colors.empty()) {
 83.1067 +				break;
 83.1068 +			}
 83.1069 +
 83.1070 +			out_mesh->mColors[i] = new aiColor4D[vertices.size()];
 83.1071 +		}
 83.1072 +
 83.1073 +		unsigned int cursor = 0, in_cursor = 0;
 83.1074 +
 83.1075 +		itf = faces.begin();
 83.1076 +		for(MatIndexArray::const_iterator it = mindices.begin(), 
 83.1077 +			end = mindices.end(); it != end; ++it, ++itf) 
 83.1078 +		{	
 83.1079 +			const unsigned int pcount = *itf;
 83.1080 +			if ((*it) != index) {
 83.1081 +				in_cursor += pcount;
 83.1082 +				continue;
 83.1083 +			}
 83.1084 +
 83.1085 +			aiFace& f = *fac++;
 83.1086 +
 83.1087 +			f.mNumIndices = pcount;
 83.1088 +			f.mIndices = new unsigned int[pcount];
 83.1089 +			switch(pcount) 
 83.1090 +			{
 83.1091 +			case 1:
 83.1092 +				out_mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
 83.1093 +				break;
 83.1094 +			case 2:
 83.1095 +				out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
 83.1096 +				break;
 83.1097 +			case 3:
 83.1098 +				out_mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
 83.1099 +				break;
 83.1100 +			default:
 83.1101 +				out_mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
 83.1102 +				break;
 83.1103 +			}
 83.1104 +			for (unsigned int i = 0; i < pcount; ++i, ++cursor, ++in_cursor) {
 83.1105 +				f.mIndices[i] = cursor;
 83.1106 +
 83.1107 +				if(reverseMapping.size()) {
 83.1108 +					reverseMapping[cursor] = in_cursor;
 83.1109 +				}
 83.1110 +
 83.1111 +				out_mesh->mVertices[cursor] = vertices[in_cursor];
 83.1112 +
 83.1113 +				if(out_mesh->mNormals) {
 83.1114 +					out_mesh->mNormals[cursor] = normals[in_cursor];
 83.1115 +				}
 83.1116 +
 83.1117 +				if(out_mesh->mTangents) {
 83.1118 +					out_mesh->mTangents[cursor] = tangents[in_cursor];
 83.1119 +					out_mesh->mBitangents[cursor] = (*binormals)[in_cursor];
 83.1120 +				}
 83.1121 +
 83.1122 +				for (unsigned int i = 0; i < num_uvs; ++i) {
 83.1123 +					const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords(i);
 83.1124 +					out_mesh->mTextureCoords[i][cursor] = aiVector3D(uvs[in_cursor].x,uvs[in_cursor].y, 0.0f);
 83.1125 +				}
 83.1126 +
 83.1127 +				for (unsigned int i = 0; i < num_vcs; ++i) {
 83.1128 +					const std::vector<aiColor4D>& cols = mesh.GetVertexColors(i);
 83.1129 +					out_mesh->mColors[i][cursor] = cols[in_cursor];
 83.1130 +				}
 83.1131 +			}
 83.1132 +		}
 83.1133 +	
 83.1134 +		ConvertMaterialForMesh(out_mesh,model,mesh,index);
 83.1135 +
 83.1136 +		if(process_weights) {
 83.1137 +			ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping);
 83.1138 +		}
 83.1139 +
 83.1140 +		return static_cast<unsigned int>(meshes.size() - 1);
 83.1141 +	}
 83.1142 +
 83.1143 +	static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */ 
 83.1144 +		static_cast<unsigned int>(-1);
 83.1145 +
 83.1146 +
 83.1147 +	// ------------------------------------------------------------------------------------------------
 83.1148 +	/** - if materialIndex == NO_MATERIAL_SEPARATION, materials are not taken into
 83.1149 +	 *  account when determining which weights to include. 
 83.1150 +	 *  - outputVertStartIndices is only used when a material index is specified, it gives for
 83.1151 +	 *    each output vertex the DOM index it maps to. */
 83.1152 +	void ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo, 
 83.1153 +		const aiMatrix4x4& node_global_transform = aiMatrix4x4(),
 83.1154 +		unsigned int materialIndex = NO_MATERIAL_SEPARATION, 
 83.1155 +		std::vector<unsigned int>* outputVertStartIndices = NULL)
 83.1156 +	{
 83.1157 +		ai_assert(geo.DeformerSkin());
 83.1158 +
 83.1159 +		std::vector<size_t> out_indices;
 83.1160 +		std::vector<size_t> index_out_indices;
 83.1161 +		std::vector<size_t> count_out_indices;
 83.1162 +
 83.1163 +		const Skin& sk = *geo.DeformerSkin();
 83.1164 +
 83.1165 +		std::vector<aiBone*> bones;
 83.1166 +		bones.reserve(sk.Clusters().size());
 83.1167 +
 83.1168 +		const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
 83.1169 +		ai_assert(no_mat_check || outputVertStartIndices);
 83.1170 +
 83.1171 +		try {
 83.1172 +
 83.1173 +			BOOST_FOREACH(const Cluster* cluster, sk.Clusters()) {
 83.1174 +				ai_assert(cluster);
 83.1175 +
 83.1176 +				const WeightIndexArray& indices = cluster->GetIndices();
 83.1177 +
 83.1178 +				if(indices.empty()) {
 83.1179 +					continue;
 83.1180 +				}
 83.1181 +
 83.1182 +				const MatIndexArray& mats = geo.GetMaterialIndices();
 83.1183 +
 83.1184 +				bool ok = false;		
 83.1185 +
 83.1186 +				const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
 83.1187 +
 83.1188 +				count_out_indices.clear();
 83.1189 +				index_out_indices.clear();
 83.1190 +				out_indices.clear();
 83.1191 +
 83.1192 +				// now check if *any* of these weights is contained in the output mesh,
 83.1193 +				// taking notes so we don't need to do it twice.
 83.1194 +				BOOST_FOREACH(WeightIndexArray::value_type index, indices) {
 83.1195 +
 83.1196 +					unsigned int count;
 83.1197 +					const unsigned int* const out_idx = geo.ToOutputVertexIndex(index, count);
 83.1198 +
 83.1199 +					index_out_indices.push_back(no_index_sentinel);
 83.1200 +					count_out_indices.push_back(0);
 83.1201 +
 83.1202 +					for(unsigned int i = 0; i < count; ++i) {					
 83.1203 +						if (no_mat_check || static_cast<size_t>(mats[geo.FaceForVertexIndex(out_idx[i])]) == materialIndex) {
 83.1204 +							
 83.1205 +							if (index_out_indices.back() == no_index_sentinel) {
 83.1206 +								index_out_indices.back() = out_indices.size();
 83.1207 +								
 83.1208 +							}
 83.1209 +
 83.1210 +							if (no_mat_check) {
 83.1211 +								out_indices.push_back(out_idx[i]);
 83.1212 +							}
 83.1213 +							else {
 83.1214 +								// this extra lookup is in O(logn), so the entire algorithm becomes O(nlogn)
 83.1215 +								const std::vector<unsigned int>::iterator it = std::lower_bound(
 83.1216 +									outputVertStartIndices->begin(),
 83.1217 +									outputVertStartIndices->end(),
 83.1218 +									out_idx[i]
 83.1219 +								);
 83.1220 +
 83.1221 +								out_indices.push_back(std::distance(outputVertStartIndices->begin(), it));
 83.1222 +							}
 83.1223 +
 83.1224 +							++count_out_indices.back();
 83.1225 +							ok = true;
 83.1226 +						}
 83.1227 +					}		
 83.1228 +				}
 83.1229 +
 83.1230 +				// if we found at least one, generate the output bones
 83.1231 +				// XXX this could be heavily simplified by collecting the bone
 83.1232 +				// data in a single step.
 83.1233 +				if (ok) {
 83.1234 +					ConvertCluster(bones, model, *cluster, out_indices, index_out_indices, 
 83.1235 +						count_out_indices, node_global_transform);
 83.1236 +				}
 83.1237 +			}
 83.1238 +		}
 83.1239 +		catch (std::exception&) {
 83.1240 +			std::for_each(bones.begin(),bones.end(),Util::delete_fun<aiBone>());
 83.1241 +			throw;
 83.1242 +		}
 83.1243 +
 83.1244 +		if(bones.empty()) {
 83.1245 +			return;
 83.1246 +		}
 83.1247 +
 83.1248 +		out->mBones = new aiBone*[bones.size()]();
 83.1249 +		out->mNumBones = static_cast<unsigned int>(bones.size());
 83.1250 +
 83.1251 +		std::swap_ranges(bones.begin(),bones.end(),out->mBones);
 83.1252 +	}
 83.1253 +
 83.1254 +
 83.1255 +
 83.1256 +	// ------------------------------------------------------------------------------------------------
 83.1257 +	void ConvertCluster(std::vector<aiBone*>& bones, const Model& model, const Cluster& cl, 		
 83.1258 +		std::vector<size_t>& out_indices,
 83.1259 +		std::vector<size_t>& index_out_indices,
 83.1260 +		std::vector<size_t>& count_out_indices,
 83.1261 +		const aiMatrix4x4& node_global_transform)
 83.1262 +	{
 83.1263 +
 83.1264 +		aiBone* const bone = new aiBone();
 83.1265 +		bones.push_back(bone);
 83.1266 +
 83.1267 +		bone->mName = FixNodeName(cl.TargetNode()->Name());
 83.1268 +
 83.1269 +		bone->mOffsetMatrix = cl.TransformLink();
 83.1270 +		bone->mOffsetMatrix.Inverse();
 83.1271 +
 83.1272 +		bone->mOffsetMatrix = bone->mOffsetMatrix * node_global_transform;
 83.1273 +
 83.1274 +		bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
 83.1275 +		aiVertexWeight* cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
 83.1276 +
 83.1277 +		const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
 83.1278 +		const WeightArray& weights = cl.GetWeights();
 83.1279 +
 83.1280 +		const size_t c = index_out_indices.size();
 83.1281 +		for (size_t i = 0; i < c; ++i) {
 83.1282 +			const size_t index_index =  index_out_indices[i];
 83.1283 +
 83.1284 +			if (index_index == no_index_sentinel) {
 83.1285 +				continue;
 83.1286 +			}
 83.1287 +
 83.1288 +			const size_t cc = count_out_indices[i];
 83.1289 +			for (size_t j = 0; j < cc; ++j) {
 83.1290 +				aiVertexWeight& out_weight = *cursor++;
 83.1291 +
 83.1292 +				out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]);
 83.1293 +				out_weight.mWeight = weights[i];
 83.1294 +			}			
 83.1295 +		}
 83.1296 +	}
 83.1297 +
 83.1298 +
 83.1299 +	// ------------------------------------------------------------------------------------------------
 83.1300 +	void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo, 
 83.1301 +		MatIndexArray::value_type materialIndex)
 83.1302 +	{
 83.1303 +		// locate source materials for this mesh
 83.1304 +		const std::vector<const Material*>& mats = model.GetMaterials();
 83.1305 +		if (static_cast<unsigned int>(materialIndex) >= mats.size() || materialIndex < 0) {
 83.1306 +			FBXImporter::LogError("material index out of bounds, setting default material");
 83.1307 +			out->mMaterialIndex = GetDefaultMaterial();
 83.1308 +			return;
 83.1309 +		}
 83.1310 +
 83.1311 +		const Material* const mat = mats[materialIndex];
 83.1312 +		MaterialMap::const_iterator it = materials_converted.find(mat);
 83.1313 +		if (it != materials_converted.end()) {
 83.1314 +			out->mMaterialIndex = (*it).second;
 83.1315 +			return;
 83.1316 +		}
 83.1317 +
 83.1318 +		out->mMaterialIndex = ConvertMaterial(*mat);	
 83.1319 +		materials_converted[mat] = out->mMaterialIndex;
 83.1320 +	}
 83.1321 +
 83.1322 +
 83.1323 +	// ------------------------------------------------------------------------------------------------
 83.1324 +	unsigned int GetDefaultMaterial()
 83.1325 +	{
 83.1326 +		if (defaultMaterialIndex) {
 83.1327 +			return defaultMaterialIndex - 1; 
 83.1328 +		}
 83.1329 +
 83.1330 +		aiMaterial* out_mat = new aiMaterial();
 83.1331 +		materials.push_back(out_mat);
 83.1332 +
 83.1333 +		const aiColor3D diffuse = aiColor3D(0.8f,0.8f,0.8f);
 83.1334 +		out_mat->AddProperty(&diffuse,1,AI_MATKEY_COLOR_DIFFUSE);
 83.1335 +
 83.1336 +		aiString s;
 83.1337 +		s.Set(AI_DEFAULT_MATERIAL_NAME);
 83.1338 +
 83.1339 +		out_mat->AddProperty(&s,AI_MATKEY_NAME);
 83.1340 +
 83.1341 +		defaultMaterialIndex = static_cast<unsigned int>(materials.size());
 83.1342 +		return defaultMaterialIndex - 1;
 83.1343 +	}
 83.1344 +
 83.1345 +
 83.1346 +	// ------------------------------------------------------------------------------------------------
 83.1347 +	// Material -> aiMaterial
 83.1348 +	unsigned int ConvertMaterial(const Material& material)
 83.1349 +	{
 83.1350 +		const PropertyTable& props = material.Props();
 83.1351 +
 83.1352 +		// generate empty output material
 83.1353 +		aiMaterial* out_mat = new aiMaterial();
 83.1354 +		materials_converted[&material] = static_cast<unsigned int>(materials.size());
 83.1355 +
 83.1356 +		materials.push_back(out_mat);
 83.1357 +
 83.1358 +		aiString str;
 83.1359 +
 83.1360 +		// stip Material:: prefix
 83.1361 +		std::string name = material.Name();
 83.1362 +		if(name.substr(0,10) == "Material::") {
 83.1363 +			name = name.substr(10);
 83.1364 +		}
 83.1365 +
 83.1366 +		// set material name if not empty - this could happen
 83.1367 +		// and there should be no key for it in this case.
 83.1368 +		if(name.length()) {
 83.1369 +			str.Set(name);
 83.1370 +			out_mat->AddProperty(&str,AI_MATKEY_NAME);
 83.1371 +		}
 83.1372 +
 83.1373 +		// shading stuff and colors
 83.1374 +		SetShadingPropertiesCommon(out_mat,props);
 83.1375 +	
 83.1376 +		// texture assignments
 83.1377 +		SetTextureProperties(out_mat,material.Textures());
 83.1378 +
 83.1379 +		return static_cast<unsigned int>(materials.size() - 1);
 83.1380 +	}
 83.1381 +
 83.1382 +
 83.1383 +	// ------------------------------------------------------------------------------------------------
 83.1384 +	void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures, 
 83.1385 +		const std::string& propName, 
 83.1386 +		aiTextureType target)
 83.1387 +	{
 83.1388 +		TextureMap::const_iterator it = textures.find(propName);
 83.1389 +		if(it == textures.end()) {
 83.1390 +			return;
 83.1391 +		}
 83.1392 +
 83.1393 +		const Texture* const tex = (*it).second;
 83.1394 +		
 83.1395 +		aiString path;
 83.1396 +		path.Set(tex->RelativeFilename());
 83.1397 +
 83.1398 +		out_mat->AddProperty(&path,_AI_MATKEY_TEXTURE_BASE,target,0);
 83.1399 +
 83.1400 +		aiUVTransform uvTrafo;
 83.1401 +		// XXX handle all kinds of UV transformations
 83.1402 +		uvTrafo.mScaling = tex->UVScaling();
 83.1403 +		uvTrafo.mTranslation = tex->UVTranslation();
 83.1404 +		out_mat->AddProperty(&uvTrafo,1,_AI_MATKEY_UVTRANSFORM_BASE,target,0);
 83.1405 +
 83.1406 +		const PropertyTable& props = tex->Props();
 83.1407 +
 83.1408 +		int uvIndex = 0;
 83.1409 +
 83.1410 +		bool ok;
 83.1411 +		const std::string& uvSet = PropertyGet<std::string>(props,"UVSet",ok);
 83.1412 +		if(ok) {
 83.1413 +			// "default" is the name which usually appears in the FbxFileTexture template
 83.1414 +			if(uvSet != "default" && uvSet.length()) {
 83.1415 +				// this is a bit awkward - we need to find a mesh that uses this
 83.1416 +				// material and scan its UV channels for the given UV name because
 83.1417 +				// assimp references UV channels by index, not by name.
 83.1418 +
 83.1419 +				// XXX: the case that UV channels may appear in different orders
 83.1420 +				// in meshes is unhandled. A possible solution would be to sort
 83.1421 +				// the UV channels alphabetically, but this would have the side
 83.1422 +				// effect that the primary (first) UV channel would sometimes
 83.1423 +				// be moved, causing trouble when users read only the first
 83.1424 +				// UV channel and ignore UV channel assignments altogether.
 83.1425 +
 83.1426 +				const unsigned int matIndex = static_cast<unsigned int>(std::distance(materials.begin(), 
 83.1427 +					std::find(materials.begin(),materials.end(),out_mat)
 83.1428 +				));
 83.1429 +
 83.1430 +				uvIndex = -1;
 83.1431 +				BOOST_FOREACH(const MeshMap::value_type& v,meshes_converted) {
 83.1432 +					const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*> (v.first);
 83.1433 +					if(!mesh) {
 83.1434 +						continue;
 83.1435 +					}
 83.1436 +
 83.1437 +					const MatIndexArray& mats = mesh->GetMaterialIndices();
 83.1438 +					if(std::find(mats.begin(),mats.end(),matIndex) == mats.end()) {
 83.1439 +						continue;
 83.1440 +					}
 83.1441 +
 83.1442 +					int index = -1;
 83.1443 +					for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
 83.1444 +						if(mesh->GetTextureCoords(i).empty()) {
 83.1445 +							break;
 83.1446 +						}
 83.1447 +						const std::string& name = mesh->GetTextureCoordChannelName(i);
 83.1448 +						if(name == uvSet) {
 83.1449 +							index = static_cast<int>(i);
 83.1450 +							break;
 83.1451 +						}
 83.1452 +					}
 83.1453 +					if(index == -1) {
 83.1454 +						FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
 83.1455 +						continue;
 83.1456 +					}
 83.1457 +
 83.1458 +					if(uvIndex == -1) {
 83.1459 +						uvIndex = index;
 83.1460 +					}
 83.1461 +					else {
 83.1462 +						FBXImporter::LogWarn("the UV channel named " + uvSet + 
 83.1463 +							" appears at different positions in meshes, results will be wrong");
 83.1464 +					}
 83.1465 +				}
 83.1466 +
 83.1467 +				if(uvIndex == -1) {
 83.1468 +					FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel");
 83.1469 +					uvIndex = 0;
 83.1470 +				}
 83.1471 +			}
 83.1472 +		}
 83.1473 +
 83.1474 +		out_mat->AddProperty(&uvIndex,1,_AI_MATKEY_UVWSRC_BASE,target,0);
 83.1475 +	}
 83.1476 +
 83.1477 +
 83.1478 +	// ------------------------------------------------------------------------------------------------
 83.1479 +	void SetTextureProperties(aiMaterial* out_mat, const TextureMap& textures)
 83.1480 +	{
 83.1481 +		TrySetTextureProperties(out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE);
 83.1482 +		TrySetTextureProperties(out_mat, textures, "AmbientColor", aiTextureType_AMBIENT);
 83.1483 +		TrySetTextureProperties(out_mat, textures, "EmissiveColor", aiTextureType_EMISSIVE);
 83.1484 +		TrySetTextureProperties(out_mat, textures, "SpecularColor", aiTextureType_SPECULAR);
 83.1485 +		TrySetTextureProperties(out_mat, textures, "TransparentColor", aiTextureType_OPACITY);
 83.1486 +		TrySetTextureProperties(out_mat, textures, "ReflectionColor", aiTextureType_REFLECTION);
 83.1487 +		TrySetTextureProperties(out_mat, textures, "DisplacementColor", aiTextureType_DISPLACEMENT);
 83.1488 +		TrySetTextureProperties(out_mat, textures, "NormalMap", aiTextureType_NORMALS);
 83.1489 +		TrySetTextureProperties(out_mat, textures, "Bump", aiTextureType_HEIGHT);
 83.1490 +	}
 83.1491 +
 83.1492 +
 83.1493 +
 83.1494 +	// ------------------------------------------------------------------------------------------------
 83.1495 +	aiColor3D GetColorPropertyFromMaterial(const PropertyTable& props, const std::string& baseName, 
 83.1496 +		bool& result)
 83.1497 +	{
 83.1498 +		result = true;
 83.1499 +
 83.1500 +		bool ok;
 83.1501 +		const aiVector3D& Diffuse = PropertyGet<aiVector3D>(props,baseName,ok);
 83.1502 +		if(ok) {
 83.1503 +			return aiColor3D(Diffuse.x,Diffuse.y,Diffuse.z);
 83.1504 +		}
 83.1505 +		else {
 83.1506 +			aiVector3D DiffuseColor = PropertyGet<aiVector3D>(props,baseName + "Color",ok);
 83.1507 +			if(ok) {
 83.1508 +				float DiffuseFactor = PropertyGet<float>(props,baseName + "Factor",ok);
 83.1509 +				if(ok) {
 83.1510 +					DiffuseColor *= DiffuseFactor;
 83.1511 +				}
 83.1512 +
 83.1513 +				return aiColor3D(DiffuseColor.x,DiffuseColor.y,DiffuseColor.z);
 83.1514 +			}
 83.1515 +		}
 83.1516 +		result = false;
 83.1517 +		return aiColor3D(0.0f,0.0f,0.0f);
 83.1518 +	}
 83.1519 +
 83.1520 +
 83.1521 +	// ------------------------------------------------------------------------------------------------
 83.1522 +	void SetShadingPropertiesCommon(aiMaterial* out_mat, const PropertyTable& props)
 83.1523 +	{
 83.1524 +		// set shading properties. There are various, redundant ways in which FBX materials
 83.1525 +		// specify their shading settings (depending on shading models, prop
 83.1526 +		// template etc.). No idea which one is right in a particular context. 
 83.1527 +		// Just try to make sense of it - there's no spec to verify this against, 
 83.1528 +		// so why should we.
 83.1529 +		bool ok;
 83.1530 +		const aiColor3D& Diffuse = GetColorPropertyFromMaterial(props,"Diffuse",ok);
 83.1531 +		if(ok) {
 83.1532 +			out_mat->AddProperty(&Diffuse,1,AI_MATKEY_COLOR_DIFFUSE);
 83.1533 +		}
 83.1534 +
 83.1535 +		const aiColor3D& Emissive = GetColorPropertyFromMaterial(props,"Emissive",ok);
 83.1536 +		if(ok) {
 83.1537 +			out_mat->AddProperty(&Emissive,1,AI_MATKEY_COLOR_EMISSIVE);
 83.1538 +		}
 83.1539 +
 83.1540 +		const aiColor3D& Ambient = GetColorPropertyFromMaterial(props,"Ambient",ok);
 83.1541 +		if(ok) {
 83.1542 +			out_mat->AddProperty(&Ambient,1,AI_MATKEY_COLOR_AMBIENT);
 83.1543 +		}
 83.1544 +
 83.1545 +		const aiColor3D& Specular = GetColorPropertyFromMaterial(props,"Specular",ok);
 83.1546 +		if(ok) {
 83.1547 +			out_mat->AddProperty(&Specular,1,AI_MATKEY_COLOR_SPECULAR);
 83.1548 +		}
 83.1549 +
 83.1550 +		const float Opacity = PropertyGet<float>(props,"Opacity",ok);
 83.1551 +		if(ok) {
 83.1552 +			out_mat->AddProperty(&Opacity,1,AI_MATKEY_OPACITY);
 83.1553 +		}
 83.1554 +
 83.1555 +		const float Reflectivity = PropertyGet<float>(props,"Reflectivity",ok);
 83.1556 +		if(ok) {
 83.1557 +			out_mat->AddProperty(&Reflectivity,1,AI_MATKEY_REFLECTIVITY);
 83.1558 +		}
 83.1559 +
 83.1560 +		const float Shininess = PropertyGet<float>(props,"Shininess",ok);
 83.1561 +		if(ok) {
 83.1562 +			out_mat->AddProperty(&Shininess,1,AI_MATKEY_SHININESS_STRENGTH);
 83.1563 +		}
 83.1564 +
 83.1565 +		const float ShininessExponent = PropertyGet<float>(props,"ShininessExponent",ok);
 83.1566 +		if(ok) {
 83.1567 +			out_mat->AddProperty(&ShininessExponent,1,AI_MATKEY_SHININESS);
 83.1568 +		}
 83.1569 +	}
 83.1570 +
 83.1571 +
 83.1572 +	// ------------------------------------------------------------------------------------------------
 83.1573 +	// get the number of fps for a FrameRate enumerated value
 83.1574 +	static double FrameRateToDouble(FileGlobalSettings::FrameRate fp, double customFPSVal = -1.0)
 83.1575 +	{
 83.1576 +		switch(fp) {
 83.1577 +			case FileGlobalSettings::FrameRate_DEFAULT:
 83.1578 +				return 1.0;
 83.1579 +
 83.1580 +			case FileGlobalSettings::FrameRate_120:
 83.1581 +				return 120.0;
 83.1582 +
 83.1583 +			case FileGlobalSettings::FrameRate_100:
 83.1584 +				return 100.0;
 83.1585 +
 83.1586 +			case FileGlobalSettings::FrameRate_60:
 83.1587 +				return 60.0;
 83.1588 +
 83.1589 +			case FileGlobalSettings::FrameRate_50:
 83.1590 +				return 50.0;
 83.1591 +
 83.1592 +			case FileGlobalSettings::FrameRate_48:
 83.1593 +				return 48.0;
 83.1594 +
 83.1595 +			case FileGlobalSettings::FrameRate_30:
 83.1596 +			case FileGlobalSettings::FrameRate_30_DROP:
 83.1597 +				return 30.0;
 83.1598 +
 83.1599 +			case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME:
 83.1600 +			case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME:
 83.1601 +				return 29.9700262;
 83.1602 +
 83.1603 +			case FileGlobalSettings::FrameRate_PAL:
 83.1604 +				return 25.0;
 83.1605 +
 83.1606 +			case FileGlobalSettings::FrameRate_CINEMA:
 83.1607 +				return 24.0;
 83.1608 +
 83.1609 +			case FileGlobalSettings::FrameRate_1000:
 83.1610 +				return 1000.0;
 83.1611 +
 83.1612 +			case FileGlobalSettings::FrameRate_CINEMA_ND:
 83.1613 +				return 23.976;
 83.1614 +
 83.1615 +			case FileGlobalSettings::FrameRate_CUSTOM:
 83.1616 +				return customFPSVal;
 83.1617 +
 83.1618 +			case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings
 83.1619 +				break;
 83.1620 +		}
 83.1621 +
 83.1622 +		ai_assert(false);
 83.1623 +		return -1.0f;
 83.1624 +	}
 83.1625 +
 83.1626 +
 83.1627 +	// ------------------------------------------------------------------------------------------------
 83.1628 +	// convert animation data to aiAnimation et al
 83.1629 +	void ConvertAnimations() 
 83.1630 +	{
 83.1631 +		// first of all determine framerate
 83.1632 +		const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode();
 83.1633 +		const float custom = doc.GlobalSettings().CustomFrameRate();
 83.1634 +		anim_fps = FrameRateToDouble(fps, custom);
 83.1635 +
 83.1636 +		const std::vector<const AnimationStack*>& animations = doc.AnimationStacks();
 83.1637 +		BOOST_FOREACH(const AnimationStack* stack, animations) {
 83.1638 +			ConvertAnimationStack(*stack);
 83.1639 +		}
 83.1640 +	}
 83.1641 +
 83.1642 +
 83.1643 +	// ------------------------------------------------------------------------------------------------
 83.1644 +	// rename a node already partially converted. fixed_name is a string previously returned by 
 83.1645 +	// FixNodeName, new_name specifies the string FixNodeName should return on all further invocations 
 83.1646 +	// which would previously have returned the old value.
 83.1647 +	//
 83.1648 +	// this also updates names in node animations, cameras and light sources and is thus slow.
 83.1649 +	//
 83.1650 +	// NOTE: the caller is responsible for ensuring that the new name is unique and does
 83.1651 +	// not collide with any other identifiers. The best way to ensure this is to only
 83.1652 +	// append to the old name, which is guaranteed to match these requirements.
 83.1653 +	void RenameNode(const std::string& fixed_name, const std::string& new_name)
 83.1654 +	{
 83.1655 +		ai_assert(node_names.find(fixed_name) != node_names.end());
 83.1656 +		ai_assert(node_names.find(new_name) == node_names.end());
 83.1657 +
 83.1658 +		renamed_nodes[fixed_name] = new_name;
 83.1659 +
 83.1660 +		const aiString fn(fixed_name);
 83.1661 +
 83.1662 +		BOOST_FOREACH(aiCamera* cam, cameras) {
 83.1663 +			if (cam->mName == fn) {
 83.1664 +				cam->mName.Set(new_name);
 83.1665 +				break;
 83.1666 +			}
 83.1667 +		}
 83.1668 +
 83.1669 +		BOOST_FOREACH(aiLight* light, lights) {
 83.1670 +			if (light->mName == fn) {
 83.1671 +				light->mName.Set(new_name);
 83.1672 +				break;
 83.1673 +			}
 83.1674 +		}
 83.1675 +
 83.1676 +		BOOST_FOREACH(aiAnimation* anim, animations) {
 83.1677 +			for (unsigned int i = 0; i < anim->mNumChannels; ++i) {
 83.1678 +				aiNodeAnim* const na = anim->mChannels[i];
 83.1679 +				if (na->mNodeName == fn) {
 83.1680 +					na->mNodeName.Set(new_name);
 83.1681 +					break;
 83.1682 +				}
 83.1683 +			}
 83.1684 +		}
 83.1685 +	}
 83.1686 +
 83.1687 +
 83.1688 +	// ------------------------------------------------------------------------------------------------
 83.1689 +	// takes a fbx node name and returns the identifier to be used in the assimp output scene.
 83.1690 +	// the function is guaranteed to provide consistent results over multiple invocations
 83.1691 +	// UNLESS RenameNode() is called for a particular node name.
 83.1692 +	std::string FixNodeName(const std::string& name)
 83.1693 +	{
 83.1694 +		// strip Model:: prefix, avoiding ambiguities (i.e. don't strip if 
 83.1695 +		// this causes ambiguities, well possible between empty identifiers,
 83.1696 +		// such as "Model::" and ""). Make sure the behaviour is consistent
 83.1697 +		// across multiple calls to FixNodeName().
 83.1698 +		if(name.substr(0,7) == "Model::") {
 83.1699 +			std::string temp = name.substr(7);
 83.1700 +
 83.1701 +			const NodeNameMap::const_iterator it = node_names.find(temp);
 83.1702 +			if (it != node_names.end()) {
 83.1703 +				if (!(*it).second) {
 83.1704 +					return FixNodeName(name + "_");
 83.1705 +				}
 83.1706 +			}
 83.1707 +			node_names[temp] = true;
 83.1708 +
 83.1709 +			const NameNameMap::const_iterator rit = renamed_nodes.find(temp);
 83.1710 +			return rit == renamed_nodes.end() ? temp : (*rit).second;
 83.1711 +		}
 83.1712 +
 83.1713 +		const NodeNameMap::const_iterator it = node_names.find(name);
 83.1714 +		if (it != node_names.end()) {
 83.1715 +			if ((*it).second) {
 83.1716 +				return FixNodeName(name + "_");
 83.1717 +			}
 83.1718 +		}
 83.1719 +		node_names[name] = false;
 83.1720 +
 83.1721 +		const NameNameMap::const_iterator rit = renamed_nodes.find(name);
 83.1722 +		return rit == renamed_nodes.end() ? name : (*rit).second;
 83.1723 +	}
 83.1724 +
 83.1725 +
 83.1726 +	typedef std::map<const AnimationCurveNode*, const AnimationLayer*> LayerMap;
 83.1727 +
 83.1728 +	// XXX: better use multi_map ..
 83.1729 +	typedef std::map<std::string, std::vector<const AnimationCurveNode*> > NodeMap;
 83.1730 +
 83.1731 +
 83.1732 +	// ------------------------------------------------------------------------------------------------
 83.1733 +	void ConvertAnimationStack(const AnimationStack& st)
 83.1734 +	{				
 83.1735 +		const AnimationLayerList& layers = st.Layers();
 83.1736 +		if(layers.empty()) {
 83.1737 +			return;
 83.1738 +		}
 83.1739 +
 83.1740 +		aiAnimation* const anim = new aiAnimation();
 83.1741 +		animations.push_back(anim);
 83.1742 +
 83.1743 +		// strip AnimationStack:: prefix
 83.1744 +		std::string name = st.Name();
 83.1745 +		if(name.substr(0,16) == "AnimationStack::") {
 83.1746 +			name = name.substr(16);
 83.1747 +		}
 83.1748 +
 83.1749 +		anim->mName.Set(name);
 83.1750 +		
 83.1751 +		// need to find all nodes for which we need to generate node animations -
 83.1752 +		// it may happen that we need to merge multiple layers, though.
 83.1753 +		NodeMap node_map;
 83.1754 +
 83.1755 +		// reverse mapping from curves to layers, much faster than querying 
 83.1756 +		// the FBX DOM for it.
 83.1757 +		LayerMap layer_map;
 83.1758 +
 83.1759 +		const char* prop_whitelist[] = {
 83.1760 +			"Lcl Scaling",
 83.1761 +			"Lcl Rotation",
 83.1762 +			"Lcl Translation"
 83.1763 +		};
 83.1764 +		
 83.1765 +		BOOST_FOREACH(const AnimationLayer* layer, layers) {
 83.1766 +			ai_assert(layer);
 83.1767 +
 83.1768 +			const AnimationCurveNodeList& nodes = layer->Nodes(prop_whitelist, 3);
 83.1769 +			BOOST_FOREACH(const AnimationCurveNode* node, nodes) {
 83.1770 +				ai_assert(node);
 83.1771 +
 83.1772 +				const Model* const model = dynamic_cast<const Model*>(node->Target());
 83.1773 +				// this can happen - it could also be a NodeAttribute (i.e. for camera animations)
 83.1774 +				if(!model) {
 83.1775 +					continue;
 83.1776 +				}
 83.1777 +
 83.1778 +				const std::string& name = FixNodeName(model->Name());
 83.1779 +				node_map[name].push_back(node);
 83.1780 +
 83.1781 +				layer_map[node] = layer;
 83.1782 +			}
 83.1783 +		}
 83.1784 +
 83.1785 +		// generate node animations
 83.1786 +		std::vector<aiNodeAnim*> node_anims;
 83.1787 +
 83.1788 +		double min_time = 1e10;
 83.1789 +		double max_time = -1e10;
 83.1790 +
 83.1791 +		try {
 83.1792 +			BOOST_FOREACH(const NodeMap::value_type& kv, node_map) {
 83.1793 +				GenerateNodeAnimations(node_anims, 
 83.1794 +					kv.first, 
 83.1795 +					kv.second, 
 83.1796 +					layer_map, 
 83.1797 +					max_time, 
 83.1798 +					min_time);
 83.1799 +			}
 83.1800 +		}
 83.1801 +		catch(std::exception&) {
 83.1802 +			std::for_each(node_anims.begin(), node_anims.end(), Util::delete_fun<aiNodeAnim>());
 83.1803 +			throw;
 83.1804 +		}
 83.1805 +
 83.1806 +		if(node_anims.size()) {
 83.1807 +			anim->mChannels = new aiNodeAnim*[node_anims.size()]();
 83.1808 +			anim->mNumChannels = static_cast<unsigned int>(node_anims.size());
 83.1809 +
 83.1810 +			std::swap_ranges(node_anims.begin(),node_anims.end(),anim->mChannels);
 83.1811 +		}
 83.1812 +		else {
 83.1813 +			// empty animations would fail validation, so drop them
 83.1814 +			delete anim;
 83.1815 +			animations.pop_back();
 83.1816 +			FBXImporter::LogInfo("ignoring empty AnimationStack (using IK?): " + name);
 83.1817 +			return;
 83.1818 +		}
 83.1819 +
 83.1820 +		// for some mysterious reason, mDuration is simply the maximum key -- the
 83.1821 +		// validator always assumes animations to start at zero.
 83.1822 +		anim->mDuration = max_time /*- min_time */;
 83.1823 +		anim->mTicksPerSecond = anim_fps;
 83.1824 +	}
 83.1825 +
 83.1826 +
 83.1827 +	// ------------------------------------------------------------------------------------------------
 83.1828 +	void GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims, 
 83.1829 +		const std::string& fixed_name, 
 83.1830 +		const std::vector<const AnimationCurveNode*>& curves, 
 83.1831 +		const LayerMap& layer_map, 
 83.1832 +		double& max_time,
 83.1833 +		double& min_time)
 83.1834 +	{
 83.1835 +
 83.1836 +		NodeMap node_property_map;
 83.1837 +		ai_assert(curves.size());
 83.1838 +
 83.1839 +		// sanity check whether the input is ok
 83.1840 +#ifdef _DEBUG
 83.1841 +		{ const Object* target = NULL;
 83.1842 +		BOOST_FOREACH(const AnimationCurveNode* node, curves) {
 83.1843 +			if(!target) {
 83.1844 +				target = node->Target();
 83.1845 +			}
 83.1846 +			ai_assert(node->Target() == target);
 83.1847 +		}}
 83.1848 +#endif
 83.1849 +
 83.1850 +		const AnimationCurveNode* curve_node;
 83.1851 +		BOOST_FOREACH(const AnimationCurveNode* node, curves) {
 83.1852 +			ai_assert(node);
 83.1853 +
 83.1854 +			if (node->TargetProperty().empty()) {
 83.1855 +				FBXImporter::LogWarn("target property for animation curve not set: " + node->Name());
 83.1856 +				continue;
 83.1857 +			}
 83.1858 +
 83.1859 +			curve_node = node;
 83.1860 +			if (node->Curves().empty()) {
 83.1861 +				FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode: " + node->Name());
 83.1862 +				continue;
 83.1863 +			}
 83.1864 +
 83.1865 +			node_property_map[node->TargetProperty()].push_back(node);
 83.1866 +		}
 83.1867 +
 83.1868 +		ai_assert(curve_node);
 83.1869 +		ai_assert(curve_node->TargetAsModel());
 83.1870 +
 83.1871 +		const Model& target = *curve_node->TargetAsModel();
 83.1872 +
 83.1873 +		// check for all possible transformation components
 83.1874 +		NodeMap::const_iterator chain[TransformationComp_MAXIMUM];
 83.1875 +
 83.1876 +		bool has_any = false;
 83.1877 +		bool has_complex = false;
 83.1878 +
 83.1879 +		for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
 83.1880 +			const TransformationComp comp = static_cast<TransformationComp>(i);
 83.1881 +
 83.1882 +			// inverse pivots don't exist in the input, we just generate them
 83.1883 +			if (comp == TransformationComp_RotationPivotInverse || comp == TransformationComp_ScalingPivotInverse) {
 83.1884 +				chain[i] = node_property_map.end();
 83.1885 +				continue;
 83.1886 +			}
 83.1887 +
 83.1888 +			chain[i] = node_property_map.find(NameTransformationCompProperty(comp));
 83.1889 +			if (chain[i] != node_property_map.end()) {
 83.1890 +
 83.1891 +				// check if this curves contains redundant information by looking
 83.1892 +				// up the corresponding node's transformation chain.
 83.1893 +				if (doc.Settings().optimizeEmptyAnimationCurves && 
 83.1894 +					IsRedundantAnimationData(target, comp, (*chain[i]).second)) {
 83.1895 +
 83.1896 +					FBXImporter::LogDebug("dropping redundant animation channel for node " + target.Name());
 83.1897 +					continue;
 83.1898 +				}
 83.1899 +
 83.1900 +				has_any = true;
 83.1901 +
 83.1902 +				if (comp != TransformationComp_Rotation && comp != TransformationComp_Scaling &&
 83.1903 +					comp != TransformationComp_Translation) {
 83.1904 +
 83.1905 +					has_complex = true;
 83.1906 +				}
 83.1907 +			}
 83.1908 +		}
 83.1909 +
 83.1910 +		if (!has_any) {
 83.1911 +			FBXImporter::LogWarn("ignoring node animation, did not find any transformation key frames");
 83.1912 +			return;
 83.1913 +		}
 83.1914 +
 83.1915 +		// this needs to play nicely with GenerateTransformationNodeChain() which will
 83.1916 +		// be invoked _later_ (animations come first). If this node has only rotation,
 83.1917 +		// scaling and translation _and_ there are no animated other components either,
 83.1918 +		// we can use a single node and also a single node animation channel.
 83.1919 +		if (!has_complex && !NeedsComplexTransformationChain(target)) {
 83.1920 +
 83.1921 +			aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain, 
 83.1922 +				node_property_map.end(), 
 83.1923 +				layer_map,
 83.1924 +				max_time,
 83.1925 +				min_time,
 83.1926 +				true // input is TRS order, assimp is SRT
 83.1927 +				);
 83.1928 +
 83.1929 +			ai_assert(nd);
 83.1930 +			node_anims.push_back(nd);
 83.1931 +			return;
 83.1932 +		}
 83.1933 +
 83.1934 +		// otherwise, things get gruesome and we need separate animation channels
 83.1935 +		// for each part of the transformation chain. Remember which channels
 83.1936 +		// we generated and pass this information to the node conversion
 83.1937 +		// code to avoid nodes that have identity transform, but non-identity
 83.1938 +		// animations, being dropped.
 83.1939 +		unsigned int flags = 0, bit = 0x1;
 83.1940 +		for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) {
 83.1941 +			const TransformationComp comp = static_cast<TransformationComp>(i);
 83.1942 +
 83.1943 +			if (chain[i] != node_property_map.end()) {
 83.1944 +				flags |= bit;
 83.1945 +
 83.1946 +				ai_assert(comp != TransformationComp_RotationPivotInverse);
 83.1947 +				ai_assert(comp != TransformationComp_ScalingPivotInverse);
 83.1948 +
 83.1949 +				const std::string& chain_name = NameTransformationChainNode(fixed_name, comp);
 83.1950 +
 83.1951 +				aiNodeAnim* na;
 83.1952 +				switch(comp) 
 83.1953 +				{
 83.1954 +				case TransformationComp_Rotation:
 83.1955 +				case TransformationComp_PreRotation:
 83.1956 +				case TransformationComp_PostRotation:
 83.1957 +					na = GenerateRotationNodeAnim(chain_name, 
 83.1958 +						target, 
 83.1959 +						(*chain[i]).second,
 83.1960 +						layer_map,
 83.1961 +						max_time,
 83.1962 +						min_time);
 83.1963 +
 83.1964 +					break;
 83.1965 +
 83.1966 +				case TransformationComp_RotationOffset:
 83.1967 +				case TransformationComp_RotationPivot:
 83.1968 +				case TransformationComp_ScalingOffset:
 83.1969 +				case TransformationComp_ScalingPivot:
 83.1970 +				case TransformationComp_Translation:
 83.1971 +					na = GenerateTranslationNodeAnim(chain_name, 
 83.1972 +						target, 
 83.1973 +						(*chain[i]).second,
 83.1974 +						layer_map,
 83.1975 +						max_time,
 83.1976 +						min_time);
 83.1977 +
 83.1978 +					// pivoting requires us to generate an implicit inverse channel to undo the pivot translation
 83.1979 +					if (comp == TransformationComp_RotationPivot) {
 83.1980 +						const std::string& invName = NameTransformationChainNode(fixed_name, 
 83.1981 +							TransformationComp_RotationPivotInverse);
 83.1982 +
 83.1983 +						aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName, 
 83.1984 +							target, 
 83.1985 +							(*chain[i]).second,
 83.1986 +							layer_map,
 83.1987 +							max_time,
 83.1988 +							min_time,
 83.1989 +							true);
 83.1990 +
 83.1991 +						ai_assert(inv);
 83.1992 +						node_anims.push_back(inv);
 83.1993 +
 83.1994 +						ai_assert(TransformationComp_RotationPivotInverse > i);
 83.1995 +						flags |= bit << (TransformationComp_RotationPivotInverse - i);
 83.1996 +					}
 83.1997 +					else if (comp == TransformationComp_ScalingPivot) {
 83.1998 +						const std::string& invName = NameTransformationChainNode(fixed_name, 
 83.1999 +							TransformationComp_ScalingPivotInverse);
 83.2000 +
 83.2001 +						aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName, 
 83.2002 +							target, 
 83.2003 +							(*chain[i]).second,
 83.2004 +							layer_map,
 83.2005 +							max_time,
 83.2006 +							min_time,
 83.2007 +							true);
 83.2008 +
 83.2009 +						ai_assert(inv);
 83.2010 +						node_anims.push_back(inv);
 83.2011 +					
 83.2012 +						ai_assert(TransformationComp_RotationPivotInverse > i);
 83.2013 +						flags |= bit << (TransformationComp_RotationPivotInverse - i);
 83.2014 +					}
 83.2015 +
 83.2016 +					break;
 83.2017 +
 83.2018 +				case TransformationComp_Scaling:
 83.2019 +					na = GenerateScalingNodeAnim(chain_name, 
 83.2020 +						target, 
 83.2021 +						(*chain[i]).second,
 83.2022 +						layer_map,
 83.2023 +						max_time,
 83.2024 +						min_time);
 83.2025 +
 83.2026 +					break;
 83.2027 +
 83.2028 +				default:
 83.2029 +					ai_assert(false);
 83.2030 +				}
 83.2031 +
 83.2032 +				ai_assert(na);
 83.2033 +				node_anims.push_back(na);
 83.2034 +				continue;
 83.2035 +			}
 83.2036 +		}
 83.2037 +
 83.2038 +		node_anim_chain_bits[fixed_name] = flags;
 83.2039 +	}
 83.2040 +
 83.2041 +
 83.2042 +	// ------------------------------------------------------------------------------------------------
 83.2043 +	bool IsRedundantAnimationData(const Model& target, 
 83.2044 +		TransformationComp comp, 
 83.2045 +		const std::vector<const AnimationCurveNode*>& curves)
 83.2046 +	{
 83.2047 +		ai_assert(curves.size());
 83.2048 +
 83.2049 +		// look for animation nodes with
 83.2050 +		//  * sub channels for all relevant components set
 83.2051 +		//  * one key/value pair per component
 83.2052 +		//  * combined values match up the corresponding value in the bind pose node transformation
 83.2053 +		// only such nodes are 'redundant' for this function.
 83.2054 +
 83.2055 +		if (curves.size() > 1) {
 83.2056 +			return false;
 83.2057 +		}
 83.2058 +
 83.2059 +		const AnimationCurveNode& nd = *curves.front();
 83.2060 +		const AnimationCurveMap& sub_curves = nd.Curves();
 83.2061 +
 83.2062 +		const AnimationCurveMap::const_iterator dx = sub_curves.find("d|X");
 83.2063 +		const AnimationCurveMap::const_iterator dy = sub_curves.find("d|Y");
 83.2064 +		const AnimationCurveMap::const_iterator dz = sub_curves.find("d|Z");
 83.2065 +
 83.2066 +		if (dx == sub_curves.end() || dy == sub_curves.end() || dz == sub_curves.end()) {
 83.2067 +			return false;
 83.2068 +		}
 83.2069 +
 83.2070 +		const KeyValueList& vx = (*dx).second->GetValues();
 83.2071 +		const KeyValueList& vy = (*dy).second->GetValues();
 83.2072 +		const KeyValueList& vz = (*dz).second->GetValues();
 83.2073 +
 83.2074 +		if(vx.size() != 1 || vy.size() != 1 || vz.size() != 1) {
 83.2075 +			return false;
 83.2076 +		}
 83.2077 +
 83.2078 +		const aiVector3D dyn_val = aiVector3D(vx[0], vy[0], vz[0]);
 83.2079 +		const aiVector3D& static_val = PropertyGet<aiVector3D>(target.Props(), 
 83.2080 +			NameTransformationCompProperty(comp), 
 83.2081 +			TransformationCompDefaultValue(comp)
 83.2082 +		);
 83.2083 +
 83.2084 +		const float epsilon = 1e-6f;
 83.2085 +		return (dyn_val - static_val).SquareLength() < epsilon;
 83.2086 +	}
 83.2087 +
 83.2088 +
 83.2089 +	// ------------------------------------------------------------------------------------------------
 83.2090 +	aiNodeAnim* GenerateRotationNodeAnim(const std::string& name, 
 83.2091 +		const Model& target, 
 83.2092 +		const std::vector<const AnimationCurveNode*>& curves,
 83.2093 +		const LayerMap& layer_map,
 83.2094 +		double& max_time,
 83.2095 +		double& min_time)
 83.2096 +	{
 83.2097 +		ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
 83.2098 +		na->mNodeName.Set(name);
 83.2099 +
 83.2100 +		ConvertRotationKeys(na, curves, layer_map, max_time,min_time, target.RotationOrder());
 83.2101 +
 83.2102 +		// dummy scaling key
 83.2103 +		na->mScalingKeys = new aiVectorKey[1];
 83.2104 +		na->mNumScalingKeys = 1;
 83.2105 +
 83.2106 +		na->mScalingKeys[0].mTime = 0.;
 83.2107 +		na->mScalingKeys[0].mValue = aiVector3D(1.0f,1.0f,1.0f);
 83.2108 +
 83.2109 +		// dummy position key
 83.2110 +		na->mPositionKeys = new aiVectorKey[1];
 83.2111 +		na->mNumPositionKeys = 1;
 83.2112 +
 83.2113 +		na->mPositionKeys[0].mTime = 0.;
 83.2114 +		na->mPositionKeys[0].mValue = aiVector3D();
 83.2115 +
 83.2116 +		return na.dismiss();
 83.2117 +	}
 83.2118 +
 83.2119 +
 83.2120 +	// ------------------------------------------------------------------------------------------------
 83.2121 +	aiNodeAnim* GenerateScalingNodeAnim(const std::string& name, 
 83.2122 +		const Model& target, 
 83.2123 +		const std::vector<const AnimationCurveNode*>& curves,
 83.2124 +		const LayerMap& layer_map,
 83.2125 +		double& max_time,
 83.2126 +		double& min_time)
 83.2127 +	{
 83.2128 +		ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
 83.2129 +		na->mNodeName.Set(name);
 83.2130 +
 83.2131 +		ConvertScaleKeys(na, curves, layer_map, max_time,min_time);
 83.2132 +
 83.2133 +		// dummy rotation key
 83.2134 +		na->mRotationKeys = new aiQuatKey[1];
 83.2135 +		na->mNumRotationKeys = 1;
 83.2136 +
 83.2137 +		na->mRotationKeys[0].mTime = 0.;
 83.2138 +		na->mRotationKeys[0].mValue = aiQuaternion();
 83.2139 +
 83.2140 +		// dummy position key
 83.2141 +		na->mPositionKeys = new aiVectorKey[1];
 83.2142 +		na->mNumPositionKeys = 1;
 83.2143 +
 83.2144 +		na->mPositionKeys[0].mTime = 0.;
 83.2145 +		na->mPositionKeys[0].mValue = aiVector3D();
 83.2146 +
 83.2147 +		return na.dismiss();
 83.2148 +	}
 83.2149 +
 83.2150 +
 83.2151 +	// ------------------------------------------------------------------------------------------------
 83.2152 +	aiNodeAnim* GenerateTranslationNodeAnim(const std::string& name, 
 83.2153 +		const Model& target, 
 83.2154 +		const std::vector<const AnimationCurveNode*>& curves,
 83.2155 +		const LayerMap& layer_map,
 83.2156 +		double& max_time,
 83.2157 +		double& min_time,
 83.2158 +		bool inverse = false)
 83.2159 +	{
 83.2160 +		ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
 83.2161 +		na->mNodeName.Set(name);
 83.2162 +
 83.2163 +		ConvertTranslationKeys(na, curves, layer_map, max_time,min_time);
 83.2164 +
 83.2165 +		if (inverse) {
 83.2166 +			for (unsigned int i = 0; i < na->mNumPositionKeys; ++i) {
 83.2167 +				na->mPositionKeys[i].mValue *= -1.0f;
 83.2168 +			}
 83.2169 +		}
 83.2170 +
 83.2171 +		// dummy scaling key
 83.2172 +		na->mScalingKeys = new aiVectorKey[1];
 83.2173 +		na->mNumScalingKeys = 1;
 83.2174 +
 83.2175 +		na->mScalingKeys[0].mTime = 0.;
 83.2176 +		na->mScalingKeys[0].mValue = aiVector3D(1.0f,1.0f,1.0f);
 83.2177 +
 83.2178 +		// dummy rotation key
 83.2179 +		na->mRotationKeys = new aiQuatKey[1];
 83.2180 +		na->mNumRotationKeys = 1;
 83.2181 +
 83.2182 +		na->mRotationKeys[0].mTime = 0.;
 83.2183 +		na->mRotationKeys[0].mValue = aiQuaternion();
 83.2184 +
 83.2185 +		return na.dismiss();
 83.2186 +	}
 83.2187 +
 83.2188 +
 83.2189 +	// ------------------------------------------------------------------------------------------------
 83.2190 +	// generate node anim, extracting only Rotation, Scaling and Translation from the given chain
 83.2191 +	aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name, 
 83.2192 +		const Model& target, 
 83.2193 +		NodeMap::const_iterator chain[TransformationComp_MAXIMUM], 
 83.2194 +		NodeMap::const_iterator iter_end,
 83.2195 +		const LayerMap& layer_map,
 83.2196 +		double& max_time,
 83.2197 +		double& min_time,
 83.2198 +		bool reverse_order = false)
 83.2199 +
 83.2200 +	{
 83.2201 +		ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
 83.2202 +		na->mNodeName.Set(name);
 83.2203 +
 83.2204 +		const PropertyTable& props = target.Props();
 83.2205 +
 83.2206 +		// need to convert from TRS order to SRT?
 83.2207 +		if(reverse_order) {
 83.2208 +		
 83.2209 +			aiVector3D def_scale, def_translate;
 83.2210 +			aiQuaternion def_rot;
 83.2211 +
 83.2212 +			KeyFrameListList scaling;
 83.2213 +			KeyFrameListList translation;
 83.2214 +			KeyFrameListList rotation;
 83.2215 +			
 83.2216 +			if(chain[TransformationComp_Scaling] != iter_end) {
 83.2217 +				scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second);
 83.2218 +			}
 83.2219 +			else {
 83.2220 +				def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
 83.2221 +			}
 83.2222 +
 83.2223 +			if(chain[TransformationComp_Translation] != iter_end) {
 83.2224 +				translation = GetKeyframeList((*chain[TransformationComp_Translation]).second);
 83.2225 +			}
 83.2226 +			else {
 83.2227 +				def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
 83.2228 +			}
 83.2229 +			
 83.2230 +			if(chain[TransformationComp_Rotation] != iter_end) {
 83.2231 +				rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second);
 83.2232 +			}
 83.2233 +			else {
 83.2234 +				def_rot = EulerToQuaternion(PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
 83.2235 +					target.RotationOrder());
 83.2236 +			}
 83.2237 +
 83.2238 +			KeyFrameListList joined;
 83.2239 +			joined.insert(joined.end(), scaling.begin(), scaling.end());
 83.2240 +			joined.insert(joined.end(), translation.begin(), translation.end());
 83.2241 +			joined.insert(joined.end(), rotation.begin(), rotation.end());
 83.2242 +
 83.2243 +			const KeyTimeList& times = GetKeyTimeList(joined);
 83.2244 +
 83.2245 +			aiQuatKey* out_quat = new aiQuatKey[times.size()];
 83.2246 +			aiVectorKey* out_scale = new aiVectorKey[times.size()];
 83.2247 +			aiVectorKey* out_translation = new aiVectorKey[times.size()];
 83.2248 +
 83.2249 +			ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation, 
 83.2250 +				scaling, 
 83.2251 +				translation, 
 83.2252 +				rotation, 
 83.2253 +				times,
 83.2254 +				max_time,
 83.2255 +				min_time,
 83.2256 +				target.RotationOrder(),
 83.2257 +				def_scale,
 83.2258 +				def_translate,
 83.2259 +				def_rot);
 83.2260 +
 83.2261 +			// XXX remove duplicates / redundant keys which this operation did
 83.2262 +			// likely produce if not all three channels were equally dense.
 83.2263 +
 83.2264 +			na->mNumScalingKeys = static_cast<unsigned int>(times.size());
 83.2265 +			na->mNumRotationKeys = na->mNumScalingKeys;
 83.2266 +			na->mNumPositionKeys = na->mNumScalingKeys;
 83.2267 +
 83.2268 +			na->mScalingKeys = out_scale;
 83.2269 +			na->mRotationKeys = out_quat;
 83.2270 +			na->mPositionKeys = out_translation;
 83.2271 +		}
 83.2272 +		else {
 83.2273 +
 83.2274 +			// if a particular transformation is not given, grab it from
 83.2275 +			// the corresponding node to meet the semantics of aiNodeAnim,
 83.2276 +			// which requires all of rotation, scaling and translation
 83.2277 +			// to be set.
 83.2278 +			if(chain[TransformationComp_Scaling] != iter_end) {
 83.2279 +				ConvertScaleKeys(na, (*chain[TransformationComp_Scaling]).second, 
 83.2280 +					layer_map, 
 83.2281 +					max_time, 
 83.2282 +					min_time);
 83.2283 +			}
 83.2284 +			else {
 83.2285 +				na->mScalingKeys = new aiVectorKey[1];
 83.2286 +				na->mNumScalingKeys = 1;
 83.2287 +
 83.2288 +				na->mScalingKeys[0].mTime = 0.;
 83.2289 +				na->mScalingKeys[0].mValue = PropertyGet(props,"Lcl Scaling",
 83.2290 +					aiVector3D(1.f,1.f,1.f));
 83.2291 +			}
 83.2292 +
 83.2293 +			if(chain[TransformationComp_Rotation] != iter_end) {
 83.2294 +				ConvertRotationKeys(na, (*chain[TransformationComp_Rotation]).second, 
 83.2295 +					layer_map, 
 83.2296 +					max_time,
 83.2297 +					min_time,
 83.2298 +					target.RotationOrder());
 83.2299 +			}
 83.2300 +			else {
 83.2301 +				na->mRotationKeys = new aiQuatKey[1];
 83.2302 +				na->mNumRotationKeys = 1;
 83.2303 +
 83.2304 +				na->mRotationKeys[0].mTime = 0.;
 83.2305 +				na->mRotationKeys[0].mValue = EulerToQuaternion(
 83.2306 +					PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
 83.2307 +					target.RotationOrder());
 83.2308 +			}
 83.2309 +
 83.2310 +			if(chain[TransformationComp_Translation] != iter_end) {
 83.2311 +				ConvertTranslationKeys(na, (*chain[TransformationComp_Translation]).second, 
 83.2312 +					layer_map, 
 83.2313 +					max_time, 
 83.2314 +					min_time);
 83.2315 +			}
 83.2316 +			else {
 83.2317 +				na->mPositionKeys = new aiVectorKey[1];
 83.2318 +				na->mNumPositionKeys = 1;
 83.2319 +
 83.2320 +				na->mPositionKeys[0].mTime = 0.;
 83.2321 +				na->mPositionKeys[0].mValue = PropertyGet(props,"Lcl Translation",
 83.2322 +					aiVector3D(0.f,0.f,0.f));
 83.2323 +			}
 83.2324 +
 83.2325 +		}
 83.2326 +		return na.dismiss();
 83.2327 +	}
 83.2328 +
 83.2329 +
 83.2330 +
 83.2331 +	// key (time), value, mapto (component index)
 83.2332 +	typedef boost::tuple< const KeyTimeList*, const KeyValueList*, unsigned int > KeyFrameList;
 83.2333 +	typedef std::vector<KeyFrameList> KeyFrameListList;
 83.2334 +
 83.2335 +	
 83.2336 +
 83.2337 +	// ------------------------------------------------------------------------------------------------
 83.2338 +	KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes)
 83.2339 +	{
 83.2340 +		KeyFrameListList inputs;
 83.2341 +		inputs.reserve(nodes.size()*3);
 83.2342 +
 83.2343 +		BOOST_FOREACH(const AnimationCurveNode* node, nodes) {
 83.2344 +			ai_assert(node);
 83.2345 +
 83.2346 +			const AnimationCurveMap& curves = node->Curves();
 83.2347 +			BOOST_FOREACH(const AnimationCurveMap::value_type& kv, curves) {
 83.2348 +
 83.2349 +				unsigned int mapto;
 83.2350 +				if (kv.first == "d|X") {
 83.2351 +					mapto = 0;
 83.2352 +				}
 83.2353 +				else if (kv.first == "d|Y") {
 83.2354 +					mapto = 1;
 83.2355 +				}
 83.2356 +				else if (kv.first == "d|Z") {
 83.2357 +					mapto = 2;
 83.2358 +				}
 83.2359 +				else {
 83.2360 +					FBXImporter::LogWarn("ignoring scale animation curve, did not recognize target component");
 83.2361 +					continue;
 83.2362 +				}
 83.2363 +
 83.2364 +				const AnimationCurve* const curve = kv.second;
 83.2365 +				ai_assert(curve->GetKeys().size() == curve->GetValues().size() && curve->GetKeys().size());
 83.2366 +
 83.2367 +				inputs.push_back(boost::make_tuple(&curve->GetKeys(), &curve->GetValues(), mapto));
 83.2368 +			}
 83.2369 +		}
 83.2370 +		return inputs; // pray for NRVO :-)
 83.2371 +	}
 83.2372 +
 83.2373 +
 83.2374 +	// ------------------------------------------------------------------------------------------------
 83.2375 +	KeyTimeList GetKeyTimeList(const KeyFrameListList& inputs)
 83.2376 +	{
 83.2377 +		ai_assert(inputs.size());
 83.2378 +
 83.2379 +		// reserve some space upfront - it is likely that the keyframe lists
 83.2380 +		// have matching time values, so max(of all keyframe lists) should 
 83.2381 +		// be a good estimate.
 83.2382 +		KeyTimeList keys;
 83.2383 +		
 83.2384 +		size_t estimate = 0;
 83.2385 +		BOOST_FOREACH(const KeyFrameList& kfl, inputs) {
 83.2386 +			estimate = std::max(estimate, kfl.get<0>()->size());
 83.2387 +		}
 83.2388 +
 83.2389 +		keys.reserve(estimate);
 83.2390 +
 83.2391 +		std::vector<unsigned int> next_pos;
 83.2392 +		next_pos.resize(inputs.size(),0);
 83.2393 +
 83.2394 +		const size_t count = inputs.size();
 83.2395 +		while(true) {
 83.2396 +
 83.2397 +			uint64_t min_tick = std::numeric_limits<uint64_t>::max();
 83.2398 +			for (size_t i = 0; i < count; ++i) {
 83.2399 +				const KeyFrameList& kfl = inputs[i];
 83.2400 +
 83.2401 +				if (kfl.get<0>()->size() > next_pos[i] && kfl.get<0>()->at(next_pos[i]) < min_tick) {
 83.2402 +					min_tick = kfl.get<0>()->at(next_pos[i]);
 83.2403 +				}
 83.2404 +			}
 83.2405 +
 83.2406 +			if (min_tick == std::numeric_limits<uint64_t>::max()) {
 83.2407 +				break;
 83.2408 +			}
 83.2409 +			keys.push_back(min_tick);
 83.2410 +
 83.2411 +			for (size_t i = 0; i < count; ++i) {
 83.2412 +				const KeyFrameList& kfl = inputs[i];
 83.2413 +
 83.2414 +
 83.2415 +				while(kfl.get<0>()->size() > next_pos[i] && kfl.get<0>()->at(next_pos[i]) == min_tick) {
 83.2416 +					++next_pos[i];
 83.2417 +				}
 83.2418 +			}
 83.2419 +		}	
 83.2420 +
 83.2421 +		return keys;
 83.2422 +	}
 83.2423 +
 83.2424 +
 83.2425 +	// ------------------------------------------------------------------------------------------------
 83.2426 +	void InterpolateKeys(aiVectorKey* valOut,const KeyTimeList& keys, const KeyFrameListList& inputs, 
 83.2427 +		const bool geom, 
 83.2428 +		double& max_time,
 83.2429 +		double& min_time)
 83.2430 +
 83.2431 +	{
 83.2432 +		ai_assert(keys.size());
 83.2433 +		ai_assert(valOut);
 83.2434 +
 83.2435 +		std::vector<unsigned int> next_pos;
 83.2436 +		const size_t count = inputs.size();
 83.2437 +
 83.2438 +		next_pos.resize(inputs.size(),0);
 83.2439 +
 83.2440 +		BOOST_FOREACH(KeyTimeList::value_type time, keys) {
 83.2441 +			float result[3] = {0.0f, 0.0f, 0.0f};
 83.2442 +			if(geom) {
 83.2443 +				result[0] = result[1] = result[2] = 1.0f;
 83.2444 +			}
 83.2445 +
 83.2446 +			for (size_t i = 0; i < count; ++i) {
 83.2447 +				const KeyFrameList& kfl = inputs[i];
 83.2448 +
 83.2449 +				const size_t ksize = kfl.get<0>()->size();
 83.2450 +				if (ksize > next_pos[i] && kfl.get<0>()->at(next_pos[i]) == time) {
 83.2451 +					++next_pos[i]; 
 83.2452 +				}
 83.2453 +
 83.2454 +				const size_t id0 = next_pos[i]>0 ? next_pos[i]-1 : 0;
 83.2455 +				const size_t id1 = next_pos[i]==ksize ? ksize-1 : next_pos[i];
 83.2456 +
 83.2457 +				// use lerp for interpolation
 83.2458 +				const KeyValueList::value_type valueA = kfl.get<1>()->at(id0);
 83.2459 +				const KeyValueList::value_type valueB = kfl.get<1>()->at(id1);
 83.2460 +
 83.2461 +				const KeyTimeList::value_type timeA = kfl.get<0>()->at(id0);
 83.2462 +				const KeyTimeList::value_type timeB = kfl.get<0>()->at(id1);
 83.2463 +
 83.2464 +				// do the actual interpolation in double-precision arithmetics
 83.2465 +				// because it is a bit sensitive to rounding errors.
 83.2466 +				const double factor = timeB == timeA ? 0. : static_cast<double>((time - timeA) / (timeB - timeA));
 83.2467 +				const float interpValue = static_cast<float>(valueA + (valueB - valueA) * factor);
 83.2468 +
 83.2469 +				if(geom) {
 83.2470 +					result[kfl.get<2>()] *= interpValue;
 83.2471 +				}
 83.2472 +				else {
 83.2473 +					result[kfl.get<2>()] += interpValue;
 83.2474 +				}
 83.2475 +			}
 83.2476 +
 83.2477 +			// magic value to convert fbx times to seconds
 83.2478 +			valOut->mTime = CONVERT_FBX_TIME(time) * anim_fps;
 83.2479 +
 83.2480 +			min_time = std::min(min_time, valOut->mTime);
 83.2481 +			max_time = std::max(max_time, valOut->mTime);
 83.2482 +
 83.2483 +			valOut->mValue.x = result[0];
 83.2484 +			valOut->mValue.y = result[1];
 83.2485 +			valOut->mValue.z = result[2];
 83.2486 +			
 83.2487 +			++valOut;
 83.2488 +		}
 83.2489 +	}
 83.2490 +
 83.2491 +
 83.2492 +	// ------------------------------------------------------------------------------------------------
 83.2493 +	void InterpolateKeys(aiQuatKey* valOut,const KeyTimeList& keys, const KeyFrameListList& inputs, 
 83.2494 +		const bool geom,
 83.2495 +		double& maxTime,
 83.2496 +		double& minTime,
 83.2497 +		Model::RotOrder order)
 83.2498 +	{
 83.2499 +		ai_assert(keys.size());
 83.2500 +		ai_assert(valOut);
 83.2501 +
 83.2502 +		boost::scoped_array<aiVectorKey> temp(new aiVectorKey[keys.size()]);
 83.2503 +		InterpolateKeys(temp.get(),keys,inputs,geom,maxTime, minTime);
 83.2504 +
 83.2505 +		aiMatrix4x4 m;
 83.2506 +
 83.2507 +		aiQuaternion lastq;
 83.2508 +
 83.2509 +		for (size_t i = 0, c = keys.size(); i < c; ++i) {
 83.2510 +
 83.2511 +			valOut[i].mTime = temp[i].mTime;
 83.2512 +
 83.2513 +			
 83.2514 +			GetRotationMatrix(order, temp[i].mValue, m);
 83.2515 +			aiQuaternion quat = aiQuaternion(aiMatrix3x3(m));
 83.2516 +
 83.2517 +			// take shortest path by checking the inner product
 83.2518 +			// http://www.3dkingdoms.com/weekly/weekly.php?a=36
 83.2519 +			if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0)
 83.2520 +			{
 83.2521 +				quat.x = -quat.x;
 83.2522 +				quat.y = -quat.y;
 83.2523 +				quat.z = -quat.z;
 83.2524 +				quat.w = -quat.w;
 83.2525 +			} 
 83.2526 +			lastq = quat;
 83.2527 +
 83.2528 +			valOut[i].mValue = quat; 
 83.2529 +		}
 83.2530 +	}
 83.2531 +
 83.2532 +
 83.2533 +	// ------------------------------------------------------------------------------------------------
 83.2534 +	void ConvertTransformOrder_TRStoSRT(aiQuatKey* out_quat, aiVectorKey* out_scale,
 83.2535 +		aiVectorKey* out_translation, 
 83.2536 +		const KeyFrameListList& scaling, 
 83.2537 +		const KeyFrameListList& translation, 
 83.2538 +		const KeyFrameListList& rotation, 
 83.2539 +		const KeyTimeList& times,
 83.2540 +		double& maxTime,
 83.2541 +		double& minTime,
 83.2542 +		Model::RotOrder order,
 83.2543 +		const aiVector3D& def_scale,
 83.2544 +		const aiVector3D& def_translate,
 83.2545 +		const aiQuaternion& def_rotation)
 83.2546 +	{
 83.2547 +		if (rotation.size()) {
 83.2548 +			InterpolateKeys(out_quat, times, rotation, false, maxTime, minTime, order);
 83.2549 +		}
 83.2550 +		else {
 83.2551 +			for (size_t i = 0; i < times.size(); ++i) {
 83.2552 +				out_quat[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
 83.2553 +				out_quat[i].mValue = def_rotation;
 83.2554 +			}
 83.2555 +		}
 83.2556 +
 83.2557 +		if (scaling.size()) {
 83.2558 +			InterpolateKeys(out_scale, times, scaling, true, maxTime, minTime);
 83.2559 +		}
 83.2560 +		else {
 83.2561 +			for (size_t i = 0; i < times.size(); ++i) {
 83.2562 +				out_scale[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
 83.2563 +				out_scale[i].mValue = def_scale;
 83.2564 +			}
 83.2565 +		}
 83.2566 +
 83.2567 +		if (translation.size()) {
 83.2568 +			InterpolateKeys(out_translation, times, translation, false, maxTime, minTime);
 83.2569 +		}
 83.2570 +		else {
 83.2571 +			for (size_t i = 0; i < times.size(); ++i) {
 83.2572 +				out_translation[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
 83.2573 +				out_translation[i].mValue = def_translate;
 83.2574 +			}
 83.2575 +		}
 83.2576 +
 83.2577 +		const size_t count = times.size();
 83.2578 +		for (size_t i = 0; i < count; ++i) {
 83.2579 +			aiQuaternion& r = out_quat[i].mValue;
 83.2580 +			aiVector3D& s = out_scale[i].mValue;
 83.2581 +			aiVector3D& t = out_translation[i].mValue;
 83.2582 +
 83.2583 +			aiMatrix4x4 mat, temp;
 83.2584 +			aiMatrix4x4::Translation(t, mat);
 83.2585 +			mat *= aiMatrix4x4( r.GetMatrix() );
 83.2586 +			mat *= aiMatrix4x4::Scaling(s, temp);
 83.2587 +
 83.2588 +			mat.Decompose(s, r, t);
 83.2589 +		}
 83.2590 +	}
 83.2591 +
 83.2592 +
 83.2593 +	// ------------------------------------------------------------------------------------------------
 83.2594 +	// euler xyz -> quat
 83.2595 +	aiQuaternion EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order) 
 83.2596 +	{
 83.2597 +		aiMatrix4x4 m;
 83.2598 +		GetRotationMatrix(order, rot, m);
 83.2599 +
 83.2600 +		return aiQuaternion(aiMatrix3x3(m));
 83.2601 +	}
 83.2602 +
 83.2603 +
 83.2604 +	// ------------------------------------------------------------------------------------------------
 83.2605 +	void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& layers,
 83.2606 +		double& maxTime,
 83.2607 +		double& minTime)
 83.2608 +	{
 83.2609 +		ai_assert(nodes.size());
 83.2610 +
 83.2611 +		// XXX for now, assume scale should be blended geometrically (i.e. two
 83.2612 +		// layers should be multiplied with each other). There is a FBX 
 83.2613 +		// property in the layer to specify the behaviour, though.
 83.2614 +
 83.2615 +		const KeyFrameListList& inputs = GetKeyframeList(nodes);
 83.2616 +		const KeyTimeList& keys = GetKeyTimeList(inputs);
 83.2617 +
 83.2618 +		na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
 83.2619 +		na->mScalingKeys = new aiVectorKey[keys.size()];
 83.2620 +		InterpolateKeys(na->mScalingKeys, keys, inputs, true, maxTime, minTime);
 83.2621 +	}
 83.2622 +
 83.2623 +
 83.2624 +	// ------------------------------------------------------------------------------------------------
 83.2625 +	void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, 
 83.2626 +		const LayerMap& layers,
 83.2627 +		double& maxTime,
 83.2628 +		double& minTime)
 83.2629 +	{
 83.2630 +		ai_assert(nodes.size());
 83.2631 +
 83.2632 +		// XXX see notes in ConvertScaleKeys()
 83.2633 +		const KeyFrameListList& inputs = GetKeyframeList(nodes);
 83.2634 +		const KeyTimeList& keys = GetKeyTimeList(inputs);
 83.2635 +
 83.2636 +		na->mNumPositionKeys = static_cast<unsigned int>(keys.size());
 83.2637 +		na->mPositionKeys = new aiVectorKey[keys.size()];
 83.2638 +		InterpolateKeys(na->mPositionKeys, keys, inputs, false, maxTime, minTime);
 83.2639 +	}
 83.2640 +
 83.2641 +
 83.2642 +	// ------------------------------------------------------------------------------------------------
 83.2643 +	void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, 
 83.2644 +		const LayerMap& layers, 
 83.2645 +		double& maxTime,
 83.2646 +		double& minTime,
 83.2647 +		Model::RotOrder order)
 83.2648 +	{
 83.2649 +		ai_assert(nodes.size());
 83.2650 +
 83.2651 +		// XXX see notes in ConvertScaleKeys()
 83.2652 +		const std::vector< KeyFrameList >& inputs = GetKeyframeList(nodes);
 83.2653 +		const KeyTimeList& keys = GetKeyTimeList(inputs);
 83.2654 +
 83.2655 +		na->mNumRotationKeys = static_cast<unsigned int>(keys.size());
 83.2656 +		na->mRotationKeys = new aiQuatKey[keys.size()];
 83.2657 +		InterpolateKeys(na->mRotationKeys, keys, inputs, false, maxTime, minTime, order);
 83.2658 +	}
 83.2659 +
 83.2660 +
 83.2661 +	// ------------------------------------------------------------------------------------------------
 83.2662 +	// copy generated meshes, animations, lights, cameras and textures to the output scene
 83.2663 +	void TransferDataToScene()
 83.2664 +	{
 83.2665 +		ai_assert(!out->mMeshes && !out->mNumMeshes);
 83.2666 +
 83.2667 +		// note: the trailing () ensures initialization with NULL - not
 83.2668 +		// many C++ users seem to know this, so pointing it out to avoid
 83.2669 +		// confusion why this code works.
 83.2670 +
 83.2671 +		if(meshes.size()) {
 83.2672 +			out->mMeshes = new aiMesh*[meshes.size()]();
 83.2673 +			out->mNumMeshes = static_cast<unsigned int>(meshes.size());
 83.2674 +
 83.2675 +			std::swap_ranges(meshes.begin(),meshes.end(),out->mMeshes);
 83.2676 +		}
 83.2677 +
 83.2678 +		if(materials.size()) {
 83.2679 +			out->mMaterials = new aiMaterial*[materials.size()]();
 83.2680 +			out->mNumMaterials = static_cast<unsigned int>(materials.size());
 83.2681 +
 83.2682 +			std::swap_ranges(materials.begin(),materials.end(),out->mMaterials);
 83.2683 +		}
 83.2684 +
 83.2685 +		if(animations.size()) {
 83.2686 +			out->mAnimations = new aiAnimation*[animations.size()]();
 83.2687 +			out->mNumAnimations = static_cast<unsigned int>(animations.size());
 83.2688 +
 83.2689 +			std::swap_ranges(animations.begin(),animations.end(),out->mAnimations);
 83.2690 +		}
 83.2691 +
 83.2692 +		if(lights.size()) {
 83.2693 +			out->mLights = new aiLight*[lights.size()]();
 83.2694 +			out->mNumLights = static_cast<unsigned int>(lights.size());
 83.2695 +
 83.2696 +			std::swap_ranges(lights.begin(),lights.end(),out->mLights);
 83.2697 +		}
 83.2698 +
 83.2699 +		if(cameras.size()) {
 83.2700 +			out->mCameras = new aiCamera*[cameras.size()]();
 83.2701 +			out->mNumCameras = static_cast<unsigned int>(cameras.size());
 83.2702 +
 83.2703 +			std::swap_ranges(cameras.begin(),cameras.end(),out->mCameras);
 83.2704 +		}
 83.2705 +	}
 83.2706 +
 83.2707 +
 83.2708 +private:
 83.2709 +
 83.2710 +	// 0: not assigned yet, others: index is value - 1
 83.2711 +	unsigned int defaultMaterialIndex;
 83.2712 +
 83.2713 +	std::vector<aiMesh*> meshes;
 83.2714 +	std::vector<aiMaterial*> materials;
 83.2715 +	std::vector<aiAnimation*> animations;
 83.2716 +	std::vector<aiLight*> lights;
 83.2717 +	std::vector<aiCamera*> cameras;
 83.2718 +
 83.2719 +	typedef std::map<const Material*, unsigned int> MaterialMap;
 83.2720 +	MaterialMap materials_converted;
 83.2721 +
 83.2722 +	typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap;
 83.2723 +	MeshMap meshes_converted;
 83.2724 +
 83.2725 +	// fixed node name -> which trafo chain components have animations?
 83.2726 +	typedef std::map<std::string, unsigned int> NodeAnimBitMap;
 83.2727 +	NodeAnimBitMap node_anim_chain_bits;
 83.2728 +
 83.2729 +	// name -> has had its prefix_stripped?
 83.2730 +	typedef std::map<std::string, bool> NodeNameMap;
 83.2731 +	NodeNameMap node_names;
 83.2732 +
 83.2733 +	typedef std::map<std::string, std::string> NameNameMap;
 83.2734 +	NameNameMap renamed_nodes;
 83.2735 +
 83.2736 +	double anim_fps;
 83.2737 +
 83.2738 +	aiScene* const out;
 83.2739 +	const FBX::Document& doc;
 83.2740 +};
 83.2741 +
 83.2742 +//} // !anon
 83.2743 +
 83.2744 +// ------------------------------------------------------------------------------------------------
 83.2745 +void ConvertToAssimpScene(aiScene* out, const Document& doc)
 83.2746 +{
 83.2747 +	Converter converter(out,doc);
 83.2748 +}
 83.2749 +
 83.2750 +} // !FBX
 83.2751 +} // !Assimp
 83.2752 +
 83.2753 +#endif
    84.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.2 +++ b/libs/assimp/FBXConverter.h	Sat Feb 01 19:58:19 2014 +0200
    84.3 @@ -0,0 +1,63 @@
    84.4 +/*
    84.5 +Open Asset Import Library (assimp)
    84.6 +----------------------------------------------------------------------
    84.7 +
    84.8 +Copyright (c) 2006-2012, assimp team
    84.9 +All rights reserved.
   84.10 +
   84.11 +Redistribution and use of this software in source and binary forms, 
   84.12 +with or without modification, are permitted provided that the 
   84.13 +following conditions are met:
   84.14 +
   84.15 +* Redistributions of source code must retain the above
   84.16 +  copyright notice, this list of conditions and the
   84.17 +  following disclaimer.
   84.18 +
   84.19 +* Redistributions in binary form must reproduce the above
   84.20 +  copyright notice, this list of conditions and the
   84.21 +  following disclaimer in the documentation and/or other
   84.22 +  materials provided with the distribution.
   84.23 +
   84.24 +* Neither the name of the assimp team, nor the names of its
   84.25 +  contributors may be used to endorse or promote products
   84.26 +  derived from this software without specific prior
   84.27 +  written permission of the assimp team.
   84.28 +
   84.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   84.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   84.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   84.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   84.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   84.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   84.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   84.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   84.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   84.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   84.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   84.40 +
   84.41 +----------------------------------------------------------------------
   84.42 +*/
   84.43 +
   84.44 +/** @file  FBXDConverter.h
   84.45 + *  @brief FBX DOM to aiScene conversion
   84.46 + */
   84.47 +#ifndef INCLUDED_AI_FBX_CONVERTER_H
   84.48 +#define INCLUDED_AI_FBX_CONVERTER_H
   84.49 +
   84.50 +namespace Assimp {
   84.51 +namespace FBX {
   84.52 +
   84.53 +	class Document;
   84.54 +
   84.55 +
   84.56 +/** Convert a FBX #Document to #aiScene
   84.57 + *  @param out Empty scene to be populated
   84.58 + *  @param doc Parsed FBX document */
   84.59 +void ConvertToAssimpScene(aiScene* out, const Document& doc);
   84.60 +
   84.61 +
   84.62 +}
   84.63 +}
   84.64 +
   84.65 +
   84.66 +#endif
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/libs/assimp/FBXDeformer.cpp	Sat Feb 01 19:58:19 2014 +0200
    85.3 @@ -0,0 +1,169 @@
    85.4 +/*
    85.5 +Open Asset Import Library (assimp)
    85.6 +----------------------------------------------------------------------
    85.7 +
    85.8 +Copyright (c) 2006-2012, assimp team
    85.9 +All rights reserved.
   85.10 +
   85.11 +Redistribution and use of this software in source and binary forms, 
   85.12 +with or without modification, are permitted provided that the 
   85.13 +following conditions are met:
   85.14 +
   85.15 +* Redistributions of source code must retain the above
   85.16 +  copyright notice, this list of conditions and the
   85.17 +  following disclaimer.
   85.18 +
   85.19 +* Redistributions in binary form must reproduce the above
   85.20 +  copyright notice, this list of conditions and the
   85.21 +  following disclaimer in the documentation and/or other
   85.22 +  materials provided with the distribution.
   85.23 +
   85.24 +* Neither the name of the assimp team, nor the names of its
   85.25 +  contributors may be used to endorse or promote products
   85.26 +  derived from this software without specific prior
   85.27 +  written permission of the assimp team.
   85.28 +
   85.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   85.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   85.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   85.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   85.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   85.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   85.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   85.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   85.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   85.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   85.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   85.40 +
   85.41 +----------------------------------------------------------------------
   85.42 +*/
   85.43 +
   85.44 +/** @file  FBXNoteAttribute.cpp
   85.45 + *  @brief Assimp::FBX::NodeAttribute (and subclasses) implementation
   85.46 + */
   85.47 +#include "AssimpPCH.h"
   85.48 +
   85.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   85.50 +
   85.51 +#include "FBXParser.h"
   85.52 +#include "FBXDocument.h"
   85.53 +#include "FBXImporter.h"
   85.54 +#include "FBXImportSettings.h"
   85.55 +#include "FBXDocumentUtil.h"
   85.56 +#include "FBXProperties.h"
   85.57 +
   85.58 +namespace Assimp {
   85.59 +namespace FBX {
   85.60 +
   85.61 +	using namespace Util;
   85.62 +
   85.63 +// ------------------------------------------------------------------------------------------------
   85.64 +Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name)
   85.65 +	: Object(id,element,name)
   85.66 +{
   85.67 +	const Scope& sc = GetRequiredScope(element);
   85.68 +
   85.69 +	const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2));
   85.70 +	props = GetPropertyTable(doc,"Deformer.Fbx" + classname,element,sc,true);
   85.71 +}
   85.72 +
   85.73 +
   85.74 +// ------------------------------------------------------------------------------------------------
   85.75 +Deformer::~Deformer()
   85.76 +{
   85.77 +
   85.78 +}
   85.79 +
   85.80 +
   85.81 +// ------------------------------------------------------------------------------------------------
   85.82 +Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name)
   85.83 +: Deformer(id,element,doc,name)
   85.84 +, node()
   85.85 +{
   85.86 +	const Scope& sc = GetRequiredScope(element);
   85.87 +
   85.88 +	const Element* const Indexes = sc["Indexes"];
   85.89 +	const Element* const Weights = sc["Weights"];
   85.90 +
   85.91 +	const Element& Transform = GetRequiredElement(sc,"Transform",&element);
   85.92 +	const Element& TransformLink = GetRequiredElement(sc,"TransformLink",&element);
   85.93 +
   85.94 +	transform = ReadMatrix(Transform);
   85.95 +	transformLink = ReadMatrix(TransformLink);
   85.96 +
   85.97 +	// it is actually possible that there be Deformer's with no weights
   85.98 +	if (!!Indexes != !!Weights) {
   85.99 +		DOMError("either Indexes or Weights are missing from Cluster",&element);
  85.100 +	}
  85.101 +
  85.102 +	if(Indexes) {
  85.103 +		ParseVectorDataArray(indices,*Indexes);
  85.104 +		ParseVectorDataArray(weights,*Weights);
  85.105 +	}
  85.106 +
  85.107 +	if(indices.size() != weights.size()) {
  85.108 +		DOMError("sizes of index and weight array don't match up",&element);
  85.109 +	}
  85.110 +
  85.111 +	// read assigned node
  85.112 +	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Model");
  85.113 +	BOOST_FOREACH(const Connection* con, conns) {
  85.114 +		const Model* const mod = ProcessSimpleConnection<Model>(*con, false, "Model -> Cluster", element);
  85.115 +		if(mod) {
  85.116 +			node = mod;
  85.117 +			break;
  85.118 +		}
  85.119 +	}
  85.120 +
  85.121 +	if (!node) {
  85.122 +		DOMError("failed to read target Node for Cluster",&element);
  85.123 +	}
  85.124 +}
  85.125 +
  85.126 +
  85.127 +// ------------------------------------------------------------------------------------------------
  85.128 +Cluster::~Cluster()
  85.129 +{
  85.130 +
  85.131 +}
  85.132 +
  85.133 +
  85.134 +// ------------------------------------------------------------------------------------------------
  85.135 +Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name)
  85.136 +: Deformer(id,element,doc,name)
  85.137 +{
  85.138 +	const Scope& sc = GetRequiredScope(element);
  85.139 +
  85.140 +	const Element* const Link_DeformAcuracy = sc["Link_DeformAcuracy"];
  85.141 +	if(Link_DeformAcuracy) {
  85.142 +		accuracy = ParseTokenAsFloat(GetRequiredToken(*Link_DeformAcuracy,0));
  85.143 +	}
  85.144 +
  85.145 +	// resolve assigned clusters 
  85.146 +	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
  85.147 +
  85.148 +	clusters.reserve(conns.size());
  85.149 +	BOOST_FOREACH(const Connection* con, conns) {
  85.150 +
  85.151 +		const Cluster* const cluster = ProcessSimpleConnection<Cluster>(*con, false, "Cluster -> Skin", element);
  85.152 +		if(cluster) {
  85.153 +			clusters.push_back(cluster);
  85.154 +			continue;
  85.155 +		}
  85.156 +	}
  85.157 +}
  85.158 +
  85.159 +
  85.160 +// ------------------------------------------------------------------------------------------------
  85.161 +Skin::~Skin()
  85.162 +{
  85.163 +
  85.164 +}
  85.165 +
  85.166 +
  85.167 +
  85.168 +}
  85.169 +}
  85.170 +
  85.171 +#endif
  85.172 +
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/libs/assimp/FBXDocument.cpp	Sat Feb 01 19:58:19 2014 +0200
    86.3 @@ -0,0 +1,713 @@
    86.4 +/*
    86.5 +Open Asset Import Library (assimp)
    86.6 +----------------------------------------------------------------------
    86.7 +
    86.8 +Copyright (c) 2006-2012, assimp team
    86.9 +All rights reserved.
   86.10 +
   86.11 +Redistribution and use of this software in source and binary forms, 
   86.12 +with or without modification, are permitted provided that the 
   86.13 +following conditions are met:
   86.14 +
   86.15 +* Redistributions of source code must retain the above
   86.16 +  copyright notice, this list of conditions and the
   86.17 +  following disclaimer.
   86.18 +
   86.19 +* Redistributions in binary form must reproduce the above
   86.20 +  copyright notice, this list of conditions and the
   86.21 +  following disclaimer in the documentation and/or other
   86.22 +  materials provided with the distribution.
   86.23 +
   86.24 +* Neither the name of the assimp team, nor the names of its
   86.25 +  contributors may be used to endorse or promote products
   86.26 +  derived from this software without specific prior
   86.27 +  written permission of the assimp team.
   86.28 +
   86.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   86.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   86.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   86.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   86.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   86.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   86.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   86.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   86.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   86.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   86.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   86.40 +
   86.41 +----------------------------------------------------------------------
   86.42 +*/
   86.43 +
   86.44 +/** @file  FBXDocument.cpp
   86.45 + *  @brief Implementation of the FBX DOM classes
   86.46 + */
   86.47 +#include "AssimpPCH.h"
   86.48 +
   86.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   86.50 +
   86.51 +#include <functional>
   86.52 +
   86.53 +#include "FBXParser.h"
   86.54 +#include "FBXDocument.h"
   86.55 +#include "FBXUtil.h"
   86.56 +#include "FBXImporter.h"
   86.57 +#include "FBXImportSettings.h"
   86.58 +#include "FBXDocumentUtil.h"
   86.59 +#include "FBXProperties.h"
   86.60 +
   86.61 +namespace Assimp {
   86.62 +namespace FBX {
   86.63 +
   86.64 +using namespace Util;
   86.65 +
   86.66 +// ------------------------------------------------------------------------------------------------
   86.67 +LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc)
   86.68 +: doc(doc)
   86.69 +, element(element)
   86.70 +, id(id)
   86.71 +, flags()
   86.72 +{
   86.73 +
   86.74 +}
   86.75 +
   86.76 +// ------------------------------------------------------------------------------------------------
   86.77 +LazyObject::~LazyObject()
   86.78 +{
   86.79 +
   86.80 +}
   86.81 +
   86.82 +// ------------------------------------------------------------------------------------------------
   86.83 +const Object* LazyObject::Get(bool dieOnError)
   86.84 +{
   86.85 +	if(IsBeingConstructed() || FailedToConstruct()) {
   86.86 +		return NULL;
   86.87 +	}
   86.88 +
   86.89 +	if (object.get()) {
   86.90 +		return object.get();
   86.91 +	}
   86.92 +
   86.93 +	// if this is the root object, we return a dummy since there
   86.94 +	// is no root object int he fbx file - it is just referenced
   86.95 +	// with id 0.
   86.96 +	if(id == 0L) {
   86.97 +		object.reset(new Object(id, element, "Model::RootNode"));
   86.98 +		return object.get();
   86.99 +	}
  86.100 +
  86.101 +	const Token& key = element.KeyToken();
  86.102 +	const TokenList& tokens = element.Tokens();
  86.103 +
  86.104 +	if(tokens.size() < 3) {
  86.105 +		DOMError("expected at least 3 tokens: id, name and class tag",&element);
  86.106 +	}
  86.107 +
  86.108 +	const char* err;
  86.109 +	std::string name = ParseTokenAsString(*tokens[1],err);
  86.110 +	if (err) {
  86.111 +		DOMError(err,&element);
  86.112 +	} 
  86.113 +
  86.114 +	// small fix for binary reading: binary fbx files don't use
  86.115 +	// prefixes such as Model:: in front of their names. The
  86.116 +	// loading code expects this at many places, though!
  86.117 +	// so convert the binary representation (a 0x0001) to the
  86.118 +	// double colon notation.
  86.119 +	if(tokens[1]->IsBinary()) {
  86.120 +		for (size_t i = 0; i < name.length(); ++i) {
  86.121 +			if (name[i] == 0x0 && name[i+1] == 0x1) {
  86.122 +				name = name.substr(i+2) + "::" + name.substr(0,i);
  86.123 +			}
  86.124 +		}
  86.125 +	}
  86.126 +
  86.127 +	const std::string classtag = ParseTokenAsString(*tokens[2],err);
  86.128 +	if (err) {
  86.129 +		DOMError(err,&element);
  86.130 +	} 
  86.131 +
  86.132 +	// prevent recursive calls
  86.133 +	flags |= BEING_CONSTRUCTED;
  86.134 +
  86.135 +	try {
  86.136 +		// this needs to be relatively fast since it happens a lot,
  86.137 +		// so avoid constructing strings all the time.
  86.138 +		const char* obtype = key.begin();
  86.139 +		const size_t length = static_cast<size_t>(key.end()-key.begin());
  86.140 +		if (!strncmp(obtype,"Geometry",length)) {
  86.141 +			if (!strcmp(classtag.c_str(),"Mesh")) {
  86.142 +				object.reset(new MeshGeometry(id,element,name,doc));
  86.143 +			}
  86.144 +		}
  86.145 +		else if (!strncmp(obtype,"NodeAttribute",length)) {
  86.146 +			if (!strcmp(classtag.c_str(),"Camera")) {
  86.147 +				object.reset(new Camera(id,element,doc,name));
  86.148 +			}
  86.149 +			else if (!strcmp(classtag.c_str(),"CameraSwitcher")) {
  86.150 +				object.reset(new CameraSwitcher(id,element,doc,name));
  86.151 +			}
  86.152 +			else if (!strcmp(classtag.c_str(),"Light")) {
  86.153 +				object.reset(new Light(id,element,doc,name));
  86.154 +			}
  86.155 +			else if (!strcmp(classtag.c_str(),"Null")) {
  86.156 +				object.reset(new Null(id,element,doc,name));
  86.157 +			}
  86.158 +			else if (!strcmp(classtag.c_str(),"LimbNode")) {
  86.159 +				object.reset(new LimbNode(id,element,doc,name));
  86.160 +			}
  86.161 +		}
  86.162 +		else if (!strncmp(obtype,"Deformer",length)) {
  86.163 +			if (!strcmp(classtag.c_str(),"Cluster")) {
  86.164 +				object.reset(new Cluster(id,element,doc,name));
  86.165 +			}
  86.166 +			else if (!strcmp(classtag.c_str(),"Skin")) {
  86.167 +				object.reset(new Skin(id,element,doc,name));
  86.168 +			}
  86.169 +		}
  86.170 +		else if (!strncmp(obtype,"Model",length)) {
  86.171 +			// FK and IK effectors are not supported
  86.172 +			if (strcmp(classtag.c_str(),"IKEffector") && strcmp(classtag.c_str(),"FKEffector")) {
  86.173 +				object.reset(new Model(id,element,doc,name));
  86.174 +			}
  86.175 +		}
  86.176 +		else if (!strncmp(obtype,"Material",length)) {
  86.177 +			object.reset(new Material(id,element,doc,name));
  86.178 +		}
  86.179 +		else if (!strncmp(obtype,"Texture",length)) {
  86.180 +			object.reset(new Texture(id,element,doc,name));
  86.181 +		}
  86.182 +		else if (!strncmp(obtype,"AnimationStack",length)) {
  86.183 +			object.reset(new AnimationStack(id,element,name,doc));
  86.184 +		}
  86.185 +		else if (!strncmp(obtype,"AnimationLayer",length)) {
  86.186 +			object.reset(new AnimationLayer(id,element,name,doc));
  86.187 +		}
  86.188 +		// note: order matters for these two
  86.189 +		else if (!strncmp(obtype,"AnimationCurve",length)) {
  86.190 +			object.reset(new AnimationCurve(id,element,name,doc));
  86.191 +		}
  86.192 +		else if (!strncmp(obtype,"AnimationCurveNode",length)) {
  86.193 +			object.reset(new AnimationCurveNode(id,element,name,doc));
  86.194 +		}	
  86.195 +	}
  86.196 +	catch(std::exception& ex) {
  86.197 +		flags &= ~BEING_CONSTRUCTED;
  86.198 +		flags |= FAILED_TO_CONSTRUCT;
  86.199 +
  86.200 +		if(dieOnError || doc.Settings().strictMode) {
  86.201 +			throw;
  86.202 +		}
  86.203 +
  86.204 +		// note: the error message is already formatted, so raw logging is ok
  86.205 +		if(!DefaultLogger::isNullLogger()) {
  86.206 +			DefaultLogger::get()->error(ex.what());
  86.207 +		}
  86.208 +		return NULL;
  86.209 +	}
  86.210 +
  86.211 +	if (!object.get()) {
  86.212 +		//DOMError("failed to convert element to DOM object, class: " + classtag + ", name: " + name,&element);
  86.213 +	}
  86.214 +
  86.215 +	flags &= ~BEING_CONSTRUCTED;
  86.216 +	return object.get();
  86.217 +}
  86.218 +
  86.219 +// ------------------------------------------------------------------------------------------------
  86.220 +Object::Object(uint64_t id, const Element& element, const std::string& name)
  86.221 +: element(element)
  86.222 +, name(name)
  86.223 +, id(id)
  86.224 +{
  86.225 +
  86.226 +}
  86.227 +
  86.228 +// ------------------------------------------------------------------------------------------------
  86.229 +Object::~Object()
  86.230 +{
  86.231 +
  86.232 +}
  86.233 +
  86.234 +
  86.235 +// ------------------------------------------------------------------------------------------------
  86.236 +FileGlobalSettings::FileGlobalSettings(const Document& doc, boost::shared_ptr<const PropertyTable> props)
  86.237 +: props(props)
  86.238 +, doc(doc) 
  86.239 +{
  86.240 +
  86.241 +}
  86.242 +
  86.243 +
  86.244 +// ------------------------------------------------------------------------------------------------
  86.245 +FileGlobalSettings::~FileGlobalSettings()
  86.246 +{
  86.247 +
  86.248 +}
  86.249 +
  86.250 +
  86.251 +// ------------------------------------------------------------------------------------------------
  86.252 +Document::Document(const Parser& parser, const ImportSettings& settings)
  86.253 +: settings(settings)
  86.254 +, parser(parser)
  86.255 +{
  86.256 +	// cannot use array default initialization syntax because vc8 fails on it
  86.257 +	for (unsigned int i = 0; i < 7; ++i) {
  86.258 +		creationTimeStamp[i] = 0;
  86.259 +	}
  86.260 +
  86.261 +	ReadHeader();
  86.262 +	ReadPropertyTemplates();
  86.263 +
  86.264 +	ReadGlobalSettings();
  86.265 +
  86.266 +	// this order is important, connections need parsed objects to check
  86.267 +	// whether connections are ok or not. Objects may not be evaluated yet,
  86.268 +	// though, since this may require valid connections.
  86.269 +	ReadObjects();
  86.270 +	ReadConnections();
  86.271 +}
  86.272 +
  86.273 +
  86.274 +// ------------------------------------------------------------------------------------------------
  86.275 +Document::~Document()
  86.276 +{
  86.277 +	BOOST_FOREACH(ObjectMap::value_type& v, objects) {
  86.278 +		delete v.second;
  86.279 +	}
  86.280 +}
  86.281 +
  86.282 +
  86.283 +// ------------------------------------------------------------------------------------------------
  86.284 +void Document::ReadHeader()
  86.285 +{
  86.286 +	// read ID objects from "Objects" section
  86.287 +	const Scope& sc = parser.GetRootScope();
  86.288 +	const Element* const ehead = sc["FBXHeaderExtension"];
  86.289 +	if(!ehead || !ehead->Compound()) {
  86.290 +		DOMError("no FBXHeaderExtension dictionary found");
  86.291 +	}
  86.292 +
  86.293 +	const Scope& shead = *ehead->Compound();
  86.294 +	fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0));
  86.295 +
  86.296 +	
  86.297 +	if(fbxVersion < 7200 || fbxVersion > 7300) {
  86.298 +		if(Settings().strictMode) {
  86.299 +			DOMError("unsupported format version, supported are only FBX 2012 and FBX 2013"\
  86.300 +				" in ASCII format (turn off strict mode to try anyhow) ");
  86.301 +		}
  86.302 +		else {
  86.303 +			DOMWarning("unsupported format version, supported are only FBX 2012 and FBX 2013, trying to read it nevertheless");
  86.304 +		}
  86.305 +	}
  86.306 +	
  86.307 +
  86.308 +	const Element* const ecreator = shead["Creator"];
  86.309 +	if(ecreator) {
  86.310 +		creator = ParseTokenAsString(GetRequiredToken(*ecreator,0));
  86.311 +	}
  86.312 +
  86.313 +	const Element* const etimestamp = shead["CreationTimeStamp"];
  86.314 +	if(etimestamp && etimestamp->Compound()) {
  86.315 +		const Scope& stimestamp = *etimestamp->Compound();
  86.316 +		creationTimeStamp[0] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Year"),0));
  86.317 +		creationTimeStamp[1] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Month"),0));
  86.318 +		creationTimeStamp[2] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Day"),0));
  86.319 +		creationTimeStamp[3] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Hour"),0));
  86.320 +		creationTimeStamp[4] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Minute"),0));
  86.321 +		creationTimeStamp[5] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Second"),0));
  86.322 +		creationTimeStamp[6] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Millisecond"),0));
  86.323 +	}
  86.324 +}
  86.325 +
  86.326 +// ------------------------------------------------------------------------------------------------
  86.327 +void Document::ReadGlobalSettings()
  86.328 +{
  86.329 +	const Scope& sc = parser.GetRootScope();
  86.330 +	const Element* const ehead = sc["GlobalSettings"];
  86.331 +	if(!ehead || !ehead->Compound()) {
  86.332 +		DOMWarning("no GlobalSettings dictionary found");
  86.333 +
  86.334 +		globals.reset(new FileGlobalSettings(*this, boost::make_shared<const PropertyTable>()));
  86.335 +		return;
  86.336 +	}
  86.337 +
  86.338 +	boost::shared_ptr<const PropertyTable> props = GetPropertyTable(*this, "", *ehead, *ehead->Compound(), true);
  86.339 +
  86.340 +	if(!props) {
  86.341 +		DOMError("GlobalSettings dictionary contains no property table");
  86.342 +	}
  86.343 +
  86.344 +	globals.reset(new FileGlobalSettings(*this, props));
  86.345 +}
  86.346 +
  86.347 +
  86.348 +// ------------------------------------------------------------------------------------------------
  86.349 +void Document::ReadObjects()
  86.350 +{
  86.351 +	// read ID objects from "Objects" section
  86.352 +	const Scope& sc = parser.GetRootScope();
  86.353 +	const Element* const eobjects = sc["Objects"];
  86.354 +	if(!eobjects || !eobjects->Compound()) {
  86.355 +		DOMError("no Objects dictionary found");
  86.356 +	}
  86.357 +
  86.358 +	// add a dummy entry to represent the Model::RootNode object (id 0),
  86.359 +	// which is only indirectly defined in the input file
  86.360 +	objects[0] = new LazyObject(0L, *eobjects, *this);
  86.361 +
  86.362 +	const Scope& sobjects = *eobjects->Compound();
  86.363 +	BOOST_FOREACH(const ElementMap::value_type& el, sobjects.Elements()) {
  86.364 +		
  86.365 +		// extract ID 
  86.366 +		const TokenList& tok = el.second->Tokens();
  86.367 +		
  86.368 +		if (tok.empty()) {
  86.369 +			DOMError("expected ID after object key",el.second);
  86.370 +		}
  86.371 +
  86.372 +		const char* err;
  86.373 +
  86.374 +		const uint64_t id = ParseTokenAsID(*tok[0], err);
  86.375 +		if(err) {
  86.376 +			DOMError(err,el.second);
  86.377 +		}
  86.378 +
  86.379 +		// id=0 is normally implicit
  86.380 +		if(id == 0L) {
  86.381 +			DOMError("encountered object with implicitly defined id 0",el.second);
  86.382 +		}
  86.383 +
  86.384 +		if(objects.find(id) != objects.end()) {
  86.385 +			DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second);
  86.386 +		}
  86.387 +
  86.388 +		objects[id] = new LazyObject(id, *el.second, *this);
  86.389 +
  86.390 +		// grab all animation stacks upfront since there is no listing of them
  86.391 +		if(!strcmp(el.first.c_str(),"AnimationStack")) {
  86.392 +			animationStacks.push_back(id);
  86.393 +		}
  86.394 +	}
  86.395 +}
  86.396 +
  86.397 +
  86.398 +// ------------------------------------------------------------------------------------------------
  86.399 +void Document::ReadPropertyTemplates()
  86.400 +{
  86.401 +	const Scope& sc = parser.GetRootScope();
  86.402 +	// read property templates from "Definitions" section
  86.403 +	const Element* const edefs = sc["Definitions"];
  86.404 +	if(!edefs || !edefs->Compound()) {
  86.405 +		DOMWarning("no Definitions dictionary found");
  86.406 +		return;
  86.407 +	}
  86.408 +
  86.409 +	const Scope& sdefs = *edefs->Compound();
  86.410 +	const ElementCollection otypes = sdefs.GetCollection("ObjectType");
  86.411 +	for(ElementMap::const_iterator it = otypes.first; it != otypes.second; ++it) {
  86.412 +		const Element& el = *(*it).second;
  86.413 +		const Scope* sc = el.Compound();
  86.414 +		if(!sc) {
  86.415 +			DOMWarning("expected nested scope in ObjectType, ignoring",&el);
  86.416 +			continue;
  86.417 +		}
  86.418 +
  86.419 +		const TokenList& tok = el.Tokens();
  86.420 +		if(tok.empty()) {
  86.421 +			DOMWarning("expected name for ObjectType element, ignoring",&el);
  86.422 +			continue;
  86.423 +		}
  86.424 +
  86.425 +		const std::string& oname = ParseTokenAsString(*tok[0]);
  86.426 +
  86.427 +		const ElementCollection templs = sc->GetCollection("PropertyTemplate");
  86.428 +		for(ElementMap::const_iterator it = templs.first; it != templs.second; ++it) {
  86.429 +			const Element& el = *(*it).second;
  86.430 +			const Scope* sc = el.Compound();
  86.431 +			if(!sc) {
  86.432 +				DOMWarning("expected nested scope in PropertyTemplate, ignoring",&el);
  86.433 +				continue;
  86.434 +			}
  86.435 +
  86.436 +			const TokenList& tok = el.Tokens();
  86.437 +			if(tok.empty()) {
  86.438 +				DOMWarning("expected name for PropertyTemplate element, ignoring",&el);
  86.439 +				continue;
  86.440 +			}
  86.441 +
  86.442 +			const std::string& pname = ParseTokenAsString(*tok[0]);
  86.443 +
  86.444 +			const Element* Properties70 = (*sc)["Properties70"];
  86.445 +			if(Properties70) {
  86.446 +				boost::shared_ptr<const PropertyTable> props = boost::make_shared<const PropertyTable>(
  86.447 +					*Properties70,boost::shared_ptr<const PropertyTable>(static_cast<const PropertyTable*>(NULL))
  86.448 +				);
  86.449 +
  86.450 +				templates[oname+"."+pname] = props;
  86.451 +			}
  86.452 +		}
  86.453 +	}
  86.454 +}
  86.455 +
  86.456 +
  86.457 +
  86.458 +// ------------------------------------------------------------------------------------------------
  86.459 +void Document::ReadConnections()
  86.460 +{
  86.461 +	const Scope& sc = parser.GetRootScope();
  86.462 +	// read property templates from "Definitions" section
  86.463 +	const Element* const econns = sc["Connections"];
  86.464 +	if(!econns || !econns->Compound()) {
  86.465 +		DOMError("no Connections dictionary found");
  86.466 +	}
  86.467 +
  86.468 +	uint64_t insertionOrder = 0l;
  86.469 +
  86.470 +	const Scope& sconns = *econns->Compound();
  86.471 +	const ElementCollection conns = sconns.GetCollection("C");
  86.472 +	for(ElementMap::const_iterator it = conns.first; it != conns.second; ++it) {
  86.473 +		const Element& el = *(*it).second;
  86.474 +		const std::string& type = ParseTokenAsString(GetRequiredToken(el,0));
  86.475 +		const uint64_t src = ParseTokenAsID(GetRequiredToken(el,1));
  86.476 +		const uint64_t dest = ParseTokenAsID(GetRequiredToken(el,2));
  86.477 +
  86.478 +		// OO = object-object connection
  86.479 +		// OP = object-property connection, in which case the destination property follows the object ID
  86.480 +		const std::string& prop = (type == "OP" ? ParseTokenAsString(GetRequiredToken(el,3)) : "");
  86.481 +
  86.482 +		if(objects.find(src) == objects.end()) {
  86.483 +			DOMWarning("source object for connection does not exist",&el);
  86.484 +			continue;
  86.485 +		}
  86.486 +
  86.487 +		// dest may be 0 (root node) but we added a dummy object before
  86.488 +		if(objects.find(dest) == objects.end()) {
  86.489 +			DOMWarning("destination object for connection does not exist",&el);
  86.490 +			continue;
  86.491 +		}
  86.492 +
  86.493 +		// add new connection
  86.494 +		const Connection* const c = new Connection(insertionOrder++,src,dest,prop,*this);
  86.495 +		src_connections.insert(ConnectionMap::value_type(src,c));  
  86.496 +		dest_connections.insert(ConnectionMap::value_type(dest,c));  
  86.497 +	}
  86.498 +}
  86.499 +
  86.500 +
  86.501 +// ------------------------------------------------------------------------------------------------
  86.502 +const std::vector<const AnimationStack*>& Document::AnimationStacks() const
  86.503 +{
  86.504 +	if (!animationStacksResolved.empty() || !animationStacks.size()) {
  86.505 +		return animationStacksResolved;
  86.506 +	}
  86.507 +
  86.508 +	animationStacksResolved.reserve(animationStacks.size());
  86.509 +	BOOST_FOREACH(uint64_t id, animationStacks) {
  86.510 +		LazyObject* const lazy = GetObject(id);
  86.511 +		const AnimationStack* stack;
  86.512 +		if(!lazy || !(stack = lazy->Get<AnimationStack>())) {
  86.513 +			DOMWarning("failed to read AnimationStack object");
  86.514 +			continue;
  86.515 +		}
  86.516 +		animationStacksResolved.push_back(stack);
  86.517 +	}
  86.518 +
  86.519 +	return animationStacksResolved;
  86.520 +}
  86.521 +
  86.522 +
  86.523 +// ------------------------------------------------------------------------------------------------
  86.524 +LazyObject* Document::GetObject(uint64_t id) const
  86.525 +{
  86.526 +	ObjectMap::const_iterator it = objects.find(id);
  86.527 +	return it == objects.end() ? NULL : (*it).second;
  86.528 +}
  86.529 +
  86.530 +#define MAX_CLASSNAMES 6
  86.531 +
  86.532 +// ------------------------------------------------------------------------------------------------
  86.533 +std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, 
  86.534 +	const ConnectionMap& conns) const
  86.535 +{
  86.536 +	std::vector<const Connection*> temp;
  86.537 +
  86.538 +	const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range = 
  86.539 +		conns.equal_range(id);
  86.540 +
  86.541 +	temp.reserve(std::distance(range.first,range.second));
  86.542 +	for (ConnectionMap::const_iterator it = range.first; it != range.second; ++it) {
  86.543 +		temp.push_back((*it).second);
  86.544 +	}
  86.545 +
  86.546 +	std::sort(temp.begin(), temp.end(), std::mem_fun(&Connection::Compare));
  86.547 +
  86.548 +	return temp; // NRVO should handle this
  86.549 +}
  86.550 +
  86.551 +
  86.552 +// ------------------------------------------------------------------------------------------------
  86.553 +std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bool is_src, 
  86.554 +	const ConnectionMap& conns, 
  86.555 +	const char* const* classnames, 
  86.556 +	size_t count) const
  86.557 +
  86.558 +{
  86.559 +	ai_assert(classnames);
  86.560 +	ai_assert(count != 0 && count <= MAX_CLASSNAMES);
  86.561 +
  86.562 +	size_t lenghts[MAX_CLASSNAMES];
  86.563 +
  86.564 +	const size_t c = count;
  86.565 +	for (size_t i = 0; i < c; ++i) {
  86.566 +		lenghts[i] = strlen(classnames[i]);
  86.567 +	}
  86.568 +
  86.569 +	std::vector<const Connection*> temp;
  86.570 +
  86.571 +	const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range = 
  86.572 +		conns.equal_range(id);
  86.573 +
  86.574 +	temp.reserve(std::distance(range.first,range.second));
  86.575 +	for (ConnectionMap::const_iterator it = range.first; it != range.second; ++it) {
  86.576 +		const Token& key = (is_src 
  86.577 +			? (*it).second->LazyDestinationObject()
  86.578 +			: (*it).second->LazySourceObject()
  86.579 +		).GetElement().KeyToken();
  86.580 +
  86.581 +		const char* obtype = key.begin();
  86.582 +
  86.583 +		for (size_t i = 0; i < c; ++i) {
  86.584 +			ai_assert(classnames[i]);
  86.585 +			if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lenghts[i] && !strncmp(classnames[i],obtype,lenghts[i])) {
  86.586 +				obtype = NULL;
  86.587 +				break;
  86.588 +			}
  86.589 +		}
  86.590 +
  86.591 +		if(obtype) {
  86.592 +			continue;
  86.593 +		}
  86.594 +
  86.595 +		temp.push_back((*it).second);
  86.596 +	}
  86.597 +
  86.598 +	std::sort(temp.begin(), temp.end(), std::mem_fun(&Connection::Compare));
  86.599 +	return temp; // NRVO should handle this
  86.600 +}
  86.601 +
  86.602 +
  86.603 +// ------------------------------------------------------------------------------------------------
  86.604 +std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const
  86.605 +{
  86.606 +	return GetConnectionsSequenced(source, ConnectionsBySource());
  86.607 +}
  86.608 +
  86.609 +
  86.610 +
  86.611 +// ------------------------------------------------------------------------------------------------
  86.612 +std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t dest, 
  86.613 +	const char* classname) const
  86.614 +{
  86.615 +	const char* arr[] = {classname};
  86.616 +	return GetConnectionsBySourceSequenced(dest, arr,1);
  86.617 +}
  86.618 +
  86.619 +
  86.620 +
  86.621 +// ------------------------------------------------------------------------------------------------
  86.622 +std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source, 
  86.623 +	const char* const* classnames, size_t count) const
  86.624 +{
  86.625 +	return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count);
  86.626 +}
  86.627 +
  86.628 +
  86.629 +// ------------------------------------------------------------------------------------------------
  86.630 +std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest, 
  86.631 +	const char* classname) const
  86.632 +{
  86.633 +	const char* arr[] = {classname};
  86.634 +	return GetConnectionsByDestinationSequenced(dest, arr,1);
  86.635 +}
  86.636 +
  86.637 +
  86.638 +// ------------------------------------------------------------------------------------------------
  86.639 +std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest) const
  86.640 +{
  86.641 +	return GetConnectionsSequenced(dest, ConnectionsByDestination());
  86.642 +}
  86.643 +
  86.644 +
  86.645 +// ------------------------------------------------------------------------------------------------
  86.646 +std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest, 
  86.647 +	const char* const* classnames, size_t count) const
  86.648 +
  86.649 +{
  86.650 +	return GetConnectionsSequenced(dest, false, ConnectionsByDestination(),classnames, count);
  86.651 +}
  86.652 +
  86.653 +
  86.654 +// ------------------------------------------------------------------------------------------------
  86.655 +Connection::Connection(uint64_t insertionOrder,  uint64_t src, uint64_t dest, const std::string& prop, 
  86.656 +	const Document& doc)
  86.657 +
  86.658 +: insertionOrder(insertionOrder)
  86.659 +, prop(prop)
  86.660 +, src(src)
  86.661 +, dest(dest)
  86.662 +, doc(doc)
  86.663 +{
  86.664 +	ai_assert(doc.Objects().find(src) != doc.Objects().end());
  86.665 +	// dest may be 0 (root node)
  86.666 +	ai_assert(!dest || doc.Objects().find(dest) != doc.Objects().end());
  86.667 +}
  86.668 +
  86.669 +
  86.670 +// ------------------------------------------------------------------------------------------------
  86.671 +Connection::~Connection()
  86.672 +{
  86.673 +
  86.674 +}
  86.675 +
  86.676 +
  86.677 +// ------------------------------------------------------------------------------------------------
  86.678 +LazyObject& Connection::LazySourceObject() const
  86.679 +{
  86.680 +	LazyObject* const lazy = doc.GetObject(src);
  86.681 +	ai_assert(lazy);
  86.682 +	return *lazy;
  86.683 +}
  86.684 +
  86.685 +
  86.686 +// ------------------------------------------------------------------------------------------------
  86.687 +LazyObject& Connection::LazyDestinationObject() const
  86.688 +{
  86.689 +	LazyObject* const lazy = doc.GetObject(dest);
  86.690 +	ai_assert(lazy);
  86.691 +	return *lazy;
  86.692 +}
  86.693 +
  86.694 +
  86.695 +// ------------------------------------------------------------------------------------------------
  86.696 +const Object* Connection::SourceObject() const
  86.697 +{
  86.698 +	LazyObject* const lazy = doc.GetObject(src);
  86.699 +	ai_assert(lazy);
  86.700 +	return lazy->Get();
  86.701 +}
  86.702 +
  86.703 +
  86.704 +// ------------------------------------------------------------------------------------------------
  86.705 +const Object* Connection::DestinationObject() const
  86.706 +{
  86.707 +	LazyObject* const lazy = doc.GetObject(dest);
  86.708 +	ai_assert(lazy);
  86.709 +	return lazy->Get();
  86.710 +}
  86.711 +
  86.712 +} // !FBX
  86.713 +} // !Assimp
  86.714 +
  86.715 +#endif
  86.716 +
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/libs/assimp/FBXDocument.h	Sat Feb 01 19:58:19 2014 +0200
    87.3 @@ -0,0 +1,1325 @@
    87.4 +/*
    87.5 +Open Asset Import Library (assimp)
    87.6 +----------------------------------------------------------------------
    87.7 +
    87.8 +Copyright (c) 2006-2012, assimp team
    87.9 +All rights reserved.
   87.10 +
   87.11 +Redistribution and use of this software in source and binary forms, 
   87.12 +with or without modification, are permitted provided that the 
   87.13 +following conditions are met:
   87.14 +
   87.15 +* Redistributions of source code must retain the above
   87.16 +  copyright notice, this list of conditions and the
   87.17 +  following disclaimer.
   87.18 +
   87.19 +* Redistributions in binary form must reproduce the above
   87.20 +  copyright notice, this list of conditions and the
   87.21 +  following disclaimer in the documentation and/or other
   87.22 +  materials provided with the distribution.
   87.23 +
   87.24 +* Neither the name of the assimp team, nor the names of its
   87.25 +  contributors may be used to endorse or promote products
   87.26 +  derived from this software without specific prior
   87.27 +  written permission of the assimp team.
   87.28 +
   87.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   87.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   87.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   87.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   87.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   87.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   87.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   87.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   87.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   87.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   87.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   87.40 +
   87.41 +----------------------------------------------------------------------
   87.42 +*/
   87.43 +
   87.44 +/** @file  FBXDocument.h
   87.45 + *  @brief FBX DOM
   87.46 + */
   87.47 +#ifndef INCLUDED_AI_FBX_DOCUMENT_H
   87.48 +#define INCLUDED_AI_FBX_DOCUMENT_H
   87.49 +
   87.50 +#include <vector>
   87.51 +#include <map>
   87.52 +#include <string>
   87.53 +
   87.54 +#include "FBXProperties.h"
   87.55 +
   87.56 +namespace Assimp {
   87.57 +namespace FBX {
   87.58 +
   87.59 +	class Parser;
   87.60 +	class Object;
   87.61 +	struct ImportSettings;
   87.62 +
   87.63 +	class PropertyTable;
   87.64 +	class Document;
   87.65 +	class Material;
   87.66 +	class Geometry;
   87.67 +
   87.68 +	class AnimationCurve;
   87.69 +	class AnimationCurveNode;
   87.70 +	class AnimationLayer;
   87.71 +	class AnimationStack;
   87.72 +
   87.73 +	class Skin;
   87.74 +	class Cluster;
   87.75 +
   87.76 +
   87.77 +/** Represents a delay-parsed FBX objects. Many objects in the scene
   87.78 + *  are not needed by assimp, so it makes no sense to parse them
   87.79 + *  upfront. */
   87.80 +class LazyObject
   87.81 +{
   87.82 +public:
   87.83 +
   87.84 +	LazyObject(uint64_t id, const Element& element, const Document& doc);
   87.85 +	~LazyObject();
   87.86 +
   87.87 +public:
   87.88 +
   87.89 +	const Object* Get(bool dieOnError = false);
   87.90 +
   87.91 +	template <typename T> 
   87.92 +	const T* Get(bool dieOnError = false) {
   87.93 +		const Object* const ob = Get(dieOnError);
   87.94 +		return ob ? dynamic_cast<const T*>(ob) : NULL;
   87.95 +	}
   87.96 +
   87.97 +	uint64_t ID() const {
   87.98 +		return id;
   87.99 +	}
  87.100 +
  87.101 +	bool IsBeingConstructed() const {
  87.102 +		return (flags & BEING_CONSTRUCTED) != 0;
  87.103 +	}
  87.104 +
  87.105 +	bool FailedToConstruct() const {
  87.106 +		return (flags & FAILED_TO_CONSTRUCT) != 0;
  87.107 +	}
  87.108 +
  87.109 +	const Element& GetElement() const {
  87.110 +		return element;
  87.111 +	}
  87.112 +
  87.113 +	const Document& GetDocument() const {
  87.114 +		return doc;
  87.115 +	}
  87.116 +
  87.117 +private:
  87.118 +
  87.119 +	const Document& doc;
  87.120 +	const Element& element;
  87.121 +	boost::scoped_ptr<const Object> object;
  87.122 +
  87.123 +	const uint64_t id;
  87.124 +
  87.125 +	enum Flags {
  87.126 +		BEING_CONSTRUCTED = 0x1,
  87.127 +		FAILED_TO_CONSTRUCT = 0x2
  87.128 +	};
  87.129 +
  87.130 +	unsigned int flags;
  87.131 +};
  87.132 +
  87.133 +
  87.134 +
  87.135 +/** Base class for in-memory (DOM) representations of FBX objects */
  87.136 +class Object
  87.137 +{
  87.138 +public:
  87.139 +
  87.140 +	Object(uint64_t id, const Element& element, const std::string& name);
  87.141 +	virtual ~Object();
  87.142 +
  87.143 +public:
  87.144 +
  87.145 +	const Element& SourceElement() const {
  87.146 +		return element;
  87.147 +	}
  87.148 +
  87.149 +	const std::string& Name() const {
  87.150 +		return name;
  87.151 +	}
  87.152 +
  87.153 +	uint64_t ID() const {
  87.154 +		return id;
  87.155 +	}
  87.156 +
  87.157 +protected:
  87.158 +	const Element& element;
  87.159 +	const std::string name;
  87.160 +	const uint64_t id;
  87.161 +};
  87.162 +
  87.163 +
  87.164 +
  87.165 +/** DOM class for generic FBX NoteAttribute blocks. NoteAttribute's just hold a property table,
  87.166 + *  fixed members are added by deriving classes. */
  87.167 +class NodeAttribute : public Object
  87.168 +{
  87.169 +public:
  87.170 +
  87.171 +	NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
  87.172 +	~NodeAttribute();
  87.173 +
  87.174 +public:
  87.175 +
  87.176 +	const PropertyTable& Props() const {
  87.177 +		ai_assert(props.get());
  87.178 +		return *props.get();
  87.179 +	}
  87.180 +
  87.181 +private:
  87.182 +
  87.183 +	boost::shared_ptr<const PropertyTable> props;
  87.184 +};
  87.185 +
  87.186 +
  87.187 +/** DOM base class for FBX camera settings attached to a node */
  87.188 +class CameraSwitcher : public NodeAttribute
  87.189 +{
  87.190 +public:
  87.191 +
  87.192 +	CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
  87.193 +	~CameraSwitcher();
  87.194 +
  87.195 +public:
  87.196 +
  87.197 +	int CameraID() const {
  87.198 +		return cameraId;
  87.199 +	}
  87.200 +
  87.201 +	const std::string& CameraName() const {
  87.202 +		return cameraName;
  87.203 +	}
  87.204 +
  87.205 +
  87.206 +	const std::string& CameraIndexName() const {
  87.207 +		return cameraIndexName;
  87.208 +	}
  87.209 +
  87.210 +private:
  87.211 +
  87.212 +	int cameraId;
  87.213 +	std::string cameraName;
  87.214 +	std::string cameraIndexName;
  87.215 +};
  87.216 +
  87.217 +
  87.218 +#define fbx_stringize(a) #a
  87.219 +
  87.220 +#define fbx_simple_property(name, type, default_value) \
  87.221 +	type name() const { \
  87.222 +		return PropertyGet<type>(Props(), fbx_stringize(name), (default_value)); \
  87.223 +	}
  87.224 +
  87.225 +// XXX improve logging
  87.226 +#define fbx_simple_enum_property(name, type, default_value) \
  87.227 +	type name() const { \
  87.228 +		const int ival = PropertyGet<int>(Props(), fbx_stringize(name), static_cast<int>(default_value)); \
  87.229 +		if (ival < 0 || ival >= AI_CONCAT(type, _MAX)) { \
  87.230 +			ai_assert(static_cast<int>(default_value) >= 0 && static_cast<int>(default_value) < AI_CONCAT(type, _MAX)); \
  87.231 +			return static_cast<type>(default_value); \
  87.232 +		} \
  87.233 +		return static_cast<type>(ival); \
  87.234 +}
  87.235 +
  87.236 +
  87.237 +
  87.238 +/** DOM base class for FBX cameras attached to a node */
  87.239 +class Camera : public NodeAttribute
  87.240 +{
  87.241 +public:
  87.242 +
  87.243 +	Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name);
  87.244 +	~Camera();
  87.245 +
  87.246 +public:
  87.247 +
  87.248 +	fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0));
  87.249 +	fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0));
  87.250 +	fbx_simple_property(InterestPosition, aiVector3D, aiVector3D(0,0,0));
  87.251 +
  87.252 +	fbx_simple_property(AspectWidth, float, 1.0f);
  87.253 +	fbx_simple_property(AspectHeight, float, 1.0f);
  87.254 +	fbx_simple_property(FilmWidth, float, 1.0f);
  87.255 +	fbx_simple_property(FilmHeight, float, 1.0f);
  87.256 +
  87.257 +	fbx_simple_property(FilmAspectRatio, float, 1.0f);
  87.258 +	fbx_simple_property(ApertureMode, int, 0);
  87.259 +
  87.260 +	fbx_simple_property(FieldOfView, float, 1.0f);
  87.261 +	fbx_simple_property(FocalLength, float, 1.0f);
  87.262 +
  87.263 +private:
  87.264 +};
  87.265 +
  87.266 +
  87.267 +/** DOM base class for FBX null markers attached to a node */
  87.268 +class Null : public NodeAttribute
  87.269 +{
  87.270 +public:
  87.271 +
  87.272 +	Null(uint64_t id, const Element& element, const Document& doc, const std::string& name);
  87.273 +	~Null();
  87.274 +};
  87.275 +
  87.276 +
  87.277 +/** DOM base class for FBX limb node markers attached to a node */
  87.278 +class LimbNode : public NodeAttribute
  87.279 +{
  87.280 +public:
  87.281 +
  87.282 +	LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name);
  87.283 +	~LimbNode();
  87.284 +};
  87.285 +
  87.286 +
  87.287 +/** DOM base class for FBX lights attached to a node */
  87.288 +class Light : public NodeAttribute
  87.289 +{
  87.290 +public:
  87.291 +
  87.292 +	Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
  87.293 +	~Light();
  87.294 +
  87.295 +public:
  87.296 +
  87.297 +	enum Type
  87.298 +	{
  87.299 +		Type_Point,
  87.300 +		Type_Directional,
  87.301 +		Type_Spot,
  87.302 +		Type_Area,
  87.303 +		Type_Volume,
  87.304 +
  87.305 +		Type_MAX // end-of-enum sentinel
  87.306 +	};
  87.307 +
  87.308 +	enum Decay
  87.309 +	{
  87.310 +		Decay_None,
  87.311 +		Decay_Linear,
  87.312 +		Decay_Quadratic,
  87.313 +		Decay_Cubic,
  87.314 +
  87.315 +		Decay_MAX // end-of-enum sentinel
  87.316 +	};
  87.317 +
  87.318 +public:
  87.319 +
  87.320 +	fbx_simple_property(Color, aiVector3D, aiVector3D(1,1,1));
  87.321 +	fbx_simple_enum_property(LightType, Type, 0);
  87.322 +	fbx_simple_property(CastLightOnObject, bool, false);
  87.323 +	fbx_simple_property(DrawVolumetricLight, bool, true);
  87.324 +	fbx_simple_property(DrawGroundProjection, bool, true);
  87.325 +	fbx_simple_property(DrawFrontFacingVolumetricLight, bool, false);
  87.326 +	fbx_simple_property(Intensity, float, 1.0f);
  87.327 +	fbx_simple_property(InnerAngle, float, 0.0f);
  87.328 +	fbx_simple_property(OuterAngle, float, 45.0f);
  87.329 +	fbx_simple_property(Fog, int, 50);
  87.330 +	fbx_simple_enum_property(DecayType, Decay, 0);
  87.331 +	fbx_simple_property(DecayStart, int, 0);
  87.332 +	fbx_simple_property(FileName, std::string, "");
  87.333 +
  87.334 +	fbx_simple_property(EnableNearAttenuation, bool, false);
  87.335 +	fbx_simple_property(NearAttenuationStart, float, 0.0f);
  87.336 +	fbx_simple_property(NearAttenuationEnd, float, 0.0f);
  87.337 +	fbx_simple_property(EnableFarAttenuation, bool, false);
  87.338 +	fbx_simple_property(FarAttenuationStart, float, 0.0f);
  87.339 +	fbx_simple_property(FarAttenuationEnd, float, 0.0f);
  87.340 +
  87.341 +	fbx_simple_property(CastShadows, bool, true);
  87.342 +	fbx_simple_property(ShadowColor, aiVector3D, aiVector3D(0,0,0));
  87.343 +
  87.344 +	fbx_simple_property(AreaLightShape, int, 0);
  87.345 +
  87.346 +	fbx_simple_property(LeftBarnDoor, float, 20.0f);
  87.347 +	fbx_simple_property(RightBarnDoor, float, 20.0f);
  87.348 +	fbx_simple_property(TopBarnDoor, float, 20.0f);
  87.349 +	fbx_simple_property(BottomBarnDoor, float, 20.0f);
  87.350 +	fbx_simple_property(EnableBarnDoor, bool, true);
  87.351 +
  87.352 +
  87.353 +private:
  87.354 +};
  87.355 +
  87.356 +
  87.357 +/** DOM base class for FBX models (even though its semantics are more "node" than "model" */
  87.358 +class Model : public Object
  87.359 +{
  87.360 +public:
  87.361 +
  87.362 +	Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
  87.363 +	~Model();
  87.364 +
  87.365 +public:
  87.366 +
  87.367 +	enum RotOrder
  87.368 +	{ 
  87.369 +		RotOrder_EulerXYZ = 0, 
  87.370 +		RotOrder_EulerXZY, 
  87.371 +		RotOrder_EulerYZX, 
  87.372 +		RotOrder_EulerYXZ, 
  87.373 +		RotOrder_EulerZXY, 
  87.374 +		RotOrder_EulerZYX,
  87.375 +
  87.376 +		RotOrder_SphericXYZ,
  87.377 +
  87.378 +		RotOrder_MAX // end-of-enum sentinel
  87.379 +	};
  87.380 +
  87.381 +
  87.382 +	enum TransformInheritance
  87.383 +	{
  87.384 +		TransformInheritance_RrSs = 0,
  87.385 +		TransformInheritance_RSrs,
  87.386 +		TransformInheritance_Rrs,
  87.387 +
  87.388 +		TransformInheritance_MAX // end-of-enum sentinel
  87.389 +	};
  87.390 +
  87.391 +public:
  87.392 +
  87.393 +	fbx_simple_property(QuaternionInterpolate, int, 0);
  87.394 +
  87.395 +	fbx_simple_property(RotationOffset, aiVector3D, aiVector3D());
  87.396 +	fbx_simple_property(RotationPivot, aiVector3D, aiVector3D());
  87.397 +	fbx_simple_property(ScalingOffset, aiVector3D, aiVector3D());
  87.398 +	fbx_simple_property(ScalingPivot, aiVector3D, aiVector3D());
  87.399 +	fbx_simple_property(TranslationActive, bool, false);
  87.400 +
  87.401 +	fbx_simple_property(TranslationMin, aiVector3D, aiVector3D());
  87.402 +	fbx_simple_property(TranslationMax, aiVector3D, aiVector3D());
  87.403 +
  87.404 +	fbx_simple_property(TranslationMinX, bool, false);
  87.405 +	fbx_simple_property(TranslationMaxX, bool, false);
  87.406 +	fbx_simple_property(TranslationMinY, bool, false);
  87.407 +	fbx_simple_property(TranslationMaxY, bool, false);
  87.408 +	fbx_simple_property(TranslationMinZ, bool, false);
  87.409 +	fbx_simple_property(TranslationMaxZ, bool, false);
  87.410 +
  87.411 +	fbx_simple_enum_property(RotationOrder, RotOrder, 0);
  87.412 +	fbx_simple_property(RotationSpaceForLimitOnly, bool, false);
  87.413 +	fbx_simple_property(RotationStiffnessX, float, 0.0f);
  87.414 +	fbx_simple_property(RotationStiffnessY, float, 0.0f);
  87.415 +	fbx_simple_property(RotationStiffnessZ, float, 0.0f);
  87.416 +	fbx_simple_property(AxisLen, float, 0.0f);
  87.417 +
  87.418 +	fbx_simple_property(PreRotation, aiVector3D, aiVector3D());
  87.419 +	fbx_simple_property(PostRotation, aiVector3D, aiVector3D());
  87.420 +	fbx_simple_property(RotationActive, bool, false);
  87.421 +
  87.422 +	fbx_simple_property(RotationMin, aiVector3D, aiVector3D());
  87.423 +	fbx_simple_property(RotationMax, aiVector3D, aiVector3D());
  87.424 +
  87.425 +	fbx_simple_property(RotationMinX, bool, false);
  87.426 +	fbx_simple_property(RotationMaxX, bool, false);
  87.427 +	fbx_simple_property(RotationMinY, bool, false);
  87.428 +	fbx_simple_property(RotationMaxY, bool, false);
  87.429 +	fbx_simple_property(RotationMinZ, bool, false);
  87.430 +	fbx_simple_property(RotationMaxZ, bool, false);
  87.431 +	fbx_simple_enum_property(InheritType, TransformInheritance, 0);
  87.432 +
  87.433 +	fbx_simple_property(ScalingActive, bool, false);
  87.434 +	fbx_simple_property(ScalingMin, aiVector3D, aiVector3D());
  87.435 +	fbx_simple_property(ScalingMax, aiVector3D, aiVector3D(1.f,1.f,1.f));
  87.436 +	fbx_simple_property(ScalingMinX, bool, false);
  87.437 +	fbx_simple_property(ScalingMaxX, bool, false);
  87.438 +	fbx_simple_property(ScalingMinY, bool, false);
  87.439 +	fbx_simple_property(ScalingMaxY, bool, false);
  87.440 +	fbx_simple_property(ScalingMinZ, bool, false);
  87.441 +	fbx_simple_property(ScalingMaxZ, bool, false);
  87.442 +
  87.443 +	fbx_simple_property(GeometricTranslation, aiVector3D, aiVector3D());
  87.444 +	fbx_simple_property(GeometricRotation, aiVector3D, aiVector3D());
  87.445 +	fbx_simple_property(GeometricScaling, aiVector3D, aiVector3D(1.f, 1.f, 1.f));
  87.446 +
  87.447 +	fbx_simple_property(MinDampRangeX, float, 0.0f);
  87.448 +	fbx_simple_property(MinDampRangeY, float, 0.0f);
  87.449 +	fbx_simple_property(MinDampRangeZ, float, 0.0f);
  87.450 +	fbx_simple_property(MaxDampRangeX, float, 0.0f);
  87.451 +	fbx_simple_property(MaxDampRangeY, float, 0.0f);
  87.452 +	fbx_simple_property(MaxDampRangeZ, float, 0.0f);
  87.453 +
  87.454 +	fbx_simple_property(MinDampStrengthX, float, 0.0f);
  87.455 +	fbx_simple_property(MinDampStrengthY, float, 0.0f);
  87.456 +	fbx_simple_property(MinDampStrengthZ, float, 0.0f);
  87.457 +	fbx_simple_property(MaxDampStrengthX, float, 0.0f);
  87.458 +	fbx_simple_property(MaxDampStrengthY, float, 0.0f);
  87.459 +	fbx_simple_property(MaxDampStrengthZ, float, 0.0f);
  87.460 +
  87.461 +	fbx_simple_property(PreferredAngleX, float, 0.0f);
  87.462 +	fbx_simple_property(PreferredAngleY, float, 0.0f);
  87.463 +	fbx_simple_property(PreferredAngleZ, float, 0.0f);
  87.464 +
  87.465 +	fbx_simple_property(Show, bool, true);
  87.466 +	fbx_simple_property(LODBox, bool, false);
  87.467 +	fbx_simple_property(Freeze, bool, false);
  87.468 +
  87.469 +public:
  87.470 +
  87.471 +	const std::string& Shading() const {
  87.472 +		return shading;
  87.473 +	}
  87.474 +
  87.475 +	const std::string& Culling() const {
  87.476 +		return culling;
  87.477 +	}
  87.478 +
  87.479 +	const PropertyTable& Props() const {
  87.480 +		ai_assert(props.get());
  87.481 +		return *props.get();
  87.482 +	}
  87.483 +
  87.484 +	/** Get material links */
  87.485 +	const std::vector<const Material*>& GetMaterials() const {
  87.486 +		return materials;
  87.487 +	}
  87.488 +
  87.489 +
  87.490 +	/** Get geometry links */
  87.491 +	const std::vector<const Geometry*>& GetGeometry() const {
  87.492 +		return geometry;
  87.493 +	}
  87.494 +
  87.495 +
  87.496 +	/** Get node attachments */
  87.497 +	const std::vector<const NodeAttribute*>& GetAttributes() const {
  87.498 +		return attributes;
  87.499 +	}
  87.500 +
  87.501 +public:
  87.502 +
  87.503 +	/** convenience method to check if the node has a Null node marker */
  87.504 +	bool IsNull() const;
  87.505 +
  87.506 +
  87.507 +private:
  87.508 +
  87.509 +	void ResolveLinks(const Element& element, const Document& doc);
  87.510 +
  87.511 +private:
  87.512 +
  87.513 +	std::vector<const Material*> materials;
  87.514 +	std::vector<const Geometry*> geometry;
  87.515 +	std::vector<const NodeAttribute*> attributes;
  87.516 +
  87.517 +	std::string shading;
  87.518 +	std::string culling;
  87.519 +	boost::shared_ptr<const PropertyTable> props;
  87.520 +};
  87.521 +
  87.522 +
  87.523 +
  87.524 +/** DOM class for generic FBX textures */
  87.525 +class Texture : public Object
  87.526 +{
  87.527 +public:
  87.528 +
  87.529 +	Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
  87.530 +	~Texture();
  87.531 +
  87.532 +public:
  87.533 +
  87.534 +	const std::string& Type() const {
  87.535 +		return type;
  87.536 +	}
  87.537 +
  87.538 +	const std::string& FileName() const {
  87.539 +		return fileName;
  87.540 +	}
  87.541 +
  87.542 +	const std::string& RelativeFilename() const {
  87.543 +		return relativeFileName;
  87.544 +	}
  87.545 +
  87.546 +	const std::string& AlphaSource() const {
  87.547 +		return alphaSource;
  87.548 +	}
  87.549 +
  87.550 +	const aiVector2D& UVTranslation() const {
  87.551 +		return uvTrans;
  87.552 +	}
  87.553 +
  87.554 +	const aiVector2D& UVScaling() const {
  87.555 +		return uvScaling;
  87.556 +	}
  87.557 +
  87.558 +	const PropertyTable& Props() const {
  87.559 +		ai_assert(props.get());
  87.560 +		return *props.get();
  87.561 +	}
  87.562 +
  87.563 +	// return a 4-tuple 
  87.564 +	const unsigned int* Crop() const {
  87.565 +		return crop;
  87.566 +	}
  87.567 +
  87.568 +private:
  87.569 +
  87.570 +	aiVector2D uvTrans;
  87.571 +	aiVector2D uvScaling;
  87.572 +
  87.573 +	std::string type;
  87.574 +	std::string relativeFileName;
  87.575 +	std::string fileName;
  87.576 +	std::string alphaSource;
  87.577 +	boost::shared_ptr<const PropertyTable> props;
  87.578 +
  87.579 +	unsigned int crop[4];
  87.580 +};
  87.581 +
  87.582 +
  87.583 +typedef std::fbx_unordered_map<std::string, const Texture*> TextureMap;
  87.584 +
  87.585 +
  87.586 +/** DOM class for generic FBX materials */
  87.587 +class Material : public Object
  87.588 +{
  87.589 +public:
  87.590 +
  87.591 +	Material(uint64_t id, const Element& element, const Document& doc, const std::string& name);
  87.592 +	~Material();
  87.593 +
  87.594 +public:
  87.595 +
  87.596 +	const std::string& GetShadingModel() const {
  87.597 +		return shading;
  87.598 +	}
  87.599 +
  87.600 +	bool IsMultilayer() const {
  87.601 +		return multilayer;
  87.602 +	}
  87.603 +
  87.604 +	const PropertyTable& Props() const {
  87.605 +		ai_assert(props.get());
  87.606 +		return *props.get();
  87.607 +	}
  87.608 +
  87.609 +	const TextureMap& Textures() const {
  87.610 +		return textures;
  87.611 +	}
  87.612 +
  87.613 +private:
  87.614 +
  87.615 +	std::string shading;
  87.616 +	bool multilayer;
  87.617 +	boost::shared_ptr<const PropertyTable> props;
  87.618 +
  87.619 +	TextureMap textures;
  87.620 +};
  87.621 +
  87.622 +
  87.623 +/** DOM base class for all kinds of FBX geometry */
  87.624 +class Geometry : public Object
  87.625 +{
  87.626 +public:
  87.627 +
  87.628 +	Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc);
  87.629 +	~Geometry();
  87.630 +
  87.631 +public:
  87.632 +
  87.633 +	/** Get the Skin attached to this geometry or NULL */
  87.634 +	const Skin* const DeformerSkin() const {
  87.635 +		return skin;
  87.636 +	}
  87.637 +
  87.638 +private:
  87.639 +
  87.640 +	const Skin* skin;
  87.641 +};
  87.642 +
  87.643 +
  87.644 +typedef std::vector<int> MatIndexArray;
  87.645 +
  87.646 +
  87.647 +/** DOM class for FBX geometry of type "Mesh"*/
  87.648 +class MeshGeometry : public Geometry
  87.649 +{
  87.650 +
  87.651 +public:
  87.652 +
  87.653 +	MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc);
  87.654 +	~MeshGeometry();
  87.655 +
  87.656 +public:
  87.657 +
  87.658 +	/** Get a list of all vertex points, non-unique*/
  87.659 +	const std::vector<aiVector3D>& GetVertices() const {
  87.660 +		return vertices;
  87.661 +	}
  87.662 +
  87.663 +	/** Get a list of all vertex normals or an empty array if
  87.664 +	 *  no normals are specified. */
  87.665 +	const std::vector<aiVector3D>& GetNormals() const {
  87.666 +		return normals;
  87.667 +	}
  87.668 +
  87.669 +	/** Get a list of all vertex tangents or an empty array
  87.670 +	 *  if no tangents are specified */
  87.671 +	const std::vector<aiVector3D>& GetTangents() const {
  87.672 +		return tangents;
  87.673 +	}
  87.674 +
  87.675 +	/** Get a list of all vertex binormals or an empty array
  87.676 +	 *  if no binormals are specified */
  87.677 +	const std::vector<aiVector3D>& GetBinormals() const {
  87.678 +		return binormals;
  87.679 +	}
  87.680 +	
  87.681 +	/** Return list of faces - each entry denotes a face and specifies
  87.682 +	 *  how many vertices it has. Vertices are taken from the 
  87.683 +	 *  vertex data arrays in sequential order. */
  87.684 +	const std::vector<unsigned int>& GetFaceIndexCounts() const {
  87.685 +		return faces;
  87.686 +	}
  87.687 +
  87.688 +	/** Get a UV coordinate slot, returns an empty array if
  87.689 +	 *  the requested slot does not exist. */
  87.690 +	const std::vector<aiVector2D>& GetTextureCoords(unsigned int index) const {
  87.691 +		static const std::vector<aiVector2D> empty;
  87.692 +		return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[index];
  87.693 +	}
  87.694 +
  87.695 +
  87.696 +	/** Get a UV coordinate slot, returns an empty array if
  87.697 +	 *  the requested slot does not exist. */
  87.698 +	std::string GetTextureCoordChannelName(unsigned int index) const {
  87.699 +		return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? "" : uvNames[index];
  87.700 +	}
  87.701 +
  87.702 +	/** Get a vertex color coordinate slot, returns an empty array if
  87.703 +	 *  the requested slot does not exist. */
  87.704 +	const std::vector<aiColor4D>& GetVertexColors(unsigned int index) const {
  87.705 +		static const std::vector<aiColor4D> empty;
  87.706 +		return index >= AI_MAX_NUMBER_OF_COLOR_SETS ? empty : colors[index];
  87.707 +	}
  87.708 +	
  87.709 +	
  87.710 +	/** Get per-face-vertex material assignments */
  87.711 +	const MatIndexArray& GetMaterialIndices() const {
  87.712 +		return materials;
  87.713 +	}
  87.714 +
  87.715 +
  87.716 +	/** Convert from a fbx file vertex index (for example from a #Cluster weight) or NULL
  87.717 +	  * if the vertex index is not valid. */
  87.718 +	const unsigned int* ToOutputVertexIndex(unsigned int in_index, unsigned int& count) const {
  87.719 +		if(in_index >= mapping_counts.size()) {
  87.720 +			return NULL;
  87.721 +		}
  87.722 +
  87.723 +		ai_assert(mapping_counts.size() == mapping_offsets.size());
  87.724 +		count = mapping_counts[in_index];
  87.725 +
  87.726 +		ai_assert(count != 0);
  87.727 +		ai_assert(mapping_offsets[in_index] + count <= mappings.size());
  87.728 +
  87.729 +		return &mappings[mapping_offsets[in_index]];
  87.730 +	}
  87.731 +
  87.732 +
  87.733 +	/** Determine the face to which a particular output vertex index belongs.
  87.734 +	 *  This mapping is always unique. */
  87.735 +	unsigned int FaceForVertexIndex(unsigned int in_index) const {
  87.736 +		ai_assert(in_index < vertices.size());
  87.737 +	
  87.738 +		// in the current conversion pattern this will only be needed if
  87.739 +		// weights are present, so no need to always pre-compute this table
  87.740 +		if (facesVertexStartIndices.empty()) {
  87.741 +			facesVertexStartIndices.resize(faces.size() + 1, 0);
  87.742 +
  87.743 +			std::partial_sum(faces.begin(), faces.end(), facesVertexStartIndices.begin() + 1);
  87.744 +			facesVertexStartIndices.pop_back();
  87.745 +		}
  87.746 +
  87.747 +		ai_assert(facesVertexStartIndices.size() == faces.size());
  87.748 +		const std::vector<unsigned int>::iterator it = std::upper_bound(
  87.749 +			facesVertexStartIndices.begin(),
  87.750 +			facesVertexStartIndices.end(),
  87.751 +			in_index
  87.752 +		);
  87.753 +
  87.754 +		return static_cast<unsigned int>(std::distance(facesVertexStartIndices.begin(), it - 1)); 
  87.755 +	}
  87.756 +
  87.757 +public:
  87.758 +
  87.759 +private:
  87.760 +
  87.761 +	void ReadLayer(const Scope& layer);
  87.762 +	void ReadLayerElement(const Scope& layerElement);
  87.763 +	void ReadVertexData(const std::string& type, int index, const Scope& source);
  87.764 +
  87.765 +	void ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope& source, 
  87.766 +		const std::string& MappingInformationType,
  87.767 +		const std::string& ReferenceInformationType);
  87.768 +
  87.769 +	void ReadVertexDataNormals(std::vector<aiVector3D>& normals_out, const Scope& source, 
  87.770 +		const std::string& MappingInformationType,
  87.771 +		const std::string& ReferenceInformationType);
  87.772 +
  87.773 +	void ReadVertexDataColors(std::vector<aiColor4D>& colors_out, const Scope& source, 
  87.774 +		const std::string& MappingInformationType,
  87.775 +		const std::string& ReferenceInformationType);
  87.776 +
  87.777 +	void ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source, 
  87.778 +		const std::string& MappingInformationType,
  87.779 +		const std::string& ReferenceInformationType);
  87.780 +
  87.781 +	void ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source, 
  87.782 +		const std::string& MappingInformationType,
  87.783 +		const std::string& ReferenceInformationType);
  87.784 +
  87.785 +	void ReadVertexDataMaterials(MatIndexArray& materials_out, const Scope& source, 
  87.786 +		const std::string& MappingInformationType,
  87.787 +		const std::string& ReferenceInformationType);
  87.788 +
  87.789 +private:
  87.790 +
  87.791 +	// cached data arrays
  87.792 +	MatIndexArray materials;
  87.793 +	std::vector<aiVector3D> vertices;
  87.794 +	std::vector<unsigned int> faces;
  87.795 +	mutable std::vector<unsigned int> facesVertexStartIndices;
  87.796 +	std::vector<aiVector3D> tangents;
  87.797 +	std::vector<aiVector3D> binormals;
  87.798 +	std::vector<aiVector3D> normals;
  87.799 +
  87.800 +	std::string uvNames[AI_MAX_NUMBER_OF_TEXTURECOORDS];
  87.801 +	std::vector<aiVector2D> uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS];
  87.802 +	std::vector<aiColor4D> colors[AI_MAX_NUMBER_OF_COLOR_SETS];
  87.803 +
  87.804 +	std::vector<unsigned int> mapping_counts;
  87.805 +	std::vector<unsigned int> mapping_offsets;
  87.806 +	std::vector<unsigned int> mappings;
  87.807 +};
  87.808 +
  87.809 +typedef std::vector<uint64_t> KeyTimeList;
  87.810 +typedef std::vector<float> KeyValueList;
  87.811 +
  87.812 +/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */
  87.813 +class AnimationCurve : public Object
  87.814 +{
  87.815 +public:
  87.816 +
  87.817 +	AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
  87.818 +	~AnimationCurve();
  87.819 +
  87.820 +public:
  87.821 +
  87.822 +	/** get list of keyframe positions (time).
  87.823 +	 *  Invariant: |GetKeys()| > 0 */
  87.824 +	const KeyTimeList& GetKeys() const {
  87.825 +		return keys;
  87.826 +	}
  87.827 +
  87.828 +
  87.829 +	/** get list of keyframe values. 
  87.830 +	  * Invariant: |GetKeys()| == |GetValues()| && |GetKeys()| > 0*/
  87.831 +	const KeyValueList& GetValues() const {
  87.832 +		return values;
  87.833 +	}
  87.834 +
  87.835 +
  87.836 +	const std::vector<float>& GetAttributes() const {
  87.837 +		return attributes;
  87.838 +	}
  87.839 +
  87.840 +	const std::vector<unsigned int>& GetFlags() const {
  87.841 +		return flags;
  87.842 +	}
  87.843 +
  87.844 +private:
  87.845 +
  87.846 +	KeyTimeList keys;
  87.847 +	KeyValueList values;
  87.848 +	std::vector<float> attributes;
  87.849 +	std::vector<unsigned int> flags;
  87.850 +};
  87.851 +
  87.852 +// property-name -> animation curve
  87.853 +typedef std::map<std::string, const AnimationCurve*> AnimationCurveMap;
  87.854 +
  87.855 +
  87.856 +/** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */
  87.857 +class AnimationCurveNode : public Object
  87.858 +{
  87.859 +public:
  87.860 +
  87.861 +	/* the optional whitelist specifies a list of property names for which the caller
  87.862 +	wants animations for. If the curve node does not match one of these, std::range_error
  87.863 +	will be thrown. */
  87.864 +	AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
  87.865 +		const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0);
  87.866 +
  87.867 +	~AnimationCurveNode();
  87.868 +
  87.869 +public:
  87.870 +
  87.871 +	const PropertyTable& Props() const {
  87.872 +		ai_assert(props.get());
  87.873 +		return *props.get();
  87.874 +	}
  87.875 +
  87.876 +
  87.877 +	const AnimationCurveMap& Curves() const;
  87.878 +
  87.879 +	/** Object the curve is assigned to, this can be NULL if the
  87.880 +	 *  target object has no DOM representation or could not
  87.881 +	 *  be read for other reasons.*/
  87.882 +	const Object* Target() const {
  87.883 +		return target;
  87.884 +	}
  87.885 +
  87.886 +	const Model* TargetAsModel() const {
  87.887 +		return dynamic_cast<const Model*>(target);
  87.888 +	}
  87.889 +
  87.890 +	const NodeAttribute* TargetAsNodeAttribute() const {
  87.891 +		return dynamic_cast<const NodeAttribute*>(target);
  87.892 +	}
  87.893 +
  87.894 +	/** Property of Target() that is being animated*/
  87.895 +	const std::string& TargetProperty() const {
  87.896 +		return prop;
  87.897 +	}
  87.898 +
  87.899 +private:
  87.900 +
  87.901 +	const Object* target;
  87.902 +	boost::shared_ptr<const PropertyTable> props;
  87.903 +	mutable AnimationCurveMap curves;
  87.904 +
  87.905 +	std::string prop;
  87.906 +	const Document& doc;
  87.907 +};
  87.908 +
  87.909 +typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList;
  87.910 +
  87.911 +
  87.912 +/** Represents a FBX animation layer (i.e. a list of node animations) */
  87.913 +class AnimationLayer : public Object
  87.914 +{
  87.915 +public:
  87.916 +
  87.917 +	
  87.918 +	AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
  87.919 +	~AnimationLayer();
  87.920 +
  87.921 +public:
  87.922 +
  87.923 +	const PropertyTable& Props() const {
  87.924 +		ai_assert(props.get());
  87.925 +		return *props.get();
  87.926 +	}
  87.927 +
  87.928 +	/* the optional whitelist specifies a list of property names for which the caller
  87.929 +	wants animations for. Curves not matching this list will not be added to the
  87.930 +	animation layer. */
  87.931 +	AnimationCurveNodeList Nodes(const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0) const;
  87.932 +
  87.933 +private:
  87.934 +
  87.935 +	boost::shared_ptr<const PropertyTable> props;
  87.936 +	const Document& doc;
  87.937 +};
  87.938 +
  87.939 +
  87.940 +typedef std::vector<const AnimationLayer*> AnimationLayerList;
  87.941 +
  87.942 +
  87.943 +/** Represents a FBX animation stack (i.e. a list of animation layers) */
  87.944 +class AnimationStack : public Object
  87.945 +{
  87.946 +public:
  87.947 +
  87.948 +	AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
  87.949 +	~AnimationStack();
  87.950 +
  87.951 +public:
  87.952 +
  87.953 +	fbx_simple_property(LocalStart, uint64_t, 0L);
  87.954 +	fbx_simple_property(LocalStop, uint64_t, 0L);
  87.955 +	fbx_simple_property(ReferenceStart, uint64_t, 0L);
  87.956 +	fbx_simple_property(ReferenceStop, uint64_t, 0L);
  87.957 +
  87.958 +
  87.959 +
  87.960 +	const PropertyTable& Props() const {
  87.961 +		ai_assert(props.get());
  87.962 +		return *props.get();
  87.963 +	}
  87.964 +
  87.965 +
  87.966 +	const AnimationLayerList& Layers() const {
  87.967 +		return layers;
  87.968 +	}
  87.969 +
  87.970 +private:
  87.971 +
  87.972 +	boost::shared_ptr<const PropertyTable> props;
  87.973 +	AnimationLayerList layers;
  87.974 +};
  87.975 +
  87.976 +
  87.977 +/** DOM class for deformers */
  87.978 +class Deformer : public Object
  87.979 +{
  87.980 +public:
  87.981 +
  87.982 +	Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name);
  87.983 +	~Deformer();
  87.984 +
  87.985 +public:
  87.986 +
  87.987 +	const PropertyTable& Props() const {
  87.988 +		ai_assert(props.get());
  87.989 +		return *props.get();
  87.990 +	}
  87.991 +
  87.992 +private:
  87.993 +
  87.994 +	boost::shared_ptr<const PropertyTable> props;
  87.995 +};
  87.996 +
  87.997 +typedef std::vector<float> WeightArray;
  87.998 +typedef std::vector<unsigned int> WeightIndexArray;
  87.999 +
 87.1000 +
 87.1001 +/** DOM class for skin deformer clusters (aka subdeformers) */
 87.1002 +class Cluster : public Deformer
 87.1003 +{
 87.1004 +public:
 87.1005 +
 87.1006 +	Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name);
 87.1007 +	~Cluster();
 87.1008 +
 87.1009 +public:
 87.1010 +
 87.1011 +	/** get the list of deformer weights associated with this cluster.
 87.1012 +	 *  Use #GetIndices() to get the associated vertices. Both arrays
 87.1013 +	 *  have the same size (and may also be empty). */
 87.1014 +	const WeightArray& GetWeights() const {
 87.1015 +		return weights;
 87.1016 +	}
 87.1017 +
 87.1018 +	/** get indices into the vertex data of the geometry associated
 87.1019 +	 *  with this cluster. Use #GetWeights() to get the associated weights.
 87.1020 +	 *  Both arrays have the same size (and may also be empty). */
 87.1021 +	const WeightIndexArray& GetIndices() const {
 87.1022 +		return indices;
 87.1023 +	}
 87.1024 +
 87.1025 +	/** */
 87.1026 +	const aiMatrix4x4& Transform() const {
 87.1027 +		return transform;
 87.1028 +	}
 87.1029 +
 87.1030 +	const aiMatrix4x4& TransformLink() const {
 87.1031 +		return transformLink;
 87.1032 +	}
 87.1033 +
 87.1034 +	const Model* const TargetNode() const {
 87.1035 +		return node;
 87.1036 +	}
 87.1037 +
 87.1038 +private:
 87.1039 +
 87.1040 +	WeightArray weights;
 87.1041 +	WeightIndexArray indices;
 87.1042 +
 87.1043 +	aiMatrix4x4 transform;
 87.1044 +	aiMatrix4x4 transformLink;
 87.1045 +
 87.1046 +	const Model* node;
 87.1047 +};
 87.1048 +
 87.1049 +
 87.1050 +
 87.1051 +/** DOM class for skin deformers */
 87.1052 +class Skin : public Deformer
 87.1053 +{
 87.1054 +public:
 87.1055 +
 87.1056 +	Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name);
 87.1057 +	~Skin();
 87.1058 +
 87.1059 +public:
 87.1060 +
 87.1061 +	float DeformAccuracy() const {
 87.1062 +		return accuracy;
 87.1063 +	}
 87.1064 +
 87.1065 +
 87.1066 +	const std::vector<const Cluster*>& Clusters() const {
 87.1067 +		return clusters;
 87.1068 +	}
 87.1069 +
 87.1070 +private:
 87.1071 +
 87.1072 +	float accuracy;
 87.1073 +	std::vector<const Cluster*> clusters;
 87.1074 +};
 87.1075 +
 87.1076 +
 87.1077 +
 87.1078 +/** Represents a link between two FBX objects. */
 87.1079 +class Connection
 87.1080 +{
 87.1081 +public:
 87.1082 +
 87.1083 +	Connection(uint64_t insertionOrder,  uint64_t src, uint64_t dest, const std::string& prop, const Document& doc);
 87.1084 +	~Connection();
 87.1085 +
 87.1086 +	// note: a connection ensures that the source and dest objects exist, but
 87.1087 +	// not that they have DOM representations, so the return value of one of
 87.1088 +	// these functions can still be NULL.
 87.1089 +	const Object* SourceObject() const;
 87.1090 +	const Object* DestinationObject() const;
 87.1091 +
 87.1092 +	// these, however, are always guaranteed to be valid
 87.1093 +	LazyObject& LazySourceObject() const;
 87.1094 +	LazyObject& LazyDestinationObject() const;
 87.1095 +
 87.1096 +
 87.1097 +	/** return the name of the property the connection is attached to.
 87.1098 +	  * this is an empty string for object to object (OO) connections. */
 87.1099 +	const std::string& PropertyName() const {
 87.1100 +		return prop;
 87.1101 +	}
 87.1102 +
 87.1103 +	uint64_t InsertionOrder() const {
 87.1104 +		return insertionOrder;
 87.1105 +	}
 87.1106 +
 87.1107 +	int CompareTo(const Connection* c) const {
 87.1108 +		// note: can't subtract because this would overflow uint64_t
 87.1109 +		if(InsertionOrder() > c->InsertionOrder()) {
 87.1110 +			return 1;
 87.1111 +		}
 87.1112 +		else if(InsertionOrder() < c->InsertionOrder()) {
 87.1113 +			return -1;
 87.1114 +		}
 87.1115 +		return 0;
 87.1116 +	}
 87.1117 +
 87.1118 +	bool Compare(const Connection* c) const {
 87.1119 +		return InsertionOrder() < c->InsertionOrder();
 87.1120 +	}
 87.1121 +
 87.1122 +public:
 87.1123 +
 87.1124 +	uint64_t insertionOrder;
 87.1125 +	const std::string prop;
 87.1126 +
 87.1127 +	uint64_t src, dest;
 87.1128 +	const Document& doc;
 87.1129 +};
 87.1130 +
 87.1131 +
 87.1132 +	// XXX again, unique_ptr would be useful. shared_ptr is too
 87.1133 +	// bloated since the objects have a well-defined single owner
 87.1134 +	// during their entire lifetime (Document). FBX files have
 87.1135 +	// up to many thousands of objects (most of which we never use),
 87.1136 +	// so the memory overhead for them should be kept at a minimum.
 87.1137 +	typedef std::map<uint64_t, LazyObject*> ObjectMap; 
 87.1138 +	typedef std::fbx_unordered_map<std::string, boost::shared_ptr<const PropertyTable> > PropertyTemplateMap;
 87.1139 +
 87.1140 +
 87.1141 +	typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
 87.1142 +
 87.1143 +
 87.1144 +/** DOM class for global document settings, a single instance per document can
 87.1145 + *  be accessed via Document.Globals(). */
 87.1146 +class FileGlobalSettings
 87.1147 +{
 87.1148 +public:
 87.1149 +
 87.1150 +	FileGlobalSettings(const Document& doc, boost::shared_ptr<const PropertyTable> props);
 87.1151 +	~FileGlobalSettings();
 87.1152 +
 87.1153 +public:
 87.1154 +
 87.1155 +	const PropertyTable& Props() const {
 87.1156 +		ai_assert(props.get());
 87.1157 +		return *props.get();
 87.1158 +	}
 87.1159 +
 87.1160 +	const Document& GetDocument() const {
 87.1161 +		return doc;
 87.1162 +	}
 87.1163 +
 87.1164 +
 87.1165 +	fbx_simple_property(UpAxis, int, 1);
 87.1166 +	fbx_simple_property(UpAxisSign, int, 1);
 87.1167 +	fbx_simple_property(FrontAxis, int, 2);
 87.1168 +	fbx_simple_property(FrontAxisSign, int, 1);
 87.1169 +	fbx_simple_property(CoordAxis, int, 0);
 87.1170 +	fbx_simple_property(CoordAxisSign, int, 1);
 87.1171 +	fbx_simple_property(OriginalUpAxis, int, 0);
 87.1172 +	fbx_simple_property(OriginalUpAxisSign, int, 1);
 87.1173 +	fbx_simple_property(UnitScaleFactor, double, 1);
 87.1174 +	fbx_simple_property(OriginalUnitScaleFactor, double, 1);
 87.1175 +	fbx_simple_property(AmbientColor, aiVector3D, aiVector3D(0,0,0));
 87.1176 +	fbx_simple_property(DefaultCamera, std::string, "");
 87.1177 +
 87.1178 +
 87.1179 +	enum FrameRate {
 87.1180 +		FrameRate_DEFAULT = 0,
 87.1181 +		FrameRate_120 = 1,
 87.1182 +		FrameRate_100 = 2,
 87.1183 +		FrameRate_60 = 3,
 87.1184 +		FrameRate_50 = 4,
 87.1185 +		FrameRate_48 = 5,
 87.1186 +		FrameRate_30 = 6,
 87.1187 +		FrameRate_30_DROP = 7,
 87.1188 +		FrameRate_NTSC_DROP_FRAME = 8,
 87.1189 +		FrameRate_NTSC_FULL_FRAME = 9,
 87.1190 +		FrameRate_PAL = 10,
 87.1191 +		FrameRate_CINEMA = 11,
 87.1192 +		FrameRate_1000 = 12,
 87.1193 +		FrameRate_CINEMA_ND = 13,
 87.1194 +		FrameRate_CUSTOM = 14,
 87.1195 +
 87.1196 +		FrameRate_MAX// end-of-enum sentinel
 87.1197 +	};
 87.1198 +
 87.1199 +	fbx_simple_enum_property(TimeMode, FrameRate, FrameRate_DEFAULT);
 87.1200 +	fbx_simple_property(TimeSpanStart, uint64_t, 0L);
 87.1201 +	fbx_simple_property(TimeSpanStop, uint64_t, 0L);
 87.1202 +	fbx_simple_property(CustomFrameRate, float, -1.0f);
 87.1203 +
 87.1204 +
 87.1205 +private:
 87.1206 +
 87.1207 +	boost::shared_ptr<const PropertyTable> props;
 87.1208 +	const Document& doc;
 87.1209 +};
 87.1210 +
 87.1211 +
 87.1212 +
 87.1213 +
 87.1214 +/** DOM root for a FBX file */
 87.1215 +class Document 
 87.1216 +{
 87.1217 +public:
 87.1218 +
 87.1219 +	Document(const Parser& parser, const ImportSettings& settings);
 87.1220 +	~Document();
 87.1221 +
 87.1222 +public:
 87.1223 +
 87.1224 +	LazyObject* GetObject(uint64_t id) const;
 87.1225 +
 87.1226 +	bool IsBinary() const {
 87.1227 +		return parser.IsBinary();
 87.1228 +	}
 87.1229 +
 87.1230 +	unsigned int FBXVersion() const {
 87.1231 +		return fbxVersion;
 87.1232 +	}
 87.1233 +
 87.1234 +	const std::string& Creator() const {
 87.1235 +		return creator;
 87.1236 +	}
 87.1237 +
 87.1238 +	// elements (in this order): Uear, Month, Day, Hour, Second, Millisecond
 87.1239 +	const unsigned int* CreationTimeStamp() const {
 87.1240 +		return creationTimeStamp;
 87.1241 +	}
 87.1242 +
 87.1243 +	const FileGlobalSettings& GlobalSettings() const {
 87.1244 +		ai_assert(globals.get());
 87.1245 +		return *globals.get();
 87.1246 +	}
 87.1247 +
 87.1248 +	const PropertyTemplateMap& Templates() const {
 87.1249 +		return templates;
 87.1250 +	}
 87.1251 +
 87.1252 +	const ObjectMap& Objects() const {
 87.1253 +		return objects;
 87.1254 +	}
 87.1255 +
 87.1256 +	const ImportSettings& Settings() const {
 87.1257 +		return settings;
 87.1258 +	}
 87.1259 +
 87.1260 +	const ConnectionMap& ConnectionsBySource() const {
 87.1261 +		return src_connections;
 87.1262 +	}
 87.1263 +
 87.1264 +	const ConnectionMap& ConnectionsByDestination() const {
 87.1265 +		return dest_connections;
 87.1266 +	}
 87.1267 +
 87.1268 +	// note: the implicit rule in all DOM classes is to always resolve
 87.1269 +	// from destination to source (since the FBX object hierarchy is,
 87.1270 +	// with very few exceptions, a DAG, this avoids cycles). In all
 87.1271 +	// cases that may involve back-facing edges in the object graph,
 87.1272 +	// use LazyObject::IsBeingConstructed() to check.
 87.1273 +
 87.1274 +	std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source) const;
 87.1275 +	std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest) const;
 87.1276 +
 87.1277 +	std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source, const char* classname) const;
 87.1278 +	std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest, const char* classname) const;
 87.1279 +
 87.1280 +	std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source, 
 87.1281 +		const char* const* classnames, size_t count) const;
 87.1282 +	std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest, 
 87.1283 +		const char* const* classnames, 
 87.1284 +		size_t count) const;
 87.1285 +
 87.1286 +	const std::vector<const AnimationStack*>& AnimationStacks() const;
 87.1287 +
 87.1288 +private:
 87.1289 +
 87.1290 +	std::vector<const Connection*> GetConnectionsSequenced(uint64_t id, const ConnectionMap&) const;
 87.1291 +	std::vector<const Connection*> GetConnectionsSequenced(uint64_t id, bool is_src, 
 87.1292 +		const ConnectionMap&, 
 87.1293 +		const char* const* classnames, 
 87.1294 +		size_t count) const;
 87.1295 +
 87.1296 +private:
 87.1297 +
 87.1298 +	void ReadHeader();
 87.1299 +	void ReadObjects();
 87.1300 +	void ReadPropertyTemplates();
 87.1301 +	void ReadConnections();
 87.1302 +	void ReadGlobalSettings();
 87.1303 +
 87.1304 +private:
 87.1305 +
 87.1306 +	const ImportSettings& settings;
 87.1307 +
 87.1308 +	ObjectMap objects;
 87.1309 +	const Parser& parser;
 87.1310 +
 87.1311 +	PropertyTemplateMap templates;
 87.1312 +	ConnectionMap src_connections;
 87.1313 +	ConnectionMap dest_connections;
 87.1314 +
 87.1315 +	unsigned int fbxVersion;
 87.1316 +	std::string creator;
 87.1317 +	unsigned int creationTimeStamp[7];
 87.1318 +
 87.1319 +	std::vector<uint64_t> animationStacks;
 87.1320 +	mutable std::vector<const AnimationStack*> animationStacksResolved;
 87.1321 +
 87.1322 +	boost::scoped_ptr<FileGlobalSettings> globals;
 87.1323 +};
 87.1324 +
 87.1325 +}
 87.1326 +}
 87.1327 +
 87.1328 +#endif
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/libs/assimp/FBXDocumentUtil.cpp	Sat Feb 01 19:58:19 2014 +0200
    88.3 @@ -0,0 +1,133 @@
    88.4 +/*
    88.5 +Open Asset Import Library (assimp)
    88.6 +----------------------------------------------------------------------
    88.7 +
    88.8 +Copyright (c) 2006-2012, assimp team
    88.9 +All rights reserved.
   88.10 +
   88.11 +Redistribution and use of this software in source and binary forms, 
   88.12 +with or without modification, are permitted provided that the 
   88.13 +following conditions are met:
   88.14 +
   88.15 +* Redistributions of source code must retain the above
   88.16 +  copyright notice, this list of conditions and the
   88.17 +  following disclaimer.
   88.18 +
   88.19 +* Redistributions in binary form must reproduce the above
   88.20 +  copyright notice, this list of conditions and the
   88.21 +  following disclaimer in the documentation and/or other
   88.22 +  materials provided with the distribution.
   88.23 +
   88.24 +* Neither the name of the assimp team, nor the names of its
   88.25 +  contributors may be used to endorse or promote products
   88.26 +  derived from this software without specific prior
   88.27 +  written permission of the assimp team.
   88.28 +
   88.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   88.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   88.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   88.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   88.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   88.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   88.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   88.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   88.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   88.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   88.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   88.40 +
   88.41 +----------------------------------------------------------------------
   88.42 +*/
   88.43 +
   88.44 +/** @file  FBXDocumentUtil.cpp
   88.45 + *  @brief Implementation of the FBX DOM utility functions declared in FBXDocumentUtil.h
   88.46 + */
   88.47 +#include "AssimpPCH.h"
   88.48 +
   88.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   88.50 +
   88.51 +#include "FBXParser.h"
   88.52 +#include "FBXDocument.h"
   88.53 +#include "FBXUtil.h"
   88.54 +#include "FBXDocumentUtil.h"
   88.55 +#include "FBXProperties.h"
   88.56 +
   88.57 +namespace Assimp {
   88.58 +namespace FBX {
   88.59 +namespace Util {
   88.60 +
   88.61 +// ------------------------------------------------------------------------------------------------
   88.62 +// signal DOM construction error, this is always unrecoverable. Throws DeadlyImportError.
   88.63 +void DOMError(const std::string& message, const Token& token)
   88.64 +{
   88.65 +	throw DeadlyImportError(Util::AddTokenText("FBX-DOM",message,&token));
   88.66 +}
   88.67 +
   88.68 +// ------------------------------------------------------------------------------------------------
   88.69 +void DOMError(const std::string& message, const Element* element /*= NULL*/)
   88.70 +{
   88.71 +	if(element) {
   88.72 +		DOMError(message,element->KeyToken());
   88.73 +	}
   88.74 +	throw DeadlyImportError("FBX-DOM " + message);
   88.75 +}
   88.76 +
   88.77 +
   88.78 +// ------------------------------------------------------------------------------------------------
   88.79 +// print warning, do return
   88.80 +void DOMWarning(const std::string& message, const Token& token)
   88.81 +{
   88.82 +	if(DefaultLogger::get()) {
   88.83 +		DefaultLogger::get()->warn(Util::AddTokenText("FBX-DOM",message,&token));
   88.84 +	}
   88.85 +}
   88.86 +
   88.87 +// ------------------------------------------------------------------------------------------------
   88.88 +void DOMWarning(const std::string& message, const Element* element /*= NULL*/)
   88.89 +{
   88.90 +	if(element) {
   88.91 +		DOMWarning(message,element->KeyToken());
   88.92 +		return;
   88.93 +	}
   88.94 +	if(DefaultLogger::get()) {
   88.95 +		DefaultLogger::get()->warn("FBX-DOM: " + message);
   88.96 +	}
   88.97 +}
   88.98 +
   88.99 +
  88.100 +// ------------------------------------------------------------------------------------------------
  88.101 +// fetch a property table and the corresponding property template 
  88.102 +boost::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc, 
  88.103 +	const std::string& templateName, 
  88.104 +	const Element &element, 
  88.105 +	const Scope& sc,
  88.106 +	bool no_warn /*= false*/)
  88.107 +{
  88.108 +	const Element* const Properties70 = sc["Properties70"];
  88.109 +	boost::shared_ptr<const PropertyTable> templateProps = boost::shared_ptr<const PropertyTable>(
  88.110 +		static_cast<const PropertyTable*>(NULL));
  88.111 +
  88.112 +	if(templateName.length()) {
  88.113 +		PropertyTemplateMap::const_iterator it = doc.Templates().find(templateName); 
  88.114 +		if(it != doc.Templates().end()) {
  88.115 +			templateProps = (*it).second;
  88.116 +		}
  88.117 +	}
  88.118 +
  88.119 +	if(!Properties70) {
  88.120 +		if(!no_warn) {
  88.121 +			DOMWarning("property table (Properties70) not found",&element);
  88.122 +		}
  88.123 +		if(templateProps) {
  88.124 +			return templateProps;
  88.125 +		}
  88.126 +		else {
  88.127 +			return boost::make_shared<const PropertyTable>();
  88.128 +		}
  88.129 +	}
  88.130 +	return boost::make_shared<const PropertyTable>(*Properties70,templateProps);
  88.131 +}
  88.132 +} // !Util
  88.133 +} // !FBX
  88.134 +} // !Assimp
  88.135 +
  88.136 +#endif
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/libs/assimp/FBXDocumentUtil.h	Sat Feb 01 19:58:19 2014 +0200
    89.3 @@ -0,0 +1,114 @@
    89.4 +/*
    89.5 +Open Asset Import Library (assimp)
    89.6 +----------------------------------------------------------------------
    89.7 +
    89.8 +Copyright (c) 2006-2012, assimp team
    89.9 +All rights reserved.
   89.10 +
   89.11 +Redistribution and use of this software in source and binary forms, 
   89.12 +with or without modification, are permitted provided that the 
   89.13 +following conditions are met:
   89.14 +
   89.15 +* Redistributions of source code must retain the above
   89.16 +  copyright notice, this list of conditions and the
   89.17 +  following disclaimer.
   89.18 +
   89.19 +* Redistributions in binary form must reproduce the above
   89.20 +  copyright notice, this list of conditions and the
   89.21 +  following disclaimer in the documentation and/or other
   89.22 +  materials provided with the distribution.
   89.23 +
   89.24 +* Neither the name of the assimp team, nor the names of its
   89.25 +  contributors may be used to endorse or promote products
   89.26 +  derived from this software without specific prior
   89.27 +  written permission of the assimp team.
   89.28 +
   89.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   89.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   89.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   89.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   89.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   89.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   89.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   89.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   89.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   89.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   89.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   89.40 +
   89.41 +----------------------------------------------------------------------
   89.42 +*/
   89.43 +
   89.44 +/** @file  FBXDocumentUtil.h
   89.45 + *  @brief FBX internal utilities used by the DOM reading code
   89.46 + */
   89.47 +#ifndef INCLUDED_AI_FBX_DOCUMENT_UTIL_H
   89.48 +#define INCLUDED_AI_FBX_DOCUMENT_UTIL_H
   89.49 +
   89.50 +namespace Assimp {
   89.51 +namespace FBX {
   89.52 +namespace Util {
   89.53 +
   89.54 +
   89.55 +/* DOM/Parse error reporting - does not return */
   89.56 +void DOMError(const std::string& message, const Token& token);
   89.57 +void DOMError(const std::string& message, const Element* element = NULL);
   89.58 +
   89.59 +// does return
   89.60 +void DOMWarning(const std::string& message, const Token& token);
   89.61 +void DOMWarning(const std::string& message, const Element* element = NULL);
   89.62 +
   89.63 +
   89.64 +// fetch a property table and the corresponding property template 
   89.65 +boost::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc, 
   89.66 +	const std::string& templateName, 
   89.67 +	const Element &element, 
   89.68 +	const Scope& sc,
   89.69 +	bool no_warn = false);
   89.70 +
   89.71 +
   89.72 +// ------------------------------------------------------------------------------------------------
   89.73 +template <typename T>
   89.74 +inline const T* ProcessSimpleConnection(const Connection& con, 
   89.75 +	bool is_object_property_conn, 
   89.76 +	const char* name, 
   89.77 +	const Element& element, 
   89.78 +	const char** propNameOut = NULL)
   89.79 +{
   89.80 +	if (is_object_property_conn && !con.PropertyName().length()) {
   89.81 +		DOMWarning("expected incoming " + std::string(name) +
   89.82 +			" link to be an object-object connection, ignoring",
   89.83 +			&element
   89.84 +			);
   89.85 +		return NULL;
   89.86 +	}
   89.87 +	else if (!is_object_property_conn && con.PropertyName().length()) {
   89.88 +		DOMWarning("expected incoming " + std::string(name) +
   89.89 +			" link to be an object-property connection, ignoring",
   89.90 +			&element
   89.91 +			);
   89.92 +		return NULL;
   89.93 +	}
   89.94 +
   89.95 +	if(is_object_property_conn && propNameOut) {
   89.96 +		// note: this is ok, the return value of PropertyValue() is guaranteed to 
   89.97 +		// remain valid and unchanged as long as the document exists.
   89.98 +		*propNameOut = con.PropertyName().c_str();
   89.99 +	}
  89.100 +
  89.101 +	const Object* const ob = con.SourceObject();
  89.102 +	if(!ob) {
  89.103 +		DOMWarning("failed to read source object for incoming" + std::string(name) +
  89.104 +			" link, ignoring",
  89.105 +			&element);
  89.106 +		return NULL;
  89.107 +	}
  89.108 +
  89.109 +	return dynamic_cast<const T*>(ob);
  89.110 +}
  89.111 +
  89.112 +
  89.113 +} //!Util
  89.114 +} //!FBX
  89.115 +} //!Assimp
  89.116 +
  89.117 +#endif
    90.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.2 +++ b/libs/assimp/FBXImportSettings.h	Sat Feb 01 19:58:19 2014 +0200
    90.3 @@ -0,0 +1,142 @@
    90.4 +/*
    90.5 +Open Asset Import Library (assimp)
    90.6 +----------------------------------------------------------------------
    90.7 +
    90.8 +Copyright (c) 2006-2012, assimp team
    90.9 +All rights reserved.
   90.10 +
   90.11 +Redistribution and use of this software in source and binary forms, 
   90.12 +with or without modification, are permitted provided that the 
   90.13 +following conditions are met:
   90.14 +
   90.15 +* Redistributions of source code must retain the above
   90.16 +  copyright notice, this list of conditions and the
   90.17 +  following disclaimer.
   90.18 +
   90.19 +* Redistributions in binary form must reproduce the above
   90.20 +  copyright notice, this list of conditions and the
   90.21 +  following disclaimer in the documentation and/or other
   90.22 +  materials provided with the distribution.
   90.23 +
   90.24 +* Neither the name of the assimp team, nor the names of its
   90.25 +  contributors may be used to endorse or promote products
   90.26 +  derived from this software without specific prior
   90.27 +  written permission of the assimp team.
   90.28 +
   90.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   90.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   90.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   90.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   90.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   90.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   90.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   90.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   90.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   90.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   90.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   90.40 +
   90.41 +----------------------------------------------------------------------
   90.42 +*/
   90.43 +
   90.44 +/** @file  FBXImportSettings.h
   90.45 + *  @brief FBX importer runtime configuration
   90.46 + */
   90.47 +#ifndef INCLUDED_AI_FBX_IMPORTSETTINGS_H
   90.48 +#define INCLUDED_AI_FBX_IMPORTSETTINGS_H
   90.49 +
   90.50 +namespace Assimp {
   90.51 +namespace FBX {
   90.52 +
   90.53 +/** FBX import settings, parts of which are publicly accessible via their corresponding AI_CONFIG constants */
   90.54 +struct ImportSettings 
   90.55 +{
   90.56 +	ImportSettings()
   90.57 +		: strictMode(true)
   90.58 +		, readAllLayers(true)
   90.59 +		, readAllMaterials()
   90.60 +		, readMaterials(true)
   90.61 +		, readCameras(true)
   90.62 +		, readLights(true)
   90.63 +		, readAnimations(true)
   90.64 +		, readWeights(true)
   90.65 +		, preservePivots(true)
   90.66 +		, optimizeEmptyAnimationCurves(true)
   90.67 +	{}
   90.68 + 
   90.69 +
   90.70 +	/** enable strict mode:
   90.71 +	 *   - only accept fbx 2012, 2013 files
   90.72 +	 *   - on the slightest error, give up.
   90.73 +	 *
   90.74 +	 *  Basically, strict mode means that the fbx file will actually
   90.75 +	 *  be validated. Strict mode is off by default. */
   90.76 +	bool strictMode;
   90.77 +
   90.78 +	/** specifies whether all geometry layers are read and scanned for
   90.79 +	  * usable data channels. The FBX spec indicates that many readers
   90.80 +	  * will only read the first channel and that this is in some way
   90.81 +	  * the recommended way- in reality, however, it happens a lot that 
   90.82 +	  * vertex data is spread among multiple layers. The default
   90.83 +	  * value for this option is true.*/
   90.84 +	bool readAllLayers;
   90.85 +
   90.86 +	/** specifies whether all materials are read, or only those that
   90.87 +	 *  are referenced by at least one mesh. Reading all materials
   90.88 +	 *  may make FBX reading a lot slower since all objects
   90.89 +	 *  need to be processed .
   90.90 +	 *  This bit is ignored unless readMaterials=true*/
   90.91 +	bool readAllMaterials;
   90.92 +
   90.93 +
   90.94 +	/** import materials (true) or skip them and assign a default 
   90.95 +	 *  material. The default value is true.*/
   90.96 +	bool readMaterials;
   90.97 +
   90.98 +	/** import cameras? Default value is true.*/
   90.99 +	bool readCameras;
  90.100 +
  90.101 +	/** import light sources? Default value is true.*/
  90.102 +	bool readLights;
  90.103 +
  90.104 +	/** import animations (i.e. animation curves, the node
  90.105 +	 *  skeleton is always imported). Default value is true. */
  90.106 +	bool readAnimations;
  90.107 +
  90.108 +	/** read bones (vertex weights and deform info).
  90.109 +	 *  Default value is true. */
  90.110 +	bool readWeights;
  90.111 +
  90.112 +	/** preserve transformation pivots and offsets. Since these can
  90.113 +	 *  not directly be represented in assimp, additional dummy
  90.114 +	 *  nodes will be generated. Note that settings this to false
  90.115 +	 *  can make animation import a lot slower. The default value
  90.116 +	 *  is true.
  90.117 +	 *
  90.118 +	 *  The naming scheme for the generated nodes is:
  90.119 +	 *    <OriginalName>_$AssimpFbx$_<TransformName>
  90.120 +	 *  
  90.121 +	 *  where <TransformName> is one of
  90.122 +	 *    RotationPivot
  90.123 +	 *    RotationOffset
  90.124 +	 *    PreRotation
  90.125 +	 *    PostRotation
  90.126 +	 *    ScalingPivot
  90.127 +	 *    ScalingOffset
  90.128 +	 *    Translation
  90.129 +	 *    Scaling
  90.130 +	 *    Rotation
  90.131 +	 **/
  90.132 +	bool preservePivots;
  90.133 +
  90.134 +	/** do not import animation curves that specify a constant
  90.135 +	 *  values matching the corresponding node transformation.
  90.136 +	 *  The default value is true. */
  90.137 +	bool optimizeEmptyAnimationCurves;
  90.138 +};
  90.139 +
  90.140 +
  90.141 +} // !FBX
  90.142 +} // !Assimp
  90.143 +
  90.144 +#endif
  90.145 +
    91.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.2 +++ b/libs/assimp/FBXImporter.cpp	Sat Feb 01 19:58:19 2014 +0200
    91.3 @@ -0,0 +1,189 @@
    91.4 +/*
    91.5 +Open Asset Import Library (assimp)
    91.6 +----------------------------------------------------------------------
    91.7 +
    91.8 +Copyright (c) 2006-2012, assimp team
    91.9 +All rights reserved.
   91.10 +
   91.11 +Redistribution and use of this software in source and binary forms, 
   91.12 +with or without modification, are permitted provided that the 
   91.13 +following conditions are met:
   91.14 +
   91.15 +* Redistributions of source code must retain the above
   91.16 +  copyright notice, this list of conditions and the
   91.17 +  following disclaimer.
   91.18 +
   91.19 +* Redistributions in binary form must reproduce the above
   91.20 +  copyright notice, this list of conditions and the
   91.21 +  following disclaimer in the documentation and/or other
   91.22 +  materials provided with the distribution.
   91.23 +
   91.24 +* Neither the name of the assimp team, nor the names of its
   91.25 +  contributors may be used to endorse or promote products
   91.26 +  derived from this software without specific prior
   91.27 +  written permission of the assimp team.
   91.28 +
   91.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   91.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   91.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   91.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   91.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   91.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   91.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   91.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   91.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   91.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   91.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   91.40 +
   91.41 +----------------------------------------------------------------------
   91.42 +*/
   91.43 +
   91.44 +/** @file  FBXImporter.cpp
   91.45 + *  @brief Implementation of the FBX importer.
   91.46 + */
   91.47 +#include "AssimpPCH.h"
   91.48 +
   91.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   91.50 +
   91.51 +#include <exception>
   91.52 +#include <iterator>
   91.53 +#include <boost/tuple/tuple.hpp>
   91.54 +
   91.55 +#include "FBXImporter.h"
   91.56 +
   91.57 +#include "FBXTokenizer.h"
   91.58 +#include "FBXParser.h"
   91.59 +#include "FBXUtil.h"
   91.60 +#include "FBXDocument.h"
   91.61 +#include "FBXConverter.h"
   91.62 +
   91.63 +#include "StreamReader.h"
   91.64 +#include "MemoryIOWrapper.h"
   91.65 +
   91.66 +namespace Assimp {
   91.67 +	template<> const std::string LogFunctions<FBXImporter>::log_prefix = "FBX: ";
   91.68 +}
   91.69 +
   91.70 +using namespace Assimp;
   91.71 +using namespace Assimp::Formatter;
   91.72 +using namespace Assimp::FBX;
   91.73 +
   91.74 +namespace {
   91.75 +static const aiImporterDesc desc = {
   91.76 +	"Autodesk FBX Importer",
   91.77 +	"",
   91.78 +	"",
   91.79 +	"",
   91.80 +	aiImporterFlags_SupportTextFlavour,
   91.81 +	0,
   91.82 +	0,
   91.83 +	0,
   91.84 +	0,
   91.85 +	"fbx" 
   91.86 +};
   91.87 +}
   91.88 +
   91.89 +// ------------------------------------------------------------------------------------------------
   91.90 +// Constructor to be privately used by #Importer
   91.91 +FBXImporter::FBXImporter()
   91.92 +{}
   91.93 +
   91.94 +// ------------------------------------------------------------------------------------------------
   91.95 +// Destructor, private as well 
   91.96 +FBXImporter::~FBXImporter()
   91.97 +{
   91.98 +}
   91.99 +
  91.100 +// ------------------------------------------------------------------------------------------------
  91.101 +// Returns whether the class can handle the format of the given file. 
  91.102 +bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  91.103 +{
  91.104 +	const std::string& extension = GetExtension(pFile);
  91.105 +	if (extension == "fbx") {
  91.106 +		return true;
  91.107 +	}
  91.108 +
  91.109 +	else if ((!extension.length() || checkSig) && pIOHandler)	{
  91.110 +		// at least ascii FBX files usually have a 'FBX' somewhere in their head
  91.111 +		const char* tokens[] = {"FBX"};
  91.112 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
  91.113 +	}
  91.114 +	return false;
  91.115 +}
  91.116 +
  91.117 +// ------------------------------------------------------------------------------------------------
  91.118 +// List all extensions handled by this loader
  91.119 +const aiImporterDesc* FBXImporter::GetInfo () const
  91.120 +{
  91.121 +	return &desc;
  91.122 +}
  91.123 +
  91.124 +
  91.125 +// ------------------------------------------------------------------------------------------------
  91.126 +// Setup configuration properties for the loader
  91.127 +void FBXImporter::SetupProperties(const Importer* pImp)
  91.128 +{
  91.129 +	settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
  91.130 +	settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
  91.131 +	settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
  91.132 +	settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
  91.133 +	settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
  91.134 +	settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
  91.135 +	settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
  91.136 +	settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
  91.137 +	settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
  91.138 +}
  91.139 +
  91.140 +
  91.141 +// ------------------------------------------------------------------------------------------------
  91.142 +// Imports the given file into the given scene structure. 
  91.143 +void FBXImporter::InternReadFile( const std::string& pFile, 
  91.144 +	aiScene* pScene, IOSystem* pIOHandler)
  91.145 +{
  91.146 +	boost::scoped_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
  91.147 +	if (!stream) {
  91.148 +		ThrowException("Could not open file for reading");
  91.149 +	}
  91.150 +
  91.151 +	// read entire file into memory - no streaming for this, fbx
  91.152 +	// files can grow large, but the assimp output data structure
  91.153 +	// then becomes very large, too. Assimp doesn't support
  91.154 +	// streaming for its output data structures so the net win with
  91.155 +	// streaming input data would be very low.
  91.156 +	std::vector<char> contents;
  91.157 +	contents.resize(stream->FileSize());
  91.158 +
  91.159 +	stream->Read(&*contents.begin(),contents.size(),1);
  91.160 +	const char* const begin = &*contents.begin();
  91.161 +
  91.162 +	// broadphase tokenizing pass in which we identify the core
  91.163 +	// syntax elements of FBX (brackets, commas, key:value mappings)
  91.164 +	TokenList tokens;
  91.165 +	try {
  91.166 +
  91.167 +		bool is_binary = false;
  91.168 +		if (!strncmp(begin,"Kaydara FBX Binary",18)) {
  91.169 +			is_binary = true;
  91.170 +			TokenizeBinary(tokens,begin,contents.size());
  91.171 +		}
  91.172 +		else {
  91.173 +			Tokenize(tokens,begin);
  91.174 +		}
  91.175 +
  91.176 +		// use this information to construct a very rudimentary 
  91.177 +		// parse-tree representing the FBX scope structure
  91.178 +		Parser parser(tokens, is_binary);
  91.179 +
  91.180 +		// take the raw parse-tree and convert it to a FBX DOM
  91.181 +		Document doc(parser,settings);
  91.182 +
  91.183 +		// convert the FBX DOM to aiScene
  91.184 +		ConvertToAssimpScene(pScene,doc);
  91.185 +	}
  91.186 +	catch(std::exception&) {
  91.187 +		std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
  91.188 +		throw;
  91.189 +	}
  91.190 +}
  91.191 +
  91.192 +#endif // !ASSIMP_BUILD_NO_FBX_IMPORTER
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/libs/assimp/FBXImporter.h	Sat Feb 01 19:58:19 2014 +0200
    92.3 @@ -0,0 +1,107 @@
    92.4 +/*
    92.5 +Open Asset Import Library (assimp)
    92.6 +----------------------------------------------------------------------
    92.7 +
    92.8 +Copyright (c) 2006-2012, assimp team
    92.9 +All rights reserved.
   92.10 +
   92.11 +Redistribution and use of this software in source and binary forms, 
   92.12 +with or without modification, are permitted provided that the 
   92.13 +following conditions are met:
   92.14 +
   92.15 +* Redistributions of source code must retain the above
   92.16 +  copyright notice, this list of conditions and the
   92.17 +  following disclaimer.
   92.18 +
   92.19 +* Redistributions in binary form must reproduce the above
   92.20 +  copyright notice, this list of conditions and the
   92.21 +  following disclaimer in the documentation and/or other
   92.22 +  materials provided with the distribution.
   92.23 +
   92.24 +* Neither the name of the assimp team, nor the names of its
   92.25 +  contributors may be used to endorse or promote products
   92.26 +  derived from this software without specific prior
   92.27 +  written permission of the assimp team.
   92.28 +
   92.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   92.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   92.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   92.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   92.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   92.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   92.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   92.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   92.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   92.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   92.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   92.40 +
   92.41 +----------------------------------------------------------------------
   92.42 +*/
   92.43 +
   92.44 +/** @file  FBXImporter.h
   92.45 + *  @brief Declaration of the FBX main importer class
   92.46 + */
   92.47 +#ifndef INCLUDED_AI_FBX_IMPORTER_H
   92.48 +#define INCLUDED_AI_FBX_IMPORTER_H
   92.49 +
   92.50 +#include "BaseImporter.h"
   92.51 +#include "LogAux.h"
   92.52 +
   92.53 +#include "FBXImportSettings.h"
   92.54 +
   92.55 +namespace Assimp	{
   92.56 +	
   92.57 +	// TinyFormatter.h
   92.58 +	namespace Formatter {
   92.59 +		template <typename T,typename TR, typename A> class basic_formatter;
   92.60 +		typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
   92.61 +	}
   92.62 +
   92.63 +
   92.64 +// -------------------------------------------------------------------------------------------
   92.65 +/** Load the Autodesk FBX file format.
   92.66 +
   92.67 + See http://en.wikipedia.org/wiki/FBX
   92.68 +*/
   92.69 +// -------------------------------------------------------------------------------------------
   92.70 +class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter>
   92.71 +{
   92.72 +public:
   92.73 +	FBXImporter();
   92.74 +	~FBXImporter();
   92.75 +
   92.76 +
   92.77 +public:
   92.78 +
   92.79 +	// --------------------
   92.80 +	bool CanRead( const std::string& pFile, 
   92.81 +		IOSystem* pIOHandler,
   92.82 +		bool checkSig
   92.83 +	) const;
   92.84 +
   92.85 +protected:
   92.86 +
   92.87 +	// --------------------
   92.88 +	const aiImporterDesc* GetInfo () const;
   92.89 +
   92.90 +	// --------------------
   92.91 +	void SetupProperties(const Importer* pImp);
   92.92 +
   92.93 +	// --------------------
   92.94 +	void InternReadFile( const std::string& pFile, 
   92.95 +		aiScene* pScene, 
   92.96 +		IOSystem* pIOHandler
   92.97 +	);
   92.98 +
   92.99 +private:
  92.100 +
  92.101 +	
  92.102 +private:
  92.103 +
  92.104 +	FBX::ImportSettings settings;
  92.105 +
  92.106 +}; // !class FBXImporter
  92.107 +
  92.108 +} // end of namespace Assimp
  92.109 +#endif // !INCLUDED_AI_FBX_IMPORTER_H
  92.110 +
    93.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.2 +++ b/libs/assimp/FBXMaterial.cpp	Sat Feb 01 19:58:19 2014 +0200
    93.3 @@ -0,0 +1,200 @@
    93.4 +/*
    93.5 +Open Asset Import Library (assimp)
    93.6 +----------------------------------------------------------------------
    93.7 +
    93.8 +Copyright (c) 2006-2012, assimp team
    93.9 +All rights reserved.
   93.10 +
   93.11 +Redistribution and use of this software in source and binary forms, 
   93.12 +with or without modification, are permitted provided that the 
   93.13 +following conditions are met:
   93.14 +
   93.15 +* Redistributions of source code must retain the above
   93.16 +  copyright notice, this list of conditions and the
   93.17 +  following disclaimer.
   93.18 +
   93.19 +* Redistributions in binary form must reproduce the above
   93.20 +  copyright notice, this list of conditions and the
   93.21 +  following disclaimer in the documentation and/or other
   93.22 +  materials provided with the distribution.
   93.23 +
   93.24 +* Neither the name of the assimp team, nor the names of its
   93.25 +  contributors may be used to endorse or promote products
   93.26 +  derived from this software without specific prior
   93.27 +  written permission of the assimp team.
   93.28 +
   93.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   93.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   93.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   93.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   93.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   93.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   93.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   93.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   93.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   93.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   93.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   93.40 +
   93.41 +----------------------------------------------------------------------
   93.42 +*/
   93.43 +
   93.44 +/** @file  FBXMaterial.cpp
   93.45 + *  @brief Assimp::FBX::Material and Assimp::FBX::Texture implementation
   93.46 + */
   93.47 +#include "AssimpPCH.h"
   93.48 +
   93.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   93.50 +
   93.51 +#include "FBXParser.h"
   93.52 +#include "FBXDocument.h"
   93.53 +#include "FBXImporter.h"
   93.54 +#include "FBXImportSettings.h"
   93.55 +#include "FBXDocumentUtil.h"
   93.56 +#include "FBXProperties.h"
   93.57 +
   93.58 +namespace Assimp {
   93.59 +namespace FBX {
   93.60 +
   93.61 +	using namespace Util;
   93.62 +
   93.63 +// ------------------------------------------------------------------------------------------------
   93.64 +Material::Material(uint64_t id, const Element& element, const Document& doc, const std::string& name)
   93.65 +: Object(id,element,name)
   93.66 +{
   93.67 +	const Scope& sc = GetRequiredScope(element);
   93.68 +	
   93.69 +	const Element* const ShadingModel = sc["ShadingModel"];
   93.70 +	const Element* const MultiLayer = sc["MultiLayer"];
   93.71 +
   93.72 +	if(MultiLayer) {
   93.73 +		multilayer = !!ParseTokenAsInt(GetRequiredToken(*MultiLayer,0));
   93.74 +	}
   93.75 +
   93.76 +	if(ShadingModel) {
   93.77 +		shading = ParseTokenAsString(GetRequiredToken(*ShadingModel,0));
   93.78 +	}
   93.79 +	else {
   93.80 +		DOMWarning("shading mode not specified, assuming phong",&element);
   93.81 +		shading = "phong";
   93.82 +	}
   93.83 +
   93.84 +	std::string templateName;
   93.85 +
   93.86 +	const char* const sh = shading.c_str();
   93.87 +	if(!strcmp(sh,"phong")) {
   93.88 +		templateName = "Material.FbxSurfacePhong";
   93.89 +	}
   93.90 +	else if(!strcmp(sh,"lambert")) {
   93.91 +		templateName = "Material.FbxSurfaceLambert";
   93.92 +	}
   93.93 +	else {
   93.94 +		DOMWarning("shading mode not recognized: " + shading,&element);
   93.95 +	}
   93.96 +
   93.97 +	props = GetPropertyTable(doc,templateName,element,sc);
   93.98 +
   93.99 +	// resolve texture links
  93.100 +	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
  93.101 +	BOOST_FOREACH(const Connection* con, conns) {
  93.102 +
  93.103 +		// texture link to properties, not objects
  93.104 +		if (!con->PropertyName().length()) {
  93.105 +			continue;
  93.106 +		}
  93.107 +
  93.108 +		const Object* const ob = con->SourceObject();
  93.109 +		if(!ob) {
  93.110 +			DOMWarning("failed to read source object for texture link, ignoring",&element);
  93.111 +			continue;
  93.112 +		}
  93.113 +
  93.114 +		const Texture* const tex = dynamic_cast<const Texture*>(ob);
  93.115 +		if(!tex) {
  93.116 +			DOMWarning("source object for texture link is not a texture, ignoring",&element);
  93.117 +			continue;
  93.118 +		}
  93.119 +
  93.120 +		const std::string& prop = con->PropertyName();
  93.121 +		if (textures.find(prop) != textures.end()) {
  93.122 +			DOMWarning("duplicate texture link: " + prop,&element);
  93.123 +		}
  93.124 +
  93.125 +		textures[prop] = tex;
  93.126 +	}
  93.127 +}
  93.128 +
  93.129 +
  93.130 +// ------------------------------------------------------------------------------------------------
  93.131 +Material::~Material()
  93.132 +{
  93.133 +}
  93.134 +
  93.135 +
  93.136 +// ------------------------------------------------------------------------------------------------
  93.137 +Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name)
  93.138 +: Object(id,element,name)
  93.139 +, uvScaling(1.0f,1.0f)
  93.140 +{
  93.141 +	const Scope& sc = GetRequiredScope(element);
  93.142 +
  93.143 +	const Element* const Type = sc["Type"];
  93.144 +	const Element* const FileName = sc["FileName"];
  93.145 +	const Element* const RelativeFilename = sc["RelativeFilename"];
  93.146 +	const Element* const ModelUVTranslation = sc["ModelUVTranslation"];
  93.147 +	const Element* const ModelUVScaling = sc["ModelUVScaling"];
  93.148 +	const Element* const Texture_Alpha_Source = sc["Texture_Alpha_Source"];
  93.149 +	const Element* const Cropping = sc["Cropping"];
  93.150 +
  93.151 +	if(Type) {
  93.152 +		type = ParseTokenAsString(GetRequiredToken(*Type,0));
  93.153 +	}
  93.154 +
  93.155 +	if(FileName) {
  93.156 +		fileName = ParseTokenAsString(GetRequiredToken(*FileName,0));
  93.157 +	}
  93.158 +
  93.159 +	if(RelativeFilename) {
  93.160 +		relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0));
  93.161 +	}
  93.162 +
  93.163 +	if(ModelUVTranslation) {
  93.164 +		uvTrans = aiVector2D(ParseTokenAsFloat(GetRequiredToken(*ModelUVTranslation,0)),
  93.165 +			ParseTokenAsFloat(GetRequiredToken(*ModelUVTranslation,1))
  93.166 +		);
  93.167 +	}
  93.168 +
  93.169 +	if(ModelUVScaling) {
  93.170 +		uvScaling = aiVector2D(ParseTokenAsFloat(GetRequiredToken(*ModelUVScaling,0)),
  93.171 +			ParseTokenAsFloat(GetRequiredToken(*ModelUVScaling,1))
  93.172 +		);
  93.173 +	}
  93.174 +
  93.175 +	if(Cropping) {
  93.176 +		crop[0] = ParseTokenAsInt(GetRequiredToken(*Cropping,0));
  93.177 +		crop[1] = ParseTokenAsInt(GetRequiredToken(*Cropping,1));
  93.178 +		crop[2] = ParseTokenAsInt(GetRequiredToken(*Cropping,2));
  93.179 +		crop[3] = ParseTokenAsInt(GetRequiredToken(*Cropping,3));
  93.180 +	}
  93.181 +	else {
  93.182 +		// vc8 doesn't support the crop() syntax in initialization lists
  93.183 +		// (and vc9 WARNS about the new (i.e. compliant) behaviour).
  93.184 +		crop[0] = crop[1] = crop[2] = crop[3] = 0;
  93.185 +	}
  93.186 +
  93.187 +	if(Texture_Alpha_Source) {
  93.188 +		alphaSource = ParseTokenAsString(GetRequiredToken(*Texture_Alpha_Source,0));
  93.189 +	}
  93.190 +
  93.191 +	props = GetPropertyTable(doc,"Texture.FbxFileTexture",element,sc);
  93.192 +}
  93.193 +
  93.194 +
  93.195 +Texture::~Texture()
  93.196 +{
  93.197 +
  93.198 +}
  93.199 +
  93.200 +} //!FBX
  93.201 +} //!Assimp
  93.202 +
  93.203 +#endif
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/libs/assimp/FBXMeshGeometry.cpp	Sat Feb 01 19:58:19 2014 +0200
    94.3 @@ -0,0 +1,540 @@
    94.4 +/*
    94.5 +Open Asset Import Library (assimp)
    94.6 +----------------------------------------------------------------------
    94.7 +
    94.8 +Copyright (c) 2006-2012, assimp team
    94.9 +All rights reserved.
   94.10 +
   94.11 +Redistribution and use of this software in source and binary forms, 
   94.12 +with or without modification, are permitted provided that the 
   94.13 +following conditions are met:
   94.14 +
   94.15 +* Redistributions of source code must retain the above
   94.16 +  copyright notice, this list of conditions and the
   94.17 +  following disclaimer.
   94.18 +
   94.19 +* Redistributions in binary form must reproduce the above
   94.20 +  copyright notice, this list of conditions and the
   94.21 +  following disclaimer in the documentation and/or other
   94.22 +  materials provided with the distribution.
   94.23 +
   94.24 +* Neither the name of the assimp team, nor the names of its
   94.25 +  contributors may be used to endorse or promote products
   94.26 +  derived from this software without specific prior
   94.27 +  written permission of the assimp team.
   94.28 +
   94.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   94.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   94.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   94.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   94.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   94.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   94.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   94.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   94.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   94.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   94.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   94.40 +
   94.41 +----------------------------------------------------------------------
   94.42 +*/
   94.43 +
   94.44 +/** @file  FBXMeshGeometry.cpp
   94.45 + *  @brief Assimp::FBX::MeshGeometry implementation
   94.46 + */
   94.47 +#include "AssimpPCH.h"
   94.48 +
   94.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   94.50 +
   94.51 +#include <functional>
   94.52 +
   94.53 +#include "FBXParser.h"
   94.54 +#include "FBXDocument.h"
   94.55 +#include "FBXImporter.h"
   94.56 +#include "FBXImportSettings.h"
   94.57 +#include "FBXDocumentUtil.h"
   94.58 +
   94.59 +
   94.60 +namespace Assimp {
   94.61 +namespace FBX {
   94.62 +
   94.63 +	using namespace Util;
   94.64 +
   94.65 +
   94.66 +// ------------------------------------------------------------------------------------------------
   94.67 +Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
   94.68 +	: Object(id, element,name)
   94.69 +	, skin()
   94.70 +{
   94.71 +	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
   94.72 +	BOOST_FOREACH(const Connection* con, conns) {
   94.73 +		const Skin* const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element);
   94.74 +		if(sk) {
   94.75 +			skin = sk;
   94.76 +			break;
   94.77 +		}
   94.78 +	}
   94.79 +}
   94.80 +
   94.81 +
   94.82 +// ------------------------------------------------------------------------------------------------
   94.83 +Geometry::~Geometry()
   94.84 +{
   94.85 +
   94.86 +}
   94.87 +
   94.88 +
   94.89 +
   94.90 +// ------------------------------------------------------------------------------------------------
   94.91 +MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
   94.92 +: Geometry(id, element,name, doc)
   94.93 +{
   94.94 +	const Scope* sc = element.Compound();
   94.95 +	if (!sc) {
   94.96 +		DOMError("failed to read Geometry object (class: Mesh), no data scope found");
   94.97 +	}
   94.98 +
   94.99 +	// must have Mesh elements:
  94.100 +	const Element& Vertices = GetRequiredElement(*sc,"Vertices",&element);
  94.101 +	const Element& PolygonVertexIndex = GetRequiredElement(*sc,"PolygonVertexIndex",&element);
  94.102 +
  94.103 +	// optional Mesh elements:
  94.104 +	const ElementCollection& Layer = sc->GetCollection("Layer");
  94.105 +
  94.106 +	std::vector<aiVector3D> tempVerts;
  94.107 +	ParseVectorDataArray(tempVerts,Vertices);
  94.108 +
  94.109 +	if(tempVerts.empty()) {
  94.110 +		FBXImporter::LogWarn("encountered mesh with no vertices");
  94.111 +		return;
  94.112 +	}
  94.113 +
  94.114 +	std::vector<int> tempFaces;
  94.115 +	ParseVectorDataArray(tempFaces,PolygonVertexIndex);
  94.116 +
  94.117 +	if(tempFaces.empty()) {
  94.118 +		FBXImporter::LogWarn("encountered mesh with no faces");
  94.119 +		return;
  94.120 +	}
  94.121 +
  94.122 +	vertices.reserve(tempFaces.size());
  94.123 +	faces.reserve(tempFaces.size() / 3);
  94.124 +
  94.125 +	mapping_offsets.resize(tempVerts.size());
  94.126 +	mapping_counts.resize(tempVerts.size(),0);
  94.127 +	mappings.resize(tempFaces.size());
  94.128 +
  94.129 +	const size_t vertex_count = tempVerts.size();
  94.130 +
  94.131 +	// generate output vertices, computing an adjacency table to
  94.132 +	// preserve the mapping from fbx indices to *this* indexing.
  94.133 +	unsigned int count = 0;
  94.134 +	BOOST_FOREACH(int index, tempFaces) {
  94.135 +		const int absi = index < 0 ? (-index - 1) : index;
  94.136 +		if(static_cast<size_t>(absi) >= vertex_count) {
  94.137 +			DOMError("polygon vertex index out of range",&PolygonVertexIndex);
  94.138 +		}
  94.139 +
  94.140 +		vertices.push_back(tempVerts[absi]);
  94.141 +		++count;
  94.142 +
  94.143 +		++mapping_counts[absi];
  94.144 +
  94.145 +		if (index < 0) {
  94.146 +			faces.push_back(count);
  94.147 +			count = 0;
  94.148 +		}
  94.149 +	}
  94.150 +
  94.151 +	unsigned int cursor = 0;
  94.152 +	for (size_t i = 0, e = tempVerts.size(); i < e; ++i) {
  94.153 +		mapping_offsets[i] = cursor;
  94.154 +		cursor += mapping_counts[i];
  94.155 +
  94.156 +		mapping_counts[i] = 0;
  94.157 +	}
  94.158 +
  94.159 +	cursor = 0;
  94.160 +	BOOST_FOREACH(int index, tempFaces) {
  94.161 +		const int absi = index < 0 ? (-index - 1) : index;
  94.162 +		mappings[mapping_offsets[absi] + mapping_counts[absi]++] = cursor++;
  94.163 +	}
  94.164 +	
  94.165 +	// if settings.readAllLayers is true:
  94.166 +	//  * read all layers, try to load as many vertex channels as possible
  94.167 +	// if settings.readAllLayers is false:
  94.168 +	//  * read only the layer with index 0, but warn about any further layers 
  94.169 +	for (ElementMap::const_iterator it = Layer.first; it != Layer.second; ++it) {
  94.170 +		const TokenList& tokens = (*it).second->Tokens();
  94.171 +
  94.172 +		const char* err;
  94.173 +		const int index = ParseTokenAsInt(*tokens[0], err);
  94.174 +		if(err) {
  94.175 +			DOMError(err,&element);
  94.176 +		}
  94.177 +
  94.178 +		if(doc.Settings().readAllLayers || index == 0) {
  94.179 +			const Scope& layer = GetRequiredScope(*(*it).second);
  94.180 +			ReadLayer(layer);
  94.181 +		}
  94.182 +		else {
  94.183 +			FBXImporter::LogWarn("ignoring additional geometry layers");
  94.184 +		}
  94.185 +	}
  94.186 +}
  94.187 +
  94.188 +
  94.189 +// ------------------------------------------------------------------------------------------------
  94.190 +MeshGeometry::~MeshGeometry()
  94.191 +{
  94.192 +
  94.193 +}
  94.194 +
  94.195 +
  94.196 +
  94.197 +// ------------------------------------------------------------------------------------------------
  94.198 +void MeshGeometry::ReadLayer(const Scope& layer)
  94.199 +{
  94.200 +	const ElementCollection& LayerElement = layer.GetCollection("LayerElement");
  94.201 +	for (ElementMap::const_iterator eit = LayerElement.first; eit != LayerElement.second; ++eit) {
  94.202 +		const Scope& elayer = GetRequiredScope(*(*eit).second);
  94.203 +
  94.204 +		ReadLayerElement(elayer);
  94.205 +	}
  94.206 +}
  94.207 +
  94.208 +
  94.209 +// ------------------------------------------------------------------------------------------------
  94.210 +void MeshGeometry::ReadLayerElement(const Scope& layerElement)
  94.211 +{
  94.212 +	const Element& Type = GetRequiredElement(layerElement,"Type");
  94.213 +	const Element& TypedIndex = GetRequiredElement(layerElement,"TypedIndex");
  94.214 +
  94.215 +	const std::string& type = ParseTokenAsString(GetRequiredToken(Type,0));
  94.216 +	const int typedIndex = ParseTokenAsInt(GetRequiredToken(TypedIndex,0));
  94.217 +
  94.218 +	const Scope& top = GetRequiredScope(element);
  94.219 +	const ElementCollection candidates = top.GetCollection(type);
  94.220 +
  94.221 +	for (ElementMap::const_iterator it = candidates.first; it != candidates.second; ++it) {
  94.222 +		const int index = ParseTokenAsInt(GetRequiredToken(*(*it).second,0));
  94.223 +		if(index == typedIndex) {
  94.224 +			ReadVertexData(type,typedIndex,GetRequiredScope(*(*it).second));
  94.225 +			return;
  94.226 +		}
  94.227 +	}
  94.228 +
  94.229 +	FBXImporter::LogError(Formatter::format("failed to resolve vertex layer element: ") 
  94.230 +		<< type << ", index: " << typedIndex);
  94.231 +}
  94.232 +
  94.233 +
  94.234 +// ------------------------------------------------------------------------------------------------
  94.235 +void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scope& source)
  94.236 +{
  94.237 +	const std::string& MappingInformationType = ParseTokenAsString(GetRequiredToken(
  94.238 +		GetRequiredElement(source,"MappingInformationType"),0)
  94.239 +	);
  94.240 +
  94.241 +	const std::string& ReferenceInformationType = ParseTokenAsString(GetRequiredToken(
  94.242 +		GetRequiredElement(source,"ReferenceInformationType"),0)
  94.243 +	);
  94.244 +	
  94.245 +	if (type == "LayerElementUV") {
  94.246 +		if(index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
  94.247 +			FBXImporter::LogError(Formatter::format("ignoring UV layer, maximum number of UV channels exceeded: ") 
  94.248 +				<< index << " (limit is " << AI_MAX_NUMBER_OF_TEXTURECOORDS << ")" );
  94.249 +			return;
  94.250 +		}
  94.251 +
  94.252 +		const Element* Name = source["Name"];
  94.253 +		uvNames[index] = "";
  94.254 +		if(Name) {
  94.255 +			uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0));
  94.256 +		}
  94.257 +
  94.258 +		ReadVertexDataUV(uvs[index],source,
  94.259 +			MappingInformationType,
  94.260 +			ReferenceInformationType
  94.261 +		);
  94.262 +	}
  94.263 +	else if (type == "LayerElementMaterial") {
  94.264 +		if (materials.size() > 0) {
  94.265 +			FBXImporter::LogError("ignoring additional material layer");
  94.266 +			return;
  94.267 +		}
  94.268 +
  94.269 +		std::vector<int> temp_materials;
  94.270 +
  94.271 +		ReadVertexDataMaterials(temp_materials,source,
  94.272 +			MappingInformationType,
  94.273 +			ReferenceInformationType
  94.274 +		);
  94.275 +
  94.276 +		// sometimes, there will be only negative entries. Drop the material
  94.277 +		// layer in such a case (I guess it means a default material should
  94.278 +		// be used). This is what the converter would do anyway, and it
  94.279 +		// avoids loosing the material if there are more material layers
  94.280 +		// coming of which at least one contains actual data (did observe
  94.281 +		// that with one test file).
  94.282 +		const size_t count_neg = std::count_if(temp_materials.begin(),temp_materials.end(),std::bind2nd(std::less<int>(),0));
  94.283 +		if(count_neg == temp_materials.size()) {
  94.284 +			FBXImporter::LogWarn("ignoring dummy material layer (all entries -1)");
  94.285 +			return;
  94.286 +		}
  94.287 +
  94.288 +		std::swap(temp_materials, materials);
  94.289 +	}
  94.290 +	else if (type == "LayerElementNormal") {
  94.291 +		if (normals.size() > 0) {
  94.292 +			FBXImporter::LogError("ignoring additional normal layer");
  94.293 +			return;
  94.294 +		}
  94.295 +
  94.296 +		ReadVertexDataNormals(normals,source,
  94.297 +			MappingInformationType,
  94.298 +			ReferenceInformationType
  94.299 +		);
  94.300 +	}
  94.301 +	else if (type == "LayerElementTangent") {
  94.302 +		if (tangents.size() > 0) {
  94.303 +			FBXImporter::LogError("ignoring additional tangent layer");
  94.304 +			return;
  94.305 +		}
  94.306 +
  94.307 +		ReadVertexDataTangents(tangents,source,
  94.308 +			MappingInformationType,
  94.309 +			ReferenceInformationType
  94.310 +		);
  94.311 +	}
  94.312 +	else if (type == "LayerElementBinormal") {
  94.313 +		if (binormals.size() > 0) {
  94.314 +			FBXImporter::LogError("ignoring additional binormal layer");
  94.315 +			return;
  94.316 +		}
  94.317 +
  94.318 +		ReadVertexDataBinormals(binormals,source,
  94.319 +			MappingInformationType,
  94.320 +			ReferenceInformationType
  94.321 +		);
  94.322 +	}
  94.323 +	else if (type == "LayerElementColor") {
  94.324 +		if(index >= AI_MAX_NUMBER_OF_COLOR_SETS) {
  94.325 +			FBXImporter::LogError(Formatter::format("ignoring vertex color layer, maximum number of color sets exceeded: ") 
  94.326 +				<< index << " (limit is " << AI_MAX_NUMBER_OF_COLOR_SETS << ")" );
  94.327 +			return;
  94.328 +		}
  94.329 +
  94.330 +		ReadVertexDataColors(colors[index],source,
  94.331 +			MappingInformationType,
  94.332 +			ReferenceInformationType
  94.333 +		);
  94.334 +	}
  94.335 +}
  94.336 +
  94.337 +
  94.338 +// ------------------------------------------------------------------------------------------------
  94.339 +// Lengthy utility function to read and resolve a FBX vertex data array - that is, the
  94.340 +// output is in polygon vertex order. This logic is used for reading normals, UVs, colors,
  94.341 +// tangents ..
  94.342 +template <typename T>
  94.343 +void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source, 
  94.344 +	const std::string& MappingInformationType,
  94.345 +	const std::string& ReferenceInformationType,
  94.346 +	const char* dataElementName,
  94.347 +	const char* indexDataElementName,
  94.348 +	size_t vertex_count,
  94.349 +	const std::vector<unsigned int>& mapping_counts,
  94.350 +	const std::vector<unsigned int>& mapping_offsets,
  94.351 +	const std::vector<unsigned int>& mappings)
  94.352 +{
  94.353 +	std::vector<T> tempUV;
  94.354 +	ParseVectorDataArray(tempUV,GetRequiredElement(source,dataElementName));
  94.355 +
  94.356 +	// handle permutations of Mapping and Reference type - it would be nice to
  94.357 +	// deal with this more elegantly and with less redundancy, but right
  94.358 +	// now it seems unavoidable.
  94.359 +	if (MappingInformationType == "ByVertice" && ReferenceInformationType == "Direct") {	
  94.360 +		data_out.resize(vertex_count);
  94.361 +		for (size_t i = 0, e = tempUV.size(); i < e; ++i) {
  94.362 +
  94.363 +			const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i];
  94.364 +			for (unsigned int j = istart; j < iend; ++j) {
  94.365 +				data_out[mappings[j]] = tempUV[i];
  94.366 +			}
  94.367 +		}
  94.368 +	}
  94.369 +	else if (MappingInformationType == "ByVertice" && ReferenceInformationType == "IndexToDirect") {	
  94.370 +		data_out.resize(vertex_count);
  94.371 +
  94.372 +		std::vector<int> uvIndices;
  94.373 +		ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
  94.374 +
  94.375 +		for (size_t i = 0, e = uvIndices.size(); i < e; ++i) {
  94.376 +
  94.377 +			const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i];
  94.378 +			for (unsigned int j = istart; j < iend; ++j) {
  94.379 +				if(static_cast<size_t>(uvIndices[i]) >= tempUV.size()) {
  94.380 +					DOMError("index out of range",&GetRequiredElement(source,indexDataElementName));
  94.381 +				}
  94.382 +				data_out[mappings[j]] = tempUV[uvIndices[i]];
  94.383 +			}
  94.384 +		}
  94.385 +	}
  94.386 +	else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "Direct") {	
  94.387 +		if (tempUV.size() != vertex_count) {
  94.388 +			FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") 
  94.389 +				<< tempUV.size() << ", expected " << vertex_count
  94.390 +			);
  94.391 +			return;
  94.392 +		}
  94.393 +
  94.394 +		data_out.swap(tempUV);
  94.395 +	}
  94.396 +	else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "IndexToDirect") {	
  94.397 +		data_out.resize(vertex_count);
  94.398 +
  94.399 +		std::vector<int> uvIndices;
  94.400 +		ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
  94.401 +
  94.402 +		if (uvIndices.size() != vertex_count) {
  94.403 +			FBXImporter::LogError("length of input data unexpected for ByPolygonVertex mapping");
  94.404 +			return;
  94.405 +		}
  94.406 +
  94.407 +		unsigned int next = 0;
  94.408 +		BOOST_FOREACH(int i, uvIndices) {
  94.409 +			if(static_cast<size_t>(i) >= tempUV.size()) {
  94.410 +				DOMError("index out of range",&GetRequiredElement(source,indexDataElementName));
  94.411 +			}
  94.412 +
  94.413 +			data_out[next++] = tempUV[i];
  94.414 +		}
  94.415 +	}
  94.416 +	else {
  94.417 +		FBXImporter::LogError(Formatter::format("ignoring vertex data channel, access type not implemented: ") 
  94.418 +			<< MappingInformationType << "," << ReferenceInformationType);
  94.419 +	}
  94.420 +}
  94.421 +
  94.422 +// ------------------------------------------------------------------------------------------------
  94.423 +void MeshGeometry::ReadVertexDataNormals(std::vector<aiVector3D>& normals_out, const Scope& source, 
  94.424 +	const std::string& MappingInformationType,
  94.425 +	const std::string& ReferenceInformationType)
  94.426 +{
  94.427 +	ResolveVertexDataArray(normals_out,source,MappingInformationType,ReferenceInformationType,
  94.428 +		"Normals",
  94.429 +		"NormalsIndex",
  94.430 +		vertices.size(),
  94.431 +		mapping_counts,
  94.432 +		mapping_offsets,
  94.433 +		mappings);
  94.434 +}
  94.435 +
  94.436 +
  94.437 +// ------------------------------------------------------------------------------------------------
  94.438 +void MeshGeometry::ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope& source, 
  94.439 +	const std::string& MappingInformationType,
  94.440 +	const std::string& ReferenceInformationType)
  94.441 +{
  94.442 +	ResolveVertexDataArray(uv_out,source,MappingInformationType,ReferenceInformationType,
  94.443 +		"UV",
  94.444 +		"UVIndex",
  94.445 +		vertices.size(),
  94.446 +		mapping_counts,
  94.447 +		mapping_offsets,
  94.448 +		mappings);
  94.449 +}
  94.450 +
  94.451 +
  94.452 +// ------------------------------------------------------------------------------------------------
  94.453 +void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D>& colors_out, const Scope& source, 
  94.454 +	const std::string& MappingInformationType,
  94.455 +	const std::string& ReferenceInformationType)
  94.456 +{
  94.457 +	ResolveVertexDataArray(colors_out,source,MappingInformationType,ReferenceInformationType,
  94.458 +		"Colors",
  94.459 +		"ColorIndex",
  94.460 +		vertices.size(),
  94.461 +		mapping_counts,
  94.462 +		mapping_offsets,
  94.463 +		mappings);
  94.464 +}
  94.465 +
  94.466 +
  94.467 +// ------------------------------------------------------------------------------------------------
  94.468 +void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source, 
  94.469 +	const std::string& MappingInformationType,
  94.470 +	const std::string& ReferenceInformationType)
  94.471 +{
  94.472 +	ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
  94.473 +		"Tangent",
  94.474 +		"TangentIndex",
  94.475 +		vertices.size(),
  94.476 +		mapping_counts,
  94.477 +		mapping_offsets,
  94.478 +		mappings);
  94.479 +}
  94.480 +
  94.481 +
  94.482 +// ------------------------------------------------------------------------------------------------
  94.483 +void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source, 
  94.484 +	const std::string& MappingInformationType,
  94.485 +	const std::string& ReferenceInformationType)
  94.486 +{
  94.487 +	ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType,
  94.488 +		"Binormal",
  94.489 +		"BinormalIndex",
  94.490 +		vertices.size(),
  94.491 +		mapping_counts,
  94.492 +		mapping_offsets,
  94.493 +		mappings);
  94.494 +}
  94.495 +
  94.496 +
  94.497 +// ------------------------------------------------------------------------------------------------
  94.498 +void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, const Scope& source, 
  94.499 +	const std::string& MappingInformationType,
  94.500 +	const std::string& ReferenceInformationType)
  94.501 +{
  94.502 +	const size_t face_count = faces.size();
  94.503 +	ai_assert(face_count);
  94.504 +
  94.505 +	// materials are handled separately. First of all, they are assigned per-face
  94.506 +	// and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect
  94.507 +	// has a slightly different meaning for materials.
  94.508 +	ParseVectorDataArray(materials_out,GetRequiredElement(source,"Materials"));
  94.509 +
  94.510 +	if (MappingInformationType == "AllSame") {
  94.511 +		// easy - same material for all faces
  94.512 +		if (materials_out.empty()) {
  94.513 +			FBXImporter::LogError(Formatter::format("expected material index, ignoring"));
  94.514 +			return;
  94.515 +		}
  94.516 +		else if (materials_out.size() > 1) {
  94.517 +			FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one"));
  94.518 +			materials_out.clear();
  94.519 +		}
  94.520 + 
  94.521 +		materials.assign(vertices.size(),materials_out[0]);
  94.522 +	}
  94.523 +	else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
  94.524 +		materials.resize(face_count);
  94.525 +
  94.526 +		if(materials_out.size() != face_count) {
  94.527 +			FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") 
  94.528 +				<< materials_out.size() << ", expected " << face_count
  94.529 +			);
  94.530 +			return;
  94.531 +		}
  94.532 +	}
  94.533 +	else {
  94.534 +		FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ") 
  94.535 +			<< MappingInformationType << "," << ReferenceInformationType);
  94.536 +	}
  94.537 +}
  94.538 +
  94.539 +} // !FBX
  94.540 +} // !Assimp
  94.541 +
  94.542 +#endif
  94.543 +
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/libs/assimp/FBXModel.cpp	Sat Feb 01 19:58:19 2014 +0200
    95.3 @@ -0,0 +1,156 @@
    95.4 +/*
    95.5 +Open Asset Import Library (assimp)
    95.6 +----------------------------------------------------------------------
    95.7 +
    95.8 +Copyright (c) 2006-2012, assimp team
    95.9 +All rights reserved.
   95.10 +
   95.11 +Redistribution and use of this software in source and binary forms, 
   95.12 +with or without modification, are permitted provided that the 
   95.13 +following conditions are met:
   95.14 +
   95.15 +* Redistributions of source code must retain the above
   95.16 +  copyright notice, this list of conditions and the
   95.17 +  following disclaimer.
   95.18 +
   95.19 +* Redistributions in binary form must reproduce the above
   95.20 +  copyright notice, this list of conditions and the
   95.21 +  following disclaimer in the documentation and/or other
   95.22 +  materials provided with the distribution.
   95.23 +
   95.24 +* Neither the name of the assimp team, nor the names of its
   95.25 +  contributors may be used to endorse or promote products
   95.26 +  derived from this software without specific prior
   95.27 +  written permission of the assimp team.
   95.28 +
   95.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   95.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   95.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   95.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   95.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   95.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   95.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   95.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   95.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   95.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   95.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   95.40 +
   95.41 +----------------------------------------------------------------------
   95.42 +*/
   95.43 +
   95.44 +/** @file  FBXModel.cpp
   95.45 + *  @brief Assimp::FBX::Model implementation
   95.46 + */
   95.47 +#include "AssimpPCH.h"
   95.48 +
   95.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   95.50 +
   95.51 +#include "FBXParser.h"
   95.52 +#include "FBXDocument.h"
   95.53 +#include "FBXImporter.h"
   95.54 +#include "FBXImportSettings.h"
   95.55 +#include "FBXDocumentUtil.h"
   95.56 +#include "FBXProperties.h"
   95.57 +
   95.58 +namespace Assimp {
   95.59 +namespace FBX {
   95.60 +
   95.61 +	using namespace Util;
   95.62 +
   95.63 +// ------------------------------------------------------------------------------------------------
   95.64 +Model::Model(uint64_t id, const Element& element, const Document& doc, const std::string& name)
   95.65 +	: Object(id,element,name)
   95.66 +	, shading("Y")
   95.67 +{
   95.68 +	const Scope& sc = GetRequiredScope(element);
   95.69 +	const Element* const Shading = sc["Shading"];
   95.70 +	const Element* const Culling = sc["Culling"];
   95.71 +
   95.72 +	if(Shading) {
   95.73 +		shading = GetRequiredToken(*Shading,0).StringContents();
   95.74 +	}
   95.75 +
   95.76 +	if (Culling) {
   95.77 +		culling = ParseTokenAsString(GetRequiredToken(*Culling,0));
   95.78 +	}
   95.79 +
   95.80 +	props = GetPropertyTable(doc,"Model.FbxNode",element,sc);
   95.81 +	ResolveLinks(element,doc);
   95.82 +}
   95.83 +
   95.84 +
   95.85 +// ------------------------------------------------------------------------------------------------
   95.86 +Model::~Model()
   95.87 +{
   95.88 +
   95.89 +}
   95.90 +
   95.91 +
   95.92 +// ------------------------------------------------------------------------------------------------
   95.93 +void Model::ResolveLinks(const Element& element, const Document& doc)
   95.94 +{
   95.95 +	const char* const arr[] = {"Geometry","Material","NodeAttribute"};
   95.96 +
   95.97 +	// resolve material
   95.98 +	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),arr, 3);
   95.99 +
  95.100 +	materials.reserve(conns.size());
  95.101 +	geometry.reserve(conns.size());
  95.102 +	attributes.reserve(conns.size());
  95.103 +	BOOST_FOREACH(const Connection* con, conns) {
  95.104 +
  95.105 +		// material and geometry links should be Object-Object connections
  95.106 +		if (con->PropertyName().length()) {
  95.107 +			continue;
  95.108 +		}
  95.109 +
  95.110 +		const Object* const ob = con->SourceObject();
  95.111 +		if(!ob) {
  95.112 +			DOMWarning("failed to read source object for incoming Model link, ignoring",&element);
  95.113 +			continue;
  95.114 +		}
  95.115 +
  95.116 +		const Material* const mat = dynamic_cast<const Material*>(ob);
  95.117 +		if(mat) {
  95.118 +			materials.push_back(mat);
  95.119 +			continue;
  95.120 +		}
  95.121 +
  95.122 +		const Geometry* const geo = dynamic_cast<const Geometry*>(ob);
  95.123 +		if(geo) {
  95.124 +			geometry.push_back(geo);
  95.125 +			continue;
  95.126 +		}
  95.127 +
  95.128 +		const NodeAttribute* const att = dynamic_cast<const NodeAttribute*>(ob);
  95.129 +		if(att) {
  95.130 +			attributes.push_back(att);
  95.131 +			continue;
  95.132 +		}
  95.133 +
  95.134 +		DOMWarning("source object for model link is neither Material, NodeAttribute nor Geometry, ignoring",&element);
  95.135 +		continue;
  95.136 +	}
  95.137 +}
  95.138 +
  95.139 +
  95.140 +// ------------------------------------------------------------------------------------------------
  95.141 +bool Model::IsNull() const
  95.142 +{
  95.143 +	const std::vector<const NodeAttribute*>& attrs = GetAttributes();
  95.144 +	BOOST_FOREACH(const NodeAttribute* att, attrs) {
  95.145 +		
  95.146 +		const Null* null_tag = dynamic_cast<const Null*>(att);
  95.147 +		if(null_tag) {
  95.148 +			return true;
  95.149 +		}
  95.150 +	}
  95.151 +
  95.152 +	return false;
  95.153 +}
  95.154 +
  95.155 +
  95.156 +} //!FBX
  95.157 +} //!Assimp
  95.158 +
  95.159 +#endif
    96.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.2 +++ b/libs/assimp/FBXNodeAttribute.cpp	Sat Feb 01 19:58:19 2014 +0200
    96.3 @@ -0,0 +1,173 @@
    96.4 +/*
    96.5 +Open Asset Import Library (assimp)
    96.6 +----------------------------------------------------------------------
    96.7 +
    96.8 +Copyright (c) 2006-2012, assimp team
    96.9 +All rights reserved.
   96.10 +
   96.11 +Redistribution and use of this software in source and binary forms, 
   96.12 +with or without modification, are permitted provided that the 
   96.13 +following conditions are met:
   96.14 +
   96.15 +* Redistributions of source code must retain the above
   96.16 +  copyright notice, this list of conditions and the
   96.17 +  following disclaimer.
   96.18 +
   96.19 +* Redistributions in binary form must reproduce the above
   96.20 +  copyright notice, this list of conditions and the
   96.21 +  following disclaimer in the documentation and/or other
   96.22 +  materials provided with the distribution.
   96.23 +
   96.24 +* Neither the name of the assimp team, nor the names of its
   96.25 +  contributors may be used to endorse or promote products
   96.26 +  derived from this software without specific prior
   96.27 +  written permission of the assimp team.
   96.28 +
   96.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   96.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   96.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   96.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   96.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   96.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   96.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   96.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   96.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   96.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   96.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   96.40 +
   96.41 +----------------------------------------------------------------------
   96.42 +*/
   96.43 +
   96.44 +/** @file  FBXNoteAttribute.cpp
   96.45 + *  @brief Assimp::FBX::NodeAttribute (and subclasses) implementation
   96.46 + */
   96.47 +#include "AssimpPCH.h"
   96.48 +
   96.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   96.50 +
   96.51 +#include "FBXParser.h"
   96.52 +#include "FBXDocument.h"
   96.53 +#include "FBXImporter.h"
   96.54 +#include "FBXImportSettings.h"
   96.55 +#include "FBXDocumentUtil.h"
   96.56 +#include "FBXProperties.h"
   96.57 +
   96.58 +namespace Assimp {
   96.59 +namespace FBX {
   96.60 +
   96.61 +	using namespace Util;
   96.62 +
   96.63 +// ------------------------------------------------------------------------------------------------
   96.64 +NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name)
   96.65 +	: Object(id,element,name)
   96.66 +{
   96.67 +	const Scope& sc = GetRequiredScope(element);
   96.68 +
   96.69 +	const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2));
   96.70 +
   96.71 +	// hack on the deriving type but Null/LimbNode attributes are the only case in which
   96.72 +	// the property table is by design absent and no warning should be generated
   96.73 +	// for it.
   96.74 +	const bool is_null_or_limb = !strcmp(classname.c_str(), "Null") || !strcmp(classname.c_str(), "LimbNode");
   96.75 +	props = GetPropertyTable(doc,"NodeAttribute.Fbx" + classname,element,sc, is_null_or_limb);
   96.76 +}
   96.77 +
   96.78 +
   96.79 +// ------------------------------------------------------------------------------------------------
   96.80 +NodeAttribute::~NodeAttribute()
   96.81 +{
   96.82 +
   96.83 +}
   96.84 +
   96.85 +
   96.86 +// ------------------------------------------------------------------------------------------------
   96.87 +CameraSwitcher::CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name)
   96.88 +	: NodeAttribute(id,element,doc,name)
   96.89 +{
   96.90 +	const Scope& sc = GetRequiredScope(element);
   96.91 +	const Element* const CameraId = sc["CameraId"];
   96.92 +	const Element* const CameraName = sc["CameraName"];
   96.93 +	const Element* const CameraIndexName = sc["CameraIndexName"];
   96.94 +
   96.95 +	if(CameraId) {
   96.96 +		cameraId = ParseTokenAsInt(GetRequiredToken(*CameraId,0));
   96.97 +	}
   96.98 +
   96.99 +	if(CameraName) {
  96.100 +		cameraName = GetRequiredToken(*CameraName,0).StringContents();
  96.101 +	}
  96.102 +
  96.103 +	if(CameraIndexName && CameraIndexName->Tokens().size()) {
  96.104 +		cameraIndexName = GetRequiredToken(*CameraIndexName,0).StringContents();
  96.105 +	}
  96.106 +}
  96.107 +
  96.108 +
  96.109 +// ------------------------------------------------------------------------------------------------
  96.110 +CameraSwitcher::~CameraSwitcher()
  96.111 +{
  96.112 +
  96.113 +}
  96.114 +
  96.115 +
  96.116 +// ------------------------------------------------------------------------------------------------
  96.117 +Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name)
  96.118 +: NodeAttribute(id,element,doc,name)
  96.119 +{
  96.120 +
  96.121 +}
  96.122 +
  96.123 +
  96.124 +// ------------------------------------------------------------------------------------------------
  96.125 +Camera::~Camera()
  96.126 +{
  96.127 +}
  96.128 +
  96.129 +
  96.130 +// ------------------------------------------------------------------------------------------------
  96.131 +Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& name)
  96.132 +: NodeAttribute(id,element,doc,name)
  96.133 +{
  96.134 +
  96.135 +}
  96.136 +
  96.137 +
  96.138 +// ------------------------------------------------------------------------------------------------
  96.139 +Light::~Light()
  96.140 +{
  96.141 +}
  96.142 +
  96.143 +
  96.144 +// ------------------------------------------------------------------------------------------------
  96.145 +Null::Null(uint64_t id, const Element& element, const Document& doc, const std::string& name)
  96.146 +: NodeAttribute(id,element,doc,name)
  96.147 +{
  96.148 +
  96.149 +}
  96.150 +
  96.151 +
  96.152 +// ------------------------------------------------------------------------------------------------
  96.153 +Null::~Null()
  96.154 +{
  96.155 +
  96.156 +}
  96.157 +
  96.158 +
  96.159 +// ------------------------------------------------------------------------------------------------
  96.160 +LimbNode::LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name)
  96.161 +: NodeAttribute(id,element,doc,name)
  96.162 +{
  96.163 +
  96.164 +}
  96.165 +
  96.166 +
  96.167 +// ------------------------------------------------------------------------------------------------
  96.168 +LimbNode::~LimbNode()
  96.169 +{
  96.170 +
  96.171 +}
  96.172 +
  96.173 +}
  96.174 +}
  96.175 +
  96.176 +#endif
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/libs/assimp/FBXParser.cpp	Sat Feb 01 19:58:19 2014 +0200
    97.3 @@ -0,0 +1,1212 @@
    97.4 +/*
    97.5 +Open Asset Import Library (assimp)
    97.6 +----------------------------------------------------------------------
    97.7 +
    97.8 +Copyright (c) 2006-2012, assimp team
    97.9 +All rights reserved.
   97.10 +
   97.11 +Redistribution and use of this software in source and binary forms, 
   97.12 +with or without modification, are permitted provided that the 
   97.13 +following conditions are met:
   97.14 +
   97.15 +* Redistributions of source code must retain the above
   97.16 +  copyright notice, this list of conditions and the
   97.17 +  following disclaimer.
   97.18 +
   97.19 +* Redistributions in binary form must reproduce the above
   97.20 +  copyright notice, this list of conditions and the
   97.21 +  following disclaimer in the documentation and/or other
   97.22 +  materials provided with the distribution.
   97.23 +
   97.24 +* Neither the name of the assimp team, nor the names of its
   97.25 +  contributors may be used to endorse or promote products
   97.26 +  derived from this software without specific prior
   97.27 +  written permission of the assimp team.
   97.28 +
   97.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   97.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   97.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   97.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   97.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   97.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   97.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   97.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   97.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   97.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   97.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   97.40 +
   97.41 +----------------------------------------------------------------------
   97.42 +*/
   97.43 +
   97.44 +/** @file  FBXParser.cpp
   97.45 + *  @brief Implementation of the FBX parser and the rudimentary DOM that we use
   97.46 + */
   97.47 +#include "AssimpPCH.h"
   97.48 +
   97.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   97.50 +
   97.51 +
   97.52 +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
   97.53 +#	include <zlib.h>
   97.54 +#else
   97.55 +#	include "../contrib/zlib/zlib.h"
   97.56 +#endif
   97.57 +
   97.58 +
   97.59 +#include "FBXTokenizer.h"
   97.60 +#include "FBXParser.h"
   97.61 +#include "FBXUtil.h"
   97.62 +
   97.63 +#include "ParsingUtils.h"
   97.64 +#include "fast_atof.h"
   97.65 +
   97.66 +using namespace Assimp;
   97.67 +using namespace Assimp::FBX;
   97.68 +
   97.69 +namespace {
   97.70 +
   97.71 +
   97.72 +	// ------------------------------------------------------------------------------------------------
   97.73 +	// signal parse error, this is always unrecoverable. Throws DeadlyImportError.
   97.74 +	void ParseError(const std::string& message, const Token& token)
   97.75 +	{
   97.76 +		throw DeadlyImportError(Util::AddTokenText("FBX-Parser",message,&token));
   97.77 +	}
   97.78 +
   97.79 +	// ------------------------------------------------------------------------------------------------
   97.80 +	void ParseError(const std::string& message, const Element* element = NULL)
   97.81 +	{
   97.82 +		if(element) {
   97.83 +			ParseError(message,element->KeyToken());
   97.84 +		}
   97.85 +		throw DeadlyImportError("FBX-Parser " + message);
   97.86 +	}
   97.87 +
   97.88 +
   97.89 +	// ------------------------------------------------------------------------------------------------
   97.90 +	// print warning, do return
   97.91 +	void ParseWarning(const std::string& message, const Token& token)
   97.92 +	{
   97.93 +		if(DefaultLogger::get()) {
   97.94 +			DefaultLogger::get()->warn(Util::AddTokenText("FBX-Parser",message,&token));
   97.95 +		}
   97.96 +	}
   97.97 +
   97.98 +	// ------------------------------------------------------------------------------------------------
   97.99 +	void ParseWarning(const std::string& message, const Element* element = NULL)
  97.100 +	{
  97.101 +		if(element) {
  97.102 +			ParseWarning(message,element->KeyToken());
  97.103 +			return;
  97.104 +		}
  97.105 +		if(DefaultLogger::get()) {
  97.106 +			DefaultLogger::get()->warn("FBX-Parser: " + message);
  97.107 +		}
  97.108 +	}
  97.109 +
  97.110 +	// ------------------------------------------------------------------------------------------------
  97.111 +	void ParseError(const std::string& message, TokenPtr token)
  97.112 +	{
  97.113 +		if(token) {
  97.114 +			ParseError(message, *token);
  97.115 +		}
  97.116 +		ParseError(message);
  97.117 +	}
  97.118 +
  97.119 +}
  97.120 +
  97.121 +namespace Assimp {
  97.122 +namespace FBX {
  97.123 +
  97.124 +// ------------------------------------------------------------------------------------------------
  97.125 +Element::Element(const Token& key_token, Parser& parser)
  97.126 +: key_token(key_token)
  97.127 +{
  97.128 +	TokenPtr n = NULL;
  97.129 +	do {
  97.130 +		n = parser.AdvanceToNextToken();
  97.131 +		if(!n) {
  97.132 +			ParseError("unexpected end of file, expected closing bracket",parser.LastToken());
  97.133 +		}
  97.134 +
  97.135 +		if (n->Type() == TokenType_DATA) {
  97.136 +			tokens.push_back(n);
  97.137 +
  97.138 +			n = parser.AdvanceToNextToken();
  97.139 +			if(!n) {
  97.140 +				ParseError("unexpected end of file, expected bracket, comma or key",parser.LastToken());
  97.141 +			}
  97.142 +
  97.143 +			const TokenType ty = n->Type();
  97.144 +			if (ty != TokenType_OPEN_BRACKET && ty != TokenType_CLOSE_BRACKET && ty != TokenType_COMMA && ty != TokenType_KEY) {
  97.145 +				ParseError("unexpected token; expected bracket, comma or key",n);
  97.146 +			}
  97.147 +		}
  97.148 +
  97.149 +		if (n->Type() == TokenType_OPEN_BRACKET) {
  97.150 +			compound.reset(new Scope(parser));
  97.151 +
  97.152 +			// current token should be a TOK_CLOSE_BRACKET
  97.153 +			n = parser.CurrentToken();
  97.154 +			ai_assert(n);
  97.155 +
  97.156 +			if (n->Type() != TokenType_CLOSE_BRACKET) {
  97.157 +				ParseError("expected closing bracket",n);
  97.158 +			}
  97.159 +
  97.160 +			parser.AdvanceToNextToken();
  97.161 +			return;
  97.162 +		}
  97.163 +	}
  97.164 +	while(n->Type() != TokenType_KEY && n->Type() != TokenType_CLOSE_BRACKET);
  97.165 +}
  97.166 +
  97.167 +// ------------------------------------------------------------------------------------------------
  97.168 +Element::~Element()
  97.169 +{
  97.170 +	 // no need to delete tokens, they are owned by the parser
  97.171 +}
  97.172 +
  97.173 +// ------------------------------------------------------------------------------------------------
  97.174 +Scope::Scope(Parser& parser,bool topLevel)
  97.175 +{
  97.176 +	if(!topLevel) {
  97.177 +		TokenPtr t = parser.CurrentToken();
  97.178 +		if (t->Type() != TokenType_OPEN_BRACKET) {
  97.179 +			ParseError("expected open bracket",t);
  97.180 +		}	
  97.181 +	}
  97.182 +
  97.183 +	TokenPtr n = parser.AdvanceToNextToken();
  97.184 +	if(n == NULL) {
  97.185 +		ParseError("unexpected end of file");
  97.186 +	}
  97.187 +
  97.188 +	// note: empty scopes are allowed
  97.189 +	while(n->Type() != TokenType_CLOSE_BRACKET)	{
  97.190 +		if (n->Type() != TokenType_KEY) {
  97.191 +			ParseError("unexpected token, expected TOK_KEY",n);
  97.192 +		}
  97.193 +
  97.194 +		const std::string& str = n->StringContents();
  97.195 +		elements.insert(ElementMap::value_type(str,new_Element(*n,parser)));
  97.196 +
  97.197 +		// Element() should stop at the next Key token (or right after a Close token)
  97.198 +		n = parser.CurrentToken();
  97.199 +		if(n == NULL) {
  97.200 +			if (topLevel) {
  97.201 +				return;
  97.202 +			}
  97.203 +			ParseError("unexpected end of file",parser.LastToken());
  97.204 +		}
  97.205 +	}
  97.206 +}
  97.207 +
  97.208 +// ------------------------------------------------------------------------------------------------
  97.209 +Scope::~Scope()
  97.210 +{
  97.211 +	BOOST_FOREACH(ElementMap::value_type& v, elements) {
  97.212 +		delete v.second;
  97.213 +	}
  97.214 +}
  97.215 +
  97.216 +
  97.217 +// ------------------------------------------------------------------------------------------------
  97.218 +Parser::Parser (const TokenList& tokens, bool is_binary)
  97.219 +: tokens(tokens)
  97.220 +, last()
  97.221 +, current()
  97.222 +, cursor(tokens.begin())
  97.223 +, is_binary(is_binary)
  97.224 +{
  97.225 +	root.reset(new Scope(*this,true));
  97.226 +}
  97.227 +
  97.228 +
  97.229 +// ------------------------------------------------------------------------------------------------
  97.230 +Parser::~Parser()
  97.231 +{
  97.232 +}
  97.233 +
  97.234 +
  97.235 +// ------------------------------------------------------------------------------------------------
  97.236 +TokenPtr Parser::AdvanceToNextToken()
  97.237 +{
  97.238 +	last = current;
  97.239 +	if (cursor == tokens.end()) {
  97.240 +		current = NULL;
  97.241 +	}
  97.242 +	else {
  97.243 +		current = *cursor++;
  97.244 +	}
  97.245 +	return current;
  97.246 +}
  97.247 +
  97.248 +
  97.249 +// ------------------------------------------------------------------------------------------------
  97.250 +TokenPtr Parser::CurrentToken() const
  97.251 +{
  97.252 +	return current;
  97.253 +}
  97.254 +
  97.255 +
  97.256 +// ------------------------------------------------------------------------------------------------
  97.257 +TokenPtr Parser::LastToken() const
  97.258 +{
  97.259 +	return last;
  97.260 +}
  97.261 +
  97.262 +
  97.263 +// ------------------------------------------------------------------------------------------------
  97.264 +uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
  97.265 +{
  97.266 +	err_out = NULL;
  97.267 +
  97.268 +	if (t.Type() != TokenType_DATA) {
  97.269 +		err_out = "expected TOK_DATA token";
  97.270 +		return 0L;
  97.271 +	}
  97.272 +
  97.273 +	if(t.IsBinary())
  97.274 +	{
  97.275 +		const char* data = t.begin();
  97.276 +		if (data[0] != 'L') {
  97.277 +			err_out = "failed to parse ID, unexpected data type, expected L(ong) (binary)";
  97.278 +			return 0L;
  97.279 +		}
  97.280 +
  97.281 +		ai_assert(t.end() - data == 9);
  97.282 +
  97.283 +		BE_NCONST uint64_t id = *reinterpret_cast<const uint64_t*>(data+1);
  97.284 +		AI_SWAP8(id);
  97.285 +		return id;
  97.286 +	}
  97.287 +
  97.288 +	// XXX: should use size_t here
  97.289 +	unsigned int length = static_cast<unsigned int>(t.end() - t.begin());
  97.290 +	ai_assert(length > 0);
  97.291 +
  97.292 +	const char* out;
  97.293 +	const uint64_t id = strtoul10_64(t.begin(),&out,&length);
  97.294 +	if (out > t.end()) {
  97.295 +		err_out = "failed to parse ID (text)";
  97.296 +		return 0L;
  97.297 +	}
  97.298 +
  97.299 +	return id;
  97.300 +}
  97.301 +
  97.302 +
  97.303 +// ------------------------------------------------------------------------------------------------
  97.304 +size_t ParseTokenAsDim(const Token& t, const char*& err_out)
  97.305 +{
  97.306 +	// same as ID parsing, except there is a trailing asterisk
  97.307 +	err_out = NULL;
  97.308 +
  97.309 +	if (t.Type() != TokenType_DATA) {
  97.310 +		err_out = "expected TOK_DATA token";
  97.311 +		return 0;
  97.312 +	}
  97.313 +
  97.314 +	if(t.IsBinary())
  97.315 +	{
  97.316 +		const char* data = t.begin();
  97.317 +		if (data[0] != 'L') {
  97.318 +			err_out = "failed to parse ID, unexpected data type, expected L(ong) (binary)";
  97.319 +			return 0;
  97.320 +		}
  97.321 +
  97.322 +		ai_assert(t.end() - data == 9);
  97.323 +		BE_NCONST uint64_t id = *reinterpret_cast<const uint64_t*>(data+1);
  97.324 +		AI_SWAP8(id);
  97.325 +		return static_cast<size_t>(id);
  97.326 +	}
  97.327 +
  97.328 +	if(*t.begin() != '*') {
  97.329 +		err_out = "expected asterisk before array dimension";
  97.330 +		return 0;
  97.331 +	}
  97.332 +
  97.333 +	// XXX: should use size_t here
  97.334 +	unsigned int length = static_cast<unsigned int>(t.end() - t.begin());
  97.335 +	if(length == 0) {
  97.336 +		err_out = "expected valid integer number after asterisk";
  97.337 +		return 0;
  97.338 +	}
  97.339 +
  97.340 +	const char* out;
  97.341 +	const size_t id = static_cast<size_t>(strtoul10_64(t.begin() + 1,&out,&length));
  97.342 +	if (out > t.end()) {
  97.343 +		err_out = "failed to parse ID";
  97.344 +		return 0;
  97.345 +	}
  97.346 +
  97.347 +	return id;
  97.348 +}
  97.349 +
  97.350 +
  97.351 +// ------------------------------------------------------------------------------------------------
  97.352 +float ParseTokenAsFloat(const Token& t, const char*& err_out)
  97.353 +{
  97.354 +	err_out = NULL;
  97.355 +
  97.356 +	if (t.Type() != TokenType_DATA) {
  97.357 +		err_out = "expected TOK_DATA token";
  97.358 +		return 0.0f;
  97.359 +	}
  97.360 +
  97.361 +	if(t.IsBinary())
  97.362 +	{
  97.363 +		const char* data = t.begin();
  97.364 +		if (data[0] != 'F' && data[0] != 'D') {
  97.365 +			err_out = "failed to parse F(loat) or D(ouble), unexpected data type (binary)";
  97.366 +			return 0.0f;
  97.367 +		}
  97.368 +
  97.369 +		if (data[0] == 'F') {
  97.370 +			ai_assert(t.end() - data == 5);
  97.371 +			// no byte swapping needed for ieee floats
  97.372 +			float res;
  97.373 +			memcpy(&res, data + 1, sizeof res);
  97.374 +			return res;
  97.375 +		}
  97.376 +		else {
  97.377 +			ai_assert(t.end() - data == 9);
  97.378 +			// no byte swapping needed for ieee floats
  97.379 +			double res;
  97.380 +			memcpy(&res, data + 1, sizeof res);
  97.381 +			return (float)res;
  97.382 +		}
  97.383 +	}
  97.384 +
  97.385 +	// need to copy the input string to a temporary buffer
  97.386 +	// first - next in the fbx token stream comes ',', 
  97.387 +	// which fast_atof could interpret as decimal point.
  97.388 +#define MAX_FLOAT_LENGTH 31
  97.389 +	char temp[MAX_FLOAT_LENGTH + 1];
  97.390 +	const size_t length = static_cast<size_t>(t.end()-t.begin());
  97.391 +	std::copy(t.begin(),t.end(),temp);
  97.392 +	temp[std::min(static_cast<size_t>(MAX_FLOAT_LENGTH),length)] = '\0';
  97.393 +
  97.394 +	return fast_atof(temp);
  97.395 +}
  97.396 +
  97.397 +
  97.398 +// ------------------------------------------------------------------------------------------------
  97.399 +int ParseTokenAsInt(const Token& t, const char*& err_out)
  97.400 +{
  97.401 +	err_out = NULL;
  97.402 +
  97.403 +	if (t.Type() != TokenType_DATA) {
  97.404 +		err_out = "expected TOK_DATA token";
  97.405 +		return 0;
  97.406 +	}
  97.407 +
  97.408 +	if(t.IsBinary())
  97.409 +	{
  97.410 +		const char* data = t.begin();
  97.411 +		if (data[0] != 'I') {
  97.412 +			err_out = "failed to parse I(nt), unexpected data type (binary)";
  97.413 +			return 0;
  97.414 +		}
  97.415 +
  97.416 +		ai_assert(t.end() - data == 5);
  97.417 +		BE_NCONST int32_t ival = *reinterpret_cast<const int32_t*>(data+1);
  97.418 +		AI_SWAP4(ival);
  97.419 +		return static_cast<int>(ival);
  97.420 +	}
  97.421 +
  97.422 +	ai_assert(static_cast<size_t>(t.end() - t.begin()) > 0);
  97.423 +
  97.424 +	const char* out;
  97.425 +	const int intval = strtol10(t.begin(),&out);
  97.426 +	if (out != t.end()) {
  97.427 +		err_out = "failed to parse ID";
  97.428 +		return 0;
  97.429 +	}
  97.430 +
  97.431 +	return intval;
  97.432 +}
  97.433 +
  97.434 +
  97.435 +// ------------------------------------------------------------------------------------------------
  97.436 +std::string ParseTokenAsString(const Token& t, const char*& err_out)
  97.437 +{
  97.438 +	err_out = NULL;
  97.439 +
  97.440 +	if (t.Type() != TokenType_DATA) {
  97.441 +		err_out = "expected TOK_DATA token";
  97.442 +		return "";
  97.443 +	}
  97.444 +
  97.445 +	if(t.IsBinary())
  97.446 +	{
  97.447 +		const char* data = t.begin();
  97.448 +		if (data[0] != 'S') {
  97.449 +			err_out = "failed to parse S(tring), unexpected data type (binary)";
  97.450 +			return "";
  97.451 +		}
  97.452 +
  97.453 +		ai_assert(t.end() - data >= 5);
  97.454 +
  97.455 +		// read string length
  97.456 +		BE_NCONST int32_t len = *reinterpret_cast<const int32_t*>(data+1);
  97.457 +		AI_SWAP4(len);
  97.458 +
  97.459 +		ai_assert(t.end() - data == 5 + len);
  97.460 +		return std::string(data + 5, len);
  97.461 +	}
  97.462 +
  97.463 +	const size_t length = static_cast<size_t>(t.end() - t.begin());
  97.464 +	if(length < 2) {
  97.465 +		err_out = "token is too short to hold a string";
  97.466 +		return "";
  97.467 +	}
  97.468 +
  97.469 +	const char* s = t.begin(), *e = t.end() - 1;
  97.470 +	if (*s != '\"' || *e != '\"') {
  97.471 +		err_out = "expected double quoted string";
  97.472 +		return "";
  97.473 +	}
  97.474 +
  97.475 +	return std::string(s+1,length-2);
  97.476 +}
  97.477 +
  97.478 +
  97.479 +namespace {
  97.480 +
  97.481 +// ------------------------------------------------------------------------------------------------
  97.482 +// read the type code and element count of a binary data array and stop there
  97.483 +void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uint32_t& count, 
  97.484 +	const Element& el)
  97.485 +{
  97.486 +	if (static_cast<size_t>(end-data) < 5) {
  97.487 +		ParseError("binary data array is too short, need five (5) bytes for type signature and element count",&el);
  97.488 +	}
  97.489 +
  97.490 +	// data type
  97.491 +	type = *data;
  97.492 +
  97.493 +	// read number of elements
  97.494 +	BE_NCONST uint32_t len = *reinterpret_cast<const uint32_t*>(data+1);
  97.495 +	AI_SWAP4(len);
  97.496 +
  97.497 +	count = len;
  97.498 +	data += 5;
  97.499 +}
  97.500 +
  97.501 +
  97.502 +// ------------------------------------------------------------------------------------------------
  97.503 +// read binary data array, assume cursor points to the 'compression mode' field (i.e. behind the header)
  97.504 +void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const char* end, 
  97.505 +	std::vector<char>& buff, 
  97.506 +	const Element& el)
  97.507 +{
  97.508 +	ai_assert(static_cast<size_t>(end-data) >= 4); // runtime check for this happens at tokenization stage
  97.509 +
  97.510 +	BE_NCONST uint32_t encmode = *reinterpret_cast<const uint32_t*>(data);
  97.511 +	AI_SWAP4(encmode);
  97.512 +	data += 4;
  97.513 +
  97.514 +	// next comes the compressed length
  97.515 +	BE_NCONST uint32_t comp_len = *reinterpret_cast<const uint32_t*>(data);
  97.516 +	AI_SWAP4(comp_len);
  97.517 +	data += 4;
  97.518 +
  97.519 +	ai_assert(data + comp_len == end);
  97.520 +
  97.521 +	// determine the length of the uncompressed data by looking at the type signature
  97.522 +	uint32_t stride;
  97.523 +	switch(type)
  97.524 +	{
  97.525 +	case 'f':
  97.526 +	case 'i':
  97.527 +		stride = 4;
  97.528 +		break;
  97.529 +
  97.530 +	case 'd':
  97.531 +	case 'l':
  97.532 +		stride = 8;
  97.533 +		break;
  97.534 +
  97.535 +	default:
  97.536 +		ai_assert(false);
  97.537 +	};
  97.538 +
  97.539 +	const uint32_t full_length = stride * count;
  97.540 +	buff.resize(full_length);
  97.541 +
  97.542 +	if(encmode == 0) {
  97.543 +		ai_assert(full_length == comp_len);
  97.544 +
  97.545 +		// plain data, no compression
  97.546 +		std::copy(data, end, buff.begin());
  97.547 +	}
  97.548 +	else if(encmode == 1) {
  97.549 +		// zlib/deflate, next comes ZIP head (0x78 0x01)
  97.550 +		// see http://www.ietf.org/rfc/rfc1950.txt
  97.551 +		
  97.552 +		z_stream zstream;
  97.553 +		zstream.opaque = Z_NULL;
  97.554 +		zstream.zalloc = Z_NULL;
  97.555 +		zstream.zfree  = Z_NULL;
  97.556 +		zstream.data_type = Z_BINARY;
  97.557 +
  97.558 +		// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
  97.559 +		inflateInit(&zstream);
  97.560 +
  97.561 +		zstream.next_in   = reinterpret_cast<Bytef*>( const_cast<char*>(data) );
  97.562 +		zstream.avail_in  = comp_len;
  97.563 +
  97.564 +		zstream.avail_out = buff.size();
  97.565 +		zstream.next_out = reinterpret_cast<Bytef*>(&*buff.begin());
  97.566 +		const int ret = inflate(&zstream, Z_FINISH);
  97.567 +
  97.568 +		if (ret != Z_STREAM_END && ret != Z_OK) {
  97.569 +			ParseError("failure decompressing compressed data section");
  97.570 +		}
  97.571 +
  97.572 +		// terminate zlib
  97.573 +		inflateEnd(&zstream);
  97.574 +	}
  97.575 +#ifdef _DEBUG
  97.576 +	else {
  97.577 +		// runtime check for this happens at tokenization stage
  97.578 +		ai_assert(false);
  97.579 +	}
  97.580 +#endif
  97.581 +
  97.582 +	data += comp_len;
  97.583 +	ai_assert(data == end);
  97.584 +}
  97.585 +
  97.586 +} // !anon
  97.587 +
  97.588 +
  97.589 +// ------------------------------------------------------------------------------------------------
  97.590 +// read an array of float3 tuples
  97.591 +void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
  97.592 +{
  97.593 +	out.clear();
  97.594 +
  97.595 +	const TokenList& tok = el.Tokens();
  97.596 +	if(tok.empty()) {
  97.597 +		ParseError("unexpected empty element",&el);
  97.598 +	}
  97.599 +	
  97.600 +	if(tok[0]->IsBinary()) {
  97.601 +		const char* data = tok[0]->begin(), *end = tok[0]->end();
  97.602 +
  97.603 +		char type;
  97.604 +		uint32_t count;
  97.605 +		ReadBinaryDataArrayHead(data, end, type, count, el);
  97.606 +
  97.607 +		if(count % 3 != 0) {
  97.608 +			ParseError("number of floats is not a multiple of three (3) (binary)",&el);
  97.609 +		}
  97.610 +
  97.611 +		if(!count) {
  97.612 +			return;
  97.613 +		}
  97.614 +
  97.615 +		if (type != 'd' && type != 'f') {
  97.616 +			ParseError("expected float or double array (binary)",&el);
  97.617 +		}
  97.618 +
  97.619 +		std::vector<char> buff;
  97.620 +		ReadBinaryDataArray(type, count, data, end, buff, el);
  97.621 +		
  97.622 +		ai_assert(data == end);
  97.623 +		ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));
  97.624 +
  97.625 +		const uint32_t count3 = count / 3;
  97.626 +		out.reserve(count3);
  97.627 +
  97.628 +		if (type == 'd') {
  97.629 +			const double* d = reinterpret_cast<const double*>(&buff[0]);
  97.630 +			for (unsigned int i = 0; i < count3; ++i, d += 3) {
  97.631 +				out.push_back(aiVector3D(static_cast<float>(d[0]),
  97.632 +					static_cast<float>(d[1]),
  97.633 +					static_cast<float>(d[2])));
  97.634 +			}
  97.635 +		}
  97.636 +		else if (type == 'f') {
  97.637 +			const float* f = reinterpret_cast<const float*>(&buff[0]);
  97.638 +			for (unsigned int i = 0; i < count3; ++i, f += 3) {
  97.639 +				out.push_back(aiVector3D(f[0],f[1],f[2]));
  97.640 +			}
  97.641 +		}
  97.642 +
  97.643 +		return;
  97.644 +	}
  97.645 +
  97.646 +	const size_t dim = ParseTokenAsDim(*tok[0]);
  97.647 +
  97.648 +	// may throw bad_alloc if the input is rubbish, but this need
  97.649 +	// not to be prevented - importing would fail but we wouldn't
  97.650 +	// crash since assimp handles this case properly.
  97.651 +	out.reserve(dim);
  97.652 +
  97.653 +	const Scope& scope = GetRequiredScope(el);
  97.654 +	const Element& a = GetRequiredElement(scope,"a",&el);
  97.655 +
  97.656 +	if (a.Tokens().size() % 3 != 0) {
  97.657 +		ParseError("number of floats is not a multiple of three (3)",&el);
  97.658 +	}
  97.659 +	for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
  97.660 +		aiVector3D v;
  97.661 +		v.x = ParseTokenAsFloat(**it++);
  97.662 +		v.y = ParseTokenAsFloat(**it++);
  97.663 +		v.z = ParseTokenAsFloat(**it++);
  97.664 +
  97.665 +		out.push_back(v);
  97.666 +	}
  97.667 +}
  97.668 +
  97.669 +
  97.670 +// ------------------------------------------------------------------------------------------------
  97.671 +// read an array of color4 tuples
  97.672 +void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
  97.673 +{
  97.674 +	out.clear();
  97.675 +	const TokenList& tok = el.Tokens();
  97.676 +	if(tok.empty()) {
  97.677 +		ParseError("unexpected empty element",&el);
  97.678 +	}
  97.679 +
  97.680 +	if(tok[0]->IsBinary()) {
  97.681 +		const char* data = tok[0]->begin(), *end = tok[0]->end();
  97.682 +
  97.683 +		char type;
  97.684 +		uint32_t count;
  97.685 +		ReadBinaryDataArrayHead(data, end, type, count, el);
  97.686 +
  97.687 +		if(count % 4 != 0) {
  97.688 +			ParseError("number of floats is not a multiple of four (4) (binary)",&el);
  97.689 +		}
  97.690 +
  97.691 +		if(!count) {
  97.692 +			return;
  97.693 +		}
  97.694 +
  97.695 +		if (type != 'd' && type != 'f') {
  97.696 +			ParseError("expected float or double array (binary)",&el);
  97.697 +		}
  97.698 +
  97.699 +		std::vector<char> buff;
  97.700 +		ReadBinaryDataArray(type, count, data, end, buff, el);
  97.701 +
  97.702 +		ai_assert(data == end);
  97.703 +		ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));
  97.704 +
  97.705 +		const uint32_t count4 = count / 4;
  97.706 +		out.reserve(count4);
  97.707 +
  97.708 +		if (type == 'd') {
  97.709 +			const double* d = reinterpret_cast<const double*>(&buff[0]);
  97.710 +			for (unsigned int i = 0; i < count4; ++i, d += 4) {
  97.711 +				out.push_back(aiColor4D(static_cast<float>(d[0]),
  97.712 +					static_cast<float>(d[1]),
  97.713 +					static_cast<float>(d[2]),
  97.714 +					static_cast<float>(d[3])));
  97.715 +			}
  97.716 +		}
  97.717 +		else if (type == 'f') {
  97.718 +			const float* f = reinterpret_cast<const float*>(&buff[0]);
  97.719 +			for (unsigned int i = 0; i < count4; ++i, f += 4) {
  97.720 +				out.push_back(aiColor4D(f[0],f[1],f[2],f[3]));
  97.721 +			}
  97.722 +		}
  97.723 +		return;
  97.724 +	}
  97.725 +
  97.726 +	const size_t dim = ParseTokenAsDim(*tok[0]);
  97.727 +
  97.728 +	//  see notes in ParseVectorDataArray() above
  97.729 +	out.reserve(dim);
  97.730 +
  97.731 +	const Scope& scope = GetRequiredScope(el);
  97.732 +	const Element& a = GetRequiredElement(scope,"a",&el);
  97.733 +
  97.734 +	if (a.Tokens().size() % 4 != 0) {
  97.735 +		ParseError("number of floats is not a multiple of four (4)",&el);
  97.736 +	}
  97.737 +	for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
  97.738 +		aiColor4D v;
  97.739 +		v.r = ParseTokenAsFloat(**it++);
  97.740 +		v.g = ParseTokenAsFloat(**it++);
  97.741 +		v.b = ParseTokenAsFloat(**it++);
  97.742 +		v.a = ParseTokenAsFloat(**it++);
  97.743 +
  97.744 +		out.push_back(v);
  97.745 +	}
  97.746 +}
  97.747 +
  97.748 +
  97.749 +// ------------------------------------------------------------------------------------------------
  97.750 +// read an array of float2 tuples
  97.751 +void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
  97.752 +{
  97.753 +	out.clear();
  97.754 +	const TokenList& tok = el.Tokens();
  97.755 +	if(tok.empty()) {
  97.756 +		ParseError("unexpected empty element",&el);
  97.757 +	}
  97.758 +
  97.759 +	if(tok[0]->IsBinary()) {
  97.760 +		const char* data = tok[0]->begin(), *end = tok[0]->end();
  97.761 +
  97.762 +		char type;
  97.763 +		uint32_t count;
  97.764 +		ReadBinaryDataArrayHead(data, end, type, count, el);
  97.765 +
  97.766 +		if(count % 2 != 0) {
  97.767 +			ParseError("number of floats is not a multiple of two (2) (binary)",&el);
  97.768 +		}
  97.769 +
  97.770 +		if(!count) {
  97.771 +			return;
  97.772 +		}
  97.773 +
  97.774 +		if (type != 'd' && type != 'f') {
  97.775 +			ParseError("expected float or double array (binary)",&el);
  97.776 +		}
  97.777 +
  97.778 +		std::vector<char> buff;
  97.779 +		ReadBinaryDataArray(type, count, data, end, buff, el);
  97.780 +
  97.781 +		ai_assert(data == end);
  97.782 +		ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));
  97.783 +
  97.784 +		const uint32_t count2 = count / 2;
  97.785 +		out.reserve(count2);
  97.786 +
  97.787 +		if (type == 'd') {
  97.788 +			const double* d = reinterpret_cast<const double*>(&buff[0]);
  97.789 +			for (unsigned int i = 0; i < count2; ++i, d += 2) {
  97.790 +				out.push_back(aiVector2D(static_cast<float>(d[0]),
  97.791 +					static_cast<float>(d[1])));
  97.792 +			}
  97.793 +		}
  97.794 +		else if (type == 'f') {
  97.795 +			const float* f = reinterpret_cast<const float*>(&buff[0]);
  97.796 +			for (unsigned int i = 0; i < count2; ++i, f += 2) {
  97.797 +				out.push_back(aiVector2D(f[0],f[1]));
  97.798 +			}
  97.799 +		}
  97.800 +
  97.801 +		return;
  97.802 +	}
  97.803 +
  97.804 +	const size_t dim = ParseTokenAsDim(*tok[0]);
  97.805 +
  97.806 +	// see notes in ParseVectorDataArray() above
  97.807 +	out.reserve(dim);
  97.808 +
  97.809 +	const Scope& scope = GetRequiredScope(el);
  97.810 +	const Element& a = GetRequiredElement(scope,"a",&el);
  97.811 +
  97.812 +	if (a.Tokens().size() % 2 != 0) {
  97.813 +		ParseError("number of floats is not a multiple of two (2)",&el);
  97.814 +	}
  97.815 +	for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
  97.816 +		aiVector2D v;
  97.817 +		v.x = ParseTokenAsFloat(**it++);
  97.818 +		v.y = ParseTokenAsFloat(**it++);
  97.819 +
  97.820 +		out.push_back(v);
  97.821 +	}
  97.822 +}
  97.823 +
  97.824 +
  97.825 +// ------------------------------------------------------------------------------------------------
  97.826 +// read an array of ints
  97.827 +void ParseVectorDataArray(std::vector<int>& out, const Element& el)
  97.828 +{
  97.829 +	out.clear();
  97.830 +	const TokenList& tok = el.Tokens();
  97.831 +	if(tok.empty()) {
  97.832 +		ParseError("unexpected empty element",&el);
  97.833 +	}
  97.834 +
  97.835 +	if(tok[0]->IsBinary()) {
  97.836 +		const char* data = tok[0]->begin(), *end = tok[0]->end();
  97.837 +
  97.838 +		char type;
  97.839 +		uint32_t count;
  97.840 +		ReadBinaryDataArrayHead(data, end, type, count, el);
  97.841 +
  97.842 +		if(!count) {
  97.843 +			return;
  97.844 +		}
  97.845 +
  97.846 +		if (type != 'i') {
  97.847 +			ParseError("expected int array (binary)",&el);
  97.848 +		}
  97.849 +
  97.850 +		std::vector<char> buff;
  97.851 +		ReadBinaryDataArray(type, count, data, end, buff, el);
  97.852 +
  97.853 +		ai_assert(data == end);
  97.854 +		ai_assert(buff.size() == count * 4);
  97.855 +
  97.856 +		out.reserve(count);
  97.857 +
  97.858 +		const int32_t* ip = reinterpret_cast<const int32_t*>(&buff[0]);
  97.859 +		for (unsigned int i = 0; i < count; ++i, ++ip) {
  97.860 +			BE_NCONST int32_t val = *ip;
  97.861 +			AI_SWAP4(val);
  97.862 +			out.push_back(val);
  97.863 +		}
  97.864 +
  97.865 +		return;
  97.866 +	}
  97.867 +
  97.868 +	const size_t dim = ParseTokenAsDim(*tok[0]);
  97.869 +
  97.870 +	// see notes in ParseVectorDataArray()
  97.871 +	out.reserve(dim);
  97.872 +
  97.873 +	const Scope& scope = GetRequiredScope(el);
  97.874 +	const Element& a = GetRequiredElement(scope,"a",&el);
  97.875 +
  97.876 +	for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
  97.877 +		const int ival = ParseTokenAsInt(**it++);
  97.878 +		out.push_back(ival);
  97.879 +	}
  97.880 +}
  97.881 +
  97.882 +
  97.883 +// ------------------------------------------------------------------------------------------------
  97.884 +// read an array of floats
  97.885 +void ParseVectorDataArray(std::vector<float>& out, const Element& el)
  97.886 +{
  97.887 +	out.clear();
  97.888 +	const TokenList& tok = el.Tokens();
  97.889 +	if(tok.empty()) {
  97.890 +		ParseError("unexpected empty element",&el);
  97.891 +	}
  97.892 +
  97.893 +	if(tok[0]->IsBinary()) {
  97.894 +		const char* data = tok[0]->begin(), *end = tok[0]->end();
  97.895 +
  97.896 +		char type;
  97.897 +		uint32_t count;
  97.898 +		ReadBinaryDataArrayHead(data, end, type, count, el);
  97.899 +
  97.900 +		if(!count) {
  97.901 +			return;
  97.902 +		}
  97.903 +
  97.904 +		if (type != 'd' && type != 'f') {
  97.905 +			ParseError("expected float or double array (binary)",&el);
  97.906 +		}
  97.907 +
  97.908 +		std::vector<char> buff;
  97.909 +		ReadBinaryDataArray(type, count, data, end, buff, el);
  97.910 +
  97.911 +		ai_assert(data == end);
  97.912 +		ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));
  97.913 +
  97.914 +		if (type == 'd') {
  97.915 +			const double* d = reinterpret_cast<const double*>(&buff[0]);
  97.916 +			for (unsigned int i = 0; i < count; ++i, ++d) {
  97.917 +				out.push_back(static_cast<float>(*d));
  97.918 +			}
  97.919 +		}
  97.920 +		else if (type == 'f') {
  97.921 +			const float* f = reinterpret_cast<const float*>(&buff[0]);
  97.922 +			for (unsigned int i = 0; i < count; ++i, ++f) {
  97.923 +				out.push_back(*f);
  97.924 +			}
  97.925 +		}
  97.926 +
  97.927 +		return;
  97.928 +	}
  97.929 +
  97.930 +	const size_t dim = ParseTokenAsDim(*tok[0]);
  97.931 +
  97.932 +	// see notes in ParseVectorDataArray()
  97.933 +	out.reserve(dim);
  97.934 +
  97.935 +	const Scope& scope = GetRequiredScope(el);
  97.936 +	const Element& a = GetRequiredElement(scope,"a",&el);
  97.937 +
  97.938 +	for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
  97.939 +		const float ival = ParseTokenAsFloat(**it++);
  97.940 +		out.push_back(ival);
  97.941 +	}
  97.942 +}
  97.943 +
  97.944 +
  97.945 +// ------------------------------------------------------------------------------------------------
  97.946 +// read an array of uints
  97.947 +void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
  97.948 +{
  97.949 +	out.clear();
  97.950 +	const TokenList& tok = el.Tokens();
  97.951 +	if(tok.empty()) {
  97.952 +		ParseError("unexpected empty element",&el);
  97.953 +	}
  97.954 +
  97.955 +	if(tok[0]->IsBinary()) {
  97.956 +		const char* data = tok[0]->begin(), *end = tok[0]->end();
  97.957 +
  97.958 +		char type;
  97.959 +		uint32_t count;
  97.960 +		ReadBinaryDataArrayHead(data, end, type, count, el);
  97.961 +
  97.962 +		if(!count) {
  97.963 +			return;
  97.964 +		}
  97.965 +
  97.966 +		if (type != 'i') {
  97.967 +			ParseError("expected (u)int array (binary)",&el);
  97.968 +		}
  97.969 +
  97.970 +		std::vector<char> buff;
  97.971 +		ReadBinaryDataArray(type, count, data, end, buff, el);
  97.972 +
  97.973 +		ai_assert(data == end);
  97.974 +		ai_assert(buff.size() == count * 4);
  97.975 +
  97.976 +		out.reserve(count);
  97.977 +
  97.978 +		const int32_t* ip = reinterpret_cast<const int32_t*>(&buff[0]);
  97.979 +		for (unsigned int i = 0; i < count; ++i, ++ip) {
  97.980 +			BE_NCONST int32_t val = *ip;
  97.981 +			if(val < 0) {
  97.982 +				ParseError("encountered negative integer index (binary)");
  97.983 +			}
  97.984 +
  97.985 +			AI_SWAP4(val);
  97.986 +			out.push_back(val);
  97.987 +		}
  97.988 +
  97.989 +		return;
  97.990 +	}
  97.991 +
  97.992 +	const size_t dim = ParseTokenAsDim(*tok[0]);
  97.993 +
  97.994 +	// see notes in ParseVectorDataArray()
  97.995 +	out.reserve(dim);
  97.996 +
  97.997 +	const Scope& scope = GetRequiredScope(el);
  97.998 +	const Element& a = GetRequiredElement(scope,"a",&el);
  97.999 +
 97.1000 +	for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
 97.1001 +		const int ival = ParseTokenAsInt(**it++);
 97.1002 +		if(ival < 0) {
 97.1003 +			ParseError("encountered negative integer index");
 97.1004 +		}
 97.1005 +		out.push_back(static_cast<unsigned int>(ival));
 97.1006 +	}
 97.1007 +}
 97.1008 +
 97.1009 +
 97.1010 +// ------------------------------------------------------------------------------------------------
 97.1011 +// read an array of uint64_ts
 97.1012 +void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el)
 97.1013 +{
 97.1014 +	out.clear();
 97.1015 +	const TokenList& tok = el.Tokens();
 97.1016 +	if(tok.empty()) {
 97.1017 +		ParseError("unexpected empty element",&el);
 97.1018 +	}
 97.1019 +
 97.1020 +	if(tok[0]->IsBinary()) {
 97.1021 +		const char* data = tok[0]->begin(), *end = tok[0]->end();
 97.1022 +
 97.1023 +		char type;
 97.1024 +		uint32_t count;
 97.1025 +		ReadBinaryDataArrayHead(data, end, type, count, el);
 97.1026 +
 97.1027 +		if(!count) {
 97.1028 +			return;
 97.1029 +		}
 97.1030 +
 97.1031 +		if (type != 'l') {
 97.1032 +			ParseError("expected long array (binary)",&el);
 97.1033 +		}
 97.1034 +
 97.1035 +		std::vector<char> buff;
 97.1036 +		ReadBinaryDataArray(type, count, data, end, buff, el);
 97.1037 +
 97.1038 +		ai_assert(data == end);
 97.1039 +		ai_assert(buff.size() == count * 8);
 97.1040 +
 97.1041 +		out.reserve(count);
 97.1042 +
 97.1043 +		const uint64_t* ip = reinterpret_cast<const uint64_t*>(&buff[0]);
 97.1044 +		for (unsigned int i = 0; i < count; ++i, ++ip) {
 97.1045 +			BE_NCONST uint64_t val = *ip;
 97.1046 +			AI_SWAP8(val);
 97.1047 +			out.push_back(val);
 97.1048 +		}
 97.1049 +
 97.1050 +		return;
 97.1051 +	}
 97.1052 +
 97.1053 +	const size_t dim = ParseTokenAsDim(*tok[0]);
 97.1054 +
 97.1055 +	// see notes in ParseVectorDataArray()
 97.1056 +	out.reserve(dim);
 97.1057 +
 97.1058 +	const Scope& scope = GetRequiredScope(el);
 97.1059 +	const Element& a = GetRequiredElement(scope,"a",&el);
 97.1060 +
 97.1061 +	for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
 97.1062 +		const uint64_t ival = ParseTokenAsID(**it++);
 97.1063 +		
 97.1064 +		out.push_back(ival);
 97.1065 +	}
 97.1066 +}
 97.1067 +
 97.1068 +
 97.1069 +// ------------------------------------------------------------------------------------------------
 97.1070 +aiMatrix4x4 ReadMatrix(const Element& element)
 97.1071 +{
 97.1072 +	std::vector<float> values;
 97.1073 +	ParseVectorDataArray(values,element);
 97.1074 +
 97.1075 +	if(values.size() != 16) {
 97.1076 +		ParseError("expected 16 matrix elements");
 97.1077 +	}
 97.1078 +
 97.1079 +	aiMatrix4x4 result;
 97.1080 +
 97.1081 +
 97.1082 +	result.a1 = values[0];
 97.1083 +	result.a2 = values[1];
 97.1084 +	result.a3 = values[2];
 97.1085 +	result.a4 = values[3];
 97.1086 +
 97.1087 +	result.b1 = values[4];
 97.1088 +	result.b2 = values[5];
 97.1089 +	result.b3 = values[6];
 97.1090 +	result.b4 = values[7];
 97.1091 +
 97.1092 +	result.c1 = values[8];
 97.1093 +	result.c2 = values[9];
 97.1094 +	result.c3 = values[10];
 97.1095 +	result.c4 = values[11];
 97.1096 +
 97.1097 +	result.d1 = values[12];
 97.1098 +	result.d2 = values[13];
 97.1099 +	result.d3 = values[14];
 97.1100 +	result.d4 = values[15];
 97.1101 +
 97.1102 +	result.Transpose();
 97.1103 +	return result;
 97.1104 +}
 97.1105 +
 97.1106 +
 97.1107 +// ------------------------------------------------------------------------------------------------
 97.1108 +// wrapper around ParseTokenAsString() with ParseError handling
 97.1109 +std::string ParseTokenAsString(const Token& t)
 97.1110 +{
 97.1111 +	const char* err;
 97.1112 +	const std::string& i = ParseTokenAsString(t,err);
 97.1113 +	if(err) {
 97.1114 +		ParseError(err,t);
 97.1115 +	}
 97.1116 +	return i;
 97.1117 +}
 97.1118 +
 97.1119 +
 97.1120 +// ------------------------------------------------------------------------------------------------
 97.1121 +// extract a required element from a scope, abort if the element cannot be found
 97.1122 +const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= NULL*/) 
 97.1123 +{
 97.1124 +	const Element* el = sc[index];
 97.1125 +	if(!el) {
 97.1126 +		ParseError("did not find required element \"" + index + "\"",element);
 97.1127 +	}
 97.1128 +	return *el;
 97.1129 +}
 97.1130 +
 97.1131 +
 97.1132 +// ------------------------------------------------------------------------------------------------
 97.1133 +// extract required compound scope
 97.1134 +const Scope& GetRequiredScope(const Element& el)
 97.1135 +{
 97.1136 +	const Scope* const s = el.Compound();
 97.1137 +	if(!s) {
 97.1138 +		ParseError("expected compound scope",&el);
 97.1139 +	}
 97.1140 +
 97.1141 +	return *s;
 97.1142 +}
 97.1143 +
 97.1144 +
 97.1145 +// ------------------------------------------------------------------------------------------------
 97.1146 +// get token at a particular index
 97.1147 +const Token& GetRequiredToken(const Element& el, unsigned int index)
 97.1148 +{
 97.1149 +	const TokenList& t = el.Tokens();
 97.1150 +	if(index >= t.size()) {
 97.1151 +		ParseError(Formatter::format( "missing token at index " ) << index,&el);
 97.1152 +	}
 97.1153 +
 97.1154 +	return *t[index];
 97.1155 +}
 97.1156 +
 97.1157 +
 97.1158 +// ------------------------------------------------------------------------------------------------
 97.1159 +// wrapper around ParseTokenAsID() with ParseError handling
 97.1160 +uint64_t ParseTokenAsID(const Token& t) 
 97.1161 +{
 97.1162 +	const char* err;
 97.1163 +	const uint64_t i = ParseTokenAsID(t,err);
 97.1164 +	if(err) {
 97.1165 +		ParseError(err,t);
 97.1166 +	}
 97.1167 +	return i;
 97.1168 +}
 97.1169 +
 97.1170 +
 97.1171 +// ------------------------------------------------------------------------------------------------
 97.1172 +// wrapper around ParseTokenAsDim() with ParseError handling
 97.1173 +size_t ParseTokenAsDim(const Token& t)
 97.1174 +{
 97.1175 +	const char* err;
 97.1176 +	const size_t i = ParseTokenAsDim(t,err);
 97.1177 +	if(err) {
 97.1178 +		ParseError(err,t);
 97.1179 +	}
 97.1180 +	return i;
 97.1181 +}
 97.1182 +
 97.1183 +
 97.1184 +// ------------------------------------------------------------------------------------------------
 97.1185 +// wrapper around ParseTokenAsFloat() with ParseError handling
 97.1186 +float ParseTokenAsFloat(const Token& t)
 97.1187 +{
 97.1188 +	const char* err;
 97.1189 +	const float i = ParseTokenAsFloat(t,err);
 97.1190 +	if(err) {
 97.1191 +		ParseError(err,t);
 97.1192 +	}
 97.1193 +	return i;
 97.1194 +}
 97.1195 +
 97.1196 +
 97.1197 +// ------------------------------------------------------------------------------------------------
 97.1198 +// wrapper around ParseTokenAsInt() with ParseError handling
 97.1199 +int ParseTokenAsInt(const Token& t)
 97.1200 +{
 97.1201 +	const char* err;
 97.1202 +	const int i = ParseTokenAsInt(t,err);
 97.1203 +	if(err) {
 97.1204 +		ParseError(err,t);
 97.1205 +	}
 97.1206 +	return i;
 97.1207 +}
 97.1208 +
 97.1209 +
 97.1210 +
 97.1211 +} // !FBX
 97.1212 +} // !Assimp
 97.1213 +
 97.1214 +#endif
 97.1215 +
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/libs/assimp/FBXParser.h	Sat Feb 01 19:58:19 2014 +0200
    98.3 @@ -0,0 +1,246 @@
    98.4 +/*
    98.5 +Open Asset Import Library (assimp)
    98.6 +----------------------------------------------------------------------
    98.7 +
    98.8 +Copyright (c) 2006-2012, assimp team
    98.9 +All rights reserved.
   98.10 +
   98.11 +Redistribution and use of this software in source and binary forms, 
   98.12 +with or without modification, are permitted provided that the 
   98.13 +following conditions are met:
   98.14 +
   98.15 +* Redistributions of source code must retain the above
   98.16 +  copyright notice, this list of conditions and the
   98.17 +  following disclaimer.
   98.18 +
   98.19 +* Redistributions in binary form must reproduce the above
   98.20 +  copyright notice, this list of conditions and the
   98.21 +  following disclaimer in the documentation and/or other
   98.22 +  materials provided with the distribution.
   98.23 +
   98.24 +* Neither the name of the assimp team, nor the names of its
   98.25 +  contributors may be used to endorse or promote products
   98.26 +  derived from this software without specific prior
   98.27 +  written permission of the assimp team.
   98.28 +
   98.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   98.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   98.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   98.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   98.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   98.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   98.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   98.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   98.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   98.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   98.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   98.40 +
   98.41 +----------------------------------------------------------------------
   98.42 +*/
   98.43 +
   98.44 +/** @file  FBXParser.h
   98.45 + *  @brief FBX parsing code
   98.46 + */
   98.47 +#ifndef INCLUDED_AI_FBX_PARSER_H
   98.48 +#define INCLUDED_AI_FBX_PARSER_H
   98.49 +
   98.50 +#include <vector>
   98.51 +#include <map>
   98.52 +#include <string>
   98.53 +#include <utility>
   98.54 +
   98.55 +#include <boost/shared_ptr.hpp>
   98.56 +
   98.57 +#include "LogAux.h"
   98.58 +
   98.59 +#include "FBXCompileConfig.h"
   98.60 +#include "FBXTokenizer.h"
   98.61 +
   98.62 +namespace Assimp {
   98.63 +namespace FBX {
   98.64 +
   98.65 +	class Scope;
   98.66 +	class Parser;
   98.67 +	class Element;
   98.68 +
   98.69 +	// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03
   98.70 +	typedef std::vector< Scope* > ScopeList;
   98.71 +	typedef std::fbx_unordered_multimap< std::string, Element* > ElementMap;
   98.72 +
   98.73 +	typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> ElementCollection;
   98.74 +
   98.75 +#	define new_Scope new Scope
   98.76 +#	define new_Element new Element
   98.77 +
   98.78 +
   98.79 +/** FBX data entity that consists of a key:value tuple.
   98.80 + *
   98.81 + *  Example:
   98.82 + *  @verbatim
   98.83 + *    AnimationCurve: 23, "AnimCurve::", "" {
   98.84 + *        [..]
   98.85 + *    }
   98.86 + *  @endverbatim
   98.87 + *
   98.88 + *  As can be seen in this sample, elements can contain nested #Scope
   98.89 + *  as their trailing member.  **/
   98.90 +class Element
   98.91 +{
   98.92 +public:
   98.93 +
   98.94 +	Element(const Token& key_token, Parser& parser);
   98.95 +	~Element();
   98.96 +
   98.97 +public:
   98.98 +
   98.99 +	const Scope* Compound() const {
  98.100 +		return compound.get();
  98.101 +	}
  98.102 +
  98.103 +	const Token& KeyToken() const {
  98.104 +		return key_token;
  98.105 +	}
  98.106 +
  98.107 +	const TokenList& Tokens() const {
  98.108 +		return tokens;
  98.109 +	}
  98.110 +
  98.111 +private:
  98.112 +
  98.113 +	const Token& key_token;
  98.114 +	TokenList tokens;
  98.115 +	boost::scoped_ptr<Scope> compound;
  98.116 +};
  98.117 +
  98.118 +
  98.119 +
  98.120 +/** FBX data entity that consists of a 'scope', a collection
  98.121 + *  of not necessarily unique #Element instances.
  98.122 + *
  98.123 + *  Example:
  98.124 + *  @verbatim
  98.125 + *    GlobalSettings:  {
  98.126 + *        Version: 1000
  98.127 + *        Properties70: 
  98.128 + *        [...]
  98.129 + *    }
  98.130 + *  @endverbatim  */
  98.131 +class Scope
  98.132 +{
  98.133 +
  98.134 +public:
  98.135 +
  98.136 +	Scope(Parser& parser, bool topLevel = false);
  98.137 +	~Scope();
  98.138 +
  98.139 +public:
  98.140 +
  98.141 +	const Element* operator[] (const std::string& index) const {
  98.142 +		ElementMap::const_iterator it = elements.find(index);
  98.143 +		return it == elements.end() ? NULL : (*it).second;
  98.144 +	}
  98.145 +
  98.146 +	ElementCollection GetCollection(const std::string& index) const {
  98.147 +		return elements.equal_range(index);
  98.148 +	}
  98.149 +
  98.150 +	const ElementMap& Elements() const	{
  98.151 +		return elements;
  98.152 +	}
  98.153 +
  98.154 +private:
  98.155 +
  98.156 +	ElementMap elements;
  98.157 +};
  98.158 +
  98.159 +
  98.160 +/** FBX parsing class, takes a list of input tokens and generates a hierarchy
  98.161 + *  of nested #Scope instances, representing the fbx DOM.*/
  98.162 +class Parser 
  98.163 +{
  98.164 +public:
  98.165 +	
  98.166 +	/** Parse given a token list. Does not take ownership of the tokens -
  98.167 +	 *  the objects must persist during the entire parser lifetime */
  98.168 +	Parser (const TokenList& tokens,bool is_binary);
  98.169 +	~Parser();
  98.170 +
  98.171 +public:
  98.172 +
  98.173 +	const Scope& GetRootScope() const {
  98.174 +		return *root.get();
  98.175 +	}
  98.176 +
  98.177 +
  98.178 +	bool IsBinary() const {
  98.179 +		return is_binary;
  98.180 +	}
  98.181 +
  98.182 +private:
  98.183 +
  98.184 +	friend class Scope;
  98.185 +	friend class Element;
  98.186 +
  98.187 +	TokenPtr AdvanceToNextToken();
  98.188 +
  98.189 +	TokenPtr LastToken() const;
  98.190 +	TokenPtr CurrentToken() const;
  98.191 +
  98.192 +	
  98.193 +
  98.194 +private:
  98.195 +
  98.196 +	const TokenList& tokens;
  98.197 +	
  98.198 +	TokenPtr last, current;
  98.199 +	TokenList::const_iterator cursor;
  98.200 +	boost::scoped_ptr<Scope> root;
  98.201 +
  98.202 +	const bool is_binary;
  98.203 +};
  98.204 +
  98.205 +
  98.206 +/* token parsing - this happens when building the DOM out of the parse-tree*/
  98.207 +uint64_t ParseTokenAsID(const Token& t, const char*& err_out);
  98.208 +size_t ParseTokenAsDim(const Token& t, const char*& err_out);
  98.209 +
  98.210 +float ParseTokenAsFloat(const Token& t, const char*& err_out);
  98.211 +int ParseTokenAsInt(const Token& t, const char*& err_out);
  98.212 +std::string ParseTokenAsString(const Token& t, const char*& err_out);
  98.213 +
  98.214 +
  98.215 +/* wrapper around ParseTokenAsXXX() with DOMError handling */
  98.216 +uint64_t ParseTokenAsID(const Token& t);
  98.217 +size_t ParseTokenAsDim(const Token& t);
  98.218 +float ParseTokenAsFloat(const Token& t);
  98.219 +int ParseTokenAsInt(const Token& t);
  98.220 +std::string ParseTokenAsString(const Token& t);
  98.221 +
  98.222 +/* read data arrays */
  98.223 +void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el);
  98.224 +void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el);
  98.225 +void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el);
  98.226 +void ParseVectorDataArray(std::vector<int>& out, const Element& el);
  98.227 +void ParseVectorDataArray(std::vector<float>& out, const Element& el);
  98.228 +void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el);
  98.229 +void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e);
  98.230 +
  98.231 +
  98.232 +
  98.233 +// extract a required element from a scope, abort if the element cannot be found
  98.234 +const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL);
  98.235 +
  98.236 +// extract required compound scope
  98.237 +const Scope& GetRequiredScope(const Element& el);
  98.238 +// get token at a particular index
  98.239 +const Token& GetRequiredToken(const Element& el, unsigned int index);
  98.240 +
  98.241 +
  98.242 +
  98.243 +// read a 4x4 matrix from an array of 16 floats
  98.244 +aiMatrix4x4 ReadMatrix(const Element& element);
  98.245 +
  98.246 +} // ! FBX
  98.247 +} // ! Assimp
  98.248 +
  98.249 +#endif // ! INCLUDED_AI_FBX_PARSER_H
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/libs/assimp/FBXProperties.cpp	Sat Feb 01 19:58:19 2014 +0200
    99.3 @@ -0,0 +1,207 @@
    99.4 +/*
    99.5 +Open Asset Import Library (assimp)
    99.6 +----------------------------------------------------------------------
    99.7 +
    99.8 +Copyright (c) 2006-2012, assimp team
    99.9 +All rights reserved.
   99.10 +
   99.11 +Redistribution and use of this software in source and binary forms, 
   99.12 +with or without modification, are permitted provided that the 
   99.13 +following conditions are met:
   99.14 +
   99.15 +* Redistributions of source code must retain the above
   99.16 +  copyright notice, this list of conditions and the
   99.17 +  following disclaimer.
   99.18 +
   99.19 +* Redistributions in binary form must reproduce the above
   99.20 +  copyright notice, this list of conditions and the
   99.21 +  following disclaimer in the documentation and/or other
   99.22 +  materials provided with the distribution.
   99.23 +
   99.24 +* Neither the name of the assimp team, nor the names of its
   99.25 +  contributors may be used to endorse or promote products
   99.26 +  derived from this software without specific prior
   99.27 +  written permission of the assimp team.
   99.28 +
   99.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   99.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   99.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   99.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   99.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   99.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   99.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   99.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   99.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   99.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   99.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   99.40 +
   99.41 +----------------------------------------------------------------------
   99.42 +*/
   99.43 +
   99.44 +/** @file  FBXProperties.cpp
   99.45 + *  @brief Implementation of the FBX dynamic properties system
   99.46 + */
   99.47 +#include "AssimpPCH.h"
   99.48 +
   99.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
   99.50 +
   99.51 +#include "FBXTokenizer.h"
   99.52 +#include "FBXParser.h"
   99.53 +#include "FBXDocument.h"
   99.54 +#include "FBXDocumentUtil.h"
   99.55 +#include "FBXProperties.h"
   99.56 +
   99.57 +namespace Assimp {
   99.58 +namespace FBX {
   99.59 +
   99.60 +	using namespace Util;
   99.61 +
   99.62 +// ------------------------------------------------------------------------------------------------
   99.63 +Property::Property()
   99.64 +{
   99.65 +}
   99.66 +
   99.67 +// ------------------------------------------------------------------------------------------------
   99.68 +Property::~Property()
   99.69 +{
   99.70 +}
   99.71 +
   99.72 +namespace {
   99.73 +
   99.74 +// ------------------------------------------------------------------------------------------------
   99.75 +// read a typed property out of a FBX element. The return value is NULL if the property cannot be read.
   99.76 +Property* ReadTypedProperty(const Element& element)
   99.77 +{
   99.78 +	ai_assert(element.KeyToken().StringContents() == "P");
   99.79 +
   99.80 +	const TokenList& tok = element.Tokens();
   99.81 +	ai_assert(tok.size() >= 5);
   99.82 +
   99.83 +	const std::string& s = ParseTokenAsString(*tok[1]);
   99.84 +	const char* const cs = s.c_str();
   99.85 +	if (!strcmp(cs,"KString")) {
   99.86 +		return new TypedProperty<std::string>(ParseTokenAsString(*tok[4]));
   99.87 +	}
   99.88 +	else if (!strcmp(cs,"bool") || !strcmp(cs,"Bool")) {
   99.89 +		return new TypedProperty<bool>(ParseTokenAsInt(*tok[4]) != 0);
   99.90 +	}
   99.91 +	else if (!strcmp(cs,"int") || !strcmp(cs,"enum")) {
   99.92 +		return new TypedProperty<int>(ParseTokenAsInt(*tok[4]));
   99.93 +	}
   99.94 +	else if (!strcmp(cs,"ULongLong")) {
   99.95 +		return new TypedProperty<uint64_t>(ParseTokenAsID(*tok[4]));
   99.96 +	}
   99.97 +	else if (!strcmp(cs,"Vector3D") || 
   99.98 +		!strcmp(cs,"ColorRGB") || 
   99.99 +		!strcmp(cs,"Vector") || 
  99.100 +		!strcmp(cs,"Color") || 
  99.101 +		!strcmp(cs,"Lcl Translation") || 
  99.102 +		!strcmp(cs,"Lcl Rotation") || 
  99.103 +		!strcmp(cs,"Lcl Scaling")
  99.104 +		) {
  99.105 +		return new TypedProperty<aiVector3D>(aiVector3D(
  99.106 +			ParseTokenAsFloat(*tok[4]),
  99.107 +			ParseTokenAsFloat(*tok[5]),
  99.108 +			ParseTokenAsFloat(*tok[6]))
  99.109 +		);
  99.110 +	}
  99.111 +	else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"KTime") || !strcmp(cs,"Float")) {
  99.112 +		return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
  99.113 +	}
  99.114 +	return NULL;
  99.115 +}
  99.116 +
  99.117 +
  99.118 +// ------------------------------------------------------------------------------------------------
  99.119 +// peek into an element and check if it contains a FBX property, if so return its name.
  99.120 +std::string PeekPropertyName(const Element& element)
  99.121 +{
  99.122 +	ai_assert(element.KeyToken().StringContents() == "P");
  99.123 +	const TokenList& tok = element.Tokens();
  99.124 +	if(tok.size() < 4) {
  99.125 +		return "";
  99.126 +	}
  99.127 +
  99.128 +	return ParseTokenAsString(*tok[0]);
  99.129 +}
  99.130 +
  99.131 +} //! anon
  99.132 +
  99.133 +
  99.134 +// ------------------------------------------------------------------------------------------------
  99.135 +PropertyTable::PropertyTable()
  99.136 +: templateProps()
  99.137 +, element()
  99.138 +{
  99.139 +}
  99.140 +
  99.141 +
  99.142 +// ------------------------------------------------------------------------------------------------
  99.143 +PropertyTable::PropertyTable(const Element& element, boost::shared_ptr<const PropertyTable> templateProps)
  99.144 +: templateProps(templateProps)
  99.145 +, element(&element)
  99.146 +{
  99.147 +	const Scope& scope = GetRequiredScope(element);
  99.148 +	BOOST_FOREACH(const ElementMap::value_type& v, scope.Elements()) {
  99.149 +		if(v.first != "P") {
  99.150 +			DOMWarning("expected only P elements in property table",v.second);
  99.151 +			continue;
  99.152 +		}
  99.153 +
  99.154 +		const std::string& name = PeekPropertyName(*v.second);
  99.155 +		if(!name.length()) {
  99.156 +			DOMWarning("could not read property name",v.second);
  99.157 +			continue;
  99.158 +		}
  99.159 +
  99.160 +		LazyPropertyMap::const_iterator it = lazyProps.find(name);
  99.161 +		if (it != lazyProps.end()) {
  99.162 +			DOMWarning("duplicate property name, will hide previous value: " + name,v.second);
  99.163 +			continue;
  99.164 +		}
  99.165 +
  99.166 +		lazyProps[name] = v.second;
  99.167 +	}
  99.168 +}
  99.169 +
  99.170 +
  99.171 +// ------------------------------------------------------------------------------------------------
  99.172 +PropertyTable::~PropertyTable()
  99.173 +{
  99.174 +	BOOST_FOREACH(PropertyMap::value_type& v, props) {
  99.175 +		delete v.second;
  99.176 +	}
  99.177 +}
  99.178 +
  99.179 +
  99.180 +// ------------------------------------------------------------------------------------------------
  99.181 +const Property* PropertyTable::Get(const std::string& name) const
  99.182 +{
  99.183 +	PropertyMap::const_iterator it = props.find(name);
  99.184 +	if (it == props.end()) {
  99.185 +		// hasn't been parsed yet?
  99.186 +		LazyPropertyMap::const_iterator lit = lazyProps.find(name);
  99.187 +		if(lit != lazyProps.end()) {
  99.188 +			props[name] = ReadTypedProperty(*(*lit).second);
  99.189 +			it = props.find(name);
  99.190 +
  99.191 +			ai_assert(it != props.end());
  99.192 +		}
  99.193 +
  99.194 +		if (it == props.end()) {
  99.195 +			// check property template
  99.196 +			if(templateProps) {
  99.197 +				return templateProps->Get(name);
  99.198 +			}
  99.199 +
  99.200 +			return NULL;
  99.201 +		}
  99.202 +	}
  99.203 +	
  99.204 +	return (*it).second;
  99.205 +}
  99.206 +
  99.207 +} //! FBX
  99.208 +} //! Assimp
  99.209 +
  99.210 +#endif
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/libs/assimp/FBXProperties.h	Sat Feb 01 19:58:19 2014 +0200
   100.3 @@ -0,0 +1,188 @@
   100.4 +/*
   100.5 +Open Asset Import Library (assimp)
   100.6 +----------------------------------------------------------------------
   100.7 +
   100.8 +Copyright (c) 2006-2012, assimp team
   100.9 +All rights reserved.
  100.10 +
  100.11 +Redistribution and use of this software in source and binary forms, 
  100.12 +with or without modification, are permitted provided that the 
  100.13 +following conditions are met:
  100.14 +
  100.15 +* Redistributions of source code must retain the above
  100.16 +  copyright notice, this list of conditions and the
  100.17 +  following disclaimer.
  100.18 +
  100.19 +* Redistributions in binary form must reproduce the above
  100.20 +  copyright notice, this list of conditions and the
  100.21 +  following disclaimer in the documentation and/or other
  100.22 +  materials provided with the distribution.
  100.23 +
  100.24 +* Neither the name of the assimp team, nor the names of its
  100.25 +  contributors may be used to endorse or promote products
  100.26 +  derived from this software without specific prior
  100.27 +  written permission of the assimp team.
  100.28 +
  100.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  100.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  100.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  100.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  100.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  100.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  100.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  100.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  100.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  100.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  100.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  100.40 +
  100.41 +----------------------------------------------------------------------
  100.42 +*/
  100.43 +
  100.44 +/** @file  FBXProperties.h
  100.45 + *  @brief FBX dynamic properties 
  100.46 + */
  100.47 +#ifndef INCLUDED_AI_FBX_PROPERTIES_H
  100.48 +#define INCLUDED_AI_FBX_PROPERTIES_H
  100.49 +
  100.50 +#include <map>
  100.51 +#include <string>
  100.52 +
  100.53 +namespace Assimp {
  100.54 +namespace FBX {
  100.55 +
  100.56 +	class Element;
  100.57 +
  100.58 +
  100.59 +/** Represents a dynamic property. Type info added by deriving classes,
  100.60 + *  see #TypedProperty.
  100.61 + Example:
  100.62 + @verbatim
  100.63 +   P: "ShininessExponent", "double", "Number", "",0.5
  100.64 + @endvebatim
  100.65 +
  100.66 +*/
  100.67 +class Property
  100.68 +{
  100.69 +protected:
  100.70 +
  100.71 +	Property();
  100.72 +
  100.73 +public:
  100.74 +
  100.75 +	virtual ~Property();
  100.76 +
  100.77 +public:
  100.78 +
  100.79 +	template <typename T>
  100.80 +	const T* As() const {
  100.81 +		return dynamic_cast<const T*>(this);
  100.82 +	}
  100.83 +};
  100.84 +
  100.85 +
  100.86 +template<typename T>
  100.87 +class TypedProperty : public Property
  100.88 +{
  100.89 +public:
  100.90 +
  100.91 +	TypedProperty(const T& value) 
  100.92 +		: value(value)
  100.93 +	{
  100.94 +	}
  100.95 +
  100.96 +public:
  100.97 +
  100.98 +	const T& Value() const {
  100.99 +		return value;
 100.100 +	}
 100.101 +
 100.102 +private:
 100.103 +	T value;
 100.104 +};
 100.105 +
 100.106 +
 100.107 +typedef std::fbx_unordered_map<std::string,const Property*> PropertyMap;
 100.108 +typedef std::fbx_unordered_map<std::string,const Element*> LazyPropertyMap;
 100.109 +
 100.110 +/** Represents a property table as can be found in the newer FBX files (Properties60, Properties70)*/
 100.111 +class PropertyTable
 100.112 +{
 100.113 +public:
 100.114 +
 100.115 +	// in-memory property table with no source element
 100.116 +	PropertyTable();
 100.117 +	
 100.118 +	PropertyTable(const Element& element, boost::shared_ptr<const PropertyTable> templateProps);
 100.119 +	~PropertyTable();
 100.120 +
 100.121 +public:
 100.122 +
 100.123 +	const Property* Get(const std::string& name) const;
 100.124 +
 100.125 +	// PropertyTable's need not be coupled with FBX elements so this can be NULL
 100.126 +	const Element* GetElement() const {
 100.127 +		return element;
 100.128 +	}
 100.129 +
 100.130 +	const PropertyTable* TemplateProps() const {
 100.131 +		return templateProps.get();
 100.132 +	}
 100.133 +
 100.134 +private:
 100.135 +
 100.136 +	LazyPropertyMap lazyProps;
 100.137 +	mutable PropertyMap props;
 100.138 +	const boost::shared_ptr<const PropertyTable> templateProps;
 100.139 +	const Element* const element;
 100.140 +};
 100.141 +
 100.142 +
 100.143 +// ------------------------------------------------------------------------------------------------
 100.144 +template <typename T>
 100.145 +inline T PropertyGet(const PropertyTable& in, const std::string& name, 
 100.146 +	const T& defaultValue, 
 100.147 +	bool ignoreTemplate = false)
 100.148 +{
 100.149 +	const Property* const prop = in.Get(name);
 100.150 +	if(!prop) {
 100.151 +		return defaultValue;
 100.152 +	}
 100.153 +
 100.154 +	// strong typing, no need to be lenient 
 100.155 +	const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
 100.156 +	if(!tprop) {
 100.157 +		return defaultValue;
 100.158 +	}
 100.159 +
 100.160 +	return tprop->Value();
 100.161 +}
 100.162 +
 100.163 +
 100.164 +// ------------------------------------------------------------------------------------------------
 100.165 +template <typename T>
 100.166 +inline T PropertyGet(const PropertyTable& in, const std::string& name, 
 100.167 +	bool& result, 
 100.168 +	bool ignoreTemplate = false)
 100.169 +{
 100.170 +	const Property* const prop = in.Get(name);
 100.171 +	if(!prop) {
 100.172 +		result = false;
 100.173 +		return T();
 100.174 +	}
 100.175 +
 100.176 +	// strong typing, no need to be lenient 
 100.177 +	const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
 100.178 +	if(!tprop) {
 100.179 +		result = false;
 100.180 +		return T();
 100.181 +	}
 100.182 +
 100.183 +	result = true;
 100.184 +	return tprop->Value();
 100.185 +}
 100.186 +
 100.187 +
 100.188 +} //! FBX
 100.189 +} //! Assimp
 100.190 +
 100.191 +#endif //
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/libs/assimp/FBXTokenizer.cpp	Sat Feb 01 19:58:19 2014 +0200
   101.3 @@ -0,0 +1,246 @@
   101.4 +/*
   101.5 +Open Asset Import Library (assimp)
   101.6 +----------------------------------------------------------------------
   101.7 +
   101.8 +Copyright (c) 2006-2012, assimp team
   101.9 +All rights reserved.
  101.10 +
  101.11 +Redistribution and use of this software in source and binary forms, 
  101.12 +with or without modification, are permitted provided that the 
  101.13 +following conditions are met:
  101.14 +
  101.15 +* Redistributions of source code must retain the above
  101.16 +  copyright notice, this list of conditions and the
  101.17 +  following disclaimer.
  101.18 +
  101.19 +* Redistributions in binary form must reproduce the above
  101.20 +  copyright notice, this list of conditions and the
  101.21 +  following disclaimer in the documentation and/or other
  101.22 +  materials provided with the distribution.
  101.23 +
  101.24 +* Neither the name of the assimp team, nor the names of its
  101.25 +  contributors may be used to endorse or promote products
  101.26 +  derived from this software without specific prior
  101.27 +  written permission of the assimp team.
  101.28 +
  101.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  101.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  101.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  101.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  101.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  101.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  101.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  101.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  101.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  101.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  101.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  101.40 +
  101.41 +----------------------------------------------------------------------
  101.42 +*/
  101.43 +
  101.44 +/** @file  FBXTokenizer.cpp
  101.45 + *  @brief Implementation of the FBX broadphase lexer
  101.46 + */
  101.47 +#include "AssimpPCH.h"
  101.48 +
  101.49 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
  101.50 +
  101.51 +// tab width for logging columns
  101.52 +#define ASSIMP_FBX_TAB_WIDTH 4
  101.53 +
  101.54 +#include "ParsingUtils.h"
  101.55 +
  101.56 +#include "FBXTokenizer.h"
  101.57 +#include "FBXUtil.h"
  101.58 +
  101.59 +namespace Assimp {
  101.60 +namespace FBX {
  101.61 +
  101.62 +// ------------------------------------------------------------------------------------------------
  101.63 +Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column)
  101.64 +	: sbegin(sbegin)
  101.65 +	, send(send)
  101.66 +	, type(type)
  101.67 +	, line(line)
  101.68 +	, column(column)
  101.69 +#ifdef DEBUG
  101.70 +	, contents(sbegin, static_cast<size_t>(send-sbegin))
  101.71 +#endif
  101.72 +{
  101.73 +	ai_assert(sbegin);
  101.74 +	ai_assert(send);
  101.75 +
  101.76 +	// tokens must be of non-zero length
  101.77 +	ai_assert(static_cast<size_t>(send-sbegin) > 0);
  101.78 +}
  101.79 +
  101.80 +
  101.81 +// ------------------------------------------------------------------------------------------------
  101.82 +Token::~Token()
  101.83 +{
  101.84 +}
  101.85 +
  101.86 +
  101.87 +namespace {
  101.88 +
  101.89 +// ------------------------------------------------------------------------------------------------
  101.90 +// signal tokenization error, this is always unrecoverable. Throws DeadlyImportError.
  101.91 +void TokenizeError(const std::string& message, unsigned int line, unsigned int column)
  101.92 +{
  101.93 +	throw DeadlyImportError(Util::AddLineAndColumn("FBX-Tokenize",message,line,column));
  101.94 +}
  101.95 +
  101.96 +
  101.97 +// process a potential data token up to 'cur', adding it to 'output_tokens'. 
  101.98 +// ------------------------------------------------------------------------------------------------
  101.99 +void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*& end,
 101.100 +					  unsigned int line, 
 101.101 +					  unsigned int column, 
 101.102 +					  TokenType type = TokenType_DATA,
 101.103 +					  bool must_have_token = false)
 101.104 +{
 101.105 +	if (start && end) {
 101.106 +		// sanity check:
 101.107 +		// tokens should have no whitespace outside quoted text and [start,end] should
 101.108 +		// properly delimit the valid range.
 101.109 +		bool in_double_quotes = false;
 101.110 +		for (const char* c = start; c != end + 1; ++c) {
 101.111 +			if (*c == '\"') {
 101.112 +				in_double_quotes = !in_double_quotes;
 101.113 +			}
 101.114 +
 101.115 +			if (!in_double_quotes && IsSpaceOrNewLine(*c)) {
 101.116 +				TokenizeError("unexpected whitespace in token", line, column);
 101.117 +			}
 101.118 +		}
 101.119 +
 101.120 +		if (in_double_quotes) {
 101.121 +			TokenizeError("non-terminated double quotes", line, column);
 101.122 +		}
 101.123 +
 101.124 +		output_tokens.push_back(new_Token(start,end + 1,type,line,column));
 101.125 +	}
 101.126 +	else if (must_have_token) {
 101.127 +		TokenizeError("unexpected character, expected data token", line, column);
 101.128 +	}
 101.129 +
 101.130 +	start = end = NULL;
 101.131 +}
 101.132 +
 101.133 +}
 101.134 +
 101.135 +// ------------------------------------------------------------------------------------------------
 101.136 +void Tokenize(TokenList& output_tokens, const char* input)
 101.137 +{
 101.138 +	ai_assert(input);
 101.139 +
 101.140 +	// line and column numbers numbers are one-based
 101.141 +	unsigned int line = 1;
 101.142 +	unsigned int column = 1;
 101.143 +
 101.144 +	bool comment = false;
 101.145 +	bool in_double_quotes = false;
 101.146 +	bool pending_data_token = false;
 101.147 +	
 101.148 +	const char* token_begin = NULL, *token_end = NULL;
 101.149 +	for (const char* cur = input;*cur;column += (*cur == '\t' ? ASSIMP_FBX_TAB_WIDTH : 1), ++cur) {
 101.150 +		const char c = *cur;
 101.151 +
 101.152 +		if (IsLineEnd(c)) {
 101.153 +			comment = false;
 101.154 +
 101.155 +			column = 0;
 101.156 +			++line;
 101.157 +		}
 101.158 +
 101.159 +		if(comment) {
 101.160 +			continue;
 101.161 +		}
 101.162 +
 101.163 +		if(in_double_quotes) {
 101.164 +			if (c == '\"') {
 101.165 +				in_double_quotes = false;
 101.166 +				token_end = cur;
 101.167 +
 101.168 +				ProcessDataToken(output_tokens,token_begin,token_end,line,column);
 101.169 +				pending_data_token = false;
 101.170 +			}
 101.171 +			continue;
 101.172 +		}
 101.173 +
 101.174 +		switch(c)
 101.175 +		{
 101.176 +		case '\"':
 101.177 +			if (token_begin) {
 101.178 +				TokenizeError("unexpected double-quote", line, column);
 101.179 +			}
 101.180 +			token_begin = cur;
 101.181 +			in_double_quotes = true;
 101.182 +			continue;
 101.183 +
 101.184 +		case ';':
 101.185 +			ProcessDataToken(output_tokens,token_begin,token_end,line,column);
 101.186 +			comment = true;
 101.187 +			continue;
 101.188 +
 101.189 +		case '{':
 101.190 +			ProcessDataToken(output_tokens,token_begin,token_end, line, column);
 101.191 +			output_tokens.push_back(new_Token(cur,cur+1,TokenType_OPEN_BRACKET,line,column));
 101.192 +			continue;
 101.193 +
 101.194 +		case '}':
 101.195 +			ProcessDataToken(output_tokens,token_begin,token_end,line,column);
 101.196 +			output_tokens.push_back(new_Token(cur,cur+1,TokenType_CLOSE_BRACKET,line,column));
 101.197 +			continue;
 101.198 +		
 101.199 +		case ',':
 101.200 +			if (pending_data_token) {
 101.201 +				ProcessDataToken(output_tokens,token_begin,token_end,line,column,TokenType_DATA,true);
 101.202 +			}
 101.203 +			output_tokens.push_back(new_Token(cur,cur+1,TokenType_COMMA,line,column));
 101.204 +			continue;
 101.205 +
 101.206 +		case ':':
 101.207 +			if (pending_data_token) {
 101.208 +				ProcessDataToken(output_tokens,token_begin,token_end,line,column,TokenType_KEY,true);
 101.209 +			}
 101.210 +			else {
 101.211 +				TokenizeError("unexpected colon", line, column);
 101.212 +			}
 101.213 +			continue;
 101.214 +		}
 101.215 +		
 101.216 +		if (IsSpaceOrNewLine(c)) {
 101.217 +
 101.218 +			if (token_begin) {
 101.219 +				// peek ahead and check if the next token is a colon in which
 101.220 +				// case this counts as KEY token.
 101.221 +				TokenType type = TokenType_DATA;
 101.222 +				for (const char* peek = cur;  *peek && IsSpaceOrNewLine(*peek); ++peek) {
 101.223 +					if (*peek == ':') {
 101.224 +						type = TokenType_KEY;
 101.225 +						cur = peek;
 101.226 +						break;
 101.227 +					}
 101.228 +				}
 101.229 +
 101.230 +				ProcessDataToken(output_tokens,token_begin,token_end,line,column,type);
 101.231 +			}
 101.232 +
 101.233 +			pending_data_token = false;
 101.234 +		}
 101.235 +		else {
 101.236 +			token_end = cur;
 101.237 +			if (!token_begin) {
 101.238 +				token_begin = cur;
 101.239 +			}
 101.240 +
 101.241 +			pending_data_token = true;
 101.242 +		}
 101.243 +	}
 101.244 +}
 101.245 +
 101.246 +} // !FBX
 101.247 +} // !Assimp
 101.248 +
 101.249 +#endif
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/libs/assimp/FBXTokenizer.h	Sat Feb 01 19:58:19 2014 +0200
   102.3 @@ -0,0 +1,190 @@
   102.4 +/*
   102.5 +Open Asset Import Library (assimp)
   102.6 +----------------------------------------------------------------------
   102.7 +
   102.8 +Copyright (c) 2006-2012, assimp team
   102.9 +All rights reserved.
  102.10 +
  102.11 +Redistribution and use of this software in source and binary forms, 
  102.12 +with or without modification, are permitted provided that the 
  102.13 +following conditions are met:
  102.14 +
  102.15 +* Redistributions of source code must retain the above
  102.16 +  copyright notice, this list of conditions and the
  102.17 +  following disclaimer.
  102.18 +
  102.19 +* Redistributions in binary form must reproduce the above
  102.20 +  copyright notice, this list of conditions and the
  102.21 +  following disclaimer in the documentation and/or other
  102.22 +  materials provided with the distribution.
  102.23 +
  102.24 +* Neither the name of the assimp team, nor the names of its
  102.25 +  contributors may be used to endorse or promote products
  102.26 +  derived from this software without specific prior
  102.27 +  written permission of the assimp team.
  102.28 +
  102.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  102.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  102.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  102.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  102.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  102.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  102.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  102.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  102.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  102.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  102.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  102.40 +
  102.41 +----------------------------------------------------------------------
  102.42 +*/
  102.43 +
  102.44 +/** @file  FBXTokenizer.h
  102.45 + *  @brief FBX lexer
  102.46 + */
  102.47 +#ifndef INCLUDED_AI_FBX_TOKENIZER_H
  102.48 +#define INCLUDED_AI_FBX_TOKENIZER_H
  102.49 +
  102.50 +#include <boost/shared_ptr.hpp>
  102.51 +
  102.52 +#include "FBXCompileConfig.h"
  102.53 +
  102.54 +namespace Assimp {
  102.55 +namespace FBX {
  102.56 +
  102.57 +/** Rough classification for text FBX tokens used for constructing the
  102.58 + *  basic scope hierarchy. */
  102.59 +enum TokenType
  102.60 +{
  102.61 +	// {
  102.62 +	TokenType_OPEN_BRACKET = 0,
  102.63 +	
  102.64 +	// }
  102.65 +	TokenType_CLOSE_BRACKET,
  102.66 +
  102.67 +	// '"blablubb"', '2', '*14' - very general token class,
  102.68 +	// further processing happens at a later stage.
  102.69 +	TokenType_DATA,
  102.70 +
  102.71 +	//
  102.72 +	TokenType_BINARY_DATA,
  102.73 +
  102.74 +	// ,
  102.75 +	TokenType_COMMA,
  102.76 +
  102.77 +	// blubb:
  102.78 +	TokenType_KEY
  102.79 +};
  102.80 +
  102.81 +
  102.82 +/** Represents a single token in a FBX file. Tokens are
  102.83 + *  classified by the #TokenType enumerated types.
  102.84 + *
  102.85 + *  Offers iterator protocol. Tokens are immutable. */
  102.86 +class Token 
  102.87 +{
  102.88 +
  102.89 +private:
  102.90 +
  102.91 +	static const unsigned int BINARY_MARKER = static_cast<unsigned int>(-1);
  102.92 +
  102.93 +public:
  102.94 +
  102.95 +	/** construct a textual token */
  102.96 +	Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column);
  102.97 +
  102.98 +	/** construct a binary token */
  102.99 +	Token(const char* sbegin, const char* send, TokenType type, unsigned int offset);
 102.100 +
 102.101 +	~Token();
 102.102 +
 102.103 +public:
 102.104 +
 102.105 +	std::string StringContents() const {
 102.106 +		return std::string(begin(),end());
 102.107 +	}
 102.108 +
 102.109 +public:
 102.110 +
 102.111 +	bool IsBinary() const {
 102.112 +		return column == BINARY_MARKER;
 102.113 +	}
 102.114 +
 102.115 +	const char* begin() const {
 102.116 +		return sbegin;
 102.117 +	}
 102.118 +
 102.119 +	const char* end() const {
 102.120 +		return send;
 102.121 +	}
 102.122 +
 102.123 +	TokenType Type() const {
 102.124 +		return type;
 102.125 +	}
 102.126 +
 102.127 +	unsigned int Offset() const {
 102.128 +		ai_assert(IsBinary());
 102.129 +		return offset;
 102.130 +	}
 102.131 +
 102.132 +	unsigned int Line() const {
 102.133 +		ai_assert(!IsBinary());
 102.134 +		return line;
 102.135 +	}
 102.136 +
 102.137 +	unsigned int Column() const {
 102.138 +		ai_assert(!IsBinary());
 102.139 +		return column;
 102.140 +	}
 102.141 +
 102.142 +private:
 102.143 +
 102.144 +#ifdef DEBUG
 102.145 +	// full string copy for the sole purpose that it nicely appears
 102.146 +	// in msvc's debugger window.
 102.147 +	const std::string contents;
 102.148 +#endif
 102.149 +
 102.150 +
 102.151 +	const char* const sbegin;
 102.152 +	const char* const send;
 102.153 +	const TokenType type;
 102.154 +
 102.155 +	union {
 102.156 +		const unsigned int line;
 102.157 +		unsigned int offset;
 102.158 +	};
 102.159 +	const unsigned int column;
 102.160 +};
 102.161 +
 102.162 +// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03
 102.163 +typedef const Token* TokenPtr;
 102.164 +typedef std::vector< TokenPtr > TokenList;
 102.165 +
 102.166 +#define new_Token new Token
 102.167 +
 102.168 +
 102.169 +/** Main FBX tokenizer function. Transform input buffer into a list of preprocessed tokens.
 102.170 + *
 102.171 + *  Skips over comments and generates line and column numbers.
 102.172 + *
 102.173 + * @param output_tokens Receives a list of all tokens in the input data.
 102.174 + * @param input_buffer Textual input buffer to be processed, 0-terminated.
 102.175 + * @throw DeadlyImportError if something goes wrong */
 102.176 +void Tokenize(TokenList& output_tokens, const char* input);
 102.177 +
 102.178 +
 102.179 +/** Tokenizer function for binary FBX files.
 102.180 + *
 102.181 + *  Emits a token list suitable for direct parsing.
 102.182 + *
 102.183 + * @param output_tokens Receives a list of all tokens in the input data.
 102.184 + * @param input_buffer Binary input buffer to be processed.
 102.185 + * @param length Length of input buffer, in bytes. There is no 0-terminal.
 102.186 + * @throw DeadlyImportError if something goes wrong */
 102.187 +void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length);
 102.188 +
 102.189 +
 102.190 +} // ! FBX
 102.191 +} // ! Assimp
 102.192 +
 102.193 +#endif // ! INCLUDED_AI_FBX_PARSER_H
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/libs/assimp/FBXUtil.cpp	Sat Feb 01 19:58:19 2014 +0200
   103.3 @@ -0,0 +1,119 @@
   103.4 +/*
   103.5 +Open Asset Import Library (assimp)
   103.6 +----------------------------------------------------------------------
   103.7 +
   103.8 +Copyright (c) 2006-2012, assimp team
   103.9 +All rights reserved.
  103.10 +
  103.11 +Redistribution and use of this software in source and binary forms, 
  103.12 +with or without modification, are permitted provided that the 
  103.13 +following conditions are met:
  103.14 +
  103.15 +* Redistributions of source code must retain the above
  103.16 +  copyright notice, this list of conditions and the
  103.17 +  following disclaimer.
  103.18 +
  103.19 +* Redistributions in binary form must reproduce the above
  103.20 +  copyright notice, this list of conditions and the
  103.21 +  following disclaimer in the documentation and/or other
  103.22 +  materials provided with the distribution.
  103.23 +
  103.24 +* Neither the name of the assimp team, nor the names of its
  103.25 +  contributors may be used to endorse or promote products
  103.26 +  derived from this software without specific prior
  103.27 +  written permission of the assimp team.
  103.28 +
  103.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  103.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  103.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  103.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  103.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  103.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  103.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  103.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  103.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  103.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  103.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  103.40 +
  103.41 +----------------------------------------------------------------------
  103.42 +*/
  103.43 +
  103.44 +/** @file  FBXUtil.cpp
  103.45 + *  @brief Implementation of internal FBX utility functions
  103.46 + */
  103.47 +#include "AssimpPCH.h"
  103.48 +
  103.49 +#include "FBXUtil.h"
  103.50 +#include "FBXTokenizer.h"
  103.51 +
  103.52 +#include "TinyFormatter.h"
  103.53 +
  103.54 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
  103.55 +
  103.56 +namespace Assimp {
  103.57 +namespace FBX {
  103.58 +namespace Util {
  103.59 +
  103.60 +// ------------------------------------------------------------------------------------------------
  103.61 +const char* TokenTypeString(TokenType t)
  103.62 +{
  103.63 +	switch(t) {
  103.64 +		case TokenType_OPEN_BRACKET:
  103.65 +			return "TOK_OPEN_BRACKET";
  103.66 +	
  103.67 +		case TokenType_CLOSE_BRACKET:
  103.68 +			return "TOK_CLOSE_BRACKET";
  103.69 +
  103.70 +		case TokenType_DATA:
  103.71 +			return "TOK_DATA";
  103.72 +
  103.73 +		case TokenType_COMMA:
  103.74 +			return "TOK_COMMA";
  103.75 +
  103.76 +		case TokenType_KEY:
  103.77 +			return "TOK_KEY";
  103.78 +
  103.79 +		case TokenType_BINARY_DATA:
  103.80 +			return "TOK_BINARY_DATA";
  103.81 +	}
  103.82 +
  103.83 +	ai_assert(false);
  103.84 +	return "";
  103.85 +}
  103.86 +	
  103.87 +
  103.88 +// ------------------------------------------------------------------------------------------------
  103.89 +std::string AddOffset(const std::string& prefix, const std::string& text, unsigned int offset)
  103.90 +{
  103.91 +	return static_cast<std::string>( (Formatter::format(),prefix," (offset 0x",std::hex,offset,") ",text) );
  103.92 +}
  103.93 +
  103.94 +// ------------------------------------------------------------------------------------------------
  103.95 +std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column)
  103.96 +{
  103.97 +	return static_cast<std::string>( (Formatter::format(),prefix," (line ",line,", col ",column,") ",text) );
  103.98 +}
  103.99 +
 103.100 +// ------------------------------------------------------------------------------------------------
 103.101 +std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok)
 103.102 +{
 103.103 +	if(tok->IsBinary()) {
 103.104 +		return static_cast<std::string>( (Formatter::format(),prefix,
 103.105 +			" (",TokenTypeString(tok->Type()),
 103.106 +			", offset 0x", std::hex, tok->Offset(),") ",
 103.107 +			text) );
 103.108 +	}
 103.109 +	
 103.110 +	return static_cast<std::string>( (Formatter::format(),prefix,
 103.111 +		" (",TokenTypeString(tok->Type()),
 103.112 +		", line ",tok->Line(),
 103.113 +		", col ",tok->Column(),") ",
 103.114 +		text) );
 103.115 +}
 103.116 +
 103.117 +} // !Util
 103.118 +} // !FBX
 103.119 +} // !Assimp
 103.120 +
 103.121 +#endif
 103.122 +
   104.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.2 +++ b/libs/assimp/FBXUtil.h	Sat Feb 01 19:58:19 2014 +0200
   104.3 @@ -0,0 +1,104 @@
   104.4 +/*
   104.5 +Open Asset Import Library (assimp)
   104.6 +----------------------------------------------------------------------
   104.7 +
   104.8 +Copyright (c) 2006-2012, assimp team
   104.9 +All rights reserved.
  104.10 +
  104.11 +Redistribution and use of this software in source and binary forms, 
  104.12 +with or without modification, are permitted provided that the 
  104.13 +following conditions are met:
  104.14 +
  104.15 +* Redistributions of source code must retain the above
  104.16 +  copyright notice, this list of conditions and the
  104.17 +  following disclaimer.
  104.18 +
  104.19 +* Redistributions in binary form must reproduce the above
  104.20 +  copyright notice, this list of conditions and the
  104.21 +  following disclaimer in the documentation and/or other
  104.22 +  materials provided with the distribution.
  104.23 +
  104.24 +* Neither the name of the assimp team, nor the names of its
  104.25 +  contributors may be used to endorse or promote products
  104.26 +  derived from this software without specific prior
  104.27 +  written permission of the assimp team.
  104.28 +
  104.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  104.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  104.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  104.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  104.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  104.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  104.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  104.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  104.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  104.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  104.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  104.40 +
  104.41 +----------------------------------------------------------------------
  104.42 +*/
  104.43 +
  104.44 +/** @file  FBXUtil.h
  104.45 + *  @brief FBX utility functions for internal use
  104.46 + */
  104.47 +#ifndef INCLUDED_AI_FBX_UTIL_H
  104.48 +#define INCLUDED_AI_FBX_UTIL_H
  104.49 +
  104.50 +#include <string>
  104.51 +#include "FBXCompileConfig.h"
  104.52 +#include "FBXTokenizer.h"
  104.53 +
  104.54 +namespace Assimp {
  104.55 +namespace FBX {
  104.56 +
  104.57 +
  104.58 +namespace Util {
  104.59 +
  104.60 +
  104.61 +/** helper for std::for_each to delete all heap-allocated items in a container */
  104.62 +template<typename T>
  104.63 +struct delete_fun
  104.64 +{
  104.65 +	void operator()(const volatile T* del) {
  104.66 +		delete del;
  104.67 +	}
  104.68 +};
  104.69 +
  104.70 +/** Get a string representation for a #TokenType. */
  104.71 +const char* TokenTypeString(TokenType t);
  104.72 +
  104.73 +
  104.74 +
  104.75 +/** Format log/error messages using a given offset in the source binary file
  104.76 + *
  104.77 + *  @param prefix Message prefix to be preprended to the location info.
  104.78 + *  @param text Message text
  104.79 + *  @param line Line index, 1-based
  104.80 + *  @param column Colum index, 1-based 
  104.81 + *  @return A string of the following format: {prefix} (offset 0x{offset}) {text}*/
  104.82 +std::string AddOffset(const std::string& prefix, const std::string& text, unsigned int offset);
  104.83 +
  104.84 +
  104.85 +/** Format log/error messages using a given line location in the source file.
  104.86 + *
  104.87 + *  @param prefix Message prefix to be preprended to the location info.
  104.88 + *  @param text Message text
  104.89 + *  @param line Line index, 1-based
  104.90 + *  @param column Colum index, 1-based 
  104.91 + *  @return A string of the following format: {prefix} (line {line}, col {column}) {text}*/
  104.92 +std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column);
  104.93 +	
  104.94 +
  104.95 +/** Format log/error messages using a given cursor token.
  104.96 + *
  104.97 + *  @param prefix Message prefix to be preprended to the location info.
  104.98 + *  @param text Message text
  104.99 + *  @param tok Token where parsing/processing stopped
 104.100 + *  @return A string of the following format: {prefix} ({token-type}, line {line}, col {column}) {text}*/
 104.101 +std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok);
 104.102 +
 104.103 +}
 104.104 +}
 104.105 +}
 104.106 +
 104.107 +#endif // ! INCLUDED_AI_FBX_UTIL_H
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/libs/assimp/FileLogStream.h	Sat Feb 01 19:58:19 2014 +0200
   105.3 @@ -0,0 +1,64 @@
   105.4 +#ifndef ASSIMP_FILELOGSTREAM_H_INC
   105.5 +#define ASSIMP_FILELOGSTREAM_H_INC
   105.6 +
   105.7 +#include "assimp/LogStream.hpp"
   105.8 +#include "assimp/IOStream.hpp"
   105.9 +
  105.10 +namespace Assimp	{
  105.11 +
  105.12 +// ----------------------------------------------------------------------------------
  105.13 +/**	@class	FileLogStream
  105.14 + *	@brief	Logstream to write into a file.
  105.15 + */
  105.16 +class FileLogStream :
  105.17 +	public LogStream
  105.18 +{
  105.19 +public:
  105.20 +	FileLogStream( const char* file, IOSystem* io = NULL );
  105.21 +	~FileLogStream();
  105.22 +	void write( const char* message );
  105.23 +
  105.24 +private:
  105.25 +	IOStream *m_pStream;
  105.26 +};
  105.27 +
  105.28 +// ----------------------------------------------------------------------------------
  105.29 +//	Constructor
  105.30 +inline FileLogStream::FileLogStream( const char* file, IOSystem* io ) :
  105.31 +	m_pStream(NULL)
  105.32 +{
  105.33 +	if ( !file || 0 == *file )
  105.34 +		return;
  105.35 +
  105.36 +	// If no IOSystem is specified: take a default one
  105.37 +	if (!io)
  105.38 +	{
  105.39 +		DefaultIOSystem FileSystem;
  105.40 +		m_pStream = FileSystem.Open( file, "wt");
  105.41 +	}
  105.42 +	else m_pStream = io->Open( file, "wt" );
  105.43 +}
  105.44 +
  105.45 +// ----------------------------------------------------------------------------------
  105.46 +//	Destructor
  105.47 +inline FileLogStream::~FileLogStream()
  105.48 +{
  105.49 +	// The virtual d'tor should destroy the underlying file
  105.50 +	delete m_pStream;
  105.51 +}
  105.52 +
  105.53 +// ----------------------------------------------------------------------------------
  105.54 +//	Write method
  105.55 +inline void FileLogStream::write( const char* message )
  105.56 +{
  105.57 +	if (m_pStream != NULL)
  105.58 +	{
  105.59 +		m_pStream->Write(message, sizeof(char), ::strlen(message));
  105.60 +		m_pStream->Flush();
  105.61 +	}
  105.62 +}
  105.63 +
  105.64 +// ----------------------------------------------------------------------------------
  105.65 +} // !Namespace Assimp
  105.66 +
  105.67 +#endif // !! ASSIMP_FILELOGSTREAM_H_INC
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/libs/assimp/FileSystemFilter.h	Sat Feb 01 19:58:19 2014 +0200
   106.3 @@ -0,0 +1,298 @@
   106.4 +/*
   106.5 +Open Asset Import Library (assimp)
   106.6 +----------------------------------------------------------------------
   106.7 +
   106.8 +Copyright (c) 2006-2008, assimp team
   106.9 +All rights reserved.
  106.10 +
  106.11 +Redistribution and use of this software in source and binary forms, 
  106.12 +with or without modification, are permitted provided that the 
  106.13 +following conditions are met:
  106.14 +
  106.15 +* Redistributions of source code must retain the above
  106.16 +  copyright notice, this list of conditions and the
  106.17 +  following disclaimer.
  106.18 +
  106.19 +* Redistributions in binary form must reproduce the above
  106.20 +  copyright notice, this list of conditions and the
  106.21 +  following disclaimer in the documentation and/or other
  106.22 +  materials provided with the distribution.
  106.23 +
  106.24 +* Neither the name of the assimp team, nor the names of its
  106.25 +  contributors may be used to endorse or promote products
  106.26 +  derived from this software without specific prior
  106.27 +  written permission of the assimp team.
  106.28 +
  106.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  106.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  106.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  106.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  106.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  106.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  106.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  106.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  106.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  106.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  106.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  106.40 +
  106.41 +----------------------------------------------------------------------
  106.42 +*/
  106.43 +
  106.44 +/** @file FileSystemFilter.h
  106.45 + *  Implements a filter system to filter calls to Exists() and Open()
  106.46 + *  in order to improve the sucess rate of file opening ...
  106.47 + */
  106.48 +#ifndef AI_FILESYSTEMFILTER_H_INC
  106.49 +#define AI_FILESYSTEMFILTER_H_INC
  106.50 +
  106.51 +#include "assimp/IOSystem.hpp"
  106.52 +#include "fast_atof.h"
  106.53 +#include "ParsingUtils.h"
  106.54 +namespace Assimp	{
  106.55 +
  106.56 +inline bool IsHex(char s) {
  106.57 +	return (s>='0' && s<='9') || (s>='a' && s<='f') || (s>='A' && s<='F');	
  106.58 +}
  106.59 +
  106.60 +// ---------------------------------------------------------------------------
  106.61 +/** File system filter  
  106.62 + */
  106.63 +class FileSystemFilter : public IOSystem
  106.64 +{
  106.65 +public:
  106.66 +	/** Constructor. */
  106.67 +	FileSystemFilter(const std::string& file, IOSystem* old)
  106.68 +		: wrapped  (old)
  106.69 +		, src_file (file)
  106.70 +		, sep(wrapped->getOsSeparator())
  106.71 +	{
  106.72 +		ai_assert(NULL != wrapped);
  106.73 +
  106.74 +		// Determine base directory
  106.75 +		base = src_file;
  106.76 +		std::string::size_type ss2;
  106.77 +		if (std::string::npos != (ss2 = base.find_last_of("\\/")))	{
  106.78 +			base.erase(ss2,base.length()-ss2);
  106.79 +		}
  106.80 +		else {
  106.81 +			base = "";
  106.82 +		//	return;
  106.83 +		}
  106.84 +
  106.85 +		// make sure the directory is terminated properly
  106.86 +		char s;
  106.87 +
  106.88 +		if (base.length() == 0) {
  106.89 +			base = ".";
  106.90 +			base += getOsSeparator();
  106.91 +		}
  106.92 +		else if ((s = *(base.end()-1)) != '\\' && s != '/') {
  106.93 +			base += getOsSeparator();
  106.94 +		}
  106.95 +
  106.96 +		DefaultLogger::get()->info("Import root directory is \'" + base + "\'");
  106.97 +	}
  106.98 +
  106.99 +	/** Destructor. */
 106.100 +	~FileSystemFilter()
 106.101 +	{
 106.102 +		// haha
 106.103 +	}
 106.104 +
 106.105 +	// -------------------------------------------------------------------
 106.106 +	/** Tests for the existence of a file at the given path. */
 106.107 +	bool Exists( const char* pFile) const
 106.108 +	{
 106.109 +		std::string tmp = pFile;
 106.110 +
 106.111 +		// Currently this IOSystem is also used to open THE ONE FILE.
 106.112 +		if (tmp != src_file)	{
 106.113 +			BuildPath(tmp);
 106.114 +			Cleanup(tmp);
 106.115 +		}
 106.116 +
 106.117 +		return wrapped->Exists(tmp);
 106.118 +	}
 106.119 +
 106.120 +	// -------------------------------------------------------------------
 106.121 +	/** Returns the directory separator. */
 106.122 +	char getOsSeparator() const
 106.123 +	{
 106.124 +		return sep;
 106.125 +	}
 106.126 +
 106.127 +	// -------------------------------------------------------------------
 106.128 +	/** Open a new file with a given path. */
 106.129 +	IOStream* Open( const char* pFile, const char* pMode = "rb")
 106.130 +	{
 106.131 +		ai_assert(pFile);
 106.132 +		ai_assert(pMode);
 106.133 +
 106.134 +		// First try the unchanged path
 106.135 +		IOStream* s = wrapped->Open(pFile,pMode);
 106.136 +
 106.137 +		if (!s)	{
 106.138 +			std::string tmp = pFile;
 106.139 +
 106.140 +			// Try to convert between absolute and relative paths
 106.141 +			BuildPath(tmp);
 106.142 +			s = wrapped->Open(tmp,pMode);
 106.143 +
 106.144 +			if (!s) {
 106.145 +				// Finally, look for typical issues with paths
 106.146 +				// and try to correct them. This is our last
 106.147 +				// resort.
 106.148 +				tmp = pFile;
 106.149 +				Cleanup(tmp);
 106.150 +				BuildPath(tmp);
 106.151 +				s = wrapped->Open(tmp,pMode);
 106.152 +			}
 106.153 +		}
 106.154 +		
 106.155 +		return s;
 106.156 +	}
 106.157 +
 106.158 +	// -------------------------------------------------------------------
 106.159 +	/** Closes the given file and releases all resources associated with it. */
 106.160 +	void Close( IOStream* pFile)
 106.161 +	{
 106.162 +		return wrapped->Close(pFile);
 106.163 +	}
 106.164 +
 106.165 +	// -------------------------------------------------------------------
 106.166 +	/** Compare two paths */
 106.167 +	bool ComparePaths (const char* one, const char* second) const
 106.168 +	{
 106.169 +		return wrapped->ComparePaths (one,second);
 106.170 +	}
 106.171 +
 106.172 +private:
 106.173 +
 106.174 +	// -------------------------------------------------------------------
 106.175 +	/** Build a valid path from a given relative or absolute path.
 106.176 +	 */
 106.177 +	void BuildPath (std::string& in) const
 106.178 +	{
 106.179 +		// if we can already access the file, great.
 106.180 +		if (in.length() < 3 || wrapped->Exists(in)) {
 106.181 +			return;
 106.182 +		}
 106.183 +
 106.184 +		// Determine whether this is a relative path (Windows-specific - most assets are packaged on Windows). 
 106.185 +		if (in[1] != ':') {
 106.186 +		
 106.187 +			// append base path and try 
 106.188 +			const std::string tmp = base + in;
 106.189 +			if (wrapped->Exists(tmp)) {
 106.190 +				in = tmp;
 106.191 +				return;
 106.192 +			}
 106.193 +		}
 106.194 +		
 106.195 +		// Chop of the file name and look in the model directory, if
 106.196 +		// this fails try all sub paths of the given path, i.e.
 106.197 +		// if the given path is foo/bar/something.lwo, try
 106.198 +		// <base>/something.lwo
 106.199 +		// <base>/bar/something.lwo
 106.200 +		// <base>/foo/bar/something.lwo
 106.201 +		std::string::size_type pos = in.rfind('/');
 106.202 +		if (std::string::npos == pos) {
 106.203 +			pos = in.rfind('\\');
 106.204 +		}
 106.205 +
 106.206 +		if (std::string::npos != pos)	{
 106.207 +			std::string tmp;
 106.208 +			std::string::size_type last_dirsep = std::string::npos;
 106.209 +
 106.210 +			while(true) {
 106.211 +				tmp = base;
 106.212 +				tmp += sep;
 106.213 +
 106.214 +				std::string::size_type dirsep = in.rfind('/', last_dirsep);
 106.215 +				if (std::string::npos == dirsep) {
 106.216 +					dirsep = in.rfind('\\', last_dirsep);
 106.217 +				}
 106.218 +
 106.219 +				if (std::string::npos == dirsep || dirsep == 0) {
 106.220 +					// we did try this already.
 106.221 +					break;
 106.222 +				}
 106.223 +
 106.224 +				last_dirsep = dirsep-1;
 106.225 +
 106.226 +				tmp += in.substr(dirsep+1, in.length()-pos); 
 106.227 +				if (wrapped->Exists(tmp)) {
 106.228 +					in = tmp;
 106.229 +					return;
 106.230 +				}
 106.231 +			}
 106.232 +		}
 106.233 +
 106.234 +		// hopefully the underlying file system has another few tricks to access this file ...
 106.235 +	}
 106.236 +
 106.237 +	// -------------------------------------------------------------------
 106.238 +	/** Cleanup the given path
 106.239 +	 */
 106.240 +	void Cleanup (std::string& in) const
 106.241 +	{
 106.242 +		char last = 0;
 106.243 +		if(in.empty()) {
 106.244 +			return;
 106.245 +		}
 106.246 +
 106.247 +		// Remove a very common issue when we're parsing file names: spaces at the
 106.248 +		// beginning of the path. 
 106.249 +		std::string::iterator it = in.begin();
 106.250 +		while (IsSpaceOrNewLine( *it ))++it;
 106.251 +		if (it != in.begin()) {
 106.252 +			in.erase(in.begin(),it+1);
 106.253 +		}
 106.254 +
 106.255 +		const char sep = getOsSeparator();
 106.256 +		for (it = in.begin(); it != in.end(); ++it) {
 106.257 +			// Exclude :// and \\, which remain untouched.
 106.258 +			// https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632
 106.259 +			if ( !strncmp(&*it, "://", 3 )) {
 106.260 +				it += 3;
 106.261 +				continue;
 106.262 +			}
 106.263 +			if (it == in.begin() && !strncmp(&*it, "\\\\", 2)) {
 106.264 +				it += 2;
 106.265 +				continue;
 106.266 +			}
 106.267 +
 106.268 +			// Cleanup path delimiters
 106.269 +			if (*it == '/' || (*it) == '\\') {
 106.270 +				*it = sep;
 106.271 +
 106.272 +				// And we're removing double delimiters, frequent issue with
 106.273 +				// incorrectly composited paths ...
 106.274 +				if (last == *it) {
 106.275 +					it = in.erase(it);
 106.276 +					--it;
 106.277 +				}
 106.278 +			}
 106.279 +			else if (*it == '%' && in.end() - it > 2) {
 106.280 +			
 106.281 +				// Hex sequence in URIs
 106.282 +				if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) {
 106.283 +					*it = HexOctetToDecimal(&*it);
 106.284 +					it = in.erase(it+1,it+2);
 106.285 +					--it;
 106.286 +				}
 106.287 +			}
 106.288 +
 106.289 +			last = *it;
 106.290 +		}
 106.291 +	}
 106.292 +
 106.293 +private:
 106.294 +	IOSystem* wrapped;
 106.295 +	std::string src_file, base;
 106.296 +	char sep;
 106.297 +};
 106.298 +
 106.299 +} //!ns Assimp
 106.300 +
 106.301 +#endif //AI_DEFAULTIOSYSTEM_H_INC
   107.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.2 +++ b/libs/assimp/FindDegenerates.cpp	Sat Feb 01 19:58:19 2014 +0200
   107.3 @@ -0,0 +1,216 @@
   107.4 +/*
   107.5 +---------------------------------------------------------------------------
   107.6 +Open Asset Import Library (assimp)
   107.7 +---------------------------------------------------------------------------
   107.8 +
   107.9 +Copyright (c) 2006-2012, assimp team
  107.10 +
  107.11 +All rights reserved.
  107.12 +
  107.13 +Redistribution and use of this software in source and binary forms, 
  107.14 +with or without modification, are permitted provided that the following 
  107.15 +conditions are met:
  107.16 +
  107.17 +* Redistributions of source code must retain the above
  107.18 +  copyright notice, this list of conditions and the
  107.19 +  following disclaimer.
  107.20 +
  107.21 +* Redistributions in binary form must reproduce the above
  107.22 +  copyright notice, this list of conditions and the
  107.23 +  following disclaimer in the documentation and/or other
  107.24 +  materials provided with the distribution.
  107.25 +
  107.26 +* Neither the name of the assimp team, nor the names of its
  107.27 +  contributors may be used to endorse or promote products
  107.28 +  derived from this software without specific prior
  107.29 +  written permission of the assimp team.
  107.30 +
  107.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  107.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  107.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  107.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  107.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  107.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  107.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  107.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  107.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  107.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  107.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  107.42 +---------------------------------------------------------------------------
  107.43 +*/
  107.44 +
  107.45 +/** @file  FindDegenerates.cpp
  107.46 + *  @brief Implementation of the FindDegenerates post-process step.
  107.47 +*/
  107.48 +
  107.49 +#include "AssimpPCH.h"
  107.50 +
  107.51 +// internal headers
  107.52 +#include "ProcessHelper.h"
  107.53 +#include "FindDegenerates.h"
  107.54 +
  107.55 +using namespace Assimp;
  107.56 +
  107.57 +// ------------------------------------------------------------------------------------------------
  107.58 +// Constructor to be privately used by Importer
  107.59 +FindDegeneratesProcess::FindDegeneratesProcess()
  107.60 +: configRemoveDegenerates (false)
  107.61 +{}
  107.62 +
  107.63 +// ------------------------------------------------------------------------------------------------
  107.64 +// Destructor, private as well
  107.65 +FindDegeneratesProcess::~FindDegeneratesProcess()
  107.66 +{
  107.67 +	// nothing to do here
  107.68 +}
  107.69 +
  107.70 +// ------------------------------------------------------------------------------------------------
  107.71 +// Returns whether the processing step is present in the given flag field.
  107.72 +bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const
  107.73 +{
  107.74 +	return 0 != (pFlags & aiProcess_FindDegenerates);
  107.75 +}
  107.76 +
  107.77 +// ------------------------------------------------------------------------------------------------
  107.78 +// Setup import configuration
  107.79 +void FindDegeneratesProcess::SetupProperties(const Importer* pImp)
  107.80 +{
  107.81 +	// Get the current value of AI_CONFIG_PP_FD_REMOVE
  107.82 +	configRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
  107.83 +}
  107.84 +
  107.85 +// ------------------------------------------------------------------------------------------------
  107.86 +// Executes the post processing step on the given imported data.
  107.87 +void FindDegeneratesProcess::Execute( aiScene* pScene)
  107.88 +{
  107.89 +	DefaultLogger::get()->debug("FindDegeneratesProcess begin");
  107.90 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
  107.91 +		ExecuteOnMesh( pScene->mMeshes[i]);
  107.92 +	}
  107.93 +	DefaultLogger::get()->debug("FindDegeneratesProcess finished");
  107.94 +}
  107.95 +
  107.96 +// ------------------------------------------------------------------------------------------------
  107.97 +// Executes the post processing step on the given imported mesh
  107.98 +void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh)
  107.99 +{
 107.100 +	mesh->mPrimitiveTypes = 0;
 107.101 +
 107.102 +	std::vector<bool> remove_me; 
 107.103 +	if (configRemoveDegenerates)
 107.104 +		remove_me.resize(mesh->mNumFaces,false);
 107.105 +
 107.106 +	unsigned int deg = 0, limit;
 107.107 +	for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
 107.108 +	{
 107.109 +		aiFace& face = mesh->mFaces[a];
 107.110 +		bool first = true;
 107.111 +
 107.112 +		// check whether the face contains degenerated entries
 107.113 +		for (register unsigned int i = 0; i < face.mNumIndices; ++i)
 107.114 +		{
 107.115 +			// Polygons with more than 4 points are allowed to have double points, that is
 107.116 +			// simulating polygons with holes just with concave polygons. However,
 107.117 +			// double points may not come directly after another.
 107.118 +			limit = face.mNumIndices;
 107.119 +			if (face.mNumIndices > 4)
 107.120 +				limit = std::min(limit,i+2);
 107.121 +
 107.122 +			for (register unsigned int t = i+1; t < limit; ++t)
 107.123 +			{
 107.124 +				if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]])
 107.125 +				{
 107.126 +					// we have found a matching vertex position
 107.127 +					// remove the corresponding index from the array
 107.128 +					--face.mNumIndices;--limit;
 107.129 +					for (unsigned int m = t; m < face.mNumIndices; ++m)
 107.130 +					{
 107.131 +						face.mIndices[m] = face.mIndices[m+1];
 107.132 +					}
 107.133 +					--t; 
 107.134 +
 107.135 +					// NOTE: we set the removed vertex index to an unique value
 107.136 +					// to make sure the developer gets notified when his
 107.137 +					// application attemps to access this data.
 107.138 +					face.mIndices[face.mNumIndices] = 0xdeadbeef;
 107.139 +
 107.140 +					if(first)
 107.141 +					{
 107.142 +						++deg;
 107.143 +						first = false;
 107.144 +					}
 107.145 +
 107.146 +					if (configRemoveDegenerates) {
 107.147 +						remove_me[a] = true;
 107.148 +						goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
 107.149 +					}
 107.150 +				}
 107.151 +			}
 107.152 +		}
 107.153 +
 107.154 +		// We need to update the primitive flags array of the mesh.
 107.155 +		switch (face.mNumIndices)
 107.156 +		{
 107.157 +		case 1u:
 107.158 +			mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
 107.159 +			break;
 107.160 +		case 2u:
 107.161 +			mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
 107.162 +			break;
 107.163 +		case 3u:
 107.164 +			mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
 107.165 +			break;
 107.166 +		default:
 107.167 +			mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
 107.168 +			break;
 107.169 +		};
 107.170 +evil_jump_outside:
 107.171 +		continue;
 107.172 +	}
 107.173 +
 107.174 +	// If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
 107.175 +	if (configRemoveDegenerates && deg) {
 107.176 +		unsigned int n = 0;
 107.177 +		for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
 107.178 +		{
 107.179 +			aiFace& face_src = mesh->mFaces[a];
 107.180 +			if (!remove_me[a]) {
 107.181 +				aiFace& face_dest = mesh->mFaces[n++];
 107.182 +
 107.183 +				// Do a manual copy, keep the index array
 107.184 +				face_dest.mNumIndices = face_src.mNumIndices;
 107.185 +				face_dest.mIndices    = face_src.mIndices;
 107.186 +
 107.187 +				if (&face_src != &face_dest) {
 107.188 +					// clear source
 107.189 +					face_src.mNumIndices = 0;
 107.190 +					face_src.mIndices = NULL;
 107.191 +				}
 107.192 +			}
 107.193 +			else {
 107.194 +				// Otherwise delete it if we don't need this face
 107.195 +				delete[] face_src.mIndices;
 107.196 +				face_src.mIndices = NULL;
 107.197 +				face_src.mNumIndices = 0;
 107.198 +			}
 107.199 +		}
 107.200 +		// Just leave the rest of the array unreferenced, we don't care for now
 107.201 +		mesh->mNumFaces = n;
 107.202 +		if (!mesh->mNumFaces) {
 107.203 +			// WTF!? 
 107.204 +			// OK ... for completeness and because I'm not yet tired,
 107.205 +			// let's write code that willl hopefully never be called
 107.206 +			// (famous last words)
 107.207 +
 107.208 +			// OK ... bad idea.
 107.209 +			throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?");
 107.210 +		}
 107.211 +	}
 107.212 +
 107.213 +	if (deg && !DefaultLogger::isNullLogger())
 107.214 +	{
 107.215 +		char s[64];
 107.216 +		ASSIMP_itoa10(s,deg); 
 107.217 +		DefaultLogger::get()->warn(std::string("Found ") + s + " degenerated primitives");
 107.218 +	}
 107.219 +}
   108.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   108.2 +++ b/libs/assimp/FindDegenerates.h	Sat Feb 01 19:58:19 2014 +0200
   108.3 @@ -0,0 +1,105 @@
   108.4 +/*
   108.5 +Open Asset Import Library (assimp)
   108.6 +----------------------------------------------------------------------
   108.7 +
   108.8 +Copyright (c) 2006-2012, assimp team
   108.9 +All rights reserved.
  108.10 +
  108.11 +Redistribution and use of this software in source and binary forms, 
  108.12 +with or without modification, are permitted provided that the 
  108.13 +following conditions are met:
  108.14 +
  108.15 +* Redistributions of source code must retain the above
  108.16 +  copyright notice, this list of conditions and the
  108.17 +  following disclaimer.
  108.18 +
  108.19 +* Redistributions in binary form must reproduce the above
  108.20 +  copyright notice, this list of conditions and the
  108.21 +  following disclaimer in the documentation and/or other
  108.22 +  materials provided with the distribution.
  108.23 +
  108.24 +* Neither the name of the assimp team, nor the names of its
  108.25 +  contributors may be used to endorse or promote products
  108.26 +  derived from this software without specific prior
  108.27 +  written permission of the assimp team.
  108.28 +
  108.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  108.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  108.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  108.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  108.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  108.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  108.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  108.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  108.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  108.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  108.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  108.40 +
  108.41 +----------------------------------------------------------------------
  108.42 +*/
  108.43 +
  108.44 +/** @file Defines a post processing step to search all meshes for
  108.45 +  degenerated faces */
  108.46 +#ifndef AI_FINDDEGENERATESPROCESS_H_INC
  108.47 +#define AI_FINDDEGENERATESPROCESS_H_INC
  108.48 +
  108.49 +#include "BaseProcess.h"
  108.50 +#include "assimp/mesh.h"
  108.51 +
  108.52 +class FindDegeneratesProcessTest;
  108.53 +namespace Assimp	{
  108.54 +
  108.55 +
  108.56 +// ---------------------------------------------------------------------------
  108.57 +/** FindDegeneratesProcess: Searches a mesh for degenerated triangles.
  108.58 +*/
  108.59 +class FindDegeneratesProcess : public BaseProcess
  108.60 +{
  108.61 +public:
  108.62 +
  108.63 +	FindDegeneratesProcess();
  108.64 +	~FindDegeneratesProcess();
  108.65 +
  108.66 +public:
  108.67 +	
  108.68 +	// -------------------------------------------------------------------
  108.69 +	// Check whether step is active
  108.70 +	bool IsActive( unsigned int pFlags) const;
  108.71 +
  108.72 +	// -------------------------------------------------------------------
  108.73 +	// Execute step on a given scene
  108.74 +	void Execute( aiScene* pScene);
  108.75 +
  108.76 +	// -------------------------------------------------------------------
  108.77 +	// Setup import settings
  108.78 +	void SetupProperties(const Importer* pImp);
  108.79 +
  108.80 +	// -------------------------------------------------------------------
  108.81 +	// Execute step on a given mesh
  108.82 +	void ExecuteOnMesh( aiMesh* mesh);
  108.83 +
  108.84 +
  108.85 +	// -------------------------------------------------------------------
  108.86 +	/** @brief Enable the instant removal of degenerated primitives
  108.87 +	 *  @param d hm ... difficult to guess what this means, hu!?
  108.88 +	 */
  108.89 +	void EnableInstantRemoval(bool d) {
  108.90 +		configRemoveDegenerates = d;
  108.91 +	}
  108.92 +
  108.93 +	// -------------------------------------------------------------------
  108.94 +	/** @brief Check whether instant removal is currently enabled
  108.95 +	 *  @return ...
  108.96 +	 */
  108.97 +	bool IsInstantRemoval() const {
  108.98 +		return configRemoveDegenerates;
  108.99 +	}
 108.100 +
 108.101 +private:
 108.102 +
 108.103 +	//! Configuration option: remove degenerates faces immediately
 108.104 +	bool configRemoveDegenerates;
 108.105 +};
 108.106 +}
 108.107 +
 108.108 +#endif // !! AI_FINDDEGENERATESPROCESS_H_INC
   109.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   109.2 +++ b/libs/assimp/FindInstancesProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
   109.3 @@ -0,0 +1,277 @@
   109.4 +/*
   109.5 +---------------------------------------------------------------------------
   109.6 +Open Asset Import Library (assimp)
   109.7 +---------------------------------------------------------------------------
   109.8 +
   109.9 +Copyright (c) 2006-2012, assimp team
  109.10 +
  109.11 +All rights reserved.
  109.12 +
  109.13 +Redistribution and use of this software in source and binary forms, 
  109.14 +with or without modification, are permitted provided that the following 
  109.15 +conditions are met:
  109.16 +
  109.17 +* Redistributions of source code must retain the above
  109.18 +  copyright notice, this list of conditions and the
  109.19 +  following disclaimer.
  109.20 +
  109.21 +* Redistributions in binary form must reproduce the above
  109.22 +  copyright notice, this list of conditions and the
  109.23 +  following disclaimer in the documentation and/or other
  109.24 +  materials provided with the distribution.
  109.25 +
  109.26 +* Neither the name of the assimp team, nor the names of its
  109.27 +  contributors may be used to endorse or promote products
  109.28 +  derived from this software without specific prior
  109.29 +  written permission of the assimp team.
  109.30 +
  109.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  109.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  109.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  109.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  109.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  109.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  109.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  109.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  109.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  109.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  109.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  109.42 +---------------------------------------------------------------------------
  109.43 +*/
  109.44 +
  109.45 +/** @file  FindInstancesProcess.cpp
  109.46 + *  @brief Implementation of the aiProcess_FindInstances postprocessing step
  109.47 +*/
  109.48 +
  109.49 +#include "AssimpPCH.h"
  109.50 +#include "FindInstancesProcess.h"
  109.51 +
  109.52 +using namespace Assimp;
  109.53 +
  109.54 +// ------------------------------------------------------------------------------------------------
  109.55 +// Constructor to be privately used by Importer
  109.56 +FindInstancesProcess::FindInstancesProcess()
  109.57 +:	configSpeedFlag (false)
  109.58 +{}
  109.59 +
  109.60 +// ------------------------------------------------------------------------------------------------
  109.61 +// Destructor, private as well
  109.62 +FindInstancesProcess::~FindInstancesProcess()
  109.63 +{}
  109.64 +
  109.65 +// ------------------------------------------------------------------------------------------------
  109.66 +// Returns whether the processing step is present in the given flag field.
  109.67 +bool FindInstancesProcess::IsActive( unsigned int pFlags) const
  109.68 +{
  109.69 +	// FindInstances makes absolutely no sense together with PreTransformVertices
  109.70 +	// fixme: spawn error message somewhere else?
  109.71 +	return 0 != (pFlags & aiProcess_FindInstances) && 0 == (pFlags & aiProcess_PreTransformVertices);
  109.72 +}
  109.73 +
  109.74 +// ------------------------------------------------------------------------------------------------
  109.75 +// Setup properties for the step
  109.76 +void FindInstancesProcess::SetupProperties(const Importer* pImp)
  109.77 +{
  109.78 +	// AI_CONFIG_FAVOUR_SPEED
  109.79 +	configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
  109.80 +}
  109.81 +
  109.82 +// ------------------------------------------------------------------------------------------------
  109.83 +// Compare the bones of two meshes
  109.84 +bool CompareBones(const aiMesh* orig, const aiMesh* inst)
  109.85 +{
  109.86 +	for (unsigned int i = 0; i < orig->mNumBones;++i) {
  109.87 +		aiBone* aha = orig->mBones[i];
  109.88 +		aiBone* oha = inst->mBones[i];
  109.89 +
  109.90 +		if (aha->mNumWeights   != oha->mNumWeights   ||
  109.91 +			aha->mOffsetMatrix != oha->mOffsetMatrix ||
  109.92 +			aha->mNumWeights   != oha->mNumWeights) {
  109.93 +			return false;
  109.94 +		}
  109.95 +
  109.96 +		// compare weight per weight ---
  109.97 +		for (unsigned int n = 0; n < aha->mNumWeights;++n) {
  109.98 +			if  (aha->mWeights[n].mVertexId != oha->mWeights[n].mVertexId ||
  109.99 +				(aha->mWeights[n].mWeight - oha->mWeights[n].mWeight) < 10e-3f) {
 109.100 +				return false;
 109.101 +			}
 109.102 +		}
 109.103 +	}
 109.104 +	return true;
 109.105 +}
 109.106 +
 109.107 +// ------------------------------------------------------------------------------------------------
 109.108 +// Update mesh indices in the node graph
 109.109 +void UpdateMeshIndices(aiNode* node, unsigned int* lookup)
 109.110 +{
 109.111 +	for (unsigned int n = 0; n < node->mNumMeshes;++n)
 109.112 +		node->mMeshes[n] = lookup[node->mMeshes[n]];
 109.113 +
 109.114 +	for (unsigned int n = 0; n < node->mNumChildren;++n)
 109.115 +		UpdateMeshIndices(node->mChildren[n],lookup);
 109.116 +}
 109.117 +
 109.118 +// ------------------------------------------------------------------------------------------------
 109.119 +// Executes the post processing step on the given imported data.
 109.120 +void FindInstancesProcess::Execute( aiScene* pScene)
 109.121 +{
 109.122 +	DefaultLogger::get()->debug("FindInstancesProcess begin");
 109.123 +	if (pScene->mNumMeshes) {
 109.124 +
 109.125 +		// use a pseudo hash for all meshes in the scene to quickly find 
 109.126 +		// the ones which are possibly equal. This step is executed early 
 109.127 +		// in the pipeline, so we could, depending on the file format,
 109.128 +		// have several thousand small meshes. That's too much for a brute
 109.129 +		// everyone-against-everyone check involving up to 10 comparisons
 109.130 +		// each.
 109.131 +		boost::scoped_array<uint64_t> hashes (new uint64_t[pScene->mNumMeshes]);
 109.132 +		boost::scoped_array<unsigned int> remapping (new unsigned int[pScene->mNumMeshes]);
 109.133 +
 109.134 +		unsigned int numMeshesOut = 0;
 109.135 +		for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
 109.136 +
 109.137 +			aiMesh* inst = pScene->mMeshes[i];
 109.138 +			hashes[i] = GetMeshHash(inst);
 109.139 +
 109.140 +			for (int a = i-1; a >= 0; --a) {
 109.141 +				if (hashes[i] == hashes[a])
 109.142 +				{
 109.143 +					aiMesh* orig = pScene->mMeshes[a];
 109.144 +					if (!orig)
 109.145 +						continue;
 109.146 +					
 109.147 +					// check for hash collision .. we needn't check
 109.148 +					// the vertex format, it *must* match due to the
 109.149 +					// (brilliant) construction of the hash
 109.150 +					if (orig->mNumBones       != inst->mNumBones      ||
 109.151 +						orig->mNumFaces       != inst->mNumFaces      ||
 109.152 +						orig->mNumVertices    != inst->mNumVertices   ||
 109.153 +						orig->mMaterialIndex  != inst->mMaterialIndex ||
 109.154 +						orig->mPrimitiveTypes != inst->mPrimitiveTypes)
 109.155 +						continue;
 109.156 +
 109.157 +					// up to now the meshes are equal. find an appropriate
 109.158 +					// epsilon to compare position differences against
 109.159 +					float epsilon = ComputePositionEpsilon(inst);
 109.160 +					epsilon *= epsilon;
 109.161 +
 109.162 +					// now compare vertex positions, normals,
 109.163 +					// tangents and bitangents using this epsilon.
 109.164 +					if (orig->HasPositions()) {
 109.165 +						if(!CompareArrays(orig->mVertices,inst->mVertices,orig->mNumVertices,epsilon))
 109.166 +							continue;
 109.167 +					}
 109.168 +					if (orig->HasNormals()) {
 109.169 +						if(!CompareArrays(orig->mNormals,inst->mNormals,orig->mNumVertices,epsilon))
 109.170 +							continue;
 109.171 +					}
 109.172 +					if (orig->HasTangentsAndBitangents()) {
 109.173 +						if (!CompareArrays(orig->mTangents,inst->mTangents,orig->mNumVertices,epsilon) ||
 109.174 +							!CompareArrays(orig->mBitangents,inst->mBitangents,orig->mNumVertices,epsilon))
 109.175 +							continue;
 109.176 +					}
 109.177 +
 109.178 +					// use a constant epsilon for colors and UV coordinates
 109.179 +					static const float uvEpsilon = 10e-4f;
 109.180 +
 109.181 +					{
 109.182 +						unsigned int i, end = orig->GetNumUVChannels();
 109.183 +						for(i = 0; i < end; ++i) {
 109.184 +							if (!orig->mTextureCoords[i]) {
 109.185 +								continue;
 109.186 +							}
 109.187 +							if(!CompareArrays(orig->mTextureCoords[i],inst->mTextureCoords[i],orig->mNumVertices,uvEpsilon)) {
 109.188 +								break;	
 109.189 +							}
 109.190 +						}
 109.191 +						if (i != end) {
 109.192 +							continue;
 109.193 +						}
 109.194 +					}
 109.195 +					{
 109.196 +						unsigned int i, end = orig->GetNumColorChannels();
 109.197 +						for(i = 0; i < end; ++i) {
 109.198 +							if (!orig->mColors[i]) {
 109.199 +								continue;
 109.200 +							}
 109.201 +							if(!CompareArrays(orig->mColors[i],inst->mColors[i],orig->mNumVertices,uvEpsilon)) {
 109.202 +								break;	
 109.203 +							}
 109.204 +						}
 109.205 +						if (i != end) {
 109.206 +							continue;
 109.207 +						}
 109.208 +					}
 109.209 +
 109.210 +					// These two checks are actually quite expensive and almost *never* required.
 109.211 +					// Almost. That's why they're still here. But there's no reason to do them
 109.212 +					// in speed-targeted imports.
 109.213 +					if (!configSpeedFlag) {
 109.214 +
 109.215 +						// It seems to be strange, but we really need to check whether the
 109.216 +						// bones are identical too. Although it's extremely unprobable
 109.217 +						// that they're not if control reaches here, we need to deal
 109.218 +						// with unprobable cases, too. It could still be that there are
 109.219 +						// equal shapes which are deformed differently.
 109.220 +						if (!CompareBones(orig,inst))
 109.221 +							continue;
 109.222 +
 109.223 +						// For completeness ... compare even the index buffers for equality
 109.224 +						// face order & winding order doesn't care. Input data is in verbose format.
 109.225 +						boost::scoped_array<unsigned int> ftbl_orig(new unsigned int[orig->mNumVertices]);
 109.226 +						boost::scoped_array<unsigned int> ftbl_inst(new unsigned int[orig->mNumVertices]);
 109.227 +
 109.228 +						for (unsigned int tt = 0; tt < orig->mNumFaces;++tt) {
 109.229 +							aiFace& f = orig->mFaces[tt];
 109.230 +							for (unsigned int nn = 0; nn < f.mNumIndices;++nn)
 109.231 +								ftbl_orig[f.mIndices[nn]] = tt;
 109.232 +
 109.233 +							aiFace& f2 = inst->mFaces[tt];
 109.234 +							for (unsigned int nn = 0; nn < f2.mNumIndices;++nn)
 109.235 +								ftbl_inst[f2.mIndices[nn]] = tt;
 109.236 +						}
 109.237 +						if (0 != ::memcmp(ftbl_inst.get(),ftbl_orig.get(),orig->mNumVertices*sizeof(unsigned int)))
 109.238 +							continue;
 109.239 +					}
 109.240 +
 109.241 +					// We're still here. Or in other words: 'inst' is an instance of 'orig'.
 109.242 +					// Place a marker in our list that we can easily update mesh indices.
 109.243 +					remapping[i] = remapping[a];
 109.244 +
 109.245 +					// Delete the instanced mesh, we don't need it anymore
 109.246 +					delete inst;
 109.247 +					pScene->mMeshes[i] = NULL;
 109.248 +					break;
 109.249 +				}
 109.250 +			}
 109.251 +
 109.252 +			// If we didn't find a match for the current mesh: keep it
 109.253 +			if (pScene->mMeshes[i]) {
 109.254 +				remapping[i] = numMeshesOut++;
 109.255 +			}
 109.256 +		}
 109.257 +		ai_assert(0 != numMeshesOut);
 109.258 +		if (numMeshesOut != pScene->mNumMeshes) {
 109.259 +
 109.260 +			// Collapse the meshes array by removing all NULL entries
 109.261 +			for (unsigned int real = 0, i = 0; real < numMeshesOut; ++i) {
 109.262 +				if (pScene->mMeshes[i])
 109.263 +					pScene->mMeshes[real++] = pScene->mMeshes[i];
 109.264 +			}
 109.265 +
 109.266 +			// And update the nodegraph with our nice lookup table
 109.267 +			UpdateMeshIndices(pScene->mRootNode,remapping.get());
 109.268 +
 109.269 +			// write to log
 109.270 +			if (!DefaultLogger::isNullLogger()) {
 109.271 +			
 109.272 +				char buffer[512];
 109.273 +				::sprintf(buffer,"FindInstancesProcess finished. Found %i instances",pScene->mNumMeshes-numMeshesOut);
 109.274 +				DefaultLogger::get()->info(buffer); 
 109.275 +			}
 109.276 +			pScene->mNumMeshes = numMeshesOut;
 109.277 +		}
 109.278 +		else DefaultLogger::get()->debug("FindInstancesProcess finished. No instanced meshes found"); 
 109.279 +	}
 109.280 +}
   110.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   110.2 +++ b/libs/assimp/FindInstancesProcess.h	Sat Feb 01 19:58:19 2014 +0200
   110.3 @@ -0,0 +1,135 @@
   110.4 +/*
   110.5 +Open Asset Import Library (assimp)
   110.6 +----------------------------------------------------------------------
   110.7 +
   110.8 +Copyright (c) 2006-2012, assimp team
   110.9 +All rights reserved.
  110.10 +
  110.11 +Redistribution and use of this software in source and binary forms, 
  110.12 +with or without modification, are permitted provided that the 
  110.13 +following conditions are met:
  110.14 +
  110.15 +* Redistributions of source code must retain the above
  110.16 +  copyright notice, this list of conditions and the
  110.17 +  following disclaimer.
  110.18 +
  110.19 +* Redistributions in binary form must reproduce the above
  110.20 +  copyright notice, this list of conditions and the
  110.21 +  following disclaimer in the documentation and/or other
  110.22 +  materials provided with the distribution.
  110.23 +
  110.24 +* Neither the name of the assimp team, nor the names of its
  110.25 +  contributors may be used to endorse or promote products
  110.26 +  derived from this software without specific prior
  110.27 +  written permission of the assimp team.
  110.28 +
  110.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  110.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  110.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  110.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  110.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  110.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  110.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  110.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  110.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  110.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  110.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  110.40 +
  110.41 +----------------------------------------------------------------------
  110.42 +*/
  110.43 +
  110.44 +/** @file  FindInstancesProcess.h
  110.45 + *  @brief Declares the aiProcess_FindInstances post-process step
  110.46 + */
  110.47 +#ifndef AI_FINDINSTANCES_H_INC
  110.48 +#define AI_FINDINSTANCES_H_INC
  110.49 +
  110.50 +#include "BaseProcess.h"
  110.51 +#include "ProcessHelper.h"
  110.52 +
  110.53 +class FindInstancesProcessTest;
  110.54 +namespace Assimp	{
  110.55 +
  110.56 +// -------------------------------------------------------------------------------
  110.57 +/** @brief Get a pseudo(!)-hash representing a mesh.
  110.58 + *
  110.59 + *  The hash is built from number of vertices, faces, primitive types,
  110.60 + *  .... but *not* from the real mesh data. The funcction is not a perfect hash.
  110.61 + *  @param in Input mesh
  110.62 + *  @return Hash. 
  110.63 + */
  110.64 +inline uint64_t GetMeshHash(aiMesh* in) 
  110.65 +{
  110.66 +	ai_assert(NULL != in);
  110.67 +
  110.68 +	// ... get an unique value representing the vertex format of the mesh
  110.69 +	const unsigned int fhash = GetMeshVFormatUnique(in);
  110.70 +
  110.71 +	// and bake it with number of vertices/faces/bones/matidx/ptypes
  110.72 +	return ((uint64_t)fhash << 32u) | ((
  110.73 +		(in->mNumBones << 16u) ^  (in->mNumVertices)       ^
  110.74 +		(in->mNumFaces<<4u)    ^  (in->mMaterialIndex<<15) ^
  110.75 +		(in->mPrimitiveTypes<<28)) & 0xffffffff );
  110.76 +}
  110.77 +
  110.78 +// -------------------------------------------------------------------------------
  110.79 +/** @brief Perform a component-wise comparison of two arrays
  110.80 + *
  110.81 + *  @param first First array
  110.82 + *  @param second Second aray
  110.83 + *  @param size Size of both arrays
  110.84 + *  @param e Epsilon
  110.85 + *  @return true if the arrays are identical
  110.86 + */
  110.87 +inline bool CompareArrays(const aiVector3D* first, const aiVector3D* second, 
  110.88 +	unsigned int size, float e) 
  110.89 +{
  110.90 +	for (const aiVector3D* end = first+size; first != end; ++first,++second) {
  110.91 +		if ( (*first - *second).SquareLength() >= e)
  110.92 +			return false;
  110.93 +	}
  110.94 +	return true;
  110.95 +}
  110.96 +
  110.97 +// and the same for colors ...
  110.98 +inline bool CompareArrays(const aiColor4D* first, const aiColor4D* second, 
  110.99 +	unsigned int size, float e) 
 110.100 +{
 110.101 +	for (const aiColor4D* end = first+size; first != end; ++first,++second) {
 110.102 +		if ( GetColorDifference(*first,*second) >= e)
 110.103 +			return false;
 110.104 +	}
 110.105 +	return true;
 110.106 +}
 110.107 +
 110.108 +// ---------------------------------------------------------------------------
 110.109 +/** @brief A post-processing steps to search for instanced meshes
 110.110 +*/
 110.111 +class FindInstancesProcess : public BaseProcess
 110.112 +{
 110.113 +public:
 110.114 +
 110.115 +	FindInstancesProcess();
 110.116 +	~FindInstancesProcess();
 110.117 +
 110.118 +public:
 110.119 +	// -------------------------------------------------------------------
 110.120 +	// Check whether step is active in given flags combination
 110.121 +	bool IsActive( unsigned int pFlags) const;
 110.122 +
 110.123 +	// -------------------------------------------------------------------
 110.124 +	// Execute step on a given scene
 110.125 +	void Execute( aiScene* pScene);
 110.126 +
 110.127 +	// -------------------------------------------------------------------
 110.128 +	// Setup properties prior to executing the process
 110.129 +	void SetupProperties(const Importer* pImp);
 110.130 +
 110.131 +private:
 110.132 +
 110.133 +	bool configSpeedFlag;
 110.134 +
 110.135 +}; // ! end class FindInstancesProcess
 110.136 +}  // ! end namespace Assimp
 110.137 +
 110.138 +#endif // !! AI_FINDINSTANCES_H_INC
   111.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   111.2 +++ b/libs/assimp/FindInvalidDataProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
   111.3 @@ -0,0 +1,419 @@
   111.4 +/*
   111.5 +---------------------------------------------------------------------------
   111.6 +Open Asset Import Library (assimp)
   111.7 +---------------------------------------------------------------------------
   111.8 +
   111.9 +Copyright (c) 2006-2012, assimp team
  111.10 +
  111.11 +All rights reserved.
  111.12 +
  111.13 +Redistribution and use of this software in source and binary forms, 
  111.14 +with or without modification, are permitted provided that the following 
  111.15 +conditions are met:
  111.16 +
  111.17 +* Redistributions of source code must retain the above
  111.18 +  copyright notice, this list of conditions and the
  111.19 +  following disclaimer.
  111.20 +
  111.21 +* Redistributions in binary form must reproduce the above
  111.22 +  copyright notice, this list of conditions and the
  111.23 +  following disclaimer in the documentation and/or other
  111.24 +  materials provided with the distribution.
  111.25 +
  111.26 +* Neither the name of the assimp team, nor the names of its
  111.27 +  contributors may be used to endorse or promote products
  111.28 +  derived from this software without specific prior
  111.29 +  written permission of the assimp team.
  111.30 +
  111.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  111.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  111.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  111.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  111.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  111.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  111.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  111.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  111.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  111.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  111.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  111.42 +---------------------------------------------------------------------------
  111.43 +*/
  111.44 +
  111.45 +/** @file Defines a post processing step to search an importer's output
  111.46 +    for data that is obviously invalid  */
  111.47 +
  111.48 +#include "AssimpPCH.h"
  111.49 +
  111.50 +#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
  111.51 +
  111.52 +// internal headers
  111.53 +#include "FindInvalidDataProcess.h"
  111.54 +#include "ProcessHelper.h"
  111.55 +
  111.56 +using namespace Assimp;
  111.57 +
  111.58 +// ------------------------------------------------------------------------------------------------
  111.59 +// Constructor to be privately used by Importer
  111.60 +FindInvalidDataProcess::FindInvalidDataProcess()
  111.61 +{
  111.62 +	// nothing to do here
  111.63 +}
  111.64 +
  111.65 +// ------------------------------------------------------------------------------------------------
  111.66 +// Destructor, private as well
  111.67 +FindInvalidDataProcess::~FindInvalidDataProcess()
  111.68 +{
  111.69 +	// nothing to do here
  111.70 +}
  111.71 +
  111.72 +// ------------------------------------------------------------------------------------------------
  111.73 +// Returns whether the processing step is present in the given flag field.
  111.74 +bool FindInvalidDataProcess::IsActive( unsigned int pFlags) const
  111.75 +{
  111.76 +	return 0 != (pFlags & aiProcess_FindInvalidData);
  111.77 +}
  111.78 +
  111.79 +// ------------------------------------------------------------------------------------------------
  111.80 +// Setup import configuration
  111.81 +void FindInvalidDataProcess::SetupProperties(const Importer* pImp)
  111.82 +{
  111.83 +	// Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY
  111.84 +	configEpsilon = (0 != pImp->GetPropertyFloat(AI_CONFIG_PP_FID_ANIM_ACCURACY,0.f));
  111.85 +}
  111.86 +
  111.87 +// ------------------------------------------------------------------------------------------------
  111.88 +// Update mesh references in the node graph
  111.89 +void UpdateMeshReferences(aiNode* node, const std::vector<unsigned int>& meshMapping)
  111.90 +{
  111.91 +	if (node->mNumMeshes)	{
  111.92 +		unsigned int out = 0;
  111.93 +		for (unsigned int a = 0; a < node->mNumMeshes;++a)	{
  111.94 +
  111.95 +			register unsigned int ref = node->mMeshes[a];
  111.96 +			if (UINT_MAX != (ref = meshMapping[ref]))	{
  111.97 +				node->mMeshes[out++] = ref;
  111.98 +			}
  111.99 +		}
 111.100 +		// just let the members that are unused, that's much cheaper
 111.101 +		// than a full array realloc'n'copy party ...
 111.102 +		if(!(node->mNumMeshes = out))	{
 111.103 +
 111.104 +			delete[] node->mMeshes;
 111.105 +			node->mMeshes = NULL;
 111.106 +		}
 111.107 +	}
 111.108 +	// recursively update all children
 111.109 +	for (unsigned int i = 0; i < node->mNumChildren;++i) {
 111.110 +		UpdateMeshReferences(node->mChildren[i],meshMapping);
 111.111 +	}
 111.112 +}
 111.113 +
 111.114 +// ------------------------------------------------------------------------------------------------
 111.115 +// Executes the post processing step on the given imported data.
 111.116 +void FindInvalidDataProcess::Execute( aiScene* pScene)
 111.117 +{
 111.118 +	DefaultLogger::get()->debug("FindInvalidDataProcess begin");
 111.119 +
 111.120 +	bool out = false;
 111.121 +	std::vector<unsigned int> meshMapping(pScene->mNumMeshes);
 111.122 +	unsigned int real = 0;	
 111.123 +
 111.124 +	// Process meshes
 111.125 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)	{
 111.126 +
 111.127 +		int result;
 111.128 +		if ((result = ProcessMesh( pScene->mMeshes[a])))	{
 111.129 +			out = true;
 111.130 +
 111.131 +			if (2 == result)	{
 111.132 +				// remove this mesh
 111.133 +				delete pScene->mMeshes[a];
 111.134 +				AI_DEBUG_INVALIDATE_PTR(pScene->mMeshes[a]);
 111.135 +
 111.136 +				meshMapping[a] = UINT_MAX;
 111.137 +				continue;
 111.138 +			}
 111.139 +		}
 111.140 +		pScene->mMeshes[real] = pScene->mMeshes[a];
 111.141 +		meshMapping[a] = real++;
 111.142 +	}
 111.143 +
 111.144 +	// Process animations
 111.145 +	for (unsigned int a = 0; a < pScene->mNumAnimations;++a) {
 111.146 +		ProcessAnimation( pScene->mAnimations[a]);
 111.147 +	}
 111.148 +
 111.149 +
 111.150 +	if (out)	{
 111.151 +		if ( real != pScene->mNumMeshes)	{
 111.152 +			if (!real) {
 111.153 +				throw DeadlyImportError("No meshes remaining");
 111.154 +			}
 111.155 +			
 111.156 +			// we need to remove some meshes.
 111.157 +			// therefore we'll also need to remove all references
 111.158 +			// to them from the scenegraph 
 111.159 +			UpdateMeshReferences(pScene->mRootNode,meshMapping);
 111.160 +			pScene->mNumMeshes = real;
 111.161 +		}
 111.162 +
 111.163 +		DefaultLogger::get()->info("FindInvalidDataProcess finished. Found issues ...");
 111.164 +	}
 111.165 +	else DefaultLogger::get()->debug("FindInvalidDataProcess finished. Everything seems to be OK.");
 111.166 +}
 111.167 +
 111.168 +// ------------------------------------------------------------------------------------------------
 111.169 +template <typename T>
 111.170 +inline const char* ValidateArrayContents(const T* arr, unsigned int size,
 111.171 +	const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true)
 111.172 +{
 111.173 +	return NULL;
 111.174 +}
 111.175 +
 111.176 +// ------------------------------------------------------------------------------------------------
 111.177 +template <>
 111.178 +inline const char* ValidateArrayContents<aiVector3D>(const aiVector3D* arr, unsigned int size,
 111.179 +	const std::vector<bool>& dirtyMask, bool mayBeIdentical , bool mayBeZero )
 111.180 +{
 111.181 +	bool b = false;
 111.182 +	unsigned int cnt = 0;
 111.183 +	for (unsigned int i = 0; i < size;++i)	{
 111.184 +
 111.185 +		if (dirtyMask.size() && dirtyMask[i]) {
 111.186 +			continue;
 111.187 +		}
 111.188 +		++cnt;
 111.189 +
 111.190 +		const aiVector3D& v = arr[i];
 111.191 +		if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z))	{
 111.192 +			return "INF/NAN was found in a vector component";
 111.193 +		}
 111.194 +		if (!mayBeZero && !v.x && !v.y && !v.z )	{
 111.195 +			return "Found zero-length vector";
 111.196 +		}
 111.197 +		if (i && v != arr[i-1])b = true;
 111.198 +	}
 111.199 +	if (cnt > 1 && !b && !mayBeIdentical) {
 111.200 +		return "All vectors are identical";
 111.201 +	}
 111.202 +	return NULL;
 111.203 +}
 111.204 +
 111.205 +// ------------------------------------------------------------------------------------------------
 111.206 +template <typename T>
 111.207 +inline bool ProcessArray(T*& in, unsigned int num,const char* name,
 111.208 +	const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true)
 111.209 +{
 111.210 +	const char* err = ValidateArrayContents(in,num,dirtyMask,mayBeIdentical,mayBeZero);
 111.211 +	if (err)	{
 111.212 +		DefaultLogger::get()->error(std::string("FindInvalidDataProcess fails on mesh ") + name + ": " + err);
 111.213 +		
 111.214 +		delete[] in;
 111.215 +		in = NULL;
 111.216 +		return true;
 111.217 +	}
 111.218 +	return false;
 111.219 +}
 111.220 +
 111.221 +// ------------------------------------------------------------------------------------------------
 111.222 +template <typename T>
 111.223 +AI_FORCE_INLINE bool EpsilonCompare(const T& n, const T& s, float epsilon);
 111.224 +
 111.225 +// ------------------------------------------------------------------------------------------------
 111.226 +AI_FORCE_INLINE bool EpsilonCompare(float n, float s, float epsilon) {
 111.227 +	return fabs(n-s)>epsilon;
 111.228 +}
 111.229 +
 111.230 +// ------------------------------------------------------------------------------------------------
 111.231 +template <>
 111.232 +bool EpsilonCompare<aiVectorKey>(const aiVectorKey& n, const aiVectorKey& s, float epsilon)	{
 111.233 +	return 
 111.234 +		EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) &&
 111.235 +		EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) &&
 111.236 +		EpsilonCompare(n.mValue.z,s.mValue.z,epsilon);
 111.237 +}
 111.238 +
 111.239 +// ------------------------------------------------------------------------------------------------
 111.240 +template <>
 111.241 +bool EpsilonCompare<aiQuatKey>(const aiQuatKey& n, const aiQuatKey& s, float epsilon)	{
 111.242 +	return 
 111.243 +		EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) &&
 111.244 +		EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) &&
 111.245 +		EpsilonCompare(n.mValue.z,s.mValue.z,epsilon) &&
 111.246 +		EpsilonCompare(n.mValue.w,s.mValue.w,epsilon);
 111.247 +}
 111.248 +
 111.249 +// ------------------------------------------------------------------------------------------------
 111.250 +template <typename T>
 111.251 +inline bool AllIdentical(T* in, unsigned int num, float epsilon)
 111.252 +{
 111.253 +	if (num <= 1) {
 111.254 +		return true;
 111.255 +	}
 111.256 +
 111.257 +	if (epsilon > 0.f) {
 111.258 +		for (unsigned int i = 0; i < num-1;++i) {
 111.259 +
 111.260 +			if (!EpsilonCompare(in[i],in[i+1],epsilon)) {
 111.261 +				return false;
 111.262 +			}
 111.263 +		}
 111.264 +	}
 111.265 +	else {
 111.266 +		for (unsigned int i = 0; i < num-1;++i) {
 111.267 +
 111.268 +			if (in[i] != in[i+1]) {
 111.269 +				return false;
 111.270 +			}
 111.271 +		}
 111.272 +	}
 111.273 +	return true;
 111.274 +}
 111.275 +
 111.276 +// ------------------------------------------------------------------------------------------------
 111.277 +// Search an animation for invalid content
 111.278 +void FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim)
 111.279 +{
 111.280 +	// Process all animation channels
 111.281 +	for (unsigned int a = 0; a < anim->mNumChannels;++a) {
 111.282 +		ProcessAnimationChannel( anim->mChannels[a]);
 111.283 +	}
 111.284 +}
 111.285 +
 111.286 +// ------------------------------------------------------------------------------------------------
 111.287 +void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
 111.288 +{
 111.289 +	int i = 0;
 111.290 +
 111.291 +	// ScenePreprocessor's work ...
 111.292 +	ai_assert((0 != anim->mPositionKeys && 0 != anim->mRotationKeys && 0 != anim->mScalingKeys));
 111.293 +
 111.294 +	// Check whether all values in a tracks are identical - in this case
 111.295 +	// we can remove al keys except one.
 111.296 +	// POSITIONS
 111.297 +	if (anim->mNumPositionKeys > 1 && AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys,configEpsilon))
 111.298 +	{
 111.299 +		aiVectorKey v = anim->mPositionKeys[0];
 111.300 +
 111.301 +		// Reallocate ... we need just ONE element, it makes no sense to reuse the array
 111.302 +		delete[] anim->mPositionKeys;
 111.303 +		anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys = 1];
 111.304 +		anim->mPositionKeys[0] = v;
 111.305 +		i = 1;
 111.306 +	}
 111.307 +
 111.308 +	// ROTATIONS
 111.309 +	if (anim->mNumRotationKeys > 1 && AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys,configEpsilon))
 111.310 +	{
 111.311 +		aiQuatKey v = anim->mRotationKeys[0];
 111.312 +
 111.313 +		// Reallocate ... we need just ONE element, it makes no sense to reuse the array
 111.314 +		delete[] anim->mRotationKeys;
 111.315 +		anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys = 1];
 111.316 +		anim->mRotationKeys[0] = v;
 111.317 +		i = 1;
 111.318 +	}
 111.319 +
 111.320 +	// SCALINGS
 111.321 +	if (anim->mNumScalingKeys > 1 && AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys,configEpsilon))
 111.322 +	{
 111.323 +		aiVectorKey v = anim->mScalingKeys[0];
 111.324 +
 111.325 +		// Reallocate ... we need just ONE element, it makes no sense to reuse the array
 111.326 +		delete[] anim->mScalingKeys;
 111.327 +		anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys = 1];
 111.328 +		anim->mScalingKeys[0] = v;
 111.329 +		i = 1;
 111.330 +	}
 111.331 +	if (1 == i)
 111.332 +		DefaultLogger::get()->warn("Simplified dummy tracks with just one key");
 111.333 +}
 111.334 +
 111.335 +// ------------------------------------------------------------------------------------------------
 111.336 +// Search a mesh for invalid contents
 111.337 +int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
 111.338 +{
 111.339 +	bool ret = false;
 111.340 +	std::vector<bool> dirtyMask(pMesh->mNumVertices,(pMesh->mNumFaces ? true : false));
 111.341 +
 111.342 +	// Ignore elements that are not referenced by vertices.
 111.343 +	// (they are, for example, caused by the FindDegenerates step)
 111.344 +	for (unsigned int m = 0; m < pMesh->mNumFaces;++m)	{
 111.345 +		const aiFace& f = pMesh->mFaces[m];
 111.346 +		
 111.347 +		for (unsigned int i = 0; i < f.mNumIndices;++i) {
 111.348 +			dirtyMask[f.mIndices[i]] = false;
 111.349 +		}
 111.350 +	}
 111.351 +
 111.352 +	// Process vertex positions
 111.353 +	if(pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask))	{
 111.354 +		DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions");
 111.355 +		return 2;
 111.356 +	}
 111.357 +
 111.358 +	// process texture coordinates
 111.359 +	for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i];++i)	{
 111.360 +		if (ProcessArray(pMesh->mTextureCoords[i],pMesh->mNumVertices,"uvcoords",dirtyMask))	{
 111.361 +
 111.362 +			// delete all subsequent texture coordinate sets.
 111.363 +			for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a)	{
 111.364 +				delete[] pMesh->mTextureCoords[a]; pMesh->mTextureCoords[a] = NULL;
 111.365 +			}
 111.366 +			ret = true;
 111.367 +		}
 111.368 +	}
 111.369 +
 111.370 +	// -- we don't validate vertex colors, it's difficult to say whether
 111.371 +	// they are invalid or not.
 111.372 +
 111.373 +	// Normals and tangents are undefined for point and line faces.
 111.374 +	if (pMesh->mNormals || pMesh->mTangents)	{
 111.375 +
 111.376 +		if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes ||
 111.377 +			aiPrimitiveType_LINE  & pMesh->mPrimitiveTypes)
 111.378 +		{
 111.379 +			if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes ||
 111.380 +				aiPrimitiveType_POLYGON  & pMesh->mPrimitiveTypes)
 111.381 +			{
 111.382 +				// We need to update the lookup-table
 111.383 +				for (unsigned int m = 0; m < pMesh->mNumFaces;++m)
 111.384 +				{
 111.385 +					const aiFace& f = pMesh->mFaces[m];
 111.386 +
 111.387 +					if (f.mNumIndices < 3)	{
 111.388 +						dirtyMask[f.mIndices[0]] = true;
 111.389 +
 111.390 +						if (f.mNumIndices == 2) {
 111.391 +							dirtyMask[f.mIndices[1]] = true;
 111.392 +						}
 111.393 +					}
 111.394 +				}
 111.395 +			}
 111.396 +			// Normals, tangents and bitangents are undefined for
 111.397 +			// the whole mesh (and should not even be there)
 111.398 +			else return ret;
 111.399 +		}
 111.400 +
 111.401 +		// Process mesh normals
 111.402 +		if (pMesh->mNormals && ProcessArray(pMesh->mNormals,pMesh->mNumVertices,
 111.403 +			"normals",dirtyMask,true,false))
 111.404 +			ret = true;
 111.405 +
 111.406 +		// Process mesh tangents
 111.407 +		if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices,"tangents",dirtyMask))	{
 111.408 +			delete[] pMesh->mBitangents; pMesh->mBitangents = NULL;
 111.409 +			ret = true;
 111.410 +		}
 111.411 +
 111.412 +		// Process mesh bitangents
 111.413 +		if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices,"bitangents",dirtyMask))	{
 111.414 +			delete[] pMesh->mTangents; pMesh->mTangents = NULL;
 111.415 +			ret = true;
 111.416 +		}
 111.417 +	}
 111.418 +	return ret ? 1 : 0;
 111.419 +}
 111.420 +
 111.421 +
 111.422 +#endif // !! ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
   112.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   112.2 +++ b/libs/assimp/FindInvalidDataProcess.h	Sat Feb 01 19:58:19 2014 +0200
   112.3 @@ -0,0 +1,105 @@
   112.4 +/*
   112.5 +Open Asset Import Library (assimp)
   112.6 +----------------------------------------------------------------------
   112.7 +
   112.8 +Copyright (c) 2006-2012, assimp team
   112.9 +All rights reserved.
  112.10 +
  112.11 +Redistribution and use of this software in source and binary forms, 
  112.12 +with or without modification, are permitted provided that the 
  112.13 +following conditions are met:
  112.14 +
  112.15 +* Redistributions of source code must retain the above
  112.16 +  copyright notice, this list of conditions and the
  112.17 +  following disclaimer.
  112.18 +
  112.19 +* Redistributions in binary form must reproduce the above
  112.20 +  copyright notice, this list of conditions and the
  112.21 +  following disclaimer in the documentation and/or other
  112.22 +  materials provided with the distribution.
  112.23 +
  112.24 +* Neither the name of the assimp team, nor the names of its
  112.25 +  contributors may be used to endorse or promote products
  112.26 +  derived from this software without specific prior
  112.27 +  written permission of the assimp team.
  112.28 +
  112.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  112.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  112.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  112.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  112.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  112.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  112.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  112.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  112.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  112.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  112.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  112.40 +
  112.41 +----------------------------------------------------------------------
  112.42 +*/
  112.43 +
  112.44 +/** @file Defines a post processing step to search an importer's output
  112.45 +    for data that is obviously invalid  */
  112.46 +#ifndef AI_FINDINVALIDDATA_H_INC
  112.47 +#define AI_FINDINVALIDDATA_H_INC
  112.48 +
  112.49 +#include "BaseProcess.h"
  112.50 +#include "assimp/types.h"
  112.51 +
  112.52 +struct aiMesh;
  112.53 +class FindInvalidDataProcessTest;
  112.54 +namespace Assimp	{
  112.55 +
  112.56 +// ---------------------------------------------------------------------------
  112.57 +/** The FindInvalidData postprocessing step. It searches the mesh data
  112.58 + *  for parts that are obviously invalid and removes them.
  112.59 + *
  112.60 + *  Originally this was a workaround for some models written by Blender
  112.61 + *  which have zero normal vectors. */
  112.62 +class FindInvalidDataProcess 
  112.63 +	: public BaseProcess
  112.64 +{
  112.65 +public:
  112.66 +
  112.67 +	FindInvalidDataProcess();
  112.68 +	~FindInvalidDataProcess();
  112.69 +
  112.70 +public:
  112.71 +
  112.72 +	// -------------------------------------------------------------------
  112.73 +	// 
  112.74 +	bool IsActive( unsigned int pFlags) const;
  112.75 +
  112.76 +	// -------------------------------------------------------------------
  112.77 +	// Setup import settings
  112.78 +	void SetupProperties(const Importer* pImp);
  112.79 +
  112.80 +	// -------------------------------------------------------------------
  112.81 +	// Run the step
  112.82 +	void Execute( aiScene* pScene);
  112.83 +
  112.84 +public:
  112.85 +
  112.86 +	// -------------------------------------------------------------------
  112.87 +	/** Executes the postprocessing step on the given mesh
  112.88 +	 * @param pMesh The mesh to process.
  112.89 +	 * @return 0 - nothing, 1 - removed sth, 2 - please delete me  */
  112.90 +	int ProcessMesh( aiMesh* pMesh);
  112.91 +
  112.92 +	// -------------------------------------------------------------------
  112.93 +	/** Executes the postprocessing step on the given animation
  112.94 +	 * @param anim The animation to process.  */
  112.95 +	void ProcessAnimation (aiAnimation* anim);
  112.96 +
  112.97 +	// -------------------------------------------------------------------
  112.98 +	/** Executes the postprocessing step on the given anim channel
  112.99 +	 * @param anim The animation channel to process.*/
 112.100 +	void ProcessAnimationChannel (aiNodeAnim* anim);
 112.101 +
 112.102 +private:
 112.103 +	float configEpsilon;
 112.104 +};
 112.105 +
 112.106 +} // end of namespace Assimp
 112.107 +
 112.108 +#endif // AI_AI_FINDINVALIDDATA_H_INC
   113.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   113.2 +++ b/libs/assimp/FixNormalsStep.cpp	Sat Feb 01 19:58:19 2014 +0200
   113.3 @@ -0,0 +1,176 @@
   113.4 +/*
   113.5 +---------------------------------------------------------------------------
   113.6 +Open Asset Import Library (assimp)
   113.7 +---------------------------------------------------------------------------
   113.8 +
   113.9 +Copyright (c) 2006-2012, assimp team
  113.10 +
  113.11 +All rights reserved.
  113.12 +
  113.13 +Redistribution and use of this software in source and binary forms, 
  113.14 +with or without modification, are permitted provided that the following 
  113.15 +conditions are met:
  113.16 +
  113.17 +* Redistributions of source code must retain the above
  113.18 +  copyright notice, this list of conditions and the
  113.19 +  following disclaimer.
  113.20 +
  113.21 +* Redistributions in binary form must reproduce the above
  113.22 +  copyright notice, this list of conditions and the
  113.23 +  following disclaimer in the documentation and/or other
  113.24 +  materials provided with the distribution.
  113.25 +
  113.26 +* Neither the name of the assimp team, nor the names of its
  113.27 +  contributors may be used to endorse or promote products
  113.28 +  derived from this software without specific prior
  113.29 +  written permission of the assimp team.
  113.30 +
  113.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  113.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  113.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  113.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  113.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  113.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  113.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  113.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  113.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  113.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  113.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  113.42 +---------------------------------------------------------------------------
  113.43 +*/
  113.44 +
  113.45 +/** @file Implementation of the post processing step to invert
  113.46 + * all normals in meshes with infacing normals.
  113.47 + */
  113.48 +
  113.49 +#include "AssimpPCH.h"
  113.50 +
  113.51 +// internal headers
  113.52 +#include "FixNormalsStep.h"
  113.53 +
  113.54 +using namespace Assimp;
  113.55 +
  113.56 +
  113.57 +// ------------------------------------------------------------------------------------------------
  113.58 +// Constructor to be privately used by Importer
  113.59 +FixInfacingNormalsProcess::FixInfacingNormalsProcess()
  113.60 +{
  113.61 +	// nothing to do here
  113.62 +}
  113.63 +
  113.64 +// ------------------------------------------------------------------------------------------------
  113.65 +// Destructor, private as well
  113.66 +FixInfacingNormalsProcess::~FixInfacingNormalsProcess()
  113.67 +{
  113.68 +	// nothing to do here
  113.69 +}
  113.70 +
  113.71 +// ------------------------------------------------------------------------------------------------
  113.72 +// Returns whether the processing step is present in the given flag field.
  113.73 +bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const
  113.74 +{
  113.75 +	return (pFlags & aiProcess_FixInfacingNormals) != 0;
  113.76 +}
  113.77 +
  113.78 +// ------------------------------------------------------------------------------------------------
  113.79 +// Executes the post processing step on the given imported data.
  113.80 +void FixInfacingNormalsProcess::Execute( aiScene* pScene)
  113.81 +{
  113.82 +	DefaultLogger::get()->debug("FixInfacingNormalsProcess begin");
  113.83 +
  113.84 +	bool bHas = false;
  113.85 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
  113.86 +		if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
  113.87 +
  113.88 +	if (bHas)
  113.89 +		 DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. Found issues.");
  113.90 +	else DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. No changes to the scene.");
  113.91 +}
  113.92 +
  113.93 +// ------------------------------------------------------------------------------------------------
  113.94 +// Apply the step to the mesh
  113.95 +bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
  113.96 +{
  113.97 +	ai_assert(NULL != pcMesh);
  113.98 +
  113.99 +	// Nothing to do if there are no model normals
 113.100 +	if (!pcMesh->HasNormals())return false;
 113.101 +
 113.102 +	// Compute the bounding box of both the model vertices + normals and
 113.103 +	// the umodified model vertices. Then check whether the first BB
 113.104 +	// is smaller than the second. In this case we can assume that the
 113.105 +	// normals need to be flipped, although there are a few special cases ..
 113.106 +	// convex, concave, planar models ...
 113.107 +
 113.108 +	aiVector3D vMin0 (1e10f,1e10f,1e10f);
 113.109 +	aiVector3D vMin1 (1e10f,1e10f,1e10f);
 113.110 +	aiVector3D vMax0 (-1e10f,-1e10f,-1e10f);
 113.111 +	aiVector3D vMax1 (-1e10f,-1e10f,-1e10f);
 113.112 +
 113.113 +	for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
 113.114 +	{
 113.115 +		vMin1.x = std::min(vMin1.x,pcMesh->mVertices[i].x);
 113.116 +		vMin1.y = std::min(vMin1.y,pcMesh->mVertices[i].y);
 113.117 +		vMin1.z = std::min(vMin1.z,pcMesh->mVertices[i].z);
 113.118 +
 113.119 +		vMax1.x = std::max(vMax1.x,pcMesh->mVertices[i].x);
 113.120 +		vMax1.y = std::max(vMax1.y,pcMesh->mVertices[i].y);
 113.121 +		vMax1.z = std::max(vMax1.z,pcMesh->mVertices[i].z);
 113.122 +
 113.123 +		const aiVector3D vWithNormal = pcMesh->mVertices[i] + pcMesh->mNormals[i];
 113.124 +
 113.125 +		vMin0.x = std::min(vMin0.x,vWithNormal.x);
 113.126 +		vMin0.y = std::min(vMin0.y,vWithNormal.y);
 113.127 +		vMin0.z = std::min(vMin0.z,vWithNormal.z);
 113.128 +
 113.129 +		vMax0.x = std::max(vMax0.x,vWithNormal.x);
 113.130 +		vMax0.y = std::max(vMax0.y,vWithNormal.y);
 113.131 +		vMax0.z = std::max(vMax0.z,vWithNormal.z);
 113.132 +	}
 113.133 +
 113.134 +	const float fDelta0_x = (vMax0.x - vMin0.x);
 113.135 +	const float fDelta0_y = (vMax0.y - vMin0.y);
 113.136 +	const float fDelta0_z = (vMax0.z - vMin0.z);
 113.137 +
 113.138 +	const float fDelta1_x = (vMax1.x - vMin1.x);
 113.139 +	const float fDelta1_y = (vMax1.y - vMin1.y);
 113.140 +	const float fDelta1_z = (vMax1.z - vMin1.z);
 113.141 +
 113.142 +	// Check whether the boxes are overlapping
 113.143 +	if ((fDelta0_x > 0.0f) != (fDelta1_x > 0.0f))return false;
 113.144 +	if ((fDelta0_y > 0.0f) != (fDelta1_y > 0.0f))return false;
 113.145 +	if ((fDelta0_z > 0.0f) != (fDelta1_z > 0.0f))return false;
 113.146 +
 113.147 +	// Check whether this is a planar surface
 113.148 +	const float fDelta1_yz = fDelta1_y * fDelta1_z;
 113.149 +
 113.150 +	if (fDelta1_x < 0.05f * sqrtf( fDelta1_yz ))return false;
 113.151 +	if (fDelta1_y < 0.05f * sqrtf( fDelta1_z * fDelta1_x ))return false;
 113.152 +	if (fDelta1_z < 0.05f * sqrtf( fDelta1_y * fDelta1_x ))return false;
 113.153 +
 113.154 +	// now compare the volumes of the bounding boxes
 113.155 +	if (::fabsf(fDelta0_x * fDelta1_yz) <
 113.156 +		::fabsf(fDelta1_x * fDelta1_y * fDelta1_z))
 113.157 +	{
 113.158 +		if (!DefaultLogger::isNullLogger())
 113.159 +		{
 113.160 +			char buffer[128]; // should be sufficiently large
 113.161 +			::sprintf(buffer,"Mesh %i: Normals are facing inwards (or the mesh is planar)",index);
 113.162 +			DefaultLogger::get()->info(buffer);
 113.163 +		}
 113.164 +
 113.165 +		// Invert normals
 113.166 +		for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
 113.167 +			pcMesh->mNormals[i] *= -1.0f;
 113.168 +
 113.169 +		// ... and flip faces
 113.170 +		for (unsigned int i = 0; i < pcMesh->mNumFaces;++i)
 113.171 +		{
 113.172 +			aiFace& face = pcMesh->mFaces[i];
 113.173 +			for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
 113.174 +				std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
 113.175 +		}
 113.176 +		return true;
 113.177 +	}
 113.178 +	return false;
 113.179 +}
   114.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   114.2 +++ b/libs/assimp/FixNormalsStep.h	Sat Feb 01 19:58:19 2014 +0200
   114.3 @@ -0,0 +1,92 @@
   114.4 +/*
   114.5 +Open Asset Import Library (assimp)
   114.6 +----------------------------------------------------------------------
   114.7 +
   114.8 +Copyright (c) 2006-2012, assimp team
   114.9 +All rights reserved.
  114.10 +
  114.11 +Redistribution and use of this software in source and binary forms, 
  114.12 +with or without modification, are permitted provided that the 
  114.13 +following conditions are met:
  114.14 +
  114.15 +* Redistributions of source code must retain the above
  114.16 +  copyright notice, this list of conditions and the
  114.17 +  following disclaimer.
  114.18 +
  114.19 +* Redistributions in binary form must reproduce the above
  114.20 +  copyright notice, this list of conditions and the
  114.21 +  following disclaimer in the documentation and/or other
  114.22 +  materials provided with the distribution.
  114.23 +
  114.24 +* Neither the name of the assimp team, nor the names of its
  114.25 +  contributors may be used to endorse or promote products
  114.26 +  derived from this software without specific prior
  114.27 +  written permission of the assimp team.
  114.28 +
  114.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  114.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  114.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  114.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  114.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  114.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  114.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  114.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  114.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  114.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  114.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  114.40 +
  114.41 +----------------------------------------------------------------------
  114.42 +*/
  114.43 +
  114.44 +
  114.45 +/** @file Defines a post processing step to fix infacing normals */
  114.46 +#ifndef AI_FIXNORMALSPROCESS_H_INC
  114.47 +#define AI_FIXNORMALSPROCESS_H_INC
  114.48 +
  114.49 +#include "BaseProcess.h"
  114.50 +
  114.51 +struct aiMesh;
  114.52 +
  114.53 +namespace Assimp
  114.54 +{
  114.55 +
  114.56 +// ---------------------------------------------------------------------------
  114.57 +/** The FixInfacingNormalsProcess tries to determine whether the normal
  114.58 + * vectors of an object are facing inwards. In this case they will be
  114.59 + * flipped.
  114.60 + */
  114.61 +class FixInfacingNormalsProcess : public BaseProcess
  114.62 +{
  114.63 +public:
  114.64 +	
  114.65 +	FixInfacingNormalsProcess();
  114.66 +	~FixInfacingNormalsProcess();
  114.67 +
  114.68 +public:
  114.69 +	// -------------------------------------------------------------------
  114.70 +	/** Returns whether the processing step is present in the given flag field.
  114.71 +	 * @param pFlags The processing flags the importer was called with. A bitwise
  114.72 +	 *   combination of #aiPostProcessSteps.
  114.73 +	 * @return true if the process is present in this flag fields, false if not.
  114.74 +	*/
  114.75 +	bool IsActive( unsigned int pFlags) const;
  114.76 +
  114.77 +	// -------------------------------------------------------------------
  114.78 +	/** Executes the post processing step on the given imported data.
  114.79 +	* At the moment a process is not supposed to fail.
  114.80 +	* @param pScene The imported data to work at.
  114.81 +	*/
  114.82 +	void Execute( aiScene* pScene);
  114.83 +
  114.84 +protected:
  114.85 +
  114.86 +	// -------------------------------------------------------------------
  114.87 +	/** Executes the step on the given mesh
  114.88 +	 * @param pMesh The mesh to process.
  114.89 +	 */
  114.90 +	bool ProcessMesh( aiMesh* pMesh, unsigned int index);
  114.91 +};
  114.92 +
  114.93 +} // end of namespace Assimp
  114.94 +
  114.95 +#endif // AI_FIXNORMALSPROCESS_H_INC
   115.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   115.2 +++ b/libs/assimp/GenFaceNormalsProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
   115.3 @@ -0,0 +1,138 @@
   115.4 +/*
   115.5 +---------------------------------------------------------------------------
   115.6 +Open Asset Import Library (assimp)
   115.7 +---------------------------------------------------------------------------
   115.8 +
   115.9 +Copyright (c) 2006-2012, assimp team
  115.10 +
  115.11 +All rights reserved.
  115.12 +
  115.13 +Redistribution and use of this software in source and binary forms, 
  115.14 +with or without modification, are permitted provided that the following 
  115.15 +conditions are met:
  115.16 +
  115.17 +* Redistributions of source code must retain the above
  115.18 +  copyright notice, this list of conditions and the
  115.19 +  following disclaimer.
  115.20 +
  115.21 +* Redistributions in binary form must reproduce the above
  115.22 +  copyright notice, this list of conditions and the
  115.23 +  following disclaimer in the documentation and/or other
  115.24 +  materials provided with the distribution.
  115.25 +
  115.26 +* Neither the name of the assimp team, nor the names of its
  115.27 +  contributors may be used to endorse or promote products
  115.28 +  derived from this software without specific prior
  115.29 +  written permission of the assimp team.
  115.30 +
  115.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  115.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  115.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  115.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  115.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  115.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  115.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  115.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  115.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  115.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  115.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  115.42 +---------------------------------------------------------------------------
  115.43 +*/
  115.44 +
  115.45 +/** @file Implementation of the post processing step to generate face
  115.46 +* normals for all imported faces.
  115.47 +*/
  115.48 +
  115.49 +#include "AssimpPCH.h"
  115.50 +#include "GenFaceNormalsProcess.h"
  115.51 +
  115.52 +
  115.53 +using namespace Assimp;
  115.54 +
  115.55 +// ------------------------------------------------------------------------------------------------
  115.56 +// Constructor to be privately used by Importer
  115.57 +GenFaceNormalsProcess::GenFaceNormalsProcess()
  115.58 +{
  115.59 +	// nothing to do here
  115.60 +}
  115.61 +
  115.62 +// ------------------------------------------------------------------------------------------------
  115.63 +// Destructor, private as well
  115.64 +GenFaceNormalsProcess::~GenFaceNormalsProcess()
  115.65 +{
  115.66 +	// nothing to do here
  115.67 +}
  115.68 +
  115.69 +// ------------------------------------------------------------------------------------------------
  115.70 +// Returns whether the processing step is present in the given flag field.
  115.71 +bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const
  115.72 +{
  115.73 +	return	(pFlags & aiProcess_GenNormals) != 0;
  115.74 +}
  115.75 +
  115.76 +// ------------------------------------------------------------------------------------------------
  115.77 +// Executes the post processing step on the given imported data.
  115.78 +void GenFaceNormalsProcess::Execute( aiScene* pScene)
  115.79 +{
  115.80 +	DefaultLogger::get()->debug("GenFaceNormalsProcess begin");
  115.81 +
  115.82 +	if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
  115.83 +		throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
  115.84 +	}
  115.85 +
  115.86 +	bool bHas = false;
  115.87 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)	{
  115.88 +		if(this->GenMeshFaceNormals( pScene->mMeshes[a])) {
  115.89 +			bHas = true;
  115.90 +		}
  115.91 +	}
  115.92 +	if (bHas)	{
  115.93 +		DefaultLogger::get()->info("GenFaceNormalsProcess finished. "
  115.94 +			"Face normals have been calculated");
  115.95 +	}
  115.96 +	else DefaultLogger::get()->debug("GenFaceNormalsProcess finished. "
  115.97 +		"Normals are already there");
  115.98 +}
  115.99 +
 115.100 +// ------------------------------------------------------------------------------------------------
 115.101 +// Executes the post processing step on the given imported data.
 115.102 +bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
 115.103 +{
 115.104 +	if (NULL != pMesh->mNormals) {
 115.105 +		return false;
 115.106 +	}
 115.107 +
 115.108 +	// If the mesh consists of lines and/or points but not of
 115.109 +	// triangles or higher-order polygons the normal vectors
 115.110 +	// are undefined.
 115.111 +	if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))	{
 115.112 +		DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes");
 115.113 +		return false;
 115.114 +	}
 115.115 +
 115.116 +	// allocate an array to hold the output normals
 115.117 +	pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
 115.118 +	const float qnan = get_qnan();
 115.119 +
 115.120 +	// iterate through all faces and compute per-face normals but store them per-vertex. 
 115.121 +	for( unsigned int a = 0; a < pMesh->mNumFaces; a++)	{
 115.122 +		const aiFace& face = pMesh->mFaces[a];
 115.123 +		if (face.mNumIndices < 3)	{
 115.124 +			// either a point or a line -> no well-defined normal vector
 115.125 +			for (unsigned int i = 0;i < face.mNumIndices;++i) {
 115.126 +				pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan);
 115.127 +			}
 115.128 +			continue;
 115.129 +		}
 115.130 +
 115.131 +		const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
 115.132 +		const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
 115.133 +		const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
 115.134 +		const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
 115.135 +
 115.136 +		for (unsigned int i = 0;i < face.mNumIndices;++i) {
 115.137 +			pMesh->mNormals[face.mIndices[i]] = vNor;
 115.138 +		}
 115.139 +	}
 115.140 +	return true;
 115.141 +}
   116.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   116.2 +++ b/libs/assimp/GenFaceNormalsProcess.h	Sat Feb 01 19:58:19 2014 +0200
   116.3 @@ -0,0 +1,84 @@
   116.4 +/*
   116.5 +Open Asset Import Library (assimp)
   116.6 +----------------------------------------------------------------------
   116.7 +
   116.8 +Copyright (c) 2006-2012, assimp team
   116.9 +All rights reserved.
  116.10 +
  116.11 +Redistribution and use of this software in source and binary forms, 
  116.12 +with or without modification, are permitted provided that the 
  116.13 +following conditions are met:
  116.14 +
  116.15 +* Redistributions of source code must retain the above
  116.16 +  copyright notice, this list of conditions and the
  116.17 +  following disclaimer.
  116.18 +
  116.19 +* Redistributions in binary form must reproduce the above
  116.20 +  copyright notice, this list of conditions and the
  116.21 +  following disclaimer in the documentation and/or other
  116.22 +  materials provided with the distribution.
  116.23 +
  116.24 +* Neither the name of the assimp team, nor the names of its
  116.25 +  contributors may be used to endorse or promote products
  116.26 +  derived from this software without specific prior
  116.27 +  written permission of the assimp team.
  116.28 +
  116.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  116.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  116.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  116.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  116.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  116.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  116.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  116.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  116.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  116.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  116.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  116.40 +
  116.41 +----------------------------------------------------------------------
  116.42 +*/
  116.43 +
  116.44 +/** @file Defines a post processing step to compute face normals for all loaded faces*/
  116.45 +#ifndef AI_GENFACENORMALPROCESS_H_INC
  116.46 +#define AI_GENFACENORMALPROCESS_H_INC
  116.47 +
  116.48 +#include "BaseProcess.h"
  116.49 +#include "assimp/mesh.h"
  116.50 +
  116.51 +namespace Assimp
  116.52 +{
  116.53 +
  116.54 +// ---------------------------------------------------------------------------
  116.55 +/** The GenFaceNormalsProcess computes face normals for all faces of all meshes
  116.56 +*/
  116.57 +class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess
  116.58 +{
  116.59 +public:
  116.60 +
  116.61 +	GenFaceNormalsProcess();
  116.62 +	~GenFaceNormalsProcess();
  116.63 +
  116.64 +public:
  116.65 +	// -------------------------------------------------------------------
  116.66 +	/** Returns whether the processing step is present in the given flag field.
  116.67 +	* @param pFlags The processing flags the importer was called with. A bitwise
  116.68 +	*   combination of #aiPostProcessSteps.
  116.69 +	* @return true if the process is present in this flag fields, false if not.
  116.70 +	*/
  116.71 +	bool IsActive( unsigned int pFlags) const;
  116.72 +
  116.73 +	// -------------------------------------------------------------------
  116.74 +	/** Executes the post processing step on the given imported data.
  116.75 +	* At the moment a process is not supposed to fail.
  116.76 +	* @param pScene The imported data to work at.
  116.77 +	*/
  116.78 +	void Execute( aiScene* pScene);
  116.79 +
  116.80 +
  116.81 +private:
  116.82 +	bool GenMeshFaceNormals (aiMesh* pcMesh);
  116.83 +};
  116.84 +
  116.85 +} // end of namespace Assimp
  116.86 +
  116.87 +#endif // !!AI_GENFACENORMALPROCESS_H_INC
   117.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   117.2 +++ b/libs/assimp/GenVertexNormalsProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
   117.3 @@ -0,0 +1,233 @@
   117.4 +/*
   117.5 +---------------------------------------------------------------------------
   117.6 +Open Asset Import Library (assimp)
   117.7 +---------------------------------------------------------------------------
   117.8 +
   117.9 +Copyright (c) 2006-2012, assimp team
  117.10 +
  117.11 +All rights reserved.
  117.12 +
  117.13 +Redistribution and use of this software in source and binary forms, 
  117.14 +with or without modification, are permitted provided that the following 
  117.15 +conditions are met:
  117.16 +
  117.17 +* Redistributions of source code must retain the above
  117.18 +  copyright notice, this list of conditions and the
  117.19 +  following disclaimer.
  117.20 +
  117.21 +* Redistributions in binary form must reproduce the above
  117.22 +  copyright notice, this list of conditions and the
  117.23 +  following disclaimer in the documentation and/or other
  117.24 +  materials provided with the distribution.
  117.25 +
  117.26 +* Neither the name of the assimp team, nor the names of its
  117.27 +  contributors may be used to endorse or promote products
  117.28 +  derived from this software without specific prior
  117.29 +  written permission of the assimp team.
  117.30 +
  117.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  117.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  117.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  117.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  117.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  117.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  117.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  117.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  117.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  117.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  117.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  117.42 +---------------------------------------------------------------------------
  117.43 +*/
  117.44 +
  117.45 +/** @file Implementation of the post processing step to generate face
  117.46 +* normals for all imported faces.
  117.47 +*/
  117.48 +
  117.49 +#include "AssimpPCH.h"
  117.50 +
  117.51 +// internal headers
  117.52 +#include "GenVertexNormalsProcess.h"
  117.53 +#include "ProcessHelper.h"
  117.54 +
  117.55 +using namespace Assimp;
  117.56 +
  117.57 +// ------------------------------------------------------------------------------------------------
  117.58 +// Constructor to be privately used by Importer
  117.59 +GenVertexNormalsProcess::GenVertexNormalsProcess()
  117.60 +{
  117.61 +	this->configMaxAngle = AI_DEG_TO_RAD(175.f);
  117.62 +}
  117.63 +
  117.64 +// ------------------------------------------------------------------------------------------------
  117.65 +// Destructor, private as well
  117.66 +GenVertexNormalsProcess::~GenVertexNormalsProcess()
  117.67 +{
  117.68 +	// nothing to do here
  117.69 +}
  117.70 +
  117.71 +// ------------------------------------------------------------------------------------------------
  117.72 +// Returns whether the processing step is present in the given flag field.
  117.73 +bool GenVertexNormalsProcess::IsActive( unsigned int pFlags) const
  117.74 +{
  117.75 +	return (pFlags & aiProcess_GenSmoothNormals) != 0;
  117.76 +}
  117.77 +
  117.78 +// ------------------------------------------------------------------------------------------------
  117.79 +// Executes the post processing step on the given imported data.
  117.80 +void GenVertexNormalsProcess::SetupProperties(const Importer* pImp)
  117.81 +{
  117.82 +	// Get the current value of the AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE property
  117.83 +	configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,175.f);
  117.84 +	configMaxAngle = AI_DEG_TO_RAD(std::max(std::min(configMaxAngle,175.0f),0.0f));
  117.85 +}
  117.86 +
  117.87 +// ------------------------------------------------------------------------------------------------
  117.88 +// Executes the post processing step on the given imported data.
  117.89 +void GenVertexNormalsProcess::Execute( aiScene* pScene)
  117.90 +{
  117.91 +	DefaultLogger::get()->debug("GenVertexNormalsProcess begin");
  117.92 +
  117.93 +	if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
  117.94 +		throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
  117.95 +
  117.96 +	bool bHas = false;
  117.97 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
  117.98 +	{
  117.99 +		if(GenMeshVertexNormals( pScene->mMeshes[a],a))
 117.100 +			bHas = true;
 117.101 +	}
 117.102 +
 117.103 +	if (bHas)	{
 117.104 +		DefaultLogger::get()->info("GenVertexNormalsProcess finished. "
 117.105 +			"Vertex normals have been calculated");
 117.106 +	}
 117.107 +	else DefaultLogger::get()->debug("GenVertexNormalsProcess finished. "
 117.108 +		"Normals are already there");
 117.109 +}
 117.110 +
 117.111 +// ------------------------------------------------------------------------------------------------
 117.112 +// Executes the post processing step on the given imported data.
 117.113 +bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex)
 117.114 +{
 117.115 +	if (NULL != pMesh->mNormals)
 117.116 +		return false;
 117.117 +
 117.118 +	// If the mesh consists of lines and/or points but not of
 117.119 +	// triangles or higher-order polygons the normal vectors
 117.120 +	// are undefined.
 117.121 +	if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
 117.122 +	{
 117.123 +		DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes");
 117.124 +		return false;
 117.125 +	}
 117.126 +
 117.127 +	// Allocate the array to hold the output normals
 117.128 +	const float qnan = std::numeric_limits<float>::quiet_NaN();
 117.129 +	pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
 117.130 +
 117.131 +	// Compute per-face normals but store them per-vertex
 117.132 +	for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
 117.133 +	{
 117.134 +		const aiFace& face = pMesh->mFaces[a];
 117.135 +		if (face.mNumIndices < 3)
 117.136 +		{
 117.137 +			// either a point or a line -> no normal vector
 117.138 +			for (unsigned int i = 0;i < face.mNumIndices;++i) {
 117.139 +				pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan);
 117.140 +			}
 117.141 +
 117.142 +			continue;
 117.143 +		}
 117.144 +
 117.145 +		const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
 117.146 +		const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
 117.147 +		const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
 117.148 +		const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
 117.149 +
 117.150 +		for (unsigned int i = 0;i < face.mNumIndices;++i) {
 117.151 +			pMesh->mNormals[face.mIndices[i]] = vNor;
 117.152 +		}
 117.153 +	}
 117.154 +
 117.155 +	// Set up a SpatialSort to quickly find all vertices close to a given position
 117.156 +	// check whether we can reuse the SpatialSort of a previous step.
 117.157 +	SpatialSort* vertexFinder = NULL;
 117.158 +	SpatialSort  _vertexFinder;
 117.159 +	float posEpsilon = 1e-5f;
 117.160 +	if (shared)	{
 117.161 +		std::vector<std::pair<SpatialSort,float> >* avf;
 117.162 +		shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
 117.163 +		if (avf)
 117.164 +		{
 117.165 +			std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
 117.166 +			vertexFinder = &blubb.first;
 117.167 +			posEpsilon = blubb.second;
 117.168 +		}
 117.169 +	}
 117.170 +	if (!vertexFinder)	{
 117.171 +		_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
 117.172 +		vertexFinder = &_vertexFinder;
 117.173 +		posEpsilon = ComputePositionEpsilon(pMesh);
 117.174 +	}
 117.175 +	std::vector<unsigned int> verticesFound;
 117.176 +	aiVector3D* pcNew = new aiVector3D[pMesh->mNumVertices];
 117.177 +
 117.178 +	if (configMaxAngle >= AI_DEG_TO_RAD( 175.f ))	{
 117.179 +		// There is no angle limit. Thus all vertices with positions close
 117.180 +		// to each other will receive the same vertex normal. This allows us
 117.181 +		// to optimize the whole algorithm a little bit ...
 117.182 +		std::vector<bool> abHad(pMesh->mNumVertices,false);
 117.183 +		for (unsigned int i = 0; i < pMesh->mNumVertices;++i)	{
 117.184 +			if (abHad[i]) {
 117.185 +				continue;
 117.186 +			}
 117.187 +
 117.188 +			// Get all vertices that share this one ...
 117.189 +			vertexFinder->FindPositions( pMesh->mVertices[i], posEpsilon, verticesFound);
 117.190 +
 117.191 +			aiVector3D pcNor; 
 117.192 +			for (unsigned int a = 0; a < verticesFound.size(); ++a)	{
 117.193 +				const aiVector3D& v = pMesh->mNormals[verticesFound[a]];
 117.194 +				if (is_not_qnan(v.x))pcNor += v;
 117.195 +			}
 117.196 +			pcNor.Normalize();
 117.197 +
 117.198 +			// Write the smoothed normal back to all affected normals
 117.199 +			for (unsigned int a = 0; a < verticesFound.size(); ++a)
 117.200 +			{
 117.201 +				register unsigned int vidx = verticesFound[a];
 117.202 +				pcNew[vidx] = pcNor;
 117.203 +				abHad[vidx] = true;
 117.204 +			}
 117.205 +		}
 117.206 +	}
 117.207 +	// Slower code path if a smooth angle is set. There are many ways to achieve
 117.208 +	// the effect, this one is the most straightforward one.
 117.209 +	else	{
 117.210 +		const float fLimit = ::cos(configMaxAngle); 
 117.211 +		for (unsigned int i = 0; i < pMesh->mNumVertices;++i)	{
 117.212 +			// Get all vertices that share this one ...
 117.213 +			vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
 117.214 +
 117.215 +			aiVector3D pcNor; 
 117.216 +			for (unsigned int a = 0; a < verticesFound.size(); ++a)	{
 117.217 +				const aiVector3D& v = pMesh->mNormals[verticesFound[a]];
 117.218 +
 117.219 +				// check whether the angle between the two normals is not too large
 117.220 +				// HACK: if v.x is qnan the dot product will become qnan, too
 117.221 +				//   therefore the comparison against fLimit should be false
 117.222 +				//   in every case. 
 117.223 +				if (v * pMesh->mNormals[i] < fLimit)
 117.224 +					continue;
 117.225 +
 117.226 +				pcNor += v;
 117.227 +			}
 117.228 +			pcNew[i] = pcNor.Normalize();
 117.229 +		}
 117.230 +	}
 117.231 +
 117.232 +	delete[] pMesh->mNormals;
 117.233 +	pMesh->mNormals = pcNew;
 117.234 +
 117.235 +	return true;
 117.236 +}
   118.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   118.2 +++ b/libs/assimp/GenVertexNormalsProcess.h	Sat Feb 01 19:58:19 2014 +0200
   118.3 @@ -0,0 +1,113 @@
   118.4 +/*
   118.5 +Open Asset Import Library (assimp)
   118.6 +----------------------------------------------------------------------
   118.7 +
   118.8 +Copyright (c) 2006-2012, assimp team
   118.9 +All rights reserved.
  118.10 +
  118.11 +Redistribution and use of this software in source and binary forms, 
  118.12 +with or without modification, are permitted provided that the 
  118.13 +following conditions are met:
  118.14 +
  118.15 +* Redistributions of source code must retain the above
  118.16 +  copyright notice, this list of conditions and the
  118.17 +  following disclaimer.
  118.18 +
  118.19 +* Redistributions in binary form must reproduce the above
  118.20 +  copyright notice, this list of conditions and the
  118.21 +  following disclaimer in the documentation and/or other
  118.22 +  materials provided with the distribution.
  118.23 +
  118.24 +* Neither the name of the assimp team, nor the names of its
  118.25 +  contributors may be used to endorse or promote products
  118.26 +  derived from this software without specific prior
  118.27 +  written permission of the assimp team.
  118.28 +
  118.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  118.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  118.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  118.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  118.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  118.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  118.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  118.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  118.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  118.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  118.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  118.40 +
  118.41 +----------------------------------------------------------------------
  118.42 +*/
  118.43 +
  118.44 +/** @file Defines a post processing step to compute vertex normals 
  118.45 +    for all loaded vertizes */
  118.46 +#ifndef AI_GENVERTEXNORMALPROCESS_H_INC
  118.47 +#define AI_GENVERTEXNORMALPROCESS_H_INC
  118.48 +
  118.49 +#include "BaseProcess.h"
  118.50 +#include "assimp/mesh.h"
  118.51 +
  118.52 +class GenNormalsTest;
  118.53 +
  118.54 +namespace Assimp {
  118.55 +
  118.56 +// ---------------------------------------------------------------------------
  118.57 +/** The GenFaceNormalsProcess computes vertex normals for all vertizes
  118.58 +*/
  118.59 +class ASSIMP_API_WINONLY GenVertexNormalsProcess : public BaseProcess
  118.60 +{
  118.61 +public:
  118.62 +
  118.63 +	GenVertexNormalsProcess();
  118.64 +	~GenVertexNormalsProcess();
  118.65 +
  118.66 +public:
  118.67 +	// -------------------------------------------------------------------
  118.68 +	/** Returns whether the processing step is present in the given flag.
  118.69 +	* @param pFlags The processing flags the importer was called with. 
  118.70 +	*   A bitwise combination of #aiPostProcessSteps.
  118.71 +	* @return true if the process is present in this flag fields, 
  118.72 +	*   false if not.
  118.73 +	*/
  118.74 +	bool IsActive( unsigned int pFlags) const;
  118.75 +	
  118.76 +	// -------------------------------------------------------------------
  118.77 +	/** Called prior to ExecuteOnScene().
  118.78 +	* The function is a request to the process to update its configuration
  118.79 +	* basing on the Importer's configuration property list.
  118.80 +	*/
  118.81 +	void SetupProperties(const Importer* pImp);
  118.82 +
  118.83 +	// -------------------------------------------------------------------
  118.84 +	/** Executes the post processing step on the given imported data.
  118.85 +	* At the moment a process is not supposed to fail.
  118.86 +	* @param pScene The imported data to work at.
  118.87 +	*/
  118.88 +	void Execute( aiScene* pScene);
  118.89 +
  118.90 +
  118.91 +	// setter for configMaxAngle
  118.92 +	inline void SetMaxSmoothAngle(float f)
  118.93 +	{
  118.94 +		configMaxAngle =f;
  118.95 +	}
  118.96 +
  118.97 +public:
  118.98 +
  118.99 +	// -------------------------------------------------------------------
 118.100 +	/** Computes normals for a specific mesh
 118.101 +	*  @param pcMesh Mesh
 118.102 +	*  @param meshIndex Index of the mesh
 118.103 +	*  @return true if vertex normals have been computed
 118.104 +	*/
 118.105 +	bool GenMeshVertexNormals (aiMesh* pcMesh, unsigned int meshIndex);
 118.106 +
 118.107 +private:
 118.108 +
 118.109 +	/** Configuration option: maximum smoothing angle, in radians*/
 118.110 +	float configMaxAngle;
 118.111 +};
 118.112 +
 118.113 +} // end of namespace Assimp
 118.114 +
 118.115 +#endif // !!AI_GENVERTEXNORMALPROCESS_H_INC
 118.116 +
   119.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   119.2 +++ b/libs/assimp/GenericProperty.h	Sat Feb 01 19:58:19 2014 +0200
   119.3 @@ -0,0 +1,112 @@
   119.4 +/*
   119.5 +Open Asset Import Library (assimp)
   119.6 +----------------------------------------------------------------------
   119.7 +
   119.8 +Copyright (c) 2006-2012, assimp team
   119.9 +All rights reserved.
  119.10 +
  119.11 +Redistribution and use of this software in source and binary forms, 
  119.12 +with or without modification, are permitted provided that the 
  119.13 +following conditions are met:
  119.14 +
  119.15 +* Redistributions of source code must retain the above
  119.16 +  copyright notice, this list of conditions and the
  119.17 +  following disclaimer.
  119.18 +
  119.19 +* Redistributions in binary form must reproduce the above
  119.20 +  copyright notice, this list of conditions and the
  119.21 +  following disclaimer in the documentation and/or other
  119.22 +  materials provided with the distribution.
  119.23 +
  119.24 +* Neither the name of the assimp team, nor the names of its
  119.25 +  contributors may be used to endorse or promote products
  119.26 +  derived from this software without specific prior
  119.27 +  written permission of the assimp team.
  119.28 +
  119.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  119.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  119.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  119.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  119.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  119.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  119.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  119.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  119.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  119.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  119.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  119.40 +
  119.41 +----------------------------------------------------------------------
  119.42 +*/
  119.43 +
  119.44 +#ifndef AI_GENERIC_PROPERTY_H_INCLUDED
  119.45 +#define AI_GENERIC_PROPERTY_H_INCLUDED
  119.46 +
  119.47 +#include "assimp/Importer.hpp"
  119.48 +#include "Hash.h"
  119.49 +
  119.50 +// ------------------------------------------------------------------------------------------------
  119.51 +template <class T>
  119.52 +inline void SetGenericProperty(std::map< unsigned int, T >& list, 
  119.53 +	const char* szName, const T& value, bool* bWasExisting = NULL)
  119.54 +{
  119.55 +	ai_assert(NULL != szName);
  119.56 +	const uint32_t hash = SuperFastHash(szName);
  119.57 +
  119.58 +	typename std::map<unsigned int, T>::iterator it = list.find(hash);
  119.59 +	if (it == list.end())	{
  119.60 +		if (bWasExisting)
  119.61 +			*bWasExisting = false;
  119.62 +		list.insert(std::pair<unsigned int, T>( hash, value ));
  119.63 +		return;
  119.64 +	}
  119.65 +	(*it).second = value;
  119.66 +	if (bWasExisting)
  119.67 +		*bWasExisting = true;
  119.68 +}
  119.69 +
  119.70 +// ------------------------------------------------------------------------------------------------
  119.71 +template <class T>
  119.72 +inline const T& GetGenericProperty(const std::map< unsigned int, T >& list, 
  119.73 +	const char* szName, const T& errorReturn)
  119.74 +{
  119.75 +	ai_assert(NULL != szName);
  119.76 +	const uint32_t hash = SuperFastHash(szName);
  119.77 +
  119.78 +	typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
  119.79 +	if (it == list.end())
  119.80 +		return errorReturn;
  119.81 +	
  119.82 +	return (*it).second;
  119.83 +}
  119.84 +
  119.85 +// ------------------------------------------------------------------------------------------------
  119.86 +// Special version for pointer types - they will be deleted when replaced with another value
  119.87 +// passing NULL removes the whole property
  119.88 +template <class T>
  119.89 +inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list, 
  119.90 +	const char* szName, T* value, bool* bWasExisting = NULL)
  119.91 +{
  119.92 +	ai_assert(NULL != szName);
  119.93 +	const uint32_t hash = SuperFastHash(szName);
  119.94 +
  119.95 +	typename std::map<unsigned int, T*>::iterator it = list.find(hash);
  119.96 +	if (it == list.end())	{
  119.97 +		if (bWasExisting)
  119.98 +			*bWasExisting = false;
  119.99 +		
 119.100 +		list.insert(std::pair<unsigned int,T*>( hash, value ));
 119.101 +		return;
 119.102 +	}
 119.103 +	if ((*it).second != value)	{
 119.104 +		delete (*it).second;
 119.105 +		(*it).second = value;
 119.106 +	}
 119.107 +	if (!value)	{
 119.108 +		list.erase(it);
 119.109 +	}
 119.110 +	if (bWasExisting)
 119.111 +		*bWasExisting = true;
 119.112 +}
 119.113 +
 119.114 +
 119.115 +#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED
   120.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   120.2 +++ b/libs/assimp/HMPFileData.h	Sat Feb 01 19:58:19 2014 +0200
   120.3 @@ -0,0 +1,134 @@
   120.4 +/*
   120.5 +Open Asset Import Library (assimp)
   120.6 +----------------------------------------------------------------------
   120.7 +
   120.8 +Copyright (c) 2006-2012, assimp team
   120.9 +All rights reserved.
  120.10 +
  120.11 +Redistribution and use of this software in source and binary forms, 
  120.12 +with or without modification, are permitted provided that the 
  120.13 +following conditions are met:
  120.14 +
  120.15 +* Redistributions of source code must retain the above
  120.16 +  copyright notice, this list of conditions and the
  120.17 +  following disclaimer.
  120.18 +
  120.19 +* Redistributions in binary form must reproduce the above
  120.20 +  copyright notice, this list of conditions and the
  120.21 +  following disclaimer in the documentation and/or other
  120.22 +  materials provided with the distribution.
  120.23 +
  120.24 +* Neither the name of the assimp team, nor the names of its
  120.25 +  contributors may be used to endorse or promote products
  120.26 +  derived from this software without specific prior
  120.27 +  written permission of the assimp team.
  120.28 +
  120.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  120.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  120.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  120.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  120.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  120.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  120.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  120.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  120.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  120.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  120.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  120.40 +
  120.41 +----------------------------------------------------------------------
  120.42 +*/
  120.43 +//!
  120.44 +//! @file Data structures for the 3D Game Studio Heightmap format (HMP)
  120.45 +//!
  120.46 +
  120.47 +namespace Assimp	{
  120.48 +namespace HMP	{
  120.49 +
  120.50 +#include "assimp/Compiler/pushpack1.h"
  120.51 +
  120.52 +// to make it easier for us, we test the magic word against both "endianesses"
  120.53 +#define AI_HMP_MAGIC_NUMBER_BE_4	AI_MAKE_MAGIC("HMP4")
  120.54 +#define AI_HMP_MAGIC_NUMBER_LE_4	AI_MAKE_MAGIC("4PMH")
  120.55 +
  120.56 +#define AI_HMP_MAGIC_NUMBER_BE_5	AI_MAKE_MAGIC("HMP5")
  120.57 +#define AI_HMP_MAGIC_NUMBER_LE_5	AI_MAKE_MAGIC("5PMH")
  120.58 +
  120.59 +#define AI_HMP_MAGIC_NUMBER_BE_7	AI_MAKE_MAGIC("HMP7")
  120.60 +#define AI_HMP_MAGIC_NUMBER_LE_7	AI_MAKE_MAGIC("7PMH")
  120.61 +
  120.62 +// ---------------------------------------------------------------------------
  120.63 +/** Data structure for the header of a HMP5 file.
  120.64 + *  This is also used by HMP4 and HMP7, but with modifications
  120.65 +*/
  120.66 +struct Header_HMP5
  120.67 +{
  120.68 +	int8_t	ident[4]; // "HMP5"
  120.69 +	int32_t		version;
  120.70 +	
  120.71 +	// ignored
  120.72 +	float	scale[3];
  120.73 +	float	scale_origin[3];
  120.74 +	float	boundingradius;
  120.75 +	
  120.76 +	//! Size of one triangle in x direction
  120.77 +	float	ftrisize_x;		
  120.78 +	//! Size of one triangle in y direction
  120.79 +	float	ftrisize_y;		
  120.80 +	//! Number of vertices in x direction
  120.81 +	float	fnumverts_x;	
  120.82 +							
  120.83 +	//! Number of skins in the file
  120.84 +	int32_t		numskins;
  120.85 +
  120.86 +	// can ignore this?
  120.87 +	int32_t		skinwidth;
  120.88 +	int32_t		skinheight;
  120.89 +
  120.90 +	//!Number of vertices in the file
  120.91 +	int32_t		numverts;
  120.92 +
  120.93 +	// ignored and zero
  120.94 +	int32_t		numtris;
  120.95 +
  120.96 +	//! only one supported ...
  120.97 +	int32_t		numframes;		
  120.98 +
  120.99 +	//! Always 0 ...
 120.100 +	int32_t		num_stverts;	
 120.101 +	int32_t		flags;
 120.102 +	float	size;
 120.103 +} PACK_STRUCT;
 120.104 +
 120.105 +// ---------------------------------------------------------------------------
 120.106 +/** Data structure for a terrain vertex in a HMP4 file 
 120.107 +*/
 120.108 +struct Vertex_HMP4
 120.109 +{
 120.110 +	uint16_t p_pos[3];		
 120.111 +	uint8_t normals162index;	
 120.112 +	uint8_t pad;				
 120.113 +} PACK_STRUCT;
 120.114 +
 120.115 +// ---------------------------------------------------------------------------
 120.116 +/** Data structure for a terrain vertex in a HMP5 file 
 120.117 +*/
 120.118 +struct Vertex_HMP5
 120.119 +{
 120.120 +	uint16_t z;	
 120.121 +	uint8_t normals162index;	
 120.122 +	uint8_t pad;				
 120.123 +} PACK_STRUCT;
 120.124 +
 120.125 +// ---------------------------------------------------------------------------
 120.126 +/** Data structure for a terrain vertex in a HMP7 file 
 120.127 +*/
 120.128 +struct Vertex_HMP7
 120.129 +{
 120.130 +	uint16_t	 z;				
 120.131 +	int8_t normal_x,normal_y;
 120.132 +} PACK_STRUCT;
 120.133 +
 120.134 +#include "assimp/Compiler/poppack1.h"
 120.135 +
 120.136 +} //! namespace HMP
 120.137 +} //! namespace Assimp
   121.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   121.2 +++ b/libs/assimp/HMPLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   121.3 @@ -0,0 +1,509 @@
   121.4 +/*
   121.5 +---------------------------------------------------------------------------
   121.6 +Open Asset Import Library (assimp)
   121.7 +---------------------------------------------------------------------------
   121.8 +
   121.9 +Copyright (c) 2006-2012, assimp team
  121.10 +
  121.11 +All rights reserved.
  121.12 +
  121.13 +Redistribution and use of this software in source and binary forms, 
  121.14 +with or without modification, are permitted provided that the following 
  121.15 +conditions are met:
  121.16 +
  121.17 +* Redistributions of source code must retain the above
  121.18 +  copyright notice, this list of conditions and the
  121.19 +  following disclaimer.
  121.20 +
  121.21 +* Redistributions in binary form must reproduce the above
  121.22 +  copyright notice, this list of conditions and the
  121.23 +  following disclaimer in the documentation and/or other
  121.24 +  materials provided with the distribution.
  121.25 +
  121.26 +* Neither the name of the assimp team, nor the names of its
  121.27 +  contributors may be used to endorse or promote products
  121.28 +  derived from this software without specific prior
  121.29 +  written permission of the assimp team.
  121.30 +
  121.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  121.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  121.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  121.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  121.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  121.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  121.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  121.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  121.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  121.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  121.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  121.42 +---------------------------------------------------------------------------
  121.43 +*/
  121.44 +
  121.45 +/** @file Implementation of the MDL importer class */
  121.46 +
  121.47 +#include "AssimpPCH.h"
  121.48 +#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
  121.49 +
  121.50 +// internal headers
  121.51 +#include "HMPLoader.h"
  121.52 +#include "MD2FileData.h"
  121.53 +
  121.54 +using namespace Assimp;
  121.55 +
  121.56 +static const aiImporterDesc desc = {
  121.57 +	"3D GameStudio Heightmap (HMP) Importer",
  121.58 +	"",
  121.59 +	"",
  121.60 +	"",
  121.61 +	aiImporterFlags_SupportBinaryFlavour,
  121.62 +	0,
  121.63 +	0,
  121.64 +	0,
  121.65 +	0,
  121.66 +	"hmp" 
  121.67 +};
  121.68 +
  121.69 +// ------------------------------------------------------------------------------------------------
  121.70 +// Constructor to be privately used by Importer
  121.71 +HMPImporter::HMPImporter()
  121.72 +{
  121.73 +	// nothing to do here
  121.74 +}
  121.75 +
  121.76 +// ------------------------------------------------------------------------------------------------
  121.77 +// Destructor, private as well 
  121.78 +HMPImporter::~HMPImporter()
  121.79 +{
  121.80 +	// nothing to do here
  121.81 +}
  121.82 +
  121.83 +// ------------------------------------------------------------------------------------------------
  121.84 +// Returns whether the class can handle the format of the given file. 
  121.85 +bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
  121.86 +{
  121.87 +	const std::string extension = GetExtension(pFile);
  121.88 +	if (extension == "hmp" )
  121.89 +		return true;
  121.90 +
  121.91 +	// if check for extension is not enough, check for the magic tokens 
  121.92 +	if (!extension.length() || cs) {
  121.93 +		uint32_t tokens[3]; 
  121.94 +		tokens[0] = AI_HMP_MAGIC_NUMBER_LE_4;
  121.95 +		tokens[1] = AI_HMP_MAGIC_NUMBER_LE_5;
  121.96 +		tokens[2] = AI_HMP_MAGIC_NUMBER_LE_7;
  121.97 +		return CheckMagicToken(pIOHandler,pFile,tokens,3,0);
  121.98 +	}
  121.99 +	return false;
 121.100 +}
 121.101 +
 121.102 +// ------------------------------------------------------------------------------------------------
 121.103 +// Get list of all file extensions that are handled by this loader
 121.104 +const aiImporterDesc* HMPImporter::GetInfo () const
 121.105 +{
 121.106 +	return &desc;
 121.107 +}
 121.108 +
 121.109 +// ------------------------------------------------------------------------------------------------
 121.110 +// Imports the given file into the given scene structure. 
 121.111 +void HMPImporter::InternReadFile( const std::string& pFile, 
 121.112 +								 aiScene* _pScene, IOSystem* _pIOHandler)
 121.113 +{
 121.114 +	pScene     = _pScene;
 121.115 +	pIOHandler = _pIOHandler;
 121.116 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
 121.117 +
 121.118 +	// Check whether we can read from the file
 121.119 +	if( file.get() == NULL)
 121.120 +		throw DeadlyImportError( "Failed to open HMP file " + pFile + ".");
 121.121 +
 121.122 +	// Check whether the HMP file is large enough to contain
 121.123 +	// at least the file header
 121.124 +	const size_t fileSize = file->FileSize();
 121.125 +	if( fileSize < 50)
 121.126 +		throw DeadlyImportError( "HMP File is too small.");
 121.127 +
 121.128 +	// Allocate storage and copy the contents of the file to a memory buffer
 121.129 +	std::vector<uint8_t> buffer(fileSize);
 121.130 +	mBuffer = &buffer[0];
 121.131 +	file->Read( (void*)mBuffer, 1, fileSize);
 121.132 +	iFileSize = (unsigned int)fileSize;
 121.133 +
 121.134 +	// Determine the file subtype and call the appropriate member function
 121.135 +	const uint32_t iMagic = *((uint32_t*)this->mBuffer);
 121.136 +
 121.137 +	// HMP4 format
 121.138 +	if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic ||
 121.139 +		AI_HMP_MAGIC_NUMBER_BE_4 == iMagic)
 121.140 +	{
 121.141 +		DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A4, magic word is HMP4");
 121.142 +		InternReadFile_HMP4();
 121.143 +	}
 121.144 +	// HMP5 format
 121.145 +	else if (AI_HMP_MAGIC_NUMBER_LE_5 == iMagic ||
 121.146 +			 AI_HMP_MAGIC_NUMBER_BE_5 == iMagic)
 121.147 +	{
 121.148 +		DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A5, magic word is HMP5");
 121.149 +		InternReadFile_HMP5();
 121.150 +	}
 121.151 +	// HMP7 format
 121.152 +	else if (AI_HMP_MAGIC_NUMBER_LE_7 == iMagic ||
 121.153 +			 AI_HMP_MAGIC_NUMBER_BE_7 == iMagic)
 121.154 +	{
 121.155 +		DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A7, magic word is HMP7");
 121.156 +		InternReadFile_HMP7();
 121.157 +	}
 121.158 +	else
 121.159 +	{
 121.160 +		// Print the magic word to the logger
 121.161 +		char szBuffer[5];
 121.162 +		szBuffer[0] = ((char*)&iMagic)[0];
 121.163 +		szBuffer[1] = ((char*)&iMagic)[1];
 121.164 +		szBuffer[2] = ((char*)&iMagic)[2];
 121.165 +		szBuffer[3] = ((char*)&iMagic)[3];
 121.166 +		szBuffer[4] = '\0';
 121.167 +
 121.168 +		// We're definitely unable to load this file
 121.169 +		throw DeadlyImportError( "Unknown HMP subformat " + pFile +
 121.170 +			". Magic word (" + szBuffer + ") is not known");
 121.171 +	}
 121.172 +
 121.173 +	// Set the AI_SCENE_FLAGS_TERRAIN bit
 121.174 +	pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
 121.175 +
 121.176 +	// File buffer destructs automatically now
 121.177 +}
 121.178 +
 121.179 +// ------------------------------------------------------------------------------------------------ 
 121.180 +void HMPImporter::ValidateHeader_HMP457( )
 121.181 +{
 121.182 +	const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
 121.183 +
 121.184 +	if (120 > iFileSize)
 121.185 +	{
 121.186 +		throw DeadlyImportError("HMP file is too small (header size is "
 121.187 +			"120 bytes, this file is smaller)");
 121.188 +	}
 121.189 +
 121.190 +	if (!pcHeader->ftrisize_x || !pcHeader->ftrisize_y)
 121.191 +		throw DeadlyImportError("Size of triangles in either  x or y direction is zero");
 121.192 +	
 121.193 +	if(pcHeader->fnumverts_x < 1.0f || (pcHeader->numverts/pcHeader->fnumverts_x) < 1.0f)
 121.194 +		throw DeadlyImportError("Number of triangles in either x or y direction is zero");
 121.195 +	
 121.196 +	if(!pcHeader->numframes)
 121.197 +		throw DeadlyImportError("There are no frames. At least one should be there");
 121.198 +
 121.199 +}
 121.200 +
 121.201 +// ------------------------------------------------------------------------------------------------ 
 121.202 +void HMPImporter::InternReadFile_HMP4( )
 121.203 +{
 121.204 +	throw DeadlyImportError("HMP4 is currently not supported");
 121.205 +}
 121.206 +
 121.207 +// ------------------------------------------------------------------------------------------------ 
 121.208 +void HMPImporter::InternReadFile_HMP5( )
 121.209 +{
 121.210 +	// read the file header and skip everything to byte 84
 121.211 +	const HMP::Header_HMP5* pcHeader = (const HMP::Header_HMP5*)mBuffer;
 121.212 +	const unsigned char* szCurrent = (const unsigned char*)(mBuffer+84);
 121.213 +	ValidateHeader_HMP457();
 121.214 +
 121.215 +	// generate an output mesh
 121.216 +	pScene->mNumMeshes = 1;
 121.217 +	pScene->mMeshes = new aiMesh*[1];
 121.218 +	aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
 121.219 +
 121.220 +	pcMesh->mMaterialIndex = 0;
 121.221 +	pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
 121.222 +	pcMesh->mNormals = new aiVector3D[pcHeader->numverts];
 121.223 +
 121.224 +	const unsigned int height = (unsigned int)(pcHeader->numverts / pcHeader->fnumverts_x);
 121.225 +	const unsigned int width =  (unsigned int)pcHeader->fnumverts_x;
 121.226 +
 121.227 +	// generate/load a material for the terrain
 121.228 +	CreateMaterial(szCurrent,&szCurrent);
 121.229 +
 121.230 +	// goto offset 120, I don't know why ...
 121.231 +	// (fixme) is this the frame header? I assume yes since it starts with 2. 
 121.232 +	szCurrent += 36;
 121.233 +	SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width);
 121.234 +
 121.235 +	// now load all vertices from the file
 121.236 +	aiVector3D* pcVertOut = pcMesh->mVertices;
 121.237 +	aiVector3D* pcNorOut = pcMesh->mNormals;
 121.238 +	const HMP::Vertex_HMP5* src = (const HMP::Vertex_HMP5*) szCurrent;
 121.239 +	for (unsigned int y = 0; y < height;++y)
 121.240 +	{
 121.241 +		for (unsigned int x = 0; x < width;++x)
 121.242 +		{
 121.243 +			pcVertOut->x = x * pcHeader->ftrisize_x;
 121.244 +			pcVertOut->y = y * pcHeader->ftrisize_y;
 121.245 +			pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f; 
 121.246 +			MD2::LookupNormalIndex(src->normals162index, *pcNorOut );
 121.247 +			++pcVertOut;++pcNorOut;++src;
 121.248 +		}
 121.249 +	}
 121.250 +
 121.251 +	// generate texture coordinates if necessary
 121.252 +	if (pcHeader->numskins)
 121.253 +		GenerateTextureCoords(width,height);
 121.254 +
 121.255 +	// now build a list of faces
 121.256 +	CreateOutputFaceList(width,height);	
 121.257 +
 121.258 +	// there is no nodegraph in HMP files. Simply assign the one mesh
 121.259 +	// (no, not the one ring) to the root node
 121.260 +	pScene->mRootNode = new aiNode();
 121.261 +	pScene->mRootNode->mName.Set("terrain_root");
 121.262 +	pScene->mRootNode->mNumMeshes = 1;
 121.263 +	pScene->mRootNode->mMeshes = new unsigned int[1];
 121.264 +	pScene->mRootNode->mMeshes[0] = 0;
 121.265 +}
 121.266 +
 121.267 +// ------------------------------------------------------------------------------------------------ 
 121.268 +void HMPImporter::InternReadFile_HMP7( )
 121.269 +{
 121.270 +	// read the file header and skip everything to byte 84
 121.271 +	const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
 121.272 +	const unsigned char* szCurrent = (const unsigned char*)(mBuffer+84);
 121.273 +	ValidateHeader_HMP457();
 121.274 +
 121.275 +	// generate an output mesh
 121.276 +	pScene->mNumMeshes = 1;
 121.277 +	pScene->mMeshes = new aiMesh*[1];
 121.278 +	aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
 121.279 +
 121.280 +	pcMesh->mMaterialIndex = 0;
 121.281 +	pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
 121.282 +	pcMesh->mNormals = new aiVector3D[pcHeader->numverts];
 121.283 +
 121.284 +	const unsigned int height = (unsigned int)(pcHeader->numverts / pcHeader->fnumverts_x);
 121.285 +	const unsigned int width = (unsigned int)pcHeader->fnumverts_x;
 121.286 +
 121.287 +	// generate/load a material for the terrain
 121.288 +	CreateMaterial(szCurrent,&szCurrent);
 121.289 +
 121.290 +	// goto offset 120, I don't know why ...
 121.291 +	// (fixme) is this the frame header? I assume yes since it starts with 2. 
 121.292 +	szCurrent += 36;
 121.293 +
 121.294 +	SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width);
 121.295 +
 121.296 +	// now load all vertices from the file
 121.297 +	aiVector3D* pcVertOut = pcMesh->mVertices;
 121.298 +	aiVector3D* pcNorOut = pcMesh->mNormals;
 121.299 +	const HMP::Vertex_HMP7* src = (const HMP::Vertex_HMP7*) szCurrent;
 121.300 +	for (unsigned int y = 0; y < height;++y)
 121.301 +	{
 121.302 +		for (unsigned int x = 0; x < width;++x)
 121.303 +		{
 121.304 +			pcVertOut->x = x * pcHeader->ftrisize_x;
 121.305 +			pcVertOut->y = y * pcHeader->ftrisize_y;
 121.306 +
 121.307 +			// FIXME: What exctly is the correct scaling factor to use?
 121.308 +			// possibly pcHeader->scale_origin[2] in combination with a
 121.309 +			// signed interpretation of src->z?
 121.310 +			pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f; 
 121.311 +
 121.312 +			pcNorOut->x = ((float)src->normal_x / 0x80 ); // * pcHeader->scale_origin[0];
 121.313 +			pcNorOut->y = ((float)src->normal_y / 0x80 ); // * pcHeader->scale_origin[1];
 121.314 +			pcNorOut->z = 1.0f;
 121.315 +			pcNorOut->Normalize();
 121.316 +			
 121.317 +			++pcVertOut;++pcNorOut;++src;
 121.318 +		}
 121.319 +	}
 121.320 +
 121.321 +	// generate texture coordinates if necessary
 121.322 +	if (pcHeader->numskins)GenerateTextureCoords(width,height);
 121.323 +
 121.324 +	// now build a list of faces
 121.325 +	CreateOutputFaceList(width,height);	
 121.326 +
 121.327 +	// there is no nodegraph in HMP files. Simply assign the one mesh
 121.328 +	// (no, not the One Ring) to the root node
 121.329 +	pScene->mRootNode = new aiNode();
 121.330 +	pScene->mRootNode->mName.Set("terrain_root");
 121.331 +	pScene->mRootNode->mNumMeshes = 1;
 121.332 +	pScene->mRootNode->mMeshes = new unsigned int[1];
 121.333 +	pScene->mRootNode->mMeshes[0] = 0;
 121.334 +}
 121.335 +
 121.336 +// ------------------------------------------------------------------------------------------------ 
 121.337 +void HMPImporter::CreateMaterial(const unsigned char* szCurrent,
 121.338 +	const unsigned char** szCurrentOut)
 121.339 +{
 121.340 +	aiMesh* const pcMesh = pScene->mMeshes[0];
 121.341 +	const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
 121.342 +
 121.343 +	// we don't need to generate texture coordinates if
 121.344 +	// we have no textures in the file ...
 121.345 +	if (pcHeader->numskins)
 121.346 +	{
 121.347 +		pcMesh->mTextureCoords[0] = new aiVector3D[pcHeader->numverts];
 121.348 +		pcMesh->mNumUVComponents[0] = 2;
 121.349 +
 121.350 +		// now read the first skin and skip all others
 121.351 +		ReadFirstSkin(pcHeader->numskins,szCurrent,&szCurrent);
 121.352 +	}
 121.353 +	else
 121.354 +	{
 121.355 +		// generate a default material
 121.356 +		const int iMode = (int)aiShadingMode_Gouraud;
 121.357 +		aiMaterial* pcHelper = new aiMaterial();
 121.358 +		pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
 121.359 +
 121.360 +		aiColor3D clr;
 121.361 +		clr.b = clr.g = clr.r = 0.6f;
 121.362 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
 121.363 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
 121.364 +
 121.365 +		clr.b = clr.g = clr.r = 0.05f;
 121.366 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
 121.367 +
 121.368 +		aiString szName;
 121.369 +		szName.Set(AI_DEFAULT_MATERIAL_NAME);
 121.370 +		pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
 121.371 +
 121.372 +		// add the material to the scene
 121.373 +		pScene->mNumMaterials = 1;
 121.374 +		pScene->mMaterials = new aiMaterial*[1];
 121.375 +		pScene->mMaterials[0] = pcHelper;
 121.376 +	}
 121.377 +	*szCurrentOut = szCurrent;
 121.378 +}
 121.379 +
 121.380 +// ------------------------------------------------------------------------------------------------ 
 121.381 +void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
 121.382 +{
 121.383 +	aiMesh* const pcMesh = this->pScene->mMeshes[0];
 121.384 +
 121.385 +	// Allocate enough storage
 121.386 +	pcMesh->mNumFaces = (width-1) * (height-1);
 121.387 +	pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
 121.388 +
 121.389 +	pcMesh->mNumVertices   = pcMesh->mNumFaces*4;
 121.390 +	aiVector3D* pcVertices = new aiVector3D[pcMesh->mNumVertices];
 121.391 +	aiVector3D* pcNormals  = new aiVector3D[pcMesh->mNumVertices];
 121.392 +
 121.393 +	aiFace* pcFaceOut(pcMesh->mFaces);
 121.394 +	aiVector3D* pcVertOut = pcVertices;
 121.395 +	aiVector3D* pcNorOut = pcNormals;
 121.396 +
 121.397 +	aiVector3D* pcUVs = pcMesh->mTextureCoords[0] ? new aiVector3D[pcMesh->mNumVertices] : NULL;
 121.398 +	aiVector3D* pcUVOut(pcUVs);
 121.399 +
 121.400 +	// Build the terrain square
 121.401 +	unsigned int iCurrent = 0;
 121.402 +	for (unsigned int y = 0; y < height-1;++y)	{
 121.403 +		for (unsigned int x = 0; x < width-1;++x,++pcFaceOut)	{
 121.404 +			pcFaceOut->mNumIndices = 4;
 121.405 +			pcFaceOut->mIndices = new unsigned int[4];
 121.406 +
 121.407 +			*pcVertOut++ = pcMesh->mVertices[y*width+x];
 121.408 +			*pcVertOut++ = pcMesh->mVertices[(y+1)*width+x];
 121.409 +			*pcVertOut++ = pcMesh->mVertices[(y+1)*width+x+1];
 121.410 +			*pcVertOut++ = pcMesh->mVertices[y*width+x+1];
 121.411 +			
 121.412 +
 121.413 +			*pcNorOut++ = pcMesh->mNormals[y*width+x];
 121.414 +			*pcNorOut++ = pcMesh->mNormals[(y+1)*width+x];
 121.415 +			*pcNorOut++ = pcMesh->mNormals[(y+1)*width+x+1];
 121.416 +			*pcNorOut++ = pcMesh->mNormals[y*width+x+1];
 121.417 +
 121.418 +			if (pcMesh->mTextureCoords[0])
 121.419 +			{
 121.420 +				*pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x];
 121.421 +				*pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x];
 121.422 +				*pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x+1];
 121.423 +				*pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x+1];
 121.424 +			}
 121.425 +			
 121.426 +			for (unsigned int i = 0; i < 4;++i)
 121.427 +				pcFaceOut->mIndices[i] = iCurrent++;
 121.428 +		}
 121.429 +	}
 121.430 +	delete[] pcMesh->mVertices;
 121.431 +	pcMesh->mVertices = pcVertices;
 121.432 +
 121.433 +	delete[] pcMesh->mNormals;
 121.434 +	pcMesh->mNormals = pcNormals;
 121.435 +
 121.436 +	if (pcMesh->mTextureCoords[0])
 121.437 +	{
 121.438 +		delete[] pcMesh->mTextureCoords[0];
 121.439 +		pcMesh->mTextureCoords[0] = pcUVs;
 121.440 +	}
 121.441 +}
 121.442 +
 121.443 +// ------------------------------------------------------------------------------------------------ 
 121.444 +void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
 121.445 +	const unsigned char** szCursorOut)
 121.446 +{
 121.447 +	ai_assert(0 != iNumSkins && NULL != szCursor);
 121.448 +
 121.449 +	// read the type of the skin ...
 121.450 +	// sometimes we need to skip 12 bytes here, I don't know why ...
 121.451 +	uint32_t iType = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
 121.452 +	if (0 == iType)
 121.453 +	{
 121.454 +		szCursor += sizeof(uint32_t) * 2;
 121.455 +		iType = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
 121.456 +		if (!iType)
 121.457 +			throw DeadlyImportError("Unable to read HMP7 skin chunk");
 121.458 +		
 121.459 +	}
 121.460 +	// read width and height
 121.461 +	uint32_t iWidth  = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
 121.462 +	uint32_t iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
 121.463 +
 121.464 +	// allocate an output material
 121.465 +	aiMaterial* pcMat = new aiMaterial();
 121.466 +
 121.467 +	// read the skin, this works exactly as for MDL7
 121.468 +	ParseSkinLump_3DGS_MDL7(szCursor,&szCursor,
 121.469 +		pcMat,iType,iWidth,iHeight);
 121.470 +
 121.471 +	// now we need to skip any other skins ... 
 121.472 +	for (unsigned int i = 1; i< iNumSkins;++i)
 121.473 +	{
 121.474 +		iType   = *((uint32_t*)szCursor);   szCursor += sizeof(uint32_t);
 121.475 +		iWidth  = *((uint32_t*)szCursor);   szCursor += sizeof(uint32_t);
 121.476 +		iHeight = *((uint32_t*)szCursor);   szCursor += sizeof(uint32_t);
 121.477 +
 121.478 +		SkipSkinLump_3DGS_MDL7(szCursor,&szCursor,iType,iWidth,iHeight);
 121.479 +		SizeCheck(szCursor);
 121.480 +	}
 121.481 +
 121.482 +	// setup the material ...
 121.483 +	pScene->mNumMaterials = 1;
 121.484 +	pScene->mMaterials = new aiMaterial*[1];
 121.485 +	pScene->mMaterials[0] = pcMat;
 121.486 +
 121.487 +	*szCursorOut = szCursor;
 121.488 +}
 121.489 +
 121.490 +// ------------------------------------------------------------------------------------------------ 
 121.491 +// Generate proepr texture coords
 121.492 +void HMPImporter::GenerateTextureCoords(
 121.493 +	const unsigned int width, const unsigned int height)
 121.494 +{
 121.495 +	ai_assert(NULL != pScene->mMeshes && NULL != pScene->mMeshes[0] &&
 121.496 +		      NULL != pScene->mMeshes[0]->mTextureCoords[0]);
 121.497 +
 121.498 +	aiVector3D* uv = pScene->mMeshes[0]->mTextureCoords[0];
 121.499 +
 121.500 +	const float fY = (1.0f / height) + (1.0f / height) / (height-1);
 121.501 +	const float fX = (1.0f / width) + (1.0f / width) / (width-1);
 121.502 +
 121.503 +	for (unsigned int y = 0; y < height;++y)	{
 121.504 +		for (unsigned int x = 0; x < width;++x,++uv)	{
 121.505 +			uv->y = fY*y;
 121.506 +			uv->x = fX*x;
 121.507 +			uv->z = 0.0f;
 121.508 +		}
 121.509 +	}
 121.510 +}
 121.511 +
 121.512 +#endif // !! ASSIMP_BUILD_NO_HMP_IMPORTER
   122.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   122.2 +++ b/libs/assimp/HMPLoader.h	Sat Feb 01 19:58:19 2014 +0200
   122.3 @@ -0,0 +1,155 @@
   122.4 +/*
   122.5 +Open Asset Import Library (assimp)
   122.6 +----------------------------------------------------------------------
   122.7 +
   122.8 +Copyright (c) 2006-2012, assimp team
   122.9 +All rights reserved.
  122.10 +
  122.11 +Redistribution and use of this software in source and binary forms, 
  122.12 +with or without modification, are permitted provided that the 
  122.13 +following conditions are met:
  122.14 +
  122.15 +* Redistributions of source code must retain the above
  122.16 +  copyright notice, this list of conditions and the
  122.17 +  following disclaimer.
  122.18 +
  122.19 +* Redistributions in binary form must reproduce the above
  122.20 +  copyright notice, this list of conditions and the
  122.21 +  following disclaimer in the documentation and/or other
  122.22 +  materials provided with the distribution.
  122.23 +
  122.24 +* Neither the name of the assimp team, nor the names of its
  122.25 +  contributors may be used to endorse or promote products
  122.26 +  derived from this software without specific prior
  122.27 +  written permission of the assimp team.
  122.28 +
  122.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  122.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  122.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  122.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  122.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  122.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  122.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  122.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  122.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  122.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  122.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  122.40 +
  122.41 +----------------------------------------------------------------------
  122.42 +*/
  122.43 +/** @file  HMPLoader.h
  122.44 + *  @brief Declaration of the HMP importer class
  122.45 + */
  122.46 +
  122.47 +#ifndef AI_HMPLOADER_H_INCLUDED
  122.48 +#define AI_HMPLOADER_H_INCLUDED
  122.49 +
  122.50 +// public ASSIMP headers
  122.51 +#include "assimp/types.h"
  122.52 +#include "assimp/texture.h"
  122.53 +#include "assimp/material.h"
  122.54 +
  122.55 +// internal headers
  122.56 +#include "BaseImporter.h"
  122.57 +#include "MDLLoader.h"
  122.58 +#include "HMPFileData.h"
  122.59 +
  122.60 +namespace Assimp {
  122.61 +using namespace HMP;
  122.62 +
  122.63 +// ---------------------------------------------------------------------------
  122.64 +/** Used to load 3D GameStudio HMP files (terrains)
  122.65 +*/
  122.66 +class HMPImporter : public MDLImporter
  122.67 +{
  122.68 +public:
  122.69 +	HMPImporter();
  122.70 +	~HMPImporter();
  122.71 +
  122.72 +
  122.73 +public:
  122.74 +
  122.75 +	// -------------------------------------------------------------------
  122.76 +	/** Returns whether the class can handle the format of the given file. 
  122.77 +	 * See BaseImporter::CanRead() for details.
  122.78 +	 */
  122.79 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, 
  122.80 +		bool checkSig) const;
  122.81 +
  122.82 +protected:
  122.83 +
  122.84 +
  122.85 +	// -------------------------------------------------------------------
  122.86 +	/** Return importer meta information.
  122.87 +	 * See #BaseImporter::GetInfo for the details
  122.88 +	 */
  122.89 +	const aiImporterDesc* GetInfo () const;
  122.90 +
  122.91 +	// -------------------------------------------------------------------
  122.92 +	/** Imports the given file into the given scene structure. 
  122.93 +	* See BaseImporter::InternReadFile() for details
  122.94 +	*/
  122.95 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  122.96 +		IOSystem* pIOHandler);
  122.97 +
  122.98 +protected:
  122.99 +
 122.100 +	// -------------------------------------------------------------------
 122.101 +	/** Import a HMP4 file
 122.102 +	*/
 122.103 +	void InternReadFile_HMP4( );
 122.104 +
 122.105 +	// -------------------------------------------------------------------
 122.106 +	/** Import a HMP5 file
 122.107 +	*/
 122.108 +	void InternReadFile_HMP5( );
 122.109 +
 122.110 +	// -------------------------------------------------------------------
 122.111 +	/** Import a HMP7 file
 122.112 +	*/
 122.113 +	void InternReadFile_HMP7( );
 122.114 +
 122.115 +	// -------------------------------------------------------------------
 122.116 +	/** Validate a HMP 5,4,7 file header
 122.117 +	*/
 122.118 +	void ValidateHeader_HMP457( );
 122.119 +
 122.120 +	// -------------------------------------------------------------------
 122.121 +	/** Try to load one material from the file, if this fails create
 122.122 +	 * a default material
 122.123 +	*/
 122.124 +	void CreateMaterial(const unsigned char* szCurrent,
 122.125 +		const unsigned char** szCurrentOut);
 122.126 +
 122.127 +	// -------------------------------------------------------------------
 122.128 +	/** Build a list of output faces and vertices. The function 
 122.129 +	 *  triangulates the height map read from the file
 122.130 +	 * \param width Width of the height field
 122.131 +	 * \param width Height of the height field
 122.132 +	*/
 122.133 +	void CreateOutputFaceList(unsigned int width,unsigned int height);
 122.134 +
 122.135 +	// -------------------------------------------------------------------
 122.136 +	/** Generate planar texture coordinates for a terrain
 122.137 +	 * \param width Width of the terrain, in vertices
 122.138 +	 * \param height Height of the terrain, in vertices
 122.139 +	*/
 122.140 +	void GenerateTextureCoords(const unsigned int width, 
 122.141 +		const unsigned int height);
 122.142 +
 122.143 +	// -------------------------------------------------------------------
 122.144 +	/** Read the first skin from the file and skip all others ...
 122.145 +	 *  \param iNumSkins Number of skins in the file
 122.146 +	 *  \param szCursor Position of the first skin (offset 84)
 122.147 +	*/
 122.148 +	void ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
 122.149 +		const unsigned char** szCursorOut);
 122.150 +
 122.151 +private:
 122.152 +
 122.153 +};
 122.154 +
 122.155 +} // end of namespace Assimp
 122.156 +
 122.157 +#endif // AI_HMPIMPORTER_H_INC
 122.158 +
   123.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   123.2 +++ b/libs/assimp/HalfLifeFileData.h	Sat Feb 01 19:58:19 2014 +0200
   123.3 @@ -0,0 +1,150 @@
   123.4 +/*
   123.5 +Open Asset Import Library (assimp)
   123.6 +----------------------------------------------------------------------
   123.7 +
   123.8 +Copyright (c) 2006-2012, assimp team
   123.9 +All rights reserved.
  123.10 +
  123.11 +Redistribution and use of this software in source and binary forms, 
  123.12 +with or without modification, are permitted provided that the 
  123.13 +following conditions are met:
  123.14 +
  123.15 +* Redistributions of source code must retain the above
  123.16 +  copyright notice, this list of conditions and the
  123.17 +  following disclaimer.
  123.18 +
  123.19 +* Redistributions in binary form must reproduce the above
  123.20 +  copyright notice, this list of conditions and the
  123.21 +  following disclaimer in the documentation and/or other
  123.22 +  materials provided with the distribution.
  123.23 +
  123.24 +* Neither the name of the assimp team, nor the names of its
  123.25 +  contributors may be used to endorse or promote products
  123.26 +  derived from this software without specific prior
  123.27 +  written permission of the assimp team.
  123.28 +
  123.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  123.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  123.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  123.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  123.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  123.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  123.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  123.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  123.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  123.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  123.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  123.40 +
  123.41 +----------------------------------------------------------------------
  123.42 +*/
  123.43 +
  123.44 +
  123.45 +//
  123.46 +//! @file Definition of in-memory structures for the HL2 MDL file format
  123.47 +//  and for the HalfLife text format (SMD)
  123.48 +//
  123.49 +// The specification has been taken from various sources on the internet.
  123.50 +
  123.51 +
  123.52 +#ifndef AI_MDLFILEHELPER2_H_INC
  123.53 +#define AI_MDLFILEHELPER2_H_INC
  123.54 +
  123.55 +#include "assimp/Compiler/pushpack1.h"
  123.56 +
  123.57 +#include "MDLFileData.h"
  123.58 +
  123.59 +namespace Assimp	{
  123.60 +namespace MDL	{
  123.61 +
  123.62 +// magic bytes used in Half Life 2 MDL models
  123.63 +#define AI_MDL_MAGIC_NUMBER_BE_HL2a	AI_MAKE_MAGIC("IDST")
  123.64 +#define AI_MDL_MAGIC_NUMBER_LE_HL2a	AI_MAKE_MAGIC("TSDI")
  123.65 +#define AI_MDL_MAGIC_NUMBER_BE_HL2b	AI_MAKE_MAGIC("IDSQ")
  123.66 +#define AI_MDL_MAGIC_NUMBER_LE_HL2b	AI_MAKE_MAGIC("QSDI")
  123.67 +
  123.68 +// ---------------------------------------------------------------------------
  123.69 +/** \struct Header_HL2
  123.70 + *  \brief Data structure for the HL2 main header
  123.71 + */
  123.72 +// ---------------------------------------------------------------------------
  123.73 +struct Header_HL2 
  123.74 +{
  123.75 +	//! magic number: "IDST"/"IDSQ"
  123.76 +	char	ident[4];		
  123.77 +
  123.78 +	//! Version number
  123.79 +	int32_t	version;
  123.80 +
  123.81 +	//! Original file name in pak ?
  123.82 +	char		name[64];
  123.83 +
  123.84 +	//! Length of file name/length of file?
  123.85 +	int32_t		length;
  123.86 +
  123.87 +	//! For viewer, ignored
  123.88 +	aiVector3D		eyeposition;	
  123.89 +	aiVector3D		min;			
  123.90 +	aiVector3D		max;			
  123.91 +
  123.92 +	//! AABB of the model
  123.93 +	aiVector3D		bbmin;			
  123.94 +	aiVector3D		bbmax;		
  123.95 +
  123.96 +	// File flags
  123.97 +	int32_t			flags;
  123.98 +
  123.99 +	//! NUmber of bones contained in the file
 123.100 +	int32_t			numbones;			
 123.101 +	int32_t			boneindex;
 123.102 +
 123.103 +	//! Number of bone controllers for bone animation
 123.104 +	int32_t			numbonecontrollers;		
 123.105 +	int32_t			bonecontrollerindex;
 123.106 +
 123.107 +	//! More bounding boxes ...
 123.108 +	int32_t			numhitboxes;			
 123.109 +	int32_t			hitboxindex;			
 123.110 +	
 123.111 +	//! Animation sequences in the file
 123.112 +	int32_t			numseq;				
 123.113 +	int32_t			seqindex;
 123.114 +
 123.115 +	//! Loaded sequences. Ignored
 123.116 +	int32_t			numseqgroups;		
 123.117 +	int32_t			seqgroupindex;
 123.118 +
 123.119 +	//! Raw texture data
 123.120 +	int32_t			numtextures;		
 123.121 +	int32_t			textureindex;
 123.122 +	int32_t			texturedataindex;
 123.123 +
 123.124 +	//! Number of skins (=textures?)
 123.125 +	int32_t			numskinref;			
 123.126 +	int32_t			numskinfamilies;
 123.127 +	int32_t			skinindex;
 123.128 +
 123.129 +	//! Number of parts
 123.130 +	int32_t			numbodyparts;		
 123.131 +	int32_t			bodypartindex;
 123.132 +
 123.133 +	//! attachable points for gameplay and physics
 123.134 +	int32_t			numattachments;		
 123.135 +	int32_t			attachmentindex;
 123.136 +
 123.137 +	//! Table of sound effects associated with the model
 123.138 +	int32_t			soundtable;
 123.139 +	int32_t			soundindex;
 123.140 +	int32_t			soundgroups;
 123.141 +	int32_t			soundgroupindex;
 123.142 +
 123.143 +	//! Number of animation transitions
 123.144 +	int32_t			numtransitions;		
 123.145 +	int32_t			transitionindex;
 123.146 +} PACK_STRUCT;
 123.147 +
 123.148 +#include "assimp/Compiler/poppack1.h"
 123.149 +
 123.150 +}
 123.151 +} // end namespaces
 123.152 +
 123.153 +#endif // ! AI_MDLFILEHELPER2_H_INC
   124.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   124.2 +++ b/libs/assimp/Hash.h	Sat Feb 01 19:58:19 2014 +0200
   124.3 @@ -0,0 +1,113 @@
   124.4 +/*
   124.5 +Open Asset Import Library (assimp)
   124.6 +----------------------------------------------------------------------
   124.7 +
   124.8 +Copyright (c) 2006-2012, assimp team
   124.9 +All rights reserved.
  124.10 +
  124.11 +Redistribution and use of this software in source and binary forms, 
  124.12 +with or without modification, are permitted provided that the 
  124.13 +following conditions are met:
  124.14 +
  124.15 +* Redistributions of source code must retain the above
  124.16 +  copyright notice, this list of conditions and the
  124.17 +  following disclaimer.
  124.18 +
  124.19 +* Redistributions in binary form must reproduce the above
  124.20 +  copyright notice, this list of conditions and the
  124.21 +  following disclaimer in the documentation and/or other
  124.22 +  materials provided with the distribution.
  124.23 +
  124.24 +* Neither the name of the assimp team, nor the names of its
  124.25 +  contributors may be used to endorse or promote products
  124.26 +  derived from this software without specific prior
  124.27 +  written permission of the assimp team.
  124.28 +
  124.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  124.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  124.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  124.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  124.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  124.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  124.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  124.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  124.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  124.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  124.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  124.40 +
  124.41 +----------------------------------------------------------------------
  124.42 +*/
  124.43 +
  124.44 +#ifndef AI_HASH_H_INCLUDED
  124.45 +#define AI_HASH_H_INCLUDED
  124.46 +
  124.47 +// ------------------------------------------------------------------------------------------------
  124.48 +// Hashing function taken from 
  124.49 +// http://www.azillionmonkeys.com/qed/hash.html
  124.50 +// (incremental version)
  124.51 +//
  124.52 +// This code is Copyright 2004-2008 by Paul Hsieh. It is used here in the belief that
  124.53 +// Assimp's license is considered compatible with Pauls's derivative license as specified
  124.54 +// on his web page.
  124.55 +//
  124.56 +// (stdint.h should have been been included here)
  124.57 +// ------------------------------------------------------------------------------------------------
  124.58 +#undef get16bits
  124.59 +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
  124.60 +  || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
  124.61 +#define get16bits(d) (*((const uint16_t *) (d)))
  124.62 +#endif
  124.63 +
  124.64 +#if !defined (get16bits)
  124.65 +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
  124.66 +                       +(uint32_t)(((const uint8_t *)(d))[0]) )
  124.67 +#endif
  124.68 +
  124.69 +// ------------------------------------------------------------------------------------------------
  124.70 +inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) {
  124.71 +uint32_t tmp;
  124.72 +int rem;
  124.73 +
  124.74 +    if (!data) return 0;
  124.75 +	if (!len)len = (uint32_t)::strlen(data);
  124.76 +
  124.77 +    rem = len & 3;
  124.78 +    len >>= 2;
  124.79 +
  124.80 +    /* Main loop */
  124.81 +    for (;len > 0; len--) {
  124.82 +        hash  += get16bits (data);
  124.83 +        tmp    = (get16bits (data+2) << 11) ^ hash;
  124.84 +        hash   = (hash << 16) ^ tmp;
  124.85 +        data  += 2*sizeof (uint16_t);
  124.86 +        hash  += hash >> 11;
  124.87 +    }
  124.88 +
  124.89 +    /* Handle end cases */
  124.90 +    switch (rem) {
  124.91 +        case 3: hash += get16bits (data);
  124.92 +                hash ^= hash << 16;
  124.93 +                hash ^= data[sizeof (uint16_t)] << 18;
  124.94 +                hash += hash >> 11;
  124.95 +                break;
  124.96 +        case 2: hash += get16bits (data);
  124.97 +                hash ^= hash << 11;
  124.98 +                hash += hash >> 17;
  124.99 +                break;
 124.100 +        case 1: hash += *data;
 124.101 +                hash ^= hash << 10;
 124.102 +                hash += hash >> 1;
 124.103 +    }
 124.104 +
 124.105 +    /* Force "avalanching" of final 127 bits */
 124.106 +    hash ^= hash << 3;
 124.107 +    hash += hash >> 5;
 124.108 +    hash ^= hash << 4;
 124.109 +    hash += hash >> 17;
 124.110 +    hash ^= hash << 25;
 124.111 +    hash += hash >> 6;
 124.112 +
 124.113 +    return hash;
 124.114 +}
 124.115 +
 124.116 +#endif // !! AI_HASH_H_INCLUDED
   125.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   125.2 +++ b/libs/assimp/IFCBoolean.cpp	Sat Feb 01 19:58:19 2014 +0200
   125.3 @@ -0,0 +1,729 @@
   125.4 +/*
   125.5 +Open Asset Import Library (assimp)
   125.6 +----------------------------------------------------------------------
   125.7 +
   125.8 +Copyright (c) 2006-2010, assimp team
   125.9 +All rights reserved.
  125.10 +
  125.11 +Redistribution and use of this software in source and binary forms, 
  125.12 +with or without modification, are permitted provided that the 
  125.13 +following conditions are met:
  125.14 +
  125.15 +* Redistributions of source code must retain the above
  125.16 +  copyright notice, this list of conditions and the
  125.17 +  following disclaimer.
  125.18 +
  125.19 +* Redistributions in binary form must reproduce the above
  125.20 +  copyright notice, this list of conditions and the
  125.21 +  following disclaimer in the documentation and/or other
  125.22 +  materials provided with the distribution.
  125.23 +
  125.24 +* Neither the name of the assimp team, nor the names of its
  125.25 +  contributors may be used to endorse or promote products
  125.26 +  derived from this software without specific prior
  125.27 +  written permission of the assimp team.
  125.28 +
  125.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  125.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  125.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  125.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  125.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  125.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  125.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  125.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  125.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  125.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  125.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  125.40 +
  125.41 +----------------------------------------------------------------------
  125.42 +*/
  125.43 +
  125.44 +/** @file  IFCBoolean.cpp
  125.45 + *  @brief Implements a subset of Ifc boolean operations
  125.46 + */
  125.47 +
  125.48 +#include "AssimpPCH.h"
  125.49 +
  125.50 +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
  125.51 +#include "IFCUtil.h"
  125.52 +#include "PolyTools.h"
  125.53 +#include "ProcessHelper.h"
  125.54 +
  125.55 +#include <iterator>
  125.56 +
  125.57 +namespace Assimp {
  125.58 +	namespace IFC {
  125.59 +		
  125.60 +// ------------------------------------------------------------------------------------------------
  125.61 +enum Intersect {
  125.62 +	Intersect_No,
  125.63 +	Intersect_LiesOnPlane,
  125.64 +	Intersect_Yes
  125.65 +};
  125.66 +
  125.67 +// ------------------------------------------------------------------------------------------------
  125.68 +Intersect IntersectSegmentPlane(const IfcVector3& p,const IfcVector3& n, const IfcVector3& e0, 
  125.69 +								const IfcVector3& e1, 
  125.70 +								IfcVector3& out) 
  125.71 +{
  125.72 +	const IfcVector3 pdelta = e0 - p, seg = e1-e0;
  125.73 +	const IfcFloat dotOne = n*seg, dotTwo = -(n*pdelta);
  125.74 +
  125.75 +	if (fabs(dotOne) < 1e-6) {
  125.76 +		return fabs(dotTwo) < 1e-6f ? Intersect_LiesOnPlane : Intersect_No;
  125.77 +	}
  125.78 +
  125.79 +	const IfcFloat t = dotTwo/dotOne;
  125.80 +	// t must be in [0..1] if the intersection point is within the given segment
  125.81 +	if (t > 1.f || t < 0.f) {
  125.82 +		return Intersect_No;
  125.83 +	}
  125.84 +	out = e0+t*seg;
  125.85 +	return Intersect_Yes;
  125.86 +}
  125.87 +
  125.88 +// ------------------------------------------------------------------------------------------------
  125.89 +void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result, 
  125.90 +									   const TempMesh& first_operand, 
  125.91 +									   ConversionData& conv)
  125.92 +{
  125.93 +	ai_assert(hs != NULL);
  125.94 +
  125.95 +	const IfcPlane* const plane = hs->BaseSurface->ToPtr<IfcPlane>();
  125.96 +	if(!plane) {
  125.97 +		IFCImporter::LogError("expected IfcPlane as base surface for the IfcHalfSpaceSolid");
  125.98 +		return;
  125.99 +	}
 125.100 +
 125.101 +	// extract plane base position vector and normal vector
 125.102 +	IfcVector3 p,n(0.f,0.f,1.f);
 125.103 +	if (plane->Position->Axis) {
 125.104 +		ConvertDirection(n,plane->Position->Axis.Get());
 125.105 +	}
 125.106 +	ConvertCartesianPoint(p,plane->Position->Location);
 125.107 +
 125.108 +	if(!IsTrue(hs->AgreementFlag)) {
 125.109 +		n *= -1.f;
 125.110 +	}
 125.111 +
 125.112 +	// clip the current contents of `meshout` against the plane we obtained from the second operand
 125.113 +	const std::vector<IfcVector3>& in = first_operand.verts;
 125.114 +	std::vector<IfcVector3>& outvert = result.verts;
 125.115 +
 125.116 +	std::vector<unsigned int>::const_iterator begin = first_operand.vertcnt.begin(), 
 125.117 +		end = first_operand.vertcnt.end(), iit;
 125.118 +
 125.119 +	outvert.reserve(in.size());
 125.120 +	result.vertcnt.reserve(first_operand.vertcnt.size());
 125.121 +
 125.122 +	unsigned int vidx = 0;
 125.123 +	for(iit = begin; iit != end; vidx += *iit++) {
 125.124 +
 125.125 +		unsigned int newcount = 0;
 125.126 +		for(unsigned int i = 0; i < *iit; ++i) {
 125.127 +			const IfcVector3& e0 = in[vidx+i], e1 = in[vidx+(i+1)%*iit];
 125.128 +
 125.129 +			// does the next segment intersect the plane?
 125.130 +			IfcVector3 isectpos;
 125.131 +			const Intersect isect = IntersectSegmentPlane(p,n,e0,e1,isectpos);
 125.132 +			if (isect == Intersect_No || isect == Intersect_LiesOnPlane) {
 125.133 +				if ( (e0-p).Normalize()*n > 0 ) {
 125.134 +					outvert.push_back(e0);
 125.135 +					++newcount;
 125.136 +				}
 125.137 +			}
 125.138 +			else if (isect == Intersect_Yes) {
 125.139 +				if ( (e0-p).Normalize()*n > 0 ) {
 125.140 +					// e0 is on the right side, so keep it 
 125.141 +					outvert.push_back(e0);
 125.142 +					outvert.push_back(isectpos);
 125.143 +					newcount += 2;
 125.144 +				}
 125.145 +				else {
 125.146 +					// e0 is on the wrong side, so drop it and keep e1 instead
 125.147 +					outvert.push_back(isectpos);
 125.148 +					++newcount;
 125.149 +				}
 125.150 +			}
 125.151 +		}	
 125.152 +
 125.153 +		if (!newcount) {
 125.154 +			continue;
 125.155 +		}
 125.156 +
 125.157 +		IfcVector3 vmin,vmax;
 125.158 +		ArrayBounds(&*(outvert.end()-newcount),newcount,vmin,vmax);
 125.159 +
 125.160 +		// filter our IfcFloat points - those may happen if a point lies
 125.161 +		// directly on the intersection line. However, due to IfcFloat
 125.162 +		// precision a bitwise comparison is not feasible to detect
 125.163 +		// this case.
 125.164 +		const IfcFloat epsilon = (vmax-vmin).SquareLength() / 1e6f;
 125.165 +		FuzzyVectorCompare fz(epsilon);
 125.166 +
 125.167 +		std::vector<IfcVector3>::iterator e = std::unique( outvert.end()-newcount, outvert.end(), fz );
 125.168 +
 125.169 +		if (e != outvert.end()) {
 125.170 +			newcount -= static_cast<unsigned int>(std::distance(e,outvert.end()));
 125.171 +			outvert.erase(e,outvert.end());
 125.172 +		}
 125.173 +		if (fz(*( outvert.end()-newcount),outvert.back())) {
 125.174 +			outvert.pop_back();
 125.175 +			--newcount;
 125.176 +		}
 125.177 +		if(newcount > 2) {
 125.178 +			result.vertcnt.push_back(newcount);
 125.179 +		}
 125.180 +		else while(newcount-->0) {
 125.181 +			result.verts.pop_back();
 125.182 +		}
 125.183 +
 125.184 +	}
 125.185 +	IFCImporter::LogDebug("generating CSG geometry by plane clipping (IfcBooleanClippingResult)");
 125.186 +}
 125.187 +
 125.188 +// ------------------------------------------------------------------------------------------------
 125.189 +// Check if e0-e1 intersects a sub-segment of the given boundary line.
 125.190 +// note: this functions works on 3D vectors, but performs its intersection checks solely in xy.
 125.191 +bool IntersectsBoundaryProfile( const IfcVector3& e0, const IfcVector3& e1, const std::vector<IfcVector3>& boundary,
 125.192 +	std::vector<size_t>& intersected_boundary_segments,
 125.193 +	std::vector<IfcVector3>& intersected_boundary_points,
 125.194 +	bool half_open = false,
 125.195 +	bool* e0_hits_border = NULL)
 125.196 +{
 125.197 +	ai_assert(intersected_boundary_segments.empty());
 125.198 +	ai_assert(intersected_boundary_points.empty());
 125.199 +
 125.200 +	if(e0_hits_border) {
 125.201 +		*e0_hits_border = false;
 125.202 +	}
 125.203 +
 125.204 +	const IfcVector3& e = e1 - e0;
 125.205 +
 125.206 +	for (size_t i = 0, bcount = boundary.size(); i < bcount; ++i) {
 125.207 +		// boundary segment i: b0-b1
 125.208 +		const IfcVector3& b0 = boundary[i];
 125.209 +		const IfcVector3& b1 = boundary[(i+1) % bcount];
 125.210 +
 125.211 +		const IfcVector3& b = b1 - b0;
 125.212 +
 125.213 +		// segment-segment intersection
 125.214 +		// solve b0 + b*s = e0 + e*t for (s,t)
 125.215 +		const IfcFloat det = (-b.x * e.y + e.x * b.y);
 125.216 +		if(fabs(det) < 1e-6) {
 125.217 +			// no solutions (parallel lines)
 125.218 +			continue;
 125.219 +		}
 125.220 +
 125.221 +		const IfcFloat x = b0.x - e0.x;
 125.222 +		const IfcFloat y = b0.y - e0.y;
 125.223 +
 125.224 +		const IfcFloat s = (x*e.y - e.x*y)/det;
 125.225 +		const IfcFloat t = (x*b.y - b.x*y)/det;
 125.226 +
 125.227 +#ifdef _DEBUG
 125.228 +		const IfcVector3 check = b0 + b*s  - (e0 + e*t);
 125.229 +		ai_assert((IfcVector2(check.x,check.y)).SquareLength() < 1e-5);
 125.230 +#endif
 125.231 +
 125.232 +		// for a valid intersection, s-t should be in range [0,1].
 125.233 +		// note that for t (i.e. the segment point) we only use a
 125.234 +		// half-sided epsilon because the next segment should catch
 125.235 +		// this case.
 125.236 +		const IfcFloat epsilon = 1e-6;
 125.237 +		if (t >= -epsilon && (t <= 1.0+epsilon || half_open) && s >= -epsilon && s <= 1.0) {
 125.238 +
 125.239 +			if (e0_hits_border && !*e0_hits_border) {
 125.240 +				*e0_hits_border = fabs(t) < 1e-5f;
 125.241 +			}
 125.242 +	
 125.243 +			const IfcVector3& p = e0 + e*t;
 125.244 +
 125.245 +			// only insert the point into the list if it is sufficiently
 125.246 +			// far away from the previous intersection point. This way,
 125.247 +			// we avoid duplicate detection if the intersection is
 125.248 +			// directly on the vertex between two segments.
 125.249 +			if (!intersected_boundary_points.empty() && intersected_boundary_segments.back()==i-1 ) {
 125.250 +				const IfcVector3 diff = intersected_boundary_points.back() - p;
 125.251 +				if(IfcVector2(diff.x, diff.y).SquareLength() < 1e-7) {
 125.252 +					continue;
 125.253 +				}
 125.254 +			}
 125.255 +			intersected_boundary_segments.push_back(i);
 125.256 +			intersected_boundary_points.push_back(p);
 125.257 +		}
 125.258 +	}
 125.259 +
 125.260 +	return !intersected_boundary_segments.empty();
 125.261 +}
 125.262 +
 125.263 +
 125.264 +// ------------------------------------------------------------------------------------------------
 125.265 +// note: this functions works on 3D vectors, but performs its intersection checks solely in xy.
 125.266 +bool PointInPoly(const IfcVector3& p, const std::vector<IfcVector3>& boundary)
 125.267 +{
 125.268 +	// even-odd algorithm: take a random vector that extends from p to infinite
 125.269 +	// and counts how many times it intersects edges of the boundary.
 125.270 +	// because checking for segment intersections is prone to numeric inaccuracies
 125.271 +	// or double detections (i.e. when hitting multiple adjacent segments at their
 125.272 +	// shared vertices) we do it thrice with different rays and vote on it.
 125.273 +
 125.274 +	// the even-odd algorithm doesn't work for points which lie directly on
 125.275 +	// the border of the polygon. If any of our attempts produces this result,
 125.276 +	// we return false immediately.
 125.277 +
 125.278 +	std::vector<size_t> intersected_boundary_segments;
 125.279 +	std::vector<IfcVector3> intersected_boundary_points;
 125.280 +	size_t votes = 0;
 125.281 +
 125.282 +	bool is_border;
 125.283 +	IntersectsBoundaryProfile(p, p + IfcVector3(1.0,0,0), boundary, 
 125.284 +		intersected_boundary_segments, 
 125.285 +		intersected_boundary_points, true, &is_border);
 125.286 +
 125.287 +	if(is_border) {
 125.288 +		return false;
 125.289 +	}
 125.290 +
 125.291 +	votes += intersected_boundary_segments.size() % 2;
 125.292 +
 125.293 +	intersected_boundary_segments.clear();
 125.294 +	intersected_boundary_points.clear();
 125.295 +
 125.296 +	IntersectsBoundaryProfile(p, p + IfcVector3(0,1.0,0), boundary, 
 125.297 +		intersected_boundary_segments, 
 125.298 +		intersected_boundary_points, true, &is_border);
 125.299 +
 125.300 +	if(is_border) {
 125.301 +		return false;
 125.302 +	}
 125.303 +
 125.304 +	votes += intersected_boundary_segments.size() % 2;
 125.305 +
 125.306 +	intersected_boundary_segments.clear();
 125.307 +	intersected_boundary_points.clear();
 125.308 +
 125.309 +	IntersectsBoundaryProfile(p, p + IfcVector3(0.6,-0.6,0.0), boundary, 
 125.310 +		intersected_boundary_segments, 
 125.311 +		intersected_boundary_points, true, &is_border);
 125.312 +
 125.313 +	if(is_border) {
 125.314 +		return false;
 125.315 +	}
 125.316 +
 125.317 +	votes += intersected_boundary_segments.size() % 2;
 125.318 +	//ai_assert(votes == 3 || votes == 0);
 125.319 +	return votes > 1;
 125.320 +}
 125.321 +
 125.322 +
 125.323 +// ------------------------------------------------------------------------------------------------
 125.324 +void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result, 
 125.325 +													   const TempMesh& first_operand, 
 125.326 +													   ConversionData& conv)
 125.327 +{
 125.328 +	ai_assert(hs != NULL);
 125.329 +
 125.330 +	const IfcPlane* const plane = hs->BaseSurface->ToPtr<IfcPlane>();
 125.331 +	if(!plane) {
 125.332 +		IFCImporter::LogError("expected IfcPlane as base surface for the IfcHalfSpaceSolid");
 125.333 +		return;
 125.334 +	}
 125.335 +
 125.336 +	// extract plane base position vector and normal vector
 125.337 +	IfcVector3 p,n(0.f,0.f,1.f);
 125.338 +	if (plane->Position->Axis) {
 125.339 +		ConvertDirection(n,plane->Position->Axis.Get());
 125.340 +	}
 125.341 +	ConvertCartesianPoint(p,plane->Position->Location);
 125.342 +
 125.343 +	if(!IsTrue(hs->AgreementFlag)) {
 125.344 +		n *= -1.f;
 125.345 +	}
 125.346 +
 125.347 +	n.Normalize();
 125.348 +
 125.349 +	// obtain the polygonal bounding volume
 125.350 +	boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh());
 125.351 +	if(!ProcessCurve(hs->PolygonalBoundary, *profile.get(), conv)) {
 125.352 +		IFCImporter::LogError("expected valid polyline for boundary of boolean halfspace");
 125.353 +		return;
 125.354 +	}
 125.355 +
 125.356 +	IfcMatrix4 proj_inv;
 125.357 +	ConvertAxisPlacement(proj_inv,hs->Position);
 125.358 +
 125.359 +	// and map everything into a plane coordinate space so all intersection
 125.360 +	// tests can be done in 2D space.
 125.361 +	IfcMatrix4 proj = proj_inv;
 125.362 +	proj.Inverse();
 125.363 +
 125.364 +	// clip the current contents of `meshout` against the plane we obtained from the second operand
 125.365 +	const std::vector<IfcVector3>& in = first_operand.verts;
 125.366 +	std::vector<IfcVector3>& outvert = result.verts;
 125.367 +
 125.368 +	std::vector<unsigned int>::const_iterator begin = first_operand.vertcnt.begin(), 
 125.369 +		end = first_operand.vertcnt.end(), iit;
 125.370 +
 125.371 +	outvert.reserve(in.size());
 125.372 +	result.vertcnt.reserve(first_operand.vertcnt.size());
 125.373 +
 125.374 +	std::vector<size_t> intersected_boundary_segments;
 125.375 +	std::vector<IfcVector3> intersected_boundary_points;
 125.376 +
 125.377 +	// TODO: the following algorithm doesn't handle all cases. 
 125.378 +	unsigned int vidx = 0;
 125.379 +	for(iit = begin; iit != end; vidx += *iit++) {
 125.380 +		if (!*iit) {
 125.381 +			continue;
 125.382 +		}
 125.383 +
 125.384 +		unsigned int newcount = 0;
 125.385 +		bool was_outside_boundary = !PointInPoly(proj * in[vidx], profile->verts);
 125.386 +
 125.387 +		// used any more?
 125.388 +		//size_t last_intersected_boundary_segment;
 125.389 +		IfcVector3 last_intersected_boundary_point;
 125.390 +
 125.391 +		bool extra_point_flag = false;
 125.392 +		IfcVector3 extra_point;
 125.393 +
 125.394 +		IfcVector3 enter_volume;
 125.395 +		bool entered_volume_flag = false;
 125.396 +
 125.397 +		for(unsigned int i = 0; i < *iit; ++i) {
 125.398 +			// current segment: [i,i+1 mod size] or [*extra_point,i] if extra_point_flag is set
 125.399 +			const IfcVector3& e0 = extra_point_flag ? extra_point : in[vidx+i];
 125.400 +			const IfcVector3& e1 = extra_point_flag ? in[vidx+i] : in[vidx+(i+1)%*iit];
 125.401 +
 125.402 +			// does the current segment intersect the polygonal boundary?
 125.403 +			const IfcVector3& e0_plane = proj * e0;
 125.404 +			const IfcVector3& e1_plane = proj * e1;
 125.405 +
 125.406 +			intersected_boundary_segments.clear();
 125.407 +			intersected_boundary_points.clear();
 125.408 +
 125.409 +			const bool is_outside_boundary = !PointInPoly(e1_plane, profile->verts);
 125.410 +			const bool is_boundary_intersection = is_outside_boundary != was_outside_boundary;
 125.411 +			
 125.412 +			IntersectsBoundaryProfile(e0_plane, e1_plane, profile->verts, 
 125.413 +				intersected_boundary_segments, 
 125.414 +				intersected_boundary_points);
 125.415 +		
 125.416 +			ai_assert(!is_boundary_intersection || !intersected_boundary_segments.empty());
 125.417 +
 125.418 +			// does the current segment intersect the plane?
 125.419 +			// (no extra check if this is an extra point)
 125.420 +			IfcVector3 isectpos;
 125.421 +			const Intersect isect =  extra_point_flag ? Intersect_No : IntersectSegmentPlane(p,n,e0,e1,isectpos);
 125.422 +
 125.423 +#ifdef _DEBUG
 125.424 +			if (isect == Intersect_Yes) {
 125.425 +				const IfcFloat f = fabs((isectpos - p)*n);
 125.426 +				ai_assert(f < 1e-5);
 125.427 +			}
 125.428 +#endif
 125.429 +
 125.430 +			const bool is_white_side = (e0-p)*n >= -1e-6;
 125.431 +
 125.432 +			// e0 on good side of plane? (i.e. we should keep all geometry on this side)
 125.433 +			if (is_white_side) {
 125.434 +				// but is there an intersection in e0-e1 and is e1 in the clipping
 125.435 +				// boundary? In this case, generate a line that only goes to the
 125.436 +				// intersection point.
 125.437 +				if (isect == Intersect_Yes  && !is_outside_boundary) {
 125.438 +					outvert.push_back(e0);
 125.439 +					++newcount;
 125.440 +
 125.441 +					outvert.push_back(isectpos);
 125.442 +					++newcount;
 125.443 +					
 125.444 +					/*
 125.445 +					// this is, however, only a line that goes to the plane, but not
 125.446 +					// necessarily to the point where the bounding volume on the
 125.447 +					// black side of the plane is hit. So basically, we need another 
 125.448 +					// check for [isectpos-e1], which should yield an intersection
 125.449 +					// point.
 125.450 +					extra_point_flag = true;
 125.451 +					extra_point = isectpos;
 125.452 +
 125.453 +					was_outside_boundary = true; 
 125.454 +					continue; */
 125.455 +
 125.456 +					// [isectpos, enter_volume] potentially needs extra points.
 125.457 +					// For this, we determine the intersection point with the
 125.458 +					// bounding volume and project it onto the plane. 
 125.459 +					/*
 125.460 +					const IfcVector3& enter_volume_proj = proj * enter_volume;
 125.461 +					const IfcVector3& enter_isectpos = proj * isectpos;
 125.462 +
 125.463 +					intersected_boundary_segments.clear();
 125.464 +					intersected_boundary_points.clear();
 125.465 +
 125.466 +					IntersectsBoundaryProfile(enter_volume_proj, enter_isectpos, profile->verts, 
 125.467 +						intersected_boundary_segments, 
 125.468 +						intersected_boundary_points);
 125.469 +
 125.470 +					if(!intersected_boundary_segments.empty()) {
 125.471 +
 125.472 +						vec = vec + ((p - vec) * n) * n;
 125.473 +					}
 125.474 +					*/				
 125.475 +
 125.476 +					//entered_volume_flag = true;
 125.477 +				}
 125.478 +				else {
 125.479 +					outvert.push_back(e0);
 125.480 +					++newcount;
 125.481 +				}
 125.482 +			}
 125.483 +			// e0 on bad side of plane, e1 on good (i.e. we should remove geometry on this side,
 125.484 +			// but only if it is within the bounding volume).
 125.485 +			else if (isect == Intersect_Yes) {
 125.486 +				// is e0 within the clipping volume? Insert the intersection point
 125.487 +				// of [e0,e1] and the plane instead of e0.
 125.488 +				if(was_outside_boundary) {
 125.489 +					outvert.push_back(e0);
 125.490 +				}
 125.491 +				else {
 125.492 +					if(entered_volume_flag) {
 125.493 +						const IfcVector3& fix_point = enter_volume + ((p - enter_volume) * n) * n;
 125.494 +						outvert.push_back(fix_point);
 125.495 +						++newcount;
 125.496 +					}
 125.497 +
 125.498 +					outvert.push_back(isectpos);	
 125.499 +				}
 125.500 +				entered_volume_flag = false;
 125.501 +				++newcount;
 125.502 +			}
 125.503 +			else { // no intersection with plane or parallel; e0,e1 are on the bad side
 125.504 +			
 125.505 +				// did we just pass the boundary line to the poly bounding?
 125.506 +				if (is_boundary_intersection) {
 125.507 +
 125.508 +					// and are now outside the clipping boundary?
 125.509 +					if (is_outside_boundary) {
 125.510 +						// in this case, get the point where the clipping boundary
 125.511 +						// was entered first. Then, get the point where the clipping
 125.512 +						// boundary volume was left! These two points with the plane
 125.513 +						// normal form another plane that intersects the clipping
 125.514 +						// volume. There are two ways to get from the first to the
 125.515 +						// second point along the intersection curve, try to pick the
 125.516 +						// one that lies within the current polygon.
 125.517 +
 125.518 +						// TODO this approach doesn't handle all cases
 125.519 +
 125.520 +						// ...
 125.521 +
 125.522 +						IfcFloat d = 1e20;
 125.523 +						IfcVector3 vclosest;
 125.524 +						BOOST_FOREACH(const IfcVector3& v, intersected_boundary_points) {
 125.525 +							const IfcFloat dn = (v-e1_plane).SquareLength();
 125.526 +							if (dn < d) {
 125.527 +								d = dn;
 125.528 +								vclosest = v;
 125.529 +							}
 125.530 +						}
 125.531 +
 125.532 +						vclosest = proj_inv * vclosest;
 125.533 +						if(entered_volume_flag) {
 125.534 +							const IfcVector3& fix_point = vclosest + ((p - vclosest) * n) * n;
 125.535 +							outvert.push_back(fix_point);
 125.536 +							++newcount;
 125.537 +
 125.538 +							entered_volume_flag = false;
 125.539 +						}
 125.540 +
 125.541 +						outvert.push_back(vclosest);
 125.542 +						++newcount;
 125.543 +
 125.544 +						//outvert.push_back(e1);
 125.545 +						//++newcount;
 125.546 +					}
 125.547 +					else {
 125.548 +						entered_volume_flag = true;
 125.549 +
 125.550 +						// we just entered the clipping boundary. Record the point
 125.551 +						// and the segment where we entered and also generate this point.
 125.552 +						//last_intersected_boundary_segment = intersected_boundary_segments.front();
 125.553 +						//last_intersected_boundary_point = intersected_boundary_points.front();
 125.554 +
 125.555 +						outvert.push_back(e0);
 125.556 +						++newcount;
 125.557 +
 125.558 +						IfcFloat d = 1e20;
 125.559 +						IfcVector3 vclosest;
 125.560 +						BOOST_FOREACH(const IfcVector3& v, intersected_boundary_points) {
 125.561 +							const IfcFloat dn = (v-e0_plane).SquareLength();
 125.562 +							if (dn < d) {
 125.563 +								d = dn;
 125.564 +								vclosest = v;
 125.565 +							}
 125.566 +						}
 125.567 +
 125.568 +						enter_volume = proj_inv * vclosest;
 125.569 +						outvert.push_back(enter_volume);
 125.570 +						++newcount;
 125.571 +					}
 125.572 +				}				
 125.573 +				// if not, we just keep the vertex
 125.574 +				else if (is_outside_boundary) {
 125.575 +					outvert.push_back(e0);
 125.576 +					++newcount;
 125.577 +
 125.578 +					entered_volume_flag = false;
 125.579 +				}
 125.580 +			}
 125.581 +
 125.582 +			was_outside_boundary = is_outside_boundary;
 125.583 +			extra_point_flag = false;
 125.584 +		}
 125.585 +	
 125.586 +		if (!newcount) {
 125.587 +			continue;
 125.588 +		}
 125.589 +		
 125.590 +		IfcVector3 vmin,vmax;
 125.591 +		ArrayBounds(&*(outvert.end()-newcount),newcount,vmin,vmax);
 125.592 +
 125.593 +		// filter our IfcFloat points - those may happen if a point lies
 125.594 +		// directly on the intersection line. However, due to IfcFloat
 125.595 +		// precision a bitwise comparison is not feasible to detect
 125.596 +		// this case.
 125.597 +		const IfcFloat epsilon = (vmax-vmin).SquareLength() / 1e6f;
 125.598 +		FuzzyVectorCompare fz(epsilon);
 125.599 +
 125.600 +		std::vector<IfcVector3>::iterator e = std::unique( outvert.end()-newcount, outvert.end(), fz );
 125.601 +
 125.602 +		if (e != outvert.end()) {
 125.603 +			newcount -= static_cast<unsigned int>(std::distance(e,outvert.end()));
 125.604 +			outvert.erase(e,outvert.end());
 125.605 +		}
 125.606 +		if (fz(*( outvert.end()-newcount),outvert.back())) {
 125.607 +			outvert.pop_back();
 125.608 +			--newcount;
 125.609 +		} 
 125.610 +		if(newcount > 2) {
 125.611 +			result.vertcnt.push_back(newcount);
 125.612 +		}
 125.613 +		else while(newcount-->0) {
 125.614 +			result.verts.pop_back();
 125.615 +		}
 125.616 +
 125.617 +	}
 125.618 +	IFCImporter::LogDebug("generating CSG geometry by plane clipping with polygonal bounding (IfcBooleanClippingResult)");	
 125.619 +}
 125.620 +
 125.621 +// ------------------------------------------------------------------------------------------------
 125.622 +void ProcessBooleanExtrudedAreaSolidDifference(const IfcExtrudedAreaSolid* as, TempMesh& result, 
 125.623 +											   const TempMesh& first_operand, 
 125.624 +											   ConversionData& conv)
 125.625 +{
 125.626 +	ai_assert(as != NULL);
 125.627 +
 125.628 +	// This case is handled by reduction to an instance of the quadrify() algorithm.
 125.629 +	// Obviously, this won't work for arbitrarily complex cases. In fact, the first
 125.630 +	// operand should be near-planar. Luckily, this is usually the case in Ifc 
 125.631 +	// buildings.
 125.632 +
 125.633 +	boost::shared_ptr<TempMesh> meshtmp = boost::shared_ptr<TempMesh>(new TempMesh());
 125.634 +	ProcessExtrudedAreaSolid(*as,*meshtmp,conv,false);
 125.635 +
 125.636 +	std::vector<TempOpening> openings(1, TempOpening(as,IfcVector3(0,0,0),meshtmp,boost::shared_ptr<TempMesh>()));
 125.637 +
 125.638 +	result = first_operand;
 125.639 +
 125.640 +	TempMesh temp;
 125.641 +
 125.642 +	std::vector<IfcVector3>::const_iterator vit = first_operand.verts.begin();
 125.643 +	BOOST_FOREACH(unsigned int pcount, first_operand.vertcnt) {
 125.644 +		temp.Clear();
 125.645 +
 125.646 +		temp.verts.insert(temp.verts.end(), vit, vit + pcount);
 125.647 +		temp.vertcnt.push_back(pcount);
 125.648 +
 125.649 +		// The algorithms used to generate mesh geometry sometimes
 125.650 +		// spit out lines or other degenerates which must be
 125.651 +		// filtered to avoid running into assertions later on.
 125.652 +
 125.653 +		// ComputePolygonNormal returns the Newell normal, so the
 125.654 +		// length of the normal is the area of the polygon.
 125.655 +		const IfcVector3& normal = temp.ComputeLastPolygonNormal(false);
 125.656 +		if (normal.SquareLength() < static_cast<IfcFloat>(1e-5)) {
 125.657 +			IFCImporter::LogWarn("skipping degenerate polygon (ProcessBooleanExtrudedAreaSolidDifference)");
 125.658 +			continue;
 125.659 +		}
 125.660 +
 125.661 +		GenerateOpenings(openings, std::vector<IfcVector3>(1,IfcVector3(1,0,0)), temp, false, true);
 125.662 +		result.Append(temp);
 125.663 +
 125.664 +		vit += pcount;
 125.665 +	}
 125.666 +
 125.667 +	IFCImporter::LogDebug("generating CSG geometry by geometric difference to a solid (IfcExtrudedAreaSolid)");
 125.668 +}
 125.669 +
 125.670 +// ------------------------------------------------------------------------------------------------
 125.671 +void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, ConversionData& conv)
 125.672 +{
 125.673 +	// supported CSG operations:
 125.674 +	//   DIFFERENCE
 125.675 +	if(const IfcBooleanResult* const clip = boolean.ToPtr<IfcBooleanResult>()) {
 125.676 +		if(clip->Operator != "DIFFERENCE") {
 125.677 +			IFCImporter::LogWarn("encountered unsupported boolean operator: " + (std::string)clip->Operator);
 125.678 +			return;
 125.679 +		}
 125.680 +
 125.681 +		// supported cases (1st operand):
 125.682 +		//  IfcBooleanResult -- call ProcessBoolean recursively
 125.683 +		//  IfcSweptAreaSolid -- obtain polygonal geometry first
 125.684 +
 125.685 +		// supported cases (2nd operand):
 125.686 +		//  IfcHalfSpaceSolid -- easy, clip against plane
 125.687 +		//  IfcExtrudedAreaSolid -- reduce to an instance of the quadrify() algorithm
 125.688 +
 125.689 +
 125.690 +		const IfcHalfSpaceSolid* const hs = clip->SecondOperand->ResolveSelectPtr<IfcHalfSpaceSolid>(conv.db);
 125.691 +		const IfcExtrudedAreaSolid* const as = clip->SecondOperand->ResolveSelectPtr<IfcExtrudedAreaSolid>(conv.db);
 125.692 +		if(!hs && !as) {
 125.693 +			IFCImporter::LogError("expected IfcHalfSpaceSolid or IfcExtrudedAreaSolid as second clipping operand");
 125.694 +			return;
 125.695 +		}
 125.696 +
 125.697 +		TempMesh first_operand;
 125.698 +		if(const IfcBooleanResult* const op0 = clip->FirstOperand->ResolveSelectPtr<IfcBooleanResult>(conv.db)) {
 125.699 +			ProcessBoolean(*op0,first_operand,conv);
 125.700 +		}
 125.701 +		else if (const IfcSweptAreaSolid* const swept = clip->FirstOperand->ResolveSelectPtr<IfcSweptAreaSolid>(conv.db)) {
 125.702 +			ProcessSweptAreaSolid(*swept,first_operand,conv);
 125.703 +		}
 125.704 +		else {
 125.705 +			IFCImporter::LogError("expected IfcSweptAreaSolid or IfcBooleanResult as first clipping operand");
 125.706 +			return;
 125.707 +		}
 125.708 +
 125.709 +		if(hs) {
 125.710 +
 125.711 +			const IfcPolygonalBoundedHalfSpace* const hs_bounded = clip->SecondOperand->ResolveSelectPtr<IfcPolygonalBoundedHalfSpace>(conv.db);
 125.712 +			if (hs_bounded) {
 125.713 +				ProcessPolygonalBoundedBooleanHalfSpaceDifference(hs_bounded, result, first_operand, conv);
 125.714 +			}
 125.715 +			else {
 125.716 +				ProcessBooleanHalfSpaceDifference(hs, result, first_operand, conv);
 125.717 +			}
 125.718 +		}
 125.719 +		else {
 125.720 +			ProcessBooleanExtrudedAreaSolidDifference(as, result, first_operand, conv);
 125.721 +		}
 125.722 +	}
 125.723 +	else {
 125.724 +		IFCImporter::LogWarn("skipping unknown IfcBooleanResult entity, type is " + boolean.GetClassName());
 125.725 +	}
 125.726 +}
 125.727 +
 125.728 +} // ! IFC
 125.729 +} // ! Assimp
 125.730 +
 125.731 +#endif 
 125.732 +
   126.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   126.2 +++ b/libs/assimp/IFCCurve.cpp	Sat Feb 01 19:58:19 2014 +0200
   126.3 @@ -0,0 +1,677 @@
   126.4 +/*
   126.5 +Open Asset Import Library (assimp)
   126.6 +----------------------------------------------------------------------
   126.7 +
   126.8 +Copyright (c) 2006-2012, assimp team
   126.9 +All rights reserved.
  126.10 +
  126.11 +Redistribution and use of this software in source and binary forms, 
  126.12 +with or without modification, are permitted provided that the 
  126.13 +following conditions are met:
  126.14 +
  126.15 +* Redistributions of source code must retain the above
  126.16 +  copyright notice, this list of conditions and the
  126.17 +  following disclaimer.
  126.18 +
  126.19 +* Redistributions in binary form must reproduce the above
  126.20 +  copyright notice, this list of conditions and the
  126.21 +  following disclaimer in the documentation and/or other
  126.22 +  materials provided with the distribution.
  126.23 +
  126.24 +* Neither the name of the assimp team, nor the names of its
  126.25 +  contributors may be used to endorse or promote products
  126.26 +  derived from this software without specific prior
  126.27 +  written permission of the assimp team.
  126.28 +
  126.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  126.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  126.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  126.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  126.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  126.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  126.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  126.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  126.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  126.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  126.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  126.40 +
  126.41 +----------------------------------------------------------------------
  126.42 +*/
  126.43 +
  126.44 +/** @file  IFCProfile.cpp
  126.45 + *  @brief Read profile and curves entities from IFC files
  126.46 + */
  126.47 +
  126.48 +#include "AssimpPCH.h"
  126.49 +
  126.50 +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
  126.51 +#include "IFCUtil.h"
  126.52 +
  126.53 +namespace Assimp {
  126.54 +	namespace IFC {
  126.55 +		namespace {
  126.56 +
  126.57 +
  126.58 +// --------------------------------------------------------------------------------
  126.59 +// Conic is the base class for Circle and Ellipse
  126.60 +// --------------------------------------------------------------------------------
  126.61 +class Conic : public Curve
  126.62 +{
  126.63 +
  126.64 +public:
  126.65 +
  126.66 +	// --------------------------------------------------
  126.67 +	Conic(const IfcConic& entity, ConversionData& conv) 
  126.68 +		: Curve(entity,conv)
  126.69 +	{
  126.70 +		IfcMatrix4 trafo;
  126.71 +		ConvertAxisPlacement(trafo,*entity.Position,conv);
  126.72 +
  126.73 +		// for convenience, extract the matrix rows
  126.74 +		location = IfcVector3(trafo.a4,trafo.b4,trafo.c4);
  126.75 +		p[0] = IfcVector3(trafo.a1,trafo.b1,trafo.c1);
  126.76 +		p[1] = IfcVector3(trafo.a2,trafo.b2,trafo.c2);
  126.77 +		p[2] = IfcVector3(trafo.a3,trafo.b3,trafo.c3);
  126.78 +	}
  126.79 +
  126.80 +public:
  126.81 +
  126.82 +	// --------------------------------------------------
  126.83 +	bool IsClosed() const {
  126.84 +		return true;
  126.85 +	}
  126.86 +	
  126.87 +	// --------------------------------------------------
  126.88 +	size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
  126.89 +		ai_assert(InRange(a) && InRange(b));
  126.90 +
  126.91 +		a *= conv.angle_scale;
  126.92 +		b *= conv.angle_scale;
  126.93 +
  126.94 +		a = fmod(a,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
  126.95 +		b = fmod(b,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
  126.96 +		const IfcFloat setting = static_cast<IfcFloat>( AI_MATH_PI * conv.settings.conicSamplingAngle / 180.0 );
  126.97 +		return static_cast<size_t>( ceil(abs( b-a)) / setting);
  126.98 +	}
  126.99 +
 126.100 +	// --------------------------------------------------
 126.101 +	ParamRange GetParametricRange() const {
 126.102 +		return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( AI_MATH_TWO_PI / conv.angle_scale ));
 126.103 +	}
 126.104 +
 126.105 +protected:
 126.106 +	IfcVector3 location, p[3];
 126.107 +};
 126.108 +
 126.109 +
 126.110 +// --------------------------------------------------------------------------------
 126.111 +// Circle
 126.112 +// --------------------------------------------------------------------------------
 126.113 +class Circle : public Conic
 126.114 +{
 126.115 +
 126.116 +public:
 126.117 +
 126.118 +	// --------------------------------------------------
 126.119 +	Circle(const IfcCircle& entity, ConversionData& conv) 
 126.120 +		: Conic(entity,conv)
 126.121 +		, entity(entity)
 126.122 +	{
 126.123 +	}
 126.124 +
 126.125 +public:
 126.126 +
 126.127 +	// --------------------------------------------------
 126.128 +	IfcVector3 Eval(IfcFloat u) const {
 126.129 +		u = -conv.angle_scale * u;
 126.130 +		return location + static_cast<IfcFloat>(entity.Radius)*(static_cast<IfcFloat>(::cos(u))*p[0] + 
 126.131 +			static_cast<IfcFloat>(::sin(u))*p[1]);
 126.132 +	}
 126.133 +
 126.134 +private:
 126.135 +	const IfcCircle& entity;
 126.136 +};
 126.137 +
 126.138 +
 126.139 +// --------------------------------------------------------------------------------
 126.140 +// Ellipse
 126.141 +// --------------------------------------------------------------------------------
 126.142 +class Ellipse : public Conic
 126.143 +{
 126.144 +
 126.145 +public:
 126.146 +
 126.147 +	// --------------------------------------------------
 126.148 +	Ellipse(const IfcEllipse& entity, ConversionData& conv) 
 126.149 +		: Conic(entity,conv)
 126.150 +		, entity(entity)
 126.151 +	{
 126.152 +	}
 126.153 +
 126.154 +public:
 126.155 +
 126.156 +	// --------------------------------------------------
 126.157 +	IfcVector3 Eval(IfcFloat u) const {
 126.158 +		u = -conv.angle_scale * u;
 126.159 +		return location + static_cast<IfcFloat>(entity.SemiAxis1)*static_cast<IfcFloat>(::cos(u))*p[0] +
 126.160 +			static_cast<IfcFloat>(entity.SemiAxis2)*static_cast<IfcFloat>(::sin(u))*p[1];
 126.161 +	}
 126.162 +
 126.163 +private:
 126.164 +	const IfcEllipse& entity;
 126.165 +};
 126.166 +
 126.167 +
 126.168 +// --------------------------------------------------------------------------------
 126.169 +// Line
 126.170 +// --------------------------------------------------------------------------------
 126.171 +class Line : public Curve 
 126.172 +{
 126.173 +
 126.174 +public:
 126.175 +
 126.176 +	// --------------------------------------------------
 126.177 +	Line(const IfcLine& entity, ConversionData& conv) 
 126.178 +		: Curve(entity,conv)
 126.179 +		, entity(entity)
 126.180 +	{
 126.181 +		ConvertCartesianPoint(p,entity.Pnt);
 126.182 +		ConvertVector(v,entity.Dir);
 126.183 +	}
 126.184 +
 126.185 +public:
 126.186 +
 126.187 +	// --------------------------------------------------
 126.188 +	bool IsClosed() const {
 126.189 +		return false;
 126.190 +	}
 126.191 +
 126.192 +	// --------------------------------------------------
 126.193 +	IfcVector3 Eval(IfcFloat u) const {
 126.194 +		return p + u*v;
 126.195 +	}
 126.196 +
 126.197 +	// --------------------------------------------------
 126.198 +	size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
 126.199 +		ai_assert(InRange(a) && InRange(b));
 126.200 +		// two points are always sufficient for a line segment
 126.201 +		return a==b ? 1 : 2;
 126.202 +	}
 126.203 +
 126.204 +
 126.205 +	// --------------------------------------------------
 126.206 +	void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
 126.207 +	{
 126.208 +		ai_assert(InRange(a) && InRange(b));
 126.209 +	
 126.210 +		if (a == b) {
 126.211 +			out.verts.push_back(Eval(a));
 126.212 +			return;
 126.213 +		}
 126.214 +		out.verts.reserve(out.verts.size()+2);
 126.215 +		out.verts.push_back(Eval(a));
 126.216 +		out.verts.push_back(Eval(b));
 126.217 +	}
 126.218 +
 126.219 +	// --------------------------------------------------
 126.220 +	ParamRange GetParametricRange() const {
 126.221 +		const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity();
 126.222 +
 126.223 +		return std::make_pair(-inf,+inf);
 126.224 +	}
 126.225 +
 126.226 +private:
 126.227 +	const IfcLine& entity;
 126.228 +	IfcVector3 p,v;
 126.229 +};
 126.230 +
 126.231 +// --------------------------------------------------------------------------------
 126.232 +// CompositeCurve joins multiple smaller, bounded curves
 126.233 +// --------------------------------------------------------------------------------
 126.234 +class CompositeCurve : public BoundedCurve 
 126.235 +{
 126.236 +
 126.237 +	typedef std::pair< boost::shared_ptr< BoundedCurve >, bool > CurveEntry;
 126.238 +
 126.239 +public:
 126.240 +
 126.241 +	// --------------------------------------------------
 126.242 +	CompositeCurve(const IfcCompositeCurve& entity, ConversionData& conv) 
 126.243 +		: BoundedCurve(entity,conv)
 126.244 +		, entity(entity)
 126.245 +		, total()
 126.246 +	{
 126.247 +		curves.reserve(entity.Segments.size());
 126.248 +		BOOST_FOREACH(const IfcCompositeCurveSegment& curveSegment,entity.Segments) {
 126.249 +			// according to the specification, this must be a bounded curve
 126.250 +			boost::shared_ptr< Curve > cv(Curve::Convert(curveSegment.ParentCurve,conv));
 126.251 +			boost::shared_ptr< BoundedCurve > bc = boost::dynamic_pointer_cast<BoundedCurve>(cv);
 126.252 +
 126.253 +			if (!bc) {
 126.254 +				IFCImporter::LogError("expected segment of composite curve to be a bounded curve");
 126.255 +				continue;
 126.256 +			}
 126.257 +
 126.258 +			if ( (std::string)curveSegment.Transition != "CONTINUOUS" ) {
 126.259 +				IFCImporter::LogDebug("ignoring transition code on composite curve segment, only continuous transitions are supported");
 126.260 +			}
 126.261 +
 126.262 +			curves.push_back( CurveEntry(bc,IsTrue(curveSegment.SameSense)) );
 126.263 +			total += bc->GetParametricRangeDelta();
 126.264 +		}
 126.265 +
 126.266 +		if (curves.empty()) {
 126.267 +			throw CurveError("empty composite curve");
 126.268 +		}
 126.269 +	}
 126.270 +
 126.271 +public:
 126.272 +
 126.273 +	// --------------------------------------------------
 126.274 +	IfcVector3 Eval(IfcFloat u) const {
 126.275 +		if (curves.empty()) {
 126.276 +			return IfcVector3();
 126.277 +		}
 126.278 +
 126.279 +		IfcFloat acc = 0;
 126.280 +		BOOST_FOREACH(const CurveEntry& entry, curves) {
 126.281 +			const ParamRange& range = entry.first->GetParametricRange();
 126.282 +			const IfcFloat delta = abs(range.second-range.first);
 126.283 +			if (u < acc+delta) {
 126.284 +				return entry.first->Eval( entry.second ? (u-acc) + range.first : range.second-(u-acc));
 126.285 +			}
 126.286 +
 126.287 +			acc += delta;
 126.288 +		}
 126.289 +		// clamp to end
 126.290 +		return curves.back().first->Eval(curves.back().first->GetParametricRange().second);
 126.291 +	}
 126.292 +
 126.293 +	// --------------------------------------------------
 126.294 +	size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
 126.295 +		ai_assert(InRange(a) && InRange(b));
 126.296 +		size_t cnt = 0;
 126.297 +
 126.298 +		IfcFloat acc = 0;
 126.299 +		BOOST_FOREACH(const CurveEntry& entry, curves) {
 126.300 +			const ParamRange& range = entry.first->GetParametricRange();
 126.301 +			const IfcFloat delta = abs(range.second-range.first);
 126.302 +			if (a <= acc+delta && b >= acc) {
 126.303 +				const IfcFloat at =  std::max(static_cast<IfcFloat>( 0. ),a-acc), bt = std::min(delta,b-acc);
 126.304 +				cnt += entry.first->EstimateSampleCount( entry.second ? at + range.first : range.second - bt, entry.second ? bt + range.first : range.second - at );
 126.305 +			}
 126.306 +
 126.307 +			acc += delta;
 126.308 +		}
 126.309 +
 126.310 +		return cnt;
 126.311 +	}
 126.312 +
 126.313 +	// --------------------------------------------------
 126.314 +	void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
 126.315 +	{
 126.316 +		ai_assert(InRange(a) && InRange(b));
 126.317 +
 126.318 +		const size_t cnt = EstimateSampleCount(a,b);
 126.319 +		out.verts.reserve(out.verts.size() + cnt);
 126.320 +
 126.321 +		BOOST_FOREACH(const CurveEntry& entry, curves) {
 126.322 +			const size_t cnt = out.verts.size();
 126.323 +			entry.first->SampleDiscrete(out);
 126.324 +
 126.325 +			if (!entry.second && cnt != out.verts.size()) {
 126.326 +				std::reverse(out.verts.begin()+cnt,out.verts.end());
 126.327 +			}
 126.328 +		}
 126.329 +	}
 126.330 +
 126.331 +	// --------------------------------------------------
 126.332 +	ParamRange GetParametricRange() const {
 126.333 +		return std::make_pair(static_cast<IfcFloat>( 0. ),total);
 126.334 +	}
 126.335 +
 126.336 +private:
 126.337 +	const IfcCompositeCurve& entity;
 126.338 +	std::vector< CurveEntry > curves;
 126.339 +
 126.340 +	IfcFloat total;
 126.341 +};
 126.342 +
 126.343 +
 126.344 +// --------------------------------------------------------------------------------
 126.345 +// TrimmedCurve can be used to trim an unbounded curve to a bounded range
 126.346 +// --------------------------------------------------------------------------------
 126.347 +class TrimmedCurve : public BoundedCurve 
 126.348 +{
 126.349 +
 126.350 +public:
 126.351 +
 126.352 +	// --------------------------------------------------
 126.353 +	TrimmedCurve(const IfcTrimmedCurve& entity, ConversionData& conv) 
 126.354 +		: BoundedCurve(entity,conv)
 126.355 +		, entity(entity)
 126.356 +		, ok()
 126.357 +	{
 126.358 +		base = boost::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv));
 126.359 +
 126.360 +		typedef boost::shared_ptr<const STEP::EXPRESS::DataType> Entry;
 126.361 +	
 126.362 +		// for some reason, trimmed curves can either specify a parametric value
 126.363 +		// or a point on the curve, or both. And they can even specify which of the
 126.364 +		// two representations they prefer, even though an information invariant
 126.365 +		// claims that they must be identical if both are present.
 126.366 +		// oh well.
 126.367 +		bool have_param = false, have_point = false;
 126.368 +		IfcVector3 point;
 126.369 +		BOOST_FOREACH(const Entry sel,entity.Trim1) {
 126.370 +			if (const EXPRESS::REAL* const r = sel->ToPtr<EXPRESS::REAL>()) {
 126.371 +				range.first = *r;
 126.372 +				have_param = true;
 126.373 +				break;
 126.374 +			}
 126.375 +			else if (const IfcCartesianPoint* const r = sel->ResolveSelectPtr<IfcCartesianPoint>(conv.db)) {
 126.376 +				ConvertCartesianPoint(point,*r);
 126.377 +				have_point = true;
 126.378 +			}
 126.379 +		}
 126.380 +		if (!have_param) {
 126.381 +			if (!have_point || !base->ReverseEval(point,range.first)) {
 126.382 +				throw CurveError("IfcTrimmedCurve: failed to read first trim parameter, ignoring curve");
 126.383 +			}
 126.384 +		}
 126.385 +		have_param = false, have_point = false;
 126.386 +		BOOST_FOREACH(const Entry sel,entity.Trim2) {
 126.387 +			if (const EXPRESS::REAL* const r = sel->ToPtr<EXPRESS::REAL>()) {
 126.388 +				range.second = *r;
 126.389 +				have_param = true;
 126.390 +				break;
 126.391 +			}
 126.392 +			else if (const IfcCartesianPoint* const r = sel->ResolveSelectPtr<IfcCartesianPoint>(conv.db)) {
 126.393 +				ConvertCartesianPoint(point,*r);
 126.394 +				have_point = true;
 126.395 +			}
 126.396 +		}
 126.397 +		if (!have_param) {
 126.398 +			if (!have_point || !base->ReverseEval(point,range.second)) {
 126.399 +				throw CurveError("IfcTrimmedCurve: failed to read second trim parameter, ignoring curve");
 126.400 +			}
 126.401 +		}
 126.402 +
 126.403 +		agree_sense = IsTrue(entity.SenseAgreement);
 126.404 +		if( !agree_sense ) {
 126.405 +			std::swap(range.first,range.second);
 126.406 +		}
 126.407 +
 126.408 +		// "NOTE In case of a closed curve, it may be necessary to increment t1 or t2
 126.409 +		// by the parametric length for consistency with the sense flag."
 126.410 +		if (base->IsClosed()) {
 126.411 +			if( range.first > range.second ) {
 126.412 +				range.second += base->GetParametricRangeDelta();
 126.413 +			}
 126.414 +		}
 126.415 +
 126.416 +		maxval = range.second-range.first;
 126.417 +		ai_assert(maxval >= 0);
 126.418 +	}
 126.419 +
 126.420 +public:
 126.421 +
 126.422 +	// --------------------------------------------------
 126.423 +	IfcVector3 Eval(IfcFloat p) const {
 126.424 +		ai_assert(InRange(p));
 126.425 +		return base->Eval( TrimParam(p) );
 126.426 +	}
 126.427 +
 126.428 +	// --------------------------------------------------
 126.429 +	size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
 126.430 +		ai_assert(InRange(a) && InRange(b));
 126.431 +		return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
 126.432 +	}
 126.433 +
 126.434 +	// --------------------------------------------------
 126.435 +	void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const {
 126.436 +		ai_assert(InRange(a) && InRange(b));
 126.437 +		return base->SampleDiscrete(out,TrimParam(a),TrimParam(b));
 126.438 +	}
 126.439 +
 126.440 +	// --------------------------------------------------
 126.441 +	ParamRange GetParametricRange() const {
 126.442 +		return std::make_pair(static_cast<IfcFloat>( 0. ),maxval);
 126.443 +	}
 126.444 +
 126.445 +private:
 126.446 +
 126.447 +	// --------------------------------------------------
 126.448 +	IfcFloat TrimParam(IfcFloat f) const {
 126.449 +		return agree_sense ? f + range.first :  range.second - f;
 126.450 +	}
 126.451 +
 126.452 +
 126.453 +private:
 126.454 +	const IfcTrimmedCurve& entity;
 126.455 +	ParamRange range;
 126.456 +	IfcFloat maxval;
 126.457 +	bool agree_sense;
 126.458 +	bool ok;
 126.459 +
 126.460 +	boost::shared_ptr<const Curve> base;
 126.461 +};
 126.462 +
 126.463 +
 126.464 +// --------------------------------------------------------------------------------
 126.465 +// PolyLine is a 'curve' defined by linear interpolation over a set of discrete points
 126.466 +// --------------------------------------------------------------------------------
 126.467 +class PolyLine : public BoundedCurve 
 126.468 +{
 126.469 +
 126.470 +public:
 126.471 +
 126.472 +	// --------------------------------------------------
 126.473 +	PolyLine(const IfcPolyline& entity, ConversionData& conv) 
 126.474 +		: BoundedCurve(entity,conv)
 126.475 +		, entity(entity)
 126.476 +	{
 126.477 +		points.reserve(entity.Points.size());
 126.478 +
 126.479 +		IfcVector3 t;
 126.480 +		BOOST_FOREACH(const IfcCartesianPoint& cp, entity.Points) {
 126.481 +			ConvertCartesianPoint(t,cp);
 126.482 +			points.push_back(t);
 126.483 +		}
 126.484 +	}
 126.485 +
 126.486 +public:
 126.487 +
 126.488 +	// --------------------------------------------------
 126.489 +	IfcVector3 Eval(IfcFloat p) const {
 126.490 +		ai_assert(InRange(p));
 126.491 +		
 126.492 +		const size_t b = static_cast<size_t>(floor(p));  
 126.493 +		if (b == points.size()-1) {
 126.494 +			return points.back();
 126.495 +		}
 126.496 +
 126.497 +		const IfcFloat d = p-static_cast<IfcFloat>(b);
 126.498 +		return points[b+1] * d + points[b] * (static_cast<IfcFloat>( 1. )-d);
 126.499 +	}
 126.500 +
 126.501 +	// --------------------------------------------------
 126.502 +	size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
 126.503 +		ai_assert(InRange(a) && InRange(b));
 126.504 +		return static_cast<size_t>( ceil(b) - floor(a) );
 126.505 +	}
 126.506 +
 126.507 +	// --------------------------------------------------
 126.508 +	ParamRange GetParametricRange() const {
 126.509 +		return std::make_pair(static_cast<IfcFloat>( 0. ),static_cast<IfcFloat>(points.size()-1));
 126.510 +	}
 126.511 +
 126.512 +private:
 126.513 +	const IfcPolyline& entity;
 126.514 +	std::vector<IfcVector3> points;
 126.515 +};
 126.516 +
 126.517 +
 126.518 +} // anon
 126.519 +
 126.520 +
 126.521 +// ------------------------------------------------------------------------------------------------
 126.522 +Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv) 
 126.523 +{
 126.524 +	if(curve.ToPtr<IfcBoundedCurve>()) {
 126.525 +		if(const IfcPolyline* c = curve.ToPtr<IfcPolyline>()) {
 126.526 +			return new PolyLine(*c,conv);
 126.527 +		}
 126.528 +		if(const IfcTrimmedCurve* c = curve.ToPtr<IfcTrimmedCurve>()) {
 126.529 +			return new TrimmedCurve(*c,conv);
 126.530 +		}
 126.531 +		if(const IfcCompositeCurve* c = curve.ToPtr<IfcCompositeCurve>()) {
 126.532 +			return new CompositeCurve(*c,conv);
 126.533 +		}
 126.534 +		//if(const IfcBSplineCurve* c = curve.ToPtr<IfcBSplineCurve>()) {
 126.535 +		//	return new BSplineCurve(*c,conv);
 126.536 +		//}
 126.537 +	}
 126.538 +
 126.539 +	if(curve.ToPtr<IfcConic>()) {
 126.540 +		if(const IfcCircle* c = curve.ToPtr<IfcCircle>()) {
 126.541 +			return new Circle(*c,conv);
 126.542 +		}
 126.543 +		if(const IfcEllipse* c = curve.ToPtr<IfcEllipse>()) {
 126.544 +			return new Ellipse(*c,conv);
 126.545 +		}
 126.546 +	}
 126.547 +
 126.548 +	if(const IfcLine* c = curve.ToPtr<IfcLine>()) {
 126.549 +		return new Line(*c,conv);
 126.550 +	}
 126.551 +
 126.552 +	// XXX OffsetCurve2D, OffsetCurve3D not currently supported
 126.553 +	return NULL;
 126.554 +}
 126.555 +
 126.556 +#ifdef _DEBUG
 126.557 +// ------------------------------------------------------------------------------------------------
 126.558 +bool Curve :: InRange(IfcFloat u) const 
 126.559 +{
 126.560 +	const ParamRange range = GetParametricRange();
 126.561 +	if (IsClosed()) {
 126.562 +		return true;
 126.563 +		//ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
 126.564 +		//u = range.first + fmod(u-range.first,range.second-range.first);
 126.565 +	}
 126.566 +	const IfcFloat epsilon = 1e-5;
 126.567 +	return u - range.first > -epsilon && range.second - u > -epsilon;
 126.568 +}
 126.569 +#endif 
 126.570 +
 126.571 +// ------------------------------------------------------------------------------------------------
 126.572 +IfcFloat Curve :: GetParametricRangeDelta() const
 126.573 +{
 126.574 +	const ParamRange& range = GetParametricRange();
 126.575 +	return abs(range.second - range.first);
 126.576 +}
 126.577 +
 126.578 +// ------------------------------------------------------------------------------------------------
 126.579 +size_t Curve :: EstimateSampleCount(IfcFloat a, IfcFloat b) const
 126.580 +{
 126.581 +	ai_assert(InRange(a) && InRange(b));
 126.582 +
 126.583 +	// arbitrary default value, deriving classes should supply better suited values
 126.584 +	return 16;
 126.585 +}
 126.586 +
 126.587 +// ------------------------------------------------------------------------------------------------
 126.588 +IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, IfcFloat b, unsigned int samples, IfcFloat threshold, unsigned int recurse = 0, unsigned int max_recurse = 15)
 126.589 +{
 126.590 +	ai_assert(samples>1);
 126.591 +
 126.592 +	const IfcFloat delta = (b-a)/samples, inf = std::numeric_limits<IfcFloat>::infinity();
 126.593 +	IfcFloat min_point[2] = {a,b}, min_diff[2] = {inf,inf};
 126.594 +	IfcFloat runner = a;
 126.595 +
 126.596 +	for (unsigned int i = 0; i < samples; ++i, runner += delta) {
 126.597 +		const IfcFloat diff = (cv->Eval(runner)-val).SquareLength();
 126.598 +		if (diff < min_diff[0]) {
 126.599 +			min_diff[1] = min_diff[0];
 126.600 +			min_point[1] = min_point[0];
 126.601 +
 126.602 +			min_diff[0] = diff;
 126.603 +			min_point[0] = runner;
 126.604 +		}
 126.605 +		else if (diff < min_diff[1]) {
 126.606 +			min_diff[1] = diff;
 126.607 +			min_point[1] = runner;
 126.608 +		}
 126.609 +	}
 126.610 +
 126.611 +	ai_assert(min_diff[0] != inf && min_diff[1] != inf);
 126.612 +	if ( fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
 126.613 +		return min_point[0];
 126.614 +	}
 126.615 +
 126.616 +	// fix for closed curves to take their wrap-over into account
 126.617 +	if (cv->IsClosed() && fabs(min_point[0]-min_point[1]) > cv->GetParametricRangeDelta()*0.5  ) {
 126.618 +		const Curve::ParamRange& range = cv->GetParametricRange();
 126.619 +		const IfcFloat wrapdiff = (cv->Eval(range.first)-val).SquareLength();
 126.620 +
 126.621 +		if (wrapdiff < min_diff[0]) {
 126.622 +			const IfcFloat t = min_point[0];
 126.623 +			min_point[0] = min_point[1] > min_point[0] ? range.first : range.second;
 126.624 +			 min_point[1] = t;
 126.625 +		}
 126.626 +	}
 126.627 +
 126.628 +	return RecursiveSearch(cv,val,min_point[0],min_point[1],samples,threshold,recurse+1,max_recurse);
 126.629 +}
 126.630 +
 126.631 +// ------------------------------------------------------------------------------------------------
 126.632 +bool Curve :: ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const
 126.633 +{
 126.634 +	// note: the following algorithm is not guaranteed to find the 'right' parameter value
 126.635 +	// in all possible cases, but it will always return at least some value so this function
 126.636 +	// will never fail in the default implementation.
 126.637 +
 126.638 +	// XXX derive threshold from curve topology
 126.639 +	const IfcFloat threshold = 1e-4f;
 126.640 +	const unsigned int samples = 16;
 126.641 +
 126.642 +	const ParamRange& range = GetParametricRange();
 126.643 +	paramOut = RecursiveSearch(this,val,range.first,range.second,samples,threshold);
 126.644 +
 126.645 +	return true;
 126.646 +}
 126.647 +
 126.648 +// ------------------------------------------------------------------------------------------------
 126.649 +void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
 126.650 +{
 126.651 +	ai_assert(InRange(a) && InRange(b));
 126.652 +
 126.653 +	const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b));
 126.654 +	out.verts.reserve( out.verts.size() + cnt );
 126.655 +
 126.656 +	IfcFloat p = a, delta = (b-a)/cnt;
 126.657 +	for(size_t i = 0; i < cnt; ++i, p += delta) {
 126.658 +		out.verts.push_back(Eval(p));
 126.659 +	}
 126.660 +}
 126.661 +
 126.662 +// ------------------------------------------------------------------------------------------------
 126.663 +bool BoundedCurve :: IsClosed() const
 126.664 +{
 126.665 +	return false;
 126.666 +}
 126.667 +
 126.668 +// ------------------------------------------------------------------------------------------------
 126.669 +void BoundedCurve :: SampleDiscrete(TempMesh& out) const
 126.670 +{
 126.671 +	const ParamRange& range = GetParametricRange();
 126.672 +	ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
 126.673 +
 126.674 +	return SampleDiscrete(out,range.first,range.second);
 126.675 +}
 126.676 +
 126.677 +} // IFC
 126.678 +} // Assimp
 126.679 +
 126.680 +#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
   127.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   127.2 +++ b/libs/assimp/IFCGeometry.cpp	Sat Feb 01 19:58:19 2014 +0200
   127.3 @@ -0,0 +1,851 @@
   127.4 +/*
   127.5 +Open Asset Import Library (assimp)
   127.6 +----------------------------------------------------------------------
   127.7 +
   127.8 +Copyright (c) 2006-2010, assimp team
   127.9 +All rights reserved.
  127.10 +
  127.11 +Redistribution and use of this software in source and binary forms, 
  127.12 +with or without modification, are permitted provided that the 
  127.13 +following conditions are met:
  127.14 +
  127.15 +* Redistributions of source code must retain the above
  127.16 +  copyright notice, this list of conditions and the
  127.17 +  following disclaimer.
  127.18 +
  127.19 +* Redistributions in binary form must reproduce the above
  127.20 +  copyright notice, this list of conditions and the
  127.21 +  following disclaimer in the documentation and/or other
  127.22 +  materials provided with the distribution.
  127.23 +
  127.24 +* Neither the name of the assimp team, nor the names of its
  127.25 +  contributors may be used to endorse or promote products
  127.26 +  derived from this software without specific prior
  127.27 +  written permission of the assimp team.
  127.28 +
  127.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  127.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  127.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  127.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  127.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  127.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  127.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  127.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  127.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  127.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  127.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  127.40 +
  127.41 +----------------------------------------------------------------------
  127.42 +*/
  127.43 +
  127.44 +/** @file  IFCGeometry.cpp
  127.45 + *  @brief Geometry conversion and synthesis for IFC
  127.46 + */
  127.47 +
  127.48 +#include "AssimpPCH.h"
  127.49 +
  127.50 +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
  127.51 +#include "IFCUtil.h"
  127.52 +#include "PolyTools.h"
  127.53 +#include "ProcessHelper.h"
  127.54 +
  127.55 +#include "../contrib/poly2tri/poly2tri/poly2tri.h"
  127.56 +#include "../contrib/clipper/clipper.hpp"
  127.57 +
  127.58 +#include <iterator>
  127.59 +
  127.60 +namespace Assimp {
  127.61 +	namespace IFC {
  127.62 +
  127.63 +// ------------------------------------------------------------------------------------------------
  127.64 +bool ProcessPolyloop(const IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/)
  127.65 +{
  127.66 +	size_t cnt = 0;
  127.67 +	BOOST_FOREACH(const IfcCartesianPoint& c, loop.Polygon) {
  127.68 +		IfcVector3 tmp;
  127.69 +		ConvertCartesianPoint(tmp,c);
  127.70 +
  127.71 +		meshout.verts.push_back(tmp);
  127.72 +		++cnt;
  127.73 +	}
  127.74 +
  127.75 +	meshout.vertcnt.push_back(cnt);
  127.76 +
  127.77 +	// zero- or one- vertex polyloops simply ignored
  127.78 +	if (meshout.vertcnt.back() > 1) { 
  127.79 +		return true;
  127.80 +	}
  127.81 +	
  127.82 +	if (meshout.vertcnt.back()==1) {
  127.83 +		meshout.vertcnt.pop_back();
  127.84 +		meshout.verts.pop_back();
  127.85 +	}
  127.86 +	return false;
  127.87 +}
  127.88 +
  127.89 +// ------------------------------------------------------------------------------------------------
  127.90 +void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t master_bounds = (size_t)-1) 
  127.91 +{
  127.92 +	// handle all trivial cases
  127.93 +	if(inmesh.vertcnt.empty()) {
  127.94 +		return;
  127.95 +	}
  127.96 +	if(inmesh.vertcnt.size() == 1) {
  127.97 +		result.Append(inmesh);
  127.98 +		return;
  127.99 +	}
 127.100 +
 127.101 +	ai_assert(std::count(inmesh.vertcnt.begin(), inmesh.vertcnt.end(), 0) == 0);
 127.102 +
 127.103 +	typedef std::vector<unsigned int>::const_iterator face_iter;
 127.104 +
 127.105 +	face_iter begin = inmesh.vertcnt.begin(), end = inmesh.vertcnt.end(), iit;
 127.106 +	std::vector<unsigned int>::const_iterator outer_polygon_it = end;
 127.107 +
 127.108 +	// major task here: given a list of nested polygon boundaries (one of which
 127.109 +	// is the outer contour), reduce the triangulation task arising here to
 127.110 +	// one that can be solved using the "quadrulation" algorithm which we use
 127.111 +	// for pouring windows out of walls. The algorithm does not handle all
 127.112 +	// cases but at least it is numerically stable and gives "nice" triangles.
 127.113 +
 127.114 +	// first compute normals for all polygons using Newell's algorithm
 127.115 +	// do not normalize 'normals', we need the original length for computing the polygon area
 127.116 +	std::vector<IfcVector3> normals;
 127.117 +	inmesh.ComputePolygonNormals(normals,false);
 127.118 +
 127.119 +	// One of the polygons might be a IfcFaceOuterBound (in which case `master_bounds` 
 127.120 +	// is its index). Sadly we can't rely on it, the docs say 'At most one of the bounds 
 127.121 +	// shall be of the type IfcFaceOuterBound' 
 127.122 +	IfcFloat area_outer_polygon = 1e-10f;
 127.123 +	if (master_bounds != (size_t)-1) {
 127.124 +		ai_assert(master_bounds < inmesh.vertcnt.size());
 127.125 +		outer_polygon_it = begin + master_bounds;
 127.126 +	}
 127.127 +	else {
 127.128 +		for(iit = begin; iit != end; iit++) {
 127.129 +			// find the polygon with the largest area and take it as the outer bound. 
 127.130 +			IfcVector3& n = normals[std::distance(begin,iit)];
 127.131 +			const IfcFloat area = n.SquareLength();
 127.132 +			if (area > area_outer_polygon) {
 127.133 +				area_outer_polygon = area;
 127.134 +				outer_polygon_it = iit;
 127.135 +			}
 127.136 +		}
 127.137 +	}
 127.138 +
 127.139 +	ai_assert(outer_polygon_it != end);
 127.140 +
 127.141 +	const size_t outer_polygon_size = *outer_polygon_it;
 127.142 +	const IfcVector3& master_normal = normals[std::distance(begin, outer_polygon_it)];
 127.143 +
 127.144 +	// Generate fake openings to meet the interface for the quadrulate
 127.145 +	// algorithm. It boils down to generating small boxes given the
 127.146 +	// inner polygon and the surface normal of the outer contour.
 127.147 +	// It is important that we use the outer contour's normal because
 127.148 +	// this is the plane onto which the quadrulate algorithm will
 127.149 +	// project the entire mesh.
 127.150 +	std::vector<TempOpening> fake_openings;
 127.151 +	fake_openings.reserve(inmesh.vertcnt.size()-1);
 127.152 +
 127.153 +	std::vector<IfcVector3>::const_iterator vit = inmesh.verts.begin(), outer_vit;
 127.154 +
 127.155 +	for(iit = begin; iit != end; vit += *iit++) {
 127.156 +		if (iit == outer_polygon_it) {
 127.157 +			outer_vit = vit;
 127.158 +			continue;
 127.159 +		}
 127.160 +
 127.161 +		// Filter degenerate polygons to keep them from causing trouble later on
 127.162 +		IfcVector3& n = normals[std::distance(begin,iit)];
 127.163 +		const IfcFloat area = n.SquareLength();
 127.164 +		if (area < 1e-5f) {
 127.165 +			IFCImporter::LogWarn("skipping degenerate polygon (ProcessPolygonBoundaries)");
 127.166 +			continue;
 127.167 +		}
 127.168 +
 127.169 +		fake_openings.push_back(TempOpening());
 127.170 +		TempOpening& opening = fake_openings.back();
 127.171 +
 127.172 +		opening.extrusionDir = master_normal;
 127.173 +		opening.solid = NULL;
 127.174 +
 127.175 +		opening.profileMesh = boost::make_shared<TempMesh>();
 127.176 +		opening.profileMesh->verts.reserve(*iit);
 127.177 +		opening.profileMesh->vertcnt.push_back(*iit);
 127.178 +
 127.179 +		std::copy(vit, vit + *iit, std::back_inserter(opening.profileMesh->verts)); 
 127.180 +	}
 127.181 +
 127.182 +	// fill a mesh with ONLY the main polygon 
 127.183 +	TempMesh temp;
 127.184 +	temp.verts.reserve(outer_polygon_size);
 127.185 +	temp.vertcnt.push_back(outer_polygon_size);
 127.186 +	std::copy(outer_vit, outer_vit+outer_polygon_size,
 127.187 +		std::back_inserter(temp.verts));
 127.188 +
 127.189 +	GenerateOpenings(fake_openings, normals, temp, false, false);
 127.190 +	result.Append(temp);
 127.191 +}
 127.192 +
 127.193 +// ------------------------------------------------------------------------------------------------
 127.194 +void ProcessConnectedFaceSet(const IfcConnectedFaceSet& fset, TempMesh& result, ConversionData& conv)
 127.195 +{
 127.196 +	BOOST_FOREACH(const IfcFace& face, fset.CfsFaces) {
 127.197 +		// size_t ob = -1, cnt = 0;
 127.198 +		TempMesh meshout;
 127.199 +		BOOST_FOREACH(const IfcFaceBound& bound, face.Bounds) {
 127.200 +			
 127.201 +			if(const IfcPolyLoop* const polyloop = bound.Bound->ToPtr<IfcPolyLoop>()) {
 127.202 +				if(ProcessPolyloop(*polyloop, meshout,conv)) {
 127.203 +
 127.204 +					// The outer boundary is better determined by checking which
 127.205 +					// polygon covers the largest area.
 127.206 +
 127.207 +					//if(bound.ToPtr<IfcFaceOuterBound>()) {
 127.208 +					//	ob = cnt;
 127.209 +					//}
 127.210 +					//++cnt;
 127.211 +
 127.212 +				}
 127.213 +			}
 127.214 +			else {
 127.215 +				IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is " + bound.Bound->GetClassName());
 127.216 +				continue;
 127.217 +			}
 127.218 +
 127.219 +			// And this, even though it is sometimes TRUE and sometimes FALSE,
 127.220 +			// does not really improve results.
 127.221 +
 127.222 +			/*if(!IsTrue(bound.Orientation)) {
 127.223 +				size_t c = 0;
 127.224 +				BOOST_FOREACH(unsigned int& c, meshout.vertcnt) {
 127.225 +					std::reverse(result.verts.begin() + cnt,result.verts.begin() + cnt + c);
 127.226 +					cnt += c;
 127.227 +				}
 127.228 +			}*/
 127.229 +		}
 127.230 +		ProcessPolygonBoundaries(result, meshout);
 127.231 +	}
 127.232 +}
 127.233 +
 127.234 +// ------------------------------------------------------------------------------------------------
 127.235 +void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv)
 127.236 +{
 127.237 +	TempMesh meshout;
 127.238 +
 127.239 +	// first read the profile description
 127.240 +	if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) {
 127.241 +		return;
 127.242 +	}
 127.243 +
 127.244 +	IfcVector3 axis, pos;
 127.245 +	ConvertAxisPlacement(axis,pos,solid.Axis);
 127.246 +
 127.247 +	IfcMatrix4 tb0,tb1;
 127.248 +	IfcMatrix4::Translation(pos,tb0);
 127.249 +	IfcMatrix4::Translation(-pos,tb1);
 127.250 +
 127.251 +	const std::vector<IfcVector3>& in = meshout.verts;
 127.252 +	const size_t size=in.size();
 127.253 +	
 127.254 +	bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2;
 127.255 +	const IfcFloat max_angle = solid.Angle*conv.angle_scale;
 127.256 +	if(fabs(max_angle) < 1e-3) {
 127.257 +		if(has_area) {
 127.258 +			result = meshout;
 127.259 +		}
 127.260 +		return;
 127.261 +	}
 127.262 +
 127.263 +	const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(16 * fabs(max_angle)/AI_MATH_HALF_PI_F));
 127.264 +	const IfcFloat delta = max_angle/cnt_segments;
 127.265 +
 127.266 +	has_area = has_area && fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;
 127.267 +	
 127.268 +	result.verts.reserve(size*((cnt_segments+1)*4+(has_area?2:0)));
 127.269 +	result.vertcnt.reserve(size*cnt_segments+2);
 127.270 +
 127.271 +	IfcMatrix4 rot;
 127.272 +	rot = tb0 * IfcMatrix4::Rotation(delta,axis,rot) * tb1;
 127.273 +
 127.274 +	size_t base = 0;
 127.275 +	std::vector<IfcVector3>& out = result.verts;
 127.276 +
 127.277 +	// dummy data to simplify later processing
 127.278 +	for(size_t i = 0; i < size; ++i) {
 127.279 +		out.insert(out.end(),4,in[i]);
 127.280 +	}
 127.281 +
 127.282 +	for(unsigned int seg = 0; seg < cnt_segments; ++seg) {
 127.283 +		for(size_t i = 0; i < size; ++i) {
 127.284 +			const size_t next = (i+1)%size;
 127.285 +
 127.286 +			result.vertcnt.push_back(4);
 127.287 +			const IfcVector3& base_0 = out[base+i*4+3],base_1 = out[base+next*4+3];
 127.288 +
 127.289 +			out.push_back(base_0);
 127.290 +			out.push_back(base_1);
 127.291 +			out.push_back(rot*base_1);
 127.292 +			out.push_back(rot*base_0);
 127.293 +		}
 127.294 +		base += size*4;
 127.295 +	}
 127.296 +
 127.297 +	out.erase(out.begin(),out.begin()+size*4);
 127.298 +
 127.299 +	if(has_area) {
 127.300 +		// leave the triangulation of the profile area to the ear cutting 
 127.301 +		// implementation in aiProcess_Triangulate - for now we just
 127.302 +		// feed in two huge polygons.
 127.303 +		base -= size*8;
 127.304 +		for(size_t i = size; i--; ) {
 127.305 +			out.push_back(out[base+i*4+3]);
 127.306 +		}
 127.307 +		for(size_t i = 0; i < size; ++i ) {
 127.308 +			out.push_back(out[i*4]);
 127.309 +		}
 127.310 +		result.vertcnt.push_back(size);
 127.311 +		result.vertcnt.push_back(size);
 127.312 +	}
 127.313 +
 127.314 +	IfcMatrix4 trafo;
 127.315 +	ConvertAxisPlacement(trafo, solid.Position);
 127.316 +	
 127.317 +	result.Transform(trafo);
 127.318 +	IFCImporter::LogDebug("generate mesh procedurally by radial extrusion (IfcRevolvedAreaSolid)");
 127.319 +}
 127.320 +
 127.321 +
 127.322 +
 127.323 +// ------------------------------------------------------------------------------------------------
 127.324 +void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, ConversionData& conv)
 127.325 +{
 127.326 +	const Curve* const curve = Curve::Convert(*solid.Directrix, conv);
 127.327 +	if(!curve) {
 127.328 +		IFCImporter::LogError("failed to convert Directrix curve (IfcSweptDiskSolid)");
 127.329 +		return;
 127.330 +	}
 127.331 +
 127.332 +	const std::vector<IfcVector3>& in = result.verts;
 127.333 +	
 127.334 +	const unsigned int cnt_segments = 16;
 127.335 +	const IfcFloat deltaAngle = AI_MATH_TWO_PI/cnt_segments;
 127.336 +
 127.337 +	const size_t samples = curve->EstimateSampleCount(solid.StartParam,solid.EndParam);
 127.338 +
 127.339 +	result.verts.reserve(cnt_segments * samples * 4);
 127.340 +	result.vertcnt.reserve((cnt_segments - 1) * samples);
 127.341 +
 127.342 +	std::vector<IfcVector3> points;
 127.343 +	points.reserve(cnt_segments * samples);
 127.344 +
 127.345 +	TempMesh temp;
 127.346 +	curve->SampleDiscrete(temp,solid.StartParam,solid.EndParam);
 127.347 +	const std::vector<IfcVector3>& curve_points = temp.verts;
 127.348 +
 127.349 +	if(curve_points.empty()) {
 127.350 +		IFCImporter::LogWarn("curve evaluation yielded no points (IfcSweptDiskSolid)");
 127.351 +		return;
 127.352 +	}
 127.353 +
 127.354 +	IfcVector3 current = curve_points[0];
 127.355 +	IfcVector3 previous = current;
 127.356 +	IfcVector3 next;
 127.357 +
 127.358 +	IfcVector3 startvec;
 127.359 +	startvec.x = 1.0f;
 127.360 +	startvec.y = 1.0f;
 127.361 +	startvec.z = 1.0f;
 127.362 +
 127.363 +	unsigned int last_dir = 0;
 127.364 +
 127.365 +	// generate circles at the sweep positions
 127.366 +	for(size_t i = 0; i < samples; ++i) {
 127.367 +
 127.368 +		if(i != samples - 1) {
 127.369 +			next = curve_points[i + 1];
 127.370 +		}
 127.371 +
 127.372 +		// get a direction vector reflecting the approximate curvature (i.e. tangent)
 127.373 +		IfcVector3 d = (current-previous) + (next-previous);
 127.374 +	
 127.375 +		d.Normalize();
 127.376 +
 127.377 +		// figure out an arbitrary point q so that (p-q) * d = 0,
 127.378 +		// try to maximize ||(p-q)|| * ||(p_last-q_last)|| 
 127.379 +		IfcVector3 q;
 127.380 +		bool take_any = false;
 127.381 +
 127.382 +		for (unsigned int i = 0; i < 2; ++i, take_any = true) {
 127.383 +			if ((last_dir == 0 || take_any) && abs(d.x) > 1e-6) {
 127.384 +				q.y = startvec.y;
 127.385 +				q.z = startvec.z;
 127.386 +				q.x = -(d.y * q.y + d.z * q.z) / d.x;
 127.387 +				last_dir = 0;
 127.388 +				break;
 127.389 +			}
 127.390 +			else if ((last_dir == 1 || take_any) && abs(d.y) > 1e-6) {
 127.391 +				q.x = startvec.x;
 127.392 +				q.z = startvec.z;
 127.393 +				q.y = -(d.x * q.x + d.z * q.z) / d.y;
 127.394 +				last_dir = 1;
 127.395 +				break;
 127.396 +			}
 127.397 +			else if ((last_dir == 2 && abs(d.z) > 1e-6) || take_any) { 
 127.398 +				q.y = startvec.y;
 127.399 +				q.x = startvec.x;
 127.400 +				q.z = -(d.y * q.y + d.x * q.x) / d.z;
 127.401 +				last_dir = 2;
 127.402 +				break;
 127.403 +			}
 127.404 +		}
 127.405 +
 127.406 +		q *= solid.Radius / q.Length();
 127.407 +		startvec = q;
 127.408 +
 127.409 +		// generate a rotation matrix to rotate q around d
 127.410 +		IfcMatrix4 rot;
 127.411 +		IfcMatrix4::Rotation(deltaAngle,d,rot);
 127.412 +
 127.413 +		for (unsigned int seg = 0; seg < cnt_segments; ++seg, q *= rot ) {
 127.414 +			points.push_back(q + current);	
 127.415 +		}
 127.416 +
 127.417 +		previous = current;
 127.418 +		current = next;
 127.419 +	}
 127.420 +
 127.421 +	// make quads
 127.422 +	for(size_t i = 0; i < samples - 1; ++i) {
 127.423 +
 127.424 +		const aiVector3D& this_start = points[ i * cnt_segments ];
 127.425 +
 127.426 +		// locate corresponding point on next sample ring
 127.427 +		unsigned int best_pair_offset = 0;
 127.428 +		float best_distance_squared = 1e10f;
 127.429 +		for (unsigned int seg = 0; seg < cnt_segments; ++seg) {
 127.430 +			const aiVector3D& p = points[ (i+1) * cnt_segments + seg];
 127.431 +			const float l = (p-this_start).SquareLength();
 127.432 +
 127.433 +			if(l < best_distance_squared) {
 127.434 +				best_pair_offset = seg;
 127.435 +				best_distance_squared = l;
 127.436 +			}
 127.437 +		}
 127.438 +
 127.439 +		for (unsigned int seg = 0; seg < cnt_segments; ++seg) {
 127.440 +
 127.441 +			result.verts.push_back(points[ i * cnt_segments + (seg % cnt_segments)]);
 127.442 +			result.verts.push_back(points[ i * cnt_segments + (seg + 1) % cnt_segments]);
 127.443 +			result.verts.push_back(points[ (i+1) * cnt_segments + ((seg + 1 + best_pair_offset) % cnt_segments)]);
 127.444 +			result.verts.push_back(points[ (i+1) * cnt_segments + ((seg + best_pair_offset) % cnt_segments)]);
 127.445 +
 127.446 +			IfcVector3& v1 = *(result.verts.end()-1);
 127.447 +			IfcVector3& v2 = *(result.verts.end()-2);
 127.448 +			IfcVector3& v3 = *(result.verts.end()-3);
 127.449 +			IfcVector3& v4 = *(result.verts.end()-4);
 127.450 +
 127.451 +			if (((v4-v3) ^ (v4-v1)) * (v4 - curve_points[i]) < 0.0f) {			
 127.452 +				std::swap(v4, v1);
 127.453 +				std::swap(v3, v2);
 127.454 +			} 
 127.455 +
 127.456 +			result.vertcnt.push_back(4);
 127.457 +		}
 127.458 +	}
 127.459 +
 127.460 +	IFCImporter::LogDebug("generate mesh procedurally by sweeping a disk along a curve (IfcSweptDiskSolid)");
 127.461 +}
 127.462 +
 127.463 +// ------------------------------------------------------------------------------------------------
 127.464 +IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut) 
 127.465 +{
 127.466 +	const std::vector<IfcVector3>& out = curmesh.verts;
 127.467 +	IfcMatrix3 m;
 127.468 +
 127.469 +	ok = true;
 127.470 +
 127.471 +	// The input "mesh" must be a single polygon
 127.472 +	const size_t s = out.size();
 127.473 +	assert(curmesh.vertcnt.size() == 1 && curmesh.vertcnt.back() == s);
 127.474 +
 127.475 +	const IfcVector3 any_point = out[s-1];
 127.476 +	IfcVector3 nor; 
 127.477 +
 127.478 +	// The input polygon is arbitrarily shaped, therefore we might need some tries
 127.479 +	// until we find a suitable normal. Note that Newell's algorithm would give
 127.480 +	// a more robust result, but this variant also gives us a suitable first
 127.481 +	// axis for the 2D coordinate space on the polygon plane, exploiting the
 127.482 +	// fact that the input polygon is nearly always a quad.
 127.483 +	bool done = false;
 127.484 +	size_t i, j;
 127.485 +	for (i = 0; !done && i < s-2; done || ++i) {
 127.486 +		for (j = i+1; j < s-1; ++j) {
 127.487 +			nor = -((out[i]-any_point)^(out[j]-any_point));
 127.488 +			if(fabs(nor.Length()) > 1e-8f) {
 127.489 +				done = true;
 127.490 +				break;
 127.491 +			}
 127.492 +		}
 127.493 +	}
 127.494 +
 127.495 +	if(!done) {
 127.496 +		ok = false;
 127.497 +		return m;
 127.498 +	}
 127.499 +
 127.500 +	nor.Normalize();
 127.501 +	norOut = nor;
 127.502 +
 127.503 +	IfcVector3 r = (out[i]-any_point);
 127.504 +	r.Normalize();
 127.505 +
 127.506 +	//if(d) {
 127.507 +	//	*d = -any_point * nor;
 127.508 +	//}
 127.509 +
 127.510 +	// Reconstruct orthonormal basis
 127.511 +	// XXX use Gram Schmidt for increased robustness
 127.512 +	IfcVector3 u = r ^ nor;
 127.513 +	u.Normalize();
 127.514 +
 127.515 +	m.a1 = r.x;
 127.516 +	m.a2 = r.y;
 127.517 +	m.a3 = r.z;
 127.518 +
 127.519 +	m.b1 = u.x;
 127.520 +	m.b2 = u.y;
 127.521 +	m.b3 = u.z;
 127.522 +
 127.523 +	m.c1 = -nor.x;
 127.524 +	m.c2 = -nor.y;
 127.525 +	m.c3 = -nor.z;
 127.526 +
 127.527 +	return m;
 127.528 +}
 127.529 +
 127.530 +
 127.531 +// ------------------------------------------------------------------------------------------------
 127.532 +void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result, 
 127.533 +	ConversionData& conv, bool collect_openings)
 127.534 +{
 127.535 +	TempMesh meshout;
 127.536 +	
 127.537 +	// First read the profile description
 127.538 +	if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) {
 127.539 +		return;
 127.540 +	}
 127.541 +
 127.542 +	IfcVector3 dir;
 127.543 +	ConvertDirection(dir,solid.ExtrudedDirection);
 127.544 +
 127.545 +	dir *= solid.Depth; /*
 127.546 +	if(conv.collect_openings && !conv.apply_openings) {
 127.547 +		dir *= 1000.0;
 127.548 +	} */
 127.549 +
 127.550 +	// Outline: assuming that `meshout.verts` is now a list of vertex points forming 
 127.551 +	// the underlying profile, extrude along the given axis, forming new
 127.552 +	// triangles.
 127.553 +	
 127.554 +	std::vector<IfcVector3>& in = meshout.verts;
 127.555 +	const size_t size=in.size();
 127.556 +
 127.557 +	const bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2;
 127.558 +	if(solid.Depth < 1e-6) {
 127.559 +		if(has_area) {
 127.560 +			result = meshout;
 127.561 +		}
 127.562 +		return;
 127.563 +	}
 127.564 +
 127.565 +	result.verts.reserve(size*(has_area?4:2));
 127.566 +	result.vertcnt.reserve(meshout.vertcnt.size()+2);
 127.567 +
 127.568 +	// First step: transform all vertices into the target coordinate space
 127.569 +	IfcMatrix4 trafo;
 127.570 +	ConvertAxisPlacement(trafo, solid.Position);
 127.571 +
 127.572 +	IfcVector3 vmin, vmax;
 127.573 +	MinMaxChooser<IfcVector3>()(vmin, vmax);
 127.574 +	BOOST_FOREACH(IfcVector3& v,in) {
 127.575 +		v *= trafo;
 127.576 +
 127.577 +		vmin = std::min(vmin, v);
 127.578 +		vmax = std::max(vmax, v);
 127.579 +	}
 127.580 +
 127.581 +	vmax -= vmin;
 127.582 +	const IfcFloat diag = vmax.Length();
 127.583 +	
 127.584 +	IfcVector3 min = in[0];
 127.585 +	dir *= IfcMatrix3(trafo);
 127.586 +
 127.587 +	std::vector<IfcVector3> nors;
 127.588 +	const bool openings = !!conv.apply_openings && conv.apply_openings->size();
 127.589 +	
 127.590 +	// Compute the normal vectors for all opening polygons as a prerequisite
 127.591 +	// to TryAddOpenings_Poly2Tri()
 127.592 +	// XXX this belongs into the aforementioned function
 127.593 +	if (openings) {
 127.594 +
 127.595 +		if (!conv.settings.useCustomTriangulation) {	         
 127.596 +			// it is essential to apply the openings in the correct spatial order. The direction	 
 127.597 +			// doesn't matter, but we would screw up if we started with e.g. a door in between	 
 127.598 +			// two windows.	 
 127.599 +			std::sort(conv.apply_openings->begin(),conv.apply_openings->end(),
 127.600 +				TempOpening::DistanceSorter(min));	 
 127.601 +		}
 127.602 +	
 127.603 +		nors.reserve(conv.apply_openings->size());
 127.604 +		BOOST_FOREACH(TempOpening& t,*conv.apply_openings) {
 127.605 +			TempMesh& bounds = *t.profileMesh.get();
 127.606 +		
 127.607 +			if (bounds.verts.size() <= 2) {
 127.608 +				nors.push_back(IfcVector3());
 127.609 +				continue;
 127.610 +			}
 127.611 +			nors.push_back(((bounds.verts[2]-bounds.verts[0])^(bounds.verts[1]-bounds.verts[0]) ).Normalize());
 127.612 +		}
 127.613 +	}
 127.614 +	
 127.615 +
 127.616 +	TempMesh temp;
 127.617 +	TempMesh& curmesh = openings ? temp : result;
 127.618 +	std::vector<IfcVector3>& out = curmesh.verts;
 127.619 + 
 127.620 +	size_t sides_with_openings = 0;
 127.621 +	for(size_t i = 0; i < size; ++i) {
 127.622 +		const size_t next = (i+1)%size;
 127.623 +
 127.624 +		curmesh.vertcnt.push_back(4);
 127.625 +		
 127.626 +		out.push_back(in[i]);
 127.627 +		out.push_back(in[i]+dir);
 127.628 +		out.push_back(in[next]+dir);
 127.629 +		out.push_back(in[next]);
 127.630 +
 127.631 +		if(openings) {
 127.632 +			if((in[i]-in[next]).Length() > diag * 0.1 && GenerateOpenings(*conv.apply_openings,nors,temp,true, true, dir)) {
 127.633 +				++sides_with_openings;
 127.634 +			}
 127.635 +			
 127.636 +			result.Append(temp);
 127.637 +			temp.Clear();
 127.638 +		}
 127.639 +	}
 127.640 +
 127.641 +	if(openings) {
 127.642 +		BOOST_FOREACH(TempOpening& opening, *conv.apply_openings) {
 127.643 +			if (!opening.wallPoints.empty()) {
 127.644 +				IFCImporter::LogError("failed to generate all window caps");
 127.645 +			}
 127.646 +			opening.wallPoints.clear();
 127.647 +		}
 127.648 +	}
 127.649 +	
 127.650 +	size_t sides_with_v_openings = 0;
 127.651 +	if(has_area) {
 127.652 +
 127.653 +		for(size_t n = 0; n < 2; ++n) {
 127.654 +			for(size_t i = size; i--; ) {
 127.655 +				out.push_back(in[i]+(n?dir:IfcVector3()));
 127.656 +			}
 127.657 +
 127.658 +			curmesh.vertcnt.push_back(size);
 127.659 +			if(openings && size > 2) {
 127.660 +				if(GenerateOpenings(*conv.apply_openings,nors,temp,true, true, dir)) {
 127.661 +					++sides_with_v_openings;
 127.662 +				}
 127.663 +
 127.664 +				result.Append(temp);
 127.665 +				temp.Clear();
 127.666 +			}
 127.667 +		}
 127.668 +	}
 127.669 +
 127.670 +	if(openings && ((sides_with_openings == 1 && sides_with_openings) || (sides_with_v_openings == 2 && sides_with_v_openings))) {
 127.671 +		IFCImporter::LogWarn("failed to resolve all openings, presumably their topology is not supported by Assimp");
 127.672 +	}
 127.673 +
 127.674 +	IFCImporter::LogDebug("generate mesh procedurally by extrusion (IfcExtrudedAreaSolid)");
 127.675 +
 127.676 +	// If this is an opening element, store both the extruded mesh and the 2D profile mesh
 127.677 +	// it was created from. Return an empty mesh to the caller.
 127.678 +	if(collect_openings && !result.IsEmpty()) {
 127.679 +		ai_assert(conv.collect_openings);
 127.680 +		boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh());
 127.681 +		profile->Swap(result);
 127.682 +
 127.683 +		boost::shared_ptr<TempMesh> profile2D = boost::shared_ptr<TempMesh>(new TempMesh());
 127.684 +		profile2D->Swap(meshout);
 127.685 +		conv.collect_openings->push_back(TempOpening(&solid,dir,profile, profile2D));
 127.686 +
 127.687 +		ai_assert(result.IsEmpty());
 127.688 +	} 
 127.689 +}
 127.690 +
 127.691 +// ------------------------------------------------------------------------------------------------
 127.692 +void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout, 
 127.693 +	ConversionData& conv)
 127.694 +{
 127.695 +	if(const IfcExtrudedAreaSolid* const solid = swept.ToPtr<IfcExtrudedAreaSolid>()) {
 127.696 +		ProcessExtrudedAreaSolid(*solid,meshout,conv, !!conv.collect_openings);
 127.697 +	}
 127.698 +	else if(const IfcRevolvedAreaSolid* const rev = swept.ToPtr<IfcRevolvedAreaSolid>()) {
 127.699 +		ProcessRevolvedAreaSolid(*rev,meshout,conv);
 127.700 +	}
 127.701 +	else {
 127.702 +		IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is " + swept.GetClassName());
 127.703 +	}
 127.704 +}
 127.705 +
 127.706 +// ------------------------------------------------------------------------------------------------
 127.707 +bool ProcessGeometricItem(const IfcRepresentationItem& geo, std::vector<unsigned int>& mesh_indices, 
 127.708 +	ConversionData& conv)
 127.709 +{
 127.710 +	bool fix_orientation = true;
 127.711 +	boost::shared_ptr< TempMesh > meshtmp = boost::make_shared<TempMesh>(); 
 127.712 +	if(const IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<IfcShellBasedSurfaceModel>()) {
 127.713 +		BOOST_FOREACH(boost::shared_ptr<const IfcShell> shell,shellmod->SbsmBoundary) {
 127.714 +			try {
 127.715 +				const EXPRESS::ENTITY& e = shell->To<ENTITY>();
 127.716 +				const IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<IfcConnectedFaceSet>(); 
 127.717 +
 127.718 +				ProcessConnectedFaceSet(fs,*meshtmp.get(),conv);
 127.719 +			}
 127.720 +			catch(std::bad_cast&) {
 127.721 +				IFCImporter::LogWarn("unexpected type error, IfcShell ought to inherit from IfcConnectedFaceSet");
 127.722 +			}
 127.723 +		}
 127.724 +	}
 127.725 +	else  if(const IfcConnectedFaceSet* fset = geo.ToPtr<IfcConnectedFaceSet>()) {
 127.726 +		ProcessConnectedFaceSet(*fset,*meshtmp.get(),conv);
 127.727 +	}	
 127.728 +	else  if(const IfcSweptAreaSolid* swept = geo.ToPtr<IfcSweptAreaSolid>()) {
 127.729 +		ProcessSweptAreaSolid(*swept,*meshtmp.get(),conv);
 127.730 +	}   
 127.731 +	else  if(const IfcSweptDiskSolid* disk = geo.ToPtr<IfcSweptDiskSolid>()) {
 127.732 +		ProcessSweptDiskSolid(*disk,*meshtmp.get(),conv);
 127.733 +		fix_orientation = false;
 127.734 +	}   
 127.735 +	else if(const IfcManifoldSolidBrep* brep = geo.ToPtr<IfcManifoldSolidBrep>()) {
 127.736 +		ProcessConnectedFaceSet(brep->Outer,*meshtmp.get(),conv);
 127.737 +	} 
 127.738 +	else if(const IfcFaceBasedSurfaceModel* surf = geo.ToPtr<IfcFaceBasedSurfaceModel>()) {
 127.739 +		BOOST_FOREACH(const IfcConnectedFaceSet& fc, surf->FbsmFaces) {
 127.740 +			ProcessConnectedFaceSet(fc,*meshtmp.get(),conv);
 127.741 +		}
 127.742 +	}  
 127.743 +	else  if(const IfcBooleanResult* boolean = geo.ToPtr<IfcBooleanResult>()) {
 127.744 +		ProcessBoolean(*boolean,*meshtmp.get(),conv);
 127.745 +	}
 127.746 +	else if(geo.ToPtr<IfcBoundingBox>()) {
 127.747 +		// silently skip over bounding boxes
 127.748 +		return false; 
 127.749 +	} 
 127.750 +	else {
 127.751 +		IFCImporter::LogWarn("skipping unknown IfcGeometricRepresentationItem entity, type is " + geo.GetClassName());
 127.752 +		return false;
 127.753 +	}
 127.754 +
 127.755 +	// Do we just collect openings for a parent element (i.e. a wall)? 
 127.756 +	// In such a case, we generate the polygonal mesh as usual,
 127.757 +	// but attach it to a TempOpening instance which will later be applied
 127.758 +	// to the wall it pertains to.
 127.759 +
 127.760 +	// Note: swep area solids are added in ProcessExtrudedAreaSolid(),
 127.761 +	// which returns an empty mesh.
 127.762 +	if(conv.collect_openings) {
 127.763 +		if (!meshtmp->IsEmpty()) {
 127.764 +			conv.collect_openings->push_back(TempOpening(geo.ToPtr<IfcSolidModel>(),
 127.765 +				IfcVector3(0,0,0),
 127.766 +				meshtmp,
 127.767 +				boost::shared_ptr<TempMesh>()));
 127.768 +		}
 127.769 +		return true;
 127.770 +	} 
 127.771 +
 127.772 +	if (meshtmp->IsEmpty()) {
 127.773 +		return false;
 127.774 +	}
 127.775 +
 127.776 +	meshtmp->RemoveAdjacentDuplicates();
 127.777 +	meshtmp->RemoveDegenerates();
 127.778 +
 127.779 +	if(fix_orientation) {
 127.780 +		meshtmp->FixupFaceOrientation();
 127.781 +	}
 127.782 +
 127.783 +	aiMesh* const mesh = meshtmp->ToMesh();
 127.784 +	if(mesh) {
 127.785 +		mesh->mMaterialIndex = ProcessMaterials(geo,conv);
 127.786 +		mesh_indices.push_back(conv.meshes.size());
 127.787 +		conv.meshes.push_back(mesh);
 127.788 +		return true;
 127.789 +	}
 127.790 +	return false;
 127.791 +}
 127.792 +
 127.793 +// ------------------------------------------------------------------------------------------------
 127.794 +void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,
 127.795 +	ConversionData& /*conv*/)
 127.796 +{
 127.797 +	if (!mesh_indices.empty()) {
 127.798 +
 127.799 +		// make unique
 127.800 +		std::sort(mesh_indices.begin(),mesh_indices.end());
 127.801 +		std::vector<unsigned int>::iterator it_end = std::unique(mesh_indices.begin(),mesh_indices.end());
 127.802 +
 127.803 +		const size_t size = std::distance(mesh_indices.begin(),it_end);
 127.804 +
 127.805 +		nd->mNumMeshes = size;
 127.806 +		nd->mMeshes = new unsigned int[nd->mNumMeshes];
 127.807 +		for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
 127.808 +			nd->mMeshes[i] = mesh_indices[i];
 127.809 +		}
 127.810 +	}
 127.811 +}
 127.812 +
 127.813 +// ------------------------------------------------------------------------------------------------
 127.814 +bool TryQueryMeshCache(const IfcRepresentationItem& item, 
 127.815 +	std::vector<unsigned int>& mesh_indices, 
 127.816 +	ConversionData& conv) 
 127.817 +{
 127.818 +	ConversionData::MeshCache::const_iterator it = conv.cached_meshes.find(&item);
 127.819 +	if (it != conv.cached_meshes.end()) {
 127.820 +		std::copy((*it).second.begin(),(*it).second.end(),std::back_inserter(mesh_indices));
 127.821 +		return true;
 127.822 +	}
 127.823 +	return false;
 127.824 +}
 127.825 +
 127.826 +// ------------------------------------------------------------------------------------------------
 127.827 +void PopulateMeshCache(const IfcRepresentationItem& item, 
 127.828 +	const std::vector<unsigned int>& mesh_indices, 
 127.829 +	ConversionData& conv)
 127.830 +{
 127.831 +	conv.cached_meshes[&item] = mesh_indices;
 127.832 +}
 127.833 +
 127.834 +// ------------------------------------------------------------------------------------------------
 127.835 +bool ProcessRepresentationItem(const IfcRepresentationItem& item, 
 127.836 +	std::vector<unsigned int>& mesh_indices, 
 127.837 +	ConversionData& conv)
 127.838 +{
 127.839 +	if (!TryQueryMeshCache(item,mesh_indices,conv)) {
 127.840 +		if(ProcessGeometricItem(item,mesh_indices,conv)) {
 127.841 +			if(mesh_indices.size()) {
 127.842 +				PopulateMeshCache(item,mesh_indices,conv);
 127.843 +			}
 127.844 +		}
 127.845 +		else return false;
 127.846 +	}
 127.847 +	return true;
 127.848 +}
 127.849 +
 127.850 +
 127.851 +} // ! IFC
 127.852 +} // ! Assimp
 127.853 +
 127.854 +#endif 
   128.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   128.2 +++ b/libs/assimp/IFCLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   128.3 @@ -0,0 +1,979 @@
   128.4 +/*
   128.5 +Open Asset Import Library (assimp)
   128.6 +----------------------------------------------------------------------
   128.7 +
   128.8 +Copyright (c) 2006-2012, assimp team
   128.9 +All rights reserved.
  128.10 +
  128.11 +Redistribution and use of this software in source and binary forms, 
  128.12 +with or without modification, are permitted provided that the 
  128.13 +following conditions are met:
  128.14 +
  128.15 +* Redistributions of source code must retain the above
  128.16 +  copyright notice, this list of conditions and the
  128.17 +  following disclaimer.
  128.18 +
  128.19 +* Redistributions in binary form must reproduce the above
  128.20 +  copyright notice, this list of conditions and the
  128.21 +  following disclaimer in the documentation and/or other
  128.22 +  materials provided with the distribution.
  128.23 +
  128.24 +* Neither the name of the assimp team, nor the names of its
  128.25 +  contributors may be used to endorse or promote products
  128.26 +  derived from this software without specific prior
  128.27 +  written permission of the assimp team.
  128.28 +
  128.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  128.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  128.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  128.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  128.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  128.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  128.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  128.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  128.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  128.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  128.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  128.40 +
  128.41 +----------------------------------------------------------------------
  128.42 +*/
  128.43 +
  128.44 +/** @file  IFCLoad.cpp
  128.45 + *  @brief Implementation of the Industry Foundation Classes loader.
  128.46 + */
  128.47 +#include "AssimpPCH.h"
  128.48 +
  128.49 +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
  128.50 +
  128.51 +#include <iterator>
  128.52 +#include <boost/tuple/tuple.hpp>
  128.53 +
  128.54 +#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
  128.55 +#	include "../contrib/unzip/unzip.h"
  128.56 +#endif
  128.57 +
  128.58 +#include "IFCLoader.h"
  128.59 +#include "STEPFileReader.h"
  128.60 +
  128.61 +#include "IFCUtil.h"
  128.62 +
  128.63 +#include "StreamReader.h"
  128.64 +#include "MemoryIOWrapper.h"
  128.65 +
  128.66 +namespace Assimp {
  128.67 +	template<> const std::string LogFunctions<IFCImporter>::log_prefix = "IFC: ";
  128.68 +}
  128.69 +
  128.70 +using namespace Assimp;
  128.71 +using namespace Assimp::Formatter;
  128.72 +using namespace Assimp::IFC;
  128.73 +
  128.74 +/* DO NOT REMOVE this comment block. The genentitylist.sh script
  128.75 + * just looks for names adhering to the IfcSomething naming scheme
  128.76 + * and includes all matches in the whitelist for code-generation. Thus,
  128.77 + * all entity classes that are only indirectly referenced need to be
  128.78 + * mentioned explicitly.
  128.79 +
  128.80 +  IfcRepresentationMap
  128.81 +  IfcProductRepresentation
  128.82 +  IfcUnitAssignment
  128.83 +  IfcClosedShell
  128.84 +  IfcDoor
  128.85 +
  128.86 + */
  128.87 +
  128.88 +namespace {
  128.89 +
  128.90 +
  128.91 +// forward declarations
  128.92 +void SetUnits(ConversionData& conv);
  128.93 +void SetCoordinateSpace(ConversionData& conv);
  128.94 +void ProcessSpatialStructures(ConversionData& conv);
  128.95 +aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el ,ConversionData& conv);
  128.96 +void ProcessProductRepresentation(const IfcProduct& el, aiNode* nd, ConversionData& conv);
  128.97 +void MakeTreeRelative(ConversionData& conv);
  128.98 +void ConvertUnit(const EXPRESS::DataType& dt,ConversionData& conv);
  128.99 +
 128.100 +} // anon
 128.101 +
 128.102 +static const aiImporterDesc desc = {
 128.103 +	"Industry Foundation Classes (IFC) Importer",
 128.104 +	"",
 128.105 +	"",
 128.106 +	"",
 128.107 +	aiImporterFlags_SupportBinaryFlavour,
 128.108 +	0,
 128.109 +	0,
 128.110 +	0,
 128.111 +	0,
 128.112 +	"ifc ifczip" 
 128.113 +};
 128.114 +
 128.115 +
 128.116 +// ------------------------------------------------------------------------------------------------
 128.117 +// Constructor to be privately used by Importer
 128.118 +IFCImporter::IFCImporter()
 128.119 +{}
 128.120 +
 128.121 +// ------------------------------------------------------------------------------------------------
 128.122 +// Destructor, private as well 
 128.123 +IFCImporter::~IFCImporter()
 128.124 +{
 128.125 +}
 128.126 +
 128.127 +// ------------------------------------------------------------------------------------------------
 128.128 +// Returns whether the class can handle the format of the given file. 
 128.129 +bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
 128.130 +{
 128.131 +	const std::string& extension = GetExtension(pFile);
 128.132 +	if (extension == "ifc" || extension == "ifczip") {
 128.133 +		return true;
 128.134 +	}
 128.135 +
 128.136 +	else if ((!extension.length() || checkSig) && pIOHandler)	{
 128.137 +		// note: this is the common identification for STEP-encoded files, so
 128.138 +		// it is only unambiguous as long as we don't support any further
 128.139 +		// file formats with STEP as their encoding.
 128.140 +		const char* tokens[] = {"ISO-10303-21"};
 128.141 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
 128.142 +	}
 128.143 +	return false;
 128.144 +}
 128.145 +
 128.146 +// ------------------------------------------------------------------------------------------------
 128.147 +// List all extensions handled by this loader
 128.148 +const aiImporterDesc* IFCImporter::GetInfo () const
 128.149 +{
 128.150 +	return &desc;
 128.151 +}
 128.152 +
 128.153 +
 128.154 +// ------------------------------------------------------------------------------------------------
 128.155 +// Setup configuration properties for the loader
 128.156 +void IFCImporter::SetupProperties(const Importer* pImp)
 128.157 +{
 128.158 +	settings.skipSpaceRepresentations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS,true);
 128.159 +	settings.skipCurveRepresentations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS,true);
 128.160 +	settings.useCustomTriangulation = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION,true);
 128.161 +
 128.162 +	settings.conicSamplingAngle = 10.f;
 128.163 +	settings.skipAnnotations = true;
 128.164 +}
 128.165 +
 128.166 +
 128.167 +// ------------------------------------------------------------------------------------------------
 128.168 +// Imports the given file into the given scene structure. 
 128.169 +void IFCImporter::InternReadFile( const std::string& pFile, 
 128.170 +	aiScene* pScene, IOSystem* pIOHandler)
 128.171 +{
 128.172 +	boost::shared_ptr<IOStream> stream(pIOHandler->Open(pFile));
 128.173 +	if (!stream) {
 128.174 +		ThrowException("Could not open file for reading");
 128.175 +	}
 128.176 +
 128.177 +
 128.178 +	// if this is a ifczip file, decompress its contents first
 128.179 +	if(GetExtension(pFile) == "ifczip") {
 128.180 +#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
 128.181 +		unzFile zip = unzOpen( pFile.c_str() );
 128.182 +		if(zip == NULL) {
 128.183 +			ThrowException("Could not open ifczip file for reading, unzip failed");
 128.184 +		}
 128.185 +
 128.186 +		// chop 'zip' postfix
 128.187 +		std::string fileName = pFile.substr(0,pFile.length() - 3);
 128.188 +
 128.189 +		std::string::size_type s = pFile.find_last_of('\\');
 128.190 +		if(s == std::string::npos) {
 128.191 +			s = pFile.find_last_of('/');
 128.192 +		}
 128.193 +		if(s != std::string::npos) {
 128.194 +			fileName = fileName.substr(s+1);
 128.195 +		}
 128.196 +
 128.197 +		// search file (same name as the IFCZIP except for the file extension) and place file pointer there
 128.198 +		
 128.199 +		if(UNZ_OK == unzGoToFirstFile(zip)) {
 128.200 +			do {
 128.201 +				//
 128.202 +
 128.203 +				// get file size, etc.
 128.204 +				unz_file_info fileInfo;
 128.205 +				char filename[256];
 128.206 +				unzGetCurrentFileInfo( zip , &fileInfo, filename, sizeof(filename), 0, 0, 0, 0 );
 128.207 +				
 128.208 +				if (GetExtension(filename) != "ifc") {
 128.209 +					continue;
 128.210 +				}
 128.211 +
 128.212 +				uint8_t* buff = new uint8_t[fileInfo.uncompressed_size];
 128.213 +
 128.214 +				LogInfo("Decompressing IFCZIP file");
 128.215 +
 128.216 +				unzOpenCurrentFile( zip  );
 128.217 +				const int ret = unzReadCurrentFile( zip, buff, fileInfo.uncompressed_size);
 128.218 +				size_t filesize = fileInfo.uncompressed_size;
 128.219 +				if ( ret < 0 || size_t(ret) != filesize )
 128.220 +				{
 128.221 +					delete[] buff;
 128.222 +					ThrowException("Failed to decompress IFC ZIP file");
 128.223 +				}
 128.224 +				unzCloseCurrentFile( zip );
 128.225 +				stream.reset(new MemoryIOStream(buff,fileInfo.uncompressed_size,true));
 128.226 +				break;
 128.227 +
 128.228 +				if (unzGoToNextFile(zip) == UNZ_END_OF_LIST_OF_FILE) {
 128.229 +					ThrowException("Found no IFC file member in IFCZIP file (1)");
 128.230 +				}
 128.231 +
 128.232 +			} while(true);
 128.233 +		}
 128.234 +		else {
 128.235 +			ThrowException("Found no IFC file member in IFCZIP file (2)");
 128.236 +		}
 128.237 +
 128.238 +		unzClose(zip);
 128.239 +#else
 128.240 +		ThrowException("Could not open ifczip file for reading, assimp was built without ifczip support");
 128.241 +#endif
 128.242 +	}
 128.243 +
 128.244 +	boost::scoped_ptr<STEP::DB> db(STEP::ReadFileHeader(stream));
 128.245 +	const STEP::HeaderInfo& head = static_cast<const STEP::DB&>(*db).GetHeader();
 128.246 +
 128.247 +	if(!head.fileSchema.size() || head.fileSchema.substr(0,3) != "IFC") {
 128.248 +		ThrowException("Unrecognized file schema: " + head.fileSchema);
 128.249 +	}
 128.250 +
 128.251 +	if (!DefaultLogger::isNullLogger()) {
 128.252 +		LogDebug("File schema is \'" + head.fileSchema + '\'');
 128.253 +		if (head.timestamp.length()) {
 128.254 +			LogDebug("Timestamp \'" + head.timestamp + '\'');
 128.255 +		}
 128.256 +		if (head.app.length()) {
 128.257 +			LogDebug("Application/Exporter identline is \'" + head.app  + '\'');
 128.258 +		}
 128.259 +	}
 128.260 +
 128.261 +	// obtain a copy of the machine-generated IFC scheme
 128.262 +	EXPRESS::ConversionSchema schema;
 128.263 +	GetSchema(schema);
 128.264 +
 128.265 +	// tell the reader which entity types to track with special care
 128.266 +	static const char* const types_to_track[] = {
 128.267 +		"ifcsite", "ifcbuilding", "ifcproject"
 128.268 +	};
 128.269 +
 128.270 +	// tell the reader for which types we need to simulate STEPs reverse indices
 128.271 +	static const char* const inverse_indices_to_track[] = {
 128.272 +		"ifcrelcontainedinspatialstructure", "ifcrelaggregates", "ifcrelvoidselement", "ifcreldefinesbyproperties", "ifcpropertyset", "ifcstyleditem"
 128.273 +	};
 128.274 +
 128.275 +	// feed the IFC schema into the reader and pre-parse all lines
 128.276 +	STEP::ReadFile(*db, schema, types_to_track, inverse_indices_to_track);
 128.277 +
 128.278 +	const STEP::LazyObject* proj =  db->GetObject("ifcproject");
 128.279 +	if (!proj) {
 128.280 +		ThrowException("missing IfcProject entity");
 128.281 +	}
 128.282 +
 128.283 +	ConversionData conv(*db,proj->To<IfcProject>(),pScene,settings);
 128.284 +	SetUnits(conv);
 128.285 +	SetCoordinateSpace(conv);
 128.286 +	ProcessSpatialStructures(conv);
 128.287 +	MakeTreeRelative(conv);
 128.288 +
 128.289 +	// NOTE - this is a stress test for the importer, but it works only
 128.290 +	// in a build with no entities disabled. See 
 128.291 +	//     scripts/IFCImporter/CPPGenerator.py
 128.292 +	// for more information.
 128.293 +#ifdef ASSIMP_IFC_TEST
 128.294 +	db->EvaluateAll();
 128.295 +#endif
 128.296 +
 128.297 +	// do final data copying
 128.298 +	if (conv.meshes.size()) {
 128.299 +		pScene->mNumMeshes = static_cast<unsigned int>(conv.meshes.size());
 128.300 +		pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
 128.301 +		std::copy(conv.meshes.begin(),conv.meshes.end(),pScene->mMeshes);
 128.302 +
 128.303 +		// needed to keep the d'tor from burning us
 128.304 +		conv.meshes.clear();
 128.305 +	}
 128.306 +
 128.307 +	if (conv.materials.size()) {
 128.308 +		pScene->mNumMaterials = static_cast<unsigned int>(conv.materials.size());
 128.309 +		pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]();
 128.310 +		std::copy(conv.materials.begin(),conv.materials.end(),pScene->mMaterials);
 128.311 +
 128.312 +		// needed to keep the d'tor from burning us
 128.313 +		conv.materials.clear();
 128.314 +	}
 128.315 +
 128.316 +	// apply world coordinate system (which includes the scaling to convert to meters and a -90 degrees rotation around x)
 128.317 +	aiMatrix4x4 scale, rot;
 128.318 +	aiMatrix4x4::Scaling(static_cast<aiVector3D>(IfcVector3(conv.len_scale)),scale);
 128.319 +	aiMatrix4x4::RotationX(-AI_MATH_HALF_PI_F,rot);
 128.320 +
 128.321 +	pScene->mRootNode->mTransformation = rot * scale * conv.wcs * pScene->mRootNode->mTransformation;
 128.322 +
 128.323 +	// this must be last because objects are evaluated lazily as we process them
 128.324 +	if ( !DefaultLogger::isNullLogger() ){
 128.325 +		LogDebug((Formatter::format(),"STEP: evaluated ",db->GetEvaluatedObjectCount()," object records"));
 128.326 +	}
 128.327 +}
 128.328 +
 128.329 +namespace {
 128.330 +
 128.331 +
 128.332 +// ------------------------------------------------------------------------------------------------
 128.333 +void ConvertUnit(const IfcNamedUnit& unit,ConversionData& conv)
 128.334 +{
 128.335 +	if(const IfcSIUnit* const si = unit.ToPtr<IfcSIUnit>()) {
 128.336 +
 128.337 +		if(si->UnitType == "LENGTHUNIT") { 
 128.338 +			conv.len_scale = si->Prefix ? ConvertSIPrefix(si->Prefix) : 1.f;
 128.339 +			IFCImporter::LogDebug("got units used for lengths");
 128.340 +		}
 128.341 +		if(si->UnitType == "PLANEANGLEUNIT") { 
 128.342 +			if (si->Name != "RADIAN") {
 128.343 +				IFCImporter::LogWarn("expected base unit for angles to be radian");
 128.344 +			}
 128.345 +		}
 128.346 +	}
 128.347 +	else if(const IfcConversionBasedUnit* const convu = unit.ToPtr<IfcConversionBasedUnit>()) {
 128.348 +
 128.349 +		if(convu->UnitType == "PLANEANGLEUNIT") { 
 128.350 +			try {
 128.351 +				conv.angle_scale = convu->ConversionFactor->ValueComponent->To<EXPRESS::REAL>();
 128.352 +				ConvertUnit(*convu->ConversionFactor->UnitComponent,conv);
 128.353 +				IFCImporter::LogDebug("got units used for angles");
 128.354 +			}
 128.355 +			catch(std::bad_cast&) {
 128.356 +				IFCImporter::LogError("skipping unknown IfcConversionBasedUnit.ValueComponent entry - expected REAL");
 128.357 +			}
 128.358 +		}
 128.359 +	}
 128.360 +}
 128.361 +
 128.362 +// ------------------------------------------------------------------------------------------------
 128.363 +void ConvertUnit(const EXPRESS::DataType& dt,ConversionData& conv)
 128.364 +{
 128.365 +	try {
 128.366 +		const EXPRESS::ENTITY& e = dt.To<ENTITY>();
 128.367 +
 128.368 +		const IfcNamedUnit& unit = e.ResolveSelect<IfcNamedUnit>(conv.db);
 128.369 +		if(unit.UnitType != "LENGTHUNIT" && unit.UnitType != "PLANEANGLEUNIT") {
 128.370 +			return;
 128.371 +		}
 128.372 +
 128.373 +		ConvertUnit(unit,conv);
 128.374 +	}
 128.375 +	catch(std::bad_cast&) {
 128.376 +		// not entity, somehow
 128.377 +		IFCImporter::LogError("skipping unknown IfcUnit entry - expected entity");
 128.378 +	}
 128.379 +}
 128.380 +
 128.381 +// ------------------------------------------------------------------------------------------------
 128.382 +void SetUnits(ConversionData& conv)
 128.383 +{
 128.384 +	// see if we can determine the coordinate space used to express. 
 128.385 +	for(size_t i = 0; i <  conv.proj.UnitsInContext->Units.size(); ++i ) {
 128.386 +		ConvertUnit(*conv.proj.UnitsInContext->Units[i],conv);
 128.387 +	}
 128.388 +}
 128.389 +
 128.390 +
 128.391 +// ------------------------------------------------------------------------------------------------
 128.392 +void SetCoordinateSpace(ConversionData& conv)
 128.393 +{
 128.394 +	const IfcRepresentationContext* fav = NULL;
 128.395 +	BOOST_FOREACH(const IfcRepresentationContext& v, conv.proj.RepresentationContexts) {
 128.396 +		fav = &v;
 128.397 +		// Model should be the most suitable type of context, hence ignore the others 
 128.398 +		if (v.ContextType && v.ContextType.Get() == "Model") { 
 128.399 +			break;
 128.400 +		}
 128.401 +	}
 128.402 +	if (fav) {
 128.403 +		if(const IfcGeometricRepresentationContext* const geo = fav->ToPtr<IfcGeometricRepresentationContext>()) {
 128.404 +			ConvertAxisPlacement(conv.wcs, *geo->WorldCoordinateSystem, conv);
 128.405 +			IFCImporter::LogDebug("got world coordinate system");
 128.406 +		}
 128.407 +	}
 128.408 +}
 128.409 +
 128.410 +
 128.411 +// ------------------------------------------------------------------------------------------------
 128.412 +void ResolveObjectPlacement(aiMatrix4x4& m, const IfcObjectPlacement& place, ConversionData& conv)
 128.413 +{
 128.414 +	if (const IfcLocalPlacement* const local = place.ToPtr<IfcLocalPlacement>()){
 128.415 +		IfcMatrix4 tmp;
 128.416 +		ConvertAxisPlacement(tmp, *local->RelativePlacement, conv);
 128.417 +
 128.418 +		m = static_cast<aiMatrix4x4>(tmp);
 128.419 +
 128.420 +		if (local->PlacementRelTo) {
 128.421 +			aiMatrix4x4 tmp;
 128.422 +			ResolveObjectPlacement(tmp,local->PlacementRelTo.Get(),conv);
 128.423 +			m = tmp * m;
 128.424 +		}
 128.425 +	}
 128.426 +	else {
 128.427 +		IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is " + place.GetClassName());
 128.428 +	}
 128.429 +}
 128.430 +
 128.431 +// ------------------------------------------------------------------------------------------------
 128.432 +void GetAbsTransform(aiMatrix4x4& out, const aiNode* nd, ConversionData& conv)
 128.433 +{
 128.434 +	aiMatrix4x4 t;
 128.435 +	if (nd->mParent) {
 128.436 +		GetAbsTransform(t,nd->mParent,conv);
 128.437 +	}
 128.438 +	out = t*nd->mTransformation;
 128.439 +}
 128.440 +
 128.441 +// ------------------------------------------------------------------------------------------------
 128.442 +bool ProcessMappedItem(const IfcMappedItem& mapped, aiNode* nd_src, std::vector< aiNode* >& subnodes_src, ConversionData& conv)
 128.443 +{
 128.444 +	// insert a custom node here, the cartesian transform operator is simply a conventional transformation matrix
 128.445 +	std::auto_ptr<aiNode> nd(new aiNode());
 128.446 +	nd->mName.Set("IfcMappedItem");
 128.447 +		
 128.448 +	// handle the Cartesian operator
 128.449 +	IfcMatrix4 m;
 128.450 +	ConvertTransformOperator(m, *mapped.MappingTarget);
 128.451 +
 128.452 +	IfcMatrix4 msrc;
 128.453 +	ConvertAxisPlacement(msrc,*mapped.MappingSource->MappingOrigin,conv);
 128.454 +
 128.455 +	msrc = m*msrc;
 128.456 +
 128.457 +	std::vector<unsigned int> meshes;
 128.458 +	const size_t old_openings = conv.collect_openings ? conv.collect_openings->size() : 0;
 128.459 +	if (conv.apply_openings) {
 128.460 +		IfcMatrix4 minv = msrc;
 128.461 +		minv.Inverse();
 128.462 +		BOOST_FOREACH(TempOpening& open,*conv.apply_openings){
 128.463 +			open.Transform(minv);
 128.464 +		}
 128.465 +	}
 128.466 +
 128.467 +	const IfcRepresentation& repr = mapped.MappingSource->MappedRepresentation;
 128.468 +
 128.469 +	bool got = false;
 128.470 +	BOOST_FOREACH(const IfcRepresentationItem& item, repr.Items) {
 128.471 +		if(!ProcessRepresentationItem(item,meshes,conv)) {
 128.472 +			IFCImporter::LogWarn("skipping mapped entity of type " + item.GetClassName() + ", no representations could be generated");
 128.473 +		}
 128.474 +		else got = true;
 128.475 +	}
 128.476 +
 128.477 +	if (!got) {
 128.478 +		return false;
 128.479 +	}
 128.480 +
 128.481 +	AssignAddedMeshes(meshes,nd.get(),conv);
 128.482 +	if (conv.collect_openings) {
 128.483 +
 128.484 +		// if this pass serves us only to collect opening geometry,
 128.485 +		// make sure we transform the TempMesh's which we need to
 128.486 +		// preserve as well.
 128.487 +		if(const size_t diff = conv.collect_openings->size() - old_openings) {
 128.488 +			for(size_t i = 0; i < diff; ++i) {
 128.489 +				(*conv.collect_openings)[old_openings+i].Transform(msrc);
 128.490 +			}
 128.491 +		}
 128.492 +	}
 128.493 +
 128.494 +	nd->mTransformation =  nd_src->mTransformation * static_cast<aiMatrix4x4>( msrc );
 128.495 +	subnodes_src.push_back(nd.release());
 128.496 +
 128.497 +	return true;
 128.498 +}
 128.499 +
 128.500 +// ------------------------------------------------------------------------------------------------
 128.501 +struct RateRepresentationPredicate {
 128.502 +
 128.503 +	int Rate(const IfcRepresentation* r) const {
 128.504 +		// the smaller, the better
 128.505 +
 128.506 +		if (! r->RepresentationIdentifier) {
 128.507 +			// neutral choice if no extra information is specified
 128.508 +			return 0;
 128.509 +		}
 128.510 +
 128.511 +		
 128.512 +		const std::string& name = r->RepresentationIdentifier.Get();
 128.513 +		if (name == "MappedRepresentation") {
 128.514 +			if (!r->Items.empty()) {
 128.515 +				// take the first item and base our choice on it
 128.516 +				const IfcMappedItem* const m = r->Items.front()->ToPtr<IfcMappedItem>();
 128.517 +				if (m) {
 128.518 +					return Rate(m->MappingSource->MappedRepresentation);
 128.519 +				}
 128.520 +			}
 128.521 +			return 100;
 128.522 +		}
 128.523 +
 128.524 +		return Rate(name);
 128.525 +	}
 128.526 +
 128.527 +	int Rate(const std::string& r) const {
 128.528 +
 128.529 +
 128.530 +		if (r == "SolidModel") {
 128.531 +			return -3;
 128.532 +		}
 128.533 +		
 128.534 +		// give strong preference to extruded geometry.
 128.535 +		if (r == "SweptSolid") {
 128.536 +			return -10;
 128.537 +		}
 128.538 +		
 128.539 +		if (r == "Clipping") {
 128.540 +			return -5;
 128.541 +		}
 128.542 +
 128.543 +		// 'Brep' is difficult to get right due to possible voids in the
 128.544 +		// polygon boundaries, so take it only if we are forced to (i.e.
 128.545 +		// if the only alternative is (non-clipping) boolean operations, 
 128.546 +		// which are not supported at all).
 128.547 +		if (r == "Brep") {
 128.548 +			return -2;
 128.549 +		}
 128.550 +		
 128.551 +		// Curves, bounding boxes - those will most likely not be loaded
 128.552 +		// as we can't make any use out of this data. So consider them
 128.553 +		// last.
 128.554 +		if (r == "BoundingBox" || r == "Curve2D") {
 128.555 +			return 100;
 128.556 +		}
 128.557 +		return 0;
 128.558 +	}
 128.559 +
 128.560 +	bool operator() (const IfcRepresentation* a, const IfcRepresentation* b) const {
 128.561 +		return Rate(a) < Rate(b);
 128.562 +	}
 128.563 +};
 128.564 +
 128.565 +// ------------------------------------------------------------------------------------------------
 128.566 +void ProcessProductRepresentation(const IfcProduct& el, aiNode* nd, std::vector< aiNode* >& subnodes, ConversionData& conv)
 128.567 +{
 128.568 +	if(!el.Representation) {
 128.569 +		return;
 128.570 +	}
 128.571 +
 128.572 +
 128.573 +	std::vector<unsigned int> meshes;
 128.574 +	
 128.575 +	// we want only one representation type, so bring them in a suitable order (i.e try those
 128.576 +	// that look as if we could read them quickly at first). This way of reading
 128.577 +	// representation is relatively generic and allows the concrete implementations
 128.578 +	// for the different representation types to make some sensible choices what
 128.579 +	// to load and what not to load.
 128.580 +	const STEP::ListOf< STEP::Lazy< IfcRepresentation >, 1, 0 >& src = el.Representation.Get()->Representations;
 128.581 +
 128.582 +	std::vector<const IfcRepresentation*> repr_ordered(src.size());
 128.583 +	std::copy(src.begin(),src.end(),repr_ordered.begin());
 128.584 +	std::sort(repr_ordered.begin(),repr_ordered.end(),RateRepresentationPredicate());
 128.585 +
 128.586 +	BOOST_FOREACH(const IfcRepresentation* repr, repr_ordered) {
 128.587 +		bool res = false;
 128.588 +		BOOST_FOREACH(const IfcRepresentationItem& item, repr->Items) {
 128.589 +			if(const IfcMappedItem* const geo = item.ToPtr<IfcMappedItem>()) {
 128.590 +				res = ProcessMappedItem(*geo,nd,subnodes,conv) || res;
 128.591 +			}
 128.592 +			else {
 128.593 +				res = ProcessRepresentationItem(item,meshes,conv) || res;
 128.594 +			}
 128.595 +		}
 128.596 +		// if we got something meaningful at this point, skip any further representations
 128.597 +		if(res) {
 128.598 +			break;
 128.599 +		}
 128.600 +	}
 128.601 +
 128.602 +	AssignAddedMeshes(meshes,nd,conv);
 128.603 +}
 128.604 +
 128.605 +typedef std::map<std::string, std::string> Metadata;
 128.606 +
 128.607 +// ------------------------------------------------------------------------------------------------
 128.608 +void ProcessMetadata(const ListOf< Lazy< IfcProperty >, 1, 0 >& set, ConversionData& conv, Metadata& properties, 
 128.609 +	const std::string& prefix = "", 
 128.610 +	unsigned int nest = 0) 
 128.611 +{
 128.612 +	BOOST_FOREACH(const IfcProperty& property, set) {
 128.613 +		const std::string& key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name;
 128.614 +		if (const IfcPropertySingleValue* const singleValue = property.ToPtr<IfcPropertySingleValue>()) {
 128.615 +			if (singleValue->NominalValue) {
 128.616 +				if (const EXPRESS::STRING* str = singleValue->NominalValue.Get()->ToPtr<EXPRESS::STRING>()) {
 128.617 +					std::string value = static_cast<std::string>(*str);
 128.618 +					properties[key]=value;
 128.619 +				}
 128.620 +				else if (const EXPRESS::REAL* val = singleValue->NominalValue.Get()->ToPtr<EXPRESS::REAL>()) {
 128.621 +					float value = static_cast<float>(*val);
 128.622 +					std::stringstream s;
 128.623 +					s << value;
 128.624 +					properties[key]=s.str();
 128.625 +				}
 128.626 +				else if (const EXPRESS::INTEGER* val = singleValue->NominalValue.Get()->ToPtr<EXPRESS::INTEGER>()) {
 128.627 +					int64_t value = static_cast<int64_t>(*val);
 128.628 +					std::stringstream s;
 128.629 +					s << value;
 128.630 +					properties[key]=s.str();
 128.631 +				}
 128.632 +			}
 128.633 +		}
 128.634 +		else if (const IfcPropertyListValue* const listValue = property.ToPtr<IfcPropertyListValue>()) {
 128.635 +			std::stringstream ss;
 128.636 +			ss << "[";
 128.637 +			unsigned index=0;
 128.638 +			BOOST_FOREACH(const IfcValue::Out& v, listValue->ListValues) {
 128.639 +				if (!v) continue;
 128.640 +				if (const EXPRESS::STRING* str = v->ToPtr<EXPRESS::STRING>()) {
 128.641 +					std::string value = static_cast<std::string>(*str);
 128.642 +					ss << "'" << value << "'";
 128.643 +				}
 128.644 +				else if (const EXPRESS::REAL* val = v->ToPtr<EXPRESS::REAL>()) {
 128.645 +					float value = static_cast<float>(*val);
 128.646 +					ss << value;
 128.647 +				}
 128.648 +				else if (const EXPRESS::INTEGER* val = v->ToPtr<EXPRESS::INTEGER>()) {
 128.649 +					int64_t value = static_cast<int64_t>(*val);
 128.650 +					ss << value;
 128.651 +				}
 128.652 +				if (index+1<listValue->ListValues.size()) {
 128.653 +					ss << ",";
 128.654 +				}
 128.655 +				index++;
 128.656 +			}
 128.657 +			ss << "]";
 128.658 +			properties[key]=ss.str();
 128.659 +		}
 128.660 +		else if (const IfcComplexProperty* const complexProp = property.ToPtr<IfcComplexProperty>()) {
 128.661 +			if(nest > 2) { // mostly arbitrary limit to prevent stack overflow vulnerabilities
 128.662 +				IFCImporter::LogError("maximum nesting level for IfcComplexProperty reached, skipping this property.");
 128.663 +			}
 128.664 +			else {
 128.665 +				ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1);
 128.666 +			}
 128.667 +		}
 128.668 +		else {
 128.669 +			properties[key]="";
 128.670 +		}
 128.671 +	}
 128.672 +}
 128.673 +
 128.674 +
 128.675 +// ------------------------------------------------------------------------------------------------
 128.676 +void ProcessMetadata(uint64_t relDefinesByPropertiesID, ConversionData& conv, Metadata& properties) 
 128.677 +{
 128.678 +	if (const IfcRelDefinesByProperties* const pset = conv.db.GetObject(relDefinesByPropertiesID)->ToPtr<IfcRelDefinesByProperties>()) {
 128.679 +		if (const IfcPropertySet* const set = conv.db.GetObject(pset->RelatingPropertyDefinition->GetID())->ToPtr<IfcPropertySet>()) {
 128.680 +			ProcessMetadata(set->HasProperties, conv, properties);			
 128.681 +		}
 128.682 +	}
 128.683 +}
 128.684 +
 128.685 +// ------------------------------------------------------------------------------------------------
 128.686 +aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, ConversionData& conv, std::vector<TempOpening>* collect_openings = NULL)
 128.687 +{
 128.688 +	const STEP::DB::RefMap& refs = conv.db.GetRefs();
 128.689 +
 128.690 +	// skip over space and annotation nodes - usually, these have no meaning in Assimp's context
 128.691 +	if(conv.settings.skipSpaceRepresentations) {
 128.692 +		if(const IfcSpace* const space = el.ToPtr<IfcSpace>()) {
 128.693 +			IFCImporter::LogDebug("skipping IfcSpace entity due to importer settings");
 128.694 +			return NULL;
 128.695 +		}
 128.696 +	}
 128.697 +
 128.698 +	if(conv.settings.skipAnnotations) {
 128.699 +		if(const IfcAnnotation* const ann = el.ToPtr<IfcAnnotation>()) {
 128.700 +			IFCImporter::LogDebug("skipping IfcAnnotation entity due to importer settings");
 128.701 +			return NULL;
 128.702 +		}
 128.703 +	}
 128.704 +
 128.705 +	// add an output node for this spatial structure
 128.706 +	std::auto_ptr<aiNode> nd(new aiNode());
 128.707 +	nd->mName.Set(el.GetClassName()+"_"+(el.Name?el.Name.Get():"Unnamed")+"_"+el.GlobalId);
 128.708 +	nd->mParent = parent;
 128.709 +
 128.710 +	conv.already_processed.insert(el.GetID());
 128.711 +
 128.712 +	// check for node metadata
 128.713 +	STEP::DB::RefMapRange children = refs.equal_range(el.GetID());
 128.714 +	if (children.first!=refs.end()) {
 128.715 +		Metadata properties;
 128.716 +		if (children.first==children.second) {
 128.717 +			// handles single property set
 128.718 +			ProcessMetadata((*children.first).second, conv, properties);
 128.719 +		} 
 128.720 +		else {
 128.721 +			// handles multiple property sets (currently all property sets are merged,
 128.722 +			// which may not be the best solution in the long run)
 128.723 +			for (STEP::DB::RefMap::const_iterator it=children.first; it!=children.second; ++it) {
 128.724 +				ProcessMetadata((*it).second, conv, properties);
 128.725 +			}
 128.726 +		}
 128.727 +
 128.728 +		if (!properties.empty()) {
 128.729 +			aiMetadata* data = new aiMetadata();
 128.730 +			data->mNumProperties = properties.size();
 128.731 +			data->mKeys = new aiString*[data->mNumProperties]();
 128.732 +			data->mValues = new aiString*[data->mNumProperties]();
 128.733 +
 128.734 +			unsigned int i = 0;
 128.735 +			BOOST_FOREACH(const Metadata::value_type& kv, properties) {
 128.736 +				data->mKeys[i] = new aiString(kv.first);
 128.737 +				if (kv.second.length() > 0) {
 128.738 +					data->mValues[i] = new aiString(kv.second);
 128.739 +				}				
 128.740 +				++i;
 128.741 +			}
 128.742 +			nd->mMetaData = data;
 128.743 +		}
 128.744 +	}
 128.745 +
 128.746 +	if(el.ObjectPlacement) {
 128.747 +		ResolveObjectPlacement(nd->mTransformation,el.ObjectPlacement.Get(),conv);
 128.748 +	}
 128.749 +
 128.750 +	std::vector<TempOpening> openings;
 128.751 +
 128.752 +	IfcMatrix4 myInv;
 128.753 +	bool didinv = false;
 128.754 +
 128.755 +	// convert everything contained directly within this structure,
 128.756 +	// this may result in more nodes.
 128.757 +	std::vector< aiNode* > subnodes;
 128.758 +	try {
 128.759 +		// locate aggregates and 'contained-in-here'-elements of this spatial structure and add them in recursively
 128.760 +		// on our way, collect openings in *this* element
 128.761 +		STEP::DB::RefMapRange range = refs.equal_range(el.GetID());
 128.762 +
 128.763 +		for(STEP::DB::RefMapRange range2 = range; range2.first != range.second; ++range2.first) {
 128.764 +			// skip over meshes that have already been processed before. This is strictly necessary
 128.765 +			// because the reverse indices also include references contained in argument lists and
 128.766 +			// therefore every element has a back-reference hold by its parent.
 128.767 +			if (conv.already_processed.find((*range2.first).second) != conv.already_processed.end()) {
 128.768 +				continue;
 128.769 +			}
 128.770 +			const STEP::LazyObject& obj = conv.db.MustGetObject((*range2.first).second);
 128.771 +
 128.772 +			// handle regularly-contained elements
 128.773 +			if(const IfcRelContainedInSpatialStructure* const cont = obj->ToPtr<IfcRelContainedInSpatialStructure>()) {
 128.774 +				if(cont->RelatingStructure->GetID() != el.GetID()) {
 128.775 +					continue;
 128.776 +				}
 128.777 +				BOOST_FOREACH(const IfcProduct& pro, cont->RelatedElements) {		
 128.778 +					if(const IfcOpeningElement* const open = pro.ToPtr<IfcOpeningElement>()) {
 128.779 +						// IfcOpeningElement is handled below. Sadly we can't use it here as is:
 128.780 +						// The docs say that opening elements are USUALLY attached to building storey,
 128.781 +						// but we want them for the building elements to which they belong.
 128.782 +						continue;
 128.783 +					}
 128.784 +					
 128.785 +					aiNode* const ndnew = ProcessSpatialStructure(nd.get(),pro,conv,NULL);
 128.786 +					if(ndnew) {
 128.787 +						subnodes.push_back( ndnew );
 128.788 +					}
 128.789 +				}
 128.790 +			}
 128.791 +			// handle openings, which we collect in a list rather than adding them to the node graph
 128.792 +			else if(const IfcRelVoidsElement* const fills = obj->ToPtr<IfcRelVoidsElement>()) {
 128.793 +				if(fills->RelatingBuildingElement->GetID() == el.GetID()) {
 128.794 +					const IfcFeatureElementSubtraction& open = fills->RelatedOpeningElement;
 128.795 +
 128.796 +					// move opening elements to a separate node since they are semantically different than elements that are just 'contained'
 128.797 +					std::auto_ptr<aiNode> nd_aggr(new aiNode());
 128.798 +					nd_aggr->mName.Set("$RelVoidsElement");
 128.799 +					nd_aggr->mParent = nd.get();
 128.800 +
 128.801 +					nd_aggr->mTransformation = nd->mTransformation;
 128.802 +
 128.803 +					std::vector<TempOpening> openings_local;
 128.804 +					aiNode* const ndnew = ProcessSpatialStructure( nd_aggr.get(),open, conv,&openings_local);
 128.805 +					if (ndnew) {
 128.806 +
 128.807 +						nd_aggr->mNumChildren = 1;
 128.808 +						nd_aggr->mChildren = new aiNode*[1]();
 128.809 +
 128.810 +						
 128.811 +						nd_aggr->mChildren[0] = ndnew;
 128.812 +						
 128.813 +						if(openings_local.size()) {
 128.814 +							if (!didinv) {
 128.815 +								myInv = aiMatrix4x4(nd->mTransformation ).Inverse();
 128.816 +								didinv = true;
 128.817 +							}
 128.818 +
 128.819 +							// we need all openings to be in the local space of *this* node, so transform them
 128.820 +							BOOST_FOREACH(TempOpening& op,openings_local) {
 128.821 +								op.Transform( myInv*nd_aggr->mChildren[0]->mTransformation);
 128.822 +								openings.push_back(op);
 128.823 +							}
 128.824 +						}
 128.825 +						subnodes.push_back( nd_aggr.release() );
 128.826 +					}
 128.827 +				}
 128.828 +			}
 128.829 +		}
 128.830 +
 128.831 +		for(;range.first != range.second; ++range.first) {
 128.832 +			// see note in loop above
 128.833 +			if (conv.already_processed.find((*range.first).second) != conv.already_processed.end()) {
 128.834 +				continue;
 128.835 +			}
 128.836 +			if(const IfcRelAggregates* const aggr = conv.db.GetObject((*range.first).second)->ToPtr<IfcRelAggregates>()) {
 128.837 +				if(aggr->RelatingObject->GetID() != el.GetID()) {
 128.838 +					continue;
 128.839 +				}
 128.840 +
 128.841 +				// move aggregate elements to a separate node since they are semantically different than elements that are just 'contained'
 128.842 +				std::auto_ptr<aiNode> nd_aggr(new aiNode());
 128.843 +				nd_aggr->mName.Set("$RelAggregates");
 128.844 +				nd_aggr->mParent = nd.get();
 128.845 +
 128.846 +				nd_aggr->mTransformation = nd->mTransformation;
 128.847 +
 128.848 +				nd_aggr->mChildren = new aiNode*[aggr->RelatedObjects.size()]();
 128.849 +				BOOST_FOREACH(const IfcObjectDefinition& def, aggr->RelatedObjects) {
 128.850 +					if(const IfcProduct* const prod = def.ToPtr<IfcProduct>()) {
 128.851 +
 128.852 +						aiNode* const ndnew = ProcessSpatialStructure(nd_aggr.get(),*prod,conv,NULL);
 128.853 +						if(ndnew) {
 128.854 +							nd_aggr->mChildren[nd_aggr->mNumChildren++] = ndnew;
 128.855 +						}
 128.856 +					}
 128.857 +				}
 128.858 +			
 128.859 +				subnodes.push_back( nd_aggr.release() );
 128.860 +			}
 128.861 +		}
 128.862 +
 128.863 +		conv.collect_openings = collect_openings;
 128.864 +		if(!conv.collect_openings) {
 128.865 +			conv.apply_openings = &openings;
 128.866 +		}
 128.867 +
 128.868 +		ProcessProductRepresentation(el,nd.get(),subnodes,conv);
 128.869 +		conv.apply_openings = conv.collect_openings = NULL;
 128.870 +
 128.871 +		if (subnodes.size()) {
 128.872 +			nd->mChildren = new aiNode*[subnodes.size()]();
 128.873 +			BOOST_FOREACH(aiNode* nd2, subnodes) {
 128.874 +				nd->mChildren[nd->mNumChildren++] = nd2;
 128.875 +				nd2->mParent = nd.get();
 128.876 +			}
 128.877 +		}
 128.878 +	}
 128.879 +	catch(...) {
 128.880 +		// it hurts, but I don't want to pull boost::ptr_vector into -noboost only for these few spots here
 128.881 +		std::for_each(subnodes.begin(),subnodes.end(),delete_fun<aiNode>());
 128.882 +		throw;
 128.883 +	}
 128.884 +
 128.885 +	ai_assert(conv.already_processed.find(el.GetID()) != conv.already_processed.end());
 128.886 +	conv.already_processed.erase(conv.already_processed.find(el.GetID()));
 128.887 +	return nd.release();
 128.888 +}
 128.889 +
 128.890 +// ------------------------------------------------------------------------------------------------
 128.891 +void ProcessSpatialStructures(ConversionData& conv)
 128.892 +{
 128.893 +	// XXX add support for multiple sites (i.e. IfcSpatialStructureElements with composition == COMPLEX)
 128.894 +
 128.895 +
 128.896 +	// process all products in the file. it is reasonable to assume that a
 128.897 +	// file that is relevant for us contains at least a site or a building.
 128.898 +	const STEP::DB::ObjectMapByType& map = conv.db.GetObjectsByType();
 128.899 +
 128.900 +	ai_assert(map.find("ifcsite") != map.end());
 128.901 +	const STEP::DB::ObjectSet* range = &map.find("ifcsite")->second;
 128.902 +
 128.903 +	if (range->empty()) {
 128.904 +		ai_assert(map.find("ifcbuilding") != map.end());
 128.905 +		range = &map.find("ifcbuilding")->second;
 128.906 +		if (range->empty()) {
 128.907 +			// no site, no building -  fail;
 128.908 +			IFCImporter::ThrowException("no root element found (expected IfcBuilding or preferably IfcSite)");
 128.909 +		}
 128.910 +	}
 128.911 +
 128.912 +	
 128.913 +	BOOST_FOREACH(const STEP::LazyObject* lz, *range) {
 128.914 +		const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
 128.915 +		if(!prod) {
 128.916 +			continue;
 128.917 +		}
 128.918 +		IFCImporter::LogDebug("looking at spatial structure `" + (prod->Name ? prod->Name.Get() : "unnamed") + "`" + (prod->ObjectType? " which is of type " + prod->ObjectType.Get():""));
 128.919 +	
 128.920 +		// the primary site is referenced by an IFCRELAGGREGATES element which assigns it to the IFCPRODUCT
 128.921 +		const STEP::DB::RefMap& refs = conv.db.GetRefs();
 128.922 +		STEP::DB::RefMapRange range = refs.equal_range(conv.proj.GetID());
 128.923 +		for(;range.first != range.second; ++range.first) {
 128.924 +			if(const IfcRelAggregates* const aggr = conv.db.GetObject((*range.first).second)->ToPtr<IfcRelAggregates>()) {
 128.925 +			
 128.926 +				BOOST_FOREACH(const IfcObjectDefinition& def, aggr->RelatedObjects) {
 128.927 +					// comparing pointer values is not sufficient, we would need to cast them to the same type first
 128.928 +					// as there is multiple inheritance in the game.
 128.929 +					if (def.GetID() == prod->GetID()) { 
 128.930 +						IFCImporter::LogDebug("selecting this spatial structure as root structure");
 128.931 +						// got it, this is the primary site.
 128.932 +						conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
 128.933 +						return;
 128.934 +					}
 128.935 +				}
 128.936 +
 128.937 +			}
 128.938 +		}
 128.939 +	}
 128.940 +
 128.941 +	
 128.942 +	IFCImporter::LogWarn("failed to determine primary site element, taking the first IfcSite");
 128.943 +	BOOST_FOREACH(const STEP::LazyObject* lz, *range) {
 128.944 +		const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
 128.945 +		if(!prod) {
 128.946 +			continue;
 128.947 +		}
 128.948 +
 128.949 +		conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
 128.950 +		return;
 128.951 +	}
 128.952 +
 128.953 +	IFCImporter::ThrowException("failed to determine primary site element");
 128.954 +}
 128.955 +
 128.956 +// ------------------------------------------------------------------------------------------------
 128.957 +void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined)
 128.958 +{
 128.959 +	// combined is the parent's absolute transformation matrix
 128.960 +	const aiMatrix4x4 old = start->mTransformation;
 128.961 +
 128.962 +	if (!combined.IsIdentity()) {
 128.963 +		start->mTransformation = aiMatrix4x4(combined).Inverse() * start->mTransformation;
 128.964 +	}
 128.965 +
 128.966 +	// All nodes store absolute transformations right now, so we need to make them relative
 128.967 +	for (unsigned int i = 0; i < start->mNumChildren; ++i) {
 128.968 +		MakeTreeRelative(start->mChildren[i],old);
 128.969 +	}
 128.970 +}
 128.971 +
 128.972 +// ------------------------------------------------------------------------------------------------
 128.973 +void MakeTreeRelative(ConversionData& conv)
 128.974 +{
 128.975 +	MakeTreeRelative(conv.out->mRootNode,IfcMatrix4());
 128.976 +}
 128.977 +
 128.978 +} // !anon
 128.979 +
 128.980 +
 128.981 +
 128.982 +#endif
   129.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   129.2 +++ b/libs/assimp/IFCLoader.h	Sat Feb 01 19:58:19 2014 +0200
   129.3 @@ -0,0 +1,132 @@
   129.4 +/*
   129.5 +Open Asset Import Library (assimp)
   129.6 +----------------------------------------------------------------------
   129.7 +
   129.8 +Copyright (c) 2006-2012, assimp team
   129.9 +All rights reserved.
  129.10 +
  129.11 +Redistribution and use of this software in source and binary forms, 
  129.12 +with or without modification, are permitted provided that the 
  129.13 +following conditions are met:
  129.14 +
  129.15 +* Redistributions of source code must retain the above
  129.16 +  copyright notice, this list of conditions and the
  129.17 +  following disclaimer.
  129.18 +
  129.19 +* Redistributions in binary form must reproduce the above
  129.20 +  copyright notice, this list of conditions and the
  129.21 +  following disclaimer in the documentation and/or other
  129.22 +  materials provided with the distribution.
  129.23 +
  129.24 +* Neither the name of the assimp team, nor the names of its
  129.25 +  contributors may be used to endorse or promote products
  129.26 +  derived from this software without specific prior
  129.27 +  written permission of the assimp team.
  129.28 +
  129.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  129.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  129.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  129.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  129.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  129.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  129.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  129.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  129.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  129.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  129.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  129.40 +
  129.41 +----------------------------------------------------------------------
  129.42 +*/
  129.43 +
  129.44 +/** @file  IFC.h
  129.45 + *  @brief Declaration of the Industry Foundation Classes (IFC) loader main class
  129.46 + */
  129.47 +#ifndef INCLUDED_AI_IFC_LOADER_H
  129.48 +#define INCLUDED_AI_IFC_LOADER_H
  129.49 +
  129.50 +#include "BaseImporter.h"
  129.51 +#include "LogAux.h"
  129.52 +
  129.53 +namespace Assimp	{
  129.54 +	
  129.55 +	// TinyFormatter.h
  129.56 +	namespace Formatter {
  129.57 +		template <typename T,typename TR, typename A> class basic_formatter;
  129.58 +		typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
  129.59 +	}
  129.60 +
  129.61 +	namespace STEP {
  129.62 +		class DB;
  129.63 +	}
  129.64 +
  129.65 +
  129.66 +// -------------------------------------------------------------------------------------------
  129.67 +/** Load the IFC format, which is an open specification to describe building and construction
  129.68 +    industry data.
  129.69 +
  129.70 + See http://en.wikipedia.org/wiki/Industry_Foundation_Classes
  129.71 +*/
  129.72 +// -------------------------------------------------------------------------------------------
  129.73 +class IFCImporter : public BaseImporter, public LogFunctions<IFCImporter>
  129.74 +{
  129.75 +public:
  129.76 +	IFCImporter();
  129.77 +	~IFCImporter();
  129.78 +
  129.79 +
  129.80 +public:
  129.81 +
  129.82 +	// --------------------
  129.83 +	bool CanRead( const std::string& pFile, 
  129.84 +		IOSystem* pIOHandler,
  129.85 +		bool checkSig
  129.86 +	) const;
  129.87 +
  129.88 +protected:
  129.89 +
  129.90 +	// --------------------
  129.91 +	const aiImporterDesc* GetInfo () const;
  129.92 +
  129.93 +	// --------------------
  129.94 +	void SetupProperties(const Importer* pImp);
  129.95 +
  129.96 +	// --------------------
  129.97 +	void InternReadFile( const std::string& pFile, 
  129.98 +		aiScene* pScene, 
  129.99 +		IOSystem* pIOHandler
 129.100 +	);
 129.101 +
 129.102 +private:
 129.103 +
 129.104 +
 129.105 +public: 
 129.106 +
 129.107 +
 129.108 +	// loader settings, publicly accessible via their corresponding AI_CONFIG constants
 129.109 +	struct Settings 
 129.110 +	{
 129.111 +		Settings()
 129.112 +			: skipSpaceRepresentations()
 129.113 +			, skipCurveRepresentations()
 129.114 +			, useCustomTriangulation()
 129.115 +			, skipAnnotations()
 129.116 +			, conicSamplingAngle(10.f)
 129.117 +		{}
 129.118 +
 129.119 +
 129.120 +		bool skipSpaceRepresentations;
 129.121 +		bool skipCurveRepresentations;
 129.122 +		bool useCustomTriangulation;
 129.123 +		bool skipAnnotations;
 129.124 +		float conicSamplingAngle;
 129.125 +	};
 129.126 +	
 129.127 +	
 129.128 +private:
 129.129 +
 129.130 +	Settings settings;
 129.131 +
 129.132 +}; // !class IFCImporter
 129.133 +
 129.134 +} // end of namespace Assimp
 129.135 +#endif // !INCLUDED_AI_IFC_LOADER_H
   130.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   130.2 +++ b/libs/assimp/IFCMaterial.cpp	Sat Feb 01 19:58:19 2014 +0200
   130.3 @@ -0,0 +1,179 @@
   130.4 +/*
   130.5 +Open Asset Import Library (assimp)
   130.6 +----------------------------------------------------------------------
   130.7 +
   130.8 +Copyright (c) 2006-2012, assimp team
   130.9 +All rights reserved.
  130.10 +
  130.11 +Redistribution and use of this software in source and binary forms, 
  130.12 +with or without modification, are permitted provided that the 
  130.13 +following conditions are met:
  130.14 +
  130.15 +* Redistributions of source code must retain the above
  130.16 +  copyright notice, this list of conditions and the
  130.17 +  following disclaimer.
  130.18 +
  130.19 +* Redistributions in binary form must reproduce the above
  130.20 +  copyright notice, this list of conditions and the
  130.21 +  following disclaimer in the documentation and/or other
  130.22 +  materials provided with the distribution.
  130.23 +
  130.24 +* Neither the name of the assimp team, nor the names of its
  130.25 +  contributors may be used to endorse or promote products
  130.26 +  derived from this software without specific prior
  130.27 +  written permission of the assimp team.
  130.28 +
  130.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  130.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  130.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  130.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  130.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  130.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  130.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  130.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  130.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  130.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  130.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  130.40 +
  130.41 +----------------------------------------------------------------------
  130.42 +*/
  130.43 +
  130.44 +/** @file  IFCMaterial.cpp
  130.45 + *  @brief Implementation of conversion routines to convert IFC materials to aiMaterial
  130.46 + */
  130.47 +
  130.48 +#include "AssimpPCH.h"
  130.49 +
  130.50 +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
  130.51 +#include "IFCUtil.h"
  130.52 +
  130.53 +namespace Assimp {
  130.54 +	namespace IFC {
  130.55 +
  130.56 +// ------------------------------------------------------------------------------------------------
  130.57 +int ConvertShadingMode(const std::string& name)
  130.58 +{
  130.59 +	if (name == "BLINN") {
  130.60 +		return aiShadingMode_Blinn;
  130.61 +	}
  130.62 +	else if (name == "FLAT" || name == "NOTDEFINED") {
  130.63 +		return aiShadingMode_NoShading;
  130.64 +	}
  130.65 +	else if (name == "PHONG") {
  130.66 +		return aiShadingMode_Phong;
  130.67 +	}
  130.68 +	IFCImporter::LogWarn("shading mode "+name+" not recognized by Assimp, using Phong instead");
  130.69 +	return aiShadingMode_Phong;
  130.70 +}
  130.71 +
  130.72 +// ------------------------------------------------------------------------------------------------
  130.73 +void FillMaterial(aiMaterial* mat,const IFC::IfcSurfaceStyle* surf,ConversionData& conv) 
  130.74 +{
  130.75 +	aiString name;
  130.76 +	name.Set((surf->Name? surf->Name.Get() : "IfcSurfaceStyle_Unnamed"));
  130.77 +	mat->AddProperty(&name,AI_MATKEY_NAME);
  130.78 +
  130.79 +	// now see which kinds of surface information are present
  130.80 +	BOOST_FOREACH(boost::shared_ptr< const IFC::IfcSurfaceStyleElementSelect > sel2, surf->Styles) {
  130.81 +		if (const IFC::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleShading>(conv.db)) {
  130.82 +			aiColor4D col_base,col;
  130.83 +
  130.84 +			ConvertColor(col_base, shade->SurfaceColour);
  130.85 +			mat->AddProperty(&col_base,1, AI_MATKEY_COLOR_DIFFUSE);
  130.86 +
  130.87 +			if (const IFC::IfcSurfaceStyleRendering* ren = shade->ToPtr<IFC::IfcSurfaceStyleRendering>()) {
  130.88 +
  130.89 +				if (ren->Transparency) {
  130.90 +					const float t = 1.f-static_cast<float>(ren->Transparency.Get());
  130.91 +					mat->AddProperty(&t,1, AI_MATKEY_OPACITY);
  130.92 +				}
  130.93 +
  130.94 +				if (ren->DiffuseColour) {
  130.95 +					ConvertColor(col, *ren->DiffuseColour.Get(),conv,&col_base);
  130.96 +					mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE);
  130.97 +				}
  130.98 +
  130.99 +				if (ren->SpecularColour) {
 130.100 +					ConvertColor(col, *ren->SpecularColour.Get(),conv,&col_base);
 130.101 +					mat->AddProperty(&col,1, AI_MATKEY_COLOR_SPECULAR);
 130.102 +				}
 130.103 +
 130.104 +				if (ren->TransmissionColour) {
 130.105 +					ConvertColor(col, *ren->TransmissionColour.Get(),conv,&col_base);
 130.106 +					mat->AddProperty(&col,1, AI_MATKEY_COLOR_TRANSPARENT);
 130.107 +				}
 130.108 +
 130.109 +				if (ren->ReflectionColour) {
 130.110 +					ConvertColor(col, *ren->ReflectionColour.Get(),conv,&col_base);
 130.111 +					mat->AddProperty(&col,1, AI_MATKEY_COLOR_REFLECTIVE);
 130.112 +				}
 130.113 +
 130.114 +				const int shading = (ren->SpecularHighlight && ren->SpecularColour)?ConvertShadingMode(ren->ReflectanceMethod):static_cast<int>(aiShadingMode_Gouraud);
 130.115 +				mat->AddProperty(&shading,1, AI_MATKEY_SHADING_MODEL);
 130.116 +
 130.117 +				if (ren->SpecularHighlight) {
 130.118 +					if(const EXPRESS::REAL* rt = ren->SpecularHighlight.Get()->ToPtr<EXPRESS::REAL>()) {
 130.119 +						// at this point we don't distinguish between the two distinct ways of
 130.120 +						// specifying highlight intensities. leave this to the user.
 130.121 +						const float e = static_cast<float>(*rt);
 130.122 +						mat->AddProperty(&e,1,AI_MATKEY_SHININESS);
 130.123 +					}
 130.124 +					else {
 130.125 +						IFCImporter::LogWarn("unexpected type error, SpecularHighlight should be a REAL");
 130.126 +					}
 130.127 +				}
 130.128 +			}
 130.129 +		} /*
 130.130 +		else if (const IFC::IfcSurfaceStyleWithTextures* tex = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleWithTextures>(conv.db)) {
 130.131 +			// XXX
 130.132 +		} */
 130.133 +	}
 130.134 +
 130.135 +}
 130.136 +
 130.137 +// ------------------------------------------------------------------------------------------------
 130.138 +unsigned int ProcessMaterials(const IFC::IfcRepresentationItem& item, ConversionData& conv)
 130.139 +{
 130.140 +	if (conv.materials.empty()) {
 130.141 +		aiString name;
 130.142 +		std::auto_ptr<aiMaterial> mat(new aiMaterial());
 130.143 +
 130.144 +		name.Set("<IFCDefault>");
 130.145 +		mat->AddProperty(&name,AI_MATKEY_NAME);
 130.146 +
 130.147 +		const aiColor4D col = aiColor4D(0.6f,0.6f,0.6f,1.0f);
 130.148 +		mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE);
 130.149 +
 130.150 +		conv.materials.push_back(mat.release());
 130.151 +	}
 130.152 +
 130.153 +	STEP::DB::RefMapRange range = conv.db.GetRefs().equal_range(item.GetID());
 130.154 +	for(;range.first != range.second; ++range.first) {
 130.155 +		if(const IFC::IfcStyledItem* const styled = conv.db.GetObject((*range.first).second)->ToPtr<IFC::IfcStyledItem>()) {
 130.156 +			BOOST_FOREACH(const IFC::IfcPresentationStyleAssignment& as, styled->Styles) {
 130.157 +				BOOST_FOREACH(boost::shared_ptr<const IFC::IfcPresentationStyleSelect> sel, as.Styles) {
 130.158 +
 130.159 +					if (const IFC::IfcSurfaceStyle* const surf =  sel->ResolveSelectPtr<IFC::IfcSurfaceStyle>(conv.db)) {
 130.160 +						const std::string side = static_cast<std::string>(surf->Side);
 130.161 +						if (side != "BOTH") {
 130.162 +							IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: " + side);
 130.163 +						}
 130.164 +
 130.165 +						std::auto_ptr<aiMaterial> mat(new aiMaterial());
 130.166 +
 130.167 +						FillMaterial(mat.get(),surf,conv);
 130.168 +
 130.169 +						conv.materials.push_back(mat.release());
 130.170 +						return conv.materials.size()-1;
 130.171 +					}
 130.172 +				}
 130.173 +			}
 130.174 +		}
 130.175 +	}
 130.176 +	return 0;
 130.177 +}
 130.178 +
 130.179 +} // ! IFC
 130.180 +} // ! Assimp
 130.181 +
 130.182 +#endif
   131.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   131.2 +++ b/libs/assimp/IFCOpenings.cpp	Sat Feb 01 19:58:19 2014 +0200
   131.3 @@ -0,0 +1,1744 @@
   131.4 +/*
   131.5 +Open Asset Import Library (assimp)
   131.6 +----------------------------------------------------------------------
   131.7 +
   131.8 +Copyright (c) 2006-2010, assimp team
   131.9 +All rights reserved.
  131.10 +
  131.11 +Redistribution and use of this software in source and binary forms, 
  131.12 +with or without modification, are permitted provided that the 
  131.13 +following conditions are met:
  131.14 +
  131.15 +* Redistributions of source code must retain the above
  131.16 +  copyright notice, this list of conditions and the
  131.17 +  following disclaimer.
  131.18 +
  131.19 +* Redistributions in binary form must reproduce the above
  131.20 +  copyright notice, this list of conditions and the
  131.21 +  following disclaimer in the documentation and/or other
  131.22 +  materials provided with the distribution.
  131.23 +
  131.24 +* Neither the name of the assimp team, nor the names of its
  131.25 +  contributors may be used to endorse or promote products
  131.26 +  derived from this software without specific prior
  131.27 +  written permission of the assimp team.
  131.28 +
  131.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  131.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  131.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  131.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  131.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  131.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  131.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  131.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  131.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  131.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  131.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  131.40 +
  131.41 +----------------------------------------------------------------------
  131.42 +*/
  131.43 +
  131.44 +/** @file  IFCOpenings.cpp
  131.45 + *  @brief Implements a subset of Ifc CSG operations for pouring 
  131.46 +  *    holes for windows and doors into walls.
  131.47 + */
  131.48 +
  131.49 +#include "AssimpPCH.h"
  131.50 +
  131.51 +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
  131.52 +#include "IFCUtil.h"
  131.53 +#include "PolyTools.h"
  131.54 +#include "ProcessHelper.h"
  131.55 +
  131.56 +#include "../contrib/poly2tri/poly2tri/poly2tri.h"
  131.57 +#include "../contrib/clipper/clipper.hpp"
  131.58 +
  131.59 +#include <iterator>
  131.60 +
  131.61 +namespace Assimp {
  131.62 +	namespace IFC {
  131.63 +
  131.64 +		using ClipperLib::ulong64;
  131.65 +		// XXX use full -+ range ...
  131.66 +		const ClipperLib::long64 max_ulong64 = 1518500249; // clipper.cpp / hiRange var
  131.67 +
  131.68 +		//#define to_int64(p)  (static_cast<ulong64>( std::max( 0., std::min( static_cast<IfcFloat>((p)), 1.) ) * max_ulong64 ))
  131.69 +#define to_int64(p)  (static_cast<ulong64>(static_cast<IfcFloat>((p) ) * max_ulong64 ))
  131.70 +#define from_int64(p) (static_cast<IfcFloat>((p)) / max_ulong64)
  131.71 +#define one_vec (IfcVector2(static_cast<IfcFloat>(1.0),static_cast<IfcFloat>(1.0)))
  131.72 +
  131.73 +
  131.74 +		// fallback method to generate wall openings
  131.75 +		bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, 
  131.76 +			TempMesh& curmesh);
  131.77 +
  131.78 +
  131.79 +typedef std::pair< IfcVector2, IfcVector2 > BoundingBox;
  131.80 +typedef std::map<IfcVector2,size_t,XYSorter> XYSortedField;
  131.81 +
  131.82 +
  131.83 +// ------------------------------------------------------------------------------------------------
  131.84 +void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField& field, 
  131.85 +	const std::vector< BoundingBox >& bbs, 
  131.86 +	std::vector<IfcVector2>& out)
  131.87 +{
  131.88 +	if (!(pmin.x-pmax.x) || !(pmin.y-pmax.y)) {
  131.89 +		return;
  131.90 +	}
  131.91 +
  131.92 +	IfcFloat xs = 1e10, xe = 1e10;	
  131.93 +	bool found = false;
  131.94 +
  131.95 +	// Search along the x-axis until we find an opening
  131.96 +	XYSortedField::iterator start = field.begin();
  131.97 +	for(; start != field.end(); ++start) {
  131.98 +		const BoundingBox& bb = bbs[(*start).second];
  131.99 +		if(bb.first.x >= pmax.x) {
 131.100 +			break;
 131.101 +		} 
 131.102 +
 131.103 +		if (bb.second.x > pmin.x && bb.second.y > pmin.y && bb.first.y < pmax.y) {
 131.104 +			xs = bb.first.x;
 131.105 +			xe = bb.second.x;
 131.106 +			found = true;
 131.107 +			break;
 131.108 +		}
 131.109 +	}
 131.110 +
 131.111 +	if (!found) {
 131.112 +		// the rectangle [pmin,pend] is opaque, fill it
 131.113 +		out.push_back(pmin);
 131.114 +		out.push_back(IfcVector2(pmin.x,pmax.y));
 131.115 +		out.push_back(pmax);
 131.116 +		out.push_back(IfcVector2(pmax.x,pmin.y));
 131.117 +		return;
 131.118 +	}
 131.119 +
 131.120 +	xs = std::max(pmin.x,xs);
 131.121 +	xe = std::min(pmax.x,xe);
 131.122 +
 131.123 +	// see if there's an offset to fill at the top of our quad
 131.124 +	if (xs - pmin.x) {
 131.125 +		out.push_back(pmin);
 131.126 +		out.push_back(IfcVector2(pmin.x,pmax.y));
 131.127 +		out.push_back(IfcVector2(xs,pmax.y));
 131.128 +		out.push_back(IfcVector2(xs,pmin.y));
 131.129 +	}
 131.130 +
 131.131 +	// search along the y-axis for all openings that overlap xs and our quad
 131.132 +	IfcFloat ylast = pmin.y;
 131.133 +	found = false;
 131.134 +	for(; start != field.end(); ++start) {
 131.135 +		const BoundingBox& bb = bbs[(*start).second];
 131.136 +		if (bb.first.x > xs || bb.first.y >= pmax.y) {
 131.137 +			break;
 131.138 +		}
 131.139 +
 131.140 +		if (bb.second.y > ylast) {
 131.141 +
 131.142 +			found = true;
 131.143 +			const IfcFloat ys = std::max(bb.first.y,pmin.y), ye = std::min(bb.second.y,pmax.y);
 131.144 +			if (ys - ylast > 0.0f) {
 131.145 +				QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,ys) ,field,bbs,out);
 131.146 +			}
 131.147 +
 131.148 +			// the following are the window vertices
 131.149 +
 131.150 +			/*wnd.push_back(IfcVector2(xs,ys));
 131.151 +			wnd.push_back(IfcVector2(xs,ye));
 131.152 +			wnd.push_back(IfcVector2(xe,ye));
 131.153 +			wnd.push_back(IfcVector2(xe,ys));*/
 131.154 +			ylast = ye;
 131.155 +		}
 131.156 +	}
 131.157 +	if (!found) {
 131.158 +		// the rectangle [pmin,pend] is opaque, fill it
 131.159 +		out.push_back(IfcVector2(xs,pmin.y));
 131.160 +		out.push_back(IfcVector2(xs,pmax.y));
 131.161 +		out.push_back(IfcVector2(xe,pmax.y));
 131.162 +		out.push_back(IfcVector2(xe,pmin.y));
 131.163 +		return;
 131.164 +	}
 131.165 +	if (ylast < pmax.y) {
 131.166 +		QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,pmax.y) ,field,bbs,out);
 131.167 +	}
 131.168 +
 131.169 +	// now for the whole rest
 131.170 +	if (pmax.x-xe) {
 131.171 +		QuadrifyPart(IfcVector2(xe,pmin.y), pmax ,field,bbs,out);
 131.172 +	}
 131.173 +}
 131.174 +
 131.175 +typedef std::vector<IfcVector2> Contour;
 131.176 +typedef std::vector<bool> SkipList; // should probably use int for performance reasons
 131.177 +
 131.178 +struct ProjectedWindowContour
 131.179 +{
 131.180 +	Contour contour;
 131.181 +	BoundingBox bb;
 131.182 +	SkipList skiplist;
 131.183 +	bool is_rectangular;
 131.184 +
 131.185 +
 131.186 +	ProjectedWindowContour(const Contour& contour, const BoundingBox& bb, bool is_rectangular)
 131.187 +		: contour(contour)
 131.188 +		, bb(bb)
 131.189 +		, is_rectangular(is_rectangular)
 131.190 +	{}
 131.191 +
 131.192 +
 131.193 +	bool IsInvalid() const {
 131.194 +		return contour.empty();
 131.195 +	}
 131.196 +
 131.197 +	void FlagInvalid() {
 131.198 +		contour.clear();
 131.199 +	}
 131.200 +
 131.201 +	void PrepareSkiplist() {
 131.202 +		skiplist.resize(contour.size(),false);
 131.203 +	}
 131.204 +};
 131.205 +
 131.206 +typedef std::vector< ProjectedWindowContour > ContourVector;
 131.207 +
 131.208 +// ------------------------------------------------------------------------------------------------
 131.209 +bool BoundingBoxesOverlapping( const BoundingBox &ibb, const BoundingBox &bb ) 
 131.210 +{
 131.211 +	// count the '=' case as non-overlapping but as adjacent to each other
 131.212 +	return ibb.first.x < bb.second.x && ibb.second.x > bb.first.x &&
 131.213 +		ibb.first.y < bb.second.y && ibb.second.y > bb.first.y;
 131.214 +}
 131.215 +
 131.216 +// ------------------------------------------------------------------------------------------------
 131.217 +bool IsDuplicateVertex(const IfcVector2& vv, const std::vector<IfcVector2>& temp_contour)
 131.218 +{
 131.219 +	// sanity check for duplicate vertices
 131.220 +	BOOST_FOREACH(const IfcVector2& cp, temp_contour) {
 131.221 +		if ((cp-vv).SquareLength() < 1e-5f) {
 131.222 +			return true;
 131.223 +		}
 131.224 +	}  
 131.225 +	return false;
 131.226 +}
 131.227 +
 131.228 +// ------------------------------------------------------------------------------------------------
 131.229 +void ExtractVerticesFromClipper(const ClipperLib::Polygon& poly, std::vector<IfcVector2>& temp_contour, 
 131.230 +	bool filter_duplicates = false)
 131.231 +{
 131.232 +	temp_contour.clear();
 131.233 +	BOOST_FOREACH(const ClipperLib::IntPoint& point, poly) {
 131.234 +		IfcVector2 vv = IfcVector2( from_int64(point.X), from_int64(point.Y));
 131.235 +		vv = std::max(vv,IfcVector2());
 131.236 +		vv = std::min(vv,one_vec);
 131.237 +
 131.238 +		if (!filter_duplicates || !IsDuplicateVertex(vv, temp_contour)) {
 131.239 +			temp_contour.push_back(vv);
 131.240 +		}
 131.241 +	}
 131.242 +}
 131.243 +
 131.244 +// ------------------------------------------------------------------------------------------------
 131.245 +BoundingBox GetBoundingBox(const ClipperLib::Polygon& poly)
 131.246 +{
 131.247 +	IfcVector2 newbb_min, newbb_max;
 131.248 +	MinMaxChooser<IfcVector2>()(newbb_min, newbb_max);
 131.249 +
 131.250 +	BOOST_FOREACH(const ClipperLib::IntPoint& point, poly) {
 131.251 +		IfcVector2 vv = IfcVector2( from_int64(point.X), from_int64(point.Y));
 131.252 +
 131.253 +		// sanity rounding
 131.254 +		vv = std::max(vv,IfcVector2());
 131.255 +		vv = std::min(vv,one_vec);
 131.256 +
 131.257 +		newbb_min = std::min(newbb_min,vv);
 131.258 +		newbb_max = std::max(newbb_max,vv);
 131.259 +	}
 131.260 +	return BoundingBox(newbb_min, newbb_max);
 131.261 +}
 131.262 +
 131.263 +// ------------------------------------------------------------------------------------------------
 131.264 +void InsertWindowContours(const ContourVector& contours,
 131.265 +	const std::vector<TempOpening>& openings,
 131.266 +	TempMesh& curmesh)
 131.267 +{
 131.268 +	// fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now
 131.269 +	for(size_t i = 0; i < contours.size();++i) {
 131.270 +		const BoundingBox& bb = contours[i].bb;
 131.271 +		const std::vector<IfcVector2>& contour = contours[i].contour;
 131.272 +		if(contour.empty()) {
 131.273 +			continue;
 131.274 +		}
 131.275 +
 131.276 +		// check if we need to do it at all - many windows just fit perfectly into their quadratic holes,
 131.277 +		// i.e. their contours *are* already their bounding boxes.
 131.278 +		if (contour.size() == 4) {
 131.279 +			std::set<IfcVector2,XYSorter> verts;
 131.280 +			for(size_t n = 0; n < 4; ++n) {
 131.281 +				verts.insert(contour[n]);
 131.282 +			}
 131.283 +			const std::set<IfcVector2,XYSorter>::const_iterator end = verts.end();
 131.284 +			if (verts.find(bb.first)!=end && verts.find(bb.second)!=end
 131.285 +				&& verts.find(IfcVector2(bb.first.x,bb.second.y))!=end 
 131.286 +				&& verts.find(IfcVector2(bb.second.x,bb.first.y))!=end 
 131.287 +				) {
 131.288 +					continue;
 131.289 +			}
 131.290 +		}
 131.291 +
 131.292 +		const IfcFloat diag = (bb.first-bb.second).Length();
 131.293 +		const IfcFloat epsilon = diag/1000.f;
 131.294 +
 131.295 +		// walk through all contour points and find those that lie on the BB corner
 131.296 +		size_t last_hit = -1, very_first_hit = -1;
 131.297 +		IfcVector2 edge;
 131.298 +		for(size_t n = 0, e=0, size = contour.size();; n=(n+1)%size, ++e) {
 131.299 +
 131.300 +			// sanity checking
 131.301 +			if (e == size*2) {
 131.302 +				IFCImporter::LogError("encountered unexpected topology while generating window contour");
 131.303 +				break;
 131.304 +			}
 131.305 +
 131.306 +			const IfcVector2& v = contour[n];
 131.307 +
 131.308 +			bool hit = false;
 131.309 +			if (fabs(v.x-bb.first.x)<epsilon) {
 131.310 +				edge.x = bb.first.x;
 131.311 +				hit = true;
 131.312 +			}
 131.313 +			else if (fabs(v.x-bb.second.x)<epsilon) {
 131.314 +				edge.x = bb.second.x;
 131.315 +				hit = true;
 131.316 +			}
 131.317 +
 131.318 +			if (fabs(v.y-bb.first.y)<epsilon) {
 131.319 +				edge.y = bb.first.y;
 131.320 +				hit = true;
 131.321 +			}
 131.322 +			else if (fabs(v.y-bb.second.y)<epsilon) {
 131.323 +				edge.y = bb.second.y;
 131.324 +				hit = true;
 131.325 +			}
 131.326 +
 131.327 +			if (hit) {
 131.328 +				if (last_hit != (size_t)-1) {
 131.329 +
 131.330 +					const size_t old = curmesh.verts.size();
 131.331 +					size_t cnt = last_hit > n ? size-(last_hit-n) : n-last_hit;
 131.332 +					for(size_t a = last_hit, e = 0; e <= cnt; a=(a+1)%size, ++e) {
 131.333 +						// hack: this is to fix cases where opening contours are self-intersecting.
 131.334 +						// Clipper doesn't produce such polygons, but as soon as we're back in
 131.335 +						// our brave new floating-point world, very small distances are consumed
 131.336 +						// by the maximum available precision, leading to self-intersecting
 131.337 +						// polygons. This fix makes concave windows fail even worse, but
 131.338 +						// anyway, fail is fail.
 131.339 +						if ((contour[a] - edge).SquareLength() > diag*diag*0.7) {
 131.340 +							continue;
 131.341 +						}
 131.342 +						curmesh.verts.push_back(IfcVector3(contour[a].x, contour[a].y, 0.0f));
 131.343 +					}
 131.344 +
 131.345 +					if (edge != contour[last_hit]) {
 131.346 +
 131.347 +						IfcVector2 corner = edge;
 131.348 +
 131.349 +						if (fabs(contour[last_hit].x-bb.first.x)<epsilon) {
 131.350 +							corner.x = bb.first.x;
 131.351 +						}
 131.352 +						else if (fabs(contour[last_hit].x-bb.second.x)<epsilon) {
 131.353 +							corner.x = bb.second.x;
 131.354 +						}
 131.355 +
 131.356 +						if (fabs(contour[last_hit].y-bb.first.y)<epsilon) {
 131.357 +							corner.y = bb.first.y;
 131.358 +						}
 131.359 +						else if (fabs(contour[last_hit].y-bb.second.y)<epsilon) {
 131.360 +							corner.y = bb.second.y;
 131.361 +						}
 131.362 +
 131.363 +						curmesh.verts.push_back(IfcVector3(corner.x, corner.y, 0.0f));
 131.364 +					}
 131.365 +					else if (cnt == 1) {
 131.366 +						// avoid degenerate polygons (also known as lines or points)
 131.367 +						curmesh.verts.erase(curmesh.verts.begin()+old,curmesh.verts.end());
 131.368 +					}
 131.369 +
 131.370 +					if (const size_t d = curmesh.verts.size()-old) {
 131.371 +						curmesh.vertcnt.push_back(d);
 131.372 +						std::reverse(curmesh.verts.rbegin(),curmesh.verts.rbegin()+d);
 131.373 +					}
 131.374 +					if (n == very_first_hit) {
 131.375 +						break;
 131.376 +					}
 131.377 +				}
 131.378 +				else {
 131.379 +					very_first_hit = n;
 131.380 +				}
 131.381 +
 131.382 +				last_hit = n;
 131.383 +			}
 131.384 +		}
 131.385 +	}
 131.386 +}
 131.387 +
 131.388 +// ------------------------------------------------------------------------------------------------
 131.389 +void MergeWindowContours (const std::vector<IfcVector2>& a, 
 131.390 +	const std::vector<IfcVector2>& b, 
 131.391 +	ClipperLib::ExPolygons& out) 
 131.392 +{
 131.393 +	out.clear();
 131.394 +
 131.395 +	ClipperLib::Clipper clipper;
 131.396 +	ClipperLib::Polygon clip;
 131.397 +
 131.398 +	BOOST_FOREACH(const IfcVector2& pip, a) {
 131.399 +		clip.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
 131.400 +	}
 131.401 +
 131.402 +	if (ClipperLib::Orientation(clip)) {
 131.403 +		std::reverse(clip.begin(), clip.end());
 131.404 +	}
 131.405 +
 131.406 +	clipper.AddPolygon(clip, ClipperLib::ptSubject);
 131.407 +	clip.clear();
 131.408 +
 131.409 +	BOOST_FOREACH(const IfcVector2& pip, b) {
 131.410 +		clip.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
 131.411 +	}
 131.412 +
 131.413 +	if (ClipperLib::Orientation(clip)) {
 131.414 +		std::reverse(clip.begin(), clip.end());
 131.415 +	}
 131.416 +
 131.417 +	clipper.AddPolygon(clip, ClipperLib::ptSubject);
 131.418 +	clipper.Execute(ClipperLib::ctUnion, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
 131.419 +}
 131.420 +
 131.421 +// ------------------------------------------------------------------------------------------------
 131.422 +// Subtract a from b
 131.423 +void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a, 
 131.424 +	const std::vector<IfcVector2>& b, 
 131.425 +	ClipperLib::ExPolygons& out) 
 131.426 +{
 131.427 +	out.clear();
 131.428 +
 131.429 +	ClipperLib::Clipper clipper;
 131.430 +	ClipperLib::Polygon clip;
 131.431 +
 131.432 +	BOOST_FOREACH(const IfcVector2& pip, a) {
 131.433 +		clip.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
 131.434 +	}
 131.435 +
 131.436 +	if (ClipperLib::Orientation(clip)) {
 131.437 +		std::reverse(clip.begin(), clip.end());
 131.438 +	}
 131.439 +
 131.440 +	clipper.AddPolygon(clip, ClipperLib::ptClip);
 131.441 +	clip.clear();
 131.442 +
 131.443 +	BOOST_FOREACH(const IfcVector2& pip, b) {
 131.444 +		clip.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
 131.445 +	}
 131.446 +
 131.447 +	if (ClipperLib::Orientation(clip)) {
 131.448 +		std::reverse(clip.begin(), clip.end());
 131.449 +	}
 131.450 +
 131.451 +	clipper.AddPolygon(clip, ClipperLib::ptSubject);
 131.452 +	clipper.Execute(ClipperLib::ctDifference, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
 131.453 +}
 131.454 +
 131.455 +// ------------------------------------------------------------------------------------------------
 131.456 +void CleanupWindowContour(ProjectedWindowContour& window)
 131.457 +{
 131.458 +	std::vector<IfcVector2> scratch;
 131.459 +	std::vector<IfcVector2>& contour = window.contour;
 131.460 +
 131.461 +	ClipperLib::Polygon subject;
 131.462 +	ClipperLib::Clipper clipper;
 131.463 +	ClipperLib::ExPolygons clipped;
 131.464 +
 131.465 +	BOOST_FOREACH(const IfcVector2& pip, contour) {
 131.466 +		subject.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
 131.467 +	}
 131.468 +
 131.469 +	clipper.AddPolygon(subject,ClipperLib::ptSubject);
 131.470 +	clipper.Execute(ClipperLib::ctUnion,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
 131.471 +
 131.472 +	// This should yield only one polygon or something went wrong 
 131.473 +	if (clipped.size() != 1) {
 131.474 +
 131.475 +		// Empty polygon? drop the contour altogether
 131.476 +		if(clipped.empty()) {
 131.477 +			IFCImporter::LogError("error during polygon clipping, window contour is degenerate");
 131.478 +			window.FlagInvalid();
 131.479 +			return;
 131.480 +		}
 131.481 +
 131.482 +		// Else: take the first only
 131.483 +		IFCImporter::LogError("error during polygon clipping, window contour is not convex");
 131.484 +	}
 131.485 +
 131.486 +	ExtractVerticesFromClipper(clipped[0].outer, scratch);
 131.487 +	// Assume the bounding box doesn't change during this operation
 131.488 +}
 131.489 +
 131.490 +// ------------------------------------------------------------------------------------------------
 131.491 +void CleanupWindowContours(ContourVector& contours)
 131.492 +{
 131.493 +	// Use PolyClipper to clean up window contours
 131.494 +	try {
 131.495 +		BOOST_FOREACH(ProjectedWindowContour& window, contours) {
 131.496 +			CleanupWindowContour(window);
 131.497 +		}
 131.498 +	}
 131.499 +	catch (const char* sx) {
 131.500 +		IFCImporter::LogError("error during polygon clipping, window shape may be wrong: (Clipper: " 
 131.501 +			+ std::string(sx) + ")");
 131.502 +	}
 131.503 +}
 131.504 +
 131.505 +// ------------------------------------------------------------------------------------------------
 131.506 +void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh& curmesh)
 131.507 +{
 131.508 +	std::vector<IfcVector3> vold;
 131.509 +	std::vector<unsigned int> iold;
 131.510 +
 131.511 +	vold.reserve(curmesh.verts.size());
 131.512 +	iold.reserve(curmesh.vertcnt.size());
 131.513 +
 131.514 +	// Fix the outer contour using polyclipper
 131.515 +	try {
 131.516 +
 131.517 +		ClipperLib::Polygon subject;
 131.518 +		ClipperLib::Clipper clipper;
 131.519 +		ClipperLib::ExPolygons clipped;
 131.520 +
 131.521 +		ClipperLib::Polygon clip;
 131.522 +		clip.reserve(contour_flat.size());
 131.523 +		BOOST_FOREACH(const IfcVector2& pip, contour_flat) {
 131.524 +			clip.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
 131.525 +		}
 131.526 +
 131.527 +		if (!ClipperLib::Orientation(clip)) {
 131.528 +			std::reverse(clip.begin(), clip.end());
 131.529 +		}
 131.530 +
 131.531 +		// We need to run polyclipper on every single polygon -- we can't run it one all
 131.532 +		// of them at once or it would merge them all together which would undo all
 131.533 +		// previous steps
 131.534 +		subject.reserve(4);
 131.535 +		size_t index = 0;
 131.536 +		size_t countdown = 0;
 131.537 +		BOOST_FOREACH(const IfcVector3& pip, curmesh.verts) {
 131.538 +			if (!countdown) {
 131.539 +				countdown = curmesh.vertcnt[index++];
 131.540 +				if (!countdown) {
 131.541 +					continue;
 131.542 +				}
 131.543 +			}
 131.544 +			subject.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
 131.545 +			if (--countdown == 0) {
 131.546 +				if (!ClipperLib::Orientation(subject)) {
 131.547 +					std::reverse(subject.begin(), subject.end());
 131.548 +				}
 131.549 +
 131.550 +				clipper.AddPolygon(subject,ClipperLib::ptSubject);
 131.551 +				clipper.AddPolygon(clip,ClipperLib::ptClip);
 131.552 +
 131.553 +				clipper.Execute(ClipperLib::ctIntersection,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
 131.554 +
 131.555 +				BOOST_FOREACH(const ClipperLib::ExPolygon& ex, clipped) {
 131.556 +					iold.push_back(ex.outer.size());
 131.557 +					BOOST_FOREACH(const ClipperLib::IntPoint& point, ex.outer) {
 131.558 +						vold.push_back(IfcVector3(
 131.559 +							from_int64(point.X), 
 131.560 +							from_int64(point.Y),
 131.561 +							0.0f));
 131.562 +					}
 131.563 +				}
 131.564 +
 131.565 +				subject.clear();
 131.566 +				clipped.clear();
 131.567 +				clipper.Clear();
 131.568 +			}
 131.569 +		}
 131.570 +	}
 131.571 +	catch (const char* sx) {
 131.572 +		IFCImporter::LogError("Ifc: error during polygon clipping, wall contour line may be wrong: (Clipper: " 
 131.573 +			+ std::string(sx) + ")");
 131.574 +
 131.575 +		return;
 131.576 +	}
 131.577 +
 131.578 +	// swap data arrays
 131.579 +	std::swap(vold,curmesh.verts);
 131.580 +	std::swap(iold,curmesh.vertcnt);
 131.581 +}
 131.582 +
 131.583 +typedef std::vector<TempOpening*> OpeningRefs;
 131.584 +typedef std::vector<OpeningRefs > OpeningRefVector;
 131.585 +
 131.586 +typedef std::vector<std::pair<
 131.587 +	ContourVector::const_iterator, 
 131.588 +	Contour::const_iterator> 
 131.589 +> ContourRefVector; 
 131.590 +
 131.591 +// ------------------------------------------------------------------------------------------------
 131.592 +bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb)
 131.593 +{
 131.594 +	// TODO: I'm pretty sure there is a much more compact way to check this
 131.595 +	const IfcFloat epsilon = 1e-5f;
 131.596 +	return	(fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
 131.597 +		(fabs(bb.first.x - ibb.second.x) < epsilon && ibb.first.y <= bb.second.y && ibb.second.y >= bb.first.y) || 
 131.598 +		(fabs(bb.second.y - ibb.first.y) < epsilon && bb.first.x <= ibb.second.x && bb.second.x >= ibb.first.x) ||
 131.599 +		(fabs(bb.first.y - ibb.second.y) < epsilon && ibb.first.x <= bb.second.x && ibb.second.x >= bb.first.x);
 131.600 +}
 131.601 +
 131.602 +// ------------------------------------------------------------------------------------------------
 131.603 +// Check if m0,m1 intersects n0,n1 assuming same ordering of the points in the line segments
 131.604 +// output the intersection points on n0,n1
 131.605 +bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1, 
 131.606 +	const IfcVector2& m0, const IfcVector2& m1,
 131.607 +	IfcVector2& out0, IfcVector2& out1)
 131.608 +{
 131.609 +	const IfcVector2& n0_to_n1 = n1 - n0;
 131.610 +
 131.611 +	const IfcVector2& n0_to_m0 = m0 - n0;
 131.612 +	const IfcVector2& n1_to_m1 = m1 - n1;
 131.613 +
 131.614 +	const IfcVector2& n0_to_m1 = m1 - n0;
 131.615 +
 131.616 +	const IfcFloat e = 1e-5f;
 131.617 +	const IfcFloat smalle = 1e-9f;
 131.618 +
 131.619 +	static const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity();
 131.620 +
 131.621 +	if (!(n0_to_m0.SquareLength() < e*e || fabs(n0_to_m0 * n0_to_n1) / (n0_to_m0.Length() * n0_to_n1.Length()) > 1-1e-5 )) {
 131.622 +		return false;
 131.623 +	}
 131.624 +
 131.625 +	if (!(n1_to_m1.SquareLength() < e*e || fabs(n1_to_m1 * n0_to_n1) / (n1_to_m1.Length() * n0_to_n1.Length()) > 1-1e-5 )) {
 131.626 +		return false;
 131.627 +	}
 131.628 +
 131.629 +	IfcFloat s0;
 131.630 +	IfcFloat s1;
 131.631 +
 131.632 +	// pick the axis with the higher absolute difference so the result
 131.633 +	// is more accurate. Since we cannot guarantee that the axis with
 131.634 +	// the higher absolute difference is big enough as to avoid
 131.635 +	// divisions by zero, the case 0/0 ~ infinity is detected and
 131.636 +	// handled separately.
 131.637 +	if(fabs(n0_to_n1.x) > fabs(n0_to_n1.y)) {
 131.638 +		s0 = n0_to_m0.x / n0_to_n1.x;
 131.639 +		s1 = n0_to_m1.x / n0_to_n1.x;
 131.640 +
 131.641 +		if (fabs(s0) == inf && fabs(n0_to_m0.x) < smalle) {
 131.642 +			s0 = 0.;
 131.643 +		}
 131.644 +		if (fabs(s1) == inf && fabs(n0_to_m1.x) < smalle) {
 131.645 +			s1 = 0.;
 131.646 +		}
 131.647 +	}
 131.648 +	else {
 131.649 +		s0 = n0_to_m0.y / n0_to_n1.y;
 131.650 +		s1 = n0_to_m1.y / n0_to_n1.y;
 131.651 +
 131.652 +		if (fabs(s0) == inf && fabs(n0_to_m0.y) < smalle) {
 131.653 +			s0 = 0.;
 131.654 +		}
 131.655 +		if (fabs(s1) == inf && fabs(n0_to_m1.y) < smalle) {
 131.656 +			s1 = 0.;
 131.657 +		}
 131.658 +	}
 131.659 +
 131.660 +	if (s1 < s0) {
 131.661 +		std::swap(s1,s0);
 131.662 +	}
 131.663 +
 131.664 +	s0 = std::max(0.0,s0);
 131.665 +	s1 = std::max(0.0,s1);
 131.666 +
 131.667 +	s0 = std::min(1.0,s0);
 131.668 +	s1 = std::min(1.0,s1);
 131.669 +
 131.670 +	if (fabs(s1-s0) < e) {
 131.671 +		return false;
 131.672 +	}
 131.673 +
 131.674 +	out0 = n0 + s0 * n0_to_n1;
 131.675 +	out1 = n0 + s1 * n0_to_n1;
 131.676 +
 131.677 +	return true;
 131.678 +}
 131.679 +
 131.680 +// ------------------------------------------------------------------------------------------------
 131.681 +void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours)
 131.682 +{
 131.683 +	const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(1e-8);
 131.684 +	const BoundingBox& bb = (*current).bb;
 131.685 +
 131.686 +	// What is to be done here is to populate the skip lists for the contour
 131.687 +	// and to add necessary padding points when needed.
 131.688 +	SkipList& skiplist = (*current).skiplist;
 131.689 +
 131.690 +	// First step to find possible adjacent contours is to check for adjacent bounding
 131.691 +	// boxes. If the bounding boxes are not adjacent, the contours lines cannot possibly be.
 131.692 +	for (ContourVector::const_iterator it = contours.begin(), end = contours.end(); it != end; ++it) {
 131.693 +		if ((*it).IsInvalid()) {
 131.694 +			continue;
 131.695 +		}
 131.696 +
 131.697 +		// this left here to make clear we also run on the current contour
 131.698 +		// to check for overlapping contour segments (which can happen due
 131.699 +		// to projection artifacts).
 131.700 +		//if(it == current) {
 131.701 +		//	continue;
 131.702 +		//}
 131.703 +
 131.704 +		const bool is_me = it == current;
 131.705 +
 131.706 +		const BoundingBox& ibb = (*it).bb;
 131.707 +
 131.708 +		// Assumption: the bounding boxes are pairwise disjoint or identical
 131.709 +		ai_assert(is_me || !BoundingBoxesOverlapping(bb, ibb));
 131.710 +
 131.711 +		if (is_me || BoundingBoxesAdjacent(bb, ibb)) {
 131.712 +
 131.713 +			// Now do a each-against-everyone check for intersecting contour
 131.714 +			// lines. This obviously scales terribly, but in typical real
 131.715 +			// world Ifc files it will not matter since most windows that
 131.716 +			// are adjacent to each others are rectangular anyway.
 131.717 +
 131.718 +			Contour& ncontour = (*current).contour;
 131.719 +			const Contour& mcontour = (*it).contour;
 131.720 +
 131.721 +			for (size_t n = 0; n < ncontour.size(); ++n) {
 131.722 +				const IfcVector2& n0 = ncontour[n];
 131.723 +				const IfcVector2& n1 = ncontour[(n+1) % ncontour.size()];
 131.724 +
 131.725 +				for (size_t m = 0, mend = (is_me ? n : mcontour.size()); m < mend; ++m) {
 131.726 +					ai_assert(&mcontour != &ncontour || m < n);
 131.727 +
 131.728 +					const IfcVector2& m0 = mcontour[m];
 131.729 +					const IfcVector2& m1 = mcontour[(m+1) % mcontour.size()];
 131.730 +
 131.731 +					IfcVector2 isect0, isect1;
 131.732 +					if (IntersectingLineSegments(n0,n1, m0, m1, isect0, isect1)) {
 131.733 +
 131.734 +						if ((isect0 - n0).SquareLength() > sqlen_epsilon) {
 131.735 +							++n;
 131.736 +
 131.737 +							ncontour.insert(ncontour.begin() + n, isect0);	
 131.738 +							skiplist.insert(skiplist.begin() + n, true);
 131.739 +						}
 131.740 +						else {
 131.741 +							skiplist[n] = true;
 131.742 +						}
 131.743 +
 131.744 +						if ((isect1 - n1).SquareLength() > sqlen_epsilon) {
 131.745 +							++n;
 131.746 +
 131.747 +							ncontour.insert(ncontour.begin() + n, isect1);
 131.748 +							skiplist.insert(skiplist.begin() + n, false);
 131.749 +						}
 131.750 +					}
 131.751 +				}
 131.752 +			}
 131.753 +		}
 131.754 +	}
 131.755 +}
 131.756 +
 131.757 +// ------------------------------------------------------------------------------------------------
 131.758 +AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta)
 131.759 +{
 131.760 +	const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(1e-5);
 131.761 +	return fabs(vdelta.x * vdelta.y) < dot_point_epsilon;
 131.762 +}
 131.763 +
 131.764 +// ------------------------------------------------------------------------------------------------
 131.765 +void FindBorderContours(ContourVector::iterator current)
 131.766 +{
 131.767 +	const IfcFloat border_epsilon_upper = static_cast<IfcFloat>(1-1e-4);
 131.768 +	const IfcFloat border_epsilon_lower = static_cast<IfcFloat>(1e-4);
 131.769 +
 131.770 +	bool outer_border = false;
 131.771 +	bool start_on_outer_border = false;
 131.772 +
 131.773 +	SkipList& skiplist = (*current).skiplist;
 131.774 +	IfcVector2 last_proj_point;
 131.775 +
 131.776 +	const Contour::const_iterator cbegin = (*current).contour.begin(), cend = (*current).contour.end();
 131.777 +
 131.778 +	for (Contour::const_iterator cit = cbegin; cit != cend; ++cit) {
 131.779 +		const IfcVector2& proj_point = *cit;
 131.780 +
 131.781 +		// Check if this connection is along the outer boundary of the projection
 131.782 +		// plane. In such a case we better drop it because such 'edges' should
 131.783 +		// not have any geometry to close them (think of door openings).
 131.784 +		if (proj_point.x <= border_epsilon_lower || proj_point.x >= border_epsilon_upper ||
 131.785 +			proj_point.y <= border_epsilon_lower || proj_point.y >= border_epsilon_upper) {
 131.786 +
 131.787 +				if (outer_border) {
 131.788 +					ai_assert(cit != cbegin);
 131.789 +					if (LikelyBorder(proj_point - last_proj_point)) {
 131.790 +						skiplist[std::distance(cbegin, cit) - 1] = true;
 131.791 +					}
 131.792 +				}
 131.793 +				else if (cit == cbegin) {
 131.794 +					start_on_outer_border = true;
 131.795 +				}
 131.796 +		
 131.797 +				outer_border = true;
 131.798 +		}
 131.799 +		else {
 131.800 +			outer_border = false;
 131.801 +		}
 131.802 +
 131.803 +		last_proj_point = proj_point;
 131.804 +	}
 131.805 +
 131.806 +	// handle last segment
 131.807 +	if (outer_border && start_on_outer_border) {
 131.808 +		const IfcVector2& proj_point = *cbegin;
 131.809 +		if (LikelyBorder(proj_point - last_proj_point)) {
 131.810 +			skiplist[skiplist.size()-1] = true;
 131.811 +		}
 131.812 +	}
 131.813 +}
 131.814 +
 131.815 +// ------------------------------------------------------------------------------------------------
 131.816 +AI_FORCE_INLINE bool LikelyDiagonal(IfcVector2 vdelta)
 131.817 +{
 131.818 +	vdelta.x = fabs(vdelta.x);
 131.819 +	vdelta.y = fabs(vdelta.y);
 131.820 +	return (fabs(vdelta.x-vdelta.y) < 0.8 * std::max(vdelta.x, vdelta.y));
 131.821 +}
 131.822 +
 131.823 +// ------------------------------------------------------------------------------------------------
 131.824 +void FindLikelyCrossingLines(ContourVector::iterator current)
 131.825 +{
 131.826 +	SkipList& skiplist = (*current).skiplist;
 131.827 +	IfcVector2 last_proj_point;
 131.828 +
 131.829 +	const Contour::const_iterator cbegin = (*current).contour.begin(), cend = (*current).contour.end();
 131.830 +	for (Contour::const_iterator cit = cbegin; cit != cend; ++cit) {
 131.831 +		const IfcVector2& proj_point = *cit;
 131.832 +
 131.833 +		if (cit != cbegin) {
 131.834 +			IfcVector2 vdelta = proj_point - last_proj_point;
 131.835 +			if (LikelyDiagonal(vdelta)) {
 131.836 +				skiplist[std::distance(cbegin, cit) - 1] = true;
 131.837 +			}
 131.838 +		} 
 131.839 +
 131.840 +		last_proj_point = proj_point;
 131.841 +	}
 131.842 +
 131.843 +	// handle last segment
 131.844 +	if (LikelyDiagonal(*cbegin - last_proj_point)) {
 131.845 +		skiplist[skiplist.size()-1] = true;
 131.846 +	}
 131.847 +}
 131.848 +
 131.849 +// ------------------------------------------------------------------------------------------------
 131.850 +size_t CloseWindows(ContourVector& contours, 		  
 131.851 +	const IfcMatrix4& minv, 
 131.852 +	OpeningRefVector& contours_to_openings, 
 131.853 +	TempMesh& curmesh)
 131.854 +{
 131.855 +	size_t closed = 0;
 131.856 +	// For all contour points, check if one of the assigned openings does
 131.857 +	// already have points assigned to it. In this case, assume this is
 131.858 +	// the other side of the wall and generate connections between
 131.859 +	// the two holes in order to close the window. 
 131.860 +
 131.861 +	// All this gets complicated by the fact that contours may pertain to
 131.862 +	// multiple openings(due to merging of adjacent or overlapping openings). 
 131.863 +	// The code is based on the assumption that this happens symmetrically
 131.864 +	// on both sides of the wall. If it doesn't (which would be a bug anyway)
 131.865 +	// wrong geometry may be generated.
 131.866 +	for (ContourVector::iterator it = contours.begin(), end = contours.end(); it != end; ++it) {
 131.867 +		if ((*it).IsInvalid()) {
 131.868 +			continue;
 131.869 +		}
 131.870 +		OpeningRefs& refs = contours_to_openings[std::distance(contours.begin(), it)];
 131.871 +
 131.872 +		bool has_other_side = false;
 131.873 +		BOOST_FOREACH(const TempOpening* opening, refs) {
 131.874 +			if(!opening->wallPoints.empty()) {
 131.875 +				has_other_side = true;
 131.876 +				break;
 131.877 +			}
 131.878 +		}
 131.879 +
 131.880 +		if (has_other_side) {
 131.881 +
 131.882 +			ContourRefVector adjacent_contours;
 131.883 +
 131.884 +			// prepare a skiplist for this contour. The skiplist is used to
 131.885 +			// eliminate unwanted contour lines for adjacent windows and
 131.886 +			// those bordering the outer frame.
 131.887 +			(*it).PrepareSkiplist();
 131.888 +
 131.889 +			FindAdjacentContours(it, contours);
 131.890 +			FindBorderContours(it);
 131.891 +
 131.892 +			// if the window is the result of a finite union or intersection of rectangles,
 131.893 +			// there shouldn't be any crossing or diagonal lines in it. Such lines would
 131.894 +			// be artifacts caused by numerical inaccuracies or other bugs in polyclipper
 131.895 +			// and our own code. Since rectangular openings are by far the most frequent
 131.896 +			// case, it is worth filtering for this corner case.
 131.897 +			if((*it).is_rectangular) {
 131.898 +				FindLikelyCrossingLines(it);
 131.899 +			}
 131.900 +
 131.901 +			ai_assert((*it).skiplist.size() == (*it).contour.size());
 131.902 +
 131.903 +			SkipList::const_iterator skipbegin = (*it).skiplist.begin();
 131.904 +
 131.905 +			curmesh.verts.reserve(curmesh.verts.size() + (*it).contour.size() * 4);
 131.906 +			curmesh.vertcnt.reserve(curmesh.vertcnt.size() + (*it).contour.size());
 131.907 +
 131.908 +			// XXX this algorithm is really a bit inefficient - both in terms
 131.909 +			// of constant factor and of asymptotic runtime.
 131.910 +			std::vector<bool>::const_iterator skipit = skipbegin;
 131.911 +
 131.912 +			IfcVector3 start0;
 131.913 +			IfcVector3 start1;
 131.914 +
 131.915 +			IfcVector2 last_proj; 
 131.916 +			//const IfcVector2& first_proj; 
 131.917 +
 131.918 +			const Contour::const_iterator cbegin = (*it).contour.begin(), cend = (*it).contour.end();
 131.919 +
 131.920 +			bool drop_this_edge = false;
 131.921 +			for (Contour::const_iterator cit = cbegin; cit != cend; ++cit, drop_this_edge = *skipit++) {
 131.922 +				const IfcVector2& proj_point = *cit;
 131.923 +
 131.924 +				// Locate the closest opposite point. This should be a good heuristic to
 131.925 +				// connect only the points that are really intended to be connected.
 131.926 +				IfcFloat best = static_cast<IfcFloat>(1e10);
 131.927 +				IfcVector3 bestv;
 131.928 +
 131.929 +				/* debug code to check for unwanted diagonal lines in window contours
 131.930 +				if (cit != cbegin) {
 131.931 +					const IfcVector2& vdelta = proj_point - last_proj;
 131.932 +					if (fabs(vdelta.x-vdelta.y) < 0.5 * std::max(vdelta.x, vdelta.y)) {
 131.933 +						//continue;
 131.934 +					}
 131.935 +				} */
 131.936 +
 131.937 +				const IfcVector3& world_point = minv * IfcVector3(proj_point.x,proj_point.y,0.0f);
 131.938 +				
 131.939 +				last_proj = proj_point;
 131.940 +
 131.941 +				BOOST_FOREACH(const TempOpening* opening, refs) {
 131.942 +					BOOST_FOREACH(const IfcVector3& other, opening->wallPoints) {
 131.943 +						const IfcFloat sqdist = (world_point - other).SquareLength();
 131.944 +						
 131.945 +						if (sqdist < best) {
 131.946 +							// avoid self-connections
 131.947 +							if(sqdist < 1e-5) {
 131.948 +								continue;
 131.949 +							}
 131.950 +
 131.951 +							bestv = other;
 131.952 +							best = sqdist;							
 131.953 +						}
 131.954 +					}
 131.955 +				}
 131.956 +
 131.957 +				if (drop_this_edge) {
 131.958 +					curmesh.verts.pop_back();
 131.959 +					curmesh.verts.pop_back();
 131.960 +				}
 131.961 +				else {
 131.962 +					curmesh.verts.push_back(cit == cbegin ? world_point : bestv);
 131.963 +					curmesh.verts.push_back(cit == cbegin ? bestv : world_point);
 131.964 +
 131.965 +					curmesh.vertcnt.push_back(4);
 131.966 +					++closed;
 131.967 +				}
 131.968 +
 131.969 +				if (cit == cbegin) {
 131.970 +					start0 = world_point;
 131.971 +					start1 = bestv;
 131.972 +					continue;
 131.973 +				}
 131.974 +
 131.975 +				curmesh.verts.push_back(world_point);
 131.976 +				curmesh.verts.push_back(bestv);
 131.977 +
 131.978 +				if (cit == cend - 1) {
 131.979 +					drop_this_edge = *skipit;
 131.980 +
 131.981 +					// Check if the final connection (last to first element) is itself
 131.982 +					// a border edge that needs to be dropped.
 131.983 +					if (drop_this_edge) {
 131.984 +						--closed;
 131.985 +						curmesh.vertcnt.pop_back();
 131.986 +						curmesh.verts.pop_back();
 131.987 +						curmesh.verts.pop_back();
 131.988 +					}
 131.989 +					else {
 131.990 +						curmesh.verts.push_back(start1);
 131.991 +						curmesh.verts.push_back(start0);
 131.992 +					}
 131.993 +				}
 131.994 +			}
 131.995 +			/*
 131.996 +			BOOST_FOREACH(TempOpening* opening, refs) {
 131.997 +				//opening->wallPoints.clear();
 131.998 +			}*/
 131.999 +
131.1000 +		}
131.1001 +		else {
131.1002 +			
131.1003 +			const Contour::const_iterator cbegin = (*it).contour.begin(), cend = (*it).contour.end();
131.1004 +			BOOST_FOREACH(TempOpening* opening, refs) {
131.1005 +				ai_assert(opening->wallPoints.empty());
131.1006 +				opening->wallPoints.reserve(opening->wallPoints.capacity() + (*it).contour.size());
131.1007 +				for (Contour::const_iterator cit = cbegin; cit != cend; ++cit) {
131.1008 +
131.1009 +					const IfcVector2& proj_point = *cit;
131.1010 +					opening->wallPoints.push_back(minv * IfcVector3(proj_point.x,proj_point.y,0.0f));
131.1011 +				}
131.1012 +			}
131.1013 +		}
131.1014 +	}
131.1015 +	return closed;
131.1016 +}
131.1017 +
131.1018 +// ------------------------------------------------------------------------------------------------
131.1019 +void Quadrify(const std::vector< BoundingBox >& bbs, TempMesh& curmesh)
131.1020 +{
131.1021 +	ai_assert(curmesh.IsEmpty());
131.1022 +
131.1023 +	std::vector<IfcVector2> quads;
131.1024 +	quads.reserve(bbs.size()*4);
131.1025 +
131.1026 +	// sort openings by x and y axis as a preliminiary to the QuadrifyPart() algorithm
131.1027 +	XYSortedField field;
131.1028 +	for (std::vector<BoundingBox>::const_iterator it = bbs.begin(); it != bbs.end(); ++it) {
131.1029 +		if (field.find((*it).first) != field.end()) {
131.1030 +			IFCImporter::LogWarn("constraint failure during generation of wall openings, results may be faulty");
131.1031 +		}
131.1032 +		field[(*it).first] = std::distance(bbs.begin(),it);
131.1033 +	}
131.1034 +
131.1035 +	QuadrifyPart(IfcVector2(),one_vec,field,bbs,quads);
131.1036 +	ai_assert(!(quads.size() % 4));
131.1037 +
131.1038 +	curmesh.vertcnt.resize(quads.size()/4,4);
131.1039 +	curmesh.verts.reserve(quads.size());
131.1040 +	BOOST_FOREACH(const IfcVector2& v2, quads) {
131.1041 +		curmesh.verts.push_back(IfcVector3(v2.x, v2.y, static_cast<IfcFloat>(0.0)));
131.1042 +	}
131.1043 +}
131.1044 +
131.1045 +// ------------------------------------------------------------------------------------------------
131.1046 +void Quadrify(const ContourVector& contours, TempMesh& curmesh)
131.1047 +{
131.1048 +	std::vector<BoundingBox> bbs;
131.1049 +	bbs.reserve(contours.size());
131.1050 +
131.1051 +	BOOST_FOREACH(const ContourVector::value_type& val, contours) {
131.1052 +		bbs.push_back(val.bb);
131.1053 +	}
131.1054 +
131.1055 +	Quadrify(bbs, curmesh);
131.1056 +}
131.1057 +
131.1058 +// ------------------------------------------------------------------------------------------------
131.1059 +IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh& in_mesh, 
131.1060 +	bool &ok, IfcVector3& nor_out)
131.1061 +{
131.1062 +	const std::vector<IfcVector3>& in_verts = in_mesh.verts;
131.1063 +	ok = true;
131.1064 +
131.1065 +	IfcMatrix4 m = IfcMatrix4(DerivePlaneCoordinateSpace(in_mesh, ok, nor_out));
131.1066 +	if(!ok) {
131.1067 +		return IfcMatrix4();
131.1068 +	}
131.1069 +#ifdef _DEBUG
131.1070 +	const IfcFloat det = m.Determinant();
131.1071 +	ai_assert(fabs(det-1) < 1e-5);
131.1072 +#endif
131.1073 +
131.1074 +	IfcFloat zcoord = 0;
131.1075 +	out_contour.reserve(in_verts.size());
131.1076 +
131.1077 +
131.1078 +	IfcVector3 vmin, vmax;
131.1079 +	MinMaxChooser<IfcVector3>()(vmin, vmax);
131.1080 +
131.1081 +	// Project all points into the new coordinate system, collect min/max verts on the way
131.1082 +	BOOST_FOREACH(const IfcVector3& x, in_verts) {
131.1083 +		const IfcVector3& vv = m * x;
131.1084 +		// keep Z offset in the plane coordinate system. Ignoring precision issues
131.1085 +		// (which  are present, of course), this should be the same value for
131.1086 +		// all polygon vertices (assuming the polygon is planar).
131.1087 +
131.1088 +		// XXX this should be guarded, but we somehow need to pick a suitable
131.1089 +		// epsilon
131.1090 +		// if(coord != -1.0f) {
131.1091 +		//	assert(fabs(coord - vv.z) < 1e-3f);
131.1092 +		// }
131.1093 +		zcoord += vv.z;
131.1094 +		vmin = std::min(vv, vmin);
131.1095 +		vmax = std::max(vv, vmax);
131.1096 +
131.1097 +		out_contour.push_back(IfcVector2(vv.x,vv.y));
131.1098 +	}
131.1099 +
131.1100 +	zcoord /= in_verts.size();
131.1101 +
131.1102 +	// Further improve the projection by mapping the entire working set into
131.1103 +	// [0,1] range. This gives us a consistent data range so all epsilons
131.1104 +	// used below can be constants.
131.1105 +	vmax -= vmin;
131.1106 +	BOOST_FOREACH(IfcVector2& vv, out_contour) {
131.1107 +		vv.x  = (vv.x - vmin.x) / vmax.x;
131.1108 +		vv.y  = (vv.y - vmin.y) / vmax.y;
131.1109 +
131.1110 +		// sanity rounding
131.1111 +		vv = std::max(vv,IfcVector2());
131.1112 +		vv = std::min(vv,one_vec);
131.1113 +	}
131.1114 +
131.1115 +	IfcMatrix4 mult;
131.1116 +	mult.a1 = static_cast<IfcFloat>(1.0) / vmax.x;
131.1117 +	mult.b2 = static_cast<IfcFloat>(1.0) / vmax.y;
131.1118 +
131.1119 +	mult.a4 = -vmin.x * mult.a1;
131.1120 +	mult.b4 = -vmin.y * mult.b2;
131.1121 +	mult.c4 = -zcoord;
131.1122 +	m = mult * m;
131.1123 +
131.1124 +	// debug code to verify correctness
131.1125 +#ifdef _DEBUG
131.1126 +	std::vector<IfcVector2> out_contour2;
131.1127 +	BOOST_FOREACH(const IfcVector3& x, in_verts) {
131.1128 +		const IfcVector3& vv = m * x;
131.1129 +
131.1130 +		out_contour2.push_back(IfcVector2(vv.x,vv.y));
131.1131 +		ai_assert(fabs(vv.z) < vmax.z + 1e-8);
131.1132 +	} 
131.1133 +
131.1134 +	for(size_t i = 0; i < out_contour.size(); ++i) {
131.1135 +		ai_assert((out_contour[i]-out_contour2[i]).SquareLength() < 1e-6);
131.1136 +	}
131.1137 +#endif
131.1138 +
131.1139 +	return m;
131.1140 +}
131.1141 +
131.1142 +// ------------------------------------------------------------------------------------------------
131.1143 +bool GenerateOpenings(std::vector<TempOpening>& openings,
131.1144 +	const std::vector<IfcVector3>& nors, 
131.1145 +	TempMesh& curmesh,
131.1146 +	bool check_intersection,
131.1147 +	bool generate_connection_geometry,
131.1148 +	const IfcVector3& wall_extrusion_axis)
131.1149 +{
131.1150 +	OpeningRefVector contours_to_openings;
131.1151 +
131.1152 +	// Try to derive a solid base plane within the current surface for use as 
131.1153 +	// working coordinate system. Map all vertices onto this plane and 
131.1154 +	// rescale them to [0,1] range. This normalization means all further
131.1155 +	// epsilons need not be scaled.
131.1156 +	bool ok = true;
131.1157 +
131.1158 +	std::vector<IfcVector2> contour_flat;
131.1159 +
131.1160 +	IfcVector3 nor;
131.1161 +	const IfcMatrix4& m = ProjectOntoPlane(contour_flat, curmesh,  ok, nor);
131.1162 +	if(!ok) {
131.1163 +		return false;
131.1164 +	}
131.1165 +
131.1166 +	// Obtain inverse transform for getting back to world space later on
131.1167 +	const IfcMatrix4 minv = IfcMatrix4(m).Inverse();
131.1168 +
131.1169 +	// Compute bounding boxes for all 2D openings in projection space
131.1170 +	ContourVector contours;
131.1171 +
131.1172 +	std::vector<IfcVector2> temp_contour;
131.1173 +	std::vector<IfcVector2> temp_contour2;
131.1174 +
131.1175 +	IfcVector3 wall_extrusion_axis_norm = wall_extrusion_axis;
131.1176 +	wall_extrusion_axis_norm.Normalize();
131.1177 +
131.1178 +	BOOST_FOREACH(TempOpening& opening,openings) {
131.1179 +
131.1180 +		// extrusionDir may be 0,0,0 on case where the opening mesh is not an
131.1181 +		// IfcExtrudedAreaSolid but something else (i.e. a brep)
131.1182 +		IfcVector3 norm_extrusion_dir = opening.extrusionDir;
131.1183 +		if (norm_extrusion_dir.SquareLength() > 1e-10) {
131.1184 +			norm_extrusion_dir.Normalize();
131.1185 +		}
131.1186 +		else {
131.1187 +			norm_extrusion_dir = IfcVector3();
131.1188 +		}
131.1189 +
131.1190 +		TempMesh* profile_data =  opening.profileMesh.get();
131.1191 +		bool is_2d_source = false;
131.1192 +		if (opening.profileMesh2D && norm_extrusion_dir.SquareLength() > 0) {
131.1193 +			
131.1194 +			if(fabs(norm_extrusion_dir * wall_extrusion_axis_norm) < 0.1) {
131.1195 +				// horizontal extrusion
131.1196 +				if (fabs(norm_extrusion_dir * nor) > 0.9) {
131.1197 +					profile_data = opening.profileMesh2D.get();
131.1198 +					is_2d_source = true;
131.1199 +				}
131.1200 +				else {
131.1201 +					//continue;
131.1202 +				}
131.1203 +			}
131.1204 +			else {
131.1205 +				// vertical extrusion
131.1206 +				if (fabs(norm_extrusion_dir * nor) > 0.9) {
131.1207 +					continue;
131.1208 +				}
131.1209 +				continue;
131.1210 +			}
131.1211 +		}
131.1212 +		std::vector<IfcVector3> profile_verts = profile_data->verts;
131.1213 +		std::vector<unsigned int> profile_vertcnts = profile_data->vertcnt;
131.1214 +		if(profile_verts.size() <= 2) {
131.1215 +			continue;	
131.1216 +		}	
131.1217 +
131.1218 +		// The opening meshes are real 3D meshes so skip over all faces
131.1219 +		// clearly facing into the wrong direction. Also, we need to check
131.1220 +		// whether the meshes do actually intersect the base surface plane.
131.1221 +		// This is done by recording minimum and maximum values for the
131.1222 +		// d component of the plane equation for all polys and checking
131.1223 +		// against surface d.
131.1224 +
131.1225 +		// Use the sign of the dot product of the face normal to the plane
131.1226 +		// normal to determine to which side of the difference mesh a
131.1227 +		// triangle belongs. Get independent bounding boxes and vertex
131.1228 +		// sets for both sides and take the better one (we can't just
131.1229 +		// take both - this would likely cause major screwup of vertex
131.1230 +		// winding, producing errors as late as in CloseWindows()).
131.1231 +		IfcFloat dmin, dmax;
131.1232 +		MinMaxChooser<IfcFloat>()(dmin,dmax);
131.1233 +
131.1234 +		temp_contour.clear();
131.1235 +		temp_contour2.clear();
131.1236 +
131.1237 +		IfcVector2 vpmin,vpmax;
131.1238 +		MinMaxChooser<IfcVector2>()(vpmin,vpmax);
131.1239 +
131.1240 +		IfcVector2 vpmin2,vpmax2;
131.1241 +		MinMaxChooser<IfcVector2>()(vpmin2,vpmax2);
131.1242 +
131.1243 +		for (size_t f = 0, vi_total = 0, fend = profile_vertcnts.size(); f < fend; ++f) {
131.1244 +
131.1245 +			bool side_flag = true;
131.1246 +			if (!is_2d_source) {
131.1247 +				const IfcVector3& face_nor = ((profile_verts[vi_total+2] - profile_verts[vi_total]) ^
131.1248 +					(profile_verts[vi_total+1] - profile_verts[vi_total])).Normalize();
131.1249 +
131.1250 +				const IfcFloat abs_dot_face_nor = abs(nor * face_nor);
131.1251 +				if (abs_dot_face_nor < 0.9) {
131.1252 +					vi_total += profile_vertcnts[f];
131.1253 +					continue;
131.1254 +				}
131.1255 +
131.1256 +				side_flag = nor * face_nor > 0;
131.1257 +			}
131.1258 +
131.1259 +			for (unsigned int vi = 0, vend = profile_vertcnts[f]; vi < vend; ++vi, ++vi_total) {
131.1260 +				const IfcVector3& x = profile_verts[vi_total];
131.1261 +
131.1262 +				const IfcVector3& v = m * x;
131.1263 +				IfcVector2 vv(v.x, v.y);
131.1264 +
131.1265 +				//if(check_intersection) {
131.1266 +					dmin = std::min(dmin, v.z);
131.1267 +					dmax = std::max(dmax, v.z);
131.1268 +				//}
131.1269 +
131.1270 +				// sanity rounding
131.1271 +				vv = std::max(vv,IfcVector2());
131.1272 +				vv = std::min(vv,one_vec);
131.1273 +
131.1274 +				if(side_flag) {
131.1275 +					vpmin = std::min(vpmin,vv);
131.1276 +					vpmax = std::max(vpmax,vv);
131.1277 +				}
131.1278 +				else {
131.1279 +					vpmin2 = std::min(vpmin2,vv);
131.1280 +					vpmax2 = std::max(vpmax2,vv);
131.1281 +				}
131.1282 +
131.1283 +				std::vector<IfcVector2>& store = side_flag ? temp_contour : temp_contour2;
131.1284 +
131.1285 +				if (!IsDuplicateVertex(vv, store)) {
131.1286 +					store.push_back(vv);
131.1287 +				}		
131.1288 +			}
131.1289 +		}
131.1290 +
131.1291 +		if (temp_contour2.size() > 2) {
131.1292 +			ai_assert(!is_2d_source);
131.1293 +			const IfcVector2 area = vpmax-vpmin;
131.1294 +			const IfcVector2 area2 = vpmax2-vpmin2;
131.1295 +			if (temp_contour.size() <= 2 || fabs(area2.x * area2.y) > fabs(area.x * area.y)) {
131.1296 +				temp_contour.swap(temp_contour2);
131.1297 +
131.1298 +				vpmax = vpmax2;
131.1299 +				vpmin = vpmin2;			
131.1300 +			}
131.1301 +		}
131.1302 +		if(temp_contour.size() <= 2) {
131.1303 +			continue;
131.1304 +		}
131.1305 +
131.1306 +		// TODO: This epsilon may be too large
131.1307 +		const IfcFloat epsilon = fabs(dmax-dmin) * 0.0001;
131.1308 +		if (!is_2d_source && check_intersection && (0 < dmin-epsilon || 0 > dmax+epsilon)) {
131.1309 +			continue;
131.1310 +		}
131.1311 +
131.1312 +		BoundingBox bb = BoundingBox(vpmin,vpmax);
131.1313 +
131.1314 +		// Skip over very small openings - these are likely projection errors
131.1315 +		// (i.e. they don't belong to this side of the wall)
131.1316 +		if(fabs(vpmax.x - vpmin.x) * fabs(vpmax.y - vpmin.y) < static_cast<IfcFloat>(1e-10)) {
131.1317 +			continue;
131.1318 +		}
131.1319 +		std::vector<TempOpening*> joined_openings(1, &opening);
131.1320 +
131.1321 +		bool is_rectangle = temp_contour.size() == 4;
131.1322 +
131.1323 +		// See if this BB intersects or is in close adjacency to any other BB we have so far.
131.1324 +		for (ContourVector::iterator it = contours.begin(); it != contours.end(); ) {
131.1325 +			const BoundingBox& ibb = (*it).bb;
131.1326 +
131.1327 +			if (BoundingBoxesOverlapping(ibb, bb)) {
131.1328 +
131.1329 +				if (!(*it).is_rectangular) {
131.1330 +					is_rectangle = false;
131.1331 +				}
131.1332 +
131.1333 +				const std::vector<IfcVector2>& other = (*it).contour;
131.1334 +				ClipperLib::ExPolygons poly;
131.1335 +
131.1336 +				// First check whether subtracting the old contour (to which ibb belongs)
131.1337 +				// from the new contour (to which bb belongs) yields an updated bb which
131.1338 +				// no longer overlaps ibb
131.1339 +				MakeDisjunctWindowContours(other, temp_contour, poly);
131.1340 +				if(poly.size() == 1) {
131.1341 +					
131.1342 +					const BoundingBox& newbb = GetBoundingBox(poly[0].outer);
131.1343 +					if (!BoundingBoxesOverlapping(ibb, newbb )) {
131.1344 +						 // Good guy bounding box
131.1345 +						 bb = newbb ;
131.1346 +
131.1347 +						 ExtractVerticesFromClipper(poly[0].outer, temp_contour, false);
131.1348 +						 continue;
131.1349 +					}
131.1350 +				}
131.1351 +
131.1352 +				// Take these two overlapping contours and try to merge them. If they 
131.1353 +				// overlap (which should not happen, but in fact happens-in-the-real-
131.1354 +				// world [tm] ), resume using a single contour and a single bounding box.
131.1355 +				MergeWindowContours(temp_contour, other, poly);
131.1356 +
131.1357 +				if (poly.size() > 1) { 
131.1358 +					return TryAddOpenings_Poly2Tri(openings, nors, curmesh);
131.1359 +				}
131.1360 +				else if (poly.size() == 0) {
131.1361 +					IFCImporter::LogWarn("ignoring duplicate opening");
131.1362 +					temp_contour.clear();
131.1363 +					break;
131.1364 +				}
131.1365 +				else {
131.1366 +					IFCImporter::LogDebug("merging overlapping openings");				
131.1367 +					ExtractVerticesFromClipper(poly[0].outer, temp_contour, false);
131.1368 +
131.1369 +					// Generate the union of the bounding boxes
131.1370 +					bb.first = std::min(bb.first, ibb.first);
131.1371 +					bb.second = std::max(bb.second, ibb.second);
131.1372 +
131.1373 +					// Update contour-to-opening tables accordingly
131.1374 +					if (generate_connection_geometry) {
131.1375 +						std::vector<TempOpening*>& t = contours_to_openings[std::distance(contours.begin(),it)]; 
131.1376 +						joined_openings.insert(joined_openings.end(), t.begin(), t.end());
131.1377 +
131.1378 +						contours_to_openings.erase(contours_to_openings.begin() + std::distance(contours.begin(),it));
131.1379 +					}
131.1380 +
131.1381 +					contours.erase(it);
131.1382 +
131.1383 +					// Restart from scratch because the newly formed BB might now
131.1384 +					// overlap any other BB which its constituent BBs didn't
131.1385 +					// previously overlap.
131.1386 +					it = contours.begin();
131.1387 +					continue;
131.1388 +				}
131.1389 +			}
131.1390 +			++it;
131.1391 +		}
131.1392 +
131.1393 +		if(!temp_contour.empty()) {
131.1394 +			if (generate_connection_geometry) {
131.1395 +				contours_to_openings.push_back(std::vector<TempOpening*>(
131.1396 +					joined_openings.begin(),
131.1397 +					joined_openings.end()));
131.1398 +			}
131.1399 +
131.1400 +			contours.push_back(ProjectedWindowContour(temp_contour, bb, is_rectangle));
131.1401 +		}
131.1402 +	}
131.1403 +
131.1404 +	// Check if we still have any openings left - it may well be that this is
131.1405 +	// not the cause, for example if all the opening candidates don't intersect
131.1406 +	// this surface or point into a direction perpendicular to it.
131.1407 +	if (contours.empty()) {
131.1408 +		return false;
131.1409 +	}
131.1410 +
131.1411 +	curmesh.Clear();
131.1412 +
131.1413 +	// Generate a base subdivision into quads to accommodate the given list
131.1414 +	// of window bounding boxes.
131.1415 +	Quadrify(contours,curmesh);
131.1416 +
131.1417 +	// Run a sanity cleanup pass on the window contours to avoid generating
131.1418 +	// artifacts during the contour generation phase later on.
131.1419 +	CleanupWindowContours(contours);
131.1420 +
131.1421 +	// Previously we reduced all windows to rectangular AABBs in projection
131.1422 +	// space, now it is time to fill the gaps between the BBs and the real
131.1423 +	// window openings.
131.1424 +	InsertWindowContours(contours,openings, curmesh);
131.1425 +
131.1426 +	// Clip the entire outer contour of our current result against the real
131.1427 +	// outer contour of the surface. This is necessary because the result
131.1428 +	// of the Quadrify() algorithm is always a square area spanning
131.1429 +	// over [0,1]^2 (i.e. entire projection space).
131.1430 +	CleanupOuterContour(contour_flat, curmesh);
131.1431 +
131.1432 +	// Undo the projection and get back to world (or local object) space
131.1433 +	BOOST_FOREACH(IfcVector3& v3, curmesh.verts) {
131.1434 +		v3 = minv * v3;
131.1435 +	}
131.1436 +
131.1437 +	// Generate window caps to connect the symmetric openings on both sides
131.1438 +	// of the wall.
131.1439 + 	if (generate_connection_geometry) {
131.1440 +		CloseWindows(contours, minv, contours_to_openings, curmesh);
131.1441 +	}
131.1442 +	return true;
131.1443 +}
131.1444 +
131.1445 +// ------------------------------------------------------------------------------------------------
131.1446 +bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, 
131.1447 +	TempMesh& curmesh)
131.1448 +{
131.1449 +	IFCImporter::LogWarn("forced to use poly2tri fallback method to generate wall openings");
131.1450 +	std::vector<IfcVector3>& out = curmesh.verts;
131.1451 +
131.1452 +	bool result = false;
131.1453 +
131.1454 +	// Try to derive a solid base plane within the current surface for use as 
131.1455 +	// working coordinate system. 
131.1456 +	bool ok;
131.1457 +	IfcVector3 nor;
131.1458 +	const IfcMatrix3& m = DerivePlaneCoordinateSpace(curmesh, ok, nor);
131.1459 +	if (!ok) {
131.1460 +		return false;
131.1461 +	}
131.1462 +
131.1463 +	const IfcMatrix3 minv = IfcMatrix3(m).Inverse();
131.1464 +
131.1465 +
131.1466 +	IfcFloat coord = -1;
131.1467 +
131.1468 +	std::vector<IfcVector2> contour_flat;
131.1469 +	contour_flat.reserve(out.size());
131.1470 +
131.1471 +	IfcVector2 vmin, vmax;
131.1472 +	MinMaxChooser<IfcVector2>()(vmin, vmax);
131.1473 +	
131.1474 +	// Move all points into the new coordinate system, collecting min/max verts on the way
131.1475 +	BOOST_FOREACH(IfcVector3& x, out) {
131.1476 +		const IfcVector3 vv = m * x;
131.1477 +
131.1478 +		// keep Z offset in the plane coordinate system. Ignoring precision issues
131.1479 +		// (which  are present, of course), this should be the same value for
131.1480 +		// all polygon vertices (assuming the polygon is planar).
131.1481 +
131.1482 +
131.1483 +		// XXX this should be guarded, but we somehow need to pick a suitable
131.1484 +		// epsilon
131.1485 +		// if(coord != -1.0f) {
131.1486 +		//	assert(fabs(coord - vv.z) < 1e-3f);
131.1487 +		// }
131.1488 +
131.1489 +		coord = vv.z;
131.1490 +
131.1491 +		vmin = std::min(IfcVector2(vv.x, vv.y), vmin);
131.1492 +		vmax = std::max(IfcVector2(vv.x, vv.y), vmax);
131.1493 +
131.1494 +		contour_flat.push_back(IfcVector2(vv.x,vv.y));
131.1495 +	}
131.1496 +		
131.1497 +	// With the current code in DerivePlaneCoordinateSpace, 
131.1498 +	// vmin,vmax should always be the 0...1 rectangle (+- numeric inaccuracies) 
131.1499 +	// but here we won't rely on this.
131.1500 +
131.1501 +	vmax -= vmin;
131.1502 +
131.1503 +	// If this happens then the projection must have been wrong.
131.1504 +	assert(vmax.Length());
131.1505 +
131.1506 +	ClipperLib::ExPolygons clipped;
131.1507 +	ClipperLib::Polygons holes_union;
131.1508 +
131.1509 +
131.1510 +	IfcVector3 wall_extrusion;
131.1511 +	bool do_connections = false, first = true;
131.1512 +
131.1513 +	try {
131.1514 +
131.1515 +		ClipperLib::Clipper clipper_holes;
131.1516 +		size_t c = 0;
131.1517 +
131.1518 +		BOOST_FOREACH(const TempOpening& t,openings) {
131.1519 +			const IfcVector3& outernor = nors[c++];
131.1520 +			const IfcFloat dot = nor * outernor;
131.1521 +			if (fabs(dot)<1.f-1e-6f) {
131.1522 +				continue;
131.1523 +			}
131.1524 +
131.1525 +			const std::vector<IfcVector3>& va = t.profileMesh->verts;
131.1526 +			if(va.size() <= 2) {
131.1527 +				continue;	
131.1528 +			}
131.1529 +		
131.1530 +			std::vector<IfcVector2> contour;
131.1531 +
131.1532 +			BOOST_FOREACH(const IfcVector3& xx, t.profileMesh->verts) {
131.1533 +				IfcVector3 vv = m *  xx, vv_extr = m * (xx + t.extrusionDir);
131.1534 +				
131.1535 +				const bool is_extruded_side = fabs(vv.z - coord) > fabs(vv_extr.z - coord);
131.1536 +				if (first) {
131.1537 +					first = false;
131.1538 +					if (dot > 0.f) {
131.1539 +						do_connections = true;
131.1540 +						wall_extrusion = t.extrusionDir;
131.1541 +						if (is_extruded_side) {
131.1542 +							wall_extrusion = - wall_extrusion;
131.1543 +						}
131.1544 +					}
131.1545 +				}
131.1546 +
131.1547 +				// XXX should not be necessary - but it is. Why? For precision reasons?
131.1548 +				vv = is_extruded_side ? vv_extr : vv;
131.1549 +				contour.push_back(IfcVector2(vv.x,vv.y));
131.1550 +			}
131.1551 +
131.1552 +			ClipperLib::Polygon hole;
131.1553 +			BOOST_FOREACH(IfcVector2& pip, contour) {
131.1554 +				pip.x  = (pip.x - vmin.x) / vmax.x;
131.1555 +				pip.y  = (pip.y - vmin.y) / vmax.y;
131.1556 +
131.1557 +				hole.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
131.1558 +			}
131.1559 +
131.1560 +			if (!ClipperLib::Orientation(hole)) {
131.1561 +				std::reverse(hole.begin(), hole.end());
131.1562 +			//	assert(ClipperLib::Orientation(hole));
131.1563 +			}
131.1564 +
131.1565 +			/*ClipperLib::Polygons pol_temp(1), pol_temp2(1);
131.1566 +			pol_temp[0] = hole;
131.1567 +
131.1568 +			ClipperLib::OffsetPolygons(pol_temp,pol_temp2,5.0);
131.1569 +			hole = pol_temp2[0];*/
131.1570 +
131.1571 +			clipper_holes.AddPolygon(hole,ClipperLib::ptSubject);
131.1572 +		}
131.1573 +
131.1574 +		clipper_holes.Execute(ClipperLib::ctUnion,holes_union,
131.1575 +			ClipperLib::pftNonZero,
131.1576 +			ClipperLib::pftNonZero);
131.1577 +
131.1578 +		if (holes_union.empty()) {
131.1579 +			return false;
131.1580 +		}
131.1581 +
131.1582 +		// Now that we have the big union of all holes, subtract it from the outer contour
131.1583 +		// to obtain the final polygon to feed into the triangulator.
131.1584 +		{
131.1585 +			ClipperLib::Polygon poly;
131.1586 +			BOOST_FOREACH(IfcVector2& pip, contour_flat) {
131.1587 +				pip.x  = (pip.x - vmin.x) / vmax.x;
131.1588 +				pip.y  = (pip.y - vmin.y) / vmax.y;
131.1589 +
131.1590 +				poly.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) ));
131.1591 +			}
131.1592 +
131.1593 +			if (ClipperLib::Orientation(poly)) {
131.1594 +				std::reverse(poly.begin(), poly.end());
131.1595 +			}
131.1596 +			clipper_holes.Clear();
131.1597 +			clipper_holes.AddPolygon(poly,ClipperLib::ptSubject);
131.1598 +
131.1599 +			clipper_holes.AddPolygons(holes_union,ClipperLib::ptClip);
131.1600 +			clipper_holes.Execute(ClipperLib::ctDifference,clipped,
131.1601 +				ClipperLib::pftNonZero,
131.1602 +				ClipperLib::pftNonZero);
131.1603 +		}
131.1604 +
131.1605 +	}
131.1606 +	catch (const char* sx) {
131.1607 +		IFCImporter::LogError("Ifc: error during polygon clipping, skipping openings for this face: (Clipper: " 
131.1608 +			+ std::string(sx) + ")");
131.1609 +
131.1610 +		return false;
131.1611 +	}
131.1612 +
131.1613 +	std::vector<IfcVector3> old_verts;
131.1614 +	std::vector<unsigned int> old_vertcnt;
131.1615 +
131.1616 +	old_verts.swap(curmesh.verts);
131.1617 +	old_vertcnt.swap(curmesh.vertcnt);
131.1618 +
131.1619 +
131.1620 +	// add connection geometry to close the adjacent 'holes' for the openings
131.1621 +	// this should only be done from one side of the wall or the polygons 
131.1622 +	// would be emitted twice.
131.1623 +	if (false && do_connections) {
131.1624 +
131.1625 +		std::vector<IfcVector3> tmpvec;
131.1626 +		BOOST_FOREACH(ClipperLib::Polygon& opening, holes_union) {
131.1627 +
131.1628 +			assert(ClipperLib::Orientation(opening));
131.1629 +
131.1630 +			tmpvec.clear();
131.1631 +
131.1632 +			BOOST_FOREACH(ClipperLib::IntPoint& point, opening) {
131.1633 +
131.1634 +				tmpvec.push_back( minv * IfcVector3(
131.1635 +					vmin.x + from_int64(point.X) * vmax.x, 
131.1636 +					vmin.y + from_int64(point.Y) * vmax.y,
131.1637 +					coord));
131.1638 +			}
131.1639 +
131.1640 +			for(size_t i = 0, size = tmpvec.size(); i < size; ++i) {
131.1641 +				const size_t next = (i+1)%size;
131.1642 +
131.1643 +				curmesh.vertcnt.push_back(4);
131.1644 +
131.1645 +				const IfcVector3& in_world = tmpvec[i];
131.1646 +				const IfcVector3& next_world = tmpvec[next];
131.1647 +
131.1648 +				// Assumptions: no 'partial' openings, wall thickness roughly the same across the wall
131.1649 +				curmesh.verts.push_back(in_world);
131.1650 +				curmesh.verts.push_back(in_world+wall_extrusion);
131.1651 +				curmesh.verts.push_back(next_world+wall_extrusion);
131.1652 +				curmesh.verts.push_back(next_world);
131.1653 +			}
131.1654 +		}
131.1655 +	}
131.1656 +	
131.1657 +	std::vector< std::vector<p2t::Point*> > contours;
131.1658 +	BOOST_FOREACH(ClipperLib::ExPolygon& clip, clipped) {
131.1659 +		
131.1660 +		contours.clear();
131.1661 +
131.1662 +		// Build the outer polygon contour line for feeding into poly2tri
131.1663 +		std::vector<p2t::Point*> contour_points;
131.1664 +		BOOST_FOREACH(ClipperLib::IntPoint& point, clip.outer) {
131.1665 +			contour_points.push_back( new p2t::Point(from_int64(point.X), from_int64(point.Y)) );
131.1666 +		}
131.1667 +
131.1668 +		p2t::CDT* cdt ;
131.1669 +		try {
131.1670 +			// Note: this relies on custom modifications in poly2tri to raise runtime_error's
131.1671 +			// instead if assertions. These failures are not debug only, they can actually
131.1672 +			// happen in production use if the input data is broken. An assertion would be
131.1673 +			// inappropriate.
131.1674 +			cdt = new p2t::CDT(contour_points);
131.1675 +		}
131.1676 +		catch(const std::exception& e) {
131.1677 +			IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: " 
131.1678 +				+ std::string(e.what()) + ")");
131.1679 +			continue;
131.1680 +		}
131.1681 +		
131.1682 +
131.1683 +		// Build the poly2tri inner contours for all holes we got from ClipperLib
131.1684 +		BOOST_FOREACH(ClipperLib::Polygon& opening, clip.holes) {
131.1685 +			
131.1686 +			contours.push_back(std::vector<p2t::Point*>());
131.1687 +			std::vector<p2t::Point*>& contour = contours.back();
131.1688 +
131.1689 +			BOOST_FOREACH(ClipperLib::IntPoint& point, opening) {
131.1690 +				contour.push_back( new p2t::Point(from_int64(point.X), from_int64(point.Y)) );
131.1691 +			}
131.1692 +
131.1693 +			cdt->AddHole(contour);
131.1694 +		}
131.1695 +		
131.1696 +		try {
131.1697 +			// Note: See above
131.1698 +			cdt->Triangulate();
131.1699 +		}
131.1700 +		catch(const std::exception& e) {
131.1701 +			IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: " 
131.1702 +				+ std::string(e.what()) + ")");
131.1703 +			continue;
131.1704 +		}
131.1705 +
131.1706 +		const std::vector<p2t::Triangle*>& tris = cdt->GetTriangles();
131.1707 +
131.1708 +		// Collect the triangles we just produced
131.1709 +		BOOST_FOREACH(p2t::Triangle* tri, tris) {
131.1710 +			for(int i = 0; i < 3; ++i) {
131.1711 +
131.1712 +				const IfcVector2& v = IfcVector2( 
131.1713 +					static_cast<IfcFloat>( tri->GetPoint(i)->x ), 
131.1714 +					static_cast<IfcFloat>( tri->GetPoint(i)->y )
131.1715 +				);
131.1716 +
131.1717 +				assert(v.x <= 1.0 && v.x >= 0.0 && v.y <= 1.0 && v.y >= 0.0);
131.1718 +				const IfcVector3 v3 = minv * IfcVector3(vmin.x + v.x * vmax.x, vmin.y + v.y * vmax.y,coord) ; 
131.1719 +
131.1720 +				curmesh.verts.push_back(v3);
131.1721 +			}
131.1722 +			curmesh.vertcnt.push_back(3);
131.1723 +		}
131.1724 +
131.1725 +		result = true;
131.1726 +	}
131.1727 +
131.1728 +	if (!result) {
131.1729 +		// revert -- it's a shame, but better than nothing
131.1730 +		curmesh.verts.insert(curmesh.verts.end(),old_verts.begin(), old_verts.end());
131.1731 +		curmesh.vertcnt.insert(curmesh.vertcnt.end(),old_vertcnt.begin(), old_vertcnt.end());
131.1732 +
131.1733 +		IFCImporter::LogError("Ifc: revert, could not generate openings for this wall");
131.1734 +	}
131.1735 +
131.1736 +	return result;
131.1737 +}
131.1738 +
131.1739 +
131.1740 +	} // ! IFC
131.1741 +} // ! Assimp
131.1742 +
131.1743 +#undef to_int64
131.1744 +#undef from_int64
131.1745 +#undef one_vec
131.1746 +
131.1747 +#endif 
131.1748 \ No newline at end of file
   132.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   132.2 +++ b/libs/assimp/IFCProfile.cpp	Sat Feb 01 19:58:19 2014 +0200
   132.3 @@ -0,0 +1,189 @@
   132.4 +/*
   132.5 +Open Asset Import Library (assimp)
   132.6 +----------------------------------------------------------------------
   132.7 +
   132.8 +Copyright (c) 2006-2012, assimp team
   132.9 +All rights reserved.
  132.10 +
  132.11 +Redistribution and use of this software in source and binary forms, 
  132.12 +with or without modification, are permitted provided that the 
  132.13 +following conditions are met:
  132.14 +
  132.15 +* Redistributions of source code must retain the above
  132.16 +  copyright notice, this list of conditions and the
  132.17 +  following disclaimer.
  132.18 +
  132.19 +* Redistributions in binary form must reproduce the above
  132.20 +  copyright notice, this list of conditions and the
  132.21 +  following disclaimer in the documentation and/or other
  132.22 +  materials provided with the distribution.
  132.23 +
  132.24 +* Neither the name of the assimp team, nor the names of its
  132.25 +  contributors may be used to endorse or promote products
  132.26 +  derived from this software without specific prior
  132.27 +  written permission of the assimp team.
  132.28 +
  132.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  132.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  132.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  132.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  132.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  132.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  132.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  132.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  132.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  132.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  132.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  132.40 +
  132.41 +----------------------------------------------------------------------
  132.42 +*/
  132.43 +
  132.44 +/** @file  IFCProfile.cpp
  132.45 + *  @brief Read profile and curves entities from IFC files
  132.46 + */
  132.47 +
  132.48 +#include "AssimpPCH.h"
  132.49 +
  132.50 +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
  132.51 +#include "IFCUtil.h"
  132.52 +
  132.53 +namespace Assimp {
  132.54 +	namespace IFC {
  132.55 +
  132.56 +// ------------------------------------------------------------------------------------------------
  132.57 +void ProcessPolyLine(const IfcPolyline& def, TempMesh& meshout, ConversionData& /*conv*/)
  132.58 +{
  132.59 +	// this won't produce a valid mesh, it just spits out a list of vertices
  132.60 +	IfcVector3 t;
  132.61 +	BOOST_FOREACH(const IfcCartesianPoint& cp, def.Points) {
  132.62 +		ConvertCartesianPoint(t,cp);
  132.63 +		meshout.verts.push_back(t);
  132.64 +	}
  132.65 +	meshout.vertcnt.push_back(meshout.verts.size());
  132.66 +}
  132.67 +
  132.68 +// ------------------------------------------------------------------------------------------------
  132.69 +bool ProcessCurve(const IfcCurve& curve,  TempMesh& meshout, ConversionData& conv)
  132.70 +{
  132.71 +	boost::scoped_ptr<const Curve> cv(Curve::Convert(curve,conv));
  132.72 +	if (!cv) {
  132.73 +		IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is " + curve.GetClassName());
  132.74 +		return false;
  132.75 +	}
  132.76 +
  132.77 +	// we must have a bounded curve at this point
  132.78 +	if (const BoundedCurve* bc = dynamic_cast<const BoundedCurve*>(cv.get())) {
  132.79 +		try {
  132.80 +			bc->SampleDiscrete(meshout);
  132.81 +		}
  132.82 +		catch(const  CurveError& cv) {
  132.83 +			IFCImporter::LogError(cv.s+ " (error occurred while processing curve)");
  132.84 +			return false;
  132.85 +		}
  132.86 +		meshout.vertcnt.push_back(meshout.verts.size());
  132.87 +		return true;
  132.88 +	}
  132.89 +
  132.90 +	IFCImporter::LogError("cannot use unbounded curve as profile");
  132.91 +	return false;
  132.92 +}
  132.93 +
  132.94 +// ------------------------------------------------------------------------------------------------
  132.95 +void ProcessClosedProfile(const IfcArbitraryClosedProfileDef& def, TempMesh& meshout, ConversionData& conv)
  132.96 +{
  132.97 +	ProcessCurve(def.OuterCurve,meshout,conv);
  132.98 +}
  132.99 +
 132.100 +// ------------------------------------------------------------------------------------------------
 132.101 +void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout, ConversionData& conv)
 132.102 +{
 132.103 +	ProcessCurve(def.Curve,meshout,conv);
 132.104 +}
 132.105 +
 132.106 +// ------------------------------------------------------------------------------------------------
 132.107 +void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv)
 132.108 +{
 132.109 +	if(const IfcRectangleProfileDef* const cprofile = def.ToPtr<IfcRectangleProfileDef>()) {
 132.110 +		const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
 132.111 +
 132.112 +		meshout.verts.reserve(meshout.verts.size()+4);
 132.113 +		meshout.verts.push_back( IfcVector3( x, y, 0.f ));
 132.114 +		meshout.verts.push_back( IfcVector3(-x, y, 0.f ));
 132.115 +		meshout.verts.push_back( IfcVector3(-x,-y, 0.f ));
 132.116 +		meshout.verts.push_back( IfcVector3( x,-y, 0.f ));
 132.117 +		meshout.vertcnt.push_back(4);
 132.118 +	}
 132.119 +	else if( const IfcCircleProfileDef* const circle = def.ToPtr<IfcCircleProfileDef>()) {
 132.120 +		if( const IfcCircleHollowProfileDef* const hollow = def.ToPtr<IfcCircleHollowProfileDef>()) {
 132.121 +			// TODO
 132.122 +		}
 132.123 +		const size_t segments = 32;
 132.124 +		const IfcFloat delta = AI_MATH_TWO_PI_F/segments, radius = circle->Radius;
 132.125 +
 132.126 +		meshout.verts.reserve(segments);
 132.127 +
 132.128 +		IfcFloat angle = 0.f;
 132.129 +		for(size_t i = 0; i < segments; ++i, angle += delta) {
 132.130 +			meshout.verts.push_back( IfcVector3( cos(angle)*radius, sin(angle)*radius, 0.f ));
 132.131 +		}
 132.132 +
 132.133 +		meshout.vertcnt.push_back(segments);
 132.134 +	}
 132.135 +	else if( const IfcIShapeProfileDef* const ishape = def.ToPtr<IfcIShapeProfileDef>()) {
 132.136 +		// construct simplified IBeam shape
 132.137 +		const IfcFloat offset = (ishape->OverallWidth - ishape->WebThickness) / 2;
 132.138 +		const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2;
 132.139 +
 132.140 +		meshout.verts.reserve(12);
 132.141 +		meshout.verts.push_back(IfcVector3(0,0,0));
 132.142 +		meshout.verts.push_back(IfcVector3(0,ishape->FlangeThickness,0));
 132.143 +		meshout.verts.push_back(IfcVector3(offset,ishape->FlangeThickness,0));
 132.144 +		meshout.verts.push_back(IfcVector3(offset,ishape->FlangeThickness + inner_height,0));
 132.145 +		meshout.verts.push_back(IfcVector3(0,ishape->FlangeThickness + inner_height,0));
 132.146 +		meshout.verts.push_back(IfcVector3(0,ishape->OverallDepth,0));
 132.147 +		meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->OverallDepth,0));
 132.148 +		meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness + inner_height,0));
 132.149 +		meshout.verts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness + inner_height,0));
 132.150 +		meshout.verts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness,0));
 132.151 +		meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness,0));
 132.152 +		meshout.verts.push_back(IfcVector3(ishape->OverallWidth,0,0));
 132.153 +
 132.154 +		meshout.vertcnt.push_back(12);
 132.155 +	}
 132.156 +	else {
 132.157 +		IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is " + def.GetClassName());
 132.158 +		return;
 132.159 +	}
 132.160 +
 132.161 +	IfcMatrix4 trafo;
 132.162 +	ConvertAxisPlacement(trafo, *def.Position);
 132.163 +	meshout.Transform(trafo);
 132.164 +}
 132.165 +
 132.166 +// ------------------------------------------------------------------------------------------------
 132.167 +bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv) 
 132.168 +{
 132.169 +	if(const IfcArbitraryClosedProfileDef* const cprofile = prof.ToPtr<IfcArbitraryClosedProfileDef>()) {
 132.170 +		ProcessClosedProfile(*cprofile,meshout,conv);
 132.171 +	}
 132.172 +	else if(const IfcArbitraryOpenProfileDef* const copen = prof.ToPtr<IfcArbitraryOpenProfileDef>()) {
 132.173 +		ProcessOpenProfile(*copen,meshout,conv);
 132.174 +	}
 132.175 +	else if(const IfcParameterizedProfileDef* const cparam = prof.ToPtr<IfcParameterizedProfileDef>()) {
 132.176 +		ProcessParametrizedProfile(*cparam,meshout,conv);
 132.177 +	}
 132.178 +	else {
 132.179 +		IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is " + prof.GetClassName());
 132.180 +		return false;
 132.181 +	}
 132.182 +	meshout.RemoveAdjacentDuplicates();
 132.183 +	if (!meshout.vertcnt.size() || meshout.vertcnt.front() <= 1) {
 132.184 +		return false;
 132.185 +	}
 132.186 +	return true;
 132.187 +}
 132.188 +
 132.189 +} // ! IFC
 132.190 +} // ! Assimp
 132.191 +
 132.192 +#endif
   133.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   133.2 +++ b/libs/assimp/IFCReaderGen.cpp	Sat Feb 01 19:58:19 2014 +0200
   133.3 @@ -0,0 +1,5030 @@
   133.4 +/*
   133.5 +Open Asset Import Library (ASSIMP)
   133.6 +----------------------------------------------------------------------
   133.7 +
   133.8 +Copyright (c) 2006-2010, ASSIMP Development Team
   133.9 +All rights reserved.
  133.10 +
  133.11 +Redistribution and use of this software in source and binary forms, 
  133.12 +with or without modification, are permitted provided that the 
  133.13 +following conditions are met:
  133.14 +
  133.15 +* Redistributions of source code must retain the above
  133.16 +  copyright notice, this list of conditions and the
  133.17 +  following disclaimer.
  133.18 +
  133.19 +* Redistributions in binary form must reproduce the above
  133.20 +  copyright notice, this list of conditions and the
  133.21 +  following disclaimer in the documentation and/or other
  133.22 +  materials provided with the distribution.
  133.23 +
  133.24 +* Neither the name of the ASSIMP team, nor the names of its
  133.25 +  contributors may be used to endorse or promote products
  133.26 +  derived from this software without specific prior
  133.27 +  written permission of the ASSIMP Development Team.
  133.28 +
  133.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  133.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  133.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  133.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  133.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  133.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  133.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  133.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  133.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  133.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  133.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  133.40 +
  133.41 +----------------------------------------------------------------------
  133.42 +*/
  133.43 +
  133.44 +/** MACHINE-GENERATED by scripts/ICFImporter/CppGenerator.py */
  133.45 +
  133.46 +#include "AssimpPCH.h"
  133.47 +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
  133.48 +
  133.49 +#include "IFCReaderGen.h"
  133.50 +
  133.51 +namespace Assimp {
  133.52 +using namespace IFC;
  133.53 +
  133.54 +namespace {
  133.55 +
  133.56 +	typedef EXPRESS::ConversionSchema::SchemaEntry SchemaEntry;
  133.57 +	const SchemaEntry schema_raw[] =  {
  133.58 +		SchemaEntry("ifcstairtypeenum",NULL )
  133.59 +,		SchemaEntry("ifcspacetypeenum",NULL )
  133.60 +,		SchemaEntry("ifcwalltypeenum",NULL )
  133.61 +,		SchemaEntry("ifcmonthinyearnumber",NULL )
  133.62 +,		SchemaEntry("ifcheatfluxdensitymeasure",NULL )
  133.63 +,		SchemaEntry("ifckinematicviscositymeasure",NULL )
  133.64 +,		SchemaEntry("ifcsequenceenum",NULL )
  133.65 +,		SchemaEntry("ifcairtoairheatrecoverytypeenum",NULL )
  133.66 +,		SchemaEntry("ifcactorselect",NULL )
  133.67 +,		SchemaEntry("ifctransformertypeenum",NULL )
  133.68 +,		SchemaEntry("ifcunitaryequipmenttypeenum",NULL )
  133.69 +,		SchemaEntry("ifcelectricflowstoragedevicetypeenum",NULL )
  133.70 +,		SchemaEntry("ifcenergysequenceenum",NULL )
  133.71 +,		SchemaEntry("ifcworkcontroltypeenum",NULL )
  133.72 +,		SchemaEntry("ifccurvaturemeasure",NULL )
  133.73 +,		SchemaEntry("ifcparametervalue",NULL )
  133.74 +,		SchemaEntry("ifcappliedvalueselect",NULL )
  133.75 +,		SchemaEntry("ifcwarpingconstantmeasure",NULL )
  133.76 +,		SchemaEntry("ifcarithmeticoperatorenum",NULL )
  133.77 +,		SchemaEntry("ifclinearforcemeasure",NULL )
  133.78 +,		SchemaEntry("ifcwindowpanelpositionenum",NULL )
  133.79 +,		SchemaEntry("ifcflowmetertypeenum",NULL )
  133.80 +,		SchemaEntry("ifcrampflighttypeenum",NULL )
  133.81 +,		SchemaEntry("ifcspecularhighlightselect",NULL )
  133.82 +,		SchemaEntry("ifcactiontypeenum",NULL )
  133.83 +,		SchemaEntry("ifcgeometricprojectionenum",NULL )
  133.84 +,		SchemaEntry("ifctimeseriesdatatypeenum",NULL )
  133.85 +,		SchemaEntry("ifcmagneticfluxmeasure",NULL )
  133.86 +,		SchemaEntry("ifcobjecttypeenum",NULL )
  133.87 +,		SchemaEntry("ifcdataoriginenum",NULL )
  133.88 +,		SchemaEntry("ifcmassdensitymeasure",NULL )
  133.89 +,		SchemaEntry("ifclightfixturetypeenum",NULL )
  133.90 +,		SchemaEntry("ifcservicelifetypeenum",NULL )
  133.91 +,		SchemaEntry("ifcelectricvoltagemeasure",NULL )
  133.92 +,		SchemaEntry("ifcheatingvaluemeasure",NULL )
  133.93 +,		SchemaEntry("ifcpresentabletext",NULL )
  133.94 +,		SchemaEntry("ifcaheadorbehind",NULL )
  133.95 +,		SchemaEntry("ifcsimplevalue",NULL )
  133.96 +,		SchemaEntry("ifcsensortypeenum",NULL )
  133.97 +,		SchemaEntry("ifcderivedunitenum",NULL )
  133.98 +,		SchemaEntry("ifcsizeselect",NULL )
  133.99 +,		SchemaEntry("ifctransportelementtypeenum",NULL )
 133.100 +,		SchemaEntry("ifcinventorytypeenum",NULL )
 133.101 +,		SchemaEntry("ifctextdecoration",NULL )
 133.102 +,		SchemaEntry("ifcdirectionsenseenum",NULL )
 133.103 +,		SchemaEntry("ifcductfittingtypeenum",NULL )
 133.104 +,		SchemaEntry("ifcdocumentstatusenum",NULL )
 133.105 +,		SchemaEntry("ifcslabtypeenum",NULL )
 133.106 +,		SchemaEntry("ifcdoorstyleconstructionenum",NULL )
 133.107 +,		SchemaEntry("ifcvolumemeasure",NULL )
 133.108 +,		SchemaEntry("ifcinductancemeasure",NULL )
 133.109 +,		SchemaEntry("ifccurtainwalltypeenum",NULL )
 133.110 +,		SchemaEntry("ifcsiunitname",NULL )
 133.111 +,		SchemaEntry("ifcspecularexponent",NULL )
 133.112 +,		SchemaEntry("ifcsoundpressuremeasure",NULL )
 133.113 +,		SchemaEntry("ifcanalysistheorytypeenum",NULL )
 133.114 +,		SchemaEntry("ifcgasterminaltypeenum",NULL )
 133.115 +,		SchemaEntry("ifcyearnumber",NULL )
 133.116 +,		SchemaEntry("ifcmodulusofelasticitymeasure",NULL )
 133.117 +,		SchemaEntry("ifcchangeactionenum",NULL )
 133.118 +,		SchemaEntry("ifcdampertypeenum",NULL )
 133.119 +,		SchemaEntry("ifcevaporatortypeenum",NULL )
 133.120 +,		SchemaEntry("ifcionconcentrationmeasure",NULL )
 133.121 +,		SchemaEntry("ifcductsegmenttypeenum",NULL )
 133.122 +,		SchemaEntry("ifcprotectivedevicetypeenum",NULL )
 133.123 +,		SchemaEntry("ifcabsorbeddosemeasure",NULL )
 133.124 +,		SchemaEntry("ifcmassperlengthmeasure",NULL )
 133.125 +,		SchemaEntry("ifctextfontname",NULL )
 133.126 +,		SchemaEntry("ifcorientationselect",NULL )
 133.127 +,		SchemaEntry("ifcilluminancemeasure",NULL )
 133.128 +,		SchemaEntry("ifcfiresuppressionterminaltypeenum",NULL )
 133.129 +,		SchemaEntry("ifcfontstyle",NULL )
 133.130 +,		SchemaEntry("ifcmomentofinertiameasure",NULL )
 133.131 +,		SchemaEntry("ifcmodulusofsubgradereactionmeasure",NULL )
 133.132 +,		SchemaEntry("ifccomplexnumber",NULL )
 133.133 +,		SchemaEntry("ifchumidifiertypeenum",NULL )
 133.134 +,		SchemaEntry("ifcpresentationstyleselect",NULL )
 133.135 +,		SchemaEntry("ifcthermaltransmittancemeasure",NULL )
 133.136 +,		SchemaEntry("ifcribplatedirectionenum",NULL )
 133.137 +,		SchemaEntry("ifcclassificationnotationselect",NULL )
 133.138 +,		SchemaEntry("ifcminuteinhour",NULL )
 133.139 +,		SchemaEntry("ifcinternalorexternalenum",NULL )
 133.140 +,		SchemaEntry("ifcrotationalfrequencymeasure",NULL )
 133.141 +,		SchemaEntry("ifcsanitaryterminaltypeenum",NULL )
 133.142 +,		SchemaEntry("ifcsymbolstyleselect",NULL )
 133.143 +,		SchemaEntry("ifcelementcompositionenum",NULL )
 133.144 +,		SchemaEntry("ifctextpath",NULL )
 133.145 +,		SchemaEntry("ifcpowermeasure",NULL )
 133.146 +,		SchemaEntry("ifcsurfacestyleelementselect",NULL )
 133.147 +,		SchemaEntry("ifcresourceconsumptionenum",NULL )
 133.148 +,		SchemaEntry("ifcelectriccapacitancemeasure",NULL )
 133.149 +,		SchemaEntry("ifclayersetdirectionenum",NULL )
 133.150 +,		SchemaEntry("ifcrailingtypeenum",NULL )
 133.151 +,		SchemaEntry("ifcobjectiveenum",NULL )
 133.152 +,		SchemaEntry("ifcdocumentselect",NULL )
 133.153 +,		SchemaEntry("ifcmodulusoflinearsubgradereactionmeasure",NULL )
 133.154 +,		SchemaEntry("ifcthermaladmittancemeasure",NULL )
 133.155 +,		SchemaEntry("ifctransitioncode",NULL )
 133.156 +,		SchemaEntry("ifcconnectiontypeenum",NULL )
 133.157 +,		SchemaEntry("ifcmonetarymeasure",NULL )
 133.158 +,		SchemaEntry("ifcstackterminaltypeenum",NULL )
 133.159 +,		SchemaEntry("ifccolour",NULL )
 133.160 +,		SchemaEntry("ifctext",NULL )
 133.161 +,		SchemaEntry("ifccontextdependentmeasure",NULL )
 133.162 +,		SchemaEntry("ifcthermalconductivitymeasure",NULL )
 133.163 +,		SchemaEntry("ifcprojectedortruelengthenum",NULL )
 133.164 +,		SchemaEntry("ifcpressuremeasure",NULL )
 133.165 +,		SchemaEntry("ifcmoisturediffusivitymeasure",NULL )
 133.166 +,		SchemaEntry("ifcbooleanoperator",NULL )
 133.167 +,		SchemaEntry("ifcpropertysourceenum",NULL )
 133.168 +,		SchemaEntry("ifctimestamp",NULL )
 133.169 +,		SchemaEntry("ifcmaterialselect",NULL )
 133.170 +,		SchemaEntry("ifcgloballyuniqueid",NULL )
 133.171 +,		SchemaEntry("ifcreflectancemethodenum",NULL )
 133.172 +,		SchemaEntry("ifcvaporpermeabilitymeasure",NULL )
 133.173 +,		SchemaEntry("ifctimeseriesscheduletypeenum",NULL )
 133.174 +,		SchemaEntry("ifclinearmomentmeasure",NULL )
 133.175 +,		SchemaEntry("ifcgeometricsetselect",NULL )
 133.176 +,		SchemaEntry("ifcsectionmodulusmeasure",NULL )
 133.177 +,		SchemaEntry("ifcbsplinecurveform",NULL )
 133.178 +,		SchemaEntry("ifcdimensionextentusage",NULL )
 133.179 +,		SchemaEntry("ifcthermalexpansioncoefficientmeasure",NULL )
 133.180 +,		SchemaEntry("ifchourinday",NULL )
 133.181 +,		SchemaEntry("ifclinearvelocitymeasure",NULL )
 133.182 +,		SchemaEntry("ifctorquemeasure",NULL )
 133.183 +,		SchemaEntry("ifctemperaturegradientmeasure",NULL )
 133.184 +,		SchemaEntry("ifcfillstyleselect",NULL )
 133.185 +,		SchemaEntry("ifcelectricchargemeasure",NULL )
 133.186 +,		SchemaEntry("ifcheatexchangertypeenum",NULL )
 133.187 +,		SchemaEntry("ifcelectriccurrentenum",NULL )
 133.188 +,		SchemaEntry("ifcdaylightsavinghour",NULL )
 133.189 +,		SchemaEntry("ifcshell",NULL )
 133.190 +,		SchemaEntry("ifcdoseequivalentmeasure",NULL )
 133.191 +,		SchemaEntry("ifcprojectordertypeenum",NULL )
 133.192 +,		SchemaEntry("ifcderivedmeasurevalue",NULL )
 133.193 +,		SchemaEntry("ifclightdistributioncurveenum",NULL )
 133.194 +,		SchemaEntry("ifcwarpingmomentmeasure",NULL )
 133.195 +,		SchemaEntry("ifcmembertypeenum",NULL )
 133.196 +,		SchemaEntry("ifcsoundpowermeasure",NULL )
 133.197 +,		SchemaEntry("ifctextalignment",NULL )
 133.198 +,		SchemaEntry("ifccurveoredgecurve",NULL )
 133.199 +,		SchemaEntry("ifcmassflowratemeasure",NULL )
 133.200 +,		SchemaEntry("ifcisothermalmoisturecapacitymeasure",NULL )
 133.201 +,		SchemaEntry("ifccsgselect",NULL )
 133.202 +,		SchemaEntry("ifccoolingtowertypeenum",NULL )
 133.203 +,		SchemaEntry("ifcmassmeasure",NULL )
 133.204 +,		SchemaEntry("ifcpileconstructionenum",NULL )
 133.205 +,		SchemaEntry("ifcdoorstyleoperationenum",NULL )
 133.206 +,		SchemaEntry("ifcflowdirectionenum",NULL )
 133.207 +,		SchemaEntry("ifcthermalloadsourceenum",NULL )
 133.208 +,		SchemaEntry("ifclengthmeasure",NULL )
 133.209 +,		SchemaEntry("ifcconstraintenum",NULL )
 133.210 +,		SchemaEntry("ifcaxis2placement",NULL )
 133.211 +,		SchemaEntry("ifcloadgrouptypeenum",NULL )
 133.212 +,		SchemaEntry("ifcvalue",NULL )
 133.213 +,		SchemaEntry("ifcreinforcingbarsurfaceenum",NULL )
 133.214 +,		SchemaEntry("ifcprojectorderrecordtypeenum",NULL )
 133.215 +,		SchemaEntry("ifcdatetimeselect",NULL )
 133.216 +,		SchemaEntry("ifcstructuralsurfacetypeenum",NULL )
 133.217 +,		SchemaEntry("ifcpermeablecoveringoperationenum",NULL )
 133.218 +,		SchemaEntry("ifcfontweight",NULL )
 133.219 +,		SchemaEntry("ifcphmeasure",NULL )
 133.220 +,		SchemaEntry("ifcdescriptivemeasure",NULL )
 133.221 +,		SchemaEntry("ifccurvestylefontselect",NULL )
 133.222 +,		SchemaEntry("ifcunit",NULL )
 133.223 +,		SchemaEntry("ifchatchlinedistanceselect",NULL )
 133.224 +,		SchemaEntry("ifctextstyleselect",NULL )
 133.225 +,		SchemaEntry("ifcmetricvalueselect",NULL )
 133.226 +,		SchemaEntry("ifcvectorordirection",NULL )
 133.227 +,		SchemaEntry("ifcassemblyplaceenum",NULL )
 133.228 +,		SchemaEntry("ifcairterminaltypeenum",NULL )
 133.229 +,		SchemaEntry("ifccoveringtypeenum",NULL )
 133.230 +,		SchemaEntry("ifcplanarforcemeasure",NULL )
 133.231 +,		SchemaEntry("ifcvalvetypeenum",NULL )
 133.232 +,		SchemaEntry("ifcalarmtypeenum",NULL )
 133.233 +,		SchemaEntry("ifcdynamicviscositymeasure",NULL )
 133.234 +,		SchemaEntry("ifccurrencyenum",NULL )
 133.235 +,		SchemaEntry("ifcmodulusofrotationalsubgradereactionmeasure",NULL )
 133.236 +,		SchemaEntry("ifccablecarrierfittingtypeenum",NULL )
 133.237 +,		SchemaEntry("ifcboolean",NULL )
 133.238 +,		SchemaEntry("ifcactionsourcetypeenum",NULL )
 133.239 +,		SchemaEntry("ifcstructuralactivityassignmentselect",NULL )
 133.240 +,		SchemaEntry("ifcdistributionchamberelementtypeenum",NULL )
 133.241 +,		SchemaEntry("ifcevaporativecoolertypeenum",NULL )
 133.242 +,		SchemaEntry("ifcmagneticfluxdensitymeasure",NULL )
 133.243 +,		SchemaEntry("ifclightdistributiondatasourceselect",NULL )
 133.244 +,		SchemaEntry("ifctubebundletypeenum",NULL )
 133.245 +,		SchemaEntry("ifcaccelerationmeasure",NULL )
 133.246 +,		SchemaEntry("ifcboilertypeenum",NULL )
 133.247 +,		SchemaEntry("ifcramptypeenum",NULL )
 133.248 +,		SchemaEntry("ifcluminousintensitydistributionmeasure",NULL )
 133.249 +,		SchemaEntry("ifctrimmingpreference",NULL )
 133.250 +,		SchemaEntry("ifcspecificheatcapacitymeasure",NULL )
 133.251 +,		SchemaEntry("ifcamountofsubstancemeasure",NULL )
 133.252 +,		SchemaEntry("ifcroleenum",NULL )
 133.253 +,		SchemaEntry("ifcdocumentconfidentialityenum",NULL )
 133.254 +,		SchemaEntry("ifcfrequencymeasure",NULL )
 133.255 +,		SchemaEntry("ifcsectiontypeenum",NULL )
 133.256 +,		SchemaEntry("ifcelementassemblytypeenum",NULL )
 133.257 +,		SchemaEntry("ifcfootingtypeenum",NULL )
 133.258 +,		SchemaEntry("ifclayereditem",NULL )
 133.259 +,		SchemaEntry("ifccablesegmenttypeenum",NULL )
 133.260 +,		SchemaEntry("ifcdefinedsymbolselect",NULL )
 133.261 +,		SchemaEntry("ifcbuildingelementproxytypeenum",NULL )
 133.262 +,		SchemaEntry("ifcelectricgeneratortypeenum",NULL )
 133.263 +,		SchemaEntry("ifcrotationalstiffnessmeasure",NULL )
 133.264 +,		SchemaEntry("ifcspaceheatertypeenum",NULL )
 133.265 +,		SchemaEntry("ifcareameasure",NULL )
 133.266 +,		SchemaEntry("ifclabel",NULL )
 133.267 +,		SchemaEntry("ifccostscheduletypeenum",NULL )
 133.268 +,		SchemaEntry("ifcswitchingdevicetypeenum",NULL )
 133.269 +,		SchemaEntry("ifcelectrictimecontroltypeenum",NULL )
 133.270 +,		SchemaEntry("ifcfiltertypeenum",NULL )
 133.271 +,		SchemaEntry("ifcpositivelengthmeasure",NULL )
 133.272 +,		SchemaEntry("ifcnullstyle",NULL )
 133.273 +,		SchemaEntry("ifcconditioncriterionselect",NULL )
 133.274 +,		SchemaEntry("ifcshearmodulusmeasure",NULL )
 133.275 +,		SchemaEntry("ifcnormalisedratiomeasure",NULL )
 133.276 +,		SchemaEntry("ifcdoorpaneloperationenum",NULL )
 133.277 +,		SchemaEntry("ifcpointorvertexpoint",NULL )
 133.278 +,		SchemaEntry("ifcrooftypeenum",NULL )
 133.279 +,		SchemaEntry("ifccountmeasure",NULL )
 133.280 +,		SchemaEntry("ifcelectricconductancemeasure",NULL )
 133.281 +,		SchemaEntry("ifcproceduretypeenum",NULL )
 133.282 +,		SchemaEntry("ifcflowinstrumenttypeenum",NULL )
 133.283 +,		SchemaEntry("ifcelectricmotortypeenum",NULL )
 133.284 +,		SchemaEntry("ifcsurfaceside",NULL )
 133.285 +,		SchemaEntry("ifcstructuralcurvetypeenum",NULL )
 133.286 +,		SchemaEntry("ifccondensertypeenum",NULL )
 133.287 +,		SchemaEntry("ifclinearstiffnessmeasure",NULL )
 133.288 +,		SchemaEntry("ifcunitenum",NULL )
 133.289 +,		SchemaEntry("ifcoccupanttypeenum",NULL )
 133.290 +,		SchemaEntry("ifcthermalloadtypeenum",NULL )
 133.291 +,		SchemaEntry("ifcreinforcingbarroleenum",NULL )
 133.292 +,		SchemaEntry("ifcbenchmarkenum",NULL )
 133.293 +,		SchemaEntry("ifcpositiveplaneanglemeasure",NULL )
 133.294 +,		SchemaEntry("ifctexttransformation",NULL )
 133.295 +,		SchemaEntry("ifcdraughtingcalloutelement",NULL )
 133.296 +,		SchemaEntry("ifcratiomeasure",NULL )
 133.297 +,		SchemaEntry("ifcsolidanglemeasure",NULL )
 133.298 +,		SchemaEntry("ifcpipesegmenttypeenum",NULL )
 133.299 +,		SchemaEntry("ifccablecarriersegmenttypeenum",NULL )
 133.300 +,		SchemaEntry("ifccolourorfactor",NULL )
 133.301 +,		SchemaEntry("ifcidentifier",NULL )
 133.302 +,		SchemaEntry("ifctendontypeenum",NULL )
 133.303 +,		SchemaEntry("ifccontrollertypeenum",NULL )
 133.304 +,		SchemaEntry("ifcradioactivitymeasure",NULL )
 133.305 +,		SchemaEntry("ifctimemeasure",NULL )
 133.306 +,		SchemaEntry("ifcpumptypeenum",NULL )
 133.307 +,		SchemaEntry("ifcelectricheatertypeenum",NULL )
 133.308 +,		SchemaEntry("ifcbeamtypeenum",NULL )
 133.309 +,		SchemaEntry("ifcstateenum",NULL )
 133.310 +,		SchemaEntry("ifcsiprefix",NULL )
 133.311 +,		SchemaEntry("ifcnumericmeasure",NULL )
 133.312 +,		SchemaEntry("ifcoutlettypeenum",NULL )
 133.313 +,		SchemaEntry("ifccompoundplaneanglemeasure",NULL )
 133.314 +,		SchemaEntry("ifcservicelifefactortypeenum",NULL )
 133.315 +,		SchemaEntry("ifclogicaloperatorenum",NULL )
 133.316 +,		SchemaEntry("ifcbooleanoperand",NULL )
 133.317 +,		SchemaEntry("ifcobjectreferenceselect",NULL )
 133.318 +,		SchemaEntry("ifccooledbeamtypeenum",NULL )
 133.319 +,		SchemaEntry("ifcductsilencertypeenum",NULL )
 133.320 +,		SchemaEntry("ifcsectionalareaintegralmeasure",NULL )
 133.321 +,		SchemaEntry("ifcfontvariant",NULL )
 133.322 +,		SchemaEntry("ifcvolumetricflowratemeasure",NULL )
 133.323 +,		SchemaEntry("ifcplatetypeenum",NULL )
 133.324 +,		SchemaEntry("ifcenvironmentalimpactcategoryenum",NULL )
 133.325 +,		SchemaEntry("ifcvibrationisolatortypeenum",NULL )
 133.326 +,		SchemaEntry("ifcthermodynamictemperaturemeasure",NULL )
 133.327 +,		SchemaEntry("ifcrotationalmassmeasure",NULL )
 133.328 +,		SchemaEntry("ifcsecondinminute",NULL )
 133.329 +,		SchemaEntry("ifcdayinmonthnumber",NULL )
 133.330 +,		SchemaEntry("ifcdimensioncount",NULL )
 133.331 +,		SchemaEntry("ifcwindowstyleoperationenum",NULL )
 133.332 +,		SchemaEntry("ifcthermalresistancemeasure",NULL )
 133.333 +,		SchemaEntry("ifcmeasurevalue",NULL )
 133.334 +,		SchemaEntry("ifcwindowpaneloperationenum",NULL )
 133.335 +,		SchemaEntry("ifcchillertypeenum",NULL )
 133.336 +,		SchemaEntry("ifcpositiveratiomeasure",NULL )
 133.337 +,		SchemaEntry("ifcinteger",NULL )
 133.338 +,		SchemaEntry("ifclogical",NULL )
 133.339 +,		SchemaEntry("ifcjunctionboxtypeenum",NULL )
 133.340 +,		SchemaEntry("ifcaddresstypeenum",NULL )
 133.341 +,		SchemaEntry("ifcwasteterminaltypeenum",NULL )
 133.342 +,		SchemaEntry("ifctrimmingselect",NULL )
 133.343 +,		SchemaEntry("ifclightemissionsourceenum",NULL )
 133.344 +,		SchemaEntry("ifcsoundscaleenum",NULL )
 133.345 +,		SchemaEntry("ifcluminousfluxmeasure",NULL )
 133.346 +,		SchemaEntry("ifcelectricresistancemeasure",NULL )
 133.347 +,		SchemaEntry("ifcintegercountratemeasure",NULL )
 133.348 +,		SchemaEntry("ifcphysicalorvirtualenum",NULL )
 133.349 +,		SchemaEntry("ifcmolecularweightmeasure",NULL )
 133.350 +,		SchemaEntry("ifcprofiletypeenum",NULL )
 133.351 +,		SchemaEntry("ifcboxalignment",NULL )
 133.352 +,		SchemaEntry("ifcglobalorlocalenum",NULL )
 133.353 +,		SchemaEntry("ifcspecularroughness",NULL )
 133.354 +,		SchemaEntry("ifclamptypeenum",NULL )
 133.355 +,		SchemaEntry("ifcpiletypeenum",NULL )
 133.356 +,		SchemaEntry("ifcelectriccurrentmeasure",NULL )
 133.357 +,		SchemaEntry("ifcfantypeenum",NULL )
 133.358 +,		SchemaEntry("ifcsurfaceorfacesurface",NULL )
 133.359 +,		SchemaEntry("ifcpipefittingtypeenum",NULL )
 133.360 +,		SchemaEntry("ifctanktypeenum",NULL )
 133.361 +,		SchemaEntry("ifccurvefontorscaledcurvefontselect",NULL )
 133.362 +,		SchemaEntry("ifcwindowstyleconstructionenum",NULL )
 133.363 +,		SchemaEntry("ifcairterminalboxtypeenum",NULL )
 133.364 +,		SchemaEntry("ifcstairflighttypeenum",NULL )
 133.365 +,		SchemaEntry("ifcluminousintensitymeasure",NULL )
 133.366 +,		SchemaEntry("ifcmotorconnectiontypeenum",NULL )
 133.367 +,		SchemaEntry("ifcplaneanglemeasure",NULL )
 133.368 +,		SchemaEntry("ifcactuatortypeenum",NULL )
 133.369 +,		SchemaEntry("ifccolumntypeenum",NULL )
 133.370 +,		SchemaEntry("ifctextfontselect",NULL )
 133.371 +,		SchemaEntry("ifcdoorpanelpositionenum",NULL )
 133.372 +,		SchemaEntry("ifccoiltypeenum",NULL )
 133.373 +,		SchemaEntry("ifcangularvelocitymeasure",NULL )
 133.374 +,		SchemaEntry("ifcanalysismodeltypeenum",NULL )
 133.375 +,		SchemaEntry("ifclibraryselect",NULL )
 133.376 +,		SchemaEntry("ifcforcemeasure",NULL )
 133.377 +,		SchemaEntry("ifcfillareastyletileshapeselect",NULL )
 133.378 +,		SchemaEntry("ifcelectricappliancetypeenum",NULL )
 133.379 +,		SchemaEntry("ifcsurfacetextureenum",NULL )
 133.380 +,		SchemaEntry("ifccharacterstyleselect",NULL )
 133.381 +,		SchemaEntry("ifcenergymeasure",NULL )
 133.382 +,		SchemaEntry("ifcreal",NULL )
 133.383 +,		SchemaEntry("ifccompressortypeenum",NULL )
 133.384 +,		SchemaEntry("ifcelectricdistributionpointfunctionenum",NULL )
 133.385 +,		SchemaEntry("ifcroot",&STEP::ObjectHelper<IfcRoot,4>::Construct )
 133.386 +,		SchemaEntry("ifcobjectdefinition",&STEP::ObjectHelper<IfcObjectDefinition,0>::Construct )
 133.387 +,		SchemaEntry("ifctypeobject",&STEP::ObjectHelper<IfcTypeObject,2>::Construct )
 133.388 +,		SchemaEntry("ifctypeproduct",&STEP::ObjectHelper<IfcTypeProduct,2>::Construct )
 133.389 +,		SchemaEntry("ifcelementtype",&STEP::ObjectHelper<IfcElementType,1>::Construct )
 133.390 +,		SchemaEntry("ifcdistributionelementtype",&STEP::ObjectHelper<IfcDistributionElementType,0>::Construct )
 133.391 +,		SchemaEntry("ifcdistributionflowelementtype",&STEP::ObjectHelper<IfcDistributionFlowElementType,0>::Construct )
 133.392 +,		SchemaEntry("ifcflowcontrollertype",&STEP::ObjectHelper<IfcFlowControllerType,0>::Construct )
 133.393 +,		SchemaEntry("ifcelectrictimecontroltype",&STEP::ObjectHelper<IfcElectricTimeControlType,1>::Construct )
 133.394 +,		SchemaEntry("ifcrepresentation",&STEP::ObjectHelper<IfcRepresentation,4>::Construct )
 133.395 +,		SchemaEntry("ifcshapemodel",&STEP::ObjectHelper<IfcShapeModel,0>::Construct )
 133.396 +,		SchemaEntry("ifctopologyrepresentation",&STEP::ObjectHelper<IfcTopologyRepresentation,0>::Construct )
 133.397 +,		SchemaEntry("ifcrelationship",&STEP::ObjectHelper<IfcRelationship,0>::Construct )
 133.398 +,		SchemaEntry("ifcrelconnects",&STEP::ObjectHelper<IfcRelConnects,0>::Construct )
 133.399 +,		SchemaEntry("ifcrelcoversspaces",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.400 +,		SchemaEntry("ifcflowfittingtype",&STEP::ObjectHelper<IfcFlowFittingType,0>::Construct )
 133.401 +,		SchemaEntry("ifccablecarrierfittingtype",&STEP::ObjectHelper<IfcCableCarrierFittingType,1>::Construct )
 133.402 +,		SchemaEntry("ifcstructuralconnectioncondition",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.403 +,		SchemaEntry("ifcslippageconnectioncondition",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.404 +,		SchemaEntry("ifcenergyconversiondevicetype",&STEP::ObjectHelper<IfcEnergyConversionDeviceType,0>::Construct )
 133.405 +,		SchemaEntry("ifccoiltype",&STEP::ObjectHelper<IfcCoilType,1>::Construct )
 133.406 +,		SchemaEntry("ifcobject",&STEP::ObjectHelper<IfcObject,1>::Construct )
 133.407 +,		SchemaEntry("ifccontrol",&STEP::ObjectHelper<IfcControl,0>::Construct )
 133.408 +,		SchemaEntry("ifcperformancehistory",&STEP::ObjectHelper<IfcPerformanceHistory,1>::Construct )
 133.409 +,		SchemaEntry("ifcrepresentationitem",&STEP::ObjectHelper<IfcRepresentationItem,0>::Construct )
 133.410 +,		SchemaEntry("ifcgeometricrepresentationitem",&STEP::ObjectHelper<IfcGeometricRepresentationItem,0>::Construct )
 133.411 +,		SchemaEntry("ifctextliteral",&STEP::ObjectHelper<IfcTextLiteral,3>::Construct )
 133.412 +,		SchemaEntry("ifctextliteralwithextent",&STEP::ObjectHelper<IfcTextLiteralWithExtent,2>::Construct )
 133.413 +,		SchemaEntry("ifcproductrepresentation",&STEP::ObjectHelper<IfcProductRepresentation,3>::Construct )
 133.414 +,		SchemaEntry("ifcproduct",&STEP::ObjectHelper<IfcProduct,2>::Construct )
 133.415 +,		SchemaEntry("ifcelement",&STEP::ObjectHelper<IfcElement,1>::Construct )
 133.416 +,		SchemaEntry("ifcdistributionelement",&STEP::ObjectHelper<IfcDistributionElement,0>::Construct )
 133.417 +,		SchemaEntry("ifcdistributionflowelement",&STEP::ObjectHelper<IfcDistributionFlowElement,0>::Construct )
 133.418 +,		SchemaEntry("ifccurve",&STEP::ObjectHelper<IfcCurve,0>::Construct )
 133.419 +,		SchemaEntry("ifcboundedcurve",&STEP::ObjectHelper<IfcBoundedCurve,0>::Construct )
 133.420 +,		SchemaEntry("ifccompositecurve",&STEP::ObjectHelper<IfcCompositeCurve,2>::Construct )
 133.421 +,		SchemaEntry("ifc2dcompositecurve",&STEP::ObjectHelper<Ifc2DCompositeCurve,0>::Construct )
 133.422 +,		SchemaEntry("ifcboundarycondition",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.423 +,		SchemaEntry("ifcboundaryfacecondition",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.424 +,		SchemaEntry("ifccartesiantransformationoperator",&STEP::ObjectHelper<IfcCartesianTransformationOperator,4>::Construct )
 133.425 +,		SchemaEntry("ifccartesiantransformationoperator3d",&STEP::ObjectHelper<IfcCartesianTransformationOperator3D,1>::Construct )
 133.426 +,		SchemaEntry("ifcproperty",&STEP::ObjectHelper<IfcProperty,2>::Construct )
 133.427 +,		SchemaEntry("ifcsimpleproperty",&STEP::ObjectHelper<IfcSimpleProperty,0>::Construct )
 133.428 +,		SchemaEntry("ifcpropertyenumeratedvalue",&STEP::ObjectHelper<IfcPropertyEnumeratedValue,2>::Construct )
 133.429 +,		SchemaEntry("ifcpresentationlayerassignment",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.430 +,		SchemaEntry("ifcpresentationlayerwithstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.431 +,		SchemaEntry("ifcbuildingelementtype",&STEP::ObjectHelper<IfcBuildingElementType,0>::Construct )
 133.432 +,		SchemaEntry("ifcstairflighttype",&STEP::ObjectHelper<IfcStairFlightType,1>::Construct )
 133.433 +,		SchemaEntry("ifcsurface",&STEP::ObjectHelper<IfcSurface,0>::Construct )
 133.434 +,		SchemaEntry("ifcelementarysurface",&STEP::ObjectHelper<IfcElementarySurface,1>::Construct )
 133.435 +,		SchemaEntry("ifcplane",&STEP::ObjectHelper<IfcPlane,0>::Construct )
 133.436 +,		SchemaEntry("ifcbooleanresult",&STEP::ObjectHelper<IfcBooleanResult,3>::Construct )
 133.437 +,		SchemaEntry("ifcbooleanclippingresult",&STEP::ObjectHelper<IfcBooleanClippingResult,0>::Construct )
 133.438 +,		SchemaEntry("ifcsolidmodel",&STEP::ObjectHelper<IfcSolidModel,0>::Construct )
 133.439 +,		SchemaEntry("ifcmanifoldsolidbrep",&STEP::ObjectHelper<IfcManifoldSolidBrep,1>::Construct )
 133.440 +,		SchemaEntry("ifcprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.441 +,		SchemaEntry("ifcgeneralprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.442 +,		SchemaEntry("ifcstructuralprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.443 +,		SchemaEntry("ifcflowterminaltype",&STEP::ObjectHelper<IfcFlowTerminalType,0>::Construct )
 133.444 +,		SchemaEntry("ifcstackterminaltype",&STEP::ObjectHelper<IfcStackTerminalType,1>::Construct )
 133.445 +,		SchemaEntry("ifcstructuralitem",&STEP::ObjectHelper<IfcStructuralItem,0>::Construct )
 133.446 +,		SchemaEntry("ifcstructuralconnection",&STEP::ObjectHelper<IfcStructuralConnection,1>::Construct )
 133.447 +,		SchemaEntry("ifcstructuralcurveconnection",&STEP::ObjectHelper<IfcStructuralCurveConnection,0>::Construct )
 133.448 +,		SchemaEntry("ifcjunctionboxtype",&STEP::ObjectHelper<IfcJunctionBoxType,1>::Construct )
 133.449 +,		SchemaEntry("ifcrelassociates",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.450 +,		SchemaEntry("ifcrelassociatesconstraint",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.451 +,		SchemaEntry("ifcpropertydefinition",&STEP::ObjectHelper<IfcPropertyDefinition,0>::Construct )
 133.452 +,		SchemaEntry("ifcpropertysetdefinition",&STEP::ObjectHelper<IfcPropertySetDefinition,0>::Construct )
 133.453 +,		SchemaEntry("ifcdoorpanelproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.454 +,		SchemaEntry("ifcconstraintrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.455 +,		SchemaEntry("ifcspacethermalloadproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.456 +,		SchemaEntry("ifclibraryinformation",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.457 +,		SchemaEntry("ifcprocess",&STEP::ObjectHelper<IfcProcess,0>::Construct )
 133.458 +,		SchemaEntry("ifctask",&STEP::ObjectHelper<IfcTask,5>::Construct )
 133.459 +,		SchemaEntry("ifcappliedvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.460 +,		SchemaEntry("ifcenvironmentalimpactvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.461 +,		SchemaEntry("ifcrelfillselement",&STEP::ObjectHelper<IfcRelFillsElement,2>::Construct )
 133.462 +,		SchemaEntry("ifcprocedure",&STEP::ObjectHelper<IfcProcedure,3>::Construct )
 133.463 +,		SchemaEntry("ifcstructuralload",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.464 +,		SchemaEntry("ifcstructuralloadstatic",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.465 +,		SchemaEntry("ifcstructuralloadsingledisplacement",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.466 +,		SchemaEntry("ifcproxy",&STEP::ObjectHelper<IfcProxy,2>::Construct )
 133.467 +,		SchemaEntry("ifccurvestylefont",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.468 +,		SchemaEntry("ifcresource",&STEP::ObjectHelper<IfcResource,0>::Construct )
 133.469 +,		SchemaEntry("ifcconstructionresource",&STEP::ObjectHelper<IfcConstructionResource,4>::Construct )
 133.470 +,		SchemaEntry("ifcsubcontractresource",&STEP::ObjectHelper<IfcSubContractResource,2>::Construct )
 133.471 +,		SchemaEntry("ifccalendardate",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.472 +,		SchemaEntry("ifcdocumentelectronicformat",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.473 +,		SchemaEntry("ifcrelcontainedinspatialstructure",&STEP::ObjectHelper<IfcRelContainedInSpatialStructure,2>::Construct )
 133.474 +,		SchemaEntry("ifcmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.475 +,		SchemaEntry("ifcproductsofcombustionproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.476 +,		SchemaEntry("ifctopologicalrepresentationitem",&STEP::ObjectHelper<IfcTopologicalRepresentationItem,0>::Construct )
 133.477 +,		SchemaEntry("ifcedge",&STEP::ObjectHelper<IfcEdge,2>::Construct )
 133.478 +,		SchemaEntry("ifcedgecurve",&STEP::ObjectHelper<IfcEdgeCurve,2>::Construct )
 133.479 +,		SchemaEntry("ifcplatetype",&STEP::ObjectHelper<IfcPlateType,1>::Construct )
 133.480 +,		SchemaEntry("ifcobjectplacement",&STEP::ObjectHelper<IfcObjectPlacement,0>::Construct )
 133.481 +,		SchemaEntry("ifcgridplacement",&STEP::ObjectHelper<IfcGridPlacement,2>::Construct )
 133.482 +,		SchemaEntry("ifcfiresuppressionterminaltype",&STEP::ObjectHelper<IfcFireSuppressionTerminalType,1>::Construct )
 133.483 +,		SchemaEntry("ifcmechanicalmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.484 +,		SchemaEntry("ifcflowstoragedevice",&STEP::ObjectHelper<IfcFlowStorageDevice,0>::Construct )
 133.485 +,		SchemaEntry("ifcperson",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.486 +,		SchemaEntry("ifcsweptsurface",&STEP::ObjectHelper<IfcSweptSurface,2>::Construct )
 133.487 +,		SchemaEntry("ifcsurfaceofrevolution",&STEP::ObjectHelper<IfcSurfaceOfRevolution,1>::Construct )
 133.488 +,		SchemaEntry("ifcorientededge",&STEP::ObjectHelper<IfcOrientedEdge,2>::Construct )
 133.489 +,		SchemaEntry("ifcownerhistory",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.490 +,		SchemaEntry("ifcrelassigns",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.491 +,		SchemaEntry("ifcrelassignstoactor",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.492 +,		SchemaEntry("ifcdirection",&STEP::ObjectHelper<IfcDirection,1>::Construct )
 133.493 +,		SchemaEntry("ifcreinforcementbarproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.494 +,		SchemaEntry("ifcprofiledef",&STEP::ObjectHelper<IfcProfileDef,2>::Construct )
 133.495 +,		SchemaEntry("ifcparameterizedprofiledef",&STEP::ObjectHelper<IfcParameterizedProfileDef,1>::Construct )
 133.496 +,		SchemaEntry("ifccshapeprofiledef",&STEP::ObjectHelper<IfcCShapeProfileDef,6>::Construct )
 133.497 +,		SchemaEntry("ifcfeatureelement",&STEP::ObjectHelper<IfcFeatureElement,0>::Construct )
 133.498 +,		SchemaEntry("ifcfeatureelementsubtraction",&STEP::ObjectHelper<IfcFeatureElementSubtraction,0>::Construct )
 133.499 +,		SchemaEntry("ifcedgefeature",&STEP::ObjectHelper<IfcEdgeFeature,1>::Construct )
 133.500 +,		SchemaEntry("ifcchamferedgefeature",&STEP::ObjectHelper<IfcChamferEdgeFeature,2>::Construct )
 133.501 +,		SchemaEntry("ifcbuildingelement",&STEP::ObjectHelper<IfcBuildingElement,0>::Construct )
 133.502 +,		SchemaEntry("ifccolumn",&STEP::ObjectHelper<IfcColumn,0>::Construct )
 133.503 +,		SchemaEntry("ifcpropertyreferencevalue",&STEP::ObjectHelper<IfcPropertyReferenceValue,2>::Construct )
 133.504 +,		SchemaEntry("ifcmaterialclassificationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.505 +,		SchemaEntry("ifcelectricmotortype",&STEP::ObjectHelper<IfcElectricMotorType,1>::Construct )
 133.506 +,		SchemaEntry("ifcspatialstructureelementtype",&STEP::ObjectHelper<IfcSpatialStructureElementType,0>::Construct )
 133.507 +,		SchemaEntry("ifcspacetype",&STEP::ObjectHelper<IfcSpaceType,1>::Construct )
 133.508 +,		SchemaEntry("ifcexternalreference",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.509 +,		SchemaEntry("ifcexternallydefinedhatchstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.510 +,		SchemaEntry("ifccolumntype",&STEP::ObjectHelper<IfcColumnType,1>::Construct )
 133.511 +,		SchemaEntry("ifccranerailashapeprofiledef",&STEP::ObjectHelper<IfcCraneRailAShapeProfileDef,12>::Construct )
 133.512 +,		SchemaEntry("ifccondensertype",&STEP::ObjectHelper<IfcCondenserType,1>::Construct )
 133.513 +,		SchemaEntry("ifcrelconnectselements",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.514 +,		SchemaEntry("ifcrelconnectswithrealizingelements",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.515 +,		SchemaEntry("ifccircleprofiledef",&STEP::ObjectHelper<IfcCircleProfileDef,1>::Construct )
 133.516 +,		SchemaEntry("ifccirclehollowprofiledef",&STEP::ObjectHelper<IfcCircleHollowProfileDef,1>::Construct )
 133.517 +,		SchemaEntry("ifcorganizationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.518 +,		SchemaEntry("ifcplacement",&STEP::ObjectHelper<IfcPlacement,1>::Construct )
 133.519 +,		SchemaEntry("ifcaxis2placement3d",&STEP::ObjectHelper<IfcAxis2Placement3D,2>::Construct )
 133.520 +,		SchemaEntry("ifcpresentationstyle",&STEP::ObjectHelper<IfcPresentationStyle,1>::Construct )
 133.521 +,		SchemaEntry("ifccurvestyle",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.522 +,		SchemaEntry("ifcequipmentelement",&STEP::ObjectHelper<IfcEquipmentElement,0>::Construct )
 133.523 +,		SchemaEntry("ifccompositecurvesegment",&STEP::ObjectHelper<IfcCompositeCurveSegment,3>::Construct )
 133.524 +,		SchemaEntry("ifcrectangleprofiledef",&STEP::ObjectHelper<IfcRectangleProfileDef,2>::Construct )
 133.525 +,		SchemaEntry("ifcphysicalquantity",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.526 +,		SchemaEntry("ifcphysicalcomplexquantity",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.527 +,		SchemaEntry("ifcrelassociateslibrary",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.528 +,		SchemaEntry("ifcrelsequence",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.529 +,		SchemaEntry("ifcbuildingelementproxy",&STEP::ObjectHelper<IfcBuildingElementProxy,1>::Construct )
 133.530 +,		SchemaEntry("ifcdistributioncontrolelementtype",&STEP::ObjectHelper<IfcDistributionControlElementType,0>::Construct )
 133.531 +,		SchemaEntry("ifcflowinstrumenttype",&STEP::ObjectHelper<IfcFlowInstrumentType,1>::Construct )
 133.532 +,		SchemaEntry("ifcdraughtingcallout",&STEP::ObjectHelper<IfcDraughtingCallout,1>::Construct )
 133.533 +,		SchemaEntry("ifcdimensioncurvedirectedcallout",&STEP::ObjectHelper<IfcDimensionCurveDirectedCallout,0>::Construct )
 133.534 +,		SchemaEntry("ifclineardimension",&STEP::ObjectHelper<IfcLinearDimension,0>::Construct )
 133.535 +,		SchemaEntry("ifcelementassembly",&STEP::ObjectHelper<IfcElementAssembly,2>::Construct )
 133.536 +,		SchemaEntry("ifcdraughtingcalloutrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.537 +,		SchemaEntry("ifccsgprimitive3d",&STEP::ObjectHelper<IfcCsgPrimitive3D,1>::Construct )
 133.538 +,		SchemaEntry("ifcrightcircularcone",&STEP::ObjectHelper<IfcRightCircularCone,2>::Construct )
 133.539 +,		SchemaEntry("ifcexternallydefinedsurfacestyle",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.540 +,		SchemaEntry("ifcprojectorder",&STEP::ObjectHelper<IfcProjectOrder,3>::Construct )
 133.541 +,		SchemaEntry("ifcpropertyconstraintrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.542 +,		SchemaEntry("ifclshapeprofiledef",&STEP::ObjectHelper<IfcLShapeProfileDef,8>::Construct )
 133.543 +,		SchemaEntry("ifcangulardimension",&STEP::ObjectHelper<IfcAngularDimension,0>::Construct )
 133.544 +,		SchemaEntry("ifctextstylefordefinedfont",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.545 +,		SchemaEntry("ifclocalplacement",&STEP::ObjectHelper<IfcLocalPlacement,2>::Construct )
 133.546 +,		SchemaEntry("ifcsweptareasolid",&STEP::ObjectHelper<IfcSweptAreaSolid,2>::Construct )
 133.547 +,		SchemaEntry("ifcrevolvedareasolid",&STEP::ObjectHelper<IfcRevolvedAreaSolid,2>::Construct )
 133.548 +,		SchemaEntry("ifcstructuralsurfaceconnection",&STEP::ObjectHelper<IfcStructuralSurfaceConnection,0>::Construct )
 133.549 +,		SchemaEntry("ifcradiusdimension",&STEP::ObjectHelper<IfcRadiusDimension,0>::Construct )
 133.550 +,		SchemaEntry("ifcsweptdisksolid",&STEP::ObjectHelper<IfcSweptDiskSolid,5>::Construct )
 133.551 +,		SchemaEntry("ifchalfspacesolid",&STEP::ObjectHelper<IfcHalfSpaceSolid,2>::Construct )
 133.552 +,		SchemaEntry("ifcpolygonalboundedhalfspace",&STEP::ObjectHelper<IfcPolygonalBoundedHalfSpace,2>::Construct )
 133.553 +,		SchemaEntry("ifctimeseriesschedule",&STEP::ObjectHelper<IfcTimeSeriesSchedule,3>::Construct )
 133.554 +,		SchemaEntry("ifcdimensioncalloutrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.555 +,		SchemaEntry("ifccooledbeamtype",&STEP::ObjectHelper<IfcCooledBeamType,1>::Construct )
 133.556 +,		SchemaEntry("ifcproject",&STEP::ObjectHelper<IfcProject,4>::Construct )
 133.557 +,		SchemaEntry("ifcapprovalrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.558 +,		SchemaEntry("ifcevaporatortype",&STEP::ObjectHelper<IfcEvaporatorType,1>::Construct )
 133.559 +,		SchemaEntry("ifclaborresource",&STEP::ObjectHelper<IfcLaborResource,1>::Construct )
 133.560 +,		SchemaEntry("ifcstructuralloadsingledisplacementdistortion",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.561 +,		SchemaEntry("ifcpropertyboundedvalue",&STEP::ObjectHelper<IfcPropertyBoundedValue,3>::Construct )
 133.562 +,		SchemaEntry("ifcrampflighttype",&STEP::ObjectHelper<IfcRampFlightType,1>::Construct )
 133.563 +,		SchemaEntry("ifcmember",&STEP::ObjectHelper<IfcMember,0>::Construct )
 133.564 +,		SchemaEntry("ifcstructuralloadplanarforce",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.565 +,		SchemaEntry("ifctubebundletype",&STEP::ObjectHelper<IfcTubeBundleType,1>::Construct )
 133.566 +,		SchemaEntry("ifcvalvetype",&STEP::ObjectHelper<IfcValveType,1>::Construct )
 133.567 +,		SchemaEntry("ifcexternallydefinedtextfont",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.568 +,		SchemaEntry("ifctrimmedcurve",&STEP::ObjectHelper<IfcTrimmedCurve,5>::Construct )
 133.569 +,		SchemaEntry("ifcreldefines",&STEP::ObjectHelper<IfcRelDefines,1>::Construct )
 133.570 +,		SchemaEntry("ifcreldefinesbyproperties",&STEP::ObjectHelper<IfcRelDefinesByProperties,1>::Construct )
 133.571 +,		SchemaEntry("ifcrelassignstocontrol",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.572 +,		SchemaEntry("ifcactor",&STEP::ObjectHelper<IfcActor,1>::Construct )
 133.573 +,		SchemaEntry("ifcoccupant",&STEP::ObjectHelper<IfcOccupant,1>::Construct )
 133.574 +,		SchemaEntry("ifchumidifiertype",&STEP::ObjectHelper<IfcHumidifierType,1>::Construct )
 133.575 +,		SchemaEntry("ifcarbitraryopenprofiledef",&STEP::ObjectHelper<IfcArbitraryOpenProfileDef,1>::Construct )
 133.576 +,		SchemaEntry("ifcrelassignstoprojectorder",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.577 +,		SchemaEntry("ifcpermit",&STEP::ObjectHelper<IfcPermit,1>::Construct )
 133.578 +,		SchemaEntry("ifcoffsetcurve3d",&STEP::ObjectHelper<IfcOffsetCurve3D,4>::Construct )
 133.579 +,		SchemaEntry("ifclightsource",&STEP::ObjectHelper<IfcLightSource,4>::Construct )
 133.580 +,		SchemaEntry("ifclightsourcepositional",&STEP::ObjectHelper<IfcLightSourcePositional,5>::Construct )
 133.581 +,		SchemaEntry("ifcsurfacetexture",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.582 +,		SchemaEntry("ifcblobtexture",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.583 +,		SchemaEntry("ifccompositeprofiledef",&STEP::ObjectHelper<IfcCompositeProfileDef,2>::Construct )
 133.584 +,		SchemaEntry("ifcdocumentinformation",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.585 +,		SchemaEntry("ifcsurfacestylelighting",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.586 +,		SchemaEntry("ifcphysicalsimplequantity",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.587 +,		SchemaEntry("ifcquantityarea",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.588 +,		SchemaEntry("ifctimeseries",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.589 +,		SchemaEntry("ifcclassificationnotation",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.590 +,		SchemaEntry("ifcramp",&STEP::ObjectHelper<IfcRamp,1>::Construct )
 133.591 +,		SchemaEntry("ifcpredefineditem",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.592 +,		SchemaEntry("ifcpredefinedcurvefont",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.593 +,		SchemaEntry("ifcpredefinedcolour",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.594 +,		SchemaEntry("ifccurrencyrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.595 +,		SchemaEntry("ifcflowmovingdevice",&STEP::ObjectHelper<IfcFlowMovingDevice,0>::Construct )
 133.596 +,		SchemaEntry("ifcspaceheatertype",&STEP::ObjectHelper<IfcSpaceHeaterType,1>::Construct )
 133.597 +,		SchemaEntry("ifclamptype",&STEP::ObjectHelper<IfcLampType,1>::Construct )
 133.598 +,		SchemaEntry("ifcbuildingelementcomponent",&STEP::ObjectHelper<IfcBuildingElementComponent,0>::Construct )
 133.599 +,		SchemaEntry("ifcreinforcingelement",&STEP::ObjectHelper<IfcReinforcingElement,1>::Construct )
 133.600 +,		SchemaEntry("ifcreinforcingbar",&STEP::ObjectHelper<IfcReinforcingBar,5>::Construct )
 133.601 +,		SchemaEntry("ifcelectricheatertype",&STEP::ObjectHelper<IfcElectricHeaterType,1>::Construct )
 133.602 +,		SchemaEntry("ifctshapeprofiledef",&STEP::ObjectHelper<IfcTShapeProfileDef,10>::Construct )
 133.603 +,		SchemaEntry("ifcconstraint",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.604 +,		SchemaEntry("ifcobjective",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.605 +,		SchemaEntry("ifcstructuralactivity",&STEP::ObjectHelper<IfcStructuralActivity,2>::Construct )
 133.606 +,		SchemaEntry("ifcstructuralaction",&STEP::ObjectHelper<IfcStructuralAction,2>::Construct )
 133.607 +,		SchemaEntry("ifctexturecoordinate",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.608 +,		SchemaEntry("ifctexturemap",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.609 +,		SchemaEntry("ifcmonetaryunit",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.610 +,		SchemaEntry("ifcquantitytime",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.611 +,		SchemaEntry("ifctablerow",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.612 +,		SchemaEntry("ifclightdistributiondata",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.613 +,		SchemaEntry("ifcductfittingtype",&STEP::ObjectHelper<IfcDuctFittingType,1>::Construct )
 133.614 +,		SchemaEntry("ifccartesiantransformationoperator2d",&STEP::ObjectHelper<IfcCartesianTransformationOperator2D,0>::Construct )
 133.615 +,		SchemaEntry("ifccartesiantransformationoperator2dnonuniform",&STEP::ObjectHelper<IfcCartesianTransformationOperator2DnonUniform,1>::Construct )
 133.616 +,		SchemaEntry("ifcclassificationnotationfacet",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.617 +,		SchemaEntry("ifcrelassociatesapproval",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.618 +,		SchemaEntry("ifcdraughtingpredefinedcurvefont",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.619 +,		SchemaEntry("ifcstructuralloadsingleforce",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.620 +,		SchemaEntry("ifcstructuralloadsingleforcewarping",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.621 +,		SchemaEntry("ifccurvestylefontandscaling",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.622 +,		SchemaEntry("ifcvirtualelement",&STEP::ObjectHelper<IfcVirtualElement,0>::Construct )
 133.623 +,		SchemaEntry("ifcrightcircularcylinder",&STEP::ObjectHelper<IfcRightCircularCylinder,2>::Construct )
 133.624 +,		SchemaEntry("ifcoutlettype",&STEP::ObjectHelper<IfcOutletType,1>::Construct )
 133.625 +,		SchemaEntry("ifcreldecomposes",&STEP::ObjectHelper<IfcRelDecomposes,2>::Construct )
 133.626 +,		SchemaEntry("ifcrelnests",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.627 +,		SchemaEntry("ifccovering",&STEP::ObjectHelper<IfcCovering,1>::Construct )
 133.628 +,		SchemaEntry("ifcexternallydefinedsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.629 +,		SchemaEntry("ifcirregulartimeseries",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.630 +,		SchemaEntry("ifcpolyline",&STEP::ObjectHelper<IfcPolyline,1>::Construct )
 133.631 +,		SchemaEntry("ifcpath",&STEP::ObjectHelper<IfcPath,1>::Construct )
 133.632 +,		SchemaEntry("ifcelementcomponent",&STEP::ObjectHelper<IfcElementComponent,0>::Construct )
 133.633 +,		SchemaEntry("ifcfastener",&STEP::ObjectHelper<IfcFastener,0>::Construct )
 133.634 +,		SchemaEntry("ifcmappeditem",&STEP::ObjectHelper<IfcMappedItem,2>::Construct )
 133.635 +,		SchemaEntry("ifcmetric",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.636 +,		SchemaEntry("ifcdocumentreference",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.637 +,		SchemaEntry("ifcsectionproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.638 +,		SchemaEntry("ifcrectangularpyramid",&STEP::ObjectHelper<IfcRectangularPyramid,3>::Construct )
 133.639 +,		SchemaEntry("ifcrelreferencedinspatialstructure",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.640 +,		SchemaEntry("ifccrewresource",&STEP::ObjectHelper<IfcCrewResource,0>::Construct )
 133.641 +,		SchemaEntry("ifcnamedunit",&STEP::ObjectHelper<IfcNamedUnit,2>::Construct )
 133.642 +,		SchemaEntry("ifccontextdependentunit",&STEP::ObjectHelper<IfcContextDependentUnit,1>::Construct )
 133.643 +,		SchemaEntry("ifcunitaryequipmenttype",&STEP::ObjectHelper<IfcUnitaryEquipmentType,1>::Construct )
 133.644 +,		SchemaEntry("ifcroof",&STEP::ObjectHelper<IfcRoof,1>::Construct )
 133.645 +,		SchemaEntry("ifcrelassignstasks",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.646 +,		SchemaEntry("ifcstructuralmember",&STEP::ObjectHelper<IfcStructuralMember,0>::Construct )
 133.647 +,		SchemaEntry("ifcrelconnectsports",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.648 +,		SchemaEntry("ifcstylemodel",&STEP::ObjectHelper<IfcStyleModel,0>::Construct )
 133.649 +,		SchemaEntry("ifcstyledrepresentation",&STEP::ObjectHelper<IfcStyledRepresentation,0>::Construct )
 133.650 +,		SchemaEntry("ifcspatialstructureelement",&STEP::ObjectHelper<IfcSpatialStructureElement,2>::Construct )
 133.651 +,		SchemaEntry("ifcbuilding",&STEP::ObjectHelper<IfcBuilding,3>::Construct )
 133.652 +,		SchemaEntry("ifcconnectedfaceset",&STEP::ObjectHelper<IfcConnectedFaceSet,1>::Construct )
 133.653 +,		SchemaEntry("ifcopenshell",&STEP::ObjectHelper<IfcOpenShell,0>::Construct )
 133.654 +,		SchemaEntry("ifcfacetedbrep",&STEP::ObjectHelper<IfcFacetedBrep,0>::Construct )
 133.655 +,		SchemaEntry("ifclocaltime",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.656 +,		SchemaEntry("ifcmechanicalconcretematerialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.657 +,		SchemaEntry("ifcconic",&STEP::ObjectHelper<IfcConic,1>::Construct )
 133.658 +,		SchemaEntry("ifccoveringtype",&STEP::ObjectHelper<IfcCoveringType,1>::Construct )
 133.659 +,		SchemaEntry("ifcroundedrectangleprofiledef",&STEP::ObjectHelper<IfcRoundedRectangleProfileDef,1>::Construct )
 133.660 +,		SchemaEntry("ifcairterminaltype",&STEP::ObjectHelper<IfcAirTerminalType,1>::Construct )
 133.661 +,		SchemaEntry("ifcflowmovingdevicetype",&STEP::ObjectHelper<IfcFlowMovingDeviceType,0>::Construct )
 133.662 +,		SchemaEntry("ifccompressortype",&STEP::ObjectHelper<IfcCompressorType,1>::Construct )
 133.663 +,		SchemaEntry("ifcwindowpanelproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.664 +,		SchemaEntry("ifcpredefinedsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.665 +,		SchemaEntry("ifcpredefinedterminatorsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.666 +,		SchemaEntry("ifcishapeprofiledef",&STEP::ObjectHelper<IfcIShapeProfileDef,5>::Construct )
 133.667 +,		SchemaEntry("ifcasymmetricishapeprofiledef",&STEP::ObjectHelper<IfcAsymmetricIShapeProfileDef,4>::Construct )
 133.668 +,		SchemaEntry("ifccontrollertype",&STEP::ObjectHelper<IfcControllerType,1>::Construct )
 133.669 +,		SchemaEntry("ifcrailing",&STEP::ObjectHelper<IfcRailing,1>::Construct )
 133.670 +,		SchemaEntry("ifcgroup",&STEP::ObjectHelper<IfcGroup,0>::Construct )
 133.671 +,		SchemaEntry("ifcasset",&STEP::ObjectHelper<IfcAsset,9>::Construct )
 133.672 +,		SchemaEntry("ifcmaterialdefinitionrepresentation",&STEP::ObjectHelper<IfcMaterialDefinitionRepresentation,1>::Construct )
 133.673 +,		SchemaEntry("ifccurvestylefontpattern",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.674 +,		SchemaEntry("ifcapprovalpropertyrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.675 +,		SchemaEntry("ifcrailingtype",&STEP::ObjectHelper<IfcRailingType,1>::Construct )
 133.676 +,		SchemaEntry("ifcwall",&STEP::ObjectHelper<IfcWall,0>::Construct )
 133.677 +,		SchemaEntry("ifcclassificationitem",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.678 +,		SchemaEntry("ifcstructuralpointconnection",&STEP::ObjectHelper<IfcStructuralPointConnection,0>::Construct )
 133.679 +,		SchemaEntry("ifcconnectiongeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.680 +,		SchemaEntry("ifcconnectionpointgeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.681 +,		SchemaEntry("ifctimeseriesvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.682 +,		SchemaEntry("ifcpropertylistvalue",&STEP::ObjectHelper<IfcPropertyListValue,2>::Construct )
 133.683 +,		SchemaEntry("ifcfurniturestandard",&STEP::ObjectHelper<IfcFurnitureStandard,0>::Construct )
 133.684 +,		SchemaEntry("ifcrelschedulescostitems",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.685 +,		SchemaEntry("ifcelectricgeneratortype",&STEP::ObjectHelper<IfcElectricGeneratorType,1>::Construct )
 133.686 +,		SchemaEntry("ifcdoor",&STEP::ObjectHelper<IfcDoor,2>::Construct )
 133.687 +,		SchemaEntry("ifcstyleditem",&STEP::ObjectHelper<IfcStyledItem,3>::Construct )
 133.688 +,		SchemaEntry("ifcannotationoccurrence",&STEP::ObjectHelper<IfcAnnotationOccurrence,0>::Construct )
 133.689 +,		SchemaEntry("ifcannotationsymboloccurrence",&STEP::ObjectHelper<IfcAnnotationSymbolOccurrence,0>::Construct )
 133.690 +,		SchemaEntry("ifcarbitraryclosedprofiledef",&STEP::ObjectHelper<IfcArbitraryClosedProfileDef,1>::Construct )
 133.691 +,		SchemaEntry("ifcarbitraryprofiledefwithvoids",&STEP::ObjectHelper<IfcArbitraryProfileDefWithVoids,1>::Construct )
 133.692 +,		SchemaEntry("ifcline",&STEP::ObjectHelper<IfcLine,2>::Construct )
 133.693 +,		SchemaEntry("ifcmateriallayerset",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.694 +,		SchemaEntry("ifcflowsegmenttype",&STEP::ObjectHelper<IfcFlowSegmentType,0>::Construct )
 133.695 +,		SchemaEntry("ifcairterminalboxtype",&STEP::ObjectHelper<IfcAirTerminalBoxType,1>::Construct )
 133.696 +,		SchemaEntry("ifcrelconnectsstructuralmember",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.697 +,		SchemaEntry("ifcpropertysinglevalue",&STEP::ObjectHelper<IfcPropertySingleValue,2>::Construct )
 133.698 +,		SchemaEntry("ifcalarmtype",&STEP::ObjectHelper<IfcAlarmType,1>::Construct )
 133.699 +,		SchemaEntry("ifcellipseprofiledef",&STEP::ObjectHelper<IfcEllipseProfileDef,2>::Construct )
 133.700 +,		SchemaEntry("ifcstair",&STEP::ObjectHelper<IfcStair,1>::Construct )
 133.701 +,		SchemaEntry("ifcpredefinedtextfont",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.702 +,		SchemaEntry("ifctextstylefontmodel",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.703 +,		SchemaEntry("ifcsurfacestyleshading",&STEP::ObjectHelper<IfcSurfaceStyleShading,1>::Construct )
 133.704 +,		SchemaEntry("ifcpumptype",&STEP::ObjectHelper<IfcPumpType,1>::Construct )
 133.705 +,		SchemaEntry("ifcdefinedsymbol",&STEP::ObjectHelper<IfcDefinedSymbol,2>::Construct )
 133.706 +,		SchemaEntry("ifcclassificationitemrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.707 +,		SchemaEntry("ifcgeneralmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.708 +,		SchemaEntry("ifcelementcomponenttype",&STEP::ObjectHelper<IfcElementComponentType,0>::Construct )
 133.709 +,		SchemaEntry("ifcfastenertype",&STEP::ObjectHelper<IfcFastenerType,0>::Construct )
 133.710 +,		SchemaEntry("ifcmechanicalfastenertype",&STEP::ObjectHelper<IfcMechanicalFastenerType,0>::Construct )
 133.711 +,		SchemaEntry("ifcpermeablecoveringproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.712 +,		SchemaEntry("ifcflowfitting",&STEP::ObjectHelper<IfcFlowFitting,0>::Construct )
 133.713 +,		SchemaEntry("ifcapproval",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.714 +,		SchemaEntry("ifcshapeaspect",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.715 +,		SchemaEntry("ifcconstraintclassificationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.716 +,		SchemaEntry("ifclightsourcedirectional",&STEP::ObjectHelper<IfcLightSourceDirectional,1>::Construct )
 133.717 +,		SchemaEntry("ifcsurfacestyle",&STEP::ObjectHelper<IfcSurfaceStyle,2>::Construct )
 133.718 +,		SchemaEntry("ifcrelconnectsstructuralactivity",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.719 +,		SchemaEntry("ifcrelassociatesprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.720 +,		SchemaEntry("ifcannotationsurface",&STEP::ObjectHelper<IfcAnnotationSurface,2>::Construct )
 133.721 +,		SchemaEntry("ifcfuelproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.722 +,		SchemaEntry("ifcflowcontroller",&STEP::ObjectHelper<IfcFlowController,0>::Construct )
 133.723 +,		SchemaEntry("ifcfailureconnectioncondition",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.724 +,		SchemaEntry("ifcbuildingstorey",&STEP::ObjectHelper<IfcBuildingStorey,1>::Construct )
 133.725 +,		SchemaEntry("ifcworkcontrol",&STEP::ObjectHelper<IfcWorkControl,10>::Construct )
 133.726 +,		SchemaEntry("ifcworkschedule",&STEP::ObjectHelper<IfcWorkSchedule,0>::Construct )
 133.727 +,		SchemaEntry("ifctable",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.728 +,		SchemaEntry("ifcductsegmenttype",&STEP::ObjectHelper<IfcDuctSegmentType,1>::Construct )
 133.729 +,		SchemaEntry("ifcstructuralsteelprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.730 +,		SchemaEntry("ifcdraughtingpredefinedtextfont",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.731 +,		SchemaEntry("ifcface",&STEP::ObjectHelper<IfcFace,1>::Construct )
 133.732 +,		SchemaEntry("ifcstructuralsurfacemember",&STEP::ObjectHelper<IfcStructuralSurfaceMember,2>::Construct )
 133.733 +,		SchemaEntry("ifcstructuralsurfacemembervarying",&STEP::ObjectHelper<IfcStructuralSurfaceMemberVarying,2>::Construct )
 133.734 +,		SchemaEntry("ifcfacesurface",&STEP::ObjectHelper<IfcFaceSurface,2>::Construct )
 133.735 +,		SchemaEntry("ifcclassification",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.736 +,		SchemaEntry("ifcmateriallist",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.737 +,		SchemaEntry("ifccostschedule",&STEP::ObjectHelper<IfcCostSchedule,8>::Construct )
 133.738 +,		SchemaEntry("ifccoordinateduniversaltimeoffset",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.739 +,		SchemaEntry("ifcplanarextent",&STEP::ObjectHelper<IfcPlanarExtent,2>::Construct )
 133.740 +,		SchemaEntry("ifcplanarbox",&STEP::ObjectHelper<IfcPlanarBox,1>::Construct )
 133.741 +,		SchemaEntry("ifcfillareastyle",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.742 +,		SchemaEntry("ifcsectionreinforcementproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.743 +,		SchemaEntry("ifccolourspecification",&STEP::ObjectHelper<IfcColourSpecification,1>::Construct )
 133.744 +,		SchemaEntry("ifcvector",&STEP::ObjectHelper<IfcVector,2>::Construct )
 133.745 +,		SchemaEntry("ifcbeam",&STEP::ObjectHelper<IfcBeam,0>::Construct )
 133.746 +,		SchemaEntry("ifccolourrgb",&STEP::ObjectHelper<IfcColourRgb,3>::Construct )
 133.747 +,		SchemaEntry("ifcstructuralplanaraction",&STEP::ObjectHelper<IfcStructuralPlanarAction,1>::Construct )
 133.748 +,		SchemaEntry("ifcstructuralplanaractionvarying",&STEP::ObjectHelper<IfcStructuralPlanarActionVarying,2>::Construct )
 133.749 +,		SchemaEntry("ifcsite",&STEP::ObjectHelper<IfcSite,5>::Construct )
 133.750 +,		SchemaEntry("ifcdiscreteaccessorytype",&STEP::ObjectHelper<IfcDiscreteAccessoryType,0>::Construct )
 133.751 +,		SchemaEntry("ifcvibrationisolatortype",&STEP::ObjectHelper<IfcVibrationIsolatorType,1>::Construct )
 133.752 +,		SchemaEntry("ifcevaporativecoolertype",&STEP::ObjectHelper<IfcEvaporativeCoolerType,1>::Construct )
 133.753 +,		SchemaEntry("ifcdistributionchamberelementtype",&STEP::ObjectHelper<IfcDistributionChamberElementType,1>::Construct )
 133.754 +,		SchemaEntry("ifcfeatureelementaddition",&STEP::ObjectHelper<IfcFeatureElementAddition,0>::Construct )
 133.755 +,		SchemaEntry("ifcrelassignstoresource",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.756 +,		SchemaEntry("ifcstructureddimensioncallout",&STEP::ObjectHelper<IfcStructuredDimensionCallout,0>::Construct )
 133.757 +,		SchemaEntry("ifccoolingtowertype",&STEP::ObjectHelper<IfcCoolingTowerType,1>::Construct )
 133.758 +,		SchemaEntry("ifccenterlineprofiledef",&STEP::ObjectHelper<IfcCenterLineProfileDef,1>::Construct )
 133.759 +,		SchemaEntry("ifctexturevertex",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.760 +,		SchemaEntry("ifcorganization",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.761 +,		SchemaEntry("ifcwindowstyle",&STEP::ObjectHelper<IfcWindowStyle,4>::Construct )
 133.762 +,		SchemaEntry("ifclightsourcegoniometric",&STEP::ObjectHelper<IfcLightSourceGoniometric,6>::Construct )
 133.763 +,		SchemaEntry("ifcribplateprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.764 +,		SchemaEntry("ifctransformertype",&STEP::ObjectHelper<IfcTransformerType,1>::Construct )
 133.765 +,		SchemaEntry("ifcmembertype",&STEP::ObjectHelper<IfcMemberType,1>::Construct )
 133.766 +,		SchemaEntry("ifcsurfaceoflinearextrusion",&STEP::ObjectHelper<IfcSurfaceOfLinearExtrusion,2>::Construct )
 133.767 +,		SchemaEntry("ifcmotorconnectiontype",&STEP::ObjectHelper<IfcMotorConnectionType,1>::Construct )
 133.768 +,		SchemaEntry("ifcflowtreatmentdevicetype",&STEP::ObjectHelper<IfcFlowTreatmentDeviceType,0>::Construct )
 133.769 +,		SchemaEntry("ifcductsilencertype",&STEP::ObjectHelper<IfcDuctSilencerType,1>::Construct )
 133.770 +,		SchemaEntry("ifcwindowliningproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.771 +,		SchemaEntry("ifcfurnishingelementtype",&STEP::ObjectHelper<IfcFurnishingElementType,0>::Construct )
 133.772 +,		SchemaEntry("ifcsystemfurnitureelementtype",&STEP::ObjectHelper<IfcSystemFurnitureElementType,0>::Construct )
 133.773 +,		SchemaEntry("ifcconnectionpointeccentricity",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.774 +,		SchemaEntry("ifcwasteterminaltype",&STEP::ObjectHelper<IfcWasteTerminalType,1>::Construct )
 133.775 +,		SchemaEntry("ifcbsplinecurve",&STEP::ObjectHelper<IfcBSplineCurve,5>::Construct )
 133.776 +,		SchemaEntry("ifcbeziercurve",&STEP::ObjectHelper<IfcBezierCurve,0>::Construct )
 133.777 +,		SchemaEntry("ifcdocumentinformationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.778 +,		SchemaEntry("ifcactuatortype",&STEP::ObjectHelper<IfcActuatorType,1>::Construct )
 133.779 +,		SchemaEntry("ifcdistributioncontrolelement",&STEP::ObjectHelper<IfcDistributionControlElement,1>::Construct )
 133.780 +,		SchemaEntry("ifcannotation",&STEP::ObjectHelper<IfcAnnotation,0>::Construct )
 133.781 +,		SchemaEntry("ifcrelassociatesdocument",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.782 +,		SchemaEntry("ifcdoorliningproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.783 +,		SchemaEntry("ifcshellbasedsurfacemodel",&STEP::ObjectHelper<IfcShellBasedSurfaceModel,1>::Construct )
 133.784 +,		SchemaEntry("ifcactionrequest",&STEP::ObjectHelper<IfcActionRequest,1>::Construct )
 133.785 +,		SchemaEntry("ifcextrudedareasolid",&STEP::ObjectHelper<IfcExtrudedAreaSolid,2>::Construct )
 133.786 +,		SchemaEntry("ifcsystem",&STEP::ObjectHelper<IfcSystem,0>::Construct )
 133.787 +,		SchemaEntry("ifcfillareastylehatching",&STEP::ObjectHelper<IfcFillAreaStyleHatching,5>::Construct )
 133.788 +,		SchemaEntry("ifcrelvoidselement",&STEP::ObjectHelper<IfcRelVoidsElement,2>::Construct )
 133.789 +,		SchemaEntry("ifcrelconnectspathelements",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.790 +,		SchemaEntry("ifcrelspaceboundary",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.791 +,		SchemaEntry("ifcsurfacecurvesweptareasolid",&STEP::ObjectHelper<IfcSurfaceCurveSweptAreaSolid,4>::Construct )
 133.792 +,		SchemaEntry("ifccartesiantransformationoperator3dnonuniform",&STEP::ObjectHelper<IfcCartesianTransformationOperator3DnonUniform,2>::Construct )
 133.793 +,		SchemaEntry("ifcrelinteractionrequirements",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.794 +,		SchemaEntry("ifccurtainwalltype",&STEP::ObjectHelper<IfcCurtainWallType,1>::Construct )
 133.795 +,		SchemaEntry("ifcquantitylength",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.796 +,		SchemaEntry("ifcequipmentstandard",&STEP::ObjectHelper<IfcEquipmentStandard,0>::Construct )
 133.797 +,		SchemaEntry("ifcflowstoragedevicetype",&STEP::ObjectHelper<IfcFlowStorageDeviceType,0>::Construct )
 133.798 +,		SchemaEntry("ifcvirtualgridintersection",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.799 +,		SchemaEntry("ifcdiameterdimension",&STEP::ObjectHelper<IfcDiameterDimension,0>::Construct )
 133.800 +,		SchemaEntry("ifcswitchingdevicetype",&STEP::ObjectHelper<IfcSwitchingDeviceType,1>::Construct )
 133.801 +,		SchemaEntry("ifcaddress",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.802 +,		SchemaEntry("ifctelecomaddress",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.803 +,		SchemaEntry("ifcwindow",&STEP::ObjectHelper<IfcWindow,2>::Construct )
 133.804 +,		SchemaEntry("ifcmechanicalsteelmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.805 +,		SchemaEntry("ifcflowtreatmentdevice",&STEP::ObjectHelper<IfcFlowTreatmentDevice,0>::Construct )
 133.806 +,		SchemaEntry("ifcrelservicesbuildings",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.807 +,		SchemaEntry("ifcchillertype",&STEP::ObjectHelper<IfcChillerType,1>::Construct )
 133.808 +,		SchemaEntry("ifcrelassignstoproduct",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.809 +,		SchemaEntry("ifcrectanglehollowprofiledef",&STEP::ObjectHelper<IfcRectangleHollowProfileDef,3>::Construct )
 133.810 +,		SchemaEntry("ifcenergyproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.811 +,		SchemaEntry("ifcboxedhalfspace",&STEP::ObjectHelper<IfcBoxedHalfSpace,1>::Construct )
 133.812 +,		SchemaEntry("ifcaxis2placement2d",&STEP::ObjectHelper<IfcAxis2Placement2D,1>::Construct )
 133.813 +,		SchemaEntry("ifcspaceprogram",&STEP::ObjectHelper<IfcSpaceProgram,5>::Construct )
 133.814 +,		SchemaEntry("ifcpoint",&STEP::ObjectHelper<IfcPoint,0>::Construct )
 133.815 +,		SchemaEntry("ifccartesianpoint",&STEP::ObjectHelper<IfcCartesianPoint,1>::Construct )
 133.816 +,		SchemaEntry("ifcboundedsurface",&STEP::ObjectHelper<IfcBoundedSurface,0>::Construct )
 133.817 +,		SchemaEntry("ifcloop",&STEP::ObjectHelper<IfcLoop,0>::Construct )
 133.818 +,		SchemaEntry("ifcpolyloop",&STEP::ObjectHelper<IfcPolyLoop,1>::Construct )
 133.819 +,		SchemaEntry("ifcpredefinedpointmarkersymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.820 +,		SchemaEntry("ifcterminatorsymbol",&STEP::ObjectHelper<IfcTerminatorSymbol,1>::Construct )
 133.821 +,		SchemaEntry("ifcdimensioncurveterminator",&STEP::ObjectHelper<IfcDimensionCurveTerminator,1>::Construct )
 133.822 +,		SchemaEntry("ifcrelprojectselement",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.823 +,		SchemaEntry("ifctrapeziumprofiledef",&STEP::ObjectHelper<IfcTrapeziumProfileDef,4>::Construct )
 133.824 +,		SchemaEntry("ifcrepresentationcontext",&STEP::ObjectHelper<IfcRepresentationContext,2>::Construct )
 133.825 +,		SchemaEntry("ifcgeometricrepresentationcontext",&STEP::ObjectHelper<IfcGeometricRepresentationContext,4>::Construct )
 133.826 +,		SchemaEntry("ifctextstylewithboxcharacteristics",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.827 +,		SchemaEntry("ifccurveboundedplane",&STEP::ObjectHelper<IfcCurveBoundedPlane,3>::Construct )
 133.828 +,		SchemaEntry("ifcquantitycount",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.829 +,		SchemaEntry("ifctimeseriesreferencerelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.830 +,		SchemaEntry("ifcstructuralloadtemperature",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.831 +,		SchemaEntry("ifcsiunit",&STEP::ObjectHelper<IfcSIUnit,2>::Construct )
 133.832 +,		SchemaEntry("ifcstructuralreaction",&STEP::ObjectHelper<IfcStructuralReaction,0>::Construct )
 133.833 +,		SchemaEntry("ifcstructuralpointreaction",&STEP::ObjectHelper<IfcStructuralPointReaction,0>::Construct )
 133.834 +,		SchemaEntry("ifcaxis1placement",&STEP::ObjectHelper<IfcAxis1Placement,1>::Construct )
 133.835 +,		SchemaEntry("ifcreinforcementdefinitionproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.836 +,		SchemaEntry("ifcelectricappliancetype",&STEP::ObjectHelper<IfcElectricApplianceType,1>::Construct )
 133.837 +,		SchemaEntry("ifcsensortype",&STEP::ObjectHelper<IfcSensorType,1>::Construct )
 133.838 +,		SchemaEntry("ifcfurnishingelement",&STEP::ObjectHelper<IfcFurnishingElement,0>::Construct )
 133.839 +,		SchemaEntry("ifcprotectivedevicetype",&STEP::ObjectHelper<IfcProtectiveDeviceType,1>::Construct )
 133.840 +,		SchemaEntry("ifczshapeprofiledef",&STEP::ObjectHelper<IfcZShapeProfileDef,6>::Construct )
 133.841 +,		SchemaEntry("ifcscheduletimecontrol",&STEP::ObjectHelper<IfcScheduleTimeControl,18>::Construct )
 133.842 +,		SchemaEntry("ifcrepresentationmap",&STEP::ObjectHelper<IfcRepresentationMap,2>::Construct )
 133.843 +,		SchemaEntry("ifcclosedshell",&STEP::ObjectHelper<IfcClosedShell,0>::Construct )
 133.844 +,		SchemaEntry("ifcbuildingelementpart",&STEP::ObjectHelper<IfcBuildingElementPart,0>::Construct )
 133.845 +,		SchemaEntry("ifcdraughtingpredefinedcolour",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.846 +,		SchemaEntry("ifcpostaladdress",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.847 +,		SchemaEntry("ifcblock",&STEP::ObjectHelper<IfcBlock,3>::Construct )
 133.848 +,		SchemaEntry("ifclightfixturetype",&STEP::ObjectHelper<IfcLightFixtureType,1>::Construct )
 133.849 +,		SchemaEntry("ifcopeningelement",&STEP::ObjectHelper<IfcOpeningElement,0>::Construct )
 133.850 +,		SchemaEntry("ifclightsourcespot",&STEP::ObjectHelper<IfcLightSourceSpot,4>::Construct )
 133.851 +,		SchemaEntry("ifctendonanchor",&STEP::ObjectHelper<IfcTendonAnchor,0>::Construct )
 133.852 +,		SchemaEntry("ifcsurfacestylerefraction",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.853 +,		SchemaEntry("ifcelectricflowstoragedevicetype",&STEP::ObjectHelper<IfcElectricFlowStorageDeviceType,1>::Construct )
 133.854 +,		SchemaEntry("ifcfluidflowproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.855 +,		SchemaEntry("ifcsphere",&STEP::ObjectHelper<IfcSphere,1>::Construct )
 133.856 +,		SchemaEntry("ifcrelassociatesappliedvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.857 +,		SchemaEntry("ifcdampertype",&STEP::ObjectHelper<IfcDamperType,1>::Construct )
 133.858 +,		SchemaEntry("ifcprojectorderrecord",&STEP::ObjectHelper<IfcProjectOrderRecord,2>::Construct )
 133.859 +,		SchemaEntry("ifcdimensionalexponents",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.860 +,		SchemaEntry("ifcreldefinesbytype",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.861 +,		SchemaEntry("ifcdistributionchamberelement",&STEP::ObjectHelper<IfcDistributionChamberElement,0>::Construct )
 133.862 +,		SchemaEntry("ifcmechanicalfastener",&STEP::ObjectHelper<IfcMechanicalFastener,2>::Construct )
 133.863 +,		SchemaEntry("ifcquantityvolume",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.864 +,		SchemaEntry("ifcrectangulartrimmedsurface",&STEP::ObjectHelper<IfcRectangularTrimmedSurface,7>::Construct )
 133.865 +,		SchemaEntry("ifcdateandtime",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.866 +,		SchemaEntry("ifczone",&STEP::ObjectHelper<IfcZone,0>::Construct )
 133.867 +,		SchemaEntry("ifcfantype",&STEP::ObjectHelper<IfcFanType,1>::Construct )
 133.868 +,		SchemaEntry("ifcgeometricset",&STEP::ObjectHelper<IfcGeometricSet,1>::Construct )
 133.869 +,		SchemaEntry("ifcfillareastyletiles",&STEP::ObjectHelper<IfcFillAreaStyleTiles,3>::Construct )
 133.870 +,		SchemaEntry("ifcpixeltexture",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.871 +,		SchemaEntry("ifccablesegmenttype",&STEP::ObjectHelper<IfcCableSegmentType,1>::Construct )
 133.872 +,		SchemaEntry("ifcreloverridesproperties",&STEP::ObjectHelper<IfcRelOverridesProperties,1>::Construct )
 133.873 +,		SchemaEntry("ifcmeasurewithunit",&STEP::ObjectHelper<IfcMeasureWithUnit,2>::Construct )
 133.874 +,		SchemaEntry("ifcslabtype",&STEP::ObjectHelper<IfcSlabType,1>::Construct )
 133.875 +,		SchemaEntry("ifcservicelife",&STEP::ObjectHelper<IfcServiceLife,2>::Construct )
 133.876 +,		SchemaEntry("ifcfurnituretype",&STEP::ObjectHelper<IfcFurnitureType,1>::Construct )
 133.877 +,		SchemaEntry("ifccostitem",&STEP::ObjectHelper<IfcCostItem,0>::Construct )
 133.878 +,		SchemaEntry("ifcreinforcingmesh",&STEP::ObjectHelper<IfcReinforcingMesh,8>::Construct )
 133.879 +,		SchemaEntry("ifcextendedmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.880 +,		SchemaEntry("ifcactorrole",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.881 +,		SchemaEntry("ifcfacetedbrepwithvoids",&STEP::ObjectHelper<IfcFacetedBrepWithVoids,1>::Construct )
 133.882 +,		SchemaEntry("ifcconstraintaggregationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.883 +,		SchemaEntry("ifcgasterminaltype",&STEP::ObjectHelper<IfcGasTerminalType,1>::Construct )
 133.884 +,		SchemaEntry("ifcrelconnectswitheccentricity",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.885 +,		SchemaEntry("ifcpile",&STEP::ObjectHelper<IfcPile,2>::Construct )
 133.886 +,		SchemaEntry("ifcfillareastyletilesymbolwithstyle",&STEP::ObjectHelper<IfcFillAreaStyleTileSymbolWithStyle,1>::Construct )
 133.887 +,		SchemaEntry("ifcelectricalbaseproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.888 +,		SchemaEntry("ifcconstructionmaterialresource",&STEP::ObjectHelper<IfcConstructionMaterialResource,2>::Construct )
 133.889 +,		SchemaEntry("ifcannotationcurveoccurrence",&STEP::ObjectHelper<IfcAnnotationCurveOccurrence,0>::Construct )
 133.890 +,		SchemaEntry("ifcdimensioncurve",&STEP::ObjectHelper<IfcDimensionCurve,0>::Construct )
 133.891 +,		SchemaEntry("ifcgeometriccurveset",&STEP::ObjectHelper<IfcGeometricCurveSet,0>::Construct )
 133.892 +,		SchemaEntry("ifcrelaggregates",&STEP::ObjectHelper<IfcRelAggregates,0>::Construct )
 133.893 +,		SchemaEntry("ifcfacebasedsurfacemodel",&STEP::ObjectHelper<IfcFaceBasedSurfaceModel,1>::Construct )
 133.894 +,		SchemaEntry("ifcenergyconversiondevice",&STEP::ObjectHelper<IfcEnergyConversionDevice,0>::Construct )
 133.895 +,		SchemaEntry("ifcrampflight",&STEP::ObjectHelper<IfcRampFlight,0>::Construct )
 133.896 +,		SchemaEntry("ifcpropertyenumeration",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.897 +,		SchemaEntry("ifcvertexloop",&STEP::ObjectHelper<IfcVertexLoop,1>::Construct )
 133.898 +,		SchemaEntry("ifcplate",&STEP::ObjectHelper<IfcPlate,0>::Construct )
 133.899 +,		SchemaEntry("ifcushapeprofiledef",&STEP::ObjectHelper<IfcUShapeProfileDef,8>::Construct )
 133.900 +,		SchemaEntry("ifchygroscopicmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.901 +,		SchemaEntry("ifcfacebound",&STEP::ObjectHelper<IfcFaceBound,2>::Construct )
 133.902 +,		SchemaEntry("ifcfaceouterbound",&STEP::ObjectHelper<IfcFaceOuterBound,0>::Construct )
 133.903 +,		SchemaEntry("ifconedirectionrepeatfactor",&STEP::ObjectHelper<IfcOneDirectionRepeatFactor,1>::Construct )
 133.904 +,		SchemaEntry("ifcboilertype",&STEP::ObjectHelper<IfcBoilerType,1>::Construct )
 133.905 +,		SchemaEntry("ifcconstructionequipmentresource",&STEP::ObjectHelper<IfcConstructionEquipmentResource,0>::Construct )
 133.906 +,		SchemaEntry("ifccomplexproperty",&STEP::ObjectHelper<IfcComplexProperty,2>::Construct )
 133.907 +,		SchemaEntry("ifcfooting",&STEP::ObjectHelper<IfcFooting,1>::Construct )
 133.908 +,		SchemaEntry("ifcopticalmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.909 +,		SchemaEntry("ifcconstructionproductresource",&STEP::ObjectHelper<IfcConstructionProductResource,0>::Construct )
 133.910 +,		SchemaEntry("ifcboundaryedgecondition",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.911 +,		SchemaEntry("ifcderivedprofiledef",&STEP::ObjectHelper<IfcDerivedProfileDef,3>::Construct )
 133.912 +,		SchemaEntry("ifcpropertytablevalue",&STEP::ObjectHelper<IfcPropertyTableValue,5>::Construct )
 133.913 +,		SchemaEntry("ifcrelassignstogroup",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.914 +,		SchemaEntry("ifcflowmetertype",&STEP::ObjectHelper<IfcFlowMeterType,1>::Construct )
 133.915 +,		SchemaEntry("ifcdoorstyle",&STEP::ObjectHelper<IfcDoorStyle,4>::Construct )
 133.916 +,		SchemaEntry("ifcrelconnectsporttoelement",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.917 +,		SchemaEntry("ifcrelassociatesclassification",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.918 +,		SchemaEntry("ifcunitassignment",&STEP::ObjectHelper<IfcUnitAssignment,1>::Construct )
 133.919 +,		SchemaEntry("ifcflowterminal",&STEP::ObjectHelper<IfcFlowTerminal,0>::Construct )
 133.920 +,		SchemaEntry("ifccranerailfshapeprofiledef",&STEP::ObjectHelper<IfcCraneRailFShapeProfileDef,9>::Construct )
 133.921 +,		SchemaEntry("ifcflowsegment",&STEP::ObjectHelper<IfcFlowSegment,0>::Construct )
 133.922 +,		SchemaEntry("ifcelementquantity",&STEP::ObjectHelper<IfcElementQuantity,2>::Construct )
 133.923 +,		SchemaEntry("ifcboundarynodecondition",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.924 +,		SchemaEntry("ifcboundarynodeconditionwarping",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.925 +,		SchemaEntry("ifccurtainwall",&STEP::ObjectHelper<IfcCurtainWall,0>::Construct )
 133.926 +,		SchemaEntry("ifcdiscreteaccessory",&STEP::ObjectHelper<IfcDiscreteAccessory,0>::Construct )
 133.927 +,		SchemaEntry("ifcgrid",&STEP::ObjectHelper<IfcGrid,3>::Construct )
 133.928 +,		SchemaEntry("ifcsanitaryterminaltype",&STEP::ObjectHelper<IfcSanitaryTerminalType,1>::Construct )
 133.929 +,		SchemaEntry("ifcsoundproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.930 +,		SchemaEntry("ifcsubedge",&STEP::ObjectHelper<IfcSubedge,1>::Construct )
 133.931 +,		SchemaEntry("ifctextstyletextmodel",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.932 +,		SchemaEntry("ifcfiltertype",&STEP::ObjectHelper<IfcFilterType,1>::Construct )
 133.933 +,		SchemaEntry("ifcsymbolstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.934 +,		SchemaEntry("ifctendon",&STEP::ObjectHelper<IfcTendon,8>::Construct )
 133.935 +,		SchemaEntry("ifcdimensionpair",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.936 +,		SchemaEntry("ifcstructuralloadgroup",&STEP::ObjectHelper<IfcStructuralLoadGroup,5>::Construct )
 133.937 +,		SchemaEntry("ifcpresentationstyleassignment",&STEP::ObjectHelper<IfcPresentationStyleAssignment,1>::Construct )
 133.938 +,		SchemaEntry("ifcregulartimeseries",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.939 +,		SchemaEntry("ifcstructuralcurvemember",&STEP::ObjectHelper<IfcStructuralCurveMember,1>::Construct )
 133.940 +,		SchemaEntry("ifclightsourceambient",&STEP::ObjectHelper<IfcLightSourceAmbient,0>::Construct )
 133.941 +,		SchemaEntry("ifccondition",&STEP::ObjectHelper<IfcCondition,0>::Construct )
 133.942 +,		SchemaEntry("ifcport",&STEP::ObjectHelper<IfcPort,0>::Construct )
 133.943 +,		SchemaEntry("ifcspace",&STEP::ObjectHelper<IfcSpace,2>::Construct )
 133.944 +,		SchemaEntry("ifcheatexchangertype",&STEP::ObjectHelper<IfcHeatExchangerType,1>::Construct )
 133.945 +,		SchemaEntry("ifctanktype",&STEP::ObjectHelper<IfcTankType,1>::Construct )
 133.946 +,		SchemaEntry("ifcinventory",&STEP::ObjectHelper<IfcInventory,6>::Construct )
 133.947 +,		SchemaEntry("ifctextstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.948 +,		SchemaEntry("ifcappliedvaluerelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.949 +,		SchemaEntry("ifcsoundvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.950 +,		SchemaEntry("ifctransportelementtype",&STEP::ObjectHelper<IfcTransportElementType,1>::Construct )
 133.951 +,		SchemaEntry("ifcairtoairheatrecoverytype",&STEP::ObjectHelper<IfcAirToAirHeatRecoveryType,1>::Construct )
 133.952 +,		SchemaEntry("ifcstairflight",&STEP::ObjectHelper<IfcStairFlight,4>::Construct )
 133.953 +,		SchemaEntry("ifcelectricalelement",&STEP::ObjectHelper<IfcElectricalElement,0>::Construct )
 133.954 +,		SchemaEntry("ifclightintensitydistribution",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.955 +,		SchemaEntry("ifcclassificationreference",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.956 +,		SchemaEntry("ifcsurfacestylewithtextures",&STEP::ObjectHelper<IfcSurfaceStyleWithTextures,1>::Construct )
 133.957 +,		SchemaEntry("ifcboundingbox",&STEP::ObjectHelper<IfcBoundingBox,4>::Construct )
 133.958 +,		SchemaEntry("ifcapplication",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.959 +,		SchemaEntry("ifcwalltype",&STEP::ObjectHelper<IfcWallType,1>::Construct )
 133.960 +,		SchemaEntry("ifcmove",&STEP::ObjectHelper<IfcMove,3>::Construct )
 133.961 +,		SchemaEntry("ifccircle",&STEP::ObjectHelper<IfcCircle,1>::Construct )
 133.962 +,		SchemaEntry("ifcoffsetcurve2d",&STEP::ObjectHelper<IfcOffsetCurve2D,3>::Construct )
 133.963 +,		SchemaEntry("ifcmateriallayersetusage",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.964 +,		SchemaEntry("ifcpointoncurve",&STEP::ObjectHelper<IfcPointOnCurve,2>::Construct )
 133.965 +,		SchemaEntry("ifcstructuralresultgroup",&STEP::ObjectHelper<IfcStructuralResultGroup,3>::Construct )
 133.966 +,		SchemaEntry("ifcsectionedspine",&STEP::ObjectHelper<IfcSectionedSpine,3>::Construct )
 133.967 +,		SchemaEntry("ifcslab",&STEP::ObjectHelper<IfcSlab,1>::Construct )
 133.968 +,		SchemaEntry("ifcconnectionportgeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.969 +,		SchemaEntry("ifcquantityweight",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.970 +,		SchemaEntry("ifcrelassociatesmaterial",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.971 +,		SchemaEntry("ifcvertex",&STEP::ObjectHelper<IfcVertex,0>::Construct )
 133.972 +,		SchemaEntry("ifcvertexpoint",&STEP::ObjectHelper<IfcVertexPoint,1>::Construct )
 133.973 +,		SchemaEntry("ifcreferencesvaluedocument",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.974 +,		SchemaEntry("ifcpersonandorganization",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.975 +,		SchemaEntry("ifcrelflowcontrolelements",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.976 +,		SchemaEntry("ifcrelassignstoprocess",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.977 +,		SchemaEntry("ifcstructurallinearaction",&STEP::ObjectHelper<IfcStructuralLinearAction,1>::Construct )
 133.978 +,		SchemaEntry("ifcstructurallinearactionvarying",&STEP::ObjectHelper<IfcStructuralLinearActionVarying,2>::Construct )
 133.979 +,		SchemaEntry("ifcbuildingelementproxytype",&STEP::ObjectHelper<IfcBuildingElementProxyType,1>::Construct )
 133.980 +,		SchemaEntry("ifcprojectionelement",&STEP::ObjectHelper<IfcProjectionElement,0>::Construct )
 133.981 +,		SchemaEntry("ifcderivedunit",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.982 +,		SchemaEntry("ifcapprovalactorrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.983 +,		SchemaEntry("ifcconversionbasedunit",&STEP::ObjectHelper<IfcConversionBasedUnit,2>::Construct )
 133.984 +,		SchemaEntry("ifcmaterial",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.985 +,		SchemaEntry("ifcgeometricrepresentationsubcontext",&STEP::ObjectHelper<IfcGeometricRepresentationSubContext,4>::Construct )
 133.986 +,		SchemaEntry("ifcannotationsurfaceoccurrence",&STEP::ObjectHelper<IfcAnnotationSurfaceOccurrence,0>::Construct )
 133.987 +,		SchemaEntry("ifcpredefineddimensionsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.988 +,		SchemaEntry("ifcroundededgefeature",&STEP::ObjectHelper<IfcRoundedEdgeFeature,1>::Construct )
 133.989 +,		SchemaEntry("ifcrelcoversbldgelements",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.990 +,		SchemaEntry("ifcelectricdistributionpoint",&STEP::ObjectHelper<IfcElectricDistributionPoint,2>::Construct )
 133.991 +,		SchemaEntry("ifccablecarriersegmenttype",&STEP::ObjectHelper<IfcCableCarrierSegmentType,1>::Construct )
 133.992 +,		SchemaEntry("ifcstructuralloadlinearforce",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.993 +,		SchemaEntry("ifcgridaxis",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.994 +,		SchemaEntry("ifcirregulartimeseriesvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.995 +,		SchemaEntry("ifcwallstandardcase",&STEP::ObjectHelper<IfcWallStandardCase,0>::Construct )
 133.996 +,		SchemaEntry("ifcreloccupiesspaces",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.997 +,		SchemaEntry("ifcderivedunitelement",&STEP::ObjectHelper<NotImplemented,0>::Construct )
 133.998 +,		SchemaEntry("ifccsgsolid",&STEP::ObjectHelper<IfcCsgSolid,1>::Construct )
 133.999 +,		SchemaEntry("ifcbeamtype",&STEP::ObjectHelper<IfcBeamType,1>::Construct )
133.1000 +,		SchemaEntry("ifcannotationfillarea",&STEP::ObjectHelper<IfcAnnotationFillArea,2>::Construct )
133.1001 +,		SchemaEntry("ifcrelaxation",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1002 +,		SchemaEntry("ifcstructuralcurvemembervarying",&STEP::ObjectHelper<IfcStructuralCurveMemberVarying,0>::Construct )
133.1003 +,		SchemaEntry("ifcpointonsurface",&STEP::ObjectHelper<IfcPointOnSurface,3>::Construct )
133.1004 +,		SchemaEntry("ifcpropertydependencyrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1005 +,		SchemaEntry("ifcvertexbasedtexturemap",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1006 +,		SchemaEntry("ifcorderaction",&STEP::ObjectHelper<IfcOrderAction,1>::Construct )
133.1007 +,		SchemaEntry("ifclibraryreference",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1008 +,		SchemaEntry("ifcedgeloop",&STEP::ObjectHelper<IfcEdgeLoop,1>::Construct )
133.1009 +,		SchemaEntry("ifcannotationfillareaoccurrence",&STEP::ObjectHelper<IfcAnnotationFillAreaOccurrence,2>::Construct )
133.1010 +,		SchemaEntry("ifcrelconnectsstructuralelement",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1011 +,		SchemaEntry("ifcworkplan",&STEP::ObjectHelper<IfcWorkPlan,0>::Construct )
133.1012 +,		SchemaEntry("ifcellipse",&STEP::ObjectHelper<IfcEllipse,2>::Construct )
133.1013 +,		SchemaEntry("ifcproductdefinitionshape",&STEP::ObjectHelper<IfcProductDefinitionShape,0>::Construct )
133.1014 +,		SchemaEntry("ifcprojectioncurve",&STEP::ObjectHelper<IfcProjectionCurve,0>::Construct )
133.1015 +,		SchemaEntry("ifcelectricalcircuit",&STEP::ObjectHelper<IfcElectricalCircuit,0>::Construct )
133.1016 +,		SchemaEntry("ifcrationalbeziercurve",&STEP::ObjectHelper<IfcRationalBezierCurve,1>::Construct )
133.1017 +,		SchemaEntry("ifcstructuralpointaction",&STEP::ObjectHelper<IfcStructuralPointAction,0>::Construct )
133.1018 +,		SchemaEntry("ifcservicelifefactor",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1019 +,		SchemaEntry("ifcthermalmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1020 +,		SchemaEntry("ifctexturecoordinategenerator",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1021 +,		SchemaEntry("ifcpipesegmenttype",&STEP::ObjectHelper<IfcPipeSegmentType,1>::Construct )
133.1022 +,		SchemaEntry("ifctwodirectionrepeatfactor",&STEP::ObjectHelper<IfcTwoDirectionRepeatFactor,1>::Construct )
133.1023 +,		SchemaEntry("ifcshaperepresentation",&STEP::ObjectHelper<IfcShapeRepresentation,0>::Construct )
133.1024 +,		SchemaEntry("ifcpropertyset",&STEP::ObjectHelper<IfcPropertySet,1>::Construct )
133.1025 +,		SchemaEntry("ifcsurfacestylerendering",&STEP::ObjectHelper<IfcSurfaceStyleRendering,8>::Construct )
133.1026 +,		SchemaEntry("ifcdistributionport",&STEP::ObjectHelper<IfcDistributionPort,1>::Construct )
133.1027 +,		SchemaEntry("ifcimagetexture",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1028 +,		SchemaEntry("ifcpipefittingtype",&STEP::ObjectHelper<IfcPipeFittingType,1>::Construct )
133.1029 +,		SchemaEntry("ifctransportelement",&STEP::ObjectHelper<IfcTransportElement,3>::Construct )
133.1030 +,		SchemaEntry("ifcannotationtextoccurrence",&STEP::ObjectHelper<IfcAnnotationTextOccurrence,0>::Construct )
133.1031 +,		SchemaEntry("ifcconnectionsurfacegeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1032 +,		SchemaEntry("ifcstructuralanalysismodel",&STEP::ObjectHelper<IfcStructuralAnalysisModel,4>::Construct )
133.1033 +,		SchemaEntry("ifcconnectioncurvegeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1034 +,		SchemaEntry("ifcconditioncriterion",&STEP::ObjectHelper<IfcConditionCriterion,2>::Construct )
133.1035 +,		SchemaEntry("ifcwaterproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1036 +,		SchemaEntry("ifcmateriallayer",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1037 +,		SchemaEntry("ifccostvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct )
133.1038 +
133.1039 +	};
133.1040 +}
133.1041 +
133.1042 +// -----------------------------------------------------------------------------------------------------------
133.1043 +void IFC::GetSchema(EXPRESS::ConversionSchema& out)
133.1044 +{
133.1045 +	out = EXPRESS::ConversionSchema(schema_raw);
133.1046 +}
133.1047 +
133.1048 +namespace STEP {
133.1049 +
133.1050 +// -----------------------------------------------------------------------------------------------------------
133.1051 +template <> size_t GenericFill<NotImplemented>(const STEP::DB& db, const LIST& params, NotImplemented* in)
133.1052 +{
133.1053 +	return 0;
133.1054 +}
133.1055 +
133.1056 +
133.1057 +
133.1058 +// -----------------------------------------------------------------------------------------------------------
133.1059 +template <> size_t GenericFill<IfcRoot>(const DB& db, const LIST& params, IfcRoot* in)
133.1060 +{
133.1061 +	size_t base = 0;
133.1062 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRoot"); }    do { // convert the 'GlobalId' argument
133.1063 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1064 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRoot,4>::aux_is_derived[0]=true; break; }
133.1065 +        try { GenericConvert( in->GlobalId, arg, db ); break; } 
133.1066 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRoot to be a `IfcGloballyUniqueId`")); }
133.1067 +    } while(0);
133.1068 +    do { // convert the 'OwnerHistory' argument
133.1069 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1070 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRoot,4>::aux_is_derived[1]=true; break; }
133.1071 +        try { GenericConvert( in->OwnerHistory, arg, db ); break; } 
133.1072 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRoot to be a `IfcOwnerHistory`")); }
133.1073 +    } while(0);
133.1074 +    do { // convert the 'Name' argument
133.1075 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1076 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRoot,4>::aux_is_derived[2]=true; break; }
133.1077 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1078 +        try { GenericConvert( in->Name, arg, db ); break; } 
133.1079 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRoot to be a `IfcLabel`")); }
133.1080 +    } while(0);
133.1081 +    do { // convert the 'Description' argument
133.1082 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1083 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRoot,4>::aux_is_derived[3]=true; break; }
133.1084 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1085 +        try { GenericConvert( in->Description, arg, db ); break; } 
133.1086 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRoot to be a `IfcText`")); }
133.1087 +    } while(0);
133.1088 +	return base;
133.1089 +}
133.1090 +// -----------------------------------------------------------------------------------------------------------
133.1091 +template <> size_t GenericFill<IfcObjectDefinition>(const DB& db, const LIST& params, IfcObjectDefinition* in)
133.1092 +{
133.1093 +	size_t base = GenericFill(db,params,static_cast<IfcRoot*>(in));
133.1094 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcObjectDefinition"); }	return base;
133.1095 +}
133.1096 +// -----------------------------------------------------------------------------------------------------------
133.1097 +template <> size_t GenericFill<IfcTypeObject>(const DB& db, const LIST& params, IfcTypeObject* in)
133.1098 +{
133.1099 +	size_t base = GenericFill(db,params,static_cast<IfcObjectDefinition*>(in));
133.1100 +// this data structure is not used yet, so there is no code generated to fill its members
133.1101 +	return base;
133.1102 +}
133.1103 +// -----------------------------------------------------------------------------------------------------------
133.1104 +template <> size_t GenericFill<IfcTypeProduct>(const DB& db, const LIST& params, IfcTypeProduct* in)
133.1105 +{
133.1106 +	size_t base = GenericFill(db,params,static_cast<IfcTypeObject*>(in));
133.1107 +// this data structure is not used yet, so there is no code generated to fill its members
133.1108 +	return base;
133.1109 +}
133.1110 +// -----------------------------------------------------------------------------------------------------------
133.1111 +template <> size_t GenericFill<IfcElementType>(const DB& db, const LIST& params, IfcElementType* in)
133.1112 +{
133.1113 +	size_t base = GenericFill(db,params,static_cast<IfcTypeProduct*>(in));
133.1114 +// this data structure is not used yet, so there is no code generated to fill its members
133.1115 +	return base;
133.1116 +}
133.1117 +// -----------------------------------------------------------------------------------------------------------
133.1118 +template <> size_t GenericFill<IfcDistributionElementType>(const DB& db, const LIST& params, IfcDistributionElementType* in)
133.1119 +{
133.1120 +	size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in));
133.1121 +// this data structure is not used yet, so there is no code generated to fill its members
133.1122 +	return base;
133.1123 +}
133.1124 +// -----------------------------------------------------------------------------------------------------------
133.1125 +template <> size_t GenericFill<IfcDistributionFlowElementType>(const DB& db, const LIST& params, IfcDistributionFlowElementType* in)
133.1126 +{
133.1127 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionElementType*>(in));
133.1128 +// this data structure is not used yet, so there is no code generated to fill its members
133.1129 +	return base;
133.1130 +}
133.1131 +// -----------------------------------------------------------------------------------------------------------
133.1132 +template <> size_t GenericFill<IfcFlowControllerType>(const DB& db, const LIST& params, IfcFlowControllerType* in)
133.1133 +{
133.1134 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in));
133.1135 +// this data structure is not used yet, so there is no code generated to fill its members
133.1136 +	return base;
133.1137 +}
133.1138 +// -----------------------------------------------------------------------------------------------------------
133.1139 +template <> size_t GenericFill<IfcElectricTimeControlType>(const DB& db, const LIST& params, IfcElectricTimeControlType* in)
133.1140 +{
133.1141 +	size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in));
133.1142 +// this data structure is not used yet, so there is no code generated to fill its members
133.1143 +	return base;
133.1144 +}
133.1145 +// -----------------------------------------------------------------------------------------------------------
133.1146 +template <> size_t GenericFill<IfcRepresentation>(const DB& db, const LIST& params, IfcRepresentation* in)
133.1147 +{
133.1148 +	size_t base = 0;
133.1149 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRepresentation"); }    do { // convert the 'ContextOfItems' argument
133.1150 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1151 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[0]=true; break; }
133.1152 +        try { GenericConvert( in->ContextOfItems, arg, db ); break; } 
133.1153 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentation to be a `IfcRepresentationContext`")); }
133.1154 +    } while(0);
133.1155 +    do { // convert the 'RepresentationIdentifier' argument
133.1156 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1157 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[1]=true; break; }
133.1158 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1159 +        try { GenericConvert( in->RepresentationIdentifier, arg, db ); break; } 
133.1160 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentation to be a `IfcLabel`")); }
133.1161 +    } while(0);
133.1162 +    do { // convert the 'RepresentationType' argument
133.1163 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1164 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[2]=true; break; }
133.1165 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1166 +        try { GenericConvert( in->RepresentationType, arg, db ); break; } 
133.1167 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRepresentation to be a `IfcLabel`")); }
133.1168 +    } while(0);
133.1169 +    do { // convert the 'Items' argument
133.1170 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1171 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[3]=true; break; }
133.1172 +        try { GenericConvert( in->Items, arg, db ); break; } 
133.1173 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRepresentation to be a `SET [1:?] OF IfcRepresentationItem`")); }
133.1174 +    } while(0);
133.1175 +	return base;
133.1176 +}
133.1177 +// -----------------------------------------------------------------------------------------------------------
133.1178 +template <> size_t GenericFill<IfcShapeModel>(const DB& db, const LIST& params, IfcShapeModel* in)
133.1179 +{
133.1180 +	size_t base = GenericFill(db,params,static_cast<IfcRepresentation*>(in));
133.1181 +// this data structure is not used yet, so there is no code generated to fill its members
133.1182 +	return base;
133.1183 +}
133.1184 +// -----------------------------------------------------------------------------------------------------------
133.1185 +template <> size_t GenericFill<IfcTopologyRepresentation>(const DB& db, const LIST& params, IfcTopologyRepresentation* in)
133.1186 +{
133.1187 +	size_t base = GenericFill(db,params,static_cast<IfcShapeModel*>(in));
133.1188 +// this data structure is not used yet, so there is no code generated to fill its members
133.1189 +	return base;
133.1190 +}
133.1191 +// -----------------------------------------------------------------------------------------------------------
133.1192 +template <> size_t GenericFill<IfcRelationship>(const DB& db, const LIST& params, IfcRelationship* in)
133.1193 +{
133.1194 +	size_t base = GenericFill(db,params,static_cast<IfcRoot*>(in));
133.1195 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRelationship"); }	return base;
133.1196 +}
133.1197 +// -----------------------------------------------------------------------------------------------------------
133.1198 +template <> size_t GenericFill<IfcRelConnects>(const DB& db, const LIST& params, IfcRelConnects* in)
133.1199 +{
133.1200 +	size_t base = GenericFill(db,params,static_cast<IfcRelationship*>(in));
133.1201 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRelConnects"); }	return base;
133.1202 +}
133.1203 +// -----------------------------------------------------------------------------------------------------------
133.1204 +template <> size_t GenericFill<IfcFlowFittingType>(const DB& db, const LIST& params, IfcFlowFittingType* in)
133.1205 +{
133.1206 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in));
133.1207 +// this data structure is not used yet, so there is no code generated to fill its members
133.1208 +	return base;
133.1209 +}
133.1210 +// -----------------------------------------------------------------------------------------------------------
133.1211 +template <> size_t GenericFill<IfcCableCarrierFittingType>(const DB& db, const LIST& params, IfcCableCarrierFittingType* in)
133.1212 +{
133.1213 +	size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in));
133.1214 +// this data structure is not used yet, so there is no code generated to fill its members
133.1215 +	return base;
133.1216 +}
133.1217 +// -----------------------------------------------------------------------------------------------------------
133.1218 +template <> size_t GenericFill<IfcEnergyConversionDeviceType>(const DB& db, const LIST& params, IfcEnergyConversionDeviceType* in)
133.1219 +{
133.1220 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in));
133.1221 +// this data structure is not used yet, so there is no code generated to fill its members
133.1222 +	return base;
133.1223 +}
133.1224 +// -----------------------------------------------------------------------------------------------------------
133.1225 +template <> size_t GenericFill<IfcCoilType>(const DB& db, const LIST& params, IfcCoilType* in)
133.1226 +{
133.1227 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.1228 +// this data structure is not used yet, so there is no code generated to fill its members
133.1229 +	return base;
133.1230 +}
133.1231 +// -----------------------------------------------------------------------------------------------------------
133.1232 +template <> size_t GenericFill<IfcObject>(const DB& db, const LIST& params, IfcObject* in)
133.1233 +{
133.1234 +	size_t base = GenericFill(db,params,static_cast<IfcObjectDefinition*>(in));
133.1235 +	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcObject"); }    do { // convert the 'ObjectType' argument
133.1236 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1237 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcObject,1>::aux_is_derived[0]=true; break; }
133.1238 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1239 +        try { GenericConvert( in->ObjectType, arg, db ); break; } 
133.1240 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcObject to be a `IfcLabel`")); }
133.1241 +    } while(0);
133.1242 +	return base;
133.1243 +}
133.1244 +// -----------------------------------------------------------------------------------------------------------
133.1245 +template <> size_t GenericFill<IfcControl>(const DB& db, const LIST& params, IfcControl* in)
133.1246 +{
133.1247 +	size_t base = GenericFill(db,params,static_cast<IfcObject*>(in));
133.1248 +// this data structure is not used yet, so there is no code generated to fill its members
133.1249 +	return base;
133.1250 +}
133.1251 +// -----------------------------------------------------------------------------------------------------------
133.1252 +template <> size_t GenericFill<IfcPerformanceHistory>(const DB& db, const LIST& params, IfcPerformanceHistory* in)
133.1253 +{
133.1254 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.1255 +// this data structure is not used yet, so there is no code generated to fill its members
133.1256 +	return base;
133.1257 +}
133.1258 +// -----------------------------------------------------------------------------------------------------------
133.1259 +template <> size_t GenericFill<IfcRepresentationItem>(const DB& db, const LIST& params, IfcRepresentationItem* in)
133.1260 +{
133.1261 +	size_t base = 0;
133.1262 +	return base;
133.1263 +}
133.1264 +// -----------------------------------------------------------------------------------------------------------
133.1265 +template <> size_t GenericFill<IfcGeometricRepresentationItem>(const DB& db, const LIST& params, IfcGeometricRepresentationItem* in)
133.1266 +{
133.1267 +	size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in));
133.1268 +	return base;
133.1269 +}
133.1270 +// -----------------------------------------------------------------------------------------------------------
133.1271 +template <> size_t GenericFill<IfcTextLiteral>(const DB& db, const LIST& params, IfcTextLiteral* in)
133.1272 +{
133.1273 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.1274 +// this data structure is not used yet, so there is no code generated to fill its members
133.1275 +	return base;
133.1276 +}
133.1277 +// -----------------------------------------------------------------------------------------------------------
133.1278 +template <> size_t GenericFill<IfcTextLiteralWithExtent>(const DB& db, const LIST& params, IfcTextLiteralWithExtent* in)
133.1279 +{
133.1280 +	size_t base = GenericFill(db,params,static_cast<IfcTextLiteral*>(in));
133.1281 +// this data structure is not used yet, so there is no code generated to fill its members
133.1282 +	return base;
133.1283 +}
133.1284 +// -----------------------------------------------------------------------------------------------------------
133.1285 +template <> size_t GenericFill<IfcProductRepresentation>(const DB& db, const LIST& params, IfcProductRepresentation* in)
133.1286 +{
133.1287 +	size_t base = 0;
133.1288 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcProductRepresentation"); }    do { // convert the 'Name' argument
133.1289 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1290 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProductRepresentation,3>::aux_is_derived[0]=true; break; }
133.1291 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1292 +        try { GenericConvert( in->Name, arg, db ); break; } 
133.1293 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProductRepresentation to be a `IfcLabel`")); }
133.1294 +    } while(0);
133.1295 +    do { // convert the 'Description' argument
133.1296 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1297 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProductRepresentation,3>::aux_is_derived[1]=true; break; }
133.1298 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1299 +        try { GenericConvert( in->Description, arg, db ); break; } 
133.1300 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProductRepresentation to be a `IfcText`")); }
133.1301 +    } while(0);
133.1302 +    do { // convert the 'Representations' argument
133.1303 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1304 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProductRepresentation,3>::aux_is_derived[2]=true; break; }
133.1305 +        try { GenericConvert( in->Representations, arg, db ); break; } 
133.1306 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcProductRepresentation to be a `LIST [1:?] OF IfcRepresentation`")); }
133.1307 +    } while(0);
133.1308 +	return base;
133.1309 +}
133.1310 +// -----------------------------------------------------------------------------------------------------------
133.1311 +template <> size_t GenericFill<IfcProduct>(const DB& db, const LIST& params, IfcProduct* in)
133.1312 +{
133.1313 +	size_t base = GenericFill(db,params,static_cast<IfcObject*>(in));
133.1314 +	if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcProduct"); }    do { // convert the 'ObjectPlacement' argument
133.1315 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1316 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProduct,2>::aux_is_derived[0]=true; break; }
133.1317 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1318 +        try { GenericConvert( in->ObjectPlacement, arg, db ); break; } 
133.1319 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcProduct to be a `IfcObjectPlacement`")); }
133.1320 +    } while(0);
133.1321 +    do { // convert the 'Representation' argument
133.1322 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1323 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProduct,2>::aux_is_derived[1]=true; break; }
133.1324 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1325 +        try { GenericConvert( in->Representation, arg, db ); break; } 
133.1326 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcProduct to be a `IfcProductRepresentation`")); }
133.1327 +    } while(0);
133.1328 +	return base;
133.1329 +}
133.1330 +// -----------------------------------------------------------------------------------------------------------
133.1331 +template <> size_t GenericFill<IfcElement>(const DB& db, const LIST& params, IfcElement* in)
133.1332 +{
133.1333 +	size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in));
133.1334 +	if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcElement"); }    do { // convert the 'Tag' argument
133.1335 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1336 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcElement,1>::aux_is_derived[0]=true; break; }
133.1337 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1338 +        try { GenericConvert( in->Tag, arg, db ); break; } 
133.1339 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcElement to be a `IfcIdentifier`")); }
133.1340 +    } while(0);
133.1341 +	return base;
133.1342 +}
133.1343 +// -----------------------------------------------------------------------------------------------------------
133.1344 +template <> size_t GenericFill<IfcDistributionElement>(const DB& db, const LIST& params, IfcDistributionElement* in)
133.1345 +{
133.1346 +	size_t base = GenericFill(db,params,static_cast<IfcElement*>(in));
133.1347 +// this data structure is not used yet, so there is no code generated to fill its members
133.1348 +	return base;
133.1349 +}
133.1350 +// -----------------------------------------------------------------------------------------------------------
133.1351 +template <> size_t GenericFill<IfcDistributionFlowElement>(const DB& db, const LIST& params, IfcDistributionFlowElement* in)
133.1352 +{
133.1353 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionElement*>(in));
133.1354 +// this data structure is not used yet, so there is no code generated to fill its members
133.1355 +	return base;
133.1356 +}
133.1357 +// -----------------------------------------------------------------------------------------------------------
133.1358 +template <> size_t GenericFill<IfcCurve>(const DB& db, const LIST& params, IfcCurve* in)
133.1359 +{
133.1360 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.1361 +	return base;
133.1362 +}
133.1363 +// -----------------------------------------------------------------------------------------------------------
133.1364 +template <> size_t GenericFill<IfcBoundedCurve>(const DB& db, const LIST& params, IfcBoundedCurve* in)
133.1365 +{
133.1366 +	size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in));
133.1367 +	return base;
133.1368 +}
133.1369 +// -----------------------------------------------------------------------------------------------------------
133.1370 +template <> size_t GenericFill<IfcCompositeCurve>(const DB& db, const LIST& params, IfcCompositeCurve* in)
133.1371 +{
133.1372 +	size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in));
133.1373 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcCompositeCurve"); }    do { // convert the 'Segments' argument
133.1374 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1375 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCompositeCurve,2>::aux_is_derived[0]=true; break; }
133.1376 +        try { GenericConvert( in->Segments, arg, db ); break; } 
133.1377 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCompositeCurve to be a `LIST [1:?] OF IfcCompositeCurveSegment`")); }
133.1378 +    } while(0);
133.1379 +    do { // convert the 'SelfIntersect' argument
133.1380 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1381 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCompositeCurve,2>::aux_is_derived[1]=true; break; }
133.1382 +        try { GenericConvert( in->SelfIntersect, arg, db ); break; } 
133.1383 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCompositeCurve to be a `LOGICAL`")); }
133.1384 +    } while(0);
133.1385 +	return base;
133.1386 +}
133.1387 +// -----------------------------------------------------------------------------------------------------------
133.1388 +template <> size_t GenericFill<Ifc2DCompositeCurve>(const DB& db, const LIST& params, Ifc2DCompositeCurve* in)
133.1389 +{
133.1390 +	size_t base = GenericFill(db,params,static_cast<IfcCompositeCurve*>(in));
133.1391 +// this data structure is not used yet, so there is no code generated to fill its members
133.1392 +	return base;
133.1393 +}
133.1394 +// -----------------------------------------------------------------------------------------------------------
133.1395 +template <> size_t GenericFill<IfcCartesianTransformationOperator>(const DB& db, const LIST& params, IfcCartesianTransformationOperator* in)
133.1396 +{
133.1397 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.1398 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcCartesianTransformationOperator"); }    do { // convert the 'Axis1' argument
133.1399 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1400 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[0]=true; break; }
133.1401 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1402 +        try { GenericConvert( in->Axis1, arg, db ); break; } 
133.1403 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCartesianTransformationOperator to be a `IfcDirection`")); }
133.1404 +    } while(0);
133.1405 +    do { // convert the 'Axis2' argument
133.1406 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1407 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[1]=true; break; }
133.1408 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1409 +        try { GenericConvert( in->Axis2, arg, db ); break; } 
133.1410 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCartesianTransformationOperator to be a `IfcDirection`")); }
133.1411 +    } while(0);
133.1412 +    do { // convert the 'LocalOrigin' argument
133.1413 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1414 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[2]=true; break; }
133.1415 +        try { GenericConvert( in->LocalOrigin, arg, db ); break; } 
133.1416 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcCartesianTransformationOperator to be a `IfcCartesianPoint`")); }
133.1417 +    } while(0);
133.1418 +    do { // convert the 'Scale' argument
133.1419 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1420 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[3]=true; break; }
133.1421 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1422 +        try { GenericConvert( in->Scale, arg, db ); break; } 
133.1423 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCartesianTransformationOperator to be a `REAL`")); }
133.1424 +    } while(0);
133.1425 +	return base;
133.1426 +}
133.1427 +// -----------------------------------------------------------------------------------------------------------
133.1428 +template <> size_t GenericFill<IfcCartesianTransformationOperator3D>(const DB& db, const LIST& params, IfcCartesianTransformationOperator3D* in)
133.1429 +{
133.1430 +	size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator*>(in));
133.1431 +	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcCartesianTransformationOperator3D"); }    do { // convert the 'Axis3' argument
133.1432 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1433 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator3D,1>::aux_is_derived[0]=true; break; }
133.1434 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1435 +        try { GenericConvert( in->Axis3, arg, db ); break; } 
133.1436 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCartesianTransformationOperator3D to be a `IfcDirection`")); }
133.1437 +    } while(0);
133.1438 +	return base;
133.1439 +}
133.1440 +// -----------------------------------------------------------------------------------------------------------
133.1441 +template <> size_t GenericFill<IfcProperty>(const DB& db, const LIST& params, IfcProperty* in)
133.1442 +{
133.1443 +	size_t base = 0;
133.1444 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcProperty"); }    do { // convert the 'Name' argument
133.1445 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1446 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProperty,2>::aux_is_derived[0]=true; break; }
133.1447 +        try { GenericConvert( in->Name, arg, db ); break; } 
133.1448 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProperty to be a `IfcIdentifier`")); }
133.1449 +    } while(0);
133.1450 +    do { // convert the 'Description' argument
133.1451 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1452 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProperty,2>::aux_is_derived[1]=true; break; }
133.1453 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1454 +        try { GenericConvert( in->Description, arg, db ); break; } 
133.1455 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProperty to be a `IfcText`")); }
133.1456 +    } while(0);
133.1457 +	return base;
133.1458 +}
133.1459 +// -----------------------------------------------------------------------------------------------------------
133.1460 +template <> size_t GenericFill<IfcSimpleProperty>(const DB& db, const LIST& params, IfcSimpleProperty* in)
133.1461 +{
133.1462 +	size_t base = GenericFill(db,params,static_cast<IfcProperty*>(in));
133.1463 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcSimpleProperty"); }	return base;
133.1464 +}
133.1465 +// -----------------------------------------------------------------------------------------------------------
133.1466 +template <> size_t GenericFill<IfcPropertyEnumeratedValue>(const DB& db, const LIST& params, IfcPropertyEnumeratedValue* in)
133.1467 +{
133.1468 +	size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in));
133.1469 +// this data structure is not used yet, so there is no code generated to fill its members
133.1470 +	return base;
133.1471 +}
133.1472 +// -----------------------------------------------------------------------------------------------------------
133.1473 +template <> size_t GenericFill<IfcBuildingElementType>(const DB& db, const LIST& params, IfcBuildingElementType* in)
133.1474 +{
133.1475 +	size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in));
133.1476 +// this data structure is not used yet, so there is no code generated to fill its members
133.1477 +	return base;
133.1478 +}
133.1479 +// -----------------------------------------------------------------------------------------------------------
133.1480 +template <> size_t GenericFill<IfcStairFlightType>(const DB& db, const LIST& params, IfcStairFlightType* in)
133.1481 +{
133.1482 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.1483 +// this data structure is not used yet, so there is no code generated to fill its members
133.1484 +	return base;
133.1485 +}
133.1486 +// -----------------------------------------------------------------------------------------------------------
133.1487 +template <> size_t GenericFill<IfcSurface>(const DB& db, const LIST& params, IfcSurface* in)
133.1488 +{
133.1489 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.1490 +	return base;
133.1491 +}
133.1492 +// -----------------------------------------------------------------------------------------------------------
133.1493 +template <> size_t GenericFill<IfcElementarySurface>(const DB& db, const LIST& params, IfcElementarySurface* in)
133.1494 +{
133.1495 +	size_t base = GenericFill(db,params,static_cast<IfcSurface*>(in));
133.1496 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcElementarySurface"); }    do { // convert the 'Position' argument
133.1497 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1498 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcElementarySurface,1>::aux_is_derived[0]=true; break; }
133.1499 +        try { GenericConvert( in->Position, arg, db ); break; } 
133.1500 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcElementarySurface to be a `IfcAxis2Placement3D`")); }
133.1501 +    } while(0);
133.1502 +	return base;
133.1503 +}
133.1504 +// -----------------------------------------------------------------------------------------------------------
133.1505 +template <> size_t GenericFill<IfcPlane>(const DB& db, const LIST& params, IfcPlane* in)
133.1506 +{
133.1507 +	size_t base = GenericFill(db,params,static_cast<IfcElementarySurface*>(in));
133.1508 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPlane"); }	return base;
133.1509 +}
133.1510 +// -----------------------------------------------------------------------------------------------------------
133.1511 +template <> size_t GenericFill<IfcBooleanResult>(const DB& db, const LIST& params, IfcBooleanResult* in)
133.1512 +{
133.1513 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.1514 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcBooleanResult"); }    do { // convert the 'Operator' argument
133.1515 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1516 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBooleanResult,3>::aux_is_derived[0]=true; break; }
133.1517 +        try { GenericConvert( in->Operator, arg, db ); break; } 
133.1518 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBooleanResult to be a `IfcBooleanOperator`")); }
133.1519 +    } while(0);
133.1520 +    do { // convert the 'FirstOperand' argument
133.1521 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1522 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBooleanResult,3>::aux_is_derived[1]=true; break; }
133.1523 +        try { GenericConvert( in->FirstOperand, arg, db ); break; } 
133.1524 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBooleanResult to be a `IfcBooleanOperand`")); }
133.1525 +    } while(0);
133.1526 +    do { // convert the 'SecondOperand' argument
133.1527 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1528 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBooleanResult,3>::aux_is_derived[2]=true; break; }
133.1529 +        try { GenericConvert( in->SecondOperand, arg, db ); break; } 
133.1530 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBooleanResult to be a `IfcBooleanOperand`")); }
133.1531 +    } while(0);
133.1532 +	return base;
133.1533 +}
133.1534 +// -----------------------------------------------------------------------------------------------------------
133.1535 +template <> size_t GenericFill<IfcBooleanClippingResult>(const DB& db, const LIST& params, IfcBooleanClippingResult* in)
133.1536 +{
133.1537 +	size_t base = GenericFill(db,params,static_cast<IfcBooleanResult*>(in));
133.1538 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcBooleanClippingResult"); }	return base;
133.1539 +}
133.1540 +// -----------------------------------------------------------------------------------------------------------
133.1541 +template <> size_t GenericFill<IfcSolidModel>(const DB& db, const LIST& params, IfcSolidModel* in)
133.1542 +{
133.1543 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.1544 +	return base;
133.1545 +}
133.1546 +// -----------------------------------------------------------------------------------------------------------
133.1547 +template <> size_t GenericFill<IfcManifoldSolidBrep>(const DB& db, const LIST& params, IfcManifoldSolidBrep* in)
133.1548 +{
133.1549 +	size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in));
133.1550 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcManifoldSolidBrep"); }    do { // convert the 'Outer' argument
133.1551 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1552 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcManifoldSolidBrep,1>::aux_is_derived[0]=true; break; }
133.1553 +        try { GenericConvert( in->Outer, arg, db ); break; } 
133.1554 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcManifoldSolidBrep to be a `IfcClosedShell`")); }
133.1555 +    } while(0);
133.1556 +	return base;
133.1557 +}
133.1558 +// -----------------------------------------------------------------------------------------------------------
133.1559 +template <> size_t GenericFill<IfcFlowTerminalType>(const DB& db, const LIST& params, IfcFlowTerminalType* in)
133.1560 +{
133.1561 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in));
133.1562 +// this data structure is not used yet, so there is no code generated to fill its members
133.1563 +	return base;
133.1564 +}
133.1565 +// -----------------------------------------------------------------------------------------------------------
133.1566 +template <> size_t GenericFill<IfcStackTerminalType>(const DB& db, const LIST& params, IfcStackTerminalType* in)
133.1567 +{
133.1568 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.1569 +// this data structure is not used yet, so there is no code generated to fill its members
133.1570 +	return base;
133.1571 +}
133.1572 +// -----------------------------------------------------------------------------------------------------------
133.1573 +template <> size_t GenericFill<IfcStructuralItem>(const DB& db, const LIST& params, IfcStructuralItem* in)
133.1574 +{
133.1575 +	size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in));
133.1576 +// this data structure is not used yet, so there is no code generated to fill its members
133.1577 +	return base;
133.1578 +}
133.1579 +// -----------------------------------------------------------------------------------------------------------
133.1580 +template <> size_t GenericFill<IfcStructuralConnection>(const DB& db, const LIST& params, IfcStructuralConnection* in)
133.1581 +{
133.1582 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralItem*>(in));
133.1583 +// this data structure is not used yet, so there is no code generated to fill its members
133.1584 +	return base;
133.1585 +}
133.1586 +// -----------------------------------------------------------------------------------------------------------
133.1587 +template <> size_t GenericFill<IfcStructuralCurveConnection>(const DB& db, const LIST& params, IfcStructuralCurveConnection* in)
133.1588 +{
133.1589 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralConnection*>(in));
133.1590 +// this data structure is not used yet, so there is no code generated to fill its members
133.1591 +	return base;
133.1592 +}
133.1593 +// -----------------------------------------------------------------------------------------------------------
133.1594 +template <> size_t GenericFill<IfcJunctionBoxType>(const DB& db, const LIST& params, IfcJunctionBoxType* in)
133.1595 +{
133.1596 +	size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in));
133.1597 +// this data structure is not used yet, so there is no code generated to fill its members
133.1598 +	return base;
133.1599 +}
133.1600 +// -----------------------------------------------------------------------------------------------------------
133.1601 +template <> size_t GenericFill<IfcPropertyDefinition>(const DB& db, const LIST& params, IfcPropertyDefinition* in)
133.1602 +{
133.1603 +	size_t base = GenericFill(db,params,static_cast<IfcRoot*>(in));
133.1604 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertyDefinition"); }	return base;
133.1605 +}
133.1606 +// -----------------------------------------------------------------------------------------------------------
133.1607 +template <> size_t GenericFill<IfcPropertySetDefinition>(const DB& db, const LIST& params, IfcPropertySetDefinition* in)
133.1608 +{
133.1609 +	size_t base = GenericFill(db,params,static_cast<IfcPropertyDefinition*>(in));
133.1610 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertySetDefinition"); }	return base;
133.1611 +}
133.1612 +// -----------------------------------------------------------------------------------------------------------
133.1613 +template <> size_t GenericFill<IfcProcess>(const DB& db, const LIST& params, IfcProcess* in)
133.1614 +{
133.1615 +	size_t base = GenericFill(db,params,static_cast<IfcObject*>(in));
133.1616 +// this data structure is not used yet, so there is no code generated to fill its members
133.1617 +	return base;
133.1618 +}
133.1619 +// -----------------------------------------------------------------------------------------------------------
133.1620 +template <> size_t GenericFill<IfcTask>(const DB& db, const LIST& params, IfcTask* in)
133.1621 +{
133.1622 +	size_t base = GenericFill(db,params,static_cast<IfcProcess*>(in));
133.1623 +// this data structure is not used yet, so there is no code generated to fill its members
133.1624 +	return base;
133.1625 +}
133.1626 +// -----------------------------------------------------------------------------------------------------------
133.1627 +template <> size_t GenericFill<IfcRelFillsElement>(const DB& db, const LIST& params, IfcRelFillsElement* in)
133.1628 +{
133.1629 +	size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in));
133.1630 +	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelFillsElement"); }    do { // convert the 'RelatingOpeningElement' argument
133.1631 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1632 +        try { GenericConvert( in->RelatingOpeningElement, arg, db ); break; } 
133.1633 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelFillsElement to be a `IfcOpeningElement`")); }
133.1634 +    } while(0);
133.1635 +    do { // convert the 'RelatedBuildingElement' argument
133.1636 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1637 +        try { GenericConvert( in->RelatedBuildingElement, arg, db ); break; } 
133.1638 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelFillsElement to be a `IfcElement`")); }
133.1639 +    } while(0);
133.1640 +	return base;
133.1641 +}
133.1642 +// -----------------------------------------------------------------------------------------------------------
133.1643 +template <> size_t GenericFill<IfcProcedure>(const DB& db, const LIST& params, IfcProcedure* in)
133.1644 +{
133.1645 +	size_t base = GenericFill(db,params,static_cast<IfcProcess*>(in));
133.1646 +// this data structure is not used yet, so there is no code generated to fill its members
133.1647 +	return base;
133.1648 +}
133.1649 +// -----------------------------------------------------------------------------------------------------------
133.1650 +template <> size_t GenericFill<IfcProxy>(const DB& db, const LIST& params, IfcProxy* in)
133.1651 +{
133.1652 +	size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in));
133.1653 +// this data structure is not used yet, so there is no code generated to fill its members
133.1654 +	return base;
133.1655 +}
133.1656 +// -----------------------------------------------------------------------------------------------------------
133.1657 +template <> size_t GenericFill<IfcResource>(const DB& db, const LIST& params, IfcResource* in)
133.1658 +{
133.1659 +	size_t base = GenericFill(db,params,static_cast<IfcObject*>(in));
133.1660 +// this data structure is not used yet, so there is no code generated to fill its members
133.1661 +	return base;
133.1662 +}
133.1663 +// -----------------------------------------------------------------------------------------------------------
133.1664 +template <> size_t GenericFill<IfcConstructionResource>(const DB& db, const LIST& params, IfcConstructionResource* in)
133.1665 +{
133.1666 +	size_t base = GenericFill(db,params,static_cast<IfcResource*>(in));
133.1667 +// this data structure is not used yet, so there is no code generated to fill its members
133.1668 +	return base;
133.1669 +}
133.1670 +// -----------------------------------------------------------------------------------------------------------
133.1671 +template <> size_t GenericFill<IfcSubContractResource>(const DB& db, const LIST& params, IfcSubContractResource* in)
133.1672 +{
133.1673 +	size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in));
133.1674 +// this data structure is not used yet, so there is no code generated to fill its members
133.1675 +	return base;
133.1676 +}
133.1677 +// -----------------------------------------------------------------------------------------------------------
133.1678 +template <> size_t GenericFill<IfcRelContainedInSpatialStructure>(const DB& db, const LIST& params, IfcRelContainedInSpatialStructure* in)
133.1679 +{
133.1680 +	size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in));
133.1681 +	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelContainedInSpatialStructure"); }    do { // convert the 'RelatedElements' argument
133.1682 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1683 +        try { GenericConvert( in->RelatedElements, arg, db ); break; } 
133.1684 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelContainedInSpatialStructure to be a `SET [1:?] OF IfcProduct`")); }
133.1685 +    } while(0);
133.1686 +    do { // convert the 'RelatingStructure' argument
133.1687 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1688 +        try { GenericConvert( in->RelatingStructure, arg, db ); break; } 
133.1689 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelContainedInSpatialStructure to be a `IfcSpatialStructureElement`")); }
133.1690 +    } while(0);
133.1691 +	return base;
133.1692 +}
133.1693 +// -----------------------------------------------------------------------------------------------------------
133.1694 +template <> size_t GenericFill<IfcTopologicalRepresentationItem>(const DB& db, const LIST& params, IfcTopologicalRepresentationItem* in)
133.1695 +{
133.1696 +	size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in));
133.1697 +	return base;
133.1698 +}
133.1699 +// -----------------------------------------------------------------------------------------------------------
133.1700 +template <> size_t GenericFill<IfcEdge>(const DB& db, const LIST& params, IfcEdge* in)
133.1701 +{
133.1702 +	size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in));
133.1703 +// this data structure is not used yet, so there is no code generated to fill its members
133.1704 +	return base;
133.1705 +}
133.1706 +// -----------------------------------------------------------------------------------------------------------
133.1707 +template <> size_t GenericFill<IfcEdgeCurve>(const DB& db, const LIST& params, IfcEdgeCurve* in)
133.1708 +{
133.1709 +	size_t base = GenericFill(db,params,static_cast<IfcEdge*>(in));
133.1710 +// this data structure is not used yet, so there is no code generated to fill its members
133.1711 +	return base;
133.1712 +}
133.1713 +// -----------------------------------------------------------------------------------------------------------
133.1714 +template <> size_t GenericFill<IfcPlateType>(const DB& db, const LIST& params, IfcPlateType* in)
133.1715 +{
133.1716 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.1717 +// this data structure is not used yet, so there is no code generated to fill its members
133.1718 +	return base;
133.1719 +}
133.1720 +// -----------------------------------------------------------------------------------------------------------
133.1721 +template <> size_t GenericFill<IfcObjectPlacement>(const DB& db, const LIST& params, IfcObjectPlacement* in)
133.1722 +{
133.1723 +	size_t base = 0;
133.1724 +	return base;
133.1725 +}
133.1726 +// -----------------------------------------------------------------------------------------------------------
133.1727 +template <> size_t GenericFill<IfcGridPlacement>(const DB& db, const LIST& params, IfcGridPlacement* in)
133.1728 +{
133.1729 +	size_t base = GenericFill(db,params,static_cast<IfcObjectPlacement*>(in));
133.1730 +// this data structure is not used yet, so there is no code generated to fill its members
133.1731 +	return base;
133.1732 +}
133.1733 +// -----------------------------------------------------------------------------------------------------------
133.1734 +template <> size_t GenericFill<IfcFireSuppressionTerminalType>(const DB& db, const LIST& params, IfcFireSuppressionTerminalType* in)
133.1735 +{
133.1736 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.1737 +// this data structure is not used yet, so there is no code generated to fill its members
133.1738 +	return base;
133.1739 +}
133.1740 +// -----------------------------------------------------------------------------------------------------------
133.1741 +template <> size_t GenericFill<IfcFlowStorageDevice>(const DB& db, const LIST& params, IfcFlowStorageDevice* in)
133.1742 +{
133.1743 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in));
133.1744 +// this data structure is not used yet, so there is no code generated to fill its members
133.1745 +	return base;
133.1746 +}
133.1747 +// -----------------------------------------------------------------------------------------------------------
133.1748 +template <> size_t GenericFill<IfcSweptSurface>(const DB& db, const LIST& params, IfcSweptSurface* in)
133.1749 +{
133.1750 +	size_t base = GenericFill(db,params,static_cast<IfcSurface*>(in));
133.1751 +// this data structure is not used yet, so there is no code generated to fill its members
133.1752 +	return base;
133.1753 +}
133.1754 +// -----------------------------------------------------------------------------------------------------------
133.1755 +template <> size_t GenericFill<IfcSurfaceOfRevolution>(const DB& db, const LIST& params, IfcSurfaceOfRevolution* in)
133.1756 +{
133.1757 +	size_t base = GenericFill(db,params,static_cast<IfcSweptSurface*>(in));
133.1758 +// this data structure is not used yet, so there is no code generated to fill its members
133.1759 +	return base;
133.1760 +}
133.1761 +// -----------------------------------------------------------------------------------------------------------
133.1762 +template <> size_t GenericFill<IfcOrientedEdge>(const DB& db, const LIST& params, IfcOrientedEdge* in)
133.1763 +{
133.1764 +	size_t base = GenericFill(db,params,static_cast<IfcEdge*>(in));
133.1765 +// this data structure is not used yet, so there is no code generated to fill its members
133.1766 +	return base;
133.1767 +}
133.1768 +// -----------------------------------------------------------------------------------------------------------
133.1769 +template <> size_t GenericFill<IfcDirection>(const DB& db, const LIST& params, IfcDirection* in)
133.1770 +{
133.1771 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.1772 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcDirection"); }    do { // convert the 'DirectionRatios' argument
133.1773 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1774 +        try { GenericConvert( in->DirectionRatios, arg, db ); break; } 
133.1775 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcDirection to be a `LIST [2:3] OF REAL`")); }
133.1776 +    } while(0);
133.1777 +	return base;
133.1778 +}
133.1779 +// -----------------------------------------------------------------------------------------------------------
133.1780 +template <> size_t GenericFill<IfcProfileDef>(const DB& db, const LIST& params, IfcProfileDef* in)
133.1781 +{
133.1782 +	size_t base = 0;
133.1783 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcProfileDef"); }    do { // convert the 'ProfileType' argument
133.1784 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1785 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProfileDef,2>::aux_is_derived[0]=true; break; }
133.1786 +        try { GenericConvert( in->ProfileType, arg, db ); break; } 
133.1787 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProfileDef to be a `IfcProfileTypeEnum`")); }
133.1788 +    } while(0);
133.1789 +    do { // convert the 'ProfileName' argument
133.1790 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1791 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProfileDef,2>::aux_is_derived[1]=true; break; }
133.1792 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1793 +        try { GenericConvert( in->ProfileName, arg, db ); break; } 
133.1794 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProfileDef to be a `IfcLabel`")); }
133.1795 +    } while(0);
133.1796 +	return base;
133.1797 +}
133.1798 +// -----------------------------------------------------------------------------------------------------------
133.1799 +template <> size_t GenericFill<IfcParameterizedProfileDef>(const DB& db, const LIST& params, IfcParameterizedProfileDef* in)
133.1800 +{
133.1801 +	size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in));
133.1802 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcParameterizedProfileDef"); }    do { // convert the 'Position' argument
133.1803 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1804 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcParameterizedProfileDef,1>::aux_is_derived[0]=true; break; }
133.1805 +        try { GenericConvert( in->Position, arg, db ); break; } 
133.1806 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcParameterizedProfileDef to be a `IfcAxis2Placement2D`")); }
133.1807 +    } while(0);
133.1808 +	return base;
133.1809 +}
133.1810 +// -----------------------------------------------------------------------------------------------------------
133.1811 +template <> size_t GenericFill<IfcCShapeProfileDef>(const DB& db, const LIST& params, IfcCShapeProfileDef* in)
133.1812 +{
133.1813 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.1814 +// this data structure is not used yet, so there is no code generated to fill its members
133.1815 +	return base;
133.1816 +}
133.1817 +// -----------------------------------------------------------------------------------------------------------
133.1818 +template <> size_t GenericFill<IfcFeatureElement>(const DB& db, const LIST& params, IfcFeatureElement* in)
133.1819 +{
133.1820 +	size_t base = GenericFill(db,params,static_cast<IfcElement*>(in));
133.1821 +	if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcFeatureElement"); }	return base;
133.1822 +}
133.1823 +// -----------------------------------------------------------------------------------------------------------
133.1824 +template <> size_t GenericFill<IfcFeatureElementSubtraction>(const DB& db, const LIST& params, IfcFeatureElementSubtraction* in)
133.1825 +{
133.1826 +	size_t base = GenericFill(db,params,static_cast<IfcFeatureElement*>(in));
133.1827 +	if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcFeatureElementSubtraction"); }	return base;
133.1828 +}
133.1829 +// -----------------------------------------------------------------------------------------------------------
133.1830 +template <> size_t GenericFill<IfcEdgeFeature>(const DB& db, const LIST& params, IfcEdgeFeature* in)
133.1831 +{
133.1832 +	size_t base = GenericFill(db,params,static_cast<IfcFeatureElementSubtraction*>(in));
133.1833 +// this data structure is not used yet, so there is no code generated to fill its members
133.1834 +	return base;
133.1835 +}
133.1836 +// -----------------------------------------------------------------------------------------------------------
133.1837 +template <> size_t GenericFill<IfcChamferEdgeFeature>(const DB& db, const LIST& params, IfcChamferEdgeFeature* in)
133.1838 +{
133.1839 +	size_t base = GenericFill(db,params,static_cast<IfcEdgeFeature*>(in));
133.1840 +// this data structure is not used yet, so there is no code generated to fill its members
133.1841 +	return base;
133.1842 +}
133.1843 +// -----------------------------------------------------------------------------------------------------------
133.1844 +template <> size_t GenericFill<IfcBuildingElement>(const DB& db, const LIST& params, IfcBuildingElement* in)
133.1845 +{
133.1846 +	size_t base = GenericFill(db,params,static_cast<IfcElement*>(in));
133.1847 +	if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcBuildingElement"); }	return base;
133.1848 +}
133.1849 +// -----------------------------------------------------------------------------------------------------------
133.1850 +template <> size_t GenericFill<IfcColumn>(const DB& db, const LIST& params, IfcColumn* in)
133.1851 +{
133.1852 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.1853 +// this data structure is not used yet, so there is no code generated to fill its members
133.1854 +	return base;
133.1855 +}
133.1856 +// -----------------------------------------------------------------------------------------------------------
133.1857 +template <> size_t GenericFill<IfcPropertyReferenceValue>(const DB& db, const LIST& params, IfcPropertyReferenceValue* in)
133.1858 +{
133.1859 +	size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in));
133.1860 +// this data structure is not used yet, so there is no code generated to fill its members
133.1861 +	return base;
133.1862 +}
133.1863 +// -----------------------------------------------------------------------------------------------------------
133.1864 +template <> size_t GenericFill<IfcElectricMotorType>(const DB& db, const LIST& params, IfcElectricMotorType* in)
133.1865 +{
133.1866 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.1867 +// this data structure is not used yet, so there is no code generated to fill its members
133.1868 +	return base;
133.1869 +}
133.1870 +// -----------------------------------------------------------------------------------------------------------
133.1871 +template <> size_t GenericFill<IfcSpatialStructureElementType>(const DB& db, const LIST& params, IfcSpatialStructureElementType* in)
133.1872 +{
133.1873 +	size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in));
133.1874 +// this data structure is not used yet, so there is no code generated to fill its members
133.1875 +	return base;
133.1876 +}
133.1877 +// -----------------------------------------------------------------------------------------------------------
133.1878 +template <> size_t GenericFill<IfcSpaceType>(const DB& db, const LIST& params, IfcSpaceType* in)
133.1879 +{
133.1880 +	size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElementType*>(in));
133.1881 +// this data structure is not used yet, so there is no code generated to fill its members
133.1882 +	return base;
133.1883 +}
133.1884 +// -----------------------------------------------------------------------------------------------------------
133.1885 +template <> size_t GenericFill<IfcColumnType>(const DB& db, const LIST& params, IfcColumnType* in)
133.1886 +{
133.1887 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.1888 +// this data structure is not used yet, so there is no code generated to fill its members
133.1889 +	return base;
133.1890 +}
133.1891 +// -----------------------------------------------------------------------------------------------------------
133.1892 +template <> size_t GenericFill<IfcCraneRailAShapeProfileDef>(const DB& db, const LIST& params, IfcCraneRailAShapeProfileDef* in)
133.1893 +{
133.1894 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.1895 +// this data structure is not used yet, so there is no code generated to fill its members
133.1896 +	return base;
133.1897 +}
133.1898 +// -----------------------------------------------------------------------------------------------------------
133.1899 +template <> size_t GenericFill<IfcCondenserType>(const DB& db, const LIST& params, IfcCondenserType* in)
133.1900 +{
133.1901 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.1902 +// this data structure is not used yet, so there is no code generated to fill its members
133.1903 +	return base;
133.1904 +}
133.1905 +// -----------------------------------------------------------------------------------------------------------
133.1906 +template <> size_t GenericFill<IfcCircleProfileDef>(const DB& db, const LIST& params, IfcCircleProfileDef* in)
133.1907 +{
133.1908 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.1909 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcCircleProfileDef"); }    do { // convert the 'Radius' argument
133.1910 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1911 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCircleProfileDef,1>::aux_is_derived[0]=true; break; }
133.1912 +        try { GenericConvert( in->Radius, arg, db ); break; } 
133.1913 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCircleProfileDef to be a `IfcPositiveLengthMeasure`")); }
133.1914 +    } while(0);
133.1915 +	return base;
133.1916 +}
133.1917 +// -----------------------------------------------------------------------------------------------------------
133.1918 +template <> size_t GenericFill<IfcCircleHollowProfileDef>(const DB& db, const LIST& params, IfcCircleHollowProfileDef* in)
133.1919 +{
133.1920 +	size_t base = GenericFill(db,params,static_cast<IfcCircleProfileDef*>(in));
133.1921 +	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcCircleHollowProfileDef"); }    do { // convert the 'WallThickness' argument
133.1922 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1923 +        try { GenericConvert( in->WallThickness, arg, db ); break; } 
133.1924 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCircleHollowProfileDef to be a `IfcPositiveLengthMeasure`")); }
133.1925 +    } while(0);
133.1926 +	return base;
133.1927 +}
133.1928 +// -----------------------------------------------------------------------------------------------------------
133.1929 +template <> size_t GenericFill<IfcPlacement>(const DB& db, const LIST& params, IfcPlacement* in)
133.1930 +{
133.1931 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.1932 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPlacement"); }    do { // convert the 'Location' argument
133.1933 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1934 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcPlacement,1>::aux_is_derived[0]=true; break; }
133.1935 +        try { GenericConvert( in->Location, arg, db ); break; } 
133.1936 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPlacement to be a `IfcCartesianPoint`")); }
133.1937 +    } while(0);
133.1938 +	return base;
133.1939 +}
133.1940 +// -----------------------------------------------------------------------------------------------------------
133.1941 +template <> size_t GenericFill<IfcAxis2Placement3D>(const DB& db, const LIST& params, IfcAxis2Placement3D* in)
133.1942 +{
133.1943 +	size_t base = GenericFill(db,params,static_cast<IfcPlacement*>(in));
133.1944 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcAxis2Placement3D"); }    do { // convert the 'Axis' argument
133.1945 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1946 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1947 +        try { GenericConvert( in->Axis, arg, db ); break; } 
133.1948 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis2Placement3D to be a `IfcDirection`")); }
133.1949 +    } while(0);
133.1950 +    do { // convert the 'RefDirection' argument
133.1951 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1952 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1953 +        try { GenericConvert( in->RefDirection, arg, db ); break; } 
133.1954 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcAxis2Placement3D to be a `IfcDirection`")); }
133.1955 +    } while(0);
133.1956 +	return base;
133.1957 +}
133.1958 +// -----------------------------------------------------------------------------------------------------------
133.1959 +template <> size_t GenericFill<IfcPresentationStyle>(const DB& db, const LIST& params, IfcPresentationStyle* in)
133.1960 +{
133.1961 +	size_t base = 0;
133.1962 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPresentationStyle"); }    do { // convert the 'Name' argument
133.1963 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1964 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcPresentationStyle,1>::aux_is_derived[0]=true; break; }
133.1965 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.1966 +        try { GenericConvert( in->Name, arg, db ); break; } 
133.1967 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPresentationStyle to be a `IfcLabel`")); }
133.1968 +    } while(0);
133.1969 +	return base;
133.1970 +}
133.1971 +// -----------------------------------------------------------------------------------------------------------
133.1972 +template <> size_t GenericFill<IfcEquipmentElement>(const DB& db, const LIST& params, IfcEquipmentElement* in)
133.1973 +{
133.1974 +	size_t base = GenericFill(db,params,static_cast<IfcElement*>(in));
133.1975 +// this data structure is not used yet, so there is no code generated to fill its members
133.1976 +	return base;
133.1977 +}
133.1978 +// -----------------------------------------------------------------------------------------------------------
133.1979 +template <> size_t GenericFill<IfcCompositeCurveSegment>(const DB& db, const LIST& params, IfcCompositeCurveSegment* in)
133.1980 +{
133.1981 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.1982 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcCompositeCurveSegment"); }    do { // convert the 'Transition' argument
133.1983 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1984 +        try { GenericConvert( in->Transition, arg, db ); break; } 
133.1985 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCompositeCurveSegment to be a `IfcTransitionCode`")); }
133.1986 +    } while(0);
133.1987 +    do { // convert the 'SameSense' argument
133.1988 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1989 +        try { GenericConvert( in->SameSense, arg, db ); break; } 
133.1990 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCompositeCurveSegment to be a `BOOLEAN`")); }
133.1991 +    } while(0);
133.1992 +    do { // convert the 'ParentCurve' argument
133.1993 +        boost::shared_ptr<const DataType> arg = params[base++];
133.1994 +        try { GenericConvert( in->ParentCurve, arg, db ); break; } 
133.1995 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcCompositeCurveSegment to be a `IfcCurve`")); }
133.1996 +    } while(0);
133.1997 +	return base;
133.1998 +}
133.1999 +// -----------------------------------------------------------------------------------------------------------
133.2000 +template <> size_t GenericFill<IfcRectangleProfileDef>(const DB& db, const LIST& params, IfcRectangleProfileDef* in)
133.2001 +{
133.2002 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.2003 +	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcRectangleProfileDef"); }    do { // convert the 'XDim' argument
133.2004 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2005 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRectangleProfileDef,2>::aux_is_derived[0]=true; break; }
133.2006 +        try { GenericConvert( in->XDim, arg, db ); break; } 
133.2007 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRectangleProfileDef to be a `IfcPositiveLengthMeasure`")); }
133.2008 +    } while(0);
133.2009 +    do { // convert the 'YDim' argument
133.2010 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2011 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRectangleProfileDef,2>::aux_is_derived[1]=true; break; }
133.2012 +        try { GenericConvert( in->YDim, arg, db ); break; } 
133.2013 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRectangleProfileDef to be a `IfcPositiveLengthMeasure`")); }
133.2014 +    } while(0);
133.2015 +	return base;
133.2016 +}
133.2017 +// -----------------------------------------------------------------------------------------------------------
133.2018 +template <> size_t GenericFill<IfcBuildingElementProxy>(const DB& db, const LIST& params, IfcBuildingElementProxy* in)
133.2019 +{
133.2020 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.2021 +// this data structure is not used yet, so there is no code generated to fill its members
133.2022 +	return base;
133.2023 +}
133.2024 +// -----------------------------------------------------------------------------------------------------------
133.2025 +template <> size_t GenericFill<IfcDistributionControlElementType>(const DB& db, const LIST& params, IfcDistributionControlElementType* in)
133.2026 +{
133.2027 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionElementType*>(in));
133.2028 +// this data structure is not used yet, so there is no code generated to fill its members
133.2029 +	return base;
133.2030 +}
133.2031 +// -----------------------------------------------------------------------------------------------------------
133.2032 +template <> size_t GenericFill<IfcFlowInstrumentType>(const DB& db, const LIST& params, IfcFlowInstrumentType* in)
133.2033 +{
133.2034 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in));
133.2035 +// this data structure is not used yet, so there is no code generated to fill its members
133.2036 +	return base;
133.2037 +}
133.2038 +// -----------------------------------------------------------------------------------------------------------
133.2039 +template <> size_t GenericFill<IfcDraughtingCallout>(const DB& db, const LIST& params, IfcDraughtingCallout* in)
133.2040 +{
133.2041 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.2042 +// this data structure is not used yet, so there is no code generated to fill its members
133.2043 +	return base;
133.2044 +}
133.2045 +// -----------------------------------------------------------------------------------------------------------
133.2046 +template <> size_t GenericFill<IfcDimensionCurveDirectedCallout>(const DB& db, const LIST& params, IfcDimensionCurveDirectedCallout* in)
133.2047 +{
133.2048 +	size_t base = GenericFill(db,params,static_cast<IfcDraughtingCallout*>(in));
133.2049 +// this data structure is not used yet, so there is no code generated to fill its members
133.2050 +	return base;
133.2051 +}
133.2052 +// -----------------------------------------------------------------------------------------------------------
133.2053 +template <> size_t GenericFill<IfcLinearDimension>(const DB& db, const LIST& params, IfcLinearDimension* in)
133.2054 +{
133.2055 +	size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in));
133.2056 +// this data structure is not used yet, so there is no code generated to fill its members
133.2057 +	return base;
133.2058 +}
133.2059 +// -----------------------------------------------------------------------------------------------------------
133.2060 +template <> size_t GenericFill<IfcElementAssembly>(const DB& db, const LIST& params, IfcElementAssembly* in)
133.2061 +{
133.2062 +	size_t base = GenericFill(db,params,static_cast<IfcElement*>(in));
133.2063 +// this data structure is not used yet, so there is no code generated to fill its members
133.2064 +	return base;
133.2065 +}
133.2066 +// -----------------------------------------------------------------------------------------------------------
133.2067 +template <> size_t GenericFill<IfcCsgPrimitive3D>(const DB& db, const LIST& params, IfcCsgPrimitive3D* in)
133.2068 +{
133.2069 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.2070 +// this data structure is not used yet, so there is no code generated to fill its members
133.2071 +	return base;
133.2072 +}
133.2073 +// -----------------------------------------------------------------------------------------------------------
133.2074 +template <> size_t GenericFill<IfcRightCircularCone>(const DB& db, const LIST& params, IfcRightCircularCone* in)
133.2075 +{
133.2076 +	size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in));
133.2077 +// this data structure is not used yet, so there is no code generated to fill its members
133.2078 +	return base;
133.2079 +}
133.2080 +// -----------------------------------------------------------------------------------------------------------
133.2081 +template <> size_t GenericFill<IfcProjectOrder>(const DB& db, const LIST& params, IfcProjectOrder* in)
133.2082 +{
133.2083 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.2084 +// this data structure is not used yet, so there is no code generated to fill its members
133.2085 +	return base;
133.2086 +}
133.2087 +// -----------------------------------------------------------------------------------------------------------
133.2088 +template <> size_t GenericFill<IfcLShapeProfileDef>(const DB& db, const LIST& params, IfcLShapeProfileDef* in)
133.2089 +{
133.2090 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.2091 +// this data structure is not used yet, so there is no code generated to fill its members
133.2092 +	return base;
133.2093 +}
133.2094 +// -----------------------------------------------------------------------------------------------------------
133.2095 +template <> size_t GenericFill<IfcAngularDimension>(const DB& db, const LIST& params, IfcAngularDimension* in)
133.2096 +{
133.2097 +	size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in));
133.2098 +// this data structure is not used yet, so there is no code generated to fill its members
133.2099 +	return base;
133.2100 +}
133.2101 +// -----------------------------------------------------------------------------------------------------------
133.2102 +template <> size_t GenericFill<IfcLocalPlacement>(const DB& db, const LIST& params, IfcLocalPlacement* in)
133.2103 +{
133.2104 +	size_t base = GenericFill(db,params,static_cast<IfcObjectPlacement*>(in));
133.2105 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcLocalPlacement"); }    do { // convert the 'PlacementRelTo' argument
133.2106 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2107 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2108 +        try { GenericConvert( in->PlacementRelTo, arg, db ); break; } 
133.2109 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcLocalPlacement to be a `IfcObjectPlacement`")); }
133.2110 +    } while(0);
133.2111 +    do { // convert the 'RelativePlacement' argument
133.2112 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2113 +        try { GenericConvert( in->RelativePlacement, arg, db ); break; } 
133.2114 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcLocalPlacement to be a `IfcAxis2Placement`")); }
133.2115 +    } while(0);
133.2116 +	return base;
133.2117 +}
133.2118 +// -----------------------------------------------------------------------------------------------------------
133.2119 +template <> size_t GenericFill<IfcSweptAreaSolid>(const DB& db, const LIST& params, IfcSweptAreaSolid* in)
133.2120 +{
133.2121 +	size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in));
133.2122 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcSweptAreaSolid"); }    do { // convert the 'SweptArea' argument
133.2123 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2124 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSweptAreaSolid,2>::aux_is_derived[0]=true; break; }
133.2125 +        try { GenericConvert( in->SweptArea, arg, db ); break; } 
133.2126 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSweptAreaSolid to be a `IfcProfileDef`")); }
133.2127 +    } while(0);
133.2128 +    do { // convert the 'Position' argument
133.2129 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2130 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSweptAreaSolid,2>::aux_is_derived[1]=true; break; }
133.2131 +        try { GenericConvert( in->Position, arg, db ); break; } 
133.2132 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSweptAreaSolid to be a `IfcAxis2Placement3D`")); }
133.2133 +    } while(0);
133.2134 +	return base;
133.2135 +}
133.2136 +// -----------------------------------------------------------------------------------------------------------
133.2137 +template <> size_t GenericFill<IfcRevolvedAreaSolid>(const DB& db, const LIST& params, IfcRevolvedAreaSolid* in)
133.2138 +{
133.2139 +	size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in));
133.2140 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRevolvedAreaSolid"); }    do { // convert the 'Axis' argument
133.2141 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2142 +        try { GenericConvert( in->Axis, arg, db ); break; } 
133.2143 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRevolvedAreaSolid to be a `IfcAxis1Placement`")); }
133.2144 +    } while(0);
133.2145 +    do { // convert the 'Angle' argument
133.2146 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2147 +        try { GenericConvert( in->Angle, arg, db ); break; } 
133.2148 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRevolvedAreaSolid to be a `IfcPlaneAngleMeasure`")); }
133.2149 +    } while(0);
133.2150 +	return base;
133.2151 +}
133.2152 +// -----------------------------------------------------------------------------------------------------------
133.2153 +template <> size_t GenericFill<IfcStructuralSurfaceConnection>(const DB& db, const LIST& params, IfcStructuralSurfaceConnection* in)
133.2154 +{
133.2155 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralConnection*>(in));
133.2156 +// this data structure is not used yet, so there is no code generated to fill its members
133.2157 +	return base;
133.2158 +}
133.2159 +// -----------------------------------------------------------------------------------------------------------
133.2160 +template <> size_t GenericFill<IfcRadiusDimension>(const DB& db, const LIST& params, IfcRadiusDimension* in)
133.2161 +{
133.2162 +	size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in));
133.2163 +// this data structure is not used yet, so there is no code generated to fill its members
133.2164 +	return base;
133.2165 +}
133.2166 +// -----------------------------------------------------------------------------------------------------------
133.2167 +template <> size_t GenericFill<IfcSweptDiskSolid>(const DB& db, const LIST& params, IfcSweptDiskSolid* in)
133.2168 +{
133.2169 +	size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in));
133.2170 +	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcSweptDiskSolid"); }    do { // convert the 'Directrix' argument
133.2171 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2172 +        try { GenericConvert( in->Directrix, arg, db ); break; } 
133.2173 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSweptDiskSolid to be a `IfcCurve`")); }
133.2174 +    } while(0);
133.2175 +    do { // convert the 'Radius' argument
133.2176 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2177 +        try { GenericConvert( in->Radius, arg, db ); break; } 
133.2178 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSweptDiskSolid to be a `IfcPositiveLengthMeasure`")); }
133.2179 +    } while(0);
133.2180 +    do { // convert the 'InnerRadius' argument
133.2181 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2182 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2183 +        try { GenericConvert( in->InnerRadius, arg, db ); break; } 
133.2184 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSweptDiskSolid to be a `IfcPositiveLengthMeasure`")); }
133.2185 +    } while(0);
133.2186 +    do { // convert the 'StartParam' argument
133.2187 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2188 +        try { GenericConvert( in->StartParam, arg, db ); break; } 
133.2189 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSweptDiskSolid to be a `IfcParameterValue`")); }
133.2190 +    } while(0);
133.2191 +    do { // convert the 'EndParam' argument
133.2192 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2193 +        try { GenericConvert( in->EndParam, arg, db ); break; } 
133.2194 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcSweptDiskSolid to be a `IfcParameterValue`")); }
133.2195 +    } while(0);
133.2196 +	return base;
133.2197 +}
133.2198 +// -----------------------------------------------------------------------------------------------------------
133.2199 +template <> size_t GenericFill<IfcHalfSpaceSolid>(const DB& db, const LIST& params, IfcHalfSpaceSolid* in)
133.2200 +{
133.2201 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.2202 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcHalfSpaceSolid"); }    do { // convert the 'BaseSurface' argument
133.2203 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2204 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcHalfSpaceSolid,2>::aux_is_derived[0]=true; break; }
133.2205 +        try { GenericConvert( in->BaseSurface, arg, db ); break; } 
133.2206 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcHalfSpaceSolid to be a `IfcSurface`")); }
133.2207 +    } while(0);
133.2208 +    do { // convert the 'AgreementFlag' argument
133.2209 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2210 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcHalfSpaceSolid,2>::aux_is_derived[1]=true; break; }
133.2211 +        try { GenericConvert( in->AgreementFlag, arg, db ); break; } 
133.2212 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcHalfSpaceSolid to be a `BOOLEAN`")); }
133.2213 +    } while(0);
133.2214 +	return base;
133.2215 +}
133.2216 +// -----------------------------------------------------------------------------------------------------------
133.2217 +template <> size_t GenericFill<IfcPolygonalBoundedHalfSpace>(const DB& db, const LIST& params, IfcPolygonalBoundedHalfSpace* in)
133.2218 +{
133.2219 +	size_t base = GenericFill(db,params,static_cast<IfcHalfSpaceSolid*>(in));
133.2220 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPolygonalBoundedHalfSpace"); }    do { // convert the 'Position' argument
133.2221 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2222 +        try { GenericConvert( in->Position, arg, db ); break; } 
133.2223 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPolygonalBoundedHalfSpace to be a `IfcAxis2Placement3D`")); }
133.2224 +    } while(0);
133.2225 +    do { // convert the 'PolygonalBoundary' argument
133.2226 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2227 +        try { GenericConvert( in->PolygonalBoundary, arg, db ); break; } 
133.2228 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPolygonalBoundedHalfSpace to be a `IfcBoundedCurve`")); }
133.2229 +    } while(0);
133.2230 +	return base;
133.2231 +}
133.2232 +// -----------------------------------------------------------------------------------------------------------
133.2233 +template <> size_t GenericFill<IfcTimeSeriesSchedule>(const DB& db, const LIST& params, IfcTimeSeriesSchedule* in)
133.2234 +{
133.2235 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.2236 +// this data structure is not used yet, so there is no code generated to fill its members
133.2237 +	return base;
133.2238 +}
133.2239 +// -----------------------------------------------------------------------------------------------------------
133.2240 +template <> size_t GenericFill<IfcCooledBeamType>(const DB& db, const LIST& params, IfcCooledBeamType* in)
133.2241 +{
133.2242 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.2243 +// this data structure is not used yet, so there is no code generated to fill its members
133.2244 +	return base;
133.2245 +}
133.2246 +// -----------------------------------------------------------------------------------------------------------
133.2247 +template <> size_t GenericFill<IfcProject>(const DB& db, const LIST& params, IfcProject* in)
133.2248 +{
133.2249 +	size_t base = GenericFill(db,params,static_cast<IfcObject*>(in));
133.2250 +	if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcProject"); }    do { // convert the 'LongName' argument
133.2251 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2252 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2253 +        try { GenericConvert( in->LongName, arg, db ); break; } 
133.2254 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcProject to be a `IfcLabel`")); }
133.2255 +    } while(0);
133.2256 +    do { // convert the 'Phase' argument
133.2257 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2258 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2259 +        try { GenericConvert( in->Phase, arg, db ); break; } 
133.2260 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcProject to be a `IfcLabel`")); }
133.2261 +    } while(0);
133.2262 +    do { // convert the 'RepresentationContexts' argument
133.2263 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2264 +        try { GenericConvert( in->RepresentationContexts, arg, db ); break; } 
133.2265 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcProject to be a `SET [1:?] OF IfcRepresentationContext`")); }
133.2266 +    } while(0);
133.2267 +    do { // convert the 'UnitsInContext' argument
133.2268 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2269 +        try { GenericConvert( in->UnitsInContext, arg, db ); break; } 
133.2270 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcProject to be a `IfcUnitAssignment`")); }
133.2271 +    } while(0);
133.2272 +	return base;
133.2273 +}
133.2274 +// -----------------------------------------------------------------------------------------------------------
133.2275 +template <> size_t GenericFill<IfcEvaporatorType>(const DB& db, const LIST& params, IfcEvaporatorType* in)
133.2276 +{
133.2277 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.2278 +// this data structure is not used yet, so there is no code generated to fill its members
133.2279 +	return base;
133.2280 +}
133.2281 +// -----------------------------------------------------------------------------------------------------------
133.2282 +template <> size_t GenericFill<IfcLaborResource>(const DB& db, const LIST& params, IfcLaborResource* in)
133.2283 +{
133.2284 +	size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in));
133.2285 +// this data structure is not used yet, so there is no code generated to fill its members
133.2286 +	return base;
133.2287 +}
133.2288 +// -----------------------------------------------------------------------------------------------------------
133.2289 +template <> size_t GenericFill<IfcPropertyBoundedValue>(const DB& db, const LIST& params, IfcPropertyBoundedValue* in)
133.2290 +{
133.2291 +	size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in));
133.2292 +// this data structure is not used yet, so there is no code generated to fill its members
133.2293 +	return base;
133.2294 +}
133.2295 +// -----------------------------------------------------------------------------------------------------------
133.2296 +template <> size_t GenericFill<IfcRampFlightType>(const DB& db, const LIST& params, IfcRampFlightType* in)
133.2297 +{
133.2298 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.2299 +// this data structure is not used yet, so there is no code generated to fill its members
133.2300 +	return base;
133.2301 +}
133.2302 +// -----------------------------------------------------------------------------------------------------------
133.2303 +template <> size_t GenericFill<IfcMember>(const DB& db, const LIST& params, IfcMember* in)
133.2304 +{
133.2305 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.2306 +// this data structure is not used yet, so there is no code generated to fill its members
133.2307 +	return base;
133.2308 +}
133.2309 +// -----------------------------------------------------------------------------------------------------------
133.2310 +template <> size_t GenericFill<IfcTubeBundleType>(const DB& db, const LIST& params, IfcTubeBundleType* in)
133.2311 +{
133.2312 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.2313 +// this data structure is not used yet, so there is no code generated to fill its members
133.2314 +	return base;
133.2315 +}
133.2316 +// -----------------------------------------------------------------------------------------------------------
133.2317 +template <> size_t GenericFill<IfcValveType>(const DB& db, const LIST& params, IfcValveType* in)
133.2318 +{
133.2319 +	size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in));
133.2320 +// this data structure is not used yet, so there is no code generated to fill its members
133.2321 +	return base;
133.2322 +}
133.2323 +// -----------------------------------------------------------------------------------------------------------
133.2324 +template <> size_t GenericFill<IfcTrimmedCurve>(const DB& db, const LIST& params, IfcTrimmedCurve* in)
133.2325 +{
133.2326 +	size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in));
133.2327 +	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcTrimmedCurve"); }    do { // convert the 'BasisCurve' argument
133.2328 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2329 +        try { GenericConvert( in->BasisCurve, arg, db ); break; } 
133.2330 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcTrimmedCurve to be a `IfcCurve`")); }
133.2331 +    } while(0);
133.2332 +    do { // convert the 'Trim1' argument
133.2333 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2334 +        try { GenericConvert( in->Trim1, arg, db ); break; } 
133.2335 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcTrimmedCurve to be a `SET [1:2] OF IfcTrimmingSelect`")); }
133.2336 +    } while(0);
133.2337 +    do { // convert the 'Trim2' argument
133.2338 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2339 +        try { GenericConvert( in->Trim2, arg, db ); break; } 
133.2340 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcTrimmedCurve to be a `SET [1:2] OF IfcTrimmingSelect`")); }
133.2341 +    } while(0);
133.2342 +    do { // convert the 'SenseAgreement' argument
133.2343 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2344 +        try { GenericConvert( in->SenseAgreement, arg, db ); break; } 
133.2345 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcTrimmedCurve to be a `BOOLEAN`")); }
133.2346 +    } while(0);
133.2347 +    do { // convert the 'MasterRepresentation' argument
133.2348 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2349 +        try { GenericConvert( in->MasterRepresentation, arg, db ); break; } 
133.2350 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcTrimmedCurve to be a `IfcTrimmingPreference`")); }
133.2351 +    } while(0);
133.2352 +	return base;
133.2353 +}
133.2354 +// -----------------------------------------------------------------------------------------------------------
133.2355 +template <> size_t GenericFill<IfcRelDefines>(const DB& db, const LIST& params, IfcRelDefines* in)
133.2356 +{
133.2357 +	size_t base = GenericFill(db,params,static_cast<IfcRelationship*>(in));
133.2358 +	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcRelDefines"); }    do { // convert the 'RelatedObjects' argument
133.2359 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2360 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRelDefines,1>::aux_is_derived[0]=true; break; }
133.2361 +        try { GenericConvert( in->RelatedObjects, arg, db ); break; } 
133.2362 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelDefines to be a `SET [1:?] OF IfcObject`")); }
133.2363 +    } while(0);
133.2364 +	return base;
133.2365 +}
133.2366 +// -----------------------------------------------------------------------------------------------------------
133.2367 +template <> size_t GenericFill<IfcRelDefinesByProperties>(const DB& db, const LIST& params, IfcRelDefinesByProperties* in)
133.2368 +{
133.2369 +	size_t base = GenericFill(db,params,static_cast<IfcRelDefines*>(in));
133.2370 +	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelDefinesByProperties"); }    do { // convert the 'RelatingPropertyDefinition' argument
133.2371 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2372 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRelDefinesByProperties,1>::aux_is_derived[0]=true; break; }
133.2373 +        try { GenericConvert( in->RelatingPropertyDefinition, arg, db ); break; } 
133.2374 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelDefinesByProperties to be a `IfcPropertySetDefinition`")); }
133.2375 +    } while(0);
133.2376 +	return base;
133.2377 +}
133.2378 +// -----------------------------------------------------------------------------------------------------------
133.2379 +template <> size_t GenericFill<IfcActor>(const DB& db, const LIST& params, IfcActor* in)
133.2380 +{
133.2381 +	size_t base = GenericFill(db,params,static_cast<IfcObject*>(in));
133.2382 +// this data structure is not used yet, so there is no code generated to fill its members
133.2383 +	return base;
133.2384 +}
133.2385 +// -----------------------------------------------------------------------------------------------------------
133.2386 +template <> size_t GenericFill<IfcOccupant>(const DB& db, const LIST& params, IfcOccupant* in)
133.2387 +{
133.2388 +	size_t base = GenericFill(db,params,static_cast<IfcActor*>(in));
133.2389 +// this data structure is not used yet, so there is no code generated to fill its members
133.2390 +	return base;
133.2391 +}
133.2392 +// -----------------------------------------------------------------------------------------------------------
133.2393 +template <> size_t GenericFill<IfcHumidifierType>(const DB& db, const LIST& params, IfcHumidifierType* in)
133.2394 +{
133.2395 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.2396 +// this data structure is not used yet, so there is no code generated to fill its members
133.2397 +	return base;
133.2398 +}
133.2399 +// -----------------------------------------------------------------------------------------------------------
133.2400 +template <> size_t GenericFill<IfcArbitraryOpenProfileDef>(const DB& db, const LIST& params, IfcArbitraryOpenProfileDef* in)
133.2401 +{
133.2402 +	size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in));
133.2403 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcArbitraryOpenProfileDef"); }    do { // convert the 'Curve' argument
133.2404 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2405 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcArbitraryOpenProfileDef,1>::aux_is_derived[0]=true; break; }
133.2406 +        try { GenericConvert( in->Curve, arg, db ); break; } 
133.2407 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcArbitraryOpenProfileDef to be a `IfcBoundedCurve`")); }
133.2408 +    } while(0);
133.2409 +	return base;
133.2410 +}
133.2411 +// -----------------------------------------------------------------------------------------------------------
133.2412 +template <> size_t GenericFill<IfcPermit>(const DB& db, const LIST& params, IfcPermit* in)
133.2413 +{
133.2414 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.2415 +// this data structure is not used yet, so there is no code generated to fill its members
133.2416 +	return base;
133.2417 +}
133.2418 +// -----------------------------------------------------------------------------------------------------------
133.2419 +template <> size_t GenericFill<IfcOffsetCurve3D>(const DB& db, const LIST& params, IfcOffsetCurve3D* in)
133.2420 +{
133.2421 +	size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in));
133.2422 +// this data structure is not used yet, so there is no code generated to fill its members
133.2423 +	return base;
133.2424 +}
133.2425 +// -----------------------------------------------------------------------------------------------------------
133.2426 +template <> size_t GenericFill<IfcLightSource>(const DB& db, const LIST& params, IfcLightSource* in)
133.2427 +{
133.2428 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.2429 +// this data structure is not used yet, so there is no code generated to fill its members
133.2430 +	return base;
133.2431 +}
133.2432 +// -----------------------------------------------------------------------------------------------------------
133.2433 +template <> size_t GenericFill<IfcLightSourcePositional>(const DB& db, const LIST& params, IfcLightSourcePositional* in)
133.2434 +{
133.2435 +	size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in));
133.2436 +// this data structure is not used yet, so there is no code generated to fill its members
133.2437 +	return base;
133.2438 +}
133.2439 +// -----------------------------------------------------------------------------------------------------------
133.2440 +template <> size_t GenericFill<IfcCompositeProfileDef>(const DB& db, const LIST& params, IfcCompositeProfileDef* in)
133.2441 +{
133.2442 +	size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in));
133.2443 +// this data structure is not used yet, so there is no code generated to fill its members
133.2444 +	return base;
133.2445 +}
133.2446 +// -----------------------------------------------------------------------------------------------------------
133.2447 +template <> size_t GenericFill<IfcRamp>(const DB& db, const LIST& params, IfcRamp* in)
133.2448 +{
133.2449 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.2450 +// this data structure is not used yet, so there is no code generated to fill its members
133.2451 +	return base;
133.2452 +}
133.2453 +// -----------------------------------------------------------------------------------------------------------
133.2454 +template <> size_t GenericFill<IfcFlowMovingDevice>(const DB& db, const LIST& params, IfcFlowMovingDevice* in)
133.2455 +{
133.2456 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in));
133.2457 +// this data structure is not used yet, so there is no code generated to fill its members
133.2458 +	return base;
133.2459 +}
133.2460 +// -----------------------------------------------------------------------------------------------------------
133.2461 +template <> size_t GenericFill<IfcSpaceHeaterType>(const DB& db, const LIST& params, IfcSpaceHeaterType* in)
133.2462 +{
133.2463 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.2464 +// this data structure is not used yet, so there is no code generated to fill its members
133.2465 +	return base;
133.2466 +}
133.2467 +// -----------------------------------------------------------------------------------------------------------
133.2468 +template <> size_t GenericFill<IfcLampType>(const DB& db, const LIST& params, IfcLampType* in)
133.2469 +{
133.2470 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.2471 +// this data structure is not used yet, so there is no code generated to fill its members
133.2472 +	return base;
133.2473 +}
133.2474 +// -----------------------------------------------------------------------------------------------------------
133.2475 +template <> size_t GenericFill<IfcBuildingElementComponent>(const DB& db, const LIST& params, IfcBuildingElementComponent* in)
133.2476 +{
133.2477 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.2478 +// this data structure is not used yet, so there is no code generated to fill its members
133.2479 +	return base;
133.2480 +}
133.2481 +// -----------------------------------------------------------------------------------------------------------
133.2482 +template <> size_t GenericFill<IfcReinforcingElement>(const DB& db, const LIST& params, IfcReinforcingElement* in)
133.2483 +{
133.2484 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementComponent*>(in));
133.2485 +// this data structure is not used yet, so there is no code generated to fill its members
133.2486 +	return base;
133.2487 +}
133.2488 +// -----------------------------------------------------------------------------------------------------------
133.2489 +template <> size_t GenericFill<IfcReinforcingBar>(const DB& db, const LIST& params, IfcReinforcingBar* in)
133.2490 +{
133.2491 +	size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in));
133.2492 +// this data structure is not used yet, so there is no code generated to fill its members
133.2493 +	return base;
133.2494 +}
133.2495 +// -----------------------------------------------------------------------------------------------------------
133.2496 +template <> size_t GenericFill<IfcElectricHeaterType>(const DB& db, const LIST& params, IfcElectricHeaterType* in)
133.2497 +{
133.2498 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.2499 +// this data structure is not used yet, so there is no code generated to fill its members
133.2500 +	return base;
133.2501 +}
133.2502 +// -----------------------------------------------------------------------------------------------------------
133.2503 +template <> size_t GenericFill<IfcTShapeProfileDef>(const DB& db, const LIST& params, IfcTShapeProfileDef* in)
133.2504 +{
133.2505 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.2506 +// this data structure is not used yet, so there is no code generated to fill its members
133.2507 +	return base;
133.2508 +}
133.2509 +// -----------------------------------------------------------------------------------------------------------
133.2510 +template <> size_t GenericFill<IfcStructuralActivity>(const DB& db, const LIST& params, IfcStructuralActivity* in)
133.2511 +{
133.2512 +	size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in));
133.2513 +// this data structure is not used yet, so there is no code generated to fill its members
133.2514 +	return base;
133.2515 +}
133.2516 +// -----------------------------------------------------------------------------------------------------------
133.2517 +template <> size_t GenericFill<IfcStructuralAction>(const DB& db, const LIST& params, IfcStructuralAction* in)
133.2518 +{
133.2519 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralActivity*>(in));
133.2520 +// this data structure is not used yet, so there is no code generated to fill its members
133.2521 +	return base;
133.2522 +}
133.2523 +// -----------------------------------------------------------------------------------------------------------
133.2524 +template <> size_t GenericFill<IfcDuctFittingType>(const DB& db, const LIST& params, IfcDuctFittingType* in)
133.2525 +{
133.2526 +	size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in));
133.2527 +// this data structure is not used yet, so there is no code generated to fill its members
133.2528 +	return base;
133.2529 +}
133.2530 +// -----------------------------------------------------------------------------------------------------------
133.2531 +template <> size_t GenericFill<IfcCartesianTransformationOperator2D>(const DB& db, const LIST& params, IfcCartesianTransformationOperator2D* in)
133.2532 +{
133.2533 +	size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator*>(in));
133.2534 +// this data structure is not used yet, so there is no code generated to fill its members
133.2535 +	return base;
133.2536 +}
133.2537 +// -----------------------------------------------------------------------------------------------------------
133.2538 +template <> size_t GenericFill<IfcCartesianTransformationOperator2DnonUniform>(const DB& db, const LIST& params, IfcCartesianTransformationOperator2DnonUniform* in)
133.2539 +{
133.2540 +	size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator2D*>(in));
133.2541 +// this data structure is not used yet, so there is no code generated to fill its members
133.2542 +	return base;
133.2543 +}
133.2544 +// -----------------------------------------------------------------------------------------------------------
133.2545 +template <> size_t GenericFill<IfcVirtualElement>(const DB& db, const LIST& params, IfcVirtualElement* in)
133.2546 +{
133.2547 +	size_t base = GenericFill(db,params,static_cast<IfcElement*>(in));
133.2548 +// this data structure is not used yet, so there is no code generated to fill its members
133.2549 +	return base;
133.2550 +}
133.2551 +// -----------------------------------------------------------------------------------------------------------
133.2552 +template <> size_t GenericFill<IfcRightCircularCylinder>(const DB& db, const LIST& params, IfcRightCircularCylinder* in)
133.2553 +{
133.2554 +	size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in));
133.2555 +// this data structure is not used yet, so there is no code generated to fill its members
133.2556 +	return base;
133.2557 +}
133.2558 +// -----------------------------------------------------------------------------------------------------------
133.2559 +template <> size_t GenericFill<IfcOutletType>(const DB& db, const LIST& params, IfcOutletType* in)
133.2560 +{
133.2561 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.2562 +// this data structure is not used yet, so there is no code generated to fill its members
133.2563 +	return base;
133.2564 +}
133.2565 +// -----------------------------------------------------------------------------------------------------------
133.2566 +template <> size_t GenericFill<IfcRelDecomposes>(const DB& db, const LIST& params, IfcRelDecomposes* in)
133.2567 +{
133.2568 +	size_t base = GenericFill(db,params,static_cast<IfcRelationship*>(in));
133.2569 +	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelDecomposes"); }    do { // convert the 'RelatingObject' argument
133.2570 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2571 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRelDecomposes,2>::aux_is_derived[0]=true; break; }
133.2572 +        try { GenericConvert( in->RelatingObject, arg, db ); break; } 
133.2573 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelDecomposes to be a `IfcObjectDefinition`")); }
133.2574 +    } while(0);
133.2575 +    do { // convert the 'RelatedObjects' argument
133.2576 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2577 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRelDecomposes,2>::aux_is_derived[1]=true; break; }
133.2578 +        try { GenericConvert( in->RelatedObjects, arg, db ); break; } 
133.2579 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelDecomposes to be a `SET [1:?] OF IfcObjectDefinition`")); }
133.2580 +    } while(0);
133.2581 +	return base;
133.2582 +}
133.2583 +// -----------------------------------------------------------------------------------------------------------
133.2584 +template <> size_t GenericFill<IfcCovering>(const DB& db, const LIST& params, IfcCovering* in)
133.2585 +{
133.2586 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.2587 +// this data structure is not used yet, so there is no code generated to fill its members
133.2588 +	return base;
133.2589 +}
133.2590 +// -----------------------------------------------------------------------------------------------------------
133.2591 +template <> size_t GenericFill<IfcPolyline>(const DB& db, const LIST& params, IfcPolyline* in)
133.2592 +{
133.2593 +	size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in));
133.2594 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPolyline"); }    do { // convert the 'Points' argument
133.2595 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2596 +        try { GenericConvert( in->Points, arg, db ); break; } 
133.2597 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPolyline to be a `LIST [2:?] OF IfcCartesianPoint`")); }
133.2598 +    } while(0);
133.2599 +	return base;
133.2600 +}
133.2601 +// -----------------------------------------------------------------------------------------------------------
133.2602 +template <> size_t GenericFill<IfcPath>(const DB& db, const LIST& params, IfcPath* in)
133.2603 +{
133.2604 +	size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in));
133.2605 +// this data structure is not used yet, so there is no code generated to fill its members
133.2606 +	return base;
133.2607 +}
133.2608 +// -----------------------------------------------------------------------------------------------------------
133.2609 +template <> size_t GenericFill<IfcElementComponent>(const DB& db, const LIST& params, IfcElementComponent* in)
133.2610 +{
133.2611 +	size_t base = GenericFill(db,params,static_cast<IfcElement*>(in));
133.2612 +// this data structure is not used yet, so there is no code generated to fill its members
133.2613 +	return base;
133.2614 +}
133.2615 +// -----------------------------------------------------------------------------------------------------------
133.2616 +template <> size_t GenericFill<IfcFastener>(const DB& db, const LIST& params, IfcFastener* in)
133.2617 +{
133.2618 +	size_t base = GenericFill(db,params,static_cast<IfcElementComponent*>(in));
133.2619 +// this data structure is not used yet, so there is no code generated to fill its members
133.2620 +	return base;
133.2621 +}
133.2622 +// -----------------------------------------------------------------------------------------------------------
133.2623 +template <> size_t GenericFill<IfcMappedItem>(const DB& db, const LIST& params, IfcMappedItem* in)
133.2624 +{
133.2625 +	size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in));
133.2626 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMappedItem"); }    do { // convert the 'MappingSource' argument
133.2627 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2628 +        try { GenericConvert( in->MappingSource, arg, db ); break; } 
133.2629 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMappedItem to be a `IfcRepresentationMap`")); }
133.2630 +    } while(0);
133.2631 +    do { // convert the 'MappingTarget' argument
133.2632 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2633 +        try { GenericConvert( in->MappingTarget, arg, db ); break; } 
133.2634 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMappedItem to be a `IfcCartesianTransformationOperator`")); }
133.2635 +    } while(0);
133.2636 +	return base;
133.2637 +}
133.2638 +// -----------------------------------------------------------------------------------------------------------
133.2639 +template <> size_t GenericFill<IfcRectangularPyramid>(const DB& db, const LIST& params, IfcRectangularPyramid* in)
133.2640 +{
133.2641 +	size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in));
133.2642 +// this data structure is not used yet, so there is no code generated to fill its members
133.2643 +	return base;
133.2644 +}
133.2645 +// -----------------------------------------------------------------------------------------------------------
133.2646 +template <> size_t GenericFill<IfcCrewResource>(const DB& db, const LIST& params, IfcCrewResource* in)
133.2647 +{
133.2648 +	size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in));
133.2649 +// this data structure is not used yet, so there is no code generated to fill its members
133.2650 +	return base;
133.2651 +}
133.2652 +// -----------------------------------------------------------------------------------------------------------
133.2653 +template <> size_t GenericFill<IfcNamedUnit>(const DB& db, const LIST& params, IfcNamedUnit* in)
133.2654 +{
133.2655 +	size_t base = 0;
133.2656 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcNamedUnit"); }    do { // convert the 'Dimensions' argument
133.2657 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2658 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcNamedUnit,2>::aux_is_derived[0]=true; break; }
133.2659 +        try { GenericConvert( in->Dimensions, arg, db ); break; } 
133.2660 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcNamedUnit to be a `IfcDimensionalExponents`")); }
133.2661 +    } while(0);
133.2662 +    do { // convert the 'UnitType' argument
133.2663 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2664 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcNamedUnit,2>::aux_is_derived[1]=true; break; }
133.2665 +        try { GenericConvert( in->UnitType, arg, db ); break; } 
133.2666 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcNamedUnit to be a `IfcUnitEnum`")); }
133.2667 +    } while(0);
133.2668 +	return base;
133.2669 +}
133.2670 +// -----------------------------------------------------------------------------------------------------------
133.2671 +template <> size_t GenericFill<IfcContextDependentUnit>(const DB& db, const LIST& params, IfcContextDependentUnit* in)
133.2672 +{
133.2673 +	size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in));
133.2674 +// this data structure is not used yet, so there is no code generated to fill its members
133.2675 +	return base;
133.2676 +}
133.2677 +// -----------------------------------------------------------------------------------------------------------
133.2678 +template <> size_t GenericFill<IfcUnitaryEquipmentType>(const DB& db, const LIST& params, IfcUnitaryEquipmentType* in)
133.2679 +{
133.2680 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.2681 +// this data structure is not used yet, so there is no code generated to fill its members
133.2682 +	return base;
133.2683 +}
133.2684 +// -----------------------------------------------------------------------------------------------------------
133.2685 +template <> size_t GenericFill<IfcRoof>(const DB& db, const LIST& params, IfcRoof* in)
133.2686 +{
133.2687 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.2688 +// this data structure is not used yet, so there is no code generated to fill its members
133.2689 +	return base;
133.2690 +}
133.2691 +// -----------------------------------------------------------------------------------------------------------
133.2692 +template <> size_t GenericFill<IfcStructuralMember>(const DB& db, const LIST& params, IfcStructuralMember* in)
133.2693 +{
133.2694 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralItem*>(in));
133.2695 +// this data structure is not used yet, so there is no code generated to fill its members
133.2696 +	return base;
133.2697 +}
133.2698 +// -----------------------------------------------------------------------------------------------------------
133.2699 +template <> size_t GenericFill<IfcStyleModel>(const DB& db, const LIST& params, IfcStyleModel* in)
133.2700 +{
133.2701 +	size_t base = GenericFill(db,params,static_cast<IfcRepresentation*>(in));
133.2702 +// this data structure is not used yet, so there is no code generated to fill its members
133.2703 +	return base;
133.2704 +}
133.2705 +// -----------------------------------------------------------------------------------------------------------
133.2706 +template <> size_t GenericFill<IfcStyledRepresentation>(const DB& db, const LIST& params, IfcStyledRepresentation* in)
133.2707 +{
133.2708 +	size_t base = GenericFill(db,params,static_cast<IfcStyleModel*>(in));
133.2709 +// this data structure is not used yet, so there is no code generated to fill its members
133.2710 +	return base;
133.2711 +}
133.2712 +// -----------------------------------------------------------------------------------------------------------
133.2713 +template <> size_t GenericFill<IfcSpatialStructureElement>(const DB& db, const LIST& params, IfcSpatialStructureElement* in)
133.2714 +{
133.2715 +	size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in));
133.2716 +	if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcSpatialStructureElement"); }    do { // convert the 'LongName' argument
133.2717 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2718 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSpatialStructureElement,2>::aux_is_derived[0]=true; break; }
133.2719 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2720 +        try { GenericConvert( in->LongName, arg, db ); break; } 
133.2721 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcSpatialStructureElement to be a `IfcLabel`")); }
133.2722 +    } while(0);
133.2723 +    do { // convert the 'CompositionType' argument
133.2724 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2725 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSpatialStructureElement,2>::aux_is_derived[1]=true; break; }
133.2726 +        try { GenericConvert( in->CompositionType, arg, db ); break; } 
133.2727 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSpatialStructureElement to be a `IfcElementCompositionEnum`")); }
133.2728 +    } while(0);
133.2729 +	return base;
133.2730 +}
133.2731 +// -----------------------------------------------------------------------------------------------------------
133.2732 +template <> size_t GenericFill<IfcBuilding>(const DB& db, const LIST& params, IfcBuilding* in)
133.2733 +{
133.2734 +	size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in));
133.2735 +	if (params.GetSize() < 12) { throw STEP::TypeError("expected 12 arguments to IfcBuilding"); }    do { // convert the 'ElevationOfRefHeight' argument
133.2736 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2737 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2738 +        try { GenericConvert( in->ElevationOfRefHeight, arg, db ); break; } 
133.2739 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcBuilding to be a `IfcLengthMeasure`")); }
133.2740 +    } while(0);
133.2741 +    do { // convert the 'ElevationOfTerrain' argument
133.2742 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2743 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2744 +        try { GenericConvert( in->ElevationOfTerrain, arg, db ); break; } 
133.2745 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcBuilding to be a `IfcLengthMeasure`")); }
133.2746 +    } while(0);
133.2747 +    do { // convert the 'BuildingAddress' argument
133.2748 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2749 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2750 +        try { GenericConvert( in->BuildingAddress, arg, db ); break; } 
133.2751 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 11 to IfcBuilding to be a `IfcPostalAddress`")); }
133.2752 +    } while(0);
133.2753 +	return base;
133.2754 +}
133.2755 +// -----------------------------------------------------------------------------------------------------------
133.2756 +template <> size_t GenericFill<IfcConnectedFaceSet>(const DB& db, const LIST& params, IfcConnectedFaceSet* in)
133.2757 +{
133.2758 +	size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in));
133.2759 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcConnectedFaceSet"); }    do { // convert the 'CfsFaces' argument
133.2760 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2761 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcConnectedFaceSet,1>::aux_is_derived[0]=true; break; }
133.2762 +        try { GenericConvert( in->CfsFaces, arg, db ); break; } 
133.2763 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcConnectedFaceSet to be a `SET [1:?] OF IfcFace`")); }
133.2764 +    } while(0);
133.2765 +	return base;
133.2766 +}
133.2767 +// -----------------------------------------------------------------------------------------------------------
133.2768 +template <> size_t GenericFill<IfcOpenShell>(const DB& db, const LIST& params, IfcOpenShell* in)
133.2769 +{
133.2770 +	size_t base = GenericFill(db,params,static_cast<IfcConnectedFaceSet*>(in));
133.2771 +// this data structure is not used yet, so there is no code generated to fill its members
133.2772 +	return base;
133.2773 +}
133.2774 +// -----------------------------------------------------------------------------------------------------------
133.2775 +template <> size_t GenericFill<IfcFacetedBrep>(const DB& db, const LIST& params, IfcFacetedBrep* in)
133.2776 +{
133.2777 +	size_t base = GenericFill(db,params,static_cast<IfcManifoldSolidBrep*>(in));
133.2778 +// this data structure is not used yet, so there is no code generated to fill its members
133.2779 +	return base;
133.2780 +}
133.2781 +// -----------------------------------------------------------------------------------------------------------
133.2782 +template <> size_t GenericFill<IfcConic>(const DB& db, const LIST& params, IfcConic* in)
133.2783 +{
133.2784 +	size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in));
133.2785 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcConic"); }    do { // convert the 'Position' argument
133.2786 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2787 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcConic,1>::aux_is_derived[0]=true; break; }
133.2788 +        try { GenericConvert( in->Position, arg, db ); break; } 
133.2789 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcConic to be a `IfcAxis2Placement`")); }
133.2790 +    } while(0);
133.2791 +	return base;
133.2792 +}
133.2793 +// -----------------------------------------------------------------------------------------------------------
133.2794 +template <> size_t GenericFill<IfcCoveringType>(const DB& db, const LIST& params, IfcCoveringType* in)
133.2795 +{
133.2796 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.2797 +// this data structure is not used yet, so there is no code generated to fill its members
133.2798 +	return base;
133.2799 +}
133.2800 +// -----------------------------------------------------------------------------------------------------------
133.2801 +template <> size_t GenericFill<IfcRoundedRectangleProfileDef>(const DB& db, const LIST& params, IfcRoundedRectangleProfileDef* in)
133.2802 +{
133.2803 +	size_t base = GenericFill(db,params,static_cast<IfcRectangleProfileDef*>(in));
133.2804 +// this data structure is not used yet, so there is no code generated to fill its members
133.2805 +	return base;
133.2806 +}
133.2807 +// -----------------------------------------------------------------------------------------------------------
133.2808 +template <> size_t GenericFill<IfcAirTerminalType>(const DB& db, const LIST& params, IfcAirTerminalType* in)
133.2809 +{
133.2810 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.2811 +// this data structure is not used yet, so there is no code generated to fill its members
133.2812 +	return base;
133.2813 +}
133.2814 +// -----------------------------------------------------------------------------------------------------------
133.2815 +template <> size_t GenericFill<IfcFlowMovingDeviceType>(const DB& db, const LIST& params, IfcFlowMovingDeviceType* in)
133.2816 +{
133.2817 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in));
133.2818 +// this data structure is not used yet, so there is no code generated to fill its members
133.2819 +	return base;
133.2820 +}
133.2821 +// -----------------------------------------------------------------------------------------------------------
133.2822 +template <> size_t GenericFill<IfcCompressorType>(const DB& db, const LIST& params, IfcCompressorType* in)
133.2823 +{
133.2824 +	size_t base = GenericFill(db,params,static_cast<IfcFlowMovingDeviceType*>(in));
133.2825 +// this data structure is not used yet, so there is no code generated to fill its members
133.2826 +	return base;
133.2827 +}
133.2828 +// -----------------------------------------------------------------------------------------------------------
133.2829 +template <> size_t GenericFill<IfcIShapeProfileDef>(const DB& db, const LIST& params, IfcIShapeProfileDef* in)
133.2830 +{
133.2831 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.2832 +	if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcIShapeProfileDef"); }    do { // convert the 'OverallWidth' argument
133.2833 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2834 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcIShapeProfileDef,5>::aux_is_derived[0]=true; break; }
133.2835 +        try { GenericConvert( in->OverallWidth, arg, db ); break; } 
133.2836 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
133.2837 +    } while(0);
133.2838 +    do { // convert the 'OverallDepth' argument
133.2839 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2840 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcIShapeProfileDef,5>::aux_is_derived[1]=true; break; }
133.2841 +        try { GenericConvert( in->OverallDepth, arg, db ); break; } 
133.2842 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
133.2843 +    } while(0);
133.2844 +    do { // convert the 'WebThickness' argument
133.2845 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2846 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcIShapeProfileDef,5>::aux_is_derived[2]=true; break; }
133.2847 +        try { GenericConvert( in->WebThickness, arg, db ); break; } 
133.2848 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
133.2849 +    } while(0);
133.2850 +    do { // convert the 'FlangeThickness' argument
133.2851 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2852 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcIShapeProfileDef,5>::aux_is_derived[3]=true; break; }
133.2853 +        try { GenericConvert( in->FlangeThickness, arg, db ); break; } 
133.2854 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
133.2855 +    } while(0);
133.2856 +    do { // convert the 'FilletRadius' argument
133.2857 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2858 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcIShapeProfileDef,5>::aux_is_derived[4]=true; break; }
133.2859 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2860 +        try { GenericConvert( in->FilletRadius, arg, db ); break; } 
133.2861 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
133.2862 +    } while(0);
133.2863 +	return base;
133.2864 +}
133.2865 +// -----------------------------------------------------------------------------------------------------------
133.2866 +template <> size_t GenericFill<IfcAsymmetricIShapeProfileDef>(const DB& db, const LIST& params, IfcAsymmetricIShapeProfileDef* in)
133.2867 +{
133.2868 +	size_t base = GenericFill(db,params,static_cast<IfcIShapeProfileDef*>(in));
133.2869 +// this data structure is not used yet, so there is no code generated to fill its members
133.2870 +	return base;
133.2871 +}
133.2872 +// -----------------------------------------------------------------------------------------------------------
133.2873 +template <> size_t GenericFill<IfcControllerType>(const DB& db, const LIST& params, IfcControllerType* in)
133.2874 +{
133.2875 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in));
133.2876 +// this data structure is not used yet, so there is no code generated to fill its members
133.2877 +	return base;
133.2878 +}
133.2879 +// -----------------------------------------------------------------------------------------------------------
133.2880 +template <> size_t GenericFill<IfcRailing>(const DB& db, const LIST& params, IfcRailing* in)
133.2881 +{
133.2882 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.2883 +// this data structure is not used yet, so there is no code generated to fill its members
133.2884 +	return base;
133.2885 +}
133.2886 +// -----------------------------------------------------------------------------------------------------------
133.2887 +template <> size_t GenericFill<IfcGroup>(const DB& db, const LIST& params, IfcGroup* in)
133.2888 +{
133.2889 +	size_t base = GenericFill(db,params,static_cast<IfcObject*>(in));
133.2890 +// this data structure is not used yet, so there is no code generated to fill its members
133.2891 +	return base;
133.2892 +}
133.2893 +// -----------------------------------------------------------------------------------------------------------
133.2894 +template <> size_t GenericFill<IfcAsset>(const DB& db, const LIST& params, IfcAsset* in)
133.2895 +{
133.2896 +	size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in));
133.2897 +// this data structure is not used yet, so there is no code generated to fill its members
133.2898 +	return base;
133.2899 +}
133.2900 +// -----------------------------------------------------------------------------------------------------------
133.2901 +template <> size_t GenericFill<IfcMaterialDefinitionRepresentation>(const DB& db, const LIST& params, IfcMaterialDefinitionRepresentation* in)
133.2902 +{
133.2903 +	size_t base = GenericFill(db,params,static_cast<IfcProductRepresentation*>(in));
133.2904 +// this data structure is not used yet, so there is no code generated to fill its members
133.2905 +	return base;
133.2906 +}
133.2907 +// -----------------------------------------------------------------------------------------------------------
133.2908 +template <> size_t GenericFill<IfcRailingType>(const DB& db, const LIST& params, IfcRailingType* in)
133.2909 +{
133.2910 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.2911 +// this data structure is not used yet, so there is no code generated to fill its members
133.2912 +	return base;
133.2913 +}
133.2914 +// -----------------------------------------------------------------------------------------------------------
133.2915 +template <> size_t GenericFill<IfcWall>(const DB& db, const LIST& params, IfcWall* in)
133.2916 +{
133.2917 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.2918 +// this data structure is not used yet, so there is no code generated to fill its members
133.2919 +	return base;
133.2920 +}
133.2921 +// -----------------------------------------------------------------------------------------------------------
133.2922 +template <> size_t GenericFill<IfcStructuralPointConnection>(const DB& db, const LIST& params, IfcStructuralPointConnection* in)
133.2923 +{
133.2924 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralConnection*>(in));
133.2925 +// this data structure is not used yet, so there is no code generated to fill its members
133.2926 +	return base;
133.2927 +}
133.2928 +// -----------------------------------------------------------------------------------------------------------
133.2929 +template <> size_t GenericFill<IfcPropertyListValue>(const DB& db, const LIST& params, IfcPropertyListValue* in)
133.2930 +{
133.2931 +	size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in));
133.2932 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertyListValue"); }    do { // convert the 'ListValues' argument
133.2933 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2934 +        try { GenericConvert( in->ListValues, arg, db ); break; } 
133.2935 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPropertyListValue to be a `LIST [1:?] OF IfcValue`")); }
133.2936 +    } while(0);
133.2937 +    do { // convert the 'Unit' argument
133.2938 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2939 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2940 +        try { GenericConvert( in->Unit, arg, db ); break; } 
133.2941 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPropertyListValue to be a `IfcUnit`")); }
133.2942 +    } while(0);
133.2943 +	return base;
133.2944 +}
133.2945 +// -----------------------------------------------------------------------------------------------------------
133.2946 +template <> size_t GenericFill<IfcFurnitureStandard>(const DB& db, const LIST& params, IfcFurnitureStandard* in)
133.2947 +{
133.2948 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.2949 +// this data structure is not used yet, so there is no code generated to fill its members
133.2950 +	return base;
133.2951 +}
133.2952 +// -----------------------------------------------------------------------------------------------------------
133.2953 +template <> size_t GenericFill<IfcElectricGeneratorType>(const DB& db, const LIST& params, IfcElectricGeneratorType* in)
133.2954 +{
133.2955 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.2956 +// this data structure is not used yet, so there is no code generated to fill its members
133.2957 +	return base;
133.2958 +}
133.2959 +// -----------------------------------------------------------------------------------------------------------
133.2960 +template <> size_t GenericFill<IfcDoor>(const DB& db, const LIST& params, IfcDoor* in)
133.2961 +{
133.2962 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.2963 +	if (params.GetSize() < 10) { throw STEP::TypeError("expected 10 arguments to IfcDoor"); }    do { // convert the 'OverallHeight' argument
133.2964 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2965 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2966 +        try { GenericConvert( in->OverallHeight, arg, db ); break; } 
133.2967 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcDoor to be a `IfcPositiveLengthMeasure`")); }
133.2968 +    } while(0);
133.2969 +    do { // convert the 'OverallWidth' argument
133.2970 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2971 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2972 +        try { GenericConvert( in->OverallWidth, arg, db ); break; } 
133.2973 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcDoor to be a `IfcPositiveLengthMeasure`")); }
133.2974 +    } while(0);
133.2975 +	return base;
133.2976 +}
133.2977 +// -----------------------------------------------------------------------------------------------------------
133.2978 +template <> size_t GenericFill<IfcStyledItem>(const DB& db, const LIST& params, IfcStyledItem* in)
133.2979 +{
133.2980 +	size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in));
133.2981 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcStyledItem"); }    do { // convert the 'Item' argument
133.2982 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2983 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcStyledItem,3>::aux_is_derived[0]=true; break; }
133.2984 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2985 +        try { GenericConvert( in->Item, arg, db ); break; } 
133.2986 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcStyledItem to be a `IfcRepresentationItem`")); }
133.2987 +    } while(0);
133.2988 +    do { // convert the 'Styles' argument
133.2989 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2990 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcStyledItem,3>::aux_is_derived[1]=true; break; }
133.2991 +        try { GenericConvert( in->Styles, arg, db ); break; } 
133.2992 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcStyledItem to be a `SET [1:?] OF IfcPresentationStyleAssignment`")); }
133.2993 +    } while(0);
133.2994 +    do { // convert the 'Name' argument
133.2995 +        boost::shared_ptr<const DataType> arg = params[base++];
133.2996 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcStyledItem,3>::aux_is_derived[2]=true; break; }
133.2997 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.2998 +        try { GenericConvert( in->Name, arg, db ); break; } 
133.2999 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcStyledItem to be a `IfcLabel`")); }
133.3000 +    } while(0);
133.3001 +	return base;
133.3002 +}
133.3003 +// -----------------------------------------------------------------------------------------------------------
133.3004 +template <> size_t GenericFill<IfcAnnotationOccurrence>(const DB& db, const LIST& params, IfcAnnotationOccurrence* in)
133.3005 +{
133.3006 +	size_t base = GenericFill(db,params,static_cast<IfcStyledItem*>(in));
133.3007 +// this data structure is not used yet, so there is no code generated to fill its members
133.3008 +	return base;
133.3009 +}
133.3010 +// -----------------------------------------------------------------------------------------------------------
133.3011 +template <> size_t GenericFill<IfcAnnotationSymbolOccurrence>(const DB& db, const LIST& params, IfcAnnotationSymbolOccurrence* in)
133.3012 +{
133.3013 +	size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in));
133.3014 +// this data structure is not used yet, so there is no code generated to fill its members
133.3015 +	return base;
133.3016 +}
133.3017 +// -----------------------------------------------------------------------------------------------------------
133.3018 +template <> size_t GenericFill<IfcArbitraryClosedProfileDef>(const DB& db, const LIST& params, IfcArbitraryClosedProfileDef* in)
133.3019 +{
133.3020 +	size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in));
133.3021 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcArbitraryClosedProfileDef"); }    do { // convert the 'OuterCurve' argument
133.3022 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3023 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcArbitraryClosedProfileDef,1>::aux_is_derived[0]=true; break; }
133.3024 +        try { GenericConvert( in->OuterCurve, arg, db ); break; } 
133.3025 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcArbitraryClosedProfileDef to be a `IfcCurve`")); }
133.3026 +    } while(0);
133.3027 +	return base;
133.3028 +}
133.3029 +// -----------------------------------------------------------------------------------------------------------
133.3030 +template <> size_t GenericFill<IfcArbitraryProfileDefWithVoids>(const DB& db, const LIST& params, IfcArbitraryProfileDefWithVoids* in)
133.3031 +{
133.3032 +	size_t base = GenericFill(db,params,static_cast<IfcArbitraryClosedProfileDef*>(in));
133.3033 +// this data structure is not used yet, so there is no code generated to fill its members
133.3034 +	return base;
133.3035 +}
133.3036 +// -----------------------------------------------------------------------------------------------------------
133.3037 +template <> size_t GenericFill<IfcLine>(const DB& db, const LIST& params, IfcLine* in)
133.3038 +{
133.3039 +	size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in));
133.3040 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcLine"); }    do { // convert the 'Pnt' argument
133.3041 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3042 +        try { GenericConvert( in->Pnt, arg, db ); break; } 
133.3043 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcLine to be a `IfcCartesianPoint`")); }
133.3044 +    } while(0);
133.3045 +    do { // convert the 'Dir' argument
133.3046 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3047 +        try { GenericConvert( in->Dir, arg, db ); break; } 
133.3048 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcLine to be a `IfcVector`")); }
133.3049 +    } while(0);
133.3050 +	return base;
133.3051 +}
133.3052 +// -----------------------------------------------------------------------------------------------------------
133.3053 +template <> size_t GenericFill<IfcFlowSegmentType>(const DB& db, const LIST& params, IfcFlowSegmentType* in)
133.3054 +{
133.3055 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in));
133.3056 +// this data structure is not used yet, so there is no code generated to fill its members
133.3057 +	return base;
133.3058 +}
133.3059 +// -----------------------------------------------------------------------------------------------------------
133.3060 +template <> size_t GenericFill<IfcAirTerminalBoxType>(const DB& db, const LIST& params, IfcAirTerminalBoxType* in)
133.3061 +{
133.3062 +	size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in));
133.3063 +// this data structure is not used yet, so there is no code generated to fill its members
133.3064 +	return base;
133.3065 +}
133.3066 +// -----------------------------------------------------------------------------------------------------------
133.3067 +template <> size_t GenericFill<IfcPropertySingleValue>(const DB& db, const LIST& params, IfcPropertySingleValue* in)
133.3068 +{
133.3069 +	size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in));
133.3070 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertySingleValue"); }    do { // convert the 'NominalValue' argument
133.3071 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3072 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3073 +        try { GenericConvert( in->NominalValue, arg, db ); break; } 
133.3074 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPropertySingleValue to be a `IfcValue`")); }
133.3075 +    } while(0);
133.3076 +    do { // convert the 'Unit' argument
133.3077 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3078 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3079 +        try { GenericConvert( in->Unit, arg, db ); break; } 
133.3080 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPropertySingleValue to be a `IfcUnit`")); }
133.3081 +    } while(0);
133.3082 +	return base;
133.3083 +}
133.3084 +// -----------------------------------------------------------------------------------------------------------
133.3085 +template <> size_t GenericFill<IfcAlarmType>(const DB& db, const LIST& params, IfcAlarmType* in)
133.3086 +{
133.3087 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in));
133.3088 +// this data structure is not used yet, so there is no code generated to fill its members
133.3089 +	return base;
133.3090 +}
133.3091 +// -----------------------------------------------------------------------------------------------------------
133.3092 +template <> size_t GenericFill<IfcEllipseProfileDef>(const DB& db, const LIST& params, IfcEllipseProfileDef* in)
133.3093 +{
133.3094 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.3095 +// this data structure is not used yet, so there is no code generated to fill its members
133.3096 +	return base;
133.3097 +}
133.3098 +// -----------------------------------------------------------------------------------------------------------
133.3099 +template <> size_t GenericFill<IfcStair>(const DB& db, const LIST& params, IfcStair* in)
133.3100 +{
133.3101 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.3102 +// this data structure is not used yet, so there is no code generated to fill its members
133.3103 +	return base;
133.3104 +}
133.3105 +// -----------------------------------------------------------------------------------------------------------
133.3106 +template <> size_t GenericFill<IfcSurfaceStyleShading>(const DB& db, const LIST& params, IfcSurfaceStyleShading* in)
133.3107 +{
133.3108 +	size_t base = 0;
133.3109 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleShading"); }    do { // convert the 'SurfaceColour' argument
133.3110 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3111 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSurfaceStyleShading,1>::aux_is_derived[0]=true; break; }
133.3112 +        try { GenericConvert( in->SurfaceColour, arg, db ); break; } 
133.3113 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSurfaceStyleShading to be a `IfcColourRgb`")); }
133.3114 +    } while(0);
133.3115 +	return base;
133.3116 +}
133.3117 +// -----------------------------------------------------------------------------------------------------------
133.3118 +template <> size_t GenericFill<IfcPumpType>(const DB& db, const LIST& params, IfcPumpType* in)
133.3119 +{
133.3120 +	size_t base = GenericFill(db,params,static_cast<IfcFlowMovingDeviceType*>(in));
133.3121 +// this data structure is not used yet, so there is no code generated to fill its members
133.3122 +	return base;
133.3123 +}
133.3124 +// -----------------------------------------------------------------------------------------------------------
133.3125 +template <> size_t GenericFill<IfcDefinedSymbol>(const DB& db, const LIST& params, IfcDefinedSymbol* in)
133.3126 +{
133.3127 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.3128 +// this data structure is not used yet, so there is no code generated to fill its members
133.3129 +	return base;
133.3130 +}
133.3131 +// -----------------------------------------------------------------------------------------------------------
133.3132 +template <> size_t GenericFill<IfcElementComponentType>(const DB& db, const LIST& params, IfcElementComponentType* in)
133.3133 +{
133.3134 +	size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in));
133.3135 +// this data structure is not used yet, so there is no code generated to fill its members
133.3136 +	return base;
133.3137 +}
133.3138 +// -----------------------------------------------------------------------------------------------------------
133.3139 +template <> size_t GenericFill<IfcFastenerType>(const DB& db, const LIST& params, IfcFastenerType* in)
133.3140 +{
133.3141 +	size_t base = GenericFill(db,params,static_cast<IfcElementComponentType*>(in));
133.3142 +// this data structure is not used yet, so there is no code generated to fill its members
133.3143 +	return base;
133.3144 +}
133.3145 +// -----------------------------------------------------------------------------------------------------------
133.3146 +template <> size_t GenericFill<IfcMechanicalFastenerType>(const DB& db, const LIST& params, IfcMechanicalFastenerType* in)
133.3147 +{
133.3148 +	size_t base = GenericFill(db,params,static_cast<IfcFastenerType*>(in));
133.3149 +// this data structure is not used yet, so there is no code generated to fill its members
133.3150 +	return base;
133.3151 +}
133.3152 +// -----------------------------------------------------------------------------------------------------------
133.3153 +template <> size_t GenericFill<IfcFlowFitting>(const DB& db, const LIST& params, IfcFlowFitting* in)
133.3154 +{
133.3155 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in));
133.3156 +// this data structure is not used yet, so there is no code generated to fill its members
133.3157 +	return base;
133.3158 +}
133.3159 +// -----------------------------------------------------------------------------------------------------------
133.3160 +template <> size_t GenericFill<IfcLightSourceDirectional>(const DB& db, const LIST& params, IfcLightSourceDirectional* in)
133.3161 +{
133.3162 +	size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in));
133.3163 +// this data structure is not used yet, so there is no code generated to fill its members
133.3164 +	return base;
133.3165 +}
133.3166 +// -----------------------------------------------------------------------------------------------------------
133.3167 +template <> size_t GenericFill<IfcSurfaceStyle>(const DB& db, const LIST& params, IfcSurfaceStyle* in)
133.3168 +{
133.3169 +	size_t base = GenericFill(db,params,static_cast<IfcPresentationStyle*>(in));
133.3170 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcSurfaceStyle"); }    do { // convert the 'Side' argument
133.3171 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3172 +        try { GenericConvert( in->Side, arg, db ); break; } 
133.3173 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSurfaceStyle to be a `IfcSurfaceSide`")); }
133.3174 +    } while(0);
133.3175 +    do { // convert the 'Styles' argument
133.3176 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3177 +        try { GenericConvert( in->Styles, arg, db ); break; } 
133.3178 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSurfaceStyle to be a `SET [1:5] OF IfcSurfaceStyleElementSelect`")); }
133.3179 +    } while(0);
133.3180 +	return base;
133.3181 +}
133.3182 +// -----------------------------------------------------------------------------------------------------------
133.3183 +template <> size_t GenericFill<IfcAnnotationSurface>(const DB& db, const LIST& params, IfcAnnotationSurface* in)
133.3184 +{
133.3185 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.3186 +// this data structure is not used yet, so there is no code generated to fill its members
133.3187 +	return base;
133.3188 +}
133.3189 +// -----------------------------------------------------------------------------------------------------------
133.3190 +template <> size_t GenericFill<IfcFlowController>(const DB& db, const LIST& params, IfcFlowController* in)
133.3191 +{
133.3192 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in));
133.3193 +// this data structure is not used yet, so there is no code generated to fill its members
133.3194 +	return base;
133.3195 +}
133.3196 +// -----------------------------------------------------------------------------------------------------------
133.3197 +template <> size_t GenericFill<IfcBuildingStorey>(const DB& db, const LIST& params, IfcBuildingStorey* in)
133.3198 +{
133.3199 +	size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in));
133.3200 +// this data structure is not used yet, so there is no code generated to fill its members
133.3201 +	return base;
133.3202 +}
133.3203 +// -----------------------------------------------------------------------------------------------------------
133.3204 +template <> size_t GenericFill<IfcWorkControl>(const DB& db, const LIST& params, IfcWorkControl* in)
133.3205 +{
133.3206 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.3207 +// this data structure is not used yet, so there is no code generated to fill its members
133.3208 +	return base;
133.3209 +}
133.3210 +// -----------------------------------------------------------------------------------------------------------
133.3211 +template <> size_t GenericFill<IfcWorkSchedule>(const DB& db, const LIST& params, IfcWorkSchedule* in)
133.3212 +{
133.3213 +	size_t base = GenericFill(db,params,static_cast<IfcWorkControl*>(in));
133.3214 +// this data structure is not used yet, so there is no code generated to fill its members
133.3215 +	return base;
133.3216 +}
133.3217 +// -----------------------------------------------------------------------------------------------------------
133.3218 +template <> size_t GenericFill<IfcDuctSegmentType>(const DB& db, const LIST& params, IfcDuctSegmentType* in)
133.3219 +{
133.3220 +	size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in));
133.3221 +// this data structure is not used yet, so there is no code generated to fill its members
133.3222 +	return base;
133.3223 +}
133.3224 +// -----------------------------------------------------------------------------------------------------------
133.3225 +template <> size_t GenericFill<IfcFace>(const DB& db, const LIST& params, IfcFace* in)
133.3226 +{
133.3227 +	size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in));
133.3228 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcFace"); }    do { // convert the 'Bounds' argument
133.3229 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3230 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcFace,1>::aux_is_derived[0]=true; break; }
133.3231 +        try { GenericConvert( in->Bounds, arg, db ); break; } 
133.3232 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFace to be a `SET [1:?] OF IfcFaceBound`")); }
133.3233 +    } while(0);
133.3234 +	return base;
133.3235 +}
133.3236 +// -----------------------------------------------------------------------------------------------------------
133.3237 +template <> size_t GenericFill<IfcStructuralSurfaceMember>(const DB& db, const LIST& params, IfcStructuralSurfaceMember* in)
133.3238 +{
133.3239 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralMember*>(in));
133.3240 +// this data structure is not used yet, so there is no code generated to fill its members
133.3241 +	return base;
133.3242 +}
133.3243 +// -----------------------------------------------------------------------------------------------------------
133.3244 +template <> size_t GenericFill<IfcStructuralSurfaceMemberVarying>(const DB& db, const LIST& params, IfcStructuralSurfaceMemberVarying* in)
133.3245 +{
133.3246 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralSurfaceMember*>(in));
133.3247 +// this data structure is not used yet, so there is no code generated to fill its members
133.3248 +	return base;
133.3249 +}
133.3250 +// -----------------------------------------------------------------------------------------------------------
133.3251 +template <> size_t GenericFill<IfcFaceSurface>(const DB& db, const LIST& params, IfcFaceSurface* in)
133.3252 +{
133.3253 +	size_t base = GenericFill(db,params,static_cast<IfcFace*>(in));
133.3254 +// this data structure is not used yet, so there is no code generated to fill its members
133.3255 +	return base;
133.3256 +}
133.3257 +// -----------------------------------------------------------------------------------------------------------
133.3258 +template <> size_t GenericFill<IfcCostSchedule>(const DB& db, const LIST& params, IfcCostSchedule* in)
133.3259 +{
133.3260 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.3261 +// this data structure is not used yet, so there is no code generated to fill its members
133.3262 +	return base;
133.3263 +}
133.3264 +// -----------------------------------------------------------------------------------------------------------
133.3265 +template <> size_t GenericFill<IfcPlanarExtent>(const DB& db, const LIST& params, IfcPlanarExtent* in)
133.3266 +{
133.3267 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.3268 +// this data structure is not used yet, so there is no code generated to fill its members
133.3269 +	return base;
133.3270 +}
133.3271 +// -----------------------------------------------------------------------------------------------------------
133.3272 +template <> size_t GenericFill<IfcPlanarBox>(const DB& db, const LIST& params, IfcPlanarBox* in)
133.3273 +{
133.3274 +	size_t base = GenericFill(db,params,static_cast<IfcPlanarExtent*>(in));
133.3275 +// this data structure is not used yet, so there is no code generated to fill its members
133.3276 +	return base;
133.3277 +}
133.3278 +// -----------------------------------------------------------------------------------------------------------
133.3279 +template <> size_t GenericFill<IfcColourSpecification>(const DB& db, const LIST& params, IfcColourSpecification* in)
133.3280 +{
133.3281 +	size_t base = 0;
133.3282 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcColourSpecification"); }    do { // convert the 'Name' argument
133.3283 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3284 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcColourSpecification,1>::aux_is_derived[0]=true; break; }
133.3285 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3286 +        try { GenericConvert( in->Name, arg, db ); break; } 
133.3287 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcColourSpecification to be a `IfcLabel`")); }
133.3288 +    } while(0);
133.3289 +	return base;
133.3290 +}
133.3291 +// -----------------------------------------------------------------------------------------------------------
133.3292 +template <> size_t GenericFill<IfcVector>(const DB& db, const LIST& params, IfcVector* in)
133.3293 +{
133.3294 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.3295 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcVector"); }    do { // convert the 'Orientation' argument
133.3296 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3297 +        try { GenericConvert( in->Orientation, arg, db ); break; } 
133.3298 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcVector to be a `IfcDirection`")); }
133.3299 +    } while(0);
133.3300 +    do { // convert the 'Magnitude' argument
133.3301 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3302 +        try { GenericConvert( in->Magnitude, arg, db ); break; } 
133.3303 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcVector to be a `IfcLengthMeasure`")); }
133.3304 +    } while(0);
133.3305 +	return base;
133.3306 +}
133.3307 +// -----------------------------------------------------------------------------------------------------------
133.3308 +template <> size_t GenericFill<IfcBeam>(const DB& db, const LIST& params, IfcBeam* in)
133.3309 +{
133.3310 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.3311 +// this data structure is not used yet, so there is no code generated to fill its members
133.3312 +	return base;
133.3313 +}
133.3314 +// -----------------------------------------------------------------------------------------------------------
133.3315 +template <> size_t GenericFill<IfcColourRgb>(const DB& db, const LIST& params, IfcColourRgb* in)
133.3316 +{
133.3317 +	size_t base = GenericFill(db,params,static_cast<IfcColourSpecification*>(in));
133.3318 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcColourRgb"); }    do { // convert the 'Red' argument
133.3319 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3320 +        try { GenericConvert( in->Red, arg, db ); break; } 
133.3321 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); }
133.3322 +    } while(0);
133.3323 +    do { // convert the 'Green' argument
133.3324 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3325 +        try { GenericConvert( in->Green, arg, db ); break; } 
133.3326 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); }
133.3327 +    } while(0);
133.3328 +    do { // convert the 'Blue' argument
133.3329 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3330 +        try { GenericConvert( in->Blue, arg, db ); break; } 
133.3331 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); }
133.3332 +    } while(0);
133.3333 +	return base;
133.3334 +}
133.3335 +// -----------------------------------------------------------------------------------------------------------
133.3336 +template <> size_t GenericFill<IfcStructuralPlanarAction>(const DB& db, const LIST& params, IfcStructuralPlanarAction* in)
133.3337 +{
133.3338 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralAction*>(in));
133.3339 +// this data structure is not used yet, so there is no code generated to fill its members
133.3340 +	return base;
133.3341 +}
133.3342 +// -----------------------------------------------------------------------------------------------------------
133.3343 +template <> size_t GenericFill<IfcStructuralPlanarActionVarying>(const DB& db, const LIST& params, IfcStructuralPlanarActionVarying* in)
133.3344 +{
133.3345 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralPlanarAction*>(in));
133.3346 +// this data structure is not used yet, so there is no code generated to fill its members
133.3347 +	return base;
133.3348 +}
133.3349 +// -----------------------------------------------------------------------------------------------------------
133.3350 +template <> size_t GenericFill<IfcSite>(const DB& db, const LIST& params, IfcSite* in)
133.3351 +{
133.3352 +	size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in));
133.3353 +	if (params.GetSize() < 14) { throw STEP::TypeError("expected 14 arguments to IfcSite"); }    do { // convert the 'RefLatitude' argument
133.3354 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3355 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3356 +        try { GenericConvert( in->RefLatitude, arg, db ); break; } 
133.3357 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcSite to be a `IfcCompoundPlaneAngleMeasure`")); }
133.3358 +    } while(0);
133.3359 +    do { // convert the 'RefLongitude' argument
133.3360 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3361 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3362 +        try { GenericConvert( in->RefLongitude, arg, db ); break; } 
133.3363 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcSite to be a `IfcCompoundPlaneAngleMeasure`")); }
133.3364 +    } while(0);
133.3365 +    do { // convert the 'RefElevation' argument
133.3366 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3367 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3368 +        try { GenericConvert( in->RefElevation, arg, db ); break; } 
133.3369 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 11 to IfcSite to be a `IfcLengthMeasure`")); }
133.3370 +    } while(0);
133.3371 +    do { // convert the 'LandTitleNumber' argument
133.3372 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3373 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3374 +        try { GenericConvert( in->LandTitleNumber, arg, db ); break; } 
133.3375 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 12 to IfcSite to be a `IfcLabel`")); }
133.3376 +    } while(0);
133.3377 +    do { // convert the 'SiteAddress' argument
133.3378 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3379 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3380 +        try { GenericConvert( in->SiteAddress, arg, db ); break; } 
133.3381 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 13 to IfcSite to be a `IfcPostalAddress`")); }
133.3382 +    } while(0);
133.3383 +	return base;
133.3384 +}
133.3385 +// -----------------------------------------------------------------------------------------------------------
133.3386 +template <> size_t GenericFill<IfcDiscreteAccessoryType>(const DB& db, const LIST& params, IfcDiscreteAccessoryType* in)
133.3387 +{
133.3388 +	size_t base = GenericFill(db,params,static_cast<IfcElementComponentType*>(in));
133.3389 +// this data structure is not used yet, so there is no code generated to fill its members
133.3390 +	return base;
133.3391 +}
133.3392 +// -----------------------------------------------------------------------------------------------------------
133.3393 +template <> size_t GenericFill<IfcVibrationIsolatorType>(const DB& db, const LIST& params, IfcVibrationIsolatorType* in)
133.3394 +{
133.3395 +	size_t base = GenericFill(db,params,static_cast<IfcDiscreteAccessoryType*>(in));
133.3396 +// this data structure is not used yet, so there is no code generated to fill its members
133.3397 +	return base;
133.3398 +}
133.3399 +// -----------------------------------------------------------------------------------------------------------
133.3400 +template <> size_t GenericFill<IfcEvaporativeCoolerType>(const DB& db, const LIST& params, IfcEvaporativeCoolerType* in)
133.3401 +{
133.3402 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.3403 +// this data structure is not used yet, so there is no code generated to fill its members
133.3404 +	return base;
133.3405 +}
133.3406 +// -----------------------------------------------------------------------------------------------------------
133.3407 +template <> size_t GenericFill<IfcDistributionChamberElementType>(const DB& db, const LIST& params, IfcDistributionChamberElementType* in)
133.3408 +{
133.3409 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in));
133.3410 +// this data structure is not used yet, so there is no code generated to fill its members
133.3411 +	return base;
133.3412 +}
133.3413 +// -----------------------------------------------------------------------------------------------------------
133.3414 +template <> size_t GenericFill<IfcFeatureElementAddition>(const DB& db, const LIST& params, IfcFeatureElementAddition* in)
133.3415 +{
133.3416 +	size_t base = GenericFill(db,params,static_cast<IfcFeatureElement*>(in));
133.3417 +// this data structure is not used yet, so there is no code generated to fill its members
133.3418 +	return base;
133.3419 +}
133.3420 +// -----------------------------------------------------------------------------------------------------------
133.3421 +template <> size_t GenericFill<IfcStructuredDimensionCallout>(const DB& db, const LIST& params, IfcStructuredDimensionCallout* in)
133.3422 +{
133.3423 +	size_t base = GenericFill(db,params,static_cast<IfcDraughtingCallout*>(in));
133.3424 +// this data structure is not used yet, so there is no code generated to fill its members
133.3425 +	return base;
133.3426 +}
133.3427 +// -----------------------------------------------------------------------------------------------------------
133.3428 +template <> size_t GenericFill<IfcCoolingTowerType>(const DB& db, const LIST& params, IfcCoolingTowerType* in)
133.3429 +{
133.3430 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.3431 +// this data structure is not used yet, so there is no code generated to fill its members
133.3432 +	return base;
133.3433 +}
133.3434 +// -----------------------------------------------------------------------------------------------------------
133.3435 +template <> size_t GenericFill<IfcCenterLineProfileDef>(const DB& db, const LIST& params, IfcCenterLineProfileDef* in)
133.3436 +{
133.3437 +	size_t base = GenericFill(db,params,static_cast<IfcArbitraryOpenProfileDef*>(in));
133.3438 +// this data structure is not used yet, so there is no code generated to fill its members
133.3439 +	return base;
133.3440 +}
133.3441 +// -----------------------------------------------------------------------------------------------------------
133.3442 +template <> size_t GenericFill<IfcWindowStyle>(const DB& db, const LIST& params, IfcWindowStyle* in)
133.3443 +{
133.3444 +	size_t base = GenericFill(db,params,static_cast<IfcTypeProduct*>(in));
133.3445 +// this data structure is not used yet, so there is no code generated to fill its members
133.3446 +	return base;
133.3447 +}
133.3448 +// -----------------------------------------------------------------------------------------------------------
133.3449 +template <> size_t GenericFill<IfcLightSourceGoniometric>(const DB& db, const LIST& params, IfcLightSourceGoniometric* in)
133.3450 +{
133.3451 +	size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in));
133.3452 +// this data structure is not used yet, so there is no code generated to fill its members
133.3453 +	return base;
133.3454 +}
133.3455 +// -----------------------------------------------------------------------------------------------------------
133.3456 +template <> size_t GenericFill<IfcTransformerType>(const DB& db, const LIST& params, IfcTransformerType* in)
133.3457 +{
133.3458 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.3459 +// this data structure is not used yet, so there is no code generated to fill its members
133.3460 +	return base;
133.3461 +}
133.3462 +// -----------------------------------------------------------------------------------------------------------
133.3463 +template <> size_t GenericFill<IfcMemberType>(const DB& db, const LIST& params, IfcMemberType* in)
133.3464 +{
133.3465 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.3466 +// this data structure is not used yet, so there is no code generated to fill its members
133.3467 +	return base;
133.3468 +}
133.3469 +// -----------------------------------------------------------------------------------------------------------
133.3470 +template <> size_t GenericFill<IfcSurfaceOfLinearExtrusion>(const DB& db, const LIST& params, IfcSurfaceOfLinearExtrusion* in)
133.3471 +{
133.3472 +	size_t base = GenericFill(db,params,static_cast<IfcSweptSurface*>(in));
133.3473 +// this data structure is not used yet, so there is no code generated to fill its members
133.3474 +	return base;
133.3475 +}
133.3476 +// -----------------------------------------------------------------------------------------------------------
133.3477 +template <> size_t GenericFill<IfcMotorConnectionType>(const DB& db, const LIST& params, IfcMotorConnectionType* in)
133.3478 +{
133.3479 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.3480 +// this data structure is not used yet, so there is no code generated to fill its members
133.3481 +	return base;
133.3482 +}
133.3483 +// -----------------------------------------------------------------------------------------------------------
133.3484 +template <> size_t GenericFill<IfcFlowTreatmentDeviceType>(const DB& db, const LIST& params, IfcFlowTreatmentDeviceType* in)
133.3485 +{
133.3486 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in));
133.3487 +// this data structure is not used yet, so there is no code generated to fill its members
133.3488 +	return base;
133.3489 +}
133.3490 +// -----------------------------------------------------------------------------------------------------------
133.3491 +template <> size_t GenericFill<IfcDuctSilencerType>(const DB& db, const LIST& params, IfcDuctSilencerType* in)
133.3492 +{
133.3493 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTreatmentDeviceType*>(in));
133.3494 +// this data structure is not used yet, so there is no code generated to fill its members
133.3495 +	return base;
133.3496 +}
133.3497 +// -----------------------------------------------------------------------------------------------------------
133.3498 +template <> size_t GenericFill<IfcFurnishingElementType>(const DB& db, const LIST& params, IfcFurnishingElementType* in)
133.3499 +{
133.3500 +	size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in));
133.3501 +// this data structure is not used yet, so there is no code generated to fill its members
133.3502 +	return base;
133.3503 +}
133.3504 +// -----------------------------------------------------------------------------------------------------------
133.3505 +template <> size_t GenericFill<IfcSystemFurnitureElementType>(const DB& db, const LIST& params, IfcSystemFurnitureElementType* in)
133.3506 +{
133.3507 +	size_t base = GenericFill(db,params,static_cast<IfcFurnishingElementType*>(in));
133.3508 +// this data structure is not used yet, so there is no code generated to fill its members
133.3509 +	return base;
133.3510 +}
133.3511 +// -----------------------------------------------------------------------------------------------------------
133.3512 +template <> size_t GenericFill<IfcWasteTerminalType>(const DB& db, const LIST& params, IfcWasteTerminalType* in)
133.3513 +{
133.3514 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.3515 +// this data structure is not used yet, so there is no code generated to fill its members
133.3516 +	return base;
133.3517 +}
133.3518 +// -----------------------------------------------------------------------------------------------------------
133.3519 +template <> size_t GenericFill<IfcBSplineCurve>(const DB& db, const LIST& params, IfcBSplineCurve* in)
133.3520 +{
133.3521 +	size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in));
133.3522 +	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcBSplineCurve"); }    do { // convert the 'Degree' argument
133.3523 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3524 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[0]=true; break; }
133.3525 +        try { GenericConvert( in->Degree, arg, db ); break; } 
133.3526 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBSplineCurve to be a `INTEGER`")); }
133.3527 +    } while(0);
133.3528 +    do { // convert the 'ControlPointsList' argument
133.3529 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3530 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[1]=true; break; }
133.3531 +        try { GenericConvert( in->ControlPointsList, arg, db ); break; } 
133.3532 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBSplineCurve to be a `LIST [2:?] OF IfcCartesianPoint`")); }
133.3533 +    } while(0);
133.3534 +    do { // convert the 'CurveForm' argument
133.3535 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3536 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[2]=true; break; }
133.3537 +        try { GenericConvert( in->CurveForm, arg, db ); break; } 
133.3538 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBSplineCurve to be a `IfcBSplineCurveForm`")); }
133.3539 +    } while(0);
133.3540 +    do { // convert the 'ClosedCurve' argument
133.3541 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3542 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[3]=true; break; }
133.3543 +        try { GenericConvert( in->ClosedCurve, arg, db ); break; } 
133.3544 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcBSplineCurve to be a `LOGICAL`")); }
133.3545 +    } while(0);
133.3546 +    do { // convert the 'SelfIntersect' argument
133.3547 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3548 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[4]=true; break; }
133.3549 +        try { GenericConvert( in->SelfIntersect, arg, db ); break; } 
133.3550 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcBSplineCurve to be a `LOGICAL`")); }
133.3551 +    } while(0);
133.3552 +	return base;
133.3553 +}
133.3554 +// -----------------------------------------------------------------------------------------------------------
133.3555 +template <> size_t GenericFill<IfcBezierCurve>(const DB& db, const LIST& params, IfcBezierCurve* in)
133.3556 +{
133.3557 +	size_t base = GenericFill(db,params,static_cast<IfcBSplineCurve*>(in));
133.3558 +// this data structure is not used yet, so there is no code generated to fill its members
133.3559 +	return base;
133.3560 +}
133.3561 +// -----------------------------------------------------------------------------------------------------------
133.3562 +template <> size_t GenericFill<IfcActuatorType>(const DB& db, const LIST& params, IfcActuatorType* in)
133.3563 +{
133.3564 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in));
133.3565 +// this data structure is not used yet, so there is no code generated to fill its members
133.3566 +	return base;
133.3567 +}
133.3568 +// -----------------------------------------------------------------------------------------------------------
133.3569 +template <> size_t GenericFill<IfcDistributionControlElement>(const DB& db, const LIST& params, IfcDistributionControlElement* in)
133.3570 +{
133.3571 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionElement*>(in));
133.3572 +// this data structure is not used yet, so there is no code generated to fill its members
133.3573 +	return base;
133.3574 +}
133.3575 +// -----------------------------------------------------------------------------------------------------------
133.3576 +template <> size_t GenericFill<IfcAnnotation>(const DB& db, const LIST& params, IfcAnnotation* in)
133.3577 +{
133.3578 +	size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in));
133.3579 +	if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcAnnotation"); }	return base;
133.3580 +}
133.3581 +// -----------------------------------------------------------------------------------------------------------
133.3582 +template <> size_t GenericFill<IfcShellBasedSurfaceModel>(const DB& db, const LIST& params, IfcShellBasedSurfaceModel* in)
133.3583 +{
133.3584 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.3585 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcShellBasedSurfaceModel"); }    do { // convert the 'SbsmBoundary' argument
133.3586 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3587 +        try { GenericConvert( in->SbsmBoundary, arg, db ); break; } 
133.3588 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcShellBasedSurfaceModel to be a `SET [1:?] OF IfcShell`")); }
133.3589 +    } while(0);
133.3590 +	return base;
133.3591 +}
133.3592 +// -----------------------------------------------------------------------------------------------------------
133.3593 +template <> size_t GenericFill<IfcActionRequest>(const DB& db, const LIST& params, IfcActionRequest* in)
133.3594 +{
133.3595 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.3596 +// this data structure is not used yet, so there is no code generated to fill its members
133.3597 +	return base;
133.3598 +}
133.3599 +// -----------------------------------------------------------------------------------------------------------
133.3600 +template <> size_t GenericFill<IfcExtrudedAreaSolid>(const DB& db, const LIST& params, IfcExtrudedAreaSolid* in)
133.3601 +{
133.3602 +	size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in));
133.3603 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcExtrudedAreaSolid"); }    do { // convert the 'ExtrudedDirection' argument
133.3604 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3605 +        try { GenericConvert( in->ExtrudedDirection, arg, db ); break; } 
133.3606 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcExtrudedAreaSolid to be a `IfcDirection`")); }
133.3607 +    } while(0);
133.3608 +    do { // convert the 'Depth' argument
133.3609 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3610 +        try { GenericConvert( in->Depth, arg, db ); break; } 
133.3611 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcExtrudedAreaSolid to be a `IfcPositiveLengthMeasure`")); }
133.3612 +    } while(0);
133.3613 +	return base;
133.3614 +}
133.3615 +// -----------------------------------------------------------------------------------------------------------
133.3616 +template <> size_t GenericFill<IfcSystem>(const DB& db, const LIST& params, IfcSystem* in)
133.3617 +{
133.3618 +	size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in));
133.3619 +// this data structure is not used yet, so there is no code generated to fill its members
133.3620 +	return base;
133.3621 +}
133.3622 +// -----------------------------------------------------------------------------------------------------------
133.3623 +template <> size_t GenericFill<IfcFillAreaStyleHatching>(const DB& db, const LIST& params, IfcFillAreaStyleHatching* in)
133.3624 +{
133.3625 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.3626 +// this data structure is not used yet, so there is no code generated to fill its members
133.3627 +	return base;
133.3628 +}
133.3629 +// -----------------------------------------------------------------------------------------------------------
133.3630 +template <> size_t GenericFill<IfcRelVoidsElement>(const DB& db, const LIST& params, IfcRelVoidsElement* in)
133.3631 +{
133.3632 +	size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in));
133.3633 +	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelVoidsElement"); }    do { // convert the 'RelatingBuildingElement' argument
133.3634 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3635 +        try { GenericConvert( in->RelatingBuildingElement, arg, db ); break; } 
133.3636 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelVoidsElement to be a `IfcElement`")); }
133.3637 +    } while(0);
133.3638 +    do { // convert the 'RelatedOpeningElement' argument
133.3639 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3640 +        try { GenericConvert( in->RelatedOpeningElement, arg, db ); break; } 
133.3641 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelVoidsElement to be a `IfcFeatureElementSubtraction`")); }
133.3642 +    } while(0);
133.3643 +	return base;
133.3644 +}
133.3645 +// -----------------------------------------------------------------------------------------------------------
133.3646 +template <> size_t GenericFill<IfcSurfaceCurveSweptAreaSolid>(const DB& db, const LIST& params, IfcSurfaceCurveSweptAreaSolid* in)
133.3647 +{
133.3648 +	size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in));
133.3649 +// this data structure is not used yet, so there is no code generated to fill its members
133.3650 +	return base;
133.3651 +}
133.3652 +// -----------------------------------------------------------------------------------------------------------
133.3653 +template <> size_t GenericFill<IfcCartesianTransformationOperator3DnonUniform>(const DB& db, const LIST& params, IfcCartesianTransformationOperator3DnonUniform* in)
133.3654 +{
133.3655 +	size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator3D*>(in));
133.3656 +	if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcCartesianTransformationOperator3DnonUniform"); }    do { // convert the 'Scale2' argument
133.3657 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3658 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3659 +        try { GenericConvert( in->Scale2, arg, db ); break; } 
133.3660 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcCartesianTransformationOperator3DnonUniform to be a `REAL`")); }
133.3661 +    } while(0);
133.3662 +    do { // convert the 'Scale3' argument
133.3663 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3664 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3665 +        try { GenericConvert( in->Scale3, arg, db ); break; } 
133.3666 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcCartesianTransformationOperator3DnonUniform to be a `REAL`")); }
133.3667 +    } while(0);
133.3668 +	return base;
133.3669 +}
133.3670 +// -----------------------------------------------------------------------------------------------------------
133.3671 +template <> size_t GenericFill<IfcCurtainWallType>(const DB& db, const LIST& params, IfcCurtainWallType* in)
133.3672 +{
133.3673 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.3674 +// this data structure is not used yet, so there is no code generated to fill its members
133.3675 +	return base;
133.3676 +}
133.3677 +// -----------------------------------------------------------------------------------------------------------
133.3678 +template <> size_t GenericFill<IfcEquipmentStandard>(const DB& db, const LIST& params, IfcEquipmentStandard* in)
133.3679 +{
133.3680 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.3681 +// this data structure is not used yet, so there is no code generated to fill its members
133.3682 +	return base;
133.3683 +}
133.3684 +// -----------------------------------------------------------------------------------------------------------
133.3685 +template <> size_t GenericFill<IfcFlowStorageDeviceType>(const DB& db, const LIST& params, IfcFlowStorageDeviceType* in)
133.3686 +{
133.3687 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in));
133.3688 +// this data structure is not used yet, so there is no code generated to fill its members
133.3689 +	return base;
133.3690 +}
133.3691 +// -----------------------------------------------------------------------------------------------------------
133.3692 +template <> size_t GenericFill<IfcDiameterDimension>(const DB& db, const LIST& params, IfcDiameterDimension* in)
133.3693 +{
133.3694 +	size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in));
133.3695 +// this data structure is not used yet, so there is no code generated to fill its members
133.3696 +	return base;
133.3697 +}
133.3698 +// -----------------------------------------------------------------------------------------------------------
133.3699 +template <> size_t GenericFill<IfcSwitchingDeviceType>(const DB& db, const LIST& params, IfcSwitchingDeviceType* in)
133.3700 +{
133.3701 +	size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in));
133.3702 +// this data structure is not used yet, so there is no code generated to fill its members
133.3703 +	return base;
133.3704 +}
133.3705 +// -----------------------------------------------------------------------------------------------------------
133.3706 +template <> size_t GenericFill<IfcWindow>(const DB& db, const LIST& params, IfcWindow* in)
133.3707 +{
133.3708 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.3709 +// this data structure is not used yet, so there is no code generated to fill its members
133.3710 +	return base;
133.3711 +}
133.3712 +// -----------------------------------------------------------------------------------------------------------
133.3713 +template <> size_t GenericFill<IfcFlowTreatmentDevice>(const DB& db, const LIST& params, IfcFlowTreatmentDevice* in)
133.3714 +{
133.3715 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in));
133.3716 +// this data structure is not used yet, so there is no code generated to fill its members
133.3717 +	return base;
133.3718 +}
133.3719 +// -----------------------------------------------------------------------------------------------------------
133.3720 +template <> size_t GenericFill<IfcChillerType>(const DB& db, const LIST& params, IfcChillerType* in)
133.3721 +{
133.3722 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.3723 +// this data structure is not used yet, so there is no code generated to fill its members
133.3724 +	return base;
133.3725 +}
133.3726 +// -----------------------------------------------------------------------------------------------------------
133.3727 +template <> size_t GenericFill<IfcRectangleHollowProfileDef>(const DB& db, const LIST& params, IfcRectangleHollowProfileDef* in)
133.3728 +{
133.3729 +	size_t base = GenericFill(db,params,static_cast<IfcRectangleProfileDef*>(in));
133.3730 +// this data structure is not used yet, so there is no code generated to fill its members
133.3731 +	return base;
133.3732 +}
133.3733 +// -----------------------------------------------------------------------------------------------------------
133.3734 +template <> size_t GenericFill<IfcBoxedHalfSpace>(const DB& db, const LIST& params, IfcBoxedHalfSpace* in)
133.3735 +{
133.3736 +	size_t base = GenericFill(db,params,static_cast<IfcHalfSpaceSolid*>(in));
133.3737 +// this data structure is not used yet, so there is no code generated to fill its members
133.3738 +	return base;
133.3739 +}
133.3740 +// -----------------------------------------------------------------------------------------------------------
133.3741 +template <> size_t GenericFill<IfcAxis2Placement2D>(const DB& db, const LIST& params, IfcAxis2Placement2D* in)
133.3742 +{
133.3743 +	size_t base = GenericFill(db,params,static_cast<IfcPlacement*>(in));
133.3744 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis2Placement2D"); }    do { // convert the 'RefDirection' argument
133.3745 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3746 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3747 +        try { GenericConvert( in->RefDirection, arg, db ); break; } 
133.3748 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis2Placement2D to be a `IfcDirection`")); }
133.3749 +    } while(0);
133.3750 +	return base;
133.3751 +}
133.3752 +// -----------------------------------------------------------------------------------------------------------
133.3753 +template <> size_t GenericFill<IfcSpaceProgram>(const DB& db, const LIST& params, IfcSpaceProgram* in)
133.3754 +{
133.3755 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.3756 +// this data structure is not used yet, so there is no code generated to fill its members
133.3757 +	return base;
133.3758 +}
133.3759 +// -----------------------------------------------------------------------------------------------------------
133.3760 +template <> size_t GenericFill<IfcPoint>(const DB& db, const LIST& params, IfcPoint* in)
133.3761 +{
133.3762 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.3763 +	return base;
133.3764 +}
133.3765 +// -----------------------------------------------------------------------------------------------------------
133.3766 +template <> size_t GenericFill<IfcCartesianPoint>(const DB& db, const LIST& params, IfcCartesianPoint* in)
133.3767 +{
133.3768 +	size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in));
133.3769 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcCartesianPoint"); }    do { // convert the 'Coordinates' argument
133.3770 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3771 +        try { GenericConvert( in->Coordinates, arg, db ); break; } 
133.3772 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCartesianPoint to be a `LIST [1:3] OF IfcLengthMeasure`")); }
133.3773 +    } while(0);
133.3774 +	return base;
133.3775 +}
133.3776 +// -----------------------------------------------------------------------------------------------------------
133.3777 +template <> size_t GenericFill<IfcBoundedSurface>(const DB& db, const LIST& params, IfcBoundedSurface* in)
133.3778 +{
133.3779 +	size_t base = GenericFill(db,params,static_cast<IfcSurface*>(in));
133.3780 +// this data structure is not used yet, so there is no code generated to fill its members
133.3781 +	return base;
133.3782 +}
133.3783 +// -----------------------------------------------------------------------------------------------------------
133.3784 +template <> size_t GenericFill<IfcLoop>(const DB& db, const LIST& params, IfcLoop* in)
133.3785 +{
133.3786 +	size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in));
133.3787 +	return base;
133.3788 +}
133.3789 +// -----------------------------------------------------------------------------------------------------------
133.3790 +template <> size_t GenericFill<IfcPolyLoop>(const DB& db, const LIST& params, IfcPolyLoop* in)
133.3791 +{
133.3792 +	size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in));
133.3793 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPolyLoop"); }    do { // convert the 'Polygon' argument
133.3794 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3795 +        try { GenericConvert( in->Polygon, arg, db ); break; } 
133.3796 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPolyLoop to be a `LIST [3:?] OF IfcCartesianPoint`")); }
133.3797 +    } while(0);
133.3798 +	return base;
133.3799 +}
133.3800 +// -----------------------------------------------------------------------------------------------------------
133.3801 +template <> size_t GenericFill<IfcTerminatorSymbol>(const DB& db, const LIST& params, IfcTerminatorSymbol* in)
133.3802 +{
133.3803 +	size_t base = GenericFill(db,params,static_cast<IfcAnnotationSymbolOccurrence*>(in));
133.3804 +// this data structure is not used yet, so there is no code generated to fill its members
133.3805 +	return base;
133.3806 +}
133.3807 +// -----------------------------------------------------------------------------------------------------------
133.3808 +template <> size_t GenericFill<IfcDimensionCurveTerminator>(const DB& db, const LIST& params, IfcDimensionCurveTerminator* in)
133.3809 +{
133.3810 +	size_t base = GenericFill(db,params,static_cast<IfcTerminatorSymbol*>(in));
133.3811 +// this data structure is not used yet, so there is no code generated to fill its members
133.3812 +	return base;
133.3813 +}
133.3814 +// -----------------------------------------------------------------------------------------------------------
133.3815 +template <> size_t GenericFill<IfcTrapeziumProfileDef>(const DB& db, const LIST& params, IfcTrapeziumProfileDef* in)
133.3816 +{
133.3817 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.3818 +// this data structure is not used yet, so there is no code generated to fill its members
133.3819 +	return base;
133.3820 +}
133.3821 +// -----------------------------------------------------------------------------------------------------------
133.3822 +template <> size_t GenericFill<IfcRepresentationContext>(const DB& db, const LIST& params, IfcRepresentationContext* in)
133.3823 +{
133.3824 +	size_t base = 0;
133.3825 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcRepresentationContext"); }    do { // convert the 'ContextIdentifier' argument
133.3826 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3827 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentationContext,2>::aux_is_derived[0]=true; break; }
133.3828 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3829 +        try { GenericConvert( in->ContextIdentifier, arg, db ); break; } 
133.3830 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentationContext to be a `IfcLabel`")); }
133.3831 +    } while(0);
133.3832 +    do { // convert the 'ContextType' argument
133.3833 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3834 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentationContext,2>::aux_is_derived[1]=true; break; }
133.3835 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3836 +        try { GenericConvert( in->ContextType, arg, db ); break; } 
133.3837 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentationContext to be a `IfcLabel`")); }
133.3838 +    } while(0);
133.3839 +	return base;
133.3840 +}
133.3841 +// -----------------------------------------------------------------------------------------------------------
133.3842 +template <> size_t GenericFill<IfcGeometricRepresentationContext>(const DB& db, const LIST& params, IfcGeometricRepresentationContext* in)
133.3843 +{
133.3844 +	size_t base = GenericFill(db,params,static_cast<IfcRepresentationContext*>(in));
133.3845 +	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcGeometricRepresentationContext"); }    do { // convert the 'CoordinateSpaceDimension' argument
133.3846 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3847 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[0]=true; break; }
133.3848 +        try { GenericConvert( in->CoordinateSpaceDimension, arg, db ); break; } 
133.3849 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcGeometricRepresentationContext to be a `IfcDimensionCount`")); }
133.3850 +    } while(0);
133.3851 +    do { // convert the 'Precision' argument
133.3852 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3853 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[1]=true; break; }
133.3854 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3855 +        try { GenericConvert( in->Precision, arg, db ); break; } 
133.3856 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcGeometricRepresentationContext to be a `REAL`")); }
133.3857 +    } while(0);
133.3858 +    do { // convert the 'WorldCoordinateSystem' argument
133.3859 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3860 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[2]=true; break; }
133.3861 +        try { GenericConvert( in->WorldCoordinateSystem, arg, db ); break; } 
133.3862 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcGeometricRepresentationContext to be a `IfcAxis2Placement`")); }
133.3863 +    } while(0);
133.3864 +    do { // convert the 'TrueNorth' argument
133.3865 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3866 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[3]=true; break; }
133.3867 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3868 +        try { GenericConvert( in->TrueNorth, arg, db ); break; } 
133.3869 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcGeometricRepresentationContext to be a `IfcDirection`")); }
133.3870 +    } while(0);
133.3871 +	return base;
133.3872 +}
133.3873 +// -----------------------------------------------------------------------------------------------------------
133.3874 +template <> size_t GenericFill<IfcCurveBoundedPlane>(const DB& db, const LIST& params, IfcCurveBoundedPlane* in)
133.3875 +{
133.3876 +	size_t base = GenericFill(db,params,static_cast<IfcBoundedSurface*>(in));
133.3877 +// this data structure is not used yet, so there is no code generated to fill its members
133.3878 +	return base;
133.3879 +}
133.3880 +// -----------------------------------------------------------------------------------------------------------
133.3881 +template <> size_t GenericFill<IfcSIUnit>(const DB& db, const LIST& params, IfcSIUnit* in)
133.3882 +{
133.3883 +	size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in));
133.3884 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcSIUnit"); }    do { // convert the 'Prefix' argument
133.3885 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3886 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3887 +        try { GenericConvert( in->Prefix, arg, db ); break; } 
133.3888 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSIUnit to be a `IfcSIPrefix`")); }
133.3889 +    } while(0);
133.3890 +    do { // convert the 'Name' argument
133.3891 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3892 +        try { GenericConvert( in->Name, arg, db ); break; } 
133.3893 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSIUnit to be a `IfcSIUnitName`")); }
133.3894 +    } while(0);
133.3895 +	return base;
133.3896 +}
133.3897 +// -----------------------------------------------------------------------------------------------------------
133.3898 +template <> size_t GenericFill<IfcStructuralReaction>(const DB& db, const LIST& params, IfcStructuralReaction* in)
133.3899 +{
133.3900 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralActivity*>(in));
133.3901 +// this data structure is not used yet, so there is no code generated to fill its members
133.3902 +	return base;
133.3903 +}
133.3904 +// -----------------------------------------------------------------------------------------------------------
133.3905 +template <> size_t GenericFill<IfcStructuralPointReaction>(const DB& db, const LIST& params, IfcStructuralPointReaction* in)
133.3906 +{
133.3907 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralReaction*>(in));
133.3908 +// this data structure is not used yet, so there is no code generated to fill its members
133.3909 +	return base;
133.3910 +}
133.3911 +// -----------------------------------------------------------------------------------------------------------
133.3912 +template <> size_t GenericFill<IfcAxis1Placement>(const DB& db, const LIST& params, IfcAxis1Placement* in)
133.3913 +{
133.3914 +	size_t base = GenericFill(db,params,static_cast<IfcPlacement*>(in));
133.3915 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis1Placement"); }    do { // convert the 'Axis' argument
133.3916 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3917 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.3918 +        try { GenericConvert( in->Axis, arg, db ); break; } 
133.3919 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis1Placement to be a `IfcDirection`")); }
133.3920 +    } while(0);
133.3921 +	return base;
133.3922 +}
133.3923 +// -----------------------------------------------------------------------------------------------------------
133.3924 +template <> size_t GenericFill<IfcElectricApplianceType>(const DB& db, const LIST& params, IfcElectricApplianceType* in)
133.3925 +{
133.3926 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.3927 +// this data structure is not used yet, so there is no code generated to fill its members
133.3928 +	return base;
133.3929 +}
133.3930 +// -----------------------------------------------------------------------------------------------------------
133.3931 +template <> size_t GenericFill<IfcSensorType>(const DB& db, const LIST& params, IfcSensorType* in)
133.3932 +{
133.3933 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in));
133.3934 +// this data structure is not used yet, so there is no code generated to fill its members
133.3935 +	return base;
133.3936 +}
133.3937 +// -----------------------------------------------------------------------------------------------------------
133.3938 +template <> size_t GenericFill<IfcFurnishingElement>(const DB& db, const LIST& params, IfcFurnishingElement* in)
133.3939 +{
133.3940 +	size_t base = GenericFill(db,params,static_cast<IfcElement*>(in));
133.3941 +// this data structure is not used yet, so there is no code generated to fill its members
133.3942 +	return base;
133.3943 +}
133.3944 +// -----------------------------------------------------------------------------------------------------------
133.3945 +template <> size_t GenericFill<IfcProtectiveDeviceType>(const DB& db, const LIST& params, IfcProtectiveDeviceType* in)
133.3946 +{
133.3947 +	size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in));
133.3948 +// this data structure is not used yet, so there is no code generated to fill its members
133.3949 +	return base;
133.3950 +}
133.3951 +// -----------------------------------------------------------------------------------------------------------
133.3952 +template <> size_t GenericFill<IfcZShapeProfileDef>(const DB& db, const LIST& params, IfcZShapeProfileDef* in)
133.3953 +{
133.3954 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.3955 +// this data structure is not used yet, so there is no code generated to fill its members
133.3956 +	return base;
133.3957 +}
133.3958 +// -----------------------------------------------------------------------------------------------------------
133.3959 +template <> size_t GenericFill<IfcScheduleTimeControl>(const DB& db, const LIST& params, IfcScheduleTimeControl* in)
133.3960 +{
133.3961 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.3962 +// this data structure is not used yet, so there is no code generated to fill its members
133.3963 +	return base;
133.3964 +}
133.3965 +// -----------------------------------------------------------------------------------------------------------
133.3966 +template <> size_t GenericFill<IfcRepresentationMap>(const DB& db, const LIST& params, IfcRepresentationMap* in)
133.3967 +{
133.3968 +	size_t base = 0;
133.3969 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcRepresentationMap"); }    do { // convert the 'MappingOrigin' argument
133.3970 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3971 +        try { GenericConvert( in->MappingOrigin, arg, db ); break; } 
133.3972 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentationMap to be a `IfcAxis2Placement`")); }
133.3973 +    } while(0);
133.3974 +    do { // convert the 'MappedRepresentation' argument
133.3975 +        boost::shared_ptr<const DataType> arg = params[base++];
133.3976 +        try { GenericConvert( in->MappedRepresentation, arg, db ); break; } 
133.3977 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentationMap to be a `IfcRepresentation`")); }
133.3978 +    } while(0);
133.3979 +	return base;
133.3980 +}
133.3981 +// -----------------------------------------------------------------------------------------------------------
133.3982 +template <> size_t GenericFill<IfcClosedShell>(const DB& db, const LIST& params, IfcClosedShell* in)
133.3983 +{
133.3984 +	size_t base = GenericFill(db,params,static_cast<IfcConnectedFaceSet*>(in));
133.3985 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcClosedShell"); }	return base;
133.3986 +}
133.3987 +// -----------------------------------------------------------------------------------------------------------
133.3988 +template <> size_t GenericFill<IfcBuildingElementPart>(const DB& db, const LIST& params, IfcBuildingElementPart* in)
133.3989 +{
133.3990 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementComponent*>(in));
133.3991 +// this data structure is not used yet, so there is no code generated to fill its members
133.3992 +	return base;
133.3993 +}
133.3994 +// -----------------------------------------------------------------------------------------------------------
133.3995 +template <> size_t GenericFill<IfcBlock>(const DB& db, const LIST& params, IfcBlock* in)
133.3996 +{
133.3997 +	size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in));
133.3998 +// this data structure is not used yet, so there is no code generated to fill its members
133.3999 +	return base;
133.4000 +}
133.4001 +// -----------------------------------------------------------------------------------------------------------
133.4002 +template <> size_t GenericFill<IfcLightFixtureType>(const DB& db, const LIST& params, IfcLightFixtureType* in)
133.4003 +{
133.4004 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.4005 +// this data structure is not used yet, so there is no code generated to fill its members
133.4006 +	return base;
133.4007 +}
133.4008 +// -----------------------------------------------------------------------------------------------------------
133.4009 +template <> size_t GenericFill<IfcOpeningElement>(const DB& db, const LIST& params, IfcOpeningElement* in)
133.4010 +{
133.4011 +	size_t base = GenericFill(db,params,static_cast<IfcFeatureElementSubtraction*>(in));
133.4012 +	if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcOpeningElement"); }	return base;
133.4013 +}
133.4014 +// -----------------------------------------------------------------------------------------------------------
133.4015 +template <> size_t GenericFill<IfcLightSourceSpot>(const DB& db, const LIST& params, IfcLightSourceSpot* in)
133.4016 +{
133.4017 +	size_t base = GenericFill(db,params,static_cast<IfcLightSourcePositional*>(in));
133.4018 +// this data structure is not used yet, so there is no code generated to fill its members
133.4019 +	return base;
133.4020 +}
133.4021 +// -----------------------------------------------------------------------------------------------------------
133.4022 +template <> size_t GenericFill<IfcTendonAnchor>(const DB& db, const LIST& params, IfcTendonAnchor* in)
133.4023 +{
133.4024 +	size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in));
133.4025 +// this data structure is not used yet, so there is no code generated to fill its members
133.4026 +	return base;
133.4027 +}
133.4028 +// -----------------------------------------------------------------------------------------------------------
133.4029 +template <> size_t GenericFill<IfcElectricFlowStorageDeviceType>(const DB& db, const LIST& params, IfcElectricFlowStorageDeviceType* in)
133.4030 +{
133.4031 +	size_t base = GenericFill(db,params,static_cast<IfcFlowStorageDeviceType*>(in));
133.4032 +// this data structure is not used yet, so there is no code generated to fill its members
133.4033 +	return base;
133.4034 +}
133.4035 +// -----------------------------------------------------------------------------------------------------------
133.4036 +template <> size_t GenericFill<IfcSphere>(const DB& db, const LIST& params, IfcSphere* in)
133.4037 +{
133.4038 +	size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in));
133.4039 +// this data structure is not used yet, so there is no code generated to fill its members
133.4040 +	return base;
133.4041 +}
133.4042 +// -----------------------------------------------------------------------------------------------------------
133.4043 +template <> size_t GenericFill<IfcDamperType>(const DB& db, const LIST& params, IfcDamperType* in)
133.4044 +{
133.4045 +	size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in));
133.4046 +// this data structure is not used yet, so there is no code generated to fill its members
133.4047 +	return base;
133.4048 +}
133.4049 +// -----------------------------------------------------------------------------------------------------------
133.4050 +template <> size_t GenericFill<IfcProjectOrderRecord>(const DB& db, const LIST& params, IfcProjectOrderRecord* in)
133.4051 +{
133.4052 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.4053 +// this data structure is not used yet, so there is no code generated to fill its members
133.4054 +	return base;
133.4055 +}
133.4056 +// -----------------------------------------------------------------------------------------------------------
133.4057 +template <> size_t GenericFill<IfcDistributionChamberElement>(const DB& db, const LIST& params, IfcDistributionChamberElement* in)
133.4058 +{
133.4059 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in));
133.4060 +// this data structure is not used yet, so there is no code generated to fill its members
133.4061 +	return base;
133.4062 +}
133.4063 +// -----------------------------------------------------------------------------------------------------------
133.4064 +template <> size_t GenericFill<IfcMechanicalFastener>(const DB& db, const LIST& params, IfcMechanicalFastener* in)
133.4065 +{
133.4066 +	size_t base = GenericFill(db,params,static_cast<IfcFastener*>(in));
133.4067 +// this data structure is not used yet, so there is no code generated to fill its members
133.4068 +	return base;
133.4069 +}
133.4070 +// -----------------------------------------------------------------------------------------------------------
133.4071 +template <> size_t GenericFill<IfcRectangularTrimmedSurface>(const DB& db, const LIST& params, IfcRectangularTrimmedSurface* in)
133.4072 +{
133.4073 +	size_t base = GenericFill(db,params,static_cast<IfcBoundedSurface*>(in));
133.4074 +// this data structure is not used yet, so there is no code generated to fill its members
133.4075 +	return base;
133.4076 +}
133.4077 +// -----------------------------------------------------------------------------------------------------------
133.4078 +template <> size_t GenericFill<IfcZone>(const DB& db, const LIST& params, IfcZone* in)
133.4079 +{
133.4080 +	size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in));
133.4081 +// this data structure is not used yet, so there is no code generated to fill its members
133.4082 +	return base;
133.4083 +}
133.4084 +// -----------------------------------------------------------------------------------------------------------
133.4085 +template <> size_t GenericFill<IfcFanType>(const DB& db, const LIST& params, IfcFanType* in)
133.4086 +{
133.4087 +	size_t base = GenericFill(db,params,static_cast<IfcFlowMovingDeviceType*>(in));
133.4088 +// this data structure is not used yet, so there is no code generated to fill its members
133.4089 +	return base;
133.4090 +}
133.4091 +// -----------------------------------------------------------------------------------------------------------
133.4092 +template <> size_t GenericFill<IfcGeometricSet>(const DB& db, const LIST& params, IfcGeometricSet* in)
133.4093 +{
133.4094 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.4095 +// this data structure is not used yet, so there is no code generated to fill its members
133.4096 +	return base;
133.4097 +}
133.4098 +// -----------------------------------------------------------------------------------------------------------
133.4099 +template <> size_t GenericFill<IfcFillAreaStyleTiles>(const DB& db, const LIST& params, IfcFillAreaStyleTiles* in)
133.4100 +{
133.4101 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.4102 +// this data structure is not used yet, so there is no code generated to fill its members
133.4103 +	return base;
133.4104 +}
133.4105 +// -----------------------------------------------------------------------------------------------------------
133.4106 +template <> size_t GenericFill<IfcCableSegmentType>(const DB& db, const LIST& params, IfcCableSegmentType* in)
133.4107 +{
133.4108 +	size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in));
133.4109 +// this data structure is not used yet, so there is no code generated to fill its members
133.4110 +	return base;
133.4111 +}
133.4112 +// -----------------------------------------------------------------------------------------------------------
133.4113 +template <> size_t GenericFill<IfcRelOverridesProperties>(const DB& db, const LIST& params, IfcRelOverridesProperties* in)
133.4114 +{
133.4115 +	size_t base = GenericFill(db,params,static_cast<IfcRelDefinesByProperties*>(in));
133.4116 +// this data structure is not used yet, so there is no code generated to fill its members
133.4117 +	return base;
133.4118 +}
133.4119 +// -----------------------------------------------------------------------------------------------------------
133.4120 +template <> size_t GenericFill<IfcMeasureWithUnit>(const DB& db, const LIST& params, IfcMeasureWithUnit* in)
133.4121 +{
133.4122 +	size_t base = 0;
133.4123 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMeasureWithUnit"); }    do { // convert the 'ValueComponent' argument
133.4124 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4125 +        try { GenericConvert( in->ValueComponent, arg, db ); break; } 
133.4126 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMeasureWithUnit to be a `IfcValue`")); }
133.4127 +    } while(0);
133.4128 +    do { // convert the 'UnitComponent' argument
133.4129 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4130 +        try { GenericConvert( in->UnitComponent, arg, db ); break; } 
133.4131 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMeasureWithUnit to be a `IfcUnit`")); }
133.4132 +    } while(0);
133.4133 +	return base;
133.4134 +}
133.4135 +// -----------------------------------------------------------------------------------------------------------
133.4136 +template <> size_t GenericFill<IfcSlabType>(const DB& db, const LIST& params, IfcSlabType* in)
133.4137 +{
133.4138 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.4139 +// this data structure is not used yet, so there is no code generated to fill its members
133.4140 +	return base;
133.4141 +}
133.4142 +// -----------------------------------------------------------------------------------------------------------
133.4143 +template <> size_t GenericFill<IfcServiceLife>(const DB& db, const LIST& params, IfcServiceLife* in)
133.4144 +{
133.4145 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.4146 +// this data structure is not used yet, so there is no code generated to fill its members
133.4147 +	return base;
133.4148 +}
133.4149 +// -----------------------------------------------------------------------------------------------------------
133.4150 +template <> size_t GenericFill<IfcFurnitureType>(const DB& db, const LIST& params, IfcFurnitureType* in)
133.4151 +{
133.4152 +	size_t base = GenericFill(db,params,static_cast<IfcFurnishingElementType*>(in));
133.4153 +// this data structure is not used yet, so there is no code generated to fill its members
133.4154 +	return base;
133.4155 +}
133.4156 +// -----------------------------------------------------------------------------------------------------------
133.4157 +template <> size_t GenericFill<IfcCostItem>(const DB& db, const LIST& params, IfcCostItem* in)
133.4158 +{
133.4159 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.4160 +// this data structure is not used yet, so there is no code generated to fill its members
133.4161 +	return base;
133.4162 +}
133.4163 +// -----------------------------------------------------------------------------------------------------------
133.4164 +template <> size_t GenericFill<IfcReinforcingMesh>(const DB& db, const LIST& params, IfcReinforcingMesh* in)
133.4165 +{
133.4166 +	size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in));
133.4167 +// this data structure is not used yet, so there is no code generated to fill its members
133.4168 +	return base;
133.4169 +}
133.4170 +// -----------------------------------------------------------------------------------------------------------
133.4171 +template <> size_t GenericFill<IfcFacetedBrepWithVoids>(const DB& db, const LIST& params, IfcFacetedBrepWithVoids* in)
133.4172 +{
133.4173 +	size_t base = GenericFill(db,params,static_cast<IfcManifoldSolidBrep*>(in));
133.4174 +// this data structure is not used yet, so there is no code generated to fill its members
133.4175 +	return base;
133.4176 +}
133.4177 +// -----------------------------------------------------------------------------------------------------------
133.4178 +template <> size_t GenericFill<IfcGasTerminalType>(const DB& db, const LIST& params, IfcGasTerminalType* in)
133.4179 +{
133.4180 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.4181 +// this data structure is not used yet, so there is no code generated to fill its members
133.4182 +	return base;
133.4183 +}
133.4184 +// -----------------------------------------------------------------------------------------------------------
133.4185 +template <> size_t GenericFill<IfcPile>(const DB& db, const LIST& params, IfcPile* in)
133.4186 +{
133.4187 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.4188 +// this data structure is not used yet, so there is no code generated to fill its members
133.4189 +	return base;
133.4190 +}
133.4191 +// -----------------------------------------------------------------------------------------------------------
133.4192 +template <> size_t GenericFill<IfcFillAreaStyleTileSymbolWithStyle>(const DB& db, const LIST& params, IfcFillAreaStyleTileSymbolWithStyle* in)
133.4193 +{
133.4194 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.4195 +// this data structure is not used yet, so there is no code generated to fill its members
133.4196 +	return base;
133.4197 +}
133.4198 +// -----------------------------------------------------------------------------------------------------------
133.4199 +template <> size_t GenericFill<IfcConstructionMaterialResource>(const DB& db, const LIST& params, IfcConstructionMaterialResource* in)
133.4200 +{
133.4201 +	size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in));
133.4202 +// this data structure is not used yet, so there is no code generated to fill its members
133.4203 +	return base;
133.4204 +}
133.4205 +// -----------------------------------------------------------------------------------------------------------
133.4206 +template <> size_t GenericFill<IfcAnnotationCurveOccurrence>(const DB& db, const LIST& params, IfcAnnotationCurveOccurrence* in)
133.4207 +{
133.4208 +	size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in));
133.4209 +// this data structure is not used yet, so there is no code generated to fill its members
133.4210 +	return base;
133.4211 +}
133.4212 +// -----------------------------------------------------------------------------------------------------------
133.4213 +template <> size_t GenericFill<IfcDimensionCurve>(const DB& db, const LIST& params, IfcDimensionCurve* in)
133.4214 +{
133.4215 +	size_t base = GenericFill(db,params,static_cast<IfcAnnotationCurveOccurrence*>(in));
133.4216 +// this data structure is not used yet, so there is no code generated to fill its members
133.4217 +	return base;
133.4218 +}
133.4219 +// -----------------------------------------------------------------------------------------------------------
133.4220 +template <> size_t GenericFill<IfcGeometricCurveSet>(const DB& db, const LIST& params, IfcGeometricCurveSet* in)
133.4221 +{
133.4222 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricSet*>(in));
133.4223 +// this data structure is not used yet, so there is no code generated to fill its members
133.4224 +	return base;
133.4225 +}
133.4226 +// -----------------------------------------------------------------------------------------------------------
133.4227 +template <> size_t GenericFill<IfcRelAggregates>(const DB& db, const LIST& params, IfcRelAggregates* in)
133.4228 +{
133.4229 +	size_t base = GenericFill(db,params,static_cast<IfcRelDecomposes*>(in));
133.4230 +	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelAggregates"); }	return base;
133.4231 +}
133.4232 +// -----------------------------------------------------------------------------------------------------------
133.4233 +template <> size_t GenericFill<IfcFaceBasedSurfaceModel>(const DB& db, const LIST& params, IfcFaceBasedSurfaceModel* in)
133.4234 +{
133.4235 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.4236 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcFaceBasedSurfaceModel"); }    do { // convert the 'FbsmFaces' argument
133.4237 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4238 +        try { GenericConvert( in->FbsmFaces, arg, db ); break; } 
133.4239 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFaceBasedSurfaceModel to be a `SET [1:?] OF IfcConnectedFaceSet`")); }
133.4240 +    } while(0);
133.4241 +	return base;
133.4242 +}
133.4243 +// -----------------------------------------------------------------------------------------------------------
133.4244 +template <> size_t GenericFill<IfcEnergyConversionDevice>(const DB& db, const LIST& params, IfcEnergyConversionDevice* in)
133.4245 +{
133.4246 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in));
133.4247 +// this data structure is not used yet, so there is no code generated to fill its members
133.4248 +	return base;
133.4249 +}
133.4250 +// -----------------------------------------------------------------------------------------------------------
133.4251 +template <> size_t GenericFill<IfcRampFlight>(const DB& db, const LIST& params, IfcRampFlight* in)
133.4252 +{
133.4253 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.4254 +// this data structure is not used yet, so there is no code generated to fill its members
133.4255 +	return base;
133.4256 +}
133.4257 +// -----------------------------------------------------------------------------------------------------------
133.4258 +template <> size_t GenericFill<IfcVertexLoop>(const DB& db, const LIST& params, IfcVertexLoop* in)
133.4259 +{
133.4260 +	size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in));
133.4261 +// this data structure is not used yet, so there is no code generated to fill its members
133.4262 +	return base;
133.4263 +}
133.4264 +// -----------------------------------------------------------------------------------------------------------
133.4265 +template <> size_t GenericFill<IfcPlate>(const DB& db, const LIST& params, IfcPlate* in)
133.4266 +{
133.4267 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.4268 +// this data structure is not used yet, so there is no code generated to fill its members
133.4269 +	return base;
133.4270 +}
133.4271 +// -----------------------------------------------------------------------------------------------------------
133.4272 +template <> size_t GenericFill<IfcUShapeProfileDef>(const DB& db, const LIST& params, IfcUShapeProfileDef* in)
133.4273 +{
133.4274 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.4275 +// this data structure is not used yet, so there is no code generated to fill its members
133.4276 +	return base;
133.4277 +}
133.4278 +// -----------------------------------------------------------------------------------------------------------
133.4279 +template <> size_t GenericFill<IfcFaceBound>(const DB& db, const LIST& params, IfcFaceBound* in)
133.4280 +{
133.4281 +	size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in));
133.4282 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcFaceBound"); }    do { // convert the 'Bound' argument
133.4283 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4284 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcFaceBound,2>::aux_is_derived[0]=true; break; }
133.4285 +        try { GenericConvert( in->Bound, arg, db ); break; } 
133.4286 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFaceBound to be a `IfcLoop`")); }
133.4287 +    } while(0);
133.4288 +    do { // convert the 'Orientation' argument
133.4289 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4290 +        if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcFaceBound,2>::aux_is_derived[1]=true; break; }
133.4291 +        try { GenericConvert( in->Orientation, arg, db ); break; } 
133.4292 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcFaceBound to be a `BOOLEAN`")); }
133.4293 +    } while(0);
133.4294 +	return base;
133.4295 +}
133.4296 +// -----------------------------------------------------------------------------------------------------------
133.4297 +template <> size_t GenericFill<IfcFaceOuterBound>(const DB& db, const LIST& params, IfcFaceOuterBound* in)
133.4298 +{
133.4299 +	size_t base = GenericFill(db,params,static_cast<IfcFaceBound*>(in));
133.4300 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcFaceOuterBound"); }	return base;
133.4301 +}
133.4302 +// -----------------------------------------------------------------------------------------------------------
133.4303 +template <> size_t GenericFill<IfcOneDirectionRepeatFactor>(const DB& db, const LIST& params, IfcOneDirectionRepeatFactor* in)
133.4304 +{
133.4305 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.4306 +// this data structure is not used yet, so there is no code generated to fill its members
133.4307 +	return base;
133.4308 +}
133.4309 +// -----------------------------------------------------------------------------------------------------------
133.4310 +template <> size_t GenericFill<IfcBoilerType>(const DB& db, const LIST& params, IfcBoilerType* in)
133.4311 +{
133.4312 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.4313 +// this data structure is not used yet, so there is no code generated to fill its members
133.4314 +	return base;
133.4315 +}
133.4316 +// -----------------------------------------------------------------------------------------------------------
133.4317 +template <> size_t GenericFill<IfcConstructionEquipmentResource>(const DB& db, const LIST& params, IfcConstructionEquipmentResource* in)
133.4318 +{
133.4319 +	size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in));
133.4320 +// this data structure is not used yet, so there is no code generated to fill its members
133.4321 +	return base;
133.4322 +}
133.4323 +// -----------------------------------------------------------------------------------------------------------
133.4324 +template <> size_t GenericFill<IfcComplexProperty>(const DB& db, const LIST& params, IfcComplexProperty* in)
133.4325 +{
133.4326 +	size_t base = GenericFill(db,params,static_cast<IfcProperty*>(in));
133.4327 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcComplexProperty"); }    do { // convert the 'UsageName' argument
133.4328 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4329 +        try { GenericConvert( in->UsageName, arg, db ); break; } 
133.4330 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcComplexProperty to be a `IfcIdentifier`")); }
133.4331 +    } while(0);
133.4332 +    do { // convert the 'HasProperties' argument
133.4333 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4334 +        try { GenericConvert( in->HasProperties, arg, db ); break; } 
133.4335 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcComplexProperty to be a `SET [1:?] OF IfcProperty`")); }
133.4336 +    } while(0);
133.4337 +	return base;
133.4338 +}
133.4339 +// -----------------------------------------------------------------------------------------------------------
133.4340 +template <> size_t GenericFill<IfcFooting>(const DB& db, const LIST& params, IfcFooting* in)
133.4341 +{
133.4342 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.4343 +// this data structure is not used yet, so there is no code generated to fill its members
133.4344 +	return base;
133.4345 +}
133.4346 +// -----------------------------------------------------------------------------------------------------------
133.4347 +template <> size_t GenericFill<IfcConstructionProductResource>(const DB& db, const LIST& params, IfcConstructionProductResource* in)
133.4348 +{
133.4349 +	size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in));
133.4350 +// this data structure is not used yet, so there is no code generated to fill its members
133.4351 +	return base;
133.4352 +}
133.4353 +// -----------------------------------------------------------------------------------------------------------
133.4354 +template <> size_t GenericFill<IfcDerivedProfileDef>(const DB& db, const LIST& params, IfcDerivedProfileDef* in)
133.4355 +{
133.4356 +	size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in));
133.4357 +// this data structure is not used yet, so there is no code generated to fill its members
133.4358 +	return base;
133.4359 +}
133.4360 +// -----------------------------------------------------------------------------------------------------------
133.4361 +template <> size_t GenericFill<IfcPropertyTableValue>(const DB& db, const LIST& params, IfcPropertyTableValue* in)
133.4362 +{
133.4363 +	size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in));
133.4364 +// this data structure is not used yet, so there is no code generated to fill its members
133.4365 +	return base;
133.4366 +}
133.4367 +// -----------------------------------------------------------------------------------------------------------
133.4368 +template <> size_t GenericFill<IfcFlowMeterType>(const DB& db, const LIST& params, IfcFlowMeterType* in)
133.4369 +{
133.4370 +	size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in));
133.4371 +// this data structure is not used yet, so there is no code generated to fill its members
133.4372 +	return base;
133.4373 +}
133.4374 +// -----------------------------------------------------------------------------------------------------------
133.4375 +template <> size_t GenericFill<IfcDoorStyle>(const DB& db, const LIST& params, IfcDoorStyle* in)
133.4376 +{
133.4377 +	size_t base = GenericFill(db,params,static_cast<IfcTypeProduct*>(in));
133.4378 +// this data structure is not used yet, so there is no code generated to fill its members
133.4379 +	return base;
133.4380 +}
133.4381 +// -----------------------------------------------------------------------------------------------------------
133.4382 +template <> size_t GenericFill<IfcUnitAssignment>(const DB& db, const LIST& params, IfcUnitAssignment* in)
133.4383 +{
133.4384 +	size_t base = 0;
133.4385 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcUnitAssignment"); }    do { // convert the 'Units' argument
133.4386 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4387 +        try { GenericConvert( in->Units, arg, db ); break; } 
133.4388 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcUnitAssignment to be a `SET [1:?] OF IfcUnit`")); }
133.4389 +    } while(0);
133.4390 +	return base;
133.4391 +}
133.4392 +// -----------------------------------------------------------------------------------------------------------
133.4393 +template <> size_t GenericFill<IfcFlowTerminal>(const DB& db, const LIST& params, IfcFlowTerminal* in)
133.4394 +{
133.4395 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in));
133.4396 +// this data structure is not used yet, so there is no code generated to fill its members
133.4397 +	return base;
133.4398 +}
133.4399 +// -----------------------------------------------------------------------------------------------------------
133.4400 +template <> size_t GenericFill<IfcCraneRailFShapeProfileDef>(const DB& db, const LIST& params, IfcCraneRailFShapeProfileDef* in)
133.4401 +{
133.4402 +	size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in));
133.4403 +// this data structure is not used yet, so there is no code generated to fill its members
133.4404 +	return base;
133.4405 +}
133.4406 +// -----------------------------------------------------------------------------------------------------------
133.4407 +template <> size_t GenericFill<IfcFlowSegment>(const DB& db, const LIST& params, IfcFlowSegment* in)
133.4408 +{
133.4409 +	size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in));
133.4410 +// this data structure is not used yet, so there is no code generated to fill its members
133.4411 +	return base;
133.4412 +}
133.4413 +// -----------------------------------------------------------------------------------------------------------
133.4414 +template <> size_t GenericFill<IfcElementQuantity>(const DB& db, const LIST& params, IfcElementQuantity* in)
133.4415 +{
133.4416 +	size_t base = GenericFill(db,params,static_cast<IfcPropertySetDefinition*>(in));
133.4417 +	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcElementQuantity"); }    do { // convert the 'MethodOfMeasurement' argument
133.4418 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4419 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.4420 +        try { GenericConvert( in->MethodOfMeasurement, arg, db ); break; } 
133.4421 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcElementQuantity to be a `IfcLabel`")); }
133.4422 +    } while(0);
133.4423 +    do { // convert the 'Quantities' argument
133.4424 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4425 +        try { GenericConvert( in->Quantities, arg, db ); break; } 
133.4426 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcElementQuantity to be a `SET [1:?] OF IfcPhysicalQuantity`")); }
133.4427 +    } while(0);
133.4428 +	return base;
133.4429 +}
133.4430 +// -----------------------------------------------------------------------------------------------------------
133.4431 +template <> size_t GenericFill<IfcCurtainWall>(const DB& db, const LIST& params, IfcCurtainWall* in)
133.4432 +{
133.4433 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.4434 +// this data structure is not used yet, so there is no code generated to fill its members
133.4435 +	return base;
133.4436 +}
133.4437 +// -----------------------------------------------------------------------------------------------------------
133.4438 +template <> size_t GenericFill<IfcDiscreteAccessory>(const DB& db, const LIST& params, IfcDiscreteAccessory* in)
133.4439 +{
133.4440 +	size_t base = GenericFill(db,params,static_cast<IfcElementComponent*>(in));
133.4441 +// this data structure is not used yet, so there is no code generated to fill its members
133.4442 +	return base;
133.4443 +}
133.4444 +// -----------------------------------------------------------------------------------------------------------
133.4445 +template <> size_t GenericFill<IfcGrid>(const DB& db, const LIST& params, IfcGrid* in)
133.4446 +{
133.4447 +	size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in));
133.4448 +// this data structure is not used yet, so there is no code generated to fill its members
133.4449 +	return base;
133.4450 +}
133.4451 +// -----------------------------------------------------------------------------------------------------------
133.4452 +template <> size_t GenericFill<IfcSanitaryTerminalType>(const DB& db, const LIST& params, IfcSanitaryTerminalType* in)
133.4453 +{
133.4454 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in));
133.4455 +// this data structure is not used yet, so there is no code generated to fill its members
133.4456 +	return base;
133.4457 +}
133.4458 +// -----------------------------------------------------------------------------------------------------------
133.4459 +template <> size_t GenericFill<IfcSubedge>(const DB& db, const LIST& params, IfcSubedge* in)
133.4460 +{
133.4461 +	size_t base = GenericFill(db,params,static_cast<IfcEdge*>(in));
133.4462 +// this data structure is not used yet, so there is no code generated to fill its members
133.4463 +	return base;
133.4464 +}
133.4465 +// -----------------------------------------------------------------------------------------------------------
133.4466 +template <> size_t GenericFill<IfcFilterType>(const DB& db, const LIST& params, IfcFilterType* in)
133.4467 +{
133.4468 +	size_t base = GenericFill(db,params,static_cast<IfcFlowTreatmentDeviceType*>(in));
133.4469 +// this data structure is not used yet, so there is no code generated to fill its members
133.4470 +	return base;
133.4471 +}
133.4472 +// -----------------------------------------------------------------------------------------------------------
133.4473 +template <> size_t GenericFill<IfcTendon>(const DB& db, const LIST& params, IfcTendon* in)
133.4474 +{
133.4475 +	size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in));
133.4476 +// this data structure is not used yet, so there is no code generated to fill its members
133.4477 +	return base;
133.4478 +}
133.4479 +// -----------------------------------------------------------------------------------------------------------
133.4480 +template <> size_t GenericFill<IfcStructuralLoadGroup>(const DB& db, const LIST& params, IfcStructuralLoadGroup* in)
133.4481 +{
133.4482 +	size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in));
133.4483 +// this data structure is not used yet, so there is no code generated to fill its members
133.4484 +	return base;
133.4485 +}
133.4486 +// -----------------------------------------------------------------------------------------------------------
133.4487 +template <> size_t GenericFill<IfcPresentationStyleAssignment>(const DB& db, const LIST& params, IfcPresentationStyleAssignment* in)
133.4488 +{
133.4489 +	size_t base = 0;
133.4490 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPresentationStyleAssignment"); }    do { // convert the 'Styles' argument
133.4491 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4492 +        try { GenericConvert( in->Styles, arg, db ); break; } 
133.4493 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPresentationStyleAssignment to be a `SET [1:?] OF IfcPresentationStyleSelect`")); }
133.4494 +    } while(0);
133.4495 +	return base;
133.4496 +}
133.4497 +// -----------------------------------------------------------------------------------------------------------
133.4498 +template <> size_t GenericFill<IfcStructuralCurveMember>(const DB& db, const LIST& params, IfcStructuralCurveMember* in)
133.4499 +{
133.4500 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralMember*>(in));
133.4501 +// this data structure is not used yet, so there is no code generated to fill its members
133.4502 +	return base;
133.4503 +}
133.4504 +// -----------------------------------------------------------------------------------------------------------
133.4505 +template <> size_t GenericFill<IfcLightSourceAmbient>(const DB& db, const LIST& params, IfcLightSourceAmbient* in)
133.4506 +{
133.4507 +	size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in));
133.4508 +// this data structure is not used yet, so there is no code generated to fill its members
133.4509 +	return base;
133.4510 +}
133.4511 +// -----------------------------------------------------------------------------------------------------------
133.4512 +template <> size_t GenericFill<IfcCondition>(const DB& db, const LIST& params, IfcCondition* in)
133.4513 +{
133.4514 +	size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in));
133.4515 +// this data structure is not used yet, so there is no code generated to fill its members
133.4516 +	return base;
133.4517 +}
133.4518 +// -----------------------------------------------------------------------------------------------------------
133.4519 +template <> size_t GenericFill<IfcPort>(const DB& db, const LIST& params, IfcPort* in)
133.4520 +{
133.4521 +	size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in));
133.4522 +// this data structure is not used yet, so there is no code generated to fill its members
133.4523 +	return base;
133.4524 +}
133.4525 +// -----------------------------------------------------------------------------------------------------------
133.4526 +template <> size_t GenericFill<IfcSpace>(const DB& db, const LIST& params, IfcSpace* in)
133.4527 +{
133.4528 +	size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in));
133.4529 +	if (params.GetSize() < 11) { throw STEP::TypeError("expected 11 arguments to IfcSpace"); }    do { // convert the 'InteriorOrExteriorSpace' argument
133.4530 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4531 +        try { GenericConvert( in->InteriorOrExteriorSpace, arg, db ); break; } 
133.4532 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcSpace to be a `IfcInternalOrExternalEnum`")); }
133.4533 +    } while(0);
133.4534 +    do { // convert the 'ElevationWithFlooring' argument
133.4535 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4536 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.4537 +        try { GenericConvert( in->ElevationWithFlooring, arg, db ); break; } 
133.4538 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcSpace to be a `IfcLengthMeasure`")); }
133.4539 +    } while(0);
133.4540 +	return base;
133.4541 +}
133.4542 +// -----------------------------------------------------------------------------------------------------------
133.4543 +template <> size_t GenericFill<IfcHeatExchangerType>(const DB& db, const LIST& params, IfcHeatExchangerType* in)
133.4544 +{
133.4545 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.4546 +// this data structure is not used yet, so there is no code generated to fill its members
133.4547 +	return base;
133.4548 +}
133.4549 +// -----------------------------------------------------------------------------------------------------------
133.4550 +template <> size_t GenericFill<IfcTankType>(const DB& db, const LIST& params, IfcTankType* in)
133.4551 +{
133.4552 +	size_t base = GenericFill(db,params,static_cast<IfcFlowStorageDeviceType*>(in));
133.4553 +// this data structure is not used yet, so there is no code generated to fill its members
133.4554 +	return base;
133.4555 +}
133.4556 +// -----------------------------------------------------------------------------------------------------------
133.4557 +template <> size_t GenericFill<IfcInventory>(const DB& db, const LIST& params, IfcInventory* in)
133.4558 +{
133.4559 +	size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in));
133.4560 +// this data structure is not used yet, so there is no code generated to fill its members
133.4561 +	return base;
133.4562 +}
133.4563 +// -----------------------------------------------------------------------------------------------------------
133.4564 +template <> size_t GenericFill<IfcTransportElementType>(const DB& db, const LIST& params, IfcTransportElementType* in)
133.4565 +{
133.4566 +	size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in));
133.4567 +// this data structure is not used yet, so there is no code generated to fill its members
133.4568 +	return base;
133.4569 +}
133.4570 +// -----------------------------------------------------------------------------------------------------------
133.4571 +template <> size_t GenericFill<IfcAirToAirHeatRecoveryType>(const DB& db, const LIST& params, IfcAirToAirHeatRecoveryType* in)
133.4572 +{
133.4573 +	size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in));
133.4574 +// this data structure is not used yet, so there is no code generated to fill its members
133.4575 +	return base;
133.4576 +}
133.4577 +// -----------------------------------------------------------------------------------------------------------
133.4578 +template <> size_t GenericFill<IfcStairFlight>(const DB& db, const LIST& params, IfcStairFlight* in)
133.4579 +{
133.4580 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.4581 +// this data structure is not used yet, so there is no code generated to fill its members
133.4582 +	return base;
133.4583 +}
133.4584 +// -----------------------------------------------------------------------------------------------------------
133.4585 +template <> size_t GenericFill<IfcElectricalElement>(const DB& db, const LIST& params, IfcElectricalElement* in)
133.4586 +{
133.4587 +	size_t base = GenericFill(db,params,static_cast<IfcElement*>(in));
133.4588 +// this data structure is not used yet, so there is no code generated to fill its members
133.4589 +	return base;
133.4590 +}
133.4591 +// -----------------------------------------------------------------------------------------------------------
133.4592 +template <> size_t GenericFill<IfcSurfaceStyleWithTextures>(const DB& db, const LIST& params, IfcSurfaceStyleWithTextures* in)
133.4593 +{
133.4594 +	size_t base = 0;
133.4595 +	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleWithTextures"); }    do { // convert the 'Textures' argument
133.4596 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4597 +        try { GenericConvert( in->Textures, arg, db ); break; } 
133.4598 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSurfaceStyleWithTextures to be a `LIST [1:?] OF IfcSurfaceTexture`")); }
133.4599 +    } while(0);
133.4600 +	return base;
133.4601 +}
133.4602 +// -----------------------------------------------------------------------------------------------------------
133.4603 +template <> size_t GenericFill<IfcBoundingBox>(const DB& db, const LIST& params, IfcBoundingBox* in)
133.4604 +{
133.4605 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.4606 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcBoundingBox"); }    do { // convert the 'Corner' argument
133.4607 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4608 +        try { GenericConvert( in->Corner, arg, db ); break; } 
133.4609 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBoundingBox to be a `IfcCartesianPoint`")); }
133.4610 +    } while(0);
133.4611 +    do { // convert the 'XDim' argument
133.4612 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4613 +        try { GenericConvert( in->XDim, arg, db ); break; } 
133.4614 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); }
133.4615 +    } while(0);
133.4616 +    do { // convert the 'YDim' argument
133.4617 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4618 +        try { GenericConvert( in->YDim, arg, db ); break; } 
133.4619 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); }
133.4620 +    } while(0);
133.4621 +    do { // convert the 'ZDim' argument
133.4622 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4623 +        try { GenericConvert( in->ZDim, arg, db ); break; } 
133.4624 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); }
133.4625 +    } while(0);
133.4626 +	return base;
133.4627 +}
133.4628 +// -----------------------------------------------------------------------------------------------------------
133.4629 +template <> size_t GenericFill<IfcWallType>(const DB& db, const LIST& params, IfcWallType* in)
133.4630 +{
133.4631 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.4632 +// this data structure is not used yet, so there is no code generated to fill its members
133.4633 +	return base;
133.4634 +}
133.4635 +// -----------------------------------------------------------------------------------------------------------
133.4636 +template <> size_t GenericFill<IfcMove>(const DB& db, const LIST& params, IfcMove* in)
133.4637 +{
133.4638 +	size_t base = GenericFill(db,params,static_cast<IfcTask*>(in));
133.4639 +// this data structure is not used yet, so there is no code generated to fill its members
133.4640 +	return base;
133.4641 +}
133.4642 +// -----------------------------------------------------------------------------------------------------------
133.4643 +template <> size_t GenericFill<IfcCircle>(const DB& db, const LIST& params, IfcCircle* in)
133.4644 +{
133.4645 +	size_t base = GenericFill(db,params,static_cast<IfcConic*>(in));
133.4646 +	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcCircle"); }    do { // convert the 'Radius' argument
133.4647 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4648 +        try { GenericConvert( in->Radius, arg, db ); break; } 
133.4649 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCircle to be a `IfcPositiveLengthMeasure`")); }
133.4650 +    } while(0);
133.4651 +	return base;
133.4652 +}
133.4653 +// -----------------------------------------------------------------------------------------------------------
133.4654 +template <> size_t GenericFill<IfcOffsetCurve2D>(const DB& db, const LIST& params, IfcOffsetCurve2D* in)
133.4655 +{
133.4656 +	size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in));
133.4657 +// this data structure is not used yet, so there is no code generated to fill its members
133.4658 +	return base;
133.4659 +}
133.4660 +// -----------------------------------------------------------------------------------------------------------
133.4661 +template <> size_t GenericFill<IfcPointOnCurve>(const DB& db, const LIST& params, IfcPointOnCurve* in)
133.4662 +{
133.4663 +	size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in));
133.4664 +// this data structure is not used yet, so there is no code generated to fill its members
133.4665 +	return base;
133.4666 +}
133.4667 +// -----------------------------------------------------------------------------------------------------------
133.4668 +template <> size_t GenericFill<IfcStructuralResultGroup>(const DB& db, const LIST& params, IfcStructuralResultGroup* in)
133.4669 +{
133.4670 +	size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in));
133.4671 +// this data structure is not used yet, so there is no code generated to fill its members
133.4672 +	return base;
133.4673 +}
133.4674 +// -----------------------------------------------------------------------------------------------------------
133.4675 +template <> size_t GenericFill<IfcSectionedSpine>(const DB& db, const LIST& params, IfcSectionedSpine* in)
133.4676 +{
133.4677 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.4678 +// this data structure is not used yet, so there is no code generated to fill its members
133.4679 +	return base;
133.4680 +}
133.4681 +// -----------------------------------------------------------------------------------------------------------
133.4682 +template <> size_t GenericFill<IfcSlab>(const DB& db, const LIST& params, IfcSlab* in)
133.4683 +{
133.4684 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in));
133.4685 +// this data structure is not used yet, so there is no code generated to fill its members
133.4686 +	return base;
133.4687 +}
133.4688 +// -----------------------------------------------------------------------------------------------------------
133.4689 +template <> size_t GenericFill<IfcVertex>(const DB& db, const LIST& params, IfcVertex* in)
133.4690 +{
133.4691 +	size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in));
133.4692 +// this data structure is not used yet, so there is no code generated to fill its members
133.4693 +	return base;
133.4694 +}
133.4695 +// -----------------------------------------------------------------------------------------------------------
133.4696 +template <> size_t GenericFill<IfcVertexPoint>(const DB& db, const LIST& params, IfcVertexPoint* in)
133.4697 +{
133.4698 +	size_t base = GenericFill(db,params,static_cast<IfcVertex*>(in));
133.4699 +// this data structure is not used yet, so there is no code generated to fill its members
133.4700 +	return base;
133.4701 +}
133.4702 +// -----------------------------------------------------------------------------------------------------------
133.4703 +template <> size_t GenericFill<IfcStructuralLinearAction>(const DB& db, const LIST& params, IfcStructuralLinearAction* in)
133.4704 +{
133.4705 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralAction*>(in));
133.4706 +// this data structure is not used yet, so there is no code generated to fill its members
133.4707 +	return base;
133.4708 +}
133.4709 +// -----------------------------------------------------------------------------------------------------------
133.4710 +template <> size_t GenericFill<IfcStructuralLinearActionVarying>(const DB& db, const LIST& params, IfcStructuralLinearActionVarying* in)
133.4711 +{
133.4712 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralLinearAction*>(in));
133.4713 +// this data structure is not used yet, so there is no code generated to fill its members
133.4714 +	return base;
133.4715 +}
133.4716 +// -----------------------------------------------------------------------------------------------------------
133.4717 +template <> size_t GenericFill<IfcBuildingElementProxyType>(const DB& db, const LIST& params, IfcBuildingElementProxyType* in)
133.4718 +{
133.4719 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.4720 +// this data structure is not used yet, so there is no code generated to fill its members
133.4721 +	return base;
133.4722 +}
133.4723 +// -----------------------------------------------------------------------------------------------------------
133.4724 +template <> size_t GenericFill<IfcProjectionElement>(const DB& db, const LIST& params, IfcProjectionElement* in)
133.4725 +{
133.4726 +	size_t base = GenericFill(db,params,static_cast<IfcFeatureElementAddition*>(in));
133.4727 +// this data structure is not used yet, so there is no code generated to fill its members
133.4728 +	return base;
133.4729 +}
133.4730 +// -----------------------------------------------------------------------------------------------------------
133.4731 +template <> size_t GenericFill<IfcConversionBasedUnit>(const DB& db, const LIST& params, IfcConversionBasedUnit* in)
133.4732 +{
133.4733 +	size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in));
133.4734 +	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcConversionBasedUnit"); }    do { // convert the 'Name' argument
133.4735 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4736 +        try { GenericConvert( in->Name, arg, db ); break; } 
133.4737 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcConversionBasedUnit to be a `IfcLabel`")); }
133.4738 +    } while(0);
133.4739 +    do { // convert the 'ConversionFactor' argument
133.4740 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4741 +        try { GenericConvert( in->ConversionFactor, arg, db ); break; } 
133.4742 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcConversionBasedUnit to be a `IfcMeasureWithUnit`")); }
133.4743 +    } while(0);
133.4744 +	return base;
133.4745 +}
133.4746 +// -----------------------------------------------------------------------------------------------------------
133.4747 +template <> size_t GenericFill<IfcGeometricRepresentationSubContext>(const DB& db, const LIST& params, IfcGeometricRepresentationSubContext* in)
133.4748 +{
133.4749 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationContext*>(in));
133.4750 +// this data structure is not used yet, so there is no code generated to fill its members
133.4751 +	return base;
133.4752 +}
133.4753 +// -----------------------------------------------------------------------------------------------------------
133.4754 +template <> size_t GenericFill<IfcAnnotationSurfaceOccurrence>(const DB& db, const LIST& params, IfcAnnotationSurfaceOccurrence* in)
133.4755 +{
133.4756 +	size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in));
133.4757 +// this data structure is not used yet, so there is no code generated to fill its members
133.4758 +	return base;
133.4759 +}
133.4760 +// -----------------------------------------------------------------------------------------------------------
133.4761 +template <> size_t GenericFill<IfcRoundedEdgeFeature>(const DB& db, const LIST& params, IfcRoundedEdgeFeature* in)
133.4762 +{
133.4763 +	size_t base = GenericFill(db,params,static_cast<IfcEdgeFeature*>(in));
133.4764 +// this data structure is not used yet, so there is no code generated to fill its members
133.4765 +	return base;
133.4766 +}
133.4767 +// -----------------------------------------------------------------------------------------------------------
133.4768 +template <> size_t GenericFill<IfcElectricDistributionPoint>(const DB& db, const LIST& params, IfcElectricDistributionPoint* in)
133.4769 +{
133.4770 +	size_t base = GenericFill(db,params,static_cast<IfcFlowController*>(in));
133.4771 +// this data structure is not used yet, so there is no code generated to fill its members
133.4772 +	return base;
133.4773 +}
133.4774 +// -----------------------------------------------------------------------------------------------------------
133.4775 +template <> size_t GenericFill<IfcCableCarrierSegmentType>(const DB& db, const LIST& params, IfcCableCarrierSegmentType* in)
133.4776 +{
133.4777 +	size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in));
133.4778 +// this data structure is not used yet, so there is no code generated to fill its members
133.4779 +	return base;
133.4780 +}
133.4781 +// -----------------------------------------------------------------------------------------------------------
133.4782 +template <> size_t GenericFill<IfcWallStandardCase>(const DB& db, const LIST& params, IfcWallStandardCase* in)
133.4783 +{
133.4784 +	size_t base = GenericFill(db,params,static_cast<IfcWall*>(in));
133.4785 +// this data structure is not used yet, so there is no code generated to fill its members
133.4786 +	return base;
133.4787 +}
133.4788 +// -----------------------------------------------------------------------------------------------------------
133.4789 +template <> size_t GenericFill<IfcCsgSolid>(const DB& db, const LIST& params, IfcCsgSolid* in)
133.4790 +{
133.4791 +	size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in));
133.4792 +// this data structure is not used yet, so there is no code generated to fill its members
133.4793 +	return base;
133.4794 +}
133.4795 +// -----------------------------------------------------------------------------------------------------------
133.4796 +template <> size_t GenericFill<IfcBeamType>(const DB& db, const LIST& params, IfcBeamType* in)
133.4797 +{
133.4798 +	size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in));
133.4799 +// this data structure is not used yet, so there is no code generated to fill its members
133.4800 +	return base;
133.4801 +}
133.4802 +// -----------------------------------------------------------------------------------------------------------
133.4803 +template <> size_t GenericFill<IfcAnnotationFillArea>(const DB& db, const LIST& params, IfcAnnotationFillArea* in)
133.4804 +{
133.4805 +	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
133.4806 +// this data structure is not used yet, so there is no code generated to fill its members
133.4807 +	return base;
133.4808 +}
133.4809 +// -----------------------------------------------------------------------------------------------------------
133.4810 +template <> size_t GenericFill<IfcStructuralCurveMemberVarying>(const DB& db, const LIST& params, IfcStructuralCurveMemberVarying* in)
133.4811 +{
133.4812 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralCurveMember*>(in));
133.4813 +// this data structure is not used yet, so there is no code generated to fill its members
133.4814 +	return base;
133.4815 +}
133.4816 +// -----------------------------------------------------------------------------------------------------------
133.4817 +template <> size_t GenericFill<IfcPointOnSurface>(const DB& db, const LIST& params, IfcPointOnSurface* in)
133.4818 +{
133.4819 +	size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in));
133.4820 +// this data structure is not used yet, so there is no code generated to fill its members
133.4821 +	return base;
133.4822 +}
133.4823 +// -----------------------------------------------------------------------------------------------------------
133.4824 +template <> size_t GenericFill<IfcOrderAction>(const DB& db, const LIST& params, IfcOrderAction* in)
133.4825 +{
133.4826 +	size_t base = GenericFill(db,params,static_cast<IfcTask*>(in));
133.4827 +// this data structure is not used yet, so there is no code generated to fill its members
133.4828 +	return base;
133.4829 +}
133.4830 +// -----------------------------------------------------------------------------------------------------------
133.4831 +template <> size_t GenericFill<IfcEdgeLoop>(const DB& db, const LIST& params, IfcEdgeLoop* in)
133.4832 +{
133.4833 +	size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in));
133.4834 +// this data structure is not used yet, so there is no code generated to fill its members
133.4835 +	return base;
133.4836 +}
133.4837 +// -----------------------------------------------------------------------------------------------------------
133.4838 +template <> size_t GenericFill<IfcAnnotationFillAreaOccurrence>(const DB& db, const LIST& params, IfcAnnotationFillAreaOccurrence* in)
133.4839 +{
133.4840 +	size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in));
133.4841 +// this data structure is not used yet, so there is no code generated to fill its members
133.4842 +	return base;
133.4843 +}
133.4844 +// -----------------------------------------------------------------------------------------------------------
133.4845 +template <> size_t GenericFill<IfcWorkPlan>(const DB& db, const LIST& params, IfcWorkPlan* in)
133.4846 +{
133.4847 +	size_t base = GenericFill(db,params,static_cast<IfcWorkControl*>(in));
133.4848 +// this data structure is not used yet, so there is no code generated to fill its members
133.4849 +	return base;
133.4850 +}
133.4851 +// -----------------------------------------------------------------------------------------------------------
133.4852 +template <> size_t GenericFill<IfcEllipse>(const DB& db, const LIST& params, IfcEllipse* in)
133.4853 +{
133.4854 +	size_t base = GenericFill(db,params,static_cast<IfcConic*>(in));
133.4855 +	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcEllipse"); }    do { // convert the 'SemiAxis1' argument
133.4856 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4857 +        try { GenericConvert( in->SemiAxis1, arg, db ); break; } 
133.4858 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcEllipse to be a `IfcPositiveLengthMeasure`")); }
133.4859 +    } while(0);
133.4860 +    do { // convert the 'SemiAxis2' argument
133.4861 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4862 +        try { GenericConvert( in->SemiAxis2, arg, db ); break; } 
133.4863 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcEllipse to be a `IfcPositiveLengthMeasure`")); }
133.4864 +    } while(0);
133.4865 +	return base;
133.4866 +}
133.4867 +// -----------------------------------------------------------------------------------------------------------
133.4868 +template <> size_t GenericFill<IfcProductDefinitionShape>(const DB& db, const LIST& params, IfcProductDefinitionShape* in)
133.4869 +{
133.4870 +	size_t base = GenericFill(db,params,static_cast<IfcProductRepresentation*>(in));
133.4871 +// this data structure is not used yet, so there is no code generated to fill its members
133.4872 +	return base;
133.4873 +}
133.4874 +// -----------------------------------------------------------------------------------------------------------
133.4875 +template <> size_t GenericFill<IfcProjectionCurve>(const DB& db, const LIST& params, IfcProjectionCurve* in)
133.4876 +{
133.4877 +	size_t base = GenericFill(db,params,static_cast<IfcAnnotationCurveOccurrence*>(in));
133.4878 +// this data structure is not used yet, so there is no code generated to fill its members
133.4879 +	return base;
133.4880 +}
133.4881 +// -----------------------------------------------------------------------------------------------------------
133.4882 +template <> size_t GenericFill<IfcElectricalCircuit>(const DB& db, const LIST& params, IfcElectricalCircuit* in)
133.4883 +{
133.4884 +	size_t base = GenericFill(db,params,static_cast<IfcSystem*>(in));
133.4885 +// this data structure is not used yet, so there is no code generated to fill its members
133.4886 +	return base;
133.4887 +}
133.4888 +// -----------------------------------------------------------------------------------------------------------
133.4889 +template <> size_t GenericFill<IfcRationalBezierCurve>(const DB& db, const LIST& params, IfcRationalBezierCurve* in)
133.4890 +{
133.4891 +	size_t base = GenericFill(db,params,static_cast<IfcBezierCurve*>(in));
133.4892 +// this data structure is not used yet, so there is no code generated to fill its members
133.4893 +	return base;
133.4894 +}
133.4895 +// -----------------------------------------------------------------------------------------------------------
133.4896 +template <> size_t GenericFill<IfcStructuralPointAction>(const DB& db, const LIST& params, IfcStructuralPointAction* in)
133.4897 +{
133.4898 +	size_t base = GenericFill(db,params,static_cast<IfcStructuralAction*>(in));
133.4899 +// this data structure is not used yet, so there is no code generated to fill its members
133.4900 +	return base;
133.4901 +}
133.4902 +// -----------------------------------------------------------------------------------------------------------
133.4903 +template <> size_t GenericFill<IfcPipeSegmentType>(const DB& db, const LIST& params, IfcPipeSegmentType* in)
133.4904 +{
133.4905 +	size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in));
133.4906 +// this data structure is not used yet, so there is no code generated to fill its members
133.4907 +	return base;
133.4908 +}
133.4909 +// -----------------------------------------------------------------------------------------------------------
133.4910 +template <> size_t GenericFill<IfcTwoDirectionRepeatFactor>(const DB& db, const LIST& params, IfcTwoDirectionRepeatFactor* in)
133.4911 +{
133.4912 +	size_t base = GenericFill(db,params,static_cast<IfcOneDirectionRepeatFactor*>(in));
133.4913 +// this data structure is not used yet, so there is no code generated to fill its members
133.4914 +	return base;
133.4915 +}
133.4916 +// -----------------------------------------------------------------------------------------------------------
133.4917 +template <> size_t GenericFill<IfcShapeRepresentation>(const DB& db, const LIST& params, IfcShapeRepresentation* in)
133.4918 +{
133.4919 +	size_t base = GenericFill(db,params,static_cast<IfcShapeModel*>(in));
133.4920 +// this data structure is not used yet, so there is no code generated to fill its members
133.4921 +	return base;
133.4922 +}
133.4923 +// -----------------------------------------------------------------------------------------------------------
133.4924 +template <> size_t GenericFill<IfcPropertySet>(const DB& db, const LIST& params, IfcPropertySet* in)
133.4925 +{
133.4926 +	size_t base = GenericFill(db,params,static_cast<IfcPropertySetDefinition*>(in));
133.4927 +	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcPropertySet"); }    do { // convert the 'HasProperties' argument
133.4928 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4929 +        try { GenericConvert( in->HasProperties, arg, db ); break; } 
133.4930 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcPropertySet to be a `SET [1:?] OF IfcProperty`")); }
133.4931 +    } while(0);
133.4932 +	return base;
133.4933 +}
133.4934 +// -----------------------------------------------------------------------------------------------------------
133.4935 +template <> size_t GenericFill<IfcSurfaceStyleRendering>(const DB& db, const LIST& params, IfcSurfaceStyleRendering* in)
133.4936 +{
133.4937 +	size_t base = GenericFill(db,params,static_cast<IfcSurfaceStyleShading*>(in));
133.4938 +	if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcSurfaceStyleRendering"); }    do { // convert the 'Transparency' argument
133.4939 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4940 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.4941 +        try { GenericConvert( in->Transparency, arg, db ); break; } 
133.4942 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSurfaceStyleRendering to be a `IfcNormalisedRatioMeasure`")); }
133.4943 +    } while(0);
133.4944 +    do { // convert the 'DiffuseColour' argument
133.4945 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4946 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.4947 +        try { GenericConvert( in->DiffuseColour, arg, db ); break; } 
133.4948 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
133.4949 +    } while(0);
133.4950 +    do { // convert the 'TransmissionColour' argument
133.4951 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4952 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.4953 +        try { GenericConvert( in->TransmissionColour, arg, db ); break; } 
133.4954 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
133.4955 +    } while(0);
133.4956 +    do { // convert the 'DiffuseTransmissionColour' argument
133.4957 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4958 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.4959 +        try { GenericConvert( in->DiffuseTransmissionColour, arg, db ); break; } 
133.4960 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
133.4961 +    } while(0);
133.4962 +    do { // convert the 'ReflectionColour' argument
133.4963 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4964 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.4965 +        try { GenericConvert( in->ReflectionColour, arg, db ); break; } 
133.4966 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
133.4967 +    } while(0);
133.4968 +    do { // convert the 'SpecularColour' argument
133.4969 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4970 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.4971 +        try { GenericConvert( in->SpecularColour, arg, db ); break; } 
133.4972 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
133.4973 +    } while(0);
133.4974 +    do { // convert the 'SpecularHighlight' argument
133.4975 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4976 +        if (dynamic_cast<const UNSET*>(&*arg)) break;
133.4977 +        try { GenericConvert( in->SpecularHighlight, arg, db ); break; } 
133.4978 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcSurfaceStyleRendering to be a `IfcSpecularHighlightSelect`")); }
133.4979 +    } while(0);
133.4980 +    do { // convert the 'ReflectanceMethod' argument
133.4981 +        boost::shared_ptr<const DataType> arg = params[base++];
133.4982 +        try { GenericConvert( in->ReflectanceMethod, arg, db ); break; } 
133.4983 +        catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSurfaceStyleRendering to be a `IfcReflectanceMethodEnum`")); }
133.4984 +    } while(0);
133.4985 +	return base;
133.4986 +}
133.4987 +// -----------------------------------------------------------------------------------------------------------
133.4988 +template <> size_t GenericFill<IfcDistributionPort>(const DB& db, const LIST& params, IfcDistributionPort* in)
133.4989 +{
133.4990 +	size_t base = GenericFill(db,params,static_cast<IfcPort*>(in));
133.4991 +// this data structure is not used yet, so there is no code generated to fill its members
133.4992 +	return base;
133.4993 +}
133.4994 +// -----------------------------------------------------------------------------------------------------------
133.4995 +template <> size_t GenericFill<IfcPipeFittingType>(const DB& db, const LIST& params, IfcPipeFittingType* in)
133.4996 +{
133.4997 +	size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in));
133.4998 +// this data structure is not used yet, so there is no code generated to fill its members
133.4999 +	return base;
133.5000 +}
133.5001 +// -----------------------------------------------------------------------------------------------------------
133.5002 +template <> size_t GenericFill<IfcTransportElement>(const DB& db, const LIST& params, IfcTransportElement* in)
133.5003 +{
133.5004 +	size_t base = GenericFill(db,params,static_cast<IfcElement*>(in));
133.5005 +// this data structure is not used yet, so there is no code generated to fill its members
133.5006 +	return base;
133.5007 +}
133.5008 +// -----------------------------------------------------------------------------------------------------------
133.5009 +template <> size_t GenericFill<IfcAnnotationTextOccurrence>(const DB& db, const LIST& params, IfcAnnotationTextOccurrence* in)
133.5010 +{
133.5011 +	size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in));
133.5012 +// this data structure is not used yet, so there is no code generated to fill its members
133.5013 +	return base;
133.5014 +}
133.5015 +// -----------------------------------------------------------------------------------------------------------
133.5016 +template <> size_t GenericFill<IfcStructuralAnalysisModel>(const DB& db, const LIST& params, IfcStructuralAnalysisModel* in)
133.5017 +{
133.5018 +	size_t base = GenericFill(db,params,static_cast<IfcSystem*>(in));
133.5019 +// this data structure is not used yet, so there is no code generated to fill its members
133.5020 +	return base;
133.5021 +}
133.5022 +// -----------------------------------------------------------------------------------------------------------
133.5023 +template <> size_t GenericFill<IfcConditionCriterion>(const DB& db, const LIST& params, IfcConditionCriterion* in)
133.5024 +{
133.5025 +	size_t base = GenericFill(db,params,static_cast<IfcControl*>(in));
133.5026 +// this data structure is not used yet, so there is no code generated to fill its members
133.5027 +	return base;
133.5028 +}
133.5029 +
133.5030 +} // ! STEP
133.5031 +} // ! Assimp
133.5032 +
133.5033 +#endif
   134.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   134.2 +++ b/libs/assimp/IFCReaderGen.h	Sat Feb 01 19:58:19 2014 +0200
   134.3 @@ -0,0 +1,4368 @@
   134.4 +/*
   134.5 +Open Asset Import Library (ASSIMP)
   134.6 +----------------------------------------------------------------------
   134.7 +
   134.8 +Copyright (c) 2006-2010, ASSIMP Development Team
   134.9 +All rights reserved.
  134.10 +
  134.11 +Redistribution and use of this software in source and binary forms, 
  134.12 +with or without modification, are permitted provided that the 
  134.13 +following conditions are met:
  134.14 +
  134.15 +* Redistributions of source code must retain the above
  134.16 +  copyright notice, this list of conditions and the
  134.17 +  following disclaimer.
  134.18 +
  134.19 +* Redistributions in binary form must reproduce the above
  134.20 +  copyright notice, this list of conditions and the
  134.21 +  following disclaimer in the documentation and/or other
  134.22 +  materials provided with the distribution.
  134.23 +
  134.24 +* Neither the name of the ASSIMP team, nor the names of its
  134.25 +  contributors may be used to endorse or promote products
  134.26 +  derived from this software without specific prior
  134.27 +  written permission of the ASSIMP Development Team.
  134.28 +
  134.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  134.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  134.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  134.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  134.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  134.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  134.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  134.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  134.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  134.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  134.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  134.40 +
  134.41 +----------------------------------------------------------------------
  134.42 +*/
  134.43 +
  134.44 +/** MACHINE-GENERATED by scripts/ICFImporter/CppGenerator.py */
  134.45 +
  134.46 +#ifndef INCLUDED_IFC_READER_GEN_H
  134.47 +#define INCLUDED_IFC_READER_GEN_H
  134.48 +
  134.49 +#include "STEPFile.h"
  134.50 +
  134.51 +namespace Assimp {
  134.52 +namespace IFC {
  134.53 +	using namespace STEP;
  134.54 +	using namespace STEP::EXPRESS;
  134.55 +	
  134.56 +	
  134.57 +	struct NotImplemented : public ObjectHelper<NotImplemented,0> {
  134.58 +		
  134.59 +	};
  134.60 +	
  134.61 +
  134.62 +	// ******************************************************************************
  134.63 +	// IFC Custom data types
  134.64 +	// ******************************************************************************
  134.65 +
  134.66 +
  134.67 +    // C++ wrapper type for IfcStairTypeEnum
  134.68 +    typedef ENUMERATION IfcStairTypeEnum;
  134.69 +    // C++ wrapper type for IfcSpaceTypeEnum
  134.70 +    typedef ENUMERATION IfcSpaceTypeEnum;
  134.71 +    // C++ wrapper type for IfcWallTypeEnum
  134.72 +    typedef ENUMERATION IfcWallTypeEnum;
  134.73 +    // C++ wrapper type for IfcMonthInYearNumber
  134.74 +    typedef INTEGER IfcMonthInYearNumber;
  134.75 +    // C++ wrapper type for IfcHeatFluxDensityMeasure
  134.76 +    typedef REAL IfcHeatFluxDensityMeasure;
  134.77 +    // C++ wrapper type for IfcKinematicViscosityMeasure
  134.78 +    typedef REAL IfcKinematicViscosityMeasure;
  134.79 +    // C++ wrapper type for IfcSequenceEnum
  134.80 +    typedef ENUMERATION IfcSequenceEnum;
  134.81 +    // C++ wrapper type for IfcAirToAirHeatRecoveryTypeEnum
  134.82 +    typedef ENUMERATION IfcAirToAirHeatRecoveryTypeEnum;
  134.83 +    // C++ wrapper type for IfcActorSelect
  134.84 +    typedef SELECT IfcActorSelect;
  134.85 +    // C++ wrapper type for IfcTransformerTypeEnum
  134.86 +    typedef ENUMERATION IfcTransformerTypeEnum;
  134.87 +    // C++ wrapper type for IfcUnitaryEquipmentTypeEnum
  134.88 +    typedef ENUMERATION IfcUnitaryEquipmentTypeEnum;
  134.89 +    // C++ wrapper type for IfcElectricFlowStorageDeviceTypeEnum
  134.90 +    typedef ENUMERATION IfcElectricFlowStorageDeviceTypeEnum;
  134.91 +    // C++ wrapper type for IfcEnergySequenceEnum
  134.92 +    typedef ENUMERATION IfcEnergySequenceEnum;
  134.93 +    // C++ wrapper type for IfcWorkControlTypeEnum
  134.94 +    typedef ENUMERATION IfcWorkControlTypeEnum;
  134.95 +    // C++ wrapper type for IfcCurvatureMeasure
  134.96 +    typedef REAL IfcCurvatureMeasure;
  134.97 +    // C++ wrapper type for IfcParameterValue
  134.98 +    typedef REAL IfcParameterValue;
  134.99 +    // C++ wrapper type for IfcAppliedValueSelect
 134.100 +    typedef SELECT IfcAppliedValueSelect;
 134.101 +    // C++ wrapper type for IfcWarpingConstantMeasure
 134.102 +    typedef REAL IfcWarpingConstantMeasure;
 134.103 +    // C++ wrapper type for IfcArithmeticOperatorEnum
 134.104 +    typedef ENUMERATION IfcArithmeticOperatorEnum;
 134.105 +    // C++ wrapper type for IfcLinearForceMeasure
 134.106 +    typedef REAL IfcLinearForceMeasure;
 134.107 +    // C++ wrapper type for IfcWindowPanelPositionEnum
 134.108 +    typedef ENUMERATION IfcWindowPanelPositionEnum;
 134.109 +    // C++ wrapper type for IfcFlowMeterTypeEnum
 134.110 +    typedef ENUMERATION IfcFlowMeterTypeEnum;
 134.111 +    // C++ wrapper type for IfcRampFlightTypeEnum
 134.112 +    typedef ENUMERATION IfcRampFlightTypeEnum;
 134.113 +    // C++ wrapper type for IfcSpecularHighlightSelect
 134.114 +    typedef SELECT IfcSpecularHighlightSelect;
 134.115 +    // C++ wrapper type for IfcActionTypeEnum
 134.116 +    typedef ENUMERATION IfcActionTypeEnum;
 134.117 +    // C++ wrapper type for IfcGeometricProjectionEnum
 134.118 +    typedef ENUMERATION IfcGeometricProjectionEnum;
 134.119 +    // C++ wrapper type for IfcTimeSeriesDataTypeEnum
 134.120 +    typedef ENUMERATION IfcTimeSeriesDataTypeEnum;
 134.121 +    // C++ wrapper type for IfcMagneticFluxMeasure
 134.122 +    typedef REAL IfcMagneticFluxMeasure;
 134.123 +    // C++ wrapper type for IfcObjectTypeEnum
 134.124 +    typedef ENUMERATION IfcObjectTypeEnum;
 134.125 +    // C++ wrapper type for IfcDataOriginEnum
 134.126 +    typedef ENUMERATION IfcDataOriginEnum;
 134.127 +    // C++ wrapper type for IfcMassDensityMeasure
 134.128 +    typedef REAL IfcMassDensityMeasure;
 134.129 +    // C++ wrapper type for IfcLightFixtureTypeEnum
 134.130 +    typedef ENUMERATION IfcLightFixtureTypeEnum;
 134.131 +    // C++ wrapper type for IfcServiceLifeTypeEnum
 134.132 +    typedef ENUMERATION IfcServiceLifeTypeEnum;
 134.133 +    // C++ wrapper type for IfcElectricVoltageMeasure
 134.134 +    typedef REAL IfcElectricVoltageMeasure;
 134.135 +    // C++ wrapper type for IfcHeatingValueMeasure
 134.136 +    typedef REAL IfcHeatingValueMeasure;
 134.137 +    // C++ wrapper type for IfcPresentableText
 134.138 +    typedef STRING IfcPresentableText;
 134.139 +    // C++ wrapper type for IfcAheadOrBehind
 134.140 +    typedef ENUMERATION IfcAheadOrBehind;
 134.141 +    // C++ wrapper type for IfcSimpleValue
 134.142 +    typedef SELECT IfcSimpleValue;
 134.143 +    // C++ wrapper type for IfcSensorTypeEnum
 134.144 +    typedef ENUMERATION IfcSensorTypeEnum;
 134.145 +    // C++ wrapper type for IfcDerivedUnitEnum
 134.146 +    typedef ENUMERATION IfcDerivedUnitEnum;
 134.147 +    // C++ wrapper type for IfcSizeSelect
 134.148 +    typedef SELECT IfcSizeSelect;
 134.149 +    // C++ wrapper type for IfcTransportElementTypeEnum
 134.150 +    typedef ENUMERATION IfcTransportElementTypeEnum;
 134.151 +    // C++ wrapper type for IfcInventoryTypeEnum
 134.152 +    typedef ENUMERATION IfcInventoryTypeEnum;
 134.153 +    // C++ wrapper type for IfcTextDecoration
 134.154 +    typedef STRING IfcTextDecoration;
 134.155 +    // C++ wrapper type for IfcDirectionSenseEnum
 134.156 +    typedef ENUMERATION IfcDirectionSenseEnum;
 134.157 +    // C++ wrapper type for IfcDuctFittingTypeEnum
 134.158 +    typedef ENUMERATION IfcDuctFittingTypeEnum;
 134.159 +    // C++ wrapper type for IfcDocumentStatusEnum
 134.160 +    typedef ENUMERATION IfcDocumentStatusEnum;
 134.161 +    // C++ wrapper type for IfcSlabTypeEnum
 134.162 +    typedef ENUMERATION IfcSlabTypeEnum;
 134.163 +    // C++ wrapper type for IfcDoorStyleConstructionEnum
 134.164 +    typedef ENUMERATION IfcDoorStyleConstructionEnum;
 134.165 +    // C++ wrapper type for IfcVolumeMeasure
 134.166 +    typedef REAL IfcVolumeMeasure;
 134.167 +    // C++ wrapper type for IfcInductanceMeasure
 134.168 +    typedef REAL IfcInductanceMeasure;
 134.169 +    // C++ wrapper type for IfcCurtainWallTypeEnum
 134.170 +    typedef ENUMERATION IfcCurtainWallTypeEnum;
 134.171 +    // C++ wrapper type for IfcSIUnitName
 134.172 +    typedef ENUMERATION IfcSIUnitName;
 134.173 +    // C++ wrapper type for IfcSpecularExponent
 134.174 +    typedef REAL IfcSpecularExponent;
 134.175 +    // C++ wrapper type for IfcSoundPressureMeasure
 134.176 +    typedef REAL IfcSoundPressureMeasure;
 134.177 +    // C++ wrapper type for IfcAnalysisTheoryTypeEnum
 134.178 +    typedef ENUMERATION IfcAnalysisTheoryTypeEnum;
 134.179 +    // C++ wrapper type for IfcGasTerminalTypeEnum
 134.180 +    typedef ENUMERATION IfcGasTerminalTypeEnum;
 134.181 +    // C++ wrapper type for IfcYearNumber
 134.182 +    typedef INTEGER IfcYearNumber;
 134.183 +    // C++ wrapper type for IfcModulusOfElasticityMeasure
 134.184 +    typedef REAL IfcModulusOfElasticityMeasure;
 134.185 +    // C++ wrapper type for IfcChangeActionEnum
 134.186 +    typedef ENUMERATION IfcChangeActionEnum;
 134.187 +    // C++ wrapper type for IfcDamperTypeEnum
 134.188 +    typedef ENUMERATION IfcDamperTypeEnum;
 134.189 +    // C++ wrapper type for IfcEvaporatorTypeEnum
 134.190 +    typedef ENUMERATION IfcEvaporatorTypeEnum;
 134.191 +    // C++ wrapper type for IfcIonConcentrationMeasure
 134.192 +    typedef REAL IfcIonConcentrationMeasure;
 134.193 +    // C++ wrapper type for IfcDuctSegmentTypeEnum
 134.194 +    typedef ENUMERATION IfcDuctSegmentTypeEnum;
 134.195 +    // C++ wrapper type for IfcProtectiveDeviceTypeEnum
 134.196 +    typedef ENUMERATION IfcProtectiveDeviceTypeEnum;
 134.197 +    // C++ wrapper type for IfcAbsorbedDoseMeasure
 134.198 +    typedef REAL IfcAbsorbedDoseMeasure;
 134.199 +    // C++ wrapper type for IfcMassPerLengthMeasure
 134.200 +    typedef REAL IfcMassPerLengthMeasure;
 134.201 +    // C++ wrapper type for IfcTextFontName
 134.202 +    typedef STRING IfcTextFontName;
 134.203 +    // C++ wrapper type for IfcOrientationSelect
 134.204 +    typedef SELECT IfcOrientationSelect;
 134.205 +    // C++ wrapper type for IfcIlluminanceMeasure
 134.206 +    typedef REAL IfcIlluminanceMeasure;
 134.207 +    // C++ wrapper type for IfcFireSuppressionTerminalTypeEnum
 134.208 +    typedef ENUMERATION IfcFireSuppressionTerminalTypeEnum;
 134.209 +    // C++ wrapper type for IfcFontStyle
 134.210 +    typedef STRING IfcFontStyle;
 134.211 +    // C++ wrapper type for IfcMomentOfInertiaMeasure
 134.212 +    typedef REAL IfcMomentOfInertiaMeasure;
 134.213 +    // C++ wrapper type for IfcModulusOfSubgradeReactionMeasure
 134.214 +    typedef REAL IfcModulusOfSubgradeReactionMeasure;
 134.215 +    // C++ wrapper type for IfcHumidifierTypeEnum
 134.216 +    typedef ENUMERATION IfcHumidifierTypeEnum;
 134.217 +    // C++ wrapper type for IfcPresentationStyleSelect
 134.218 +    typedef SELECT IfcPresentationStyleSelect;
 134.219 +    // C++ wrapper type for IfcThermalTransmittanceMeasure
 134.220 +    typedef REAL IfcThermalTransmittanceMeasure;
 134.221 +    // C++ wrapper type for IfcRibPlateDirectionEnum
 134.222 +    typedef ENUMERATION IfcRibPlateDirectionEnum;
 134.223 +    // C++ wrapper type for IfcClassificationNotationSelect
 134.224 +    typedef SELECT IfcClassificationNotationSelect;
 134.225 +    // C++ wrapper type for IfcMinuteInHour
 134.226 +    typedef INTEGER IfcMinuteInHour;
 134.227 +    // C++ wrapper type for IfcInternalOrExternalEnum
 134.228 +    typedef ENUMERATION IfcInternalOrExternalEnum;
 134.229 +    // C++ wrapper type for IfcRotationalFrequencyMeasure
 134.230 +    typedef REAL IfcRotationalFrequencyMeasure;
 134.231 +    // C++ wrapper type for IfcSanitaryTerminalTypeEnum
 134.232 +    typedef ENUMERATION IfcSanitaryTerminalTypeEnum;
 134.233 +    // C++ wrapper type for IfcSymbolStyleSelect
 134.234 +    typedef SELECT IfcSymbolStyleSelect;
 134.235 +    // C++ wrapper type for IfcElementCompositionEnum
 134.236 +    typedef ENUMERATION IfcElementCompositionEnum;
 134.237 +    // C++ wrapper type for IfcTextPath
 134.238 +    typedef ENUMERATION IfcTextPath;
 134.239 +    // C++ wrapper type for IfcPowerMeasure
 134.240 +    typedef REAL IfcPowerMeasure;
 134.241 +    // C++ wrapper type for IfcSurfaceStyleElementSelect
 134.242 +    typedef SELECT IfcSurfaceStyleElementSelect;
 134.243 +    // C++ wrapper type for IfcResourceConsumptionEnum
 134.244 +    typedef ENUMERATION IfcResourceConsumptionEnum;
 134.245 +    // C++ wrapper type for IfcElectricCapacitanceMeasure
 134.246 +    typedef REAL IfcElectricCapacitanceMeasure;
 134.247 +    // C++ wrapper type for IfcLayerSetDirectionEnum
 134.248 +    typedef ENUMERATION IfcLayerSetDirectionEnum;
 134.249 +    // C++ wrapper type for IfcRailingTypeEnum
 134.250 +    typedef ENUMERATION IfcRailingTypeEnum;
 134.251 +    // C++ wrapper type for IfcObjectiveEnum
 134.252 +    typedef ENUMERATION IfcObjectiveEnum;
 134.253 +    // C++ wrapper type for IfcDocumentSelect
 134.254 +    typedef SELECT IfcDocumentSelect;
 134.255 +    // C++ wrapper type for IfcModulusOfLinearSubgradeReactionMeasure
 134.256 +    typedef REAL IfcModulusOfLinearSubgradeReactionMeasure;
 134.257 +    // C++ wrapper type for IfcThermalAdmittanceMeasure
 134.258 +    typedef REAL IfcThermalAdmittanceMeasure;
 134.259 +    // C++ wrapper type for IfcTransitionCode
 134.260 +    typedef ENUMERATION IfcTransitionCode;
 134.261 +    // C++ wrapper type for IfcConnectionTypeEnum
 134.262 +    typedef ENUMERATION IfcConnectionTypeEnum;
 134.263 +    // C++ wrapper type for IfcMonetaryMeasure
 134.264 +    typedef REAL IfcMonetaryMeasure;
 134.265 +    // C++ wrapper type for IfcStackTerminalTypeEnum
 134.266 +    typedef ENUMERATION IfcStackTerminalTypeEnum;
 134.267 +    // C++ wrapper type for IfcColour
 134.268 +    typedef SELECT IfcColour;
 134.269 +    // C++ wrapper type for IfcText
 134.270 +    typedef STRING IfcText;
 134.271 +    // C++ wrapper type for IfcContextDependentMeasure
 134.272 +    typedef REAL IfcContextDependentMeasure;
 134.273 +    // C++ wrapper type for IfcThermalConductivityMeasure
 134.274 +    typedef REAL IfcThermalConductivityMeasure;
 134.275 +    // C++ wrapper type for IfcProjectedOrTrueLengthEnum
 134.276 +    typedef ENUMERATION IfcProjectedOrTrueLengthEnum;
 134.277 +    // C++ wrapper type for IfcPressureMeasure
 134.278 +    typedef REAL IfcPressureMeasure;
 134.279 +    // C++ wrapper type for IfcMoistureDiffusivityMeasure
 134.280 +    typedef REAL IfcMoistureDiffusivityMeasure;
 134.281 +    // C++ wrapper type for IfcBooleanOperator
 134.282 +    typedef ENUMERATION IfcBooleanOperator;
 134.283 +    // C++ wrapper type for IfcPropertySourceEnum
 134.284 +    typedef ENUMERATION IfcPropertySourceEnum;
 134.285 +    // C++ wrapper type for IfcTimeStamp
 134.286 +    typedef INTEGER IfcTimeStamp;
 134.287 +    // C++ wrapper type for IfcMaterialSelect
 134.288 +    typedef SELECT IfcMaterialSelect;
 134.289 +    // C++ wrapper type for IfcGloballyUniqueId
 134.290 +    typedef STRING IfcGloballyUniqueId;
 134.291 +    // C++ wrapper type for IfcReflectanceMethodEnum
 134.292 +    typedef ENUMERATION IfcReflectanceMethodEnum;
 134.293 +    // C++ wrapper type for IfcVaporPermeabilityMeasure
 134.294 +    typedef REAL IfcVaporPermeabilityMeasure;
 134.295 +    // C++ wrapper type for IfcTimeSeriesScheduleTypeEnum
 134.296 +    typedef ENUMERATION IfcTimeSeriesScheduleTypeEnum;
 134.297 +    // C++ wrapper type for IfcLinearMomentMeasure
 134.298 +    typedef REAL IfcLinearMomentMeasure;
 134.299 +    // C++ wrapper type for IfcGeometricSetSelect
 134.300 +    typedef SELECT IfcGeometricSetSelect;
 134.301 +    // C++ wrapper type for IfcSectionModulusMeasure
 134.302 +    typedef REAL IfcSectionModulusMeasure;
 134.303 +    // C++ wrapper type for IfcBSplineCurveForm
 134.304 +    typedef ENUMERATION IfcBSplineCurveForm;
 134.305 +    // C++ wrapper type for IfcDimensionExtentUsage
 134.306 +    typedef ENUMERATION IfcDimensionExtentUsage;
 134.307 +    // C++ wrapper type for IfcThermalExpansionCoefficientMeasure
 134.308 +    typedef REAL IfcThermalExpansionCoefficientMeasure;
 134.309 +    // C++ wrapper type for IfcHourInDay
 134.310 +    typedef INTEGER IfcHourInDay;
 134.311 +    // C++ wrapper type for IfcLinearVelocityMeasure
 134.312 +    typedef REAL IfcLinearVelocityMeasure;
 134.313 +    // C++ wrapper type for IfcTorqueMeasure
 134.314 +    typedef REAL IfcTorqueMeasure;
 134.315 +    // C++ wrapper type for IfcTemperatureGradientMeasure
 134.316 +    typedef REAL IfcTemperatureGradientMeasure;
 134.317 +    // C++ wrapper type for IfcFillStyleSelect
 134.318 +    typedef SELECT IfcFillStyleSelect;
 134.319 +    // C++ wrapper type for IfcElectricChargeMeasure
 134.320 +    typedef REAL IfcElectricChargeMeasure;
 134.321 +    // C++ wrapper type for IfcHeatExchangerTypeEnum
 134.322 +    typedef ENUMERATION IfcHeatExchangerTypeEnum;
 134.323 +    // C++ wrapper type for IfcElectricCurrentEnum
 134.324 +    typedef ENUMERATION IfcElectricCurrentEnum;
 134.325 +    // C++ wrapper type for IfcDaylightSavingHour
 134.326 +    typedef INTEGER IfcDaylightSavingHour;
 134.327 +    // C++ wrapper type for IfcShell
 134.328 +    typedef SELECT IfcShell;
 134.329 +    // C++ wrapper type for IfcDoseEquivalentMeasure
 134.330 +    typedef REAL IfcDoseEquivalentMeasure;
 134.331 +    // C++ wrapper type for IfcProjectOrderTypeEnum
 134.332 +    typedef ENUMERATION IfcProjectOrderTypeEnum;
 134.333 +    // C++ wrapper type for IfcDerivedMeasureValue
 134.334 +    typedef SELECT IfcDerivedMeasureValue;
 134.335 +    // C++ wrapper type for IfcLightDistributionCurveEnum
 134.336 +    typedef ENUMERATION IfcLightDistributionCurveEnum;
 134.337 +    // C++ wrapper type for IfcWarpingMomentMeasure
 134.338 +    typedef REAL IfcWarpingMomentMeasure;
 134.339 +    // C++ wrapper type for IfcMemberTypeEnum
 134.340 +    typedef ENUMERATION IfcMemberTypeEnum;
 134.341 +    // C++ wrapper type for IfcSoundPowerMeasure
 134.342 +    typedef REAL IfcSoundPowerMeasure;
 134.343 +    // C++ wrapper type for IfcTextAlignment
 134.344 +    typedef STRING IfcTextAlignment;
 134.345 +    // C++ wrapper type for IfcCurveOrEdgeCurve
 134.346 +    typedef SELECT IfcCurveOrEdgeCurve;
 134.347 +    // C++ wrapper type for IfcMassFlowRateMeasure
 134.348 +    typedef REAL IfcMassFlowRateMeasure;
 134.349 +    // C++ wrapper type for IfcIsothermalMoistureCapacityMeasure
 134.350 +    typedef REAL IfcIsothermalMoistureCapacityMeasure;
 134.351 +    // C++ wrapper type for IfcCsgSelect
 134.352 +    typedef SELECT IfcCsgSelect;
 134.353 +    // C++ wrapper type for IfcCoolingTowerTypeEnum
 134.354 +    typedef ENUMERATION IfcCoolingTowerTypeEnum;
 134.355 +    // C++ wrapper type for IfcMassMeasure
 134.356 +    typedef REAL IfcMassMeasure;
 134.357 +    // C++ wrapper type for IfcPileConstructionEnum
 134.358 +    typedef ENUMERATION IfcPileConstructionEnum;
 134.359 +    // C++ wrapper type for IfcDoorStyleOperationEnum
 134.360 +    typedef ENUMERATION IfcDoorStyleOperationEnum;
 134.361 +    // C++ wrapper type for IfcFlowDirectionEnum
 134.362 +    typedef ENUMERATION IfcFlowDirectionEnum;
 134.363 +    // C++ wrapper type for IfcThermalLoadSourceEnum
 134.364 +    typedef ENUMERATION IfcThermalLoadSourceEnum;
 134.365 +    // C++ wrapper type for IfcLengthMeasure
 134.366 +    typedef REAL IfcLengthMeasure;
 134.367 +    // C++ wrapper type for IfcConstraintEnum
 134.368 +    typedef ENUMERATION IfcConstraintEnum;
 134.369 +    // C++ wrapper type for IfcAxis2Placement
 134.370 +    typedef SELECT IfcAxis2Placement;
 134.371 +    // C++ wrapper type for IfcLoadGroupTypeEnum
 134.372 +    typedef ENUMERATION IfcLoadGroupTypeEnum;
 134.373 +    // C++ wrapper type for IfcValue
 134.374 +    typedef SELECT IfcValue;
 134.375 +    // C++ wrapper type for IfcReinforcingBarSurfaceEnum
 134.376 +    typedef ENUMERATION IfcReinforcingBarSurfaceEnum;
 134.377 +    // C++ wrapper type for IfcProjectOrderRecordTypeEnum
 134.378 +    typedef ENUMERATION IfcProjectOrderRecordTypeEnum;
 134.379 +    // C++ wrapper type for IfcDateTimeSelect
 134.380 +    typedef SELECT IfcDateTimeSelect;
 134.381 +    // C++ wrapper type for IfcStructuralSurfaceTypeEnum
 134.382 +    typedef ENUMERATION IfcStructuralSurfaceTypeEnum;
 134.383 +    // C++ wrapper type for IfcPermeableCoveringOperationEnum
 134.384 +    typedef ENUMERATION IfcPermeableCoveringOperationEnum;
 134.385 +    // C++ wrapper type for IfcFontWeight
 134.386 +    typedef STRING IfcFontWeight;
 134.387 +    // C++ wrapper type for IfcPHMeasure
 134.388 +    typedef REAL IfcPHMeasure;
 134.389 +    // C++ wrapper type for IfcDescriptiveMeasure
 134.390 +    typedef STRING IfcDescriptiveMeasure;
 134.391 +    // C++ wrapper type for IfcCurveStyleFontSelect
 134.392 +    typedef SELECT IfcCurveStyleFontSelect;
 134.393 +    // C++ wrapper type for IfcUnit
 134.394 +    typedef SELECT IfcUnit;
 134.395 +    // C++ wrapper type for IfcHatchLineDistanceSelect
 134.396 +    typedef SELECT IfcHatchLineDistanceSelect;
 134.397 +    // C++ wrapper type for IfcTextStyleSelect
 134.398 +    typedef SELECT IfcTextStyleSelect;
 134.399 +    // C++ wrapper type for IfcMetricValueSelect
 134.400 +    typedef SELECT IfcMetricValueSelect;
 134.401 +    // C++ wrapper type for IfcVectorOrDirection
 134.402 +    typedef SELECT IfcVectorOrDirection;
 134.403 +    // C++ wrapper type for IfcAssemblyPlaceEnum
 134.404 +    typedef ENUMERATION IfcAssemblyPlaceEnum;
 134.405 +    // C++ wrapper type for IfcAirTerminalTypeEnum
 134.406 +    typedef ENUMERATION IfcAirTerminalTypeEnum;
 134.407 +    // C++ wrapper type for IfcCoveringTypeEnum
 134.408 +    typedef ENUMERATION IfcCoveringTypeEnum;
 134.409 +    // C++ wrapper type for IfcPlanarForceMeasure
 134.410 +    typedef REAL IfcPlanarForceMeasure;
 134.411 +    // C++ wrapper type for IfcValveTypeEnum
 134.412 +    typedef ENUMERATION IfcValveTypeEnum;
 134.413 +    // C++ wrapper type for IfcAlarmTypeEnum
 134.414 +    typedef ENUMERATION IfcAlarmTypeEnum;
 134.415 +    // C++ wrapper type for IfcDynamicViscosityMeasure
 134.416 +    typedef REAL IfcDynamicViscosityMeasure;
 134.417 +    // C++ wrapper type for IfcCurrencyEnum
 134.418 +    typedef ENUMERATION IfcCurrencyEnum;
 134.419 +    // C++ wrapper type for IfcModulusOfRotationalSubgradeReactionMeasure
 134.420 +    typedef REAL IfcModulusOfRotationalSubgradeReactionMeasure;
 134.421 +    // C++ wrapper type for IfcCableCarrierFittingTypeEnum
 134.422 +    typedef ENUMERATION IfcCableCarrierFittingTypeEnum;
 134.423 +    // C++ wrapper type for IfcBoolean
 134.424 +    typedef BOOLEAN IfcBoolean;
 134.425 +    // C++ wrapper type for IfcActionSourceTypeEnum
 134.426 +    typedef ENUMERATION IfcActionSourceTypeEnum;
 134.427 +    // C++ wrapper type for IfcStructuralActivityAssignmentSelect
 134.428 +    typedef SELECT IfcStructuralActivityAssignmentSelect;
 134.429 +    // C++ wrapper type for IfcDistributionChamberElementTypeEnum
 134.430 +    typedef ENUMERATION IfcDistributionChamberElementTypeEnum;
 134.431 +    // C++ wrapper type for IfcEvaporativeCoolerTypeEnum
 134.432 +    typedef ENUMERATION IfcEvaporativeCoolerTypeEnum;
 134.433 +    // C++ wrapper type for IfcMagneticFluxDensityMeasure
 134.434 +    typedef REAL IfcMagneticFluxDensityMeasure;
 134.435 +    // C++ wrapper type for IfcLightDistributionDataSourceSelect
 134.436 +    typedef SELECT IfcLightDistributionDataSourceSelect;
 134.437 +    // C++ wrapper type for IfcTubeBundleTypeEnum
 134.438 +    typedef ENUMERATION IfcTubeBundleTypeEnum;
 134.439 +    // C++ wrapper type for IfcAccelerationMeasure
 134.440 +    typedef REAL IfcAccelerationMeasure;
 134.441 +    // C++ wrapper type for IfcBoilerTypeEnum
 134.442 +    typedef ENUMERATION IfcBoilerTypeEnum;
 134.443 +    // C++ wrapper type for IfcRampTypeEnum
 134.444 +    typedef ENUMERATION IfcRampTypeEnum;
 134.445 +    // C++ wrapper type for IfcLuminousIntensityDistributionMeasure
 134.446 +    typedef REAL IfcLuminousIntensityDistributionMeasure;
 134.447 +    // C++ wrapper type for IfcTrimmingPreference
 134.448 +    typedef ENUMERATION IfcTrimmingPreference;
 134.449 +    // C++ wrapper type for IfcSpecificHeatCapacityMeasure
 134.450 +    typedef REAL IfcSpecificHeatCapacityMeasure;
 134.451 +    // C++ wrapper type for IfcAmountOfSubstanceMeasure
 134.452 +    typedef REAL IfcAmountOfSubstanceMeasure;
 134.453 +    // C++ wrapper type for IfcRoleEnum
 134.454 +    typedef ENUMERATION IfcRoleEnum;
 134.455 +    // C++ wrapper type for IfcDocumentConfidentialityEnum
 134.456 +    typedef ENUMERATION IfcDocumentConfidentialityEnum;
 134.457 +    // C++ wrapper type for IfcFrequencyMeasure
 134.458 +    typedef REAL IfcFrequencyMeasure;
 134.459 +    // C++ wrapper type for IfcSectionTypeEnum
 134.460 +    typedef ENUMERATION IfcSectionTypeEnum;
 134.461 +    // C++ wrapper type for IfcElementAssemblyTypeEnum
 134.462 +    typedef ENUMERATION IfcElementAssemblyTypeEnum;
 134.463 +    // C++ wrapper type for IfcFootingTypeEnum
 134.464 +    typedef ENUMERATION IfcFootingTypeEnum;
 134.465 +    // C++ wrapper type for IfcLayeredItem
 134.466 +    typedef SELECT IfcLayeredItem;
 134.467 +    // C++ wrapper type for IfcCableSegmentTypeEnum
 134.468 +    typedef ENUMERATION IfcCableSegmentTypeEnum;
 134.469 +    // C++ wrapper type for IfcDefinedSymbolSelect
 134.470 +    typedef SELECT IfcDefinedSymbolSelect;
 134.471 +    // C++ wrapper type for IfcBuildingElementProxyTypeEnum
 134.472 +    typedef ENUMERATION IfcBuildingElementProxyTypeEnum;
 134.473 +    // C++ wrapper type for IfcElectricGeneratorTypeEnum
 134.474 +    typedef ENUMERATION IfcElectricGeneratorTypeEnum;
 134.475 +    // C++ wrapper type for IfcRotationalStiffnessMeasure
 134.476 +    typedef REAL IfcRotationalStiffnessMeasure;
 134.477 +    // C++ wrapper type for IfcSpaceHeaterTypeEnum
 134.478 +    typedef ENUMERATION IfcSpaceHeaterTypeEnum;
 134.479 +    // C++ wrapper type for IfcAreaMeasure
 134.480 +    typedef REAL IfcAreaMeasure;
 134.481 +    // C++ wrapper type for IfcLabel
 134.482 +    typedef STRING IfcLabel;
 134.483 +    // C++ wrapper type for IfcCostScheduleTypeEnum
 134.484 +    typedef ENUMERATION IfcCostScheduleTypeEnum;
 134.485 +    // C++ wrapper type for IfcSwitchingDeviceTypeEnum
 134.486 +    typedef ENUMERATION IfcSwitchingDeviceTypeEnum;
 134.487 +    // C++ wrapper type for IfcElectricTimeControlTypeEnum
 134.488 +    typedef ENUMERATION IfcElectricTimeControlTypeEnum;
 134.489 +    // C++ wrapper type for IfcFilterTypeEnum
 134.490 +    typedef ENUMERATION IfcFilterTypeEnum;
 134.491 +    // C++ wrapper type for IfcPositiveLengthMeasure
 134.492 +    typedef REAL IfcPositiveLengthMeasure;
 134.493 +    // C++ wrapper type for IfcNullStyle
 134.494 +    typedef ENUMERATION IfcNullStyle;
 134.495 +    // C++ wrapper type for IfcConditionCriterionSelect
 134.496 +    typedef SELECT IfcConditionCriterionSelect;
 134.497 +    // C++ wrapper type for IfcShearModulusMeasure
 134.498 +    typedef REAL IfcShearModulusMeasure;
 134.499 +    // C++ wrapper type for IfcNormalisedRatioMeasure
 134.500 +    typedef REAL IfcNormalisedRatioMeasure;
 134.501 +    // C++ wrapper type for IfcDoorPanelOperationEnum
 134.502 +    typedef ENUMERATION IfcDoorPanelOperationEnum;
 134.503 +    // C++ wrapper type for IfcPointOrVertexPoint
 134.504 +    typedef SELECT IfcPointOrVertexPoint;
 134.505 +    // C++ wrapper type for IfcRoofTypeEnum
 134.506 +    typedef ENUMERATION IfcRoofTypeEnum;
 134.507 +    // C++ wrapper type for IfcCountMeasure
 134.508 +    typedef NUMBER IfcCountMeasure;
 134.509 +    // C++ wrapper type for IfcElectricConductanceMeasure
 134.510 +    typedef REAL IfcElectricConductanceMeasure;
 134.511 +    // C++ wrapper type for IfcProcedureTypeEnum
 134.512 +    typedef ENUMERATION IfcProcedureTypeEnum;
 134.513 +    // C++ wrapper type for IfcFlowInstrumentTypeEnum
 134.514 +    typedef ENUMERATION IfcFlowInstrumentTypeEnum;
 134.515 +    // C++ wrapper type for IfcElectricMotorTypeEnum
 134.516 +    typedef ENUMERATION IfcElectricMotorTypeEnum;
 134.517 +    // C++ wrapper type for IfcSurfaceSide
 134.518 +    typedef ENUMERATION IfcSurfaceSide;
 134.519 +    // C++ wrapper type for IfcStructuralCurveTypeEnum
 134.520 +    typedef ENUMERATION IfcStructuralCurveTypeEnum;
 134.521 +    // C++ wrapper type for IfcCondenserTypeEnum
 134.522 +    typedef ENUMERATION IfcCondenserTypeEnum;
 134.523 +    // C++ wrapper type for IfcLinearStiffnessMeasure
 134.524 +    typedef REAL IfcLinearStiffnessMeasure;
 134.525 +    // C++ wrapper type for IfcUnitEnum
 134.526 +    typedef ENUMERATION IfcUnitEnum;
 134.527 +    // C++ wrapper type for IfcOccupantTypeEnum
 134.528 +    typedef ENUMERATION IfcOccupantTypeEnum;
 134.529 +    // C++ wrapper type for IfcThermalLoadTypeEnum
 134.530 +    typedef ENUMERATION IfcThermalLoadTypeEnum;
 134.531 +    // C++ wrapper type for IfcReinforcingBarRoleEnum
 134.532 +    typedef ENUMERATION IfcReinforcingBarRoleEnum;
 134.533 +    // C++ wrapper type for IfcBenchmarkEnum
 134.534 +    typedef ENUMERATION IfcBenchmarkEnum;
 134.535 +    // C++ wrapper type for IfcPositivePlaneAngleMeasure
 134.536 +    typedef REAL IfcPositivePlaneAngleMeasure;
 134.537 +    // C++ wrapper type for IfcTextTransformation
 134.538 +    typedef STRING IfcTextTransformation;
 134.539 +    // C++ wrapper type for IfcDraughtingCalloutElement
 134.540 +    typedef SELECT IfcDraughtingCalloutElement;
 134.541 +    // C++ wrapper type for IfcRatioMeasure
 134.542 +    typedef REAL IfcRatioMeasure;
 134.543 +    // C++ wrapper type for IfcSolidAngleMeasure
 134.544 +    typedef REAL IfcSolidAngleMeasure;
 134.545 +    // C++ wrapper type for IfcPipeSegmentTypeEnum
 134.546 +    typedef ENUMERATION IfcPipeSegmentTypeEnum;
 134.547 +    // C++ wrapper type for IfcCableCarrierSegmentTypeEnum
 134.548 +    typedef ENUMERATION IfcCableCarrierSegmentTypeEnum;
 134.549 +    // C++ wrapper type for IfcColourOrFactor
 134.550 +    typedef SELECT IfcColourOrFactor;
 134.551 +    // C++ wrapper type for IfcIdentifier
 134.552 +    typedef STRING IfcIdentifier;
 134.553 +    // C++ wrapper type for IfcTendonTypeEnum
 134.554 +    typedef ENUMERATION IfcTendonTypeEnum;
 134.555 +    // C++ wrapper type for IfcControllerTypeEnum
 134.556 +    typedef ENUMERATION IfcControllerTypeEnum;
 134.557 +    // C++ wrapper type for IfcRadioActivityMeasure
 134.558 +    typedef REAL IfcRadioActivityMeasure;
 134.559 +    // C++ wrapper type for IfcTimeMeasure
 134.560 +    typedef REAL IfcTimeMeasure;
 134.561 +    // C++ wrapper type for IfcPumpTypeEnum
 134.562 +    typedef ENUMERATION IfcPumpTypeEnum;
 134.563 +    // C++ wrapper type for IfcElectricHeaterTypeEnum
 134.564 +    typedef ENUMERATION IfcElectricHeaterTypeEnum;
 134.565 +    // C++ wrapper type for IfcBeamTypeEnum
 134.566 +    typedef ENUMERATION IfcBeamTypeEnum;
 134.567 +    // C++ wrapper type for IfcStateEnum
 134.568 +    typedef ENUMERATION IfcStateEnum;
 134.569 +    // C++ wrapper type for IfcSIPrefix
 134.570 +    typedef ENUMERATION IfcSIPrefix;
 134.571 +    // C++ wrapper type for IfcNumericMeasure
 134.572 +    typedef NUMBER IfcNumericMeasure;
 134.573 +    // C++ wrapper type for IfcOutletTypeEnum
 134.574 +    typedef ENUMERATION IfcOutletTypeEnum;
 134.575 +    // C++ wrapper type for IfcCompoundPlaneAngleMeasure
 134.576 +    typedef ListOf< INTEGER, 3, 3 > IfcCompoundPlaneAngleMeasure;
 134.577 +    // C++ wrapper type for IfcServiceLifeFactorTypeEnum
 134.578 +    typedef ENUMERATION IfcServiceLifeFactorTypeEnum;
 134.579 +    // C++ wrapper type for IfcLogicalOperatorEnum
 134.580 +    typedef ENUMERATION IfcLogicalOperatorEnum;
 134.581 +    // C++ wrapper type for IfcBooleanOperand
 134.582 +    typedef SELECT IfcBooleanOperand;
 134.583 +    // C++ wrapper type for IfcObjectReferenceSelect
 134.584 +    typedef SELECT IfcObjectReferenceSelect;
 134.585 +    // C++ wrapper type for IfcCooledBeamTypeEnum
 134.586 +    typedef ENUMERATION IfcCooledBeamTypeEnum;
 134.587 +    // C++ wrapper type for IfcDuctSilencerTypeEnum
 134.588 +    typedef ENUMERATION IfcDuctSilencerTypeEnum;
 134.589 +    // C++ wrapper type for IfcSectionalAreaIntegralMeasure
 134.590 +    typedef REAL IfcSectionalAreaIntegralMeasure;
 134.591 +    // C++ wrapper type for IfcFontVariant
 134.592 +    typedef STRING IfcFontVariant;
 134.593 +    // C++ wrapper type for IfcVolumetricFlowRateMeasure
 134.594 +    typedef REAL IfcVolumetricFlowRateMeasure;
 134.595 +    // C++ wrapper type for IfcPlateTypeEnum
 134.596 +    typedef ENUMERATION IfcPlateTypeEnum;
 134.597 +    // C++ wrapper type for IfcEnvironmentalImpactCategoryEnum
 134.598 +    typedef ENUMERATION IfcEnvironmentalImpactCategoryEnum;
 134.599 +    // C++ wrapper type for IfcVibrationIsolatorTypeEnum
 134.600 +    typedef ENUMERATION IfcVibrationIsolatorTypeEnum;
 134.601 +    // C++ wrapper type for IfcThermodynamicTemperatureMeasure
 134.602 +    typedef REAL IfcThermodynamicTemperatureMeasure;
 134.603 +    // C++ wrapper type for IfcRotationalMassMeasure
 134.604 +    typedef REAL IfcRotationalMassMeasure;
 134.605 +    // C++ wrapper type for IfcSecondInMinute
 134.606 +    typedef REAL IfcSecondInMinute;
 134.607 +    // C++ wrapper type for IfcDayInMonthNumber
 134.608 +    typedef INTEGER IfcDayInMonthNumber;
 134.609 +    // C++ wrapper type for IfcDimensionCount
 134.610 +    typedef INTEGER IfcDimensionCount;
 134.611 +    // C++ wrapper type for IfcWindowStyleOperationEnum
 134.612 +    typedef ENUMERATION IfcWindowStyleOperationEnum;
 134.613 +    // C++ wrapper type for IfcThermalResistanceMeasure
 134.614 +    typedef REAL IfcThermalResistanceMeasure;
 134.615 +    // C++ wrapper type for IfcMeasureValue
 134.616 +    typedef SELECT IfcMeasureValue;
 134.617 +    // C++ wrapper type for IfcWindowPanelOperationEnum
 134.618 +    typedef ENUMERATION IfcWindowPanelOperationEnum;
 134.619 +    // C++ wrapper type for IfcChillerTypeEnum
 134.620 +    typedef ENUMERATION IfcChillerTypeEnum;
 134.621 +    // C++ wrapper type for IfcPositiveRatioMeasure
 134.622 +    typedef REAL IfcPositiveRatioMeasure;
 134.623 +    // C++ wrapper type for IfcInteger
 134.624 +    typedef INTEGER IfcInteger;
 134.625 +    // C++ wrapper type for IfcLogical
 134.626 +    typedef LOGICAL IfcLogical;
 134.627 +    // C++ wrapper type for IfcJunctionBoxTypeEnum
 134.628 +    typedef ENUMERATION IfcJunctionBoxTypeEnum;
 134.629 +    // C++ wrapper type for IfcAddressTypeEnum
 134.630 +    typedef ENUMERATION IfcAddressTypeEnum;
 134.631 +    // C++ wrapper type for IfcWasteTerminalTypeEnum
 134.632 +    typedef ENUMERATION IfcWasteTerminalTypeEnum;
 134.633 +    // C++ wrapper type for IfcTrimmingSelect
 134.634 +    typedef SELECT IfcTrimmingSelect;
 134.635 +    // C++ wrapper type for IfcLightEmissionSourceEnum
 134.636 +    typedef ENUMERATION IfcLightEmissionSourceEnum;
 134.637 +    // C++ wrapper type for IfcSoundScaleEnum
 134.638 +    typedef ENUMERATION IfcSoundScaleEnum;
 134.639 +    // C++ wrapper type for IfcLuminousFluxMeasure
 134.640 +    typedef REAL IfcLuminousFluxMeasure;
 134.641 +    // C++ wrapper type for IfcElectricResistanceMeasure
 134.642 +    typedef REAL IfcElectricResistanceMeasure;
 134.643 +    // C++ wrapper type for IfcIntegerCountRateMeasure
 134.644 +    typedef INTEGER IfcIntegerCountRateMeasure;
 134.645 +    // C++ wrapper type for IfcPhysicalOrVirtualEnum
 134.646 +    typedef ENUMERATION IfcPhysicalOrVirtualEnum;
 134.647 +    // C++ wrapper type for IfcMolecularWeightMeasure
 134.648 +    typedef REAL IfcMolecularWeightMeasure;
 134.649 +    // C++ wrapper type for IfcProfileTypeEnum
 134.650 +    typedef ENUMERATION IfcProfileTypeEnum;
 134.651 +    // C++ wrapper type for IfcBoxAlignment
 134.652 +    typedef STRING IfcBoxAlignment;
 134.653 +    // C++ wrapper type for IfcGlobalOrLocalEnum
 134.654 +    typedef ENUMERATION IfcGlobalOrLocalEnum;
 134.655 +    // C++ wrapper type for IfcSpecularRoughness
 134.656 +    typedef REAL IfcSpecularRoughness;
 134.657 +    // C++ wrapper type for IfcLampTypeEnum
 134.658 +    typedef ENUMERATION IfcLampTypeEnum;
 134.659 +    // C++ wrapper type for IfcPileTypeEnum
 134.660 +    typedef ENUMERATION IfcPileTypeEnum;
 134.661 +    // C++ wrapper type for IfcElectricCurrentMeasure
 134.662 +    typedef REAL IfcElectricCurrentMeasure;
 134.663 +    // C++ wrapper type for IfcFanTypeEnum
 134.664 +    typedef ENUMERATION IfcFanTypeEnum;
 134.665 +    // C++ wrapper type for IfcSurfaceOrFaceSurface
 134.666 +    typedef SELECT IfcSurfaceOrFaceSurface;
 134.667 +    // C++ wrapper type for IfcPipeFittingTypeEnum
 134.668 +    typedef ENUMERATION IfcPipeFittingTypeEnum;
 134.669 +    // C++ wrapper type for IfcTankTypeEnum
 134.670 +    typedef ENUMERATION IfcTankTypeEnum;
 134.671 +    // C++ wrapper type for IfcCurveFontOrScaledCurveFontSelect
 134.672 +    typedef SELECT IfcCurveFontOrScaledCurveFontSelect;
 134.673 +    // C++ wrapper type for IfcWindowStyleConstructionEnum
 134.674 +    typedef ENUMERATION IfcWindowStyleConstructionEnum;
 134.675 +    // C++ wrapper type for IfcAirTerminalBoxTypeEnum
 134.676 +    typedef ENUMERATION IfcAirTerminalBoxTypeEnum;
 134.677 +    // C++ wrapper type for IfcStairFlightTypeEnum
 134.678 +    typedef ENUMERATION IfcStairFlightTypeEnum;
 134.679 +    // C++ wrapper type for IfcLuminousIntensityMeasure
 134.680 +    typedef REAL IfcLuminousIntensityMeasure;
 134.681 +    // C++ wrapper type for IfcMotorConnectionTypeEnum
 134.682 +    typedef ENUMERATION IfcMotorConnectionTypeEnum;
 134.683 +    // C++ wrapper type for IfcPlaneAngleMeasure
 134.684 +    typedef REAL IfcPlaneAngleMeasure;
 134.685 +    // C++ wrapper type for IfcActuatorTypeEnum
 134.686 +    typedef ENUMERATION IfcActuatorTypeEnum;
 134.687 +    // C++ wrapper type for IfcColumnTypeEnum
 134.688 +    typedef ENUMERATION IfcColumnTypeEnum;
 134.689 +    // C++ wrapper type for IfcTextFontSelect
 134.690 +    typedef SELECT IfcTextFontSelect;
 134.691 +    // C++ wrapper type for IfcDoorPanelPositionEnum
 134.692 +    typedef ENUMERATION IfcDoorPanelPositionEnum;
 134.693 +    // C++ wrapper type for IfcCoilTypeEnum
 134.694 +    typedef ENUMERATION IfcCoilTypeEnum;
 134.695 +    // C++ wrapper type for IfcAngularVelocityMeasure
 134.696 +    typedef REAL IfcAngularVelocityMeasure;
 134.697 +    // C++ wrapper type for IfcAnalysisModelTypeEnum
 134.698 +    typedef ENUMERATION IfcAnalysisModelTypeEnum;
 134.699 +    // C++ wrapper type for IfcLibrarySelect
 134.700 +    typedef SELECT IfcLibrarySelect;
 134.701 +    // C++ wrapper type for IfcForceMeasure
 134.702 +    typedef REAL IfcForceMeasure;
 134.703 +    // C++ wrapper type for IfcFillAreaStyleTileShapeSelect
 134.704 +    typedef SELECT IfcFillAreaStyleTileShapeSelect;
 134.705 +    // C++ wrapper type for IfcElectricApplianceTypeEnum
 134.706 +    typedef ENUMERATION IfcElectricApplianceTypeEnum;
 134.707 +    // C++ wrapper type for IfcSurfaceTextureEnum
 134.708 +    typedef ENUMERATION IfcSurfaceTextureEnum;
 134.709 +    // C++ wrapper type for IfcCharacterStyleSelect
 134.710 +    typedef SELECT IfcCharacterStyleSelect;
 134.711 +    // C++ wrapper type for IfcEnergyMeasure
 134.712 +    typedef REAL IfcEnergyMeasure;
 134.713 +    // C++ wrapper type for IfcReal
 134.714 +    typedef REAL IfcReal;
 134.715 +    // C++ wrapper type for IfcCompressorTypeEnum
 134.716 +    typedef ENUMERATION IfcCompressorTypeEnum;
 134.717 +    // C++ wrapper type for IfcElectricDistributionPointFunctionEnum
 134.718 +    typedef ENUMERATION IfcElectricDistributionPointFunctionEnum;
 134.719 +
 134.720 +
 134.721 +	// ******************************************************************************
 134.722 +	// IFC Entities
 134.723 +	// ******************************************************************************
 134.724 +
 134.725 +	struct IfcRoot;
 134.726 +	struct IfcObjectDefinition;
 134.727 +	struct IfcTypeObject;
 134.728 +	struct IfcTypeProduct;
 134.729 +	struct IfcElementType;
 134.730 +	struct IfcDistributionElementType;
 134.731 +	struct IfcDistributionFlowElementType;
 134.732 +	struct IfcFlowControllerType;
 134.733 +	struct IfcElectricTimeControlType;
 134.734 +	struct IfcRepresentation;
 134.735 +	struct IfcShapeModel;
 134.736 +	struct IfcTopologyRepresentation;
 134.737 +	struct IfcRelationship;
 134.738 +	struct IfcRelConnects;
 134.739 +	typedef NotImplemented IfcRelCoversSpaces; // (not currently used by Assimp)
 134.740 +	struct IfcFlowFittingType;
 134.741 +	struct IfcCableCarrierFittingType;
 134.742 +	typedef NotImplemented IfcStructuralConnectionCondition; // (not currently used by Assimp)
 134.743 +	typedef NotImplemented IfcSlippageConnectionCondition; // (not currently used by Assimp)
 134.744 +	struct IfcEnergyConversionDeviceType;
 134.745 +	struct IfcCoilType;
 134.746 +	struct IfcObject;
 134.747 +	struct IfcControl;
 134.748 +	struct IfcPerformanceHistory;
 134.749 +	struct IfcRepresentationItem;
 134.750 +	struct IfcGeometricRepresentationItem;
 134.751 +	struct IfcTextLiteral;
 134.752 +	struct IfcTextLiteralWithExtent;
 134.753 +	struct IfcProductRepresentation;
 134.754 +	struct IfcProduct;
 134.755 +	struct IfcElement;
 134.756 +	struct IfcDistributionElement;
 134.757 +	struct IfcDistributionFlowElement;
 134.758 +	struct IfcCurve;
 134.759 +	struct IfcBoundedCurve;
 134.760 +	struct IfcCompositeCurve;
 134.761 +	struct Ifc2DCompositeCurve;
 134.762 +	typedef NotImplemented IfcBoundaryCondition; // (not currently used by Assimp)
 134.763 +	typedef NotImplemented IfcBoundaryFaceCondition; // (not currently used by Assimp)
 134.764 +	struct IfcCartesianTransformationOperator;
 134.765 +	struct IfcCartesianTransformationOperator3D;
 134.766 +	struct IfcProperty;
 134.767 +	struct IfcSimpleProperty;
 134.768 +	struct IfcPropertyEnumeratedValue;
 134.769 +	typedef NotImplemented IfcPresentationLayerAssignment; // (not currently used by Assimp)
 134.770 +	typedef NotImplemented IfcPresentationLayerWithStyle; // (not currently used by Assimp)
 134.771 +	struct IfcBuildingElementType;
 134.772 +	struct IfcStairFlightType;
 134.773 +	struct IfcSurface;
 134.774 +	struct IfcElementarySurface;
 134.775 +	struct IfcPlane;
 134.776 +	struct IfcBooleanResult;
 134.777 +	struct IfcBooleanClippingResult;
 134.778 +	struct IfcSolidModel;
 134.779 +	struct IfcManifoldSolidBrep;
 134.780 +	typedef NotImplemented IfcProfileProperties; // (not currently used by Assimp)
 134.781 +	typedef NotImplemented IfcGeneralProfileProperties; // (not currently used by Assimp)
 134.782 +	typedef NotImplemented IfcStructuralProfileProperties; // (not currently used by Assimp)
 134.783 +	struct IfcFlowTerminalType;
 134.784 +	struct IfcStackTerminalType;
 134.785 +	struct IfcStructuralItem;
 134.786 +	struct IfcStructuralConnection;
 134.787 +	struct IfcStructuralCurveConnection;
 134.788 +	struct IfcJunctionBoxType;
 134.789 +	typedef NotImplemented IfcRelAssociates; // (not currently used by Assimp)
 134.790 +	typedef NotImplemented IfcRelAssociatesConstraint; // (not currently used by Assimp)
 134.791 +	struct IfcPropertyDefinition;
 134.792 +	struct IfcPropertySetDefinition;
 134.793 +	typedef NotImplemented IfcDoorPanelProperties; // (not currently used by Assimp)
 134.794 +	typedef NotImplemented IfcConstraintRelationship; // (not currently used by Assimp)
 134.795 +	typedef NotImplemented IfcSpaceThermalLoadProperties; // (not currently used by Assimp)
 134.796 +	typedef NotImplemented IfcLibraryInformation; // (not currently used by Assimp)
 134.797 +	struct IfcProcess;
 134.798 +	struct IfcTask;
 134.799 +	typedef NotImplemented IfcAppliedValue; // (not currently used by Assimp)
 134.800 +	typedef NotImplemented IfcEnvironmentalImpactValue; // (not currently used by Assimp)
 134.801 +	struct IfcRelFillsElement;
 134.802 +	struct IfcProcedure;
 134.803 +	typedef NotImplemented IfcStructuralLoad; // (not currently used by Assimp)
 134.804 +	typedef NotImplemented IfcStructuralLoadStatic; // (not currently used by Assimp)
 134.805 +	typedef NotImplemented IfcStructuralLoadSingleDisplacement; // (not currently used by Assimp)
 134.806 +	struct IfcProxy;
 134.807 +	typedef NotImplemented IfcCurveStyleFont; // (not currently used by Assimp)
 134.808 +	struct IfcResource;
 134.809 +	struct IfcConstructionResource;
 134.810 +	struct IfcSubContractResource;
 134.811 +	typedef NotImplemented IfcCalendarDate; // (not currently used by Assimp)
 134.812 +	typedef NotImplemented IfcDocumentElectronicFormat; // (not currently used by Assimp)
 134.813 +	struct IfcRelContainedInSpatialStructure;
 134.814 +	typedef NotImplemented IfcMaterialProperties; // (not currently used by Assimp)
 134.815 +	typedef NotImplemented IfcProductsOfCombustionProperties; // (not currently used by Assimp)
 134.816 +	struct IfcTopologicalRepresentationItem;
 134.817 +	struct IfcEdge;
 134.818 +	struct IfcEdgeCurve;
 134.819 +	struct IfcPlateType;
 134.820 +	struct IfcObjectPlacement;
 134.821 +	struct IfcGridPlacement;
 134.822 +	struct IfcFireSuppressionTerminalType;
 134.823 +	typedef NotImplemented IfcMechanicalMaterialProperties; // (not currently used by Assimp)
 134.824 +	struct IfcFlowStorageDevice;
 134.825 +	typedef NotImplemented IfcPerson; // (not currently used by Assimp)
 134.826 +	struct IfcSweptSurface;
 134.827 +	struct IfcSurfaceOfRevolution;
 134.828 +	struct IfcOrientedEdge;
 134.829 +	typedef NotImplemented IfcOwnerHistory; // (not currently used by Assimp)
 134.830 +	typedef NotImplemented IfcRelAssigns; // (not currently used by Assimp)
 134.831 +	typedef NotImplemented IfcRelAssignsToActor; // (not currently used by Assimp)
 134.832 +	struct IfcDirection;
 134.833 +	typedef NotImplemented IfcReinforcementBarProperties; // (not currently used by Assimp)
 134.834 +	struct IfcProfileDef;
 134.835 +	struct IfcParameterizedProfileDef;
 134.836 +	struct IfcCShapeProfileDef;
 134.837 +	struct IfcFeatureElement;
 134.838 +	struct IfcFeatureElementSubtraction;
 134.839 +	struct IfcEdgeFeature;
 134.840 +	struct IfcChamferEdgeFeature;
 134.841 +	struct IfcBuildingElement;
 134.842 +	struct IfcColumn;
 134.843 +	struct IfcPropertyReferenceValue;
 134.844 +	typedef NotImplemented IfcMaterialClassificationRelationship; // (not currently used by Assimp)
 134.845 +	struct IfcElectricMotorType;
 134.846 +	struct IfcSpatialStructureElementType;
 134.847 +	struct IfcSpaceType;
 134.848 +	typedef NotImplemented IfcExternalReference; // (not currently used by Assimp)
 134.849 +	typedef NotImplemented IfcExternallyDefinedHatchStyle; // (not currently used by Assimp)
 134.850 +	struct IfcColumnType;
 134.851 +	struct IfcCraneRailAShapeProfileDef;
 134.852 +	struct IfcCondenserType;
 134.853 +	typedef NotImplemented IfcRelConnectsElements; // (not currently used by Assimp)
 134.854 +	typedef NotImplemented IfcRelConnectsWithRealizingElements; // (not currently used by Assimp)
 134.855 +	struct IfcCircleProfileDef;
 134.856 +	struct IfcCircleHollowProfileDef;
 134.857 +	typedef NotImplemented IfcOrganizationRelationship; // (not currently used by Assimp)
 134.858 +	struct IfcPlacement;
 134.859 +	struct IfcAxis2Placement3D;
 134.860 +	struct IfcPresentationStyle;
 134.861 +	typedef NotImplemented IfcCurveStyle; // (not currently used by Assimp)
 134.862 +	struct IfcEquipmentElement;
 134.863 +	struct IfcCompositeCurveSegment;
 134.864 +	struct IfcRectangleProfileDef;
 134.865 +	typedef NotImplemented IfcPhysicalQuantity; // (not currently used by Assimp)
 134.866 +	typedef NotImplemented IfcPhysicalComplexQuantity; // (not currently used by Assimp)
 134.867 +	typedef NotImplemented IfcRelAssociatesLibrary; // (not currently used by Assimp)
 134.868 +	typedef NotImplemented IfcRelSequence; // (not currently used by Assimp)
 134.869 +	struct IfcBuildingElementProxy;
 134.870 +	struct IfcDistributionControlElementType;
 134.871 +	struct IfcFlowInstrumentType;
 134.872 +	struct IfcDraughtingCallout;
 134.873 +	struct IfcDimensionCurveDirectedCallout;
 134.874 +	struct IfcLinearDimension;
 134.875 +	struct IfcElementAssembly;
 134.876 +	typedef NotImplemented IfcDraughtingCalloutRelationship; // (not currently used by Assimp)
 134.877 +	struct IfcCsgPrimitive3D;
 134.878 +	struct IfcRightCircularCone;
 134.879 +	typedef NotImplemented IfcExternallyDefinedSurfaceStyle; // (not currently used by Assimp)
 134.880 +	struct IfcProjectOrder;
 134.881 +	typedef NotImplemented IfcPropertyConstraintRelationship; // (not currently used by Assimp)
 134.882 +	struct IfcLShapeProfileDef;
 134.883 +	struct IfcAngularDimension;
 134.884 +	typedef NotImplemented IfcTextStyleForDefinedFont; // (not currently used by Assimp)
 134.885 +	struct IfcLocalPlacement;
 134.886 +	struct IfcSweptAreaSolid;
 134.887 +	struct IfcRevolvedAreaSolid;
 134.888 +	struct IfcStructuralSurfaceConnection;
 134.889 +	struct IfcRadiusDimension;
 134.890 +	struct IfcSweptDiskSolid;
 134.891 +	struct IfcHalfSpaceSolid;
 134.892 +	struct IfcPolygonalBoundedHalfSpace;
 134.893 +	struct IfcTimeSeriesSchedule;
 134.894 +	typedef NotImplemented IfcDimensionCalloutRelationship; // (not currently used by Assimp)
 134.895 +	struct IfcCooledBeamType;
 134.896 +	struct IfcProject;
 134.897 +	typedef NotImplemented IfcApprovalRelationship; // (not currently used by Assimp)
 134.898 +	struct IfcEvaporatorType;
 134.899 +	struct IfcLaborResource;
 134.900 +	typedef NotImplemented IfcStructuralLoadSingleDisplacementDistortion; // (not currently used by Assimp)
 134.901 +	struct IfcPropertyBoundedValue;
 134.902 +	struct IfcRampFlightType;
 134.903 +	struct IfcMember;
 134.904 +	typedef NotImplemented IfcStructuralLoadPlanarForce; // (not currently used by Assimp)
 134.905 +	struct IfcTubeBundleType;
 134.906 +	struct IfcValveType;
 134.907 +	typedef NotImplemented IfcExternallyDefinedTextFont; // (not currently used by Assimp)
 134.908 +	struct IfcTrimmedCurve;
 134.909 +	struct IfcRelDefines;
 134.910 +	struct IfcRelDefinesByProperties;
 134.911 +	typedef NotImplemented IfcRelAssignsToControl; // (not currently used by Assimp)
 134.912 +	struct IfcActor;
 134.913 +	struct IfcOccupant;
 134.914 +	struct IfcHumidifierType;
 134.915 +	struct IfcArbitraryOpenProfileDef;
 134.916 +	typedef NotImplemented IfcRelAssignsToProjectOrder; // (not currently used by Assimp)
 134.917 +	struct IfcPermit;
 134.918 +	struct IfcOffsetCurve3D;
 134.919 +	struct IfcLightSource;
 134.920 +	struct IfcLightSourcePositional;
 134.921 +	typedef NotImplemented IfcSurfaceTexture; // (not currently used by Assimp)
 134.922 +	typedef NotImplemented IfcBlobTexture; // (not currently used by Assimp)
 134.923 +	struct IfcCompositeProfileDef;
 134.924 +	typedef NotImplemented IfcDocumentInformation; // (not currently used by Assimp)
 134.925 +	typedef NotImplemented IfcSurfaceStyleLighting; // (not currently used by Assimp)
 134.926 +	typedef NotImplemented IfcPhysicalSimpleQuantity; // (not currently used by Assimp)
 134.927 +	typedef NotImplemented IfcQuantityArea; // (not currently used by Assimp)
 134.928 +	typedef NotImplemented IfcTimeSeries; // (not currently used by Assimp)
 134.929 +	typedef NotImplemented IfcClassificationNotation; // (not currently used by Assimp)
 134.930 +	struct IfcRamp;
 134.931 +	typedef NotImplemented IfcPreDefinedItem; // (not currently used by Assimp)
 134.932 +	typedef NotImplemented IfcPreDefinedCurveFont; // (not currently used by Assimp)
 134.933 +	typedef NotImplemented IfcPreDefinedColour; // (not currently used by Assimp)
 134.934 +	typedef NotImplemented IfcCurrencyRelationship; // (not currently used by Assimp)
 134.935 +	struct IfcFlowMovingDevice;
 134.936 +	struct IfcSpaceHeaterType;
 134.937 +	struct IfcLampType;
 134.938 +	struct IfcBuildingElementComponent;
 134.939 +	struct IfcReinforcingElement;
 134.940 +	struct IfcReinforcingBar;
 134.941 +	struct IfcElectricHeaterType;
 134.942 +	struct IfcTShapeProfileDef;
 134.943 +	typedef NotImplemented IfcConstraint; // (not currently used by Assimp)
 134.944 +	typedef NotImplemented IfcObjective; // (not currently used by Assimp)
 134.945 +	struct IfcStructuralActivity;
 134.946 +	struct IfcStructuralAction;
 134.947 +	typedef NotImplemented IfcTextureCoordinate; // (not currently used by Assimp)
 134.948 +	typedef NotImplemented IfcTextureMap; // (not currently used by Assimp)
 134.949 +	typedef NotImplemented IfcMonetaryUnit; // (not currently used by Assimp)
 134.950 +	typedef NotImplemented IfcQuantityTime; // (not currently used by Assimp)
 134.951 +	typedef NotImplemented IfcTableRow; // (not currently used by Assimp)
 134.952 +	typedef NotImplemented IfcLightDistributionData; // (not currently used by Assimp)
 134.953 +	struct IfcDuctFittingType;
 134.954 +	struct IfcCartesianTransformationOperator2D;
 134.955 +	struct IfcCartesianTransformationOperator2DnonUniform;
 134.956 +	typedef NotImplemented IfcClassificationNotationFacet; // (not currently used by Assimp)
 134.957 +	typedef NotImplemented IfcRelAssociatesApproval; // (not currently used by Assimp)
 134.958 +	typedef NotImplemented IfcDraughtingPreDefinedCurveFont; // (not currently used by Assimp)
 134.959 +	typedef NotImplemented IfcStructuralLoadSingleForce; // (not currently used by Assimp)
 134.960 +	typedef NotImplemented IfcStructuralLoadSingleForceWarping; // (not currently used by Assimp)
 134.961 +	typedef NotImplemented IfcCurveStyleFontAndScaling; // (not currently used by Assimp)
 134.962 +	struct IfcVirtualElement;
 134.963 +	struct IfcRightCircularCylinder;
 134.964 +	struct IfcOutletType;
 134.965 +	struct IfcRelDecomposes;
 134.966 +	typedef NotImplemented IfcRelNests; // (not currently used by Assimp)
 134.967 +	struct IfcCovering;
 134.968 +	typedef NotImplemented IfcExternallyDefinedSymbol; // (not currently used by Assimp)
 134.969 +	typedef NotImplemented IfcIrregularTimeSeries; // (not currently used by Assimp)
 134.970 +	struct IfcPolyline;
 134.971 +	struct IfcPath;
 134.972 +	struct IfcElementComponent;
 134.973 +	struct IfcFastener;
 134.974 +	struct IfcMappedItem;
 134.975 +	typedef NotImplemented IfcMetric; // (not currently used by Assimp)
 134.976 +	typedef NotImplemented IfcDocumentReference; // (not currently used by Assimp)
 134.977 +	typedef NotImplemented IfcSectionProperties; // (not currently used by Assimp)
 134.978 +	struct IfcRectangularPyramid;
 134.979 +	typedef NotImplemented IfcRelReferencedInSpatialStructure; // (not currently used by Assimp)
 134.980 +	struct IfcCrewResource;
 134.981 +	struct IfcNamedUnit;
 134.982 +	struct IfcContextDependentUnit;
 134.983 +	struct IfcUnitaryEquipmentType;
 134.984 +	struct IfcRoof;
 134.985 +	typedef NotImplemented IfcRelAssignsTasks; // (not currently used by Assimp)
 134.986 +	struct IfcStructuralMember;
 134.987 +	typedef NotImplemented IfcRelConnectsPorts; // (not currently used by Assimp)
 134.988 +	struct IfcStyleModel;
 134.989 +	struct IfcStyledRepresentation;
 134.990 +	struct IfcSpatialStructureElement;
 134.991 +	struct IfcBuilding;
 134.992 +	struct IfcConnectedFaceSet;
 134.993 +	struct IfcOpenShell;
 134.994 +	struct IfcFacetedBrep;
 134.995 +	typedef NotImplemented IfcLocalTime; // (not currently used by Assimp)
 134.996 +	typedef NotImplemented IfcMechanicalConcreteMaterialProperties; // (not currently used by Assimp)
 134.997 +	struct IfcConic;
 134.998 +	struct IfcCoveringType;
 134.999 +	struct IfcRoundedRectangleProfileDef;
134.1000 +	struct IfcAirTerminalType;
134.1001 +	struct IfcFlowMovingDeviceType;
134.1002 +	struct IfcCompressorType;
134.1003 +	typedef NotImplemented IfcWindowPanelProperties; // (not currently used by Assimp)
134.1004 +	typedef NotImplemented IfcPreDefinedSymbol; // (not currently used by Assimp)
134.1005 +	typedef NotImplemented IfcPreDefinedTerminatorSymbol; // (not currently used by Assimp)
134.1006 +	struct IfcIShapeProfileDef;
134.1007 +	struct IfcAsymmetricIShapeProfileDef;
134.1008 +	struct IfcControllerType;
134.1009 +	struct IfcRailing;
134.1010 +	struct IfcGroup;
134.1011 +	struct IfcAsset;
134.1012 +	struct IfcMaterialDefinitionRepresentation;
134.1013 +	typedef NotImplemented IfcCurveStyleFontPattern; // (not currently used by Assimp)
134.1014 +	typedef NotImplemented IfcApprovalPropertyRelationship; // (not currently used by Assimp)
134.1015 +	struct IfcRailingType;
134.1016 +	struct IfcWall;
134.1017 +	typedef NotImplemented IfcClassificationItem; // (not currently used by Assimp)
134.1018 +	struct IfcStructuralPointConnection;
134.1019 +	typedef NotImplemented IfcConnectionGeometry; // (not currently used by Assimp)
134.1020 +	typedef NotImplemented IfcConnectionPointGeometry; // (not currently used by Assimp)
134.1021 +	typedef NotImplemented IfcTimeSeriesValue; // (not currently used by Assimp)
134.1022 +	struct IfcPropertyListValue;
134.1023 +	struct IfcFurnitureStandard;
134.1024 +	typedef NotImplemented IfcRelSchedulesCostItems; // (not currently used by Assimp)
134.1025 +	struct IfcElectricGeneratorType;
134.1026 +	struct IfcDoor;
134.1027 +	struct IfcStyledItem;
134.1028 +	struct IfcAnnotationOccurrence;
134.1029 +	struct IfcAnnotationSymbolOccurrence;
134.1030 +	struct IfcArbitraryClosedProfileDef;
134.1031 +	struct IfcArbitraryProfileDefWithVoids;
134.1032 +	struct IfcLine;
134.1033 +	typedef NotImplemented IfcMaterialLayerSet; // (not currently used by Assimp)
134.1034 +	struct IfcFlowSegmentType;
134.1035 +	struct IfcAirTerminalBoxType;
134.1036 +	typedef NotImplemented IfcRelConnectsStructuralMember; // (not currently used by Assimp)
134.1037 +	struct IfcPropertySingleValue;
134.1038 +	struct IfcAlarmType;
134.1039 +	struct IfcEllipseProfileDef;
134.1040 +	struct IfcStair;
134.1041 +	typedef NotImplemented IfcPreDefinedTextFont; // (not currently used by Assimp)
134.1042 +	typedef NotImplemented IfcTextStyleFontModel; // (not currently used by Assimp)
134.1043 +	struct IfcSurfaceStyleShading;
134.1044 +	struct IfcPumpType;
134.1045 +	struct IfcDefinedSymbol;
134.1046 +	typedef NotImplemented IfcClassificationItemRelationship; // (not currently used by Assimp)
134.1047 +	typedef NotImplemented IfcGeneralMaterialProperties; // (not currently used by Assimp)
134.1048 +	struct IfcElementComponentType;
134.1049 +	struct IfcFastenerType;
134.1050 +	struct IfcMechanicalFastenerType;
134.1051 +	typedef NotImplemented IfcPermeableCoveringProperties; // (not currently used by Assimp)
134.1052 +	struct IfcFlowFitting;
134.1053 +	typedef NotImplemented IfcApproval; // (not currently used by Assimp)
134.1054 +	typedef NotImplemented IfcShapeAspect; // (not currently used by Assimp)
134.1055 +	typedef NotImplemented IfcConstraintClassificationRelationship; // (not currently used by Assimp)
134.1056 +	struct IfcLightSourceDirectional;
134.1057 +	struct IfcSurfaceStyle;
134.1058 +	typedef NotImplemented IfcRelConnectsStructuralActivity; // (not currently used by Assimp)
134.1059 +	typedef NotImplemented IfcRelAssociatesProfileProperties; // (not currently used by Assimp)
134.1060 +	struct IfcAnnotationSurface;
134.1061 +	typedef NotImplemented IfcFuelProperties; // (not currently used by Assimp)
134.1062 +	struct IfcFlowController;
134.1063 +	typedef NotImplemented IfcFailureConnectionCondition; // (not currently used by Assimp)
134.1064 +	struct IfcBuildingStorey;
134.1065 +	struct IfcWorkControl;
134.1066 +	struct IfcWorkSchedule;
134.1067 +	typedef NotImplemented IfcTable; // (not currently used by Assimp)
134.1068 +	struct IfcDuctSegmentType;
134.1069 +	typedef NotImplemented IfcStructuralSteelProfileProperties; // (not currently used by Assimp)
134.1070 +	typedef NotImplemented IfcDraughtingPreDefinedTextFont; // (not currently used by Assimp)
134.1071 +	struct IfcFace;
134.1072 +	struct IfcStructuralSurfaceMember;
134.1073 +	struct IfcStructuralSurfaceMemberVarying;
134.1074 +	struct IfcFaceSurface;
134.1075 +	typedef NotImplemented IfcClassification; // (not currently used by Assimp)
134.1076 +	typedef NotImplemented IfcMaterialList; // (not currently used by Assimp)
134.1077 +	struct IfcCostSchedule;
134.1078 +	typedef NotImplemented IfcCoordinatedUniversalTimeOffset; // (not currently used by Assimp)
134.1079 +	struct IfcPlanarExtent;
134.1080 +	struct IfcPlanarBox;
134.1081 +	typedef NotImplemented IfcFillAreaStyle; // (not currently used by Assimp)
134.1082 +	typedef NotImplemented IfcSectionReinforcementProperties; // (not currently used by Assimp)
134.1083 +	struct IfcColourSpecification;
134.1084 +	struct IfcVector;
134.1085 +	struct IfcBeam;
134.1086 +	struct IfcColourRgb;
134.1087 +	struct IfcStructuralPlanarAction;
134.1088 +	struct IfcStructuralPlanarActionVarying;
134.1089 +	struct IfcSite;
134.1090 +	struct IfcDiscreteAccessoryType;
134.1091 +	struct IfcVibrationIsolatorType;
134.1092 +	struct IfcEvaporativeCoolerType;
134.1093 +	struct IfcDistributionChamberElementType;
134.1094 +	struct IfcFeatureElementAddition;
134.1095 +	typedef NotImplemented IfcRelAssignsToResource; // (not currently used by Assimp)
134.1096 +	struct IfcStructuredDimensionCallout;
134.1097 +	struct IfcCoolingTowerType;
134.1098 +	struct IfcCenterLineProfileDef;
134.1099 +	typedef NotImplemented IfcTextureVertex; // (not currently used by Assimp)
134.1100 +	typedef NotImplemented IfcOrganization; // (not currently used by Assimp)
134.1101 +	struct IfcWindowStyle;
134.1102 +	struct IfcLightSourceGoniometric;
134.1103 +	typedef NotImplemented IfcRibPlateProfileProperties; // (not currently used by Assimp)
134.1104 +	struct IfcTransformerType;
134.1105 +	struct IfcMemberType;
134.1106 +	struct IfcSurfaceOfLinearExtrusion;
134.1107 +	struct IfcMotorConnectionType;
134.1108 +	struct IfcFlowTreatmentDeviceType;
134.1109 +	struct IfcDuctSilencerType;
134.1110 +	typedef NotImplemented IfcWindowLiningProperties; // (not currently used by Assimp)
134.1111 +	struct IfcFurnishingElementType;
134.1112 +	struct IfcSystemFurnitureElementType;
134.1113 +	typedef NotImplemented IfcConnectionPointEccentricity; // (not currently used by Assimp)
134.1114 +	struct IfcWasteTerminalType;
134.1115 +	struct IfcBSplineCurve;
134.1116 +	struct IfcBezierCurve;
134.1117 +	typedef NotImplemented IfcDocumentInformationRelationship; // (not currently used by Assimp)
134.1118 +	struct IfcActuatorType;
134.1119 +	struct IfcDistributionControlElement;
134.1120 +	struct IfcAnnotation;
134.1121 +	typedef NotImplemented IfcRelAssociatesDocument; // (not currently used by Assimp)
134.1122 +	typedef NotImplemented IfcDoorLiningProperties; // (not currently used by Assimp)
134.1123 +	struct IfcShellBasedSurfaceModel;
134.1124 +	struct IfcActionRequest;
134.1125 +	struct IfcExtrudedAreaSolid;
134.1126 +	struct IfcSystem;
134.1127 +	struct IfcFillAreaStyleHatching;
134.1128 +	struct IfcRelVoidsElement;
134.1129 +	typedef NotImplemented IfcRelConnectsPathElements; // (not currently used by Assimp)
134.1130 +	typedef NotImplemented IfcRelSpaceBoundary; // (not currently used by Assimp)
134.1131 +	struct IfcSurfaceCurveSweptAreaSolid;
134.1132 +	struct IfcCartesianTransformationOperator3DnonUniform;
134.1133 +	typedef NotImplemented IfcRelInteractionRequirements; // (not currently used by Assimp)
134.1134 +	struct IfcCurtainWallType;
134.1135 +	typedef NotImplemented IfcQuantityLength; // (not currently used by Assimp)
134.1136 +	struct IfcEquipmentStandard;
134.1137 +	struct IfcFlowStorageDeviceType;
134.1138 +	typedef NotImplemented IfcVirtualGridIntersection; // (not currently used by Assimp)
134.1139 +	struct IfcDiameterDimension;
134.1140 +	struct IfcSwitchingDeviceType;
134.1141 +	typedef NotImplemented IfcAddress; // (not currently used by Assimp)
134.1142 +	typedef NotImplemented IfcTelecomAddress; // (not currently used by Assimp)
134.1143 +	struct IfcWindow;
134.1144 +	typedef NotImplemented IfcMechanicalSteelMaterialProperties; // (not currently used by Assimp)
134.1145 +	struct IfcFlowTreatmentDevice;
134.1146 +	typedef NotImplemented IfcRelServicesBuildings; // (not currently used by Assimp)
134.1147 +	struct IfcChillerType;
134.1148 +	typedef NotImplemented IfcRelAssignsToProduct; // (not currently used by Assimp)
134.1149 +	struct IfcRectangleHollowProfileDef;
134.1150 +	typedef NotImplemented IfcEnergyProperties; // (not currently used by Assimp)
134.1151 +	struct IfcBoxedHalfSpace;
134.1152 +	struct IfcAxis2Placement2D;
134.1153 +	struct IfcSpaceProgram;
134.1154 +	struct IfcPoint;
134.1155 +	struct IfcCartesianPoint;
134.1156 +	struct IfcBoundedSurface;
134.1157 +	struct IfcLoop;
134.1158 +	struct IfcPolyLoop;
134.1159 +	typedef NotImplemented IfcPreDefinedPointMarkerSymbol; // (not currently used by Assimp)
134.1160 +	struct IfcTerminatorSymbol;
134.1161 +	struct IfcDimensionCurveTerminator;
134.1162 +	typedef NotImplemented IfcRelProjectsElement; // (not currently used by Assimp)
134.1163 +	struct IfcTrapeziumProfileDef;
134.1164 +	struct IfcRepresentationContext;
134.1165 +	struct IfcGeometricRepresentationContext;
134.1166 +	typedef NotImplemented IfcTextStyleWithBoxCharacteristics; // (not currently used by Assimp)
134.1167 +	struct IfcCurveBoundedPlane;
134.1168 +	typedef NotImplemented IfcQuantityCount; // (not currently used by Assimp)
134.1169 +	typedef NotImplemented IfcTimeSeriesReferenceRelationship; // (not currently used by Assimp)
134.1170 +	typedef NotImplemented IfcStructuralLoadTemperature; // (not currently used by Assimp)
134.1171 +	struct IfcSIUnit;
134.1172 +	struct IfcStructuralReaction;
134.1173 +	struct IfcStructuralPointReaction;
134.1174 +	struct IfcAxis1Placement;
134.1175 +	typedef NotImplemented IfcReinforcementDefinitionProperties; // (not currently used by Assimp)
134.1176 +	struct IfcElectricApplianceType;
134.1177 +	struct IfcSensorType;
134.1178 +	struct IfcFurnishingElement;
134.1179 +	struct IfcProtectiveDeviceType;
134.1180 +	struct IfcZShapeProfileDef;
134.1181 +	struct IfcScheduleTimeControl;
134.1182 +	struct IfcRepresentationMap;
134.1183 +	struct IfcClosedShell;
134.1184 +	struct IfcBuildingElementPart;
134.1185 +	typedef NotImplemented IfcDraughtingPreDefinedColour; // (not currently used by Assimp)
134.1186 +	typedef NotImplemented IfcPostalAddress; // (not currently used by Assimp)
134.1187 +	struct IfcBlock;
134.1188 +	struct IfcLightFixtureType;
134.1189 +	struct IfcOpeningElement;
134.1190 +	struct IfcLightSourceSpot;
134.1191 +	struct IfcTendonAnchor;
134.1192 +	typedef NotImplemented IfcSurfaceStyleRefraction; // (not currently used by Assimp)
134.1193 +	struct IfcElectricFlowStorageDeviceType;
134.1194 +	typedef NotImplemented IfcFluidFlowProperties; // (not currently used by Assimp)
134.1195 +	struct IfcSphere;
134.1196 +	typedef NotImplemented IfcRelAssociatesAppliedValue; // (not currently used by Assimp)
134.1197 +	struct IfcDamperType;
134.1198 +	struct IfcProjectOrderRecord;
134.1199 +	typedef NotImplemented IfcDimensionalExponents; // (not currently used by Assimp)
134.1200 +	typedef NotImplemented IfcRelDefinesByType; // (not currently used by Assimp)
134.1201 +	struct IfcDistributionChamberElement;
134.1202 +	struct IfcMechanicalFastener;
134.1203 +	typedef NotImplemented IfcQuantityVolume; // (not currently used by Assimp)
134.1204 +	struct IfcRectangularTrimmedSurface;
134.1205 +	typedef NotImplemented IfcDateAndTime; // (not currently used by Assimp)
134.1206 +	struct IfcZone;
134.1207 +	struct IfcFanType;
134.1208 +	struct IfcGeometricSet;
134.1209 +	struct IfcFillAreaStyleTiles;
134.1210 +	typedef NotImplemented IfcPixelTexture; // (not currently used by Assimp)
134.1211 +	struct IfcCableSegmentType;
134.1212 +	struct IfcRelOverridesProperties;
134.1213 +	struct IfcMeasureWithUnit;
134.1214 +	struct IfcSlabType;
134.1215 +	struct IfcServiceLife;
134.1216 +	struct IfcFurnitureType;
134.1217 +	struct IfcCostItem;
134.1218 +	struct IfcReinforcingMesh;
134.1219 +	typedef NotImplemented IfcExtendedMaterialProperties; // (not currently used by Assimp)
134.1220 +	typedef NotImplemented IfcActorRole; // (not currently used by Assimp)
134.1221 +	struct IfcFacetedBrepWithVoids;
134.1222 +	typedef NotImplemented IfcConstraintAggregationRelationship; // (not currently used by Assimp)
134.1223 +	struct IfcGasTerminalType;
134.1224 +	typedef NotImplemented IfcRelConnectsWithEccentricity; // (not currently used by Assimp)
134.1225 +	struct IfcPile;
134.1226 +	struct IfcFillAreaStyleTileSymbolWithStyle;
134.1227 +	typedef NotImplemented IfcElectricalBaseProperties; // (not currently used by Assimp)
134.1228 +	struct IfcConstructionMaterialResource;
134.1229 +	struct IfcAnnotationCurveOccurrence;
134.1230 +	struct IfcDimensionCurve;
134.1231 +	struct IfcGeometricCurveSet;
134.1232 +	struct IfcRelAggregates;
134.1233 +	struct IfcFaceBasedSurfaceModel;
134.1234 +	struct IfcEnergyConversionDevice;
134.1235 +	struct IfcRampFlight;
134.1236 +	typedef NotImplemented IfcPropertyEnumeration; // (not currently used by Assimp)
134.1237 +	struct IfcVertexLoop;
134.1238 +	struct IfcPlate;
134.1239 +	struct IfcUShapeProfileDef;
134.1240 +	typedef NotImplemented IfcHygroscopicMaterialProperties; // (not currently used by Assimp)
134.1241 +	struct IfcFaceBound;
134.1242 +	struct IfcFaceOuterBound;
134.1243 +	struct IfcOneDirectionRepeatFactor;
134.1244 +	struct IfcBoilerType;
134.1245 +	struct IfcConstructionEquipmentResource;
134.1246 +	struct IfcComplexProperty;
134.1247 +	struct IfcFooting;
134.1248 +	typedef NotImplemented IfcOpticalMaterialProperties; // (not currently used by Assimp)
134.1249 +	struct IfcConstructionProductResource;
134.1250 +	typedef NotImplemented IfcBoundaryEdgeCondition; // (not currently used by Assimp)
134.1251 +	struct IfcDerivedProfileDef;
134.1252 +	struct IfcPropertyTableValue;
134.1253 +	typedef NotImplemented IfcRelAssignsToGroup; // (not currently used by Assimp)
134.1254 +	struct IfcFlowMeterType;
134.1255 +	struct IfcDoorStyle;
134.1256 +	typedef NotImplemented IfcRelConnectsPortToElement; // (not currently used by Assimp)
134.1257 +	typedef NotImplemented IfcRelAssociatesClassification; // (not currently used by Assimp)
134.1258 +	struct IfcUnitAssignment;
134.1259 +	struct IfcFlowTerminal;
134.1260 +	struct IfcCraneRailFShapeProfileDef;
134.1261 +	struct IfcFlowSegment;
134.1262 +	struct IfcElementQuantity;
134.1263 +	typedef NotImplemented IfcBoundaryNodeCondition; // (not currently used by Assimp)
134.1264 +	typedef NotImplemented IfcBoundaryNodeConditionWarping; // (not currently used by Assimp)
134.1265 +	struct IfcCurtainWall;
134.1266 +	struct IfcDiscreteAccessory;
134.1267 +	struct IfcGrid;
134.1268 +	struct IfcSanitaryTerminalType;
134.1269 +	typedef NotImplemented IfcSoundProperties; // (not currently used by Assimp)
134.1270 +	struct IfcSubedge;
134.1271 +	typedef NotImplemented IfcTextStyleTextModel; // (not currently used by Assimp)
134.1272 +	struct IfcFilterType;
134.1273 +	typedef NotImplemented IfcSymbolStyle; // (not currently used by Assimp)
134.1274 +	struct IfcTendon;
134.1275 +	typedef NotImplemented IfcDimensionPair; // (not currently used by Assimp)
134.1276 +	struct IfcStructuralLoadGroup;
134.1277 +	struct IfcPresentationStyleAssignment;
134.1278 +	typedef NotImplemented IfcRegularTimeSeries; // (not currently used by Assimp)
134.1279 +	struct IfcStructuralCurveMember;
134.1280 +	struct IfcLightSourceAmbient;
134.1281 +	struct IfcCondition;
134.1282 +	struct IfcPort;
134.1283 +	struct IfcSpace;
134.1284 +	struct IfcHeatExchangerType;
134.1285 +	struct IfcTankType;
134.1286 +	struct IfcInventory;
134.1287 +	typedef NotImplemented IfcTextStyle; // (not currently used by Assimp)
134.1288 +	typedef NotImplemented IfcAppliedValueRelationship; // (not currently used by Assimp)
134.1289 +	typedef NotImplemented IfcSoundValue; // (not currently used by Assimp)
134.1290 +	struct IfcTransportElementType;
134.1291 +	struct IfcAirToAirHeatRecoveryType;
134.1292 +	struct IfcStairFlight;
134.1293 +	struct IfcElectricalElement;
134.1294 +	typedef NotImplemented IfcLightIntensityDistribution; // (not currently used by Assimp)
134.1295 +	typedef NotImplemented IfcClassificationReference; // (not currently used by Assimp)
134.1296 +	struct IfcSurfaceStyleWithTextures;
134.1297 +	struct IfcBoundingBox;
134.1298 +	typedef NotImplemented IfcApplication; // (not currently used by Assimp)
134.1299 +	struct IfcWallType;
134.1300 +	struct IfcMove;
134.1301 +	struct IfcCircle;
134.1302 +	struct IfcOffsetCurve2D;
134.1303 +	typedef NotImplemented IfcMaterialLayerSetUsage; // (not currently used by Assimp)
134.1304 +	struct IfcPointOnCurve;
134.1305 +	struct IfcStructuralResultGroup;
134.1306 +	struct IfcSectionedSpine;
134.1307 +	struct IfcSlab;
134.1308 +	typedef NotImplemented IfcConnectionPortGeometry; // (not currently used by Assimp)
134.1309 +	typedef NotImplemented IfcQuantityWeight; // (not currently used by Assimp)
134.1310 +	typedef NotImplemented IfcRelAssociatesMaterial; // (not currently used by Assimp)
134.1311 +	struct IfcVertex;
134.1312 +	struct IfcVertexPoint;
134.1313 +	typedef NotImplemented IfcReferencesValueDocument; // (not currently used by Assimp)
134.1314 +	typedef NotImplemented IfcPersonAndOrganization; // (not currently used by Assimp)
134.1315 +	typedef NotImplemented IfcRelFlowControlElements; // (not currently used by Assimp)
134.1316 +	typedef NotImplemented IfcRelAssignsToProcess; // (not currently used by Assimp)
134.1317 +	struct IfcStructuralLinearAction;
134.1318 +	struct IfcStructuralLinearActionVarying;
134.1319 +	struct IfcBuildingElementProxyType;
134.1320 +	struct IfcProjectionElement;
134.1321 +	typedef NotImplemented IfcDerivedUnit; // (not currently used by Assimp)
134.1322 +	typedef NotImplemented IfcApprovalActorRelationship; // (not currently used by Assimp)
134.1323 +	struct IfcConversionBasedUnit;
134.1324 +	typedef NotImplemented IfcMaterial; // (not currently used by Assimp)
134.1325 +	struct IfcGeometricRepresentationSubContext;
134.1326 +	struct IfcAnnotationSurfaceOccurrence;
134.1327 +	typedef NotImplemented IfcPreDefinedDimensionSymbol; // (not currently used by Assimp)
134.1328 +	struct IfcRoundedEdgeFeature;
134.1329 +	typedef NotImplemented IfcRelCoversBldgElements; // (not currently used by Assimp)
134.1330 +	struct IfcElectricDistributionPoint;
134.1331 +	struct IfcCableCarrierSegmentType;
134.1332 +	typedef NotImplemented IfcStructuralLoadLinearForce; // (not currently used by Assimp)
134.1333 +	typedef NotImplemented IfcGridAxis; // (not currently used by Assimp)
134.1334 +	typedef NotImplemented IfcIrregularTimeSeriesValue; // (not currently used by Assimp)
134.1335 +	struct IfcWallStandardCase;
134.1336 +	typedef NotImplemented IfcRelOccupiesSpaces; // (not currently used by Assimp)
134.1337 +	typedef NotImplemented IfcDerivedUnitElement; // (not currently used by Assimp)
134.1338 +	struct IfcCsgSolid;
134.1339 +	struct IfcBeamType;
134.1340 +	struct IfcAnnotationFillArea;
134.1341 +	typedef NotImplemented IfcRelaxation; // (not currently used by Assimp)
134.1342 +	struct IfcStructuralCurveMemberVarying;
134.1343 +	struct IfcPointOnSurface;
134.1344 +	typedef NotImplemented IfcPropertyDependencyRelationship; // (not currently used by Assimp)
134.1345 +	typedef NotImplemented IfcVertexBasedTextureMap; // (not currently used by Assimp)
134.1346 +	struct IfcOrderAction;
134.1347 +	typedef NotImplemented IfcLibraryReference; // (not currently used by Assimp)
134.1348 +	struct IfcEdgeLoop;
134.1349 +	struct IfcAnnotationFillAreaOccurrence;
134.1350 +	typedef NotImplemented IfcRelConnectsStructuralElement; // (not currently used by Assimp)
134.1351 +	struct IfcWorkPlan;
134.1352 +	struct IfcEllipse;
134.1353 +	struct IfcProductDefinitionShape;
134.1354 +	struct IfcProjectionCurve;
134.1355 +	struct IfcElectricalCircuit;
134.1356 +	struct IfcRationalBezierCurve;
134.1357 +	struct IfcStructuralPointAction;
134.1358 +	typedef NotImplemented IfcServiceLifeFactor; // (not currently used by Assimp)
134.1359 +	typedef NotImplemented IfcThermalMaterialProperties; // (not currently used by Assimp)
134.1360 +	typedef NotImplemented IfcTextureCoordinateGenerator; // (not currently used by Assimp)
134.1361 +	struct IfcPipeSegmentType;
134.1362 +	struct IfcTwoDirectionRepeatFactor;
134.1363 +	struct IfcShapeRepresentation;
134.1364 +	struct IfcPropertySet;
134.1365 +	struct IfcSurfaceStyleRendering;
134.1366 +	struct IfcDistributionPort;
134.1367 +	typedef NotImplemented IfcImageTexture; // (not currently used by Assimp)
134.1368 +	struct IfcPipeFittingType;
134.1369 +	struct IfcTransportElement;
134.1370 +	struct IfcAnnotationTextOccurrence;
134.1371 +	typedef NotImplemented IfcConnectionSurfaceGeometry; // (not currently used by Assimp)
134.1372 +	struct IfcStructuralAnalysisModel;
134.1373 +	typedef NotImplemented IfcConnectionCurveGeometry; // (not currently used by Assimp)
134.1374 +	struct IfcConditionCriterion;
134.1375 +	typedef NotImplemented IfcWaterProperties; // (not currently used by Assimp)
134.1376 +	typedef NotImplemented IfcMaterialLayer; // (not currently used by Assimp)
134.1377 +	typedef NotImplemented IfcCostValue; // (not currently used by Assimp)
134.1378 +
134.1379 +
134.1380 +
134.1381 +    // C++ wrapper for IfcRoot
134.1382 +    struct IfcRoot :  ObjectHelper<IfcRoot,4> { IfcRoot() : Object("IfcRoot") {}
134.1383 +		IfcGloballyUniqueId::Out GlobalId;
134.1384 +		Lazy< NotImplemented > OwnerHistory;
134.1385 +		Maybe< IfcLabel::Out > Name;
134.1386 +		Maybe< IfcText::Out > Description;
134.1387 +    };
134.1388 +
134.1389 +    // C++ wrapper for IfcObjectDefinition
134.1390 +    struct IfcObjectDefinition : IfcRoot, ObjectHelper<IfcObjectDefinition,0> { IfcObjectDefinition() : Object("IfcObjectDefinition") {}
134.1391 +
134.1392 +    };
134.1393 +
134.1394 +    // C++ wrapper for IfcTypeObject
134.1395 +    struct IfcTypeObject : IfcObjectDefinition, ObjectHelper<IfcTypeObject,2> { IfcTypeObject() : Object("IfcTypeObject") {}
134.1396 +		Maybe< IfcLabel::Out > ApplicableOccurrence;
134.1397 +		Maybe< ListOf< Lazy< IfcPropertySetDefinition >, 1, 0 > > HasPropertySets;
134.1398 +    };
134.1399 +
134.1400 +    // C++ wrapper for IfcTypeProduct
134.1401 +    struct IfcTypeProduct : IfcTypeObject, ObjectHelper<IfcTypeProduct,2> { IfcTypeProduct() : Object("IfcTypeProduct") {}
134.1402 +		Maybe< ListOf< Lazy< IfcRepresentationMap >, 1, 0 > > RepresentationMaps;
134.1403 +		Maybe< IfcLabel::Out > Tag;
134.1404 +    };
134.1405 +
134.1406 +    // C++ wrapper for IfcElementType
134.1407 +    struct IfcElementType : IfcTypeProduct, ObjectHelper<IfcElementType,1> { IfcElementType() : Object("IfcElementType") {}
134.1408 +		Maybe< IfcLabel::Out > ElementType;
134.1409 +    };
134.1410 +
134.1411 +    // C++ wrapper for IfcDistributionElementType
134.1412 +    struct IfcDistributionElementType : IfcElementType, ObjectHelper<IfcDistributionElementType,0> { IfcDistributionElementType() : Object("IfcDistributionElementType") {}
134.1413 +
134.1414 +    };
134.1415 +
134.1416 +    // C++ wrapper for IfcDistributionFlowElementType
134.1417 +    struct IfcDistributionFlowElementType : IfcDistributionElementType, ObjectHelper<IfcDistributionFlowElementType,0> { IfcDistributionFlowElementType() : Object("IfcDistributionFlowElementType") {}
134.1418 +
134.1419 +    };
134.1420 +
134.1421 +    // C++ wrapper for IfcFlowControllerType
134.1422 +    struct IfcFlowControllerType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowControllerType,0> { IfcFlowControllerType() : Object("IfcFlowControllerType") {}
134.1423 +
134.1424 +    };
134.1425 +
134.1426 +    // C++ wrapper for IfcElectricTimeControlType
134.1427 +    struct IfcElectricTimeControlType : IfcFlowControllerType, ObjectHelper<IfcElectricTimeControlType,1> { IfcElectricTimeControlType() : Object("IfcElectricTimeControlType") {}
134.1428 +		IfcElectricTimeControlTypeEnum::Out PredefinedType;
134.1429 +    };
134.1430 +
134.1431 +    // C++ wrapper for IfcRepresentation
134.1432 +    struct IfcRepresentation :  ObjectHelper<IfcRepresentation,4> { IfcRepresentation() : Object("IfcRepresentation") {}
134.1433 +		Lazy< IfcRepresentationContext > ContextOfItems;
134.1434 +		Maybe< IfcLabel::Out > RepresentationIdentifier;
134.1435 +		Maybe< IfcLabel::Out > RepresentationType;
134.1436 +		ListOf< Lazy< IfcRepresentationItem >, 1, 0 > Items;
134.1437 +    };
134.1438 +
134.1439 +    // C++ wrapper for IfcShapeModel
134.1440 +    struct IfcShapeModel : IfcRepresentation, ObjectHelper<IfcShapeModel,0> { IfcShapeModel() : Object("IfcShapeModel") {}
134.1441 +
134.1442 +    };
134.1443 +
134.1444 +    // C++ wrapper for IfcTopologyRepresentation
134.1445 +    struct IfcTopologyRepresentation : IfcShapeModel, ObjectHelper<IfcTopologyRepresentation,0> { IfcTopologyRepresentation() : Object("IfcTopologyRepresentation") {}
134.1446 +
134.1447 +    };
134.1448 +
134.1449 +    // C++ wrapper for IfcRelationship
134.1450 +    struct IfcRelationship : IfcRoot, ObjectHelper<IfcRelationship,0> { IfcRelationship() : Object("IfcRelationship") {}
134.1451 +
134.1452 +    };
134.1453 +
134.1454 +    // C++ wrapper for IfcRelConnects
134.1455 +    struct IfcRelConnects : IfcRelationship, ObjectHelper<IfcRelConnects,0> { IfcRelConnects() : Object("IfcRelConnects") {}
134.1456 +
134.1457 +    };
134.1458 +
134.1459 +    // C++ wrapper for IfcFlowFittingType
134.1460 +    struct IfcFlowFittingType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowFittingType,0> { IfcFlowFittingType() : Object("IfcFlowFittingType") {}
134.1461 +
134.1462 +    };
134.1463 +
134.1464 +    // C++ wrapper for IfcCableCarrierFittingType
134.1465 +    struct IfcCableCarrierFittingType : IfcFlowFittingType, ObjectHelper<IfcCableCarrierFittingType,1> { IfcCableCarrierFittingType() : Object("IfcCableCarrierFittingType") {}
134.1466 +		IfcCableCarrierFittingTypeEnum::Out PredefinedType;
134.1467 +    };
134.1468 +
134.1469 +    // C++ wrapper for IfcEnergyConversionDeviceType
134.1470 +    struct IfcEnergyConversionDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcEnergyConversionDeviceType,0> { IfcEnergyConversionDeviceType() : Object("IfcEnergyConversionDeviceType") {}
134.1471 +
134.1472 +    };
134.1473 +
134.1474 +    // C++ wrapper for IfcCoilType
134.1475 +    struct IfcCoilType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCoilType,1> { IfcCoilType() : Object("IfcCoilType") {}
134.1476 +		IfcCoilTypeEnum::Out PredefinedType;
134.1477 +    };
134.1478 +
134.1479 +    // C++ wrapper for IfcObject
134.1480 +    struct IfcObject : IfcObjectDefinition, ObjectHelper<IfcObject,1> { IfcObject() : Object("IfcObject") {}
134.1481 +		Maybe< IfcLabel::Out > ObjectType;
134.1482 +    };
134.1483 +
134.1484 +    // C++ wrapper for IfcControl
134.1485 +    struct IfcControl : IfcObject, ObjectHelper<IfcControl,0> { IfcControl() : Object("IfcControl") {}
134.1486 +
134.1487 +    };
134.1488 +
134.1489 +    // C++ wrapper for IfcPerformanceHistory
134.1490 +    struct IfcPerformanceHistory : IfcControl, ObjectHelper<IfcPerformanceHistory,1> { IfcPerformanceHistory() : Object("IfcPerformanceHistory") {}
134.1491 +		IfcLabel::Out LifeCyclePhase;
134.1492 +    };
134.1493 +
134.1494 +    // C++ wrapper for IfcRepresentationItem
134.1495 +    struct IfcRepresentationItem :  ObjectHelper<IfcRepresentationItem,0> { IfcRepresentationItem() : Object("IfcRepresentationItem") {}
134.1496 +
134.1497 +    };
134.1498 +
134.1499 +    // C++ wrapper for IfcGeometricRepresentationItem
134.1500 +    struct IfcGeometricRepresentationItem : IfcRepresentationItem, ObjectHelper<IfcGeometricRepresentationItem,0> { IfcGeometricRepresentationItem() : Object("IfcGeometricRepresentationItem") {}
134.1501 +
134.1502 +    };
134.1503 +
134.1504 +    // C++ wrapper for IfcTextLiteral
134.1505 +    struct IfcTextLiteral : IfcGeometricRepresentationItem, ObjectHelper<IfcTextLiteral,3> { IfcTextLiteral() : Object("IfcTextLiteral") {}
134.1506 +		IfcPresentableText::Out Literal;
134.1507 +		IfcAxis2Placement::Out Placement;
134.1508 +		IfcTextPath::Out Path;
134.1509 +    };
134.1510 +
134.1511 +    // C++ wrapper for IfcTextLiteralWithExtent
134.1512 +    struct IfcTextLiteralWithExtent : IfcTextLiteral, ObjectHelper<IfcTextLiteralWithExtent,2> { IfcTextLiteralWithExtent() : Object("IfcTextLiteralWithExtent") {}
134.1513 +		Lazy< IfcPlanarExtent > Extent;
134.1514 +		IfcBoxAlignment::Out BoxAlignment;
134.1515 +    };
134.1516 +
134.1517 +    // C++ wrapper for IfcProductRepresentation
134.1518 +    struct IfcProductRepresentation :  ObjectHelper<IfcProductRepresentation,3> { IfcProductRepresentation() : Object("IfcProductRepresentation") {}
134.1519 +		Maybe< IfcLabel::Out > Name;
134.1520 +		Maybe< IfcText::Out > Description;
134.1521 +		ListOf< Lazy< IfcRepresentation >, 1, 0 > Representations;
134.1522 +    };
134.1523 +
134.1524 +    // C++ wrapper for IfcProduct
134.1525 +    struct IfcProduct : IfcObject, ObjectHelper<IfcProduct,2> { IfcProduct() : Object("IfcProduct") {}
134.1526 +		Maybe< Lazy< IfcObjectPlacement > > ObjectPlacement;
134.1527 +		Maybe< Lazy< IfcProductRepresentation > > Representation;
134.1528 +    };
134.1529 +
134.1530 +    // C++ wrapper for IfcElement
134.1531 +    struct IfcElement : IfcProduct, ObjectHelper<IfcElement,1> { IfcElement() : Object("IfcElement") {}
134.1532 +		Maybe< IfcIdentifier::Out > Tag;
134.1533 +    };
134.1534 +
134.1535 +    // C++ wrapper for IfcDistributionElement
134.1536 +    struct IfcDistributionElement : IfcElement, ObjectHelper<IfcDistributionElement,0> { IfcDistributionElement() : Object("IfcDistributionElement") {}
134.1537 +
134.1538 +    };
134.1539 +
134.1540 +    // C++ wrapper for IfcDistributionFlowElement
134.1541 +    struct IfcDistributionFlowElement : IfcDistributionElement, ObjectHelper<IfcDistributionFlowElement,0> { IfcDistributionFlowElement() : Object("IfcDistributionFlowElement") {}
134.1542 +
134.1543 +    };
134.1544 +
134.1545 +    // C++ wrapper for IfcCurve
134.1546 +    struct IfcCurve : IfcGeometricRepresentationItem, ObjectHelper<IfcCurve,0> { IfcCurve() : Object("IfcCurve") {}
134.1547 +
134.1548 +    };
134.1549 +
134.1550 +    // C++ wrapper for IfcBoundedCurve
134.1551 +    struct IfcBoundedCurve : IfcCurve, ObjectHelper<IfcBoundedCurve,0> { IfcBoundedCurve() : Object("IfcBoundedCurve") {}
134.1552 +
134.1553 +    };
134.1554 +
134.1555 +    // C++ wrapper for IfcCompositeCurve
134.1556 +    struct IfcCompositeCurve : IfcBoundedCurve, ObjectHelper<IfcCompositeCurve,2> { IfcCompositeCurve() : Object("IfcCompositeCurve") {}
134.1557 +		ListOf< Lazy< IfcCompositeCurveSegment >, 1, 0 > Segments;
134.1558 +		LOGICAL::Out SelfIntersect;
134.1559 +    };
134.1560 +
134.1561 +    // C++ wrapper for Ifc2DCompositeCurve
134.1562 +    struct Ifc2DCompositeCurve : IfcCompositeCurve, ObjectHelper<Ifc2DCompositeCurve,0> { Ifc2DCompositeCurve() : Object("Ifc2DCompositeCurve") {}
134.1563 +
134.1564 +    };
134.1565 +
134.1566 +    // C++ wrapper for IfcCartesianTransformationOperator
134.1567 +    struct IfcCartesianTransformationOperator : IfcGeometricRepresentationItem, ObjectHelper<IfcCartesianTransformationOperator,4> { IfcCartesianTransformationOperator() : Object("IfcCartesianTransformationOperator") {}
134.1568 +		Maybe< Lazy< IfcDirection > > Axis1;
134.1569 +		Maybe< Lazy< IfcDirection > > Axis2;
134.1570 +		Lazy< IfcCartesianPoint > LocalOrigin;
134.1571 +		Maybe< REAL::Out > Scale;
134.1572 +    };
134.1573 +
134.1574 +    // C++ wrapper for IfcCartesianTransformationOperator3D
134.1575 +    struct IfcCartesianTransformationOperator3D : IfcCartesianTransformationOperator, ObjectHelper<IfcCartesianTransformationOperator3D,1> { IfcCartesianTransformationOperator3D() : Object("IfcCartesianTransformationOperator3D") {}
134.1576 +		Maybe< Lazy< IfcDirection > > Axis3;
134.1577 +    };
134.1578 +
134.1579 +    // C++ wrapper for IfcProperty
134.1580 +    struct IfcProperty :  ObjectHelper<IfcProperty,2> { IfcProperty() : Object("IfcProperty") {}
134.1581 +		IfcIdentifier::Out Name;
134.1582 +		Maybe< IfcText::Out > Description;
134.1583 +    };
134.1584 +
134.1585 +    // C++ wrapper for IfcSimpleProperty
134.1586 +    struct IfcSimpleProperty : IfcProperty, ObjectHelper<IfcSimpleProperty,0> { IfcSimpleProperty() : Object("IfcSimpleProperty") {}
134.1587 +
134.1588 +    };
134.1589 +
134.1590 +    // C++ wrapper for IfcPropertyEnumeratedValue
134.1591 +    struct IfcPropertyEnumeratedValue : IfcSimpleProperty, ObjectHelper<IfcPropertyEnumeratedValue,2> { IfcPropertyEnumeratedValue() : Object("IfcPropertyEnumeratedValue") {}
134.1592 +		ListOf< IfcValue, 1, 0 >::Out EnumerationValues;
134.1593 +		Maybe< Lazy< NotImplemented > > EnumerationReference;
134.1594 +    };
134.1595 +
134.1596 +    // C++ wrapper for IfcBuildingElementType
134.1597 +    struct IfcBuildingElementType : IfcElementType, ObjectHelper<IfcBuildingElementType,0> { IfcBuildingElementType() : Object("IfcBuildingElementType") {}
134.1598 +
134.1599 +    };
134.1600 +
134.1601 +    // C++ wrapper for IfcStairFlightType
134.1602 +    struct IfcStairFlightType : IfcBuildingElementType, ObjectHelper<IfcStairFlightType,1> { IfcStairFlightType() : Object("IfcStairFlightType") {}
134.1603 +		IfcStairFlightTypeEnum::Out PredefinedType;
134.1604 +    };
134.1605 +
134.1606 +    // C++ wrapper for IfcSurface
134.1607 +    struct IfcSurface : IfcGeometricRepresentationItem, ObjectHelper<IfcSurface,0> { IfcSurface() : Object("IfcSurface") {}
134.1608 +
134.1609 +    };
134.1610 +
134.1611 +    // C++ wrapper for IfcElementarySurface
134.1612 +    struct IfcElementarySurface : IfcSurface, ObjectHelper<IfcElementarySurface,1> { IfcElementarySurface() : Object("IfcElementarySurface") {}
134.1613 +		Lazy< IfcAxis2Placement3D > Position;
134.1614 +    };
134.1615 +
134.1616 +    // C++ wrapper for IfcPlane
134.1617 +    struct IfcPlane : IfcElementarySurface, ObjectHelper<IfcPlane,0> { IfcPlane() : Object("IfcPlane") {}
134.1618 +
134.1619 +    };
134.1620 +
134.1621 +    // C++ wrapper for IfcBooleanResult
134.1622 +    struct IfcBooleanResult : IfcGeometricRepresentationItem, ObjectHelper<IfcBooleanResult,3> { IfcBooleanResult() : Object("IfcBooleanResult") {}
134.1623 +		IfcBooleanOperator::Out Operator;
134.1624 +		IfcBooleanOperand::Out FirstOperand;
134.1625 +		IfcBooleanOperand::Out SecondOperand;
134.1626 +    };
134.1627 +
134.1628 +    // C++ wrapper for IfcBooleanClippingResult
134.1629 +    struct IfcBooleanClippingResult : IfcBooleanResult, ObjectHelper<IfcBooleanClippingResult,0> { IfcBooleanClippingResult() : Object("IfcBooleanClippingResult") {}
134.1630 +
134.1631 +    };
134.1632 +
134.1633 +    // C++ wrapper for IfcSolidModel
134.1634 +    struct IfcSolidModel : IfcGeometricRepresentationItem, ObjectHelper<IfcSolidModel,0> { IfcSolidModel() : Object("IfcSolidModel") {}
134.1635 +
134.1636 +    };
134.1637 +
134.1638 +    // C++ wrapper for IfcManifoldSolidBrep
134.1639 +    struct IfcManifoldSolidBrep : IfcSolidModel, ObjectHelper<IfcManifoldSolidBrep,1> { IfcManifoldSolidBrep() : Object("IfcManifoldSolidBrep") {}
134.1640 +		Lazy< IfcClosedShell > Outer;
134.1641 +    };
134.1642 +
134.1643 +    // C++ wrapper for IfcFlowTerminalType
134.1644 +    struct IfcFlowTerminalType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowTerminalType,0> { IfcFlowTerminalType() : Object("IfcFlowTerminalType") {}
134.1645 +
134.1646 +    };
134.1647 +
134.1648 +    // C++ wrapper for IfcStackTerminalType
134.1649 +    struct IfcStackTerminalType : IfcFlowTerminalType, ObjectHelper<IfcStackTerminalType,1> { IfcStackTerminalType() : Object("IfcStackTerminalType") {}
134.1650 +		IfcStackTerminalTypeEnum::Out PredefinedType;
134.1651 +    };
134.1652 +
134.1653 +    // C++ wrapper for IfcStructuralItem
134.1654 +    struct IfcStructuralItem : IfcProduct, ObjectHelper<IfcStructuralItem,0> { IfcStructuralItem() : Object("IfcStructuralItem") {}
134.1655 +
134.1656 +    };
134.1657 +
134.1658 +    // C++ wrapper for IfcStructuralConnection
134.1659 +    struct IfcStructuralConnection : IfcStructuralItem, ObjectHelper<IfcStructuralConnection,1> { IfcStructuralConnection() : Object("IfcStructuralConnection") {}
134.1660 +		Maybe< Lazy< NotImplemented > > AppliedCondition;
134.1661 +    };
134.1662 +
134.1663 +    // C++ wrapper for IfcStructuralCurveConnection
134.1664 +    struct IfcStructuralCurveConnection : IfcStructuralConnection, ObjectHelper<IfcStructuralCurveConnection,0> { IfcStructuralCurveConnection() : Object("IfcStructuralCurveConnection") {}
134.1665 +
134.1666 +    };
134.1667 +
134.1668 +    // C++ wrapper for IfcJunctionBoxType
134.1669 +    struct IfcJunctionBoxType : IfcFlowFittingType, ObjectHelper<IfcJunctionBoxType,1> { IfcJunctionBoxType() : Object("IfcJunctionBoxType") {}
134.1670 +		IfcJunctionBoxTypeEnum::Out PredefinedType;
134.1671 +    };
134.1672 +
134.1673 +    // C++ wrapper for IfcPropertyDefinition
134.1674 +    struct IfcPropertyDefinition : IfcRoot, ObjectHelper<IfcPropertyDefinition,0> { IfcPropertyDefinition() : Object("IfcPropertyDefinition") {}
134.1675 +
134.1676 +    };
134.1677 +
134.1678 +    // C++ wrapper for IfcPropertySetDefinition
134.1679 +    struct IfcPropertySetDefinition : IfcPropertyDefinition, ObjectHelper<IfcPropertySetDefinition,0> { IfcPropertySetDefinition() : Object("IfcPropertySetDefinition") {}
134.1680 +
134.1681 +    };
134.1682 +
134.1683 +    // C++ wrapper for IfcProcess
134.1684 +    struct IfcProcess : IfcObject, ObjectHelper<IfcProcess,0> { IfcProcess() : Object("IfcProcess") {}
134.1685 +
134.1686 +    };
134.1687 +
134.1688 +    // C++ wrapper for IfcTask
134.1689 +    struct IfcTask : IfcProcess, ObjectHelper<IfcTask,5> { IfcTask() : Object("IfcTask") {}
134.1690 +		IfcIdentifier::Out TaskId;
134.1691 +		Maybe< IfcLabel::Out > Status;
134.1692 +		Maybe< IfcLabel::Out > WorkMethod;
134.1693 +		BOOLEAN::Out IsMilestone;
134.1694 +		Maybe< INTEGER::Out > Priority;
134.1695 +    };
134.1696 +
134.1697 +    // C++ wrapper for IfcRelFillsElement
134.1698 +    struct IfcRelFillsElement : IfcRelConnects, ObjectHelper<IfcRelFillsElement,2> { IfcRelFillsElement() : Object("IfcRelFillsElement") {}
134.1699 +		Lazy< IfcOpeningElement > RelatingOpeningElement;
134.1700 +		Lazy< IfcElement > RelatedBuildingElement;
134.1701 +    };
134.1702 +
134.1703 +    // C++ wrapper for IfcProcedure
134.1704 +    struct IfcProcedure : IfcProcess, ObjectHelper<IfcProcedure,3> { IfcProcedure() : Object("IfcProcedure") {}
134.1705 +		IfcIdentifier::Out ProcedureID;
134.1706 +		IfcProcedureTypeEnum::Out ProcedureType;
134.1707 +		Maybe< IfcLabel::Out > UserDefinedProcedureType;
134.1708 +    };
134.1709 +
134.1710 +    // C++ wrapper for IfcProxy
134.1711 +    struct IfcProxy : IfcProduct, ObjectHelper<IfcProxy,2> { IfcProxy() : Object("IfcProxy") {}
134.1712 +		IfcObjectTypeEnum::Out ProxyType;
134.1713 +		Maybe< IfcLabel::Out > Tag;
134.1714 +    };
134.1715 +
134.1716 +    // C++ wrapper for IfcResource
134.1717 +    struct IfcResource : IfcObject, ObjectHelper<IfcResource,0> { IfcResource() : Object("IfcResource") {}
134.1718 +
134.1719 +    };
134.1720 +
134.1721 +    // C++ wrapper for IfcConstructionResource
134.1722 +    struct IfcConstructionResource : IfcResource, ObjectHelper<IfcConstructionResource,4> { IfcConstructionResource() : Object("IfcConstructionResource") {}
134.1723 +		Maybe< IfcIdentifier::Out > ResourceIdentifier;
134.1724 +		Maybe< IfcLabel::Out > ResourceGroup;
134.1725 +		Maybe< IfcResourceConsumptionEnum::Out > ResourceConsumption;
134.1726 +		Maybe< Lazy< IfcMeasureWithUnit > > BaseQuantity;
134.1727 +    };
134.1728 +
134.1729 +    // C++ wrapper for IfcSubContractResource
134.1730 +    struct IfcSubContractResource : IfcConstructionResource, ObjectHelper<IfcSubContractResource,2> { IfcSubContractResource() : Object("IfcSubContractResource") {}
134.1731 +		Maybe< IfcActorSelect::Out > SubContractor;
134.1732 +		Maybe< IfcText::Out > JobDescription;
134.1733 +    };
134.1734 +
134.1735 +    // C++ wrapper for IfcRelContainedInSpatialStructure
134.1736 +    struct IfcRelContainedInSpatialStructure : IfcRelConnects, ObjectHelper<IfcRelContainedInSpatialStructure,2> { IfcRelContainedInSpatialStructure() : Object("IfcRelContainedInSpatialStructure") {}
134.1737 +		ListOf< Lazy< IfcProduct >, 1, 0 > RelatedElements;
134.1738 +		Lazy< IfcSpatialStructureElement > RelatingStructure;
134.1739 +    };
134.1740 +
134.1741 +    // C++ wrapper for IfcTopologicalRepresentationItem
134.1742 +    struct IfcTopologicalRepresentationItem : IfcRepresentationItem, ObjectHelper<IfcTopologicalRepresentationItem,0> { IfcTopologicalRepresentationItem() : Object("IfcTopologicalRepresentationItem") {}
134.1743 +
134.1744 +    };
134.1745 +
134.1746 +    // C++ wrapper for IfcEdge
134.1747 +    struct IfcEdge : IfcTopologicalRepresentationItem, ObjectHelper<IfcEdge,2> { IfcEdge() : Object("IfcEdge") {}
134.1748 +		Lazy< IfcVertex > EdgeStart;
134.1749 +		Lazy< IfcVertex > EdgeEnd;
134.1750 +    };
134.1751 +
134.1752 +    // C++ wrapper for IfcEdgeCurve
134.1753 +    struct IfcEdgeCurve : IfcEdge, ObjectHelper<IfcEdgeCurve,2> { IfcEdgeCurve() : Object("IfcEdgeCurve") {}
134.1754 +		Lazy< IfcCurve > EdgeGeometry;
134.1755 +		BOOLEAN::Out SameSense;
134.1756 +    };
134.1757 +
134.1758 +    // C++ wrapper for IfcPlateType
134.1759 +    struct IfcPlateType : IfcBuildingElementType, ObjectHelper<IfcPlateType,1> { IfcPlateType() : Object("IfcPlateType") {}
134.1760 +		IfcPlateTypeEnum::Out PredefinedType;
134.1761 +    };
134.1762 +
134.1763 +    // C++ wrapper for IfcObjectPlacement
134.1764 +    struct IfcObjectPlacement :  ObjectHelper<IfcObjectPlacement,0> { IfcObjectPlacement() : Object("IfcObjectPlacement") {}
134.1765 +
134.1766 +    };
134.1767 +
134.1768 +    // C++ wrapper for IfcGridPlacement
134.1769 +    struct IfcGridPlacement : IfcObjectPlacement, ObjectHelper<IfcGridPlacement,2> { IfcGridPlacement() : Object("IfcGridPlacement") {}
134.1770 +		Lazy< NotImplemented > PlacementLocation;
134.1771 +		Maybe< Lazy< NotImplemented > > PlacementRefDirection;
134.1772 +    };
134.1773 +
134.1774 +    // C++ wrapper for IfcFireSuppressionTerminalType
134.1775 +    struct IfcFireSuppressionTerminalType : IfcFlowTerminalType, ObjectHelper<IfcFireSuppressionTerminalType,1> { IfcFireSuppressionTerminalType() : Object("IfcFireSuppressionTerminalType") {}
134.1776 +		IfcFireSuppressionTerminalTypeEnum::Out PredefinedType;
134.1777 +    };
134.1778 +
134.1779 +    // C++ wrapper for IfcFlowStorageDevice
134.1780 +    struct IfcFlowStorageDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowStorageDevice,0> { IfcFlowStorageDevice() : Object("IfcFlowStorageDevice") {}
134.1781 +
134.1782 +    };
134.1783 +
134.1784 +    // C++ wrapper for IfcSweptSurface
134.1785 +    struct IfcSweptSurface : IfcSurface, ObjectHelper<IfcSweptSurface,2> { IfcSweptSurface() : Object("IfcSweptSurface") {}
134.1786 +		Lazy< IfcProfileDef > SweptCurve;
134.1787 +		Lazy< IfcAxis2Placement3D > Position;
134.1788 +    };
134.1789 +
134.1790 +    // C++ wrapper for IfcSurfaceOfRevolution
134.1791 +    struct IfcSurfaceOfRevolution : IfcSweptSurface, ObjectHelper<IfcSurfaceOfRevolution,1> { IfcSurfaceOfRevolution() : Object("IfcSurfaceOfRevolution") {}
134.1792 +		Lazy< IfcAxis1Placement > AxisPosition;
134.1793 +    };
134.1794 +
134.1795 +    // C++ wrapper for IfcOrientedEdge
134.1796 +    struct IfcOrientedEdge : IfcEdge, ObjectHelper<IfcOrientedEdge,2> { IfcOrientedEdge() : Object("IfcOrientedEdge") {}
134.1797 +		Lazy< IfcEdge > EdgeElement;
134.1798 +		BOOLEAN::Out Orientation;
134.1799 +    };
134.1800 +
134.1801 +    // C++ wrapper for IfcDirection
134.1802 +    struct IfcDirection : IfcGeometricRepresentationItem, ObjectHelper<IfcDirection,1> { IfcDirection() : Object("IfcDirection") {}
134.1803 +		ListOf< REAL, 2, 3 >::Out DirectionRatios;
134.1804 +    };
134.1805 +
134.1806 +    // C++ wrapper for IfcProfileDef
134.1807 +    struct IfcProfileDef :  ObjectHelper<IfcProfileDef,2> { IfcProfileDef() : Object("IfcProfileDef") {}
134.1808 +		IfcProfileTypeEnum::Out ProfileType;
134.1809 +		Maybe< IfcLabel::Out > ProfileName;
134.1810 +    };
134.1811 +
134.1812 +    // C++ wrapper for IfcParameterizedProfileDef
134.1813 +    struct IfcParameterizedProfileDef : IfcProfileDef, ObjectHelper<IfcParameterizedProfileDef,1> { IfcParameterizedProfileDef() : Object("IfcParameterizedProfileDef") {}
134.1814 +		Lazy< IfcAxis2Placement2D > Position;
134.1815 +    };
134.1816 +
134.1817 +    // C++ wrapper for IfcCShapeProfileDef
134.1818 +    struct IfcCShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCShapeProfileDef,6> { IfcCShapeProfileDef() : Object("IfcCShapeProfileDef") {}
134.1819 +		IfcPositiveLengthMeasure::Out Depth;
134.1820 +		IfcPositiveLengthMeasure::Out Width;
134.1821 +		IfcPositiveLengthMeasure::Out WallThickness;
134.1822 +		IfcPositiveLengthMeasure::Out Girth;
134.1823 +		Maybe< IfcPositiveLengthMeasure::Out > InternalFilletRadius;
134.1824 +		Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInX;
134.1825 +    };
134.1826 +
134.1827 +    // C++ wrapper for IfcFeatureElement
134.1828 +    struct IfcFeatureElement : IfcElement, ObjectHelper<IfcFeatureElement,0> { IfcFeatureElement() : Object("IfcFeatureElement") {}
134.1829 +
134.1830 +    };
134.1831 +
134.1832 +    // C++ wrapper for IfcFeatureElementSubtraction
134.1833 +    struct IfcFeatureElementSubtraction : IfcFeatureElement, ObjectHelper<IfcFeatureElementSubtraction,0> { IfcFeatureElementSubtraction() : Object("IfcFeatureElementSubtraction") {}
134.1834 +
134.1835 +    };
134.1836 +
134.1837 +    // C++ wrapper for IfcEdgeFeature
134.1838 +    struct IfcEdgeFeature : IfcFeatureElementSubtraction, ObjectHelper<IfcEdgeFeature,1> { IfcEdgeFeature() : Object("IfcEdgeFeature") {}
134.1839 +		Maybe< IfcPositiveLengthMeasure::Out > FeatureLength;
134.1840 +    };
134.1841 +
134.1842 +    // C++ wrapper for IfcChamferEdgeFeature
134.1843 +    struct IfcChamferEdgeFeature : IfcEdgeFeature, ObjectHelper<IfcChamferEdgeFeature,2> { IfcChamferEdgeFeature() : Object("IfcChamferEdgeFeature") {}
134.1844 +		Maybe< IfcPositiveLengthMeasure::Out > Width;
134.1845 +		Maybe< IfcPositiveLengthMeasure::Out > Height;
134.1846 +    };
134.1847 +
134.1848 +    // C++ wrapper for IfcBuildingElement
134.1849 +    struct IfcBuildingElement : IfcElement, ObjectHelper<IfcBuildingElement,0> { IfcBuildingElement() : Object("IfcBuildingElement") {}
134.1850 +
134.1851 +    };
134.1852 +
134.1853 +    // C++ wrapper for IfcColumn
134.1854 +    struct IfcColumn : IfcBuildingElement, ObjectHelper<IfcColumn,0> { IfcColumn() : Object("IfcColumn") {}
134.1855 +
134.1856 +    };
134.1857 +
134.1858 +    // C++ wrapper for IfcPropertyReferenceValue
134.1859 +    struct IfcPropertyReferenceValue : IfcSimpleProperty, ObjectHelper<IfcPropertyReferenceValue,2> { IfcPropertyReferenceValue() : Object("IfcPropertyReferenceValue") {}
134.1860 +		Maybe< IfcLabel::Out > UsageName;
134.1861 +		IfcObjectReferenceSelect::Out PropertyReference;
134.1862 +    };
134.1863 +
134.1864 +    // C++ wrapper for IfcElectricMotorType
134.1865 +    struct IfcElectricMotorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcElectricMotorType,1> { IfcElectricMotorType() : Object("IfcElectricMotorType") {}
134.1866 +		IfcElectricMotorTypeEnum::Out PredefinedType;
134.1867 +    };
134.1868 +
134.1869 +    // C++ wrapper for IfcSpatialStructureElementType
134.1870 +    struct IfcSpatialStructureElementType : IfcElementType, ObjectHelper<IfcSpatialStructureElementType,0> { IfcSpatialStructureElementType() : Object("IfcSpatialStructureElementType") {}
134.1871 +
134.1872 +    };
134.1873 +
134.1874 +    // C++ wrapper for IfcSpaceType
134.1875 +    struct IfcSpaceType : IfcSpatialStructureElementType, ObjectHelper<IfcSpaceType,1> { IfcSpaceType() : Object("IfcSpaceType") {}
134.1876 +		IfcSpaceTypeEnum::Out PredefinedType;
134.1877 +    };
134.1878 +
134.1879 +    // C++ wrapper for IfcColumnType
134.1880 +    struct IfcColumnType : IfcBuildingElementType, ObjectHelper<IfcColumnType,1> { IfcColumnType() : Object("IfcColumnType") {}
134.1881 +		IfcColumnTypeEnum::Out PredefinedType;
134.1882 +    };
134.1883 +
134.1884 +    // C++ wrapper for IfcCraneRailAShapeProfileDef
134.1885 +    struct IfcCraneRailAShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCraneRailAShapeProfileDef,12> { IfcCraneRailAShapeProfileDef() : Object("IfcCraneRailAShapeProfileDef") {}
134.1886 +		IfcPositiveLengthMeasure::Out OverallHeight;
134.1887 +		IfcPositiveLengthMeasure::Out BaseWidth2;
134.1888 +		Maybe< IfcPositiveLengthMeasure::Out > Radius;
134.1889 +		IfcPositiveLengthMeasure::Out HeadWidth;
134.1890 +		IfcPositiveLengthMeasure::Out HeadDepth2;
134.1891 +		IfcPositiveLengthMeasure::Out HeadDepth3;
134.1892 +		IfcPositiveLengthMeasure::Out WebThickness;
134.1893 +		IfcPositiveLengthMeasure::Out BaseWidth4;
134.1894 +		IfcPositiveLengthMeasure::Out BaseDepth1;
134.1895 +		IfcPositiveLengthMeasure::Out BaseDepth2;
134.1896 +		IfcPositiveLengthMeasure::Out BaseDepth3;
134.1897 +		Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY;
134.1898 +    };
134.1899 +
134.1900 +    // C++ wrapper for IfcCondenserType
134.1901 +    struct IfcCondenserType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCondenserType,1> { IfcCondenserType() : Object("IfcCondenserType") {}
134.1902 +		IfcCondenserTypeEnum::Out PredefinedType;
134.1903 +    };
134.1904 +
134.1905 +    // C++ wrapper for IfcCircleProfileDef
134.1906 +    struct IfcCircleProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCircleProfileDef,1> { IfcCircleProfileDef() : Object("IfcCircleProfileDef") {}
134.1907 +		IfcPositiveLengthMeasure::Out Radius;
134.1908 +    };
134.1909 +
134.1910 +    // C++ wrapper for IfcCircleHollowProfileDef
134.1911 +    struct IfcCircleHollowProfileDef : IfcCircleProfileDef, ObjectHelper<IfcCircleHollowProfileDef,1> { IfcCircleHollowProfileDef() : Object("IfcCircleHollowProfileDef") {}
134.1912 +		IfcPositiveLengthMeasure::Out WallThickness;
134.1913 +    };
134.1914 +
134.1915 +    // C++ wrapper for IfcPlacement
134.1916 +    struct IfcPlacement : IfcGeometricRepresentationItem, ObjectHelper<IfcPlacement,1> { IfcPlacement() : Object("IfcPlacement") {}
134.1917 +		Lazy< IfcCartesianPoint > Location;
134.1918 +    };
134.1919 +
134.1920 +    // C++ wrapper for IfcAxis2Placement3D
134.1921 +    struct IfcAxis2Placement3D : IfcPlacement, ObjectHelper<IfcAxis2Placement3D,2> { IfcAxis2Placement3D() : Object("IfcAxis2Placement3D") {}
134.1922 +		Maybe< Lazy< IfcDirection > > Axis;
134.1923 +		Maybe< Lazy< IfcDirection > > RefDirection;
134.1924 +    };
134.1925 +
134.1926 +    // C++ wrapper for IfcPresentationStyle
134.1927 +    struct IfcPresentationStyle :  ObjectHelper<IfcPresentationStyle,1> { IfcPresentationStyle() : Object("IfcPresentationStyle") {}
134.1928 +		Maybe< IfcLabel::Out > Name;
134.1929 +    };
134.1930 +
134.1931 +    // C++ wrapper for IfcEquipmentElement
134.1932 +    struct IfcEquipmentElement : IfcElement, ObjectHelper<IfcEquipmentElement,0> { IfcEquipmentElement() : Object("IfcEquipmentElement") {}
134.1933 +
134.1934 +    };
134.1935 +
134.1936 +    // C++ wrapper for IfcCompositeCurveSegment
134.1937 +    struct IfcCompositeCurveSegment : IfcGeometricRepresentationItem, ObjectHelper<IfcCompositeCurveSegment,3> { IfcCompositeCurveSegment() : Object("IfcCompositeCurveSegment") {}
134.1938 +		IfcTransitionCode::Out Transition;
134.1939 +		BOOLEAN::Out SameSense;
134.1940 +		Lazy< IfcCurve > ParentCurve;
134.1941 +    };
134.1942 +
134.1943 +    // C++ wrapper for IfcRectangleProfileDef
134.1944 +    struct IfcRectangleProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcRectangleProfileDef,2> { IfcRectangleProfileDef() : Object("IfcRectangleProfileDef") {}
134.1945 +		IfcPositiveLengthMeasure::Out XDim;
134.1946 +		IfcPositiveLengthMeasure::Out YDim;
134.1947 +    };
134.1948 +
134.1949 +    // C++ wrapper for IfcBuildingElementProxy
134.1950 +    struct IfcBuildingElementProxy : IfcBuildingElement, ObjectHelper<IfcBuildingElementProxy,1> { IfcBuildingElementProxy() : Object("IfcBuildingElementProxy") {}
134.1951 +		Maybe< IfcElementCompositionEnum::Out > CompositionType;
134.1952 +    };
134.1953 +
134.1954 +    // C++ wrapper for IfcDistributionControlElementType
134.1955 +    struct IfcDistributionControlElementType : IfcDistributionElementType, ObjectHelper<IfcDistributionControlElementType,0> { IfcDistributionControlElementType() : Object("IfcDistributionControlElementType") {}
134.1956 +
134.1957 +    };
134.1958 +
134.1959 +    // C++ wrapper for IfcFlowInstrumentType
134.1960 +    struct IfcFlowInstrumentType : IfcDistributionControlElementType, ObjectHelper<IfcFlowInstrumentType,1> { IfcFlowInstrumentType() : Object("IfcFlowInstrumentType") {}
134.1961 +		IfcFlowInstrumentTypeEnum::Out PredefinedType;
134.1962 +    };
134.1963 +
134.1964 +    // C++ wrapper for IfcDraughtingCallout
134.1965 +    struct IfcDraughtingCallout : IfcGeometricRepresentationItem, ObjectHelper<IfcDraughtingCallout,1> { IfcDraughtingCallout() : Object("IfcDraughtingCallout") {}
134.1966 +		ListOf< IfcDraughtingCalloutElement, 1, 0 >::Out Contents;
134.1967 +    };
134.1968 +
134.1969 +    // C++ wrapper for IfcDimensionCurveDirectedCallout
134.1970 +    struct IfcDimensionCurveDirectedCallout : IfcDraughtingCallout, ObjectHelper<IfcDimensionCurveDirectedCallout,0> { IfcDimensionCurveDirectedCallout() : Object("IfcDimensionCurveDirectedCallout") {}
134.1971 +
134.1972 +    };
134.1973 +
134.1974 +    // C++ wrapper for IfcLinearDimension
134.1975 +    struct IfcLinearDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcLinearDimension,0> { IfcLinearDimension() : Object("IfcLinearDimension") {}
134.1976 +
134.1977 +    };
134.1978 +
134.1979 +    // C++ wrapper for IfcElementAssembly
134.1980 +    struct IfcElementAssembly : IfcElement, ObjectHelper<IfcElementAssembly,2> { IfcElementAssembly() : Object("IfcElementAssembly") {}
134.1981 +		Maybe< IfcAssemblyPlaceEnum::Out > AssemblyPlace;
134.1982 +		IfcElementAssemblyTypeEnum::Out PredefinedType;
134.1983 +    };
134.1984 +
134.1985 +    // C++ wrapper for IfcCsgPrimitive3D
134.1986 +    struct IfcCsgPrimitive3D : IfcGeometricRepresentationItem, ObjectHelper<IfcCsgPrimitive3D,1> { IfcCsgPrimitive3D() : Object("IfcCsgPrimitive3D") {}
134.1987 +		Lazy< IfcAxis2Placement3D > Position;
134.1988 +    };
134.1989 +
134.1990 +    // C++ wrapper for IfcRightCircularCone
134.1991 +    struct IfcRightCircularCone : IfcCsgPrimitive3D, ObjectHelper<IfcRightCircularCone,2> { IfcRightCircularCone() : Object("IfcRightCircularCone") {}
134.1992 +		IfcPositiveLengthMeasure::Out Height;
134.1993 +		IfcPositiveLengthMeasure::Out BottomRadius;
134.1994 +    };
134.1995 +
134.1996 +    // C++ wrapper for IfcProjectOrder
134.1997 +    struct IfcProjectOrder : IfcControl, ObjectHelper<IfcProjectOrder,3> { IfcProjectOrder() : Object("IfcProjectOrder") {}
134.1998 +		IfcIdentifier::Out ID;
134.1999 +		IfcProjectOrderTypeEnum::Out PredefinedType;
134.2000 +		Maybe< IfcLabel::Out > Status;
134.2001 +    };
134.2002 +
134.2003 +    // C++ wrapper for IfcLShapeProfileDef
134.2004 +    struct IfcLShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcLShapeProfileDef,8> { IfcLShapeProfileDef() : Object("IfcLShapeProfileDef") {}
134.2005 +		IfcPositiveLengthMeasure::Out Depth;
134.2006 +		Maybe< IfcPositiveLengthMeasure::Out > Width;
134.2007 +		IfcPositiveLengthMeasure::Out Thickness;
134.2008 +		Maybe< IfcPositiveLengthMeasure::Out > FilletRadius;
134.2009 +		Maybe< IfcPositiveLengthMeasure::Out > EdgeRadius;
134.2010 +		Maybe< IfcPlaneAngleMeasure::Out > LegSlope;
134.2011 +		Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInX;
134.2012 +		Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY;
134.2013 +    };
134.2014 +
134.2015 +    // C++ wrapper for IfcAngularDimension
134.2016 +    struct IfcAngularDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcAngularDimension,0> { IfcAngularDimension() : Object("IfcAngularDimension") {}
134.2017 +
134.2018 +    };
134.2019 +
134.2020 +    // C++ wrapper for IfcLocalPlacement
134.2021 +    struct IfcLocalPlacement : IfcObjectPlacement, ObjectHelper<IfcLocalPlacement,2> { IfcLocalPlacement() : Object("IfcLocalPlacement") {}
134.2022 +		Maybe< Lazy< IfcObjectPlacement > > PlacementRelTo;
134.2023 +		IfcAxis2Placement::Out RelativePlacement;
134.2024 +    };
134.2025 +
134.2026 +    // C++ wrapper for IfcSweptAreaSolid
134.2027 +    struct IfcSweptAreaSolid : IfcSolidModel, ObjectHelper<IfcSweptAreaSolid,2> { IfcSweptAreaSolid() : Object("IfcSweptAreaSolid") {}
134.2028 +		Lazy< IfcProfileDef > SweptArea;
134.2029 +		Lazy< IfcAxis2Placement3D > Position;
134.2030 +    };
134.2031 +
134.2032 +    // C++ wrapper for IfcRevolvedAreaSolid
134.2033 +    struct IfcRevolvedAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcRevolvedAreaSolid,2> { IfcRevolvedAreaSolid() : Object("IfcRevolvedAreaSolid") {}
134.2034 +		Lazy< IfcAxis1Placement > Axis;
134.2035 +		IfcPlaneAngleMeasure::Out Angle;
134.2036 +    };
134.2037 +
134.2038 +    // C++ wrapper for IfcStructuralSurfaceConnection
134.2039 +    struct IfcStructuralSurfaceConnection : IfcStructuralConnection, ObjectHelper<IfcStructuralSurfaceConnection,0> { IfcStructuralSurfaceConnection() : Object("IfcStructuralSurfaceConnection") {}
134.2040 +
134.2041 +    };
134.2042 +
134.2043 +    // C++ wrapper for IfcRadiusDimension
134.2044 +    struct IfcRadiusDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcRadiusDimension,0> { IfcRadiusDimension() : Object("IfcRadiusDimension") {}
134.2045 +
134.2046 +    };
134.2047 +
134.2048 +    // C++ wrapper for IfcSweptDiskSolid
134.2049 +    struct IfcSweptDiskSolid : IfcSolidModel, ObjectHelper<IfcSweptDiskSolid,5> { IfcSweptDiskSolid() : Object("IfcSweptDiskSolid") {}
134.2050 +		Lazy< IfcCurve > Directrix;
134.2051 +		IfcPositiveLengthMeasure::Out Radius;
134.2052 +		Maybe< IfcPositiveLengthMeasure::Out > InnerRadius;
134.2053 +		IfcParameterValue::Out StartParam;
134.2054 +		IfcParameterValue::Out EndParam;
134.2055 +    };
134.2056 +
134.2057 +    // C++ wrapper for IfcHalfSpaceSolid
134.2058 +    struct IfcHalfSpaceSolid : IfcGeometricRepresentationItem, ObjectHelper<IfcHalfSpaceSolid,2> { IfcHalfSpaceSolid() : Object("IfcHalfSpaceSolid") {}
134.2059 +		Lazy< IfcSurface > BaseSurface;
134.2060 +		BOOLEAN::Out AgreementFlag;
134.2061 +    };
134.2062 +
134.2063 +    // C++ wrapper for IfcPolygonalBoundedHalfSpace
134.2064 +    struct IfcPolygonalBoundedHalfSpace : IfcHalfSpaceSolid, ObjectHelper<IfcPolygonalBoundedHalfSpace,2> { IfcPolygonalBoundedHalfSpace() : Object("IfcPolygonalBoundedHalfSpace") {}
134.2065 +		Lazy< IfcAxis2Placement3D > Position;
134.2066 +		Lazy< IfcBoundedCurve > PolygonalBoundary;
134.2067 +    };
134.2068 +
134.2069 +    // C++ wrapper for IfcTimeSeriesSchedule
134.2070 +    struct IfcTimeSeriesSchedule : IfcControl, ObjectHelper<IfcTimeSeriesSchedule,3> { IfcTimeSeriesSchedule() : Object("IfcTimeSeriesSchedule") {}
134.2071 +		Maybe< ListOf< IfcDateTimeSelect, 1, 0 >::Out > ApplicableDates;
134.2072 +		IfcTimeSeriesScheduleTypeEnum::Out TimeSeriesScheduleType;
134.2073 +		Lazy< NotImplemented > TimeSeries;
134.2074 +    };
134.2075 +
134.2076 +    // C++ wrapper for IfcCooledBeamType
134.2077 +    struct IfcCooledBeamType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCooledBeamType,1> { IfcCooledBeamType() : Object("IfcCooledBeamType") {}
134.2078 +		IfcCooledBeamTypeEnum::Out PredefinedType;
134.2079 +    };
134.2080 +
134.2081 +    // C++ wrapper for IfcProject
134.2082 +    struct IfcProject : IfcObject, ObjectHelper<IfcProject,4> { IfcProject() : Object("IfcProject") {}
134.2083 +		Maybe< IfcLabel::Out > LongName;
134.2084 +		Maybe< IfcLabel::Out > Phase;
134.2085 +		ListOf< Lazy< IfcRepresentationContext >, 1, 0 > RepresentationContexts;
134.2086 +		Lazy< IfcUnitAssignment > UnitsInContext;
134.2087 +    };
134.2088 +
134.2089 +    // C++ wrapper for IfcEvaporatorType
134.2090 +    struct IfcEvaporatorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcEvaporatorType,1> { IfcEvaporatorType() : Object("IfcEvaporatorType") {}
134.2091 +		IfcEvaporatorTypeEnum::Out PredefinedType;
134.2092 +    };
134.2093 +
134.2094 +    // C++ wrapper for IfcLaborResource
134.2095 +    struct IfcLaborResource : IfcConstructionResource, ObjectHelper<IfcLaborResource,1> { IfcLaborResource() : Object("IfcLaborResource") {}
134.2096 +		Maybe< IfcText::Out > SkillSet;
134.2097 +    };
134.2098 +
134.2099 +    // C++ wrapper for IfcPropertyBoundedValue
134.2100 +    struct IfcPropertyBoundedValue : IfcSimpleProperty, ObjectHelper<IfcPropertyBoundedValue,3> { IfcPropertyBoundedValue() : Object("IfcPropertyBoundedValue") {}
134.2101 +		Maybe< IfcValue::Out > UpperBoundValue;
134.2102 +		Maybe< IfcValue::Out > LowerBoundValue;
134.2103 +		Maybe< IfcUnit::Out > Unit;
134.2104 +    };
134.2105 +
134.2106 +    // C++ wrapper for IfcRampFlightType
134.2107 +    struct IfcRampFlightType : IfcBuildingElementType, ObjectHelper<IfcRampFlightType,1> { IfcRampFlightType() : Object("IfcRampFlightType") {}
134.2108 +		IfcRampFlightTypeEnum::Out PredefinedType;
134.2109 +    };
134.2110 +
134.2111 +    // C++ wrapper for IfcMember
134.2112 +    struct IfcMember : IfcBuildingElement, ObjectHelper<IfcMember,0> { IfcMember() : Object("IfcMember") {}
134.2113 +
134.2114 +    };
134.2115 +
134.2116 +    // C++ wrapper for IfcTubeBundleType
134.2117 +    struct IfcTubeBundleType : IfcEnergyConversionDeviceType, ObjectHelper<IfcTubeBundleType,1> { IfcTubeBundleType() : Object("IfcTubeBundleType") {}
134.2118 +		IfcTubeBundleTypeEnum::Out PredefinedType;
134.2119 +    };
134.2120 +
134.2121 +    // C++ wrapper for IfcValveType
134.2122 +    struct IfcValveType : IfcFlowControllerType, ObjectHelper<IfcValveType,1> { IfcValveType() : Object("IfcValveType") {}
134.2123 +		IfcValveTypeEnum::Out PredefinedType;
134.2124 +    };
134.2125 +
134.2126 +    // C++ wrapper for IfcTrimmedCurve
134.2127 +    struct IfcTrimmedCurve : IfcBoundedCurve, ObjectHelper<IfcTrimmedCurve,5> { IfcTrimmedCurve() : Object("IfcTrimmedCurve") {}
134.2128 +		Lazy< IfcCurve > BasisCurve;
134.2129 +		ListOf< IfcTrimmingSelect, 1, 2 >::Out Trim1;
134.2130 +		ListOf< IfcTrimmingSelect, 1, 2 >::Out Trim2;
134.2131 +		BOOLEAN::Out SenseAgreement;
134.2132 +		IfcTrimmingPreference::Out MasterRepresentation;
134.2133 +    };
134.2134 +
134.2135 +    // C++ wrapper for IfcRelDefines
134.2136 +    struct IfcRelDefines : IfcRelationship, ObjectHelper<IfcRelDefines,1> { IfcRelDefines() : Object("IfcRelDefines") {}
134.2137 +		ListOf< Lazy< IfcObject >, 1, 0 > RelatedObjects;
134.2138 +    };
134.2139 +
134.2140 +    // C++ wrapper for IfcRelDefinesByProperties
134.2141 +    struct IfcRelDefinesByProperties : IfcRelDefines, ObjectHelper<IfcRelDefinesByProperties,1> { IfcRelDefinesByProperties() : Object("IfcRelDefinesByProperties") {}
134.2142 +		Lazy< IfcPropertySetDefinition > RelatingPropertyDefinition;
134.2143 +    };
134.2144 +
134.2145 +    // C++ wrapper for IfcActor
134.2146 +    struct IfcActor : IfcObject, ObjectHelper<IfcActor,1> { IfcActor() : Object("IfcActor") {}
134.2147 +		IfcActorSelect::Out TheActor;
134.2148 +    };
134.2149 +
134.2150 +    // C++ wrapper for IfcOccupant
134.2151 +    struct IfcOccupant : IfcActor, ObjectHelper<IfcOccupant,1> { IfcOccupant() : Object("IfcOccupant") {}
134.2152 +		IfcOccupantTypeEnum::Out PredefinedType;
134.2153 +    };
134.2154 +
134.2155 +    // C++ wrapper for IfcHumidifierType
134.2156 +    struct IfcHumidifierType : IfcEnergyConversionDeviceType, ObjectHelper<IfcHumidifierType,1> { IfcHumidifierType() : Object("IfcHumidifierType") {}
134.2157 +		IfcHumidifierTypeEnum::Out PredefinedType;
134.2158 +    };
134.2159 +
134.2160 +    // C++ wrapper for IfcArbitraryOpenProfileDef
134.2161 +    struct IfcArbitraryOpenProfileDef : IfcProfileDef, ObjectHelper<IfcArbitraryOpenProfileDef,1> { IfcArbitraryOpenProfileDef() : Object("IfcArbitraryOpenProfileDef") {}
134.2162 +		Lazy< IfcBoundedCurve > Curve;
134.2163 +    };
134.2164 +
134.2165 +    // C++ wrapper for IfcPermit
134.2166 +    struct IfcPermit : IfcControl, ObjectHelper<IfcPermit,1> { IfcPermit() : Object("IfcPermit") {}
134.2167 +		IfcIdentifier::Out PermitID;
134.2168 +    };
134.2169 +
134.2170 +    // C++ wrapper for IfcOffsetCurve3D
134.2171 +    struct IfcOffsetCurve3D : IfcCurve, ObjectHelper<IfcOffsetCurve3D,4> { IfcOffsetCurve3D() : Object("IfcOffsetCurve3D") {}
134.2172 +		Lazy< IfcCurve > BasisCurve;
134.2173 +		IfcLengthMeasure::Out Distance;
134.2174 +		LOGICAL::Out SelfIntersect;
134.2175 +		Lazy< IfcDirection > RefDirection;
134.2176 +    };
134.2177 +
134.2178 +    // C++ wrapper for IfcLightSource
134.2179 +    struct IfcLightSource : IfcGeometricRepresentationItem, ObjectHelper<IfcLightSource,4> { IfcLightSource() : Object("IfcLightSource") {}
134.2180 +		Maybe< IfcLabel::Out > Name;
134.2181 +		Lazy< IfcColourRgb > LightColour;
134.2182 +		Maybe< IfcNormalisedRatioMeasure::Out > AmbientIntensity;
134.2183 +		Maybe< IfcNormalisedRatioMeasure::Out > Intensity;
134.2184 +    };
134.2185 +
134.2186 +    // C++ wrapper for IfcLightSourcePositional
134.2187 +    struct IfcLightSourcePositional : IfcLightSource, ObjectHelper<IfcLightSourcePositional,5> { IfcLightSourcePositional() : Object("IfcLightSourcePositional") {}
134.2188 +		Lazy< IfcCartesianPoint > Position;
134.2189 +		IfcPositiveLengthMeasure::Out Radius;
134.2190 +		IfcReal::Out ConstantAttenuation;
134.2191 +		IfcReal::Out DistanceAttenuation;
134.2192 +		IfcReal::Out QuadricAttenuation;
134.2193 +    };
134.2194 +
134.2195 +    // C++ wrapper for IfcCompositeProfileDef
134.2196 +    struct IfcCompositeProfileDef : IfcProfileDef, ObjectHelper<IfcCompositeProfileDef,2> { IfcCompositeProfileDef() : Object("IfcCompositeProfileDef") {}
134.2197 +		ListOf< Lazy< IfcProfileDef >, 2, 0 > Profiles;
134.2198 +		Maybe< IfcLabel::Out > Label;
134.2199 +    };
134.2200 +
134.2201 +    // C++ wrapper for IfcRamp
134.2202 +    struct IfcRamp : IfcBuildingElement, ObjectHelper<IfcRamp,1> { IfcRamp() : Object("IfcRamp") {}
134.2203 +		IfcRampTypeEnum::Out ShapeType;
134.2204 +    };
134.2205 +
134.2206 +    // C++ wrapper for IfcFlowMovingDevice
134.2207 +    struct IfcFlowMovingDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowMovingDevice,0> { IfcFlowMovingDevice() : Object("IfcFlowMovingDevice") {}
134.2208 +
134.2209 +    };
134.2210 +
134.2211 +    // C++ wrapper for IfcSpaceHeaterType
134.2212 +    struct IfcSpaceHeaterType : IfcEnergyConversionDeviceType, ObjectHelper<IfcSpaceHeaterType,1> { IfcSpaceHeaterType() : Object("IfcSpaceHeaterType") {}
134.2213 +		IfcSpaceHeaterTypeEnum::Out PredefinedType;
134.2214 +    };
134.2215 +
134.2216 +    // C++ wrapper for IfcLampType
134.2217 +    struct IfcLampType : IfcFlowTerminalType, ObjectHelper<IfcLampType,1> { IfcLampType() : Object("IfcLampType") {}
134.2218 +		IfcLampTypeEnum::Out PredefinedType;
134.2219 +    };
134.2220 +
134.2221 +    // C++ wrapper for IfcBuildingElementComponent
134.2222 +    struct IfcBuildingElementComponent : IfcBuildingElement, ObjectHelper<IfcBuildingElementComponent,0> { IfcBuildingElementComponent() : Object("IfcBuildingElementComponent") {}
134.2223 +
134.2224 +    };
134.2225 +
134.2226 +    // C++ wrapper for IfcReinforcingElement
134.2227 +    struct IfcReinforcingElement : IfcBuildingElementComponent, ObjectHelper<IfcReinforcingElement,1> { IfcReinforcingElement() : Object("IfcReinforcingElement") {}
134.2228 +		Maybe< IfcLabel::Out > SteelGrade;
134.2229 +    };
134.2230 +
134.2231 +    // C++ wrapper for IfcReinforcingBar
134.2232 +    struct IfcReinforcingBar : IfcReinforcingElement, ObjectHelper<IfcReinforcingBar,5> { IfcReinforcingBar() : Object("IfcReinforcingBar") {}
134.2233 +		IfcPositiveLengthMeasure::Out NominalDiameter;
134.2234 +		IfcAreaMeasure::Out CrossSectionArea;
134.2235 +		Maybe< IfcPositiveLengthMeasure::Out > BarLength;
134.2236 +		IfcReinforcingBarRoleEnum::Out BarRole;
134.2237 +		Maybe< IfcReinforcingBarSurfaceEnum::Out > BarSurface;
134.2238 +    };
134.2239 +
134.2240 +    // C++ wrapper for IfcElectricHeaterType
134.2241 +    struct IfcElectricHeaterType : IfcFlowTerminalType, ObjectHelper<IfcElectricHeaterType,1> { IfcElectricHeaterType() : Object("IfcElectricHeaterType") {}
134.2242 +		IfcElectricHeaterTypeEnum::Out PredefinedType;
134.2243 +    };
134.2244 +
134.2245 +    // C++ wrapper for IfcTShapeProfileDef
134.2246 +    struct IfcTShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcTShapeProfileDef,10> { IfcTShapeProfileDef() : Object("IfcTShapeProfileDef") {}
134.2247 +		IfcPositiveLengthMeasure::Out Depth;
134.2248 +		IfcPositiveLengthMeasure::Out FlangeWidth;
134.2249 +		IfcPositiveLengthMeasure::Out WebThickness;
134.2250 +		IfcPositiveLengthMeasure::Out FlangeThickness;
134.2251 +		Maybe< IfcPositiveLengthMeasure::Out > FilletRadius;
134.2252 +		Maybe< IfcPositiveLengthMeasure::Out > FlangeEdgeRadius;
134.2253 +		Maybe< IfcPositiveLengthMeasure::Out > WebEdgeRadius;
134.2254 +		Maybe< IfcPlaneAngleMeasure::Out > WebSlope;
134.2255 +		Maybe< IfcPlaneAngleMeasure::Out > FlangeSlope;
134.2256 +		Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY;
134.2257 +    };
134.2258 +
134.2259 +    // C++ wrapper for IfcStructuralActivity
134.2260 +    struct IfcStructuralActivity : IfcProduct, ObjectHelper<IfcStructuralActivity,2> { IfcStructuralActivity() : Object("IfcStructuralActivity") {}
134.2261 +		Lazy< NotImplemented > AppliedLoad;
134.2262 +		IfcGlobalOrLocalEnum::Out GlobalOrLocal;
134.2263 +    };
134.2264 +
134.2265 +    // C++ wrapper for IfcStructuralAction
134.2266 +    struct IfcStructuralAction : IfcStructuralActivity, ObjectHelper<IfcStructuralAction,2> { IfcStructuralAction() : Object("IfcStructuralAction") {}
134.2267 +		BOOLEAN::Out DestabilizingLoad;
134.2268 +		Maybe< Lazy< IfcStructuralReaction > > CausedBy;
134.2269 +    };
134.2270 +
134.2271 +    // C++ wrapper for IfcDuctFittingType
134.2272 +    struct IfcDuctFittingType : IfcFlowFittingType, ObjectHelper<IfcDuctFittingType,1> { IfcDuctFittingType() : Object("IfcDuctFittingType") {}
134.2273 +		IfcDuctFittingTypeEnum::Out PredefinedType;
134.2274 +    };
134.2275 +
134.2276 +    // C++ wrapper for IfcCartesianTransformationOperator2D
134.2277 +    struct IfcCartesianTransformationOperator2D : IfcCartesianTransformationOperator, ObjectHelper<IfcCartesianTransformationOperator2D,0> { IfcCartesianTransformationOperator2D() : Object("IfcCartesianTransformationOperator2D") {}
134.2278 +
134.2279 +    };
134.2280 +
134.2281 +    // C++ wrapper for IfcCartesianTransformationOperator2DnonUniform
134.2282 +    struct IfcCartesianTransformationOperator2DnonUniform : IfcCartesianTransformationOperator2D, ObjectHelper<IfcCartesianTransformationOperator2DnonUniform,1> { IfcCartesianTransformationOperator2DnonUniform() : Object("IfcCartesianTransformationOperator2DnonUniform") {}
134.2283 +		Maybe< REAL::Out > Scale2;
134.2284 +    };
134.2285 +
134.2286 +    // C++ wrapper for IfcVirtualElement
134.2287 +    struct IfcVirtualElement : IfcElement, ObjectHelper<IfcVirtualElement,0> { IfcVirtualElement() : Object("IfcVirtualElement") {}
134.2288 +
134.2289 +    };
134.2290 +
134.2291 +    // C++ wrapper for IfcRightCircularCylinder
134.2292 +    struct IfcRightCircularCylinder : IfcCsgPrimitive3D, ObjectHelper<IfcRightCircularCylinder,2> { IfcRightCircularCylinder() : Object("IfcRightCircularCylinder") {}
134.2293 +		IfcPositiveLengthMeasure::Out Height;
134.2294 +		IfcPositiveLengthMeasure::Out Radius;
134.2295 +    };
134.2296 +
134.2297 +    // C++ wrapper for IfcOutletType
134.2298 +    struct IfcOutletType : IfcFlowTerminalType, ObjectHelper<IfcOutletType,1> { IfcOutletType() : Object("IfcOutletType") {}
134.2299 +		IfcOutletTypeEnum::Out PredefinedType;
134.2300 +    };
134.2301 +
134.2302 +    // C++ wrapper for IfcRelDecomposes
134.2303 +    struct IfcRelDecomposes : IfcRelationship, ObjectHelper<IfcRelDecomposes,2> { IfcRelDecomposes() : Object("IfcRelDecomposes") {}
134.2304 +		Lazy< IfcObjectDefinition > RelatingObject;
134.2305 +		ListOf< Lazy< IfcObjectDefinition >, 1, 0 > RelatedObjects;
134.2306 +    };
134.2307 +
134.2308 +    // C++ wrapper for IfcCovering
134.2309 +    struct IfcCovering : IfcBuildingElement, ObjectHelper<IfcCovering,1> { IfcCovering() : Object("IfcCovering") {}
134.2310 +		Maybe< IfcCoveringTypeEnum::Out > PredefinedType;
134.2311 +    };
134.2312 +
134.2313 +    // C++ wrapper for IfcPolyline
134.2314 +    struct IfcPolyline : IfcBoundedCurve, ObjectHelper<IfcPolyline,1> { IfcPolyline() : Object("IfcPolyline") {}
134.2315 +		ListOf< Lazy< IfcCartesianPoint >, 2, 0 > Points;
134.2316 +    };
134.2317 +
134.2318 +    // C++ wrapper for IfcPath
134.2319 +    struct IfcPath : IfcTopologicalRepresentationItem, ObjectHelper<IfcPath,1> { IfcPath() : Object("IfcPath") {}
134.2320 +		ListOf< Lazy< IfcOrientedEdge >, 1, 0 > EdgeList;
134.2321 +    };
134.2322 +
134.2323 +    // C++ wrapper for IfcElementComponent
134.2324 +    struct IfcElementComponent : IfcElement, ObjectHelper<IfcElementComponent,0> { IfcElementComponent() : Object("IfcElementComponent") {}
134.2325 +
134.2326 +    };
134.2327 +
134.2328 +    // C++ wrapper for IfcFastener
134.2329 +    struct IfcFastener : IfcElementComponent, ObjectHelper<IfcFastener,0> { IfcFastener() : Object("IfcFastener") {}
134.2330 +
134.2331 +    };
134.2332 +
134.2333 +    // C++ wrapper for IfcMappedItem
134.2334 +    struct IfcMappedItem : IfcRepresentationItem, ObjectHelper<IfcMappedItem,2> { IfcMappedItem() : Object("IfcMappedItem") {}
134.2335 +		Lazy< IfcRepresentationMap > MappingSource;
134.2336 +		Lazy< IfcCartesianTransformationOperator > MappingTarget;
134.2337 +    };
134.2338 +
134.2339 +    // C++ wrapper for IfcRectangularPyramid
134.2340 +    struct IfcRectangularPyramid : IfcCsgPrimitive3D, ObjectHelper<IfcRectangularPyramid,3> { IfcRectangularPyramid() : Object("IfcRectangularPyramid") {}
134.2341 +		IfcPositiveLengthMeasure::Out XLength;
134.2342 +		IfcPositiveLengthMeasure::Out YLength;
134.2343 +		IfcPositiveLengthMeasure::Out Height;
134.2344 +    };
134.2345 +
134.2346 +    // C++ wrapper for IfcCrewResource
134.2347 +    struct IfcCrewResource : IfcConstructionResource, ObjectHelper<IfcCrewResource,0> { IfcCrewResource() : Object("IfcCrewResource") {}
134.2348 +
134.2349 +    };
134.2350 +
134.2351 +    // C++ wrapper for IfcNamedUnit
134.2352 +    struct IfcNamedUnit :  ObjectHelper<IfcNamedUnit,2> { IfcNamedUnit() : Object("IfcNamedUnit") {}
134.2353 +		Lazy< NotImplemented > Dimensions;
134.2354 +		IfcUnitEnum::Out UnitType;
134.2355 +    };
134.2356 +
134.2357 +    // C++ wrapper for IfcContextDependentUnit
134.2358 +    struct IfcContextDependentUnit : IfcNamedUnit, ObjectHelper<IfcContextDependentUnit,1> { IfcContextDependentUnit() : Object("IfcContextDependentUnit") {}
134.2359 +		IfcLabel::Out Name;
134.2360 +    };
134.2361 +
134.2362 +    // C++ wrapper for IfcUnitaryEquipmentType
134.2363 +    struct IfcUnitaryEquipmentType : IfcEnergyConversionDeviceType, ObjectHelper<IfcUnitaryEquipmentType,1> { IfcUnitaryEquipmentType() : Object("IfcUnitaryEquipmentType") {}
134.2364 +		IfcUnitaryEquipmentTypeEnum::Out PredefinedType;
134.2365 +    };
134.2366 +
134.2367 +    // C++ wrapper for IfcRoof
134.2368 +    struct IfcRoof : IfcBuildingElement, ObjectHelper<IfcRoof,1> { IfcRoof() : Object("IfcRoof") {}
134.2369 +		IfcRoofTypeEnum::Out ShapeType;
134.2370 +    };
134.2371 +
134.2372 +    // C++ wrapper for IfcStructuralMember
134.2373 +    struct IfcStructuralMember : IfcStructuralItem, ObjectHelper<IfcStructuralMember,0> { IfcStructuralMember() : Object("IfcStructuralMember") {}
134.2374 +
134.2375 +    };
134.2376 +
134.2377 +    // C++ wrapper for IfcStyleModel
134.2378 +    struct IfcStyleModel : IfcRepresentation, ObjectHelper<IfcStyleModel,0> { IfcStyleModel() : Object("IfcStyleModel") {}
134.2379 +
134.2380 +    };
134.2381 +
134.2382 +    // C++ wrapper for IfcStyledRepresentation
134.2383 +    struct IfcStyledRepresentation : IfcStyleModel, ObjectHelper<IfcStyledRepresentation,0> { IfcStyledRepresentation() : Object("IfcStyledRepresentation") {}
134.2384 +
134.2385 +    };
134.2386 +
134.2387 +    // C++ wrapper for IfcSpatialStructureElement
134.2388 +    struct IfcSpatialStructureElement : IfcProduct, ObjectHelper<IfcSpatialStructureElement,2> { IfcSpatialStructureElement() : Object("IfcSpatialStructureElement") {}
134.2389 +		Maybe< IfcLabel::Out > LongName;
134.2390 +		IfcElementCompositionEnum::Out CompositionType;
134.2391 +    };
134.2392 +
134.2393 +    // C++ wrapper for IfcBuilding
134.2394 +    struct IfcBuilding : IfcSpatialStructureElement, ObjectHelper<IfcBuilding,3> { IfcBuilding() : Object("IfcBuilding") {}
134.2395 +		Maybe< IfcLengthMeasure::Out > ElevationOfRefHeight;
134.2396 +		Maybe< IfcLengthMeasure::Out > ElevationOfTerrain;
134.2397 +		Maybe< Lazy< NotImplemented > > BuildingAddress;
134.2398 +    };
134.2399 +
134.2400 +    // C++ wrapper for IfcConnectedFaceSet
134.2401 +    struct IfcConnectedFaceSet : IfcTopologicalRepresentationItem, ObjectHelper<IfcConnectedFaceSet,1> { IfcConnectedFaceSet() : Object("IfcConnectedFaceSet") {}
134.2402 +		ListOf< Lazy< IfcFace >, 1, 0 > CfsFaces;
134.2403 +    };
134.2404 +
134.2405 +    // C++ wrapper for IfcOpenShell
134.2406 +    struct IfcOpenShell : IfcConnectedFaceSet, ObjectHelper<IfcOpenShell,0> { IfcOpenShell() : Object("IfcOpenShell") {}
134.2407 +
134.2408 +    };
134.2409 +
134.2410 +    // C++ wrapper for IfcFacetedBrep
134.2411 +    struct IfcFacetedBrep : IfcManifoldSolidBrep, ObjectHelper<IfcFacetedBrep,0> { IfcFacetedBrep() : Object("IfcFacetedBrep") {}
134.2412 +
134.2413 +    };
134.2414 +
134.2415 +    // C++ wrapper for IfcConic
134.2416 +    struct IfcConic : IfcCurve, ObjectHelper<IfcConic,1> { IfcConic() : Object("IfcConic") {}
134.2417 +		IfcAxis2Placement::Out Position;
134.2418 +    };
134.2419 +
134.2420 +    // C++ wrapper for IfcCoveringType
134.2421 +    struct IfcCoveringType : IfcBuildingElementType, ObjectHelper<IfcCoveringType,1> { IfcCoveringType() : Object("IfcCoveringType") {}
134.2422 +		IfcCoveringTypeEnum::Out PredefinedType;
134.2423 +    };
134.2424 +
134.2425 +    // C++ wrapper for IfcRoundedRectangleProfileDef
134.2426 +    struct IfcRoundedRectangleProfileDef : IfcRectangleProfileDef, ObjectHelper<IfcRoundedRectangleProfileDef,1> { IfcRoundedRectangleProfileDef() : Object("IfcRoundedRectangleProfileDef") {}
134.2427 +		IfcPositiveLengthMeasure::Out RoundingRadius;
134.2428 +    };
134.2429 +
134.2430 +    // C++ wrapper for IfcAirTerminalType
134.2431 +    struct IfcAirTerminalType : IfcFlowTerminalType, ObjectHelper<IfcAirTerminalType,1> { IfcAirTerminalType() : Object("IfcAirTerminalType") {}
134.2432 +		IfcAirTerminalTypeEnum::Out PredefinedType;
134.2433 +    };
134.2434 +
134.2435 +    // C++ wrapper for IfcFlowMovingDeviceType
134.2436 +    struct IfcFlowMovingDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowMovingDeviceType,0> { IfcFlowMovingDeviceType() : Object("IfcFlowMovingDeviceType") {}
134.2437 +
134.2438 +    };
134.2439 +
134.2440 +    // C++ wrapper for IfcCompressorType
134.2441 +    struct IfcCompressorType : IfcFlowMovingDeviceType, ObjectHelper<IfcCompressorType,1> { IfcCompressorType() : Object("IfcCompressorType") {}
134.2442 +		IfcCompressorTypeEnum::Out PredefinedType;
134.2443 +    };
134.2444 +
134.2445 +    // C++ wrapper for IfcIShapeProfileDef
134.2446 +    struct IfcIShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcIShapeProfileDef,5> { IfcIShapeProfileDef() : Object("IfcIShapeProfileDef") {}
134.2447 +		IfcPositiveLengthMeasure::Out OverallWidth;
134.2448 +		IfcPositiveLengthMeasure::Out OverallDepth;
134.2449 +		IfcPositiveLengthMeasure::Out WebThickness;
134.2450 +		IfcPositiveLengthMeasure::Out FlangeThickness;
134.2451 +		Maybe< IfcPositiveLengthMeasure::Out > FilletRadius;
134.2452 +    };
134.2453 +
134.2454 +    // C++ wrapper for IfcAsymmetricIShapeProfileDef
134.2455 +    struct IfcAsymmetricIShapeProfileDef : IfcIShapeProfileDef, ObjectHelper<IfcAsymmetricIShapeProfileDef,4> { IfcAsymmetricIShapeProfileDef() : Object("IfcAsymmetricIShapeProfileDef") {}
134.2456 +		IfcPositiveLengthMeasure::Out TopFlangeWidth;
134.2457 +		Maybe< IfcPositiveLengthMeasure::Out > TopFlangeThickness;
134.2458 +		Maybe< IfcPositiveLengthMeasure::Out > TopFlangeFilletRadius;
134.2459 +		Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY;
134.2460 +    };
134.2461 +
134.2462 +    // C++ wrapper for IfcControllerType
134.2463 +    struct IfcControllerType : IfcDistributionControlElementType, ObjectHelper<IfcControllerType,1> { IfcControllerType() : Object("IfcControllerType") {}
134.2464 +		IfcControllerTypeEnum::Out PredefinedType;
134.2465 +    };
134.2466 +
134.2467 +    // C++ wrapper for IfcRailing
134.2468 +    struct IfcRailing : IfcBuildingElement, ObjectHelper<IfcRailing,1> { IfcRailing() : Object("IfcRailing") {}
134.2469 +		Maybe< IfcRailingTypeEnum::Out > PredefinedType;
134.2470 +    };
134.2471 +
134.2472 +    // C++ wrapper for IfcGroup
134.2473 +    struct IfcGroup : IfcObject, ObjectHelper<IfcGroup,0> { IfcGroup() : Object("IfcGroup") {}
134.2474 +
134.2475 +    };
134.2476 +
134.2477 +    // C++ wrapper for IfcAsset
134.2478 +    struct IfcAsset : IfcGroup, ObjectHelper<IfcAsset,9> { IfcAsset() : Object("IfcAsset") {}
134.2479 +		IfcIdentifier::Out AssetID;
134.2480 +		Lazy< NotImplemented > OriginalValue;
134.2481 +		Lazy< NotImplemented > CurrentValue;
134.2482 +		Lazy< NotImplemented > TotalReplacementCost;
134.2483 +		IfcActorSelect::Out Owner;
134.2484 +		IfcActorSelect::Out User;
134.2485 +		Lazy< NotImplemented > ResponsiblePerson;
134.2486 +		Lazy< NotImplemented > IncorporationDate;
134.2487 +		Lazy< NotImplemented > DepreciatedValue;
134.2488 +    };
134.2489 +
134.2490 +    // C++ wrapper for IfcMaterialDefinitionRepresentation
134.2491 +    struct IfcMaterialDefinitionRepresentation : IfcProductRepresentation, ObjectHelper<IfcMaterialDefinitionRepresentation,1> { IfcMaterialDefinitionRepresentation() : Object("IfcMaterialDefinitionRepresentation") {}
134.2492 +		Lazy< NotImplemented > RepresentedMaterial;
134.2493 +    };
134.2494 +
134.2495 +    // C++ wrapper for IfcRailingType
134.2496 +    struct IfcRailingType : IfcBuildingElementType, ObjectHelper<IfcRailingType,1> { IfcRailingType() : Object("IfcRailingType") {}
134.2497 +		IfcRailingTypeEnum::Out PredefinedType;
134.2498 +    };
134.2499 +
134.2500 +    // C++ wrapper for IfcWall
134.2501 +    struct IfcWall : IfcBuildingElement, ObjectHelper<IfcWall,0> { IfcWall() : Object("IfcWall") {}
134.2502 +
134.2503 +    };
134.2504 +
134.2505 +    // C++ wrapper for IfcStructuralPointConnection
134.2506 +    struct IfcStructuralPointConnection : IfcStructuralConnection, ObjectHelper<IfcStructuralPointConnection,0> { IfcStructuralPointConnection() : Object("IfcStructuralPointConnection") {}
134.2507 +
134.2508 +    };
134.2509 +
134.2510 +    // C++ wrapper for IfcPropertyListValue
134.2511 +    struct IfcPropertyListValue : IfcSimpleProperty, ObjectHelper<IfcPropertyListValue,2> { IfcPropertyListValue() : Object("IfcPropertyListValue") {}
134.2512 +		ListOf< IfcValue, 1, 0 >::Out ListValues;
134.2513 +		Maybe< IfcUnit::Out > Unit;
134.2514 +    };
134.2515 +
134.2516 +    // C++ wrapper for IfcFurnitureStandard
134.2517 +    struct IfcFurnitureStandard : IfcControl, ObjectHelper<IfcFurnitureStandard,0> { IfcFurnitureStandard() : Object("IfcFurnitureStandard") {}
134.2518 +
134.2519 +    };
134.2520 +
134.2521 +    // C++ wrapper for IfcElectricGeneratorType
134.2522 +    struct IfcElectricGeneratorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcElectricGeneratorType,1> { IfcElectricGeneratorType() : Object("IfcElectricGeneratorType") {}
134.2523 +		IfcElectricGeneratorTypeEnum::Out PredefinedType;
134.2524 +    };
134.2525 +
134.2526 +    // C++ wrapper for IfcDoor
134.2527 +    struct IfcDoor : IfcBuildingElement, ObjectHelper<IfcDoor,2> { IfcDoor() : Object("IfcDoor") {}
134.2528 +		Maybe< IfcPositiveLengthMeasure::Out > OverallHeight;
134.2529 +		Maybe< IfcPositiveLengthMeasure::Out > OverallWidth;
134.2530 +    };
134.2531 +
134.2532 +    // C++ wrapper for IfcStyledItem
134.2533 +    struct IfcStyledItem : IfcRepresentationItem, ObjectHelper<IfcStyledItem,3> { IfcStyledItem() : Object("IfcStyledItem") {}
134.2534 +		Maybe< Lazy< IfcRepresentationItem > > Item;
134.2535 +		ListOf< Lazy< IfcPresentationStyleAssignment >, 1, 0 > Styles;
134.2536 +		Maybe< IfcLabel::Out > Name;
134.2537 +    };
134.2538 +
134.2539 +    // C++ wrapper for IfcAnnotationOccurrence
134.2540 +    struct IfcAnnotationOccurrence : IfcStyledItem, ObjectHelper<IfcAnnotationOccurrence,0> { IfcAnnotationOccurrence() : Object("IfcAnnotationOccurrence") {}
134.2541 +
134.2542 +    };
134.2543 +
134.2544 +    // C++ wrapper for IfcAnnotationSymbolOccurrence
134.2545 +    struct IfcAnnotationSymbolOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationSymbolOccurrence,0> { IfcAnnotationSymbolOccurrence() : Object("IfcAnnotationSymbolOccurrence") {}
134.2546 +
134.2547 +    };
134.2548 +
134.2549 +    // C++ wrapper for IfcArbitraryClosedProfileDef
134.2550 +    struct IfcArbitraryClosedProfileDef : IfcProfileDef, ObjectHelper<IfcArbitraryClosedProfileDef,1> { IfcArbitraryClosedProfileDef() : Object("IfcArbitraryClosedProfileDef") {}
134.2551 +		Lazy< IfcCurve > OuterCurve;
134.2552 +    };
134.2553 +
134.2554 +    // C++ wrapper for IfcArbitraryProfileDefWithVoids
134.2555 +    struct IfcArbitraryProfileDefWithVoids : IfcArbitraryClosedProfileDef, ObjectHelper<IfcArbitraryProfileDefWithVoids,1> { IfcArbitraryProfileDefWithVoids() : Object("IfcArbitraryProfileDefWithVoids") {}
134.2556 +		ListOf< Lazy< IfcCurve >, 1, 0 > InnerCurves;
134.2557 +    };
134.2558 +
134.2559 +    // C++ wrapper for IfcLine
134.2560 +    struct IfcLine : IfcCurve, ObjectHelper<IfcLine,2> { IfcLine() : Object("IfcLine") {}
134.2561 +		Lazy< IfcCartesianPoint > Pnt;
134.2562 +		Lazy< IfcVector > Dir;
134.2563 +    };
134.2564 +
134.2565 +    // C++ wrapper for IfcFlowSegmentType
134.2566 +    struct IfcFlowSegmentType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowSegmentType,0> { IfcFlowSegmentType() : Object("IfcFlowSegmentType") {}
134.2567 +
134.2568 +    };
134.2569 +
134.2570 +    // C++ wrapper for IfcAirTerminalBoxType
134.2571 +    struct IfcAirTerminalBoxType : IfcFlowControllerType, ObjectHelper<IfcAirTerminalBoxType,1> { IfcAirTerminalBoxType() : Object("IfcAirTerminalBoxType") {}
134.2572 +		IfcAirTerminalBoxTypeEnum::Out PredefinedType;
134.2573 +    };
134.2574 +
134.2575 +    // C++ wrapper for IfcPropertySingleValue
134.2576 +    struct IfcPropertySingleValue : IfcSimpleProperty, ObjectHelper<IfcPropertySingleValue,2> { IfcPropertySingleValue() : Object("IfcPropertySingleValue") {}
134.2577 +		Maybe< IfcValue::Out > NominalValue;
134.2578 +		Maybe< IfcUnit::Out > Unit;
134.2579 +    };
134.2580 +
134.2581 +    // C++ wrapper for IfcAlarmType
134.2582 +    struct IfcAlarmType : IfcDistributionControlElementType, ObjectHelper<IfcAlarmType,1> { IfcAlarmType() : Object("IfcAlarmType") {}
134.2583 +		IfcAlarmTypeEnum::Out PredefinedType;
134.2584 +    };
134.2585 +
134.2586 +    // C++ wrapper for IfcEllipseProfileDef
134.2587 +    struct IfcEllipseProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcEllipseProfileDef,2> { IfcEllipseProfileDef() : Object("IfcEllipseProfileDef") {}
134.2588 +		IfcPositiveLengthMeasure::Out SemiAxis1;
134.2589 +		IfcPositiveLengthMeasure::Out SemiAxis2;
134.2590 +    };
134.2591 +
134.2592 +    // C++ wrapper for IfcStair
134.2593 +    struct IfcStair : IfcBuildingElement, ObjectHelper<IfcStair,1> { IfcStair() : Object("IfcStair") {}
134.2594 +		IfcStairTypeEnum::Out ShapeType;
134.2595 +    };
134.2596 +
134.2597 +    // C++ wrapper for IfcSurfaceStyleShading
134.2598 +    struct IfcSurfaceStyleShading :  ObjectHelper<IfcSurfaceStyleShading,1> { IfcSurfaceStyleShading() : Object("IfcSurfaceStyleShading") {}
134.2599 +		Lazy< IfcColourRgb > SurfaceColour;
134.2600 +    };
134.2601 +
134.2602 +    // C++ wrapper for IfcPumpType
134.2603 +    struct IfcPumpType : IfcFlowMovingDeviceType, ObjectHelper<IfcPumpType,1> { IfcPumpType() : Object("IfcPumpType") {}
134.2604 +		IfcPumpTypeEnum::Out PredefinedType;
134.2605 +    };
134.2606 +
134.2607 +    // C++ wrapper for IfcDefinedSymbol
134.2608 +    struct IfcDefinedSymbol : IfcGeometricRepresentationItem, ObjectHelper<IfcDefinedSymbol,2> { IfcDefinedSymbol() : Object("IfcDefinedSymbol") {}
134.2609 +		IfcDefinedSymbolSelect::Out Definition;
134.2610 +		Lazy< IfcCartesianTransformationOperator2D > Target;
134.2611 +    };
134.2612 +
134.2613 +    // C++ wrapper for IfcElementComponentType
134.2614 +    struct IfcElementComponentType : IfcElementType, ObjectHelper<IfcElementComponentType,0> { IfcElementComponentType() : Object("IfcElementComponentType") {}
134.2615 +
134.2616 +    };
134.2617 +
134.2618 +    // C++ wrapper for IfcFastenerType
134.2619 +    struct IfcFastenerType : IfcElementComponentType, ObjectHelper<IfcFastenerType,0> { IfcFastenerType() : Object("IfcFastenerType") {}
134.2620 +
134.2621 +    };
134.2622 +
134.2623 +    // C++ wrapper for IfcMechanicalFastenerType
134.2624 +    struct IfcMechanicalFastenerType : IfcFastenerType, ObjectHelper<IfcMechanicalFastenerType,0> { IfcMechanicalFastenerType() : Object("IfcMechanicalFastenerType") {}
134.2625 +
134.2626 +    };
134.2627 +
134.2628 +    // C++ wrapper for IfcFlowFitting
134.2629 +    struct IfcFlowFitting : IfcDistributionFlowElement, ObjectHelper<IfcFlowFitting,0> { IfcFlowFitting() : Object("IfcFlowFitting") {}
134.2630 +
134.2631 +    };
134.2632 +
134.2633 +    // C++ wrapper for IfcLightSourceDirectional
134.2634 +    struct IfcLightSourceDirectional : IfcLightSource, ObjectHelper<IfcLightSourceDirectional,1> { IfcLightSourceDirectional() : Object("IfcLightSourceDirectional") {}
134.2635 +		Lazy< IfcDirection > Orientation;
134.2636 +    };
134.2637 +
134.2638 +    // C++ wrapper for IfcSurfaceStyle
134.2639 +    struct IfcSurfaceStyle : IfcPresentationStyle, ObjectHelper<IfcSurfaceStyle,2> { IfcSurfaceStyle() : Object("IfcSurfaceStyle") {}
134.2640 +		IfcSurfaceSide::Out Side;
134.2641 +		ListOf< IfcSurfaceStyleElementSelect, 1, 5 >::Out Styles;
134.2642 +    };
134.2643 +
134.2644 +    // C++ wrapper for IfcAnnotationSurface
134.2645 +    struct IfcAnnotationSurface : IfcGeometricRepresentationItem, ObjectHelper<IfcAnnotationSurface,2> { IfcAnnotationSurface() : Object("IfcAnnotationSurface") {}
134.2646 +		Lazy< IfcGeometricRepresentationItem > Item;
134.2647 +		Maybe< Lazy< NotImplemented > > TextureCoordinates;
134.2648 +    };
134.2649 +
134.2650 +    // C++ wrapper for IfcFlowController
134.2651 +    struct IfcFlowController : IfcDistributionFlowElement, ObjectHelper<IfcFlowController,0> { IfcFlowController() : Object("IfcFlowController") {}
134.2652 +
134.2653 +    };
134.2654 +
134.2655 +    // C++ wrapper for IfcBuildingStorey
134.2656 +    struct IfcBuildingStorey : IfcSpatialStructureElement, ObjectHelper<IfcBuildingStorey,1> { IfcBuildingStorey() : Object("IfcBuildingStorey") {}
134.2657 +		Maybe< IfcLengthMeasure::Out > Elevation;
134.2658 +    };
134.2659 +
134.2660 +    // C++ wrapper for IfcWorkControl
134.2661 +    struct IfcWorkControl : IfcControl, ObjectHelper<IfcWorkControl,10> { IfcWorkControl() : Object("IfcWorkControl") {}
134.2662 +		IfcIdentifier::Out Identifier;
134.2663 +		IfcDateTimeSelect::Out CreationDate;
134.2664 +		Maybe< ListOf< Lazy< NotImplemented >, 1, 0 > > Creators;
134.2665 +		Maybe< IfcLabel::Out > Purpose;
134.2666 +		Maybe< IfcTimeMeasure::Out > Duration;
134.2667 +		Maybe< IfcTimeMeasure::Out > TotalFloat;
134.2668 +		IfcDateTimeSelect::Out StartTime;
134.2669 +		Maybe< IfcDateTimeSelect::Out > FinishTime;
134.2670 +		Maybe< IfcWorkControlTypeEnum::Out > WorkControlType;
134.2671 +		Maybe< IfcLabel::Out > UserDefinedControlType;
134.2672 +    };
134.2673 +
134.2674 +    // C++ wrapper for IfcWorkSchedule
134.2675 +    struct IfcWorkSchedule : IfcWorkControl, ObjectHelper<IfcWorkSchedule,0> { IfcWorkSchedule() : Object("IfcWorkSchedule") {}
134.2676 +
134.2677 +    };
134.2678 +
134.2679 +    // C++ wrapper for IfcDuctSegmentType
134.2680 +    struct IfcDuctSegmentType : IfcFlowSegmentType, ObjectHelper<IfcDuctSegmentType,1> { IfcDuctSegmentType() : Object("IfcDuctSegmentType") {}
134.2681 +		IfcDuctSegmentTypeEnum::Out PredefinedType;
134.2682 +    };
134.2683 +
134.2684 +    // C++ wrapper for IfcFace
134.2685 +    struct IfcFace : IfcTopologicalRepresentationItem, ObjectHelper<IfcFace,1> { IfcFace() : Object("IfcFace") {}
134.2686 +		ListOf< Lazy< IfcFaceBound >, 1, 0 > Bounds;
134.2687 +    };
134.2688 +
134.2689 +    // C++ wrapper for IfcStructuralSurfaceMember
134.2690 +    struct IfcStructuralSurfaceMember : IfcStructuralMember, ObjectHelper<IfcStructuralSurfaceMember,2> { IfcStructuralSurfaceMember() : Object("IfcStructuralSurfaceMember") {}
134.2691 +		IfcStructuralSurfaceTypeEnum::Out PredefinedType;
134.2692 +		Maybe< IfcPositiveLengthMeasure::Out > Thickness;
134.2693 +    };
134.2694 +
134.2695 +    // C++ wrapper for IfcStructuralSurfaceMemberVarying
134.2696 +    struct IfcStructuralSurfaceMemberVarying : IfcStructuralSurfaceMember, ObjectHelper<IfcStructuralSurfaceMemberVarying,2> { IfcStructuralSurfaceMemberVarying() : Object("IfcStructuralSurfaceMemberVarying") {}
134.2697 +		ListOf< IfcPositiveLengthMeasure, 2, 0 >::Out SubsequentThickness;
134.2698 +		Lazy< NotImplemented > VaryingThicknessLocation;
134.2699 +    };
134.2700 +
134.2701 +    // C++ wrapper for IfcFaceSurface
134.2702 +    struct IfcFaceSurface : IfcFace, ObjectHelper<IfcFaceSurface,2> { IfcFaceSurface() : Object("IfcFaceSurface") {}
134.2703 +		Lazy< IfcSurface > FaceSurface;
134.2704 +		BOOLEAN::Out SameSense;
134.2705 +    };
134.2706 +
134.2707 +    // C++ wrapper for IfcCostSchedule
134.2708 +    struct IfcCostSchedule : IfcControl, ObjectHelper<IfcCostSchedule,8> { IfcCostSchedule() : Object("IfcCostSchedule") {}
134.2709 +		Maybe< IfcActorSelect::Out > SubmittedBy;
134.2710 +		Maybe< IfcActorSelect::Out > PreparedBy;
134.2711 +		Maybe< IfcDateTimeSelect::Out > SubmittedOn;
134.2712 +		Maybe< IfcLabel::Out > Status;
134.2713 +		Maybe< ListOf< IfcActorSelect, 1, 0 >::Out > TargetUsers;
134.2714 +		Maybe< IfcDateTimeSelect::Out > UpdateDate;
134.2715 +		IfcIdentifier::Out ID;
134.2716 +		IfcCostScheduleTypeEnum::Out PredefinedType;
134.2717 +    };
134.2718 +
134.2719 +    // C++ wrapper for IfcPlanarExtent
134.2720 +    struct IfcPlanarExtent : IfcGeometricRepresentationItem, ObjectHelper<IfcPlanarExtent,2> { IfcPlanarExtent() : Object("IfcPlanarExtent") {}
134.2721 +		IfcLengthMeasure::Out SizeInX;
134.2722 +		IfcLengthMeasure::Out SizeInY;
134.2723 +    };
134.2724 +
134.2725 +    // C++ wrapper for IfcPlanarBox
134.2726 +    struct IfcPlanarBox : IfcPlanarExtent, ObjectHelper<IfcPlanarBox,1> { IfcPlanarBox() : Object("IfcPlanarBox") {}
134.2727 +		IfcAxis2Placement::Out Placement;
134.2728 +    };
134.2729 +
134.2730 +    // C++ wrapper for IfcColourSpecification
134.2731 +    struct IfcColourSpecification :  ObjectHelper<IfcColourSpecification,1> { IfcColourSpecification() : Object("IfcColourSpecification") {}
134.2732 +		Maybe< IfcLabel::Out > Name;
134.2733 +    };
134.2734 +
134.2735 +    // C++ wrapper for IfcVector
134.2736 +    struct IfcVector : IfcGeometricRepresentationItem, ObjectHelper<IfcVector,2> { IfcVector() : Object("IfcVector") {}
134.2737 +		Lazy< IfcDirection > Orientation;
134.2738 +		IfcLengthMeasure::Out Magnitude;
134.2739 +    };
134.2740 +
134.2741 +    // C++ wrapper for IfcBeam
134.2742 +    struct IfcBeam : IfcBuildingElement, ObjectHelper<IfcBeam,0> { IfcBeam() : Object("IfcBeam") {}
134.2743 +
134.2744 +    };
134.2745 +
134.2746 +    // C++ wrapper for IfcColourRgb
134.2747 +    struct IfcColourRgb : IfcColourSpecification, ObjectHelper<IfcColourRgb,3> { IfcColourRgb() : Object("IfcColourRgb") {}
134.2748 +		IfcNormalisedRatioMeasure::Out Red;
134.2749 +		IfcNormalisedRatioMeasure::Out Green;
134.2750 +		IfcNormalisedRatioMeasure::Out Blue;
134.2751 +    };
134.2752 +
134.2753 +    // C++ wrapper for IfcStructuralPlanarAction
134.2754 +    struct IfcStructuralPlanarAction : IfcStructuralAction, ObjectHelper<IfcStructuralPlanarAction,1> { IfcStructuralPlanarAction() : Object("IfcStructuralPlanarAction") {}
134.2755 +		IfcProjectedOrTrueLengthEnum::Out ProjectedOrTrue;
134.2756 +    };
134.2757 +
134.2758 +    // C++ wrapper for IfcStructuralPlanarActionVarying
134.2759 +    struct IfcStructuralPlanarActionVarying : IfcStructuralPlanarAction, ObjectHelper<IfcStructuralPlanarActionVarying,2> { IfcStructuralPlanarActionVarying() : Object("IfcStructuralPlanarActionVarying") {}
134.2760 +		Lazy< NotImplemented > VaryingAppliedLoadLocation;
134.2761 +		ListOf< Lazy< NotImplemented >, 2, 0 > SubsequentAppliedLoads;
134.2762 +    };
134.2763 +
134.2764 +    // C++ wrapper for IfcSite
134.2765 +    struct IfcSite : IfcSpatialStructureElement, ObjectHelper<IfcSite,5> { IfcSite() : Object("IfcSite") {}
134.2766 +		Maybe< IfcCompoundPlaneAngleMeasure::Out > RefLatitude;
134.2767 +		Maybe< IfcCompoundPlaneAngleMeasure::Out > RefLongitude;
134.2768 +		Maybe< IfcLengthMeasure::Out > RefElevation;
134.2769 +		Maybe< IfcLabel::Out > LandTitleNumber;
134.2770 +		Maybe< Lazy< NotImplemented > > SiteAddress;
134.2771 +    };
134.2772 +
134.2773 +    // C++ wrapper for IfcDiscreteAccessoryType
134.2774 +    struct IfcDiscreteAccessoryType : IfcElementComponentType, ObjectHelper<IfcDiscreteAccessoryType,0> { IfcDiscreteAccessoryType() : Object("IfcDiscreteAccessoryType") {}
134.2775 +
134.2776 +    };
134.2777 +
134.2778 +    // C++ wrapper for IfcVibrationIsolatorType
134.2779 +    struct IfcVibrationIsolatorType : IfcDiscreteAccessoryType, ObjectHelper<IfcVibrationIsolatorType,1> { IfcVibrationIsolatorType() : Object("IfcVibrationIsolatorType") {}
134.2780 +		IfcVibrationIsolatorTypeEnum::Out PredefinedType;
134.2781 +    };
134.2782 +
134.2783 +    // C++ wrapper for IfcEvaporativeCoolerType
134.2784 +    struct IfcEvaporativeCoolerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcEvaporativeCoolerType,1> { IfcEvaporativeCoolerType() : Object("IfcEvaporativeCoolerType") {}
134.2785 +		IfcEvaporativeCoolerTypeEnum::Out PredefinedType;
134.2786 +    };
134.2787 +
134.2788 +    // C++ wrapper for IfcDistributionChamberElementType
134.2789 +    struct IfcDistributionChamberElementType : IfcDistributionFlowElementType, ObjectHelper<IfcDistributionChamberElementType,1> { IfcDistributionChamberElementType() : Object("IfcDistributionChamberElementType") {}
134.2790 +		IfcDistributionChamberElementTypeEnum::Out PredefinedType;
134.2791 +    };
134.2792 +
134.2793 +    // C++ wrapper for IfcFeatureElementAddition
134.2794 +    struct IfcFeatureElementAddition : IfcFeatureElement, ObjectHelper<IfcFeatureElementAddition,0> { IfcFeatureElementAddition() : Object("IfcFeatureElementAddition") {}
134.2795 +
134.2796 +    };
134.2797 +
134.2798 +    // C++ wrapper for IfcStructuredDimensionCallout
134.2799 +    struct IfcStructuredDimensionCallout : IfcDraughtingCallout, ObjectHelper<IfcStructuredDimensionCallout,0> { IfcStructuredDimensionCallout() : Object("IfcStructuredDimensionCallout") {}
134.2800 +
134.2801 +    };
134.2802 +
134.2803 +    // C++ wrapper for IfcCoolingTowerType
134.2804 +    struct IfcCoolingTowerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCoolingTowerType,1> { IfcCoolingTowerType() : Object("IfcCoolingTowerType") {}
134.2805 +		IfcCoolingTowerTypeEnum::Out PredefinedType;
134.2806 +    };
134.2807 +
134.2808 +    // C++ wrapper for IfcCenterLineProfileDef
134.2809 +    struct IfcCenterLineProfileDef : IfcArbitraryOpenProfileDef, ObjectHelper<IfcCenterLineProfileDef,1> { IfcCenterLineProfileDef() : Object("IfcCenterLineProfileDef") {}
134.2810 +		IfcPositiveLengthMeasure::Out Thickness;
134.2811 +    };
134.2812 +
134.2813 +    // C++ wrapper for IfcWindowStyle
134.2814 +    struct IfcWindowStyle : IfcTypeProduct, ObjectHelper<IfcWindowStyle,4> { IfcWindowStyle() : Object("IfcWindowStyle") {}
134.2815 +		IfcWindowStyleConstructionEnum::Out ConstructionType;
134.2816 +		IfcWindowStyleOperationEnum::Out OperationType;
134.2817 +		BOOLEAN::Out ParameterTakesPrecedence;
134.2818 +		BOOLEAN::Out Sizeable;
134.2819 +    };
134.2820 +
134.2821 +    // C++ wrapper for IfcLightSourceGoniometric
134.2822 +    struct IfcLightSourceGoniometric : IfcLightSource, ObjectHelper<IfcLightSourceGoniometric,6> { IfcLightSourceGoniometric() : Object("IfcLightSourceGoniometric") {}
134.2823 +		Lazy< IfcAxis2Placement3D > Position;
134.2824 +		Maybe< Lazy< IfcColourRgb > > ColourAppearance;
134.2825 +		IfcThermodynamicTemperatureMeasure::Out ColourTemperature;
134.2826 +		IfcLuminousFluxMeasure::Out LuminousFlux;
134.2827 +		IfcLightEmissionSourceEnum::Out LightEmissionSource;
134.2828 +		IfcLightDistributionDataSourceSelect::Out LightDistributionDataSource;
134.2829 +    };
134.2830 +
134.2831 +    // C++ wrapper for IfcTransformerType
134.2832 +    struct IfcTransformerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcTransformerType,1> { IfcTransformerType() : Object("IfcTransformerType") {}
134.2833 +		IfcTransformerTypeEnum::Out PredefinedType;
134.2834 +    };
134.2835 +
134.2836 +    // C++ wrapper for IfcMemberType
134.2837 +    struct IfcMemberType : IfcBuildingElementType, ObjectHelper<IfcMemberType,1> { IfcMemberType() : Object("IfcMemberType") {}
134.2838 +		IfcMemberTypeEnum::Out PredefinedType;
134.2839 +    };
134.2840 +
134.2841 +    // C++ wrapper for IfcSurfaceOfLinearExtrusion
134.2842 +    struct IfcSurfaceOfLinearExtrusion : IfcSweptSurface, ObjectHelper<IfcSurfaceOfLinearExtrusion,2> { IfcSurfaceOfLinearExtrusion() : Object("IfcSurfaceOfLinearExtrusion") {}
134.2843 +		Lazy< IfcDirection > ExtrudedDirection;
134.2844 +		IfcLengthMeasure::Out Depth;
134.2845 +    };
134.2846 +
134.2847 +    // C++ wrapper for IfcMotorConnectionType
134.2848 +    struct IfcMotorConnectionType : IfcEnergyConversionDeviceType, ObjectHelper<IfcMotorConnectionType,1> { IfcMotorConnectionType() : Object("IfcMotorConnectionType") {}
134.2849 +		IfcMotorConnectionTypeEnum::Out PredefinedType;
134.2850 +    };
134.2851 +
134.2852 +    // C++ wrapper for IfcFlowTreatmentDeviceType
134.2853 +    struct IfcFlowTreatmentDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowTreatmentDeviceType,0> { IfcFlowTreatmentDeviceType() : Object("IfcFlowTreatmentDeviceType") {}
134.2854 +
134.2855 +    };
134.2856 +
134.2857 +    // C++ wrapper for IfcDuctSilencerType
134.2858 +    struct IfcDuctSilencerType : IfcFlowTreatmentDeviceType, ObjectHelper<IfcDuctSilencerType,1> { IfcDuctSilencerType() : Object("IfcDuctSilencerType") {}
134.2859 +		IfcDuctSilencerTypeEnum::Out PredefinedType;
134.2860 +    };
134.2861 +
134.2862 +    // C++ wrapper for IfcFurnishingElementType
134.2863 +    struct IfcFurnishingElementType : IfcElementType, ObjectHelper<IfcFurnishingElementType,0> { IfcFurnishingElementType() : Object("IfcFurnishingElementType") {}
134.2864 +
134.2865 +    };
134.2866 +
134.2867 +    // C++ wrapper for IfcSystemFurnitureElementType
134.2868 +    struct IfcSystemFurnitureElementType : IfcFurnishingElementType, ObjectHelper<IfcSystemFurnitureElementType,0> { IfcSystemFurnitureElementType() : Object("IfcSystemFurnitureElementType") {}
134.2869 +
134.2870 +    };
134.2871 +
134.2872 +    // C++ wrapper for IfcWasteTerminalType
134.2873 +    struct IfcWasteTerminalType : IfcFlowTerminalType, ObjectHelper<IfcWasteTerminalType,1> { IfcWasteTerminalType() : Object("IfcWasteTerminalType") {}
134.2874 +		IfcWasteTerminalTypeEnum::Out PredefinedType;
134.2875 +    };
134.2876 +
134.2877 +    // C++ wrapper for IfcBSplineCurve
134.2878 +    struct IfcBSplineCurve : IfcBoundedCurve, ObjectHelper<IfcBSplineCurve,5> { IfcBSplineCurve() : Object("IfcBSplineCurve") {}
134.2879 +		INTEGER::Out Degree;
134.2880 +		ListOf< Lazy< IfcCartesianPoint >, 2, 0 > ControlPointsList;
134.2881 +		IfcBSplineCurveForm::Out CurveForm;
134.2882 +		LOGICAL::Out ClosedCurve;
134.2883 +		LOGICAL::Out SelfIntersect;
134.2884 +    };
134.2885 +
134.2886 +    // C++ wrapper for IfcBezierCurve
134.2887 +    struct IfcBezierCurve : IfcBSplineCurve, ObjectHelper<IfcBezierCurve,0> { IfcBezierCurve() : Object("IfcBezierCurve") {}
134.2888 +
134.2889 +    };
134.2890 +
134.2891 +    // C++ wrapper for IfcActuatorType
134.2892 +    struct IfcActuatorType : IfcDistributionControlElementType, ObjectHelper<IfcActuatorType,1> { IfcActuatorType() : Object("IfcActuatorType") {}
134.2893 +		IfcActuatorTypeEnum::Out PredefinedType;
134.2894 +    };
134.2895 +
134.2896 +    // C++ wrapper for IfcDistributionControlElement
134.2897 +    struct IfcDistributionControlElement : IfcDistributionElement, ObjectHelper<IfcDistributionControlElement,1> { IfcDistributionControlElement() : Object("IfcDistributionControlElement") {}
134.2898 +		Maybe< IfcIdentifier::Out > ControlElementId;
134.2899 +    };
134.2900 +
134.2901 +    // C++ wrapper for IfcAnnotation
134.2902 +    struct IfcAnnotation : IfcProduct, ObjectHelper<IfcAnnotation,0> { IfcAnnotation() : Object("IfcAnnotation") {}
134.2903 +
134.2904 +    };
134.2905 +
134.2906 +    // C++ wrapper for IfcShellBasedSurfaceModel
134.2907 +    struct IfcShellBasedSurfaceModel : IfcGeometricRepresentationItem, ObjectHelper<IfcShellBasedSurfaceModel,1> { IfcShellBasedSurfaceModel() : Object("IfcShellBasedSurfaceModel") {}
134.2908 +		ListOf< IfcShell, 1, 0 >::Out SbsmBoundary;
134.2909 +    };
134.2910 +
134.2911 +    // C++ wrapper for IfcActionRequest
134.2912 +    struct IfcActionRequest : IfcControl, ObjectHelper<IfcActionRequest,1> { IfcActionRequest() : Object("IfcActionRequest") {}
134.2913 +		IfcIdentifier::Out RequestID;
134.2914 +    };
134.2915 +
134.2916 +    // C++ wrapper for IfcExtrudedAreaSolid
134.2917 +    struct IfcExtrudedAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcExtrudedAreaSolid,2> { IfcExtrudedAreaSolid() : Object("IfcExtrudedAreaSolid") {}
134.2918 +		Lazy< IfcDirection > ExtrudedDirection;
134.2919 +		IfcPositiveLengthMeasure::Out Depth;
134.2920 +    };
134.2921 +
134.2922 +    // C++ wrapper for IfcSystem
134.2923 +    struct IfcSystem : IfcGroup, ObjectHelper<IfcSystem,0> { IfcSystem() : Object("IfcSystem") {}
134.2924 +
134.2925 +    };
134.2926 +
134.2927 +    // C++ wrapper for IfcFillAreaStyleHatching
134.2928 +    struct IfcFillAreaStyleHatching : IfcGeometricRepresentationItem, ObjectHelper<IfcFillAreaStyleHatching,5> { IfcFillAreaStyleHatching() : Object("IfcFillAreaStyleHatching") {}
134.2929 +		Lazy< NotImplemented > HatchLineAppearance;
134.2930 +		IfcHatchLineDistanceSelect::Out StartOfNextHatchLine;
134.2931 +		Maybe< Lazy< IfcCartesianPoint > > PointOfReferenceHatchLine;
134.2932 +		Maybe< Lazy< IfcCartesianPoint > > PatternStart;
134.2933 +		IfcPlaneAngleMeasure::Out HatchLineAngle;
134.2934 +    };
134.2935 +
134.2936 +    // C++ wrapper for IfcRelVoidsElement
134.2937 +    struct IfcRelVoidsElement : IfcRelConnects, ObjectHelper<IfcRelVoidsElement,2> { IfcRelVoidsElement() : Object("IfcRelVoidsElement") {}
134.2938 +		Lazy< IfcElement > RelatingBuildingElement;
134.2939 +		Lazy< IfcFeatureElementSubtraction > RelatedOpeningElement;
134.2940 +    };
134.2941 +
134.2942 +    // C++ wrapper for IfcSurfaceCurveSweptAreaSolid
134.2943 +    struct IfcSurfaceCurveSweptAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcSurfaceCurveSweptAreaSolid,4> { IfcSurfaceCurveSweptAreaSolid() : Object("IfcSurfaceCurveSweptAreaSolid") {}
134.2944 +		Lazy< IfcCurve > Directrix;
134.2945 +		IfcParameterValue::Out StartParam;
134.2946 +		IfcParameterValue::Out EndParam;
134.2947 +		Lazy< IfcSurface > ReferenceSurface;
134.2948 +    };
134.2949 +
134.2950 +    // C++ wrapper for IfcCartesianTransformationOperator3DnonUniform
134.2951 +    struct IfcCartesianTransformationOperator3DnonUniform : IfcCartesianTransformationOperator3D, ObjectHelper<IfcCartesianTransformationOperator3DnonUniform,2> { IfcCartesianTransformationOperator3DnonUniform() : Object("IfcCartesianTransformationOperator3DnonUniform") {}
134.2952 +		Maybe< REAL::Out > Scale2;
134.2953 +		Maybe< REAL::Out > Scale3;
134.2954 +    };
134.2955 +
134.2956 +    // C++ wrapper for IfcCurtainWallType
134.2957 +    struct IfcCurtainWallType : IfcBuildingElementType, ObjectHelper<IfcCurtainWallType,1> { IfcCurtainWallType() : Object("IfcCurtainWallType") {}
134.2958 +		IfcCurtainWallTypeEnum::Out PredefinedType;
134.2959 +    };
134.2960 +
134.2961 +    // C++ wrapper for IfcEquipmentStandard
134.2962 +    struct IfcEquipmentStandard : IfcControl, ObjectHelper<IfcEquipmentStandard,0> { IfcEquipmentStandard() : Object("IfcEquipmentStandard") {}
134.2963 +
134.2964 +    };
134.2965 +
134.2966 +    // C++ wrapper for IfcFlowStorageDeviceType
134.2967 +    struct IfcFlowStorageDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowStorageDeviceType,0> { IfcFlowStorageDeviceType() : Object("IfcFlowStorageDeviceType") {}
134.2968 +
134.2969 +    };
134.2970 +
134.2971 +    // C++ wrapper for IfcDiameterDimension
134.2972 +    struct IfcDiameterDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcDiameterDimension,0> { IfcDiameterDimension() : Object("IfcDiameterDimension") {}
134.2973 +
134.2974 +    };
134.2975 +
134.2976 +    // C++ wrapper for IfcSwitchingDeviceType
134.2977 +    struct IfcSwitchingDeviceType : IfcFlowControllerType, ObjectHelper<IfcSwitchingDeviceType,1> { IfcSwitchingDeviceType() : Object("IfcSwitchingDeviceType") {}
134.2978 +		IfcSwitchingDeviceTypeEnum::Out PredefinedType;
134.2979 +    };
134.2980 +
134.2981 +    // C++ wrapper for IfcWindow
134.2982 +    struct IfcWindow : IfcBuildingElement, ObjectHelper<IfcWindow,2> { IfcWindow() : Object("IfcWindow") {}
134.2983 +		Maybe< IfcPositiveLengthMeasure::Out > OverallHeight;
134.2984 +		Maybe< IfcPositiveLengthMeasure::Out > OverallWidth;
134.2985 +    };
134.2986 +
134.2987 +    // C++ wrapper for IfcFlowTreatmentDevice
134.2988 +    struct IfcFlowTreatmentDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowTreatmentDevice,0> { IfcFlowTreatmentDevice() : Object("IfcFlowTreatmentDevice") {}
134.2989 +
134.2990 +    };
134.2991 +
134.2992 +    // C++ wrapper for IfcChillerType
134.2993 +    struct IfcChillerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcChillerType,1> { IfcChillerType() : Object("IfcChillerType") {}
134.2994 +		IfcChillerTypeEnum::Out PredefinedType;
134.2995 +    };
134.2996 +
134.2997 +    // C++ wrapper for IfcRectangleHollowProfileDef
134.2998 +    struct IfcRectangleHollowProfileDef : IfcRectangleProfileDef, ObjectHelper<IfcRectangleHollowProfileDef,3> { IfcRectangleHollowProfileDef() : Object("IfcRectangleHollowProfileDef") {}
134.2999 +		IfcPositiveLengthMeasure::Out WallThickness;
134.3000 +		Maybe< IfcPositiveLengthMeasure::Out > InnerFilletRadius;
134.3001 +		Maybe< IfcPositiveLengthMeasure::Out > OuterFilletRadius;
134.3002 +    };
134.3003 +
134.3004 +    // C++ wrapper for IfcBoxedHalfSpace
134.3005 +    struct IfcBoxedHalfSpace : IfcHalfSpaceSolid, ObjectHelper<IfcBoxedHalfSpace,1> { IfcBoxedHalfSpace() : Object("IfcBoxedHalfSpace") {}
134.3006 +		Lazy< IfcBoundingBox > Enclosure;
134.3007 +    };
134.3008 +
134.3009 +    // C++ wrapper for IfcAxis2Placement2D
134.3010 +    struct IfcAxis2Placement2D : IfcPlacement, ObjectHelper<IfcAxis2Placement2D,1> { IfcAxis2Placement2D() : Object("IfcAxis2Placement2D") {}
134.3011 +		Maybe< Lazy< IfcDirection > > RefDirection;
134.3012 +    };
134.3013 +
134.3014 +    // C++ wrapper for IfcSpaceProgram
134.3015 +    struct IfcSpaceProgram : IfcControl, ObjectHelper<IfcSpaceProgram,5> { IfcSpaceProgram() : Object("IfcSpaceProgram") {}
134.3016 +		IfcIdentifier::Out SpaceProgramIdentifier;
134.3017 +		Maybe< IfcAreaMeasure::Out > MaxRequiredArea;
134.3018 +		Maybe< IfcAreaMeasure::Out > MinRequiredArea;
134.3019 +		Maybe< Lazy< IfcSpatialStructureElement > > RequestedLocation;
134.3020 +		IfcAreaMeasure::Out StandardRequiredArea;
134.3021 +    };
134.3022 +
134.3023 +    // C++ wrapper for IfcPoint
134.3024 +    struct IfcPoint : IfcGeometricRepresentationItem, ObjectHelper<IfcPoint,0> { IfcPoint() : Object("IfcPoint") {}
134.3025 +
134.3026 +    };
134.3027 +
134.3028 +    // C++ wrapper for IfcCartesianPoint
134.3029 +    struct IfcCartesianPoint : IfcPoint, ObjectHelper<IfcCartesianPoint,1> { IfcCartesianPoint() : Object("IfcCartesianPoint") {}
134.3030 +		ListOf< IfcLengthMeasure, 1, 3 >::Out Coordinates;
134.3031 +    };
134.3032 +
134.3033 +    // C++ wrapper for IfcBoundedSurface
134.3034 +    struct IfcBoundedSurface : IfcSurface, ObjectHelper<IfcBoundedSurface,0> { IfcBoundedSurface() : Object("IfcBoundedSurface") {}
134.3035 +
134.3036 +    };
134.3037 +
134.3038 +    // C++ wrapper for IfcLoop
134.3039 +    struct IfcLoop : IfcTopologicalRepresentationItem, ObjectHelper<IfcLoop,0> { IfcLoop() : Object("IfcLoop") {}
134.3040 +
134.3041 +    };
134.3042 +
134.3043 +    // C++ wrapper for IfcPolyLoop
134.3044 +    struct IfcPolyLoop : IfcLoop, ObjectHelper<IfcPolyLoop,1> { IfcPolyLoop() : Object("IfcPolyLoop") {}
134.3045 +		ListOf< Lazy< IfcCartesianPoint >, 3, 0 > Polygon;
134.3046 +    };
134.3047 +
134.3048 +    // C++ wrapper for IfcTerminatorSymbol
134.3049 +    struct IfcTerminatorSymbol : IfcAnnotationSymbolOccurrence, ObjectHelper<IfcTerminatorSymbol,1> { IfcTerminatorSymbol() : Object("IfcTerminatorSymbol") {}
134.3050 +		Lazy< IfcAnnotationCurveOccurrence > AnnotatedCurve;
134.3051 +    };
134.3052 +
134.3053 +    // C++ wrapper for IfcDimensionCurveTerminator
134.3054 +    struct IfcDimensionCurveTerminator : IfcTerminatorSymbol, ObjectHelper<IfcDimensionCurveTerminator,1> { IfcDimensionCurveTerminator() : Object("IfcDimensionCurveTerminator") {}
134.3055 +		IfcDimensionExtentUsage::Out Role;
134.3056 +    };
134.3057 +
134.3058 +    // C++ wrapper for IfcTrapeziumProfileDef
134.3059 +    struct IfcTrapeziumProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcTrapeziumProfileDef,4> { IfcTrapeziumProfileDef() : Object("IfcTrapeziumProfileDef") {}
134.3060 +		IfcPositiveLengthMeasure::Out BottomXDim;
134.3061 +		IfcPositiveLengthMeasure::Out TopXDim;
134.3062 +		IfcPositiveLengthMeasure::Out YDim;
134.3063 +		IfcLengthMeasure::Out TopXOffset;
134.3064 +    };
134.3065 +
134.3066 +    // C++ wrapper for IfcRepresentationContext
134.3067 +    struct IfcRepresentationContext :  ObjectHelper<IfcRepresentationContext,2> { IfcRepresentationContext() : Object("IfcRepresentationContext") {}
134.3068 +		Maybe< IfcLabel::Out > ContextIdentifier;
134.3069 +		Maybe< IfcLabel::Out > ContextType;
134.3070 +    };
134.3071 +
134.3072 +    // C++ wrapper for IfcGeometricRepresentationContext
134.3073 +    struct IfcGeometricRepresentationContext : IfcRepresentationContext, ObjectHelper<IfcGeometricRepresentationContext,4> { IfcGeometricRepresentationContext() : Object("IfcGeometricRepresentationContext") {}
134.3074 +		IfcDimensionCount::Out CoordinateSpaceDimension;
134.3075 +		Maybe< REAL::Out > Precision;
134.3076 +		IfcAxis2Placement::Out WorldCoordinateSystem;
134.3077 +		Maybe< Lazy< IfcDirection > > TrueNorth;
134.3078 +    };
134.3079 +
134.3080 +    // C++ wrapper for IfcCurveBoundedPlane
134.3081 +    struct IfcCurveBoundedPlane : IfcBoundedSurface, ObjectHelper<IfcCurveBoundedPlane,3> { IfcCurveBoundedPlane() : Object("IfcCurveBoundedPlane") {}
134.3082 +		Lazy< IfcPlane > BasisSurface;
134.3083 +		Lazy< IfcCurve > OuterBoundary;
134.3084 +		ListOf< Lazy< IfcCurve >, 0, 0 > InnerBoundaries;
134.3085 +    };
134.3086 +
134.3087 +    // C++ wrapper for IfcSIUnit
134.3088 +    struct IfcSIUnit : IfcNamedUnit, ObjectHelper<IfcSIUnit,2> { IfcSIUnit() : Object("IfcSIUnit") {}
134.3089 +		Maybe< IfcSIPrefix::Out > Prefix;
134.3090 +		IfcSIUnitName::Out Name;
134.3091 +    };
134.3092 +
134.3093 +    // C++ wrapper for IfcStructuralReaction
134.3094 +    struct IfcStructuralReaction : IfcStructuralActivity, ObjectHelper<IfcStructuralReaction,0> { IfcStructuralReaction() : Object("IfcStructuralReaction") {}
134.3095 +
134.3096 +    };
134.3097 +
134.3098 +    // C++ wrapper for IfcStructuralPointReaction
134.3099 +    struct IfcStructuralPointReaction : IfcStructuralReaction, ObjectHelper<IfcStructuralPointReaction,0> { IfcStructuralPointReaction() : Object("IfcStructuralPointReaction") {}
134.3100 +
134.3101 +    };
134.3102 +
134.3103 +    // C++ wrapper for IfcAxis1Placement
134.3104 +    struct IfcAxis1Placement : IfcPlacement, ObjectHelper<IfcAxis1Placement,1> { IfcAxis1Placement() : Object("IfcAxis1Placement") {}
134.3105 +		Maybe< Lazy< IfcDirection > > Axis;
134.3106 +    };
134.3107 +
134.3108 +    // C++ wrapper for IfcElectricApplianceType
134.3109 +    struct IfcElectricApplianceType : IfcFlowTerminalType, ObjectHelper<IfcElectricApplianceType,1> { IfcElectricApplianceType() : Object("IfcElectricApplianceType") {}
134.3110 +		IfcElectricApplianceTypeEnum::Out PredefinedType;
134.3111 +    };
134.3112 +
134.3113 +    // C++ wrapper for IfcSensorType
134.3114 +    struct IfcSensorType : IfcDistributionControlElementType, ObjectHelper<IfcSensorType,1> { IfcSensorType() : Object("IfcSensorType") {}
134.3115 +		IfcSensorTypeEnum::Out PredefinedType;
134.3116 +    };
134.3117 +
134.3118 +    // C++ wrapper for IfcFurnishingElement
134.3119 +    struct IfcFurnishingElement : IfcElement, ObjectHelper<IfcFurnishingElement,0> { IfcFurnishingElement() : Object("IfcFurnishingElement") {}
134.3120 +
134.3121 +    };
134.3122 +
134.3123 +    // C++ wrapper for IfcProtectiveDeviceType
134.3124 +    struct IfcProtectiveDeviceType : IfcFlowControllerType, ObjectHelper<IfcProtectiveDeviceType,1> { IfcProtectiveDeviceType() : Object("IfcProtectiveDeviceType") {}
134.3125 +		IfcProtectiveDeviceTypeEnum::Out PredefinedType;
134.3126 +    };
134.3127 +
134.3128 +    // C++ wrapper for IfcZShapeProfileDef
134.3129 +    struct IfcZShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcZShapeProfileDef,6> { IfcZShapeProfileDef() : Object("IfcZShapeProfileDef") {}
134.3130 +		IfcPositiveLengthMeasure::Out Depth;
134.3131 +		IfcPositiveLengthMeasure::Out FlangeWidth;
134.3132 +		IfcPositiveLengthMeasure::Out WebThickness;
134.3133 +		IfcPositiveLengthMeasure::Out FlangeThickness;
134.3134 +		Maybe< IfcPositiveLengthMeasure::Out > FilletRadius;
134.3135 +		Maybe< IfcPositiveLengthMeasure::Out > EdgeRadius;
134.3136 +    };
134.3137 +
134.3138 +    // C++ wrapper for IfcScheduleTimeControl
134.3139 +    struct IfcScheduleTimeControl : IfcControl, ObjectHelper<IfcScheduleTimeControl,18> { IfcScheduleTimeControl() : Object("IfcScheduleTimeControl") {}
134.3140 +		Maybe< IfcDateTimeSelect::Out > ActualStart;
134.3141 +		Maybe< IfcDateTimeSelect::Out > EarlyStart;
134.3142 +		Maybe< IfcDateTimeSelect::Out > LateStart;
134.3143 +		Maybe< IfcDateTimeSelect::Out > ScheduleStart;
134.3144 +		Maybe< IfcDateTimeSelect::Out > ActualFinish;
134.3145 +		Maybe< IfcDateTimeSelect::Out > EarlyFinish;
134.3146 +		Maybe< IfcDateTimeSelect::Out > LateFinish;
134.3147 +		Maybe< IfcDateTimeSelect::Out > ScheduleFinish;
134.3148 +		Maybe< IfcTimeMeasure::Out > ScheduleDuration;
134.3149 +		Maybe< IfcTimeMeasure::Out > ActualDuration;
134.3150 +		Maybe< IfcTimeMeasure::Out > RemainingTime;
134.3151 +		Maybe< IfcTimeMeasure::Out > FreeFloat;
134.3152 +		Maybe< IfcTimeMeasure::Out > TotalFloat;
134.3153 +		Maybe< BOOLEAN::Out > IsCritical;
134.3154 +		Maybe< IfcDateTimeSelect::Out > StatusTime;
134.3155 +		Maybe< IfcTimeMeasure::Out > StartFloat;
134.3156 +		Maybe< IfcTimeMeasure::Out > FinishFloat;
134.3157 +		Maybe< IfcPositiveRatioMeasure::Out > Completion;
134.3158 +    };
134.3159 +
134.3160 +    // C++ wrapper for IfcRepresentationMap
134.3161 +    struct IfcRepresentationMap :  ObjectHelper<IfcRepresentationMap,2> { IfcRepresentationMap() : Object("IfcRepresentationMap") {}
134.3162 +		IfcAxis2Placement::Out MappingOrigin;
134.3163 +		Lazy< IfcRepresentation > MappedRepresentation;
134.3164 +    };
134.3165 +
134.3166 +    // C++ wrapper for IfcClosedShell
134.3167 +    struct IfcClosedShell : IfcConnectedFaceSet, ObjectHelper<IfcClosedShell,0> { IfcClosedShell() : Object("IfcClosedShell") {}
134.3168 +
134.3169 +    };
134.3170 +
134.3171 +    // C++ wrapper for IfcBuildingElementPart
134.3172 +    struct IfcBuildingElementPart : IfcBuildingElementComponent, ObjectHelper<IfcBuildingElementPart,0> { IfcBuildingElementPart() : Object("IfcBuildingElementPart") {}
134.3173 +
134.3174 +    };
134.3175 +
134.3176 +    // C++ wrapper for IfcBlock
134.3177 +    struct IfcBlock : IfcCsgPrimitive3D, ObjectHelper<IfcBlock,3> { IfcBlock() : Object("IfcBlock") {}
134.3178 +		IfcPositiveLengthMeasure::Out XLength;
134.3179 +		IfcPositiveLengthMeasure::Out YLength;
134.3180 +		IfcPositiveLengthMeasure::Out ZLength;
134.3181 +    };
134.3182 +
134.3183 +    // C++ wrapper for IfcLightFixtureType
134.3184 +    struct IfcLightFixtureType : IfcFlowTerminalType, ObjectHelper<IfcLightFixtureType,1> { IfcLightFixtureType() : Object("IfcLightFixtureType") {}
134.3185 +		IfcLightFixtureTypeEnum::Out PredefinedType;
134.3186 +    };
134.3187 +
134.3188 +    // C++ wrapper for IfcOpeningElement
134.3189 +    struct IfcOpeningElement : IfcFeatureElementSubtraction, ObjectHelper<IfcOpeningElement,0> { IfcOpeningElement() : Object("IfcOpeningElement") {}
134.3190 +
134.3191 +    };
134.3192 +
134.3193 +    // C++ wrapper for IfcLightSourceSpot
134.3194 +    struct IfcLightSourceSpot : IfcLightSourcePositional, ObjectHelper<IfcLightSourceSpot,4> { IfcLightSourceSpot() : Object("IfcLightSourceSpot") {}
134.3195 +		Lazy< IfcDirection > Orientation;
134.3196 +		Maybe< IfcReal::Out > ConcentrationExponent;
134.3197 +		IfcPositivePlaneAngleMeasure::Out SpreadAngle;
134.3198 +		IfcPositivePlaneAngleMeasure::Out BeamWidthAngle;
134.3199 +    };
134.3200 +
134.3201 +    // C++ wrapper for IfcTendonAnchor
134.3202 +    struct IfcTendonAnchor : IfcReinforcingElement, ObjectHelper<IfcTendonAnchor,0> { IfcTendonAnchor() : Object("IfcTendonAnchor") {}
134.3203 +
134.3204 +    };
134.3205 +
134.3206 +    // C++ wrapper for IfcElectricFlowStorageDeviceType
134.3207 +    struct IfcElectricFlowStorageDeviceType : IfcFlowStorageDeviceType, ObjectHelper<IfcElectricFlowStorageDeviceType,1> { IfcElectricFlowStorageDeviceType() : Object("IfcElectricFlowStorageDeviceType") {}
134.3208 +		IfcElectricFlowStorageDeviceTypeEnum::Out PredefinedType;
134.3209 +    };
134.3210 +
134.3211 +    // C++ wrapper for IfcSphere
134.3212 +    struct IfcSphere : IfcCsgPrimitive3D, ObjectHelper<IfcSphere,1> { IfcSphere() : Object("IfcSphere") {}
134.3213 +		IfcPositiveLengthMeasure::Out Radius;
134.3214 +    };
134.3215 +
134.3216 +    // C++ wrapper for IfcDamperType
134.3217 +    struct IfcDamperType : IfcFlowControllerType, ObjectHelper<IfcDamperType,1> { IfcDamperType() : Object("IfcDamperType") {}
134.3218 +		IfcDamperTypeEnum::Out PredefinedType;
134.3219 +    };
134.3220 +
134.3221 +    // C++ wrapper for IfcProjectOrderRecord
134.3222 +    struct IfcProjectOrderRecord : IfcControl, ObjectHelper<IfcProjectOrderRecord,2> { IfcProjectOrderRecord() : Object("IfcProjectOrderRecord") {}
134.3223 +		ListOf< Lazy< NotImplemented >, 1, 0 > Records;
134.3224 +		IfcProjectOrderRecordTypeEnum::Out PredefinedType;
134.3225 +    };
134.3226 +
134.3227 +    // C++ wrapper for IfcDistributionChamberElement
134.3228 +    struct IfcDistributionChamberElement : IfcDistributionFlowElement, ObjectHelper<IfcDistributionChamberElement,0> { IfcDistributionChamberElement() : Object("IfcDistributionChamberElement") {}
134.3229 +
134.3230 +    };
134.3231 +
134.3232 +    // C++ wrapper for IfcMechanicalFastener
134.3233 +    struct IfcMechanicalFastener : IfcFastener, ObjectHelper<IfcMechanicalFastener,2> { IfcMechanicalFastener() : Object("IfcMechanicalFastener") {}
134.3234 +		Maybe< IfcPositiveLengthMeasure::Out > NominalDiameter;
134.3235 +		Maybe< IfcPositiveLengthMeasure::Out > NominalLength;
134.3236 +    };
134.3237 +
134.3238 +    // C++ wrapper for IfcRectangularTrimmedSurface
134.3239 +    struct IfcRectangularTrimmedSurface : IfcBoundedSurface, ObjectHelper<IfcRectangularTrimmedSurface,7> { IfcRectangularTrimmedSurface() : Object("IfcRectangularTrimmedSurface") {}
134.3240 +		Lazy< IfcSurface > BasisSurface;
134.3241 +		IfcParameterValue::Out U1;
134.3242 +		IfcParameterValue::Out V1;
134.3243 +		IfcParameterValue::Out U2;
134.3244 +		IfcParameterValue::Out V2;
134.3245 +		BOOLEAN::Out Usense;
134.3246 +		BOOLEAN::Out Vsense;
134.3247 +    };
134.3248 +
134.3249 +    // C++ wrapper for IfcZone
134.3250 +    struct IfcZone : IfcGroup, ObjectHelper<IfcZone,0> { IfcZone() : Object("IfcZone") {}
134.3251 +
134.3252 +    };
134.3253 +
134.3254 +    // C++ wrapper for IfcFanType
134.3255 +    struct IfcFanType : IfcFlowMovingDeviceType, ObjectHelper<IfcFanType,1> { IfcFanType() : Object("IfcFanType") {}
134.3256 +		IfcFanTypeEnum::Out PredefinedType;
134.3257 +    };
134.3258 +
134.3259 +    // C++ wrapper for IfcGeometricSet
134.3260 +    struct IfcGeometricSet : IfcGeometricRepresentationItem, ObjectHelper<IfcGeometricSet,1> { IfcGeometricSet() : Object("IfcGeometricSet") {}
134.3261 +		ListOf< IfcGeometricSetSelect, 1, 0 >::Out Elements;
134.3262 +    };
134.3263 +
134.3264 +    // C++ wrapper for IfcFillAreaStyleTiles
134.3265 +    struct IfcFillAreaStyleTiles : IfcGeometricRepresentationItem, ObjectHelper<IfcFillAreaStyleTiles,3> { IfcFillAreaStyleTiles() : Object("IfcFillAreaStyleTiles") {}
134.3266 +		Lazy< IfcOneDirectionRepeatFactor > TilingPattern;
134.3267 +		ListOf< IfcFillAreaStyleTileShapeSelect, 1, 0 >::Out Tiles;
134.3268 +		IfcPositiveRatioMeasure::Out TilingScale;
134.3269 +    };
134.3270 +
134.3271 +    // C++ wrapper for IfcCableSegmentType
134.3272 +    struct IfcCableSegmentType : IfcFlowSegmentType, ObjectHelper<IfcCableSegmentType,1> { IfcCableSegmentType() : Object("IfcCableSegmentType") {}
134.3273 +		IfcCableSegmentTypeEnum::Out PredefinedType;
134.3274 +    };
134.3275 +
134.3276 +    // C++ wrapper for IfcRelOverridesProperties
134.3277 +    struct IfcRelOverridesProperties : IfcRelDefinesByProperties, ObjectHelper<IfcRelOverridesProperties,1> { IfcRelOverridesProperties() : Object("IfcRelOverridesProperties") {}
134.3278 +		ListOf< Lazy< IfcProperty >, 1, 0 > OverridingProperties;
134.3279 +    };
134.3280 +
134.3281 +    // C++ wrapper for IfcMeasureWithUnit
134.3282 +    struct IfcMeasureWithUnit :  ObjectHelper<IfcMeasureWithUnit,2> { IfcMeasureWithUnit() : Object("IfcMeasureWithUnit") {}
134.3283 +		IfcValue::Out ValueComponent;
134.3284 +		IfcUnit::Out UnitComponent;
134.3285 +    };
134.3286 +
134.3287 +    // C++ wrapper for IfcSlabType
134.3288 +    struct IfcSlabType : IfcBuildingElementType, ObjectHelper<IfcSlabType,1> { IfcSlabType() : Object("IfcSlabType") {}
134.3289 +		IfcSlabTypeEnum::Out PredefinedType;
134.3290 +    };
134.3291 +
134.3292 +    // C++ wrapper for IfcServiceLife
134.3293 +    struct IfcServiceLife : IfcControl, ObjectHelper<IfcServiceLife,2> { IfcServiceLife() : Object("IfcServiceLife") {}
134.3294 +		IfcServiceLifeTypeEnum::Out ServiceLifeType;
134.3295 +		IfcTimeMeasure::Out ServiceLifeDuration;
134.3296 +    };
134.3297 +
134.3298 +    // C++ wrapper for IfcFurnitureType
134.3299 +    struct IfcFurnitureType : IfcFurnishingElementType, ObjectHelper<IfcFurnitureType,1> { IfcFurnitureType() : Object("IfcFurnitureType") {}
134.3300 +		IfcAssemblyPlaceEnum::Out AssemblyPlace;
134.3301 +    };
134.3302 +
134.3303 +    // C++ wrapper for IfcCostItem
134.3304 +    struct IfcCostItem : IfcControl, ObjectHelper<IfcCostItem,0> { IfcCostItem() : Object("IfcCostItem") {}
134.3305 +
134.3306 +    };
134.3307 +
134.3308 +    // C++ wrapper for IfcReinforcingMesh
134.3309 +    struct IfcReinforcingMesh : IfcReinforcingElement, ObjectHelper<IfcReinforcingMesh,8> { IfcReinforcingMesh() : Object("IfcReinforcingMesh") {}
134.3310 +		Maybe< IfcPositiveLengthMeasure::Out > MeshLength;
134.3311 +		Maybe< IfcPositiveLengthMeasure::Out > MeshWidth;
134.3312 +		IfcPositiveLengthMeasure::Out LongitudinalBarNominalDiameter;
134.3313 +		IfcPositiveLengthMeasure::Out TransverseBarNominalDiameter;
134.3314 +		IfcAreaMeasure::Out LongitudinalBarCrossSectionArea;
134.3315 +		IfcAreaMeasure::Out TransverseBarCrossSectionArea;
134.3316 +		IfcPositiveLengthMeasure::Out LongitudinalBarSpacing;
134.3317 +		IfcPositiveLengthMeasure::Out TransverseBarSpacing;
134.3318 +    };
134.3319 +
134.3320 +    // C++ wrapper for IfcFacetedBrepWithVoids
134.3321 +    struct IfcFacetedBrepWithVoids : IfcManifoldSolidBrep, ObjectHelper<IfcFacetedBrepWithVoids,1> { IfcFacetedBrepWithVoids() : Object("IfcFacetedBrepWithVoids") {}
134.3322 +		ListOf< Lazy< IfcClosedShell >, 1, 0 > Voids;
134.3323 +    };
134.3324 +
134.3325 +    // C++ wrapper for IfcGasTerminalType
134.3326 +    struct IfcGasTerminalType : IfcFlowTerminalType, ObjectHelper<IfcGasTerminalType,1> { IfcGasTerminalType() : Object("IfcGasTerminalType") {}
134.3327 +		IfcGasTerminalTypeEnum::Out PredefinedType;
134.3328 +    };
134.3329 +
134.3330 +    // C++ wrapper for IfcPile
134.3331 +    struct IfcPile : IfcBuildingElement, ObjectHelper<IfcPile,2> { IfcPile() : Object("IfcPile") {}
134.3332 +		IfcPileTypeEnum::Out PredefinedType;
134.3333 +		Maybe< IfcPileConstructionEnum::Out > ConstructionType;
134.3334 +    };
134.3335 +
134.3336 +    // C++ wrapper for IfcFillAreaStyleTileSymbolWithStyle
134.3337 +    struct IfcFillAreaStyleTileSymbolWithStyle : IfcGeometricRepresentationItem, ObjectHelper<IfcFillAreaStyleTileSymbolWithStyle,1> { IfcFillAreaStyleTileSymbolWithStyle() : Object("IfcFillAreaStyleTileSymbolWithStyle") {}
134.3338 +		Lazy< IfcAnnotationSymbolOccurrence > Symbol;
134.3339 +    };
134.3340 +
134.3341 +    // C++ wrapper for IfcConstructionMaterialResource
134.3342 +    struct IfcConstructionMaterialResource : IfcConstructionResource, ObjectHelper<IfcConstructionMaterialResource,2> { IfcConstructionMaterialResource() : Object("IfcConstructionMaterialResource") {}
134.3343 +		Maybe< ListOf< IfcActorSelect, 1, 0 >::Out > Suppliers;
134.3344 +		Maybe< IfcRatioMeasure::Out > UsageRatio;
134.3345 +    };
134.3346 +
134.3347 +    // C++ wrapper for IfcAnnotationCurveOccurrence
134.3348 +    struct IfcAnnotationCurveOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationCurveOccurrence,0> { IfcAnnotationCurveOccurrence() : Object("IfcAnnotationCurveOccurrence") {}
134.3349 +
134.3350 +    };
134.3351 +
134.3352 +    // C++ wrapper for IfcDimensionCurve
134.3353 +    struct IfcDimensionCurve : IfcAnnotationCurveOccurrence, ObjectHelper<IfcDimensionCurve,0> { IfcDimensionCurve() : Object("IfcDimensionCurve") {}
134.3354 +
134.3355 +    };
134.3356 +
134.3357 +    // C++ wrapper for IfcGeometricCurveSet
134.3358 +    struct IfcGeometricCurveSet : IfcGeometricSet, ObjectHelper<IfcGeometricCurveSet,0> { IfcGeometricCurveSet() : Object("IfcGeometricCurveSet") {}
134.3359 +
134.3360 +    };
134.3361 +
134.3362 +    // C++ wrapper for IfcRelAggregates
134.3363 +    struct IfcRelAggregates : IfcRelDecomposes, ObjectHelper<IfcRelAggregates,0> { IfcRelAggregates() : Object("IfcRelAggregates") {}
134.3364 +
134.3365 +    };
134.3366 +
134.3367 +    // C++ wrapper for IfcFaceBasedSurfaceModel
134.3368 +    struct IfcFaceBasedSurfaceModel : IfcGeometricRepresentationItem, ObjectHelper<IfcFaceBasedSurfaceModel,1> { IfcFaceBasedSurfaceModel() : Object("IfcFaceBasedSurfaceModel") {}
134.3369 +		ListOf< Lazy< IfcConnectedFaceSet >, 1, 0 > FbsmFaces;
134.3370 +    };
134.3371 +
134.3372 +    // C++ wrapper for IfcEnergyConversionDevice
134.3373 +    struct IfcEnergyConversionDevice : IfcDistributionFlowElement, ObjectHelper<IfcEnergyConversionDevice,0> { IfcEnergyConversionDevice() : Object("IfcEnergyConversionDevice") {}
134.3374 +
134.3375 +    };
134.3376 +
134.3377 +    // C++ wrapper for IfcRampFlight
134.3378 +    struct IfcRampFlight : IfcBuildingElement, ObjectHelper<IfcRampFlight,0> { IfcRampFlight() : Object("IfcRampFlight") {}
134.3379 +
134.3380 +    };
134.3381 +
134.3382 +    // C++ wrapper for IfcVertexLoop
134.3383 +    struct IfcVertexLoop : IfcLoop, ObjectHelper<IfcVertexLoop,1> { IfcVertexLoop() : Object("IfcVertexLoop") {}
134.3384 +		Lazy< IfcVertex > LoopVertex;
134.3385 +    };
134.3386 +
134.3387 +    // C++ wrapper for IfcPlate
134.3388 +    struct IfcPlate : IfcBuildingElement, ObjectHelper<IfcPlate,0> { IfcPlate() : Object("IfcPlate") {}
134.3389 +
134.3390 +    };
134.3391 +
134.3392 +    // C++ wrapper for IfcUShapeProfileDef
134.3393 +    struct IfcUShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcUShapeProfileDef,8> { IfcUShapeProfileDef() : Object("IfcUShapeProfileDef") {}
134.3394 +		IfcPositiveLengthMeasure::Out Depth;
134.3395 +		IfcPositiveLengthMeasure::Out FlangeWidth;
134.3396 +		IfcPositiveLengthMeasure::Out WebThickness;
134.3397 +		IfcPositiveLengthMeasure::Out FlangeThickness;
134.3398 +		Maybe< IfcPositiveLengthMeasure::Out > FilletRadius;
134.3399 +		Maybe< IfcPositiveLengthMeasure::Out > EdgeRadius;
134.3400 +		Maybe< IfcPlaneAngleMeasure::Out > FlangeSlope;
134.3401 +		Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInX;
134.3402 +    };
134.3403 +
134.3404 +    // C++ wrapper for IfcFaceBound
134.3405 +    struct IfcFaceBound : IfcTopologicalRepresentationItem, ObjectHelper<IfcFaceBound,2> { IfcFaceBound() : Object("IfcFaceBound") {}
134.3406 +		Lazy< IfcLoop > Bound;
134.3407 +		BOOLEAN::Out Orientation;
134.3408 +    };
134.3409 +
134.3410 +    // C++ wrapper for IfcFaceOuterBound
134.3411 +    struct IfcFaceOuterBound : IfcFaceBound, ObjectHelper<IfcFaceOuterBound,0> { IfcFaceOuterBound() : Object("IfcFaceOuterBound") {}
134.3412 +
134.3413 +    };
134.3414 +
134.3415 +    // C++ wrapper for IfcOneDirectionRepeatFactor
134.3416 +    struct IfcOneDirectionRepeatFactor : IfcGeometricRepresentationItem, ObjectHelper<IfcOneDirectionRepeatFactor,1> { IfcOneDirectionRepeatFactor() : Object("IfcOneDirectionRepeatFactor") {}
134.3417 +		Lazy< IfcVector > RepeatFactor;
134.3418 +    };
134.3419 +
134.3420 +    // C++ wrapper for IfcBoilerType
134.3421 +    struct IfcBoilerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcBoilerType,1> { IfcBoilerType() : Object("IfcBoilerType") {}
134.3422 +		IfcBoilerTypeEnum::Out PredefinedType;
134.3423 +    };
134.3424 +
134.3425 +    // C++ wrapper for IfcConstructionEquipmentResource
134.3426 +    struct IfcConstructionEquipmentResource : IfcConstructionResource, ObjectHelper<IfcConstructionEquipmentResource,0> { IfcConstructionEquipmentResource() : Object("IfcConstructionEquipmentResource") {}
134.3427 +
134.3428 +    };
134.3429 +
134.3430 +    // C++ wrapper for IfcComplexProperty
134.3431 +    struct IfcComplexProperty : IfcProperty, ObjectHelper<IfcComplexProperty,2> { IfcComplexProperty() : Object("IfcComplexProperty") {}
134.3432 +		IfcIdentifier::Out UsageName;
134.3433 +		ListOf< Lazy< IfcProperty >, 1, 0 > HasProperties;
134.3434 +    };
134.3435 +
134.3436 +    // C++ wrapper for IfcFooting
134.3437 +    struct IfcFooting : IfcBuildingElement, ObjectHelper<IfcFooting,1> { IfcFooting() : Object("IfcFooting") {}
134.3438 +		IfcFootingTypeEnum::Out PredefinedType;
134.3439 +    };
134.3440 +
134.3441 +    // C++ wrapper for IfcConstructionProductResource
134.3442 +    struct IfcConstructionProductResource : IfcConstructionResource, ObjectHelper<IfcConstructionProductResource,0> { IfcConstructionProductResource() : Object("IfcConstructionProductResource") {}
134.3443 +
134.3444 +    };
134.3445 +
134.3446 +    // C++ wrapper for IfcDerivedProfileDef
134.3447 +    struct IfcDerivedProfileDef : IfcProfileDef, ObjectHelper<IfcDerivedProfileDef,3> { IfcDerivedProfileDef() : Object("IfcDerivedProfileDef") {}
134.3448 +		Lazy< IfcProfileDef > ParentProfile;
134.3449 +		Lazy< IfcCartesianTransformationOperator2D > Operator;
134.3450 +		Maybe< IfcLabel::Out > Label;
134.3451 +    };
134.3452 +
134.3453 +    // C++ wrapper for IfcPropertyTableValue
134.3454 +    struct IfcPropertyTableValue : IfcSimpleProperty, ObjectHelper<IfcPropertyTableValue,5> { IfcPropertyTableValue() : Object("IfcPropertyTableValue") {}
134.3455 +		ListOf< IfcValue, 1, 0 >::Out DefiningValues;
134.3456 +		ListOf< IfcValue, 1, 0 >::Out DefinedValues;
134.3457 +		Maybe< IfcText::Out > Expression;
134.3458 +		Maybe< IfcUnit::Out > DefiningUnit;
134.3459 +		Maybe< IfcUnit::Out > DefinedUnit;
134.3460 +    };
134.3461 +
134.3462 +    // C++ wrapper for IfcFlowMeterType
134.3463 +    struct IfcFlowMeterType : IfcFlowControllerType, ObjectHelper<IfcFlowMeterType,1> { IfcFlowMeterType() : Object("IfcFlowMeterType") {}
134.3464 +		IfcFlowMeterTypeEnum::Out PredefinedType;
134.3465 +    };
134.3466 +
134.3467 +    // C++ wrapper for IfcDoorStyle
134.3468 +    struct IfcDoorStyle : IfcTypeProduct, ObjectHelper<IfcDoorStyle,4> { IfcDoorStyle() : Object("IfcDoorStyle") {}
134.3469 +		IfcDoorStyleOperationEnum::Out OperationType;
134.3470 +		IfcDoorStyleConstructionEnum::Out ConstructionType;
134.3471 +		BOOLEAN::Out ParameterTakesPrecedence;
134.3472 +		BOOLEAN::Out Sizeable;
134.3473 +    };
134.3474 +
134.3475 +    // C++ wrapper for IfcUnitAssignment
134.3476 +    struct IfcUnitAssignment :  ObjectHelper<IfcUnitAssignment,1> { IfcUnitAssignment() : Object("IfcUnitAssignment") {}
134.3477 +		ListOf< IfcUnit, 1, 0 >::Out Units;
134.3478 +    };
134.3479 +
134.3480 +    // C++ wrapper for IfcFlowTerminal
134.3481 +    struct IfcFlowTerminal : IfcDistributionFlowElement, ObjectHelper<IfcFlowTerminal,0> { IfcFlowTerminal() : Object("IfcFlowTerminal") {}
134.3482 +
134.3483 +    };
134.3484 +
134.3485 +    // C++ wrapper for IfcCraneRailFShapeProfileDef
134.3486 +    struct IfcCraneRailFShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCraneRailFShapeProfileDef,9> { IfcCraneRailFShapeProfileDef() : Object("IfcCraneRailFShapeProfileDef") {}
134.3487 +		IfcPositiveLengthMeasure::Out OverallHeight;
134.3488 +		IfcPositiveLengthMeasure::Out HeadWidth;
134.3489 +		Maybe< IfcPositiveLengthMeasure::Out > Radius;
134.3490 +		IfcPositiveLengthMeasure::Out HeadDepth2;
134.3491 +		IfcPositiveLengthMeasure::Out HeadDepth3;
134.3492 +		IfcPositiveLengthMeasure::Out WebThickness;
134.3493 +		IfcPositiveLengthMeasure::Out BaseDepth1;
134.3494 +		IfcPositiveLengthMeasure::Out BaseDepth2;
134.3495 +		Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY;
134.3496 +    };
134.3497 +
134.3498 +    // C++ wrapper for IfcFlowSegment
134.3499 +    struct IfcFlowSegment : IfcDistributionFlowElement, ObjectHelper<IfcFlowSegment,0> { IfcFlowSegment() : Object("IfcFlowSegment") {}
134.3500 +
134.3501 +    };
134.3502 +
134.3503 +    // C++ wrapper for IfcElementQuantity
134.3504 +    struct IfcElementQuantity : IfcPropertySetDefinition, ObjectHelper<IfcElementQuantity,2> { IfcElementQuantity() : Object("IfcElementQuantity") {}
134.3505 +		Maybe< IfcLabel::Out > MethodOfMeasurement;
134.3506 +		ListOf< Lazy< NotImplemented >, 1, 0 > Quantities;
134.3507 +    };
134.3508 +
134.3509 +    // C++ wrapper for IfcCurtainWall
134.3510 +    struct IfcCurtainWall : IfcBuildingElement, ObjectHelper<IfcCurtainWall,0> { IfcCurtainWall() : Object("IfcCurtainWall") {}
134.3511 +
134.3512 +    };
134.3513 +
134.3514 +    // C++ wrapper for IfcDiscreteAccessory
134.3515 +    struct IfcDiscreteAccessory : IfcElementComponent, ObjectHelper<IfcDiscreteAccessory,0> { IfcDiscreteAccessory() : Object("IfcDiscreteAccessory") {}
134.3516 +
134.3517 +    };
134.3518 +
134.3519 +    // C++ wrapper for IfcGrid
134.3520 +    struct IfcGrid : IfcProduct, ObjectHelper<IfcGrid,3> { IfcGrid() : Object("IfcGrid") {}
134.3521 +		ListOf< Lazy< NotImplemented >, 1, 0 > UAxes;
134.3522 +		ListOf< Lazy< NotImplemented >, 1, 0 > VAxes;
134.3523 +		Maybe< ListOf< Lazy< NotImplemented >, 1, 0 > > WAxes;
134.3524 +    };
134.3525 +
134.3526 +    // C++ wrapper for IfcSanitaryTerminalType
134.3527 +    struct IfcSanitaryTerminalType : IfcFlowTerminalType, ObjectHelper<IfcSanitaryTerminalType,1> { IfcSanitaryTerminalType() : Object("IfcSanitaryTerminalType") {}
134.3528 +		IfcSanitaryTerminalTypeEnum::Out PredefinedType;
134.3529 +    };
134.3530 +
134.3531 +    // C++ wrapper for IfcSubedge
134.3532 +    struct IfcSubedge : IfcEdge, ObjectHelper<IfcSubedge,1> { IfcSubedge() : Object("IfcSubedge") {}
134.3533 +		Lazy< IfcEdge > ParentEdge;
134.3534 +    };
134.3535 +
134.3536 +    // C++ wrapper for IfcFilterType
134.3537 +    struct IfcFilterType : IfcFlowTreatmentDeviceType, ObjectHelper<IfcFilterType,1> { IfcFilterType() : Object("IfcFilterType") {}
134.3538 +		IfcFilterTypeEnum::Out PredefinedType;
134.3539 +    };
134.3540 +
134.3541 +    // C++ wrapper for IfcTendon
134.3542 +    struct IfcTendon : IfcReinforcingElement, ObjectHelper<IfcTendon,8> { IfcTendon() : Object("IfcTendon") {}
134.3543 +		IfcTendonTypeEnum::Out PredefinedType;
134.3544 +		IfcPositiveLengthMeasure::Out NominalDiameter;
134.3545 +		IfcAreaMeasure::Out CrossSectionArea;
134.3546 +		Maybe< IfcForceMeasure::Out > TensionForce;
134.3547 +		Maybe< IfcPressureMeasure::Out > PreStress;
134.3548 +		Maybe< IfcNormalisedRatioMeasure::Out > FrictionCoefficient;
134.3549 +		Maybe< IfcPositiveLengthMeasure::Out > AnchorageSlip;
134.3550 +		Maybe< IfcPositiveLengthMeasure::Out > MinCurvatureRadius;
134.3551 +    };
134.3552 +
134.3553 +    // C++ wrapper for IfcStructuralLoadGroup
134.3554 +    struct IfcStructuralLoadGroup : IfcGroup, ObjectHelper<IfcStructuralLoadGroup,5> { IfcStructuralLoadGroup() : Object("IfcStructuralLoadGroup") {}
134.3555 +		IfcLoadGroupTypeEnum::Out PredefinedType;
134.3556 +		IfcActionTypeEnum::Out ActionType;
134.3557 +		IfcActionSourceTypeEnum::Out ActionSource;
134.3558 +		Maybe< IfcPositiveRatioMeasure::Out > Coefficient;
134.3559 +		Maybe< IfcLabel::Out > Purpose;
134.3560 +    };
134.3561 +
134.3562 +    // C++ wrapper for IfcPresentationStyleAssignment
134.3563 +    struct IfcPresentationStyleAssignment :  ObjectHelper<IfcPresentationStyleAssignment,1> { IfcPresentationStyleAssignment() : Object("IfcPresentationStyleAssignment") {}
134.3564 +		ListOf< IfcPresentationStyleSelect, 1, 0 >::Out Styles;
134.3565 +    };
134.3566 +
134.3567 +    // C++ wrapper for IfcStructuralCurveMember
134.3568 +    struct IfcStructuralCurveMember : IfcStructuralMember, ObjectHelper<IfcStructuralCurveMember,1> { IfcStructuralCurveMember() : Object("IfcStructuralCurveMember") {}
134.3569 +		IfcStructuralCurveTypeEnum::Out PredefinedType;
134.3570 +    };
134.3571 +
134.3572 +    // C++ wrapper for IfcLightSourceAmbient
134.3573 +    struct IfcLightSourceAmbient : IfcLightSource, ObjectHelper<IfcLightSourceAmbient,0> { IfcLightSourceAmbient() : Object("IfcLightSourceAmbient") {}
134.3574 +
134.3575 +    };
134.3576 +
134.3577 +    // C++ wrapper for IfcCondition
134.3578 +    struct IfcCondition : IfcGroup, ObjectHelper<IfcCondition,0> { IfcCondition() : Object("IfcCondition") {}
134.3579 +
134.3580 +    };
134.3581 +
134.3582 +    // C++ wrapper for IfcPort
134.3583 +    struct IfcPort : IfcProduct, ObjectHelper<IfcPort,0> { IfcPort() : Object("IfcPort") {}
134.3584 +
134.3585 +    };
134.3586 +
134.3587 +    // C++ wrapper for IfcSpace
134.3588 +    struct IfcSpace : IfcSpatialStructureElement, ObjectHelper<IfcSpace,2> { IfcSpace() : Object("IfcSpace") {}
134.3589 +		IfcInternalOrExternalEnum::Out InteriorOrExteriorSpace;
134.3590 +		Maybe< IfcLengthMeasure::Out > ElevationWithFlooring;
134.3591 +    };
134.3592 +
134.3593 +    // C++ wrapper for IfcHeatExchangerType
134.3594 +    struct IfcHeatExchangerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcHeatExchangerType,1> { IfcHeatExchangerType() : Object("IfcHeatExchangerType") {}
134.3595 +		IfcHeatExchangerTypeEnum::Out PredefinedType;
134.3596 +    };
134.3597 +
134.3598 +    // C++ wrapper for IfcTankType
134.3599 +    struct IfcTankType : IfcFlowStorageDeviceType, ObjectHelper<IfcTankType,1> { IfcTankType() : Object("IfcTankType") {}
134.3600 +		IfcTankTypeEnum::Out PredefinedType;
134.3601 +    };
134.3602 +
134.3603 +    // C++ wrapper for IfcInventory
134.3604 +    struct IfcInventory : IfcGroup, ObjectHelper<IfcInventory,6> { IfcInventory() : Object("IfcInventory") {}
134.3605 +		IfcInventoryTypeEnum::Out InventoryType;
134.3606 +		IfcActorSelect::Out Jurisdiction;
134.3607 +		ListOf< Lazy< NotImplemented >, 1, 0 > ResponsiblePersons;
134.3608 +		Lazy< NotImplemented > LastUpdateDate;
134.3609 +		Maybe< Lazy< NotImplemented > > CurrentValue;
134.3610 +		Maybe< Lazy< NotImplemented > > OriginalValue;
134.3611 +    };
134.3612 +
134.3613 +    // C++ wrapper for IfcTransportElementType
134.3614 +    struct IfcTransportElementType : IfcElementType, ObjectHelper<IfcTransportElementType,1> { IfcTransportElementType() : Object("IfcTransportElementType") {}
134.3615 +		IfcTransportElementTypeEnum::Out PredefinedType;
134.3616 +    };
134.3617 +
134.3618 +    // C++ wrapper for IfcAirToAirHeatRecoveryType
134.3619 +    struct IfcAirToAirHeatRecoveryType : IfcEnergyConversionDeviceType, ObjectHelper<IfcAirToAirHeatRecoveryType,1> { IfcAirToAirHeatRecoveryType() : Object("IfcAirToAirHeatRecoveryType") {}
134.3620 +		IfcAirToAirHeatRecoveryTypeEnum::Out PredefinedType;
134.3621 +    };
134.3622 +
134.3623 +    // C++ wrapper for IfcStairFlight
134.3624 +    struct IfcStairFlight : IfcBuildingElement, ObjectHelper<IfcStairFlight,4> { IfcStairFlight() : Object("IfcStairFlight") {}
134.3625 +		Maybe< INTEGER::Out > NumberOfRiser;
134.3626 +		Maybe< INTEGER::Out > NumberOfTreads;
134.3627 +		Maybe< IfcPositiveLengthMeasure::Out > RiserHeight;
134.3628 +		Maybe< IfcPositiveLengthMeasure::Out > TreadLength;
134.3629 +    };
134.3630 +
134.3631 +    // C++ wrapper for IfcElectricalElement
134.3632 +    struct IfcElectricalElement : IfcElement, ObjectHelper<IfcElectricalElement,0> { IfcElectricalElement() : Object("IfcElectricalElement") {}
134.3633 +
134.3634 +    };
134.3635 +
134.3636 +    // C++ wrapper for IfcSurfaceStyleWithTextures
134.3637 +    struct IfcSurfaceStyleWithTextures :  ObjectHelper<IfcSurfaceStyleWithTextures,1> { IfcSurfaceStyleWithTextures() : Object("IfcSurfaceStyleWithTextures") {}
134.3638 +		ListOf< Lazy< NotImplemented >, 1, 0 > Textures;
134.3639 +    };
134.3640 +
134.3641 +    // C++ wrapper for IfcBoundingBox
134.3642 +    struct IfcBoundingBox : IfcGeometricRepresentationItem, ObjectHelper<IfcBoundingBox,4> { IfcBoundingBox() : Object("IfcBoundingBox") {}
134.3643 +		Lazy< IfcCartesianPoint > Corner;
134.3644 +		IfcPositiveLengthMeasure::Out XDim;
134.3645 +		IfcPositiveLengthMeasure::Out YDim;
134.3646 +		IfcPositiveLengthMeasure::Out ZDim;
134.3647 +    };
134.3648 +
134.3649 +    // C++ wrapper for IfcWallType
134.3650 +    struct IfcWallType : IfcBuildingElementType, ObjectHelper<IfcWallType,1> { IfcWallType() : Object("IfcWallType") {}
134.3651 +		IfcWallTypeEnum::Out PredefinedType;
134.3652 +    };
134.3653 +
134.3654 +    // C++ wrapper for IfcMove
134.3655 +    struct IfcMove : IfcTask, ObjectHelper<IfcMove,3> { IfcMove() : Object("IfcMove") {}
134.3656 +		Lazy< IfcSpatialStructureElement > MoveFrom;
134.3657 +		Lazy< IfcSpatialStructureElement > MoveTo;
134.3658 +		Maybe< ListOf< IfcText, 1, 0 >::Out > PunchList;
134.3659 +    };
134.3660 +
134.3661 +    // C++ wrapper for IfcCircle
134.3662 +    struct IfcCircle : IfcConic, ObjectHelper<IfcCircle,1> { IfcCircle() : Object("IfcCircle") {}
134.3663 +		IfcPositiveLengthMeasure::Out Radius;
134.3664 +    };
134.3665 +
134.3666 +    // C++ wrapper for IfcOffsetCurve2D
134.3667 +    struct IfcOffsetCurve2D : IfcCurve, ObjectHelper<IfcOffsetCurve2D,3> { IfcOffsetCurve2D() : Object("IfcOffsetCurve2D") {}
134.3668 +		Lazy< IfcCurve > BasisCurve;
134.3669 +		IfcLengthMeasure::Out Distance;
134.3670 +		LOGICAL::Out SelfIntersect;
134.3671 +    };
134.3672 +
134.3673 +    // C++ wrapper for IfcPointOnCurve
134.3674 +    struct IfcPointOnCurve : IfcPoint, ObjectHelper<IfcPointOnCurve,2> { IfcPointOnCurve() : Object("IfcPointOnCurve") {}
134.3675 +		Lazy< IfcCurve > BasisCurve;
134.3676 +		IfcParameterValue::Out PointParameter;
134.3677 +    };
134.3678 +
134.3679 +    // C++ wrapper for IfcStructuralResultGroup
134.3680 +    struct IfcStructuralResultGroup : IfcGroup, ObjectHelper<IfcStructuralResultGroup,3> { IfcStructuralResultGroup() : Object("IfcStructuralResultGroup") {}
134.3681 +		IfcAnalysisTheoryTypeEnum::Out TheoryType;
134.3682 +		Maybe< Lazy< IfcStructuralLoadGroup > > ResultForLoadGroup;
134.3683 +		BOOLEAN::Out IsLinear;
134.3684 +    };
134.3685 +
134.3686 +    // C++ wrapper for IfcSectionedSpine
134.3687 +    struct IfcSectionedSpine : IfcGeometricRepresentationItem, ObjectHelper<IfcSectionedSpine,3> { IfcSectionedSpine() : Object("IfcSectionedSpine") {}
134.3688 +		Lazy< IfcCompositeCurve > SpineCurve;
134.3689 +		ListOf< Lazy< IfcProfileDef >, 2, 0 > CrossSections;
134.3690 +		ListOf< Lazy< IfcAxis2Placement3D >, 2, 0 > CrossSectionPositions;
134.3691 +    };
134.3692 +
134.3693 +    // C++ wrapper for IfcSlab
134.3694 +    struct IfcSlab : IfcBuildingElement, ObjectHelper<IfcSlab,1> { IfcSlab() : Object("IfcSlab") {}
134.3695 +		Maybe< IfcSlabTypeEnum::Out > PredefinedType;
134.3696 +    };
134.3697 +
134.3698 +    // C++ wrapper for IfcVertex
134.3699 +    struct IfcVertex : IfcTopologicalRepresentationItem, ObjectHelper<IfcVertex,0> { IfcVertex() : Object("IfcVertex") {}
134.3700 +
134.3701 +    };
134.3702 +
134.3703 +    // C++ wrapper for IfcVertexPoint
134.3704 +    struct IfcVertexPoint : IfcVertex, ObjectHelper<IfcVertexPoint,1> { IfcVertexPoint() : Object("IfcVertexPoint") {}
134.3705 +		Lazy< IfcPoint > VertexGeometry;
134.3706 +    };
134.3707 +
134.3708 +    // C++ wrapper for IfcStructuralLinearAction
134.3709 +    struct IfcStructuralLinearAction : IfcStructuralAction, ObjectHelper<IfcStructuralLinearAction,1> { IfcStructuralLinearAction() : Object("IfcStructuralLinearAction") {}
134.3710 +		IfcProjectedOrTrueLengthEnum::Out ProjectedOrTrue;
134.3711 +    };
134.3712 +
134.3713 +    // C++ wrapper for IfcStructuralLinearActionVarying
134.3714 +    struct IfcStructuralLinearActionVarying : IfcStructuralLinearAction, ObjectHelper<IfcStructuralLinearActionVarying,2> { IfcStructuralLinearActionVarying() : Object("IfcStructuralLinearActionVarying") {}
134.3715 +		Lazy< NotImplemented > VaryingAppliedLoadLocation;
134.3716 +		ListOf< Lazy< NotImplemented >, 1, 0 > SubsequentAppliedLoads;
134.3717 +    };
134.3718 +
134.3719 +    // C++ wrapper for IfcBuildingElementProxyType
134.3720 +    struct IfcBuildingElementProxyType : IfcBuildingElementType, ObjectHelper<IfcBuildingElementProxyType,1> { IfcBuildingElementProxyType() : Object("IfcBuildingElementProxyType") {}
134.3721 +		IfcBuildingElementProxyTypeEnum::Out PredefinedType;
134.3722 +    };
134.3723 +
134.3724 +    // C++ wrapper for IfcProjectionElement
134.3725 +    struct IfcProjectionElement : IfcFeatureElementAddition, ObjectHelper<IfcProjectionElement,0> { IfcProjectionElement() : Object("IfcProjectionElement") {}
134.3726 +
134.3727 +    };
134.3728 +
134.3729 +    // C++ wrapper for IfcConversionBasedUnit
134.3730 +    struct IfcConversionBasedUnit : IfcNamedUnit, ObjectHelper<IfcConversionBasedUnit,2> { IfcConversionBasedUnit() : Object("IfcConversionBasedUnit") {}
134.3731 +		IfcLabel::Out Name;
134.3732 +		Lazy< IfcMeasureWithUnit > ConversionFactor;
134.3733 +    };
134.3734 +
134.3735 +    // C++ wrapper for IfcGeometricRepresentationSubContext
134.3736 +    struct IfcGeometricRepresentationSubContext : IfcGeometricRepresentationContext, ObjectHelper<IfcGeometricRepresentationSubContext,4> { IfcGeometricRepresentationSubContext() : Object("IfcGeometricRepresentationSubContext") {}
134.3737 +		Lazy< IfcGeometricRepresentationContext > ParentContext;
134.3738 +		Maybe< IfcPositiveRatioMeasure::Out > TargetScale;
134.3739 +		IfcGeometricProjectionEnum::Out TargetView;
134.3740 +		Maybe< IfcLabel::Out > UserDefinedTargetView;
134.3741 +    };
134.3742 +
134.3743 +    // C++ wrapper for IfcAnnotationSurfaceOccurrence
134.3744 +    struct IfcAnnotationSurfaceOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationSurfaceOccurrence,0> { IfcAnnotationSurfaceOccurrence() : Object("IfcAnnotationSurfaceOccurrence") {}
134.3745 +
134.3746 +    };
134.3747 +
134.3748 +    // C++ wrapper for IfcRoundedEdgeFeature
134.3749 +    struct IfcRoundedEdgeFeature : IfcEdgeFeature, ObjectHelper<IfcRoundedEdgeFeature,1> { IfcRoundedEdgeFeature() : Object("IfcRoundedEdgeFeature") {}
134.3750 +		Maybe< IfcPositiveLengthMeasure::Out > Radius;
134.3751 +    };
134.3752 +
134.3753 +    // C++ wrapper for IfcElectricDistributionPoint
134.3754 +    struct IfcElectricDistributionPoint : IfcFlowController, ObjectHelper<IfcElectricDistributionPoint,2> { IfcElectricDistributionPoint() : Object("IfcElectricDistributionPoint") {}
134.3755 +		IfcElectricDistributionPointFunctionEnum::Out DistributionPointFunction;
134.3756 +		Maybe< IfcLabel::Out > UserDefinedFunction;
134.3757 +    };
134.3758 +
134.3759 +    // C++ wrapper for IfcCableCarrierSegmentType
134.3760 +    struct IfcCableCarrierSegmentType : IfcFlowSegmentType, ObjectHelper<IfcCableCarrierSegmentType,1> { IfcCableCarrierSegmentType() : Object("IfcCableCarrierSegmentType") {}
134.3761 +		IfcCableCarrierSegmentTypeEnum::Out PredefinedType;
134.3762 +    };
134.3763 +
134.3764 +    // C++ wrapper for IfcWallStandardCase
134.3765 +    struct IfcWallStandardCase : IfcWall, ObjectHelper<IfcWallStandardCase,0> { IfcWallStandardCase() : Object("IfcWallStandardCase") {}
134.3766 +
134.3767 +    };
134.3768 +
134.3769 +    // C++ wrapper for IfcCsgSolid
134.3770 +    struct IfcCsgSolid : IfcSolidModel, ObjectHelper<IfcCsgSolid,1> { IfcCsgSolid() : Object("IfcCsgSolid") {}
134.3771 +		IfcCsgSelect::Out TreeRootExpression;
134.3772 +    };
134.3773 +
134.3774 +    // C++ wrapper for IfcBeamType
134.3775 +    struct IfcBeamType : IfcBuildingElementType, ObjectHelper<IfcBeamType,1> { IfcBeamType() : Object("IfcBeamType") {}
134.3776 +		IfcBeamTypeEnum::Out PredefinedType;
134.3777 +    };
134.3778 +
134.3779 +    // C++ wrapper for IfcAnnotationFillArea
134.3780 +    struct IfcAnnotationFillArea : IfcGeometricRepresentationItem, ObjectHelper<IfcAnnotationFillArea,2> { IfcAnnotationFillArea() : Object("IfcAnnotationFillArea") {}
134.3781 +		Lazy< IfcCurve > OuterBoundary;
134.3782 +		Maybe< ListOf< Lazy< IfcCurve >, 1, 0 > > InnerBoundaries;
134.3783 +    };
134.3784 +
134.3785 +    // C++ wrapper for IfcStructuralCurveMemberVarying
134.3786 +    struct IfcStructuralCurveMemberVarying : IfcStructuralCurveMember, ObjectHelper<IfcStructuralCurveMemberVarying,0> { IfcStructuralCurveMemberVarying() : Object("IfcStructuralCurveMemberVarying") {}
134.3787 +
134.3788 +    };
134.3789 +
134.3790 +    // C++ wrapper for IfcPointOnSurface
134.3791 +    struct IfcPointOnSurface : IfcPoint, ObjectHelper<IfcPointOnSurface,3> { IfcPointOnSurface() : Object("IfcPointOnSurface") {}
134.3792 +		Lazy< IfcSurface > BasisSurface;
134.3793 +		IfcParameterValue::Out PointParameterU;
134.3794 +		IfcParameterValue::Out PointParameterV;
134.3795 +    };
134.3796 +
134.3797 +    // C++ wrapper for IfcOrderAction
134.3798 +    struct IfcOrderAction : IfcTask, ObjectHelper<IfcOrderAction,1> { IfcOrderAction() : Object("IfcOrderAction") {}
134.3799 +		IfcIdentifier::Out ActionID;
134.3800 +    };
134.3801 +
134.3802 +    // C++ wrapper for IfcEdgeLoop
134.3803 +    struct IfcEdgeLoop : IfcLoop, ObjectHelper<IfcEdgeLoop,1> { IfcEdgeLoop() : Object("IfcEdgeLoop") {}
134.3804 +		ListOf< Lazy< IfcOrientedEdge >, 1, 0 > EdgeList;
134.3805 +    };
134.3806 +
134.3807 +    // C++ wrapper for IfcAnnotationFillAreaOccurrence
134.3808 +    struct IfcAnnotationFillAreaOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationFillAreaOccurrence,2> { IfcAnnotationFillAreaOccurrence() : Object("IfcAnnotationFillAreaOccurrence") {}
134.3809 +		Maybe< Lazy< IfcPoint > > FillStyleTarget;
134.3810 +		Maybe< IfcGlobalOrLocalEnum::Out > GlobalOrLocal;
134.3811 +    };
134.3812 +
134.3813 +    // C++ wrapper for IfcWorkPlan
134.3814 +    struct IfcWorkPlan : IfcWorkControl, ObjectHelper<IfcWorkPlan,0> { IfcWorkPlan() : Object("IfcWorkPlan") {}
134.3815 +
134.3816 +    };
134.3817 +
134.3818 +    // C++ wrapper for IfcEllipse
134.3819 +    struct IfcEllipse : IfcConic, ObjectHelper<IfcEllipse,2> { IfcEllipse() : Object("IfcEllipse") {}
134.3820 +		IfcPositiveLengthMeasure::Out SemiAxis1;
134.3821 +		IfcPositiveLengthMeasure::Out SemiAxis2;
134.3822 +    };
134.3823 +
134.3824 +    // C++ wrapper for IfcProductDefinitionShape
134.3825 +    struct IfcProductDefinitionShape : IfcProductRepresentation, ObjectHelper<IfcProductDefinitionShape,0> { IfcProductDefinitionShape() : Object("IfcProductDefinitionShape") {}
134.3826 +
134.3827 +    };
134.3828 +
134.3829 +    // C++ wrapper for IfcProjectionCurve
134.3830 +    struct IfcProjectionCurve : IfcAnnotationCurveOccurrence, ObjectHelper<IfcProjectionCurve,0> { IfcProjectionCurve() : Object("IfcProjectionCurve") {}
134.3831 +
134.3832 +    };
134.3833 +
134.3834 +    // C++ wrapper for IfcElectricalCircuit
134.3835 +    struct IfcElectricalCircuit : IfcSystem, ObjectHelper<IfcElectricalCircuit,0> { IfcElectricalCircuit() : Object("IfcElectricalCircuit") {}
134.3836 +
134.3837 +    };
134.3838 +
134.3839 +    // C++ wrapper for IfcRationalBezierCurve
134.3840 +    struct IfcRationalBezierCurve : IfcBezierCurve, ObjectHelper<IfcRationalBezierCurve,1> { IfcRationalBezierCurve() : Object("IfcRationalBezierCurve") {}
134.3841 +		ListOf< REAL, 2, 0 >::Out WeightsData;
134.3842 +    };
134.3843 +
134.3844 +    // C++ wrapper for IfcStructuralPointAction
134.3845 +    struct IfcStructuralPointAction : IfcStructuralAction, ObjectHelper<IfcStructuralPointAction,0> { IfcStructuralPointAction() : Object("IfcStructuralPointAction") {}
134.3846 +
134.3847 +    };
134.3848 +
134.3849 +    // C++ wrapper for IfcPipeSegmentType
134.3850 +    struct IfcPipeSegmentType : IfcFlowSegmentType, ObjectHelper<IfcPipeSegmentType,1> { IfcPipeSegmentType() : Object("IfcPipeSegmentType") {}
134.3851 +		IfcPipeSegmentTypeEnum::Out PredefinedType;
134.3852 +    };
134.3853 +
134.3854 +    // C++ wrapper for IfcTwoDirectionRepeatFactor
134.3855 +    struct IfcTwoDirectionRepeatFactor : IfcOneDirectionRepeatFactor, ObjectHelper<IfcTwoDirectionRepeatFactor,1> { IfcTwoDirectionRepeatFactor() : Object("IfcTwoDirectionRepeatFactor") {}
134.3856 +		Lazy< IfcVector > SecondRepeatFactor;
134.3857 +    };
134.3858 +
134.3859 +    // C++ wrapper for IfcShapeRepresentation
134.3860 +    struct IfcShapeRepresentation : IfcShapeModel, ObjectHelper<IfcShapeRepresentation,0> { IfcShapeRepresentation() : Object("IfcShapeRepresentation") {}
134.3861 +
134.3862 +    };
134.3863 +
134.3864 +    // C++ wrapper for IfcPropertySet
134.3865 +    struct IfcPropertySet : IfcPropertySetDefinition, ObjectHelper<IfcPropertySet,1> { IfcPropertySet() : Object("IfcPropertySet") {}
134.3866 +		ListOf< Lazy< IfcProperty >, 1, 0 > HasProperties;
134.3867 +    };
134.3868 +
134.3869 +    // C++ wrapper for IfcSurfaceStyleRendering
134.3870 +    struct IfcSurfaceStyleRendering : IfcSurfaceStyleShading, ObjectHelper<IfcSurfaceStyleRendering,8> { IfcSurfaceStyleRendering() : Object("IfcSurfaceStyleRendering") {}
134.3871 +		Maybe< IfcNormalisedRatioMeasure::Out > Transparency;
134.3872 +		Maybe< IfcColourOrFactor::Out > DiffuseColour;
134.3873 +		Maybe< IfcColourOrFactor::Out > TransmissionColour;
134.3874 +		Maybe< IfcColourOrFactor::Out > DiffuseTransmissionColour;
134.3875 +		Maybe< IfcColourOrFactor::Out > ReflectionColour;
134.3876 +		Maybe< IfcColourOrFactor::Out > SpecularColour;
134.3877 +		Maybe< IfcSpecularHighlightSelect::Out > SpecularHighlight;
134.3878 +		IfcReflectanceMethodEnum::Out ReflectanceMethod;
134.3879 +    };
134.3880 +
134.3881 +    // C++ wrapper for IfcDistributionPort
134.3882 +    struct IfcDistributionPort : IfcPort, ObjectHelper<IfcDistributionPort,1> { IfcDistributionPort() : Object("IfcDistributionPort") {}
134.3883 +		Maybe< IfcFlowDirectionEnum::Out > FlowDirection;
134.3884 +    };
134.3885 +
134.3886 +    // C++ wrapper for IfcPipeFittingType
134.3887 +    struct IfcPipeFittingType : IfcFlowFittingType, ObjectHelper<IfcPipeFittingType,1> { IfcPipeFittingType() : Object("IfcPipeFittingType") {}
134.3888 +		IfcPipeFittingTypeEnum::Out PredefinedType;
134.3889 +    };
134.3890 +
134.3891 +    // C++ wrapper for IfcTransportElement
134.3892 +    struct IfcTransportElement : IfcElement, ObjectHelper<IfcTransportElement,3> { IfcTransportElement() : Object("IfcTransportElement") {}
134.3893 +		Maybe< IfcTransportElementTypeEnum::Out > OperationType;
134.3894 +		Maybe< IfcMassMeasure::Out > CapacityByWeight;
134.3895 +		Maybe< IfcCountMeasure::Out > CapacityByNumber;
134.3896 +    };
134.3897 +
134.3898 +    // C++ wrapper for IfcAnnotationTextOccurrence
134.3899 +    struct IfcAnnotationTextOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationTextOccurrence,0> { IfcAnnotationTextOccurrence() : Object("IfcAnnotationTextOccurrence") {}
134.3900 +
134.3901 +    };
134.3902 +
134.3903 +    // C++ wrapper for IfcStructuralAnalysisModel
134.3904 +    struct IfcStructuralAnalysisModel : IfcSystem, ObjectHelper<IfcStructuralAnalysisModel,4> { IfcStructuralAnalysisModel() : Object("IfcStructuralAnalysisModel") {}
134.3905 +		IfcAnalysisModelTypeEnum::Out PredefinedType;
134.3906 +		Maybe< Lazy< IfcAxis2Placement3D > > OrientationOf2DPlane;
134.3907 +		Maybe< ListOf< Lazy< IfcStructuralLoadGroup >, 1, 0 > > LoadedBy;
134.3908 +		Maybe< ListOf< Lazy< IfcStructuralResultGroup >, 1, 0 > > HasResults;
134.3909 +    };
134.3910 +
134.3911 +    // C++ wrapper for IfcConditionCriterion
134.3912 +    struct IfcConditionCriterion : IfcControl, ObjectHelper<IfcConditionCriterion,2> { IfcConditionCriterion() : Object("IfcConditionCriterion") {}
134.3913 +		IfcConditionCriterionSelect::Out Criterion;
134.3914 +		IfcDateTimeSelect::Out CriterionDateTime;
134.3915 +    };
134.3916 +
134.3917 +	void GetSchema(EXPRESS::ConversionSchema& out);
134.3918 +
134.3919 +} //! IFC
134.3920 +namespace STEP {
134.3921 +
134.3922 +	// ******************************************************************************
134.3923 +	// Converter stubs
134.3924 +	// ******************************************************************************
134.3925 +	
134.3926 +#define DECL_CONV_STUB(type) template <> size_t GenericFill<IFC::type>(const STEP::DB& db, const EXPRESS::LIST& params, IFC::type* in)
134.3927 +	
134.3928 +	DECL_CONV_STUB(IfcRoot);
134.3929 +	DECL_CONV_STUB(IfcObjectDefinition);
134.3930 +	DECL_CONV_STUB(IfcTypeObject);
134.3931 +	DECL_CONV_STUB(IfcTypeProduct);
134.3932 +	DECL_CONV_STUB(IfcElementType);
134.3933 +	DECL_CONV_STUB(IfcDistributionElementType);
134.3934 +	DECL_CONV_STUB(IfcDistributionFlowElementType);
134.3935 +	DECL_CONV_STUB(IfcFlowControllerType);
134.3936 +	DECL_CONV_STUB(IfcElectricTimeControlType);
134.3937 +	DECL_CONV_STUB(IfcRepresentation);
134.3938 +	DECL_CONV_STUB(IfcShapeModel);
134.3939 +	DECL_CONV_STUB(IfcTopologyRepresentation);
134.3940 +	DECL_CONV_STUB(IfcRelationship);
134.3941 +	DECL_CONV_STUB(IfcRelConnects);
134.3942 +	DECL_CONV_STUB(IfcFlowFittingType);
134.3943 +	DECL_CONV_STUB(IfcCableCarrierFittingType);
134.3944 +	DECL_CONV_STUB(IfcEnergyConversionDeviceType);
134.3945 +	DECL_CONV_STUB(IfcCoilType);
134.3946 +	DECL_CONV_STUB(IfcObject);
134.3947 +	DECL_CONV_STUB(IfcControl);
134.3948 +	DECL_CONV_STUB(IfcPerformanceHistory);
134.3949 +	DECL_CONV_STUB(IfcRepresentationItem);
134.3950 +	DECL_CONV_STUB(IfcGeometricRepresentationItem);
134.3951 +	DECL_CONV_STUB(IfcTextLiteral);
134.3952 +	DECL_CONV_STUB(IfcTextLiteralWithExtent);
134.3953 +	DECL_CONV_STUB(IfcProductRepresentation);
134.3954 +	DECL_CONV_STUB(IfcProduct);
134.3955 +	DECL_CONV_STUB(IfcElement);
134.3956 +	DECL_CONV_STUB(IfcDistributionElement);
134.3957 +	DECL_CONV_STUB(IfcDistributionFlowElement);
134.3958 +	DECL_CONV_STUB(IfcCurve);
134.3959 +	DECL_CONV_STUB(IfcBoundedCurve);
134.3960 +	DECL_CONV_STUB(IfcCompositeCurve);
134.3961 +	DECL_CONV_STUB(Ifc2DCompositeCurve);
134.3962 +	DECL_CONV_STUB(IfcCartesianTransformationOperator);
134.3963 +	DECL_CONV_STUB(IfcCartesianTransformationOperator3D);
134.3964 +	DECL_CONV_STUB(IfcProperty);
134.3965 +	DECL_CONV_STUB(IfcSimpleProperty);
134.3966 +	DECL_CONV_STUB(IfcPropertyEnumeratedValue);
134.3967 +	DECL_CONV_STUB(IfcBuildingElementType);
134.3968 +	DECL_CONV_STUB(IfcStairFlightType);
134.3969 +	DECL_CONV_STUB(IfcSurface);
134.3970 +	DECL_CONV_STUB(IfcElementarySurface);
134.3971 +	DECL_CONV_STUB(IfcPlane);
134.3972 +	DECL_CONV_STUB(IfcBooleanResult);
134.3973 +	DECL_CONV_STUB(IfcBooleanClippingResult);
134.3974 +	DECL_CONV_STUB(IfcSolidModel);
134.3975 +	DECL_CONV_STUB(IfcManifoldSolidBrep);
134.3976 +	DECL_CONV_STUB(IfcFlowTerminalType);
134.3977 +	DECL_CONV_STUB(IfcStackTerminalType);
134.3978 +	DECL_CONV_STUB(IfcStructuralItem);
134.3979 +	DECL_CONV_STUB(IfcStructuralConnection);
134.3980 +	DECL_CONV_STUB(IfcStructuralCurveConnection);
134.3981 +	DECL_CONV_STUB(IfcJunctionBoxType);
134.3982 +	DECL_CONV_STUB(IfcPropertyDefinition);
134.3983 +	DECL_CONV_STUB(IfcPropertySetDefinition);
134.3984 +	DECL_CONV_STUB(IfcProcess);
134.3985 +	DECL_CONV_STUB(IfcTask);
134.3986 +	DECL_CONV_STUB(IfcRelFillsElement);
134.3987 +	DECL_CONV_STUB(IfcProcedure);
134.3988 +	DECL_CONV_STUB(IfcProxy);
134.3989 +	DECL_CONV_STUB(IfcResource);
134.3990 +	DECL_CONV_STUB(IfcConstructionResource);
134.3991 +	DECL_CONV_STUB(IfcSubContractResource);
134.3992 +	DECL_CONV_STUB(IfcRelContainedInSpatialStructure);
134.3993 +	DECL_CONV_STUB(IfcTopologicalRepresentationItem);
134.3994 +	DECL_CONV_STUB(IfcEdge);
134.3995 +	DECL_CONV_STUB(IfcEdgeCurve);
134.3996 +	DECL_CONV_STUB(IfcPlateType);
134.3997 +	DECL_CONV_STUB(IfcObjectPlacement);
134.3998 +	DECL_CONV_STUB(IfcGridPlacement);
134.3999 +	DECL_CONV_STUB(IfcFireSuppressionTerminalType);
134.4000 +	DECL_CONV_STUB(IfcFlowStorageDevice);
134.4001 +	DECL_CONV_STUB(IfcSweptSurface);
134.4002 +	DECL_CONV_STUB(IfcSurfaceOfRevolution);
134.4003 +	DECL_CONV_STUB(IfcOrientedEdge);
134.4004 +	DECL_CONV_STUB(IfcDirection);
134.4005 +	DECL_CONV_STUB(IfcProfileDef);
134.4006 +	DECL_CONV_STUB(IfcParameterizedProfileDef);
134.4007 +	DECL_CONV_STUB(IfcCShapeProfileDef);
134.4008 +	DECL_CONV_STUB(IfcFeatureElement);
134.4009 +	DECL_CONV_STUB(IfcFeatureElementSubtraction);
134.4010 +	DECL_CONV_STUB(IfcEdgeFeature);
134.4011 +	DECL_CONV_STUB(IfcChamferEdgeFeature);
134.4012 +	DECL_CONV_STUB(IfcBuildingElement);
134.4013 +	DECL_CONV_STUB(IfcColumn);
134.4014 +	DECL_CONV_STUB(IfcPropertyReferenceValue);
134.4015 +	DECL_CONV_STUB(IfcElectricMotorType);
134.4016 +	DECL_CONV_STUB(IfcSpatialStructureElementType);
134.4017 +	DECL_CONV_STUB(IfcSpaceType);
134.4018 +	DECL_CONV_STUB(IfcColumnType);
134.4019 +	DECL_CONV_STUB(IfcCraneRailAShapeProfileDef);
134.4020 +	DECL_CONV_STUB(IfcCondenserType);
134.4021 +	DECL_CONV_STUB(IfcCircleProfileDef);
134.4022 +	DECL_CONV_STUB(IfcCircleHollowProfileDef);
134.4023 +	DECL_CONV_STUB(IfcPlacement);
134.4024 +	DECL_CONV_STUB(IfcAxis2Placement3D);
134.4025 +	DECL_CONV_STUB(IfcPresentationStyle);
134.4026 +	DECL_CONV_STUB(IfcEquipmentElement);
134.4027 +	DECL_CONV_STUB(IfcCompositeCurveSegment);
134.4028 +	DECL_CONV_STUB(IfcRectangleProfileDef);
134.4029 +	DECL_CONV_STUB(IfcBuildingElementProxy);
134.4030 +	DECL_CONV_STUB(IfcDistributionControlElementType);
134.4031 +	DECL_CONV_STUB(IfcFlowInstrumentType);
134.4032 +	DECL_CONV_STUB(IfcDraughtingCallout);
134.4033 +	DECL_CONV_STUB(IfcDimensionCurveDirectedCallout);
134.4034 +	DECL_CONV_STUB(IfcLinearDimension);
134.4035 +	DECL_CONV_STUB(IfcElementAssembly);
134.4036 +	DECL_CONV_STUB(IfcCsgPrimitive3D);
134.4037 +	DECL_CONV_STUB(IfcRightCircularCone);
134.4038 +	DECL_CONV_STUB(IfcProjectOrder);
134.4039 +	DECL_CONV_STUB(IfcLShapeProfileDef);
134.4040 +	DECL_CONV_STUB(IfcAngularDimension);
134.4041 +	DECL_CONV_STUB(IfcLocalPlacement);
134.4042 +	DECL_CONV_STUB(IfcSweptAreaSolid);
134.4043 +	DECL_CONV_STUB(IfcRevolvedAreaSolid);
134.4044 +	DECL_CONV_STUB(IfcStructuralSurfaceConnection);
134.4045 +	DECL_CONV_STUB(IfcRadiusDimension);
134.4046 +	DECL_CONV_STUB(IfcSweptDiskSolid);
134.4047 +	DECL_CONV_STUB(IfcHalfSpaceSolid);
134.4048 +	DECL_CONV_STUB(IfcPolygonalBoundedHalfSpace);
134.4049 +	DECL_CONV_STUB(IfcTimeSeriesSchedule);
134.4050 +	DECL_CONV_STUB(IfcCooledBeamType);
134.4051 +	DECL_CONV_STUB(IfcProject);
134.4052 +	DECL_CONV_STUB(IfcEvaporatorType);
134.4053 +	DECL_CONV_STUB(IfcLaborResource);
134.4054 +	DECL_CONV_STUB(IfcPropertyBoundedValue);
134.4055 +	DECL_CONV_STUB(IfcRampFlightType);
134.4056 +	DECL_CONV_STUB(IfcMember);
134.4057 +	DECL_CONV_STUB(IfcTubeBundleType);
134.4058 +	DECL_CONV_STUB(IfcValveType);
134.4059 +	DECL_CONV_STUB(IfcTrimmedCurve);
134.4060 +	DECL_CONV_STUB(IfcRelDefines);
134.4061 +	DECL_CONV_STUB(IfcRelDefinesByProperties);
134.4062 +	DECL_CONV_STUB(IfcActor);
134.4063 +	DECL_CONV_STUB(IfcOccupant);
134.4064 +	DECL_CONV_STUB(IfcHumidifierType);
134.4065 +	DECL_CONV_STUB(IfcArbitraryOpenProfileDef);
134.4066 +	DECL_CONV_STUB(IfcPermit);
134.4067 +	DECL_CONV_STUB(IfcOffsetCurve3D);
134.4068 +	DECL_CONV_STUB(IfcLightSource);
134.4069 +	DECL_CONV_STUB(IfcLightSourcePositional);
134.4070 +	DECL_CONV_STUB(IfcCompositeProfileDef);
134.4071 +	DECL_CONV_STUB(IfcRamp);
134.4072 +	DECL_CONV_STUB(IfcFlowMovingDevice);
134.4073 +	DECL_CONV_STUB(IfcSpaceHeaterType);
134.4074 +	DECL_CONV_STUB(IfcLampType);
134.4075 +	DECL_CONV_STUB(IfcBuildingElementComponent);
134.4076 +	DECL_CONV_STUB(IfcReinforcingElement);
134.4077 +	DECL_CONV_STUB(IfcReinforcingBar);
134.4078 +	DECL_CONV_STUB(IfcElectricHeaterType);
134.4079 +	DECL_CONV_STUB(IfcTShapeProfileDef);
134.4080 +	DECL_CONV_STUB(IfcStructuralActivity);
134.4081 +	DECL_CONV_STUB(IfcStructuralAction);
134.4082 +	DECL_CONV_STUB(IfcDuctFittingType);
134.4083 +	DECL_CONV_STUB(IfcCartesianTransformationOperator2D);
134.4084 +	DECL_CONV_STUB(IfcCartesianTransformationOperator2DnonUniform);
134.4085 +	DECL_CONV_STUB(IfcVirtualElement);
134.4086 +	DECL_CONV_STUB(IfcRightCircularCylinder);
134.4087 +	DECL_CONV_STUB(IfcOutletType);
134.4088 +	DECL_CONV_STUB(IfcRelDecomposes);
134.4089 +	DECL_CONV_STUB(IfcCovering);
134.4090 +	DECL_CONV_STUB(IfcPolyline);
134.4091 +	DECL_CONV_STUB(IfcPath);
134.4092 +	DECL_CONV_STUB(IfcElementComponent);
134.4093 +	DECL_CONV_STUB(IfcFastener);
134.4094 +	DECL_CONV_STUB(IfcMappedItem);
134.4095 +	DECL_CONV_STUB(IfcRectangularPyramid);
134.4096 +	DECL_CONV_STUB(IfcCrewResource);
134.4097 +	DECL_CONV_STUB(IfcNamedUnit);
134.4098 +	DECL_CONV_STUB(IfcContextDependentUnit);
134.4099 +	DECL_CONV_STUB(IfcUnitaryEquipmentType);
134.4100 +	DECL_CONV_STUB(IfcRoof);
134.4101 +	DECL_CONV_STUB(IfcStructuralMember);
134.4102 +	DECL_CONV_STUB(IfcStyleModel);
134.4103 +	DECL_CONV_STUB(IfcStyledRepresentation);
134.4104 +	DECL_CONV_STUB(IfcSpatialStructureElement);
134.4105 +	DECL_CONV_STUB(IfcBuilding);
134.4106 +	DECL_CONV_STUB(IfcConnectedFaceSet);
134.4107 +	DECL_CONV_STUB(IfcOpenShell);
134.4108 +	DECL_CONV_STUB(IfcFacetedBrep);
134.4109 +	DECL_CONV_STUB(IfcConic);
134.4110 +	DECL_CONV_STUB(IfcCoveringType);
134.4111 +	DECL_CONV_STUB(IfcRoundedRectangleProfileDef);
134.4112 +	DECL_CONV_STUB(IfcAirTerminalType);
134.4113 +	DECL_CONV_STUB(IfcFlowMovingDeviceType);
134.4114 +	DECL_CONV_STUB(IfcCompressorType);
134.4115 +	DECL_CONV_STUB(IfcIShapeProfileDef);
134.4116 +	DECL_CONV_STUB(IfcAsymmetricIShapeProfileDef);
134.4117 +	DECL_CONV_STUB(IfcControllerType);
134.4118 +	DECL_CONV_STUB(IfcRailing);
134.4119 +	DECL_CONV_STUB(IfcGroup);
134.4120 +	DECL_CONV_STUB(IfcAsset);
134.4121 +	DECL_CONV_STUB(IfcMaterialDefinitionRepresentation);
134.4122 +	DECL_CONV_STUB(IfcRailingType);
134.4123 +	DECL_CONV_STUB(IfcWall);
134.4124 +	DECL_CONV_STUB(IfcStructuralPointConnection);
134.4125 +	DECL_CONV_STUB(IfcPropertyListValue);
134.4126 +	DECL_CONV_STUB(IfcFurnitureStandard);
134.4127 +	DECL_CONV_STUB(IfcElectricGeneratorType);
134.4128 +	DECL_CONV_STUB(IfcDoor);
134.4129 +	DECL_CONV_STUB(IfcStyledItem);
134.4130 +	DECL_CONV_STUB(IfcAnnotationOccurrence);
134.4131 +	DECL_CONV_STUB(IfcAnnotationSymbolOccurrence);
134.4132 +	DECL_CONV_STUB(IfcArbitraryClosedProfileDef);
134.4133 +	DECL_CONV_STUB(IfcArbitraryProfileDefWithVoids);
134.4134 +	DECL_CONV_STUB(IfcLine);
134.4135 +	DECL_CONV_STUB(IfcFlowSegmentType);
134.4136 +	DECL_CONV_STUB(IfcAirTerminalBoxType);
134.4137 +	DECL_CONV_STUB(IfcPropertySingleValue);
134.4138 +	DECL_CONV_STUB(IfcAlarmType);
134.4139 +	DECL_CONV_STUB(IfcEllipseProfileDef);
134.4140 +	DECL_CONV_STUB(IfcStair);
134.4141 +	DECL_CONV_STUB(IfcSurfaceStyleShading);
134.4142 +	DECL_CONV_STUB(IfcPumpType);
134.4143 +	DECL_CONV_STUB(IfcDefinedSymbol);
134.4144 +	DECL_CONV_STUB(IfcElementComponentType);
134.4145 +	DECL_CONV_STUB(IfcFastenerType);
134.4146 +	DECL_CONV_STUB(IfcMechanicalFastenerType);
134.4147 +	DECL_CONV_STUB(IfcFlowFitting);
134.4148 +	DECL_CONV_STUB(IfcLightSourceDirectional);
134.4149 +	DECL_CONV_STUB(IfcSurfaceStyle);
134.4150 +	DECL_CONV_STUB(IfcAnnotationSurface);
134.4151 +	DECL_CONV_STUB(IfcFlowController);
134.4152 +	DECL_CONV_STUB(IfcBuildingStorey);
134.4153 +	DECL_CONV_STUB(IfcWorkControl);
134.4154 +	DECL_CONV_STUB(IfcWorkSchedule);
134.4155 +	DECL_CONV_STUB(IfcDuctSegmentType);
134.4156 +	DECL_CONV_STUB(IfcFace);
134.4157 +	DECL_CONV_STUB(IfcStructuralSurfaceMember);
134.4158 +	DECL_CONV_STUB(IfcStructuralSurfaceMemberVarying);
134.4159 +	DECL_CONV_STUB(IfcFaceSurface);
134.4160 +	DECL_CONV_STUB(IfcCostSchedule);
134.4161 +	DECL_CONV_STUB(IfcPlanarExtent);
134.4162 +	DECL_CONV_STUB(IfcPlanarBox);
134.4163 +	DECL_CONV_STUB(IfcColourSpecification);
134.4164 +	DECL_CONV_STUB(IfcVector);
134.4165 +	DECL_CONV_STUB(IfcBeam);
134.4166 +	DECL_CONV_STUB(IfcColourRgb);
134.4167 +	DECL_CONV_STUB(IfcStructuralPlanarAction);
134.4168 +	DECL_CONV_STUB(IfcStructuralPlanarActionVarying);
134.4169 +	DECL_CONV_STUB(IfcSite);
134.4170 +	DECL_CONV_STUB(IfcDiscreteAccessoryType);
134.4171 +	DECL_CONV_STUB(IfcVibrationIsolatorType);
134.4172 +	DECL_CONV_STUB(IfcEvaporativeCoolerType);
134.4173 +	DECL_CONV_STUB(IfcDistributionChamberElementType);
134.4174 +	DECL_CONV_STUB(IfcFeatureElementAddition);
134.4175 +	DECL_CONV_STUB(IfcStructuredDimensionCallout);
134.4176 +	DECL_CONV_STUB(IfcCoolingTowerType);
134.4177 +	DECL_CONV_STUB(IfcCenterLineProfileDef);
134.4178 +	DECL_CONV_STUB(IfcWindowStyle);
134.4179 +	DECL_CONV_STUB(IfcLightSourceGoniometric);
134.4180 +	DECL_CONV_STUB(IfcTransformerType);
134.4181 +	DECL_CONV_STUB(IfcMemberType);
134.4182 +	DECL_CONV_STUB(IfcSurfaceOfLinearExtrusion);
134.4183 +	DECL_CONV_STUB(IfcMotorConnectionType);
134.4184 +	DECL_CONV_STUB(IfcFlowTreatmentDeviceType);
134.4185 +	DECL_CONV_STUB(IfcDuctSilencerType);
134.4186 +	DECL_CONV_STUB(IfcFurnishingElementType);
134.4187 +	DECL_CONV_STUB(IfcSystemFurnitureElementType);
134.4188 +	DECL_CONV_STUB(IfcWasteTerminalType);
134.4189 +	DECL_CONV_STUB(IfcBSplineCurve);
134.4190 +	DECL_CONV_STUB(IfcBezierCurve);
134.4191 +	DECL_CONV_STUB(IfcActuatorType);
134.4192 +	DECL_CONV_STUB(IfcDistributionControlElement);
134.4193 +	DECL_CONV_STUB(IfcAnnotation);
134.4194 +	DECL_CONV_STUB(IfcShellBasedSurfaceModel);
134.4195 +	DECL_CONV_STUB(IfcActionRequest);
134.4196 +	DECL_CONV_STUB(IfcExtrudedAreaSolid);
134.4197 +	DECL_CONV_STUB(IfcSystem);
134.4198 +	DECL_CONV_STUB(IfcFillAreaStyleHatching);
134.4199 +	DECL_CONV_STUB(IfcRelVoidsElement);
134.4200 +	DECL_CONV_STUB(IfcSurfaceCurveSweptAreaSolid);
134.4201 +	DECL_CONV_STUB(IfcCartesianTransformationOperator3DnonUniform);
134.4202 +	DECL_CONV_STUB(IfcCurtainWallType);
134.4203 +	DECL_CONV_STUB(IfcEquipmentStandard);
134.4204 +	DECL_CONV_STUB(IfcFlowStorageDeviceType);
134.4205 +	DECL_CONV_STUB(IfcDiameterDimension);
134.4206 +	DECL_CONV_STUB(IfcSwitchingDeviceType);
134.4207 +	DECL_CONV_STUB(IfcWindow);
134.4208 +	DECL_CONV_STUB(IfcFlowTreatmentDevice);
134.4209 +	DECL_CONV_STUB(IfcChillerType);
134.4210 +	DECL_CONV_STUB(IfcRectangleHollowProfileDef);
134.4211 +	DECL_CONV_STUB(IfcBoxedHalfSpace);
134.4212 +	DECL_CONV_STUB(IfcAxis2Placement2D);
134.4213 +	DECL_CONV_STUB(IfcSpaceProgram);
134.4214 +	DECL_CONV_STUB(IfcPoint);
134.4215 +	DECL_CONV_STUB(IfcCartesianPoint);
134.4216 +	DECL_CONV_STUB(IfcBoundedSurface);
134.4217 +	DECL_CONV_STUB(IfcLoop);
134.4218 +	DECL_CONV_STUB(IfcPolyLoop);
134.4219 +	DECL_CONV_STUB(IfcTerminatorSymbol);
134.4220 +	DECL_CONV_STUB(IfcDimensionCurveTerminator);
134.4221 +	DECL_CONV_STUB(IfcTrapeziumProfileDef);
134.4222 +	DECL_CONV_STUB(IfcRepresentationContext);
134.4223 +	DECL_CONV_STUB(IfcGeometricRepresentationContext);
134.4224 +	DECL_CONV_STUB(IfcCurveBoundedPlane);
134.4225 +	DECL_CONV_STUB(IfcSIUnit);
134.4226 +	DECL_CONV_STUB(IfcStructuralReaction);
134.4227 +	DECL_CONV_STUB(IfcStructuralPointReaction);
134.4228 +	DECL_CONV_STUB(IfcAxis1Placement);
134.4229 +	DECL_CONV_STUB(IfcElectricApplianceType);
134.4230 +	DECL_CONV_STUB(IfcSensorType);
134.4231 +	DECL_CONV_STUB(IfcFurnishingElement);
134.4232 +	DECL_CONV_STUB(IfcProtectiveDeviceType);
134.4233 +	DECL_CONV_STUB(IfcZShapeProfileDef);
134.4234 +	DECL_CONV_STUB(IfcScheduleTimeControl);
134.4235 +	DECL_CONV_STUB(IfcRepresentationMap);
134.4236 +	DECL_CONV_STUB(IfcClosedShell);
134.4237 +	DECL_CONV_STUB(IfcBuildingElementPart);
134.4238 +	DECL_CONV_STUB(IfcBlock);
134.4239 +	DECL_CONV_STUB(IfcLightFixtureType);
134.4240 +	DECL_CONV_STUB(IfcOpeningElement);
134.4241 +	DECL_CONV_STUB(IfcLightSourceSpot);
134.4242 +	DECL_CONV_STUB(IfcTendonAnchor);
134.4243 +	DECL_CONV_STUB(IfcElectricFlowStorageDeviceType);
134.4244 +	DECL_CONV_STUB(IfcSphere);
134.4245 +	DECL_CONV_STUB(IfcDamperType);
134.4246 +	DECL_CONV_STUB(IfcProjectOrderRecord);
134.4247 +	DECL_CONV_STUB(IfcDistributionChamberElement);
134.4248 +	DECL_CONV_STUB(IfcMechanicalFastener);
134.4249 +	DECL_CONV_STUB(IfcRectangularTrimmedSurface);
134.4250 +	DECL_CONV_STUB(IfcZone);
134.4251 +	DECL_CONV_STUB(IfcFanType);
134.4252 +	DECL_CONV_STUB(IfcGeometricSet);
134.4253 +	DECL_CONV_STUB(IfcFillAreaStyleTiles);
134.4254 +	DECL_CONV_STUB(IfcCableSegmentType);
134.4255 +	DECL_CONV_STUB(IfcRelOverridesProperties);
134.4256 +	DECL_CONV_STUB(IfcMeasureWithUnit);
134.4257 +	DECL_CONV_STUB(IfcSlabType);
134.4258 +	DECL_CONV_STUB(IfcServiceLife);
134.4259 +	DECL_CONV_STUB(IfcFurnitureType);
134.4260 +	DECL_CONV_STUB(IfcCostItem);
134.4261 +	DECL_CONV_STUB(IfcReinforcingMesh);
134.4262 +	DECL_CONV_STUB(IfcFacetedBrepWithVoids);
134.4263 +	DECL_CONV_STUB(IfcGasTerminalType);
134.4264 +	DECL_CONV_STUB(IfcPile);
134.4265 +	DECL_CONV_STUB(IfcFillAreaStyleTileSymbolWithStyle);
134.4266 +	DECL_CONV_STUB(IfcConstructionMaterialResource);
134.4267 +	DECL_CONV_STUB(IfcAnnotationCurveOccurrence);
134.4268 +	DECL_CONV_STUB(IfcDimensionCurve);
134.4269 +	DECL_CONV_STUB(IfcGeometricCurveSet);
134.4270 +	DECL_CONV_STUB(IfcRelAggregates);
134.4271 +	DECL_CONV_STUB(IfcFaceBasedSurfaceModel);
134.4272 +	DECL_CONV_STUB(IfcEnergyConversionDevice);
134.4273 +	DECL_CONV_STUB(IfcRampFlight);
134.4274 +	DECL_CONV_STUB(IfcVertexLoop);
134.4275 +	DECL_CONV_STUB(IfcPlate);
134.4276 +	DECL_CONV_STUB(IfcUShapeProfileDef);
134.4277 +	DECL_CONV_STUB(IfcFaceBound);
134.4278 +	DECL_CONV_STUB(IfcFaceOuterBound);
134.4279 +	DECL_CONV_STUB(IfcOneDirectionRepeatFactor);
134.4280 +	DECL_CONV_STUB(IfcBoilerType);
134.4281 +	DECL_CONV_STUB(IfcConstructionEquipmentResource);
134.4282 +	DECL_CONV_STUB(IfcComplexProperty);
134.4283 +	DECL_CONV_STUB(IfcFooting);
134.4284 +	DECL_CONV_STUB(IfcConstructionProductResource);
134.4285 +	DECL_CONV_STUB(IfcDerivedProfileDef);
134.4286 +	DECL_CONV_STUB(IfcPropertyTableValue);
134.4287 +	DECL_CONV_STUB(IfcFlowMeterType);
134.4288 +	DECL_CONV_STUB(IfcDoorStyle);
134.4289 +	DECL_CONV_STUB(IfcUnitAssignment);
134.4290 +	DECL_CONV_STUB(IfcFlowTerminal);
134.4291 +	DECL_CONV_STUB(IfcCraneRailFShapeProfileDef);
134.4292 +	DECL_CONV_STUB(IfcFlowSegment);
134.4293 +	DECL_CONV_STUB(IfcElementQuantity);
134.4294 +	DECL_CONV_STUB(IfcCurtainWall);
134.4295 +	DECL_CONV_STUB(IfcDiscreteAccessory);
134.4296 +	DECL_CONV_STUB(IfcGrid);
134.4297 +	DECL_CONV_STUB(IfcSanitaryTerminalType);
134.4298 +	DECL_CONV_STUB(IfcSubedge);
134.4299 +	DECL_CONV_STUB(IfcFilterType);
134.4300 +	DECL_CONV_STUB(IfcTendon);
134.4301 +	DECL_CONV_STUB(IfcStructuralLoadGroup);
134.4302 +	DECL_CONV_STUB(IfcPresentationStyleAssignment);
134.4303 +	DECL_CONV_STUB(IfcStructuralCurveMember);
134.4304 +	DECL_CONV_STUB(IfcLightSourceAmbient);
134.4305 +	DECL_CONV_STUB(IfcCondition);
134.4306 +	DECL_CONV_STUB(IfcPort);
134.4307 +	DECL_CONV_STUB(IfcSpace);
134.4308 +	DECL_CONV_STUB(IfcHeatExchangerType);
134.4309 +	DECL_CONV_STUB(IfcTankType);
134.4310 +	DECL_CONV_STUB(IfcInventory);
134.4311 +	DECL_CONV_STUB(IfcTransportElementType);
134.4312 +	DECL_CONV_STUB(IfcAirToAirHeatRecoveryType);
134.4313 +	DECL_CONV_STUB(IfcStairFlight);
134.4314 +	DECL_CONV_STUB(IfcElectricalElement);
134.4315 +	DECL_CONV_STUB(IfcSurfaceStyleWithTextures);
134.4316 +	DECL_CONV_STUB(IfcBoundingBox);
134.4317 +	DECL_CONV_STUB(IfcWallType);
134.4318 +	DECL_CONV_STUB(IfcMove);
134.4319 +	DECL_CONV_STUB(IfcCircle);
134.4320 +	DECL_CONV_STUB(IfcOffsetCurve2D);
134.4321 +	DECL_CONV_STUB(IfcPointOnCurve);
134.4322 +	DECL_CONV_STUB(IfcStructuralResultGroup);
134.4323 +	DECL_CONV_STUB(IfcSectionedSpine);
134.4324 +	DECL_CONV_STUB(IfcSlab);
134.4325 +	DECL_CONV_STUB(IfcVertex);
134.4326 +	DECL_CONV_STUB(IfcVertexPoint);
134.4327 +	DECL_CONV_STUB(IfcStructuralLinearAction);
134.4328 +	DECL_CONV_STUB(IfcStructuralLinearActionVarying);
134.4329 +	DECL_CONV_STUB(IfcBuildingElementProxyType);
134.4330 +	DECL_CONV_STUB(IfcProjectionElement);
134.4331 +	DECL_CONV_STUB(IfcConversionBasedUnit);
134.4332 +	DECL_CONV_STUB(IfcGeometricRepresentationSubContext);
134.4333 +	DECL_CONV_STUB(IfcAnnotationSurfaceOccurrence);
134.4334 +	DECL_CONV_STUB(IfcRoundedEdgeFeature);
134.4335 +	DECL_CONV_STUB(IfcElectricDistributionPoint);
134.4336 +	DECL_CONV_STUB(IfcCableCarrierSegmentType);
134.4337 +	DECL_CONV_STUB(IfcWallStandardCase);
134.4338 +	DECL_CONV_STUB(IfcCsgSolid);
134.4339 +	DECL_CONV_STUB(IfcBeamType);
134.4340 +	DECL_CONV_STUB(IfcAnnotationFillArea);
134.4341 +	DECL_CONV_STUB(IfcStructuralCurveMemberVarying);
134.4342 +	DECL_CONV_STUB(IfcPointOnSurface);
134.4343 +	DECL_CONV_STUB(IfcOrderAction);
134.4344 +	DECL_CONV_STUB(IfcEdgeLoop);
134.4345 +	DECL_CONV_STUB(IfcAnnotationFillAreaOccurrence);
134.4346 +	DECL_CONV_STUB(IfcWorkPlan);
134.4347 +	DECL_CONV_STUB(IfcEllipse);
134.4348 +	DECL_CONV_STUB(IfcProductDefinitionShape);
134.4349 +	DECL_CONV_STUB(IfcProjectionCurve);
134.4350 +	DECL_CONV_STUB(IfcElectricalCircuit);
134.4351 +	DECL_CONV_STUB(IfcRationalBezierCurve);
134.4352 +	DECL_CONV_STUB(IfcStructuralPointAction);
134.4353 +	DECL_CONV_STUB(IfcPipeSegmentType);
134.4354 +	DECL_CONV_STUB(IfcTwoDirectionRepeatFactor);
134.4355 +	DECL_CONV_STUB(IfcShapeRepresentation);
134.4356 +	DECL_CONV_STUB(IfcPropertySet);
134.4357 +	DECL_CONV_STUB(IfcSurfaceStyleRendering);
134.4358 +	DECL_CONV_STUB(IfcDistributionPort);
134.4359 +	DECL_CONV_STUB(IfcPipeFittingType);
134.4360 +	DECL_CONV_STUB(IfcTransportElement);
134.4361 +	DECL_CONV_STUB(IfcAnnotationTextOccurrence);
134.4362 +	DECL_CONV_STUB(IfcStructuralAnalysisModel);
134.4363 +	DECL_CONV_STUB(IfcConditionCriterion);
134.4364 +
134.4365 +
134.4366 +#undef DECL_CONV_STUB
134.4367 +
134.4368 +} //! STEP
134.4369 +} //! Assimp
134.4370 +
134.4371 +#endif // INCLUDED_IFC_READER_GEN_H
   135.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   135.2 +++ b/libs/assimp/IFCUtil.cpp	Sat Feb 01 19:58:19 2014 +0200
   135.3 @@ -0,0 +1,577 @@
   135.4 +/*
   135.5 +Open Asset Import Library (assimp)
   135.6 +----------------------------------------------------------------------
   135.7 +
   135.8 +Copyright (c) 2006-2012, assimp team
   135.9 +All rights reserved.
  135.10 +
  135.11 +Redistribution and use of this software in source and binary forms, 
  135.12 +with or without modification, are permitted provided that the 
  135.13 +following conditions are met:
  135.14 +
  135.15 +* Redistributions of source code must retain the above
  135.16 +  copyright notice, this list of conditions and the
  135.17 +  following disclaimer.
  135.18 +
  135.19 +* Redistributions in binary form must reproduce the above
  135.20 +  copyright notice, this list of conditions and the
  135.21 +  following disclaimer in the documentation and/or other
  135.22 +  materials provided with the distribution.
  135.23 +
  135.24 +* Neither the name of the assimp team, nor the names of its
  135.25 +  contributors may be used to endorse or promote products
  135.26 +  derived from this software without specific prior
  135.27 +  written permission of the assimp team.
  135.28 +
  135.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  135.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  135.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  135.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  135.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  135.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  135.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  135.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  135.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  135.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  135.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  135.40 +
  135.41 +----------------------------------------------------------------------
  135.42 +*/
  135.43 +
  135.44 +/** @file  IFCUtil.cpp
  135.45 + *  @brief Implementation of conversion routines for some common Ifc helper entities.
  135.46 + */
  135.47 +
  135.48 +#include "AssimpPCH.h"
  135.49 +
  135.50 +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
  135.51 +
  135.52 +#include "IFCUtil.h"
  135.53 +#include "PolyTools.h"
  135.54 +#include "ProcessHelper.h"
  135.55 +
  135.56 +namespace Assimp {
  135.57 +	namespace IFC {
  135.58 +
  135.59 +// ------------------------------------------------------------------------------------------------
  135.60 +void TempOpening::Transform(const IfcMatrix4& mat) 
  135.61 +{
  135.62 +	if(profileMesh) {
  135.63 +		profileMesh->Transform(mat);
  135.64 +	}
  135.65 +	if(profileMesh2D) {
  135.66 +		profileMesh2D->Transform(mat);
  135.67 +	}
  135.68 +	extrusionDir *= IfcMatrix3(mat);
  135.69 +}
  135.70 +
  135.71 +// ------------------------------------------------------------------------------------------------
  135.72 +aiMesh* TempMesh::ToMesh() 
  135.73 +{
  135.74 +	ai_assert(verts.size() == std::accumulate(vertcnt.begin(),vertcnt.end(),size_t(0)));
  135.75 +
  135.76 +	if (verts.empty()) {
  135.77 +		return NULL;
  135.78 +	}
  135.79 +
  135.80 +	std::auto_ptr<aiMesh> mesh(new aiMesh());
  135.81 +
  135.82 +	// copy vertices
  135.83 +	mesh->mNumVertices = static_cast<unsigned int>(verts.size());
  135.84 +	mesh->mVertices = new aiVector3D[mesh->mNumVertices];
  135.85 +	std::copy(verts.begin(),verts.end(),mesh->mVertices);
  135.86 +
  135.87 +	// and build up faces
  135.88 +	mesh->mNumFaces = static_cast<unsigned int>(vertcnt.size());
  135.89 +	mesh->mFaces = new aiFace[mesh->mNumFaces];
  135.90 +
  135.91 +	for(unsigned int i = 0,n=0, acc = 0; i < mesh->mNumFaces; ++n) {
  135.92 +		aiFace& f = mesh->mFaces[i];
  135.93 +		if (!vertcnt[n]) {
  135.94 +			--mesh->mNumFaces;
  135.95 +			continue;
  135.96 +		}
  135.97 +
  135.98 +		f.mNumIndices = vertcnt[n];
  135.99 +		f.mIndices = new unsigned int[f.mNumIndices];
 135.100 +		for(unsigned int a = 0; a < f.mNumIndices; ++a) {
 135.101 +			f.mIndices[a] = acc++;
 135.102 +		}
 135.103 +
 135.104 +		++i;
 135.105 +	}
 135.106 +
 135.107 +	return mesh.release();
 135.108 +}
 135.109 +
 135.110 +// ------------------------------------------------------------------------------------------------
 135.111 +void TempMesh::Clear()
 135.112 +{
 135.113 +	verts.clear();
 135.114 +	vertcnt.clear();
 135.115 +}
 135.116 +
 135.117 +// ------------------------------------------------------------------------------------------------
 135.118 +void TempMesh::Transform(const IfcMatrix4& mat) 
 135.119 +{
 135.120 +	BOOST_FOREACH(IfcVector3& v, verts) {
 135.121 +		v *= mat;
 135.122 +	}
 135.123 +}
 135.124 +
 135.125 +// ------------------------------------------------------------------------------
 135.126 +IfcVector3 TempMesh::Center() const
 135.127 +{
 135.128 +	return std::accumulate(verts.begin(),verts.end(),IfcVector3()) / static_cast<IfcFloat>(verts.size());
 135.129 +}
 135.130 +
 135.131 +// ------------------------------------------------------------------------------------------------
 135.132 +void TempMesh::Append(const TempMesh& other)
 135.133 +{
 135.134 +	verts.insert(verts.end(),other.verts.begin(),other.verts.end());
 135.135 +	vertcnt.insert(vertcnt.end(),other.vertcnt.begin(),other.vertcnt.end());
 135.136 +}
 135.137 +
 135.138 +// ------------------------------------------------------------------------------------------------
 135.139 +void TempMesh::RemoveDegenerates()
 135.140 +{
 135.141 +	// The strategy is simple: walk the mesh and compute normals using
 135.142 +	// Newell's algorithm. The length of the normals gives the area
 135.143 +	// of the polygons, which is close to zero for lines.
 135.144 +
 135.145 +	std::vector<IfcVector3> normals;
 135.146 +	ComputePolygonNormals(normals, false);
 135.147 +
 135.148 +	bool drop = false;
 135.149 +	size_t inor = 0;
 135.150 +
 135.151 +	std::vector<IfcVector3>::iterator vit = verts.begin();
 135.152 +	for (std::vector<unsigned int>::iterator it = vertcnt.begin(); it != vertcnt.end(); ++inor) {
 135.153 +		const unsigned int pcount = *it;
 135.154 +		
 135.155 +		if (normals[inor].SquareLength() < 1e-5f) {
 135.156 +			it = vertcnt.erase(it);
 135.157 +			vit = verts.erase(vit, vit + pcount);
 135.158 +
 135.159 +			drop = true;
 135.160 +			continue;
 135.161 +		}
 135.162 +
 135.163 +		vit += pcount;
 135.164 +		++it;
 135.165 +	}
 135.166 +
 135.167 +	if(drop) {
 135.168 +		IFCImporter::LogDebug("removing degenerate faces");
 135.169 +	}
 135.170 +}
 135.171 +
 135.172 +// ------------------------------------------------------------------------------------------------
 135.173 +void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals, 
 135.174 +	bool normalize, 
 135.175 +	size_t ofs) const
 135.176 +{
 135.177 +	size_t max_vcount = 0;
 135.178 +	std::vector<unsigned int>::const_iterator begin = vertcnt.begin()+ofs, end = vertcnt.end(),  iit;
 135.179 +	for(iit = begin; iit != end; ++iit) {
 135.180 +		max_vcount = std::max(max_vcount,static_cast<size_t>(*iit));
 135.181 +	}
 135.182 +
 135.183 +	std::vector<IfcFloat> temp((max_vcount+2)*4);
 135.184 +	normals.reserve( normals.size() + vertcnt.size()-ofs );
 135.185 +
 135.186 +	// `NewellNormal()` currently has a relatively strange interface and need to 
 135.187 +	// re-structure things a bit to meet them.
 135.188 +	size_t vidx = std::accumulate(vertcnt.begin(),begin,0);
 135.189 +	for(iit = begin; iit != end; vidx += *iit++) {
 135.190 +		if (!*iit) {
 135.191 +			normals.push_back(IfcVector3());
 135.192 +			continue;
 135.193 +		}
 135.194 +		for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) {
 135.195 +			const IfcVector3& v = verts[vidx+vofs];
 135.196 +			temp[cnt++] = v.x;
 135.197 +			temp[cnt++] = v.y;
 135.198 +			temp[cnt++] = v.z;
 135.199 +#ifdef _DEBUG
 135.200 +			temp[cnt] = std::numeric_limits<IfcFloat>::quiet_NaN();
 135.201 +#endif
 135.202 +			++cnt;
 135.203 +		}
 135.204 +
 135.205 +		normals.push_back(IfcVector3());
 135.206 +		NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]);
 135.207 +	}
 135.208 +
 135.209 +	if(normalize) {
 135.210 +		BOOST_FOREACH(IfcVector3& n, normals) {
 135.211 +			n.Normalize();
 135.212 +		}
 135.213 +	}
 135.214 +}
 135.215 +
 135.216 +// ------------------------------------------------------------------------------------------------
 135.217 +// Compute the normal of the last polygon in the given mesh
 135.218 +IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const
 135.219 +{
 135.220 +	size_t total = vertcnt.back(), vidx = verts.size() - total;
 135.221 +	std::vector<IfcFloat> temp((total+2)*3);
 135.222 +	for(size_t vofs = 0, cnt = 0; vofs < total; ++vofs) {
 135.223 +		const IfcVector3& v = verts[vidx+vofs];
 135.224 +		temp[cnt++] = v.x;
 135.225 +		temp[cnt++] = v.y;
 135.226 +		temp[cnt++] = v.z;
 135.227 +	}
 135.228 +	IfcVector3 nor;
 135.229 +	NewellNormal<3,3,3>(nor,total,&temp[0],&temp[1],&temp[2]);
 135.230 +	return normalize ? nor.Normalize() : nor;
 135.231 +}
 135.232 +
 135.233 +// ------------------------------------------------------------------------------------------------
 135.234 +void TempMesh::FixupFaceOrientation()
 135.235 +{
 135.236 +	const IfcVector3 vavg = Center();
 135.237 +
 135.238 +	std::vector<IfcVector3> normals;
 135.239 +	ComputePolygonNormals(normals);
 135.240 +
 135.241 +	size_t c = 0, ofs = 0;
 135.242 +	BOOST_FOREACH(unsigned int cnt, vertcnt) {
 135.243 +		if (cnt>2){
 135.244 +			const IfcVector3& thisvert = verts[c];
 135.245 +			if (normals[ofs]*(thisvert-vavg) < 0) {
 135.246 +				std::reverse(verts.begin()+c,verts.begin()+cnt+c);
 135.247 +			}
 135.248 +		}
 135.249 +		c += cnt;
 135.250 +		++ofs;
 135.251 +	}
 135.252 +}
 135.253 +
 135.254 +// ------------------------------------------------------------------------------------------------
 135.255 +void TempMesh::RemoveAdjacentDuplicates() 
 135.256 +{
 135.257 +
 135.258 +	bool drop = false;
 135.259 +	std::vector<IfcVector3>::iterator base = verts.begin();
 135.260 +	BOOST_FOREACH(unsigned int& cnt, vertcnt) {
 135.261 +		if (cnt < 2){
 135.262 +			base += cnt;
 135.263 +			continue;
 135.264 +		}
 135.265 +
 135.266 +		IfcVector3 vmin,vmax;
 135.267 +		ArrayBounds(&*base, cnt ,vmin,vmax);
 135.268 +
 135.269 +
 135.270 +		const IfcFloat epsilon = (vmax-vmin).SquareLength() / static_cast<IfcFloat>(1e9);
 135.271 +		//const IfcFloat dotepsilon = 1e-9;
 135.272 +
 135.273 +		//// look for vertices that lie directly on the line between their predecessor and their 
 135.274 +		//// successor and replace them with either of them.
 135.275 +
 135.276 +		//for(size_t i = 0; i < cnt; ++i) {
 135.277 +		//	IfcVector3& v1 = *(base+i), &v0 = *(base+(i?i-1:cnt-1)), &v2 = *(base+(i+1)%cnt);
 135.278 +		//	const IfcVector3& d0 = (v1-v0), &d1 = (v2-v1);
 135.279 +		//	const IfcFloat l0 = d0.SquareLength(), l1 = d1.SquareLength();
 135.280 +		//	if (!l0 || !l1) {
 135.281 +		//		continue;
 135.282 +		//	}
 135.283 +
 135.284 +		//	const IfcFloat d = (d0/sqrt(l0))*(d1/sqrt(l1));
 135.285 +
 135.286 +		//	if ( d >= 1.f-dotepsilon ) {
 135.287 +		//		v1 = v0;
 135.288 +		//	}
 135.289 +		//	else if ( d < -1.f+dotepsilon ) {
 135.290 +		//		v2 = v1;
 135.291 +		//		continue;
 135.292 +		//	}
 135.293 +		//}
 135.294 +
 135.295 +		// drop any identical, adjacent vertices. this pass will collect the dropouts
 135.296 +		// of the previous pass as a side-effect.
 135.297 +		FuzzyVectorCompare fz(epsilon);
 135.298 +		std::vector<IfcVector3>::iterator end = base+cnt, e = std::unique( base, end, fz );
 135.299 +		if (e != end) {
 135.300 +			cnt -= static_cast<unsigned int>(std::distance(e, end));
 135.301 +			verts.erase(e,end);
 135.302 +			drop  = true;
 135.303 +		}
 135.304 +
 135.305 +		// check front and back vertices for this polygon
 135.306 +		if (cnt > 1 && fz(*base,*(base+cnt-1))) {
 135.307 +			verts.erase(base+ --cnt);
 135.308 +			drop  = true;
 135.309 +		}
 135.310 +
 135.311 +		// removing adjacent duplicates shouldn't erase everything :-)
 135.312 +		ai_assert(cnt>0);
 135.313 +		base += cnt;
 135.314 +	}
 135.315 +	if(drop) {
 135.316 +		IFCImporter::LogDebug("removing duplicate vertices");
 135.317 +	}
 135.318 +}
 135.319 +
 135.320 +// ------------------------------------------------------------------------------------------------
 135.321 +void TempMesh::Swap(TempMesh& other)
 135.322 +{
 135.323 +	vertcnt.swap(other.vertcnt);
 135.324 +	verts.swap(other.verts);
 135.325 +}
 135.326 +
 135.327 +// ------------------------------------------------------------------------------------------------
 135.328 +bool IsTrue(const EXPRESS::BOOLEAN& in)
 135.329 +{
 135.330 +	return (std::string)in == "TRUE" || (std::string)in == "T";
 135.331 +}
 135.332 +
 135.333 +// ------------------------------------------------------------------------------------------------
 135.334 +IfcFloat ConvertSIPrefix(const std::string& prefix)
 135.335 +{
 135.336 +	if (prefix == "EXA") {
 135.337 +		return 1e18f;
 135.338 +	}
 135.339 +	else if (prefix == "PETA") {
 135.340 +		return 1e15f;
 135.341 +	}
 135.342 +	else if (prefix == "TERA") {
 135.343 +		return 1e12f;
 135.344 +	}
 135.345 +	else if (prefix == "GIGA") {
 135.346 +		return 1e9f;
 135.347 +	}
 135.348 +	else if (prefix == "MEGA") {
 135.349 +		return 1e6f;
 135.350 +	}
 135.351 +	else if (prefix == "KILO") {
 135.352 +		return 1e3f;
 135.353 +	}
 135.354 +	else if (prefix == "HECTO") {
 135.355 +		return 1e2f;
 135.356 +	}
 135.357 +	else if (prefix == "DECA") {
 135.358 +		return 1e-0f;
 135.359 +	}
 135.360 +	else if (prefix == "DECI") {
 135.361 +		return 1e-1f;
 135.362 +	}
 135.363 +	else if (prefix == "CENTI") {
 135.364 +		return 1e-2f;
 135.365 +	}
 135.366 +	else if (prefix == "MILLI") {
 135.367 +		return 1e-3f;
 135.368 +	}
 135.369 +	else if (prefix == "MICRO") {
 135.370 +		return 1e-6f;
 135.371 +	}
 135.372 +	else if (prefix == "NANO") {
 135.373 +		return 1e-9f;
 135.374 +	}
 135.375 +	else if (prefix == "PICO") {
 135.376 +		return 1e-12f;
 135.377 +	}
 135.378 +	else if (prefix == "FEMTO") {
 135.379 +		return 1e-15f;
 135.380 +	}
 135.381 +	else if (prefix == "ATTO") {
 135.382 +		return 1e-18f;
 135.383 +	}
 135.384 +	else {
 135.385 +		IFCImporter::LogError("Unrecognized SI prefix: " + prefix);
 135.386 +		return 1;
 135.387 +	}
 135.388 +}
 135.389 +
 135.390 +// ------------------------------------------------------------------------------------------------
 135.391 +void ConvertColor(aiColor4D& out, const IfcColourRgb& in)
 135.392 +{
 135.393 +	out.r = static_cast<float>( in.Red );
 135.394 +	out.g = static_cast<float>( in.Green );
 135.395 +	out.b = static_cast<float>( in.Blue );
 135.396 +	out.a = static_cast<float>( 1.f );
 135.397 +}
 135.398 +
 135.399 +// ------------------------------------------------------------------------------------------------
 135.400 +void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base)
 135.401 +{
 135.402 +	if (const EXPRESS::REAL* const r = in.ToPtr<EXPRESS::REAL>()) {
 135.403 +		out.r = out.g = out.b = static_cast<float>(*r);
 135.404 +		if(base) {
 135.405 +			out.r *= static_cast<float>( base->r );
 135.406 +			out.g *= static_cast<float>( base->g );
 135.407 +			out.b *= static_cast<float>( base->b );
 135.408 +			out.a = static_cast<float>( base->a );
 135.409 +		}
 135.410 +		else out.a = 1.0;
 135.411 +	}
 135.412 +	else if (const IfcColourRgb* const rgb = in.ResolveSelectPtr<IfcColourRgb>(conv.db)) {
 135.413 +		ConvertColor(out,*rgb);
 135.414 +	}
 135.415 +	else {
 135.416 +		IFCImporter::LogWarn("skipping unknown IfcColourOrFactor entity");
 135.417 +	}
 135.418 +}
 135.419 +
 135.420 +// ------------------------------------------------------------------------------------------------
 135.421 +void ConvertCartesianPoint(IfcVector3& out, const IfcCartesianPoint& in)
 135.422 +{
 135.423 +	out = IfcVector3();
 135.424 +	for(size_t i = 0; i < in.Coordinates.size(); ++i) {
 135.425 +		out[i] = in.Coordinates[i];
 135.426 +	}
 135.427 +}
 135.428 +
 135.429 +// ------------------------------------------------------------------------------------------------
 135.430 +void ConvertVector(IfcVector3& out, const IfcVector& in)
 135.431 +{
 135.432 +	ConvertDirection(out,in.Orientation);
 135.433 +	out *= in.Magnitude;
 135.434 +}
 135.435 +
 135.436 +// ------------------------------------------------------------------------------------------------
 135.437 +void ConvertDirection(IfcVector3& out, const IfcDirection& in)
 135.438 +{
 135.439 +	out = IfcVector3();
 135.440 +	for(size_t i = 0; i < in.DirectionRatios.size(); ++i) {
 135.441 +		out[i] = in.DirectionRatios[i];
 135.442 +	}
 135.443 +	const IfcFloat len = out.Length();
 135.444 +	if (len<1e-6) {
 135.445 +		IFCImporter::LogWarn("direction vector magnitude too small, normalization would result in a division by zero");
 135.446 +		return;
 135.447 +	}
 135.448 +	out /= len;
 135.449 +}
 135.450 +
 135.451 +// ------------------------------------------------------------------------------------------------
 135.452 +void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z)
 135.453 +{
 135.454 +	out.a1 = x.x;
 135.455 +	out.b1 = x.y;
 135.456 +	out.c1 = x.z;
 135.457 +
 135.458 +	out.a2 = y.x;
 135.459 +	out.b2 = y.y;
 135.460 +	out.c2 = y.z;
 135.461 +
 135.462 +	out.a3 = z.x;
 135.463 +	out.b3 = z.y;
 135.464 +	out.c3 = z.z;
 135.465 +}
 135.466 +
 135.467 +// ------------------------------------------------------------------------------------------------
 135.468 +void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement3D& in)
 135.469 +{
 135.470 +	IfcVector3 loc;
 135.471 +	ConvertCartesianPoint(loc,in.Location);
 135.472 +
 135.473 +	IfcVector3 z(0.f,0.f,1.f),r(1.f,0.f,0.f),x;
 135.474 +
 135.475 +	if (in.Axis) { 
 135.476 +		ConvertDirection(z,*in.Axis.Get());
 135.477 +	}
 135.478 +	if (in.RefDirection) {
 135.479 +		ConvertDirection(r,*in.RefDirection.Get());
 135.480 +	}
 135.481 +
 135.482 +	IfcVector3 v = r.Normalize();
 135.483 +	IfcVector3 tmpx = z * (v*z);
 135.484 +
 135.485 +	x = (v-tmpx).Normalize();
 135.486 +	IfcVector3 y = (z^x);
 135.487 +
 135.488 +	IfcMatrix4::Translation(loc,out);
 135.489 +	AssignMatrixAxes(out,x,y,z);
 135.490 +}
 135.491 +
 135.492 +// ------------------------------------------------------------------------------------------------
 135.493 +void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement2D& in)
 135.494 +{
 135.495 +	IfcVector3 loc;
 135.496 +	ConvertCartesianPoint(loc,in.Location);
 135.497 +
 135.498 +	IfcVector3 x(1.f,0.f,0.f);
 135.499 +	if (in.RefDirection) {
 135.500 +		ConvertDirection(x,*in.RefDirection.Get());
 135.501 +	}
 135.502 +
 135.503 +	const IfcVector3 y = IfcVector3(x.y,-x.x,0.f);
 135.504 +
 135.505 +	IfcMatrix4::Translation(loc,out);
 135.506 +	AssignMatrixAxes(out,x,y,IfcVector3(0.f,0.f,1.f));
 135.507 +}
 135.508 +
 135.509 +// ------------------------------------------------------------------------------------------------
 135.510 +void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const IfcAxis1Placement& in)
 135.511 +{
 135.512 +	ConvertCartesianPoint(pos,in.Location);
 135.513 +	if (in.Axis) {
 135.514 +		ConvertDirection(axis,in.Axis.Get());
 135.515 +	}
 135.516 +	else {
 135.517 +		axis = IfcVector3(0.f,0.f,1.f);
 135.518 +	}
 135.519 +}
 135.520 +
 135.521 +// ------------------------------------------------------------------------------------------------
 135.522 +void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement& in, ConversionData& conv)
 135.523 +{
 135.524 +	if(const IfcAxis2Placement3D* pl3 = in.ResolveSelectPtr<IfcAxis2Placement3D>(conv.db)) {
 135.525 +		ConvertAxisPlacement(out,*pl3);
 135.526 +	}
 135.527 +	else if(const IfcAxis2Placement2D* pl2 = in.ResolveSelectPtr<IfcAxis2Placement2D>(conv.db)) {
 135.528 +		ConvertAxisPlacement(out,*pl2);
 135.529 +	}
 135.530 +	else {
 135.531 +		IFCImporter::LogWarn("skipping unknown IfcAxis2Placement entity");
 135.532 +	}
 135.533 +}
 135.534 +
 135.535 +// ------------------------------------------------------------------------------------------------
 135.536 +void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationOperator& op)
 135.537 +{
 135.538 +	IfcVector3 loc;
 135.539 +	ConvertCartesianPoint(loc,op.LocalOrigin);
 135.540 +
 135.541 +	IfcVector3 x(1.f,0.f,0.f),y(0.f,1.f,0.f),z(0.f,0.f,1.f);
 135.542 +	if (op.Axis1) {
 135.543 +		ConvertDirection(x,*op.Axis1.Get());
 135.544 +	}
 135.545 +	if (op.Axis2) {
 135.546 +		ConvertDirection(y,*op.Axis2.Get());
 135.547 +	}
 135.548 +	if (const IfcCartesianTransformationOperator3D* op2 = op.ToPtr<IfcCartesianTransformationOperator3D>()) {
 135.549 +		if(op2->Axis3) {
 135.550 +			ConvertDirection(z,*op2->Axis3.Get());
 135.551 +		}
 135.552 +	}
 135.553 +
 135.554 +	IfcMatrix4 locm;
 135.555 +	IfcMatrix4::Translation(loc,locm);	
 135.556 +	AssignMatrixAxes(out,x,y,z);
 135.557 +
 135.558 +
 135.559 +	IfcVector3 vscale;
 135.560 +	if (const IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr<IfcCartesianTransformationOperator3DnonUniform>()) {
 135.561 +		vscale.x = nuni->Scale?op.Scale.Get():1.f;
 135.562 +		vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f;
 135.563 +		vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f;
 135.564 +	}
 135.565 +	else {
 135.566 +		const IfcFloat sc = op.Scale?op.Scale.Get():1.f;
 135.567 +		vscale = IfcVector3(sc,sc,sc);
 135.568 +	}
 135.569 +
 135.570 +	IfcMatrix4 s;
 135.571 +	IfcMatrix4::Scaling(vscale,s);
 135.572 +
 135.573 +	out = locm * out * s;
 135.574 +}
 135.575 +
 135.576 +
 135.577 +} // ! IFC
 135.578 +} // ! Assimp
 135.579 +
 135.580 +#endif
   136.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   136.2 +++ b/libs/assimp/IFCUtil.h	Sat Feb 01 19:58:19 2014 +0200
   136.3 @@ -0,0 +1,412 @@
   136.4 +/*
   136.5 +Open Asset Import Library (assimp)
   136.6 +----------------------------------------------------------------------
   136.7 +
   136.8 +Copyright (c) 2006-2012, assimp team
   136.9 +All rights reserved.
  136.10 +
  136.11 +Redistribution and use of this software in source and binary forms, 
  136.12 +with or without modification, are permitted provided that the 
  136.13 +following conditions are met:
  136.14 +
  136.15 +* Redistributions of source code must retain the above
  136.16 +  copyright notice, this list of conditions and the
  136.17 +  following disclaimer.
  136.18 +
  136.19 +* Redistributions in binary form must reproduce the above
  136.20 +  copyright notice, this list of conditions and the
  136.21 +  following disclaimer in the documentation and/or other
  136.22 +  materials provided with the distribution.
  136.23 +
  136.24 +* Neither the name of the assimp team, nor the names of its
  136.25 +  contributors may be used to endorse or promote products
  136.26 +  derived from this software without specific prior
  136.27 +  written permission of the assimp team.
  136.28 +
  136.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  136.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  136.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  136.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  136.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  136.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  136.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  136.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  136.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  136.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  136.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  136.40 +
  136.41 +----------------------------------------------------------------------
  136.42 +*/
  136.43 +
  136.44 +/** @file  IFC.cpp
  136.45 + *  @brief Implementation of the Industry Foundation Classes loader.
  136.46 + */
  136.47 +
  136.48 +#ifndef INCLUDED_IFCUTIL_H
  136.49 +#define INCLUDED_IFCUTIL_H
  136.50 +
  136.51 +#include "IFCReaderGen.h"
  136.52 +#include "IFCLoader.h"
  136.53 +
  136.54 +namespace Assimp {
  136.55 +namespace IFC {
  136.56 +
  136.57 +	typedef double IfcFloat;
  136.58 +
  136.59 +	// IfcFloat-precision math data types
  136.60 +	typedef aiVector2t<IfcFloat> IfcVector2;
  136.61 +	typedef aiVector3t<IfcFloat> IfcVector3;
  136.62 +	typedef aiMatrix4x4t<IfcFloat> IfcMatrix4;
  136.63 +	typedef aiMatrix3x3t<IfcFloat> IfcMatrix3;
  136.64 +	typedef aiColor4t<IfcFloat> IfcColor4; 
  136.65 +
  136.66 +
  136.67 +// ------------------------------------------------------------------------------------------------
  136.68 +// Helper for std::for_each to delete all heap-allocated items in a container
  136.69 +// ------------------------------------------------------------------------------------------------
  136.70 +template<typename T>
  136.71 +struct delete_fun
  136.72 +{
  136.73 +	void operator()(T* del) {
  136.74 +		delete del;
  136.75 +	}
  136.76 +};
  136.77 +
  136.78 +
  136.79 +
  136.80 +// ------------------------------------------------------------------------------------------------
  136.81 +// Helper used during mesh construction. Aids at creating aiMesh'es out of relatively few polygons.
  136.82 +// ------------------------------------------------------------------------------------------------
  136.83 +struct TempMesh
  136.84 +{
  136.85 +	std::vector<IfcVector3> verts;
  136.86 +	std::vector<unsigned int> vertcnt;
  136.87 +
  136.88 +	// utilities
  136.89 +	aiMesh* ToMesh();
  136.90 +	void Clear();
  136.91 +	void Transform(const IfcMatrix4& mat);
  136.92 +	IfcVector3 Center() const;
  136.93 +	void Append(const TempMesh& other);
  136.94 +
  136.95 +	bool IsEmpty() const {
  136.96 +		return verts.empty() && vertcnt.empty();
  136.97 +	}
  136.98 +
  136.99 +	void RemoveAdjacentDuplicates();
 136.100 +	void RemoveDegenerates();
 136.101 +
 136.102 +	void FixupFaceOrientation();
 136.103 +	IfcVector3 ComputeLastPolygonNormal(bool normalize = true) const;
 136.104 +	void ComputePolygonNormals(std::vector<IfcVector3>& normals, 
 136.105 +		bool normalize = true, 
 136.106 +		size_t ofs = 0) const;
 136.107 +
 136.108 +	void Swap(TempMesh& other);
 136.109 +};
 136.110 +
 136.111 +
 136.112 +// ------------------------------------------------------------------------------------------------
 136.113 +// Temporary representation of an opening in a wall or a floor
 136.114 +// ------------------------------------------------------------------------------------------------
 136.115 +struct TempOpening 
 136.116 +{
 136.117 +	const IFC::IfcSolidModel* solid;
 136.118 +	IfcVector3 extrusionDir;
 136.119 +	
 136.120 +	boost::shared_ptr<TempMesh> profileMesh;
 136.121 +	boost::shared_ptr<TempMesh> profileMesh2D;
 136.122 +
 136.123 +	// list of points generated for this opening. This is used to
 136.124 +	// create connections between two opposing holes created
 136.125 +	// from a single opening instance (two because walls tend to
 136.126 +	// have two sides). If !empty(), the other side of the wall
 136.127 +	// has already been processed.
 136.128 +	std::vector<IfcVector3> wallPoints;
 136.129 +
 136.130 +	// ------------------------------------------------------------------------------
 136.131 +	TempOpening()
 136.132 +		: solid()
 136.133 +		, extrusionDir()
 136.134 +		, profileMesh()
 136.135 +	{
 136.136 +	}
 136.137 +
 136.138 +	// ------------------------------------------------------------------------------
 136.139 +	TempOpening(const IFC::IfcSolidModel* solid,IfcVector3 extrusionDir,
 136.140 +		boost::shared_ptr<TempMesh> profileMesh, 
 136.141 +		boost::shared_ptr<TempMesh> profileMesh2D)
 136.142 +		: solid(solid)
 136.143 +		, extrusionDir(extrusionDir)
 136.144 +		, profileMesh(profileMesh)
 136.145 +		, profileMesh2D(profileMesh2D)
 136.146 +	{
 136.147 +	}
 136.148 +
 136.149 +	// ------------------------------------------------------------------------------
 136.150 +	void Transform(const IfcMatrix4& mat); // defined later since TempMesh is not complete yet
 136.151 +
 136.152 +
 136.153 +
 136.154 +	// ------------------------------------------------------------------------------
 136.155 +	// Helper to sort openings by distance from a given base point
 136.156 +	struct DistanceSorter {
 136.157 +
 136.158 +		DistanceSorter(const IfcVector3& base) : base(base) {}
 136.159 +
 136.160 +		bool operator () (const TempOpening& a, const TempOpening& b) const {
 136.161 +			return (a.profileMesh->Center()-base).SquareLength() < (b.profileMesh->Center()-base).SquareLength();
 136.162 +		}
 136.163 +
 136.164 +		IfcVector3 base;
 136.165 +	};
 136.166 +};
 136.167 +
 136.168 +
 136.169 +// ------------------------------------------------------------------------------------------------
 136.170 +// Intermediate data storage during conversion. Keeps everything and a bit more.
 136.171 +// ------------------------------------------------------------------------------------------------
 136.172 +struct ConversionData 
 136.173 +{
 136.174 +	ConversionData(const STEP::DB& db, const IFC::IfcProject& proj, aiScene* out,const IFCImporter::Settings& settings)
 136.175 +		: len_scale(1.0)
 136.176 +		, angle_scale(-1.0)
 136.177 +		, db(db)
 136.178 +		, proj(proj)
 136.179 +		, out(out)
 136.180 +		, settings(settings)
 136.181 +		, apply_openings()
 136.182 +		, collect_openings()
 136.183 +	{}
 136.184 +
 136.185 +	~ConversionData() {
 136.186 +		std::for_each(meshes.begin(),meshes.end(),delete_fun<aiMesh>());
 136.187 +		std::for_each(materials.begin(),materials.end(),delete_fun<aiMaterial>());
 136.188 +	}
 136.189 +
 136.190 +	IfcFloat len_scale, angle_scale;
 136.191 +	bool plane_angle_in_radians;
 136.192 +
 136.193 +	const STEP::DB& db;
 136.194 +	const IFC::IfcProject& proj;
 136.195 +	aiScene* out;
 136.196 +
 136.197 +	IfcMatrix4 wcs;
 136.198 +	std::vector<aiMesh*> meshes;
 136.199 +	std::vector<aiMaterial*> materials;
 136.200 +
 136.201 +	typedef std::map<const IFC::IfcRepresentationItem*, std::vector<unsigned int> > MeshCache;
 136.202 +	MeshCache cached_meshes;
 136.203 +
 136.204 +	const IFCImporter::Settings& settings;
 136.205 +
 136.206 +	// Intermediate arrays used to resolve openings in walls: only one of them
 136.207 +	// can be given at a time. apply_openings if present if the current element
 136.208 +	// is a wall and needs its openings to be poured into its geometry while
 136.209 +	// collect_openings is present only if the current element is an 
 136.210 +	// IfcOpeningElement, for which all the geometry needs to be preserved
 136.211 +	// for later processing by a parent, which is a wall. 
 136.212 +	std::vector<TempOpening>* apply_openings;
 136.213 +	std::vector<TempOpening>* collect_openings;
 136.214 +
 136.215 +	std::set<uint64_t> already_processed;
 136.216 +};
 136.217 +
 136.218 +
 136.219 +// ------------------------------------------------------------------------------------------------
 136.220 +// Binary predicate to compare vectors with a given, quadratic epsilon.
 136.221 +// ------------------------------------------------------------------------------------------------
 136.222 +struct FuzzyVectorCompare {
 136.223 +
 136.224 +	FuzzyVectorCompare(IfcFloat epsilon) : epsilon(epsilon) {}
 136.225 +	bool operator()(const IfcVector3& a, const IfcVector3& b) {
 136.226 +		return fabs((a-b).SquareLength()) < epsilon;
 136.227 +	}
 136.228 +
 136.229 +	const IfcFloat epsilon;
 136.230 +};
 136.231 +
 136.232 +
 136.233 +// ------------------------------------------------------------------------------------------------
 136.234 +// Ordering predicate to totally order R^2 vectors first by x and then by y
 136.235 +// ------------------------------------------------------------------------------------------------
 136.236 +struct XYSorter {
 136.237 +
 136.238 +	// sort first by X coordinates, then by Y coordinates
 136.239 +	bool operator () (const IfcVector2&a, const IfcVector2& b) const {
 136.240 +		if (a.x == b.x) {
 136.241 +			return a.y < b.y;
 136.242 +		}
 136.243 +		return a.x < b.x;
 136.244 +	}
 136.245 +};
 136.246 +
 136.247 +
 136.248 +
 136.249 +// conversion routines for common IFC entities, implemented in IFCUtil.cpp
 136.250 +void ConvertColor(aiColor4D& out, const IfcColourRgb& in);
 136.251 +void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base);
 136.252 +void ConvertCartesianPoint(IfcVector3& out, const IfcCartesianPoint& in);
 136.253 +void ConvertDirection(IfcVector3& out, const IfcDirection& in);
 136.254 +void ConvertVector(IfcVector3& out, const IfcVector& in);
 136.255 +void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z);
 136.256 +void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement3D& in);
 136.257 +void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement2D& in);
 136.258 +void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const IFC::IfcAxis1Placement& in);
 136.259 +void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement& in, ConversionData& conv);
 136.260 +void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationOperator& op);
 136.261 +bool IsTrue(const EXPRESS::BOOLEAN& in);
 136.262 +IfcFloat ConvertSIPrefix(const std::string& prefix);
 136.263 +
 136.264 +
 136.265 +// IFCProfile.cpp
 136.266 +bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv);
 136.267 +
 136.268 +// IFCMaterial.cpp
 136.269 +unsigned int ProcessMaterials(const IFC::IfcRepresentationItem& item, ConversionData& conv);
 136.270 +
 136.271 +// IFCGeometry.cpp
 136.272 +IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut);
 136.273 +bool ProcessRepresentationItem(const IfcRepresentationItem& item, std::vector<unsigned int>& mesh_indices, ConversionData& conv);
 136.274 +void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,ConversionData& /*conv*/);
 136.275 +
 136.276 +void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout, 
 136.277 +						   ConversionData& conv);
 136.278 +
 136.279 +void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result, 
 136.280 +							  ConversionData& conv, bool collect_openings);
 136.281 +
 136.282 +// IFCBoolean.cpp
 136.283 +
 136.284 +void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, ConversionData& conv);
 136.285 +void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result, 
 136.286 +									   const TempMesh& first_operand, 
 136.287 +									   ConversionData& conv);
 136.288 +
 136.289 +void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result, 
 136.290 +													   const TempMesh& first_operand, 
 136.291 +													   ConversionData& conv);
 136.292 +void ProcessBooleanExtrudedAreaSolidDifference(const IfcExtrudedAreaSolid* as, TempMesh& result, 
 136.293 +											   const TempMesh& first_operand, 
 136.294 +											   ConversionData& conv);
 136.295 +
 136.296 +
 136.297 +// IFCOpenings.cpp
 136.298 +
 136.299 +bool GenerateOpenings(std::vector<TempOpening>& openings,
 136.300 +					  const std::vector<IfcVector3>& nors, 
 136.301 +					  TempMesh& curmesh,
 136.302 +					  bool check_intersection,
 136.303 +					  bool generate_connection_geometry,
 136.304 +					  const IfcVector3& wall_extrusion_axis = IfcVector3(0,1,0));
 136.305 +
 136.306 +
 136.307 +
 136.308 +// IFCCurve.cpp
 136.309 +
 136.310 +// ------------------------------------------------------------------------------------------------
 136.311 +// Custom exception for use by members of the Curve class
 136.312 +// ------------------------------------------------------------------------------------------------
 136.313 +class CurveError 
 136.314 +{
 136.315 +public:
 136.316 +	CurveError(const std::string& s)
 136.317 +		: s(s)
 136.318 +	{
 136.319 +	}
 136.320 +
 136.321 +	std::string s;
 136.322 +};
 136.323 +
 136.324 +
 136.325 +// ------------------------------------------------------------------------------------------------
 136.326 +// Temporary representation for an arbitrary sub-class of IfcCurve. Used to sample the curves
 136.327 +// to obtain a list of line segments.
 136.328 +// ------------------------------------------------------------------------------------------------
 136.329 +class Curve
 136.330 +{
 136.331 +protected:
 136.332 +
 136.333 +	Curve(const IfcCurve& base_entity, ConversionData& conv)
 136.334 +		: base_entity(base_entity)
 136.335 +		, conv(conv)
 136.336 +	{}
 136.337 +
 136.338 +public:
 136.339 +
 136.340 +	typedef std::pair<IfcFloat, IfcFloat> ParamRange;
 136.341 +
 136.342 +public:
 136.343 +
 136.344 +
 136.345 +	virtual ~Curve() {}
 136.346 +
 136.347 +
 136.348 +	// check if a curve is closed 
 136.349 +	virtual bool IsClosed() const = 0;
 136.350 +
 136.351 +	// evaluate the curve at the given parametric position
 136.352 +	virtual IfcVector3 Eval(IfcFloat p) const = 0;
 136.353 +
 136.354 +	// try to match a point on the curve to a given parameter
 136.355 +	// for self-intersecting curves, the result is not ambiguous and
 136.356 +	// it is undefined which parameter is returned. 
 136.357 +	virtual bool ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const;
 136.358 +
 136.359 +	// get the range of the curve (both inclusive).
 136.360 +	// +inf and -inf are valid return values, the curve is not bounded in such a case.
 136.361 +	virtual std::pair<IfcFloat,IfcFloat> GetParametricRange() const = 0;
 136.362 +	IfcFloat GetParametricRangeDelta() const;
 136.363 +
 136.364 +	// estimate the number of sample points that this curve will require
 136.365 +	virtual size_t EstimateSampleCount(IfcFloat start,IfcFloat end) const;
 136.366 +
 136.367 +	// intelligently sample the curve based on the current settings
 136.368 +	// and append the result to the mesh
 136.369 +	virtual void SampleDiscrete(TempMesh& out,IfcFloat start,IfcFloat end) const;
 136.370 +
 136.371 +#ifdef _DEBUG
 136.372 +	// check if a particular parameter value lies within the well-defined range
 136.373 +	bool InRange(IfcFloat) const;
 136.374 +#endif 
 136.375 +
 136.376 +public:
 136.377 +
 136.378 +	static Curve* Convert(const IFC::IfcCurve&,ConversionData& conv);
 136.379 +
 136.380 +protected:
 136.381 +
 136.382 +	const IfcCurve& base_entity;
 136.383 +	ConversionData& conv;
 136.384 +};
 136.385 +
 136.386 +
 136.387 +// --------------------------------------------------------------------------------
 136.388 +// A BoundedCurve always holds the invariant that GetParametricRange()
 136.389 +// never returns infinite values.
 136.390 +// --------------------------------------------------------------------------------
 136.391 +class BoundedCurve : public Curve 
 136.392 +{
 136.393 +public:
 136.394 +
 136.395 +	BoundedCurve(const IfcBoundedCurve& entity, ConversionData& conv)
 136.396 +		: Curve(entity,conv)
 136.397 +	{}
 136.398 +
 136.399 +public:
 136.400 +
 136.401 +	bool IsClosed() const;
 136.402 +
 136.403 +public:
 136.404 +
 136.405 +	// sample the entire curve
 136.406 +	void SampleDiscrete(TempMesh& out) const;
 136.407 +	using Curve::SampleDiscrete;
 136.408 +};
 136.409 +
 136.410 +// IfcProfile.cpp
 136.411 +bool ProcessCurve(const IfcCurve& curve,  TempMesh& meshout, ConversionData& conv);
 136.412 +}
 136.413 +}
 136.414 +
 136.415 +#endif 
   137.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   137.2 +++ b/libs/assimp/IFF.h	Sat Feb 01 19:58:19 2014 +0200
   137.3 @@ -0,0 +1,102 @@
   137.4 +
   137.5 +
   137.6 +// Definitions for the Interchange File Format (IFF)
   137.7 +// Alexander Gessler, 2006
   137.8 +// Adapted to Assimp August 2008
   137.9 +
  137.10 +#ifndef AI_IFF_H_INCLUDED
  137.11 +#define AI_IFF_H_INCLUDED
  137.12 +
  137.13 +#include "ByteSwap.h"
  137.14 +
  137.15 +namespace Assimp	{
  137.16 +namespace IFF		{
  137.17 +
  137.18 +#include "assimp/Compiler/pushpack1.h"
  137.19 +
  137.20 +/////////////////////////////////////////////////////////////////////////////////
  137.21 +//! Describes an IFF chunk header
  137.22 +/////////////////////////////////////////////////////////////////////////////////
  137.23 +struct ChunkHeader
  137.24 +{
  137.25 +	//! Type of the chunk header - FourCC
  137.26 +	uint32_t type;
  137.27 +
  137.28 +	//! Length of the chunk data, in bytes
  137.29 +	uint32_t length;
  137.30 +} PACK_STRUCT;
  137.31 +
  137.32 +
  137.33 +/////////////////////////////////////////////////////////////////////////////////
  137.34 +//! Describes an IFF sub chunk header
  137.35 +/////////////////////////////////////////////////////////////////////////////////
  137.36 +struct SubChunkHeader
  137.37 +{
  137.38 +	//! Type of the chunk header - FourCC
  137.39 +	uint32_t type;
  137.40 +
  137.41 +	//! Length of the chunk data, in bytes
  137.42 +	uint16_t length;
  137.43 +} PACK_STRUCT;
  137.44 +
  137.45 +#include "assimp/Compiler/poppack1.h"
  137.46 +
  137.47 +
  137.48 +#define AI_IFF_FOURCC(a,b,c,d) ((uint32_t) (((uint8_t)a << 24u) | \
  137.49 +	((uint8_t)b << 16u) | ((uint8_t)c << 8u) | ((uint8_t)d)))
  137.50 +
  137.51 +
  137.52 +#define AI_IFF_FOURCC_FORM AI_IFF_FOURCC('F','O','R','M')
  137.53 +
  137.54 +
  137.55 +/////////////////////////////////////////////////////////////////////////////////
  137.56 +//! Load a chunk header
  137.57 +//! @param outFile Pointer to the file data - points to the chunk data afterwards
  137.58 +//! @return Pointer to the chunk header
  137.59 +/////////////////////////////////////////////////////////////////////////////////
  137.60 +inline ChunkHeader* LoadChunk(uint8_t*& outFile)
  137.61 +{
  137.62 +	ChunkHeader* head = (ChunkHeader*) outFile;
  137.63 +	AI_LSWAP4(head->length);
  137.64 +	AI_LSWAP4(head->type);
  137.65 +	outFile += sizeof(ChunkHeader);
  137.66 +	return head;
  137.67 +}
  137.68 +
  137.69 +/////////////////////////////////////////////////////////////////////////////////
  137.70 +//! Load a sub chunk header
  137.71 +//! @param outFile Pointer to the file data - points to the chunk data afterwards
  137.72 +//! @return Pointer to the sub chunk header
  137.73 +/////////////////////////////////////////////////////////////////////////////////
  137.74 +inline SubChunkHeader* LoadSubChunk(uint8_t*& outFile)
  137.75 +{
  137.76 +	SubChunkHeader* head = (SubChunkHeader*) outFile;
  137.77 +	AI_LSWAP2(head->length);
  137.78 +	AI_LSWAP4(head->type);
  137.79 +	outFile += sizeof(SubChunkHeader);
  137.80 +	return head;
  137.81 +}
  137.82 +
  137.83 +/////////////////////////////////////////////////////////////////////////////////
  137.84 +//! Read the file header and return the type of the file and its size
  137.85 +//! @param outFile Pointer to the file data. The buffer must at 
  137.86 +//!   least be 12 bytes large.
  137.87 +//! @param fileType Receives the type of the file
  137.88 +//! @return 0 if everything was OK, otherwise an error message
  137.89 +/////////////////////////////////////////////////////////////////////////////////
  137.90 +inline const char* ReadHeader(uint8_t* outFile,uint32_t& fileType) 
  137.91 +{
  137.92 +	ChunkHeader* head = LoadChunk(outFile);
  137.93 +	if(AI_IFF_FOURCC_FORM != head->type)
  137.94 +	{
  137.95 +		return "The file is not an IFF file: FORM chunk is missing";
  137.96 +	}
  137.97 +	fileType = *((uint32_t*)(head+1));
  137.98 +	AI_LSWAP4(fileType);
  137.99 +	return 0;
 137.100 +}
 137.101 +
 137.102 +
 137.103 +}}
 137.104 +
 137.105 +#endif // !! AI_IFF_H_INCLUDED
   138.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   138.2 +++ b/libs/assimp/Importer.cpp	Sat Feb 01 19:58:19 2014 +0200
   138.3 @@ -0,0 +1,1077 @@
   138.4 +/*
   138.5 +---------------------------------------------------------------------------
   138.6 +Open Asset Import Library (assimp)
   138.7 +---------------------------------------------------------------------------
   138.8 +
   138.9 +Copyright (c) 2006-2012, assimp team
  138.10 +
  138.11 +All rights reserved.
  138.12 +
  138.13 +Redistribution and use of this software in source and binary forms, 
  138.14 +with or without modification, are permitted provided that the following 
  138.15 +conditions are met:
  138.16 +
  138.17 +* Redistributions of source code must retain the above
  138.18 +  copyright notice, this list of conditions and the
  138.19 +  following disclaimer.
  138.20 +
  138.21 +* Redistributions in binary form must reproduce the above
  138.22 +  copyright notice, this list of conditions and the
  138.23 +  following disclaimer in the documentation and/or other
  138.24 +  materials provided with the distribution.
  138.25 +
  138.26 +* Neither the name of the assimp team, nor the names of its
  138.27 +  contributors may be used to endorse or promote products
  138.28 +  derived from this software without specific prior
  138.29 +  written permission of the assimp team.
  138.30 +
  138.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  138.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  138.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  138.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  138.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  138.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  138.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  138.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  138.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  138.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  138.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  138.42 +---------------------------------------------------------------------------
  138.43 +*/
  138.44 +
  138.45 +/** @file  Importer.cpp
  138.46 + *  @brief Implementation of the CPP-API class #Importer
  138.47 + */
  138.48 +
  138.49 +#include "AssimpPCH.h"
  138.50 +#include "assimp/version.h"
  138.51 +
  138.52 +// ------------------------------------------------------------------------------------------------
  138.53 +/* Uncomment this line to prevent Assimp from catching unknown exceptions.
  138.54 + *
  138.55 + * Note that any Exception except DeadlyImportError may lead to 
  138.56 + * undefined behaviour -> loaders could remain in an unusable state and
  138.57 + * further imports with the same Importer instance could fail/crash/burn ...
  138.58 + */
  138.59 +// ------------------------------------------------------------------------------------------------
  138.60 +#ifndef ASSIMP_BUILD_DEBUG
  138.61 +#	define ASSIMP_CATCH_GLOBAL_EXCEPTIONS
  138.62 +#endif
  138.63 +
  138.64 +// ------------------------------------------------------------------------------------------------
  138.65 +// Internal headers
  138.66 +// ------------------------------------------------------------------------------------------------
  138.67 +#include "Importer.h"
  138.68 +#include "BaseProcess.h"
  138.69 +
  138.70 +#include "DefaultIOStream.h"
  138.71 +#include "DefaultIOSystem.h"
  138.72 +#include "DefaultProgressHandler.h"
  138.73 +#include "GenericProperty.h"
  138.74 +#include "ProcessHelper.h"
  138.75 +#include "ScenePreprocessor.h"
  138.76 +#include "MemoryIOWrapper.h"
  138.77 +#include "Profiler.h"
  138.78 +#include "TinyFormatter.h"
  138.79 +
  138.80 +#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
  138.81 +#	include "ValidateDataStructure.h"
  138.82 +#endif
  138.83 +
  138.84 +using namespace Assimp::Profiling;
  138.85 +using namespace Assimp::Formatter;
  138.86 +
  138.87 +namespace Assimp {
  138.88 +	// ImporterRegistry.cpp
  138.89 +	void GetImporterInstanceList(std::vector< BaseImporter* >& out);
  138.90 +	// PostStepRegistry.cpp
  138.91 +	void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
  138.92 +}
  138.93 +
  138.94 +using namespace Assimp;
  138.95 +using namespace Assimp::Intern;
  138.96 +
  138.97 +// ------------------------------------------------------------------------------------------------
  138.98 +// Intern::AllocateFromAssimpHeap serves as abstract base class. It overrides
  138.99 +// new and delete (and their array counterparts) of public API classes (e.g. Logger) to
 138.100 +// utilize our DLL heap.
 138.101 +// See http://www.gotw.ca/publications/mill15.htm
 138.102 +// ------------------------------------------------------------------------------------------------
 138.103 +void* AllocateFromAssimpHeap::operator new ( size_t num_bytes)	{
 138.104 +	return ::operator new(num_bytes);
 138.105 +}
 138.106 +
 138.107 +void* AllocateFromAssimpHeap::operator new ( size_t num_bytes, const std::nothrow_t& ) throw()	{
 138.108 +	try	{
 138.109 +		return AllocateFromAssimpHeap::operator new( num_bytes );
 138.110 +	}
 138.111 +	catch( ... )	{
 138.112 +		return NULL;
 138.113 +	}
 138.114 +}
 138.115 +
 138.116 +void AllocateFromAssimpHeap::operator delete ( void* data)	{
 138.117 +	return ::operator delete(data);
 138.118 +}
 138.119 +
 138.120 +void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes)	{
 138.121 +	return ::operator new[](num_bytes);
 138.122 +}
 138.123 +
 138.124 +void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes, const std::nothrow_t& ) throw() {
 138.125 +	try	{
 138.126 +		return AllocateFromAssimpHeap::operator new[]( num_bytes );
 138.127 +	}
 138.128 +	catch( ... )	{
 138.129 +		return NULL;
 138.130 +	}
 138.131 +}
 138.132 +
 138.133 +void AllocateFromAssimpHeap::operator delete[] ( void* data)	{
 138.134 +	return ::operator delete[](data);
 138.135 +}
 138.136 +
 138.137 +// ------------------------------------------------------------------------------------------------
 138.138 +// Importer constructor. 
 138.139 +Importer::Importer() 
 138.140 +{
 138.141 +	// allocate the pimpl first
 138.142 +	pimpl = new ImporterPimpl();
 138.143 +
 138.144 +	pimpl->mScene = NULL;
 138.145 +	pimpl->mErrorString = "";
 138.146 +
 138.147 +	// Allocate a default IO handler
 138.148 +	pimpl->mIOHandler = new DefaultIOSystem;
 138.149 +	pimpl->mIsDefaultHandler = true; 
 138.150 +	pimpl->bExtraVerbose     = false; // disable extra verbose mode by default
 138.151 +
 138.152 +	pimpl->mProgressHandler = new DefaultProgressHandler();
 138.153 +	pimpl->mIsDefaultProgressHandler = true;
 138.154 +
 138.155 +	GetImporterInstanceList(pimpl->mImporter);
 138.156 +	GetPostProcessingStepInstanceList(pimpl->mPostProcessingSteps);
 138.157 +
 138.158 +	// Allocate a SharedPostProcessInfo object and store pointers to it in all post-process steps in the list.
 138.159 +	pimpl->mPPShared = new SharedPostProcessInfo();
 138.160 +	for (std::vector<BaseProcess*>::iterator it =  pimpl->mPostProcessingSteps.begin();
 138.161 +		it != pimpl->mPostProcessingSteps.end(); 
 138.162 +		++it)	{
 138.163 +
 138.164 +		(*it)->SetSharedData(pimpl->mPPShared);
 138.165 +	}
 138.166 +}
 138.167 +
 138.168 +// ------------------------------------------------------------------------------------------------
 138.169 +// Destructor of Importer
 138.170 +Importer::~Importer()
 138.171 +{
 138.172 +	// Delete all import plugins
 138.173 +	for( unsigned int a = 0; a < pimpl->mImporter.size(); a++)
 138.174 +		delete pimpl->mImporter[a];
 138.175 +
 138.176 +	// Delete all post-processing plug-ins
 138.177 +	for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)
 138.178 +		delete pimpl->mPostProcessingSteps[a];
 138.179 +
 138.180 +	// Delete the assigned IO and progress handler
 138.181 +	delete pimpl->mIOHandler;
 138.182 +	delete pimpl->mProgressHandler;
 138.183 +
 138.184 +	// Kill imported scene. Destructors should do that recursivly
 138.185 +	delete pimpl->mScene;
 138.186 +
 138.187 +	// Delete shared post-processing data
 138.188 +	delete pimpl->mPPShared;
 138.189 +
 138.190 +	// and finally the pimpl itself
 138.191 +	delete pimpl;
 138.192 +}
 138.193 +
 138.194 +// ------------------------------------------------------------------------------------------------
 138.195 +// Copy constructor - copies the config of another Importer, not the scene
 138.196 +Importer::Importer(const Importer &other)
 138.197 +{
 138.198 +	new(this) Importer();
 138.199 +
 138.200 +	pimpl->mIntProperties    = other.pimpl->mIntProperties;
 138.201 +	pimpl->mFloatProperties  = other.pimpl->mFloatProperties;
 138.202 +	pimpl->mStringProperties = other.pimpl->mStringProperties;
 138.203 +}
 138.204 +
 138.205 +// ------------------------------------------------------------------------------------------------
 138.206 +// Register a custom post-processing step
 138.207 +aiReturn Importer::RegisterPPStep(BaseProcess* pImp)
 138.208 +{
 138.209 +	ai_assert(NULL != pImp);
 138.210 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.211 +
 138.212 +		pimpl->mPostProcessingSteps.push_back(pImp);
 138.213 +		DefaultLogger::get()->info("Registering custom post-processing step");
 138.214 +	
 138.215 +	ASSIMP_END_EXCEPTION_REGION(aiReturn);
 138.216 +	return AI_SUCCESS;
 138.217 +}
 138.218 +
 138.219 +// ------------------------------------------------------------------------------------------------
 138.220 +// Register a custom loader plugin
 138.221 +aiReturn Importer::RegisterLoader(BaseImporter* pImp)
 138.222 +{
 138.223 +	ai_assert(NULL != pImp);
 138.224 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.225 +
 138.226 +	// --------------------------------------------------------------------
 138.227 +	// Check whether we would have two loaders for the same file extension 
 138.228 +	// This is absolutely OK, but we should warn the developer of the new
 138.229 +	// loader that his code will probably never be called if the first 
 138.230 +	// loader is a bit too lazy in his file checking.
 138.231 +	// --------------------------------------------------------------------
 138.232 +	std::set<std::string> st;
 138.233 +	std::string baked;
 138.234 +	pImp->GetExtensionList(st);
 138.235 +
 138.236 +	for(std::set<std::string>::const_iterator it = st.begin(); it != st.end(); ++it) {
 138.237 +
 138.238 +#ifdef _DEBUG
 138.239 +		if (IsExtensionSupported(*it)) {
 138.240 +			DefaultLogger::get()->warn("The file extension " + *it + " is already in use");
 138.241 +		}
 138.242 +#endif
 138.243 +		baked += *it;
 138.244 +	}
 138.245 +
 138.246 +	// add the loader
 138.247 +	pimpl->mImporter.push_back(pImp);
 138.248 +	DefaultLogger::get()->info("Registering custom importer for these file extensions: " + baked);
 138.249 +	ASSIMP_END_EXCEPTION_REGION(aiReturn);
 138.250 +	return AI_SUCCESS;
 138.251 +}
 138.252 +
 138.253 +// ------------------------------------------------------------------------------------------------
 138.254 +// Unregister a custom loader plugin
 138.255 +aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
 138.256 +{
 138.257 +	if(!pImp) {
 138.258 +		// unregistering a NULL importer is no problem for us ... really!
 138.259 +		return AI_SUCCESS;
 138.260 +	}
 138.261 +
 138.262 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.263 +	std::vector<BaseImporter*>::iterator it = std::find(pimpl->mImporter.begin(),
 138.264 +		pimpl->mImporter.end(),pImp);
 138.265 +
 138.266 +	if (it != pimpl->mImporter.end())	{
 138.267 +		pimpl->mImporter.erase(it);
 138.268 +
 138.269 +		std::set<std::string> st;
 138.270 +		pImp->GetExtensionList(st);
 138.271 +
 138.272 +		DefaultLogger::get()->info("Unregistering custom importer: ");
 138.273 +		return AI_SUCCESS;
 138.274 +	}
 138.275 +	DefaultLogger::get()->warn("Unable to remove custom importer: I can't find you ...");
 138.276 +	ASSIMP_END_EXCEPTION_REGION(aiReturn);
 138.277 +	return AI_FAILURE;
 138.278 +}
 138.279 +
 138.280 +// ------------------------------------------------------------------------------------------------
 138.281 +// Unregister a custom loader plugin
 138.282 +aiReturn Importer::UnregisterPPStep(BaseProcess* pImp)
 138.283 +{
 138.284 +	if(!pImp) {
 138.285 +		// unregistering a NULL ppstep is no problem for us ... really!
 138.286 +		return AI_SUCCESS;
 138.287 +	}
 138.288 +
 138.289 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.290 +	std::vector<BaseProcess*>::iterator it = std::find(pimpl->mPostProcessingSteps.begin(),
 138.291 +		pimpl->mPostProcessingSteps.end(),pImp);
 138.292 +
 138.293 +	if (it != pimpl->mPostProcessingSteps.end())	{
 138.294 +		pimpl->mPostProcessingSteps.erase(it);
 138.295 +		DefaultLogger::get()->info("Unregistering custom post-processing step");
 138.296 +		return AI_SUCCESS;
 138.297 +	}
 138.298 +	DefaultLogger::get()->warn("Unable to remove custom post-processing step: I can't find you ..");
 138.299 +	ASSIMP_END_EXCEPTION_REGION(aiReturn);
 138.300 +	return AI_FAILURE;
 138.301 +}
 138.302 +
 138.303 +// ------------------------------------------------------------------------------------------------
 138.304 +// Supplies a custom IO handler to the importer to open and access files.
 138.305 +void Importer::SetIOHandler( IOSystem* pIOHandler)
 138.306 +{
 138.307 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.308 +	// If the new handler is zero, allocate a default IO implementation.
 138.309 +	if (!pIOHandler)
 138.310 +	{
 138.311 +		// Release pointer in the possession of the caller
 138.312 +		pimpl->mIOHandler = new DefaultIOSystem();
 138.313 +		pimpl->mIsDefaultHandler = true;
 138.314 +	}
 138.315 +	// Otherwise register the custom handler
 138.316 +	else if (pimpl->mIOHandler != pIOHandler)
 138.317 +	{
 138.318 +		delete pimpl->mIOHandler;
 138.319 +		pimpl->mIOHandler = pIOHandler;
 138.320 +		pimpl->mIsDefaultHandler = false;
 138.321 +	}
 138.322 +	ASSIMP_END_EXCEPTION_REGION(void);
 138.323 +}
 138.324 +
 138.325 +// ------------------------------------------------------------------------------------------------
 138.326 +// Get the currently set IO handler
 138.327 +IOSystem* Importer::GetIOHandler() const
 138.328 +{
 138.329 +	return pimpl->mIOHandler;
 138.330 +}
 138.331 +
 138.332 +// ------------------------------------------------------------------------------------------------
 138.333 +// Check whether a custom IO handler is currently set
 138.334 +bool Importer::IsDefaultIOHandler() const
 138.335 +{
 138.336 +	return pimpl->mIsDefaultHandler;
 138.337 +}
 138.338 +
 138.339 +// ------------------------------------------------------------------------------------------------
 138.340 +// Supplies a custom progress handler to get regular callbacks during importing
 138.341 +void Importer::SetProgressHandler ( ProgressHandler* pHandler )
 138.342 +{
 138.343 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.344 +	// If the new handler is zero, allocate a default implementation.
 138.345 +	if (!pHandler)
 138.346 +	{
 138.347 +		// Release pointer in the possession of the caller
 138.348 +		pimpl->mProgressHandler = new DefaultProgressHandler();
 138.349 +		pimpl->mIsDefaultProgressHandler = true;
 138.350 +	}
 138.351 +	// Otherwise register the custom handler
 138.352 +	else if (pimpl->mProgressHandler != pHandler)
 138.353 +	{
 138.354 +		delete pimpl->mProgressHandler;
 138.355 +		pimpl->mProgressHandler = pHandler;
 138.356 +		pimpl->mIsDefaultProgressHandler = false;
 138.357 +	}
 138.358 +	ASSIMP_END_EXCEPTION_REGION(void);
 138.359 +}
 138.360 +
 138.361 +// ------------------------------------------------------------------------------------------------
 138.362 +// Get the currently set progress handler
 138.363 +ProgressHandler* Importer::GetProgressHandler() const
 138.364 +{
 138.365 +	return pimpl->mProgressHandler;
 138.366 +}
 138.367 +
 138.368 +// ------------------------------------------------------------------------------------------------
 138.369 +// Check whether a custom progress handler is currently set
 138.370 +bool Importer::IsDefaultProgressHandler() const
 138.371 +{
 138.372 +	return pimpl->mIsDefaultProgressHandler;
 138.373 +}
 138.374 +
 138.375 +// ------------------------------------------------------------------------------------------------
 138.376 +// Validate post process step flags 
 138.377 +bool _ValidateFlags(unsigned int pFlags) 
 138.378 +{
 138.379 +	if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals)	{
 138.380 +		DefaultLogger::get()->error("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible");
 138.381 +		return false;
 138.382 +	}
 138.383 +	if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices)	{
 138.384 +		DefaultLogger::get()->error("#aiProcess_OptimizeGraph and #aiProcess_PreTransformVertices are incompatible");
 138.385 +		return false;
 138.386 +	}
 138.387 +	return true;
 138.388 +}
 138.389 +
 138.390 +// ------------------------------------------------------------------------------------------------
 138.391 +// Free the current scene
 138.392 +void Importer::FreeScene( )
 138.393 +{
 138.394 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.395 +	delete pimpl->mScene;
 138.396 +	pimpl->mScene = NULL;
 138.397 +
 138.398 +	pimpl->mErrorString = "";
 138.399 +	ASSIMP_END_EXCEPTION_REGION(void);
 138.400 +}
 138.401 +
 138.402 +// ------------------------------------------------------------------------------------------------
 138.403 +// Get the current error string, if any
 138.404 +const char* Importer::GetErrorString() const 
 138.405 +{ 
 138.406 +	 /* Must remain valid as long as ReadFile() or FreeFile() are not called */
 138.407 +	return pimpl->mErrorString.c_str();
 138.408 +}
 138.409 +
 138.410 +// ------------------------------------------------------------------------------------------------
 138.411 +// Enable extra-verbose mode
 138.412 +void Importer::SetExtraVerbose(bool bDo)
 138.413 +{
 138.414 +	pimpl->bExtraVerbose = bDo;
 138.415 +}
 138.416 +
 138.417 +// ------------------------------------------------------------------------------------------------
 138.418 +// Get the current scene
 138.419 +const aiScene* Importer::GetScene() const
 138.420 +{
 138.421 +	return pimpl->mScene;
 138.422 +}
 138.423 +
 138.424 +// ------------------------------------------------------------------------------------------------
 138.425 +// Orphan the current scene and return it.
 138.426 +aiScene* Importer::GetOrphanedScene()
 138.427 +{
 138.428 +	aiScene* s = pimpl->mScene;
 138.429 +
 138.430 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.431 +	pimpl->mScene = NULL;
 138.432 +
 138.433 +	pimpl->mErrorString = ""; /* reset error string */
 138.434 +	ASSIMP_END_EXCEPTION_REGION(aiScene*);
 138.435 +	return s;
 138.436 +}
 138.437 +
 138.438 +// ------------------------------------------------------------------------------------------------
 138.439 +// Validate post-processing flags
 138.440 +bool Importer::ValidateFlags(unsigned int pFlags) const
 138.441 +{
 138.442 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.443 +	// run basic checks for mutually exclusive flags
 138.444 +	if(!_ValidateFlags(pFlags)) {
 138.445 +		return false;
 138.446 +	}
 138.447 +
 138.448 +	// ValidateDS does not anymore occur in the pp list, it plays an awesome extra role ...
 138.449 +#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
 138.450 +	if (pFlags & aiProcess_ValidateDataStructure) {
 138.451 +		return false;
 138.452 +	}
 138.453 +#endif
 138.454 +	pFlags &= ~aiProcess_ValidateDataStructure;
 138.455 +
 138.456 +	// Now iterate through all bits which are set in the flags and check whether we find at least
 138.457 +	// one pp plugin which handles it.
 138.458 +	for (unsigned int mask = 1; mask < (1u << (sizeof(unsigned int)*8-1));mask <<= 1) {
 138.459 +		
 138.460 +		if (pFlags & mask) {
 138.461 +		
 138.462 +			bool have = false;
 138.463 +			for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)	{
 138.464 +				if (pimpl->mPostProcessingSteps[a]-> IsActive(mask) ) {
 138.465 +				
 138.466 +					have = true;
 138.467 +					break;
 138.468 +				}
 138.469 +			}
 138.470 +			if (!have) {
 138.471 +				return false;
 138.472 +			}
 138.473 +		}
 138.474 +	}
 138.475 +	ASSIMP_END_EXCEPTION_REGION(bool);
 138.476 +	return true;
 138.477 +}
 138.478 +
 138.479 +// ------------------------------------------------------------------------------------------------
 138.480 +const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
 138.481 +	size_t pLength,
 138.482 +	unsigned int pFlags,
 138.483 +	const char* pHint /*= ""*/)
 138.484 +{
 138.485 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.486 +	if (!pHint) {
 138.487 +		pHint = "";
 138.488 +	}
 138.489 +
 138.490 +	if (!pBuffer || !pLength || strlen(pHint) > 100) {
 138.491 +		pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()";
 138.492 +		return NULL;
 138.493 +	}
 138.494 +
 138.495 +	// prevent deletion of the previous IOHandler
 138.496 +	IOSystem* io = pimpl->mIOHandler;
 138.497 +	pimpl->mIOHandler = NULL;
 138.498 +
 138.499 +	SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength));
 138.500 +
 138.501 +	// read the file and recover the previous IOSystem
 138.502 +	char fbuff[128];
 138.503 +	sprintf(fbuff,"%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
 138.504 +
 138.505 +	ReadFile(fbuff,pFlags);
 138.506 +	SetIOHandler(io);
 138.507 +
 138.508 +	ASSIMP_END_EXCEPTION_REGION(const aiScene*);
 138.509 +	return pimpl->mScene;
 138.510 +}
 138.511 +
 138.512 +// ------------------------------------------------------------------------------------------------
 138.513 +void WriteLogOpening(const std::string& file)
 138.514 +{
 138.515 +	Logger* l = DefaultLogger::get();
 138.516 +	if (!l) {
 138.517 +		return;
 138.518 +	}
 138.519 +	l->info("Load " + file);
 138.520 +
 138.521 +	// print a full version dump. This is nice because we don't
 138.522 +	// need to ask the authors of incoming bug reports for
 138.523 +	// the library version they're using - a log dump is
 138.524 +	// sufficient.
 138.525 +	const unsigned int flags = aiGetCompileFlags();
 138.526 +	l->debug(format()
 138.527 +		<< "Assimp "
 138.528 +		<< aiGetVersionMajor() 
 138.529 +		<< "." 
 138.530 +		<< aiGetVersionMinor() 
 138.531 +		<< "." 
 138.532 +		<< aiGetVersionRevision()
 138.533 +
 138.534 +		<< " "
 138.535 +#if defined(ASSIMP_BUILD_ARCHITECTURE)
 138.536 +		<< ASSIMP_BUILD_ARCHITECTURE
 138.537 +#elif defined(_M_IX86) || defined(__x86_32__) || defined(__i386__)
 138.538 +		<< "x86"
 138.539 +#elif defined(_M_X64) || defined(__x86_64__) 
 138.540 +		<< "amd64"
 138.541 +#elif defined(_M_IA64) || defined(__ia64__)
 138.542 +		<< "itanium"
 138.543 +#elif defined(__ppc__) || defined(__powerpc__)
 138.544 +		<< "ppc32"
 138.545 +#elif defined(__powerpc64__)
 138.546 +		<< "ppc64"
 138.547 +#elif defined(__arm__)
 138.548 +		<< "arm"
 138.549 +#else
 138.550 +	<< "<unknown architecture>"
 138.551 +#endif
 138.552 +
 138.553 +		<< " "
 138.554 +#if defined(ASSIMP_BUILD_COMPILER)
 138.555 +		<< ASSIMP_BUILD_COMPILER
 138.556 +#elif defined(_MSC_VER)
 138.557 +		<< "msvc"
 138.558 +#elif defined(__GNUC__)
 138.559 +		<< "gcc"
 138.560 +#else
 138.561 +		<< "<unknown compiler>"
 138.562 +#endif
 138.563 +
 138.564 +#ifndef NDEBUG
 138.565 +		<< " debug"
 138.566 +#endif
 138.567 +
 138.568 +		<< (flags & ASSIMP_CFLAGS_NOBOOST ? " noboost" : "")
 138.569 +		<< (flags & ASSIMP_CFLAGS_SHARED  ? " shared" : "")
 138.570 +		<< (flags & ASSIMP_CFLAGS_SINGLETHREADED  ? " singlethreaded" : "")
 138.571 +		);
 138.572 +}
 138.573 +
 138.574 +// ------------------------------------------------------------------------------------------------
 138.575 +// Reads the given file and returns its contents if successful.
 138.576 +const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
 138.577 +{
 138.578 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.579 +	const std::string pFile(_pFile);
 138.580 +
 138.581 +	// ----------------------------------------------------------------------
 138.582 +	// Put a large try block around everything to catch all std::exception's
 138.583 +	// that might be thrown by STL containers or by new(). 
 138.584 +	// ImportErrorException's are throw by ourselves and caught elsewhere.
 138.585 +	//-----------------------------------------------------------------------
 138.586 +
 138.587 +	WriteLogOpening(pFile);
 138.588 +
 138.589 +#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS
 138.590 +	try
 138.591 +#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
 138.592 +	{
 138.593 +		// Check whether this Importer instance has already loaded
 138.594 +		// a scene. In this case we need to delete the old one
 138.595 +		if (pimpl->mScene)	{
 138.596 +
 138.597 +			DefaultLogger::get()->debug("(Deleting previous scene)");
 138.598 +			FreeScene();
 138.599 +		}
 138.600 +
 138.601 +		// First check if the file is accessable at all
 138.602 +		if( !pimpl->mIOHandler->Exists( pFile))	{
 138.603 +
 138.604 +			pimpl->mErrorString = "Unable to open file \"" + pFile + "\".";
 138.605 +			DefaultLogger::get()->error(pimpl->mErrorString);
 138.606 +			return NULL;
 138.607 +		}
 138.608 +
 138.609 +		boost::scoped_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL);
 138.610 +		if (profiler) {
 138.611 +			profiler->BeginRegion("total");
 138.612 +		}
 138.613 +
 138.614 +		// Find an worker class which can handle the file
 138.615 +		BaseImporter* imp = NULL;
 138.616 +		for( unsigned int a = 0; a < pimpl->mImporter.size(); a++)	{
 138.617 +
 138.618 +			if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {
 138.619 +				imp = pimpl->mImporter[a];
 138.620 +				break;
 138.621 +			}
 138.622 +		}
 138.623 +
 138.624 +		if (!imp)	{
 138.625 +			// not so bad yet ... try format auto detection.
 138.626 +			const std::string::size_type s = pFile.find_last_of('.');
 138.627 +			if (s != std::string::npos) {
 138.628 +				DefaultLogger::get()->info("File extension not known, trying signature-based detection");
 138.629 +				for( unsigned int a = 0; a < pimpl->mImporter.size(); a++)	{
 138.630 +
 138.631 +					if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
 138.632 +						imp = pimpl->mImporter[a];
 138.633 +						break;
 138.634 +					}
 138.635 +				}
 138.636 +			}
 138.637 +			// Put a proper error message if no suitable importer was found
 138.638 +			if( !imp)	{
 138.639 +				pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\".";
 138.640 +				DefaultLogger::get()->error(pimpl->mErrorString);
 138.641 +				return NULL;
 138.642 +			}
 138.643 +		}
 138.644 +
 138.645 +		// Dispatch the reading to the worker class for this format
 138.646 +		DefaultLogger::get()->info("Found a matching importer for this file format");
 138.647 +		pimpl->mProgressHandler->Update();
 138.648 +
 138.649 +		if (profiler) {
 138.650 +			profiler->BeginRegion("import");
 138.651 +		}
 138.652 +
 138.653 +		pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler);
 138.654 +		pimpl->mProgressHandler->Update();
 138.655 +
 138.656 +		if (profiler) {
 138.657 +			profiler->EndRegion("import");
 138.658 +		}
 138.659 +
 138.660 +		// If successful, apply all active post processing steps to the imported data
 138.661 +		if( pimpl->mScene)	{
 138.662 +
 138.663 +#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
 138.664 +			// The ValidateDS process is an exception. It is executed first, even before ScenePreprocessor is called.
 138.665 +			if (pFlags & aiProcess_ValidateDataStructure)
 138.666 +			{
 138.667 +				ValidateDSProcess ds;
 138.668 +				ds.ExecuteOnScene (this);
 138.669 +				if (!pimpl->mScene) {
 138.670 +					return NULL;
 138.671 +				}
 138.672 +			}
 138.673 +#endif // no validation
 138.674 +
 138.675 +			// Preprocess the scene and prepare it for post-processing 
 138.676 +			if (profiler) {
 138.677 +				profiler->BeginRegion("preprocess");
 138.678 +			}
 138.679 +
 138.680 +			ScenePreprocessor pre(pimpl->mScene);
 138.681 +			pre.ProcessScene();
 138.682 +
 138.683 +			pimpl->mProgressHandler->Update();
 138.684 +			if (profiler) {
 138.685 +				profiler->EndRegion("preprocess");
 138.686 +			}
 138.687 +
 138.688 +			// Ensure that the validation process won't be called twice
 138.689 +			ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure));
 138.690 +		}
 138.691 +		// if failed, extract the error string
 138.692 +		else if( !pimpl->mScene) {
 138.693 +			pimpl->mErrorString = imp->GetErrorText();
 138.694 +		}
 138.695 +
 138.696 +		// clear any data allocated by post-process steps
 138.697 +		pimpl->mPPShared->Clean();
 138.698 +
 138.699 +		if (profiler) {
 138.700 +			profiler->EndRegion("total");
 138.701 +		}
 138.702 +	}
 138.703 +#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS
 138.704 +	catch (std::exception &e)
 138.705 +	{
 138.706 +#if (defined _MSC_VER) &&	(defined _CPPRTTI) 
 138.707 +		// if we have RTTI get the full name of the exception that occured
 138.708 +		pimpl->mErrorString = std::string(typeid( e ).name()) + ": " + e.what();
 138.709 +#else
 138.710 +		pimpl->mErrorString = std::string("std::exception: ") + e.what();
 138.711 +#endif
 138.712 +
 138.713 +		DefaultLogger::get()->error(pimpl->mErrorString);
 138.714 +		delete pimpl->mScene; pimpl->mScene = NULL;
 138.715 +	}
 138.716 +#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
 138.717 +
 138.718 +	// either successful or failure - the pointer expresses it anyways
 138.719 +	ASSIMP_END_EXCEPTION_REGION(const aiScene*);
 138.720 +	return pimpl->mScene;
 138.721 +}
 138.722 +
 138.723 +
 138.724 +// ------------------------------------------------------------------------------------------------
 138.725 +// Apply post-processing to the currently bound scene
 138.726 +const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
 138.727 +{
 138.728 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.729 +	// Return immediately if no scene is active
 138.730 +	if (!pimpl->mScene) {
 138.731 +		return NULL;
 138.732 +	}
 138.733 +
 138.734 +	// If no flags are given, return the current scene with no further action
 138.735 +	if (!pFlags) {
 138.736 +		return pimpl->mScene;
 138.737 +	}
 138.738 +
 138.739 +	// In debug builds: run basic flag validation
 138.740 +	ai_assert(_ValidateFlags(pFlags));
 138.741 +	DefaultLogger::get()->info("Entering post processing pipeline");
 138.742 +
 138.743 +#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
 138.744 +	// The ValidateDS process plays an exceptional role. It isn't contained in the global
 138.745 +	// list of post-processing steps, so we need to call it manually.
 138.746 +	if (pFlags & aiProcess_ValidateDataStructure)
 138.747 +	{
 138.748 +		ValidateDSProcess ds;
 138.749 +		ds.ExecuteOnScene (this);
 138.750 +		if (!pimpl->mScene) {
 138.751 +			return NULL;
 138.752 +		}
 138.753 +	}
 138.754 +#endif // no validation
 138.755 +#ifdef _DEBUG
 138.756 +	if (pimpl->bExtraVerbose)
 138.757 +	{
 138.758 +#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
 138.759 +		DefaultLogger::get()->error("Verbose Import is not available due to build settings");
 138.760 +#endif  // no validation
 138.761 +		pFlags |= aiProcess_ValidateDataStructure;
 138.762 +	}
 138.763 +#else
 138.764 +	if (pimpl->bExtraVerbose) {
 138.765 +		DefaultLogger::get()->warn("Not a debug build, ignoring extra verbose setting");
 138.766 +	}
 138.767 +#endif // ! DEBUG
 138.768 +
 138.769 +	boost::scoped_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL);
 138.770 +	for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)	{
 138.771 +
 138.772 +		BaseProcess* process = pimpl->mPostProcessingSteps[a];
 138.773 +		if( process->IsActive( pFlags))	{
 138.774 +
 138.775 +			if (profiler) {
 138.776 +				profiler->BeginRegion("postprocess");
 138.777 +			}
 138.778 +
 138.779 +			process->ExecuteOnScene	( this );
 138.780 +			pimpl->mProgressHandler->Update();
 138.781 +
 138.782 +			if (profiler) {
 138.783 +				profiler->EndRegion("postprocess");
 138.784 +			}
 138.785 +		}
 138.786 +		if( !pimpl->mScene) {
 138.787 +			break; 
 138.788 +		}
 138.789 +#ifdef _DEBUG
 138.790 +
 138.791 +#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
 138.792 +		continue;
 138.793 +#endif  // no validation
 138.794 +
 138.795 +		// If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step
 138.796 +		if (pimpl->bExtraVerbose)	{
 138.797 +			DefaultLogger::get()->debug("Verbose Import: revalidating data structures");
 138.798 +
 138.799 +			ValidateDSProcess ds; 
 138.800 +			ds.ExecuteOnScene (this);
 138.801 +			if( !pimpl->mScene)	{
 138.802 +				DefaultLogger::get()->error("Verbose Import: failed to revalidate data structures");
 138.803 +				break; 
 138.804 +			}
 138.805 +		}
 138.806 +#endif // ! DEBUG
 138.807 +	}
 138.808 +
 138.809 +	// update private scene flags
 138.810 +  if( pimpl->mScene )
 138.811 +  	ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags;
 138.812 +
 138.813 +	// clear any data allocated by post-process steps
 138.814 +	pimpl->mPPShared->Clean();
 138.815 +	DefaultLogger::get()->info("Leaving post processing pipeline");
 138.816 +
 138.817 +	ASSIMP_END_EXCEPTION_REGION(const aiScene*);
 138.818 +	return pimpl->mScene;
 138.819 +}
 138.820 +
 138.821 +// ------------------------------------------------------------------------------------------------
 138.822 +// Helper function to check whether an extension is supported by ASSIMP
 138.823 +bool Importer::IsExtensionSupported(const char* szExtension) const
 138.824 +{
 138.825 +	return NULL != GetImporter(szExtension);
 138.826 +}
 138.827 +
 138.828 +// ------------------------------------------------------------------------------------------------
 138.829 +size_t Importer::GetImporterCount() const
 138.830 +{
 138.831 +	return pimpl->mImporter.size();
 138.832 +}
 138.833 +
 138.834 +// ------------------------------------------------------------------------------------------------
 138.835 +const aiImporterDesc* Importer::GetImporterInfo(size_t index) const
 138.836 +{
 138.837 +	if (index >= pimpl->mImporter.size()) {
 138.838 +		return NULL;
 138.839 +	}
 138.840 +	return pimpl->mImporter[index]->GetInfo();
 138.841 +}
 138.842 +
 138.843 +
 138.844 +// ------------------------------------------------------------------------------------------------
 138.845 +BaseImporter* Importer::GetImporter (size_t index) const
 138.846 +{
 138.847 +	if (index >= pimpl->mImporter.size()) {
 138.848 +		return NULL;
 138.849 +	}
 138.850 +	return pimpl->mImporter[index];
 138.851 +}
 138.852 +
 138.853 +// ------------------------------------------------------------------------------------------------
 138.854 +// Find a loader plugin for a given file extension
 138.855 +BaseImporter* Importer::GetImporter (const char* szExtension) const
 138.856 +{
 138.857 +	return GetImporter(GetImporterIndex(szExtension));
 138.858 +}
 138.859 +
 138.860 +// ------------------------------------------------------------------------------------------------
 138.861 +// Find a loader plugin for a given file extension
 138.862 +size_t Importer::GetImporterIndex (const char* szExtension) const
 138.863 +{
 138.864 +	ai_assert(szExtension);
 138.865 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.866 +
 138.867 +	// skip over wildcard and dot characters at string head --
 138.868 +	for(;*szExtension == '*' || *szExtension == '.'; ++szExtension);
 138.869 +
 138.870 +	std::string ext(szExtension);
 138.871 +	if (ext.empty()) {
 138.872 +		return static_cast<size_t>(-1);
 138.873 +	}
 138.874 +	std::transform(ext.begin(),ext.end(), ext.begin(), tolower);
 138.875 +
 138.876 +	std::set<std::string> str;
 138.877 +	for (std::vector<BaseImporter*>::const_iterator i =  pimpl->mImporter.begin();i != pimpl->mImporter.end();++i)	{
 138.878 +		str.clear();
 138.879 +
 138.880 +		(*i)->GetExtensionList(str);
 138.881 +		for (std::set<std::string>::const_iterator it = str.begin(); it != str.end(); ++it) {
 138.882 +			if (ext == *it) {
 138.883 +				return std::distance(static_cast< std::vector<BaseImporter*>::const_iterator >(pimpl->mImporter.begin()), i);
 138.884 +			}
 138.885 +		}
 138.886 +	}
 138.887 +	ASSIMP_END_EXCEPTION_REGION(size_t);
 138.888 +	return static_cast<size_t>(-1);
 138.889 +}
 138.890 +
 138.891 +// ------------------------------------------------------------------------------------------------
 138.892 +// Helper function to build a list of all file extensions supported by ASSIMP
 138.893 +void Importer::GetExtensionList(aiString& szOut) const
 138.894 +{
 138.895 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.896 +	std::set<std::string> str;
 138.897 +	for (std::vector<BaseImporter*>::const_iterator i =  pimpl->mImporter.begin();i != pimpl->mImporter.end();++i)	{
 138.898 +		(*i)->GetExtensionList(str);
 138.899 +	}
 138.900 +
 138.901 +	for (std::set<std::string>::const_iterator it = str.begin();; ) {
 138.902 +		szOut.Append("*.");
 138.903 +		szOut.Append((*it).c_str());
 138.904 +
 138.905 +		if (++it == str.end()) {
 138.906 +			break;
 138.907 +		}
 138.908 +		szOut.Append(";");
 138.909 +	}
 138.910 +	ASSIMP_END_EXCEPTION_REGION(void);
 138.911 +}
 138.912 +
 138.913 +// ------------------------------------------------------------------------------------------------
 138.914 +// Set a configuration property
 138.915 +void Importer::SetPropertyInteger(const char* szName, int iValue, 
 138.916 +	bool* bWasExisting /*= NULL*/)
 138.917 +{
 138.918 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.919 +		SetGenericProperty<int>(pimpl->mIntProperties, szName,iValue,bWasExisting);	
 138.920 +	ASSIMP_END_EXCEPTION_REGION(void);
 138.921 +}
 138.922 +
 138.923 +// ------------------------------------------------------------------------------------------------
 138.924 +// Set a configuration property
 138.925 +void Importer::SetPropertyFloat(const char* szName, float iValue, 
 138.926 +	bool* bWasExisting /*= NULL*/)
 138.927 +{
 138.928 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.929 +		SetGenericProperty<float>(pimpl->mFloatProperties, szName,iValue,bWasExisting);	
 138.930 +	ASSIMP_END_EXCEPTION_REGION(void);
 138.931 +}
 138.932 +
 138.933 +// ------------------------------------------------------------------------------------------------
 138.934 +// Set a configuration property
 138.935 +void Importer::SetPropertyString(const char* szName, const std::string& value, 
 138.936 +	bool* bWasExisting /*= NULL*/)
 138.937 +{
 138.938 +	ASSIMP_BEGIN_EXCEPTION_REGION();
 138.939 +		SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value,bWasExisting);	
 138.940 +	ASSIMP_END_EXCEPTION_REGION(void);
 138.941 +}
 138.942 +
 138.943 +// ------------------------------------------------------------------------------------------------
 138.944 +// Get a configuration property
 138.945 +int Importer::GetPropertyInteger(const char* szName, 
 138.946 +	int iErrorReturn /*= 0xffffffff*/) const
 138.947 +{
 138.948 +	return GetGenericProperty<int>(pimpl->mIntProperties,szName,iErrorReturn);
 138.949 +}
 138.950 +
 138.951 +// ------------------------------------------------------------------------------------------------
 138.952 +// Get a configuration property
 138.953 +float Importer::GetPropertyFloat(const char* szName, 
 138.954 +	float iErrorReturn /*= 10e10*/) const
 138.955 +{
 138.956 +	return GetGenericProperty<float>(pimpl->mFloatProperties,szName,iErrorReturn);
 138.957 +}
 138.958 +
 138.959 +// ------------------------------------------------------------------------------------------------
 138.960 +// Get a configuration property
 138.961 +const std::string& Importer::GetPropertyString(const char* szName, 
 138.962 +	const std::string& iErrorReturn /*= ""*/) const
 138.963 +{
 138.964 +	return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn);
 138.965 +}
 138.966 +
 138.967 +// ------------------------------------------------------------------------------------------------
 138.968 +// Get the memory requirements of a single node
 138.969 +inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode)
 138.970 +{
 138.971 +	iScene += sizeof(aiNode);
 138.972 +	iScene += sizeof(unsigned int) * pcNode->mNumMeshes;
 138.973 +	iScene += sizeof(void*) * pcNode->mNumChildren;
 138.974 +	
 138.975 +	for (unsigned int i = 0; i < pcNode->mNumChildren;++i) {
 138.976 +		AddNodeWeight(iScene,pcNode->mChildren[i]);
 138.977 +	}
 138.978 +}
 138.979 +
 138.980 +// ------------------------------------------------------------------------------------------------
 138.981 +// Get the memory requirements of the scene
 138.982 +void Importer::GetMemoryRequirements(aiMemoryInfo& in) const
 138.983 +{
 138.984 +	in = aiMemoryInfo();
 138.985 +	aiScene* mScene = pimpl->mScene;
 138.986 +
 138.987 +	// return if we have no scene loaded
 138.988 +	if (!pimpl->mScene)
 138.989 +		return;
 138.990 +
 138.991 +
 138.992 +	in.total = sizeof(aiScene);
 138.993 +
 138.994 +	// add all meshes
 138.995 +	for (unsigned int i = 0; i < mScene->mNumMeshes;++i)
 138.996 +	{
 138.997 +		in.meshes += sizeof(aiMesh);
 138.998 +		if (mScene->mMeshes[i]->HasPositions()) {
 138.999 +			in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
138.1000 +		}
138.1001 +
138.1002 +		if (mScene->mMeshes[i]->HasNormals()) {
138.1003 +			in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
138.1004 +		}
138.1005 +
138.1006 +		if (mScene->mMeshes[i]->HasTangentsAndBitangents()) {
138.1007 +			in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices * 2;
138.1008 +		}
138.1009 +
138.1010 +		for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a) {
138.1011 +			if (mScene->mMeshes[i]->HasVertexColors(a)) {
138.1012 +				in.meshes += sizeof(aiColor4D) * mScene->mMeshes[i]->mNumVertices;
138.1013 +			}
138.1014 +			else break;
138.1015 +		}
138.1016 +		for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) {
138.1017 +			if (mScene->mMeshes[i]->HasTextureCoords(a)) {
138.1018 +				in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
138.1019 +			}
138.1020 +			else break;
138.1021 +		}
138.1022 +		if (mScene->mMeshes[i]->HasBones()) {
138.1023 +			in.meshes += sizeof(void*) * mScene->mMeshes[i]->mNumBones;
138.1024 +			for (unsigned int p = 0; p < mScene->mMeshes[i]->mNumBones;++p) {
138.1025 +				in.meshes += sizeof(aiBone);
138.1026 +				in.meshes += mScene->mMeshes[i]->mBones[p]->mNumWeights * sizeof(aiVertexWeight);
138.1027 +			}
138.1028 +		}
138.1029 +		in.meshes += (sizeof(aiFace) + 3 * sizeof(unsigned int))*mScene->mMeshes[i]->mNumFaces;
138.1030 +	}
138.1031 +    in.total += in.meshes;
138.1032 +
138.1033 +	// add all embedded textures
138.1034 +	for (unsigned int i = 0; i < mScene->mNumTextures;++i) {
138.1035 +		const aiTexture* pc = mScene->mTextures[i];
138.1036 +		in.textures += sizeof(aiTexture);
138.1037 +		if (pc->mHeight) {
138.1038 +			in.textures += 4 * pc->mHeight * pc->mWidth;
138.1039 +		}
138.1040 +		else in.textures += pc->mWidth;
138.1041 +	}
138.1042 +	in.total += in.textures;
138.1043 +
138.1044 +	// add all animations
138.1045 +	for (unsigned int i = 0; i < mScene->mNumAnimations;++i) {
138.1046 +		const aiAnimation* pc = mScene->mAnimations[i];
138.1047 +		in.animations += sizeof(aiAnimation);
138.1048 +
138.1049 +		// add all bone anims
138.1050 +		for (unsigned int a = 0; a < pc->mNumChannels; ++a) {
138.1051 +			const aiNodeAnim* pc2 = pc->mChannels[i];
138.1052 +			in.animations += sizeof(aiNodeAnim);
138.1053 +			in.animations += pc2->mNumPositionKeys * sizeof(aiVectorKey);
138.1054 +			in.animations += pc2->mNumScalingKeys * sizeof(aiVectorKey);
138.1055 +			in.animations += pc2->mNumRotationKeys * sizeof(aiQuatKey);
138.1056 +		}
138.1057 +	}
138.1058 +	in.total += in.animations;
138.1059 +
138.1060 +	// add all cameras and all lights
138.1061 +	in.total += in.cameras = sizeof(aiCamera) *  mScene->mNumCameras;
138.1062 +	in.total += in.lights  = sizeof(aiLight)  *  mScene->mNumLights;
138.1063 +
138.1064 +	// add all nodes
138.1065 +	AddNodeWeight(in.nodes,mScene->mRootNode);
138.1066 +	in.total += in.nodes;
138.1067 +
138.1068 +	// add all materials
138.1069 +	for (unsigned int i = 0; i < mScene->mNumMaterials;++i) {
138.1070 +		const aiMaterial* pc = mScene->mMaterials[i];
138.1071 +		in.materials += sizeof(aiMaterial);
138.1072 +		in.materials += pc->mNumAllocated * sizeof(void*);
138.1073 +
138.1074 +		for (unsigned int a = 0; a < pc->mNumProperties;++a) {
138.1075 +			in.materials += pc->mProperties[a]->mDataLength;
138.1076 +		}
138.1077 +	}
138.1078 +	in.total += in.materials;
138.1079 +}
138.1080 +
   139.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   139.2 +++ b/libs/assimp/Importer.h	Sat Feb 01 19:58:19 2014 +0200
   139.3 @@ -0,0 +1,204 @@
   139.4 +/*
   139.5 +Open Asset Import Library (assimp)
   139.6 +----------------------------------------------------------------------
   139.7 +
   139.8 +Copyright (c) 2006-2012, assimp team
   139.9 +All rights reserved.
  139.10 +
  139.11 +Redistribution and use of this software in source and binary forms, 
  139.12 +with or without modification, are permitted provided that the 
  139.13 +following conditions are met:
  139.14 +
  139.15 +* Redistributions of source code must retain the above
  139.16 +  copyright notice, this list of conditions and the
  139.17 +  following disclaimer.
  139.18 +
  139.19 +* Redistributions in binary form must reproduce the above
  139.20 +  copyright notice, this list of conditions and the
  139.21 +  following disclaimer in the documentation and/or other
  139.22 +  materials provided with the distribution.
  139.23 +
  139.24 +* Neither the name of the assimp team, nor the names of its
  139.25 +  contributors may be used to endorse or promote products
  139.26 +  derived from this software without specific prior
  139.27 +  written permission of the assimp team.
  139.28 +
  139.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  139.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  139.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  139.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  139.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  139.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  139.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  139.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  139.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  139.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  139.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  139.40 +
  139.41 +----------------------------------------------------------------------
  139.42 +*/
  139.43 +
  139.44 +/** @file Importer.h mostly internal stuff for use by #Assimp::Importer */
  139.45 +#ifndef INCLUDED_AI_IMPORTER_H
  139.46 +#define INCLUDED_AI_IMPORTER_H
  139.47 +
  139.48 +namespace Assimp	{
  139.49 +
  139.50 +	class BaseImporter;
  139.51 +	class BaseProcess;
  139.52 +
  139.53 +	
  139.54 +//! @cond never
  139.55 +// ---------------------------------------------------------------------------
  139.56 +/** @brief Internal PIMPL implementation for Assimp::Importer
  139.57 + *
  139.58 + *  Using this idiom here allows us to drop the dependency from
  139.59 + *  std::vector and std::map in the public headers. Furthermore we are dropping
  139.60 + *  any STL interface problems caused by mismatching STL settings. All
  139.61 + *  size calculation are now done by us, not the app heap. */
  139.62 +class ImporterPimpl 
  139.63 +{
  139.64 +public:
  139.65 +
  139.66 +	// Data type to store the key hash
  139.67 +	typedef unsigned int KeyType;
  139.68 +	
  139.69 +	// typedefs for our three configuration maps.
  139.70 +	// We don't need more, so there is no need for a generic solution
  139.71 +	typedef std::map<KeyType, int> IntPropertyMap;
  139.72 +	typedef std::map<KeyType, float> FloatPropertyMap;
  139.73 +	typedef std::map<KeyType, std::string> StringPropertyMap;
  139.74 +
  139.75 +public:
  139.76 +
  139.77 +	/** IO handler to use for all file accesses. */
  139.78 +	IOSystem* mIOHandler;
  139.79 +	bool mIsDefaultHandler;
  139.80 +
  139.81 +	/** Progress handler for feedback. */
  139.82 +	ProgressHandler* mProgressHandler;
  139.83 +	bool mIsDefaultProgressHandler;
  139.84 +
  139.85 +	/** Format-specific importer worker objects - one for each format we can read.*/
  139.86 +	std::vector< BaseImporter* > mImporter;
  139.87 +
  139.88 +	/** Post processing steps we can apply at the imported data. */
  139.89 +	std::vector< BaseProcess* > mPostProcessingSteps;
  139.90 +
  139.91 +	/** The imported data, if ReadFile() was successful, NULL otherwise. */
  139.92 +	aiScene* mScene;
  139.93 +
  139.94 +	/** The error description, if there was one. */
  139.95 +	std::string mErrorString;
  139.96 +
  139.97 +	/** List of integer properties */
  139.98 +	IntPropertyMap mIntProperties;
  139.99 +
 139.100 +	/** List of floating-point properties */
 139.101 +	FloatPropertyMap mFloatProperties;
 139.102 +
 139.103 +	/** List of string properties */
 139.104 +	StringPropertyMap mStringProperties;
 139.105 +
 139.106 +	/** Used for testing - extra verbose mode causes the ValidateDataStructure-Step
 139.107 +	 *  to be executed before and after every single postprocess step */
 139.108 +	bool bExtraVerbose;
 139.109 +
 139.110 +	/** Used by post-process steps to share data */
 139.111 +	SharedPostProcessInfo* mPPShared;
 139.112 +};
 139.113 +//! @endcond
 139.114 +
 139.115 +
 139.116 +struct BatchData;
 139.117 +
 139.118 +// ---------------------------------------------------------------------------
 139.119 +/** FOR IMPORTER PLUGINS ONLY: A helper class to the pleasure of importers 
 139.120 + *  that need to load many external meshes recursively.
 139.121 + *
 139.122 + *  The class uses several threads to load these meshes (or at least it
 139.123 + *  could, this has not yet been implemented at the moment).
 139.124 + *
 139.125 + *  @note The class may not be used by more than one thread*/
 139.126 +class BatchLoader 
 139.127 +{
 139.128 +	// friend of Importer
 139.129 +
 139.130 +public:
 139.131 +
 139.132 +	//! @cond never
 139.133 +	// -------------------------------------------------------------------
 139.134 +	/** Wraps a full list of configuration properties for an importer.
 139.135 +	 *  Properties can be set using SetGenericProperty */
 139.136 +	struct PropertyMap
 139.137 +	{
 139.138 +		ImporterPimpl::IntPropertyMap     ints;
 139.139 +		ImporterPimpl::FloatPropertyMap   floats;
 139.140 +		ImporterPimpl::StringPropertyMap  strings;
 139.141 +
 139.142 +		bool operator == (const PropertyMap& prop) const {
 139.143 +			// fixme: really isocpp? gcc complains
 139.144 +			return ints == prop.ints && floats == prop.floats && strings == prop.strings; 
 139.145 +		}
 139.146 +
 139.147 +		bool empty () const {
 139.148 +			return ints.empty() && floats.empty() && strings.empty();
 139.149 +		}
 139.150 +	};
 139.151 +	//! @endcond
 139.152 +
 139.153 +public:
 139.154 +	
 139.155 +
 139.156 +	// -------------------------------------------------------------------
 139.157 +	/** Construct a batch loader from a given IO system to be used 
 139.158 +	 *  to acess external files */
 139.159 +	BatchLoader(IOSystem* pIO);
 139.160 +	~BatchLoader();
 139.161 +
 139.162 +
 139.163 +	// -------------------------------------------------------------------
 139.164 +	/** Add a new file to the list of files to be loaded.
 139.165 +	 *  @param file File to be loaded
 139.166 +	 *  @param steps Post-processing steps to be executed on the file
 139.167 +	 *  @param map Optional configuration properties
 139.168 +	 *  @return 'Load request channel' - an unique ID that can later
 139.169 +	 *    be used to access the imported file data.
 139.170 +	 *  @see GetImport */
 139.171 +	unsigned int AddLoadRequest	(
 139.172 +		const std::string& file,
 139.173 +		unsigned int steps = 0, 
 139.174 +		const PropertyMap* map = NULL
 139.175 +		);
 139.176 +
 139.177 +
 139.178 +	// -------------------------------------------------------------------
 139.179 +	/** Get an imported scene.
 139.180 +	 *  This polls the import from the internal request list.
 139.181 +	 *  If an import is requested several times, this function
 139.182 +	 *  can be called several times, too.
 139.183 +	 *
 139.184 +	 *  @param which LRWC returned by AddLoadRequest().
 139.185 +	 *  @return NULL if there is no scene with this file name
 139.186 +	 *  in the queue of the scene hasn't been loaded yet. */
 139.187 +	aiScene* GetImport(
 139.188 +		unsigned int which
 139.189 +		);
 139.190 +
 139.191 +
 139.192 +	// -------------------------------------------------------------------
 139.193 +	/** Waits until all scenes have been loaded. This returns
 139.194 +	 *  immediately if no scenes are queued.*/
 139.195 +	void LoadAll();
 139.196 +
 139.197 +private:
 139.198 +
 139.199 +	// No need to have that in the public API ...
 139.200 +	BatchData* data;
 139.201 +};
 139.202 +
 139.203 +}
 139.204 +
 139.205 +
 139.206 +
 139.207 +#endif
   140.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   140.2 +++ b/libs/assimp/ImporterRegistry.cpp	Sat Feb 01 19:58:19 2014 +0200
   140.3 @@ -0,0 +1,296 @@
   140.4 +/*
   140.5 +---------------------------------------------------------------------------
   140.6 +Open Asset Import Library (assimp)
   140.7 +---------------------------------------------------------------------------
   140.8 +
   140.9 +Copyright (c) 2006-2012, assimp team
  140.10 +
  140.11 +All rights reserved.
  140.12 +
  140.13 +Redistribution and use of this software in source and binary forms, 
  140.14 +with or without modification, are permitted provided that the following 
  140.15 +conditions are met:
  140.16 +
  140.17 +* Redistributions of source code must retain the above
  140.18 +  copyright notice, this list of conditions and the
  140.19 +  following disclaimer.
  140.20 +
  140.21 +* Redistributions in binary form must reproduce the above
  140.22 +  copyright notice, this list of conditions and the
  140.23 +  following disclaimer in the documentation and/or other
  140.24 +  materials provided with the distribution.
  140.25 +
  140.26 +* Neither the name of the assimp team, nor the names of its
  140.27 +  contributors may be used to endorse or promote products
  140.28 +  derived from this software without specific prior
  140.29 +  written permission of the assimp team.
  140.30 +
  140.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  140.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  140.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  140.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  140.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  140.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  140.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  140.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  140.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  140.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  140.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  140.42 +---------------------------------------------------------------------------
  140.43 +*/
  140.44 +
  140.45 +/** @file ImporterRegistry.cpp
  140.46 +
  140.47 +Central registry for all importers available. Do not edit this file
  140.48 +directly (unless you are adding new loaders), instead use the
  140.49 +corresponding preprocessor flag to selectively disable formats.
  140.50 +*/
  140.51 +
  140.52 +#include "AssimpPCH.h"
  140.53 +
  140.54 +// ------------------------------------------------------------------------------------------------
  140.55 +// Importers
  140.56 +// (include_new_importers_here)
  140.57 +// ------------------------------------------------------------------------------------------------
  140.58 +#ifndef ASSIMP_BUILD_NO_X_IMPORTER
  140.59 +#	include "XFileImporter.h"
  140.60 +#endif
  140.61 +#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
  140.62 +#	include "3DSLoader.h"
  140.63 +#endif
  140.64 +#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
  140.65 +#	include "MD3Loader.h"
  140.66 +#endif
  140.67 +#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
  140.68 +#	include "MDLLoader.h"
  140.69 +#endif
  140.70 +#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
  140.71 +#	include "MD2Loader.h"
  140.72 +#endif
  140.73 +#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
  140.74 +#	include "PlyLoader.h"
  140.75 +#endif
  140.76 +#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
  140.77 +#	include "ASELoader.h"
  140.78 +#endif
  140.79 +#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
  140.80 +#	include "ObjFileImporter.h"
  140.81 +#endif
  140.82 +#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
  140.83 +#	include "HMPLoader.h"
  140.84 +#endif
  140.85 +#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER
  140.86 +#	include "SMDLoader.h"
  140.87 +#endif
  140.88 +#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
  140.89 +#	include "MDCLoader.h"
  140.90 +#endif
  140.91 +#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
  140.92 +#	include "MD5Loader.h"
  140.93 +#endif
  140.94 +#ifndef ASSIMP_BUILD_NO_STL_IMPORTER
  140.95 +#	include "STLLoader.h"
  140.96 +#endif
  140.97 +#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
  140.98 +#	include "LWOLoader.h"
  140.99 +#endif
 140.100 +#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
 140.101 +#	include "DXFLoader.h"
 140.102 +#endif
 140.103 +#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER
 140.104 +#	include "NFFLoader.h"
 140.105 +#endif
 140.106 +#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
 140.107 +#	include "RawLoader.h"
 140.108 +#endif
 140.109 +#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
 140.110 +#	include "OFFLoader.h"
 140.111 +#endif
 140.112 +#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
 140.113 +#	include "ACLoader.h"
 140.114 +#endif
 140.115 +#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
 140.116 +#	include "BVHLoader.h"
 140.117 +#endif
 140.118 +#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
 140.119 +#	include "IRRMeshLoader.h"
 140.120 +#endif
 140.121 +#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
 140.122 +#	include "IRRLoader.h"
 140.123 +#endif
 140.124 +#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
 140.125 +#	include "Q3DLoader.h"
 140.126 +#endif
 140.127 +#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
 140.128 +#	include "B3DImporter.h"
 140.129 +#endif
 140.130 +#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
 140.131 +#	include "ColladaLoader.h"
 140.132 +#endif
 140.133 +#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
 140.134 +#	include "TerragenLoader.h"
 140.135 +#endif
 140.136 +#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
 140.137 +#	include "CSMLoader.h"
 140.138 +#endif
 140.139 +#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
 140.140 +#	include "UnrealLoader.h"
 140.141 +#endif
 140.142 +#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
 140.143 +#	include "LWSLoader.h"
 140.144 +#endif
 140.145 +#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
 140.146 +#	include "OgreImporter.hpp"
 140.147 +#endif
 140.148 +#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
 140.149 +#	include "MS3DLoader.h"
 140.150 +#endif
 140.151 +#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
 140.152 +#	include "COBLoader.h"
 140.153 +#endif
 140.154 +#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 140.155 +#	include "BlenderLoader.h"
 140.156 +#endif
 140.157 +#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
 140.158 +#	include "Q3BSPFileImporter.h"
 140.159 +#endif
 140.160 +#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
 140.161 +#	include "NDOLoader.h"
 140.162 +#endif
 140.163 +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
 140.164 +#	include "IFCLoader.h"
 140.165 +#endif
 140.166 +#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
 140.167 +#   include "XGLLoader.h"
 140.168 +#endif 
 140.169 +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
 140.170 +#   include "FBXImporter.h"
 140.171 +#endif 
 140.172 +
 140.173 +namespace Assimp {
 140.174 +
 140.175 +// ------------------------------------------------------------------------------------------------
 140.176 +void GetImporterInstanceList(std::vector< BaseImporter* >& out)
 140.177 +{
 140.178 +	// ----------------------------------------------------------------------------
 140.179 +	// Add an instance of each worker class here
 140.180 +	// (register_new_importers_here)
 140.181 +	// ----------------------------------------------------------------------------
 140.182 +	out.reserve(64);
 140.183 +#if (!defined ASSIMP_BUILD_NO_X_IMPORTER)
 140.184 +	out.push_back( new XFileImporter());
 140.185 +#endif
 140.186 +#if (!defined ASSIMP_BUILD_NO_OBJ_IMPORTER)
 140.187 +	out.push_back( new ObjFileImporter());
 140.188 +#endif
 140.189 +#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
 140.190 +	out.push_back( new Discreet3DSImporter());
 140.191 +#endif
 140.192 +#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
 140.193 +	out.push_back( new MD3Importer());
 140.194 +#endif
 140.195 +#if (!defined ASSIMP_BUILD_NO_MD2_IMPORTER)
 140.196 +	out.push_back( new MD2Importer());
 140.197 +#endif
 140.198 +#if (!defined ASSIMP_BUILD_NO_PLY_IMPORTER)
 140.199 +	out.push_back( new PLYImporter());
 140.200 +#endif
 140.201 +#if (!defined ASSIMP_BUILD_NO_MDL_IMPORTER)
 140.202 +	out.push_back( new MDLImporter());
 140.203 +#endif
 140.204 +#if (!defined ASSIMP_BUILD_NO_ASE_IMPORTER)
 140.205 +	out.push_back( new ASEImporter());
 140.206 +#endif
 140.207 +#if (!defined ASSIMP_BUILD_NO_HMP_IMPORTER)
 140.208 +	out.push_back( new HMPImporter());
 140.209 +#endif
 140.210 +#if (!defined ASSIMP_BUILD_NO_SMD_IMPORTER)
 140.211 +	out.push_back( new SMDImporter());
 140.212 +#endif
 140.213 +#if (!defined ASSIMP_BUILD_NO_MDC_IMPORTER)
 140.214 +	out.push_back( new MDCImporter());
 140.215 +#endif
 140.216 +#if (!defined ASSIMP_BUILD_NO_MD5_IMPORTER)
 140.217 +	out.push_back( new MD5Importer());
 140.218 +#endif
 140.219 +#if (!defined ASSIMP_BUILD_NO_STL_IMPORTER)
 140.220 +	out.push_back( new STLImporter());
 140.221 +#endif
 140.222 +#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER)
 140.223 +	out.push_back( new LWOImporter());
 140.224 +#endif
 140.225 +#if (!defined ASSIMP_BUILD_NO_DXF_IMPORTER)
 140.226 +	out.push_back( new DXFImporter());
 140.227 +#endif
 140.228 +#if (!defined ASSIMP_BUILD_NO_NFF_IMPORTER)
 140.229 +	out.push_back( new NFFImporter());
 140.230 +#endif
 140.231 +#if (!defined ASSIMP_BUILD_NO_RAW_IMPORTER)
 140.232 +	out.push_back( new RAWImporter());
 140.233 +#endif
 140.234 +#if (!defined ASSIMP_BUILD_NO_OFF_IMPORTER)
 140.235 +	out.push_back( new OFFImporter());
 140.236 +#endif
 140.237 +#if (!defined ASSIMP_BUILD_NO_AC_IMPORTER)
 140.238 +	out.push_back( new AC3DImporter());
 140.239 +#endif
 140.240 +#if (!defined ASSIMP_BUILD_NO_BVH_IMPORTER)
 140.241 +	out.push_back( new BVHLoader());
 140.242 +#endif
 140.243 +#if (!defined ASSIMP_BUILD_NO_IRRMESH_IMPORTER)
 140.244 +	out.push_back( new IRRMeshImporter());
 140.245 +#endif
 140.246 +#if (!defined ASSIMP_BUILD_NO_IRR_IMPORTER)
 140.247 +	out.push_back( new IRRImporter());
 140.248 +#endif
 140.249 +#if (!defined ASSIMP_BUILD_NO_Q3D_IMPORTER)
 140.250 +	out.push_back( new Q3DImporter());
 140.251 +#endif
 140.252 +#if (!defined ASSIMP_BUILD_NO_B3D_IMPORTER)
 140.253 +	out.push_back( new B3DImporter());
 140.254 +#endif
 140.255 +#if (!defined ASSIMP_BUILD_NO_COLLADA_IMPORTER)
 140.256 +	out.push_back( new ColladaLoader());
 140.257 +#endif
 140.258 +#if (!defined ASSIMP_BUILD_NO_TERRAGEN_IMPORTER)
 140.259 +	out.push_back( new TerragenImporter());
 140.260 +#endif
 140.261 +#if (!defined ASSIMP_BUILD_NO_CSM_IMPORTER)
 140.262 +	out.push_back( new CSMImporter());
 140.263 +#endif
 140.264 +#if (!defined ASSIMP_BUILD_NO_3D_IMPORTER)
 140.265 +	out.push_back( new UnrealImporter());
 140.266 +#endif
 140.267 +#if (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
 140.268 +	out.push_back( new LWSImporter());
 140.269 +#endif
 140.270 +#if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER)
 140.271 +	out.push_back( new Ogre::OgreImporter());
 140.272 +#endif
 140.273 +#if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER)
 140.274 +	out.push_back( new MS3DImporter());
 140.275 +#endif
 140.276 +#if (!defined ASSIMP_BUILD_NO_COB_IMPORTER)
 140.277 +	out.push_back( new COBImporter());
 140.278 +#endif
 140.279 +#if (!defined ASSIMP_BUILD_NO_BLEND_IMPORTER)
 140.280 +	out.push_back( new BlenderImporter());
 140.281 +#endif
 140.282 +#if (!defined ASSIMP_BUILD_NO_Q3BSP_IMPORTER)
 140.283 +	out.push_back( new Q3BSPFileImporter() );
 140.284 +#endif
 140.285 +#if (!defined ASSIMP_BUILD_NO_NDO_IMPORTER)
 140.286 +	out.push_back( new NDOImporter() );
 140.287 +#endif
 140.288 +#if (!defined ASSIMP_BUILD_NO_IFC_IMPORTER)
 140.289 +	out.push_back( new IFCImporter() );
 140.290 +#endif
 140.291 +#if ( !defined ASSIMP_BUILD_NO_XGL_IMPORTER )
 140.292 +	out.push_back( new XGLImporter() );
 140.293 +#endif
 140.294 +#if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER )
 140.295 +	out.push_back( new FBXImporter() );
 140.296 +#endif
 140.297 +}
 140.298 +
 140.299 +}
   141.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   141.2 +++ b/libs/assimp/ImproveCacheLocality.cpp	Sat Feb 01 19:58:19 2014 +0200
   141.3 @@ -0,0 +1,380 @@
   141.4 +/*
   141.5 +---------------------------------------------------------------------------
   141.6 +Open Asset Import Library (assimp)
   141.7 +---------------------------------------------------------------------------
   141.8 +
   141.9 +Copyright (c) 2006-2012, assimp team
  141.10 +
  141.11 +All rights reserved.
  141.12 +
  141.13 +Redistribution and use of this software in source and binary forms, 
  141.14 +with or without modification, are permitted provided that the following 
  141.15 +conditions are met:
  141.16 +
  141.17 +* Redistributions of source code must retain the above
  141.18 +  copyright notice, this list of conditions and the
  141.19 +  following disclaimer.
  141.20 +
  141.21 +* Redistributions in binary form must reproduce the above
  141.22 +  copyright notice, this list of conditions and the
  141.23 +  following disclaimer in the documentation and/or other
  141.24 +  materials provided with the distribution.
  141.25 +
  141.26 +* Neither the name of the assimp team, nor the names of its
  141.27 +  contributors may be used to endorse or promote products
  141.28 +  derived from this software without specific prior
  141.29 +  written permission of the assimp team.
  141.30 +
  141.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  141.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  141.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  141.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  141.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  141.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  141.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  141.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  141.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  141.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  141.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  141.42 +---------------------------------------------------------------------------
  141.43 +*/
  141.44 +
  141.45 +/** @file Implementation of the post processing step to improve the cache locality of a mesh.
  141.46 + * <br>
  141.47 + * The algorithm is roughly basing on this paper:
  141.48 + * http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf
  141.49 + *   .. although overdraw rduction isn't implemented yet ...
  141.50 + */
  141.51 +
  141.52 +#include "AssimpPCH.h"
  141.53 +
  141.54 +// internal headers
  141.55 +#include "ImproveCacheLocality.h"
  141.56 +#include "VertexTriangleAdjacency.h"
  141.57 +
  141.58 +using namespace Assimp;
  141.59 +
  141.60 +// ------------------------------------------------------------------------------------------------
  141.61 +// Constructor to be privately used by Importer
  141.62 +ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() {
  141.63 +	configCacheDepth = PP_ICL_PTCACHE_SIZE;
  141.64 +}
  141.65 +
  141.66 +// ------------------------------------------------------------------------------------------------
  141.67 +// Destructor, private as well
  141.68 +ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess()
  141.69 +{
  141.70 +	// nothing to do here
  141.71 +}
  141.72 +
  141.73 +// ------------------------------------------------------------------------------------------------
  141.74 +// Returns whether the processing step is present in the given flag field.
  141.75 +bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const
  141.76 +{
  141.77 +	return (pFlags & aiProcess_ImproveCacheLocality) != 0;
  141.78 +}
  141.79 +
  141.80 +// ------------------------------------------------------------------------------------------------
  141.81 +// Setup configuration
  141.82 +void ImproveCacheLocalityProcess::SetupProperties(const Importer* pImp)
  141.83 +{
  141.84 +	// AI_CONFIG_PP_ICL_PTCACHE_SIZE controls the target cache size for the optimizer
  141.85 +	configCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE,PP_ICL_PTCACHE_SIZE);
  141.86 +}
  141.87 +
  141.88 +// ------------------------------------------------------------------------------------------------
  141.89 +// Executes the post processing step on the given imported data.
  141.90 +void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
  141.91 +{
  141.92 +	if (!pScene->mNumMeshes) {
  141.93 +		DefaultLogger::get()->debug("ImproveCacheLocalityProcess skipped; there are no meshes");
  141.94 +		return;
  141.95 +	}
  141.96 +
  141.97 +	DefaultLogger::get()->debug("ImproveCacheLocalityProcess begin");
  141.98 +
  141.99 +	float out = 0.f;
 141.100 +	unsigned int numf = 0, numm = 0;
 141.101 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++){
 141.102 +		const float res = ProcessMesh( pScene->mMeshes[a],a);
 141.103 +		if (res) {
 141.104 +			numf += pScene->mMeshes[a]->mNumFaces;
 141.105 +			out  += res;
 141.106 +			++numm;
 141.107 +		}
 141.108 +	}
 141.109 +	if (!DefaultLogger::isNullLogger()) {
 141.110 +		char szBuff[128]; // should be sufficiently large in every case
 141.111 +		::sprintf(szBuff,"Cache relevant are %i meshes (%i faces). Average output ACMR is %f",
 141.112 +			numm,numf,out/numf);
 141.113 +
 141.114 +		DefaultLogger::get()->info(szBuff);
 141.115 +		DefaultLogger::get()->debug("ImproveCacheLocalityProcess finished. ");
 141.116 +	}
 141.117 +}
 141.118 +
 141.119 +// ------------------------------------------------------------------------------------------------
 141.120 +// Improves the cache coherency of a specific mesh
 141.121 +float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshNum)
 141.122 +{
 141.123 +	// TODO: rewrite this to use std::vector or boost::shared_array
 141.124 +	ai_assert(NULL != pMesh);
 141.125 +
 141.126 +	// Check whether the input data is valid
 141.127 +	// - there must be vertices and faces 
 141.128 +	// - all faces must be triangulated or we can't operate on them
 141.129 +	if (!pMesh->HasFaces() || !pMesh->HasPositions())
 141.130 +		return 0.f;
 141.131 +
 141.132 +	if (pMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE)	{
 141.133 +		DefaultLogger::get()->error("This algorithm works on triangle meshes only");
 141.134 +		return 0.f;
 141.135 +	}
 141.136 +
 141.137 +	if(pMesh->mNumVertices <= configCacheDepth) {
 141.138 +		return 0.f;
 141.139 +	}
 141.140 +
 141.141 +	float fACMR = 3.f;
 141.142 +	const aiFace* const pcEnd = pMesh->mFaces+pMesh->mNumFaces;
 141.143 +
 141.144 +	// Input ACMR is for logging purposes only
 141.145 +	if (!DefaultLogger::isNullLogger())		{
 141.146 +
 141.147 +		unsigned int* piFIFOStack = new unsigned int[configCacheDepth];
 141.148 +		memset(piFIFOStack,0xff,configCacheDepth*sizeof(unsigned int));
 141.149 +		unsigned int* piCur = piFIFOStack;
 141.150 +		const unsigned int* const piCurEnd = piFIFOStack + configCacheDepth;
 141.151 +
 141.152 +		// count the number of cache misses
 141.153 +		unsigned int iCacheMisses = 0;
 141.154 +		for (const aiFace* pcFace = pMesh->mFaces;pcFace != pcEnd;++pcFace)	{
 141.155 +
 141.156 +			for (unsigned int qq = 0; qq < 3;++qq) {
 141.157 +				bool bInCache = false;
 141.158 +
 141.159 +				for (unsigned int* pp = piFIFOStack;pp < piCurEnd;++pp)	{
 141.160 +					if (*pp == pcFace->mIndices[qq])	{
 141.161 +						// the vertex is in cache
 141.162 +						bInCache = true;
 141.163 +						break;
 141.164 +					}
 141.165 +				}
 141.166 +				if (!bInCache)	{
 141.167 +					++iCacheMisses;
 141.168 +					if (piCurEnd == piCur) {
 141.169 +						piCur = piFIFOStack;
 141.170 +					}
 141.171 +					*piCur++ = pcFace->mIndices[qq];
 141.172 +				}
 141.173 +			}
 141.174 +		}
 141.175 +		delete[] piFIFOStack;
 141.176 +		fACMR = (float)iCacheMisses / pMesh->mNumFaces;
 141.177 +		if (3.0 == fACMR)	{
 141.178 +			char szBuff[128]; // should be sufficiently large in every case
 141.179 +
 141.180 +			// the JoinIdenticalVertices process has not been executed on this
 141.181 +			// mesh, otherwise this value would normally be at least minimally
 141.182 +			// smaller than 3.0 ...
 141.183 +			sprintf(szBuff,"Mesh %i: Not suitable for vcache optimization",meshNum);
 141.184 +			DefaultLogger::get()->warn(szBuff);
 141.185 +			return 0.f;
 141.186 +		}
 141.187 +	}
 141.188 +
 141.189 +	// first we need to build a vertex-triangle adjacency list
 141.190 +	VertexTriangleAdjacency adj(pMesh->mFaces,pMesh->mNumFaces, pMesh->mNumVertices,true);
 141.191 +
 141.192 +	// build a list to store per-vertex caching time stamps
 141.193 +	unsigned int* const piCachingStamps = new unsigned int[pMesh->mNumVertices];
 141.194 +	memset(piCachingStamps,0x0,pMesh->mNumVertices*sizeof(unsigned int));
 141.195 +
 141.196 +	// allocate an empty output index buffer. We store the output indices in one large array.
 141.197 +	// Since the number of triangles won't change the input faces can be reused. This is how 
 141.198 +	// we save thousands of redundant mini allocations for aiFace::mIndices
 141.199 +	const unsigned int iIdxCnt = pMesh->mNumFaces*3;
 141.200 +	unsigned int* const piIBOutput = new unsigned int[iIdxCnt];
 141.201 +	unsigned int* piCSIter = piIBOutput;
 141.202 +
 141.203 +	// allocate the flag array to hold the information
 141.204 +	// whether a face has already been emitted or not
 141.205 +	std::vector<bool> abEmitted(pMesh->mNumFaces,false);
 141.206 +
 141.207 +	// dead-end vertex index stack
 141.208 +	std::stack<unsigned int, std::vector<unsigned int> > sDeadEndVStack;
 141.209 +
 141.210 +	// create a copy of the piNumTriPtr buffer
 141.211 +	unsigned int* const piNumTriPtr = adj.mLiveTriangles;
 141.212 +	const std::vector<unsigned int> piNumTriPtrNoModify(piNumTriPtr, piNumTriPtr + pMesh->mNumVertices);
 141.213 +	
 141.214 +	// get the largest number of referenced triangles and allocate the "candidate buffer"
 141.215 +	unsigned int iMaxRefTris = 0; {
 141.216 +		const unsigned int* piCur = adj.mLiveTriangles;
 141.217 +		const unsigned int* const piCurEnd = adj.mLiveTriangles+pMesh->mNumVertices;
 141.218 +		for (;piCur != piCurEnd;++piCur) {
 141.219 +			iMaxRefTris = std::max(iMaxRefTris,*piCur);
 141.220 +		}
 141.221 +	}
 141.222 +	unsigned int* piCandidates = new unsigned int[iMaxRefTris*3];
 141.223 +	unsigned int iCacheMisses = 0;
 141.224 +
 141.225 +	// ...................................................................................
 141.226 +	/** PSEUDOCODE for the algorithm
 141.227 +
 141.228 +		A = Build-Adjacency(I) Vertex-triangle adjacency
 141.229 +		L = Get-Triangle-Counts(A) Per-vertex live triangle counts
 141.230 +		C = Zero(Vertex-Count(I)) Per-vertex caching time stamps
 141.231 +		D = Empty-Stack() Dead-end vertex stack
 141.232 +		E = False(Triangle-Count(I)) Per triangle emitted flag
 141.233 +		O = Empty-Index-Buffer() Empty output buffer
 141.234 +		f = 0 Arbitrary starting vertex
 141.235 +		s = k+1, i = 1 Time stamp and cursor
 141.236 +		while f >= 0 For all valid fanning vertices
 141.237 +			N = Empty-Set() 1-ring of next candidates
 141.238 +			for each Triangle t in Neighbors(A, f)
 141.239 +				if !Emitted(E,t)
 141.240 +					for each Vertex v in t
 141.241 +						Append(O,v) Output vertex
 141.242 +						Push(D,v) Add to dead-end stack
 141.243 +						Insert(N,v) Register as candidate
 141.244 +						L[v] = L[v]-1 Decrease live triangle count
 141.245 +						if s-C[v] > k If not in cache
 141.246 +							C[v] = s Set time stamp
 141.247 +							s = s+1 Increment time stamp
 141.248 +					E[t] = true Flag triangle as emitted
 141.249 +			Select next fanning vertex
 141.250 +			f = Get-Next-Vertex(I,i,k,N,C,s,L,D)
 141.251 +		return O
 141.252 +		*/
 141.253 +	// ...................................................................................
 141.254 +
 141.255 +	int ivdx = 0;
 141.256 +	int ics = 1;
 141.257 +	int iStampCnt = configCacheDepth+1;
 141.258 +	while (ivdx >= 0)	{
 141.259 +
 141.260 +		unsigned int icnt = piNumTriPtrNoModify[ivdx]; 
 141.261 +		unsigned int* piList = adj.GetAdjacentTriangles(ivdx);
 141.262 +		unsigned int* piCurCandidate = piCandidates;
 141.263 +
 141.264 +		// get all triangles in the neighborhood
 141.265 +		for (unsigned int tri = 0; tri < icnt;++tri)	{
 141.266 +
 141.267 +			// if they have not yet been emitted, add them to the output IB
 141.268 +			const unsigned int fidx = *piList++;
 141.269 +			if (!abEmitted[fidx])	{
 141.270 +
 141.271 +				// so iterate through all vertices of the current triangle
 141.272 +				const aiFace* pcFace = &pMesh->mFaces[ fidx ];
 141.273 +				for (unsigned int* p = pcFace->mIndices, *p2 = pcFace->mIndices+3;p != p2;++p)	{
 141.274 +					const unsigned int dp = *p;
 141.275 +
 141.276 +					// the current vertex won't have any free triangles after this step
 141.277 +					if (ivdx != (int)dp) {
 141.278 +						// append the vertex to the dead-end stack
 141.279 +						sDeadEndVStack.push(dp);
 141.280 +
 141.281 +						// register as candidate for the next step
 141.282 +						*piCurCandidate++ = dp;
 141.283 +
 141.284 +						// decrease the per-vertex triangle counts
 141.285 +						piNumTriPtr[dp]--;
 141.286 +					}
 141.287 +
 141.288 +					// append the vertex to the output index buffer
 141.289 +					*piCSIter++ = dp;
 141.290 +
 141.291 +					// if the vertex is not yet in cache, set its cache count
 141.292 +					if (iStampCnt-piCachingStamps[dp] > configCacheDepth) {
 141.293 +						piCachingStamps[dp] = iStampCnt++;
 141.294 +						++iCacheMisses;
 141.295 +					}
 141.296 +				}
 141.297 +				// flag triangle as emitted
 141.298 +				abEmitted[fidx] = true;
 141.299 +			}
 141.300 +		}
 141.301 +
 141.302 +		// the vertex has now no living adjacent triangles anymore
 141.303 +		piNumTriPtr[ivdx] = 0;
 141.304 +
 141.305 +		// get next fanning vertex
 141.306 +		ivdx = -1; 
 141.307 +		int max_priority = -1;
 141.308 +		for (unsigned int* piCur = piCandidates;piCur != piCurCandidate;++piCur)	{
 141.309 +			register const unsigned int dp = *piCur;
 141.310 +
 141.311 +			// must have live triangles
 141.312 +			if (piNumTriPtr[dp] > 0)	{
 141.313 +				int priority = 0;
 141.314 +
 141.315 +				// will the vertex be in cache, even after fanning occurs?
 141.316 +				unsigned int tmp;
 141.317 +				if ((tmp = iStampCnt-piCachingStamps[dp]) + 2*piNumTriPtr[dp] <= configCacheDepth) {
 141.318 +					priority = tmp;
 141.319 +				}
 141.320 +
 141.321 +				// keep best candidate
 141.322 +				if (priority > max_priority) {
 141.323 +					max_priority = priority;
 141.324 +					ivdx = dp;
 141.325 +				}
 141.326 +			}
 141.327 +		}
 141.328 +		// did we reach a dead end?
 141.329 +		if (-1 == ivdx)	{
 141.330 +			// need to get a non-local vertex for which we have a good chance that it is still 
 141.331 +			// in the cache ...
 141.332 +			while (!sDeadEndVStack.empty())	{
 141.333 +				unsigned int iCachedIdx = sDeadEndVStack.top();
 141.334 +				sDeadEndVStack.pop();
 141.335 +				if (piNumTriPtr[ iCachedIdx ] > 0)	{
 141.336 +					ivdx = iCachedIdx;
 141.337 +					break;
 141.338 +				}
 141.339 +			}
 141.340 +
 141.341 +			if (-1 == ivdx)	{
 141.342 +				// well, there isn't such a vertex. Simply get the next vertex in input order and
 141.343 +				// hope it is not too bad ...
 141.344 +				while (ics < (int)pMesh->mNumVertices)	{
 141.345 +					++ics;
 141.346 +					if (piNumTriPtr[ics] > 0)	{
 141.347 +						ivdx = ics;
 141.348 +						break;
 141.349 +					}
 141.350 +				}
 141.351 +			}
 141.352 +		}
 141.353 +	}
 141.354 +	float fACMR2 = 0.0f;
 141.355 +	if (!DefaultLogger::isNullLogger()) {
 141.356 +		fACMR2 = (float)iCacheMisses / pMesh->mNumFaces;
 141.357 +
 141.358 +		// very intense verbose logging ... prepare for much text if there are many meshes
 141.359 +		if ( DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
 141.360 +			char szBuff[128]; // should be sufficiently large in every case
 141.361 +
 141.362 +			::sprintf(szBuff,"Mesh %i | ACMR in: %f out: %f | ~%.1f%%",meshNum,fACMR,fACMR2,
 141.363 +				((fACMR - fACMR2) / fACMR) * 100.f);
 141.364 +			DefaultLogger::get()->debug(szBuff);
 141.365 +		}
 141.366 +
 141.367 +		fACMR2 *= pMesh->mNumFaces;
 141.368 +	}
 141.369 +	// sort the output index buffer back to the input array
 141.370 +	piCSIter = piIBOutput;
 141.371 +	for (aiFace* pcFace = pMesh->mFaces; pcFace != pcEnd;++pcFace)	{
 141.372 +		pcFace->mIndices[0] = *piCSIter++;
 141.373 +		pcFace->mIndices[1] = *piCSIter++;
 141.374 +		pcFace->mIndices[2] = *piCSIter++;
 141.375 +	}
 141.376 +
 141.377 +	// delete temporary storage
 141.378 +	delete[] piCachingStamps;
 141.379 +	delete[] piIBOutput;
 141.380 +	delete[] piCandidates;
 141.381 +
 141.382 +	return fACMR2;
 141.383 +}
   142.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   142.2 +++ b/libs/assimp/ImproveCacheLocality.h	Sat Feb 01 19:58:19 2014 +0200
   142.3 @@ -0,0 +1,98 @@
   142.4 +/*
   142.5 +Open Asset Import Library (assimp)
   142.6 +----------------------------------------------------------------------
   142.7 +
   142.8 +Copyright (c) 2006-2012, assimp team
   142.9 +All rights reserved.
  142.10 +
  142.11 +Redistribution and use of this software in source and binary forms, 
  142.12 +with or without modification, are permitted provided that the 
  142.13 +following conditions are met:
  142.14 +
  142.15 +* Redistributions of source code must retain the above
  142.16 +  copyright notice, this list of conditions and the
  142.17 +  following disclaimer.
  142.18 +
  142.19 +* Redistributions in binary form must reproduce the above
  142.20 +  copyright notice, this list of conditions and the
  142.21 +  following disclaimer in the documentation and/or other
  142.22 +  materials provided with the distribution.
  142.23 +
  142.24 +* Neither the name of the assimp team, nor the names of its
  142.25 +  contributors may be used to endorse or promote products
  142.26 +  derived from this software without specific prior
  142.27 +  written permission of the assimp team.
  142.28 +
  142.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  142.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  142.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  142.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  142.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  142.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  142.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  142.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  142.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  142.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  142.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  142.40 +
  142.41 +----------------------------------------------------------------------
  142.42 +*/
  142.43 +
  142.44 +/** @file Defines a post processing step to reorder faces for 
  142.45 + better cache locality*/
  142.46 +#ifndef AI_IMPROVECACHELOCALITY_H_INC
  142.47 +#define AI_IMPROVECACHELOCALITY_H_INC
  142.48 +
  142.49 +#include "BaseProcess.h"
  142.50 +#include "assimp/types.h"
  142.51 +
  142.52 +struct aiMesh;
  142.53 +
  142.54 +namespace Assimp
  142.55 +{
  142.56 +
  142.57 +// ---------------------------------------------------------------------------
  142.58 +/** The ImproveCacheLocalityProcess reorders all faces for improved vertex
  142.59 + *  cache locality. It tries to arrange all faces to fans and to render
  142.60 + *  faces which share vertices directly one after the other.
  142.61 + *
  142.62 + *  @note This step expects triagulated input data.
  142.63 + */
  142.64 +class ImproveCacheLocalityProcess : public BaseProcess
  142.65 +{
  142.66 +public:
  142.67 +
  142.68 +	ImproveCacheLocalityProcess();
  142.69 +	~ImproveCacheLocalityProcess();
  142.70 +
  142.71 +public:
  142.72 +
  142.73 +	// -------------------------------------------------------------------
  142.74 +	// Check whether the pp step is active
  142.75 +	bool IsActive( unsigned int pFlags) const;
  142.76 +
  142.77 +	// -------------------------------------------------------------------
  142.78 +	// Executes the pp step on a given scene
  142.79 +	void Execute( aiScene* pScene);
  142.80 +
  142.81 +	// -------------------------------------------------------------------
  142.82 +	// Configures the pp step
  142.83 +	void SetupProperties(const Importer* pImp);
  142.84 +
  142.85 +protected:
  142.86 +	// -------------------------------------------------------------------
  142.87 +	/** Executes the postprocessing step on the given mesh
  142.88 +	 * @param pMesh The mesh to process.
  142.89 +	 * @param meshNum Index of the mesh to process
  142.90 +	 */
  142.91 +	float ProcessMesh( aiMesh* pMesh, unsigned int meshNum);
  142.92 +
  142.93 +private:
  142.94 +	//! Configuration parameter: specifies the size of the cache to
  142.95 +	//! optimize the vertex data for.
  142.96 +	unsigned int configCacheDepth;
  142.97 +};
  142.98 +
  142.99 +} // end of namespace Assimp
 142.100 +
 142.101 +#endif // AI_IMPROVECACHELOCALITY_H_INC
   143.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   143.2 +++ b/libs/assimp/JoinVerticesProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
   143.3 @@ -0,0 +1,414 @@
   143.4 +/*
   143.5 +---------------------------------------------------------------------------
   143.6 +Open Asset Import Library (assimp)
   143.7 +---------------------------------------------------------------------------
   143.8 +
   143.9 +Copyright (c) 2006-2012, assimp team
  143.10 +
  143.11 +All rights reserved.
  143.12 +
  143.13 +Redistribution and use of this software in source and binary forms, 
  143.14 +with or without modification, are permitted provided that the following 
  143.15 +conditions are met:
  143.16 +
  143.17 +* Redistributions of source code must retain the above
  143.18 +  copyright notice, this list of conditions and the
  143.19 +  following disclaimer.
  143.20 +
  143.21 +* Redistributions in binary form must reproduce the above
  143.22 +  copyright notice, this list of conditions and the
  143.23 +  following disclaimer in the documentation and/or other
  143.24 +  materials provided with the distribution.
  143.25 +
  143.26 +* Neither the name of the assimp team, nor the names of its
  143.27 +  contributors may be used to endorse or promote products
  143.28 +  derived from this software without specific prior
  143.29 +  written permission of the assimp team.
  143.30 +
  143.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  143.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  143.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  143.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  143.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  143.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  143.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  143.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  143.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  143.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  143.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  143.42 +---------------------------------------------------------------------------
  143.43 +*/
  143.44 +
  143.45 +/** @file Implementation of the post processing step to join identical vertices
  143.46 + * for all imported meshes
  143.47 + */
  143.48 +
  143.49 +#include "AssimpPCH.h"
  143.50 +#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
  143.51 +
  143.52 +#include "JoinVerticesProcess.h"
  143.53 +#include "ProcessHelper.h"
  143.54 +#include "Vertex.h"
  143.55 +#include "TinyFormatter.h"
  143.56 +
  143.57 +using namespace Assimp;
  143.58 +// ------------------------------------------------------------------------------------------------
  143.59 +// Constructor to be privately used by Importer
  143.60 +JoinVerticesProcess::JoinVerticesProcess()
  143.61 +{
  143.62 +	// nothing to do here
  143.63 +}
  143.64 +
  143.65 +// ------------------------------------------------------------------------------------------------
  143.66 +// Destructor, private as well
  143.67 +JoinVerticesProcess::~JoinVerticesProcess()
  143.68 +{
  143.69 +	// nothing to do here
  143.70 +}
  143.71 +
  143.72 +// ------------------------------------------------------------------------------------------------
  143.73 +// Returns whether the processing step is present in the given flag field.
  143.74 +bool JoinVerticesProcess::IsActive( unsigned int pFlags) const
  143.75 +{
  143.76 +	return (pFlags & aiProcess_JoinIdenticalVertices) != 0;
  143.77 +}
  143.78 +// ------------------------------------------------------------------------------------------------
  143.79 +// Executes the post processing step on the given imported data.
  143.80 +void JoinVerticesProcess::Execute( aiScene* pScene)
  143.81 +{
  143.82 +	DefaultLogger::get()->debug("JoinVerticesProcess begin");
  143.83 +
  143.84 +	// get the total number of vertices BEFORE the step is executed
  143.85 +	int iNumOldVertices = 0;
  143.86 +	if (!DefaultLogger::isNullLogger()) {
  143.87 +		for( unsigned int a = 0; a < pScene->mNumMeshes; a++)	{
  143.88 +			iNumOldVertices +=	pScene->mMeshes[a]->mNumVertices;
  143.89 +		}
  143.90 +	}
  143.91 +
  143.92 +	// execute the step
  143.93 +	int iNumVertices = 0;
  143.94 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
  143.95 +		iNumVertices +=	ProcessMesh( pScene->mMeshes[a],a);
  143.96 +
  143.97 +	// if logging is active, print detailed statistics
  143.98 +	if (!DefaultLogger::isNullLogger())
  143.99 +	{
 143.100 +		if (iNumOldVertices == iNumVertices)
 143.101 +		{
 143.102 +			DefaultLogger::get()->debug("JoinVerticesProcess finished ");
 143.103 +		} else
 143.104 +		{
 143.105 +			char szBuff[128]; // should be sufficiently large in every case
 143.106 +			sprintf(szBuff,"JoinVerticesProcess finished | Verts in: %i out: %i | ~%.1f%%",
 143.107 +				iNumOldVertices,
 143.108 +				iNumVertices,
 143.109 +				((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f);
 143.110 +			DefaultLogger::get()->info(szBuff);
 143.111 +		}
 143.112 +	}
 143.113 +
 143.114 +	pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
 143.115 +}
 143.116 +
 143.117 +// ------------------------------------------------------------------------------------------------
 143.118 +// Unites identical vertices in the given mesh
 143.119 +int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
 143.120 +{
 143.121 +	BOOST_STATIC_ASSERT( AI_MAX_NUMBER_OF_COLOR_SETS    == 8);
 143.122 +	BOOST_STATIC_ASSERT( AI_MAX_NUMBER_OF_TEXTURECOORDS == 8);
 143.123 +
 143.124 +	// Return early if we don't have any positions
 143.125 +	if (!pMesh->HasPositions() || !pMesh->HasFaces()) {
 143.126 +		return 0;
 143.127 +	}
 143.128 +
 143.129 +	// We'll never have more vertices afterwards.
 143.130 +	std::vector<Vertex> uniqueVertices;
 143.131 +	uniqueVertices.reserve( pMesh->mNumVertices);
 143.132 +
 143.133 +	// For each vertex the index of the vertex it was replaced by.
 143.134 +	// Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark
 143.135 +	//	whether a new vertex was created for the index (true) or if it was replaced by an existing
 143.136 +	//	unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
 143.137 +	//	branching performance.
 143.138 +	BOOST_STATIC_ASSERT(AI_MAX_VERTICES == 0x7fffffff);
 143.139 +	std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
 143.140 +
 143.141 +	// A little helper to find locally close vertices faster.
 143.142 +	// Try to reuse the lookup table from the last step.
 143.143 +	const static float epsilon = 1e-5f;
 143.144 +	// float posEpsilonSqr;
 143.145 +	SpatialSort* vertexFinder = NULL;
 143.146 +	SpatialSort _vertexFinder;
 143.147 +
 143.148 +	typedef std::pair<SpatialSort,float> SpatPair;
 143.149 +	if (shared)	{
 143.150 +		std::vector<SpatPair >* avf;
 143.151 +		shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
 143.152 +		if (avf)	{
 143.153 +			SpatPair& blubb = (*avf)[meshIndex];
 143.154 +			vertexFinder  = &blubb.first;
 143.155 +			// posEpsilonSqr = blubb.second;
 143.156 +		}
 143.157 +	}
 143.158 +	if (!vertexFinder)	{
 143.159 +		// bad, need to compute it.
 143.160 +		_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
 143.161 +		vertexFinder = &_vertexFinder; 
 143.162 +		// posEpsilonSqr = ComputePositionEpsilon(pMesh);
 143.163 +	}
 143.164 +
 143.165 +	// Squared because we check against squared length of the vector difference
 143.166 +	static const float squareEpsilon = epsilon * epsilon;
 143.167 +
 143.168 +	// Again, better waste some bytes than a realloc ...
 143.169 +	std::vector<unsigned int> verticesFound;
 143.170 +	verticesFound.reserve(10);
 143.171 +
 143.172 +	// Run an optimized code path if we don't have multiple UVs or vertex colors.
 143.173 +	// This should yield false in more than 99% of all imports ...
 143.174 +	const bool complex = ( pMesh->GetNumColorChannels() > 0 || pMesh->GetNumUVChannels() > 1);
 143.175 +
 143.176 +	// Now check each vertex if it brings something new to the table
 143.177 +	for( unsigned int a = 0; a < pMesh->mNumVertices; a++)	{
 143.178 +		// collect the vertex data
 143.179 +		Vertex v(pMesh,a);
 143.180 +
 143.181 +		// collect all vertices that are close enough to the given position
 143.182 +		vertexFinder->FindIdenticalPositions( v.position, verticesFound);
 143.183 +		unsigned int matchIndex = 0xffffffff;
 143.184 +
 143.185 +		// check all unique vertices close to the position if this vertex is already present among them
 143.186 +		for( unsigned int b = 0; b < verticesFound.size(); b++)	{
 143.187 +
 143.188 +			const unsigned int vidx = verticesFound[b];
 143.189 +			const unsigned int uidx = replaceIndex[ vidx];
 143.190 +			if( uidx & 0x80000000)
 143.191 +				continue;
 143.192 +
 143.193 +			const Vertex& uv = uniqueVertices[ uidx];
 143.194 +			// Position mismatch is impossible - the vertex finder already discarded all non-matching positions
 143.195 +
 143.196 +			// We just test the other attributes even if they're not present in the mesh.
 143.197 +			// In this case they're initialized to 0 so the comparision succeeds. 
 143.198 +			// By this method the non-present attributes are effectively ignored in the comparision.
 143.199 +			if( (uv.normal - v.normal).SquareLength() > squareEpsilon)
 143.200 +				continue;
 143.201 +			if( (uv.texcoords[0] - v.texcoords[0]).SquareLength() > squareEpsilon)
 143.202 +				continue;
 143.203 +			if( (uv.tangent - v.tangent).SquareLength() > squareEpsilon)
 143.204 +				continue;
 143.205 +			if( (uv.bitangent - v.bitangent).SquareLength() > squareEpsilon)
 143.206 +				continue;
 143.207 +
 143.208 +			// Usually we won't have vertex colors or multiple UVs, so we can skip from here
 143.209 +			// Actually this increases runtime performance slightly, at least if branch
 143.210 +			// prediction is on our side.
 143.211 +			if (complex){
 143.212 +				// manually unrolled because continue wouldn't work as desired in an inner loop, 
 143.213 +				// also because some compilers seem to fail the task. Colors and UV coords
 143.214 +				// are interleaved since the higher entries are most likely to be
 143.215 +				// zero and thus useless. By interleaving the arrays, vertices are,
 143.216 +				// on average, rejected earlier.
 143.217 +
 143.218 +				if( (uv.texcoords[1] - v.texcoords[1]).SquareLength() > squareEpsilon)
 143.219 +					continue;
 143.220 +				if( GetColorDifference( uv.colors[0], v.colors[0]) > squareEpsilon)
 143.221 +					continue;
 143.222 +
 143.223 +				if( (uv.texcoords[2] - v.texcoords[2]).SquareLength() > squareEpsilon)
 143.224 +					continue;
 143.225 +				if( GetColorDifference( uv.colors[1], v.colors[1]) > squareEpsilon)
 143.226 +					continue;
 143.227 +
 143.228 +				if( (uv.texcoords[3] - v.texcoords[3]).SquareLength() > squareEpsilon)
 143.229 +					continue;
 143.230 +				if( GetColorDifference( uv.colors[2], v.colors[2]) > squareEpsilon)
 143.231 +					continue;
 143.232 +
 143.233 +				if( (uv.texcoords[4] - v.texcoords[4]).SquareLength() > squareEpsilon)
 143.234 +					continue;
 143.235 +				if( GetColorDifference( uv.colors[3], v.colors[3]) > squareEpsilon)
 143.236 +					continue;
 143.237 +
 143.238 +				if( (uv.texcoords[5] - v.texcoords[5]).SquareLength() > squareEpsilon)
 143.239 +					continue;
 143.240 +				if( GetColorDifference( uv.colors[4], v.colors[4]) > squareEpsilon)
 143.241 +					continue;
 143.242 +
 143.243 +				if( (uv.texcoords[6] - v.texcoords[6]).SquareLength() > squareEpsilon)
 143.244 +					continue;
 143.245 +				if( GetColorDifference( uv.colors[5], v.colors[5]) > squareEpsilon)
 143.246 +					continue;
 143.247 +
 143.248 +				if( (uv.texcoords[7] - v.texcoords[7]).SquareLength() > squareEpsilon)
 143.249 +					continue;
 143.250 +				if( GetColorDifference( uv.colors[6], v.colors[6]) > squareEpsilon)
 143.251 +					continue;
 143.252 +				
 143.253 +				if( GetColorDifference( uv.colors[7], v.colors[7]) > squareEpsilon)
 143.254 +					continue;
 143.255 +			}
 143.256 +
 143.257 +			// we're still here -> this vertex perfectly matches our given vertex
 143.258 +			matchIndex = uidx;
 143.259 +			break;
 143.260 +		}
 143.261 +
 143.262 +		// found a replacement vertex among the uniques?
 143.263 +		if( matchIndex != 0xffffffff)
 143.264 +		{
 143.265 +			// store where to found the matching unique vertex
 143.266 +			replaceIndex[a] = matchIndex | 0x80000000;
 143.267 +		}
 143.268 +		else
 143.269 +		{
 143.270 +			// no unique vertex matches it upto now -> so add it
 143.271 +			replaceIndex[a] = (unsigned int)uniqueVertices.size();
 143.272 +			uniqueVertices.push_back( v);
 143.273 +		}
 143.274 +	}
 143.275 +
 143.276 +	if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE)	{
 143.277 +		DefaultLogger::get()->debug((Formatter::format(),
 143.278 +			"Mesh ",meshIndex,
 143.279 +			" (",
 143.280 +			(pMesh->mName.length ? pMesh->mName.data : "unnamed"),
 143.281 +			") | Verts in: ",pMesh->mNumVertices,
 143.282 +			" out: ",
 143.283 +			uniqueVertices.size(),
 143.284 +			" | ~",
 143.285 +			((pMesh->mNumVertices - uniqueVertices.size()) / (float)pMesh->mNumVertices) * 100.f,
 143.286 +			"%"
 143.287 +		));
 143.288 +	}
 143.289 +
 143.290 +	// replace vertex data with the unique data sets
 143.291 +	pMesh->mNumVertices = (unsigned int)uniqueVertices.size();
 143.292 +
 143.293 +	// ----------------------------------------------------------------------------
 143.294 +	// NOTE - we're *not* calling Vertex::SortBack() because it would check for 
 143.295 +	// presence of every single vertex component once PER VERTEX. And our CPU 
 143.296 +	// dislikes branches, even if they're easily predictable.
 143.297 +	// ----------------------------------------------------------------------------
 143.298 +
 143.299 +	// Position
 143.300 +	delete [] pMesh->mVertices;
 143.301 +	pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
 143.302 +	for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
 143.303 +		pMesh->mVertices[a] = uniqueVertices[a].position;
 143.304 +
 143.305 +	// Normals, if present
 143.306 +	if( pMesh->mNormals)
 143.307 +	{
 143.308 +		delete [] pMesh->mNormals;
 143.309 +		pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
 143.310 +		for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
 143.311 +			pMesh->mNormals[a] = uniqueVertices[a].normal;
 143.312 +		}
 143.313 +	}
 143.314 +	// Tangents, if present
 143.315 +	if( pMesh->mTangents)
 143.316 +	{
 143.317 +		delete [] pMesh->mTangents;
 143.318 +		pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
 143.319 +		for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
 143.320 +			pMesh->mTangents[a] = uniqueVertices[a].tangent;
 143.321 +		}
 143.322 +	}
 143.323 +	// Bitangents as well
 143.324 +	if( pMesh->mBitangents)
 143.325 +	{
 143.326 +		delete [] pMesh->mBitangents;
 143.327 +		pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
 143.328 +		for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
 143.329 +			pMesh->mBitangents[a] = uniqueVertices[a].bitangent;
 143.330 +		}
 143.331 +	}
 143.332 +	// Vertex colors
 143.333 +	for( unsigned int a = 0; pMesh->HasVertexColors(a); a++)
 143.334 +	{
 143.335 +		delete [] pMesh->mColors[a];
 143.336 +		pMesh->mColors[a] = new aiColor4D[pMesh->mNumVertices];
 143.337 +		for( unsigned int b = 0; b < pMesh->mNumVertices; b++) {
 143.338 +			pMesh->mColors[a][b] = uniqueVertices[b].colors[a];
 143.339 +		}
 143.340 +	}
 143.341 +	// Texture coords
 143.342 +	for( unsigned int a = 0; pMesh->HasTextureCoords(a); a++)
 143.343 +	{
 143.344 +		delete [] pMesh->mTextureCoords[a];
 143.345 +		pMesh->mTextureCoords[a] = new aiVector3D[pMesh->mNumVertices];
 143.346 +		for( unsigned int b = 0; b < pMesh->mNumVertices; b++) {
 143.347 +			pMesh->mTextureCoords[a][b] = uniqueVertices[b].texcoords[a];
 143.348 +		}
 143.349 +	}
 143.350 +
 143.351 +	// adjust the indices in all faces
 143.352 +	for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
 143.353 +	{
 143.354 +		aiFace& face = pMesh->mFaces[a];
 143.355 +		for( unsigned int b = 0; b < face.mNumIndices; b++)	{
 143.356 +			face.mIndices[b] = replaceIndex[face.mIndices[b]] & ~0x80000000;
 143.357 +		}
 143.358 +	}
 143.359 +
 143.360 +	// adjust bone vertex weights.
 143.361 +	for( int a = 0; a < (int)pMesh->mNumBones; a++)
 143.362 +	{
 143.363 +		aiBone* bone = pMesh->mBones[a];
 143.364 +		std::vector<aiVertexWeight> newWeights;
 143.365 +		newWeights.reserve( bone->mNumWeights);
 143.366 +
 143.367 +		for( unsigned int b = 0; b < bone->mNumWeights; b++)
 143.368 +		{
 143.369 +			const aiVertexWeight& ow = bone->mWeights[b];
 143.370 +			// if the vertex is a unique one, translate it
 143.371 +			if( !(replaceIndex[ow.mVertexId] & 0x80000000))
 143.372 +			{
 143.373 +				aiVertexWeight nw;
 143.374 +				nw.mVertexId = replaceIndex[ow.mVertexId];
 143.375 +				nw.mWeight = ow.mWeight;
 143.376 +				newWeights.push_back( nw);
 143.377 +			}
 143.378 +		}
 143.379 +
 143.380 +		if (newWeights.size() > 0) {
 143.381 +			// kill the old and replace them with the translated weights
 143.382 +			delete [] bone->mWeights;
 143.383 +			bone->mNumWeights = (unsigned int)newWeights.size();
 143.384 +
 143.385 +			bone->mWeights = new aiVertexWeight[bone->mNumWeights];
 143.386 +			memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight));
 143.387 +		}
 143.388 +		else {
 143.389 +		
 143.390 +			/*  NOTE:
 143.391 +			 *
 143.392 +			 *  In the algorithm above we're assuming that there are no vertices
 143.393 +			 *  with a different bone weight setup at the same position. That wouldn't
 143.394 +			 *  make sense, but it is not absolutely impossible. SkeletonMeshBuilder
 143.395 +			 *  for example generates such input data if two skeleton points
 143.396 +			 *  share the same position. Again this doesn't make sense but is
 143.397 +			 *  reality for some model formats (MD5 for example uses these special
 143.398 +			 *  nodes as attachment tags for its weapons). 
 143.399 +			 *
 143.400 +			 *  Then it is possible that a bone has no weights anymore .... as a quick
 143.401 +			 *  workaround, we're just removing these bones. If they're animated,
 143.402 +			 *  model geometry might be modified but at least there's no risk of a crash.
 143.403 +			 */
 143.404 +			delete bone;
 143.405 +			--pMesh->mNumBones;
 143.406 +			for (unsigned int n = a; n < pMesh->mNumBones; ++n)  {
 143.407 +				pMesh->mBones[n] = pMesh->mBones[n+1];
 143.408 +			}
 143.409 +
 143.410 +			--a; 
 143.411 +			DefaultLogger::get()->warn("Removing bone -> no weights remaining");
 143.412 +		}
 143.413 +	}
 143.414 +	return pMesh->mNumVertices;
 143.415 +}
 143.416 +
 143.417 +#endif // !! ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
   144.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   144.2 +++ b/libs/assimp/JoinVerticesProcess.h	Sat Feb 01 19:58:19 2014 +0200
   144.3 @@ -0,0 +1,98 @@
   144.4 +/*
   144.5 +Open Asset Import Library (assimp)
   144.6 +----------------------------------------------------------------------
   144.7 +
   144.8 +Copyright (c) 2006-2012, assimp team
   144.9 +All rights reserved.
  144.10 +
  144.11 +Redistribution and use of this software in source and binary forms, 
  144.12 +with or without modification, are permitted provided that the 
  144.13 +following conditions are met:
  144.14 +
  144.15 +* Redistributions of source code must retain the above
  144.16 +  copyright notice, this list of conditions and the
  144.17 +  following disclaimer.
  144.18 +
  144.19 +* Redistributions in binary form must reproduce the above
  144.20 +  copyright notice, this list of conditions and the
  144.21 +  following disclaimer in the documentation and/or other
  144.22 +  materials provided with the distribution.
  144.23 +
  144.24 +* Neither the name of the assimp team, nor the names of its
  144.25 +  contributors may be used to endorse or promote products
  144.26 +  derived from this software without specific prior
  144.27 +  written permission of the assimp team.
  144.28 +
  144.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  144.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  144.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  144.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  144.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  144.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  144.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  144.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  144.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  144.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  144.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  144.40 +
  144.41 +----------------------------------------------------------------------
  144.42 +*/
  144.43 +
  144.44 +/** @file Defines a post processing step to join identical vertices 
  144.45 +    on all imported meshes.*/
  144.46 +#ifndef AI_JOINVERTICESPROCESS_H_INC
  144.47 +#define AI_JOINVERTICESPROCESS_H_INC
  144.48 +
  144.49 +#include "BaseProcess.h"
  144.50 +#include "assimp/types.h"
  144.51 +
  144.52 +namespace Assimp
  144.53 +{
  144.54 +
  144.55 +class JoinVerticesTest;
  144.56 +
  144.57 +// ---------------------------------------------------------------------------
  144.58 +/** The JoinVerticesProcess unites identical vertices in all imported meshes. 
  144.59 + * By default the importer returns meshes where each face addressed its own 
  144.60 + * set of vertices even if that means that identical vertices are stored multiple
  144.61 + * times. The JoinVerticesProcess finds these identical vertices and 
  144.62 + * erases all but one of the copies. This usually reduces the number of vertices
  144.63 + * in a mesh by a serious amount and is the standard form to render a mesh.
  144.64 + */
  144.65 +class ASSIMP_API_WINONLY JoinVerticesProcess : public BaseProcess
  144.66 +{
  144.67 +public:
  144.68 +
  144.69 +	JoinVerticesProcess();
  144.70 +	~JoinVerticesProcess();
  144.71 +
  144.72 +public:
  144.73 +	// -------------------------------------------------------------------
  144.74 +	/** Returns whether the processing step is present in the given flag field.
  144.75 +	 * @param pFlags The processing flags the importer was called with. A bitwise
  144.76 +	 *   combination of #aiPostProcessSteps.
  144.77 +	 * @return true if the process is present in this flag fields, false if not.
  144.78 +	*/
  144.79 +	bool IsActive( unsigned int pFlags) const;
  144.80 +
  144.81 +	// -------------------------------------------------------------------
  144.82 +	/** Executes the post processing step on the given imported data.
  144.83 +	* At the moment a process is not supposed to fail.
  144.84 +	* @param pScene The imported data to work at.
  144.85 +	*/
  144.86 +	void Execute( aiScene* pScene);
  144.87 +
  144.88 +public:
  144.89 +	// -------------------------------------------------------------------
  144.90 +	/** Unites identical vertices in the given mesh.
  144.91 +	 * @param pMesh The mesh to process.
  144.92 +	 * @param meshIndex Index of the mesh to process
  144.93 +	 */
  144.94 +	int ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
  144.95 +
  144.96 +private:
  144.97 +};
  144.98 +
  144.99 +} // end of namespace Assimp
 144.100 +
 144.101 +#endif // AI_CALCTANGENTSPROCESS_H_INC
   145.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   145.2 +++ b/libs/assimp/LWOAnimation.cpp	Sat Feb 01 19:58:19 2014 +0200
   145.3 @@ -0,0 +1,594 @@
   145.4 +/*
   145.5 +Open Asset Import Library (assimp)
   145.6 +----------------------------------------------------------------------
   145.7 +
   145.8 +Copyright (c) 2006-2012, assimp team
   145.9 +All rights reserved.
  145.10 +
  145.11 +Redistribution and use of this software in source and binary forms, 
  145.12 +with or without modification, are permitted provided that the 
  145.13 +following conditions are met:
  145.14 +
  145.15 +* Redistributions of source code must retain the above
  145.16 +  copyright notice, this list of conditions and the
  145.17 +  following disclaimer.
  145.18 +
  145.19 +* Redistributions in binary form must reproduce the above
  145.20 +  copyright notice, this list of conditions and the
  145.21 +  following disclaimer in the documentation and/or other
  145.22 +  materials provided with the distribution.
  145.23 +
  145.24 +* Neither the name of the assimp team, nor the names of its
  145.25 +  contributors may be used to endorse or promote products
  145.26 +  derived from this software without specific prior
  145.27 +  written permission of the assimp team.
  145.28 +
  145.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  145.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  145.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  145.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  145.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  145.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  145.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  145.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  145.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  145.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  145.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  145.40 +
  145.41 +----------------------------------------------------------------------
  145.42 +*/
  145.43 +
  145.44 +/** @file  LWOAnimation.cpp
  145.45 + *  @brief LWOAnimationResolver utility class 
  145.46 + *
  145.47 + *  It's a very generic implementation of LightWave's system of
  145.48 + *  componentwise-animated stuff. The one and only fully free
  145.49 + *  implementation of LightWave envelopes of which I know.
  145.50 +*/
  145.51 +
  145.52 +#include "AssimpPCH.h"
  145.53 +#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER) && (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
  145.54 +
  145.55 +#include <functional>
  145.56 +
  145.57 +// internal headers
  145.58 +#include "LWOFileData.h"
  145.59 +
  145.60 +using namespace Assimp;
  145.61 +using namespace Assimp::LWO;
  145.62 +
  145.63 +// ------------------------------------------------------------------------------------------------
  145.64 +// Construct an animation resolver from a given list of envelopes
  145.65 +AnimResolver::AnimResolver(std::list<Envelope>& _envelopes,double tick)
  145.66 +	: envelopes   (_envelopes)
  145.67 +	, sample_rate (0.)
  145.68 +{
  145.69 +	trans_x = trans_y = trans_z = NULL;
  145.70 +	rotat_x = rotat_y = rotat_z = NULL;
  145.71 +	scale_x = scale_y = scale_z = NULL;
  145.72 +
  145.73 +	first = last = 150392.;
  145.74 +
  145.75 +	// find transformation envelopes
  145.76 +	for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
  145.77 +
  145.78 +		(*it).old_first = 0;
  145.79 +		(*it).old_last  = (*it).keys.size()-1;
  145.80 +
  145.81 +		if ((*it).keys.empty()) continue;
  145.82 +		switch ((*it).type) {
  145.83 +
  145.84 +			// translation
  145.85 +			case LWO::EnvelopeType_Position_X:
  145.86 +				trans_x = &*it;break;
  145.87 +			case LWO::EnvelopeType_Position_Y:
  145.88 +				trans_y = &*it;break;
  145.89 +			case LWO::EnvelopeType_Position_Z:
  145.90 +				trans_z = &*it;break;
  145.91 +
  145.92 +				// rotation
  145.93 +			case LWO::EnvelopeType_Rotation_Heading:
  145.94 +				rotat_x = &*it;break;
  145.95 +			case LWO::EnvelopeType_Rotation_Pitch:
  145.96 +				rotat_y = &*it;break;
  145.97 +			case LWO::EnvelopeType_Rotation_Bank:
  145.98 +				rotat_z = &*it;break;
  145.99 +
 145.100 +				// scaling
 145.101 +			case LWO::EnvelopeType_Scaling_X:
 145.102 +				scale_x = &*it;break;
 145.103 +			case LWO::EnvelopeType_Scaling_Y:
 145.104 +				scale_y = &*it;break;
 145.105 +			case LWO::EnvelopeType_Scaling_Z:
 145.106 +				scale_z = &*it;break;
 145.107 +			default:
 145.108 +				continue;
 145.109 +		};
 145.110 +
 145.111 +		// convert from seconds to ticks
 145.112 +		for (std::vector<LWO::Key>::iterator d = (*it).keys.begin(); d != (*it).keys.end(); ++d)
 145.113 +			(*d).time *= tick;
 145.114 +
 145.115 +		// set default animation range (minimum and maximum time value for which we have a keyframe)
 145.116 +		first = std::min(first, (*it).keys.front().time );
 145.117 +		last  = std::max(last,  (*it).keys.back().time );
 145.118 +	}
 145.119 +
 145.120 +	// deferred setup of animation range to increase performance.
 145.121 +	// typically the application will want to specify its own.
 145.122 +	need_to_setup = true;
 145.123 +}
 145.124 +
 145.125 +// ------------------------------------------------------------------------------------------------
 145.126 +// Reset all envelopes to their original contents
 145.127 +void AnimResolver::ClearAnimRangeSetup()
 145.128 +{
 145.129 +	for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
 145.130 +		
 145.131 +		(*it).keys.erase((*it).keys.begin(),(*it).keys.begin()+(*it).old_first);
 145.132 +		(*it).keys.erase((*it).keys.begin()+(*it).old_last+1,(*it).keys.end());
 145.133 +	}
 145.134 +}
 145.135 +
 145.136 +// ------------------------------------------------------------------------------------------------
 145.137 +// Insert additional keys to match LWO's pre& post behaviours.
 145.138 +void AnimResolver::UpdateAnimRangeSetup()
 145.139 +{
 145.140 +	// XXX doesn't work yet (hangs if more than one envelope channels needs to be interpolated)
 145.141 +
 145.142 +	for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
 145.143 +		if ((*it).keys.empty()) continue;
 145.144 +	
 145.145 +		const double my_first = (*it).keys.front().time;
 145.146 +		const double my_last  = (*it).keys.back().time;
 145.147 +
 145.148 +		const double delta = my_last-my_first;
 145.149 +		const size_t old_size = (*it).keys.size();
 145.150 +
 145.151 +		const float value_delta = (*it).keys.back().value - (*it).keys.front().value; 
 145.152 +
 145.153 +		// NOTE: We won't handle reset, linear and constant here.
 145.154 +		// See DoInterpolation() for their implementation.
 145.155 +
 145.156 +		// process pre behaviour
 145.157 +		switch ((*it).pre) {
 145.158 +			case LWO::PrePostBehaviour_OffsetRepeat:
 145.159 +			case LWO::PrePostBehaviour_Repeat:
 145.160 +			case LWO::PrePostBehaviour_Oscillate:
 145.161 +				{
 145.162 +				const double start_time = delta - fmod(my_first-first,delta);
 145.163 +				std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(),(*it).keys.end(), 
 145.164 +					std::bind1st(std::greater<double>(),start_time)),m;
 145.165 +
 145.166 +				size_t ofs = 0;
 145.167 +				if (n != (*it).keys.end()) {
 145.168 +					// copy from here - don't use iterators, insert() would invalidate them
 145.169 +					ofs = (*it).keys.end()-n;
 145.170 +					(*it).keys.insert((*it).keys.begin(),ofs,LWO::Key());
 145.171 +
 145.172 +					std::copy((*it).keys.end()-ofs,(*it).keys.end(),(*it).keys.begin());
 145.173 +				}
 145.174 +
 145.175 +				// do full copies. again, no iterators
 145.176 +				const unsigned int num = (unsigned int)((my_first-first) / delta);
 145.177 +				(*it).keys.resize((*it).keys.size() + num*old_size);
 145.178 +
 145.179 +				n = (*it).keys.begin()+ofs;
 145.180 +				bool reverse = false;
 145.181 +				for (unsigned int i = 0; i < num; ++i) {
 145.182 +					m = n+old_size*(i+1);
 145.183 +					std::copy(n,n+old_size,m);
 145.184 +
 145.185 +					if ((*it).pre == LWO::PrePostBehaviour_Oscillate && (reverse = !reverse))
 145.186 +						std::reverse(m,m+old_size-1);
 145.187 +				}
 145.188 +
 145.189 +				// update time values 
 145.190 +				n = (*it).keys.end() - (old_size+1);
 145.191 +				double cur_minus = delta;
 145.192 +				unsigned int tt = 1;
 145.193 +				for (const double tmp =  delta*(num+1);cur_minus <= tmp;cur_minus += delta,++tt) {
 145.194 +					m = (delta == tmp ? (*it).keys.begin() :  n - (old_size+1));
 145.195 +					for (;m != n; --n) {
 145.196 +						(*n).time -= cur_minus;
 145.197 +					
 145.198 +						// offset repeat? add delta offset to key value
 145.199 +						if ((*it).pre == LWO::PrePostBehaviour_OffsetRepeat) {
 145.200 +							(*n).value += tt * value_delta;
 145.201 +						}
 145.202 +					}
 145.203 +				}
 145.204 +				break;
 145.205 +				}
 145.206 +			default:
 145.207 +				// silence compiler warning
 145.208 +				break;
 145.209 +		}
 145.210 +
 145.211 +		// process post behaviour
 145.212 +		switch ((*it).post) {
 145.213 +			
 145.214 +			case LWO::PrePostBehaviour_OffsetRepeat:
 145.215 +			case LWO::PrePostBehaviour_Repeat:
 145.216 +			case LWO::PrePostBehaviour_Oscillate:
 145.217 +
 145.218 +				break;
 145.219 +
 145.220 +			default:
 145.221 +				// silence compiler warning
 145.222 +				break;
 145.223 +		}
 145.224 +	}
 145.225 +}
 145.226 +
 145.227 +// ------------------------------------------------------------------------------------------------
 145.228 +// Extract bind pose matrix
 145.229 +void AnimResolver::ExtractBindPose(aiMatrix4x4& out)
 145.230 +{
 145.231 +	// If we have no envelopes, return identity
 145.232 +	if (envelopes.empty()) {
 145.233 +		out = aiMatrix4x4();
 145.234 +		return;
 145.235 +	}
 145.236 +	aiVector3D angles, scaling(1.f,1.f,1.f), translation;
 145.237 +
 145.238 +	if (trans_x) translation.x = trans_x->keys[0].value;
 145.239 +	if (trans_y) translation.y = trans_y->keys[0].value;
 145.240 +	if (trans_z) translation.z = trans_z->keys[0].value;
 145.241 +
 145.242 +	if (rotat_x) angles.x = rotat_x->keys[0].value;
 145.243 +	if (rotat_y) angles.y = rotat_y->keys[0].value;
 145.244 +	if (rotat_z) angles.z = rotat_z->keys[0].value;
 145.245 +
 145.246 +	if (scale_x) scaling.x = scale_x->keys[0].value;
 145.247 +	if (scale_y) scaling.y = scale_y->keys[0].value;
 145.248 +	if (scale_z) scaling.z = scale_z->keys[0].value;
 145.249 +
 145.250 +	// build the final matrix
 145.251 +	aiMatrix4x4 s,rx,ry,rz,t;
 145.252 +	aiMatrix4x4::RotationZ(angles.z, rz);
 145.253 +	aiMatrix4x4::RotationX(angles.y, rx);
 145.254 +	aiMatrix4x4::RotationY(angles.x, ry);
 145.255 +	aiMatrix4x4::Translation(translation,t);
 145.256 +	aiMatrix4x4::Scaling(scaling,s);
 145.257 +	out = t*ry*rx*rz*s;
 145.258 +}
 145.259 +
 145.260 +// ------------------------------------------------------------------------------------------------
 145.261 +// Do a single interpolation on a channel 
 145.262 +void AnimResolver::DoInterpolation(std::vector<LWO::Key>::const_iterator cur, 
 145.263 +	LWO::Envelope* envl,double time, float& fill)
 145.264 +{
 145.265 +	if (envl->keys.size() == 1) {
 145.266 +		fill = envl->keys[0].value;
 145.267 +		return;
 145.268 +	}
 145.269 +
 145.270 +	// check whether we're at the beginning of the animation track
 145.271 +	if (cur == envl->keys.begin()) {
 145.272 +	
 145.273 +		// ok ... this depends on pre behaviour now
 145.274 +		// we don't need to handle repeat&offset repeat&oszillate here, see UpdateAnimRangeSetup()
 145.275 +		switch (envl->pre)
 145.276 +		{
 145.277 +		case LWO::PrePostBehaviour_Linear:
 145.278 +			DoInterpolation2(cur,cur+1,time,fill);
 145.279 +			return;
 145.280 +
 145.281 +		case LWO::PrePostBehaviour_Reset:
 145.282 +			fill = 0.f;
 145.283 +			return;
 145.284 +
 145.285 +		default : //case LWO::PrePostBehaviour_Constant:
 145.286 +			fill = (*cur).value;
 145.287 +			return;
 145.288 +		}
 145.289 +	}
 145.290 +	// check whether we're at the end of the animation track
 145.291 +	else if (cur == envl->keys.end()-1 && time > envl->keys.rbegin()->time) {
 145.292 +		// ok ... this depends on post behaviour now
 145.293 +		switch (envl->post)
 145.294 +		{
 145.295 +		case LWO::PrePostBehaviour_Linear:
 145.296 +			DoInterpolation2(cur,cur-1,time,fill);
 145.297 +			return;
 145.298 +
 145.299 +		case LWO::PrePostBehaviour_Reset:
 145.300 +			fill = 0.f;
 145.301 +			return;
 145.302 +
 145.303 +		default : //case LWO::PrePostBehaviour_Constant:
 145.304 +			fill = (*cur).value;
 145.305 +			return;
 145.306 +		}
 145.307 +	}
 145.308 +
 145.309 +	// Otherwise do a simple interpolation
 145.310 +	DoInterpolation2(cur-1,cur,time,fill);
 145.311 +}
 145.312 +
 145.313 +// ------------------------------------------------------------------------------------------------
 145.314 +// Almost the same, except we won't handle pre/post conditions here
 145.315 +void AnimResolver::DoInterpolation2(std::vector<LWO::Key>::const_iterator beg, 
 145.316 +	std::vector<LWO::Key>::const_iterator end,double time, float& fill)
 145.317 +{
 145.318 +	switch ((*end).inter) {
 145.319 +		
 145.320 +		case LWO::IT_STEP:
 145.321 +			// no interpolation at all - take the value of the last key
 145.322 +			fill = (*beg).value;
 145.323 +			return;
 145.324 +		default:
 145.325 +
 145.326 +			// silence compiler warning
 145.327 +			break;
 145.328 +	}
 145.329 +	// linear interpolation - default
 145.330 +	fill = (*beg).value + ((*end).value - (*beg).value)*(float)(((time - (*beg).time) / ((*end).time - (*beg).time)));
 145.331 +}
 145.332 +
 145.333 +// ------------------------------------------------------------------------------------------------
 145.334 +// Subsample animation track by given key values
 145.335 +void AnimResolver::SubsampleAnimTrack(std::vector<aiVectorKey>& /*out*/,
 145.336 +	double /*time*/ ,double /*sample_delta*/ )
 145.337 +{
 145.338 +	//ai_assert(out.empty() && sample_delta);
 145.339 +
 145.340 +	//const double time_start = out.back().mTime;
 145.341 +//	for ()
 145.342 +}
 145.343 +
 145.344 +// ------------------------------------------------------------------------------------------------
 145.345 +// Track interpolation
 145.346 +void AnimResolver::InterpolateTrack(std::vector<aiVectorKey>& out,aiVectorKey& fill,double time)
 145.347 +{
 145.348 +	// subsample animation track?
 145.349 +	if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
 145.350 +		SubsampleAnimTrack(out,time, sample_delta);
 145.351 +	}
 145.352 +
 145.353 +	fill.mTime = time;
 145.354 +
 145.355 +	// get x
 145.356 +	if ((*cur_x).time == time) {
 145.357 +		fill.mValue.x = (*cur_x).value;
 145.358 +
 145.359 +		if (cur_x != envl_x->keys.end()-1) /* increment x */
 145.360 +			++cur_x;
 145.361 +		else end_x = true;
 145.362 +	}
 145.363 +	else DoInterpolation(cur_x,envl_x,time,(float&)fill.mValue.x);
 145.364 +
 145.365 +	// get y
 145.366 +	if ((*cur_y).time == time) {
 145.367 +		fill.mValue.y = (*cur_y).value;
 145.368 +
 145.369 +		if (cur_y != envl_y->keys.end()-1) /* increment y */
 145.370 +			++cur_y;
 145.371 +		else end_y = true;
 145.372 +	}
 145.373 +	else DoInterpolation(cur_y,envl_y,time,(float&)fill.mValue.y);
 145.374 +
 145.375 +	// get z
 145.376 +	if ((*cur_z).time == time) {
 145.377 +		fill.mValue.z = (*cur_z).value;
 145.378 +
 145.379 +		if (cur_z != envl_z->keys.end()-1) /* increment z */
 145.380 +			++cur_z;
 145.381 +		else end_x = true;
 145.382 +	}
 145.383 +	else DoInterpolation(cur_z,envl_z,time,(float&)fill.mValue.z);
 145.384 +}
 145.385 +
 145.386 +// ------------------------------------------------------------------------------------------------
 145.387 +// Build linearly subsampled keys from three single envelopes, one for each component (x,y,z)
 145.388 +void AnimResolver::GetKeys(std::vector<aiVectorKey>& out, 
 145.389 +	LWO::Envelope* _envl_x,
 145.390 +	LWO::Envelope* _envl_y,
 145.391 +	LWO::Envelope* _envl_z,
 145.392 +	unsigned int _flags)
 145.393 +{
 145.394 +	envl_x = _envl_x;
 145.395 +	envl_y = _envl_y;
 145.396 +	envl_z = _envl_z;
 145.397 +	flags  = _flags;
 145.398 +
 145.399 +	// generate default channels if none are given
 145.400 +	LWO::Envelope def_x, def_y, def_z;
 145.401 +	LWO::Key key_dummy;
 145.402 +	key_dummy.time = 0.f;
 145.403 +	if ((envl_x && envl_x->type == LWO::EnvelopeType_Scaling_X) ||
 145.404 +		(envl_y && envl_y->type == LWO::EnvelopeType_Scaling_Y) || 
 145.405 +		(envl_z && envl_z->type == LWO::EnvelopeType_Scaling_Z)) {
 145.406 +		key_dummy.value = 1.f;
 145.407 +	}
 145.408 +	else key_dummy.value = 0.f;
 145.409 +
 145.410 +	if (!envl_x) {
 145.411 +		envl_x = &def_x;
 145.412 +		envl_x->keys.push_back(key_dummy);
 145.413 +	}
 145.414 +	if (!envl_y) {
 145.415 +		envl_y = &def_y;
 145.416 +		envl_y->keys.push_back(key_dummy);
 145.417 +	}
 145.418 +	if (!envl_z) {
 145.419 +		envl_z = &def_z;
 145.420 +		envl_z->keys.push_back(key_dummy);
 145.421 +	}
 145.422 +
 145.423 +	// guess how many keys we'll get
 145.424 +	size_t reserve;
 145.425 +	double sr = 1.;
 145.426 +	if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
 145.427 +		if (!sample_rate)
 145.428 +			sr = 100.f;
 145.429 +		else sr = sample_rate;
 145.430 +		sample_delta = 1.f / sr; 
 145.431 +
 145.432 +		reserve = (size_t)(
 145.433 +			std::max( envl_x->keys.rbegin()->time,
 145.434 +			std::max( envl_y->keys.rbegin()->time, envl_z->keys.rbegin()->time )) * sr);
 145.435 +	}
 145.436 +	else reserve = std::max(envl_x->keys.size(),std::max(envl_x->keys.size(),envl_z->keys.size()));
 145.437 +	out.reserve(reserve+(reserve>>1));
 145.438 +
 145.439 +	// Iterate through all three arrays at once - it's tricky, but 
 145.440 +	// rather interesting to implement.
 145.441 +	double lasttime = std::min(envl_x->keys[0].time,std::min(envl_y->keys[0].time,envl_z->keys[0].time));
 145.442 +	
 145.443 +	cur_x = envl_x->keys.begin();
 145.444 +	cur_y = envl_y->keys.begin();
 145.445 +	cur_z = envl_z->keys.begin();
 145.446 +
 145.447 +	end_x = end_y = end_z = false;
 145.448 +	while (1) {
 145.449 +
 145.450 +		aiVectorKey fill;
 145.451 +
 145.452 +		if ((*cur_x).time == (*cur_y).time && (*cur_x).time == (*cur_z).time ) {
 145.453 +
 145.454 +			// we have a keyframe for all of them defined .. this means
 145.455 +			// we don't need to interpolate here.
 145.456 +			fill.mTime = (*cur_x).time;
 145.457 +
 145.458 +			fill.mValue.x = (*cur_x).value;
 145.459 +			fill.mValue.y = (*cur_y).value;
 145.460 +			fill.mValue.z = (*cur_z).value;
 145.461 +
 145.462 +			// subsample animation track
 145.463 +			if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
 145.464 +				//SubsampleAnimTrack(out,cur_x, cur_y, cur_z, d, sample_delta);
 145.465 +			}
 145.466 +		}
 145.467 +
 145.468 +		// Find key with lowest time value
 145.469 +		else if ((*cur_x).time <= (*cur_y).time && !end_x) {
 145.470 +
 145.471 +			if ((*cur_z).time <= (*cur_x).time && !end_z) {
 145.472 +				InterpolateTrack(out,fill,(*cur_z).time);
 145.473 +			}
 145.474 +			else {
 145.475 +				InterpolateTrack(out,fill,(*cur_x).time);
 145.476 +			}
 145.477 +		}
 145.478 +		else if ((*cur_z).time <= (*cur_y).time && !end_y)	{
 145.479 +			InterpolateTrack(out,fill,(*cur_y).time);
 145.480 +		}
 145.481 +		else if (!end_y) {
 145.482 +			// welcome on the server, y
 145.483 +			InterpolateTrack(out,fill,(*cur_y).time);
 145.484 +		}
 145.485 +		else {
 145.486 +			// we have reached the end of at least 2 channels,
 145.487 +			// only one is remaining. Extrapolate the 2.
 145.488 +			if (end_y) {
 145.489 +				InterpolateTrack(out,fill,(end_x ? (*cur_z) : (*cur_x)).time);
 145.490 +			}
 145.491 +			else if (end_x) {
 145.492 +				InterpolateTrack(out,fill,(end_z ? (*cur_y) : (*cur_z)).time);
 145.493 +			}
 145.494 +			else { // if (end_z) 
 145.495 +				InterpolateTrack(out,fill,(end_y ? (*cur_x) : (*cur_y)).time);
 145.496 +			}
 145.497 +		}
 145.498 +		lasttime = fill.mTime;
 145.499 +		out.push_back(fill);
 145.500 +
 145.501 +		if (lasttime >= (*cur_x).time) {
 145.502 +			if (cur_x != envl_x->keys.end()-1)
 145.503 +				++cur_x;
 145.504 +			else end_x = true;
 145.505 +		}
 145.506 +		if (lasttime >= (*cur_y).time) {
 145.507 +			if (cur_y != envl_y->keys.end()-1)
 145.508 +				++cur_y;
 145.509 +			else end_y = true;
 145.510 +		}
 145.511 +		if (lasttime >= (*cur_z).time) {
 145.512 +			if (cur_z != envl_z->keys.end()-1)
 145.513 +				++cur_z;
 145.514 +			else end_z = true;
 145.515 +		}
 145.516 +
 145.517 +		if( end_x && end_y && end_z ) /* finished? */
 145.518 +			break;
 145.519 +	}
 145.520 +
 145.521 +	if (flags & AI_LWO_ANIM_FLAG_START_AT_ZERO) {
 145.522 +		for (std::vector<aiVectorKey>::iterator it = out.begin(); it != out.end(); ++it)
 145.523 +			(*it).mTime -= first;
 145.524 +	}
 145.525 +}
 145.526 +
 145.527 +// ------------------------------------------------------------------------------------------------
 145.528 +// Extract animation channel
 145.529 +void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int flags /*= 0*/)
 145.530 +{
 145.531 +	*out = NULL;
 145.532 +
 145.533 +
 145.534 +	//FIXME: crashes if more than one component is animated at different timings, to be resolved.
 145.535 +	
 145.536 +	// If we have no envelopes, return NULL
 145.537 +	if (envelopes.empty()) {
 145.538 +		return;
 145.539 +	}
 145.540 +
 145.541 +	// We won't spawn an animation channel if we don't have at least one envelope with more than one keyframe defined.
 145.542 +	const bool trans = ((trans_x && trans_x->keys.size() > 1) || (trans_y && trans_y->keys.size() > 1) || (trans_z && trans_z->keys.size() > 1));
 145.543 +	const bool rotat = ((rotat_x && rotat_x->keys.size() > 1) || (rotat_y && rotat_y->keys.size() > 1) || (rotat_z && rotat_z->keys.size() > 1));
 145.544 +	const bool scale = ((scale_x && scale_x->keys.size() > 1) || (scale_y && scale_y->keys.size() > 1) || (scale_z && scale_z->keys.size() > 1));
 145.545 +	if (!trans && !rotat && !scale)
 145.546 +		return;
 145.547 +
 145.548 +	// Allocate the output animation 
 145.549 +	aiNodeAnim* anim = *out = new aiNodeAnim();
 145.550 +
 145.551 +	// Setup default animation setup if necessary
 145.552 +	if (need_to_setup) {
 145.553 +		UpdateAnimRangeSetup();
 145.554 +		need_to_setup = false;
 145.555 +	}
 145.556 +
 145.557 +	// copy translation keys
 145.558 +	if (trans) {
 145.559 +		std::vector<aiVectorKey> keys;
 145.560 +		GetKeys(keys,trans_x,trans_y,trans_z,flags);
 145.561 +
 145.562 +		anim->mPositionKeys = new aiVectorKey[ anim->mNumPositionKeys = keys.size() ];
 145.563 +		std::copy(keys.begin(),keys.end(),anim->mPositionKeys);
 145.564 +	}
 145.565 +
 145.566 +	// copy rotation keys
 145.567 +	if (rotat) {
 145.568 +		std::vector<aiVectorKey> keys;
 145.569 +		GetKeys(keys,rotat_x,rotat_y,rotat_z,flags);
 145.570 +
 145.571 +		anim->mRotationKeys = new aiQuatKey[ anim->mNumRotationKeys = keys.size() ];
 145.572 +		
 145.573 +		// convert heading, pitch, bank to quaternion
 145.574 +		// mValue.x=Heading=Rot(Y), mValue.y=Pitch=Rot(X), mValue.z=Bank=Rot(Z)
 145.575 +		// Lightwave's rotation order is ZXY
 145.576 +		aiVector3D X(1.0,0.0,0.0);
 145.577 +		aiVector3D Y(0.0,1.0,0.0);
 145.578 +		aiVector3D Z(0.0,0.0,1.0);
 145.579 +		for (unsigned int i = 0; i < anim->mNumRotationKeys; ++i) {
 145.580 +			aiQuatKey& qk = anim->mRotationKeys[i];
 145.581 +			qk.mTime  = keys[i].mTime;
 145.582 +			qk.mValue = aiQuaternion(Y,keys[i].mValue.x)*aiQuaternion(X,keys[i].mValue.y)*aiQuaternion(Z,keys[i].mValue.z);
 145.583 +		}
 145.584 +	}
 145.585 +
 145.586 +	// copy scaling keys
 145.587 +	if (scale) {
 145.588 +		std::vector<aiVectorKey> keys;
 145.589 +		GetKeys(keys,scale_x,scale_y,scale_z,flags);
 145.590 +
 145.591 +		anim->mScalingKeys = new aiVectorKey[ anim->mNumScalingKeys = keys.size() ];
 145.592 +		std::copy(keys.begin(),keys.end(),anim->mScalingKeys);
 145.593 +	}
 145.594 +}
 145.595 +
 145.596 +
 145.597 +#endif // no lwo or no lws
   146.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   146.2 +++ b/libs/assimp/LWOAnimation.h	Sat Feb 01 19:58:19 2014 +0200
   146.3 @@ -0,0 +1,336 @@
   146.4 +/*
   146.5 +Open Asset Import Library (assimp)
   146.6 +----------------------------------------------------------------------
   146.7 +
   146.8 +Copyright (c) 2006-2012, assimp team
   146.9 +All rights reserved.
  146.10 +
  146.11 +Redistribution and use of this software in source and binary forms, 
  146.12 +with or without modification, are permitted provided that the 
  146.13 +following conditions are met:
  146.14 +
  146.15 +* Redistributions of source code must retain the above
  146.16 +  copyright notice, this list of conditions and the
  146.17 +  following disclaimer.
  146.18 +
  146.19 +* Redistributions in binary form must reproduce the above
  146.20 +  copyright notice, this list of conditions and the
  146.21 +  following disclaimer in the documentation and/or other
  146.22 +  materials provided with the distribution.
  146.23 +
  146.24 +* Neither the name of the assimp team, nor the names of its
  146.25 +  contributors may be used to endorse or promote products
  146.26 +  derived from this software without specific prior
  146.27 +  written permission of the assimp team.
  146.28 +
  146.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  146.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  146.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  146.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  146.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  146.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  146.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  146.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  146.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  146.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  146.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  146.40 +
  146.41 +----------------------------------------------------------------------
  146.42 +*/
  146.43 +
  146.44 +/** @file  LWOAnimation.h
  146.45 + *  @brief LWOAnimationResolver utility class 
  146.46 + *
  146.47 + *  This is for all lightwave-related file format, not only LWO.
  146.48 + *  LWS isthe main purpose.
  146.49 +*/
  146.50 +#ifndef AI_LWO_ANIMATION_INCLUDED
  146.51 +#define AI_LWO_ANIMATION_INCLUDED
  146.52 +
  146.53 +namespace Assimp {
  146.54 +namespace LWO {
  146.55 +
  146.56 +// ---------------------------------------------------------------------------
  146.57 +/** \brief List of recognized LWO envelopes
  146.58 + */
  146.59 +enum EnvelopeType
  146.60 +{
  146.61 +	EnvelopeType_Position_X = 0x1,
  146.62 +	EnvelopeType_Position_Y = 0x2,
  146.63 +	EnvelopeType_Position_Z = 0x3,
  146.64 +
  146.65 +	EnvelopeType_Rotation_Heading = 0x4,
  146.66 +	EnvelopeType_Rotation_Pitch = 0x5,
  146.67 +	EnvelopeType_Rotation_Bank = 0x6,
  146.68 +
  146.69 +	EnvelopeType_Scaling_X = 0x7,
  146.70 +	EnvelopeType_Scaling_Y = 0x8,
  146.71 +	EnvelopeType_Scaling_Z = 0x9,
  146.72 +
  146.73 +	// -- currently not yet handled
  146.74 +	EnvelopeType_Color_R = 0xa,
  146.75 +	EnvelopeType_Color_G = 0xb,
  146.76 +	EnvelopeType_Color_B = 0xc,
  146.77 +
  146.78 +	EnvelopeType_Falloff_X = 0xd,
  146.79 +	EnvelopeType_Falloff_Y = 0xe,
  146.80 +	EnvelopeType_Falloff_Z = 0xf,
  146.81 +
  146.82 +	EnvelopeType_Unknown
  146.83 +};
  146.84 +
  146.85 +// ---------------------------------------------------------------------------
  146.86 +/** \brief List of recognized LWO interpolation modes
  146.87 + */
  146.88 +enum InterpolationType
  146.89 +{
  146.90 +	IT_STEP, IT_LINE, IT_TCB, IT_HERM, IT_BEZI, IT_BEZ2	
  146.91 +};
  146.92 +
  146.93 +
  146.94 +// ---------------------------------------------------------------------------
  146.95 +/** \brief List of recognized LWO pre or post range behaviours
  146.96 + */
  146.97 +enum PrePostBehaviour
  146.98 +{
  146.99 +	PrePostBehaviour_Reset        = 0x0,
 146.100 +	PrePostBehaviour_Constant     = 0x1,
 146.101 +	PrePostBehaviour_Repeat       = 0x2,
 146.102 +	PrePostBehaviour_Oscillate    = 0x3,
 146.103 +	PrePostBehaviour_OffsetRepeat = 0x4,
 146.104 +	PrePostBehaviour_Linear       = 0x5
 146.105 +};
 146.106 +
 146.107 +// ---------------------------------------------------------------------------
 146.108 +/** \brief Data structure for a LWO animation keyframe
 146.109 + */
 146.110 +struct Key
 146.111 +{
 146.112 +	Key()
 146.113 +		:	inter	(IT_LINE)
 146.114 +	{}
 146.115 +
 146.116 +	//! Current time
 146.117 +	double time;
 146.118 +
 146.119 +	//! Current value
 146.120 +	float value;
 146.121 +
 146.122 +	//! How to interpolate this key with previous key?
 146.123 +	InterpolationType inter;
 146.124 +
 146.125 +	//! Interpolation parameters
 146.126 +	float params[5];
 146.127 +
 146.128 +
 146.129 +	// for std::find()
 146.130 +	operator double () {
 146.131 +		return time;
 146.132 +	}
 146.133 +};
 146.134 +
 146.135 +// ---------------------------------------------------------------------------
 146.136 +/** \brief Data structure for a LWO animation envelope
 146.137 + */
 146.138 +struct Envelope
 146.139 +{
 146.140 +	Envelope()
 146.141 +		:	type	(EnvelopeType_Unknown)
 146.142 +		,	pre		(PrePostBehaviour_Constant)
 146.143 +		,	post	(PrePostBehaviour_Constant)
 146.144 +		
 146.145 +		,	old_first (0)
 146.146 +		,	old_last  (0)
 146.147 +	{}
 146.148 +
 146.149 +	//! Index of this envelope
 146.150 +	unsigned int index;
 146.151 +
 146.152 +	//! Type of envelope
 146.153 +	EnvelopeType type;
 146.154 +
 146.155 +	//! Pre and post-behaviour
 146.156 +	PrePostBehaviour pre,post;
 146.157 +
 146.158 +	//! Keyframes for this envelope
 146.159 +	std::vector<Key> keys;
 146.160 +
 146.161 +
 146.162 +	// temporary data for AnimResolver
 146.163 +	size_t old_first,old_last;
 146.164 +};
 146.165 +
 146.166 +// ---------------------------------------------------------------------------
 146.167 +//! @def AI_LWO_ANIM_FLAG_SAMPLE_ANIMS 
 146.168 +//! Flag for AnimResolver, subsamples the input data with the rate specified
 146.169 +//! by AnimResolver::SetSampleRate().
 146.170 +#define AI_LWO_ANIM_FLAG_SAMPLE_ANIMS 0x1
 146.171 +
 146.172 +
 146.173 +// ---------------------------------------------------------------------------
 146.174 +//! @def AI_LWO_ANIM_FLAG_START_AT_ZERO
 146.175 +//! Flag for AnimResolver, ensures that the animations starts at zero.
 146.176 +#define AI_LWO_ANIM_FLAG_START_AT_ZERO 0x2
 146.177 +
 146.178 +// ---------------------------------------------------------------------------
 146.179 +/** @brief Utility class to build Assimp animations from LWO envelopes.
 146.180 + *
 146.181 + *  Used for both LWO and LWS (MOT also).
 146.182 + */
 146.183 +class AnimResolver
 146.184 +{
 146.185 +public:
 146.186 +
 146.187 +	// ------------------------------------------------------------------
 146.188 +	/** @brief Construct an AnimResolver from a given list of envelopes
 146.189 +	 *  @param envelopes Input envelopes. May be empty.
 146.190 +	 *  @param Output tick rate, per second
 146.191 +	 *  @note The input envelopes are possibly modified.
 146.192 +	 */
 146.193 +	AnimResolver(std::list<Envelope>& envelopes,
 146.194 +		double tick);
 146.195 +
 146.196 +public:
 146.197 +
 146.198 +	// ------------------------------------------------------------------
 146.199 +	/** @brief Extract the bind-pose transformation matrix.
 146.200 +	 *  @param out Receives bind-pose transformation matrix
 146.201 +	 */
 146.202 +	void ExtractBindPose(aiMatrix4x4& out);
 146.203 +
 146.204 +	// ------------------------------------------------------------------
 146.205 +	/** @brief Extract a node animation channel
 146.206 +	 *  @param out Receives a pointer to a newly allocated node anim.
 146.207 +	 *    If there's just one keyframe defined, *out is set to NULL and
 146.208 +	 *    no animation channel is computed.
 146.209 +	 *  @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
 146.210 +	 */
 146.211 +	void ExtractAnimChannel(aiNodeAnim** out, unsigned int flags = 0);
 146.212 +
 146.213 +
 146.214 +	// ------------------------------------------------------------------
 146.215 +	/** @brief Set the sampling rate for ExtractAnimChannel().
 146.216 +	 *
 146.217 +	 *  Non-linear interpolations are subsampled with this rate (keys 
 146.218 +	 *  per second). Closer sampling positions, if existent, are kept.
 146.219 +	 *  The sampling rate defaults to 0, if this value is not changed and
 146.220 +	 *  AI_LWO_ANIM_FLAG_SAMPLE_ANIMS is specified for ExtractAnimChannel(),
 146.221 +	 *  the class finds a suitable sample rate by itself.
 146.222 +	 */
 146.223 +	void SetSampleRate(double sr) {
 146.224 +		sample_rate = sr;
 146.225 +	}
 146.226 +
 146.227 +	// ------------------------------------------------------------------
 146.228 +	/** @brief Getter for SetSampleRate()
 146.229 +	 */
 146.230 +	double GetSampleRate() const {
 146.231 +		return sample_rate;
 146.232 +	}
 146.233 +
 146.234 +	// ------------------------------------------------------------------
 146.235 +	/** @brief Set the animation time range
 146.236 +	 *
 146.237 +	 *  @param first Time where the animation starts, in ticks
 146.238 +	 *  @param last  Time where the animation ends, in ticks
 146.239 +	 */
 146.240 +	void SetAnimationRange(double _first, double _last) {
 146.241 +		first = _first;
 146.242 +		last  = _last;
 146.243 +
 146.244 +		ClearAnimRangeSetup();
 146.245 +		UpdateAnimRangeSetup();
 146.246 +	}
 146.247 +
 146.248 +protected:
 146.249 +
 146.250 +	// ------------------------------------------------------------------
 146.251 +	/** @brief Build linearly subsampled keys from 3 single envelopes
 146.252 +	 *  @param out Receives output keys
 146.253 +	 *  @param envl_x X-component envelope
 146.254 +	 *  @param envl_y Y-component envelope
 146.255 +	 *  @param envl_z Z-component envelope
 146.256 +	 *  @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
 146.257 +	 *  @note Up to two input envelopes may be NULL
 146.258 +	 */
 146.259 +	void GetKeys(std::vector<aiVectorKey>& out, 
 146.260 +		LWO::Envelope* envl_x,
 146.261 +		LWO::Envelope* envl_y,
 146.262 +		LWO::Envelope* envl_z,
 146.263 +		unsigned int flags);
 146.264 +
 146.265 +	// ------------------------------------------------------------------
 146.266 +	/** @brief Resolve a single animation key by applying the right
 146.267 +	 *  interpolation to it.
 146.268 +	 *  @param cur Current key
 146.269 +	 *  @param envl Envelope working on
 146.270 +	 *  @param time time to be interpolated
 146.271 +	 *  @param fill Receives the interpolated output value.
 146.272 +	 */
 146.273 +	void DoInterpolation(std::vector<LWO::Key>::const_iterator cur, 
 146.274 +		LWO::Envelope* envl,double time, float& fill);
 146.275 +
 146.276 +	// ------------------------------------------------------------------
 146.277 +	/** @brief Almost the same, except we won't handle pre/post 
 146.278 +	 *  conditions here.
 146.279 +	 *  @see DoInterpolation
 146.280 +	 */
 146.281 +	void DoInterpolation2(std::vector<LWO::Key>::const_iterator beg, 
 146.282 +		std::vector<LWO::Key>::const_iterator end,double time, float& fill);
 146.283 +
 146.284 +	// ------------------------------------------------------------------
 146.285 +	/** @brief Interpolate 2 tracks if one is given
 146.286 +	 * 
 146.287 +	 *  @param out Receives extra output keys
 146.288 +	 *  @param key_out Primary output key
 146.289 +	 *  @param time Time to interpolate for
 146.290 +	 */
 146.291 +	void InterpolateTrack(std::vector<aiVectorKey>& out,
 146.292 +		aiVectorKey& key_out,double time);
 146.293 +
 146.294 +	// ------------------------------------------------------------------
 146.295 +	/** @brief Subsample an animation track by a given sampling rate
 146.296 +	 *
 146.297 +	 *  @param out Receives output keys. Last key at input defines the
 146.298 +	 *    time where subsampling starts.
 146.299 +	 *  @param time Time to end subsampling at
 146.300 +	 *  @param sample_delta Time delta between two samples
 146.301 +	 */
 146.302 +	void SubsampleAnimTrack(std::vector<aiVectorKey>& out,
 146.303 +		double time,double sample_delta);
 146.304 +
 146.305 +	// ------------------------------------------------------------------
 146.306 +	/** @brief Delete all keys which we inserted to match anim setup
 146.307 +	 */
 146.308 +	void ClearAnimRangeSetup();
 146.309 +
 146.310 +	// ------------------------------------------------------------------
 146.311 +	/** @brief Insert extra keys to match LWO's pre and post behaviours
 146.312 +	 *  in a given time range [first...last]
 146.313 +	 */
 146.314 +	void UpdateAnimRangeSetup();
 146.315 +
 146.316 +private:
 146.317 +	std::list<Envelope>& envelopes;
 146.318 +	double sample_rate;
 146.319 +
 146.320 +	LWO::Envelope* trans_x, *trans_y, *trans_z;
 146.321 +	LWO::Envelope* rotat_x, *rotat_y, *rotat_z;
 146.322 +	LWO::Envelope* scale_x, *scale_y, *scale_z;
 146.323 +
 146.324 +	double first, last;
 146.325 +	bool need_to_setup;
 146.326 +
 146.327 +	// temporary storage
 146.328 +	LWO::Envelope* envl_x, * envl_y, * envl_z;
 146.329 +	std::vector<LWO::Key>::const_iterator cur_x,cur_y,cur_z;
 146.330 +	bool end_x, end_y, end_z;
 146.331 +
 146.332 +	unsigned int flags;
 146.333 +	double sample_delta;
 146.334 +};
 146.335 +
 146.336 +} // end namespace LWO
 146.337 +} // end namespace Assimp
 146.338 +
 146.339 +#endif // !! AI_LWO_ANIMATION_INCLUDED
   147.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   147.2 +++ b/libs/assimp/LWOBLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   147.3 @@ -0,0 +1,396 @@
   147.4 +/*
   147.5 +---------------------------------------------------------------------------
   147.6 +Open Asset Import Library (assimp)
   147.7 +---------------------------------------------------------------------------
   147.8 +
   147.9 +Copyright (c) 2006-2012, assimp team
  147.10 +
  147.11 +All rights reserved.
  147.12 +
  147.13 +Redistribution and use of this software in source and binary forms, 
  147.14 +with or without modification, are permitted provided that the following 
  147.15 +conditions are met:
  147.16 +
  147.17 +* Redistributions of source code must retain the above
  147.18 +  copyright notice, this list of conditions and the
  147.19 +  following disclaimer.
  147.20 +
  147.21 +* Redistributions in binary form must reproduce the above
  147.22 +  copyright notice, this list of conditions and the
  147.23 +  following disclaimer in the documentation and/or other
  147.24 +  materials provided with the distribution.
  147.25 +
  147.26 +* Neither the name of the assimp team, nor the names of its
  147.27 +  contributors may be used to endorse or promote products
  147.28 +  derived from this software without specific prior
  147.29 +  written permission of the assimp team.
  147.30 +
  147.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  147.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  147.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  147.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  147.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  147.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  147.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  147.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  147.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  147.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  147.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  147.42 +---------------------------------------------------------------------------
  147.43 +*/
  147.44 +
  147.45 +/** @file Implementation of the LWO importer class for the older LWOB 
  147.46 +    file formats, including materials */
  147.47 +
  147.48 +#include "AssimpPCH.h"
  147.49 +#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
  147.50 +
  147.51 +// Internal headers
  147.52 +#include "LWOLoader.h"
  147.53 +using namespace Assimp;
  147.54 +
  147.55 +
  147.56 +// ------------------------------------------------------------------------------------------------
  147.57 +void LWOImporter::LoadLWOBFile()
  147.58 +{
  147.59 +	LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
  147.60 +	bool running = true;
  147.61 +	while (running)
  147.62 +	{
  147.63 +		if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
  147.64 +		LE_NCONST IFF::ChunkHeader* const head = IFF::LoadChunk(mFileBuffer);
  147.65 +
  147.66 +		if (mFileBuffer + head->length > end)
  147.67 +		{
  147.68 +			throw DeadlyImportError("LWOB: Invalid chunk length");
  147.69 +			break;
  147.70 +		}
  147.71 +		uint8_t* const next = mFileBuffer+head->length;
  147.72 +		switch (head->type)
  147.73 +		{
  147.74 +			// vertex list
  147.75 +		case AI_LWO_PNTS:
  147.76 +			{
  147.77 +				if (!mCurLayer->mTempPoints.empty())
  147.78 +					DefaultLogger::get()->warn("LWO: PNTS chunk encountered twice");
  147.79 +				else LoadLWOPoints(head->length);
  147.80 +				break;
  147.81 +			}
  147.82 +			// face list
  147.83 +		case AI_LWO_POLS:
  147.84 +			{
  147.85 +				if (!mCurLayer->mFaces.empty())
  147.86 +					DefaultLogger::get()->warn("LWO: POLS chunk encountered twice");
  147.87 +				else LoadLWOBPolygons(head->length);
  147.88 +				break;
  147.89 +			}
  147.90 +			// list of tags
  147.91 +		case AI_LWO_SRFS:
  147.92 +			{
  147.93 +				if (!mTags->empty())
  147.94 +					DefaultLogger::get()->warn("LWO: SRFS chunk encountered twice");
  147.95 +				else LoadLWOTags(head->length);
  147.96 +				break;
  147.97 +			}
  147.98 +
  147.99 +			// surface chunk
 147.100 +		case AI_LWO_SURF:
 147.101 +			{
 147.102 +				LoadLWOBSurface(head->length);
 147.103 +				break;
 147.104 +			}
 147.105 +		}
 147.106 +		mFileBuffer = next;
 147.107 +	}
 147.108 +}
 147.109 +
 147.110 +// ------------------------------------------------------------------------------------------------
 147.111 +void LWOImporter::LoadLWOBPolygons(unsigned int length)
 147.112 +{
 147.113 +	// first find out how many faces and vertices we'll finally need
 147.114 +	LE_NCONST uint16_t* const end	= (LE_NCONST uint16_t*)(mFileBuffer+length);
 147.115 +	LE_NCONST uint16_t* cursor		= (LE_NCONST uint16_t*)mFileBuffer;
 147.116 +
 147.117 +	// perform endianess conversions
 147.118 +#ifndef AI_BUILD_BIG_ENDIAN
 147.119 +	while (cursor < end)ByteSwap::Swap2(cursor++);
 147.120 +	cursor = (LE_NCONST uint16_t*)mFileBuffer;
 147.121 +#endif
 147.122 +
 147.123 +	unsigned int iNumFaces = 0,iNumVertices = 0;
 147.124 +	CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end);
 147.125 +
 147.126 +	// allocate the output array and copy face indices
 147.127 +	if (iNumFaces)
 147.128 +	{
 147.129 +		cursor = (LE_NCONST uint16_t*)mFileBuffer;
 147.130 +
 147.131 +		mCurLayer->mFaces.resize(iNumFaces);
 147.132 +		FaceList::iterator it = mCurLayer->mFaces.begin();
 147.133 +		CopyFaceIndicesLWOB(it,cursor,end);
 147.134 +	}
 147.135 +}
 147.136 +
 147.137 +// ------------------------------------------------------------------------------------------------
 147.138 +void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& faces,
 147.139 +	LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max)
 147.140 +{
 147.141 +	while (cursor < end && max--)
 147.142 +	{
 147.143 +		uint16_t numIndices = *cursor++;
 147.144 +		verts += numIndices;faces++;
 147.145 +		cursor += numIndices;
 147.146 +		int16_t surface = *cursor++;
 147.147 +		if (surface < 0)
 147.148 +		{
 147.149 +			// there are detail polygons
 147.150 +			numIndices = *cursor++;
 147.151 +			CountVertsAndFacesLWOB(verts,faces,cursor,end,numIndices);
 147.152 +		}
 147.153 +	}
 147.154 +}
 147.155 +
 147.156 +// ------------------------------------------------------------------------------------------------
 147.157 +void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
 147.158 +	LE_NCONST uint16_t*& cursor, 
 147.159 +	const uint16_t* const end,
 147.160 +	unsigned int max)
 147.161 +{
 147.162 +	while (cursor < end && max--)
 147.163 +	{
 147.164 +		LWO::Face& face = *it;++it;
 147.165 +		if((face.mNumIndices = *cursor++))
 147.166 +		{
 147.167 +			if (cursor + face.mNumIndices >= end)break;
 147.168 +			face.mIndices = new unsigned int[face.mNumIndices];
 147.169 +			for (unsigned int i = 0; i < face.mNumIndices;++i)
 147.170 +			{
 147.171 +				unsigned int & mi = face.mIndices[i] = *cursor++;
 147.172 +				if (mi > mCurLayer->mTempPoints.size())
 147.173 +				{
 147.174 +					DefaultLogger::get()->warn("LWOB: face index is out of range");
 147.175 +					mi = (unsigned int)mCurLayer->mTempPoints.size()-1;
 147.176 +				}
 147.177 +			}
 147.178 +		}
 147.179 +		else DefaultLogger::get()->warn("LWOB: Face has 0 indices");
 147.180 +		int16_t surface = *cursor++;
 147.181 +		if (surface < 0)
 147.182 +		{
 147.183 +			surface = -surface;
 147.184 +
 147.185 +			// there are detail polygons. 
 147.186 +			const uint16_t numPolygons = *cursor++;
 147.187 +			if (cursor < end)CopyFaceIndicesLWOB(it,cursor,end,numPolygons);
 147.188 +		}
 147.189 +		face.surfaceIndex = surface-1;
 147.190 +	}
 147.191 +}
 147.192 +
 147.193 +// ------------------------------------------------------------------------------------------------
 147.194 +LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size)
 147.195 +{
 147.196 +	list.push_back(LWO::Texture());
 147.197 +	LWO::Texture* tex = &list.back();
 147.198 +
 147.199 +	std::string type;
 147.200 +	GetS0(type,size);
 147.201 +	const char* s = type.c_str();
 147.202 +
 147.203 +	if(strstr(s, "Image Map"))
 147.204 +	{
 147.205 +		// Determine mapping type
 147.206 +		if(strstr(s, "Planar"))
 147.207 +			tex->mapMode = LWO::Texture::Planar;
 147.208 +		else if(strstr(s, "Cylindrical"))
 147.209 +			tex->mapMode = LWO::Texture::Cylindrical;
 147.210 +		else if(strstr(s, "Spherical"))
 147.211 +			tex->mapMode = LWO::Texture::Spherical;
 147.212 +		else if(strstr(s, "Cubic"))
 147.213 +			tex->mapMode = LWO::Texture::Cubic;
 147.214 +		else if(strstr(s, "Front"))
 147.215 +			tex->mapMode = LWO::Texture::FrontProjection;
 147.216 +	}
 147.217 +	else
 147.218 +	{
 147.219 +		// procedural or gradient, not supported
 147.220 +		DefaultLogger::get()->error("LWOB: Unsupported legacy texture: " + type);
 147.221 +	}
 147.222 +
 147.223 +	return tex;
 147.224 +}
 147.225 +
 147.226 +// ------------------------------------------------------------------------------------------------
 147.227 +void LWOImporter::LoadLWOBSurface(unsigned int size)
 147.228 +{
 147.229 +	LE_NCONST uint8_t* const end = mFileBuffer + size;
 147.230 +
 147.231 +	mSurfaces->push_back( LWO::Surface () );
 147.232 +	LWO::Surface& surf = mSurfaces->back();
 147.233 +	LWO::Texture* pTex = NULL;
 147.234 +
 147.235 +	GetS0(surf.mName,size);
 147.236 +	bool runnning = true;
 147.237 +	while (runnning)	{
 147.238 +		if (mFileBuffer + 6 >= end)
 147.239 +			break;
 147.240 +
 147.241 +		IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
 147.242 +
 147.243 +		/*  A single test file (sonycam.lwo) seems to have invalid surface chunks.
 147.244 +		 *  I'm assuming it's the fault of a single, unknown exporter so there are
 147.245 +		 *  probably THOUSANDS of them. Here's a dirty workaround:
 147.246 +		 *
 147.247 +		 *  We don't break if the chunk limit is exceeded. Instead, we're computing 
 147.248 +		 *  how much storage is actually left and work with this value from now on.
 147.249 +		 */
 147.250 +		if (mFileBuffer + head->length > end) {
 147.251 +			DefaultLogger::get()->error("LWOB: Invalid surface chunk length. Trying to continue.");
 147.252 +			head->length = (uint16_t) (end - mFileBuffer);
 147.253 +		}
 147.254 +
 147.255 +		uint8_t* const next = mFileBuffer+head->length;
 147.256 +		switch (head->type)
 147.257 +		{
 147.258 +		// diffuse color
 147.259 +		case AI_LWO_COLR:
 147.260 +			{
 147.261 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,COLR,3);
 147.262 +				surf.mColor.r = GetU1() / 255.0f;
 147.263 +				surf.mColor.g = GetU1() / 255.0f;
 147.264 +				surf.mColor.b = GetU1() / 255.0f;
 147.265 +				break;
 147.266 +			}
 147.267 +		// diffuse strength ...
 147.268 +		case AI_LWO_DIFF:
 147.269 +			{
 147.270 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,DIFF,2);
 147.271 +				surf.mDiffuseValue = GetU2() / 255.0f;
 147.272 +				break;
 147.273 +			}
 147.274 +		// specular strength ... 
 147.275 +		case AI_LWO_SPEC:
 147.276 +			{
 147.277 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPEC,2);
 147.278 +				surf.mSpecularValue = GetU2() / 255.0f;
 147.279 +				break;
 147.280 +			}
 147.281 +		// luminosity ... 
 147.282 +		case AI_LWO_LUMI:
 147.283 +			{
 147.284 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LUMI,2);
 147.285 +				surf.mLuminosity = GetU2() / 255.0f;
 147.286 +				break;
 147.287 +			}
 147.288 +		// transparency
 147.289 +		case AI_LWO_TRAN:
 147.290 +			{
 147.291 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TRAN,2);
 147.292 +				surf.mTransparency = GetU2() / 255.0f;
 147.293 +				break;
 147.294 +			}
 147.295 +		// surface flags
 147.296 +		case AI_LWO_FLAG:
 147.297 +			{
 147.298 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,FLAG,2);
 147.299 +				uint16_t flag = GetU2();
 147.300 +				if (flag & 0x4 )   surf.mMaximumSmoothAngle = 1.56207f;
 147.301 +				if (flag & 0x8 )   surf.mColorHighlights = 1.f;
 147.302 +				if (flag & 0x100)  surf.bDoubleSided = true;
 147.303 +				break;
 147.304 +			}
 147.305 +		// maximum smoothing angle
 147.306 +		case AI_LWO_SMAN:
 147.307 +			{
 147.308 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SMAN,4);
 147.309 +				surf.mMaximumSmoothAngle = fabs( GetF4() );
 147.310 +				break;
 147.311 +			}
 147.312 +		// glossiness
 147.313 +		case AI_LWO_GLOS:
 147.314 +			{
 147.315 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,GLOS,2);
 147.316 +				surf.mGlossiness = (float)GetU2();
 147.317 +				break;
 147.318 +			}
 147.319 +		// color texture
 147.320 +		case AI_LWO_CTEX:
 147.321 +			{
 147.322 +				pTex = SetupNewTextureLWOB(surf.mColorTextures,
 147.323 +					head->length);
 147.324 +				break;
 147.325 +			}
 147.326 +		// diffuse texture
 147.327 +		case AI_LWO_DTEX:
 147.328 +			{
 147.329 +				pTex = SetupNewTextureLWOB(surf.mDiffuseTextures,
 147.330 +					head->length);
 147.331 +				break;
 147.332 +			}
 147.333 +		// specular texture
 147.334 +		case AI_LWO_STEX:
 147.335 +			{
 147.336 +				pTex = SetupNewTextureLWOB(surf.mSpecularTextures,
 147.337 +					head->length);
 147.338 +				break;
 147.339 +			}
 147.340 +		// bump texture
 147.341 +		case AI_LWO_BTEX:
 147.342 +			{
 147.343 +				pTex = SetupNewTextureLWOB(surf.mBumpTextures,
 147.344 +					head->length);
 147.345 +				break;
 147.346 +			}
 147.347 +		// transparency texture
 147.348 +		case AI_LWO_TTEX:
 147.349 +			{
 147.350 +				pTex = SetupNewTextureLWOB(surf.mOpacityTextures,
 147.351 +					head->length);
 147.352 +				break;
 147.353 +			}
 147.354 +		// texture path
 147.355 +		case AI_LWO_TIMG:
 147.356 +			{
 147.357 +				if (pTex)	{
 147.358 +					GetS0(pTex->mFileName,head->length);	
 147.359 +				}
 147.360 +				else DefaultLogger::get()->warn("LWOB: Unexpected TIMG chunk");
 147.361 +				break;
 147.362 +			}
 147.363 +		// texture strength
 147.364 +		case AI_LWO_TVAL:
 147.365 +			{
 147.366 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TVAL,1);
 147.367 +				if (pTex)	{
 147.368 +					pTex->mStrength = (float)GetU1()/ 255.f;
 147.369 +				}
 147.370 +				else DefaultLogger::get()->warn("LWOB: Unexpected TVAL chunk");
 147.371 +				break;
 147.372 +			}
 147.373 +		// texture flags
 147.374 +		case AI_LWO_TFLG:
 147.375 +			{
 147.376 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TFLG,2);
 147.377 +
 147.378 +				if (pTex) 
 147.379 +				{
 147.380 +					const uint16_t s = GetU2();
 147.381 +					if (s & 1)
 147.382 +						pTex->majorAxis = LWO::Texture::AXIS_X;
 147.383 +					else if (s & 2)
 147.384 +						pTex->majorAxis = LWO::Texture::AXIS_Y;
 147.385 +					else if (s & 4)
 147.386 +						pTex->majorAxis = LWO::Texture::AXIS_Z;
 147.387 +
 147.388 +					if (s & 16)
 147.389 +						DefaultLogger::get()->warn("LWOB: Ignoring \'negate\' flag on texture");
 147.390 +				} 
 147.391 +				else DefaultLogger::get()->warn("LWOB: Unexpected TFLG chunk");
 147.392 +				break;
 147.393 +			}
 147.394 +		}
 147.395 +		mFileBuffer = next;
 147.396 +	}
 147.397 +}
 147.398 +
 147.399 +#endif // !! ASSIMP_BUILD_NO_LWO_IMPORTER
   148.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   148.2 +++ b/libs/assimp/LWOFileData.h	Sat Feb 01 19:58:19 2014 +0200
   148.3 @@ -0,0 +1,699 @@
   148.4 +/*
   148.5 +Open Asset Import Library (assimp)
   148.6 +----------------------------------------------------------------------
   148.7 +
   148.8 +Copyright (c) 2006-2012, assimp team
   148.9 +All rights reserved.
  148.10 +
  148.11 +Redistribution and use of this software in source and binary forms, 
  148.12 +with or without modification, are permitted provided that the 
  148.13 +following conditions are met:
  148.14 +
  148.15 +* Redistributions of source code must retain the above
  148.16 +  copyright notice, this list of conditions and the
  148.17 +  following disclaimer.
  148.18 +
  148.19 +* Redistributions in binary form must reproduce the above
  148.20 +  copyright notice, this list of conditions and the
  148.21 +  following disclaimer in the documentation and/or other
  148.22 +  materials provided with the distribution.
  148.23 +
  148.24 +* Neither the name of the assimp team, nor the names of its
  148.25 +  contributors may be used to endorse or promote products
  148.26 +  derived from this software without specific prior
  148.27 +  written permission of the assimp team.
  148.28 +
  148.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  148.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  148.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  148.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  148.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  148.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  148.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  148.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  148.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  148.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  148.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  148.40 +
  148.41 +----------------------------------------------------------------------
  148.42 +*/
  148.43 +
  148.44 +/** @file LWOFileData.h
  148.45 + *  @brief Defines chunk constants used by the LWO file format
  148.46 +
  148.47 +The chunks are taken from the official LightWave SDK headers.
  148.48 + 
  148.49 +*/
  148.50 +#ifndef AI_LWO_FILEDATA_INCLUDED
  148.51 +#define AI_LWO_FILEDATA_INCLUDED
  148.52 +
  148.53 +// STL headers
  148.54 +#include <vector>
  148.55 +#include <list>
  148.56 +
  148.57 +// public ASSIMP headers
  148.58 +#include "assimp/mesh.h"
  148.59 +
  148.60 +// internal headers
  148.61 +#include "IFF.h"
  148.62 +#include "LWOAnimation.h"
  148.63 +
  148.64 +namespace Assimp {
  148.65 +namespace LWO {
  148.66 +
  148.67 +#define AI_LWO_FOURCC_LWOB AI_IFF_FOURCC('L','W','O','B')
  148.68 +#define AI_LWO_FOURCC_LWO2 AI_IFF_FOURCC('L','W','O','2')
  148.69 +#define AI_LWO_FOURCC_LXOB AI_IFF_FOURCC('L','X','O','B')
  148.70 +
  148.71 +// chunks specific to the LWOB format
  148.72 +#define AI_LWO_SRFS  AI_IFF_FOURCC('S','R','F','S')
  148.73 +#define AI_LWO_FLAG  AI_IFF_FOURCC('F','L','A','G')
  148.74 +#define AI_LWO_VLUM  AI_IFF_FOURCC('V','L','U','M')
  148.75 +#define AI_LWO_VDIF  AI_IFF_FOURCC('V','D','I','F')
  148.76 +#define AI_LWO_VSPC  AI_IFF_FOURCC('V','S','P','C')
  148.77 +#define AI_LWO_RFLT  AI_IFF_FOURCC('R','F','L','T')
  148.78 +#define AI_LWO_BTEX  AI_IFF_FOURCC('B','T','E','X')
  148.79 +#define AI_LWO_CTEX  AI_IFF_FOURCC('C','T','E','X')
  148.80 +#define AI_LWO_DTEX  AI_IFF_FOURCC('D','T','E','X')
  148.81 +#define AI_LWO_LTEX  AI_IFF_FOURCC('L','T','E','X')
  148.82 +#define AI_LWO_RTEX  AI_IFF_FOURCC('R','T','E','X')
  148.83 +#define AI_LWO_STEX  AI_IFF_FOURCC('S','T','E','X')
  148.84 +#define AI_LWO_TTEX  AI_IFF_FOURCC('T','T','E','X')
  148.85 +#define AI_LWO_TFLG  AI_IFF_FOURCC('T','F','L','G')
  148.86 +#define AI_LWO_TSIZ  AI_IFF_FOURCC('T','S','I','Z')
  148.87 +#define AI_LWO_TCTR  AI_IFF_FOURCC('T','C','T','R')
  148.88 +#define AI_LWO_TFAL  AI_IFF_FOURCC('T','F','A','L')
  148.89 +#define AI_LWO_TVEL  AI_IFF_FOURCC('T','V','E','L')
  148.90 +#define AI_LWO_TCLR  AI_IFF_FOURCC('T','C','L','R')
  148.91 +#define AI_LWO_TVAL  AI_IFF_FOURCC('T','V','A','L')
  148.92 +#define AI_LWO_TAMP  AI_IFF_FOURCC('T','A','M','P')
  148.93 +#define AI_LWO_TIMG  AI_IFF_FOURCC('T','I','M','G')
  148.94 +#define AI_LWO_TAAS  AI_IFF_FOURCC('T','A','A','S')
  148.95 +#define AI_LWO_TREF  AI_IFF_FOURCC('T','R','E','F')
  148.96 +#define AI_LWO_TOPC  AI_IFF_FOURCC('T','O','P','C')
  148.97 +#define AI_LWO_SDAT  AI_IFF_FOURCC('S','D','A','T')
  148.98 +#define AI_LWO_TFP0  AI_IFF_FOURCC('T','F','P','0')
  148.99 +#define AI_LWO_TFP1  AI_IFF_FOURCC('T','F','P','1')
 148.100 +
 148.101 +
 148.102 +/* top-level chunks */
 148.103 +#define AI_LWO_LAYR  AI_IFF_FOURCC('L','A','Y','R')
 148.104 +#define AI_LWO_TAGS  AI_IFF_FOURCC('T','A','G','S')
 148.105 +#define AI_LWO_PNTS  AI_IFF_FOURCC('P','N','T','S')
 148.106 +#define AI_LWO_BBOX  AI_IFF_FOURCC('B','B','O','X')
 148.107 +#define AI_LWO_VMAP  AI_IFF_FOURCC('V','M','A','P')
 148.108 +#define AI_LWO_VMAD  AI_IFF_FOURCC('V','M','A','D')
 148.109 +#define AI_LWO_POLS  AI_IFF_FOURCC('P','O','L','S')
 148.110 +#define AI_LWO_PTAG  AI_IFF_FOURCC('P','T','A','G')
 148.111 +#define AI_LWO_ENVL  AI_IFF_FOURCC('E','N','V','L')
 148.112 +#define AI_LWO_CLIP  AI_IFF_FOURCC('C','L','I','P')
 148.113 +#define AI_LWO_SURF  AI_IFF_FOURCC('S','U','R','F')
 148.114 +#define AI_LWO_DESC  AI_IFF_FOURCC('D','E','S','C')
 148.115 +#define AI_LWO_TEXT  AI_IFF_FOURCC('T','E','X','T')
 148.116 +#define AI_LWO_ICON  AI_IFF_FOURCC('I','C','O','N')
 148.117 +
 148.118 +/* polygon types */
 148.119 +#define AI_LWO_FACE  AI_IFF_FOURCC('F','A','C','E')
 148.120 +#define AI_LWO_CURV  AI_IFF_FOURCC('C','U','R','V')
 148.121 +#define AI_LWO_PTCH  AI_IFF_FOURCC('P','T','C','H')
 148.122 +#define AI_LWO_MBAL  AI_IFF_FOURCC('M','B','A','L')
 148.123 +#define AI_LWO_BONE  AI_IFF_FOURCC('B','O','N','E')
 148.124 +#define AI_LWO_SUBD  AI_IFF_FOURCC('S','U','B','D')
 148.125 +
 148.126 +/* polygon tags */
 148.127 +#define AI_LWO_SURF  AI_IFF_FOURCC('S','U','R','F')
 148.128 +#define AI_LWO_PART  AI_IFF_FOURCC('P','A','R','T')
 148.129 +#define AI_LWO_SMGP  AI_IFF_FOURCC('S','M','G','P')
 148.130 +
 148.131 +/* envelopes */
 148.132 +#define AI_LWO_PRE   AI_IFF_FOURCC('P','R','E',' ')
 148.133 +#define AI_LWO_POST  AI_IFF_FOURCC('P','O','S','T')
 148.134 +#define AI_LWO_KEY   AI_IFF_FOURCC('K','E','Y',' ')
 148.135 +#define AI_LWO_SPAN  AI_IFF_FOURCC('S','P','A','N')
 148.136 +#define AI_LWO_TCB   AI_IFF_FOURCC('T','C','B',' ')
 148.137 +#define AI_LWO_HERM  AI_IFF_FOURCC('H','E','R','M')
 148.138 +#define AI_LWO_BEZI  AI_IFF_FOURCC('B','E','Z','I')
 148.139 +#define AI_LWO_BEZ2  AI_IFF_FOURCC('B','E','Z','2')
 148.140 +#define AI_LWO_LINE  AI_IFF_FOURCC('L','I','N','E')
 148.141 +#define AI_LWO_STEP  AI_IFF_FOURCC('S','T','E','P')
 148.142 +
 148.143 +/* clips */
 148.144 +#define AI_LWO_STIL  AI_IFF_FOURCC('S','T','I','L')
 148.145 +#define AI_LWO_ISEQ  AI_IFF_FOURCC('I','S','E','Q')
 148.146 +#define AI_LWO_ANIM  AI_IFF_FOURCC('A','N','I','M')
 148.147 +#define AI_LWO_XREF  AI_IFF_FOURCC('X','R','E','F')
 148.148 +#define AI_LWO_STCC  AI_IFF_FOURCC('S','T','C','C')
 148.149 +#define AI_LWO_TIME  AI_IFF_FOURCC('T','I','M','E')
 148.150 +#define AI_LWO_CONT  AI_IFF_FOURCC('C','O','N','T')
 148.151 +#define AI_LWO_BRIT  AI_IFF_FOURCC('B','R','I','T')
 148.152 +#define AI_LWO_SATR  AI_IFF_FOURCC('S','A','T','R')
 148.153 +#define AI_LWO_HUE   AI_IFF_FOURCC('H','U','E',' ')
 148.154 +#define AI_LWO_GAMM  AI_IFF_FOURCC('G','A','M','M')
 148.155 +#define AI_LWO_NEGA  AI_IFF_FOURCC('N','E','G','A')
 148.156 +#define AI_LWO_IFLT  AI_IFF_FOURCC('I','F','L','T')
 148.157 +#define AI_LWO_PFLT  AI_IFF_FOURCC('P','F','L','T')
 148.158 +
 148.159 +/* surfaces */
 148.160 +#define AI_LWO_COLR  AI_IFF_FOURCC('C','O','L','R')
 148.161 +#define AI_LWO_LUMI  AI_IFF_FOURCC('L','U','M','I')
 148.162 +#define AI_LWO_DIFF  AI_IFF_FOURCC('D','I','F','F')
 148.163 +#define AI_LWO_SPEC  AI_IFF_FOURCC('S','P','E','C')
 148.164 +#define AI_LWO_GLOS  AI_IFF_FOURCC('G','L','O','S')
 148.165 +#define AI_LWO_REFL  AI_IFF_FOURCC('R','E','F','L')
 148.166 +#define AI_LWO_RFOP  AI_IFF_FOURCC('R','F','O','P')
 148.167 +#define AI_LWO_RIMG  AI_IFF_FOURCC('R','I','M','G')
 148.168 +#define AI_LWO_RSAN  AI_IFF_FOURCC('R','S','A','N')
 148.169 +#define AI_LWO_TRAN  AI_IFF_FOURCC('T','R','A','N')
 148.170 +#define AI_LWO_TROP  AI_IFF_FOURCC('T','R','O','P')
 148.171 +#define AI_LWO_TIMG  AI_IFF_FOURCC('T','I','M','G')
 148.172 +#define AI_LWO_RIND  AI_IFF_FOURCC('R','I','N','D')
 148.173 +#define AI_LWO_TRNL  AI_IFF_FOURCC('T','R','N','L')
 148.174 +#define AI_LWO_BUMP  AI_IFF_FOURCC('B','U','M','P')
 148.175 +#define AI_LWO_SMAN  AI_IFF_FOURCC('S','M','A','N')
 148.176 +#define AI_LWO_SIDE  AI_IFF_FOURCC('S','I','D','E')
 148.177 +#define AI_LWO_CLRH  AI_IFF_FOURCC('C','L','R','H')
 148.178 +#define AI_LWO_CLRF  AI_IFF_FOURCC('C','L','R','F')
 148.179 +#define AI_LWO_ADTR  AI_IFF_FOURCC('A','D','T','R')
 148.180 +#define AI_LWO_SHRP  AI_IFF_FOURCC('S','H','R','P')
 148.181 +#define AI_LWO_LINE  AI_IFF_FOURCC('L','I','N','E')
 148.182 +#define AI_LWO_LSIZ  AI_IFF_FOURCC('L','S','I','Z')
 148.183 +#define AI_LWO_ALPH  AI_IFF_FOURCC('A','L','P','H')
 148.184 +#define AI_LWO_AVAL  AI_IFF_FOURCC('A','V','A','L')
 148.185 +#define AI_LWO_GVAL  AI_IFF_FOURCC('G','V','A','L')
 148.186 +#define AI_LWO_BLOK  AI_IFF_FOURCC('B','L','O','K')
 148.187 +#define AI_LWO_VCOL  AI_IFF_FOURCC('V','C','O','L')
 148.188 +
 148.189 +/* texture layer */
 148.190 +#define AI_LWO_TYPE  AI_IFF_FOURCC('T','Y','P','E')
 148.191 +#define AI_LWO_CHAN  AI_IFF_FOURCC('C','H','A','N')
 148.192 +#define AI_LWO_NAME  AI_IFF_FOURCC('N','A','M','E')
 148.193 +#define AI_LWO_ENAB  AI_IFF_FOURCC('E','N','A','B')
 148.194 +#define AI_LWO_OPAC  AI_IFF_FOURCC('O','P','A','C')
 148.195 +#define AI_LWO_FLAG  AI_IFF_FOURCC('F','L','A','G')
 148.196 +#define AI_LWO_PROJ  AI_IFF_FOURCC('P','R','O','J')
 148.197 +#define AI_LWO_STCK  AI_IFF_FOURCC('S','T','C','K')
 148.198 +#define AI_LWO_TAMP  AI_IFF_FOURCC('T','A','M','P')
 148.199 +
 148.200 +/* texture coordinates */
 148.201 +#define AI_LWO_TMAP  AI_IFF_FOURCC('T','M','A','P')
 148.202 +#define AI_LWO_AXIS  AI_IFF_FOURCC('A','X','I','S')
 148.203 +#define AI_LWO_CNTR  AI_IFF_FOURCC('C','N','T','R')
 148.204 +#define AI_LWO_SIZE  AI_IFF_FOURCC('S','I','Z','E')
 148.205 +#define AI_LWO_ROTA  AI_IFF_FOURCC('R','O','T','A')
 148.206 +#define AI_LWO_OREF  AI_IFF_FOURCC('O','R','E','F')
 148.207 +#define AI_LWO_FALL  AI_IFF_FOURCC('F','A','L','L')
 148.208 +#define AI_LWO_CSYS  AI_IFF_FOURCC('C','S','Y','S')
 148.209 +
 148.210 +/* image map */
 148.211 +#define AI_LWO_IMAP  AI_IFF_FOURCC('I','M','A','P')
 148.212 +#define AI_LWO_IMAG  AI_IFF_FOURCC('I','M','A','G')
 148.213 +#define AI_LWO_WRAP  AI_IFF_FOURCC('W','R','A','P')
 148.214 +#define AI_LWO_WRPW  AI_IFF_FOURCC('W','R','P','W')
 148.215 +#define AI_LWO_WRPH  AI_IFF_FOURCC('W','R','P','H')
 148.216 +#define AI_LWO_VMAP  AI_IFF_FOURCC('V','M','A','P')
 148.217 +#define AI_LWO_AAST  AI_IFF_FOURCC('A','A','S','T')
 148.218 +#define AI_LWO_PIXB  AI_IFF_FOURCC('P','I','X','B')
 148.219 +
 148.220 +/* procedural */
 148.221 +#define AI_LWO_PROC  AI_IFF_FOURCC('P','R','O','C')
 148.222 +#define AI_LWO_COLR  AI_IFF_FOURCC('C','O','L','R')
 148.223 +#define AI_LWO_VALU  AI_IFF_FOURCC('V','A','L','U')
 148.224 +#define AI_LWO_FUNC  AI_IFF_FOURCC('F','U','N','C')
 148.225 +#define AI_LWO_FTPS  AI_IFF_FOURCC('F','T','P','S')
 148.226 +#define AI_LWO_ITPS  AI_IFF_FOURCC('I','T','P','S')
 148.227 +#define AI_LWO_ETPS  AI_IFF_FOURCC('E','T','P','S')
 148.228 +
 148.229 +/* gradient */
 148.230 +#define AI_LWO_GRAD  AI_IFF_FOURCC('G','R','A','D')
 148.231 +#define AI_LWO_GRST  AI_IFF_FOURCC('G','R','S','T')
 148.232 +#define AI_LWO_GREN  AI_IFF_FOURCC('G','R','E','N')
 148.233 +#define AI_LWO_PNAM  AI_IFF_FOURCC('P','N','A','M')
 148.234 +#define AI_LWO_INAM  AI_IFF_FOURCC('I','N','A','M')
 148.235 +#define AI_LWO_GRPT  AI_IFF_FOURCC('G','R','P','T')
 148.236 +#define AI_LWO_FKEY  AI_IFF_FOURCC('F','K','E','Y')
 148.237 +#define AI_LWO_IKEY  AI_IFF_FOURCC('I','K','E','Y')
 148.238 +
 148.239 +/* shader */
 148.240 +#define AI_LWO_SHDR  AI_IFF_FOURCC('S','H','D','R')
 148.241 +#define AI_LWO_DATA  AI_IFF_FOURCC('D','A','T','A')
 148.242 +
 148.243 +
 148.244 +/* VMAP types */
 148.245 +#define AI_LWO_TXUV  AI_IFF_FOURCC('T','X','U','V')
 148.246 +#define AI_LWO_RGB   AI_IFF_FOURCC('R','G','B',' ')
 148.247 +#define AI_LWO_RGBA  AI_IFF_FOURCC('R','G','B','A')
 148.248 +#define AI_LWO_WGHT  AI_IFF_FOURCC('W','G','H','T')
 148.249 +
 148.250 +#define AI_LWO_MNVW  AI_IFF_FOURCC('M','N','V','W')
 148.251 +#define AI_LWO_MORF  AI_IFF_FOURCC('M','O','R','F')
 148.252 +#define AI_LWO_SPOT  AI_IFF_FOURCC('S','P','O','T')
 148.253 +#define AI_LWO_PICK  AI_IFF_FOURCC('P','I','C','K')
 148.254 +
 148.255 +// MODO extension - per-vertex normal vectors
 148.256 +#define AI_LWO_MODO_NORM AI_IFF_FOURCC('N', 'O', 'R', 'M')
 148.257 +
 148.258 +
 148.259 +// ---------------------------------------------------------------------------
 148.260 +/** \brief Data structure for a face in a LWO file
 148.261 + *
 148.262 + * \note We can't use the code in SmoothingGroups.inl here - the mesh
 148.263 + *   structures of 3DS/ASE and LWO are too different. 
 148.264 + */
 148.265 +struct Face : public aiFace
 148.266 +{
 148.267 +	//! Default construction
 148.268 +	Face() 
 148.269 +		: surfaceIndex	(0)
 148.270 +		, smoothGroup	(0)
 148.271 +		, type			(AI_LWO_FACE)
 148.272 +	{}
 148.273 +
 148.274 +	//! Construction from given type
 148.275 +	Face(uint32_t _type) 
 148.276 +		: surfaceIndex	(0)
 148.277 +		, smoothGroup	(0)
 148.278 +		, type			(_type)
 148.279 +	{}
 148.280 +
 148.281 +	//! Copy construction
 148.282 +	Face(const Face& f) : aiFace() {
 148.283 +		*this = f;
 148.284 +	}
 148.285 +
 148.286 +	//! Zero-based index into tags chunk
 148.287 +	unsigned int surfaceIndex;
 148.288 +
 148.289 +	//! Smooth group this face is assigned to
 148.290 +	unsigned int smoothGroup;
 148.291 +
 148.292 +	//! Type of face
 148.293 +	uint32_t type;
 148.294 +
 148.295 +
 148.296 +	//! Assignment operator
 148.297 +	Face& operator=(const LWO::Face& f)	{
 148.298 +		aiFace::operator =(f);
 148.299 +		surfaceIndex	= f.surfaceIndex;
 148.300 +		smoothGroup		= f.smoothGroup;
 148.301 +		type            = f.type;
 148.302 +		return *this;
 148.303 +	}
 148.304 +};
 148.305 +
 148.306 +// ---------------------------------------------------------------------------
 148.307 +/** \brief Base structure for all vertex map representations
 148.308 + */
 148.309 +struct VMapEntry
 148.310 +{
 148.311 +	VMapEntry(unsigned int _dims)
 148.312 +		:  dims(_dims)
 148.313 +	{}
 148.314 +
 148.315 +	virtual ~VMapEntry() {}
 148.316 +
 148.317 +	//! allocates memory for the vertex map
 148.318 +	virtual void Allocate(unsigned int num)
 148.319 +	{
 148.320 +		if (!rawData.empty())
 148.321 +			return; // return if already allocated
 148.322 +
 148.323 +		const unsigned int m = num*dims;
 148.324 +		rawData.reserve(m + (m>>2u)); // 25% as  extra storage for VMADs
 148.325 +		rawData.resize(m,0.f);
 148.326 +		abAssigned.resize(num,false);
 148.327 +	}
 148.328 +
 148.329 +	std::string name;
 148.330 +	unsigned int dims;
 148.331 +
 148.332 +	std::vector<float> rawData;
 148.333 +	std::vector<bool> abAssigned;
 148.334 +};
 148.335 +
 148.336 +// ---------------------------------------------------------------------------
 148.337 +/** \brief Represents an extra vertex color channel
 148.338 + */
 148.339 +struct VColorChannel : public VMapEntry
 148.340 +{
 148.341 +	VColorChannel()
 148.342 +		: VMapEntry(4)
 148.343 +	{}
 148.344 +
 148.345 +	//! need to overwrite this function - the alpha channel must
 148.346 +	//! be initialized to 1.0 by default
 148.347 +	virtual void Allocate(unsigned int num)
 148.348 +	{
 148.349 +		if (!rawData.empty())
 148.350 +			return; // return if already allocated
 148.351 +
 148.352 +		register unsigned int m = num*dims;
 148.353 +		rawData.reserve(m + (m>>2u)); // 25% as  extra storage for VMADs
 148.354 +		rawData.resize(m);
 148.355 +
 148.356 +		for (aiColor4D* p = (aiColor4D*)&rawData[0]; p < (aiColor4D*)&rawData[m-1]; ++p)
 148.357 +			p->a = 1.f;
 148.358 +
 148.359 +		abAssigned.resize(num,false);
 148.360 +	}
 148.361 +};
 148.362 +
 148.363 +// ---------------------------------------------------------------------------
 148.364 +/** \brief Represents an extra vertex UV channel
 148.365 + */
 148.366 +struct UVChannel : public VMapEntry
 148.367 +{
 148.368 +	UVChannel()
 148.369 +		: VMapEntry(2)
 148.370 +	{}
 148.371 +};
 148.372 +
 148.373 +// ---------------------------------------------------------------------------
 148.374 +/** \brief Represents a weight map 
 148.375 + */
 148.376 +struct WeightChannel : public VMapEntry
 148.377 +{
 148.378 +	WeightChannel()
 148.379 +		: VMapEntry(1)
 148.380 +	{}
 148.381 +};
 148.382 +
 148.383 +// ---------------------------------------------------------------------------
 148.384 +/** \brief Represents a vertex-normals channel (MODO extension)
 148.385 + */
 148.386 +struct NormalChannel : public VMapEntry
 148.387 +{
 148.388 +	NormalChannel()
 148.389 +		: VMapEntry(3)
 148.390 +	{}
 148.391 +};
 148.392 +
 148.393 +// ---------------------------------------------------------------------------
 148.394 +/** \brief Data structure for a LWO file texture
 148.395 + */
 148.396 +struct Texture
 148.397 +{
 148.398 +	// we write the enum values out here to make debugging easier ...
 148.399 +	enum BlendType
 148.400 +	{
 148.401 +		Normal			= 0,
 148.402 +		Subtractive		= 1,
 148.403 +		Difference		= 2,
 148.404 +		Multiply		= 3,
 148.405 +		Divide			= 4,
 148.406 +		Alpha			= 5,
 148.407 +		TextureDispl	= 6,
 148.408 +		Additive		= 7
 148.409 +	};
 148.410 +
 148.411 +	enum MappingMode
 148.412 +	{
 148.413 +		Planar			= 0,
 148.414 +		Cylindrical		= 1,
 148.415 +		Spherical		= 2,
 148.416 +		Cubic			= 3,
 148.417 +		FrontProjection	= 4,
 148.418 +		UV				= 5
 148.419 +	};
 148.420 +
 148.421 +	enum Axes
 148.422 +	{
 148.423 +		AXIS_X			= 0,
 148.424 +		AXIS_Y			= 1,
 148.425 +		AXIS_Z			= 2
 148.426 +	};
 148.427 +
 148.428 +	enum Wrap
 148.429 +	{
 148.430 +		RESET			= 0,
 148.431 +		REPEAT			= 1,
 148.432 +		MIRROR			= 2,
 148.433 +		EDGE			= 3
 148.434 +	};
 148.435 +
 148.436 +	Texture()
 148.437 +		: mClipIdx(UINT_MAX)
 148.438 +		, mStrength			(1.0f)
 148.439 +		, mUVChannelIndex	("unknown")
 148.440 +		, mRealUVIndex		(UINT_MAX)
 148.441 +		, enabled			(true)
 148.442 +		, blendType			(Additive)
 148.443 +		, bCanUse			(true)
 148.444 +		, mapMode			(UV)
 148.445 +		, majorAxis			(AXIS_X)
 148.446 +		, wrapAmountH		(1.0f)
 148.447 +		, wrapAmountW		(1.0f)
 148.448 +		, wrapModeWidth		(REPEAT)
 148.449 +		, wrapModeHeight	(REPEAT)
 148.450 +		, ordinal			("\x00")
 148.451 +	{}
 148.452 +
 148.453 +	//! File name of the texture
 148.454 +	std::string mFileName;
 148.455 +
 148.456 +	//! Clip index
 148.457 +	unsigned int mClipIdx;
 148.458 +
 148.459 +	//! Strength of the texture - blend factor
 148.460 +	float mStrength;
 148.461 +
 148.462 +	uint32_t type; // type of the texture
 148.463 +
 148.464 +	//! Name of the corresponding UV channel
 148.465 +	std::string mUVChannelIndex;
 148.466 +	unsigned int mRealUVIndex;
 148.467 +
 148.468 +	//! is the texture enabled?
 148.469 +	bool enabled;
 148.470 +
 148.471 +	//! blend type
 148.472 +	BlendType blendType;
 148.473 +
 148.474 +	//! are we able to use the texture?
 148.475 +	bool bCanUse;
 148.476 +
 148.477 +	//! mapping mode
 148.478 +	MappingMode mapMode;
 148.479 +
 148.480 +	//! major axis for planar, cylindrical, spherical projections
 148.481 +	Axes majorAxis;
 148.482 +
 148.483 +	//! wrap amount for cylindrical and spherical projections
 148.484 +	float wrapAmountH,wrapAmountW;
 148.485 +
 148.486 +	//! wrapping mode for the texture
 148.487 +	Wrap wrapModeWidth,wrapModeHeight;
 148.488 +
 148.489 +	//! ordinal string of the texture
 148.490 +	std::string ordinal;
 148.491 +};
 148.492 +
 148.493 +// ---------------------------------------------------------------------------
 148.494 +/** \brief Data structure for a LWO file clip
 148.495 + */
 148.496 +struct Clip
 148.497 +{
 148.498 +	enum Type
 148.499 +	{
 148.500 +		 STILL, SEQ, REF, UNSUPPORTED
 148.501 +	} type;
 148.502 +
 148.503 +	Clip()
 148.504 +		: type	 (UNSUPPORTED)
 148.505 +		, idx	 (0)
 148.506 +		, negate (false)
 148.507 +	{}
 148.508 +
 148.509 +	//! path to the base texture -
 148.510 +	std::string path;
 148.511 +
 148.512 +	//! reference to another CLIP
 148.513 +	unsigned int clipRef;
 148.514 +
 148.515 +	//! index of the clip
 148.516 +	unsigned int idx;
 148.517 +
 148.518 +	//! Negate the clip?
 148.519 +	bool negate;
 148.520 +};
 148.521 +
 148.522 +
 148.523 +// ---------------------------------------------------------------------------
 148.524 +/** \brief Data structure for a LWO file shader
 148.525 + *
 148.526 + *  Later
 148.527 + */
 148.528 +struct Shader
 148.529 +{
 148.530 +	Shader()
 148.531 +		:	ordinal			("\x00")
 148.532 +		,	functionName	("unknown")
 148.533 +		,	enabled			(true)
 148.534 +	{}
 148.535 +
 148.536 +	std::string ordinal;
 148.537 +	std::string functionName;
 148.538 +	bool enabled;
 148.539 +};
 148.540 +
 148.541 +typedef std::list < Texture >		TextureList;
 148.542 +typedef std::list < Shader >		ShaderList;
 148.543 +
 148.544 +// ---------------------------------------------------------------------------
 148.545 +/** \brief Data structure for a LWO file surface (= material)
 148.546 + */
 148.547 +struct Surface
 148.548 +{
 148.549 +	Surface()
 148.550 +		: mColor				(0.78431f,0.78431f,0.78431f)
 148.551 +		, bDoubleSided			(false)
 148.552 +		, mDiffuseValue			(1.f)
 148.553 +		, mSpecularValue		(0.f)
 148.554 +		, mTransparency			(0.f)
 148.555 +		, mGlossiness			(0.4f)
 148.556 +		, mLuminosity			(0.f)
 148.557 +		, mColorHighlights		(0.f)
 148.558 +		, mMaximumSmoothAngle	(0.f) // 0 == not specified, no smoothing
 148.559 +		, mVCMap				("")
 148.560 +		, mVCMapType			(AI_LWO_RGBA)
 148.561 +		, mIOR					(1.f) // vakuum
 148.562 +		, mBumpIntensity		(1.f)
 148.563 +		, mWireframe			(false)
 148.564 +		, mAdditiveTransparency (0.f)
 148.565 +	{}
 148.566 +
 148.567 +	//! Name of the surface
 148.568 +	std::string mName;
 148.569 +
 148.570 +	//! Color of the surface
 148.571 +	aiColor3D mColor;
 148.572 +
 148.573 +	//! true for two-sided materials
 148.574 +	bool bDoubleSided;
 148.575 +
 148.576 +	//! Various material parameters
 148.577 +	float mDiffuseValue,mSpecularValue,mTransparency,mGlossiness,mLuminosity,mColorHighlights;
 148.578 +
 148.579 +	//! Maximum angle between two adjacent triangles
 148.580 +	//! that they can be smoothed - in degrees
 148.581 +	float mMaximumSmoothAngle;
 148.582 +
 148.583 +	//! Vertex color map to be used to color the surface
 148.584 +	std::string mVCMap;
 148.585 +	uint32_t mVCMapType;
 148.586 +
 148.587 +	//! Names of the special shaders to be applied to the surface
 148.588 +	ShaderList mShaders;
 148.589 +
 148.590 +	//! Textures - the first entry in the list is evaluated first
 148.591 +	TextureList mColorTextures, // color textures are added to both diffuse and specular texture stacks
 148.592 +		mDiffuseTextures,
 148.593 +		mSpecularTextures,
 148.594 +		mOpacityTextures,
 148.595 +		mBumpTextures,
 148.596 +		mGlossinessTextures,
 148.597 +		mReflectionTextures;
 148.598 +
 148.599 +	//! Index of refraction
 148.600 +	float mIOR;
 148.601 +
 148.602 +	//! Bump intensity scaling
 148.603 +	float mBumpIntensity;
 148.604 +
 148.605 +	//! Wireframe flag
 148.606 +	bool mWireframe;
 148.607 +
 148.608 +	//! Intensity of additive blending
 148.609 +	float mAdditiveTransparency;
 148.610 +};
 148.611 +
 148.612 +// ---------------------------------------------------------------------------
 148.613 +#define AI_LWO_VALIDATE_CHUNK_LENGTH(length,name,size) \
 148.614 +	if (length < size) \
 148.615 +	{ \
 148.616 +		throw DeadlyImportError("LWO: "#name" chunk is too small"); \
 148.617 +	} \
 148.618 +
 148.619 +
 148.620 +// some typedefs ... to make life with loader monsters like this easier
 148.621 +typedef std::vector	<	aiVector3D		>	PointList;
 148.622 +typedef std::vector	<	LWO::Face		>	FaceList;
 148.623 +typedef std::vector	<	LWO::Surface	>	SurfaceList;
 148.624 +typedef std::vector	<	std::string		>	TagList;
 148.625 +typedef std::vector	<	unsigned int	>	TagMappingTable;
 148.626 +typedef std::vector	<	unsigned int	>	ReferrerList;
 148.627 +typedef std::vector	<	WeightChannel	>	WeightChannelList;
 148.628 +typedef std::vector	<	VColorChannel	>	VColorChannelList;
 148.629 +typedef std::vector	<	UVChannel		>	UVChannelList;
 148.630 +typedef std::vector	<	Clip			>	ClipList;
 148.631 +typedef std::vector	<	Envelope		>	EnvelopeList;
 148.632 +typedef std::vector <   unsigned int    >   SortedRep;
 148.633 +
 148.634 +// ---------------------------------------------------------------------------
 148.635 +/** \brief Represents a layer in the file
 148.636 + */
 148.637 +struct Layer
 148.638 +{
 148.639 +	Layer()
 148.640 +		: mFaceIDXOfs	(0)
 148.641 +		, mPointIDXOfs	(0)
 148.642 +		, mParent		(0x0)
 148.643 +		, mIndex		(0xffff)
 148.644 +		, skip			(false)
 148.645 +	{}
 148.646 +
 148.647 +	/** Temporary point list from the file */
 148.648 +	PointList mTempPoints;
 148.649 +
 148.650 +	/** Lists for every point the index of another point
 148.651 +	    that has been copied from *this* point or UINT_MAX if
 148.652 +		no copy of the point has been made */
 148.653 +	ReferrerList mPointReferrers;
 148.654 +
 148.655 +	/** Weight channel list from the file */
 148.656 +	WeightChannelList mWeightChannels;
 148.657 +
 148.658 +	/** Subdivision weight channel list from the file */
 148.659 +	WeightChannelList mSWeightChannels;
 148.660 +
 148.661 +	/** Vertex color list from the file */
 148.662 +	VColorChannelList mVColorChannels;
 148.663 +
 148.664 +	/** UV channel list from the file */
 148.665 +	UVChannelList mUVChannels;
 148.666 +
 148.667 +	/** Normal vector channel from the file */
 148.668 +	NormalChannel mNormals;
 148.669 +
 148.670 +	/** Temporary face list from the file*/
 148.671 +	FaceList mFaces;
 148.672 +
 148.673 +	/** Current face indexing offset from the beginning of the buffers*/
 148.674 +	unsigned int mFaceIDXOfs;
 148.675 +
 148.676 +	/** Current point indexing offset from the beginning of the buffers*/
 148.677 +	unsigned int mPointIDXOfs;
 148.678 +
 148.679 +	/** Parent index */
 148.680 +	uint16_t mParent;
 148.681 +
 148.682 +	/** Index of the layer */
 148.683 +	uint16_t mIndex;
 148.684 +
 148.685 +	/** Name of the layer */
 148.686 +	std::string mName;
 148.687 +
 148.688 +	/** Pivot point of the layer */
 148.689 +	aiVector3D mPivot;
 148.690 +
 148.691 +	/** Skip this layer? */
 148.692 +	bool skip;
 148.693 +};
 148.694 +
 148.695 +typedef std::list<LWO::Layer>		LayerList;
 148.696 +
 148.697 +
 148.698 +}}
 148.699 +
 148.700 +
 148.701 +#endif // !! AI_LWO_FILEDATA_INCLUDED
 148.702 +
   149.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   149.2 +++ b/libs/assimp/LWOLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   149.3 @@ -0,0 +1,1436 @@
   149.4 +/*
   149.5 +---------------------------------------------------------------------------
   149.6 +Open Asset Import Library (assimp)
   149.7 +---------------------------------------------------------------------------
   149.8 +
   149.9 +Copyright (c) 2006-2012, assimp team
  149.10 +
  149.11 +All rights reserved.
  149.12 +
  149.13 +Redistribution and use of this software in source and binary forms, 
  149.14 +with or without modification, are permitted provided that the following 
  149.15 +conditions are met:
  149.16 +
  149.17 +* Redistributions of source code must retain the above
  149.18 +  copyright notice, this list of conditions and the
  149.19 +  following disclaimer.
  149.20 +
  149.21 +* Redistributions in binary form must reproduce the above
  149.22 +  copyright notice, this list of conditions and the
  149.23 +  following disclaimer in the documentation and/or other
  149.24 +  materials provided with the distribution.
  149.25 +
  149.26 +* Neither the name of the assimp team, nor the names of its
  149.27 +  contributors may be used to endorse or promote products
  149.28 +  derived from this software without specific prior
  149.29 +  written permission of the assimp team.
  149.30 +
  149.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  149.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  149.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  149.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  149.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  149.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  149.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  149.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  149.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  149.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  149.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  149.42 +---------------------------------------------------------------------------
  149.43 +*/
  149.44 +
  149.45 +/** @file  LWOLoader.cpp
  149.46 + *  @brief Implementation of the LWO importer class
  149.47 + */
  149.48 +
  149.49 +#include "AssimpPCH.h"
  149.50 +#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
  149.51 +
  149.52 +// internal headers
  149.53 +#include "LWOLoader.h"
  149.54 +#include "StringComparison.h"
  149.55 +#include "SGSpatialSort.h"
  149.56 +#include "ByteSwap.h"
  149.57 +#include "ProcessHelper.h"
  149.58 +#include "ConvertToLHProcess.h"
  149.59 +
  149.60 +using namespace Assimp;
  149.61 +
  149.62 +static const aiImporterDesc desc = {
  149.63 +	"LightWave/Modo Object Importer",
  149.64 +	"",
  149.65 +	"",
  149.66 +	"http://www.newtek.com/lightwave.html\nhttp://www.luxology.com/modo/",
  149.67 +	aiImporterFlags_SupportTextFlavour,
  149.68 +	0,
  149.69 +	0,
  149.70 +	0,
  149.71 +	0,
  149.72 +	"lwo lxo"
  149.73 +};
  149.74 +
  149.75 +// ------------------------------------------------------------------------------------------------
  149.76 +// Constructor to be privately used by Importer
  149.77 +LWOImporter::LWOImporter()
  149.78 +{}
  149.79 +
  149.80 +// ------------------------------------------------------------------------------------------------
  149.81 +// Destructor, private as well 
  149.82 +LWOImporter::~LWOImporter()
  149.83 +{}
  149.84 +
  149.85 +// ------------------------------------------------------------------------------------------------
  149.86 +// Returns whether the class can handle the format of the given file. 
  149.87 +bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  149.88 +{
  149.89 +	const std::string extension = GetExtension(pFile);
  149.90 +	if (extension == "lwo" || extension == "lxo") {
  149.91 +		return true;
  149.92 +	}
  149.93 +
  149.94 +	// if check for extension is not enough, check for the magic tokens 
  149.95 +	if (!extension.length() || checkSig) {
  149.96 +		uint32_t tokens[3]; 
  149.97 +		tokens[0] = AI_LWO_FOURCC_LWOB;
  149.98 +		tokens[1] = AI_LWO_FOURCC_LWO2;
  149.99 +		tokens[2] = AI_LWO_FOURCC_LXOB;
 149.100 +		return CheckMagicToken(pIOHandler,pFile,tokens,3,8);
 149.101 +	}
 149.102 +	return false;
 149.103 +}
 149.104 +
 149.105 +// ------------------------------------------------------------------------------------------------
 149.106 +// Setup configuration properties
 149.107 +void LWOImporter::SetupProperties(const Importer* pImp)
 149.108 +{
 149.109 +	configSpeedFlag  = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0) ? true : false);
 149.110 +	configLayerIndex = pImp->GetPropertyInteger (AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,UINT_MAX); 
 149.111 +	configLayerName  = pImp->GetPropertyString  (AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,"");
 149.112 +}
 149.113 +
 149.114 +// ------------------------------------------------------------------------------------------------
 149.115 +// Get list of file extensions
 149.116 +const aiImporterDesc* LWOImporter::GetInfo () const
 149.117 +{
 149.118 +	return &desc;
 149.119 +}
 149.120 +
 149.121 +// ------------------------------------------------------------------------------------------------
 149.122 +// Imports the given file into the given scene structure. 
 149.123 +void LWOImporter::InternReadFile( const std::string& pFile, 
 149.124 +	aiScene* pScene, 
 149.125 +	IOSystem* pIOHandler)
 149.126 +{
 149.127 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 149.128 +
 149.129 +	// Check whether we can read from the file
 149.130 +	if( file.get() == NULL)
 149.131 +		throw DeadlyImportError( "Failed to open LWO file " + pFile + ".");
 149.132 +
 149.133 +	if((this->fileSize = (unsigned int)file->FileSize()) < 12)
 149.134 +		throw DeadlyImportError("LWO: The file is too small to contain the IFF header");
 149.135 +
 149.136 +	// Allocate storage and copy the contents of the file to a memory buffer
 149.137 +	std::vector< uint8_t > mBuffer(fileSize);
 149.138 +	file->Read( &mBuffer[0], 1, fileSize);
 149.139 +	this->pScene = pScene;
 149.140 +
 149.141 +	// Determine the type of the file
 149.142 +	uint32_t fileType;
 149.143 +	const char* sz = IFF::ReadHeader(&mBuffer[0],fileType);
 149.144 +	if (sz)throw DeadlyImportError(sz);
 149.145 +
 149.146 +	mFileBuffer = &mBuffer[0] + 12;
 149.147 +	fileSize -= 12;
 149.148 +
 149.149 +	// Initialize some members with their default values
 149.150 +	hasNamedLayer   = false;
 149.151 +
 149.152 +	// Create temporary storage on the stack but store pointers to it in the class 
 149.153 +	// instance. Therefore everything will be destructed properly if an exception 
 149.154 +	// is thrown and we needn't take care of that.
 149.155 +	LayerList		_mLayers;
 149.156 +	SurfaceList		_mSurfaces;		
 149.157 +	TagList			_mTags;		
 149.158 +	TagMappingTable _mMapping;	
 149.159 +
 149.160 +	mLayers			= &_mLayers;
 149.161 +	mTags			= &_mTags;
 149.162 +	mMapping		= &_mMapping;
 149.163 +	mSurfaces		= &_mSurfaces;
 149.164 +
 149.165 +	// Allocate a default layer (layer indices are 1-based from now)
 149.166 +	mLayers->push_back(Layer());
 149.167 +	mCurLayer = &mLayers->back();
 149.168 +	mCurLayer->mName = "<LWODefault>";
 149.169 +	mCurLayer->mIndex = -1;
 149.170 +
 149.171 +	// old lightwave file format (prior to v6)
 149.172 +	if (AI_LWO_FOURCC_LWOB == fileType)	{
 149.173 +		DefaultLogger::get()->info("LWO file format: LWOB (<= LightWave 5.5)");
 149.174 +
 149.175 +		mIsLWO2 = false;
 149.176 +        mIsLXOB = false;
 149.177 +		LoadLWOBFile();
 149.178 +	}
 149.179 +	// New lightwave format
 149.180 +	else if (AI_LWO_FOURCC_LWO2 == fileType)	{
 149.181 +        mIsLXOB = false;
 149.182 +		DefaultLogger::get()->info("LWO file format: LWO2 (>= LightWave 6)");
 149.183 +	}
 149.184 +	// MODO file format
 149.185 +	else if (AI_LWO_FOURCC_LXOB == fileType)	{
 149.186 +        mIsLXOB = true;
 149.187 +		DefaultLogger::get()->info("LWO file format: LXOB (Modo)");
 149.188 +	}
 149.189 +	// we don't know this format
 149.190 +	else 
 149.191 +	{
 149.192 +		char szBuff[5];
 149.193 +		szBuff[0] = (char)(fileType >> 24u);
 149.194 +		szBuff[1] = (char)(fileType >> 16u);
 149.195 +		szBuff[2] = (char)(fileType >> 8u);
 149.196 +		szBuff[3] = (char)(fileType);
 149.197 +		szBuff[4] = '\0';
 149.198 +		throw DeadlyImportError(std::string("Unknown LWO sub format: ") + szBuff);
 149.199 +	}
 149.200 +
 149.201 +	if (AI_LWO_FOURCC_LWOB != fileType)	{
 149.202 +		mIsLWO2 = true;
 149.203 +		LoadLWO2File();
 149.204 +
 149.205 +		// The newer lightwave format allows the user to configure the
 149.206 +		// loader that just one layer is used. If this is the case
 149.207 +		// we need to check now whether the requested layer has been found.
 149.208 +		if (UINT_MAX != configLayerIndex) {
 149.209 +			unsigned int layerCount = 0;
 149.210 +			for(std::list<LWO::Layer>::iterator itLayers=mLayers->begin(); itLayers!=mLayers->end(); itLayers++)
 149.211 +				if (!itLayers->skip)
 149.212 +					layerCount++;
 149.213 +			if (layerCount!=2)
 149.214 +				throw DeadlyImportError("LWO2: The requested layer was not found");
 149.215 +		}
 149.216 +
 149.217 +		if (configLayerName.length() && !hasNamedLayer)	{
 149.218 +			throw DeadlyImportError("LWO2: Unable to find the requested layer: " 
 149.219 +				+ configLayerName);
 149.220 +		}
 149.221 +	}
 149.222 +
 149.223 +	// now, as we have loaded all data, we can resolve cross-referenced tags and clips
 149.224 +	ResolveTags();
 149.225 +	ResolveClips();
 149.226 +
 149.227 +	// now process all layers and build meshes and nodes
 149.228 +	std::vector<aiMesh*> apcMeshes;
 149.229 +	std::map<uint16_t, aiNode*> apcNodes;
 149.230 +
 149.231 +	apcMeshes.reserve(mLayers->size()*std::min(((unsigned int)mSurfaces->size()/2u), 1u));
 149.232 +
 149.233 +	unsigned int iDefaultSurface = UINT_MAX; // index of the default surface
 149.234 +	for (LayerList::iterator lit = mLayers->begin(), lend = mLayers->end();lit != lend;++lit)	{
 149.235 +		LWO::Layer& layer = *lit;
 149.236 +		if (layer.skip)
 149.237 +			continue;
 149.238 +
 149.239 +		// I don't know whether there could be dummy layers, but it would be possible
 149.240 +		const unsigned int meshStart = (unsigned int)apcMeshes.size();
 149.241 +		if (!layer.mFaces.empty() && !layer.mTempPoints.empty())	{
 149.242 +
 149.243 +			// now sort all faces by the surfaces assigned to them
 149.244 +			std::vector<SortedRep> pSorted(mSurfaces->size()+1);
 149.245 +
 149.246 +			unsigned int i = 0;
 149.247 +			for (FaceList::iterator it = layer.mFaces.begin(), end = layer.mFaces.end();it != end;++it,++i)	{
 149.248 +				// Check whether we support this face's type
 149.249 +				if ((*it).type != AI_LWO_FACE && (*it).type != AI_LWO_PTCH &&
 149.250 +				    (*it).type != AI_LWO_BONE && (*it).type != AI_LWO_SUBD) {
 149.251 +					continue;
 149.252 +				}
 149.253 +
 149.254 +				unsigned int idx = (*it).surfaceIndex;
 149.255 +				if (idx >= mTags->size())
 149.256 +				{
 149.257 +					DefaultLogger::get()->warn("LWO: Invalid face surface index");
 149.258 +					idx = UINT_MAX;
 149.259 +				}
 149.260 +				if(UINT_MAX == idx || UINT_MAX == (idx = _mMapping[idx]))	{
 149.261 +					if (UINT_MAX == iDefaultSurface)	{
 149.262 +						iDefaultSurface = (unsigned int)mSurfaces->size();
 149.263 +						mSurfaces->push_back(LWO::Surface());
 149.264 +						LWO::Surface& surf = mSurfaces->back();
 149.265 +						surf.mColor.r = surf.mColor.g = surf.mColor.b = 0.6f; 
 149.266 +						surf.mName = "LWODefaultSurface";
 149.267 +					}
 149.268 +					idx = iDefaultSurface;
 149.269 +				}
 149.270 +				pSorted[idx].push_back(i);
 149.271 +			}
 149.272 +			if (UINT_MAX == iDefaultSurface) {
 149.273 +				pSorted.erase(pSorted.end()-1);
 149.274 +			}
 149.275 +			for (unsigned int p = 0,i = 0;i < mSurfaces->size();++i)	{
 149.276 +				SortedRep& sorted = pSorted[i];
 149.277 +				if (sorted.empty())
 149.278 +					continue;
 149.279 +
 149.280 +				// generate the mesh 
 149.281 +				aiMesh* mesh = new aiMesh();
 149.282 +				apcMeshes.push_back(mesh);
 149.283 +				mesh->mNumFaces = (unsigned int)sorted.size();
 149.284 +
 149.285 +				// count the number of vertices
 149.286 +				SortedRep::const_iterator it = sorted.begin(), end = sorted.end();
 149.287 +				for (;it != end;++it)	{
 149.288 +					mesh->mNumVertices += layer.mFaces[*it].mNumIndices;
 149.289 +				}
 149.290 +
 149.291 +				aiVector3D *nrm = NULL, * pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
 149.292 +				aiFace* pf = mesh->mFaces = new aiFace[mesh->mNumFaces];
 149.293 +				mesh->mMaterialIndex = i;
 149.294 +
 149.295 +				// find out which vertex color channels and which texture coordinate
 149.296 +				// channels are really required by the material attached to this mesh
 149.297 +				unsigned int vUVChannelIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 149.298 +				unsigned int vVColorIndices[AI_MAX_NUMBER_OF_COLOR_SETS];
 149.299 +
 149.300 +#if _DEBUG
 149.301 +				for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui ) {
 149.302 +					vUVChannelIndices[mui] = UINT_MAX;
 149.303 +				}
 149.304 +				for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS;++mui ) {
 149.305 +					vVColorIndices[mui] = UINT_MAX;
 149.306 +				}
 149.307 +#endif
 149.308 +
 149.309 +				FindUVChannels(_mSurfaces[i],sorted,layer,vUVChannelIndices);
 149.310 +				FindVCChannels(_mSurfaces[i],sorted,layer,vVColorIndices);
 149.311 +
 149.312 +				// allocate storage for UV and CV channels
 149.313 +				aiVector3D* pvUV[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 149.314 +				for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui )	{
 149.315 +					if (UINT_MAX == vUVChannelIndices[mui]) {
 149.316 +						break;
 149.317 +					}
 149.318 +					
 149.319 +					pvUV[mui] = mesh->mTextureCoords[mui] = new aiVector3D[mesh->mNumVertices];
 149.320 +
 149.321 +					// LightWave doesn't support more than 2 UV components (?)
 149.322 +					mesh->mNumUVComponents[0] = 2;
 149.323 +				}
 149.324 +
 149.325 +				if (layer.mNormals.name.length())
 149.326 +					nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
 149.327 +		
 149.328 +				aiColor4D* pvVC[AI_MAX_NUMBER_OF_COLOR_SETS];
 149.329 +				for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS;++mui)	{
 149.330 +					if (UINT_MAX == vVColorIndices[mui]) {
 149.331 +						break;
 149.332 +					}
 149.333 +					pvVC[mui] = mesh->mColors[mui] = new aiColor4D[mesh->mNumVertices];
 149.334 +				}
 149.335 +
 149.336 +				// we would not need this extra array, but the code is much cleaner if we use it
 149.337 +				std::vector<unsigned int>& smoothingGroups = layer.mPointReferrers;
 149.338 +				smoothingGroups.erase (smoothingGroups.begin(),smoothingGroups.end());
 149.339 +				smoothingGroups.resize(mesh->mNumFaces,0);
 149.340 +
 149.341 +				// now convert all faces
 149.342 +				unsigned int vert = 0;
 149.343 +				std::vector<unsigned int>::iterator outIt = smoothingGroups.begin();
 149.344 +				for (it = sorted.begin(); it != end;++it,++outIt)	{
 149.345 +					const LWO::Face& face = layer.mFaces[*it];
 149.346 +					*outIt = face.smoothGroup;
 149.347 +
 149.348 +					// copy all vertices
 149.349 +					for (unsigned int q = 0; q  < face.mNumIndices;++q,++vert)	{
 149.350 +						register unsigned int idx = face.mIndices[q];
 149.351 +						*pv++ = layer.mTempPoints[idx] /*- layer.mPivot*/;
 149.352 +
 149.353 +						// process UV coordinates
 149.354 +						for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_TEXTURECOORDS;++w)	{
 149.355 +							if (UINT_MAX == vUVChannelIndices[w]) {
 149.356 +								break;
 149.357 +							}
 149.358 +							aiVector3D*& pp = pvUV[w];
 149.359 +							const aiVector2D& src = ((aiVector2D*)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx];
 149.360 +							pp->x = src.x;
 149.361 +							pp->y = src.y; 
 149.362 +							pp++;
 149.363 +						}
 149.364 +
 149.365 +						// process normals (MODO extension)
 149.366 +						if (nrm)	{
 149.367 +							*nrm = ((aiVector3D*)&layer.mNormals.rawData[0])[idx];
 149.368 +							nrm->z *= -1.f;
 149.369 +							++nrm;
 149.370 +						}
 149.371 +
 149.372 +						// process vertex colors
 149.373 +						for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_COLOR_SETS;++w)	{
 149.374 +							if (UINT_MAX == vVColorIndices[w]) {
 149.375 +								break;
 149.376 +							}
 149.377 +							*pvVC[w] = ((aiColor4D*)&layer.mVColorChannels[vVColorIndices[w]].rawData[0])[idx];
 149.378 +
 149.379 +							// If a RGB color map is explicitly requested delete the
 149.380 +							// alpha channel - it could theoretically be != 1.
 149.381 +							if(_mSurfaces[i].mVCMapType == AI_LWO_RGB)
 149.382 +								pvVC[w]->a = 1.f;
 149.383 +
 149.384 +							pvVC[w]++;
 149.385 +						}
 149.386 +
 149.387 +#if 0
 149.388 +						// process vertex weights. We can't properly reconstruct the whole skeleton for now,
 149.389 +						// but we can create dummy bones for all weight channels which we have.
 149.390 +						for (unsigned int w = 0; w < layer.mWeightChannels.size();++w)
 149.391 +						{
 149.392 +						}
 149.393 +#endif
 149.394 +
 149.395 +						face.mIndices[q] = vert;
 149.396 +					}
 149.397 +					pf->mIndices = face.mIndices;
 149.398 +					pf->mNumIndices = face.mNumIndices;
 149.399 +					unsigned int** p = (unsigned int**)&face.mIndices;*p = NULL; // HACK: make sure it won't be deleted
 149.400 +					pf++;
 149.401 +				}
 149.402 +
 149.403 +				if (!mesh->mNormals)	{
 149.404 +					// Compute normal vectors for the mesh - we can't use our GenSmoothNormal-
 149.405 +					// Step here since it wouldn't handle smoothing groups correctly for LWO.
 149.406 +					// So we use a separate implementation. 
 149.407 +					ComputeNormals(mesh,smoothingGroups,_mSurfaces[i]);
 149.408 +				}
 149.409 +				else DefaultLogger::get()->debug("LWO2: No need to compute normals, they're already there");
 149.410 +				++p;
 149.411 +			}
 149.412 +		}
 149.413 +
 149.414 +		// Generate nodes to render the mesh. Store the source layer in the mParent member of the nodes
 149.415 +		unsigned int num = apcMeshes.size() - meshStart;
 149.416 +		if (layer.mName != "<LWODefault>" || num > 0) {
 149.417 +			aiNode* pcNode = new aiNode();
 149.418 +			apcNodes[layer.mIndex] = pcNode;
 149.419 +			pcNode->mName.Set(layer.mName);
 149.420 +			pcNode->mParent = (aiNode*)&layer;
 149.421 +			pcNode->mNumMeshes = num;
 149.422 +
 149.423 +			if (pcNode->mNumMeshes) {
 149.424 +				pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
 149.425 +				for (unsigned int p = 0; p < pcNode->mNumMeshes;++p)
 149.426 +					pcNode->mMeshes[p] = p + meshStart;
 149.427 +			}
 149.428 +		}
 149.429 +	}
 149.430 +
 149.431 +	if (apcNodes.empty() || apcMeshes.empty())
 149.432 +		throw DeadlyImportError("LWO: No meshes loaded");
 149.433 +
 149.434 +	// The RemoveRedundantMaterials step will clean this up later
 149.435 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = (unsigned int)mSurfaces->size()];
 149.436 +	for (unsigned int mat = 0; mat < pScene->mNumMaterials;++mat)	{
 149.437 +		aiMaterial* pcMat = new aiMaterial();
 149.438 +		pScene->mMaterials[mat] = pcMat;
 149.439 +		ConvertMaterial((*mSurfaces)[mat],pcMat);
 149.440 +	}
 149.441 +
 149.442 +	// copy the meshes to the output structure
 149.443 +	pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = (unsigned int)apcMeshes.size() ];
 149.444 +	::memcpy(pScene->mMeshes,&apcMeshes[0],pScene->mNumMeshes*sizeof(void*));
 149.445 +
 149.446 +	// generate the final node graph
 149.447 +	GenerateNodeGraph(apcNodes);
 149.448 +}
 149.449 +
 149.450 +// ------------------------------------------------------------------------------------------------
 149.451 +void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& smoothingGroups,
 149.452 +	const LWO::Surface& surface)
 149.453 +{
 149.454 +	// Allocate output storage
 149.455 +	mesh->mNormals = new aiVector3D[mesh->mNumVertices];
 149.456 +
 149.457 +	// First generate per-face normals
 149.458 +	aiVector3D* out;
 149.459 +	std::vector<aiVector3D> faceNormals;
 149.460 +
 149.461 +	// ... in some cases that's already enough
 149.462 +	if (!surface.mMaximumSmoothAngle)
 149.463 +		out = mesh->mNormals;
 149.464 +	else	{
 149.465 +		faceNormals.resize(mesh->mNumVertices);
 149.466 +		out = &faceNormals[0];
 149.467 +	}
 149.468 +
 149.469 +	aiFace* begin = mesh->mFaces, *const end = mesh->mFaces+mesh->mNumFaces;
 149.470 +	for (; begin != end; ++begin)	{
 149.471 +		aiFace& face = *begin;
 149.472 +
 149.473 +		if(face.mNumIndices < 3) {
 149.474 +			continue;
 149.475 +		}
 149.476 +
 149.477 +		// LWO doc: "the normal is defined as the cross product of the first and last edges"
 149.478 +		aiVector3D* pV1 = mesh->mVertices + face.mIndices[0];
 149.479 +		aiVector3D* pV2 = mesh->mVertices + face.mIndices[1];
 149.480 +		aiVector3D* pV3 = mesh->mVertices + face.mIndices[face.mNumIndices-1];
 149.481 +
 149.482 +		aiVector3D vNor = ((*pV2 - *pV1) ^(*pV3 - *pV1)).Normalize();
 149.483 +		for (unsigned int i = 0; i < face.mNumIndices;++i)
 149.484 +			out[face.mIndices[i]] = vNor;
 149.485 +	}
 149.486 +	if (!surface.mMaximumSmoothAngle)return;
 149.487 +	const float posEpsilon = ComputePositionEpsilon(mesh);
 149.488 +	
 149.489 +	// Now generate the spatial sort tree
 149.490 +	SGSpatialSort sSort;
 149.491 +	std::vector<unsigned int>::const_iterator it = smoothingGroups.begin();
 149.492 +	for( begin =  mesh->mFaces; begin != end; ++begin, ++it)
 149.493 +	{
 149.494 +		aiFace& face = *begin;
 149.495 +		for (unsigned int i = 0; i < face.mNumIndices;++i)
 149.496 +		{
 149.497 +			register unsigned int tt = face.mIndices[i];
 149.498 +			sSort.Add(mesh->mVertices[tt],tt,*it);
 149.499 +		}
 149.500 +	}
 149.501 +	// Sort everything - this takes O(nlogn) time
 149.502 +	sSort.Prepare();
 149.503 +	std::vector<unsigned int> poResult;
 149.504 +	poResult.reserve(20);
 149.505 +
 149.506 +	// Generate vertex normals. We have O(logn) for the binary lookup, which we need
 149.507 +	// for n elements, thus the EXPECTED complexity is O(nlogn)
 149.508 +	if (surface.mMaximumSmoothAngle < 3.f && !configSpeedFlag)	{
 149.509 +		const float fLimit = cos(surface.mMaximumSmoothAngle);
 149.510 +
 149.511 +		for( begin =  mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it)	{
 149.512 +			const aiFace& face = *begin;
 149.513 +			unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices;
 149.514 +			for (; beginIdx != endIdx; ++beginIdx)
 149.515 +			{
 149.516 +				register unsigned int idx = *beginIdx;
 149.517 +				sSort.FindPositions(mesh->mVertices[idx],*it,posEpsilon,poResult,true);
 149.518 +				std::vector<unsigned int>::const_iterator a, end = poResult.end();
 149.519 +
 149.520 +				aiVector3D vNormals;
 149.521 +				for (a =  poResult.begin();a != end;++a)	{
 149.522 +					const aiVector3D& v = faceNormals[*a];
 149.523 +					if (v * faceNormals[idx] < fLimit)
 149.524 +						continue;
 149.525 +					vNormals += v;
 149.526 +				}
 149.527 +				mesh->mNormals[idx] = vNormals.Normalize();
 149.528 +			}
 149.529 +		}
 149.530 +	}
 149.531 +	 // faster code path in case there is no smooth angle
 149.532 +	else	{
 149.533 +		std::vector<bool> vertexDone(mesh->mNumVertices,false);
 149.534 +		for( begin =  mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it)	{
 149.535 +			const aiFace& face = *begin;
 149.536 +			unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices;
 149.537 +			for (; beginIdx != endIdx; ++beginIdx)
 149.538 +			{
 149.539 +				register unsigned int idx = *beginIdx;
 149.540 +				if (vertexDone[idx])
 149.541 +					continue;
 149.542 +				sSort.FindPositions(mesh->mVertices[idx],*it,posEpsilon,poResult,true);
 149.543 +				std::vector<unsigned int>::const_iterator a, end = poResult.end();
 149.544 +
 149.545 +				aiVector3D vNormals;
 149.546 +				for (a =  poResult.begin();a != end;++a)	{
 149.547 +					const aiVector3D& v = faceNormals[*a];
 149.548 +					vNormals += v;
 149.549 +				}
 149.550 +				vNormals.Normalize();
 149.551 +				for (a =  poResult.begin();a != end;++a)	{
 149.552 +					mesh->mNormals[*a] = vNormals;
 149.553 +					vertexDone[*a] = true;
 149.554 +				}
 149.555 +			}
 149.556 +		}
 149.557 +	}
 149.558 +}
 149.559 +
 149.560 +// ------------------------------------------------------------------------------------------------
 149.561 +void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
 149.562 +{
 149.563 +	// now generate the final nodegraph - generate a root node and attach children
 149.564 +	aiNode* root = pScene->mRootNode = new aiNode();
 149.565 +	root->mName.Set("<LWORoot>");
 149.566 +
 149.567 +	//Set parent of all children, inserting pivots
 149.568 +	//std::cout << "Set parent of all children" << std::endl;
 149.569 +	std::map<uint16_t, aiNode*> mapPivot;
 149.570 +	for (std::map<uint16_t,aiNode*>::iterator itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
 149.571 +
 149.572 +		//Get the parent index
 149.573 +		LWO::Layer* nodeLayer = (LWO::Layer*)(itapcNodes->second->mParent);
 149.574 +		uint16_t parentIndex = nodeLayer->mParent;
 149.575 +
 149.576 +		//Create pivot node, store it into the pivot map, and set the parent as the pivot
 149.577 +		aiNode* pivotNode = new aiNode();
 149.578 +		pivotNode->mName.Set("Pivot-"+std::string(itapcNodes->second->mName.data));
 149.579 +		mapPivot[-(itapcNodes->first+2)] = pivotNode;
 149.580 +		itapcNodes->second->mParent = pivotNode;
 149.581 +
 149.582 +		//Look for the parent node to attach the pivot to
 149.583 +		if (apcNodes.find(parentIndex) != apcNodes.end()) {
 149.584 +			pivotNode->mParent = apcNodes[parentIndex];
 149.585 +		} else {
 149.586 +			//If not, attach to the root node
 149.587 +			pivotNode->mParent = root;
 149.588 +		}
 149.589 +
 149.590 +		//Set the node and the pivot node transformation
 149.591 +		itapcNodes->second->mTransformation.a4 = -nodeLayer->mPivot.x;
 149.592 +		itapcNodes->second->mTransformation.b4 = -nodeLayer->mPivot.y;
 149.593 +		itapcNodes->second->mTransformation.c4 = -nodeLayer->mPivot.z;
 149.594 +		pivotNode->mTransformation.a4 = nodeLayer->mPivot.x;
 149.595 +		pivotNode->mTransformation.b4 = nodeLayer->mPivot.y;
 149.596 +		pivotNode->mTransformation.c4 = nodeLayer->mPivot.z;
 149.597 +	}
 149.598 +
 149.599 +	//Merge pivot map into node map
 149.600 +	//std::cout << "Merge pivot map into node map" << std::endl;
 149.601 +	for (std::map<uint16_t, aiNode*>::iterator itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end(); ++itMapPivot) {
 149.602 +		apcNodes[itMapPivot->first] = itMapPivot->second;
 149.603 +	}
 149.604 +
 149.605 +	//Set children of all parents
 149.606 +	apcNodes[-1] = root;
 149.607 +	for (std::map<uint16_t,aiNode*>::iterator itMapParentNodes = apcNodes.begin(); itMapParentNodes != apcNodes.end(); ++itMapParentNodes) {
 149.608 +		for (std::map<uint16_t,aiNode*>::iterator itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
 149.609 +			if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
 149.610 +				++(itMapParentNodes->second->mNumChildren);
 149.611 +			}
 149.612 +		}
 149.613 +		if (itMapParentNodes->second->mNumChildren) {
 149.614 +			itMapParentNodes->second->mChildren = new aiNode* [ itMapParentNodes->second->mNumChildren ];
 149.615 +			uint16_t p = 0;
 149.616 +			for (std::map<uint16_t,aiNode*>::iterator itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
 149.617 +				if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
 149.618 +					itMapParentNodes->second->mChildren[p++] = itMapChildNodes->second;
 149.619 +				}
 149.620 +			}
 149.621 +		}
 149.622 +	}
 149.623 +
 149.624 +	if (!pScene->mRootNode->mNumChildren)
 149.625 +		throw DeadlyImportError("LWO: Unable to build a valid node graph");
 149.626 +
 149.627 +	// Remove a single root node with no meshes assigned to it ... 
 149.628 +	if (1 == pScene->mRootNode->mNumChildren)	{
 149.629 +		aiNode* pc = pScene->mRootNode->mChildren[0];
 149.630 +		pc->mParent = pScene->mRootNode->mChildren[0] = NULL;
 149.631 +		delete pScene->mRootNode;
 149.632 +		pScene->mRootNode = pc;
 149.633 +	}
 149.634 +
 149.635 +	// convert the whole stuff to RH with CCW winding
 149.636 +	MakeLeftHandedProcess maker;
 149.637 +	maker.Execute(pScene);
 149.638 +
 149.639 +	FlipWindingOrderProcess flipper;
 149.640 +	flipper.Execute(pScene);
 149.641 +}
 149.642 +
 149.643 +// ------------------------------------------------------------------------------------------------
 149.644 +void LWOImporter::ResolveTags()
 149.645 +{
 149.646 +	// --- this function is used for both LWO2 and LWOB
 149.647 +	mMapping->resize(mTags->size(), UINT_MAX);
 149.648 +	for (unsigned int a = 0; a  < mTags->size();++a)	{
 149.649 +
 149.650 +		const std::string& c = (*mTags)[a];
 149.651 +		for (unsigned int i = 0; i < mSurfaces->size();++i)	{
 149.652 +
 149.653 +			const std::string& d = (*mSurfaces)[i].mName;
 149.654 +			if (!ASSIMP_stricmp(c,d))	{
 149.655 +
 149.656 +				(*mMapping)[a] = i;
 149.657 +				break;
 149.658 +			}
 149.659 +		}
 149.660 +	}
 149.661 +}
 149.662 +
 149.663 +// ------------------------------------------------------------------------------------------------
 149.664 +void LWOImporter::ResolveClips()
 149.665 +{
 149.666 +	for( unsigned int i = 0; i < mClips.size();++i)	{
 149.667 +
 149.668 +		Clip& clip = mClips[i];
 149.669 +		if (Clip::REF == clip.type)	{
 149.670 +
 149.671 +			if (clip.clipRef >= mClips.size())	{
 149.672 +				DefaultLogger::get()->error("LWO2: Clip referrer index is out of range");
 149.673 +				clip.clipRef = 0;
 149.674 +			}
 149.675 +
 149.676 +			Clip& dest = mClips[clip.clipRef];
 149.677 +			if (Clip::REF == dest.type) {
 149.678 +				DefaultLogger::get()->error("LWO2: Clip references another clip reference");
 149.679 +				clip.type = Clip::UNSUPPORTED;
 149.680 +			}
 149.681 +
 149.682 +			else	{
 149.683 +				clip.path = dest.path;
 149.684 +				clip.type = dest.type;
 149.685 +			}
 149.686 +		}
 149.687 +	}
 149.688 +}
 149.689 +
 149.690 +// ------------------------------------------------------------------------------------------------
 149.691 +void LWOImporter::AdjustTexturePath(std::string& out)
 149.692 +{
 149.693 +	// --- this function is used for both LWO2 and LWOB
 149.694 +	if (!mIsLWO2 && ::strstr(out.c_str(), "(sequence)"))	{
 149.695 +
 149.696 +		// remove the (sequence) and append 000
 149.697 +		DefaultLogger::get()->info("LWOB: Sequence of animated texture found. It will be ignored");
 149.698 +		out = out.substr(0,out.length()-10) + "000";
 149.699 +	}
 149.700 +
 149.701 +	// format: drive:path/file - we just need to insert a slash after the drive
 149.702 +	std::string::size_type n = out.find_first_of(':');
 149.703 +	if (std::string::npos != n)	{
 149.704 +		out.insert(n+1,"/");
 149.705 +	}
 149.706 +}
 149.707 +
 149.708 +// ------------------------------------------------------------------------------------------------
 149.709 +void LWOImporter::LoadLWOTags(unsigned int size)
 149.710 +{
 149.711 +	// --- this function is used for both LWO2 and LWOB
 149.712 +
 149.713 +	const char* szCur = (const char*)mFileBuffer, *szLast = szCur;
 149.714 +	const char* const szEnd = szLast+size;
 149.715 +	while (szCur < szEnd)
 149.716 +	{
 149.717 +		if (!(*szCur))
 149.718 +		{
 149.719 +			const size_t len = (size_t)(szCur-szLast);
 149.720 +			// FIX: skip empty-sized tags
 149.721 +			if (len)
 149.722 +				mTags->push_back(std::string(szLast,len));
 149.723 +			szCur += (len&0x1 ? 1 : 2);
 149.724 +			szLast = szCur;
 149.725 +		}
 149.726 +		szCur++;
 149.727 +	}
 149.728 +}
 149.729 +
 149.730 +// ------------------------------------------------------------------------------------------------
 149.731 +void LWOImporter::LoadLWOPoints(unsigned int length)
 149.732 +{
 149.733 +	// --- this function is used for both LWO2 and LWOB but for
 149.734 +	// LWO2 we need to allocate 25% more storage - it could be we'll 
 149.735 +	// need to duplicate some points later.
 149.736 +	register unsigned int regularSize = (unsigned int)mCurLayer->mTempPoints.size() + length / 12;
 149.737 +	if (mIsLWO2)
 149.738 +	{
 149.739 +		mCurLayer->mTempPoints.reserve	( regularSize + (regularSize>>2u) );
 149.740 +		mCurLayer->mTempPoints.resize	( regularSize );
 149.741 +
 149.742 +		// initialize all point referrers with the default values
 149.743 +		mCurLayer->mPointReferrers.reserve	( regularSize + (regularSize>>2u) );
 149.744 +		mCurLayer->mPointReferrers.resize	( regularSize, UINT_MAX );
 149.745 +	}
 149.746 +	else mCurLayer->mTempPoints.resize( regularSize );
 149.747 +
 149.748 +	// perform endianess conversions
 149.749 +#ifndef AI_BUILD_BIG_ENDIAN
 149.750 +	for (unsigned int i = 0; i < length>>2;++i)
 149.751 +		ByteSwap::Swap4( mFileBuffer + (i << 2));
 149.752 +#endif
 149.753 +	::memcpy(&mCurLayer->mTempPoints[0],mFileBuffer,length);
 149.754 +}
 149.755 +
 149.756 +// ------------------------------------------------------------------------------------------------
 149.757 +void LWOImporter::LoadLWO2Polygons(unsigned int length)
 149.758 +{
 149.759 +	LE_NCONST uint16_t* const end	= (LE_NCONST uint16_t*)(mFileBuffer+length);
 149.760 +	const uint32_t type = GetU4();
 149.761 +
 149.762 +	// Determine the type of the polygons
 149.763 +	switch (type)
 149.764 +	{
 149.765 +		// read unsupported stuff too (although we wont process it)
 149.766 +	case  AI_LWO_MBAL:
 149.767 +		DefaultLogger::get()->warn("LWO2: Encountered unsupported primitive chunk (METABALL)");
 149.768 +		break;
 149.769 +	case  AI_LWO_CURV:
 149.770 +		DefaultLogger::get()->warn("LWO2: Encountered unsupported primitive chunk (SPLINE)");;
 149.771 +		break;
 149.772 +
 149.773 +		// These are ok with no restrictions
 149.774 +	case  AI_LWO_PTCH:
 149.775 +	case  AI_LWO_FACE:
 149.776 +	case  AI_LWO_BONE:
 149.777 +	case  AI_LWO_SUBD:
 149.778 +		break;
 149.779 +	default:
 149.780 +
 149.781 +		// hm!? wtf is this? ok ...
 149.782 +		DefaultLogger::get()->error("LWO2: Ignoring unknown polygon type.");
 149.783 +		break;
 149.784 +	}
 149.785 +
 149.786 +	// first find out how many faces and vertices we'll finally need
 149.787 +	uint16_t* cursor= (uint16_t*)mFileBuffer;
 149.788 +
 149.789 +	unsigned int iNumFaces = 0,iNumVertices = 0;
 149.790 +	CountVertsAndFacesLWO2(iNumVertices,iNumFaces,cursor,end);
 149.791 +
 149.792 +	// allocate the output array and copy face indices
 149.793 +	if (iNumFaces)	{
 149.794 +		cursor = (uint16_t*)mFileBuffer;
 149.795 +
 149.796 +		mCurLayer->mFaces.resize(iNumFaces,LWO::Face(type));
 149.797 +		FaceList::iterator it = mCurLayer->mFaces.begin();
 149.798 +		CopyFaceIndicesLWO2(it,cursor,end);
 149.799 +	}
 149.800 +}
 149.801 +
 149.802 +// ------------------------------------------------------------------------------------------------
 149.803 +void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& faces,
 149.804 +	uint16_t*& cursor, const uint16_t* const end, unsigned int max)
 149.805 +{
 149.806 +	while (cursor < end && max--)
 149.807 +	{
 149.808 +		AI_LSWAP2P(cursor);
 149.809 +		uint16_t numIndices = *cursor++;
 149.810 +		numIndices &= 0x03FF;
 149.811 +		verts += numIndices;++faces;
 149.812 +
 149.813 +		for(uint16_t i = 0; i < numIndices; i++)
 149.814 +			ReadVSizedIntLWO2((uint8_t*&)cursor);
 149.815 +	}
 149.816 +}
 149.817 +
 149.818 +// ------------------------------------------------------------------------------------------------
 149.819 +void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator& it,
 149.820 +	uint16_t*& cursor, 
 149.821 +	const uint16_t* const end)
 149.822 +{
 149.823 +	while (cursor < end)	{
 149.824 +
 149.825 +		LWO::Face& face = *it++;;
 149.826 +		if((face.mNumIndices = (*cursor++) & 0x03FF)) /* byte swapping has already been done */ {
 149.827 +			face.mIndices = new unsigned int[face.mNumIndices];
 149.828 +			for(unsigned int i = 0; i < face.mNumIndices; i++)
 149.829 +			{
 149.830 +				face.mIndices[i] = ReadVSizedIntLWO2((uint8_t*&)cursor) + mCurLayer->mPointIDXOfs;
 149.831 +				if(face.mIndices[i] > mCurLayer->mTempPoints.size())
 149.832 +				{
 149.833 +					DefaultLogger::get()->warn("LWO2: Failure evaluating face record, index is out of range");
 149.834 +					face.mIndices[i] = (unsigned int)mCurLayer->mTempPoints.size()-1;
 149.835 +				}
 149.836 +			}
 149.837 +		}
 149.838 +		else throw DeadlyImportError("LWO2: Encountered invalid face record with zero indices");
 149.839 +	}
 149.840 +}
 149.841 +
 149.842 +
 149.843 +// ------------------------------------------------------------------------------------------------
 149.844 +void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
 149.845 +{
 149.846 +	LE_NCONST uint8_t* const end = mFileBuffer+length;
 149.847 +
 149.848 +	AI_LWO_VALIDATE_CHUNK_LENGTH(length,PTAG,4);
 149.849 +	uint32_t type = GetU4();
 149.850 +
 149.851 +	if (type != AI_LWO_SURF && type != AI_LWO_SMGP)
 149.852 +		return;
 149.853 +
 149.854 +	while (mFileBuffer < end)	{
 149.855 +
 149.856 +		unsigned int i = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
 149.857 +		unsigned int j = GetU2();
 149.858 +
 149.859 +		if (i >= mCurLayer->mFaces.size())	{
 149.860 +			DefaultLogger::get()->warn("LWO2: face index in PTAG is out of range");
 149.861 +			continue;
 149.862 +		}
 149.863 +
 149.864 +		switch (type)	{
 149.865 +
 149.866 +		case AI_LWO_SURF:
 149.867 +			mCurLayer->mFaces[i].surfaceIndex = j;
 149.868 +			break;
 149.869 +		case AI_LWO_SMGP: /* is that really used? */
 149.870 +			mCurLayer->mFaces[i].smoothGroup = j;
 149.871 +			break;
 149.872 +		};
 149.873 +	}
 149.874 +}
 149.875 +
 149.876 +// ------------------------------------------------------------------------------------------------
 149.877 +template <class T>
 149.878 +VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPoly)
 149.879 +{
 149.880 +	for (typename std::vector< T >::iterator it = list.begin(), end = list.end();it != end; ++it)	{
 149.881 +		if ((*it).name == name)	{
 149.882 +			if (!perPoly)	{
 149.883 +				DefaultLogger::get()->warn("LWO2: Found two VMAP sections with equal names");
 149.884 +			}
 149.885 +			return &(*it);
 149.886 +		}
 149.887 +	}
 149.888 +	list.push_back( T() );
 149.889 +	VMapEntry* p = &list.back();
 149.890 +	p->name = name;
 149.891 +	return p;
 149.892 +}
 149.893 +
 149.894 +// ------------------------------------------------------------------------------------------------
 149.895 +template <class T>
 149.896 +inline void CreateNewEntry(T& chan, unsigned int srcIdx)
 149.897 +{
 149.898 +	if (!chan.name.length())
 149.899 +		return;
 149.900 +
 149.901 +	chan.abAssigned[srcIdx] = true;
 149.902 +	chan.abAssigned.resize(chan.abAssigned.size()+1,false);
 149.903 +
 149.904 +	for (unsigned int a = 0; a < chan.dims;++a)
 149.905 +		chan.rawData.push_back(chan.rawData[srcIdx*chan.dims+a]);
 149.906 +}
 149.907 +
 149.908 +// ------------------------------------------------------------------------------------------------
 149.909 +template <class T>
 149.910 +inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
 149.911 +{
 149.912 +	for (typename std::vector< T >::iterator it =  list.begin(), end = list.end();it != end;++it)	{
 149.913 +		CreateNewEntry( *it, srcIdx );
 149.914 +	}
 149.915 +}
 149.916 +
 149.917 +// ------------------------------------------------------------------------------------------------
 149.918 +inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int numRead, 
 149.919 +	unsigned int idx, float* data)
 149.920 +{
 149.921 +	ai_assert(NULL != data);
 149.922 +	LWO::ReferrerList& refList	= mCurLayer->mPointReferrers;
 149.923 +	unsigned int i;
 149.924 +
 149.925 +	base->abAssigned[idx] = true;
 149.926 +	for (i = 0; i < numRead;++i) {
 149.927 +		base->rawData[idx*base->dims+i]= data[i];
 149.928 +	}
 149.929 +
 149.930 +	if (UINT_MAX != (i = refList[idx])) {
 149.931 +		DoRecursiveVMAPAssignment(base,numRead,i,data);
 149.932 +	}
 149.933 +}
 149.934 +
 149.935 +// ------------------------------------------------------------------------------------------------
 149.936 +inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, unsigned int destIdx)
 149.937 +{
 149.938 +	if(UINT_MAX == refList[srcIdx])	{
 149.939 +		refList[srcIdx] = destIdx;
 149.940 +		return;
 149.941 +	}
 149.942 +	AddToSingleLinkedList(refList,refList[srcIdx],destIdx);
 149.943 +}
 149.944 +
 149.945 +// ------------------------------------------------------------------------------------------------
 149.946 +// Load LWO2 vertex map
 149.947 +void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
 149.948 +{
 149.949 +	LE_NCONST uint8_t* const end = mFileBuffer+length;
 149.950 +
 149.951 +	AI_LWO_VALIDATE_CHUNK_LENGTH(length,VMAP,6);
 149.952 +	unsigned int type = GetU4();
 149.953 +	unsigned int dims = GetU2();
 149.954 +
 149.955 +	VMapEntry* base;
 149.956 +
 149.957 +	// read the name of the vertex map 
 149.958 +	std::string name;
 149.959 +	GetS0(name,length);
 149.960 +
 149.961 +	switch (type)
 149.962 +	{
 149.963 +	case AI_LWO_TXUV:
 149.964 +		if (dims != 2)	{
 149.965 +			DefaultLogger::get()->warn("LWO2: Skipping UV channel \'" 
 149.966 +			+ name + "\' with !2 components"); 
 149.967 +			return;
 149.968 +		}
 149.969 +		base = FindEntry(mCurLayer->mUVChannels,name,perPoly);
 149.970 +		break;
 149.971 +	case AI_LWO_WGHT:
 149.972 +	case AI_LWO_MNVW:
 149.973 +		if (dims != 1)	{
 149.974 +			DefaultLogger::get()->warn("LWO2: Skipping Weight Channel \'" 
 149.975 +			+ name + "\' with !1 components"); 
 149.976 +			return;
 149.977 +		}
 149.978 +		base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels
 149.979 +			: mCurLayer->mSWeightChannels),name,perPoly);
 149.980 +		break;
 149.981 +	case AI_LWO_RGB:
 149.982 +	case AI_LWO_RGBA:
 149.983 +		if (dims != 3 && dims != 4)	{
 149.984 +			DefaultLogger::get()->warn("LWO2: Skipping Color Map \'" 
 149.985 +			+ name + "\' with a dimension > 4 or < 3"); 
 149.986 +			return;
 149.987 +		}
 149.988 +		base = FindEntry(mCurLayer->mVColorChannels,name,perPoly);
 149.989 +		break;
 149.990 +
 149.991 +	case AI_LWO_MODO_NORM:
 149.992 +		/*  This is a non-standard extension chunk used by Luxology's MODO.
 149.993 +		 *  It stores per-vertex normals. This VMAP exists just once, has
 149.994 +		 *  3 dimensions and is btw extremely beautiful.
 149.995 +		 */
 149.996 +		if (name != "vert_normals" || dims != 3 || mCurLayer->mNormals.name.length())
 149.997 +			return;
 149.998 +
 149.999 +		DefaultLogger::get()->info("Processing non-standard extension: MODO VMAP.NORM.vert_normals");
149.1000 +		
149.1001 +		mCurLayer->mNormals.name = name;
149.1002 +		base = & mCurLayer->mNormals;
149.1003 +		break;
149.1004 +
149.1005 +	case AI_LWO_PICK: /* these VMAPs are just silently dropped */
149.1006 +	case AI_LWO_MORF:
149.1007 +	case AI_LWO_SPOT:
149.1008 +		return;
149.1009 +
149.1010 +	default: 
149.1011 +		if (name == "APS.Level") {
149.1012 +			// XXX handle this (seems to be subdivision-related).
149.1013 +		}
149.1014 +		DefaultLogger::get()->warn("LWO2: Skipping unknown VMAP/VMAD channel \'" + name + "\'"); 
149.1015 +		return;
149.1016 +	};
149.1017 +	base->Allocate((unsigned int)mCurLayer->mTempPoints.size());
149.1018 +
149.1019 +	// now read all entries in the map
149.1020 +	type = std::min(dims,base->dims); 
149.1021 +	const unsigned int diff = (dims - type)<<2u;
149.1022 +
149.1023 +	LWO::FaceList& list	= mCurLayer->mFaces;
149.1024 +	LWO::PointList& pointList = mCurLayer->mTempPoints;
149.1025 +	LWO::ReferrerList& refList = mCurLayer->mPointReferrers;
149.1026 +
149.1027 +	float temp[4];
149.1028 +
149.1029 +	const unsigned int numPoints = (unsigned int)pointList.size();
149.1030 +	const unsigned int numFaces  = (unsigned int)list.size();
149.1031 +
149.1032 +	while (mFileBuffer < end)	{
149.1033 +
149.1034 +		unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs;
149.1035 +		if (idx >= numPoints)	{
149.1036 +			DefaultLogger::get()->warn("LWO2: Failure evaluating VMAP/VMAD entry \'" + name + "\', vertex index is out of range");
149.1037 +			mFileBuffer += base->dims<<2u;
149.1038 +			continue;
149.1039 +		}
149.1040 +		if (perPoly)	{
149.1041 +			unsigned int polyIdx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
149.1042 +			if (base->abAssigned[idx])	{
149.1043 +				// we have already a VMAP entry for this vertex - thus
149.1044 +				// we need to duplicate the corresponding polygon.
149.1045 +				if (polyIdx >= numFaces)	{
149.1046 +					DefaultLogger::get()->warn("LWO2: Failure evaluating VMAD entry \'" + name + "\', polygon index is out of range");
149.1047 +					mFileBuffer += base->dims<<2u;
149.1048 +					continue;
149.1049 +				}
149.1050 +
149.1051 +				LWO::Face& src = list[polyIdx];
149.1052 +
149.1053 +				// generate a new unique vertex for the corresponding index - but only
149.1054 +				// if we can find the index in the face
149.1055 +				bool had = false;
149.1056 +				for (unsigned int i = 0; i < src.mNumIndices;++i)	{
149.1057 +
149.1058 +					unsigned int srcIdx = src.mIndices[i], tmp = idx;
149.1059 +					do {
149.1060 +						if (tmp == srcIdx)
149.1061 +							break;
149.1062 +					}
149.1063 +					while ((tmp = refList[tmp]) != UINT_MAX);
149.1064 +					if (tmp == UINT_MAX) {
149.1065 +						continue;
149.1066 +					}
149.1067 +
149.1068 +					had = true;
149.1069 +					refList.resize(refList.size()+1, UINT_MAX);
149.1070 +						
149.1071 +					idx = (unsigned int)pointList.size();
149.1072 +					src.mIndices[i] = (unsigned int)pointList.size();
149.1073 +
149.1074 +					// store the index of the new vertex in the old vertex
149.1075 +					// so we get a single linked list we can traverse in
149.1076 +					// only one direction
149.1077 +					AddToSingleLinkedList(refList,srcIdx,src.mIndices[i]);
149.1078 +					pointList.push_back(pointList[srcIdx]);
149.1079 +
149.1080 +					CreateNewEntry(mCurLayer->mVColorChannels,	srcIdx );
149.1081 +					CreateNewEntry(mCurLayer->mUVChannels,		srcIdx );
149.1082 +					CreateNewEntry(mCurLayer->mWeightChannels,	srcIdx );
149.1083 +					CreateNewEntry(mCurLayer->mSWeightChannels,	srcIdx );
149.1084 +					CreateNewEntry(mCurLayer->mNormals, srcIdx );	
149.1085 +				}
149.1086 +				if (!had) {
149.1087 +					DefaultLogger::get()->warn("LWO2: Failure evaluating VMAD entry \'" + name + "\', vertex index wasn't found in that polygon");
149.1088 +					ai_assert(had);
149.1089 +				}
149.1090 +			}
149.1091 +		}
149.1092 +		for (unsigned int l = 0; l < type;++l)
149.1093 +			temp[l] = GetF4();
149.1094 +
149.1095 +		DoRecursiveVMAPAssignment(base,type,idx, temp);
149.1096 +		mFileBuffer += diff;
149.1097 +	}
149.1098 +}
149.1099 +
149.1100 +// ------------------------------------------------------------------------------------------------
149.1101 +// Load LWO2 clip
149.1102 +void LWOImporter::LoadLWO2Clip(unsigned int length)
149.1103 +{
149.1104 +	AI_LWO_VALIDATE_CHUNK_LENGTH(length,CLIP,10);
149.1105 +
149.1106 +	mClips.push_back(LWO::Clip());
149.1107 +	LWO::Clip& clip = mClips.back();
149.1108 +
149.1109 +	// first - get the index of the clip
149.1110 +	clip.idx = GetU4();
149.1111 +
149.1112 +	IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
149.1113 +	switch (head->type)
149.1114 +	{
149.1115 +	case AI_LWO_STIL:
149.1116 +		AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,STIL,1);
149.1117 +
149.1118 +		// "Normal" texture
149.1119 +		GetS0(clip.path,head->length);
149.1120 +		clip.type = Clip::STILL;
149.1121 +		break;
149.1122 +
149.1123 +	case AI_LWO_ISEQ:
149.1124 +		AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,ISEQ,16);
149.1125 +		// Image sequence. We'll later take the first.
149.1126 +		{
149.1127 +			uint8_t digits = GetU1();  mFileBuffer++;
149.1128 +			int16_t offset = GetU2();  mFileBuffer+=4;
149.1129 +			int16_t start  = GetU2();  mFileBuffer+=4;
149.1130 +
149.1131 +			std::string s;
149.1132 +			std::ostringstream ss;
149.1133 +			GetS0(s,head->length);
149.1134 +
149.1135 +			head->length -= (unsigned int)s.length()+1;
149.1136 +			ss << s;
149.1137 +			ss << std::setw(digits) << offset + start;
149.1138 +			GetS0(s,head->length);
149.1139 +			ss << s;
149.1140 +			clip.path = ss.str();
149.1141 +			clip.type = Clip::SEQ;
149.1142 +		}
149.1143 +		break;
149.1144 +
149.1145 +	case AI_LWO_STCC:
149.1146 +		DefaultLogger::get()->warn("LWO2: Color shifted images are not supported");
149.1147 +		break;
149.1148 +
149.1149 +	case AI_LWO_ANIM:
149.1150 +		DefaultLogger::get()->warn("LWO2: Animated textures are not supported");
149.1151 +		break;
149.1152 +
149.1153 +	case AI_LWO_XREF:
149.1154 +		AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,XREF,4);
149.1155 +
149.1156 +		// Just a cross-reference to another CLIp
149.1157 +		clip.type = Clip::REF;
149.1158 +		clip.clipRef = GetU4();
149.1159 +		break;
149.1160 +
149.1161 +	case AI_LWO_NEGA:
149.1162 +		AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,NEGA,2);
149.1163 +		clip.negate = (0 != GetU2());
149.1164 +		break;
149.1165 +
149.1166 +	default:
149.1167 +		DefaultLogger::get()->warn("LWO2: Encountered unknown CLIP subchunk");
149.1168 +	}
149.1169 +}
149.1170 +
149.1171 +// ------------------------------------------------------------------------------------------------
149.1172 +// Load envelope description
149.1173 +void LWOImporter::LoadLWO2Envelope(unsigned int length)
149.1174 +{
149.1175 +	LE_NCONST uint8_t* const end = mFileBuffer + length;
149.1176 +	AI_LWO_VALIDATE_CHUNK_LENGTH(length,ENVL,4);
149.1177 +
149.1178 +	mEnvelopes.push_back(LWO::Envelope());
149.1179 +	LWO::Envelope& envelope = mEnvelopes.back();
149.1180 +
149.1181 +	// Get the index of the envelope
149.1182 +	envelope.index = ReadVSizedIntLWO2(mFileBuffer);
149.1183 +
149.1184 +	// It looks like there might be an extra U4 right after the index,
149.1185 +	// at least in modo (LXOB) files: we'll ignore it if it's zero,
149.1186 +	// otherwise it represents the start of a subchunk, so we backtrack.
149.1187 +	if (mIsLXOB)
149.1188 +	{
149.1189 +        uint32_t extra = GetU4();
149.1190 +        if (extra)
149.1191 +        {
149.1192 +            mFileBuffer -= 4;
149.1193 +        }
149.1194 +	}
149.1195 +
149.1196 +	// ... and read all subchunks
149.1197 +	while (true)
149.1198 +	{
149.1199 +		if (mFileBuffer + 6 >= end)break;
149.1200 +		LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
149.1201 +
149.1202 +		if (mFileBuffer + head->length > end)
149.1203 +			throw DeadlyImportError("LWO2: Invalid envelope chunk length");
149.1204 +
149.1205 +		uint8_t* const next = mFileBuffer+head->length;
149.1206 +		switch (head->type)
149.1207 +		{
149.1208 +			// Type & representation of the envelope
149.1209 +		case AI_LWO_TYPE:
149.1210 +			AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TYPE,2);
149.1211 +			mFileBuffer++; // skip user format
149.1212 +
149.1213 +			// Determine type of envelope
149.1214 +			envelope.type  = (LWO::EnvelopeType)*mFileBuffer;
149.1215 +			++mFileBuffer;
149.1216 +			break;
149.1217 +
149.1218 +			// precondition
149.1219 +		case AI_LWO_PRE:
149.1220 +			AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,PRE,2);
149.1221 +			envelope.pre = (LWO::PrePostBehaviour)GetU2();
149.1222 +			break;
149.1223 +		
149.1224 +			// postcondition
149.1225 +		case AI_LWO_POST:
149.1226 +			AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,POST,2);
149.1227 +			envelope.post = (LWO::PrePostBehaviour)GetU2();
149.1228 +			break;
149.1229 +
149.1230 +			// keyframe
149.1231 +		case AI_LWO_KEY: 
149.1232 +			{
149.1233 +			AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,KEY,8);
149.1234 +			
149.1235 +			envelope.keys.push_back(LWO::Key());
149.1236 +			LWO::Key& key = envelope.keys.back();
149.1237 +
149.1238 +			key.time = GetF4();
149.1239 +			key.value = GetF4();
149.1240 +			break;
149.1241 +			}
149.1242 +
149.1243 +			// interval interpolation
149.1244 +		case AI_LWO_SPAN: 
149.1245 +			{
149.1246 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPAN,4);
149.1247 +				if (envelope.keys.size()<2)
149.1248 +					DefaultLogger::get()->warn("LWO2: Unexpected SPAN chunk");
149.1249 +				else {
149.1250 +					LWO::Key& key = envelope.keys.back();
149.1251 +					switch (GetU4())
149.1252 +					{
149.1253 +						case AI_LWO_STEP:
149.1254 +							key.inter = LWO::IT_STEP;break;
149.1255 +						case AI_LWO_LINE:
149.1256 +							key.inter = LWO::IT_LINE;break;
149.1257 +						case AI_LWO_TCB:
149.1258 +							key.inter = LWO::IT_TCB;break;
149.1259 +						case AI_LWO_HERM:
149.1260 +							key.inter = LWO::IT_HERM;break;
149.1261 +						case AI_LWO_BEZI:
149.1262 +							key.inter = LWO::IT_BEZI;break;
149.1263 +						case AI_LWO_BEZ2:
149.1264 +							key.inter = LWO::IT_BEZ2;break;
149.1265 +						default:
149.1266 +							DefaultLogger::get()->warn("LWO2: Unknown interval interpolation mode");
149.1267 +					};
149.1268 +
149.1269 +					// todo ... read params
149.1270 +				}
149.1271 +				break;
149.1272 +			}
149.1273 +
149.1274 +		default:
149.1275 +			DefaultLogger::get()->warn("LWO2: Encountered unknown ENVL subchunk");
149.1276 +		}
149.1277 +		// regardless how much we did actually read, go to the next chunk
149.1278 +		mFileBuffer = next;
149.1279 +	}
149.1280 +}
149.1281 +
149.1282 +// ------------------------------------------------------------------------------------------------
149.1283 +// Load file - master function
149.1284 +void LWOImporter::LoadLWO2File()
149.1285 +{
149.1286 +	bool skip = false;
149.1287 +
149.1288 +	LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
149.1289 +	while (true)
149.1290 +	{
149.1291 +		if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
149.1292 +		IFF::ChunkHeader* const head = IFF::LoadChunk(mFileBuffer);
149.1293 +
149.1294 +		if (mFileBuffer + head->length > end)
149.1295 +		{
149.1296 +			throw DeadlyImportError("LWO2: Chunk length points behind the file");
149.1297 +			break;
149.1298 +		}
149.1299 +		uint8_t* const next = mFileBuffer+head->length;
149.1300 +		unsigned int iUnnamed = 0;
149.1301 +
149.1302 +		switch (head->type)
149.1303 +		{
149.1304 +			// new layer
149.1305 +		case AI_LWO_LAYR:
149.1306 +			{
149.1307 +				// add a new layer to the list ....
149.1308 +				mLayers->push_back ( LWO::Layer() );
149.1309 +				LWO::Layer& layer = mLayers->back();
149.1310 +				mCurLayer = &layer;
149.1311 +
149.1312 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LAYR,16);
149.1313 +
149.1314 +				// layer index.
149.1315 +				layer.mIndex = GetU2();
149.1316 +
149.1317 +				// Continue loading this layer or ignore it? Check the layer index property
149.1318 +				if (UINT_MAX != configLayerIndex && (configLayerIndex-1) != layer.mIndex)	{
149.1319 +					skip = true;
149.1320 +				}
149.1321 +				else skip = false;
149.1322 +
149.1323 +				// pivot point
149.1324 +				mFileBuffer += 2; /* unknown */
149.1325 +				mCurLayer->mPivot.x = GetF4();
149.1326 +				mCurLayer->mPivot.y = GetF4();
149.1327 +				mCurLayer->mPivot.z = GetF4();
149.1328 +				GetS0(layer.mName,head->length-16);
149.1329 +
149.1330 +				// if the name is empty, generate a default name
149.1331 +				if (layer.mName.empty())	{
149.1332 +					char buffer[128]; // should be sufficiently large
149.1333 +					::sprintf(buffer,"Layer_%i", iUnnamed++);
149.1334 +					layer.mName = buffer;
149.1335 +				}
149.1336 +
149.1337 +				// load this layer or ignore it? Check the layer name property
149.1338 +				if (configLayerName.length() && configLayerName != layer.mName)	{
149.1339 +					skip = true;
149.1340 +				}
149.1341 +				else hasNamedLayer = true;
149.1342 +
149.1343 +				// optional: parent of this layer
149.1344 +				if (mFileBuffer + 2 <= next)
149.1345 +					layer.mParent = GetU2();
149.1346 +				else layer.mParent = -1;
149.1347 +
149.1348 +				// Set layer skip parameter
149.1349 +				layer.skip = skip;
149.1350 +
149.1351 +				break;
149.1352 +			}
149.1353 +
149.1354 +			// vertex list
149.1355 +		case AI_LWO_PNTS:
149.1356 +			{
149.1357 +				if (skip)
149.1358 +					break;
149.1359 +
149.1360 +				unsigned int old = (unsigned int)mCurLayer->mTempPoints.size();
149.1361 +				LoadLWOPoints(head->length);
149.1362 +				mCurLayer->mPointIDXOfs = old;
149.1363 +				break;
149.1364 +			}
149.1365 +			// vertex tags
149.1366 +		case AI_LWO_VMAD:
149.1367 +			if (mCurLayer->mFaces.empty())
149.1368 +			{
149.1369 +				DefaultLogger::get()->warn("LWO2: Unexpected VMAD chunk");
149.1370 +				break;
149.1371 +			}
149.1372 +			// --- intentionally no break here
149.1373 +		case AI_LWO_VMAP:
149.1374 +			{
149.1375 +				if (skip)
149.1376 +					break;
149.1377 +
149.1378 +				if (mCurLayer->mTempPoints.empty())
149.1379 +					DefaultLogger::get()->warn("LWO2: Unexpected VMAP chunk");
149.1380 +				else LoadLWO2VertexMap(head->length,head->type == AI_LWO_VMAD);
149.1381 +				break;
149.1382 +			}
149.1383 +			// face list
149.1384 +		case AI_LWO_POLS:
149.1385 +			{
149.1386 +				if (skip)
149.1387 +					break;
149.1388 +
149.1389 +				unsigned int old = (unsigned int)mCurLayer->mFaces.size();
149.1390 +				LoadLWO2Polygons(head->length);
149.1391 +				mCurLayer->mFaceIDXOfs = old;
149.1392 +				break;
149.1393 +			}
149.1394 +			// polygon tags 
149.1395 +		case AI_LWO_PTAG:
149.1396 +			{
149.1397 +				if (skip)
149.1398 +					break;
149.1399 +
149.1400 +				if (mCurLayer->mFaces.empty())
149.1401 +					DefaultLogger::get()->warn("LWO2: Unexpected PTAG");
149.1402 +				else LoadLWO2PolygonTags(head->length);
149.1403 +				break;
149.1404 +			}
149.1405 +			// list of tags
149.1406 +		case AI_LWO_TAGS:
149.1407 +			{
149.1408 +				if (!mTags->empty())
149.1409 +					DefaultLogger::get()->warn("LWO2: SRFS chunk encountered twice");
149.1410 +				else LoadLWOTags(head->length);
149.1411 +				break;
149.1412 +			}
149.1413 +
149.1414 +			// surface chunk
149.1415 +		case AI_LWO_SURF:
149.1416 +			{
149.1417 +				LoadLWO2Surface(head->length);
149.1418 +				break;
149.1419 +			}
149.1420 +
149.1421 +			// clip chunk
149.1422 +		case AI_LWO_CLIP:
149.1423 +			{
149.1424 +				LoadLWO2Clip(head->length);
149.1425 +				break;
149.1426 +			}
149.1427 +
149.1428 +			// envelope chunk
149.1429 +		case AI_LWO_ENVL:
149.1430 +			{
149.1431 +				LoadLWO2Envelope(head->length);
149.1432 +				break;
149.1433 +			}
149.1434 +		}
149.1435 +		mFileBuffer = next;
149.1436 +	}
149.1437 +}
149.1438 +
149.1439 +#endif // !! ASSIMP_BUILD_NO_LWO_IMPORTER
   150.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   150.2 +++ b/libs/assimp/LWOLoader.h	Sat Feb 01 19:58:19 2014 +0200
   150.3 @@ -0,0 +1,478 @@
   150.4 +/*
   150.5 +Open Asset Import Library (assimp)
   150.6 +----------------------------------------------------------------------
   150.7 +
   150.8 +Copyright (c) 2006-2012, assimp team
   150.9 +All rights reserved.
  150.10 +
  150.11 +Redistribution and use of this software in source and binary forms, 
  150.12 +with or without modification, are permitted provided that the 
  150.13 +following conditions are met:
  150.14 +
  150.15 +* Redistributions of source code must retain the above
  150.16 +  copyright notice, this list of conditions and the
  150.17 +  following disclaimer.
  150.18 +
  150.19 +* Redistributions in binary form must reproduce the above
  150.20 +  copyright notice, this list of conditions and the
  150.21 +  following disclaimer in the documentation and/or other
  150.22 +  materials provided with the distribution.
  150.23 +
  150.24 +* Neither the name of the assimp team, nor the names of its
  150.25 +  contributors may be used to endorse or promote products
  150.26 +  derived from this software without specific prior
  150.27 +  written permission of the assimp team.
  150.28 +
  150.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  150.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  150.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  150.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  150.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  150.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  150.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  150.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  150.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  150.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  150.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  150.40 +
  150.41 +----------------------------------------------------------------------
  150.42 +*/
  150.43 +
  150.44 +/** @file Declaration of the LWO importer class. */
  150.45 +#ifndef AI_LWOLOADER_H_INCLUDED
  150.46 +#define AI_LWOLOADER_H_INCLUDED
  150.47 +
  150.48 +#include "assimp/types.h"
  150.49 +#include "assimp/DefaultLogger.hpp"
  150.50 +
  150.51 +#include "LWOFileData.h"
  150.52 +#include "BaseImporter.h"
  150.53 +
  150.54 +struct aiTexture;
  150.55 +struct aiNode;
  150.56 +
  150.57 +namespace Assimp	{
  150.58 +using namespace LWO;
  150.59 +
  150.60 +// ---------------------------------------------------------------------------
  150.61 +/** Class to load LWO files.
  150.62 + *
  150.63 + *  @note  Methods named "xxxLWO2[xxx]" are used with the newer LWO2 format.
  150.64 + *         Methods named "xxxLWOB[xxx]" are used with the older LWOB format.
  150.65 + *         Methods named "xxxLWO[xxx]" are used with both formats.
  150.66 + *         Methods named "xxx" are used to preprocess the loaded data -
  150.67 + *         they aren't specific to one format version
  150.68 +*/
  150.69 +// ---------------------------------------------------------------------------
  150.70 +class LWOImporter : public BaseImporter
  150.71 +{
  150.72 +public:
  150.73 +	LWOImporter();
  150.74 +	~LWOImporter();
  150.75 +
  150.76 +
  150.77 +public:
  150.78 +
  150.79 +	// -------------------------------------------------------------------
  150.80 +	/** Returns whether the class can handle the format of the given file. 
  150.81 +	 * See BaseImporter::CanRead() for details.	
  150.82 +	 */
  150.83 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  150.84 +		bool checkSig) const;
  150.85 +
  150.86 +
  150.87 +	// -------------------------------------------------------------------
  150.88 +	/** Called prior to ReadFile().
  150.89 +	* The function is a request to the importer to update its configuration
  150.90 +	* basing on the Importer's configuration property list.
  150.91 +	*/
  150.92 +	void SetupProperties(const Importer* pImp);
  150.93 +
  150.94 +protected:
  150.95 +
  150.96 +	// -------------------------------------------------------------------
  150.97 +	// Get list of supported extensions
  150.98 +	const aiImporterDesc* GetInfo () const;
  150.99 +
 150.100 +	// -------------------------------------------------------------------
 150.101 +	/** Imports the given file into the given scene structure. 
 150.102 +	* See BaseImporter::InternReadFile() for details
 150.103 +	*/
 150.104 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
 150.105 +		IOSystem* pIOHandler);
 150.106 +
 150.107 +private:
 150.108 +
 150.109 +	// -------------------------------------------------------------------
 150.110 +	/** Loads a LWO file in the older LWOB format (LW < 6)
 150.111 +	 */
 150.112 +	void LoadLWOBFile();
 150.113 +
 150.114 +	// -------------------------------------------------------------------
 150.115 +	/** Loads a LWO file in the newer LWO2 format (LW >= 6)
 150.116 +	 */
 150.117 +	void LoadLWO2File();
 150.118 +
 150.119 +
 150.120 +	// -------------------------------------------------------------------
 150.121 +	/** Parsing functions used for all file format versions
 150.122 +	*/
 150.123 +	inline void GetS0(std::string& out,unsigned int max);
 150.124 +	inline float GetF4();
 150.125 +	inline uint32_t GetU4();
 150.126 +	inline uint16_t GetU2();
 150.127 +	inline uint8_t  GetU1();
 150.128 +
 150.129 +
 150.130 +	// -------------------------------------------------------------------
 150.131 +	/** Loads a surface chunk from an LWOB file
 150.132 +	 *  @param size Maximum size to be read, in bytes.  
 150.133 +	 */
 150.134 +	void LoadLWOBSurface(unsigned int size);
 150.135 +
 150.136 +	// -------------------------------------------------------------------
 150.137 +	/** Loads a surface chunk from an LWO2 file
 150.138 +	 *  @param size Maximum size to be read, in bytes.  
 150.139 +	 */
 150.140 +	void LoadLWO2Surface(unsigned int size);
 150.141 +
 150.142 +	// -------------------------------------------------------------------
 150.143 +	/** Loads a texture block from a LWO2 file.
 150.144 +	 *  @param size Maximum size to be read, in bytes.  
 150.145 +	 *  @param head Header of the SUF.BLOK header
 150.146 +	 */
 150.147 +	void LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head,
 150.148 +		unsigned int size );
 150.149 +
 150.150 +	// -------------------------------------------------------------------
 150.151 +	/** Loads a shader block from a LWO2 file.
 150.152 +	 *  @param size Maximum size to be read, in bytes.  
 150.153 +	 *  @param head Header of the SUF.BLOK header
 150.154 +	 */
 150.155 +	void LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* head,
 150.156 +		unsigned int size );
 150.157 +
 150.158 +	// -------------------------------------------------------------------
 150.159 +	/** Loads an image map from a LWO2 file
 150.160 +	 *  @param size Maximum size to be read, in bytes.  
 150.161 +	 *  @param tex Texture object to be filled
 150.162 +	 */
 150.163 +	void LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex );
 150.164 +	void LoadLWO2Gradient(unsigned int size, LWO::Texture& tex );
 150.165 +	void LoadLWO2Procedural(unsigned int size, LWO::Texture& tex );
 150.166 +
 150.167 +	// loads the header - used by thethree functions above
 150.168 +	void LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex );
 150.169 +
 150.170 +	// -------------------------------------------------------------------
 150.171 +	/** Loads the LWO tag list from the file
 150.172 +	 *  @param size Maximum size to be read, in bytes.  
 150.173 +	 */
 150.174 +	void LoadLWOTags(unsigned int size);
 150.175 +
 150.176 +	// -------------------------------------------------------------------
 150.177 +	/** Load polygons from a POLS chunk
 150.178 +	 *  @param length Size of the chunk
 150.179 +	*/
 150.180 +	void LoadLWO2Polygons(unsigned int length);
 150.181 +	void LoadLWOBPolygons(unsigned int length);
 150.182 +
 150.183 +	// -------------------------------------------------------------------
 150.184 +	/** Load polygon tags from a PTAG chunk
 150.185 +	 *  @param length Size of the chunk
 150.186 +	*/
 150.187 +	void LoadLWO2PolygonTags(unsigned int length);
 150.188 +
 150.189 +	// -------------------------------------------------------------------
 150.190 +	/** Load a vertex map from a VMAP/VMAD chunk
 150.191 +	 *  @param length Size of the chunk
 150.192 +	 *  @param perPoly Operate on per-polygon base?
 150.193 +	*/
 150.194 +	void LoadLWO2VertexMap(unsigned int length, bool perPoly);
 150.195 +
 150.196 +	// -------------------------------------------------------------------
 150.197 +	/** Load polygons from a PNTS chunk
 150.198 +	 *  @param length Size of the chunk
 150.199 +	*/
 150.200 +	void LoadLWOPoints(unsigned int length);
 150.201 +
 150.202 +	// -------------------------------------------------------------------
 150.203 +	/** Load a clip from a CLIP chunk
 150.204 +	 *  @param length Size of the chunk
 150.205 +	*/
 150.206 +	void LoadLWO2Clip(unsigned int length);
 150.207 +
 150.208 +	// -------------------------------------------------------------------
 150.209 +	/** Load an envelope from an EVL chunk
 150.210 +	 *  @param length Size of the chunk
 150.211 +	*/
 150.212 +	void LoadLWO2Envelope(unsigned int length);
 150.213 +
 150.214 +	// -------------------------------------------------------------------
 150.215 +	/** Count vertices and faces in a LWOB/LWO2 file
 150.216 +	*/
 150.217 +	void CountVertsAndFacesLWO2(unsigned int& verts, 
 150.218 +		unsigned int& faces,
 150.219 +		uint16_t*& cursor, 
 150.220 +		const uint16_t* const end,
 150.221 +		unsigned int max = UINT_MAX);
 150.222 +
 150.223 +	void CountVertsAndFacesLWOB(unsigned int& verts, 
 150.224 +		unsigned int& faces,
 150.225 +		LE_NCONST uint16_t*& cursor, 
 150.226 +		const uint16_t* const end,
 150.227 +		unsigned int max = UINT_MAX);
 150.228 +
 150.229 +	// -------------------------------------------------------------------
 150.230 +	/** Read vertices and faces in a LWOB/LWO2 file
 150.231 +	*/
 150.232 +	void CopyFaceIndicesLWO2(LWO::FaceList::iterator& it,
 150.233 +		uint16_t*& cursor, 
 150.234 +		const uint16_t* const end);
 150.235 +
 150.236 +	// -------------------------------------------------------------------
 150.237 +	void CopyFaceIndicesLWOB(LWO::FaceList::iterator& it,
 150.238 +		LE_NCONST uint16_t*& cursor, 
 150.239 +		const uint16_t* const end, 
 150.240 +		unsigned int max = UINT_MAX);
 150.241 +
 150.242 +	// -------------------------------------------------------------------
 150.243 +	/** Resolve the tag and surface lists that have been loaded.
 150.244 +	*   Generates the mMapping table.
 150.245 +	*/
 150.246 +	void ResolveTags();
 150.247 +
 150.248 +	// -------------------------------------------------------------------
 150.249 +	/** Resolve the clip list that has been loaded.
 150.250 +	*   Replaces clip references with real clips.
 150.251 +	*/
 150.252 +	void ResolveClips();
 150.253 +
 150.254 +	// -------------------------------------------------------------------
 150.255 +	/** Add a texture list to an output material description.
 150.256 +	 *
 150.257 +	 *  @param pcMat Output material
 150.258 +	 *  @param in Input texture list
 150.259 +	 *  @param type Type identifier of the texture list
 150.260 +	*/
 150.261 +	bool HandleTextures(aiMaterial* pcMat, const TextureList& in,
 150.262 +		aiTextureType type);
 150.263 +
 150.264 +	// -------------------------------------------------------------------
 150.265 +	/** Adjust a texture path
 150.266 +	*/
 150.267 +	void AdjustTexturePath(std::string& out);
 150.268 +
 150.269 +	// -------------------------------------------------------------------
 150.270 +	/** Convert a LWO surface description to an ASSIMP material
 150.271 +	*/
 150.272 +	void ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat);
 150.273 +
 150.274 +	
 150.275 +	// -------------------------------------------------------------------
 150.276 +	/** Get a list of all UV/VC channels required by a specific surface.
 150.277 +	 *
 150.278 +	 *  @param surf Working surface
 150.279 +	 *  @param layer Working layer
 150.280 +	 *  @param out Output list. The members are indices into the 
 150.281 +	 *    UV/VC channel lists of the layer
 150.282 +	*/
 150.283 +	void FindUVChannels(/*const*/ LWO::Surface& surf, 
 150.284 +		LWO::SortedRep& sorted,
 150.285 +		/*const*/ LWO::Layer& layer,
 150.286 +		unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS]);
 150.287 +
 150.288 +	// -------------------------------------------------------------------
 150.289 +	char FindUVChannels(LWO::TextureList& list,
 150.290 +		LWO::Layer& layer,LWO::UVChannel& uv, unsigned int next);
 150.291 +
 150.292 +	// -------------------------------------------------------------------
 150.293 +	void FindVCChannels(const LWO::Surface& surf, 
 150.294 +		LWO::SortedRep& sorted,  
 150.295 +		const LWO::Layer& layer,
 150.296 +		unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS]);
 150.297 +
 150.298 +	// -------------------------------------------------------------------
 150.299 +	/** Generate the final node graph
 150.300 +	 *  Unused nodes are deleted.
 150.301 +	 *  @param apcNodes Flat list of nodes
 150.302 +	*/
 150.303 +	void GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes);
 150.304 +
 150.305 +	// -------------------------------------------------------------------
 150.306 +	/** Add children to a node
 150.307 +	 *  @param node Node to become a father
 150.308 +	 *  @param parent Index of the node
 150.309 +	 *  @param apcNodes Flat list of nodes - used nodes are set to NULL.
 150.310 +	*/
 150.311 +	void AddChildren(aiNode* node, uint16_t parent, 
 150.312 +		std::vector<aiNode*>& apcNodes);
 150.313 +
 150.314 +	// -------------------------------------------------------------------
 150.315 +	/** Read a variable sized integer
 150.316 +	 *  @param inout Input and output buffer
 150.317 +	*/
 150.318 +	int ReadVSizedIntLWO2(uint8_t*& inout);
 150.319 +
 150.320 +	// -------------------------------------------------------------------
 150.321 +	/** Assign a value from a VMAP to a vertex and all vertices 
 150.322 +	 *  attached to it.
 150.323 +	 *  @param base VMAP destination data
 150.324 +	 *  @param numRead Number of float's to be read
 150.325 +	 *  @param idx Absolute index of the first vertex
 150.326 +	 *  @param data Value of the VMAP to be assigned - read numRead
 150.327 +	 *    floats from this array.
 150.328 +	*/
 150.329 +	void DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int numRead, 
 150.330 +		unsigned int idx, float* data);
 150.331 +
 150.332 +	// -------------------------------------------------------------------
 150.333 +	/** Compute normal vectors for a mesh
 150.334 +	 *  @param mesh Input mesh
 150.335 +	 *  @param smoothingGroups Smoothing-groups-per-face array
 150.336 +	 *  @param surface Surface for the mesh 
 150.337 +	*/
 150.338 +	void ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& smoothingGroups,
 150.339 +		const LWO::Surface& surface);
 150.340 +
 150.341 +
 150.342 +	// -------------------------------------------------------------------
 150.343 +	/** Setup a new texture after the corresponding chunk was 
 150.344 +	 *  encountered in the file.
 150.345 +	 *  @param list Texture list
 150.346 +	 *  @param size Maximum number of bytes to be read
 150.347 +	 *  @return Pointer to new texture
 150.348 +	*/
 150.349 +	LWO::Texture* SetupNewTextureLWOB(LWO::TextureList& list,
 150.350 +		unsigned int size);
 150.351 +
 150.352 +protected:
 150.353 +
 150.354 +	/** true if the file is a LWO2 file*/
 150.355 +	bool mIsLWO2;
 150.356 +
 150.357 +	/** true if the file is a LXOB file*/
 150.358 +	bool mIsLXOB;
 150.359 +
 150.360 +	/** Temporary list of layers from the file */
 150.361 +	LayerList* mLayers;
 150.362 +
 150.363 +	/** Pointer to the current layer */
 150.364 +	LWO::Layer* mCurLayer;
 150.365 +
 150.366 +	/** Temporary tag list from the file */
 150.367 +	TagList* mTags;
 150.368 +
 150.369 +	/** Mapping table to convert from tag to surface indices.
 150.370 +	    UINT_MAX indicates that a no corresponding surface is available */
 150.371 +	TagMappingTable* mMapping;
 150.372 +
 150.373 +	/** Temporary surface list from the file */
 150.374 +	SurfaceList* mSurfaces;
 150.375 +
 150.376 +	/** Temporary clip list from the file */
 150.377 +	ClipList mClips;
 150.378 +
 150.379 +	/** Temporary envelope list from the file */
 150.380 +	EnvelopeList mEnvelopes;
 150.381 +
 150.382 +	/** file buffer */
 150.383 +	uint8_t* mFileBuffer;
 150.384 +
 150.385 +	/** Size of the file, in bytes */
 150.386 +	unsigned int fileSize;
 150.387 +
 150.388 +	/** Output scene */
 150.389 +	aiScene* pScene;
 150.390 +
 150.391 +	/** Configuration option: speed flag set? */
 150.392 +	bool configSpeedFlag;
 150.393 +
 150.394 +	/** Configuration option: index of layer to be loaded */
 150.395 +	unsigned int configLayerIndex;
 150.396 +
 150.397 +	/** Configuration option: name of layer to be loaded */
 150.398 +	std::string  configLayerName;
 150.399 +
 150.400 +	/** True if we have a named layer */
 150.401 +	bool hasNamedLayer;
 150.402 +};
 150.403 +
 150.404 +
 150.405 +// ------------------------------------------------------------------------------------------------
 150.406 +inline float LWOImporter::GetF4()
 150.407 +{
 150.408 +	float f = *((float*)mFileBuffer);mFileBuffer += 4;
 150.409 +	AI_LSWAP4(f);
 150.410 +	return f;
 150.411 +}
 150.412 +
 150.413 +// ------------------------------------------------------------------------------------------------
 150.414 +inline uint32_t LWOImporter::GetU4()
 150.415 +{
 150.416 +	uint32_t f = *((uint32_t*)mFileBuffer);mFileBuffer += 4;
 150.417 +	AI_LSWAP4(f);
 150.418 +	return f;
 150.419 +}
 150.420 +
 150.421 +// ------------------------------------------------------------------------------------------------
 150.422 +inline uint16_t LWOImporter::GetU2()
 150.423 +{
 150.424 +	uint16_t f = *((uint16_t*)mFileBuffer);mFileBuffer += 2;
 150.425 +	AI_LSWAP2(f);
 150.426 +	return f;
 150.427 +}
 150.428 +
 150.429 +// ------------------------------------------------------------------------------------------------
 150.430 +inline uint8_t LWOImporter::GetU1()
 150.431 +{
 150.432 +	return *mFileBuffer++;
 150.433 +}
 150.434 +
 150.435 +// ------------------------------------------------------------------------------------------------
 150.436 +inline int LWOImporter::ReadVSizedIntLWO2(uint8_t*& inout)
 150.437 +{
 150.438 +	int i;
 150.439 +	int c = *inout;inout++;
 150.440 +	if(c != 0xFF)
 150.441 +	{
 150.442 +		i = c << 8;
 150.443 +		c = *inout;inout++;
 150.444 +		i |= c;
 150.445 +	}
 150.446 +	else
 150.447 +	{
 150.448 +		c = *inout;inout++;
 150.449 +		i = c << 16;
 150.450 +		c = *inout;inout++;
 150.451 +		i |= c << 8;
 150.452 +		c = *inout;inout++;
 150.453 +		i |= c;
 150.454 +	}
 150.455 +	return i;
 150.456 +}
 150.457 +
 150.458 +// ------------------------------------------------------------------------------------------------
 150.459 +inline void LWOImporter::GetS0(std::string& out,unsigned int max)
 150.460 +{
 150.461 +	unsigned int iCursor = 0;
 150.462 +	const char*sz = (const char*)mFileBuffer;
 150.463 +	while (*mFileBuffer)
 150.464 +	{
 150.465 +		if (++iCursor > max)
 150.466 +		{
 150.467 +			DefaultLogger::get()->warn("LWO: Invalid file, string is is too long");
 150.468 +			break;
 150.469 +		}
 150.470 +		++mFileBuffer;
 150.471 +	}
 150.472 +	size_t len = (size_t) ((const char*)mFileBuffer-sz);
 150.473 +	out = std::string(sz,len);
 150.474 +	mFileBuffer += (len&0x1 ? 1 : 2);
 150.475 +}
 150.476 +
 150.477 +
 150.478 +
 150.479 +} // end of namespace Assimp
 150.480 +
 150.481 +#endif // AI_LWOIMPORTER_H_INCLUDED
   151.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   151.2 +++ b/libs/assimp/LWOMaterial.cpp	Sat Feb 01 19:58:19 2014 +0200
   151.3 @@ -0,0 +1,896 @@
   151.4 +/*
   151.5 +---------------------------------------------------------------------------
   151.6 +Open Asset Import Library (assimp)
   151.7 +---------------------------------------------------------------------------
   151.8 +
   151.9 +Copyright (c) 2006-2012, assimp team
  151.10 +
  151.11 +All rights reserved.
  151.12 +
  151.13 +Redistribution and use of this software in source and binary forms, 
  151.14 +with or without modification, are permitted provided that the following 
  151.15 +conditions are met:
  151.16 +
  151.17 +* Redistributions of source code must retain the above
  151.18 +  copyright notice, this list of conditions and the
  151.19 +  following disclaimer.
  151.20 +
  151.21 +* Redistributions in binary form must reproduce the above
  151.22 +  copyright notice, this list of conditions and the
  151.23 +  following disclaimer in the documentation and/or other
  151.24 +  materials provided with the distribution.
  151.25 +
  151.26 +* Neither the name of the assimp team, nor the names of its
  151.27 +  contributors may be used to endorse or promote products
  151.28 +  derived from this software without specific prior
  151.29 +  written permission of the assimp team.
  151.30 +
  151.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  151.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  151.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  151.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  151.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  151.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  151.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  151.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  151.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  151.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  151.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  151.42 +---------------------------------------------------------------------------
  151.43 +*/
  151.44 +
  151.45 +/** @file Implementation of the material oart of the LWO importer class */
  151.46 +
  151.47 +
  151.48 +#include "AssimpPCH.h"
  151.49 +#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
  151.50 +
  151.51 +// internal headers
  151.52 +#include "LWOLoader.h"
  151.53 +#include "ByteSwap.h"
  151.54 +
  151.55 +using namespace Assimp;
  151.56 +
  151.57 +// ------------------------------------------------------------------------------------------------
  151.58 +template <class T>
  151.59 +T lerp(const T& one, const T& two, float val)
  151.60 +{
  151.61 +	return one + (two-one)*val;
  151.62 +}
  151.63 +
  151.64 +// ------------------------------------------------------------------------------------------------
  151.65 +// Convert a lightwave mapping mode to our's
  151.66 +inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
  151.67 +{
  151.68 +	switch (in)
  151.69 +	{	
  151.70 +		case LWO::Texture::REPEAT:
  151.71 +			return aiTextureMapMode_Wrap;
  151.72 +
  151.73 +		case LWO::Texture::MIRROR:
  151.74 +			return aiTextureMapMode_Mirror;
  151.75 +
  151.76 +		case LWO::Texture::RESET:
  151.77 +			DefaultLogger::get()->warn("LWO2: Unsupported texture map mode: RESET");
  151.78 +
  151.79 +			// fall though here
  151.80 +		case LWO::Texture::EDGE:
  151.81 +			return aiTextureMapMode_Clamp;
  151.82 +	}
  151.83 +	return (aiTextureMapMode)0;
  151.84 +}
  151.85 +
  151.86 +// ------------------------------------------------------------------------------------------------
  151.87 +bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTextureType type)
  151.88 +{
  151.89 +	ai_assert(NULL != pcMat);
  151.90 +
  151.91 +	unsigned int cur = 0, temp = 0;
  151.92 +	aiString s;
  151.93 +	bool ret = false;
  151.94 +
  151.95 +	for (TextureList::const_iterator it = in.begin(), end = in.end();it != end;++it)	{
  151.96 +		if (!(*it).enabled || !(*it).bCanUse)
  151.97 +			continue;
  151.98 +		ret = true;
  151.99 +
 151.100 +		// Convert lightwave's mapping modes to ours. We let them
 151.101 +		// as they are, the GenUVcoords step will compute UV 
 151.102 +		// channels if they're not there.
 151.103 +
 151.104 +		aiTextureMapping mapping;
 151.105 +		switch ((*it).mapMode)
 151.106 +		{
 151.107 +			case LWO::Texture::Planar:
 151.108 +				mapping = aiTextureMapping_PLANE;
 151.109 +				break;
 151.110 +			case LWO::Texture::Cylindrical:
 151.111 +				mapping = aiTextureMapping_CYLINDER;
 151.112 +				break;
 151.113 +			case LWO::Texture::Spherical:
 151.114 +				mapping = aiTextureMapping_SPHERE;
 151.115 +				break;
 151.116 +			case LWO::Texture::Cubic:
 151.117 +				mapping = aiTextureMapping_BOX;
 151.118 +				break;
 151.119 +			case LWO::Texture::FrontProjection:
 151.120 +				DefaultLogger::get()->error("LWO2: Unsupported texture mapping: FrontProjection");
 151.121 +				mapping = aiTextureMapping_OTHER;
 151.122 +				break;
 151.123 +			case LWO::Texture::UV:
 151.124 +				{
 151.125 +					if( UINT_MAX == (*it).mRealUVIndex )	{
 151.126 +						// We have no UV index for this texture, so we can't display it
 151.127 +						continue;
 151.128 +					}
 151.129 +
 151.130 +					// add the UV source index
 151.131 +					temp = (*it).mRealUVIndex;
 151.132 +					pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_UVWSRC(type,cur));
 151.133 +
 151.134 +					mapping = aiTextureMapping_UV;
 151.135 +				}
 151.136 +				break;
 151.137 +			default:
 151.138 +				ai_assert(false);
 151.139 +		};
 151.140 +
 151.141 +		if (mapping != aiTextureMapping_UV)	{
 151.142 +			// Setup the main axis 
 151.143 +			aiVector3D v;
 151.144 +			switch ((*it).majorAxis)	{
 151.145 +				case Texture::AXIS_X:
 151.146 +					v = aiVector3D(1.f,0.f,0.f);
 151.147 +					break;
 151.148 +				case Texture::AXIS_Y:
 151.149 +					v = aiVector3D(0.f,1.f,0.f);
 151.150 +					break;
 151.151 +				default: // case Texture::AXIS_Z:
 151.152 +					v = aiVector3D(0.f,0.f,1.f);
 151.153 +					break;
 151.154 +			}
 151.155 +
 151.156 +			pcMat->AddProperty(&v,1,AI_MATKEY_TEXMAP_AXIS(type,cur));
 151.157 +
 151.158 +			// Setup UV scalings for cylindric and spherical projections
 151.159 +			if (mapping == aiTextureMapping_CYLINDER || mapping == aiTextureMapping_SPHERE)	{
 151.160 +				aiUVTransform trafo;
 151.161 +				trafo.mScaling.x = (*it).wrapAmountW;
 151.162 +				trafo.mScaling.y = (*it).wrapAmountH;
 151.163 +
 151.164 +				BOOST_STATIC_ASSERT(sizeof(aiUVTransform)/sizeof(float) == 5);
 151.165 +				pcMat->AddProperty(&trafo,1,AI_MATKEY_UVTRANSFORM(type,cur));
 151.166 +			}
 151.167 +			DefaultLogger::get()->debug("LWO2: Setting up non-UV mapping");
 151.168 +		}
 151.169 +
 151.170 +		// The older LWOB format does not use indirect references to clips.
 151.171 +		// The file name of a texture is directly specified in the tex chunk.
 151.172 +		if (mIsLWO2)	{
 151.173 +			// find the corresponding clip
 151.174 +			ClipList::iterator clip = mClips.begin();
 151.175 +			temp = (*it).mClipIdx;
 151.176 +			for (ClipList::iterator end = mClips.end(); clip != end; ++clip)	{
 151.177 +				if ((*clip).idx == temp)
 151.178 +					break;
 151.179 +				
 151.180 +			}
 151.181 +			if (mClips.end() == clip)	{
 151.182 +				DefaultLogger::get()->error("LWO2: Clip index is out of bounds");
 151.183 +				temp = 0;
 151.184 +
 151.185 +				// fixme: appearently some LWO files shipping with Doom3 don't
 151.186 +				// have clips at all ... check whether that's true or whether
 151.187 +				// it's a bug in the loader.
 151.188 +
 151.189 +				s.Set("$texture.png");
 151.190 +
 151.191 +				//continue;
 151.192 +			}
 151.193 +			else {
 151.194 +				if (Clip::UNSUPPORTED == (*clip).type)	{
 151.195 +					DefaultLogger::get()->error("LWO2: Clip type is not supported");
 151.196 +					continue;
 151.197 +				}
 151.198 +				AdjustTexturePath((*clip).path);
 151.199 +				s.Set((*clip).path);
 151.200 +
 151.201 +				// Additional image settings
 151.202 +				int flags = 0;
 151.203 +				if ((*clip).negate) {
 151.204 +					flags |= aiTextureFlags_Invert;
 151.205 +				}
 151.206 +				pcMat->AddProperty(&flags,1,AI_MATKEY_TEXFLAGS(type,cur));
 151.207 +			}
 151.208 +		}
 151.209 +		else 
 151.210 +		{
 151.211 +			std::string ss = (*it).mFileName;
 151.212 +			if (!ss.length()) {
 151.213 +				DefaultLogger::get()->error("LWOB: Empty file name");
 151.214 +				continue;
 151.215 +			}
 151.216 +			AdjustTexturePath(ss);
 151.217 +			s.Set(ss);
 151.218 +		}
 151.219 +		pcMat->AddProperty(&s,AI_MATKEY_TEXTURE(type,cur));
 151.220 +
 151.221 +		// add the blend factor
 151.222 +		pcMat->AddProperty<float>(&(*it).mStrength,1,AI_MATKEY_TEXBLEND(type,cur));
 151.223 +
 151.224 +		// add the blend operation
 151.225 +		switch ((*it).blendType)
 151.226 +		{
 151.227 +			case LWO::Texture::Normal:
 151.228 +			case LWO::Texture::Multiply:
 151.229 +				temp = (unsigned int)aiTextureOp_Multiply;
 151.230 +				break;
 151.231 +
 151.232 +			case LWO::Texture::Subtractive:
 151.233 +			case LWO::Texture::Difference:
 151.234 +				temp = (unsigned int)aiTextureOp_Subtract;
 151.235 +				break;
 151.236 +
 151.237 +			case LWO::Texture::Divide:
 151.238 +				temp = (unsigned int)aiTextureOp_Divide;
 151.239 +				break;
 151.240 +
 151.241 +			case LWO::Texture::Additive:
 151.242 +				temp = (unsigned int)aiTextureOp_Add;
 151.243 +				break;
 151.244 +
 151.245 +			default:
 151.246 +				temp = (unsigned int)aiTextureOp_Multiply;
 151.247 +				DefaultLogger::get()->warn("LWO2: Unsupported texture blend mode: alpha or displacement");
 151.248 +
 151.249 +		}
 151.250 +		// Setup texture operation
 151.251 +		pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_TEXOP(type,cur));
 151.252 +
 151.253 +		// setup the mapping mode
 151.254 +		pcMat->AddProperty<int>((int*)&mapping,1,AI_MATKEY_MAPPING(type,cur));
 151.255 +
 151.256 +		// add the u-wrapping
 151.257 +		temp = (unsigned int)GetMapMode((*it).wrapModeWidth);
 151.258 +		pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_U(type,cur));
 151.259 +
 151.260 +		// add the v-wrapping
 151.261 +		temp = (unsigned int)GetMapMode((*it).wrapModeHeight);
 151.262 +		pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_V(type,cur));
 151.263 +
 151.264 +		++cur;
 151.265 +	}
 151.266 +	return ret;
 151.267 +}
 151.268 +
 151.269 +// ------------------------------------------------------------------------------------------------
 151.270 +void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
 151.271 +{
 151.272 +	// copy the name of the surface
 151.273 +	aiString st;
 151.274 +	st.Set(surf.mName);
 151.275 +	pcMat->AddProperty(&st,AI_MATKEY_NAME);
 151.276 +
 151.277 +	const int i = surf.bDoubleSided ? 1 : 0;
 151.278 +	pcMat->AddProperty(&i,1,AI_MATKEY_TWOSIDED);
 151.279 +
 151.280 +	// add the refraction index and the bump intensity
 151.281 +	pcMat->AddProperty(&surf.mIOR,1,AI_MATKEY_REFRACTI);
 151.282 +	pcMat->AddProperty(&surf.mBumpIntensity,1,AI_MATKEY_BUMPSCALING);
 151.283 +	
 151.284 +	aiShadingMode m;
 151.285 +	if (surf.mSpecularValue && surf.mGlossiness)
 151.286 +	{
 151.287 +		float fGloss;
 151.288 +		if (mIsLWO2)	{
 151.289 +			fGloss = pow( surf.mGlossiness*10.0f+2.0f, 2.0f);
 151.290 +		}
 151.291 +		else
 151.292 +		{
 151.293 +			if (16.0f >= surf.mGlossiness)
 151.294 +				fGloss = 6.0f;
 151.295 +			else if (64.0f >= surf.mGlossiness)
 151.296 +				fGloss = 20.0f;
 151.297 +			else if (256.0f >= surf.mGlossiness)
 151.298 +				fGloss = 50.0f;
 151.299 +			else fGloss = 80.0f;
 151.300 +		}
 151.301 +
 151.302 +		pcMat->AddProperty(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH);
 151.303 +		pcMat->AddProperty(&fGloss,1,AI_MATKEY_SHININESS);
 151.304 +		m = aiShadingMode_Phong;
 151.305 +	}
 151.306 +	else m = aiShadingMode_Gouraud;
 151.307 +
 151.308 +	// specular color
 151.309 +	aiColor3D clr = lerp( aiColor3D(1.f,1.f,1.f), surf.mColor, surf.mColorHighlights );
 151.310 +	pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_SPECULAR);
 151.311 +	pcMat->AddProperty(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH);
 151.312 +
 151.313 +	// emissive color
 151.314 +	// luminosity is not really the same but it affects the surface in a similar way. Some scaling looks good.
 151.315 +	clr.g = clr.b = clr.r = surf.mLuminosity*0.8f;
 151.316 +	pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
 151.317 +
 151.318 +	// opacity ... either additive or default-blended, please
 151.319 +	if (0.f != surf.mAdditiveTransparency)	{
 151.320 +
 151.321 +		const int add = aiBlendMode_Additive;
 151.322 +		pcMat->AddProperty(&surf.mAdditiveTransparency,1,AI_MATKEY_OPACITY);
 151.323 +		pcMat->AddProperty(&add,1,AI_MATKEY_BLEND_FUNC);
 151.324 +	}
 151.325 +
 151.326 +	else if (10e10f != surf.mTransparency)	{
 151.327 +		const int def = aiBlendMode_Default;
 151.328 +		const float f = 1.0f-surf.mTransparency;
 151.329 +		pcMat->AddProperty(&f,1,AI_MATKEY_OPACITY);
 151.330 +		pcMat->AddProperty(&def,1,AI_MATKEY_BLEND_FUNC);
 151.331 +	}
 151.332 +	
 151.333 +
 151.334 +	// ADD TEXTURES to the material
 151.335 +	// TODO: find out how we can handle COLOR textures correctly...
 151.336 +	bool b = HandleTextures(pcMat,surf.mColorTextures,aiTextureType_DIFFUSE);
 151.337 +	b = (b || HandleTextures(pcMat,surf.mDiffuseTextures,aiTextureType_DIFFUSE));
 151.338 +	HandleTextures(pcMat,surf.mSpecularTextures,aiTextureType_SPECULAR);
 151.339 +	HandleTextures(pcMat,surf.mGlossinessTextures,aiTextureType_SHININESS);
 151.340 +	HandleTextures(pcMat,surf.mBumpTextures,aiTextureType_HEIGHT);
 151.341 +	HandleTextures(pcMat,surf.mOpacityTextures,aiTextureType_OPACITY);
 151.342 +	HandleTextures(pcMat,surf.mReflectionTextures,aiTextureType_REFLECTION);
 151.343 +
 151.344 +	// Now we need to know which shader to use .. iterate through the shader list of
 151.345 +	// the surface and  search for a name which we know ... 
 151.346 +	for (ShaderList::const_iterator it = surf.mShaders.begin(), end = surf.mShaders.end();it != end;++it)	{
 151.347 +		//if (!(*it).enabled)continue;
 151.348 +
 151.349 +		if ((*it).functionName == "LW_SuperCelShader" || (*it).functionName == "AH_CelShader")	{
 151.350 +			DefaultLogger::get()->info("LWO2: Mapping LW_SuperCelShader/AH_CelShader to aiShadingMode_Toon");
 151.351 +
 151.352 +			m = aiShadingMode_Toon;
 151.353 +			break;
 151.354 +		}
 151.355 +		else if ((*it).functionName == "LW_RealFresnel" || (*it).functionName == "LW_FastFresnel")	{
 151.356 +			DefaultLogger::get()->info("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel");
 151.357 +
 151.358 +			m = aiShadingMode_Fresnel;
 151.359 +			break;
 151.360 +		}
 151.361 +		else
 151.362 +		{
 151.363 +			DefaultLogger::get()->warn("LWO2: Unknown surface shader: " + (*it).functionName);
 151.364 +		}
 151.365 +	}
 151.366 +	if (surf.mMaximumSmoothAngle <= 0.0f)
 151.367 +		m = aiShadingMode_Flat;
 151.368 +	pcMat->AddProperty((int*)&m,1,AI_MATKEY_SHADING_MODEL);
 151.369 +
 151.370 +	// (the diffuse value is just a scaling factor)
 151.371 +	// If a diffuse texture is set, we set this value to 1.0
 151.372 +	clr = (b && false ? aiColor3D(1.f,1.f,1.f) : surf.mColor);
 151.373 +	clr.r *= surf.mDiffuseValue;
 151.374 +	clr.g *= surf.mDiffuseValue;
 151.375 +	clr.b *= surf.mDiffuseValue;
 151.376 +	pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
 151.377 +}
 151.378 +
 151.379 +// ------------------------------------------------------------------------------------------------
 151.380 +char LWOImporter::FindUVChannels(LWO::TextureList& list,
 151.381 +	LWO::Layer& /*layer*/,LWO::UVChannel& uv, unsigned int next)
 151.382 +{
 151.383 +	char ret = 0;
 151.384 +	for (TextureList::iterator it = list.begin(), end = list.end();it != end;++it)	{
 151.385 +
 151.386 +		// Ignore textures with non-UV mappings for the moment.
 151.387 +		if (!(*it).enabled || !(*it).bCanUse || (*it).mapMode != LWO::Texture::UV)	{
 151.388 +			continue;
 151.389 +		}
 151.390 +		
 151.391 +		if ((*it).mUVChannelIndex == uv.name) {
 151.392 +			ret = 1;
 151.393 +		
 151.394 +			// got it.
 151.395 +			if ((*it).mRealUVIndex == UINT_MAX || (*it).mRealUVIndex == next)
 151.396 +			{
 151.397 +				(*it).mRealUVIndex = next;
 151.398 +			}
 151.399 +			else {
 151.400 +				// channel mismatch. need to duplicate the material.
 151.401 +				DefaultLogger::get()->warn("LWO: Channel mismatch, would need to duplicate surface [design bug]");
 151.402 +
 151.403 +				// TODO
 151.404 +			}
 151.405 +		}
 151.406 +	}
 151.407 +	return ret;
 151.408 +}
 151.409 +
 151.410 +// ------------------------------------------------------------------------------------------------
 151.411 +void LWOImporter::FindUVChannels(LWO::Surface& surf, 
 151.412 +	LWO::SortedRep& sorted,LWO::Layer& layer,
 151.413 +	unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS])
 151.414 +{
 151.415 +	unsigned int next = 0, extra = 0, num_extra = 0;
 151.416 +
 151.417 +	// Check whether we have an UV entry != 0 for one of the faces in 'sorted'
 151.418 +	for (unsigned int i = 0; i < layer.mUVChannels.size();++i)	{
 151.419 +		LWO::UVChannel& uv = layer.mUVChannels[i];
 151.420 +
 151.421 +		for (LWO::SortedRep::const_iterator it = sorted.begin(); it != sorted.end(); ++it)	{
 151.422 +			
 151.423 +			LWO::Face& face = layer.mFaces[*it];
 151.424 +
 151.425 +			for (unsigned int n = 0; n < face.mNumIndices; ++n) {
 151.426 +				unsigned int idx = face.mIndices[n];
 151.427 +
 151.428 +				if (uv.abAssigned[idx] && ((aiVector2D*)&uv.rawData[0])[idx] != aiVector2D()) {
 151.429 +
 151.430 +					if (extra >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
 151.431 +
 151.432 +						DefaultLogger::get()->error("LWO: Maximum number of UV channels for "
 151.433 +							"this mesh reached. Skipping channel \'" + uv.name + "\'");
 151.434 +
 151.435 +					}
 151.436 +					else {
 151.437 +						// Search through all textures assigned to 'surf' and look for this UV channel
 151.438 +						char had = 0;
 151.439 +						had |= FindUVChannels(surf.mColorTextures,layer,uv,next);
 151.440 +						had |= FindUVChannels(surf.mDiffuseTextures,layer,uv,next);
 151.441 +						had |= FindUVChannels(surf.mSpecularTextures,layer,uv,next);
 151.442 +						had |= FindUVChannels(surf.mGlossinessTextures,layer,uv,next);
 151.443 +						had |= FindUVChannels(surf.mOpacityTextures,layer,uv,next);
 151.444 +						had |= FindUVChannels(surf.mBumpTextures,layer,uv,next);
 151.445 +						had |= FindUVChannels(surf.mReflectionTextures,layer,uv,next);
 151.446 +
 151.447 +						// We have a texture referencing this UV channel so we have to take special care
 151.448 +						// and are willing to drop unreferenced channels in favour of it.
 151.449 +						if (had != 0) {
 151.450 +							if (num_extra) {
 151.451 +							
 151.452 +								for (unsigned int a = next; a < std::min( extra, AI_MAX_NUMBER_OF_TEXTURECOORDS-1u ); ++a) {								
 151.453 +									out[a+1] = out[a];
 151.454 +								}
 151.455 +							}
 151.456 +							++extra;
 151.457 +							out[next++] = i;
 151.458 +						}
 151.459 +						// Bäh ... seems not to be used at all. Push to end if enough space is available.
 151.460 +						else {
 151.461 +							out[extra++] = i;
 151.462 +							++num_extra;
 151.463 +						}
 151.464 +					}
 151.465 +					it = sorted.end()-1;
 151.466 +					break;
 151.467 +				}
 151.468 +			}
 151.469 +		}
 151.470 +	}
 151.471 +	if (extra < AI_MAX_NUMBER_OF_TEXTURECOORDS) {
 151.472 +		out[extra] = UINT_MAX;
 151.473 +	}
 151.474 +}
 151.475 +
 151.476 +// ------------------------------------------------------------------------------------------------
 151.477 +void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorted, const LWO::Layer& layer,
 151.478 +	unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS])
 151.479 +{
 151.480 +	unsigned int next = 0;
 151.481 +
 151.482 +	// Check whether we have an vc entry != 0 for one of the faces in 'sorted'
 151.483 +	for (unsigned int i = 0; i < layer.mVColorChannels.size();++i)	{
 151.484 +		const LWO::VColorChannel& vc = layer.mVColorChannels[i];
 151.485 +
 151.486 +		if (surf.mVCMap == vc.name) {
 151.487 +			// The vertex color map is explicitely requested by the surface so we need to take special care of it
 151.488 +			for (unsigned int a = 0; a < std::min(next,AI_MAX_NUMBER_OF_COLOR_SETS-1u); ++a) {
 151.489 +				out[a+1] = out[a];
 151.490 +			}
 151.491 +			out[0] = i;
 151.492 +			++next;
 151.493 +		}
 151.494 +		else {
 151.495 +
 151.496 +			for (LWO::SortedRep::iterator it = sorted.begin(); it != sorted.end(); ++it)	{
 151.497 +				const LWO::Face& face = layer.mFaces[*it];
 151.498 +
 151.499 +				for (unsigned int n = 0; n < face.mNumIndices; ++n) {
 151.500 +					unsigned int idx = face.mIndices[n];
 151.501 +
 151.502 +					if (vc.abAssigned[idx] && ((aiColor4D*)&vc.rawData[0])[idx] != aiColor4D(0.f,0.f,0.f,1.f)) {
 151.503 +						if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) {
 151.504 +
 151.505 +							DefaultLogger::get()->error("LWO: Maximum number of vertex color channels for "
 151.506 +								"this mesh reached. Skipping channel \'" + vc.name + "\'");
 151.507 +
 151.508 +						}
 151.509 +						else {
 151.510 +							out[next++] = i;
 151.511 +						}
 151.512 +						it = sorted.end()-1;
 151.513 +						break;
 151.514 +					}
 151.515 +				}
 151.516 +			}
 151.517 +		}
 151.518 +	}
 151.519 +	if (next != AI_MAX_NUMBER_OF_COLOR_SETS) {
 151.520 +		out[next] = UINT_MAX;
 151.521 +	}
 151.522 +}
 151.523 +
 151.524 +// ------------------------------------------------------------------------------------------------
 151.525 +void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
 151.526 +{
 151.527 +	LE_NCONST uint8_t* const end = mFileBuffer + size;
 151.528 +	while (true)
 151.529 +	{
 151.530 +		if (mFileBuffer + 6 >= end)break;
 151.531 +		LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
 151.532 +
 151.533 +		if (mFileBuffer + head->length > end)
 151.534 +			throw DeadlyImportError("LWO2: Invalid SURF.BLOCK chunk length");
 151.535 +
 151.536 +		uint8_t* const next = mFileBuffer+head->length;
 151.537 +		switch (head->type)
 151.538 +		{
 151.539 +		case AI_LWO_PROJ:
 151.540 +			tex.mapMode = (Texture::MappingMode)GetU2();
 151.541 +			break;
 151.542 +		case AI_LWO_WRAP:
 151.543 +			tex.wrapModeWidth  = (Texture::Wrap)GetU2();
 151.544 +			tex.wrapModeHeight = (Texture::Wrap)GetU2();
 151.545 +			break;
 151.546 +		case AI_LWO_AXIS:
 151.547 +			tex.majorAxis = (Texture::Axes)GetU2();
 151.548 +			break;
 151.549 +		case AI_LWO_IMAG:
 151.550 +			tex.mClipIdx = GetU2();
 151.551 +			break;
 151.552 +		case AI_LWO_VMAP:
 151.553 +			GetS0(tex.mUVChannelIndex,head->length);
 151.554 +			break;
 151.555 +		case AI_LWO_WRPH:
 151.556 +			tex.wrapAmountH = GetF4();
 151.557 +			break;
 151.558 +		case AI_LWO_WRPW:
 151.559 +			tex.wrapAmountW = GetF4();
 151.560 +			break;
 151.561 +		}
 151.562 +		mFileBuffer = next;
 151.563 +	}
 151.564 +}
 151.565 +
 151.566 +// ------------------------------------------------------------------------------------------------
 151.567 +void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture& tex )
 151.568 +{
 151.569 +	// --- not supported at the moment
 151.570 +	DefaultLogger::get()->error("LWO2: Found procedural texture, this is not supported");
 151.571 +	tex.bCanUse = false;
 151.572 +}
 151.573 +
 151.574 +// ------------------------------------------------------------------------------------------------
 151.575 +void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture& tex  )
 151.576 +{
 151.577 +	// --- not supported at the moment
 151.578 +	DefaultLogger::get()->error("LWO2: Found gradient texture, this is not supported");
 151.579 +	tex.bCanUse = false;
 151.580 +}
 151.581 +
 151.582 +// ------------------------------------------------------------------------------------------------
 151.583 +void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
 151.584 +{
 151.585 +	LE_NCONST uint8_t* const end = mFileBuffer + size;
 151.586 +
 151.587 +	// get the ordinal string
 151.588 +	GetS0( tex.ordinal, size);
 151.589 +
 151.590 +	// we could crash later if this is an empty string ...
 151.591 +	if (!tex.ordinal.length())
 151.592 +	{
 151.593 +		DefaultLogger::get()->error("LWO2: Ill-formed SURF.BLOK ordinal string");
 151.594 +		tex.ordinal = "\x00";
 151.595 +	}
 151.596 +	while (true)
 151.597 +	{
 151.598 +		if (mFileBuffer + 6 >= end)break;
 151.599 +		LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
 151.600 +
 151.601 +		if (mFileBuffer + head->length > end)
 151.602 +			throw DeadlyImportError("LWO2: Invalid texture header chunk length");
 151.603 +
 151.604 +		uint8_t* const next = mFileBuffer+head->length;
 151.605 +		switch (head->type)
 151.606 +		{
 151.607 +		case AI_LWO_CHAN:
 151.608 +			tex.type = GetU4();
 151.609 +			break;
 151.610 +		case AI_LWO_ENAB:
 151.611 +			tex.enabled = GetU2() ? true : false;
 151.612 +			break;
 151.613 +		case AI_LWO_OPAC:
 151.614 +			tex.blendType = (Texture::BlendType)GetU2();
 151.615 +			tex.mStrength = GetF4();
 151.616 +			break;
 151.617 +		}
 151.618 +		mFileBuffer = next;
 151.619 +	}
 151.620 +}
 151.621 +
 151.622 +// ------------------------------------------------------------------------------------------------
 151.623 +void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsigned int size )
 151.624 +{
 151.625 +	ai_assert(!mSurfaces->empty());
 151.626 +	LWO::Surface& surf = mSurfaces->back();
 151.627 +	LWO::Texture tex;
 151.628 +
 151.629 +	// load the texture header
 151.630 +	LoadLWO2TextureHeader(head->length,tex);
 151.631 +	size -= head->length + 6;
 151.632 +
 151.633 +	// now get the exact type of the texture
 151.634 +	switch (head->type)
 151.635 +	{
 151.636 +	case AI_LWO_PROC:
 151.637 +		LoadLWO2Procedural(size,tex);
 151.638 +		break;
 151.639 +	case AI_LWO_GRAD:
 151.640 +		LoadLWO2Gradient(size,tex); 
 151.641 +		break;
 151.642 +	case AI_LWO_IMAP:
 151.643 +		LoadLWO2ImageMap(size,tex);
 151.644 +	}
 151.645 +
 151.646 +	// get the destination channel
 151.647 +	TextureList* listRef = NULL;
 151.648 +	switch (tex.type)
 151.649 +	{
 151.650 +	case AI_LWO_COLR:
 151.651 +		listRef = &surf.mColorTextures;break;
 151.652 +	case AI_LWO_DIFF:
 151.653 +		listRef = &surf.mDiffuseTextures;break;
 151.654 +	case AI_LWO_SPEC:
 151.655 +		listRef = &surf.mSpecularTextures;break;
 151.656 +	case AI_LWO_GLOS:
 151.657 +		listRef = &surf.mGlossinessTextures;break;
 151.658 +	case AI_LWO_BUMP:
 151.659 +		listRef = &surf.mBumpTextures;break;
 151.660 +	case AI_LWO_TRAN:
 151.661 +		listRef = &surf.mOpacityTextures;break;
 151.662 +	case AI_LWO_REFL:
 151.663 +		listRef = &surf.mReflectionTextures;break;
 151.664 +	default:
 151.665 +		DefaultLogger::get()->warn("LWO2: Encountered unknown texture type");
 151.666 +		return;
 151.667 +	}
 151.668 +
 151.669 +	// now attach the texture to the parent surface - sort by ordinal string
 151.670 +	for (TextureList::iterator it = listRef->begin();it != listRef->end(); ++it)	{
 151.671 +		if (::strcmp(tex.ordinal.c_str(),(*it).ordinal.c_str()) < 0)	{
 151.672 +			listRef->insert(it,tex);
 151.673 +			return;
 151.674 +		}
 151.675 +	}
 151.676 +	listRef->push_back(tex);
 151.677 +}
 151.678 +
 151.679 +// ------------------------------------------------------------------------------------------------
 151.680 +void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, unsigned int size )
 151.681 +{
 151.682 +	LE_NCONST uint8_t* const end = mFileBuffer + size;
 151.683 +
 151.684 +	ai_assert(!mSurfaces->empty());
 151.685 +	LWO::Surface& surf = mSurfaces->back();
 151.686 +	LWO::Shader shader;
 151.687 +
 151.688 +	// get the ordinal string
 151.689 +	GetS0( shader.ordinal, size);
 151.690 +
 151.691 +	// we could crash later if this is an empty string ...
 151.692 +	if (!shader.ordinal.length())
 151.693 +	{
 151.694 +		DefaultLogger::get()->error("LWO2: Ill-formed SURF.BLOK ordinal string");
 151.695 +		shader.ordinal = "\x00";
 151.696 +	}
 151.697 +
 151.698 +	// read the header
 151.699 +	while (true)
 151.700 +	{
 151.701 +		if (mFileBuffer + 6 >= end)break;
 151.702 +		LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
 151.703 +
 151.704 +		if (mFileBuffer + head->length > end)
 151.705 +			throw DeadlyImportError("LWO2: Invalid shader header chunk length");
 151.706 +
 151.707 +		uint8_t* const next = mFileBuffer+head->length;
 151.708 +		switch (head->type)
 151.709 +		{
 151.710 +		case AI_LWO_ENAB:
 151.711 +			shader.enabled = GetU2() ? true : false;
 151.712 +			break;
 151.713 +
 151.714 +		case AI_LWO_FUNC:
 151.715 +			GetS0( shader.functionName, head->length );
 151.716 +		}
 151.717 +		mFileBuffer = next;
 151.718 +	}
 151.719 +
 151.720 +	// now attach the shader to the parent surface - sort by ordinal string
 151.721 +	for (ShaderList::iterator it = surf.mShaders.begin();it != surf.mShaders.end(); ++it)	{
 151.722 +		if (::strcmp(shader.ordinal.c_str(),(*it).ordinal.c_str()) < 0)	{
 151.723 +			surf.mShaders.insert(it,shader);
 151.724 +			return;
 151.725 +		}
 151.726 +	}
 151.727 +	surf.mShaders.push_back(shader);
 151.728 +}
 151.729 +
 151.730 +// ------------------------------------------------------------------------------------------------
 151.731 +void LWOImporter::LoadLWO2Surface(unsigned int size)
 151.732 +{
 151.733 +	LE_NCONST uint8_t* const end = mFileBuffer + size;
 151.734 +
 151.735 +	mSurfaces->push_back( LWO::Surface () );
 151.736 +	LWO::Surface& surf = mSurfaces->back();
 151.737 +
 151.738 +	GetS0(surf.mName,size);
 151.739 +
 151.740 +	// check whether this surface was derived from any other surface
 151.741 +	std::string derived;
 151.742 +	GetS0(derived,(unsigned int)(end - mFileBuffer));
 151.743 +	if (derived.length())	{
 151.744 +		// yes, find this surface
 151.745 +		for (SurfaceList::iterator it = mSurfaces->begin(), end = mSurfaces->end()-1; it != end; ++it)	{
 151.746 +			if ((*it).mName == derived)	{
 151.747 +				// we have it ...
 151.748 +				surf = *it;
 151.749 +				derived.clear();break;
 151.750 +			}
 151.751 +		}
 151.752 +		if (derived.size())
 151.753 +			DefaultLogger::get()->warn("LWO2: Unable to find source surface: " + derived);
 151.754 +	}
 151.755 +
 151.756 +	while (true)
 151.757 +	{
 151.758 +		if (mFileBuffer + 6 >= end)
 151.759 +			break;
 151.760 +		LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
 151.761 +
 151.762 +		if (mFileBuffer + head->length > end)
 151.763 +			throw DeadlyImportError("LWO2: Invalid surface chunk length");
 151.764 +
 151.765 +		uint8_t* const next = mFileBuffer+head->length;
 151.766 +		switch (head->type)
 151.767 +		{
 151.768 +			// diffuse color
 151.769 +		case AI_LWO_COLR:
 151.770 +			{
 151.771 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,COLR,12);
 151.772 +				surf.mColor.r = GetF4();
 151.773 +				surf.mColor.g = GetF4();
 151.774 +				surf.mColor.b = GetF4();
 151.775 +				break;
 151.776 +			}
 151.777 +			// diffuse strength ... hopefully
 151.778 +		case AI_LWO_DIFF:
 151.779 +			{
 151.780 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,DIFF,4);
 151.781 +				surf.mDiffuseValue = GetF4();
 151.782 +				break;
 151.783 +			}
 151.784 +			// specular strength ... hopefully
 151.785 +		case AI_LWO_SPEC:
 151.786 +			{
 151.787 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPEC,4);
 151.788 +				surf.mSpecularValue = GetF4();
 151.789 +				break;
 151.790 +			}
 151.791 +			// transparency
 151.792 +		case AI_LWO_TRAN:
 151.793 +			{
 151.794 +				// transparency explicitly disabled?
 151.795 +				if (surf.mTransparency == 10e10f)
 151.796 +					break;
 151.797 +
 151.798 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TRAN,4);
 151.799 +				surf.mTransparency = GetF4();
 151.800 +				break;
 151.801 +			}
 151.802 +			// additive transparency
 151.803 +		case AI_LWO_ADTR:
 151.804 +			{
 151.805 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,ADTR,4);
 151.806 +				surf.mAdditiveTransparency = GetF4();
 151.807 +				break;
 151.808 +			}
 151.809 +			// wireframe mode
 151.810 +		case AI_LWO_LINE:
 151.811 +			{
 151.812 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LINE,2);
 151.813 +				if (GetU2() & 0x1)
 151.814 +					surf.mWireframe = true;
 151.815 +				break;
 151.816 +			}
 151.817 +			// glossiness
 151.818 +		case AI_LWO_GLOS:
 151.819 +			{
 151.820 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,GLOS,4);
 151.821 +				surf.mGlossiness = GetF4();
 151.822 +				break;
 151.823 +			}
 151.824 +			// bump intensity
 151.825 +		case AI_LWO_BUMP:
 151.826 +			{
 151.827 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,BUMP,4);
 151.828 +				surf.mBumpIntensity = GetF4();
 151.829 +				break;
 151.830 +			}
 151.831 +			// color highlights
 151.832 +		case AI_LWO_CLRH:
 151.833 +			{
 151.834 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,CLRH,4);
 151.835 +				surf.mColorHighlights = GetF4();
 151.836 +				break;
 151.837 +			}
 151.838 +			// index of refraction
 151.839 +		case AI_LWO_RIND:
 151.840 +			{
 151.841 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,RIND,4);
 151.842 +				surf.mIOR = GetF4();
 151.843 +				break;
 151.844 +			}
 151.845 +			// polygon sidedness
 151.846 +		case AI_LWO_SIDE:
 151.847 +			{
 151.848 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SIDE,2);
 151.849 +				surf.bDoubleSided = (3 == GetU2());
 151.850 +				break;
 151.851 +			}
 151.852 +			// maximum smoothing angle
 151.853 +		case AI_LWO_SMAN:
 151.854 +			{
 151.855 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SMAN,4);
 151.856 +				surf.mMaximumSmoothAngle = fabs( GetF4() );
 151.857 +				break;
 151.858 +			}
 151.859 +			// vertex color channel to be applied to the surface
 151.860 +		case AI_LWO_VCOL:
 151.861 +			{
 151.862 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,VCOL,12);
 151.863 +				surf.mDiffuseValue *= GetF4();				// strength
 151.864 +				ReadVSizedIntLWO2(mFileBuffer);             // skip envelope
 151.865 +				surf.mVCMapType = GetU4();					// type of the channel
 151.866 +
 151.867 +				// name of the channel
 151.868 +				GetS0(surf.mVCMap, (unsigned int) (next - mFileBuffer ));
 151.869 +				break;
 151.870 +			}
 151.871 +			// surface bock entry
 151.872 +		case AI_LWO_BLOK:
 151.873 +			{
 151.874 +				AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,BLOK,4);
 151.875 +				LE_NCONST IFF::SubChunkHeader* head2 = IFF::LoadSubChunk(mFileBuffer);
 151.876 +
 151.877 +				switch (head2->type)
 151.878 +				{
 151.879 +				case AI_LWO_PROC:
 151.880 +				case AI_LWO_GRAD:
 151.881 +				case AI_LWO_IMAP:
 151.882 +					LoadLWO2TextureBlock(head2, head->length);
 151.883 +					break;
 151.884 +				case AI_LWO_SHDR:
 151.885 +					LoadLWO2ShaderBlock(head2, head->length);
 151.886 +					break;
 151.887 +
 151.888 +				default:
 151.889 +					DefaultLogger::get()->warn("LWO2: Found an unsupported surface BLOK");
 151.890 +				};
 151.891 +
 151.892 +				break;
 151.893 +			}
 151.894 +		}
 151.895 +		mFileBuffer = next;
 151.896 +	}
 151.897 +}
 151.898 +
 151.899 +#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
   152.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   152.2 +++ b/libs/assimp/LWSLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   152.3 @@ -0,0 +1,924 @@
   152.4 +/*
   152.5 +---------------------------------------------------------------------------
   152.6 +Open Asset Import Library (assimp)
   152.7 +---------------------------------------------------------------------------
   152.8 +
   152.9 +Copyright (c) 2006-2012, assimp team
  152.10 +
  152.11 +All rights reserved.
  152.12 +
  152.13 +Redistribution and use of this software in source and binary forms, 
  152.14 +with or without modification, are permitted provided that the following 
  152.15 +conditions are met:
  152.16 +
  152.17 +* Redistributions of source code must retain the above
  152.18 +  copyright notice, this list of conditions and the
  152.19 +  following disclaimer.
  152.20 +
  152.21 +* Redistributions in binary form must reproduce the above
  152.22 +  copyright notice, this list of conditions and the
  152.23 +  following disclaimer in the documentation and/or other
  152.24 +  materials provided with the distribution.
  152.25 +
  152.26 +* Neither the name of the assimp team, nor the names of its
  152.27 +  contributors may be used to endorse or promote products
  152.28 +  derived from this software without specific prior
  152.29 +  written permission of the assimp team.
  152.30 +
  152.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  152.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  152.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  152.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  152.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  152.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  152.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  152.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  152.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  152.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  152.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  152.42 +---------------------------------------------------------------------------
  152.43 +*/
  152.44 +
  152.45 +/** @file  LWSLoader.cpp
  152.46 + *  @brief Implementation of the LWS importer class 
  152.47 + */
  152.48 +
  152.49 +#include "AssimpPCH.h"
  152.50 +#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
  152.51 +
  152.52 +#include "LWSLoader.h"
  152.53 +#include "ParsingUtils.h"
  152.54 +#include "fast_atof.h"
  152.55 +
  152.56 +#include "SceneCombiner.h"
  152.57 +#include "GenericProperty.h"
  152.58 +#include "SkeletonMeshBuilder.h"
  152.59 +#include "ConvertToLHProcess.h"
  152.60 +#include "Importer.h"
  152.61 +
  152.62 +using namespace Assimp;
  152.63 +
  152.64 +static const aiImporterDesc desc = {
  152.65 +	"LightWave Scene Importer",
  152.66 +	"",
  152.67 +	"",
  152.68 +	"http://www.newtek.com/lightwave.html=",
  152.69 +	aiImporterFlags_SupportTextFlavour,
  152.70 +	0,
  152.71 +	0,
  152.72 +	0,
  152.73 +	0,
  152.74 +	"lws mot" 
  152.75 +};
  152.76 +
  152.77 +// ------------------------------------------------------------------------------------------------
  152.78 +// Recursive parsing of LWS files
  152.79 +void LWS::Element::Parse (const char*& buffer)
  152.80 +{
  152.81 +	for (;SkipSpacesAndLineEnd(&buffer);SkipLine(&buffer)) {
  152.82 +	
  152.83 +		// begin of a new element with children
  152.84 +		bool sub = false;
  152.85 +		if (*buffer == '{') {
  152.86 +			++buffer;
  152.87 +			SkipSpaces(&buffer);
  152.88 +			sub = true;
  152.89 +		}
  152.90 +		else if (*buffer == '}')
  152.91 +			return;
  152.92 +
  152.93 +		children.push_back(Element());
  152.94 +
  152.95 +		// copy data line - read token per token
  152.96 +
  152.97 +		const char* cur = buffer;
  152.98 +		while (!IsSpaceOrNewLine(*buffer)) ++buffer;
  152.99 +		children.back().tokens[0] = std::string(cur,(size_t) (buffer-cur));
 152.100 +		SkipSpaces(&buffer);
 152.101 +
 152.102 +		if (children.back().tokens[0] == "Plugin") 
 152.103 +		{
 152.104 +			DefaultLogger::get()->debug("LWS: Skipping over plugin-specific data");
 152.105 +
 152.106 +			// strange stuff inside Plugin/Endplugin blocks. Needn't
 152.107 +			// follow LWS syntax, so we skip over it
 152.108 +			for (;SkipSpacesAndLineEnd(&buffer);SkipLine(&buffer)) {
 152.109 +				if (!::strncmp(buffer,"EndPlugin",9)) {
 152.110 +					//SkipLine(&buffer);
 152.111 +					break;
 152.112 +				}
 152.113 +			}
 152.114 +			continue;
 152.115 +		}
 152.116 +
 152.117 +		cur = buffer;
 152.118 +		while (!IsLineEnd(*buffer)) ++buffer;
 152.119 +		children.back().tokens[1] = std::string(cur,(size_t) (buffer-cur));
 152.120 +
 152.121 +		// parse more elements recursively
 152.122 +		if (sub)
 152.123 +			children.back().Parse(buffer);
 152.124 +	}
 152.125 +}
 152.126 +
 152.127 +// ------------------------------------------------------------------------------------------------
 152.128 +// Constructor to be privately used by Importer
 152.129 +LWSImporter::LWSImporter()
 152.130 +: noSkeletonMesh()
 152.131 +{
 152.132 +	// nothing to do here
 152.133 +}
 152.134 +
 152.135 +// ------------------------------------------------------------------------------------------------
 152.136 +// Destructor, private as well 
 152.137 +LWSImporter::~LWSImporter()
 152.138 +{
 152.139 +	// nothing to do here
 152.140 +}
 152.141 +
 152.142 +// ------------------------------------------------------------------------------------------------
 152.143 +// Returns whether the class can handle the format of the given file. 
 152.144 +bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool checkSig) const
 152.145 +{
 152.146 +	const std::string extension = GetExtension(pFile);
 152.147 +	if (extension == "lws" || extension == "mot")
 152.148 +		return true;
 152.149 +
 152.150 +	// if check for extension is not enough, check for the magic tokens LWSC and LWMO
 152.151 +	if (!extension.length() || checkSig) {
 152.152 +		uint32_t tokens[2]; 
 152.153 +		tokens[0] = AI_MAKE_MAGIC("LWSC");
 152.154 +		tokens[1] = AI_MAKE_MAGIC("LWMO");
 152.155 +		return CheckMagicToken(pIOHandler,pFile,tokens,2);
 152.156 +	}
 152.157 +	return false;
 152.158 +}
 152.159 +
 152.160 +// ------------------------------------------------------------------------------------------------
 152.161 +// Get list of file extensions
 152.162 +const aiImporterDesc* LWSImporter::GetInfo () const
 152.163 +{
 152.164 +	return &desc;
 152.165 +}
 152.166 +
 152.167 +// ------------------------------------------------------------------------------------------------
 152.168 +// Setup configuration properties
 152.169 +void LWSImporter::SetupProperties(const Importer* pImp)
 152.170 +{
 152.171 +	// AI_CONFIG_FAVOUR_SPEED
 152.172 +	configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
 152.173 +
 152.174 +	// AI_CONFIG_IMPORT_LWS_ANIM_START
 152.175 +	first = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_START,
 152.176 +		150392 /* magic hack */);
 152.177 +
 152.178 +	// AI_CONFIG_IMPORT_LWS_ANIM_END
 152.179 +	last = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_END,
 152.180 +		150392 /* magic hack */);
 152.181 +
 152.182 +	if (last < first) {
 152.183 +		std::swap(last,first);
 152.184 +	}
 152.185 +
 152.186 +	noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
 152.187 +}
 152.188 +
 152.189 +// ------------------------------------------------------------------------------------------------
 152.190 +// Read an envelope description
 152.191 +void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
 152.192 +{
 152.193 +	if (dad.children.empty()) {
 152.194 +		DefaultLogger::get()->error("LWS: Envelope descriptions must not be empty");	
 152.195 +		return;
 152.196 +	}
 152.197 +
 152.198 +	// reserve enough storage
 152.199 +	std::list< LWS::Element >::const_iterator it = dad.children.begin();;
 152.200 +	fill.keys.reserve(strtoul10(it->tokens[1].c_str()));
 152.201 +
 152.202 +	for (++it; it != dad.children.end(); ++it) {
 152.203 +		const char* c = (*it).tokens[1].c_str();
 152.204 +
 152.205 +		if ((*it).tokens[0] == "Key") {
 152.206 +			fill.keys.push_back(LWO::Key());
 152.207 +			LWO::Key& key = fill.keys.back();
 152.208 +
 152.209 +			float f;
 152.210 +			SkipSpaces(&c);
 152.211 +			c = fast_atoreal_move<float>(c,key.value);
 152.212 +			SkipSpaces(&c);
 152.213 +			c = fast_atoreal_move<float>(c,f);
 152.214 +
 152.215 +			key.time = f;
 152.216 +
 152.217 +			unsigned int span = strtoul10(c,&c), num = 0;
 152.218 +			switch (span) {
 152.219 +			
 152.220 +				case 0:
 152.221 +					key.inter = LWO::IT_TCB;
 152.222 +					num = 5;
 152.223 +					break;
 152.224 +				case 1:
 152.225 +				case 2:
 152.226 +					key.inter = LWO::IT_HERM;
 152.227 +					num = 5;
 152.228 +					break;
 152.229 +				case 3:
 152.230 +					key.inter = LWO::IT_LINE;
 152.231 +					num = 0;
 152.232 +					break;
 152.233 +				case 4:
 152.234 +					key.inter = LWO::IT_STEP;
 152.235 +					num = 0;
 152.236 +					break;
 152.237 +				case 5:
 152.238 +					key.inter = LWO::IT_BEZ2;
 152.239 +					num = 4;
 152.240 +					break;
 152.241 +				default:
 152.242 +					DefaultLogger::get()->error("LWS: Unknown span type");
 152.243 +			}
 152.244 +			for (unsigned int i = 0; i < num;++i) {
 152.245 +				SkipSpaces(&c);
 152.246 +				c = fast_atoreal_move<float>(c,key.params[i]);
 152.247 +			}
 152.248 +		}
 152.249 +		else if ((*it).tokens[0] == "Behaviors") {
 152.250 +			SkipSpaces(&c);
 152.251 +			fill.pre = (LWO::PrePostBehaviour) strtoul10(c,&c);
 152.252 +			SkipSpaces(&c);
 152.253 +			fill.post = (LWO::PrePostBehaviour) strtoul10(c,&c);
 152.254 +		}
 152.255 +	}
 152.256 +}
 152.257 +
 152.258 +// ------------------------------------------------------------------------------------------------
 152.259 +// Read animation channels in the old LightWave animation format
 152.260 +void LWSImporter::ReadEnvelope_Old(
 152.261 +	std::list< LWS::Element >::const_iterator& it, 
 152.262 +	const std::list< LWS::Element >::const_iterator& end,
 152.263 +	LWS::NodeDesc& nodes,
 152.264 +	unsigned int /*version*/)
 152.265 +{
 152.266 +	unsigned int num,sub_num;
 152.267 +	if (++it == end)goto unexpected_end;
 152.268 +
 152.269 +	num = strtoul10((*it).tokens[0].c_str());
 152.270 +	for (unsigned int i = 0; i < num; ++i) {
 152.271 +	
 152.272 +		nodes.channels.push_back(LWO::Envelope());
 152.273 +		LWO::Envelope& envl = nodes.channels.back();
 152.274 +
 152.275 +		envl.index = i;
 152.276 +		envl.type  = (LWO::EnvelopeType)(i+1);
 152.277 +	
 152.278 +		if (++it == end)goto unexpected_end;
 152.279 +		sub_num = strtoul10((*it).tokens[0].c_str());
 152.280 +
 152.281 +		for (unsigned int n = 0; n < sub_num;++n) {
 152.282 +
 152.283 +			if (++it == end)goto unexpected_end;
 152.284 +
 152.285 +			// parse value and time, skip the rest for the moment.
 152.286 +			LWO::Key key;
 152.287 +			const char* c = fast_atoreal_move<float>((*it).tokens[0].c_str(),key.value);
 152.288 +			SkipSpaces(&c);
 152.289 +			float f;
 152.290 +			fast_atoreal_move<float>((*it).tokens[0].c_str(),f);
 152.291 +			key.time = f;
 152.292 +
 152.293 +			envl.keys.push_back(key);
 152.294 +		}
 152.295 +	}
 152.296 +	return;
 152.297 +
 152.298 +unexpected_end:
 152.299 +	DefaultLogger::get()->error("LWS: Encountered unexpected end of file while parsing object motion");
 152.300 +}
 152.301 +
 152.302 +// ------------------------------------------------------------------------------------------------
 152.303 +// Setup a nice name for a node 
 152.304 +void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src)
 152.305 +{
 152.306 +	const unsigned int combined = src.number | ((unsigned int)src.type) << 28u;
 152.307 +
 152.308 +	// the name depends on the type. We break LWS's strange naming convention
 152.309 +	// and return human-readable, but still machine-parsable and unique, strings.
 152.310 +	if (src.type == LWS::NodeDesc::OBJECT)	{
 152.311 +
 152.312 +		if (src.path.length()) {
 152.313 +			std::string::size_type s = src.path.find_last_of("\\/");
 152.314 +			if (s == std::string::npos)
 152.315 +				s = 0;
 152.316 +			else ++s;
 152.317 +            std::string::size_type t = src.path.substr(s).find_last_of(".");
 152.318 +			
 152.319 +			nd->mName.length = ::sprintf(nd->mName.data,"%s_(%08X)",src.path.substr(s).substr(0,t).c_str(),combined);
 152.320 +			return;
 152.321 +		}
 152.322 +	}
 152.323 +	nd->mName.length = ::sprintf(nd->mName.data,"%s_(%08X)",src.name,combined);
 152.324 +}
 152.325 +
 152.326 +// ------------------------------------------------------------------------------------------------
 152.327 +// Recursively build the scenegraph
 152.328 +void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<AttachmentInfo>& attach,
 152.329 +	BatchLoader& batch,
 152.330 +	aiCamera**& camOut,
 152.331 +	aiLight**& lightOut, 
 152.332 +	std::vector<aiNodeAnim*>& animOut)
 152.333 +{
 152.334 +	// Setup a very cryptic name for the node, we want the user to be happy
 152.335 +	SetupNodeName(nd,src);
 152.336 +    aiNode* ndAnim = nd;
 152.337 +
 152.338 +	// If the node is an object
 152.339 +	if (src.type == LWS::NodeDesc::OBJECT) {
 152.340 +
 152.341 +		// If the object is from an external file, get it
 152.342 +		aiScene* obj = NULL;
 152.343 +        if (src.path.length() ) {
 152.344 +            obj = batch.GetImport(src.id);
 152.345 +            if (!obj) {
 152.346 +                DefaultLogger::get()->error("LWS: Failed to read external file " + src.path);
 152.347 +            }
 152.348 +            else {
 152.349 +                if (obj->mRootNode->mNumChildren == 1) {
 152.350 +					
 152.351 +                    //If the pivot is not set for this layer, get it from the external object
 152.352 +                    if (!src.isPivotSet) {
 152.353 +                        src.pivotPos.x = +obj->mRootNode->mTransformation.a4;
 152.354 +                        src.pivotPos.y = +obj->mRootNode->mTransformation.b4;
 152.355 +                        src.pivotPos.z = -obj->mRootNode->mTransformation.c4; //The sign is the RH to LH back conversion
 152.356 +                    }
 152.357 +					
 152.358 +                    //Remove first node from obj (the old pivot), reset transform of second node (the mesh node)
 152.359 +                    aiNode* newRootNode = obj->mRootNode->mChildren[0];
 152.360 +					obj->mRootNode->mChildren[0] = NULL;
 152.361 +					delete obj->mRootNode;
 152.362 +
 152.363 +                    obj->mRootNode = newRootNode;
 152.364 +                    obj->mRootNode->mTransformation.a4 = 0.0;
 152.365 +                    obj->mRootNode->mTransformation.b4 = 0.0;
 152.366 +                    obj->mRootNode->mTransformation.c4 = 0.0;
 152.367 +                }
 152.368 +            }
 152.369 +        }
 152.370 +		
 152.371 +		//Setup the pivot node (also the animation node), the one we received
 152.372 +        nd->mName = std::string("Pivot:") + nd->mName.data;
 152.373 +		ndAnim = nd;
 152.374 +		
 152.375 +        //Add the attachment node to it
 152.376 +        nd->mNumChildren = 1;
 152.377 +        nd->mChildren = new aiNode*[1];
 152.378 +        nd->mChildren[0] = new aiNode();
 152.379 +        nd->mChildren[0]->mParent = nd;
 152.380 +        nd->mChildren[0]->mTransformation.a4 = -src.pivotPos.x;
 152.381 +        nd->mChildren[0]->mTransformation.b4 = -src.pivotPos.y;
 152.382 +        nd->mChildren[0]->mTransformation.c4 = -src.pivotPos.z;
 152.383 +		SetupNodeName(nd->mChildren[0], src);
 152.384 +		
 152.385 +		//Update the attachment node
 152.386 +		nd = nd->mChildren[0];
 152.387 +		
 152.388 +        //Push attachment, if the object came from an external file
 152.389 +        if (obj) {
 152.390 +            attach.push_back(AttachmentInfo(obj,nd));
 152.391 +        }
 152.392 +    }
 152.393 +
 152.394 +	// If object is a light source - setup a corresponding ai structure
 152.395 +	else if (src.type == LWS::NodeDesc::LIGHT) {
 152.396 +		aiLight* lit = *lightOut++ = new aiLight();
 152.397 +
 152.398 +		// compute final light color
 152.399 +		lit->mColorDiffuse = lit->mColorSpecular = src.lightColor*src.lightIntensity;
 152.400 +
 152.401 +		// name to attach light to node -> unique due to LWs indexing system
 152.402 +		lit->mName = nd->mName;
 152.403 +
 152.404 +		// detemine light type and setup additional members
 152.405 +		if (src.lightType == 2) { /* spot light */
 152.406 +
 152.407 +			lit->mType = aiLightSource_SPOT;
 152.408 +			lit->mAngleInnerCone = (float)AI_DEG_TO_RAD( src.lightConeAngle );
 152.409 +			lit->mAngleOuterCone = lit->mAngleInnerCone+(float)AI_DEG_TO_RAD( src.lightEdgeAngle );
 152.410 +
 152.411 +		}
 152.412 +		else if (src.lightType == 1) { /* directional light source */
 152.413 +			lit->mType = aiLightSource_DIRECTIONAL;
 152.414 +		}
 152.415 +		else lit->mType = aiLightSource_POINT;
 152.416 +
 152.417 +		// fixme: no proper handling of light falloffs yet
 152.418 +		if (src.lightFalloffType == 1)
 152.419 +			lit->mAttenuationConstant = 1.f;
 152.420 +		else if (src.lightFalloffType == 1)
 152.421 +			lit->mAttenuationLinear = 1.f;
 152.422 +		else 
 152.423 +			lit->mAttenuationQuadratic = 1.f;
 152.424 +	}
 152.425 +
 152.426 +	// If object is a camera - setup a corresponding ai structure
 152.427 +	else if (src.type == LWS::NodeDesc::CAMERA) {
 152.428 +		aiCamera* cam = *camOut++ = new aiCamera();
 152.429 +
 152.430 +		// name to attach cam to node -> unique due to LWs indexing system
 152.431 +		cam->mName = nd->mName;
 152.432 +	}
 152.433 +
 152.434 +	// Get the node transformation from the LWO key
 152.435 +	LWO::AnimResolver resolver(src.channels,fps);
 152.436 +	resolver.ExtractBindPose(ndAnim->mTransformation);
 152.437 +
 152.438 +	// .. and construct animation channels
 152.439 +	aiNodeAnim* anim = NULL;
 152.440 +
 152.441 +	if (first != last) {
 152.442 +		resolver.SetAnimationRange(first,last);
 152.443 +		resolver.ExtractAnimChannel(&anim,AI_LWO_ANIM_FLAG_SAMPLE_ANIMS|AI_LWO_ANIM_FLAG_START_AT_ZERO);
 152.444 +		if (anim) {
 152.445 +			anim->mNodeName = ndAnim->mName;
 152.446 +			animOut.push_back(anim);
 152.447 +		}
 152.448 +	}
 152.449 +
 152.450 +	// Add children
 152.451 +	if (src.children.size()) {
 152.452 +		nd->mChildren = new aiNode*[src.children.size()];
 152.453 +		for (std::list<LWS::NodeDesc*>::iterator it = src.children.begin(); it != src.children.end(); ++it) {
 152.454 +			aiNode* ndd = nd->mChildren[nd->mNumChildren++] = new aiNode();
 152.455 +			ndd->mParent = nd;
 152.456 +
 152.457 +			BuildGraph(ndd,**it,attach,batch,camOut,lightOut,animOut);
 152.458 +		}
 152.459 +	}
 152.460 +}
 152.461 +
 152.462 +// ------------------------------------------------------------------------------------------------
 152.463 +// Determine the exact location of a LWO file
 152.464 +std::string LWSImporter::FindLWOFile(const std::string& in)
 152.465 +{
 152.466 +	// insert missing directory seperator if necessary
 152.467 +	std::string tmp;
 152.468 +	if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
 152.469 +	{
 152.470 +		tmp = in[0] + (":\\" + in.substr(2));
 152.471 +	}
 152.472 +	else tmp = in;
 152.473 +
 152.474 +	if (io->Exists(tmp)) {
 152.475 +		return in;
 152.476 +	}
 152.477 +
 152.478 +	// file is not accessible for us ... maybe it's packed by 
 152.479 +	// LightWave's 'Package Scene' command?
 152.480 +
 152.481 +	// Relevant for us are the following two directories:
 152.482 +	// <folder>\Objects\<hh>\<*>.lwo
 152.483 +	// <folder>\Scenes\<hh>\<*>.lws
 152.484 +	// where <hh> is optional.
 152.485 +
 152.486 +	std::string test = ".." + (io->getOsSeparator() + tmp); 
 152.487 +	if (io->Exists(test)) {
 152.488 +		return test;
 152.489 +	}
 152.490 +
 152.491 +	test = ".." + (io->getOsSeparator() + test); 
 152.492 +	if (io->Exists(test)) {
 152.493 +		return test;
 152.494 +	}
 152.495 +
 152.496 +
 152.497 +	// return original path, maybe the IOsystem knows better
 152.498 +	return tmp;
 152.499 +}
 152.500 +
 152.501 +// ------------------------------------------------------------------------------------------------
 152.502 +// Read file into given scene data structure
 152.503 +void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene, 
 152.504 +	IOSystem* pIOHandler)
 152.505 +{
 152.506 +	io = pIOHandler;
 152.507 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 152.508 +
 152.509 +	// Check whether we can read from the file
 152.510 +	if( file.get() == NULL) {
 152.511 +		throw DeadlyImportError( "Failed to open LWS file " + pFile + ".");
 152.512 +	}
 152.513 +
 152.514 +	// Allocate storage and copy the contents of the file to a memory buffer
 152.515 +	std::vector< char > mBuffer;
 152.516 +	TextFileToBuffer(file.get(),mBuffer);
 152.517 +	
 152.518 +	// Parse the file structure
 152.519 +	LWS::Element root; const char* dummy = &mBuffer[0];
 152.520 +	root.Parse(dummy);
 152.521 +
 152.522 +	// Construct a Batchimporter to read more files recursively
 152.523 +	BatchLoader batch(pIOHandler);
 152.524 +//	batch.SetBasePath(pFile);
 152.525 +
 152.526 +	// Construct an array to receive the flat output graph
 152.527 +	std::list<LWS::NodeDesc> nodes;
 152.528 +
 152.529 +	unsigned int cur_light = 0, cur_camera = 0, cur_object = 0;
 152.530 +	unsigned int num_light = 0, num_camera = 0, num_object = 0;
 152.531 +
 152.532 +	// check magic identifier, 'LWSC'
 152.533 +	bool motion_file = false;
 152.534 +	std::list< LWS::Element >::const_iterator it = root.children.begin();
 152.535 +	
 152.536 +	if ((*it).tokens[0] == "LWMO")
 152.537 +		motion_file = true;
 152.538 +
 152.539 +	if ((*it).tokens[0] != "LWSC" && !motion_file)
 152.540 +		throw DeadlyImportError("LWS: Not a LightWave scene, magic tag LWSC not found");
 152.541 +
 152.542 +	// get file format version and print to log
 152.543 +	++it;
 152.544 +	unsigned int version = strtoul10((*it).tokens[0].c_str());
 152.545 +	DefaultLogger::get()->info("LWS file format version is " + (*it).tokens[0]);
 152.546 +	first = 0.;
 152.547 +	last  = 60.;
 152.548 +	fps   = 25.; /* seems to be a good default frame rate */
 152.549 +
 152.550 +	// Now read all elements in a very straghtforward manner
 152.551 +	for (; it != root.children.end(); ++it) {
 152.552 +		const char* c = (*it).tokens[1].c_str();
 152.553 +
 152.554 +		// 'FirstFrame': begin of animation slice
 152.555 +		if ((*it).tokens[0] == "FirstFrame") {
 152.556 +			if (150392. != first           /* see SetupProperties() */)
 152.557 +				first = strtoul10(c,&c)-1.; /* we're zero-based */
 152.558 +		}
 152.559 +
 152.560 +		// 'LastFrame': end of animation slice
 152.561 +		else if ((*it).tokens[0] == "LastFrame") {
 152.562 +			if (150392. != last      /* see SetupProperties() */)
 152.563 +				last = strtoul10(c,&c)-1.; /* we're zero-based */
 152.564 +		}
 152.565 +
 152.566 +		// 'FramesPerSecond': frames per second
 152.567 +		else if ((*it).tokens[0] == "FramesPerSecond") {
 152.568 +			fps = strtoul10(c,&c);
 152.569 +		}
 152.570 +
 152.571 +		// 'LoadObjectLayer': load a layer of a specific LWO file
 152.572 +		else if ((*it).tokens[0] == "LoadObjectLayer") {
 152.573 +
 152.574 +			// get layer index
 152.575 +			const int layer = strtoul10(c,&c);
 152.576 +
 152.577 +			// setup the layer to be loaded
 152.578 +			BatchLoader::PropertyMap props;
 152.579 +			SetGenericProperty(props.ints,AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,layer);
 152.580 +
 152.581 +			// add node to list
 152.582 +			LWS::NodeDesc d;
 152.583 +			d.type = LWS::NodeDesc::OBJECT;
 152.584 +			if (version >= 4) { // handle LWSC 4 explicit ID
 152.585 +				SkipSpaces(&c);
 152.586 +				d.number = strtoul16(c,&c) & AI_LWS_MASK;
 152.587 +			}
 152.588 +			else d.number = cur_object++;
 152.589 +
 152.590 +			// and add the file to the import list
 152.591 +			SkipSpaces(&c);
 152.592 +			std::string path = FindLWOFile( c );
 152.593 +			d.path = path;
 152.594 +			d.id = batch.AddLoadRequest(path,0,&props);
 152.595 +
 152.596 +			nodes.push_back(d);
 152.597 +			num_object++;
 152.598 +		}
 152.599 +		// 'LoadObject': load a LWO file into the scenegraph
 152.600 +		else if ((*it).tokens[0] == "LoadObject") {
 152.601 +			
 152.602 +			// add node to list
 152.603 +			LWS::NodeDesc d;
 152.604 +			d.type = LWS::NodeDesc::OBJECT;
 152.605 +			
 152.606 +			if (version >= 4) { // handle LWSC 4 explicit ID
 152.607 +				d.number = strtoul16(c,&c) & AI_LWS_MASK;
 152.608 +				SkipSpaces(&c);
 152.609 +			}
 152.610 +			else d.number = cur_object++;
 152.611 +			std::string path = FindLWOFile( c );
 152.612 +			d.id = batch.AddLoadRequest(path,0,NULL);
 152.613 +
 152.614 +			d.path = path;
 152.615 +			nodes.push_back(d);
 152.616 +			num_object++;
 152.617 +		}
 152.618 +		// 'AddNullObject': add a dummy node to the hierarchy
 152.619 +		else if ((*it).tokens[0] == "AddNullObject") {
 152.620 +
 152.621 +			// add node to list
 152.622 +			LWS::NodeDesc d;
 152.623 +			d.type = LWS::NodeDesc::OBJECT;
 152.624 +			if (version >= 4) { // handle LWSC 4 explicit ID
 152.625 +				d.number = strtoul16(c,&c) & AI_LWS_MASK;
 152.626 +				SkipSpaces(&c);
 152.627 +			}
 152.628 +			else d.number = cur_object++;
 152.629 +            d.name = c;
 152.630 +			nodes.push_back(d);
 152.631 +
 152.632 +			num_object++;
 152.633 +		}
 152.634 +		// 'NumChannels': Number of envelope channels assigned to last layer
 152.635 +		else if ((*it).tokens[0] == "NumChannels") {
 152.636 +			// ignore for now
 152.637 +		}
 152.638 +		// 'Channel': preceedes any envelope description
 152.639 +		else if ((*it).tokens[0] == "Channel") {
 152.640 +			if (nodes.empty()) {
 152.641 +				if (motion_file) {
 152.642 +
 152.643 +					// LightWave motion file. Add dummy node
 152.644 +					LWS::NodeDesc d;
 152.645 +					d.type = LWS::NodeDesc::OBJECT;
 152.646 +					d.name = c;
 152.647 +					d.number = cur_object++;
 152.648 +					nodes.push_back(d);
 152.649 +				}
 152.650 +				else DefaultLogger::get()->error("LWS: Unexpected keyword: \'Channel\'");
 152.651 +			}
 152.652 +
 152.653 +			// important: index of channel
 152.654 +			nodes.back().channels.push_back(LWO::Envelope());
 152.655 +			LWO::Envelope& env = nodes.back().channels.back();
 152.656 +			
 152.657 +			env.index = strtoul10(c);
 152.658 +
 152.659 +			// currently we can just interpret the standard channels 0...9
 152.660 +			// (hack) assume that index-i yields the binary channel type from LWO
 152.661 +			env.type = (LWO::EnvelopeType)(env.index+1);
 152.662 +
 152.663 +		}
 152.664 +		// 'Envelope': a single animation channel
 152.665 +		else if ((*it).tokens[0] == "Envelope") {
 152.666 +			if (nodes.empty() || nodes.back().channels.empty())
 152.667 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'Envelope\'");
 152.668 +			else {
 152.669 +				ReadEnvelope((*it),nodes.back().channels.back());
 152.670 +			}
 152.671 +		}
 152.672 +		// 'ObjectMotion': animation information for older lightwave formats
 152.673 +		else if (version < 3  && ((*it).tokens[0] == "ObjectMotion" ||
 152.674 +			(*it).tokens[0] == "CameraMotion" ||
 152.675 +			(*it).tokens[0] == "LightMotion")) {
 152.676 +
 152.677 +			if (nodes.empty())
 152.678 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'<Light|Object|Camera>Motion\'");
 152.679 +			else {
 152.680 +				ReadEnvelope_Old(it,root.children.end(),nodes.back(),version);
 152.681 +			}
 152.682 +		}
 152.683 +		// 'Pre/PostBehavior': pre/post animation behaviour for LWSC 2
 152.684 +		else if (version == 2 && (*it).tokens[0] == "Pre/PostBehavior") {
 152.685 +			if (nodes.empty())
 152.686 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'Pre/PostBehavior'");
 152.687 +			else {
 152.688 +				for (std::list<LWO::Envelope>::iterator it = nodes.back().channels.begin(); it != nodes.back().channels.end(); ++it) {
 152.689 +					// two ints per envelope
 152.690 +					LWO::Envelope& env = *it;
 152.691 +					env.pre  = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c);
 152.692 +					env.post = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c);
 152.693 +				}
 152.694 +			}
 152.695 +		}
 152.696 +		// 'ParentItem': specifies the parent of the current element
 152.697 +		else if ((*it).tokens[0] == "ParentItem") {
 152.698 +			if (nodes.empty())
 152.699 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'ParentItem\'");
 152.700 +
 152.701 +			else nodes.back().parent = strtoul16(c,&c);
 152.702 +		}
 152.703 +		// 'ParentObject': deprecated one for older formats
 152.704 +		else if (version < 3 && (*it).tokens[0] == "ParentObject") {
 152.705 +			if (nodes.empty())
 152.706 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'ParentObject\'");
 152.707 +
 152.708 +			else { 
 152.709 +				nodes.back().parent = strtoul10(c,&c) | (1u << 28u);
 152.710 +			}
 152.711 +		}
 152.712 +		// 'AddCamera': add a camera to the scenegraph
 152.713 +		else if ((*it).tokens[0] == "AddCamera") {
 152.714 +
 152.715 +			// add node to list
 152.716 +			LWS::NodeDesc d;
 152.717 +			d.type = LWS::NodeDesc::CAMERA;
 152.718 +
 152.719 +			if (version >= 4) { // handle LWSC 4 explicit ID
 152.720 +				d.number = strtoul16(c,&c) & AI_LWS_MASK;
 152.721 +			}
 152.722 +			else d.number = cur_camera++;
 152.723 +			nodes.push_back(d);
 152.724 +
 152.725 +			num_camera++;
 152.726 +		}
 152.727 +		// 'CameraName': set name of currently active camera
 152.728 +		else if ((*it).tokens[0] == "CameraName") {
 152.729 +			if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA)
 152.730 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'CameraName\'");
 152.731 +
 152.732 +			else nodes.back().name = c;
 152.733 +		}
 152.734 +		// 'AddLight': add a light to the scenegraph
 152.735 +		else if ((*it).tokens[0] == "AddLight") {
 152.736 +
 152.737 +			// add node to list
 152.738 +			LWS::NodeDesc d;
 152.739 +			d.type = LWS::NodeDesc::LIGHT;
 152.740 +
 152.741 +			if (version >= 4) { // handle LWSC 4 explicit ID
 152.742 +				d.number = strtoul16(c,&c) & AI_LWS_MASK;
 152.743 +			}
 152.744 +			else d.number = cur_light++;
 152.745 +			nodes.push_back(d);
 152.746 +
 152.747 +			num_light++;
 152.748 +		}
 152.749 +		// 'LightName': set name of currently active light
 152.750 +		else if ((*it).tokens[0] == "LightName") {
 152.751 +			if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
 152.752 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightName\'");
 152.753 +
 152.754 +			else nodes.back().name = c;
 152.755 +		}
 152.756 +		// 'LightIntensity': set intensity of currently active light
 152.757 +		else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity" ) {
 152.758 +			if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
 152.759 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightIntensity\'");
 152.760 +
 152.761 +			else fast_atoreal_move<float>(c, nodes.back().lightIntensity );
 152.762 +			
 152.763 +		}
 152.764 +		// 'LightType': set type of currently active light
 152.765 +		else if ((*it).tokens[0] == "LightType") {
 152.766 +			if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
 152.767 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightType\'");
 152.768 +
 152.769 +			else nodes.back().lightType = strtoul10(c);
 152.770 +			
 152.771 +		}
 152.772 +		// 'LightFalloffType': set falloff type of currently active light
 152.773 +		else if ((*it).tokens[0] == "LightFalloffType") {
 152.774 +			if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
 152.775 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightFalloffType\'");
 152.776 +
 152.777 +			else nodes.back().lightFalloffType = strtoul10(c);
 152.778 +			
 152.779 +		}
 152.780 +		// 'LightConeAngle': set cone angle of currently active light
 152.781 +		else if ((*it).tokens[0] == "LightConeAngle") {
 152.782 +			if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
 152.783 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightConeAngle\'");
 152.784 +
 152.785 +			else nodes.back().lightConeAngle = fast_atof(c);
 152.786 +			
 152.787 +		}
 152.788 +		// 'LightEdgeAngle': set area where we're smoothing from min to max intensity
 152.789 +		else if ((*it).tokens[0] == "LightEdgeAngle") {
 152.790 +			if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
 152.791 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightEdgeAngle\'");
 152.792 +
 152.793 +			else nodes.back().lightEdgeAngle = fast_atof(c);
 152.794 +			
 152.795 +		}
 152.796 +		// 'LightColor': set color of currently active light
 152.797 +		else if ((*it).tokens[0] == "LightColor") {
 152.798 +			if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
 152.799 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightColor\'");
 152.800 +
 152.801 +			else {
 152.802 +				c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.r );
 152.803 +				SkipSpaces(&c);
 152.804 +				c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.g );
 152.805 +				SkipSpaces(&c);
 152.806 +				c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.b );
 152.807 +			}
 152.808 +		}
 152.809 +
 152.810 +		// 'PivotPosition': position of local transformation origin
 152.811 +		else if ((*it).tokens[0] == "PivotPosition" || (*it).tokens[0] == "PivotPoint") {
 152.812 +			if (nodes.empty())
 152.813 +				DefaultLogger::get()->error("LWS: Unexpected keyword: \'PivotPosition\'");
 152.814 +			else {
 152.815 +				c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.x );
 152.816 +				SkipSpaces(&c);
 152.817 +				c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.y );
 152.818 +				SkipSpaces(&c);
 152.819 +				c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.z );
 152.820 +                // Mark pivotPos as set
 152.821 +                nodes.back().isPivotSet = true;
 152.822 +			}
 152.823 +		}
 152.824 +	}
 152.825 +
 152.826 +	// resolve parenting
 152.827 +	for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
 152.828 +	
 152.829 +		// check whether there is another node which calls us a parent
 152.830 +		for (std::list<LWS::NodeDesc>::iterator dit = nodes.begin(); dit != nodes.end(); ++dit) {
 152.831 +			if (dit != it && *it == (*dit).parent) {
 152.832 +				if ((*dit).parent_resolved) {
 152.833 +					// fixme: it's still possible to produce an overflow due to cross references ..
 152.834 +					DefaultLogger::get()->error("LWS: Found cross reference in scenegraph");
 152.835 +					continue;
 152.836 +				}
 152.837 +
 152.838 +				(*it).children.push_back(&*dit);
 152.839 +				(*dit).parent_resolved = &*it;
 152.840 +			}
 152.841 +		}
 152.842 +	}
 152.843 +
 152.844 +	// find out how many nodes have no parent yet
 152.845 +	unsigned int no_parent = 0;
 152.846 +	for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
 152.847 +		if (!(*it).parent_resolved)
 152.848 +			++ no_parent;
 152.849 +	}
 152.850 +	if (!no_parent)
 152.851 +		throw DeadlyImportError("LWS: Unable to find scene root node");
 152.852 +
 152.853 +
 152.854 +	// Load all subsequent files
 152.855 +	batch.LoadAll();
 152.856 +
 152.857 +	// and build the final output graph by attaching the loaded external
 152.858 +	// files to ourselves. first build a master graph 
 152.859 +	aiScene* master = new aiScene();
 152.860 +	aiNode* nd = master->mRootNode = new aiNode();
 152.861 +
 152.862 +	// allocate storage for cameras&lights
 152.863 +	if (num_camera) {
 152.864 +		master->mCameras = new aiCamera*[master->mNumCameras = num_camera];
 152.865 +	}
 152.866 +	aiCamera** cams = master->mCameras;
 152.867 +	if (num_light) {
 152.868 +		master->mLights = new aiLight*[master->mNumLights = num_light];
 152.869 +	}
 152.870 +	aiLight** lights = master->mLights;
 152.871 +
 152.872 +	std::vector<AttachmentInfo> attach;
 152.873 +	std::vector<aiNodeAnim*> anims;
 152.874 +
 152.875 +	nd->mName.Set("<LWSRoot>");
 152.876 +	nd->mChildren = new aiNode*[no_parent];
 152.877 +	for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
 152.878 +		if (!(*it).parent_resolved) {
 152.879 +			aiNode* ro = nd->mChildren[ nd->mNumChildren++ ] = new aiNode();
 152.880 +			ro->mParent = nd;
 152.881 +
 152.882 +			// ... and build the scene graph. If we encounter object nodes,
 152.883 +			// add then to our attachment table.
 152.884 +			BuildGraph(ro,*it, attach, batch, cams, lights, anims);
 152.885 +		}
 152.886 +	}
 152.887 +
 152.888 +	// create a master animation channel for us
 152.889 +	if (anims.size()) {
 152.890 +		master->mAnimations = new aiAnimation*[master->mNumAnimations = 1];
 152.891 +		aiAnimation* anim = master->mAnimations[0] = new aiAnimation();
 152.892 +		anim->mName.Set("LWSMasterAnim");
 152.893 +
 152.894 +		// LWS uses seconds as time units, but we convert to frames
 152.895 +		anim->mTicksPerSecond = fps;
 152.896 +		anim->mDuration = last-(first-1); /* fixme ... zero or one-based?*/
 152.897 +
 152.898 +		anim->mChannels = new aiNodeAnim*[anim->mNumChannels = anims.size()];
 152.899 +		std::copy(anims.begin(),anims.end(),anim->mChannels);
 152.900 +	}
 152.901 +
 152.902 +	// convert the master scene to RH
 152.903 +	MakeLeftHandedProcess monster_cheat;
 152.904 +	monster_cheat.Execute(master);
 152.905 +
 152.906 +	// .. ccw
 152.907 +	FlipWindingOrderProcess flipper;
 152.908 +	flipper.Execute(master);
 152.909 +
 152.910 +	// OK ... finally build the output graph
 152.911 +	SceneCombiner::MergeScenes(&pScene,master,attach,
 152.912 +		AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES    | (!configSpeedFlag ? (
 152.913 +		AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) : 0));
 152.914 +
 152.915 +	// Check flags
 152.916 +	if (!pScene->mNumMeshes || !pScene->mNumMaterials) {
 152.917 +		pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
 152.918 +
 152.919 +		if (pScene->mNumAnimations && !noSkeletonMesh) {
 152.920 +			// construct skeleton mesh
 152.921 +			SkeletonMeshBuilder builder(pScene);
 152.922 +		}
 152.923 +	}
 152.924 +
 152.925 +}
 152.926 +
 152.927 +#endif // !! ASSIMP_BUILD_NO_LWS_IMPORTER
   153.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   153.2 +++ b/libs/assimp/LWSLoader.h	Sat Feb 01 19:58:19 2014 +0200
   153.3 @@ -0,0 +1,242 @@
   153.4 +/*
   153.5 +Open Asset Import Library (assimp)
   153.6 +----------------------------------------------------------------------
   153.7 +
   153.8 +Copyright (c) 2006-2012, assimp team
   153.9 +All rights reserved.
  153.10 +
  153.11 +Redistribution and use of this software in source and binary forms, 
  153.12 +with or without modification, are permitted provided that the 
  153.13 +following conditions are met:
  153.14 +
  153.15 +* Redistributions of source code must retain the above
  153.16 +  copyright notice, this list of conditions and the
  153.17 +  following disclaimer.
  153.18 +
  153.19 +* Redistributions in binary form must reproduce the above
  153.20 +  copyright notice, this list of conditions and the
  153.21 +  following disclaimer in the documentation and/or other
  153.22 +  materials provided with the distribution.
  153.23 +
  153.24 +* Neither the name of the assimp team, nor the names of its
  153.25 +  contributors may be used to endorse or promote products
  153.26 +  derived from this software without specific prior
  153.27 +  written permission of the assimp team.
  153.28 +
  153.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  153.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  153.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  153.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  153.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  153.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  153.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  153.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  153.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  153.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  153.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  153.40 +
  153.41 +----------------------------------------------------------------------
  153.42 +*/
  153.43 +
  153.44 +/** @file  LWSLoader.h
  153.45 + *  @brief Declaration of the LightWave scene importer class. 
  153.46 + */
  153.47 +#ifndef AI_LWSLOADER_H_INCLUDED
  153.48 +#define AI_LWSLOADER_H_INCLUDED
  153.49 +
  153.50 +#include "LWOFileData.h"
  153.51 +#include "SceneCombiner.h"
  153.52 +
  153.53 +namespace Assimp	{
  153.54 +	namespace LWS	{
  153.55 +
  153.56 +// ---------------------------------------------------------------------------
  153.57 +/** Represents an element in a LWS file.
  153.58 + *
  153.59 + *  This can either be a single data line - <name> <value> or a data
  153.60 + *  group - { name <data_line0> ... n }
  153.61 + */
  153.62 +class Element
  153.63 +{
  153.64 +public:
  153.65 +	Element()
  153.66 +	{}
  153.67 +
  153.68 +	// first: name, second: rest
  153.69 +	std::string tokens[2];
  153.70 +	std::list<Element> children;
  153.71 +
  153.72 +	//! Recursive parsing function
  153.73 +	void Parse (const char*& buffer);
  153.74 +};
  153.75 +
  153.76 +#define AI_LWS_MASK (0xffffffff >> 4u)
  153.77 +
  153.78 +// ---------------------------------------------------------------------------
  153.79 +/** Represents a LWS scenegraph element
  153.80 + */
  153.81 +struct NodeDesc
  153.82 +{
  153.83 +	NodeDesc()
  153.84 +		:	number	(0)
  153.85 +		,	parent	(0)
  153.86 +		,	name	("")
  153.87 +		,	isPivotSet (false)
  153.88 +		,	lightColor (1.f,1.f,1.f)
  153.89 +		,	lightIntensity (1.f)
  153.90 +		,	lightType (0)
  153.91 +		,	lightFalloffType (0)
  153.92 +		,	lightConeAngle (45.f)
  153.93 +		,	parent_resolved (NULL)
  153.94 +	{}
  153.95 +
  153.96 +	enum {
  153.97 +	
  153.98 +		OBJECT = 1,
  153.99 +		LIGHT  = 2,
 153.100 +		CAMERA = 3,
 153.101 +		BONE   = 4
 153.102 +	} type; // type of node
 153.103 +
 153.104 +	// if object: path
 153.105 +	std::string path;
 153.106 +	unsigned int id;
 153.107 +
 153.108 +	// number of object
 153.109 +	unsigned int number;
 153.110 +
 153.111 +	// index of parent index
 153.112 +	unsigned int parent;
 153.113 +
 153.114 +	// lights & cameras & dummies: name
 153.115 +	const char* name;
 153.116 +
 153.117 +	// animation channels
 153.118 +	std::list< LWO::Envelope > channels;
 153.119 +
 153.120 +	// position of pivot point
 153.121 +	aiVector3D pivotPos;
 153.122 +	bool isPivotSet;
 153.123 +
 153.124 +
 153.125 +
 153.126 +	// color of light source
 153.127 +	aiColor3D lightColor;
 153.128 +
 153.129 +	// intensity of light source
 153.130 +	float lightIntensity;
 153.131 +
 153.132 +	// type of light source
 153.133 +	unsigned int lightType;
 153.134 +
 153.135 +	// falloff type of light source
 153.136 +	unsigned int lightFalloffType;
 153.137 +
 153.138 +	// cone angle of (spot) light source
 153.139 +	float lightConeAngle;
 153.140 +
 153.141 +	// soft cone angle of (spot) light source
 153.142 +	float lightEdgeAngle;
 153.143 +
 153.144 +
 153.145 +
 153.146 +	// list of resolved children
 153.147 +	std::list< NodeDesc* > children;
 153.148 +
 153.149 +	// resolved parent node
 153.150 +	NodeDesc* parent_resolved;
 153.151 +
 153.152 +
 153.153 +	// for std::find()
 153.154 +	bool operator == (unsigned int num)  const {
 153.155 +		if (!num)
 153.156 +			return false;
 153.157 +		unsigned int _type = num >> 28u;
 153.158 +		
 153.159 +		return _type == static_cast<unsigned int>(type) && (num & AI_LWS_MASK) == number;
 153.160 +	}
 153.161 +};
 153.162 +
 153.163 +} // end namespace LWS
 153.164 +
 153.165 +// ---------------------------------------------------------------------------
 153.166 +/** LWS (LightWave Scene Format) importer class.
 153.167 + *
 153.168 + *  This class does heavily depend on the LWO importer class. LWS files
 153.169 + *  contain mainly descriptions how LWO objects are composed together
 153.170 + *  in a scene. 
 153.171 +*/
 153.172 +class LWSImporter : public BaseImporter
 153.173 +{
 153.174 +public:
 153.175 +	LWSImporter();
 153.176 +	~LWSImporter();
 153.177 +
 153.178 +
 153.179 +public:
 153.180 +
 153.181 +	// -------------------------------------------------------------------
 153.182 +	// Check whether we can read a specific file
 153.183 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
 153.184 +		bool checkSig) const;
 153.185 +
 153.186 +protected:
 153.187 +
 153.188 +	// -------------------------------------------------------------------
 153.189 +	// Get list of supported extensions
 153.190 +	const aiImporterDesc* GetInfo () const;
 153.191 +
 153.192 +	// -------------------------------------------------------------------
 153.193 +	// Import file into given scene data structure
 153.194 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
 153.195 +		IOSystem* pIOHandler);
 153.196 +
 153.197 +	// -------------------------------------------------------------------
 153.198 +	// Setup import properties
 153.199 +	void SetupProperties(const Importer* pImp);
 153.200 +
 153.201 +private:
 153.202 +
 153.203 +
 153.204 +	// -------------------------------------------------------------------
 153.205 +	// Read an envelope description
 153.206 +	void ReadEnvelope(const LWS::Element& dad, LWO::Envelope& out );
 153.207 +
 153.208 +	// -------------------------------------------------------------------
 153.209 +	// Read an envelope description for the older LW file format
 153.210 +	void ReadEnvelope_Old(std::list< LWS::Element >::const_iterator& it, 
 153.211 +		const std::list< LWS::Element >::const_iterator& end,
 153.212 +		LWS::NodeDesc& nodes,
 153.213 +		unsigned int version);
 153.214 +
 153.215 +	// -------------------------------------------------------------------
 153.216 +	// Setup a nice name for a node 
 153.217 +	void SetupNodeName(aiNode* nd, LWS::NodeDesc& src);
 153.218 +
 153.219 +	// -------------------------------------------------------------------
 153.220 +	// Recursively build the scenegraph
 153.221 +	void BuildGraph(aiNode* nd, 
 153.222 +		LWS::NodeDesc& src, 
 153.223 +		std::vector<AttachmentInfo>& attach,
 153.224 +		BatchLoader& batch,
 153.225 +		aiCamera**& camOut,
 153.226 +		aiLight**& lightOut, 
 153.227 +		std::vector<aiNodeAnim*>& animOut);
 153.228 +
 153.229 +	// -------------------------------------------------------------------
 153.230 +	// Try several dirs until we find the right location of a LWS file.
 153.231 +	std::string FindLWOFile(const std::string& in);
 153.232 +
 153.233 +private:
 153.234 +
 153.235 +	bool configSpeedFlag;
 153.236 +	IOSystem* io;
 153.237 +
 153.238 +	double first,last,fps;
 153.239 +
 153.240 +	bool noSkeletonMesh; 
 153.241 +};
 153.242 +
 153.243 +} // end of namespace Assimp
 153.244 +
 153.245 +#endif // AI_LWSIMPORTER_H_INC
   154.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   154.2 +++ b/libs/assimp/LimitBoneWeightsProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
   154.3 @@ -0,0 +1,204 @@
   154.4 +/*
   154.5 +Open Asset Import Library (assimp)
   154.6 +----------------------------------------------------------------------
   154.7 +
   154.8 +Copyright (c) 2006-2012, assimp team
   154.9 +All rights reserved.
  154.10 +
  154.11 +Redistribution and use of this software in source and binary forms, 
  154.12 +with or without modification, are permitted provided that the 
  154.13 +following conditions are met:
  154.14 +
  154.15 +* Redistributions of source code must retain the above
  154.16 +  copyright notice, this list of conditions and the
  154.17 +  following disclaimer.
  154.18 +
  154.19 +* Redistributions in binary form must reproduce the above
  154.20 +  copyright notice, this list of conditions and the
  154.21 +  following disclaimer in the documentation and/or other
  154.22 +  materials provided with the distribution.
  154.23 +
  154.24 +* Neither the name of the assimp team, nor the names of its
  154.25 +  contributors may be used to endorse or promote products
  154.26 +  derived from this software without specific prior
  154.27 +  written permission of the assimp team.
  154.28 +
  154.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  154.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  154.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  154.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  154.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  154.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  154.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  154.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  154.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  154.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  154.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  154.40 +
  154.41 +----------------------------------------------------------------------
  154.42 +*/
  154.43 +
  154.44 +/** Implementation of the LimitBoneWeightsProcess post processing step */
  154.45 +
  154.46 +#include "AssimpPCH.h"
  154.47 +#include "LimitBoneWeightsProcess.h"
  154.48 +
  154.49 +
  154.50 +using namespace Assimp;
  154.51 +
  154.52 +
  154.53 +// ------------------------------------------------------------------------------------------------
  154.54 +// Constructor to be privately used by Importer
  154.55 +LimitBoneWeightsProcess::LimitBoneWeightsProcess()
  154.56 +{
  154.57 +	mMaxWeights = AI_LMW_MAX_WEIGHTS;
  154.58 +}
  154.59 +
  154.60 +// ------------------------------------------------------------------------------------------------
  154.61 +// Destructor, private as well
  154.62 +LimitBoneWeightsProcess::~LimitBoneWeightsProcess()
  154.63 +{
  154.64 +	// nothing to do here
  154.65 +}
  154.66 +
  154.67 +// ------------------------------------------------------------------------------------------------
  154.68 +// Returns whether the processing step is present in the given flag field.
  154.69 +bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const
  154.70 +{
  154.71 +	return (pFlags & aiProcess_LimitBoneWeights) != 0;
  154.72 +}
  154.73 +
  154.74 +// ------------------------------------------------------------------------------------------------
  154.75 +// Executes the post processing step on the given imported data.
  154.76 +void LimitBoneWeightsProcess::Execute( aiScene* pScene)
  154.77 +{
  154.78 +	DefaultLogger::get()->debug("LimitBoneWeightsProcess begin");
  154.79 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
  154.80 +		ProcessMesh( pScene->mMeshes[a]);
  154.81 +
  154.82 +	DefaultLogger::get()->debug("LimitBoneWeightsProcess end");
  154.83 +}
  154.84 +
  154.85 +// ------------------------------------------------------------------------------------------------
  154.86 +// Executes the post processing step on the given imported data.
  154.87 +void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp)
  154.88 +{
  154.89 +	// get the current value of the property
  154.90 +	this->mMaxWeights = pImp->GetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS,AI_LMW_MAX_WEIGHTS);
  154.91 +}
  154.92 +
  154.93 +// ------------------------------------------------------------------------------------------------
  154.94 +// Unites identical vertices in the given mesh
  154.95 +void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
  154.96 +{
  154.97 +	if( !pMesh->HasBones())
  154.98 +		return;
  154.99 +
 154.100 +	// collect all bone weights per vertex
 154.101 +	typedef std::vector< std::vector< Weight > > WeightsPerVertex;
 154.102 +	WeightsPerVertex vertexWeights( pMesh->mNumVertices);
 154.103 +
 154.104 +	// collect all weights per vertex
 154.105 +	for( unsigned int a = 0; a < pMesh->mNumBones; a++)
 154.106 +	{
 154.107 +		const aiBone* bone = pMesh->mBones[a];
 154.108 +		for( unsigned int b = 0; b < bone->mNumWeights; b++)
 154.109 +		{
 154.110 +			const aiVertexWeight& w = bone->mWeights[b];
 154.111 +			vertexWeights[w.mVertexId].push_back( Weight( a, w.mWeight));
 154.112 +		}
 154.113 +	}
 154.114 +
 154.115 +	unsigned int removed = 0, old_bones = pMesh->mNumBones;
 154.116 +
 154.117 +	// now cut the weight count if it exceeds the maximum
 154.118 +	bool bChanged = false;
 154.119 +	for( WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit)
 154.120 +	{
 154.121 +		if( vit->size() <= mMaxWeights)
 154.122 +			continue;
 154.123 +
 154.124 +		bChanged = true;
 154.125 +
 154.126 +		// more than the defined maximum -> first sort by weight in descending order. That's 
 154.127 +		// why we defined the < operator in such a weird way.
 154.128 +		std::sort( vit->begin(), vit->end());
 154.129 +
 154.130 +		// now kill everything beyond the maximum count
 154.131 +		unsigned int m = vit->size();
 154.132 +		vit->erase( vit->begin() + mMaxWeights, vit->end());
 154.133 +		removed += m-vit->size();
 154.134 +
 154.135 +		// and renormalize the weights
 154.136 +		float sum = 0.0f;
 154.137 +		for( std::vector<Weight>::const_iterator it = vit->begin(); it != vit->end(); ++it)
 154.138 +			sum += it->mWeight;
 154.139 +		for( std::vector<Weight>::iterator it = vit->begin(); it != vit->end(); ++it)
 154.140 +			it->mWeight /= sum;
 154.141 +	}
 154.142 +
 154.143 +	if (bChanged)	{
 154.144 +		// rebuild the vertex weight array for all bones 
 154.145 +		typedef std::vector< std::vector< aiVertexWeight > > WeightsPerBone;
 154.146 +		WeightsPerBone boneWeights( pMesh->mNumBones);
 154.147 +		for( unsigned int a = 0; a < vertexWeights.size(); a++)
 154.148 +		{
 154.149 +			const std::vector<Weight>& vw = vertexWeights[a];
 154.150 +			for( std::vector<Weight>::const_iterator it = vw.begin(); it != vw.end(); ++it)
 154.151 +				boneWeights[it->mBone].push_back( aiVertexWeight( a, it->mWeight));
 154.152 +		}
 154.153 +
 154.154 +		// and finally copy the vertex weight list over to the mesh's bones
 154.155 +		std::vector<bool> abNoNeed(pMesh->mNumBones,false);
 154.156 +		bChanged = false;
 154.157 +
 154.158 +		for( unsigned int a = 0; a < pMesh->mNumBones; a++)
 154.159 +		{
 154.160 +			const std::vector<aiVertexWeight>& bw = boneWeights[a];
 154.161 +			aiBone* bone = pMesh->mBones[a];
 154.162 +
 154.163 +			// ignore the bone if no vertex weights were removed there
 154.164 +
 154.165 +			// FIX (Aramis, 07|22|08)
 154.166 +			// NO! we can't ignore it in this case ... it is possible that
 154.167 +			// the number of weights did not change, but the weight values did.
 154.168 +
 154.169 +			// if( bw.size() == bone->mNumWeights)
 154.170 +			//	continue;
 154.171 +
 154.172 +			// FIX (Aramis, 07|21|08)
 154.173 +			// It is possible that all weights of a bone have been removed.
 154.174 +			// This would naturally cause an exception in &bw[0].
 154.175 +			if ( bw.empty() )
 154.176 +			{
 154.177 +				abNoNeed[a] = bChanged = true;
 154.178 +				continue;
 154.179 +			}
 154.180 +
 154.181 +			// copy the weight list. should always be less weights than before, so we don't need a new allocation
 154.182 +			ai_assert( bw.size() <= bone->mNumWeights);
 154.183 +			bone->mNumWeights = (unsigned int) bw.size();
 154.184 +			::memcpy( bone->mWeights, &bw[0], bw.size() * sizeof( aiVertexWeight));
 154.185 +		}
 154.186 +
 154.187 +		if (bChanged)	{
 154.188 +			// the number of new bones is smaller than before, so we can reuse the old array
 154.189 +			aiBone** ppcCur = pMesh->mBones;aiBone** ppcSrc = ppcCur;
 154.190 +
 154.191 +			for (std::vector<bool>::const_iterator iter  = abNoNeed.begin();iter != abNoNeed.end()  ;++iter)	{
 154.192 +				if (*iter)	{
 154.193 +					delete *ppcSrc;
 154.194 +					--pMesh->mNumBones;
 154.195 +				}
 154.196 +				else *ppcCur++ = *ppcSrc;
 154.197 +				++ppcSrc;
 154.198 +			}
 154.199 +		}
 154.200 +
 154.201 +		if (!DefaultLogger::isNullLogger()) {
 154.202 +			char buffer[1024];
 154.203 +			::sprintf(buffer,"Removed %i weights. Input bones: %i. Output bones: %i",removed,old_bones,pMesh->mNumBones);
 154.204 +			DefaultLogger::get()->info(buffer);
 154.205 +		}
 154.206 +	}
 154.207 +}
   155.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   155.2 +++ b/libs/assimp/LimitBoneWeightsProcess.h	Sat Feb 01 19:58:19 2014 +0200
   155.3 @@ -0,0 +1,141 @@
   155.4 +/*
   155.5 +Open Asset Import Library (assimp)
   155.6 +----------------------------------------------------------------------
   155.7 +
   155.8 +Copyright (c) 2006-2012, assimp team
   155.9 +All rights reserved.
  155.10 +
  155.11 +Redistribution and use of this software in source and binary forms, 
  155.12 +with or without modification, are permitted provided that the 
  155.13 +following conditions are met:
  155.14 +
  155.15 +* Redistributions of source code must retain the above
  155.16 +  copyright notice, this list of conditions and the
  155.17 +  following disclaimer.
  155.18 +
  155.19 +* Redistributions in binary form must reproduce the above
  155.20 +  copyright notice, this list of conditions and the
  155.21 +  following disclaimer in the documentation and/or other
  155.22 +  materials provided with the distribution.
  155.23 +
  155.24 +* Neither the name of the assimp team, nor the names of its
  155.25 +  contributors may be used to endorse or promote products
  155.26 +  derived from this software without specific prior
  155.27 +  written permission of the assimp team.
  155.28 +
  155.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  155.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  155.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  155.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  155.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  155.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  155.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  155.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  155.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  155.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  155.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  155.40 +
  155.41 +----------------------------------------------------------------------
  155.42 +*/
  155.43 +
  155.44 +/** Defines a post processing step to limit the number of bones affecting a single vertex. */
  155.45 +#ifndef AI_LIMITBONEWEIGHTSPROCESS_H_INC
  155.46 +#define AI_LIMITBONEWEIGHTSPROCESS_H_INC
  155.47 +
  155.48 +#include "BaseProcess.h"
  155.49 +
  155.50 +struct aiMesh;
  155.51 +class LimitBoneWeightsTest;
  155.52 +
  155.53 +namespace Assimp
  155.54 +{
  155.55 +
  155.56 +// NOTE: If you change these limits, don't forget to change the
  155.57 +// corresponding values in all Assimp ports
  155.58 +
  155.59 +// **********************************************************
  155.60 +// Java: ConfigProperty.java, 
  155.61 +//  ConfigProperty.DEFAULT_BONE_WEIGHT_LIMIT
  155.62 +// **********************************************************
  155.63 +
  155.64 +#if (!defined AI_LMW_MAX_WEIGHTS)
  155.65 +#	define AI_LMW_MAX_WEIGHTS	0x4
  155.66 +#endif // !! AI_LMW_MAX_WEIGHTS
  155.67 +
  155.68 +// ---------------------------------------------------------------------------
  155.69 +/** This post processing step limits the number of bones affecting a vertex
  155.70 +* to a certain maximum value. If a vertex is affected by more than that number
  155.71 +* of bones, the bone weight with the least influence on this vertex are removed.
  155.72 +* The other weights on this bone are then renormalized to assure the sum weight
  155.73 +* to be 1.
  155.74 +*/
  155.75 +class LimitBoneWeightsProcess : public BaseProcess
  155.76 +{
  155.77 +public:
  155.78 +
  155.79 +	LimitBoneWeightsProcess();
  155.80 +	~LimitBoneWeightsProcess();
  155.81 +
  155.82 +public:
  155.83 +	// -------------------------------------------------------------------
  155.84 +	/** Returns whether the processing step is present in the given flag.
  155.85 +	* @param pFlags The processing flags the importer was called with. 
  155.86 +	*   A bitwise combination of #aiPostProcessSteps.
  155.87 +	* @return true if the process is present in this flag fields, 
  155.88 +	*   false if not.
  155.89 +	*/
  155.90 +	bool IsActive( unsigned int pFlags) const;
  155.91 +
  155.92 +	// -------------------------------------------------------------------
  155.93 +	/** Called prior to ExecuteOnScene().
  155.94 +	* The function is a request to the process to update its configuration
  155.95 +	* basing on the Importer's configuration property list.
  155.96 +	*/
  155.97 +	void SetupProperties(const Importer* pImp);
  155.98 +
  155.99 +public:
 155.100 +
 155.101 +	// -------------------------------------------------------------------
 155.102 +	/** Limits the bone weight count for all vertices in the given mesh.
 155.103 +	* @param pMesh The mesh to process.
 155.104 +	*/
 155.105 +	void ProcessMesh( aiMesh* pMesh);
 155.106 +
 155.107 +	// -------------------------------------------------------------------
 155.108 +	/** Executes the post processing step on the given imported data.
 155.109 +	* At the moment a process is not supposed to fail.
 155.110 +	* @param pScene The imported data to work at.
 155.111 +	*/
 155.112 +	void Execute( aiScene* pScene);
 155.113 +
 155.114 +
 155.115 +public:
 155.116 +
 155.117 +	// -------------------------------------------------------------------
 155.118 +	/** Describes a bone weight on a vertex */
 155.119 +	struct Weight
 155.120 +	{
 155.121 +		unsigned int mBone; ///< Index of the bone
 155.122 +		float mWeight;      ///< Weight of that bone on this vertex
 155.123 +		Weight() { }
 155.124 +		Weight( unsigned int pBone, float pWeight) 
 155.125 +		{
 155.126 +			mBone = pBone; 
 155.127 +			mWeight = pWeight; 
 155.128 +		}
 155.129 +
 155.130 +		/** Comparision operator to sort bone weights by descending weight */
 155.131 +		bool operator < (const Weight& pWeight) const
 155.132 +		{ 
 155.133 +			return mWeight > pWeight.mWeight;
 155.134 +		}
 155.135 +	};
 155.136 +
 155.137 +public:
 155.138 +	/** Maximum number of bones influencing any single vertex. */
 155.139 +	unsigned int mMaxWeights;
 155.140 +};
 155.141 +
 155.142 +} // end of namespace Assimp
 155.143 +
 155.144 +#endif // AI_LIMITBONEWEIGHTSPROCESS_H_INC
   156.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   156.2 +++ b/libs/assimp/LineSplitter.h	Sat Feb 01 19:58:19 2014 +0200
   156.3 @@ -0,0 +1,242 @@
   156.4 +/*
   156.5 +Open Asset Import Library (assimp)
   156.6 +----------------------------------------------------------------------
   156.7 +
   156.8 +Copyright (c) 2006-2012, assimp team
   156.9 +All rights reserved.
  156.10 +
  156.11 +Redistribution and use of this software in source and binary forms, 
  156.12 +with or without modification, are permitted provided that the 
  156.13 +following conditions are met:
  156.14 +
  156.15 +* Redistributions of source code must retain the above
  156.16 +  copyright notice, this list of conditions and the
  156.17 +  following disclaimer.
  156.18 +
  156.19 +* Redistributions in binary form must reproduce the above
  156.20 +  copyright notice, this list of conditions and the
  156.21 +  following disclaimer in the documentation and/or other
  156.22 +  materials provided with the distribution.
  156.23 +
  156.24 +* Neither the name of the assimp team, nor the names of its
  156.25 +  contributors may be used to endorse or promote products
  156.26 +  derived from this software without specific prior
  156.27 +  written permission of the assimp team.
  156.28 +
  156.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  156.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  156.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  156.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  156.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  156.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  156.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  156.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  156.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  156.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  156.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  156.40 +
  156.41 +----------------------------------------------------------------------
  156.42 +*/
  156.43 +
  156.44 +/** @file  LineSplitter.h
  156.45 + *  @brief LineSplitter, a helper class to iterate through all lines
  156.46 + *    of a file easily. Works with StreamReader.
  156.47 + */
  156.48 +#ifndef INCLUDED_LINE_SPLITTER_H
  156.49 +#define INCLUDED_LINE_SPLITTER_H
  156.50 +
  156.51 +#include <stdexcept>
  156.52 +
  156.53 +#include "StreamReader.h"
  156.54 +#include "ParsingUtils.h"
  156.55 +
  156.56 +namespace Assimp {
  156.57 +
  156.58 +// ------------------------------------------------------------------------------------------------
  156.59 +/** Usage:
  156.60 +@code
  156.61 +for(LineSplitter splitter(stream);splitter;++splitter) {
  156.62 +
  156.63 +	if (*splitter == "hi!") {
  156.64 +	   ...
  156.65 +	}
  156.66 +    else if (splitter->substr(0,5) == "hello") {
  156.67 +	   ...
  156.68 +	   // access the third token in the line (tokens are space-separated)
  156.69 +	   if (strtol(splitter[2]) > 5) { .. }
  156.70 +	}
  156.71 +
  156.72 +	std::cout << "Current line is: " << splitter.get_index() << std::endl;
  156.73 +}
  156.74 +@endcode */
  156.75 +// ------------------------------------------------------------------------------------------------
  156.76 +class LineSplitter
  156.77 +{
  156.78 +public:
  156.79 +
  156.80 +	typedef size_t line_idx;
  156.81 +
  156.82 +public:
  156.83 +
  156.84 +	// -----------------------------------------
  156.85 +	/** construct from existing stream reader 
  156.86 +	note: trim is *always* assumed true if skyp_empty_lines==true
  156.87 +	*/
  156.88 +	LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true)
  156.89 +		: stream(stream)
  156.90 +		, swallow()
  156.91 +		, skip_empty_lines(skip_empty_lines)
  156.92 +		, trim(trim)
  156.93 +	{
  156.94 +		cur.reserve(1024);
  156.95 +		operator++();
  156.96 +
  156.97 +		idx = 0;
  156.98 +	}
  156.99 +
 156.100 +public:
 156.101 +
 156.102 +	// -----------------------------------------
 156.103 +	/** pseudo-iterator increment */
 156.104 +	LineSplitter& operator++() {
 156.105 +		if(swallow) {
 156.106 +			swallow = false;
 156.107 +			return *this;
 156.108 +		}
 156.109 +		
 156.110 +		if (!*this) {
 156.111 +			throw std::logic_error("End of file, no more lines to be retrieved.");
 156.112 +		}
 156.113 +
 156.114 +		char s;
 156.115 +
 156.116 +		cur.clear();
 156.117 +		while(stream.GetRemainingSize() && (s = stream.GetI1(),1)) {
 156.118 +			if (s == '\n' || s == '\r') {
 156.119 +				if (skip_empty_lines) {
 156.120 +					while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\r' || s == '\n'));
 156.121 +					if (stream.GetRemainingSize()) {
 156.122 +						stream.IncPtr(-1);
 156.123 +					}
 156.124 +				}
 156.125 +				else {
 156.126 +					// skip both potential line terminators but don't read past this line.
 156.127 +					if (stream.GetRemainingSize() && (s == '\r' && stream.GetI1() != '\n')) {
 156.128 +						stream.IncPtr(-1);
 156.129 +					}
 156.130 +
 156.131 +					if (trim) {
 156.132 +						while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\t'));
 156.133 +						if (stream.GetRemainingSize()) {
 156.134 +							stream.IncPtr(-1);
 156.135 +						}
 156.136 +					}
 156.137 +				}
 156.138 +				
 156.139 +				break;
 156.140 +			}
 156.141 +			cur += s;
 156.142 +		}
 156.143 +
 156.144 +		++idx;
 156.145 +		return *this;
 156.146 +	}
 156.147 +
 156.148 +	// -----------------------------------------
 156.149 +	LineSplitter& operator++(int) {
 156.150 +		return ++(*this);
 156.151 +	}
 156.152 +
 156.153 +	// -----------------------------------------
 156.154 +	/** get a pointer to the beginning of a particular token */
 156.155 +	const char* operator[] (size_t idx) const {
 156.156 +		const char* s = operator->()->c_str();
 156.157 +
 156.158 +		SkipSpaces(&s);
 156.159 +		for(size_t i = 0; i < idx; ++i) {
 156.160 +
 156.161 +			for(;!IsSpace(*s); ++s) {
 156.162 +				if(IsLineEnd(*s)) {
 156.163 +					throw std::range_error("Token index out of range, EOL reached");
 156.164 +				}
 156.165 +			}
 156.166 +			SkipSpaces(&s);
 156.167 +		}
 156.168 +		return s;
 156.169 +	}
 156.170 +
 156.171 +	// -----------------------------------------
 156.172 +	/** extract the start positions of N tokens from the current line*/
 156.173 +	template <size_t N>
 156.174 +	void get_tokens(const char* (&tokens)[N]) const {
 156.175 +		const char* s = operator->()->c_str();
 156.176 +
 156.177 +		SkipSpaces(&s);
 156.178 +		for(size_t i = 0; i < N; ++i) {
 156.179 +			if(IsLineEnd(*s)) {
 156.180 +				throw std::range_error("Token count out of range, EOL reached");
 156.181 +			}
 156.182 +			tokens[i] = s;
 156.183 +
 156.184 +			for(;*s && !IsSpace(*s); ++s);
 156.185 +			SkipSpaces(&s);
 156.186 +		}
 156.187 +	}
 156.188 +
 156.189 +	// -----------------------------------------
 156.190 +	/** member access */
 156.191 +	const std::string* operator -> () const {
 156.192 +		return &cur;
 156.193 +	}
 156.194 +
 156.195 +	std::string operator* () const {
 156.196 +		return cur;
 156.197 +	}
 156.198 +
 156.199 +	// -----------------------------------------
 156.200 +	/** boolean context */
 156.201 +	operator bool() const {
 156.202 +		return stream.GetRemainingSize()>0;
 156.203 +	}
 156.204 +
 156.205 +	// -----------------------------------------
 156.206 +	/** line indices are zero-based, empty lines are included */
 156.207 +	operator line_idx() const {
 156.208 +		return idx;
 156.209 +	}
 156.210 +
 156.211 +	line_idx get_index() const {
 156.212 +		return idx;
 156.213 +	}
 156.214 +
 156.215 +	// -----------------------------------------
 156.216 +	/** access the underlying stream object */
 156.217 +	StreamReaderLE& get_stream() {
 156.218 +		return stream;
 156.219 +	}
 156.220 +
 156.221 +	// -----------------------------------------
 156.222 +	/** !strcmp((*this)->substr(0,strlen(check)),check) */
 156.223 +	bool match_start(const char* check) {
 156.224 +		const size_t len = strlen(check);
 156.225 +		
 156.226 +		return len <= cur.length() && std::equal(check,check+len,cur.begin());
 156.227 +	}
 156.228 +
 156.229 +
 156.230 +	// -----------------------------------------
 156.231 +	/** swallow the next call to ++, return the previous value. */
 156.232 +	void swallow_next_increment() {
 156.233 +		swallow = true;
 156.234 +	}
 156.235 +
 156.236 +private:
 156.237 +
 156.238 +	line_idx idx;
 156.239 +	std::string cur;
 156.240 +	StreamReaderLE& stream;
 156.241 +	bool swallow, skip_empty_lines, trim;
 156.242 +};
 156.243 +
 156.244 +}
 156.245 +#endif // INCLUDED_LINE_SPLITTER_H
   157.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   157.2 +++ b/libs/assimp/LogAux.h	Sat Feb 01 19:58:19 2014 +0200
   157.3 @@ -0,0 +1,131 @@
   157.4 +/*
   157.5 +Open Asset Import Library (assimp)
   157.6 +----------------------------------------------------------------------
   157.7 +
   157.8 +Copyright (c) 2006-2012, assimp team
   157.9 +All rights reserved.
  157.10 +
  157.11 +Redistribution and use of this software in source and binary forms, 
  157.12 +with or without modification, are permitted provided that the 
  157.13 +following conditions are met:
  157.14 +
  157.15 +* Redistributions of source code must retain the above
  157.16 +  copyright notice, this list of conditions and the
  157.17 +  following disclaimer.
  157.18 +
  157.19 +* Redistributions in binary form must reproduce the above
  157.20 +  copyright notice, this list of conditions and the
  157.21 +  following disclaimer in the documentation and/or other
  157.22 +  materials provided with the distribution.
  157.23 +
  157.24 +* Neither the name of the assimp team, nor the names of its
  157.25 +  contributors may be used to endorse or promote products
  157.26 +  derived from this software without specific prior
  157.27 +  written permission of the assimp team.
  157.28 +
  157.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  157.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  157.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  157.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  157.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  157.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  157.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  157.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  157.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  157.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  157.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  157.40 +
  157.41 +----------------------------------------------------------------------
  157.42 +*/
  157.43 +
  157.44 +/** @file  LogAux.h
  157.45 + *  @brief Common logging usage patterns for importer implementations
  157.46 + */
  157.47 +#ifndef INCLUDED_AI_LOGAUX_H
  157.48 +#define INCLUDED_AI_LOGAUX_H
  157.49 +
  157.50 +#include "TinyFormatter.h"
  157.51 +
  157.52 +namespace Assimp {
  157.53 +
  157.54 +template <class TDeriving>
  157.55 +class LogFunctions 
  157.56 +{
  157.57 +
  157.58 +public:
  157.59 +
  157.60 +	// ------------------------------------------------------------------------------------------------
  157.61 +	static void ThrowException(const std::string& msg)
  157.62 +	{
  157.63 +		throw DeadlyImportError(log_prefix+msg);
  157.64 +	}
  157.65 +
  157.66 +	// ------------------------------------------------------------------------------------------------
  157.67 +	static void LogWarn(const Formatter::format& message)	{
  157.68 +		if (!DefaultLogger::isNullLogger()) {
  157.69 +			DefaultLogger::get()->warn(log_prefix+(std::string)message);
  157.70 +		}
  157.71 +	}
  157.72 +
  157.73 +	// ------------------------------------------------------------------------------------------------
  157.74 +	static void LogError(const Formatter::format& message)	{
  157.75 +		if (!DefaultLogger::isNullLogger()) {
  157.76 +			DefaultLogger::get()->error(log_prefix+(std::string)message);
  157.77 +		}
  157.78 +	}
  157.79 +
  157.80 +	// ------------------------------------------------------------------------------------------------
  157.81 +	static void LogInfo(const Formatter::format& message)	{
  157.82 +		if (!DefaultLogger::isNullLogger()) {
  157.83 +			DefaultLogger::get()->info(log_prefix+(std::string)message);
  157.84 +		}
  157.85 +	}
  157.86 +
  157.87 +	// ------------------------------------------------------------------------------------------------
  157.88 +	static void LogDebug(const Formatter::format& message)	{
  157.89 +		if (!DefaultLogger::isNullLogger()) {
  157.90 +			DefaultLogger::get()->debug(log_prefix+(std::string)message);
  157.91 +		}
  157.92 +	}
  157.93 +
  157.94 +	// https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462
  157.95 +#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
  157.96 +
  157.97 +	// ------------------------------------------------------------------------------------------------
  157.98 +	static void LogWarn  (const char* message) {
  157.99 +		if (!DefaultLogger::isNullLogger()) {
 157.100 +			LogWarn(Formatter::format(message));
 157.101 +		}
 157.102 +	}
 157.103 +
 157.104 +	// ------------------------------------------------------------------------------------------------
 157.105 +	static void LogError  (const char* message) {
 157.106 +		if (!DefaultLogger::isNullLogger()) {
 157.107 +			LogError(Formatter::format(message));
 157.108 +		}
 157.109 +	}
 157.110 +
 157.111 +	// ------------------------------------------------------------------------------------------------
 157.112 +	static void LogInfo  (const char* message) {
 157.113 +		if (!DefaultLogger::isNullLogger()) {
 157.114 +			LogInfo(Formatter::format(message));
 157.115 +		}
 157.116 +	}
 157.117 +
 157.118 +	// ------------------------------------------------------------------------------------------------
 157.119 +	static void LogDebug  (const char* message) {
 157.120 +		if (!DefaultLogger::isNullLogger()) {
 157.121 +			LogDebug(Formatter::format(message));
 157.122 +		}
 157.123 +	}
 157.124 +
 157.125 +#endif
 157.126 +
 157.127 +private:
 157.128 +
 157.129 +	static const std::string log_prefix;
 157.130 +
 157.131 +};
 157.132 +
 157.133 +} // ! Assimp
 157.134 +#endif
   158.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   158.2 +++ b/libs/assimp/MD2FileData.h	Sat Feb 01 19:58:19 2014 +0200
   158.3 @@ -0,0 +1,163 @@
   158.4 +/*
   158.5 +Open Asset Import Library (assimp)
   158.6 +----------------------------------------------------------------------
   158.7 +
   158.8 +Copyright (c) 2006-2012, assimp team
   158.9 +All rights reserved.
  158.10 +
  158.11 +Redistribution and use of this software in source and binary forms, 
  158.12 +with or without modification, are permitted provided that the 
  158.13 +following conditions are met:
  158.14 +
  158.15 +* Redistributions of source code must retain the above
  158.16 +  copyright notice, this list of conditions and the
  158.17 +  following disclaimer.
  158.18 +
  158.19 +* Redistributions in binary form must reproduce the above
  158.20 +  copyright notice, this list of conditions and the
  158.21 +  following disclaimer in the documentation and/or other
  158.22 +  materials provided with the distribution.
  158.23 +
  158.24 +* Neither the name of the assimp team, nor the names of its
  158.25 +  contributors may be used to endorse or promote products
  158.26 +  derived from this software without specific prior
  158.27 +  written permission of the assimp team.
  158.28 +
  158.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  158.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  158.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  158.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  158.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  158.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  158.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  158.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  158.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  158.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  158.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  158.40 +
  158.41 +----------------------------------------------------------------------
  158.42 +*/
  158.43 +
  158.44 +/** @file  MD2FileData.h
  158.45 + *  @brief Defines helper data structures for importing MD2 files  
  158.46 + *  http://linux.ucla.edu/~phaethon/q3/formats/md2-schoenblum.html
  158.47 + */
  158.48 +#ifndef AI_MD2FILEHELPER_H_INC
  158.49 +#define AI_MD2FILEHELPER_H_INC
  158.50 +
  158.51 +#include "assimp/types.h"
  158.52 +#include "assimp/mesh.h"
  158.53 +#include "assimp/anim.h"
  158.54 +
  158.55 +#include "assimp/Compiler/pushpack1.h"
  158.56 +
  158.57 +namespace Assimp	{
  158.58 +namespace MD2	{
  158.59 +
  158.60 +// to make it easier for us, we test the magic word against both "endianesses"
  158.61 +#define AI_MD2_MAGIC_NUMBER_BE	AI_MAKE_MAGIC("IDP2")
  158.62 +#define AI_MD2_MAGIC_NUMBER_LE	AI_MAKE_MAGIC("2PDI")
  158.63 +
  158.64 +// common limitations
  158.65 +#define AI_MD2_VERSION			15
  158.66 +#define AI_MD2_MAXQPATH			64
  158.67 +#define AI_MD2_MAX_FRAMES		512
  158.68 +#define AI_MD2_MAX_SKINS		32	
  158.69 +#define AI_MD2_MAX_VERTS		2048	
  158.70 +#define AI_MD2_MAX_TRIANGLES	4096	
  158.71 +
  158.72 +// ---------------------------------------------------------------------------
  158.73 +/**	\brief Data structure for the MD2 main header
  158.74 + */
  158.75 +struct Header
  158.76 +{
  158.77 +	uint32_t magic; 
  158.78 +	uint32_t version; 
  158.79 +	uint32_t skinWidth; 
  158.80 +	uint32_t skinHeight; 
  158.81 +	uint32_t frameSize; 
  158.82 +	uint32_t numSkins; 
  158.83 +	uint32_t numVertices; 
  158.84 +	uint32_t numTexCoords; 
  158.85 +	uint32_t numTriangles; 
  158.86 +	uint32_t numGlCommands; 
  158.87 +	uint32_t numFrames; 
  158.88 +	uint32_t offsetSkins; 
  158.89 +	uint32_t offsetTexCoords; 
  158.90 +	uint32_t offsetTriangles; 
  158.91 +	uint32_t offsetFrames; 
  158.92 +	uint32_t offsetGlCommands; 
  158.93 +	uint32_t offsetEnd; 
  158.94 +
  158.95 +} PACK_STRUCT;
  158.96 +
  158.97 +// ---------------------------------------------------------------------------
  158.98 +/**	\brief Data structure for a MD2 OpenGl draw command
  158.99 + */
 158.100 +struct GLCommand
 158.101 +{
 158.102 +   float s, t;
 158.103 +   uint32_t vertexIndex;
 158.104 +} PACK_STRUCT;
 158.105 +
 158.106 +// ---------------------------------------------------------------------------
 158.107 +/**	\brief Data structure for a MD2 triangle
 158.108 + */
 158.109 +struct Triangle
 158.110 +{
 158.111 +	uint16_t vertexIndices[3];
 158.112 +	uint16_t textureIndices[3];
 158.113 +} PACK_STRUCT;
 158.114 +
 158.115 +// ---------------------------------------------------------------------------
 158.116 +/**	\brief Data structure for a MD2 vertex
 158.117 + */
 158.118 +struct Vertex
 158.119 +{
 158.120 +	uint8_t vertex[3];
 158.121 +	uint8_t lightNormalIndex;
 158.122 +} PACK_STRUCT;
 158.123 +
 158.124 +// ---------------------------------------------------------------------------
 158.125 +/**	\brief Data structure for a MD2 frame
 158.126 + */
 158.127 +struct Frame
 158.128 +{
 158.129 +	float scale[3];
 158.130 +	float translate[3];
 158.131 +	char name[16];
 158.132 +	Vertex vertices[1];
 158.133 +} PACK_STRUCT;
 158.134 +
 158.135 +// ---------------------------------------------------------------------------
 158.136 +/**	\brief Data structure for a MD2 texture coordinate
 158.137 + */
 158.138 +struct TexCoord
 158.139 +{
 158.140 +	uint16_t s;
 158.141 +	uint16_t t;
 158.142 +} PACK_STRUCT;
 158.143 +
 158.144 +// ---------------------------------------------------------------------------
 158.145 +/**	\brief Data structure for a MD2 skin
 158.146 + */
 158.147 +struct Skin
 158.148 +{
 158.149 +	char name[AI_MD2_MAXQPATH];              /* texture file name */
 158.150 +} PACK_STRUCT;
 158.151 +
 158.152 +#include "assimp/Compiler/poppack1.h"
 158.153 +
 158.154 +
 158.155 +// ---------------------------------------------------------------------------
 158.156 +//! Lookup a normal vector from Quake's normal lookup table
 158.157 +//! \param index Input index (0-161)
 158.158 +//! \param vOut Receives the output normal
 158.159 +void LookupNormalIndex(uint8_t index,aiVector3D& vOut);
 158.160 +
 158.161 +
 158.162 +}
 158.163 +}
 158.164 +
 158.165 +#endif // !! include guard
 158.166 +
   159.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   159.2 +++ b/libs/assimp/MD2Loader.cpp	Sat Feb 01 19:58:19 2014 +0200
   159.3 @@ -0,0 +1,426 @@
   159.4 +/*
   159.5 +---------------------------------------------------------------------------
   159.6 +Open Asset Import Library (assimp)
   159.7 +---------------------------------------------------------------------------
   159.8 +
   159.9 +Copyright (c) 2006-2012, assimp team
  159.10 +
  159.11 +All rights reserved.
  159.12 +
  159.13 +Redistribution and use of this software in source and binary forms, 
  159.14 +with or without modification, are permitted provided that the following 
  159.15 +conditions are met:
  159.16 +
  159.17 +* Redistributions of source code must retain the above
  159.18 +  copyright notice, this list of conditions and the
  159.19 +  following disclaimer.
  159.20 +
  159.21 +* Redistributions in binary form must reproduce the above
  159.22 +  copyright notice, this list of conditions and the
  159.23 +  following disclaimer in the documentation and/or other
  159.24 +  materials provided with the distribution.
  159.25 +
  159.26 +* Neither the name of the assimp team, nor the names of its
  159.27 +  contributors may be used to endorse or promote products
  159.28 +  derived from this software without specific prior
  159.29 +  written permission of the assimp team.
  159.30 +
  159.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  159.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  159.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  159.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  159.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  159.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  159.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  159.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  159.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  159.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  159.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  159.42 +---------------------------------------------------------------------------
  159.43 +*/
  159.44 +
  159.45 +#include "AssimpPCH.h"
  159.46 +#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
  159.47 +
  159.48 +/** @file Implementation of the MD2 importer class */
  159.49 +#include "MD2Loader.h"
  159.50 +#include "ByteSwap.h"
  159.51 +#include "MD2NormalTable.h" // shouldn't be included by other units
  159.52 +
  159.53 +using namespace Assimp;
  159.54 +using namespace Assimp::MD2;
  159.55 +
  159.56 +
  159.57 +// helper macro to determine the size of an array
  159.58 +#if (!defined ARRAYSIZE)
  159.59 +#	define ARRAYSIZE(_array) (int(sizeof(_array) / sizeof(_array[0])))
  159.60 +#endif 
  159.61 +
  159.62 +static const aiImporterDesc desc = {
  159.63 +	"Quake II Mesh Importer",
  159.64 +	"",
  159.65 +	"",
  159.66 +	"",
  159.67 +	aiImporterFlags_SupportBinaryFlavour,
  159.68 +	0,
  159.69 +	0,
  159.70 +	0,
  159.71 +	0,
  159.72 +	"md2" 
  159.73 +};
  159.74 +
  159.75 +// ------------------------------------------------------------------------------------------------
  159.76 +// Helper function to lookup a normal in Quake 2's precalculated table
  159.77 +void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut)
  159.78 +{
  159.79 +	// make sure the normal index has a valid value
  159.80 +	if (iNormalIndex >= ARRAYSIZE(g_avNormals))	{
  159.81 +		DefaultLogger::get()->warn("Index overflow in Quake II normal vector list");
  159.82 +		iNormalIndex = ARRAYSIZE(g_avNormals) - 1;
  159.83 +	}
  159.84 +	vOut = *((const aiVector3D*)(&g_avNormals[iNormalIndex]));
  159.85 +}
  159.86 +
  159.87 +
  159.88 +// ------------------------------------------------------------------------------------------------
  159.89 +// Constructor to be privately used by Importer
  159.90 +MD2Importer::MD2Importer()
  159.91 +{}
  159.92 +
  159.93 +// ------------------------------------------------------------------------------------------------
  159.94 +// Destructor, private as well 
  159.95 +MD2Importer::~MD2Importer()
  159.96 +{}
  159.97 +
  159.98 +// ------------------------------------------------------------------------------------------------
  159.99 +// Returns whether the class can handle the format of the given file. 
 159.100 +bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
 159.101 +{
 159.102 +	const std::string extension = GetExtension(pFile);
 159.103 +	if (extension == "md2")
 159.104 +		return true;
 159.105 +
 159.106 +	// if check for extension is not enough, check for the magic tokens 
 159.107 +	if (!extension.length() || checkSig) {
 159.108 +		uint32_t tokens[1]; 
 159.109 +		tokens[0] = AI_MD2_MAGIC_NUMBER_LE;
 159.110 +		return CheckMagicToken(pIOHandler,pFile,tokens,1);
 159.111 +	}
 159.112 +	return false;
 159.113 +}
 159.114 +
 159.115 +// ------------------------------------------------------------------------------------------------
 159.116 +// Get a list of all extensions supported by this loader
 159.117 +const aiImporterDesc* MD2Importer::GetInfo () const
 159.118 +{
 159.119 +	return &desc;
 159.120 +}
 159.121 +
 159.122 +// ------------------------------------------------------------------------------------------------
 159.123 +// Setup configuration properties
 159.124 +void MD2Importer::SetupProperties(const Importer* pImp)
 159.125 +{
 159.126 +	// The 
 159.127 +	// AI_CONFIG_IMPORT_MD2_KEYFRAME option overrides the
 159.128 +	// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
 159.129 +	configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD2_KEYFRAME,-1);
 159.130 +	if(static_cast<unsigned int>(-1) == configFrameID){
 159.131 +		configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
 159.132 +	}
 159.133 +}
 159.134 +// ------------------------------------------------------------------------------------------------
 159.135 +// Validate the file header
 159.136 +void MD2Importer::ValidateHeader( )
 159.137 +{
 159.138 +	// check magic number
 159.139 +	if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
 159.140 +		m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
 159.141 +	{
 159.142 +		char szBuffer[5];
 159.143 +		szBuffer[0] = ((char*)&m_pcHeader->magic)[0];
 159.144 +		szBuffer[1] = ((char*)&m_pcHeader->magic)[1];
 159.145 +		szBuffer[2] = ((char*)&m_pcHeader->magic)[2];
 159.146 +		szBuffer[3] = ((char*)&m_pcHeader->magic)[3];
 159.147 +		szBuffer[4] = '\0';
 159.148 +
 159.149 +		throw DeadlyImportError("Invalid MD2 magic word: should be IDP2, the "
 159.150 +			"magic word found is " + std::string(szBuffer));
 159.151 +	}
 159.152 +
 159.153 +	// check file format version
 159.154 +	if (m_pcHeader->version != 8)
 159.155 +		DefaultLogger::get()->warn( "Unsupported md2 file version. Continuing happily ...");
 159.156 +
 159.157 +	// check some values whether they are valid
 159.158 +	if (0 == m_pcHeader->numFrames)
 159.159 +		throw DeadlyImportError( "Invalid md2 file: NUM_FRAMES is 0");
 159.160 +
 159.161 +	if (m_pcHeader->offsetEnd > (uint32_t)fileSize)
 159.162 +		throw DeadlyImportError( "Invalid md2 file: File is too small");
 159.163 +
 159.164 +	if (m_pcHeader->offsetSkins		+ m_pcHeader->numSkins * sizeof (MD2::Skin)			>= fileSize ||
 159.165 +		m_pcHeader->offsetTexCoords	+ m_pcHeader->numTexCoords * sizeof (MD2::TexCoord)	>= fileSize ||
 159.166 +		m_pcHeader->offsetTriangles	+ m_pcHeader->numTriangles * sizeof (MD2::Triangle)	>= fileSize ||
 159.167 +		m_pcHeader->offsetFrames		+ m_pcHeader->numFrames * sizeof (MD2::Frame)			>= fileSize ||
 159.168 +		m_pcHeader->offsetEnd			> fileSize)
 159.169 +	{
 159.170 +		throw DeadlyImportError("Invalid MD2 header: some offsets are outside the file");
 159.171 +	}
 159.172 +
 159.173 +	if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
 159.174 +		DefaultLogger::get()->warn("The model contains more skins than Quake 2 supports");
 159.175 +	if ( m_pcHeader->numFrames > AI_MD2_MAX_FRAMES)
 159.176 +		DefaultLogger::get()->warn("The model contains more frames than Quake 2 supports");
 159.177 +	if (m_pcHeader->numVertices > AI_MD2_MAX_VERTS)
 159.178 +		DefaultLogger::get()->warn("The model contains more vertices than Quake 2 supports");
 159.179 +
 159.180 +	if (m_pcHeader->numFrames <= configFrameID )
 159.181 +		throw DeadlyImportError("The requested frame is not existing the file");
 159.182 +}
 159.183 +
 159.184 +// ------------------------------------------------------------------------------------------------
 159.185 +// Imports the given file into the given scene structure. 
 159.186 +void MD2Importer::InternReadFile( const std::string& pFile, 
 159.187 +	aiScene* pScene, IOSystem* pIOHandler)
 159.188 +{
 159.189 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
 159.190 +
 159.191 +	// Check whether we can read from the file
 159.192 +	if( file.get() == NULL)
 159.193 +		throw DeadlyImportError( "Failed to open MD2 file " + pFile + "");
 159.194 +
 159.195 +	// check whether the md3 file is large enough to contain
 159.196 +	// at least the file header
 159.197 +	fileSize = (unsigned int)file->FileSize();
 159.198 +	if( fileSize < sizeof(MD2::Header))
 159.199 +		throw DeadlyImportError( "MD2 File is too small");
 159.200 +
 159.201 +	std::vector<uint8_t> mBuffer2(fileSize);
 159.202 +	file->Read(&mBuffer2[0], 1, fileSize);
 159.203 +	mBuffer = &mBuffer2[0];
 159.204 +
 159.205 +
 159.206 +	m_pcHeader = (BE_NCONST MD2::Header*)mBuffer;
 159.207 +
 159.208 +#ifdef AI_BUILD_BIG_ENDIAN
 159.209 +
 159.210 +	ByteSwap::Swap4(&m_pcHeader->frameSize);
 159.211 +	ByteSwap::Swap4(&m_pcHeader->magic);
 159.212 +	ByteSwap::Swap4(&m_pcHeader->numFrames);
 159.213 +	ByteSwap::Swap4(&m_pcHeader->numGlCommands);
 159.214 +	ByteSwap::Swap4(&m_pcHeader->numSkins);
 159.215 +	ByteSwap::Swap4(&m_pcHeader->numTexCoords);
 159.216 +	ByteSwap::Swap4(&m_pcHeader->numTriangles);
 159.217 +	ByteSwap::Swap4(&m_pcHeader->numVertices);
 159.218 +	ByteSwap::Swap4(&m_pcHeader->offsetEnd);
 159.219 +	ByteSwap::Swap4(&m_pcHeader->offsetFrames);
 159.220 +	ByteSwap::Swap4(&m_pcHeader->offsetGlCommands);
 159.221 +	ByteSwap::Swap4(&m_pcHeader->offsetSkins);
 159.222 +	ByteSwap::Swap4(&m_pcHeader->offsetTexCoords);
 159.223 +	ByteSwap::Swap4(&m_pcHeader->offsetTriangles);
 159.224 +	ByteSwap::Swap4(&m_pcHeader->skinHeight);
 159.225 +	ByteSwap::Swap4(&m_pcHeader->skinWidth);
 159.226 +	ByteSwap::Swap4(&m_pcHeader->version);
 159.227 +
 159.228 +#endif
 159.229 +
 159.230 +	ValidateHeader();
 159.231 +
 159.232 +	// there won't be more than one mesh inside the file
 159.233 +	pScene->mNumMaterials = 1;
 159.234 +	pScene->mRootNode = new aiNode();
 159.235 +	pScene->mRootNode->mNumMeshes = 1;
 159.236 +	pScene->mRootNode->mMeshes = new unsigned int[1];
 159.237 +	pScene->mRootNode->mMeshes[0] = 0;
 159.238 +	pScene->mMaterials = new aiMaterial*[1];
 159.239 +	pScene->mMaterials[0] = new aiMaterial();
 159.240 +	pScene->mNumMeshes = 1;
 159.241 +	pScene->mMeshes = new aiMesh*[1];
 159.242 +
 159.243 +	aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
 159.244 +	pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 159.245 +
 159.246 +	// navigate to the begin of the frame data
 159.247 +	BE_NCONST MD2::Frame* pcFrame = (BE_NCONST MD2::Frame*) ((uint8_t*)
 159.248 +		m_pcHeader + m_pcHeader->offsetFrames);
 159.249 +
 159.250 +	pcFrame += configFrameID;
 159.251 +
 159.252 +	// navigate to the begin of the triangle data
 159.253 +	MD2::Triangle* pcTriangles = (MD2::Triangle*) ((uint8_t*)
 159.254 +		m_pcHeader + m_pcHeader->offsetTriangles);
 159.255 +
 159.256 +	// navigate to the begin of the tex coords data
 159.257 +	BE_NCONST MD2::TexCoord* pcTexCoords = (BE_NCONST MD2::TexCoord*) ((uint8_t*)
 159.258 +		m_pcHeader + m_pcHeader->offsetTexCoords);
 159.259 +
 159.260 +	// navigate to the begin of the vertex data
 159.261 +	BE_NCONST MD2::Vertex* pcVerts = (BE_NCONST MD2::Vertex*) (pcFrame->vertices);
 159.262 +
 159.263 +#ifdef AI_BUILD_BIG_ENDIAN
 159.264 +	for (uint32_t i = 0; i< m_pcHeader->numTriangles; ++i)
 159.265 +	{
 159.266 +		for (unsigned int p = 0; p < 3;++p)
 159.267 +		{
 159.268 +			ByteSwap::Swap2(& pcTriangles[i].textureIndices[p]);
 159.269 +			ByteSwap::Swap2(& pcTriangles[i].vertexIndices[p]);
 159.270 +		}
 159.271 +	}
 159.272 +	for (uint32_t i = 0; i < m_pcHeader->offsetTexCoords;++i)
 159.273 +	{
 159.274 +		ByteSwap::Swap2(& pcTexCoords[i].s);
 159.275 +		ByteSwap::Swap2(& pcTexCoords[i].t);
 159.276 +	}
 159.277 +	ByteSwap::Swap4( & pcFrame->scale[0] );
 159.278 +	ByteSwap::Swap4( & pcFrame->scale[1] );
 159.279 +	ByteSwap::Swap4( & pcFrame->scale[2] );
 159.280 +	ByteSwap::Swap4( & pcFrame->translate[0] );
 159.281 +	ByteSwap::Swap4( & pcFrame->translate[1] );
 159.282 +	ByteSwap::Swap4( & pcFrame->translate[2] );
 159.283 +#endif
 159.284 +
 159.285 +	pcMesh->mNumFaces = m_pcHeader->numTriangles;
 159.286 +	pcMesh->mFaces = new aiFace[m_pcHeader->numTriangles];
 159.287 +
 159.288 +	// allocate output storage
 159.289 +	pcMesh->mNumVertices = (unsigned int)pcMesh->mNumFaces*3;
 159.290 +	pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
 159.291 +	pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
 159.292 +
 159.293 +	// Not sure whether there are MD2 files without texture coordinates
 159.294 +	// NOTE: texture coordinates can be there without a texture,
 159.295 +	// but a texture can't be there without a valid UV channel
 159.296 +	aiMaterial* pcHelper = (aiMaterial*)pScene->mMaterials[0];
 159.297 +	const int iMode = (int)aiShadingMode_Gouraud;
 159.298 +	pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
 159.299 +
 159.300 +	if (m_pcHeader->numTexCoords && m_pcHeader->numSkins)
 159.301 +	{
 159.302 +		// navigate to the first texture associated with the mesh
 159.303 +		const MD2::Skin* pcSkins = (const MD2::Skin*) ((unsigned char*)m_pcHeader + 
 159.304 +			m_pcHeader->offsetSkins);
 159.305 +
 159.306 +		aiColor3D clr;
 159.307 +		clr.b = clr.g = clr.r = 1.0f;
 159.308 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
 159.309 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
 159.310 +
 159.311 +		clr.b = clr.g = clr.r = 0.05f;
 159.312 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
 159.313 +
 159.314 +		if (pcSkins->name[0])
 159.315 +		{
 159.316 +			aiString szString;
 159.317 +			const size_t iLen = ::strlen(pcSkins->name);
 159.318 +			::memcpy(szString.data,pcSkins->name,iLen);
 159.319 +			szString.data[iLen] = '\0';
 159.320 +			szString.length = iLen;
 159.321 +
 159.322 +			pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
 159.323 +		}
 159.324 +		else{
 159.325 +			DefaultLogger::get()->warn("Texture file name has zero length. It will be skipped.");
 159.326 +		}
 159.327 +	}
 159.328 +	else	{
 159.329 +		// apply a default material
 159.330 +		aiColor3D clr;
 159.331 +		clr.b = clr.g = clr.r = 0.6f;
 159.332 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
 159.333 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
 159.334 +
 159.335 +		clr.b = clr.g = clr.r = 0.05f;
 159.336 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
 159.337 +
 159.338 +		aiString szName;
 159.339 +		szName.Set(AI_DEFAULT_MATERIAL_NAME);
 159.340 +		pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
 159.341 +
 159.342 +		aiString sz;
 159.343 +
 159.344 +		// TODO: Try to guess the name of the texture file from the model file name
 159.345 +
 159.346 +		sz.Set("$texture_dummy.bmp");
 159.347 +		pcHelper->AddProperty(&sz,AI_MATKEY_TEXTURE_DIFFUSE(0));
 159.348 +	}
 159.349 +
 159.350 +
 159.351 +	// now read all triangles of the first frame, apply scaling and translation
 159.352 +	unsigned int iCurrent = 0;
 159.353 +
 159.354 +	float fDivisorU = 1.0f,fDivisorV = 1.0f;
 159.355 +	if (m_pcHeader->numTexCoords)	{
 159.356 +		// allocate storage for texture coordinates, too
 159.357 +		pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
 159.358 +		pcMesh->mNumUVComponents[0] = 2;
 159.359 +
 159.360 +		// check whether the skin width or height are zero (this would
 159.361 +		// cause a division through zero)
 159.362 +		if (!m_pcHeader->skinWidth)	{
 159.363 +			DefaultLogger::get()->error("MD2: No valid skin width given");
 159.364 +		}
 159.365 +		else fDivisorU = (float)m_pcHeader->skinWidth;
 159.366 +		if (!m_pcHeader->skinHeight){
 159.367 +			DefaultLogger::get()->error("MD2: No valid skin height given");
 159.368 +		}
 159.369 +		else fDivisorV = (float)m_pcHeader->skinHeight;
 159.370 +	}
 159.371 +
 159.372 +	for (unsigned int i = 0; i < (unsigned int)m_pcHeader->numTriangles;++i)	{
 159.373 +		// Allocate the face
 159.374 +		pScene->mMeshes[0]->mFaces[i].mIndices = new unsigned int[3];
 159.375 +		pScene->mMeshes[0]->mFaces[i].mNumIndices = 3;
 159.376 +
 159.377 +		// copy texture coordinates
 159.378 +		// check whether they are different from the previous value at this index.
 159.379 +		// In this case, create a full separate set of vertices/normals/texcoords
 159.380 +		for (unsigned int c = 0; c < 3;++c,++iCurrent)	{
 159.381 +
 159.382 +			// validate vertex indices
 159.383 +			register unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c];
 159.384 +			if (iIndex >= m_pcHeader->numVertices)	{
 159.385 +				DefaultLogger::get()->error("MD2: Vertex index is outside the allowed range");
 159.386 +				iIndex = m_pcHeader->numVertices-1;
 159.387 +			}
 159.388 +
 159.389 +			// read x,y, and z component of the vertex
 159.390 +			aiVector3D& vec = pcMesh->mVertices[iCurrent];
 159.391 +
 159.392 +			vec.x = (float)pcVerts[iIndex].vertex[0] * pcFrame->scale[0];
 159.393 +			vec.x += pcFrame->translate[0];
 159.394 +
 159.395 +			vec.y = (float)pcVerts[iIndex].vertex[1] * pcFrame->scale[1];
 159.396 +			vec.y += pcFrame->translate[1];
 159.397 +
 159.398 +			vec.z = (float)pcVerts[iIndex].vertex[2] * pcFrame->scale[2];
 159.399 +			vec.z += pcFrame->translate[2];
 159.400 +
 159.401 +			// read the normal vector from the precalculated normal table
 159.402 +			aiVector3D& vNormal = pcMesh->mNormals[iCurrent];
 159.403 +			LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal);
 159.404 +
 159.405 +			// flip z and y to become right-handed
 159.406 +			std::swap((float&)vNormal.z,(float&)vNormal.y);
 159.407 +			std::swap((float&)vec.z,(float&)vec.y);
 159.408 +
 159.409 +			if (m_pcHeader->numTexCoords)	{
 159.410 +				// validate texture coordinates
 159.411 +				iIndex = pcTriangles[i].textureIndices[c];
 159.412 +				if (iIndex >= m_pcHeader->numTexCoords)	{
 159.413 +					DefaultLogger::get()->error("MD2: UV index is outside the allowed range");
 159.414 +					iIndex = m_pcHeader->numTexCoords-1;
 159.415 +				}
 159.416 +
 159.417 +				aiVector3D& pcOut = pcMesh->mTextureCoords[0][iCurrent];
 159.418 +
 159.419 +				// the texture coordinates are absolute values but we
 159.420 +				// need relative values between 0 and 1
 159.421 +				pcOut.x = pcTexCoords[iIndex].s / fDivisorU;
 159.422 +				pcOut.y = 1.f-pcTexCoords[iIndex].t / fDivisorV;
 159.423 +			}
 159.424 +			pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent;
 159.425 +		}
 159.426 +	}
 159.427 +}
 159.428 +
 159.429 +#endif // !! ASSIMP_BUILD_NO_MD2_IMPORTER
   160.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   160.2 +++ b/libs/assimp/MD2Loader.h	Sat Feb 01 19:58:19 2014 +0200
   160.3 @@ -0,0 +1,122 @@
   160.4 +/*
   160.5 +Open Asset Import Library (assimp)
   160.6 +----------------------------------------------------------------------
   160.7 +
   160.8 +Copyright (c) 2006-2012, assimp team
   160.9 +All rights reserved.
  160.10 +
  160.11 +Redistribution and use of this software in source and binary forms, 
  160.12 +with or without modification, are permitted provided that the 
  160.13 +following conditions are met:
  160.14 +
  160.15 +* Redistributions of source code must retain the above
  160.16 +  copyright notice, this list of conditions and the
  160.17 +  following disclaimer.
  160.18 +
  160.19 +* Redistributions in binary form must reproduce the above
  160.20 +  copyright notice, this list of conditions and the
  160.21 +  following disclaimer in the documentation and/or other
  160.22 +  materials provided with the distribution.
  160.23 +
  160.24 +* Neither the name of the assimp team, nor the names of its
  160.25 +  contributors may be used to endorse or promote products
  160.26 +  derived from this software without specific prior
  160.27 +  written permission of the assimp team.
  160.28 +
  160.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  160.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  160.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  160.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  160.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  160.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  160.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  160.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  160.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  160.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  160.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  160.40 +
  160.41 +----------------------------------------------------------------------
  160.42 +*/
  160.43 +
  160.44 +/** @file  MD2Loader.h
  160.45 + *  @brief Declaration of the .MD2 importer class.
  160.46 + */
  160.47 +#ifndef AI_MD2LOADER_H_INCLUDED
  160.48 +#define AI_MD2LOADER_H_INCLUDED
  160.49 +
  160.50 +#include "BaseImporter.h"
  160.51 +#include "assimp/types.h"
  160.52 +
  160.53 +struct aiNode;
  160.54 +#include "MD2FileData.h"
  160.55 +
  160.56 +namespace Assimp	{
  160.57 +
  160.58 +
  160.59 +using namespace MD2;
  160.60 +
  160.61 +// ---------------------------------------------------------------------------
  160.62 +/** Importer class for MD2
  160.63 +*/
  160.64 +class MD2Importer : public BaseImporter
  160.65 +{
  160.66 +public:
  160.67 +	MD2Importer();
  160.68 +	~MD2Importer();
  160.69 +
  160.70 +
  160.71 +public:
  160.72 +
  160.73 +	// -------------------------------------------------------------------
  160.74 +	/** Returns whether the class can handle the format of the given file. 
  160.75 +	* See BaseImporter::CanRead() for details.	*/
  160.76 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  160.77 +		bool checkSig) const;
  160.78 +
  160.79 +
  160.80 +	// -------------------------------------------------------------------
  160.81 +	/** Called prior to ReadFile().
  160.82 +	* The function is a request to the importer to update its configuration
  160.83 +	* basing on the Importer's configuration property list.
  160.84 +	*/
  160.85 +	void SetupProperties(const Importer* pImp);
  160.86 +
  160.87 +protected:
  160.88 +
  160.89 +	// -------------------------------------------------------------------
  160.90 +	/** Return importer meta information.
  160.91 +	 * See #BaseImporter::GetInfo for the details
  160.92 +	 */
  160.93 +	const aiImporterDesc* GetInfo () const;
  160.94 +
  160.95 +	// -------------------------------------------------------------------
  160.96 +	/** Imports the given file into the given scene structure. 
  160.97 +	* See BaseImporter::InternReadFile() for details
  160.98 +	*/
  160.99 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
 160.100 +		IOSystem* pIOHandler);
 160.101 +
 160.102 +
 160.103 +	// -------------------------------------------------------------------
 160.104 +	/** Validate the header of the file
 160.105 +	*/
 160.106 +	void ValidateHeader();
 160.107 +
 160.108 +protected:
 160.109 +
 160.110 +	/** Configuration option: frame to be loaded */
 160.111 +	unsigned int configFrameID;
 160.112 +
 160.113 +	/** Header of the MD2 file */
 160.114 +	BE_NCONST MD2::Header* m_pcHeader;
 160.115 +
 160.116 +	/** Buffer to hold the loaded file */
 160.117 +	BE_NCONST uint8_t* mBuffer;
 160.118 +
 160.119 +	/** Size of the file, in bytes */
 160.120 +	unsigned int fileSize;
 160.121 +};
 160.122 +
 160.123 +} // end of namespace Assimp
 160.124 +
 160.125 +#endif // AI_3DSIMPORTER_H_INC
   161.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   161.2 +++ b/libs/assimp/MD2NormalTable.h	Sat Feb 01 19:58:19 2014 +0200
   161.3 @@ -0,0 +1,217 @@
   161.4 +/*
   161.5 +Open Asset Import Library (assimp)
   161.6 +----------------------------------------------------------------------
   161.7 +
   161.8 +Copyright (c) 2006-2012, assimp team
   161.9 +All rights reserved.
  161.10 +
  161.11 +Redistribution and use of this software in source and binary forms, 
  161.12 +with or without modification, are permitted provided that the 
  161.13 +following conditions are met:
  161.14 +
  161.15 +* Redistributions of source code must retain the above
  161.16 +  copyright notice, this list of conditions and the
  161.17 +  following disclaimer.
  161.18 +
  161.19 +* Redistributions in binary form must reproduce the above
  161.20 +  copyright notice, this list of conditions and the
  161.21 +  following disclaimer in the documentation and/or other
  161.22 +  materials provided with the distribution.
  161.23 +
  161.24 +* Neither the name of the assimp team, nor the names of its
  161.25 +  contributors may be used to endorse or promote products
  161.26 +  derived from this software without specific prior
  161.27 +  written permission of the assimp team.
  161.28 +
  161.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  161.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  161.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  161.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  161.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  161.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  161.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  161.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  161.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  161.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  161.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  161.40 +
  161.41 +----------------------------------------------------------------------
  161.42 +*/
  161.43 +
  161.44 +/*
  161.45 + *	@file Slightly modified version of the anorms.h header file 
  161.46 + *  released by ID software with the Quake 2 source code.
  161.47 + *
  161.48 + *	Table of normals used by MD2 models
  161.49 + */
  161.50 +
  161.51 +#ifndef AI_MDL_NORMALTABLE_H_INC
  161.52 +#define AI_MDL_NORMALTABLE_H_INC
  161.53 +
  161.54 +
  161.55 +float g_avNormals[162][3] = {
  161.56 +{ -0.525731f,  0.000000f,  0.850651f }, 
  161.57 +{ -0.442863f,  0.238856f,  0.864188f }, 
  161.58 +{ -0.295242f,  0.000000f,  0.955423f }, 
  161.59 +{ -0.309017f,  0.500000f,  0.809017f }, 
  161.60 +{ -0.162460f,  0.262866f,  0.951056f }, 
  161.61 +{  0.000000f,  0.000000f,  1.000000f }, 
  161.62 +{  0.000000f,  0.850651f,  0.525731f }, 
  161.63 +{ -0.147621f,  0.716567f,  0.681718f }, 
  161.64 +{  0.147621f,  0.716567f,  0.681718f }, 
  161.65 +{  0.000000f,  0.525731f,  0.850651f }, 
  161.66 +{  0.309017f,  0.500000f,  0.809017f }, 
  161.67 +{  0.525731f,  0.000000f,  0.850651f }, 
  161.68 +{  0.295242f,  0.000000f,  0.955423f }, 
  161.69 +{  0.442863f,  0.238856f,  0.864188f }, 
  161.70 +{  0.162460f,  0.262866f,  0.951056f }, 
  161.71 +{ -0.681718f,  0.147621f,  0.716567f }, 
  161.72 +{ -0.809017f,  0.309017f,  0.500000f }, 
  161.73 +{ -0.587785f,  0.425325f,  0.688191f }, 
  161.74 +{ -0.850651f,  0.525731f,  0.000000f }, 
  161.75 +{ -0.864188f,  0.442863f,  0.238856f }, 
  161.76 +{ -0.716567f,  0.681718f,  0.147621f }, 
  161.77 +{ -0.688191f,  0.587785f,  0.425325f }, 
  161.78 +{ -0.500000f,  0.809017f,  0.309017f }, 
  161.79 +{ -0.238856f,  0.864188f,  0.442863f }, 
  161.80 +{ -0.425325f,  0.688191f,  0.587785f }, 
  161.81 +{ -0.716567f,  0.681718f, -0.147621f }, 
  161.82 +{ -0.500000f,  0.809017f, -0.309017f }, 
  161.83 +{ -0.525731f,  0.850651f,  0.000000f }, 
  161.84 +{  0.000000f,  0.850651f, -0.525731f }, 
  161.85 +{ -0.238856f,  0.864188f, -0.442863f }, 
  161.86 +{  0.000000f,  0.955423f, -0.295242f }, 
  161.87 +{ -0.262866f,  0.951056f, -0.162460f }, 
  161.88 +{  0.000000f,  1.000000f,  0.000000f }, 
  161.89 +{  0.000000f,  0.955423f,  0.295242f }, 
  161.90 +{ -0.262866f,  0.951056f,  0.162460f }, 
  161.91 +{  0.238856f,  0.864188f,  0.442863f }, 
  161.92 +{  0.262866f,  0.951056f,  0.162460f }, 
  161.93 +{  0.500000f,  0.809017f,  0.309017f }, 
  161.94 +{  0.238856f,  0.864188f, -0.442863f }, 
  161.95 +{  0.262866f,  0.951056f, -0.162460f }, 
  161.96 +{  0.500000f,  0.809017f, -0.309017f }, 
  161.97 +{  0.850651f,  0.525731f,  0.000000f }, 
  161.98 +{  0.716567f,  0.681718f,  0.147621f }, 
  161.99 +{  0.716567f,  0.681718f, -0.147621f }, 
 161.100 +{  0.525731f,  0.850651f,  0.000000f }, 
 161.101 +{  0.425325f,  0.688191f,  0.587785f }, 
 161.102 +{  0.864188f,  0.442863f,  0.238856f }, 
 161.103 +{  0.688191f,  0.587785f,  0.425325f }, 
 161.104 +{  0.809017f,  0.309017f,  0.500000f }, 
 161.105 +{  0.681718f,  0.147621f,  0.716567f }, 
 161.106 +{  0.587785f,  0.425325f,  0.688191f }, 
 161.107 +{  0.955423f,  0.295242f,  0.000000f }, 
 161.108 +{  1.000000f,  0.000000f,  0.000000f }, 
 161.109 +{  0.951056f,  0.162460f,  0.262866f }, 
 161.110 +{  0.850651f, -0.525731f,  0.000000f }, 
 161.111 +{  0.955423f, -0.295242f,  0.000000f }, 
 161.112 +{  0.864188f, -0.442863f,  0.238856f }, 
 161.113 +{  0.951056f, -0.162460f,  0.262866f }, 
 161.114 +{  0.809017f, -0.309017f,  0.500000f }, 
 161.115 +{  0.681718f, -0.147621f,  0.716567f }, 
 161.116 +{  0.850651f,  0.000000f,  0.525731f }, 
 161.117 +{  0.864188f,  0.442863f, -0.238856f }, 
 161.118 +{  0.809017f,  0.309017f, -0.500000f }, 
 161.119 +{  0.951056f,  0.162460f, -0.262866f }, 
 161.120 +{  0.525731f,  0.000000f, -0.850651f }, 
 161.121 +{  0.681718f,  0.147621f, -0.716567f }, 
 161.122 +{  0.681718f, -0.147621f, -0.716567f }, 
 161.123 +{  0.850651f,  0.000000f, -0.525731f }, 
 161.124 +{  0.809017f, -0.309017f, -0.500000f }, 
 161.125 +{  0.864188f, -0.442863f, -0.238856f }, 
 161.126 +{  0.951056f, -0.162460f, -0.262866f }, 
 161.127 +{  0.147621f,  0.716567f, -0.681718f }, 
 161.128 +{  0.309017f,  0.500000f, -0.809017f }, 
 161.129 +{  0.425325f,  0.688191f, -0.587785f }, 
 161.130 +{  0.442863f,  0.238856f, -0.864188f }, 
 161.131 +{  0.587785f,  0.425325f, -0.688191f }, 
 161.132 +{  0.688191f,  0.587785f, -0.425325f }, 
 161.133 +{ -0.147621f,  0.716567f, -0.681718f }, 
 161.134 +{ -0.309017f,  0.500000f, -0.809017f }, 
 161.135 +{  0.000000f,  0.525731f, -0.850651f }, 
 161.136 +{ -0.525731f,  0.000000f, -0.850651f }, 
 161.137 +{ -0.442863f,  0.238856f, -0.864188f }, 
 161.138 +{ -0.295242f,  0.000000f, -0.955423f }, 
 161.139 +{ -0.162460f,  0.262866f, -0.951056f }, 
 161.140 +{  0.000000f,  0.000000f, -1.000000f }, 
 161.141 +{  0.295242f,  0.000000f, -0.955423f }, 
 161.142 +{  0.162460f,  0.262866f, -0.951056f }, 
 161.143 +{ -0.442863f, -0.238856f, -0.864188f }, 
 161.144 +{ -0.309017f, -0.500000f, -0.809017f }, 
 161.145 +{ -0.162460f, -0.262866f, -0.951056f }, 
 161.146 +{  0.000000f, -0.850651f, -0.525731f }, 
 161.147 +{ -0.147621f, -0.716567f, -0.681718f }, 
 161.148 +{  0.147621f, -0.716567f, -0.681718f }, 
 161.149 +{  0.000000f, -0.525731f, -0.850651f }, 
 161.150 +{  0.309017f, -0.500000f, -0.809017f }, 
 161.151 +{  0.442863f, -0.238856f, -0.864188f }, 
 161.152 +{  0.162460f, -0.262866f, -0.951056f }, 
 161.153 +{  0.238856f, -0.864188f, -0.442863f }, 
 161.154 +{  0.500000f, -0.809017f, -0.309017f }, 
 161.155 +{  0.425325f, -0.688191f, -0.587785f }, 
 161.156 +{  0.716567f, -0.681718f, -0.147621f }, 
 161.157 +{  0.688191f, -0.587785f, -0.425325f }, 
 161.158 +{  0.587785f, -0.425325f, -0.688191f }, 
 161.159 +{  0.000000f, -0.955423f, -0.295242f }, 
 161.160 +{  0.000000f, -1.000000f,  0.000000f }, 
 161.161 +{  0.262866f, -0.951056f, -0.162460f }, 
 161.162 +{  0.000000f, -0.850651f,  0.525731f }, 
 161.163 +{  0.000000f, -0.955423f,  0.295242f }, 
 161.164 +{  0.238856f, -0.864188f,  0.442863f }, 
 161.165 +{  0.262866f, -0.951056f,  0.162460f }, 
 161.166 +{  0.500000f, -0.809017f,  0.309017f }, 
 161.167 +{  0.716567f, -0.681718f,  0.147621f }, 
 161.168 +{  0.525731f, -0.850651f,  0.000000f }, 
 161.169 +{ -0.238856f, -0.864188f, -0.442863f }, 
 161.170 +{ -0.500000f, -0.809017f, -0.309017f }, 
 161.171 +{ -0.262866f, -0.951056f, -0.162460f }, 
 161.172 +{ -0.850651f, -0.525731f,  0.000000f }, 
 161.173 +{ -0.716567f, -0.681718f, -0.147621f }, 
 161.174 +{ -0.716567f, -0.681718f,  0.147621f }, 
 161.175 +{ -0.525731f, -0.850651f,  0.000000f }, 
 161.176 +{ -0.500000f, -0.809017f,  0.309017f }, 
 161.177 +{ -0.238856f, -0.864188f,  0.442863f }, 
 161.178 +{ -0.262866f, -0.951056f,  0.162460f }, 
 161.179 +{ -0.864188f, -0.442863f,  0.238856f }, 
 161.180 +{ -0.809017f, -0.309017f,  0.500000f }, 
 161.181 +{ -0.688191f, -0.587785f,  0.425325f }, 
 161.182 +{ -0.681718f, -0.147621f,  0.716567f }, 
 161.183 +{ -0.442863f, -0.238856f,  0.864188f }, 
 161.184 +{ -0.587785f, -0.425325f,  0.688191f }, 
 161.185 +{ -0.309017f, -0.500000f,  0.809017f }, 
 161.186 +{ -0.147621f, -0.716567f,  0.681718f }, 
 161.187 +{ -0.425325f, -0.688191f,  0.587785f }, 
 161.188 +{ -0.162460f, -0.262866f,  0.951056f }, 
 161.189 +{  0.442863f, -0.238856f,  0.864188f }, 
 161.190 +{  0.162460f, -0.262866f,  0.951056f }, 
 161.191 +{  0.309017f, -0.500000f,  0.809017f }, 
 161.192 +{  0.147621f, -0.716567f,  0.681718f }, 
 161.193 +{  0.000000f, -0.525731f,  0.850651f }, 
 161.194 +{  0.425325f, -0.688191f,  0.587785f }, 
 161.195 +{  0.587785f, -0.425325f,  0.688191f }, 
 161.196 +{  0.688191f, -0.587785f,  0.425325f }, 
 161.197 +{ -0.955423f,  0.295242f,  0.000000f }, 
 161.198 +{ -0.951056f,  0.162460f,  0.262866f }, 
 161.199 +{ -1.000000f,  0.000000f,  0.000000f }, 
 161.200 +{ -0.850651f,  0.000000f,  0.525731f }, 
 161.201 +{ -0.955423f, -0.295242f,  0.000000f }, 
 161.202 +{ -0.951056f, -0.162460f,  0.262866f }, 
 161.203 +{ -0.864188f,  0.442863f, -0.238856f }, 
 161.204 +{ -0.951056f,  0.162460f, -0.262866f }, 
 161.205 +{ -0.809017f,  0.309017f, -0.500000f }, 
 161.206 +{ -0.864188f, -0.442863f, -0.238856f }, 
 161.207 +{ -0.951056f, -0.162460f, -0.262866f }, 
 161.208 +{ -0.809017f, -0.309017f, -0.500000f }, 
 161.209 +{ -0.681718f,  0.147621f, -0.716567f }, 
 161.210 +{ -0.681718f, -0.147621f, -0.716567f }, 
 161.211 +{ -0.850651f,  0.000000f, -0.525731f }, 
 161.212 +{ -0.688191f,  0.587785f, -0.425325f }, 
 161.213 +{ -0.587785f,  0.425325f, -0.688191f }, 
 161.214 +{ -0.425325f,  0.688191f, -0.587785f }, 
 161.215 +{ -0.425325f, -0.688191f, -0.587785f }, 
 161.216 +{ -0.587785f, -0.425325f, -0.688191f }, 
 161.217 +{ -0.688191f, -0.587785f, -0.425325f }
 161.218 +};
 161.219 +
 161.220 +#endif // !! include guard
   162.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   162.2 +++ b/libs/assimp/MD3FileData.h	Sat Feb 01 19:58:19 2014 +0200
   162.3 @@ -0,0 +1,315 @@
   162.4 +/*
   162.5 +Open Asset Import Library (assimp)
   162.6 +----------------------------------------------------------------------
   162.7 +
   162.8 +Copyright (c) 2006-2012, assimp team
   162.9 +All rights reserved.
  162.10 +
  162.11 +Redistribution and use of this software in source and binary forms, 
  162.12 +with or without modification, are permitted provided that the 
  162.13 +following conditions are met:
  162.14 +
  162.15 +* Redistributions of source code must retain the above
  162.16 +  copyright notice, this list of conditions and the
  162.17 +  following disclaimer.
  162.18 +
  162.19 +* Redistributions in binary form must reproduce the above
  162.20 +  copyright notice, this list of conditions and the
  162.21 +  following disclaimer in the documentation and/or other
  162.22 +  materials provided with the distribution.
  162.23 +
  162.24 +* Neither the name of the assimp team, nor the names of its
  162.25 +  contributors may be used to endorse or promote products
  162.26 +  derived from this software without specific prior
  162.27 +  written permission of the assimp team.
  162.28 +
  162.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  162.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  162.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  162.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  162.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  162.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  162.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  162.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  162.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  162.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  162.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  162.40 +
  162.41 +----------------------------------------------------------------------
  162.42 +*/
  162.43 +
  162.44 +/** @file Md3FileData.h
  162.45 + *
  162.46 + *  @brief Defines helper data structures for importing MD3 files.
  162.47 + *  http://linux.ucla.edu/~phaethon/q3/formats/md3format.html
  162.48 + */
  162.49 +#ifndef AI_MD3FILEHELPER_H_INC
  162.50 +#define AI_MD3FILEHELPER_H_INC
  162.51 +
  162.52 +#include <string>
  162.53 +#include <vector>
  162.54 +#include <sstream>
  162.55 +
  162.56 +#include "assimp/types.h"
  162.57 +#include "assimp/mesh.h"
  162.58 +#include "assimp/anim.h"
  162.59 +
  162.60 +#include "assimp/Compiler/pushpack1.h"
  162.61 +
  162.62 +namespace Assimp	{
  162.63 +namespace MD3	{
  162.64 +
  162.65 +// to make it easier for us, we test the magic word against both "endianesses"
  162.66 +#define AI_MD3_MAGIC_NUMBER_BE	AI_MAKE_MAGIC("IDP3")
  162.67 +#define AI_MD3_MAGIC_NUMBER_LE	AI_MAKE_MAGIC("3PDI")
  162.68 +
  162.69 +// common limitations
  162.70 +#define AI_MD3_VERSION			15
  162.71 +#define AI_MD3_MAXQPATH			64
  162.72 +#define AI_MD3_MAXFRAME			16
  162.73 +#define AI_MD3_MAX_FRAMES		1024
  162.74 +#define AI_MD3_MAX_TAGS			16
  162.75 +#define AI_MD3_MAX_SURFACES		32
  162.76 +#define AI_MD3_MAX_SHADERS		256	
  162.77 +#define AI_MD3_MAX_VERTS		4096	
  162.78 +#define AI_MD3_MAX_TRIANGLES	8192	
  162.79 +
  162.80 +// master scale factor for all vertices in a MD3 model
  162.81 +#define AI_MD3_XYZ_SCALE		(1.0f/64.0f)
  162.82 +
  162.83 +// -------------------------------------------------------------------------------
  162.84 +/** @brief Data structure for the MD3 main header
  162.85 + */
  162.86 +struct Header
  162.87 +{
  162.88 +	//! magic number
  162.89 +	uint32_t IDENT;
  162.90 +
  162.91 +	//! file format version
  162.92 +	uint32_t VERSION;
  162.93 +
  162.94 +	//! original name in .pak archive
  162.95 +	char NAME[ AI_MD3_MAXQPATH ];
  162.96 +
  162.97 +	//! unknown
  162.98 +	int32_t FLAGS;
  162.99 +
 162.100 +	//! number of frames in the file
 162.101 +	uint32_t NUM_FRAMES;
 162.102 +
 162.103 +	//! number of tags in the file
 162.104 +	uint32_t NUM_TAGS;
 162.105 +
 162.106 +	//! number of surfaces in the file
 162.107 +	uint32_t NUM_SURFACES;
 162.108 +
 162.109 +	//! number of skins in the file
 162.110 +	uint32_t NUM_SKINS;
 162.111 +
 162.112 +	//! offset of the first frame
 162.113 +	uint32_t OFS_FRAMES;
 162.114 +
 162.115 +	//! offset of the first tag
 162.116 +	uint32_t OFS_TAGS;
 162.117 +
 162.118 +	//! offset of the first surface
 162.119 +	uint32_t OFS_SURFACES;
 162.120 +
 162.121 +	//! end of file
 162.122 +	uint32_t OFS_EOF;
 162.123 +} PACK_STRUCT;
 162.124 +
 162.125 +
 162.126 +// -------------------------------------------------------------------------------
 162.127 +/** @brief Data structure for the frame header
 162.128 + */
 162.129 +struct Frame
 162.130 +{
 162.131 +	//! minimum bounds
 162.132 +	aiVector3D min;
 162.133 +
 162.134 +	//! maximum bounds
 162.135 +	aiVector3D max;
 162.136 +
 162.137 +	//! local origin for this frame
 162.138 +	aiVector3D origin;
 162.139 +
 162.140 +	//! radius of bounding sphere
 162.141 +	float radius;
 162.142 +
 162.143 +	//! name of frame
 162.144 +	char name[ AI_MD3_MAXFRAME ];
 162.145 +
 162.146 +} PACK_STRUCT;
 162.147 +
 162.148 +
 162.149 +// -------------------------------------------------------------------------------
 162.150 +/** @brief Data structure for the tag header
 162.151 + */
 162.152 +struct Tag
 162.153 +{
 162.154 +	//! name of the tag
 162.155 +	char NAME[ AI_MD3_MAXQPATH ];
 162.156 +
 162.157 +	//! Local tag origin and orientation
 162.158 +	aiVector3D  origin;
 162.159 +	float  orientation[3][3];
 162.160 +
 162.161 +} PACK_STRUCT;
 162.162 +
 162.163 +
 162.164 +// -------------------------------------------------------------------------------
 162.165 +/** @brief Data structure for the surface header
 162.166 + */
 162.167 +struct Surface
 162.168 +{
 162.169 +	//! magic number
 162.170 +	int32_t IDENT;
 162.171 +
 162.172 +	//! original name of the surface
 162.173 +	char NAME[ AI_MD3_MAXQPATH ];
 162.174 +
 162.175 +	//! unknown
 162.176 +	int32_t FLAGS;
 162.177 +
 162.178 +	//! number of frames in the surface
 162.179 +	uint32_t NUM_FRAMES;
 162.180 +
 162.181 +	//! number of shaders in the surface
 162.182 +	uint32_t NUM_SHADER;
 162.183 +
 162.184 +	//! number of vertices in the surface
 162.185 +	uint32_t NUM_VERTICES;
 162.186 +
 162.187 +	//! number of triangles in the surface
 162.188 +	uint32_t NUM_TRIANGLES;
 162.189 +
 162.190 +
 162.191 +	//! offset to the triangle data 
 162.192 +	uint32_t OFS_TRIANGLES;
 162.193 +
 162.194 +	//! offset to the shader data
 162.195 +	uint32_t OFS_SHADERS;
 162.196 +
 162.197 +	//! offset to the texture coordinate data
 162.198 +	uint32_t OFS_ST;
 162.199 +
 162.200 +	//! offset to the vertex/normal data
 162.201 +	uint32_t OFS_XYZNORMAL;
 162.202 +
 162.203 +	//! offset to the end of the Surface object
 162.204 +	int32_t OFS_END;
 162.205 +} PACK_STRUCT;
 162.206 +
 162.207 +// -------------------------------------------------------------------------------
 162.208 +/** @brief Data structure for a shader defined in there
 162.209 + */
 162.210 +struct Shader
 162.211 +{
 162.212 +	//! filename of the shader
 162.213 +	char NAME[ AI_MD3_MAXQPATH ];
 162.214 +
 162.215 +	//! index of the shader
 162.216 +	uint32_t SHADER_INDEX;
 162.217 +} PACK_STRUCT;
 162.218 +
 162.219 +
 162.220 +// -------------------------------------------------------------------------------
 162.221 +/** @brief Data structure for a triangle
 162.222 + */
 162.223 +struct Triangle
 162.224 +{
 162.225 +	//! triangle indices
 162.226 +	uint32_t INDEXES[3];
 162.227 +} PACK_STRUCT;
 162.228 +
 162.229 +
 162.230 +// -------------------------------------------------------------------------------
 162.231 +/** @brief Data structure for an UV coord
 162.232 + */
 162.233 +struct TexCoord
 162.234 +{
 162.235 +	//! UV coordinates
 162.236 +	float U,V;
 162.237 +} PACK_STRUCT;
 162.238 +
 162.239 +
 162.240 +// -------------------------------------------------------------------------------
 162.241 +/** @brief Data structure for a vertex
 162.242 + */
 162.243 +struct Vertex
 162.244 +{
 162.245 +	//! X/Y/Z coordinates
 162.246 +	int16_t X,Y,Z;
 162.247 +
 162.248 +	//! encoded normal vector
 162.249 +	uint16_t  NORMAL;
 162.250 +} PACK_STRUCT;
 162.251 +
 162.252 +#include "assimp/Compiler/poppack1.h"
 162.253 +
 162.254 +// -------------------------------------------------------------------------------
 162.255 +/**	@brief Unpack a Q3 16 bit vector to its full float3 representation
 162.256 + *
 162.257 + *	@param p_iNormal Input normal vector in latitude/longitude form
 162.258 + *	@param p_afOut Pointer to an array of three floats to receive the result
 162.259 + *
 162.260 + *	@note This has been taken from q3 source (misc_model.c)
 162.261 + */
 162.262 +inline void LatLngNormalToVec3(uint16_t p_iNormal, float* p_afOut)
 162.263 +{
 162.264 +	float lat = (float)(( p_iNormal >> 8u ) & 0xff);
 162.265 +	float lng = (float)(( p_iNormal & 0xff ));
 162.266 +	lat *= 3.141926f/128.0f;
 162.267 +	lng *= 3.141926f/128.0f;
 162.268 +
 162.269 +	p_afOut[0] = cosf(lat) * sinf(lng);
 162.270 +	p_afOut[1] = sinf(lat) * sinf(lng);
 162.271 +	p_afOut[2] = cosf(lng);
 162.272 +	return;
 162.273 +}
 162.274 +
 162.275 +
 162.276 +// -------------------------------------------------------------------------------
 162.277 +/**	@brief Pack a Q3 normal into 16bit latitute/longitude representation
 162.278 + *	@param p_vIn Input vector
 162.279 + *	@param p_iOut Output normal
 162.280 + *
 162.281 + *	@note This has been taken from q3 source (mathlib.c)
 162.282 + */
 162.283 +inline void Vec3NormalToLatLng( const aiVector3D& p_vIn, uint16_t& p_iOut ) 
 162.284 +{
 162.285 +	// check for singularities
 162.286 +	if ( 0.0f == p_vIn[0] && 0.0f == p_vIn[1] ) 
 162.287 +	{
 162.288 +		if ( p_vIn[2] > 0.0f ) 
 162.289 +		{
 162.290 +			((unsigned char*)&p_iOut)[0] = 0;
 162.291 +			((unsigned char*)&p_iOut)[1] = 0;		// lat = 0, long = 0
 162.292 +		} 
 162.293 +		else 
 162.294 +		{
 162.295 +			((unsigned char*)&p_iOut)[0] = 128;
 162.296 +			((unsigned char*)&p_iOut)[1] = 0;		// lat = 0, long = 128
 162.297 +		}
 162.298 +	} 
 162.299 +	else 
 162.300 +	{
 162.301 +		int	a, b;
 162.302 +
 162.303 +		a = int(57.2957795f * ( atan2f( p_vIn[1], p_vIn[0] ) ) * (255.0f / 360.0f ));
 162.304 +		a &= 0xff;
 162.305 +
 162.306 +		b = int(57.2957795f * ( acosf( p_vIn[2] ) ) * ( 255.0f / 360.0f ));
 162.307 +		b &= 0xff;
 162.308 +
 162.309 +		((unsigned char*)&p_iOut)[0] = b;	// longitude
 162.310 +		((unsigned char*)&p_iOut)[1] = a;	// lattitude
 162.311 +	}
 162.312 +}
 162.313 +
 162.314 +}
 162.315 +}
 162.316 +
 162.317 +#endif // !! AI_MD3FILEHELPER_H_INC
 162.318 +
   163.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   163.2 +++ b/libs/assimp/MD3Loader.cpp	Sat Feb 01 19:58:19 2014 +0200
   163.3 @@ -0,0 +1,1057 @@
   163.4 +/*
   163.5 +---------------------------------------------------------------------------
   163.6 +Open Asset Import Library (assimp)
   163.7 +---------------------------------------------------------------------------
   163.8 +
   163.9 +Copyright (c) 2006-2012, assimp team
  163.10 +
  163.11 +All rights reserved.
  163.12 +
  163.13 +Redistribution and use of this software in source and binary forms, 
  163.14 +with or without modification, are permitted provided that the following 
  163.15 +conditions are met:
  163.16 +
  163.17 +* Redistributions of source code must retain the above
  163.18 +  copyright notice, this list of conditions and the
  163.19 +  following disclaimer.
  163.20 +
  163.21 +* Redistributions in binary form must reproduce the above
  163.22 +  copyright notice, this list of conditions and the
  163.23 +  following disclaimer in the documentation and/or other
  163.24 +  materials provided with the distribution.
  163.25 +
  163.26 +* Neither the name of the assimp team, nor the names of its
  163.27 +  contributors may be used to endorse or promote products
  163.28 +  derived from this software without specific prior
  163.29 +  written permission of the assimp team.
  163.30 +
  163.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  163.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  163.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  163.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  163.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  163.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  163.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  163.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  163.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  163.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  163.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  163.42 +---------------------------------------------------------------------------
  163.43 +*/
  163.44 +
  163.45 +/** @file MD3Loader.cpp
  163.46 + *  @brief Implementation of the MD3 importer class 
  163.47 + * 
  163.48 + *  Sources: 
  163.49 + *     http://www.gamers.org/dEngine/quake3/UQ3S
  163.50 + *     http://linux.ucla.edu/~phaethon/q3/formats/md3format.html
  163.51 + *     http://www.heppler.com/shader/shader/
  163.52 + */
  163.53 +
  163.54 +#include "AssimpPCH.h"
  163.55 +#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
  163.56 +
  163.57 +#include "MD3Loader.h"
  163.58 +#include "ByteSwap.h"
  163.59 +#include "SceneCombiner.h"
  163.60 +#include "GenericProperty.h"
  163.61 +#include "RemoveComments.h"
  163.62 +#include "ParsingUtils.h"
  163.63 +#include "Importer.h"
  163.64 +
  163.65 +using namespace Assimp;
  163.66 +
  163.67 +static const aiImporterDesc desc = {
  163.68 +	"Quake III Mesh Importer",
  163.69 +	"",
  163.70 +	"",
  163.71 +	"",
  163.72 +	aiImporterFlags_SupportBinaryFlavour,
  163.73 +	0,
  163.74 +	0,
  163.75 +	0,
  163.76 +	0,
  163.77 +	"md3" 
  163.78 +};
  163.79 +
  163.80 +// ------------------------------------------------------------------------------------------------
  163.81 +// Convert a Q3 shader blend function to the appropriate enum value
  163.82 +Q3Shader::BlendFunc StringToBlendFunc(const std::string& m)
  163.83 +{
  163.84 +	if (m == "GL_ONE") {
  163.85 +		return Q3Shader::BLEND_GL_ONE;
  163.86 +	}
  163.87 +	if (m == "GL_ZERO") {
  163.88 +		return Q3Shader::BLEND_GL_ZERO;
  163.89 +	}
  163.90 +	if (m == "GL_SRC_ALPHA") {
  163.91 +		return Q3Shader::BLEND_GL_SRC_ALPHA;
  163.92 +	}
  163.93 +	if (m == "GL_ONE_MINUS_SRC_ALPHA") {
  163.94 +		return Q3Shader::BLEND_GL_ONE_MINUS_SRC_ALPHA;
  163.95 +	}
  163.96 +	if (m == "GL_ONE_MINUS_DST_COLOR") {
  163.97 +		return Q3Shader::BLEND_GL_ONE_MINUS_DST_COLOR;
  163.98 +	}
  163.99 +	DefaultLogger::get()->error("Q3Shader: Unknown blend function: " + m);
 163.100 +	return Q3Shader::BLEND_NONE;
 163.101 +}
 163.102 +
 163.103 +// ------------------------------------------------------------------------------------------------
 163.104 +// Load a Quake 3 shader
 163.105 +bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* io)
 163.106 +{
 163.107 +	boost::scoped_ptr<IOStream> file( io->Open( pFile, "rt"));
 163.108 +	if (!file.get())
 163.109 +		return false; // if we can't access the file, don't worry and return
 163.110 +
 163.111 +	DefaultLogger::get()->info("Loading Quake3 shader file " + pFile);
 163.112 +
 163.113 +	// read file in memory
 163.114 +	const size_t s = file->FileSize();
 163.115 +	std::vector<char> _buff(s+1);
 163.116 +	file->Read(&_buff[0],s,1);
 163.117 +	_buff[s] = 0;
 163.118 +
 163.119 +	// remove comments from it (C++ style)
 163.120 +	CommentRemover::RemoveLineComments("//",&_buff[0]);
 163.121 +	const char* buff = &_buff[0];
 163.122 +
 163.123 +	Q3Shader::ShaderDataBlock* curData = NULL;
 163.124 +	Q3Shader::ShaderMapBlock*  curMap  = NULL;
 163.125 +
 163.126 +	// read line per line
 163.127 +	for (;SkipSpacesAndLineEnd(&buff);SkipLine(&buff)) {
 163.128 +	
 163.129 +		if (*buff == '{') {
 163.130 +			++buff;
 163.131 +
 163.132 +			// append to last section, if any
 163.133 +			if (!curData) {
 163.134 +				DefaultLogger::get()->error("Q3Shader: Unexpected shader section token \'{\'");
 163.135 +				return true; // still no failure, the file is there
 163.136 +			}
 163.137 +
 163.138 +			// read this data section
 163.139 +			for (;SkipSpacesAndLineEnd(&buff);SkipLine(&buff)) {
 163.140 +				if (*buff == '{') {
 163.141 +					++buff;
 163.142 +					// add new map section
 163.143 +					curData->maps.push_back(Q3Shader::ShaderMapBlock());
 163.144 +					curMap = &curData->maps.back();
 163.145 +
 163.146 +					for (;SkipSpacesAndLineEnd(&buff);SkipLine(&buff)) {
 163.147 +						// 'map' - Specifies texture file name
 163.148 +						if (TokenMatchI(buff,"map",3) || TokenMatchI(buff,"clampmap",8)) {
 163.149 +							curMap->name = GetNextToken(buff);
 163.150 +						}	
 163.151 +						// 'blendfunc' - Alpha blending mode
 163.152 +						else if (TokenMatchI(buff,"blendfunc",9)) {	
 163.153 +							const std::string blend_src = GetNextToken(buff);
 163.154 +							if (blend_src == "add") {
 163.155 +								curMap->blend_src  = Q3Shader::BLEND_GL_ONE;
 163.156 +								curMap->blend_dest = Q3Shader::BLEND_GL_ONE;
 163.157 +							}
 163.158 +							else if (blend_src == "filter") {
 163.159 +								curMap->blend_src  = Q3Shader::BLEND_GL_DST_COLOR;
 163.160 +								curMap->blend_dest = Q3Shader::BLEND_GL_ZERO;
 163.161 +							}
 163.162 +							else if (blend_src == "blend") {
 163.163 +								curMap->blend_src  = Q3Shader::BLEND_GL_SRC_ALPHA;
 163.164 +								curMap->blend_dest = Q3Shader::BLEND_GL_ONE_MINUS_SRC_ALPHA;
 163.165 +							}
 163.166 +							else {
 163.167 +								curMap->blend_src  = StringToBlendFunc(blend_src);
 163.168 +								curMap->blend_dest = StringToBlendFunc(GetNextToken(buff));
 163.169 +							}
 163.170 +						}
 163.171 +						// 'alphafunc' - Alpha testing mode
 163.172 +						else if (TokenMatchI(buff,"alphafunc",9)) {	
 163.173 +							const std::string at = GetNextToken(buff);
 163.174 +							if (at == "GT0") {
 163.175 +								curMap->alpha_test = Q3Shader::AT_GT0;
 163.176 +							}
 163.177 +							else if (at == "LT128") {
 163.178 +								curMap->alpha_test = Q3Shader::AT_LT128;
 163.179 +							}
 163.180 +							else if (at == "GE128") {
 163.181 +								curMap->alpha_test = Q3Shader::AT_GE128;
 163.182 +							}
 163.183 +						}
 163.184 +						else if (*buff == '}') {
 163.185 +							++buff;
 163.186 +							// close this map section
 163.187 +							curMap = NULL;
 163.188 +							break;
 163.189 +						}
 163.190 +					}
 163.191 +
 163.192 +				}
 163.193 +				else if (*buff == '}') {
 163.194 +					++buff;
 163.195 +					curData = NULL;					
 163.196 +					break;
 163.197 +				}
 163.198 +
 163.199 +				// 'cull' specifies culling behaviour for the model
 163.200 +				else if (TokenMatchI(buff,"cull",4)) {
 163.201 +					SkipSpaces(&buff);
 163.202 +					if (!ASSIMP_strincmp(buff,"back",4)) {
 163.203 +						curData->cull = Q3Shader::CULL_CCW;
 163.204 +					}
 163.205 +					else if (!ASSIMP_strincmp(buff,"front",5)) {
 163.206 +						curData->cull = Q3Shader::CULL_CW;
 163.207 +					}
 163.208 +					else if (!ASSIMP_strincmp(buff,"none",4) || !ASSIMP_strincmp(buff,"disable",7)) {
 163.209 +						curData->cull = Q3Shader::CULL_NONE;
 163.210 +					}
 163.211 +					else DefaultLogger::get()->error("Q3Shader: Unrecognized cull mode");
 163.212 +				}
 163.213 +			}
 163.214 +		}
 163.215 +
 163.216 +		else {
 163.217 +			// add new section
 163.218 +			fill.blocks.push_back(Q3Shader::ShaderDataBlock());
 163.219 +			curData = &fill.blocks.back();
 163.220 +
 163.221 +			// get the name of this section
 163.222 +			curData->name = GetNextToken(buff);
 163.223 +		}
 163.224 +	}
 163.225 +	return true;
 163.226 +}
 163.227 +
 163.228 +// ------------------------------------------------------------------------------------------------
 163.229 +// Load a Quake 3 skin
 163.230 +bool Q3Shader::LoadSkin(SkinData& fill, const std::string& pFile,IOSystem* io)
 163.231 +{
 163.232 +	boost::scoped_ptr<IOStream> file( io->Open( pFile, "rt"));
 163.233 +	if (!file.get())
 163.234 +		return false; // if we can't access the file, don't worry and return
 163.235 +
 163.236 +	DefaultLogger::get()->info("Loading Quake3 skin file " + pFile);
 163.237 +
 163.238 +	// read file in memory
 163.239 +	const size_t s = file->FileSize();
 163.240 +	std::vector<char> _buff(s+1);const char* buff = &_buff[0];
 163.241 +	file->Read(&_buff[0],s,1);
 163.242 +	_buff[s] = 0;
 163.243 +
 163.244 +	// remove commas
 163.245 +	std::replace(_buff.begin(),_buff.end(),',',' ');
 163.246 +
 163.247 +	// read token by token and fill output table
 163.248 +	for (;*buff;) {
 163.249 +		SkipSpacesAndLineEnd(&buff);
 163.250 +
 163.251 +		// get first identifier
 163.252 +		std::string ss = GetNextToken(buff);
 163.253 +		
 163.254 +		// ignore tokens starting with tag_
 163.255 +		if (!::strncmp(&ss[0],"tag_",std::min((size_t)4, ss.length())))
 163.256 +			continue;
 163.257 +
 163.258 +		fill.textures.push_back(SkinData::TextureEntry());
 163.259 +		SkinData::TextureEntry& s = fill.textures.back();
 163.260 +
 163.261 +		s.first  = ss;
 163.262 +		s.second = GetNextToken(buff);
 163.263 +	}
 163.264 +	return true;
 163.265 +}
 163.266 +
 163.267 +// ------------------------------------------------------------------------------------------------
 163.268 +// Convert Q3Shader to material
 163.269 +void Q3Shader::ConvertShaderToMaterial(aiMaterial* out, const ShaderDataBlock& shader)
 163.270 +{
 163.271 +	ai_assert(NULL != out);
 163.272 +
 163.273 +	/*  IMPORTANT: This is not a real conversion. Actually we're just guessing and
 163.274 +	 *  hacking around to build an aiMaterial that looks nearly equal to the
 163.275 +	 *  original Quake 3 shader. We're missing some important features like
 163.276 +	 *  animatable material properties in our material system, but at least 
 163.277 +	 *  multiple textures should be handled correctly.
 163.278 +	 */ 
 163.279 +
 163.280 +	// Two-sided material?
 163.281 +	if (shader.cull == Q3Shader::CULL_NONE) {
 163.282 +		const int twosided = 1;
 163.283 +		out->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
 163.284 +	}
 163.285 +
 163.286 +	unsigned int cur_emissive = 0, cur_diffuse = 0, cur_lm =0;
 163.287 +
 163.288 +	// Iterate through all textures
 163.289 +	for (std::list< Q3Shader::ShaderMapBlock >::const_iterator it = shader.maps.begin(); it != shader.maps.end();++it) {
 163.290 +		
 163.291 +		// CONVERSION BEHAVIOUR:
 163.292 +		//
 163.293 +		//
 163.294 +		// If the texture is additive
 163.295 +		//  - if it is the first texture, assume additive blending for the whole material
 163.296 +		//  - otherwise register it as emissive texture.
 163.297 +		//
 163.298 +		// If the texture is using standard blend (or if the blend mode is unknown)
 163.299 +		//  - if first texture: assume default blending for material
 163.300 +		//  - in any case: set it as diffuse texture
 163.301 +		//
 163.302 +		// If the texture is using 'filter' blending
 163.303 +		//  - take as lightmap
 163.304 +		//
 163.305 +		// Textures with alpha funcs
 163.306 +		//  - aiTextureFlags_UseAlpha is set (otherwise aiTextureFlags_NoAlpha is explicitly set)
 163.307 +		aiString s((*it).name);
 163.308 +		aiTextureType type; unsigned int index;
 163.309 +
 163.310 +		if ((*it).blend_src == Q3Shader::BLEND_GL_ONE && (*it).blend_dest == Q3Shader::BLEND_GL_ONE) {
 163.311 +			if (it == shader.maps.begin()) {
 163.312 +				const int additive = aiBlendMode_Additive;
 163.313 +				out->AddProperty(&additive,1,AI_MATKEY_BLEND_FUNC);
 163.314 +				
 163.315 +				index = cur_diffuse++;
 163.316 +				type  = aiTextureType_DIFFUSE;
 163.317 +			}
 163.318 +			else {
 163.319 +				index = cur_emissive++;
 163.320 +				type  = aiTextureType_EMISSIVE;
 163.321 +			}
 163.322 +		}
 163.323 +		else if ((*it).blend_src == Q3Shader::BLEND_GL_DST_COLOR && (*it).blend_dest == Q3Shader::BLEND_GL_ZERO) {
 163.324 +			index = cur_lm++;
 163.325 +			type  = aiTextureType_LIGHTMAP;
 163.326 +		}
 163.327 +		else {
 163.328 +			const int blend = aiBlendMode_Default;
 163.329 +			out->AddProperty(&blend,1,AI_MATKEY_BLEND_FUNC);
 163.330 +			
 163.331 +			index = cur_diffuse++;
 163.332 +			type  = aiTextureType_DIFFUSE;
 163.333 +		}
 163.334 +
 163.335 +		// setup texture
 163.336 +		out->AddProperty(&s,AI_MATKEY_TEXTURE(type,index));
 163.337 +
 163.338 +		// setup texture flags
 163.339 +		const int use_alpha = ((*it).alpha_test != Q3Shader::AT_NONE ? aiTextureFlags_UseAlpha : aiTextureFlags_IgnoreAlpha);
 163.340 +		out->AddProperty(&use_alpha,1,AI_MATKEY_TEXFLAGS(type,index));
 163.341 +	}
 163.342 +	// If at least one emissive texture was set, set the emissive base color to 1 to ensure
 163.343 +	// the texture is actually displayed.
 163.344 +	if (0 != cur_emissive) {
 163.345 +		aiColor3D one(1.f,1.f,1.f);
 163.346 +		out->AddProperty(&one,1,AI_MATKEY_COLOR_EMISSIVE);
 163.347 +	}
 163.348 +}
 163.349 +
 163.350 +// ------------------------------------------------------------------------------------------------
 163.351 +// Constructor to be privately used by Importer
 163.352 +MD3Importer::MD3Importer()
 163.353 +: configFrameID  (0)
 163.354 +, configHandleMP (true)
 163.355 +{}
 163.356 +
 163.357 +// ------------------------------------------------------------------------------------------------
 163.358 +// Destructor, private as well 
 163.359 +MD3Importer::~MD3Importer()
 163.360 +{}
 163.361 +
 163.362 +// ------------------------------------------------------------------------------------------------
 163.363 +// Returns whether the class can handle the format of the given file. 
 163.364 +bool MD3Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
 163.365 +{
 163.366 +	const std::string extension = GetExtension(pFile);
 163.367 +	if (extension == "md3")
 163.368 +		return true;
 163.369 +
 163.370 +	// if check for extension is not enough, check for the magic tokens 
 163.371 +	if (!extension.length() || checkSig) {
 163.372 +		uint32_t tokens[1]; 
 163.373 +		tokens[0] = AI_MD3_MAGIC_NUMBER_LE;
 163.374 +		return CheckMagicToken(pIOHandler,pFile,tokens,1);
 163.375 +	}
 163.376 +	return false;
 163.377 +}
 163.378 +
 163.379 +// ------------------------------------------------------------------------------------------------
 163.380 +void MD3Importer::ValidateHeaderOffsets()
 163.381 +{
 163.382 +	// Check magic number
 163.383 +	if (pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_BE &&
 163.384 +		pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_LE)
 163.385 +			throw DeadlyImportError( "Invalid MD3 file: Magic bytes not found");
 163.386 +
 163.387 +	// Check file format version
 163.388 +	if (pcHeader->VERSION > 15)
 163.389 +		DefaultLogger::get()->warn( "Unsupported MD3 file version. Continuing happily ...");
 163.390 +
 163.391 +	// Check some offset values whether they are valid
 163.392 +	if (!pcHeader->NUM_SURFACES)
 163.393 +		throw DeadlyImportError( "Invalid md3 file: NUM_SURFACES is 0");
 163.394 +
 163.395 +	if (pcHeader->OFS_FRAMES >= fileSize || pcHeader->OFS_SURFACES >= fileSize || 
 163.396 +		pcHeader->OFS_EOF > fileSize) {
 163.397 +		throw DeadlyImportError("Invalid MD3 header: some offsets are outside the file");
 163.398 +	}
 163.399 +
 163.400 +	if (pcHeader->NUM_FRAMES <= configFrameID )
 163.401 +		throw DeadlyImportError("The requested frame is not existing the file");
 163.402 +}
 163.403 +
 163.404 +// ------------------------------------------------------------------------------------------------
 163.405 +void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
 163.406 +{
 163.407 +	// Calculate the relative offset of the surface
 163.408 +	const int32_t ofs = int32_t((const unsigned char*)pcSurf-this->mBuffer);
 163.409 +
 163.410 +	// Check whether all data chunks are inside the valid range
 163.411 +	if (pcSurf->OFS_TRIANGLES + ofs + pcSurf->NUM_TRIANGLES * sizeof(MD3::Triangle)	> fileSize  ||
 163.412 +		pcSurf->OFS_SHADERS + ofs + pcSurf->NUM_SHADER * sizeof(MD3::Shader) > fileSize         ||
 163.413 +		pcSurf->OFS_ST + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::TexCoord) > fileSize          ||
 163.414 +		pcSurf->OFS_XYZNORMAL + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::Vertex) > fileSize)	{
 163.415 +
 163.416 +		throw DeadlyImportError("Invalid MD3 surface header: some offsets are outside the file");
 163.417 +	}
 163.418 +
 163.419 +	// Check whether all requirements for Q3 files are met. We don't
 163.420 +	// care, but probably someone does.
 163.421 +	if (pcSurf->NUM_TRIANGLES > AI_MD3_MAX_TRIANGLES) {
 163.422 +		DefaultLogger::get()->warn("MD3: Quake III triangle limit exceeded");
 163.423 +	}
 163.424 +
 163.425 +	if (pcSurf->NUM_SHADER > AI_MD3_MAX_SHADERS) {
 163.426 +		DefaultLogger::get()->warn("MD3: Quake III shader limit exceeded");
 163.427 +	}
 163.428 +
 163.429 +	if (pcSurf->NUM_VERTICES > AI_MD3_MAX_VERTS) {
 163.430 +		DefaultLogger::get()->warn("MD3: Quake III vertex limit exceeded");
 163.431 +	}
 163.432 +
 163.433 +	if (pcSurf->NUM_FRAMES > AI_MD3_MAX_FRAMES) {
 163.434 +		DefaultLogger::get()->warn("MD3: Quake III frame limit exceeded");
 163.435 +	}
 163.436 +}
 163.437 +
 163.438 +// ------------------------------------------------------------------------------------------------
 163.439 +const aiImporterDesc* MD3Importer::GetInfo () const
 163.440 +{
 163.441 +	return &desc;
 163.442 +}
 163.443 +
 163.444 +// ------------------------------------------------------------------------------------------------
 163.445 +// Setup configuration properties
 163.446 +void MD3Importer::SetupProperties(const Importer* pImp)
 163.447 +{
 163.448 +	// The 
 163.449 +	// AI_CONFIG_IMPORT_MD3_KEYFRAME option overrides the
 163.450 +	// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
 163.451 +	configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD3_KEYFRAME,-1);
 163.452 +	if(static_cast<unsigned int>(-1) == configFrameID) {
 163.453 +		configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
 163.454 +	}
 163.455 +
 163.456 +	// AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART
 163.457 +	configHandleMP = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART,1));
 163.458 +
 163.459 +	// AI_CONFIG_IMPORT_MD3_SKIN_NAME
 163.460 +	configSkinFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SKIN_NAME,"default"));
 163.461 +
 163.462 +	// AI_CONFIG_IMPORT_MD3_SHADER_SRC
 163.463 +	configShaderFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SHADER_SRC,""));
 163.464 +
 163.465 +	// AI_CONFIG_FAVOUR_SPEED
 163.466 +	configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
 163.467 +}
 163.468 +
 163.469 +// ------------------------------------------------------------------------------------------------
 163.470 +// Try to read the skin for a MD3 file
 163.471 +void MD3Importer::ReadSkin(Q3Shader::SkinData& fill) const
 163.472 +{
 163.473 +	// skip any postfixes (e.g. lower_1.md3)
 163.474 +	std::string::size_type s = filename.find_last_of('_');
 163.475 +	if (s == std::string::npos) {
 163.476 +		s = filename.find_last_of('.');
 163.477 +	}
 163.478 +	ai_assert(s != std::string::npos);
 163.479 +
 163.480 +	const std::string skin_file = path + filename.substr(0,s) + "_" + configSkinFile + ".skin";
 163.481 +	Q3Shader::LoadSkin(fill,skin_file,mIOHandler);
 163.482 +}
 163.483 +
 163.484 +// ------------------------------------------------------------------------------------------------
 163.485 +// Try to read the shader for a MD3 file
 163.486 +void MD3Importer::ReadShader(Q3Shader::ShaderData& fill) const
 163.487 +{
 163.488 +	// Determine Q3 model name from given path
 163.489 +	const std::string::size_type s = path.find_last_of("\\/",path.length()-2);
 163.490 +	const std::string model_file = path.substr(s+1,path.length()-(s+2));
 163.491 +
 163.492 +	// If no specific dir or file is given, use our default search behaviour
 163.493 +	if (!configShaderFile.length()) {
 163.494 +		if(!Q3Shader::LoadShader(fill,path + "..\\..\\..\\scripts\\" + model_file + ".shader",mIOHandler)) {
 163.495 +			Q3Shader::LoadShader(fill,path + "..\\..\\..\\scripts\\" + filename + ".shader",mIOHandler);
 163.496 +		}
 163.497 +	}
 163.498 +	else {
 163.499 +		// If the given string specifies a file, load this file.
 163.500 +		// Otherwise it's a directory.
 163.501 +		const std::string::size_type st = configShaderFile.find_last_of('.');
 163.502 +		if (st == std::string::npos) {
 163.503 +			
 163.504 +			if(!Q3Shader::LoadShader(fill,configShaderFile + model_file + ".shader",mIOHandler)) {
 163.505 +				Q3Shader::LoadShader(fill,configShaderFile + filename + ".shader",mIOHandler);
 163.506 +			}
 163.507 +		}
 163.508 +		else {
 163.509 +			Q3Shader::LoadShader(fill,configShaderFile,mIOHandler);
 163.510 +		}
 163.511 +	}
 163.512 +}
 163.513 +
 163.514 +// ------------------------------------------------------------------------------------------------
 163.515 +// Tiny helper to remove a single node from its parent' list
 163.516 +void RemoveSingleNodeFromList(aiNode* nd)
 163.517 +{
 163.518 +	if (!nd || nd->mNumChildren || !nd->mParent)return;
 163.519 +	aiNode* par = nd->mParent;
 163.520 +	for (unsigned int i = 0; i < par->mNumChildren;++i) {
 163.521 +		if (par->mChildren[i] == nd) { 
 163.522 +			--par->mNumChildren;
 163.523 +			for (;i < par->mNumChildren;++i) {
 163.524 +				par->mChildren[i] = par->mChildren[i+1];
 163.525 +			}
 163.526 +			delete nd;
 163.527 +			break;
 163.528 +		}
 163.529 +	}
 163.530 +}
 163.531 +
 163.532 +// ------------------------------------------------------------------------------------------------
 163.533 +// Read a multi-part Q3 player model
 163.534 +bool MD3Importer::ReadMultipartFile()
 163.535 +{
 163.536 +	// check whether the file name contains a common postfix, e.g lower_2.md3
 163.537 +	std::string::size_type s = filename.find_last_of('_'), t = filename.find_last_of('.');
 163.538 +	ai_assert(t != std::string::npos);
 163.539 +	if (s == std::string::npos)
 163.540 +		s = t;
 163.541 +
 163.542 +	const std::string mod_filename = filename.substr(0,s);
 163.543 +	const std::string suffix = filename.substr(s,t-s);
 163.544 +
 163.545 +	if (mod_filename == "lower" || mod_filename == "upper" || mod_filename == "head"){
 163.546 +		const std::string lower = path + "lower" + suffix + ".md3";
 163.547 +		const std::string upper = path + "upper" + suffix + ".md3";
 163.548 +		const std::string head  = path + "head"  + suffix + ".md3";
 163.549 +
 163.550 +		aiScene* scene_upper = NULL;
 163.551 +		aiScene* scene_lower = NULL;
 163.552 +		aiScene* scene_head = NULL;
 163.553 +		std::string failure;
 163.554 +
 163.555 +		aiNode* tag_torso, *tag_head;
 163.556 +		std::vector<AttachmentInfo> attach;
 163.557 +
 163.558 +		DefaultLogger::get()->info("Multi part MD3 player model: lower, upper and head parts are joined");
 163.559 +
 163.560 +		// ensure we won't try to load ourselves recursively
 163.561 +		BatchLoader::PropertyMap props;
 163.562 +		SetGenericProperty( props.ints, AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART, 0, NULL);
 163.563 +
 163.564 +		// now read these three files
 163.565 +		BatchLoader batch(mIOHandler);
 163.566 +		const unsigned int _lower = batch.AddLoadRequest(lower,0,&props);
 163.567 +		const unsigned int _upper = batch.AddLoadRequest(upper,0,&props);
 163.568 +		const unsigned int _head  = batch.AddLoadRequest(head,0,&props);
 163.569 +		batch.LoadAll();
 163.570 +
 163.571 +		// now construct a dummy scene to place these three parts in
 163.572 +		aiScene* master   = new aiScene();
 163.573 +		aiNode* nd = master->mRootNode = new aiNode();
 163.574 +		nd->mName.Set("<MD3_Player>");
 163.575 +
 163.576 +		// ... and get them. We need all of them.
 163.577 +		scene_lower = batch.GetImport(_lower);
 163.578 +		if (!scene_lower) {
 163.579 +			DefaultLogger::get()->error("M3D: Failed to read multi part model, lower.md3 fails to load");
 163.580 +			failure = "lower";
 163.581 +			goto error_cleanup;
 163.582 +		}
 163.583 +
 163.584 +		scene_upper = batch.GetImport(_upper);
 163.585 +		if (!scene_upper) {
 163.586 +			DefaultLogger::get()->error("M3D: Failed to read multi part model, upper.md3 fails to load");
 163.587 +			failure = "upper";
 163.588 +			goto error_cleanup;
 163.589 +		}
 163.590 +
 163.591 +		scene_head  = batch.GetImport(_head);
 163.592 +		if (!scene_head) {
 163.593 +			DefaultLogger::get()->error("M3D: Failed to read multi part model, head.md3 fails to load");
 163.594 +			failure = "head";
 163.595 +			goto error_cleanup;
 163.596 +		}
 163.597 +
 163.598 +		// build attachment infos. search for typical Q3 tags
 163.599 +
 163.600 +		// original root
 163.601 +		scene_lower->mRootNode->mName.Set("lower");
 163.602 +		attach.push_back(AttachmentInfo(scene_lower, nd));
 163.603 +
 163.604 +		// tag_torso
 163.605 +		tag_torso = scene_lower->mRootNode->FindNode("tag_torso");
 163.606 +		if (!tag_torso) {
 163.607 +			DefaultLogger::get()->error("M3D: Failed to find attachment tag for multi part model: tag_torso expected");
 163.608 +			goto error_cleanup;
 163.609 +		}
 163.610 +		scene_upper->mRootNode->mName.Set("upper");
 163.611 +		attach.push_back(AttachmentInfo(scene_upper,tag_torso));
 163.612 +
 163.613 +		// tag_head
 163.614 +		tag_head = scene_upper->mRootNode->FindNode("tag_head");
 163.615 +		if (!tag_head) {
 163.616 +			DefaultLogger::get()->error("M3D: Failed to find attachment tag for multi part model: tag_head expected");
 163.617 +			goto error_cleanup;
 163.618 +		}
 163.619 +		scene_head->mRootNode->mName.Set("head");
 163.620 +		attach.push_back(AttachmentInfo(scene_head,tag_head));
 163.621 +
 163.622 +		// Remove tag_head and tag_torso from all other model parts ...
 163.623 +		// this ensures (together with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY)
 163.624 +		// that tag_torso/tag_head is also the name of the (unique) output node
 163.625 +		RemoveSingleNodeFromList (scene_upper->mRootNode->FindNode("tag_torso"));
 163.626 +		RemoveSingleNodeFromList (scene_head-> mRootNode->FindNode("tag_head" ));
 163.627 +
 163.628 +		// Undo the rotations which we applied to the coordinate systems. We're
 163.629 +		// working in global Quake space here
 163.630 +		scene_head->mRootNode->mTransformation  = aiMatrix4x4();
 163.631 +		scene_lower->mRootNode->mTransformation = aiMatrix4x4();
 163.632 +		scene_upper->mRootNode->mTransformation = aiMatrix4x4();
 163.633 +
 163.634 +		// and merge the scenes
 163.635 +		SceneCombiner::MergeScenes(&mScene,master, attach,
 163.636 +			AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES          |
 163.637 +			AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES       |
 163.638 +			AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS |
 163.639 +			(!configSpeedFlag ? AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY : 0));
 163.640 +
 163.641 +		// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
 163.642 +		mScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
 163.643 +			0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
 163.644 +
 163.645 +		return true;
 163.646 +
 163.647 +error_cleanup:
 163.648 +		delete scene_upper;
 163.649 +		delete scene_lower;
 163.650 +		delete scene_head;
 163.651 +		delete master;
 163.652 +
 163.653 +		if (failure == mod_filename) {
 163.654 +			throw DeadlyImportError("MD3: failure to read multipart host file");
 163.655 +		}
 163.656 +	}
 163.657 +	return false;
 163.658 +}
 163.659 +
 163.660 +// ------------------------------------------------------------------------------------------------
 163.661 +// Convert a MD3 path to a proper value
 163.662 +void MD3Importer::ConvertPath(const char* texture_name, const char* header_name, std::string& out) const
 163.663 +{
 163.664 +	// If the MD3's internal path itself and the given path are using
 163.665 +	// the same directory, remove it completely to get right output paths.
 163.666 +	const char* end1 = ::strrchr(header_name,'\\');
 163.667 +	if (!end1)end1   = ::strrchr(header_name,'/');
 163.668 +
 163.669 +	const char* end2 = ::strrchr(texture_name,'\\');
 163.670 +	if (!end2)end2   = ::strrchr(texture_name,'/');
 163.671 +
 163.672 +	// HACK: If the paths starts with "models", ignore the
 163.673 +	// next two hierarchy levels, it specifies just the model name.
 163.674 +	// Ignored by Q3, it might be not equal to the real model location.
 163.675 +	if (end2)	{
 163.676 +
 163.677 +		size_t len2;
 163.678 +		const size_t len1 = (size_t)(end1 - header_name);
 163.679 +		if (!ASSIMP_strincmp(texture_name,"models",6) && (texture_name[6] == '/' || texture_name[6] == '\\')) {
 163.680 +			len2 = 6; // ignore the seventh - could be slash or backslash
 163.681 +
 163.682 +			if (!header_name[0]) {
 163.683 +				// Use the file name only
 163.684 +				out = end2+1;
 163.685 +				return;
 163.686 +			}
 163.687 +		}
 163.688 +		else len2 = std::min (len1, (size_t)(end2 - texture_name ));
 163.689 +		if (!ASSIMP_strincmp(texture_name,header_name,len2)) {
 163.690 +			// Use the file name only
 163.691 +			out = end2+1;
 163.692 +			return;
 163.693 +		}
 163.694 +	}
 163.695 +	// Use the full path
 163.696 +	out = texture_name;
 163.697 +}
 163.698 +
 163.699 +// ------------------------------------------------------------------------------------------------
 163.700 +// Imports the given file into the given scene structure. 
 163.701 +void MD3Importer::InternReadFile( const std::string& pFile, 
 163.702 +	aiScene* pScene, IOSystem* pIOHandler)
 163.703 +{
 163.704 +	mFile = pFile;
 163.705 +	mScene = pScene;
 163.706 +	mIOHandler = pIOHandler;
 163.707 +
 163.708 +	// get base path and file name
 163.709 +	// todo ... move to PathConverter
 163.710 +	std::string::size_type s = mFile.find_last_of("/\\");
 163.711 +	if (s == std::string::npos) {
 163.712 +		s = 0;
 163.713 +	}
 163.714 +	else ++s;
 163.715 +	filename = mFile.substr(s), path = mFile.substr(0,s);
 163.716 +	for( std::string::iterator it = filename .begin(); it != filename.end(); ++it)
 163.717 +		*it = tolower( *it);
 163.718 +
 163.719 +	// Load multi-part model file, if necessary
 163.720 +	if (configHandleMP) {
 163.721 +		if (ReadMultipartFile())
 163.722 +			return;
 163.723 +	}
 163.724 +
 163.725 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
 163.726 +
 163.727 +	// Check whether we can read from the file
 163.728 +	if( file.get() == NULL)
 163.729 +		throw DeadlyImportError( "Failed to open MD3 file " + pFile + ".");
 163.730 +
 163.731 +	// Check whether the md3 file is large enough to contain the header
 163.732 +	fileSize = (unsigned int)file->FileSize();
 163.733 +	if( fileSize < sizeof(MD3::Header))
 163.734 +		throw DeadlyImportError( "MD3 File is too small.");
 163.735 +
 163.736 +	// Allocate storage and copy the contents of the file to a memory buffer
 163.737 +	std::vector<unsigned char> mBuffer2 (fileSize);
 163.738 +	file->Read( &mBuffer2[0], 1, fileSize);
 163.739 +	mBuffer = &mBuffer2[0];
 163.740 +
 163.741 +	pcHeader = (BE_NCONST MD3::Header*)mBuffer;
 163.742 +
 163.743 +	// Ensure correct endianess
 163.744 +#ifdef AI_BUILD_BIG_ENDIAN
 163.745 +
 163.746 +	AI_SWAP4(pcHeader->VERSION);
 163.747 +	AI_SWAP4(pcHeader->FLAGS);
 163.748 +	AI_SWAP4(pcHeader->IDENT);
 163.749 +	AI_SWAP4(pcHeader->NUM_FRAMES);
 163.750 +	AI_SWAP4(pcHeader->NUM_SKINS);
 163.751 +	AI_SWAP4(pcHeader->NUM_SURFACES);
 163.752 +	AI_SWAP4(pcHeader->NUM_TAGS);
 163.753 +	AI_SWAP4(pcHeader->OFS_EOF);
 163.754 +	AI_SWAP4(pcHeader->OFS_FRAMES);
 163.755 +	AI_SWAP4(pcHeader->OFS_SURFACES);
 163.756 +	AI_SWAP4(pcHeader->OFS_TAGS);
 163.757 +
 163.758 +#endif
 163.759 +
 163.760 +	// Validate the file header
 163.761 +	ValidateHeaderOffsets();
 163.762 +
 163.763 +	// Navigate to the list of surfaces
 163.764 +	BE_NCONST MD3::Surface* pcSurfaces = (BE_NCONST MD3::Surface*)(mBuffer + pcHeader->OFS_SURFACES);
 163.765 +
 163.766 +	// Navigate to the list of tags
 163.767 +	BE_NCONST MD3::Tag* pcTags = (BE_NCONST MD3::Tag*)(mBuffer + pcHeader->OFS_TAGS);
 163.768 +
 163.769 +	// Allocate output storage
 163.770 +	pScene->mNumMeshes = pcHeader->NUM_SURFACES;
 163.771 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
 163.772 +
 163.773 +	pScene->mNumMaterials = pcHeader->NUM_SURFACES;
 163.774 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes];
 163.775 +
 163.776 +	// Set arrays to zero to ensue proper destruction if an exception is raised
 163.777 +	::memset(pScene->mMeshes,0,pScene->mNumMeshes*sizeof(aiMesh*));
 163.778 +	::memset(pScene->mMaterials,0,pScene->mNumMaterials*sizeof(aiMaterial*));
 163.779 +
 163.780 +	// Now read possible skins from .skin file
 163.781 +	Q3Shader::SkinData skins;
 163.782 +	ReadSkin(skins);
 163.783 +
 163.784 +	// And check whether we can locate a shader file for this model
 163.785 +	Q3Shader::ShaderData shaders;
 163.786 +	ReadShader(shaders);
 163.787 +
 163.788 +	// Adjust all texture paths in the shader
 163.789 +	const char* header_name = pcHeader->NAME;
 163.790 +	if (shaders.blocks.size()) {
 163.791 +		for (std::list< Q3Shader::ShaderDataBlock >::iterator dit = shaders.blocks.begin(); dit != shaders.blocks.end(); ++dit) {
 163.792 +			ConvertPath((*dit).name.c_str(),header_name,(*dit).name);
 163.793 +
 163.794 +			for (std::list< Q3Shader::ShaderMapBlock >::iterator mit = (*dit).maps.begin(); mit != (*dit).maps.end(); ++mit) {
 163.795 +				ConvertPath((*mit).name.c_str(),header_name,(*mit).name);
 163.796 +			}
 163.797 +		}
 163.798 +	}
 163.799 +
 163.800 +	// Read all surfaces from the file
 163.801 +	unsigned int iNum = pcHeader->NUM_SURFACES;
 163.802 +	unsigned int iNumMaterials = 0;
 163.803 +	while (iNum-- > 0)	{
 163.804 +
 163.805 +		// Ensure correct endianess
 163.806 +#ifdef AI_BUILD_BIG_ENDIAN
 163.807 +
 163.808 +		AI_SWAP4(pcSurfaces->FLAGS);
 163.809 +		AI_SWAP4(pcSurfaces->IDENT);
 163.810 +		AI_SWAP4(pcSurfaces->NUM_FRAMES);
 163.811 +		AI_SWAP4(pcSurfaces->NUM_SHADER);
 163.812 +		AI_SWAP4(pcSurfaces->NUM_TRIANGLES);
 163.813 +		AI_SWAP4(pcSurfaces->NUM_VERTICES);
 163.814 +		AI_SWAP4(pcSurfaces->OFS_END);
 163.815 +		AI_SWAP4(pcSurfaces->OFS_SHADERS);
 163.816 +		AI_SWAP4(pcSurfaces->OFS_ST);
 163.817 +		AI_SWAP4(pcSurfaces->OFS_TRIANGLES);
 163.818 +		AI_SWAP4(pcSurfaces->OFS_XYZNORMAL);
 163.819 +
 163.820 +#endif
 163.821 +
 163.822 +		// Validate the surface header
 163.823 +		ValidateSurfaceHeaderOffsets(pcSurfaces);
 163.824 +
 163.825 +		// Navigate to the vertex list of the surface
 163.826 +		BE_NCONST MD3::Vertex* pcVertices = (BE_NCONST MD3::Vertex*)
 163.827 +			(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_XYZNORMAL);
 163.828 +
 163.829 +		// Navigate to the triangle list of the surface
 163.830 +		BE_NCONST MD3::Triangle* pcTriangles = (BE_NCONST MD3::Triangle*)
 163.831 +			(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_TRIANGLES);
 163.832 +
 163.833 +		// Navigate to the texture coordinate list of the surface
 163.834 +		BE_NCONST MD3::TexCoord* pcUVs = (BE_NCONST MD3::TexCoord*)
 163.835 +			(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_ST);
 163.836 +
 163.837 +		// Navigate to the shader list of the surface
 163.838 +		BE_NCONST MD3::Shader* pcShaders = (BE_NCONST MD3::Shader*)
 163.839 +			(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_SHADERS);
 163.840 +
 163.841 +		// If the submesh is empty ignore it
 163.842 +		if (0 == pcSurfaces->NUM_VERTICES || 0 == pcSurfaces->NUM_TRIANGLES)
 163.843 +		{
 163.844 +			pcSurfaces = (BE_NCONST MD3::Surface*)(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_END);
 163.845 +			pScene->mNumMeshes--;
 163.846 +			continue;
 163.847 +		}
 163.848 +
 163.849 +		// Allocate output mesh
 163.850 +		pScene->mMeshes[iNum] = new aiMesh();
 163.851 +		aiMesh* pcMesh = pScene->mMeshes[iNum];
 163.852 +
 163.853 +		std::string _texture_name;
 163.854 +		const char* texture_name = NULL;
 163.855 +
 163.856 +		// Check whether we have a texture record for this surface in the .skin file
 163.857 +		std::list< Q3Shader::SkinData::TextureEntry >::iterator it = std::find( 
 163.858 +			skins.textures.begin(), skins.textures.end(), pcSurfaces->NAME );
 163.859 +
 163.860 +		if (it != skins.textures.end()) {
 163.861 +			texture_name = &*( _texture_name = (*it).second).begin();
 163.862 +			DefaultLogger::get()->debug("MD3: Assigning skin texture " + (*it).second + " to surface " + pcSurfaces->NAME);
 163.863 +			(*it).resolved = true; // mark entry as resolved
 163.864 +		}
 163.865 +
 163.866 +		// Get the first shader (= texture?) assigned to the surface
 163.867 +		if (!texture_name && pcSurfaces->NUM_SHADER)	{
 163.868 +			texture_name = pcShaders->NAME;
 163.869 +		}
 163.870 +
 163.871 +		std::string convertedPath;
 163.872 +		if (texture_name) {
 163.873 +			ConvertPath(texture_name,header_name,convertedPath);
 163.874 +		}
 163.875 +
 163.876 +		const Q3Shader::ShaderDataBlock* shader = NULL;
 163.877 +
 163.878 +		// Now search the current shader for a record with this name (
 163.879 +		// excluding texture file extension)
 163.880 +		if (shaders.blocks.size()) {
 163.881 +
 163.882 +			std::string::size_type s = convertedPath.find_last_of('.');
 163.883 +			if (s == std::string::npos)
 163.884 +				s = convertedPath.length();
 163.885 +
 163.886 +			const std::string without_ext = convertedPath.substr(0,s);
 163.887 +			std::list< Q3Shader::ShaderDataBlock >::const_iterator dit = std::find(shaders.blocks.begin(),shaders.blocks.end(),without_ext);
 163.888 +			if (dit != shaders.blocks.end()) {
 163.889 +				// Hurra, wir haben einen. Tolle Sache.
 163.890 +				shader = &*dit;
 163.891 +				DefaultLogger::get()->info("Found shader record for " +without_ext );
 163.892 +			}
 163.893 +			else DefaultLogger::get()->warn("Unable to find shader record for " +without_ext );
 163.894 +		}
 163.895 +
 163.896 +		aiMaterial* pcHelper = new aiMaterial();
 163.897 +
 163.898 +		const int iMode = (int)aiShadingMode_Gouraud;
 163.899 +		pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
 163.900 +
 163.901 +		// Add a small ambient color value - Quake 3 seems to have one
 163.902 +		aiColor3D clr;
 163.903 +		clr.b = clr.g = clr.r = 0.05f;
 163.904 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
 163.905 +
 163.906 +		clr.b = clr.g = clr.r = 1.0f;
 163.907 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
 163.908 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
 163.909 +
 163.910 +		// use surface name + skin_name as material name
 163.911 +		aiString name;
 163.912 +		name.Set("MD3_[" + configSkinFile + "][" + pcSurfaces->NAME + "]");
 163.913 +		pcHelper->AddProperty(&name,AI_MATKEY_NAME);
 163.914 +
 163.915 +		if (!shader) {
 163.916 +			// Setup dummy texture file name to ensure UV coordinates are kept during postprocessing
 163.917 +			aiString szString;
 163.918 +			if (convertedPath.length())	{
 163.919 +				szString.Set(convertedPath);
 163.920 +			}
 163.921 +			else	{
 163.922 +				DefaultLogger::get()->warn("Texture file name has zero length. Using default name");
 163.923 +				szString.Set("dummy_texture.bmp");
 163.924 +			}
 163.925 +			pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
 163.926 +
 163.927 +			// prevent transparency by default
 163.928 +			int no_alpha = aiTextureFlags_IgnoreAlpha;
 163.929 +			pcHelper->AddProperty(&no_alpha,1,AI_MATKEY_TEXFLAGS_DIFFUSE(0));
 163.930 +		}
 163.931 +		else {
 163.932 +			Q3Shader::ConvertShaderToMaterial(pcHelper,*shader);
 163.933 +		}
 163.934 +
 163.935 +		pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper;
 163.936 +		pcMesh->mMaterialIndex = iNumMaterials++;
 163.937 +
 163.938 +			// Ensure correct endianess
 163.939 +#ifdef AI_BUILD_BIG_ENDIAN
 163.940 +
 163.941 +		for (uint32_t i = 0; i < pcSurfaces->NUM_VERTICES;++i)	{
 163.942 +			AI_SWAP2( pcVertices[i].NORMAL );
 163.943 +			AI_SWAP2( pcVertices[i].X );
 163.944 +			AI_SWAP2( pcVertices[i].Y );
 163.945 +			AI_SWAP2( pcVertices[i].Z );
 163.946 +
 163.947 +			AI_SWAP4( pcUVs[i].U );
 163.948 +			AI_SWAP4( pcUVs[i].U );
 163.949 +		}
 163.950 +		for (uint32_t i = 0; i < pcSurfaces->NUM_TRIANGLES;++i)	{
 163.951 +			AI_SWAP4(pcTriangles[i].INDEXES[0]);
 163.952 +			AI_SWAP4(pcTriangles[i].INDEXES[1]);
 163.953 +			AI_SWAP4(pcTriangles[i].INDEXES[2]);
 163.954 +		}
 163.955 +
 163.956 +#endif
 163.957 +
 163.958 +		// Fill mesh information
 163.959 +		pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 163.960 +
 163.961 +		pcMesh->mNumVertices		= pcSurfaces->NUM_TRIANGLES*3;
 163.962 +		pcMesh->mNumFaces			= pcSurfaces->NUM_TRIANGLES;
 163.963 +		pcMesh->mFaces				= new aiFace[pcSurfaces->NUM_TRIANGLES];
 163.964 +		pcMesh->mNormals			= new aiVector3D[pcMesh->mNumVertices];
 163.965 +		pcMesh->mVertices			= new aiVector3D[pcMesh->mNumVertices];
 163.966 +		pcMesh->mTextureCoords[0]	= new aiVector3D[pcMesh->mNumVertices];
 163.967 +		pcMesh->mNumUVComponents[0] = 2;
 163.968 +
 163.969 +		// Fill in all triangles
 163.970 +		unsigned int iCurrent = 0;
 163.971 +		for (unsigned int i = 0; i < (unsigned int)pcSurfaces->NUM_TRIANGLES;++i)	{
 163.972 +			pcMesh->mFaces[i].mIndices = new unsigned int[3];
 163.973 +			pcMesh->mFaces[i].mNumIndices = 3;
 163.974 +
 163.975 +			//unsigned int iTemp = iCurrent;
 163.976 +			for (unsigned int c = 0; c < 3;++c,++iCurrent)	{
 163.977 +				pcMesh->mFaces[i].mIndices[c] = iCurrent;
 163.978 +
 163.979 +				// Read vertices
 163.980 +				aiVector3D& vec = pcMesh->mVertices[iCurrent];
 163.981 +				vec.x = pcVertices[ pcTriangles->INDEXES[c]].X*AI_MD3_XYZ_SCALE;
 163.982 +				vec.y = pcVertices[ pcTriangles->INDEXES[c]].Y*AI_MD3_XYZ_SCALE;
 163.983 +				vec.z = pcVertices[ pcTriangles->INDEXES[c]].Z*AI_MD3_XYZ_SCALE;
 163.984 +
 163.985 +				// Convert the normal vector to uncompressed float3 format
 163.986 +				aiVector3D& nor = pcMesh->mNormals[iCurrent];
 163.987 +				LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,(float*)&nor);
 163.988 +
 163.989 +				// Read texture coordinates
 163.990 +				pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
 163.991 +				pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-pcUVs[ pcTriangles->INDEXES[c]].V;
 163.992 +			}
 163.993 +			// Flip face order if necessary
 163.994 +			if (!shader || shader->cull == Q3Shader::CULL_CW) {
 163.995 +				std::swap(pcMesh->mFaces[i].mIndices[2],pcMesh->mFaces[i].mIndices[1]);
 163.996 +			}
 163.997 +			pcTriangles++;
 163.998 +		}
 163.999 +	
163.1000 +		// Go to the next surface
163.1001 +		pcSurfaces = (BE_NCONST MD3::Surface*)(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_END);
163.1002 +	}
163.1003 +
163.1004 +	// For debugging purposes: check whether we found matches for all entries in the skins file
163.1005 +	if (!DefaultLogger::isNullLogger()) {
163.1006 +		for (std::list< Q3Shader::SkinData::TextureEntry>::const_iterator it = skins.textures.begin();it != skins.textures.end(); ++it) {
163.1007 +			if (!(*it).resolved) {
163.1008 +				DefaultLogger::get()->error("MD3: Failed to match skin " + (*it).first + " to surface " + (*it).second);
163.1009 +			}
163.1010 +		}
163.1011 +	}
163.1012 +
163.1013 +	if (!pScene->mNumMeshes)
163.1014 +		throw DeadlyImportError( "MD3: File contains no valid mesh");
163.1015 +	pScene->mNumMaterials = iNumMaterials;
163.1016 +
163.1017 +	// Now we need to generate an empty node graph
163.1018 +	pScene->mRootNode = new aiNode("<MD3Root>");
163.1019 +	pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
163.1020 +	pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
163.1021 +
163.1022 +	// Attach tiny children for all tags
163.1023 +	if (pcHeader->NUM_TAGS) {
163.1024 +		pScene->mRootNode->mNumChildren = pcHeader->NUM_TAGS;
163.1025 +		pScene->mRootNode->mChildren = new aiNode*[pcHeader->NUM_TAGS];
163.1026 +
163.1027 +		for (unsigned int i = 0; i < pcHeader->NUM_TAGS; ++i, ++pcTags) {
163.1028 +
163.1029 +			aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
163.1030 +			nd->mName.Set((const char*)pcTags->NAME);
163.1031 +			nd->mParent = pScene->mRootNode;
163.1032 +
163.1033 +			AI_SWAP4(pcTags->origin.x);
163.1034 +			AI_SWAP4(pcTags->origin.y);
163.1035 +			AI_SWAP4(pcTags->origin.z);
163.1036 +
163.1037 +			// Copy local origin, again flip z,y
163.1038 +			nd->mTransformation.a4 = pcTags->origin.x;
163.1039 +			nd->mTransformation.b4 = pcTags->origin.y;
163.1040 +			nd->mTransformation.c4 = pcTags->origin.z;
163.1041 +
163.1042 +			// Copy rest of transformation (need to transpose to match row-order matrix)
163.1043 +			for (unsigned int a = 0; a < 3;++a) {
163.1044 +				for (unsigned int m = 0; m < 3;++m) {
163.1045 +					nd->mTransformation[m][a] = pcTags->orientation[a][m];
163.1046 +					AI_SWAP4(nd->mTransformation[m][a]);
163.1047 +				}
163.1048 +			}
163.1049 +		}
163.1050 +	}
163.1051 +
163.1052 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
163.1053 +		pScene->mRootNode->mMeshes[i] = i;
163.1054 +
163.1055 +	// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
163.1056 +	pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
163.1057 +		0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
163.1058 +}
163.1059 +
163.1060 +#endif // !! ASSIMP_BUILD_NO_MD3_IMPORTER
   164.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   164.2 +++ b/libs/assimp/MD3Loader.h	Sat Feb 01 19:58:19 2014 +0200
   164.3 @@ -0,0 +1,327 @@
   164.4 +/*
   164.5 +Open Asset Import Library (assimp)
   164.6 +----------------------------------------------------------------------
   164.7 +
   164.8 +Copyright (c) 2006-2012, assimp team
   164.9 +All rights reserved.
  164.10 +
  164.11 +Redistribution and use of this software in source and binary forms, 
  164.12 +with or without modification, are permitted provided that the 
  164.13 +following conditions are met:
  164.14 +
  164.15 +* Redistributions of source code must retain the above
  164.16 +  copyright notice, this list of conditions and the
  164.17 +  following disclaimer.
  164.18 +
  164.19 +* Redistributions in binary form must reproduce the above
  164.20 +  copyright notice, this list of conditions and the
  164.21 +  following disclaimer in the documentation and/or other
  164.22 +  materials provided with the distribution.
  164.23 +
  164.24 +* Neither the name of the assimp team, nor the names of its
  164.25 +  contributors may be used to endorse or promote products
  164.26 +  derived from this software without specific prior
  164.27 +  written permission of the assimp team.
  164.28 +
  164.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  164.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  164.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  164.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  164.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  164.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  164.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  164.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  164.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  164.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  164.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  164.40 +
  164.41 +----------------------------------------------------------------------
  164.42 +*/
  164.43 +
  164.44 +/** @file  Md3Loader.h
  164.45 + *  @brief Declaration of the .MD3 importer class.
  164.46 + */
  164.47 +#ifndef AI_MD3LOADER_H_INCLUDED
  164.48 +#define AI_MD3LOADER_H_INCLUDED
  164.49 +
  164.50 +#include "BaseImporter.h"
  164.51 +#include "ByteSwap.h"
  164.52 +
  164.53 +#include "assimp/types.h"
  164.54 +
  164.55 +#include "MD3FileData.h"
  164.56 +namespace Assimp	{
  164.57 +
  164.58 +
  164.59 +using namespace MD3;
  164.60 +namespace Q3Shader {
  164.61 +
  164.62 +// ---------------------------------------------------------------------------
  164.63 +/** @brief Tiny utility data structure to hold the data of a .skin file
  164.64 + */
  164.65 +struct SkinData
  164.66 +{
  164.67 +	//! A single entryin texture list
  164.68 +	struct TextureEntry : public std::pair<std::string,std::string>
  164.69 +	{
  164.70 +		// did we resolve this texture entry?
  164.71 +		bool resolved;
  164.72 +
  164.73 +		// for std::find()
  164.74 +		bool operator == (const std::string& f) const {
  164.75 +			return f == first;
  164.76 +		}
  164.77 +	};
  164.78 +
  164.79 +	//! List of textures
  164.80 +	std::list<TextureEntry> textures;
  164.81 +
  164.82 +	// rest is ignored for the moment
  164.83 +};
  164.84 +
  164.85 +// ---------------------------------------------------------------------------
  164.86 +/** @brief Specifies cull modi for Quake shader files.
  164.87 + */
  164.88 +enum ShaderCullMode
  164.89 +{
  164.90 +	CULL_NONE,
  164.91 +	CULL_CW,
  164.92 +	CULL_CCW
  164.93 +};
  164.94 +
  164.95 +// ---------------------------------------------------------------------------
  164.96 +/** @brief Specifies alpha blend modi (src + dest) for Quake shader files
  164.97 + */
  164.98 +enum BlendFunc
  164.99 +{
 164.100 +	BLEND_NONE,
 164.101 +	BLEND_GL_ONE, 
 164.102 +	BLEND_GL_ZERO,
 164.103 +	BLEND_GL_DST_COLOR,
 164.104 +	BLEND_GL_ONE_MINUS_DST_COLOR,
 164.105 +	BLEND_GL_SRC_ALPHA,
 164.106 +	BLEND_GL_ONE_MINUS_SRC_ALPHA
 164.107 +};
 164.108 +
 164.109 +// ---------------------------------------------------------------------------
 164.110 +/** @brief Specifies alpha test modi for Quake texture maps
 164.111 + */
 164.112 +enum AlphaTestFunc
 164.113 +{
 164.114 +	AT_NONE,
 164.115 +	AT_GT0,
 164.116 +	AT_LT128, 
 164.117 +	AT_GE128
 164.118 +};
 164.119 +
 164.120 +// ---------------------------------------------------------------------------
 164.121 +/** @brief Tiny utility data structure to hold a .shader map data block
 164.122 + */
 164.123 +struct ShaderMapBlock
 164.124 +{
 164.125 +	ShaderMapBlock()
 164.126 +		 :	blend_src	(BLEND_NONE)
 164.127 +		 ,	blend_dest	(BLEND_NONE)
 164.128 +		 ,	alpha_test	(AT_NONE)
 164.129 +	{}
 164.130 +
 164.131 +	//! Name of referenced map
 164.132 +	std::string name;
 164.133 +
 164.134 +	//! Blend and alpha test settings for texture
 164.135 +	BlendFunc blend_src,blend_dest;
 164.136 +	AlphaTestFunc alpha_test;
 164.137 +
 164.138 +
 164.139 +	//! For std::find()
 164.140 +	bool operator== (const std::string& o) const {
 164.141 +		return !ASSIMP_stricmp(o,name);
 164.142 +	}
 164.143 +};
 164.144 +
 164.145 +// ---------------------------------------------------------------------------
 164.146 +/** @brief Tiny utility data structure to hold a .shader data block
 164.147 + */
 164.148 +struct ShaderDataBlock
 164.149 +{
 164.150 +	ShaderDataBlock()
 164.151 +		:	cull	(CULL_CW)
 164.152 +	{}
 164.153 +
 164.154 +	//! Name of referenced data element
 164.155 +	std::string name;
 164.156 +
 164.157 +	//! Cull mode for the element
 164.158 +	ShaderCullMode cull;
 164.159 +
 164.160 +	//! Maps defined in the shader
 164.161 +	std::list<ShaderMapBlock> maps;
 164.162 +
 164.163 +
 164.164 +	//! For std::find()
 164.165 +	bool operator== (const std::string& o) const {
 164.166 +		return !ASSIMP_stricmp(o,name);
 164.167 +	}
 164.168 +};
 164.169 +
 164.170 +// ---------------------------------------------------------------------------
 164.171 +/** @brief Tiny utility data structure to hold the data of a .shader file
 164.172 + */
 164.173 +struct ShaderData
 164.174 +{
 164.175 +	//! Shader data blocks
 164.176 +	std::list<ShaderDataBlock> blocks;
 164.177 +};
 164.178 +
 164.179 +// ---------------------------------------------------------------------------
 164.180 +/** @brief Load a shader file
 164.181 + *
 164.182 + *  Generally, parsing is error tolerant. There's no failure.
 164.183 + *  @param fill Receives output data
 164.184 + *  @param file File to be read.
 164.185 + *  @param io IOSystem to be used for reading
 164.186 + *  @return false if file is not accessible
 164.187 + */
 164.188 +bool LoadShader(ShaderData& fill, const std::string& file,IOSystem* io);
 164.189 +
 164.190 +
 164.191 +// ---------------------------------------------------------------------------
 164.192 +/** @brief Convert a Q3Shader to an aiMaterial
 164.193 + *
 164.194 + *  @param[out] out Material structure to be filled.
 164.195 + *  @param[in] shader Input shader
 164.196 + */
 164.197 +void ConvertShaderToMaterial(aiMaterial* out, const ShaderDataBlock& shader);
 164.198 +
 164.199 +// ---------------------------------------------------------------------------
 164.200 +/** @brief Load a skin file
 164.201 + *
 164.202 + *  Generally, parsing is error tolerant. There's no failure.
 164.203 + *  @param fill Receives output data
 164.204 + *  @param file File to be read.
 164.205 + *  @param io IOSystem to be used for reading
 164.206 + *  @return false if file is not accessible
 164.207 + */
 164.208 +bool LoadSkin(SkinData& fill, const std::string& file,IOSystem* io);
 164.209 +
 164.210 +} // ! namespace Q3SHader
 164.211 +
 164.212 +// ---------------------------------------------------------------------------
 164.213 +/** @brief Importer class to load MD3 files
 164.214 +*/
 164.215 +class MD3Importer : public BaseImporter
 164.216 +{
 164.217 +public:
 164.218 +	MD3Importer();
 164.219 +	~MD3Importer();
 164.220 +
 164.221 +
 164.222 +public:
 164.223 +
 164.224 +	// -------------------------------------------------------------------
 164.225 +	/** Returns whether the class can handle the format of the given file. 
 164.226 +	* See BaseImporter::CanRead() for details.	*/
 164.227 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
 164.228 +		bool checkSig) const;
 164.229 +
 164.230 +
 164.231 +	// -------------------------------------------------------------------
 164.232 +	/** Called prior to ReadFile().
 164.233 +	* The function is a request to the importer to update its configuration
 164.234 +	* basing on the Importer's configuration property list.
 164.235 +	*/
 164.236 +	void SetupProperties(const Importer* pImp);
 164.237 +
 164.238 +protected:
 164.239 +
 164.240 +	// -------------------------------------------------------------------
 164.241 +	/** Return importer meta information.
 164.242 +	 * See #BaseImporter::GetInfo for the details
 164.243 +	 */
 164.244 +	const aiImporterDesc* GetInfo () const;
 164.245 +
 164.246 +	// -------------------------------------------------------------------
 164.247 +	/** Imports the given file into the given scene structure. 
 164.248 +	 * See BaseImporter::InternReadFile() for details
 164.249 +	 */
 164.250 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
 164.251 +		IOSystem* pIOHandler);
 164.252 +
 164.253 +	// -------------------------------------------------------------------
 164.254 +	/** Validate offsets in the header
 164.255 +	 */
 164.256 +	void ValidateHeaderOffsets();
 164.257 +	void ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurfHeader);
 164.258 +
 164.259 +	// -------------------------------------------------------------------
 164.260 +	/** Read a Q3 multipart file
 164.261 +	 *  @return true if multi part has been processed
 164.262 +	 */
 164.263 +	bool ReadMultipartFile();
 164.264 +
 164.265 +	// -------------------------------------------------------------------
 164.266 +	/** Try to read the skin for a MD3 file
 164.267 +	 *  @param fill Receives output information
 164.268 +	 */
 164.269 +	void ReadSkin(Q3Shader::SkinData& fill) const;
 164.270 +
 164.271 +	// -------------------------------------------------------------------
 164.272 +	/** Try to read the shader for a MD3 file
 164.273 +	 *  @param fill Receives output information
 164.274 +	 */
 164.275 +	void ReadShader(Q3Shader::ShaderData& fill) const;
 164.276 +
 164.277 +	// -------------------------------------------------------------------
 164.278 +	/** Convert a texture path in a MD3 file to a proper value
 164.279 +	 *  @param[in] texture_name Path to be converted
 164.280 +	 *  @param[in] header_path Base path specified in MD3 header
 164.281 +	 *  @param[out] out Receives the converted output string
 164.282 +	 */
 164.283 +	void ConvertPath(const char* texture_name, const char* header_path, 
 164.284 +		std::string& out) const;
 164.285 +
 164.286 +protected:
 164.287 +
 164.288 +	/** Configuration option: frame to be loaded */
 164.289 +	unsigned int configFrameID;
 164.290 +
 164.291 +	/** Configuration option: process multi-part files */
 164.292 +	bool configHandleMP;
 164.293 +
 164.294 +	/** Configuration option: name of skin file to be read */
 164.295 +	std::string configSkinFile;
 164.296 +
 164.297 +	/** Configuration option: name or path of shader */
 164.298 +	std::string configShaderFile;
 164.299 +
 164.300 +	/** Configuration option: speed flag was set? */
 164.301 +	bool configSpeedFlag;
 164.302 +
 164.303 +	/** Header of the MD3 file */
 164.304 +	BE_NCONST MD3::Header* pcHeader;
 164.305 +
 164.306 +	/** File buffer  */
 164.307 +	BE_NCONST unsigned char* mBuffer;
 164.308 +
 164.309 +	/** Size of the file, in bytes */
 164.310 +	unsigned int fileSize;
 164.311 +
 164.312 +	/** Current file name */
 164.313 +	std::string mFile;
 164.314 +
 164.315 +	/** Current base directory  */
 164.316 +	std::string path;
 164.317 +
 164.318 +	/** Pure file we're currently reading */
 164.319 +	std::string filename;
 164.320 +
 164.321 +	/** Output scene to be filled */
 164.322 +	aiScene* mScene;
 164.323 +
 164.324 +	/** IO system to be used to access the data*/
 164.325 +	IOSystem* mIOHandler;
 164.326 +	};
 164.327 +
 164.328 +} // end of namespace Assimp
 164.329 +
 164.330 +#endif // AI_3DSIMPORTER_H_INC
   165.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   165.2 +++ b/libs/assimp/MD4FileData.h	Sat Feb 01 19:58:19 2014 +0200
   165.3 @@ -0,0 +1,218 @@
   165.4 +/*
   165.5 +Open Asset Import Library (ASSIMP)
   165.6 +----------------------------------------------------------------------
   165.7 +
   165.8 +Copyright (c) 2006-2010, ASSIMP Development Team
   165.9 +All rights reserved.
  165.10 +
  165.11 +Redistribution and use of this software in source and binary forms, 
  165.12 +with or without modification, are permitted provided that the 
  165.13 +following conditions are met:
  165.14 +
  165.15 +* Redistributions of source code must retain the above
  165.16 +  copyright notice, this list of conditions and the
  165.17 +  following disclaimer.
  165.18 +
  165.19 +* Redistributions in binary form must reproduce the above
  165.20 +  copyright notice, this list of conditions and the
  165.21 +  following disclaimer in the documentation and/or other
  165.22 +  materials provided with the distribution.
  165.23 +
  165.24 +* Neither the name of the ASSIMP team, nor the names of its
  165.25 +  contributors may be used to endorse or promote products
  165.26 +  derived from this software without specific prior
  165.27 +  written permission of the ASSIMP Development Team.
  165.28 +
  165.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  165.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  165.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  165.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  165.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  165.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  165.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  165.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  165.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  165.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  165.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  165.40 +
  165.41 +----------------------------------------------------------------------
  165.42 +*/
  165.43 +
  165.44 +/** @file Defines the helper data structures for importing MD4 files  */
  165.45 +#ifndef AI_MD4FILEHELPER_H_INC
  165.46 +#define AI_MD4FILEHELPER_H_INC
  165.47 +
  165.48 +#include <string>
  165.49 +#include <vector>
  165.50 +#include <sstream>
  165.51 +
  165.52 +#include "../include/aiTypes.h"
  165.53 +#include "../include/aiMesh.h"
  165.54 +#include "../include/aiAnim.h"
  165.55 +
  165.56 +#if defined(_MSC_VER) ||  defined(__BORLANDC__) ||	defined (__BCPLUSPLUS__)
  165.57 +#	pragma pack(push,1)
  165.58 +#	define PACK_STRUCT
  165.59 +#elif defined( __GNUC__ )
  165.60 +#	define PACK_STRUCT	__attribute__((packed))
  165.61 +#else
  165.62 +#	error Compiler not supported
  165.63 +#endif
  165.64 +
  165.65 +
  165.66 +namespace Assimp
  165.67 +{
  165.68 +// http://gongo.quakedev.com/md4.html
  165.69 +namespace MD4
  165.70 +{
  165.71 +
  165.72 +#define AI_MD4_MAGIC_NUMBER_BE	'IDP4'
  165.73 +#define AI_MD4_MAGIC_NUMBER_LE	'4PDI'
  165.74 +
  165.75 +// common limitations
  165.76 +#define AI_MD4_VERSION			4
  165.77 +#define AI_MD4_MAXQPATH			64
  165.78 +#define AI_MD4_MAX_FRAMES		2028
  165.79 +#define AI_MD4_MAX_SURFACES		32
  165.80 +#define AI_MD4_MAX_BONES		256
  165.81 +#define AI_MD4_MAX_VERTS		4096	
  165.82 +#define AI_MD4_MAX_TRIANGLES	8192	
  165.83 +
  165.84 +// ---------------------------------------------------------------------------
  165.85 +/** \brief Data structure for the MD4 main header
  165.86 + */
  165.87 +// ---------------------------------------------------------------------------
  165.88 +struct Header
  165.89 +{
  165.90 +	//! magic number
  165.91 +	int32_t magic;
  165.92 +
  165.93 +	//! file format version
  165.94 +	int32_t version;
  165.95 +
  165.96 +	//! original name in .pak archive
  165.97 +	unsigned char name[ AI_MD4_MAXQPATH ];
  165.98 +
  165.99 +	//! number of frames in the file
 165.100 +	int32_t NUM_FRAMES;
 165.101 +
 165.102 +	//! number of bones in the file
 165.103 +	int32_t NUM_BONES;
 165.104 +
 165.105 +	//! number of surfaces in the file
 165.106 +	int32_t NUM_SURFACES;
 165.107 +
 165.108 +	//! offset of the first frame
 165.109 +	int32_t OFS_FRAMES;
 165.110 +
 165.111 +	//! offset of the first bone
 165.112 +	int32_t OFS_BONES;
 165.113 +
 165.114 +	//! offset of the first surface
 165.115 +	int32_t OFS_SURFACES;
 165.116 +
 165.117 +	//! end of file
 165.118 +	int32_t OFS_EOF;
 165.119 +} PACK_STRUCT;
 165.120 +
 165.121 +// ---------------------------------------------------------------------------
 165.122 +/** \brief Stores the local transformation matrix of a bone
 165.123 + */
 165.124 +// ---------------------------------------------------------------------------
 165.125 +struct BoneFrame
 165.126 +{  
 165.127 +	float matrix[3][4]; 
 165.128 +} PACK_STRUCT;
 165.129 +
 165.130 +// ---------------------------------------------------------------------------
 165.131 +/** \brief Stores the name / parent index / flag of a node
 165.132 + */
 165.133 +// ---------------------------------------------------------------------------
 165.134 +struct  BoneName
 165.135 +{  
 165.136 +	char name[32] ; 
 165.137 +	int parent ;
 165.138 +	int flags ;
 165.139 +}  PACK_STRUCT;
 165.140 +
 165.141 +// ---------------------------------------------------------------------------
 165.142 +/** \brief Data structure for a surface in a MD4 file
 165.143 + */
 165.144 +// ---------------------------------------------------------------------------
 165.145 +struct Surface
 165.146 +{  
 165.147 +	int32_t ident;
 165.148 +	char name[64];
 165.149 +	char shader[64];
 165.150 +	int32_t shaderIndex;
 165.151 +	int32_t lodBias;
 165.152 +	int32_t minLod;
 165.153 +	int32_t ofsHeader;
 165.154 +	int32_t numVerts;
 165.155 +	int32_t ofsVerts;
 165.156 +	int32_t numTris;
 165.157 +	int32_t ofsTris;
 165.158 +	int32_t numBoneRefs;
 165.159 +	int32_t ofsBoneRefs;
 165.160 +	int32_t ofsCollapseMap;
 165.161 +	int32_t ofsEnd;
 165.162 +} PACK_STRUCT;
 165.163 +
 165.164 +
 165.165 +// ---------------------------------------------------------------------------
 165.166 +/** \brief Data structure for a MD4 vertex' weight
 165.167 + */
 165.168 +// ---------------------------------------------------------------------------
 165.169 +struct Weight
 165.170 +{  
 165.171 +	int32_t boneIndex; 
 165.172 +	float boneWeight; 
 165.173 +	float offset[3]; 
 165.174 +} PACK_STRUCT; 
 165.175 +
 165.176 +// ---------------------------------------------------------------------------
 165.177 +/** \brief Data structure for a vertex in a MD4 file
 165.178 + */
 165.179 +// ---------------------------------------------------------------------------
 165.180 +struct Vertex
 165.181 +{  
 165.182 +	float vertex[3];
 165.183 +	float normal[3];
 165.184 +	float texCoords[2];
 165.185 +	int32_t numWeights;
 165.186 +	Weight weights[1];
 165.187 +} PACK_STRUCT; 
 165.188 +
 165.189 +// ---------------------------------------------------------------------------
 165.190 +/** \brief Data structure for a triangle in a MD4 file
 165.191 + */
 165.192 +// ---------------------------------------------------------------------------
 165.193 +struct Triangle 
 165.194 +{  
 165.195 +	int32_t indexes[3]; 
 165.196 +} PACK_STRUCT;
 165.197 +
 165.198 +// ---------------------------------------------------------------------------
 165.199 +/** \brief Data structure for a MD4 frame
 165.200 + */
 165.201 +// ---------------------------------------------------------------------------
 165.202 +struct Frame
 165.203 +{  
 165.204 +	float bounds[3][2];
 165.205 +	float localOrigin[3]; 
 165.206 +	float radius;
 165.207 +	BoneFrame bones[1]; 
 165.208 +} PACK_STRUCT; 
 165.209 +
 165.210 +
 165.211 +// reset packing to the original value
 165.212 +#if defined(_MSC_VER) ||  defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
 165.213 +#	pragma pack( pop )
 165.214 +#endif
 165.215 +#undef PACK_STRUCT
 165.216 +
 165.217 +
 165.218 +};
 165.219 +};
 165.220 +
 165.221 +#endif // !! AI_MD4FILEHELPER_H_INC
 165.222 \ No newline at end of file
   166.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   166.2 +++ b/libs/assimp/MD5Loader.cpp	Sat Feb 01 19:58:19 2014 +0200
   166.3 @@ -0,0 +1,748 @@
   166.4 +/*
   166.5 +---------------------------------------------------------------------------
   166.6 +Open Asset Import Library (assimp)
   166.7 +---------------------------------------------------------------------------
   166.8 +
   166.9 +Copyright (c) 2006-2012, assimp team
  166.10 +
  166.11 +All rights reserved.
  166.12 +
  166.13 +Redistribution and use of this software in source and binary forms, 
  166.14 +with or without modification, are permitted provided that the following 
  166.15 +conditions are met:
  166.16 +
  166.17 +* Redistributions of source code must retain the above
  166.18 +  copyright notice, this list of conditions and the
  166.19 +  following disclaimer.
  166.20 +
  166.21 +* Redistributions in binary form must reproduce the above
  166.22 +  copyright notice, this list of conditions and the
  166.23 +  following disclaimer in the documentation and/or other
  166.24 +  materials provided with the distribution.
  166.25 +
  166.26 +* Neither the name of the assimp team, nor the names of its
  166.27 +  contributors may be used to endorse or promote products
  166.28 +  derived from this software without specific prior
  166.29 +  written permission of the assimp team.
  166.30 +
  166.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  166.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  166.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  166.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  166.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  166.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  166.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  166.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  166.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  166.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  166.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  166.42 +---------------------------------------------------------------------------
  166.43 +*/
  166.44 +
  166.45 +/** @file  MD5Loader.cpp
  166.46 + *  @brief Implementation of the MD5 importer class 
  166.47 + */
  166.48 +
  166.49 +#include "AssimpPCH.h"
  166.50 +#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
  166.51 +
  166.52 +// internal headers
  166.53 +#include "RemoveComments.h"
  166.54 +#include "MD5Loader.h"
  166.55 +#include "StringComparison.h"
  166.56 +#include "fast_atof.h"
  166.57 +#include "SkeletonMeshBuilder.h"
  166.58 +
  166.59 +using namespace Assimp;
  166.60 +
  166.61 +// Minimum weight value. Weights inside [-n ... n] are ignored
  166.62 +#define AI_MD5_WEIGHT_EPSILON 1e-5f
  166.63 +
  166.64 +
  166.65 +static const aiImporterDesc desc = {
  166.66 +	"Doom 3 / MD5 Mesh Importer",
  166.67 +	"",
  166.68 +	"",
  166.69 +	"",
  166.70 +	aiImporterFlags_SupportBinaryFlavour,
  166.71 +	0,
  166.72 +	0,
  166.73 +	0,
  166.74 +	0,
  166.75 +	"md5mesh md5camera md5anim"
  166.76 +};
  166.77 +
  166.78 +// ------------------------------------------------------------------------------------------------
  166.79 +// Constructor to be privately used by Importer
  166.80 +MD5Importer::MD5Importer()
  166.81 +: mBuffer()
  166.82 +, configNoAutoLoad (false)
  166.83 +{}
  166.84 +
  166.85 +// ------------------------------------------------------------------------------------------------
  166.86 +// Destructor, private as well 
  166.87 +MD5Importer::~MD5Importer()
  166.88 +{}
  166.89 +
  166.90 +// ------------------------------------------------------------------------------------------------
  166.91 +// Returns whether the class can handle the format of the given file. 
  166.92 +bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  166.93 +{
  166.94 +	const std::string extension = GetExtension(pFile);
  166.95 +
  166.96 +	if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera")
  166.97 +		return true;
  166.98 +	else if (!extension.length() || checkSig)	{
  166.99 +		if (!pIOHandler) {
 166.100 +			return true;
 166.101 +		}
 166.102 +		const char* tokens[] = {"MD5Version"};
 166.103 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
 166.104 +	}
 166.105 +	return false;
 166.106 +}
 166.107 +
 166.108 +// ------------------------------------------------------------------------------------------------
 166.109 +// Get list of all supported extensions
 166.110 +const aiImporterDesc* MD5Importer::GetInfo () const
 166.111 +{
 166.112 +	return &desc;
 166.113 +}
 166.114 +
 166.115 +// ------------------------------------------------------------------------------------------------
 166.116 +// Setup import properties
 166.117 +void MD5Importer::SetupProperties(const Importer* pImp)
 166.118 +{
 166.119 +	// AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD
 166.120 +	configNoAutoLoad = (0 !=  pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD,0));
 166.121 +}
 166.122 +
 166.123 +// ------------------------------------------------------------------------------------------------
 166.124 +// Imports the given file into the given scene structure. 
 166.125 +void MD5Importer::InternReadFile( const std::string& pFile, 
 166.126 +								 aiScene* _pScene, IOSystem* _pIOHandler)
 166.127 +{
 166.128 +	pIOHandler = _pIOHandler;
 166.129 +	pScene     = _pScene;
 166.130 +	bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
 166.131 +
 166.132 +	// remove the file extension
 166.133 +	const std::string::size_type pos = pFile.find_last_of('.');
 166.134 +	mFile = (std::string::npos == pos ? pFile : pFile.substr(0,pos+1));
 166.135 +
 166.136 +	const std::string extension = GetExtension(pFile);
 166.137 +	try {
 166.138 +		if (extension == "md5camera") {
 166.139 +			LoadMD5CameraFile();
 166.140 +		}
 166.141 +		else if (configNoAutoLoad || extension == "md5anim") {
 166.142 +			// determine file extension and process just *one* file
 166.143 +			if (extension.length() == 0) {
 166.144 +				throw DeadlyImportError("Failure, need file extension to determine MD5 part type");
 166.145 +			}
 166.146 +			if (extension == "md5anim") {
 166.147 +				LoadMD5AnimFile();
 166.148 +			}
 166.149 +			else if (extension == "md5mesh") {
 166.150 +				LoadMD5MeshFile();
 166.151 +			}
 166.152 +		}
 166.153 +		else {
 166.154 +			LoadMD5MeshFile();
 166.155 +			LoadMD5AnimFile();
 166.156 +		}
 166.157 +	}
 166.158 +	catch ( ... ) { // std::exception, Assimp::DeadlyImportError
 166.159 +		UnloadFileFromMemory();
 166.160 +		throw;
 166.161 +	}
 166.162 +
 166.163 +	// make sure we have at least one file
 166.164 +	if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera) {
 166.165 +		throw DeadlyImportError("Failed to read valid contents out of this MD5* file");
 166.166 +	}
 166.167 +
 166.168 +	// Now rotate the whole scene 90 degrees around the x axis to match our internal coordinate system
 166.169 +	pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
 166.170 +		0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
 166.171 +
 166.172 +	// the output scene wouldn't pass the validation without this flag
 166.173 +	if (!bHadMD5Mesh) {
 166.174 +		pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
 166.175 +	}
 166.176 +
 166.177 +	// clean the instance -- the BaseImporter instance may be reused later.
 166.178 +	UnloadFileFromMemory();
 166.179 +}
 166.180 +
 166.181 +// ------------------------------------------------------------------------------------------------
 166.182 +// Load a file into a memory buffer
 166.183 +void MD5Importer::LoadFileIntoMemory (IOStream* file)
 166.184 +{
 166.185 +	// unload the previous buffer, if any
 166.186 +	UnloadFileFromMemory();
 166.187 +
 166.188 +	ai_assert(NULL != file);
 166.189 +	fileSize = (unsigned int)file->FileSize();
 166.190 +	ai_assert(fileSize);
 166.191 +
 166.192 +	// allocate storage and copy the contents of the file to a memory buffer
 166.193 +	mBuffer = new char[fileSize+1];
 166.194 +	file->Read( (void*)mBuffer, 1, fileSize);
 166.195 +	iLineNumber = 1;
 166.196 +
 166.197 +	// append a terminal 0
 166.198 +	mBuffer[fileSize] = '\0';
 166.199 +
 166.200 +	// now remove all line comments from the file
 166.201 +	CommentRemover::RemoveLineComments("//",mBuffer,' ');
 166.202 +}
 166.203 +
 166.204 +// ------------------------------------------------------------------------------------------------
 166.205 +// Unload the current memory buffer
 166.206 +void MD5Importer::UnloadFileFromMemory ()
 166.207 +{
 166.208 +	// delete the file buffer
 166.209 +	delete[] mBuffer;
 166.210 +	mBuffer = NULL;
 166.211 +	fileSize = 0;
 166.212 +}
 166.213 +
 166.214 +// ------------------------------------------------------------------------------------------------
 166.215 +// Build unique vertices
 166.216 +void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
 166.217 +{
 166.218 +	std::vector<bool> abHad(meshSrc.mVertices.size(),false);
 166.219 +
 166.220 +	// allocate enough storage to keep the output structures
 166.221 +	const unsigned int iNewNum = meshSrc.mFaces.size()*3;
 166.222 +	unsigned int iNewIndex = meshSrc.mVertices.size();
 166.223 +	meshSrc.mVertices.resize(iNewNum);
 166.224 +
 166.225 +	// try to guess how much storage we'll need for new weights
 166.226 +	const float fWeightsPerVert = meshSrc.mWeights.size() / (float)iNewIndex;
 166.227 +	const unsigned int guess = (unsigned int)(fWeightsPerVert*iNewNum); 
 166.228 +	meshSrc.mWeights.reserve(guess + (guess >> 3)); // + 12.5% as buffer
 166.229 +
 166.230 +	for (FaceList::const_iterator iter = meshSrc.mFaces.begin(),iterEnd = meshSrc.mFaces.end();iter != iterEnd;++iter){
 166.231 +		const aiFace& face = *iter;
 166.232 +		for (unsigned int i = 0; i < 3;++i) {
 166.233 +			if (face.mIndices[0] >= meshSrc.mVertices.size()) {
 166.234 +				throw DeadlyImportError("MD5MESH: Invalid vertex index");
 166.235 +			}
 166.236 +
 166.237 +			if (abHad[face.mIndices[i]])	{
 166.238 +				// generate a new vertex
 166.239 +				meshSrc.mVertices[iNewIndex] = meshSrc.mVertices[face.mIndices[i]];
 166.240 +				face.mIndices[i] = iNewIndex++;
 166.241 +			}
 166.242 +			else abHad[face.mIndices[i]] = true;
 166.243 +		}
 166.244 +		// swap face order
 166.245 +		std::swap(face.mIndices[0],face.mIndices[2]);
 166.246 +	}
 166.247 +}
 166.248 +
 166.249 +// ------------------------------------------------------------------------------------------------
 166.250 +// Recursive node graph construction from a MD5MESH
 166.251 +void MD5Importer::AttachChilds_Mesh(int iParentID,aiNode* piParent, BoneList& bones)
 166.252 +{
 166.253 +	ai_assert(NULL != piParent && !piParent->mNumChildren);
 166.254 +
 166.255 +	// First find out how many children we'll have
 166.256 +	for (int i = 0; i < (int)bones.size();++i)	{
 166.257 +		if (iParentID != i && bones[i].mParentIndex == iParentID)	{
 166.258 +			++piParent->mNumChildren;
 166.259 +		}
 166.260 +	}
 166.261 +	if (piParent->mNumChildren)	{
 166.262 +		piParent->mChildren = new aiNode*[piParent->mNumChildren];
 166.263 +		for (int i = 0; i < (int)bones.size();++i)	{
 166.264 +			// (avoid infinite recursion)
 166.265 +			if (iParentID != i && bones[i].mParentIndex == iParentID)	{
 166.266 +				aiNode* pc;
 166.267 +				// setup a new node
 166.268 +				*piParent->mChildren++ = pc = new aiNode();
 166.269 +				pc->mName = aiString(bones[i].mName); 
 166.270 +				pc->mParent = piParent;
 166.271 +
 166.272 +				// get the transformation matrix from rotation and translational components
 166.273 +				aiQuaternion quat; 
 166.274 +				MD5::ConvertQuaternion ( bones[i].mRotationQuat, quat );
 166.275 +
 166.276 +				// FIX to get to Assimp's quaternion conventions
 166.277 +				quat.w *= -1.f;
 166.278 +
 166.279 +				bones[i].mTransform = aiMatrix4x4 ( quat.GetMatrix());
 166.280 +				bones[i].mTransform.a4 = bones[i].mPositionXYZ.x;
 166.281 +				bones[i].mTransform.b4 = bones[i].mPositionXYZ.y;
 166.282 +				bones[i].mTransform.c4 = bones[i].mPositionXYZ.z;
 166.283 +
 166.284 +				// store it for later use
 166.285 +				pc->mTransformation = bones[i].mInvTransform = bones[i].mTransform;
 166.286 +				bones[i].mInvTransform.Inverse();
 166.287 +
 166.288 +				// the transformations for each bone are absolute, so we need to multiply them
 166.289 +				// with the inverse of the absolute matrix of the parent joint
 166.290 +				if (-1 != iParentID)	{
 166.291 +					pc->mTransformation = bones[iParentID].mInvTransform * pc->mTransformation;
 166.292 +				}
 166.293 +
 166.294 +				// add children to this node, too
 166.295 +				AttachChilds_Mesh( i, pc, bones);
 166.296 +			}
 166.297 +		}
 166.298 +		// undo offset computations
 166.299 +		piParent->mChildren -= piParent->mNumChildren;
 166.300 +	}
 166.301 +}
 166.302 +
 166.303 +// ------------------------------------------------------------------------------------------------
 166.304 +// Recursive node graph construction from a MD5ANIM
 166.305 +void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList& bones,const aiNodeAnim** node_anims)
 166.306 +{
 166.307 +	ai_assert(NULL != piParent && !piParent->mNumChildren);
 166.308 +
 166.309 +	// First find out how many children we'll have
 166.310 +	for (int i = 0; i < (int)bones.size();++i)	{
 166.311 +		if (iParentID != i && bones[i].mParentIndex == iParentID)	{
 166.312 +			++piParent->mNumChildren;
 166.313 +		}
 166.314 +	}
 166.315 +	if (piParent->mNumChildren)	{
 166.316 +		piParent->mChildren = new aiNode*[piParent->mNumChildren];
 166.317 +		for (int i = 0; i < (int)bones.size();++i)	{
 166.318 +			// (avoid infinite recursion)
 166.319 +			if (iParentID != i && bones[i].mParentIndex == iParentID)
 166.320 +			{
 166.321 +				aiNode* pc;
 166.322 +				// setup a new node
 166.323 +				*piParent->mChildren++ = pc = new aiNode();
 166.324 +				pc->mName = aiString(bones[i].mName); 
 166.325 +				pc->mParent = piParent;
 166.326 +
 166.327 +				// get the corresponding animation channel and its first frame
 166.328 +				const aiNodeAnim** cur = node_anims;
 166.329 +				while ((**cur).mNodeName != pc->mName)++cur;
 166.330 +
 166.331 +				aiMatrix4x4::Translation((**cur).mPositionKeys[0].mValue,pc->mTransformation);
 166.332 +				pc->mTransformation = pc->mTransformation * aiMatrix4x4((**cur).mRotationKeys[0].mValue.GetMatrix()) ;
 166.333 +
 166.334 +				// add children to this node, too
 166.335 +				AttachChilds_Anim( i, pc, bones,node_anims);
 166.336 +			}
 166.337 +		}
 166.338 +		// undo offset computations
 166.339 +		piParent->mChildren -= piParent->mNumChildren;
 166.340 +	}
 166.341 +}
 166.342 +
 166.343 +// ------------------------------------------------------------------------------------------------
 166.344 +// Load a MD5MESH file
 166.345 +void MD5Importer::LoadMD5MeshFile ()
 166.346 +{
 166.347 +	std::string pFile = mFile + "md5mesh";
 166.348 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 166.349 +
 166.350 +	// Check whether we can read from the file
 166.351 +	if( file.get() == NULL || !file->FileSize())	{
 166.352 +		DefaultLogger::get()->warn("Failed to access MD5MESH file: " + pFile);
 166.353 +		return;
 166.354 +	}
 166.355 +	bHadMD5Mesh = true;
 166.356 +	LoadFileIntoMemory(file.get());
 166.357 +
 166.358 +	// now construct a parser and parse the file
 166.359 +	MD5::MD5Parser parser(mBuffer,fileSize);
 166.360 +
 166.361 +	// load the mesh information from it
 166.362 +	MD5::MD5MeshParser meshParser(parser.mSections);
 166.363 +
 166.364 +	// create the bone hierarchy - first the root node and dummy nodes for all meshes
 166.365 +	pScene->mRootNode = new aiNode("<MD5_Root>");
 166.366 +	pScene->mRootNode->mNumChildren = 2;
 166.367 +	pScene->mRootNode->mChildren = new aiNode*[2];
 166.368 +
 166.369 +	// build the hierarchy from the MD5MESH file
 166.370 +	aiNode* pcNode = pScene->mRootNode->mChildren[1] = new aiNode();
 166.371 +	pcNode->mName.Set("<MD5_Hierarchy>");
 166.372 +	pcNode->mParent = pScene->mRootNode;
 166.373 +	AttachChilds_Mesh(-1,pcNode,meshParser.mJoints);
 166.374 +
 166.375 +	pcNode = pScene->mRootNode->mChildren[0] = new aiNode();
 166.376 +	pcNode->mName.Set("<MD5_Mesh>");
 166.377 +	pcNode->mParent = pScene->mRootNode;
 166.378 +
 166.379 +#if 0
 166.380 +	if (pScene->mRootNode->mChildren[1]->mNumChildren) /* start at the right hierarchy level */
 166.381 +		SkeletonMeshBuilder skeleton_maker(pScene,pScene->mRootNode->mChildren[1]->mChildren[0]);
 166.382 +#else
 166.383 +
 166.384 +	// FIX: MD5 files exported from Blender can have empty meshes
 166.385 +	for (std::vector<MD5::MeshDesc>::const_iterator it  = meshParser.mMeshes.begin(),end = meshParser.mMeshes.end(); it != end;++it) {
 166.386 +		if (!(*it).mFaces.empty() && !(*it).mVertices.empty())
 166.387 +			++pScene->mNumMaterials;
 166.388 +	}
 166.389 +
 166.390 +	// generate all meshes
 166.391 +	pScene->mNumMeshes = pScene->mNumMaterials;
 166.392 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
 166.393 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes];
 166.394 +
 166.395 +	//  storage for node mesh indices
 166.396 +	pcNode->mNumMeshes = pScene->mNumMeshes;
 166.397 +	pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
 166.398 +	for (unsigned int m = 0; m < pcNode->mNumMeshes;++m)
 166.399 +		pcNode->mMeshes[m] = m;
 166.400 +
 166.401 +	unsigned int n = 0;
 166.402 +	for (std::vector<MD5::MeshDesc>::iterator it  = meshParser.mMeshes.begin(),end = meshParser.mMeshes.end(); it != end;++it) {
 166.403 +		MD5::MeshDesc& meshSrc = *it;
 166.404 +		if (meshSrc.mFaces.empty() || meshSrc.mVertices.empty())
 166.405 +			continue;
 166.406 +
 166.407 +		aiMesh* mesh = pScene->mMeshes[n] = new aiMesh();
 166.408 +		mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 166.409 +
 166.410 +		// generate unique vertices in our internal verbose format
 166.411 +		MakeDataUnique(meshSrc);
 166.412 +
 166.413 +		mesh->mNumVertices = (unsigned int) meshSrc.mVertices.size();
 166.414 +		mesh->mVertices = new aiVector3D[mesh->mNumVertices];
 166.415 +		mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
 166.416 +		mesh->mNumUVComponents[0] = 2;
 166.417 +
 166.418 +		// copy texture coordinates
 166.419 +		aiVector3D* pv = mesh->mTextureCoords[0];
 166.420 +		for (MD5::VertexList::const_iterator iter =  meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) {
 166.421 +			pv->x = (*iter).mUV.x;
 166.422 +			pv->y = 1.0f-(*iter).mUV.y; // D3D to OpenGL
 166.423 +			pv->z = 0.0f;
 166.424 +		}
 166.425 +
 166.426 +		// sort all bone weights - per bone
 166.427 +		unsigned int* piCount = new unsigned int[meshParser.mJoints.size()];
 166.428 +		::memset(piCount,0,sizeof(unsigned int)*meshParser.mJoints.size());
 166.429 +
 166.430 +		for (MD5::VertexList::const_iterator iter =  meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) {
 166.431 +			for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w)
 166.432 +			{
 166.433 +				MD5::WeightDesc& desc = meshSrc.mWeights[w];
 166.434 +				/* FIX for some invalid exporters */
 166.435 +				if (!(desc.mWeight < AI_MD5_WEIGHT_EPSILON && desc.mWeight >= -AI_MD5_WEIGHT_EPSILON ))
 166.436 +					++piCount[desc.mBone]; 
 166.437 +			}
 166.438 +		}
 166.439 +
 166.440 +		// check how many we will need
 166.441 +		for (unsigned int p = 0; p < meshParser.mJoints.size();++p)
 166.442 +			if (piCount[p])mesh->mNumBones++;
 166.443 +
 166.444 +		if (mesh->mNumBones) // just for safety
 166.445 +		{
 166.446 +			mesh->mBones = new aiBone*[mesh->mNumBones];
 166.447 +			for (unsigned int q = 0,h = 0; q < meshParser.mJoints.size();++q) 
 166.448 +			{
 166.449 +				if (!piCount[q])continue;
 166.450 +				aiBone* p = mesh->mBones[h] = new aiBone();
 166.451 +				p->mNumWeights = piCount[q];
 166.452 +				p->mWeights = new aiVertexWeight[p->mNumWeights];
 166.453 +				p->mName = aiString(meshParser.mJoints[q].mName);
 166.454 +				p->mOffsetMatrix = meshParser.mJoints[q].mInvTransform;
 166.455 +
 166.456 +				// store the index for later use
 166.457 +				MD5::BoneDesc& boneSrc = meshParser.mJoints[q];
 166.458 +				boneSrc.mMap = h++;
 166.459 +
 166.460 +				// compute w-component of quaternion
 166.461 +				MD5::ConvertQuaternion( boneSrc.mRotationQuat, boneSrc.mRotationQuatConverted );
 166.462 +			}
 166.463 +	
 166.464 +			//unsigned int g = 0;
 166.465 +			pv = mesh->mVertices;
 166.466 +			for (MD5::VertexList::const_iterator iter =  meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) {
 166.467 +				// compute the final vertex position from all single weights
 166.468 +				*pv = aiVector3D();
 166.469 +
 166.470 +				// there are models which have weights which don't sum to 1 ...
 166.471 +				float fSum = 0.0f;
 166.472 +				for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w)
 166.473 +					fSum += meshSrc.mWeights[w].mWeight;
 166.474 +				if (!fSum) {
 166.475 +					DefaultLogger::get()->error("MD5MESH: The sum of all vertex bone weights is 0");
 166.476 +					continue;
 166.477 +				}
 166.478 +
 166.479 +				// process bone weights
 166.480 +				for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w)	{
 166.481 +					if (w >= meshSrc.mWeights.size())
 166.482 +						throw DeadlyImportError("MD5MESH: Invalid weight index");
 166.483 +
 166.484 +					MD5::WeightDesc& desc = meshSrc.mWeights[w];
 166.485 +					if ( desc.mWeight < AI_MD5_WEIGHT_EPSILON && desc.mWeight >= -AI_MD5_WEIGHT_EPSILON) {
 166.486 +						continue;
 166.487 +					}
 166.488 +
 166.489 +					const float fNewWeight = desc.mWeight / fSum; 
 166.490 +
 166.491 +					// transform the local position into worldspace
 166.492 +					MD5::BoneDesc& boneSrc = meshParser.mJoints[desc.mBone];
 166.493 +					const aiVector3D v = boneSrc.mRotationQuatConverted.Rotate (desc.vOffsetPosition);
 166.494 +
 166.495 +					// use the original weight to compute the vertex position
 166.496 +					// (some MD5s seem to depend on the invalid weight values ...)
 166.497 +					*pv += ((boneSrc.mPositionXYZ+v)* desc.mWeight);
 166.498 +			
 166.499 +					aiBone* bone = mesh->mBones[boneSrc.mMap];
 166.500 +					*bone->mWeights++ = aiVertexWeight((unsigned int)(pv-mesh->mVertices),fNewWeight);
 166.501 +				}
 166.502 +			}
 166.503 +
 166.504 +			// undo our nice offset tricks ...
 166.505 +			for (unsigned int p = 0; p < mesh->mNumBones;++p) {
 166.506 +				mesh->mBones[p]->mWeights -= mesh->mBones[p]->mNumWeights;
 166.507 +			}
 166.508 +		}
 166.509 +
 166.510 +		delete[] piCount;
 166.511 +
 166.512 +		// now setup all faces - we can directly copy the list
 166.513 +		// (however, take care that the aiFace destructor doesn't delete the mIndices array)
 166.514 +		mesh->mNumFaces = (unsigned int)meshSrc.mFaces.size();
 166.515 +		mesh->mFaces = new aiFace[mesh->mNumFaces];
 166.516 +		for (unsigned int c = 0; c < mesh->mNumFaces;++c)	{
 166.517 +			mesh->mFaces[c].mNumIndices = 3;
 166.518 +			mesh->mFaces[c].mIndices = meshSrc.mFaces[c].mIndices;
 166.519 +			meshSrc.mFaces[c].mIndices = NULL;
 166.520 +		}
 166.521 +
 166.522 +		// generate a material for the mesh
 166.523 +		aiMaterial* mat = new aiMaterial();
 166.524 +		pScene->mMaterials[n] = mat;
 166.525 +
 166.526 +		// insert the typical doom3 textures:
 166.527 +		// nnn_local.tga  - normal map
 166.528 +		// nnn_h.tga      - height map
 166.529 +		// nnn_s.tga      - specular map
 166.530 +		// nnn_d.tga      - diffuse map
 166.531 +		if (meshSrc.mShader.length && !strchr(meshSrc.mShader.data,'.')) {
 166.532 +		
 166.533 +			aiString temp(meshSrc.mShader);
 166.534 +			temp.Append("_local.tga");
 166.535 +			mat->AddProperty(&temp,AI_MATKEY_TEXTURE_NORMALS(0));
 166.536 +
 166.537 +			temp =  aiString(meshSrc.mShader);
 166.538 +			temp.Append("_s.tga");
 166.539 +			mat->AddProperty(&temp,AI_MATKEY_TEXTURE_SPECULAR(0));
 166.540 +
 166.541 +			temp =  aiString(meshSrc.mShader);
 166.542 +			temp.Append("_d.tga");
 166.543 +			mat->AddProperty(&temp,AI_MATKEY_TEXTURE_DIFFUSE(0));
 166.544 +
 166.545 +			temp =  aiString(meshSrc.mShader);
 166.546 +			temp.Append("_h.tga");
 166.547 +			mat->AddProperty(&temp,AI_MATKEY_TEXTURE_HEIGHT(0));
 166.548 +
 166.549 +			// set this also as material name
 166.550 +			mat->AddProperty(&meshSrc.mShader,AI_MATKEY_NAME);
 166.551 +		}
 166.552 +		else mat->AddProperty(&meshSrc.mShader,AI_MATKEY_TEXTURE_DIFFUSE(0));
 166.553 +		mesh->mMaterialIndex = n++;
 166.554 +	}
 166.555 +#endif
 166.556 +}
 166.557 +
 166.558 +// ------------------------------------------------------------------------------------------------
 166.559 +// Load an MD5ANIM file
 166.560 +void MD5Importer::LoadMD5AnimFile ()
 166.561 +{
 166.562 +	std::string pFile = mFile + "md5anim";
 166.563 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 166.564 +
 166.565 +	// Check whether we can read from the file
 166.566 +	if( !file.get() || !file->FileSize())	{
 166.567 +		DefaultLogger::get()->warn("Failed to read MD5ANIM file: " + pFile);
 166.568 +		return;
 166.569 +	}
 166.570 +	LoadFileIntoMemory(file.get());
 166.571 +
 166.572 +	// parse the basic file structure
 166.573 +	MD5::MD5Parser parser(mBuffer,fileSize);
 166.574 +
 166.575 +	// load the animation information from the parse tree
 166.576 +	MD5::MD5AnimParser animParser(parser.mSections);
 166.577 +
 166.578 +	// generate and fill the output animation
 166.579 +	if (animParser.mAnimatedBones.empty() || animParser.mFrames.empty() || 
 166.580 +		animParser.mBaseFrames.size() != animParser.mAnimatedBones.size())	{
 166.581 +		
 166.582 +		DefaultLogger::get()->error("MD5ANIM: No frames or animated bones loaded");
 166.583 +	}
 166.584 +	else {
 166.585 +		bHadMD5Anim = true;
 166.586 +
 166.587 +		pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations = 1];
 166.588 +		aiAnimation* anim = pScene->mAnimations[0] = new aiAnimation();
 166.589 +		anim->mNumChannels = (unsigned int)animParser.mAnimatedBones.size();
 166.590 +		anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
 166.591 +		for (unsigned int i = 0; i < anim->mNumChannels;++i)	{
 166.592 +			aiNodeAnim* node = anim->mChannels[i] = new aiNodeAnim();
 166.593 +			node->mNodeName = aiString( animParser.mAnimatedBones[i].mName );
 166.594 +
 166.595 +			// allocate storage for the keyframes
 166.596 +			node->mPositionKeys = new aiVectorKey[animParser.mFrames.size()];
 166.597 +			node->mRotationKeys = new aiQuatKey[animParser.mFrames.size()];
 166.598 +		}
 166.599 +
 166.600 +		// 1 tick == 1 frame
 166.601 +		anim->mTicksPerSecond = animParser.fFrameRate;
 166.602 +
 166.603 +		for (FrameList::const_iterator iter = animParser.mFrames.begin(), iterEnd = animParser.mFrames.end();iter != iterEnd;++iter){
 166.604 +			double dTime = (double)(*iter).iIndex;
 166.605 +			aiNodeAnim** pcAnimNode = anim->mChannels;
 166.606 +			if (!(*iter).mValues.empty() || iter == animParser.mFrames.begin()) /* be sure we have at least one frame */
 166.607 +			{
 166.608 +				// now process all values in there ... read all joints
 166.609 +				MD5::BaseFrameDesc* pcBaseFrame = &animParser.mBaseFrames[0];
 166.610 +				for (AnimBoneList::const_iterator iter2	= animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end();++iter2,
 166.611 +					++pcAnimNode,++pcBaseFrame)
 166.612 +				{
 166.613 +					if((*iter2).iFirstKeyIndex >= (*iter).mValues.size()) {
 166.614 +
 166.615 +						// Allow for empty frames
 166.616 +						if ((*iter2).iFlags != 0) {
 166.617 +							throw DeadlyImportError("MD5: Keyframe index is out of range");
 166.618 +						
 166.619 +						}
 166.620 +						continue;
 166.621 +					}
 166.622 +					const float* fpCur = &(*iter).mValues[(*iter2).iFirstKeyIndex];
 166.623 +					aiNodeAnim* pcCurAnimBone = *pcAnimNode;
 166.624 +
 166.625 +					aiVectorKey* vKey = &pcCurAnimBone->mPositionKeys[pcCurAnimBone->mNumPositionKeys++];
 166.626 +					aiQuatKey* qKey = &pcCurAnimBone->mRotationKeys  [pcCurAnimBone->mNumRotationKeys++];
 166.627 +					aiVector3D vTemp;
 166.628 +
 166.629 +					// translational component
 166.630 +					for (unsigned int i = 0; i < 3; ++i) {
 166.631 +						if ((*iter2).iFlags & (1u << i)) {
 166.632 +							vKey->mValue[i] =  *fpCur++;
 166.633 +						}
 166.634 +						else vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
 166.635 +					}
 166.636 +
 166.637 +					// orientation component
 166.638 +					for (unsigned int i = 0; i < 3; ++i) {
 166.639 +						if ((*iter2).iFlags & (8u << i)) {
 166.640 +							vTemp[i] =  *fpCur++;
 166.641 +						}
 166.642 +						else vTemp[i] = pcBaseFrame->vRotationQuat[i];
 166.643 +					}
 166.644 +
 166.645 +					MD5::ConvertQuaternion(vTemp, qKey->mValue);
 166.646 +					qKey->mTime = vKey->mTime = dTime;
 166.647 +
 166.648 +					// we need this to get to Assimp quaternion conventions
 166.649 +					qKey->mValue.w *= -1.f;
 166.650 +				}
 166.651 +			}
 166.652 +
 166.653 +			// compute the duration of the animation
 166.654 +			anim->mDuration = std::max(dTime,anim->mDuration);
 166.655 +		}
 166.656 +
 166.657 +		// If we didn't build the hierarchy yet (== we didn't load a MD5MESH),
 166.658 +		// construct it now from the data given in the MD5ANIM.
 166.659 +		if (!pScene->mRootNode) {
 166.660 +			pScene->mRootNode = new aiNode();
 166.661 +			pScene->mRootNode->mName.Set("<MD5_Hierarchy>");
 166.662 +
 166.663 +			AttachChilds_Anim(-1,pScene->mRootNode,animParser.mAnimatedBones,(const aiNodeAnim**)anim->mChannels);
 166.664 +
 166.665 +			// Call SkeletonMeshBuilder to construct a mesh to represent the shape
 166.666 +			if (pScene->mRootNode->mNumChildren) {
 166.667 +				SkeletonMeshBuilder skeleton_maker(pScene,pScene->mRootNode->mChildren[0]);
 166.668 +			}
 166.669 +		}
 166.670 +	}
 166.671 +}
 166.672 +
 166.673 +// ------------------------------------------------------------------------------------------------
 166.674 +// Load an MD5CAMERA file
 166.675 +void MD5Importer::LoadMD5CameraFile ()
 166.676 +{
 166.677 +	std::string pFile = mFile + "md5camera";
 166.678 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 166.679 +
 166.680 +	// Check whether we can read from the file
 166.681 +	if( !file.get() || !file->FileSize())	{
 166.682 +		throw DeadlyImportError("Failed to read MD5CAMERA file: " + pFile);
 166.683 +	}
 166.684 +	bHadMD5Camera = true;
 166.685 +	LoadFileIntoMemory(file.get());
 166.686 +
 166.687 +	// parse the basic file structure
 166.688 +	MD5::MD5Parser parser(mBuffer,fileSize);
 166.689 +
 166.690 +	// load the camera animation data from the parse tree
 166.691 +	MD5::MD5CameraParser cameraParser(parser.mSections);
 166.692 +
 166.693 +	if (cameraParser.frames.empty()) {
 166.694 +		throw DeadlyImportError("MD5CAMERA: No frames parsed");
 166.695 +	}
 166.696 +
 166.697 +	std::vector<unsigned int>& cuts = cameraParser.cuts;
 166.698 +	std::vector<MD5::CameraAnimFrameDesc>& frames = cameraParser.frames;
 166.699 +
 166.700 +	// Construct output graph - a simple root with a dummy child.
 166.701 +	// The root node performs the coordinate system conversion
 166.702 +	aiNode* root = pScene->mRootNode = new aiNode("<MD5CameraRoot>");
 166.703 +	root->mChildren = new aiNode*[root->mNumChildren = 1];
 166.704 +	root->mChildren[0] = new aiNode("<MD5Camera>");
 166.705 +	root->mChildren[0]->mParent = root;
 166.706 +
 166.707 +	// ... but with one camera assigned to it
 166.708 +	pScene->mCameras = new aiCamera*[pScene->mNumCameras = 1];
 166.709 +	aiCamera* cam = pScene->mCameras[0] = new aiCamera();
 166.710 +	cam->mName = "<MD5Camera>";
 166.711 +
 166.712 +	// FIXME: Fov is currently set to the first frame's value
 166.713 +	cam->mHorizontalFOV = AI_DEG_TO_RAD( frames.front().fFOV );
 166.714 +
 166.715 +	// every cut is written to a separate aiAnimation
 166.716 +	if (!cuts.size()) {
 166.717 +		cuts.push_back(0);
 166.718 +		cuts.push_back(frames.size()-1);
 166.719 +	}
 166.720 +	else {		
 166.721 +		cuts.insert(cuts.begin(),0);
 166.722 +
 166.723 +		if (cuts.back() < frames.size()-1)
 166.724 +			cuts.push_back(frames.size()-1);
 166.725 +	}
 166.726 +
 166.727 +	pScene->mNumAnimations = cuts.size()-1;
 166.728 +	aiAnimation** tmp = pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations];
 166.729 +	for (std::vector<unsigned int>::const_iterator it = cuts.begin(); it != cuts.end()-1; ++it) {
 166.730 +	
 166.731 +		aiAnimation* anim = *tmp++ = new aiAnimation();
 166.732 +		anim->mName.length = ::sprintf(anim->mName.data,"anim%u_from_%u_to_%u",(unsigned int)(it-cuts.begin()),(*it),*(it+1));
 166.733 +		
 166.734 +		anim->mTicksPerSecond = cameraParser.fFrameRate;
 166.735 +		anim->mChannels = new aiNodeAnim*[anim->mNumChannels = 1];
 166.736 +		aiNodeAnim* nd  = anim->mChannels[0] = new aiNodeAnim();
 166.737 +		nd->mNodeName.Set("<MD5Camera>");
 166.738 +
 166.739 +		nd->mNumPositionKeys = nd->mNumRotationKeys = *(it+1) - (*it);
 166.740 +		nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
 166.741 +		nd->mRotationKeys = new aiQuatKey  [nd->mNumRotationKeys];
 166.742 +		for (unsigned int i = 0; i < nd->mNumPositionKeys; ++i) {
 166.743 +
 166.744 +			nd->mPositionKeys[i].mValue = frames[*it+i].vPositionXYZ;
 166.745 +			MD5::ConvertQuaternion(frames[*it+i].vRotationQuat,nd->mRotationKeys[i].mValue);
 166.746 +			nd->mRotationKeys[i].mTime = nd->mPositionKeys[i].mTime = *it+i;
 166.747 +		}
 166.748 +	}
 166.749 +}
 166.750 +
 166.751 +#endif // !! ASSIMP_BUILD_NO_MD5_IMPORTER
   167.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   167.2 +++ b/libs/assimp/MD5Loader.h	Sat Feb 01 19:58:19 2014 +0200
   167.3 @@ -0,0 +1,190 @@
   167.4 +/*
   167.5 +Open Asset Import Library (assimp)
   167.6 +----------------------------------------------------------------------
   167.7 +
   167.8 +Copyright (c) 2006-2012, assimp team
   167.9 +All rights reserved.
  167.10 +
  167.11 +Redistribution and use of this software in source and binary forms, 
  167.12 +with or without modification, are permitted provided that the 
  167.13 +following conditions are met:
  167.14 +
  167.15 +* Redistributions of source code must retain the above
  167.16 +  copyright notice, this list of conditions and the
  167.17 +  following disclaimer.
  167.18 +
  167.19 +* Redistributions in binary form must reproduce the above
  167.20 +  copyright notice, this list of conditions and the
  167.21 +  following disclaimer in the documentation and/or other
  167.22 +  materials provided with the distribution.
  167.23 +
  167.24 +* Neither the name of the assimp team, nor the names of its
  167.25 +  contributors may be used to endorse or promote products
  167.26 +  derived from this software without specific prior
  167.27 +  written permission of the assimp team.
  167.28 +
  167.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  167.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  167.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  167.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  167.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  167.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  167.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  167.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  167.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  167.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  167.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  167.40 +
  167.41 +----------------------------------------------------------------------
  167.42 +*/
  167.43 +
  167.44 +
  167.45 +/** @file   MD5Loader.h
  167.46 + *  @brief Definition of the .MD5 importer class.
  167.47 + *  http://www.modwiki.net/wiki/MD5_(file_format)
  167.48 +*/
  167.49 +#ifndef AI_MD5LOADER_H_INCLUDED
  167.50 +#define AI_MD5LOADER_H_INCLUDED
  167.51 +
  167.52 +#include "BaseImporter.h"
  167.53 +#include "MD5Parser.h"
  167.54 +
  167.55 +#include "assimp/types.h"
  167.56 +
  167.57 +namespace Assimp	{
  167.58 +
  167.59 +class IOStream;
  167.60 +using namespace Assimp::MD5;
  167.61 +
  167.62 +// ---------------------------------------------------------------------------
  167.63 +/** Importer class for the MD5 file format
  167.64 +*/
  167.65 +class MD5Importer : public BaseImporter
  167.66 +{
  167.67 +public:
  167.68 +	MD5Importer();
  167.69 +	~MD5Importer();
  167.70 +
  167.71 +
  167.72 +public:
  167.73 +
  167.74 +	// -------------------------------------------------------------------
  167.75 +	/** Returns whether the class can handle the format of the given file. 
  167.76 +	 * See BaseImporter::CanRead() for details.
  167.77 + 	 */
  167.78 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  167.79 +		bool checkSig) const;
  167.80 +
  167.81 +protected:
  167.82 +
  167.83 +	// -------------------------------------------------------------------
  167.84 +	/** Return importer meta information.
  167.85 +	 * See #BaseImporter::GetInfo for the details
  167.86 +	 */
  167.87 +	const aiImporterDesc* GetInfo () const;
  167.88 +
  167.89 +	// -------------------------------------------------------------------
  167.90 +	/** Called prior to ReadFile().
  167.91 +	 * The function is a request to the importer to update its configuration
  167.92 +	 * basing on the Importer's configuration property list.
  167.93 +	 */
  167.94 +	void SetupProperties(const Importer* pImp);
  167.95 +	
  167.96 +	// -------------------------------------------------------------------
  167.97 +	/** Imports the given file into the given scene structure. 
  167.98 +	 * See BaseImporter::InternReadFile() for details
  167.99 +	 */
 167.100 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
 167.101 +		IOSystem* pIOHandler);
 167.102 +
 167.103 +protected:
 167.104 +
 167.105 +
 167.106 +	// -------------------------------------------------------------------
 167.107 +	/** Load a *.MD5MESH file.
 167.108 +	 */
 167.109 +	void LoadMD5MeshFile ();
 167.110 +
 167.111 +	// -------------------------------------------------------------------
 167.112 +	/** Load a *.MD5ANIM file.
 167.113 +	 */
 167.114 +	void LoadMD5AnimFile ();
 167.115 +
 167.116 +	// -------------------------------------------------------------------
 167.117 +	/** Load a *.MD5CAMERA file.
 167.118 +	 */
 167.119 +	void LoadMD5CameraFile ();
 167.120 +
 167.121 +	// -------------------------------------------------------------------
 167.122 +	/** Construct node hierarchy from a given MD5ANIM 
 167.123 +	 *  @param iParentID Current parent ID
 167.124 +	 *  @param piParent Parent node to attach to
 167.125 +	 *  @param bones Input bones
 167.126 +	 *  @param node_anims Generated node animations
 167.127 +	*/
 167.128 +	void AttachChilds_Anim(int iParentID,aiNode* piParent, 
 167.129 +		AnimBoneList& bones,const aiNodeAnim** node_anims);
 167.130 +
 167.131 +	// -------------------------------------------------------------------
 167.132 +	/** Construct node hierarchy from a given MD5MESH 
 167.133 +	 *  @param iParentID Current parent ID
 167.134 +	 *  @param piParent Parent node to attach to
 167.135 +	 *  @param bones Input bones
 167.136 +	*/
 167.137 +	void AttachChilds_Mesh(int iParentID,aiNode* piParent,BoneList& bones);
 167.138 +
 167.139 +	// -------------------------------------------------------------------
 167.140 +	/** Build unique vertex buffers from a given MD5ANIM
 167.141 +	 *  @param meshSrc Input data
 167.142 +	 */
 167.143 +	void MakeDataUnique (MD5::MeshDesc& meshSrc);
 167.144 +
 167.145 +	// -------------------------------------------------------------------
 167.146 +	/** Load the contents of a specific file into memory and
 167.147 +	 *  alocates a buffer to keep it.
 167.148 +	 *
 167.149 +	 *  mBuffer is modified to point to this buffer.
 167.150 +	 *  @param pFile File stream to be read
 167.151 +	*/
 167.152 +	void LoadFileIntoMemory (IOStream* pFile);
 167.153 +	void UnloadFileFromMemory ();
 167.154 +
 167.155 +
 167.156 +	/** IOSystem to be used to access files */
 167.157 +	IOSystem* mIOHandler;
 167.158 +
 167.159 +	/** Path to the file, excluding the file extension but
 167.160 +	    with the dot */
 167.161 +	std::string mFile;
 167.162 +
 167.163 +	/** Buffer to hold the loaded file */
 167.164 +	char* mBuffer;
 167.165 +
 167.166 +	/** Size of the file */
 167.167 +	unsigned int fileSize;
 167.168 +
 167.169 +	/** Current line number. For debugging purposes */
 167.170 +	unsigned int iLineNumber;
 167.171 +
 167.172 +	/** Scene to be filled */
 167.173 +	aiScene* pScene;
 167.174 +
 167.175 +	/** (Custom) I/O handler implementation */
 167.176 +	IOSystem* pIOHandler;
 167.177 +
 167.178 +	/** true if a MD5MESH file has already been parsed */
 167.179 +	bool bHadMD5Mesh;
 167.180 +
 167.181 +	/** true if a MD5ANIM file has already been parsed */
 167.182 +	bool bHadMD5Anim;
 167.183 +
 167.184 +	/** true if a MD5CAMERA file has already been parsed */
 167.185 +	bool bHadMD5Camera;
 167.186 +
 167.187 +	/** configuration option: prevent anim autoload */
 167.188 +	bool configNoAutoLoad;
 167.189 +};
 167.190 +
 167.191 +} // end of namespace Assimp
 167.192 +
 167.193 +#endif // AI_3DSIMPORTER_H_INC
   168.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   168.2 +++ b/libs/assimp/MD5Parser.cpp	Sat Feb 01 19:58:19 2014 +0200
   168.3 @@ -0,0 +1,473 @@
   168.4 +/*
   168.5 +---------------------------------------------------------------------------
   168.6 +Open Asset Import Library (assimp)
   168.7 +---------------------------------------------------------------------------
   168.8 +
   168.9 +Copyright (c) 2006-2012, assimp team
  168.10 +
  168.11 +All rights reserved.
  168.12 +
  168.13 +Redistribution and use of this software in source and binary forms, 
  168.14 +with or without modification, are permitted provided that the following 
  168.15 +conditions are met:
  168.16 +
  168.17 +* Redistributions of source code must retain the above
  168.18 +  copyright notice, this list of conditions and the
  168.19 +  following disclaimer.
  168.20 +
  168.21 +* Redistributions in binary form must reproduce the above
  168.22 +  copyright notice, this list of conditions and the
  168.23 +  following disclaimer in the documentation and/or other
  168.24 +  materials provided with the distribution.
  168.25 +
  168.26 +* Neither the name of the assimp team, nor the names of its
  168.27 +  contributors may be used to endorse or promote products
  168.28 +  derived from this software without specific prior
  168.29 +  written permission of the assimp team.
  168.30 +
  168.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  168.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  168.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  168.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  168.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  168.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  168.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  168.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  168.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  168.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  168.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  168.42 +---------------------------------------------------------------------------
  168.43 +*/
  168.44 +
  168.45 +/** @file  MD5Parser.cpp 
  168.46 + *  @brief Implementation of the MD5 parser class
  168.47 + */
  168.48 +#include "AssimpPCH.h"
  168.49 +
  168.50 +// internal headers
  168.51 +#include "MD5Loader.h"
  168.52 +#include "MaterialSystem.h"
  168.53 +#include "fast_atof.h"
  168.54 +#include "ParsingUtils.h"
  168.55 +#include "StringComparison.h"
  168.56 +
  168.57 +using namespace Assimp;
  168.58 +using namespace Assimp::MD5;
  168.59 +
  168.60 +// ------------------------------------------------------------------------------------------------
  168.61 +// Parse the segment structure fo a MD5 file
  168.62 +MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
  168.63 +{
  168.64 +	ai_assert(NULL != _buffer && 0 != _fileSize);
  168.65 +
  168.66 +	buffer = _buffer;
  168.67 +	fileSize = _fileSize;
  168.68 +	lineNumber = 0;
  168.69 +
  168.70 +	DefaultLogger::get()->debug("MD5Parser begin");
  168.71 +
  168.72 +	// parse the file header
  168.73 +	ParseHeader();
  168.74 +
  168.75 +	// and read all sections until we're finished
  168.76 +	bool running = true;
  168.77 +	while (running)	{
  168.78 +		mSections.push_back(Section());
  168.79 +		Section& sec = mSections.back();
  168.80 +		if(!ParseSection(sec))	{
  168.81 +			break;
  168.82 +		}
  168.83 +	}
  168.84 +
  168.85 +	if ( !DefaultLogger::isNullLogger())	{
  168.86 +		char szBuffer[128]; // should be sufficiently large
  168.87 +		::sprintf(szBuffer,"MD5Parser end. Parsed %i sections",(int)mSections.size());
  168.88 +		DefaultLogger::get()->debug(szBuffer);
  168.89 +	}
  168.90 +}
  168.91 +
  168.92 +// ------------------------------------------------------------------------------------------------
  168.93 +// Report error to the log stream
  168.94 +/*static*/ void MD5Parser::ReportError (const char* error, unsigned int line)
  168.95 +{
  168.96 +	char szBuffer[1024];
  168.97 +	::sprintf(szBuffer,"[MD5] Line %i: %s",line,error);
  168.98 +	throw DeadlyImportError(szBuffer);
  168.99 +}
 168.100 +
 168.101 +// ------------------------------------------------------------------------------------------------
 168.102 +// Report warning to the log stream
 168.103 +/*static*/ void MD5Parser::ReportWarning (const char* warn, unsigned int line)
 168.104 +{
 168.105 +	char szBuffer[1024]; 
 168.106 +	::sprintf(szBuffer,"[MD5] Line %i: %s",line,warn);
 168.107 +	DefaultLogger::get()->warn(szBuffer);
 168.108 +}
 168.109 +
 168.110 +// ------------------------------------------------------------------------------------------------
 168.111 +// Parse and validate the MD5 header
 168.112 +void MD5Parser::ParseHeader()
 168.113 +{
 168.114 +	// parse and validate the file version
 168.115 +	SkipSpaces();
 168.116 +	if (!TokenMatch(buffer,"MD5Version",10))	{
 168.117 +		ReportError("Invalid MD5 file: MD5Version tag has not been found");
 168.118 +	}
 168.119 +	SkipSpaces();
 168.120 +	unsigned int iVer = ::strtoul10(buffer,(const char**)&buffer);
 168.121 +	if (10 != iVer)	{
 168.122 +		ReportError("MD5 version tag is unknown (10 is expected)");
 168.123 +	}
 168.124 +	SkipLine();
 168.125 +
 168.126 +	// print the command line options to the console
 168.127 +	// FIX: can break the log length limit, so we need to be careful
 168.128 +	char* sz = buffer;
 168.129 +	while (!IsLineEnd( *buffer++));
 168.130 +	DefaultLogger::get()->info(std::string(sz,std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer-sz))));
 168.131 +	SkipSpacesAndLineEnd();
 168.132 +}
 168.133 +
 168.134 +// ------------------------------------------------------------------------------------------------
 168.135 +// Recursive MD5 parsing function
 168.136 +bool MD5Parser::ParseSection(Section& out)
 168.137 +{
 168.138 +	// store the current line number for use in error messages
 168.139 +	out.iLineNumber = lineNumber;
 168.140 +
 168.141 +	// first parse the name of the section
 168.142 +	char* sz = buffer;
 168.143 +	while (!IsSpaceOrNewLine( *buffer))buffer++;
 168.144 +	out.mName = std::string(sz,(uintptr_t)(buffer-sz));
 168.145 +	SkipSpaces();
 168.146 +
 168.147 +	bool running = true;
 168.148 +	while (running)	{
 168.149 +		if ('{' == *buffer)	{
 168.150 +			// it is a normal section so read all lines
 168.151 +			buffer++;
 168.152 +			bool run = true;
 168.153 +			while (run)
 168.154 +			{
 168.155 +				if (!SkipSpacesAndLineEnd()) {
 168.156 +					return false; // seems this was the last section
 168.157 +				}
 168.158 +				if ('}' == *buffer)	{
 168.159 +					buffer++;
 168.160 +					break;
 168.161 +				}
 168.162 +
 168.163 +				out.mElements.push_back(Element());
 168.164 +				Element& elem = out.mElements.back();
 168.165 +
 168.166 +				elem.iLineNumber = lineNumber;
 168.167 +				elem.szStart = buffer;
 168.168 +
 168.169 +				// terminate the line with zero 
 168.170 +				while (!IsLineEnd( *buffer))buffer++;
 168.171 +				if (*buffer) {
 168.172 +					++lineNumber;
 168.173 +					*buffer++ = '\0';
 168.174 +				}
 168.175 +			}
 168.176 +			break;
 168.177 +		}
 168.178 +		else if (!IsSpaceOrNewLine(*buffer))	{
 168.179 +			// it is an element at global scope. Parse its value and go on
 168.180 +			sz = buffer;
 168.181 +			while (!IsSpaceOrNewLine( *buffer++));
 168.182 +			out.mGlobalValue = std::string(sz,(uintptr_t)(buffer-sz));
 168.183 +			continue;
 168.184 +		}
 168.185 +		break;
 168.186 +	}
 168.187 +	return SkipSpacesAndLineEnd();
 168.188 +}
 168.189 +
 168.190 +// ------------------------------------------------------------------------------------------------
 168.191 +// Some dirty macros just because they're so funny and easy to debug
 168.192 +
 168.193 +// skip all spaces ... handle EOL correctly
 168.194 +#define	AI_MD5_SKIP_SPACES()  if(!SkipSpaces(&sz)) \
 168.195 +	MD5Parser::ReportWarning("Unexpected end of line",(*eit).iLineNumber);
 168.196 +
 168.197 +	// read a triple float in brackets: (1.0 1.0 1.0)
 168.198 +#define AI_MD5_READ_TRIPLE(vec) \
 168.199 +	AI_MD5_SKIP_SPACES(); \
 168.200 +	if ('(' != *sz++) \
 168.201 +		MD5Parser::ReportWarning("Unexpected token: ( was expected",(*eit).iLineNumber); \
 168.202 +	AI_MD5_SKIP_SPACES(); \
 168.203 +	sz = fast_atoreal_move<float>(sz,(float&)vec.x); \
 168.204 +	AI_MD5_SKIP_SPACES(); \
 168.205 +	sz = fast_atoreal_move<float>(sz,(float&)vec.y); \
 168.206 +	AI_MD5_SKIP_SPACES(); \
 168.207 +	sz = fast_atoreal_move<float>(sz,(float&)vec.z); \
 168.208 +	AI_MD5_SKIP_SPACES(); \
 168.209 +	if (')' != *sz++) \
 168.210 +		MD5Parser::ReportWarning("Unexpected token: ) was expected",(*eit).iLineNumber);
 168.211 +
 168.212 +	// parse a string, enclosed in quotation marks or not
 168.213 +#define AI_MD5_PARSE_STRING(out) \
 168.214 +	bool bQuota = (*sz == '\"'); \
 168.215 +	const char* szStart = sz; \
 168.216 +	while (!IsSpaceOrNewLine(*sz))++sz; \
 168.217 +	const char* szEnd = sz; \
 168.218 +	if (bQuota) { \
 168.219 +		szStart++; \
 168.220 +		if ('\"' != *(szEnd-=1)) { \
 168.221 +			MD5Parser::ReportWarning("Expected closing quotation marks in string", \
 168.222 +				(*eit).iLineNumber); \
 168.223 +			continue; \
 168.224 +		} \
 168.225 +	} \
 168.226 +	out.length = (size_t)(szEnd - szStart); \
 168.227 +	::memcpy(out.data,szStart,out.length); \
 168.228 +	out.data[out.length] = '\0';
 168.229 +
 168.230 +// ------------------------------------------------------------------------------------------------
 168.231 +// .MD5MESH parsing function
 168.232 +MD5MeshParser::MD5MeshParser(SectionList& mSections)
 168.233 +{
 168.234 +	DefaultLogger::get()->debug("MD5MeshParser begin");
 168.235 +
 168.236 +	// now parse all sections
 168.237 +	for (SectionList::const_iterator iter =  mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter){
 168.238 +		if ( (*iter).mName == "numMeshes")	{
 168.239 +			mMeshes.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
 168.240 +		}
 168.241 +		else if ( (*iter).mName == "numJoints")	{
 168.242 +			mJoints.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
 168.243 +		}
 168.244 +		else if ((*iter).mName == "joints")	{
 168.245 +			// "origin"	-1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 )
 168.246 +			for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end();eit != eitEnd; ++eit){
 168.247 +				mJoints.push_back(BoneDesc());
 168.248 +				BoneDesc& desc = mJoints.back();
 168.249 +
 168.250 +				const char* sz = (*eit).szStart;
 168.251 +				AI_MD5_PARSE_STRING(desc.mName);
 168.252 +				AI_MD5_SKIP_SPACES();
 168.253 +
 168.254 +				// negative values, at least -1, is allowed here
 168.255 +				desc.mParentIndex = (int)strtol10(sz,&sz);
 168.256 +		
 168.257 +				AI_MD5_READ_TRIPLE(desc.mPositionXYZ);
 168.258 +				AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
 168.259 +			}
 168.260 +		}
 168.261 +		else if ((*iter).mName == "mesh")	{
 168.262 +			mMeshes.push_back(MeshDesc());
 168.263 +			MeshDesc& desc = mMeshes.back();
 168.264 +
 168.265 +			for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end();eit != eitEnd; ++eit){
 168.266 +				const char* sz = (*eit).szStart;
 168.267 +
 168.268 +				// shader attribute
 168.269 +				if (TokenMatch(sz,"shader",6))	{
 168.270 +					AI_MD5_SKIP_SPACES();
 168.271 +					AI_MD5_PARSE_STRING(desc.mShader);
 168.272 +				}
 168.273 +				// numverts attribute
 168.274 +				else if (TokenMatch(sz,"numverts",8))	{
 168.275 +					AI_MD5_SKIP_SPACES();
 168.276 +					desc.mVertices.resize(strtoul10(sz));
 168.277 +				}
 168.278 +				// numtris attribute
 168.279 +				else if (TokenMatch(sz,"numtris",7))	{
 168.280 +					AI_MD5_SKIP_SPACES();
 168.281 +					desc.mFaces.resize(strtoul10(sz));
 168.282 +				}
 168.283 +				// numweights attribute
 168.284 +				else if (TokenMatch(sz,"numweights",10))	{
 168.285 +					AI_MD5_SKIP_SPACES();
 168.286 +					desc.mWeights.resize(strtoul10(sz));
 168.287 +				}
 168.288 +				// vert attribute
 168.289 +				// "vert 0 ( 0.394531 0.513672 ) 0 1"
 168.290 +				else if (TokenMatch(sz,"vert",4))	{
 168.291 +					AI_MD5_SKIP_SPACES();
 168.292 +					const unsigned int idx = ::strtoul10(sz,&sz);
 168.293 +					AI_MD5_SKIP_SPACES();
 168.294 +					if (idx >= desc.mVertices.size())
 168.295 +						desc.mVertices.resize(idx+1);
 168.296 +
 168.297 +					VertexDesc& vert = desc.mVertices[idx];	
 168.298 +					if ('(' != *sz++)
 168.299 +						MD5Parser::ReportWarning("Unexpected token: ( was expected",(*eit).iLineNumber);
 168.300 +					AI_MD5_SKIP_SPACES();
 168.301 +					sz = fast_atoreal_move<float>(sz,(float&)vert.mUV.x);
 168.302 +					AI_MD5_SKIP_SPACES();
 168.303 +					sz = fast_atoreal_move<float>(sz,(float&)vert.mUV.y);
 168.304 +					AI_MD5_SKIP_SPACES();
 168.305 +					if (')' != *sz++)
 168.306 +						MD5Parser::ReportWarning("Unexpected token: ) was expected",(*eit).iLineNumber);
 168.307 +					AI_MD5_SKIP_SPACES();
 168.308 +					vert.mFirstWeight = ::strtoul10(sz,&sz);
 168.309 +					AI_MD5_SKIP_SPACES();
 168.310 +					vert.mNumWeights = ::strtoul10(sz,&sz);
 168.311 +				}
 168.312 +				// tri attribute
 168.313 +				// "tri 0 15 13 12"
 168.314 +				else if (TokenMatch(sz,"tri",3)) {
 168.315 +					AI_MD5_SKIP_SPACES();
 168.316 +					const unsigned int idx = strtoul10(sz,&sz);
 168.317 +					if (idx >= desc.mFaces.size())
 168.318 +						desc.mFaces.resize(idx+1);
 168.319 +
 168.320 +					aiFace& face = desc.mFaces[idx];	
 168.321 +					face.mIndices = new unsigned int[face.mNumIndices = 3];
 168.322 +					for (unsigned int i = 0; i < 3;++i)	{
 168.323 +						AI_MD5_SKIP_SPACES();
 168.324 +						face.mIndices[i] = strtoul10(sz,&sz);
 168.325 +					}
 168.326 +				}
 168.327 +				// weight attribute
 168.328 +				// "weight 362 5 0.500000 ( -3.553583 11.893474 9.719339 )"
 168.329 +				else if (TokenMatch(sz,"weight",6))	{
 168.330 +					AI_MD5_SKIP_SPACES();
 168.331 +					const unsigned int idx = strtoul10(sz,&sz);
 168.332 +					AI_MD5_SKIP_SPACES();
 168.333 +					if (idx >= desc.mWeights.size())
 168.334 +						desc.mWeights.resize(idx+1);
 168.335 +
 168.336 +					WeightDesc& weight = desc.mWeights[idx];	
 168.337 +					weight.mBone = strtoul10(sz,&sz);
 168.338 +					AI_MD5_SKIP_SPACES();
 168.339 +					sz = fast_atoreal_move<float>(sz,weight.mWeight);
 168.340 +					AI_MD5_READ_TRIPLE(weight.vOffsetPosition);
 168.341 +				}
 168.342 +			}
 168.343 +		}
 168.344 +	}
 168.345 +	DefaultLogger::get()->debug("MD5MeshParser end");
 168.346 +}
 168.347 +
 168.348 +// ------------------------------------------------------------------------------------------------
 168.349 +// .MD5ANIM parsing function
 168.350 +MD5AnimParser::MD5AnimParser(SectionList& mSections)
 168.351 +{
 168.352 +	DefaultLogger::get()->debug("MD5AnimParser begin");
 168.353 +
 168.354 +	fFrameRate = 24.0f;
 168.355 +	mNumAnimatedComponents = UINT_MAX;
 168.356 +	for (SectionList::const_iterator iter =  mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
 168.357 +		if ((*iter).mName == "hierarchy")	{
 168.358 +			// "sheath"	0 63 6 
 168.359 +			for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end();eit != eitEnd; ++eit) {
 168.360 +				mAnimatedBones.push_back ( AnimBoneDesc () );
 168.361 +				AnimBoneDesc& desc = mAnimatedBones.back();
 168.362 +
 168.363 +				const char* sz = (*eit).szStart;
 168.364 +				AI_MD5_PARSE_STRING(desc.mName);
 168.365 +				AI_MD5_SKIP_SPACES();
 168.366 +
 168.367 +				// parent index - negative values are allowed (at least -1)
 168.368 +				desc.mParentIndex = ::strtol10(sz,&sz);
 168.369 +
 168.370 +				// flags (highest is 2^6-1)
 168.371 +				AI_MD5_SKIP_SPACES();
 168.372 +				if(63 < (desc.iFlags = ::strtoul10(sz,&sz))){
 168.373 +					MD5Parser::ReportWarning("Invalid flag combination in hierarchy section",(*eit).iLineNumber);
 168.374 +				}
 168.375 +				AI_MD5_SKIP_SPACES();
 168.376 +
 168.377 +				// index of the first animation keyframe component for this joint
 168.378 +				desc.iFirstKeyIndex = ::strtoul10(sz,&sz);
 168.379 +			}
 168.380 +		}
 168.381 +		else if((*iter).mName == "baseframe")	{
 168.382 +			// ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000242 0.707107 )
 168.383 +			for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit) {
 168.384 +				const char* sz = (*eit).szStart;
 168.385 +
 168.386 +				mBaseFrames.push_back ( BaseFrameDesc () );
 168.387 +				BaseFrameDesc& desc = mBaseFrames.back();
 168.388 +
 168.389 +				AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
 168.390 +				AI_MD5_READ_TRIPLE(desc.vRotationQuat);
 168.391 +			}
 168.392 +		}
 168.393 +		else if((*iter).mName ==  "frame")	{
 168.394 +			if (!(*iter).mGlobalValue.length())	{
 168.395 +				MD5Parser::ReportWarning("A frame section must have a frame index",(*iter).iLineNumber);
 168.396 +				continue;
 168.397 +			}
 168.398 +
 168.399 +			mFrames.push_back ( FrameDesc () );
 168.400 +			FrameDesc& desc = mFrames.back();
 168.401 +			desc.iIndex = strtoul10((*iter).mGlobalValue.c_str());
 168.402 +
 168.403 +			// we do already know how much storage we will presumably need
 168.404 +			if (UINT_MAX != mNumAnimatedComponents) {
 168.405 +				desc.mValues.reserve(mNumAnimatedComponents);
 168.406 +			}
 168.407 +
 168.408 +			// now read all elements (continous list of floats)
 168.409 +			for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit){
 168.410 +				const char* sz = (*eit).szStart;
 168.411 +				while (SkipSpacesAndLineEnd(&sz))	{
 168.412 +					float f;sz = fast_atoreal_move<float>(sz,f);
 168.413 +					desc.mValues.push_back(f);
 168.414 +				}
 168.415 +			}
 168.416 +		}
 168.417 +		else if((*iter).mName == "numFrames")	{
 168.418 +			mFrames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
 168.419 +		}
 168.420 +		else if((*iter).mName == "numJoints")	{
 168.421 +			const unsigned int num = strtoul10((*iter).mGlobalValue.c_str());
 168.422 +			mAnimatedBones.reserve(num);
 168.423 +
 168.424 +			// try to guess the number of animated components if that element is not given
 168.425 +			if (UINT_MAX  == mNumAnimatedComponents) {
 168.426 +				mNumAnimatedComponents = num * 6;
 168.427 +			}
 168.428 +		}
 168.429 +		else if((*iter).mName == "numAnimatedComponents")	{
 168.430 +			mAnimatedBones.reserve( strtoul10((*iter).mGlobalValue.c_str()));
 168.431 +		}
 168.432 +		else if((*iter).mName == "frameRate")	{
 168.433 +			fast_atoreal_move<float>((*iter).mGlobalValue.c_str(),fFrameRate);
 168.434 +		}
 168.435 +	}
 168.436 +	DefaultLogger::get()->debug("MD5AnimParser end");
 168.437 +}
 168.438 +
 168.439 +// ------------------------------------------------------------------------------------------------
 168.440 +// .MD5CAMERA parsing function
 168.441 +MD5CameraParser::MD5CameraParser(SectionList& mSections)
 168.442 +{
 168.443 +	DefaultLogger::get()->debug("MD5CameraParser begin");
 168.444 +	fFrameRate = 24.0f;
 168.445 +
 168.446 +	for (SectionList::const_iterator iter =  mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
 168.447 +		if ((*iter).mName == "numFrames")	{
 168.448 +			frames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
 168.449 +		}
 168.450 +		else if ((*iter).mName == "frameRate")	{
 168.451 +			fFrameRate = fast_atof ((*iter).mGlobalValue.c_str());
 168.452 +		}
 168.453 +		else if ((*iter).mName == "numCuts")	{
 168.454 +			cuts.reserve(strtoul10((*iter).mGlobalValue.c_str()));
 168.455 +		}
 168.456 +		else if ((*iter).mName == "cuts")	{
 168.457 +			for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit){
 168.458 +				cuts.push_back(strtoul10((*eit).szStart)+1);
 168.459 +			}
 168.460 +		}
 168.461 +		else if ((*iter).mName == "camera")	{
 168.462 +			for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit){
 168.463 +				const char* sz = (*eit).szStart;
 168.464 +
 168.465 +				frames.push_back(CameraAnimFrameDesc());
 168.466 +				CameraAnimFrameDesc& cur = frames.back();
 168.467 +				AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
 168.468 +				AI_MD5_READ_TRIPLE(cur.vRotationQuat);
 168.469 +				AI_MD5_SKIP_SPACES();
 168.470 +				cur.fFOV = fast_atof(sz);
 168.471 +			}
 168.472 +		}
 168.473 +	}
 168.474 +	DefaultLogger::get()->debug("MD5CameraParser end");
 168.475 +}
 168.476 +
   169.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   169.2 +++ b/libs/assimp/MD5Parser.h	Sat Feb 01 19:58:19 2014 +0200
   169.3 @@ -0,0 +1,460 @@
   169.4 +/*
   169.5 +Open Asset Import Library (assimp)
   169.6 +----------------------------------------------------------------------
   169.7 +
   169.8 +Copyright (c) 2006-2012, assimp team
   169.9 +All rights reserved.
  169.10 +
  169.11 +Redistribution and use of this software in source and binary forms, 
  169.12 +with or without modification, are permitted provided that the 
  169.13 +following conditions are met:
  169.14 +
  169.15 +* Redistributions of source code must retain the above
  169.16 +  copyright notice, this list of conditions and the
  169.17 +  following disclaimer.
  169.18 +
  169.19 +* Redistributions in binary form must reproduce the above
  169.20 +  copyright notice, this list of conditions and the
  169.21 +  following disclaimer in the documentation and/or other
  169.22 +  materials provided with the distribution.
  169.23 +
  169.24 +* Neither the name of the assimp team, nor the names of its
  169.25 +  contributors may be used to endorse or promote products
  169.26 +  derived from this software without specific prior
  169.27 +  written permission of the assimp team.
  169.28 +
  169.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  169.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  169.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  169.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  169.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  169.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  169.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  169.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  169.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  169.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  169.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  169.40 +
  169.41 +----------------------------------------------------------------------
  169.42 +*/
  169.43 +
  169.44 +
  169.45 +/** @file  MD5Parser.h
  169.46 + *  @brief Definition of the .MD5 parser class.
  169.47 + *  http://www.modwiki.net/wiki/MD5_(file_format)
  169.48 + */
  169.49 +#ifndef AI_MD5PARSER_H_INCLUDED
  169.50 +#define AI_MD5PARSER_H_INCLUDED
  169.51 +
  169.52 +#include "assimp/types.h"
  169.53 +#include "ParsingUtils.h"
  169.54 +
  169.55 +struct aiFace;
  169.56 +
  169.57 +namespace Assimp	{
  169.58 +namespace MD5			{
  169.59 +
  169.60 +// ---------------------------------------------------------------------------
  169.61 +/** Represents a single element in a MD5 file
  169.62 + *  
  169.63 + *  Elements are always contained in sections.
  169.64 +*/
  169.65 +struct Element
  169.66 +{
  169.67 +	//! Points to the starting point of the element
  169.68 +	//! Whitespace at the beginning and at the end have been removed,
  169.69 +	//! Elements are terminated with \0
  169.70 +	char* szStart;
  169.71 +
  169.72 +	//! Original line number (can be used in error messages
  169.73 +	//! if a parsing error occurs)
  169.74 +	unsigned int iLineNumber;
  169.75 +};
  169.76 +
  169.77 +typedef std::vector< Element > ElementList;
  169.78 +
  169.79 +// ---------------------------------------------------------------------------
  169.80 +/** Represents a section of a MD5 file (such as the mesh or the joints section)
  169.81 + *  
  169.82 + *  A section is always enclosed in { and } brackets.
  169.83 +*/
  169.84 +struct Section
  169.85 +{
  169.86 +	//! Original line number (can be used in error messages
  169.87 +	//! if a parsing error occurs)
  169.88 +	unsigned int iLineNumber;
  169.89 +
  169.90 +	//! List of all elements which have been parsed in this section.
  169.91 +	ElementList mElements;
  169.92 +
  169.93 +	//! Name of the section
  169.94 +	std::string mName;
  169.95 +
  169.96 +	//! For global elements: the value of the element as string
  169.97 +	//! Iif !length() the section is not a global element
  169.98 +	std::string mGlobalValue;
  169.99 +};
 169.100 +
 169.101 +typedef std::vector< Section> SectionList;
 169.102 +
 169.103 +// ---------------------------------------------------------------------------
 169.104 +/** Basic information about a joint
 169.105 +*/
 169.106 +struct BaseJointDescription
 169.107 +{
 169.108 +	//! Name of the bone
 169.109 +	aiString mName;
 169.110 +
 169.111 +	//! Parent index of the bone
 169.112 +	int mParentIndex;
 169.113 +};
 169.114 +
 169.115 +// ---------------------------------------------------------------------------
 169.116 +/** Represents a bone (joint) descriptor in a MD5Mesh file
 169.117 +*/
 169.118 +struct BoneDesc : BaseJointDescription
 169.119 +{
 169.120 +	//! Absolute position of the bone
 169.121 +	aiVector3D mPositionXYZ;
 169.122 +
 169.123 +	//! Absolute rotation of the bone
 169.124 +	aiVector3D mRotationQuat;
 169.125 +	aiQuaternion mRotationQuatConverted;
 169.126 +
 169.127 +	//! Absolute transformation of the bone
 169.128 +	//! (temporary)
 169.129 +	aiMatrix4x4 mTransform;
 169.130 +
 169.131 +	//! Inverse transformation of the bone
 169.132 +	//! (temporary)
 169.133 +	aiMatrix4x4 mInvTransform;
 169.134 +
 169.135 +	//! Internal
 169.136 +	unsigned int mMap;
 169.137 +};
 169.138 +
 169.139 +typedef std::vector< BoneDesc > BoneList;
 169.140 +
 169.141 +// ---------------------------------------------------------------------------
 169.142 +/** Represents a bone (joint) descriptor in a MD5Anim file
 169.143 +*/
 169.144 +struct AnimBoneDesc : BaseJointDescription
 169.145 +{
 169.146 +	//! Flags (AI_MD5_ANIMATION_FLAG_xxx)
 169.147 +	unsigned int iFlags;
 169.148 +
 169.149 +	//! Index of the first key that corresponds to this anim bone
 169.150 +	unsigned int iFirstKeyIndex;
 169.151 +};
 169.152 +
 169.153 +typedef std::vector< AnimBoneDesc > AnimBoneList;
 169.154 +
 169.155 +
 169.156 +// ---------------------------------------------------------------------------
 169.157 +/** Represents a base frame descriptor in a MD5Anim file
 169.158 +*/
 169.159 +struct BaseFrameDesc
 169.160 +{
 169.161 +	aiVector3D vPositionXYZ;
 169.162 +	aiVector3D vRotationQuat;
 169.163 +};
 169.164 +
 169.165 +typedef std::vector< BaseFrameDesc > BaseFrameList;
 169.166 +
 169.167 +// ---------------------------------------------------------------------------
 169.168 +/** Represents a camera animation frame in a MDCamera file
 169.169 +*/
 169.170 +struct CameraAnimFrameDesc : BaseFrameDesc
 169.171 +{
 169.172 +	float fFOV;
 169.173 +};
 169.174 +
 169.175 +typedef std::vector< CameraAnimFrameDesc > CameraFrameList;
 169.176 +
 169.177 +// ---------------------------------------------------------------------------
 169.178 +/** Represents a frame descriptor in a MD5Anim file
 169.179 +*/
 169.180 +struct FrameDesc
 169.181 +{
 169.182 +	//! Index of the frame
 169.183 +	unsigned int iIndex;
 169.184 +
 169.185 +	//! Animation keyframes - a large blob of data at first
 169.186 +	std::vector< float > mValues;
 169.187 +};
 169.188 +
 169.189 +typedef std::vector< FrameDesc > FrameList;
 169.190 +
 169.191 +// ---------------------------------------------------------------------------
 169.192 +/** Represents a vertex  descriptor in a MD5 file
 169.193 +*/
 169.194 +struct VertexDesc
 169.195 +{
 169.196 +	VertexDesc()
 169.197 +		: mFirstWeight	(0)
 169.198 +		, mNumWeights	(0)
 169.199 +	{}
 169.200 +
 169.201 +	//! UV cordinate of the vertex
 169.202 +	aiVector2D mUV;
 169.203 +
 169.204 +	//! Index of the first weight of the vertex in
 169.205 +	//! the vertex weight list
 169.206 +	unsigned int mFirstWeight;
 169.207 +
 169.208 +	//! Number of weights assigned to this vertex
 169.209 +	unsigned int mNumWeights;
 169.210 +};
 169.211 +
 169.212 +typedef std::vector< VertexDesc > VertexList;
 169.213 +
 169.214 +// ---------------------------------------------------------------------------
 169.215 +/** Represents a vertex weight descriptor in a MD5 file
 169.216 +*/
 169.217 +struct WeightDesc
 169.218 +{
 169.219 +	//! Index of the bone to which this weight refers
 169.220 +	unsigned int mBone;
 169.221 +
 169.222 +	//! The weight value
 169.223 +	float mWeight;
 169.224 +
 169.225 +	//! The offset position of this weight
 169.226 +	// ! (in the coordinate system defined by the parent bone)
 169.227 +	aiVector3D vOffsetPosition;
 169.228 +};
 169.229 +
 169.230 +typedef std::vector< WeightDesc > WeightList;
 169.231 +typedef std::vector< aiFace > FaceList;
 169.232 +
 169.233 +// ---------------------------------------------------------------------------
 169.234 +/** Represents a mesh in a MD5 file
 169.235 +*/
 169.236 +struct MeshDesc
 169.237 +{
 169.238 +	//! Weights of the mesh
 169.239 +	WeightList mWeights;
 169.240 +
 169.241 +	//! Vertices of the mesh
 169.242 +	VertexList mVertices;
 169.243 +
 169.244 +	//! Faces of the mesh
 169.245 +	FaceList mFaces;
 169.246 +
 169.247 +	//! Name of the shader (=texture) to be assigned to the mesh
 169.248 +	aiString mShader;
 169.249 +};
 169.250 +
 169.251 +typedef std::vector< MeshDesc > MeshList;
 169.252 +
 169.253 +// ---------------------------------------------------------------------------
 169.254 +// Convert a quaternion to its usual representation
 169.255 +inline void ConvertQuaternion (const aiVector3D& in, aiQuaternion& out) {
 169.256 +
 169.257 +	out.x = in.x;
 169.258 +	out.y = in.y;
 169.259 +	out.z = in.z;
 169.260 +
 169.261 +	const float t = 1.0f - (in.x*in.x) - (in.y*in.y) - (in.z*in.z);
 169.262 +
 169.263 +	if (t < 0.0f)
 169.264 +		out.w = 0.0f;
 169.265 +	else out.w = sqrt (t);
 169.266 +}
 169.267 +
 169.268 +// ---------------------------------------------------------------------------
 169.269 +/** Parses the data sections of a MD5 mesh file
 169.270 +*/
 169.271 +class MD5MeshParser
 169.272 +{
 169.273 +public:
 169.274 +
 169.275 +	// -------------------------------------------------------------------
 169.276 +	/** Constructs a new MD5MeshParser instance from an existing
 169.277 +	 *  preparsed list of file sections.
 169.278 +	 *
 169.279 +	 *  @param mSections List of file sections (output of MD5Parser)
 169.280 +	 */
 169.281 +	MD5MeshParser(SectionList& mSections);
 169.282 +
 169.283 +	//! List of all meshes
 169.284 +	MeshList mMeshes;
 169.285 +
 169.286 +	//! List of all joints
 169.287 +	BoneList mJoints;
 169.288 +};
 169.289 +
 169.290 +// remove this flag if you need to the bounding box data
 169.291 +#define AI_MD5_PARSE_NO_BOUNDS
 169.292 +
 169.293 +// ---------------------------------------------------------------------------
 169.294 +/** Parses the data sections of a MD5 animation file
 169.295 +*/
 169.296 +class MD5AnimParser
 169.297 +{
 169.298 +public:
 169.299 +
 169.300 +	// -------------------------------------------------------------------
 169.301 +	/** Constructs a new MD5AnimParser instance from an existing
 169.302 +	 *  preparsed list of file sections.
 169.303 +	 *
 169.304 +	 *  @param mSections List of file sections (output of MD5Parser)
 169.305 +	 */
 169.306 +	MD5AnimParser(SectionList& mSections);
 169.307 +
 169.308 +	
 169.309 +	//! Output frame rate
 169.310 +	float fFrameRate;
 169.311 +
 169.312 +	//! List of animation bones
 169.313 +	AnimBoneList mAnimatedBones;
 169.314 +
 169.315 +	//! List of base frames
 169.316 +	BaseFrameList mBaseFrames;
 169.317 +
 169.318 +	//! List of animation frames
 169.319 +	FrameList mFrames;
 169.320 +
 169.321 +	//! Number of animated components
 169.322 +	unsigned int mNumAnimatedComponents;
 169.323 +};
 169.324 +
 169.325 +// ---------------------------------------------------------------------------
 169.326 +/** Parses the data sections of a MD5 camera animation file
 169.327 +*/
 169.328 +class MD5CameraParser
 169.329 +{
 169.330 +public:
 169.331 +
 169.332 +	// -------------------------------------------------------------------
 169.333 +	/** Constructs a new MD5CameraParser instance from an existing
 169.334 +	 *  preparsed list of file sections.
 169.335 +	 *
 169.336 +	 *  @param mSections List of file sections (output of MD5Parser)
 169.337 +	 */
 169.338 +	MD5CameraParser(SectionList& mSections);
 169.339 +
 169.340 +	
 169.341 +	//! Output frame rate
 169.342 +	float fFrameRate;
 169.343 +
 169.344 +	//! List of cuts
 169.345 +	std::vector<unsigned int> cuts;
 169.346 +
 169.347 +	//! Frames
 169.348 +	CameraFrameList frames;
 169.349 +};
 169.350 +
 169.351 +// ---------------------------------------------------------------------------
 169.352 +/** Parses the block structure of MD5MESH and MD5ANIM files (but does no
 169.353 + *  further processing)
 169.354 +*/
 169.355 +class MD5Parser
 169.356 +{
 169.357 +public:
 169.358 +
 169.359 +	// -------------------------------------------------------------------
 169.360 +	/** Constructs a new MD5Parser instance from an existing buffer.
 169.361 +	 *
 169.362 +	 *  @param buffer File buffer
 169.363 +	 *  @param fileSize Length of the file in bytes (excluding a terminal 0)
 169.364 +	 */
 169.365 +	MD5Parser(char* buffer, unsigned int fileSize);
 169.366 +
 169.367 +	
 169.368 +	// -------------------------------------------------------------------
 169.369 +	/** Report a specific error message and throw an exception
 169.370 +	 *  @param error Error message to be reported
 169.371 +	 *  @param line Index of the line where the error occured
 169.372 +	 */
 169.373 +	static void ReportError (const char* error, unsigned int line);
 169.374 +
 169.375 +	// -------------------------------------------------------------------
 169.376 +	/** Report a specific warning
 169.377 +	 *  @param warn Warn message to be reported
 169.378 +	 *  @param line Index of the line where the error occured
 169.379 +	 */
 169.380 +	static void ReportWarning (const char* warn, unsigned int line);
 169.381 +
 169.382 +
 169.383 +	void ReportError (const char* error) {
 169.384 +		return ReportError(error, lineNumber);
 169.385 +	}
 169.386 +
 169.387 +	void ReportWarning (const char* warn) {
 169.388 +		return ReportWarning(warn, lineNumber);
 169.389 +	}
 169.390 +
 169.391 +public:
 169.392 +
 169.393 +	//! List of all sections which have been read
 169.394 +	SectionList mSections;
 169.395 +
 169.396 +private:
 169.397 +
 169.398 +	// -------------------------------------------------------------------
 169.399 +	/** Parses a file section. The current file pointer must be outside
 169.400 +	 *  of a section.
 169.401 +	 *  @param out Receives the section data
 169.402 +	 *  @return true if the end of the file has been reached
 169.403 +	 *  @throws ImportErrorException if an error occurs
 169.404 +	 */
 169.405 +	bool ParseSection(Section& out);
 169.406 +
 169.407 +	// -------------------------------------------------------------------
 169.408 +	/** Parses the file header
 169.409 +	 *  @throws ImportErrorException if an error occurs
 169.410 +	 */
 169.411 +	void ParseHeader();
 169.412 +
 169.413 +
 169.414 +	// override these functions to make sure the line counter gets incremented
 169.415 +	// -------------------------------------------------------------------
 169.416 +	bool SkipLine( const char* in, const char** out)
 169.417 +	{
 169.418 +		++lineNumber;
 169.419 +		return Assimp::SkipLine(in,out);
 169.420 +	}
 169.421 +	// -------------------------------------------------------------------
 169.422 +	bool SkipLine( )
 169.423 +	{
 169.424 +		return SkipLine(buffer,(const char**)&buffer);
 169.425 +	}
 169.426 +	// -------------------------------------------------------------------
 169.427 +	bool SkipSpacesAndLineEnd( const char* in, const char** out)
 169.428 +	{
 169.429 +		bool bHad = false;
 169.430 +		bool running = true;
 169.431 +		while (running)	{
 169.432 +			if( *in == '\r' || *in == '\n')	{
 169.433 +				 // we open files in binary mode, so there could be \r\n sequences ...
 169.434 +				if (!bHad)	{
 169.435 +					bHad = true;
 169.436 +					++lineNumber;
 169.437 +				}
 169.438 +			}
 169.439 +			else if (*in == '\t' || *in == ' ')bHad = false;
 169.440 +			else break;
 169.441 +			in++;
 169.442 +		}
 169.443 +		*out = in;
 169.444 +		return *in != '\0';
 169.445 +	}
 169.446 +	// -------------------------------------------------------------------
 169.447 +	bool SkipSpacesAndLineEnd( )
 169.448 +	{
 169.449 +		return SkipSpacesAndLineEnd(buffer,(const char**)&buffer);
 169.450 +	}
 169.451 +	// -------------------------------------------------------------------
 169.452 +	bool SkipSpaces( )
 169.453 +	{
 169.454 +		return Assimp::SkipSpaces((const char**)&buffer);
 169.455 +	}
 169.456 +
 169.457 +	char* buffer;
 169.458 +	unsigned int fileSize;
 169.459 +	unsigned int lineNumber;
 169.460 +};
 169.461 +}}
 169.462 +
 169.463 +#endif // AI_MD5PARSER_H_INCLUDED
   170.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   170.2 +++ b/libs/assimp/MDCFileData.h	Sat Feb 01 19:58:19 2014 +0200
   170.3 @@ -0,0 +1,203 @@
   170.4 +/*
   170.5 +Open Asset Import Library (assimp)
   170.6 +----------------------------------------------------------------------
   170.7 +
   170.8 +Copyright (c) 2006-2012, assimp team
   170.9 +All rights reserved.
  170.10 +
  170.11 +Redistribution and use of this software in source and binary forms, 
  170.12 +with or without modification, are permitted provided that the 
  170.13 +following conditions are met:
  170.14 +
  170.15 +* Redistributions of source code must retain the above
  170.16 +  copyright notice, this list of conditions and the
  170.17 +  following disclaimer.
  170.18 +
  170.19 +* Redistributions in binary form must reproduce the above
  170.20 +  copyright notice, this list of conditions and the
  170.21 +  following disclaimer in the documentation and/or other
  170.22 +  materials provided with the distribution.
  170.23 +
  170.24 +* Neither the name of the assimp team, nor the names of its
  170.25 +  contributors may be used to endorse or promote products
  170.26 +  derived from this software without specific prior
  170.27 +  written permission of the assimp team.
  170.28 +
  170.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  170.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  170.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  170.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  170.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  170.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  170.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  170.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  170.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  170.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  170.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  170.40 +
  170.41 +----------------------------------------------------------------------
  170.42 +*/
  170.43 +
  170.44 +/** @file Defines the helper data structures for importing MDC files  
  170.45 +
  170.46 +**********************************************************************
  170.47 +File format specification: 
  170.48 +http://themdcfile.planetwolfenstein.gamespy.com/MDC_File_Format.pdf
  170.49 +**********************************************************************
  170.50 +
  170.51 +*/
  170.52 +#ifndef AI_MDCFILEHELPER_H_INC
  170.53 +#define AI_MDCFILEHELPER_H_INC
  170.54 +
  170.55 +#include "assimp/types.h"
  170.56 +#include "assimp/mesh.h"
  170.57 +#include "assimp/anim.h"
  170.58 +
  170.59 +#include "assimp/Compiler/pushpack1.h"
  170.60 +
  170.61 +
  170.62 +namespace Assimp {
  170.63 +namespace MDC {
  170.64 +
  170.65 +
  170.66 +// to make it easier for us, we test the magic word against both "endianesses"
  170.67 +#define AI_MDC_MAGIC_NUMBER_BE	AI_MAKE_MAGIC("CPDI")
  170.68 +#define AI_MDC_MAGIC_NUMBER_LE	AI_MAKE_MAGIC("IDPC")
  170.69 +
  170.70 +// common limitations
  170.71 +#define AI_MDC_VERSION			2
  170.72 +#define AI_MDC_MAXQPATH			64
  170.73 +#define	AI_MDC_MAX_BONES		128
  170.74 +
  170.75 +#define AI_MDC_CVERT_BIAS		127.0f
  170.76 +#define	AI_MDC_DELTA_SCALING	4.0f
  170.77 +#define	AI_MDC_BASE_SCALING		(1.0f / 64.0f)
  170.78 +
  170.79 +
  170.80 +// ---------------------------------------------------------------------------
  170.81 +/** \brief Data structure for a MDC file's main header
  170.82 + */
  170.83 +struct Header
  170.84 +{
  170.85 +	uint32_t ulIdent ;
  170.86 +	uint32_t ulVersion ;
  170.87 +	char ucName [ AI_MDC_MAXQPATH ] ;
  170.88 +	uint32_t ulFlags ;
  170.89 +	uint32_t ulNumFrames ;
  170.90 +	uint32_t ulNumTags ;
  170.91 +	uint32_t ulNumSurfaces ;
  170.92 +	uint32_t ulNumSkins ;
  170.93 +	uint32_t ulOffsetBorderFrames ;
  170.94 +	uint32_t ulOffsetTagNames ;
  170.95 +	uint32_t ulOffsetTagFrames ;
  170.96 +	uint32_t ulOffsetSurfaces ;
  170.97 +	uint32_t ulOffsetEnd ;
  170.98 +} PACK_STRUCT ;
  170.99 +
 170.100 +
 170.101 +// ---------------------------------------------------------------------------
 170.102 +/** \brief Data structure for a MDC file's surface header
 170.103 + */
 170.104 +struct Surface
 170.105 +{
 170.106 +	uint32_t ulIdent ;
 170.107 +	char ucName [ AI_MDC_MAXQPATH ] ;
 170.108 +	uint32_t ulFlags ;
 170.109 +	uint32_t ulNumCompFrames ;
 170.110 +	uint32_t ulNumBaseFrames ;
 170.111 +	uint32_t ulNumShaders ;
 170.112 +	uint32_t ulNumVertices ;
 170.113 +	uint32_t ulNumTriangles ;
 170.114 +	uint32_t ulOffsetTriangles ;
 170.115 +	uint32_t ulOffsetShaders ;
 170.116 +	uint32_t ulOffsetTexCoords ;
 170.117 +	uint32_t ulOffsetBaseVerts ;
 170.118 +	uint32_t ulOffsetCompVerts ;
 170.119 +	uint32_t ulOffsetFrameBaseFrames ;
 170.120 +	uint32_t ulOffsetFrameCompFrames ;
 170.121 +	uint32_t ulOffsetEnd;
 170.122 +	Surface()
 170.123 +	{
 170.124 +		ucName[AI_MDC_MAXQPATH-1] = '\0';
 170.125 +	}
 170.126 +} PACK_STRUCT;
 170.127 +
 170.128 +// ---------------------------------------------------------------------------
 170.129 +/** \brief Data structure for a MDC frame
 170.130 + */
 170.131 +struct Frame
 170.132 +{
 170.133 +	//! bounding box minimum coords
 170.134 +	aiVector3D bboxMin ;
 170.135 +
 170.136 +	//! bounding box maximum coords
 170.137 +	aiVector3D bboxMax ;
 170.138 +
 170.139 +	//! local origin of the frame
 170.140 +	aiVector3D localOrigin ;
 170.141 +
 170.142 +	//! radius of the BB
 170.143 +	float radius ;
 170.144 +
 170.145 +	//! Name of the frame
 170.146 +	char name [ 16 ] ;
 170.147 +} PACK_STRUCT;
 170.148 +
 170.149 +// ---------------------------------------------------------------------------
 170.150 +/** \brief Data structure for a MDC triangle
 170.151 + */
 170.152 +struct Triangle
 170.153 +{
 170.154 +	uint32_t aiIndices[3];
 170.155 +} PACK_STRUCT;
 170.156 +
 170.157 +// ---------------------------------------------------------------------------
 170.158 +/** \brief Data structure for a MDC texture coordinate
 170.159 + */
 170.160 +struct TexturCoord
 170.161 +{
 170.162 +	float u,v;
 170.163 +} PACK_STRUCT;
 170.164 +
 170.165 +// ---------------------------------------------------------------------------
 170.166 +/** \brief Data structure for a MDC base vertex
 170.167 + */
 170.168 +struct BaseVertex
 170.169 +{
 170.170 +	int16_t x,y,z;
 170.171 +	uint16_t normal;
 170.172 +} PACK_STRUCT;
 170.173 +
 170.174 +// ---------------------------------------------------------------------------
 170.175 +/** \brief Data structure for a MDC compressed vertex
 170.176 + */
 170.177 +struct CompressedVertex
 170.178 +{
 170.179 +	uint8_t xd,yd,zd,nd;
 170.180 +} PACK_STRUCT;
 170.181 +
 170.182 +
 170.183 +// ---------------------------------------------------------------------------
 170.184 +/** \brief Data structure for a MDC shader
 170.185 + */
 170.186 +struct Shader
 170.187 +{
 170.188 +	char ucName [ AI_MDC_MAXQPATH ] ;
 170.189 +	uint32_t ulPath;
 170.190 +
 170.191 +} PACK_STRUCT;
 170.192 +
 170.193 +#include "assimp/Compiler/poppack1.h"
 170.194 +
 170.195 +
 170.196 +// ---------------------------------------------------------------------------
 170.197 +/** Build a floating point vertex from the compressed data in MDC files
 170.198 + */
 170.199 +void BuildVertex(const Frame& frame,
 170.200 +	const BaseVertex& bvert,
 170.201 +	const CompressedVertex& cvert,
 170.202 +	aiVector3D& vXYZOut, 
 170.203 +	aiVector3D& vNorOut);
 170.204 +}}
 170.205 +
 170.206 +#endif // !! AI_MDCFILEHELPER_H_INC
   171.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   171.2 +++ b/libs/assimp/MDCLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   171.3 @@ -0,0 +1,482 @@
   171.4 +/*
   171.5 +---------------------------------------------------------------------------
   171.6 +Open Asset Import Library (assimp)
   171.7 +---------------------------------------------------------------------------
   171.8 +
   171.9 +Copyright (c) 2006-2012, assimp team
  171.10 +
  171.11 +All rights reserved.
  171.12 +
  171.13 +Redistribution and use of this software in source and binary forms, 
  171.14 +with or without modification, are permitted provided that the following 
  171.15 +conditions are met:
  171.16 +
  171.17 +* Redistributions of source code must retain the above
  171.18 +  copyright notice, this list of conditions and the
  171.19 +  following disclaimer.
  171.20 +
  171.21 +* Redistributions in binary form must reproduce the above
  171.22 +  copyright notice, this list of conditions and the
  171.23 +  following disclaimer in the documentation and/or other
  171.24 +  materials provided with the distribution.
  171.25 +
  171.26 +* Neither the name of the assimp team, nor the names of its
  171.27 +  contributors may be used to endorse or promote products
  171.28 +  derived from this software without specific prior
  171.29 +  written permission of the assimp team.
  171.30 +
  171.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  171.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  171.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  171.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  171.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  171.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  171.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  171.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  171.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  171.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  171.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  171.42 +---------------------------------------------------------------------------
  171.43 +*/
  171.44 +
  171.45 +/** @file Implementation of the MDC importer class */
  171.46 +
  171.47 +#include "AssimpPCH.h"
  171.48 +#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
  171.49 +
  171.50 +// internal headers
  171.51 +#include "MDCLoader.h"
  171.52 +#include "MD3FileData.h"
  171.53 +#include "MDCNormalTable.h" // shouldn't be included by other units
  171.54 +
  171.55 +using namespace Assimp;
  171.56 +using namespace Assimp::MDC;
  171.57 +
  171.58 +static const aiImporterDesc desc = {
  171.59 +	"Return To Castle Wolfenstein Mesh Importer",
  171.60 +	"",
  171.61 +	"",
  171.62 +	"",
  171.63 +	aiImporterFlags_SupportBinaryFlavour,
  171.64 +	0,
  171.65 +	0,
  171.66 +	0,
  171.67 +	0,
  171.68 +	"mdc" 
  171.69 +};
  171.70 +
  171.71 +// ------------------------------------------------------------------------------------------------
  171.72 +void MDC::BuildVertex(const Frame& frame,
  171.73 +	const BaseVertex& bvert,
  171.74 +	const CompressedVertex& cvert,
  171.75 +	aiVector3D& vXYZOut, 
  171.76 +	aiVector3D& vNorOut)
  171.77 +{
  171.78 +	// compute the position
  171.79 +	const float xd = (cvert.xd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
  171.80 +	const float yd = (cvert.yd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
  171.81 +	const float zd = (cvert.zd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
  171.82 +	vXYZOut.x = frame.localOrigin.x + AI_MDC_BASE_SCALING * (bvert.x + xd);
  171.83 +	vXYZOut.y = frame.localOrigin.y + AI_MDC_BASE_SCALING * (bvert.y + yd);
  171.84 +	vXYZOut.z = frame.localOrigin.z + AI_MDC_BASE_SCALING * (bvert.z + zd);
  171.85 +
  171.86 +	// compute the normal vector .. ehm ... lookup it in the table :-)
  171.87 +	vNorOut.x = mdcNormals[cvert.nd][0];
  171.88 +	vNorOut.y = mdcNormals[cvert.nd][1];
  171.89 +	vNorOut.z = mdcNormals[cvert.nd][2];
  171.90 +}
  171.91 +
  171.92 +// ------------------------------------------------------------------------------------------------
  171.93 +// Constructor to be privately used by Importer
  171.94 +MDCImporter::MDCImporter()
  171.95 +{
  171.96 +}
  171.97 +
  171.98 +// ------------------------------------------------------------------------------------------------
  171.99 +// Destructor, private as well 
 171.100 +MDCImporter::~MDCImporter()
 171.101 +{
 171.102 +}
 171.103 +// ------------------------------------------------------------------------------------------------
 171.104 +// Returns whether the class can handle the format of the given file. 
 171.105 +bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
 171.106 +{
 171.107 +	const std::string extension = GetExtension(pFile);
 171.108 +	if (extension == "mdc")
 171.109 +		return true;
 171.110 +
 171.111 +	// if check for extension is not enough, check for the magic tokens 
 171.112 +	if (!extension.length() || checkSig) {
 171.113 +		uint32_t tokens[1]; 
 171.114 +		tokens[0] = AI_MDC_MAGIC_NUMBER_LE;
 171.115 +		return CheckMagicToken(pIOHandler,pFile,tokens,1);
 171.116 +	}
 171.117 +	return false;
 171.118 +}
 171.119 +
 171.120 +// ------------------------------------------------------------------------------------------------
 171.121 +const aiImporterDesc* MDCImporter::GetInfo () const
 171.122 +{
 171.123 +	return &desc;
 171.124 +}
 171.125 +
 171.126 +// ------------------------------------------------------------------------------------------------
 171.127 +// Validate the header of the given MDC file
 171.128 +void MDCImporter::ValidateHeader()
 171.129 +{
 171.130 +	AI_SWAP4( this->pcHeader->ulVersion );
 171.131 +	AI_SWAP4( this->pcHeader->ulFlags );
 171.132 +	AI_SWAP4( this->pcHeader->ulNumFrames );
 171.133 +	AI_SWAP4( this->pcHeader->ulNumTags );
 171.134 +	AI_SWAP4( this->pcHeader->ulNumSurfaces );
 171.135 +	AI_SWAP4( this->pcHeader->ulNumSkins );
 171.136 +	AI_SWAP4( this->pcHeader->ulOffsetBorderFrames );
 171.137 +
 171.138 +	if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
 171.139 +		pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE)
 171.140 +	{
 171.141 +		char szBuffer[5];
 171.142 +		szBuffer[0] = ((char*)&pcHeader->ulIdent)[0];
 171.143 +		szBuffer[1] = ((char*)&pcHeader->ulIdent)[1];
 171.144 +		szBuffer[2] = ((char*)&pcHeader->ulIdent)[2];
 171.145 +		szBuffer[3] = ((char*)&pcHeader->ulIdent)[3];
 171.146 +		szBuffer[4] = '\0';
 171.147 +
 171.148 +		throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
 171.149 +			"magic word found is " + std::string( szBuffer ));
 171.150 +	}
 171.151 +
 171.152 +	if (pcHeader->ulVersion != AI_MDC_VERSION)
 171.153 +		DefaultLogger::get()->warn("Unsupported MDC file version (2 (AI_MDC_VERSION) was expected)");
 171.154 +
 171.155 +	if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize ||
 171.156 +		pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize)
 171.157 +	{
 171.158 +		throw DeadlyImportError("Some of the offset values in the MDC header are invalid "
 171.159 +			"and point to something behind the file.");
 171.160 +	}
 171.161 +
 171.162 +	if (this->configFrameID >= this->pcHeader->ulNumFrames)
 171.163 +		throw DeadlyImportError("The requested frame is not available");
 171.164 +}
 171.165 +
 171.166 +// ------------------------------------------------------------------------------------------------
 171.167 +// Validate the header of a given MDC file surface
 171.168 +void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
 171.169 +{
 171.170 +	AI_SWAP4(pcSurf->ulFlags);
 171.171 +	AI_SWAP4(pcSurf->ulNumCompFrames);
 171.172 +	AI_SWAP4(pcSurf->ulNumBaseFrames);
 171.173 +	AI_SWAP4(pcSurf->ulNumShaders);
 171.174 +	AI_SWAP4(pcSurf->ulNumVertices);
 171.175 +	AI_SWAP4(pcSurf->ulNumTriangles);
 171.176 +	AI_SWAP4(pcSurf->ulOffsetTriangles);
 171.177 +	AI_SWAP4(pcSurf->ulOffsetTexCoords);
 171.178 +	AI_SWAP4(pcSurf->ulOffsetBaseVerts);
 171.179 +	AI_SWAP4(pcSurf->ulOffsetCompVerts);
 171.180 +	AI_SWAP4(pcSurf->ulOffsetFrameBaseFrames);
 171.181 +	AI_SWAP4(pcSurf->ulOffsetFrameCompFrames);
 171.182 +	AI_SWAP4(pcSurf->ulOffsetEnd);
 171.183 +
 171.184 +    const unsigned int iMax = this->fileSize - (unsigned int)((int8_t*)pcSurf-(int8_t*)pcHeader);
 171.185 +
 171.186 +    if (pcSurf->ulOffsetBaseVerts + pcSurf->ulNumVertices * sizeof(MDC::BaseVertex)			> iMax ||
 171.187 +        (pcSurf->ulNumCompFrames && pcSurf->ulOffsetCompVerts + pcSurf->ulNumVertices * sizeof(MDC::CompressedVertex)	> iMax) ||
 171.188 +        pcSurf->ulOffsetTriangles + pcSurf->ulNumTriangles * sizeof(MDC::Triangle)			> iMax ||
 171.189 +        pcSurf->ulOffsetTexCoords + pcSurf->ulNumVertices * sizeof(MDC::TexturCoord)		> iMax ||
 171.190 +        pcSurf->ulOffsetShaders + pcSurf->ulNumShaders * sizeof(MDC::Shader)				> iMax ||
 171.191 +        pcSurf->ulOffsetFrameBaseFrames + pcSurf->ulNumBaseFrames * 2						> iMax ||
 171.192 +        (pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2	> iMax))
 171.193 +    {
 171.194 +        throw DeadlyImportError("Some of the offset values in the MDC surface header "
 171.195 +            "are invalid and point somewhere behind the file.");
 171.196 +    }
 171.197 +}
 171.198 +
 171.199 +// ------------------------------------------------------------------------------------------------
 171.200 +// Setup configuration properties
 171.201 +void MDCImporter::SetupProperties(const Importer* pImp)
 171.202 +{
 171.203 +	// The AI_CONFIG_IMPORT_MDC_KEYFRAME option overrides the
 171.204 +	// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
 171.205 +	if(static_cast<unsigned int>(-1) == (configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDC_KEYFRAME,-1))){
 171.206 +		configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
 171.207 +	}
 171.208 +}
 171.209 +
 171.210 +// ------------------------------------------------------------------------------------------------
 171.211 +// Imports the given file into the given scene structure. 
 171.212 +void MDCImporter::InternReadFile( 
 171.213 +	const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
 171.214 +{
 171.215 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
 171.216 +
 171.217 +	// Check whether we can read from the file
 171.218 +	if( file.get() == NULL)
 171.219 +		throw DeadlyImportError( "Failed to open MDC file " + pFile + ".");
 171.220 +
 171.221 +	// check whether the mdc file is large enough to contain the file header
 171.222 +	fileSize = (unsigned int)file->FileSize();
 171.223 +	if( fileSize < sizeof(MDC::Header))
 171.224 +		throw DeadlyImportError( "MDC File is too small.");
 171.225 +
 171.226 +	std::vector<unsigned char> mBuffer2(fileSize);
 171.227 +	file->Read( &mBuffer2[0], 1, fileSize);
 171.228 +	mBuffer = &mBuffer2[0];
 171.229 +
 171.230 +	// validate the file header
 171.231 +	this->pcHeader = (BE_NCONST MDC::Header*)this->mBuffer;
 171.232 +	this->ValidateHeader();
 171.233 +
 171.234 +	std::vector<std::string> aszShaders;
 171.235 +
 171.236 +	// get a pointer to the frame we want to read
 171.237 +	BE_NCONST MDC::Frame* pcFrame = (BE_NCONST MDC::Frame*)(this->mBuffer+
 171.238 +		this->pcHeader->ulOffsetBorderFrames);
 171.239 +
 171.240 +	// no need to swap the other members, we won't need them
 171.241 +	pcFrame += configFrameID;
 171.242 +	AI_SWAP4( pcFrame->localOrigin[0] );
 171.243 +	AI_SWAP4( pcFrame->localOrigin[1] );
 171.244 +	AI_SWAP4( pcFrame->localOrigin[2] );
 171.245 +
 171.246 +	// get the number of valid surfaces
 171.247 +	BE_NCONST MDC::Surface* pcSurface, *pcSurface2;
 171.248 +	pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface;
 171.249 +	unsigned int iNumShaders = 0;
 171.250 +	for (unsigned int i = 0; i < pcHeader->ulNumSurfaces;++i)
 171.251 +	{
 171.252 +		// validate the surface header
 171.253 +		this->ValidateSurfaceHeader(pcSurface2);
 171.254 +
 171.255 +		if (pcSurface2->ulNumVertices && pcSurface2->ulNumTriangles)++pScene->mNumMeshes;
 171.256 +		iNumShaders += pcSurface2->ulNumShaders;
 171.257 +		pcSurface2 = new ((int8_t*)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface;
 171.258 +	}
 171.259 +	aszShaders.reserve(iNumShaders);
 171.260 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
 171.261 +
 171.262 +	// necessary that we don't crash if an exception occurs
 171.263 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
 171.264 +		pScene->mMeshes[i] = NULL;
 171.265 +
 171.266 +	// now read all surfaces
 171.267 +	unsigned int iDefaultMatIndex = UINT_MAX;
 171.268 +	for (unsigned int i = 0, iNum = 0; i < pcHeader->ulNumSurfaces;++i)
 171.269 +	{
 171.270 +		if (!pcSurface->ulNumVertices || !pcSurface->ulNumTriangles)continue;
 171.271 +		aiMesh* pcMesh = pScene->mMeshes[iNum++] = new aiMesh();
 171.272 +
 171.273 +		pcMesh->mNumFaces = pcSurface->ulNumTriangles;
 171.274 +		pcMesh->mNumVertices = pcMesh->mNumFaces * 3;
 171.275 +
 171.276 +		// store the name of the surface for use as node name.
 171.277 +		// FIX: make sure there is a 0 termination
 171.278 +		const_cast<char&>(pcSurface->ucName[AI_MDC_MAXQPATH-1]) = '\0';
 171.279 +		pcMesh->mTextureCoords[3] = (aiVector3D*)pcSurface->ucName;
 171.280 +
 171.281 +		// go to the first shader in the file. ignore the others.
 171.282 +		if (pcSurface->ulNumShaders)
 171.283 +		{
 171.284 +			const MDC::Shader* pcShader = (const MDC::Shader*)((int8_t*)pcSurface + pcSurface->ulOffsetShaders);
 171.285 +			pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
 171.286 +			
 171.287 +			// create a new shader
 171.288 +			aszShaders.push_back(std::string( pcShader->ucName, std::min(
 171.289 +				::strlen(pcShader->ucName),sizeof(pcShader->ucName)) ));
 171.290 +		}
 171.291 +		// need to create a default material
 171.292 +		else if (UINT_MAX == iDefaultMatIndex)
 171.293 +		{
 171.294 +			pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
 171.295 +			aszShaders.push_back(std::string());
 171.296 +		}
 171.297 +		// otherwise assign a reference to the default material
 171.298 +		else pcMesh->mMaterialIndex = iDefaultMatIndex;
 171.299 +
 171.300 +		// allocate output storage for the mesh
 171.301 +		aiVector3D* pcVertCur	= pcMesh->mVertices			= new aiVector3D[pcMesh->mNumVertices];
 171.302 +		aiVector3D* pcNorCur	= pcMesh->mNormals			= new aiVector3D[pcMesh->mNumVertices];
 171.303 +		aiVector3D* pcUVCur		= pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
 171.304 +		aiFace* pcFaceCur		= pcMesh->mFaces			= new aiFace[pcMesh->mNumFaces];
 171.305 +
 171.306 +		// create all vertices/faces
 171.307 +		BE_NCONST MDC::Triangle* pcTriangle = (BE_NCONST MDC::Triangle*)
 171.308 +			((int8_t*)pcSurface+pcSurface->ulOffsetTriangles);
 171.309 +
 171.310 +		BE_NCONST MDC::TexturCoord* const pcUVs = (BE_NCONST MDC::TexturCoord*)
 171.311 +			((int8_t*)pcSurface+pcSurface->ulOffsetTexCoords);
 171.312 +
 171.313 +		// get a pointer to the uncompressed vertices
 171.314 +		int16_t iOfs = *((int16_t*) ((int8_t*) pcSurface +
 171.315 +			pcSurface->ulOffsetFrameBaseFrames) +  this->configFrameID);
 171.316 +
 171.317 +		AI_SWAP2(iOfs);
 171.318 +
 171.319 +		BE_NCONST MDC::BaseVertex* const pcVerts = (BE_NCONST MDC::BaseVertex*)
 171.320 +			((int8_t*)pcSurface+pcSurface->ulOffsetBaseVerts) +
 171.321 +			((int)iOfs * pcSurface->ulNumVertices * 4);
 171.322 +
 171.323 +		// do the main swapping stuff ...
 171.324 +#if (defined AI_BUILD_BIG_ENDIAN)
 171.325 +
 171.326 +		// swap all triangles
 171.327 +		for (unsigned int i = 0; i < pcSurface->ulNumTriangles;++i)
 171.328 +		{
 171.329 +			AI_SWAP4( pcTriangle[i].aiIndices[0] );
 171.330 +			AI_SWAP4( pcTriangle[i].aiIndices[1] );
 171.331 +			AI_SWAP4( pcTriangle[i].aiIndices[2] );
 171.332 +		}
 171.333 +
 171.334 +		// swap all vertices
 171.335 +		for (unsigned int i = 0; i < pcSurface->ulNumVertices*pcSurface->ulNumBaseFrames;++i)
 171.336 +		{
 171.337 +			AI_SWAP2( pcVerts->normal );
 171.338 +			AI_SWAP2( pcVerts->x );
 171.339 +			AI_SWAP2( pcVerts->y );
 171.340 +			AI_SWAP2( pcVerts->z );
 171.341 +		}
 171.342 +
 171.343 +		// swap all texture coordinates
 171.344 +		for (unsigned int i = 0; i < pcSurface->ulNumVertices;++i)
 171.345 +		{
 171.346 +			AI_SWAP4( pcUVs->v );
 171.347 +			AI_SWAP4( pcUVs->v );
 171.348 +		}
 171.349 +
 171.350 +#endif
 171.351 +
 171.352 +		const MDC::CompressedVertex* pcCVerts = NULL;
 171.353 +		int16_t* mdcCompVert = NULL;
 171.354 +
 171.355 +		// access compressed frames for large frame numbers, but never for the first
 171.356 +		if( this->configFrameID && pcSurface->ulNumCompFrames > 0 )
 171.357 +		{
 171.358 +			mdcCompVert = (int16_t*) ((int8_t*)pcSurface+pcSurface->ulOffsetFrameCompFrames) + this->configFrameID;
 171.359 +			AI_SWAP2P(mdcCompVert);
 171.360 +			if( *mdcCompVert >= 0 )
 171.361 +			{
 171.362 +				pcCVerts = (const MDC::CompressedVertex*)((int8_t*)pcSurface +
 171.363 +					pcSurface->ulOffsetCompVerts) + *mdcCompVert * pcSurface->ulNumVertices;
 171.364 +			}
 171.365 +			else mdcCompVert = NULL;
 171.366 +		}
 171.367 +
 171.368 +		// copy all faces
 171.369 +		for (unsigned int iFace = 0; iFace < pcSurface->ulNumTriangles;++iFace,
 171.370 +			++pcTriangle,++pcFaceCur)
 171.371 +		{
 171.372 +			const unsigned int iOutIndex = iFace*3;
 171.373 +			pcFaceCur->mNumIndices = 3;
 171.374 +			pcFaceCur->mIndices = new unsigned int[3];
 171.375 +
 171.376 +			for (unsigned int iIndex = 0; iIndex < 3;++iIndex,
 171.377 +				++pcVertCur,++pcUVCur,++pcNorCur)
 171.378 +			{
 171.379 +				uint32_t quak = pcTriangle->aiIndices[iIndex];
 171.380 +				if (quak >= pcSurface->ulNumVertices)
 171.381 +				{
 171.382 +					DefaultLogger::get()->error("MDC vertex index is out of range");
 171.383 +					quak = pcSurface->ulNumVertices-1;
 171.384 +				}
 171.385 +
 171.386 +				// compressed vertices?
 171.387 +				if (mdcCompVert)
 171.388 +				{
 171.389 +					MDC::BuildVertex(*pcFrame,pcVerts[quak],pcCVerts[quak],
 171.390 +						*pcVertCur,*pcNorCur);
 171.391 +				}
 171.392 +				else
 171.393 +				{
 171.394 +					// copy position
 171.395 +					pcVertCur->x = pcVerts[quak].x * AI_MDC_BASE_SCALING;
 171.396 +					pcVertCur->y = pcVerts[quak].y * AI_MDC_BASE_SCALING;
 171.397 +					pcVertCur->z = pcVerts[quak].z * AI_MDC_BASE_SCALING;
 171.398 +
 171.399 +					// copy normals
 171.400 +					MD3::LatLngNormalToVec3( pcVerts[quak].normal, &pcNorCur->x );
 171.401 +
 171.402 +					// copy texture coordinates
 171.403 +					pcUVCur->x = pcUVs[quak].u;
 171.404 +					pcUVCur->y = 1.0f-pcUVs[quak].v; // DX to OGL
 171.405 +				}
 171.406 +				pcVertCur->x += pcFrame->localOrigin[0] ;
 171.407 +				pcVertCur->y += pcFrame->localOrigin[1] ;
 171.408 +				pcVertCur->z += pcFrame->localOrigin[2] ;
 171.409 +			}
 171.410 +
 171.411 +			// swap the face order - DX to OGL
 171.412 +			pcFaceCur->mIndices[0] = iOutIndex + 2;
 171.413 +			pcFaceCur->mIndices[1] = iOutIndex + 1;
 171.414 +			pcFaceCur->mIndices[2] = iOutIndex + 0;
 171.415 +		}
 171.416 +
 171.417 +		pcSurface =  new ((int8_t*)pcSurface + pcSurface->ulOffsetEnd) MDC::Surface;
 171.418 +	}
 171.419 +
 171.420 +	// create a flat node graph with a root node and one child for each surface
 171.421 +	if (!pScene->mNumMeshes)
 171.422 +		throw DeadlyImportError( "Invalid MDC file: File contains no valid mesh");
 171.423 +	else if (1 == pScene->mNumMeshes)
 171.424 +	{
 171.425 +		pScene->mRootNode = new aiNode();
 171.426 +		pScene->mRootNode->mName.Set(std::string((const char*)pScene->mMeshes[0]->mTextureCoords[3]));
 171.427 +		pScene->mRootNode->mNumMeshes = 1;
 171.428 +		pScene->mRootNode->mMeshes = new unsigned int[1];
 171.429 +		pScene->mRootNode->mMeshes[0] = 0;
 171.430 +	}
 171.431 +	else
 171.432 +	{
 171.433 +		pScene->mRootNode = new aiNode();
 171.434 +		pScene->mRootNode->mNumChildren = pScene->mNumMeshes;
 171.435 +		pScene->mRootNode->mChildren = new aiNode*[pScene->mNumMeshes];
 171.436 +		pScene->mRootNode->mName.Set("<root>");
 171.437 +		for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
 171.438 +		{
 171.439 +			aiNode* pcNode = pScene->mRootNode->mChildren[i] = new aiNode();
 171.440 +			pcNode->mParent = pScene->mRootNode;
 171.441 +			pcNode->mName.Set(std::string((const char*)pScene->mMeshes[i]->mTextureCoords[3]));
 171.442 +			pcNode->mNumMeshes = 1;
 171.443 +			pcNode->mMeshes = new unsigned int[1];
 171.444 +			pcNode->mMeshes[0] = i;
 171.445 +		}
 171.446 +	}
 171.447 +
 171.448 +	// make sure we invalidate the pointer to the mesh name
 171.449 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
 171.450 +		pScene->mMeshes[i]->mTextureCoords[3] = NULL;
 171.451 +
 171.452 +	// create materials
 171.453 +	pScene->mNumMaterials = (unsigned int)aszShaders.size();
 171.454 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
 171.455 +	for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
 171.456 +	{
 171.457 +		aiMaterial* pcMat = new aiMaterial();
 171.458 +		pScene->mMaterials[i] = pcMat;
 171.459 +
 171.460 +		const std::string& name = aszShaders[i];
 171.461 +
 171.462 +		int iMode = (int)aiShadingMode_Gouraud;
 171.463 +		pcMat->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
 171.464 +
 171.465 +		// add a small ambient color value - RtCW seems to have one
 171.466 +		aiColor3D clr;
 171.467 +		clr.b = clr.g = clr.r = 0.05f;
 171.468 +		pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
 171.469 +
 171.470 +		if (name.length())clr.b = clr.g = clr.r = 1.0f;
 171.471 +		else clr.b = clr.g = clr.r = 0.6f;
 171.472 +
 171.473 +		pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
 171.474 +		pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
 171.475 +
 171.476 +		if (name.length())
 171.477 +		{
 171.478 +			aiString path;
 171.479 +			path.Set(name);
 171.480 +			pcMat->AddProperty(&path,AI_MATKEY_TEXTURE_DIFFUSE(0));
 171.481 +		}
 171.482 +	}
 171.483 +}
 171.484 +
 171.485 +#endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER
   172.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   172.2 +++ b/libs/assimp/MDCLoader.h	Sat Feb 01 19:58:19 2014 +0200
   172.3 @@ -0,0 +1,128 @@
   172.4 +/*
   172.5 +Open Asset Import Library (assimp)
   172.6 +----------------------------------------------------------------------
   172.7 +
   172.8 +Copyright (c) 2006-2012, assimp team
   172.9 +All rights reserved.
  172.10 +
  172.11 +Redistribution and use of this software in source and binary forms, 
  172.12 +with or without modification, are permitted provided that the 
  172.13 +following conditions are met:
  172.14 +
  172.15 +* Redistributions of source code must retain the above
  172.16 +  copyright notice, this list of conditions and the
  172.17 +  following disclaimer.
  172.18 +
  172.19 +* Redistributions in binary form must reproduce the above
  172.20 +  copyright notice, this list of conditions and the
  172.21 +  following disclaimer in the documentation and/or other
  172.22 +  materials provided with the distribution.
  172.23 +
  172.24 +* Neither the name of the assimp team, nor the names of its
  172.25 +  contributors may be used to endorse or promote products
  172.26 +  derived from this software without specific prior
  172.27 +  written permission of the assimp team.
  172.28 +
  172.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  172.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  172.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  172.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  172.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  172.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  172.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  172.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  172.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  172.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  172.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  172.40 +
  172.41 +----------------------------------------------------------------------
  172.42 +*/
  172.43 +
  172.44 +/** @file  MDCLoader.h
  172.45 + *  @brief Definition of the MDC importer class. 
  172.46 + */
  172.47 +#ifndef AI_MDCLOADER_H_INCLUDED
  172.48 +#define AI_MDCLOADER_H_INCLUDED
  172.49 +
  172.50 +#include "assimp/types.h"
  172.51 +
  172.52 +#include "BaseImporter.h"
  172.53 +#include "MDCFileData.h"
  172.54 +#include "ByteSwap.h"
  172.55 +
  172.56 +namespace Assimp	{
  172.57 +using namespace MDC;
  172.58 +
  172.59 +// ---------------------------------------------------------------------------
  172.60 +/** Importer class to load the RtCW MDC file format
  172.61 +*/
  172.62 +class MDCImporter : public BaseImporter
  172.63 +{
  172.64 +public:
  172.65 +	MDCImporter();
  172.66 +	~MDCImporter();
  172.67 +
  172.68 +
  172.69 +public:
  172.70 +
  172.71 +	// -------------------------------------------------------------------
  172.72 +	/** Returns whether the class can handle the format of the given file. 
  172.73 +	* See BaseImporter::CanRead() for details.	*/
  172.74 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  172.75 +		bool checkSig) const;
  172.76 +
  172.77 +	// -------------------------------------------------------------------
  172.78 +	/** Called prior to ReadFile().
  172.79 +	* The function is a request to the importer to update its configuration
  172.80 +	* basing on the Importer's configuration property list.
  172.81 +	*/
  172.82 +	void SetupProperties(const Importer* pImp);
  172.83 +
  172.84 +protected:
  172.85 +
  172.86 +	// -------------------------------------------------------------------
  172.87 +	/** Return importer meta information.
  172.88 +	 * See #BaseImporter::GetInfo for the details
  172.89 +	 */
  172.90 +	const aiImporterDesc* GetInfo () const;
  172.91 +
  172.92 +	// -------------------------------------------------------------------
  172.93 +	/** Imports the given file into the given scene structure. 
  172.94 +	* See BaseImporter::InternReadFile() for details
  172.95 +	*/
  172.96 +	void InternReadFile( const std::string& pFile, aiScene* pScene,
  172.97 +		IOSystem* pIOHandler);
  172.98 +
  172.99 +protected:
 172.100 +
 172.101 +
 172.102 +	// -------------------------------------------------------------------
 172.103 +	/** Validate the header of the file
 172.104 +	*/
 172.105 +	void ValidateHeader();
 172.106 +
 172.107 +	// -------------------------------------------------------------------
 172.108 +	/** Validate the header of a MDC surface
 172.109 +	*/
 172.110 +	void ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf);
 172.111 +
 172.112 +protected:
 172.113 +
 172.114 +
 172.115 +	/** Configuration option: frame to be loaded */
 172.116 +	unsigned int configFrameID;
 172.117 +
 172.118 +	/** Header of the MDC file */
 172.119 +	BE_NCONST MDC::Header* pcHeader;
 172.120 +
 172.121 +	/** Buffer to hold the loaded file */
 172.122 +	unsigned char* mBuffer;
 172.123 +
 172.124 +	/** size of the file, in bytes */
 172.125 +	unsigned int fileSize;
 172.126 +};
 172.127 +
 172.128 +} // end of namespace Assimp
 172.129 +
 172.130 +#endif // AI_3DSIMPORTER_H_INC
 172.131 +
   173.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   173.2 +++ b/libs/assimp/MDCNormalTable.h	Sat Feb 01 19:58:19 2014 +0200
   173.3 @@ -0,0 +1,299 @@
   173.4 +/* -----------------------------------------------------------------------------
   173.5 +
   173.6 +PicoModel Library 
   173.7 +
   173.8 +Copyright (c) 2002, Randy Reddig & seaw0lf
   173.9 +All rights reserved.
  173.10 +
  173.11 +Redistribution and use in source and binary forms, with or without modification,
  173.12 +are permitted provided that the following conditions are met:
  173.13 +
  173.14 +Redistributions of source code must retain the above copyright notice, this list
  173.15 +of conditions and the following disclaimer.
  173.16 +
  173.17 +Redistributions in binary form must reproduce the above copyright notice, this
  173.18 +list of conditions and the following disclaimer in the documentation and/or
  173.19 +other materials provided with the distribution.
  173.20 +
  173.21 +Neither the names of the copyright holders nor the names of its contributors may
  173.22 +be used to endorse or promote products derived from this software without
  173.23 +specific prior written permission. 
  173.24 +
  173.25 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  173.26 +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  173.27 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  173.28 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  173.29 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  173.30 +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  173.31 +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  173.32 +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  173.33 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  173.34 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  173.35 +
  173.36 +----------------------------------------------------------------------------- */
  173.37 +
  173.38 +#if (!defined MDC_NORMAL_TABLE_INCLUDED)
  173.39 +#define MDC_NORMAL_TABLE_INCLUDED
  173.40 +
  173.41 +/* mdc decoding normal table */
  173.42 +float mdcNormals[ 256 ][ 3 ] =
  173.43 +{
  173.44 +	{ 1.000000f, 0.000000f, 0.000000f },
  173.45 +	{ 0.980785f, 0.195090f, 0.000000f },
  173.46 +	{ 0.923880f, 0.382683f, 0.000000f },
  173.47 +	{ 0.831470f, 0.555570f, 0.000000f },
  173.48 +	{ 0.707107f, 0.707107f, 0.000000f },
  173.49 +	{ 0.555570f, 0.831470f, 0.000000f },
  173.50 +	{ 0.382683f, 0.923880f, 0.000000f },
  173.51 +	{ 0.195090f, 0.980785f, 0.000000f },
  173.52 +	{ -0.000000f, 1.000000f, 0.000000f },
  173.53 +	{ -0.195090f, 0.980785f, 0.000000f },
  173.54 +	{ -0.382683f, 0.923880f, 0.000000f },
  173.55 +	{ -0.555570f, 0.831470f, 0.000000f },
  173.56 +	{ -0.707107f, 0.707107f, 0.000000f },
  173.57 +	{ -0.831470f, 0.555570f, 0.000000f },
  173.58 +	{ -0.923880f, 0.382683f, 0.000000f },
  173.59 +	{ -0.980785f, 0.195090f, 0.000000f },
  173.60 +	{ -1.000000f, -0.000000f, 0.000000f },
  173.61 +	{ -0.980785f, -0.195090f, 0.000000f },
  173.62 +	{ -0.923880f, -0.382683f, 0.000000f },
  173.63 +	{ -0.831470f, -0.555570f, 0.000000f },
  173.64 +	{ -0.707107f, -0.707107f, 0.000000f },
  173.65 +	{ -0.555570f, -0.831469f, 0.000000f },
  173.66 +	{ -0.382684f, -0.923880f, 0.000000f },
  173.67 +	{ -0.195090f, -0.980785f, 0.000000f },
  173.68 +	{ 0.000000f, -1.000000f, 0.000000f },
  173.69 +	{ 0.195090f, -0.980785f, 0.000000f },
  173.70 +	{ 0.382684f, -0.923879f, 0.000000f },
  173.71 +	{ 0.555570f, -0.831470f, 0.000000f },
  173.72 +	{ 0.707107f, -0.707107f, 0.000000f },
  173.73 +	{ 0.831470f, -0.555570f, 0.000000f },
  173.74 +	{ 0.923880f, -0.382683f, 0.000000f },
  173.75 +	{ 0.980785f, -0.195090f, 0.000000f },
  173.76 +	{ 0.980785f, 0.000000f, -0.195090f },
  173.77 +	{ 0.956195f, 0.218245f, -0.195090f },
  173.78 +	{ 0.883657f, 0.425547f, -0.195090f },
  173.79 +	{ 0.766809f, 0.611510f, -0.195090f },
  173.80 +	{ 0.611510f, 0.766809f, -0.195090f },
  173.81 +	{ 0.425547f, 0.883657f, -0.195090f },
  173.82 +	{ 0.218245f, 0.956195f, -0.195090f },
  173.83 +	{ -0.000000f, 0.980785f, -0.195090f },
  173.84 +	{ -0.218245f, 0.956195f, -0.195090f },
  173.85 +	{ -0.425547f, 0.883657f, -0.195090f },
  173.86 +	{ -0.611510f, 0.766809f, -0.195090f },
  173.87 +	{ -0.766809f, 0.611510f, -0.195090f },
  173.88 +	{ -0.883657f, 0.425547f, -0.195090f },
  173.89 +	{ -0.956195f, 0.218245f, -0.195090f },
  173.90 +	{ -0.980785f, -0.000000f, -0.195090f },
  173.91 +	{ -0.956195f, -0.218245f, -0.195090f },
  173.92 +	{ -0.883657f, -0.425547f, -0.195090f },
  173.93 +	{ -0.766809f, -0.611510f, -0.195090f },
  173.94 +	{ -0.611510f, -0.766809f, -0.195090f },
  173.95 +	{ -0.425547f, -0.883657f, -0.195090f },
  173.96 +	{ -0.218245f, -0.956195f, -0.195090f },
  173.97 +	{ 0.000000f, -0.980785f, -0.195090f },
  173.98 +	{ 0.218245f, -0.956195f, -0.195090f },
  173.99 +	{ 0.425547f, -0.883657f, -0.195090f },
 173.100 +	{ 0.611510f, -0.766809f, -0.195090f },
 173.101 +	{ 0.766809f, -0.611510f, -0.195090f },
 173.102 +	{ 0.883657f, -0.425547f, -0.195090f },
 173.103 +	{ 0.956195f, -0.218245f, -0.195090f },
 173.104 +	{ 0.923880f, 0.000000f, -0.382683f },
 173.105 +	{ 0.892399f, 0.239118f, -0.382683f },
 173.106 +	{ 0.800103f, 0.461940f, -0.382683f },
 173.107 +	{ 0.653281f, 0.653281f, -0.382683f },
 173.108 +	{ 0.461940f, 0.800103f, -0.382683f },
 173.109 +	{ 0.239118f, 0.892399f, -0.382683f },
 173.110 +	{ -0.000000f, 0.923880f, -0.382683f },
 173.111 +	{ -0.239118f, 0.892399f, -0.382683f },
 173.112 +	{ -0.461940f, 0.800103f, -0.382683f },
 173.113 +	{ -0.653281f, 0.653281f, -0.382683f },
 173.114 +	{ -0.800103f, 0.461940f, -0.382683f },
 173.115 +	{ -0.892399f, 0.239118f, -0.382683f },
 173.116 +	{ -0.923880f, -0.000000f, -0.382683f },
 173.117 +	{ -0.892399f, -0.239118f, -0.382683f },
 173.118 +	{ -0.800103f, -0.461940f, -0.382683f },
 173.119 +	{ -0.653282f, -0.653281f, -0.382683f },
 173.120 +	{ -0.461940f, -0.800103f, -0.382683f },
 173.121 +	{ -0.239118f, -0.892399f, -0.382683f },
 173.122 +	{ 0.000000f, -0.923880f, -0.382683f },
 173.123 +	{ 0.239118f, -0.892399f, -0.382683f },
 173.124 +	{ 0.461940f, -0.800103f, -0.382683f },
 173.125 +	{ 0.653281f, -0.653282f, -0.382683f },
 173.126 +	{ 0.800103f, -0.461940f, -0.382683f },
 173.127 +	{ 0.892399f, -0.239117f, -0.382683f },
 173.128 +	{ 0.831470f, 0.000000f, -0.555570f },
 173.129 +	{ 0.790775f, 0.256938f, -0.555570f },
 173.130 +	{ 0.672673f, 0.488726f, -0.555570f },
 173.131 +	{ 0.488726f, 0.672673f, -0.555570f },
 173.132 +	{ 0.256938f, 0.790775f, -0.555570f },
 173.133 +	{ -0.000000f, 0.831470f, -0.555570f },
 173.134 +	{ -0.256938f, 0.790775f, -0.555570f },
 173.135 +	{ -0.488726f, 0.672673f, -0.555570f },
 173.136 +	{ -0.672673f, 0.488726f, -0.555570f },
 173.137 +	{ -0.790775f, 0.256938f, -0.555570f },
 173.138 +	{ -0.831470f, -0.000000f, -0.555570f },
 173.139 +	{ -0.790775f, -0.256938f, -0.555570f },
 173.140 +	{ -0.672673f, -0.488726f, -0.555570f },
 173.141 +	{ -0.488725f, -0.672673f, -0.555570f },
 173.142 +	{ -0.256938f, -0.790775f, -0.555570f },
 173.143 +	{ 0.000000f, -0.831470f, -0.555570f },
 173.144 +	{ 0.256938f, -0.790775f, -0.555570f },
 173.145 +	{ 0.488725f, -0.672673f, -0.555570f },
 173.146 +	{ 0.672673f, -0.488726f, -0.555570f },
 173.147 +	{ 0.790775f, -0.256938f, -0.555570f },
 173.148 +	{ 0.707107f, 0.000000f, -0.707107f },
 173.149 +	{ 0.653281f, 0.270598f, -0.707107f },
 173.150 +	{ 0.500000f, 0.500000f, -0.707107f },
 173.151 +	{ 0.270598f, 0.653281f, -0.707107f },
 173.152 +	{ -0.000000f, 0.707107f, -0.707107f },
 173.153 +	{ -0.270598f, 0.653282f, -0.707107f },
 173.154 +	{ -0.500000f, 0.500000f, -0.707107f },
 173.155 +	{ -0.653281f, 0.270598f, -0.707107f },
 173.156 +	{ -0.707107f, -0.000000f, -0.707107f },
 173.157 +	{ -0.653281f, -0.270598f, -0.707107f },
 173.158 +	{ -0.500000f, -0.500000f, -0.707107f },
 173.159 +	{ -0.270598f, -0.653281f, -0.707107f },
 173.160 +	{ 0.000000f, -0.707107f, -0.707107f },
 173.161 +	{ 0.270598f, -0.653281f, -0.707107f },
 173.162 +	{ 0.500000f, -0.500000f, -0.707107f },
 173.163 +	{ 0.653282f, -0.270598f, -0.707107f },
 173.164 +	{ 0.555570f, 0.000000f, -0.831470f },
 173.165 +	{ 0.481138f, 0.277785f, -0.831470f },
 173.166 +	{ 0.277785f, 0.481138f, -0.831470f },
 173.167 +	{ -0.000000f, 0.555570f, -0.831470f },
 173.168 +	{ -0.277785f, 0.481138f, -0.831470f },
 173.169 +	{ -0.481138f, 0.277785f, -0.831470f },
 173.170 +	{ -0.555570f, -0.000000f, -0.831470f },
 173.171 +	{ -0.481138f, -0.277785f, -0.831470f },
 173.172 +	{ -0.277785f, -0.481138f, -0.831470f },
 173.173 +	{ 0.000000f, -0.555570f, -0.831470f },
 173.174 +	{ 0.277785f, -0.481138f, -0.831470f },
 173.175 +	{ 0.481138f, -0.277785f, -0.831470f },
 173.176 +	{ 0.382683f, 0.000000f, -0.923880f },
 173.177 +	{ 0.270598f, 0.270598f, -0.923880f },
 173.178 +	{ -0.000000f, 0.382683f, -0.923880f },
 173.179 +	{ -0.270598f, 0.270598f, -0.923880f },
 173.180 +	{ -0.382683f, -0.000000f, -0.923880f },
 173.181 +	{ -0.270598f, -0.270598f, -0.923880f },
 173.182 +	{ 0.000000f, -0.382683f, -0.923880f },
 173.183 +	{ 0.270598f, -0.270598f, -0.923880f },
 173.184 +	{ 0.195090f, 0.000000f, -0.980785f },
 173.185 +	{ -0.000000f, 0.195090f, -0.980785f },
 173.186 +	{ -0.195090f, -0.000000f, -0.980785f },
 173.187 +	{ 0.000000f, -0.195090f, -0.980785f },
 173.188 +	{ 0.980785f, 0.000000f, 0.195090f },
 173.189 +	{ 0.956195f, 0.218245f, 0.195090f },
 173.190 +	{ 0.883657f, 0.425547f, 0.195090f },
 173.191 +	{ 0.766809f, 0.611510f, 0.195090f },
 173.192 +	{ 0.611510f, 0.766809f, 0.195090f },
 173.193 +	{ 0.425547f, 0.883657f, 0.195090f },
 173.194 +	{ 0.218245f, 0.956195f, 0.195090f },
 173.195 +	{ -0.000000f, 0.980785f, 0.195090f },
 173.196 +	{ -0.218245f, 0.956195f, 0.195090f },
 173.197 +	{ -0.425547f, 0.883657f, 0.195090f },
 173.198 +	{ -0.611510f, 0.766809f, 0.195090f },
 173.199 +	{ -0.766809f, 0.611510f, 0.195090f },
 173.200 +	{ -0.883657f, 0.425547f, 0.195090f },
 173.201 +	{ -0.956195f, 0.218245f, 0.195090f },
 173.202 +	{ -0.980785f, -0.000000f, 0.195090f },
 173.203 +	{ -0.956195f, -0.218245f, 0.195090f },
 173.204 +	{ -0.883657f, -0.425547f, 0.195090f },
 173.205 +	{ -0.766809f, -0.611510f, 0.195090f },
 173.206 +	{ -0.611510f, -0.766809f, 0.195090f },
 173.207 +	{ -0.425547f, -0.883657f, 0.195090f },
 173.208 +	{ -0.218245f, -0.956195f, 0.195090f },
 173.209 +	{ 0.000000f, -0.980785f, 0.195090f },
 173.210 +	{ 0.218245f, -0.956195f, 0.195090f },
 173.211 +	{ 0.425547f, -0.883657f, 0.195090f },
 173.212 +	{ 0.611510f, -0.766809f, 0.195090f },
 173.213 +	{ 0.766809f, -0.611510f, 0.195090f },
 173.214 +	{ 0.883657f, -0.425547f, 0.195090f },
 173.215 +	{ 0.956195f, -0.218245f, 0.195090f },
 173.216 +	{ 0.923880f, 0.000000f, 0.382683f },
 173.217 +	{ 0.892399f, 0.239118f, 0.382683f },
 173.218 +	{ 0.800103f, 0.461940f, 0.382683f },
 173.219 +	{ 0.653281f, 0.653281f, 0.382683f },
 173.220 +	{ 0.461940f, 0.800103f, 0.382683f },
 173.221 +	{ 0.239118f, 0.892399f, 0.382683f },
 173.222 +	{ -0.000000f, 0.923880f, 0.382683f },
 173.223 +	{ -0.239118f, 0.892399f, 0.382683f },
 173.224 +	{ -0.461940f, 0.800103f, 0.382683f },
 173.225 +	{ -0.653281f, 0.653281f, 0.382683f },
 173.226 +	{ -0.800103f, 0.461940f, 0.382683f },
 173.227 +	{ -0.892399f, 0.239118f, 0.382683f },
 173.228 +	{ -0.923880f, -0.000000f, 0.382683f },
 173.229 +	{ -0.892399f, -0.239118f, 0.382683f },
 173.230 +	{ -0.800103f, -0.461940f, 0.382683f },
 173.231 +	{ -0.653282f, -0.653281f, 0.382683f },
 173.232 +	{ -0.461940f, -0.800103f, 0.382683f },
 173.233 +	{ -0.239118f, -0.892399f, 0.382683f },
 173.234 +	{ 0.000000f, -0.923880f, 0.382683f },
 173.235 +	{ 0.239118f, -0.892399f, 0.382683f },
 173.236 +	{ 0.461940f, -0.800103f, 0.382683f },
 173.237 +	{ 0.653281f, -0.653282f, 0.382683f },
 173.238 +	{ 0.800103f, -0.461940f, 0.382683f },
 173.239 +	{ 0.892399f, -0.239117f, 0.382683f },
 173.240 +	{ 0.831470f, 0.000000f, 0.555570f },
 173.241 +	{ 0.790775f, 0.256938f, 0.555570f },
 173.242 +	{ 0.672673f, 0.488726f, 0.555570f },
 173.243 +	{ 0.488726f, 0.672673f, 0.555570f },
 173.244 +	{ 0.256938f, 0.790775f, 0.555570f },
 173.245 +	{ -0.000000f, 0.831470f, 0.555570f },
 173.246 +	{ -0.256938f, 0.790775f, 0.555570f },
 173.247 +	{ -0.488726f, 0.672673f, 0.555570f },
 173.248 +	{ -0.672673f, 0.488726f, 0.555570f },
 173.249 +	{ -0.790775f, 0.256938f, 0.555570f },
 173.250 +	{ -0.831470f, -0.000000f, 0.555570f },
 173.251 +	{ -0.790775f, -0.256938f, 0.555570f },
 173.252 +	{ -0.672673f, -0.488726f, 0.555570f },
 173.253 +	{ -0.488725f, -0.672673f, 0.555570f },
 173.254 +	{ -0.256938f, -0.790775f, 0.555570f },
 173.255 +	{ 0.000000f, -0.831470f, 0.555570f },
 173.256 +	{ 0.256938f, -0.790775f, 0.555570f },
 173.257 +	{ 0.488725f, -0.672673f, 0.555570f },
 173.258 +	{ 0.672673f, -0.488726f, 0.555570f },
 173.259 +	{ 0.790775f, -0.256938f, 0.555570f },
 173.260 +	{ 0.707107f, 0.000000f, 0.707107f },
 173.261 +	{ 0.653281f, 0.270598f, 0.707107f },
 173.262 +	{ 0.500000f, 0.500000f, 0.707107f },
 173.263 +	{ 0.270598f, 0.653281f, 0.707107f },
 173.264 +	{ -0.000000f, 0.707107f, 0.707107f },
 173.265 +	{ -0.270598f, 0.653282f, 0.707107f },
 173.266 +	{ -0.500000f, 0.500000f, 0.707107f },
 173.267 +	{ -0.653281f, 0.270598f, 0.707107f },
 173.268 +	{ -0.707107f, -0.000000f, 0.707107f },
 173.269 +	{ -0.653281f, -0.270598f, 0.707107f },
 173.270 +	{ -0.500000f, -0.500000f, 0.707107f },
 173.271 +	{ -0.270598f, -0.653281f, 0.707107f },
 173.272 +	{ 0.000000f, -0.707107f, 0.707107f },
 173.273 +	{ 0.270598f, -0.653281f, 0.707107f },
 173.274 +	{ 0.500000f, -0.500000f, 0.707107f },
 173.275 +	{ 0.653282f, -0.270598f, 0.707107f },
 173.276 +	{ 0.555570f, 0.000000f, 0.831470f },
 173.277 +	{ 0.481138f, 0.277785f, 0.831470f },
 173.278 +	{ 0.277785f, 0.481138f, 0.831470f },
 173.279 +	{ -0.000000f, 0.555570f, 0.831470f },
 173.280 +	{ -0.277785f, 0.481138f, 0.831470f },
 173.281 +	{ -0.481138f, 0.277785f, 0.831470f },
 173.282 +	{ -0.555570f, -0.000000f, 0.831470f },
 173.283 +	{ -0.481138f, -0.277785f, 0.831470f },
 173.284 +	{ -0.277785f, -0.481138f, 0.831470f },
 173.285 +	{ 0.000000f, -0.555570f, 0.831470f },
 173.286 +	{ 0.277785f, -0.481138f, 0.831470f },
 173.287 +	{ 0.481138f, -0.277785f, 0.831470f },
 173.288 +	{ 0.382683f, 0.000000f, 0.923880f },
 173.289 +	{ 0.270598f, 0.270598f, 0.923880f },
 173.290 +	{ -0.000000f, 0.382683f, 0.923880f },
 173.291 +	{ -0.270598f, 0.270598f, 0.923880f },
 173.292 +	{ -0.382683f, -0.000000f, 0.923880f },
 173.293 +	{ -0.270598f, -0.270598f, 0.923880f },
 173.294 +	{ 0.000000f, -0.382683f, 0.923880f },
 173.295 +	{ 0.270598f, -0.270598f, 0.923880f },
 173.296 +	{ 0.195090f, 0.000000f, 0.980785f },
 173.297 +	{ -0.000000f, 0.195090f, 0.980785f },
 173.298 +	{ -0.195090f, -0.000000f, 0.980785f },
 173.299 +	{ 0.000000f, -0.195090f, 0.980785f }
 173.300 +};
 173.301 +
 173.302 +#endif // !! MDC_NORMAL_TABLE_INCLUDED
   174.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   174.2 +++ b/libs/assimp/MDLDefaultColorMap.h	Sat Feb 01 19:58:19 2014 +0200
   174.3 @@ -0,0 +1,118 @@
   174.4 +/*
   174.5 +Open Asset Import Library (assimp)
   174.6 +----------------------------------------------------------------------
   174.7 +
   174.8 +Copyright (c) 2006-2012, assimp team
   174.9 +All rights reserved.
  174.10 +
  174.11 +Redistribution and use of this software in source and binary forms, 
  174.12 +with or without modification, are permitted provided that the 
  174.13 +following conditions are met:
  174.14 +
  174.15 +* Redistributions of source code must retain the above
  174.16 +  copyright notice, this list of conditions and the
  174.17 +  following disclaimer.
  174.18 +
  174.19 +* Redistributions in binary form must reproduce the above
  174.20 +  copyright notice, this list of conditions and the
  174.21 +  following disclaimer in the documentation and/or other
  174.22 +  materials provided with the distribution.
  174.23 +
  174.24 +* Neither the name of the assimp team, nor the names of its
  174.25 +  contributors may be used to endorse or promote products
  174.26 +  derived from this software without specific prior
  174.27 +  written permission of the assimp team.
  174.28 +
  174.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  174.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  174.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  174.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  174.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  174.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  174.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  174.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  174.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  174.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  174.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  174.40 +
  174.41 +----------------------------------------------------------------------
  174.42 +*/
  174.43 +
  174.44 +
  174.45 +/** @file Defines the default color map used for Quake 1 model textures
  174.46 + *
  174.47 + * The lib tries to load colormap.lmp from the model's directory.
  174.48 + * This table is only used when required.
  174.49 + */
  174.50 +
  174.51 +#ifndef AI_MDL_DEFAULTLMP_H_INC
  174.52 +#define AI_MDL_DEFAULTLMP_H_INC
  174.53 +
  174.54 +const unsigned char g_aclrDefaultColorMap[256][3] = {
  174.55 +{  0,   0,   0}, { 15,  15,  15}, { 31,  31,  31}, { 47,  47,  47}, 
  174.56 +{ 63,  63,  63}, { 75,  75,  75}, { 91,  91,  91}, {107, 107, 107}, 
  174.57 +{123, 123, 123}, {139, 139, 139}, {155, 155, 155}, {171, 171, 171}, 
  174.58 +{187, 187, 187}, {203, 203, 203}, {219, 219, 219}, {235, 235, 235}, 
  174.59 +{ 15,  11,   7}, { 23,  15,  11}, { 31,  23,  11}, { 39,  27,  15}, 
  174.60 +{ 47,  35,  19}, { 55,  43,  23}, { 63,  47,  23}, { 75,  55,  27}, 
  174.61 +{ 83,  59,  27}, { 91,  67,  31}, { 99,  75,  31}, {107,  83,  31}, 
  174.62 +{115,  87,  31}, {123,  95,  35}, {131, 103,  35}, {143, 111,  35}, 
  174.63 +{ 11,  11,  15}, { 19,  19,  27}, { 27,  27,  39}, { 39,  39,  51}, 
  174.64 +{ 47,  47,  63}, { 55,  55,  75}, { 63,  63,  87}, { 71,  71, 103}, 
  174.65 +{ 79,  79, 115}, { 91,  91, 127}, { 99,  99, 139}, {107, 107, 151}, 
  174.66 +{115, 115, 163}, {123, 123, 175}, {131, 131, 187}, {139, 139, 203}, 
  174.67 +{  0,   0,   0}, {  7,   7,   0}, { 11,  11,   0}, { 19,  19,   0}, 
  174.68 +{ 27,  27,   0}, { 35,  35,   0}, { 43,  43,   7}, { 47,  47,   7}, 
  174.69 +{ 55,  55,   7}, { 63,  63,   7}, { 71,  71,   7}, { 75,  75,  11}, 
  174.70 +{ 83,  83,  11}, { 91,  91,  11}, { 99,  99,  11}, {107, 107,  15}, 
  174.71 +{  7,   0,   0}, { 15,   0,   0}, { 23,   0,   0}, { 31,   0,   0}, 
  174.72 +{ 39,   0,   0}, { 47,   0,   0}, { 55,   0,   0}, { 63,   0,   0}, 
  174.73 +{ 71,   0,   0}, { 79,   0,   0}, { 87,   0,   0}, { 95,   0,   0}, 
  174.74 +{103,   0,   0}, {111,   0,   0}, {119,   0,   0}, {127,   0,   0}, 
  174.75 +{ 19,  19,   0}, { 27,  27,   0}, { 35,  35,   0}, { 47,  43,   0}, 
  174.76 +{ 55,  47,   0}, { 67,  55,   0}, { 75,  59,   7}, { 87,  67,   7}, 
  174.77 +{ 95,  71,   7}, {107,  75,  11}, {119,  83,  15}, {131,  87,  19}, 
  174.78 +{139,  91,  19}, {151,  95,  27}, {163,  99,  31}, {175, 103,  35}, 
  174.79 +{ 35,  19,   7}, { 47,  23,  11}, { 59,  31,  15}, { 75,  35,  19}, 
  174.80 +{ 87,  43,  23}, { 99,  47,  31}, {115,  55,  35}, {127,  59,  43}, 
  174.81 +{143,  67,  51}, {159,  79,  51}, {175,  99,  47}, {191, 119,  47}, 
  174.82 +{207, 143,  43}, {223, 171,  39}, {239, 203,  31}, {255, 243,  27}, 
  174.83 +{ 11,   7,   0}, { 27,  19,   0}, { 43,  35,  15}, { 55,  43,  19}, 
  174.84 +{ 71,  51,  27}, { 83,  55,  35}, { 99,  63,  43}, {111,  71,  51}, 
  174.85 +{127,  83,  63}, {139,  95,  71}, {155, 107,  83}, {167, 123,  95}, 
  174.86 +{183, 135, 107}, {195, 147, 123}, {211, 163, 139}, {227, 179, 151}, 
  174.87 +{171, 139, 163}, {159, 127, 151}, {147, 115, 135}, {139, 103, 123}, 
  174.88 +{127,  91, 111}, {119,  83,  99}, {107,  75,  87}, { 95,  63,  75}, 
  174.89 +{ 87,  55,  67}, { 75,  47,  55}, { 67,  39,  47}, { 55,  31,  35}, 
  174.90 +{ 43,  23,  27}, { 35,  19,  19}, { 23,  11,  11}, { 15,   7,   7}, 
  174.91 +{187, 115, 159}, {175, 107, 143}, {163,  95, 131}, {151,  87, 119}, 
  174.92 +{139,  79, 107}, {127,  75,  95}, {115,  67,  83}, {107,  59,  75}, 
  174.93 +{ 95,  51,  63}, { 83,  43,  55}, { 71,  35,  43}, { 59,  31,  35}, 
  174.94 +{ 47,  23,  27}, { 35,  19,  19}, { 23,  11,  11}, { 15,   7,   7}, 
  174.95 +{219, 195, 187}, {203, 179, 167}, {191, 163, 155}, {175, 151, 139}, 
  174.96 +{163, 135, 123}, {151, 123, 111}, {135, 111,  95}, {123,  99,  83}, 
  174.97 +{107,  87,  71}, { 95,  75,  59}, { 83,  63,  51}, { 67,  51,  39}, 
  174.98 +{ 55,  43,  31}, { 39,  31,  23}, { 27,  19,  15}, { 15,  11,   7}, 
  174.99 +{111, 131, 123}, {103, 123, 111}, { 95, 115, 103}, { 87, 107,  95}, 
 174.100 +{ 79,  99,  87}, { 71,  91,  79}, { 63,  83,  71}, { 55,  75,  63}, 
 174.101 +{ 47,  67,  55}, { 43,  59,  47}, { 35,  51,  39}, { 31,  43,  31}, 
 174.102 +{ 23,  35,  23}, { 15,  27,  19}, { 11,  19,  11}, {  7,  11,   7}, 
 174.103 +{255, 243,  27}, {239, 223,  23}, {219, 203,  19}, {203, 183,  15}, 
 174.104 +{187, 167,  15}, {171, 151,  11}, {155, 131,   7}, {139, 115,   7}, 
 174.105 +{123,  99,   7}, {107,  83,   0}, { 91,  71,   0}, { 75,  55,   0}, 
 174.106 +{ 59,  43,   0}, { 43,  31,   0}, { 27,  15,   0}, { 11,   7,   0}, 
 174.107 +{  0,   0, 255}, { 11,  11, 239}, { 19,  19, 223}, { 27,  27, 207}, 
 174.108 +{ 35,  35, 191}, { 43,  43, 175}, { 47,  47, 159}, { 47,  47, 143}, 
 174.109 +{ 47,  47, 127}, { 47,  47, 111}, { 47,  47,  95}, { 43,  43,  79}, 
 174.110 +{ 35,  35,  63}, { 27,  27,  47}, { 19,  19,  31}, { 11,  11,  15}, 
 174.111 +{ 43,   0,   0}, { 59,   0,   0}, { 75,   7,   0}, { 95,   7,   0}, 
 174.112 +{111,  15,   0}, {127,  23,   7}, {147,  31,   7}, {163,  39,  11}, 
 174.113 +{183,  51,  15}, {195,  75,  27}, {207,  99,  43}, {219, 127,  59}, 
 174.114 +{227, 151,  79}, {231, 171,  95}, {239, 191, 119}, {247, 211, 139}, 
 174.115 +{167, 123,  59}, {183, 155,  55}, {199, 195,  55}, {231, 227,  87}, 
 174.116 +{127, 191, 255}, {171, 231, 255}, {215, 255, 255}, {103,   0,   0}, 
 174.117 +{139,   0,   0}, {179,   0,   0}, {215,   0,   0}, {255,   0,   0}, 
 174.118 +{255, 243, 147}, {255, 247, 199}, {255, 255, 255}, {159,  91,  83} };
 174.119 +
 174.120 +
 174.121 +#endif // !! AI_MDL_DEFAULTLMP_H_INC
   175.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   175.2 +++ b/libs/assimp/MDLFileData.h	Sat Feb 01 19:58:19 2014 +0200
   175.3 @@ -0,0 +1,959 @@
   175.4 +/*
   175.5 +Open Asset Import Library (assimp)
   175.6 +----------------------------------------------------------------------
   175.7 +
   175.8 +Copyright (c) 2006-2012, assimp team
   175.9 +All rights reserved.
  175.10 +
  175.11 +Redistribution and use of this software in source and binary forms, 
  175.12 +with or without modification, are permitted provided that the 
  175.13 +following conditions are met:
  175.14 +
  175.15 +* Redistributions of source code must retain the above
  175.16 +  copyright notice, this list of conditions and the
  175.17 +  following disclaimer.
  175.18 +
  175.19 +* Redistributions in binary form must reproduce the above
  175.20 +  copyright notice, this list of conditions and the
  175.21 +  following disclaimer in the documentation and/or other
  175.22 +  materials provided with the distribution.
  175.23 +
  175.24 +* Neither the name of the assimp team, nor the names of its
  175.25 +  contributors may be used to endorse or promote products
  175.26 +  derived from this software without specific prior
  175.27 +  written permission of the assimp team.
  175.28 +
  175.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  175.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  175.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  175.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  175.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  175.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  175.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  175.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  175.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  175.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  175.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  175.40 +
  175.41 +----------------------------------------------------------------------
  175.42 +*/
  175.43 +
  175.44 +
  175.45 +/**
  175.46 + * @file  MDLFileData.h
  175.47 + * @brief Definition of in-memory structures for the MDL file format. 
  175.48 + *
  175.49 + * The specification has been taken from various sources on the internet.
  175.50 + * - http://tfc.duke.free.fr/coding/mdl-specs-en.html
  175.51 + * - Conitec's MED SDK
  175.52 + * - Many quite long HEX-editor sessions
  175.53 + */
  175.54 +
  175.55 +#ifndef AI_MDLFILEHELPER_H_INC
  175.56 +#define AI_MDLFILEHELPER_H_INC
  175.57 +
  175.58 +#include "assimp/Compiler/pushpack1.h"
  175.59 +
  175.60 +namespace Assimp	{
  175.61 +namespace MDL	{
  175.62 +
  175.63 +// -------------------------------------------------------------------------------------
  175.64 +// to make it easier for us, we test the magic word against both "endianesses"
  175.65 +
  175.66 +// magic bytes used in Quake 1 MDL meshes
  175.67 +#define AI_MDL_MAGIC_NUMBER_BE	AI_MAKE_MAGIC("IDPO")
  175.68 +#define AI_MDL_MAGIC_NUMBER_LE	AI_MAKE_MAGIC("OPDI")
  175.69 +
  175.70 +// magic bytes used in GameStudio A<very  low> MDL meshes
  175.71 +#define AI_MDL_MAGIC_NUMBER_BE_GS3	AI_MAKE_MAGIC("MDL2")
  175.72 +#define AI_MDL_MAGIC_NUMBER_LE_GS3	AI_MAKE_MAGIC("2LDM")
  175.73 +
  175.74 +// magic bytes used in GameStudio A4 MDL meshes
  175.75 +#define AI_MDL_MAGIC_NUMBER_BE_GS4	AI_MAKE_MAGIC("MDL3")
  175.76 +#define AI_MDL_MAGIC_NUMBER_LE_GS4	AI_MAKE_MAGIC("3LDM")
  175.77 +
  175.78 +// magic bytes used in GameStudio A5+ MDL meshes
  175.79 +#define AI_MDL_MAGIC_NUMBER_BE_GS5a	AI_MAKE_MAGIC("MDL4")
  175.80 +#define AI_MDL_MAGIC_NUMBER_LE_GS5a	AI_MAKE_MAGIC("4LDM")
  175.81 +#define AI_MDL_MAGIC_NUMBER_BE_GS5b	AI_MAKE_MAGIC("MDL5")
  175.82 +#define AI_MDL_MAGIC_NUMBER_LE_GS5b	AI_MAKE_MAGIC("5LDM")
  175.83 +
  175.84 +// magic bytes used in GameStudio A7+ MDL meshes
  175.85 +#define AI_MDL_MAGIC_NUMBER_BE_GS7	AI_MAKE_MAGIC("MDL7")
  175.86 +#define AI_MDL_MAGIC_NUMBER_LE_GS7	AI_MAKE_MAGIC("7LDM")
  175.87 +
  175.88 +
  175.89 +// common limitations for Quake1 meshes. The loader does not check them,
  175.90 +// (however it warns) but models should not exceed these limits.
  175.91 +#if (!defined AI_MDL_VERSION)
  175.92 +#	define AI_MDL_VERSION				6
  175.93 +#endif
  175.94 +#if (!defined AI_MDL_MAX_FRAMES)
  175.95 +#	define AI_MDL_MAX_FRAMES			256
  175.96 +#endif
  175.97 +#if (!defined AI_MDL_MAX_UVS)
  175.98 +#	define AI_MDL_MAX_UVS				1024	
  175.99 +#endif
 175.100 +#if (!defined AI_MDL_MAX_VERTS)
 175.101 +#	define AI_MDL_MAX_VERTS				1024
 175.102 +#endif
 175.103 +#if (!defined AI_MDL_MAX_TRIANGLES)
 175.104 +#	define AI_MDL_MAX_TRIANGLES			2048	
 175.105 +#endif
 175.106 +
 175.107 +// material key that is set for dummy materials that are
 175.108 +// just referencing another material
 175.109 +#if (!defined AI_MDL7_REFERRER_MATERIAL)
 175.110 +#	define AI_MDL7_REFERRER_MATERIAL "&&&referrer&&&",0,0
 175.111 +#endif
 175.112 +
 175.113 +// -------------------------------------------------------------------------------------
 175.114 +/** \struct Header
 175.115 + *  \brief Data structure for the MDL main header
 175.116 + */
 175.117 +struct Header
 175.118 +{
 175.119 +	//! magic number: "IDPO"
 175.120 +	uint32_t ident;          
 175.121 +
 175.122 +	//! version number: 6
 175.123 +	int32_t version;          
 175.124 +
 175.125 +	//! scale factors for each axis
 175.126 +	aiVector3D scale;				
 175.127 +
 175.128 +	//! translation factors for each axis
 175.129 +	aiVector3D translate;	
 175.130 +
 175.131 +	//! bounding radius of the mesh
 175.132 +	float boundingradius;
 175.133 +	 
 175.134 +	//! Position of the viewer's exe. Ignored
 175.135 +	aiVector3D vEyePos;
 175.136 +
 175.137 +	//! Number of textures
 175.138 +	int32_t num_skins;       
 175.139 +
 175.140 +	//! Texture width in pixels
 175.141 +	int32_t skinwidth;
 175.142 +
 175.143 +	//! Texture height in pixels
 175.144 +	int32_t skinheight;       
 175.145 +
 175.146 +	//! Number of vertices contained in the file
 175.147 +	int32_t num_verts;       
 175.148 +
 175.149 +	//! Number of triangles contained in the file
 175.150 +	int32_t num_tris;         
 175.151 +
 175.152 +	//! Number of frames contained in the file
 175.153 +	int32_t num_frames;      
 175.154 +
 175.155 +	//! 0 = synchron, 1 = random . Ignored
 175.156 +	//! (MDLn formats: number of texture coordinates)
 175.157 +	int32_t synctype;         
 175.158 +
 175.159 +	//! State flag
 175.160 +	int32_t flags;     
 175.161 +
 175.162 +	//! Could be the total size of the file (and not a float)
 175.163 +	float size;
 175.164 +} PACK_STRUCT;
 175.165 +
 175.166 +
 175.167 +// -------------------------------------------------------------------------------------
 175.168 +/** \struct Header_MDL7
 175.169 + *  \brief Data structure for the MDL 7 main header
 175.170 + */
 175.171 +struct Header_MDL7
 175.172 +{
 175.173 +	//! magic number: "MDL7"
 175.174 +	char	ident[4];		
 175.175 +
 175.176 +	//! Version number. Ignored
 175.177 +	int32_t	version;		
 175.178 +
 175.179 +	//! Number of bones in file
 175.180 +	uint32_t	bones_num;
 175.181 +
 175.182 +	//! Number of groups in file
 175.183 +	uint32_t	groups_num;
 175.184 +
 175.185 +	//! Size of data in the file
 175.186 +	uint32_t	data_size;	
 175.187 +
 175.188 +	//! Ignored. Used to store entity specific information
 175.189 +	int32_t	entlump_size;	
 175.190 +
 175.191 +	//! Ignored. Used to store MED related data
 175.192 +	int32_t	medlump_size;	
 175.193 +
 175.194 +	//! Size of the Bone_MDL7 data structure used in the file
 175.195 +	uint16_t bone_stc_size;
 175.196 +
 175.197 +	//! Size of the Skin_MDL 7 data structure used in the file
 175.198 +	uint16_t skin_stc_size;
 175.199 +
 175.200 +	//! Size of a single color (e.g. in a material)
 175.201 +	uint16_t colorvalue_stc_size;
 175.202 +
 175.203 +	//! Size of the Material_MDL7 data structure used in the file
 175.204 +	uint16_t material_stc_size;
 175.205 +
 175.206 +	//! Size of a texture coordinate set in the file
 175.207 +	uint16_t skinpoint_stc_size;
 175.208 +
 175.209 +	//! Size of a triangle in the file
 175.210 +	uint16_t triangle_stc_size;
 175.211 +
 175.212 +	//! Size of a normal vertex in the file
 175.213 +	uint16_t mainvertex_stc_size;
 175.214 +
 175.215 +	//! Size of a per-frame animated vertex in the file
 175.216 +	//! (this is not supported)
 175.217 +	uint16_t framevertex_stc_size;
 175.218 +
 175.219 +	//! Size of a bone animation matrix
 175.220 +	uint16_t bonetrans_stc_size;
 175.221 +
 175.222 +	//! Size of the Frame_MDL7 data structure used in the file
 175.223 +	uint16_t frame_stc_size;
 175.224 +} PACK_STRUCT;
 175.225 +
 175.226 +
 175.227 +// -------------------------------------------------------------------------------------
 175.228 +/** \struct Bone_MDL7
 175.229 + *  \brief Data structure for a bone in a MDL7 file
 175.230 + */
 175.231 +struct Bone_MDL7
 175.232 +{
 175.233 +	//! Index of the parent bone of *this* bone. 0xffff means:
 175.234 +	//! "hey, I have no parent, I'm an orphan"
 175.235 +	uint16_t parent_index;
 175.236 +	uint8_t _unused_[2]; 
 175.237 +
 175.238 +	//! Relative position of the bone (relative to the
 175.239 +	//! parent bone)
 175.240 +	float x,y,z;
 175.241 +
 175.242 +	//! Optional name of the bone
 175.243 +	char name[1 /* DUMMY SIZE */];
 175.244 +} PACK_STRUCT;
 175.245 +
 175.246 +#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
 175.247 +#	define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
 175.248 +#endif
 175.249 +
 175.250 +#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS)
 175.251 +#	define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS (16 + 32)
 175.252 +#endif
 175.253 +
 175.254 +#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE)
 175.255 +#	define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE (16)
 175.256 +#endif
 175.257 +
 175.258 +#if (!defined AI_MDL7_MAX_GROUPNAMESIZE)
 175.259 +#	define AI_MDL7_MAX_GROUPNAMESIZE	16
 175.260 +#endif // ! AI_MDL7_MAX_GROUPNAMESIZE
 175.261 +
 175.262 +// -------------------------------------------------------------------------------------
 175.263 +/** \struct Group_MDL7
 175.264 + *  \brief Group in a MDL7 file
 175.265 + */
 175.266 +struct Group_MDL7
 175.267 +{
 175.268 +	//! = '1' -> triangle based Mesh
 175.269 +	unsigned char	typ;		
 175.270 +
 175.271 +	int8_t	deformers;
 175.272 +	int8_t	max_weights;
 175.273 +	int8_t	_unused_;
 175.274 +
 175.275 +	//! size of data for this group in bytes ( MD7_GROUP stc. included).
 175.276 +	int32_t	groupdata_size; 
 175.277 +	char	name[AI_MDL7_MAX_GROUPNAMESIZE];
 175.278 +
 175.279 +	//! Number of skins
 175.280 +	int32_t	numskins;
 175.281 +
 175.282 +	//! Number of texture coordinates
 175.283 +	int32_t	num_stpts;	
 175.284 +
 175.285 +	//! Number of triangles
 175.286 +	int32_t	numtris;
 175.287 +
 175.288 +	//! Number of vertices
 175.289 +	int32_t	numverts;
 175.290 +
 175.291 +	//! Number of frames
 175.292 +	int32_t	numframes;
 175.293 +} PACK_STRUCT;
 175.294 +
 175.295 +#define	AI_MDL7_SKINTYPE_MIPFLAG				0x08
 175.296 +#define	AI_MDL7_SKINTYPE_MATERIAL				0x10
 175.297 +#define	AI_MDL7_SKINTYPE_MATERIAL_ASCDEF		0x20
 175.298 +#define	AI_MDL7_SKINTYPE_RGBFLAG				0x80
 175.299 +
 175.300 +#if (!defined AI_MDL7_MAX_BONENAMESIZE)
 175.301 +#	define AI_MDL7_MAX_BONENAMESIZE 20
 175.302 +#endif // !! AI_MDL7_MAX_BONENAMESIZE
 175.303 +
 175.304 +// -------------------------------------------------------------------------------------
 175.305 +/** \struct Deformer_MDL7
 175.306 + *  \brief Deformer in a MDL7 file
 175.307 + */
 175.308 +struct Deformer_MDL7
 175.309 +{
 175.310 +	int8_t	deformer_version;		// 0
 175.311 +	int8_t	deformer_typ;			// 0 - bones
 175.312 +	int8_t	_unused_[2];
 175.313 +	int32_t	group_index;
 175.314 +	int32_t	elements;
 175.315 +	int32_t	deformerdata_size;
 175.316 +} PACK_STRUCT;
 175.317 +
 175.318 +
 175.319 +// -------------------------------------------------------------------------------------
 175.320 +/** \struct DeformerElement_MDL7
 175.321 + *  \brief Deformer element in a MDL7 file
 175.322 + */
 175.323 +struct DeformerElement_MDL7
 175.324 +{
 175.325 +	//! bei deformer_typ==0 (==bones) element_index == bone index
 175.326 +	int32_t	element_index;		
 175.327 +	char	element_name[AI_MDL7_MAX_BONENAMESIZE];
 175.328 +	int32_t	weights;
 175.329 +} PACK_STRUCT;
 175.330 +
 175.331 +
 175.332 +// -------------------------------------------------------------------------------------
 175.333 +/** \struct DeformerWeight_MDL7
 175.334 + *  \brief Deformer weight in a MDL7 file
 175.335 + */
 175.336 +struct DeformerWeight_MDL7
 175.337 +{
 175.338 +	//! for deformer_typ==0 (==bones) index == vertex index
 175.339 +	int32_t	index;				
 175.340 +	float	weight;
 175.341 +} PACK_STRUCT;
 175.342 +
 175.343 +
 175.344 +// don't know why this was in the original headers ...
 175.345 +typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
 175.346 +
 175.347 +// -------------------------------------------------------------------------------------
 175.348 +/** \struct ColorValue_MDL7
 175.349 + *  \brief Data structure for a color value in a MDL7 file
 175.350 + */
 175.351 +struct ColorValue_MDL7
 175.352 +{
 175.353 +	float r,g,b,a;
 175.354 +} PACK_STRUCT;
 175.355 +
 175.356 +// -------------------------------------------------------------------------------------
 175.357 +/** \struct Material_MDL7
 175.358 + *  \brief Data structure for a Material in a MDL7 file
 175.359 + */
 175.360 +struct Material_MDL7
 175.361 +{
 175.362 +	//! Diffuse base color of the material
 175.363 +	ColorValue_MDL7	Diffuse;        
 175.364 +
 175.365 +	//! Ambient base color of the material
 175.366 +    ColorValue_MDL7	Ambient;  
 175.367 +
 175.368 +	//! Specular base color of the material
 175.369 +    ColorValue_MDL7	Specular;  
 175.370 +
 175.371 +	//! Emissive base color of the material
 175.372 +    ColorValue_MDL7	Emissive; 
 175.373 +
 175.374 +	//! Phong power
 175.375 +    float			Power;         
 175.376 +} PACK_STRUCT;
 175.377 +
 175.378 +
 175.379 +// -------------------------------------------------------------------------------------
 175.380 +/** \struct Skin
 175.381 + *  \brief Skin data structure #1 - used by Quake1, MDL2, MDL3 and MDL4
 175.382 + */
 175.383 +struct Skin
 175.384 +{
 175.385 +	//! 0 = single (Skin), 1 = group (GroupSkin)
 175.386 +	//! For MDL3-5: Defines the type of the skin and there
 175.387 +	//! fore the size of the data to skip:
 175.388 +	//-------------------------------------------------------
 175.389 +	//! 2 for 565 RGB,
 175.390 +	//! 3 for 4444 ARGB, 
 175.391 +	//! 10 for 565 mipmapped, 
 175.392 +	//! 11 for 4444 mipmapped (bpp = 2),
 175.393 +	//! 12 for 888 RGB mipmapped (bpp = 3), 
 175.394 +	//! 13 for 8888 ARGB mipmapped (bpp = 4)
 175.395 +	//-------------------------------------------------------
 175.396 +	int32_t group;      
 175.397 +
 175.398 +	//! Texture data
 175.399 +	uint8_t *data;  
 175.400 +} PACK_STRUCT;
 175.401 +
 175.402 +
 175.403 +// -------------------------------------------------------------------------------------
 175.404 +/** \struct Skin
 175.405 + *  \brief Skin data structure #2 - used by MDL5, MDL6 and MDL7
 175.406 + *  \see Skin
 175.407 + */
 175.408 +struct Skin_MDL5
 175.409 +{
 175.410 +	int32_t size, width, height;      
 175.411 +	uint8_t *data;  
 175.412 +} PACK_STRUCT;
 175.413 +
 175.414 +// maximum length of texture file name
 175.415 +#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
 175.416 +#	define AI_MDL7_MAX_TEXNAMESIZE		0x10
 175.417 +#endif
 175.418 +
 175.419 +// ---------------------------------------------------------------------------
 175.420 +/** \struct Skin_MDL7
 175.421 + *  \brief Skin data structure #3 - used by MDL7 and HMP7
 175.422 + */
 175.423 +struct Skin_MDL7
 175.424 +{
 175.425 +	uint8_t			typ;
 175.426 +	int8_t			_unused_[3];
 175.427 +	int32_t			width;
 175.428 +	int32_t			height;
 175.429 +	char			texture_name[AI_MDL7_MAX_TEXNAMESIZE];	
 175.430 +} PACK_STRUCT;
 175.431 +
 175.432 +// -------------------------------------------------------------------------------------
 175.433 +/** \struct RGB565
 175.434 + *  \brief Data structure for a RGB565 pixel in a texture
 175.435 + */
 175.436 +struct RGB565
 175.437 +{
 175.438 +	uint16_t r : 5;
 175.439 +	uint16_t g : 6;
 175.440 +	uint16_t b : 5;
 175.441 +} PACK_STRUCT;
 175.442 +
 175.443 +// -------------------------------------------------------------------------------------
 175.444 +/** \struct ARGB4
 175.445 + *  \brief Data structure for a ARGB4444 pixel in a texture
 175.446 + */
 175.447 +struct ARGB4
 175.448 +{
 175.449 +	uint16_t a : 4;
 175.450 +	uint16_t r : 4;
 175.451 +	uint16_t g : 4;
 175.452 +	uint16_t b : 4;
 175.453 +} PACK_STRUCT;
 175.454 +
 175.455 +// -------------------------------------------------------------------------------------
 175.456 +/** \struct GroupSkin
 175.457 + *  \brief Skin data structure #2 (group of pictures)
 175.458 + */
 175.459 +struct GroupSkin
 175.460 +{
 175.461 +	//! 0 = single (Skin), 1 = group (GroupSkin)
 175.462 +    int32_t group;     
 175.463 +
 175.464 +	//! Number of images
 175.465 +	int32_t nb;       
 175.466 +
 175.467 +	//! Time for each image
 175.468 +    float *time;   
 175.469 +
 175.470 +	//! Data of each image
 175.471 +	uint8_t **data;  
 175.472 +} PACK_STRUCT;
 175.473 +
 175.474 +// -------------------------------------------------------------------------------------
 175.475 +/** \struct TexCoord
 175.476 + *  \brief Texture coordinate data structure used by the Quake1 MDL format
 175.477 + */
 175.478 +struct TexCoord
 175.479 +{
 175.480 +	//! Is the vertex on the noundary between front and back piece?
 175.481 +	int32_t onseam;
 175.482 +
 175.483 +	//! Texture coordinate in the tx direction
 175.484 +	int32_t s;
 175.485 +
 175.486 +	//! Texture coordinate in the ty direction
 175.487 +	int32_t t;
 175.488 +} PACK_STRUCT;
 175.489 +
 175.490 +// -------------------------------------------------------------------------------------
 175.491 +/** \struct TexCoord_MDL3
 175.492 + *  \brief Data structure for an UV coordinate in the 3DGS MDL3 format
 175.493 + */
 175.494 +struct TexCoord_MDL3
 175.495 +{
 175.496 +	//! position, horizontally in range 0..skinwidth-1
 175.497 +	int16_t u; 
 175.498 +
 175.499 +	//! position, vertically in range 0..skinheight-1
 175.500 +	int16_t v; 
 175.501 +} PACK_STRUCT;
 175.502 +
 175.503 +// -------------------------------------------------------------------------------------
 175.504 +/** \struct TexCoord_MDL7
 175.505 + *  \brief Data structure for an UV coordinate in the 3DGS MDL7 format
 175.506 + */
 175.507 +struct TexCoord_MDL7
 175.508 +{
 175.509 +	//! position, horizontally in range 0..1
 175.510 +	float u; 
 175.511 +
 175.512 +	//! position, vertically in range 0..1
 175.513 +	float v; 
 175.514 +} PACK_STRUCT;
 175.515 +
 175.516 +// -------------------------------------------------------------------------------------
 175.517 +/** \struct SkinSet_MDL7
 175.518 + *  \brief Skin set data structure for the 3DGS MDL7 format
 175.519 + * MDL7 references UV coordinates per face via an index list.
 175.520 + * This allows the use of multiple skins per face with just one
 175.521 + * UV coordinate set.
 175.522 + */
 175.523 +struct SkinSet_MDL7
 175.524 +{
 175.525 +	//! Index into the UV coordinate list
 175.526 +	uint16_t	st_index[3]; // size 6	
 175.527 +
 175.528 +	//! Material index
 175.529 +	int32_t		material;	 // size 4				
 175.530 +} PACK_STRUCT;
 175.531 +
 175.532 +// -------------------------------------------------------------------------------------
 175.533 +/** \struct Triangle
 175.534 + *  \brief Triangle data structure for the Quake1 MDL format
 175.535 + */
 175.536 +struct Triangle
 175.537 +{
 175.538 +	//! 0 = backface, 1 = frontface
 175.539 +	int32_t facesfront;  
 175.540 +
 175.541 +	//! Vertex indices
 175.542 +	int32_t vertex[3];   
 175.543 +} PACK_STRUCT;
 175.544 +
 175.545 +// -------------------------------------------------------------------------------------
 175.546 +/** \struct Triangle_MDL3
 175.547 + *  \brief Triangle data structure for the 3DGS MDL3 format
 175.548 + */
 175.549 +struct Triangle_MDL3
 175.550 +{
 175.551 +	//!  Index of 3 3D vertices in range 0..numverts
 175.552 +	uint16_t index_xyz[3];
 175.553 +
 175.554 +	//! Index of 3 skin vertices in range 0..numskinverts
 175.555 +	uint16_t index_uv[3]; 
 175.556 +} PACK_STRUCT;
 175.557 +
 175.558 +// -------------------------------------------------------------------------------------
 175.559 +/** \struct Triangle_MDL7
 175.560 + *  \brief Triangle data structure for the 3DGS MDL7 format
 175.561 + */
 175.562 +struct Triangle_MDL7
 175.563 +{
 175.564 +	//! Vertex indices
 175.565 +	uint16_t   v_index[3]; 	// size 6
 175.566 +
 175.567 +	//! Two skinsets. The second will be used for multi-texturing
 175.568 +	SkinSet_MDL7  skinsets[2];
 175.569 +} PACK_STRUCT; 
 175.570 +
 175.571 +#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
 175.572 +#	define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV (6+sizeof(SkinSet_MDL7)-sizeof(uint32_t))
 175.573 +#endif 
 175.574 +#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX)
 175.575 +#	define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX (6+sizeof(SkinSet_MDL7))
 175.576 +#endif 
 175.577 +#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV)
 175.578 +#	define AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV (6+2*sizeof(SkinSet_MDL7))
 175.579 +#endif 
 175.580 +
 175.581 +// Helper constants for Triangle::facesfront
 175.582 +#if (!defined AI_MDL_BACKFACE)
 175.583 +#	define AI_MDL_BACKFACE			0x0
 175.584 +#endif
 175.585 +#if (!defined  AI_MDL_FRONTFACE)
 175.586 +#	define AI_MDL_FRONTFACE			0x1
 175.587 +#endif
 175.588 +
 175.589 +// -------------------------------------------------------------------------------------
 175.590 +/** \struct Vertex
 175.591 + *  \brief Vertex data structure
 175.592 + */
 175.593 +struct Vertex
 175.594 +{
 175.595 +	uint8_t v[3];
 175.596 +	uint8_t normalIndex;
 175.597 +} PACK_STRUCT;
 175.598 +
 175.599 +
 175.600 +// -------------------------------------------------------------------------------------
 175.601 +struct Vertex_MDL4
 175.602 +{
 175.603 +	uint16_t v[3];
 175.604 +	uint8_t normalIndex;
 175.605 +	uint8_t unused;
 175.606 +} PACK_STRUCT;
 175.607 +
 175.608 +#define AI_MDL7_FRAMEVERTEX120503_STCSIZE		16
 175.609 +#define AI_MDL7_FRAMEVERTEX030305_STCSIZE		26
 175.610 +
 175.611 +// -------------------------------------------------------------------------------------
 175.612 +/** \struct Vertex_MDL7
 175.613 + *  \brief Vertex data structure used in MDL7 files
 175.614 + */
 175.615 +struct Vertex_MDL7
 175.616 +{
 175.617 +	float	x,y,z;
 175.618 +	uint16_t vertindex;	// = bone index
 175.619 +	union {
 175.620 +		uint8_t norm162index;
 175.621 +		float norm[3];
 175.622 +	};
 175.623 +} PACK_STRUCT;
 175.624 +
 175.625 +
 175.626 +// -------------------------------------------------------------------------------------
 175.627 +/** \struct BoneTransform_MDL7
 175.628 + *  \brief bone transformation matrix structure used in MDL7 files
 175.629 + */
 175.630 +struct BoneTransform_MDL7
 175.631 +{
 175.632 +	//! 4*3
 175.633 +	float	m [4*4];				
 175.634 +
 175.635 +	//! the index of this vertex, 0.. header::bones_num - 1
 175.636 +	uint16_t bone_index;		
 175.637 +
 175.638 +	//! I HATE 3DGS AND THE SILLY DEVELOPER WHO DESIGNED
 175.639 +	//! THIS STUPID FILE FORMAT!
 175.640 +	int8_t _unused_[2];
 175.641 +} PACK_STRUCT;
 175.642 +
 175.643 +
 175.644 +#define AI_MDL7_MAX_FRAMENAMESIZE		16
 175.645 +
 175.646 +
 175.647 +// -------------------------------------------------------------------------------------
 175.648 +/** \struct Frame_MDL7
 175.649 + *  \brief Frame data structure used by MDL7 files
 175.650 + */
 175.651 +struct Frame_MDL7
 175.652 +{
 175.653 +	char	frame_name[AI_MDL7_MAX_FRAMENAMESIZE];
 175.654 +	uint32_t	vertices_count;			
 175.655 +	uint32_t	transmatrix_count;		
 175.656 +};
 175.657 +
 175.658 +
 175.659 +// -------------------------------------------------------------------------------------
 175.660 +/** \struct SimpleFrame
 175.661 + *  \brief Data structure for a simple frame
 175.662 + */
 175.663 +struct SimpleFrame
 175.664 +{
 175.665 +	//! Minimum vertex of the bounding box
 175.666 +	Vertex bboxmin; 
 175.667 +
 175.668 +	//! Maximum vertex of the bounding box
 175.669 +	Vertex bboxmax; 
 175.670 +
 175.671 +	//! Name of the frame
 175.672 +	char name[16];
 175.673 +
 175.674 +	//! Vertex list of the frame
 175.675 +	Vertex *verts; 
 175.676 +} PACK_STRUCT;
 175.677 +
 175.678 +// -------------------------------------------------------------------------------------
 175.679 +/** \struct Frame
 175.680 + *  \brief Model frame data structure
 175.681 + */
 175.682 +struct Frame
 175.683 +{
 175.684 +	//! 0 = simple frame, !0 = group frame
 175.685 +	int32_t type;       
 175.686 +
 175.687 +	//! Frame data
 175.688 +	SimpleFrame frame;  	      
 175.689 +} PACK_STRUCT;
 175.690 +
 175.691 +
 175.692 +// -------------------------------------------------------------------------------------
 175.693 +struct SimpleFrame_MDLn_SP
 175.694 +{
 175.695 +	//! Minimum vertex of the bounding box
 175.696 +	Vertex_MDL4 bboxmin; 
 175.697 +
 175.698 +	//! Maximum vertex of the bounding box
 175.699 +	Vertex_MDL4 bboxmax; 
 175.700 +
 175.701 +	//! Name of the frame
 175.702 +	char name[16];
 175.703 +
 175.704 +	//! Vertex list of the frame
 175.705 +	Vertex_MDL4 *verts; 
 175.706 +} PACK_STRUCT;
 175.707 +
 175.708 +// -------------------------------------------------------------------------------------
 175.709 +/** \struct GroupFrame
 175.710 + *  \brief Data structure for a group of frames
 175.711 + */
 175.712 +struct GroupFrame
 175.713 +{
 175.714 +	//! 0 = simple frame, !0 = group frame
 175.715 +	int32_t type;                         
 175.716 +
 175.717 +	//! Minimum vertex for all single frames
 175.718 +	Vertex min;         
 175.719 +
 175.720 +	//! Maximum vertex for all single frames
 175.721 +	Vertex max;         
 175.722 +
 175.723 +	//! Time for all single frames
 175.724 +	float *time;                  
 175.725 +
 175.726 +	//! List of single frames
 175.727 +	SimpleFrame *frames; 
 175.728 +} PACK_STRUCT;
 175.729 +
 175.730 +#include "assimp/Compiler/poppack1.h"
 175.731 +
 175.732 +// -------------------------------------------------------------------------------------
 175.733 +/** \struct IntFace_MDL7
 175.734 + *  \brief Internal data structure to temporarily represent a face
 175.735 + */
 175.736 +struct IntFace_MDL7
 175.737 +{
 175.738 +	// provide a constructor for our own convenience
 175.739 +	IntFace_MDL7()
 175.740 +	{
 175.741 +		// set everything to zero
 175.742 +		mIndices[0] = mIndices[1] = mIndices[2] = 0;
 175.743 +		iMatIndex[0] = iMatIndex[1] = 0;
 175.744 +	}
 175.745 +
 175.746 +	//! Vertex indices
 175.747 +	uint32_t mIndices[3];
 175.748 +
 175.749 +	//! Material index (maximally two channels, which are joined later)
 175.750 +	unsigned int iMatIndex[2];
 175.751 +}; 
 175.752 +
 175.753 +// -------------------------------------------------------------------------------------
 175.754 +/** \struct IntMaterial_MDL7
 175.755 + *  \brief Internal data structure to temporarily represent a material
 175.756 + *  which has been created from two single materials along with the
 175.757 + *  original material indices.
 175.758 + */
 175.759 +struct IntMaterial_MDL7
 175.760 +{
 175.761 +	// provide a constructor for our own convenience
 175.762 +	IntMaterial_MDL7()
 175.763 +	{
 175.764 +		pcMat = NULL;
 175.765 +		iOldMatIndices[0] = iOldMatIndices[1] = 0;
 175.766 +	}
 175.767 +
 175.768 +	//! Material instance
 175.769 +	aiMaterial* pcMat;
 175.770 +
 175.771 +	//! Old material indices
 175.772 +	unsigned int iOldMatIndices[2];
 175.773 +};
 175.774 +
 175.775 +// -------------------------------------------------------------------------------------
 175.776 +/** \struct IntBone_MDL7
 175.777 + *  \brief Internal data structure to represent a bone in a MDL7 file with
 175.778 + *  all of its animation channels assigned to it.
 175.779 + */
 175.780 +struct IntBone_MDL7 : aiBone
 175.781 +{
 175.782 +	//! Default constructor
 175.783 +	IntBone_MDL7() : iParent (0xffff)
 175.784 +	{
 175.785 +		pkeyPositions.reserve(30);
 175.786 +		pkeyScalings.reserve(30);
 175.787 +		pkeyRotations.reserve(30);
 175.788 +	}
 175.789 +
 175.790 +	//! Parent bone of the bone
 175.791 +	uint64_t iParent;
 175.792 +
 175.793 +	//! Relative position of the bone
 175.794 +	aiVector3D vPosition;
 175.795 +
 175.796 +	//! Array of position keys
 175.797 +	std::vector<aiVectorKey> pkeyPositions;
 175.798 +
 175.799 +	//! Array of scaling keys
 175.800 +	std::vector<aiVectorKey> pkeyScalings;
 175.801 +
 175.802 +	//! Array of rotation keys
 175.803 +	std::vector<aiQuatKey> pkeyRotations;
 175.804 +};
 175.805 +
 175.806 +// -------------------------------------------------------------------------------------
 175.807 +//! Describes a MDL7 frame
 175.808 +struct IntFrameInfo_MDL7
 175.809 +{
 175.810 +	//! Construction from an existing frame header
 175.811 +	IntFrameInfo_MDL7(BE_NCONST MDL::Frame_MDL7* _pcFrame,unsigned int _iIndex) 
 175.812 +		: iIndex(_iIndex)
 175.813 +		, pcFrame(_pcFrame)
 175.814 +	{}
 175.815 +
 175.816 +	//! Index of the frame
 175.817 +	unsigned int iIndex;
 175.818 +
 175.819 +	//! Points to the header of the frame
 175.820 +	BE_NCONST MDL::Frame_MDL7*	pcFrame; 
 175.821 +};
 175.822 +
 175.823 +// -------------------------------------------------------------------------------------
 175.824 +//! Describes a MDL7 mesh group
 175.825 +struct IntGroupInfo_MDL7
 175.826 +{
 175.827 +	//! Default constructor
 175.828 +	IntGroupInfo_MDL7()		
 175.829 +		:	iIndex(0)
 175.830 +		,	pcGroup(NULL)
 175.831 +		,	pcGroupUVs(NULL)
 175.832 +		,	pcGroupTris(NULL)
 175.833 +		,	pcGroupVerts(NULL)
 175.834 +		{}
 175.835 +
 175.836 +	//! Construction from an existing group header
 175.837 +	IntGroupInfo_MDL7(BE_NCONST MDL::Group_MDL7* _pcGroup, unsigned int _iIndex)
 175.838 +		:	iIndex(_iIndex)
 175.839 +		,	pcGroup(_pcGroup)
 175.840 +	{}
 175.841 +
 175.842 +	//! Index of the group
 175.843 +	unsigned int iIndex;
 175.844 +
 175.845 +	//! Points to the header of the group
 175.846 +	BE_NCONST MDL::Group_MDL7*		pcGroup; 
 175.847 +
 175.848 +	//! Points to the beginning of the uv coordinate section
 175.849 +	BE_NCONST MDL::TexCoord_MDL7*	pcGroupUVs;		
 175.850 +
 175.851 +	//! Points to the beginning of the triangle section
 175.852 +	MDL::Triangle_MDL7*	pcGroupTris;		
 175.853 +
 175.854 +	//! Points to the beginning of the vertex section
 175.855 +	BE_NCONST MDL::Vertex_MDL7*		pcGroupVerts;
 175.856 +};
 175.857 +
 175.858 +// -------------------------------------------------------------------------------------
 175.859 +//! Holds the data that belongs to a MDL7 mesh group
 175.860 +struct IntGroupData_MDL7
 175.861 +{
 175.862 +	IntGroupData_MDL7()
 175.863 +		: pcFaces(NULL), bNeed2UV(false)
 175.864 +	{}
 175.865 +
 175.866 +	//! Array of faces that belong to the group
 175.867 +	MDL::IntFace_MDL7* pcFaces;		
 175.868 +
 175.869 +	//! Array of vertex positions
 175.870 +	std::vector<aiVector3D>		vPositions;			
 175.871 +
 175.872 +	//! Array of vertex normals
 175.873 +	std::vector<aiVector3D>		vNormals;	
 175.874 +
 175.875 +	//! Array of bones indices
 175.876 +	std::vector<unsigned int>	aiBones;	
 175.877 +
 175.878 +	//! First UV coordinate set
 175.879 +	std::vector<aiVector3D>		vTextureCoords1;
 175.880 +
 175.881 +	//! Optional second UV coordinate set
 175.882 +	std::vector<aiVector3D>		vTextureCoords2;
 175.883 +
 175.884 +	//! Specifies whether there are two texture
 175.885 +	//! coordinate sets required
 175.886 +	bool bNeed2UV;
 175.887 +};
 175.888 +
 175.889 +// -------------------------------------------------------------------------------------
 175.890 +//! Holds data from an MDL7 file that is shared by all mesh groups
 175.891 +struct IntSharedData_MDL7
 175.892 +{
 175.893 +	//! Default constructor
 175.894 +	IntSharedData_MDL7() 
 175.895 +	{
 175.896 +		abNeedMaterials.reserve(10);
 175.897 +	}
 175.898 +
 175.899 +	//! Destruction: properly delete all allocated resources
 175.900 +	~IntSharedData_MDL7()
 175.901 +	{
 175.902 +		// kill all bones
 175.903 +		if (this->apcOutBones)
 175.904 +		{
 175.905 +			for (unsigned int m = 0; m < iNum;++m)
 175.906 +				delete this->apcOutBones[m];
 175.907 +			delete[] this->apcOutBones;
 175.908 +		}
 175.909 +	}
 175.910 +
 175.911 +	//! Specifies which materials are used
 175.912 +	std::vector<bool> abNeedMaterials;
 175.913 +
 175.914 +	//! List of all materials
 175.915 +	std::vector<aiMaterial*> pcMats;
 175.916 +
 175.917 +	//! List of all bones
 175.918 +	IntBone_MDL7** apcOutBones;
 175.919 +
 175.920 +	//! number of bones
 175.921 +	unsigned int iNum;
 175.922 +};
 175.923 +
 175.924 +// -------------------------------------------------------------------------------------
 175.925 +//! Contains input data for GenerateOutputMeshes_3DGS_MDL7
 175.926 +struct IntSplitGroupData_MDL7
 175.927 +{
 175.928 +	//! Construction from a given shared data set 
 175.929 +	IntSplitGroupData_MDL7(IntSharedData_MDL7& _shared,
 175.930 +		std::vector<aiMesh*>& _avOutList)
 175.931 +
 175.932 +		: shared(_shared), avOutList(_avOutList)
 175.933 +	{
 175.934 +	}
 175.935 +
 175.936 +	//! Destruction: properly delete all allocated resources
 175.937 +	~IntSplitGroupData_MDL7()
 175.938 +	{
 175.939 +		// kill all face lists
 175.940 +		if(this->aiSplit)
 175.941 +		{
 175.942 +			for (unsigned int m = 0; m < shared.pcMats.size();++m)
 175.943 +				delete this->aiSplit[m];
 175.944 +			delete[] this->aiSplit;
 175.945 +		}
 175.946 +	}
 175.947 +
 175.948 +	//! Contains a list of all faces per material
 175.949 +	std::vector<unsigned int>** aiSplit;
 175.950 +
 175.951 +	//! Shared data for all groups of the model
 175.952 +	IntSharedData_MDL7& shared;
 175.953 +
 175.954 +	//! List of meshes 
 175.955 +	std::vector<aiMesh*>& avOutList;
 175.956 +};
 175.957 +
 175.958 +
 175.959 +}
 175.960 +} // end namespaces
 175.961 +
 175.962 +#endif // !! AI_MDLFILEHELPER_H_INC
   176.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   176.2 +++ b/libs/assimp/MDLLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   176.3 @@ -0,0 +1,1942 @@
   176.4 +/*
   176.5 +---------------------------------------------------------------------------
   176.6 +Open Asset Import Library (assimp)
   176.7 +---------------------------------------------------------------------------
   176.8 +
   176.9 +Copyright (c) 2006-2012, assimp team
  176.10 +
  176.11 +All rights reserved.
  176.12 +
  176.13 +Redistribution and use of this software in source and binary forms, 
  176.14 +with or without modification, are permitted provided that the following 
  176.15 +conditions are met:
  176.16 +
  176.17 +* Redistributions of source code must retain the above
  176.18 +  copyright notice, this list of conditions and the
  176.19 +  following disclaimer.
  176.20 +
  176.21 +* Redistributions in binary form must reproduce the above
  176.22 +  copyright notice, this list of conditions and the
  176.23 +  following disclaimer in the documentation and/or other
  176.24 +  materials provided with the distribution.
  176.25 +
  176.26 +* Neither the name of the assimp team, nor the names of its
  176.27 +  contributors may be used to endorse or promote products
  176.28 +  derived from this software without specific prior
  176.29 +  written permission of the assimp team.
  176.30 +
  176.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  176.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  176.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  176.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  176.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  176.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  176.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  176.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  176.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  176.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  176.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  176.42 +---------------------------------------------------------------------------
  176.43 +*/
  176.44 +
  176.45 +/** @file MDLLoader.cpp
  176.46 + *  @brief Implementation of the main parts of the MDL importer class
  176.47 + *  *TODO* Cleanup and further testing of some parts necessary
  176.48 + */
  176.49 +
  176.50 +// internal headers
  176.51 +#include "AssimpPCH.h"
  176.52 +#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
  176.53 +
  176.54 +#include "MDLLoader.h"
  176.55 +#include "MDLDefaultColorMap.h"
  176.56 +#include "MD2FileData.h" 
  176.57 +
  176.58 +using namespace Assimp;
  176.59 +
  176.60 +static const aiImporterDesc desc = {
  176.61 +	"Quake Mesh / 3D GameStudio Mesh Importer",
  176.62 +	"",
  176.63 +	"",
  176.64 +	"",
  176.65 +	aiImporterFlags_SupportBinaryFlavour,
  176.66 +	0,
  176.67 +	0,
  176.68 +	7,
  176.69 +	0,
  176.70 +	"mdl"
  176.71 +};
  176.72 +
  176.73 +// ------------------------------------------------------------------------------------------------
  176.74 +// Ugly stuff ... nevermind
  176.75 +#define _AI_MDL7_ACCESS(_data, _index, _limit, _type)				\
  176.76 +	(*((const _type*)(((const char*)_data) + _index * _limit)))
  176.77 +
  176.78 +#define _AI_MDL7_ACCESS_PTR(_data, _index, _limit, _type)			\
  176.79 +	((BE_NCONST _type*)(((const char*)_data) + _index * _limit))
  176.80 +
  176.81 +#define _AI_MDL7_ACCESS_VERT(_data, _index, _limit)					\
  176.82 +	_AI_MDL7_ACCESS(_data,_index,_limit,MDL::Vertex_MDL7)
  176.83 +
  176.84 +// ------------------------------------------------------------------------------------------------
  176.85 +// Constructor to be privately used by Importer
  176.86 +MDLImporter::MDLImporter()
  176.87 +{}
  176.88 +
  176.89 +// ------------------------------------------------------------------------------------------------
  176.90 +// Destructor, private as well 
  176.91 +MDLImporter::~MDLImporter()
  176.92 +{}
  176.93 +
  176.94 +// ------------------------------------------------------------------------------------------------
  176.95 +// Returns whether the class can handle the format of the given file. 
  176.96 +bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  176.97 +{
  176.98 +	const std::string extension = GetExtension(pFile);
  176.99 +
 176.100 +	// if check for extension is not enough, check for the magic tokens 
 176.101 +	if (extension == "mdl"  || !extension.length() || checkSig) {
 176.102 +		uint32_t tokens[8]; 
 176.103 +		tokens[0] = AI_MDL_MAGIC_NUMBER_LE_HL2a;
 176.104 +		tokens[1] = AI_MDL_MAGIC_NUMBER_LE_HL2b;
 176.105 +		tokens[2] = AI_MDL_MAGIC_NUMBER_LE_GS7;
 176.106 +		tokens[3] = AI_MDL_MAGIC_NUMBER_LE_GS5b;
 176.107 +		tokens[4] = AI_MDL_MAGIC_NUMBER_LE_GS5a;
 176.108 +		tokens[5] = AI_MDL_MAGIC_NUMBER_LE_GS4;
 176.109 +		tokens[6] = AI_MDL_MAGIC_NUMBER_LE_GS3;
 176.110 +		tokens[7] = AI_MDL_MAGIC_NUMBER_LE;
 176.111 +		return CheckMagicToken(pIOHandler,pFile,tokens,8,0);
 176.112 +	}
 176.113 +	return false;
 176.114 +}
 176.115 +
 176.116 +// ------------------------------------------------------------------------------------------------
 176.117 +// Setup configuration properties
 176.118 +void MDLImporter::SetupProperties(const Importer* pImp)
 176.119 +{
 176.120 +	configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDL_KEYFRAME,-1);
 176.121 +
 176.122 +	// The 
 176.123 +	// AI_CONFIG_IMPORT_MDL_KEYFRAME option overrides the
 176.124 +	// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
 176.125 +	if(static_cast<unsigned int>(-1) == configFrameID)	{
 176.126 +		configFrameID =  pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
 176.127 +	}
 176.128 +
 176.129 +	// AI_CONFIG_IMPORT_MDL_COLORMAP - pallette file
 176.130 +	configPalette =  pImp->GetPropertyString(AI_CONFIG_IMPORT_MDL_COLORMAP,"colormap.lmp");
 176.131 +}
 176.132 +
 176.133 +// ------------------------------------------------------------------------------------------------
 176.134 +// Get a list of all supported extensions
 176.135 +const aiImporterDesc* MDLImporter::GetInfo () const
 176.136 +{
 176.137 +	return &desc;
 176.138 +}
 176.139 +
 176.140 +// ------------------------------------------------------------------------------------------------
 176.141 +// Imports the given file into the given scene structure. 
 176.142 +void MDLImporter::InternReadFile( const std::string& pFile, 
 176.143 +	aiScene* _pScene, IOSystem* _pIOHandler)
 176.144 +{
 176.145 +	pScene     = _pScene;
 176.146 +	pIOHandler = _pIOHandler;
 176.147 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
 176.148 +
 176.149 +	// Check whether we can read from the file
 176.150 +	if( file.get() == NULL) {
 176.151 +		throw DeadlyImportError( "Failed to open MDL file " + pFile + ".");
 176.152 +	}
 176.153 +
 176.154 +	// This should work for all other types of MDL files, too ...
 176.155 +	// the quake header is one of the smallest, afaik
 176.156 +	iFileSize = (unsigned int)file->FileSize();
 176.157 +	if( iFileSize < sizeof(MDL::Header)) {
 176.158 +		throw DeadlyImportError( "MDL File is too small.");
 176.159 +	}
 176.160 +
 176.161 +	// Allocate storage and copy the contents of the file to a memory buffer
 176.162 +	std::vector<unsigned char> buffer(iFileSize+1);
 176.163 +	mBuffer = &buffer[0];
 176.164 +	file->Read( (void*)mBuffer, 1, iFileSize);
 176.165 +
 176.166 +	// Append a binary zero to the end of the buffer.
 176.167 +	// this is just for safety that string parsing routines
 176.168 +	// find the end of the buffer ...
 176.169 +	mBuffer[iFileSize] = '\0';
 176.170 +	const uint32_t iMagicWord = *((uint32_t*)mBuffer);
 176.171 +
 176.172 +	// Determine the file subtype and call the appropriate member function
 176.173 +
 176.174 +	// Original Quake1 format
 176.175 +	if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord ||	AI_MDL_MAGIC_NUMBER_LE == iMagicWord)	{
 176.176 +		DefaultLogger::get()->debug("MDL subtype: Quake 1, magic word is IDPO");
 176.177 +		iGSFileVersion = 0;
 176.178 +		InternReadFile_Quake1();
 176.179 +	}
 176.180 +	// GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
 176.181 +	else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord)	{
 176.182 +		DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A2, magic word is MDL2");
 176.183 +		iGSFileVersion = 2;
 176.184 +		InternReadFile_Quake1();
 176.185 +	}
 176.186 +	// GameStudio A4 MDL3 format
 176.187 +	else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord)	{
 176.188 +		DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL3");
 176.189 +		iGSFileVersion = 3;
 176.190 +		InternReadFile_3DGS_MDL345();
 176.191 +	}
 176.192 +	// GameStudio A5+ MDL4 format
 176.193 +	else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord)	{
 176.194 +		DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL4");
 176.195 +		iGSFileVersion = 4;
 176.196 +		InternReadFile_3DGS_MDL345();
 176.197 +	}
 176.198 +	// GameStudio A5+ MDL5 format
 176.199 +	else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord)	{
 176.200 +		DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A5, magic word is MDL5");
 176.201 +		iGSFileVersion = 5;
 176.202 +		InternReadFile_3DGS_MDL345();
 176.203 +	}
 176.204 +	// GameStudio A7 MDL7 format
 176.205 +	else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord)	{
 176.206 +		DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A7, magic word is MDL7");
 176.207 +		iGSFileVersion = 7;
 176.208 +		InternReadFile_3DGS_MDL7();
 176.209 +	}
 176.210 +	// IDST/IDSQ Format (CS:S/HL^2, etc ...)
 176.211 +	else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
 176.212 +		AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
 176.213 +	{
 176.214 +		DefaultLogger::get()->debug("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ");
 176.215 +		iGSFileVersion = 0;
 176.216 +		InternReadFile_HL2();
 176.217 +	}
 176.218 +	else	{
 176.219 +		// print the magic word to the log file
 176.220 +		throw DeadlyImportError( "Unknown MDL subformat " + pFile +
 176.221 +			". Magic word (" + std::string((char*)&iMagicWord,4) + ") is not known");
 176.222 +	}
 176.223 +
 176.224 +	// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
 176.225 +	pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
 176.226 +		0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
 176.227 +
 176.228 +	// delete the file buffer and cleanup
 176.229 +	AI_DEBUG_INVALIDATE_PTR(mBuffer);
 176.230 +	AI_DEBUG_INVALIDATE_PTR(pIOHandler);
 176.231 +	AI_DEBUG_INVALIDATE_PTR(pScene);
 176.232 +}
 176.233 +
 176.234 +// ------------------------------------------------------------------------------------------------
 176.235 +// Check whether we're still inside the valid file range
 176.236 +void MDLImporter::SizeCheck(const void* szPos)
 176.237 +{
 176.238 +	if (!szPos || (const unsigned char*)szPos > this->mBuffer + this->iFileSize)
 176.239 +	{
 176.240 +		throw DeadlyImportError("Invalid MDL file. The file is too small "
 176.241 +			"or contains invalid data.");
 176.242 +	}
 176.243 +}
 176.244 +
 176.245 +// ------------------------------------------------------------------------------------------------
 176.246 +// Just for debgging purposes
 176.247 +void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int iLine)
 176.248 +{
 176.249 +	ai_assert(NULL != szFile);
 176.250 +	if (!szPos || (const unsigned char*)szPos > mBuffer + iFileSize)
 176.251 +	{
 176.252 +		// remove a directory if there is one
 176.253 +		const char* szFilePtr = ::strrchr(szFile,'\\');
 176.254 +		if (!szFilePtr)	{
 176.255 +			if(!(szFilePtr = ::strrchr(szFile,'/')))
 176.256 +				szFilePtr = szFile;
 176.257 +		}
 176.258 +		if (szFilePtr)++szFilePtr;
 176.259 +
 176.260 +		char szBuffer[1024];
 176.261 +		::sprintf(szBuffer,"Invalid MDL file. The file is too small "
 176.262 +			"or contains invalid data (File: %s Line: %i)",szFilePtr,iLine);
 176.263 +
 176.264 +		throw DeadlyImportError(szBuffer);
 176.265 +	}
 176.266 +}
 176.267 +
 176.268 +// ------------------------------------------------------------------------------------------------
 176.269 +// Validate a quake file header
 176.270 +void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
 176.271 +{
 176.272 +	// some values may not be NULL
 176.273 +	if (!pcHeader->num_frames)
 176.274 +		throw DeadlyImportError( "[Quake 1 MDL] There are no frames in the file");
 176.275 +
 176.276 +	if (!pcHeader->num_verts)
 176.277 +		throw DeadlyImportError( "[Quake 1 MDL] There are no vertices in the file");
 176.278 +
 176.279 +	if (!pcHeader->num_tris)
 176.280 +		throw DeadlyImportError( "[Quake 1 MDL] There are no triangles in the file");
 176.281 +
 176.282 +	// check whether the maxima are exceeded ...however, this applies for Quake 1 MDLs only
 176.283 +	if (!this->iGSFileVersion)
 176.284 +	{
 176.285 +		if (pcHeader->num_verts > AI_MDL_MAX_VERTS)
 176.286 +			DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_VERTS vertices");
 176.287 +
 176.288 +		if (pcHeader->num_tris > AI_MDL_MAX_TRIANGLES)
 176.289 +			DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_TRIANGLES triangles");
 176.290 +
 176.291 +		if (pcHeader->num_frames > AI_MDL_MAX_FRAMES)
 176.292 +			DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_FRAMES frames");
 176.293 +
 176.294 +		// (this does not apply for 3DGS MDLs)
 176.295 +		if (!this->iGSFileVersion && pcHeader->version != AI_MDL_VERSION)
 176.296 +			DefaultLogger::get()->warn("Quake 1 MDL model has an unknown version: AI_MDL_VERSION (=6) is "
 176.297 +				"the expected file format version");
 176.298 +		if(pcHeader->num_skins && (!pcHeader->skinwidth || !pcHeader->skinheight))
 176.299 +			DefaultLogger::get()->warn("Skin width or height are 0");
 176.300 +	}
 176.301 +}
 176.302 +
 176.303 +#ifdef AI_BUILD_BIG_ENDIAN
 176.304 +// ------------------------------------------------------------------------------------------------
 176.305 +void FlipQuakeHeader(BE_NCONST MDL::Header* pcHeader)
 176.306 +{
 176.307 +	AI_SWAP4( pcHeader->ident);
 176.308 +	AI_SWAP4( pcHeader->version);
 176.309 +	AI_SWAP4( pcHeader->boundingradius);
 176.310 +	AI_SWAP4( pcHeader->flags);
 176.311 +	AI_SWAP4( pcHeader->num_frames);
 176.312 +	AI_SWAP4( pcHeader->num_skins);
 176.313 +	AI_SWAP4( pcHeader->num_tris);
 176.314 +	AI_SWAP4( pcHeader->num_verts);
 176.315 +	for (unsigned int i = 0; i < 3;++i)
 176.316 +	{
 176.317 +		AI_SWAP4( pcHeader->scale[i]);
 176.318 +		AI_SWAP4( pcHeader->translate[i]);
 176.319 +	}
 176.320 +	AI_SWAP4( pcHeader->size);
 176.321 +	AI_SWAP4( pcHeader->skinheight);
 176.322 +	AI_SWAP4( pcHeader->skinwidth); 
 176.323 +	AI_SWAP4( pcHeader->synctype); 
 176.324 +}
 176.325 +#endif
 176.326 +
 176.327 +// ------------------------------------------------------------------------------------------------
 176.328 +// Read a Quake 1 file
 176.329 +void MDLImporter::InternReadFile_Quake1( )
 176.330 +{
 176.331 +	ai_assert(NULL != pScene);
 176.332 +	BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header*)this->mBuffer;
 176.333 +
 176.334 +#ifdef AI_BUILD_BIG_ENDIAN
 176.335 +	FlipQuakeHeader(pcHeader);
 176.336 +#endif
 176.337 +
 176.338 +	ValidateHeader_Quake1(pcHeader);
 176.339 +
 176.340 +	// current cursor position in the file
 176.341 +	const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
 176.342 +
 176.343 +	// need to read all textures
 176.344 +	for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i)
 176.345 +	{
 176.346 +		union{BE_NCONST MDL::Skin* pcSkin;BE_NCONST MDL::GroupSkin* pcGroupSkin;};
 176.347 +		pcSkin = (BE_NCONST MDL::Skin*)szCurrent;
 176.348 +
 176.349 +		AI_SWAP4( pcSkin->group );
 176.350 +
 176.351 +		// Quake 1 groupskins
 176.352 +		if (1 == pcSkin->group)
 176.353 +		{
 176.354 +			AI_SWAP4( pcGroupSkin->nb );
 176.355 +
 176.356 +			// need to skip multiple images
 176.357 +			const unsigned int iNumImages = (unsigned int)pcGroupSkin->nb;
 176.358 +			szCurrent += sizeof(uint32_t) * 2;
 176.359 +
 176.360 +			if (0 != iNumImages)	
 176.361 +			{
 176.362 +				if (!i) {
 176.363 +					// however, create only one output image (the first)
 176.364 +					this->CreateTextureARGB8_3DGS_MDL3(szCurrent + iNumImages * sizeof(float));
 176.365 +				}
 176.366 +				// go to the end of the skin section / the beginning of the next skin
 176.367 +				szCurrent += pcHeader->skinheight * pcHeader->skinwidth +
 176.368 +					sizeof(float) * iNumImages;
 176.369 +			}
 176.370 +		}
 176.371 +		// 3DGS has a few files that are using other 3DGS like texture formats here
 176.372 +		else
 176.373 +		{
 176.374 +			szCurrent += sizeof(uint32_t);
 176.375 +			unsigned int iSkip = i ? UINT_MAX : 0;
 176.376 +			CreateTexture_3DGS_MDL4(szCurrent,pcSkin->group,&iSkip);
 176.377 +			szCurrent += iSkip;
 176.378 +		}
 176.379 +	}
 176.380 +	// get a pointer to the texture coordinates
 176.381 +	BE_NCONST MDL::TexCoord* pcTexCoords = (BE_NCONST MDL::TexCoord*)szCurrent;
 176.382 +	szCurrent += sizeof(MDL::TexCoord) * pcHeader->num_verts;
 176.383 +
 176.384 +	// get a pointer to the triangles
 176.385 +	BE_NCONST MDL::Triangle* pcTriangles = (BE_NCONST MDL::Triangle*)szCurrent;
 176.386 +	szCurrent += sizeof(MDL::Triangle) * pcHeader->num_tris;
 176.387 +	VALIDATE_FILE_SIZE(szCurrent);
 176.388 +
 176.389 +	// now get a pointer to the first frame in the file
 176.390 +	BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent;
 176.391 +	BE_NCONST MDL::SimpleFrame* pcFirstFrame;
 176.392 +
 176.393 +	if (0 == pcFrames->type)
 176.394 +	{
 176.395 +		// get address of single frame
 176.396 +		pcFirstFrame = &pcFrames->frame;
 176.397 +	}
 176.398 +	else
 176.399 +	{
 176.400 +		// get the first frame in the group
 176.401 +		BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames;
 176.402 +		pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type);
 176.403 +	}
 176.404 +	BE_NCONST MDL::Vertex* pcVertices = (BE_NCONST MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
 176.405 +	VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts));
 176.406 +
 176.407 +#ifdef AI_BUILD_BIG_ENDIAN
 176.408 +	for (int i = 0; i<pcHeader->num_verts;++i)
 176.409 +	{
 176.410 +		AI_SWAP4( pcTexCoords[i].onseam );
 176.411 +		AI_SWAP4( pcTexCoords[i].s );
 176.412 +		AI_SWAP4( pcTexCoords[i].t );
 176.413 +	}
 176.414 +
 176.415 +	for (int i = 0; i<pcHeader->num_tris;++i)
 176.416 +	{
 176.417 +		AI_SWAP4( pcTriangles[i].facesfront);
 176.418 +		AI_SWAP4( pcTriangles[i].vertex[0]);
 176.419 +		AI_SWAP4( pcTriangles[i].vertex[1]);
 176.420 +		AI_SWAP4( pcTriangles[i].vertex[2]);
 176.421 +	}
 176.422 +#endif
 176.423 +
 176.424 +	// setup materials
 176.425 +	SetupMaterialProperties_3DGS_MDL5_Quake1();
 176.426 +
 176.427 +	// allocate enough storage to hold all vertices and triangles
 176.428 +	aiMesh* pcMesh = new aiMesh();
 176.429 +	
 176.430 +	pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 176.431 +	pcMesh->mNumVertices = pcHeader->num_tris * 3;
 176.432 +	pcMesh->mNumFaces = pcHeader->num_tris;
 176.433 +	pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
 176.434 +	pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
 176.435 +	pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
 176.436 +	pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
 176.437 +	pcMesh->mNumUVComponents[0] = 2;
 176.438 +
 176.439 +	// there won't be more than one mesh inside the file
 176.440 +	pScene->mRootNode = new aiNode();
 176.441 +	pScene->mRootNode->mNumMeshes = 1;
 176.442 +	pScene->mRootNode->mMeshes = new unsigned int[1];
 176.443 +	pScene->mRootNode->mMeshes[0] = 0;
 176.444 +	pScene->mNumMeshes = 1;
 176.445 +	pScene->mMeshes = new aiMesh*[1];
 176.446 +	pScene->mMeshes[0] = pcMesh;
 176.447 +
 176.448 +	// now iterate through all triangles
 176.449 +	unsigned int iCurrent = 0;
 176.450 +	for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i)
 176.451 +	{
 176.452 +		pcMesh->mFaces[i].mIndices = new unsigned int[3];
 176.453 +		pcMesh->mFaces[i].mNumIndices = 3;
 176.454 +
 176.455 +		unsigned int iTemp = iCurrent;
 176.456 +		for (unsigned int c = 0; c < 3;++c,++iCurrent)
 176.457 +		{
 176.458 +			pcMesh->mFaces[i].mIndices[c] = iCurrent;
 176.459 +
 176.460 +			// read vertices
 176.461 +			unsigned int iIndex = pcTriangles->vertex[c];
 176.462 +			if (iIndex >= (unsigned int)pcHeader->num_verts)
 176.463 +			{
 176.464 +				iIndex = pcHeader->num_verts-1;
 176.465 +				DefaultLogger::get()->warn("Index overflow in Q1-MDL vertex list.");
 176.466 +			}
 176.467 +
 176.468 +			aiVector3D& vec = pcMesh->mVertices[iCurrent];
 176.469 +			vec.x = (float)pcVertices[iIndex].v[0] * pcHeader->scale[0];
 176.470 +			vec.x += pcHeader->translate[0];
 176.471 +
 176.472 +			vec.y = (float)pcVertices[iIndex].v[1] * pcHeader->scale[1];
 176.473 +			vec.y += pcHeader->translate[1];
 176.474 +			//vec.y *= -1.0f;
 176.475 +
 176.476 +			vec.z = (float)pcVertices[iIndex].v[2] * pcHeader->scale[2];
 176.477 +			vec.z += pcHeader->translate[2];
 176.478 +
 176.479 +			// read the normal vector from the precalculated normal table
 176.480 +			MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex,pcMesh->mNormals[iCurrent]);
 176.481 +			//pcMesh->mNormals[iCurrent].y *= -1.0f;
 176.482 +
 176.483 +			// read texture coordinates
 176.484 +			float s = (float)pcTexCoords[iIndex].s;
 176.485 +			float t = (float)pcTexCoords[iIndex].t;
 176.486 +
 176.487 +			// translate texture coordinates
 176.488 +			if (0 == pcTriangles->facesfront && 0 != pcTexCoords[iIndex].onseam)	{
 176.489 +				s += pcHeader->skinwidth * 0.5f; 
 176.490 +			}
 176.491 +
 176.492 +			// Scale s and t to range from 0.0 to 1.0 
 176.493 +			pcMesh->mTextureCoords[0][iCurrent].x = (s + 0.5f) / pcHeader->skinwidth;
 176.494 +			pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-(t + 0.5f) / pcHeader->skinheight;
 176.495 +
 176.496 +		}
 176.497 +		pcMesh->mFaces[i].mIndices[0] = iTemp+2;
 176.498 +		pcMesh->mFaces[i].mIndices[1] = iTemp+1;
 176.499 +		pcMesh->mFaces[i].mIndices[2] = iTemp+0;
 176.500 +		pcTriangles++;
 176.501 +	}
 176.502 +	return;
 176.503 +}
 176.504 +
 176.505 +// ------------------------------------------------------------------------------------------------
 176.506 +// Setup material properties for Quake and older GameStudio files
 176.507 +void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
 176.508 +{
 176.509 +	const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
 176.510 +
 176.511 +	// allocate ONE material
 176.512 +	pScene->mMaterials    = new aiMaterial*[1];
 176.513 +	pScene->mMaterials[0] = new aiMaterial();
 176.514 +	pScene->mNumMaterials = 1;
 176.515 +
 176.516 +	// setup the material's properties
 176.517 +	const int iMode = (int)aiShadingMode_Gouraud;
 176.518 +	aiMaterial* const pcHelper = (aiMaterial*)pScene->mMaterials[0];
 176.519 +	pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
 176.520 +
 176.521 +	aiColor4D clr;
 176.522 +	if (0 != pcHeader->num_skins && pScene->mNumTextures)	{
 176.523 +		// can we replace the texture with a single color?
 176.524 +		clr = this->ReplaceTextureWithColor(pScene->mTextures[0]);
 176.525 +		if (is_not_qnan(clr.r))	{
 176.526 +			delete pScene->mTextures[0];
 176.527 +			delete[] pScene->mTextures;
 176.528 +
 176.529 +			pScene->mTextures = NULL;
 176.530 +			pScene->mNumTextures = 0;
 176.531 +		}
 176.532 +		else	{
 176.533 +			clr.b = clr.a = clr.g = clr.r = 1.0f;
 176.534 +			aiString szString;
 176.535 +			::memcpy(szString.data,AI_MAKE_EMBEDDED_TEXNAME(0),3);
 176.536 +			szString.length = 2;
 176.537 +			pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
 176.538 +		}
 176.539 +	}
 176.540 +
 176.541 +	pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
 176.542 +	pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
 176.543 +
 176.544 +	clr.r *= 0.05f;clr.g *= 0.05f;
 176.545 +	clr.b *= 0.05f;clr.a  = 1.0f;
 176.546 +	pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
 176.547 +}
 176.548 +
 176.549 +// ------------------------------------------------------------------------------------------------
 176.550 +// Read a MDL 3,4,5 file
 176.551 +void MDLImporter::InternReadFile_3DGS_MDL345( )
 176.552 +{
 176.553 +	ai_assert(NULL != pScene);
 176.554 +
 176.555 +	// the header of MDL 3/4/5 is nearly identical to the original Quake1 header
 176.556 +	BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header*)this->mBuffer;
 176.557 +#ifdef AI_BUILD_BIG_ENDIAN
 176.558 +	FlipQuakeHeader(pcHeader);
 176.559 +#endif
 176.560 +	ValidateHeader_Quake1(pcHeader);
 176.561 +
 176.562 +	// current cursor position in the file
 176.563 +	const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
 176.564 +
 176.565 +	// need to read all textures
 176.566 +	for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i)	{
 176.567 +		BE_NCONST MDL::Skin* pcSkin;
 176.568 +		pcSkin = (BE_NCONST  MDL::Skin*)szCurrent;
 176.569 +		AI_SWAP4( pcSkin->group);
 176.570 +		// create one output image
 176.571 +		unsigned int iSkip = i ? UINT_MAX : 0;
 176.572 +		if (5 <= iGSFileVersion)
 176.573 +		{
 176.574 +			// MDL5 format could contain MIPmaps
 176.575 +			CreateTexture_3DGS_MDL5((unsigned char*)pcSkin + sizeof(uint32_t),
 176.576 +				pcSkin->group,&iSkip);
 176.577 +		}
 176.578 +		else	{
 176.579 +			CreateTexture_3DGS_MDL4((unsigned char*)pcSkin + sizeof(uint32_t),
 176.580 +				pcSkin->group,&iSkip);
 176.581 +		}
 176.582 +		// need to skip one image
 176.583 +		szCurrent += iSkip + sizeof(uint32_t);
 176.584 +		
 176.585 +	}
 176.586 +	// get a pointer to the texture coordinates
 176.587 +	BE_NCONST MDL::TexCoord_MDL3* pcTexCoords = (BE_NCONST MDL::TexCoord_MDL3*)szCurrent;
 176.588 +	szCurrent += sizeof(MDL::TexCoord_MDL3) * pcHeader->synctype;
 176.589 +
 176.590 +	// NOTE: for MDLn formats "synctype" corresponds to the number of UV coords
 176.591 +
 176.592 +	// get a pointer to the triangles
 176.593 +	BE_NCONST MDL::Triangle_MDL3* pcTriangles = (BE_NCONST MDL::Triangle_MDL3*)szCurrent;
 176.594 +	szCurrent += sizeof(MDL::Triangle_MDL3) * pcHeader->num_tris;
 176.595 +
 176.596 +#ifdef AI_BUILD_BIG_ENDIAN
 176.597 +
 176.598 +	for (int i = 0; i<pcHeader->synctype;++i)	{
 176.599 +		AI_SWAP2( pcTexCoords[i].u );
 176.600 +		AI_SWAP2( pcTexCoords[i].v );
 176.601 +	}
 176.602 +
 176.603 +	for (int i = 0; i<pcHeader->num_tris;++i)	{
 176.604 +		AI_SWAP2( pcTriangles[i].index_xyz[0]);
 176.605 +		AI_SWAP2( pcTriangles[i].index_xyz[1]);
 176.606 +		AI_SWAP2( pcTriangles[i].index_xyz[2]);
 176.607 +		AI_SWAP2( pcTriangles[i].index_uv[0]);
 176.608 +		AI_SWAP2( pcTriangles[i].index_uv[1]);
 176.609 +		AI_SWAP2( pcTriangles[i].index_uv[2]);
 176.610 +	}
 176.611 +
 176.612 +#endif
 176.613 +
 176.614 +	VALIDATE_FILE_SIZE(szCurrent);
 176.615 +
 176.616 +	// setup materials
 176.617 +	SetupMaterialProperties_3DGS_MDL5_Quake1();
 176.618 +
 176.619 +	// allocate enough storage to hold all vertices and triangles
 176.620 +	aiMesh* pcMesh = new aiMesh();
 176.621 +	pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 176.622 +
 176.623 +	pcMesh->mNumVertices = pcHeader->num_tris * 3;
 176.624 +	pcMesh->mNumFaces = pcHeader->num_tris;
 176.625 +	pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
 176.626 +
 176.627 +	// there won't be more than one mesh inside the file
 176.628 +	pScene->mRootNode = new aiNode();
 176.629 +	pScene->mRootNode->mNumMeshes = 1;
 176.630 +	pScene->mRootNode->mMeshes = new unsigned int[1];
 176.631 +	pScene->mRootNode->mMeshes[0] = 0;
 176.632 +	pScene->mNumMeshes = 1;
 176.633 +	pScene->mMeshes = new aiMesh*[1];
 176.634 +	pScene->mMeshes[0] = pcMesh;
 176.635 +
 176.636 +	// allocate output storage
 176.637 +	pcMesh->mNumVertices = (unsigned int)pcHeader->num_tris*3;
 176.638 +	pcMesh->mVertices    = new aiVector3D[pcMesh->mNumVertices];
 176.639 +	pcMesh->mNormals     = new aiVector3D[pcMesh->mNumVertices];
 176.640 +
 176.641 +	if (pcHeader->synctype)	{
 176.642 +		pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
 176.643 +		pcMesh->mNumUVComponents[0] = 2;
 176.644 +	}
 176.645 +
 176.646 +	// now get a pointer to the first frame in the file
 176.647 +	BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent;
 176.648 +	AI_SWAP4(pcFrames->type);
 176.649 +
 176.650 +	// byte packed vertices
 176.651 +	// FIXME: these two snippets below are almost identical ... join them?
 176.652 +	/////////////////////////////////////////////////////////////////////////////////////
 176.653 +	if (0 == pcFrames->type || 3 >= this->iGSFileVersion)	{
 176.654 +
 176.655 +		const MDL::SimpleFrame* pcFirstFrame = (const MDL::SimpleFrame*)(szCurrent + sizeof(uint32_t));
 176.656 +		const MDL::Vertex* pcVertices = (const MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
 176.657 +
 176.658 +		VALIDATE_FILE_SIZE(pcVertices + pcHeader->num_verts);
 176.659 +
 176.660 +		// now iterate through all triangles
 176.661 +		unsigned int iCurrent = 0;
 176.662 +		for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i)	{
 176.663 +			pcMesh->mFaces[i].mIndices = new unsigned int[3];
 176.664 +			pcMesh->mFaces[i].mNumIndices = 3;
 176.665 +
 176.666 +			unsigned int iTemp = iCurrent;
 176.667 +			for (unsigned int c = 0; c < 3;++c,++iCurrent)	{
 176.668 +				// read vertices
 176.669 +				unsigned int iIndex = pcTriangles->index_xyz[c];
 176.670 +				if (iIndex >= (unsigned int)pcHeader->num_verts)	{
 176.671 +					iIndex = pcHeader->num_verts-1;
 176.672 +					DefaultLogger::get()->warn("Index overflow in MDLn vertex list");
 176.673 +				}
 176.674 +
 176.675 +				aiVector3D& vec = pcMesh->mVertices[iCurrent];
 176.676 +				vec.x = (float)pcVertices[iIndex].v[0] * pcHeader->scale[0];
 176.677 +				vec.x += pcHeader->translate[0];
 176.678 +
 176.679 +				vec.y = (float)pcVertices[iIndex].v[1] * pcHeader->scale[1];
 176.680 +				vec.y += pcHeader->translate[1];
 176.681 +				// vec.y *= -1.0f;
 176.682 +
 176.683 +				vec.z = (float)pcVertices[iIndex].v[2] * pcHeader->scale[2];
 176.684 +				vec.z += pcHeader->translate[2];
 176.685 +
 176.686 +				// read the normal vector from the precalculated normal table
 176.687 +				MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex,pcMesh->mNormals[iCurrent]);
 176.688 +				// pcMesh->mNormals[iCurrent].y *= -1.0f;
 176.689 +
 176.690 +				// read texture coordinates
 176.691 +				if (pcHeader->synctype)	{
 176.692 +					ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
 176.693 +						pcTexCoords,pcTriangles->index_uv[c]);
 176.694 +				}
 176.695 +			}
 176.696 +			pcMesh->mFaces[i].mIndices[0] = iTemp+2;
 176.697 +			pcMesh->mFaces[i].mIndices[1] = iTemp+1;
 176.698 +			pcMesh->mFaces[i].mIndices[2] = iTemp+0;
 176.699 +			pcTriangles++;
 176.700 +		}
 176.701 +
 176.702 +	}
 176.703 +	// short packed vertices 
 176.704 +	/////////////////////////////////////////////////////////////////////////////////////
 176.705 +	else	{
 176.706 +		// now get a pointer to the first frame in the file
 176.707 +		const MDL::SimpleFrame_MDLn_SP* pcFirstFrame = (const MDL::SimpleFrame_MDLn_SP*) (szCurrent + sizeof(uint32_t));
 176.708 +
 176.709 +		// get a pointer to the vertices
 176.710 +		const MDL::Vertex_MDL4* pcVertices = (const MDL::Vertex_MDL4*) ((pcFirstFrame->name) + 
 176.711 +			sizeof(pcFirstFrame->name));
 176.712 +
 176.713 +		VALIDATE_FILE_SIZE(pcVertices + pcHeader->num_verts);
 176.714 +
 176.715 +		// now iterate through all triangles
 176.716 +		unsigned int iCurrent = 0;
 176.717 +		for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i)	{
 176.718 +			pcMesh->mFaces[i].mIndices = new unsigned int[3];
 176.719 +			pcMesh->mFaces[i].mNumIndices = 3;
 176.720 +
 176.721 +			unsigned int iTemp = iCurrent;
 176.722 +			for (unsigned int c = 0; c < 3;++c,++iCurrent)	{
 176.723 +				// read vertices
 176.724 +				unsigned int iIndex = pcTriangles->index_xyz[c];
 176.725 +				if (iIndex >= (unsigned int)pcHeader->num_verts)	{
 176.726 +					iIndex = pcHeader->num_verts-1;
 176.727 +					DefaultLogger::get()->warn("Index overflow in MDLn vertex list");
 176.728 +				}
 176.729 +
 176.730 +				aiVector3D& vec = pcMesh->mVertices[iCurrent];
 176.731 +				vec.x = (float)pcVertices[iIndex].v[0] * pcHeader->scale[0];
 176.732 +				vec.x += pcHeader->translate[0];
 176.733 +
 176.734 +				vec.y = (float)pcVertices[iIndex].v[1] * pcHeader->scale[1];
 176.735 +				vec.y += pcHeader->translate[1];
 176.736 +				// vec.y *= -1.0f;
 176.737 +
 176.738 +				vec.z = (float)pcVertices[iIndex].v[2] * pcHeader->scale[2];
 176.739 +				vec.z += pcHeader->translate[2];
 176.740 +
 176.741 +				// read the normal vector from the precalculated normal table
 176.742 +				MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex,pcMesh->mNormals[iCurrent]);
 176.743 +				// pcMesh->mNormals[iCurrent].y *= -1.0f;
 176.744 +
 176.745 +				// read texture coordinates
 176.746 +				if (pcHeader->synctype)	{
 176.747 +					ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
 176.748 +						pcTexCoords,pcTriangles->index_uv[c]);
 176.749 +				}
 176.750 +			}
 176.751 +			pcMesh->mFaces[i].mIndices[0] = iTemp+2;
 176.752 +			pcMesh->mFaces[i].mIndices[1] = iTemp+1;
 176.753 +			pcMesh->mFaces[i].mIndices[2] = iTemp+0;
 176.754 +			pcTriangles++;
 176.755 +		}
 176.756 +	}
 176.757 +
 176.758 +	// For MDL5 we will need to build valid texture coordinates
 176.759 +	// basing upon the file loaded (only support one file as skin)
 176.760 +	if (0x5 == iGSFileVersion)
 176.761 +		CalculateUVCoordinates_MDL5();
 176.762 +	return;
 176.763 +}
 176.764 +
 176.765 +// ------------------------------------------------------------------------------------------------
 176.766 +// Get a single UV coordinate for Quake and older GameStudio files
 176.767 +void MDLImporter::ImportUVCoordinate_3DGS_MDL345( 
 176.768 +	aiVector3D& vOut,
 176.769 +	const MDL::TexCoord_MDL3* pcSrc, 
 176.770 +	unsigned int iIndex)
 176.771 +{
 176.772 +	ai_assert(NULL != pcSrc);
 176.773 +	const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
 176.774 +
 176.775 +	// validate UV indices
 176.776 +	if (iIndex >= (unsigned int) pcHeader->synctype)	{
 176.777 +		iIndex = pcHeader->synctype-1;
 176.778 +		DefaultLogger::get()->warn("Index overflow in MDLn UV coord list");
 176.779 +	}
 176.780 +
 176.781 +	float s = (float)pcSrc[iIndex].u;
 176.782 +	float t = (float)pcSrc[iIndex].v;
 176.783 +
 176.784 +	// Scale s and t to range from 0.0 to 1.0 
 176.785 +	if (0x5 != iGSFileVersion)	{
 176.786 +		s = (s + 0.5f)      / pcHeader->skinwidth;
 176.787 +		t = 1.0f-(t + 0.5f) / pcHeader->skinheight;
 176.788 +	}
 176.789 +
 176.790 +	vOut.x = s;
 176.791 +	vOut.y = t;
 176.792 +	vOut.z = 0.0f;
 176.793 +}
 176.794 +
 176.795 +// ------------------------------------------------------------------------------------------------
 176.796 +// Compute UV coordinates for a MDL5 file
 176.797 +void MDLImporter::CalculateUVCoordinates_MDL5()
 176.798 +{
 176.799 +	const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
 176.800 +	if (pcHeader->num_skins && this->pScene->mNumTextures)	{
 176.801 +		const aiTexture* pcTex = this->pScene->mTextures[0];
 176.802 +
 176.803 +		// if the file is loaded in DDS format: get the size of the
 176.804 +		// texture from the header of the DDS file
 176.805 +		// skip three DWORDs and read first height, then the width
 176.806 +		unsigned int iWidth, iHeight;
 176.807 +		if (!pcTex->mHeight)	{
 176.808 +			const uint32_t* piPtr = (uint32_t*)pcTex->pcData;
 176.809 +
 176.810 +			piPtr += 3;
 176.811 +			iHeight = (unsigned int)*piPtr++;
 176.812 +			iWidth  = (unsigned int)*piPtr;
 176.813 +			if (!iHeight || !iWidth)
 176.814 +			{
 176.815 +				DefaultLogger::get()->warn("Either the width or the height of the "
 176.816 +					"embedded DDS texture is zero. Unable to compute final texture "
 176.817 +					"coordinates. The texture coordinates remain in their original "
 176.818 +					"0-x/0-y (x,y = texture size) range.");
 176.819 +				iWidth  = 1;
 176.820 +				iHeight = 1;
 176.821 +			}
 176.822 +		}
 176.823 +		else	{
 176.824 +			iWidth  = pcTex->mWidth;
 176.825 +			iHeight = pcTex->mHeight;
 176.826 +		}
 176.827 +
 176.828 +		if (1 != iWidth || 1 != iHeight)	{
 176.829 +			const float fWidth = (float)iWidth;
 176.830 +			const float fHeight = (float)iHeight;
 176.831 +			aiMesh* pcMesh = this->pScene->mMeshes[0];
 176.832 +			for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
 176.833 +			{
 176.834 +				pcMesh->mTextureCoords[0][i].x /= fWidth;
 176.835 +				pcMesh->mTextureCoords[0][i].y /= fHeight;
 176.836 +				pcMesh->mTextureCoords[0][i].y = 1.0f - pcMesh->mTextureCoords[0][i].y; // DX to OGL
 176.837 +			}
 176.838 +		}
 176.839 +	}
 176.840 +}
 176.841 +
 176.842 +// ------------------------------------------------------------------------------------------------
 176.843 +// Validate the header of a MDL7 file
 176.844 +void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader)
 176.845 +{
 176.846 +	ai_assert(NULL != pcHeader);
 176.847 +
 176.848 +	// There are some fixed sizes ...
 176.849 +	if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size)	{
 176.850 +		throw DeadlyImportError( 
 176.851 +			"[3DGS MDL7] sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size");
 176.852 +	}
 176.853 +	if (sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size)	{
 176.854 +		throw DeadlyImportError( 
 176.855 +			"[3DGS MDL7] sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size");
 176.856 +	}
 176.857 +	if (sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size)	{
 176.858 +		throw DeadlyImportError( 
 176.859 +			"sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size");
 176.860 +	}
 176.861 +
 176.862 +	// if there are no groups ... how should we load such a file?
 176.863 +	if(!pcHeader->groups_num)	{
 176.864 +		throw DeadlyImportError( "[3DGS MDL7] No frames found");
 176.865 +	}
 176.866 +}
 176.867 +
 176.868 +// ------------------------------------------------------------------------------------------------
 176.869 +// resolve bone animation matrices
 176.870 +void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
 176.871 +{
 176.872 +	const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
 176.873 +	const MDL::Bone_MDL7* pcBones = (const MDL::Bone_MDL7*)(pcHeader+1);
 176.874 +	ai_assert(NULL != apcOutBones);
 176.875 +
 176.876 +	// first find the bone that has NO parent, calculate the
 176.877 +	// animation matrix for it, then go on and search for the next parent
 176.878 +	// index (0) and so on until we can't find a new node.
 176.879 +	uint16_t iParent = 0xffff;
 176.880 +	uint32_t iIterations = 0;
 176.881 +	while (iIterations++ < pcHeader->bones_num)	{
 176.882 +		for (uint32_t iBone = 0; iBone < pcHeader->bones_num;++iBone)	{
 176.883 +			BE_NCONST MDL::Bone_MDL7* pcBone = _AI_MDL7_ACCESS_PTR(pcBones,iBone,
 176.884 +				pcHeader->bone_stc_size,MDL::Bone_MDL7);
 176.885 +
 176.886 +			AI_SWAP2(pcBone->parent_index);
 176.887 +			AI_SWAP4(pcBone->x);
 176.888 +			AI_SWAP4(pcBone->y);
 176.889 +			AI_SWAP4(pcBone->z);
 176.890 +
 176.891 +			if (iParent == pcBone->parent_index)	{
 176.892 +				// MDL7 readme
 176.893 +				////////////////////////////////////////////////////////////////
 176.894 +				/*
 176.895 +				The animation matrix is then calculated the following way:
 176.896 +
 176.897 +				vector3 bPos = <absolute bone position>
 176.898 +				matrix44 laM;   // local animation matrix
 176.899 +				sphrvector key_rotate = <bone rotation>
 176.900 +		
 176.901 +				matrix44 m1,m2;
 176.902 +				create_trans_matrix(m1, -bPos.x, -bPos.y, -bPos.z);
 176.903 +				create_trans_matrix(m2, -bPos.x, -bPos.y, -bPos.z);
 176.904 +
 176.905 +				create_rotation_matrix(laM,key_rotate);
 176.906 +
 176.907 +				laM = sm1 * laM;
 176.908 +				laM = laM * sm2;
 176.909 +				*/
 176.910 +				/////////////////////////////////////////////////////////////////
 176.911 +
 176.912 +				MDL::IntBone_MDL7* const pcOutBone = apcOutBones[iBone];
 176.913 +
 176.914 +				// store the parent index of the bone
 176.915 +				pcOutBone->iParent = pcBone->parent_index;
 176.916 +				if (0xffff != iParent)	{
 176.917 +					const MDL::IntBone_MDL7* pcParentBone = apcOutBones[iParent];
 176.918 +					pcOutBone->mOffsetMatrix.a4 = -pcParentBone->vPosition.x;
 176.919 +					pcOutBone->mOffsetMatrix.b4 = -pcParentBone->vPosition.y;
 176.920 +					pcOutBone->mOffsetMatrix.c4 = -pcParentBone->vPosition.z;
 176.921 +				}
 176.922 +				pcOutBone->vPosition.x = pcBone->x; 
 176.923 +				pcOutBone->vPosition.y = pcBone->y;
 176.924 +				pcOutBone->vPosition.z = pcBone->z;
 176.925 +				pcOutBone->mOffsetMatrix.a4 -= pcBone->x;
 176.926 +				pcOutBone->mOffsetMatrix.b4 -= pcBone->y;
 176.927 +				pcOutBone->mOffsetMatrix.c4 -= pcBone->z;
 176.928 +
 176.929 +				if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE == pcHeader->bone_stc_size)	{
 176.930 +					// no real name for our poor bone is specified :-(	
 176.931 +					pcOutBone->mName.length = ::sprintf(pcOutBone->mName.data,
 176.932 +						"UnnamedBone_%i",iBone);
 176.933 +				}
 176.934 +				else	{
 176.935 +					// Make sure we won't run over the buffer's end if there is no
 176.936 +					// terminal 0 character (however the documentation says there
 176.937 +					// should be one)
 176.938 +					uint32_t iMaxLen = pcHeader->bone_stc_size-16;
 176.939 +					for (uint32_t qq = 0; qq < iMaxLen;++qq)	{
 176.940 +						if (!pcBone->name[qq])	{
 176.941 +							iMaxLen = qq;
 176.942 +							break;
 176.943 +						}
 176.944 +					}
 176.945 +
 176.946 +					// store the name of the bone
 176.947 +					pcOutBone->mName.length = (size_t)iMaxLen;
 176.948 +					::memcpy(pcOutBone->mName.data,pcBone->name,pcOutBone->mName.length);
 176.949 +					pcOutBone->mName.data[pcOutBone->mName.length] = '\0';
 176.950 +				}
 176.951 +			}
 176.952 +		}
 176.953 +		++iParent;
 176.954 +	}
 176.955 +}
 176.956 +
 176.957 +// ------------------------------------------------------------------------------------------------
 176.958 +// read bones from a MDL7 file
 176.959 +MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
 176.960 +{
 176.961 +  const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
 176.962 +	if (pcHeader->bones_num)	{
 176.963 +		// validate the size of the bone data structure in the file
 176.964 +		if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS  != pcHeader->bone_stc_size &&
 176.965 +			AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS  != pcHeader->bone_stc_size &&
 176.966 +			AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size)
 176.967 +		{
 176.968 +			DefaultLogger::get()->warn("Unknown size of bone data structure");
 176.969 +			return NULL;
 176.970 +		}
 176.971 +
 176.972 +		MDL::IntBone_MDL7** apcBonesOut = new MDL::IntBone_MDL7*[pcHeader->bones_num];
 176.973 +		for (uint32_t crank = 0; crank < pcHeader->bones_num;++crank)
 176.974 +			apcBonesOut[crank] = new MDL::IntBone_MDL7();
 176.975 +
 176.976 +		// and calculate absolute bone offset matrices ...
 176.977 +		CalcAbsBoneMatrices_3DGS_MDL7(apcBonesOut);
 176.978 +		return apcBonesOut;
 176.979 +	}
 176.980 +	return NULL;
 176.981 +}
 176.982 +
 176.983 +// ------------------------------------------------------------------------------------------------
 176.984 +// read faces from a MDL7 file
 176.985 +void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
 176.986 +	MDL::IntGroupData_MDL7& groupData)
 176.987 +{
 176.988 +	const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer; 
 176.989 +	MDL::Triangle_MDL7* pcGroupTris = groupInfo.pcGroupTris;
 176.990 +
 176.991 +	// iterate through all triangles and build valid display lists
 176.992 +	unsigned int iOutIndex = 0;
 176.993 +	for (unsigned int iTriangle = 0; iTriangle < (unsigned int)groupInfo.pcGroup->numtris; ++iTriangle)	{  
 176.994 +		AI_SWAP2(pcGroupTris->v_index[0]);
 176.995 +		AI_SWAP2(pcGroupTris->v_index[1]);
 176.996 +		AI_SWAP2(pcGroupTris->v_index[2]);
 176.997 +
 176.998 +		// iterate through all indices of the current triangle
 176.999 +		for (unsigned int c = 0; c < 3;++c,++iOutIndex)	{
176.1000 +
176.1001 +			// validate the vertex index
176.1002 +			unsigned int iIndex = pcGroupTris->v_index[c];
176.1003 +			if(iIndex > (unsigned int)groupInfo.pcGroup->numverts)	{
176.1004 +				// (we might need to read this section a second time - to process frame vertices correctly)
176.1005 +				pcGroupTris->v_index[c] = iIndex = groupInfo.pcGroup->numverts-1;
176.1006 +				DefaultLogger::get()->warn("Index overflow in MDL7 vertex list");
176.1007 +			}
176.1008 +
176.1009 +			// write the output face index
176.1010 +			groupData.pcFaces[iTriangle].mIndices[2-c] = iOutIndex;
176.1011 +
176.1012 +			aiVector3D& vPosition = groupData.vPositions[ iOutIndex ];
176.1013 +			vPosition.x = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex, pcHeader->mainvertex_stc_size) .x;
176.1014 +			vPosition.y = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .y;
176.1015 +			vPosition.z = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .z;
176.1016 +
176.1017 +			// if we have bones, save the index
176.1018 +			if (!groupData.aiBones.empty()) {
176.1019 +				groupData.aiBones[iOutIndex] = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,
176.1020 +					iIndex,pcHeader->mainvertex_stc_size).vertindex;
176.1021 +			}
176.1022 +
176.1023 +			// now read the normal vector
176.1024 +			if (AI_MDL7_FRAMEVERTEX030305_STCSIZE <= pcHeader->mainvertex_stc_size)	{
176.1025 +				// read the full normal vector
176.1026 +				aiVector3D& vNormal = groupData.vNormals[ iOutIndex ];
176.1027 +				vNormal.x = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[0];
176.1028 +				AI_SWAP4(vNormal.x);    
176.1029 +				vNormal.y = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[1];
176.1030 +				AI_SWAP4(vNormal.y);    
176.1031 +				vNormal.z = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[2];
176.1032 +				AI_SWAP4(vNormal.z);    
176.1033 +			}
176.1034 +			else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size)	{
176.1035 +				// read the normal vector from Quake2's smart table
176.1036 +				aiVector3D& vNormal = groupData.vNormals[ iOutIndex ];
176.1037 +				MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,
176.1038 +					pcHeader->mainvertex_stc_size) .norm162index,vNormal);
176.1039 +			}
176.1040 +			// validate and process the first uv coordinate set
176.1041 +			if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)	{
176.1042 +
176.1043 +				if (groupInfo.pcGroup->num_stpts)	{
176.1044 +					AI_SWAP2(pcGroupTris->skinsets[0].st_index[0]); 
176.1045 +					AI_SWAP2(pcGroupTris->skinsets[0].st_index[1]);
176.1046 +					AI_SWAP2(pcGroupTris->skinsets[0].st_index[2]);
176.1047 +
176.1048 +					iIndex = pcGroupTris->skinsets[0].st_index[c];
176.1049 +					if(iIndex > (unsigned int)groupInfo.pcGroup->num_stpts)	{
176.1050 +						iIndex = groupInfo.pcGroup->num_stpts-1;
176.1051 +						DefaultLogger::get()->warn("Index overflow in MDL7 UV coordinate list (#1)");
176.1052 +					}
176.1053 +
176.1054 +					float u = groupInfo.pcGroupUVs[iIndex].u;
176.1055 +					float v = 1.0f-groupInfo.pcGroupUVs[iIndex].v; // DX to OGL
176.1056 +
176.1057 +					groupData.vTextureCoords1[iOutIndex].x = u;
176.1058 +					groupData.vTextureCoords1[iOutIndex].y = v;
176.1059 +				}
176.1060 +				// assign the material index, but only if it is existing
176.1061 +				if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX){
176.1062 +					AI_SWAP4(pcGroupTris->skinsets[0].material);		
176.1063 +					groupData.pcFaces[iTriangle].iMatIndex[0] = pcGroupTris->skinsets[0].material;
176.1064 +				}     
176.1065 +			}
176.1066 +			// validate and process the second uv coordinate set
176.1067 +			if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV)	{
176.1068 +
176.1069 +				if (groupInfo.pcGroup->num_stpts)	{
176.1070 +					AI_SWAP2(pcGroupTris->skinsets[1].st_index[0]); 
176.1071 +					AI_SWAP2(pcGroupTris->skinsets[1].st_index[1]);
176.1072 +					AI_SWAP2(pcGroupTris->skinsets[1].st_index[2]);
176.1073 +					AI_SWAP4(pcGroupTris->skinsets[1].material);		
176.1074 +
176.1075 +					iIndex = pcGroupTris->skinsets[1].st_index[c];
176.1076 +					if(iIndex > (unsigned int)groupInfo.pcGroup->num_stpts)	{
176.1077 +						iIndex = groupInfo.pcGroup->num_stpts-1;
176.1078 +						DefaultLogger::get()->warn("Index overflow in MDL7 UV coordinate list (#2)");
176.1079 +					}
176.1080 +
176.1081 +					float u = groupInfo.pcGroupUVs[ iIndex ].u;
176.1082 +					float v = 1.0f-groupInfo.pcGroupUVs[ iIndex ].v;
176.1083 +
176.1084 +					groupData.vTextureCoords2[ iOutIndex ].x = u;
176.1085 +					groupData.vTextureCoords2[ iOutIndex ].y = v; // DX to OGL
176.1086 +
176.1087 +					// check whether we do really need the second texture
176.1088 +					// coordinate set ... wastes memory and loading time
176.1089 +					if (0 != iIndex && (u != groupData.vTextureCoords1[ iOutIndex ].x ||
176.1090 +						v != groupData.vTextureCoords1[ iOutIndex ].y ) )
176.1091 +						groupData.bNeed2UV = true;
176.1092 +
176.1093 +					// if the material differs, we need a second skin, too
176.1094 +					if (pcGroupTris->skinsets[ 1 ].material != pcGroupTris->skinsets[ 0 ].material)
176.1095 +						groupData.bNeed2UV = true;
176.1096 +				}
176.1097 +				// assign the material index
176.1098 +				groupData.pcFaces[ iTriangle ].iMatIndex[ 1 ] = pcGroupTris->skinsets[ 1 ].material;
176.1099 +			}
176.1100 +		}
176.1101 +		// get the next triangle in the list
176.1102 +		pcGroupTris = (MDL::Triangle_MDL7*)((const char*)pcGroupTris + pcHeader->triangle_stc_size);
176.1103 +	}
176.1104 +}
176.1105 +
176.1106 +// ------------------------------------------------------------------------------------------------
176.1107 +// handle frames in a MDL7 file
176.1108 +bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
176.1109 +	MDL::IntGroupData_MDL7&  groupData,
176.1110 +	MDL::IntSharedData_MDL7& shared,
176.1111 +	const unsigned char*     szCurrent,
176.1112 +	const unsigned char**    szCurrentOut)
176.1113 +{
176.1114 +	ai_assert(NULL != szCurrent && NULL != szCurrentOut);
176.1115 +	const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)mBuffer;
176.1116 +
176.1117 +	// if we have no bones we can simply skip all frames,
176.1118 +	// otherwise we'll need to process them.
176.1119 +	// FIX: If we need another frame than the first we must apply frame vertex replacements ...
176.1120 +	for(unsigned int iFrame = 0; iFrame < (unsigned int)groupInfo.pcGroup->numframes;++iFrame)	{
176.1121 +		MDL::IntFrameInfo_MDL7 frame ((BE_NCONST MDL::Frame_MDL7*)szCurrent,iFrame);
176.1122 +
176.1123 +		AI_SWAP4(frame.pcFrame->vertices_count);     
176.1124 +		AI_SWAP4(frame.pcFrame->transmatrix_count);
176.1125 +
176.1126 +		const unsigned int iAdd = pcHeader->frame_stc_size + 
176.1127 +			frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size +
176.1128 +			frame.pcFrame->transmatrix_count * pcHeader->bonetrans_stc_size;
176.1129 +
176.1130 +		if (((const char*)szCurrent - (const char*)pcHeader) + iAdd > (unsigned int)pcHeader->data_size)	{
176.1131 +			DefaultLogger::get()->warn("Index overflow in frame area. "
176.1132 +				"Ignoring all frames and all further mesh groups, too.");
176.1133 +
176.1134 +			// don't parse more groups if we can't even read one
176.1135 +			// FIXME: sometimes this seems to occur even for valid files ...
176.1136 +			*szCurrentOut = szCurrent;
176.1137 +			return false;
176.1138 +		}
176.1139 +		// our output frame?
176.1140 +		if (configFrameID == iFrame)	{
176.1141 +			BE_NCONST MDL::Vertex_MDL7* pcFrameVertices = (BE_NCONST MDL::Vertex_MDL7*)(szCurrent+pcHeader->frame_stc_size);
176.1142 +
176.1143 +			for (unsigned int qq = 0; qq < frame.pcFrame->vertices_count;++qq)	{
176.1144 +				// I assume this are simple replacements for normal vertices, the bone index serving 
176.1145 +				// as the index of the vertex to be replaced.
176.1146 +				uint16_t iIndex = _AI_MDL7_ACCESS(pcFrameVertices,qq,pcHeader->framevertex_stc_size,MDL::Vertex_MDL7).vertindex;
176.1147 +				AI_SWAP2(iIndex);
176.1148 +				if (iIndex >= groupInfo.pcGroup->numverts)	{
176.1149 +					DefaultLogger::get()->warn("Invalid vertex index in frame vertex section");
176.1150 +					continue;
176.1151 +				}
176.1152 +
176.1153 +				aiVector3D vPosition,vNormal;
176.1154 +
176.1155 +				vPosition.x = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .x;
176.1156 +				AI_SWAP4(vPosition.x);    
176.1157 +				vPosition.y = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .y;
176.1158 +				AI_SWAP4(vPosition.y);		
176.1159 +				vPosition.z = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .z;
176.1160 +				AI_SWAP4(vPosition.z);
176.1161 +
176.1162 +				// now read the normal vector
176.1163 +				if (AI_MDL7_FRAMEVERTEX030305_STCSIZE <= pcHeader->mainvertex_stc_size)	{
176.1164 +					// read the full normal vector
176.1165 +					vNormal.x = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[0];
176.1166 +					AI_SWAP4(vNormal.x);     
176.1167 +					vNormal.y = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[1];
176.1168 +					AI_SWAP4(vNormal.y);		
176.1169 +					vNormal.z = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[2];
176.1170 +					AI_SWAP4(vNormal.z);
176.1171 +				}
176.1172 +				else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size)	{
176.1173 +					// read the normal vector from Quake2's smart table
176.1174 +					MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,
176.1175 +						pcHeader->framevertex_stc_size) .norm162index,vNormal);
176.1176 +				}
176.1177 +
176.1178 +				// FIXME: O(n^2) at the moment ...
176.1179 +				BE_NCONST MDL::Triangle_MDL7* pcGroupTris = groupInfo.pcGroupTris;
176.1180 +				unsigned int iOutIndex = 0;
176.1181 +				for (unsigned int iTriangle = 0; iTriangle < (unsigned int)groupInfo.pcGroup->numtris; ++iTriangle)	{
176.1182 +					// iterate through all indices of the current triangle
176.1183 +					for (unsigned int c = 0; c < 3;++c,++iOutIndex)	{
176.1184 +						// replace the vertex with the new data
176.1185 +						const unsigned int iCurIndex = pcGroupTris->v_index[c];
176.1186 +						if (iCurIndex == iIndex)	{
176.1187 +							groupData.vPositions[iOutIndex] = vPosition;
176.1188 +							groupData.vNormals[iOutIndex] = vNormal;
176.1189 +						}
176.1190 +					}
176.1191 +					// get the next triangle in the list
176.1192 +					pcGroupTris = (BE_NCONST MDL::Triangle_MDL7*)((const char*)
176.1193 +						pcGroupTris + pcHeader->triangle_stc_size);
176.1194 +				}
176.1195 +			}
176.1196 +		}
176.1197 +		// parse bone trafo matrix keys (only if there are bones ...)
176.1198 +		if (shared.apcOutBones) {
176.1199 +			ParseBoneTrafoKeys_3DGS_MDL7(groupInfo,frame,shared);
176.1200 +		}
176.1201 +		szCurrent += iAdd;
176.1202 +	}
176.1203 +	*szCurrentOut = szCurrent;
176.1204 +	return true;
176.1205 +}
176.1206 +
176.1207 +// ------------------------------------------------------------------------------------------------
176.1208 +// Sort faces by material, handle multiple UVs correctly
176.1209 +void MDLImporter::SortByMaterials_3DGS_MDL7(
176.1210 +	const MDL::IntGroupInfo_MDL7&   groupInfo,
176.1211 +	MDL::IntGroupData_MDL7&         groupData,
176.1212 +	MDL::IntSplitGroupData_MDL7& splitGroupData)
176.1213 +{
176.1214 +	const unsigned int iNumMaterials = (unsigned int)splitGroupData.shared.pcMats.size();
176.1215 +	if (!groupData.bNeed2UV)	{
176.1216 +		// if we don't need a second set of texture coordinates there is no reason to keep it in memory ...
176.1217 +		groupData.vTextureCoords2.clear();
176.1218 +
176.1219 +		// allocate the array
176.1220 +		splitGroupData.aiSplit = new std::vector<unsigned int>*[iNumMaterials];
176.1221 +
176.1222 +		for (unsigned int m = 0; m < iNumMaterials;++m)
176.1223 +			splitGroupData.aiSplit[m] = new std::vector<unsigned int>();
176.1224 +
176.1225 +		// iterate through all faces and sort by material
176.1226 +		for (unsigned int iFace = 0; iFace < (unsigned int)groupInfo.pcGroup->numtris;++iFace)	{
176.1227 +			// check range
176.1228 +			if (groupData.pcFaces[iFace].iMatIndex[0] >= iNumMaterials)	{
176.1229 +				// use the last material instead
176.1230 +				splitGroupData.aiSplit[iNumMaterials-1]->push_back(iFace);
176.1231 +
176.1232 +				// sometimes MED writes -1, but normally only if there is only
176.1233 +				// one skin assigned. No warning in this case
176.1234 +				if(0xFFFFFFFF != groupData.pcFaces[iFace].iMatIndex[0])
176.1235 +					DefaultLogger::get()->warn("Index overflow in MDL7 material list [#0]");
176.1236 +			}
176.1237 +			else splitGroupData.aiSplit[groupData.pcFaces[iFace].
176.1238 +				iMatIndex[0]]->push_back(iFace);
176.1239 +		}
176.1240 +	}
176.1241 +	else
176.1242 +	{
176.1243 +		// we need to build combined materials for each combination of
176.1244 +		std::vector<MDL::IntMaterial_MDL7> avMats;
176.1245 +		avMats.reserve(iNumMaterials*2);
176.1246 +
176.1247 +		// fixme: why on the heap?
176.1248 +		std::vector<std::vector<unsigned int>* > aiTempSplit(iNumMaterials*2);
176.1249 +		for (unsigned int m = 0; m < iNumMaterials;++m)
176.1250 +			aiTempSplit[m] = new std::vector<unsigned int>();
176.1251 +
176.1252 +		// iterate through all faces and sort by material
176.1253 +		for (unsigned int iFace = 0; iFace < (unsigned int)groupInfo.pcGroup->numtris;++iFace)	{
176.1254 +			// check range
176.1255 +			unsigned int iMatIndex = groupData.pcFaces[iFace].iMatIndex[0];
176.1256 +			if (iMatIndex >= iNumMaterials)	{
176.1257 +				// sometimes MED writes -1, but normally only if there is only
176.1258 +				// one skin assigned. No warning in this case
176.1259 +				if(UINT_MAX != iMatIndex)
176.1260 +					DefaultLogger::get()->warn("Index overflow in MDL7 material list [#1]");
176.1261 +				iMatIndex = iNumMaterials-1;
176.1262 +			}
176.1263 +			unsigned int iMatIndex2 = groupData.pcFaces[iFace].iMatIndex[1];
176.1264 +
176.1265 +			unsigned int iNum = iMatIndex;
176.1266 +			if (UINT_MAX != iMatIndex2 && iMatIndex != iMatIndex2)	{
176.1267 +				if (iMatIndex2 >= iNumMaterials)	{
176.1268 +					// sometimes MED writes -1, but normally only if there is only
176.1269 +					// one skin assigned. No warning in this case
176.1270 +					DefaultLogger::get()->warn("Index overflow in MDL7 material list [#2]");
176.1271 +					iMatIndex2 = iNumMaterials-1;
176.1272 +				}
176.1273 +
176.1274 +				// do a slow seach in the list ...
176.1275 +				iNum = 0;
176.1276 +				bool bFound = false;
176.1277 +				for (std::vector<MDL::IntMaterial_MDL7>::iterator i =  avMats.begin();i != avMats.end();++i,++iNum){
176.1278 +					if ((*i).iOldMatIndices[0] == iMatIndex && (*i).iOldMatIndices[1] == iMatIndex2)	{
176.1279 +						// reuse this material
176.1280 +						bFound = true;
176.1281 +						break;
176.1282 +					}
176.1283 +				}
176.1284 +				if (!bFound)	{
176.1285 +					//  build a new material ...
176.1286 +					MDL::IntMaterial_MDL7 sHelper;
176.1287 +					sHelper.pcMat = new aiMaterial();
176.1288 +					sHelper.iOldMatIndices[0] = iMatIndex;
176.1289 +					sHelper.iOldMatIndices[1] = iMatIndex2;
176.1290 +					JoinSkins_3DGS_MDL7(splitGroupData.shared.pcMats[iMatIndex],
176.1291 +						splitGroupData.shared.pcMats[iMatIndex2],sHelper.pcMat);
176.1292 +
176.1293 +					// and add it to the list
176.1294 +					avMats.push_back(sHelper);
176.1295 +					iNum = (unsigned int)avMats.size()-1;
176.1296 +				}
176.1297 +				// adjust the size of the file array
176.1298 +				if (iNum == aiTempSplit.size()) {
176.1299 +					aiTempSplit.push_back(new std::vector<unsigned int>());
176.1300 +				}
176.1301 +			}
176.1302 +			aiTempSplit[iNum]->push_back(iFace);
176.1303 +		}
176.1304 +
176.1305 +		// now add the newly created materials to the old list
176.1306 +		if (0 == groupInfo.iIndex)	{
176.1307 +			splitGroupData.shared.pcMats.resize(avMats.size());
176.1308 +			for (unsigned int o = 0; o < avMats.size();++o)
176.1309 +				splitGroupData.shared.pcMats[o] = avMats[o].pcMat;
176.1310 +		}
176.1311 +		else	{
176.1312 +			// This might result in redundant materials ...
176.1313 +			splitGroupData.shared.pcMats.resize(iNumMaterials + avMats.size());
176.1314 +			for (unsigned int o = iNumMaterials; o < avMats.size();++o)
176.1315 +				splitGroupData.shared.pcMats[o] = avMats[o].pcMat;
176.1316 +		}
176.1317 +
176.1318 +		// and build the final face-to-material array
176.1319 +		splitGroupData.aiSplit = new std::vector<unsigned int>*[aiTempSplit.size()];
176.1320 +		for (unsigned int m = 0; m < iNumMaterials;++m)
176.1321 +			splitGroupData.aiSplit[m] = aiTempSplit[m];
176.1322 +	}
176.1323 +}
176.1324 +
176.1325 +// ------------------------------------------------------------------------------------------------
176.1326 +// Read a MDL7 file
176.1327 +void MDLImporter::InternReadFile_3DGS_MDL7( )
176.1328 +{
176.1329 +	ai_assert(NULL != pScene);
176.1330 +
176.1331 +	MDL::IntSharedData_MDL7 sharedData;
176.1332 +
176.1333 +	// current cursor position in the file
176.1334 +	BE_NCONST MDL::Header_MDL7 *pcHeader = (BE_NCONST MDL::Header_MDL7*)this->mBuffer; 
176.1335 +	const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
176.1336 +
176.1337 +	AI_SWAP4(pcHeader->version);
176.1338 +	AI_SWAP4(pcHeader->bones_num);
176.1339 +	AI_SWAP4(pcHeader->groups_num);
176.1340 +	AI_SWAP4(pcHeader->data_size);
176.1341 +	AI_SWAP4(pcHeader->entlump_size);
176.1342 +	AI_SWAP4(pcHeader->medlump_size);
176.1343 +	AI_SWAP2(pcHeader->bone_stc_size);
176.1344 +	AI_SWAP2(pcHeader->skin_stc_size);
176.1345 +	AI_SWAP2(pcHeader->colorvalue_stc_size);
176.1346 +	AI_SWAP2(pcHeader->material_stc_size);
176.1347 +	AI_SWAP2(pcHeader->skinpoint_stc_size);
176.1348 +	AI_SWAP2(pcHeader->triangle_stc_size);
176.1349 +	AI_SWAP2(pcHeader->mainvertex_stc_size);
176.1350 +	AI_SWAP2(pcHeader->framevertex_stc_size);
176.1351 +	AI_SWAP2(pcHeader->bonetrans_stc_size);
176.1352 +	AI_SWAP2(pcHeader->frame_stc_size);
176.1353 +
176.1354 +	// validate the header of the file. There are some structure
176.1355 +	// sizes that are expected by the loader to be constant 
176.1356 +	this->ValidateHeader_3DGS_MDL7(pcHeader);
176.1357 +
176.1358 +	// load all bones (they are shared by all groups, so
176.1359 +	// we'll need to add them to all groups/meshes later)
176.1360 +	// apcBonesOut is a list of all bones or NULL if they could not been loaded 
176.1361 +	szCurrent += pcHeader->bones_num * pcHeader->bone_stc_size;
176.1362 +	sharedData.apcOutBones = this->LoadBones_3DGS_MDL7();
176.1363 +
176.1364 +	// vector to held all created meshes
176.1365 +	std::vector<aiMesh*>* avOutList;
176.1366 +
176.1367 +	// 3 meshes per group - that should be OK for most models
176.1368 +	avOutList = new std::vector<aiMesh*>[pcHeader->groups_num];
176.1369 +	for (uint32_t i = 0; i < pcHeader->groups_num;++i)
176.1370 +		avOutList[i].reserve(3);
176.1371 +
176.1372 +	// buffer to held the names of all groups in the file
176.1373 +	char* aszGroupNameBuffer = new char[AI_MDL7_MAX_GROUPNAMESIZE*pcHeader->groups_num];
176.1374 +
176.1375 +	// read all groups
176.1376 +	for (unsigned int iGroup = 0; iGroup < (unsigned int)pcHeader->groups_num;++iGroup)	{
176.1377 +		MDL::IntGroupInfo_MDL7 groupInfo((BE_NCONST MDL::Group_MDL7*)szCurrent,iGroup);
176.1378 +		szCurrent = (const unsigned char*)(groupInfo.pcGroup+1);
176.1379 +
176.1380 +		VALIDATE_FILE_SIZE(szCurrent);
176.1381 +
176.1382 +		AI_SWAP4(groupInfo.pcGroup->groupdata_size);
176.1383 +		AI_SWAP4(groupInfo.pcGroup->numskins);
176.1384 +		AI_SWAP4(groupInfo.pcGroup->num_stpts);
176.1385 +		AI_SWAP4(groupInfo.pcGroup->numtris);
176.1386 +		AI_SWAP4(groupInfo.pcGroup->numverts);
176.1387 +		AI_SWAP4(groupInfo.pcGroup->numframes);
176.1388 +
176.1389 +		if (1 != groupInfo.pcGroup->typ)	{
176.1390 +			// Not a triangle-based mesh
176.1391 +			DefaultLogger::get()->warn("[3DGS MDL7] Not a triangle mesh group. Continuing happily");
176.1392 +		}
176.1393 +
176.1394 +		// store the name of the group
176.1395 +		const unsigned int ofs = iGroup*AI_MDL7_MAX_GROUPNAMESIZE;
176.1396 +		::memcpy(&aszGroupNameBuffer[ofs],
176.1397 +			groupInfo.pcGroup->name,AI_MDL7_MAX_GROUPNAMESIZE);
176.1398 +
176.1399 +		// make sure '\0' is at the end
176.1400 +		aszGroupNameBuffer[ofs+AI_MDL7_MAX_GROUPNAMESIZE-1] = '\0';
176.1401 +
176.1402 +		// read all skins
176.1403 +		sharedData.pcMats.reserve(sharedData.pcMats.size() + groupInfo.pcGroup->numskins);
176.1404 +		sharedData.abNeedMaterials.resize(sharedData.abNeedMaterials.size() +
176.1405 +			groupInfo.pcGroup->numskins,false);
176.1406 +
176.1407 +		for (unsigned int iSkin = 0; iSkin < (unsigned int)groupInfo.pcGroup->numskins;++iSkin)	{
176.1408 +			ParseSkinLump_3DGS_MDL7(szCurrent,&szCurrent,sharedData.pcMats);
176.1409 +		}
176.1410 +		// if we have absolutely no skin loaded we need to generate a default material
176.1411 +		if (sharedData.pcMats.empty())	{
176.1412 +			const int iMode = (int)aiShadingMode_Gouraud;
176.1413 +			sharedData.pcMats.push_back(new aiMaterial());
176.1414 +			aiMaterial* pcHelper = (aiMaterial*)sharedData.pcMats[0];
176.1415 +			pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
176.1416 +
176.1417 +			aiColor3D clr;
176.1418 +			clr.b = clr.g = clr.r = 0.6f;
176.1419 +			pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
176.1420 +			pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
176.1421 +
176.1422 +			clr.b = clr.g = clr.r = 0.05f;
176.1423 +			pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
176.1424 +
176.1425 +			aiString szName;
176.1426 +			szName.Set(AI_DEFAULT_MATERIAL_NAME);
176.1427 +			pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
176.1428 +
176.1429 +			sharedData.abNeedMaterials.resize(1,false);
176.1430 +		}
176.1431 +
176.1432 +		// now get a pointer to all texture coords in the group
176.1433 +		groupInfo.pcGroupUVs = (BE_NCONST MDL::TexCoord_MDL7*)szCurrent;      
176.1434 +		for(int i = 0; i < groupInfo.pcGroup->num_stpts; ++i){  
176.1435 +			AI_SWAP4(groupInfo.pcGroupUVs[i].u);
176.1436 +			AI_SWAP4(groupInfo.pcGroupUVs[i].v);
176.1437 +		}
176.1438 +		szCurrent += pcHeader->skinpoint_stc_size * groupInfo.pcGroup->num_stpts;
176.1439 +
176.1440 +		// now get a pointer to all triangle in the group
176.1441 +		groupInfo.pcGroupTris = (Triangle_MDL7*)szCurrent;
176.1442 +		szCurrent += pcHeader->triangle_stc_size * groupInfo.pcGroup->numtris;
176.1443 +
176.1444 +		// now get a pointer to all vertices in the group
176.1445 +		groupInfo.pcGroupVerts = (BE_NCONST MDL::Vertex_MDL7*)szCurrent;
176.1446 +		for(int i = 0; i < groupInfo.pcGroup->numverts; ++i){  
176.1447 +			AI_SWAP4(groupInfo.pcGroupVerts[i].x);
176.1448 +			AI_SWAP4(groupInfo.pcGroupVerts[i].y);
176.1449 +			AI_SWAP4(groupInfo.pcGroupVerts[i].z);
176.1450 +
176.1451 +			AI_SWAP2(groupInfo.pcGroupVerts[i].vertindex);
176.1452 +			//We can not swap the normal information now as we don't know which of the two kinds it is
176.1453 +		}
176.1454 +		szCurrent += pcHeader->mainvertex_stc_size * groupInfo.pcGroup->numverts;
176.1455 +		VALIDATE_FILE_SIZE(szCurrent);
176.1456 +
176.1457 +		MDL::IntSplitGroupData_MDL7 splitGroupData(sharedData,avOutList[iGroup]);
176.1458 +		MDL::IntGroupData_MDL7 groupData;
176.1459 +		if (groupInfo.pcGroup->numtris && groupInfo.pcGroup->numverts)
176.1460 +		{
176.1461 +			// build output vectors
176.1462 +			const unsigned int iNumVertices = groupInfo.pcGroup->numtris*3;
176.1463 +			groupData.vPositions.resize(iNumVertices);
176.1464 +			groupData.vNormals.resize(iNumVertices);
176.1465 +
176.1466 +			if (sharedData.apcOutBones)groupData.aiBones.resize(iNumVertices,UINT_MAX);
176.1467 +
176.1468 +			// it is also possible that there are 0 UV coordinate sets
176.1469 +			if (groupInfo.pcGroup->num_stpts){
176.1470 +				groupData.vTextureCoords1.resize(iNumVertices,aiVector3D());
176.1471 +
176.1472 +				// check whether the triangle data structure is large enough
176.1473 +				// to contain a second UV coodinate set
176.1474 +				if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV)	{
176.1475 +					groupData.vTextureCoords2.resize(iNumVertices,aiVector3D());
176.1476 +					groupData.bNeed2UV = true;
176.1477 +				}
176.1478 +			}
176.1479 +			groupData.pcFaces = new MDL::IntFace_MDL7[groupInfo.pcGroup->numtris];
176.1480 +
176.1481 +			// read all faces into the preallocated arrays
176.1482 +			ReadFaces_3DGS_MDL7(groupInfo, groupData);
176.1483 +
176.1484 +			// sort by materials
176.1485 +			SortByMaterials_3DGS_MDL7(groupInfo, groupData,
176.1486 +				splitGroupData);
176.1487 +
176.1488 +			for (unsigned int qq = 0; qq < sharedData.pcMats.size();++qq)	{
176.1489 +				if (!splitGroupData.aiSplit[qq]->empty())
176.1490 +					sharedData.abNeedMaterials[qq] = true;
176.1491 +			}
176.1492 +		}
176.1493 +		else DefaultLogger::get()->warn("[3DGS MDL7] Mesh group consists of 0 "
176.1494 +			"vertices or faces. It will be skipped.");
176.1495 +
176.1496 +		// process all frames and generate output meshes
176.1497 +		ProcessFrames_3DGS_MDL7(groupInfo,groupData, sharedData,szCurrent,&szCurrent);
176.1498 +		GenerateOutputMeshes_3DGS_MDL7(groupData,splitGroupData);
176.1499 +	}
176.1500 +
176.1501 +	// generate a nodegraph and subnodes for each group
176.1502 +	pScene->mRootNode = new aiNode();
176.1503 +
176.1504 +	// now we need to build a final mesh list
176.1505 +	for (uint32_t i = 0; i < pcHeader->groups_num;++i)
176.1506 +		pScene->mNumMeshes += (unsigned int)avOutList[i].size();
176.1507 +	
176.1508 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];	{
176.1509 +		unsigned int p = 0,q = 0;
176.1510 +		for (uint32_t i = 0; i < pcHeader->groups_num;++i)	{
176.1511 +			for (unsigned int a = 0; a < avOutList[i].size();++a)	{
176.1512 +				pScene->mMeshes[p++] = avOutList[i][a];
176.1513 +			}
176.1514 +			if (!avOutList[i].empty())++pScene->mRootNode->mNumChildren;
176.1515 +		}
176.1516 +		// we will later need an extra node to serve as parent for all bones
176.1517 +		if (sharedData.apcOutBones)++pScene->mRootNode->mNumChildren;
176.1518 +		this->pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
176.1519 +		p = 0;
176.1520 +		for (uint32_t i = 0; i < pcHeader->groups_num;++i)	{
176.1521 +			if (avOutList[i].empty())continue;
176.1522 +
176.1523 +			aiNode* const pcNode = pScene->mRootNode->mChildren[p] = new aiNode();
176.1524 +			pcNode->mNumMeshes = (unsigned int)avOutList[i].size();
176.1525 +			pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
176.1526 +			pcNode->mParent = this->pScene->mRootNode;
176.1527 +			for (unsigned int a = 0; a < pcNode->mNumMeshes;++a)
176.1528 +				pcNode->mMeshes[a] = q + a;
176.1529 +			q += (unsigned int)avOutList[i].size();
176.1530 +
176.1531 +			// setup the name of the node
176.1532 +			char* const szBuffer = &aszGroupNameBuffer[i*AI_MDL7_MAX_GROUPNAMESIZE];
176.1533 +			if ('\0' == *szBuffer)
176.1534 +				pcNode->mName.length = ::sprintf(szBuffer,"Group_%i",p);
176.1535 +			else pcNode->mName.length = ::strlen(szBuffer);
176.1536 +			::strcpy(pcNode->mName.data,szBuffer);
176.1537 +			++p;
176.1538 +		}
176.1539 +	}
176.1540 +
176.1541 +	// if there is only one root node with a single child we can optimize it a bit ...
176.1542 +	if (1 == pScene->mRootNode->mNumChildren && !sharedData.apcOutBones)	{
176.1543 +		aiNode* pcOldRoot = this->pScene->mRootNode;
176.1544 +		pScene->mRootNode = pcOldRoot->mChildren[0];
176.1545 +		pcOldRoot->mChildren[0] = NULL;
176.1546 +		delete pcOldRoot;
176.1547 +		pScene->mRootNode->mParent = NULL;
176.1548 +	}
176.1549 +	else pScene->mRootNode->mName.Set("<mesh_root>");
176.1550 +
176.1551 +	delete[] avOutList;
176.1552 +	delete[] aszGroupNameBuffer; 
176.1553 +	AI_DEBUG_INVALIDATE_PTR(avOutList);
176.1554 +	AI_DEBUG_INVALIDATE_PTR(aszGroupNameBuffer);
176.1555 +
176.1556 +	// build a final material list. 
176.1557 +	CopyMaterials_3DGS_MDL7(sharedData);
176.1558 +	HandleMaterialReferences_3DGS_MDL7();
176.1559 +
176.1560 +	// generate output bone animations and add all bones to the scenegraph
176.1561 +	if (sharedData.apcOutBones)	{
176.1562 +		// this step adds empty dummy bones to the nodegraph
176.1563 +		// insert another dummy node to avoid name conflicts
176.1564 +		aiNode* const pc = pScene->mRootNode->mChildren[pScene->mRootNode->mNumChildren-1] = new aiNode();
176.1565 +
176.1566 +		pc->mName.Set("<skeleton_root>");
176.1567 +
176.1568 +		// add bones to the nodegraph
176.1569 +		AddBonesToNodeGraph_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
176.1570 +			sharedData.apcOutBones,pc,0xffff);
176.1571 +
176.1572 +		// this steps build a valid output animation
176.1573 +		BuildOutputAnims_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
176.1574 +			sharedData.apcOutBones);
176.1575 +	}
176.1576 +}
176.1577 +
176.1578 +// ------------------------------------------------------------------------------------------------
176.1579 +// Copy materials
176.1580 +void MDLImporter::CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared)
176.1581 +{
176.1582 +	pScene->mNumMaterials = (unsigned int)shared.pcMats.size();
176.1583 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
176.1584 +	for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
176.1585 +		pScene->mMaterials[i] = shared.pcMats[i];
176.1586 +}
176.1587 +
176.1588 +
176.1589 +// ------------------------------------------------------------------------------------------------
176.1590 +// Process material references
176.1591 +void MDLImporter::HandleMaterialReferences_3DGS_MDL7()
176.1592 +{
176.1593 +	// search for referrer materials
176.1594 +	for (unsigned int i = 0; i < pScene->mNumMaterials;++i)	{
176.1595 +		int iIndex = 0;
176.1596 +		if (AI_SUCCESS == aiGetMaterialInteger(pScene->mMaterials[i],AI_MDL7_REFERRER_MATERIAL, &iIndex) )	{
176.1597 +			for (unsigned int a = 0; a < pScene->mNumMeshes;++a)	{
176.1598 +				aiMesh* const pcMesh = pScene->mMeshes[a];
176.1599 +				if (i == pcMesh->mMaterialIndex) {
176.1600 +					pcMesh->mMaterialIndex = iIndex;
176.1601 +				}
176.1602 +			}
176.1603 +			// collapse the rest of the array
176.1604 +			delete pScene->mMaterials[i];
176.1605 +			for (unsigned int pp = i; pp < pScene->mNumMaterials-1;++pp)	{
176.1606 +
176.1607 +				pScene->mMaterials[pp] = pScene->mMaterials[pp+1];
176.1608 +				for (unsigned int a = 0; a < pScene->mNumMeshes;++a)	{
176.1609 +					aiMesh* const pcMesh = pScene->mMeshes[a];
176.1610 +					if (pcMesh->mMaterialIndex > i)--pcMesh->mMaterialIndex;
176.1611 +				}
176.1612 +			}
176.1613 +			--pScene->mNumMaterials;
176.1614 +		}
176.1615 +	}
176.1616 +}
176.1617 +
176.1618 +// ------------------------------------------------------------------------------------------------
176.1619 +// Read bone transformation keys
176.1620 +void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
176.1621 +	const MDL::IntGroupInfo_MDL7& groupInfo,
176.1622 +	IntFrameInfo_MDL7&            frame,
176.1623 +	MDL::IntSharedData_MDL7&      shared)
176.1624 +{
176.1625 +	const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
176.1626 +
176.1627 +	// only the first group contains bone animation keys
176.1628 +	if (frame.pcFrame->transmatrix_count)	{
176.1629 +		if (!groupInfo.iIndex)	{
176.1630 +			// skip all frames vertices. We can't support them
176.1631 +			const MDL::BoneTransform_MDL7* pcBoneTransforms = (const MDL::BoneTransform_MDL7*)
176.1632 +				(((const char*)frame.pcFrame) + pcHeader->frame_stc_size + 
176.1633 +				frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size);
176.1634 +
176.1635 +			// read all transformation matrices
176.1636 +			for (unsigned int iTrafo = 0; iTrafo < frame.pcFrame->transmatrix_count;++iTrafo)	{
176.1637 +				if(pcBoneTransforms->bone_index >= pcHeader->bones_num)	{
176.1638 +					DefaultLogger::get()->warn("Index overflow in frame area. "
176.1639 +						"Unable to parse this bone transformation");
176.1640 +				}
176.1641 +				else	{
176.1642 +					AddAnimationBoneTrafoKey_3DGS_MDL7(frame.iIndex,
176.1643 +						pcBoneTransforms,shared.apcOutBones);
176.1644 +				}
176.1645 +				pcBoneTransforms = (const MDL::BoneTransform_MDL7*)(
176.1646 +					(const char*)pcBoneTransforms + pcHeader->bonetrans_stc_size);
176.1647 +			}
176.1648 +		}
176.1649 +		else	{
176.1650 +			DefaultLogger::get()->warn("Ignoring animation keyframes in groups != 0");
176.1651 +		}
176.1652 +	}
176.1653 +}
176.1654 +
176.1655 +// ------------------------------------------------------------------------------------------------
176.1656 +// Attach bones to the output nodegraph
176.1657 +void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBones,
176.1658 +	aiNode* pcParent,uint16_t iParentIndex)
176.1659 +{
176.1660 +	ai_assert(NULL != apcBones && NULL != pcParent);
176.1661 +
176.1662 +	// get a pointer to the header ...
176.1663 +	const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
176.1664 +
176.1665 +	const MDL::IntBone_MDL7** apcBones2 = apcBones;
176.1666 +	for (uint32_t i = 0; i <  pcHeader->bones_num;++i)	{
176.1667 +
176.1668 +		const MDL::IntBone_MDL7* const pcBone = *apcBones2++;
176.1669 +		if (pcBone->iParent == iParentIndex) {
176.1670 +			++pcParent->mNumChildren;
176.1671 +		}
176.1672 +	}
176.1673 +	pcParent->mChildren = new aiNode*[pcParent->mNumChildren];
176.1674 +	unsigned int qq = 0;
176.1675 +	for (uint32_t i = 0; i <  pcHeader->bones_num;++i)	{
176.1676 +
176.1677 +		const MDL::IntBone_MDL7* const pcBone = *apcBones++;
176.1678 +		if (pcBone->iParent != iParentIndex)continue;
176.1679 +
176.1680 +		aiNode* pcNode = pcParent->mChildren[qq++] = new aiNode();
176.1681 +		pcNode->mName = aiString( pcBone->mName );
176.1682 +
176.1683 +		AddBonesToNodeGraph_3DGS_MDL7(apcBones,pcNode,(uint16_t)i);
176.1684 +	}
176.1685 +}
176.1686 +
176.1687 +// ------------------------------------------------------------------------------------------------
176.1688 +// Build output animations
176.1689 +void MDLImporter::BuildOutputAnims_3DGS_MDL7(
176.1690 +	const MDL::IntBone_MDL7** apcBonesOut)
176.1691 +{
176.1692 +	ai_assert(NULL != apcBonesOut);
176.1693 +	const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)mBuffer;
176.1694 +
176.1695 +	// one animation ...
176.1696 +	aiAnimation* pcAnim = new aiAnimation();
176.1697 +	for (uint32_t i = 0; i < pcHeader->bones_num;++i)	{
176.1698 +		if (!apcBonesOut[i]->pkeyPositions.empty())	{
176.1699 +
176.1700 +			// get the last frame ... (needn't be equal to pcHeader->frames_num)
176.1701 +			for (size_t qq = 0; qq < apcBonesOut[i]->pkeyPositions.size();++qq)	{
176.1702 +				pcAnim->mDuration = std::max(pcAnim->mDuration, (double)
176.1703 +					apcBonesOut[i]->pkeyPositions[qq].mTime);
176.1704 +			}
176.1705 +			++pcAnim->mNumChannels;
176.1706 +		}
176.1707 +	}
176.1708 +	if (pcAnim->mDuration)	{
176.1709 +		pcAnim->mChannels = new aiNodeAnim*[pcAnim->mNumChannels];
176.1710 +
176.1711 +		unsigned int iCnt = 0;
176.1712 +		for (uint32_t i = 0; i < pcHeader->bones_num;++i)	{
176.1713 +			if (!apcBonesOut[i]->pkeyPositions.empty())	{
176.1714 +				const MDL::IntBone_MDL7* const intBone = apcBonesOut[i];
176.1715 +
176.1716 +				aiNodeAnim* const pcNodeAnim = pcAnim->mChannels[iCnt++] = new aiNodeAnim();
176.1717 +				pcNodeAnim->mNodeName = aiString( intBone->mName );
176.1718 +
176.1719 +				// allocate enough storage for all keys
176.1720 +				pcNodeAnim->mNumPositionKeys = (unsigned int)intBone->pkeyPositions.size();
176.1721 +				pcNodeAnim->mNumScalingKeys  = (unsigned int)intBone->pkeyPositions.size();
176.1722 +				pcNodeAnim->mNumRotationKeys = (unsigned int)intBone->pkeyPositions.size();
176.1723 +
176.1724 +				pcNodeAnim->mPositionKeys = new aiVectorKey[pcNodeAnim->mNumPositionKeys];
176.1725 +				pcNodeAnim->mScalingKeys  = new aiVectorKey[pcNodeAnim->mNumPositionKeys];
176.1726 +				pcNodeAnim->mRotationKeys = new aiQuatKey[pcNodeAnim->mNumPositionKeys];
176.1727 +
176.1728 +				// copy all keys
176.1729 +				for (unsigned int qq = 0; qq < pcNodeAnim->mNumPositionKeys;++qq)	{
176.1730 +					pcNodeAnim->mPositionKeys[qq] = intBone->pkeyPositions[qq];
176.1731 +					pcNodeAnim->mScalingKeys[qq] = intBone->pkeyScalings[qq];
176.1732 +					pcNodeAnim->mRotationKeys[qq] = intBone->pkeyRotations[qq];
176.1733 +				}
176.1734 +			}
176.1735 +		}
176.1736 +
176.1737 +		// store the output animation
176.1738 +		pScene->mNumAnimations = 1;
176.1739 +		pScene->mAnimations = new aiAnimation*[1];
176.1740 +		pScene->mAnimations[0] = pcAnim;
176.1741 +	}
176.1742 +	else delete pcAnim;
176.1743 +}
176.1744 +
176.1745 +// ------------------------------------------------------------------------------------------------
176.1746 +void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
176.1747 +	const MDL::BoneTransform_MDL7* pcBoneTransforms,
176.1748 +	MDL::IntBone_MDL7** apcBonesOut)
176.1749 +{
176.1750 +	ai_assert(NULL != pcBoneTransforms);
176.1751 +	ai_assert(NULL != apcBonesOut);
176.1752 +
176.1753 +	// first .. get the transformation matrix
176.1754 +	aiMatrix4x4 mTransform;
176.1755 +	mTransform.a1 = pcBoneTransforms->m[0];
176.1756 +	mTransform.b1 = pcBoneTransforms->m[1];
176.1757 +	mTransform.c1 = pcBoneTransforms->m[2];
176.1758 +	mTransform.d1 = pcBoneTransforms->m[3];
176.1759 +
176.1760 +	mTransform.a2 = pcBoneTransforms->m[4];
176.1761 +	mTransform.b2 = pcBoneTransforms->m[5];
176.1762 +	mTransform.c2 = pcBoneTransforms->m[6];
176.1763 +	mTransform.d2 = pcBoneTransforms->m[7];
176.1764 +
176.1765 +	mTransform.a3 = pcBoneTransforms->m[8];
176.1766 +	mTransform.b3 = pcBoneTransforms->m[9];
176.1767 +	mTransform.c3 = pcBoneTransforms->m[10];
176.1768 +	mTransform.d3 = pcBoneTransforms->m[11];
176.1769 +
176.1770 +	// now decompose the transformation matrix into separate
176.1771 +	// scaling, rotation and translation
176.1772 +	aiVectorKey vScaling,vPosition;
176.1773 +	aiQuatKey qRotation;
176.1774 +
176.1775 +	// FIXME: Decompose will assert in debug builds if the matrix is invalid ...
176.1776 +	mTransform.Decompose(vScaling.mValue,qRotation.mValue,vPosition.mValue);
176.1777 +
176.1778 +	// now generate keys
176.1779 +	vScaling.mTime = qRotation.mTime = vPosition.mTime = (double)iTrafo;
176.1780 +
176.1781 +	// add the keys to the bone
176.1782 +	MDL::IntBone_MDL7* const pcBoneOut = apcBonesOut[pcBoneTransforms->bone_index];
176.1783 +	pcBoneOut->pkeyPositions.push_back	( vPosition );
176.1784 +	pcBoneOut->pkeyScalings.push_back	( vScaling  );
176.1785 +	pcBoneOut->pkeyRotations.push_back	( qRotation );
176.1786 +}
176.1787 +
176.1788 +// ------------------------------------------------------------------------------------------------
176.1789 +// Construct output meshes
176.1790 +void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
176.1791 +	MDL::IntGroupData_MDL7& groupData,
176.1792 +	MDL::IntSplitGroupData_MDL7& splitGroupData)
176.1793 +{
176.1794 +	const MDL::IntSharedData_MDL7& shared = splitGroupData.shared;
176.1795 +
176.1796 +	// get a pointer to the header ...
176.1797 +	const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
176.1798 +	const unsigned int iNumOutBones = pcHeader->bones_num;
176.1799 +
176.1800 +	for (std::vector<aiMaterial*>::size_type i = 0; i < shared.pcMats.size();++i)	{
176.1801 +		if (!splitGroupData.aiSplit[i]->empty())	{
176.1802 +
176.1803 +			// allocate the output mesh
176.1804 +			aiMesh* pcMesh = new aiMesh();
176.1805 +
176.1806 +			pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
176.1807 +			pcMesh->mMaterialIndex = (unsigned int)i;
176.1808 +
176.1809 +			// allocate output storage
176.1810 +			pcMesh->mNumFaces = (unsigned int)splitGroupData.aiSplit[i]->size();
176.1811 +			pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
176.1812 +
176.1813 +			pcMesh->mNumVertices = pcMesh->mNumFaces*3;
176.1814 +			pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
176.1815 +			pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
176.1816 +
176.1817 +			if (!groupData.vTextureCoords1.empty())	{
176.1818 +				pcMesh->mNumUVComponents[0] = 2;
176.1819 +				pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
176.1820 +				if (!groupData.vTextureCoords2.empty())	{
176.1821 +					pcMesh->mNumUVComponents[1] = 2;
176.1822 +					pcMesh->mTextureCoords[1] = new aiVector3D[pcMesh->mNumVertices];
176.1823 +				}
176.1824 +			}
176.1825 +
176.1826 +			// iterate through all faces and build an unique set of vertices
176.1827 +			unsigned int iCurrent = 0;
176.1828 +			for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace)	{
176.1829 +				pcMesh->mFaces[iFace].mNumIndices = 3;
176.1830 +				pcMesh->mFaces[iFace].mIndices = new unsigned int[3];
176.1831 +
176.1832 +				unsigned int iSrcFace = splitGroupData.aiSplit[i]->operator[](iFace);
176.1833 +				const MDL::IntFace_MDL7& oldFace = groupData.pcFaces[iSrcFace];
176.1834 +
176.1835 +				// iterate through all face indices
176.1836 +				for (unsigned int c = 0; c < 3;++c)	{
176.1837 +					const uint32_t iIndex = oldFace.mIndices[c];
176.1838 +					pcMesh->mVertices[iCurrent] = groupData.vPositions[iIndex];
176.1839 +					pcMesh->mNormals[iCurrent] = groupData.vNormals[iIndex];
176.1840 +
176.1841 +					if (!groupData.vTextureCoords1.empty())	{
176.1842 +
176.1843 +						pcMesh->mTextureCoords[0][iCurrent] = groupData.vTextureCoords1[iIndex];
176.1844 +						if (!groupData.vTextureCoords2.empty())	{
176.1845 +							pcMesh->mTextureCoords[1][iCurrent] = groupData.vTextureCoords2[iIndex];
176.1846 +						}
176.1847 +					}
176.1848 +					pcMesh->mFaces[iFace].mIndices[c] = iCurrent++;
176.1849 +				}
176.1850 +			}
176.1851 +
176.1852 +			// if we have bones in the mesh we'll need to generate
176.1853 +			// proper vertex weights for them
176.1854 +			if (!groupData.aiBones.empty())	{
176.1855 +				std::vector<std::vector<unsigned int> > aaiVWeightList;
176.1856 +				aaiVWeightList.resize(iNumOutBones);
176.1857 +
176.1858 +				int iCurrent = 0;
176.1859 +				for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace)	{
176.1860 +					unsigned int iSrcFace = splitGroupData.aiSplit[i]->operator[](iFace);
176.1861 +					const MDL::IntFace_MDL7& oldFace = groupData.pcFaces[iSrcFace];
176.1862 +
176.1863 +					// iterate through all face indices
176.1864 +					for (unsigned int c = 0; c < 3;++c)	{
176.1865 +						unsigned int iBone = groupData.aiBones[ oldFace.mIndices[c] ];
176.1866 +						if (UINT_MAX != iBone)	{
176.1867 +							if (iBone >= iNumOutBones)	{
176.1868 +								DefaultLogger::get()->error("Bone index overflow. "
176.1869 +									"The bone index of a vertex exceeds the allowed range. ");
176.1870 +								iBone = iNumOutBones-1;
176.1871 +							}
176.1872 +							aaiVWeightList[ iBone ].push_back ( iCurrent );
176.1873 +						}
176.1874 +						++iCurrent;
176.1875 +					}
176.1876 +				}
176.1877 +				// now check which bones are required ...
176.1878 +				for (std::vector<std::vector<unsigned int> >::const_iterator k =  aaiVWeightList.begin();k != aaiVWeightList.end();++k)	{
176.1879 +					if (!(*k).empty()) {
176.1880 +						++pcMesh->mNumBones;
176.1881 +					}
176.1882 +				}
176.1883 +				pcMesh->mBones = new aiBone*[pcMesh->mNumBones];
176.1884 +				iCurrent = 0;
176.1885 +				for (std::vector<std::vector<unsigned int> >::const_iterator k = aaiVWeightList.begin();k!= aaiVWeightList.end();++k,++iCurrent)
176.1886 +				{
176.1887 +					if ((*k).empty())
176.1888 +						continue;
176.1889 +
176.1890 +					// seems we'll need this node
176.1891 +					aiBone* pcBone = pcMesh->mBones[ iCurrent ] = new aiBone();
176.1892 +					pcBone->mName = aiString(shared.apcOutBones[ iCurrent ]->mName);
176.1893 +					pcBone->mOffsetMatrix = shared.apcOutBones[ iCurrent ]->mOffsetMatrix;
176.1894 +
176.1895 +					// setup vertex weights
176.1896 +					pcBone->mNumWeights = (unsigned int)(*k).size();
176.1897 +					pcBone->mWeights = new aiVertexWeight[pcBone->mNumWeights];
176.1898 +
176.1899 +					for (unsigned int weight = 0; weight < pcBone->mNumWeights;++weight)	{
176.1900 +						pcBone->mWeights[weight].mVertexId = (*k)[weight]; 
176.1901 +						pcBone->mWeights[weight].mWeight = 1.0f;
176.1902 +					}
176.1903 +				}
176.1904 +			}
176.1905 +			// add the mesh to the list of output meshes
176.1906 +			splitGroupData.avOutList.push_back(pcMesh);
176.1907 +		}
176.1908 +	}
176.1909 +}
176.1910 +
176.1911 +// ------------------------------------------------------------------------------------------------
176.1912 +// Join to materials
176.1913 +void MDLImporter::JoinSkins_3DGS_MDL7(
176.1914 +	aiMaterial* pcMat1,
176.1915 +	aiMaterial* pcMat2,
176.1916 +	aiMaterial* pcMatOut)
176.1917 +{
176.1918 +	ai_assert(NULL != pcMat1 && NULL != pcMat2 && NULL != pcMatOut);
176.1919 +
176.1920 +	// first create a full copy of the first skin property set
176.1921 +	// and assign it to the output material
176.1922 +	aiMaterial::CopyPropertyList(pcMatOut,pcMat1);
176.1923 +
176.1924 +	int iVal = 0;
176.1925 +	pcMatOut->AddProperty<int>(&iVal,1,AI_MATKEY_UVWSRC_DIFFUSE(0));
176.1926 +
176.1927 +	// then extract the diffuse texture from the second skin,
176.1928 +	// setup 1 as UV source and we have it
176.1929 +	aiString sString;
176.1930 +	if(AI_SUCCESS == aiGetMaterialString ( pcMat2, AI_MATKEY_TEXTURE_DIFFUSE(0),&sString ))	{
176.1931 +		iVal = 1;
176.1932 +		pcMatOut->AddProperty<int>(&iVal,1,AI_MATKEY_UVWSRC_DIFFUSE(1));
176.1933 +		pcMatOut->AddProperty(&sString,AI_MATKEY_TEXTURE_DIFFUSE(1));
176.1934 +	}
176.1935 +}
176.1936 +
176.1937 +// ------------------------------------------------------------------------------------------------
176.1938 +// Read a half-life 2 MDL
176.1939 +void MDLImporter::InternReadFile_HL2( )
176.1940 +{
176.1941 +	//const MDL::Header_HL2* pcHeader = (const MDL::Header_HL2*)this->mBuffer;
176.1942 +	throw DeadlyImportError("HL2 MDLs are not implemented");
176.1943 +}
176.1944 +
176.1945 +#endif // !! ASSIMP_BUILD_NO_MDL_IMPORTER
   177.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   177.2 +++ b/libs/assimp/MDLLoader.h	Sat Feb 01 19:58:19 2014 +0200
   177.3 @@ -0,0 +1,456 @@
   177.4 +/*
   177.5 +Open Asset Import Library (assimp)
   177.6 +----------------------------------------------------------------------
   177.7 +
   177.8 +Copyright (c) 2006-2012, assimp team
   177.9 +All rights reserved.
  177.10 +
  177.11 +Redistribution and use of this software in source and binary forms, 
  177.12 +with or without modification, are permitted provided that the 
  177.13 +following conditions are met:
  177.14 +
  177.15 +* Redistributions of source code must retain the above
  177.16 +  copyright notice, this list of conditions and the
  177.17 +  following disclaimer.
  177.18 +
  177.19 +* Redistributions in binary form must reproduce the above
  177.20 +  copyright notice, this list of conditions and the
  177.21 +  following disclaimer in the documentation and/or other
  177.22 +  materials provided with the distribution.
  177.23 +
  177.24 +* Neither the name of the assimp team, nor the names of its
  177.25 +  contributors may be used to endorse or promote products
  177.26 +  derived from this software without specific prior
  177.27 +  written permission of the assimp team.
  177.28 +
  177.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  177.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  177.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  177.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  177.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  177.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  177.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  177.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  177.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  177.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  177.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  177.40 +
  177.41 +----------------------------------------------------------------------
  177.42 +*/
  177.43 +
  177.44 +
  177.45 +/**  @file MDLLoader.h
  177.46 + *   @brief Declaration of the loader for MDL files
  177.47 + */
  177.48 +
  177.49 +#ifndef AI_MDLLOADER_H_INCLUDED
  177.50 +#define AI_MDLLOADER_H_INCLUDED
  177.51 +
  177.52 +#include "BaseImporter.h"
  177.53 +
  177.54 +struct aiNode;
  177.55 +#include "MDLFileData.h"
  177.56 +#include "HalfLifeFileData.h"
  177.57 +
  177.58 +namespace Assimp	{
  177.59 +
  177.60 +
  177.61 +using namespace MDL;
  177.62 +
  177.63 +// --------------------------------------------------------------------------------------
  177.64 +// Include file/line information in debug builds
  177.65 +#ifdef ASSIMP_BUILD_DEBUG
  177.66 +#	define VALIDATE_FILE_SIZE(msg) SizeCheck(msg,__FILE__,__LINE__)
  177.67 +#else
  177.68 +#	define VALIDATE_FILE_SIZE(msg) SizeCheck(msg)
  177.69 +#endif
  177.70 +
  177.71 +// --------------------------------------------------------------------------------------
  177.72 +/** @brief Class to load MDL files.
  177.73 + *
  177.74 + *  Several subformats exist:
  177.75 + *   <ul>
  177.76 + *      <li>Quake I</li>
  177.77 + *      <li>3D Game Studio MDL3, MDL4</li>
  177.78 + *      <li>3D Game Studio MDL5</li>
  177.79 + *      <li>3D Game Studio MDL7</li>
  177.80 + *      <li>Halflife 2</li>
  177.81 + *   </ul>
  177.82 + *  These formats are partially identical and it would be possible to load
  177.83 + *  them all with a single 1000-line function-beast. However, it has been
  177.84 + *  split into several code paths to make the code easier to read and maintain.
  177.85 +*/
  177.86 +class MDLImporter : public BaseImporter
  177.87 +{
  177.88 +public:
  177.89 +	MDLImporter();
  177.90 +	~MDLImporter();
  177.91 +
  177.92 +
  177.93 +public:
  177.94 +
  177.95 +	// -------------------------------------------------------------------
  177.96 +	/** Returns whether the class can handle the format of the given file. 
  177.97 +	* See BaseImporter::CanRead() for details.	*/
  177.98 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  177.99 +		bool checkSig) const;
 177.100 +
 177.101 +
 177.102 +	// -------------------------------------------------------------------
 177.103 +	/** Called prior to ReadFile().
 177.104 +	* The function is a request to the importer to update its configuration
 177.105 +	* basing on the Importer's configuration property list.
 177.106 +	*/
 177.107 +	void SetupProperties(const Importer* pImp);
 177.108 +
 177.109 +protected:
 177.110 +
 177.111 +
 177.112 +	// -------------------------------------------------------------------
 177.113 +	/** Return importer meta information.
 177.114 +	 * See #BaseImporter::GetInfo for the details
 177.115 +	 */
 177.116 +	const aiImporterDesc* GetInfo () const;
 177.117 +
 177.118 +	// -------------------------------------------------------------------
 177.119 +	/** Imports the given file into the given scene structure. 
 177.120 +	* See BaseImporter::InternReadFile() for details
 177.121 +	*/
 177.122 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
 177.123 +		IOSystem* pIOHandler);
 177.124 +
 177.125 +protected:
 177.126 +
 177.127 +	// -------------------------------------------------------------------
 177.128 +	/** Import a quake 1 MDL file (IDPO)
 177.129 +	*/
 177.130 +	void InternReadFile_Quake1( );
 177.131 +
 177.132 +	// -------------------------------------------------------------------
 177.133 +	/** Import a GameStudio A4/A5 file (MDL 3,4,5)
 177.134 +	*/
 177.135 +	void InternReadFile_3DGS_MDL345( );
 177.136 +
 177.137 +	// -------------------------------------------------------------------
 177.138 +	/** Import a GameStudio A7 file (MDL 7)
 177.139 +	*/
 177.140 +	void InternReadFile_3DGS_MDL7( );
 177.141 +
 177.142 +	// -------------------------------------------------------------------
 177.143 +	/** Import a CS:S/HL2 MDL file (not fully implemented)
 177.144 +	*/
 177.145 +	void InternReadFile_HL2( );
 177.146 +
 177.147 +	// -------------------------------------------------------------------
 177.148 +	/** Check whether a given position is inside the valid range
 177.149 +	 *  Throw a DeadlyImportError if it is not
 177.150 +	 * \param szPos Cursor position
 177.151 +	 * \param szFile Name of the source file from which the function was called
 177.152 +	 * \param iLine Source code line from which the function was called
 177.153 +	*/
 177.154 +	void SizeCheck(const void* szPos);
 177.155 +	void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine);
 177.156 +
 177.157 +
 177.158 +	// -------------------------------------------------------------------
 177.159 +	/** Validate the header data structure of a game studio MDL7 file
 177.160 +	 * \param pcHeader Input header to be validated
 177.161 +	 */
 177.162 +	void ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader);
 177.163 +
 177.164 +	// -------------------------------------------------------------------
 177.165 +	/** Validate the header data structure of a Quake 1 model
 177.166 +	 * \param pcHeader Input header to be validated
 177.167 +	 */
 177.168 +	void ValidateHeader_Quake1(const MDL::Header* pcHeader);
 177.169 +
 177.170 +
 177.171 +	// -------------------------------------------------------------------
 177.172 +	/** Try to load a  palette from the current directory (colormap.lmp)
 177.173 +	 *  If it is not found the default palette of Quake1 is returned
 177.174 +	 */
 177.175 +	void SearchPalette(const unsigned char** pszColorMap);
 177.176 +
 177.177 +	// -------------------------------------------------------------------
 177.178 +	/** Free a palette created with a previous call to SearchPalette()
 177.179 +	 */
 177.180 +	void FreePalette(const unsigned char* pszColorMap);
 177.181 +
 177.182 +
 177.183 +	// -------------------------------------------------------------------
 177.184 +	/** Load a paletized texture from the file and convert it to 32bpp
 177.185 +	*/
 177.186 +	void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData);
 177.187 +
 177.188 +	// -------------------------------------------------------------------
 177.189 +	/** Used to load textures from MDL3/4
 177.190 +	 * \param szData Input data
 177.191 +	 * \param iType Color data type
 177.192 +	 * \param piSkip Receive: Size to skip, in bytes
 177.193 +	*/
 177.194 +	void CreateTexture_3DGS_MDL4(const unsigned char* szData, 
 177.195 +		unsigned int iType,
 177.196 +		unsigned int* piSkip);
 177.197 +
 177.198 +
 177.199 +	// -------------------------------------------------------------------
 177.200 +	/** Used to load textures from MDL5
 177.201 +	 * \param szData Input data
 177.202 +	 * \param iType Color data type
 177.203 +	 * \param piSkip Receive: Size to skip, in bytes
 177.204 +	*/
 177.205 +	void CreateTexture_3DGS_MDL5(const unsigned char* szData, 
 177.206 +		unsigned int iType,
 177.207 +		unsigned int* piSkip);
 177.208 +
 177.209 +
 177.210 +	// -------------------------------------------------------------------
 177.211 +	/** Checks whether a texture can be replaced with a single color
 177.212 +	 * This is useful for all file formats before MDL7 (all those
 177.213 +	 * that are not containing material colors separate from textures).
 177.214 +	 * MED seems to write dummy 8x8 monochrome images instead.
 177.215 +	 * \param pcTexture Input texture
 177.216 +	 * \return aiColor.r is set to qnan if the function fails and no
 177.217 +	 *   color can be found.
 177.218 +	*/
 177.219 +	aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
 177.220 +
 177.221 +
 177.222 +	// -------------------------------------------------------------------
 177.223 +	/** Converts the absolute texture coordinates in MDL5 files to
 177.224 +	 *  relative in a range between 0 and 1
 177.225 +	*/
 177.226 +	void CalculateUVCoordinates_MDL5();
 177.227 +
 177.228 +
 177.229 +	// -------------------------------------------------------------------
 177.230 +	/** Read an UV coordinate from the file. If the file format is not
 177.231 +	 * MDL5, the function calculates relative texture coordinates
 177.232 +	 * \param vOut Receives the output UV coord
 177.233 +	 * \param pcSrc UV coordinate buffer
 177.234 +	 * \param UV coordinate index
 177.235 +	*/
 177.236 +	void ImportUVCoordinate_3DGS_MDL345( aiVector3D& vOut,
 177.237 +		const MDL::TexCoord_MDL3* pcSrc, 
 177.238 +		unsigned int iIndex);
 177.239 +
 177.240 +	// -------------------------------------------------------------------
 177.241 +	/** Setup the material properties for Quake and MDL<7 models.
 177.242 +	 * These formats don't support more than one material per mesh,
 177.243 +	 * therefore the method processes only ONE skin and removes
 177.244 +	 * all others.
 177.245 +	 */
 177.246 +	void SetupMaterialProperties_3DGS_MDL5_Quake1( );
 177.247 +
 177.248 +
 177.249 +	// -------------------------------------------------------------------
 177.250 +	/** Parse a skin lump in a MDL7/HMP7 file with all of its features
 177.251 +	 *  variant 1: Current cursor position is the beginning of the skin header 
 177.252 +	 * \param szCurrent Current data pointer
 177.253 +	 * \param szCurrentOut Output data pointer
 177.254 +	 * \param pcMats Material list for this group. To be filled ...
 177.255 +	 */
 177.256 +	void ParseSkinLump_3DGS_MDL7(
 177.257 +		const unsigned char* szCurrent,
 177.258 +		const unsigned char** szCurrentOut,
 177.259 +		std::vector<aiMaterial*>& pcMats);
 177.260 +
 177.261 +	// -------------------------------------------------------------------
 177.262 +	/** Parse a skin lump in a MDL7/HMP7 file with all of its features
 177.263 +	 *  variant 2: Current cursor position is the beginning of the skin data
 177.264 +	 * \param szCurrent Current data pointer
 177.265 +	 * \param szCurrentOut Output data pointer
 177.266 +	 * \param pcMatOut Output material
 177.267 +	 * \param iType header.typ
 177.268 +	 * \param iWidth header.width
 177.269 +	 * \param iHeight header.height
 177.270 +	 */
 177.271 +	void ParseSkinLump_3DGS_MDL7(
 177.272 +		const unsigned char* szCurrent,
 177.273 +		const unsigned char** szCurrentOut,
 177.274 +		aiMaterial* pcMatOut,
 177.275 +		unsigned int iType,
 177.276 +		unsigned int iWidth,
 177.277 +		unsigned int iHeight);
 177.278 +
 177.279 +	// -------------------------------------------------------------------
 177.280 +	/** Skip a skin lump in a MDL7/HMP7 file 
 177.281 +	 * \param szCurrent Current data pointer
 177.282 +	 * \param szCurrentOut Output data pointer. Points to the byte just
 177.283 +	 * behind the last byte of the skin.
 177.284 +	 * \param iType header.typ
 177.285 +	 * \param iWidth header.width
 177.286 +	 * \param iHeight header.height
 177.287 +	 */
 177.288 +	void SkipSkinLump_3DGS_MDL7(const unsigned char* szCurrent,
 177.289 +		const unsigned char** szCurrentOut,
 177.290 +		unsigned int iType,
 177.291 +		unsigned int iWidth,
 177.292 +		unsigned int iHeight);
 177.293 +
 177.294 +	// -------------------------------------------------------------------
 177.295 +	/** Parse texture color data for MDL5, MDL6 and MDL7 formats
 177.296 +	 * \param szData Current data pointer
 177.297 +	 * \param iType type of the texture data. No DDS or external
 177.298 +	 * \param piSkip Receive the number of bytes to skip
 177.299 +	 * \param pcNew Must point to fully initialized data. Width and 
 177.300 +	 *        height must be set. If pcNew->pcData is set to UINT_MAX,
 177.301 +	 *        piSkip will receive the size of the texture, in bytes, but no
 177.302 +	 *        color data will be read.
 177.303 +	 */
 177.304 +	void ParseTextureColorData(const unsigned char* szData, 
 177.305 +		unsigned int iType,
 177.306 +		unsigned int* piSkip,
 177.307 +		aiTexture* pcNew);
 177.308 +
 177.309 +	// -------------------------------------------------------------------
 177.310 +	/** Join two materials / skins. Setup UV source ... etc
 177.311 +	 * \param pcMat1 First input material
 177.312 +	 * \param pcMat2 Second input material
 177.313 +	 * \param pcMatOut Output material instance to be filled. Must be empty
 177.314 +	 */
 177.315 +	void JoinSkins_3DGS_MDL7(aiMaterial* pcMat1,
 177.316 +		aiMaterial* pcMat2,
 177.317 +		aiMaterial* pcMatOut);
 177.318 +
 177.319 +	// -------------------------------------------------------------------
 177.320 +	/** Add a bone transformation key to an animation
 177.321 +	 * \param iTrafo Index of the transformation (always==frame index?)
 177.322 +	 * No need to validate this index, it is always valid.
 177.323 +	 * \param pcBoneTransforms Bone transformation for this index
 177.324 +	 * \param apcOutBones Output bones array
 177.325 +	 */
 177.326 +	void AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
 177.327 +		const MDL::BoneTransform_MDL7* pcBoneTransforms,
 177.328 +		MDL::IntBone_MDL7** apcBonesOut);
 177.329 +
 177.330 +	// -------------------------------------------------------------------
 177.331 +	/** Load the bone list of a MDL7 file
 177.332 +	 * \return If the bones could be loaded successfully, a valid
 177.333 +	 *   array containing pointers to a temporary bone
 177.334 +	 *   representation. NULL if the bones could not be loaded.
 177.335 +	 */
 177.336 +	MDL::IntBone_MDL7** LoadBones_3DGS_MDL7();
 177.337 +
 177.338 +	// -------------------------------------------------------------------
 177.339 +	/** Load bone transformation keyframes from a file chunk
 177.340 +	 * \param groupInfo -> doc of data structure
 177.341 +	 * \param frame -> doc of data structure
 177.342 +	 * \param shared -> doc of data structure
 177.343 +	 */
 177.344 +	void ParseBoneTrafoKeys_3DGS_MDL7(
 177.345 +		const MDL::IntGroupInfo_MDL7& groupInfo,
 177.346 +		IntFrameInfo_MDL7& frame,
 177.347 +		MDL::IntSharedData_MDL7& shared);
 177.348 +
 177.349 +	// -------------------------------------------------------------------
 177.350 +	/** Calculate absolute bone animation matrices for each bone
 177.351 +	 * \param apcOutBones Output bones array
 177.352 +	 */
 177.353 +	void CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones);
 177.354 +
 177.355 +	// -------------------------------------------------------------------
 177.356 +	/** Add all bones to the nodegraph (as children of the root node)
 177.357 +	 * \param apcBonesOut List of bones
 177.358 +	 * \param pcParent Parent node. New nodes will be added to this node
 177.359 +	 * \param iParentIndex Index of the parent bone
 177.360 +	 */
 177.361 +	void AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut,
 177.362 +		aiNode* pcParent,uint16_t iParentIndex);
 177.363 +
 177.364 +	// -------------------------------------------------------------------
 177.365 +	/** Build output animations
 177.366 +	 * \param apcBonesOut List of bones
 177.367 +	 */
 177.368 +	void BuildOutputAnims_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut);
 177.369 +
 177.370 +	// -------------------------------------------------------------------
 177.371 +	/** Handles materials that are just referencing another material
 177.372 +	 * There is no test file for this feature, but Conitec's doc
 177.373 +	 * say it is used.
 177.374 +	 */
 177.375 +	void HandleMaterialReferences_3DGS_MDL7();
 177.376 +
 177.377 +	// -------------------------------------------------------------------
 177.378 +	/** Copies only the material that are referenced by at least one
 177.379 +	 * mesh to the final output material list. All other materials
 177.380 +	 * will be discarded.
 177.381 +	 * \param shared -> doc of data structure
 177.382 +	 */
 177.383 +	void CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared);
 177.384 +
 177.385 +	// -------------------------------------------------------------------
 177.386 +	/** Process the frame section at the end of a group
 177.387 +	 * \param groupInfo -> doc of data structure
 177.388 +	 * \param shared -> doc of data structure
 177.389 +	 * \param szCurrent Pointer to the start of the frame section
 177.390 +	 * \param szCurrentOut Receives a pointer to the first byte of the
 177.391 +	 *   next data section.
 177.392 +	 * \return false to read no further groups (a small workaround for
 177.393 +	 *   some tiny and unsolved problems ... )
 177.394 +	 */
 177.395 +	bool ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
 177.396 +		MDL::IntGroupData_MDL7& groupData,
 177.397 +		MDL::IntSharedData_MDL7& shared,
 177.398 +		const unsigned char* szCurrent,
 177.399 +		const unsigned char** szCurrentOut);
 177.400 +
 177.401 +	// -------------------------------------------------------------------
 177.402 +	/** Sort all faces by their materials. If the mesh is using
 177.403 +	 * multiple materials per face (that are blended together) the function
 177.404 +	 * might create new materials.
 177.405 +	 * \param groupInfo -> doc of data structure
 177.406 +	 * \param groupData -> doc of data structure
 177.407 +	 * \param splitGroupData -> doc of data structure
 177.408 +	 */
 177.409 +	void SortByMaterials_3DGS_MDL7(
 177.410 +		const MDL::IntGroupInfo_MDL7& groupInfo,
 177.411 +		MDL::IntGroupData_MDL7& groupData,
 177.412 +		MDL::IntSplitGroupData_MDL7& splitGroupData);
 177.413 +	
 177.414 +	// -------------------------------------------------------------------
 177.415 +	/** Read all faces and vertices from a MDL7 group. The function fills
 177.416 +	 *  preallocated memory buffers.
 177.417 +	 * \param groupInfo -> doc of data structure
 177.418 +	 * \param groupData -> doc of data structure
 177.419 +	 */
 177.420 +	void ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
 177.421 +		MDL::IntGroupData_MDL7& groupData);
 177.422 +
 177.423 +	// -------------------------------------------------------------------
 177.424 +	/** Generate the final output meshes for a7 models
 177.425 +	 * \param groupData -> doc of data structure
 177.426 +	 * \param splitGroupData -> doc of data structure
 177.427 +	 */
 177.428 +	void GenerateOutputMeshes_3DGS_MDL7(
 177.429 +		MDL::IntGroupData_MDL7& groupData,
 177.430 +		MDL::IntSplitGroupData_MDL7& splitGroupData);
 177.431 +
 177.432 +protected:
 177.433 +
 177.434 +	/** Configuration option: frame to be loaded */
 177.435 +	unsigned int configFrameID;
 177.436 +
 177.437 +	/** Configuration option: palette to be used to decode palletized images*/
 177.438 +	std::string configPalette;
 177.439 +
 177.440 +	/** Buffer to hold the loaded file */
 177.441 +	unsigned char* mBuffer;
 177.442 +    
 177.443 +	/** For GameStudio MDL files: The number in the magic word, either 3,4 or 5 
 177.444 +	 * (MDL7 doesn't need this, the format has a separate loader) */
 177.445 +	unsigned int iGSFileVersion;
 177.446 +
 177.447 +	/** Output I/O handler. used to load external lmp files */
 177.448 +	IOSystem* pIOHandler;
 177.449 +
 177.450 +	/** Output scene to be filled */
 177.451 +	aiScene* pScene;
 177.452 +
 177.453 +	/** Size of the input file in bytes */
 177.454 +	unsigned int iFileSize;
 177.455 +};
 177.456 +
 177.457 +} // end of namespace Assimp
 177.458 +
 177.459 +#endif // AI_3DSIMPORTER_H_INC
   178.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   178.2 +++ b/libs/assimp/MDLMaterialLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   178.3 @@ -0,0 +1,827 @@
   178.4 +/*
   178.5 +---------------------------------------------------------------------------
   178.6 +Open Asset Import Library (assimp)
   178.7 +---------------------------------------------------------------------------
   178.8 +
   178.9 +Copyright (c) 2006-2012, assimp team
  178.10 +
  178.11 +All rights reserved.
  178.12 +
  178.13 +Redistribution and use of this software in source and binary forms, 
  178.14 +with or without modification, are permitted provided that the following 
  178.15 +conditions are met:
  178.16 +
  178.17 +* Redistributions of source code must retain the above
  178.18 +  copyright notice, this list of conditions and the
  178.19 +  following disclaimer.
  178.20 +
  178.21 +* Redistributions in binary form must reproduce the above
  178.22 +  copyright notice, this list of conditions and the
  178.23 +  following disclaimer in the documentation and/or other
  178.24 +  materials provided with the distribution.
  178.25 +
  178.26 +* Neither the name of the assimp team, nor the names of its
  178.27 +  contributors may be used to endorse or promote products
  178.28 +  derived from this software without specific prior
  178.29 +  written permission of the assimp team.
  178.30 +
  178.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  178.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  178.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  178.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  178.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  178.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  178.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  178.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  178.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  178.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  178.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  178.42 +---------------------------------------------------------------------------
  178.43 +*/
  178.44 +
  178.45 +/** @file Implementation of the material part of the MDL importer class */
  178.46 +
  178.47 +#include "AssimpPCH.h"
  178.48 +#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
  178.49 +
  178.50 +// internal headers
  178.51 +#include "MDLLoader.h"
  178.52 +#include "MDLDefaultColorMap.h"
  178.53 +
  178.54 +using namespace Assimp;
  178.55 +static aiTexel* const bad_texel = reinterpret_cast<aiTexel*>(SIZE_MAX);
  178.56 +
  178.57 +// ------------------------------------------------------------------------------------------------
  178.58 +// Find a suitable pallette file or take teh default one
  178.59 +void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
  178.60 +{
  178.61 +	// now try to find the color map in the current directory
  178.62 +	IOStream* pcStream = pIOHandler->Open(configPalette,"rb");
  178.63 +
  178.64 +	const unsigned char* szColorMap = (const unsigned char*)::g_aclrDefaultColorMap;
  178.65 +	if(pcStream)
  178.66 +	{
  178.67 +		if (pcStream->FileSize() >= 768)
  178.68 +		{
  178.69 +			unsigned char* colorMap = new unsigned char[256*3];
  178.70 +			szColorMap = colorMap;
  178.71 +			pcStream->Read(colorMap,256*3,1);
  178.72 +			DefaultLogger::get()->info("Found valid colormap.lmp in directory. "
  178.73 +				"It will be used to decode embedded textures in palletized formats.");
  178.74 +		}
  178.75 +		delete pcStream;
  178.76 +		pcStream = NULL;
  178.77 +	}
  178.78 +	*pszColorMap = szColorMap;
  178.79 +}
  178.80 +
  178.81 +// ------------------------------------------------------------------------------------------------
  178.82 +// Free the palette again
  178.83 +void MDLImporter::FreePalette(const unsigned char* szColorMap)
  178.84 +{
  178.85 +	if (szColorMap != (const unsigned char*)::g_aclrDefaultColorMap)
  178.86 +		delete[] szColorMap;
  178.87 +}
  178.88 +
  178.89 +// ------------------------------------------------------------------------------------------------
  178.90 +// Check whether we can replace a texture with a single color
  178.91 +aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
  178.92 +{
  178.93 +	ai_assert(NULL != pcTexture);
  178.94 +
  178.95 +	aiColor4D clrOut;
  178.96 +	clrOut.r = get_qnan();
  178.97 +	if (!pcTexture->mHeight || !pcTexture->mWidth)
  178.98 +		return clrOut;
  178.99 +
 178.100 +	const unsigned int iNumPixels = pcTexture->mHeight*pcTexture->mWidth;
 178.101 +	const aiTexel* pcTexel = pcTexture->pcData+1;
 178.102 +	const aiTexel* const pcTexelEnd = &pcTexture->pcData[iNumPixels];
 178.103 +
 178.104 +	while (pcTexel != pcTexelEnd)
 178.105 +	{
 178.106 +		if (*pcTexel != *(pcTexel-1))
 178.107 +		{
 178.108 +			pcTexel = NULL;
 178.109 +			break;
 178.110 +		}
 178.111 +		++pcTexel;
 178.112 +	}
 178.113 +	if (pcTexel)
 178.114 +	{
 178.115 +		clrOut.r = pcTexture->pcData->r / 255.0f;
 178.116 +		clrOut.g = pcTexture->pcData->g / 255.0f;
 178.117 +		clrOut.b = pcTexture->pcData->b / 255.0f;
 178.118 +		clrOut.a = pcTexture->pcData->a / 255.0f;
 178.119 +	}
 178.120 +	return clrOut;
 178.121 +}
 178.122 +
 178.123 +// ------------------------------------------------------------------------------------------------
 178.124 +// Read a texture from a MDL3 file
 178.125 +void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
 178.126 +{
 178.127 +	const MDL::Header *pcHeader = (const MDL::Header*)mBuffer;  //the endianess is allready corrected in the InternReadFile_3DGS_MDL345 function
 178.128 +
 178.129 +	VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
 178.130 +		pcHeader->skinheight);
 178.131 +
 178.132 +	// allocate a new texture object
 178.133 +	aiTexture* pcNew = new aiTexture();
 178.134 +	pcNew->mWidth = pcHeader->skinwidth;
 178.135 +	pcNew->mHeight = pcHeader->skinheight;
 178.136 +
 178.137 +	pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
 178.138 +
 178.139 +	const unsigned char* szColorMap;
 178.140 +	this->SearchPalette(&szColorMap);
 178.141 +
 178.142 +	// copy texture data
 178.143 +	for (unsigned int i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
 178.144 +	{
 178.145 +		const unsigned char val = szData[i];
 178.146 +		const unsigned char* sz = &szColorMap[val*3];
 178.147 +
 178.148 +		pcNew->pcData[i].a = 0xFF;
 178.149 +		pcNew->pcData[i].r = *sz++;
 178.150 +		pcNew->pcData[i].g = *sz++;
 178.151 +		pcNew->pcData[i].b = *sz;
 178.152 +	}
 178.153 +
 178.154 +	FreePalette(szColorMap);
 178.155 +
 178.156 +	// store the texture
 178.157 +	aiTexture** pc = this->pScene->mTextures;
 178.158 +	this->pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
 178.159 +	for (unsigned int i = 0; i <pScene->mNumTextures;++i)
 178.160 +		pScene->mTextures[i] = pc[i];
 178.161 +
 178.162 +	pScene->mTextures[this->pScene->mNumTextures] = pcNew;
 178.163 +	pScene->mNumTextures++;
 178.164 +	delete[] pc;
 178.165 +	return;
 178.166 +}
 178.167 +
 178.168 +// ------------------------------------------------------------------------------------------------
 178.169 +// Read a texture from a MDL4 file
 178.170 +void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData, 
 178.171 +	unsigned int iType,
 178.172 +	 unsigned int* piSkip)
 178.173 +{
 178.174 +	ai_assert(NULL != piSkip);
 178.175 +
 178.176 +	const MDL::Header *pcHeader = (const MDL::Header*)mBuffer;  //the endianess is allready corrected in the InternReadFile_3DGS_MDL345 function
 178.177 +
 178.178 +	if (iType == 1 || iType > 3)
 178.179 +	{
 178.180 +		DefaultLogger::get()->error("Unsupported texture file format");
 178.181 +		return;
 178.182 +	}
 178.183 +
 178.184 +	const bool bNoRead = *piSkip == UINT_MAX;
 178.185 +
 178.186 +	// allocate a new texture object
 178.187 +	aiTexture* pcNew = new aiTexture();
 178.188 +	pcNew->mWidth = pcHeader->skinwidth;
 178.189 +	pcNew->mHeight = pcHeader->skinheight;
 178.190 +
 178.191 +	if (bNoRead)pcNew->pcData = bad_texel;
 178.192 +	ParseTextureColorData(szData,iType,piSkip,pcNew);
 178.193 +
 178.194 +	// store the texture
 178.195 +	if (!bNoRead)
 178.196 +	{
 178.197 +		if (!this->pScene->mNumTextures)
 178.198 +		{
 178.199 +			pScene->mNumTextures = 1;
 178.200 +			pScene->mTextures = new aiTexture*[1];
 178.201 +			pScene->mTextures[0] = pcNew;
 178.202 +		}
 178.203 +		else
 178.204 +		{
 178.205 +			aiTexture** pc = pScene->mTextures;
 178.206 +			pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
 178.207 +			for (unsigned int i = 0; i < this->pScene->mNumTextures;++i)
 178.208 +				pScene->mTextures[i] = pc[i];
 178.209 +			pScene->mTextures[pScene->mNumTextures] = pcNew;
 178.210 +			pScene->mNumTextures++;
 178.211 +			delete[] pc;
 178.212 +		}
 178.213 +	}
 178.214 +	else {
 178.215 +		pcNew->pcData = NULL;
 178.216 +		delete pcNew;
 178.217 +	}
 178.218 +	return;
 178.219 +}
 178.220 +
 178.221 +// ------------------------------------------------------------------------------------------------
 178.222 +// Load color data of a texture and convert it to our output format
 178.223 +void MDLImporter::ParseTextureColorData(const unsigned char* szData, 
 178.224 +	unsigned int iType,
 178.225 +	unsigned int* piSkip,
 178.226 +	aiTexture* pcNew)
 178.227 +{
 178.228 +	const bool do_read = bad_texel != pcNew->pcData;
 178.229 +
 178.230 +	// allocate storage for the texture image
 178.231 +	if (do_read) {
 178.232 +		pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
 178.233 +	}
 178.234 +
 178.235 +	// R5G6B5 format (with or without MIPs)
 178.236 +	// ****************************************************************
 178.237 +	if (2 == iType || 10 == iType)
 178.238 +	{
 178.239 +		VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*2);
 178.240 +
 178.241 +		// copy texture data
 178.242 +		unsigned int i;
 178.243 +		if (do_read) 
 178.244 +		{
 178.245 +			for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
 178.246 +			{
 178.247 +				MDL::RGB565 val = ((MDL::RGB565*)szData)[i];
 178.248 +				AI_SWAP2(val);    
 178.249 +
 178.250 +				pcNew->pcData[i].a = 0xFF;
 178.251 +				pcNew->pcData[i].r = (unsigned char)val.b << 3;
 178.252 +				pcNew->pcData[i].g = (unsigned char)val.g << 2;
 178.253 +				pcNew->pcData[i].b = (unsigned char)val.r << 3;
 178.254 +			}
 178.255 +		} 
 178.256 +		else i = pcNew->mWidth*pcNew->mHeight;
 178.257 +		*piSkip = i * 2;
 178.258 +
 178.259 +		// apply MIP maps
 178.260 +		if (10 == iType)
 178.261 +		{
 178.262 +			*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
 178.263 +			VALIDATE_FILE_SIZE(szData + *piSkip);
 178.264 +		}
 178.265 +	}
 178.266 +	// ARGB4 format (with or without MIPs)
 178.267 +	// ****************************************************************
 178.268 +	else if (3 == iType || 11 == iType)
 178.269 +	{
 178.270 +		VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);
 178.271 +
 178.272 +		// copy texture data
 178.273 +		unsigned int i;
 178.274 +		if (do_read) 
 178.275 +		{
 178.276 +			for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
 178.277 +			{
 178.278 +				MDL::ARGB4 val = ((MDL::ARGB4*)szData)[i];
 178.279 +				AI_SWAP2(val);    
 178.280 +
 178.281 +				pcNew->pcData[i].a = (unsigned char)val.a << 4;
 178.282 +				pcNew->pcData[i].r = (unsigned char)val.r << 4;
 178.283 +				pcNew->pcData[i].g = (unsigned char)val.g << 4;
 178.284 +				pcNew->pcData[i].b = (unsigned char)val.b << 4;
 178.285 +			}
 178.286 +		}
 178.287 +		else i = pcNew->mWidth*pcNew->mHeight;
 178.288 +		*piSkip = i * 2;
 178.289 +
 178.290 +		// apply MIP maps
 178.291 +		if (11 == iType)
 178.292 +		{
 178.293 +			*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
 178.294 +			VALIDATE_FILE_SIZE(szData + *piSkip);
 178.295 +		}
 178.296 +	}
 178.297 +	// RGB8 format (with or without MIPs)
 178.298 +	// ****************************************************************
 178.299 +	else if (4 == iType || 12 == iType)
 178.300 +	{
 178.301 +		VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*3);
 178.302 +
 178.303 +		// copy texture data
 178.304 +		unsigned int i;
 178.305 +		if (do_read)
 178.306 +		{
 178.307 +			for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
 178.308 +			{
 178.309 +				const unsigned char* _szData = &szData[i*3];
 178.310 +
 178.311 +				pcNew->pcData[i].a = 0xFF;
 178.312 +				pcNew->pcData[i].b = *_szData++;
 178.313 +				pcNew->pcData[i].g = *_szData++;
 178.314 +				pcNew->pcData[i].r = *_szData;
 178.315 +			}
 178.316 +		} 
 178.317 +		else i = pcNew->mWidth*pcNew->mHeight;
 178.318 +
 178.319 +
 178.320 +		// apply MIP maps
 178.321 +		*piSkip = i * 3;
 178.322 +		if (12 == iType)
 178.323 +		{
 178.324 +			*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) *3;
 178.325 +			VALIDATE_FILE_SIZE(szData + *piSkip);
 178.326 +		}
 178.327 +	}
 178.328 +	// ARGB8 format (with ir without MIPs)
 178.329 +	// ****************************************************************
 178.330 +	else if (5 == iType || 13 == iType)
 178.331 +	{
 178.332 +		VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);
 178.333 +
 178.334 +		// copy texture data
 178.335 +		unsigned int i;
 178.336 +		if (do_read)
 178.337 +		{
 178.338 +			for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
 178.339 +			{
 178.340 +				const unsigned char* _szData = &szData[i*4];
 178.341 +
 178.342 +				pcNew->pcData[i].b = *_szData++;
 178.343 +				pcNew->pcData[i].g = *_szData++;
 178.344 +				pcNew->pcData[i].r = *_szData++;
 178.345 +				pcNew->pcData[i].a = *_szData;
 178.346 +			}
 178.347 +		} 
 178.348 +		else i = pcNew->mWidth*pcNew->mHeight;
 178.349 +
 178.350 +		// apply MIP maps
 178.351 +		*piSkip = i << 2;
 178.352 +		if (13 == iType)
 178.353 +		{
 178.354 +			*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2;
 178.355 +		}
 178.356 +	}
 178.357 +	// palletized 8 bit texture. As for Quake 1
 178.358 +	// ****************************************************************
 178.359 +	else if (0 == iType)
 178.360 +	{
 178.361 +		VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight);
 178.362 +
 178.363 +		// copy texture data
 178.364 +		unsigned int i;
 178.365 +		if (do_read) 
 178.366 +		{
 178.367 +
 178.368 +			const unsigned char* szColorMap;
 178.369 +			SearchPalette(&szColorMap);
 178.370 +
 178.371 +			for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
 178.372 +			{
 178.373 +				const unsigned char val = szData[i];
 178.374 +				const unsigned char* sz = &szColorMap[val*3];
 178.375 +
 178.376 +				pcNew->pcData[i].a = 0xFF;
 178.377 +				pcNew->pcData[i].r = *sz++;
 178.378 +				pcNew->pcData[i].g = *sz++;
 178.379 +				pcNew->pcData[i].b = *sz;
 178.380 +			}
 178.381 +			this->FreePalette(szColorMap);
 178.382 +
 178.383 +		} 
 178.384 +		else i = pcNew->mWidth*pcNew->mHeight;
 178.385 +		*piSkip = i;
 178.386 +
 178.387 +		// FIXME: Also support for MIP maps?
 178.388 +	}
 178.389 +}
 178.390 +
 178.391 +// ------------------------------------------------------------------------------------------------
 178.392 +// Get a texture from a MDL5 file
 178.393 +void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData, 
 178.394 +	unsigned int iType,
 178.395 +	unsigned int* piSkip)
 178.396 +{
 178.397 +	ai_assert(NULL != piSkip);
 178.398 +	bool bNoRead = *piSkip == UINT_MAX;
 178.399 +
 178.400 +	// allocate a new texture object
 178.401 +	aiTexture* pcNew = new aiTexture();
 178.402 +
 178.403 +	VALIDATE_FILE_SIZE(szData+8);
 178.404 +
 178.405 +	// first read the size of the texture
 178.406 +	pcNew->mWidth = *((uint32_t*)szData);
 178.407 +	AI_SWAP4(pcNew->mWidth); 
 178.408 +	szData += sizeof(uint32_t);
 178.409 +
 178.410 +	pcNew->mHeight = *((uint32_t*)szData);
 178.411 +	AI_SWAP4(pcNew->mHeight); 
 178.412 +	szData += sizeof(uint32_t);
 178.413 +
 178.414 +	if (bNoRead) {
 178.415 +		pcNew->pcData = bad_texel;
 178.416 +	}
 178.417 +
 178.418 +	// this should not occur - at least the docs say it shouldn't.
 178.419 +	// however, one can easily try out what MED does if you have
 178.420 +	// a model with a DDS texture and export it to MDL5 ...
 178.421 +	// yeah, it embedds the DDS file.
 178.422 +	if (6 == iType)
 178.423 +	{
 178.424 +		// this is a compressed texture in DDS format
 178.425 +		*piSkip = pcNew->mWidth;
 178.426 +		VALIDATE_FILE_SIZE(szData + *piSkip);
 178.427 +
 178.428 +		if (!bNoRead)
 178.429 +		{
 178.430 +			// place a hint and let the application know that this is a DDS file
 178.431 +			pcNew->mHeight = 0;
 178.432 +			pcNew->achFormatHint[0] = 'd';
 178.433 +			pcNew->achFormatHint[1] = 'd';
 178.434 +			pcNew->achFormatHint[2] = 's';
 178.435 +			pcNew->achFormatHint[3] = '\0';
 178.436 +
 178.437 +			pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
 178.438 +			::memcpy(pcNew->pcData,szData,pcNew->mWidth);
 178.439 +		}
 178.440 +	}
 178.441 +	else
 178.442 +	{
 178.443 +		// parse the color data of the texture
 178.444 +		ParseTextureColorData(szData,iType,piSkip,pcNew);
 178.445 +	}
 178.446 +	*piSkip += sizeof(uint32_t) * 2;
 178.447 +
 178.448 +	if (!bNoRead)
 178.449 +	{
 178.450 +		// store the texture
 178.451 +		if (!this->pScene->mNumTextures)
 178.452 +		{
 178.453 +			pScene->mNumTextures = 1;
 178.454 +			pScene->mTextures = new aiTexture*[1];
 178.455 +			pScene->mTextures[0] = pcNew;
 178.456 +		}
 178.457 +		else
 178.458 +		{
 178.459 +			aiTexture** pc = pScene->mTextures;
 178.460 +			pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
 178.461 +			for (unsigned int i = 0; i < pScene->mNumTextures;++i)
 178.462 +				this->pScene->mTextures[i] = pc[i];
 178.463 +
 178.464 +			pScene->mTextures[pScene->mNumTextures] = pcNew;
 178.465 +			pScene->mNumTextures++;
 178.466 +			delete[] pc;
 178.467 +		}
 178.468 +	}
 178.469 +	else {
 178.470 +		pcNew->pcData = NULL;
 178.471 +		delete pcNew;
 178.472 +	}
 178.473 +	return;
 178.474 +}
 178.475 +
 178.476 +// ------------------------------------------------------------------------------------------------
 178.477 +// Get a skin from a MDL7 file - more complex than all other subformats
 178.478 +void MDLImporter::ParseSkinLump_3DGS_MDL7(
 178.479 +	const unsigned char* szCurrent,
 178.480 +	const unsigned char** szCurrentOut,
 178.481 +	aiMaterial* pcMatOut,
 178.482 +	unsigned int iType,
 178.483 +	unsigned int iWidth,
 178.484 +	unsigned int iHeight)
 178.485 +{
 178.486 +	aiTexture* pcNew = NULL;
 178.487 +
 178.488 +	// get the type of the skin
 178.489 +	unsigned int iMasked = (unsigned int)(iType & 0xF);
 178.490 +
 178.491 +	if (0x1 ==  iMasked)
 178.492 +	{
 178.493 +		// ***** REFERENCE TO ANOTHER SKIN INDEX *****
 178.494 +		int referrer = (int)iWidth;
 178.495 +		pcMatOut->AddProperty<int>(&referrer,1,AI_MDL7_REFERRER_MATERIAL);
 178.496 +	}
 178.497 +	else if (0x6 == iMasked)
 178.498 +	{
 178.499 +		// ***** EMBEDDED DDS FILE *****
 178.500 +		if (1 != iHeight)
 178.501 +		{
 178.502 +			DefaultLogger::get()->warn("Found a reference to an embedded DDS texture, "
 178.503 +				"but texture height is not equal to 1, which is not supported by MED");
 178.504 +		}
 178.505 +
 178.506 +		pcNew = new aiTexture();
 178.507 +		pcNew->mHeight = 0;
 178.508 +		pcNew->mWidth = iWidth;
 178.509 +
 178.510 +		// place a proper format hint
 178.511 +		pcNew->achFormatHint[0] = 'd';
 178.512 +		pcNew->achFormatHint[1] = 'd';
 178.513 +		pcNew->achFormatHint[2] = 's';
 178.514 +		pcNew->achFormatHint[3] = '\0';
 178.515 +
 178.516 +		pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
 178.517 +		memcpy(pcNew->pcData,szCurrent,pcNew->mWidth);
 178.518 +		szCurrent += iWidth;
 178.519 +	}
 178.520 +	if (0x7 == iMasked)
 178.521 +	{
 178.522 +		// ***** REFERENCE TO EXTERNAL FILE *****
 178.523 +		if (1 != iHeight)
 178.524 +		{
 178.525 +			DefaultLogger::get()->warn("Found a reference to an external texture, "
 178.526 +				"but texture height is not equal to 1, which is not supported by MED");
 178.527 +		}
 178.528 +
 178.529 +		aiString szFile;
 178.530 +		const size_t iLen = strlen((const char*)szCurrent);
 178.531 +		size_t iLen2 = iLen+1;
 178.532 +		iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
 178.533 +		memcpy(szFile.data,(const char*)szCurrent,iLen2);
 178.534 +		szFile.length = iLen;
 178.535 +
 178.536 +		szCurrent += iLen2;
 178.537 +
 178.538 +		// place this as diffuse texture
 178.539 +		pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
 178.540 +	}
 178.541 +	else if (iMasked || !iType || (iType && iWidth && iHeight))
 178.542 +	{
 178.543 +		// ***** STANDARD COLOR TEXTURE *****
 178.544 +		pcNew = new aiTexture();
 178.545 +		if (!iHeight || !iWidth)
 178.546 +		{
 178.547 +			DefaultLogger::get()->warn("Found embedded texture, but its width "
 178.548 +				"an height are both 0. Is this a joke?");
 178.549 +
 178.550 +			// generate an empty chess pattern
 178.551 +			pcNew->mWidth = pcNew->mHeight = 8;
 178.552 +			pcNew->pcData = new aiTexel[64];
 178.553 +			for (unsigned int x = 0; x < 8;++x)
 178.554 +			{
 178.555 +				for (unsigned int y = 0; y < 8;++y)
 178.556 +				{
 178.557 +					const bool bSet = ((0 == x % 2 && 0 != y % 2) ||
 178.558 +						(0 != x % 2 && 0 == y % 2));
 178.559 +				
 178.560 +					aiTexel* pc = &pcNew->pcData[y * 8 + x];
 178.561 +					pc->r = pc->b = pc->g = (bSet?0xFF:0);
 178.562 +					pc->a = 0xFF;
 178.563 +				}
 178.564 +			}
 178.565 +		}
 178.566 +		else
 178.567 +		{
 178.568 +			// it is a standard color texture. Fill in width and height
 178.569 +			// and call the same function we used for loading MDL5 files
 178.570 +
 178.571 +			pcNew->mWidth = iWidth;
 178.572 +			pcNew->mHeight = iHeight;
 178.573 +
 178.574 +			unsigned int iSkip = 0;
 178.575 +			ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew);
 178.576 +
 178.577 +			// skip length of texture data
 178.578 +			szCurrent += iSkip;
 178.579 +		}
 178.580 +	}
 178.581 +
 178.582 +	// sometimes there are MDL7 files which have a monochrome
 178.583 +	// texture instead of material colors ... posssible they have
 178.584 +	// been converted to MDL7 from other formats, such as MDL5
 178.585 +	aiColor4D clrTexture;
 178.586 +	if (pcNew)clrTexture = ReplaceTextureWithColor(pcNew);
 178.587 +	else clrTexture.r = get_qnan();
 178.588 +	
 178.589 +	// check whether a material definition is contained in the skin
 178.590 +	if (iType & AI_MDL7_SKINTYPE_MATERIAL)
 178.591 +	{
 178.592 +		BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent;
 178.593 +		szCurrent = (unsigned char*)(pcMatIn+1);
 178.594 +		VALIDATE_FILE_SIZE(szCurrent);
 178.595 +
 178.596 +		aiColor3D clrTemp;
 178.597 +
 178.598 +#define COLOR_MULTIPLY_RGB() \
 178.599 +	if (is_not_qnan(clrTexture.r)) \
 178.600 +		{ \
 178.601 +		clrTemp.r *= clrTexture.r; \
 178.602 +		clrTemp.g *= clrTexture.g; \
 178.603 +		clrTemp.b *= clrTexture.b; \
 178.604 +		}
 178.605 +
 178.606 +		// read diffuse color
 178.607 +		clrTemp.r = pcMatIn->Diffuse.r;
 178.608 +		AI_SWAP4(clrTemp.r);  
 178.609 +		clrTemp.g = pcMatIn->Diffuse.g;
 178.610 +		AI_SWAP4(clrTemp.g);  
 178.611 +		clrTemp.b = pcMatIn->Diffuse.b;
 178.612 +		AI_SWAP4(clrTemp.b);  
 178.613 +		COLOR_MULTIPLY_RGB();
 178.614 +		pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_DIFFUSE);
 178.615 +
 178.616 +		// read specular color
 178.617 +		clrTemp.r = pcMatIn->Specular.r;
 178.618 +		AI_SWAP4(clrTemp.r);  
 178.619 +		clrTemp.g = pcMatIn->Specular.g;
 178.620 +		AI_SWAP4(clrTemp.g);  
 178.621 +		clrTemp.b = pcMatIn->Specular.b;
 178.622 +		AI_SWAP4(clrTemp.b);  
 178.623 +		COLOR_MULTIPLY_RGB();
 178.624 +		pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_SPECULAR);
 178.625 +
 178.626 +		// read ambient color
 178.627 +		clrTemp.r = pcMatIn->Ambient.r;
 178.628 +		AI_SWAP4(clrTemp.r);  
 178.629 +		clrTemp.g = pcMatIn->Ambient.g;
 178.630 +		AI_SWAP4(clrTemp.g);  
 178.631 +		clrTemp.b = pcMatIn->Ambient.b;
 178.632 +		AI_SWAP4(clrTemp.b);  
 178.633 +		COLOR_MULTIPLY_RGB();
 178.634 +		pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_AMBIENT);
 178.635 +
 178.636 +		// read emissive color
 178.637 +		clrTemp.r = pcMatIn->Emissive.r;
 178.638 +		AI_SWAP4(clrTemp.r);  
 178.639 +		clrTemp.g = pcMatIn->Emissive.g;
 178.640 +		AI_SWAP4(clrTemp.g);  
 178.641 +		clrTemp.b = pcMatIn->Emissive.b;
 178.642 +		AI_SWAP4(clrTemp.b);  
 178.643 +		pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_EMISSIVE);
 178.644 +
 178.645 +#undef COLOR_MULITPLY_RGB
 178.646 +
 178.647 +		// FIX: Take the opacity from the ambient color.
 178.648 +		// The doc say something else, but it is fact that MED exports the
 178.649 +		// opacity like this .... oh well.
 178.650 +		clrTemp.r = pcMatIn->Ambient.a;
 178.651 +		AI_SWAP4(clrTemp.r);  
 178.652 +		if (is_not_qnan(clrTexture.r)) {
 178.653 +			clrTemp.r *= clrTexture.a;
 178.654 +		}
 178.655 +		pcMatOut->AddProperty<float>(&clrTemp.r,1,AI_MATKEY_OPACITY);
 178.656 +
 178.657 +		// read phong power
 178.658 +		int iShadingMode = (int)aiShadingMode_Gouraud;
 178.659 +		AI_SWAP4(pcMatIn->Power);  
 178.660 +		if (0.0f != pcMatIn->Power)
 178.661 +		{
 178.662 +			iShadingMode = (int)aiShadingMode_Phong;
 178.663 +			pcMatOut->AddProperty<float>(&pcMatIn->Power,1,AI_MATKEY_SHININESS);
 178.664 +		}
 178.665 +		pcMatOut->AddProperty<int>(&iShadingMode,1,AI_MATKEY_SHADING_MODEL);
 178.666 +	}
 178.667 +	else if (is_not_qnan(clrTexture.r))
 178.668 +	{
 178.669 +		pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_DIFFUSE);
 178.670 +		pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_SPECULAR);
 178.671 +	}
 178.672 +	// if the texture could be replaced by a single material color
 178.673 +	// we don't need the texture anymore
 178.674 +	if (is_not_qnan(clrTexture.r))
 178.675 +	{
 178.676 +		delete pcNew;
 178.677 +		pcNew = NULL;
 178.678 +	}
 178.679 +
 178.680 +	// If an ASCII effect description (HLSL?) is contained in the file,
 178.681 +	// we can simply ignore it ...
 178.682 +	if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
 178.683 +	{
 178.684 +		VALIDATE_FILE_SIZE(szCurrent);
 178.685 +		int32_t iMe = *((int32_t*)szCurrent);
 178.686 +		AI_SWAP4(iMe);  
 178.687 +		szCurrent += sizeof(char) * iMe + sizeof(int32_t);
 178.688 +		VALIDATE_FILE_SIZE(szCurrent);
 178.689 +	}
 178.690 +
 178.691 +	// If an embedded texture has been loaded setup the corresponding
 178.692 +	// data structures in the aiScene instance
 178.693 +	if (pcNew && pScene->mNumTextures <= 999)
 178.694 +	{
 178.695 +
 178.696 +		// place this as diffuse texture
 178.697 +		char szCurrent[5];
 178.698 +		::sprintf(szCurrent,"*%i",this->pScene->mNumTextures);
 178.699 +
 178.700 +		aiString szFile;
 178.701 +		const size_t iLen = strlen((const char*)szCurrent);
 178.702 +		::memcpy(szFile.data,(const char*)szCurrent,iLen+1);
 178.703 +		szFile.length = iLen;
 178.704 +
 178.705 +		pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
 178.706 +
 178.707 +		// store the texture
 178.708 +		if (!pScene->mNumTextures)
 178.709 +		{
 178.710 +			pScene->mNumTextures = 1;
 178.711 +			pScene->mTextures = new aiTexture*[1];
 178.712 +			pScene->mTextures[0] = pcNew;
 178.713 +		}
 178.714 +		else
 178.715 +		{
 178.716 +			aiTexture** pc = pScene->mTextures;
 178.717 +			pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
 178.718 +			for (unsigned int i = 0; i < pScene->mNumTextures;++i) {
 178.719 +				pScene->mTextures[i] = pc[i];
 178.720 +			}
 178.721 +
 178.722 +			pScene->mTextures[pScene->mNumTextures] = pcNew;
 178.723 +			pScene->mNumTextures++;
 178.724 +			delete[] pc;
 178.725 +		}
 178.726 +	}
 178.727 +	VALIDATE_FILE_SIZE(szCurrent);
 178.728 +	*szCurrentOut = szCurrent;
 178.729 +}
 178.730 +
 178.731 +// ------------------------------------------------------------------------------------------------
 178.732 +// Skip a skin lump
 178.733 +void MDLImporter::SkipSkinLump_3DGS_MDL7(
 178.734 +	const unsigned char* szCurrent,
 178.735 +	const unsigned char** szCurrentOut,
 178.736 +	unsigned int iType,
 178.737 +	unsigned int iWidth,
 178.738 +	unsigned int iHeight)
 178.739 +{
 178.740 +	// get the type of the skin
 178.741 +	const unsigned int iMasked = (unsigned int)(iType & 0xF);
 178.742 +
 178.743 +	if (0x6 == iMasked)
 178.744 +	{
 178.745 +		szCurrent += iWidth;
 178.746 +	}
 178.747 +	if (0x7 == iMasked)
 178.748 +	{
 178.749 +		const size_t iLen = ::strlen((const char*)szCurrent);
 178.750 +		szCurrent += iLen+1;
 178.751 +	}
 178.752 +	else if (iMasked || !iType)
 178.753 +	{
 178.754 +		if (iMasked || !iType || (iType && iWidth && iHeight))
 178.755 +		{
 178.756 +			// ParseTextureColorData(..., aiTexture::pcData == bad_texel) will simply
 178.757 +			// return the size of the color data in bytes in iSkip
 178.758 +			unsigned int iSkip = 0;
 178.759 +
 178.760 +			aiTexture tex;
 178.761 +			tex.pcData = bad_texel;
 178.762 +			tex.mHeight = iHeight;
 178.763 +			tex.mWidth = iWidth;
 178.764 +			ParseTextureColorData(szCurrent,iMasked,&iSkip,&tex);
 178.765 +
 178.766 +			// FIX: Important, otherwise the destructor will crash
 178.767 +			tex.pcData = NULL;
 178.768 +
 178.769 +			// skip length of texture data
 178.770 +			szCurrent += iSkip;
 178.771 +		}
 178.772 +	}
 178.773 +
 178.774 +	// check whether a material definition is contained in the skin
 178.775 +	if (iType & AI_MDL7_SKINTYPE_MATERIAL)
 178.776 +	{
 178.777 +		BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent;
 178.778 +		szCurrent = (unsigned char*)(pcMatIn+1);
 178.779 +	}
 178.780 +
 178.781 +	// if an ASCII effect description (HLSL?) is contained in the file,
 178.782 +	// we can simply ignore it ...
 178.783 +	if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
 178.784 +	{
 178.785 +		int32_t iMe = *((int32_t*)szCurrent);
 178.786 +		AI_SWAP4(iMe);  
 178.787 +		szCurrent += sizeof(char) * iMe + sizeof(int32_t);
 178.788 +	}
 178.789 +	*szCurrentOut = szCurrent;
 178.790 +}
 178.791 +
 178.792 +// ------------------------------------------------------------------------------------------------
 178.793 +void MDLImporter::ParseSkinLump_3DGS_MDL7(
 178.794 +	const unsigned char* szCurrent,
 178.795 +	const unsigned char** szCurrentOut,
 178.796 +	std::vector<aiMaterial*>& pcMats)
 178.797 +{
 178.798 +	ai_assert(NULL != szCurrent);
 178.799 +	ai_assert(NULL != szCurrentOut);
 178.800 +
 178.801 +	*szCurrentOut = szCurrent;
 178.802 +	BE_NCONST MDL::Skin_MDL7* pcSkin = (BE_NCONST MDL::Skin_MDL7*)szCurrent;
 178.803 +	AI_SWAP4(pcSkin->width);
 178.804 +	AI_SWAP4(pcSkin->height); 
 178.805 +	szCurrent += 12;
 178.806 +
 178.807 +	// allocate an output material
 178.808 +	aiMaterial* pcMatOut = new aiMaterial();
 178.809 +	pcMats.push_back(pcMatOut);
 178.810 +
 178.811 +	// skip length of file name
 178.812 +	szCurrent += AI_MDL7_MAX_TEXNAMESIZE;
 178.813 +
 178.814 +	ParseSkinLump_3DGS_MDL7(szCurrent,szCurrentOut,pcMatOut,
 178.815 +		pcSkin->typ,pcSkin->width,pcSkin->height);
 178.816 +
 178.817 +	// place the name of the skin in the material
 178.818 +	if (pcSkin->texture_name[0])
 178.819 +	{
 178.820 +		// the 0 termination could be there or not - we can't know
 178.821 +		aiString szFile;
 178.822 +		::memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name));
 178.823 +		szFile.data[sizeof(pcSkin->texture_name)] = '\0';
 178.824 +		szFile.length = ::strlen(szFile.data);
 178.825 +
 178.826 +		pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME);
 178.827 +	}
 178.828 +}
 178.829 +
 178.830 +#endif // !! ASSIMP_BUILD_NO_MDL_IMPORTER
   179.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   179.2 +++ b/libs/assimp/MS3DLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   179.3 @@ -0,0 +1,663 @@
   179.4 +/*
   179.5 +---------------------------------------------------------------------------
   179.6 +Open Asset Import Library (assimp)
   179.7 +---------------------------------------------------------------------------
   179.8 +
   179.9 +Copyright (c) 2006-2012, assimp team
  179.10 +
  179.11 +All rights reserved.
  179.12 +
  179.13 +Redistribution and use of this software in source and binary forms, 
  179.14 +with or without modification, are permitted provided that the following 
  179.15 +conditions are met:
  179.16 +
  179.17 +* Redistributions of source code must retain the above
  179.18 +  copyright notice, this list of conditions and the
  179.19 +  following disclaimer.
  179.20 +
  179.21 +* Redistributions in binary form must reproduce the above
  179.22 +  copyright notice, this list of conditions and the
  179.23 +  following disclaimer in the documentation and/or other
  179.24 +  materials provided with the distribution.
  179.25 +
  179.26 +* Neither the name of the assimp team, nor the names of its
  179.27 +  contributors may be used to endorse or promote products
  179.28 +  derived from this software without specific prior
  179.29 +  written permission of the assimp team.
  179.30 +
  179.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  179.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  179.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  179.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  179.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  179.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  179.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  179.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  179.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  179.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  179.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  179.42 +---------------------------------------------------------------------------
  179.43 +*/
  179.44 +
  179.45 +/** @file  MS3DLoader.cpp
  179.46 + *  @brief Implementation of the Ms3D importer class.
  179.47 + *  Written against http://chumbalum.swissquake.ch/ms3d/ms3dspec.txt
  179.48 + */
  179.49 +
  179.50 +#include "AssimpPCH.h"
  179.51 +#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
  179.52 +
  179.53 +// internal headers
  179.54 +#include "MS3DLoader.h"
  179.55 +#include "StreamReader.h"
  179.56 +using namespace Assimp;
  179.57 +
  179.58 +static const aiImporterDesc desc = {
  179.59 +	"Milkshape 3D Importer",
  179.60 +	"",
  179.61 +	"",
  179.62 +	"http://chumbalum.swissquake.ch/",
  179.63 +	aiImporterFlags_SupportBinaryFlavour,
  179.64 +	0,
  179.65 +	0,
  179.66 +	0,
  179.67 +	0,
  179.68 +	"ms3d" 
  179.69 +};
  179.70 +
  179.71 +// ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH
  179.72 +//   (enable old code path, which generates extra nodes per mesh while
  179.73 +//    the newer code uses aiMesh::mName to express the name of the
  179.74 +//    meshes (a.k.a. groups in MS3D))
  179.75 +
  179.76 +// ------------------------------------------------------------------------------------------------
  179.77 +// Constructor to be privately used by Importer
  179.78 +MS3DImporter::MS3DImporter()
  179.79 +{}
  179.80 +
  179.81 +// ------------------------------------------------------------------------------------------------
  179.82 +// Destructor, private as well 
  179.83 +MS3DImporter::~MS3DImporter()
  179.84 +{}
  179.85 +
  179.86 +// ------------------------------------------------------------------------------------------------
  179.87 +// Returns whether the class can handle the format of the given file. 
  179.88 +bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  179.89 +{
  179.90 +	// first call - simple extension check
  179.91 +	const std::string extension = GetExtension(pFile);
  179.92 +	if (extension == "ms3d") {
  179.93 +		return true;
  179.94 +	}
  179.95 +
  179.96 +	// second call - check for magic identifiers
  179.97 +	else if (!extension.length() || checkSig)	{
  179.98 +		if (!pIOHandler) {
  179.99 +			return true;
 179.100 +		}
 179.101 +		const char* tokens[] = {"MS3D000000"};
 179.102 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
 179.103 +	}
 179.104 +	return false;
 179.105 +}
 179.106 +
 179.107 +// ------------------------------------------------------------------------------------------------
 179.108 +const aiImporterDesc* MS3DImporter::GetInfo () const
 179.109 +{
 179.110 +	return &desc;
 179.111 +}
 179.112 +
 179.113 +// ------------------------------------------------------------------------------------------------
 179.114 +void ReadColor(StreamReaderLE& stream, aiColor4D& ambient)
 179.115 +{
 179.116 +	// aiColor4D is packed on gcc, implicit binding to float& fails therefore.
 179.117 +	stream >> (float&)ambient.r >> (float&)ambient.g >> (float&)ambient.b >> (float&)ambient.a;
 179.118 +}
 179.119 +
 179.120 +// ------------------------------------------------------------------------------------------------
 179.121 +void ReadVector(StreamReaderLE& stream, aiVector3D& pos)
 179.122 +{
 179.123 +	// See note in ReadColor()
 179.124 +	stream >> (float&)pos.x >> (float&)pos.y >> (float&)pos.z;
 179.125 +}
 179.126 +
 179.127 +// ------------------------------------------------------------------------------------------------
 179.128 +template<typename T> 
 179.129 +void MS3DImporter :: ReadComments(StreamReaderLE& stream, std::vector<T>& outp)
 179.130 +{
 179.131 +	uint16_t cnt;
 179.132 +	stream >> cnt;
 179.133 +
 179.134 +	for(unsigned int i = 0; i < cnt; ++i) {
 179.135 +		uint32_t index, clength;
 179.136 +		stream >> index >> clength;
 179.137 +
 179.138 +		if(index >= outp.size()) {
 179.139 +			DefaultLogger::get()->warn("MS3D: Invalid index in comment section");
 179.140 +		}
 179.141 +		else if (clength > stream.GetRemainingSize()) {
 179.142 +			throw DeadlyImportError("MS3D: Failure reading comment, length field is out of range");
 179.143 +		}
 179.144 +		else {
 179.145 +			outp[index].comment = std::string(reinterpret_cast<char*>(stream.GetPtr()),clength);
 179.146 +		}
 179.147 +		stream.IncPtr(clength);
 179.148 +	}
 179.149 +}
 179.150 +
 179.151 +// ------------------------------------------------------------------------------------------------
 179.152 +template <typename T, typename T2, typename T3> bool inrange(const T& in, const T2& lower, const T3& higher)
 179.153 +{
 179.154 +	return in > lower && in <= higher;
 179.155 +}
 179.156 +
 179.157 +// ------------------------------------------------------------------------------------------------
 179.158 +void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints,
 179.159 +	std::vector<bool>& hadit, 
 179.160 +	aiNode* nd, 
 179.161 +	const aiMatrix4x4& absTrafo)
 179.162 +{
 179.163 +	unsigned int cnt = 0;
 179.164 +	for(size_t i = 0; i < joints.size(); ++i) {
 179.165 +		if (!hadit[i] && !strcmp(joints[i].parentName,nd->mName.data)) {
 179.166 +			++cnt;
 179.167 +		}
 179.168 +	}
 179.169 +
 179.170 +	nd->mChildren = new aiNode*[nd->mNumChildren = cnt];
 179.171 +	cnt = 0;
 179.172 +	for(size_t i = 0; i < joints.size(); ++i) {
 179.173 +		if (!hadit[i] && !strcmp(joints[i].parentName,nd->mName.data)) {
 179.174 +			aiNode* ch = nd->mChildren[cnt++] = new aiNode(joints[i].name);
 179.175 +			ch->mParent = nd;
 179.176 +
 179.177 +			ch->mTransformation = aiMatrix4x4::Translation(joints[i].position,aiMatrix4x4()=aiMatrix4x4())*
 179.178 +				// XXX actually, I don't *know* why we need the inverse here. Probably column vs. row order?
 179.179 +				aiMatrix4x4().FromEulerAnglesXYZ(joints[i].rotation).Transpose();
 179.180 +
 179.181 +			const aiMatrix4x4 abs = absTrafo*ch->mTransformation;
 179.182 +			for(unsigned int a = 0; a < mScene->mNumMeshes; ++a) {
 179.183 +				aiMesh* const msh = mScene->mMeshes[a];
 179.184 +				for(unsigned int n = 0; n < msh->mNumBones; ++n) {
 179.185 +					aiBone* const bone = msh->mBones[n];
 179.186 +
 179.187 +					if(bone->mName == ch->mName) {
 179.188 +						bone->mOffsetMatrix = aiMatrix4x4(abs).Inverse();
 179.189 +					}
 179.190 +				}
 179.191 +			}
 179.192 +	
 179.193 +			hadit[i] = true;
 179.194 +			CollectChildJoints(joints,hadit,ch,abs);
 179.195 +		}
 179.196 +	}
 179.197 +}
 179.198 +
 179.199 +// ------------------------------------------------------------------------------------------------
 179.200 +void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints, aiNode* nd)
 179.201 +{
 179.202 +	 std::vector<bool> hadit(joints.size(),false);
 179.203 +	 aiMatrix4x4 trafo;
 179.204 +
 179.205 +	 CollectChildJoints(joints,hadit,nd,trafo);
 179.206 +}
 179.207 +
 179.208 +// ------------------------------------------------------------------------------------------------
 179.209 +// Imports the given file into the given scene structure. 
 179.210 +void MS3DImporter::InternReadFile( const std::string& pFile, 
 179.211 +	aiScene* pScene, IOSystem* pIOHandler)
 179.212 +{
 179.213 +	StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
 179.214 +
 179.215 +	// CanRead() should have done this already
 179.216 +	char head[10];
 179.217 +	int32_t version;
 179.218 +
 179.219 +	mScene = pScene;
 179.220 +
 179.221 +
 179.222 +	// 1 ------------ read into temporary data structures mirroring the original file
 179.223 +
 179.224 +	stream.CopyAndAdvance(head,10);
 179.225 +	stream >> version;
 179.226 +	if (strncmp(head,"MS3D000000",10)) {
 179.227 +		throw DeadlyImportError("Not a MS3D file, magic string MS3D000000 not found: "+pFile);
 179.228 +	}
 179.229 +
 179.230 +	if (version != 4) {
 179.231 +		throw DeadlyImportError("MS3D: Unsupported file format version, 4 was expected");
 179.232 +	}
 179.233 +
 179.234 +	uint16_t verts;
 179.235 +	stream >> verts;
 179.236 +
 179.237 +	std::vector<TempVertex> vertices(verts);
 179.238 +	for (unsigned int i = 0; i < verts; ++i) {
 179.239 +		TempVertex& v = vertices[i];
 179.240 +
 179.241 +		stream.IncPtr(1);
 179.242 +		ReadVector(stream,v.pos);
 179.243 +		v.bone_id[0] = stream.GetI1(); 
 179.244 +		v.ref_cnt = stream.GetI1();
 179.245 +
 179.246 +		v.bone_id[1] = v.bone_id[2] = v.bone_id[3] = UINT_MAX;
 179.247 +		v.weights[1] = v.weights[2] = v.weights[3] = 0.f;
 179.248 +		v.weights[0] = 1.f;
 179.249 +	}
 179.250 +
 179.251 +	uint16_t tris;
 179.252 +	stream >> tris;
 179.253 +
 179.254 +	std::vector<TempTriangle> triangles(tris);
 179.255 +	for (unsigned int i = 0;i < tris; ++i) {
 179.256 +		TempTriangle& t = triangles[i];
 179.257 +
 179.258 +		stream.IncPtr(2);
 179.259 +		for (unsigned int i = 0; i < 3; ++i) {
 179.260 +			t.indices[i] = stream.GetI2();
 179.261 +		}
 179.262 +
 179.263 +		for (unsigned int i = 0; i < 3; ++i) {
 179.264 +			ReadVector(stream,t.normals[i]);
 179.265 +		}
 179.266 +
 179.267 +		for (unsigned int i = 0; i < 3; ++i) {
 179.268 +			stream >> (float&)(t.uv[i].x); // see note in ReadColor()
 179.269 +		}
 179.270 +		for (unsigned int i = 0; i < 3; ++i) {
 179.271 +			stream >> (float&)(t.uv[i].y);
 179.272 +		}
 179.273 +
 179.274 +		t.sg    = stream.GetI1(); 
 179.275 +		t.group = stream.GetI1(); 
 179.276 +	}
 179.277 +
 179.278 +	uint16_t grp;
 179.279 +	stream >> grp;
 179.280 +
 179.281 +	bool need_default = false;
 179.282 +	std::vector<TempGroup> groups(grp);
 179.283 +	for (unsigned int i = 0;i < grp; ++i) {
 179.284 +		TempGroup& t = groups[i];
 179.285 +
 179.286 +		stream.IncPtr(1);
 179.287 +		stream.CopyAndAdvance(t.name,32);
 179.288 +
 179.289 +		t.name[32] = '\0';
 179.290 +		uint16_t num;
 179.291 +		stream >> num;
 179.292 +
 179.293 +		t.triangles.resize(num);
 179.294 +		for (unsigned int i = 0; i < num; ++i) {
 179.295 +			t.triangles[i] = stream.GetI2(); 
 179.296 +		}
 179.297 +		t.mat = stream.GetI1(); 
 179.298 +		if (t.mat == UINT_MAX) {
 179.299 +			need_default = true;
 179.300 +		}
 179.301 +	}
 179.302 +
 179.303 +	uint16_t mat;
 179.304 +	stream >> mat;
 179.305 +
 179.306 +	std::vector<TempMaterial> materials(mat);
 179.307 +	for (unsigned int i = 0;i < mat; ++i) {
 179.308 +		TempMaterial& t = materials[i];
 179.309 +
 179.310 +		stream.CopyAndAdvance(t.name,32);
 179.311 +		t.name[32] = '\0';
 179.312 +
 179.313 +		ReadColor(stream,t.ambient);
 179.314 +		ReadColor(stream,t.diffuse);
 179.315 +		ReadColor(stream,t.specular);
 179.316 +		ReadColor(stream,t.emissive);
 179.317 +		stream >> t.shininess  >> t.transparency;
 179.318 +
 179.319 +		stream.IncPtr(1);
 179.320 +
 179.321 +		stream.CopyAndAdvance(t.texture,128);
 179.322 +		t.texture[128] = '\0';
 179.323 +
 179.324 +		stream.CopyAndAdvance(t.alphamap,128);
 179.325 +		t.alphamap[128] = '\0';
 179.326 +	}
 179.327 +
 179.328 +	float animfps, currenttime;
 179.329 +	uint32_t totalframes;
 179.330 +	stream >> animfps >> currenttime >> totalframes;
 179.331 +
 179.332 +	uint16_t joint;
 179.333 +	stream >> joint;
 179.334 +
 179.335 +	std::vector<TempJoint> joints(joint);
 179.336 +	for(unsigned int i = 0; i < joint; ++i) {
 179.337 +		TempJoint& j = joints[i];
 179.338 +
 179.339 +		stream.IncPtr(1);
 179.340 +		stream.CopyAndAdvance(j.name,32);
 179.341 +		j.name[32] = '\0';
 179.342 +
 179.343 +		stream.CopyAndAdvance(j.parentName,32);
 179.344 +		j.parentName[32] = '\0';
 179.345 +
 179.346 +	//	DefaultLogger::get()->debug(j.name);
 179.347 +	//	DefaultLogger::get()->debug(j.parentName);
 179.348 +
 179.349 +		ReadVector(stream,j.rotation);
 179.350 +		ReadVector(stream,j.position);
 179.351 +
 179.352 +		j.rotFrames.resize(stream.GetI2());
 179.353 +		j.posFrames.resize(stream.GetI2());
 179.354 +
 179.355 +		for(unsigned int a = 0; a < j.rotFrames.size(); ++a) {
 179.356 +			TempKeyFrame& kf = j.rotFrames[a];
 179.357 +			stream >> kf.time;
 179.358 +			ReadVector(stream,kf.value);
 179.359 +		}
 179.360 +		for(unsigned int a = 0; a < j.posFrames.size(); ++a) {
 179.361 +			TempKeyFrame& kf = j.posFrames[a];
 179.362 +			stream >> kf.time;
 179.363 +			ReadVector(stream,kf.value);
 179.364 +		}
 179.365 +	}
 179.366 +
 179.367 +	if(stream.GetRemainingSize() > 4) {
 179.368 +		uint32_t subversion;
 179.369 +		stream >> subversion;
 179.370 +		if (subversion == 1) {
 179.371 +			ReadComments<TempGroup>(stream,groups);
 179.372 +			ReadComments<TempMaterial>(stream,materials);
 179.373 +			ReadComments<TempJoint>(stream,joints);
 179.374 +			
 179.375 +			// model comment - print it for we have such a nice log.
 179.376 +			if (stream.GetI4()) {
 179.377 +				const size_t len = static_cast<size_t>(stream.GetI4());
 179.378 +				if (len > stream.GetRemainingSize()) {
 179.379 +					throw DeadlyImportError("MS3D: Model comment is too long");
 179.380 +				}
 179.381 +
 179.382 +				const std::string& s = std::string(reinterpret_cast<char*>(stream.GetPtr()),len);
 179.383 +				DefaultLogger::get()->debug("MS3D: Model comment: " + s);
 179.384 +			}
 179.385 +
 179.386 +			if(stream.GetRemainingSize() > 4 && inrange((stream >> subversion,subversion),1u,3u)) {
 179.387 +				for(unsigned int i = 0; i < verts; ++i) {
 179.388 +					TempVertex& v = vertices[i];
 179.389 +					v.weights[3]=1.f;
 179.390 +					for(unsigned int n = 0; n < 3; v.weights[3]-=v.weights[n++]) {
 179.391 +						v.bone_id[n+1] = stream.GetI1();
 179.392 +						v.weights[n] = static_cast<float>(static_cast<unsigned int>(stream.GetI1()))/255.f;
 179.393 +					}
 179.394 +					stream.IncPtr((subversion-1)<<2u);
 179.395 +				}
 179.396 +
 179.397 +				// even further extra data is not of interest for us, at least now now.
 179.398 +			}
 179.399 +		}
 179.400 +	}
 179.401 +
 179.402 +	// 2 ------------ convert to proper aiXX data structures -----------------------------------
 179.403 +
 179.404 +	if (need_default && materials.size()) {
 179.405 +		DefaultLogger::get()->warn("MS3D: Found group with no material assigned, spawning default material");
 179.406 +		// if one of the groups has no material assigned, but there are other 
 179.407 +		// groups with materials, a default material needs to be added (
 179.408 +		// scenepreprocessor adds a default material only if nummat==0).
 179.409 +		materials.push_back(TempMaterial());
 179.410 +		TempMaterial& m = materials.back();
 179.411 +
 179.412 +		strcpy(m.name,"<MS3D_DefaultMat>");
 179.413 +		m.diffuse = aiColor4D(0.6f,0.6f,0.6f,1.0);
 179.414 +		m.transparency = 1.f;
 179.415 +		m.shininess = 0.f;
 179.416 +
 179.417 +		// this is because these TempXXX struct's have no c'tors.
 179.418 +		m.texture[0] = m.alphamap[0] = '\0';
 179.419 +
 179.420 +		for (unsigned int i = 0; i < groups.size(); ++i) {
 179.421 +			TempGroup& g = groups[i];
 179.422 +			if (g.mat == UINT_MAX) {
 179.423 +				g.mat = materials.size()-1;
 179.424 +			}
 179.425 +		}
 179.426 +	}
 179.427 +
 179.428 +	// convert materials to our generic key-value dict-alike
 179.429 +	if (materials.size()) {
 179.430 +		pScene->mMaterials = new aiMaterial*[materials.size()];
 179.431 +		for (size_t i = 0; i < materials.size(); ++i) {
 179.432 +
 179.433 +			aiMaterial* mo = new aiMaterial();
 179.434 +			pScene->mMaterials[pScene->mNumMaterials++] = mo;
 179.435 +
 179.436 +			const TempMaterial& mi = materials[i];
 179.437 +
 179.438 +			aiString tmp;
 179.439 +			if (0[mi.alphamap]) {
 179.440 +				tmp = aiString(mi.alphamap);
 179.441 +				mo->AddProperty(&tmp,AI_MATKEY_TEXTURE_OPACITY(0));
 179.442 +			}
 179.443 +			if (0[mi.texture]) {
 179.444 +				tmp = aiString(mi.texture);
 179.445 +				mo->AddProperty(&tmp,AI_MATKEY_TEXTURE_DIFFUSE(0));
 179.446 +			}
 179.447 +			if (0[mi.name]) {
 179.448 +				tmp = aiString(mi.name);
 179.449 +				mo->AddProperty(&tmp,AI_MATKEY_NAME);
 179.450 +			}
 179.451 +
 179.452 +			mo->AddProperty(&mi.ambient,1,AI_MATKEY_COLOR_AMBIENT);
 179.453 +			mo->AddProperty(&mi.diffuse,1,AI_MATKEY_COLOR_DIFFUSE);
 179.454 +			mo->AddProperty(&mi.specular,1,AI_MATKEY_COLOR_SPECULAR);
 179.455 +			mo->AddProperty(&mi.emissive,1,AI_MATKEY_COLOR_EMISSIVE);
 179.456 +
 179.457 +			mo->AddProperty(&mi.shininess,1,AI_MATKEY_SHININESS);
 179.458 +			mo->AddProperty(&mi.transparency,1,AI_MATKEY_OPACITY);
 179.459 +
 179.460 +			const int sm = mi.shininess>0.f?aiShadingMode_Phong:aiShadingMode_Gouraud;
 179.461 +			mo->AddProperty(&sm,1,AI_MATKEY_SHADING_MODEL);
 179.462 +		}
 179.463 +	}
 179.464 +
 179.465 +	// convert groups to meshes
 179.466 +	if (groups.empty()) {
 179.467 +		throw DeadlyImportError("MS3D: Didn't get any group records, file is malformed");
 179.468 +	}
 179.469 +
 179.470 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes=static_cast<unsigned int>(groups.size())]();
 179.471 +	for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
 179.472 +	
 179.473 +		aiMesh* m = pScene->mMeshes[i] = new aiMesh();
 179.474 +		const TempGroup& g = groups[i];
 179.475 +
 179.476 +		if (pScene->mNumMaterials && g.mat > pScene->mNumMaterials) {
 179.477 +			throw DeadlyImportError("MS3D: Encountered invalid material index, file is malformed");
 179.478 +		} // no error if no materials at all - scenepreprocessor adds one then
 179.479 +
 179.480 +		m->mMaterialIndex  = g.mat;
 179.481 +		m->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; 
 179.482 +
 179.483 +		m->mFaces = new aiFace[m->mNumFaces = g.triangles.size()];
 179.484 +		m->mNumVertices = m->mNumFaces*3;
 179.485 +
 179.486 +		// storage for vertices - verbose format, as requested by the postprocessing pipeline
 179.487 +		m->mVertices = new aiVector3D[m->mNumVertices];
 179.488 +		m->mNormals  = new aiVector3D[m->mNumVertices];
 179.489 +		m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];
 179.490 +		m->mNumUVComponents[0] = 2;
 179.491 +
 179.492 +		typedef std::map<unsigned int,unsigned int> BoneSet;
 179.493 +		BoneSet mybones;
 179.494 +
 179.495 +		for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) {
 179.496 +			aiFace& f = m->mFaces[i];
 179.497 +			if (g.triangles[i]>triangles.size()) {
 179.498 +				throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
 179.499 +			}
 179.500 +
 179.501 +			TempTriangle& t = triangles[g.triangles[i]];
 179.502 +			f.mIndices = new unsigned int[f.mNumIndices=3];
 179.503 +			
 179.504 +			for (unsigned int i = 0; i < 3; ++i,++n) {
 179.505 +				if (t.indices[i]>vertices.size()) {
 179.506 +					throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
 179.507 +				}
 179.508 +
 179.509 +				const TempVertex& v = vertices[t.indices[i]];
 179.510 +				for(unsigned int a = 0; a < 4; ++a) {
 179.511 +					if (v.bone_id[a] != UINT_MAX) {
 179.512 +						if (v.bone_id[a] >= joints.size()) {
 179.513 +							throw DeadlyImportError("MS3D: Encountered invalid bone index, file is malformed");
 179.514 +						}
 179.515 +						if (mybones.find(v.bone_id[a]) == mybones.end()) {
 179.516 +							 mybones[v.bone_id[a]] = 1;
 179.517 +						}
 179.518 +						else ++mybones[v.bone_id[a]];
 179.519 +					}
 179.520 +				}
 179.521 +
 179.522 +				// collect vertex components
 179.523 +				m->mVertices[n] = v.pos;
 179.524 +
 179.525 +				m->mNormals[n] = t.normals[i];
 179.526 +				m->mTextureCoords[0][n] = aiVector3D(t.uv[i].x,1.f-t.uv[i].y,0.0);
 179.527 +				f.mIndices[i] = n;
 179.528 +			}
 179.529 +		}
 179.530 +
 179.531 +		// allocate storage for bones
 179.532 +		if(mybones.size()) {
 179.533 +			std::vector<unsigned int> bmap(joints.size());
 179.534 +			m->mBones = new aiBone*[mybones.size()]();
 179.535 +			for(BoneSet::const_iterator it = mybones.begin(); it != mybones.end(); ++it) {
 179.536 +				aiBone* const bn = m->mBones[m->mNumBones] = new aiBone();
 179.537 +				const TempJoint& jnt = joints[(*it).first]; 
 179.538 +
 179.539 +				bn->mName.Set(jnt.name);
 179.540 +				bn->mWeights = new aiVertexWeight[(*it).second];
 179.541 +
 179.542 +				bmap[(*it).first] = m->mNumBones++;
 179.543 +			}
 179.544 +
 179.545 +			// .. and collect bone weights
 179.546 +			for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) {
 179.547 +				TempTriangle& t = triangles[g.triangles[i]];
 179.548 +
 179.549 +				for (unsigned int i = 0; i < 3; ++i,++n) {
 179.550 +					const TempVertex& v = vertices[t.indices[i]];
 179.551 +					for(unsigned int a = 0; a < 4; ++a) {
 179.552 +						const unsigned int bone = v.bone_id[a];
 179.553 +						if(bone==UINT_MAX){
 179.554 +							continue;
 179.555 +						}
 179.556 +
 179.557 +						aiBone* const outbone = m->mBones[bmap[bone]];
 179.558 +						aiVertexWeight& outwght = outbone->mWeights[outbone->mNumWeights++];
 179.559 +
 179.560 +						outwght.mVertexId = n;
 179.561 +						outwght.mWeight = v.weights[a];
 179.562 +					}
 179.563 +				}
 179.564 +			}
 179.565 +		}
 179.566 +	}
 179.567 +
 179.568 +	// ... add dummy nodes under a single root, each holding a reference to one
 179.569 +	// mesh. If we didn't do this, we'd loose the group name.
 179.570 +	aiNode* rt = pScene->mRootNode = new aiNode("<MS3DRoot>");
 179.571 +	
 179.572 +#ifdef ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH
 179.573 +	rt->mChildren = new aiNode*[rt->mNumChildren=pScene->mNumMeshes+(joints.size()?1:0)]();
 179.574 +
 179.575 +	for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
 179.576 +		aiNode* nd = rt->mChildren[i] = new aiNode();
 179.577 +
 179.578 +		const TempGroup& g = groups[i];
 179.579 +
 179.580 +		// we need to generate an unique name for all mesh nodes.
 179.581 +		// since we want to keep the group name, a prefix is
 179.582 +		// prepended.
 179.583 +		nd->mName = aiString("<MS3DMesh>_");
 179.584 +		nd->mName.Append(g.name);
 179.585 +		nd->mParent = rt;
 179.586 +
 179.587 +		nd->mMeshes = new unsigned int[nd->mNumMeshes = 1];
 179.588 +		nd->mMeshes[0] = i;
 179.589 +	}
 179.590 +#else
 179.591 +	rt->mMeshes = new unsigned int[pScene->mNumMeshes];
 179.592 +	for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
 179.593 +		rt->mMeshes[rt->mNumMeshes++] = i;
 179.594 +	}
 179.595 +#endif
 179.596 +
 179.597 +	// convert animations as well
 179.598 +	if(joints.size()) {
 179.599 +#ifndef ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH
 179.600 +		rt->mChildren = new aiNode*[1]();
 179.601 +		rt->mNumChildren = 1;
 179.602 +
 179.603 +		aiNode* jt = rt->mChildren[0] = new aiNode();
 179.604 +#else
 179.605 +		aiNode* jt = rt->mChildren[pScene->mNumMeshes] = new aiNode();
 179.606 +#endif
 179.607 +		jt->mParent = rt;
 179.608 +		CollectChildJoints(joints,jt);
 179.609 +		jt->mName.Set("<MS3DJointRoot>");
 179.610 +
 179.611 +		pScene->mAnimations = new aiAnimation*[ pScene->mNumAnimations = 1 ];
 179.612 +		aiAnimation* const anim = pScene->mAnimations[0] = new aiAnimation();
 179.613 +
 179.614 +		anim->mName.Set("<MS3DMasterAnim>");
 179.615 +
 179.616 +		// carry the fps info to the user by scaling all times with it
 179.617 +		anim->mTicksPerSecond = animfps;
 179.618 +		
 179.619 +		// leave duration at its default, so ScenePreprocessor will fill an appropriate
 179.620 +		// value (the values taken from some MS3D files seem to be too unreliable
 179.621 +		// to pass the validation)
 179.622 +		// anim->mDuration = totalframes/animfps;
 179.623 +
 179.624 +		anim->mChannels = new aiNodeAnim*[joints.size()]();
 179.625 +		for(std::vector<TempJoint>::const_iterator it = joints.begin(); it != joints.end(); ++it) {
 179.626 +			if ((*it).rotFrames.empty() && (*it).posFrames.empty()) {
 179.627 +				continue;
 179.628 +			}
 179.629 +
 179.630 +			aiNodeAnim* nd = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
 179.631 +			nd->mNodeName.Set((*it).name);
 179.632 +
 179.633 +			if ((*it).rotFrames.size()) {
 179.634 +				nd->mRotationKeys = new aiQuatKey[(*it).rotFrames.size()];
 179.635 +				for(std::vector<TempKeyFrame>::const_iterator rot = (*it).rotFrames.begin(); rot != (*it).rotFrames.end(); ++rot) {
 179.636 +					aiQuatKey& q = nd->mRotationKeys[nd->mNumRotationKeys++];
 179.637 +
 179.638 +					q.mTime = (*rot).time*animfps;
 179.639 +
 179.640 +					// XXX it seems our matrix&quaternion code has faults in its conversion routines --
 179.641 +					// aiQuaternion(x,y,z) seems to besomething different as quat(matrix.fromeuler(x,y,z)).
 179.642 +					q.mValue = aiQuaternion(aiMatrix3x3(aiMatrix4x4().FromEulerAnglesXYZ((*rot).value)*
 179.643 +						aiMatrix4x4().FromEulerAnglesXYZ((*it).rotation)).Transpose());
 179.644 +				}
 179.645 +			}
 179.646 +
 179.647 +			if ((*it).posFrames.size()) {
 179.648 +				nd->mPositionKeys = new aiVectorKey[(*it).posFrames.size()];
 179.649 +
 179.650 +				aiQuatKey* qu = nd->mRotationKeys;
 179.651 +				for(std::vector<TempKeyFrame>::const_iterator pos = (*it).posFrames.begin(); pos != (*it).posFrames.end(); ++pos,++qu) {
 179.652 +					aiVectorKey& v = nd->mPositionKeys[nd->mNumPositionKeys++];
 179.653 +
 179.654 +					v.mTime = (*pos).time*animfps;
 179.655 +					v.mValue = (*it).position + (*pos).value;
 179.656 +				}
 179.657 +			}
 179.658 +		}
 179.659 +		// fixup to pass the validation if not a single animation channel is non-trivial
 179.660 +		if (!anim->mNumChannels) {
 179.661 +			anim->mChannels = NULL;
 179.662 +		}
 179.663 +	}
 179.664 +}
 179.665 +
 179.666 +#endif
   180.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   180.2 +++ b/libs/assimp/MS3DLoader.h	Sat Feb 01 19:58:19 2014 +0200
   180.3 @@ -0,0 +1,157 @@
   180.4 +/*
   180.5 +Open Asset Import Library (assimp)
   180.6 +----------------------------------------------------------------------
   180.7 +
   180.8 +Copyright (c) 2006-2012, assimp team
   180.9 +All rights reserved.
  180.10 +
  180.11 +Redistribution and use of this software in source and binary forms, 
  180.12 +with or without modification, are permitted provided that the 
  180.13 +following conditions are met:
  180.14 +
  180.15 +* Redistributions of source code must retain the above
  180.16 +  copyright notice, this list of conditions and the
  180.17 +  following disclaimer.
  180.18 +
  180.19 +* Redistributions in binary form must reproduce the above
  180.20 +  copyright notice, this list of conditions and the
  180.21 +  following disclaimer in the documentation and/or other
  180.22 +  materials provided with the distribution.
  180.23 +
  180.24 +* Neither the name of the assimp team, nor the names of its
  180.25 +  contributors may be used to endorse or promote products
  180.26 +  derived from this software without specific prior
  180.27 +  written permission of the assimp team.
  180.28 +
  180.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  180.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  180.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  180.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  180.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  180.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  180.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  180.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  180.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  180.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  180.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  180.40 +
  180.41 +----------------------------------------------------------------------
  180.42 +*/
  180.43 +
  180.44 +/** @file  MS3DLoader.h
  180.45 + *  @brief Declaration of the MS3D importer class.
  180.46 + */
  180.47 +#ifndef AI_MS3DLOADER_H_INCLUDED
  180.48 +#define AI_MS3DLOADER_H_INCLUDED
  180.49 +
  180.50 +#include "BaseImporter.h"
  180.51 +namespace Assimp	{
  180.52 +
  180.53 +// ----------------------------------------------------------------------------------------------
  180.54 +/** Milkshape 3D importer implementation */
  180.55 +// ----------------------------------------------------------------------------------------------
  180.56 +class MS3DImporter 
  180.57 +	: public BaseImporter
  180.58 +{
  180.59 +
  180.60 +public:
  180.61 +
  180.62 +	MS3DImporter();
  180.63 +	~MS3DImporter();
  180.64 +
  180.65 +public:
  180.66 +
  180.67 +	// -------------------------------------------------------------------
  180.68 +	/** Returns whether the class can handle the format of the given file. 
  180.69 +	* See BaseImporter::CanRead() for details.	*/
  180.70 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  180.71 +		bool checkSig) const;
  180.72 +
  180.73 +protected:
  180.74 +
  180.75 +	// -------------------------------------------------------------------
  180.76 +	/** Return importer meta information.
  180.77 +	 * See #BaseImporter::GetInfo for the details */
  180.78 +	const aiImporterDesc* GetInfo () const;
  180.79 +
  180.80 +
  180.81 +	// -------------------------------------------------------------------
  180.82 +	/** Imports the given file into the given scene structure. 
  180.83 +	* See BaseImporter::InternReadFile() for details */
  180.84 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  180.85 +		IOSystem* pIOHandler);
  180.86 +
  180.87 +
  180.88 +private:
  180.89 +
  180.90 +	struct TempJoint;
  180.91 +	void CollectChildJoints(const std::vector<TempJoint>& joints, std::vector<bool>& hadit, aiNode* nd,const aiMatrix4x4& absTrafo);
  180.92 +	void CollectChildJoints(const std::vector<TempJoint>& joints, aiNode* nd);
  180.93 +
  180.94 +	template<typename T> void ReadComments(StreamReaderLE& stream, std::vector<T>& outp);
  180.95 +private:
  180.96 +
  180.97 +	aiScene* mScene;
  180.98 +
  180.99 +private:
 180.100 +
 180.101 +	struct TempVertex
 180.102 +	{
 180.103 +		aiVector3D pos;
 180.104 +		unsigned int bone_id[4], ref_cnt;
 180.105 +		float weights[4];
 180.106 +	};
 180.107 +
 180.108 +	struct TempTriangle
 180.109 +	{
 180.110 +		unsigned int indices[3];
 180.111 +		aiVector3D normals[3];
 180.112 +		aiVector2D uv[3];
 180.113 +
 180.114 +		unsigned int sg, group;
 180.115 +	};
 180.116 +
 180.117 +	struct TempGroup
 180.118 +	{
 180.119 +		char name[33]; // +0
 180.120 +		std::vector<unsigned int> triangles;
 180.121 +		unsigned int mat; // 0xff is no material
 180.122 +		std::string comment;
 180.123 +	};
 180.124 +
 180.125 +	struct TempMaterial
 180.126 +	{
 180.127 +		// again, add an extra 0 character to all strings -
 180.128 +		char name[33];
 180.129 +		char texture[129];
 180.130 +		char alphamap[129];
 180.131 +
 180.132 +		aiColor4D diffuse,specular,ambient,emissive;
 180.133 +		float shininess,transparency;
 180.134 +		std::string comment;
 180.135 +	};
 180.136 +
 180.137 +	struct TempKeyFrame 
 180.138 +	{
 180.139 +		float time;
 180.140 +		aiVector3D value;
 180.141 +	};
 180.142 +
 180.143 +	struct TempJoint
 180.144 +	{
 180.145 +		char name[33];
 180.146 +		char parentName[33];
 180.147 +		aiVector3D rotation, position;
 180.148 +
 180.149 +		std::vector<TempKeyFrame> rotFrames;
 180.150 +		std::vector<TempKeyFrame> posFrames;
 180.151 +		std::string comment;
 180.152 +	};
 180.153 +
 180.154 +	//struct TempModel {
 180.155 +	//	std::string comment;
 180.156 +	//};
 180.157 +};
 180.158 +
 180.159 +}
 180.160 +#endif
   181.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   181.2 +++ b/libs/assimp/MakeVerboseFormat.cpp	Sat Feb 01 19:58:19 2014 +0200
   181.3 @@ -0,0 +1,215 @@
   181.4 +/*
   181.5 +---------------------------------------------------------------------------
   181.6 +Open Asset Import Library (assimp)
   181.7 +---------------------------------------------------------------------------
   181.8 +
   181.9 +Copyright (c) 2006-2012, assimp team
  181.10 +
  181.11 +All rights reserved.
  181.12 +
  181.13 +Redistribution and use of this software in source and binary forms, 
  181.14 +with or without modification, are permitted provided that the following 
  181.15 +conditions are met:
  181.16 +
  181.17 +* Redistributions of source code must retain the above
  181.18 +  copyright notice, this list of conditions and the
  181.19 +  following disclaimer.
  181.20 +
  181.21 +* Redistributions in binary form must reproduce the above
  181.22 +  copyright notice, this list of conditions and the
  181.23 +  following disclaimer in the documentation and/or other
  181.24 +  materials provided with the distribution.
  181.25 +
  181.26 +* Neither the name of the assimp team, nor the names of its
  181.27 +  contributors may be used to endorse or promote products
  181.28 +  derived from this software without specific prior
  181.29 +  written permission of the assimp team.
  181.30 +
  181.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  181.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  181.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  181.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  181.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  181.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  181.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  181.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  181.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  181.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  181.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  181.42 +---------------------------------------------------------------------------
  181.43 +*/
  181.44 +/** @file Implementation of the post processing step "MakeVerboseFormat"
  181.45 +*/
  181.46 +
  181.47 +#include "AssimpPCH.h"
  181.48 +#include "MakeVerboseFormat.h"
  181.49 +
  181.50 +using namespace Assimp;
  181.51 +
  181.52 +// ------------------------------------------------------------------------------------------------
  181.53 +MakeVerboseFormatProcess::MakeVerboseFormatProcess()
  181.54 +{
  181.55 +	// nothing to do here
  181.56 +}
  181.57 +// ------------------------------------------------------------------------------------------------
  181.58 +MakeVerboseFormatProcess::~MakeVerboseFormatProcess()
  181.59 +{
  181.60 +	// nothing to do here
  181.61 +}
  181.62 +// ------------------------------------------------------------------------------------------------
  181.63 +// Executes the post processing step on the given imported data.
  181.64 +void MakeVerboseFormatProcess::Execute( aiScene* pScene)
  181.65 +{
  181.66 +	ai_assert(NULL != pScene);
  181.67 +	DefaultLogger::get()->debug("MakeVerboseFormatProcess begin");
  181.68 +
  181.69 +	bool bHas = false;
  181.70 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
  181.71 +	{
  181.72 +		if(	MakeVerboseFormat( pScene->mMeshes[a]))
  181.73 +			bHas = true;
  181.74 +	}
  181.75 +	if (bHas) DefaultLogger::get()->info("MakeVerboseFormatProcess finished. There was much work to do ...");
  181.76 +	else DefaultLogger::get()->debug("MakeVerboseFormatProcess. There was nothing to do.");
  181.77 +
  181.78 +	pScene->mFlags &= ~AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
  181.79 +
  181.80 +}
  181.81 +// ------------------------------------------------------------------------------------------------
  181.82 +// Executes the post processing step on the given imported data.
  181.83 +bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
  181.84 +{
  181.85 +	ai_assert(NULL != pcMesh);
  181.86 +
  181.87 +	unsigned int iOldNumVertices = pcMesh->mNumVertices;
  181.88 +	const unsigned int iNumVerts = pcMesh->mNumFaces*3;
  181.89 +
  181.90 +	aiVector3D* pvPositions = new aiVector3D[ iNumVerts ];
  181.91 +
  181.92 +	aiVector3D* pvNormals = NULL;
  181.93 +	if (pcMesh->HasNormals()) 
  181.94 +	{
  181.95 +		pvNormals = new aiVector3D[iNumVerts];
  181.96 +	}
  181.97 +	aiVector3D* pvTangents = NULL, *pvBitangents = NULL;
  181.98 +	if (pcMesh->HasTangentsAndBitangents()) 
  181.99 +	{
 181.100 +		pvTangents = new aiVector3D[iNumVerts];
 181.101 +		pvBitangents = new aiVector3D[iNumVerts];
 181.102 +	}
 181.103 +
 181.104 +	aiVector3D* apvTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS] = {0};
 181.105 +	aiColor4D* apvColorSets[AI_MAX_NUMBER_OF_COLOR_SETS] = {0};
 181.106 +
 181.107 +	unsigned int p = 0;
 181.108 +	while (pcMesh->HasTextureCoords(p))
 181.109 +		apvTextureCoords[p++] = new aiVector3D[iNumVerts];
 181.110 +
 181.111 +	p = 0;
 181.112 +	while (pcMesh->HasVertexColors(p))
 181.113 +		apvColorSets[p++] = new aiColor4D[iNumVerts];
 181.114 +
 181.115 +	// allocate enough memory to hold output bones and vertex weights ...
 181.116 +	std::vector<aiVertexWeight>* newWeights = new std::vector<aiVertexWeight>[pcMesh->mNumBones];
 181.117 +	for (unsigned int i = 0;i < pcMesh->mNumBones;++i) {
 181.118 +		newWeights[i].reserve(pcMesh->mBones[i]->mNumWeights*3);
 181.119 +	}
 181.120 +
 181.121 +	// iterate through all faces and build a clean list
 181.122 +	unsigned int iIndex = 0;
 181.123 +	for (unsigned int a = 0; a< pcMesh->mNumFaces;++a)
 181.124 +	{
 181.125 +		aiFace* pcFace = &pcMesh->mFaces[a];
 181.126 +		for (unsigned int q = 0; q < pcFace->mNumIndices;++q,++iIndex)
 181.127 +		{
 181.128 +			// need to build a clean list of bones, too
 181.129 +			for (unsigned int i = 0;i < pcMesh->mNumBones;++i) 
 181.130 +			{
 181.131 +				for (unsigned int a = 0;  a < pcMesh->mBones[i]->mNumWeights;a++)
 181.132 +				{
 181.133 +					const aiVertexWeight& w = pcMesh->mBones[i]->mWeights[a];
 181.134 +					if(pcFace->mIndices[q] == w.mVertexId)
 181.135 +					{
 181.136 +						aiVertexWeight wNew;
 181.137 +						wNew.mVertexId = iIndex;
 181.138 +						wNew.mWeight = w.mWeight;
 181.139 +						newWeights[i].push_back(wNew);
 181.140 +					}
 181.141 +				}
 181.142 +			}
 181.143 +
 181.144 +			pvPositions[iIndex] = pcMesh->mVertices[pcFace->mIndices[q]];
 181.145 +
 181.146 +			if (pcMesh->HasNormals()) 
 181.147 +			{
 181.148 +				pvNormals[iIndex] = pcMesh->mNormals[pcFace->mIndices[q]];
 181.149 +			}
 181.150 +			if (pcMesh->HasTangentsAndBitangents()) 
 181.151 +			{
 181.152 +				pvTangents[iIndex] = pcMesh->mTangents[pcFace->mIndices[q]];
 181.153 +				pvBitangents[iIndex] = pcMesh->mBitangents[pcFace->mIndices[q]];
 181.154 +			}
 181.155 +
 181.156 +			unsigned int p = 0;
 181.157 +			while (pcMesh->HasTextureCoords(p))
 181.158 +			{
 181.159 +				apvTextureCoords[p][iIndex] = pcMesh->mTextureCoords[p][pcFace->mIndices[q]];
 181.160 +				++p;
 181.161 +			}
 181.162 +			p = 0;
 181.163 +			while (pcMesh->HasVertexColors(p))
 181.164 +			{
 181.165 +				apvColorSets[p][iIndex] = pcMesh->mColors[p][pcFace->mIndices[q]];
 181.166 +				++p;
 181.167 +			}
 181.168 +			pcFace->mIndices[q] = iIndex;
 181.169 +		}
 181.170 +	}
 181.171 +
 181.172 +	// build output vertex weights
 181.173 +	for (unsigned int i = 0;i < pcMesh->mNumBones;++i) 
 181.174 +	{
 181.175 +		delete pcMesh->mBones[i]->mWeights;
 181.176 +		if (!newWeights[i].empty())
 181.177 +		{
 181.178 +			pcMesh->mBones[i]->mWeights = new aiVertexWeight[newWeights[i].size()];
 181.179 +			memcpy(pcMesh->mBones[i]->mWeights,&newWeights[i][0],
 181.180 +				sizeof(aiVertexWeight) * newWeights[i].size());
 181.181 +		}
 181.182 +		else pcMesh->mBones[i]->mWeights = NULL;
 181.183 +	}
 181.184 +
 181.185 +	// delete the old members
 181.186 +	delete[] pcMesh->mVertices;
 181.187 +	pcMesh->mVertices = pvPositions;
 181.188 +
 181.189 +	p = 0;
 181.190 +	while (pcMesh->HasTextureCoords(p))
 181.191 +	{
 181.192 +		delete pcMesh->mTextureCoords[p];
 181.193 +		pcMesh->mTextureCoords[p] = apvTextureCoords[p];
 181.194 +		++p;
 181.195 +	}
 181.196 +	p = 0;
 181.197 +	while (pcMesh->HasVertexColors(p))
 181.198 +	{
 181.199 +		delete pcMesh->mColors[p];
 181.200 +		pcMesh->mColors[p] = apvColorSets[p];
 181.201 +		++p;
 181.202 +	}
 181.203 +	pcMesh->mNumVertices = iNumVerts;
 181.204 +
 181.205 +	if (pcMesh->HasNormals()) 
 181.206 +	{
 181.207 +		delete[] pcMesh->mNormals;
 181.208 +		pcMesh->mNormals = pvNormals;
 181.209 +	}
 181.210 +	if (pcMesh->HasTangentsAndBitangents()) 
 181.211 +	{
 181.212 +		delete[] pcMesh->mTangents;
 181.213 +		pcMesh->mTangents = pvTangents;
 181.214 +		delete[] pcMesh->mBitangents;
 181.215 +		pcMesh->mBitangents = pvBitangents;
 181.216 +	}
 181.217 +	return (pcMesh->mNumVertices != iOldNumVertices);
 181.218 +}
   182.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   182.2 +++ b/libs/assimp/MakeVerboseFormat.h	Sat Feb 01 19:58:19 2014 +0200
   182.3 @@ -0,0 +1,101 @@
   182.4 +/*
   182.5 +Open Asset Import Library (assimp)
   182.6 +----------------------------------------------------------------------
   182.7 +
   182.8 +Copyright (c) 2006-2012, assimp team
   182.9 +All rights reserved.
  182.10 +
  182.11 +Redistribution and use of this software in source and binary forms, 
  182.12 +with or without modification, are permitted provided that the 
  182.13 +following conditions are met:
  182.14 +
  182.15 +* Redistributions of source code must retain the above
  182.16 +  copyright notice, this list of conditions and the
  182.17 +  following disclaimer.
  182.18 +
  182.19 +* Redistributions in binary form must reproduce the above
  182.20 +  copyright notice, this list of conditions and the
  182.21 +  following disclaimer in the documentation and/or other
  182.22 +  materials provided with the distribution.
  182.23 +
  182.24 +* Neither the name of the assimp team, nor the names of its
  182.25 +  contributors may be used to endorse or promote products
  182.26 +  derived from this software without specific prior
  182.27 +  written permission of the assimp team.
  182.28 +
  182.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  182.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  182.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  182.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  182.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  182.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  182.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  182.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  182.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  182.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  182.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  182.40 +
  182.41 +----------------------------------------------------------------------
  182.42 +*/
  182.43 +
  182.44 +/** @file Defines a post processing step to bring a given scene
  182.45 + into the verbose format that is expected by most postprocess steps. 
  182.46 + This is the inverse of the "JoinIdenticalVertices" step. */
  182.47 +#ifndef AI_MAKEVERBOSEFORMAT_H_INC
  182.48 +#define AI_MAKEVERBOSEFORMAT_H_INC
  182.49 +
  182.50 +#include "BaseProcess.h"
  182.51 +namespace Assimp	{
  182.52 +
  182.53 +// ---------------------------------------------------------------------------
  182.54 +/** MakeVerboseFormatProcess: Class to convert an asset to the verbose 
  182.55 + *  format which is expected by most postprocess steps.
  182.56 + *
  182.57 + * This is the inverse of what the "JoinIdenticalVertices" step is doing. 
  182.58 + * This step has no official flag (since it wouldn't make sense to run it 
  182.59 + * during import). It is intended for applications intending to modify the 
  182.60 + * returned aiScene. After this step has been executed, they can execute
  182.61 + * other postprocess steps on the data. The code might also be useful to
  182.62 + * quickly adapt code that doesn't result in a verbose representation of
  182.63 + * the scene data.
  182.64 + * The step has been added because it was required by the viewer, however
  182.65 + * it has been moved to the main library since others might find it
  182.66 + * useful, too. */
  182.67 +class ASSIMP_API_WINONLY MakeVerboseFormatProcess : public BaseProcess
  182.68 +{
  182.69 +public:
  182.70 +
  182.71 +	
  182.72 +	MakeVerboseFormatProcess();
  182.73 +	~MakeVerboseFormatProcess();
  182.74 +
  182.75 +public:
  182.76 +
  182.77 +	// -------------------------------------------------------------------
  182.78 +	/** Returns whether the processing step is present in the given flag field.
  182.79 +	* @param pFlags The processing flags the importer was called with. A bitwise
  182.80 +	*   combination of #aiPostProcessSteps.
  182.81 +	* @return true if the process is present in this flag fields, false if not */
  182.82 +	bool IsActive( unsigned int /*pFlags*/ ) const 
  182.83 +	{
  182.84 +		// NOTE: There is no direct flag that corresponds to
  182.85 +		// this postprocess step.
  182.86 +		return false;
  182.87 +	}
  182.88 +
  182.89 +	// -------------------------------------------------------------------
  182.90 +	/** Executes the post processing step on the given imported data.
  182.91 +	* At the moment a process is not supposed to fail.
  182.92 +	* @param pScene The imported data to work at. */
  182.93 +	void Execute( aiScene* pScene);
  182.94 +
  182.95 +
  182.96 +private:
  182.97 +
  182.98 +	//! Apply the postprocess step to a given submesh
  182.99 +	bool MakeVerboseFormat (aiMesh* pcMesh);
 182.100 +};
 182.101 +        
 182.102 +} // end of namespace Assimp
 182.103 +
 182.104 +#endif // !!AI_KILLNORMALPROCESS_H_INC
   183.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   183.2 +++ b/libs/assimp/MaterialSystem.cpp	Sat Feb 01 19:58:19 2014 +0200
   183.3 @@ -0,0 +1,590 @@
   183.4 +/*
   183.5 +Open Asset Import Library (assimp)
   183.6 +----------------------------------------------------------------------
   183.7 +
   183.8 +Copyright (c) 2006-2012, assimp team
   183.9 +All rights reserved.
  183.10 +
  183.11 +Redistribution and use of this software in source and binary forms, 
  183.12 +with or without modification, are permitted provided that the 
  183.13 +following conditions are met:
  183.14 +
  183.15 +* Redistributions of source code must retain the above
  183.16 +  copyright notice, this list of conditions and the
  183.17 +  following disclaimer.
  183.18 +
  183.19 +* Redistributions in binary form must reproduce the above
  183.20 +  copyright notice, this list of conditions and the
  183.21 +  following disclaimer in the documentation and/or other
  183.22 +  materials provided with the distribution.
  183.23 +
  183.24 +* Neither the name of the assimp team, nor the names of its
  183.25 +  contributors may be used to endorse or promote products
  183.26 +  derived from this software without specific prior
  183.27 +  written permission of the assimp team.
  183.28 +
  183.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  183.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  183.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  183.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  183.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  183.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  183.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  183.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  183.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  183.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  183.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  183.40 +
  183.41 +----------------------------------------------------------------------
  183.42 +*/
  183.43 +
  183.44 +/** @file  MaterialSystem.cpp
  183.45 + *  @brief Implementation of the material system of the library
  183.46 + */
  183.47 +
  183.48 +#include "AssimpPCH.h"
  183.49 +
  183.50 +#include "Hash.h"
  183.51 +#include "fast_atof.h"
  183.52 +#include "ParsingUtils.h"
  183.53 +#include "MaterialSystem.h"
  183.54 +
  183.55 +using namespace Assimp;
  183.56 +
  183.57 +// ------------------------------------------------------------------------------------------------
  183.58 +// Get a specific property from a material
  183.59 +aiReturn aiGetMaterialProperty(const aiMaterial* pMat, 
  183.60 +	const char* pKey,
  183.61 +	unsigned int type,
  183.62 +    unsigned int index,
  183.63 +	const aiMaterialProperty** pPropOut)
  183.64 +{
  183.65 +	ai_assert (pMat != NULL);
  183.66 +	ai_assert (pKey != NULL);
  183.67 +	ai_assert (pPropOut != NULL);
  183.68 +
  183.69 +	/*  Just search for a property with exactly this name ..
  183.70 +	 *  could be improved by hashing, but it's possibly 
  183.71 +	 *  no worth the effort (we're bound to C structures,
  183.72 +	 *  thus std::map or derivates are not applicable. */
  183.73 +	for (unsigned int i = 0; i < pMat->mNumProperties;++i) {
  183.74 +		aiMaterialProperty* prop = pMat->mProperties[i];
  183.75 +
  183.76 +		if (prop /* just for safety ... */
  183.77 +			&& 0 == strcmp( prop->mKey.data, pKey ) 
  183.78 +			&& (UINT_MAX == type  || prop->mSemantic == type) /* UINT_MAX is a wildcard, but this is undocumented :-) */ 
  183.79 +			&& (UINT_MAX == index || prop->mIndex == index))
  183.80 +		{
  183.81 +			*pPropOut = pMat->mProperties[i];
  183.82 +			return AI_SUCCESS;
  183.83 +		}
  183.84 +	}
  183.85 +	*pPropOut = NULL;
  183.86 +	return AI_FAILURE;
  183.87 +}
  183.88 +
  183.89 +// ------------------------------------------------------------------------------------------------
  183.90 +// Get an array of floating-point values from the material.
  183.91 +aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat, 
  183.92 +	const char* pKey,
  183.93 +	unsigned int type,
  183.94 +    unsigned int index,
  183.95 +	float* pOut,
  183.96 +	unsigned int* pMax)
  183.97 +{
  183.98 +	ai_assert (pOut != NULL);
  183.99 +	ai_assert (pMat != NULL);
 183.100 +
 183.101 +	const aiMaterialProperty* prop;
 183.102 +	aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
 183.103 +	if (!prop) {
 183.104 +		return AI_FAILURE;
 183.105 +	}
 183.106 +
 183.107 +	// data is given in floats, simply copy it
 183.108 +	unsigned int iWrite;
 183.109 +	if( aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType)	{
 183.110 +		iWrite = prop->mDataLength / sizeof(float);
 183.111 +		if (pMax) {
 183.112 +			iWrite = std::min(*pMax,iWrite); ;
 183.113 +		}
 183.114 +		for (unsigned int a = 0; a < iWrite;++a)	{
 183.115 +			pOut[a] = static_cast<float> ( reinterpret_cast<float*>(prop->mData)[a] );
 183.116 +		}
 183.117 +		if (pMax) {
 183.118 +			*pMax = iWrite;
 183.119 +		}
 183.120 +	}
 183.121 +	// data is given in ints, convert to float
 183.122 +	else if( aiPTI_Integer == prop->mType)	{
 183.123 +		iWrite = prop->mDataLength / sizeof(int32_t);
 183.124 +		if (pMax) {
 183.125 +			iWrite = std::min(*pMax,iWrite); ;
 183.126 +		}
 183.127 +		for (unsigned int a = 0; a < iWrite;++a)	{
 183.128 +			pOut[a] = static_cast<float> ( reinterpret_cast<int32_t*>(prop->mData)[a] );
 183.129 +		}
 183.130 +		if (pMax) {
 183.131 +			*pMax = iWrite;
 183.132 +		}
 183.133 +	}
 183.134 +	// a string ... read floats separated by spaces
 183.135 +	else {
 183.136 +		if (pMax) {
 183.137 +			iWrite = *pMax;
 183.138 +		}
 183.139 +		// strings are zero-terminated with a 32 bit length prefix, so this is safe
 183.140 +		const char* cur =  prop->mData+4;
 183.141 +		ai_assert(prop->mDataLength>=5 && !prop->mData[prop->mDataLength-1]);
 183.142 +		for (unsigned int a = 0; ;++a) {	
 183.143 +			cur = fast_atoreal_move<float>(cur,pOut[a]);
 183.144 +			if(a==iWrite-1) {
 183.145 +				break;
 183.146 +			}
 183.147 +			if(!IsSpace(*cur)) {
 183.148 +				DefaultLogger::get()->error("Material property" + std::string(pKey) + 
 183.149 +					" is a string; failed to parse a float array out of it.");
 183.150 +				return AI_FAILURE;
 183.151 +			}
 183.152 +		}
 183.153 +
 183.154 +		if (pMax) {
 183.155 +			*pMax = iWrite;
 183.156 +		}
 183.157 +	}
 183.158 +	return AI_SUCCESS;
 183.159 +
 183.160 +}
 183.161 +
 183.162 +// ------------------------------------------------------------------------------------------------
 183.163 +// Get an array if integers from the material
 183.164 +aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat, 
 183.165 +	const char* pKey,
 183.166 +	unsigned int type,
 183.167 +    unsigned int index,
 183.168 +	int* pOut,
 183.169 +	unsigned int* pMax)
 183.170 +{
 183.171 +	ai_assert (pOut != NULL);
 183.172 +	ai_assert (pMat != NULL);
 183.173 +
 183.174 +	const aiMaterialProperty* prop;
 183.175 +	aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop);
 183.176 +	if (!prop) {
 183.177 +		return AI_FAILURE;
 183.178 +	}
 183.179 +
 183.180 +	// data is given in ints, simply copy it
 183.181 +	unsigned int iWrite;
 183.182 +	if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType)	{
 183.183 +		iWrite = prop->mDataLength / sizeof(int32_t);
 183.184 +		if (pMax) {
 183.185 +			iWrite = std::min(*pMax,iWrite); ;
 183.186 +		}
 183.187 +		for (unsigned int a = 0; a < iWrite;++a) {
 183.188 +			pOut[a] = static_cast<int>(reinterpret_cast<int32_t*>(prop->mData)[a]);
 183.189 +		}
 183.190 +		if (pMax) {
 183.191 +			*pMax = iWrite;
 183.192 +		}
 183.193 +	}
 183.194 +	// data is given in floats convert to int 
 183.195 +	else if( aiPTI_Float == prop->mType)	{
 183.196 +		iWrite = prop->mDataLength / sizeof(float);
 183.197 +		if (pMax) {
 183.198 +			iWrite = std::min(*pMax,iWrite); ;
 183.199 +		}
 183.200 +		for (unsigned int a = 0; a < iWrite;++a) {
 183.201 +			pOut[a] = static_cast<int>(reinterpret_cast<float*>(prop->mData)[a]);
 183.202 +		}
 183.203 +		if (pMax) {
 183.204 +			*pMax = iWrite;
 183.205 +		}
 183.206 +	}
 183.207 +	// it is a string ... no way to read something out of this
 183.208 +	else	{
 183.209 +		if (pMax) {
 183.210 +			iWrite = *pMax;
 183.211 +		}
 183.212 +		// strings are zero-terminated with a 32 bit length prefix, so this is safe
 183.213 +		const char* cur =  prop->mData+4;
 183.214 +		ai_assert(prop->mDataLength>=5 && !prop->mData[prop->mDataLength-1]);
 183.215 +		for (unsigned int a = 0; ;++a) {	
 183.216 +			pOut[a] = strtol10(cur,&cur);
 183.217 +			if(a==iWrite-1) {
 183.218 +				break;
 183.219 +			}
 183.220 +			if(!IsSpace(*cur)) {
 183.221 +				DefaultLogger::get()->error("Material property" + std::string(pKey) + 
 183.222 +					" is a string; failed to parse an integer array out of it.");
 183.223 +				return AI_FAILURE;
 183.224 +			}
 183.225 +		}
 183.226 +
 183.227 +		if (pMax) {
 183.228 +			*pMax = iWrite;
 183.229 +		}
 183.230 +	}
 183.231 +	return AI_SUCCESS;
 183.232 +}
 183.233 +
 183.234 +// ------------------------------------------------------------------------------------------------
 183.235 +// Get a color (3 or 4 floats) from the material
 183.236 +aiReturn aiGetMaterialColor(const aiMaterial* pMat, 
 183.237 +	const char* pKey,
 183.238 +	unsigned int type,
 183.239 +	unsigned int index,
 183.240 +	aiColor4D* pOut)
 183.241 +{
 183.242 +	unsigned int iMax = 4;
 183.243 +	const aiReturn eRet = aiGetMaterialFloatArray(pMat,pKey,type,index,(float*)pOut,&iMax);
 183.244 +
 183.245 +	// if no alpha channel is defined: set it to 1.0
 183.246 +	if (3 == iMax) {
 183.247 +		pOut->a = 1.0f;
 183.248 +	}
 183.249 +
 183.250 +	return eRet;
 183.251 +}
 183.252 +
 183.253 +// ------------------------------------------------------------------------------------------------
 183.254 +// Get a string from the material
 183.255 +aiReturn aiGetMaterialString(const aiMaterial* pMat, 
 183.256 +	const char* pKey,
 183.257 +	unsigned int type,
 183.258 +	unsigned int index,
 183.259 +	aiString* pOut)
 183.260 +{
 183.261 +	ai_assert (pOut != NULL);
 183.262 +
 183.263 +	const aiMaterialProperty* prop;
 183.264 +	aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**)&prop);
 183.265 +	if (!prop) {
 183.266 +		return AI_FAILURE;
 183.267 +	}
 183.268 +
 183.269 +	if( aiPTI_String == prop->mType) {
 183.270 +		ai_assert(prop->mDataLength>=5);
 183.271 +
 183.272 +		// The string is stored as 32 but length prefix followed by zero-terminated UTF8 data
 183.273 +		pOut->length = static_cast<unsigned int>(*reinterpret_cast<uint32_t*>(prop->mData));
 183.274 +
 183.275 +		ai_assert(pOut->length+1+4==prop->mDataLength && !prop->mData[prop->mDataLength-1]);
 183.276 +		memcpy(pOut->data,prop->mData+4,pOut->length+1);
 183.277 +	}
 183.278 +	else {
 183.279 +		// TODO - implement lexical cast as well
 183.280 +		DefaultLogger::get()->error("Material property" + std::string(pKey) + 
 183.281 +			" was found, but is no string" );	
 183.282 +		return AI_FAILURE;
 183.283 +	}
 183.284 +	return AI_SUCCESS;
 183.285 +}
 183.286 +
 183.287 +// ------------------------------------------------------------------------------------------------
 183.288 +// Get the number of textures on a particular texture stack
 183.289 +ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,  
 183.290 +	C_ENUM aiTextureType type)
 183.291 +{
 183.292 +	ai_assert (pMat != NULL);
 183.293 +
 183.294 +	/* Textures are always stored with ascending indices (ValidateDS provides a check, so we don't need to do it again) */
 183.295 +	unsigned int max = 0;
 183.296 +	for (unsigned int i = 0; i < pMat->mNumProperties;++i) {
 183.297 +		aiMaterialProperty* prop = pMat->mProperties[i];
 183.298 +
 183.299 +		if (prop /* just a sanity check ... */ 
 183.300 +			&& 0 == strcmp( prop->mKey.data, _AI_MATKEY_TEXTURE_BASE )
 183.301 +			&& prop->mSemantic == type) {
 183.302 +	
 183.303 +			max = std::max(max,prop->mIndex+1);
 183.304 +		}
 183.305 +	}
 183.306 +	return max;
 183.307 +}
 183.308 +
 183.309 +// ------------------------------------------------------------------------------------------------
 183.310 +aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
 183.311 +    aiTextureType type,
 183.312 +    unsigned int  index,
 183.313 +    C_STRUCT aiString* path,
 183.314 +	aiTextureMapping* _mapping	/*= NULL*/,
 183.315 +    unsigned int* uvindex		/*= NULL*/,
 183.316 +    float* blend				/*= NULL*/,
 183.317 +    aiTextureOp* op				/*= NULL*/,
 183.318 +	aiTextureMapMode* mapmode	/*= NULL*/,
 183.319 +	unsigned int* flags         /*= NULL*/
 183.320 +	)
 183.321 +{
 183.322 +	ai_assert(NULL != mat && NULL != path);
 183.323 +
 183.324 +	// Get the path to the texture
 183.325 +	if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path))	{
 183.326 +		return AI_FAILURE;
 183.327 +	}
 183.328 +	// Determine mapping type 
 183.329 +	aiTextureMapping mapping = aiTextureMapping_UV;
 183.330 +	aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index),(int*)&mapping);
 183.331 +	if (_mapping)
 183.332 +		*_mapping = mapping;
 183.333 +
 183.334 +	// Get UV index 
 183.335 +	if (aiTextureMapping_UV == mapping && uvindex)	{
 183.336 +		aiGetMaterialInteger(mat,AI_MATKEY_UVWSRC(type,index),(int*)uvindex);
 183.337 +	}
 183.338 +	// Get blend factor 
 183.339 +	if (blend)	{
 183.340 +		aiGetMaterialFloat(mat,AI_MATKEY_TEXBLEND(type,index),blend);
 183.341 +	}
 183.342 +	// Get texture operation 
 183.343 +	if (op){
 183.344 +		aiGetMaterialInteger(mat,AI_MATKEY_TEXOP(type,index),(int*)op);
 183.345 +	}
 183.346 +	// Get texture mapping modes
 183.347 +	if (mapmode)	{
 183.348 +		aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U(type,index),(int*)&mapmode[0]);
 183.349 +		aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V(type,index),(int*)&mapmode[1]);		
 183.350 +	}
 183.351 +	// Get texture flags
 183.352 +	if (flags){
 183.353 +		aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags);
 183.354 +	}
 183.355 +	return AI_SUCCESS;
 183.356 +}
 183.357 +
 183.358 +// ------------------------------------------------------------------------------------------------
 183.359 +// Construction. Actually the one and only way to get an aiMaterial instance
 183.360 +aiMaterial::aiMaterial()
 183.361 +{
 183.362 +	// Allocate 5 entries by default
 183.363 +	mNumProperties = 0;
 183.364 +	mNumAllocated = 5;
 183.365 +	mProperties = new aiMaterialProperty*[5];
 183.366 +}
 183.367 +
 183.368 +// ------------------------------------------------------------------------------------------------
 183.369 +aiMaterial::~aiMaterial()
 183.370 +{
 183.371 +	Clear();
 183.372 +
 183.373 +	delete[] mProperties;
 183.374 +}
 183.375 +
 183.376 +// ------------------------------------------------------------------------------------------------
 183.377 +void aiMaterial::Clear()
 183.378 +{
 183.379 +	for (unsigned int i = 0; i < mNumProperties;++i)	{
 183.380 +		// delete this entry
 183.381 +		delete mProperties[i];
 183.382 +		AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
 183.383 +	}
 183.384 +	mNumProperties = 0;
 183.385 +
 183.386 +	// The array remains allocated, we just invalidated its contents
 183.387 +}
 183.388 +
 183.389 +// ------------------------------------------------------------------------------------------------
 183.390 +aiReturn aiMaterial::RemoveProperty (const char* pKey,unsigned int type,
 183.391 +    unsigned int index
 183.392 +	)
 183.393 +{
 183.394 +	ai_assert(NULL != pKey);
 183.395 +
 183.396 +	for (unsigned int i = 0; i < mNumProperties;++i) {
 183.397 +		aiMaterialProperty* prop = mProperties[i];
 183.398 +
 183.399 +		if (prop && !strcmp( prop->mKey.data, pKey ) &&
 183.400 +			prop->mSemantic == type && prop->mIndex == index)
 183.401 +		{
 183.402 +			// Delete this entry
 183.403 +			delete mProperties[i];
 183.404 +
 183.405 +			// collapse the array behind --.
 183.406 +			--mNumProperties;
 183.407 +			for (unsigned int a = i; a < mNumProperties;++a)	{
 183.408 +				mProperties[a] = mProperties[a+1];
 183.409 +			}
 183.410 +			return AI_SUCCESS;
 183.411 +		}
 183.412 +	}
 183.413 +
 183.414 +	return AI_FAILURE;
 183.415 +}
 183.416 +
 183.417 +// ------------------------------------------------------------------------------------------------
 183.418 +aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
 183.419 +	unsigned int pSizeInBytes,
 183.420 +	const char* pKey,
 183.421 +	unsigned int type,
 183.422 +    unsigned int index,
 183.423 +	aiPropertyTypeInfo pType
 183.424 +	)
 183.425 +{
 183.426 +	ai_assert (pInput != NULL);
 183.427 +	ai_assert (pKey != NULL);
 183.428 +	ai_assert (0 != pSizeInBytes);
 183.429 +
 183.430 +	// first search the list whether there is already an entry with this key
 183.431 +	unsigned int iOutIndex = UINT_MAX;
 183.432 +	for (unsigned int i = 0; i < mNumProperties;++i)	{
 183.433 +		aiMaterialProperty* prop = mProperties[i];
 183.434 +
 183.435 +		if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) &&
 183.436 +			prop->mSemantic == type && prop->mIndex == index){
 183.437 +
 183.438 +			delete mProperties[i];
 183.439 +			iOutIndex = i;
 183.440 +		}
 183.441 +	}
 183.442 +
 183.443 +	// Allocate a new material property
 183.444 +	aiMaterialProperty* pcNew = new aiMaterialProperty();
 183.445 +
 183.446 +	// .. and fill it
 183.447 +	pcNew->mType = pType;
 183.448 +	pcNew->mSemantic = type;
 183.449 +	pcNew->mIndex = index;
 183.450 +
 183.451 +	pcNew->mDataLength = pSizeInBytes;
 183.452 +	pcNew->mData = new char[pSizeInBytes];
 183.453 +	memcpy (pcNew->mData,pInput,pSizeInBytes);
 183.454 +
 183.455 +	pcNew->mKey.length = ::strlen(pKey);
 183.456 +	ai_assert ( MAXLEN > pcNew->mKey.length);
 183.457 +	strcpy( pcNew->mKey.data, pKey );
 183.458 +
 183.459 +	if (UINT_MAX != iOutIndex)	{
 183.460 +		mProperties[iOutIndex] = pcNew;
 183.461 +		return AI_SUCCESS;
 183.462 +	}
 183.463 +
 183.464 +	// resize the array ... double the storage allocated
 183.465 +	if (mNumProperties == mNumAllocated)	{
 183.466 +		const unsigned int iOld = mNumAllocated;
 183.467 +		mNumAllocated *= 2;
 183.468 +
 183.469 +		aiMaterialProperty** ppTemp;
 183.470 +		try {
 183.471 +		ppTemp = new aiMaterialProperty*[mNumAllocated];
 183.472 +		} catch (std::bad_alloc&) {
 183.473 +			return AI_OUTOFMEMORY;
 183.474 +		}
 183.475 +
 183.476 +		// just copy all items over; then replace the old array
 183.477 +		memcpy (ppTemp,mProperties,iOld * sizeof(void*));
 183.478 +
 183.479 +		delete[] mProperties;
 183.480 +		mProperties = ppTemp;
 183.481 +	}
 183.482 +	// push back ...
 183.483 +	mProperties[mNumProperties++] = pcNew;
 183.484 +	return AI_SUCCESS;
 183.485 +}
 183.486 +
 183.487 +// ------------------------------------------------------------------------------------------------
 183.488 +aiReturn aiMaterial::AddProperty (const aiString* pInput,
 183.489 +	const char* pKey,
 183.490 +	unsigned int type,
 183.491 +    unsigned int index)
 183.492 +{
 183.493 +	// We don't want to add the whole buffer .. write a 32 bit length
 183.494 +	// prefix followed by the zero-terminated UTF8 string.
 183.495 +	// (HACK) I don't want to break the ABI now, but we definitely
 183.496 +	// ought to change aiString::mLength to uint32_t one day.
 183.497 +	if (sizeof(size_t) == 8) {
 183.498 +		aiString copy = *pInput;
 183.499 +		uint32_t* s = reinterpret_cast<uint32_t*>(&copy.length);
 183.500 +		s[1] = static_cast<uint32_t>(pInput->length);
 183.501 +
 183.502 +		return AddBinaryProperty(s+1,
 183.503 +			pInput->length+1+4,
 183.504 +			pKey,
 183.505 +			type,
 183.506 +			index, 
 183.507 +			aiPTI_String);
 183.508 +	}
 183.509 +	ai_assert(sizeof(size_t)==4);
 183.510 +	return AddBinaryProperty(pInput,
 183.511 +		pInput->length+1+4,
 183.512 +		pKey,
 183.513 +		type,
 183.514 +		index, 
 183.515 +		aiPTI_String);
 183.516 +}
 183.517 +
 183.518 +// ------------------------------------------------------------------------------------------------
 183.519 +uint32_t Assimp :: ComputeMaterialHash(const aiMaterial* mat, bool includeMatName /*= false*/)
 183.520 +{
 183.521 +	uint32_t hash = 1503; // magic start value, chosen to be my birthday :-)
 183.522 +	for (unsigned int i = 0; i < mat->mNumProperties;++i)	{
 183.523 +		aiMaterialProperty* prop;
 183.524 +
 183.525 +		// Exclude all properties whose first character is '?' from the hash
 183.526 +		// See doc for aiMaterialProperty.
 183.527 +		if ((prop = mat->mProperties[i]) && (includeMatName || prop->mKey.data[0] != '?'))	{
 183.528 +
 183.529 +			hash = SuperFastHash(prop->mKey.data,(unsigned int)prop->mKey.length,hash);
 183.530 +			hash = SuperFastHash(prop->mData,prop->mDataLength,hash);
 183.531 +
 183.532 +			// Combine the semantic and the index with the hash
 183.533 +			hash = SuperFastHash((const char*)&prop->mSemantic,sizeof(unsigned int),hash);
 183.534 +			hash = SuperFastHash((const char*)&prop->mIndex,sizeof(unsigned int),hash);
 183.535 +		}
 183.536 +	}
 183.537 +	return hash;
 183.538 +}
 183.539 +
 183.540 +// ------------------------------------------------------------------------------------------------
 183.541 +void aiMaterial::CopyPropertyList(aiMaterial* pcDest, 
 183.542 +	const aiMaterial* pcSrc
 183.543 +	)
 183.544 +{
 183.545 +	ai_assert(NULL != pcDest);
 183.546 +	ai_assert(NULL != pcSrc);
 183.547 +
 183.548 +	unsigned int iOldNum = pcDest->mNumProperties;
 183.549 +	pcDest->mNumAllocated += pcSrc->mNumAllocated;
 183.550 +	pcDest->mNumProperties += pcSrc->mNumProperties;
 183.551 +
 183.552 +	aiMaterialProperty** pcOld = pcDest->mProperties;
 183.553 +	pcDest->mProperties = new aiMaterialProperty*[pcDest->mNumAllocated];
 183.554 +
 183.555 +	if (iOldNum && pcOld)	{
 183.556 +		for (unsigned int i = 0; i < iOldNum;++i) {
 183.557 +			pcDest->mProperties[i] = pcOld[i];
 183.558 +		}
 183.559 +
 183.560 +		delete[] pcOld;
 183.561 +	}
 183.562 +	for (unsigned int i = iOldNum; i< pcDest->mNumProperties;++i)	{
 183.563 +		aiMaterialProperty* propSrc = pcSrc->mProperties[i];
 183.564 +
 183.565 +		// search whether we have already a property with this name -> if yes, overwrite it
 183.566 +		aiMaterialProperty* prop;
 183.567 +		for (unsigned int q = 0; q < iOldNum;++q) {
 183.568 +			prop = pcDest->mProperties[q];
 183.569 +			if (prop /* just for safety */ && prop->mKey == propSrc->mKey && prop->mSemantic == propSrc->mSemantic
 183.570 +				&& prop->mIndex == propSrc->mIndex)	{
 183.571 +				delete prop;
 183.572 +
 183.573 +				// collapse the whole array ...
 183.574 +				memmove(&pcDest->mProperties[q],&pcDest->mProperties[q+1],i-q);
 183.575 +				i--;
 183.576 +				pcDest->mNumProperties--;
 183.577 +			}
 183.578 +		}
 183.579 +
 183.580 +		// Allocate the output property and copy the source property
 183.581 +		prop = pcDest->mProperties[i] = new aiMaterialProperty();
 183.582 +		prop->mKey = propSrc->mKey;
 183.583 +		prop->mDataLength = propSrc->mDataLength;
 183.584 +		prop->mType = propSrc->mType;
 183.585 +		prop->mSemantic = propSrc->mSemantic;
 183.586 +		prop->mIndex = propSrc->mIndex;
 183.587 +
 183.588 +		prop->mData = new char[propSrc->mDataLength];
 183.589 +		memcpy(prop->mData,propSrc->mData,prop->mDataLength);
 183.590 +	}
 183.591 +	return;
 183.592 +}
 183.593 +
   184.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   184.2 +++ b/libs/assimp/MaterialSystem.h	Sat Feb 01 19:58:19 2014 +0200
   184.3 @@ -0,0 +1,66 @@
   184.4 +/*
   184.5 +Open Asset Import Library (assimp)
   184.6 +----------------------------------------------------------------------
   184.7 +
   184.8 +Copyright (c) 2006-2012, assimp team
   184.9 +All rights reserved.
  184.10 +
  184.11 +Redistribution and use of this software in source and binary forms, 
  184.12 +with or without modification, are permitted provided that the 
  184.13 +following conditions are met:
  184.14 +
  184.15 +* Redistributions of source code must retain the above
  184.16 +  copyright notice, this list of conditions and the
  184.17 +  following disclaimer.
  184.18 +
  184.19 +* Redistributions in binary form must reproduce the above
  184.20 +  copyright notice, this list of conditions and the
  184.21 +  following disclaimer in the documentation and/or other
  184.22 +  materials provided with the distribution.
  184.23 +
  184.24 +* Neither the name of the assimp team, nor the names of its
  184.25 +  contributors may be used to endorse or promote products
  184.26 +  derived from this software without specific prior
  184.27 +  written permission of the assimp team.
  184.28 +
  184.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  184.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  184.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  184.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  184.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  184.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  184.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  184.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  184.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  184.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  184.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  184.40 +
  184.41 +----------------------------------------------------------------------
  184.42 +*/
  184.43 +
  184.44 +/** @file MaterialSystem.h
  184.45 + *  Now that #MaterialHelper is gone, this file only contains some
  184.46 + *  internal material utility functions.
  184.47 + */
  184.48 +#ifndef AI_MATERIALSYSTEM_H_INC
  184.49 +#define AI_MATERIALSYSTEM_H_INC
  184.50 +
  184.51 +namespace Assimp	{
  184.52 +
  184.53 +// ------------------------------------------------------------------------------
  184.54 +/** Computes a hash (hopefully unique) from all material properties
  184.55 + *  The hash value reflects the current property state, so if you add any
  184.56 + *  property and call this method again, the resulting hash value will be 
  184.57 + *  different. The hash is not persistent across different builds and platforms.
  184.58 + *
  184.59 + *  @param  includeMatName Set to 'true' to take all properties with
  184.60 + *    '?' as initial character in their name into account. 
  184.61 + *    Currently #AI_MATKEY_NAME is the only example.
  184.62 + *  @return 32 Bit jash value for the material
  184.63 + */
  184.64 +uint32_t ComputeMaterialHash(const aiMaterial* mat, bool includeMatName = false);
  184.65 +
  184.66 +
  184.67 +} // ! namespace Assimp
  184.68 +
  184.69 +#endif //!! AI_MATERIALSYSTEM_H_INC
   185.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   185.2 +++ b/libs/assimp/MemoryIOWrapper.h	Sat Feb 01 19:58:19 2014 +0200
   185.3 @@ -0,0 +1,190 @@
   185.4 +/*
   185.5 +Open Asset Import Library (assimp)
   185.6 +----------------------------------------------------------------------
   185.7 +
   185.8 +Copyright (c) 2006-2012, assimp team
   185.9 +All rights reserved.
  185.10 +
  185.11 +Redistribution and use of this software in source and binary forms, 
  185.12 +with or without modification, are permitted provided that the 
  185.13 +following conditions are met:
  185.14 +
  185.15 +* Redistributions of source code must retain the above
  185.16 +  copyright notice, this list of conditions and the
  185.17 +  following disclaimer.
  185.18 +
  185.19 +* Redistributions in binary form must reproduce the above
  185.20 +  copyright notice, this list of conditions and the
  185.21 +  following disclaimer in the documentation and/or other
  185.22 +  materials provided with the distribution.
  185.23 +
  185.24 +* Neither the name of the assimp team, nor the names of its
  185.25 +  contributors may be used to endorse or promote products
  185.26 +  derived from this software without specific prior
  185.27 +  written permission of the assimp team.
  185.28 +
  185.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  185.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  185.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  185.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  185.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  185.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  185.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  185.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  185.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  185.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  185.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  185.40 +
  185.41 +----------------------------------------------------------------------
  185.42 +*/
  185.43 +
  185.44 +/** @file MemoryIOWrapper.h
  185.45 + *  Handy IOStream/IOSystem implemetation to read directly from a memory buffer */
  185.46 +#ifndef AI_MEMORYIOSTREAM_H_INC
  185.47 +#define AI_MEMORYIOSTREAM_H_INC
  185.48 +namespace Assimp	{
  185.49 +#define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$"
  185.50 +#define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17
  185.51 +
  185.52 +// ----------------------------------------------------------------------------------
  185.53 +/** Implementation of IOStream to read directly from a memory buffer */
  185.54 +// ----------------------------------------------------------------------------------
  185.55 +class MemoryIOStream : public IOStream
  185.56 +{
  185.57 +	//friend class MemoryIOSystem;
  185.58 +public:
  185.59 +	MemoryIOStream (const uint8_t* buff, size_t len, bool own = false) 
  185.60 +		: buffer (buff)
  185.61 +		, length(len)
  185.62 +		, pos((size_t)0)
  185.63 +		, own(own) 
  185.64 +	{
  185.65 +	}
  185.66 +
  185.67 +public:
  185.68 +
  185.69 +	~MemoryIOStream ()	{
  185.70 +		if(own) {
  185.71 +			delete[] buffer;
  185.72 +		}
  185.73 +	}
  185.74 +
  185.75 +	// -------------------------------------------------------------------
  185.76 +	// Read from stream
  185.77 +    size_t Read(void* pvBuffer, size_t pSize, size_t pCount)	{
  185.78 +		const size_t cnt = std::min(pCount,(length-pos)/pSize),ofs = pSize*cnt;
  185.79 +		
  185.80 +		memcpy(pvBuffer,buffer+pos,ofs);
  185.81 +		pos += ofs;
  185.82 +
  185.83 +		return cnt;
  185.84 +	}
  185.85 +
  185.86 +	// -------------------------------------------------------------------
  185.87 +	// Write to stream
  185.88 +	size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/,size_t /*pCount*/)	{
  185.89 +		ai_assert(false); // won't be needed
  185.90 +		return 0;
  185.91 +	}
  185.92 +
  185.93 +	// -------------------------------------------------------------------
  185.94 +	// Seek specific position
  185.95 +	aiReturn Seek(size_t pOffset, aiOrigin pOrigin) {
  185.96 +		if (aiOrigin_SET == pOrigin) {
  185.97 +			if (pOffset >= length) {
  185.98 +				return AI_FAILURE;
  185.99 +			}
 185.100 +			pos = pOffset;
 185.101 +		}
 185.102 +		else if (aiOrigin_END == pOrigin) {
 185.103 +			if (pOffset >= length) {
 185.104 +				return AI_FAILURE;
 185.105 +			}
 185.106 +			pos = length-pOffset;
 185.107 +		}
 185.108 +		else {
 185.109 +			if (pOffset+pos >= length) {
 185.110 +				return AI_FAILURE;
 185.111 +			}
 185.112 +			pos += pOffset;
 185.113 +		}
 185.114 +		return AI_SUCCESS;
 185.115 +	}
 185.116 +
 185.117 +	// -------------------------------------------------------------------
 185.118 +	// Get current seek position
 185.119 +	size_t Tell() const {
 185.120 +		return pos;
 185.121 +	}
 185.122 +
 185.123 +	// -------------------------------------------------------------------
 185.124 +	// Get size of file
 185.125 +	size_t FileSize() const {
 185.126 +		return length;
 185.127 +	}
 185.128 +
 185.129 +	// -------------------------------------------------------------------
 185.130 +	// Flush file contents
 185.131 +	void Flush() {
 185.132 +		ai_assert(false); // won't be needed
 185.133 +	}
 185.134 +
 185.135 +private:
 185.136 +	const uint8_t* buffer;
 185.137 +	size_t length,pos;
 185.138 +	bool own;
 185.139 +};
 185.140 +
 185.141 +// ---------------------------------------------------------------------------
 185.142 +/** Dummy IO system to read from a memory buffer */
 185.143 +class MemoryIOSystem : public IOSystem
 185.144 +{
 185.145 +public:
 185.146 +	/** Constructor. */
 185.147 +    MemoryIOSystem (const uint8_t* buff, size_t len) 
 185.148 +		: buffer (buff), length(len) {
 185.149 +	}
 185.150 +
 185.151 +	/** Destructor. */
 185.152 +	~MemoryIOSystem() {
 185.153 +	}
 185.154 +
 185.155 +	// -------------------------------------------------------------------
 185.156 +	/** Tests for the existence of a file at the given path. */
 185.157 +	bool Exists( const char* pFile) const {
 185.158 +		return !strncmp(pFile,AI_MEMORYIO_MAGIC_FILENAME,AI_MEMORYIO_MAGIC_FILENAME_LENGTH);
 185.159 +	}
 185.160 +
 185.161 +	// -------------------------------------------------------------------
 185.162 +	/** Returns the directory separator. */
 185.163 +	char getOsSeparator() const {
 185.164 +		return '/'; // why not? it doesn't care
 185.165 +	}
 185.166 +
 185.167 +	// -------------------------------------------------------------------
 185.168 +	/** Open a new file with a given path. */
 185.169 +	IOStream* Open( const char* pFile, const char* /*pMode*/ = "rb") {
 185.170 +		if (strncmp(pFile,AI_MEMORYIO_MAGIC_FILENAME,AI_MEMORYIO_MAGIC_FILENAME_LENGTH)) {
 185.171 +			return NULL;
 185.172 +		}
 185.173 +		return new MemoryIOStream(buffer,length);
 185.174 +	}
 185.175 +
 185.176 +	// -------------------------------------------------------------------
 185.177 +	/** Closes the given file and releases all resources associated with it. */
 185.178 +	void Close( IOStream* /*pFile*/) {
 185.179 +	}
 185.180 +
 185.181 +	// -------------------------------------------------------------------
 185.182 +	/** Compare two paths */
 185.183 +	bool ComparePaths (const char* /*one*/, const char* /*second*/) const {
 185.184 +		return false;
 185.185 +	}
 185.186 +
 185.187 +private:
 185.188 +	const uint8_t* buffer;
 185.189 +	size_t length;
 185.190 +};
 185.191 +} // end namespace Assimp
 185.192 +
 185.193 +#endif
   186.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   186.2 +++ b/libs/assimp/NDOLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   186.3 @@ -0,0 +1,302 @@
   186.4 +/*
   186.5 +---------------------------------------------------------------------------
   186.6 +Open Asset Import Library (assimp)
   186.7 +---------------------------------------------------------------------------
   186.8 +
   186.9 +Copyright (c) 2006-2012, assimp team
  186.10 +
  186.11 +All rights reserved.
  186.12 +
  186.13 +Redistribution and use of this software in source and binary forms, 
  186.14 +with or without modification, are permitted provided that the following 
  186.15 +conditions are met:
  186.16 +
  186.17 +* Redistributions of source code must retain the above
  186.18 +  copyright notice, this list of conditions and the
  186.19 +  following disclaimer.
  186.20 +
  186.21 +* Redistributions in binary form must reproduce the above
  186.22 +  copyright notice, this list of conditions and the
  186.23 +  following disclaimer in the documentation and/or other
  186.24 +  materials provided with the distribution.
  186.25 +
  186.26 +* Neither the name of the assimp team, nor the names of its
  186.27 +  contributors may be used to endorse or promote products
  186.28 +  derived from this software without specific prior
  186.29 +  written permission of the assimp team.
  186.30 +
  186.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  186.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  186.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  186.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  186.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  186.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  186.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  186.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  186.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  186.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  186.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  186.42 +---------------------------------------------------------------------------
  186.43 +*/
  186.44 +
  186.45 +/** @file  NDOLoader.cpp
  186.46 + *  Implementation of the NDO importer class.
  186.47 + */
  186.48 +
  186.49 +#include "AssimpPCH.h"
  186.50 +#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
  186.51 +#include "NDOLoader.h"
  186.52 +
  186.53 +using namespace Assimp;
  186.54 +#define for_each BOOST_FOREACH
  186.55 +
  186.56 +static const aiImporterDesc desc = {
  186.57 +	"Nendo Mesh Importer",
  186.58 +	"",
  186.59 +	"",
  186.60 +	"http://www.izware.com/nendo/index.htm",
  186.61 +	aiImporterFlags_SupportBinaryFlavour,
  186.62 +	0,
  186.63 +	0,
  186.64 +	0,
  186.65 +	0,
  186.66 +	"ndo" 
  186.67 +};
  186.68 +
  186.69 +// ------------------------------------------------------------------------------------------------
  186.70 +// Constructor to be privately used by Importer
  186.71 +NDOImporter::NDOImporter()
  186.72 +{}
  186.73 +
  186.74 +// ------------------------------------------------------------------------------------------------
  186.75 +// Destructor, private as well 
  186.76 +NDOImporter::~NDOImporter()
  186.77 +{}
  186.78 +
  186.79 +// ------------------------------------------------------------------------------------------------
  186.80 +// Returns whether the class can handle the format of the given file. 
  186.81 +bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  186.82 +{
  186.83 +	// check file extension 
  186.84 +	const std::string extension = GetExtension(pFile);
  186.85 +	
  186.86 +	if( extension == "ndo")
  186.87 +		return true;
  186.88 +
  186.89 +	if ((checkSig || !extension.length()) && pIOHandler) {
  186.90 +		const char* tokens[] = {"nendo"};
  186.91 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,5);
  186.92 +	}
  186.93 +	return false;
  186.94 +}
  186.95 +
  186.96 +// ------------------------------------------------------------------------------------------------
  186.97 +// Build a string of all file extensions supported
  186.98 +const aiImporterDesc* NDOImporter::GetInfo () const
  186.99 +{
 186.100 +	return &desc;
 186.101 +}
 186.102 +
 186.103 +// ------------------------------------------------------------------------------------------------
 186.104 +// Setup configuration properties for the loader
 186.105 +void NDOImporter::SetupProperties(const Importer* /*pImp*/)
 186.106 +{
 186.107 +	// nothing to be done for the moment
 186.108 +}
 186.109 +
 186.110 +// ------------------------------------------------------------------------------------------------
 186.111 +// Imports the given file into the given scene structure. 
 186.112 +void NDOImporter::InternReadFile( const std::string& pFile, 
 186.113 +	aiScene* pScene, IOSystem* pIOHandler)
 186.114 +{
 186.115 +	StreamReaderBE reader(pIOHandler->Open( pFile, "rb"));
 186.116 +
 186.117 +	// first 9 bytes are nendo file format ("nendo 1.n")
 186.118 +	const char* head = (const char*)reader.GetPtr();
 186.119 +	reader.IncPtr(9);
 186.120 +
 186.121 +	if (strncmp("nendo ",head,6)) {
 186.122 +		throw DeadlyImportError("Not a Nendo file; magic signature missing");
 186.123 +	}
 186.124 +	// check if this is a supported version. if not, continue, too -- users,
 186.125 +	// please don't complain if it doesn't work then ...
 186.126 +	unsigned int file_format = 12;
 186.127 +	if (!strncmp("1.0",head+6,3)) {
 186.128 +		file_format = 10;
 186.129 +		DefaultLogger::get()->info("NDO file format is 1.0");
 186.130 +	}
 186.131 +	else if (!strncmp("1.1",head+6,3)) {
 186.132 +		file_format = 11;
 186.133 +		DefaultLogger::get()->info("NDO file format is 1.1");
 186.134 +	}
 186.135 +	else if (!strncmp("1.2",head+6,3)) {
 186.136 +		file_format = 12;
 186.137 +		DefaultLogger::get()->info("NDO file format is 1.2");
 186.138 +	}
 186.139 +	else {
 186.140 +		DefaultLogger::get()->warn(std::string("Unrecognized nendo file format version, continuing happily ... :") + (head+6));
 186.141 +	}
 186.142 +
 186.143 +	reader.IncPtr(2); /* skip flags */
 186.144 +	if (file_format >= 12) {
 186.145 +		reader.IncPtr(2);
 186.146 +	}
 186.147 +	unsigned int temp = reader.GetU1();
 186.148 +
 186.149 +	std::vector<Object> objects(temp); /* buffer to store all the loaded objects in */
 186.150 +
 186.151 +	// read all objects
 186.152 +	for (unsigned int o = 0; o < objects.size(); ++o) {
 186.153 +		
 186.154 +//		if (file_format < 12) {
 186.155 +			if (!reader.GetI1()) {
 186.156 +				continue; /* skip over empty object */
 186.157 +			}
 186.158 +		//	reader.GetI2();
 186.159 +//		}
 186.160 +		Object& obj = objects[o];
 186.161 +
 186.162 +		temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.163 +		head = (const char*)reader.GetPtr();
 186.164 +		reader.IncPtr(temp + 76); /* skip unknown stuff */
 186.165 +
 186.166 +		obj.name = std::string(head, temp);
 186.167 +
 186.168 +		// read edge table
 186.169 +		temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.170 +		obj.edges.reserve(temp);
 186.171 +		for (unsigned int e = 0; e < temp; ++e) {
 186.172 +			
 186.173 +			obj.edges.push_back(Edge());
 186.174 +			Edge& edge = obj.edges.back();
 186.175 +
 186.176 +			for (unsigned int i = 0; i< 8; ++i) {
 186.177 +				edge.edge[i] = file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.178 +			}
 186.179 +			edge.hard =  file_format >= 11 ? reader.GetU1() : 0;
 186.180 +			for (unsigned int i = 0; i< 8; ++i) {
 186.181 +				edge.color[i] = reader.GetU1();
 186.182 +			}
 186.183 +		}
 186.184 +
 186.185 +		// read face table
 186.186 +		temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.187 +		obj.faces.reserve(temp);
 186.188 +		for (unsigned int e = 0; e < temp; ++e) {
 186.189 +			
 186.190 +			obj.faces.push_back(Face());
 186.191 +			Face& face = obj.faces.back();
 186.192 +
 186.193 +			face.elem = file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.194 +		}
 186.195 +
 186.196 +		// read vertex table
 186.197 +		temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.198 +		obj.vertices.reserve(temp);
 186.199 +		for (unsigned int e = 0; e < temp; ++e) {
 186.200 +			
 186.201 +			obj.vertices.push_back(Vertex());
 186.202 +			Vertex& v = obj.vertices.back();
 186.203 +
 186.204 +			v.num = file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.205 +			v.val.x = reader.GetF4();
 186.206 +			v.val.y = reader.GetF4();
 186.207 +			v.val.z = reader.GetF4();
 186.208 +		}
 186.209 +
 186.210 +		// read UVs
 186.211 +		temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.212 +		for (unsigned int e = 0; e < temp; ++e) {
 186.213 +			 file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.214 +		}
 186.215 +
 186.216 +		temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.217 +		for (unsigned int e = 0; e < temp; ++e) {
 186.218 +			 file_format >= 12 ? reader.GetU4() : reader.GetU2();
 186.219 +		}
 186.220 +
 186.221 +		if (reader.GetU1()) {
 186.222 +			const unsigned int x = reader.GetU2(), y = reader.GetU2();
 186.223 +			temp = 0;
 186.224 +			while (temp < x*y)  {
 186.225 +				unsigned int repeat = reader.GetU1();
 186.226 +				reader.GetU1();
 186.227 +				reader.GetU1();
 186.228 +				reader.GetU1();
 186.229 +				temp += repeat;
 186.230 +			}
 186.231 +		}
 186.232 +	}
 186.233 +
 186.234 +	// construct a dummy node graph and add all named objects as child nodes
 186.235 +	aiNode* root = pScene->mRootNode = new aiNode("$NDODummyRoot");
 186.236 +	aiNode** cc = root->mChildren = new aiNode* [ root->mNumChildren = static_cast<unsigned int>( objects.size()) ] ();
 186.237 +	pScene->mMeshes = new aiMesh* [ root->mNumChildren] ();
 186.238 +
 186.239 +	std::vector<aiVector3D> vertices;
 186.240 +	std::vector<unsigned int> indices;
 186.241 +
 186.242 +	for_each(const Object& obj,objects) {
 186.243 +		aiNode* nd = *cc++ = new aiNode(obj.name);
 186.244 +		nd->mParent = root;
 186.245 +
 186.246 +		// translated from a python dict() - a vector might be sufficient as well
 186.247 +		typedef std::map<unsigned int, unsigned int>  FaceTable;
 186.248 +		FaceTable face_table;
 186.249 +
 186.250 +		unsigned int n = 0;
 186.251 +		for_each(const Edge& edge, obj.edges) {
 186.252 +		
 186.253 +			face_table[edge.edge[2]] = n;
 186.254 +			face_table[edge.edge[3]] = n;
 186.255 +
 186.256 +			++n;
 186.257 +		}
 186.258 +
 186.259 +		aiMesh* mesh = new aiMesh();
 186.260 +		aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces=face_table.size()];
 186.261 +
 186.262 +		vertices.clear();
 186.263 +		vertices.reserve(4 * face_table.size()); // arbitrarily choosen 
 186.264 +		for_each(FaceTable::value_type& v, face_table) {
 186.265 +			indices.clear();
 186.266 +
 186.267 +			aiFace& f = *faces++;
 186.268 +		
 186.269 +			const unsigned int key = v.first;
 186.270 +			unsigned int cur_edge = v.second;
 186.271 +			while (1) {
 186.272 +				unsigned int next_edge, next_vert;
 186.273 +				if (key == obj.edges[cur_edge].edge[3]) {
 186.274 +					next_edge = obj.edges[cur_edge].edge[5];
 186.275 +					next_vert = obj.edges[cur_edge].edge[1];
 186.276 +				}
 186.277 +				else {
 186.278 +					next_edge = obj.edges[cur_edge].edge[4];
 186.279 +					next_vert = obj.edges[cur_edge].edge[0];
 186.280 +				}
 186.281 +				indices.push_back( vertices.size() );
 186.282 +				vertices.push_back(obj.vertices[ next_vert ].val);
 186.283 +
 186.284 +				cur_edge = next_edge;
 186.285 +				if (cur_edge == v.second) {
 186.286 +					break;
 186.287 +				}
 186.288 +			}
 186.289 +			
 186.290 +			f.mIndices = new unsigned int[f.mNumIndices = indices.size()];
 186.291 +			std::copy(indices.begin(),indices.end(),f.mIndices);
 186.292 +		}
 186.293 +
 186.294 +		mesh->mVertices = new aiVector3D[mesh->mNumVertices = vertices.size()];
 186.295 +		std::copy(vertices.begin(),vertices.end(),mesh->mVertices);
 186.296 +
 186.297 +		if (mesh->mNumVertices) {
 186.298 +			pScene->mMeshes[pScene->mNumMeshes] = mesh;
 186.299 +
 186.300 +			(nd->mMeshes = new unsigned int[nd->mNumMeshes=1])[0]=pScene->mNumMeshes++;
 186.301 +		}
 186.302 +	}
 186.303 +}
 186.304 +
 186.305 +#endif 
   187.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   187.2 +++ b/libs/assimp/NDOLoader.h	Sat Feb 01 19:58:19 2014 +0200
   187.3 @@ -0,0 +1,113 @@
   187.4 +/*
   187.5 +Open Asset Import Library (assimp)
   187.6 +----------------------------------------------------------------------
   187.7 +
   187.8 +Copyright (c) 2006-2008, assimp team
   187.9 +All rights reserved.
  187.10 +
  187.11 +Redistribution and use of this software in source and binary forms, 
  187.12 +with or without modification, are permitted provided that the 
  187.13 +following conditions are met:
  187.14 +
  187.15 +* Redistributions of source code must retain the above
  187.16 +  copyright notice, this list of conditions and the
  187.17 +  following disclaimer.
  187.18 +
  187.19 +* Redistributions in binary form must reproduce the above
  187.20 +  copyright notice, this list of conditions and the
  187.21 +  following disclaimer in the documentation and/or other
  187.22 +  materials provided with the distribution.
  187.23 +
  187.24 +* Neither the name of the assimp team, nor the names of its
  187.25 +  contributors may be used to endorse or promote products
  187.26 +  derived from this software without specific prior
  187.27 +  written permission of the assimp team.
  187.28 +
  187.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  187.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  187.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  187.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  187.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  187.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  187.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  187.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  187.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  187.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  187.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  187.40 +
  187.41 +----------------------------------------------------------------------
  187.42 +*/
  187.43 +
  187.44 +/** @file NDOLoader.h
  187.45 + *  Declaration of the Nendo importer class.
  187.46 + */
  187.47 +#ifndef INCLUDED_AI_NDO_LOADER_H
  187.48 +#define INCLUDED_AI_NDO_LOADER_H
  187.49 +namespace Assimp	{
  187.50 +
  187.51 +// ---------------------------------------------------------------------------
  187.52 +/** @brief Importer class to load meshes from Nendo.
  187.53 + *
  187.54 + *  Basing on
  187.55 + *  <blender>/blender/release/scripts/nendo_import.py by Anthony D'Agostino. 
  187.56 +*/
  187.57 +class NDOImporter : public BaseImporter
  187.58 +{
  187.59 +public:
  187.60 +	NDOImporter();
  187.61 +	~NDOImporter();
  187.62 +
  187.63 +
  187.64 +public:
  187.65 +
  187.66 +	//! Represents a single edge
  187.67 +	struct Edge
  187.68 +	{
  187.69 +		unsigned int edge[8];
  187.70 +		unsigned int hard;
  187.71 +		uint8_t color[8];
  187.72 +	};
  187.73 +
  187.74 +	//! Represents a single face
  187.75 +	struct Face
  187.76 +	{
  187.77 +		unsigned int elem;
  187.78 +	};
  187.79 +
  187.80 +	struct Vertex
  187.81 +	{
  187.82 +		unsigned int num;
  187.83 +		aiVector3D val;
  187.84 +	};
  187.85 +
  187.86 +	//! Represents a single object
  187.87 +	struct Object 
  187.88 +	{
  187.89 +		std::string name;
  187.90 +	
  187.91 +		std::vector<Edge> edges;
  187.92 +		std::vector<Face> faces;
  187.93 +		std::vector<Vertex> vertices;
  187.94 +	};
  187.95 +
  187.96 +	// -------------------------------------------------------------------
  187.97 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, 
  187.98 +		bool checkSig) const;
  187.99 +
 187.100 +protected:
 187.101 +
 187.102 +	// -------------------------------------------------------------------
 187.103 +	const aiImporterDesc* GetInfo () const;
 187.104 +
 187.105 +	// -------------------------------------------------------------------
 187.106 +	void SetupProperties(const Importer* pImp);
 187.107 +
 187.108 +	// -------------------------------------------------------------------
 187.109 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
 187.110 +		IOSystem* pIOHandler);
 187.111 +
 187.112 +private:
 187.113 +
 187.114 +}; // end of class NDOImporter
 187.115 +} // end of namespace Assimp
 187.116 +#endif // INCLUDED_AI_NDO_LOADER_H
   188.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   188.2 +++ b/libs/assimp/NFFLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   188.3 @@ -0,0 +1,1268 @@
   188.4 +/*
   188.5 +---------------------------------------------------------------------------
   188.6 +Open Asset Import Library (assimp)
   188.7 +---------------------------------------------------------------------------
   188.8 +
   188.9 +Copyright (c) 2006-2012, assimp team
  188.10 +
  188.11 +All rights reserved.
  188.12 +
  188.13 +Redistribution and use of this software in source and binary forms, 
  188.14 +with or without modification, are permitted provided that the following 
  188.15 +conditions are met:
  188.16 +
  188.17 +* Redistributions of source code must retain the above
  188.18 +  copyright notice, this list of conditions and the
  188.19 +  following disclaimer.
  188.20 +
  188.21 +* Redistributions in binary form must reproduce the above
  188.22 +  copyright notice, this list of conditions and the
  188.23 +  following disclaimer in the documentation and/or other
  188.24 +  materials provided with the distribution.
  188.25 +
  188.26 +* Neither the name of the assimp team, nor the names of its
  188.27 +  contributors may be used to endorse or promote products
  188.28 +  derived from this software without specific prior
  188.29 +  written permission of the assimp team.
  188.30 +
  188.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  188.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  188.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  188.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  188.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  188.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  188.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  188.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  188.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  188.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  188.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  188.42 +---------------------------------------------------------------------------
  188.43 +*/
  188.44 +
  188.45 +/** @file Implementation of the STL importer class */
  188.46 +
  188.47 +#include "AssimpPCH.h"
  188.48 +#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER
  188.49 +
  188.50 +// internal headers
  188.51 +#include "NFFLoader.h"
  188.52 +#include "ParsingUtils.h"
  188.53 +#include "StandardShapes.h"
  188.54 +#include "fast_atof.h"
  188.55 +#include "RemoveComments.h"
  188.56 +
  188.57 +using namespace Assimp;
  188.58 +
  188.59 +static const aiImporterDesc desc = {
  188.60 +	"Neutral File Format Importer",
  188.61 +	"",
  188.62 +	"",
  188.63 +	"",
  188.64 +	aiImporterFlags_SupportBinaryFlavour,
  188.65 +	0,
  188.66 +	0,
  188.67 +	0,
  188.68 +	0,
  188.69 +	"enff nff" 
  188.70 +};
  188.71 +
  188.72 +// ------------------------------------------------------------------------------------------------
  188.73 +// Constructor to be privately used by Importer
  188.74 +NFFImporter::NFFImporter()
  188.75 +{}
  188.76 +
  188.77 +// ------------------------------------------------------------------------------------------------
  188.78 +// Destructor, private as well 
  188.79 +NFFImporter::~NFFImporter()
  188.80 +{}
  188.81 +
  188.82 +// ------------------------------------------------------------------------------------------------
  188.83 +// Returns whether the class can handle the format of the given file. 
  188.84 +bool NFFImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
  188.85 +{
  188.86 +	return SimpleExtensionCheck(pFile,"nff","enff");
  188.87 +}
  188.88 +
  188.89 +// ------------------------------------------------------------------------------------------------
  188.90 +// Get the list of all supported file extensions
  188.91 +const aiImporterDesc* NFFImporter::GetInfo () const
  188.92 +{
  188.93 +	return &desc;
  188.94 +}
  188.95 +
  188.96 +// ------------------------------------------------------------------------------------------------
  188.97 +#define AI_NFF_PARSE_FLOAT(f) \
  188.98 +	SkipSpaces(&sz); \
  188.99 +	if (!::IsLineEnd(*sz))sz = fast_atoreal_move<float>(sz, (float&)f); 
 188.100 +
 188.101 +// ------------------------------------------------------------------------------------------------
 188.102 +#define AI_NFF_PARSE_TRIPLE(v) \
 188.103 +	AI_NFF_PARSE_FLOAT(v[0]) \
 188.104 +	AI_NFF_PARSE_FLOAT(v[1]) \
 188.105 +	AI_NFF_PARSE_FLOAT(v[2]) 
 188.106 +
 188.107 +// ------------------------------------------------------------------------------------------------
 188.108 +#define AI_NFF_PARSE_SHAPE_INFORMATION() \
 188.109 +	aiVector3D center, radius(1.0f,get_qnan(),get_qnan()); \
 188.110 +	AI_NFF_PARSE_TRIPLE(center); \
 188.111 +	AI_NFF_PARSE_TRIPLE(radius); \
 188.112 +	if (is_qnan(radius.z))radius.z = radius.x; \
 188.113 +	if (is_qnan(radius.y))radius.y = radius.x; \
 188.114 +	currentMesh.radius = radius; \
 188.115 +	currentMesh.center = center;
 188.116 +
 188.117 +// ------------------------------------------------------------------------------------------------
 188.118 +#define AI_NFF2_GET_NEXT_TOKEN() \
 188.119 +	do \
 188.120 +	{ \
 188.121 +	if (!GetNextLine(buffer,line)) \
 188.122 +		{DefaultLogger::get()->warn("NFF2: Unexpected EOF, can't read next token");break;} \
 188.123 +	SkipSpaces(line,&sz); \
 188.124 +	} \
 188.125 +	while(IsLineEnd(*sz))
 188.126 +
 188.127 +
 188.128 +// ------------------------------------------------------------------------------------------------
 188.129 +// Loads the materail table for the NFF2 file format from an external file
 188.130 +void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo>& output,
 188.131 +	const std::string& path, IOSystem* pIOHandler)
 188.132 +{
 188.133 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( path, "rb"));
 188.134 +
 188.135 +	// Check whether we can read from the file
 188.136 +	if( !file.get())	{
 188.137 +		DefaultLogger::get()->error("NFF2: Unable to open material library " + path + ".");
 188.138 +		return;
 188.139 +	}
 188.140 +
 188.141 +	// get the size of the file
 188.142 +	const unsigned int m = (unsigned int)file->FileSize();
 188.143 +
 188.144 +	// allocate storage and copy the contents of the file to a memory buffer
 188.145 +	// (terminate it with zero)
 188.146 +	std::vector<char> mBuffer2(m+1);
 188.147 +	TextFileToBuffer(file.get(),mBuffer2);
 188.148 +	const char* buffer = &mBuffer2[0];
 188.149 +
 188.150 +	// First of all: remove all comments from the file
 188.151 +	CommentRemover::RemoveLineComments("//",&mBuffer2[0]);
 188.152 +
 188.153 +	// The file should start with the magic sequence "mat"
 188.154 +	if (!TokenMatch(buffer,"mat",3))	{
 188.155 +		DefaultLogger::get()->error("NFF2: Not a valid material library " + path + ".");
 188.156 +		return;
 188.157 +	}
 188.158 +
 188.159 +	ShadingInfo* curShader = NULL;
 188.160 +
 188.161 +	// No read the file line per line
 188.162 +	char line[4096];
 188.163 +	const char* sz;
 188.164 +	while (GetNextLine(buffer,line))
 188.165 +	{
 188.166 +		SkipSpaces(line,&sz);
 188.167 +
 188.168 +		// 'version' defines the version of the file format
 188.169 +		if (TokenMatch(sz,"version",7))
 188.170 +		{
 188.171 +			DefaultLogger::get()->info("NFF (Sense8) material library file format: " + std::string(sz));
 188.172 +		}
 188.173 +		// 'matdef' starts a new material in the file
 188.174 +		else if (TokenMatch(sz,"matdef",6))
 188.175 +		{
 188.176 +			// add a new material to the list
 188.177 +			output.push_back( ShadingInfo() );
 188.178 +			curShader = & output.back();
 188.179 +
 188.180 +			// parse the name of the material
 188.181 +		}
 188.182 +		else if (!TokenMatch(sz,"valid",5))
 188.183 +		{
 188.184 +			// check whether we have an active material at the moment
 188.185 +			if (!IsLineEnd(*sz))
 188.186 +			{
 188.187 +				if (!curShader)
 188.188 +				{
 188.189 +					DefaultLogger::get()->error(std::string("NFF2 material library: Found element ") + 
 188.190 +						sz + "but there is no active material");
 188.191 +					continue;
 188.192 +				}
 188.193 +			}
 188.194 +			else continue;
 188.195 +
 188.196 +			// now read the material property and determine its type
 188.197 +			aiColor3D c;
 188.198 +			if (TokenMatch(sz,"ambient",7))
 188.199 +			{
 188.200 +				AI_NFF_PARSE_TRIPLE(c);
 188.201 +				curShader->ambient = c;
 188.202 +			}
 188.203 +			else if (TokenMatch(sz,"diffuse",7) || TokenMatch(sz,"ambientdiffuse",14) /* correct? */)
 188.204 +			{
 188.205 +				AI_NFF_PARSE_TRIPLE(c);
 188.206 +				curShader->diffuse = curShader->ambient = c;
 188.207 +			}
 188.208 +			else if (TokenMatch(sz,"specular",8))
 188.209 +			{
 188.210 +				AI_NFF_PARSE_TRIPLE(c);
 188.211 +				curShader->specular = c;
 188.212 +			}
 188.213 +			else if (TokenMatch(sz,"emission",8))
 188.214 +			{
 188.215 +				AI_NFF_PARSE_TRIPLE(c);
 188.216 +				curShader->emissive = c;
 188.217 +			}
 188.218 +			else if (TokenMatch(sz,"shininess",9))
 188.219 +			{
 188.220 +				AI_NFF_PARSE_FLOAT(curShader->shininess);
 188.221 +			}
 188.222 +			else if (TokenMatch(sz,"opacity",7))
 188.223 +			{
 188.224 +				AI_NFF_PARSE_FLOAT(curShader->opacity);
 188.225 +			}
 188.226 +		}
 188.227 +	}
 188.228 +}
 188.229 +
 188.230 +// ------------------------------------------------------------------------------------------------
 188.231 +// Imports the given file into the given scene structure. 
 188.232 +void NFFImporter::InternReadFile( const std::string& pFile, 
 188.233 +	aiScene* pScene, IOSystem* pIOHandler)
 188.234 +{
 188.235 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 188.236 +
 188.237 +	// Check whether we can read from the file
 188.238 +	if( !file.get())
 188.239 +		throw DeadlyImportError( "Failed to open NFF file " + pFile + ".");
 188.240 +
 188.241 +	unsigned int m = (unsigned int)file->FileSize();
 188.242 +
 188.243 +	// allocate storage and copy the contents of the file to a memory buffer
 188.244 +	// (terminate it with zero)
 188.245 +	std::vector<char> mBuffer2;
 188.246 +	TextFileToBuffer(file.get(),mBuffer2);
 188.247 +	const char* buffer = &mBuffer2[0];
 188.248 +
 188.249 +	// mesh arrays - separate here to make the handling of the pointers below easier.
 188.250 +	std::vector<MeshInfo> meshes;
 188.251 +	std::vector<MeshInfo> meshesWithNormals;
 188.252 +	std::vector<MeshInfo> meshesWithUVCoords;
 188.253 +	std::vector<MeshInfo> meshesLocked;
 188.254 +
 188.255 +	char line[4096];
 188.256 +	const char* sz;
 188.257 +
 188.258 +	// camera parameters
 188.259 +	aiVector3D camPos, camUp(0.f,1.f,0.f), camLookAt(0.f,0.f,1.f);
 188.260 +	float angle = 45.f;
 188.261 +	aiVector2D resolution;
 188.262 +
 188.263 +	bool hasCam = false;
 188.264 +
 188.265 +	MeshInfo* currentMeshWithNormals = NULL;
 188.266 +	MeshInfo* currentMesh = NULL;
 188.267 +	MeshInfo* currentMeshWithUVCoords = NULL;
 188.268 +
 188.269 +	ShadingInfo s; // current material info
 188.270 +
 188.271 +	// degree of tesselation
 188.272 +	unsigned int iTesselation = 4;
 188.273 +
 188.274 +	// some temporary variables we need to parse the file
 188.275 +	unsigned int sphere		= 0,
 188.276 +		cylinder			= 0,
 188.277 +		cone				= 0,
 188.278 +		numNamed			= 0,
 188.279 +		dodecahedron		= 0,
 188.280 +		octahedron			= 0,
 188.281 +		tetrahedron			= 0,
 188.282 +		hexahedron			= 0;
 188.283 +
 188.284 +	// lights imported from the file
 188.285 +	std::vector<Light> lights;
 188.286 +
 188.287 +	// check whether this is the NFF2 file format
 188.288 +	if (TokenMatch(buffer,"nff",3))
 188.289 +	{
 188.290 +		const float qnan = get_qnan();
 188.291 +		const aiColor4D  cQNAN = aiColor4D (qnan,0.f,0.f,1.f);
 188.292 +		const aiVector3D vQNAN = aiVector3D(qnan,0.f,0.f);
 188.293 +
 188.294 +		// another NFF file format ... just a raw parser has been implemented
 188.295 +		// no support for further details, I don't think it is worth the effort
 188.296 +		// http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/nff/nff2.html
 188.297 +		// http://www.netghost.narod.ru/gff/graphics/summary/sense8.htm
 188.298 +
 188.299 +		// First of all: remove all comments from the file
 188.300 +		CommentRemover::RemoveLineComments("//",&mBuffer2[0]);
 188.301 +
 188.302 +		while (GetNextLine(buffer,line))
 188.303 +		{
 188.304 +			SkipSpaces(line,&sz);
 188.305 +			if (TokenMatch(sz,"version",7))
 188.306 +			{
 188.307 +				DefaultLogger::get()->info("NFF (Sense8) file format: " + std::string(sz));
 188.308 +			}
 188.309 +			else if (TokenMatch(sz,"viewpos",7))
 188.310 +			{
 188.311 +				AI_NFF_PARSE_TRIPLE(camPos);
 188.312 +				hasCam = true;
 188.313 +			}
 188.314 +			else if (TokenMatch(sz,"viewdir",7))
 188.315 +			{
 188.316 +				AI_NFF_PARSE_TRIPLE(camLookAt);
 188.317 +				hasCam = true;
 188.318 +			}
 188.319 +			// This starts a new object section
 188.320 +			else if (!IsSpaceOrNewLine(*sz))
 188.321 +			{
 188.322 +				unsigned int subMeshIdx = 0;
 188.323 +
 188.324 +				// read the name of the object, skip all spaces
 188.325 +				// at the end of it.
 188.326 +				const char* sz3 = sz;
 188.327 +				while (!IsSpaceOrNewLine(*sz))++sz;
 188.328 +				std::string objectName = std::string(sz3,(unsigned int)(sz-sz3));
 188.329 +
 188.330 +				const unsigned int objStart = (unsigned int)meshes.size();
 188.331 +
 188.332 +				// There could be a material table in a separate file
 188.333 +				std::vector<ShadingInfo> materialTable;
 188.334 +				while (true)
 188.335 +				{
 188.336 +					AI_NFF2_GET_NEXT_TOKEN();
 188.337 +
 188.338 +					// material table - an external file
 188.339 +					if (TokenMatch(sz,"mtable",6))
 188.340 +					{
 188.341 +						SkipSpaces(&sz);
 188.342 +						sz3 = sz;
 188.343 +						while (!IsSpaceOrNewLine(*sz))++sz;
 188.344 +						const unsigned int diff = (unsigned int)(sz-sz3);
 188.345 +						if (!diff)DefaultLogger::get()->warn("NFF2: Found empty mtable token");
 188.346 +						else 
 188.347 +						{
 188.348 +							// The material table has the file extension .mat.
 188.349 +							// If it is not there, we need to append it
 188.350 +							std::string path = std::string(sz3,diff);
 188.351 +							if(std::string::npos == path.find_last_of(".mat"))
 188.352 +							{
 188.353 +								path.append(".mat");
 188.354 +							}
 188.355 +
 188.356 +							// Now extract the working directory from the path to
 188.357 +							// this file and append the material library filename 
 188.358 +							// to it.
 188.359 +							std::string::size_type s;
 188.360 +							if ((std::string::npos == (s = path.find_last_of('\\')) || !s) &&
 188.361 +								(std::string::npos == (s = path.find_last_of('/'))  || !s) )
 188.362 +							{
 188.363 +								s = pFile.find_last_of('\\');
 188.364 +								if (std::string::npos == s)s = pFile.find_last_of('/');
 188.365 +								if (std::string::npos != s)
 188.366 +								{
 188.367 +									path = pFile.substr(0,s+1) + path;
 188.368 +								}
 188.369 +							}
 188.370 +							LoadNFF2MaterialTable(materialTable,path,pIOHandler);
 188.371 +						}
 188.372 +					}
 188.373 +					else break;
 188.374 +				}
 188.375 +
 188.376 +				// read the numbr of vertices
 188.377 +				unsigned int num = ::strtoul10(sz,&sz);
 188.378 +				
 188.379 +				// temporary storage
 188.380 +				std::vector<aiColor4D>  tempColors;
 188.381 +				std::vector<aiVector3D> tempPositions,tempTextureCoords,tempNormals;
 188.382 +
 188.383 +				bool hasNormals = false,hasUVs = false,hasColor = false;
 188.384 +
 188.385 +				tempPositions.reserve      (num);
 188.386 +				tempColors.reserve         (num);
 188.387 +				tempNormals.reserve        (num);
 188.388 +				tempTextureCoords.reserve  (num);
 188.389 +				for (unsigned int i = 0; i < num; ++i)
 188.390 +				{
 188.391 +					AI_NFF2_GET_NEXT_TOKEN();
 188.392 +					aiVector3D v;
 188.393 +					AI_NFF_PARSE_TRIPLE(v);
 188.394 +					tempPositions.push_back(v);
 188.395 +
 188.396 +					// parse all other attributes in the line
 188.397 +					while (true)
 188.398 +					{
 188.399 +						SkipSpaces(&sz);
 188.400 +						if (IsLineEnd(*sz))break;
 188.401 +
 188.402 +						// color definition
 188.403 +						if (TokenMatch(sz,"0x",2))
 188.404 +						{
 188.405 +							hasColor = true;
 188.406 +							register unsigned int numIdx = ::strtoul16(sz,&sz);
 188.407 +							aiColor4D clr;
 188.408 +							clr.a = 1.f;
 188.409 +
 188.410 +							// 0xRRGGBB
 188.411 +							clr.r = ((numIdx >> 16u) & 0xff) / 255.f;
 188.412 +							clr.g = ((numIdx >> 8u)  & 0xff) / 255.f;
 188.413 +							clr.b = ((numIdx)        & 0xff) / 255.f;
 188.414 +							tempColors.push_back(clr);
 188.415 +						}
 188.416 +						// normal vector
 188.417 +						else if (TokenMatch(sz,"norm",4))
 188.418 +						{
 188.419 +							hasNormals = true;
 188.420 +							AI_NFF_PARSE_TRIPLE(v);
 188.421 +							tempNormals.push_back(v);
 188.422 +						}
 188.423 +						// UV coordinate
 188.424 +						else if (TokenMatch(sz,"uv",2))
 188.425 +						{
 188.426 +							hasUVs = true;
 188.427 +							AI_NFF_PARSE_FLOAT(v.x);
 188.428 +							AI_NFF_PARSE_FLOAT(v.y);
 188.429 +							v.z = 0.f;
 188.430 +							tempTextureCoords.push_back(v);
 188.431 +						}
 188.432 +					}
 188.433 +
 188.434 +					// fill in dummies for all attributes that have not been set
 188.435 +					if (tempNormals.size() != tempPositions.size())
 188.436 +						tempNormals.push_back(vQNAN);
 188.437 +
 188.438 +					if (tempTextureCoords.size() != tempPositions.size())
 188.439 +						tempTextureCoords.push_back(vQNAN);
 188.440 +
 188.441 +					if (tempColors.size() != tempPositions.size())
 188.442 +						tempColors.push_back(cQNAN);
 188.443 +				}
 188.444 +
 188.445 +				AI_NFF2_GET_NEXT_TOKEN();
 188.446 +				if (!num)throw DeadlyImportError("NFF2: There are zero vertices");
 188.447 +				num = ::strtoul10(sz,&sz);
 188.448 +
 188.449 +				std::vector<unsigned int> tempIdx;
 188.450 +				tempIdx.reserve(10);
 188.451 +				for (unsigned int i = 0; i < num; ++i)
 188.452 +				{
 188.453 +					AI_NFF2_GET_NEXT_TOKEN();
 188.454 +					SkipSpaces(line,&sz);
 188.455 +					unsigned int numIdx = ::strtoul10(sz,&sz);
 188.456 +
 188.457 +					// read all faces indices
 188.458 +					if (numIdx)
 188.459 +					{
 188.460 +						// mesh.faces.push_back(numIdx);
 188.461 +						// tempIdx.erase(tempIdx.begin(),tempIdx.end());
 188.462 +						tempIdx.resize(numIdx);
 188.463 +
 188.464 +						for (unsigned int a = 0; a < numIdx;++a)
 188.465 +						{
 188.466 +							SkipSpaces(sz,&sz);
 188.467 +							m = ::strtoul10(sz,&sz);
 188.468 +							if (m >= (unsigned int)tempPositions.size())
 188.469 +							{
 188.470 +								DefaultLogger::get()->error("NFF2: Vertex index overflow");
 188.471 +								m= 0;
 188.472 +							}
 188.473 +							// mesh.vertices.push_back (tempPositions[idx]);
 188.474 +							tempIdx[a] = m;
 188.475 +						}
 188.476 +					}
 188.477 +
 188.478 +					// build a temporary shader object for the face. 
 188.479 +					ShadingInfo shader;
 188.480 +					unsigned int matIdx = 0;
 188.481 +
 188.482 +					// white material color - we have vertex colors
 188.483 +					shader.color = aiColor3D(1.f,1.f,1.f); 
 188.484 +					aiColor4D c  = aiColor4D(1.f,1.f,1.f,1.f);
 188.485 +					while (true)
 188.486 +					{
 188.487 +						SkipSpaces(sz,&sz);
 188.488 +						if(IsLineEnd(*sz))break;
 188.489 +
 188.490 +						// per-polygon colors
 188.491 +						if (TokenMatch(sz,"0x",2))
 188.492 +						{
 188.493 +							hasColor = true;
 188.494 +							const char* sz2 = sz;
 188.495 +							numIdx = ::strtoul16(sz,&sz);
 188.496 +							const unsigned int diff = (unsigned int)(sz-sz2);
 188.497 +
 188.498 +							// 0xRRGGBB
 188.499 +							if (diff > 3)
 188.500 +							{
 188.501 +								c.r = ((numIdx >> 16u) & 0xff) / 255.f;
 188.502 +								c.g = ((numIdx >> 8u)  & 0xff) / 255.f;
 188.503 +								c.b = ((numIdx)        & 0xff) / 255.f;
 188.504 +							}
 188.505 +							// 0xRGB
 188.506 +							else
 188.507 +							{
 188.508 +								c.r = ((numIdx >> 8u) & 0xf) / 16.f;
 188.509 +								c.g = ((numIdx >> 4u) & 0xf) / 16.f;
 188.510 +								c.b = ((numIdx)       & 0xf) / 16.f;
 188.511 +							}
 188.512 +						}
 188.513 +						// TODO - implement texture mapping here
 188.514 +#if 0
 188.515 +						// mirror vertex texture coordinate?
 188.516 +						else if (TokenMatch(sz,"mirror",6))
 188.517 +						{
 188.518 +						}
 188.519 +						// texture coordinate scaling
 188.520 +						else if (TokenMatch(sz,"scale",5))
 188.521 +						{
 188.522 +						}
 188.523 +						// texture coordinate translation
 188.524 +						else if (TokenMatch(sz,"trans",5))
 188.525 +						{
 188.526 +						}
 188.527 +						// texture coordinate rotation angle
 188.528 +						else if (TokenMatch(sz,"rot",3))
 188.529 +						{
 188.530 +						}
 188.531 +#endif
 188.532 +
 188.533 +						// texture file name for this polygon + mapping information
 188.534 +						else if ('_' == sz[0])
 188.535 +						{
 188.536 +							// get mapping information
 188.537 +							switch (sz[1])
 188.538 +							{
 188.539 +							case 'v':
 188.540 +							case 'V':
 188.541 +
 188.542 +								shader.shaded = false;
 188.543 +								break;
 188.544 +
 188.545 +							case 't':
 188.546 +							case 'T':
 188.547 +							case 'u':
 188.548 +							case 'U':
 188.549 +
 188.550 +								DefaultLogger::get()->warn("Unsupported NFF2 texture attribute: trans");
 188.551 +							};
 188.552 +							if (!sz[1] || '_' != sz[2])
 188.553 +							{
 188.554 +								DefaultLogger::get()->warn("NFF2: Expected underscore after texture attributes");
 188.555 +								continue;
 188.556 +							}
 188.557 +							const char* sz2 = sz+3;
 188.558 +							while (!IsSpaceOrNewLine( *sz ))++sz;
 188.559 +							const unsigned int diff = (unsigned int)(sz-sz2);
 188.560 +							if (diff)shader.texFile = std::string(sz2,diff);
 188.561 +						}
 188.562 +
 188.563 +						// Two-sided material?
 188.564 +						else if (TokenMatch(sz,"both",4))
 188.565 +						{
 188.566 +							shader.twoSided = true;
 188.567 +						}
 188.568 +
 188.569 +						// Material ID?
 188.570 +						else if (!materialTable.empty() && TokenMatch(sz,"matid",5))
 188.571 +						{
 188.572 +							SkipSpaces(&sz);
 188.573 +							matIdx = ::strtoul10(sz,&sz);
 188.574 +							if (matIdx >= materialTable.size())
 188.575 +							{
 188.576 +								DefaultLogger::get()->error("NFF2: Material index overflow.");
 188.577 +								matIdx = 0;
 188.578 +							}
 188.579 +
 188.580 +							// now combine our current shader with the shader we
 188.581 +							// read from the material table.
 188.582 +							ShadingInfo& mat = materialTable[matIdx];
 188.583 +							shader.ambient   = mat.ambient;
 188.584 +							shader.diffuse   = mat.diffuse;
 188.585 +							shader.emissive  = mat.emissive;
 188.586 +							shader.opacity   = mat.opacity;
 188.587 +							shader.specular  = mat.specular;
 188.588 +							shader.shininess = mat.shininess;
 188.589 +						}
 188.590 +						else SkipToken(sz);
 188.591 +					}
 188.592 +
 188.593 +					// search the list of all shaders we have for this object whether
 188.594 +					// there is an identical one. In this case, we append our mesh
 188.595 +					// data to it.
 188.596 +					MeshInfo* mesh = NULL;
 188.597 +					for (std::vector<MeshInfo>::iterator it = meshes.begin() + objStart, end = meshes.end();
 188.598 +						 it != end; ++it)
 188.599 +					{
 188.600 +						if ((*it).shader == shader && (*it).matIndex == matIdx)
 188.601 +						{
 188.602 +							// we have one, we can append our data to it
 188.603 +							mesh = &(*it);
 188.604 +						}
 188.605 +					}
 188.606 +					if (!mesh)
 188.607 +					{
 188.608 +						meshes.push_back(MeshInfo(PatchType_Simple,false));
 188.609 +						mesh = &meshes.back();
 188.610 +						mesh->matIndex = matIdx;
 188.611 +
 188.612 +						// We need to add a new mesh to the list. We assign
 188.613 +						// an unique name to it to make sure the scene will
 188.614 +						// pass the validation step for the moment.
 188.615 +						// TODO: fix naming of objects in the scenegraph later
 188.616 +						if (objectName.length())
 188.617 +						{
 188.618 +							::strcpy(mesh->name,objectName.c_str()); 
 188.619 +							ASSIMP_itoa10(&mesh->name[objectName.length()],30,subMeshIdx++);
 188.620 +						}
 188.621 +
 188.622 +						// copy the shader to the mesh. 
 188.623 +						mesh->shader = shader;
 188.624 +					}
 188.625 +
 188.626 +					// fill the mesh with data
 188.627 +					if (!tempIdx.empty())
 188.628 +					{
 188.629 +						mesh->faces.push_back((unsigned int)tempIdx.size());
 188.630 +						for (std::vector<unsigned int>::const_iterator it = tempIdx.begin(), end = tempIdx.end();
 188.631 +							it != end;++it)
 188.632 +						{
 188.633 +							m = *it;
 188.634 +
 188.635 +							// copy colors -vertex color specifications override polygon color specifications
 188.636 +							if (hasColor)
 188.637 +							{
 188.638 +								const aiColor4D& clr = tempColors[m];
 188.639 +								mesh->colors.push_back((is_qnan( clr.r ) ? c : clr));
 188.640 +							}
 188.641 +
 188.642 +							// positions should always be there
 188.643 +							mesh->vertices.push_back (tempPositions[m]);
 188.644 +
 188.645 +							// copy normal vectors
 188.646 +							if (hasNormals)
 188.647 +								mesh->normals.push_back  (tempNormals[m]);
 188.648 +
 188.649 +							// copy texture coordinates
 188.650 +							if (hasUVs)
 188.651 +								mesh->uvs.push_back      (tempTextureCoords[m]);
 188.652 +						}
 188.653 +					}
 188.654 +				}
 188.655 +				if (!num)throw DeadlyImportError("NFF2: There are zero faces");
 188.656 +			}
 188.657 +		}
 188.658 +		camLookAt = camLookAt + camPos;
 188.659 +	}
 188.660 +	else // "Normal" Neutral file format that is quite more common
 188.661 +	{
 188.662 +		while (GetNextLine(buffer,line))
 188.663 +		{
 188.664 +			sz = line;
 188.665 +			if ('p' == line[0] || TokenMatch(sz,"tpp",3))
 188.666 +			{
 188.667 +				MeshInfo* out = NULL;
 188.668 +
 188.669 +				// 'tpp' - texture polygon patch primitive
 188.670 +				if ('t' == line[0])
 188.671 +				{
 188.672 +					currentMeshWithUVCoords = NULL;
 188.673 +					for (std::vector<MeshInfo>::iterator it = meshesWithUVCoords.begin(), end = meshesWithUVCoords.end();
 188.674 +						it != end;++it)
 188.675 +					{
 188.676 +						if ((*it).shader == s)
 188.677 +						{
 188.678 +							currentMeshWithUVCoords = &(*it);
 188.679 +							break;
 188.680 +						}
 188.681 +					}
 188.682 +
 188.683 +					if (!currentMeshWithUVCoords)
 188.684 +					{
 188.685 +						meshesWithUVCoords.push_back(MeshInfo(PatchType_UVAndNormals));
 188.686 +						currentMeshWithUVCoords = &meshesWithUVCoords.back();
 188.687 +						currentMeshWithUVCoords->shader = s;
 188.688 +					}
 188.689 +					out = currentMeshWithUVCoords;
 188.690 +				}
 188.691 +				// 'pp' - polygon patch primitive
 188.692 +				else if ('p' == line[1])
 188.693 +				{
 188.694 +					currentMeshWithNormals = NULL;
 188.695 +					for (std::vector<MeshInfo>::iterator it = meshesWithNormals.begin(), end = meshesWithNormals.end();
 188.696 +						it != end;++it)
 188.697 +					{
 188.698 +						if ((*it).shader == s)
 188.699 +						{
 188.700 +							currentMeshWithNormals = &(*it);
 188.701 +							break;
 188.702 +						}
 188.703 +					}
 188.704 +
 188.705 +					if (!currentMeshWithNormals)
 188.706 +					{
 188.707 +						meshesWithNormals.push_back(MeshInfo(PatchType_Normals));
 188.708 +						currentMeshWithNormals = &meshesWithNormals.back();
 188.709 +						currentMeshWithNormals->shader = s;
 188.710 +					}
 188.711 +					sz = &line[2];out = currentMeshWithNormals;
 188.712 +				}
 188.713 +				// 'p' - polygon primitive
 188.714 +				else
 188.715 +				{
 188.716 +					currentMesh = NULL;
 188.717 +					for (std::vector<MeshInfo>::iterator it = meshes.begin(), end = meshes.end();
 188.718 +						it != end;++it)
 188.719 +					{
 188.720 +						if ((*it).shader == s)
 188.721 +						{
 188.722 +							currentMesh = &(*it);
 188.723 +							break;
 188.724 +						}
 188.725 +					}
 188.726 +
 188.727 +					if (!currentMesh)
 188.728 +					{
 188.729 +						meshes.push_back(MeshInfo(PatchType_Simple));
 188.730 +						currentMesh = &meshes.back();
 188.731 +						currentMesh->shader = s;
 188.732 +					}
 188.733 +					sz = &line[1];out = currentMesh;
 188.734 +				}
 188.735 +				SkipSpaces(sz,&sz);
 188.736 +				m = strtoul10(sz);
 188.737 +
 188.738 +				// ---- flip the face order
 188.739 +				out->vertices.resize(out->vertices.size()+m);
 188.740 +				if (out != currentMesh)
 188.741 +				{
 188.742 +					out->normals.resize(out->vertices.size());
 188.743 +				}
 188.744 +				if (out == currentMeshWithUVCoords)
 188.745 +				{
 188.746 +					out->uvs.resize(out->vertices.size());
 188.747 +				}
 188.748 +				for (unsigned int n = 0; n < m;++n)
 188.749 +				{
 188.750 +					if(!GetNextLine(buffer,line))
 188.751 +					{
 188.752 +						DefaultLogger::get()->error("NFF: Unexpected EOF was encountered. Patch definition incomplete");
 188.753 +						continue;
 188.754 +					}
 188.755 +
 188.756 +					aiVector3D v; sz = &line[0];
 188.757 +					AI_NFF_PARSE_TRIPLE(v);
 188.758 +					out->vertices[out->vertices.size()-n-1] = v;
 188.759 +
 188.760 +					if (out != currentMesh)
 188.761 +					{
 188.762 +						AI_NFF_PARSE_TRIPLE(v);
 188.763 +						out->normals[out->vertices.size()-n-1] = v;
 188.764 +					}
 188.765 +					if (out == currentMeshWithUVCoords)
 188.766 +					{
 188.767 +						// FIX: in one test file this wraps over multiple lines
 188.768 +						SkipSpaces(&sz);
 188.769 +						if (IsLineEnd(*sz))
 188.770 +						{
 188.771 +							GetNextLine(buffer,line);
 188.772 +							sz = line;
 188.773 +						}
 188.774 +						AI_NFF_PARSE_FLOAT(v.x);
 188.775 +						SkipSpaces(&sz);
 188.776 +						if (IsLineEnd(*sz))
 188.777 +						{
 188.778 +							GetNextLine(buffer,line);
 188.779 +							sz = line;
 188.780 +						}
 188.781 +						AI_NFF_PARSE_FLOAT(v.y);
 188.782 +						v.y = 1.f - v.y;
 188.783 +						out->uvs[out->vertices.size()-n-1] = v;
 188.784 +					}
 188.785 +				}
 188.786 +				out->faces.push_back(m);
 188.787 +			}
 188.788 +			// 'f' - shading information block
 188.789 +			else if (TokenMatch(sz,"f",1))
 188.790 +			{
 188.791 +				float d;
 188.792 +
 188.793 +				// read the RGB colors
 188.794 +				AI_NFF_PARSE_TRIPLE(s.color);
 188.795 +
 188.796 +				// read the other properties
 188.797 +				AI_NFF_PARSE_FLOAT(s.diffuse.r);
 188.798 +				AI_NFF_PARSE_FLOAT(s.specular.r);
 188.799 +				AI_NFF_PARSE_FLOAT(d); // skip shininess and transmittance
 188.800 +				AI_NFF_PARSE_FLOAT(d);
 188.801 +				AI_NFF_PARSE_FLOAT(s.refracti);
 188.802 +
 188.803 +				// NFF2 uses full colors here so we need to use them too
 188.804 +				// although NFF uses simple scaling factors
 188.805 +				s.diffuse.g  = s.diffuse.b = s.diffuse.r;
 188.806 +				s.specular.g = s.specular.b = s.specular.r;
 188.807 +
 188.808 +				// if the next one is NOT a number we assume it is a texture file name
 188.809 +				// this feature is used by some NFF files on the internet and it has
 188.810 +				// been implemented as it can be really useful
 188.811 +				SkipSpaces(&sz);
 188.812 +				if (!IsNumeric(*sz))
 188.813 +				{
 188.814 +					// TODO: Support full file names with spaces and quotation marks ...
 188.815 +					const char* p = sz;
 188.816 +					while (!IsSpaceOrNewLine( *sz ))++sz;
 188.817 +
 188.818 +					unsigned int diff = (unsigned int)(sz-p);
 188.819 +					if (diff)
 188.820 +					{
 188.821 +						s.texFile = std::string(p,diff);
 188.822 +					}
 188.823 +				}
 188.824 +				else
 188.825 +				{
 188.826 +					AI_NFF_PARSE_FLOAT(s.ambient); // optional
 188.827 +				}
 188.828 +			}
 188.829 +			// 'shader' - other way to specify a texture
 188.830 +			else if (TokenMatch(sz,"shader",6))
 188.831 +			{
 188.832 +				SkipSpaces(&sz);
 188.833 +				const char* old = sz;
 188.834 +				while (!IsSpaceOrNewLine(*sz))++sz;
 188.835 +				s.texFile = std::string(old, (uintptr_t)sz - (uintptr_t)old);
 188.836 +			}
 188.837 +			// 'l' - light source
 188.838 +			else if (TokenMatch(sz,"l",1))
 188.839 +			{
 188.840 +				lights.push_back(Light());
 188.841 +				Light& light = lights.back();
 188.842 +
 188.843 +				AI_NFF_PARSE_TRIPLE(light.position);
 188.844 +				AI_NFF_PARSE_FLOAT (light.intensity);
 188.845 +				AI_NFF_PARSE_TRIPLE(light.color);
 188.846 +			}
 188.847 +			// 's' - sphere
 188.848 +			else if (TokenMatch(sz,"s",1))
 188.849 +			{
 188.850 +				meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
 188.851 +				MeshInfo& currentMesh = meshesLocked.back();
 188.852 +				currentMesh.shader = s;
 188.853 +				currentMesh.shader.mapping = aiTextureMapping_SPHERE;
 188.854 +
 188.855 +				AI_NFF_PARSE_SHAPE_INFORMATION();
 188.856 +
 188.857 +				// we don't need scaling or translation here - we do it in the node's transform
 188.858 +				StandardShapes::MakeSphere(iTesselation, currentMesh.vertices);
 188.859 +				currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 188.860 +
 188.861 +				// generate a name for the mesh
 188.862 +				::sprintf(currentMesh.name,"sphere_%i",sphere++);
 188.863 +			}
 188.864 +			// 'dod' - dodecahedron
 188.865 +			else if (TokenMatch(sz,"dod",3))
 188.866 +			{
 188.867 +				meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
 188.868 +				MeshInfo& currentMesh = meshesLocked.back();
 188.869 +				currentMesh.shader = s;
 188.870 +				currentMesh.shader.mapping = aiTextureMapping_SPHERE;
 188.871 +
 188.872 +				AI_NFF_PARSE_SHAPE_INFORMATION();
 188.873 +
 188.874 +				// we don't need scaling or translation here - we do it in the node's transform
 188.875 +				StandardShapes::MakeDodecahedron(currentMesh.vertices);
 188.876 +				currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 188.877 +
 188.878 +				// generate a name for the mesh
 188.879 +				::sprintf(currentMesh.name,"dodecahedron_%i",dodecahedron++);
 188.880 +			}
 188.881 +
 188.882 +			// 'oct' - octahedron
 188.883 +			else if (TokenMatch(sz,"oct",3))
 188.884 +			{
 188.885 +				meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
 188.886 +				MeshInfo& currentMesh = meshesLocked.back();
 188.887 +				currentMesh.shader = s;
 188.888 +				currentMesh.shader.mapping = aiTextureMapping_SPHERE;
 188.889 +
 188.890 +				AI_NFF_PARSE_SHAPE_INFORMATION();
 188.891 +
 188.892 +				// we don't need scaling or translation here - we do it in the node's transform
 188.893 +				StandardShapes::MakeOctahedron(currentMesh.vertices);
 188.894 +				currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 188.895 +
 188.896 +				// generate a name for the mesh
 188.897 +				::sprintf(currentMesh.name,"octahedron_%i",octahedron++);
 188.898 +			}
 188.899 +
 188.900 +			// 'tet' - tetrahedron
 188.901 +			else if (TokenMatch(sz,"tet",3))
 188.902 +			{
 188.903 +				meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
 188.904 +				MeshInfo& currentMesh = meshesLocked.back();
 188.905 +				currentMesh.shader = s;
 188.906 +				currentMesh.shader.mapping = aiTextureMapping_SPHERE;
 188.907 +
 188.908 +				AI_NFF_PARSE_SHAPE_INFORMATION();
 188.909 +
 188.910 +				// we don't need scaling or translation here - we do it in the node's transform
 188.911 +				StandardShapes::MakeTetrahedron(currentMesh.vertices);
 188.912 +				currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 188.913 +
 188.914 +				// generate a name for the mesh
 188.915 +				::sprintf(currentMesh.name,"tetrahedron_%i",tetrahedron++);
 188.916 +			}
 188.917 +
 188.918 +			// 'hex' - hexahedron
 188.919 +			else if (TokenMatch(sz,"hex",3))
 188.920 +			{
 188.921 +				meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
 188.922 +				MeshInfo& currentMesh = meshesLocked.back();
 188.923 +				currentMesh.shader = s;
 188.924 +				currentMesh.shader.mapping = aiTextureMapping_BOX;
 188.925 +
 188.926 +				AI_NFF_PARSE_SHAPE_INFORMATION();
 188.927 +
 188.928 +				// we don't need scaling or translation here - we do it in the node's transform
 188.929 +				StandardShapes::MakeHexahedron(currentMesh.vertices);
 188.930 +				currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 188.931 +
 188.932 +				// generate a name for the mesh
 188.933 +				::sprintf(currentMesh.name,"hexahedron_%i",hexahedron++);
 188.934 +			}
 188.935 +			// 'c' - cone
 188.936 +			else if (TokenMatch(sz,"c",1))
 188.937 +			{
 188.938 +				meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
 188.939 +				MeshInfo& currentMesh = meshesLocked.back();
 188.940 +				currentMesh.shader = s;
 188.941 +				currentMesh.shader.mapping = aiTextureMapping_CYLINDER;
 188.942 +
 188.943 +				if(!GetNextLine(buffer,line))
 188.944 +				{
 188.945 +					DefaultLogger::get()->error("NFF: Unexpected end of file (cone definition not complete)");
 188.946 +					break;
 188.947 +				}
 188.948 +				sz = line;
 188.949 +
 188.950 +				// read the two center points and the respective radii
 188.951 +				aiVector3D center1, center2; float radius1, radius2;
 188.952 +				AI_NFF_PARSE_TRIPLE(center1);
 188.953 +				AI_NFF_PARSE_FLOAT(radius1);
 188.954 +
 188.955 +				if(!GetNextLine(buffer,line))
 188.956 +				{
 188.957 +					DefaultLogger::get()->error("NFF: Unexpected end of file (cone definition not complete)");
 188.958 +					break;
 188.959 +				}
 188.960 +				sz = line;
 188.961 +
 188.962 +				AI_NFF_PARSE_TRIPLE(center2);
 188.963 +				AI_NFF_PARSE_FLOAT(radius2);
 188.964 +
 188.965 +				// compute the center point of the cone/cylinder -
 188.966 +				// it is its local transformation origin
 188.967 +				currentMesh.dir    =  center2-center1;
 188.968 +				currentMesh.center =  center1+currentMesh.dir/2.f;
 188.969 +
 188.970 +				float f;
 188.971 +				if (( f = currentMesh.dir.Length()) < 10e-3f )
 188.972 +				{
 188.973 +					DefaultLogger::get()->error("NFF: Cone height is close to zero");
 188.974 +					continue;
 188.975 +				}
 188.976 +				currentMesh.dir /= f; // normalize
 188.977 +
 188.978 +				// generate the cone - it consists of simple triangles
 188.979 +				StandardShapes::MakeCone(f, radius1, radius2,
 188.980 +					integer_pow(4, iTesselation), currentMesh.vertices);
 188.981 +
 188.982 +				// MakeCone() returns tris
 188.983 +				currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 188.984 +
 188.985 +				// generate a name for the mesh. 'cone' if it a cone,
 188.986 +				// 'cylinder' if it is a cylinder. Funny, isn't it?
 188.987 +				if (radius1 != radius2)
 188.988 +					::sprintf(currentMesh.name,"cone_%i",cone++);
 188.989 +				else ::sprintf(currentMesh.name,"cylinder_%i",cylinder++);
 188.990 +			}
 188.991 +			// 'tess' - tesselation
 188.992 +			else if (TokenMatch(sz,"tess",4))
 188.993 +			{
 188.994 +				SkipSpaces(&sz);
 188.995 +				iTesselation = strtoul10(sz);
 188.996 +			}
 188.997 +			// 'from' - camera position
 188.998 +			else if (TokenMatch(sz,"from",4))
 188.999 +			{
188.1000 +				AI_NFF_PARSE_TRIPLE(camPos);
188.1001 +				hasCam = true;
188.1002 +			}
188.1003 +			// 'at' - camera look-at vector
188.1004 +			else if (TokenMatch(sz,"at",2))
188.1005 +			{
188.1006 +				AI_NFF_PARSE_TRIPLE(camLookAt);
188.1007 +				hasCam = true;
188.1008 +			}
188.1009 +			// 'up' - camera up vector
188.1010 +			else if (TokenMatch(sz,"up",2))
188.1011 +			{
188.1012 +				AI_NFF_PARSE_TRIPLE(camUp);
188.1013 +				hasCam = true;
188.1014 +			}
188.1015 +			// 'angle' - (half?) camera field of view
188.1016 +			else if (TokenMatch(sz,"angle",5))
188.1017 +			{
188.1018 +				AI_NFF_PARSE_FLOAT(angle);
188.1019 +				hasCam = true;
188.1020 +			}
188.1021 +			// 'resolution' - used to compute the screen aspect
188.1022 +			else if (TokenMatch(sz,"resolution",10))
188.1023 +			{
188.1024 +				AI_NFF_PARSE_FLOAT(resolution.x);
188.1025 +				AI_NFF_PARSE_FLOAT(resolution.y);
188.1026 +				hasCam = true;
188.1027 +			}
188.1028 +			// 'pb' - bezier patch. Not supported yet
188.1029 +			else if (TokenMatch(sz,"pb",2))
188.1030 +			{
188.1031 +				DefaultLogger::get()->error("NFF: Encountered unsupported ID: bezier patch");
188.1032 +			}
188.1033 +			// 'pn' - NURBS. Not supported yet
188.1034 +			else if (TokenMatch(sz,"pn",2) || TokenMatch(sz,"pnn",3))
188.1035 +			{
188.1036 +				DefaultLogger::get()->error("NFF: Encountered unsupported ID: NURBS");
188.1037 +			}
188.1038 +			// '' - comment
188.1039 +			else if ('#' == line[0])
188.1040 +			{
188.1041 +				const char* sz;SkipSpaces(&line[1],&sz);
188.1042 +				if (!IsLineEnd(*sz))DefaultLogger::get()->info(sz);
188.1043 +			}
188.1044 +		}
188.1045 +	}
188.1046 +
188.1047 +	// copy all arrays into one large
188.1048 +	meshes.reserve (meshes.size()+meshesLocked.size()+meshesWithNormals.size()+meshesWithUVCoords.size());
188.1049 +	meshes.insert  (meshes.end(),meshesLocked.begin(),meshesLocked.end());
188.1050 +	meshes.insert  (meshes.end(),meshesWithNormals.begin(),meshesWithNormals.end());
188.1051 +	meshes.insert  (meshes.end(),meshesWithUVCoords.begin(),meshesWithUVCoords.end());
188.1052 +
188.1053 +	// now generate output meshes. first find out how many meshes we'll need
188.1054 +	std::vector<MeshInfo>::const_iterator it = meshes.begin(), end = meshes.end();
188.1055 +	for (;it != end;++it)
188.1056 +	{
188.1057 +		if (!(*it).faces.empty())
188.1058 +		{
188.1059 +			++pScene->mNumMeshes;
188.1060 +			if ((*it).name[0])++numNamed;
188.1061 +		}
188.1062 +	}
188.1063 +
188.1064 +	// generate a dummy root node - assign all unnamed elements such
188.1065 +	// as polygons and polygon patches to the root node and generate
188.1066 +	// sub nodes for named objects such as spheres and cones.
188.1067 +	aiNode* const root = new aiNode();
188.1068 +	root->mName.Set("<NFF_Root>");
188.1069 +	root->mNumChildren = numNamed + (hasCam ? 1 : 0) + (unsigned int) lights.size();
188.1070 +	root->mNumMeshes = pScene->mNumMeshes-numNamed;
188.1071 +
188.1072 +	aiNode** ppcChildren = NULL;
188.1073 +	unsigned int* pMeshes = NULL;
188.1074 +	if (root->mNumMeshes)
188.1075 +		pMeshes = root->mMeshes = new unsigned int[root->mNumMeshes];
188.1076 +	if (root->mNumChildren)
188.1077 +		ppcChildren = root->mChildren = new aiNode*[root->mNumChildren];
188.1078 +
188.1079 +	// generate the camera
188.1080 +	if (hasCam)
188.1081 +	{
188.1082 +		aiNode* nd = *ppcChildren = new aiNode();
188.1083 +		nd->mName.Set("<NFF_Camera>");
188.1084 +		nd->mParent = root;
188.1085 +
188.1086 +		// allocate the camera in the scene
188.1087 +		pScene->mNumCameras = 1;
188.1088 +		pScene->mCameras = new aiCamera*[1];
188.1089 +		aiCamera* c = pScene->mCameras[0] = new aiCamera;
188.1090 +
188.1091 +		c->mName = nd->mName; // make sure the names are identical
188.1092 +		c->mHorizontalFOV = AI_DEG_TO_RAD( angle );
188.1093 +		c->mLookAt		= camLookAt - camPos;
188.1094 +		c->mPosition	= camPos;
188.1095 +		c->mUp			= camUp;
188.1096 +
188.1097 +		// If the resolution is not specified in the file, we
188.1098 +		// need to set 1.0 as aspect. 
188.1099 +		c->mAspect		= (!resolution.y ? 0.f : resolution.x / resolution.y);
188.1100 +		++ppcChildren;
188.1101 +	}
188.1102 +
188.1103 +	// generate light sources
188.1104 +	if (!lights.empty())
188.1105 +	{
188.1106 +		pScene->mNumLights = (unsigned int)lights.size();
188.1107 +		pScene->mLights = new aiLight*[pScene->mNumLights];
188.1108 +		for (unsigned int i = 0; i < pScene->mNumLights;++i,++ppcChildren)
188.1109 +		{
188.1110 +			const Light& l = lights[i];
188.1111 +
188.1112 +			aiNode* nd = *ppcChildren  = new aiNode();
188.1113 +			nd->mParent = root;
188.1114 +
188.1115 +			nd->mName.length = ::sprintf(nd->mName.data,"<NFF_Light%i>",i);
188.1116 +
188.1117 +			// allocate the light in the scene data structure
188.1118 +			aiLight* out = pScene->mLights[i] = new aiLight();
188.1119 +			out->mName = nd->mName; // make sure the names are identical
188.1120 +			out->mType = aiLightSource_POINT;
188.1121 +			out->mColorDiffuse = out->mColorSpecular = l.color * l.intensity;
188.1122 +			out->mPosition = l.position;
188.1123 +		}
188.1124 +	}
188.1125 +
188.1126 +	if (!pScene->mNumMeshes)throw DeadlyImportError("NFF: No meshes loaded");
188.1127 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
188.1128 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
188.1129 +	for (it = meshes.begin(), m = 0; it != end;++it)
188.1130 +	{
188.1131 +		if ((*it).faces.empty())continue;
188.1132 +
188.1133 +		const MeshInfo& src = *it;
188.1134 +		aiMesh* const mesh = pScene->mMeshes[m] = new aiMesh();
188.1135 +		mesh->mNumVertices = (unsigned int)src.vertices.size();
188.1136 +		mesh->mNumFaces = (unsigned int)src.faces.size();
188.1137 +
188.1138 +		// Generate sub nodes for named meshes
188.1139 +		if (src.name[0])
188.1140 +		{
188.1141 +			aiNode* const node = *ppcChildren = new aiNode();
188.1142 +			node->mParent = root;
188.1143 +			node->mNumMeshes = 1;
188.1144 +			node->mMeshes = new unsigned int[1];
188.1145 +			node->mMeshes[0] = m;
188.1146 +			node->mName.Set(src.name);
188.1147 +
188.1148 +			// setup the transformation matrix of the node
188.1149 +			aiMatrix4x4::FromToMatrix(aiVector3D(0.f,1.f,0.f),
188.1150 +				src.dir,node->mTransformation);
188.1151 +
188.1152 +			aiMatrix4x4& mat = node->mTransformation;
188.1153 +			mat.a1 *= src.radius.x; mat.b1 *= src.radius.x; mat.c1 *= src.radius.x;
188.1154 +			mat.a2 *= src.radius.y; mat.b2 *= src.radius.y; mat.c2 *= src.radius.y;
188.1155 +			mat.a3 *= src.radius.z; mat.b3 *= src.radius.z; mat.c3 *= src.radius.z;
188.1156 +			mat.a4 = src.center.x;
188.1157 +			mat.b4 = src.center.y;
188.1158 +			mat.c4 = src.center.z;
188.1159 +
188.1160 +			++ppcChildren;
188.1161 +		}
188.1162 +		else *pMeshes++ = m;
188.1163 +
188.1164 +		// copy vertex positions
188.1165 +		mesh->mVertices = new aiVector3D[mesh->mNumVertices];
188.1166 +		::memcpy(mesh->mVertices,&src.vertices[0],
188.1167 +			sizeof(aiVector3D)*mesh->mNumVertices);
188.1168 +
188.1169 +		// NFF2: there could be vertex colors
188.1170 +		if (!src.colors.empty())
188.1171 +		{
188.1172 +			ai_assert(src.colors.size() == src.vertices.size());
188.1173 +
188.1174 +			// copy vertex colors
188.1175 +			mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
188.1176 +			::memcpy(mesh->mColors[0],&src.colors[0],
188.1177 +				sizeof(aiColor4D)*mesh->mNumVertices);
188.1178 +		}
188.1179 +
188.1180 +		if (!src.normals.empty())
188.1181 +		{
188.1182 +			ai_assert(src.normals.size() == src.vertices.size());
188.1183 +
188.1184 +			// copy normal vectors
188.1185 +			mesh->mNormals = new aiVector3D[mesh->mNumVertices];
188.1186 +			::memcpy(mesh->mNormals,&src.normals[0],
188.1187 +				sizeof(aiVector3D)*mesh->mNumVertices);
188.1188 +		}
188.1189 +
188.1190 +		if (!src.uvs.empty())
188.1191 +		{
188.1192 +			ai_assert(src.uvs.size() == src.vertices.size());
188.1193 +
188.1194 +			// copy texture coordinates
188.1195 +			mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
188.1196 +			::memcpy(mesh->mTextureCoords[0],&src.uvs[0],
188.1197 +				sizeof(aiVector3D)*mesh->mNumVertices);
188.1198 +		}
188.1199 +
188.1200 +		// generate faces
188.1201 +		unsigned int p = 0;
188.1202 +		aiFace* pFace = mesh->mFaces = new aiFace[mesh->mNumFaces];
188.1203 +		for (std::vector<unsigned int>::const_iterator it2 = src.faces.begin(),
188.1204 +			end2 = src.faces.end();
188.1205 +			it2 != end2;++it2,++pFace)
188.1206 +		{
188.1207 +			pFace->mIndices = new unsigned int [ pFace->mNumIndices = *it2 ];
188.1208 +			for (unsigned int o = 0; o < pFace->mNumIndices;++o)
188.1209 +				pFace->mIndices[o] = p++;
188.1210 +		}
188.1211 +
188.1212 +		// generate a material for the mesh
188.1213 +		aiMaterial* pcMat = (aiMaterial*)(pScene->mMaterials[m] = new aiMaterial());
188.1214 +
188.1215 +		mesh->mMaterialIndex = m++;
188.1216 +
188.1217 +		aiString s;
188.1218 +		s.Set(AI_DEFAULT_MATERIAL_NAME);
188.1219 +		pcMat->AddProperty(&s, AI_MATKEY_NAME);
188.1220 +
188.1221 +		// FIX: Ignore diffuse == 0 
188.1222 +		aiColor3D c = src.shader.color * (src.shader.diffuse.r ?  src.shader.diffuse : aiColor3D(1.f,1.f,1.f));
188.1223 +		pcMat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE);
188.1224 +		c = src.shader.color * src.shader.specular;
188.1225 +		pcMat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
188.1226 +
188.1227 +		// NFF2 - default values for NFF
188.1228 +		pcMat->AddProperty(&src.shader.ambient, 1,AI_MATKEY_COLOR_AMBIENT);
188.1229 +		pcMat->AddProperty(&src.shader.emissive,1,AI_MATKEY_COLOR_EMISSIVE);
188.1230 +		pcMat->AddProperty(&src.shader.opacity, 1,AI_MATKEY_OPACITY);
188.1231 +
188.1232 +		// setup the first texture layer, if existing
188.1233 +		if (src.shader.texFile.length())
188.1234 +		{
188.1235 +			s.Set(src.shader.texFile);
188.1236 +			pcMat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
188.1237 +
188.1238 +			if (aiTextureMapping_UV != src.shader.mapping) {
188.1239 +
188.1240 +				aiVector3D v(0.f,-1.f,0.f);
188.1241 +				pcMat->AddProperty(&v, 1,AI_MATKEY_TEXMAP_AXIS_DIFFUSE(0));
188.1242 +				pcMat->AddProperty((int*)&src.shader.mapping, 1,AI_MATKEY_MAPPING_DIFFUSE(0));
188.1243 +			}
188.1244 +		}
188.1245 +
188.1246 +		// setup the name of the material
188.1247 +		if (src.shader.name.length())
188.1248 +		{
188.1249 +			s.Set(src.shader.texFile);
188.1250 +			pcMat->AddProperty(&s,AI_MATKEY_NAME);
188.1251 +		}
188.1252 +
188.1253 +		// setup some more material properties that are specific to NFF2
188.1254 +		int i;
188.1255 +		if (src.shader.twoSided)
188.1256 +		{
188.1257 +			i = 1;
188.1258 +			pcMat->AddProperty(&i,1,AI_MATKEY_TWOSIDED);
188.1259 +		}
188.1260 +		i = (src.shader.shaded ? aiShadingMode_Gouraud : aiShadingMode_NoShading);
188.1261 +		if (src.shader.shininess)
188.1262 +		{
188.1263 +			i = aiShadingMode_Phong;
188.1264 +			pcMat->AddProperty(&src.shader.shininess,1,AI_MATKEY_SHININESS);
188.1265 +		}
188.1266 +		pcMat->AddProperty(&i,1,AI_MATKEY_SHADING_MODEL);
188.1267 +	}
188.1268 +	pScene->mRootNode = root;
188.1269 +}
188.1270 +
188.1271 +#endif // !! ASSIMP_BUILD_NO_NFF_IMPORTER
   189.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   189.2 +++ b/libs/assimp/NFFLoader.h	Sat Feb 01 19:58:19 2014 +0200
   189.3 @@ -0,0 +1,212 @@
   189.4 +/*
   189.5 +Open Asset Import Library (assimp)
   189.6 +----------------------------------------------------------------------
   189.7 +
   189.8 +Copyright (c) 2006-2012, assimp team
   189.9 +All rights reserved.
  189.10 +
  189.11 +Redistribution and use of this software in source and binary forms, 
  189.12 +with or without modification, are permitted provided that the 
  189.13 +following conditions are met:
  189.14 +
  189.15 +* Redistributions of source code must retain the above
  189.16 +  copyright notice, this list of conditions and the
  189.17 +  following disclaimer.
  189.18 +
  189.19 +* Redistributions in binary form must reproduce the above
  189.20 +  copyright notice, this list of conditions and the
  189.21 +  following disclaimer in the documentation and/or other
  189.22 +  materials provided with the distribution.
  189.23 +
  189.24 +* Neither the name of the assimp team, nor the names of its
  189.25 +  contributors may be used to endorse or promote products
  189.26 +  derived from this software without specific prior
  189.27 +  written permission of the assimp team.
  189.28 +
  189.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  189.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  189.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  189.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  189.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  189.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  189.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  189.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  189.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  189.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  189.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  189.40 +
  189.41 +----------------------------------------------------------------------
  189.42 +*/
  189.43 +
  189.44 +/** @file NFFLoader.h
  189.45 + *  @brief Declaration of the NFF importer class.
  189.46 + */
  189.47 +#ifndef AI_NFFLOADER_H_INCLUDED
  189.48 +#define AI_NFFLOADER_H_INCLUDED
  189.49 +
  189.50 +#include "BaseImporter.h"
  189.51 +#include <vector>
  189.52 +
  189.53 +#include "assimp/types.h"
  189.54 +
  189.55 +namespace Assimp	{
  189.56 +
  189.57 +// ----------------------------------------------------------------------------------
  189.58 +/** NFF (Neutral File Format) Importer class.
  189.59 + *
  189.60 + * The class implements both Eric Haynes NFF format and Sense8's NFF (NFF2) format.
  189.61 + * Both are quite different and the loading code is somewhat dirty at 
  189.62 + * the moment. Sense8 should be moved to a separate loader.
  189.63 +*/
  189.64 +class NFFImporter : public BaseImporter
  189.65 +{
  189.66 +public:
  189.67 +	NFFImporter();
  189.68 +	~NFFImporter();
  189.69 +
  189.70 +
  189.71 +public:
  189.72 +
  189.73 +	// -------------------------------------------------------------------
  189.74 +	/** Returns whether the class can handle the format of the given file. 
  189.75 +	 * See BaseImporter::CanRead() for details.
  189.76 +	 */
  189.77 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  189.78 +		bool checkSig) const;
  189.79 +
  189.80 +protected:
  189.81 +
  189.82 +	// -------------------------------------------------------------------
  189.83 +	/** Return importer meta information.
  189.84 +	 * See #BaseImporter::GetInfo for the details
  189.85 +	 */
  189.86 +	const aiImporterDesc* GetInfo () const;
  189.87 +
  189.88 +	// -------------------------------------------------------------------
  189.89 +	/** Imports the given file into the given scene structure. 
  189.90 +	* See BaseImporter::InternReadFile() for details
  189.91 +	*/
  189.92 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  189.93 +		IOSystem* pIOHandler);
  189.94 +
  189.95 +private:
  189.96 +
  189.97 +	
  189.98 +	// describes face material properties
  189.99 +	struct ShadingInfo
 189.100 +	{
 189.101 +		ShadingInfo()
 189.102 +			: color     (0.6f,0.6f,0.6f)
 189.103 +			, diffuse   (1.f,1.f,1.f)
 189.104 +			, specular  (1.f,1.f,1.f)
 189.105 +			, ambient   (0.f,0.f,0.f)
 189.106 +			, emissive	(0.f,0.f,0.f)
 189.107 +			, refracti  (1.f)
 189.108 +			, twoSided  (false) // for NFF2
 189.109 +			, shaded    (true)  // for NFF2
 189.110 +			, opacity	(1.f)
 189.111 +			, shininess	(0.f)
 189.112 +			, mapping	(aiTextureMapping_UV)
 189.113 +		{}
 189.114 +
 189.115 +		aiColor3D color,diffuse,specular,ambient,emissive;
 189.116 +		float refracti;
 189.117 +
 189.118 +		std::string texFile;
 189.119 +
 189.120 +		// For NFF2
 189.121 +		bool twoSided;
 189.122 +		bool shaded;
 189.123 +		float opacity, shininess;
 189.124 +
 189.125 +		std::string name;
 189.126 +
 189.127 +		// texture mapping to be generated for the mesh - uv is the default
 189.128 +		// it means: use UV if there, nothing otherwise. This property is
 189.129 +		// used for locked meshes.
 189.130 +		aiTextureMapping mapping;
 189.131 +
 189.132 +		// shininess is ignored for the moment
 189.133 +		bool operator == (const ShadingInfo& other) const
 189.134 +		{
 189.135 +			return color == other.color		&& 
 189.136 +				diffuse  == other.diffuse	&&
 189.137 +				specular == other.specular	&&
 189.138 +				ambient  == other.ambient	&&
 189.139 +				refracti == other.refracti  &&
 189.140 +				texFile  == other.texFile   &&
 189.141 +				twoSided == other.twoSided  &&
 189.142 +				shaded   == other.shaded;
 189.143 +
 189.144 +			// Some properties from NFF2 aren't compared by this operator.
 189.145 +			// Comparing MeshInfo::matIndex should do that.
 189.146 +		}
 189.147 +	};
 189.148 +
 189.149 +	// describes a NFF light source
 189.150 +	struct Light
 189.151 +	{
 189.152 +		Light()
 189.153 +			: intensity	(1.f)
 189.154 +			, color		(1.f,1.f,1.f)
 189.155 +		{}
 189.156 +
 189.157 +		aiVector3D position;
 189.158 +		float intensity;
 189.159 +		aiColor3D color;
 189.160 +	};
 189.161 +
 189.162 +	enum PatchType
 189.163 +	{
 189.164 +		PatchType_Simple = 0x0,
 189.165 +		PatchType_Normals = 0x1,
 189.166 +		PatchType_UVAndNormals = 0x2
 189.167 +	};
 189.168 +
 189.169 +	// describes a NFF mesh
 189.170 +	struct MeshInfo
 189.171 +	{
 189.172 +		MeshInfo(PatchType _pType, bool bL = false)
 189.173 +			: pType     (_pType)
 189.174 +			, bLocked   (bL)
 189.175 +			, radius	(1.f,1.f,1.f)
 189.176 +			, dir		(0.f,1.f,0.f)
 189.177 +			, matIndex  (0)
 189.178 +		{
 189.179 +			name[0] = '\0'; // by default meshes are unnamed
 189.180 +		}
 189.181 +
 189.182 +		ShadingInfo shader;
 189.183 +		PatchType pType;
 189.184 +		bool bLocked;
 189.185 +
 189.186 +		// for spheres, cones and cylinders: center point of the object
 189.187 +		aiVector3D center, radius, dir;
 189.188 +
 189.189 +		char name[128];
 189.190 +
 189.191 +		std::vector<aiVector3D> vertices, normals, uvs;
 189.192 +		std::vector<unsigned int> faces;
 189.193 +
 189.194 +		// for NFF2
 189.195 +		std::vector<aiColor4D>  colors; 
 189.196 +		unsigned int matIndex;
 189.197 +	};
 189.198 +
 189.199 +	
 189.200 +	// -------------------------------------------------------------------
 189.201 +	/** Loads the material table for the NFF2 file format from an
 189.202 +	 *  external file.
 189.203 +	 *
 189.204 +	 *  @param output Receives the list of output meshes
 189.205 +	 *  @param path Path to the file (abs. or rel.)
 189.206 +	 *  @param pIOHandler IOSystem to be used to open the file
 189.207 +	*/
 189.208 +	void LoadNFF2MaterialTable(std::vector<ShadingInfo>& output,
 189.209 +		const std::string& path, IOSystem* pIOHandler);
 189.210 +
 189.211 +};
 189.212 +
 189.213 +} // end of namespace Assimp
 189.214 +
 189.215 +#endif // AI_NFFIMPORTER_H_IN
   190.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   190.2 +++ b/libs/assimp/OFFLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   190.3 @@ -0,0 +1,224 @@
   190.4 +/*
   190.5 +---------------------------------------------------------------------------
   190.6 +Open Asset Import Library (assimp)
   190.7 +---------------------------------------------------------------------------
   190.8 +
   190.9 +Copyright (c) 2006-2012, assimp team
  190.10 +
  190.11 +All rights reserved.
  190.12 +
  190.13 +Redistribution and use of this software in source and binary forms, 
  190.14 +with or without modification, are permitted provided that the following 
  190.15 +conditions are met:
  190.16 +
  190.17 +* Redistributions of source code must retain the above
  190.18 +  copyright notice, this list of conditions and the
  190.19 +  following disclaimer.
  190.20 +
  190.21 +* Redistributions in binary form must reproduce the above
  190.22 +  copyright notice, this list of conditions and the
  190.23 +  following disclaimer in the documentation and/or other
  190.24 +  materials provided with the distribution.
  190.25 +
  190.26 +* Neither the name of the assimp team, nor the names of its
  190.27 +  contributors may be used to endorse or promote products
  190.28 +  derived from this software without specific prior
  190.29 +  written permission of the assimp team.
  190.30 +
  190.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  190.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  190.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  190.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  190.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  190.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  190.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  190.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  190.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  190.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  190.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  190.42 +---------------------------------------------------------------------------
  190.43 +*/
  190.44 +
  190.45 +/** @file  OFFLoader.cpp
  190.46 + *  @brief Implementation of the OFF importer class 
  190.47 + */
  190.48 +
  190.49 +#include "AssimpPCH.h"
  190.50 +#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
  190.51 +
  190.52 +// internal headers
  190.53 +#include "OFFLoader.h"
  190.54 +#include "ParsingUtils.h"
  190.55 +#include "fast_atof.h"
  190.56 +
  190.57 +
  190.58 +using namespace Assimp;
  190.59 +
  190.60 +static const aiImporterDesc desc = {
  190.61 +	"OFF Importer",
  190.62 +	"",
  190.63 +	"",
  190.64 +	"",
  190.65 +	aiImporterFlags_SupportBinaryFlavour,
  190.66 +	0,
  190.67 +	0,
  190.68 +	0,
  190.69 +	0,
  190.70 +	"off" 
  190.71 +};
  190.72 +
  190.73 +// ------------------------------------------------------------------------------------------------
  190.74 +// Constructor to be privately used by Importer
  190.75 +OFFImporter::OFFImporter()
  190.76 +{}
  190.77 +
  190.78 +// ------------------------------------------------------------------------------------------------
  190.79 +// Destructor, private as well 
  190.80 +OFFImporter::~OFFImporter()
  190.81 +{}
  190.82 +
  190.83 +// ------------------------------------------------------------------------------------------------
  190.84 +// Returns whether the class can handle the format of the given file. 
  190.85 +bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  190.86 +{
  190.87 +	const std::string extension = GetExtension(pFile);
  190.88 +
  190.89 +	if (extension == "off")
  190.90 +		return true;
  190.91 +	else if (!extension.length() || checkSig)
  190.92 +	{
  190.93 +		if (!pIOHandler)return true;
  190.94 +		const char* tokens[] = {"off"};
  190.95 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
  190.96 +	}
  190.97 +	return false;
  190.98 +}
  190.99 +
 190.100 +// ------------------------------------------------------------------------------------------------
 190.101 +const aiImporterDesc* OFFImporter::GetInfo () const
 190.102 +{
 190.103 +	return &desc;
 190.104 +}
 190.105 +
 190.106 +// ------------------------------------------------------------------------------------------------
 190.107 +// Imports the given file into the given scene structure. 
 190.108 +void OFFImporter::InternReadFile( const std::string& pFile, 
 190.109 +	aiScene* pScene, IOSystem* pIOHandler)
 190.110 +{
 190.111 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 190.112 +
 190.113 +	// Check whether we can read from the file
 190.114 +	if( file.get() == NULL) {
 190.115 +		throw DeadlyImportError( "Failed to open OFF file " + pFile + ".");
 190.116 +	}
 190.117 +	
 190.118 +	// allocate storage and copy the contents of the file to a memory buffer
 190.119 +	std::vector<char> mBuffer2;
 190.120 +	TextFileToBuffer(file.get(),mBuffer2);
 190.121 +	const char* buffer = &mBuffer2[0];
 190.122 +
 190.123 +	char line[4096];
 190.124 +	GetNextLine(buffer,line);
 190.125 +	if ('O' == line[0]) {
 190.126 +		GetNextLine(buffer,line); // skip the 'OFF' line
 190.127 +	}
 190.128 +
 190.129 +	const char* sz = line; SkipSpaces(&sz);
 190.130 +	const unsigned int numVertices = strtoul10(sz,&sz);SkipSpaces(&sz);
 190.131 +	const unsigned int numFaces = strtoul10(sz,&sz);
 190.132 +
 190.133 +	pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = 1 ];
 190.134 +	aiMesh* mesh = pScene->mMeshes[0] = new aiMesh();
 190.135 +	aiFace* faces = mesh->mFaces = new aiFace [mesh->mNumFaces = numFaces];
 190.136 +
 190.137 +	std::vector<aiVector3D> tempPositions(numVertices);
 190.138 +
 190.139 +	// now read all vertex lines
 190.140 +	for (unsigned int i = 0; i< numVertices;++i)
 190.141 +	{
 190.142 +		if(!GetNextLine(buffer,line))
 190.143 +		{
 190.144 +			DefaultLogger::get()->error("OFF: The number of verts in the header is incorrect");
 190.145 +			break;
 190.146 +		}
 190.147 +		aiVector3D& v = tempPositions[i];
 190.148 +
 190.149 +		sz = line; SkipSpaces(&sz);
 190.150 +		sz = fast_atoreal_move<float>(sz,(float&)v.x); SkipSpaces(&sz);
 190.151 +		sz = fast_atoreal_move<float>(sz,(float&)v.y); SkipSpaces(&sz);
 190.152 +		fast_atoreal_move<float>(sz,(float&)v.z);
 190.153 +	}
 190.154 +
 190.155 +	
 190.156 +	// First find out how many vertices we'll need
 190.157 +	const char* old = buffer;
 190.158 +	for (unsigned int i = 0; i< mesh->mNumFaces;++i)
 190.159 +	{
 190.160 +		if(!GetNextLine(buffer,line))
 190.161 +		{
 190.162 +			DefaultLogger::get()->error("OFF: The number of faces in the header is incorrect");
 190.163 +			break;
 190.164 +		}
 190.165 +		sz = line;SkipSpaces(&sz);
 190.166 +		if(!(faces->mNumIndices = strtoul10(sz,&sz)) || faces->mNumIndices > 9)
 190.167 +		{
 190.168 +			DefaultLogger::get()->error("OFF: Faces with zero indices aren't allowed");
 190.169 +			--mesh->mNumFaces;
 190.170 +			continue;
 190.171 +		}
 190.172 +		mesh->mNumVertices += faces->mNumIndices;
 190.173 +		++faces;
 190.174 +	}
 190.175 +
 190.176 +	if (!mesh->mNumVertices)
 190.177 +		throw DeadlyImportError("OFF: There are no valid faces");
 190.178 +
 190.179 +	// allocate storage for the output vertices
 190.180 +	aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
 190.181 +
 190.182 +	// second: now parse all face indices
 190.183 +	buffer = old;faces = mesh->mFaces;
 190.184 +	for (unsigned int i = 0, p = 0; i< mesh->mNumFaces;)
 190.185 +	{
 190.186 +		if(!GetNextLine(buffer,line))break;
 190.187 +
 190.188 +		unsigned int idx;
 190.189 +		sz = line;SkipSpaces(&sz);
 190.190 +		if(!(idx = strtoul10(sz,&sz)) || idx > 9)
 190.191 +			continue;
 190.192 +
 190.193 +		faces->mIndices = new unsigned int [faces->mNumIndices];
 190.194 +		for (unsigned int m = 0; m < faces->mNumIndices;++m)
 190.195 +		{
 190.196 +			SkipSpaces(&sz);
 190.197 +			if ((idx = strtoul10(sz,&sz)) >= numVertices)
 190.198 +			{
 190.199 +				DefaultLogger::get()->error("OFF: Vertex index is out of range");
 190.200 +				idx = numVertices-1;
 190.201 +			}
 190.202 +			faces->mIndices[m] = p++;
 190.203 +			*verts++ = tempPositions[idx];
 190.204 +		}
 190.205 +		++i;
 190.206 +		++faces;
 190.207 +	}
 190.208 +	
 190.209 +	// generate the output node graph
 190.210 +	pScene->mRootNode = new aiNode();
 190.211 +	pScene->mRootNode->mName.Set("<OFFRoot>");
 190.212 +	pScene->mRootNode->mMeshes = new unsigned int [pScene->mRootNode->mNumMeshes = 1];
 190.213 +	pScene->mRootNode->mMeshes[0] = 0;
 190.214 +
 190.215 +	// generate a default material
 190.216 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = 1];
 190.217 +	aiMaterial* pcMat = new aiMaterial();
 190.218 +
 190.219 +	aiColor4D clr(0.6f,0.6f,0.6f,1.0f);
 190.220 +	pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
 190.221 +	pScene->mMaterials[0] = pcMat;
 190.222 +
 190.223 +	const int twosided =1;
 190.224 +	pcMat->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
 190.225 +}
 190.226 +
 190.227 +#endif // !! ASSIMP_BUILD_NO_OFF_IMPORTER
   191.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   191.2 +++ b/libs/assimp/OFFLoader.h	Sat Feb 01 19:58:19 2014 +0200
   191.3 @@ -0,0 +1,92 @@
   191.4 +/*
   191.5 +Open Asset Import Library (assimp)
   191.6 +----------------------------------------------------------------------
   191.7 +
   191.8 +Copyright (c) 2006-2012, assimp team
   191.9 +All rights reserved.
  191.10 +
  191.11 +Redistribution and use of this software in source and binary forms, 
  191.12 +with or without modification, are permitted provided that the 
  191.13 +following conditions are met:
  191.14 +
  191.15 +* Redistributions of source code must retain the above
  191.16 +  copyright notice, this list of conditions and the
  191.17 +  following disclaimer.
  191.18 +
  191.19 +* Redistributions in binary form must reproduce the above
  191.20 +  copyright notice, this list of conditions and the
  191.21 +  following disclaimer in the documentation and/or other
  191.22 +  materials provided with the distribution.
  191.23 +
  191.24 +* Neither the name of the assimp team, nor the names of its
  191.25 +  contributors may be used to endorse or promote products
  191.26 +  derived from this software without specific prior
  191.27 +  written permission of the assimp team.
  191.28 +
  191.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  191.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  191.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  191.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  191.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  191.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  191.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  191.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  191.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  191.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  191.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  191.40 +
  191.41 +----------------------------------------------------------------------
  191.42 +*/
  191.43 +
  191.44 +/** @file  OFFLoader.h
  191.45 + *  @brief Declaration of the OFF importer class. 
  191.46 + */
  191.47 +#ifndef AI_OFFLOADER_H_INCLUDED
  191.48 +#define AI_OFFLOADER_H_INCLUDED
  191.49 +
  191.50 +#include "BaseImporter.h"
  191.51 +#include "assimp/types.h"
  191.52 +#include <vector>
  191.53 +
  191.54 +namespace Assimp	{
  191.55 +
  191.56 +// ---------------------------------------------------------------------------
  191.57 +/** Importer class for the Object File Format (.off)
  191.58 +*/
  191.59 +class OFFImporter : public BaseImporter
  191.60 +{
  191.61 +public:
  191.62 +	OFFImporter();
  191.63 +	~OFFImporter();
  191.64 +
  191.65 +
  191.66 +public:
  191.67 +
  191.68 +	// -------------------------------------------------------------------
  191.69 +	/** Returns whether the class can handle the format of the given file. 
  191.70 +	* See BaseImporter::CanRead() for details.	*/
  191.71 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  191.72 +		bool checkSig) const;
  191.73 +
  191.74 +protected:
  191.75 +
  191.76 +	// -------------------------------------------------------------------
  191.77 +	/** Return importer meta information.
  191.78 +	 * See #BaseImporter::GetInfo for the details
  191.79 +	 */
  191.80 +	const aiImporterDesc* GetInfo () const;
  191.81 +
  191.82 +	// -------------------------------------------------------------------
  191.83 +	/** Imports the given file into the given scene structure. 
  191.84 +	* See BaseImporter::InternReadFile() for details
  191.85 +	*/
  191.86 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  191.87 +		IOSystem* pIOHandler);
  191.88 +
  191.89 +private:
  191.90 +
  191.91 +};
  191.92 +
  191.93 +} // end of namespace Assimp
  191.94 +
  191.95 +#endif // AI_3DSIMPORTER_H_IN
   192.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   192.2 +++ b/libs/assimp/ObjExporter.cpp	Sat Feb 01 19:58:19 2014 +0200
   192.3 @@ -0,0 +1,318 @@
   192.4 +/*
   192.5 +Open Asset Import Library (assimp)
   192.6 +----------------------------------------------------------------------
   192.7 +
   192.8 +Copyright (c) 2006-2012, assimp team
   192.9 +All rights reserved.
  192.10 +
  192.11 +Redistribution and use of this software in source and binary forms, 
  192.12 +with or without modification, are permitted provided that the 
  192.13 +following conditions are met:
  192.14 +
  192.15 +* Redistributions of source code must retain the above
  192.16 +  copyright notice, this list of conditions and the
  192.17 +  following disclaimer.
  192.18 +
  192.19 +* Redistributions in binary form must reproduce the above
  192.20 +  copyright notice, this list of conditions and the
  192.21 +  following disclaimer in the documentation and/or other
  192.22 +  materials provided with the distribution.
  192.23 +
  192.24 +* Neither the name of the assimp team, nor the names of its
  192.25 +  contributors may be used to endorse or promote products
  192.26 +  derived from this software without specific prior
  192.27 +  written permission of the assimp team.
  192.28 +
  192.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  192.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  192.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  192.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  192.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  192.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  192.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  192.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  192.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  192.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  192.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  192.40 +
  192.41 +----------------------------------------------------------------------
  192.42 +*/
  192.43 +
  192.44 +#include "AssimpPCH.h"
  192.45 +
  192.46 +#ifndef ASSIMP_BUILD_NO_EXPORT
  192.47 +#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
  192.48 +
  192.49 +#include "ObjExporter.h"
  192.50 +#include "assimp/version.h"
  192.51 +
  192.52 +using namespace Assimp;
  192.53 +namespace Assimp	{
  192.54 +
  192.55 +// ------------------------------------------------------------------------------------------------
  192.56 +// Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp
  192.57 +void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
  192.58 +{
  192.59 +	// invoke the exporter 
  192.60 +	ObjExporter exporter(pFile, pScene);
  192.61 +
  192.62 +	// we're still here - export successfully completed. Write both the main OBJ file and the material script
  192.63 +	{
  192.64 +		boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
  192.65 +		if(outfile == NULL) {
  192.66 +			throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
  192.67 +		}
  192.68 +		outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
  192.69 +	}
  192.70 +	{
  192.71 +		boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt"));
  192.72 +		if(outfile == NULL) {
  192.73 +			throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName()));
  192.74 +		}
  192.75 +		outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1);
  192.76 +	}
  192.77 +}
  192.78 +
  192.79 +} // end of namespace Assimp
  192.80 +
  192.81 +
  192.82 +// ------------------------------------------------------------------------------------------------
  192.83 +ObjExporter :: ObjExporter(const char* _filename, const aiScene* pScene)
  192.84 +: filename(_filename)
  192.85 +, pScene(pScene)
  192.86 +, endl("\n") 
  192.87 +{
  192.88 +	// make sure that all formatting happens using the standard, C locale and not the user's current locale
  192.89 +	const std::locale& l = std::locale("C");
  192.90 +	mOutput.imbue(l);
  192.91 +	mOutputMat.imbue(l);
  192.92 +
  192.93 +	WriteGeometryFile();
  192.94 +	WriteMaterialFile();
  192.95 +}
  192.96 +
  192.97 +// ------------------------------------------------------------------------------------------------
  192.98 +std::string ObjExporter :: GetMaterialLibName()
  192.99 +{	
 192.100 +	// within the Obj file, we use just the relative file name with the path stripped
 192.101 +	const std::string& s = GetMaterialLibFileName();
 192.102 +	std::string::size_type il = s.find_last_of("/\\");
 192.103 +	if (il != std::string::npos) {
 192.104 +		return s.substr(il + 1);
 192.105 +	}
 192.106 +
 192.107 +	return s;
 192.108 +}
 192.109 +
 192.110 +// ------------------------------------------------------------------------------------------------
 192.111 +std::string ObjExporter :: GetMaterialLibFileName()
 192.112 +{	
 192.113 +	return filename + ".mtl";
 192.114 +}
 192.115 +
 192.116 +// ------------------------------------------------------------------------------------------------
 192.117 +void ObjExporter :: WriteHeader(std::ostringstream& out)
 192.118 +{
 192.119 +	out << "# File produced by Open Asset Import Library (http://www.assimp.sf.net)" << endl;
 192.120 +	out << "# (assimp v" << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.' << aiGetVersionRevision() << ")" << endl  << endl;
 192.121 +}
 192.122 +
 192.123 +// ------------------------------------------------------------------------------------------------
 192.124 +std::string ObjExporter :: GetMaterialName(unsigned int index)
 192.125 +{
 192.126 +	const aiMaterial* const mat = pScene->mMaterials[index];
 192.127 +	aiString s;
 192.128 +	if(AI_SUCCESS == mat->Get(AI_MATKEY_NAME,s)) {
 192.129 +		return std::string(s.data,s.length);
 192.130 +	}
 192.131 +
 192.132 +	char number[ sizeof(unsigned int) * 3 + 1 ];
 192.133 +	ASSIMP_itoa10(number,index);
 192.134 +	return "$Material_" + std::string(number);
 192.135 +}
 192.136 +
 192.137 +// ------------------------------------------------------------------------------------------------
 192.138 +void ObjExporter :: WriteMaterialFile()
 192.139 +{
 192.140 +	WriteHeader(mOutputMat);
 192.141 +
 192.142 +	for(unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
 192.143 +		const aiMaterial* const mat = pScene->mMaterials[i];
 192.144 +
 192.145 +		int illum = 1;
 192.146 +		mOutputMat << "newmtl " << GetMaterialName(i)  << endl;
 192.147 +
 192.148 +		aiColor4D c;
 192.149 +		if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_DIFFUSE,c)) {
 192.150 +			mOutputMat << "kd " << c.r << " " << c.g << " " << c.b << endl;
 192.151 +		}
 192.152 +		if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_AMBIENT,c)) {
 192.153 +			mOutputMat << "ka " << c.r << " " << c.g << " " << c.b << endl;
 192.154 +		}
 192.155 +		if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_SPECULAR,c)) {
 192.156 +			mOutputMat << "ks " << c.r << " " << c.g << " " << c.b << endl;
 192.157 +		}
 192.158 +
 192.159 +		float o;
 192.160 +		if(AI_SUCCESS == mat->Get(AI_MATKEY_OPACITY,o)) {
 192.161 +			mOutputMat << "d " << o << endl;
 192.162 +		}
 192.163 +
 192.164 +		if(AI_SUCCESS == mat->Get(AI_MATKEY_SHININESS,o) && o) {
 192.165 +			mOutputMat << "Ns " << o << endl;
 192.166 +			illum = 2;
 192.167 +		}
 192.168 +
 192.169 +		mOutputMat << "illum " << illum << endl;
 192.170 +
 192.171 +		aiString s;
 192.172 +		if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_DIFFUSE(0),s)) {
 192.173 +			mOutputMat << "map_kd " << s.data << endl;
 192.174 +		}
 192.175 +		if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_AMBIENT(0),s)) {
 192.176 +			mOutputMat << "map_ka " << s.data << endl;
 192.177 +		}
 192.178 +		if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SPECULAR(0),s)) {
 192.179 +			mOutputMat << "map_ks " << s.data << endl;
 192.180 +		}
 192.181 +		if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SHININESS(0),s)) {
 192.182 +			mOutputMat << "map_ns " << s.data << endl;
 192.183 +		}
 192.184 +		if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_HEIGHT(0),s) || AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_NORMALS(0),s)) {
 192.185 +			// implementations seem to vary here, so write both variants
 192.186 +			mOutputMat << "bump " << s.data << endl;
 192.187 +			mOutputMat << "map_bump " << s.data << endl;
 192.188 +		}
 192.189 +
 192.190 +		mOutputMat << endl;
 192.191 +	}
 192.192 +}
 192.193 +
 192.194 +// ------------------------------------------------------------------------------------------------
 192.195 +void ObjExporter :: WriteGeometryFile()
 192.196 +{
 192.197 +	WriteHeader(mOutput);
 192.198 +	mOutput << "mtllib "  << GetMaterialLibName() << endl << endl;
 192.199 +
 192.200 +	// collect mesh geometry
 192.201 +	aiMatrix4x4 mBase;
 192.202 +	AddNode(pScene->mRootNode,mBase);
 192.203 +
 192.204 +	// write vertex positions
 192.205 +	mOutput << "# " << vp.size() << " vertex positions" << endl;
 192.206 +	BOOST_FOREACH(const aiVector3D& v, vp) {
 192.207 +		mOutput << "v  " << v.x << " " << v.y << " " << v.z << endl;
 192.208 +	}
 192.209 +	mOutput << endl;
 192.210 +
 192.211 +	// write uv coordinates
 192.212 +	mOutput << "# " << vt.size() << " UV coordinates" << endl;
 192.213 +	BOOST_FOREACH(const aiVector3D& v, vt) {
 192.214 +		mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
 192.215 +	}
 192.216 +	mOutput << endl;
 192.217 +
 192.218 +	// write vertex normals
 192.219 +	mOutput << "# " << vn.size() << " vertex normals" << endl;
 192.220 +	BOOST_FOREACH(const aiVector3D& v, vn) {
 192.221 +		mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
 192.222 +	}
 192.223 +	mOutput << endl;
 192.224 +
 192.225 +	// now write all mesh instances
 192.226 +	BOOST_FOREACH(const MeshInstance& m, meshes) {
 192.227 +		mOutput << "# Mesh \'" << m.name << "\' with " << m.faces.size() << " faces" << endl;
 192.228 +		mOutput << "g " << m.name << endl;
 192.229 +		mOutput << "usemtl " << m.matname << endl;
 192.230 +
 192.231 +		BOOST_FOREACH(const Face& f, m.faces) {
 192.232 +			mOutput << f.kind << ' ';
 192.233 +			BOOST_FOREACH(const FaceVertex& fv, f.indices) {
 192.234 +				mOutput << ' ' << fv.vp;
 192.235 +
 192.236 +				if (f.kind != 'p') {
 192.237 +					if (fv.vt || f.kind == 'f') {
 192.238 +						mOutput << '/';
 192.239 +					}
 192.240 +					if (fv.vt) {
 192.241 +						mOutput << fv.vt;
 192.242 +					}
 192.243 +					if (f.kind == 'f') {
 192.244 +						mOutput << '/';
 192.245 +						if (fv.vn) {
 192.246 +							mOutput << fv.vn;
 192.247 +						}
 192.248 +					}
 192.249 +				}
 192.250 +			}
 192.251 +
 192.252 +			mOutput << endl;
 192.253 +		}
 192.254 +		mOutput << endl;
 192.255 +	}
 192.256 +}
 192.257 +
 192.258 +// ------------------------------------------------------------------------------------------------
 192.259 +void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat)
 192.260 +{
 192.261 +	meshes.push_back(MeshInstance());
 192.262 +	MeshInstance& mesh = meshes.back();
 192.263 +
 192.264 +	mesh.name = std::string(name.data,name.length) + (m->mName.length ? "_"+std::string(m->mName.data,m->mName.length) : "");
 192.265 +	mesh.matname = GetMaterialName(m->mMaterialIndex);
 192.266 +
 192.267 +	mesh.faces.resize(m->mNumFaces);
 192.268 +	for(unsigned int i = 0; i < m->mNumFaces; ++i) {
 192.269 +		const aiFace& f = m->mFaces[i];
 192.270 +
 192.271 +		Face& face = mesh.faces[i];
 192.272 +		switch (f.mNumIndices) {
 192.273 +			case 1: 
 192.274 +				face.kind = 'p';
 192.275 +				break;
 192.276 +			case 2: 
 192.277 +				face.kind = 'l';
 192.278 +				break;
 192.279 +			default: 
 192.280 +				face.kind = 'f';
 192.281 +		}
 192.282 +		face.indices.resize(f.mNumIndices);
 192.283 +
 192.284 +		for(unsigned int a = 0; a < f.mNumIndices; ++a) {
 192.285 +			const unsigned int idx = f.mIndices[a];
 192.286 +
 192.287 +			// XXX need a way to check if this is an unique vertex or if we had it already, 
 192.288 +			// in which case we should instead reference the previous occurrence.
 192.289 +			ai_assert(m->mVertices);
 192.290 +			vp.push_back( mat * m->mVertices[idx] );
 192.291 +			face.indices[a].vp = vp.size();
 192.292 +
 192.293 +			if (m->mNormals) {
 192.294 +				vn.push_back( m->mNormals[idx] );
 192.295 +			}
 192.296 +			face.indices[a].vn = vn.size();
 192.297 +
 192.298 +			if (m->mTextureCoords[0]) {
 192.299 +				vt.push_back( m->mTextureCoords[0][idx] );
 192.300 +			}
 192.301 +			face.indices[a].vt = vt.size();
 192.302 +		}
 192.303 +	}
 192.304 +}
 192.305 +
 192.306 +// ------------------------------------------------------------------------------------------------
 192.307 +void ObjExporter :: AddNode(const aiNode* nd, const aiMatrix4x4& mParent)
 192.308 +{
 192.309 +	const aiMatrix4x4& mAbs = mParent * nd->mTransformation;
 192.310 +
 192.311 +	for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
 192.312 +		AddMesh(nd->mName, pScene->mMeshes[nd->mMeshes[i]],mAbs);
 192.313 +	}
 192.314 +
 192.315 +	for(unsigned int i = 0; i < nd->mNumChildren; ++i) {
 192.316 +		AddNode(nd->mChildren[i],mAbs);
 192.317 +	}
 192.318 +}
 192.319 +
 192.320 +#endif
 192.321 +#endif
   193.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   193.2 +++ b/libs/assimp/ObjExporter.h	Sat Feb 01 19:58:19 2014 +0200
   193.3 @@ -0,0 +1,123 @@
   193.4 +/*
   193.5 +Open Asset Import Library (assimp)
   193.6 +----------------------------------------------------------------------
   193.7 +
   193.8 +Copyright (c) 2006-2012, assimp team
   193.9 +All rights reserved.
  193.10 +
  193.11 +Redistribution and use of this software in source and binary forms, 
  193.12 +with or without modification, are permitted provided that the 
  193.13 +following conditions are met:
  193.14 +
  193.15 +* Redistributions of source code must retain the above
  193.16 +  copyright notice, this list of conditions and the
  193.17 +  following disclaimer.
  193.18 +
  193.19 +* Redistributions in binary form must reproduce the above
  193.20 +  copyright notice, this list of conditions and the
  193.21 +  following disclaimer in the documentation and/or other
  193.22 +  materials provided with the distribution.
  193.23 +
  193.24 +* Neither the name of the assimp team, nor the names of its
  193.25 +  contributors may be used to endorse or promote products
  193.26 +  derived from this software without specific prior
  193.27 +  written permission of the assimp team.
  193.28 +
  193.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  193.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  193.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  193.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  193.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  193.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  193.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  193.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  193.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  193.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  193.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  193.40 +
  193.41 +----------------------------------------------------------------------
  193.42 +*/
  193.43 +
  193.44 +/** @file ColladaExporter.h
  193.45 + * Declares the exporter class to write a scene to a Collada file
  193.46 + */
  193.47 +#ifndef AI_OBJEXPORTER_H_INC
  193.48 +#define AI_OBJEXPORTER_H_INC
  193.49 +
  193.50 +#include <sstream>
  193.51 +
  193.52 +struct aiScene;
  193.53 +struct aiNode;
  193.54 +
  193.55 +namespace Assimp	
  193.56 +{
  193.57 +
  193.58 +// ------------------------------------------------------------------------------------------------
  193.59 +/** Helper class to export a given scene to an OBJ file. */
  193.60 +// ------------------------------------------------------------------------------------------------
  193.61 +class ObjExporter
  193.62 +{
  193.63 +public:
  193.64 +	/// Constructor for a specific scene to export
  193.65 +	ObjExporter(const char* filename, const aiScene* pScene);
  193.66 +
  193.67 +public:
  193.68 +
  193.69 +	std::string GetMaterialLibName();
  193.70 +	std::string GetMaterialLibFileName();
  193.71 +	
  193.72 +public:
  193.73 +
  193.74 +	/// public stringstreams to write all output into
  193.75 +	std::ostringstream mOutput, mOutputMat;
  193.76 +
  193.77 +private:
  193.78 +
  193.79 +	// intermediate data structures
  193.80 +	struct FaceVertex 
  193.81 +	{
  193.82 +		FaceVertex()
  193.83 +			: vp(),vn(),vt() 
  193.84 +		{
  193.85 +		}
  193.86 +
  193.87 +		// one-based, 0 means: 'does not exist'
  193.88 +		unsigned int vp,vn,vt;
  193.89 +	};
  193.90 +
  193.91 +	struct Face {
  193.92 +		char kind;
  193.93 +		std::vector<FaceVertex> indices;
  193.94 +	};
  193.95 +
  193.96 +	struct MeshInstance {
  193.97 +
  193.98 +		std::string name, matname;
  193.99 +		std::vector<Face> faces;
 193.100 +	};
 193.101 +
 193.102 +	void WriteHeader(std::ostringstream& out);
 193.103 +
 193.104 +	void WriteMaterialFile();
 193.105 +	void WriteGeometryFile();
 193.106 +
 193.107 +	std::string GetMaterialName(unsigned int index);
 193.108 +
 193.109 +	void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat);
 193.110 +	void AddNode(const aiNode* nd, const aiMatrix4x4& mParent);
 193.111 +
 193.112 +private:
 193.113 +
 193.114 +	const std::string filename;
 193.115 +	const aiScene* const pScene;
 193.116 +
 193.117 +	std::vector<aiVector3D> vp, vn, vt;
 193.118 +	std::vector<MeshInstance> meshes;
 193.119 +
 193.120 +	// this endl() doesn't flush() the stream
 193.121 +	const std::string endl;
 193.122 +};
 193.123 +
 193.124 +}
 193.125 +
 193.126 +#endif
   194.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   194.2 +++ b/libs/assimp/ObjFileData.h	Sat Feb 01 19:58:19 2014 +0200
   194.3 @@ -0,0 +1,326 @@
   194.4 +/*
   194.5 +Open Asset Import Library (assimp)
   194.6 +----------------------------------------------------------------------
   194.7 +
   194.8 +Copyright (c) 2006-2012, assimp team
   194.9 +All rights reserved.
  194.10 +
  194.11 +Redistribution and use of this software in source and binary forms, 
  194.12 +with or without modification, are permitted provided that the 
  194.13 +following conditions are met:
  194.14 +
  194.15 +* Redistributions of source code must retain the above
  194.16 +  copyright notice, this list of conditions and the
  194.17 +  following disclaimer.
  194.18 +
  194.19 +* Redistributions in binary form must reproduce the above
  194.20 +  copyright notice, this list of conditions and the
  194.21 +  following disclaimer in the documentation and/or other
  194.22 +  materials provided with the distribution.
  194.23 +
  194.24 +* Neither the name of the assimp team, nor the names of its
  194.25 +  contributors may be used to endorse or promote products
  194.26 +  derived from this software without specific prior
  194.27 +  written permission of the assimp team.
  194.28 +
  194.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  194.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  194.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  194.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  194.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  194.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  194.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  194.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  194.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  194.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  194.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  194.40 +
  194.41 +----------------------------------------------------------------------
  194.42 +*/
  194.43 +
  194.44 +#ifndef OBJ_FILEDATA_H_INC
  194.45 +#define OBJ_FILEDATA_H_INC
  194.46 +
  194.47 +#include <vector>
  194.48 +#include <map>
  194.49 +#include "assimp/types.h"
  194.50 +#include "assimp/mesh.h"
  194.51 +
  194.52 +namespace Assimp
  194.53 +{
  194.54 +
  194.55 +namespace ObjFile
  194.56 +{
  194.57 +// ------------------------------------------------------------------------------------------------
  194.58 +struct Object;
  194.59 +struct Face;
  194.60 +struct Material;
  194.61 +
  194.62 +// ------------------------------------------------------------------------------------------------
  194.63 +//!	\struct	Face
  194.64 +//!	\brief	Data structure for a simple obj-face, describes discredit,l.ation and materials
  194.65 +struct Face
  194.66 +{
  194.67 +	typedef std::vector<unsigned int> IndexArray;
  194.68 +
  194.69 +	//!	Primitive type
  194.70 +	aiPrimitiveType m_PrimitiveType;
  194.71 +	//!	Vertex indices
  194.72 +	IndexArray *m_pVertices;
  194.73 +	//!	Normal indices
  194.74 +	IndexArray *m_pNormals;
  194.75 +	//!	Texture coordinates indices
  194.76 +	IndexArray *m_pTexturCoords;
  194.77 +	//!	Pointer to assigned material
  194.78 +	Material *m_pMaterial;
  194.79 +	
  194.80 +	//!	\brief	Default constructor
  194.81 +	//!	\param	pVertices	Pointer to assigned vertex indexbuffer
  194.82 +	//!	\param	pNormals	Pointer to assigned normals indexbuffer
  194.83 +	//!	\param	pTexCoords	Pointer to assigned texture indexbuffer
  194.84 +	Face( std::vector<unsigned int> *pVertices, 
  194.85 +			std::vector<unsigned int> *pNormals, 
  194.86 +			std::vector<unsigned int> *pTexCoords,
  194.87 +			aiPrimitiveType pt = aiPrimitiveType_POLYGON) : 
  194.88 +		m_PrimitiveType( pt ), 
  194.89 +		m_pVertices( pVertices ), 
  194.90 +		m_pNormals( pNormals ),
  194.91 +		m_pTexturCoords( pTexCoords ), 
  194.92 +		m_pMaterial( 0L )
  194.93 +	{
  194.94 +		// empty
  194.95 +	}
  194.96 +	
  194.97 +	//!	\brief	Destructor	
  194.98 +	~Face()
  194.99 +	{	
 194.100 +		delete m_pVertices;
 194.101 +		m_pVertices = NULL;
 194.102 +
 194.103 +		delete m_pNormals;
 194.104 +		m_pNormals = NULL;
 194.105 +
 194.106 +		delete m_pTexturCoords;
 194.107 +		m_pTexturCoords = NULL;
 194.108 +	}
 194.109 +};
 194.110 +
 194.111 +// ------------------------------------------------------------------------------------------------
 194.112 +//!	\struct	Object
 194.113 +//!	\brief	Stores all objects of an objfile object definition
 194.114 +struct Object
 194.115 +{
 194.116 +	enum ObjectType
 194.117 +	{
 194.118 +		ObjType,
 194.119 +		GroupType
 194.120 +	};
 194.121 +
 194.122 +	//!	Object name
 194.123 +	std::string m_strObjName;
 194.124 +	//!	Transformation matrix, stored in OpenGL format
 194.125 +	aiMatrix4x4 m_Transformation;
 194.126 +	//!	All sub-objects referenced by this object
 194.127 +	std::vector<Object*> m_SubObjects;
 194.128 +	///	Assigned meshes
 194.129 +	std::vector<unsigned int> m_Meshes;
 194.130 +
 194.131 +	//!	\brief	Default constructor
 194.132 +	Object() :
 194.133 +		m_strObjName("")
 194.134 +	{
 194.135 +		// empty
 194.136 +	}
 194.137 +	
 194.138 +	//!	\brief	Destructor	
 194.139 +	~Object()
 194.140 +	{
 194.141 +		for (std::vector<Object*>::iterator it = m_SubObjects.begin();
 194.142 +			it != m_SubObjects.end(); ++it)
 194.143 +		{
 194.144 +			delete *it;
 194.145 +		}
 194.146 +		m_SubObjects.clear();
 194.147 +	}
 194.148 +};
 194.149 +
 194.150 +// ------------------------------------------------------------------------------------------------
 194.151 +//!	\struct	Material
 194.152 +//!	\brief	Data structure to store all material specific data
 194.153 +struct Material
 194.154 +{
 194.155 +	//!	Name of material description
 194.156 +	aiString MaterialName;
 194.157 +
 194.158 +	//!	Texture names
 194.159 +	aiString texture;
 194.160 +	aiString textureSpecular;
 194.161 +	aiString textureAmbient;
 194.162 +	aiString textureBump;
 194.163 +	aiString textureNormal;
 194.164 +	aiString textureSpecularity;
 194.165 +	aiString textureOpacity;
 194.166 +	aiString textureDisp;
 194.167 +
 194.168 +	//!	Ambient color 
 194.169 +	aiColor3D ambient;
 194.170 +	//!	Diffuse color
 194.171 +	aiColor3D diffuse;
 194.172 +	//!	Specular color
 194.173 +	aiColor3D specular;
 194.174 +	//!	Alpha value
 194.175 +	float alpha;
 194.176 +	//!	Shineness factor
 194.177 +	float shineness;
 194.178 +	//!	Illumination model 
 194.179 +	int illumination_model;
 194.180 +	//! Index of refraction
 194.181 +	float ior;
 194.182 +
 194.183 +	//!	Constructor
 194.184 +	Material()
 194.185 +		:	diffuse (0.6f,0.6f,0.6f)
 194.186 +		,	alpha	(1.f)
 194.187 +		,	shineness (0.0f)
 194.188 +		,	illumination_model (1)
 194.189 +		,	ior		(1.f)
 194.190 +	{
 194.191 +		// empty
 194.192 +	}
 194.193 +
 194.194 +	// Destructor
 194.195 +	~Material()
 194.196 +	{
 194.197 +		// empty
 194.198 +	}
 194.199 +};
 194.200 +
 194.201 +// ------------------------------------------------------------------------------------------------
 194.202 +//!	\struct	Mesh
 194.203 +//!	\brief	Data structure to store a mesh
 194.204 +struct Mesh
 194.205 +{
 194.206 +	static const unsigned int NoMaterial = ~0u;
 194.207 +
 194.208 +	///	Array with pointer to all stored faces
 194.209 +	std::vector<Face*> m_Faces;
 194.210 +	///	Assigned material
 194.211 +	Material *m_pMaterial;
 194.212 +	///	Number of stored indices.
 194.213 +	unsigned int m_uiNumIndices;
 194.214 +	/// Number of UV
 194.215 +	unsigned int m_uiUVCoordinates[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
 194.216 +	///	Material index.
 194.217 +	unsigned int m_uiMaterialIndex;
 194.218 +	///	True, if normals are stored.
 194.219 +	bool m_hasNormals;
 194.220 +	///	Constructor
 194.221 +	Mesh() :
 194.222 +		m_pMaterial(NULL),
 194.223 +		m_uiNumIndices(0),
 194.224 +		m_uiMaterialIndex( NoMaterial ),
 194.225 +		m_hasNormals(false)
 194.226 +	{
 194.227 +		memset(m_uiUVCoordinates, 0, sizeof( unsigned int ) * AI_MAX_NUMBER_OF_TEXTURECOORDS);
 194.228 +	}
 194.229 +
 194.230 +	///	Destructor
 194.231 +	~Mesh() 
 194.232 +	{
 194.233 +		for (std::vector<Face*>::iterator it = m_Faces.begin();
 194.234 +			it != m_Faces.end(); ++it)
 194.235 +		{
 194.236 +			delete *it;
 194.237 +		}
 194.238 +	}
 194.239 +};
 194.240 +
 194.241 +// ------------------------------------------------------------------------------------------------
 194.242 +//!	\struct	Model
 194.243 +//!	\brief	Data structure to store all obj-specific model datas
 194.244 +struct Model
 194.245 +{
 194.246 +	typedef std::map<std::string, std::vector<unsigned int>* > GroupMap;
 194.247 +	typedef std::map<std::string, std::vector<unsigned int>* >::iterator GroupMapIt;
 194.248 +	typedef std::map<std::string, std::vector<unsigned int>* >::const_iterator ConstGroupMapIt;
 194.249 +
 194.250 +	//!	Model name
 194.251 +	std::string m_ModelName;
 194.252 +	//!	List ob assigned objects
 194.253 +	std::vector<Object*> m_Objects;
 194.254 +	//!	Pointer to current object
 194.255 +	ObjFile::Object *m_pCurrent;
 194.256 +	//!	Pointer to current material
 194.257 +	ObjFile::Material *m_pCurrentMaterial;
 194.258 +	//!	Pointer to default material
 194.259 +	ObjFile::Material *m_pDefaultMaterial;
 194.260 +	//!	Vector with all generated materials
 194.261 +	std::vector<std::string> m_MaterialLib;
 194.262 +	//!	Vector with all generated group
 194.263 +	std::vector<std::string> m_GroupLib;
 194.264 +	//!	Vector with all generated vertices
 194.265 +	std::vector<aiVector3D> m_Vertices;
 194.266 +	//!	vector with all generated normals
 194.267 +	std::vector<aiVector3D> m_Normals;
 194.268 +	//!	Group map
 194.269 +	GroupMap m_Groups;
 194.270 +	//!	Group to face id assignment
 194.271 +	std::vector<unsigned int> *m_pGroupFaceIDs;
 194.272 +	//!	Active group
 194.273 +	std::string m_strActiveGroup;
 194.274 +	//!	Vector with generated texture coordinates
 194.275 +	std::vector<aiVector2D> m_TextureCoord;
 194.276 +	//!	Current mesh instance
 194.277 +	Mesh *m_pCurrentMesh;
 194.278 +	//!	Vector with stored meshes
 194.279 +	std::vector<Mesh*> m_Meshes;
 194.280 +	//!	Material map
 194.281 +	std::map<std::string, Material*> m_MaterialMap;
 194.282 +
 194.283 +	//!	\brief	Default constructor
 194.284 +	Model() :
 194.285 +		m_ModelName(""),
 194.286 +		m_pCurrent(NULL),
 194.287 +		m_pCurrentMaterial(NULL),
 194.288 +		m_pDefaultMaterial(NULL),
 194.289 +        m_pGroupFaceIDs(NULL),
 194.290 +		m_strActiveGroup(""),
 194.291 +		m_pCurrentMesh(NULL)
 194.292 +	{
 194.293 +		// empty
 194.294 +	}
 194.295 +	
 194.296 +	//!	\brief	Destructor
 194.297 +	~Model()
 194.298 +	{
 194.299 +		// Clear all stored object instances
 194.300 +		for (std::vector<Object*>::iterator it = m_Objects.begin();
 194.301 +			it != m_Objects.end(); ++it) {
 194.302 +			delete *it;
 194.303 +		}
 194.304 +		m_Objects.clear();
 194.305 +		
 194.306 +		// Clear all stored mesh instances
 194.307 +		for (std::vector<Mesh*>::iterator it = m_Meshes.begin();
 194.308 +			it != m_Meshes.end(); ++it) {
 194.309 +			delete *it;
 194.310 +		}
 194.311 +		m_Meshes.clear();
 194.312 +
 194.313 +		for(GroupMapIt it = m_Groups.begin(); it != m_Groups.end(); ++it) {
 194.314 +			delete it->second;
 194.315 +		}
 194.316 +		m_Groups.clear();
 194.317 +
 194.318 +		for ( std::map<std::string, Material*>::iterator it = m_MaterialMap.begin(); it != m_MaterialMap.end(); ++it ) {
 194.319 +			delete it->second;
 194.320 +		}
 194.321 +	}
 194.322 +};
 194.323 +
 194.324 +// ------------------------------------------------------------------------------------------------
 194.325 +
 194.326 +} // Namespace ObjFile
 194.327 +} // Namespace Assimp
 194.328 +
 194.329 +#endif
   195.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   195.2 +++ b/libs/assimp/ObjFileImporter.cpp	Sat Feb 01 19:58:19 2014 +0200
   195.3 @@ -0,0 +1,620 @@
   195.4 +/*
   195.5 +---------------------------------------------------------------------------
   195.6 +Open Asset Import Library (assimp)
   195.7 +---------------------------------------------------------------------------
   195.8 +
   195.9 +Copyright (c) 2006-2012, assimp team
  195.10 +
  195.11 +All rights reserved.
  195.12 +
  195.13 +Redistribution and use of this software in source and binary forms, 
  195.14 +with or without modification, are permitted provided that the following 
  195.15 +conditions are met:
  195.16 +
  195.17 +* Redistributions of source code must retain the above
  195.18 +  copyright notice, this list of conditions and the
  195.19 +  following disclaimer.
  195.20 +
  195.21 +* Redistributions in binary form must reproduce the above
  195.22 +  copyright notice, this list of conditions and the
  195.23 +  following disclaimer in the documentation and/or other
  195.24 +  materials provided with the distribution.
  195.25 +
  195.26 +* Neither the name of the assimp team, nor the names of its
  195.27 +  contributors may be used to endorse or promote products
  195.28 +  derived from this software without specific prior
  195.29 +  written permission of the assimp team.
  195.30 +
  195.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  195.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  195.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  195.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  195.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  195.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  195.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  195.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  195.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  195.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  195.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  195.42 +---------------------------------------------------------------------------
  195.43 +*/
  195.44 +
  195.45 +#include "AssimpPCH.h"
  195.46 +#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
  195.47 +
  195.48 +#include "DefaultIOSystem.h"
  195.49 +#include "ObjFileImporter.h"
  195.50 +#include "ObjFileParser.h"
  195.51 +#include "ObjFileData.h"
  195.52 +
  195.53 +static const aiImporterDesc desc = {
  195.54 +	"Wavefront Object Importer",
  195.55 +	"",
  195.56 +	"",
  195.57 +	"surfaces not supported",
  195.58 +	aiImporterFlags_SupportTextFlavour,
  195.59 +	0,
  195.60 +	0,
  195.61 +	0,
  195.62 +	0,
  195.63 +	"obj"
  195.64 +};
  195.65 +
  195.66 +
  195.67 +namespace Assimp	{
  195.68 +
  195.69 +using namespace std;
  195.70 +
  195.71 +// ------------------------------------------------------------------------------------------------
  195.72 +//	Default constructor
  195.73 +ObjFileImporter::ObjFileImporter() :
  195.74 +	m_Buffer(),	
  195.75 +	m_pRootObject( NULL ),
  195.76 +	m_strAbsPath( "" )
  195.77 +{
  195.78 +    DefaultIOSystem io;
  195.79 +	m_strAbsPath = io.getOsSeparator();
  195.80 +}
  195.81 +
  195.82 +// ------------------------------------------------------------------------------------------------
  195.83 +//	Destructor.
  195.84 +ObjFileImporter::~ObjFileImporter()
  195.85 +{
  195.86 +	// Release root object instance
  195.87 +	if (NULL != m_pRootObject)
  195.88 +	{
  195.89 +		delete m_pRootObject;
  195.90 +		m_pRootObject = NULL;
  195.91 +	}
  195.92 +}
  195.93 +
  195.94 +// ------------------------------------------------------------------------------------------------
  195.95 +//	Returns true, if file is an obj file.
  195.96 +bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem*  pIOHandler , bool checkSig ) const
  195.97 +{
  195.98 +	if(!checkSig) //Check File Extension
  195.99 +	{
 195.100 +		return SimpleExtensionCheck(pFile,"obj");
 195.101 +	}
 195.102 +	else //Check file Header
 195.103 +	{
 195.104 +		static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " };
 195.105 +		return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9 );
 195.106 +	}
 195.107 +}
 195.108 +
 195.109 +// ------------------------------------------------------------------------------------------------
 195.110 +const aiImporterDesc* ObjFileImporter::GetInfo () const
 195.111 +{
 195.112 +	return &desc;
 195.113 +}
 195.114 +
 195.115 +// ------------------------------------------------------------------------------------------------
 195.116 +//	Obj-file import implementation
 195.117 +void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
 195.118 +{
 195.119 +    DefaultIOSystem io;
 195.120 +    
 195.121 +	// Read file into memory
 195.122 +	const std::string mode = "rb";
 195.123 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode));
 195.124 +	if (NULL == file.get())
 195.125 +		throw DeadlyImportError( "Failed to open file " + pFile + ".");
 195.126 +
 195.127 +	// Get the file-size and validate it, throwing an exception when fails
 195.128 +	size_t fileSize = file->FileSize();
 195.129 +	if( fileSize < 16)
 195.130 +		throw DeadlyImportError( "OBJ-file is too small.");
 195.131 +
 195.132 +	// Allocate buffer and read file into it
 195.133 +	TextFileToBuffer(file.get(),m_Buffer);
 195.134 +
 195.135 +	// Get the model name
 195.136 +	std::string  strModelName;
 195.137 +	std::string::size_type pos = pFile.find_last_of( "\\/" );
 195.138 +	if ( pos != std::string::npos )	
 195.139 +	{
 195.140 +		strModelName = pFile.substr(pos+1, pFile.size() - pos - 1);
 195.141 +	}
 195.142 +	else
 195.143 +	{
 195.144 +		strModelName = pFile;
 195.145 +	}
 195.146 +	
 195.147 +	// parse the file into a temporary representation
 195.148 +	ObjFileParser parser(m_Buffer, strModelName, pIOHandler);
 195.149 +
 195.150 +	// And create the proper return structures out of it
 195.151 +	CreateDataFromImport(parser.GetModel(), pScene);
 195.152 +
 195.153 +	// Clean up allocated storage for the next import 
 195.154 +	m_Buffer.clear();
 195.155 +}
 195.156 +
 195.157 +// ------------------------------------------------------------------------------------------------
 195.158 +//	Create the data from parsed obj-file
 195.159 +void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene)
 195.160 +{
 195.161 +	if (0L == pModel)
 195.162 +		return;
 195.163 +		
 195.164 +	// Create the root node of the scene
 195.165 +	pScene->mRootNode = new aiNode;
 195.166 +	if ( !pModel->m_ModelName.empty() )
 195.167 +	{
 195.168 +		// Set the name of the scene
 195.169 +		pScene->mRootNode->mName.Set(pModel->m_ModelName);
 195.170 +	}
 195.171 +	else
 195.172 +	{
 195.173 +		// This is an error, so break down the application
 195.174 +		ai_assert(false);
 195.175 +	}
 195.176 +
 195.177 +	// Create nodes for the whole scene	
 195.178 +	std::vector<aiMesh*> MeshArray;
 195.179 +	for (size_t index = 0; index < pModel->m_Objects.size(); index++)
 195.180 +	{
 195.181 +		createNodes(pModel, pModel->m_Objects[ index ], index, pScene->mRootNode, pScene, MeshArray);
 195.182 +	}
 195.183 +
 195.184 +	// Create mesh pointer buffer for this scene
 195.185 +	if (pScene->mNumMeshes > 0)
 195.186 +	{
 195.187 +		pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
 195.188 +		for (size_t index =0; index < MeshArray.size(); index++)
 195.189 +		{
 195.190 +			pScene->mMeshes [ index ] = MeshArray[ index ];
 195.191 +		}
 195.192 +	}
 195.193 +
 195.194 +	// Create all materials
 195.195 +	createMaterials( pModel, pScene );
 195.196 +}
 195.197 +
 195.198 +// ------------------------------------------------------------------------------------------------
 195.199 +//	Creates all nodes of the model
 195.200 +aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pObject, 
 195.201 +									 unsigned int /*uiMeshIndex*/,
 195.202 +									 aiNode *pParent, aiScene* pScene, 
 195.203 +									 std::vector<aiMesh*> &MeshArray )
 195.204 +{
 195.205 +	ai_assert( NULL != pModel );
 195.206 +	if ( NULL == pObject )
 195.207 +		return NULL;
 195.208 +	
 195.209 +	// Store older mesh size to be able to computes mesh offsets for new mesh instances
 195.210 +	const size_t oldMeshSize = MeshArray.size();
 195.211 +	aiNode *pNode = new aiNode;
 195.212 +
 195.213 +	pNode->mName = pObject->m_strObjName;
 195.214 +	
 195.215 +	// If we have a parent node, store it
 195.216 +	if (pParent != NULL)
 195.217 +		appendChildToParentNode(pParent, pNode);
 195.218 +
 195.219 +	for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ )
 195.220 +	{
 195.221 +		unsigned int meshId = pObject->m_Meshes[ i ];
 195.222 +		aiMesh *pMesh = new aiMesh;
 195.223 +		createTopology( pModel, pObject, meshId, pMesh );	
 195.224 +		if ( pMesh->mNumVertices > 0 ) 
 195.225 +		{
 195.226 +			MeshArray.push_back( pMesh );
 195.227 +		}
 195.228 +		else
 195.229 +		{
 195.230 +			delete pMesh;
 195.231 +		}
 195.232 +	}
 195.233 +
 195.234 +	// Create all nodes from the sub-objects stored in the current object
 195.235 +	if ( !pObject->m_SubObjects.empty() )
 195.236 +	{
 195.237 +		size_t numChilds = pObject->m_SubObjects.size();
 195.238 +		pNode->mNumChildren = static_cast<unsigned int>( numChilds );
 195.239 +		pNode->mChildren = new aiNode*[ numChilds ];
 195.240 +		pNode->mNumMeshes = 1;
 195.241 +		pNode->mMeshes = new unsigned int[ 1 ];
 195.242 +	}
 195.243 +
 195.244 +	// Set mesh instances into scene- and node-instances
 195.245 +	const size_t meshSizeDiff = MeshArray.size()- oldMeshSize;
 195.246 +	if ( meshSizeDiff > 0 )
 195.247 +	{
 195.248 +		pNode->mMeshes = new unsigned int[ meshSizeDiff ];
 195.249 +		pNode->mNumMeshes = static_cast<unsigned int>( meshSizeDiff );
 195.250 +		size_t index = 0;
 195.251 +		for (size_t i = oldMeshSize; i < MeshArray.size(); i++)
 195.252 +		{
 195.253 +			pNode->mMeshes[ index ] = pScene->mNumMeshes;
 195.254 +			pScene->mNumMeshes++;
 195.255 +			index++;
 195.256 +		}
 195.257 +	}
 195.258 +	
 195.259 +	return pNode;
 195.260 +}
 195.261 +
 195.262 +// ------------------------------------------------------------------------------------------------
 195.263 +//	Create topology data
 195.264 +void ObjFileImporter::createTopology(const ObjFile::Model* pModel, 
 195.265 +									 const ObjFile::Object* pData, 
 195.266 +									 unsigned int uiMeshIndex,
 195.267 +									 aiMesh* pMesh )
 195.268 +{
 195.269 +	// Checking preconditions
 195.270 +	ai_assert( NULL != pModel );
 195.271 +	if (NULL == pData)
 195.272 +		return;
 195.273 +
 195.274 +	// Create faces
 195.275 +	ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
 195.276 +	ai_assert( NULL != pObjMesh );
 195.277 +
 195.278 +	pMesh->mNumFaces = 0;
 195.279 +	for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
 195.280 +	{
 195.281 +		ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
 195.282 +		if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
 195.283 +			pMesh->mNumFaces += inp->m_pVertices->size() - 1;
 195.284 +		}
 195.285 +		else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
 195.286 +			pMesh->mNumFaces += inp->m_pVertices->size();
 195.287 +		}
 195.288 +		else {
 195.289 +			++pMesh->mNumFaces;
 195.290 +		}
 195.291 +	}
 195.292 +
 195.293 +	unsigned int uiIdxCount = 0u;
 195.294 +	if ( pMesh->mNumFaces > 0 )
 195.295 +	{
 195.296 +		pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
 195.297 +		if ( pObjMesh->m_uiMaterialIndex != ObjFile::Mesh::NoMaterial )
 195.298 +		{
 195.299 +			pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex;
 195.300 +		}
 195.301 +
 195.302 +		unsigned int outIndex = 0;
 195.303 +
 195.304 +		// Copy all data from all stored meshes
 195.305 +		for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
 195.306 +		{
 195.307 +			ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
 195.308 +			if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
 195.309 +				for(size_t i = 0; i < inp->m_pVertices->size() - 1; ++i) {
 195.310 +					aiFace& f = pMesh->mFaces[ outIndex++ ];
 195.311 +					uiIdxCount += f.mNumIndices = 2;
 195.312 +					f.mIndices = new unsigned int[2];
 195.313 +				}
 195.314 +				continue;
 195.315 +			}
 195.316 +			else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
 195.317 +				for(size_t i = 0; i < inp->m_pVertices->size(); ++i) {
 195.318 +					aiFace& f = pMesh->mFaces[ outIndex++ ];
 195.319 +					uiIdxCount += f.mNumIndices = 1;
 195.320 +					f.mIndices = new unsigned int[1];
 195.321 +				}
 195.322 +				continue;
 195.323 +			}
 195.324 +
 195.325 +			aiFace *pFace = &pMesh->mFaces[ outIndex++ ];
 195.326 +			const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_pVertices->size();
 195.327 +			uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices;
 195.328 +			if (pFace->mNumIndices > 0) {
 195.329 +				pFace->mIndices = new unsigned int[ uiNumIndices ];			
 195.330 +			}
 195.331 +		}
 195.332 +	}
 195.333 +
 195.334 +	// Create mesh vertices
 195.335 +	createVertexArray(pModel, pData, uiMeshIndex, pMesh, uiIdxCount);
 195.336 +}
 195.337 +
 195.338 +// ------------------------------------------------------------------------------------------------
 195.339 +//	Creates a vertex array
 195.340 +void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, 
 195.341 +										const ObjFile::Object* pCurrentObject, 
 195.342 +										unsigned int uiMeshIndex,
 195.343 +										aiMesh* pMesh,
 195.344 +										unsigned int uiIdxCount)
 195.345 +{
 195.346 +	// Checking preconditions
 195.347 +	ai_assert( NULL != pCurrentObject );
 195.348 +	
 195.349 +	// Break, if no faces are stored in object
 195.350 +	if ( pCurrentObject->m_Meshes.empty() )
 195.351 +		return;
 195.352 +
 195.353 +	// Get current mesh
 195.354 +	ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
 195.355 +	if ( NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1)
 195.356 +		return;
 195.357 +
 195.358 +	// Copy vertices of this mesh instance
 195.359 +	pMesh->mNumVertices = uiIdxCount;
 195.360 +	pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
 195.361 +	
 195.362 +	// Allocate buffer for normal vectors
 195.363 +	if ( !pModel->m_Normals.empty() && pObjMesh->m_hasNormals )
 195.364 +		pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ];
 195.365 +	
 195.366 +	// Allocate buffer for texture coordinates
 195.367 +	if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] )
 195.368 +	{
 195.369 +		pMesh->mNumUVComponents[ 0 ] = 2;
 195.370 +		pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ];
 195.371 +	}
 195.372 +	
 195.373 +	// Copy vertices, normals and textures into aiMesh instance
 195.374 +	unsigned int newIndex = 0, outIndex = 0;
 195.375 +	for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ )
 195.376 +	{
 195.377 +		// Get source face
 195.378 +		ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ]; 
 195.379 +
 195.380 +		// Copy all index arrays
 195.381 +		for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ )
 195.382 +		{
 195.383 +			const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex );
 195.384 +			if ( vertex >= pModel->m_Vertices.size() ) 
 195.385 +				throw DeadlyImportError( "OBJ: vertex index out of range" );
 195.386 +			
 195.387 +			pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
 195.388 +			
 195.389 +			// Copy all normals 
 195.390 +			if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty())
 195.391 +			{
 195.392 +				const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex );
 195.393 +				if ( normal >= pModel->m_Normals.size() )
 195.394 +					throw DeadlyImportError("OBJ: vertex normal index out of range");
 195.395 +
 195.396 +				pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ];
 195.397 +			}
 195.398 +			
 195.399 +			// Copy all texture coordinates
 195.400 +			if ( !pModel->m_TextureCoord.empty() )
 195.401 +			{
 195.402 +				if ( !pSourceFace->m_pTexturCoords->empty() )
 195.403 +				{
 195.404 +					const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex );
 195.405 +					ai_assert( tex < pModel->m_TextureCoord.size() );
 195.406 +					for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ )
 195.407 +					{
 195.408 +						if ( tex >= pModel->m_TextureCoord.size() )
 195.409 +							throw DeadlyImportError("OBJ: texture coord index out of range");
 195.410 +
 195.411 +						aiVector2D coord2d = pModel->m_TextureCoord[ tex ];
 195.412 +						pMesh->mTextureCoords[ i ][ newIndex ] = aiVector3D( coord2d.x, coord2d.y, 0.0 );
 195.413 +					}
 195.414 +				}
 195.415 +			}
 195.416 +
 195.417 +			ai_assert( pMesh->mNumVertices > newIndex );
 195.418 +
 195.419 +			// Get destination face
 195.420 +			aiFace *pDestFace = &pMesh->mFaces[ outIndex ];
 195.421 +
 195.422 +			const bool last = ( vertexIndex == pSourceFace->m_pVertices->size() - 1 ); 
 195.423 +			if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) 
 195.424 +			{
 195.425 +				pDestFace->mIndices[ outVertexIndex ] = newIndex;
 195.426 +				outVertexIndex++;
 195.427 +			}
 195.428 +
 195.429 +			if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) 
 195.430 +			{
 195.431 +				outIndex++;
 195.432 +				outVertexIndex = 0;
 195.433 +			}
 195.434 +			else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) 
 195.435 +			{
 195.436 +				outVertexIndex = 0;
 195.437 +
 195.438 +				if(!last) 
 195.439 +					outIndex++;
 195.440 +
 195.441 +				if (vertexIndex) {
 195.442 +					if(!last) {
 195.443 +						pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ];
 195.444 +						if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) {
 195.445 +							pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ];
 195.446 +						}
 195.447 +						if ( !pModel->m_TextureCoord.empty() ) {
 195.448 +							for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ ) {
 195.449 +								pMesh->mTextureCoords[ i ][ newIndex+1 ] = pMesh->mTextureCoords[ i ][ newIndex ];
 195.450 +							}
 195.451 +						}
 195.452 +						++newIndex;
 195.453 +					}
 195.454 +
 195.455 +					pDestFace[-1].mIndices[1] = newIndex;
 195.456 +				}
 195.457 +			}
 195.458 +			else if (last) {
 195.459 +				outIndex++;
 195.460 +			}
 195.461 +			++newIndex;
 195.462 +		}
 195.463 +	}	
 195.464 +}
 195.465 +
 195.466 +// ------------------------------------------------------------------------------------------------
 195.467 +//	Counts all stored meshes 
 195.468 +void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes)
 195.469 +{
 195.470 +	iNumMeshes = 0;
 195.471 +	if ( rObjects.empty() )	
 195.472 +		return;
 195.473 +
 195.474 +	iNumMeshes += static_cast<unsigned int>( rObjects.size() );
 195.475 +	for (std::vector<ObjFile::Object*>::const_iterator it = rObjects.begin();
 195.476 +		it != rObjects.end(); 
 195.477 +		++it)
 195.478 +	{
 195.479 +		if (!(*it)->m_SubObjects.empty())
 195.480 +		{
 195.481 +			countObjects((*it)->m_SubObjects, iNumMeshes);
 195.482 +		}
 195.483 +	}
 195.484 +}
 195.485 +
 195.486 +// ------------------------------------------------------------------------------------------------
 195.487 +//	Creates the material 
 195.488 +void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pScene )
 195.489 +{
 195.490 +	ai_assert( NULL != pScene );
 195.491 +	if ( NULL == pScene )
 195.492 +		return;
 195.493 +
 195.494 +	const unsigned int numMaterials = (unsigned int) pModel->m_MaterialLib.size();
 195.495 +	pScene->mNumMaterials = 0;
 195.496 +	if ( pModel->m_MaterialLib.empty() ) {
 195.497 +		DefaultLogger::get()->debug("OBJ: no materials specified");
 195.498 +		return;
 195.499 +	}
 195.500 +	
 195.501 +	pScene->mMaterials = new aiMaterial*[ numMaterials ];
 195.502 +	for ( unsigned int matIndex = 0; matIndex < numMaterials; matIndex++ )
 195.503 +	{		
 195.504 +		// Store material name
 195.505 +		std::map<std::string, ObjFile::Material*>::const_iterator it;
 195.506 +		it = pModel->m_MaterialMap.find( pModel->m_MaterialLib[ matIndex ] );
 195.507 +		
 195.508 +		// No material found, use the default material
 195.509 +		if ( pModel->m_MaterialMap.end() == it )
 195.510 +			continue;
 195.511 +
 195.512 +		aiMaterial* mat = new aiMaterial;
 195.513 +		ObjFile::Material *pCurrentMaterial = (*it).second;
 195.514 +		mat->AddProperty( &pCurrentMaterial->MaterialName, AI_MATKEY_NAME );
 195.515 +
 195.516 +		// convert illumination model
 195.517 +		int sm = 0;
 195.518 +		switch (pCurrentMaterial->illumination_model) 
 195.519 +		{
 195.520 +		case 0:
 195.521 +			sm = aiShadingMode_NoShading;
 195.522 +			break;
 195.523 +		case 1:
 195.524 +			sm = aiShadingMode_Gouraud;
 195.525 +			break;
 195.526 +		case 2:
 195.527 +			sm = aiShadingMode_Phong;
 195.528 +			break;
 195.529 +		default:
 195.530 +			sm = aiShadingMode_Gouraud;
 195.531 +			DefaultLogger::get()->error("OBJ: unexpected illumination model (0-2 recognized)");
 195.532 +		}
 195.533 +	
 195.534 +		mat->AddProperty<int>( &sm, 1, AI_MATKEY_SHADING_MODEL);
 195.535 +
 195.536 +		// multiplying the specular exponent with 2 seems to yield better results
 195.537 +		pCurrentMaterial->shineness *= 4.f;
 195.538 +
 195.539 +		// Adding material colors
 195.540 +		mat->AddProperty( &pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT );
 195.541 +		mat->AddProperty( &pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE );
 195.542 +		mat->AddProperty( &pCurrentMaterial->specular, 1, AI_MATKEY_COLOR_SPECULAR );
 195.543 +		mat->AddProperty( &pCurrentMaterial->shineness, 1, AI_MATKEY_SHININESS );
 195.544 +		mat->AddProperty( &pCurrentMaterial->alpha, 1, AI_MATKEY_OPACITY );
 195.545 +
 195.546 +		// Adding refraction index
 195.547 +		mat->AddProperty( &pCurrentMaterial->ior, 1, AI_MATKEY_REFRACTI );
 195.548 +
 195.549 +		// Adding textures
 195.550 +		if ( 0 != pCurrentMaterial->texture.length )
 195.551 +			mat->AddProperty( &pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0));
 195.552 +
 195.553 +		if ( 0 != pCurrentMaterial->textureAmbient.length )
 195.554 +			mat->AddProperty( &pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0));
 195.555 +
 195.556 +		if ( 0 != pCurrentMaterial->textureSpecular.length )
 195.557 +			mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0));
 195.558 +
 195.559 +		if ( 0 != pCurrentMaterial->textureBump.length )
 195.560 +			mat->AddProperty( &pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0));
 195.561 +
 195.562 +		if ( 0 != pCurrentMaterial->textureNormal.length )
 195.563 +			mat->AddProperty( &pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0));
 195.564 +
 195.565 +		if ( 0 != pCurrentMaterial->textureDisp.length )
 195.566 +			mat->AddProperty( &pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0) );
 195.567 +
 195.568 +		if ( 0 != pCurrentMaterial->textureOpacity.length )
 195.569 +			mat->AddProperty( &pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0));
 195.570 +
 195.571 +		if ( 0 != pCurrentMaterial->textureSpecularity.length )
 195.572 +			mat->AddProperty( &pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0));
 195.573 +		
 195.574 +		// Store material property info in material array in scene
 195.575 +		pScene->mMaterials[ pScene->mNumMaterials ] = mat;
 195.576 +		pScene->mNumMaterials++;
 195.577 +	}
 195.578 +	
 195.579 +	// Test number of created materials.
 195.580 +	ai_assert( pScene->mNumMaterials == numMaterials );
 195.581 +}
 195.582 +
 195.583 +// ------------------------------------------------------------------------------------------------
 195.584 +//	Appends this node to the parent node
 195.585 +void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
 195.586 +{
 195.587 +	// Checking preconditions
 195.588 +	ai_assert( NULL != pParent );
 195.589 +	ai_assert( NULL != pChild );
 195.590 +
 195.591 +	// Assign parent to child
 195.592 +	pChild->mParent = pParent;
 195.593 +	size_t sNumChildren = 0;
 195.594 +	(void)sNumChildren; // remove warning on release build
 195.595 +	
 195.596 +	// If already children was assigned to the parent node, store them in a 
 195.597 +	std::vector<aiNode*> temp;
 195.598 +	if (pParent->mChildren != NULL)
 195.599 +	{
 195.600 +		sNumChildren = pParent->mNumChildren;
 195.601 +		ai_assert( 0 != sNumChildren );
 195.602 +		for (size_t index = 0; index < pParent->mNumChildren; index++)
 195.603 +		{
 195.604 +			temp.push_back(pParent->mChildren [ index ] );
 195.605 +		}
 195.606 +		delete [] pParent->mChildren;
 195.607 +	}
 195.608 +	
 195.609 +	// Copy node instances into parent node
 195.610 +	pParent->mNumChildren++;
 195.611 +	pParent->mChildren = new aiNode*[ pParent->mNumChildren ];
 195.612 +	for (size_t index = 0; index < pParent->mNumChildren-1; index++)
 195.613 +	{
 195.614 +		pParent->mChildren[ index ] = temp [ index ];
 195.615 +	}
 195.616 +	pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
 195.617 +}
 195.618 +
 195.619 +// ------------------------------------------------------------------------------------------------
 195.620 +
 195.621 +}	// Namespace Assimp
 195.622 +
 195.623 +#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER
   196.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   196.2 +++ b/libs/assimp/ObjFileImporter.h	Sat Feb 01 19:58:19 2014 +0200
   196.3 @@ -0,0 +1,126 @@
   196.4 +/*
   196.5 +Open Asset Import Library (assimp)
   196.6 +----------------------------------------------------------------------
   196.7 +
   196.8 +Copyright (c) 2006-2012, assimp team
   196.9 +All rights reserved.
  196.10 +
  196.11 +Redistribution and use of this software in source and binary forms, 
  196.12 +with or without modification, are permitted provided that the 
  196.13 +following conditions are met:
  196.14 +
  196.15 +* Redistributions of source code must retain the above
  196.16 +  copyright notice, this list of conditions and the
  196.17 +  following disclaimer.
  196.18 +
  196.19 +* Redistributions in binary form must reproduce the above
  196.20 +  copyright notice, this list of conditions and the
  196.21 +  following disclaimer in the documentation and/or other
  196.22 +  materials provided with the distribution.
  196.23 +
  196.24 +* Neither the name of the assimp team, nor the names of its
  196.25 +  contributors may be used to endorse or promote products
  196.26 +  derived from this software without specific prior
  196.27 +  written permission of the assimp team.
  196.28 +
  196.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  196.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  196.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  196.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  196.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  196.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  196.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  196.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  196.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  196.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  196.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  196.40 +
  196.41 +----------------------------------------------------------------------
  196.42 +*/
  196.43 +
  196.44 +
  196.45 +#ifndef OBJ_FILE_IMPORTER_H_INC
  196.46 +#define OBJ_FILE_IMPORTER_H_INC
  196.47 +
  196.48 +#include "BaseImporter.h"
  196.49 +#include <vector>
  196.50 +
  196.51 +struct aiMesh;
  196.52 +struct aiNode;
  196.53 +
  196.54 +namespace Assimp
  196.55 +{
  196.56 +
  196.57 +namespace ObjFile
  196.58 +{
  196.59 +struct Object;
  196.60 +struct Model;
  196.61 +}
  196.62 +
  196.63 +// ------------------------------------------------------------------------------------------------
  196.64 +///	\class	ObjFileImporter
  196.65 +///	\brief	Imports a waveform obj file
  196.66 +// ------------------------------------------------------------------------------------------------
  196.67 +class ObjFileImporter : public BaseImporter
  196.68 +{	
  196.69 +public:
  196.70 +	///	\brief	Default constructor
  196.71 +	ObjFileImporter();
  196.72 +
  196.73 +	///	\brief	Destructor
  196.74 +	~ObjFileImporter();
  196.75 +
  196.76 +public:
  196.77 +	/// \brief	Returns whether the class can handle the format of the given file. 
  196.78 +	/// \remark	See BaseImporter::CanRead() for details.
  196.79 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
  196.80 +
  196.81 +private:
  196.82 +
  196.83 +	//! \brief	Appends the supported extention.
  196.84 +	const aiImporterDesc* GetInfo () const;
  196.85 +
  196.86 +	//!	\brief	File import implementation.
  196.87 +	void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
  196.88 +	
  196.89 +	//!	\brief	Create the data from imported content.
  196.90 +	void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene);
  196.91 +	
  196.92 +	//!	\brief	Creates all nodes stored in imported content.
  196.93 +	aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData, unsigned int uiMeshIndex,
  196.94 +		aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
  196.95 +
  196.96 +	//!	\brief	Creates topology data like faces and meshes for the geometry.
  196.97 +	void createTopology(const ObjFile::Model* pModel, const ObjFile::Object* pData,
  196.98 +		unsigned int uiMeshIndex, aiMesh* pMesh);	
  196.99 +	
 196.100 +	//!	\brief	Creates vertices from model.
 196.101 +	void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
 196.102 +		unsigned int uiMeshIndex, aiMesh* pMesh,unsigned int uiIdxCount);
 196.103 +
 196.104 +	//!	\brief	Object counter helper method.
 196.105 +	void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);
 196.106 +
 196.107 +	//!	\brief	Material creation.
 196.108 +	void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
 196.109 +
 196.110 +	//!	\brief	Appends a child node to a parentnode and updates the datastructures.
 196.111 +	void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
 196.112 +
 196.113 +	//!	\brief TODO!
 196.114 +	void createAnimations();
 196.115 +
 196.116 +private:
 196.117 +	//!	Data buffer
 196.118 +	std::vector<char> m_Buffer;
 196.119 +	//!	Pointer to root object instance
 196.120 +	ObjFile::Object *m_pRootObject;
 196.121 +	//!	Absolute pathname of model in filesystem
 196.122 +	std::string m_strAbsPath;
 196.123 +};
 196.124 +
 196.125 +// ------------------------------------------------------------------------------------------------
 196.126 +
 196.127 +} // Namespace Assimp
 196.128 +
 196.129 +#endif
   197.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   197.2 +++ b/libs/assimp/ObjFileMtlImporter.cpp	Sat Feb 01 19:58:19 2014 +0200
   197.3 @@ -0,0 +1,311 @@
   197.4 +/*
   197.5 +---------------------------------------------------------------------------
   197.6 +Open Asset Import Library (assimp)
   197.7 +---------------------------------------------------------------------------
   197.8 +
   197.9 +Copyright (c) 2006-2012, assimp team
  197.10 +
  197.11 +All rights reserved.
  197.12 +
  197.13 +Redistribution and use of this software in source and binary forms, 
  197.14 +with or without modification, are permitted provided that the following 
  197.15 +conditions are met:
  197.16 +
  197.17 +* Redistributions of source code must retain the above
  197.18 +  copyright notice, this list of conditions and the
  197.19 +  following disclaimer.
  197.20 +
  197.21 +* Redistributions in binary form must reproduce the above
  197.22 +  copyright notice, this list of conditions and the
  197.23 +  following disclaimer in the documentation and/or other
  197.24 +  materials provided with the distribution.
  197.25 +
  197.26 +* Neither the name of the assimp team, nor the names of its
  197.27 +  contributors may be used to endorse or promote products
  197.28 +  derived from this software without specific prior
  197.29 +  written permission of the assimp team.
  197.30 +
  197.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  197.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  197.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  197.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  197.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  197.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  197.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  197.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  197.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  197.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  197.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  197.42 +---------------------------------------------------------------------------
  197.43 +*/
  197.44 +
  197.45 +#include "AssimpPCH.h"
  197.46 +#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
  197.47 +
  197.48 +#include "ObjFileMtlImporter.h"
  197.49 +#include "ObjTools.h"
  197.50 +#include "ObjFileData.h"
  197.51 +#include "fast_atof.h"
  197.52 +
  197.53 +namespace Assimp	{
  197.54 +
  197.55 +// Material specific token
  197.56 +static const std::string DiffuseTexture      = "map_kd";
  197.57 +static const std::string AmbientTexture      = "map_ka";
  197.58 +static const std::string SpecularTexture     = "map_ks";
  197.59 +static const std::string OpacityTexture      = "map_d";
  197.60 +static const std::string BumpTexture1        = "map_bump";
  197.61 +static const std::string BumpTexture2        = "map_Bump";
  197.62 +static const std::string BumpTexture3        = "bump";
  197.63 +static const std::string NormalTexture       = "map_Kn";
  197.64 +static const std::string DisplacementTexture = "disp";
  197.65 +static const std::string SpecularityTexture  = "map_ns";
  197.66 +
  197.67 +// -------------------------------------------------------------------
  197.68 +//	Constructor
  197.69 +ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer, 
  197.70 +									   const std::string & /*strAbsPath*/,
  197.71 +									   ObjFile::Model *pModel ) :
  197.72 +	m_DataIt( buffer.begin() ),
  197.73 +	m_DataItEnd( buffer.end() ),
  197.74 +	m_pModel( pModel ),
  197.75 +	m_uiLine( 0 )
  197.76 +{
  197.77 +	ai_assert( NULL != m_pModel );
  197.78 +	if ( NULL == m_pModel->m_pDefaultMaterial )
  197.79 +	{
  197.80 +		m_pModel->m_pDefaultMaterial = new ObjFile::Material;
  197.81 +		m_pModel->m_pDefaultMaterial->MaterialName.Set( "default" );
  197.82 +	}
  197.83 +	load();
  197.84 +}
  197.85 +
  197.86 +// -------------------------------------------------------------------
  197.87 +//	Destructor
  197.88 +ObjFileMtlImporter::~ObjFileMtlImporter()
  197.89 +{
  197.90 +	// empty
  197.91 +}
  197.92 +
  197.93 +// -------------------------------------------------------------------
  197.94 +//	Private copy constructor
  197.95 +ObjFileMtlImporter::ObjFileMtlImporter(const ObjFileMtlImporter & /* rOther */ )
  197.96 +{
  197.97 +	// empty
  197.98 +}
  197.99 +	
 197.100 +// -------------------------------------------------------------------
 197.101 +//	Private copy constructor
 197.102 +ObjFileMtlImporter &ObjFileMtlImporter::operator = ( const ObjFileMtlImporter & /*rOther */ )
 197.103 +{
 197.104 +	return *this;
 197.105 +}
 197.106 +
 197.107 +// -------------------------------------------------------------------
 197.108 +//	Loads the material description
 197.109 +void ObjFileMtlImporter::load()
 197.110 +{
 197.111 +	if ( m_DataIt == m_DataItEnd )
 197.112 +		return;
 197.113 +
 197.114 +	while ( m_DataIt != m_DataItEnd )
 197.115 +	{
 197.116 +		switch (*m_DataIt)
 197.117 +		{
 197.118 +		case 'K':
 197.119 +			{
 197.120 +				++m_DataIt;
 197.121 +				if (*m_DataIt == 'a') // Ambient color
 197.122 +				{
 197.123 +					++m_DataIt;
 197.124 +					getColorRGBA( &m_pModel->m_pCurrentMaterial->ambient );
 197.125 +				}
 197.126 +				else if (*m_DataIt == 'd')	// Diffuse color
 197.127 +				{
 197.128 +					++m_DataIt;
 197.129 +					getColorRGBA( &m_pModel->m_pCurrentMaterial->diffuse );
 197.130 +				}
 197.131 +				else if (*m_DataIt == 's')
 197.132 +				{
 197.133 +					++m_DataIt;
 197.134 +					getColorRGBA( &m_pModel->m_pCurrentMaterial->specular );
 197.135 +				}
 197.136 +				m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 197.137 +			}
 197.138 +			break;
 197.139 +
 197.140 +		case 'd':	// Alpha value
 197.141 +			{
 197.142 +				++m_DataIt;
 197.143 +				getFloatValue( m_pModel->m_pCurrentMaterial->alpha );
 197.144 +				m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 197.145 +			}
 197.146 +			break;
 197.147 +
 197.148 +		case 'N':	// Shineness
 197.149 +			{
 197.150 +				++m_DataIt;
 197.151 +				switch(*m_DataIt) 
 197.152 +				{
 197.153 +				case 's':
 197.154 +					++m_DataIt;
 197.155 +					getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
 197.156 +					break;
 197.157 +				case 'i': //Index Of refraction 
 197.158 +					++m_DataIt;
 197.159 +					getFloatValue(m_pModel->m_pCurrentMaterial->ior);
 197.160 +					break;
 197.161 +				}
 197.162 +				m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 197.163 +				break;
 197.164 +			}
 197.165 +			break;
 197.166 +		
 197.167 +
 197.168 +		case 'm':	// Texture
 197.169 +		case 'b':   // quick'n'dirty - for 'bump' sections
 197.170 +			{
 197.171 +				getTexture();
 197.172 +				m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 197.173 +			}
 197.174 +			break;
 197.175 +
 197.176 +		case 'n':	// New material name
 197.177 +			{
 197.178 +				createMaterial();
 197.179 +				m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 197.180 +			}
 197.181 +			break;
 197.182 +
 197.183 +		case 'i':	// Illumination model
 197.184 +			{
 197.185 +				m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
 197.186 +				getIlluminationModel( m_pModel->m_pCurrentMaterial->illumination_model );
 197.187 +				m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 197.188 +			}
 197.189 +			break;
 197.190 +
 197.191 +		default:
 197.192 +			{
 197.193 +				m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 197.194 +			}
 197.195 +			break;
 197.196 +		}
 197.197 +	}
 197.198 +}
 197.199 +
 197.200 +// -------------------------------------------------------------------
 197.201 +//	Loads a color definition
 197.202 +void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor )
 197.203 +{
 197.204 +	ai_assert( NULL != pColor );
 197.205 +	
 197.206 +	float r, g, b;
 197.207 +	m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, r );
 197.208 +	pColor->r = r;
 197.209 +	
 197.210 +	m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, g );
 197.211 +	pColor->g = g;
 197.212 +
 197.213 +	m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, b );
 197.214 +	pColor->b = b;
 197.215 +}
 197.216 +
 197.217 +// -------------------------------------------------------------------
 197.218 +//	Loads the kind of illumination model.
 197.219 +void ObjFileMtlImporter::getIlluminationModel( int &illum_model )
 197.220 +{
 197.221 +	m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
 197.222 +	illum_model = atoi(m_buffer);
 197.223 +}
 197.224 +
 197.225 +// -------------------------------------------------------------------
 197.226 +//	Loads a single float value. 
 197.227 +void ObjFileMtlImporter::getFloatValue( float &value )
 197.228 +{
 197.229 +	m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
 197.230 +	value = (float) fast_atof(m_buffer);
 197.231 +}
 197.232 +
 197.233 +// -------------------------------------------------------------------
 197.234 +//	Creates a material from loaded data.
 197.235 +void ObjFileMtlImporter::createMaterial()
 197.236 +{	
 197.237 +	std::string line( "" );
 197.238 +	while ( !isNewLine( *m_DataIt ) ) {
 197.239 +		line += *m_DataIt;
 197.240 +		++m_DataIt;
 197.241 +	}
 197.242 +	
 197.243 +	std::vector<std::string> token;
 197.244 +	const unsigned int numToken = tokenize<std::string>( line, token, " " );
 197.245 +	std::string name( "" );
 197.246 +	if ( numToken == 1 ) {
 197.247 +		name = AI_DEFAULT_MATERIAL_NAME;
 197.248 +	} else {
 197.249 +		name = token[ 1 ];
 197.250 +	}
 197.251 +
 197.252 +	std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( name );
 197.253 +	if ( m_pModel->m_MaterialMap.end() == it) {
 197.254 +		// New Material created
 197.255 +		m_pModel->m_pCurrentMaterial = new ObjFile::Material();	
 197.256 +		m_pModel->m_pCurrentMaterial->MaterialName.Set( name );
 197.257 +		m_pModel->m_MaterialLib.push_back( name );
 197.258 +		m_pModel->m_MaterialMap[ name ] = m_pModel->m_pCurrentMaterial;
 197.259 +	} else {
 197.260 +		// Use older material
 197.261 +		m_pModel->m_pCurrentMaterial = (*it).second;
 197.262 +	}
 197.263 +}
 197.264 +
 197.265 +// -------------------------------------------------------------------
 197.266 +//	Gets a texture name from data.
 197.267 +void ObjFileMtlImporter::getTexture() {
 197.268 +	aiString *out( NULL );
 197.269 +
 197.270 +	const char *pPtr( &(*m_DataIt) );
 197.271 +	if ( !ASSIMP_strincmp( pPtr, DiffuseTexture.c_str(), DiffuseTexture.size() ) ) {
 197.272 +		// Diffuse texture
 197.273 +		out = & m_pModel->m_pCurrentMaterial->texture;
 197.274 +	} else if ( !ASSIMP_strincmp( pPtr,AmbientTexture.c_str(),AmbientTexture.size() ) ) {
 197.275 +		// Ambient texture
 197.276 +		out = & m_pModel->m_pCurrentMaterial->textureAmbient;
 197.277 +	} else if (!ASSIMP_strincmp( pPtr, SpecularTexture.c_str(), SpecularTexture.size())) {
 197.278 +		// Specular texture
 197.279 +		out = & m_pModel->m_pCurrentMaterial->textureSpecular;
 197.280 +	} else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), OpacityTexture.size() ) ) {
 197.281 +		// Opacity texture
 197.282 +		out = & m_pModel->m_pCurrentMaterial->textureOpacity;
 197.283 +	} else if (!ASSIMP_strincmp( pPtr,"map_ka",6)) {
 197.284 +		// Ambient texture
 197.285 +		out = & m_pModel->m_pCurrentMaterial->textureAmbient;
 197.286 +	} else if ( !ASSIMP_strincmp( pPtr, BumpTexture1.c_str(), BumpTexture1.size() ) ||
 197.287 +		        !ASSIMP_strincmp( pPtr, BumpTexture2.c_str(), BumpTexture2.size() ) || 
 197.288 +		        !ASSIMP_strincmp( pPtr, BumpTexture3.c_str(), BumpTexture3.size() ) ) {
 197.289 +		// Bump texture 
 197.290 +		out = & m_pModel->m_pCurrentMaterial->textureBump;
 197.291 +	} else if (!ASSIMP_strincmp( pPtr,NormalTexture.c_str(), NormalTexture.size())) { 
 197.292 +		// Normal map
 197.293 +		out = & m_pModel->m_pCurrentMaterial->textureNormal;
 197.294 +	} else if (!ASSIMP_strincmp( pPtr, DisplacementTexture.c_str(), DisplacementTexture.size() ) ) {
 197.295 +		// Displacement texture
 197.296 +		out = &m_pModel->m_pCurrentMaterial->textureDisp;
 197.297 +	} else if (!ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(),SpecularityTexture.size() ) ) {
 197.298 +		// Specularity scaling (glossiness)
 197.299 +		out = & m_pModel->m_pCurrentMaterial->textureSpecularity;
 197.300 +	} else {
 197.301 +		DefaultLogger::get()->error("OBJ/MTL: Encountered unknown texture type");
 197.302 +		return;
 197.303 +	}
 197.304 +
 197.305 +	std::string strTexture;
 197.306 +	m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, strTexture );
 197.307 +	out->Set( strTexture );
 197.308 +}
 197.309 +
 197.310 +// -------------------------------------------------------------------
 197.311 +
 197.312 +} // Namespace Assimp
 197.313 +
 197.314 +#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER
   198.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   198.2 +++ b/libs/assimp/ObjFileMtlImporter.h	Sat Feb 01 19:58:19 2014 +0200
   198.3 @@ -0,0 +1,115 @@
   198.4 +/*
   198.5 +Open Asset Import Library (assimp)
   198.6 +----------------------------------------------------------------------
   198.7 +
   198.8 +Copyright (c) 2006-2012, assimp team
   198.9 +All rights reserved.
  198.10 +
  198.11 +Redistribution and use of this software in source and binary forms, 
  198.12 +with or without modification, are permitted provided that the 
  198.13 +following conditions are met:
  198.14 +
  198.15 +* Redistributions of source code must retain the above
  198.16 +  copyright notice, this list of conditions and the
  198.17 +  following disclaimer.
  198.18 +
  198.19 +* Redistributions in binary form must reproduce the above
  198.20 +  copyright notice, this list of conditions and the
  198.21 +  following disclaimer in the documentation and/or other
  198.22 +  materials provided with the distribution.
  198.23 +
  198.24 +* Neither the name of the assimp team, nor the names of its
  198.25 +  contributors may be used to endorse or promote products
  198.26 +  derived from this software without specific prior
  198.27 +  written permission of the assimp team.
  198.28 +
  198.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  198.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  198.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  198.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  198.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  198.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  198.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  198.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  198.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  198.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  198.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  198.40 +
  198.41 +----------------------------------------------------------------------*/
  198.42 +#ifndef OBJFILEMTLIMPORTER_H_INC
  198.43 +#define OBJFILEMTLIMPORTER_H_INC
  198.44 +
  198.45 +#include <vector>
  198.46 +#include <string>
  198.47 +
  198.48 +struct aiColor3D;
  198.49 +
  198.50 +namespace Assimp
  198.51 +{
  198.52 +
  198.53 +namespace ObjFile
  198.54 +{
  198.55 +struct Model;
  198.56 +struct Material;
  198.57 +
  198.58 +}
  198.59 +
  198.60 +
  198.61 +/**
  198.62 + *	@class	ObjFileMtlImporter
  198.63 + *	@brief	Loads the material description from a mtl file.
  198.64 + */
  198.65 +class ObjFileMtlImporter
  198.66 +{
  198.67 +public:
  198.68 +	static const size_t BUFFERSIZE = 2048;
  198.69 +	typedef std::vector<char> DataArray;
  198.70 +	typedef std::vector<char>::iterator DataArrayIt;
  198.71 +	typedef std::vector<char>::const_iterator ConstDataArrayIt;
  198.72 +
  198.73 +public:
  198.74 +	//!	\brief	Default constructor
  198.75 +	ObjFileMtlImporter( std::vector<char> &buffer, const std::string &strAbsPath, 
  198.76 +		ObjFile::Model *pModel );
  198.77 +	
  198.78 +	//!	\brief	DEstructor
  198.79 +	~ObjFileMtlImporter();
  198.80 +
  198.81 +private:
  198.82 +	///	Copy constructor, empty.
  198.83 +	ObjFileMtlImporter(const ObjFileMtlImporter &rOther);
  198.84 +	///	\brief	Assignment operator, returns only a reference of this instance.
  198.85 +	ObjFileMtlImporter &operator = (const ObjFileMtlImporter &rOther);
  198.86 +	///	Load the whole material description
  198.87 +	void load();
  198.88 +	///	Get color data.
  198.89 +	void getColorRGBA( aiColor3D *pColor);
  198.90 +	///	Get illumination model from loaded data
  198.91 +	void getIlluminationModel( int &illum_model );
  198.92 +	///	Gets a float value from data.	
  198.93 +	void getFloatValue( float &value );
  198.94 +	///	Creates a new material from loaded data.
  198.95 +	void createMaterial();
  198.96 +	///	Get texture name from loaded data.
  198.97 +	void getTexture();
  198.98 +
  198.99 +private:
 198.100 +	//!	Absolute pathname
 198.101 +	std::string m_strAbsPath;
 198.102 +	//!	Data iterator showing to the current position in data buffer
 198.103 +	DataArrayIt m_DataIt;
 198.104 +	//!	Data iterator to end of buffer
 198.105 +	DataArrayIt m_DataItEnd;
 198.106 +	//!	USed model instance
 198.107 +	ObjFile::Model *m_pModel;
 198.108 +	//!	Current line in file
 198.109 +	unsigned int m_uiLine;
 198.110 +	//!	Helper buffer
 198.111 +	char m_buffer[BUFFERSIZE];
 198.112 +};
 198.113 +
 198.114 +// ------------------------------------------------------------------------------------------------
 198.115 +
 198.116 +} // Namespace Assimp
 198.117 +
 198.118 +#endif
   199.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   199.2 +++ b/libs/assimp/ObjFileParser.cpp	Sat Feb 01 19:58:19 2014 +0200
   199.3 @@ -0,0 +1,679 @@
   199.4 +/*
   199.5 +---------------------------------------------------------------------------
   199.6 +Open Asset Import Library (assimp)
   199.7 +---------------------------------------------------------------------------
   199.8 +
   199.9 +Copyright (c) 2006-2012, assimp team
  199.10 +
  199.11 +All rights reserved.
  199.12 +
  199.13 +Redistribution and use of this software in source and binary forms, 
  199.14 +with or without modification, are permitted provided that the following 
  199.15 +conditions are met:
  199.16 +
  199.17 +* Redistributions of source code must retain the above
  199.18 +  copyright notice, this list of conditions and the
  199.19 +  following disclaimer.
  199.20 +
  199.21 +* Redistributions in binary form must reproduce the above
  199.22 +  copyright notice, this list of conditions and the
  199.23 +  following disclaimer in the documentation and/or other
  199.24 +  materials provided with the distribution.
  199.25 +
  199.26 +* Neither the name of the assimp team, nor the names of its
  199.27 +  contributors may be used to endorse or promote products
  199.28 +  derived from this software without specific prior
  199.29 +  written permission of the assimp team.
  199.30 +
  199.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  199.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  199.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  199.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  199.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  199.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  199.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  199.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  199.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  199.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  199.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  199.42 +---------------------------------------------------------------------------
  199.43 +*/
  199.44 +
  199.45 +#include "AssimpPCH.h"
  199.46 +#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
  199.47 +
  199.48 +#include "ObjFileParser.h"
  199.49 +#include "ObjFileMtlImporter.h"
  199.50 +#include "ObjTools.h"
  199.51 +#include "ObjFileData.h"
  199.52 +#include "ParsingUtils.h"
  199.53 +#include "assimp/types.h"
  199.54 +#include "DefaultIOSystem.h"
  199.55 +
  199.56 +namespace Assimp	
  199.57 +{
  199.58 +
  199.59 +// -------------------------------------------------------------------
  199.60 +const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME; 
  199.61 +
  199.62 +// -------------------------------------------------------------------
  199.63 +//	Constructor with loaded data and directories.
  199.64 +ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem *io ) :
  199.65 +	m_DataIt(Data.begin()),
  199.66 +	m_DataItEnd(Data.end()),
  199.67 +	m_pModel(NULL),
  199.68 +	m_uiLine(0),
  199.69 +	m_pIO( io )
  199.70 +{
  199.71 +	std::fill_n(m_buffer,BUFFERSIZE,0);
  199.72 +
  199.73 +	// Create the model instance to store all the data
  199.74 +	m_pModel = new ObjFile::Model();
  199.75 +	m_pModel->m_ModelName = strModelName;
  199.76 +	
  199.77 +	m_pModel->m_pDefaultMaterial = new ObjFile::Material();
  199.78 +	m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL );
  199.79 +	m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL );
  199.80 +	m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial;
  199.81 +	
  199.82 +	// Start parsing the file
  199.83 +	parseFile();
  199.84 +}
  199.85 +
  199.86 +// -------------------------------------------------------------------
  199.87 +//	Destructor
  199.88 +ObjFileParser::~ObjFileParser()
  199.89 +{
  199.90 +	/*delete m_pModel->m_pDefaultMaterial;
  199.91 +	m_pModel->m_pDefaultMaterial = NULL;*/
  199.92 +
  199.93 +	delete m_pModel;
  199.94 +	m_pModel = NULL;
  199.95 +}
  199.96 +
  199.97 +// -------------------------------------------------------------------
  199.98 +//	Returns a pointer to the model instance.
  199.99 +ObjFile::Model *ObjFileParser::GetModel() const
 199.100 +{
 199.101 +	return m_pModel;
 199.102 +}
 199.103 +
 199.104 +// -------------------------------------------------------------------
 199.105 +//	File parsing method.
 199.106 +void ObjFileParser::parseFile()
 199.107 +{
 199.108 +	if (m_DataIt == m_DataItEnd)
 199.109 +		return;
 199.110 +
 199.111 +	while (m_DataIt != m_DataItEnd)
 199.112 +	{
 199.113 +		switch (*m_DataIt)
 199.114 +		{
 199.115 +		case 'v': // Parse a vertex texture coordinate
 199.116 +			{
 199.117 +				++m_DataIt;
 199.118 +				if (*m_DataIt == ' ')
 199.119 +				{
 199.120 +					// Read in vertex definition
 199.121 +					getVector3(m_pModel->m_Vertices);
 199.122 +				}
 199.123 +				else if (*m_DataIt == 't')
 199.124 +				{
 199.125 +					// Read in texture coordinate (2D)
 199.126 +					++m_DataIt;
 199.127 +					getVector2(m_pModel->m_TextureCoord);
 199.128 +				}
 199.129 +				else if (*m_DataIt == 'n')
 199.130 +				{
 199.131 +					// Read in normal vector definition
 199.132 +					++m_DataIt;
 199.133 +					getVector3( m_pModel->m_Normals );
 199.134 +				}
 199.135 +			}
 199.136 +			break;
 199.137 +
 199.138 +		case 'p': // Parse a face, line or point statement
 199.139 +		case 'l':
 199.140 +		case 'f':
 199.141 +			{
 199.142 +				getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l' 
 199.143 +					? aiPrimitiveType_LINE : aiPrimitiveType_POINT));
 199.144 +			}
 199.145 +			break;
 199.146 +
 199.147 +		case '#': // Parse a comment
 199.148 +			{
 199.149 +				getComment();
 199.150 +			}
 199.151 +			break;
 199.152 +
 199.153 +		case 'u': // Parse a material desc. setter
 199.154 +			{
 199.155 +				getMaterialDesc();
 199.156 +			}
 199.157 +			break;
 199.158 +
 199.159 +		case 'm': // Parse a material library
 199.160 +			{
 199.161 +				getMaterialLib();
 199.162 +			}
 199.163 +			break;
 199.164 +
 199.165 +		case 'g': // Parse group name
 199.166 +			{
 199.167 +				getGroupName();
 199.168 +			}
 199.169 +			break;
 199.170 +
 199.171 +		case 's': // Parse group number
 199.172 +			{
 199.173 +				getGroupNumber();
 199.174 +			}
 199.175 +			break;
 199.176 +
 199.177 +		case 'o': // Parse object name
 199.178 +			{
 199.179 +				getObjectName();
 199.180 +			}
 199.181 +			break;
 199.182 +		
 199.183 +		default:
 199.184 +			{
 199.185 +				m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.186 +			}
 199.187 +			break;
 199.188 +		}
 199.189 +	}
 199.190 +}
 199.191 +
 199.192 +// -------------------------------------------------------------------
 199.193 +//	Copy the next word in a temporary buffer
 199.194 +void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
 199.195 +{
 199.196 +	size_t index = 0;
 199.197 +	m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
 199.198 +	while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) )
 199.199 +	{
 199.200 +		pBuffer[index] = *m_DataIt;
 199.201 +		index++;
 199.202 +		if (index == length-1)
 199.203 +			break;
 199.204 +		++m_DataIt;
 199.205 +	}
 199.206 +	pBuffer[index] = '\0';
 199.207 +}
 199.208 +
 199.209 +// -------------------------------------------------------------------
 199.210 +// Copy the next line into a temporary buffer
 199.211 +void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
 199.212 +{
 199.213 +	size_t index = 0;
 199.214 +	while (m_DataIt != m_DataItEnd)
 199.215 +	{
 199.216 +		if (*m_DataIt == '\n' || *m_DataIt == '\r' || index == length-1)
 199.217 +			break;
 199.218 +
 199.219 +		pBuffer[ index ] = *m_DataIt;
 199.220 +		++index;
 199.221 +		++m_DataIt;
 199.222 +	}
 199.223 +	pBuffer[ index ] = '\0';
 199.224 +}
 199.225 +
 199.226 +// -------------------------------------------------------------------
 199.227 +//	Get values for a new 3D vector instance
 199.228 +void ObjFileParser::getVector3(std::vector<aiVector3D> &point3d_array)
 199.229 +{
 199.230 +	float x, y, z;
 199.231 +	copyNextWord(m_buffer, BUFFERSIZE);
 199.232 +	x = (float) fast_atof(m_buffer);	
 199.233 +	
 199.234 +	copyNextWord(m_buffer, BUFFERSIZE);
 199.235 +	y = (float) fast_atof(m_buffer);
 199.236 +
 199.237 +	copyNextWord(m_buffer, BUFFERSIZE);
 199.238 +	z = (float) fast_atof(m_buffer);
 199.239 +
 199.240 +	point3d_array.push_back( aiVector3D( x, y, z ) );
 199.241 +	//skipLine();
 199.242 +	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.243 +}
 199.244 +
 199.245 +// -------------------------------------------------------------------
 199.246 +//	Get values for a new 2D vector instance
 199.247 +void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array )
 199.248 +{
 199.249 +	float x, y;
 199.250 +	copyNextWord(m_buffer, BUFFERSIZE);
 199.251 +	x = (float) fast_atof(m_buffer);	
 199.252 +	
 199.253 +	copyNextWord(m_buffer, BUFFERSIZE);
 199.254 +	y = (float) fast_atof(m_buffer);
 199.255 +
 199.256 +	point2d_array.push_back(aiVector2D(x, y));
 199.257 +
 199.258 +	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.259 +}
 199.260 +
 199.261 +// -------------------------------------------------------------------
 199.262 +//	Get values for a new face instance
 199.263 +void ObjFileParser::getFace(aiPrimitiveType type)
 199.264 +{
 199.265 +	copyNextLine(m_buffer, BUFFERSIZE);
 199.266 +	if (m_DataIt == m_DataItEnd)
 199.267 +		return;
 199.268 +
 199.269 +	char *pPtr = m_buffer;
 199.270 +	char *pEnd = &pPtr[BUFFERSIZE];
 199.271 +	pPtr = getNextToken<char*>(pPtr, pEnd);
 199.272 +	if (pPtr == pEnd || *pPtr == '\0')
 199.273 +		return;
 199.274 +
 199.275 +	std::vector<unsigned int> *pIndices = new std::vector<unsigned int>;
 199.276 +	std::vector<unsigned int> *pTexID = new std::vector<unsigned int>;
 199.277 +	std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
 199.278 +	bool hasNormal = false;
 199.279 +
 199.280 +	const bool vt = (!m_pModel->m_TextureCoord.empty());
 199.281 +	const bool vn = (!m_pModel->m_Normals.empty());
 199.282 +	int iStep = 0, iPos = 0;
 199.283 +	while (pPtr != pEnd)
 199.284 +	{
 199.285 +		iStep = 1;
 199.286 +
 199.287 +		if (IsLineEnd(*pPtr))
 199.288 +			break;
 199.289 +
 199.290 +		if (*pPtr=='/' )
 199.291 +		{
 199.292 +			if (type == aiPrimitiveType_POINT) {
 199.293 +				DefaultLogger::get()->error("Obj: Separator unexpected in point statement");
 199.294 +			}
 199.295 +			if (iPos == 0)
 199.296 +			{
 199.297 +				//if there are no texture coordinates in the file, but normals
 199.298 +				if (!vt && vn) {
 199.299 +					iPos = 1;
 199.300 +					iStep++;
 199.301 +				}
 199.302 +			}
 199.303 +			iPos++;
 199.304 +		}
 199.305 +		else if ( isSeparator(*pPtr) )
 199.306 +		{
 199.307 +			iPos = 0;
 199.308 +		}
 199.309 +		else 
 199.310 +		{
 199.311 +			//OBJ USES 1 Base ARRAYS!!!!
 199.312 +			const int iVal = atoi( pPtr );
 199.313 +			int tmp = iVal;
 199.314 +			while ( ( tmp = tmp / 10 )!=0 )
 199.315 +				++iStep;
 199.316 +
 199.317 +			if ( iVal > 0 )
 199.318 +			{
 199.319 +				// Store parsed index
 199.320 +				if ( 0 == iPos )
 199.321 +				{
 199.322 +					pIndices->push_back( iVal-1 );
 199.323 +				}
 199.324 +				else if ( 1 == iPos )
 199.325 +				{	
 199.326 +					pTexID->push_back( iVal-1 );
 199.327 +				}
 199.328 +				else if ( 2 == iPos )
 199.329 +				{
 199.330 +					pNormalID->push_back( iVal-1 );
 199.331 +					hasNormal = true;
 199.332 +				}
 199.333 +				else
 199.334 +				{
 199.335 +					reportErrorTokenInFace();
 199.336 +				}
 199.337 +			}
 199.338 +		}
 199.339 +		pPtr += iStep;
 199.340 +	}
 199.341 +
 199.342 +	if ( pIndices->empty() ) 
 199.343 +	{
 199.344 +		DefaultLogger::get()->error("Obj: Ignoring empty face");
 199.345 +		m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.346 +		return;
 199.347 +	}
 199.348 +
 199.349 +	ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID, type );
 199.350 +	
 199.351 +	// Set active material, if one set
 199.352 +	if (NULL != m_pModel->m_pCurrentMaterial) 
 199.353 +		face->m_pMaterial = m_pModel->m_pCurrentMaterial;
 199.354 +	else 
 199.355 +		face->m_pMaterial = m_pModel->m_pDefaultMaterial;
 199.356 +
 199.357 +	// Create a default object, if nothing is there
 199.358 +	if ( NULL == m_pModel->m_pCurrent )
 199.359 +		createObject( "defaultobject" );
 199.360 +	
 199.361 +	// Assign face to mesh
 199.362 +	if ( NULL == m_pModel->m_pCurrentMesh )
 199.363 +	{
 199.364 +		createMesh();
 199.365 +	}
 199.366 +	
 199.367 +	// Store the face
 199.368 +	m_pModel->m_pCurrentMesh->m_Faces.push_back( face );
 199.369 +	m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_pVertices->size();
 199.370 +	m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].size(); 
 199.371 +	if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal ) 
 199.372 +	{
 199.373 +		m_pModel->m_pCurrentMesh->m_hasNormals = true;
 199.374 +	}
 199.375 +	// Skip the rest of the line
 199.376 +	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.377 +}
 199.378 +
 199.379 +// -------------------------------------------------------------------
 199.380 +//	Get values for a new material description
 199.381 +void ObjFileParser::getMaterialDesc()
 199.382 +{
 199.383 +	// Each material request a new object.
 199.384 +	// Sometimes the object is already created (see 'o' tag by example), but it is not initialized !
 199.385 +	// So, we create a new object only if the current on is already initialized !
 199.386 +	if (m_pModel->m_pCurrent != NULL &&
 199.387 +		(	m_pModel->m_pCurrent->m_Meshes.size() > 1 ||
 199.388 +			(m_pModel->m_pCurrent->m_Meshes.size() == 1 && m_pModel->m_Meshes[m_pModel->m_pCurrent->m_Meshes[0]]->m_Faces.size() != 0)	)
 199.389 +		)
 199.390 +		m_pModel->m_pCurrent = NULL;
 199.391 +
 199.392 +	// Get next data for material data
 199.393 +	m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
 199.394 +	if (m_DataIt == m_DataItEnd)
 199.395 +		return;
 199.396 +
 199.397 +	char *pStart = &(*m_DataIt);
 199.398 +	while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) )
 199.399 +		++m_DataIt;
 199.400 +
 199.401 +	// Get name
 199.402 +	std::string strName(pStart, &(*m_DataIt));
 199.403 +	if ( strName.empty())
 199.404 +		return;
 199.405 +
 199.406 +	// Search for material
 199.407 +	std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strName );
 199.408 +	if ( it == m_pModel->m_MaterialMap.end() )
 199.409 +	{
 199.410 +		// Not found, use default material
 199.411 +		m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
 199.412 +		DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping");
 199.413 +	}
 199.414 +	else
 199.415 +	{
 199.416 +		// Found, using detected material
 199.417 +		m_pModel->m_pCurrentMaterial = (*it).second;
 199.418 +		if ( needsNewMesh( strName ))
 199.419 +		{
 199.420 +			createMesh();	
 199.421 +		}
 199.422 +		m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName );
 199.423 +	}
 199.424 +
 199.425 +	// Skip rest of line
 199.426 +	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.427 +}
 199.428 +
 199.429 +// -------------------------------------------------------------------
 199.430 +//	Get a comment, values will be skipped
 199.431 +void ObjFileParser::getComment()
 199.432 +{
 199.433 +	while (m_DataIt != m_DataItEnd)
 199.434 +	{
 199.435 +		if ( '\n' == (*m_DataIt))
 199.436 +		{
 199.437 +			++m_DataIt;
 199.438 +			break;
 199.439 +		}
 199.440 +		else
 199.441 +		{
 199.442 +			++m_DataIt;
 199.443 +		}
 199.444 +	}
 199.445 +}
 199.446 +
 199.447 +// -------------------------------------------------------------------
 199.448 +//	Get material library from file.
 199.449 +void ObjFileParser::getMaterialLib()
 199.450 +{
 199.451 +	// Translate tuple
 199.452 +	m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
 199.453 +	if (m_DataIt ==  m_DataItEnd)
 199.454 +		return;
 199.455 +	
 199.456 +	char *pStart = &(*m_DataIt);
 199.457 +	while (m_DataIt != m_DataItEnd && !isNewLine(*m_DataIt))
 199.458 +		m_DataIt++;
 199.459 +
 199.460 +	// Check for existence
 199.461 +	const std::string strMatName(pStart, &(*m_DataIt));
 199.462 +	IOStream *pFile = m_pIO->Open(strMatName);
 199.463 +
 199.464 +	if (!pFile )
 199.465 +	{
 199.466 +		DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName);
 199.467 +		m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.468 +		return;
 199.469 +	}
 199.470 +
 199.471 +	// Import material library data from file
 199.472 +	std::vector<char> buffer;
 199.473 +	BaseImporter::TextFileToBuffer(pFile,buffer);
 199.474 +	m_pIO->Close( pFile );
 199.475 +
 199.476 +	// Importing the material library 
 199.477 +	ObjFileMtlImporter mtlImporter( buffer, strMatName, m_pModel );			
 199.478 +}
 199.479 +
 199.480 +// -------------------------------------------------------------------
 199.481 +//	Set a new material definition as the current material.
 199.482 +void ObjFileParser::getNewMaterial()
 199.483 +{
 199.484 +	m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
 199.485 +	m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
 199.486 +	if ( m_DataIt == m_DataItEnd )
 199.487 +		return;
 199.488 +
 199.489 +	char *pStart = &(*m_DataIt);
 199.490 +	std::string strMat( pStart, *m_DataIt );
 199.491 +	while ( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) )
 199.492 +		m_DataIt++;
 199.493 +	std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
 199.494 +	if ( it == m_pModel->m_MaterialMap.end() )
 199.495 +	{
 199.496 +		// Show a warning, if material was not found
 199.497 +		DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat);
 199.498 +		m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
 199.499 +	}
 199.500 +	else
 199.501 +	{
 199.502 +		// Set new material
 199.503 +		if ( needsNewMesh( strMat ) )
 199.504 +		{
 199.505 +			createMesh();	
 199.506 +		}
 199.507 +		m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat );
 199.508 +	}
 199.509 +
 199.510 +	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.511 +}
 199.512 +
 199.513 +// -------------------------------------------------------------------
 199.514 +int ObjFileParser::getMaterialIndex( const std::string &strMaterialName )
 199.515 +{
 199.516 +	int mat_index = -1;
 199.517 +	if ( strMaterialName.empty() )
 199.518 +		return mat_index;
 199.519 +	for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index)
 199.520 +	{
 199.521 +		if ( strMaterialName == m_pModel->m_MaterialLib[ index ])
 199.522 +		{
 199.523 +			mat_index = (int)index;
 199.524 +			break;
 199.525 +		}
 199.526 +	}
 199.527 +	return mat_index;
 199.528 +}
 199.529 +
 199.530 +// -------------------------------------------------------------------
 199.531 +//	Getter for a group name.  
 199.532 +void ObjFileParser::getGroupName()
 199.533 +{
 199.534 +	std::string strGroupName;
 199.535 +   
 199.536 +	m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName);
 199.537 +	if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) )
 199.538 +		return;
 199.539 +
 199.540 +	// Change active group, if necessary
 199.541 +	if ( m_pModel->m_strActiveGroup != strGroupName )
 199.542 +	{
 199.543 +		// Search for already existing entry
 199.544 +		ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(strGroupName);
 199.545 +		
 199.546 +		// We are mapping groups into the object structure
 199.547 +		createObject( strGroupName );
 199.548 +		
 199.549 +		// New group name, creating a new entry
 199.550 +		if (it == m_pModel->m_Groups.end())
 199.551 +		{
 199.552 +			std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
 199.553 +			m_pModel->m_Groups[ strGroupName ] = pFaceIDArray;
 199.554 +			m_pModel->m_pGroupFaceIDs = (pFaceIDArray);
 199.555 +		}
 199.556 +		else
 199.557 +		{
 199.558 +			m_pModel->m_pGroupFaceIDs = (*it).second;
 199.559 +		}
 199.560 +		m_pModel->m_strActiveGroup = strGroupName;
 199.561 +	}
 199.562 +	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.563 +}
 199.564 +
 199.565 +// -------------------------------------------------------------------
 199.566 +//	Not supported
 199.567 +void ObjFileParser::getGroupNumber()
 199.568 +{
 199.569 +	// Not used
 199.570 +
 199.571 +	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.572 +}
 199.573 +
 199.574 +// -------------------------------------------------------------------
 199.575 +//	Stores values for a new object instance, name will be used to 
 199.576 +//	identify it.
 199.577 +void ObjFileParser::getObjectName()
 199.578 +{
 199.579 +	m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
 199.580 +	if (m_DataIt == m_DataItEnd)
 199.581 +		return;
 199.582 +	char *pStart = &(*m_DataIt);
 199.583 +	while ( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) )
 199.584 +		++m_DataIt;
 199.585 +
 199.586 +	std::string strObjectName(pStart, &(*m_DataIt));
 199.587 +	if (!strObjectName.empty()) 
 199.588 +	{
 199.589 +		// Reset current object
 199.590 +		m_pModel->m_pCurrent = NULL;
 199.591 +		
 199.592 +		// Search for actual object
 199.593 +		for (std::vector<ObjFile::Object*>::const_iterator it = m_pModel->m_Objects.begin();
 199.594 +			it != m_pModel->m_Objects.end();
 199.595 +			++it)
 199.596 +		{
 199.597 +			if ((*it)->m_strObjName == strObjectName)
 199.598 +			{
 199.599 +				m_pModel->m_pCurrent = *it;
 199.600 +				break;
 199.601 +			}
 199.602 +		}
 199.603 +
 199.604 +		// Allocate a new object, if current one was not found before
 199.605 +		if ( NULL == m_pModel->m_pCurrent )
 199.606 +			createObject(strObjectName);
 199.607 +	}
 199.608 +	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.609 +}
 199.610 +// -------------------------------------------------------------------
 199.611 +//	Creates a new object instance
 199.612 +void ObjFileParser::createObject(const std::string &strObjectName)
 199.613 +{
 199.614 +	ai_assert( NULL != m_pModel );
 199.615 +	//ai_assert( !strObjectName.empty() );
 199.616 +
 199.617 +	m_pModel->m_pCurrent = new ObjFile::Object;
 199.618 +	m_pModel->m_pCurrent->m_strObjName = strObjectName;
 199.619 +	m_pModel->m_Objects.push_back( m_pModel->m_pCurrent );
 199.620 +	
 199.621 +
 199.622 +	createMesh();
 199.623 +
 199.624 +	if( m_pModel->m_pCurrentMaterial )
 199.625 +	{
 199.626 +		m_pModel->m_pCurrentMesh->m_uiMaterialIndex = 
 199.627 +			getMaterialIndex( m_pModel->m_pCurrentMaterial->MaterialName.data );
 199.628 +		m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial;
 199.629 +	}		
 199.630 +}
 199.631 +// -------------------------------------------------------------------
 199.632 +//	Creates a new mesh
 199.633 +void ObjFileParser::createMesh()
 199.634 +{
 199.635 +	ai_assert( NULL != m_pModel );
 199.636 +	m_pModel->m_pCurrentMesh = new ObjFile::Mesh;
 199.637 +	m_pModel->m_Meshes.push_back( m_pModel->m_pCurrentMesh );
 199.638 +	unsigned int meshId = m_pModel->m_Meshes.size()-1;
 199.639 +	if ( NULL != m_pModel->m_pCurrent )
 199.640 +	{
 199.641 +		m_pModel->m_pCurrent->m_Meshes.push_back( meshId );
 199.642 +	}
 199.643 +	else
 199.644 +	{
 199.645 +		DefaultLogger::get()->error("OBJ: No object detected to attach a new mesh instance.");
 199.646 +	}
 199.647 +}
 199.648 +
 199.649 +// -------------------------------------------------------------------
 199.650 +//	Returns true, if a new mesh must be created.
 199.651 +bool ObjFileParser::needsNewMesh( const std::string &rMaterialName )
 199.652 +{
 199.653 +	if(m_pModel->m_pCurrentMesh == 0)
 199.654 +	{
 199.655 +		// No mesh data yet
 199.656 +		return true;
 199.657 +	}
 199.658 +	bool newMat = false;
 199.659 +	int matIdx = getMaterialIndex( rMaterialName );
 199.660 +	int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
 199.661 +	if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) || curMatIdx != matIdx )
 199.662 +	{
 199.663 +		// New material -> only one material per mesh, so we need to create a new 
 199.664 +		// material
 199.665 +		newMat = true;
 199.666 +	}
 199.667 +	return newMat;
 199.668 +}
 199.669 +
 199.670 +// -------------------------------------------------------------------
 199.671 +//	Shows an error in parsing process.
 199.672 +void ObjFileParser::reportErrorTokenInFace()
 199.673 +{		
 199.674 +	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 199.675 +	DefaultLogger::get()->error("OBJ: Not supported token in face description detected");
 199.676 +}
 199.677 +
 199.678 +// -------------------------------------------------------------------
 199.679 +
 199.680 +}	// Namespace Assimp
 199.681 +
 199.682 +#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER
   200.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   200.2 +++ b/libs/assimp/ObjFileParser.h	Sat Feb 01 19:58:19 2014 +0200
   200.3 @@ -0,0 +1,137 @@
   200.4 +/*
   200.5 +Open Asset Import Library (assimp)
   200.6 +----------------------------------------------------------------------
   200.7 +
   200.8 +Copyright (c) 2006-2012, assimp team
   200.9 +All rights reserved.
  200.10 +
  200.11 +Redistribution and use of this software in source and binary forms, 
  200.12 +with or without modification, are permitted provided that the 
  200.13 +following conditions are met:
  200.14 +
  200.15 +* Redistributions of source code must retain the above
  200.16 +  copyright notice, this list of conditions and the
  200.17 +  following disclaimer.
  200.18 +
  200.19 +* Redistributions in binary form must reproduce the above
  200.20 +  copyright notice, this list of conditions and the
  200.21 +  following disclaimer in the documentation and/or other
  200.22 +  materials provided with the distribution.
  200.23 +
  200.24 +* Neither the name of the assimp team, nor the names of its
  200.25 +  contributors may be used to endorse or promote products
  200.26 +  derived from this software without specific prior
  200.27 +  written permission of the assimp team.
  200.28 +
  200.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  200.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  200.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  200.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  200.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  200.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  200.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  200.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  200.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  200.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  200.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  200.40 +
  200.41 +----------------------------------------------------------------------
  200.42 +*/
  200.43 +
  200.44 +
  200.45 +#ifndef OBJ_FILEPARSER_H_INC
  200.46 +#define OBJ_FILEPARSER_H_INC
  200.47 +
  200.48 +#include <vector>
  200.49 +#include <string>
  200.50 +#include <map>
  200.51 +
  200.52 +namespace Assimp
  200.53 +{
  200.54 +
  200.55 +namespace ObjFile
  200.56 +{
  200.57 +struct Model;
  200.58 +struct Object;
  200.59 +struct Material;
  200.60 +struct Point3;
  200.61 +struct Point2;
  200.62 +}
  200.63 +class ObjFileImporter;
  200.64 +class IOSystem;
  200.65 +
  200.66 +///	\class	ObjFileParser
  200.67 +///	\brief	Parser for a obj waveform file
  200.68 +class ObjFileParser
  200.69 +{
  200.70 +public:
  200.71 +	static const size_t BUFFERSIZE = 4096;
  200.72 +	typedef std::vector<char> DataArray;
  200.73 +	typedef std::vector<char>::iterator DataArrayIt;
  200.74 +	typedef std::vector<char>::const_iterator ConstDataArrayIt;
  200.75 +
  200.76 +public:
  200.77 +	///	\brief	Constructor with data array.
  200.78 +	ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem* io);
  200.79 +	///	\brief	Destructor
  200.80 +	~ObjFileParser();
  200.81 +	///	\brief	Model getter.
  200.82 +	ObjFile::Model *GetModel() const;
  200.83 +
  200.84 +private:
  200.85 +	///	Parse the loadedfile
  200.86 +	void parseFile();
  200.87 +	///	Method to copy the new delimited word in the current line.
  200.88 +	void copyNextWord(char *pBuffer, size_t length);
  200.89 +	///	Method to copy the new line.
  200.90 +	void copyNextLine(char *pBuffer, size_t length);
  200.91 +	///	Stores the following 3d vector.
  200.92 +	void getVector3( std::vector<aiVector3D> &point3d_array );
  200.93 +	///	Stores the following 3d vector.
  200.94 +	void getVector2(std::vector<aiVector2D> &point2d_array);
  200.95 +	///	Stores the following face.
  200.96 +	void getFace(aiPrimitiveType type);
  200.97 +	void getMaterialDesc();
  200.98 +	///	Gets a comment.
  200.99 +	void getComment();
 200.100 +	/// Gets a a material library.
 200.101 +	void getMaterialLib();
 200.102 +	/// Creates a new material.
 200.103 +	void getNewMaterial();
 200.104 +	/// Gets the groupname from file.
 200.105 +	void getGroupName();
 200.106 +	/// Gets the group number from file.
 200.107 +	void getGroupNumber();
 200.108 +	/// Returns the index of the material. Is -1 if not material was found.
 200.109 +	int getMaterialIndex( const std::string &strMaterialName );
 200.110 +	/// Parse object name
 200.111 +	void getObjectName();
 200.112 +	/// Creates a new object.
 200.113 +	void createObject(const std::string &strObjectName);
 200.114 +	///	Creates a new mesh.
 200.115 +	void createMesh(); 
 200.116 +	///	Returns true, if a new mesh instance must be created.
 200.117 +	bool needsNewMesh( const std::string &rMaterialName );
 200.118 +	///	Error report in token
 200.119 +	void reportErrorTokenInFace();
 200.120 +
 200.121 +private:
 200.122 +	///	Default material name
 200.123 +	static const std::string DEFAULT_MATERIAL;
 200.124 +	//!	Iterator to current position in buffer
 200.125 +	DataArrayIt m_DataIt;
 200.126 +	//!	Iterator to end position of buffer
 200.127 +	DataArrayIt m_DataItEnd;
 200.128 +	//!	Pointer to model instance
 200.129 +	ObjFile::Model *m_pModel;
 200.130 +	//!	Current line (for debugging)
 200.131 +	unsigned int m_uiLine;
 200.132 +	//!	Helper buffer
 200.133 +	char m_buffer[BUFFERSIZE];
 200.134 +	///	Pointer to IO system instance.
 200.135 +	IOSystem *m_pIO;
 200.136 +};
 200.137 +
 200.138 +}	// Namespace Assimp
 200.139 +
 200.140 +#endif
   201.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   201.2 +++ b/libs/assimp/ObjTools.h	Sat Feb 01 19:58:19 2014 +0200
   201.3 @@ -0,0 +1,263 @@
   201.4 +/*
   201.5 +Open Asset Import Library (assimp)
   201.6 +----------------------------------------------------------------------
   201.7 +
   201.8 +Copyright (c) 2006-2012, assimp team
   201.9 +All rights reserved.
  201.10 +
  201.11 +Redistribution and use of this software in source and binary forms, 
  201.12 +with or without modification, are permitted provided that the 
  201.13 +following conditions are met:
  201.14 +
  201.15 +* Redistributions of source code must retain the above
  201.16 +  copyright notice, this list of conditions and the
  201.17 +  following disclaimer.
  201.18 +
  201.19 +* Redistributions in binary form must reproduce the above
  201.20 +  copyright notice, this list of conditions and the
  201.21 +  following disclaimer in the documentation and/or other
  201.22 +  materials provided with the distribution.
  201.23 +
  201.24 +* Neither the name of the assimp team, nor the names of its
  201.25 +  contributors may be used to endorse or promote products
  201.26 +  derived from this software without specific prior
  201.27 +  written permission of the assimp team.
  201.28 +
  201.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  201.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  201.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  201.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  201.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  201.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  201.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  201.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  201.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  201.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  201.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  201.40 +
  201.41 +----------------------------------------------------------------------
  201.42 +*/
  201.43 +
  201.44 +/**	@file	ObjTools.h
  201.45 + *	@brief	Some helpful templates for text parsing
  201.46 + */
  201.47 +#ifndef OBJ_TOOLS_H_INC
  201.48 +#define OBJ_TOOLS_H_INC
  201.49 +
  201.50 +#include "fast_atof.h"
  201.51 +
  201.52 +namespace Assimp
  201.53 +{
  201.54 +
  201.55 +/**	@brief	Returns true, if the last entry of the buffer is reached.
  201.56 + *	@param	it	Iterator of current position.
  201.57 + *	@param	end	Iterator with end of buffer.
  201.58 + *	@return	true, if the end of the buffer is reached.
  201.59 + */
  201.60 +template<class char_t>
  201.61 +inline bool isEndOfBuffer(  char_t it, char_t end )
  201.62 +{
  201.63 +	if ( it == end )
  201.64 +	{
  201.65 +		return true;
  201.66 +	}
  201.67 +	else
  201.68 +	{
  201.69 +		end--;
  201.70 +	}
  201.71 +	return ( it == end );	
  201.72 +}
  201.73 +
  201.74 +/** @brief	Returns true, if token is a space on any supported platform
  201.75 +*	@param	token	Token to search in
  201.76 +*	@return	true, if token is a space			
  201.77 +*/
  201.78 +inline bool isSeparator( char token )
  201.79 +{
  201.80 +	return ( token == ' ' || 
  201.81 +			token == '\n' || 
  201.82 +			token == '\f' || 
  201.83 +			token == '\r' ||
  201.84 +			token == '\t' );
  201.85 +}
  201.86 +
  201.87 +/**	@brief	Returns true, fi token id a new line marking token.
  201.88 + *	@param	token	Token to search in
  201.89 + *	@return	true, if token is a newline token.
  201.90 + */
  201.91 +inline bool isNewLine( char token )
  201.92 +{
  201.93 +	return ( token == '\n' || token == '\f' || token == '\r' );
  201.94 +}
  201.95 +
  201.96 +/**	@brief	Returns next word separated by a space
  201.97 + *	@param	pBuffer	Pointer to data buffer
  201.98 + *	@param	pEnd	Pointer to end of buffer
  201.99 + *	@return	Pointer to next space
 201.100 + */
 201.101 +template<class Char_T>
 201.102 +inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
 201.103 +{
 201.104 +	while ( !isEndOfBuffer( pBuffer, pEnd ) )
 201.105 +	{
 201.106 +		if ( !isSeparator( *pBuffer ) || isNewLine( *pBuffer ) )
 201.107 +			break;
 201.108 +		pBuffer++;
 201.109 +	}
 201.110 +	return pBuffer;
 201.111 +}
 201.112 +
 201.113 +/**	@brief	Returns ponter a next token
 201.114 + *	@param	pBuffer	Pointer to data buffer
 201.115 + *	@param	pEnd	Pointer to end of buffer
 201.116 + *	@return	Pointer to next token
 201.117 + */
 201.118 +template<class Char_T>
 201.119 +inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
 201.120 +{
 201.121 +	while ( !isEndOfBuffer( pBuffer, pEnd ) )
 201.122 +	{
 201.123 +		if ( isSeparator( *pBuffer ) )
 201.124 +			break;
 201.125 +		pBuffer++;
 201.126 +	}
 201.127 +	return getNextWord( pBuffer, pEnd );
 201.128 +}
 201.129 +
 201.130 +/**	@brief	Skips a line
 201.131 + *	@param	it		Iterator set to current position
 201.132 + *	@param	end		Iterator set to end of scratch buffer for readout
 201.133 + *	@param	uiLine	Current linenumber in format
 201.134 + *	@return	Current-iterator with new position
 201.135 + */
 201.136 +template<class char_t>
 201.137 +inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine )
 201.138 +{
 201.139 +	while ( !isEndOfBuffer( it, end ) && !isNewLine( *it ) )
 201.140 +		++it;
 201.141 +	if ( it != end )
 201.142 +	{
 201.143 +		++it;
 201.144 +		++uiLine;
 201.145 +	}
 201.146 +	// fix .. from time to time there are spaces at the beginning of a material line
 201.147 +	while ( it != end && (*it == '\t' || *it == ' ') )
 201.148 +		++it;
 201.149 +	return it;
 201.150 +}
 201.151 +
 201.152 +/**	@brief	Get a name from the current line. Preserve space in the middle,
 201.153 + *    but trim it at the end.
 201.154 + *	@param	it		set to current position
 201.155 + *	@param	end		set to end of scratch buffer for readout
 201.156 + *	@param	name	Separated name
 201.157 + *	@return	Current-iterator with new position
 201.158 + */
 201.159 +template<class char_t>
 201.160 +inline char_t getName( char_t it, char_t end, std::string &name )
 201.161 +{
 201.162 +	name = "";
 201.163 +	it = getNextToken<char_t>( it, end );
 201.164 +	if ( isEndOfBuffer( it, end ) )
 201.165 +		return end;
 201.166 +	
 201.167 +	char *pStart = &( *it );
 201.168 +	while ( !isEndOfBuffer( it, end ) && !isNewLine( *it ) ) {
 201.169 +		++it;
 201.170 +	}
 201.171 +
 201.172 +	while(isEndOfBuffer( it, end ) || isNewLine( *it ) || isSeparator(*it)) {
 201.173 +		--it;
 201.174 +	}
 201.175 +	++it;
 201.176 +
 201.177 +	// Get name
 201.178 +	// if there is no name, and the previous char is a separator, come back to start
 201.179 +	while (&(*it) < pStart) {
 201.180 +		++it;
 201.181 +	}
 201.182 +	std::string strName( pStart, &(*it) );
 201.183 +	if ( strName.empty() )
 201.184 +		return it;
 201.185 +	else
 201.186 +		name = strName;
 201.187 +	
 201.188 +	return it;
 201.189 +}
 201.190 +
 201.191 +/**	@brief	Get next word from given line
 201.192 + *	@param	it		set to current position
 201.193 + *	@param	end		set to end of scratch buffer for readout
 201.194 + *	@param	pBuffer	Buffer for next word
 201.195 + *	@param	length	Buffer length
 201.196 + *	@return	Current-iterator with new position
 201.197 + */
 201.198 +template<class char_t>
 201.199 +inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length )
 201.200 +{
 201.201 +	size_t index = 0;
 201.202 +	it = getNextWord<char_t>( it, end );
 201.203 +	while ( !isSeparator( *it ) && !isEndOfBuffer( it, end ) )
 201.204 +	{
 201.205 +		pBuffer[index] = *it ;
 201.206 +		index++;
 201.207 +		if (index == length-1)
 201.208 +			break;
 201.209 +		++it;
 201.210 +	}
 201.211 +	pBuffer[ index ] = '\0';
 201.212 +	return it;
 201.213 +}
 201.214 +
 201.215 +/**	@brief	Get next float from given line
 201.216 + *	@param	it		set to current position
 201.217 + *	@param	end		set to end of scratch buffer for readout
 201.218 + *	@param	value	Separated float value.
 201.219 + *	@return	Current-iterator with new position
 201.220 + */
 201.221 +template<class char_t>
 201.222 +inline char_t getFloat( char_t it, char_t end, float &value )
 201.223 +{
 201.224 +	static const size_t BUFFERSIZE = 1024;
 201.225 +	char buffer[ BUFFERSIZE ];
 201.226 +	it = CopyNextWord<char_t>( it, end, buffer, BUFFERSIZE );
 201.227 +	value = (float) fast_atof( buffer );
 201.228 +
 201.229 +	return it;
 201.230 +}
 201.231 +
 201.232 +/**	@brief	Will perform a simple tokenize.
 201.233 + *	@param	str			String to tokenize.
 201.234 + *	@param	tokens		Array with tokens, will be empty if no token was found.
 201.235 + *	@param	delimiters	Delimiter for tokenize.
 201.236 + *	@return	Number of found token.
 201.237 + */
 201.238 +template<class string_type>
 201.239 +unsigned int tokenize( const string_type& str, std::vector<string_type>& tokens, 
 201.240 +						 const string_type& delimiters ) 
 201.241 +{
 201.242 +	// Skip delimiters at beginning.
 201.243 +	typename string_type::size_type lastPos = str.find_first_not_of( delimiters, 0 );
 201.244 +
 201.245 +	// Find first "non-delimiter".
 201.246 +	typename string_type::size_type pos = str.find_first_of( delimiters, lastPos );
 201.247 +	while ( string_type::npos != pos || string_type::npos != lastPos )
 201.248 +	{
 201.249 +		// Found a token, add it to the vector.
 201.250 +		string_type tmp = str.substr(lastPos, pos - lastPos);
 201.251 +		if ( !tmp.empty() && ' ' != tmp[ 0 ] )
 201.252 +			tokens.push_back( tmp );
 201.253 +
 201.254 +		// Skip delimiters.  Note the "not_of"
 201.255 +		lastPos = str.find_first_not_of( delimiters, pos );
 201.256 +
 201.257 +		// Find next "non-delimiter"
 201.258 +		pos = str.find_first_of( delimiters, lastPos );
 201.259 +	}
 201.260 +
 201.261 +	return static_cast<unsigned int>( tokens.size() );
 201.262 +}
 201.263 +
 201.264 +} // Namespace Assimp
 201.265 +
 201.266 +#endif
   202.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   202.2 +++ b/libs/assimp/OgreImporter.cpp	Sat Feb 01 19:58:19 2014 +0200
   202.3 @@ -0,0 +1,263 @@
   202.4 +/*
   202.5 +Open Asset Import Library (assimp)
   202.6 +----------------------------------------------------------------------
   202.7 +
   202.8 +Copyright (c) 2006-2012, assimp team
   202.9 +All rights reserved.
  202.10 +
  202.11 +Redistribution and use of this software in source and binary forms, 
  202.12 +with or without modification, are permitted provided that the 
  202.13 +following conditions are met:
  202.14 +
  202.15 +* Redistributions of source code must retain the above
  202.16 +  copyright notice, this list of conditions and the
  202.17 +  following disclaimer.
  202.18 +
  202.19 +* Redistributions in binary form must reproduce the above
  202.20 +  copyright notice, this list of conditions and the
  202.21 +  following disclaimer in the documentation and/or other
  202.22 +  materials provided with the distribution.
  202.23 +
  202.24 +* Neither the name of the assimp team, nor the names of its
  202.25 +  contributors may be used to endorse or promote products
  202.26 +  derived from this software without specific prior
  202.27 +  written permission of the assimp team.
  202.28 +
  202.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  202.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  202.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  202.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  202.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  202.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  202.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  202.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  202.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  202.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  202.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  202.40 +
  202.41 +----------------------------------------------------------------------
  202.42 +*/
  202.43 +
  202.44 +/** @file  OgreImporter.cpp
  202.45 + *  @brief Implementation of the Ogre XML (.mesh.xml) loader.
  202.46 + */
  202.47 +#include "AssimpPCH.h"
  202.48 +#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
  202.49 +
  202.50 +#include <vector>
  202.51 +#include <sstream>
  202.52 +using namespace std;
  202.53 +
  202.54 +#include "OgreImporter.hpp"
  202.55 +#include "TinyFormatter.h"
  202.56 +#include "irrXMLWrapper.h"
  202.57 +
  202.58 +static const aiImporterDesc desc = {
  202.59 +	"Ogre XML Mesh Importer",
  202.60 +	"",
  202.61 +	"",
  202.62 +	"",
  202.63 +	aiImporterFlags_SupportTextFlavour,
  202.64 +	0,
  202.65 +	0,
  202.66 +	0,
  202.67 +	0,
  202.68 +	"mesh.xml"
  202.69 +};
  202.70 +
  202.71 +namespace Assimp
  202.72 +{
  202.73 +namespace Ogre
  202.74 +{
  202.75 +
  202.76 +
  202.77 +bool OgreImporter::CanRead(const std::string &pFile, Assimp::IOSystem *pIOHandler, bool checkSig) const
  202.78 +{
  202.79 +	if(!checkSig)//Check File Extension
  202.80 +	{
  202.81 +		std::string extension("mesh.xml");
  202.82 +		int l=extension.length();
  202.83 +		return pFile.substr(pFile.length()-l, l)==extension;
  202.84 +	}
  202.85 +	else//Check file Header
  202.86 +	{
  202.87 +		const char* tokens[] = {"<mesh>"};
  202.88 +		return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
  202.89 +	}
  202.90 +}
  202.91 +
  202.92 +
  202.93 +void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Assimp::IOSystem *pIOHandler)
  202.94 +{
  202.95 +	m_CurrentFilename=pFile;
  202.96 +	m_CurrentIOHandler=pIOHandler;
  202.97 +	m_CurrentScene=pScene;
  202.98 +
  202.99 +	//Open the File:
 202.100 +	boost::scoped_ptr<IOStream> file(pIOHandler->Open(pFile));
 202.101 +	if( file.get() == NULL)
 202.102 +		throw DeadlyImportError("Failed to open file "+pFile+".");
 202.103 +
 202.104 +	//Read the Mesh File:
 202.105 +	boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
 202.106 +	boost::scoped_ptr<XmlReader> MeshFile(irr::io::createIrrXMLReader(mIOWrapper.get()));
 202.107 +	if(!MeshFile)//parse the xml file
 202.108 +		throw DeadlyImportError("Failed to create XML Reader for "+pFile);
 202.109 +
 202.110 +
 202.111 +	DefaultLogger::get()->debug("Mesh File opened");
 202.112 +	
 202.113 +	//Read root Node:
 202.114 +	if(!(XmlRead(MeshFile.get()) && string(MeshFile->getNodeName())=="mesh"))
 202.115 +	{
 202.116 +		throw DeadlyImportError("Root Node is not <mesh>! "+pFile+"  "+MeshFile->getNodeName());
 202.117 +	}
 202.118 +
 202.119 +	//eventually load shared geometry
 202.120 +	XmlRead(MeshFile.get());//shared geometry is optional, so we need a reed for the next two if's
 202.121 +	if(MeshFile->getNodeName()==string("sharedgeometry"))
 202.122 +	{
 202.123 +		unsigned int NumVertices=GetAttribute<int>(MeshFile.get(), "vertexcount");;
 202.124 +
 202.125 +		XmlRead(MeshFile.get());
 202.126 +		while(MeshFile->getNodeName()==string("vertexbuffer"))
 202.127 +		{
 202.128 +			ReadVertexBuffer(m_SharedGeometry, MeshFile.get(), NumVertices);
 202.129 +		}
 202.130 +	}
 202.131 +
 202.132 +	//Go to the submeshs:
 202.133 +	if(MeshFile->getNodeName()!=string("submeshes"))
 202.134 +	{
 202.135 +		throw DeadlyImportError("No <submeshes> node in <mesh> node! "+pFile);
 202.136 +	}
 202.137 +
 202.138 +
 202.139 +	//-------------------Read the submeshs and materials:-----------------------
 202.140 +	std::list<boost::shared_ptr<SubMesh> > SubMeshes;
 202.141 +	vector<aiMaterial*> Materials;
 202.142 +	XmlRead(MeshFile.get());
 202.143 +	while(MeshFile->getNodeName()==string("submesh"))
 202.144 +	{
 202.145 +		SubMesh* theSubMesh=new SubMesh();
 202.146 +		theSubMesh->MaterialName=GetAttribute<string>(MeshFile.get(), "material");
 202.147 +		DefaultLogger::get()->debug("Loading Submehs with Material: "+theSubMesh->MaterialName);
 202.148 +		ReadSubMesh(*theSubMesh, MeshFile.get());
 202.149 +
 202.150 +		//just a index in a array, we add a mesh in each loop cycle, so we get indicies like 0, 1, 2 ... n;
 202.151 +		//so it is important to do this before pushing the mesh in the vector!
 202.152 +		theSubMesh->MaterialIndex=SubMeshes.size();
 202.153 +
 202.154 +		SubMeshes.push_back(boost::shared_ptr<SubMesh>(theSubMesh));
 202.155 +
 202.156 +		//Load the Material:
 202.157 +		aiMaterial* MeshMat=LoadMaterial(theSubMesh->MaterialName);
 202.158 +		
 202.159 +		//Set the Material:
 202.160 +		Materials.push_back(MeshMat);
 202.161 +	}
 202.162 +
 202.163 +	if(SubMeshes.empty())
 202.164 +		throw DeadlyImportError("no submesh loaded!");
 202.165 +	if(SubMeshes.size()!=Materials.size())
 202.166 +		throw DeadlyImportError("materialcount doesn't match mesh count!");
 202.167 +
 202.168 +	//____________________________________________________________
 202.169 +
 202.170 +
 202.171 +	//skip submeshnames (stupid irrxml)
 202.172 +	if(MeshFile->getNodeName()==string("submeshnames"))
 202.173 +	{
 202.174 +		XmlRead(MeshFile.get());
 202.175 +		while(MeshFile->getNodeName()==string("submesh"))
 202.176 +			XmlRead(MeshFile.get());
 202.177 +	}
 202.178 +
 202.179 +
 202.180 +	//----------------Load the skeleton: -------------------------------
 202.181 +	vector<Bone> Bones;
 202.182 +	vector<Animation> Animations;
 202.183 +	if(MeshFile->getNodeName()==string("skeletonlink"))
 202.184 +	{
 202.185 +		string SkeletonFile=GetAttribute<string>(MeshFile.get(), "name");
 202.186 +		LoadSkeleton(SkeletonFile, Bones, Animations);
 202.187 +		XmlRead(MeshFile.get());
 202.188 +	}
 202.189 +	else
 202.190 +	{
 202.191 +		DefaultLogger::get()->debug("No skeleton file will be loaded");
 202.192 +		DefaultLogger::get()->debug(MeshFile->getNodeName());
 202.193 +	}
 202.194 +	//__________________________________________________________________
 202.195 +
 202.196 +
 202.197 +	//now there might be boneassignments for the shared geometry:
 202.198 +	if(MeshFile->getNodeName()==string("boneassignments"))
 202.199 +	{
 202.200 +		ReadBoneWeights(m_SharedGeometry, MeshFile.get());
 202.201 +	}
 202.202 +
 202.203 +
 202.204 +	//----------------- Process Meshs -----------------------
 202.205 +	BOOST_FOREACH(boost::shared_ptr<SubMesh> theSubMesh, SubMeshes)
 202.206 +	{
 202.207 +		ProcessSubMesh(*theSubMesh, m_SharedGeometry);
 202.208 +	}
 202.209 +	//_______________________________________________________
 202.210 +
 202.211 +
 202.212 +
 202.213 +	
 202.214 +	//----------------- Now fill the Assimp scene ---------------------------
 202.215 +	
 202.216 +	//put the aiMaterials in the scene:
 202.217 +	m_CurrentScene->mMaterials=new aiMaterial*[Materials.size()];
 202.218 +	m_CurrentScene->mNumMaterials=Materials.size();
 202.219 +	for(unsigned int i=0; i<Materials.size(); ++i)
 202.220 +		m_CurrentScene->mMaterials[i]=Materials[i];
 202.221 +
 202.222 +	//create the aiMehs... 
 202.223 +	vector<aiMesh*> aiMeshes;
 202.224 +	BOOST_FOREACH(boost::shared_ptr<SubMesh> theSubMesh, SubMeshes)
 202.225 +	{
 202.226 +		aiMeshes.push_back(CreateAssimpSubMesh(*theSubMesh, Bones));
 202.227 +	}
 202.228 +	//... and put them in the scene:
 202.229 +	m_CurrentScene->mNumMeshes=aiMeshes.size();
 202.230 +	m_CurrentScene->mMeshes=new aiMesh*[aiMeshes.size()];
 202.231 +	memcpy(m_CurrentScene->mMeshes, &(aiMeshes[0]), sizeof(aiMeshes[0])*aiMeshes.size());
 202.232 +
 202.233 +	//Create the root node
 202.234 +	m_CurrentScene->mRootNode=new aiNode("root");
 202.235 +
 202.236 +	//link the meshs with the root node:
 202.237 +	m_CurrentScene->mRootNode->mMeshes=new unsigned int[SubMeshes.size()];
 202.238 +	m_CurrentScene->mRootNode->mNumMeshes=SubMeshes.size();
 202.239 +	for(unsigned int i=0; i<SubMeshes.size(); ++i)
 202.240 +		m_CurrentScene->mRootNode->mMeshes[i]=i;
 202.241 +
 202.242 +	
 202.243 +
 202.244 +	CreateAssimpSkeleton(Bones, Animations);
 202.245 +	PutAnimationsInScene(Bones, Animations);
 202.246 +	//___________________________________________________________
 202.247 +}
 202.248 +
 202.249 +
 202.250 +const aiImporterDesc* OgreImporter::GetInfo () const
 202.251 +{
 202.252 +	return &desc;
 202.253 +}
 202.254 +
 202.255 +
 202.256 +void OgreImporter::SetupProperties(const Importer* pImp)
 202.257 +{
 202.258 +	m_MaterialLibFilename=pImp->GetPropertyString(AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE, "Scene.material");
 202.259 +	m_TextureTypeFromFilename=pImp->GetPropertyBool(AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME, false);
 202.260 +}
 202.261 +
 202.262 +
 202.263 +}//namespace Ogre
 202.264 +}//namespace Assimp
 202.265 +
 202.266 +#endif  // !! ASSIMP_BUILD_NO_OGRE_IMPORTER
   203.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   203.2 +++ b/libs/assimp/OgreImporter.hpp	Sat Feb 01 19:58:19 2014 +0200
   203.3 @@ -0,0 +1,185 @@
   203.4 +#include "BaseImporter.h"
   203.5 +
   203.6 +#include <vector>
   203.7 +
   203.8 +#include "OgreXmlHelper.hpp"
   203.9 +#include "irrXMLWrapper.h"
  203.10 +
  203.11 +/// Ogre Importer TODO
  203.12 +/*	- Read Vertex Colors
  203.13 +	- Read multiple TexCoords
  203.14 +*/
  203.15 +
  203.16 +
  203.17 +
  203.18 +namespace Assimp
  203.19 +{
  203.20 +namespace Ogre
  203.21 +{
  203.22 +
  203.23 +
  203.24 +//Forward declarations:
  203.25 +struct Face;
  203.26 +struct Weight;
  203.27 +struct Bone;
  203.28 +struct Animation;
  203.29 +struct Track;
  203.30 +struct Keyframe;
  203.31 +
  203.32 +///A submesh from Ogre
  203.33 +struct SubMesh
  203.34 +{	
  203.35 +	bool SharedData;
  203.36 +
  203.37 +	std::string Name;
  203.38 +	std::string MaterialName;
  203.39 +	std::vector<Face> FaceList;
  203.40 +
  203.41 +	std::vector<aiVector3D> Positions; bool HasPositions;
  203.42 +	std::vector<aiVector3D> Normals; bool HasNormals;
  203.43 +	std::vector<aiVector3D> Tangents; bool HasTangents;
  203.44 +	std::vector<std::vector<aiVector3D> > Uvs;//arbitrary number of texcoords, they are nearly always 2d, but assimp has always 3d texcoords, n vectors(outer) with texcoords for each vertex(inner)
  203.45 +
  203.46 +	std::vector< std::vector<Weight> > Weights;//a list(inner) of bones for each vertex(outer)
  203.47 +	int MaterialIndex;///< The Index in the Assimp Materialarray from the material witch is attached to this submesh
  203.48 +	unsigned int BonesUsed;//the highest index of a bone from a bone weight, this is needed to create the assimp bone structur (converting from Vertex-Bones to Bone-Vertices)
  203.49 +
  203.50 +	SubMesh(): SharedData(false), HasPositions(false), HasNormals(false), HasTangents(false),
  203.51 +		MaterialIndex(-1), BonesUsed(0) {}//initialize everything
  203.52 +};
  203.53 +
  203.54 +
  203.55 +///The Main Ogre Importer Class
  203.56 +class OgreImporter : public BaseImporter
  203.57 +{
  203.58 +public:
  203.59 +	virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
  203.60 +	virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
  203.61 +	virtual const aiImporterDesc* GetInfo () const;
  203.62 +	virtual void SetupProperties(const Importer* pImp);
  203.63 +private:
  203.64 +
  203.65 +
  203.66 +	//-------------------------------- OgreMesh.cpp -------------------------------
  203.67 +	/// Helper Functions to read parts of the XML File
  203.68 +	void ReadSubMesh(SubMesh& theSubMesh, XmlReader* Reader);//the submesh reference is the result value
  203.69 +
  203.70 +	/// Reads a single Vertexbuffer and writes its data in the Submesh
  203.71 +	static void ReadVertexBuffer(SubMesh &theSubMesh, XmlReader *Reader, unsigned int NumVertices);
  203.72 +
  203.73 +	/// Reads bone weights are stores them into the given submesh
  203.74 +	static void ReadBoneWeights(SubMesh &theSubMesh, XmlReader *Reader);
  203.75 +
  203.76 +	/// After Loading a SubMehs some work needs to be done (make all Vertexes unique, normalize weights)
  203.77 +	static void ProcessSubMesh(SubMesh &theSubMesh, SubMesh &theSharedGeometry);
  203.78 +
  203.79 +	/// Uses the bone data to convert a SubMesh into a aiMesh which will be created and returned
  203.80 +	aiMesh* CreateAssimpSubMesh(const SubMesh &theSubMesh, const std::vector<Bone>& Bones) const;
  203.81 +	
  203.82 +
  203.83 +	//-------------------------------- OgreSkeleton.cpp -------------------------------
  203.84 +	/// Writes the results in Bones and Animations, Filename is not const, because its call-by-value and the function will change it!
  203.85 +	void LoadSkeleton(std::string FileName, std::vector<Bone> &Bones, std::vector<Animation> &Animations) const;
  203.86 +
  203.87 +	/// Converts the animations in aiAnimations and puts them into the scene
  203.88 +	void PutAnimationsInScene(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations);
  203.89 +
  203.90 +	/// Creates the aiskeleton in current scene
  203.91 +	void CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations);
  203.92 +
  203.93 +	/// Recursivly creates a filled aiNode from a given root bone
  203.94 +	static aiNode* CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode);
  203.95 +	
  203.96 +
  203.97 +	//-------------------------------- OgreMaterial.cpp -------------------------------
  203.98 +	aiMaterial* LoadMaterial(const std::string MaterialName) const;
  203.99 +	void ReadTechnique(std::stringstream &ss, aiMaterial* NewMaterial) const;
 203.100 +	
 203.101 +
 203.102 +
 203.103 +
 203.104 +	//Now we don't have to give theses parameters to all functions
 203.105 +	std::string m_CurrentFilename;
 203.106 +	std::string m_MaterialLibFilename;
 203.107 +	bool m_TextureTypeFromFilename;
 203.108 +	IOSystem* m_CurrentIOHandler;
 203.109 +	aiScene *m_CurrentScene;
 203.110 +	SubMesh m_SharedGeometry;///< we will just use the vertexbuffers of the submesh
 203.111 +};
 203.112 +
 203.113 +///For the moment just triangles, no other polygon types!
 203.114 +struct Face
 203.115 +{
 203.116 +	unsigned int VertexIndices[3];
 203.117 +};
 203.118 +
 203.119 +struct BoneAssignment
 203.120 +{
 203.121 +	unsigned int BoneId;//this is, what we get from ogre
 203.122 +	std::string BoneName;//this is, what we need for assimp
 203.123 +};
 203.124 +
 203.125 +///for a vertex->bone structur
 203.126 +struct Weight
 203.127 +{
 203.128 +	unsigned int BoneId;
 203.129 +	float Value;
 203.130 +};
 203.131 +
 203.132 +
 203.133 +/// Helper Class to describe an ogre-bone for the skeleton:
 203.134 +/** All Id's are signed ints, because than we have -1 as a simple INVALID_ID Value (we start from 0 so 0 is a valid bone ID!*/
 203.135 +struct Bone
 203.136 +{
 203.137 +	int Id;
 203.138 +	int ParentId;
 203.139 +	std::string Name;
 203.140 +	aiVector3D Position;
 203.141 +	float RotationAngle;
 203.142 +	aiVector3D RotationAxis;
 203.143 +	std::vector<int> Children;
 203.144 +	aiMatrix4x4 BoneToWorldSpace;
 203.145 +
 203.146 +	///ctor
 203.147 +	Bone(): Id(-1), ParentId(-1), RotationAngle(0.0f) {}
 203.148 +	///this operator is needed to sort the bones after Id's
 203.149 +	bool operator<(const Bone& rval) const
 203.150 +		{return Id<rval.Id; }
 203.151 +	///this operator is needed to find a bone by its name in a vector<Bone>
 203.152 +	bool operator==(const std::string& rval) const
 203.153 +		{return Name==rval; }
 203.154 +	bool operator==(const aiString& rval) const
 203.155 +	{return Name==std::string(rval.data); }
 203.156 +
 203.157 +	// implemented in OgreSkeleton.cpp
 203.158 +	void CalculateBoneToWorldSpaceMatrix(std::vector<Bone>& Bones);
 203.159 +};
 203.160 +
 203.161 +
 203.162 +
 203.163 +///Describes an Ogre Animation
 203.164 +struct Animation
 203.165 +{
 203.166 +	std::string Name;
 203.167 +	float Length;
 203.168 +	std::vector<Track> Tracks;
 203.169 +};
 203.170 +
 203.171 +///a track (keyframes for one bone) from an animation
 203.172 +struct Track
 203.173 +{
 203.174 +	std::string BoneName;
 203.175 +	std::vector<Keyframe> Keyframes;
 203.176 +};
 203.177 +
 203.178 +/// keyframe (bone transformation) from a track from a animation
 203.179 +struct Keyframe
 203.180 +{
 203.181 +	float Time;
 203.182 +	aiVector3D Position;
 203.183 +	aiQuaternion Rotation;
 203.184 +	aiVector3D Scaling;
 203.185 +};
 203.186 +
 203.187 +}//namespace Ogre
 203.188 +}//namespace Assimp
   204.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   204.2 +++ b/libs/assimp/OgreMaterial.cpp	Sat Feb 01 19:58:19 2014 +0200
   204.3 @@ -0,0 +1,453 @@
   204.4 +/*
   204.5 +Open Asset Import Library (assimp)
   204.6 +----------------------------------------------------------------------
   204.7 +
   204.8 +Copyright (c) 2006-2012, assimp team
   204.9 +All rights reserved.
  204.10 +
  204.11 +Redistribution and use of this software in source and binary forms, 
  204.12 +with or without modification, are permitted provided that the 
  204.13 +following conditions are met:
  204.14 +
  204.15 +* Redistributions of source code must retain the above
  204.16 +  copyright notice, this list of conditions and the
  204.17 +  following disclaimer.
  204.18 +
  204.19 +* Redistributions in binary form must reproduce the above
  204.20 +  copyright notice, this list of conditions and the
  204.21 +  following disclaimer in the documentation and/or other
  204.22 +  materials provided with the distribution.
  204.23 +
  204.24 +* Neither the name of the assimp team, nor the names of its
  204.25 +  contributors may be used to endorse or promote products
  204.26 +  derived from this software without specific prior
  204.27 +  written permission of the assimp team.
  204.28 +
  204.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  204.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  204.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  204.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  204.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  204.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  204.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  204.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  204.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  204.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  204.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  204.40 +
  204.41 +----------------------------------------------------------------------
  204.42 +*/
  204.43 +
  204.44 +/**
  204.45 +This file contains material related code. This is
  204.46 +spilitted up from the main file OgreImporter.cpp
  204.47 +to make it shorter easier to maintain.
  204.48 +*/
  204.49 +#include "AssimpPCH.h"
  204.50 +
  204.51 +#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
  204.52 +
  204.53 +#include <vector>
  204.54 +#include <sstream>
  204.55 +using namespace std;
  204.56 +
  204.57 +#include "OgreImporter.hpp"
  204.58 +#include "irrXMLWrapper.h"
  204.59 +#include "TinyFormatter.h"
  204.60 +
  204.61 +namespace Assimp
  204.62 +{
  204.63 +namespace Ogre
  204.64 +{
  204.65 +
  204.66 +
  204.67 +
  204.68 +aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const
  204.69 +{
  204.70 +	/*For better understanding of the material parser, here is a material example file:
  204.71 +
  204.72 +	material Sarg
  204.73 +	{
  204.74 +		receive_shadows on
  204.75 +		technique
  204.76 +		{
  204.77 +			pass
  204.78 +			{
  204.79 +				ambient 0.500000 0.500000 0.500000 1.000000
  204.80 +				diffuse 0.640000 0.640000 0.640000 1.000000
  204.81 +				specular 0.500000 0.500000 0.500000 1.000000 12.500000
  204.82 +				emissive 0.000000 0.000000 0.000000 1.000000
  204.83 +				texture_unit
  204.84 +				{
  204.85 +					texture SargTextur.tga
  204.86 +					tex_address_mode wrap
  204.87 +					filtering linear linear none
  204.88 +				}
  204.89 +			}
  204.90 +		}
  204.91 +	}
  204.92 +
  204.93 +	*/
  204.94 +
  204.95 +	/*and here is another one:
  204.96 +
  204.97 +	import * from abstract_base_passes_depth.material
  204.98 +	import * from abstract_base.material
  204.99 +	import * from mat_shadow_caster.material
 204.100 +	import * from mat_character_singlepass.material
 204.101 +
 204.102 +	material hero/hair/caster : mat_shadow_caster_skin_areject
 204.103 +	{
 204.104 +	  set $diffuse_map "hero_hair_alpha_c.dds"
 204.105 +	}
 204.106 +	
 204.107 +	material hero/hair_alpha : mat_char_cns_singlepass_areject_4weights
 204.108 +	{
 204.109 +	  set $diffuse_map  "hero_hair_alpha_c.dds"
 204.110 +	  set $specular_map "hero_hair_alpha_s.dds"
 204.111 +	  set $normal_map   "hero_hair_alpha_n.dds"
 204.112 +	  set $light_map    "black_lightmap.dds"
 204.113 +  
 204.114 +	  set $shadow_caster_material "hero/hair/caster"
 204.115 +	}
 204.116 +	*/
 204.117 +
 204.118 +	//Read the file into memory and put it in a stringstream
 204.119 +	stringstream ss;
 204.120 +	{// after this block, the temporarly loaded data will be released
 204.121 +
 204.122 +		/*
 204.123 +		We have 3 guesses for the Material filename:
 204.124 +		- the Material Name
 204.125 +		- the Name of the mesh file
 204.126 +		- the DefaultMaterialLib (which you can set before importing)
 204.127 +		*/
 204.128 +		
 204.129 +		IOStream* MatFilePtr=m_CurrentIOHandler->Open(MaterialName+".material");
 204.130 +		if(NULL==MatFilePtr)
 204.131 +		{
 204.132 +			//the filename typically ends with .mesh or .mesh.xml
 204.133 +			const string MaterialFileName=m_CurrentFilename.substr(0, m_CurrentFilename.rfind(".mesh"))+".material";
 204.134 +
 204.135 +			MatFilePtr=m_CurrentIOHandler->Open(MaterialFileName);
 204.136 +			if(NULL==MatFilePtr)
 204.137 +			{
 204.138 +				//try the default mat Library
 204.139 +				if(NULL==MatFilePtr)
 204.140 +				{
 204.141 +				
 204.142 +					MatFilePtr=m_CurrentIOHandler->Open(m_MaterialLibFilename);
 204.143 +					if(NULL==MatFilePtr)
 204.144 +					{
 204.145 +						DefaultLogger::get()->error(m_MaterialLibFilename+" and "+MaterialFileName + " could not be opened, Material will not be loaded!");
 204.146 +						return new aiMaterial();
 204.147 +					}
 204.148 +				}
 204.149 +			}
 204.150 +		}
 204.151 +		//Fill the stream
 204.152 +		boost::scoped_ptr<IOStream> MaterialFile(MatFilePtr);
 204.153 +		if(MaterialFile->FileSize()>0)
 204.154 +		{
 204.155 +			vector<char> FileData(MaterialFile->FileSize());
 204.156 +			MaterialFile->Read(&FileData[0], MaterialFile->FileSize(), 1);
 204.157 +			BaseImporter::ConvertToUTF8(FileData);
 204.158 +
 204.159 +			FileData.push_back('\0');//terminate the string with zero, so that the ss can parse it correctly
 204.160 +			ss << &FileData[0];
 204.161 +		}
 204.162 +		else
 204.163 +		{
 204.164 +			DefaultLogger::get()->warn("Material " + MaterialName + " seams to be empty");
 204.165 +			return NULL;
 204.166 +		}
 204.167 +	}
 204.168 +
 204.169 +	//create the material
 204.170 +	aiMaterial *NewMaterial=new aiMaterial();
 204.171 +
 204.172 +	aiString ts(MaterialName.c_str());
 204.173 +	NewMaterial->AddProperty(&ts, AI_MATKEY_NAME);
 204.174 +
 204.175 +	string Line;
 204.176 +	ss >> Line;
 204.177 +//	unsigned int Level=0;//Hierarchielevels in the material file, like { } blocks into another
 204.178 +	while(!ss.eof())
 204.179 +	{
 204.180 +		if(Line=="material")
 204.181 +		{
 204.182 +			ss >> Line;
 204.183 +			if(Line==MaterialName)//Load the next material
 204.184 +			{
 204.185 +				string RestOfLine;
 204.186 +				getline(ss, RestOfLine);//ignore the rest of the line
 204.187 +				ss >> Line;
 204.188 +
 204.189 +				if(Line!="{")
 204.190 +				{
 204.191 +					DefaultLogger::get()->warn("empyt material!");
 204.192 +					return NULL;
 204.193 +				}
 204.194 +
 204.195 +				while(Line!="}")//read until the end of the material
 204.196 +				{
 204.197 +					//Proceed to the first technique
 204.198 +					ss >> Line;
 204.199 +					if(Line=="technique")
 204.200 +					{
 204.201 +						ReadTechnique(ss, NewMaterial);
 204.202 +					}
 204.203 +
 204.204 +					DefaultLogger::get()->info(Line);
 204.205 +					//read informations from a custom material:
 204.206 +					if(Line=="set")
 204.207 +					{
 204.208 +						ss >> Line;
 204.209 +						if(Line=="$specular")//todo load this values:
 204.210 +						{
 204.211 +						}
 204.212 +						if(Line=="$diffuse")
 204.213 +						{
 204.214 +						}
 204.215 +						if(Line=="$ambient")
 204.216 +						{
 204.217 +						}
 204.218 +						if(Line=="$colormap")
 204.219 +						{
 204.220 +							ss >> Line;
 204.221 +							aiString ts(Line.c_str());
 204.222 +							NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
 204.223 +						}
 204.224 +						if(Line=="$normalmap")
 204.225 +						{
 204.226 +							ss >> Line;
 204.227 +							aiString ts(Line.c_str());
 204.228 +							NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
 204.229 +						}
 204.230 +						
 204.231 +						if(Line=="$shininess_strength")
 204.232 +						{
 204.233 +							ss >> Line;
 204.234 +							float Shininess=fast_atof(Line.c_str());
 204.235 +							NewMaterial->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS_STRENGTH);
 204.236 +						}
 204.237 +
 204.238 +						if(Line=="$shininess_exponent")
 204.239 +						{
 204.240 +							ss >> Line;
 204.241 +							float Shininess=fast_atof(Line.c_str());
 204.242 +							NewMaterial->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS);
 204.243 +						}
 204.244 +
 204.245 +						//Properties from Venetica:
 204.246 +						if(Line=="$diffuse_map")
 204.247 +						{
 204.248 +							ss >> Line;
 204.249 +							if(Line[0]=='"')// "file" -> file
 204.250 +								Line=Line.substr(1, Line.size()-2);
 204.251 +							aiString ts(Line.c_str());
 204.252 +							NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
 204.253 +						}
 204.254 +						if(Line=="$specular_map")
 204.255 +						{
 204.256 +							ss >> Line;
 204.257 +							if(Line[0]=='"')// "file" -> file
 204.258 +								Line=Line.substr(1, Line.size()-2);
 204.259 +							aiString ts(Line.c_str());
 204.260 +							NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0));
 204.261 +						}
 204.262 +						if(Line=="$normal_map")
 204.263 +						{
 204.264 +							ss >> Line;
 204.265 +							if(Line[0]=='"')// "file" -> file
 204.266 +								Line=Line.substr(1, Line.size()-2);
 204.267 +							aiString ts(Line.c_str());
 204.268 +							NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
 204.269 +						}
 204.270 +						if(Line=="$light_map")
 204.271 +						{
 204.272 +							ss >> Line;
 204.273 +							if(Line[0]=='"')// "file" -> file
 204.274 +								Line=Line.substr(1, Line.size()-2);
 204.275 +							aiString ts(Line.c_str());
 204.276 +							NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, 0));
 204.277 +						}
 204.278 +					}					
 204.279 +				}//end of material
 204.280 +			}
 204.281 +			else {} //this is the wrong material, proceed the file until we reach the next material
 204.282 +		}
 204.283 +		ss >> Line;
 204.284 +	}
 204.285 +
 204.286 +	return NewMaterial;
 204.287 +}
 204.288 +
 204.289 +void OgreImporter::ReadTechnique(stringstream &ss, aiMaterial* NewMaterial) const
 204.290 +{
 204.291 +	unsigned int CurrentDiffuseTextureId=0;
 204.292 +	unsigned int CurrentSpecularTextureId=0;
 204.293 +	unsigned int CurrentNormalTextureId=0;
 204.294 +	unsigned int CurrentLightTextureId=0;
 204.295 +
 204.296 +
 204.297 +	string RestOfLine;
 204.298 +	getline(ss, RestOfLine);//ignore the rest of the line
 204.299 +
 204.300 +	string Line;
 204.301 +	ss >> Line;
 204.302 +	if(Line!="{")
 204.303 +	{
 204.304 +		DefaultLogger::get()->warn("empty technique!");
 204.305 +		return;
 204.306 +	}
 204.307 +	while(Line!="}")//read until the end of the technique
 204.308 +	{
 204.309 +		ss >> Line;
 204.310 +		if(Line=="pass")
 204.311 +		{
 204.312 +			getline(ss, RestOfLine);//ignore the rest of the line
 204.313 +
 204.314 +			ss >> Line;
 204.315 +			if(Line!="{")
 204.316 +			{
 204.317 +				DefaultLogger::get()->warn("empty pass!");
 204.318 +				return;
 204.319 +			}
 204.320 +			while(Line!="}")//read until the end of the pass
 204.321 +			{
 204.322 +				ss >> Line;
 204.323 +				if(Line=="ambient")
 204.324 +				{
 204.325 +					float r,g,b;
 204.326 +					ss >> r >> g >> b;
 204.327 +					const aiColor3D Color(r,g,b);
 204.328 +					NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_AMBIENT);
 204.329 +				}
 204.330 +				else if(Line=="diffuse")
 204.331 +				{
 204.332 +					float r,g,b;
 204.333 +					ss >> r >> g >> b;
 204.334 +					const aiColor3D Color(r,g,b);
 204.335 +					NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_DIFFUSE);
 204.336 +				}
 204.337 +				else if(Line=="specular")
 204.338 +				{
 204.339 +					float r,g,b;
 204.340 +					ss >> r >> g >> b;
 204.341 +					const aiColor3D Color(r,g,b);
 204.342 +					NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_SPECULAR);
 204.343 +				}
 204.344 +				else if(Line=="emmisive")
 204.345 +				{
 204.346 +					float r,g,b;
 204.347 +					ss >> r >> g >> b;
 204.348 +					const aiColor3D Color(r,g,b);
 204.349 +					NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_EMISSIVE);
 204.350 +				}
 204.351 +				else if(Line=="texture_unit")
 204.352 +				{
 204.353 +					getline(ss, RestOfLine);//ignore the rest of the line
 204.354 +
 204.355 +					std::string TextureName;
 204.356 +					int TextureType=-1;
 204.357 +					int UvSet=0;
 204.358 +
 204.359 +					ss >> Line;
 204.360 +					if(Line!="{")
 204.361 +						throw DeadlyImportError("empty texture unit!");
 204.362 +					while(Line!="}")//read until the end of the texture_unit
 204.363 +					{
 204.364 +						ss >> Line;
 204.365 +						if(Line=="texture")
 204.366 +						{
 204.367 +							ss >> Line;
 204.368 +							TextureName=Line;
 204.369 +
 204.370 +							if(m_TextureTypeFromFilename)
 204.371 +							{
 204.372 +								if(Line.find("_n.")!=string::npos)// Normalmap
 204.373 +								{
 204.374 +									TextureType=aiTextureType_NORMALS;
 204.375 +								}
 204.376 +								else if(Line.find("_s.")!=string::npos)// Specularmap
 204.377 +								{
 204.378 +									TextureType=aiTextureType_SPECULAR;
 204.379 +								}
 204.380 +								else if(Line.find("_l.")!=string::npos)// Lightmap
 204.381 +								{
 204.382 +									TextureType=aiTextureType_LIGHTMAP;
 204.383 +								}
 204.384 +								else// colormap
 204.385 +								{
 204.386 +									TextureType=aiTextureType_DIFFUSE;
 204.387 +								}
 204.388 +							}
 204.389 +							else
 204.390 +							{
 204.391 +								TextureType=aiTextureType_DIFFUSE;
 204.392 +							}
 204.393 +						}
 204.394 +						else if(Line=="tex_coord_set")
 204.395 +						{
 204.396 +							ss >> UvSet;
 204.397 +						}
 204.398 +						else if(Line=="colour_op")//TODO implement this
 204.399 +						{
 204.400 +							/*
 204.401 +							ss >> Line;
 204.402 +							if("replace"==Line)//I don't think, assimp has something for this...
 204.403 +							{
 204.404 +							}
 204.405 +							else if("modulate"==Line)
 204.406 +							{
 204.407 +								//TODO: set value
 204.408 +								//NewMaterial->AddProperty(aiTextureOp_Multiply)
 204.409 +							}
 204.410 +							*/
 204.411 +						}
 204.412 +						
 204.413 +					}//end of texture unit
 204.414 +					Line="";//clear the } that would end the outer loop
 204.415 +
 204.416 +					//give the texture to assimp:
 204.417 +					
 204.418 +					aiString ts(TextureName.c_str());
 204.419 +					switch(TextureType)
 204.420 +					{
 204.421 +					case aiTextureType_DIFFUSE:
 204.422 +						NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, CurrentDiffuseTextureId));
 204.423 +						NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentDiffuseTextureId));
 204.424 +						CurrentDiffuseTextureId++;
 204.425 +						break;
 204.426 +					case aiTextureType_NORMALS:
 204.427 +						NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, CurrentNormalTextureId));
 204.428 +						NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentNormalTextureId));
 204.429 +						CurrentNormalTextureId++;
 204.430 +						break;
 204.431 +					case aiTextureType_SPECULAR:
 204.432 +						NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SPECULAR, CurrentSpecularTextureId));
 204.433 +						NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentSpecularTextureId));
 204.434 +						CurrentSpecularTextureId++;
 204.435 +						break;
 204.436 +					case aiTextureType_LIGHTMAP:
 204.437 +						NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, CurrentLightTextureId));
 204.438 +						NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentLightTextureId));
 204.439 +						CurrentLightTextureId++;
 204.440 +						break;
 204.441 +					default:
 204.442 +						DefaultLogger::get()->warn("Invalid Texture Type!");
 204.443 +						break;
 204.444 +					}
 204.445 +				}
 204.446 +			}
 204.447 +			Line="";//clear the } that would end the outer loop
 204.448 +		}
 204.449 +	}//end of technique
 204.450 +}
 204.451 +
 204.452 +
 204.453 +}//namespace Ogre
 204.454 +}//namespace Assimp
 204.455 +
 204.456 +#endif  // !! ASSIMP_BUILD_NO_OGRE_IMPORTER
   205.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   205.2 +++ b/libs/assimp/OgreMesh.cpp	Sat Feb 01 19:58:19 2014 +0200
   205.3 @@ -0,0 +1,516 @@
   205.4 +/*
   205.5 +Open Asset Import Library (assimp)
   205.6 +----------------------------------------------------------------------
   205.7 +
   205.8 +Copyright (c) 2006-2012, assimp team
   205.9 +All rights reserved.
  205.10 +
  205.11 +Redistribution and use of this software in source and binary forms, 
  205.12 +with or without modification, are permitted provided that the 
  205.13 +following conditions are met:
  205.14 +
  205.15 +* Redistributions of source code must retain the above
  205.16 +  copyright notice, this list of conditions and the
  205.17 +  following disclaimer.
  205.18 +
  205.19 +* Redistributions in binary form must reproduce the above
  205.20 +  copyright notice, this list of conditions and the
  205.21 +  following disclaimer in the documentation and/or other
  205.22 +  materials provided with the distribution.
  205.23 +
  205.24 +* Neither the name of the assimp team, nor the names of its
  205.25 +  contributors may be used to endorse or promote products
  205.26 +  derived from this software without specific prior
  205.27 +  written permission of the assimp team.
  205.28 +
  205.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  205.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  205.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  205.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  205.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  205.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  205.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  205.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  205.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  205.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  205.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  205.40 +
  205.41 +----------------------------------------------------------------------
  205.42 +*/
  205.43 +
  205.44 +#include "AssimpPCH.h"
  205.45 +
  205.46 +#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
  205.47 +
  205.48 +#include "OgreImporter.hpp"
  205.49 +#include "TinyFormatter.h"
  205.50 +
  205.51 +using namespace std;
  205.52 +
  205.53 +namespace Assimp
  205.54 +{
  205.55 +namespace Ogre
  205.56 +{
  205.57 +
  205.58 +
  205.59 +void OgreImporter::ReadSubMesh(SubMesh &theSubMesh, XmlReader *Reader)
  205.60 +{
  205.61 +	if(Reader->getAttributeValue("usesharedvertices"))
  205.62 +		theSubMesh.SharedData=GetAttribute<bool>(Reader, "usesharedvertices");
  205.63 +
  205.64 +	XmlRead(Reader);
  205.65 +	//TODO: maybe we have alsways just 1 faces and 1 geometry and always in this order. this loop will only work correct, when the order
  205.66 +	//of faces and geometry changed, and not if we have more than one of one
  205.67 +	while(	Reader->getNodeName()==string("faces")
  205.68 +		||	Reader->getNodeName()==string("geometry")
  205.69 +		||	Reader->getNodeName()==string("boneassignments"))
  205.70 +	{
  205.71 +		if(string(Reader->getNodeName())=="faces")//Read the face list
  205.72 +		{
  205.73 +			//some info logging:
  205.74 +			unsigned int NumFaces=GetAttribute<int>(Reader, "count");
  205.75 +			ostringstream ss; ss <<"Submesh has " << NumFaces << " Faces.";
  205.76 +			DefaultLogger::get()->debug(ss.str());
  205.77 +
  205.78 +			while(XmlRead(Reader) && Reader->getNodeName()==string("face"))
  205.79 +			{
  205.80 +				Face NewFace;
  205.81 +				NewFace.VertexIndices[0]=GetAttribute<int>(Reader, "v1");
  205.82 +				NewFace.VertexIndices[1]=GetAttribute<int>(Reader, "v2");
  205.83 +				NewFace.VertexIndices[2]=GetAttribute<int>(Reader, "v3");
  205.84 +				if(Reader->getAttributeValue("v4"))//this should be supported in the future
  205.85 +				{
  205.86 +					DefaultLogger::get()->warn("Submesh has quads, only traingles are supported!");
  205.87 +					//throw DeadlyImportError("Submesh has quads, only traingles are supported!");
  205.88 +				}
  205.89 +				theSubMesh.FaceList.push_back(NewFace);
  205.90 +			}
  205.91 +
  205.92 +		}//end of faces
  205.93 +		else if(string(Reader->getNodeName())=="geometry")//Read the vertexdata
  205.94 +		{	
  205.95 +			//some info logging:
  205.96 +			unsigned int NumVertices=GetAttribute<int>(Reader, "vertexcount");
  205.97 +			ostringstream ss; ss<<"VertexCount: " << NumVertices;
  205.98 +			DefaultLogger::get()->debug(ss.str());
  205.99 +			
 205.100 +			//General Informations about vertices
 205.101 +			XmlRead(Reader);
 205.102 +			while(Reader->getNodeName()==string("vertexbuffer"))
 205.103 +			{
 205.104 +				ReadVertexBuffer(theSubMesh, Reader, NumVertices);
 205.105 +			}
 205.106 +
 205.107 +			//some error checking on the loaded data
 205.108 +			if(!theSubMesh.HasPositions)
 205.109 +				throw DeadlyImportError("No positions could be loaded!");
 205.110 +
 205.111 +			if(theSubMesh.HasNormals && theSubMesh.Normals.size() != NumVertices)
 205.112 +				throw DeadlyImportError("Wrong Number of Normals loaded!");
 205.113 +
 205.114 +			if(theSubMesh.HasTangents && theSubMesh.Tangents.size() != NumVertices)
 205.115 +				throw DeadlyImportError("Wrong Number of Tangents loaded!");
 205.116 +
 205.117 +			for(unsigned int i=0; i<theSubMesh.Uvs.size(); ++i)
 205.118 +			{
 205.119 +				if(theSubMesh.Uvs[i].size() != NumVertices)
 205.120 +					throw DeadlyImportError("Wrong Number of Uvs loaded!");
 205.121 +			}
 205.122 +
 205.123 +		}//end of "geometry
 205.124 +
 205.125 +
 205.126 +		else if(Reader->getNodeName()==string("boneassignments"))
 205.127 +		{
 205.128 +			ReadBoneWeights(theSubMesh, Reader);
 205.129 +		}
 205.130 +	}
 205.131 +	DefaultLogger::get()->debug((Formatter::format(),
 205.132 +		"Positionen: ",theSubMesh.Positions.size(),
 205.133 +		" Normale: ",theSubMesh.Normals.size(),
 205.134 +		" TexCoords: ",theSubMesh.Uvs.size(),
 205.135 +		" Tantents: ",theSubMesh.Tangents.size()
 205.136 +	));
 205.137 +}
 205.138 +
 205.139 +
 205.140 +void OgreImporter::ReadVertexBuffer(SubMesh &theSubMesh, XmlReader *Reader, unsigned int NumVertices)
 205.141 +{
 205.142 +	DefaultLogger::get()->debug("new Vertex Buffer");
 205.143 +
 205.144 +	bool ReadPositions=false;
 205.145 +	bool ReadNormals=false;
 205.146 +	bool ReadTangents=false;
 205.147 +	unsigned int NumUvs=0;
 205.148 +
 205.149 +	//-------------------- check, what we need to read: --------------------------------
 205.150 +	if(Reader->getAttributeValue("positions") && GetAttribute<bool>(Reader, "positions"))
 205.151 +	{
 205.152 +		ReadPositions=theSubMesh.HasPositions=true;
 205.153 +		theSubMesh.Positions.reserve(NumVertices);
 205.154 +		DefaultLogger::get()->debug("reading positions");
 205.155 +	}
 205.156 +	if(Reader->getAttributeValue("normals") && GetAttribute<bool>(Reader, "normals"))
 205.157 +	{
 205.158 +		ReadNormals=theSubMesh.HasNormals=true;
 205.159 +		theSubMesh.Normals.reserve(NumVertices);
 205.160 +		DefaultLogger::get()->debug("reading normals");
 205.161 +	}
 205.162 +	if(Reader->getAttributeValue("tangents") && GetAttribute<bool>(Reader, "tangents"))
 205.163 +	{
 205.164 +		ReadTangents=theSubMesh.HasTangents=true;
 205.165 +		theSubMesh.Tangents.reserve(NumVertices);
 205.166 +		DefaultLogger::get()->debug("reading tangents");
 205.167 +	}
 205.168 +
 205.169 +	if(Reader->getAttributeValue("texture_coords"))
 205.170 +	{
 205.171 +		NumUvs=GetAttribute<unsigned int>(Reader, "texture_coords");
 205.172 +		theSubMesh.Uvs.resize(NumUvs);
 205.173 +		for(unsigned int i=0; i<theSubMesh.Uvs.size(); ++i) theSubMesh.Uvs[i].reserve(NumVertices);
 205.174 +		DefaultLogger::get()->debug("reading texture coords");
 205.175 +	}
 205.176 +	//___________________________________________________________________
 205.177 +
 205.178 +
 205.179 +	//check if we will load anything
 205.180 +	if(!( ReadPositions || ReadNormals || ReadTangents || (NumUvs>0) ))
 205.181 +		DefaultLogger::get()->warn("vertexbuffer seams to be empty!");
 205.182 +	
 205.183 +
 205.184 +	//read all the vertices:
 205.185 +	XmlRead(Reader);
 205.186 +
 205.187 +	/*it might happen, that we have more than one attribute per vertex (they are not splitted to different buffers)
 205.188 +	so the break condition is a bit tricky */
 205.189 +	while(Reader->getNodeName()==string("vertex")
 205.190 +		||Reader->getNodeName()==string("position")
 205.191 +		||Reader->getNodeName()==string("normal")
 205.192 +		||Reader->getNodeName()==string("tangent")
 205.193 +		||Reader->getNodeName()==string("texcoord")
 205.194 +		||Reader->getNodeName()==string("colour_diffuse"))
 205.195 +	{
 205.196 +		if(Reader->getNodeName()==string("vertex"))
 205.197 +			XmlRead(Reader);//Read an attribute tag
 205.198 +
 205.199 +		//Position
 205.200 +		if(ReadPositions && Reader->getNodeName()==string("position"))
 205.201 +		{
 205.202 +			aiVector3D NewPos;
 205.203 +			NewPos.x=GetAttribute<float>(Reader, "x");
 205.204 +			NewPos.y=GetAttribute<float>(Reader, "y");
 205.205 +			NewPos.z=GetAttribute<float>(Reader, "z");
 205.206 +			theSubMesh.Positions.push_back(NewPos);
 205.207 +		}
 205.208 +				
 205.209 +		//Normal
 205.210 +		else if(ReadNormals && Reader->getNodeName()==string("normal"))
 205.211 +		{
 205.212 +			aiVector3D NewNormal;
 205.213 +			NewNormal.x=GetAttribute<float>(Reader, "x");
 205.214 +			NewNormal.y=GetAttribute<float>(Reader, "y");
 205.215 +			NewNormal.z=GetAttribute<float>(Reader, "z");
 205.216 +			theSubMesh.Normals.push_back(NewNormal);
 205.217 +		}
 205.218 +				
 205.219 +		//Tangent
 205.220 +		else if(ReadTangents && Reader->getNodeName()==string("tangent"))
 205.221 +		{
 205.222 +			aiVector3D NewTangent;
 205.223 +			NewTangent.x=GetAttribute<float>(Reader, "x");
 205.224 +			NewTangent.y=GetAttribute<float>(Reader, "y");
 205.225 +			NewTangent.z=GetAttribute<float>(Reader, "z");
 205.226 +			theSubMesh.Tangents.push_back(NewTangent);
 205.227 +		}
 205.228 +
 205.229 +		//Uv:
 205.230 +		else if(NumUvs>0 && Reader->getNodeName()==string("texcoord"))
 205.231 +		{
 205.232 +			for(unsigned int i=0; i<NumUvs; ++i)
 205.233 +			{
 205.234 +				if(Reader->getNodeName()!=string("texcoord"))
 205.235 +				{
 205.236 +					DefaultLogger::get()->warn(string("Not enough UVs in Vertex: ")+Reader->getNodeName());
 205.237 +				}
 205.238 +				aiVector3D NewUv;
 205.239 +				NewUv.x=GetAttribute<float>(Reader, "u");
 205.240 +				NewUv.y=GetAttribute<float>(Reader, "v")*(-1)+1;//flip the uv vertikal, blender exports them so!
 205.241 +				theSubMesh.Uvs[i].push_back(NewUv);
 205.242 +				XmlRead(Reader);
 205.243 +			}
 205.244 +			continue;//because we already read the next node...
 205.245 +		}
 205.246 +
 205.247 +		//Color:
 205.248 +		//TODO: actually save this data!
 205.249 +		else if(Reader->getNodeName()==string("colour_diffuse"))
 205.250 +		{
 205.251 +			//do nothing, because we not yet support them
 205.252 +		}
 205.253 +
 205.254 +		//Attribute could not be read
 205.255 +		else
 205.256 +		{
 205.257 +			DefaultLogger::get()->warn(string("Attribute was not read: ")+Reader->getNodeName());
 205.258 +		}
 205.259 +
 205.260 +		XmlRead(Reader);//Read the Vertex tag
 205.261 +	}
 205.262 +}
 205.263 +
 205.264 +
 205.265 +void OgreImporter::ReadBoneWeights(SubMesh &theSubMesh, XmlReader *Reader)
 205.266 +{
 205.267 +	theSubMesh.Weights.resize(theSubMesh.Positions.size());
 205.268 +	while(XmlRead(Reader) && Reader->getNodeName()==string("vertexboneassignment"))
 205.269 +	{
 205.270 +		Weight NewWeight;
 205.271 +		unsigned int VertexId=GetAttribute<int>(Reader, "vertexindex");
 205.272 +		NewWeight.BoneId=GetAttribute<int>(Reader, "boneindex");
 205.273 +		NewWeight.Value=GetAttribute<float>(Reader, "weight");
 205.274 +		//calculate the number of bones used (this is the highest id +1 becuase bone ids start at 0)
 205.275 +		theSubMesh.BonesUsed=max(theSubMesh.BonesUsed, NewWeight.BoneId+1);
 205.276 +
 205.277 +		theSubMesh.Weights[VertexId].push_back(NewWeight);
 205.278 +	}
 205.279 +}
 205.280 +
 205.281 +
 205.282 +
 205.283 +void OgreImporter::ProcessSubMesh(SubMesh &theSubMesh, SubMesh &theSharedGeometry)
 205.284 +{
 205.285 +	//---------------Make all Vertexes unique: (this is required by assimp)-----------------------
 205.286 +	vector<Face> UniqueFaceList(theSubMesh.FaceList.size());
 205.287 +	unsigned int UniqueVertexCount=theSubMesh.FaceList.size()*3;//*3 because each face consists of 3 vertexes, because we only support triangles^^
 205.288 +
 205.289 +	vector<aiVector3D> UniquePositions(UniqueVertexCount);
 205.290 +
 205.291 +	vector<aiVector3D> UniqueNormals(UniqueVertexCount);
 205.292 +
 205.293 +	vector<aiVector3D> UniqueTangents(UniqueVertexCount);
 205.294 +
 205.295 +	vector< vector<Weight> > UniqueWeights(UniqueVertexCount);
 205.296 +
 205.297 +	vector< vector<aiVector3D> > UniqueUvs(theSubMesh.Uvs.size());
 205.298 +	for(unsigned int i=0; i<UniqueUvs.size(); ++i)	UniqueUvs[i].resize(UniqueVertexCount);
 205.299 +
 205.300 +
 205.301 +
 205.302 +	//Support for shared data:
 205.303 +	/*We can use this loop to copy vertex informations from the shared data pool. In order to do so
 205.304 +	  we just use a reference to a submodel instead of our submodel itself*/
 205.305 +
 205.306 +	SubMesh& VertexSource= theSubMesh.SharedData ? theSharedGeometry : theSubMesh;
 205.307 +	if(theSubMesh.SharedData)//copy vertexinformations to our mesh:
 205.308 +	{
 205.309 +		theSubMesh.HasPositions=theSharedGeometry.HasPositions;
 205.310 +		theSubMesh.HasNormals=theSharedGeometry.HasNormals;
 205.311 +		theSubMesh.HasTangents=theSharedGeometry.HasTangents;
 205.312 +
 205.313 +		theSubMesh.BonesUsed=theSharedGeometry.BonesUsed;
 205.314 +
 205.315 +		UniqueUvs.resize(theSharedGeometry.Uvs.size());
 205.316 +		for(unsigned int i=0; i<UniqueUvs.size(); ++i)	UniqueUvs[i].resize(UniqueVertexCount);
 205.317 +	}
 205.318 +
 205.319 +	for(unsigned int i=0; i<theSubMesh.FaceList.size(); ++i)
 205.320 +	{
 205.321 +		//We precalculate the index vlaues her, because we need them in all vertex attributes
 205.322 +		unsigned int Vertex1=theSubMesh.FaceList[i].VertexIndices[0];
 205.323 +		unsigned int Vertex2=theSubMesh.FaceList[i].VertexIndices[1];
 205.324 +		unsigned int Vertex3=theSubMesh.FaceList[i].VertexIndices[2];
 205.325 +
 205.326 +		UniquePositions[3*i+0]=VertexSource.Positions[Vertex1];
 205.327 +		UniquePositions[3*i+1]=VertexSource.Positions[Vertex2];
 205.328 +		UniquePositions[3*i+2]=VertexSource.Positions[Vertex3];
 205.329 +
 205.330 +		if(VertexSource.HasNormals)
 205.331 +		{
 205.332 +			UniqueNormals[3*i+0]=VertexSource.Normals[Vertex1];
 205.333 +			UniqueNormals[3*i+1]=VertexSource.Normals[Vertex2];
 205.334 +			UniqueNormals[3*i+2]=VertexSource.Normals[Vertex3];
 205.335 +		}
 205.336 +
 205.337 +		if(VertexSource.HasTangents)
 205.338 +		{
 205.339 +			UniqueTangents[3*i+0]=VertexSource.Tangents[Vertex1];
 205.340 +			UniqueTangents[3*i+1]=VertexSource.Tangents[Vertex2];
 205.341 +			UniqueTangents[3*i+2]=VertexSource.Tangents[Vertex3];
 205.342 +		}
 205.343 +
 205.344 +		if(UniqueUvs.size()>0)
 205.345 +		{
 205.346 +			for(unsigned int j=0; j<UniqueUvs.size(); ++j)
 205.347 +			{
 205.348 +				UniqueUvs[j][3*i+0]=VertexSource.Uvs[j][Vertex1];
 205.349 +				UniqueUvs[j][3*i+1]=VertexSource.Uvs[j][Vertex2];
 205.350 +				UniqueUvs[j][3*i+2]=VertexSource.Uvs[j][Vertex3];
 205.351 +			}
 205.352 +		}
 205.353 +
 205.354 +		if(VertexSource.Weights.size() > 0)
 205.355 +		{
 205.356 +			UniqueWeights[3*i+0]=VertexSource.Weights[Vertex1];
 205.357 +			UniqueWeights[3*i+1]=VertexSource.Weights[Vertex2];
 205.358 +			UniqueWeights[3*i+2]=VertexSource.Weights[Vertex3];
 205.359 +		}
 205.360 +
 205.361 +		//The indexvalues a just continuous numbers (0, 1, 2, 3, 4, 5, 6...)
 205.362 +		UniqueFaceList[i].VertexIndices[0]=3*i+0;
 205.363 +		UniqueFaceList[i].VertexIndices[1]=3*i+1;
 205.364 +		UniqueFaceList[i].VertexIndices[2]=3*i+2;
 205.365 +	}
 205.366 +	//_________________________________________________________________________________________
 205.367 +
 205.368 +	//now we have the unique datas, but want them in the SubMesh, so we swap all the containers:
 205.369 +	//if we don't have one of them, we just swap empty containers, so everything is ok
 205.370 +	theSubMesh.FaceList.swap(UniqueFaceList);
 205.371 +	theSubMesh.Positions.swap(UniquePositions);
 205.372 +	theSubMesh.Normals.swap(UniqueNormals);
 205.373 +	theSubMesh.Tangents.swap(UniqueTangents);
 205.374 +	theSubMesh.Uvs.swap(UniqueUvs);
 205.375 +	theSubMesh.Weights.swap(UniqueWeights);
 205.376 +
 205.377 +
 205.378 +
 205.379 +	//------------- normalize weights -----------------------------
 205.380 +	//The Blender exporter doesn't care about whether the sum of all boneweights for a single vertex equals 1 or not,
 205.381 +	//so we have to make this sure:
 205.382 +	for(unsigned int VertexId=0; VertexId<theSubMesh.Weights.size(); ++VertexId)//iterate over all vertices
 205.383 +	{
 205.384 +		float WeightSum=0.0f;
 205.385 +		for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
 205.386 +		{
 205.387 +			WeightSum+=theSubMesh.Weights[VertexId][BoneId].Value;
 205.388 +		}
 205.389 +		
 205.390 +		//check if the sum is too far away from 1
 205.391 +		if(WeightSum<1.0f-0.05f || WeightSum>1.0f+0.05f)
 205.392 +		{
 205.393 +			//normalize all weights:
 205.394 +			for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
 205.395 +			{
 205.396 +				theSubMesh.Weights[VertexId][BoneId].Value/=WeightSum;
 205.397 +			}
 205.398 +		}
 205.399 +	}
 205.400 +	//_________________________________________________________
 205.401 +}
 205.402 +
 205.403 +
 205.404 +
 205.405 +
 205.406 +aiMesh* OgreImporter::CreateAssimpSubMesh(const SubMesh& theSubMesh, const vector<Bone>& Bones) const
 205.407 +{
 205.408 +	const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
 205.409 +	(void)m_CurrentScene;
 205.410 +
 205.411 +	aiMesh* NewAiMesh=new aiMesh();
 205.412 +		
 205.413 +	//Positions
 205.414 +	NewAiMesh->mVertices=new aiVector3D[theSubMesh.Positions.size()];
 205.415 +	memcpy(NewAiMesh->mVertices, &theSubMesh.Positions[0], theSubMesh.Positions.size()*sizeof(aiVector3D));
 205.416 +	NewAiMesh->mNumVertices=theSubMesh.Positions.size();
 205.417 +
 205.418 +	//Normals
 205.419 +	if(theSubMesh.HasNormals)
 205.420 +	{
 205.421 +		NewAiMesh->mNormals=new aiVector3D[theSubMesh.Normals.size()];
 205.422 +		memcpy(NewAiMesh->mNormals, &theSubMesh.Normals[0], theSubMesh.Normals.size()*sizeof(aiVector3D));
 205.423 +	}
 205.424 +
 205.425 +
 205.426 +	//until we have support for bitangents, no tangents will be written
 205.427 +	/*
 205.428 +	//Tangents
 205.429 +	if(theSubMesh.HasTangents)
 205.430 +	{
 205.431 +		NewAiMesh->mTangents=new aiVector3D[theSubMesh.Tangents.size()];
 205.432 +		memcpy(NewAiMesh->mTangents, &theSubMesh.Tangents[0], theSubMesh.Tangents.size()*sizeof(aiVector3D));
 205.433 +	}
 205.434 +	*/
 205.435 +
 205.436 +	//Uvs
 205.437 +	if(theSubMesh.Uvs.size()>0)
 205.438 +	{
 205.439 +		for(unsigned int i=0; i<theSubMesh.Uvs.size(); ++i)
 205.440 +		{
 205.441 +			NewAiMesh->mNumUVComponents[i]=2;
 205.442 +			NewAiMesh->mTextureCoords[i]=new aiVector3D[theSubMesh.Uvs[i].size()];
 205.443 +			memcpy(NewAiMesh->mTextureCoords[i], &(theSubMesh.Uvs[i][0]), theSubMesh.Uvs[i].size()*sizeof(aiVector3D));
 205.444 +		}
 205.445 +	}
 205.446 +
 205.447 +
 205.448 +	//---------------------------------------- Bones --------------------------------------------
 205.449 +
 205.450 +	//Copy the weights in in Bone-Vertices Struktur
 205.451 +	//(we have them in a Vertex-Bones Structur, this is much easier for making them unique, which is required by assimp
 205.452 +	vector< vector<aiVertexWeight> > aiWeights(theSubMesh.BonesUsed);//now the outer list are the bones, and the inner vector the vertices
 205.453 +	for(unsigned int VertexId=0; VertexId<theSubMesh.Weights.size(); ++VertexId)//iterate over all vertices
 205.454 +	{
 205.455 +		for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
 205.456 +		{
 205.457 +			aiVertexWeight NewWeight;
 205.458 +			NewWeight.mVertexId=VertexId;//the current Vertex, we can't use the Id form the submehs weights, because they are bone id's
 205.459 +			NewWeight.mWeight=theSubMesh.Weights[VertexId][BoneId].Value;
 205.460 +			aiWeights[theSubMesh.Weights[VertexId][BoneId].BoneId].push_back(NewWeight);
 205.461 +		}
 205.462 +	}
 205.463 +
 205.464 +	
 205.465 +
 205.466 +	vector<aiBone*> aiBones;
 205.467 +	aiBones.reserve(theSubMesh.BonesUsed);//the vector might be smaller, because there might be empty bones (bones that are not attached to any vertex)
 205.468 +	
 205.469 +	//create all the bones and fill them with informations
 205.470 +	for(unsigned int i=0; i<theSubMesh.BonesUsed; ++i)
 205.471 +	{
 205.472 +		if(aiWeights[i].size()>0)
 205.473 +		{
 205.474 +			aiBone* NewBone=new aiBone();
 205.475 +			NewBone->mNumWeights=aiWeights[i].size();
 205.476 +			NewBone->mWeights=new aiVertexWeight[aiWeights[i].size()];
 205.477 +			memcpy(NewBone->mWeights, &(aiWeights[i][0]), sizeof(aiVertexWeight)*aiWeights[i].size());
 205.478 +			NewBone->mName=Bones[i].Name;//The bone list should be sorted after its id's, this was done in LoadSkeleton
 205.479 +			NewBone->mOffsetMatrix=Bones[i].BoneToWorldSpace;
 205.480 +				
 205.481 +			aiBones.push_back(NewBone);
 205.482 +		}
 205.483 +	}
 205.484 +	NewAiMesh->mNumBones=aiBones.size();
 205.485 +	
 205.486 +	// mBones must be NULL if mNumBones is non 0 or the validation fails.
 205.487 +	if (aiBones.size()) {
 205.488 +		NewAiMesh->mBones=new aiBone* [aiBones.size()];
 205.489 +		memcpy(NewAiMesh->mBones, &(aiBones[0]), aiBones.size()*sizeof(aiBone*));
 205.490 +	}
 205.491 +
 205.492 +	//______________________________________________________________________________________________________
 205.493 +
 205.494 +
 205.495 +
 205.496 +	//Faces
 205.497 +	NewAiMesh->mFaces=new aiFace[theSubMesh.FaceList.size()];
 205.498 +	for(unsigned int i=0; i<theSubMesh.FaceList.size(); ++i)
 205.499 +	{
 205.500 +		NewAiMesh->mFaces[i].mNumIndices=3;
 205.501 +		NewAiMesh->mFaces[i].mIndices=new unsigned int[3];
 205.502 +
 205.503 +		NewAiMesh->mFaces[i].mIndices[0]=theSubMesh.FaceList[i].VertexIndices[0];
 205.504 +		NewAiMesh->mFaces[i].mIndices[1]=theSubMesh.FaceList[i].VertexIndices[1];
 205.505 +		NewAiMesh->mFaces[i].mIndices[2]=theSubMesh.FaceList[i].VertexIndices[2];
 205.506 +	}
 205.507 +	NewAiMesh->mNumFaces=theSubMesh.FaceList.size();
 205.508 +
 205.509 +	//Link the material:
 205.510 +	NewAiMesh->mMaterialIndex=theSubMesh.MaterialIndex;//the index is set by the function who called ReadSubMesh
 205.511 +
 205.512 +	return NewAiMesh;
 205.513 +}
 205.514 +
 205.515 +
 205.516 +}//namespace Ogre
 205.517 +}//namespace Assimp
 205.518 +
 205.519 +#endif  // !! ASSIMP_BUILD_NO_OGRE_IMPORTER
   206.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   206.2 +++ b/libs/assimp/OgreSkeleton.cpp	Sat Feb 01 19:58:19 2014 +0200
   206.3 @@ -0,0 +1,451 @@
   206.4 +/*
   206.5 +Open Asset Import Library (assimp)
   206.6 +----------------------------------------------------------------------
   206.7 +
   206.8 +Copyright (c) 2006-2012, assimp team
   206.9 +All rights reserved.
  206.10 +
  206.11 +Redistribution and use of this software in source and binary forms, 
  206.12 +with or without modification, are permitted provided that the 
  206.13 +following conditions are met:
  206.14 +
  206.15 +* Redistributions of source code must retain the above
  206.16 +  copyright notice, this list of conditions and the
  206.17 +  following disclaimer.
  206.18 +
  206.19 +* Redistributions in binary form must reproduce the above
  206.20 +  copyright notice, this list of conditions and the
  206.21 +  following disclaimer in the documentation and/or other
  206.22 +  materials provided with the distribution.
  206.23 +
  206.24 +* Neither the name of the assimp team, nor the names of its
  206.25 +  contributors may be used to endorse or promote products
  206.26 +  derived from this software without specific prior
  206.27 +  written permission of the assimp team.
  206.28 +
  206.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  206.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  206.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  206.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  206.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  206.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  206.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  206.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  206.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  206.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  206.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  206.40 +
  206.41 +----------------------------------------------------------------------
  206.42 +*/
  206.43 +
  206.44 +#include "AssimpPCH.h"
  206.45 +
  206.46 +#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
  206.47 +
  206.48 +#include "OgreImporter.hpp"
  206.49 +#include "TinyFormatter.h"
  206.50 +
  206.51 +using namespace std;
  206.52 +
  206.53 +namespace Assimp
  206.54 +{
  206.55 +namespace Ogre
  206.56 +{
  206.57 +
  206.58 +
  206.59 +
  206.60 +void OgreImporter::LoadSkeleton(std::string FileName, vector<Bone> &Bones, vector<Animation> &Animations) const
  206.61 +{
  206.62 +	const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
  206.63 +	(void)m_CurrentScene;
  206.64 +
  206.65 +
  206.66 +	//most likely the skeleton file will only end with .skeleton
  206.67 +	//But this is a xml reader, so we need: .skeleton.xml
  206.68 +	FileName+=".xml";
  206.69 +
  206.70 +	DefaultLogger::get()->debug(string("Loading Skeleton: ")+FileName);
  206.71 +
  206.72 +	//Open the File:
  206.73 +	boost::scoped_ptr<IOStream> File(m_CurrentIOHandler->Open(FileName));
  206.74 +	if(NULL==File.get())
  206.75 +		throw DeadlyImportError("Failed to open skeleton file "+FileName+".");
  206.76 +
  206.77 +	//Read the Mesh File:
  206.78 +	boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(File.get()));
  206.79 +	XmlReader* SkeletonFile = irr::io::createIrrXMLReader(mIOWrapper.get());
  206.80 +	if(!SkeletonFile)
  206.81 +		throw DeadlyImportError(string("Failed to create XML Reader for ")+FileName);
  206.82 +
  206.83 +	XmlRead(SkeletonFile);
  206.84 +	if(string("skeleton")!=SkeletonFile->getNodeName())
  206.85 +		throw DeadlyImportError("No <skeleton> node in SkeletonFile: "+FileName);
  206.86 +
  206.87 +
  206.88 +
  206.89 +	//------------------------------------load bones-----------------------------------------
  206.90 +	XmlRead(SkeletonFile);
  206.91 +	if(string("bones")!=SkeletonFile->getNodeName())
  206.92 +		throw DeadlyImportError("No bones node in skeleton "+FileName);
  206.93 +
  206.94 +	XmlRead(SkeletonFile);
  206.95 +
  206.96 +	while(string("bone")==SkeletonFile->getNodeName())
  206.97 +	{
  206.98 +		//TODO: Maybe we can have bone ids for the errrors, but normaly, they should never appear, so what....
  206.99 +
 206.100 +		//read a new bone:
 206.101 +		Bone NewBone;
 206.102 +		NewBone.Id=GetAttribute<int>(SkeletonFile, "id");
 206.103 +		NewBone.Name=GetAttribute<string>(SkeletonFile, "name");
 206.104 +
 206.105 +		//load the position:
 206.106 +		XmlRead(SkeletonFile);
 206.107 +		if(string("position")!=SkeletonFile->getNodeName())
 206.108 +			throw DeadlyImportError("Position is not first node in Bone!");
 206.109 +		NewBone.Position.x=GetAttribute<float>(SkeletonFile, "x");
 206.110 +		NewBone.Position.y=GetAttribute<float>(SkeletonFile, "y");
 206.111 +		NewBone.Position.z=GetAttribute<float>(SkeletonFile, "z");
 206.112 +
 206.113 +		//Rotation:
 206.114 +		XmlRead(SkeletonFile);
 206.115 +		if(string("rotation")!=SkeletonFile->getNodeName())
 206.116 +			throw DeadlyImportError("Rotation is not the second node in Bone!");
 206.117 +		NewBone.RotationAngle=GetAttribute<float>(SkeletonFile, "angle");
 206.118 +		XmlRead(SkeletonFile);
 206.119 +		if(string("axis")!=SkeletonFile->getNodeName())
 206.120 +			throw DeadlyImportError("No axis specified for bone rotation!");
 206.121 +		NewBone.RotationAxis.x=GetAttribute<float>(SkeletonFile, "x");
 206.122 +		NewBone.RotationAxis.y=GetAttribute<float>(SkeletonFile, "y");
 206.123 +		NewBone.RotationAxis.z=GetAttribute<float>(SkeletonFile, "z");
 206.124 +
 206.125 +		//append the newly loaded bone to the bone list
 206.126 +		Bones.push_back(NewBone);
 206.127 +
 206.128 +		//Proceed to the next bone:
 206.129 +		XmlRead(SkeletonFile);
 206.130 +	}
 206.131 +	//The bones in the file a not neccesarly ordered by there id's so we do it now:
 206.132 +	std::sort(Bones.begin(), Bones.end());
 206.133 +
 206.134 +	//now the id of each bone should be equal to its position in the vector:
 206.135 +	//so we do a simple check:
 206.136 +	{
 206.137 +		bool IdsOk=true;
 206.138 +		for(int i=0; i<static_cast<signed int>(Bones.size()); ++i)//i is signed, because all Id's are also signed!
 206.139 +		{
 206.140 +			if(Bones[i].Id!=i)
 206.141 +				IdsOk=false;
 206.142 +		}
 206.143 +		if(!IdsOk)
 206.144 +			throw DeadlyImportError("Bone Ids are not valid!"+FileName);
 206.145 +	}
 206.146 +	DefaultLogger::get()->debug((Formatter::format(),"Number of bones: ",Bones.size()));
 206.147 +	//________________________________________________________________________________
 206.148 +
 206.149 +
 206.150 +
 206.151 +
 206.152 +
 206.153 +
 206.154 +	//----------------------------load bonehierarchy--------------------------------
 206.155 +	if(string("bonehierarchy")!=SkeletonFile->getNodeName())
 206.156 +		throw DeadlyImportError("no bonehierarchy node in "+FileName);
 206.157 +
 206.158 +	DefaultLogger::get()->debug("loading bonehierarchy...");
 206.159 +	XmlRead(SkeletonFile);
 206.160 +	while(string("boneparent")==SkeletonFile->getNodeName())
 206.161 +	{
 206.162 +		string Child, Parent;
 206.163 +		Child=GetAttribute<string>(SkeletonFile, "bone");
 206.164 +		Parent=GetAttribute<string>(SkeletonFile, "parent");
 206.165 +
 206.166 +		unsigned int ChildId, ParentId;
 206.167 +		ChildId=find(Bones.begin(), Bones.end(), Child)->Id;
 206.168 +		ParentId=find(Bones.begin(), Bones.end(), Parent)->Id;
 206.169 +
 206.170 +		Bones[ChildId].ParentId=ParentId;
 206.171 +		Bones[ParentId].Children.push_back(ChildId);
 206.172 +
 206.173 +		XmlRead(SkeletonFile);
 206.174 +	}
 206.175 +	//_____________________________________________________________________________
 206.176 +
 206.177 +
 206.178 +	//--------- Calculate the WorldToBoneSpace Matrix recursively for all bones: ------------------
 206.179 +	BOOST_FOREACH(Bone &theBone, Bones)
 206.180 +	{
 206.181 +		if(-1==theBone.ParentId) //the bone is a root bone
 206.182 +		{
 206.183 +			theBone.CalculateBoneToWorldSpaceMatrix(Bones);
 206.184 +		}
 206.185 +	}
 206.186 +	//_______________________________________________________________________
 206.187 +	
 206.188 +
 206.189 +	//---------------------------load animations-----------------------------
 206.190 +	if(string("animations")==SkeletonFile->getNodeName())//animations are optional values
 206.191 +	{
 206.192 +		DefaultLogger::get()->debug("Loading Animations");
 206.193 +		XmlRead(SkeletonFile);
 206.194 +		while(string("animation")==SkeletonFile->getNodeName())
 206.195 +		{
 206.196 +			Animation NewAnimation;
 206.197 +			NewAnimation.Name=GetAttribute<string>(SkeletonFile, "name");
 206.198 +			NewAnimation.Length=GetAttribute<float>(SkeletonFile, "length");
 206.199 +			
 206.200 +			//Load all Tracks
 206.201 +			XmlRead(SkeletonFile);
 206.202 +			if(string("tracks")!=SkeletonFile->getNodeName())
 206.203 +				throw DeadlyImportError("no tracks node in animation");
 206.204 +			XmlRead(SkeletonFile);
 206.205 +			while(string("track")==SkeletonFile->getNodeName())
 206.206 +			{
 206.207 +				Track NewTrack;
 206.208 +				NewTrack.BoneName=GetAttribute<string>(SkeletonFile, "bone");
 206.209 +
 206.210 +				//Load all keyframes;
 206.211 +				XmlRead(SkeletonFile);
 206.212 +				if(string("keyframes")!=SkeletonFile->getNodeName())
 206.213 +					throw DeadlyImportError("no keyframes node!");
 206.214 +				XmlRead(SkeletonFile);
 206.215 +				while(string("keyframe")==SkeletonFile->getNodeName())
 206.216 +				{
 206.217 +					Keyframe NewKeyframe;
 206.218 +					NewKeyframe.Time=GetAttribute<float>(SkeletonFile, "time");
 206.219 +
 206.220 +					//loop over the attributes:
 206.221 +					
 206.222 +					while(true) //will quit, if a Node is not a animationkey
 206.223 +					{
 206.224 +						XmlRead(SkeletonFile);
 206.225 +
 206.226 +						//If any property doesn't show up, it will keep its initialization value
 206.227 +
 206.228 +						//Position:
 206.229 +						if(string("translate")==SkeletonFile->getNodeName())
 206.230 +						{
 206.231 +							NewKeyframe.Position.x=GetAttribute<float>(SkeletonFile, "x");
 206.232 +							NewKeyframe.Position.y=GetAttribute<float>(SkeletonFile, "y");
 206.233 +							NewKeyframe.Position.z=GetAttribute<float>(SkeletonFile, "z");
 206.234 +						}
 206.235 +
 206.236 +						//Rotation:
 206.237 +						else if(string("rotate")==SkeletonFile->getNodeName())
 206.238 +						{
 206.239 +							float RotationAngle=GetAttribute<float>(SkeletonFile, "angle");
 206.240 +							aiVector3D RotationAxis;
 206.241 +							XmlRead(SkeletonFile);
 206.242 +							if(string("axis")!=SkeletonFile->getNodeName())
 206.243 +								throw DeadlyImportError("No axis for keyframe rotation!");
 206.244 +							RotationAxis.x=GetAttribute<float>(SkeletonFile, "x");
 206.245 +							RotationAxis.y=GetAttribute<float>(SkeletonFile, "y");
 206.246 +							RotationAxis.z=GetAttribute<float>(SkeletonFile, "z");
 206.247 +
 206.248 +							if(0==RotationAxis.x && 0==RotationAxis.y && 0==RotationAxis.z)//we have an invalid rotation axis
 206.249 +							{
 206.250 +								RotationAxis.x=1.0f;
 206.251 +								if(0!=RotationAngle)//if we don't rotate at all, the axis does not matter
 206.252 +								{
 206.253 +									DefaultLogger::get()->warn("Invalid Rotation Axis in Keyframe!");
 206.254 +								}
 206.255 +							}
 206.256 +							NewKeyframe.Rotation=aiQuaternion(RotationAxis, RotationAngle);
 206.257 +						}
 206.258 +
 206.259 +						//Scaling:
 206.260 +						else if(string("scale")==SkeletonFile->getNodeName())
 206.261 +						{
 206.262 +							NewKeyframe.Scaling.x=GetAttribute<float>(SkeletonFile, "x");
 206.263 +							NewKeyframe.Scaling.y=GetAttribute<float>(SkeletonFile, "y");
 206.264 +							NewKeyframe.Scaling.z=GetAttribute<float>(SkeletonFile, "z");
 206.265 +						}
 206.266 +
 206.267 +						//we suppose, that we read all attributes and this is a new keyframe or the end of the animation
 206.268 +						else
 206.269 +							break;
 206.270 +					}
 206.271 +
 206.272 +					NewTrack.Keyframes.push_back(NewKeyframe);
 206.273 +				}
 206.274 +
 206.275 +				NewAnimation.Tracks.push_back(NewTrack);
 206.276 +			}
 206.277 +
 206.278 +			Animations.push_back(NewAnimation);
 206.279 +		}
 206.280 +	}
 206.281 +	//_____________________________________________________________________________
 206.282 +
 206.283 +}
 206.284 +
 206.285 +
 206.286 +void OgreImporter::CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &/*Animations*/)
 206.287 +{
 206.288 +	if(!m_CurrentScene->mRootNode)
 206.289 +		throw DeadlyImportError("No root node exists!!");
 206.290 +	if(0!=m_CurrentScene->mRootNode->mNumChildren)
 206.291 +		throw DeadlyImportError("Root Node already has childnodes!");
 206.292 +
 206.293 +
 206.294 +	//Createt the assimp bone hierarchy
 206.295 +	vector<aiNode*> RootBoneNodes;
 206.296 +	BOOST_FOREACH(const Bone &theBone, Bones)
 206.297 +	{
 206.298 +		if(-1==theBone.ParentId) //the bone is a root bone
 206.299 +		{
 206.300 +			//which will recursily add all other nodes
 206.301 +			RootBoneNodes.push_back(CreateAiNodeFromBone(theBone.Id, Bones, m_CurrentScene->mRootNode));
 206.302 +		}
 206.303 +	}
 206.304 +	
 206.305 +	if(RootBoneNodes.size() > 0)
 206.306 +	{
 206.307 +		m_CurrentScene->mRootNode->mNumChildren=RootBoneNodes.size();	
 206.308 +		m_CurrentScene->mRootNode->mChildren=new aiNode*[RootBoneNodes.size()];
 206.309 +		memcpy(m_CurrentScene->mRootNode->mChildren, &RootBoneNodes[0], sizeof(aiNode*)*RootBoneNodes.size());
 206.310 +	}
 206.311 +}
 206.312 +
 206.313 +
 206.314 +void OgreImporter::PutAnimationsInScene(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations)
 206.315 +{
 206.316 +	//-----------------Create the Assimp Animations --------------------
 206.317 +	if(Animations.size()>0)//Maybe the model had only a skeleton and no animations. (If it also has no skeleton, this function would'nt have been called
 206.318 +	{
 206.319 +		m_CurrentScene->mNumAnimations=Animations.size();
 206.320 +		m_CurrentScene->mAnimations=new aiAnimation*[Animations.size()];
 206.321 +		for(unsigned int i=0; i<Animations.size(); ++i)//create all animations
 206.322 +		{
 206.323 +			aiAnimation* NewAnimation=new aiAnimation();
 206.324 +			NewAnimation->mName=Animations[i].Name;
 206.325 +			NewAnimation->mDuration=Animations[i].Length;
 206.326 +			NewAnimation->mTicksPerSecond=1.0f;
 206.327 +
 206.328 +			//Create all tracks in this animation
 206.329 +			NewAnimation->mNumChannels=Animations[i].Tracks.size();
 206.330 +			NewAnimation->mChannels=new aiNodeAnim*[Animations[i].Tracks.size()];
 206.331 +			for(unsigned int j=0; j<Animations[i].Tracks.size(); ++j)
 206.332 +			{
 206.333 +				aiNodeAnim* NewNodeAnim=new aiNodeAnim();
 206.334 +				NewNodeAnim->mNodeName=Animations[i].Tracks[j].BoneName;
 206.335 +
 206.336 +				//we need this, to acces the bones default pose, which we need to make keys absolute to the default bone pose
 206.337 +				vector<Bone>::const_iterator CurBone=find(Bones.begin(), Bones.end(), NewNodeAnim->mNodeName);
 206.338 +				aiMatrix4x4 t0, t1;
 206.339 +				aiMatrix4x4 DefBonePose=aiMatrix4x4::Translation(CurBone->Position, t1)
 206.340 +									 *	aiMatrix4x4::Rotation(CurBone->RotationAngle, CurBone->RotationAxis, t0);
 206.341 +				
 206.342 +
 206.343 +				//Create the keyframe arrays...
 206.344 +				unsigned int KeyframeCount=Animations[i].Tracks[j].Keyframes.size();
 206.345 +				NewNodeAnim->mNumPositionKeys=KeyframeCount;
 206.346 +				NewNodeAnim->mNumRotationKeys=KeyframeCount;
 206.347 +				NewNodeAnim->mNumScalingKeys =KeyframeCount;
 206.348 +				NewNodeAnim->mPositionKeys=new aiVectorKey[KeyframeCount];
 206.349 +				NewNodeAnim->mRotationKeys=new aiQuatKey[KeyframeCount];
 206.350 +				NewNodeAnim->mScalingKeys =new aiVectorKey[KeyframeCount];
 206.351 +				
 206.352 +				//...and fill them
 206.353 +				for(unsigned int k=0; k<KeyframeCount; ++k)
 206.354 +				{
 206.355 +					aiMatrix4x4 t2, t3;
 206.356 +
 206.357 +					//Create a matrix to transfrom a vector from the bones default pose to the bone bones in this animation key
 206.358 +					aiMatrix4x4 PoseToKey=
 206.359 +									  aiMatrix4x4::Translation(Animations[i].Tracks[j].Keyframes[k].Position, t3)	//pos
 206.360 +									* aiMatrix4x4(Animations[i].Tracks[j].Keyframes[k].Rotation.GetMatrix())		//rot
 206.361 +									* aiMatrix4x4::Scaling(Animations[i].Tracks[j].Keyframes[k].Scaling, t2);		//scale
 206.362 +									
 206.363 +
 206.364 +					//calculate the complete transformation from world space to bone space
 206.365 +					aiMatrix4x4 CompleteTransform=DefBonePose * PoseToKey;
 206.366 +					
 206.367 +					aiVector3D Pos;
 206.368 +					aiQuaternion Rot;
 206.369 +					aiVector3D Scale;
 206.370 +
 206.371 +					CompleteTransform.Decompose(Scale, Rot, Pos);
 206.372 +
 206.373 +					double Time=Animations[i].Tracks[j].Keyframes[k].Time;
 206.374 +
 206.375 +					NewNodeAnim->mPositionKeys[k].mTime=Time;
 206.376 +					NewNodeAnim->mPositionKeys[k].mValue=Pos;
 206.377 +					
 206.378 +					NewNodeAnim->mRotationKeys[k].mTime=Time;
 206.379 +					NewNodeAnim->mRotationKeys[k].mValue=Rot;
 206.380 +
 206.381 +					NewNodeAnim->mScalingKeys[k].mTime=Time;
 206.382 +					NewNodeAnim->mScalingKeys[k].mValue=Scale;
 206.383 +				}
 206.384 +				
 206.385 +				NewAnimation->mChannels[j]=NewNodeAnim;
 206.386 +			}
 206.387 +
 206.388 +			m_CurrentScene->mAnimations[i]=NewAnimation;
 206.389 +		}
 206.390 +	}
 206.391 +//TODO: Auf nicht vorhandene Animationskeys achten!
 206.392 +//#pragma warning (s.o.)
 206.393 +	//__________________________________________________________________
 206.394 +}
 206.395 +
 206.396 +
 206.397 +aiNode* OgreImporter::CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode)
 206.398 +{
 206.399 +	//----Create the node for this bone and set its values-----
 206.400 +	aiNode* NewNode=new aiNode(Bones[BoneId].Name);
 206.401 +	NewNode->mParent=ParentNode;
 206.402 +
 206.403 +	aiMatrix4x4 t0,t1;
 206.404 +	NewNode->mTransformation=
 206.405 +		aiMatrix4x4::Translation(Bones[BoneId].Position, t0)
 206.406 +		*aiMatrix4x4::Rotation(Bones[BoneId].RotationAngle, Bones[BoneId].RotationAxis, t1)
 206.407 +	;
 206.408 +	//__________________________________________________________
 206.409 +
 206.410 +
 206.411 +	//---------- recursivly create all children Nodes: ----------
 206.412 +	NewNode->mNumChildren=Bones[BoneId].Children.size();
 206.413 +	NewNode->mChildren=new aiNode*[Bones[BoneId].Children.size()];
 206.414 +	for(unsigned int i=0; i<Bones[BoneId].Children.size(); ++i)
 206.415 +	{
 206.416 +		NewNode->mChildren[i]=CreateAiNodeFromBone(Bones[BoneId].Children[i], Bones, NewNode);
 206.417 +	}
 206.418 +	//____________________________________________________
 206.419 +
 206.420 +
 206.421 +	return NewNode;
 206.422 +}
 206.423 +
 206.424 +
 206.425 +void Bone::CalculateBoneToWorldSpaceMatrix(vector<Bone> &Bones)
 206.426 +{
 206.427 +	//Calculate the matrix for this bone:
 206.428 +
 206.429 +	aiMatrix4x4 t0,t1;
 206.430 +	aiMatrix4x4 Transf=	aiMatrix4x4::Rotation(-RotationAngle, RotationAxis, t1)
 206.431 +					*	aiMatrix4x4::Translation(-Position, t0);
 206.432 +
 206.433 +	if(-1==ParentId)
 206.434 +	{
 206.435 +		BoneToWorldSpace=Transf;
 206.436 +	}
 206.437 +	else
 206.438 +	{
 206.439 +		BoneToWorldSpace=Transf*Bones[ParentId].BoneToWorldSpace;
 206.440 +	}
 206.441 +	
 206.442 +
 206.443 +	//and recursivly for all children:
 206.444 +	BOOST_FOREACH(int theChildren, Children)
 206.445 +	{
 206.446 +		Bones[theChildren].CalculateBoneToWorldSpaceMatrix(Bones);
 206.447 +	}
 206.448 +}
 206.449 +
 206.450 +
 206.451 +}//namespace Ogre
 206.452 +}//namespace Assimp
 206.453 +
 206.454 +#endif  // !! ASSIMP_BUILD_NO_OGRE_IMPORTER
   207.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   207.2 +++ b/libs/assimp/OgreXmlHelper.hpp	Sat Feb 01 19:58:19 2014 +0200
   207.3 @@ -0,0 +1,88 @@
   207.4 +
   207.5 +#include "irrXMLWrapper.h"
   207.6 +#include "fast_atof.h"
   207.7 +
   207.8 +namespace Assimp
   207.9 +{
  207.10 +namespace Ogre
  207.11 +{
  207.12 +	
  207.13 +typedef irr::io::IrrXMLReader XmlReader;
  207.14 +
  207.15 +
  207.16 +//------------Helper Funktion to Get a Attribute Save---------------
  207.17 +template<typename t> inline t GetAttribute(XmlReader* Reader, std::string Name);
  207.18 +
  207.19 +/*
  207.20 +{
  207.21 +	BOOST_STATIC_ASSERT(false);
  207.22 +	return t();
  207.23 +}
  207.24 +*/
  207.25 +
  207.26 +template<> inline int GetAttribute<int>(XmlReader* Reader, std::string Name)
  207.27 +{
  207.28 +	const char* Value=Reader->getAttributeValue(Name.c_str());
  207.29 +	if(Value)
  207.30 +		return atoi(Value);
  207.31 +	else
  207.32 +		throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
  207.33 +}
  207.34 +
  207.35 +template<> inline unsigned int GetAttribute<unsigned int>(XmlReader* Reader, std::string Name)
  207.36 +{
  207.37 +	const char* Value=Reader->getAttributeValue(Name.c_str());
  207.38 +	if(Value)
  207.39 +		return static_cast<unsigned int>(atoi(Value));//yes, ugly, but pfff
  207.40 +	else
  207.41 +		throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
  207.42 +}
  207.43 +
  207.44 +template<> inline float GetAttribute<float>(XmlReader* Reader, std::string Name)
  207.45 +{
  207.46 +	const char* Value=Reader->getAttributeValue(Name.c_str());
  207.47 +	if(Value)
  207.48 +		return fast_atof(Value);
  207.49 +	else
  207.50 +		throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
  207.51 +}
  207.52 +
  207.53 +template<> inline std::string GetAttribute<std::string>(XmlReader* Reader, std::string Name)
  207.54 +{
  207.55 +	const char* Value=Reader->getAttributeValue(Name.c_str());
  207.56 +	if(Value)
  207.57 +		return std::string(Value);
  207.58 +	else
  207.59 +		throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
  207.60 +}
  207.61 +
  207.62 +template<> inline bool GetAttribute<bool>(XmlReader* Reader, std::string Name)
  207.63 +{
  207.64 +	const char* Value=Reader->getAttributeValue(Name.c_str());
  207.65 +	if(Value)
  207.66 +	{
  207.67 +		if(Value==std::string("true"))
  207.68 +			return true;
  207.69 +		else if(Value==std::string("false"))
  207.70 +			return false;
  207.71 +		else
  207.72 +			throw DeadlyImportError(std::string("Bool value has invalid value: "+Name+" / "+Value+" / "+Reader->getNodeName()));
  207.73 +	}
  207.74 +	else
  207.75 +		throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
  207.76 +}
  207.77 +//__________________________________________________________________
  207.78 +
  207.79 +inline bool XmlRead(XmlReader* Reader)
  207.80 +{
  207.81 +	do
  207.82 +	{
  207.83 +		if(!Reader->read())
  207.84 +			return false;
  207.85 +	}
  207.86 +	while(Reader->getNodeType()!=irr::io::EXN_ELEMENT);
  207.87 +	return true;
  207.88 +}
  207.89 +
  207.90 +}//namespace Ogre
  207.91 +}//namespace Assimp
   208.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   208.2 +++ b/libs/assimp/OptimizeGraph.cpp	Sat Feb 01 19:58:19 2014 +0200
   208.3 @@ -0,0 +1,352 @@
   208.4 +/*
   208.5 +---------------------------------------------------------------------------
   208.6 +Open Asset Import Library (assimp)
   208.7 +---------------------------------------------------------------------------
   208.8 +
   208.9 +Copyright (c) 2006-2012, assimp team
  208.10 +
  208.11 +All rights reserved.
  208.12 +
  208.13 +Redistribution and use of this software in source and binary forms, 
  208.14 +with or without modification, are permitted provided that the following 
  208.15 +conditions are met:
  208.16 +
  208.17 +* Redistributions of source code must retain the above
  208.18 +  copyright notice, this list of conditions and the
  208.19 +  following disclaimer.
  208.20 +
  208.21 +* Redistributions in binary form must reproduce the above
  208.22 +  copyright notice, this list of conditions and the
  208.23 +  following disclaimer in the documentation and/or other
  208.24 +  materials provided with the distribution.
  208.25 +
  208.26 +* Neither the name of the assimp team, nor the names of its
  208.27 +  contributors may be used to endorse or promote products
  208.28 +  derived from this software without specific prior
  208.29 +  written permission of the assimp team.
  208.30 +
  208.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  208.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  208.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  208.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  208.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  208.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  208.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  208.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  208.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  208.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  208.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  208.42 +---------------------------------------------------------------------------
  208.43 +*/
  208.44 +
  208.45 +/** @file  OptimizeGraph.cpp
  208.46 + *  @brief Implementation of the aiProcess_OptimizGraph step
  208.47 + */
  208.48 +
  208.49 +#include "AssimpPCH.h"
  208.50 +#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
  208.51 +
  208.52 +using namespace Assimp;
  208.53 +#include "OptimizeGraph.h"
  208.54 +#include "ProcessHelper.h"
  208.55 +#include "SceneCombiner.h"
  208.56 +
  208.57 +#define AI_RESERVED_NODE_NAME "$Reserved_And_Evil"
  208.58 +
  208.59 +/* AI_OG_USE_HASHING enables the use of hashing to speed-up std::set lookups.
  208.60 + * The unhashed variant should be faster, except for *very* large data sets
  208.61 + */
  208.62 +#ifdef AI_OG_USE_HASHING
  208.63 +	// Use our standard hashing function to compute the hash 
  208.64 +#	define AI_OG_GETKEY(str) SuperFastHash(str.data,str.length)
  208.65 +#else
  208.66 +	// Otherwise hope that std::string will utilize a static buffer 
  208.67 +	// for shorter node names. This would avoid endless heap copying.
  208.68 +#	define AI_OG_GETKEY(str) std::string(str.data)
  208.69 +#endif
  208.70 +
  208.71 +// ------------------------------------------------------------------------------------------------
  208.72 +// Constructor to be privately used by Importer
  208.73 +OptimizeGraphProcess::OptimizeGraphProcess()
  208.74 +{}
  208.75 +
  208.76 +// ------------------------------------------------------------------------------------------------
  208.77 +// Destructor, private as well
  208.78 +OptimizeGraphProcess::~OptimizeGraphProcess()
  208.79 +{}
  208.80 +
  208.81 +// ------------------------------------------------------------------------------------------------
  208.82 +// Returns whether the processing step is present in the given flag field.
  208.83 +bool OptimizeGraphProcess::IsActive( unsigned int pFlags) const
  208.84 +{
  208.85 +	return (0 != (pFlags & aiProcess_OptimizeGraph));
  208.86 +}
  208.87 +
  208.88 +// ------------------------------------------------------------------------------------------------
  208.89 +// Setup properties for the postprocessing step
  208.90 +void OptimizeGraphProcess::SetupProperties(const Importer* pImp)
  208.91 +{	
  208.92 +	// Get value of AI_CONFIG_PP_OG_EXCLUDE_LIST
  208.93 +	std::string tmp = pImp->GetPropertyString(AI_CONFIG_PP_OG_EXCLUDE_LIST,"");
  208.94 +	AddLockedNodeList(tmp);
  208.95 +}
  208.96 +
  208.97 +// ------------------------------------------------------------------------------------------------
  208.98 +// Collect new children
  208.99 +void OptimizeGraphProcess::CollectNewChildren(aiNode* nd, std::list<aiNode*>& nodes)
 208.100 +{
 208.101 +	nodes_in += nd->mNumChildren;
 208.102 +
 208.103 +	// Process children
 208.104 +	std::list<aiNode*> child_nodes;
 208.105 +	for (unsigned int i = 0; i < nd->mNumChildren; ++i) {
 208.106 +
 208.107 +		CollectNewChildren(nd->mChildren[i],child_nodes);
 208.108 +		nd->mChildren[i] = NULL;
 208.109 +	}
 208.110 +
 208.111 +	// Check whether we need this node; if not we can replace it by our own children (warn, danger of incest).
 208.112 +	if (locked.find(AI_OG_GETKEY(nd->mName)) == locked.end() ) {
 208.113 +		for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end();) {
 208.114 +
 208.115 +			if (locked.find(AI_OG_GETKEY((*it)->mName)) == locked.end()) {
 208.116 +				(*it)->mTransformation = nd->mTransformation * (*it)->mTransformation;
 208.117 +				nodes.push_back(*it);
 208.118 +
 208.119 +				it = child_nodes.erase(it);
 208.120 +				continue;
 208.121 +			}
 208.122 +			++it;
 208.123 +		}
 208.124 +
 208.125 +		if (nd->mNumMeshes || child_nodes.size()) { 
 208.126 +			nodes.push_back(nd);
 208.127 +		}
 208.128 +		else {
 208.129 +			delete nd; /* bye, node */
 208.130 +			return;
 208.131 +		}
 208.132 +	}
 208.133 +	else {
 208.134 +		
 208.135 +		// Retain our current position in the hierarchy
 208.136 +		nodes.push_back(nd);
 208.137 +
 208.138 +		// Now check for possible optimizations in our list of child nodes. join as many as possible
 208.139 +		aiNode* join_master = NULL;
 208.140 +		aiMatrix4x4 inv;
 208.141 +
 208.142 +		const LockedSetType::const_iterator end = locked.end();
 208.143 +
 208.144 +		std::list<aiNode*> join;
 208.145 +		for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end();)	{
 208.146 +			aiNode* child = *it;
 208.147 +			if (child->mNumChildren == 0 && locked.find(AI_OG_GETKEY(child->mName)) == end) {
 208.148 +			
 208.149 +				// There may be no instanced meshes
 208.150 +				unsigned int n = 0;
 208.151 +				for (; n < child->mNumMeshes;++n) {
 208.152 +					if (meshes[child->mMeshes[n]] > 1) {
 208.153 +						break;
 208.154 +					}
 208.155 +				}
 208.156 +				if (n == child->mNumMeshes) {
 208.157 +
 208.158 +					if (!join_master) {
 208.159 +						join_master = child;
 208.160 +						inv = join_master->mTransformation;
 208.161 +						inv.Inverse();
 208.162 +					}
 208.163 +					else {
 208.164 +
 208.165 +						child->mTransformation = inv * child->mTransformation ;
 208.166 +
 208.167 +						join.push_back(child);	
 208.168 +						it = child_nodes.erase(it);
 208.169 +						continue;
 208.170 +					}
 208.171 +				}
 208.172 +			}
 208.173 +			++it;
 208.174 +		}
 208.175 +		if (join_master && join.size()) {
 208.176 +			join_master->mName.length = sprintf(join_master->mName.data,"$MergedNode_%i",count_merged++);
 208.177 +
 208.178 +			unsigned int out_meshes = 0;
 208.179 +			for (std::list<aiNode*>::iterator it = join.begin(); it != join.end(); ++it) {
 208.180 +				out_meshes += (*it)->mNumMeshes;
 208.181 +			}
 208.182 +			
 208.183 +			// copy all mesh references in one array
 208.184 +			if (out_meshes) {
 208.185 +				unsigned int* meshes = new unsigned int[out_meshes+join_master->mNumMeshes], *tmp = meshes;
 208.186 +				for (unsigned int n = 0; n < join_master->mNumMeshes;++n) {
 208.187 +					*tmp++ = join_master->mMeshes[n];		
 208.188 +				}
 208.189 +
 208.190 +				for (std::list<aiNode*>::iterator it = join.begin(); it != join.end(); ++it) {
 208.191 +					for (unsigned int n = 0; n < (*it)->mNumMeshes; ++n) {
 208.192 +
 208.193 +						*tmp = (*it)->mMeshes[n];
 208.194 +						aiMesh* mesh = mScene->mMeshes[*tmp++];
 208.195 +
 208.196 +						// manually move the mesh into the right coordinate system
 208.197 +						const aiMatrix3x3 IT = aiMatrix3x3( (*it)->mTransformation ).Inverse().Transpose(); 
 208.198 +						for (unsigned int a = 0; a < mesh->mNumVertices; ++a) {
 208.199 +						
 208.200 +							mesh->mVertices[a] *= (*it)->mTransformation;
 208.201 +
 208.202 +							if (mesh->HasNormals())
 208.203 +								mesh->mNormals[a] *= IT;
 208.204 +
 208.205 +							if (mesh->HasTangentsAndBitangents()) {
 208.206 +								mesh->mTangents[a] *= IT;
 208.207 +								mesh->mBitangents[a] *= IT;
 208.208 +							}
 208.209 +						}
 208.210 +					}
 208.211 +					delete *it; // bye, node
 208.212 +				}
 208.213 +				delete[] join_master->mMeshes;
 208.214 +				join_master->mMeshes = meshes;
 208.215 +				join_master->mNumMeshes += out_meshes;
 208.216 +			}
 208.217 +		}
 208.218 +	}
 208.219 +	// reassign children if something changed
 208.220 +	if (child_nodes.empty() || child_nodes.size() > nd->mNumChildren) {
 208.221 +
 208.222 +		delete[] nd->mChildren;
 208.223 +
 208.224 +		if (child_nodes.size())
 208.225 +			nd->mChildren = new aiNode*[child_nodes.size()];
 208.226 +		else nd->mChildren = NULL;
 208.227 +	}
 208.228 +
 208.229 +	nd->mNumChildren = child_nodes.size();
 208.230 +
 208.231 +	aiNode** tmp = nd->mChildren;
 208.232 +	for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end(); ++it) {
 208.233 +		aiNode* node = *tmp++ = *it;
 208.234 +		node->mParent = nd;
 208.235 +	}
 208.236 +
 208.237 +	nodes_out += child_nodes.size();
 208.238 +}
 208.239 +
 208.240 +// ------------------------------------------------------------------------------------------------
 208.241 +// Execute the postprocessing step on the given scene
 208.242 +void OptimizeGraphProcess::Execute( aiScene* pScene)
 208.243 +{
 208.244 +	DefaultLogger::get()->debug("OptimizeGraphProcess begin");
 208.245 +	nodes_in = nodes_out = count_merged = 0;
 208.246 +	mScene = pScene;
 208.247 +
 208.248 +	meshes.resize(pScene->mNumMeshes,0);
 208.249 +	FindInstancedMeshes(pScene->mRootNode);
 208.250 +
 208.251 +	// build a blacklist of identifiers. If the name of a node matches one of these, we won't touch it
 208.252 +	locked.clear();
 208.253 +	for (std::list<std::string>::const_iterator it = locked_nodes.begin(); it != locked_nodes.end(); ++it) {
 208.254 +#ifdef AI_OG_USE_HASHING
 208.255 +		locked.insert(SuperFastHash((*it).c_str()));
 208.256 +#else
 208.257 +		locked.insert(*it);
 208.258 +#endif
 208.259 +	}
 208.260 +
 208.261 +	for (unsigned int i = 0; i < pScene->mNumAnimations; ++i) {
 208.262 +		for (unsigned int a = 0; a < pScene->mAnimations[i]->mNumChannels; ++a) {
 208.263 +		
 208.264 +			aiNodeAnim* anim = pScene->mAnimations[i]->mChannels[a];
 208.265 +			locked.insert(AI_OG_GETKEY(anim->mNodeName));
 208.266 +		}
 208.267 +	}
 208.268 +
 208.269 +	for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
 208.270 +		for (unsigned int a = 0; a < pScene->mMeshes[i]->mNumBones; ++a) {
 208.271 +		
 208.272 +			aiBone* bone = pScene->mMeshes[i]->mBones[a];
 208.273 +			locked.insert(AI_OG_GETKEY(bone->mName));
 208.274 +
 208.275 +			// HACK: Meshes referencing bones may not be transformed; we need to look them.
 208.276 +			// The easiest way to do this is to increase their reference counters ...
 208.277 +			meshes[i] += 2;
 208.278 +		}
 208.279 +	}
 208.280 +
 208.281 +	for (unsigned int i = 0; i < pScene->mNumCameras; ++i) {
 208.282 +		aiCamera* cam = pScene->mCameras[i];
 208.283 +		locked.insert(AI_OG_GETKEY(cam->mName));
 208.284 +	}
 208.285 +
 208.286 +	for (unsigned int i = 0; i < pScene->mNumLights; ++i) {
 208.287 +		aiLight* lgh = pScene->mLights[i];
 208.288 +		locked.insert(AI_OG_GETKEY(lgh->mName));
 208.289 +	}
 208.290 +
 208.291 +	// Insert a dummy master node and make it read-only
 208.292 +	aiNode* dummy_root = new aiNode(AI_RESERVED_NODE_NAME);
 208.293 +	locked.insert(AI_OG_GETKEY(dummy_root->mName));
 208.294 +
 208.295 +	const aiString prev = pScene->mRootNode->mName;
 208.296 +	pScene->mRootNode->mParent = dummy_root;
 208.297 +
 208.298 +	dummy_root->mChildren = new aiNode*[dummy_root->mNumChildren = 1];
 208.299 +	dummy_root->mChildren[0] = pScene->mRootNode;
 208.300 +
 208.301 +	// Do our recursive processing of scenegraph nodes. For each node collect
 208.302 +	// a fully new list of children and allow their children to place themselves
 208.303 +	// on the same hierarchy layer as their parents.
 208.304 +	std::list<aiNode*> nodes;
 208.305 +	CollectNewChildren (dummy_root,nodes);
 208.306 +
 208.307 +	ai_assert(nodes.size() == 1);
 208.308 +
 208.309 +	if (dummy_root->mNumChildren == 0) {
 208.310 +		pScene->mRootNode = NULL;
 208.311 +		throw DeadlyImportError("After optimizing the scene graph, no data remains");
 208.312 +	}
 208.313 +
 208.314 +	if (dummy_root->mNumChildren > 1) {
 208.315 +		pScene->mRootNode = dummy_root;
 208.316 +	
 208.317 +		// Keep the dummy node but assign the name of the old root node to it
 208.318 +		pScene->mRootNode->mName = prev;
 208.319 +	}
 208.320 +	else {
 208.321 +		
 208.322 +		// Remove the dummy root node again.
 208.323 +		pScene->mRootNode = dummy_root->mChildren[0];
 208.324 +
 208.325 +		dummy_root->mChildren[0] = NULL;
 208.326 +		delete dummy_root;
 208.327 +	}
 208.328 +
 208.329 +	pScene->mRootNode->mParent = NULL;
 208.330 +	if (!DefaultLogger::isNullLogger()) {
 208.331 +		if ( nodes_in != nodes_out) {
 208.332 +
 208.333 +			char buf[512];
 208.334 +			sprintf(buf,"OptimizeGraphProcess finished; Input nodes: %i, Output nodes: %i",nodes_in,nodes_out);
 208.335 +			DefaultLogger::get()->info(buf);
 208.336 +		}
 208.337 +		else DefaultLogger::get()->debug("OptimizeGraphProcess finished");
 208.338 +	}
 208.339 +	meshes.clear();
 208.340 +	locked.clear();
 208.341 +}
 208.342 +
 208.343 +// ------------------------------------------------------------------------------------------------
 208.344 +// Buidl a LUT of all instanced meshes
 208.345 +void OptimizeGraphProcess::FindInstancedMeshes (aiNode* pNode)
 208.346 +{
 208.347 +	for (unsigned int i = 0; i < pNode->mNumMeshes;++i) {
 208.348 +		++meshes[pNode->mMeshes[i]]; 
 208.349 +	}
 208.350 +
 208.351 +	for (unsigned int i = 0; i < pNode->mNumChildren; ++i)
 208.352 +		FindInstancedMeshes(pNode->mChildren[i]);
 208.353 +}
 208.354 +
 208.355 +#endif // !! ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
   209.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   209.2 +++ b/libs/assimp/OptimizeGraph.h	Sat Feb 01 19:58:19 2014 +0200
   209.3 @@ -0,0 +1,142 @@
   209.4 +/*
   209.5 +Open Asset Import Library (assimp)
   209.6 +----------------------------------------------------------------------
   209.7 +
   209.8 +Copyright (c) 2006-2012, assimp team
   209.9 +All rights reserved.
  209.10 +
  209.11 +Redistribution and use of this software in source and binary forms, 
  209.12 +with or without modification, are permitted provided that the 
  209.13 +following conditions are met:
  209.14 +
  209.15 +* Redistributions of source code must retain the above
  209.16 +  copyright notice, this list of conditions and the
  209.17 +  following disclaimer.
  209.18 +
  209.19 +* Redistributions in binary form must reproduce the above
  209.20 +  copyright notice, this list of conditions and the
  209.21 +  following disclaimer in the documentation and/or other
  209.22 +  materials provided with the distribution.
  209.23 +
  209.24 +* Neither the name of the assimp team, nor the names of its
  209.25 +  contributors may be used to endorse or promote products
  209.26 +  derived from this software without specific prior
  209.27 +  written permission of the assimp team.
  209.28 +
  209.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  209.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  209.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  209.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  209.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  209.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  209.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  209.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  209.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  209.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  209.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  209.40 +
  209.41 +----------------------------------------------------------------------
  209.42 +*/
  209.43 +
  209.44 +/** @file  OptimizeGraph.h
  209.45 + *  @brief Declares a post processing step to optimize the scenegraph
  209.46 + */
  209.47 +#ifndef AI_OPTIMIZEGRAPHPROCESS_H_INC
  209.48 +#define AI_OPTIMIZEGRAPHPROCESS_H_INC
  209.49 +
  209.50 +#include "BaseProcess.h"
  209.51 +#include "ProcessHelper.h"
  209.52 +#include "assimp/types.h"
  209.53 +
  209.54 +struct aiMesh;
  209.55 +class OptimizeGraphProcessTest;
  209.56 +namespace Assimp	{
  209.57 +
  209.58 +// -----------------------------------------------------------------------------
  209.59 +/** @brief Postprocessing step to optimize the scenegraph
  209.60 + *
  209.61 + *  The implementation tries to merge nodes, even if they use different
  209.62 + *  transformations. Animations are preserved. 
  209.63 + *
  209.64 + *  @see aiProcess_OptimizeGraph for a detailed description of the
  209.65 + *  algorithm being applied.
  209.66 + */
  209.67 +class OptimizeGraphProcess : public BaseProcess
  209.68 +{
  209.69 +public:
  209.70 +
  209.71 +	OptimizeGraphProcess();
  209.72 +	~OptimizeGraphProcess();
  209.73 +
  209.74 +public:
  209.75 +	// -------------------------------------------------------------------
  209.76 +	bool IsActive( unsigned int pFlags) const;
  209.77 +
  209.78 +	// -------------------------------------------------------------------
  209.79 +	void Execute( aiScene* pScene);
  209.80 +	
  209.81 +	// -------------------------------------------------------------------
  209.82 +	void SetupProperties(const Importer* pImp);
  209.83 +
  209.84 +
  209.85 +	// -------------------------------------------------------------------
  209.86 +	/** @brief Add a list of node names to be locked and not modified.
  209.87 +	 *  @param in List of nodes. See #AI_CONFIG_PP_OG_EXCLUDE_LIST for
  209.88 +	 *    format explanations.
  209.89 +	 */
  209.90 +	inline void AddLockedNodeList(std::string& in)
  209.91 +	{
  209.92 +		ConvertListToStrings (in,locked_nodes);
  209.93 +	}
  209.94 +
  209.95 +	// -------------------------------------------------------------------
  209.96 +	/** @brief Add another node to be locked and not modified.
  209.97 +	 *  @param name Name to be locked
  209.98 +	 */
  209.99 +	inline void AddLockedNode(std::string& name)
 209.100 +	{
 209.101 +		locked_nodes.push_back(name);
 209.102 +	}
 209.103 +
 209.104 +	// -------------------------------------------------------------------
 209.105 +	/** @brief Rmeove a node from the list of locked nodes.
 209.106 +	 *  @param name Name to be unlocked
 209.107 +	 */
 209.108 +	inline void RemoveLockedNode(std::string& name)
 209.109 +	{
 209.110 +		locked_nodes.remove(name);
 209.111 +	}
 209.112 +
 209.113 +protected:
 209.114 +
 209.115 +	void CollectNewChildren(aiNode* nd, std::list<aiNode*>& nodes);
 209.116 +	void FindInstancedMeshes (aiNode* pNode);
 209.117 +
 209.118 +private:
 209.119 +
 209.120 +#ifdef AI_OG_USE_HASHING
 209.121 +	typedef std::set<unsigned int> LockedSetType;
 209.122 +#else
 209.123 +	typedef std::set<std::string> LockedSetType;
 209.124 +#endif
 209.125 +
 209.126 +
 209.127 +	//! Scene we're working with
 209.128 +	aiScene* mScene;
 209.129 +
 209.130 +	//! List of locked names. Stored is the hash of the name
 209.131 +	LockedSetType locked;
 209.132 +
 209.133 +	//! List of nodes to be locked in addition to those with animations, lights or cameras assigned.
 209.134 +	std::list<std::string> locked_nodes;
 209.135 +
 209.136 +	//! Node counters for logging purposes
 209.137 +	unsigned int nodes_in,nodes_out, count_merged;
 209.138 +
 209.139 +	//! Reference counters for meshes
 209.140 +	std::vector<unsigned int> meshes;
 209.141 +};
 209.142 +
 209.143 +} // end of namespace Assimp
 209.144 +
 209.145 +#endif // AI_OPTIMIZEGRAPHPROCESS_H_INC
   210.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   210.2 +++ b/libs/assimp/OptimizeMeshes.cpp	Sat Feb 01 19:58:19 2014 +0200
   210.3 @@ -0,0 +1,243 @@
   210.4 +/*
   210.5 +---------------------------------------------------------------------------
   210.6 +Open Asset Import Library (assimp)
   210.7 +---------------------------------------------------------------------------
   210.8 +
   210.9 +Copyright (c) 2006-2012, assimp team
  210.10 +
  210.11 +All rights reserved.
  210.12 +
  210.13 +Redistribution and use of this software in source and binary forms, 
  210.14 +with or without modification, are permitted provided that the following 
  210.15 +conditions are met:
  210.16 +
  210.17 +* Redistributions of source code must retain the above
  210.18 +  copyright notice, this list of conditions and the
  210.19 +  following disclaimer.
  210.20 +
  210.21 +* Redistributions in binary form must reproduce the above
  210.22 +  copyright notice, this list of conditions and the
  210.23 +  following disclaimer in the documentation and/or other
  210.24 +  materials provided with the distribution.
  210.25 +
  210.26 +* Neither the name of the assimp team, nor the names of its
  210.27 +  contributors may be used to endorse or promote products
  210.28 +  derived from this software without specific prior
  210.29 +  written permission of the assimp team.
  210.30 +
  210.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  210.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  210.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  210.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  210.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  210.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  210.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  210.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  210.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  210.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  210.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  210.42 +---------------------------------------------------------------------------
  210.43 +*/
  210.44 +
  210.45 +/** @file  OptimizeMeshes.cpp
  210.46 + *  @brief Implementation of the aiProcess_OptimizeMeshes step
  210.47 + */
  210.48 +
  210.49 +#include "AssimpPCH.h"
  210.50 +#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
  210.51 +
  210.52 +using namespace Assimp;
  210.53 +#include "OptimizeMeshes.h"
  210.54 +#include "ProcessHelper.h"
  210.55 +#include "SceneCombiner.h"
  210.56 +
  210.57 +// ------------------------------------------------------------------------------------------------
  210.58 +// Constructor to be privately used by Importer
  210.59 +OptimizeMeshesProcess::OptimizeMeshesProcess()
  210.60 +: pts (false)
  210.61 +, max_verts (0xffffffff)
  210.62 +, max_faces (0xffffffff)
  210.63 +{}
  210.64 +
  210.65 +// ------------------------------------------------------------------------------------------------
  210.66 +// Destructor, private as well
  210.67 +OptimizeMeshesProcess::~OptimizeMeshesProcess()
  210.68 +{}
  210.69 +
  210.70 +// ------------------------------------------------------------------------------------------------
  210.71 +// Returns whether the processing step is present in the given flag field.
  210.72 +bool OptimizeMeshesProcess::IsActive( unsigned int pFlags) const
  210.73 +{
  210.74 +	// Our behaviour needs to be different if the SortByPType or SplitLargeMeshes
  210.75 +	// steps are active. Thus we need to query their flags here and store the
  210.76 +	// information, although we're breaking const-correctness. 
  210.77 +	// That's a serious design flaw, consider redesign.
  210.78 +	if( 0 != (pFlags & aiProcess_OptimizeMeshes) ) {
  210.79 +		pts = (0 != (pFlags & aiProcess_SortByPType));
  210.80 +		max_verts = (0 != (pFlags & aiProcess_SplitLargeMeshes)) ? 0xdeadbeef : 0;
  210.81 +		return true;
  210.82 +	}
  210.83 +	return false;
  210.84 +}
  210.85 +
  210.86 +// ------------------------------------------------------------------------------------------------
  210.87 +// Setup properties for the postprocessing step
  210.88 +void OptimizeMeshesProcess::SetupProperties(const Importer* pImp)
  210.89 +{
  210.90 +	if (max_verts == 0xdeadbeef /* magic hack */) {
  210.91 +		max_faces = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
  210.92 +		max_verts = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
  210.93 +	}
  210.94 +}
  210.95 +
  210.96 +// ------------------------------------------------------------------------------------------------
  210.97 +// Execute step
  210.98 +void OptimizeMeshesProcess::Execute( aiScene* pScene)
  210.99 +{
 210.100 +	const unsigned int num_old = pScene->mNumMeshes;
 210.101 +	if (num_old <= 1) {
 210.102 +		DefaultLogger::get()->debug("Skipping OptimizeMeshesProcess");
 210.103 +		return;
 210.104 +	}
 210.105 +
 210.106 +	DefaultLogger::get()->debug("OptimizeMeshesProcess begin");
 210.107 +	mScene = pScene;
 210.108 +
 210.109 +	// need to clear persistent members from previous runs
 210.110 +	merge_list.clear();
 210.111 +	output.clear();
 210.112 +
 210.113 +	merge_list.reserve(pScene->mNumMeshes);
 210.114 +	output.reserve(pScene->mNumMeshes);
 210.115 +
 210.116 +	// Prepare lookup tables
 210.117 +	meshes.resize(pScene->mNumMeshes);
 210.118 +	FindInstancedMeshes(pScene->mRootNode);
 210.119 +	if (max_verts == 0xdeadbeef) /* undo the magic hack */
 210.120 +		max_verts = 0xffffffff;
 210.121 +
 210.122 +	// ... instanced meshes are immediately processed and added to the output list
 210.123 +	for (unsigned int i = 0, n = 0; i < pScene->mNumMeshes;++i) {
 210.124 +		meshes[i].vertex_format = GetMeshVFormatUnique(pScene->mMeshes[i]);
 210.125 +
 210.126 +		if (meshes[i].instance_cnt > 1 && meshes[i].output_id == 0xffffffff) {
 210.127 +			meshes[i].output_id = n++;
 210.128 +			output.push_back(mScene->mMeshes[i]);
 210.129 +		}
 210.130 +	}
 210.131 +
 210.132 +	// and process all nodes in the scenegraoh recursively
 210.133 +	ProcessNode(pScene->mRootNode);
 210.134 +	if (!output.size()) {
 210.135 +		throw DeadlyImportError("OptimizeMeshes: No meshes remaining; there's definitely something wrong");
 210.136 +	}
 210.137 +
 210.138 +	meshes.clear();
 210.139 +	ai_assert(output.size() <= num_old);
 210.140 +
 210.141 +	mScene->mNumMeshes = output.size();
 210.142 +	std::copy(output.begin(),output.end(),mScene->mMeshes);
 210.143 +
 210.144 +	if (output.size() != num_old) {
 210.145 +		char tmp[512];
 210.146 +		::sprintf(tmp,"OptimizeMeshesProcess finished. Input meshes: %i, Output meshes: %i",num_old,pScene->mNumMeshes);
 210.147 +		DefaultLogger::get()->info(tmp);
 210.148 +	}
 210.149 +	else DefaultLogger::get()->debug("OptimizeMeshesProcess finished");
 210.150 +}
 210.151 +
 210.152 +// ------------------------------------------------------------------------------------------------
 210.153 +// Process meshes for a single node
 210.154 +void OptimizeMeshesProcess::ProcessNode( aiNode* pNode)
 210.155 +{
 210.156 +	for (unsigned int i = 0; i < pNode->mNumMeshes;++i) {
 210.157 +		unsigned int& im = pNode->mMeshes[i];
 210.158 +
 210.159 +		if (meshes[im].instance_cnt > 1) {
 210.160 +			im = meshes[im].output_id;
 210.161 +		}
 210.162 +		else  {
 210.163 +			merge_list.clear();
 210.164 +			unsigned int verts = 0, faces = 0;
 210.165 +
 210.166 +			// Find meshes to merge with us
 210.167 +			for (unsigned int a = i+1; a < pNode->mNumMeshes;++a) {
 210.168 +				register unsigned int am = pNode->mMeshes[a];
 210.169 +				if (meshes[am].instance_cnt == 1 && CanJoin(im,am,verts,faces)) {
 210.170 +
 210.171 +					merge_list.push_back(mScene->mMeshes[am]);
 210.172 +					verts += mScene->mMeshes[am]->mNumVertices;
 210.173 +					faces += mScene->mMeshes[am]->mNumFaces;
 210.174 +
 210.175 +					--pNode->mNumMeshes;
 210.176 +					for (unsigned int n = a; n < pNode->mNumMeshes; ++n)
 210.177 +						pNode->mMeshes[n] = pNode->mMeshes[n+1];
 210.178 +
 210.179 +					--a;
 210.180 +				}
 210.181 +			}
 210.182 +
 210.183 +			// and merge all meshes which we found, replace the old ones
 210.184 +			if (!merge_list.empty()) {
 210.185 +				merge_list.push_back(mScene->mMeshes[im]);
 210.186 +
 210.187 +				aiMesh* out;
 210.188 +				SceneCombiner::MergeMeshes(&out,0,merge_list.begin(),merge_list.end());
 210.189 +				output.push_back(out);
 210.190 +			}
 210.191 +			else {
 210.192 +				output.push_back(mScene->mMeshes[im]);
 210.193 +			}
 210.194 +			im = output.size()-1;
 210.195 +		}
 210.196 +	}
 210.197 +
 210.198 +
 210.199 +	for (unsigned int i = 0; i < pNode->mNumChildren; ++i)
 210.200 +		ProcessNode(pNode->mChildren[i]);
 210.201 +}
 210.202 +
 210.203 +// ------------------------------------------------------------------------------------------------
 210.204 +// Check whether two meshes can be joined
 210.205 +bool OptimizeMeshesProcess::CanJoin ( unsigned int a, unsigned int b, unsigned int verts, unsigned int faces )
 210.206 +{
 210.207 +	if (meshes[a].vertex_format != meshes[b].vertex_format)
 210.208 +		return false;
 210.209 +
 210.210 +	aiMesh* ma = mScene->mMeshes[a], *mb = mScene->mMeshes[b];
 210.211 +
 210.212 +	if ((0xffffffff != max_verts && verts+mb->mNumVertices > max_verts) ||
 210.213 +		(0xffffffff != max_faces && faces+mb->mNumFaces    > max_faces)) {
 210.214 +		return false;
 210.215 +	}
 210.216 +
 210.217 +	// Never merge unskinned meshes with skinned meshes
 210.218 +	if (ma->mMaterialIndex != mb->mMaterialIndex || ma->HasBones() != mb->HasBones())
 210.219 +		return false;
 210.220 +
 210.221 +	// Never merge meshes with different kinds of primitives if SortByPType did already
 210.222 +	// do its work. We would destroy everything again ...
 210.223 +	if (pts && ma->mPrimitiveTypes != mb->mPrimitiveTypes)
 210.224 +		return false;
 210.225 +
 210.226 +	// If both meshes are skinned, check whether we have many bones defined in both meshes. 
 210.227 +	// If yes, we can savely join them. 
 210.228 +	if (ma->HasBones()) {
 210.229 +		// TODO
 210.230 +		return false;
 210.231 +	}
 210.232 +	return true;
 210.233 +}
 210.234 +
 210.235 +// ------------------------------------------------------------------------------------------------
 210.236 +// Buidl a LUT of all instanced meshes
 210.237 +void OptimizeMeshesProcess::FindInstancedMeshes (aiNode* pNode)
 210.238 +{
 210.239 +	for (unsigned int i = 0; i < pNode->mNumMeshes;++i)
 210.240 +		++meshes[pNode->mMeshes[i]].instance_cnt; 
 210.241 +
 210.242 +	for (unsigned int i = 0; i < pNode->mNumChildren; ++i)
 210.243 +		FindInstancedMeshes(pNode->mChildren[i]);
 210.244 +}
 210.245 +
 210.246 +#endif // !! ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
   211.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   211.2 +++ b/libs/assimp/OptimizeMeshes.h	Sat Feb 01 19:58:19 2014 +0200
   211.3 @@ -0,0 +1,182 @@
   211.4 +/*
   211.5 +Open Asset Import Library (assimp)
   211.6 +----------------------------------------------------------------------
   211.7 +
   211.8 +Copyright (c) 2006-2012, assimp team
   211.9 +All rights reserved.
  211.10 +
  211.11 +Redistribution and use of this software in source and binary forms, 
  211.12 +with or without modification, are permitted provided that the 
  211.13 +following conditions are met:
  211.14 +
  211.15 +* Redistributions of source code must retain the above
  211.16 +  copyright notice, this list of conditions and the
  211.17 +  following disclaimer.
  211.18 +
  211.19 +* Redistributions in binary form must reproduce the above
  211.20 +  copyright notice, this list of conditions and the
  211.21 +  following disclaimer in the documentation and/or other
  211.22 +  materials provided with the distribution.
  211.23 +
  211.24 +* Neither the name of the assimp team, nor the names of its
  211.25 +  contributors may be used to endorse or promote products
  211.26 +  derived from this software without specific prior
  211.27 +  written permission of the assimp team.
  211.28 +
  211.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  211.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  211.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  211.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  211.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  211.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  211.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  211.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  211.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  211.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  211.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  211.40 +
  211.41 +----------------------------------------------------------------------
  211.42 +*/
  211.43 +
  211.44 +/** @file  OptimizeMeshes.h
  211.45 + *  @brief Declares a post processing step to join meshes, if possible 
  211.46 + */
  211.47 +#ifndef AI_OPTIMIZEMESHESPROCESS_H_INC
  211.48 +#define AI_OPTIMIZEMESHESPROCESS_H_INC
  211.49 +
  211.50 +#include "BaseProcess.h"
  211.51 +#include "assimp/types.h"
  211.52 +
  211.53 +struct aiMesh;
  211.54 +class OptimizeMeshesProcessTest;
  211.55 +namespace Assimp	{
  211.56 +
  211.57 +// ---------------------------------------------------------------------------
  211.58 +/** @brief Postprocessing step to optimize mesh usage
  211.59 + *
  211.60 + *  The implementation looks for meshes that could be joined and joins them.
  211.61 + *  Usually this will reduce the number of drawcalls.
  211.62 + *
  211.63 + *  @note Instanced meshes are currently not processed.
  211.64 + */
  211.65 +class OptimizeMeshesProcess : public BaseProcess
  211.66 +{
  211.67 +public:
  211.68 +
  211.69 +	OptimizeMeshesProcess();
  211.70 +	~OptimizeMeshesProcess();
  211.71 +
  211.72 +
  211.73 +	/** @brief Internal utility to store additional mesh info
  211.74 +	 */
  211.75 +	struct MeshInfo
  211.76 +	{
  211.77 +		MeshInfo()
  211.78 +			:	instance_cnt  (0)
  211.79 +			,	vertex_format (0)
  211.80 +			,	output_id	  (0xffffffff)
  211.81 +		{}
  211.82 +
  211.83 +		//! Number of times this mesh is referenced
  211.84 +		unsigned int instance_cnt;
  211.85 +
  211.86 +		//! Vertex format id
  211.87 +		unsigned int vertex_format;
  211.88 +
  211.89 +		//! Output ID
  211.90 +		unsigned int output_id;
  211.91 +	};
  211.92 +
  211.93 +public:
  211.94 +	// -------------------------------------------------------------------
  211.95 +	bool IsActive( unsigned int pFlags) const;
  211.96 +
  211.97 +	// -------------------------------------------------------------------
  211.98 +	void Execute( aiScene* pScene);
  211.99 +	
 211.100 +	// -------------------------------------------------------------------
 211.101 +	void SetupProperties(const Importer* pImp);
 211.102 +
 211.103 +
 211.104 +	// -------------------------------------------------------------------
 211.105 +	/** @brief Specify whether you want meshes with different 
 211.106 +	 *   primitive types to be merged as well.
 211.107 +	 *
 211.108 +	 *  IsActive() sets this property automatically to true if the
 211.109 +	 *  aiProcess_SortByPType flag is found.
 211.110 +	 */
 211.111 +	void EnablePrimitiveTypeSorting(bool enable) {
 211.112 +		pts = enable;
 211.113 +	}
 211.114 +
 211.115 +	// Getter 
 211.116 +	bool IsPrimitiveTypeSortingEnabled () const {
 211.117 +		return pts;
 211.118 +	}
 211.119 +
 211.120 +
 211.121 +	// -------------------------------------------------------------------
 211.122 +	/** @brief Specify a maximum size of a single output mesh.
 211.123 +	 *  
 211.124 +	 *  If a single input mesh already exceeds this limit, it won't
 211.125 +	 *  be split.
 211.126 +	 *  @param verts Maximum number of vertices per mesh
 211.127 +	 *  @param faces Maximum number of faces per mesh
 211.128 +	 */
 211.129 +	void SetPreferredMeshSizeLimit (unsigned int verts, unsigned int faces)
 211.130 +	{
 211.131 +		max_verts = verts;
 211.132 +		max_faces = faces;
 211.133 +	}
 211.134 +
 211.135 +
 211.136 +protected:
 211.137 +
 211.138 +	// -------------------------------------------------------------------
 211.139 +	/** @brief Do the actual optimization on all meshes of this node
 211.140 +	 *  @param pNode Node we're working with
 211.141 +	 */
 211.142 +	void ProcessNode( aiNode* pNode);
 211.143 +
 211.144 +	// -------------------------------------------------------------------
 211.145 +	/** @brief Returns true if b can be joined with a
 211.146 +	 *
 211.147 +	 *  @param verts Number of output verts up to now
 211.148 +	 *  @param faces Number of output faces up to now
 211.149 +	 */
 211.150 +	bool CanJoin ( unsigned int a, unsigned int b,
 211.151 +		unsigned int verts, unsigned int faces );
 211.152 +
 211.153 +	// -------------------------------------------------------------------
 211.154 +	/** @brief Find instanced meshes, for the moment we're excluding
 211.155 +	 *   them from all optimizations
 211.156 +	 */
 211.157 +	void FindInstancedMeshes (aiNode* pNode);
 211.158 +
 211.159 +private:
 211.160 +
 211.161 +	//! Scene we're working with
 211.162 +	aiScene* mScene;
 211.163 +
 211.164 +	//! Per mesh info
 211.165 +	std::vector<MeshInfo> meshes;
 211.166 +
 211.167 +	//! Next output mesh
 211.168 +	aiMesh* mesh;
 211.169 +
 211.170 +	//! Output meshes
 211.171 +	std::vector<aiMesh*> output;
 211.172 +
 211.173 +	//! @see EnablePrimitiveTypeSorting
 211.174 +	mutable bool pts;
 211.175 +
 211.176 +	//! @see SetPreferredMeshSizeLimit
 211.177 +	mutable unsigned int max_verts,max_faces;
 211.178 +
 211.179 +	//! Temporary storage
 211.180 +	std::vector<aiMesh*> merge_list;
 211.181 +};
 211.182 +
 211.183 +} // end of namespace Assimp
 211.184 +
 211.185 +#endif // AI_CALCTANGENTSPROCESS_H_INC
   212.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   212.2 +++ b/libs/assimp/ParsingUtils.h	Sat Feb 01 19:58:19 2014 +0200
   212.3 @@ -0,0 +1,210 @@
   212.4 +/*
   212.5 +Open Asset Import Library (assimp)
   212.6 +----------------------------------------------------------------------
   212.7 +
   212.8 +Copyright (c) 2006-2012, assimp team
   212.9 +All rights reserved.
  212.10 +
  212.11 +Redistribution and use of this software in source and binary forms, 
  212.12 +with or without modification, are permitted provided that the 
  212.13 +following conditions are met:
  212.14 +
  212.15 +* Redistributions of source code must retain the above
  212.16 +  copyright notice, this list of conditions and the
  212.17 +  following disclaimer.
  212.18 +
  212.19 +* Redistributions in binary form must reproduce the above
  212.20 +  copyright notice, this list of conditions and the
  212.21 +  following disclaimer in the documentation and/or other
  212.22 +  materials provided with the distribution.
  212.23 +
  212.24 +* Neither the name of the assimp team, nor the names of its
  212.25 +  contributors may be used to endorse or promote products
  212.26 +  derived from this software without specific prior
  212.27 +  written permission of the assimp team.
  212.28 +
  212.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  212.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  212.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  212.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  212.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  212.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  212.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  212.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  212.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  212.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  212.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  212.40 +
  212.41 +----------------------------------------------------------------------
  212.42 +*/
  212.43 +
  212.44 +
  212.45 +/** @file ParsingUtils.h
  212.46 + *  @brief Defines helper functions for text parsing 
  212.47 + */
  212.48 +#ifndef AI_PARSING_UTILS_H_INC
  212.49 +#define AI_PARSING_UTILS_H_INC
  212.50 +
  212.51 +#include "StringComparison.h"
  212.52 +namespace Assimp {
  212.53 +
  212.54 +	// NOTE: the functions below are mostly intended as replacement for
  212.55 +	// std::upper, std::lower, std::isupper, std::islower, std::isspace.
  212.56 +	// we don't bother of locales. We don't want them. We want reliable
  212.57 +	// (i.e. identical) results across all locales.
  212.58 +
  212.59 +	// The functions below accept any character type, but know only
  212.60 +	// about ASCII. However, UTF-32 is the only safe ASCII superset to
  212.61 +	// use since it doesn't have multibyte sequences.
  212.62 +
  212.63 +// ---------------------------------------------------------------------------------
  212.64 +template <class char_t>
  212.65 +AI_FORCE_INLINE char_t ToLower( char_t in)
  212.66 +{
  212.67 +	return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in;
  212.68 +}
  212.69 +// ---------------------------------------------------------------------------------
  212.70 +template <class char_t>
  212.71 +AI_FORCE_INLINE char_t ToUpper( char_t in)
  212.72 +{
  212.73 +	return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in;
  212.74 +}
  212.75 +// ---------------------------------------------------------------------------------
  212.76 +template <class char_t>
  212.77 +AI_FORCE_INLINE bool IsUpper( char_t in)
  212.78 +{
  212.79 +	return (in >= (char_t)'A' && in <= (char_t)'Z');
  212.80 +}
  212.81 +// ---------------------------------------------------------------------------------
  212.82 +template <class char_t>
  212.83 +AI_FORCE_INLINE bool IsLower( char_t in)
  212.84 +{
  212.85 +	return (in >= (char_t)'a' && in <= (char_t)'z');
  212.86 +}
  212.87 +// ---------------------------------------------------------------------------------
  212.88 +template <class char_t>
  212.89 +AI_FORCE_INLINE bool IsSpace( char_t in)
  212.90 +{
  212.91 +	return (in == (char_t)' ' || in == (char_t)'\t');
  212.92 +}
  212.93 +// ---------------------------------------------------------------------------------
  212.94 +template <class char_t>
  212.95 +AI_FORCE_INLINE bool IsLineEnd( char_t in)
  212.96 +{
  212.97 +	return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0');
  212.98 +}
  212.99 +// ---------------------------------------------------------------------------------
 212.100 +template <class char_t>
 212.101 +AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in)
 212.102 +{
 212.103 +	return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
 212.104 +}
 212.105 +// ---------------------------------------------------------------------------------
 212.106 +template <class char_t>
 212.107 +AI_FORCE_INLINE bool SkipSpaces( const char_t* in, const char_t** out)
 212.108 +{
 212.109 +	while (*in == (char_t)' ' || *in == (char_t)'\t')in++;
 212.110 +	*out = in;
 212.111 +	return !IsLineEnd<char_t>(*in);
 212.112 +}
 212.113 +// ---------------------------------------------------------------------------------
 212.114 +template <class char_t>
 212.115 +AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
 212.116 +{
 212.117 +	return SkipSpaces<char_t>(*inout,inout);
 212.118 +}
 212.119 +// ---------------------------------------------------------------------------------
 212.120 +template <class char_t>
 212.121 +inline bool SkipLine( const char_t* in, const char_t** out)
 212.122 +{
 212.123 +	while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0')in++;
 212.124 +
 212.125 +	// files are opened in binary mode. Ergo there are both NL and CR
 212.126 +	while (*in == (char_t)'\r' || *in == (char_t)'\n')in++;
 212.127 +	*out = in;
 212.128 +	return *in != (char_t)'\0';
 212.129 +}
 212.130 +// ---------------------------------------------------------------------------------
 212.131 +template <class char_t>
 212.132 +inline bool SkipLine( const char_t** inout)
 212.133 +{
 212.134 +	return SkipLine<char_t>(*inout,inout);
 212.135 +}
 212.136 +// ---------------------------------------------------------------------------------
 212.137 +template <class char_t>
 212.138 +inline bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out)
 212.139 +{
 212.140 +	while (*in == (char_t)' ' || *in == (char_t)'\t' ||
 212.141 +		*in == (char_t)'\r' || *in == (char_t)'\n')in++;
 212.142 +	*out = in;
 212.143 +	return *in != '\0';
 212.144 +}
 212.145 +// ---------------------------------------------------------------------------------
 212.146 +template <class char_t>
 212.147 +inline bool SkipSpacesAndLineEnd( const char_t** inout)
 212.148 +{
 212.149 +	return SkipSpacesAndLineEnd<char_t>(*inout,inout);
 212.150 +}
 212.151 +// ---------------------------------------------------------------------------------
 212.152 +template <class char_t>
 212.153 +inline bool GetNextLine(const char_t*& buffer, char_t out[4096])
 212.154 +{
 212.155 +	if ((char_t)'\0' == *buffer)return false;
 212.156 +
 212.157 +	char* _out = out;
 212.158 +	char* const end = _out+4096;
 212.159 +	while (!IsLineEnd( *buffer ) && _out < end)
 212.160 +		*_out++ = *buffer++;
 212.161 +	*_out = (char_t)'\0';
 212.162 +
 212.163 +	while (IsLineEnd( *buffer ) && '\0' != *buffer)++buffer;
 212.164 +	return true;
 212.165 +}
 212.166 +// ---------------------------------------------------------------------------------
 212.167 +template <class char_t>
 212.168 +AI_FORCE_INLINE bool IsNumeric( char_t in)
 212.169 +{
 212.170 +	return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
 212.171 +}
 212.172 +// ---------------------------------------------------------------------------------
 212.173 +template <class char_t>
 212.174 +AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len)
 212.175 +{
 212.176 +	if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len]))
 212.177 +	{
 212.178 +		in += len+1;
 212.179 +		return true;
 212.180 +	}
 212.181 +	return false;
 212.182 +}
 212.183 +// ---------------------------------------------------------------------------------
 212.184 +/** @brief Case-ignoring version of TokenMatch
 212.185 + *  @param in Input
 212.186 + *  @param token Token to check for
 212.187 + *  @param len Number of characters to check
 212.188 + */
 212.189 +AI_FORCE_INLINE bool TokenMatchI(const char*& in, const char* token, unsigned int len)
 212.190 +{
 212.191 +	if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len]))
 212.192 +	{
 212.193 +		in += len+1;
 212.194 +		return true;
 212.195 +	}
 212.196 +	return false;
 212.197 +}
 212.198 +// ---------------------------------------------------------------------------------
 212.199 +AI_FORCE_INLINE void SkipToken(const char*& in)
 212.200 +{
 212.201 +	SkipSpaces(&in);
 212.202 +	while (!IsSpaceOrNewLine(*in))++in;
 212.203 +}
 212.204 +// ---------------------------------------------------------------------------------
 212.205 +AI_FORCE_INLINE std::string GetNextToken(const char*& in)
 212.206 +{
 212.207 +	SkipSpacesAndLineEnd(&in);
 212.208 +	const char* cur = in;
 212.209 +	while (!IsSpaceOrNewLine(*in))++in;
 212.210 +	return std::string(cur,(size_t)(in-cur));
 212.211 +}
 212.212 +} // ! namespace Assimp
 212.213 +#endif // ! AI_PARSING_UTILS_H_INC
   213.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   213.2 +++ b/libs/assimp/PlyExporter.cpp	Sat Feb 01 19:58:19 2014 +0200
   213.3 @@ -0,0 +1,251 @@
   213.4 +/*
   213.5 +Open Asset Import Library (assimp)
   213.6 +----------------------------------------------------------------------
   213.7 +
   213.8 +Copyright (c) 2006-2012, assimp team
   213.9 +All rights reserved.
  213.10 +
  213.11 +Redistribution and use of this software in source and binary forms, 
  213.12 +with or without modification, are permitted provided that the 
  213.13 +following conditions are met:
  213.14 +
  213.15 +* Redistributions of source code must retain the above
  213.16 +  copyright notice, this list of conditions and the
  213.17 +  following disclaimer.
  213.18 +
  213.19 +* Redistributions in binary form must reproduce the above
  213.20 +  copyright notice, this list of conditions and the
  213.21 +  following disclaimer in the documentation and/or other
  213.22 +  materials provided with the distribution.
  213.23 +
  213.24 +* Neither the name of the assimp team, nor the names of its
  213.25 +  contributors may be used to endorse or promote products
  213.26 +  derived from this software without specific prior
  213.27 +  written permission of the assimp team.
  213.28 +
  213.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  213.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  213.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  213.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  213.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  213.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  213.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  213.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  213.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  213.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  213.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  213.40 +
  213.41 +----------------------------------------------------------------------
  213.42 +*/
  213.43 +
  213.44 +#include "AssimpPCH.h"
  213.45 +
  213.46 +#if !defined(ASSIMP_BUILD_NO_EXPORT) && !defined(ASSIMP_BUILD_NO_PLY_EXPORTER)
  213.47 +
  213.48 +#include "PlyExporter.h"
  213.49 +#include "assimp/version.h"
  213.50 +
  213.51 +using namespace Assimp;
  213.52 +namespace Assimp	{
  213.53 +
  213.54 +// ------------------------------------------------------------------------------------------------
  213.55 +// Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp
  213.56 +void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
  213.57 +{
  213.58 +	// invoke the exporter 
  213.59 +	PlyExporter exporter(pFile, pScene);
  213.60 +
  213.61 +	// we're still here - export successfully completed. Write the file.
  213.62 +	boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
  213.63 +	if(outfile == NULL) {
  213.64 +		throw DeadlyExportError("could not open output .ply file: " + std::string(pFile));
  213.65 +	}
  213.66 +
  213.67 +	outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
  213.68 +}
  213.69 +
  213.70 +} // end of namespace Assimp
  213.71 +
  213.72 +#define PLY_EXPORT_HAS_NORMALS 0x1
  213.73 +#define PLY_EXPORT_HAS_TANGENTS_BITANGENTS 0x2
  213.74 +#define PLY_EXPORT_HAS_TEXCOORDS 0x4
  213.75 +#define PLY_EXPORT_HAS_COLORS (PLY_EXPORT_HAS_TEXCOORDS << AI_MAX_NUMBER_OF_TEXTURECOORDS)
  213.76 +
  213.77 +// ------------------------------------------------------------------------------------------------
  213.78 +PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene)
  213.79 +: filename(_filename)
  213.80 +, pScene(pScene)
  213.81 +, endl("\n") 
  213.82 +{
  213.83 +	// make sure that all formatting happens using the standard, C locale and not the user's current locale
  213.84 +	const std::locale& l = std::locale("C");
  213.85 +	mOutput.imbue(l);
  213.86 +
  213.87 +	unsigned int faces = 0u, vertices = 0u, components = 0u;
  213.88 +	for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
  213.89 +		const aiMesh& m = *pScene->mMeshes[i];
  213.90 +		faces += m.mNumFaces;
  213.91 +		vertices += m.mNumVertices;
  213.92 +
  213.93 +		if (m.HasNormals()) {
  213.94 +			components |= PLY_EXPORT_HAS_NORMALS;
  213.95 +		}
  213.96 +		if (m.HasTangentsAndBitangents()) {
  213.97 +			components |= PLY_EXPORT_HAS_TANGENTS_BITANGENTS;
  213.98 +		}
  213.99 +		for (unsigned int t = 0; m.HasTextureCoords(t); ++t) {
 213.100 +			components |= PLY_EXPORT_HAS_TEXCOORDS << t;
 213.101 +		}
 213.102 +		for (unsigned int t = 0; m.HasVertexColors(t); ++t) {
 213.103 +			components |= PLY_EXPORT_HAS_COLORS << t;
 213.104 +		}
 213.105 +	}
 213.106 +
 213.107 +	mOutput << "ply" << endl;
 213.108 +	mOutput << "format ascii 1.0" << endl;
 213.109 +	mOutput << "Created by Open Asset Import Library - http://assimp.sf.net (v"
 213.110 +		<< aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.' 
 213.111 +		<< aiGetVersionRevision() << ")" << endl;
 213.112 +
 213.113 +	mOutput << "element vertex " << vertices << endl;
 213.114 +	mOutput << "property float x" << endl;
 213.115 +	mOutput << "property float y" << endl;
 213.116 +	mOutput << "property float z" << endl;
 213.117 +
 213.118 +	if(components & PLY_EXPORT_HAS_NORMALS) {
 213.119 +		mOutput << "property float nx" << endl;
 213.120 +		mOutput << "property float ny" << endl;
 213.121 +		mOutput << "property float nz" << endl;
 213.122 +	}
 213.123 +
 213.124 +	// write texcoords first, just in case an importer does not support tangents
 213.125 +	// bitangents and just skips over the rest of the line upon encountering
 213.126 +	// unknown fields (Ply leaves pretty much every vertex component open,
 213.127 +	// but in reality most importers only know about vertex positions, normals
 213.128 +	// and texture coordinates).
 213.129 +	for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) {
 213.130 +		if (!c) {
 213.131 +			mOutput << "property float s" << endl;
 213.132 +			mOutput << "property float t" << endl;
 213.133 +		}
 213.134 +		else {
 213.135 +			mOutput << "property float s" << c << endl;
 213.136 +			mOutput << "property float t" << c << endl;
 213.137 +		}
 213.138 +	}
 213.139 +
 213.140 +	for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) {
 213.141 +		if (!c) {
 213.142 +			mOutput << "property float r" << endl;
 213.143 +			mOutput << "property float g" << endl;
 213.144 +			mOutput << "property float b" << endl;
 213.145 +			mOutput << "property float a" << endl;
 213.146 +		}
 213.147 +		else {
 213.148 +			mOutput << "property float r" << c << endl;
 213.149 +			mOutput << "property float g" << c << endl;
 213.150 +			mOutput << "property float b" << c << endl;
 213.151 +			mOutput << "property float a" << c << endl;
 213.152 +		}
 213.153 +	}
 213.154 +
 213.155 +	if(components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) {
 213.156 +		mOutput << "property float tx" << endl;
 213.157 +		mOutput << "property float ty" << endl;
 213.158 +		mOutput << "property float tz" << endl;
 213.159 +		mOutput << "property float bx" << endl;
 213.160 +		mOutput << "property float by" << endl;
 213.161 +		mOutput << "property float bz" << endl;
 213.162 +	}
 213.163 +
 213.164 +	mOutput << "element face " << faces << endl;
 213.165 +	mOutput << "property list uint uint vertex_indices" << endl;
 213.166 +	mOutput << "end_header" << endl;
 213.167 +
 213.168 +	for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
 213.169 +		WriteMeshVerts(pScene->mMeshes[i],components);
 213.170 +	}
 213.171 +	for (unsigned int i = 0, ofs = 0; i < pScene->mNumMeshes; ++i) {
 213.172 +		WriteMeshIndices(pScene->mMeshes[i],ofs);
 213.173 +		ofs += pScene->mMeshes[i]->mNumVertices;
 213.174 +	}
 213.175 +}
 213.176 +
 213.177 +// ------------------------------------------------------------------------------------------------
 213.178 +void PlyExporter :: WriteMeshVerts(const aiMesh* m, unsigned int components)
 213.179 +{
 213.180 +	for (unsigned int i = 0; i < m->mNumVertices; ++i) {
 213.181 +		mOutput << 
 213.182 +			m->mVertices[i].x << " " << 
 213.183 +			m->mVertices[i].y << " " << 
 213.184 +			m->mVertices[i].z
 213.185 +		;
 213.186 +		if(components & PLY_EXPORT_HAS_NORMALS) {
 213.187 +			if (m->HasNormals()) {
 213.188 +				mOutput << 
 213.189 +				" " << m->mNormals[i].x << 
 213.190 +				" " << m->mNormals[i].y << 
 213.191 +				" " << m->mNormals[i].z;
 213.192 +			}
 213.193 +			else {
 213.194 +				mOutput << " 0.0 0.0 0.0"; 
 213.195 +			}
 213.196 +		}
 213.197 +
 213.198 +		for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) {
 213.199 +			if (m->HasTextureCoords(c)) {
 213.200 +				mOutput << 
 213.201 +					" " << m->mTextureCoords[c][i].x << 
 213.202 +					" " << m->mTextureCoords[c][i].y;
 213.203 +			}
 213.204 +			else {
 213.205 +				mOutput << " -1.0 -1.0"; 
 213.206 +			}
 213.207 +		}
 213.208 +
 213.209 +		for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) {
 213.210 +			if (m->HasVertexColors(c)) {
 213.211 +				mOutput << 
 213.212 +					" " << m->mColors[c][i].r << 
 213.213 +					" " << m->mColors[c][i].g <<
 213.214 +					" " << m->mColors[c][i].b <<
 213.215 +					" " << m->mColors[c][i].a;
 213.216 +			}
 213.217 +			else {
 213.218 +				mOutput << " -1.0 -1.0 -1.0 -1.0"; 
 213.219 +			}
 213.220 +		}
 213.221 +
 213.222 +		if(components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) {
 213.223 +			if (m->HasTangentsAndBitangents()) {
 213.224 +				mOutput << 
 213.225 +				" " << m->mTangents[i].x << 
 213.226 +				" " << m->mTangents[i].y << 
 213.227 +				" " << m->mTangents[i].z << 
 213.228 +				" " << m->mBitangents[i].x << 
 213.229 +				" " << m->mBitangents[i].y << 
 213.230 +				" " << m->mBitangents[i].z
 213.231 +				;
 213.232 +			}
 213.233 +			else {
 213.234 +				mOutput << " 0.0 0.0 0.0 0.0 0.0 0.0"; 
 213.235 +			}
 213.236 +		}
 213.237 +
 213.238 +		mOutput << endl;
 213.239 +	}
 213.240 +}
 213.241 +
 213.242 +// ------------------------------------------------------------------------------------------------
 213.243 +void PlyExporter :: WriteMeshIndices(const aiMesh* m, unsigned int offset)
 213.244 +{
 213.245 +	for (unsigned int i = 0; i < m->mNumFaces; ++i) {
 213.246 +		const aiFace& f = m->mFaces[i];
 213.247 +		mOutput << f.mNumIndices << " ";
 213.248 +		for(unsigned int c = 0; c < f.mNumIndices; ++c) {
 213.249 +			mOutput << (f.mIndices[c] + offset) << (c == f.mNumIndices-1 ? endl : " ");
 213.250 +		}
 213.251 +	}
 213.252 +}
 213.253 +
 213.254 +#endif
   214.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   214.2 +++ b/libs/assimp/PlyExporter.h	Sat Feb 01 19:58:19 2014 +0200
   214.3 @@ -0,0 +1,85 @@
   214.4 +/*
   214.5 +Open Asset Import Library (assimp)
   214.6 +----------------------------------------------------------------------
   214.7 +
   214.8 +Copyright (c) 2006-2012, assimp team
   214.9 +All rights reserved.
  214.10 +
  214.11 +Redistribution and use of this software in source and binary forms, 
  214.12 +with or without modification, are permitted provided that the 
  214.13 +following conditions are met:
  214.14 +
  214.15 +* Redistributions of source code must retain the above
  214.16 +  copyright notice, this list of conditions and the
  214.17 +  following disclaimer.
  214.18 +
  214.19 +* Redistributions in binary form must reproduce the above
  214.20 +  copyright notice, this list of conditions and the
  214.21 +  following disclaimer in the documentation and/or other
  214.22 +  materials provided with the distribution.
  214.23 +
  214.24 +* Neither the name of the assimp team, nor the names of its
  214.25 +  contributors may be used to endorse or promote products
  214.26 +  derived from this software without specific prior
  214.27 +  written permission of the assimp team.
  214.28 +
  214.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  214.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  214.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  214.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  214.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  214.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  214.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  214.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  214.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  214.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  214.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  214.40 +
  214.41 +----------------------------------------------------------------------
  214.42 +*/
  214.43 +
  214.44 +/** @file PlyExporter.h
  214.45 + * Declares the exporter class to write a scene to a Polygon Library (ply)
  214.46 + */
  214.47 +#ifndef AI_PLYEXPORTER_H_INC
  214.48 +#define AI_PLYEXPORTER_H_INC
  214.49 +
  214.50 +#include <sstream>
  214.51 +
  214.52 +struct aiScene;
  214.53 +struct aiNode;
  214.54 +
  214.55 +namespace Assimp	
  214.56 +{
  214.57 +
  214.58 +// ------------------------------------------------------------------------------------------------
  214.59 +/** Helper class to export a given scene to a Stanford Ply file. */
  214.60 +// ------------------------------------------------------------------------------------------------
  214.61 +class PlyExporter
  214.62 +{
  214.63 +public:
  214.64 +	/// Constructor for a specific scene to export
  214.65 +	PlyExporter(const char* filename, const aiScene* pScene);
  214.66 +
  214.67 +public:
  214.68 +
  214.69 +	/// public stringstreams to write all output into
  214.70 +	std::ostringstream mOutput;
  214.71 +
  214.72 +private:
  214.73 +
  214.74 +	void WriteMeshVerts(const aiMesh* m, unsigned int components);
  214.75 +	void WriteMeshIndices(const aiMesh* m, unsigned int ofs);
  214.76 +
  214.77 +private:
  214.78 +
  214.79 +	const std::string filename;
  214.80 +	const aiScene* const pScene;
  214.81 +
  214.82 +	// obviously, this endl() doesn't flush() the stream 
  214.83 +	const std::string endl;
  214.84 +};
  214.85 +
  214.86 +}
  214.87 +
  214.88 +#endif
   215.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   215.2 +++ b/libs/assimp/PlyLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   215.3 @@ -0,0 +1,1062 @@
   215.4 +/*
   215.5 +---------------------------------------------------------------------------
   215.6 +Open Asset Import Library (assimp)
   215.7 +---------------------------------------------------------------------------
   215.8 +
   215.9 +Copyright (c) 2006-2012, assimp team
  215.10 +
  215.11 +All rights reserved.
  215.12 +
  215.13 +Redistribution and use of this software in source and binary forms, 
  215.14 +with or without modification, are permitted provided that the following 
  215.15 +conditions are met:
  215.16 +
  215.17 +* Redistributions of source code must retain the above
  215.18 +  copyright notice, this list of conditions and the
  215.19 +  following disclaimer.
  215.20 +
  215.21 +* Redistributions in binary form must reproduce the above
  215.22 +  copyright notice, this list of conditions and the
  215.23 +  following disclaimer in the documentation and/or other
  215.24 +  materials provided with the distribution.
  215.25 +
  215.26 +* Neither the name of the assimp team, nor the names of its
  215.27 +  contributors may be used to endorse or promote products
  215.28 +  derived from this software without specific prior
  215.29 +  written permission of the assimp team.
  215.30 +
  215.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  215.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  215.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  215.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  215.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  215.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  215.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  215.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  215.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  215.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  215.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  215.42 +---------------------------------------------------------------------------
  215.43 +*/
  215.44 +
  215.45 +/** @file  PlyLoader.cpp
  215.46 + *  @brief Implementation of the PLY importer class
  215.47 + */
  215.48 +
  215.49 +#include "AssimpPCH.h"
  215.50 +#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
  215.51 +
  215.52 +// internal headers
  215.53 +#include "PlyLoader.h"
  215.54 +
  215.55 +using namespace Assimp;
  215.56 +
  215.57 +static const aiImporterDesc desc = {
  215.58 +	"Stanford Polygon Library (PLY) Importer",
  215.59 +	"",
  215.60 +	"",
  215.61 +	"",
  215.62 +	aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportTextFlavour,
  215.63 +	0,
  215.64 +	0,
  215.65 +	0,
  215.66 +	0,
  215.67 +	"ply" 
  215.68 +};
  215.69 +
  215.70 +// ------------------------------------------------------------------------------------------------
  215.71 +// Constructor to be privately used by Importer
  215.72 +PLYImporter::PLYImporter()
  215.73 +{}
  215.74 +
  215.75 +// ------------------------------------------------------------------------------------------------
  215.76 +// Destructor, private as well 
  215.77 +PLYImporter::~PLYImporter()
  215.78 +{}
  215.79 +
  215.80 +// ------------------------------------------------------------------------------------------------
  215.81 +// Returns whether the class can handle the format of the given file. 
  215.82 +bool PLYImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  215.83 +{
  215.84 +	const std::string extension = GetExtension(pFile);
  215.85 +
  215.86 +	if (extension == "ply")
  215.87 +		return true;
  215.88 +	else if (!extension.length() || checkSig)
  215.89 +	{
  215.90 +		if (!pIOHandler)return true;
  215.91 +		const char* tokens[] = {"ply"};
  215.92 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
  215.93 +	}
  215.94 +	return false;
  215.95 +}
  215.96 +
  215.97 +// ------------------------------------------------------------------------------------------------
  215.98 +const aiImporterDesc* PLYImporter::GetInfo () const
  215.99 +{
 215.100 +	return &desc;
 215.101 +}
 215.102 +
 215.103 +// ------------------------------------------------------------------------------------------------
 215.104 +// Imports the given file into the given scene structure. 
 215.105 +void PLYImporter::InternReadFile( const std::string& pFile, 
 215.106 +	aiScene* pScene, IOSystem* pIOHandler)
 215.107 +{
 215.108 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
 215.109 +
 215.110 +	// Check whether we can read from the file
 215.111 +	if( file.get() == NULL) {
 215.112 +		throw DeadlyImportError( "Failed to open PLY file " + pFile + ".");
 215.113 +	}
 215.114 +
 215.115 +	// allocate storage and copy the contents of the file to a memory buffer
 215.116 +	std::vector<char> mBuffer2;
 215.117 +	TextFileToBuffer(file.get(),mBuffer2);
 215.118 +	mBuffer = (unsigned char*)&mBuffer2[0];
 215.119 +
 215.120 +	// the beginning of the file must be PLY - magic, magic
 215.121 +	if ((mBuffer[0] != 'P' && mBuffer[0] != 'p') ||
 215.122 +		(mBuffer[1] != 'L' && mBuffer[1] != 'l') ||
 215.123 +		(mBuffer[2] != 'Y' && mBuffer[2] != 'y'))	{
 215.124 +		throw DeadlyImportError( "Invalid .ply file: Magic number \'ply\' is no there");
 215.125 +	}
 215.126 +
 215.127 +	char* szMe = (char*)&this->mBuffer[3];
 215.128 +	SkipSpacesAndLineEnd(szMe,(const char**)&szMe);
 215.129 +	
 215.130 +	// determine the format of the file data
 215.131 +	PLY::DOM sPlyDom;
 215.132 +	if (TokenMatch(szMe,"format",6))
 215.133 +	{
 215.134 +		if (TokenMatch(szMe,"ascii",5))
 215.135 +		{
 215.136 +			SkipLine(szMe,(const char**)&szMe);
 215.137 +			if(!PLY::DOM::ParseInstance(szMe,&sPlyDom))
 215.138 +				throw DeadlyImportError( "Invalid .ply file: Unable to build DOM (#1)");
 215.139 +		}
 215.140 +		else if (!::strncmp(szMe,"binary_",7))
 215.141 +		{
 215.142 +			bool bIsBE = false;
 215.143 +			szMe+=7;
 215.144 +
 215.145 +			// binary_little_endian
 215.146 +			// binary_big_endian
 215.147 +#if (defined AI_BUILD_BIG_ENDIAN)
 215.148 +			if ('l' == *szMe || 'L' == *szMe)bIsBE = true;
 215.149 +#else
 215.150 +			if ('b' == *szMe || 'B' == *szMe)bIsBE = true;
 215.151 +#endif // ! AI_BUILD_BIG_ENDIAN
 215.152 +
 215.153 +			// skip the line, parse the rest of the header and build the DOM
 215.154 +			SkipLine(szMe,(const char**)&szMe);
 215.155 +			if(!PLY::DOM::ParseInstanceBinary(szMe,&sPlyDom,bIsBE))
 215.156 +				throw DeadlyImportError( "Invalid .ply file: Unable to build DOM (#2)");
 215.157 +		}
 215.158 +		else throw DeadlyImportError( "Invalid .ply file: Unknown file format");
 215.159 +	}
 215.160 +	else
 215.161 +	{
 215.162 +		delete[] this->mBuffer;
 215.163 +		AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
 215.164 +		throw DeadlyImportError( "Invalid .ply file: Missing format specification");
 215.165 +	}
 215.166 +	this->pcDOM = &sPlyDom;
 215.167 +
 215.168 +	// now load a list of vertices. This must be sucessfull in order to procede
 215.169 +	std::vector<aiVector3D> avPositions;
 215.170 +	this->LoadVertices(&avPositions,false);
 215.171 +
 215.172 +	if (avPositions.empty())
 215.173 +		throw DeadlyImportError( "Invalid .ply file: No vertices found. "
 215.174 +			"Unable to parse the data format of the PLY file.");
 215.175 +
 215.176 +	// now load a list of normals. 
 215.177 +	std::vector<aiVector3D> avNormals;
 215.178 +	LoadVertices(&avNormals,true);
 215.179 +
 215.180 +	// load the face list
 215.181 +	std::vector<PLY::Face> avFaces;
 215.182 +	LoadFaces(&avFaces);
 215.183 +
 215.184 +	// if no face list is existing we assume that the vertex
 215.185 +	// list is containing a list of triangles
 215.186 +	if (avFaces.empty())
 215.187 +	{
 215.188 +		if (avPositions.size() < 3)
 215.189 +		{
 215.190 +			throw DeadlyImportError( "Invalid .ply file: Not enough "
 215.191 +				"vertices to build a proper face list. ");
 215.192 +		}
 215.193 +
 215.194 +		const unsigned int iNum = (unsigned int)avPositions.size() / 3;
 215.195 +		for (unsigned int i = 0; i< iNum;++i)
 215.196 +		{
 215.197 +			PLY::Face sFace;
 215.198 +			sFace.mIndices.push_back((iNum*3));
 215.199 +			sFace.mIndices.push_back((iNum*3)+1);
 215.200 +			sFace.mIndices.push_back((iNum*3)+2);
 215.201 +			avFaces.push_back(sFace);
 215.202 +		}
 215.203 +	}
 215.204 +
 215.205 +	// now load a list of all materials
 215.206 +	std::vector<aiMaterial*> avMaterials;
 215.207 +	LoadMaterial(&avMaterials);
 215.208 +
 215.209 +	// now load a list of all vertex color channels
 215.210 +	std::vector<aiColor4D> avColors;
 215.211 +	avColors.reserve(avPositions.size());
 215.212 +	LoadVertexColor(&avColors);
 215.213 +
 215.214 +	// now try to load texture coordinates
 215.215 +	std::vector<aiVector2D> avTexCoords;
 215.216 +	avTexCoords.reserve(avPositions.size());
 215.217 +	LoadTextureCoordinates(&avTexCoords);
 215.218 +
 215.219 +	// now replace the default material in all faces and validate all material indices
 215.220 +	ReplaceDefaultMaterial(&avFaces,&avMaterials);
 215.221 +
 215.222 +	// now convert this to a list of aiMesh instances
 215.223 +	std::vector<aiMesh*> avMeshes;
 215.224 +	avMeshes.reserve(avMaterials.size()+1);
 215.225 +	ConvertMeshes(&avFaces,&avPositions,&avNormals,
 215.226 +		&avColors,&avTexCoords,&avMaterials,&avMeshes);
 215.227 +
 215.228 +	if (avMeshes.empty())
 215.229 +		throw DeadlyImportError( "Invalid .ply file: Unable to extract mesh data ");
 215.230 +
 215.231 +	// now generate the output scene object. Fill the material list
 215.232 +	pScene->mNumMaterials = (unsigned int)avMaterials.size();
 215.233 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
 215.234 +	for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
 215.235 +		pScene->mMaterials[i] = avMaterials[i];
 215.236 +
 215.237 +	// fill the mesh list
 215.238 +	pScene->mNumMeshes = (unsigned int)avMeshes.size();
 215.239 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
 215.240 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
 215.241 +		pScene->mMeshes[i] = avMeshes[i];
 215.242 +
 215.243 +	// generate a simple node structure
 215.244 +	pScene->mRootNode = new aiNode();
 215.245 +	pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
 215.246 +	pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
 215.247 +
 215.248 +	for (unsigned int i = 0; i < pScene->mRootNode->mNumMeshes;++i)
 215.249 +		pScene->mRootNode->mMeshes[i] = i;
 215.250 +}
 215.251 +
 215.252 +// ------------------------------------------------------------------------------------------------
 215.253 +// Split meshes by material IDs
 215.254 +void PLYImporter::ConvertMeshes(std::vector<PLY::Face>* avFaces,
 215.255 +	const std::vector<aiVector3D>*			avPositions,
 215.256 +	const std::vector<aiVector3D>*			avNormals,
 215.257 +	const std::vector<aiColor4D>*			avColors,
 215.258 +	const std::vector<aiVector2D>*			avTexCoords,
 215.259 +	const std::vector<aiMaterial*>*		avMaterials,
 215.260 +	std::vector<aiMesh*>* avOut)
 215.261 +{
 215.262 +	ai_assert(NULL != avFaces);
 215.263 +	ai_assert(NULL != avPositions);
 215.264 +	ai_assert(NULL != avMaterials);
 215.265 +
 215.266 +	// split by materials
 215.267 +	std::vector<unsigned int>* aiSplit = new std::vector<unsigned int>[avMaterials->size()];
 215.268 +
 215.269 +	unsigned int iNum = 0;
 215.270 +	for (std::vector<PLY::Face>::const_iterator i = avFaces->begin();i != avFaces->end();++i,++iNum)
 215.271 +		aiSplit[(*i).iMaterialIndex].push_back(iNum);
 215.272 +	
 215.273 +	// now generate submeshes
 215.274 +	for (unsigned int p = 0; p < avMaterials->size();++p)
 215.275 +	{
 215.276 +		if (aiSplit[p].size() != 0)
 215.277 +		{
 215.278 +			// allocate the mesh object
 215.279 +			aiMesh* p_pcOut = new aiMesh();
 215.280 +			p_pcOut->mMaterialIndex = p;
 215.281 +
 215.282 +			p_pcOut->mNumFaces = (unsigned int)aiSplit[p].size();
 215.283 +			p_pcOut->mFaces = new aiFace[aiSplit[p].size()];
 215.284 +
 215.285 +			// at first we need to determine the size of the output vector array
 215.286 +			unsigned int iNum = 0;
 215.287 +			for (unsigned int i = 0; i < aiSplit[p].size();++i)
 215.288 +			{
 215.289 +				iNum += (unsigned int)(*avFaces)[aiSplit[p][i]].mIndices.size();
 215.290 +			}
 215.291 +			p_pcOut->mNumVertices = iNum;
 215.292 +			p_pcOut->mVertices = new aiVector3D[iNum];
 215.293 +
 215.294 +			if (!avColors->empty())
 215.295 +				p_pcOut->mColors[0] = new aiColor4D[iNum];
 215.296 +			if (!avTexCoords->empty())
 215.297 +			{
 215.298 +				p_pcOut->mNumUVComponents[0] = 2;
 215.299 +				p_pcOut->mTextureCoords[0] = new aiVector3D[iNum];
 215.300 +			}
 215.301 +			if (!avNormals->empty())
 215.302 +				p_pcOut->mNormals = new aiVector3D[iNum];
 215.303 +
 215.304 +			// add all faces
 215.305 +			iNum = 0;
 215.306 +			unsigned int iVertex = 0;
 215.307 +			for (std::vector<unsigned int>::const_iterator i =  aiSplit[p].begin();
 215.308 +				i != aiSplit[p].end();++i,++iNum)
 215.309 +			{
 215.310 +				p_pcOut->mFaces[iNum].mNumIndices = (unsigned int)(*avFaces)[*i].mIndices.size(); 
 215.311 +				p_pcOut->mFaces[iNum].mIndices = new unsigned int[p_pcOut->mFaces[iNum].mNumIndices];
 215.312 +
 215.313 +				// build an unique set of vertices/colors for this face
 215.314 +				for (unsigned int q = 0; q <  p_pcOut->mFaces[iNum].mNumIndices;++q)
 215.315 +				{
 215.316 +					p_pcOut->mFaces[iNum].mIndices[q] = iVertex;
 215.317 +					p_pcOut->mVertices[iVertex] = (*avPositions)[(*avFaces)[*i].mIndices[q]];
 215.318 +
 215.319 +					if (!avColors->empty())
 215.320 +						p_pcOut->mColors[0][iVertex] = (*avColors)[(*avFaces)[*i].mIndices[q]];
 215.321 +
 215.322 +					if (!avTexCoords->empty())
 215.323 +					{
 215.324 +						const aiVector2D& vec = (*avTexCoords)[(*avFaces)[*i].mIndices[q]];
 215.325 +						p_pcOut->mTextureCoords[0][iVertex].x = vec.x;
 215.326 +						p_pcOut->mTextureCoords[0][iVertex].y = vec.y;
 215.327 +					}
 215.328 +
 215.329 +					if (!avNormals->empty())
 215.330 +						p_pcOut->mNormals[iVertex] = (*avNormals)[(*avFaces)[*i].mIndices[q]];
 215.331 +					iVertex++;
 215.332 +				}
 215.333 +
 215.334 +			}
 215.335 +			// add the mesh to the output list
 215.336 +			avOut->push_back(p_pcOut);
 215.337 +		}
 215.338 +	}
 215.339 +	delete[] aiSplit; // cleanup
 215.340 +}
 215.341 +
 215.342 +// ------------------------------------------------------------------------------------------------
 215.343 +// Generate a default material if none was specified and apply it to all vanilla faces
 215.344 +void PLYImporter::ReplaceDefaultMaterial(std::vector<PLY::Face>* avFaces,
 215.345 +	std::vector<aiMaterial*>* avMaterials)
 215.346 +{
 215.347 +	bool bNeedDefaultMat = false;
 215.348 +
 215.349 +	for (std::vector<PLY::Face>::iterator i =  avFaces->begin();i != avFaces->end();++i)	{
 215.350 +		if (0xFFFFFFFF == (*i).iMaterialIndex)	{
 215.351 +			bNeedDefaultMat = true;
 215.352 +			(*i).iMaterialIndex = (unsigned int)avMaterials->size();
 215.353 +		}
 215.354 +		else if ((*i).iMaterialIndex >= avMaterials->size() )	{
 215.355 +			// clamp the index
 215.356 +			(*i).iMaterialIndex = (unsigned int)avMaterials->size()-1;
 215.357 +		}
 215.358 +	}
 215.359 +
 215.360 +	if (bNeedDefaultMat)	{
 215.361 +		// generate a default material
 215.362 +		aiMaterial* pcHelper = new aiMaterial();
 215.363 +
 215.364 +		// fill in a default material
 215.365 +		int iMode = (int)aiShadingMode_Gouraud;
 215.366 +		pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
 215.367 +
 215.368 +		aiColor3D clr;
 215.369 +		clr.b = clr.g = clr.r = 0.6f;
 215.370 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
 215.371 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
 215.372 +
 215.373 +		clr.b = clr.g = clr.r = 0.05f;
 215.374 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
 215.375 +
 215.376 +		// The face order is absolutely undefined for PLY, so we have to
 215.377 +		// use two-sided rendering to be sure it's ok.
 215.378 +		const int two_sided = 1;
 215.379 +		pcHelper->AddProperty(&two_sided,1,AI_MATKEY_TWOSIDED);
 215.380 +
 215.381 +		avMaterials->push_back(pcHelper);
 215.382 +	}
 215.383 +}
 215.384 +
 215.385 +// ------------------------------------------------------------------------------------------------
 215.386 +void PLYImporter::LoadTextureCoordinates(std::vector<aiVector2D>* pvOut)
 215.387 +{
 215.388 +	ai_assert(NULL != pvOut);
 215.389 +
 215.390 +	unsigned int aiPositions[2] = {0xFFFFFFFF,0xFFFFFFFF};
 215.391 +	PLY::EDataType aiTypes[2] = {EDT_Char,EDT_Char};
 215.392 +	PLY::ElementInstanceList* pcList = NULL;
 215.393 +	unsigned int cnt = 0;
 215.394 +
 215.395 +	// serach in the DOM for a vertex entry
 215.396 +	unsigned int _i = 0;
 215.397 +	for (std::vector<PLY::Element>::const_iterator i = pcDOM->alElements.begin();
 215.398 +		i != pcDOM->alElements.end();++i,++_i)
 215.399 +	{
 215.400 +		if (PLY::EEST_Vertex == (*i).eSemantic)
 215.401 +		{
 215.402 +			pcList = &this->pcDOM->alElementData[_i];
 215.403 +
 215.404 +			// now check whether which normal components are available
 215.405 +			unsigned int _a = 0;
 215.406 +			for (std::vector<PLY::Property>::const_iterator a =  (*i).alProperties.begin();
 215.407 +				a != (*i).alProperties.end();++a,++_a)
 215.408 +			{
 215.409 +				if ((*a).bIsList)continue;
 215.410 +				if (PLY::EST_UTextureCoord == (*a).Semantic)
 215.411 +				{
 215.412 +					cnt++;
 215.413 +					aiPositions[0] = _a;
 215.414 +					aiTypes[0] = (*a).eType;
 215.415 +				}
 215.416 +				else if (PLY::EST_VTextureCoord == (*a).Semantic)
 215.417 +				{
 215.418 +					cnt++;
 215.419 +					aiPositions[1] = _a;
 215.420 +					aiTypes[1] = (*a).eType;
 215.421 +				}
 215.422 +			}
 215.423 +		}
 215.424 +	}
 215.425 +	// check whether we have a valid source for the texture coordinates data
 215.426 +	if (NULL != pcList && 0 != cnt)
 215.427 +	{
 215.428 +		pvOut->reserve(pcList->alInstances.size());
 215.429 +		for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();
 215.430 +			i != pcList->alInstances.end();++i)
 215.431 +		{
 215.432 +			// convert the vertices to sp floats
 215.433 +			aiVector2D vOut;
 215.434 +
 215.435 +			if (0xFFFFFFFF != aiPositions[0])
 215.436 +			{
 215.437 +				vOut.x = PLY::PropertyInstance::ConvertTo<float>(
 215.438 +					(*i).alProperties[aiPositions[0]].avList.front(),aiTypes[0]);
 215.439 +			}
 215.440 +
 215.441 +			if (0xFFFFFFFF != aiPositions[1])
 215.442 +			{
 215.443 +				vOut.y = PLY::PropertyInstance::ConvertTo<float>(
 215.444 +					(*i).alProperties[aiPositions[1]].avList.front(),aiTypes[1]);
 215.445 +			}
 215.446 +			// and add them to our nice list
 215.447 +			pvOut->push_back(vOut);
 215.448 +		}
 215.449 +	}
 215.450 +}
 215.451 +
 215.452 +// ------------------------------------------------------------------------------------------------
 215.453 +// Try to extract vertices from the PLY DOM
 215.454 +void PLYImporter::LoadVertices(std::vector<aiVector3D>* pvOut, bool p_bNormals)
 215.455 +{
 215.456 +	ai_assert(NULL != pvOut);
 215.457 +
 215.458 +	unsigned int aiPositions[3] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
 215.459 +	PLY::EDataType aiTypes[3] = {EDT_Char,EDT_Char,EDT_Char};
 215.460 +	PLY::ElementInstanceList* pcList = NULL;
 215.461 +	unsigned int cnt = 0;
 215.462 +
 215.463 +	// serach in the DOM for a vertex entry
 215.464 +	unsigned int _i = 0;
 215.465 +	for (std::vector<PLY::Element>::const_iterator i =  pcDOM->alElements.begin();
 215.466 +		i != pcDOM->alElements.end();++i,++_i)
 215.467 +	{
 215.468 +		if (PLY::EEST_Vertex == (*i).eSemantic)
 215.469 +		{
 215.470 +			pcList = &pcDOM->alElementData[_i];
 215.471 +
 215.472 +			// load normal vectors?
 215.473 +			if (p_bNormals)
 215.474 +			{
 215.475 +				// now check whether which normal components are available
 215.476 +				unsigned int _a = 0;
 215.477 +				for (std::vector<PLY::Property>::const_iterator a = (*i).alProperties.begin();
 215.478 +					a != (*i).alProperties.end();++a,++_a)
 215.479 +				{
 215.480 +					if ((*a).bIsList)continue;
 215.481 +					if (PLY::EST_XNormal == (*a).Semantic)
 215.482 +					{
 215.483 +						cnt++;
 215.484 +						aiPositions[0] = _a;
 215.485 +						aiTypes[0] = (*a).eType;
 215.486 +					}
 215.487 +					else if (PLY::EST_YNormal == (*a).Semantic)
 215.488 +					{
 215.489 +						cnt++;
 215.490 +						aiPositions[1] = _a;
 215.491 +						aiTypes[1] = (*a).eType;
 215.492 +					}
 215.493 +					else if (PLY::EST_ZNormal == (*a).Semantic)
 215.494 +					{
 215.495 +						cnt++;
 215.496 +						aiPositions[2] = _a;
 215.497 +						aiTypes[2] = (*a).eType;
 215.498 +					}
 215.499 +				}
 215.500 +			}
 215.501 +			// load vertex coordinates
 215.502 +			else
 215.503 +			{
 215.504 +				// now check whether which coordinate sets are available
 215.505 +				unsigned int _a = 0;
 215.506 +				for (std::vector<PLY::Property>::const_iterator a = (*i).alProperties.begin();
 215.507 +					a != (*i).alProperties.end();++a,++_a)
 215.508 +				{
 215.509 +					if ((*a).bIsList)continue;
 215.510 +					if (PLY::EST_XCoord == (*a).Semantic)
 215.511 +					{
 215.512 +						cnt++;
 215.513 +						aiPositions[0] = _a;
 215.514 +						aiTypes[0] = (*a).eType;
 215.515 +					}
 215.516 +					else if (PLY::EST_YCoord == (*a).Semantic)
 215.517 +					{
 215.518 +						cnt++;
 215.519 +						aiPositions[1] = _a;
 215.520 +						aiTypes[1] = (*a).eType;
 215.521 +					}
 215.522 +					else if (PLY::EST_ZCoord == (*a).Semantic)
 215.523 +					{
 215.524 +						cnt++;
 215.525 +						aiPositions[2] = _a;
 215.526 +						aiTypes[2] = (*a).eType;
 215.527 +					}
 215.528 +					if (3 == cnt)break; 
 215.529 +				}
 215.530 +			}
 215.531 +			break;
 215.532 +		}
 215.533 +	}
 215.534 +	// check whether we have a valid source for the vertex data
 215.535 +	if (NULL != pcList && 0 != cnt)
 215.536 +	{
 215.537 +		pvOut->reserve(pcList->alInstances.size());
 215.538 +		for (std::vector<ElementInstance>::const_iterator
 215.539 +			i =  pcList->alInstances.begin();
 215.540 +			i != pcList->alInstances.end();++i)
 215.541 +		{
 215.542 +			// convert the vertices to sp floats
 215.543 +			aiVector3D vOut;
 215.544 +
 215.545 +			if (0xFFFFFFFF != aiPositions[0])
 215.546 +			{
 215.547 +				vOut.x = PLY::PropertyInstance::ConvertTo<float>(
 215.548 +					(*i).alProperties[aiPositions[0]].avList.front(),aiTypes[0]);
 215.549 +			}
 215.550 +
 215.551 +			if (0xFFFFFFFF != aiPositions[1])
 215.552 +			{
 215.553 +				vOut.y = PLY::PropertyInstance::ConvertTo<float>(
 215.554 +					(*i).alProperties[aiPositions[1]].avList.front(),aiTypes[1]);
 215.555 +			}
 215.556 +
 215.557 +			if (0xFFFFFFFF != aiPositions[2])
 215.558 +			{
 215.559 +				vOut.z = PLY::PropertyInstance::ConvertTo<float>(
 215.560 +					(*i).alProperties[aiPositions[2]].avList.front(),aiTypes[2]);
 215.561 +			}
 215.562 +
 215.563 +			// and add them to our nice list
 215.564 +			pvOut->push_back(vOut);
 215.565 +		}
 215.566 +	}
 215.567 +}
 215.568 +
 215.569 +// ------------------------------------------------------------------------------------------------
 215.570 +// Convert a color component to [0...1]
 215.571 +float PLYImporter::NormalizeColorValue (PLY::PropertyInstance::ValueUnion val,
 215.572 +	PLY::EDataType eType)
 215.573 +{
 215.574 +	switch (eType)
 215.575 +	{
 215.576 +	case EDT_Float:
 215.577 +		return val.fFloat;
 215.578 +	case EDT_Double:
 215.579 +		return (float)val.fDouble;
 215.580 +
 215.581 +	case EDT_UChar:
 215.582 +		return (float)val.iUInt / (float)0xFF;
 215.583 +	case EDT_Char:
 215.584 +		return (float)(val.iInt+(0xFF/2)) / (float)0xFF;
 215.585 +	case EDT_UShort:
 215.586 +		return (float)val.iUInt / (float)0xFFFF;
 215.587 +	case EDT_Short:
 215.588 +		return (float)(val.iInt+(0xFFFF/2)) / (float)0xFFFF;
 215.589 +	case EDT_UInt:
 215.590 +		return (float)val.iUInt / (float)0xFFFF;
 215.591 +	case EDT_Int:
 215.592 +		return ((float)val.iInt / (float)0xFF) + 0.5f;
 215.593 +	default: ;
 215.594 +	};
 215.595 +	return 0.0f;
 215.596 +}
 215.597 +
 215.598 +// ------------------------------------------------------------------------------------------------
 215.599 +// Try to extract proper vertex colors from the PLY DOM
 215.600 +void PLYImporter::LoadVertexColor(std::vector<aiColor4D>* pvOut)
 215.601 +{
 215.602 +	ai_assert(NULL != pvOut);
 215.603 +
 215.604 +	unsigned int aiPositions[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
 215.605 +	PLY::EDataType aiTypes[4] = {EDT_Char, EDT_Char, EDT_Char, EDT_Char}; // silencing gcc
 215.606 +	unsigned int cnt = 0;
 215.607 +	PLY::ElementInstanceList* pcList = NULL;
 215.608 +
 215.609 +	// serach in the DOM for a vertex entry
 215.610 +	unsigned int _i = 0;
 215.611 +	for (std::vector<PLY::Element>::const_iterator i = pcDOM->alElements.begin();
 215.612 +		i != pcDOM->alElements.end();++i,++_i)
 215.613 +	{
 215.614 +		if (PLY::EEST_Vertex == (*i).eSemantic)
 215.615 +		{
 215.616 +			pcList = &this->pcDOM->alElementData[_i];
 215.617 +
 215.618 +			// now check whether which coordinate sets are available
 215.619 +			unsigned int _a = 0;
 215.620 +			for (std::vector<PLY::Property>::const_iterator
 215.621 +				a =  (*i).alProperties.begin();
 215.622 +				a != (*i).alProperties.end();++a,++_a)
 215.623 +			{
 215.624 +				if ((*a).bIsList)continue;
 215.625 +				if (PLY::EST_Red == (*a).Semantic)
 215.626 +				{
 215.627 +					cnt++;
 215.628 +					aiPositions[0] = _a;
 215.629 +					aiTypes[0] = (*a).eType;
 215.630 +				}
 215.631 +				else if (PLY::EST_Green == (*a).Semantic)
 215.632 +				{
 215.633 +					cnt++;
 215.634 +					aiPositions[1] = _a;
 215.635 +					aiTypes[1] = (*a).eType;
 215.636 +				}
 215.637 +				else if (PLY::EST_Blue == (*a).Semantic)
 215.638 +				{
 215.639 +					cnt++;
 215.640 +					aiPositions[2] = _a;
 215.641 +					aiTypes[2] = (*a).eType;
 215.642 +				}
 215.643 +				else if (PLY::EST_Alpha == (*a).Semantic)
 215.644 +				{
 215.645 +					cnt++;
 215.646 +					aiPositions[3] = _a;
 215.647 +					aiTypes[3] = (*a).eType;
 215.648 +				}
 215.649 +				if (4 == cnt)break; 
 215.650 +			}
 215.651 +			break;
 215.652 +		}
 215.653 +	}
 215.654 +	// check whether we have a valid source for the vertex data
 215.655 +	if (NULL != pcList && 0 != cnt)
 215.656 +	{
 215.657 +		pvOut->reserve(pcList->alInstances.size());
 215.658 +		for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();
 215.659 +			i != pcList->alInstances.end();++i)
 215.660 +		{
 215.661 +			// convert the vertices to sp floats
 215.662 +			aiColor4D vOut;
 215.663 +			
 215.664 +			if (0xFFFFFFFF != aiPositions[0])
 215.665 +			{
 215.666 +				vOut.r = NormalizeColorValue((*i).alProperties[
 215.667 +					aiPositions[0]].avList.front(),aiTypes[0]);
 215.668 +			}
 215.669 +
 215.670 +			if (0xFFFFFFFF != aiPositions[1])
 215.671 +			{
 215.672 +				vOut.g = NormalizeColorValue((*i).alProperties[
 215.673 +					aiPositions[1]].avList.front(),aiTypes[1]);
 215.674 +			}
 215.675 +
 215.676 +			if (0xFFFFFFFF != aiPositions[2])
 215.677 +			{
 215.678 +				vOut.b = NormalizeColorValue((*i).alProperties[
 215.679 +					aiPositions[2]].avList.front(),aiTypes[2]);
 215.680 +			}
 215.681 +
 215.682 +			// assume 1.0 for the alpha channel ifit is not set
 215.683 +			if (0xFFFFFFFF == aiPositions[3])vOut.a = 1.0f;
 215.684 +			else
 215.685 +			{
 215.686 +				vOut.a = NormalizeColorValue((*i).alProperties[
 215.687 +					aiPositions[3]].avList.front(),aiTypes[3]);
 215.688 +			}
 215.689 +
 215.690 +			// and add them to our nice list
 215.691 +			pvOut->push_back(vOut);
 215.692 +		}
 215.693 +	}
 215.694 +}
 215.695 +
 215.696 +// ------------------------------------------------------------------------------------------------
 215.697 +// Try to extract proper faces from the PLY DOM
 215.698 +void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
 215.699 +{
 215.700 +	ai_assert(NULL != pvOut);
 215.701 +
 215.702 +	PLY::ElementInstanceList* pcList = NULL;
 215.703 +	bool bOne = false;
 215.704 +
 215.705 +	// index of the vertex index list
 215.706 +	unsigned int iProperty = 0xFFFFFFFF;
 215.707 +	PLY::EDataType eType = EDT_Char;
 215.708 +	bool bIsTristrip = false;
 215.709 +
 215.710 +	// index of the material index property
 215.711 +	unsigned int iMaterialIndex = 0xFFFFFFFF;
 215.712 +	PLY::EDataType eType2 = EDT_Char;
 215.713 +
 215.714 +	// serach in the DOM for a face entry
 215.715 +	unsigned int _i = 0;
 215.716 +	for (std::vector<PLY::Element>::const_iterator i =  pcDOM->alElements.begin();
 215.717 +		i != pcDOM->alElements.end();++i,++_i)
 215.718 +	{
 215.719 +		// face = unique number of vertex indices
 215.720 +		if (PLY::EEST_Face == (*i).eSemantic)
 215.721 +		{
 215.722 +			pcList = &pcDOM->alElementData[_i];
 215.723 +			unsigned int _a = 0;
 215.724 +			for (std::vector<PLY::Property>::const_iterator a =  (*i).alProperties.begin();
 215.725 +				a != (*i).alProperties.end();++a,++_a)
 215.726 +			{
 215.727 +				if (PLY::EST_VertexIndex == (*a).Semantic)
 215.728 +				{
 215.729 +					// must be a dynamic list!
 215.730 +					if (!(*a).bIsList)continue;
 215.731 +					iProperty	= _a;
 215.732 +					bOne		= true;
 215.733 +					eType		= (*a).eType;		
 215.734 +				}
 215.735 +				else if (PLY::EST_MaterialIndex == (*a).Semantic)
 215.736 +				{
 215.737 +					if ((*a).bIsList)continue;
 215.738 +					iMaterialIndex	= _a;
 215.739 +					bOne			= true;
 215.740 +					eType2		= (*a).eType;		
 215.741 +				}
 215.742 +			}
 215.743 +			break;
 215.744 +		}
 215.745 +		// triangle strip
 215.746 +		// TODO: triangle strip and material index support???
 215.747 +		else if (PLY::EEST_TriStrip == (*i).eSemantic)
 215.748 +		{
 215.749 +			// find a list property in this ...
 215.750 +			pcList = &this->pcDOM->alElementData[_i];
 215.751 +			unsigned int _a = 0;
 215.752 +			for (std::vector<PLY::Property>::const_iterator a =  (*i).alProperties.begin();
 215.753 +				a != (*i).alProperties.end();++a,++_a)
 215.754 +			{
 215.755 +				// must be a dynamic list!
 215.756 +				if (!(*a).bIsList)continue;
 215.757 +				iProperty	= _a;
 215.758 +				bOne		= true;
 215.759 +				bIsTristrip	= true;
 215.760 +				eType		= (*a).eType;	
 215.761 +				break;
 215.762 +			}
 215.763 +			break;
 215.764 +		}
 215.765 +	}
 215.766 +	// check whether we have at least one per-face information set
 215.767 +	if (pcList && bOne)
 215.768 +	{
 215.769 +		if (!bIsTristrip)
 215.770 +		{
 215.771 +			pvOut->reserve(pcList->alInstances.size());
 215.772 +			for (std::vector<ElementInstance>::const_iterator i =  pcList->alInstances.begin();
 215.773 +				i != pcList->alInstances.end();++i)
 215.774 +			{
 215.775 +				PLY::Face sFace;
 215.776 +
 215.777 +				// parse the list of vertex indices
 215.778 +				if (0xFFFFFFFF != iProperty)
 215.779 +				{
 215.780 +					const unsigned int iNum = (unsigned int)(*i).alProperties[iProperty].avList.size();
 215.781 +					sFace.mIndices.resize(iNum);
 215.782 +
 215.783 +					std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p = 
 215.784 +						(*i).alProperties[iProperty].avList.begin();
 215.785 +
 215.786 +					for (unsigned int a = 0; a < iNum;++a,++p)
 215.787 +					{
 215.788 +						sFace.mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p,eType);
 215.789 +					}
 215.790 +				}
 215.791 +
 215.792 +				// parse the material index
 215.793 +				if (0xFFFFFFFF != iMaterialIndex)
 215.794 +				{
 215.795 +					sFace.iMaterialIndex = PLY::PropertyInstance::ConvertTo<unsigned int>(
 215.796 +						(*i).alProperties[iMaterialIndex].avList.front(),eType2);
 215.797 +				}
 215.798 +				pvOut->push_back(sFace);
 215.799 +			}
 215.800 +		}
 215.801 +		else // triangle strips
 215.802 +		{
 215.803 +			// normally we have only one triangle strip instance where
 215.804 +			// a value of -1 indicates a restart of the strip
 215.805 +			bool flip = false;
 215.806 +			for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
 215.807 +				const std::vector<PLY::PropertyInstance::ValueUnion>& quak = (*i).alProperties[iProperty].avList;
 215.808 +				pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u));
 215.809 +
 215.810 +				int aiTable[2] = {-1,-1};
 215.811 +				for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a =  quak.begin();a != quak.end();++a)	{
 215.812 +					const int p = PLY::PropertyInstance::ConvertTo<int>(*a,eType);
 215.813 +
 215.814 +					if (-1 == p)	{
 215.815 +						// restart the strip ...
 215.816 +						aiTable[0] = aiTable[1] = -1;
 215.817 +						flip = false;
 215.818 +						continue;
 215.819 +					}
 215.820 +					if (-1 == aiTable[0]) {
 215.821 +						aiTable[0] = p;
 215.822 +						continue;
 215.823 +					}
 215.824 +					if (-1 == aiTable[1]) {
 215.825 +						aiTable[1] = p;
 215.826 +						continue;
 215.827 +					}
 215.828 +				
 215.829 +					pvOut->push_back(PLY::Face());
 215.830 +					PLY::Face& sFace = pvOut->back();
 215.831 +					sFace.mIndices[0] = aiTable[0];
 215.832 +					sFace.mIndices[1] = aiTable[1];
 215.833 +					sFace.mIndices[2] = p;
 215.834 +					if ((flip = !flip)) {
 215.835 +						std::swap(sFace.mIndices[0],sFace.mIndices[1]);
 215.836 +					}
 215.837 +					
 215.838 +					aiTable[0] = aiTable[1];
 215.839 +					aiTable[1] = p;
 215.840 +				}
 215.841 +			}
 215.842 +		}
 215.843 +	}
 215.844 +}
 215.845 +
 215.846 +// ------------------------------------------------------------------------------------------------
 215.847 +// Get a RGBA color in [0...1] range
 215.848 +void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance>& avList,
 215.849 +	unsigned int aiPositions[4], 
 215.850 +	PLY::EDataType aiTypes[4],
 215.851 +	 aiColor4D* clrOut)
 215.852 +{
 215.853 +	ai_assert(NULL != clrOut);
 215.854 +
 215.855 +	if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
 215.856 +	else
 215.857 +	{
 215.858 +		clrOut->r = NormalizeColorValue(avList[
 215.859 +			aiPositions[0]].avList.front(),aiTypes[0]);
 215.860 +	}
 215.861 +
 215.862 +	if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
 215.863 +	else
 215.864 +	{
 215.865 +		clrOut->g = NormalizeColorValue(avList[
 215.866 +			aiPositions[1]].avList.front(),aiTypes[1]);
 215.867 +	}
 215.868 +
 215.869 +	if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
 215.870 +	else
 215.871 +	{
 215.872 +		clrOut->b = NormalizeColorValue(avList[
 215.873 +			aiPositions[2]].avList.front(),aiTypes[2]);
 215.874 +	}
 215.875 +
 215.876 +	// assume 1.0 for the alpha channel ifit is not set
 215.877 +	if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
 215.878 +	else
 215.879 +	{
 215.880 +		clrOut->a = NormalizeColorValue(avList[
 215.881 +			aiPositions[3]].avList.front(),aiTypes[3]);
 215.882 +	}
 215.883 +}
 215.884 +
 215.885 +// ------------------------------------------------------------------------------------------------
 215.886 +// Extract a material from the PLY DOM
 215.887 +void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut)
 215.888 +{
 215.889 +	ai_assert(NULL != pvOut);
 215.890 +
 215.891 +	// diffuse[4], specular[4], ambient[4]
 215.892 +	// rgba order
 215.893 +	unsigned int aaiPositions[3][4] = {
 215.894 +
 215.895 +		{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
 215.896 +		{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
 215.897 +		{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
 215.898 +	};
 215.899 +
 215.900 +	PLY::EDataType aaiTypes[3][4] = {
 215.901 +		{EDT_Char,EDT_Char,EDT_Char,EDT_Char},
 215.902 +		{EDT_Char,EDT_Char,EDT_Char,EDT_Char},
 215.903 +		{EDT_Char,EDT_Char,EDT_Char,EDT_Char}
 215.904 +	};
 215.905 +	PLY::ElementInstanceList* pcList = NULL;
 215.906 +
 215.907 +	unsigned int iPhong = 0xFFFFFFFF;
 215.908 +	PLY::EDataType ePhong = EDT_Char;
 215.909 +
 215.910 +	unsigned int iOpacity = 0xFFFFFFFF;
 215.911 +	PLY::EDataType eOpacity = EDT_Char;
 215.912 +
 215.913 +	// serach in the DOM for a vertex entry
 215.914 +	unsigned int _i = 0;
 215.915 +	for (std::vector<PLY::Element>::const_iterator i =  this->pcDOM->alElements.begin();
 215.916 +		i != this->pcDOM->alElements.end();++i,++_i)
 215.917 +	{
 215.918 +		if (PLY::EEST_Material == (*i).eSemantic)
 215.919 +		{
 215.920 +			pcList = &this->pcDOM->alElementData[_i];
 215.921 +
 215.922 +			// now check whether which coordinate sets are available
 215.923 +			unsigned int _a = 0;
 215.924 +			for (std::vector<PLY::Property>::const_iterator
 215.925 +				a =  (*i).alProperties.begin();
 215.926 +				a != (*i).alProperties.end();++a,++_a)
 215.927 +			{
 215.928 +				if ((*a).bIsList)continue;
 215.929 +
 215.930 +				// pohng specularity      -----------------------------------
 215.931 +				if (PLY::EST_PhongPower == (*a).Semantic)
 215.932 +				{
 215.933 +					iPhong		= _a;
 215.934 +					ePhong		= (*a).eType;
 215.935 +				}
 215.936 +
 215.937 +				// general opacity        -----------------------------------
 215.938 +				if (PLY::EST_Opacity == (*a).Semantic)
 215.939 +				{
 215.940 +					iOpacity		= _a;
 215.941 +					eOpacity		= (*a).eType;
 215.942 +				}
 215.943 +
 215.944 +				// diffuse color channels -----------------------------------
 215.945 +				if (PLY::EST_DiffuseRed == (*a).Semantic)
 215.946 +				{
 215.947 +					aaiPositions[0][0]	= _a;
 215.948 +					aaiTypes[0][0]		= (*a).eType;
 215.949 +				}
 215.950 +				else if (PLY::EST_DiffuseGreen == (*a).Semantic)
 215.951 +				{
 215.952 +					aaiPositions[0][1]	= _a;
 215.953 +					aaiTypes[0][1]		= (*a).eType;
 215.954 +				}
 215.955 +				else if (PLY::EST_DiffuseBlue == (*a).Semantic)
 215.956 +				{
 215.957 +					aaiPositions[0][2]	= _a;
 215.958 +					aaiTypes[0][2]		= (*a).eType;
 215.959 +				}
 215.960 +				else if (PLY::EST_DiffuseAlpha == (*a).Semantic)
 215.961 +				{
 215.962 +					aaiPositions[0][3]	= _a;
 215.963 +					aaiTypes[0][3]		= (*a).eType;
 215.964 +				}
 215.965 +				// specular color channels -----------------------------------
 215.966 +				else if (PLY::EST_SpecularRed == (*a).Semantic)
 215.967 +				{
 215.968 +					aaiPositions[1][0]	= _a;
 215.969 +					aaiTypes[1][0]		= (*a).eType;
 215.970 +				}
 215.971 +				else if (PLY::EST_SpecularGreen == (*a).Semantic)
 215.972 +				{
 215.973 +					aaiPositions[1][1]	= _a;
 215.974 +					aaiTypes[1][1]		= (*a).eType;
 215.975 +				}
 215.976 +				else if (PLY::EST_SpecularBlue == (*a).Semantic)
 215.977 +				{
 215.978 +					aaiPositions[1][2]	= _a;
 215.979 +					aaiTypes[1][2]		= (*a).eType;
 215.980 +				}
 215.981 +				else if (PLY::EST_SpecularAlpha == (*a).Semantic)
 215.982 +				{
 215.983 +					aaiPositions[1][3]	= _a;
 215.984 +					aaiTypes[1][3]		= (*a).eType;
 215.985 +				}
 215.986 +				// ambient color channels -----------------------------------
 215.987 +				else if (PLY::EST_AmbientRed == (*a).Semantic)
 215.988 +				{
 215.989 +					aaiPositions[2][0]	= _a;
 215.990 +					aaiTypes[2][0]		= (*a).eType;
 215.991 +				}
 215.992 +				else if (PLY::EST_AmbientGreen == (*a).Semantic)
 215.993 +				{
 215.994 +					aaiPositions[2][1]	= _a;
 215.995 +					aaiTypes[2][1]		= (*a).eType;
 215.996 +				}
 215.997 +				else if (PLY::EST_AmbientBlue == (*a).Semantic)
 215.998 +				{
 215.999 +					aaiPositions[2][2]	= _a;
215.1000 +					aaiTypes[2][2]		= (*a).eType;
215.1001 +				}
215.1002 +				else if (PLY::EST_AmbientAlpha == (*a).Semantic)
215.1003 +				{
215.1004 +					aaiPositions[2][3]	= _a;
215.1005 +					aaiTypes[2][3]		= (*a).eType;
215.1006 +				}
215.1007 +			}
215.1008 +			break;
215.1009 +		}
215.1010 +	}
215.1011 +	// check whether we have a valid source for the material data
215.1012 +	if (NULL != pcList)	{
215.1013 +		for (std::vector<ElementInstance>::const_iterator i =  pcList->alInstances.begin();i != pcList->alInstances.end();++i)	{
215.1014 +			aiColor4D clrOut;
215.1015 +			aiMaterial* pcHelper = new aiMaterial();
215.1016 +	
215.1017 +			// build the diffuse material color
215.1018 +			GetMaterialColor((*i).alProperties,aaiPositions[0],aaiTypes[0],&clrOut);
215.1019 +			pcHelper->AddProperty<aiColor4D>(&clrOut,1,AI_MATKEY_COLOR_DIFFUSE);
215.1020 +
215.1021 +			// build the specular material color
215.1022 +			GetMaterialColor((*i).alProperties,aaiPositions[1],aaiTypes[1],&clrOut);
215.1023 +			pcHelper->AddProperty<aiColor4D>(&clrOut,1,AI_MATKEY_COLOR_SPECULAR);
215.1024 +
215.1025 +			// build the ambient material color
215.1026 +			GetMaterialColor((*i).alProperties,aaiPositions[2],aaiTypes[2],&clrOut);
215.1027 +			pcHelper->AddProperty<aiColor4D>(&clrOut,1,AI_MATKEY_COLOR_AMBIENT);
215.1028 +
215.1029 +			// handle phong power and shading mode
215.1030 +			int iMode;
215.1031 +			if (0xFFFFFFFF != iPhong)	{
215.1032 +				float fSpec = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),ePhong);
215.1033 +
215.1034 +				// if shininess is 0 (and the pow() calculation would therefore always
215.1035 +				// become 1, not depending on the angle), use gouraud lighting
215.1036 +				if (fSpec)	{
215.1037 +					// scale this with 15 ... hopefully this is correct
215.1038 +					fSpec *= 15;
215.1039 +					pcHelper->AddProperty<float>(&fSpec, 1, AI_MATKEY_SHININESS);
215.1040 +
215.1041 +					iMode = (int)aiShadingMode_Phong;
215.1042 +				}
215.1043 +				else iMode = (int)aiShadingMode_Gouraud;
215.1044 +			}
215.1045 +			else iMode = (int)aiShadingMode_Gouraud;
215.1046 +			pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
215.1047 +
215.1048 +			// handle opacity
215.1049 +			if (0xFFFFFFFF != iOpacity)	{
215.1050 +				float fOpacity = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),eOpacity);
215.1051 +				pcHelper->AddProperty<float>(&fOpacity, 1, AI_MATKEY_OPACITY);
215.1052 +			}
215.1053 +
215.1054 +			// The face order is absolutely undefined for PLY, so we have to
215.1055 +			// use two-sided rendering to be sure it's ok.
215.1056 +			const int two_sided = 1;
215.1057 +			pcHelper->AddProperty(&two_sided,1,AI_MATKEY_TWOSIDED);
215.1058 +
215.1059 +			// add the newly created material instance to the list
215.1060 +			pvOut->push_back(pcHelper);
215.1061 +		}
215.1062 +	}
215.1063 +}
215.1064 +
215.1065 +#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
   216.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   216.2 +++ b/libs/assimp/PlyLoader.h	Sat Feb 01 19:58:19 2014 +0200
   216.3 @@ -0,0 +1,170 @@
   216.4 +/*
   216.5 +Open Asset Import Library (assimp)
   216.6 +----------------------------------------------------------------------
   216.7 +
   216.8 +Copyright (c) 2006-2012, assimp team
   216.9 +All rights reserved.
  216.10 +
  216.11 +Redistribution and use of this software in source and binary forms, 
  216.12 +with or without modification, are permitted provided that the 
  216.13 +following conditions are met:
  216.14 +
  216.15 +* Redistributions of source code must retain the above
  216.16 +  copyright notice, this list of conditions and the
  216.17 +  following disclaimer.
  216.18 +
  216.19 +* Redistributions in binary form must reproduce the above
  216.20 +  copyright notice, this list of conditions and the
  216.21 +  following disclaimer in the documentation and/or other
  216.22 +  materials provided with the distribution.
  216.23 +
  216.24 +* Neither the name of the assimp team, nor the names of its
  216.25 +  contributors may be used to endorse or promote products
  216.26 +  derived from this software without specific prior
  216.27 +  written permission of the assimp team.
  216.28 +
  216.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  216.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  216.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  216.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  216.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  216.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  216.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  216.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  216.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  216.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  216.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  216.40 +
  216.41 +----------------------------------------------------------------------
  216.42 +*/
  216.43 +
  216.44 +/** @file  PLYLoader.h
  216.45 + *  @brief Declaration of the .ply importer class.
  216.46 + */
  216.47 +#ifndef AI_PLYLOADER_H_INCLUDED
  216.48 +#define AI_PLYLOADER_H_INCLUDED
  216.49 +
  216.50 +#include "BaseImporter.h"
  216.51 +#include "assimp/types.h"
  216.52 +
  216.53 +struct aiNode;
  216.54 +
  216.55 +#include "PlyParser.h"
  216.56 +
  216.57 +namespace Assimp	{
  216.58 +
  216.59 +
  216.60 +using namespace PLY;
  216.61 +
  216.62 +// ---------------------------------------------------------------------------
  216.63 +/** Importer class to load the stanford PLY file format
  216.64 +*/
  216.65 +class PLYImporter : public BaseImporter
  216.66 +{
  216.67 +public:
  216.68 +	PLYImporter();
  216.69 +	~PLYImporter();
  216.70 +
  216.71 +
  216.72 +public:
  216.73 +
  216.74 +	// -------------------------------------------------------------------
  216.75 +	/** Returns whether the class can handle the format of the given file. 
  216.76 +	 * See BaseImporter::CanRead() for details.
  216.77 + 	 */
  216.78 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  216.79 +		bool checkSig) const;
  216.80 +
  216.81 +protected:
  216.82 +
  216.83 +	// -------------------------------------------------------------------
  216.84 +	/** Return importer meta information.
  216.85 +	 * See #BaseImporter::GetInfo for the details
  216.86 +	 */
  216.87 +	const aiImporterDesc* GetInfo () const;
  216.88 +
  216.89 +	// -------------------------------------------------------------------
  216.90 +	/** Imports the given file into the given scene structure. 
  216.91 +	* See BaseImporter::InternReadFile() for details
  216.92 +	*/
  216.93 +	void InternReadFile( const std::string& pFile, aiScene* pScene,
  216.94 +		IOSystem* pIOHandler);
  216.95 +
  216.96 +protected:
  216.97 +
  216.98 +
  216.99 +	// -------------------------------------------------------------------
 216.100 +	/** Extract vertices from the DOM
 216.101 +	*/
 216.102 +	void LoadVertices(std::vector<aiVector3D>* pvOut,
 216.103 +		bool p_bNormals = false);
 216.104 +
 216.105 +	// -------------------------------------------------------------------
 216.106 +	/** Extract vertex color channels from the DOM
 216.107 +	*/
 216.108 +	void LoadVertexColor(std::vector<aiColor4D>* pvOut);
 216.109 +
 216.110 +	// -------------------------------------------------------------------
 216.111 +	/** Extract texture coordinate channels from the DOM
 216.112 +	*/
 216.113 +	void LoadTextureCoordinates(std::vector<aiVector2D>* pvOut);
 216.114 +
 216.115 +	// -------------------------------------------------------------------
 216.116 +	/** Extract a face list from the DOM
 216.117 +	*/
 216.118 +	void LoadFaces(std::vector<PLY::Face>* pvOut);
 216.119 +
 216.120 +	// -------------------------------------------------------------------
 216.121 +	/** Extract a material list from the DOM
 216.122 +	*/
 216.123 +	void LoadMaterial(std::vector<aiMaterial*>* pvOut);
 216.124 +
 216.125 +
 216.126 +	// -------------------------------------------------------------------
 216.127 +	/** Validate material indices, replace default material identifiers
 216.128 +	*/
 216.129 +	void ReplaceDefaultMaterial(std::vector<PLY::Face>* avFaces,
 216.130 +		std::vector<aiMaterial*>* avMaterials);
 216.131 +
 216.132 +
 216.133 +	// -------------------------------------------------------------------
 216.134 +	/** Convert all meshes into our ourer representation
 216.135 +	*/
 216.136 +	void ConvertMeshes(std::vector<PLY::Face>* avFaces,
 216.137 +		const std::vector<aiVector3D>* avPositions,
 216.138 +		const std::vector<aiVector3D>* avNormals,
 216.139 +		const std::vector<aiColor4D>* avColors,
 216.140 +		const std::vector<aiVector2D>* avTexCoords,
 216.141 +		const std::vector<aiMaterial*>* avMaterials,
 216.142 +		std::vector<aiMesh*>* avOut);
 216.143 +
 216.144 +
 216.145 +	// -------------------------------------------------------------------
 216.146 +	/** Static helper to parse a color from four single channels in
 216.147 +	*/
 216.148 +	static void GetMaterialColor(
 216.149 +		const std::vector<PLY::PropertyInstance>& avList,
 216.150 +		unsigned int aiPositions[4], 
 216.151 +		PLY::EDataType aiTypes[4],
 216.152 +		aiColor4D* clrOut);
 216.153 +
 216.154 +
 216.155 +	// -------------------------------------------------------------------
 216.156 +	/** Static helper to parse a color channel value. The input value
 216.157 +	*  is normalized to 0-1.
 216.158 +	*/
 216.159 +	static float NormalizeColorValue (
 216.160 +		PLY::PropertyInstance::ValueUnion val,
 216.161 +		PLY::EDataType eType);
 216.162 +
 216.163 +
 216.164 +	/** Buffer to hold the loaded file */
 216.165 +	unsigned char* mBuffer;
 216.166 +
 216.167 +	/** Document object model representation extracted from the file */
 216.168 +	PLY::DOM* pcDOM;
 216.169 +};
 216.170 +
 216.171 +} // end of namespace Assimp
 216.172 +
 216.173 +#endif // AI_3DSIMPORTER_H_INC
   217.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   217.2 +++ b/libs/assimp/PlyParser.cpp	Sat Feb 01 19:58:19 2014 +0200
   217.3 @@ -0,0 +1,919 @@
   217.4 +/*
   217.5 +---------------------------------------------------------------------------
   217.6 +Open Asset Import Library (assimp)
   217.7 +---------------------------------------------------------------------------
   217.8 +
   217.9 +Copyright (c) 2006-2012, assimp team
  217.10 +
  217.11 +All rights reserved.
  217.12 +
  217.13 +Redistribution and use of this software in source and binary forms, 
  217.14 +with or without modification, are permitted provided that the following 
  217.15 +conditions are met:
  217.16 +
  217.17 +* Redistributions of source code must retain the above
  217.18 +  copyright notice, this list of conditions and the
  217.19 +  following disclaimer.
  217.20 +
  217.21 +* Redistributions in binary form must reproduce the above
  217.22 +  copyright notice, this list of conditions and the
  217.23 +  following disclaimer in the documentation and/or other
  217.24 +  materials provided with the distribution.
  217.25 +
  217.26 +* Neither the name of the assimp team, nor the names of its
  217.27 +  contributors may be used to endorse or promote products
  217.28 +  derived from this software without specific prior
  217.29 +  written permission of the assimp team.
  217.30 +
  217.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  217.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  217.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  217.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  217.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  217.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  217.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  217.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  217.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  217.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  217.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  217.42 +---------------------------------------------------------------------------
  217.43 +*/
  217.44 +
  217.45 +/** @file Implementation of the PLY parser class */
  217.46 +
  217.47 +#include "AssimpPCH.h"
  217.48 +#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
  217.49 +
  217.50 +#include "PlyLoader.h"
  217.51 +#include "fast_atof.h"
  217.52 +
  217.53 +using namespace Assimp;
  217.54 +
  217.55 +// ------------------------------------------------------------------------------------------------
  217.56 +PLY::EDataType PLY::Property::ParseDataType(const char* pCur,const char** pCurOut)
  217.57 +{
  217.58 +	ai_assert(NULL != pCur && NULL != pCurOut);
  217.59 +	PLY::EDataType eOut = PLY::EDT_INVALID;
  217.60 +
  217.61 +	if (TokenMatch(pCur,"char",4) ||
  217.62 +		TokenMatch(pCur,"int8",4))
  217.63 +	{
  217.64 +		eOut = PLY::EDT_Char;
  217.65 +	}
  217.66 +	else if (TokenMatch(pCur,"uchar",5) ||
  217.67 +			 TokenMatch(pCur,"uint8",5))
  217.68 +	{
  217.69 +		eOut = PLY::EDT_UChar;
  217.70 +	}
  217.71 +	else if (TokenMatch(pCur,"short",5) ||
  217.72 +			 TokenMatch(pCur,"int16",5))
  217.73 +	{
  217.74 +		eOut = PLY::EDT_Short;
  217.75 +	}
  217.76 +	else if (TokenMatch(pCur,"ushort",6) ||
  217.77 +			 TokenMatch(pCur,"uint16",6))
  217.78 +	{
  217.79 +		eOut = PLY::EDT_UShort;
  217.80 +	}
  217.81 +	else if (TokenMatch(pCur,"int32",5) || TokenMatch(pCur,"int",3))
  217.82 +	{
  217.83 +		eOut = PLY::EDT_Int;
  217.84 +	}
  217.85 +	else if (TokenMatch(pCur,"uint32",6) || TokenMatch(pCur,"uint",4))
  217.86 +	{
  217.87 +		eOut = PLY::EDT_UInt;
  217.88 +	}
  217.89 +	else if (TokenMatch(pCur,"float",5) || TokenMatch(pCur,"float32",7))
  217.90 +	{
  217.91 +		eOut = PLY::EDT_Float;
  217.92 +	}
  217.93 +	else if (TokenMatch(pCur,"double64",8) || TokenMatch(pCur,"double",6) ||
  217.94 +		     TokenMatch(pCur,"float64",7))
  217.95 +	{
  217.96 +		eOut = PLY::EDT_Double;
  217.97 +	}
  217.98 +	if (PLY::EDT_INVALID == eOut)
  217.99 +	{
 217.100 +		DefaultLogger::get()->info("Found unknown data type in PLY file. This is OK");
 217.101 +	}
 217.102 +	*pCurOut = pCur;
 217.103 +	return eOut;
 217.104 +}
 217.105 +
 217.106 +// ------------------------------------------------------------------------------------------------
 217.107 +PLY::ESemantic PLY::Property::ParseSemantic(const char* pCur,const char** pCurOut)
 217.108 +{
 217.109 +	ai_assert(NULL != pCur && NULL != pCurOut);
 217.110 +
 217.111 +	PLY::ESemantic eOut = PLY::EST_INVALID;
 217.112 +	if (TokenMatch(pCur,"red",3))
 217.113 +	{
 217.114 +		eOut = PLY::EST_Red;
 217.115 +	}
 217.116 +	else if (TokenMatch(pCur,"green",5))
 217.117 +	{
 217.118 +		eOut = PLY::EST_Green;
 217.119 +	}
 217.120 +	else if (TokenMatch(pCur,"blue",4))
 217.121 +	{
 217.122 +		eOut = PLY::EST_Blue;
 217.123 +	}
 217.124 +	else if (TokenMatch(pCur,"alpha",5))
 217.125 +	{
 217.126 +		eOut = PLY::EST_Alpha;
 217.127 +	}
 217.128 +	else if (TokenMatch(pCur,"vertex_index",12) || TokenMatch(pCur,"vertex_indices",14))
 217.129 +	{
 217.130 +		eOut = PLY::EST_VertexIndex;
 217.131 +	}
 217.132 +	else if (TokenMatch(pCur,"material_index",14))
 217.133 +	{
 217.134 +		eOut = PLY::EST_MaterialIndex;
 217.135 +	}
 217.136 +	else if (TokenMatch(pCur,"ambient_red",11))
 217.137 +	{
 217.138 +		eOut = PLY::EST_AmbientRed;
 217.139 +	}
 217.140 +	else if (TokenMatch(pCur,"ambient_green",13))
 217.141 +	{
 217.142 +		eOut = PLY::EST_AmbientGreen;
 217.143 +	}
 217.144 +	else if (TokenMatch(pCur,"ambient_blue",12))
 217.145 +	{
 217.146 +		eOut = PLY::EST_AmbientBlue;
 217.147 +	}
 217.148 +	else if (TokenMatch(pCur,"ambient_alpha",13))
 217.149 +	{
 217.150 +		eOut = PLY::EST_AmbientAlpha;
 217.151 +	}
 217.152 +	else if (TokenMatch(pCur,"diffuse_red",11))
 217.153 +	{
 217.154 +		eOut = PLY::EST_DiffuseRed;
 217.155 +	}
 217.156 +	else if (TokenMatch(pCur,"diffuse_green",13))
 217.157 +	{
 217.158 +		eOut = PLY::EST_DiffuseGreen;
 217.159 +	}
 217.160 +	else if (TokenMatch(pCur,"diffuse_blue",12))
 217.161 +	{
 217.162 +		eOut = PLY::EST_DiffuseBlue;
 217.163 +	}
 217.164 +	else if (TokenMatch(pCur,"diffuse_alpha",13))
 217.165 +	{
 217.166 +		eOut = PLY::EST_DiffuseAlpha;
 217.167 +	}
 217.168 +	else if (TokenMatch(pCur,"specular_red",12))
 217.169 +	{
 217.170 +		eOut = PLY::EST_SpecularRed;
 217.171 +	}
 217.172 +	else if (TokenMatch(pCur,"specular_green",14))
 217.173 +	{
 217.174 +		eOut = PLY::EST_SpecularGreen;
 217.175 +	}
 217.176 +	else if (TokenMatch(pCur,"specular_blue",13))
 217.177 +	{
 217.178 +		eOut = PLY::EST_SpecularBlue;
 217.179 +	}
 217.180 +	else if (TokenMatch(pCur,"specular_alpha",14))
 217.181 +	{
 217.182 +		eOut = PLY::EST_SpecularAlpha;
 217.183 +	}
 217.184 +	else if (TokenMatch(pCur,"opacity",7))
 217.185 +	{
 217.186 +		eOut = PLY::EST_Opacity;
 217.187 +	}
 217.188 +	else if (TokenMatch(pCur,"specular_power",6))
 217.189 +	{
 217.190 +		eOut = PLY::EST_PhongPower;
 217.191 +	}
 217.192 +	else if (TokenMatch(pCur,"r",1))
 217.193 +	{
 217.194 +		eOut = PLY::EST_Red;
 217.195 +	}
 217.196 +	else if (TokenMatch(pCur,"g",1))
 217.197 +	{
 217.198 +		eOut = PLY::EST_Green;
 217.199 +	}
 217.200 +	else if (TokenMatch(pCur,"b",1))
 217.201 +	{
 217.202 +		eOut = PLY::EST_Blue;
 217.203 +	}
 217.204 +	// NOTE: Blender3D exports texture coordinates as s,t tuples
 217.205 +	else if (TokenMatch(pCur,"u",1) ||  TokenMatch(pCur,"s",1) || TokenMatch(pCur,"tx",2))
 217.206 +	{
 217.207 +		eOut = PLY::EST_UTextureCoord;
 217.208 +	}
 217.209 +	else if (TokenMatch(pCur,"v",1) ||  TokenMatch(pCur,"t",1) || TokenMatch(pCur,"ty",2))
 217.210 +	{
 217.211 +		eOut = PLY::EST_VTextureCoord;
 217.212 +	}
 217.213 +	else if (TokenMatch(pCur,"x",1))
 217.214 +	{
 217.215 +		eOut = PLY::EST_XCoord;
 217.216 +	}
 217.217 +	else if (TokenMatch(pCur,"y",1))
 217.218 +	{
 217.219 +		eOut = PLY::EST_YCoord;
 217.220 +	}
 217.221 +	else if (TokenMatch(pCur,"z",1))
 217.222 +	{
 217.223 +		eOut = PLY::EST_ZCoord;
 217.224 +	}
 217.225 +	else if (TokenMatch(pCur,"nx",2))
 217.226 +	{
 217.227 +		eOut = PLY::EST_XNormal;
 217.228 +	}
 217.229 +	else if (TokenMatch(pCur,"ny",2))
 217.230 +	{
 217.231 +		eOut = PLY::EST_YNormal;
 217.232 +	}
 217.233 +	else if (TokenMatch(pCur,"nz",2))
 217.234 +	{
 217.235 +		eOut = PLY::EST_ZNormal;
 217.236 +	}
 217.237 +	else
 217.238 +	{
 217.239 +		DefaultLogger::get()->info("Found unknown property semantic in file. This is ok");
 217.240 +		SkipLine(&pCur);
 217.241 +	}
 217.242 +	*pCurOut = pCur;
 217.243 +	return eOut;
 217.244 +}
 217.245 +
 217.246 +// ------------------------------------------------------------------------------------------------
 217.247 +bool PLY::Property::ParseProperty (const char* pCur,
 217.248 +	const char** pCurOut,
 217.249 +	PLY::Property* pOut)
 217.250 +{
 217.251 +	ai_assert(NULL != pCur && NULL != pCurOut);
 217.252 +
 217.253 +	// Forms supported:
 217.254 +	// "property float x"
 217.255 +	// "property list uchar int vertex_index"
 217.256 +	*pCurOut = pCur;
 217.257 +
 217.258 +	// skip leading spaces
 217.259 +	if (!SkipSpaces(pCur,&pCur))return false;
 217.260 +
 217.261 +	// skip the "property" string at the beginning
 217.262 +	if (!TokenMatch(pCur,"property",8))
 217.263 +	{
 217.264 +		// seems not to be a valid property entry
 217.265 +		return false;
 217.266 +	}
 217.267 +	// get next word
 217.268 +	if (!SkipSpaces(pCur,&pCur))return false;
 217.269 +	if (TokenMatch(pCur,"list",4))
 217.270 +	{
 217.271 +		pOut->bIsList = true;
 217.272 +
 217.273 +		// seems to be a list.
 217.274 +		if(EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(pCur, &pCur)))
 217.275 +		{
 217.276 +			// unable to parse list size data type
 217.277 +			SkipLine(pCur,&pCur);
 217.278 +			*pCurOut = pCur;
 217.279 +			return false;
 217.280 +		}
 217.281 +		if (!SkipSpaces(pCur,&pCur))return false;
 217.282 +		if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(pCur, &pCur)))
 217.283 +		{
 217.284 +			// unable to parse list data type
 217.285 +			SkipLine(pCur,&pCur);
 217.286 +			*pCurOut = pCur;
 217.287 +			return false;
 217.288 +		}
 217.289 +	}
 217.290 +	else
 217.291 +	{
 217.292 +		if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(pCur, &pCur)))
 217.293 +		{
 217.294 +			// unable to parse data type. Skip the property
 217.295 +			SkipLine(pCur,&pCur);
 217.296 +			*pCurOut = pCur;
 217.297 +			return false;
 217.298 +		}
 217.299 +	}
 217.300 +	
 217.301 +	if (!SkipSpaces(pCur,&pCur))return false;
 217.302 +	const char* szCur = pCur;
 217.303 +	pOut->Semantic = PLY::Property::ParseSemantic(pCur, &pCur);
 217.304 +
 217.305 +	if (PLY::EST_INVALID == pOut->Semantic)
 217.306 +	{
 217.307 +		// store the name of the semantic
 217.308 +		uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
 217.309 +
 217.310 +		DefaultLogger::get()->info("Found unknown semantic in PLY file. This is OK");
 217.311 +		pOut->szName = std::string(szCur,iDiff);
 217.312 +	}
 217.313 +
 217.314 +	SkipSpacesAndLineEnd(pCur,&pCur);
 217.315 +	*pCurOut = pCur;
 217.316 +	return true;
 217.317 +}
 217.318 +
 217.319 +// ------------------------------------------------------------------------------------------------
 217.320 +PLY::EElementSemantic PLY::Element::ParseSemantic(const char* pCur,
 217.321 +	const char** pCurOut)
 217.322 +{
 217.323 +	ai_assert(NULL != pCur && NULL != pCurOut);
 217.324 +	PLY::EElementSemantic eOut = PLY::EEST_INVALID;
 217.325 +	if (TokenMatch(pCur,"vertex",6))
 217.326 +	{
 217.327 +		eOut = PLY::EEST_Vertex;
 217.328 +	}
 217.329 +	else if (TokenMatch(pCur,"face",4))
 217.330 +	{
 217.331 +		eOut = PLY::EEST_Face;
 217.332 +	}
 217.333 +#if 0
 217.334 +	// TODO: maybe implement this?
 217.335 +	else if (TokenMatch(pCur,"range_grid",10))
 217.336 +	{
 217.337 +		eOut = PLY::EEST_Face;
 217.338 +	}
 217.339 +#endif
 217.340 +	else if (TokenMatch(pCur,"tristrips",9))
 217.341 +	{
 217.342 +		eOut = PLY::EEST_TriStrip;
 217.343 +	}
 217.344 +	else if (TokenMatch(pCur,"edge",4))
 217.345 +	{
 217.346 +		eOut = PLY::EEST_Edge;
 217.347 +	}
 217.348 +	else if (TokenMatch(pCur,"material",8))
 217.349 +	{
 217.350 +		eOut = PLY::EEST_Material;
 217.351 +	}
 217.352 +	*pCurOut = pCur;
 217.353 +	return eOut;
 217.354 +}
 217.355 +
 217.356 +// ------------------------------------------------------------------------------------------------
 217.357 +bool PLY::Element::ParseElement (const char* pCur, 
 217.358 +	const char** pCurOut,
 217.359 +	PLY::Element* pOut)
 217.360 +{
 217.361 +	ai_assert(NULL != pCur && NULL != pCurOut && NULL != pOut);
 217.362 +
 217.363 +	// Example format: "element vertex 8"
 217.364 +	*pCurOut = pCur;
 217.365 +
 217.366 +	// skip leading spaces
 217.367 +	if (!SkipSpaces(&pCur))return false;
 217.368 +
 217.369 +	// skip the "element" string at the beginning
 217.370 +	if (!TokenMatch(pCur,"element",7))
 217.371 +	{
 217.372 +		// seems not to be a valid property entry
 217.373 +		return false;
 217.374 +	}
 217.375 +	// get next word
 217.376 +	if (!SkipSpaces(&pCur))return false;
 217.377 +
 217.378 +	// parse the semantic of the element
 217.379 +	const char* szCur = pCur;
 217.380 +	pOut->eSemantic = PLY::Element::ParseSemantic(pCur,&pCur);
 217.381 +	if (PLY::EEST_INVALID == pOut->eSemantic)
 217.382 +	{
 217.383 +		// if the exact semantic can't be determined, just store
 217.384 +		// the original string identifier
 217.385 +		uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
 217.386 +		pOut->szName = std::string(szCur,iDiff);
 217.387 +	}
 217.388 +
 217.389 +	if (!SkipSpaces(&pCur))return false;
 217.390 +	
 217.391 +	//parse the number of occurences of this element
 217.392 +	pOut->NumOccur = strtoul10(pCur,&pCur);
 217.393 +
 217.394 +	// go to the next line
 217.395 +	SkipSpacesAndLineEnd(pCur,&pCur);
 217.396 +
 217.397 +	// now parse all properties of the element
 217.398 +	while(true)
 217.399 +	{
 217.400 +		// skip all comments
 217.401 +		PLY::DOM::SkipComments(pCur,&pCur);
 217.402 +
 217.403 +		PLY::Property prop;
 217.404 +		if(!PLY::Property::ParseProperty(pCur,&pCur,&prop))break;
 217.405 +		pOut->alProperties.push_back(prop);
 217.406 +	}
 217.407 +	*pCurOut = pCur;
 217.408 +	return true;
 217.409 +}
 217.410 +
 217.411 +// ------------------------------------------------------------------------------------------------
 217.412 +bool PLY::DOM::SkipComments (const char* pCur,
 217.413 +	const char** pCurOut)
 217.414 +{
 217.415 +	ai_assert(NULL != pCur && NULL != pCurOut);
 217.416 +	*pCurOut = pCur;
 217.417 +
 217.418 +	// skip spaces
 217.419 +	if (!SkipSpaces(pCur,&pCur))return false;
 217.420 +
 217.421 +	if (TokenMatch(pCur,"comment",7))
 217.422 +	{
 217.423 +		SkipLine(pCur,&pCur);
 217.424 +		SkipComments(pCur,&pCur);
 217.425 +		*pCurOut = pCur;
 217.426 +		return true;
 217.427 +	}
 217.428 +	*pCurOut = pCur;
 217.429 +	return false;
 217.430 +}
 217.431 +
 217.432 +// ------------------------------------------------------------------------------------------------
 217.433 +bool PLY::DOM::ParseHeader (const char* pCur,const char** pCurOut)
 217.434 +{
 217.435 +	ai_assert(NULL != pCur && NULL != pCurOut);
 217.436 +	DefaultLogger::get()->debug("PLY::DOM::ParseHeader() begin");
 217.437 +
 217.438 +	// after ply and format line
 217.439 +	*pCurOut = pCur;
 217.440 +
 217.441 +	// parse all elements
 217.442 +	while (true)
 217.443 +	{
 217.444 +		// skip all comments
 217.445 +		PLY::DOM::SkipComments(pCur,&pCur);
 217.446 +
 217.447 +		PLY::Element out;
 217.448 +		if(PLY::Element::ParseElement(pCur,&pCur,&out))
 217.449 +		{
 217.450 +			// add the element to the list of elements
 217.451 +			alElements.push_back(out);
 217.452 +		}
 217.453 +		else if (TokenMatch(pCur,"end_header",10))
 217.454 +		{
 217.455 +			// we have reached the end of the header
 217.456 +			break;
 217.457 +		}
 217.458 +		else
 217.459 +		{
 217.460 +			// ignore unknown header elements
 217.461 +			SkipLine(&pCur);
 217.462 +		}
 217.463 +	}
 217.464 +	SkipSpacesAndLineEnd(pCur,&pCur);
 217.465 +	*pCurOut = pCur;
 217.466 +
 217.467 +	DefaultLogger::get()->debug("PLY::DOM::ParseHeader() succeeded");
 217.468 +	return true;
 217.469 +}
 217.470 +
 217.471 +// ------------------------------------------------------------------------------------------------
 217.472 +bool PLY::DOM::ParseElementInstanceLists (
 217.473 +	const char* pCur,
 217.474 +	const char** pCurOut)
 217.475 +{
 217.476 +	ai_assert(NULL != pCur && NULL != pCurOut);
 217.477 +
 217.478 +	DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() begin");
 217.479 +	*pCurOut = pCur;
 217.480 +
 217.481 +	alElementData.resize(alElements.size());
 217.482 +
 217.483 +	std::vector<PLY::Element>::const_iterator i = alElements.begin();
 217.484 +	std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
 217.485 +
 217.486 +	// parse all element instances
 217.487 +	for (;i != alElements.end();++i,++a)
 217.488 +	{
 217.489 +		(*a).alInstances.resize((*i).NumOccur);
 217.490 +		PLY::ElementInstanceList::ParseInstanceList(pCur,&pCur,&(*i),&(*a));
 217.491 +	}
 217.492 +
 217.493 +	DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() succeeded");
 217.494 +	*pCurOut = pCur;
 217.495 +	return true;
 217.496 +}
 217.497 +
 217.498 +// ------------------------------------------------------------------------------------------------
 217.499 +bool PLY::DOM::ParseElementInstanceListsBinary (
 217.500 +	const char* pCur,
 217.501 +	const char** pCurOut,
 217.502 +	bool p_bBE)
 217.503 +{
 217.504 +	ai_assert(NULL != pCur && NULL != pCurOut);
 217.505 +
 217.506 +	DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() begin");
 217.507 +	*pCurOut = pCur;
 217.508 +	
 217.509 +	alElementData.resize(alElements.size());
 217.510 +
 217.511 +	std::vector<PLY::Element>::const_iterator i = alElements.begin();
 217.512 +	std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
 217.513 +
 217.514 +	// parse all element instances
 217.515 +	for (;i != alElements.end();++i,++a)
 217.516 +	{
 217.517 +		(*a).alInstances.resize((*i).NumOccur);
 217.518 +		PLY::ElementInstanceList::ParseInstanceListBinary(pCur,&pCur,&(*i),&(*a),p_bBE);
 217.519 +	}
 217.520 +
 217.521 +	DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() succeeded");
 217.522 +	*pCurOut = pCur;
 217.523 +	return true;
 217.524 +}
 217.525 +
 217.526 +// ------------------------------------------------------------------------------------------------
 217.527 +bool PLY::DOM::ParseInstanceBinary (const char* pCur,DOM* p_pcOut,bool p_bBE)
 217.528 +{
 217.529 +	ai_assert(NULL != pCur && NULL != p_pcOut);
 217.530 +
 217.531 +	DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() begin");
 217.532 +
 217.533 +	if(!p_pcOut->ParseHeader(pCur,&pCur))
 217.534 +	{
 217.535 +		DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
 217.536 +		return false;
 217.537 +	}
 217.538 +	if(!p_pcOut->ParseElementInstanceListsBinary(pCur,&pCur,p_bBE))
 217.539 +	{
 217.540 +		DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
 217.541 +		return false;
 217.542 +	}
 217.543 +	DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() succeeded");
 217.544 +	return true;
 217.545 +}
 217.546 +
 217.547 +// ------------------------------------------------------------------------------------------------
 217.548 +bool PLY::DOM::ParseInstance (const char* pCur,DOM* p_pcOut)
 217.549 +{
 217.550 +	ai_assert(NULL != pCur);
 217.551 +	ai_assert(NULL != p_pcOut);
 217.552 +
 217.553 +	DefaultLogger::get()->debug("PLY::DOM::ParseInstance() begin");
 217.554 +
 217.555 +
 217.556 +	if(!p_pcOut->ParseHeader(pCur,&pCur))
 217.557 +	{
 217.558 +		DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
 217.559 +		return false;
 217.560 +	}
 217.561 +	if(!p_pcOut->ParseElementInstanceLists(pCur,&pCur))
 217.562 +	{
 217.563 +		DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
 217.564 +		return false;
 217.565 +	}
 217.566 +	DefaultLogger::get()->debug("PLY::DOM::ParseInstance() succeeded");
 217.567 +	return true;
 217.568 +}
 217.569 +
 217.570 +// ------------------------------------------------------------------------------------------------
 217.571 +bool PLY::ElementInstanceList::ParseInstanceList (
 217.572 +	const char* pCur,
 217.573 +	const char** pCurOut,
 217.574 +	const PLY::Element* pcElement, 
 217.575 +	PLY::ElementInstanceList* p_pcOut)
 217.576 +{
 217.577 +	ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
 217.578 +
 217.579 +	if (EEST_INVALID == pcElement->eSemantic || pcElement->alProperties.empty())
 217.580 +	{
 217.581 +		// if the element has an unknown semantic we can skip all lines
 217.582 +		// However, there could be comments
 217.583 +		for (unsigned int i = 0; i < pcElement->NumOccur;++i)
 217.584 +		{
 217.585 +			PLY::DOM::SkipComments(pCur,&pCur);
 217.586 +			SkipLine(pCur,&pCur);
 217.587 +		}
 217.588 +	}
 217.589 +	else
 217.590 +	{
 217.591 +		// be sure to have enough storage
 217.592 +		for (unsigned int i = 0; i < pcElement->NumOccur;++i)
 217.593 +		{
 217.594 +			PLY::DOM::SkipComments(pCur,&pCur);
 217.595 +			PLY::ElementInstance::ParseInstance(pCur, &pCur,pcElement,
 217.596 +				&p_pcOut->alInstances[i]);
 217.597 +		}
 217.598 +	}
 217.599 +	*pCurOut = pCur;
 217.600 +	return true;
 217.601 +}
 217.602 +
 217.603 +// ------------------------------------------------------------------------------------------------
 217.604 +bool PLY::ElementInstanceList::ParseInstanceListBinary (
 217.605 +	const char* pCur,
 217.606 +	const char** pCurOut,
 217.607 +	const PLY::Element* pcElement,
 217.608 +	PLY::ElementInstanceList* p_pcOut,
 217.609 +	bool p_bBE /* = false */)
 217.610 +{
 217.611 +	ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
 217.612 +
 217.613 +	// we can add special handling code for unknown element semantics since
 217.614 +	// we can't skip it as a whole block (we don't know its exact size
 217.615 +	// due to the fact that lists could be contained in the property list 
 217.616 +	// of the unknown element)
 217.617 +	for (unsigned int i = 0; i < pcElement->NumOccur;++i)
 217.618 +	{
 217.619 +		PLY::ElementInstance::ParseInstanceBinary(pCur, &pCur,pcElement,
 217.620 +			&p_pcOut->alInstances[i], p_bBE);
 217.621 +	}
 217.622 +	*pCurOut = pCur;
 217.623 +	return true;
 217.624 +}
 217.625 +
 217.626 +// ------------------------------------------------------------------------------------------------
 217.627 +bool PLY::ElementInstance::ParseInstance (
 217.628 +	const char* pCur,
 217.629 +	const char** pCurOut,
 217.630 +	const PLY::Element* pcElement,
 217.631 +	PLY::ElementInstance* p_pcOut)
 217.632 +{
 217.633 +	ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
 217.634 +
 217.635 +	if (!SkipSpaces(pCur, &pCur))return false;
 217.636 +
 217.637 +	// allocate enough storage
 217.638 +	p_pcOut->alProperties.resize(pcElement->alProperties.size());
 217.639 +
 217.640 +	std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
 217.641 +	std::vector<PLY::Property>::const_iterator  a = pcElement->alProperties.begin();
 217.642 +	for (;i != p_pcOut->alProperties.end();++i,++a)
 217.643 +	{
 217.644 +		if(!(PLY::PropertyInstance::ParseInstance(pCur, &pCur,&(*a),&(*i))))
 217.645 +		{
 217.646 +			DefaultLogger::get()->warn("Unable to parse property instance. "
 217.647 +				"Skipping this element instance");
 217.648 +
 217.649 +			// skip the rest of the instance
 217.650 +			SkipLine(pCur, &pCur);
 217.651 +
 217.652 +			PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a).eType);
 217.653 +			(*i).avList.push_back(v);
 217.654 +		}
 217.655 +	}
 217.656 +	*pCurOut = pCur;
 217.657 +	return true;
 217.658 +}
 217.659 +
 217.660 +// ------------------------------------------------------------------------------------------------
 217.661 +bool PLY::ElementInstance::ParseInstanceBinary (
 217.662 +	const char* pCur,
 217.663 +	const char** pCurOut,
 217.664 +	const PLY::Element* pcElement,
 217.665 +	PLY::ElementInstance* p_pcOut,
 217.666 +	bool p_bBE /* = false */)
 217.667 +{
 217.668 +	ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
 217.669 +
 217.670 +	// allocate enough storage
 217.671 +	p_pcOut->alProperties.resize(pcElement->alProperties.size());
 217.672 +
 217.673 +	std::vector<PLY::PropertyInstance>::iterator i =  p_pcOut->alProperties.begin();
 217.674 +	std::vector<PLY::Property>::const_iterator   a =  pcElement->alProperties.begin();
 217.675 +	for (;i != p_pcOut->alProperties.end();++i,++a)
 217.676 +	{
 217.677 +		if(!(PLY::PropertyInstance::ParseInstanceBinary(pCur, &pCur,&(*a),&(*i),p_bBE)))
 217.678 +		{
 217.679 +			DefaultLogger::get()->warn("Unable to parse binary property instance. "
 217.680 +				"Skipping this element instance");
 217.681 +
 217.682 +			(*i).avList.push_back(PLY::PropertyInstance::DefaultValue((*a).eType));
 217.683 +		}
 217.684 +	}
 217.685 +	*pCurOut = pCur;
 217.686 +	return true;
 217.687 +}
 217.688 +
 217.689 +// ------------------------------------------------------------------------------------------------
 217.690 +bool PLY::PropertyInstance::ParseInstance (const char* pCur,const char** pCurOut,
 217.691 +	const PLY::Property* prop, PLY::PropertyInstance* p_pcOut)
 217.692 +{
 217.693 +	ai_assert(NULL != pCur && NULL != pCurOut && NULL !=  prop && NULL != p_pcOut);
 217.694 +
 217.695 +	*pCurOut = pCur;
 217.696 +
 217.697 +	// skip spaces at the beginning
 217.698 +	if (!SkipSpaces(pCur, &pCur))return false;
 217.699 +
 217.700 +	if (prop->bIsList)
 217.701 +	{
 217.702 +		// parse the number of elements in the list
 217.703 +		PLY::PropertyInstance::ValueUnion v;
 217.704 +		PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eFirstType,&v);
 217.705 +
 217.706 +		// convert to unsigned int
 217.707 +		unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
 217.708 +
 217.709 +		// parse all list elements
 217.710 +		p_pcOut->avList.resize(iNum);
 217.711 +		for (unsigned int i = 0; i < iNum;++i)
 217.712 +		{
 217.713 +			if (!SkipSpaces(pCur, &pCur))return false;
 217.714 +			PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eType,&p_pcOut->avList[i]);
 217.715 +		}
 217.716 +	}
 217.717 +	else
 217.718 +	{
 217.719 +		// parse the property
 217.720 +		PLY::PropertyInstance::ValueUnion v;
 217.721 +
 217.722 +		PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eType,&v);
 217.723 +		p_pcOut->avList.push_back(v);
 217.724 +	}
 217.725 +	SkipSpacesAndLineEnd(pCur, &pCur);
 217.726 +	*pCurOut = pCur;
 217.727 +	return true;
 217.728 +}
 217.729 +
 217.730 +// ------------------------------------------------------------------------------------------------
 217.731 +bool PLY::PropertyInstance::ParseInstanceBinary (
 217.732 +	const char*  pCur,
 217.733 +	const char** pCurOut,
 217.734 +	const PLY::Property* prop, 
 217.735 +	PLY::PropertyInstance* p_pcOut,
 217.736 +	bool p_bBE)
 217.737 +{
 217.738 +	ai_assert(NULL != pCur && NULL != pCurOut && NULL != prop && NULL != p_pcOut);
 217.739 +
 217.740 +	if (prop->bIsList)
 217.741 +	{
 217.742 +		// parse the number of elements in the list
 217.743 +		PLY::PropertyInstance::ValueUnion v;
 217.744 +		PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eFirstType,&v,p_bBE);
 217.745 +
 217.746 +		// convert to unsigned int
 217.747 +		unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
 217.748 +
 217.749 +		// parse all list elements
 217.750 +		p_pcOut->avList.resize(iNum);
 217.751 +		for (unsigned int i = 0; i < iNum;++i){
 217.752 +			PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eType,&p_pcOut->avList[i],p_bBE);
 217.753 +		}
 217.754 +	}
 217.755 +	else
 217.756 +	{
 217.757 +		// parse the property
 217.758 +		PLY::PropertyInstance::ValueUnion v;
 217.759 +		PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eType,&v,p_bBE);
 217.760 +		p_pcOut->avList.push_back(v);
 217.761 +	}
 217.762 +	*pCurOut = pCur;
 217.763 +	return true;
 217.764 +}
 217.765 +
 217.766 +// ------------------------------------------------------------------------------------------------
 217.767 +PLY::PropertyInstance::ValueUnion PLY::PropertyInstance::DefaultValue(
 217.768 +	PLY::EDataType eType)
 217.769 +{
 217.770 +	PLY::PropertyInstance::ValueUnion out;
 217.771 +
 217.772 +	switch (eType)
 217.773 +	{
 217.774 +	case EDT_Float:
 217.775 +		out.fFloat = 0.f;
 217.776 +		return out;
 217.777 +
 217.778 +	case EDT_Double:
 217.779 +		out.fDouble = 0.;
 217.780 +		return out;
 217.781 +
 217.782 +	default: ;
 217.783 +	};
 217.784 +	out.iUInt = 0;
 217.785 +	return out;
 217.786 +}
 217.787 +
 217.788 +// ------------------------------------------------------------------------------------------------
 217.789 +bool PLY::PropertyInstance::ParseValue(
 217.790 +	const char* pCur,
 217.791 +	const char** pCurOut,
 217.792 +	PLY::EDataType eType,
 217.793 +	PLY::PropertyInstance::ValueUnion* out)
 217.794 +{
 217.795 +	ai_assert(NULL != pCur && NULL != pCurOut && NULL != out);
 217.796 +
 217.797 +	register bool ret = true;
 217.798 +	*pCurOut = pCur;
 217.799 +	switch (eType)
 217.800 +	{
 217.801 +	case EDT_UInt:
 217.802 +	case EDT_UShort:
 217.803 +	case EDT_UChar:
 217.804 +
 217.805 +		out->iUInt = (uint32_t)strtoul10(pCur, &pCur);
 217.806 +		break;
 217.807 +
 217.808 +	case EDT_Int:
 217.809 +	case EDT_Short:
 217.810 +	case EDT_Char:
 217.811 +
 217.812 +		out->iInt = (int32_t)strtol10(pCur, &pCur);
 217.813 +		break;
 217.814 +
 217.815 +	case EDT_Float:
 217.816 +
 217.817 +		pCur = fast_atoreal_move<float>(pCur,out->fFloat);
 217.818 +		break;
 217.819 +
 217.820 +	case EDT_Double:
 217.821 +
 217.822 +		float f;
 217.823 +		pCur = fast_atoreal_move<float>(pCur,f);
 217.824 +		out->fDouble = (double)f;
 217.825 +		break;
 217.826 +
 217.827 +	default:
 217.828 +		ret = false;
 217.829 +	}
 217.830 +	*pCurOut = pCur;
 217.831 +	return ret;
 217.832 +}
 217.833 +
 217.834 +// ------------------------------------------------------------------------------------------------
 217.835 +bool PLY::PropertyInstance::ParseValueBinary(
 217.836 +	const char* pCur,
 217.837 +	const char** pCurOut,
 217.838 +	PLY::EDataType eType,
 217.839 +	PLY::PropertyInstance::ValueUnion* out, 
 217.840 +	bool p_bBE)
 217.841 +{
 217.842 +	ai_assert(NULL != pCur && NULL != pCurOut && NULL != out);
 217.843 +
 217.844 +	register bool ret = true;
 217.845 +	switch (eType)
 217.846 +	{
 217.847 +	case EDT_UInt:
 217.848 +		out->iUInt = (uint32_t)*((uint32_t*)pCur);
 217.849 +		pCur += 4;
 217.850 +		
 217.851 +		// Swap endianess
 217.852 +		if (p_bBE)ByteSwap::Swap((int32_t*)&out->iUInt);
 217.853 +		break;
 217.854 +
 217.855 +	case EDT_UShort:
 217.856 +		{
 217.857 +		int16_t i = *((uint16_t*)pCur);
 217.858 +
 217.859 +		// Swap endianess
 217.860 +		if (p_bBE)ByteSwap::Swap(&i);
 217.861 +		out->iUInt = (uint32_t)i;
 217.862 +		pCur += 2;
 217.863 +		break;
 217.864 +		}
 217.865 +
 217.866 +	case EDT_UChar:
 217.867 +		{
 217.868 +		out->iUInt = (uint32_t)(*((uint8_t*)pCur));
 217.869 +		pCur ++;
 217.870 +		break;
 217.871 +		}
 217.872 +
 217.873 +	case EDT_Int:
 217.874 +		out->iInt = *((int32_t*)pCur);
 217.875 +		pCur += 4;
 217.876 +		
 217.877 +		// Swap endianess
 217.878 +		if (p_bBE)ByteSwap::Swap(&out->iInt);
 217.879 +		break;
 217.880 +
 217.881 +	case EDT_Short:
 217.882 +		{
 217.883 +		int16_t i = *((int16_t*)pCur);
 217.884 +
 217.885 +		// Swap endianess
 217.886 +		if (p_bBE)ByteSwap::Swap(&i);
 217.887 +		out->iInt = (int32_t)i;
 217.888 +		pCur += 2;
 217.889 +		break;
 217.890 +		}
 217.891 +
 217.892 +	case EDT_Char:
 217.893 +		out->iInt = (int32_t)*((int8_t*)pCur);
 217.894 +		pCur ++;
 217.895 +		break;
 217.896 +
 217.897 +	case EDT_Float:
 217.898 +		{
 217.899 +		out->fFloat = *((float*)pCur);
 217.900 +
 217.901 +		// Swap endianess
 217.902 +		if (p_bBE)ByteSwap::Swap((int32_t*)&out->fFloat);
 217.903 +		pCur += 4;
 217.904 +		break;
 217.905 +		}
 217.906 +	case EDT_Double:
 217.907 +		{
 217.908 +		out->fDouble = *((double*)pCur);
 217.909 +
 217.910 +		// Swap endianess
 217.911 +		if (p_bBE)ByteSwap::Swap((int64_t*)&out->fDouble);
 217.912 +		pCur += 8;
 217.913 +		break;
 217.914 +		}
 217.915 +	default:
 217.916 +		ret = false;
 217.917 +	}
 217.918 +	*pCurOut = pCur;
 217.919 +	return ret;
 217.920 +}
 217.921 +
 217.922 +#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
   218.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   218.2 +++ b/libs/assimp/PlyParser.h	Sat Feb 01 19:58:19 2014 +0200
   218.3 @@ -0,0 +1,501 @@
   218.4 +/*
   218.5 +Open Asset Import Library (assimp)
   218.6 +----------------------------------------------------------------------
   218.7 +
   218.8 +Copyright (c) 2006-2012, assimp team
   218.9 +All rights reserved.
  218.10 +
  218.11 +Redistribution and use of this software in source and binary forms, 
  218.12 +with or without modification, are permitted provided that the 
  218.13 +following conditions are met:
  218.14 +
  218.15 +* Redistributions of source code must retain the above
  218.16 +  copyright notice, this list of conditions and the
  218.17 +  following disclaimer.
  218.18 +
  218.19 +* Redistributions in binary form must reproduce the above
  218.20 +  copyright notice, this list of conditions and the
  218.21 +  following disclaimer in the documentation and/or other
  218.22 +  materials provided with the distribution.
  218.23 +
  218.24 +* Neither the name of the assimp team, nor the names of its
  218.25 +  contributors may be used to endorse or promote products
  218.26 +  derived from this software without specific prior
  218.27 +  written permission of the assimp team.
  218.28 +
  218.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  218.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  218.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  218.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  218.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  218.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  218.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  218.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  218.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  218.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  218.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  218.40 +
  218.41 +----------------------------------------------------------------------
  218.42 +*/
  218.43 +
  218.44 +
  218.45 +/** @file Defines the helper data structures for importing PLY files  */
  218.46 +#ifndef AI_PLYFILEHELPER_H_INC
  218.47 +#define AI_PLYFILEHELPER_H_INC
  218.48 +
  218.49 +
  218.50 +#include "ParsingUtils.h"
  218.51 +
  218.52 +
  218.53 +namespace Assimp
  218.54 +{
  218.55 +
  218.56 +// http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/
  218.57 +// http://w3.impa.br/~lvelho/outgoing/sossai/old/ViHAP_D4.4.2_PLY_format_v1.1.pdf
  218.58 +// http://www.okino.com/conv/exp_ply.htm
  218.59 +namespace PLY
  218.60 +{
  218.61 +
  218.62 +
  218.63 +// ---------------------------------------------------------------------------------
  218.64 +/*
  218.65 +name        type        number of bytes
  218.66 +---------------------------------------
  218.67 +char       character                 1
  218.68 +uchar      unsigned character        1
  218.69 +short      short integer             2
  218.70 +ushort     unsigned short integer    2
  218.71 +int        integer                   4
  218.72 +uint       unsigned integer          4
  218.73 +float      single-precision float    4
  218.74 +double     double-precision float    8
  218.75 +
  218.76 +int8
  218.77 +int16
  218.78 +uint8 ... forms are also used
  218.79 +*/
  218.80 +enum EDataType
  218.81 +{
  218.82 +	EDT_Char = 0x0u,
  218.83 +	EDT_UChar,
  218.84 +	EDT_Short,
  218.85 +	EDT_UShort,
  218.86 +	EDT_Int,
  218.87 +	EDT_UInt,
  218.88 +	EDT_Float,
  218.89 +	EDT_Double,
  218.90 +
  218.91 +	// Marks invalid entries
  218.92 +	EDT_INVALID
  218.93 +};
  218.94 +
  218.95 +// ---------------------------------------------------------------------------------
  218.96 +/** \brief Specifies semantics for PLY element properties
  218.97 + *
  218.98 + * Semantics define the usage of a property, e.g. x coordinate
  218.99 +*/
 218.100 +enum ESemantic
 218.101 +{
 218.102 +	//! vertex position x coordinate
 218.103 +	EST_XCoord = 0x0u,
 218.104 +	//! vertex position x coordinate
 218.105 +	EST_YCoord,
 218.106 +	//! vertex position x coordinate
 218.107 +	EST_ZCoord,
 218.108 +
 218.109 +	//! vertex normal x coordinate
 218.110 +	EST_XNormal,
 218.111 +	//! vertex normal y coordinate
 218.112 +	EST_YNormal,
 218.113 +	//! vertex normal z coordinate
 218.114 +	EST_ZNormal,
 218.115 +
 218.116 +	//! u texture coordinate
 218.117 +	EST_UTextureCoord,
 218.118 +	//! v texture coordinate
 218.119 +	EST_VTextureCoord,
 218.120 +	
 218.121 +	//! vertex colors, red channel
 218.122 +	EST_Red,		
 218.123 +	//! vertex colors, green channel
 218.124 +	EST_Green,
 218.125 +	//! vertex colors, blue channel
 218.126 +	EST_Blue,
 218.127 +	//! vertex colors, alpha channel
 218.128 +	EST_Alpha,
 218.129 +
 218.130 +	//! vertex index list 
 218.131 +	EST_VertexIndex,
 218.132 +
 218.133 +	//! texture index 
 218.134 +	EST_TextureIndex,
 218.135 +
 218.136 +	//! texture coordinates (stored as element of a face)
 218.137 +	EST_TextureCoordinates,
 218.138 +
 218.139 +	//! material index 
 218.140 +	EST_MaterialIndex,
 218.141 +
 218.142 +	//! ambient color, red channel
 218.143 +	EST_AmbientRed,
 218.144 +	//! ambient color, green channel
 218.145 +	EST_AmbientGreen,
 218.146 +	//! ambient color, blue channel
 218.147 +	EST_AmbientBlue,
 218.148 +	//! ambient color, alpha channel
 218.149 +	EST_AmbientAlpha,
 218.150 +
 218.151 +	//! diffuse color, red channel
 218.152 +	EST_DiffuseRed,
 218.153 +	//! diffuse color, green channel
 218.154 +	EST_DiffuseGreen,
 218.155 +	//! diffuse color, blue channel
 218.156 +	EST_DiffuseBlue,
 218.157 +	//! diffuse color, alpha channel
 218.158 +	EST_DiffuseAlpha,
 218.159 +
 218.160 +	//! specular color, red channel
 218.161 +	EST_SpecularRed,
 218.162 +	//! specular color, green channel
 218.163 +	EST_SpecularGreen,
 218.164 +	//! specular color, blue channel
 218.165 +	EST_SpecularBlue,
 218.166 +	//! specular color, alpha channel
 218.167 +	EST_SpecularAlpha,
 218.168 +
 218.169 +	//! specular power for phong shading
 218.170 +	EST_PhongPower,
 218.171 +
 218.172 +	//! opacity between 0 and 1
 218.173 +	EST_Opacity,
 218.174 +
 218.175 +	//! Marks invalid entries
 218.176 +	EST_INVALID
 218.177 +};
 218.178 +
 218.179 +// ---------------------------------------------------------------------------------
 218.180 +/** \brief Specifies semantics for PLY elements
 218.181 + *
 218.182 + * Semantics define the usage of an element, e.g. vertex or material
 218.183 +*/
 218.184 +enum EElementSemantic
 218.185 +{
 218.186 +	//! The element is a vertex
 218.187 +	EEST_Vertex	= 0x0u,
 218.188 +
 218.189 +	//! The element is a face description (index table)
 218.190 +	EEST_Face,
 218.191 +
 218.192 +	//! The element is a tristrip description (index table)
 218.193 +	EEST_TriStrip,
 218.194 +
 218.195 +	//! The element is an edge description (ignored)
 218.196 +	EEST_Edge,
 218.197 +
 218.198 +	//! The element is a material description 
 218.199 +	EEST_Material,
 218.200 +
 218.201 +	//! Marks invalid entries
 218.202 +	EEST_INVALID
 218.203 +};
 218.204 +
 218.205 +// ---------------------------------------------------------------------------------
 218.206 +/** \brief Helper class for a property in a PLY file.
 218.207 + *
 218.208 + * This can e.g. be a part of the vertex declaration
 218.209 + */
 218.210 +class Property
 218.211 +{
 218.212 +public:
 218.213 +
 218.214 +	//! Default constructor
 218.215 +	Property()
 218.216 +		: eType (EDT_Int), bIsList(false), eFirstType(EDT_UChar)
 218.217 +	{}
 218.218 +
 218.219 +	//!	Data type of the property
 218.220 +	EDataType eType;
 218.221 +
 218.222 +	//!	Semantical meaning of the property
 218.223 +	ESemantic Semantic;
 218.224 +
 218.225 +	//! Of the semantic of the property could not be parsed:
 218.226 +	//! Contains the semantic specified in the file
 218.227 +	std::string szName;
 218.228 +
 218.229 +	//!	Specifies whether the data type is a list where
 218.230 +	//! the first element specifies the size of the list
 218.231 +	bool bIsList;
 218.232 +	EDataType eFirstType;
 218.233 +
 218.234 +	// -------------------------------------------------------------------
 218.235 +	//! Parse a property from a string. The end of the
 218.236 +	//! string is either '\n', '\r' or '\0'. Return valie is false
 218.237 +	//! if the input string is NOT a valid property (E.g. does
 218.238 +	//! not start with the "property" keyword)
 218.239 +	static bool ParseProperty (const char* pCur, const char** pCurOut, 
 218.240 +		Property* pOut);
 218.241 +
 218.242 +	// -------------------------------------------------------------------
 218.243 +	//! Parse a data type from a string
 218.244 +	static EDataType ParseDataType(const char* pCur,const char** pCurOut);
 218.245 +
 218.246 +	// -------------------------------------------------------------------
 218.247 +	//! Parse a semantic from a string
 218.248 +	static ESemantic ParseSemantic(const char* pCur,const char** pCurOut);
 218.249 +};
 218.250 +
 218.251 +// ---------------------------------------------------------------------------------
 218.252 +/** \brief Helper class for an element in a PLY file.
 218.253 + *
 218.254 + * This can e.g. be the vertex declaration. Elements contain a
 218.255 + * well-defined number of properties.
 218.256 + */
 218.257 +class Element
 218.258 +{
 218.259 +public:
 218.260 +
 218.261 +	//! Default constructor
 218.262 +	Element()
 218.263 +		:	eSemantic (EEST_INVALID)
 218.264 +		,	NumOccur(0)
 218.265 +	{}
 218.266 +
 218.267 +	//! List of properties assigned to the element
 218.268 +	//! std::vector to support operator[]
 218.269 +	std::vector<Property> alProperties;
 218.270 +
 218.271 +	//! Semantic of the element
 218.272 +	EElementSemantic eSemantic;
 218.273 +
 218.274 +	//! Of the semantic of the element could not be parsed:
 218.275 +	//! Contains the semantic specified in the file
 218.276 +	std::string szName;
 218.277 +
 218.278 +	//! How many times will the element occur?
 218.279 +	unsigned int NumOccur;
 218.280 +
 218.281 +
 218.282 +	// -------------------------------------------------------------------
 218.283 +	//! Parse an element from a string. 
 218.284 +	//! The function will parse all properties contained in the
 218.285 +	//! element, too.
 218.286 +	static bool ParseElement (const char* pCur, const char** pCurOut, 
 218.287 +		Element* pOut);
 218.288 +
 218.289 +	// -------------------------------------------------------------------
 218.290 +	//! Parse a semantic from a string
 218.291 +	static EElementSemantic ParseSemantic(const char* pCur,
 218.292 +		const char** pCurOut);
 218.293 +};
 218.294 +
 218.295 +// ---------------------------------------------------------------------------------
 218.296 +/** \brief Instance of a property in a PLY file
 218.297 + */
 218.298 +class PropertyInstance 
 218.299 +{
 218.300 +public:
 218.301 +
 218.302 +	//! Default constructor
 218.303 +	PropertyInstance ()
 218.304 +	{}
 218.305 +
 218.306 +	union ValueUnion
 218.307 +	{
 218.308 +
 218.309 +		//! uInt32 representation of the property. All
 218.310 +		// uint types are automatically converted to uint32
 218.311 +		uint32_t iUInt;
 218.312 +
 218.313 +		//! Int32 representation of the property. All
 218.314 +		// int types are automatically converted to int32
 218.315 +		int32_t iInt;
 218.316 +
 218.317 +		//! Float32 representation of the property
 218.318 +		float fFloat;
 218.319 +
 218.320 +		//! Float64 representation of the property
 218.321 +		double fDouble;
 218.322 +
 218.323 +	};
 218.324 +
 218.325 +	// -------------------------------------------------------------------
 218.326 +	//! List of all values parsed. Contains only one value
 218.327 +	// for non-list properties
 218.328 +	std::vector<ValueUnion> avList;
 218.329 +
 218.330 +	// -------------------------------------------------------------------
 218.331 +	//! Parse a property instance 
 218.332 +	static bool ParseInstance (const char* pCur,const char** pCurOut,
 218.333 +		const Property* prop, PropertyInstance* p_pcOut);
 218.334 +
 218.335 +	// -------------------------------------------------------------------
 218.336 +	//! Parse a property instance in binary format
 218.337 +	static bool ParseInstanceBinary (const char* pCur,const char** pCurOut,
 218.338 +		const Property* prop, PropertyInstance* p_pcOut,bool p_bBE);
 218.339 +
 218.340 +	// -------------------------------------------------------------------
 218.341 +	//! Get the default value for a given data type
 218.342 +	static ValueUnion DefaultValue(EDataType eType);
 218.343 +
 218.344 +	// -------------------------------------------------------------------
 218.345 +	//! Parse a value
 218.346 +	static bool ParseValue(const char* pCur,const char** pCurOut,
 218.347 +		EDataType eType,ValueUnion* out);
 218.348 +
 218.349 +	// -------------------------------------------------------------------
 218.350 +	//! Parse a binary value
 218.351 +	static bool ParseValueBinary(const char* pCur,const char** pCurOut,
 218.352 +		EDataType eType,ValueUnion* out,bool p_bBE);
 218.353 +
 218.354 +	// -------------------------------------------------------------------
 218.355 +	//! Convert a property value to a given type TYPE
 218.356 +	template <typename TYPE>
 218.357 +	static TYPE ConvertTo(ValueUnion v, EDataType eType);
 218.358 +};
 218.359 +
 218.360 +// ---------------------------------------------------------------------------------
 218.361 +/** \brief Class for an element instance in a PLY file
 218.362 + */
 218.363 +class ElementInstance 
 218.364 +{
 218.365 +public:
 218.366 +
 218.367 +	//! Default constructor
 218.368 +	ElementInstance ()
 218.369 +	{}
 218.370 +
 218.371 +	//! List of all parsed properties
 218.372 +	std::vector< PropertyInstance > alProperties;
 218.373 +
 218.374 +	// -------------------------------------------------------------------
 218.375 +	//! Parse an element instance
 218.376 +	static bool ParseInstance (const char* pCur,const char** pCurOut,
 218.377 +		const Element* pcElement, ElementInstance* p_pcOut);
 218.378 +
 218.379 +	// -------------------------------------------------------------------
 218.380 +	//! Parse a binary element instance
 218.381 +	static bool ParseInstanceBinary (const char* pCur,const char** pCurOut,
 218.382 +		const Element* pcElement, ElementInstance* p_pcOut,bool p_bBE);
 218.383 +};
 218.384 +
 218.385 +// ---------------------------------------------------------------------------------
 218.386 +/** \brief Class for an element instance list in a PLY file
 218.387 + */
 218.388 +class ElementInstanceList 
 218.389 +{
 218.390 +public:
 218.391 +
 218.392 +	//! Default constructor
 218.393 +	ElementInstanceList ()
 218.394 +	{}
 218.395 +
 218.396 +	//! List of all element instances
 218.397 +	std::vector< ElementInstance > alInstances;
 218.398 +
 218.399 +	// -------------------------------------------------------------------
 218.400 +	//! Parse an element instance list
 218.401 +	static bool ParseInstanceList (const char* pCur,const char** pCurOut,
 218.402 +		const Element* pcElement, ElementInstanceList* p_pcOut);
 218.403 +
 218.404 +	// -------------------------------------------------------------------
 218.405 +	//! Parse a binary element instance list
 218.406 +	static bool ParseInstanceListBinary (const char* pCur,const char** pCurOut,
 218.407 +		const Element* pcElement, ElementInstanceList* p_pcOut,bool p_bBE);
 218.408 +};
 218.409 +// ---------------------------------------------------------------------------------
 218.410 +/** \brief Class to represent the document object model of an ASCII or binary 
 218.411 + * (both little and big-endian) PLY file
 218.412 + */
 218.413 +class DOM
 218.414 +{
 218.415 +public:
 218.416 +
 218.417 +	//! Default constructor
 218.418 +	DOM()
 218.419 +	{}
 218.420 +
 218.421 +
 218.422 +	//! Contains all elements of the file format
 218.423 +	std::vector<Element> alElements;
 218.424 +	//! Contains the real data of each element's instance list
 218.425 +	std::vector<ElementInstanceList> alElementData;
 218.426 +
 218.427 +	//! Parse the DOM for a PLY file. The input string is assumed
 218.428 +	//! to be terminated with zero
 218.429 +	static bool ParseInstance (const char* pCur,DOM* p_pcOut);
 218.430 +	static bool ParseInstanceBinary (const char* pCur,
 218.431 +		DOM* p_pcOut,bool p_bBE);
 218.432 +
 218.433 +	//! Skip all comment lines after this
 218.434 +	static bool SkipComments (const char* pCur,const char** pCurOut);
 218.435 +
 218.436 +private:
 218.437 +
 218.438 +	// -------------------------------------------------------------------
 218.439 +	//! Handle the file header and read all element descriptions
 218.440 +	bool ParseHeader (const char* pCur,const char** pCurOut);
 218.441 +
 218.442 +	// -------------------------------------------------------------------
 218.443 +	//! Read in all element instance lists
 218.444 +	bool ParseElementInstanceLists (const char* pCur,const char** pCurOut);
 218.445 +
 218.446 +	// -------------------------------------------------------------------
 218.447 +	//! Read in all element instance lists for a binary file format
 218.448 +	bool ParseElementInstanceListsBinary (const char* pCur,
 218.449 +		const char** pCurOut,bool p_bBE);
 218.450 +};
 218.451 +
 218.452 +// ---------------------------------------------------------------------------------
 218.453 +/** \brief Helper class to represent a loaded PLY face
 218.454 + */
 218.455 +class Face
 218.456 +{
 218.457 +public:
 218.458 +
 218.459 +	Face()
 218.460 +		: iMaterialIndex(0xFFFFFFFF)
 218.461 +	{
 218.462 +		// set all indices to zero by default
 218.463 +		mIndices.resize(3,0);
 218.464 +	}
 218.465 +
 218.466 +public:
 218.467 +
 218.468 +	//! List of vertex indices
 218.469 +	std::vector<unsigned int> mIndices;
 218.470 +
 218.471 +	//! Material index
 218.472 +	unsigned int iMaterialIndex;
 218.473 +};
 218.474 +
 218.475 +// ---------------------------------------------------------------------------------
 218.476 +template <typename TYPE>
 218.477 +inline TYPE PLY::PropertyInstance::ConvertTo(
 218.478 +	PLY::PropertyInstance::ValueUnion v, PLY::EDataType eType)
 218.479 +{
 218.480 +	switch (eType)
 218.481 +	{
 218.482 +	case EDT_Float:
 218.483 +		return (TYPE)v.fFloat;
 218.484 +	case EDT_Double:
 218.485 +		return (TYPE)v.fDouble;
 218.486 +
 218.487 +	case EDT_UInt:
 218.488 +	case EDT_UShort:
 218.489 +	case EDT_UChar:
 218.490 +		return (TYPE)v.iUInt;
 218.491 +
 218.492 +	case EDT_Int:
 218.493 +	case EDT_Short:
 218.494 +	case EDT_Char:
 218.495 +		return (TYPE)v.iInt;
 218.496 +	default: ;
 218.497 +	};
 218.498 +	return (TYPE)0;
 218.499 +}
 218.500 +
 218.501 +} // Namespace PLY
 218.502 +} // Namespace AssImp
 218.503 +
 218.504 +#endif // !! include guard
   219.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   219.2 +++ b/libs/assimp/PolyTools.h	Sat Feb 01 19:58:19 2014 +0200
   219.3 @@ -0,0 +1,224 @@
   219.4 +/*
   219.5 +Open Asset Import Library (assimp)
   219.6 +----------------------------------------------------------------------
   219.7 +
   219.8 +Copyright (c) 2006-2012, assimp team
   219.9 +All rights reserved.
  219.10 +
  219.11 +Redistribution and use of this software in source and binary forms, 
  219.12 +with or without modification, are permitted provided that the 
  219.13 +following conditions are met:
  219.14 +
  219.15 +* Redistributions of source code must retain the above
  219.16 +  copyright notice, this list of conditions and the
  219.17 +  following disclaimer.
  219.18 +
  219.19 +* Redistributions in binary form must reproduce the above
  219.20 +  copyright notice, this list of conditions and the
  219.21 +  following disclaimer in the documentation and/or other
  219.22 +  materials provided with the distribution.
  219.23 +
  219.24 +* Neither the name of the assimp team, nor the names of its
  219.25 +  contributors may be used to endorse or promote products
  219.26 +  derived from this software without specific prior
  219.27 +  written permission of the assimp team.
  219.28 +
  219.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  219.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  219.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  219.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  219.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  219.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  219.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  219.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  219.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  219.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  219.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  219.40 +
  219.41 +----------------------------------------------------------------------
  219.42 +*/
  219.43 +
  219.44 +/** @file PolyTools.h, various utilities for our dealings with arbitrary polygons */
  219.45 +
  219.46 +#ifndef AI_POLYTOOLS_H_INCLUDED
  219.47 +#define AI_POLYTOOLS_H_INCLUDED
  219.48 +
  219.49 +namespace Assimp {
  219.50 +
  219.51 +// -------------------------------------------------------------------------------
  219.52 +/** Compute the signed area of a triangle.
  219.53 + *  The function accepts an unconstrained template parameter for use with
  219.54 + *  both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
  219.55 +template <typename T>
  219.56 +inline double GetArea2D(const T& v1, const T& v2, const T& v3) 
  219.57 +{
  219.58 +	return 0.5 * (v1.x * ((double)v3.y - v2.y) + v2.x * ((double)v1.y - v3.y) + v3.x * ((double)v2.y - v1.y));
  219.59 +}
  219.60 +
  219.61 +// -------------------------------------------------------------------------------
  219.62 +/** Test if a given point p2 is on the left side of the line formed by p0-p1.
  219.63 + *  The function accepts an unconstrained template parameter for use with
  219.64 + *  both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
  219.65 +template <typename T>
  219.66 +inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2)
  219.67 +{
  219.68 +	return GetArea2D(p0,p2,p1) > 0;
  219.69 +}
  219.70 +
  219.71 +// -------------------------------------------------------------------------------
  219.72 +/** Test if a given point is inside a given triangle in R2.
  219.73 + * The function accepts an unconstrained template parameter for use with
  219.74 + *  both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
  219.75 +template <typename T>
  219.76 +inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp)
  219.77 +{
  219.78 +	// Point in triangle test using baryzentric coordinates
  219.79 +	const aiVector2D v0 = p1 - p0;
  219.80 +	const aiVector2D v1 = p2 - p0;
  219.81 +	const aiVector2D v2 = pp - p0;
  219.82 +
  219.83 +	double dot00 = v0 * v0;
  219.84 +	double dot01 = v0 * v1;
  219.85 +	double dot02 = v0 * v2;
  219.86 +	double dot11 = v1 * v1;
  219.87 +	double dot12 = v1 * v2;
  219.88 +
  219.89 +	const double invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
  219.90 +	dot11 = (dot11 * dot02 - dot01 * dot12) * invDenom;
  219.91 +	dot00 = (dot00 * dot12 - dot01 * dot02) * invDenom;
  219.92 +
  219.93 +	return (dot11 > 0) && (dot00 > 0) && (dot11 + dot00 < 1);
  219.94 +}
  219.95 +
  219.96 +
  219.97 +// -------------------------------------------------------------------------------
  219.98 +/** Check whether the winding order of a given polygon is counter-clockwise.
  219.99 + *  The function accepts an unconstrained template parameter, but is intended 
 219.100 + *  to be used only with aiVector2D and aiVector3D (z axis is ignored, only
 219.101 + *  x and y are taken into account).
 219.102 + * @note Code taken from http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/applet1.html and translated to C++
 219.103 + */
 219.104 +template <typename T>
 219.105 +inline bool IsCCW(T* in, size_t npoints) {
 219.106 +	double aa, bb, cc, b, c, theta;
 219.107 +	double convex_turn;
 219.108 +	double convex_sum = 0;
 219.109 +
 219.110 +	ai_assert(npoints >= 3);
 219.111 +
 219.112 +	for (size_t i = 0; i < npoints - 2; i++) {		
 219.113 +		aa = ((in[i+2].x - in[i].x) * (in[i+2].x - in[i].x)) +
 219.114 +			((-in[i+2].y + in[i].y) * (-in[i+2].y + in[i].y));
 219.115 +
 219.116 +		bb = ((in[i+1].x - in[i].x) * (in[i+1].x - in[i].x)) +
 219.117 +			((-in[i+1].y + in[i].y) * (-in[i+1].y + in[i].y));
 219.118 +
 219.119 +		cc = ((in[i+2].x - in[i+1].x) * 
 219.120 +			(in[i+2].x - in[i+1].x)) +
 219.121 +			((-in[i+2].y + in[i+1].y) *
 219.122 +			(-in[i+2].y + in[i+1].y));
 219.123 +
 219.124 +		b = sqrt(bb);
 219.125 +		c = sqrt(cc);
 219.126 +		theta = acos((bb + cc - aa) / (2 * b * c));
 219.127 +
 219.128 +		if (OnLeftSideOfLine2D(in[i],in[i+2],in[i+1])) {
 219.129 +			//	if (convex(in[i].x, in[i].y,
 219.130 +			//		in[i+1].x, in[i+1].y,
 219.131 +			//		in[i+2].x, in[i+2].y)) {
 219.132 +			convex_turn = AI_MATH_PI_F - theta;
 219.133 +			convex_sum += convex_turn;
 219.134 +		}
 219.135 +		else {
 219.136 +			convex_sum -= AI_MATH_PI_F - theta;
 219.137 +		}
 219.138 +	}
 219.139 +	aa = ((in[1].x - in[npoints-2].x) * 
 219.140 +		(in[1].x - in[npoints-2].x)) +
 219.141 +		((-in[1].y + in[npoints-2].y) * 
 219.142 +		(-in[1].y + in[npoints-2].y));
 219.143 +
 219.144 +	bb = ((in[0].x - in[npoints-2].x) * 
 219.145 +		(in[0].x - in[npoints-2].x)) +
 219.146 +		((-in[0].y + in[npoints-2].y) * 
 219.147 +		(-in[0].y + in[npoints-2].y));
 219.148 +
 219.149 +	cc = ((in[1].x - in[0].x) * (in[1].x - in[0].x)) +
 219.150 +		((-in[1].y + in[0].y) * (-in[1].y + in[0].y));
 219.151 +
 219.152 +	b = sqrt(bb);
 219.153 +	c = sqrt(cc);
 219.154 +	theta = acos((bb + cc - aa) / (2 * b * c));
 219.155 +
 219.156 +	//if (convex(in[npoints-2].x, in[npoints-2].y,
 219.157 +	//	in[0].x, in[0].y,
 219.158 +	//	in[1].x, in[1].y)) {
 219.159 +	if (OnLeftSideOfLine2D(in[npoints-2],in[1],in[0])) {
 219.160 +		convex_turn = AI_MATH_PI_F - theta;
 219.161 +		convex_sum += convex_turn;
 219.162 +	}
 219.163 +	else { 
 219.164 +		convex_sum -= AI_MATH_PI_F - theta;
 219.165 +	}
 219.166 +
 219.167 +	return convex_sum >= (2 * AI_MATH_PI_F);
 219.168 +}
 219.169 +
 219.170 +
 219.171 +// -------------------------------------------------------------------------------
 219.172 +/** Compute the normal of an arbitrary polygon in R3.
 219.173 + *
 219.174 + *  The code is based on Newell's formula, that is a polygons normal is the ratio
 219.175 + *  of its area when projected onto the three coordinate axes.
 219.176 + *
 219.177 + *  @param out Receives the output normal
 219.178 + *  @param num Number of input vertices
 219.179 + *  @param x X data source. x[ofs_x*n] is the n'th element. 
 219.180 + *  @param y Y data source. y[ofs_y*n] is the y'th element 
 219.181 + *  @param z Z data source. z[ofs_z*n] is the z'th element 
 219.182 + *
 219.183 + *  @note The data arrays must have storage for at least num+2 elements. Using
 219.184 + *  this method is much faster than the 'other' NewellNormal()
 219.185 + */
 219.186 +template <int ofs_x, int ofs_y, int ofs_z, typename TReal>
 219.187 +inline void NewellNormal (aiVector3t<TReal>& out, int num, TReal* x, TReal* y, TReal* z)
 219.188 +{
 219.189 +	// Duplicate the first two vertices at the end
 219.190 +	x[(num+0)*ofs_x] = x[0]; 
 219.191 +	x[(num+1)*ofs_x] = x[ofs_x]; 
 219.192 +
 219.193 +	y[(num+0)*ofs_y] = y[0]; 
 219.194 +	y[(num+1)*ofs_y] = y[ofs_y]; 
 219.195 +
 219.196 +	z[(num+0)*ofs_z] = z[0]; 
 219.197 +	z[(num+1)*ofs_z] = z[ofs_z]; 
 219.198 +
 219.199 +	TReal sum_xy = 0.0, sum_yz = 0.0, sum_zx = 0.0;
 219.200 +
 219.201 +	TReal *xptr = x +ofs_x, *xlow = x, *xhigh = x + ofs_x*2;
 219.202 +	TReal *yptr = y +ofs_y, *ylow = y, *yhigh = y + ofs_y*2;
 219.203 +	TReal *zptr = z +ofs_z, *zlow = z, *zhigh = z + ofs_z*2;
 219.204 +
 219.205 +	for (int tmp=0; tmp < num; tmp++) {
 219.206 +		sum_xy += (*xptr) * ( (*yhigh) - (*ylow) );
 219.207 +		sum_yz += (*yptr) * ( (*zhigh) - (*zlow) );
 219.208 +		sum_zx += (*zptr) * ( (*xhigh) - (*xlow) );
 219.209 +
 219.210 +		xptr  += ofs_x;
 219.211 +		xlow  += ofs_x;
 219.212 +		xhigh += ofs_x;
 219.213 +
 219.214 +		yptr  += ofs_y;
 219.215 +		ylow  += ofs_y;
 219.216 +		yhigh += ofs_y;
 219.217 +
 219.218 +		zptr  += ofs_z;
 219.219 +		zlow  += ofs_z;
 219.220 +		zhigh += ofs_z;
 219.221 +	}
 219.222 +	out = aiVector3t<TReal>(sum_yz,sum_zx,sum_xy);
 219.223 +}
 219.224 +
 219.225 +} // ! Assimp
 219.226 +
 219.227 +#endif
   220.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   220.2 +++ b/libs/assimp/PostStepRegistry.cpp	Sat Feb 01 19:58:19 2014 +0200
   220.3 @@ -0,0 +1,229 @@
   220.4 +/*
   220.5 +---------------------------------------------------------------------------
   220.6 +Open Asset Import Library (assimp)
   220.7 +---------------------------------------------------------------------------
   220.8 +
   220.9 +Copyright (c) 2006-2012, assimp team
  220.10 +
  220.11 +All rights reserved.
  220.12 +
  220.13 +Redistribution and use of this software in source and binary forms, 
  220.14 +with or without modification, are permitted provided that the following 
  220.15 +conditions are met:
  220.16 +
  220.17 +* Redistributions of source code must retain the above
  220.18 +  copyright notice, this list of conditions and the
  220.19 +  following disclaimer.
  220.20 +
  220.21 +* Redistributions in binary form must reproduce the above
  220.22 +  copyright notice, this list of conditions and the
  220.23 +  following disclaimer in the documentation and/or other
  220.24 +  materials provided with the distribution.
  220.25 +
  220.26 +* Neither the name of the assimp team, nor the names of its
  220.27 +  contributors may be used to endorse or promote products
  220.28 +  derived from this software without specific prior
  220.29 +  written permission of the assimp team.
  220.30 +
  220.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  220.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  220.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  220.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  220.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  220.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  220.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  220.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  220.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  220.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  220.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  220.42 +---------------------------------------------------------------------------
  220.43 +*/
  220.44 +
  220.45 +/** @file ImporterRegistry.cpp
  220.46 +
  220.47 +Central registry for all postprocessing steps available. Do not edit this file
  220.48 +directly (unless you are adding new steps), instead use the
  220.49 +corresponding preprocessor flag to selectively disable steps.
  220.50 +*/
  220.51 +
  220.52 +#include "AssimpPCH.h"
  220.53 +
  220.54 +#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
  220.55 +#	include "CalcTangentsProcess.h"
  220.56 +#endif
  220.57 +#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
  220.58 +#	include "JoinVerticesProcess.h"
  220.59 +#endif
  220.60 +#if !(defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS && defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS && defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
  220.61 +#	include "ConvertToLHProcess.h"
  220.62 +#endif
  220.63 +#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
  220.64 +#	include "TriangulateProcess.h"
  220.65 +#endif
  220.66 +#ifndef ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS
  220.67 +#	include "GenFaceNormalsProcess.h"
  220.68 +#endif
  220.69 +#ifndef ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS
  220.70 +#	include "GenVertexNormalsProcess.h"
  220.71 +#endif
  220.72 +#ifndef ASSIMP_BUILD_NO_REMOVEVC_PROCESS
  220.73 +#	include "RemoveVCProcess.h"
  220.74 +#endif
  220.75 +#ifndef ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS
  220.76 +#	include "SplitLargeMeshes.h"
  220.77 +#endif
  220.78 +#ifndef ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS
  220.79 +#	include "PretransformVertices.h"
  220.80 +#endif
  220.81 +#ifndef ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS
  220.82 +#	include "LimitBoneWeightsProcess.h"
  220.83 +#endif
  220.84 +#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
  220.85 +#	include "ValidateDataStructure.h"
  220.86 +#endif
  220.87 +#ifndef ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS
  220.88 +#	include "ImproveCacheLocality.h"
  220.89 +#endif
  220.90 +#ifndef ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS
  220.91 +#	include "FixNormalsStep.h"
  220.92 +#endif
  220.93 +#ifndef ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS
  220.94 +#	include "RemoveRedundantMaterials.h"
  220.95 +#endif
  220.96 +#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
  220.97 +#	include "FindInvalidDataProcess.h"
  220.98 +#endif
  220.99 +#ifndef ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS
 220.100 +#	include "FindDegenerates.h"
 220.101 +#endif
 220.102 +#ifndef ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS
 220.103 +#	include "SortByPTypeProcess.h"
 220.104 +#endif
 220.105 +#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
 220.106 +#	include "ComputeUVMappingProcess.h"
 220.107 +#endif
 220.108 +#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
 220.109 +#	include "TextureTransform.h"
 220.110 +#endif
 220.111 +#ifndef ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS
 220.112 +#	include "FindInstancesProcess.h"
 220.113 +#endif
 220.114 +#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
 220.115 +#	include "OptimizeMeshes.h"
 220.116 +#endif
 220.117 +#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
 220.118 +#	include "OptimizeGraph.h"
 220.119 +#endif
 220.120 +#ifndef ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS
 220.121 +#	include "SplitByBoneCountProcess.h"
 220.122 +#endif
 220.123 +#ifndef ASSIMP_BUILD_NO_DEBONE_PROCESS
 220.124 +#	include "DeboneProcess.h"
 220.125 +#endif
 220.126 +
 220.127 +namespace Assimp {
 220.128 +
 220.129 +// ------------------------------------------------------------------------------------------------
 220.130 +void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
 220.131 +{
 220.132 +	// ----------------------------------------------------------------------------
 220.133 +	// Add an instance of each post processing step here in the order 
 220.134 +	// of sequence it is executed. Steps that are added here are not
 220.135 +	// validated - as RegisterPPStep() does - all dependencies must be given.
 220.136 +	// ----------------------------------------------------------------------------
 220.137 +	out.reserve(25);
 220.138 +#if (!defined ASSIMP_BUILD_NO_REMOVEVC_PROCESS)
 220.139 +	out.push_back( new RemoveVCProcess());
 220.140 +#endif
 220.141 +#if (!defined ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS)
 220.142 +	out.push_back( new RemoveRedundantMatsProcess());
 220.143 +#endif
 220.144 +#if (!defined ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS)
 220.145 +	out.push_back( new FindInstancesProcess());
 220.146 +#endif
 220.147 +#if (!defined ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS)
 220.148 +	out.push_back( new OptimizeGraphProcess());
 220.149 +#endif
 220.150 +#if (!defined ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS)
 220.151 +	out.push_back( new OptimizeMeshesProcess());
 220.152 +#endif
 220.153 +#if (!defined ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS)
 220.154 +	out.push_back( new FindDegeneratesProcess());
 220.155 +#endif
 220.156 +#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
 220.157 +	out.push_back( new ComputeUVMappingProcess());
 220.158 +#endif
 220.159 +#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
 220.160 +	out.push_back( new TextureTransformStep());
 220.161 +#endif
 220.162 +#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
 220.163 +	out.push_back( new PretransformVertices());
 220.164 +#endif
 220.165 +#if (!defined ASSIMP_BUILD_NO_TRIANGULATE_PROCESS)
 220.166 +	out.push_back( new TriangulateProcess());
 220.167 +#endif
 220.168 +#if (!defined ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS)
 220.169 +	out.push_back( new SortByPTypeProcess());
 220.170 +#endif
 220.171 +#if (!defined ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS)
 220.172 +	out.push_back( new FindInvalidDataProcess());
 220.173 +#endif
 220.174 +#if (!defined ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS)
 220.175 +	out.push_back( new FixInfacingNormalsProcess());
 220.176 +#endif
 220.177 +#if (!defined ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS)
 220.178 +	out.push_back( new SplitByBoneCountProcess());
 220.179 +#endif
 220.180 +#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
 220.181 +	out.push_back( new SplitLargeMeshesProcess_Triangle());
 220.182 +#endif
 220.183 +#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
 220.184 +	out.push_back( new GenFaceNormalsProcess());
 220.185 +#endif
 220.186 +
 220.187 +	// .........................................................................
 220.188 +	// DON'T change the order of these five ..
 220.189 +	// XXX this is actually a design weakness that dates back to the time
 220.190 +	// when Importer would maintain the postprocessing step list exclusively.
 220.191 +	// Now that others access it too, we need a better solution.
 220.192 +	out.push_back( new ComputeSpatialSortProcess());
 220.193 +	// .........................................................................
 220.194 +
 220.195 +#if (!defined ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS)
 220.196 +	out.push_back( new GenVertexNormalsProcess());
 220.197 +#endif
 220.198 +#if (!defined ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS)
 220.199 +	out.push_back( new CalcTangentsProcess());
 220.200 +#endif
 220.201 +#if (!defined ASSIMP_BUILD_NO_JOINVERTICES_PROCESS)
 220.202 +	out.push_back( new JoinVerticesProcess());
 220.203 +#endif
 220.204 +
 220.205 +	// .........................................................................
 220.206 +	out.push_back( new DestroySpatialSortProcess());
 220.207 +	// .........................................................................
 220.208 +
 220.209 +#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
 220.210 +	out.push_back( new SplitLargeMeshesProcess_Vertex());
 220.211 +#endif
 220.212 +#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS)
 220.213 +	out.push_back( new MakeLeftHandedProcess());
 220.214 +#endif
 220.215 +#if (!defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS)
 220.216 +	out.push_back( new FlipUVsProcess());
 220.217 +#endif
 220.218 +#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
 220.219 +	out.push_back( new FlipWindingOrderProcess());
 220.220 +#endif
 220.221 +#if (!defined ASSIMP_BUILD_DEBONE_PROCESS)
 220.222 +	out.push_back( new DeboneProcess());
 220.223 +#endif
 220.224 +#if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
 220.225 +	out.push_back( new LimitBoneWeightsProcess());
 220.226 +#endif
 220.227 +#if (!defined ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
 220.228 +	out.push_back( new ImproveCacheLocalityProcess());
 220.229 +#endif
 220.230 +}
 220.231 +
 220.232 +}
   221.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   221.2 +++ b/libs/assimp/PretransformVertices.cpp	Sat Feb 01 19:58:19 2014 +0200
   221.3 @@ -0,0 +1,712 @@
   221.4 +/*
   221.5 +---------------------------------------------------------------------------
   221.6 +Open Asset Import Library (assimp)
   221.7 +---------------------------------------------------------------------------
   221.8 +
   221.9 +Copyright (c) 2006-2012, assimp team
  221.10 +
  221.11 +All rights reserved.
  221.12 +
  221.13 +Redistribution and use of this software in source and binary forms, 
  221.14 +with or without modification, are permitted provided that the following 
  221.15 +conditions are met:
  221.16 +
  221.17 +* Redistributions of source code must retain the above
  221.18 +  copyright notice, this list of conditions and the
  221.19 +  following disclaimer.
  221.20 +
  221.21 +* Redistributions in binary form must reproduce the above
  221.22 +  copyright notice, this list of conditions and the
  221.23 +  following disclaimer in the documentation and/or other
  221.24 +  materials provided with the distribution.
  221.25 +
  221.26 +* Neither the name of the assimp team, nor the names of its
  221.27 +  contributors may be used to endorse or promote products
  221.28 +  derived from this software without specific prior
  221.29 +  written permission of the assimp team.
  221.30 +
  221.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  221.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  221.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  221.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  221.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  221.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  221.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  221.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  221.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  221.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  221.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  221.42 +---------------------------------------------------------------------------
  221.43 +*/
  221.44 +
  221.45 +/** @file PretransformVertices.cpp
  221.46 + *  @brief Implementation of the "PretransformVertices" post processing step 
  221.47 +*/
  221.48 +
  221.49 +#include "AssimpPCH.h"
  221.50 +#include "PretransformVertices.h"
  221.51 +#include "ProcessHelper.h"
  221.52 +#include "SceneCombiner.h"
  221.53 +
  221.54 +using namespace Assimp;
  221.55 +
  221.56 +// some array offsets
  221.57 +#define AI_PTVS_VERTEX 0x0
  221.58 +#define AI_PTVS_FACE 0x1
  221.59 +
  221.60 +// ------------------------------------------------------------------------------------------------
  221.61 +// Constructor to be privately used by Importer
  221.62 +PretransformVertices::PretransformVertices()
  221.63 +:	configKeepHierarchy (false)
  221.64 +{
  221.65 +}
  221.66 +
  221.67 +// ------------------------------------------------------------------------------------------------
  221.68 +// Destructor, private as well
  221.69 +PretransformVertices::~PretransformVertices()
  221.70 +{
  221.71 +	// nothing to do here
  221.72 +}
  221.73 +
  221.74 +// ------------------------------------------------------------------------------------------------
  221.75 +// Returns whether the processing step is present in the given flag field.
  221.76 +bool PretransformVertices::IsActive( unsigned int pFlags) const
  221.77 +{
  221.78 +	return	(pFlags & aiProcess_PreTransformVertices) != 0;
  221.79 +}
  221.80 +
  221.81 +// ------------------------------------------------------------------------------------------------
  221.82 +// Setup import configuration
  221.83 +void PretransformVertices::SetupProperties(const Importer* pImp)
  221.84 +{
  221.85 +	// Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY and AI_CONFIG_PP_PTV_NORMALIZE
  221.86 +	configKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,0));
  221.87 +	configNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE,0));
  221.88 +}
  221.89 +
  221.90 +// ------------------------------------------------------------------------------------------------
  221.91 +// Count the number of nodes
  221.92 +unsigned int PretransformVertices::CountNodes( aiNode* pcNode )
  221.93 +{
  221.94 +	unsigned int iRet = 1;
  221.95 +	for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
  221.96 +	{
  221.97 +		iRet += CountNodes(pcNode->mChildren[i]);
  221.98 +	}
  221.99 +	return iRet;
 221.100 +}
 221.101 +
 221.102 +// ------------------------------------------------------------------------------------------------
 221.103 +// Get a bitwise combination identifying the vertex format of a mesh
 221.104 +unsigned int PretransformVertices::GetMeshVFormat(aiMesh* pcMesh)
 221.105 +{
 221.106 +	// the vertex format is stored in aiMesh::mBones for later retrieval.
 221.107 +	// there isn't a good reason to compute it a few hundred times
 221.108 +	// from scratch. The pointer is unused as animations are lost
 221.109 +	// during PretransformVertices.
 221.110 +	if (pcMesh->mBones)
 221.111 +		return (unsigned int)(uint64_t)pcMesh->mBones;
 221.112 +
 221.113 +
 221.114 +	const unsigned int iRet = GetMeshVFormatUnique(pcMesh);
 221.115 +
 221.116 +	// store the value for later use
 221.117 +	pcMesh->mBones = (aiBone**)(uint64_t)iRet;
 221.118 +	return iRet;
 221.119 +}
 221.120 +
 221.121 +// ------------------------------------------------------------------------------------------------
 221.122 +// Count the number of vertices in the whole scene and a given
 221.123 +// material index
 221.124 +void PretransformVertices::CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
 221.125 +	unsigned int iVFormat, unsigned int* piFaces, unsigned int* piVertices)
 221.126 +{
 221.127 +	for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
 221.128 +	{
 221.129 +		aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ]; 
 221.130 +		if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh))
 221.131 +		{
 221.132 +			*piVertices += pcMesh->mNumVertices;
 221.133 +			*piFaces += pcMesh->mNumFaces;
 221.134 +		}
 221.135 +	}
 221.136 +	for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
 221.137 +	{
 221.138 +		CountVerticesAndFaces(pcScene,pcNode->mChildren[i],iMat,
 221.139 +			iVFormat,piFaces,piVertices);
 221.140 +	}
 221.141 +}
 221.142 +
 221.143 +// ------------------------------------------------------------------------------------------------
 221.144 +// Collect vertex/face data
 221.145 +void PretransformVertices::CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
 221.146 +	unsigned int iVFormat, aiMesh* pcMeshOut, 
 221.147 +	unsigned int aiCurrent[2], unsigned int* num_refs)
 221.148 +{
 221.149 +	// No need to multiply if there's no transformation
 221.150 +	const bool identity = pcNode->mTransformation.IsIdentity();
 221.151 +	for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
 221.152 +	{
 221.153 +		aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ]; 
 221.154 +		if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh))
 221.155 +		{
 221.156 +			// Decrement mesh reference counter
 221.157 +			unsigned int& num_ref = num_refs[pcNode->mMeshes[i]];
 221.158 +			ai_assert(0 != num_ref);
 221.159 +			--num_ref;
 221.160 +
 221.161 +			if (identity)	{
 221.162 +				// copy positions without modifying them
 221.163 +				::memcpy(pcMeshOut->mVertices + aiCurrent[AI_PTVS_VERTEX],
 221.164 +					pcMesh->mVertices,
 221.165 +					pcMesh->mNumVertices * sizeof(aiVector3D));
 221.166 +
 221.167 +				if (iVFormat & 0x2) {
 221.168 +					// copy normals without modifying them
 221.169 +					::memcpy(pcMeshOut->mNormals + aiCurrent[AI_PTVS_VERTEX],
 221.170 +						pcMesh->mNormals,
 221.171 +						pcMesh->mNumVertices * sizeof(aiVector3D));
 221.172 +				}
 221.173 +				if (iVFormat & 0x4)
 221.174 +				{
 221.175 +					// copy tangents without modifying them
 221.176 +					::memcpy(pcMeshOut->mTangents + aiCurrent[AI_PTVS_VERTEX],
 221.177 +						pcMesh->mTangents,
 221.178 +						pcMesh->mNumVertices * sizeof(aiVector3D));
 221.179 +					// copy bitangents without modifying them
 221.180 +					::memcpy(pcMeshOut->mBitangents + aiCurrent[AI_PTVS_VERTEX],
 221.181 +						pcMesh->mBitangents,
 221.182 +						pcMesh->mNumVertices * sizeof(aiVector3D));
 221.183 +				}
 221.184 +			}
 221.185 +			else
 221.186 +			{
 221.187 +				// copy positions, transform them to worldspace
 221.188 +				for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)	{
 221.189 +					pcMeshOut->mVertices[aiCurrent[AI_PTVS_VERTEX]+n] = pcNode->mTransformation * pcMesh->mVertices[n];
 221.190 +				}
 221.191 +				aiMatrix4x4 mWorldIT = pcNode->mTransformation;
 221.192 +				mWorldIT.Inverse().Transpose();
 221.193 +
 221.194 +				// TODO: implement Inverse() for aiMatrix3x3
 221.195 +				aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
 221.196 +
 221.197 +				if (iVFormat & 0x2)
 221.198 +				{
 221.199 +					// copy normals, transform them to worldspace
 221.200 +					for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)	{
 221.201 +						pcMeshOut->mNormals[aiCurrent[AI_PTVS_VERTEX]+n] = 
 221.202 +							(m * pcMesh->mNormals[n]).Normalize();
 221.203 +					}
 221.204 +				}
 221.205 +				if (iVFormat & 0x4)
 221.206 +				{
 221.207 +					// copy tangents and bitangents, transform them to worldspace
 221.208 +					for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)	{
 221.209 +						pcMeshOut->mTangents  [aiCurrent[AI_PTVS_VERTEX]+n] = (m * pcMesh->mTangents[n]).Normalize();
 221.210 +						pcMeshOut->mBitangents[aiCurrent[AI_PTVS_VERTEX]+n] = (m * pcMesh->mBitangents[n]).Normalize();
 221.211 +					}
 221.212 +				}
 221.213 +			}
 221.214 +			unsigned int p = 0;
 221.215 +			while (iVFormat & (0x100 << p))
 221.216 +			{
 221.217 +				// copy texture coordinates
 221.218 +				memcpy(pcMeshOut->mTextureCoords[p] + aiCurrent[AI_PTVS_VERTEX],
 221.219 +					pcMesh->mTextureCoords[p],
 221.220 +					pcMesh->mNumVertices * sizeof(aiVector3D));
 221.221 +				++p;
 221.222 +			}
 221.223 +			p = 0;
 221.224 +			while (iVFormat & (0x1000000 << p))
 221.225 +			{
 221.226 +				// copy vertex colors
 221.227 +				memcpy(pcMeshOut->mColors[p] + aiCurrent[AI_PTVS_VERTEX],
 221.228 +					pcMesh->mColors[p],
 221.229 +					pcMesh->mNumVertices * sizeof(aiColor4D));
 221.230 +				++p;
 221.231 +			}
 221.232 +			// now we need to copy all faces. since we will delete the source mesh afterwards,
 221.233 +			// we don't need to reallocate the array of indices except if this mesh is 
 221.234 +			// referenced multiple times.
 221.235 +			for (unsigned int planck = 0;planck < pcMesh->mNumFaces;++planck)
 221.236 +			{
 221.237 +				aiFace& f_src = pcMesh->mFaces[planck];
 221.238 +				aiFace& f_dst = pcMeshOut->mFaces[aiCurrent[AI_PTVS_FACE]+planck];
 221.239 +
 221.240 +				const unsigned int num_idx = f_src.mNumIndices;
 221.241 +
 221.242 +				f_dst.mNumIndices = num_idx; 
 221.243 +
 221.244 +				unsigned int* pi;
 221.245 +				if (!num_ref) { /* if last time the mesh is referenced -> no reallocation */
 221.246 +					pi = f_dst.mIndices = f_src.mIndices; 
 221.247 +
 221.248 +					// offset all vertex indices
 221.249 +					for (unsigned int hahn = 0; hahn < num_idx;++hahn){
 221.250 +						pi[hahn] += aiCurrent[AI_PTVS_VERTEX];
 221.251 +					}
 221.252 +				}
 221.253 +				else {
 221.254 +					pi = f_dst.mIndices = new unsigned int[num_idx];
 221.255 +					
 221.256 +					// copy and offset all vertex indices
 221.257 +					for (unsigned int hahn = 0; hahn < num_idx;++hahn){
 221.258 +						pi[hahn] = f_src.mIndices[hahn] + aiCurrent[AI_PTVS_VERTEX];
 221.259 +					}
 221.260 +				}
 221.261 +
 221.262 +				// Update the mPrimitiveTypes member of the mesh
 221.263 +				switch (pcMesh->mFaces[planck].mNumIndices)
 221.264 +				{
 221.265 +				case 0x1:
 221.266 +					pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_POINT;
 221.267 +					break;
 221.268 +				case 0x2:
 221.269 +					pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_LINE;
 221.270 +					break;
 221.271 +				case 0x3:
 221.272 +					pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
 221.273 +					break;
 221.274 +				default:
 221.275 +					pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
 221.276 +					break;
 221.277 +				};
 221.278 +			}
 221.279 +			aiCurrent[AI_PTVS_VERTEX] += pcMesh->mNumVertices;
 221.280 +			aiCurrent[AI_PTVS_FACE]   += pcMesh->mNumFaces;
 221.281 +		}
 221.282 +	}
 221.283 +
 221.284 +	// append all children of us
 221.285 +	for (unsigned int i = 0;i < pcNode->mNumChildren;++i) {
 221.286 +		CollectData(pcScene,pcNode->mChildren[i],iMat,
 221.287 +			iVFormat,pcMeshOut,aiCurrent,num_refs);
 221.288 +	}
 221.289 +}
 221.290 +
 221.291 +// ------------------------------------------------------------------------------------------------
 221.292 +// Get a list of all vertex formats that occur for a given material index
 221.293 +// The output list contains duplicate elements
 221.294 +void PretransformVertices::GetVFormatList( aiScene* pcScene, unsigned int iMat,
 221.295 +	std::list<unsigned int>& aiOut)
 221.296 +{
 221.297 +	for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
 221.298 +	{
 221.299 +		aiMesh* pcMesh = pcScene->mMeshes[ i ]; 
 221.300 +		if (iMat == pcMesh->mMaterialIndex)	{
 221.301 +			aiOut.push_back(GetMeshVFormat(pcMesh));
 221.302 +		}
 221.303 +	}
 221.304 +}
 221.305 +
 221.306 +// ------------------------------------------------------------------------------------------------
 221.307 +// Compute the absolute transformation matrices of each node
 221.308 +void PretransformVertices::ComputeAbsoluteTransform( aiNode* pcNode )
 221.309 +{
 221.310 +	if (pcNode->mParent)	{
 221.311 +		pcNode->mTransformation = pcNode->mParent->mTransformation*pcNode->mTransformation;
 221.312 +	}
 221.313 +
 221.314 +	for (unsigned int i = 0;i < pcNode->mNumChildren;++i)	{
 221.315 +		ComputeAbsoluteTransform(pcNode->mChildren[i]);
 221.316 +	}
 221.317 +}
 221.318 +
 221.319 +// ------------------------------------------------------------------------------------------------
 221.320 +// Apply the node transformation to a mesh
 221.321 +void PretransformVertices::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)
 221.322 +{
 221.323 +	// Check whether we need to transform the coordinates at all
 221.324 +	if (!mat.IsIdentity()) {
 221.325 +		
 221.326 +		if (mesh->HasPositions()) {
 221.327 +			for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
 221.328 +				mesh->mVertices[i] = mat * mesh->mVertices[i];
 221.329 +			}
 221.330 +		}
 221.331 +		if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
 221.332 +			aiMatrix4x4 mWorldIT = mat;
 221.333 +			mWorldIT.Inverse().Transpose();
 221.334 +
 221.335 +			// TODO: implement Inverse() for aiMatrix3x3
 221.336 +			aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
 221.337 +
 221.338 +			if (mesh->HasNormals()) {
 221.339 +				for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
 221.340 +					mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
 221.341 +				}
 221.342 +			}
 221.343 +			if (mesh->HasTangentsAndBitangents()) {
 221.344 +				for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
 221.345 +					mesh->mTangents[i]   = (m * mesh->mTangents[i]).Normalize();
 221.346 +					mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
 221.347 +				}
 221.348 +			}
 221.349 +		}
 221.350 +	}
 221.351 +}
 221.352 +
 221.353 +// ------------------------------------------------------------------------------------------------
 221.354 +// Simple routine to build meshes in worldspace, no further optimization
 221.355 +void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in,
 221.356 +	unsigned int numIn, aiNode* node)
 221.357 +{
 221.358 +	// NOTE:
 221.359 +	//  aiMesh::mNumBones store original source mesh, or UINT_MAX if not a copy
 221.360 +	//  aiMesh::mBones store reference to abs. transform we multiplied with
 221.361 +
 221.362 +	// process meshes
 221.363 +	for (unsigned int i = 0; i < node->mNumMeshes;++i) {
 221.364 +		aiMesh* mesh = in[node->mMeshes[i]];
 221.365 +
 221.366 +		// check whether we can operate on this mesh
 221.367 +		if (!mesh->mBones || *reinterpret_cast<aiMatrix4x4*>(mesh->mBones) == node->mTransformation) {
 221.368 +			// yes, we can.
 221.369 +			mesh->mBones = reinterpret_cast<aiBone**> (&node->mTransformation);
 221.370 +			mesh->mNumBones = UINT_MAX;
 221.371 +		}
 221.372 +		else {
 221.373 +		
 221.374 +			// try to find us in the list of newly created meshes
 221.375 +			for (unsigned int n = 0; n < out.size(); ++n) {
 221.376 +				aiMesh* ctz = out[n];
 221.377 +				if (ctz->mNumBones == node->mMeshes[i] && *reinterpret_cast<aiMatrix4x4*>(ctz->mBones) ==  node->mTransformation) {
 221.378 +					
 221.379 +					// ok, use this one. Update node mesh index
 221.380 +					node->mMeshes[i] = numIn + n;
 221.381 +				}
 221.382 +			}
 221.383 +			if (node->mMeshes[i] < numIn) {
 221.384 +				// Worst case. Need to operate on a full copy of the mesh
 221.385 +				DefaultLogger::get()->info("PretransformVertices: Copying mesh due to mismatching transforms");
 221.386 +				aiMesh* ntz;
 221.387 +
 221.388 +				const unsigned int tmp = mesh->mNumBones; //
 221.389 +				mesh->mNumBones = 0;
 221.390 +				SceneCombiner::Copy(&ntz,mesh);
 221.391 +				mesh->mNumBones = tmp;
 221.392 +
 221.393 +				ntz->mNumBones = node->mMeshes[i];
 221.394 +				ntz->mBones = reinterpret_cast<aiBone**> (&node->mTransformation);
 221.395 +
 221.396 +				out.push_back(ntz);
 221.397 +			}
 221.398 +		}
 221.399 +	}
 221.400 +
 221.401 +	// call children
 221.402 +	for (unsigned int i = 0; i < node->mNumChildren;++i)
 221.403 +		BuildWCSMeshes(out,in,numIn,node->mChildren[i]);
 221.404 +}
 221.405 +
 221.406 +// ------------------------------------------------------------------------------------------------
 221.407 +// Reset transformation matrices to identity
 221.408 +void PretransformVertices::MakeIdentityTransform(aiNode* nd)
 221.409 +{
 221.410 +	nd->mTransformation = aiMatrix4x4();
 221.411 +
 221.412 +	// call children
 221.413 +	for (unsigned int i = 0; i < nd->mNumChildren;++i)
 221.414 +		MakeIdentityTransform(nd->mChildren[i]);
 221.415 +}
 221.416 +
 221.417 +// ------------------------------------------------------------------------------------------------
 221.418 +// Build reference counters for all meshes
 221.419 +void PretransformVertices::BuildMeshRefCountArray(aiNode* nd, unsigned int * refs)
 221.420 +{
 221.421 +	for (unsigned int i = 0; i< nd->mNumMeshes;++i)
 221.422 +		refs[nd->mMeshes[i]]++;
 221.423 +
 221.424 +	// call children
 221.425 +	for (unsigned int i = 0; i < nd->mNumChildren;++i)
 221.426 +		BuildMeshRefCountArray(nd->mChildren[i],refs);
 221.427 +}
 221.428 +
 221.429 +// ------------------------------------------------------------------------------------------------
 221.430 +// Executes the post processing step on the given imported data.
 221.431 +void PretransformVertices::Execute( aiScene* pScene)
 221.432 +{
 221.433 +	DefaultLogger::get()->debug("PretransformVerticesProcess begin");
 221.434 +
 221.435 +	// Return immediately if we have no meshes
 221.436 +	if (!pScene->mNumMeshes)
 221.437 +		return;
 221.438 +
 221.439 +	const unsigned int iOldMeshes = pScene->mNumMeshes;
 221.440 +	const unsigned int iOldAnimationChannels = pScene->mNumAnimations;
 221.441 +	const unsigned int iOldNodes = CountNodes(pScene->mRootNode);
 221.442 +
 221.443 +	// first compute absolute transformation matrices for all nodes
 221.444 +	ComputeAbsoluteTransform(pScene->mRootNode);
 221.445 +
 221.446 +	// Delete aiMesh::mBones for all meshes. The bones are
 221.447 +	// removed during this step and we need the pointer as
 221.448 +	// temporary storage
 221.449 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)	{
 221.450 +		aiMesh* mesh = pScene->mMeshes[i];
 221.451 +
 221.452 +		for (unsigned int a = 0; a < mesh->mNumBones;++a)
 221.453 +			delete mesh->mBones[a];
 221.454 +
 221.455 +		delete[] mesh->mBones;
 221.456 +		mesh->mBones = NULL;
 221.457 +	}
 221.458 +
 221.459 +	// now build a list of output meshes
 221.460 +	std::vector<aiMesh*> apcOutMeshes;
 221.461 +
 221.462 +	// Keep scene hierarchy? It's an easy job in this case ...
 221.463 +	// we go on and transform all meshes, if one is referenced by nodes
 221.464 +	// with different absolute transformations a depth copy of the mesh
 221.465 +	// is required.
 221.466 +	if( configKeepHierarchy ) {
 221.467 +
 221.468 +		// Hack: store the matrix we're transforming a mesh with in aiMesh::mBones
 221.469 +		BuildWCSMeshes(apcOutMeshes,pScene->mMeshes,pScene->mNumMeshes, pScene->mRootNode);
 221.470 +
 221.471 +		// ... if new meshes have been generated, append them to the end of the scene
 221.472 +		if (apcOutMeshes.size() > 0) {
 221.473 +			aiMesh** npp = new aiMesh*[pScene->mNumMeshes + apcOutMeshes.size()];
 221.474 +
 221.475 +			memcpy(npp,pScene->mMeshes,sizeof(aiMesh*)*pScene->mNumMeshes);
 221.476 +			memcpy(npp+pScene->mNumMeshes,&apcOutMeshes[0],sizeof(aiMesh*)*apcOutMeshes.size());
 221.477 +
 221.478 +			pScene->mNumMeshes  += apcOutMeshes.size();
 221.479 +			delete[] pScene->mMeshes; pScene->mMeshes = npp;
 221.480 +		}
 221.481 +
 221.482 +		// now iterate through all meshes and transform them to worldspace
 221.483 +		for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
 221.484 +			ApplyTransform(pScene->mMeshes[i],*reinterpret_cast<aiMatrix4x4*>( pScene->mMeshes[i]->mBones ));
 221.485 +
 221.486 +			// prevent improper destruction
 221.487 +			pScene->mMeshes[i]->mBones    = NULL;
 221.488 +			pScene->mMeshes[i]->mNumBones = 0;
 221.489 +		}
 221.490 +	}
 221.491 +	else {
 221.492 +
 221.493 +		apcOutMeshes.reserve(pScene->mNumMaterials<<1u);
 221.494 +		std::list<unsigned int> aiVFormats;
 221.495 +
 221.496 +		std::vector<unsigned int> s(pScene->mNumMeshes,0);
 221.497 +		BuildMeshRefCountArray(pScene->mRootNode,&s[0]);
 221.498 +
 221.499 +		for (unsigned int i = 0; i < pScene->mNumMaterials;++i)		{
 221.500 +			// get the list of all vertex formats for this material
 221.501 +			aiVFormats.clear();
 221.502 +			GetVFormatList(pScene,i,aiVFormats);
 221.503 +			aiVFormats.sort();
 221.504 +			aiVFormats.unique();
 221.505 +			for (std::list<unsigned int>::const_iterator j =  aiVFormats.begin();j != aiVFormats.end();++j)	{
 221.506 +				unsigned int iVertices = 0;
 221.507 +				unsigned int iFaces = 0; 
 221.508 +				CountVerticesAndFaces(pScene,pScene->mRootNode,i,*j,&iFaces,&iVertices);
 221.509 +				if (0 != iFaces && 0 != iVertices)
 221.510 +				{
 221.511 +					apcOutMeshes.push_back(new aiMesh());
 221.512 +					aiMesh* pcMesh = apcOutMeshes.back();
 221.513 +					pcMesh->mNumFaces = iFaces;
 221.514 +					pcMesh->mNumVertices = iVertices;
 221.515 +					pcMesh->mFaces = new aiFace[iFaces];
 221.516 +					pcMesh->mVertices = new aiVector3D[iVertices];
 221.517 +					pcMesh->mMaterialIndex = i;
 221.518 +					if ((*j) & 0x2)pcMesh->mNormals = new aiVector3D[iVertices];
 221.519 +					if ((*j) & 0x4)
 221.520 +					{
 221.521 +						pcMesh->mTangents    = new aiVector3D[iVertices];
 221.522 +						pcMesh->mBitangents  = new aiVector3D[iVertices];
 221.523 +					}
 221.524 +					iFaces = 0;
 221.525 +					while ((*j) & (0x100 << iFaces))
 221.526 +					{
 221.527 +						pcMesh->mTextureCoords[iFaces] = new aiVector3D[iVertices];
 221.528 +						if ((*j) & (0x10000 << iFaces))pcMesh->mNumUVComponents[iFaces] = 3;
 221.529 +						else pcMesh->mNumUVComponents[iFaces] = 2;
 221.530 +						iFaces++;
 221.531 +					}
 221.532 +					iFaces = 0;
 221.533 +					while ((*j) & (0x1000000 << iFaces))
 221.534 +						pcMesh->mColors[iFaces++] = new aiColor4D[iVertices];
 221.535 +
 221.536 +					// fill the mesh ...
 221.537 +					unsigned int aiTemp[2] = {0,0};
 221.538 +					CollectData(pScene,pScene->mRootNode,i,*j,pcMesh,aiTemp,&s[0]);
 221.539 +				}
 221.540 +			}
 221.541 +		}
 221.542 +
 221.543 +		// If no meshes are referenced in the node graph it is possible that we get no output meshes. 
 221.544 +		if (apcOutMeshes.empty())	{		
 221.545 +			throw DeadlyImportError("No output meshes: all meshes are orphaned and are not referenced by any nodes");
 221.546 +		}
 221.547 +		else
 221.548 +		{
 221.549 +			// now delete all meshes in the scene and build a new mesh list
 221.550 +			for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
 221.551 +			{
 221.552 +				aiMesh* mesh = pScene->mMeshes[i];
 221.553 +				mesh->mNumBones = 0;
 221.554 +				mesh->mBones    = NULL;
 221.555 +
 221.556 +				// we're reusing the face index arrays. avoid destruction
 221.557 +				for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
 221.558 +					mesh->mFaces[a].mNumIndices = 0;
 221.559 +					mesh->mFaces[a].mIndices = NULL;
 221.560 +				}
 221.561 +
 221.562 +				delete mesh;
 221.563 +
 221.564 +				// Invalidate the contents of the old mesh array. We will most
 221.565 +				// likely have less output meshes now, so the last entries of 
 221.566 +				// the mesh array are not overridden. We set them to NULL to 
 221.567 +				// make sure the developer gets notified when his application
 221.568 +				// attempts to access these fields ...
 221.569 +				mesh = NULL;
 221.570 +			}
 221.571 +
 221.572 +			// It is impossible that we have more output meshes than 
 221.573 +			// input meshes, so we can easily reuse the old mesh array
 221.574 +			pScene->mNumMeshes = (unsigned int)apcOutMeshes.size();
 221.575 +			for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
 221.576 +				pScene->mMeshes[i] = apcOutMeshes[i];
 221.577 +			}
 221.578 +		}
 221.579 +	}
 221.580 +
 221.581 +	// remove all animations from the scene
 221.582 +	for (unsigned int i = 0; i < pScene->mNumAnimations;++i)
 221.583 +		delete pScene->mAnimations[i];
 221.584 +	delete[] pScene->mAnimations;
 221.585 +
 221.586 +	pScene->mAnimations    = NULL;
 221.587 +	pScene->mNumAnimations = 0;
 221.588 +
 221.589 +	// --- we need to keep all cameras and lights 
 221.590 +	for (unsigned int i = 0; i < pScene->mNumCameras;++i)
 221.591 +	{
 221.592 +		aiCamera* cam = pScene->mCameras[i];
 221.593 +		const aiNode* nd = pScene->mRootNode->FindNode(cam->mName);
 221.594 +		ai_assert(NULL != nd);
 221.595 +
 221.596 +		// multiply all properties of the camera with the absolute
 221.597 +		// transformation of the corresponding node
 221.598 +		cam->mPosition = nd->mTransformation * cam->mPosition;
 221.599 +		cam->mLookAt   = aiMatrix3x3( nd->mTransformation ) * cam->mLookAt;
 221.600 +		cam->mUp       = aiMatrix3x3( nd->mTransformation ) * cam->mUp;
 221.601 +	}
 221.602 +
 221.603 +	for (unsigned int i = 0; i < pScene->mNumLights;++i)
 221.604 +	{
 221.605 +		aiLight* l = pScene->mLights[i];
 221.606 +		const aiNode* nd = pScene->mRootNode->FindNode(l->mName);
 221.607 +		ai_assert(NULL != nd);
 221.608 +
 221.609 +		// multiply all properties of the camera with the absolute
 221.610 +		// transformation of the corresponding node
 221.611 +		l->mPosition   = nd->mTransformation * l->mPosition;
 221.612 +		l->mDirection  = aiMatrix3x3( nd->mTransformation ) * l->mDirection;
 221.613 +	}
 221.614 +
 221.615 +	if( !configKeepHierarchy ) {
 221.616 +
 221.617 +		// now delete all nodes in the scene and build a new
 221.618 +		// flat node graph with a root node and some level 1 children
 221.619 +		delete pScene->mRootNode;
 221.620 +		pScene->mRootNode = new aiNode();
 221.621 +		pScene->mRootNode->mName.Set("<dummy_root>");
 221.622 +
 221.623 +		if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras)
 221.624 +		{
 221.625 +			pScene->mRootNode->mNumMeshes = 1;
 221.626 +			pScene->mRootNode->mMeshes = new unsigned int[1];
 221.627 +			pScene->mRootNode->mMeshes[0] = 0;
 221.628 +		}
 221.629 +		else
 221.630 +		{
 221.631 +			pScene->mRootNode->mNumChildren = pScene->mNumMeshes+pScene->mNumLights+pScene->mNumCameras;
 221.632 +			aiNode** nodes = pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
 221.633 +
 221.634 +			// generate mesh nodes
 221.635 +			for (unsigned int i = 0; i < pScene->mNumMeshes;++i,++nodes)
 221.636 +			{
 221.637 +				aiNode* pcNode = *nodes = new aiNode();
 221.638 +				pcNode->mParent = pScene->mRootNode;
 221.639 +				pcNode->mName.length = ::sprintf(pcNode->mName.data,"mesh_%i",i);
 221.640 +
 221.641 +				// setup mesh indices
 221.642 +				pcNode->mNumMeshes = 1;
 221.643 +				pcNode->mMeshes = new unsigned int[1];
 221.644 +				pcNode->mMeshes[0] = i;
 221.645 +			}
 221.646 +			// generate light nodes
 221.647 +			for (unsigned int i = 0; i < pScene->mNumLights;++i,++nodes)
 221.648 +			{
 221.649 +				aiNode* pcNode = *nodes = new aiNode();
 221.650 +				pcNode->mParent = pScene->mRootNode;
 221.651 +				pcNode->mName.length = ::sprintf(pcNode->mName.data,"light_%i",i);
 221.652 +				pScene->mLights[i]->mName = pcNode->mName;
 221.653 +			}
 221.654 +			// generate camera nodes
 221.655 +			for (unsigned int i = 0; i < pScene->mNumCameras;++i,++nodes)
 221.656 +			{
 221.657 +				aiNode* pcNode = *nodes = new aiNode();
 221.658 +				pcNode->mParent = pScene->mRootNode;
 221.659 +				pcNode->mName.length = ::sprintf(pcNode->mName.data,"cam_%i",i);
 221.660 +				pScene->mCameras[i]->mName = pcNode->mName;
 221.661 +			}
 221.662 +		}
 221.663 +	}
 221.664 +	else {
 221.665 +		// ... and finally set the transformation matrix of all nodes to identity
 221.666 +		MakeIdentityTransform(pScene->mRootNode);
 221.667 +	}
 221.668 +
 221.669 +	if (configNormalize) {
 221.670 +		// compute the boundary of all meshes
 221.671 +		aiVector3D min,max;
 221.672 +		MinMaxChooser<aiVector3D> ()(min,max);
 221.673 +
 221.674 +		for (unsigned int a = 0; a <  pScene->mNumMeshes; ++a) {
 221.675 +			aiMesh* m = pScene->mMeshes[a];
 221.676 +			for (unsigned int i = 0; i < m->mNumVertices;++i) {
 221.677 +				min = std::min(m->mVertices[i],min);
 221.678 +				max = std::max(m->mVertices[i],max);
 221.679 +			}
 221.680 +		}
 221.681 +
 221.682 +		// find the dominant axis
 221.683 +		aiVector3D d = max-min;
 221.684 +		const float div = std::max(d.x,std::max(d.y,d.z))*0.5f;
 221.685 +	
 221.686 +		d = min+d*0.5f;
 221.687 +		for (unsigned int a = 0; a <  pScene->mNumMeshes; ++a) {
 221.688 +			aiMesh* m = pScene->mMeshes[a];
 221.689 +			for (unsigned int i = 0; i < m->mNumVertices;++i) {
 221.690 +				m->mVertices[i] = (m->mVertices[i]-d)/div;
 221.691 +			}
 221.692 +		}
 221.693 +	}
 221.694 +
 221.695 +	// print statistics
 221.696 +	if (!DefaultLogger::isNullLogger())
 221.697 +	{
 221.698 +		char buffer[4096];
 221.699 +
 221.700 +		DefaultLogger::get()->debug("PretransformVerticesProcess finished");
 221.701 +
 221.702 +		sprintf(buffer,"Removed %i nodes and %i animation channels (%i output nodes)",
 221.703 +			iOldNodes,iOldAnimationChannels,CountNodes(pScene->mRootNode));
 221.704 +		DefaultLogger::get()->info(buffer);
 221.705 +
 221.706 +		sprintf(buffer,"Kept %i lights and %i cameras",
 221.707 +			pScene->mNumLights,pScene->mNumCameras);
 221.708 +		DefaultLogger::get()->info(buffer);
 221.709 +
 221.710 +		sprintf(buffer,"Moved %i meshes to WCS (number of output meshes: %i)",
 221.711 +			iOldMeshes,pScene->mNumMeshes);
 221.712 +		DefaultLogger::get()->info(buffer);
 221.713 +	}
 221.714 +}
 221.715 +
   222.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   222.2 +++ b/libs/assimp/PretransformVertices.h	Sat Feb 01 19:58:19 2014 +0200
   222.3 @@ -0,0 +1,161 @@
   222.4 +/*
   222.5 +Open Asset Import Library (assimp)
   222.6 +----------------------------------------------------------------------
   222.7 +
   222.8 +Copyright (c) 2006-2012, assimp team
   222.9 +All rights reserved.
  222.10 +
  222.11 +Redistribution and use of this software in source and binary forms, 
  222.12 +with or without modification, are permitted provided that the 
  222.13 +following conditions are met:
  222.14 +
  222.15 +* Redistributions of source code must retain the above
  222.16 +  copyright notice, this list of conditions and the
  222.17 +  following disclaimer.
  222.18 +
  222.19 +* Redistributions in binary form must reproduce the above
  222.20 +  copyright notice, this list of conditions and the
  222.21 +  following disclaimer in the documentation and/or other
  222.22 +  materials provided with the distribution.
  222.23 +
  222.24 +* Neither the name of the assimp team, nor the names of its
  222.25 +  contributors may be used to endorse or promote products
  222.26 +  derived from this software without specific prior
  222.27 +  written permission of the assimp team.
  222.28 +
  222.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  222.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  222.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  222.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  222.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  222.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  222.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  222.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  222.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  222.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  222.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  222.40 +
  222.41 +----------------------------------------------------------------------
  222.42 +*/
  222.43 +
  222.44 +/** @file PretransformVertices.h
  222.45 + *  @brief Defines a post processing step to pretransform all 
  222.46 + *    vertices in the scenegraph 
  222.47 + */
  222.48 +#ifndef AI_PRETRANSFORMVERTICES_H_INC
  222.49 +#define AI_PRETRANSFORMVERTICES_H_INC
  222.50 +
  222.51 +#include "BaseProcess.h"
  222.52 +#include "assimp/mesh.h"
  222.53 +
  222.54 +class PretransformVerticesTest;
  222.55 +namespace Assimp	{
  222.56 +
  222.57 +// ---------------------------------------------------------------------------
  222.58 +/** The PretransformVertices pretransforms all vertices in the nodegraph
  222.59 + *  and removes the whole graph. The output is a list of meshes, one for
  222.60 + *  each material.
  222.61 +*/
  222.62 +class PretransformVertices : public BaseProcess
  222.63 +{
  222.64 +public:
  222.65 +
  222.66 +	PretransformVertices ();
  222.67 +	~PretransformVertices ();
  222.68 +
  222.69 +public:
  222.70 +
  222.71 +	// -------------------------------------------------------------------
  222.72 +	// Check whether step is active
  222.73 +	bool IsActive( unsigned int pFlags) const;
  222.74 +
  222.75 +	// -------------------------------------------------------------------
  222.76 +	// Execute step on a given scene
  222.77 +	void Execute( aiScene* pScene);
  222.78 +
  222.79 +	// -------------------------------------------------------------------
  222.80 +	// Setup import settings
  222.81 +	void SetupProperties(const Importer* pImp);
  222.82 +
  222.83 +
  222.84 +	// -------------------------------------------------------------------
  222.85 +	/** @brief Toggle the 'keep hierarchy' option
  222.86 +	 *  @param d hm ... difficult to guess what this means, hu!?
  222.87 +	 */
  222.88 +	void KeepHierarchy(bool d) {
  222.89 +		configKeepHierarchy = d;
  222.90 +	}
  222.91 +
  222.92 +	// -------------------------------------------------------------------
  222.93 +	/** @brief Check whether 'keep hierarchy' is currently enabled.
  222.94 +	 *  @return ...
  222.95 +	 */
  222.96 +	bool IsHierarchyKept() const {
  222.97 +		return configKeepHierarchy;
  222.98 +	}
  222.99 +
 222.100 +private:
 222.101 +
 222.102 +	// -------------------------------------------------------------------
 222.103 +	// Count the number of nodes
 222.104 +	unsigned int CountNodes( aiNode* pcNode );
 222.105 +
 222.106 +	// -------------------------------------------------------------------
 222.107 +	// Get a bitwise combination identifying the vertex format of a mesh
 222.108 +	unsigned int GetMeshVFormat(aiMesh* pcMesh);
 222.109 +
 222.110 +	// -------------------------------------------------------------------
 222.111 +	// Count the number of vertices in the whole scene and a given
 222.112 +	// material index
 222.113 +	void CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode, 
 222.114 +		unsigned int iMat,
 222.115 +		unsigned int iVFormat, 
 222.116 +		unsigned int* piFaces,
 222.117 +		unsigned int* piVertices);
 222.118 +
 222.119 +	// -------------------------------------------------------------------
 222.120 +	// Collect vertex/face data
 222.121 +	void CollectData( aiScene* pcScene, aiNode* pcNode,
 222.122 +		unsigned int iMat,
 222.123 +		unsigned int iVFormat, 
 222.124 +		aiMesh* pcMeshOut, 
 222.125 +		unsigned int aiCurrent[2],
 222.126 +		unsigned int* num_refs);
 222.127 +
 222.128 +	// -------------------------------------------------------------------
 222.129 +	// Get a list of all vertex formats that occur for a given material
 222.130 +	// The output list contains duplicate elements
 222.131 +	void GetVFormatList( aiScene* pcScene, unsigned int iMat,
 222.132 +		std::list<unsigned int>& aiOut);
 222.133 +
 222.134 +	// -------------------------------------------------------------------
 222.135 +	// Compute the absolute transformation matrices of each node
 222.136 +	void ComputeAbsoluteTransform( aiNode* pcNode );
 222.137 +
 222.138 +	// -------------------------------------------------------------------
 222.139 +	// Simple routine to build meshes in worldspace, no further optimization
 222.140 +	void BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in,
 222.141 +		unsigned int numIn, aiNode* node);
 222.142 +
 222.143 +	// -------------------------------------------------------------------
 222.144 +	// Apply the node transformation to a mesh
 222.145 +	void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat);
 222.146 +
 222.147 +	// -------------------------------------------------------------------
 222.148 +	// Reset transformation matrices to identity
 222.149 +	void MakeIdentityTransform(aiNode* nd);
 222.150 +
 222.151 +	// -------------------------------------------------------------------
 222.152 +	// Build reference counters for all meshes
 222.153 +	void BuildMeshRefCountArray(aiNode* nd, unsigned int * refs);
 222.154 +
 222.155 +
 222.156 +
 222.157 +	//! Configuration option: keep scene hierarchy as long as possible
 222.158 +	bool configKeepHierarchy, configNormalize;
 222.159 +
 222.160 +};
 222.161 +
 222.162 +} // end of namespace Assimp
 222.163 +
 222.164 +#endif // !!AI_GENFACENORMALPROCESS_H_INC
   223.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   223.2 +++ b/libs/assimp/ProcessHelper.cpp	Sat Feb 01 19:58:19 2014 +0200
   223.3 @@ -0,0 +1,415 @@
   223.4 +/*
   223.5 +Open Asset Import Library (assimp)
   223.6 +----------------------------------------------------------------------
   223.7 +
   223.8 +Copyright (c) 2006-2012, assimp team
   223.9 +All rights reserved.
  223.10 +
  223.11 +Redistribution and use of this software in source and binary forms, 
  223.12 +with or without modification, are permitted provided that the 
  223.13 +following conditions are met:
  223.14 +
  223.15 +* Redistributions of source code must retain the above
  223.16 +  copyright notice, this list of conditions and the
  223.17 +  following disclaimer.
  223.18 +
  223.19 +* Redistributions in binary form must reproduce the above
  223.20 +  copyright notice, this list of conditions and the
  223.21 +  following disclaimer in the documentation and/or other
  223.22 +  materials provided with the distribution.
  223.23 +
  223.24 +* Neither the name of the assimp team, nor the names of its
  223.25 +  contributors may be used to endorse or promote products
  223.26 +  derived from this software without specific prior
  223.27 +  written permission of the assimp team.
  223.28 +
  223.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  223.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  223.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  223.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  223.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  223.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  223.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  223.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  223.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  223.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  223.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  223.40 +
  223.41 +----------------------------------------------------------------------
  223.42 +*/
  223.43 +
  223.44 +/// @file ProcessHelper.cpp
  223.45 +/** Implement shared utility functions for postprocessing steps */
  223.46 +
  223.47 +#include "AssimpPCH.h"
  223.48 +#include "ProcessHelper.h"
  223.49 +
  223.50 +
  223.51 +#include <limits>
  223.52 +
  223.53 +namespace Assimp {
  223.54 +
  223.55 +// -------------------------------------------------------------------------------
  223.56 +void ConvertListToStrings(const std::string& in, std::list<std::string>& out)
  223.57 +{
  223.58 +	const char* s = in.c_str();
  223.59 +	while (*s) {
  223.60 +		SkipSpacesAndLineEnd(&s);
  223.61 +		if (*s == '\'') {
  223.62 +			const char* base = ++s;
  223.63 +			while (*s != '\'') {
  223.64 +				++s;
  223.65 +				if (*s == '\0') {
  223.66 +					DefaultLogger::get()->error("ConvertListToString: String list is ill-formatted");
  223.67 +					return;
  223.68 +				}
  223.69 +			}
  223.70 +			out.push_back(std::string(base,(size_t)(s-base)));
  223.71 +			++s;
  223.72 +		}
  223.73 +		else {
  223.74 +			out.push_back(GetNextToken(s));
  223.75 +		}
  223.76 +	}
  223.77 +}
  223.78 +
  223.79 +// -------------------------------------------------------------------------------
  223.80 +void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max, 
  223.81 +	const aiMatrix4x4& m)
  223.82 +{
  223.83 +	min = aiVector3D (10e10f,  10e10f, 10e10f);
  223.84 +	max = aiVector3D (-10e10f,-10e10f,-10e10f);
  223.85 +	for (unsigned int i = 0;i < mesh->mNumVertices;++i)
  223.86 +	{
  223.87 +		const aiVector3D v = m * mesh->mVertices[i];
  223.88 +		min = std::min(v,min);
  223.89 +		max = std::max(v,max);
  223.90 +	}
  223.91 +}
  223.92 +
  223.93 +// -------------------------------------------------------------------------------
  223.94 +void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max)
  223.95 +{
  223.96 +	ArrayBounds(mesh->mVertices,mesh->mNumVertices, min,max);
  223.97 +	out = min + (max-min)*0.5f;
  223.98 +}
  223.99 +
 223.100 +// -------------------------------------------------------------------------------
 223.101 +void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min,
 223.102 +	aiVector3D& max, const aiMatrix4x4& m)
 223.103 +{
 223.104 +	FindAABBTransformed(mesh,min,max,m);
 223.105 +	out = min + (max-min)*0.5f;
 223.106 +}
 223.107 +
 223.108 +// -------------------------------------------------------------------------------
 223.109 +void FindMeshCenter (aiMesh* mesh, aiVector3D& out)
 223.110 +{
 223.111 +	aiVector3D min,max;
 223.112 +	FindMeshCenter(mesh,out,min,max);
 223.113 +}
 223.114 +
 223.115 +// -------------------------------------------------------------------------------
 223.116 +void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out,
 223.117 +	const aiMatrix4x4& m)
 223.118 +{
 223.119 +	aiVector3D min,max;
 223.120 +	FindMeshCenterTransformed(mesh,out,min,max,m);
 223.121 +}
 223.122 +
 223.123 +// -------------------------------------------------------------------------------
 223.124 +float ComputePositionEpsilon(const aiMesh* pMesh)
 223.125 +{
 223.126 +	const float epsilon = 1e-4f;
 223.127 +
 223.128 +	// calculate the position bounds so we have a reliable epsilon to check position differences against 
 223.129 +	aiVector3D minVec, maxVec;
 223.130 +	ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,minVec,maxVec);
 223.131 +	return (maxVec - minVec).Length() * epsilon;
 223.132 +}
 223.133 +
 223.134 +// -------------------------------------------------------------------------------
 223.135 +float ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num)
 223.136 +{
 223.137 +	const float epsilon = 1e-4f;
 223.138 +
 223.139 +	// calculate the position bounds so we have a reliable epsilon to check position differences against 
 223.140 +	aiVector3D minVec, maxVec, mi, ma;
 223.141 +	MinMaxChooser<aiVector3D>()(minVec,maxVec);
 223.142 +
 223.143 +	for (size_t a = 0; a < num; ++a) {
 223.144 +		const aiMesh* pMesh = pMeshes[a];
 223.145 +		ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,mi,ma);
 223.146 +
 223.147 +		minVec = std::min(minVec,mi);
 223.148 +		maxVec = std::max(maxVec,ma);
 223.149 +	}
 223.150 +	return (maxVec - minVec).Length() * epsilon;
 223.151 +}
 223.152 +
 223.153 +
 223.154 +// -------------------------------------------------------------------------------
 223.155 +unsigned int GetMeshVFormatUnique(const aiMesh* pcMesh)
 223.156 +{
 223.157 +	ai_assert(NULL != pcMesh);
 223.158 +
 223.159 +	// FIX: the hash may never be 0. Otherwise a comparison against
 223.160 +	// nullptr could be successful
 223.161 +	unsigned int iRet = 1;
 223.162 +
 223.163 +	// normals
 223.164 +	if (pcMesh->HasNormals())iRet |= 0x2;
 223.165 +	// tangents and bitangents
 223.166 +	if (pcMesh->HasTangentsAndBitangents())iRet |= 0x4;
 223.167 +
 223.168 +#ifdef BOOST_STATIC_ASSERT
 223.169 +	BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_COLOR_SETS);
 223.170 +	BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS);
 223.171 +#endif
 223.172 +
 223.173 +	// texture coordinates
 223.174 +	unsigned int p = 0;
 223.175 +	while (pcMesh->HasTextureCoords(p))
 223.176 +	{
 223.177 +		iRet |= (0x100 << p);
 223.178 +		if (3 == pcMesh->mNumUVComponents[p])
 223.179 +			iRet |= (0x10000 << p);
 223.180 +
 223.181 +		++p;
 223.182 +	}
 223.183 +	// vertex colors
 223.184 +	p = 0;
 223.185 +	while (pcMesh->HasVertexColors(p))iRet |= (0x1000000 << p++);
 223.186 +	return iRet;
 223.187 +}
 223.188 +
 223.189 +// -------------------------------------------------------------------------------
 223.190 +VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh)
 223.191 +{
 223.192 +	if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) {
 223.193 +		return NULL;
 223.194 +	}
 223.195 +
 223.196 +	VertexWeightTable* avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
 223.197 +	for (unsigned int i = 0; i < pMesh->mNumBones;++i)	{
 223.198 +
 223.199 +		aiBone* bone = pMesh->mBones[i];
 223.200 +		for (unsigned int a = 0; a < bone->mNumWeights;++a)	{
 223.201 +			const aiVertexWeight& weight = bone->mWeights[a];
 223.202 +			avPerVertexWeights[weight.mVertexId].push_back( std::pair<unsigned int,float>(i,weight.mWeight) );
 223.203 +		}
 223.204 +	}
 223.205 +	return avPerVertexWeights;
 223.206 +}
 223.207 +
 223.208 +
 223.209 +// -------------------------------------------------------------------------------
 223.210 +const char* TextureTypeToString(aiTextureType in)
 223.211 +{
 223.212 +	switch (in)
 223.213 +	{
 223.214 +	case aiTextureType_NONE:
 223.215 +		return "n/a";
 223.216 +	case aiTextureType_DIFFUSE:
 223.217 +		return "Diffuse";
 223.218 +	case aiTextureType_SPECULAR:
 223.219 +		return "Specular";
 223.220 +	case aiTextureType_AMBIENT:
 223.221 +		return "Ambient";
 223.222 +	case aiTextureType_EMISSIVE:
 223.223 +		return "Emissive";
 223.224 +	case aiTextureType_OPACITY:
 223.225 +		return "Opacity";
 223.226 +	case aiTextureType_NORMALS:
 223.227 +		return "Normals";
 223.228 +	case aiTextureType_HEIGHT:
 223.229 +		return "Height";
 223.230 +	case aiTextureType_SHININESS:
 223.231 +		return "Shininess";
 223.232 +	case aiTextureType_DISPLACEMENT:
 223.233 +		return "Displacement";
 223.234 +	case aiTextureType_LIGHTMAP:
 223.235 +		return "Lightmap";
 223.236 +	case aiTextureType_REFLECTION:
 223.237 +		return "Reflection";
 223.238 +	case aiTextureType_UNKNOWN:
 223.239 +		return "Unknown";
 223.240 +	default:
 223.241 +		break;
 223.242 +	}
 223.243 +   
 223.244 +	ai_assert(false);
 223.245 +    return  "BUG";          
 223.246 +}
 223.247 +
 223.248 +// -------------------------------------------------------------------------------
 223.249 +const char* MappingTypeToString(aiTextureMapping in)
 223.250 +{
 223.251 +	switch (in)
 223.252 +	{
 223.253 +	case aiTextureMapping_UV:
 223.254 +		return "UV";
 223.255 +	case aiTextureMapping_BOX:
 223.256 +		return "Box";
 223.257 +	case aiTextureMapping_SPHERE:
 223.258 +		return "Sphere";
 223.259 +	case aiTextureMapping_CYLINDER:
 223.260 +		return "Cylinder";
 223.261 +	case aiTextureMapping_PLANE:
 223.262 +		return "Plane";
 223.263 +	case aiTextureMapping_OTHER:
 223.264 +		return "Other";
 223.265 +	default:
 223.266 +		break;
 223.267 +	}
 223.268 +
 223.269 +	ai_assert(false);
 223.270 +    return  "BUG";   
 223.271 +}
 223.272 +
 223.273 +
 223.274 +// -------------------------------------------------------------------------------
 223.275 +aiMesh* MakeSubmesh(const aiMesh *pMesh, const std::vector<unsigned int> &subMeshFaces, unsigned int subFlags)
 223.276 +{		
 223.277 +	aiMesh *oMesh = new aiMesh(); 
 223.278 +	std::vector<unsigned int> vMap(pMesh->mNumVertices,UINT_MAX);
 223.279 +
 223.280 +	size_t numSubVerts = 0; 
 223.281 +	size_t numSubFaces = subMeshFaces.size();
 223.282 +
 223.283 +	for(unsigned int i=0;i<numSubFaces;i++)	{
 223.284 +		const aiFace &f = pMesh->mFaces[subMeshFaces[i]];
 223.285 +
 223.286 +		for(unsigned int j=0;j<f.mNumIndices;j++)	{
 223.287 +			if(vMap[f.mIndices[j]]==UINT_MAX)	{
 223.288 +				vMap[f.mIndices[j]] = numSubVerts++;
 223.289 +			}
 223.290 +		}		
 223.291 +	} 
 223.292 +
 223.293 +	oMesh->mName = pMesh->mName;
 223.294 +		
 223.295 +	oMesh->mMaterialIndex = pMesh->mMaterialIndex;
 223.296 +	oMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes;
 223.297 +	
 223.298 +	// create all the arrays for this mesh if the old mesh contained them
 223.299 +		
 223.300 +	oMesh->mNumFaces = subMeshFaces.size();
 223.301 +	oMesh->mNumVertices = numSubVerts;
 223.302 +	oMesh->mVertices = new aiVector3D[numSubVerts];
 223.303 +	if( pMesh->HasNormals() ) {
 223.304 +		oMesh->mNormals = new aiVector3D[numSubVerts];
 223.305 +	}
 223.306 +
 223.307 +	if( pMesh->HasTangentsAndBitangents() )	{
 223.308 +		oMesh->mTangents = new aiVector3D[numSubVerts];
 223.309 +		oMesh->mBitangents = new aiVector3D[numSubVerts];
 223.310 +	}
 223.311 +
 223.312 +	for( size_t a = 0;  pMesh->HasTextureCoords( a) ; ++a )	{
 223.313 +		oMesh->mTextureCoords[a] = new aiVector3D[numSubVerts];
 223.314 +		oMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
 223.315 +	}
 223.316 +
 223.317 +	for( size_t a = 0; pMesh->HasVertexColors( a); ++a )	{
 223.318 +		oMesh->mColors[a] = new aiColor4D[numSubVerts];
 223.319 +	}
 223.320 +
 223.321 +	// and copy over the data, generating faces with linear indices along the way
 223.322 +	oMesh->mFaces = new aiFace[numSubFaces];
 223.323 +	
 223.324 +	for(unsigned int a = 0; a < numSubFaces; ++a )	{
 223.325 +
 223.326 +		const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
 223.327 +		aiFace& dstFace = oMesh->mFaces[a];
 223.328 +		dstFace.mNumIndices = srcFace.mNumIndices;
 223.329 +		dstFace.mIndices = new unsigned int[dstFace.mNumIndices];
 223.330 +
 223.331 +		// accumulate linearly all the vertices of the source face
 223.332 +		for( size_t b = 0; b < dstFace.mNumIndices; ++b )	{
 223.333 +			dstFace.mIndices[b] = vMap[srcFace.mIndices[b]];
 223.334 +		}
 223.335 +	}
 223.336 +
 223.337 +	for(unsigned int srcIndex = 0; srcIndex < pMesh->mNumVertices; ++srcIndex ) {
 223.338 +		unsigned int nvi = vMap[srcIndex]; 
 223.339 +		if(nvi==UINT_MAX) {
 223.340 +			continue;
 223.341 +		}
 223.342 +
 223.343 +		oMesh->mVertices[nvi] = pMesh->mVertices[srcIndex];
 223.344 +		if( pMesh->HasNormals() ) {
 223.345 +			oMesh->mNormals[nvi] = pMesh->mNormals[srcIndex];
 223.346 +		}
 223.347 +		
 223.348 +		if( pMesh->HasTangentsAndBitangents() )	{
 223.349 +			oMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
 223.350 +			oMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
 223.351 +		}
 223.352 +		for( size_t c = 0, cc = pMesh->GetNumUVChannels(); c < cc; ++c )	{
 223.353 +				oMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
 223.354 +		}
 223.355 +		for( size_t c = 0, cc = pMesh->GetNumColorChannels(); c < cc; ++c )	{
 223.356 +			oMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
 223.357 +		}
 223.358 +	}
 223.359 +
 223.360 +	if(~subFlags&AI_SUBMESH_FLAGS_SANS_BONES)	{			
 223.361 +		std::vector<unsigned int> subBones(pMesh->mNumBones,0);
 223.362 +
 223.363 +		for(unsigned int a=0;a<pMesh->mNumBones;++a)	{
 223.364 +			const aiBone* bone = pMesh->mBones[a];
 223.365 +
 223.366 +			for(unsigned int b=0;b<bone->mNumWeights;b++)	{
 223.367 +				unsigned int v = vMap[bone->mWeights[b].mVertexId];
 223.368 +
 223.369 +				if(v!=UINT_MAX) {
 223.370 +					subBones[a]++;
 223.371 +				}
 223.372 +			}
 223.373 +		}
 223.374 +
 223.375 +		for(unsigned int a=0;a<pMesh->mNumBones;++a)	{
 223.376 +			if(subBones[a]>0) {
 223.377 +				oMesh->mNumBones++;
 223.378 +			}
 223.379 +		}
 223.380 +
 223.381 +		if(oMesh->mNumBones) {
 223.382 +			oMesh->mBones = new aiBone*[oMesh->mNumBones]();
 223.383 +			unsigned int nbParanoia = oMesh->mNumBones;
 223.384 +
 223.385 +			oMesh->mNumBones = 0; //rewind
 223.386 +
 223.387 +			for(unsigned int a=0;a<pMesh->mNumBones;++a)	{
 223.388 +				if(subBones[a]==0) {
 223.389 +					continue; 
 223.390 +				}
 223.391 +				aiBone *newBone = new aiBone;
 223.392 +				oMesh->mBones[oMesh->mNumBones++] = newBone;
 223.393 +
 223.394 +				const aiBone* bone = pMesh->mBones[a];
 223.395 +
 223.396 +				newBone->mName = bone->mName;
 223.397 +				newBone->mOffsetMatrix = bone->mOffsetMatrix;
 223.398 +				newBone->mWeights = new aiVertexWeight[subBones[a]];
 223.399 +
 223.400 +				for(unsigned int b=0;b<bone->mNumWeights;b++)	{
 223.401 +					const unsigned int v = vMap[bone->mWeights[b].mVertexId];
 223.402 +
 223.403 +					if(v!=UINT_MAX)	{	
 223.404 +						aiVertexWeight w(v,bone->mWeights[b].mWeight);
 223.405 +						newBone->mWeights[newBone->mNumWeights++] = w;
 223.406 +					}
 223.407 +				}
 223.408 +			}
 223.409 +
 223.410 +			ai_assert(nbParanoia==oMesh->mNumBones);
 223.411 +			(void)nbParanoia; // remove compiler warning on release build
 223.412 +		}
 223.413 +	}					 
 223.414 +
 223.415 +	return oMesh;
 223.416 +}
 223.417 +
 223.418 +} // namespace Assimp
   224.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   224.2 +++ b/libs/assimp/ProcessHelper.h	Sat Feb 01 19:58:19 2014 +0200
   224.3 @@ -0,0 +1,367 @@
   224.4 +/*
   224.5 +Open Asset Import Library (assimp)
   224.6 +----------------------------------------------------------------------
   224.7 +
   224.8 +Copyright (c) 2006-2012, assimp team
   224.9 +All rights reserved.
  224.10 +
  224.11 +Redistribution and use of this software in source and binary forms, 
  224.12 +with or without modification, are permitted provided that the 
  224.13 +following conditions are met:
  224.14 +
  224.15 +* Redistributions of source code must retain the above
  224.16 +  copyright notice, this list of conditions and the
  224.17 +  following disclaimer.
  224.18 +
  224.19 +* Redistributions in binary form must reproduce the above
  224.20 +  copyright notice, this list of conditions and the
  224.21 +  following disclaimer in the documentation and/or other
  224.22 +  materials provided with the distribution.
  224.23 +
  224.24 +* Neither the name of the assimp team, nor the names of its
  224.25 +  contributors may be used to endorse or promote products
  224.26 +  derived from this software without specific prior
  224.27 +  written permission of the assimp team.
  224.28 +
  224.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  224.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  224.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  224.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  224.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  224.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  224.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  224.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  224.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  224.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  224.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  224.40 +
  224.41 +----------------------------------------------------------------------
  224.42 +*/
  224.43 +
  224.44 +#ifndef AI_PROCESS_HELPER_H_INCLUDED
  224.45 +#define AI_PROCESS_HELPER_H_INCLUDED
  224.46 +
  224.47 +#include "assimp/postprocess.h"
  224.48 +
  224.49 +#include "SpatialSort.h"
  224.50 +#include "BaseProcess.h"
  224.51 +#include "ParsingUtils.h"
  224.52 +
  224.53 +// -------------------------------------------------------------------------------
  224.54 +// Some extensions to std namespace. Mainly std::min and std::max for all
  224.55 +// flat data types in the aiScene. They're used to quickly determine the
  224.56 +// min/max bounds of data arrays.
  224.57 +#ifdef __cplusplus
  224.58 +namespace std {
  224.59 +
  224.60 +	// std::min for aiVector3D
  224.61 +	template <typename TReal>
  224.62 +	inline ::aiVector3t<TReal> min (const ::aiVector3t<TReal>& a, const ::aiVector3t<TReal>& b)	{
  224.63 +		return ::aiVector3t<TReal> (min(a.x,b.x),min(a.y,b.y),min(a.z,b.z));
  224.64 +	}
  224.65 +
  224.66 +	// std::max for aiVector3t<TReal>
  224.67 +	template <typename TReal>
  224.68 +	inline ::aiVector3t<TReal> max (const ::aiVector3t<TReal>& a, const ::aiVector3t<TReal>& b)	{
  224.69 +		return ::aiVector3t<TReal> (max(a.x,b.x),max(a.y,b.y),max(a.z,b.z));
  224.70 +	}
  224.71 +
  224.72 +	// std::min for aiVector2t<TReal>
  224.73 +	template <typename TReal>
  224.74 +	inline ::aiVector2t<TReal> min (const ::aiVector2t<TReal>& a, const ::aiVector2t<TReal>& b)	{
  224.75 +		return ::aiVector2t<TReal> (min(a.x,b.x),min(a.y,b.y));
  224.76 +	}
  224.77 +
  224.78 +	// std::max for aiVector2t<TReal>
  224.79 +	template <typename TReal>
  224.80 +	inline ::aiVector2t<TReal> max (const ::aiVector2t<TReal>& a, const ::aiVector2t<TReal>& b)	{
  224.81 +		return ::aiVector2t<TReal> (max(a.x,b.x),max(a.y,b.y));
  224.82 +	}
  224.83 +
  224.84 +	// std::min for aiColor4D
  224.85 +	template <typename TReal>
  224.86 +	inline ::aiColor4t<TReal> min (const ::aiColor4t<TReal>& a, const ::aiColor4t<TReal>& b)	{
  224.87 +		return ::aiColor4t<TReal> (min(a.r,b.r),min(a.g,b.g),min(a.b,b.b),min(a.a,b.a));
  224.88 +	}
  224.89 +
  224.90 +	// std::max for aiColor4D
  224.91 +	template <typename TReal>
  224.92 +	inline ::aiColor4t<TReal> max (const ::aiColor4t<TReal>& a, const ::aiColor4t<TReal>& b)	{
  224.93 +		return ::aiColor4t<TReal> (max(a.r,b.r),max(a.g,b.g),max(a.b,b.b),max(a.a,b.a));
  224.94 +	}
  224.95 +
  224.96 +
  224.97 +	// std::min for aiQuaterniont<TReal>
  224.98 +	template <typename TReal>
  224.99 +	inline ::aiQuaterniont<TReal> min (const ::aiQuaterniont<TReal>& a, const ::aiQuaterniont<TReal>& b)	{
 224.100 +		return ::aiQuaterniont<TReal> (min(a.w,b.w),min(a.x,b.x),min(a.y,b.y),min(a.z,b.z));
 224.101 +	}
 224.102 +
 224.103 +	// std::max for aiQuaterniont<TReal>
 224.104 +	template <typename TReal>
 224.105 +	inline ::aiQuaterniont<TReal> max (const ::aiQuaterniont<TReal>& a, const ::aiQuaterniont<TReal>& b)	{
 224.106 +		return ::aiQuaterniont<TReal> (max(a.w,b.w),max(a.x,b.x),max(a.y,b.y),max(a.z,b.z));
 224.107 +	}
 224.108 +
 224.109 +
 224.110 +
 224.111 +	// std::min for aiVectorKey
 224.112 +	inline ::aiVectorKey min (const ::aiVectorKey& a, const ::aiVectorKey& b)	{
 224.113 +		return ::aiVectorKey (min(a.mTime,b.mTime),min(a.mValue,b.mValue));
 224.114 +	}
 224.115 +
 224.116 +	// std::max for aiVectorKey
 224.117 +	inline ::aiVectorKey max (const ::aiVectorKey& a, const ::aiVectorKey& b)	{
 224.118 +		return ::aiVectorKey (max(a.mTime,b.mTime),max(a.mValue,b.mValue));
 224.119 +	}
 224.120 +
 224.121 +	// std::min for aiQuatKey
 224.122 +	inline ::aiQuatKey min (const ::aiQuatKey& a, const ::aiQuatKey& b)	{
 224.123 +		return ::aiQuatKey (min(a.mTime,b.mTime),min(a.mValue,b.mValue));
 224.124 +	}
 224.125 +
 224.126 +	// std::max for aiQuatKey
 224.127 +	inline ::aiQuatKey max (const ::aiQuatKey& a, const ::aiQuatKey& b)	{
 224.128 +		return ::aiQuatKey (max(a.mTime,b.mTime),max(a.mValue,b.mValue));
 224.129 +	}
 224.130 +
 224.131 +	// std::min for aiVertexWeight
 224.132 +	inline ::aiVertexWeight min (const ::aiVertexWeight& a, const ::aiVertexWeight& b)	{
 224.133 +		return ::aiVertexWeight (min(a.mVertexId,b.mVertexId),min(a.mWeight,b.mWeight));
 224.134 +	}
 224.135 +
 224.136 +	// std::max for aiVertexWeight
 224.137 +	inline ::aiVertexWeight max (const ::aiVertexWeight& a, const ::aiVertexWeight& b)	{
 224.138 +		return ::aiVertexWeight (max(a.mVertexId,b.mVertexId),max(a.mWeight,b.mWeight));
 224.139 +	}
 224.140 +
 224.141 +} // end namespace std
 224.142 +#endif // !! C++
 224.143 +
 224.144 +namespace Assimp {
 224.145 +
 224.146 +// -------------------------------------------------------------------------------
 224.147 +// Start points for ArrayBounds<T> for all supported Ts
 224.148 +template <typename T>
 224.149 +struct MinMaxChooser;
 224.150 +
 224.151 +template <> struct MinMaxChooser<float> {
 224.152 +	void operator ()(float& min,float& max) {
 224.153 +		max = -1e10f;
 224.154 +		min =  1e10f;
 224.155 +}};
 224.156 +template <> struct MinMaxChooser<double> {
 224.157 +	void operator ()(double& min,double& max) {
 224.158 +		max = -1e10;
 224.159 +		min =  1e10;
 224.160 +}};
 224.161 +template <> struct MinMaxChooser<unsigned int> {
 224.162 +	void operator ()(unsigned int& min,unsigned int& max) {
 224.163 +		max = 0;
 224.164 +		min = (1u<<(sizeof(unsigned int)*8-1));
 224.165 +}};
 224.166 +
 224.167 +template <typename T> struct MinMaxChooser< aiVector3t<T> > {
 224.168 +	void operator ()(aiVector3t<T>& min,aiVector3t<T>& max) {
 224.169 +		max = aiVector3t<T>(-1e10f,-1e10f,-1e10f);
 224.170 +		min = aiVector3t<T>( 1e10f, 1e10f, 1e10f);
 224.171 +}};
 224.172 +template <typename T> struct MinMaxChooser< aiVector2t<T> > {
 224.173 +	void operator ()(aiVector2t<T>& min,aiVector2t<T>& max) {
 224.174 +		max = aiVector2t<T>(-1e10f,-1e10f);
 224.175 +		min = aiVector2t<T>( 1e10f, 1e10f);
 224.176 +	}};
 224.177 +template <typename T> struct MinMaxChooser< aiColor4t<T> > {
 224.178 +	void operator ()(aiColor4t<T>& min,aiColor4t<T>& max) {
 224.179 +		max = aiColor4t<T>(-1e10f,-1e10f,-1e10f,-1e10f);
 224.180 +		min = aiColor4t<T>( 1e10f, 1e10f, 1e10f, 1e10f);
 224.181 +}};
 224.182 +
 224.183 +template <typename T> struct MinMaxChooser< aiQuaterniont<T> > {
 224.184 +	void operator ()(aiQuaterniont<T>& min,aiQuaterniont<T>& max) {
 224.185 +		max = aiQuaterniont<T>(-1e10f,-1e10f,-1e10f,-1e10f);
 224.186 +		min = aiQuaterniont<T>( 1e10f, 1e10f, 1e10f, 1e10f);
 224.187 +}};
 224.188 +
 224.189 +template <> struct MinMaxChooser<aiVectorKey> {
 224.190 +	void operator ()(aiVectorKey& min,aiVectorKey& max) {
 224.191 +		MinMaxChooser<double>()(min.mTime,max.mTime);
 224.192 +		MinMaxChooser<aiVector3D>()(min.mValue,max.mValue);
 224.193 +}};
 224.194 +template <> struct MinMaxChooser<aiQuatKey> {
 224.195 +	void operator ()(aiQuatKey& min,aiQuatKey& max) {
 224.196 +		MinMaxChooser<double>()(min.mTime,max.mTime);
 224.197 +		MinMaxChooser<aiQuaternion>()(min.mValue,max.mValue);
 224.198 +}};
 224.199 +
 224.200 +template <> struct MinMaxChooser<aiVertexWeight> {
 224.201 +	void operator ()(aiVertexWeight& min,aiVertexWeight& max) {
 224.202 +		MinMaxChooser<unsigned int>()(min.mVertexId,max.mVertexId);
 224.203 +		MinMaxChooser<float>()(min.mWeight,max.mWeight);
 224.204 +}};
 224.205 +
 224.206 +// -------------------------------------------------------------------------------
 224.207 +/** @brief Find the min/max values of an array of Ts
 224.208 + *  @param in Input array
 224.209 + *  @param size Numebr of elements to process
 224.210 + *  @param[out] min minimum value
 224.211 + *  @param[out] max maximum value
 224.212 + */
 224.213 +template <typename T>
 224.214 +inline void ArrayBounds(const T* in, unsigned int size, T& min, T& max) 
 224.215 +{
 224.216 +	MinMaxChooser<T> ()(min,max);
 224.217 +	for (unsigned int i = 0; i < size;++i) {
 224.218 +		min = std::min(in[i],min);
 224.219 +		max = std::max(in[i],max);
 224.220 +	}
 224.221 +}
 224.222 +
 224.223 +
 224.224 +// -------------------------------------------------------------------------------
 224.225 +/** Little helper function to calculate the quadratic difference 
 224.226 + * of two colours. 
 224.227 + * @param pColor1 First color
 224.228 + * @param pColor2 second color
 224.229 + * @return Quadratic color difference */
 224.230 +inline float GetColorDifference( const aiColor4D& pColor1, const aiColor4D& pColor2) 
 224.231 +{
 224.232 +	const aiColor4D c (pColor1.r - pColor2.r, pColor1.g - pColor2.g, pColor1.b - pColor2.b, pColor1.a - pColor2.a);
 224.233 +	return c.r*c.r + c.g*c.g + c.b*c.b + c.a*c.a;
 224.234 +}
 224.235 +
 224.236 +
 224.237 +// -------------------------------------------------------------------------------
 224.238 +/** @brief Extract single strings from a list of identifiers
 224.239 + *  @param in Input string list. 
 224.240 + *  @param out Receives a list of clean output strings
 224.241 + *  @sdee #AI_CONFIG_PP_OG_EXCLUDE_LIST */
 224.242 +void ConvertListToStrings(const std::string& in, std::list<std::string>& out);
 224.243 +
 224.244 +
 224.245 +// -------------------------------------------------------------------------------
 224.246 +/** @brief Compute the AABB of a mesh after applying a given transform
 224.247 + *  @param mesh Input mesh
 224.248 + *  @param[out] min Receives minimum transformed vertex
 224.249 + *  @param[out] max Receives maximum transformed vertex
 224.250 + *  @param m Transformation matrix to be applied */
 224.251 +void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max, const aiMatrix4x4& m);
 224.252 +
 224.253 +
 224.254 +// -------------------------------------------------------------------------------
 224.255 +/** @brief Helper function to determine the 'real' center of a mesh
 224.256 + *
 224.257 + *  That is the center of its axis-aligned bounding box.
 224.258 + *  @param mesh Input mesh
 224.259 + *  @param[out] min Minimum vertex of the mesh
 224.260 + *  @param[out] max maximum vertex of the mesh
 224.261 + *  @param[out] out Center point */
 224.262 +void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max);
 224.263 +
 224.264 +
 224.265 +// -------------------------------------------------------------------------------
 224.266 +// Helper function to determine the 'real' center of a mesh after applying a given transform
 224.267 +void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min,aiVector3D& max, const aiMatrix4x4& m);
 224.268 +
 224.269 +
 224.270 +// -------------------------------------------------------------------------------
 224.271 +// Helper function to determine the 'real' center of a mesh
 224.272 +void FindMeshCenter (aiMesh* mesh, aiVector3D& out);
 224.273 +
 224.274 +
 224.275 +// -------------------------------------------------------------------------------
 224.276 +// Helper function to determine the 'real' center of a mesh after applying a given transform
 224.277 +void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out,const aiMatrix4x4& m);
 224.278 +
 224.279 +
 224.280 +// -------------------------------------------------------------------------------
 224.281 +// Compute a good epsilon value for position comparisons on a mesh
 224.282 +float ComputePositionEpsilon(const aiMesh* pMesh);
 224.283 +
 224.284 +
 224.285 +// -------------------------------------------------------------------------------
 224.286 +// Compute a good epsilon value for position comparisons on a array of meshes
 224.287 +float ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num);
 224.288 +
 224.289 +
 224.290 +// -------------------------------------------------------------------------------
 224.291 +// Compute an unique value for the vertex format of a mesh
 224.292 +unsigned int GetMeshVFormatUnique(const aiMesh* pcMesh);
 224.293 +
 224.294 +
 224.295 +// defs for ComputeVertexBoneWeightTable()
 224.296 +typedef std::pair <unsigned int,float> PerVertexWeight;
 224.297 +typedef std::vector	<PerVertexWeight> VertexWeightTable;
 224.298 +
 224.299 +// -------------------------------------------------------------------------------
 224.300 +// Compute a per-vertex bone weight table
 224.301 +VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh);
 224.302 +
 224.303 +
 224.304 +// -------------------------------------------------------------------------------
 224.305 +// Get a string for a given aiTextureType
 224.306 +const char* TextureTypeToString(aiTextureType in);
 224.307 +
 224.308 +
 224.309 +// -------------------------------------------------------------------------------
 224.310 +// Get a string for a given aiTextureMapping
 224.311 +const char* MappingTypeToString(aiTextureMapping in);
 224.312 +
 224.313 +
 224.314 +// flags for MakeSubmesh()
 224.315 +#define AI_SUBMESH_FLAGS_SANS_BONES	0x1
 224.316 +
 224.317 +// -------------------------------------------------------------------------------
 224.318 +// Split a mesh given a list of faces to be contained in the sub mesh
 224.319 +aiMesh* MakeSubmesh(const aiMesh *superMesh, const std::vector<unsigned int> &subMeshFaces, unsigned int subFlags);
 224.320 +
 224.321 +// -------------------------------------------------------------------------------
 224.322 +// Utility postprocess step to share the spatial sort tree between
 224.323 +// all steps which use it to speedup its computations.
 224.324 +class ComputeSpatialSortProcess : public BaseProcess
 224.325 +{
 224.326 +	bool IsActive( unsigned int pFlags) const
 224.327 +	{
 224.328 +		return NULL != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace | 
 224.329 +			aiProcess_GenNormals | aiProcess_JoinIdenticalVertices));
 224.330 +	}
 224.331 +
 224.332 +	void Execute( aiScene* pScene)
 224.333 +	{
 224.334 +		typedef std::pair<SpatialSort, float> _Type; 
 224.335 +		DefaultLogger::get()->debug("Generate spatially-sorted vertex cache");
 224.336 +
 224.337 +		std::vector<_Type>* p = new std::vector<_Type>(pScene->mNumMeshes); 
 224.338 +		std::vector<_Type>::iterator it = p->begin();
 224.339 +
 224.340 +		for (unsigned int i = 0; i < pScene->mNumMeshes; ++i, ++it)	{
 224.341 +			aiMesh* mesh = pScene->mMeshes[i];
 224.342 +			_Type& blubb = *it;
 224.343 +			blubb.first.Fill(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D));
 224.344 +			blubb.second = ComputePositionEpsilon(mesh);
 224.345 +		}
 224.346 +
 224.347 +		shared->AddProperty(AI_SPP_SPATIAL_SORT,p);
 224.348 +	}
 224.349 +};
 224.350 +
 224.351 +// -------------------------------------------------------------------------------
 224.352 +// ... and the same again to cleanup the whole stuff
 224.353 +class DestroySpatialSortProcess : public BaseProcess
 224.354 +{
 224.355 +	bool IsActive( unsigned int pFlags) const
 224.356 +	{
 224.357 +		return NULL != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace | 
 224.358 +			aiProcess_GenNormals | aiProcess_JoinIdenticalVertices));
 224.359 +	}
 224.360 +
 224.361 +	void Execute( aiScene* /*pScene*/)
 224.362 +	{
 224.363 +		shared->RemoveProperty(AI_SPP_SPATIAL_SORT);
 224.364 +	}
 224.365 +};
 224.366 +
 224.367 +
 224.368 +
 224.369 +} // ! namespace Assimp
 224.370 +#endif // !! AI_PROCESS_HELPER_H_INCLUDED
   225.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   225.2 +++ b/libs/assimp/Profiler.h	Sat Feb 01 19:58:19 2014 +0200
   225.3 @@ -0,0 +1,97 @@
   225.4 +/*
   225.5 +Open Asset Import Library (assimp)
   225.6 +----------------------------------------------------------------------
   225.7 +
   225.8 +Copyright (c) 2006-2012, assimp team
   225.9 +All rights reserved.
  225.10 +
  225.11 +Redistribution and use of this software in source and binary forms, 
  225.12 +with or without modification, are permitted provided that the 
  225.13 +following conditions are met:
  225.14 +
  225.15 +* Redistributions of source code must retain the above
  225.16 +  copyright notice, this list of conditions and the
  225.17 +  following disclaimer.
  225.18 +
  225.19 +* Redistributions in binary form must reproduce the above
  225.20 +  copyright notice, this list of conditions and the
  225.21 +  following disclaimer in the documentation and/or other
  225.22 +  materials provided with the distribution.
  225.23 +
  225.24 +* Neither the name of the assimp team, nor the names of its
  225.25 +  contributors may be used to endorse or promote products
  225.26 +  derived from this software without specific prior
  225.27 +  written permission of the assimp team.
  225.28 +
  225.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  225.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  225.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  225.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  225.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  225.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  225.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  225.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  225.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  225.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  225.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  225.40 +
  225.41 +----------------------------------------------------------------------
  225.42 +*/
  225.43 +
  225.44 +/** @file Profiler.h
  225.45 + *  @brief Utility to measure the respective runtime of each import step
  225.46 + */
  225.47 +#ifndef INCLUDED_PROFILER_H
  225.48 +#define INCLUDED_PROFILER_H
  225.49 +
  225.50 +#include "boost/timer.hpp"
  225.51 +
  225.52 +#include "assimp/DefaultLogger.hpp"
  225.53 +#include "TinyFormatter.h"
  225.54 +
  225.55 +namespace Assimp {
  225.56 +	namespace Profiling {
  225.57 +
  225.58 +		using namespace Formatter;
  225.59 +
  225.60 +
  225.61 +// ------------------------------------------------------------------------------------------------
  225.62 +/** Simple wrapper around boost::timer to simplify reporting. Timings are automatically
  225.63 + *  dumped to the log file.
  225.64 + */
  225.65 +class Profiler
  225.66 +{
  225.67 +
  225.68 +public:
  225.69 +
  225.70 +	Profiler() {}
  225.71 +
  225.72 +public:
  225.73 +	
  225.74 +	/** Start a named timer */
  225.75 +	void BeginRegion(const std::string& region) {
  225.76 +		regions[region] = boost::timer();
  225.77 +		DefaultLogger::get()->debug((format("START `"),region,"`"));
  225.78 +	}
  225.79 +	
  225.80 +	
  225.81 +	/** End a specific named timer and write its end time to the log */
  225.82 +	void EndRegion(const std::string& region) {
  225.83 +		RegionMap::const_iterator it = regions.find(region);
  225.84 +		if (it == regions.end()) {
  225.85 +			return;
  225.86 +		}
  225.87 +
  225.88 +		DefaultLogger::get()->debug((format("END   `"),region,"`, dt= ",(*it).second.elapsed()," s"));
  225.89 +	}
  225.90 +
  225.91 +private:
  225.92 +
  225.93 +	typedef std::map<std::string,boost::timer> RegionMap;
  225.94 +	RegionMap regions;
  225.95 +};
  225.96 +
  225.97 +	}
  225.98 +}
  225.99 +
 225.100 +#endif
   226.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   226.2 +++ b/libs/assimp/Q3BSPFileData.h	Sat Feb 01 19:58:19 2014 +0200
   226.3 @@ -0,0 +1,228 @@
   226.4 +/*
   226.5 +Open Asset Import Library (assimp)
   226.6 +----------------------------------------------------------------------
   226.7 +
   226.8 +Copyright (c) 2006-2008, assimp team
   226.9 +All rights reserved.
  226.10 +
  226.11 +Redistribution and use of this software in source and binary forms, 
  226.12 +with or without modification, are permitted provided that the 
  226.13 +following conditions are met:
  226.14 +
  226.15 +* Redistributions of source code must retain the above
  226.16 +  copyright notice, this list of conditions and the
  226.17 +  following disclaimer.
  226.18 +
  226.19 +* Redistributions in binary form must reproduce the above
  226.20 +  copyright notice, this list of conditions and the
  226.21 +  following disclaimer in the documentation and/or other
  226.22 +  materials provided with the distribution.
  226.23 +
  226.24 +* Neither the name of the assimp team, nor the names of its
  226.25 +  contributors may be used to endorse or promote products
  226.26 +  derived from this software without specific prior
  226.27 +  written permission of the assimp team.
  226.28 +
  226.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  226.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  226.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  226.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  226.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  226.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  226.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  226.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  226.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  226.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  226.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  226.40 +
  226.41 +----------------------------------------------------------------------
  226.42 +*/
  226.43 +#ifndef ASSIMP_Q3BSPFILEDATA_H_INC
  226.44 +#define ASSIMP_Q3BSPFILEDATA_H_INC
  226.45 +
  226.46 +#include <vector>
  226.47 +
  226.48 +namespace Assimp
  226.49 +{
  226.50 +namespace Q3BSP
  226.51 +{
  226.52 +
  226.53 +static const unsigned int CE_BSP_LIGHTMAPWIDTH = 128;
  226.54 +static const unsigned int CE_BSP_LIGHTMAPHEIGHT = 128;
  226.55 +
  226.56 +static const unsigned int CE_BSP_LIGHTMAPSIZE = 128*128*3;	///< = 128( width ) * 128 ( height ) * 3 ( channels / RGB ).
  226.57 +static const int VERION_Q3LEVEL = 46;						///< Supported version.
  226.58 +
  226.59 +///	Geometric type enumeration
  226.60 +enum Q3BSPGeoType
  226.61 +{
  226.62 +	Polygon = 1,
  226.63 +	Patch, 
  226.64 +	TriangleMesh,
  226.65 +	Billboard 
  226.66 +};
  226.67 +
  226.68 +///	Integer vector.
  226.69 +struct ceVec3i 
  226.70 +{
  226.71 +    int x, y, z;
  226.72 +	ceVec3i(): x( 0 ), y( 0 ), z( 0 ) { /* empty */ }
  226.73 +	ceVec3i( int iX, int iY=0, int iZ=0) : x( iX ), y( iY ), z( iZ ) { /* empty */ }
  226.74 +};
  226.75 +
  226.76 +///	Fileheader
  226.77 +struct sQ3BSPHeader 
  226.78 +{
  226.79 +	char strID[ 4 ];	//!< Should be "IBSP"
  226.80 +	int iVersion;	//!< 46 for standard levels
  226.81 +};
  226.82 +
  226.83 +///	Descripes an entry.
  226.84 +struct sQ3BSPLump 
  226.85 +{
  226.86 +	int iOffset;	///< Offset from startpointer of file
  226.87 +	int iSize;		///< Size fo part
  226.88 +};
  226.89 +
  226.90 +struct vec2f
  226.91 +{
  226.92 +	float x,y;
  226.93 +};
  226.94 +
  226.95 +struct vec3f
  226.96 +{
  226.97 +	float x, y, z;
  226.98 +};
  226.99 +
 226.100 +///	Vertex of a Q3 level
 226.101 +struct sQ3BSPVertex 
 226.102 +{
 226.103 +	vec3f vPosition;	///< Position of vertex
 226.104 +	vec2f vTexCoord;	///< (u,v) Texturecoordinate of detailtexture
 226.105 +	vec2f vLightmap;	///< (u,v) Texturecoordinate of lightmap
 226.106 +	vec3f vNormal;		///< vertex normale
 226.107 +	unsigned char bColor[ 4 ];			///< Color in RGBA
 226.108 +};
 226.109 +
 226.110 +///	A face in bsp format info
 226.111 +struct sQ3BSPFace 
 226.112 +{
 226.113 +	int iTextureID;					///< Index in texture array
 226.114 +	int iEffect;					///< Index in effectarray (-1 = no effect)
 226.115 +	int iType;						///< 1=Polygon, 2=Patch, 3=Mesh, 4=Billboard
 226.116 +	int iVertexIndex;				///< Start index of polygon
 226.117 +	int iNumOfVerts;				///< Number of vertices
 226.118 +	int	iFaceVertexIndex;			///< Index of first mesh vertex
 226.119 +	int iNumOfFaceVerts;			///< Anzahl der Meshvertices
 226.120 +	int iLightmapID;				///< Index to the lightmap array
 226.121 +	int iLMapCorner[ 2 ];			///< Die Ecke der Lightmap in der Textur
 226.122 +	int iLMapSize[ 2 ];				///< Size of the lightmap stored on the texture
 226.123 +	vec3f vLMapPos;					///< 3D-Ursprung der Lightmap
 226.124 +	vec3f vLMapVecs[ 2 ];			///< 3D-s-t-Vektoren
 226.125 +	vec3f vNormal;					///< Polygonnormale
 226.126 +	int patchWidth, patchHeight;	///< bezier patch
 226.127 +};
 226.128 +
 226.129 +/// A quake3 texture name.
 226.130 +struct sQ3BSPTexture 
 226.131 +{
 226.132 +	char strName[ 64 ];		///< Name of the texture without extention
 226.133 +	int iFlags;				///< Not used
 226.134 +	int iContents;			///< Not used
 226.135 +};
 226.136 +
 226.137 +///	A lightmap of the level, size 128 x 128, RGB components.
 226.138 +struct sQ3BSPLightmap 
 226.139 +{
 226.140 +	unsigned char bLMapData[ CE_BSP_LIGHTMAPSIZE ];
 226.141 +	sQ3BSPLightmap() 
 226.142 +	{	
 226.143 +		memset(bLMapData, 0, CE_BSP_LIGHTMAPSIZE ); 
 226.144 +	}
 226.145 +};
 226.146 +
 226.147 +struct SubPatch
 226.148 +{
 226.149 +	std::vector<size_t> indices;
 226.150 +	int lightmapID;
 226.151 +};
 226.152 +
 226.153 +enum eLumps 
 226.154 +{
 226.155 +	kEntities = 0,
 226.156 +	kTextures,
 226.157 +	kPlanes,
 226.158 +	kNodes,
 226.159 +	kLeafs,
 226.160 +	kLeafFaces,
 226.161 +	kLeafBrushes,
 226.162 +	kModels,
 226.163 +	kBrushes,
 226.164 +	kBrushSides,
 226.165 +	kVertices,
 226.166 +	kMeshVerts,
 226.167 +	kShaders,
 226.168 +	kFaces,
 226.169 +	kLightmaps,
 226.170 +	kLightVolumes,
 226.171 +	kVisData,
 226.172 +	kMaxLumps
 226.173 +};
 226.174 +
 226.175 +struct Q3BSPModel
 226.176 +{
 226.177 +	std::vector<unsigned char> m_Data;
 226.178 +	std::vector<sQ3BSPLump*> m_Lumps;
 226.179 +	std::vector<sQ3BSPVertex*> m_Vertices;
 226.180 +	std::vector<sQ3BSPFace*> m_Faces;
 226.181 +	std::vector<int> m_Indices;
 226.182 +	std::vector<sQ3BSPTexture*> m_Textures;
 226.183 +	std::vector<sQ3BSPLightmap*> m_Lightmaps;
 226.184 +	std::vector<char> m_EntityData;
 226.185 +	std::string m_ModelName;
 226.186 +
 226.187 +	Q3BSPModel() :
 226.188 +		m_Data(),
 226.189 +		m_Lumps(),
 226.190 +		m_Vertices(),
 226.191 +		m_Faces(),
 226.192 +		m_Indices(),
 226.193 +		m_Textures(),
 226.194 +		m_Lightmaps(),
 226.195 +		m_EntityData(),
 226.196 +		m_ModelName( "" )
 226.197 +	{
 226.198 +		// empty
 226.199 +	}
 226.200 +
 226.201 +	~Q3BSPModel()
 226.202 +	{
 226.203 +		for ( unsigned int i=0; i<m_Lumps.size(); i++ )
 226.204 +			if ( NULL != m_Lumps[i] )
 226.205 +				delete m_Lumps[i];
 226.206 +		
 226.207 +		for ( unsigned int i=0; i<m_Vertices.size(); i++ )
 226.208 +			if ( NULL != m_Vertices[ i ] )
 226.209 +				delete m_Vertices[ i ];
 226.210 +		for ( unsigned int i=0; i<m_Faces.size(); i++ )
 226.211 +			if ( NULL != m_Faces[ i ] )
 226.212 +				delete m_Faces[ i ];
 226.213 +		for ( unsigned int i=0; i<m_Textures.size(); i++ )
 226.214 +			if ( NULL != m_Textures[ i ] )
 226.215 +				delete m_Textures[ i ];
 226.216 +		for ( unsigned int i=0; i<m_Lightmaps.size(); i++ )
 226.217 +			if ( NULL != m_Lightmaps[ i ] )
 226.218 +				delete m_Lightmaps[ i ];
 226.219 +
 226.220 +		m_Lumps.clear();
 226.221 +		m_Vertices.clear();
 226.222 +		m_Faces.clear();
 226.223 +		m_Textures.clear();
 226.224 +		m_Lightmaps.clear();
 226.225 +	}
 226.226 +};
 226.227 +
 226.228 +} // Namespace Q3BSP
 226.229 +} // Namespace Assimp
 226.230 +
 226.231 +#endif // ASSIMP_Q3BSPFILEDATA_H_INC
   227.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   227.2 +++ b/libs/assimp/Q3BSPFileImporter.cpp	Sat Feb 01 19:58:19 2014 +0200
   227.3 @@ -0,0 +1,787 @@
   227.4 +/*
   227.5 +Open Asset Import Library (assimp)
   227.6 +---------------------------------------------------------------------------------------------------
   227.7 +
   227.8 +Copyright (c) 2006-2008, assimp team
   227.9 +All rights reserved.
  227.10 +
  227.11 +Redistribution and use of this software in source and binary forms, 
  227.12 +with or without modification, are permitted provided that the 
  227.13 +following conditions are met:
  227.14 +
  227.15 +* Redistributions of source code must retain the above
  227.16 +  copyright notice, this list of conditions and the
  227.17 +  following disclaimer.
  227.18 +
  227.19 +* Redistributions in binary form must reproduce the above
  227.20 +  copyright notice, this list of conditions and the
  227.21 +  following disclaimer in the documentation and/or other
  227.22 +  materials provided with the distribution.
  227.23 +
  227.24 +* Neither the name of the assimp team, nor the names of its
  227.25 +  contributors may be used to endorse or promote products
  227.26 +  derived from this software without specific prior
  227.27 +  written permission of the assimp team.
  227.28 +
  227.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  227.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  227.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  227.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  227.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  227.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  227.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  227.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  227.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  227.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  227.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  227.40 +
  227.41 +---------------------------------------------------------------------------------------------------
  227.42 +*/
  227.43 +#include "AssimpPCH.h"
  227.44 +#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
  227.45 +
  227.46 +//#include <windows.h> 
  227.47 +#include "DefaultIOSystem.h"
  227.48 +#include "Q3BSPFileImporter.h"
  227.49 +#include "Q3BSPZipArchive.h"
  227.50 +#include "Q3BSPFileParser.h"
  227.51 +#include "Q3BSPFileData.h"
  227.52 +
  227.53 +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
  227.54 +#	include <zlib.h>
  227.55 +#else
  227.56 +#	include "../contrib/zlib/zlib.h"
  227.57 +#endif
  227.58 +
  227.59 +#include "assimp/types.h"
  227.60 +#include "assimp/mesh.h"
  227.61 +#include <vector>
  227.62 +
  227.63 +
  227.64 +static const aiImporterDesc desc = {
  227.65 +	"Quake III BSP Importer",
  227.66 +	"",
  227.67 +	"",
  227.68 +	"",
  227.69 +	aiImporterFlags_SupportBinaryFlavour,
  227.70 +	0,
  227.71 +	0,
  227.72 +	0,
  227.73 +	0,
  227.74 +	"pk3"
  227.75 +};
  227.76 +
  227.77 +namespace Assimp
  227.78 +{
  227.79 +
  227.80 +using namespace Q3BSP;
  227.81 +
  227.82 +// ------------------------------------------------------------------------------------------------
  227.83 +//	Local function to create a material key name.
  227.84 +static void createKey( int id1, int id2, std::string &rKey )
  227.85 +{
  227.86 +	std::ostringstream str;
  227.87 +	str << id1 << "." << id2;
  227.88 +	rKey = str.str();
  227.89 +}
  227.90 +
  227.91 +// ------------------------------------------------------------------------------------------------
  227.92 +//	Local function to extract the texture ids from a material keyname.
  227.93 +static void extractIds( const std::string &rKey, int &rId1, int &rId2 )
  227.94 +{
  227.95 +	rId1 = -1;
  227.96 +	rId2 = -1;
  227.97 +	if ( rKey.empty() )
  227.98 +		return;
  227.99 +
 227.100 +	std::string::size_type pos = rKey.find( "." );
 227.101 +	if ( std::string::npos == pos )
 227.102 +		return;
 227.103 +
 227.104 +	std::string tmp1 = rKey.substr( 0, pos );
 227.105 +	std::string tmp2 = rKey.substr( pos + 1, rKey.size() - pos - 1 );
 227.106 +	rId1 = atoi( tmp1.c_str() );
 227.107 +	rId2 = atoi( tmp2.c_str() );
 227.108 +}
 227.109 +
 227.110 +// ------------------------------------------------------------------------------------------------
 227.111 +//	Local helper function to normalize filenames.
 227.112 +static void normalizePathName( const std::string &rPath, std::string &rNormalizedPath )
 227.113 +{
 227.114 +	rNormalizedPath = "";
 227.115 +	if ( rPath.empty() )
 227.116 +		return;
 227.117 +
 227.118 +#ifdef _WIN32
 227.119 +	std::string sep = "\\";
 227.120 +#else
 227.121 +	std::string sep = "/";
 227.122 +#endif
 227.123 +
 227.124 +	static const unsigned int numDelimiters = 2;
 227.125 +	const char delimiters[ numDelimiters ] = { '/', '\\' };
 227.126 +	rNormalizedPath = rPath;
 227.127 +	for ( unsigned int i=0; i<numDelimiters; i++ )
 227.128 +	{
 227.129 +		for ( size_t j=0; j<rNormalizedPath.size(); j++ )
 227.130 +		{
 227.131 +			if ( rNormalizedPath[j] == delimiters[ i ] )
 227.132 +			{
 227.133 +				rNormalizedPath[ j ] = sep[ 0 ];
 227.134 +			}
 227.135 +		}
 227.136 +	}
 227.137 +}
 227.138 +
 227.139 +// ------------------------------------------------------------------------------------------------
 227.140 +//	Constructor.
 227.141 +Q3BSPFileImporter::Q3BSPFileImporter() :
 227.142 +	m_pCurrentMesh( NULL ),
 227.143 +	m_pCurrentFace( NULL ),
 227.144 +	m_MaterialLookupMap(),
 227.145 +	mTextures()
 227.146 +{
 227.147 +	// empty
 227.148 +}
 227.149 +
 227.150 +// ------------------------------------------------------------------------------------------------
 227.151 +//	Destructor.
 227.152 +Q3BSPFileImporter::~Q3BSPFileImporter()
 227.153 +{
 227.154 +	// For lint
 227.155 +	m_pCurrentMesh = NULL;
 227.156 +	m_pCurrentFace = NULL;
 227.157 +	
 227.158 +	// Clear face-to-material map
 227.159 +	for ( FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end();
 227.160 +		++it )
 227.161 +	{
 227.162 +		const std::string matName = (*it).first;
 227.163 +		if ( matName.empty() )
 227.164 +		{
 227.165 +			continue;
 227.166 +		}
 227.167 +
 227.168 +		std::vector<Q3BSP::sQ3BSPFace*> *pCurFaceArray = (*it).second;
 227.169 +		delete pCurFaceArray;
 227.170 +	}
 227.171 +	m_MaterialLookupMap.clear();
 227.172 +}
 227.173 +
 227.174 +// ------------------------------------------------------------------------------------------------
 227.175 +//	Returns true, if the loader can read this.
 227.176 +bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const
 227.177 +{
 227.178 +	if(!checkSig) {
 227.179 +		return SimpleExtensionCheck( rFile, "pk3" );
 227.180 +	}
 227.181 +	// TODO perhaps add keyword based detection
 227.182 +	return false;
 227.183 +}
 227.184 +
 227.185 +// ------------------------------------------------------------------------------------------------
 227.186 +//	Adds extensions.
 227.187 +const aiImporterDesc* Q3BSPFileImporter::GetInfo () const
 227.188 +{
 227.189 +	return &desc;
 227.190 +}
 227.191 +
 227.192 +// ------------------------------------------------------------------------------------------------
 227.193 +//	Import method.
 227.194 +void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* /*pIOHandler*/)
 227.195 +{
 227.196 +	Q3BSPZipArchive Archive( rFile );
 227.197 +	if ( !Archive.isOpen() )
 227.198 +	{
 227.199 +		throw DeadlyImportError( "Failed to open file " + rFile + "." );
 227.200 +	}
 227.201 +
 227.202 +	std::string archiveName( "" ), mapName( "" );
 227.203 +	separateMapName( rFile, archiveName, mapName );
 227.204 +
 227.205 +	if ( mapName.empty() )
 227.206 +	{
 227.207 +		if ( !findFirstMapInArchive( Archive, mapName ) )
 227.208 +		{
 227.209 +			return;
 227.210 +		}
 227.211 +	}
 227.212 +
 227.213 +	Q3BSPFileParser fileParser( mapName, &Archive );
 227.214 +	Q3BSPModel *pBSPModel = fileParser.getModel();
 227.215 +	if ( NULL != pBSPModel )
 227.216 +	{
 227.217 +		CreateDataFromImport( pBSPModel, pScene, &Archive );
 227.218 +	}
 227.219 +}
 227.220 +
 227.221 +// ------------------------------------------------------------------------------------------------
 227.222 +//	Separates the map name from the import name.
 227.223 +void Q3BSPFileImporter::separateMapName( const std::string &rImportName, std::string &rArchiveName, 
 227.224 +										std::string &rMapName )
 227.225 +{
 227.226 +	rArchiveName = "";
 227.227 +	rMapName = "";
 227.228 +	if ( rImportName.empty() )
 227.229 +		return;
 227.230 +
 227.231 +	std::string::size_type pos = rImportName.rfind( "," );
 227.232 +	if ( std::string::npos == pos )
 227.233 +	{
 227.234 +		rArchiveName = rImportName;
 227.235 +		return;
 227.236 +	}
 227.237 +
 227.238 +	rArchiveName = rImportName.substr( 0, pos );
 227.239 +	rMapName = rImportName.substr( pos, rImportName.size() - pos - 1 );
 227.240 +}
 227.241 +
 227.242 +// ------------------------------------------------------------------------------------------------
 227.243 +//	Returns the first map in the map archive.
 227.244 +bool Q3BSPFileImporter::findFirstMapInArchive( Q3BSPZipArchive &rArchive, std::string &rMapName )
 227.245 +{
 227.246 +	rMapName = "";
 227.247 +	std::vector<std::string> fileList;
 227.248 +	rArchive.getFileList( fileList );
 227.249 +	if ( fileList.empty() )  
 227.250 +		return false;
 227.251 +
 227.252 +	for ( std::vector<std::string>::iterator it = fileList.begin(); it != fileList.end();
 227.253 +		++it )
 227.254 +	{
 227.255 +		std::string::size_type pos = (*it).find( "maps/" );
 227.256 +		if ( std::string::npos != pos )
 227.257 +		{
 227.258 +			std::string::size_type extPos = (*it).find( ".bsp" );
 227.259 +			if ( std::string::npos != extPos )
 227.260 +			{
 227.261 +				rMapName = *it;
 227.262 +				return true;
 227.263 +			}
 227.264 +		}
 227.265 +	}
 227.266 +	
 227.267 +	return false;
 227.268 +}
 227.269 +
 227.270 +// ------------------------------------------------------------------------------------------------
 227.271 +//	Creates the assimp specific data.
 227.272 +void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, 
 227.273 +											 Q3BSPZipArchive *pArchive )
 227.274 +{
 227.275 +	if ( NULL == pModel || NULL == pScene )
 227.276 +		return;
 227.277 +
 227.278 +	pScene->mRootNode = new aiNode;
 227.279 +	if ( !pModel->m_ModelName.empty() )
 227.280 +	{
 227.281 +		pScene->mRootNode->mName.Set( pModel->m_ModelName );
 227.282 +	}
 227.283 +
 227.284 +	// Create the face to material relation map 
 227.285 +	createMaterialMap( pModel );
 227.286 +
 227.287 +	// Create all nodes
 227.288 +	CreateNodes( pModel, pScene, pScene->mRootNode );
 227.289 +	
 227.290 +	// Create the assigned materials
 227.291 +	createMaterials( pModel, pScene, pArchive );
 227.292 +}
 227.293 +
 227.294 +// ------------------------------------------------------------------------------------------------
 227.295 +//	Creates all assimp nodes.
 227.296 +void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, 
 227.297 +									aiNode *pParent )
 227.298 +{
 227.299 +	ai_assert( NULL != pModel );
 227.300 +	if ( NULL == pModel )
 227.301 +	{
 227.302 +		return;
 227.303 +	}
 227.304 +
 227.305 +	unsigned int matIdx = 0;
 227.306 +	std::vector<aiMesh*> MeshArray;
 227.307 +	std::vector<aiNode*> NodeArray;
 227.308 +	for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it )
 227.309 +	{
 227.310 +		std::vector<Q3BSP::sQ3BSPFace*> *pArray = (*it).second;
 227.311 +		size_t numVerts = countData( *pArray );
 227.312 +		if ( 0 != numVerts )
 227.313 +		{
 227.314 +			aiMesh* pMesh = new aiMesh;
 227.315 +			aiNode *pNode = CreateTopology( pModel, matIdx, *pArray, pMesh );
 227.316 +			if ( NULL != pNode )
 227.317 +			{
 227.318 +				NodeArray.push_back( pNode );
 227.319 +				MeshArray.push_back( pMesh );
 227.320 +			}
 227.321 +			else
 227.322 +			{
 227.323 +				delete pMesh;
 227.324 +			}
 227.325 +		}
 227.326 +		matIdx++;
 227.327 +	}
 227.328 +
 227.329 +	pScene->mNumMeshes = MeshArray.size();
 227.330 +	if ( pScene->mNumMeshes > 0 )
 227.331 +	{
 227.332 +		pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
 227.333 +		for ( size_t i = 0; i < MeshArray.size(); i++ )
 227.334 +		{
 227.335 +			aiMesh *pMesh = MeshArray[ i ];
 227.336 +			if ( NULL != pMesh )
 227.337 +			{
 227.338 +				pScene->mMeshes[ i ] = pMesh;
 227.339 +			}
 227.340 +		}
 227.341 +	}
 227.342 +
 227.343 +	pParent->mNumChildren = MeshArray.size();
 227.344 +	pParent->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren ];
 227.345 +	for ( size_t i=0; i<NodeArray.size(); i++ )
 227.346 +	{
 227.347 +		aiNode *pNode = NodeArray[ i ];
 227.348 +		pNode->mParent = pParent;
 227.349 +		pParent->mChildren[ i ] = pNode;
 227.350 +		pParent->mChildren[ i ]->mMeshes[ 0 ] = i;
 227.351 +	}
 227.352 +}
 227.353 +
 227.354 +// ------------------------------------------------------------------------------------------------
 227.355 +//	Creates the topology.
 227.356 +aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel,
 227.357 +										  unsigned int materialIdx,
 227.358 +										  std::vector<sQ3BSPFace*> &rArray, 
 227.359 +										  aiMesh* pMesh )
 227.360 +{
 227.361 +	size_t numVerts = countData( rArray );
 227.362 +	if ( 0 == numVerts )
 227.363 +	{
 227.364 +		return NULL;
 227.365 +	}
 227.366 +	
 227.367 +	size_t numFaces = countFaces( rArray );
 227.368 +	if ( 0 == numFaces )
 227.369 +	{
 227.370 +		return NULL;
 227.371 +	}
 227.372 +
 227.373 +	size_t numTriangles = countTriangles( rArray );
 227.374 +	pMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 227.375 +
 227.376 +	pMesh->mFaces = new aiFace[ numTriangles ];
 227.377 +	pMesh->mNumFaces = numTriangles;
 227.378 +	
 227.379 +	pMesh->mNumVertices = numVerts;
 227.380 +	pMesh->mVertices = new aiVector3D[ numVerts ];
 227.381 +	pMesh->mNormals =  new aiVector3D[ numVerts ];
 227.382 +	pMesh->mTextureCoords[ 0 ] = new aiVector3D[ numVerts ];
 227.383 +	pMesh->mTextureCoords[ 1 ] = new aiVector3D[ numVerts ];
 227.384 +	pMesh->mMaterialIndex = materialIdx;
 227.385 +
 227.386 +	unsigned int faceIdx = 0;
 227.387 +	unsigned int vertIdx = 0;
 227.388 +	pMesh->mNumUVComponents[ 0 ] = 2;
 227.389 +	pMesh->mNumUVComponents[ 1 ] = 2;
 227.390 +	for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); ++it )
 227.391 +	{
 227.392 +		Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
 227.393 +		ai_assert( NULL != pQ3BSPFace );
 227.394 +		if ( NULL == pQ3BSPFace )
 227.395 +		{
 227.396 +			continue;
 227.397 +		}
 227.398 +
 227.399 +		if ( pQ3BSPFace->iNumOfFaceVerts > 0 )
 227.400 +		{
 227.401 +			if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh )
 227.402 +			{
 227.403 +				createTriangleTopology( pModel, pQ3BSPFace, pMesh, faceIdx, vertIdx );
 227.404 +			}		
 227.405 +		}
 227.406 +	}
 227.407 +
 227.408 +	aiNode *pNode = new aiNode;
 227.409 +	pNode->mNumMeshes = 1;
 227.410 +	pNode->mMeshes = new unsigned int[ 1 ];
 227.411 +
 227.412 +	return pNode;
 227.413 +}
 227.414 +
 227.415 +// ------------------------------------------------------------------------------------------------
 227.416 +//	Creates the triangle topology from a face array.
 227.417 +void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel,
 227.418 +											  Q3BSP::sQ3BSPFace *pQ3BSPFace, 
 227.419 +											  aiMesh* pMesh,
 227.420 +											  unsigned int &rFaceIdx, 
 227.421 +											  unsigned int &rVertIdx )
 227.422 +{
 227.423 +	ai_assert( rFaceIdx < pMesh->mNumFaces );
 227.424 +	
 227.425 +	m_pCurrentFace = getNextFace( pMesh, rFaceIdx );
 227.426 +	ai_assert( NULL != m_pCurrentFace );
 227.427 +	if ( NULL == m_pCurrentFace )
 227.428 +	{
 227.429 +		return;
 227.430 +	}
 227.431 +
 227.432 +	m_pCurrentFace->mNumIndices = 3;
 227.433 +	m_pCurrentFace->mIndices = new unsigned int[ m_pCurrentFace->mNumIndices ];
 227.434 +	
 227.435 +	size_t idx = 0;
 227.436 +	for ( size_t i = 0; i < (size_t) pQ3BSPFace->iNumOfFaceVerts; i++ )
 227.437 +	{
 227.438 +		const size_t index = pQ3BSPFace->iVertexIndex + pModel->m_Indices[ pQ3BSPFace->iFaceVertexIndex + i ];
 227.439 +		ai_assert( index < pModel->m_Vertices.size() );
 227.440 +		if ( index >= pModel->m_Vertices.size() )
 227.441 +		{
 227.442 +			continue;
 227.443 +		}
 227.444 +
 227.445 +		sQ3BSPVertex *pVertex = pModel->m_Vertices[ index ];
 227.446 +		ai_assert( NULL != pVertex );
 227.447 +		if ( NULL == pVertex )
 227.448 +		{
 227.449 +			continue;
 227.450 +		}
 227.451 +
 227.452 +		pMesh->mVertices[ rVertIdx ].Set( pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z );
 227.453 +		pMesh->mNormals[ rVertIdx ].Set( pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z );
 227.454 +				
 227.455 +		pMesh->mTextureCoords[ 0 ][ rVertIdx ].Set( pVertex->vTexCoord.x, pVertex->vTexCoord.y, 0.0f );
 227.456 +		pMesh->mTextureCoords[ 1 ][ rVertIdx ].Set( pVertex->vLightmap.x, pVertex->vLightmap.y, 0.0f );
 227.457 +		
 227.458 +		m_pCurrentFace->mIndices[ idx ] = rVertIdx;
 227.459 +		rVertIdx++;
 227.460 +		
 227.461 +		idx++;
 227.462 +		if ( idx > 2 )
 227.463 +		{
 227.464 +			idx = 0;
 227.465 +			m_pCurrentFace = getNextFace( pMesh, rFaceIdx );
 227.466 +			if ( NULL != m_pCurrentFace )
 227.467 +			{
 227.468 +				m_pCurrentFace->mNumIndices = 3;
 227.469 +				m_pCurrentFace->mIndices = new unsigned int[ 3 ];
 227.470 +			}
 227.471 +		}
 227.472 +	}
 227.473 +	rFaceIdx--;
 227.474 +}
 227.475 +
 227.476 +// ------------------------------------------------------------------------------------------------
 227.477 +//	Creates all referenced materials.
 227.478 +void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
 227.479 +										Q3BSPZipArchive *pArchive )
 227.480 +{
 227.481 +	if ( m_MaterialLookupMap.empty() )
 227.482 +	{
 227.483 +		return;
 227.484 +	}
 227.485 +
 227.486 +	pScene->mMaterials = new aiMaterial*[ m_MaterialLookupMap.size() ];
 227.487 +	aiString aiMatName;
 227.488 +	int textureId( -1 ), lightmapId( -1 );
 227.489 +	for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end();
 227.490 +		++it )
 227.491 +	{
 227.492 +		const std::string matName = (*it).first;
 227.493 +		if ( matName.empty() )
 227.494 +		{
 227.495 +			continue;
 227.496 +		}
 227.497 +
 227.498 +		aiMatName.Set( matName );
 227.499 +		aiMaterial *pMatHelper = new aiMaterial;
 227.500 +		pMatHelper->AddProperty( &aiMatName, AI_MATKEY_NAME );
 227.501 +
 227.502 +		extractIds( matName, textureId, lightmapId );
 227.503 +		
 227.504 +		// Adding the texture
 227.505 +		if ( -1 != textureId )
 227.506 +		{
 227.507 +			sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ];
 227.508 +			if ( NULL != pTexture )
 227.509 +			{
 227.510 +				std::string tmp( "*" ), texName( "" );
 227.511 +				tmp += pTexture->strName;
 227.512 +				tmp += ".jpg";
 227.513 +				normalizePathName( tmp, texName );
 227.514 +				
 227.515 +				if ( !importTextureFromArchive( pModel, pArchive, pScene, pMatHelper, textureId ) )
 227.516 +				{
 227.517 +				}
 227.518 +			}
 227.519 +
 227.520 +		}
 227.521 +		if ( -1 != lightmapId )
 227.522 +		{
 227.523 +			importLightmap( pModel, pScene, pMatHelper, lightmapId );
 227.524 +		}
 227.525 +		pScene->mMaterials[ pScene->mNumMaterials ] = pMatHelper;
 227.526 +		pScene->mNumMaterials++;
 227.527 +	}
 227.528 +	pScene->mNumTextures = mTextures.size();
 227.529 +	pScene->mTextures = new aiTexture*[ pScene->mNumTextures ];
 227.530 +	std::copy( mTextures.begin(), mTextures.end(), pScene->mTextures );
 227.531 +}
 227.532 +
 227.533 +// ------------------------------------------------------------------------------------------------
 227.534 +//	Counts the number of referenced vertices.
 227.535 +size_t Q3BSPFileImporter::countData( const std::vector<sQ3BSPFace*> &rArray ) const
 227.536 +{
 227.537 +	size_t numVerts = 0;
 227.538 +	for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); 
 227.539 +		++it )
 227.540 +	{
 227.541 +		sQ3BSPFace *pQ3BSPFace = *it;
 227.542 +		if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh )
 227.543 +		{
 227.544 +			Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
 227.545 +			ai_assert( NULL != pQ3BSPFace );
 227.546 +			numVerts += pQ3BSPFace->iNumOfFaceVerts;
 227.547 +		}
 227.548 +	}
 227.549 +
 227.550 +	return numVerts;
 227.551 +}
 227.552 +
 227.553 +// ------------------------------------------------------------------------------------------------
 227.554 +//	Counts the faces with vertices.
 227.555 +size_t Q3BSPFileImporter::countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const
 227.556 +{
 227.557 +	size_t numFaces = 0;
 227.558 +	for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); 
 227.559 +		++it )
 227.560 +	{
 227.561 +		Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
 227.562 +		if ( pQ3BSPFace->iNumOfFaceVerts > 0 )
 227.563 +		{
 227.564 +			numFaces++;
 227.565 +		}
 227.566 +	}
 227.567 +
 227.568 +	return numFaces;
 227.569 +}
 227.570 +
 227.571 +// ------------------------------------------------------------------------------------------------
 227.572 +//	Counts the number of triangles in a Q3-facearray.
 227.573 +size_t Q3BSPFileImporter::countTriangles( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const
 227.574 +{
 227.575 +	size_t numTriangles = 0;
 227.576 +	for ( std::vector<Q3BSP::sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); 
 227.577 +		++it )
 227.578 +	{
 227.579 +		const Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
 227.580 +		if ( NULL != pQ3BSPFace )
 227.581 +		{
 227.582 +			numTriangles += pQ3BSPFace->iNumOfFaceVerts / 3;
 227.583 +		}
 227.584 +	}
 227.585 +
 227.586 +	return numTriangles;
 227.587 +}
 227.588 +
 227.589 +// ------------------------------------------------------------------------------------------------
 227.590 +//	Creates the faces-to-material map.
 227.591 +void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel )
 227.592 +{
 227.593 +	std::string key( "" );
 227.594 +	std::vector<sQ3BSPFace*> *pCurFaceArray = NULL;
 227.595 +	for ( size_t idx = 0; idx < pModel->m_Faces.size(); idx++ )
 227.596 +	{
 227.597 +		Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[ idx ];
 227.598 +		const int texId = pQ3BSPFace->iTextureID;
 227.599 +		const int lightMapId = pQ3BSPFace->iLightmapID;
 227.600 +		createKey( texId, lightMapId, key );
 227.601 +		FaceMapIt it = m_MaterialLookupMap.find( key );
 227.602 +		if ( m_MaterialLookupMap.end() == it )
 227.603 +		{
 227.604 +			pCurFaceArray = new std::vector<Q3BSP::sQ3BSPFace*>;
 227.605 +			m_MaterialLookupMap[ key ] = pCurFaceArray;
 227.606 +		}
 227.607 +		else
 227.608 +		{
 227.609 +			pCurFaceArray = (*it).second;
 227.610 +		}
 227.611 +		ai_assert( NULL != pCurFaceArray );
 227.612 +		if ( NULL != pCurFaceArray )
 227.613 +		{
 227.614 +			pCurFaceArray->push_back( pQ3BSPFace );
 227.615 +		}
 227.616 +	}
 227.617 +}
 227.618 +
 227.619 +// ------------------------------------------------------------------------------------------------
 227.620 +//	Returns the next face.
 227.621 +aiFace *Q3BSPFileImporter::getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx )
 227.622 +{
 227.623 +	aiFace *pFace = NULL;
 227.624 +	if ( rFaceIdx < pMesh->mNumFaces )
 227.625 +	{
 227.626 +		pFace = &pMesh->mFaces[ rFaceIdx ];
 227.627 +		rFaceIdx++;
 227.628 +	}
 227.629 +	else
 227.630 +	{
 227.631 +		pFace = NULL;
 227.632 +	}
 227.633 +
 227.634 +	return pFace;
 227.635 +}
 227.636 +
 227.637 +// ------------------------------------------------------------------------------------------------
 227.638 +//	Imports a texture file.
 227.639 +bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel,
 227.640 +												 Q3BSP::Q3BSPZipArchive *pArchive, aiScene* /*pScene*/,
 227.641 +												 aiMaterial *pMatHelper, int textureId )
 227.642 +{
 227.643 +	std::vector<std::string> supportedExtensions;
 227.644 +	supportedExtensions.push_back( ".jpg" );
 227.645 +	supportedExtensions.push_back( ".png" );
 227.646 +  supportedExtensions.push_back( ".tga" );
 227.647 +	if ( NULL == pArchive || NULL == pArchive || NULL == pMatHelper )
 227.648 +	{
 227.649 +		return false;
 227.650 +	}
 227.651 +
 227.652 +	if ( textureId < 0 || textureId >= static_cast<int>( pModel->m_Textures.size() ) )
 227.653 +	{
 227.654 +		return false;
 227.655 +	}
 227.656 +
 227.657 +	bool res = true;
 227.658 +	sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ];
 227.659 +	if ( NULL == pTexture )
 227.660 +		return false;
 227.661 +
 227.662 +	std::string textureName, ext;
 227.663 +	if ( expandFile( pArchive, pTexture->strName, supportedExtensions, textureName, ext ) )
 227.664 +	{
 227.665 +		IOStream *pTextureStream = pArchive->Open( textureName.c_str() );
 227.666 +		if ( NULL != pTextureStream )
 227.667 +		{
 227.668 +			size_t texSize = pTextureStream->FileSize();
 227.669 +			aiTexture *pTexture = new aiTexture;
 227.670 +			pTexture->mHeight = 0;
 227.671 +			pTexture->mWidth = texSize;
 227.672 +			unsigned char *pData = new unsigned char[ pTexture->mWidth ];
 227.673 +			size_t readSize = pTextureStream->Read( pData, sizeof( unsigned char ), pTexture->mWidth );
 227.674 +			(void)readSize;
 227.675 +			ai_assert( readSize == pTexture->mWidth );
 227.676 +			pTexture->pcData = reinterpret_cast<aiTexel*>( pData );
 227.677 +			pTexture->achFormatHint[ 0 ] = ext[ 1 ];
 227.678 +			pTexture->achFormatHint[ 1 ] = ext[ 2 ];
 227.679 +			pTexture->achFormatHint[ 2 ] = ext[ 3 ];
 227.680 +			pTexture->achFormatHint[ 3 ] = '\0';
 227.681 +			res = true;
 227.682 +
 227.683 +			aiString name;
 227.684 +			name.data[ 0 ] = '*';
 227.685 +			name.length = 1 + ASSIMP_itoa10( name.data + 1, MAXLEN-1, mTextures.size() );
 227.686 +
 227.687 +			pArchive->Close( pTextureStream );
 227.688 +
 227.689 +			pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
 227.690 +			mTextures.push_back( pTexture );
 227.691 +		}
 227.692 +		else
 227.693 +		{
 227.694 +			// If it doesn't exist in the archive, it is probably just a reference to an external file.
 227.695 +			// We'll leave it up to the user to figure out which extension the file has.
 227.696 +			aiString name;
 227.697 +			strncpy( name.data, pTexture->strName, sizeof name.data );
 227.698 +			name.length = strlen( name.data );
 227.699 +			pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
 227.700 +		}
 227.701 +	}
 227.702 +
 227.703 +	return res;
 227.704 +}
 227.705 +
 227.706 +// ------------------------------------------------------------------------------------------------
 227.707 +//	Imports a light map file.
 227.708 +bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, 
 227.709 +									   aiMaterial *pMatHelper, int lightmapId )
 227.710 +{
 227.711 +	if ( NULL == pModel || NULL == pScene || NULL == pMatHelper )
 227.712 +	{
 227.713 +		return false;
 227.714 +	}
 227.715 +
 227.716 +	if ( lightmapId < 0 || lightmapId >= static_cast<int>( pModel->m_Lightmaps.size() ) )
 227.717 +	{
 227.718 +		return false;
 227.719 +	}
 227.720 +
 227.721 +	sQ3BSPLightmap *pLightMap = pModel->m_Lightmaps[ lightmapId ];
 227.722 +	if ( NULL == pLightMap )
 227.723 +	{
 227.724 +		return false;
 227.725 +	}
 227.726 +
 227.727 +	aiTexture *pTexture = new aiTexture;
 227.728 +	
 227.729 +	pTexture->mWidth = CE_BSP_LIGHTMAPWIDTH;
 227.730 +	pTexture->mHeight = CE_BSP_LIGHTMAPHEIGHT;
 227.731 +	pTexture->pcData = new aiTexel[CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT];
 227.732 +
 227.733 +	::memcpy( pTexture->pcData, pLightMap->bLMapData, pTexture->mWidth );
 227.734 +	size_t p = 0;
 227.735 +	for ( size_t i = 0; i < CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT; ++i )
 227.736 +	{
 227.737 +		pTexture->pcData[ i ].r = pLightMap->bLMapData[ p++ ];
 227.738 +		pTexture->pcData[ i ].g = pLightMap->bLMapData[ p++ ];
 227.739 +		pTexture->pcData[ i ].b = pLightMap->bLMapData[ p++ ];
 227.740 +		pTexture->pcData[ i ].a = 0xFF;
 227.741 +	}
 227.742 +	
 227.743 +	aiString name;
 227.744 +	name.data[ 0 ] = '*';
 227.745 +	name.length = 1 + ASSIMP_itoa10( name.data + 1, MAXLEN-1,  mTextures.size() );
 227.746 +
 227.747 +	pMatHelper->AddProperty( &name,AI_MATKEY_TEXTURE_LIGHTMAP( 1 ) );
 227.748 +	mTextures.push_back( pTexture );
 227.749 +
 227.750 +	return true;
 227.751 +}
 227.752 +
 227.753 +
 227.754 +// ------------------------------------------------------------------------------------------------
 227.755 +//	Will search for a supported extension.
 227.756 +bool Q3BSPFileImporter::expandFile(  Q3BSP::Q3BSPZipArchive *pArchive, const std::string &rFilename, 
 227.757 +								   const std::vector<std::string> &rExtList, std::string &rFile,
 227.758 +								   std::string &rExt )
 227.759 +{
 227.760 +	ai_assert( NULL != pArchive );
 227.761 +	ai_assert( !rFilename.empty() );
 227.762 +
 227.763 +	if ( rExtList.empty() )
 227.764 +	{
 227.765 +		rFile =  rFilename;
 227.766 +		rExt = "";
 227.767 +		return true;
 227.768 +	}
 227.769 +
 227.770 +	bool found = false;
 227.771 +	for ( std::vector<std::string>::const_iterator it = rExtList.begin(); it != rExtList.end(); ++it )
 227.772 +	{
 227.773 +		const std::string textureName = rFilename + *it;
 227.774 +		if ( pArchive->Exists( textureName.c_str() ) )
 227.775 +		{
 227.776 +			rExt = *it;
 227.777 +			rFile = textureName;
 227.778 +			found = true;
 227.779 +			break;
 227.780 +		}
 227.781 +	}
 227.782 +
 227.783 +	return found;
 227.784 +}
 227.785 +
 227.786 +// ------------------------------------------------------------------------------------------------
 227.787 +
 227.788 +} // Namespace Assimp
 227.789 +
 227.790 +#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER
   228.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   228.2 +++ b/libs/assimp/Q3BSPFileImporter.h	Sat Feb 01 19:58:19 2014 +0200
   228.3 @@ -0,0 +1,116 @@
   228.4 +/*
   228.5 +Open Asset Import Library (assimp)
   228.6 +----------------------------------------------------------------------
   228.7 +
   228.8 +Copyright (c) 2006-2008, assimp team
   228.9 +All rights reserved.
  228.10 +
  228.11 +Redistribution and use of this software in source and binary forms, 
  228.12 +with or without modification, are permitted provided that the 
  228.13 +following conditions are met:
  228.14 +
  228.15 +* Redistributions of source code must retain the above
  228.16 +  copyright notice, this list of conditions and the
  228.17 +  following disclaimer.
  228.18 +
  228.19 +* Redistributions in binary form must reproduce the above
  228.20 +  copyright notice, this list of conditions and the
  228.21 +  following disclaimer in the documentation and/or other
  228.22 +  materials provided with the distribution.
  228.23 +
  228.24 +* Neither the name of the assimp team, nor the names of its
  228.25 +  contributors may be used to endorse or promote products
  228.26 +  derived from this software without specific prior
  228.27 +  written permission of the assimp team.
  228.28 +
  228.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  228.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  228.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  228.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  228.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  228.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  228.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  228.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  228.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  228.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  228.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  228.40 +
  228.41 +----------------------------------------------------------------------
  228.42 +*/
  228.43 +#ifndef ASSIMP_Q3BSPFILEIMPORTER_H_INC
  228.44 +#define ASSIMP_Q3BSPFILEIMPORTER_H_INC
  228.45 +
  228.46 +#include "BaseImporter.h"
  228.47 +
  228.48 +struct aiMesh;
  228.49 +
  228.50 +namespace Assimp
  228.51 +{
  228.52 +namespace Q3BSP
  228.53 +{
  228.54 +
  228.55 +class Q3BSPZipArchive;
  228.56 +struct Q3BSPModel;
  228.57 +struct sQ3BSPFace;
  228.58 +
  228.59 +}
  228.60 +// ------------------------------------------------------------------------------------------------
  228.61 +/**	Loader to import BSP-levels from a PK3 archive or from a unpacked BSP-level.
  228.62 + */
  228.63 +// ------------------------------------------------------------------------------------------------
  228.64 +class Q3BSPFileImporter : public BaseImporter
  228.65 +{
  228.66 +public:
  228.67 +
  228.68 +	///	@brief	Default constructor.
  228.69 +	Q3BSPFileImporter();
  228.70 +
  228.71 +	///	@brief	Destructor.
  228.72 +	~Q3BSPFileImporter();
  228.73 +
  228.74 +public:
  228.75 +	/// @brief	Returns whether the class can handle the format of the given file. 
  228.76 +	/// @remark	See BaseImporter::CanRead() for details.
  228.77 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const;
  228.78 +
  228.79 +private:
  228.80 +	typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*> FaceMap;
  228.81 +	typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>* >::iterator FaceMapIt;
  228.82 +	typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*>::const_iterator FaceMapConstIt;
  228.83 +
  228.84 +	const aiImporterDesc* GetInfo () const;
  228.85 +	void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
  228.86 +	void separateMapName( const std::string &rImportName, std::string &rArchiveName, std::string &rMapName );
  228.87 +	bool findFirstMapInArchive( Q3BSP::Q3BSPZipArchive &rArchive, std::string &rMapName );
  228.88 +	void CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive );
  228.89 +	void CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiNode *pParent );
  228.90 +	aiNode *CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int materialIdx, 
  228.91 +		std::vector<Q3BSP::sQ3BSPFace*> &rArray, aiMesh* pMesh );
  228.92 +	void createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, Q3BSP::sQ3BSPFace *pQ3BSPFace, aiMesh* pMesh, unsigned int &rFaceIdx, 
  228.93 +		unsigned int &rVertIdx  );
  228.94 +	void createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive );
  228.95 +	size_t countData( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const;
  228.96 +	size_t countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const;
  228.97 +	size_t countTriangles( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const;
  228.98 +	void createMaterialMap( const Q3BSP::Q3BSPModel *pModel);
  228.99 +	aiFace *getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx );
 228.100 +	bool importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel, Q3BSP::Q3BSPZipArchive *pArchive, aiScene* pScene, 
 228.101 +		aiMaterial *pMatHelper, int textureId );
 228.102 +	bool importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiMaterial *pMatHelper, int lightmapId );
 228.103 +	bool importEntities( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene );
 228.104 +	bool expandFile(  Q3BSP::Q3BSPZipArchive *pArchive, const std::string &rFilename, const std::vector<std::string> &rExtList, 
 228.105 +		std::string &rFile, std::string &rExt );
 228.106 +
 228.107 +private:
 228.108 +	aiMesh *m_pCurrentMesh;
 228.109 +	aiFace *m_pCurrentFace;
 228.110 +	FaceMap m_MaterialLookupMap;
 228.111 +	std::vector<aiTexture*> mTextures;
 228.112 +};
 228.113 +
 228.114 +// ------------------------------------------------------------------------------------------------
 228.115 +
 228.116 +} // Namespace Assimp
 228.117 +
 228.118 +
 228.119 +#endif // ASSIMP_Q3BSPFILEIMPORTER_H_INC
   229.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   229.2 +++ b/libs/assimp/Q3BSPFileParser.cpp	Sat Feb 01 19:58:19 2014 +0200
   229.3 @@ -0,0 +1,280 @@
   229.4 +/*
   229.5 +Open Asset Import Library (assimp)
   229.6 +----------------------------------------------------------------------
   229.7 +
   229.8 +Copyright (c) 2006-2008, assimp team
   229.9 +All rights reserved.
  229.10 +
  229.11 +Redistribution and use of this software in source and binary forms, 
  229.12 +with or without modification, are permitted provided that the 
  229.13 +following conditions are met:
  229.14 +
  229.15 +* Redistributions of source code must retain the above
  229.16 +  copyright notice, this list of conditions and the
  229.17 +  following disclaimer.
  229.18 +
  229.19 +* Redistributions in binary form must reproduce the above
  229.20 +  copyright notice, this list of conditions and the
  229.21 +  following disclaimer in the documentation and/or other
  229.22 +  materials provided with the distribution.
  229.23 +
  229.24 +* Neither the name of the assimp team, nor the names of its
  229.25 +  contributors may be used to endorse or promote products
  229.26 +  derived from this software without specific prior
  229.27 +  written permission of the assimp team.
  229.28 +
  229.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  229.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  229.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  229.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  229.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  229.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  229.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  229.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  229.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  229.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  229.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  229.40 +
  229.41 +----------------------------------------------------------------------
  229.42 +*/
  229.43 +#include "AssimpPCH.h"
  229.44 +
  229.45 +#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
  229.46 +
  229.47 +#include "Q3BSPFileParser.h"
  229.48 +#include "DefaultIOSystem.h"
  229.49 +#include "Q3BSPFileData.h"
  229.50 +#include "Q3BSPZipArchive.h"
  229.51 +#include <vector>
  229.52 +
  229.53 +namespace Assimp
  229.54 +{
  229.55 +
  229.56 +using namespace Q3BSP;
  229.57 +
  229.58 +// ------------------------------------------------------------------------------------------------
  229.59 +Q3BSPFileParser::Q3BSPFileParser( const std::string &rMapName, Q3BSPZipArchive *pZipArchive ) :
  229.60 +	m_sOffset( 0 ),
  229.61 +	m_Data(),
  229.62 +	m_pModel( NULL ),
  229.63 +	m_pZipArchive( pZipArchive )
  229.64 +{
  229.65 +	ai_assert( NULL != m_pZipArchive );
  229.66 +	ai_assert( !rMapName.empty() );
  229.67 +
  229.68 +	if ( !readData( rMapName ) )
  229.69 +		return;
  229.70 +
  229.71 +	m_pModel = new Q3BSPModel;
  229.72 +	m_pModel->m_ModelName = rMapName;
  229.73 +	if ( !parseFile() )
  229.74 +	{
  229.75 +		delete m_pModel;
  229.76 +		m_pModel = NULL;
  229.77 +	}
  229.78 +}
  229.79 +
  229.80 +// ------------------------------------------------------------------------------------------------
  229.81 +Q3BSPFileParser::~Q3BSPFileParser()
  229.82 +{
  229.83 +	delete m_pModel;
  229.84 +	m_pModel = NULL;
  229.85 +}
  229.86 +
  229.87 +// ------------------------------------------------------------------------------------------------
  229.88 +Q3BSP::Q3BSPModel *Q3BSPFileParser::getModel() const
  229.89 +{
  229.90 +	return m_pModel;
  229.91 +}
  229.92 +
  229.93 +// ------------------------------------------------------------------------------------------------
  229.94 +bool Q3BSPFileParser::readData( const std::string &rMapName )
  229.95 +{
  229.96 +	if ( !m_pZipArchive->Exists( rMapName.c_str() ) )
  229.97 +		return false;
  229.98 +
  229.99 +	IOStream *pMapFile = m_pZipArchive->Open( rMapName.c_str() );
 229.100 +	if ( NULL == pMapFile )
 229.101 +		return false;
 229.102 +		
 229.103 +	const size_t size = pMapFile->FileSize();
 229.104 +	m_Data.resize( size );
 229.105 +
 229.106 +	const size_t readSize = pMapFile->Read( &m_Data[0], sizeof( char ), size );
 229.107 +	if ( readSize != size )
 229.108 +	{
 229.109 +		m_Data.clear();
 229.110 +		return false;
 229.111 +	}
 229.112 +	m_pZipArchive->Close( pMapFile );
 229.113 +
 229.114 +	return true;
 229.115 +}
 229.116 +
 229.117 +// ------------------------------------------------------------------------------------------------
 229.118 +bool Q3BSPFileParser::parseFile()
 229.119 +{
 229.120 +	if ( m_Data.empty() )
 229.121 +	{
 229.122 +		return false;
 229.123 +	}
 229.124 +
 229.125 +	if ( !validateFormat() )
 229.126 +	{
 229.127 +		return false;
 229.128 +	}
 229.129 +
 229.130 +	// Imports the dictionary of the level
 229.131 +	getLumps();
 229.132 +
 229.133 +	// Conunt data and prepare model data 
 229.134 +	countLumps();
 229.135 +
 229.136 +	// Read in Vertices
 229.137 +	getVertices();
 229.138 +
 229.139 +	// Read in Indices
 229.140 +	getIndices();
 229.141 +	
 229.142 +	// Read Faces
 229.143 +	getFaces();
 229.144 +
 229.145 +	// Read Textures
 229.146 +	getTextures();
 229.147 +
 229.148 +	// Read Lightmaps
 229.149 +	getLightMaps();
 229.150 +
 229.151 +	// Load the entities
 229.152 +	getEntities();
 229.153 +
 229.154 +	return true;
 229.155 +}
 229.156 +
 229.157 +// ------------------------------------------------------------------------------------------------
 229.158 +bool Q3BSPFileParser::validateFormat()
 229.159 +{
 229.160 +	sQ3BSPHeader *pHeader = (sQ3BSPHeader*) &m_Data[ 0 ];
 229.161 +	m_sOffset += sizeof( sQ3BSPHeader );
 229.162 +
 229.163 +	// Version and identify string validation
 229.164 +	if (pHeader->strID[ 0 ] != 'I' || pHeader->strID[ 1 ] != 'B' || pHeader->strID[ 2 ] != 'S' 
 229.165 +		|| pHeader->strID[ 3 ] != 'P') 
 229.166 +	{
 229.167 +		return false;
 229.168 +	}
 229.169 +
 229.170 +	return true;
 229.171 +}
 229.172 +
 229.173 +// ------------------------------------------------------------------------------------------------
 229.174 +void Q3BSPFileParser::getLumps()
 229.175 +{
 229.176 +	size_t Offset = m_sOffset;
 229.177 +	m_pModel->m_Lumps.resize( kMaxLumps );
 229.178 +	for ( size_t idx=0; idx < kMaxLumps; idx++ )
 229.179 +	{
 229.180 +		sQ3BSPLump *pLump = new sQ3BSPLump;
 229.181 +		memcpy( pLump, &m_Data[ Offset ], sizeof( sQ3BSPLump ) );
 229.182 +		Offset += sizeof( sQ3BSPLump );
 229.183 +		m_pModel->m_Lumps[ idx ] = pLump;
 229.184 +	}
 229.185 +}
 229.186 +
 229.187 +// ------------------------------------------------------------------------------------------------
 229.188 +void Q3BSPFileParser::countLumps()
 229.189 +{
 229.190 +	m_pModel->m_Vertices.resize( m_pModel->m_Lumps[ kVertices ]->iSize / sizeof( sQ3BSPVertex ) );
 229.191 +	m_pModel->m_Indices.resize( m_pModel->m_Lumps[ kMeshVerts ]->iSize  / sizeof( int ) );
 229.192 +	m_pModel->m_Faces.resize( m_pModel->m_Lumps[ kFaces ]->iSize / sizeof( sQ3BSPFace ) );
 229.193 +	m_pModel->m_Textures.resize( m_pModel->m_Lumps[ kTextures ]->iSize / sizeof( sQ3BSPTexture ) );
 229.194 +	m_pModel->m_Lightmaps.resize( m_pModel->m_Lumps[ kLightmaps ]->iSize / sizeof( sQ3BSPLightmap ) );
 229.195 +}
 229.196 +
 229.197 +// ------------------------------------------------------------------------------------------------
 229.198 +void Q3BSPFileParser::getVertices()
 229.199 +{
 229.200 +	size_t Offset = m_pModel->m_Lumps[ kVertices ]->iOffset;
 229.201 +	for ( size_t idx = 0; idx < m_pModel->m_Vertices.size(); idx++ )
 229.202 +	{
 229.203 +		sQ3BSPVertex *pVertex = new sQ3BSPVertex;
 229.204 +		memcpy( pVertex, &m_Data[ Offset ], sizeof( sQ3BSPVertex ) );
 229.205 +		Offset += sizeof( sQ3BSPVertex );
 229.206 +		m_pModel->m_Vertices[ idx ] = pVertex;
 229.207 +	}
 229.208 +}
 229.209 +
 229.210 +// ------------------------------------------------------------------------------------------------
 229.211 +void Q3BSPFileParser::getIndices()
 229.212 +{
 229.213 +	ai_assert( NULL != m_pModel );
 229.214 +
 229.215 +	sQ3BSPLump *lump = m_pModel->m_Lumps[ kMeshVerts ];	
 229.216 +	size_t Offset = (size_t) lump->iOffset;
 229.217 +	const size_t nIndices = lump->iSize / sizeof( int );
 229.218 +	m_pModel->m_Indices.resize( nIndices );
 229.219 +	memcpy( &m_pModel->m_Indices[ 0 ], &m_Data[ Offset ], lump->iSize );
 229.220 +}
 229.221 +
 229.222 +// ------------------------------------------------------------------------------------------------
 229.223 +void Q3BSPFileParser::getFaces()
 229.224 +{
 229.225 +	ai_assert( NULL != m_pModel );
 229.226 +	
 229.227 +	size_t Offset = m_pModel->m_Lumps[ kFaces ]->iOffset;
 229.228 +	for ( size_t idx = 0; idx < m_pModel->m_Faces.size(); idx++ )
 229.229 +	{
 229.230 +		sQ3BSPFace *pFace = new sQ3BSPFace;
 229.231 +		memcpy( pFace, &m_Data[ Offset ], sizeof( sQ3BSPFace ) );
 229.232 +		m_pModel->m_Faces[ idx ] = pFace;
 229.233 +		Offset += sizeof( sQ3BSPFace );
 229.234 +	}
 229.235 +}
 229.236 +
 229.237 +// ------------------------------------------------------------------------------------------------
 229.238 +void Q3BSPFileParser::getTextures()
 229.239 +{
 229.240 +	ai_assert( NULL != m_pModel );
 229.241 +
 229.242 +	size_t Offset = m_pModel->m_Lumps[ kTextures ]->iOffset;
 229.243 +	for ( size_t idx=0; idx < m_pModel->m_Textures.size(); idx++ )
 229.244 +	{
 229.245 +		sQ3BSPTexture *pTexture = new sQ3BSPTexture;
 229.246 +		memcpy( pTexture, &m_Data[ Offset ], sizeof(sQ3BSPTexture) );
 229.247 +		m_pModel->m_Textures[ idx ] = pTexture;
 229.248 +		Offset += sizeof(sQ3BSPTexture);
 229.249 +	}
 229.250 +}
 229.251 +
 229.252 +// ------------------------------------------------------------------------------------------------
 229.253 +void Q3BSPFileParser::getLightMaps()
 229.254 +{
 229.255 +	ai_assert( NULL != m_pModel );
 229.256 +
 229.257 +	size_t Offset = m_pModel->m_Lumps[kLightmaps]->iOffset;
 229.258 +	for ( size_t idx=0; idx < m_pModel->m_Lightmaps.size(); idx++ )
 229.259 +	{
 229.260 +		sQ3BSPLightmap *pLightmap = new sQ3BSPLightmap;
 229.261 +		memcpy( pLightmap, &m_Data[ Offset ], sizeof( sQ3BSPLightmap ) );
 229.262 +		Offset += sizeof( sQ3BSPLightmap );
 229.263 +		m_pModel->m_Lightmaps[ idx ] = pLightmap;
 229.264 +	}
 229.265 +}
 229.266 +
 229.267 +// ------------------------------------------------------------------------------------------------
 229.268 +void Q3BSPFileParser::getEntities()
 229.269 +{
 229.270 +	int size = m_pModel->m_Lumps[ kEntities ]->iSize;
 229.271 +	m_pModel->m_EntityData.resize( size );
 229.272 +	if ( size > 0 ) 
 229.273 +	{
 229.274 +		size_t Offset = m_pModel->m_Lumps[ kEntities ]->iOffset;
 229.275 +		memcpy( &m_pModel->m_EntityData[ 0 ], &m_Data[ Offset ], sizeof( char ) * size );
 229.276 +	}
 229.277 +}
 229.278 +
 229.279 +// ------------------------------------------------------------------------------------------------
 229.280 +
 229.281 +} // Namespace Assimp
 229.282 +
 229.283 +#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER
   230.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   230.2 +++ b/libs/assimp/Q3BSPFileParser.h	Sat Feb 01 19:58:19 2014 +0200
   230.3 @@ -0,0 +1,89 @@
   230.4 +/*
   230.5 +Open Asset Import Library (assimp)
   230.6 +----------------------------------------------------------------------
   230.7 +
   230.8 +Copyright (c) 2006-2008, assimp team
   230.9 +All rights reserved.
  230.10 +
  230.11 +Redistribution and use of this software in source and binary forms, 
  230.12 +with or without modification, are permitted provided that the 
  230.13 +following conditions are met:
  230.14 +
  230.15 +* Redistributions of source code must retain the above
  230.16 +  copyright notice, this list of conditions and the
  230.17 +  following disclaimer.
  230.18 +
  230.19 +* Redistributions in binary form must reproduce the above
  230.20 +  copyright notice, this list of conditions and the
  230.21 +  following disclaimer in the documentation and/or other
  230.22 +  materials provided with the distribution.
  230.23 +
  230.24 +* Neither the name of the assimp team, nor the names of its
  230.25 +  contributors may be used to endorse or promote products
  230.26 +  derived from this software without specific prior
  230.27 +  written permission of the assimp team.
  230.28 +
  230.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  230.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  230.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  230.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  230.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  230.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  230.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  230.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  230.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  230.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  230.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  230.40 +
  230.41 +----------------------------------------------------------------------
  230.42 +*/
  230.43 +
  230.44 +#ifndef ASSIMP_Q3BSPFILEPARSER_H_INC
  230.45 +#define ASSIMP_Q3BSPFILEPARSER_H_INC
  230.46 +
  230.47 +#include "BaseImporter.h"
  230.48 +#include <string>
  230.49 +
  230.50 +namespace Assimp
  230.51 +{
  230.52 +namespace Q3BSP
  230.53 +{
  230.54 +
  230.55 +class Q3BSPZipArchive;
  230.56 +struct Q3BSPModel;
  230.57 +class ZipFile;
  230.58 +
  230.59 +}
  230.60 +
  230.61 +// -------------------------------------------------------------------
  230.62 +// -------------------------------------------------------------------
  230.63 +class Q3BSPFileParser
  230.64 +{
  230.65 +public:
  230.66 +	Q3BSPFileParser( const std::string &rMapName, Q3BSP::Q3BSPZipArchive *pZipArchive );
  230.67 +	~Q3BSPFileParser();
  230.68 +	Q3BSP::Q3BSPModel *getModel() const;
  230.69 +
  230.70 +protected:
  230.71 +	bool readData(const std::string &rMapName);
  230.72 +	bool parseFile();
  230.73 +	bool validateFormat();
  230.74 +	void getLumps();
  230.75 +	void countLumps();
  230.76 +	void getVertices();
  230.77 +	void getIndices();
  230.78 +	void getFaces();
  230.79 +	void getTextures();
  230.80 +	void getLightMaps();
  230.81 +	void getEntities();
  230.82 +
  230.83 +private:
  230.84 +	size_t m_sOffset;
  230.85 +	std::vector<char> m_Data;
  230.86 +	Q3BSP::Q3BSPModel *m_pModel;
  230.87 +	Q3BSP::Q3BSPZipArchive *m_pZipArchive;
  230.88 +};
  230.89 +
  230.90 +} // Namespace Assimp
  230.91 +
  230.92 +#endif // ASSIMP_Q3BSPFILEPARSER_H_INC
   231.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   231.2 +++ b/libs/assimp/Q3BSPZipArchive.cpp	Sat Feb 01 19:58:19 2014 +0200
   231.3 @@ -0,0 +1,201 @@
   231.4 +/*
   231.5 +Open Asset Import Library (assimp)
   231.6 +----------------------------------------------------------------------
   231.7 +
   231.8 +Copyright (c) 2006-2008, assimp team
   231.9 +All rights reserved.
  231.10 +
  231.11 +Redistribution and use of this software in source and binary forms, 
  231.12 +with or without modification, are permitted provided that the 
  231.13 +following conditions are met:
  231.14 +
  231.15 +* Redistributions of source code must retain the above
  231.16 +  copyright notice, this list of conditions and the
  231.17 +  following disclaimer.
  231.18 +
  231.19 +* Redistributions in binary form must reproduce the above
  231.20 +  copyright notice, this list of conditions and the
  231.21 +  following disclaimer in the documentation and/or other
  231.22 +  materials provided with the distribution.
  231.23 +
  231.24 +* Neither the name of the assimp team, nor the names of its
  231.25 +  contributors may be used to endorse or promote products
  231.26 +  derived from this software without specific prior
  231.27 +  written permission of the assimp team.
  231.28 +
  231.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  231.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  231.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  231.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  231.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  231.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  231.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  231.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  231.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  231.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  231.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  231.40 +
  231.41 +----------------------------------------------------------------------
  231.42 +*/
  231.43 +
  231.44 +#include "AssimpPCH.h"
  231.45 +
  231.46 +#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
  231.47 +
  231.48 +#include "Q3BSPZipArchive.h"
  231.49 +#include <algorithm>
  231.50 +#include <cassert>
  231.51 +
  231.52 +namespace Assimp
  231.53 +{
  231.54 +namespace Q3BSP
  231.55 +{
  231.56 +
  231.57 +// ------------------------------------------------------------------------------------------------
  231.58 +//	Constructor.
  231.59 +Q3BSPZipArchive::Q3BSPZipArchive( const std::string& rFile ) :
  231.60 +	m_ZipFileHandle( NULL ),
  231.61 +	m_FileList(),
  231.62 +	m_bDirty( true )
  231.63 +{
  231.64 +	if ( !rFile.empty() )
  231.65 +	{
  231.66 +		m_ZipFileHandle = unzOpen( rFile.c_str() );
  231.67 +		if ( NULL != m_ZipFileHandle )
  231.68 +		{
  231.69 +			mapArchive();
  231.70 +		}
  231.71 +	}
  231.72 +}
  231.73 +
  231.74 +// ------------------------------------------------------------------------------------------------
  231.75 +//	Destructor.
  231.76 +Q3BSPZipArchive::~Q3BSPZipArchive()
  231.77 +{
  231.78 +	if ( NULL != m_ZipFileHandle )
  231.79 +	{
  231.80 +		unzClose( m_ZipFileHandle );
  231.81 +	}
  231.82 +	m_ZipFileHandle = NULL;
  231.83 +	m_FileList.clear();
  231.84 +}
  231.85 +
  231.86 +// ------------------------------------------------------------------------------------------------
  231.87 +//	Returns true, if the archive is already open.
  231.88 +bool Q3BSPZipArchive::isOpen() const
  231.89 +{
  231.90 +	return ( NULL != m_ZipFileHandle );
  231.91 +}
  231.92 +
  231.93 +// ------------------------------------------------------------------------------------------------
  231.94 +//	Returns true, if the filename is part of the archive.
  231.95 +bool Q3BSPZipArchive::Exists( const char* pFile ) const
  231.96 +{
  231.97 +	ai_assert( NULL != pFile );
  231.98 +	if ( NULL == pFile )
  231.99 +	{
 231.100 +		return false;
 231.101 +	}
 231.102 +
 231.103 +	std::string rFile( pFile );
 231.104 +	std::vector<std::string>::const_iterator it = std::find( m_FileList.begin(), m_FileList.end(), rFile );
 231.105 +	if ( m_FileList.end() == it )
 231.106 +	{
 231.107 +		return false;
 231.108 +	}
 231.109 +
 231.110 +	return true;
 231.111 +}
 231.112 +
 231.113 +// ------------------------------------------------------------------------------------------------
 231.114 +//	Returns the separator delimiter.
 231.115 +char Q3BSPZipArchive::getOsSeparator() const
 231.116 +{
 231.117 +	return '/';
 231.118 +}
 231.119 +
 231.120 +// ------------------------------------------------------------------------------------------------
 231.121 +//	Opens a file, which is part of the archive.
 231.122 +IOStream *Q3BSPZipArchive::Open( const char* pFile, const char* /*pMode*/ )
 231.123 +{
 231.124 +	ai_assert( NULL != pFile );
 231.125 +
 231.126 +	std::string rItem( pFile );
 231.127 +	std::vector<std::string>::iterator it = std::find( m_FileList.begin(), m_FileList.end(), rItem );
 231.128 +	if ( m_FileList.end() == it )
 231.129 +		return NULL;
 231.130 +
 231.131 +	ZipFile *pZipFile = new ZipFile( *it, m_ZipFileHandle );
 231.132 +	m_ArchiveMap[ rItem ] = pZipFile;
 231.133 +
 231.134 +	return pZipFile;
 231.135 +}
 231.136 +
 231.137 +// ------------------------------------------------------------------------------------------------
 231.138 +//	Close a filestream.
 231.139 +void Q3BSPZipArchive::Close( IOStream *pFile )
 231.140 +{
 231.141 +	ai_assert( NULL != pFile );
 231.142 +
 231.143 +	std::map<std::string, IOStream*>::iterator it;
 231.144 +	for ( it = m_ArchiveMap.begin(); it != m_ArchiveMap.end(); ++it )
 231.145 +	{
 231.146 +		if ( (*it).second == pFile )
 231.147 +		{
 231.148 +			ZipFile *pZipFile = reinterpret_cast<ZipFile*>( (*it).second ); 
 231.149 +			delete pZipFile;
 231.150 +			m_ArchiveMap.erase( it );
 231.151 +			break;
 231.152 +		}
 231.153 +	}
 231.154 +}
 231.155 +// ------------------------------------------------------------------------------------------------
 231.156 +//	Returns the file-list of the archive.
 231.157 +void Q3BSPZipArchive::getFileList( std::vector<std::string> &rFileList )
 231.158 +{
 231.159 +	rFileList = m_FileList;
 231.160 +}
 231.161 +
 231.162 +// ------------------------------------------------------------------------------------------------
 231.163 +//	Maps the archive content.
 231.164 +bool Q3BSPZipArchive::mapArchive()
 231.165 +{
 231.166 +	if ( NULL == m_ZipFileHandle )
 231.167 +		return false;
 231.168 +
 231.169 +	if ( !m_bDirty )
 231.170 +		return true;
 231.171 +
 231.172 +	if ( !m_FileList.empty() )
 231.173 +		m_FileList.resize( 0 );
 231.174 +
 231.175 +	//	At first ensure file is already open
 231.176 +	if ( UNZ_OK == unzGoToFirstFile( m_ZipFileHandle ) ) 
 231.177 +	{
 231.178 +		char filename[ FileNameSize ];
 231.179 +		unzGetCurrentFileInfo( m_ZipFileHandle, NULL, filename, FileNameSize, NULL, 0, NULL, 0 );
 231.180 +		m_FileList.push_back( filename );
 231.181 +		unzCloseCurrentFile( m_ZipFileHandle );
 231.182 +			
 231.183 +		// Loop over all files
 231.184 +		while ( unzGoToNextFile( m_ZipFileHandle ) != UNZ_END_OF_LIST_OF_FILE )  
 231.185 +		{
 231.186 +			char filename[ FileNameSize ];
 231.187 +			unzGetCurrentFileInfo( m_ZipFileHandle, NULL, filename, FileNameSize, NULL, 0, NULL, 0 );
 231.188 +			m_FileList.push_back( filename );
 231.189 +			unzCloseCurrentFile( m_ZipFileHandle );
 231.190 +		}
 231.191 +	}
 231.192 +	
 231.193 +	std::sort( m_FileList.begin(), m_FileList.end() );
 231.194 +	m_bDirty = false;
 231.195 +
 231.196 +	return true;
 231.197 +}
 231.198 +
 231.199 +// ------------------------------------------------------------------------------------------------
 231.200 +
 231.201 +} // Namespace Q3BSP
 231.202 +} // Namespace Assimp
 231.203 +
 231.204 +#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER
   232.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   232.2 +++ b/libs/assimp/Q3BSPZipArchive.h	Sat Feb 01 19:58:19 2014 +0200
   232.3 @@ -0,0 +1,183 @@
   232.4 +/*
   232.5 +Open Asset Import Library (assimp)
   232.6 +----------------------------------------------------------------------
   232.7 +
   232.8 +Copyright (c) 2006-2008, assimp team
   232.9 +All rights reserved.
  232.10 +
  232.11 +Redistribution and use of this software in source and binary forms, 
  232.12 +with or without modification, are permitted provided that the 
  232.13 +following conditions are met:
  232.14 +
  232.15 +* Redistributions of source code must retain the above
  232.16 +  copyright notice, this list of conditions and the
  232.17 +  following disclaimer.
  232.18 +
  232.19 +* Redistributions in binary form must reproduce the above
  232.20 +  copyright notice, this list of conditions and the
  232.21 +  following disclaimer in the documentation and/or other
  232.22 +  materials provided with the distribution.
  232.23 +
  232.24 +* Neither the name of the assimp team, nor the names of its
  232.25 +  contributors may be used to endorse or promote products
  232.26 +  derived from this software without specific prior
  232.27 +  written permission of the assimp team.
  232.28 +
  232.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  232.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  232.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  232.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  232.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  232.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  232.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  232.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  232.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  232.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  232.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  232.40 +
  232.41 +----------------------------------------------------------------------
  232.42 +*/
  232.43 +#ifndef AI_Q3BSP_ZIPARCHIVE_H_INC
  232.44 +#define AI_Q3BSP_ZIPARCHIVE_H_INC
  232.45 +
  232.46 +#include "../contrib/unzip/unzip.h"
  232.47 +#include "assimp/IOStream.hpp"
  232.48 +#include "assimp/IOSystem.hpp"
  232.49 +#include <string>
  232.50 +#include <vector>
  232.51 +#include <map>
  232.52 +#include <cassert>
  232.53 +
  232.54 +namespace Assimp
  232.55 +{
  232.56 +namespace Q3BSP
  232.57 +{
  232.58 +
  232.59 +// ------------------------------------------------------------------------------------------------
  232.60 +///	\class		ZipFile
  232.61 +///	\ingroup	Assimp::Q3BSP
  232.62 +///
  232.63 +///	\brief
  232.64 +// ------------------------------------------------------------------------------------------------
  232.65 +class ZipFile : public IOStream
  232.66 +{
  232.67 +public:
  232.68 +	ZipFile( const std::string &rFileName, unzFile zipFile ) :
  232.69 +		m_Name( rFileName ),
  232.70 +		m_zipFile( zipFile )
  232.71 +	{
  232.72 +		ai_assert( NULL != m_zipFile );
  232.73 +	}
  232.74 +	
  232.75 +	~ZipFile()
  232.76 +	{
  232.77 +		m_zipFile = NULL;
  232.78 +	}
  232.79 +
  232.80 +	size_t Read(void* pvBuffer, size_t pSize, size_t pCount )
  232.81 +	{
  232.82 +		size_t bytes_read = 0;
  232.83 +		if ( NULL == m_zipFile )
  232.84 +			return bytes_read;
  232.85 +		
  232.86 +		// search file and place file pointer there
  232.87 +		if ( unzLocateFile( m_zipFile, m_Name.c_str(), 0 ) == UNZ_OK )
  232.88 +		{
  232.89 +			// get file size, etc.
  232.90 +			unz_file_info fileInfo;
  232.91 +			unzGetCurrentFileInfo( m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0 );
  232.92 +			const size_t size = pSize * pCount;
  232.93 +			assert( size <= fileInfo.uncompressed_size );
  232.94 +			
  232.95 +			// The file has EXACTLY the size of uncompressed_size. In C
  232.96 +			// you need to mark the last character with '\0', so add 
  232.97 +			// another character
  232.98 +			unzOpenCurrentFile( m_zipFile );
  232.99 +			const int ret = unzReadCurrentFile( m_zipFile, pvBuffer, fileInfo.uncompressed_size);
 232.100 +			size_t filesize = fileInfo.uncompressed_size;
 232.101 +			if ( ret < 0 || size_t(ret) != filesize )
 232.102 +			{
 232.103 +				return 0;
 232.104 +			}
 232.105 +			bytes_read = ret;
 232.106 +			unzCloseCurrentFile( m_zipFile );
 232.107 +		}
 232.108 +		return bytes_read;
 232.109 +	}
 232.110 +
 232.111 +	size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/)
 232.112 +	{
 232.113 +		return 0;
 232.114 +	}
 232.115 +
 232.116 +	size_t FileSize() const
 232.117 +	{
 232.118 +		if ( NULL == m_zipFile )
 232.119 +			return 0;
 232.120 +		if ( unzLocateFile( m_zipFile, m_Name.c_str(), 0 ) == UNZ_OK ) 
 232.121 +		{
 232.122 +			unz_file_info fileInfo;
 232.123 +			unzGetCurrentFileInfo( m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0 );
 232.124 +			return fileInfo.uncompressed_size;
 232.125 +		}
 232.126 +		return 0;
 232.127 +	}
 232.128 +
 232.129 +	aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/)
 232.130 +	{
 232.131 +		return aiReturn_FAILURE;
 232.132 +	}
 232.133 +
 232.134 +    size_t Tell() const
 232.135 +	{
 232.136 +		return 0;
 232.137 +	}
 232.138 +
 232.139 +	void Flush()
 232.140 +	{
 232.141 +		// empty
 232.142 +	}
 232.143 +
 232.144 +private:
 232.145 +	std::string m_Name;
 232.146 +	unzFile m_zipFile;
 232.147 +};
 232.148 +
 232.149 +// ------------------------------------------------------------------------------------------------
 232.150 +///	\class		Q3BSPZipArchive
 232.151 +///	\ingroup	Assimp::Q3BSP
 232.152 +///	
 232.153 +///	\brief	IMplements a zip archive like the WinZip archives. Will be also used to import data 
 232.154 +///	from a P3K archive ( Quake level format ).
 232.155 +// ------------------------------------------------------------------------------------------------
 232.156 +class Q3BSPZipArchive : public Assimp::IOSystem
 232.157 +{
 232.158 +public:
 232.159 +	static const unsigned int FileNameSize = 256;
 232.160 +
 232.161 +public:
 232.162 +	Q3BSPZipArchive( const std::string & rFile );
 232.163 +	~Q3BSPZipArchive();
 232.164 +	bool Exists( const char* pFile) const;
 232.165 +	char getOsSeparator() const;
 232.166 +	IOStream* Open(const char* pFile, const char* pMode = "rb");
 232.167 +	void Close( IOStream* pFile);
 232.168 +	bool isOpen() const;
 232.169 +	void getFileList( std::vector<std::string> &rFileList );
 232.170 +
 232.171 +private:
 232.172 +	bool mapArchive();
 232.173 +
 232.174 +private:
 232.175 +	unzFile m_ZipFileHandle;
 232.176 +	std::map<std::string, IOStream*> m_ArchiveMap;
 232.177 +	std::vector<std::string> m_FileList;
 232.178 +	bool m_bDirty;
 232.179 +};
 232.180 +
 232.181 +// ------------------------------------------------------------------------------------------------
 232.182 +
 232.183 +} // Namespace Q3BSP
 232.184 +} // Namespace Assimp
 232.185 +
 232.186 +#endif // AI_Q3BSP_ZIPARCHIVE_H_INC
   233.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   233.2 +++ b/libs/assimp/Q3DLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   233.3 @@ -0,0 +1,611 @@
   233.4 +/*
   233.5 +---------------------------------------------------------------------------
   233.6 +Open Asset Import Library (assimp)
   233.7 +---------------------------------------------------------------------------
   233.8 +
   233.9 +Copyright (c) 2006-2012, assimp team
  233.10 +
  233.11 +All rights reserved.
  233.12 +
  233.13 +Redistribution and use of this software in source and binary forms, 
  233.14 +with or without modification, are permitted provided that the following 
  233.15 +conditions are met:
  233.16 +
  233.17 +* Redistributions of source code must retain the above
  233.18 +  copyright notice, this list of conditions and the
  233.19 +  following disclaimer.
  233.20 +
  233.21 +* Redistributions in binary form must reproduce the above
  233.22 +  copyright notice, this list of conditions and the
  233.23 +  following disclaimer in the documentation and/or other
  233.24 +  materials provided with the distribution.
  233.25 +
  233.26 +* Neither the name of the assimp team, nor the names of its
  233.27 +  contributors may be used to endorse or promote products
  233.28 +  derived from this software without specific prior
  233.29 +  written permission of the assimp team.
  233.30 +
  233.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  233.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  233.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  233.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  233.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  233.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  233.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  233.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  233.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  233.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  233.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  233.42 +---------------------------------------------------------------------------
  233.43 +*/
  233.44 +
  233.45 +/** @file  Q3DLoader.cpp
  233.46 + *  @brief Implementation of the Q3D importer class
  233.47 + */
  233.48 +
  233.49 +#include "AssimpPCH.h"
  233.50 +#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
  233.51 +
  233.52 +// internal headers
  233.53 +#include "Q3DLoader.h"
  233.54 +#include "StreamReader.h"
  233.55 +#include "fast_atof.h"
  233.56 +
  233.57 +using namespace Assimp;
  233.58 +
  233.59 +static const aiImporterDesc desc = {
  233.60 +	"Quick3D Importer",
  233.61 +	"",
  233.62 +	"",
  233.63 +	"http://www.quick3d.com/",
  233.64 +	aiImporterFlags_SupportBinaryFlavour,
  233.65 +	0,
  233.66 +	0,
  233.67 +	0,
  233.68 +	0,
  233.69 +	"q3o q3s" 
  233.70 +};
  233.71 +
  233.72 +// ------------------------------------------------------------------------------------------------
  233.73 +// Constructor to be privately used by Importer
  233.74 +Q3DImporter::Q3DImporter()
  233.75 +{}
  233.76 +
  233.77 +// ------------------------------------------------------------------------------------------------
  233.78 +// Destructor, private as well 
  233.79 +Q3DImporter::~Q3DImporter()
  233.80 +{}
  233.81 +
  233.82 +// ------------------------------------------------------------------------------------------------
  233.83 +// Returns whether the class can handle the format of the given file. 
  233.84 +bool Q3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  233.85 +{
  233.86 +	const std::string extension = GetExtension(pFile);
  233.87 +
  233.88 +	if (extension == "q3s" || extension == "q3o")
  233.89 +		return true;
  233.90 +	else if (!extension.length() || checkSig)	{
  233.91 +		if (!pIOHandler)
  233.92 +			return true;
  233.93 +		const char* tokens[] = {"quick3Do","quick3Ds"};
  233.94 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2);
  233.95 +	}
  233.96 +	return false;
  233.97 +}
  233.98 +
  233.99 +// ------------------------------------------------------------------------------------------------
 233.100 +const aiImporterDesc* Q3DImporter::GetInfo () const
 233.101 +{
 233.102 +	return &desc;
 233.103 +}
 233.104 +
 233.105 +// ------------------------------------------------------------------------------------------------
 233.106 +// Imports the given file into the given scene structure. 
 233.107 +void Q3DImporter::InternReadFile( const std::string& pFile, 
 233.108 +	aiScene* pScene, IOSystem* pIOHandler)
 233.109 +{
 233.110 +	StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
 233.111 +
 233.112 +	// The header is 22 bytes large
 233.113 +	if (stream.GetRemainingSize() < 22)
 233.114 +		throw DeadlyImportError("File is either empty or corrupt: " + pFile);
 233.115 +
 233.116 +	// Check the file's signature
 233.117 +	if (ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Do", 8 ) &&
 233.118 +		ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Ds", 8 ))
 233.119 +	{
 233.120 +		throw DeadlyImportError("Not a Quick3D file. Signature string is: " + 
 233.121 +			std::string((const char*)stream.GetPtr(),8));
 233.122 +	}
 233.123 +
 233.124 +	// Print the file format version
 233.125 +	DefaultLogger::get()->info("Quick3D File format version: " + 
 233.126 +		std::string(&((const char*)stream.GetPtr())[8],2));
 233.127 +
 233.128 +	// ... an store it
 233.129 +	char major = ((const char*)stream.GetPtr())[8];
 233.130 +	char minor = ((const char*)stream.GetPtr())[9];
 233.131 +
 233.132 +	stream.IncPtr(10);
 233.133 +	unsigned int numMeshes    = (unsigned int)stream.GetI4();
 233.134 +	unsigned int numMats      = (unsigned int)stream.GetI4();
 233.135 +	unsigned int numTextures  = (unsigned int)stream.GetI4();
 233.136 +
 233.137 +	std::vector<Material> materials;
 233.138 +	materials.reserve(numMats);
 233.139 +
 233.140 +	std::vector<Mesh> meshes;
 233.141 +	meshes.reserve(numMeshes);
 233.142 +
 233.143 +	// Allocate the scene root node
 233.144 +	pScene->mRootNode = new aiNode();
 233.145 +
 233.146 +	aiColor3D fgColor (0.6f,0.6f,0.6f);
 233.147 +
 233.148 +	// Now read all file chunks
 233.149 +	while (true)
 233.150 +	{
 233.151 +		if (stream.GetRemainingSize() < 1)break;
 233.152 +		char c = stream.GetI1();
 233.153 +		switch (c)
 233.154 +		{
 233.155 +			// Meshes chunk
 233.156 +		case 'm':
 233.157 +			{
 233.158 +				for (unsigned int quak = 0; quak < numMeshes; ++quak)
 233.159 +				{
 233.160 +					meshes.push_back(Mesh());
 233.161 +					Mesh& mesh = meshes.back();
 233.162 +
 233.163 +					// read all vertices
 233.164 +					unsigned int numVerts = (unsigned int)stream.GetI4();
 233.165 +					if (!numVerts)
 233.166 +						throw DeadlyImportError("Quick3D: Found mesh with zero vertices");
 233.167 +
 233.168 +					std::vector<aiVector3D>& verts = mesh.verts;
 233.169 +					verts.resize(numVerts);
 233.170 +
 233.171 +					for (unsigned int i = 0; i < numVerts;++i)
 233.172 +					{
 233.173 +						verts[i].x = stream.GetF4();
 233.174 +						verts[i].y = stream.GetF4();
 233.175 +						verts[i].z = stream.GetF4();
 233.176 +					}
 233.177 +
 233.178 +					// read all faces
 233.179 +					numVerts = (unsigned int)stream.GetI4();
 233.180 +					if (!numVerts)
 233.181 +						throw DeadlyImportError("Quick3D: Found mesh with zero faces");
 233.182 +
 233.183 +					std::vector<Face >& faces = mesh.faces;
 233.184 +					faces.reserve(numVerts);
 233.185 +
 233.186 +					// number of indices
 233.187 +					for (unsigned int i = 0; i < numVerts;++i)
 233.188 +					{
 233.189 +						faces.push_back(Face(stream.GetI2()) );
 233.190 +						if (faces.back().indices.empty())
 233.191 +							throw DeadlyImportError("Quick3D: Found face with zero indices");
 233.192 +					}
 233.193 +
 233.194 +					// indices
 233.195 +					for (unsigned int i = 0; i < numVerts;++i)
 233.196 +					{
 233.197 +						Face& vec = faces[i];
 233.198 +						for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
 233.199 +							vec.indices[a] = stream.GetI4();
 233.200 +					}
 233.201 +
 233.202 +					// material indices
 233.203 +					for (unsigned int i = 0; i < numVerts;++i)
 233.204 +					{
 233.205 +						faces[i].mat = (unsigned int)stream.GetI4();
 233.206 +					}
 233.207 +
 233.208 +					// read all normals
 233.209 +					numVerts = (unsigned int)stream.GetI4();
 233.210 +					std::vector<aiVector3D>& normals = mesh.normals;
 233.211 +					normals.resize(numVerts);
 233.212 +
 233.213 +					for (unsigned int i = 0; i < numVerts;++i)
 233.214 +					{
 233.215 +						normals[i].x = stream.GetF4();
 233.216 +						normals[i].y = stream.GetF4();
 233.217 +						normals[i].z = stream.GetF4();
 233.218 +					}
 233.219 +
 233.220 +					numVerts = (unsigned int)stream.GetI4();
 233.221 +					if (numTextures && numVerts)
 233.222 +					{
 233.223 +						// read all texture coordinates
 233.224 +						std::vector<aiVector3D>& uv = mesh.uv;
 233.225 +						uv.resize(numVerts);
 233.226 +
 233.227 +						for (unsigned int i = 0; i < numVerts;++i)
 233.228 +						{
 233.229 +							uv[i].x = stream.GetF4();
 233.230 +							uv[i].y = stream.GetF4();
 233.231 +						}
 233.232 +
 233.233 +						// UV indices
 233.234 +						for (unsigned int i = 0; i < (unsigned int)faces.size();++i)
 233.235 +						{
 233.236 +							Face& vec = faces[i];
 233.237 +							for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
 233.238 +							{
 233.239 +								vec.uvindices[a] = stream.GetI4();
 233.240 +								if (!i && !a)
 233.241 +									mesh.prevUVIdx = vec.uvindices[a];
 233.242 +								else if (vec.uvindices[a] != mesh.prevUVIdx)
 233.243 +									mesh.prevUVIdx = UINT_MAX;
 233.244 +							}
 233.245 +						}
 233.246 +					}
 233.247 +
 233.248 +					// we don't need the rest, but we need to get to the next chunk
 233.249 +					stream.IncPtr(36);
 233.250 +					if (minor > '0' && major == '3')
 233.251 +						stream.IncPtr(mesh.faces.size());
 233.252 +				}
 233.253 +				// stream.IncPtr(4); // unknown value here
 233.254 +			}
 233.255 +			break;
 233.256 +
 233.257 +			// materials chunk 
 233.258 +		case 'c':
 233.259 +
 233.260 +			for (unsigned int i = 0; i < numMats; ++i)
 233.261 +			{
 233.262 +				materials.push_back(Material());
 233.263 +				Material& mat = materials.back();
 233.264 +
 233.265 +				// read the material name
 233.266 +				while (( c = stream.GetI1()))
 233.267 +					mat.name.data[mat.name.length++] = c;
 233.268 +				
 233.269 +				// add the terminal character
 233.270 +				mat.name.data[mat.name.length] = '\0';
 233.271 +
 233.272 +				// read the ambient color
 233.273 +				mat.ambient.r = stream.GetF4();
 233.274 +				mat.ambient.g = stream.GetF4();
 233.275 +				mat.ambient.b = stream.GetF4();
 233.276 +
 233.277 +				// read the diffuse color
 233.278 +				mat.diffuse.r = stream.GetF4();
 233.279 +				mat.diffuse.g = stream.GetF4();
 233.280 +				mat.diffuse.b = stream.GetF4();
 233.281 +
 233.282 +				// read the ambient color
 233.283 +				mat.specular.r = stream.GetF4();
 233.284 +				mat.specular.g = stream.GetF4();
 233.285 +				mat.specular.b = stream.GetF4();
 233.286 +
 233.287 +				// read the transparency
 233.288 +				mat.transparency = stream.GetF4();
 233.289 +
 233.290 +				// unknown value here
 233.291 +				// stream.IncPtr(4);
 233.292 +				// FIX: it could be the texture index ...
 233.293 +				mat.texIdx = (unsigned int)stream.GetI4();
 233.294 +			}
 233.295 +
 233.296 +			break;
 233.297 +
 233.298 +			// texture chunk
 233.299 +		case 't':
 233.300 +
 233.301 +			pScene->mNumTextures = numTextures;
 233.302 +			if (!numTextures)break;
 233.303 +			pScene->mTextures    = new aiTexture*[pScene->mNumTextures];
 233.304 +			// to make sure we won't crash if we leave through an exception
 233.305 +			::memset(pScene->mTextures,0,sizeof(void*)*pScene->mNumTextures);
 233.306 +			for (unsigned int i = 0; i < pScene->mNumTextures; ++i)
 233.307 +			{
 233.308 +				aiTexture* tex = pScene->mTextures[i] = new aiTexture();
 233.309 +
 233.310 +				// skip the texture name
 233.311 +				while (stream.GetI1());
 233.312 +
 233.313 +				// read texture width and height
 233.314 +				tex->mWidth  = (unsigned int)stream.GetI4();
 233.315 +				tex->mHeight = (unsigned int)stream.GetI4();
 233.316 +
 233.317 +				if (!tex->mWidth || !tex->mHeight)
 233.318 +					throw DeadlyImportError("Quick3D: Invalid texture. Width or height is zero");
 233.319 +
 233.320 +				register unsigned int mul = tex->mWidth * tex->mHeight;
 233.321 +				aiTexel* begin = tex->pcData = new aiTexel[mul];
 233.322 +				aiTexel* const end = & begin [mul];
 233.323 +
 233.324 +				for (;begin != end; ++begin)
 233.325 +				{
 233.326 +					begin->r = stream.GetI1();
 233.327 +					begin->g = stream.GetI1();
 233.328 +					begin->b = stream.GetI1();
 233.329 +					begin->a = 0xff;
 233.330 +				}
 233.331 +			}
 233.332 +
 233.333 +			break;
 233.334 +
 233.335 +			// scene chunk
 233.336 +		case 's':
 233.337 +			{
 233.338 +				// skip position and rotation
 233.339 +				stream.IncPtr(12);
 233.340 +
 233.341 +				for (unsigned int i = 0; i < 4;++i)
 233.342 +					for (unsigned int a = 0; a < 4;++a)
 233.343 +						pScene->mRootNode->mTransformation[i][a] = stream.GetF4();
 233.344 +				
 233.345 +				stream.IncPtr(16);
 233.346 +
 233.347 +				// now setup a single camera
 233.348 +				pScene->mNumCameras = 1;
 233.349 +				pScene->mCameras = new aiCamera*[1];
 233.350 +				aiCamera* cam = pScene->mCameras[0] = new aiCamera();
 233.351 +				cam->mPosition.x = stream.GetF4();
 233.352 +				cam->mPosition.y = stream.GetF4();
 233.353 +				cam->mPosition.z = stream.GetF4();
 233.354 +				cam->mName.Set("Q3DCamera");
 233.355 +
 233.356 +				// skip eye rotation for the moment
 233.357 +				stream.IncPtr(12);
 233.358 +
 233.359 +				// read the default material color
 233.360 +				fgColor .r = stream.GetF4();
 233.361 +				fgColor .g = stream.GetF4();
 233.362 +				fgColor .b = stream.GetF4();
 233.363 +
 233.364 +				// skip some unimportant properties
 233.365 +				stream.IncPtr(29);
 233.366 +
 233.367 +				// setup a single point light with no attenuation
 233.368 +				pScene->mNumLights = 1;
 233.369 +				pScene->mLights = new aiLight*[1];
 233.370 +				aiLight* light = pScene->mLights[0] = new aiLight();
 233.371 +				light->mName.Set("Q3DLight");
 233.372 +				light->mType = aiLightSource_POINT;
 233.373 +
 233.374 +				light->mAttenuationConstant  = 1;
 233.375 +				light->mAttenuationLinear    = 0;
 233.376 +				light->mAttenuationQuadratic = 0;
 233.377 +
 233.378 +				light->mColorDiffuse.r = stream.GetF4();
 233.379 +				light->mColorDiffuse.g = stream.GetF4();
 233.380 +				light->mColorDiffuse.b = stream.GetF4();
 233.381 +
 233.382 +				light->mColorSpecular = light->mColorDiffuse;
 233.383 +
 233.384 +
 233.385 +				// We don't need the rest, but we need to know where this chunk ends.
 233.386 +				unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4());
 233.387 +
 233.388 +				// skip the background file name
 233.389 +				while (stream.GetI1());
 233.390 +
 233.391 +				// skip background texture data + the remaining fields 
 233.392 +				stream.IncPtr(temp*3 + 20); // 4 bytes of unknown data here
 233.393 +
 233.394 +				// TODO
 233.395 +				goto outer;
 233.396 +			}
 233.397 +			break;
 233.398 +
 233.399 +		default:
 233.400 +			throw DeadlyImportError("Quick3D: Unknown chunk");
 233.401 +			break;
 233.402 +		};
 233.403 +	}
 233.404 +outer:
 233.405 +
 233.406 +	// If we have no mesh loaded - break here
 233.407 +	if (meshes.empty())
 233.408 +		throw DeadlyImportError("Quick3D: No meshes loaded");
 233.409 +
 233.410 +	// If we have no materials loaded - generate a default mat
 233.411 +	if (materials.empty())
 233.412 +	{
 233.413 +		DefaultLogger::get()->info("Quick3D: No material found, generating one");
 233.414 +		materials.push_back(Material());
 233.415 +		materials.back().diffuse  = fgColor ;
 233.416 +	}
 233.417 +
 233.418 +	// find out which materials we'll need
 233.419 +	typedef std::pair<unsigned int, unsigned int> FaceIdx;
 233.420 +	typedef std::vector< FaceIdx > FaceIdxArray;
 233.421 +	FaceIdxArray* fidx = new FaceIdxArray[materials.size()]; 
 233.422 +
 233.423 +	unsigned int p = 0;
 233.424 +	for (std::vector<Mesh>::iterator it = meshes.begin(), end = meshes.end();
 233.425 +		 it != end; ++it,++p)
 233.426 +	{
 233.427 +		unsigned int q = 0;
 233.428 +		for (std::vector<Face>::iterator fit = (*it).faces.begin(), fend = (*it).faces.end();
 233.429 +			 fit != fend; ++fit,++q)
 233.430 +		{
 233.431 +			if ((*fit).mat >= materials.size())
 233.432 +			{
 233.433 +				DefaultLogger::get()->warn("Quick3D: Material index overflow");
 233.434 +				(*fit).mat = 0;
 233.435 +			}
 233.436 +			if (fidx[(*fit).mat].empty())++pScene->mNumMeshes;
 233.437 +			fidx[(*fit).mat].push_back( FaceIdx(p,q) );
 233.438 +		}
 233.439 +	}
 233.440 +	pScene->mNumMaterials = pScene->mNumMeshes;
 233.441 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
 233.442 +	pScene->mMeshes = new aiMesh*[pScene->mNumMaterials];
 233.443 +
 233.444 +	for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i)
 233.445 +	{
 233.446 +		if (fidx[i].empty())continue;
 233.447 +
 233.448 +		// Allocate a mesh and a material
 233.449 +		aiMesh* mesh = pScene->mMeshes[real] = new aiMesh();
 233.450 +		aiMaterial* mat = new aiMaterial();
 233.451 +		pScene->mMaterials[real] = mat;
 233.452 +
 233.453 +		mesh->mMaterialIndex = real;
 233.454 +
 233.455 +		// Build the output material
 233.456 +		Material& srcMat = materials[i];
 233.457 +		mat->AddProperty(&srcMat.diffuse,  1,AI_MATKEY_COLOR_DIFFUSE);
 233.458 +		mat->AddProperty(&srcMat.specular, 1,AI_MATKEY_COLOR_SPECULAR);
 233.459 +		mat->AddProperty(&srcMat.ambient,  1,AI_MATKEY_COLOR_AMBIENT);
 233.460 +	
 233.461 +		// NOTE: Ignore transparency for the moment - it seems
 233.462 +		// unclear how to interpret the data
 233.463 +#if 0
 233.464 +		if (!(minor > '0' && major == '3'))
 233.465 +			srcMat.transparency = 1.0f - srcMat.transparency;
 233.466 +		mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_OPACITY);
 233.467 +#endif
 233.468 +
 233.469 +		// add shininess - Quick3D seems to use it ins its viewer
 233.470 +		srcMat.transparency = 16.f;
 233.471 +		mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_SHININESS);
 233.472 +
 233.473 +		int m = (int)aiShadingMode_Phong;
 233.474 +		mat->AddProperty(&m, 1, AI_MATKEY_SHADING_MODEL);
 233.475 +
 233.476 +		if (srcMat.name.length)
 233.477 +			mat->AddProperty(&srcMat.name,AI_MATKEY_NAME);
 233.478 +
 233.479 +		// Add a texture
 233.480 +		if (srcMat.texIdx < pScene->mNumTextures || real < pScene->mNumTextures)
 233.481 +		{
 233.482 +			srcMat.name.data[0] = '*';
 233.483 +			srcMat.name.length  = ASSIMP_itoa10(&srcMat.name.data[1],1000,
 233.484 +				(srcMat.texIdx < pScene->mNumTextures ? srcMat.texIdx : real));
 233.485 +			mat->AddProperty(&srcMat.name,AI_MATKEY_TEXTURE_DIFFUSE(0));
 233.486 +		}
 233.487 +
 233.488 +		mesh->mNumFaces = (unsigned int)fidx[i].size();
 233.489 +		aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
 233.490 +
 233.491 +		// Now build the output mesh. First find out how many
 233.492 +		// vertices we'll need
 233.493 +		for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end();
 233.494 +			 it != end; ++it)
 233.495 +		{
 233.496 +			mesh->mNumVertices += (unsigned int)meshes[(*it).first].faces[
 233.497 +				(*it).second].indices.size();
 233.498 +		}
 233.499 +
 233.500 +		aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
 233.501 +		aiVector3D* norms = mesh->mNormals  = new aiVector3D[mesh->mNumVertices];
 233.502 +		aiVector3D* uv;
 233.503 +		if (real < pScene->mNumTextures)
 233.504 +		{
 233.505 +			uv = mesh->mTextureCoords[0] =  new aiVector3D[mesh->mNumVertices];
 233.506 +			mesh->mNumUVComponents[0]    =  2;
 233.507 +		}
 233.508 +		else uv = NULL;
 233.509 +
 233.510 +		// Build the final array
 233.511 +		unsigned int cnt = 0;
 233.512 +		for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end();
 233.513 +			 it != end; ++it, ++faces)
 233.514 +		{
 233.515 +			Mesh& m    = meshes[(*it).first];
 233.516 +			Face& face = m.faces[(*it).second];
 233.517 +			faces->mNumIndices = (unsigned int)face.indices.size();
 233.518 +			faces->mIndices = new unsigned int [faces->mNumIndices]; 
 233.519 +
 233.520 +
 233.521 +			aiVector3D faceNormal;
 233.522 +			bool fnOK = false;
 233.523 +
 233.524 +			for (unsigned int n = 0; n < faces->mNumIndices;++n, ++cnt, ++norms, ++verts)
 233.525 +			{
 233.526 +				if (face.indices[n] >= m.verts.size())
 233.527 +				{
 233.528 +					DefaultLogger::get()->warn("Quick3D: Vertex index overflow");
 233.529 +					face.indices[n] = 0;
 233.530 +				}
 233.531 +
 233.532 +				// copy vertices
 233.533 +				*verts =  m.verts[ face.indices[n] ];
 233.534 +
 233.535 +				if (face.indices[n] >= m.normals.size() && faces->mNumIndices >= 3)
 233.536 +				{
 233.537 +					// we have no normal here - assign the face normal
 233.538 +					if (!fnOK)
 233.539 +					{
 233.540 +						const aiVector3D& pV1 =  m.verts[ face.indices[0] ];
 233.541 +						const aiVector3D& pV2 =  m.verts[ face.indices[1] ];
 233.542 +						const aiVector3D& pV3 =  m.verts[ face.indices.size() - 1 ];
 233.543 +						faceNormal = (pV2 - pV1) ^ (pV3 - pV1).Normalize();
 233.544 +						fnOK = true;
 233.545 +					}
 233.546 +					*norms = faceNormal;
 233.547 +				}
 233.548 +				else *norms =  m.normals[ face.indices[n] ];
 233.549 +
 233.550 +				// copy texture coordinates
 233.551 +				if (uv && m.uv.size())
 233.552 +				{
 233.553 +					if (m.prevUVIdx != 0xffffffff && m.uv.size() >= m.verts.size()) // workaround
 233.554 +					{
 233.555 +						*uv = m.uv[face.indices[n]];
 233.556 +					}
 233.557 +					else
 233.558 +					{
 233.559 +						if (face.uvindices[n] >= m.uv.size())
 233.560 +						{
 233.561 +							DefaultLogger::get()->warn("Quick3D: Texture coordinate index overflow");
 233.562 +							face.uvindices[n] = 0;
 233.563 +						}
 233.564 +						*uv = m.uv[face.uvindices[n]];
 233.565 +					}
 233.566 +					uv->y = 1.f - uv->y;
 233.567 +					++uv;
 233.568 +				}
 233.569 +
 233.570 +				// setup the new vertex index
 233.571 +				faces->mIndices[n] = cnt;
 233.572 +			}
 233.573 +
 233.574 +		}
 233.575 +		++real;
 233.576 +	}
 233.577 +
 233.578 +	// Delete our nice helper array
 233.579 +	delete[] fidx;
 233.580 +
 233.581 +	// Now we need to attach the meshes to the root node of the scene
 233.582 +	pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
 233.583 +	pScene->mRootNode->mMeshes = new unsigned int [pScene->mNumMeshes];
 233.584 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
 233.585 +		pScene->mRootNode->mMeshes[i] = i;
 233.586 +
 233.587 +	/*pScene->mRootNode->mTransformation *= aiMatrix4x4(
 233.588 +		1.f, 0.f, 0.f, 0.f,
 233.589 +	    0.f, -1.f,0.f, 0.f,
 233.590 +		0.f, 0.f, 1.f, 0.f,
 233.591 +		0.f, 0.f, 0.f, 1.f);*/
 233.592 +
 233.593 +	// Add cameras and light sources to the scene root node
 233.594 +	pScene->mRootNode->mNumChildren = pScene->mNumLights+pScene->mNumCameras;
 233.595 +	if (pScene->mRootNode->mNumChildren)
 233.596 +	{
 233.597 +		pScene->mRootNode->mChildren = new aiNode* [ pScene->mRootNode->mNumChildren ];
 233.598 +
 233.599 +		// the light source
 233.600 +		aiNode* nd = pScene->mRootNode->mChildren[0] = new aiNode();
 233.601 +		nd->mParent = pScene->mRootNode;
 233.602 +		nd->mName.Set("Q3DLight");
 233.603 +		nd->mTransformation = pScene->mRootNode->mTransformation;
 233.604 +		nd->mTransformation.Inverse();
 233.605 +
 233.606 +		// camera
 233.607 +		nd = pScene->mRootNode->mChildren[1] = new aiNode();
 233.608 +		nd->mParent = pScene->mRootNode;
 233.609 +		nd->mName.Set("Q3DCamera");
 233.610 +		nd->mTransformation = pScene->mRootNode->mChildren[0]->mTransformation;
 233.611 +	}
 233.612 +}
 233.613 +
 233.614 +#endif // !! ASSIMP_BUILD_NO_Q3D_IMPORTER
   234.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   234.2 +++ b/libs/assimp/Q3DLoader.h	Sat Feb 01 19:58:19 2014 +0200
   234.3 @@ -0,0 +1,131 @@
   234.4 +/*
   234.5 +Open Asset Import Library (assimp)
   234.6 +----------------------------------------------------------------------
   234.7 +
   234.8 +Copyright (c) 2006-2012, assimp team
   234.9 +All rights reserved.
  234.10 +
  234.11 +Redistribution and use of this software in source and binary forms, 
  234.12 +with or without modification, are permitted provided that the 
  234.13 +following conditions are met:
  234.14 +
  234.15 +* Redistributions of source code must retain the above
  234.16 +  copyright notice, this list of conditions and the
  234.17 +  following disclaimer.
  234.18 +
  234.19 +* Redistributions in binary form must reproduce the above
  234.20 +  copyright notice, this list of conditions and the
  234.21 +  following disclaimer in the documentation and/or other
  234.22 +  materials provided with the distribution.
  234.23 +
  234.24 +* Neither the name of the assimp team, nor the names of its
  234.25 +  contributors may be used to endorse or promote products
  234.26 +  derived from this software without specific prior
  234.27 +  written permission of the assimp team.
  234.28 +
  234.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  234.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  234.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  234.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  234.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  234.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  234.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  234.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  234.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  234.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  234.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  234.40 +
  234.41 +----------------------------------------------------------------------
  234.42 +*/
  234.43 +
  234.44 +/** @file  Q3DLoader.h
  234.45 + *  @brief Declaration of the Q3D importer class.
  234.46 + */
  234.47 +#ifndef AI_Q3DLOADER_H_INCLUDED
  234.48 +#define AI_Q3DLOADER_H_INCLUDED
  234.49 +
  234.50 +#include "BaseImporter.h"
  234.51 +#include "assimp/types.h"
  234.52 +#include <vector>
  234.53 +
  234.54 +namespace Assimp	{
  234.55 +
  234.56 +// ---------------------------------------------------------------------------
  234.57 +/** Importer class for the Quick3D Object and Scene formats.
  234.58 +*/
  234.59 +class Q3DImporter : public BaseImporter
  234.60 +{
  234.61 +public:
  234.62 +	Q3DImporter();
  234.63 +	~Q3DImporter();
  234.64 +
  234.65 +
  234.66 +public:
  234.67 +
  234.68 +	// -------------------------------------------------------------------
  234.69 +	/** Returns whether the class can handle the format of the given file. 
  234.70 +	* See BaseImporter::CanRead() for details.	*/
  234.71 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  234.72 +		bool checkSig) const;
  234.73 +
  234.74 +protected:
  234.75 +
  234.76 +	// -------------------------------------------------------------------
  234.77 +	/** Return importer meta information.
  234.78 +	 * See #BaseImporter::GetInfo for the details
  234.79 +	 */
  234.80 +	const aiImporterDesc* GetInfo () const;
  234.81 +
  234.82 +	// -------------------------------------------------------------------
  234.83 +	/** Imports the given file into the given scene structure. 
  234.84 +	* See BaseImporter::InternReadFile() for details
  234.85 +	*/
  234.86 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  234.87 +		IOSystem* pIOHandler);
  234.88 +
  234.89 +private:
  234.90 +
  234.91 +	struct Material
  234.92 +	{
  234.93 +		Material()
  234.94 +			:	diffuse			(0.6f,0.6f,0.6f)
  234.95 +			,	transparency	(0.f)
  234.96 +			,	texIdx			(UINT_MAX)
  234.97 +		{}
  234.98 +
  234.99 +		aiString name;
 234.100 +		aiColor3D ambient, diffuse, specular;
 234.101 +		float transparency;
 234.102 +
 234.103 +		unsigned int texIdx;
 234.104 +	};
 234.105 +
 234.106 +	struct Face
 234.107 +	{
 234.108 +		Face(unsigned int s)
 234.109 +			:	indices	  (s)
 234.110 +			,	uvindices (s)
 234.111 +			,	mat		  (0)
 234.112 +		{
 234.113 +		}
 234.114 +
 234.115 +		std::vector<unsigned int> indices;
 234.116 +		std::vector<unsigned int> uvindices;
 234.117 +		unsigned int mat;
 234.118 +	};
 234.119 +
 234.120 +	struct Mesh
 234.121 +	{
 234.122 +
 234.123 +		std::vector<aiVector3D> verts;
 234.124 +		std::vector<aiVector3D> normals;
 234.125 +		std::vector<aiVector3D> uv;
 234.126 +		std::vector<Face>       faces;
 234.127 +
 234.128 +		uint32_t prevUVIdx;
 234.129 +	};
 234.130 +};
 234.131 +
 234.132 +} // end of namespace Assimp
 234.133 +
 234.134 +#endif // AI_Q3DIMPORTER_H_IN
   235.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   235.2 +++ b/libs/assimp/RawLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   235.3 @@ -0,0 +1,324 @@
   235.4 +/*
   235.5 +---------------------------------------------------------------------------
   235.6 +Open Asset Import Library (assimp)
   235.7 +---------------------------------------------------------------------------
   235.8 +
   235.9 +Copyright (c) 2006-2012, assimp team
  235.10 +
  235.11 +All rights reserved.
  235.12 +
  235.13 +Redistribution and use of this software in source and binary forms, 
  235.14 +with or without modification, are permitted provided that the following 
  235.15 +conditions are met:
  235.16 +
  235.17 +* Redistributions of source code must retain the above
  235.18 +  copyright notice, this list of conditions and the
  235.19 +  following disclaimer.
  235.20 +
  235.21 +* Redistributions in binary form must reproduce the above
  235.22 +  copyright notice, this list of conditions and the
  235.23 +  following disclaimer in the documentation and/or other
  235.24 +  materials provided with the distribution.
  235.25 +
  235.26 +* Neither the name of the assimp team, nor the names of its
  235.27 +  contributors may be used to endorse or promote products
  235.28 +  derived from this software without specific prior
  235.29 +  written permission of the assimp team.
  235.30 +
  235.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  235.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  235.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  235.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  235.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  235.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  235.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  235.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  235.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  235.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  235.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  235.42 +---------------------------------------------------------------------------
  235.43 +*/
  235.44 +
  235.45 +/** @file  RawLoader.cpp
  235.46 + *  @brief Implementation of the RAW importer class 
  235.47 + */
  235.48 +
  235.49 +#include "AssimpPCH.h"
  235.50 +#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
  235.51 +
  235.52 +// internal headers
  235.53 +#include "RawLoader.h"
  235.54 +#include "ParsingUtils.h"
  235.55 +#include "fast_atof.h"
  235.56 +
  235.57 +using namespace Assimp;
  235.58 +
  235.59 +static const aiImporterDesc desc = {
  235.60 +	"Raw Importer",
  235.61 +	"",
  235.62 +	"",
  235.63 +	"",
  235.64 +	aiImporterFlags_SupportTextFlavour,
  235.65 +	0,
  235.66 +	0,
  235.67 +	0,
  235.68 +	0,
  235.69 +	"raw"
  235.70 +};
  235.71 +
  235.72 +// ------------------------------------------------------------------------------------------------
  235.73 +// Constructor to be privately used by Importer
  235.74 +RAWImporter::RAWImporter()
  235.75 +{}
  235.76 +
  235.77 +// ------------------------------------------------------------------------------------------------
  235.78 +// Destructor, private as well 
  235.79 +RAWImporter::~RAWImporter()
  235.80 +{}
  235.81 +
  235.82 +// ------------------------------------------------------------------------------------------------
  235.83 +// Returns whether the class can handle the format of the given file. 
  235.84 +bool RAWImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
  235.85 +{
  235.86 +	return SimpleExtensionCheck(pFile,"raw");
  235.87 +}
  235.88 +
  235.89 +// ------------------------------------------------------------------------------------------------
  235.90 +const aiImporterDesc* RAWImporter::GetInfo () const
  235.91 +{
  235.92 +	return &desc;
  235.93 +}
  235.94 +
  235.95 +// ------------------------------------------------------------------------------------------------
  235.96 +// Imports the given file into the given scene structure. 
  235.97 +void RAWImporter::InternReadFile( const std::string& pFile, 
  235.98 +	aiScene* pScene, IOSystem* pIOHandler)
  235.99 +{
 235.100 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 235.101 +
 235.102 +	// Check whether we can read from the file
 235.103 +	if( file.get() == NULL) {
 235.104 +		throw DeadlyImportError( "Failed to open RAW file " + pFile + ".");
 235.105 +	}
 235.106 +
 235.107 +	// allocate storage and copy the contents of the file to a memory buffer
 235.108 +	// (terminate it with zero)
 235.109 +	std::vector<char> mBuffer2;
 235.110 +	TextFileToBuffer(file.get(),mBuffer2);
 235.111 +	const char* buffer = &mBuffer2[0];
 235.112 +
 235.113 +	// list of groups loaded from the file
 235.114 +	std::vector< GroupInformation > outGroups(1,GroupInformation("<default>"));
 235.115 +	std::vector< GroupInformation >::iterator curGroup = outGroups.begin();
 235.116 +
 235.117 +	// now read all lines
 235.118 +	char line[4096];
 235.119 +	while (GetNextLine(buffer,line))
 235.120 +	{
 235.121 +		// if the line starts with a non-numeric identifier, it marks
 235.122 +		// the beginning of a new group
 235.123 +		const char* sz = line;SkipSpaces(&sz);
 235.124 +		if (IsLineEnd(*sz))continue;
 235.125 +		if (!IsNumeric(*sz))
 235.126 +		{
 235.127 +			const char* sz2 = sz;
 235.128 +			while (!IsSpaceOrNewLine(*sz2))++sz2;
 235.129 +			const unsigned int length = (unsigned int)(sz2-sz);
 235.130 +
 235.131 +			// find an existing group with this name
 235.132 +			for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
 235.133 +				it != end;++it)
 235.134 +			{
 235.135 +				if (length == (*it).name.length() && !::strcmp(sz,(*it).name.c_str()))
 235.136 +				{
 235.137 +					curGroup = it;sz2 = NULL;
 235.138 +					break;
 235.139 +				}
 235.140 +			}
 235.141 +			if (sz2)
 235.142 +			{
 235.143 +				outGroups.push_back(GroupInformation(std::string(sz,length)));
 235.144 +				curGroup = outGroups.end()-1;
 235.145 +			}
 235.146 +		}
 235.147 +		else
 235.148 +		{
 235.149 +			// there can be maximally 12 floats plus an extra texture file name
 235.150 +			float data[12];
 235.151 +			unsigned int num;
 235.152 +			for (num = 0; num < 12;++num)
 235.153 +			{
 235.154 +				if(!SkipSpaces(&sz) || !IsNumeric(*sz))break;
 235.155 +				sz = fast_atoreal_move<float>(sz,data[num]);
 235.156 +			}
 235.157 +			if (num != 12 && num != 9)
 235.158 +			{
 235.159 +				DefaultLogger::get()->error("A line may have either 9 or 12 floats and an optional texture");
 235.160 +				continue;
 235.161 +			}
 235.162 +
 235.163 +			MeshInformation* output = NULL;
 235.164 +
 235.165 +			const char* sz2 = sz;
 235.166 +			unsigned int length;
 235.167 +			if (!IsLineEnd(*sz))
 235.168 +			{
 235.169 +				while (!IsSpaceOrNewLine(*sz2))++sz2;
 235.170 +				length = (unsigned int)(sz2-sz);
 235.171 +			}
 235.172 +			else if (9 == num)
 235.173 +			{
 235.174 +				sz = "%default%";
 235.175 +				length = 9;
 235.176 +			}
 235.177 +			else 
 235.178 +			{
 235.179 +				sz = "";
 235.180 +				length = 0;
 235.181 +			}
 235.182 +
 235.183 +			// search in the list of meshes whether we have one with this texture
 235.184 +			for (std::vector< MeshInformation >::iterator it = (*curGroup).meshes.begin(),
 235.185 +				end = (*curGroup).meshes.end(); it != end; ++it)
 235.186 +			{
 235.187 +				if (length == (*it).name.length() && (length ? !::strcmp(sz,(*it).name.c_str()) : true))
 235.188 +				{
 235.189 +					output = &(*it);
 235.190 +					break;
 235.191 +				}
 235.192 +			}
 235.193 +			// if we don't have the mesh, create it
 235.194 +			if (!output)
 235.195 +			{
 235.196 +				(*curGroup).meshes.push_back(MeshInformation(std::string(sz,length)));
 235.197 +				output = &((*curGroup).meshes.back());
 235.198 +			}
 235.199 +			if (12 == num)
 235.200 +			{
 235.201 +				aiColor4D v(data[0],data[1],data[2],1.0f);
 235.202 +				output->colors.push_back(v);
 235.203 +				output->colors.push_back(v);
 235.204 +				output->colors.push_back(v);
 235.205 +
 235.206 +				output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
 235.207 +				output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
 235.208 +				output->vertices.push_back(aiVector3D(data[9],data[10],data[11]));
 235.209 +			}
 235.210 +			else
 235.211 +			{
 235.212 +				output->vertices.push_back(aiVector3D(data[0],data[1],data[2]));
 235.213 +				output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
 235.214 +				output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
 235.215 +			}
 235.216 +		}
 235.217 +	}
 235.218 +
 235.219 +	pScene->mRootNode = new aiNode();
 235.220 +	pScene->mRootNode->mName.Set("<RawRoot>");
 235.221 +
 235.222 +	// count the number of valid groups
 235.223 +	// (meshes can't be empty)
 235.224 +	for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
 235.225 +		it != end;++it)
 235.226 +	{
 235.227 +		if (!(*it).meshes.empty())
 235.228 +		{
 235.229 +			++pScene->mRootNode->mNumChildren; 
 235.230 +			pScene->mNumMeshes += (unsigned int)(*it).meshes.size();
 235.231 +		}
 235.232 +	}
 235.233 +
 235.234 +	if (!pScene->mNumMeshes)
 235.235 +	{
 235.236 +		throw DeadlyImportError("RAW: No meshes loaded. The file seems to be corrupt or empty.");
 235.237 +	}
 235.238 +
 235.239 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
 235.240 +	aiNode** cc;
 235.241 +	if (1 == pScene->mRootNode->mNumChildren)
 235.242 +	{
 235.243 +		cc = &pScene->mRootNode;
 235.244 +		pScene->mRootNode->mNumChildren = 0;
 235.245 +	}
 235.246 +	else cc = pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
 235.247 +
 235.248 +	pScene->mNumMaterials = pScene->mNumMeshes;
 235.249 +	aiMaterial** mats = pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
 235.250 +
 235.251 +	unsigned int meshIdx = 0;
 235.252 +	for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
 235.253 +		it != end;++it)
 235.254 +	{
 235.255 +		if ((*it).meshes.empty())continue;
 235.256 +		
 235.257 +		aiNode* node;
 235.258 +		if (pScene->mRootNode->mNumChildren)
 235.259 +		{
 235.260 +			node = *cc = new aiNode();
 235.261 +			node->mParent = pScene->mRootNode;
 235.262 +		}
 235.263 +		else node = *cc;++cc;
 235.264 +		node->mName.Set((*it).name);
 235.265 +
 235.266 +		// add all meshes
 235.267 +		node->mNumMeshes = (unsigned int)(*it).meshes.size();
 235.268 +		unsigned int* pi = node->mMeshes = new unsigned int[ node->mNumMeshes ];
 235.269 +		for (std::vector< MeshInformation >::iterator it2 = (*it).meshes.begin(),
 235.270 +			end2 = (*it).meshes.end(); it2 != end2; ++it2)
 235.271 +		{
 235.272 +			ai_assert(!(*it2).vertices.empty());
 235.273 +
 235.274 +			// allocate the mesh
 235.275 +			*pi++ = meshIdx;
 235.276 +			aiMesh* mesh = pScene->mMeshes[meshIdx] = new aiMesh();
 235.277 +			mesh->mMaterialIndex = meshIdx++;
 235.278 +
 235.279 +			mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 235.280 +
 235.281 +			// allocate storage for the vertex components and copy them
 235.282 +			mesh->mNumVertices = (unsigned int)(*it2).vertices.size();
 235.283 +			mesh->mVertices = new aiVector3D[ mesh->mNumVertices ];
 235.284 +			::memcpy(mesh->mVertices,&(*it2).vertices[0],sizeof(aiVector3D)*mesh->mNumVertices);
 235.285 +
 235.286 +			if ((*it2).colors.size())
 235.287 +			{
 235.288 +				ai_assert((*it2).colors.size() == mesh->mNumVertices);
 235.289 +
 235.290 +				mesh->mColors[0] = new aiColor4D[ mesh->mNumVertices ];
 235.291 +				::memcpy(mesh->mColors[0],&(*it2).colors[0],sizeof(aiColor4D)*mesh->mNumVertices);
 235.292 +			}
 235.293 +
 235.294 +			// generate triangles
 235.295 +			ai_assert(0 == mesh->mNumVertices % 3);
 235.296 +			aiFace* fc = mesh->mFaces = new aiFace[ mesh->mNumFaces = mesh->mNumVertices/3 ];
 235.297 +			aiFace* const fcEnd = fc + mesh->mNumFaces;
 235.298 +			unsigned int n = 0;
 235.299 +			while (fc != fcEnd)
 235.300 +			{
 235.301 +				aiFace& f = *fc++;
 235.302 +				f.mIndices = new unsigned int[f.mNumIndices = 3];
 235.303 +				for (unsigned int m = 0; m < 3;++m)
 235.304 +					f.mIndices[m] = n++;
 235.305 +			}
 235.306 +
 235.307 +			// generate a material for the mesh
 235.308 +			aiMaterial* mat = new aiMaterial();
 235.309 +
 235.310 +			aiColor4D clr(1.0f,1.0f,1.0f,1.0f);
 235.311 +			if ("%default%" == (*it2).name) // a gray default material
 235.312 +			{
 235.313 +				clr.r = clr.g = clr.b = 0.6f;
 235.314 +			}
 235.315 +			else if ((*it2).name.length() > 0) // a texture
 235.316 +			{
 235.317 +				aiString s;
 235.318 +				s.Set((*it2).name);
 235.319 +				mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
 235.320 +			}
 235.321 +			mat->AddProperty<aiColor4D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
 235.322 +			*mats++ = mat;
 235.323 +		}
 235.324 +	}
 235.325 +}
 235.326 +
 235.327 +#endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER
   236.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   236.2 +++ b/libs/assimp/RawLoader.h	Sat Feb 01 19:58:19 2014 +0200
   236.3 @@ -0,0 +1,119 @@
   236.4 +/*
   236.5 +Open Asset Import Library (assimp)
   236.6 +----------------------------------------------------------------------
   236.7 +
   236.8 +Copyright (c) 2006-2012, assimp team
   236.9 +All rights reserved.
  236.10 +
  236.11 +Redistribution and use of this software in source and binary forms, 
  236.12 +with or without modification, are permitted provided that the 
  236.13 +following conditions are met:
  236.14 +
  236.15 +* Redistributions of source code must retain the above
  236.16 +  copyright notice, this list of conditions and the
  236.17 +  following disclaimer.
  236.18 +
  236.19 +* Redistributions in binary form must reproduce the above
  236.20 +  copyright notice, this list of conditions and the
  236.21 +  following disclaimer in the documentation and/or other
  236.22 +  materials provided with the distribution.
  236.23 +
  236.24 +* Neither the name of the assimp team, nor the names of its
  236.25 +  contributors may be used to endorse or promote products
  236.26 +  derived from this software without specific prior
  236.27 +  written permission of the assimp team.
  236.28 +
  236.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  236.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  236.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  236.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  236.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  236.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  236.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  236.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  236.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  236.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  236.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  236.40 +
  236.41 +----------------------------------------------------------------------
  236.42 +*/
  236.43 +
  236.44 +/** @file  RAWLoader.h
  236.45 + *  @brief Declaration of the RAW importer class.
  236.46 + */
  236.47 +#ifndef AI_RAWLOADER_H_INCLUDED
  236.48 +#define AI_RAWLOADER_H_INCLUDED
  236.49 +
  236.50 +#include "BaseImporter.h"
  236.51 +#include "assimp/types.h"
  236.52 +#include <vector>
  236.53 +
  236.54 +namespace Assimp	{
  236.55 +
  236.56 +// ---------------------------------------------------------------------------
  236.57 +/** Importer class for the PovRay RAW triangle format
  236.58 +*/
  236.59 +class RAWImporter : public BaseImporter
  236.60 +{
  236.61 +public:
  236.62 +	RAWImporter();
  236.63 +	~RAWImporter();
  236.64 +
  236.65 +
  236.66 +public:
  236.67 +
  236.68 +	// -------------------------------------------------------------------
  236.69 +	/** Returns whether the class can handle the format of the given file. 
  236.70 +	 * See BaseImporter::CanRead() for details.
  236.71 + 	 */
  236.72 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, 
  236.73 +		bool checkSig) const;
  236.74 +
  236.75 +protected:
  236.76 +
  236.77 +	// -------------------------------------------------------------------
  236.78 +	/** Return importer meta information.
  236.79 +	 * See #BaseImporter::GetInfo for the details
  236.80 +	 */
  236.81 +	const aiImporterDesc* GetInfo () const;
  236.82 +
  236.83 +	// -------------------------------------------------------------------
  236.84 +	/** Imports the given file into the given scene structure. 
  236.85 +	* See BaseImporter::InternReadFile() for details
  236.86 +	*/
  236.87 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  236.88 +		IOSystem* pIOHandler);
  236.89 +
  236.90 +private:
  236.91 +
  236.92 +	struct MeshInformation
  236.93 +	{
  236.94 +		MeshInformation(const std::string& _name)
  236.95 +			: name(_name)
  236.96 +		{
  236.97 +			vertices.reserve(100);
  236.98 +			colors.reserve(100);
  236.99 +		}
 236.100 +
 236.101 +		std::string name;
 236.102 +		
 236.103 +		std::vector<aiVector3D> vertices;
 236.104 +		std::vector<aiColor4D> colors;
 236.105 +	};
 236.106 +
 236.107 +	struct GroupInformation
 236.108 +	{
 236.109 +		GroupInformation(const std::string& _name)
 236.110 +			: name(_name)
 236.111 +		{
 236.112 +			meshes.reserve(10);
 236.113 +		}
 236.114 +
 236.115 +		std::string name;
 236.116 +		std::vector<MeshInformation> meshes;
 236.117 +	};
 236.118 +};
 236.119 +
 236.120 +} // end of namespace Assimp
 236.121 +
 236.122 +#endif // AI_3DSIMPORTER_H_IN
   237.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   237.2 +++ b/libs/assimp/RemoveComments.cpp	Sat Feb 01 19:58:19 2014 +0200
   237.3 @@ -0,0 +1,108 @@
   237.4 +/*
   237.5 +Open Asset Import Library (assimp)
   237.6 +----------------------------------------------------------------------
   237.7 +
   237.8 +Copyright (c) 2006-2012, assimp team
   237.9 +All rights reserved.
  237.10 +
  237.11 +Redistribution and use of this software in source and binary forms, 
  237.12 +with or without modification, are permitted provided that the 
  237.13 +following conditions are met:
  237.14 +
  237.15 +* Redistributions of source code must retain the above
  237.16 +  copyright notice, this list of conditions and the
  237.17 +  following disclaimer.
  237.18 +
  237.19 +* Redistributions in binary form must reproduce the above
  237.20 +  copyright notice, this list of conditions and the
  237.21 +  following disclaimer in the documentation and/or other
  237.22 +  materials provided with the distribution.
  237.23 +
  237.24 +* Neither the name of the assimp team, nor the names of its
  237.25 +  contributors may be used to endorse or promote products
  237.26 +  derived from this software without specific prior
  237.27 +  written permission of the assimp team.
  237.28 +
  237.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  237.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  237.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  237.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  237.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  237.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  237.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  237.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  237.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  237.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  237.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  237.40 +
  237.41 +----------------------------------------------------------------------
  237.42 +*/
  237.43 +
  237.44 +/** @file  RemoveComments.cpp
  237.45 + *  @brief Defines the CommentRemover utility class
  237.46 + */
  237.47 +
  237.48 +#include "AssimpPCH.h"
  237.49 +#include "RemoveComments.h"
  237.50 +#include "ParsingUtils.h"
  237.51 +
  237.52 +namespace Assimp	{
  237.53 +
  237.54 +// ------------------------------------------------------------------------------------------------
  237.55 +// Remove line comments from a file
  237.56 +void CommentRemover::RemoveLineComments(const char* szComment,
  237.57 +	char* szBuffer, char chReplacement /* = ' ' */)
  237.58 +{
  237.59 +	// validate parameters
  237.60 +	ai_assert(NULL != szComment && NULL != szBuffer && *szComment);
  237.61 +
  237.62 +	const size_t len = strlen(szComment);
  237.63 +	while (*szBuffer)	{
  237.64 +
  237.65 +		// skip over quotes
  237.66 +		if (*szBuffer == '\"' || *szBuffer == '\'')
  237.67 +			while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\'');
  237.68 +
  237.69 +		if (!strncmp(szBuffer,szComment,len)) {
  237.70 +			while (!IsLineEnd(*szBuffer))
  237.71 +				*szBuffer++ = chReplacement;
  237.72 +		}
  237.73 +		++szBuffer;
  237.74 +	}
  237.75 +}
  237.76 +
  237.77 +// ------------------------------------------------------------------------------------------------
  237.78 +// Remove multi-line comments from a file
  237.79 +void CommentRemover::RemoveMultiLineComments(const char* szCommentStart,
  237.80 +	const char* szCommentEnd,char* szBuffer,
  237.81 +	char chReplacement)
  237.82 +{
  237.83 +	// validate parameters
  237.84 +	ai_assert(NULL != szCommentStart && NULL != szCommentEnd &&
  237.85 +		NULL != szBuffer && *szCommentStart && *szCommentEnd);
  237.86 +
  237.87 +	const size_t len  = strlen(szCommentEnd);
  237.88 +	const size_t len2 = strlen(szCommentStart);
  237.89 +
  237.90 +	while (*szBuffer)	{
  237.91 +		// skip over quotes
  237.92 +		if (*szBuffer == '\"' || *szBuffer == '\'')
  237.93 +			while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\'');
  237.94 +
  237.95 +		if (!strncmp(szBuffer,szCommentStart,len2))  {
  237.96 +			while (*szBuffer) {
  237.97 +				if (!::strncmp(szBuffer,szCommentEnd,len)) {
  237.98 +					for (unsigned int i = 0; i < len;++i)
  237.99 +						*szBuffer++ = chReplacement;
 237.100 +
 237.101 +					break;
 237.102 +				}
 237.103 +			*szBuffer++ = chReplacement;
 237.104 +			}
 237.105 +			continue;
 237.106 +		}
 237.107 +		++szBuffer;
 237.108 +	}
 237.109 +}
 237.110 +
 237.111 +} // !! Assimp
   238.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   238.2 +++ b/libs/assimp/RemoveComments.h	Sat Feb 01 19:58:19 2014 +0200
   238.3 @@ -0,0 +1,88 @@
   238.4 +/*
   238.5 +Open Asset Import Library (assimp)
   238.6 +----------------------------------------------------------------------
   238.7 +
   238.8 +Copyright (c) 2006-2012, assimp team
   238.9 +All rights reserved.
  238.10 +
  238.11 +Redistribution and use of this software in source and binary forms, 
  238.12 +with or without modification, are permitted provided that the 
  238.13 +following conditions are met:
  238.14 +
  238.15 +* Redistributions of source code must retain the above
  238.16 +  copyright notice, this list of conditions and the
  238.17 +  following disclaimer.
  238.18 +
  238.19 +* Redistributions in binary form must reproduce the above
  238.20 +  copyright notice, this list of conditions and the
  238.21 +  following disclaimer in the documentation and/or other
  238.22 +  materials provided with the distribution.
  238.23 +
  238.24 +* Neither the name of the assimp team, nor the names of its
  238.25 +  contributors may be used to endorse or promote products
  238.26 +  derived from this software without specific prior
  238.27 +  written permission of the assimp team.
  238.28 +
  238.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  238.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  238.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  238.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  238.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  238.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  238.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  238.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  238.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  238.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  238.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  238.40 +
  238.41 +----------------------------------------------------------------------
  238.42 +*/
  238.43 +
  238.44 +/** @file Declares a helper class, "CommentRemover", which can be
  238.45 + *  used to remove comments (single and multi line) from a text file.
  238.46 + */
  238.47 +#ifndef AI_REMOVE_COMMENTS_H_INC
  238.48 +#define AI_REMOVE_COMMENTS_H_INC
  238.49 +
  238.50 +#include "assimp/ai_assert.h"
  238.51 +
  238.52 +namespace Assimp	{
  238.53 +
  238.54 +// ---------------------------------------------------------------------------
  238.55 +/** \brief Helper class to remove single and multi line comments from a file
  238.56 + * 
  238.57 + *  Some mesh formats like MD5 have comments that are quite similar
  238.58 + *  to those in C or C++ so this code has been moved to a separate
  238.59 + *  module.
  238.60 + */
  238.61 +class CommentRemover
  238.62 +{
  238.63 +	// class cannot be instanced
  238.64 +	CommentRemover() {}
  238.65 +
  238.66 +public:
  238.67 +
  238.68 +	//! Remove single-line comments. The end of a line is
  238.69 +	//! expected to be either NL or CR or NLCR.
  238.70 +	//! \param szComment The start sequence of the comment, e.g. "//"
  238.71 +	//! \param szBuffer Buffer to work with
  238.72 +	//! \param chReplacement Character to be used as replacement
  238.73 +	//! for commented lines. By default this is ' '
  238.74 +	static void RemoveLineComments(const char* szComment,
  238.75 +		char* szBuffer, char chReplacement = ' ');
  238.76 +
  238.77 +	//! Remove multi-line comments. The end of a line is
  238.78 +	//! expected to be either NL or CR or NLCR. Multi-line comments
  238.79 +	//! may not be nested (as in C).
  238.80 +	//! \param szCommentStart The start sequence of the comment, e.g. "/*"
  238.81 +	//! \param szCommentEnd The end sequence of the comment, e.g. "*/"
  238.82 +	//! \param szBuffer Buffer to work with
  238.83 +	//! \param chReplacement Character to be used as replacement
  238.84 +	//! for commented lines. By default this is ' '
  238.85 +	static void RemoveMultiLineComments(const char* szCommentStart,
  238.86 +		const char* szCommentEnd,char* szBuffer,
  238.87 +		char chReplacement = ' ');
  238.88 +};
  238.89 +} // ! Assimp
  238.90 +
  238.91 +#endif // !! AI_REMOVE_COMMENTS_H_INC
   239.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   239.2 +++ b/libs/assimp/RemoveRedundantMaterials.cpp	Sat Feb 01 19:58:19 2014 +0200
   239.3 @@ -0,0 +1,205 @@
   239.4 +/*
   239.5 +---------------------------------------------------------------------------
   239.6 +Open Asset Import Library (assimp)
   239.7 +---------------------------------------------------------------------------
   239.8 +
   239.9 +Copyright (c) 2006-2012, assimp team
  239.10 +
  239.11 +All rights reserved.
  239.12 +
  239.13 +Redistribution and use of this software in source and binary forms, 
  239.14 +with or without modification, are permitted provided that the following 
  239.15 +conditions are met:
  239.16 +
  239.17 +* Redistributions of source code must retain the above
  239.18 +  copyright notice, this list of conditions and the
  239.19 +  following disclaimer.
  239.20 +
  239.21 +* Redistributions in binary form must reproduce the above
  239.22 +  copyright notice, this list of conditions and the
  239.23 +  following disclaimer in the documentation and/or other
  239.24 +  materials provided with the distribution.
  239.25 +
  239.26 +* Neither the name of the assimp team, nor the names of its
  239.27 +  contributors may be used to endorse or promote products
  239.28 +  derived from this software without specific prior
  239.29 +  written permission of the assimp team.
  239.30 +
  239.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  239.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  239.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  239.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  239.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  239.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  239.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  239.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  239.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  239.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  239.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  239.42 +---------------------------------------------------------------------------
  239.43 +*/
  239.44 +/** @file RemoveRedundantMaterials.cpp
  239.45 + *  @brief Implementation of the "RemoveRedundantMaterials" post processing step 
  239.46 +*/
  239.47 +
  239.48 +// internal headers
  239.49 +#include "AssimpPCH.h"
  239.50 +#include "RemoveRedundantMaterials.h"
  239.51 +#include "ParsingUtils.h"
  239.52 +#include "ProcessHelper.h"
  239.53 +#include "MaterialSystem.h"
  239.54 +
  239.55 +using namespace Assimp;
  239.56 +
  239.57 +// ------------------------------------------------------------------------------------------------
  239.58 +// Constructor to be privately used by Importer
  239.59 +RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
  239.60 +{
  239.61 +	// nothing to do here
  239.62 +}
  239.63 +
  239.64 +// ------------------------------------------------------------------------------------------------
  239.65 +// Destructor, private as well
  239.66 +RemoveRedundantMatsProcess::~RemoveRedundantMatsProcess()
  239.67 +{
  239.68 +	// nothing to do here
  239.69 +}
  239.70 +
  239.71 +// ------------------------------------------------------------------------------------------------
  239.72 +// Returns whether the processing step is present in the given flag field.
  239.73 +bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const
  239.74 +{
  239.75 +	return (pFlags & aiProcess_RemoveRedundantMaterials) != 0;
  239.76 +}
  239.77 +
  239.78 +// ------------------------------------------------------------------------------------------------
  239.79 +// Setup import properties
  239.80 +void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp)
  239.81 +{
  239.82 +	// Get value of AI_CONFIG_PP_RRM_EXCLUDE_LIST
  239.83 +	configFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
  239.84 +}
  239.85 +
  239.86 +// ------------------------------------------------------------------------------------------------
  239.87 +// Executes the post processing step on the given imported data.
  239.88 +void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
  239.89 +{
  239.90 +	DefaultLogger::get()->debug("RemoveRedundantMatsProcess begin");
  239.91 +
  239.92 +	unsigned int iCnt = 0, unreferenced = 0;
  239.93 +	if (pScene->mNumMaterials)
  239.94 +	{
  239.95 +		// Find out which materials are referenced by meshes
  239.96 +		std::vector<bool> abReferenced(pScene->mNumMaterials,false);
  239.97 +		for (unsigned int i = 0;i < pScene->mNumMeshes;++i)
  239.98 +			abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true;
  239.99 +
 239.100 +		// If a list of materials to be excluded was given, match the list with 
 239.101 +		// our imported materials and 'salt' all positive matches to ensure that
 239.102 +		// we get unique hashes later.
 239.103 +		if (configFixedMaterials.length()) {
 239.104 +
 239.105 +			std::list<std::string> strings;
 239.106 +			ConvertListToStrings(configFixedMaterials,strings);
 239.107 +			
 239.108 +			for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
 239.109 +				aiMaterial* mat = pScene->mMaterials[i];
 239.110 +
 239.111 +				aiString name;
 239.112 +				mat->Get(AI_MATKEY_NAME,name);
 239.113 +
 239.114 +				if (name.length) {
 239.115 +					std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data);
 239.116 +					if (it != strings.end()) {
 239.117 +						
 239.118 +						// Our brilliant 'salt': A single material property with ~ as first
 239.119 +						// character to mark it as internal and temporary.
 239.120 +						const int dummy = 1;
 239.121 +						((aiMaterial*)mat)->AddProperty(&dummy,1,"~RRM.UniqueMaterial",0,0);
 239.122 +
 239.123 +						// Keep this material even if no mesh references it
 239.124 +						abReferenced[i] = true;
 239.125 +						DefaultLogger::get()->debug(std::string("Found positive match in exclusion list: \'") + name.data + "\'");
 239.126 +					}
 239.127 +				}
 239.128 +			}
 239.129 +		}
 239.130 +
 239.131 +
 239.132 +		// TODO: reimplement this algorithm to work in-place
 239.133 +
 239.134 +		unsigned int* aiMappingTable = new unsigned int[pScene->mNumMaterials];
 239.135 +		unsigned int iNewNum = 0;
 239.136 +
 239.137 +		// Iterate through all materials and calculate a hash for them
 239.138 +		// store all hashes in a list and so a quick search whether
 239.139 +		// we do already have a specific hash. This allows us to
 239.140 +		// determine which materials are identical.
 239.141 +		uint32_t* aiHashes;
 239.142 +		aiHashes = new uint32_t[pScene->mNumMaterials];
 239.143 +		for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
 239.144 +		{
 239.145 +			// if the material is not referenced ... remove it
 239.146 +			if (!abReferenced[i])	{
 239.147 +				++unreferenced;
 239.148 +				continue;
 239.149 +			}
 239.150 +
 239.151 +			uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]);
 239.152 +			for (unsigned int a = 0; a < i;++a)
 239.153 +			{
 239.154 +				if (abReferenced[a] && me == aiHashes[a]) {
 239.155 +					++iCnt;
 239.156 +					me = 0;
 239.157 +					aiMappingTable[i] = aiMappingTable[a];
 239.158 +					delete pScene->mMaterials[i];
 239.159 +					break;
 239.160 +				}
 239.161 +			}
 239.162 +			if (me)	{
 239.163 +				aiMappingTable[i] = iNewNum++;
 239.164 +			}
 239.165 +		}
 239.166 +		if (iCnt)	{
 239.167 +			// build an output material list
 239.168 +			aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
 239.169 +			::memset(ppcMaterials,0,sizeof(void*)*iNewNum); 
 239.170 +			for (unsigned int p = 0; p < pScene->mNumMaterials;++p)
 239.171 +			{
 239.172 +				// if the material is not referenced ... remove it
 239.173 +				if (!abReferenced[p])
 239.174 +					continue;
 239.175 +
 239.176 +				// generate new names for all modified materials
 239.177 +				const unsigned int idx = aiMappingTable[p]; 
 239.178 +				if (ppcMaterials[idx]) 
 239.179 +				{
 239.180 +					aiString sz;
 239.181 +					sz.length = ::sprintf(sz.data,"JoinedMaterial_#%i",p);
 239.182 +					((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
 239.183 +				}
 239.184 +				else ppcMaterials[idx] = pScene->mMaterials[p];
 239.185 +			}
 239.186 +			// update all material indices
 239.187 +			for (unsigned int p = 0; p < pScene->mNumMeshes;++p)	{
 239.188 +				aiMesh* mesh = pScene->mMeshes[p];
 239.189 +				mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex];
 239.190 +			}
 239.191 +			// delete the old material list
 239.192 +			delete[] pScene->mMaterials;
 239.193 +			pScene->mMaterials = ppcMaterials;
 239.194 +			pScene->mNumMaterials = iNewNum;
 239.195 +		}
 239.196 +		// delete temporary storage
 239.197 +		delete[] aiHashes;
 239.198 +		delete[] aiMappingTable;
 239.199 +	}
 239.200 +	if (!iCnt)DefaultLogger::get()->debug("RemoveRedundantMatsProcess finished ");
 239.201 +	else 
 239.202 +	{
 239.203 +		char szBuffer[128]; // should be sufficiently large
 239.204 +		::sprintf(szBuffer,"RemoveRedundantMatsProcess finished. %i redundant and %i unused materials",
 239.205 +			iCnt,unreferenced);
 239.206 +		DefaultLogger::get()->info(szBuffer);
 239.207 +	}
 239.208 +}
   240.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   240.2 +++ b/libs/assimp/RemoveRedundantMaterials.h	Sat Feb 01 19:58:19 2014 +0200
   240.3 @@ -0,0 +1,102 @@
   240.4 +/*
   240.5 +Open Asset Import Library (assimp)
   240.6 +----------------------------------------------------------------------
   240.7 +
   240.8 +Copyright (c) 2006-2012, assimp team
   240.9 +All rights reserved.
  240.10 +
  240.11 +Redistribution and use of this software in source and binary forms, 
  240.12 +with or without modification, are permitted provided that the 
  240.13 +following conditions are met:
  240.14 +
  240.15 +* Redistributions of source code must retain the above
  240.16 +  copyright notice, this list of conditions and the
  240.17 +  following disclaimer.
  240.18 +
  240.19 +* Redistributions in binary form must reproduce the above
  240.20 +  copyright notice, this list of conditions and the
  240.21 +  following disclaimer in the documentation and/or other
  240.22 +  materials provided with the distribution.
  240.23 +
  240.24 +* Neither the name of the assimp team, nor the names of its
  240.25 +  contributors may be used to endorse or promote products
  240.26 +  derived from this software without specific prior
  240.27 +  written permission of the assimp team.
  240.28 +
  240.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  240.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  240.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  240.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  240.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  240.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  240.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  240.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  240.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  240.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  240.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  240.40 +
  240.41 +----------------------------------------------------------------------
  240.42 +*/
  240.43 +
  240.44 +/** @file RemoveRedundantMaterials.h
  240.45 + *  @brief Defines a post processing step to remove redundant materials 
  240.46 + */
  240.47 +#ifndef AI_REMOVEREDUNDANTMATERIALS_H_INC
  240.48 +#define AI_REMOVEREDUNDANTMATERIALS_H_INC
  240.49 +
  240.50 +#include "BaseProcess.h"
  240.51 +#include "assimp/mesh.h"
  240.52 +
  240.53 +class RemoveRedundantMatsTest;
  240.54 +namespace Assimp	{
  240.55 +
  240.56 +// ---------------------------------------------------------------------------
  240.57 +/** RemoveRedundantMatsProcess: Postprocessing steo to remove redundant 
  240.58 + *  materials from the imported scene.
  240.59 + */
  240.60 +class RemoveRedundantMatsProcess : public BaseProcess
  240.61 +{
  240.62 +public:
  240.63 +
  240.64 +	RemoveRedundantMatsProcess();
  240.65 +	~RemoveRedundantMatsProcess();
  240.66 +
  240.67 +public:
  240.68 +	// -------------------------------------------------------------------
  240.69 +	// Check whether step is active
  240.70 +	bool IsActive( unsigned int pFlags) const;
  240.71 +
  240.72 +	// -------------------------------------------------------------------
  240.73 +	// Execute step on a given scene
  240.74 +	void Execute( aiScene* pScene);
  240.75 +
  240.76 +	// -------------------------------------------------------------------
  240.77 +	// Setup import settings
  240.78 +	void SetupProperties(const Importer* pImp);
  240.79 +
  240.80 +
  240.81 +	// -------------------------------------------------------------------
  240.82 +	/** @brief Set list of fixed (unmutable) materials
  240.83 +	 *  @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
  240.84 +	 */
  240.85 +	void SetFixedMaterialsString(const std::string& fixed = "") {
  240.86 +		configFixedMaterials = fixed;
  240.87 +	}
  240.88 +
  240.89 +	// -------------------------------------------------------------------
  240.90 +	/** @brief Get list of fixed (unmutable) materials
  240.91 +	 *  @return See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
  240.92 +	 */
  240.93 +	const std::string& GetFixedMaterialsString() const {
  240.94 +		return configFixedMaterials;
  240.95 +	}
  240.96 +
  240.97 +private:
  240.98 +
  240.99 +	//! Configuration option: list of all fixed materials
 240.100 +	std::string configFixedMaterials;
 240.101 +};
 240.102 +
 240.103 +} // end of namespace Assimp
 240.104 +
 240.105 +#endif // !!AI_REMOVEREDUNDANTMATERIALS_H_INC
   241.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   241.2 +++ b/libs/assimp/RemoveVCProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
   241.3 @@ -0,0 +1,328 @@
   241.4 +/*
   241.5 +---------------------------------------------------------------------------
   241.6 +Open Asset Import Library (assimp)
   241.7 +---------------------------------------------------------------------------
   241.8 +
   241.9 +Copyright (c) 2006-2012, assimp team
  241.10 +
  241.11 +All rights reserved.
  241.12 +
  241.13 +Redistribution and use of this software in source and binary forms, 
  241.14 +with or without modification, are permitted provided that the following 
  241.15 +conditions are met:
  241.16 +
  241.17 +* Redistributions of source code must retain the above
  241.18 +  copyright notice, this list of conditions and the
  241.19 +  following disclaimer.
  241.20 +
  241.21 +* Redistributions in binary form must reproduce the above
  241.22 +  copyright notice, this list of conditions and the
  241.23 +  following disclaimer in the documentation and/or other
  241.24 +  materials provided with the distribution.
  241.25 +
  241.26 +* Neither the name of the assimp team, nor the names of its
  241.27 +  contributors may be used to endorse or promote products
  241.28 +  derived from this software without specific prior
  241.29 +  written permission of the assimp team.
  241.30 +
  241.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  241.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  241.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  241.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  241.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  241.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  241.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  241.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  241.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  241.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  241.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  241.42 +---------------------------------------------------------------------------
  241.43 +*/
  241.44 +/** @file Implementation of the post processing step to remove
  241.45 + *        any parts of the mesh structure from the imported data.
  241.46 +*/
  241.47 +
  241.48 +#include "AssimpPCH.h"
  241.49 +#include "RemoveVCProcess.h"
  241.50 +
  241.51 +using namespace Assimp;
  241.52 +
  241.53 +
  241.54 +// ------------------------------------------------------------------------------------------------
  241.55 +// Constructor to be privately used by Importer
  241.56 +RemoveVCProcess::RemoveVCProcess()
  241.57 +{}
  241.58 +
  241.59 +// ------------------------------------------------------------------------------------------------
  241.60 +// Destructor, private as well
  241.61 +RemoveVCProcess::~RemoveVCProcess()
  241.62 +{}
  241.63 +
  241.64 +// ------------------------------------------------------------------------------------------------
  241.65 +// Returns whether the processing step is present in the given flag field.
  241.66 +bool RemoveVCProcess::IsActive( unsigned int pFlags) const
  241.67 +{
  241.68 +	return (pFlags & aiProcess_RemoveComponent) != 0;
  241.69 +}
  241.70 +
  241.71 +// ------------------------------------------------------------------------------------------------
  241.72 +// Small helper function to delete all elements in a T** aray using delete
  241.73 +template <typename T>
  241.74 +inline void ArrayDelete(T**& in, unsigned int& num)
  241.75 +{
  241.76 +	for (unsigned int i = 0; i < num; ++i)
  241.77 +		delete in[i];
  241.78 +
  241.79 +	delete[] in;
  241.80 +	in = NULL;
  241.81 +	num = 0;
  241.82 +}
  241.83 +
  241.84 +#if 0
  241.85 +// ------------------------------------------------------------------------------------------------
  241.86 +// Updates the node graph - removes all nodes which have the "remove" flag set and the 
  241.87 +// "don't remove" flag not set. Nodes with meshes are never deleted.
  241.88 +bool UpdateNodeGraph(aiNode* node,std::list<aiNode*>& childsOfParent,bool root)
  241.89 +{
  241.90 +	register bool b = false;
  241.91 +
  241.92 +	std::list<aiNode*> mine;
  241.93 +	for (unsigned int i = 0; i < node->mNumChildren;++i)
  241.94 +	{
  241.95 +		if(UpdateNodeGraph(node->mChildren[i],mine,false))
  241.96 +			b = true;
  241.97 +	}
  241.98 +
  241.99 +	// somewhat tricky ... mNumMeshes must be originally 0 and MSB2 may not be set,
 241.100 +	// so we can do a simple comparison against MSB here
 241.101 +	if (!root && AI_RC_UINT_MSB == node->mNumMeshes )
 241.102 +	{
 241.103 +		// this node needs to be removed
 241.104 +		if(node->mNumChildren)
 241.105 +		{
 241.106 +			childsOfParent.insert(childsOfParent.end(),mine.begin(),mine.end());
 241.107 +
 241.108 +			// set all children to NULL to make sure they are not deleted when we delete ourself
 241.109 +			for (unsigned int i = 0; i < node->mNumChildren;++i)
 241.110 +				node->mChildren[i] = NULL;
 241.111 +		}
 241.112 +		b = true;
 241.113 +		delete node;
 241.114 +	}
 241.115 +	else
 241.116 +	{
 241.117 +		AI_RC_UNMASK(node->mNumMeshes);
 241.118 +		childsOfParent.push_back(node);
 241.119 +
 241.120 +		if (b)
 241.121 +		{
 241.122 +			// reallocate the array of our children here
 241.123 +			node->mNumChildren = (unsigned int)mine.size();
 241.124 +			aiNode** const children = new aiNode*[mine.size()];
 241.125 +			aiNode** ptr = children;
 241.126 +
 241.127 +			for (std::list<aiNode*>::iterator it = mine.begin(), end = mine.end();
 241.128 +				 it != end; ++it)
 241.129 +			{
 241.130 +				*ptr++ = *it;
 241.131 +			}
 241.132 +			delete[] node->mChildren;
 241.133 +			node->mChildren = children;
 241.134 +			return false;
 241.135 +		}
 241.136 +	}
 241.137 +	return b;
 241.138 +}
 241.139 +#endif
 241.140 +
 241.141 +// ------------------------------------------------------------------------------------------------
 241.142 +// Executes the post processing step on the given imported data.
 241.143 +void RemoveVCProcess::Execute( aiScene* pScene)
 241.144 +{
 241.145 +	DefaultLogger::get()->debug("RemoveVCProcess begin");
 241.146 +	bool bHas = false; //,bMasked = false;
 241.147 +
 241.148 +	mScene = pScene;
 241.149 +
 241.150 +	// handle animations
 241.151 +	if ( configDeleteFlags & aiComponent_ANIMATIONS)
 241.152 +	{
 241.153 +
 241.154 +		bHas = true;
 241.155 +		ArrayDelete(pScene->mAnimations,pScene->mNumAnimations);
 241.156 +	}
 241.157 +
 241.158 +	// handle textures
 241.159 +	if ( configDeleteFlags & aiComponent_TEXTURES)
 241.160 +	{
 241.161 +		bHas = true;
 241.162 +		ArrayDelete(pScene->mTextures,pScene->mNumTextures);
 241.163 +	}
 241.164 +
 241.165 +	// handle materials
 241.166 +	if ( configDeleteFlags & aiComponent_MATERIALS && pScene->mNumMaterials)
 241.167 +	{
 241.168 +		bHas = true;
 241.169 +		for (unsigned int i = 1;i < pScene->mNumMaterials;++i)
 241.170 +			delete pScene->mMaterials[i];
 241.171 +
 241.172 +		pScene->mNumMaterials = 1;
 241.173 +		aiMaterial* helper = (aiMaterial*) pScene->mMaterials[0];
 241.174 +		ai_assert(NULL != helper);
 241.175 +		helper->Clear();
 241.176 +
 241.177 +		// gray
 241.178 +		aiColor3D clr(0.6f,0.6f,0.6f);
 241.179 +		helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
 241.180 +
 241.181 +		// add a small ambient color value
 241.182 +		clr = aiColor3D(0.05f,0.05f,0.05f);
 241.183 +		helper->AddProperty(&clr,1,AI_MATKEY_COLOR_AMBIENT);
 241.184 +
 241.185 +		aiString s;
 241.186 +		s.Set("Dummy_MaterialsRemoved");
 241.187 +		helper->AddProperty(&s,AI_MATKEY_NAME);
 241.188 +	}
 241.189 +
 241.190 +	// handle light sources
 241.191 +	if ( configDeleteFlags & aiComponent_LIGHTS)
 241.192 +	{
 241.193 +		bHas =  true;
 241.194 +		ArrayDelete(pScene->mLights,pScene->mNumLights);
 241.195 +	}
 241.196 +
 241.197 +	// handle camneras
 241.198 +	if ( configDeleteFlags & aiComponent_CAMERAS)
 241.199 +	{
 241.200 +		bHas = true;
 241.201 +		ArrayDelete(pScene->mCameras,pScene->mNumCameras);
 241.202 +	}
 241.203 +
 241.204 +	// handle meshes
 241.205 +	if (configDeleteFlags & aiComponent_MESHES)
 241.206 +	{
 241.207 +		bHas = true;
 241.208 +		ArrayDelete(pScene->mMeshes,pScene->mNumMeshes);
 241.209 +	}
 241.210 +	else
 241.211 +	{
 241.212 +		for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
 241.213 +		{
 241.214 +			if(	ProcessMesh( pScene->mMeshes[a]))
 241.215 +				bHas = true;
 241.216 +		}
 241.217 +	}
 241.218 +
 241.219 +
 241.220 +	// now check whether the result is still a full scene
 241.221 +	if (!pScene->mNumMeshes || !pScene->mNumMaterials)
 241.222 +	{
 241.223 +		pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
 241.224 +		DefaultLogger::get()->debug("Setting AI_SCENE_FLAGS_INCOMPLETE flag");
 241.225 +
 241.226 +		// If we have no meshes anymore we should also clear another flag ...
 241.227 +		if (!pScene->mNumMeshes)
 241.228 +			pScene->mFlags &= ~AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
 241.229 +	}
 241.230 +
 241.231 +	if (bHas)DefaultLogger::get()->info("RemoveVCProcess finished. Data structure cleanup has been done.");
 241.232 +	else DefaultLogger::get()->debug("RemoveVCProcess finished. Nothing to be done ...");
 241.233 +}
 241.234 +
 241.235 +// ------------------------------------------------------------------------------------------------
 241.236 +// Setup configuration properties for the step
 241.237 +void RemoveVCProcess::SetupProperties(const Importer* pImp)
 241.238 +{
 241.239 +	configDeleteFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS,0x0);
 241.240 +	if (!configDeleteFlags)
 241.241 +	{
 241.242 +		DefaultLogger::get()->warn("RemoveVCProcess: AI_CONFIG_PP_RVC_FLAGS is zero.");
 241.243 +	}
 241.244 +}
 241.245 +
 241.246 +// ------------------------------------------------------------------------------------------------
 241.247 +// Executes the post processing step on the given imported data.
 241.248 +bool RemoveVCProcess::ProcessMesh(aiMesh* pMesh)
 241.249 +{
 241.250 +	bool ret = false;
 241.251 +
 241.252 +	// if all materials have been deleted let the material
 241.253 +	// index of the mesh point to the created default material
 241.254 +	if ( configDeleteFlags & aiComponent_MATERIALS)
 241.255 +		pMesh->mMaterialIndex = 0;
 241.256 +
 241.257 +	// handle normals
 241.258 +	if (configDeleteFlags & aiComponent_NORMALS && pMesh->mNormals)
 241.259 +	{
 241.260 +		delete[] pMesh->mNormals;
 241.261 +		pMesh->mNormals = NULL;
 241.262 +		ret = true;
 241.263 +	}
 241.264 +
 241.265 +	// handle tangents and bitangents
 241.266 +	if (configDeleteFlags & aiComponent_TANGENTS_AND_BITANGENTS && pMesh->mTangents)
 241.267 +	{
 241.268 +		delete[] pMesh->mTangents;
 241.269 +		pMesh->mTangents = NULL;
 241.270 +
 241.271 +		delete[] pMesh->mBitangents;
 241.272 +		pMesh->mBitangents = NULL;
 241.273 +		ret = true;
 241.274 +	}
 241.275 +
 241.276 +	// handle texture coordinates
 241.277 +	register bool b = (0 != (configDeleteFlags & aiComponent_TEXCOORDS));
 241.278 +	for (unsigned int i = 0, real = 0; real < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++real)
 241.279 +	{
 241.280 +		if (!pMesh->mTextureCoords[i])break;
 241.281 +		if (configDeleteFlags & aiComponent_TEXCOORDSn(real) || b)
 241.282 +		{
 241.283 +			delete pMesh->mTextureCoords[i];
 241.284 +			pMesh->mTextureCoords[i] = NULL;
 241.285 +			ret = true;
 241.286 +
 241.287 +			if (!b)
 241.288 +			{
 241.289 +				// collapse the rest of the array
 241.290 +				for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a)
 241.291 +					pMesh->mTextureCoords[a-1] = pMesh->mTextureCoords[a];
 241.292 +				
 241.293 +				pMesh->mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS-1] = NULL;
 241.294 +				continue;
 241.295 +			}
 241.296 +		}
 241.297 +		++i;
 241.298 +	}
 241.299 +
 241.300 +	// handle vertex colors
 241.301 +	b = (0 != (configDeleteFlags & aiComponent_COLORS));
 241.302 +	for (unsigned int i = 0, real = 0; real < AI_MAX_NUMBER_OF_COLOR_SETS; ++real)
 241.303 +	{
 241.304 +		if (!pMesh->mColors[i])break;
 241.305 +		if (configDeleteFlags & aiComponent_COLORSn(i) || b)
 241.306 +		{
 241.307 +			delete pMesh->mColors[i];
 241.308 +			pMesh->mColors[i] = NULL;
 241.309 +			ret = true;
 241.310 +
 241.311 +			if (!b)
 241.312 +			{
 241.313 +				// collapse the rest of the array
 241.314 +				for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a)
 241.315 +					pMesh->mColors[a-1] = pMesh->mColors[a];
 241.316 +
 241.317 +				pMesh->mColors[AI_MAX_NUMBER_OF_COLOR_SETS-1] = NULL;
 241.318 +				continue;
 241.319 +			}
 241.320 +		}
 241.321 +		++i;
 241.322 +	}
 241.323 +
 241.324 +	// handle bones
 241.325 +	if (configDeleteFlags & aiComponent_BONEWEIGHTS && pMesh->mBones)
 241.326 +	{
 241.327 +		ArrayDelete(pMesh->mBones,pMesh->mNumBones);
 241.328 +		ret = true;
 241.329 +	}
 241.330 +	return ret;
 241.331 +}
   242.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   242.2 +++ b/libs/assimp/RemoveVCProcess.h	Sat Feb 01 19:58:19 2014 +0200
   242.3 @@ -0,0 +1,118 @@
   242.4 +/*
   242.5 +Open Asset Import Library (assimp)
   242.6 +----------------------------------------------------------------------
   242.7 +
   242.8 +Copyright (c) 2006-2012, assimp team
   242.9 +All rights reserved.
  242.10 +
  242.11 +Redistribution and use of this software in source and binary forms, 
  242.12 +with or without modification, are permitted provided that the 
  242.13 +following conditions are met:
  242.14 +
  242.15 +* Redistributions of source code must retain the above
  242.16 +  copyright notice, this list of conditions and the
  242.17 +  following disclaimer.
  242.18 +
  242.19 +* Redistributions in binary form must reproduce the above
  242.20 +  copyright notice, this list of conditions and the
  242.21 +  following disclaimer in the documentation and/or other
  242.22 +  materials provided with the distribution.
  242.23 +
  242.24 +* Neither the name of the assimp team, nor the names of its
  242.25 +  contributors may be used to endorse or promote products
  242.26 +  derived from this software without specific prior
  242.27 +  written permission of the assimp team.
  242.28 +
  242.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  242.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  242.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  242.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  242.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  242.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  242.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  242.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  242.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  242.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  242.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  242.40 +
  242.41 +----------------------------------------------------------------------
  242.42 +*/
  242.43 +
  242.44 +/** @file Defines a post processing step to remove specific parts of the scene */
  242.45 +#ifndef AI_REMOVEVCPROCESS_H_INCLUDED
  242.46 +#define AI_REMOVEVCPROCESS_H_INCLUDED
  242.47 +
  242.48 +#include "BaseProcess.h"
  242.49 +#include "assimp/mesh.h"
  242.50 +
  242.51 +class RemoveVCProcessTest;
  242.52 +namespace Assimp	{
  242.53 +
  242.54 +// ---------------------------------------------------------------------------
  242.55 +/** RemoveVCProcess: Class to exclude specific parts of the data structure
  242.56 + *  from further processing by removing them,
  242.57 +*/
  242.58 +class RemoveVCProcess : public BaseProcess
  242.59 +{
  242.60 +public:
  242.61 +
  242.62 +	RemoveVCProcess();
  242.63 +	~RemoveVCProcess();
  242.64 +
  242.65 +public:
  242.66 +	// -------------------------------------------------------------------
  242.67 +	/** Returns whether the processing step is present in the given flag field.
  242.68 +	* @param pFlags The processing flags the importer was called with. A bitwise
  242.69 +	*   combination of #aiPostProcessSteps.
  242.70 +	* @return true if the process is present in this flag fields, false if not.
  242.71 +	*/
  242.72 +	bool IsActive( unsigned int pFlags) const;
  242.73 +
  242.74 +	// -------------------------------------------------------------------
  242.75 +	/** Executes the post processing step on the given imported data.
  242.76 +	* At the moment a process is not supposed to fail.
  242.77 +	* @param pScene The imported data to work at.
  242.78 +	*/
  242.79 +	void Execute( aiScene* pScene);
  242.80 +
  242.81 +	// -------------------------------------------------------------------
  242.82 +	/** Called prior to ExecuteOnScene().
  242.83 +	* The function is a request to the process to update its configuration
  242.84 +	* basing on the Importer's configuration property list.
  242.85 +	*/
  242.86 +	virtual void SetupProperties(const Importer* pImp);
  242.87 +
  242.88 +	// -------------------------------------------------------------------
  242.89 +	/** Manually setup the configuration flags for the step
  242.90 +	 *
  242.91 +	 *  @param Bitwise combintion of the #aiComponent enumerated values.
  242.92 +	*/
  242.93 +	void SetDeleteFlags(unsigned int f)	
  242.94 +	{
  242.95 +		configDeleteFlags = f;
  242.96 +	}
  242.97 +
  242.98 +	// -------------------------------------------------------------------
  242.99 +	/** Query the current configuration.
 242.100 +	*/
 242.101 +	unsigned int GetDeleteFlags() const
 242.102 +	{
 242.103 +		return configDeleteFlags;
 242.104 +	}
 242.105 +
 242.106 +private:
 242.107 +
 242.108 +	bool ProcessMesh (aiMesh* pcMesh);
 242.109 +
 242.110 +	/** Configuration flag
 242.111 +	 */
 242.112 +	unsigned int configDeleteFlags;
 242.113 +
 242.114 +	/** The scene we're working with
 242.115 +	 */
 242.116 +	aiScene* mScene;
 242.117 +};
 242.118 +
 242.119 +} // end of namespace Assimp
 242.120 +
 242.121 +#endif // !!AI_REMOVEVCPROCESS_H_INCLUDED
   243.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   243.2 +++ b/libs/assimp/SGSpatialSort.cpp	Sat Feb 01 19:58:19 2014 +0200
   243.3 @@ -0,0 +1,169 @@
   243.4 +/*
   243.5 +---------------------------------------------------------------------------
   243.6 +Open Asset Import Library (assimp)
   243.7 +---------------------------------------------------------------------------
   243.8 +
   243.9 +Copyright (c) 2006-2012, assimp team
  243.10 +
  243.11 +All rights reserved.
  243.12 +
  243.13 +Redistribution and use of this software in source and binary forms, 
  243.14 +with or without modification, are permitted provided that the following 
  243.15 +conditions are met:
  243.16 +
  243.17 +* Redistributions of source code must retain the above
  243.18 +copyright notice, this list of conditions and the
  243.19 +following disclaimer.
  243.20 +
  243.21 +* Redistributions in binary form must reproduce the above
  243.22 +copyright notice, this list of conditions and the
  243.23 +following disclaimer in the documentation and/or other
  243.24 +materials provided with the distribution.
  243.25 +
  243.26 +* Neither the name of the assimp team, nor the names of its
  243.27 +contributors may be used to endorse or promote products
  243.28 +derived from this software without specific prior
  243.29 +written permission of the assimp team.
  243.30 +
  243.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  243.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  243.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  243.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  243.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  243.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  243.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  243.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  243.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  243.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  243.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  243.42 +---------------------------------------------------------------------------
  243.43 +*/
  243.44 +
  243.45 +/** @file Implementation of the helper class to quickly find 
  243.46 +vertices close to a given position. Special implementation for 
  243.47 +the 3ds loader handling smooth groups correctly  */
  243.48 +
  243.49 +#include "AssimpPCH.h"
  243.50 +#include "SGSpatialSort.h"
  243.51 +
  243.52 +using namespace Assimp;
  243.53 +
  243.54 +
  243.55 +// ------------------------------------------------------------------------------------------------
  243.56 +SGSpatialSort::SGSpatialSort()
  243.57 +{
  243.58 +	// define the reference plane. We choose some arbitrary vector away from all basic axises 
  243.59 +	// in the hope that no model spreads all its vertices along this plane.
  243.60 +	mPlaneNormal.Set( 0.8523f, 0.34321f, 0.5736f);
  243.61 +	mPlaneNormal.Normalize();
  243.62 +}
  243.63 +// ------------------------------------------------------------------------------------------------
  243.64 +// Destructor
  243.65 +SGSpatialSort::~SGSpatialSort()
  243.66 +{
  243.67 +	// nothing to do here, everything destructs automatically
  243.68 +}
  243.69 +// ------------------------------------------------------------------------------------------------
  243.70 +void SGSpatialSort::Add(const aiVector3D& vPosition, unsigned int index,
  243.71 +	unsigned int smoothingGroup)
  243.72 +{
  243.73 +	// store position by index and distance
  243.74 +	float distance = vPosition * mPlaneNormal;
  243.75 +	mPositions.push_back( Entry( index, vPosition, 
  243.76 +		distance, smoothingGroup));
  243.77 +}
  243.78 +// ------------------------------------------------------------------------------------------------
  243.79 +void SGSpatialSort::Prepare()
  243.80 +{
  243.81 +	// now sort the array ascending by distance.
  243.82 +	std::sort( this->mPositions.begin(), this->mPositions.end());
  243.83 +}
  243.84 +// ------------------------------------------------------------------------------------------------
  243.85 +// Returns an iterator for all positions close to the given position.
  243.86 +void SGSpatialSort::FindPositions( const aiVector3D& pPosition, 
  243.87 +	uint32_t pSG,
  243.88 +	float pRadius,
  243.89 +	std::vector<unsigned int>& poResults,
  243.90 +	bool exactMatch /*= false*/) const
  243.91 +{
  243.92 +	float dist = pPosition * mPlaneNormal;
  243.93 +	float minDist = dist - pRadius, maxDist = dist + pRadius;
  243.94 +
  243.95 +	// clear the array in this strange fashion because a simple clear() would also deallocate
  243.96 +	// the array which we want to avoid
  243.97 +	poResults.erase( poResults.begin(), poResults.end());
  243.98 +
  243.99 +	// quick check for positions outside the range
 243.100 +	if( mPositions.size() == 0)
 243.101 +		return;
 243.102 +	if( maxDist < mPositions.front().mDistance)
 243.103 +		return;
 243.104 +	if( minDist > mPositions.back().mDistance)
 243.105 +		return;
 243.106 +
 243.107 +	// do a binary search for the minimal distance to start the iteration there
 243.108 +	unsigned int index = (unsigned int)mPositions.size() / 2;
 243.109 +	unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
 243.110 +	while( binaryStepSize > 1)
 243.111 +	{
 243.112 +		if( mPositions[index].mDistance < minDist)
 243.113 +			index += binaryStepSize;
 243.114 +		else
 243.115 +			index -= binaryStepSize;
 243.116 +
 243.117 +		binaryStepSize /= 2;
 243.118 +	}
 243.119 +
 243.120 +	// depending on the direction of the last step we need to single step a bit back or forth
 243.121 +	// to find the actual beginning element of the range
 243.122 +	while( index > 0 && mPositions[index].mDistance > minDist)
 243.123 +		index--;
 243.124 +	while( index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist)
 243.125 +		index++;
 243.126 +
 243.127 +	// Mow start iterating from there until the first position lays outside of the distance range.
 243.128 +	// Add all positions inside the distance range within the given radius to the result aray
 243.129 +
 243.130 +	float squareEpsilon = pRadius * pRadius;
 243.131 +	std::vector<Entry>::const_iterator it  = mPositions.begin() + index;
 243.132 +	std::vector<Entry>::const_iterator end = mPositions.end();
 243.133 +
 243.134 +	if (exactMatch)
 243.135 +	{
 243.136 +		while( it->mDistance < maxDist)
 243.137 +		{
 243.138 +			if((it->mPosition - pPosition).SquareLength() < squareEpsilon && it->mSmoothGroups == pSG)
 243.139 +			{
 243.140 +				poResults.push_back( it->mIndex);
 243.141 +			}
 243.142 +			++it;
 243.143 +			if( end == it )break;
 243.144 +		}
 243.145 +	}
 243.146 +	else
 243.147 +	{
 243.148 +		// if the given smoothing group is 0, we'll return all surrounding vertices
 243.149 +		if (!pSG)
 243.150 +		{
 243.151 +			while( it->mDistance < maxDist)
 243.152 +			{
 243.153 +				if((it->mPosition - pPosition).SquareLength() < squareEpsilon)
 243.154 +					poResults.push_back( it->mIndex);
 243.155 +				++it;
 243.156 +				if( end == it)break;
 243.157 +			}
 243.158 +		}
 243.159 +		else while( it->mDistance < maxDist)
 243.160 +		{
 243.161 +			if((it->mPosition - pPosition).SquareLength() < squareEpsilon &&
 243.162 +				(it->mSmoothGroups & pSG || !it->mSmoothGroups))
 243.163 +			{
 243.164 +				poResults.push_back( it->mIndex);
 243.165 +			}
 243.166 +			++it;
 243.167 +			if( end == it)break;
 243.168 +		}
 243.169 +	}
 243.170 +}
 243.171 +
 243.172 +
   244.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   244.2 +++ b/libs/assimp/SGSpatialSort.h	Sat Feb 01 19:58:19 2014 +0200
   244.3 @@ -0,0 +1,139 @@
   244.4 +/*
   244.5 +Open Asset Import Library (assimp)
   244.6 +----------------------------------------------------------------------
   244.7 +
   244.8 +Copyright (c) 2006-2012, assimp team
   244.9 +All rights reserved.
  244.10 +
  244.11 +Redistribution and use of this software in source and binary forms, 
  244.12 +with or without modification, are permitted provided that the 
  244.13 +following conditions are met:
  244.14 +
  244.15 +* Redistributions of source code must retain the above
  244.16 +  copyright notice, this list of conditions and the
  244.17 +  following disclaimer.
  244.18 +
  244.19 +* Redistributions in binary form must reproduce the above
  244.20 +  copyright notice, this list of conditions and the
  244.21 +  following disclaimer in the documentation and/or other
  244.22 +  materials provided with the distribution.
  244.23 +
  244.24 +* Neither the name of the assimp team, nor the names of its
  244.25 +  contributors may be used to endorse or promote products
  244.26 +  derived from this software without specific prior
  244.27 +  written permission of the assimp team.
  244.28 +
  244.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  244.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  244.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  244.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  244.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  244.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  244.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  244.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  244.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  244.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  244.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  244.40 +
  244.41 +----------------------------------------------------------------------
  244.42 +*/
  244.43 +
  244.44 +/** Small helper classes to optimise finding vertizes close to a given location
  244.45 + */
  244.46 +#ifndef AI_D3DSSPATIALSORT_H_INC
  244.47 +#define AI_D3DSSPATIALSORT_H_INC
  244.48 +
  244.49 +#include <vector>
  244.50 +#include "assimp/types.h"
  244.51 +
  244.52 +namespace Assimp	{
  244.53 +
  244.54 +// ----------------------------------------------------------------------------------
  244.55 +/** Specialized version of SpatialSort to support smoothing groups
  244.56 + *  This is used in by the 3DS, ASE and LWO loaders. 3DS and ASE share their 
  244.57 + *  normal computation code in SmoothingGroups.inl, the LWO loader has its own
  244.58 + *  implementation to handle all details of its file format correctly.
  244.59 + */
  244.60 +// ----------------------------------------------------------------------------------
  244.61 +class SGSpatialSort
  244.62 +{
  244.63 +public:
  244.64 +
  244.65 +	SGSpatialSort();
  244.66 +
  244.67 +	// -------------------------------------------------------------------
  244.68 +	/** Construction from a given face array, handling smoothing groups
  244.69 +	 *  properly
  244.70 +	 */
  244.71 +	SGSpatialSort(const std::vector<aiVector3D>& vPositions);
  244.72 +
  244.73 +	// -------------------------------------------------------------------
  244.74 +	/** Add a vertex to the spatial sort
  244.75 +	 * @param vPosition Vertex position to be added
  244.76 +	 * @param index Index of the vrtex
  244.77 +	 * @param smoothingGroup SmoothingGroup for this vertex
  244.78 +	 */
  244.79 +	void Add(const aiVector3D& vPosition, unsigned int index,
  244.80 +		unsigned int smoothingGroup);
  244.81 +
  244.82 +	// -------------------------------------------------------------------
  244.83 +	/** Prepare the spatial sorter for use. This step runs in O(logn)
  244.84 +	 */
  244.85 +	void Prepare();
  244.86 +
  244.87 +	/** Destructor */
  244.88 +	~SGSpatialSort();
  244.89 +
  244.90 +	// -------------------------------------------------------------------
  244.91 +	/** Returns an iterator for all positions close to the given position.
  244.92 +	 * @param pPosition The position to look for vertices.
  244.93 +	 * @param pSG Only included vertices with at least one shared smooth group
  244.94 +	 * @param pRadius Maximal distance from the position a vertex may have
  244.95 +	 *   to be counted in.
  244.96 +	 * @param poResults The container to store the indices of the found
  244.97 +	 *   positions. Will be emptied by the call so it may contain anything.
  244.98 +	 * @param exactMatch Specifies whether smoothing groups are bit masks 
  244.99 +	 *   (false) or integral values (true). In the latter case, a vertex
 244.100 +	 *   cannot belong to more than one smoothing group.
 244.101 +	 * @return An iterator to iterate over all vertices in the given area.
 244.102 +	 */
 244.103 +	// -------------------------------------------------------------------
 244.104 +	void FindPositions( const aiVector3D& pPosition, uint32_t pSG,
 244.105 +		float pRadius, std::vector<unsigned int>& poResults, 
 244.106 +		bool exactMatch = false) const;
 244.107 +
 244.108 +protected:
 244.109 +	/** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */
 244.110 +	aiVector3D mPlaneNormal;
 244.111 +
 244.112 +	// -------------------------------------------------------------------
 244.113 +	/** An entry in a spatially sorted position array. Consists of a 
 244.114 +	 *  vertex index, its position and its precalculated distance from
 244.115 +	 *  the reference plane */
 244.116 +	// -------------------------------------------------------------------
 244.117 +	struct Entry
 244.118 +	{
 244.119 +		unsigned int mIndex;	///< The vertex referred by this entry
 244.120 +		aiVector3D mPosition;	///< Position
 244.121 +		uint32_t mSmoothGroups;
 244.122 +		float mDistance;		///< Distance of this vertex to the sorting plane
 244.123 +
 244.124 +		Entry() { /** intentionally not initialized.*/ }
 244.125 +		Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance,uint32_t pSG) 
 244.126 +			: 
 244.127 +			mIndex( pIndex),
 244.128 +			mPosition( pPosition),
 244.129 +			mSmoothGroups (pSG),
 244.130 +			mDistance( pDistance)
 244.131 +			{ 	}
 244.132 +
 244.133 +		bool operator < (const Entry& e) const { return mDistance < e.mDistance; }
 244.134 +	};
 244.135 +
 244.136 +	// all positions, sorted by distance to the sorting plane
 244.137 +	std::vector<Entry> mPositions;
 244.138 +};
 244.139 +
 244.140 +} // end of namespace Assimp
 244.141 +
 244.142 +#endif // AI_SPATIALSORT_H_INC
   245.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   245.2 +++ b/libs/assimp/SMDLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   245.3 @@ -0,0 +1,1141 @@
   245.4 +/*
   245.5 +---------------------------------------------------------------------------
   245.6 +Open Asset Import Library (assimp)
   245.7 +---------------------------------------------------------------------------
   245.8 +
   245.9 +Copyright (c) 2006-2012, assimp team
  245.10 +
  245.11 +All rights reserved.
  245.12 +
  245.13 +Redistribution and use of this software in source and binary forms, 
  245.14 +with or without modification, are permitted provided that the following 
  245.15 +conditions are met:
  245.16 +
  245.17 +* Redistributions of source code must retain the above
  245.18 +  copyright notice, this list of conditions and the
  245.19 +  following disclaimer.
  245.20 +
  245.21 +* Redistributions in binary form must reproduce the above
  245.22 +  copyright notice, this list of conditions and the
  245.23 +  following disclaimer in the documentation and/or other
  245.24 +  materials provided with the distribution.
  245.25 +
  245.26 +* Neither the name of the assimp team, nor the names of its
  245.27 +  contributors may be used to endorse or promote products
  245.28 +  derived from this software without specific prior
  245.29 +  written permission of the assimp team.
  245.30 +
  245.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  245.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  245.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  245.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  245.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  245.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  245.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  245.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  245.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  245.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  245.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  245.42 +---------------------------------------------------------------------------
  245.43 +*/
  245.44 +
  245.45 +/** @file  SMDLoader.cpp 
  245.46 + *  @brief Implementation of the SMD importer class 
  245.47 + */
  245.48 +
  245.49 +#include "AssimpPCH.h"
  245.50 +#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER
  245.51 +
  245.52 +// internal headers
  245.53 +#include "SMDLoader.h"
  245.54 +#include "fast_atof.h"
  245.55 +#include "SkeletonMeshBuilder.h"
  245.56 +
  245.57 +using namespace Assimp;
  245.58 +
  245.59 +static const aiImporterDesc desc = {
  245.60 +	"Valve SMD Importer",
  245.61 +	"",
  245.62 +	"",
  245.63 +	"",
  245.64 +	aiImporterFlags_SupportTextFlavour,
  245.65 +	0,
  245.66 +	0,
  245.67 +	0,
  245.68 +	0,
  245.69 +	"smd vta" 
  245.70 +};
  245.71 +
  245.72 +// ------------------------------------------------------------------------------------------------
  245.73 +// Constructor to be privately used by Importer
  245.74 +SMDImporter::SMDImporter()
  245.75 +{}
  245.76 +
  245.77 +// ------------------------------------------------------------------------------------------------
  245.78 +// Destructor, private as well 
  245.79 +SMDImporter::~SMDImporter()
  245.80 +{}
  245.81 +
  245.82 +// ------------------------------------------------------------------------------------------------
  245.83 +// Returns whether the class can handle the format of the given file. 
  245.84 +bool SMDImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool) const
  245.85 +{
  245.86 +	// fixme: auto format detection
  245.87 +	return SimpleExtensionCheck(pFile,"smd","vta");
  245.88 +}
  245.89 +
  245.90 +// ------------------------------------------------------------------------------------------------
  245.91 +// Get a list of all supported file extensions
  245.92 +const aiImporterDesc* SMDImporter::GetInfo () const
  245.93 +{
  245.94 +	return &desc;
  245.95 +}
  245.96 +
  245.97 +// ------------------------------------------------------------------------------------------------
  245.98 +// Setup configuration properties
  245.99 +void SMDImporter::SetupProperties(const Importer* pImp)
 245.100 +{
 245.101 +	// The 
 245.102 +	// AI_CONFIG_IMPORT_SMD_KEYFRAME option overrides the
 245.103 +	// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
 245.104 +	configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_SMD_KEYFRAME,-1);
 245.105 +	if(static_cast<unsigned int>(-1) == configFrameID)	{
 245.106 +		configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
 245.107 +	}
 245.108 +}
 245.109 +
 245.110 +// ------------------------------------------------------------------------------------------------
 245.111 +// Imports the given file into the given scene structure. 
 245.112 +void SMDImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
 245.113 +{
 245.114 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 245.115 +
 245.116 +	// Check whether we can read from the file
 245.117 +	if( file.get() == NULL)	{
 245.118 +		throw DeadlyImportError( "Failed to open SMD/VTA file " + pFile + ".");
 245.119 +	}
 245.120 +
 245.121 +	iFileSize = (unsigned int)file->FileSize();
 245.122 +
 245.123 +	// Allocate storage and copy the contents of the file to a memory buffer
 245.124 +	this->pScene = pScene;
 245.125 +
 245.126 +	std::vector<char> buff(iFileSize+1);
 245.127 +	TextFileToBuffer(file.get(),buff);
 245.128 +	mBuffer = &buff[0];
 245.129 +
 245.130 +	iSmallestFrame = (1 << 31);
 245.131 +	bHasUVs = true;
 245.132 +	iLineNumber = 1;
 245.133 +
 245.134 +	// Reserve enough space for ... hm ... 10 textures
 245.135 +	aszTextures.reserve(10);
 245.136 +
 245.137 +	// Reserve enough space for ... hm ... 1000 triangles
 245.138 +	asTriangles.reserve(1000);
 245.139 +
 245.140 +	// Reserve enough space for ... hm ... 20 bones
 245.141 +	asBones.reserve(20);
 245.142 +
 245.143 +
 245.144 +	// parse the file ...
 245.145 +	ParseFile();
 245.146 +
 245.147 +	// If there are no triangles it seems to be an animation SMD,
 245.148 +	// containing only the animation skeleton.
 245.149 +	if (asTriangles.empty())
 245.150 +	{
 245.151 +		if (asBones.empty())
 245.152 +		{
 245.153 +			throw DeadlyImportError("SMD: No triangles and no bones have "
 245.154 +				"been found in the file. This file seems to be invalid.");
 245.155 +		}
 245.156 +
 245.157 +		// Set the flag in the scene structure which indicates
 245.158 +		// that there is nothing than an animation skeleton
 245.159 +		pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
 245.160 +	}
 245.161 +
 245.162 +	if (!asBones.empty())
 245.163 +	{
 245.164 +		// Check whether all bones have been initialized
 245.165 +		for (std::vector<SMD::Bone>::const_iterator
 245.166 +			i =  asBones.begin();
 245.167 +			i != asBones.end();++i)
 245.168 +		{
 245.169 +			if (!(*i).mName.length())
 245.170 +			{
 245.171 +				DefaultLogger::get()->warn("SMD: Not all bones have been initialized");
 245.172 +				break;
 245.173 +			}
 245.174 +		}
 245.175 +
 245.176 +		// now fix invalid time values and make sure the animation starts at frame 0
 245.177 +		FixTimeValues();
 245.178 +
 245.179 +		// compute absolute bone transformation matrices
 245.180 +	//	ComputeAbsoluteBoneTransformations();
 245.181 +	}
 245.182 +
 245.183 +	if (!(pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))
 245.184 +	{
 245.185 +		// create output meshes
 245.186 +		CreateOutputMeshes();
 245.187 +
 245.188 +		// build an output material list
 245.189 +		CreateOutputMaterials();
 245.190 +	}
 245.191 +
 245.192 +	// build the output animation
 245.193 +	CreateOutputAnimations();
 245.194 +
 245.195 +	// build output nodes (bones are added as empty dummy nodes)
 245.196 +	CreateOutputNodes();
 245.197 +
 245.198 +	if (pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)
 245.199 +	{
 245.200 +		SkeletonMeshBuilder skeleton(pScene);
 245.201 +	}
 245.202 +}
 245.203 +// ------------------------------------------------------------------------------------------------
 245.204 +// Write an error message with line number to the log file
 245.205 +void SMDImporter::LogErrorNoThrow(const char* msg)
 245.206 +{
 245.207 +	char szTemp[1024];
 245.208 +	sprintf(szTemp,"Line %i: %s",iLineNumber,msg);
 245.209 +	DefaultLogger::get()->error(szTemp);
 245.210 +}
 245.211 +
 245.212 +// ------------------------------------------------------------------------------------------------
 245.213 +// Write a warning with line number to the log file
 245.214 +void SMDImporter::LogWarning(const char* msg)
 245.215 +{
 245.216 +	char szTemp[1024];
 245.217 +	ai_assert(strlen(msg) < 1000);
 245.218 +	sprintf(szTemp,"Line %i: %s",iLineNumber,msg);
 245.219 +	DefaultLogger::get()->warn(szTemp);
 245.220 +}
 245.221 +
 245.222 +// ------------------------------------------------------------------------------------------------
 245.223 +// Fix invalid time values in the file
 245.224 +void SMDImporter::FixTimeValues()
 245.225 +{
 245.226 +	double dDelta = (double)iSmallestFrame;
 245.227 +	double dMax = 0.0f;
 245.228 +	for (std::vector<SMD::Bone>::iterator
 245.229 +		iBone =  asBones.begin();
 245.230 +		iBone != asBones.end();++iBone)
 245.231 +	{
 245.232 +		for (std::vector<SMD::Bone::Animation::MatrixKey>::iterator
 245.233 +			iKey =  (*iBone).sAnim.asKeys.begin();
 245.234 +			iKey != (*iBone).sAnim.asKeys.end();++iKey)
 245.235 +		{
 245.236 +			(*iKey).dTime -= dDelta;
 245.237 +			dMax = std::max(dMax, (*iKey).dTime);
 245.238 +		}
 245.239 +	}
 245.240 +	dLengthOfAnim = dMax;
 245.241 +}
 245.242 +
 245.243 +// ------------------------------------------------------------------------------------------------
 245.244 +// create output meshes
 245.245 +void SMDImporter::CreateOutputMeshes()
 245.246 +{
 245.247 +	if (aszTextures.empty())
 245.248 +		aszTextures.push_back(std::string());
 245.249 +
 245.250 +	// we need to sort all faces by their material index
 245.251 +	// in opposition to other loaders we can be sure that each
 245.252 +	// material is at least used once.
 245.253 +	pScene->mNumMeshes = (unsigned int) aszTextures.size();
 245.254 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
 245.255 +
 245.256 +	typedef std::vector<unsigned int> FaceList;
 245.257 +	FaceList* aaiFaces = new FaceList[pScene->mNumMeshes];
 245.258 +
 245.259 +	// approximate the space that will be required
 245.260 +	unsigned int iNum = (unsigned int)asTriangles.size() / pScene->mNumMeshes;
 245.261 +	iNum += iNum >> 1;
 245.262 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
 245.263 +		aaiFaces[i].reserve(iNum);
 245.264 +
 245.265 +
 245.266 +	// collect all faces
 245.267 +	iNum = 0;
 245.268 +	for (std::vector<SMD::Face>::const_iterator
 245.269 +		iFace =  asTriangles.begin();
 245.270 +		iFace != asTriangles.end();++iFace,++iNum)
 245.271 +	{
 245.272 +		if (UINT_MAX == (*iFace).iTexture)aaiFaces[(*iFace).iTexture].push_back( 0 );
 245.273 +		else if ((*iFace).iTexture >= aszTextures.size())
 245.274 +		{
 245.275 +			DefaultLogger::get()->error("[SMD/VTA] Material index overflow in face");
 245.276 +			aaiFaces[(*iFace).iTexture].push_back((unsigned int)aszTextures.size()-1);
 245.277 +		}
 245.278 +		else aaiFaces[(*iFace).iTexture].push_back(iNum);
 245.279 +	} 
 245.280 +
 245.281 +	// now create the output meshes
 245.282 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
 245.283 +	{
 245.284 +		aiMesh*& pcMesh = pScene->mMeshes[i] = new aiMesh();
 245.285 +		ai_assert(!aaiFaces[i].empty()); // should not be empty ...
 245.286 +
 245.287 +		pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 245.288 +		pcMesh->mNumVertices = (unsigned int)aaiFaces[i].size()*3;
 245.289 +		pcMesh->mNumFaces = (unsigned int)aaiFaces[i].size();
 245.290 +		pcMesh->mMaterialIndex = i;
 245.291 +
 245.292 +		// storage for bones
 245.293 +		typedef std::pair<unsigned int,float> TempWeightListEntry;
 245.294 +		typedef std::vector< TempWeightListEntry > TempBoneWeightList;
 245.295 +
 245.296 +		TempBoneWeightList* aaiBones = new TempBoneWeightList[asBones.size()]();
 245.297 +
 245.298 +		// try to reserve enough memory without wasting too much
 245.299 +		for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
 245.300 +		{
 245.301 +			aaiBones[iBone].reserve(pcMesh->mNumVertices/asBones.size());
 245.302 +		}
 245.303 +
 245.304 +		// allocate storage
 245.305 +		pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
 245.306 +		aiVector3D* pcNormals = pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
 245.307 +		aiVector3D* pcVerts = pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
 245.308 +
 245.309 +		aiVector3D* pcUVs = NULL;
 245.310 +		if (bHasUVs)
 245.311 +		{
 245.312 +			pcUVs = pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
 245.313 +			pcMesh->mNumUVComponents[0] = 2;
 245.314 +		}
 245.315 +
 245.316 +		iNum = 0;
 245.317 +		for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace)
 245.318 +		{
 245.319 +			pcMesh->mFaces[iFace].mIndices = new unsigned int[3];
 245.320 +			pcMesh->mFaces[iFace].mNumIndices = 3;
 245.321 +
 245.322 +			// fill the vertices 
 245.323 +			unsigned int iSrcFace = aaiFaces[i][iFace];
 245.324 +			SMD::Face& face = asTriangles[iSrcFace];
 245.325 +
 245.326 +			*pcVerts++ = face.avVertices[0].pos;
 245.327 +			*pcVerts++ = face.avVertices[1].pos;
 245.328 +			*pcVerts++ = face.avVertices[2].pos; 
 245.329 +
 245.330 +			// fill the normals
 245.331 +			*pcNormals++ = face.avVertices[0].nor;
 245.332 +			*pcNormals++ = face.avVertices[1].nor;
 245.333 +			*pcNormals++ = face.avVertices[2].nor;
 245.334 +
 245.335 +			// fill the texture coordinates
 245.336 +			if (pcUVs)
 245.337 +			{
 245.338 +				*pcUVs++ = face.avVertices[0].uv;
 245.339 +				*pcUVs++ = face.avVertices[1].uv;
 245.340 +				*pcUVs++ = face.avVertices[2].uv;
 245.341 +			}
 245.342 +			
 245.343 +			for (unsigned int iVert = 0; iVert < 3;++iVert)
 245.344 +			{
 245.345 +				float fSum = 0.0f;
 245.346 +				for (unsigned int iBone = 0;iBone < face.avVertices[iVert].aiBoneLinks.size();++iBone)
 245.347 +				{
 245.348 +					TempWeightListEntry& pairval = face.avVertices[iVert].aiBoneLinks[iBone];
 245.349 +
 245.350 +					// FIX: The second check is here just to make sure we won't 
 245.351 +					// assign more than one weight to a single vertex index
 245.352 +					if (pairval.first >= asBones.size() || 
 245.353 +						pairval.first == face.avVertices[iVert].iParentNode)
 245.354 +					{
 245.355 +						DefaultLogger::get()->error("[SMD/VTA] Bone index overflow. "
 245.356 +							"The bone index will be ignored, the weight will be assigned "
 245.357 +							"to the vertex' parent node");
 245.358 +						continue;
 245.359 +					}
 245.360 +					aaiBones[pairval.first].push_back(TempWeightListEntry(iNum,pairval.second));
 245.361 +					fSum += pairval.second;
 245.362 +				}
 245.363 +				// ******************************************************************
 245.364 +				// If the sum of all vertex weights is not 1.0 we must assign 
 245.365 +				// the rest to the vertex' parent node. Well, at least the doc says 
 245.366 +				// we should ...
 245.367 +				// FIX: We use 0.975 as limit, floating-point inaccuracies seem to
 245.368 +				// be very strong in some SMD exporters. Furthermore it is possible
 245.369 +				// that the parent of a vertex is 0xffffffff (if the corresponding
 245.370 +				// entry in the file was unreadable)
 245.371 +				// ******************************************************************
 245.372 +				if (fSum < 0.975f && face.avVertices[iVert].iParentNode != UINT_MAX)
 245.373 +				{
 245.374 +					if (face.avVertices[iVert].iParentNode >= asBones.size())
 245.375 +					{
 245.376 +						DefaultLogger::get()->error("[SMD/VTA] Bone index overflow. "
 245.377 +							"The index of the vertex parent bone is invalid. "
 245.378 +							"The remaining weights will be normalized to 1.0");
 245.379 +
 245.380 +						if (fSum)
 245.381 +						{
 245.382 +							fSum = 1 / fSum;
 245.383 +							for (unsigned int iBone = 0;iBone < face.avVertices[iVert].aiBoneLinks.size();++iBone)
 245.384 +							{
 245.385 +								TempWeightListEntry& pairval = face.avVertices[iVert].aiBoneLinks[iBone];
 245.386 +								if (pairval.first >= asBones.size())continue;
 245.387 +								aaiBones[pairval.first].back().second *= fSum;
 245.388 +							}
 245.389 +						}
 245.390 +					}
 245.391 +					else
 245.392 +					{
 245.393 +						aaiBones[face.avVertices[iVert].iParentNode].push_back(
 245.394 +							TempWeightListEntry(iNum,1.0f-fSum));
 245.395 +					}
 245.396 +				}
 245.397 +				pcMesh->mFaces[iFace].mIndices[iVert] = iNum++;
 245.398 +			}
 245.399 +		}
 245.400 +
 245.401 +		// now build all bones of the mesh
 245.402 +		iNum = 0;
 245.403 +		for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
 245.404 +			if (!aaiBones[iBone].empty())++iNum;
 245.405 +		
 245.406 +		if (false && iNum)
 245.407 +		{
 245.408 +			pcMesh->mNumBones = iNum;
 245.409 +			pcMesh->mBones = new aiBone*[pcMesh->mNumBones];
 245.410 +			iNum = 0;
 245.411 +			for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
 245.412 +			{
 245.413 +				if (aaiBones[iBone].empty())continue;
 245.414 +				aiBone*& bone = pcMesh->mBones[iNum] = new aiBone();
 245.415 +
 245.416 +				bone->mNumWeights = (unsigned int)aaiBones[iBone].size();
 245.417 +				bone->mWeights = new aiVertexWeight[bone->mNumWeights];
 245.418 +				bone->mOffsetMatrix = asBones[iBone].mOffsetMatrix;
 245.419 +				bone->mName.Set( asBones[iBone].mName );
 245.420 +
 245.421 +				asBones[iBone].bIsUsed = true;
 245.422 +
 245.423 +				for (unsigned int iWeight = 0; iWeight < bone->mNumWeights;++iWeight)
 245.424 +				{
 245.425 +					bone->mWeights[iWeight].mVertexId = aaiBones[iBone][iWeight].first;
 245.426 +					bone->mWeights[iWeight].mWeight = aaiBones[iBone][iWeight].second;
 245.427 +				}
 245.428 +				++iNum;
 245.429 +			}
 245.430 +		}
 245.431 +		delete[] aaiBones;
 245.432 +	}
 245.433 +	delete[] aaiFaces;
 245.434 +}
 245.435 +
 245.436 +// ------------------------------------------------------------------------------------------------
 245.437 +// add bone child nodes
 245.438 +void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent)
 245.439 +{
 245.440 +	ai_assert(NULL != pcNode && 0 == pcNode->mNumChildren && NULL == pcNode->mChildren);
 245.441 +
 245.442 +	// first count ...
 245.443 +	for (unsigned int i = 0; i < asBones.size();++i)
 245.444 +	{
 245.445 +		SMD::Bone& bone = asBones[i];
 245.446 +		if (bone.iParent == iParent)++pcNode->mNumChildren;
 245.447 +	}
 245.448 +
 245.449 +	// now allocate the output array
 245.450 +	pcNode->mChildren = new aiNode*[pcNode->mNumChildren];
 245.451 +
 245.452 +	// and fill all subnodes
 245.453 +	unsigned int qq = 0;
 245.454 +	for (unsigned int i = 0; i < asBones.size();++i)
 245.455 +	{
 245.456 +		SMD::Bone& bone = asBones[i];
 245.457 +		if (bone.iParent != iParent)continue;
 245.458 +
 245.459 +		aiNode* pc = pcNode->mChildren[qq++] = new aiNode();
 245.460 +		pc->mName.Set(bone.mName);
 245.461 +
 245.462 +		// store the local transformation matrix of the bind pose
 245.463 +		pc->mTransformation = bone.sAnim.asKeys[bone.sAnim.iFirstTimeKey].matrix;
 245.464 +		pc->mParent = pcNode;
 245.465 +
 245.466 +		// add children to this node, too
 245.467 +		AddBoneChildren(pc,i);
 245.468 +	}
 245.469 +}
 245.470 +
 245.471 +// ------------------------------------------------------------------------------------------------
 245.472 +// create output nodes
 245.473 +void SMDImporter::CreateOutputNodes()
 245.474 +{
 245.475 +	pScene->mRootNode = new aiNode();
 245.476 +	if (!(pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))
 245.477 +	{
 245.478 +		// create one root node that renders all meshes
 245.479 +		pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
 245.480 +		pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
 245.481 +		for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
 245.482 +			pScene->mRootNode->mMeshes[i] = i;
 245.483 +	}
 245.484 +
 245.485 +	// now add all bones as dummy sub nodes to the graph
 245.486 +	// AddBoneChildren(pScene->mRootNode,(uint32_t)-1);
 245.487 +
 245.488 +	// if we have only one bone we can even remove the root node
 245.489 +	if (pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE && 
 245.490 +		1 == pScene->mRootNode->mNumChildren)
 245.491 +	{
 245.492 +		aiNode* pcOldRoot = pScene->mRootNode;
 245.493 +		pScene->mRootNode = pcOldRoot->mChildren[0];
 245.494 +		pcOldRoot->mChildren[0] = NULL;
 245.495 +		delete pcOldRoot;
 245.496 +
 245.497 +		pScene->mRootNode->mParent = NULL;
 245.498 +	}
 245.499 +	else
 245.500 +	{
 245.501 +		::strcpy(pScene->mRootNode->mName.data, "<SMD_root>");
 245.502 +		pScene->mRootNode->mName.length = 10;
 245.503 +	}
 245.504 +}
 245.505 +
 245.506 +// ------------------------------------------------------------------------------------------------
 245.507 +// create output animations
 245.508 +void SMDImporter::CreateOutputAnimations()
 245.509 +{
 245.510 +	unsigned int iNumBones = 0;
 245.511 +	for (std::vector<SMD::Bone>::const_iterator
 245.512 +		i =  asBones.begin();
 245.513 +		i != asBones.end();++i)
 245.514 +	{
 245.515 +		if ((*i).bIsUsed)++iNumBones;
 245.516 +	}
 245.517 +	if (!iNumBones)
 245.518 +	{
 245.519 +		// just make sure this case doesn't occur ... (it could occur
 245.520 +		// if the file was invalid)
 245.521 +		return;
 245.522 +	}
 245.523 +
 245.524 +	pScene->mNumAnimations = 1;
 245.525 +	pScene->mAnimations = new aiAnimation*[1];
 245.526 +	aiAnimation*& anim = pScene->mAnimations[0] = new aiAnimation();
 245.527 +
 245.528 +	anim->mDuration = dLengthOfAnim;
 245.529 +	anim->mNumChannels = iNumBones;
 245.530 +	anim->mTicksPerSecond = 25.0; // FIXME: is this correct?
 245.531 +
 245.532 +	aiNodeAnim** pp = anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
 245.533 +	
 245.534 +	// now build valid keys
 245.535 +	unsigned int a = 0;
 245.536 +	for (std::vector<SMD::Bone>::const_iterator
 245.537 +		i =  asBones.begin();
 245.538 +		i != asBones.end();++i)
 245.539 +	{
 245.540 +		if (!(*i).bIsUsed)continue;
 245.541 +
 245.542 +		aiNodeAnim* p = pp[a] = new aiNodeAnim();
 245.543 +
 245.544 +		// copy the name of the bone
 245.545 +		p->mNodeName.Set( i->mName);
 245.546 +
 245.547 +		p->mNumRotationKeys = (unsigned int) (*i).sAnim.asKeys.size();
 245.548 +		if (p->mNumRotationKeys)
 245.549 +		{
 245.550 +			p->mNumPositionKeys = p->mNumRotationKeys;
 245.551 +			aiVectorKey* pVecKeys = p->mPositionKeys = new aiVectorKey[p->mNumRotationKeys];
 245.552 +			aiQuatKey* pRotKeys = p->mRotationKeys = new aiQuatKey[p->mNumRotationKeys];
 245.553 +
 245.554 +			for (std::vector<SMD::Bone::Animation::MatrixKey>::const_iterator
 245.555 +				qq =  (*i).sAnim.asKeys.begin();
 245.556 +				qq != (*i).sAnim.asKeys.end(); ++qq)
 245.557 +			{
 245.558 +				pRotKeys->mTime = pVecKeys->mTime = (*qq).dTime;
 245.559 +
 245.560 +				// compute the rotation quaternion from the euler angles
 245.561 +				pRotKeys->mValue = aiQuaternion( (*qq).vRot.x, (*qq).vRot.y, (*qq).vRot.z );
 245.562 +				pVecKeys->mValue = (*qq).vPos;
 245.563 +
 245.564 +				++pVecKeys; ++pRotKeys;
 245.565 +			}
 245.566 +		}
 245.567 +		++a;
 245.568 +
 245.569 +		// there are no scaling keys ...
 245.570 +	}
 245.571 +}
 245.572 +
 245.573 +// ------------------------------------------------------------------------------------------------
 245.574 +void SMDImporter::ComputeAbsoluteBoneTransformations()
 245.575 +{
 245.576 +	// For each bone: determine the key with the lowest time value
 245.577 +	// theoretically the SMD format should have all keyframes
 245.578 +	// in order. However, I've seen a file where this wasn't true.
 245.579 +	for (unsigned int i = 0; i < asBones.size();++i)
 245.580 +	{
 245.581 +		SMD::Bone& bone = asBones[i];
 245.582 +
 245.583 +		uint32_t iIndex = 0;
 245.584 +		double dMin = 10e10;
 245.585 +		for (unsigned int i = 0; i < bone.sAnim.asKeys.size();++i)
 245.586 +		{
 245.587 +			double d = std::min(bone.sAnim.asKeys[i].dTime,dMin);
 245.588 +			if (d < dMin)	
 245.589 +			{
 245.590 +				dMin = d;
 245.591 +				iIndex = i;
 245.592 +			}
 245.593 +		}
 245.594 +		bone.sAnim.iFirstTimeKey = iIndex;
 245.595 +	}
 245.596 +
 245.597 +	unsigned int iParent = 0;
 245.598 +	while (iParent < asBones.size())
 245.599 +	{
 245.600 +		for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
 245.601 +		{
 245.602 +			SMD::Bone& bone = asBones[iBone];
 245.603 +	
 245.604 +			if (iParent == bone.iParent)
 245.605 +			{
 245.606 +				SMD::Bone& parentBone = asBones[iParent];
 245.607 +
 245.608 +			
 245.609 +				uint32_t iIndex = bone.sAnim.iFirstTimeKey;
 245.610 +				const aiMatrix4x4& mat = bone.sAnim.asKeys[iIndex].matrix;
 245.611 +				aiMatrix4x4& matOut = bone.sAnim.asKeys[iIndex].matrixAbsolute;
 245.612 +
 245.613 +				// The same for the parent bone ...
 245.614 +				iIndex = parentBone.sAnim.iFirstTimeKey;
 245.615 +				const aiMatrix4x4& mat2 = parentBone.sAnim.asKeys[iIndex].matrixAbsolute;
 245.616 +
 245.617 +				// Compute the absolute transformation matrix
 245.618 +				matOut = mat * mat2;
 245.619 +			}
 245.620 +		}
 245.621 +		++iParent;
 245.622 +	}
 245.623 +
 245.624 +	// Store the inverse of the absolute transformation matrix 
 245.625 +	// of the first key as bone offset matrix
 245.626 +	for (iParent = 0; iParent < asBones.size();++iParent)
 245.627 +	{
 245.628 +		SMD::Bone& bone = asBones[iParent];
 245.629 +		bone.mOffsetMatrix = bone.sAnim.asKeys[bone.sAnim.iFirstTimeKey].matrixAbsolute;
 245.630 +		bone.mOffsetMatrix.Inverse();
 245.631 +	}
 245.632 +}
 245.633 +
 245.634 +// ------------------------------------------------------------------------------------------------
 245.635 +// create output materials
 245.636 +void SMDImporter::CreateOutputMaterials()
 245.637 +{
 245.638 +	pScene->mNumMaterials = (unsigned int)aszTextures.size();
 245.639 +	pScene->mMaterials = new aiMaterial*[std::max(1u, pScene->mNumMaterials)];
 245.640 +
 245.641 +	for (unsigned int iMat = 0; iMat < pScene->mNumMaterials;++iMat)
 245.642 +	{
 245.643 +		aiMaterial* pcMat = new aiMaterial();
 245.644 +		pScene->mMaterials[iMat] = pcMat;
 245.645 +
 245.646 +		aiString szName;
 245.647 +		szName.length = (size_t)::sprintf(szName.data,"Texture_%i",iMat);
 245.648 +		pcMat->AddProperty(&szName,AI_MATKEY_NAME);
 245.649 +
 245.650 +		if (aszTextures[iMat].length())
 245.651 +		{
 245.652 +			::strcpy(szName.data, aszTextures[iMat].c_str() );
 245.653 +			szName.length = aszTextures[iMat].length();
 245.654 +			pcMat->AddProperty(&szName,AI_MATKEY_TEXTURE_DIFFUSE(0));
 245.655 +		}
 245.656 +	}
 245.657 +
 245.658 +	// create a default material if necessary
 245.659 +	if (0 == pScene->mNumMaterials)
 245.660 +	{
 245.661 +		pScene->mNumMaterials = 1;
 245.662 +
 245.663 +		aiMaterial* pcHelper = new aiMaterial();
 245.664 +		pScene->mMaterials[0] = pcHelper;
 245.665 +
 245.666 +		int iMode = (int)aiShadingMode_Gouraud;
 245.667 +		pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
 245.668 +
 245.669 +		aiColor3D clr;
 245.670 +		clr.b = clr.g = clr.r = 0.7f;
 245.671 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
 245.672 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
 245.673 +
 245.674 +		clr.b = clr.g = clr.r = 0.05f;
 245.675 +		pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
 245.676 +
 245.677 +		aiString szName;
 245.678 +		szName.Set(AI_DEFAULT_MATERIAL_NAME);
 245.679 +		pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
 245.680 +	}
 245.681 +}
 245.682 +
 245.683 +// ------------------------------------------------------------------------------------------------
 245.684 +// Parse the file
 245.685 +void SMDImporter::ParseFile()
 245.686 +{
 245.687 +	const char* szCurrent = mBuffer;
 245.688 +
 245.689 +	// read line per line ...
 245.690 +	for ( ;; )
 245.691 +	{
 245.692 +		if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
 245.693 +
 245.694 +		// "version <n> \n", <n> should be 1 for hl and hl² SMD files
 245.695 +		if (TokenMatch(szCurrent,"version",7))
 245.696 +		{
 245.697 +			if(!SkipSpaces(szCurrent,&szCurrent)) break;
 245.698 +			if (1 != strtoul10(szCurrent,&szCurrent))
 245.699 +			{
 245.700 +				DefaultLogger::get()->warn("SMD.version is not 1. This "
 245.701 +					"file format is not known. Continuing happily ...");
 245.702 +			}
 245.703 +			continue;
 245.704 +		}
 245.705 +		// "nodes\n" - Starts the node section
 245.706 +		if (TokenMatch(szCurrent,"nodes",5))
 245.707 +		{
 245.708 +			ParseNodesSection(szCurrent,&szCurrent);
 245.709 +			continue;
 245.710 +		}
 245.711 +		// "triangles\n" - Starts the triangle section
 245.712 +		if (TokenMatch(szCurrent,"triangles",9))
 245.713 +		{
 245.714 +			ParseTrianglesSection(szCurrent,&szCurrent);
 245.715 +			continue;
 245.716 +		}
 245.717 +		// "vertexanimation\n" - Starts the vertex animation section
 245.718 +		if (TokenMatch(szCurrent,"vertexanimation",15))
 245.719 +		{
 245.720 +			bHasUVs = false;
 245.721 +			ParseVASection(szCurrent,&szCurrent);
 245.722 +			continue;
 245.723 +		}
 245.724 +		// "skeleton\n" - Starts the skeleton section
 245.725 +		if (TokenMatch(szCurrent,"skeleton",8))
 245.726 +		{
 245.727 +			ParseSkeletonSection(szCurrent,&szCurrent);
 245.728 +			continue;
 245.729 +		}
 245.730 +		SkipLine(szCurrent,&szCurrent);
 245.731 +	}
 245.732 +	return;
 245.733 +}
 245.734 +
 245.735 +// ------------------------------------------------------------------------------------------------
 245.736 +unsigned int SMDImporter::GetTextureIndex(const std::string& filename)
 245.737 +{
 245.738 +	unsigned int iIndex = 0;
 245.739 +	for (std::vector<std::string>::const_iterator
 245.740 +		i =  aszTextures.begin();
 245.741 +		i != aszTextures.end();++i,++iIndex)
 245.742 +	{
 245.743 +		// case-insensitive ... it's a path
 245.744 +		if (0 == ASSIMP_stricmp ( filename.c_str(),(*i).c_str()))return iIndex;
 245.745 +	}
 245.746 +	iIndex = (unsigned int)aszTextures.size();
 245.747 +	aszTextures.push_back(filename);
 245.748 +	return iIndex;
 245.749 +}
 245.750 +
 245.751 +// ------------------------------------------------------------------------------------------------
 245.752 +// Parse the nodes section of the file
 245.753 +void SMDImporter::ParseNodesSection(const char* szCurrent,
 245.754 +	const char** szCurrentOut)
 245.755 +{
 245.756 +	for ( ;; )
 245.757 +	{
 245.758 +		// "end\n" - Ends the nodes section
 245.759 +		if (0 == ASSIMP_strincmp(szCurrent,"end",3) &&
 245.760 +			IsSpaceOrNewLine(*(szCurrent+3)))
 245.761 +		{
 245.762 +			szCurrent += 4;
 245.763 +			break;
 245.764 +		}
 245.765 +		ParseNodeInfo(szCurrent,&szCurrent);
 245.766 +	}
 245.767 +	SkipSpacesAndLineEnd(szCurrent,&szCurrent);
 245.768 +	*szCurrentOut = szCurrent;
 245.769 +}
 245.770 +
 245.771 +// ------------------------------------------------------------------------------------------------
 245.772 +// Parse the triangles section of the file
 245.773 +void SMDImporter::ParseTrianglesSection(const char* szCurrent,
 245.774 +	const char** szCurrentOut)
 245.775 +{
 245.776 +	// Parse a triangle, parse another triangle, parse the next triangle ...
 245.777 +	// and so on until we reach a token that looks quite similar to "end"
 245.778 +	for ( ;; )
 245.779 +	{
 245.780 +		if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
 245.781 +
 245.782 +		// "end\n" - Ends the triangles section
 245.783 +		if (TokenMatch(szCurrent,"end",3))
 245.784 +			break;
 245.785 +		ParseTriangle(szCurrent,&szCurrent);
 245.786 +	}
 245.787 +	SkipSpacesAndLineEnd(szCurrent,&szCurrent);
 245.788 +	*szCurrentOut = szCurrent;
 245.789 +}
 245.790 +// ------------------------------------------------------------------------------------------------
 245.791 +// Parse the vertex animation section of the file
 245.792 +void SMDImporter::ParseVASection(const char* szCurrent,
 245.793 +	const char** szCurrentOut)
 245.794 +{
 245.795 +	unsigned int iCurIndex = 0;
 245.796 +	for ( ;; )
 245.797 +	{
 245.798 +		if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
 245.799 +
 245.800 +		// "end\n" - Ends the "vertexanimation" section
 245.801 +		if (TokenMatch(szCurrent,"end",3))
 245.802 +			break;
 245.803 +	
 245.804 +		// "time <n>\n" 
 245.805 +		if (TokenMatch(szCurrent,"time",4))
 245.806 +		{
 245.807 +			// NOTE: The doc says that time values COULD be negative ...
 245.808 +			// NOTE2: this is the shape key -> valve docs
 245.809 +			int iTime = 0;
 245.810 +			if(!ParseSignedInt(szCurrent,&szCurrent,iTime) || configFrameID != (unsigned int)iTime)break;
 245.811 +			SkipLine(szCurrent,&szCurrent);
 245.812 +		}
 245.813 +		else 
 245.814 +		{
 245.815 +			if(0 == iCurIndex)
 245.816 +			{
 245.817 +				asTriangles.push_back(SMD::Face());
 245.818 +			}
 245.819 +			if (++iCurIndex == 3)iCurIndex = 0;
 245.820 +			ParseVertex(szCurrent,&szCurrent,asTriangles.back().avVertices[iCurIndex],true);
 245.821 +		}
 245.822 +	}
 245.823 +
 245.824 +	if (iCurIndex != 2 && !asTriangles.empty())
 245.825 +	{
 245.826 +		// we want to no degenerates, so throw this triangle away
 245.827 +		asTriangles.pop_back();
 245.828 +	}
 245.829 +
 245.830 +	SkipSpacesAndLineEnd(szCurrent,&szCurrent);
 245.831 +	*szCurrentOut = szCurrent;
 245.832 +}
 245.833 +// ------------------------------------------------------------------------------------------------
 245.834 +// Parse the skeleton section of the file
 245.835 +void SMDImporter::ParseSkeletonSection(const char* szCurrent,
 245.836 +	const char** szCurrentOut)
 245.837 +{
 245.838 +	int iTime = 0;
 245.839 +	for ( ;; )
 245.840 +	{
 245.841 +		if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
 245.842 +
 245.843 +		// "end\n" - Ends the skeleton section
 245.844 +		if (TokenMatch(szCurrent,"end",3))
 245.845 +			break;
 245.846 +	
 245.847 +		// "time <n>\n" - Specifies the current animation frame
 245.848 +		else if (TokenMatch(szCurrent,"time",4))
 245.849 +		{
 245.850 +			// NOTE: The doc says that time values COULD be negative ...
 245.851 +			if(!ParseSignedInt(szCurrent,&szCurrent,iTime))break;
 245.852 +
 245.853 +			iSmallestFrame = std::min(iSmallestFrame,iTime);
 245.854 +			SkipLine(szCurrent,&szCurrent);
 245.855 +		}
 245.856 +		else ParseSkeletonElement(szCurrent,&szCurrent,iTime);
 245.857 +	}
 245.858 +	*szCurrentOut = szCurrent;	
 245.859 +}
 245.860 +
 245.861 +// ------------------------------------------------------------------------------------------------
 245.862 +#define SMDI_PARSE_RETURN { \
 245.863 +	SkipLine(szCurrent,&szCurrent); \
 245.864 +	*szCurrentOut = szCurrent; \
 245.865 +	return; \
 245.866 +}
 245.867 +// ------------------------------------------------------------------------------------------------
 245.868 +// Parse a node line
 245.869 +void SMDImporter::ParseNodeInfo(const char* szCurrent,
 245.870 +	const char** szCurrentOut)
 245.871 +{
 245.872 +	unsigned int iBone  = 0;
 245.873 +	SkipSpacesAndLineEnd(szCurrent,&szCurrent);
 245.874 +	if(!ParseUnsignedInt(szCurrent,&szCurrent,iBone) || !SkipSpaces(szCurrent,&szCurrent))
 245.875 +	{
 245.876 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing bone index");
 245.877 +		SMDI_PARSE_RETURN;
 245.878 +	}
 245.879 +	// add our bone to the list
 245.880 +	if (iBone >= asBones.size())asBones.resize(iBone+1);
 245.881 +	SMD::Bone& bone = asBones[iBone];
 245.882 +
 245.883 +	bool bQuota = true;
 245.884 +	if ('\"' != *szCurrent)
 245.885 +	{
 245.886 +		LogWarning("Bone name is expcted to be enclosed in "
 245.887 +			"double quotation marks. ");
 245.888 +		bQuota = false;
 245.889 +	}
 245.890 +	else ++szCurrent;
 245.891 +
 245.892 +	const char* szEnd = szCurrent;
 245.893 +	for ( ;; )
 245.894 +	{
 245.895 +		if (bQuota && '\"' == *szEnd)
 245.896 +		{
 245.897 +			iBone = (unsigned int)(szEnd - szCurrent);
 245.898 +			++szEnd;
 245.899 +			break;
 245.900 +		}
 245.901 +		else if (IsSpaceOrNewLine(*szEnd))
 245.902 +		{
 245.903 +			iBone = (unsigned int)(szEnd - szCurrent);
 245.904 +			break;
 245.905 +		}
 245.906 +		else if (!(*szEnd))
 245.907 +		{
 245.908 +			LogErrorNoThrow("Unexpected EOF/EOL while parsing bone name");
 245.909 +			SMDI_PARSE_RETURN;
 245.910 +		}
 245.911 +		++szEnd;
 245.912 +	}
 245.913 +	bone.mName = std::string(szCurrent,iBone);
 245.914 +	szCurrent = szEnd;
 245.915 +
 245.916 +	// the only negative bone parent index that could occur is -1 AFAIK
 245.917 +	if(!ParseSignedInt(szCurrent,&szCurrent,(int&)bone.iParent))
 245.918 +	{
 245.919 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing bone parent index. Assuming -1");
 245.920 +		SMDI_PARSE_RETURN;
 245.921 +	}
 245.922 +
 245.923 +	// go to the beginning of the next line
 245.924 +	SMDI_PARSE_RETURN;
 245.925 +}
 245.926 +
 245.927 +// ------------------------------------------------------------------------------------------------
 245.928 +// Parse a skeleton element
 245.929 +void SMDImporter::ParseSkeletonElement(const char* szCurrent,
 245.930 +	const char** szCurrentOut,int iTime)
 245.931 +{
 245.932 +	aiVector3D vPos;
 245.933 +	aiVector3D vRot;
 245.934 +
 245.935 +	unsigned int iBone  = 0;
 245.936 +	if(!ParseUnsignedInt(szCurrent,&szCurrent,iBone))
 245.937 +	{
 245.938 +		DefaultLogger::get()->error("Unexpected EOF/EOL while parsing bone index");
 245.939 +		SMDI_PARSE_RETURN;
 245.940 +	}
 245.941 +	if (iBone >= asBones.size())
 245.942 +	{
 245.943 +		LogErrorNoThrow("Bone index in skeleton section is out of range");
 245.944 +		SMDI_PARSE_RETURN;
 245.945 +	}
 245.946 +	SMD::Bone& bone = asBones[iBone];
 245.947 +
 245.948 +	bone.sAnim.asKeys.push_back(SMD::Bone::Animation::MatrixKey());
 245.949 +	SMD::Bone::Animation::MatrixKey& key = bone.sAnim.asKeys.back();
 245.950 +
 245.951 +	key.dTime = (double)iTime;
 245.952 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.x))
 245.953 +	{
 245.954 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.x");
 245.955 +		SMDI_PARSE_RETURN;
 245.956 +	}
 245.957 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.y))
 245.958 +	{
 245.959 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.y");
 245.960 +		SMDI_PARSE_RETURN;
 245.961 +	}
 245.962 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.z))
 245.963 +	{
 245.964 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.z");
 245.965 +		SMDI_PARSE_RETURN;
 245.966 +	}
 245.967 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.x))
 245.968 +	{
 245.969 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.x");
 245.970 +		SMDI_PARSE_RETURN;
 245.971 +	}
 245.972 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.y))
 245.973 +	{
 245.974 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.y");
 245.975 +		SMDI_PARSE_RETURN;
 245.976 +	}
 245.977 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.z))
 245.978 +	{
 245.979 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.z");
 245.980 +		SMDI_PARSE_RETURN;
 245.981 +	}
 245.982 +	// build the transformation matrix of the key
 245.983 +	key.matrix.FromEulerAnglesXYZ(vRot.x,vRot.y,vRot.z);
 245.984 +	{
 245.985 +		aiMatrix4x4 mTemp;
 245.986 +		mTemp.a4 = vPos.x;
 245.987 +		mTemp.b4 = vPos.y;
 245.988 +		mTemp.c4 = vPos.z;
 245.989 +		key.matrix = key.matrix * mTemp;
 245.990 +	}
 245.991 +
 245.992 +	// go to the beginning of the next line
 245.993 +	SMDI_PARSE_RETURN;
 245.994 +}
 245.995 +
 245.996 +// ------------------------------------------------------------------------------------------------
 245.997 +// Parse a triangle
 245.998 +void SMDImporter::ParseTriangle(const char* szCurrent,
 245.999 +	const char** szCurrentOut)
245.1000 +{
245.1001 +	asTriangles.push_back(SMD::Face());
245.1002 +	SMD::Face& face = asTriangles.back();
245.1003 +	
245.1004 +	if(!SkipSpaces(szCurrent,&szCurrent))
245.1005 +	{
245.1006 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing a triangle");
245.1007 +		return;
245.1008 +	}
245.1009 +
245.1010 +	// read the texture file name
245.1011 +	const char* szLast = szCurrent;
245.1012 +	while (!IsSpaceOrNewLine(*szCurrent++));
245.1013 +
245.1014 +	// ... and get the index that belongs to this file name
245.1015 +	face.iTexture = GetTextureIndex(std::string(szLast,(uintptr_t)szCurrent-(uintptr_t)szLast));
245.1016 +
245.1017 +	SkipSpacesAndLineEnd(szCurrent,&szCurrent);
245.1018 +
245.1019 +	// load three vertices
245.1020 +	for (unsigned int iVert = 0; iVert < 3;++iVert)
245.1021 +	{
245.1022 +		ParseVertex(szCurrent,&szCurrent,
245.1023 +			face.avVertices[iVert]);
245.1024 +	}
245.1025 +	*szCurrentOut = szCurrent;
245.1026 +}
245.1027 +
245.1028 +// ------------------------------------------------------------------------------------------------
245.1029 +// Parse a float
245.1030 +bool SMDImporter::ParseFloat(const char* szCurrent,
245.1031 +	const char** szCurrentOut, float& out)
245.1032 +{
245.1033 +	if(!SkipSpaces(&szCurrent))
245.1034 +		return false;
245.1035 +
245.1036 +	*szCurrentOut = fast_atoreal_move<float>(szCurrent,out);
245.1037 +	return true;
245.1038 +}
245.1039 +
245.1040 +// ------------------------------------------------------------------------------------------------
245.1041 +// Parse an unsigned int
245.1042 +bool SMDImporter::ParseUnsignedInt(const char* szCurrent,
245.1043 +	const char** szCurrentOut, unsigned int& out)
245.1044 +{
245.1045 +	if(!SkipSpaces(&szCurrent))
245.1046 +		return false;
245.1047 +
245.1048 +	out = strtoul10(szCurrent,szCurrentOut);
245.1049 +	return true;
245.1050 +}
245.1051 +
245.1052 +// ------------------------------------------------------------------------------------------------
245.1053 +// Parse a signed int
245.1054 +bool SMDImporter::ParseSignedInt(const char* szCurrent,
245.1055 +	const char** szCurrentOut, int& out)
245.1056 +{
245.1057 +	if(!SkipSpaces(&szCurrent))
245.1058 +		return false;
245.1059 +
245.1060 +	out = strtol10(szCurrent,szCurrentOut);
245.1061 +	return true;
245.1062 +}
245.1063 +
245.1064 +// ------------------------------------------------------------------------------------------------
245.1065 +// Parse a vertex
245.1066 +void SMDImporter::ParseVertex(const char* szCurrent,
245.1067 +	const char** szCurrentOut, SMD::Vertex& vertex,
245.1068 +	bool bVASection /*= false*/)
245.1069 +{
245.1070 +	if (SkipSpaces(&szCurrent) && IsLineEnd(*szCurrent))
245.1071 +	{
245.1072 +		SkipSpacesAndLineEnd(szCurrent,&szCurrent);
245.1073 +		return ParseVertex(szCurrent,szCurrentOut,vertex,bVASection);
245.1074 +	}
245.1075 +	if(!ParseSignedInt(szCurrent,&szCurrent,(int&)vertex.iParentNode))
245.1076 +	{
245.1077 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.parent");
245.1078 +		SMDI_PARSE_RETURN;
245.1079 +	}
245.1080 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.x))
245.1081 +	{
245.1082 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.x");
245.1083 +		SMDI_PARSE_RETURN;
245.1084 +	}
245.1085 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.y))
245.1086 +	{
245.1087 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.y");
245.1088 +		SMDI_PARSE_RETURN;
245.1089 +	}
245.1090 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.z))
245.1091 +	{
245.1092 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.z");
245.1093 +		SMDI_PARSE_RETURN;
245.1094 +	}
245.1095 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.x))
245.1096 +	{
245.1097 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.x");
245.1098 +		SMDI_PARSE_RETURN;
245.1099 +	}
245.1100 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.y))
245.1101 +	{
245.1102 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.y");
245.1103 +		SMDI_PARSE_RETURN;
245.1104 +	}
245.1105 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.z))
245.1106 +	{
245.1107 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.z");
245.1108 +		SMDI_PARSE_RETURN;
245.1109 +	}
245.1110 +
245.1111 +	if (bVASection)SMDI_PARSE_RETURN;
245.1112 +
245.1113 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.x))
245.1114 +	{
245.1115 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.x");
245.1116 +		SMDI_PARSE_RETURN;
245.1117 +	}
245.1118 +	if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.y))
245.1119 +	{
245.1120 +		LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.y");
245.1121 +		SMDI_PARSE_RETURN;
245.1122 +	}
245.1123 +
245.1124 +	// now read the number of bones affecting this vertex
245.1125 +	// all elements from now are fully optional, we don't need them
245.1126 +	unsigned int iSize = 0;
245.1127 +	if(!ParseUnsignedInt(szCurrent,&szCurrent,iSize))SMDI_PARSE_RETURN;
245.1128 +	vertex.aiBoneLinks.resize(iSize,std::pair<unsigned int, float>(0,0.0f));
245.1129 +
245.1130 +	for (std::vector<std::pair<unsigned int, float> >::iterator
245.1131 +		i =  vertex.aiBoneLinks.begin();
245.1132 +		i != vertex.aiBoneLinks.end();++i)
245.1133 +	{
245.1134 +		if(!ParseUnsignedInt(szCurrent,&szCurrent,(*i).first))
245.1135 +			SMDI_PARSE_RETURN;
245.1136 +		if(!ParseFloat(szCurrent,&szCurrent,(*i).second))
245.1137 +			SMDI_PARSE_RETURN;
245.1138 +	}
245.1139 +
245.1140 +	// go to the beginning of the next line
245.1141 +	SMDI_PARSE_RETURN;
245.1142 +}
245.1143 +
245.1144 +#endif // !! ASSIMP_BUILD_NO_SMD_IMPORTER
   246.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   246.2 +++ b/libs/assimp/SMDLoader.h	Sat Feb 01 19:58:19 2014 +0200
   246.3 @@ -0,0 +1,416 @@
   246.4 +/*
   246.5 +Open Asset Import Library (assimp)
   246.6 +----------------------------------------------------------------------
   246.7 +
   246.8 +Copyright (c) 2006-2012, assimp team
   246.9 +All rights reserved.
  246.10 +
  246.11 +Redistribution and use of this software in source and binary forms, 
  246.12 +with or without modification, are permitted provided that the 
  246.13 +following conditions are met:
  246.14 +
  246.15 +* Redistributions of source code must retain the above
  246.16 +  copyright notice, this list of conditions and the
  246.17 +  following disclaimer.
  246.18 +
  246.19 +* Redistributions in binary form must reproduce the above
  246.20 +  copyright notice, this list of conditions and the
  246.21 +  following disclaimer in the documentation and/or other
  246.22 +  materials provided with the distribution.
  246.23 +
  246.24 +* Neither the name of the assimp team, nor the names of its
  246.25 +  contributors may be used to endorse or promote products
  246.26 +  derived from this software without specific prior
  246.27 +  written permission of the assimp team.
  246.28 +
  246.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  246.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  246.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  246.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  246.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  246.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  246.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  246.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  246.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  246.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  246.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  246.40 +
  246.41 +----------------------------------------------------------------------
  246.42 +*/
  246.43 +
  246.44 +/** @file  SMDLoader.h
  246.45 + *  @brief Defintion of the Valve SMD file format
  246.46 + */
  246.47 +
  246.48 +#ifndef AI_SMDLOADER_H_INCLUDED
  246.49 +#define AI_SMDLOADER_H_INCLUDED
  246.50 +
  246.51 +// internal headers
  246.52 +#include "BaseImporter.h"
  246.53 +#include "ParsingUtils.h"
  246.54 +
  246.55 +// public Assimp headers
  246.56 +#include "assimp/types.h"
  246.57 +#include "assimp/texture.h"
  246.58 +#include "assimp/anim.h"
  246.59 +#include "assimp/material.h"
  246.60 +struct aiNode;
  246.61 +
  246.62 +// STL headers
  246.63 +#include <vector>
  246.64 +
  246.65 +namespace Assimp	{
  246.66 +
  246.67 +
  246.68 +namespace SMD	{
  246.69 +
  246.70 +// ---------------------------------------------------------------------------
  246.71 +/** Data structure for a vertex in a SMD file
  246.72 +*/
  246.73 +struct Vertex
  246.74 +{
  246.75 +	Vertex() : iParentNode(UINT_MAX)
  246.76 +	 {}
  246.77 +
  246.78 +	//! Vertex position, normal and texture coordinate
  246.79 +	aiVector3D pos,nor,uv;
  246.80 +
  246.81 +	//! Vertex parent node
  246.82 +	unsigned int iParentNode;
  246.83 +
  246.84 +	//! Links to bones: pair.first is the bone index,
  246.85 +	//! pair.second is the vertex weight.
  246.86 +	//! WARN: The remaining weight (to reach 1.0f) is assigned
  246.87 +	//! to the parent node/bone
  246.88 +	std::vector<std::pair<unsigned int, float> > aiBoneLinks;
  246.89 +};
  246.90 +
  246.91 +// ---------------------------------------------------------------------------
  246.92 +/** Data structure for a face in a SMD file
  246.93 +*/
  246.94 +struct Face
  246.95 +{
  246.96 +	Face() : iTexture(0x0)
  246.97 +	 {}
  246.98 +
  246.99 +	//! Texture index for the face
 246.100 +	unsigned int iTexture;
 246.101 +
 246.102 +	//! The three vertices of the face
 246.103 +	Vertex avVertices[3];
 246.104 +};
 246.105 +
 246.106 +// ---------------------------------------------------------------------------
 246.107 +/** Data structure for a bone in a SMD file
 246.108 +*/
 246.109 +struct Bone
 246.110 +{
 246.111 +	//! Default constructor
 246.112 +	Bone() : iParent(UINT_MAX), bIsUsed(false)
 246.113 +	{
 246.114 +	}
 246.115 +
 246.116 +	//! Destructor
 246.117 +	~Bone()
 246.118 +	{
 246.119 +	}
 246.120 +
 246.121 +	//! Name of the bone
 246.122 +	std::string mName;
 246.123 +
 246.124 +	//! Parent of the bone
 246.125 +	uint32_t iParent;
 246.126 +
 246.127 +	//! Animation of the bone
 246.128 +	struct Animation
 246.129 +	{
 246.130 +		//! Public default constructor
 246.131 +		Animation() 
 246.132 +		{
 246.133 +			asKeys.reserve(20);
 246.134 +		}
 246.135 +
 246.136 +		//! Data structure for a matrix key
 246.137 +		struct MatrixKey
 246.138 +		{
 246.139 +			//! Matrix at this time
 246.140 +			aiMatrix4x4 matrix;
 246.141 +
 246.142 +			//! Absolute transformation matrix
 246.143 +			aiMatrix4x4 matrixAbsolute;
 246.144 +
 246.145 +			//! Position
 246.146 +			aiVector3D vPos;
 246.147 +
 246.148 +			//! Rotation (euler angles)
 246.149 +			aiVector3D vRot;
 246.150 +
 246.151 +			//! Current time. may be negative, this
 246.152 +			//! will be fixed later
 246.153 +			double dTime;
 246.154 +		};
 246.155 +
 246.156 +		//! Index of the key with the smallest time value
 246.157 +		uint32_t iFirstTimeKey;
 246.158 +
 246.159 +		//! Array of matrix keys
 246.160 +		std::vector<MatrixKey> asKeys;
 246.161 +
 246.162 +	} sAnim;
 246.163 +
 246.164 +	//! Offset matrix of the bone
 246.165 +	aiMatrix4x4 mOffsetMatrix;
 246.166 +
 246.167 +	//! true if the bone is referenced by at least one mesh
 246.168 +	bool bIsUsed;
 246.169 +};
 246.170 +
 246.171 +} //! namespace SMD
 246.172 +
 246.173 +// ---------------------------------------------------------------------------
 246.174 +/** Used to load Half-life 1 and 2 SMD models
 246.175 +*/
 246.176 +class SMDImporter : public BaseImporter
 246.177 +{
 246.178 +public:
 246.179 +	SMDImporter();
 246.180 +	~SMDImporter();
 246.181 +
 246.182 +
 246.183 +public:
 246.184 +
 246.185 +	// -------------------------------------------------------------------
 246.186 +	/** Returns whether the class can handle the format of the given file. 
 246.187 +	 * See BaseImporter::CanRead() for details.
 246.188 +	 */
 246.189 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
 246.190 +		bool checkSig) const;
 246.191 +
 246.192 +	// -------------------------------------------------------------------
 246.193 +	/** Called prior to ReadFile().
 246.194 +	 * The function is a request to the importer to update its configuration
 246.195 +	 * basing on the Importer's configuration property list.
 246.196 +	 */
 246.197 +	void SetupProperties(const Importer* pImp);
 246.198 +
 246.199 +protected:
 246.200 +
 246.201 +
 246.202 +	// -------------------------------------------------------------------
 246.203 +	/** Return importer meta information.
 246.204 +	 * See #BaseImporter::GetInfo for the details
 246.205 +	 */
 246.206 +	const aiImporterDesc* GetInfo () const;
 246.207 +
 246.208 +	// -------------------------------------------------------------------
 246.209 +	/** Imports the given file into the given scene structure. 
 246.210 +	* See BaseImporter::InternReadFile() for details
 246.211 +	*/
 246.212 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
 246.213 +		IOSystem* pIOHandler);
 246.214 +
 246.215 +protected:
 246.216 +
 246.217 +	// -------------------------------------------------------------------
 246.218 +	/** Parse the SMD file and create the output scene
 246.219 +	*/
 246.220 +	void ParseFile();
 246.221 +
 246.222 +	// -------------------------------------------------------------------
 246.223 +	/** Parse the triangles section of the SMD file
 246.224 +	 * \param szCurrent Current position in the file. Points to the first
 246.225 +	 * data line of the section.
 246.226 +	 * \param szCurrentOut Receives a pointer to the heading line of
 246.227 +	 * the next section (or to EOF)
 246.228 +	*/
 246.229 +	void ParseTrianglesSection(const char* szCurrent,
 246.230 +		const char** szCurrentOut);
 246.231 +
 246.232 +	// -------------------------------------------------------------------
 246.233 +	/** Parse the vertex animation section in VTA files
 246.234 +	 * \param szCurrent Current position in the file. Points to the first
 246.235 +	 * data line of the section.
 246.236 +	 * \param szCurrentOut Receives a pointer to the heading line of
 246.237 +	 * the next section (or to EOF)
 246.238 +	*/
 246.239 +	void ParseVASection(const char* szCurrent,
 246.240 +		const char** szCurrentOut);
 246.241 +
 246.242 +	// -------------------------------------------------------------------
 246.243 +	/** Parse the nodes section of the SMD file
 246.244 +	 * \param szCurrent Current position in the file. Points to the first
 246.245 +	 * data line of the section.
 246.246 +	 * \param szCurrentOut Receives a pointer to the heading line of
 246.247 +	 * the next section (or to EOF)
 246.248 +	*/
 246.249 +	void ParseNodesSection(const char* szCurrent,
 246.250 +		const char** szCurrentOut);
 246.251 +
 246.252 +	// -------------------------------------------------------------------
 246.253 +	/** Parse the skeleton section of the SMD file
 246.254 +	 * \param szCurrent Current position in the file. Points to the first
 246.255 +	 * data line of the section.
 246.256 +	 * \param szCurrentOut Receives a pointer to the heading line of
 246.257 +	 * the next section (or to EOF)
 246.258 +	*/
 246.259 +	void ParseSkeletonSection(const char* szCurrent,
 246.260 +		const char** szCurrentOut);
 246.261 +
 246.262 +	// -------------------------------------------------------------------
 246.263 +	/** Parse a single triangle in the SMD file
 246.264 +	 * \param szCurrent Current position in the file. Points to the first
 246.265 +	 * data line of the section.
 246.266 +	 * \param szCurrentOut Receives the output cursor position
 246.267 +	*/
 246.268 +	void ParseTriangle(const char* szCurrent,
 246.269 +		const char** szCurrentOut);
 246.270 +
 246.271 +
 246.272 +	// -------------------------------------------------------------------
 246.273 +	/** Parse a single vertex in the SMD file
 246.274 +	 * \param szCurrent Current position in the file. Points to the first
 246.275 +	 * data line of the section.
 246.276 +	 * \param szCurrentOut Receives the output cursor position
 246.277 +	 * \param vertex Vertex to be filled
 246.278 +	*/
 246.279 +	void ParseVertex(const char* szCurrent,
 246.280 +		const char** szCurrentOut, SMD::Vertex& vertex,
 246.281 +		bool bVASection = false);
 246.282 +
 246.283 +	// -------------------------------------------------------------------
 246.284 +	/** Get  the index of a texture. If the texture was not yet known
 246.285 +	 *  it will be added to the internal texture list.
 246.286 +	 * \param filename Name of the texture
 246.287 +	 * \return Value texture index
 246.288 +	 */
 246.289 +	unsigned int GetTextureIndex(const std::string& filename);
 246.290 +
 246.291 +	// -------------------------------------------------------------------
 246.292 +	/** Computes absolute bone transformations
 246.293 +	 * All output transformations are in worldspace.
 246.294 +	 */
 246.295 +	void ComputeAbsoluteBoneTransformations();
 246.296 +
 246.297 +
 246.298 +	// -------------------------------------------------------------------
 246.299 +	/** Parse a line in the skeleton section
 246.300 +	 */
 246.301 +	void ParseSkeletonElement(const char* szCurrent,
 246.302 +		const char** szCurrentOut,int iTime);
 246.303 +
 246.304 +	// -------------------------------------------------------------------
 246.305 +	/** Parse a line in the nodes section
 246.306 +	 */
 246.307 +	void ParseNodeInfo(const char* szCurrent,
 246.308 +		const char** szCurrentOut);
 246.309 +
 246.310 +
 246.311 +	// -------------------------------------------------------------------
 246.312 +	/** Parse a floating-point value
 246.313 +	 */
 246.314 +	bool ParseFloat(const char* szCurrent,
 246.315 +		const char** szCurrentOut, float& out);
 246.316 +
 246.317 +	// -------------------------------------------------------------------
 246.318 +	/** Parse an unsigned integer. There may be no sign!
 246.319 +	 */
 246.320 +	bool ParseUnsignedInt(const char* szCurrent,
 246.321 +		const char** szCurrentOut, unsigned int& out);
 246.322 +
 246.323 +	// -------------------------------------------------------------------
 246.324 +	/** Parse a signed integer. Signs (+,-) are handled.
 246.325 +	 */
 246.326 +	bool ParseSignedInt(const char* szCurrent,
 246.327 +		const char** szCurrentOut, int& out);
 246.328 +
 246.329 +	// -------------------------------------------------------------------
 246.330 +	/** Fix invalid time values in the file
 246.331 +	 */
 246.332 +	void FixTimeValues();
 246.333 +
 246.334 +	// -------------------------------------------------------------------
 246.335 +	/** Add all children of a bone as subnodes to a node
 246.336 +	 * \param pcNode Parent node
 246.337 +	 * \param iParent Parent bone index
 246.338 +	 */
 246.339 +	void AddBoneChildren(aiNode* pcNode, uint32_t iParent);
 246.340 +
 246.341 +	// -------------------------------------------------------------------
 246.342 +	/** Build output meshes/materials/nodes/animations
 246.343 +	 */
 246.344 +	void CreateOutputMeshes();
 246.345 +	void CreateOutputNodes();
 246.346 +	void CreateOutputAnimations();
 246.347 +	void CreateOutputMaterials();
 246.348 +
 246.349 +
 246.350 +	// -------------------------------------------------------------------
 246.351 +	/** Print a log message together with the current line number
 246.352 +	 */
 246.353 +	void LogErrorNoThrow(const char* msg);
 246.354 +	void LogWarning(const char* msg);
 246.355 +
 246.356 +
 246.357 +	// -------------------------------------------------------------------
 246.358 +	inline bool SkipLine( const char* in, const char** out)
 246.359 +	{
 246.360 +		Assimp::SkipLine(in,out);
 246.361 +		++iLineNumber;
 246.362 +		return true;
 246.363 +	}
 246.364 +	// -------------------------------------------------------------------
 246.365 +	inline bool SkipSpacesAndLineEnd( const char* in, const char** out)
 246.366 +	{
 246.367 +		++iLineNumber;
 246.368 +		return Assimp::SkipSpacesAndLineEnd(in,out);
 246.369 +	}
 246.370 +
 246.371 +private:
 246.372 +
 246.373 +	/** Configuration option: frame to be loaded */
 246.374 +	unsigned int configFrameID;
 246.375 +
 246.376 +	/** Buffer to hold the loaded file */
 246.377 +	const char* mBuffer;
 246.378 +
 246.379 +	/** Output scene to be filled
 246.380 +	*/
 246.381 +	aiScene* pScene;
 246.382 +
 246.383 +	/** Size of the input file in bytes
 246.384 +	 */
 246.385 +	unsigned int iFileSize;
 246.386 +
 246.387 +	/** Array of textures found in the file
 246.388 +	 */
 246.389 +	std::vector<std::string> aszTextures;
 246.390 +
 246.391 +	/** Array of triangles found in the file
 246.392 +	 */
 246.393 +	std::vector<SMD::Face> asTriangles;
 246.394 +
 246.395 +	/** Array of bones found in the file
 246.396 +	 */
 246.397 +	std::vector<SMD::Bone> asBones;
 246.398 +
 246.399 +	/** Smallest frame index found in the skeleton
 246.400 +	 */
 246.401 +	int iSmallestFrame;
 246.402 +
 246.403 +	/** Length of the whole animation, in frames
 246.404 +	 */
 246.405 +	double dLengthOfAnim;
 246.406 +
 246.407 +	/** Do we have texture coordinates?
 246.408 +	 */
 246.409 +	bool bHasUVs;
 246.410 +
 246.411 +	/** Current line numer
 246.412 +	 */
 246.413 +	unsigned int iLineNumber;
 246.414 +
 246.415 +};
 246.416 +
 246.417 +} // end of namespace Assimp
 246.418 +
 246.419 +#endif // AI_SMDIMPORTER_H_INC
   247.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   247.2 +++ b/libs/assimp/STLExporter.cpp	Sat Feb 01 19:58:19 2014 +0200
   247.3 @@ -0,0 +1,116 @@
   247.4 +/*
   247.5 +Open Asset Import Library (assimp)
   247.6 +----------------------------------------------------------------------
   247.7 +
   247.8 +Copyright (c) 2006-2012, assimp team
   247.9 +All rights reserved.
  247.10 +
  247.11 +Redistribution and use of this software in source and binary forms, 
  247.12 +with or without modification, are permitted provided that the 
  247.13 +following conditions are met:
  247.14 +
  247.15 +* Redistributions of source code must retain the above
  247.16 +  copyright notice, this list of conditions and the
  247.17 +  following disclaimer.
  247.18 +
  247.19 +* Redistributions in binary form must reproduce the above
  247.20 +  copyright notice, this list of conditions and the
  247.21 +  following disclaimer in the documentation and/or other
  247.22 +  materials provided with the distribution.
  247.23 +
  247.24 +* Neither the name of the assimp team, nor the names of its
  247.25 +  contributors may be used to endorse or promote products
  247.26 +  derived from this software without specific prior
  247.27 +  written permission of the assimp team.
  247.28 +
  247.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  247.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  247.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  247.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  247.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  247.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  247.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  247.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  247.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  247.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  247.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  247.40 +
  247.41 +----------------------------------------------------------------------
  247.42 +*/
  247.43 +
  247.44 +#include "AssimpPCH.h"
  247.45 +
  247.46 +#if !defined(ASSIMP_BUILD_NO_EXPORT) && !defined(ASSIMP_BUILD_NO_STL_EXPORTER)
  247.47 +
  247.48 +#include "STLExporter.h"
  247.49 +#include "assimp/version.h"
  247.50 +
  247.51 +using namespace Assimp;
  247.52 +namespace Assimp	{
  247.53 +
  247.54 +// ------------------------------------------------------------------------------------------------
  247.55 +// Worker function for exporting a scene to Stereolithograpy. Prototyped and registered in Exporter.cpp
  247.56 +void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
  247.57 +{
  247.58 +	// invoke the exporter 
  247.59 +	STLExporter exporter(pFile, pScene);
  247.60 +
  247.61 +	// we're still here - export successfully completed. Write the file.
  247.62 +	boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
  247.63 +	if(outfile == NULL) {
  247.64 +		throw DeadlyExportError("could not open output .stl file: " + std::string(pFile));
  247.65 +	}
  247.66 +
  247.67 +	outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
  247.68 +}
  247.69 +
  247.70 +} // end of namespace Assimp
  247.71 +
  247.72 +
  247.73 +// ------------------------------------------------------------------------------------------------
  247.74 +STLExporter :: STLExporter(const char* _filename, const aiScene* pScene)
  247.75 +: filename(_filename)
  247.76 +, pScene(pScene)
  247.77 +, endl("\n") 
  247.78 +{
  247.79 +	// make sure that all formatting happens using the standard, C locale and not the user's current locale
  247.80 +	const std::locale& l = std::locale("C");
  247.81 +	mOutput.imbue(l);
  247.82 +
  247.83 +	const std::string& name = "AssimpScene";
  247.84 +	
  247.85 +	mOutput << "solid " << name << endl;
  247.86 +	for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
  247.87 +		WriteMesh(pScene->mMeshes[i]);
  247.88 +	}
  247.89 +	mOutput << "endsolid " << name << endl;
  247.90 +}
  247.91 +
  247.92 +// ------------------------------------------------------------------------------------------------
  247.93 +void STLExporter :: WriteMesh(const aiMesh* m)
  247.94 +{
  247.95 +	for (unsigned int i = 0; i < m->mNumFaces; ++i) {
  247.96 +		const aiFace& f = m->mFaces[i];
  247.97 +
  247.98 +		// we need per-face normals. We specified aiProcess_GenNormals as pre-requisite for this exporter,
  247.99 +		// but nonetheless we have to expect per-vertex normals.
 247.100 +		aiVector3D nor;
 247.101 +		if (m->mNormals) {
 247.102 +			for(unsigned int a = 0; a < f.mNumIndices; ++a) {
 247.103 +				nor += m->mNormals[f.mIndices[a]];
 247.104 +			}
 247.105 +			nor.Normalize();
 247.106 +		}
 247.107 +		mOutput << " facet normal " << nor.x << " " << nor.y << " " << nor.z << endl;
 247.108 +		mOutput << "  outer loop" << endl; 
 247.109 +		for(unsigned int a = 0; a < f.mNumIndices; ++a) {
 247.110 +			const aiVector3D& v  = m->mVertices[f.mIndices[a]];
 247.111 +			mOutput << "  vertex " << v.x << " " << v.y << " " << v.z << endl;
 247.112 +		}
 247.113 +
 247.114 +		mOutput << "  endloop" << endl; 
 247.115 +		mOutput << " endfacet" << endl << endl; 
 247.116 +	}
 247.117 +}
 247.118 +
 247.119 +#endif
   248.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   248.2 +++ b/libs/assimp/STLExporter.h	Sat Feb 01 19:58:19 2014 +0200
   248.3 @@ -0,0 +1,84 @@
   248.4 +/*
   248.5 +Open Asset Import Library (assimp)
   248.6 +----------------------------------------------------------------------
   248.7 +
   248.8 +Copyright (c) 2006-2012, assimp team
   248.9 +All rights reserved.
  248.10 +
  248.11 +Redistribution and use of this software in source and binary forms, 
  248.12 +with or without modification, are permitted provided that the 
  248.13 +following conditions are met:
  248.14 +
  248.15 +* Redistributions of source code must retain the above
  248.16 +  copyright notice, this list of conditions and the
  248.17 +  following disclaimer.
  248.18 +
  248.19 +* Redistributions in binary form must reproduce the above
  248.20 +  copyright notice, this list of conditions and the
  248.21 +  following disclaimer in the documentation and/or other
  248.22 +  materials provided with the distribution.
  248.23 +
  248.24 +* Neither the name of the assimp team, nor the names of its
  248.25 +  contributors may be used to endorse or promote products
  248.26 +  derived from this software without specific prior
  248.27 +  written permission of the assimp team.
  248.28 +
  248.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  248.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  248.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  248.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  248.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  248.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  248.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  248.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  248.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  248.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  248.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  248.40 +
  248.41 +----------------------------------------------------------------------
  248.42 +*/
  248.43 +
  248.44 +/** @file STLExporter.h
  248.45 + * Declares the exporter class to write a scene to a Stereolithography (STL) file
  248.46 + */
  248.47 +#ifndef AI_STLEXPORTER_H_INC
  248.48 +#define AI_STLEXPORTER_H_INC
  248.49 +
  248.50 +#include <sstream>
  248.51 +
  248.52 +struct aiScene;
  248.53 +struct aiNode;
  248.54 +
  248.55 +namespace Assimp	
  248.56 +{
  248.57 +
  248.58 +// ------------------------------------------------------------------------------------------------
  248.59 +/** Helper class to export a given scene to a STL file. */
  248.60 +// ------------------------------------------------------------------------------------------------
  248.61 +class STLExporter
  248.62 +{
  248.63 +public:
  248.64 +	/// Constructor for a specific scene to export
  248.65 +	STLExporter(const char* filename, const aiScene* pScene);
  248.66 +
  248.67 +public:
  248.68 +
  248.69 +	/// public stringstreams to write all output into
  248.70 +	std::ostringstream mOutput;
  248.71 +
  248.72 +private:
  248.73 +
  248.74 +	void WriteMesh(const aiMesh* m);
  248.75 +
  248.76 +private:
  248.77 +
  248.78 +	const std::string filename;
  248.79 +	const aiScene* const pScene;
  248.80 +
  248.81 +	// this endl() doesn't flush() the stream
  248.82 +	const std::string endl;
  248.83 +};
  248.84 +
  248.85 +}
  248.86 +
  248.87 +#endif
   249.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   249.2 +++ b/libs/assimp/STLLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   249.3 @@ -0,0 +1,412 @@
   249.4 +/*
   249.5 +---------------------------------------------------------------------------
   249.6 +Open Asset Import Library (assimp)
   249.7 +---------------------------------------------------------------------------
   249.8 +
   249.9 +Copyright (c) 2006-2012, assimp team
  249.10 +
  249.11 +All rights reserved.
  249.12 +
  249.13 +Redistribution and use of this software in source and binary forms, 
  249.14 +with or without modification, are permitted provided that the following 
  249.15 +conditions are met:
  249.16 +
  249.17 +* Redistributions of source code must retain the above
  249.18 +  copyright notice, this list of conditions and the
  249.19 +  following disclaimer.
  249.20 +
  249.21 +* Redistributions in binary form must reproduce the above
  249.22 +  copyright notice, this list of conditions and the
  249.23 +  following disclaimer in the documentation and/or other
  249.24 +  materials provided with the distribution.
  249.25 +
  249.26 +* Neither the name of the assimp team, nor the names of its
  249.27 +  contributors may be used to endorse or promote products
  249.28 +  derived from this software without specific prior
  249.29 +  written permission of the assimp team.
  249.30 +
  249.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  249.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  249.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  249.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  249.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  249.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  249.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  249.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  249.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  249.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  249.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  249.42 +---------------------------------------------------------------------------
  249.43 +*/
  249.44 +
  249.45 +/** @file Implementation of the STL importer class */
  249.46 +
  249.47 +#include "AssimpPCH.h"
  249.48 +#ifndef ASSIMP_BUILD_NO_STL_IMPORTER
  249.49 +
  249.50 +// internal headers
  249.51 +#include "STLLoader.h"
  249.52 +#include "ParsingUtils.h"
  249.53 +#include "fast_atof.h"
  249.54 +
  249.55 +using namespace Assimp;
  249.56 +
  249.57 +static const aiImporterDesc desc = {
  249.58 +	"Stereolithography (STL) Importer",
  249.59 +	"",
  249.60 +	"",
  249.61 +	"",
  249.62 +	aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour,
  249.63 +	0,
  249.64 +	0,
  249.65 +	0,
  249.66 +	0,
  249.67 +	"stl" 
  249.68 +};
  249.69 +
  249.70 +// ------------------------------------------------------------------------------------------------
  249.71 +// Constructor to be privately used by Importer
  249.72 +STLImporter::STLImporter()
  249.73 +{}
  249.74 +
  249.75 +// ------------------------------------------------------------------------------------------------
  249.76 +// Destructor, private as well 
  249.77 +STLImporter::~STLImporter()
  249.78 +{}
  249.79 +
  249.80 +// ------------------------------------------------------------------------------------------------
  249.81 +// Returns whether the class can handle the format of the given file. 
  249.82 +bool STLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  249.83 +{
  249.84 +	const std::string extension = GetExtension(pFile);
  249.85 +
  249.86 +	if (extension == "stl")
  249.87 +		return true;
  249.88 +	else if (!extension.length() || checkSig)	{
  249.89 +		if (!pIOHandler)
  249.90 +			return true;
  249.91 +		const char* tokens[] = {"STL","solid"};
  249.92 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2);
  249.93 +	}
  249.94 +	return false;
  249.95 +}
  249.96 +
  249.97 +// ------------------------------------------------------------------------------------------------
  249.98 +const aiImporterDesc* STLImporter::GetInfo () const
  249.99 +{
 249.100 +	return &desc;
 249.101 +}
 249.102 +
 249.103 +// ------------------------------------------------------------------------------------------------
 249.104 +// Imports the given file into the given scene structure. 
 249.105 +void STLImporter::InternReadFile( const std::string& pFile, 
 249.106 +	aiScene* pScene, IOSystem* pIOHandler)
 249.107 +{
 249.108 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 249.109 +
 249.110 +	// Check whether we can read from the file
 249.111 +	if( file.get() == NULL)	{
 249.112 +		throw DeadlyImportError( "Failed to open STL file " + pFile + ".");
 249.113 +	}
 249.114 +
 249.115 +	fileSize = (unsigned int)file->FileSize();
 249.116 +
 249.117 +	// allocate storage and copy the contents of the file to a memory buffer
 249.118 +	// (terminate it with zero)
 249.119 +	std::vector<char> mBuffer2;
 249.120 +	TextFileToBuffer(file.get(),mBuffer2);
 249.121 +
 249.122 +	this->pScene = pScene;
 249.123 +	this->mBuffer = &mBuffer2[0];
 249.124 +
 249.125 +	// the default vertex color is white
 249.126 +	clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 1.0f;
 249.127 +
 249.128 +	// allocate one mesh
 249.129 +	pScene->mNumMeshes = 1;
 249.130 +	pScene->mMeshes = new aiMesh*[1];
 249.131 +	aiMesh* pMesh = pScene->mMeshes[0] = new aiMesh();
 249.132 +	pMesh->mMaterialIndex = 0;
 249.133 +
 249.134 +	// allocate a single node
 249.135 +	pScene->mRootNode = new aiNode();
 249.136 +	pScene->mRootNode->mNumMeshes = 1;
 249.137 +	pScene->mRootNode->mMeshes = new unsigned int[1];
 249.138 +	pScene->mRootNode->mMeshes[0] = 0;
 249.139 +
 249.140 +	bool bMatClr = false;
 249.141 +
 249.142 +	// check whether the file starts with 'solid' -
 249.143 +	// in this case we can simply assume it IS a text file. finished.
 249.144 +	if (!::strncmp(mBuffer,"solid",5)) {
 249.145 +		LoadASCIIFile();
 249.146 +	}
 249.147 +	else bMatClr = LoadBinaryFile();
 249.148 +
 249.149 +	// now copy faces
 249.150 +	pMesh->mFaces = new aiFace[pMesh->mNumFaces];
 249.151 +	for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i)	{
 249.152 +
 249.153 +		aiFace& face = pMesh->mFaces[i];
 249.154 +		face.mIndices = new unsigned int[face.mNumIndices = 3];
 249.155 +		for (unsigned int o = 0; o < 3;++o,++p) {
 249.156 +			face.mIndices[o] = p;
 249.157 +		}
 249.158 +	}
 249.159 +
 249.160 +	// create a single default material - everything white, as we have vertex colors
 249.161 +	aiMaterial* pcMat = new aiMaterial();
 249.162 +	aiString s;
 249.163 +	s.Set(AI_DEFAULT_MATERIAL_NAME);
 249.164 +	pcMat->AddProperty(&s, AI_MATKEY_NAME);
 249.165 +
 249.166 +	aiColor4D clrDiffuse(1.0f,1.0f,1.0f,1.0f);
 249.167 +	if (bMatClr) {
 249.168 +		clrDiffuse = clrColorDefault;
 249.169 +	}
 249.170 +	pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
 249.171 +	pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
 249.172 +	clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f);
 249.173 +	pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
 249.174 +
 249.175 +	pScene->mNumMaterials = 1;
 249.176 +	pScene->mMaterials = new aiMaterial*[1];
 249.177 +	pScene->mMaterials[0] = pcMat;
 249.178 +}
 249.179 +// ------------------------------------------------------------------------------------------------
 249.180 +// Read an ASCII STL file
 249.181 +void STLImporter::LoadASCIIFile()
 249.182 +{
 249.183 +	aiMesh* pMesh = pScene->mMeshes[0];
 249.184 +
 249.185 +	const char* sz = mBuffer + 5; // skip the "solid"
 249.186 +	SkipSpaces(&sz);
 249.187 +	const char* szMe = sz;
 249.188 +	while (!::IsSpaceOrNewLine(*sz)) {
 249.189 +		sz++;
 249.190 +	}
 249.191 +
 249.192 +	size_t temp;
 249.193 +	// setup the name of the node
 249.194 +	if ((temp = (size_t)(sz-szMe)))	{
 249.195 +
 249.196 +		pScene->mRootNode->mName.length = temp;
 249.197 +		memcpy(pScene->mRootNode->mName.data,szMe,temp);
 249.198 +		pScene->mRootNode->mName.data[temp] = '\0';
 249.199 +	}
 249.200 +	else pScene->mRootNode->mName.Set("<STL_ASCII>");
 249.201 +
 249.202 +	// try to guess how many vertices we could have
 249.203 +	// assume we'll need 160 bytes for each face
 249.204 +	pMesh->mNumVertices = ( pMesh->mNumFaces = std::max(1u,fileSize / 160u )) * 3;
 249.205 +	pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
 249.206 +	pMesh->mNormals  = new aiVector3D[pMesh->mNumVertices];
 249.207 +	
 249.208 +	unsigned int curFace = 0, curVertex = 3;
 249.209 +	for ( ;; )
 249.210 +	{
 249.211 +		// go to the next token
 249.212 +		if(!SkipSpacesAndLineEnd(&sz))
 249.213 +		{
 249.214 +			// seems we're finished although there was no end marker
 249.215 +			DefaultLogger::get()->warn("STL: unexpected EOF. \'endsolid\' keyword was expected");
 249.216 +			break;
 249.217 +		}
 249.218 +		// facet normal -0.13 -0.13 -0.98
 249.219 +		if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5)))	{
 249.220 +
 249.221 +			if (3 != curVertex) {
 249.222 +				DefaultLogger::get()->warn("STL: A new facet begins but the old is not yet complete");
 249.223 +			}
 249.224 +			if (pMesh->mNumFaces == curFace)	{
 249.225 +				ai_assert(pMesh->mNumFaces != 0);
 249.226 +
 249.227 +				// need to resize the arrays, our size estimate was wrong
 249.228 +				unsigned int iNeededSize = (unsigned int)(sz-mBuffer) / pMesh->mNumFaces;
 249.229 +				if (iNeededSize <= 160)iNeededSize >>= 1; // prevent endless looping
 249.230 +				unsigned int add = (unsigned int)((mBuffer+fileSize)-sz) / iNeededSize;
 249.231 +				add += add >> 3; // add 12.5% as buffer
 249.232 +				iNeededSize = (pMesh->mNumFaces + add)*3;
 249.233 +				aiVector3D* pv = new aiVector3D[iNeededSize];
 249.234 +				memcpy(pv,pMesh->mVertices,pMesh->mNumVertices*sizeof(aiVector3D));
 249.235 +				delete[] pMesh->mVertices;
 249.236 +				pMesh->mVertices = pv;
 249.237 +				pv = new aiVector3D[iNeededSize];
 249.238 +				memcpy(pv,pMesh->mNormals,pMesh->mNumVertices*sizeof(aiVector3D));
 249.239 +				delete[] pMesh->mNormals;
 249.240 +				pMesh->mNormals = pv;
 249.241 +
 249.242 +				pMesh->mNumVertices = iNeededSize;
 249.243 +				pMesh->mNumFaces += add;
 249.244 +			}
 249.245 +			aiVector3D* vn = &pMesh->mNormals[curFace++*3];
 249.246 +
 249.247 +			sz += 6;
 249.248 +			curVertex = 0;
 249.249 +			SkipSpaces(&sz);
 249.250 +			if (strncmp(sz,"normal",6))	{
 249.251 +				DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
 249.252 +			}
 249.253 +			else
 249.254 +			{
 249.255 +				sz += 7;
 249.256 +				SkipSpaces(&sz);
 249.257 +				sz = fast_atoreal_move<float>(sz, (float&)vn->x ); 
 249.258 +				SkipSpaces(&sz);
 249.259 +				sz = fast_atoreal_move<float>(sz, (float&)vn->y ); 
 249.260 +				SkipSpaces(&sz);
 249.261 +				sz = fast_atoreal_move<float>(sz, (float&)vn->z ); 
 249.262 +				*(vn+1) = *vn;
 249.263 +				*(vn+2) = *vn;
 249.264 +			}
 249.265 +		}
 249.266 +		// vertex 1.50000 1.50000 0.00000
 249.267 +		else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
 249.268 +		{
 249.269 +			if (3 == curVertex)	{
 249.270 +				DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
 249.271 +			}
 249.272 +			else
 249.273 +			{
 249.274 +				sz += 7;
 249.275 +				SkipSpaces(&sz);
 249.276 +				aiVector3D* vn = &pMesh->mVertices[(curFace-1)*3 + curVertex++];
 249.277 +				sz = fast_atoreal_move<float>(sz, (float&)vn->x ); 
 249.278 +				SkipSpaces(&sz);
 249.279 +				sz = fast_atoreal_move<float>(sz, (float&)vn->y ); 
 249.280 +				SkipSpaces(&sz);
 249.281 +				sz = fast_atoreal_move<float>(sz, (float&)vn->z ); 
 249.282 +			}
 249.283 +		}
 249.284 +		else if (!::strncmp(sz,"endsolid",8))	{
 249.285 +			// finished!
 249.286 +			break;
 249.287 +		}
 249.288 +		// else skip the whole identifier
 249.289 +		else while (!::IsSpaceOrNewLine(*sz)) {
 249.290 +			++sz;
 249.291 +		}
 249.292 +	}
 249.293 +
 249.294 +	if (!curFace)	{
 249.295 +		pMesh->mNumFaces = 0;
 249.296 +		throw DeadlyImportError("STL: ASCII file is empty or invalid; no data loaded");
 249.297 +	}
 249.298 +	pMesh->mNumFaces = curFace;
 249.299 +	pMesh->mNumVertices = curFace*3;
 249.300 +	// we are finished!
 249.301 +}
 249.302 +
 249.303 +// ------------------------------------------------------------------------------------------------
 249.304 +// Read a binary STL file
 249.305 +bool STLImporter::LoadBinaryFile()
 249.306 +{
 249.307 +	// skip the first 80 bytes
 249.308 +	if (fileSize < 84) {
 249.309 +		throw DeadlyImportError("STL: file is too small for the header");
 249.310 +	}
 249.311 +	bool bIsMaterialise = false;
 249.312 +
 249.313 +	// search for an occurence of "COLOR=" in the header
 249.314 +	const char* sz2 = (const char*)mBuffer;
 249.315 +	const char* const szEnd = sz2+80;
 249.316 +	while (sz2 < szEnd)	{
 249.317 +
 249.318 +		if ('C' == *sz2++ && 'O' == *sz2++ && 'L' == *sz2++ &&
 249.319 +			'O' == *sz2++ && 'R' == *sz2++ && '=' == *sz2++)	{
 249.320 +
 249.321 +			// read the default vertex color for facets
 249.322 +			bIsMaterialise = true;
 249.323 +			DefaultLogger::get()->info("STL: Taking code path for Materialise files");
 249.324 +			clrColorDefault.r = (*sz2++) / 255.0f;
 249.325 +			clrColorDefault.g = (*sz2++) / 255.0f;
 249.326 +			clrColorDefault.b = (*sz2++) / 255.0f;
 249.327 +			clrColorDefault.a = (*sz2++) / 255.0f;
 249.328 +			break;
 249.329 +		}
 249.330 +	}
 249.331 +	const unsigned char* sz = (const unsigned char*)mBuffer + 80;
 249.332 +
 249.333 +	// now read the number of facets
 249.334 +	aiMesh* pMesh = pScene->mMeshes[0];
 249.335 +	pScene->mRootNode->mName.Set("<STL_BINARY>");
 249.336 +
 249.337 +	pMesh->mNumFaces = *((uint32_t*)sz);
 249.338 +	sz += 4;
 249.339 +
 249.340 +	if (fileSize < 84 + pMesh->mNumFaces*50) {
 249.341 +		throw DeadlyImportError("STL: file is too small to hold all facets");
 249.342 +	}
 249.343 +
 249.344 +	if (!pMesh->mNumFaces) {
 249.345 +		throw DeadlyImportError("STL: file is empty. There are no facets defined");
 249.346 +	}
 249.347 +
 249.348 +	pMesh->mNumVertices = pMesh->mNumFaces*3;
 249.349 +
 249.350 +	aiVector3D* vp,*vn;
 249.351 +	vp = pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
 249.352 +	vn = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
 249.353 +
 249.354 +	for (unsigned int i = 0; i < pMesh->mNumFaces;++i)	{
 249.355 +
 249.356 +		// NOTE: Blender sometimes writes empty normals ... this is not
 249.357 +		// our fault ... the RemoveInvalidData helper step should fix that
 249.358 +		*vn = *((aiVector3D*)sz);
 249.359 +		sz += sizeof(aiVector3D);
 249.360 +		*(vn+1) = *vn;
 249.361 +		*(vn+2) = *vn;
 249.362 +		vn += 3;
 249.363 +
 249.364 +		*vp++ = *((aiVector3D*)sz);
 249.365 +		sz += sizeof(aiVector3D);
 249.366 +
 249.367 +		*vp++ = *((aiVector3D*)sz);
 249.368 +		sz += sizeof(aiVector3D);
 249.369 +
 249.370 +		*vp++ = *((aiVector3D*)sz);
 249.371 +		sz += sizeof(aiVector3D);
 249.372 +
 249.373 +		uint16_t color = *((uint16_t*)sz);
 249.374 +		sz += 2;
 249.375 +
 249.376 +		if (color & (1 << 15))
 249.377 +		{
 249.378 +			// seems we need to take the color
 249.379 +			if (!pMesh->mColors[0])
 249.380 +			{
 249.381 +				pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
 249.382 +				for (unsigned int i = 0; i <pMesh->mNumVertices;++i)
 249.383 +					*pMesh->mColors[0]++ = this->clrColorDefault;
 249.384 +				pMesh->mColors[0] -= pMesh->mNumVertices;
 249.385 +
 249.386 +				DefaultLogger::get()->info("STL: Mesh has vertex colors");
 249.387 +			}
 249.388 +			aiColor4D* clr = &pMesh->mColors[0][i*3];
 249.389 +			clr->a = 1.0f;
 249.390 +			if (bIsMaterialise) // this is reversed
 249.391 +			{
 249.392 +				clr->r = (color & 0x31u) / 31.0f;
 249.393 +				clr->g = ((color & (0x31u<<5))>>5u) / 31.0f;
 249.394 +				clr->b = ((color & (0x31u<<10))>>10u) / 31.0f;
 249.395 +			}
 249.396 +			else
 249.397 +			{
 249.398 +				clr->b = (color & 0x31u) / 31.0f;
 249.399 +				clr->g = ((color & (0x31u<<5))>>5u) / 31.0f;
 249.400 +				clr->r = ((color & (0x31u<<10))>>10u) / 31.0f;
 249.401 +			}
 249.402 +			// assign the color to all vertices of the face
 249.403 +			*(clr+1) = *clr;
 249.404 +			*(clr+2) = *clr;
 249.405 +		}
 249.406 +	}
 249.407 +	if (bIsMaterialise && !pMesh->mColors[0])
 249.408 +	{
 249.409 +		// use the color as diffuse material color
 249.410 +		return true;
 249.411 +	}
 249.412 +	return false;
 249.413 +}
 249.414 +
 249.415 +#endif // !! ASSIMP_BUILD_NO_STL_IMPORTER
   250.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   250.2 +++ b/libs/assimp/STLLoader.h	Sat Feb 01 19:58:19 2014 +0200
   250.3 @@ -0,0 +1,115 @@
   250.4 +/*
   250.5 +Open Asset Import Library (assimp)
   250.6 +----------------------------------------------------------------------
   250.7 +
   250.8 +Copyright (c) 2006-2012, assimp team
   250.9 +All rights reserved.
  250.10 +
  250.11 +Redistribution and use of this software in source and binary forms, 
  250.12 +with or without modification, are permitted provided that the 
  250.13 +following conditions are met:
  250.14 +
  250.15 +* Redistributions of source code must retain the above
  250.16 +  copyright notice, this list of conditions and the
  250.17 +  following disclaimer.
  250.18 +
  250.19 +* Redistributions in binary form must reproduce the above
  250.20 +  copyright notice, this list of conditions and the
  250.21 +  following disclaimer in the documentation and/or other
  250.22 +  materials provided with the distribution.
  250.23 +
  250.24 +* Neither the name of the assimp team, nor the names of its
  250.25 +  contributors may be used to endorse or promote products
  250.26 +  derived from this software without specific prior
  250.27 +  written permission of the assimp team.
  250.28 +
  250.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  250.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  250.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  250.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  250.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  250.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  250.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  250.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  250.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  250.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  250.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  250.40 +
  250.41 +----------------------------------------------------------------------
  250.42 +*/
  250.43 +
  250.44 +/** @file STLLoader.h
  250.45 + *  Declaration of the STL importer class. 
  250.46 + */
  250.47 +#ifndef AI_STLLOADER_H_INCLUDED
  250.48 +#define AI_STLLOADER_H_INCLUDED
  250.49 +
  250.50 +#include "BaseImporter.h"
  250.51 +#include "assimp/types.h"
  250.52 +
  250.53 +namespace Assimp	{
  250.54 +
  250.55 +// ---------------------------------------------------------------------------
  250.56 +/** Importer class for the sterolithography STL file format
  250.57 +*/
  250.58 +class STLImporter : public BaseImporter
  250.59 +{
  250.60 +public:
  250.61 +	STLImporter();
  250.62 +	~STLImporter();
  250.63 +
  250.64 +
  250.65 +public:
  250.66 +
  250.67 +	// -------------------------------------------------------------------
  250.68 +	/** Returns whether the class can handle the format of the given file. 
  250.69 +	 * See BaseImporter::CanRead() for details.	
  250.70 +	 */
  250.71 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  250.72 +		bool checkSig) const;
  250.73 +
  250.74 +protected:
  250.75 +
  250.76 +	// -------------------------------------------------------------------
  250.77 +	/** Return importer meta information.
  250.78 +	 * See #BaseImporter::GetInfo for the details
  250.79 +	 */
  250.80 +	const aiImporterDesc* GetInfo () const;
  250.81 +
  250.82 +	// -------------------------------------------------------------------
  250.83 +	/** Imports the given file into the given scene structure. 
  250.84 +	* See BaseImporter::InternReadFile() for details
  250.85 +	*/
  250.86 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  250.87 +		IOSystem* pIOHandler);
  250.88 +
  250.89 +
  250.90 +	// -------------------------------------------------------------------
  250.91 +	/** Loads a binary .stl file
  250.92 +	 * @return true if the default vertex color must be used as material color
  250.93 +	*/
  250.94 +	bool LoadBinaryFile();
  250.95 +
  250.96 +	// -------------------------------------------------------------------
  250.97 +	/** Loads a ASCII text .stl file
  250.98 +	*/
  250.99 +	void LoadASCIIFile();
 250.100 +
 250.101 +protected:
 250.102 +
 250.103 +	/** Buffer to hold the loaded file */
 250.104 +	const char* mBuffer;
 250.105 +
 250.106 +	/** Size of the file, in bytes */
 250.107 +	unsigned int fileSize;
 250.108 +
 250.109 +	/** Output scene */
 250.110 +	aiScene* pScene;
 250.111 +
 250.112 +	/** Default vertex color */
 250.113 +	aiColor4D clrColorDefault;
 250.114 +};
 250.115 +
 250.116 +} // end of namespace Assimp
 250.117 +
 250.118 +#endif // AI_3DSIMPORTER_H_IN
   251.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   251.2 +++ b/libs/assimp/SceneCombiner.cpp	Sat Feb 01 19:58:19 2014 +0200
   251.3 @@ -0,0 +1,1146 @@
   251.4 +/*
   251.5 +Open Asset Import Library (assimp)
   251.6 +----------------------------------------------------------------------
   251.7 +
   251.8 +Copyright (c) 2006-2012, assimp team
   251.9 +All rights reserved.
  251.10 +
  251.11 +Redistribution and use of this software in source and binary forms, 
  251.12 +with or without modification, are permitted provided that the 
  251.13 +following conditions are met:
  251.14 +
  251.15 +* Redistributions of source code must retain the above
  251.16 +  copyright notice, this list of conditions and the
  251.17 +  following disclaimer.
  251.18 +
  251.19 +* Redistributions in binary form must reproduce the above
  251.20 +  copyright notice, this list of conditions and the
  251.21 +  following disclaimer in the documentation and/or other
  251.22 +  materials provided with the distribution.
  251.23 +
  251.24 +* Neither the name of the assimp team, nor the names of its
  251.25 +  contributors may be used to endorse or promote products
  251.26 +  derived from this software without specific prior
  251.27 +  written permission of the assimp team.
  251.28 +
  251.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  251.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  251.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  251.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  251.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  251.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  251.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  251.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  251.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  251.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  251.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  251.40 +
  251.41 +----------------------------------------------------------------------
  251.42 +*/
  251.43 +
  251.44 +
  251.45 +// ----------------------------------------------------------------------------
  251.46 +/** @file Implements Assimp::SceneCombiner. This is a smart utility
  251.47 + *    class that combines multiple scenes, meshes, ... into one. Currently 
  251.48 + *    these utilities are used by the IRR and LWS loaders and the
  251.49 + *    OptimizeGraph step.
  251.50 + */
  251.51 +// ----------------------------------------------------------------------------
  251.52 +#include "AssimpPCH.h"
  251.53 +#include "SceneCombiner.h"
  251.54 +#include "fast_atof.h"
  251.55 +#include "Hash.h"
  251.56 +#include "time.h"
  251.57 +
  251.58 +namespace Assimp	{
  251.59 +
  251.60 +// ------------------------------------------------------------------------------------------------
  251.61 +// Add a prefix to a string
  251.62 +inline void PrefixString(aiString& string,const char* prefix, unsigned int len)
  251.63 +{
  251.64 +	// If the string is already prefixed, we won't prefix it a second time
  251.65 +	if (string.length >= 1 && string.data[0] == '$')
  251.66 +		return;
  251.67 +
  251.68 +	if (len+string.length>=MAXLEN-1) {
  251.69 +		DefaultLogger::get()->debug("Can't add an unique prefix because the string is too long");
  251.70 +		ai_assert(false);
  251.71 +		return;
  251.72 +	}
  251.73 +
  251.74 +	// Add the prefix
  251.75 +	::memmove(string.data+len,string.data,string.length+1);
  251.76 +	::memcpy (string.data, prefix, len);
  251.77 +
  251.78 +	// And update the string's length
  251.79 +	string.length += len;
  251.80 +}
  251.81 +
  251.82 +// ------------------------------------------------------------------------------------------------
  251.83 +// Add node identifiers to a hashing set
  251.84 +void SceneCombiner::AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes)
  251.85 +{
  251.86 +	// Add node name to hashing set if it is non-empty - empty nodes are allowed 
  251.87 +	// and they can't have any anims assigned so its absolutely safe to duplicate them.
  251.88 +	if (node->mName.length) {
  251.89 +		hashes.insert( SuperFastHash(node->mName.data,node->mName.length) );
  251.90 +	}
  251.91 +
  251.92 +	// Process all children recursively
  251.93 +	for (unsigned int i = 0; i < node->mNumChildren;++i)
  251.94 +		AddNodeHashes(node->mChildren[i],hashes);
  251.95 +}
  251.96 +
  251.97 +// ------------------------------------------------------------------------------------------------
  251.98 +// Add a name prefix to all nodes in a hierarchy
  251.99 +void SceneCombiner::AddNodePrefixes(aiNode* node, const char* prefix, unsigned int len)
 251.100 +{
 251.101 +	ai_assert(NULL != prefix);
 251.102 +	PrefixString(node->mName,prefix,len);
 251.103 +
 251.104 +	// Process all children recursively
 251.105 +	for (unsigned int i = 0; i < node->mNumChildren;++i)
 251.106 +		AddNodePrefixes(node->mChildren[i],prefix,len);
 251.107 +}
 251.108 +
 251.109 +// ------------------------------------------------------------------------------------------------
 251.110 +// Search for matching names
 251.111 +bool SceneCombiner::FindNameMatch(const aiString& name, std::vector<SceneHelper>& input, unsigned int cur)
 251.112 +{
 251.113 +	const unsigned int hash = SuperFastHash(name.data, name.length);
 251.114 +
 251.115 +	// Check whether we find a positive match in one of the given sets
 251.116 +	for (unsigned int i = 0; i < input.size(); ++i) {
 251.117 +
 251.118 +		if (cur != i && input[i].hashes.find(hash) != input[i].hashes.end()) {
 251.119 +			return true;
 251.120 +		}
 251.121 +	}
 251.122 +	return false;
 251.123 +}
 251.124 +
 251.125 +// ------------------------------------------------------------------------------------------------
 251.126 +// Add a name prefix to all nodes in a hierarchy if a hash match is found
 251.127 +void SceneCombiner::AddNodePrefixesChecked(aiNode* node, const char* prefix, unsigned int len,
 251.128 +	std::vector<SceneHelper>& input, unsigned int cur)
 251.129 +{
 251.130 +	ai_assert(NULL != prefix);
 251.131 +	const unsigned int hash = SuperFastHash(node->mName.data,node->mName.length);
 251.132 +
 251.133 +	// Check whether we find a positive match in one of the given sets
 251.134 +	for (unsigned int i = 0; i < input.size(); ++i) {
 251.135 +
 251.136 +		if (cur != i && input[i].hashes.find(hash) != input[i].hashes.end()) {
 251.137 +			PrefixString(node->mName,prefix,len);
 251.138 +			break;
 251.139 +		}
 251.140 +	}
 251.141 +
 251.142 +	// Process all children recursively
 251.143 +	for (unsigned int i = 0; i < node->mNumChildren;++i)
 251.144 +		AddNodePrefixesChecked(node->mChildren[i],prefix,len,input,cur);
 251.145 +}
 251.146 +
 251.147 +// ------------------------------------------------------------------------------------------------
 251.148 +// Add an offset to all mesh indices in a node graph
 251.149 +void SceneCombiner::OffsetNodeMeshIndices (aiNode* node, unsigned int offset)
 251.150 +{
 251.151 +	for (unsigned int i = 0; i < node->mNumMeshes;++i)
 251.152 +		node->mMeshes[i] += offset;
 251.153 +
 251.154 +	for (unsigned int i = 0; i < node->mNumChildren;++i)
 251.155 +		OffsetNodeMeshIndices(node->mChildren[i],offset);
 251.156 +}
 251.157 +
 251.158 +// ------------------------------------------------------------------------------------------------
 251.159 +// Merges two scenes. Currently only used by the LWS loader.
 251.160 +void SceneCombiner::MergeScenes(aiScene** _dest,std::vector<aiScene*>& src,
 251.161 +	unsigned int flags)
 251.162 +{
 251.163 +	ai_assert(NULL != _dest);
 251.164 +
 251.165 +	// if _dest points to NULL allocate a new scene. Otherwise clear the old and reuse it
 251.166 +	if (src.empty())
 251.167 +	{
 251.168 +		if (*_dest)
 251.169 +		{
 251.170 +			(*_dest)->~aiScene();
 251.171 +			SceneCombiner::CopySceneFlat(_dest,src[0]);
 251.172 +		}
 251.173 +		else *_dest = src[0];
 251.174 +		return;
 251.175 +	}
 251.176 +	if (*_dest)(*_dest)->~aiScene();
 251.177 +	else *_dest = new aiScene();
 251.178 +
 251.179 +	// Create a dummy scene to serve as master for the others
 251.180 +	aiScene* master = new aiScene();
 251.181 +	master->mRootNode = new aiNode();
 251.182 +	master->mRootNode->mName.Set("<MergeRoot>");
 251.183 +
 251.184 +	std::vector<AttachmentInfo> srcList (src.size());
 251.185 +	for (unsigned int i = 0; i < srcList.size();++i)	{
 251.186 +		srcList[i] = AttachmentInfo(src[i],master->mRootNode);
 251.187 +	}
 251.188 +
 251.189 +	// 'master' will be deleted afterwards
 251.190 +	MergeScenes (_dest, master, srcList, flags);
 251.191 +}
 251.192 +
 251.193 +// ------------------------------------------------------------------------------------------------
 251.194 +void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInfo>& srcList)
 251.195 +{
 251.196 +	unsigned int cnt;
 251.197 +	for (cnt = 0; cnt < attach->mNumChildren;++cnt)
 251.198 +		AttachToGraph(attach->mChildren[cnt],srcList);
 251.199 +
 251.200 +	cnt = 0;
 251.201 +	for (std::vector<NodeAttachmentInfo>::iterator it = srcList.begin();
 251.202 +		 it != srcList.end(); ++it)
 251.203 +	{
 251.204 +		if ((*it).attachToNode == attach && !(*it).resolved)
 251.205 +			++cnt;
 251.206 +	}
 251.207 +
 251.208 +	if (cnt)	{
 251.209 +		aiNode** n = new aiNode*[cnt+attach->mNumChildren];
 251.210 +		if (attach->mNumChildren)	{
 251.211 +			::memcpy(n,attach->mChildren,sizeof(void*)*attach->mNumChildren);
 251.212 +			delete[] attach->mChildren;
 251.213 +		}
 251.214 +		attach->mChildren = n;
 251.215 +
 251.216 +		n += attach->mNumChildren;
 251.217 +		attach->mNumChildren += cnt;
 251.218 +
 251.219 +		for (unsigned int i = 0; i < srcList.size();++i)	{
 251.220 +			NodeAttachmentInfo& att = srcList[i];
 251.221 +			if (att.attachToNode == attach && !att.resolved)	{
 251.222 +				*n = att.node;
 251.223 +				(**n).mParent = attach;
 251.224 +				++n;
 251.225 +
 251.226 +				// mark this attachment as resolved
 251.227 +				att.resolved = true;
 251.228 +			}
 251.229 +		}
 251.230 +	}
 251.231 +}
 251.232 +
 251.233 +// ------------------------------------------------------------------------------------------------
 251.234 +void SceneCombiner::AttachToGraph ( aiScene* master, 
 251.235 +	std::vector<NodeAttachmentInfo>& src)
 251.236 +{
 251.237 +	ai_assert(NULL != master);
 251.238 +	AttachToGraph(master->mRootNode,src);
 251.239 +}
 251.240 +
 251.241 +// ------------------------------------------------------------------------------------------------
 251.242 +void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master, 
 251.243 +	std::vector<AttachmentInfo>& srcList,
 251.244 +	unsigned int flags)
 251.245 +{
 251.246 +	ai_assert(NULL != _dest);
 251.247 +
 251.248 +	// if _dest points to NULL allocate a new scene. Otherwise clear the old and reuse it
 251.249 +	if (srcList.empty())	{
 251.250 +		if (*_dest)	{
 251.251 +			SceneCombiner::CopySceneFlat(_dest,master);
 251.252 +		}
 251.253 +		else *_dest = master;
 251.254 +		return;
 251.255 +	}
 251.256 +	if (*_dest) {
 251.257 +		(*_dest)->~aiScene();
 251.258 +		new (*_dest) aiScene();
 251.259 +	}
 251.260 +	else *_dest = new aiScene();
 251.261 +
 251.262 +	aiScene* dest = *_dest;
 251.263 +
 251.264 +	std::vector<SceneHelper> src (srcList.size()+1);
 251.265 +	src[0].scene = master;
 251.266 +	for (unsigned int i = 0; i < srcList.size();++i)	{
 251.267 +		src[i+1] = SceneHelper( srcList[i].scene );
 251.268 +	}
 251.269 +
 251.270 +	// this helper array specifies which scenes are duplicates of others
 251.271 +	std::vector<unsigned int> duplicates(src.size(),UINT_MAX);
 251.272 +
 251.273 +	// this helper array is used as lookup table several times
 251.274 +	std::vector<unsigned int> offset(src.size());
 251.275 +
 251.276 +	// Find duplicate scenes
 251.277 +	for (unsigned int i = 0; i < src.size();++i) {
 251.278 +		if (duplicates[i] != i && duplicates[i] != UINT_MAX) {
 251.279 +			continue;
 251.280 +		}
 251.281 +			
 251.282 +		duplicates[i] = i;
 251.283 +		for ( unsigned int a = i+1; a < src.size(); ++a)	{
 251.284 +			if (src[i].scene == src[a].scene) {
 251.285 +				duplicates[a] = i;
 251.286 +			}
 251.287 +		}
 251.288 +	}
 251.289 +
 251.290 +	// Generate unique names for all named stuff?
 251.291 +	if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES)
 251.292 +	{
 251.293 +#if 0
 251.294 +		// Construct a proper random number generator
 251.295 +		boost::mt19937 rng(  );
 251.296 +		boost::uniform_int<> dist(1u,1 << 24u);
 251.297 +		boost::variate_generator<boost::mt19937&, boost::uniform_int<> > rndGen(rng, dist);   
 251.298 +#endif
 251.299 +		for (unsigned int i = 1; i < src.size();++i)
 251.300 +		{
 251.301 +			//if (i != duplicates[i]) 
 251.302 +			//{
 251.303 +			//	// duplicate scenes share the same UID
 251.304 +			//	::strcpy( src[i].id, src[duplicates[i]].id );
 251.305 +			//	src[i].idlen = src[duplicates[i]].idlen;
 251.306 +
 251.307 +			//	continue;
 251.308 +			//}
 251.309 +
 251.310 +			src[i].idlen = ::sprintf(src[i].id,"$%.6X$_",i);
 251.311 +
 251.312 +			if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
 251.313 +				
 251.314 +				// Compute hashes for all identifiers in this scene and store them
 251.315 +				// in a sorted table (for convenience I'm using std::set). We hash
 251.316 +				// just the node and animation channel names, all identifiers except
 251.317 +				// the material names should be caught by doing this.
 251.318 +				AddNodeHashes(src[i]->mRootNode,src[i].hashes);
 251.319 +
 251.320 +				for (unsigned int a = 0; a < src[i]->mNumAnimations;++a) {
 251.321 +					aiAnimation* anim = src[i]->mAnimations[a];
 251.322 +					src[i].hashes.insert(SuperFastHash(anim->mName.data,anim->mName.length));
 251.323 +				}
 251.324 +			}
 251.325 +		}
 251.326 +	}
 251.327 +	
 251.328 +	unsigned int cnt;
 251.329 +
 251.330 +	// First find out how large the respective output arrays must be
 251.331 +	for ( unsigned int n = 0; n < src.size();++n )
 251.332 +	{
 251.333 +		SceneHelper* cur = &src[n];
 251.334 +
 251.335 +		if (n == duplicates[n] || flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)	{
 251.336 +			dest->mNumTextures   += (*cur)->mNumTextures;
 251.337 +			dest->mNumMaterials  += (*cur)->mNumMaterials;
 251.338 +			dest->mNumMeshes     += (*cur)->mNumMeshes;
 251.339 +		}
 251.340 +
 251.341 +		dest->mNumLights     += (*cur)->mNumLights;
 251.342 +		dest->mNumCameras    += (*cur)->mNumCameras;
 251.343 +		dest->mNumAnimations += (*cur)->mNumAnimations;
 251.344 +
 251.345 +		// Combine the flags of all scenes
 251.346 +		// We need to process them flag-by-flag here to get correct results
 251.347 +		// dest->mFlags ; //|= (*cur)->mFlags;
 251.348 +		if ((*cur)->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
 251.349 +			dest->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
 251.350 +		}
 251.351 +	}
 251.352 +
 251.353 +	// generate the output texture list + an offset table for all texture indices
 251.354 +	if (dest->mNumTextures)
 251.355 +	{
 251.356 +		aiTexture** pip = dest->mTextures = new aiTexture*[dest->mNumMaterials];
 251.357 +		cnt = 0;
 251.358 +		for ( unsigned int n = 0; n < src.size();++n )
 251.359 +		{
 251.360 +			SceneHelper* cur = &src[n];
 251.361 +			for (unsigned int i = 0; i < (*cur)->mNumTextures;++i)
 251.362 +			{
 251.363 +				if (n != duplicates[n])
 251.364 +				{
 251.365 +					if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
 251.366 +						Copy(pip,(*cur)->mTextures[i]);
 251.367 +
 251.368 +					else continue;
 251.369 +				}
 251.370 +				else *pip = (*cur)->mTextures[i];
 251.371 +				++pip;
 251.372 +			}
 251.373 +
 251.374 +			offset[n] = cnt;
 251.375 +			cnt = (unsigned int)(pip - dest->mTextures);
 251.376 +		}
 251.377 +	}
 251.378 +
 251.379 +	// generate the output material list + an offset table for all material indices
 251.380 +	if (dest->mNumMaterials)
 251.381 +	{ 
 251.382 +		aiMaterial** pip = dest->mMaterials = new aiMaterial*[dest->mNumMaterials];
 251.383 +		cnt = 0;
 251.384 +		for ( unsigned int n = 0; n < src.size();++n )	{
 251.385 +			SceneHelper* cur = &src[n];
 251.386 +			for (unsigned int i = 0; i < (*cur)->mNumMaterials;++i)
 251.387 +			{
 251.388 +				if (n != duplicates[n])
 251.389 +				{
 251.390 +					if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
 251.391 +						Copy(pip,(*cur)->mMaterials[i]);
 251.392 +
 251.393 +					else continue;
 251.394 +				}
 251.395 +				else *pip = (*cur)->mMaterials[i];
 251.396 +
 251.397 +				if ((*cur)->mNumTextures != dest->mNumTextures)		{
 251.398 +					// We need to update all texture indices of the mesh. So we need to search for
 251.399 +					// a material property called '$tex.file'
 251.400 +
 251.401 +					for (unsigned int a = 0; a < (*pip)->mNumProperties;++a)
 251.402 +					{
 251.403 +						aiMaterialProperty* prop = (*pip)->mProperties[a];
 251.404 +						if (!strncmp(prop->mKey.data,"$tex.file",9))
 251.405 +						{
 251.406 +							// Check whether this texture is an embedded texture.
 251.407 +							// In this case the property looks like this: *<n>,
 251.408 +							// where n is the index of the texture.
 251.409 +							aiString& s = *((aiString*)prop->mData);
 251.410 +							if ('*' == s.data[0])	{
 251.411 +								// Offset the index and write it back ..
 251.412 +								const unsigned int idx = strtoul10(&s.data[1]) + offset[n];
 251.413 +								ASSIMP_itoa10(&s.data[1],sizeof(s.data)-1,idx);
 251.414 +							}
 251.415 +						}
 251.416 +
 251.417 +						// Need to generate new, unique material names?
 251.418 +						else if (!::strcmp( prop->mKey.data,"$mat.name" ) && flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES)
 251.419 +						{
 251.420 +							aiString* pcSrc = (aiString*) prop->mData; 
 251.421 +							PrefixString(*pcSrc, (*cur).id, (*cur).idlen);
 251.422 +						}
 251.423 +					}
 251.424 +				}
 251.425 +				++pip;
 251.426 +			}
 251.427 +
 251.428 +			offset[n] = cnt;
 251.429 +			cnt = (unsigned int)(pip - dest->mMaterials);
 251.430 +		}
 251.431 +	}
 251.432 +
 251.433 +	// generate the output mesh list + again an offset table for all mesh indices
 251.434 +	if (dest->mNumMeshes)
 251.435 +	{
 251.436 +		aiMesh** pip = dest->mMeshes = new aiMesh*[dest->mNumMeshes];
 251.437 +		cnt = 0;
 251.438 +		for ( unsigned int n = 0; n < src.size();++n )
 251.439 +		{
 251.440 +			SceneHelper* cur = &src[n];
 251.441 +			for (unsigned int i = 0; i < (*cur)->mNumMeshes;++i)
 251.442 +			{
 251.443 +				if (n != duplicates[n])	{
 251.444 +					if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
 251.445 +						Copy(pip, (*cur)->mMeshes[i]);
 251.446 +
 251.447 +					else continue;
 251.448 +				}
 251.449 +				else *pip = (*cur)->mMeshes[i];
 251.450 +
 251.451 +				// update the material index of the mesh
 251.452 +				(*pip)->mMaterialIndex +=  offset[n];
 251.453 +				++pip;
 251.454 +			}
 251.455 +
 251.456 +			// reuse the offset array - store now the mesh offset in it
 251.457 +			offset[n] = cnt;
 251.458 +			cnt = (unsigned int)(pip - dest->mMeshes);
 251.459 +		}
 251.460 +	}
 251.461 +
 251.462 +	std::vector <NodeAttachmentInfo> nodes;
 251.463 +	nodes.reserve(srcList.size());
 251.464 +
 251.465 +	// ----------------------------------------------------------------------------
 251.466 +	// Now generate the output node graph. We need to make those
 251.467 +	// names in the graph that are referenced by anims or lights
 251.468 +	// or cameras unique. So we add a prefix to them ... $<rand>_
 251.469 +	// We could also use a counter, but using a random value allows us to
 251.470 +	// use just one prefix if we are joining multiple scene hierarchies recursively.
 251.471 +	// Chances are quite good we don't collide, so we try that ...
 251.472 +	// ----------------------------------------------------------------------------
 251.473 +
 251.474 +	// Allocate space for light sources, cameras and animations
 251.475 +	aiLight** ppLights = dest->mLights = (dest->mNumLights 
 251.476 +		? new aiLight*[dest->mNumLights] : NULL);
 251.477 +
 251.478 +	aiCamera** ppCameras = dest->mCameras = (dest->mNumCameras 
 251.479 +		? new aiCamera*[dest->mNumCameras] : NULL);
 251.480 +
 251.481 +	aiAnimation** ppAnims = dest->mAnimations = (dest->mNumAnimations 
 251.482 +		? new aiAnimation*[dest->mNumAnimations] : NULL);
 251.483 +
 251.484 +	for ( int n = src.size()-1; n >= 0 ;--n ) /* !!! important !!! */
 251.485 +	{
 251.486 +		SceneHelper* cur = &src[n];
 251.487 +		aiNode* node;
 251.488 +
 251.489 +		// To offset or not to offset, this is the question
 251.490 +		if (n != (int)duplicates[n])
 251.491 +		{
 251.492 +			// Get full scenegraph copy
 251.493 +			Copy( &node, (*cur)->mRootNode );
 251.494 +			OffsetNodeMeshIndices(node,offset[duplicates[n]]);
 251.495 +
 251.496 +			if (flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)	{
 251.497 +				// (note:) they are already 'offseted' by offset[duplicates[n]] 
 251.498 +				OffsetNodeMeshIndices(node,offset[n] - offset[duplicates[n]]);
 251.499 +			}
 251.500 +		}
 251.501 +		else // if (n == duplicates[n])
 251.502 +		{
 251.503 +			node = (*cur)->mRootNode;
 251.504 +			OffsetNodeMeshIndices(node,offset[n]);
 251.505 +		}
 251.506 +		if (n) // src[0] is the master node
 251.507 +			nodes.push_back(NodeAttachmentInfo( node,srcList[n-1].attachToNode,n ));
 251.508 +
 251.509 +		// add name prefixes?
 251.510 +		if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
 251.511 +
 251.512 +			// or the whole scenegraph
 251.513 +			if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
 251.514 +				AddNodePrefixesChecked(node,(*cur).id,(*cur).idlen,src,n);
 251.515 +			}
 251.516 +			else AddNodePrefixes(node,(*cur).id,(*cur).idlen);
 251.517 +
 251.518 +			// meshes
 251.519 +			for (unsigned int i = 0; i < (*cur)->mNumMeshes;++i)	{
 251.520 +				aiMesh* mesh = (*cur)->mMeshes[i]; 
 251.521 +
 251.522 +				// rename all bones
 251.523 +				for (unsigned int a = 0; a < mesh->mNumBones;++a)	{
 251.524 +					if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
 251.525 +						if (!FindNameMatch(mesh->mBones[a]->mName,src,n))
 251.526 +							continue;
 251.527 +					}
 251.528 +					PrefixString(mesh->mBones[a]->mName,(*cur).id,(*cur).idlen);
 251.529 +				}
 251.530 +			}
 251.531 +		}
 251.532 +
 251.533 +		// --------------------------------------------------------------------
 251.534 +		// Copy light sources
 251.535 +		for (unsigned int i = 0; i < (*cur)->mNumLights;++i,++ppLights)
 251.536 +		{
 251.537 +			if (n != (int)duplicates[n]) // duplicate scene? 
 251.538 +			{
 251.539 +				Copy(ppLights, (*cur)->mLights[i]);
 251.540 +			}
 251.541 +			else *ppLights = (*cur)->mLights[i];
 251.542 +
 251.543 +
 251.544 +			// Add name prefixes?
 251.545 +			if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
 251.546 +				if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
 251.547 +					if (!FindNameMatch((*ppLights)->mName,src,n))
 251.548 +						continue;
 251.549 +				}
 251.550 +
 251.551 +				PrefixString((*ppLights)->mName,(*cur).id,(*cur).idlen);
 251.552 +			}
 251.553 +		}
 251.554 +
 251.555 +		// --------------------------------------------------------------------
 251.556 +		// Copy cameras
 251.557 +		for (unsigned int i = 0; i < (*cur)->mNumCameras;++i,++ppCameras)	{
 251.558 +			if (n != (int)duplicates[n]) // duplicate scene? 
 251.559 +			{
 251.560 +				Copy(ppCameras, (*cur)->mCameras[i]);
 251.561 +			}
 251.562 +			else *ppCameras = (*cur)->mCameras[i];
 251.563 +
 251.564 +			// Add name prefixes?
 251.565 +			if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
 251.566 +				if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
 251.567 +					if (!FindNameMatch((*ppCameras)->mName,src,n))
 251.568 +						continue;
 251.569 +				}
 251.570 +
 251.571 +				PrefixString((*ppCameras)->mName,(*cur).id,(*cur).idlen);
 251.572 +			}
 251.573 +		}
 251.574 +
 251.575 +		// --------------------------------------------------------------------
 251.576 +		// Copy animations
 251.577 +		for (unsigned int i = 0; i < (*cur)->mNumAnimations;++i,++ppAnims)	{
 251.578 +			if (n != (int)duplicates[n]) // duplicate scene? 
 251.579 +			{
 251.580 +				Copy(ppAnims, (*cur)->mAnimations[i]);
 251.581 +			}
 251.582 +			else *ppAnims = (*cur)->mAnimations[i];
 251.583 +
 251.584 +			// Add name prefixes?
 251.585 +			if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
 251.586 +				if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
 251.587 +					if (!FindNameMatch((*ppAnims)->mName,src,n))
 251.588 +						continue;
 251.589 +				}
 251.590 +
 251.591 +				PrefixString((*ppAnims)->mName,(*cur).id,(*cur).idlen);
 251.592 +
 251.593 +				// don't forget to update all node animation channels
 251.594 +				for (unsigned int a = 0; a < (*ppAnims)->mNumChannels;++a) {
 251.595 +					if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
 251.596 +						if (!FindNameMatch((*ppAnims)->mChannels[a]->mNodeName,src,n))
 251.597 +							continue;
 251.598 +					}
 251.599 +
 251.600 +					PrefixString((*ppAnims)->mChannels[a]->mNodeName,(*cur).id,(*cur).idlen);
 251.601 +				}
 251.602 +			}
 251.603 +		}
 251.604 +	}
 251.605 +
 251.606 +	// Now build the output graph
 251.607 +	AttachToGraph ( master, nodes);
 251.608 +	dest->mRootNode = master->mRootNode;
 251.609 +
 251.610 +	// Check whether we succeeded at building the output graph
 251.611 +	for (std::vector <NodeAttachmentInfo> ::iterator it = nodes.begin(); 
 251.612 +		it != nodes.end(); ++it)
 251.613 +	{
 251.614 +		if (!(*it).resolved) {
 251.615 +			if (flags & AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS) {
 251.616 +				// search for this attachment point in all other imported scenes, too.
 251.617 +				for ( unsigned int n = 0; n < src.size();++n ) {
 251.618 +					if (n != (*it).src_idx) {
 251.619 +						AttachToGraph(src[n].scene,nodes);
 251.620 +						if ((*it).resolved)
 251.621 +							break;
 251.622 +					}
 251.623 +				}
 251.624 +			}
 251.625 +			if (!(*it).resolved) {
 251.626 +				DefaultLogger::get()->error(std::string("SceneCombiner: Failed to resolve attachment ") 
 251.627 +					+ (*it).node->mName.data + " " + (*it).attachToNode->mName.data);
 251.628 +			}
 251.629 +		}
 251.630 +	}
 251.631 +
 251.632 +	// now delete all input scenes. Make sure duplicate scenes aren't
 251.633 +	// deleted more than one time
 251.634 +	for ( unsigned int n = 0; n < src.size();++n )	{
 251.635 +		if (n != duplicates[n]) // duplicate scene?
 251.636 +			continue;
 251.637 +
 251.638 +		aiScene* deleteMe = src[n].scene;
 251.639 +
 251.640 +		// We need to delete the arrays before the destructor is called -
 251.641 +		// we are reusing the array members
 251.642 +		delete[] deleteMe->mMeshes;     deleteMe->mMeshes     = NULL;
 251.643 +		delete[] deleteMe->mCameras;    deleteMe->mCameras    = NULL;
 251.644 +		delete[] deleteMe->mLights;     deleteMe->mLights     = NULL;
 251.645 +		delete[] deleteMe->mMaterials;  deleteMe->mMaterials  = NULL;
 251.646 +		delete[] deleteMe->mAnimations; deleteMe->mAnimations = NULL;
 251.647 +
 251.648 +		deleteMe->mRootNode = NULL;
 251.649 +
 251.650 +		// Now we can safely delete the scene
 251.651 +		delete deleteMe;
 251.652 +	}
 251.653 +
 251.654 +	// Check flags
 251.655 +	if (!dest->mNumMeshes || !dest->mNumMaterials) {
 251.656 +		dest->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
 251.657 +	}
 251.658 +
 251.659 +	// We're finished
 251.660 +}
 251.661 +
 251.662 +// ------------------------------------------------------------------------------------------------
 251.663 +// Build a list of unique bones
 251.664 +void SceneCombiner::BuildUniqueBoneList(std::list<BoneWithHash>& asBones,
 251.665 +	std::vector<aiMesh*>::const_iterator it,
 251.666 +	std::vector<aiMesh*>::const_iterator end)
 251.667 +{
 251.668 +	unsigned int iOffset = 0;
 251.669 +	for (; it != end;++it)	{
 251.670 +		for (unsigned int l = 0; l < (*it)->mNumBones;++l)	{
 251.671 +			aiBone* p = (*it)->mBones[l];
 251.672 +			uint32_t itml = SuperFastHash(p->mName.data,(unsigned int)p->mName.length);
 251.673 +
 251.674 +			std::list<BoneWithHash>::iterator it2  = asBones.begin();
 251.675 +			std::list<BoneWithHash>::iterator end2 = asBones.end();
 251.676 +
 251.677 +			for (;it2 != end2;++it2)	{
 251.678 +				if ((*it2).first == itml)	{
 251.679 +					(*it2).pSrcBones.push_back(BoneSrcIndex(p,iOffset));
 251.680 +					break;
 251.681 +				}
 251.682 +			}
 251.683 +			if (end2 == it2)	{
 251.684 +				// need to begin a new bone entry
 251.685 +				asBones.push_back(BoneWithHash());
 251.686 +				BoneWithHash& btz = asBones.back();
 251.687 +
 251.688 +				// setup members
 251.689 +				btz.first = itml;
 251.690 +				btz.second = &p->mName;
 251.691 +				btz.pSrcBones.push_back(BoneSrcIndex(p,iOffset));
 251.692 +			}
 251.693 +		}
 251.694 +		iOffset += (*it)->mNumVertices;
 251.695 +	}
 251.696 +}
 251.697 +
 251.698 +// ------------------------------------------------------------------------------------------------
 251.699 +// Merge a list of bones
 251.700 +void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it,
 251.701 +	std::vector<aiMesh*>::const_iterator end)
 251.702 +{
 251.703 +	ai_assert(NULL != out && !out->mNumBones);
 251.704 +
 251.705 +	// find we need to build an unique list of all bones.
 251.706 +	// we work with hashes to make the comparisons MUCH faster,
 251.707 +	// at least if we have many bones.
 251.708 +	std::list<BoneWithHash> asBones;
 251.709 +	BuildUniqueBoneList(asBones, it,end);
 251.710 +	
 251.711 +	// now create the output bones
 251.712 +	out->mNumBones = 0;
 251.713 +	out->mBones = new aiBone*[asBones.size()];
 251.714 +
 251.715 +	for (std::list<BoneWithHash>::const_iterator it = asBones.begin(),end = asBones.end(); it != end;++it)	{
 251.716 +		// Allocate a bone and setup it's name
 251.717 +		aiBone* pc = out->mBones[out->mNumBones++] = new aiBone();
 251.718 +		pc->mName = aiString( *((*it).second ));
 251.719 +
 251.720 +		std::vector< BoneSrcIndex >::const_iterator wend = (*it).pSrcBones.end();
 251.721 +
 251.722 +		// Loop through all bones to be joined for this bone
 251.723 +		for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit)	{
 251.724 +			pc->mNumWeights += (*wmit).first->mNumWeights;
 251.725 +
 251.726 +			// NOTE: different offset matrices for bones with equal names
 251.727 +			// are - at the moment - not handled correctly. 
 251.728 +			if (wmit != (*it).pSrcBones.begin() && pc->mOffsetMatrix != (*wmit).first->mOffsetMatrix)	{
 251.729 +				DefaultLogger::get()->warn("Bones with equal names but different offset matrices can't be joined at the moment");
 251.730 +				continue;
 251.731 +			}
 251.732 +			pc->mOffsetMatrix = (*wmit).first->mOffsetMatrix;
 251.733 +		}
 251.734 +
 251.735 +		// Allocate the vertex weight array
 251.736 +		aiVertexWeight* avw = pc->mWeights = new aiVertexWeight[pc->mNumWeights];
 251.737 +
 251.738 +		// And copy the final weights - adjust the vertex IDs by the 
 251.739 +		// face index offset of the coresponding mesh.
 251.740 +		for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit)	{
 251.741 +			aiBone* pip = (*wmit).first;
 251.742 +			for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw)	{
 251.743 +				const aiVertexWeight& vfi = pip->mWeights[mp];
 251.744 +				avw->mWeight = vfi.mWeight;
 251.745 +				avw->mVertexId = vfi.mVertexId + (*wmit).second;
 251.746 +			}
 251.747 +		}
 251.748 +	}
 251.749 +}
 251.750 +
 251.751 +// ------------------------------------------------------------------------------------------------
 251.752 +// Merge a list of meshes
 251.753 +void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
 251.754 +	std::vector<aiMesh*>::const_iterator begin,
 251.755 +	std::vector<aiMesh*>::const_iterator end)
 251.756 +{
 251.757 +	ai_assert(NULL != _out);
 251.758 +
 251.759 +	if (begin == end)	{
 251.760 +		*_out = NULL; // no meshes ...
 251.761 +		return;
 251.762 +	}
 251.763 +
 251.764 +	// Allocate the output mesh
 251.765 +	aiMesh* out = *_out = new aiMesh();
 251.766 +	out->mMaterialIndex = (*begin)->mMaterialIndex;
 251.767 +
 251.768 +	// Find out how much output storage we'll need
 251.769 +	for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it)	{
 251.770 +		out->mNumVertices	+= (*it)->mNumVertices;
 251.771 +		out->mNumFaces		+= (*it)->mNumFaces;
 251.772 +		out->mNumBones		+= (*it)->mNumBones;
 251.773 +
 251.774 +		// combine primitive type flags
 251.775 +		out->mPrimitiveTypes |= (*it)->mPrimitiveTypes;
 251.776 +	}
 251.777 +
 251.778 +	if (out->mNumVertices) {
 251.779 +		aiVector3D* pv2;
 251.780 +
 251.781 +		// copy vertex positions
 251.782 +		if ((**begin).HasPositions())	{
 251.783 +
 251.784 +			pv2 = out->mVertices = new aiVector3D[out->mNumVertices];
 251.785 +			for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it)	{
 251.786 +				if ((*it)->mVertices)	{
 251.787 +					::memcpy(pv2,(*it)->mVertices,(*it)->mNumVertices*sizeof(aiVector3D));
 251.788 +				}
 251.789 +				else DefaultLogger::get()->warn("JoinMeshes: Positions expected but input mesh contains no positions");
 251.790 +				pv2 += (*it)->mNumVertices;
 251.791 +			}
 251.792 +		}
 251.793 +		// copy normals
 251.794 +		if ((**begin).HasNormals())	{
 251.795 +
 251.796 +			pv2 = out->mNormals = new aiVector3D[out->mNumVertices];
 251.797 +			for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it)	{
 251.798 +				if ((*it)->mNormals)	{
 251.799 +					::memcpy(pv2,(*it)->mNormals,(*it)->mNumVertices*sizeof(aiVector3D));
 251.800 +				}
 251.801 +				else DefaultLogger::get()->warn("JoinMeshes: Normals expected but input mesh contains no normals");
 251.802 +				pv2 += (*it)->mNumVertices;
 251.803 +			}
 251.804 +		}
 251.805 +		// copy tangents and bitangents
 251.806 +		if ((**begin).HasTangentsAndBitangents())	{
 251.807 +
 251.808 +			pv2 = out->mTangents = new aiVector3D[out->mNumVertices];
 251.809 +			aiVector3D* pv2b = out->mBitangents = new aiVector3D[out->mNumVertices];
 251.810 +
 251.811 +			for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it)	{
 251.812 +				if ((*it)->mTangents)	{
 251.813 +					::memcpy(pv2, (*it)->mTangents,	 (*it)->mNumVertices*sizeof(aiVector3D));
 251.814 +					::memcpy(pv2b,(*it)->mBitangents,(*it)->mNumVertices*sizeof(aiVector3D));
 251.815 +				}
 251.816 +				else DefaultLogger::get()->warn("JoinMeshes: Tangents expected but input mesh contains no tangents");
 251.817 +				pv2  += (*it)->mNumVertices;
 251.818 +				pv2b += (*it)->mNumVertices;
 251.819 +			}
 251.820 +		}
 251.821 +		// copy texture coordinates
 251.822 +		unsigned int n = 0;
 251.823 +		while ((**begin).HasTextureCoords(n))	{
 251.824 +			out->mNumUVComponents[n] = (*begin)->mNumUVComponents[n];
 251.825 +
 251.826 +			pv2 = out->mTextureCoords[n] = new aiVector3D[out->mNumVertices];
 251.827 +			for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it)	{
 251.828 +
 251.829 +				if ((*it)->mTextureCoords[n])	{
 251.830 +					::memcpy(pv2,(*it)->mTextureCoords[n],(*it)->mNumVertices*sizeof(aiVector3D));
 251.831 +				}
 251.832 +				else DefaultLogger::get()->warn("JoinMeshes: UVs expected but input mesh contains no UVs");
 251.833 +				pv2 += (*it)->mNumVertices;
 251.834 +			}
 251.835 +			++n;
 251.836 +		}
 251.837 +		// copy vertex colors
 251.838 +		n = 0;
 251.839 +		while ((**begin).HasVertexColors(n))	{
 251.840 +			aiColor4D* pv2 = out->mColors[n] = new aiColor4D[out->mNumVertices];
 251.841 +			for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it)	{
 251.842 +
 251.843 +				if ((*it)->mColors[n])	{
 251.844 +					::memcpy(pv2,(*it)->mColors[n],(*it)->mNumVertices*sizeof(aiColor4D));
 251.845 +				}
 251.846 +				else DefaultLogger::get()->warn("JoinMeshes: VCs expected but input mesh contains no VCs");
 251.847 +				pv2 += (*it)->mNumVertices;
 251.848 +			}
 251.849 +			++n;
 251.850 +		}
 251.851 +	}
 251.852 +
 251.853 +	if (out->mNumFaces) // just for safety
 251.854 +	{
 251.855 +		// copy faces
 251.856 +		out->mFaces = new aiFace[out->mNumFaces];
 251.857 +		aiFace* pf2 = out->mFaces;
 251.858 +
 251.859 +		unsigned int ofs = 0;
 251.860 +		for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it)	{
 251.861 +			for (unsigned int m = 0; m < (*it)->mNumFaces;++m,++pf2)	{
 251.862 +				aiFace& face = (*it)->mFaces[m];
 251.863 +				pf2->mNumIndices = face.mNumIndices;
 251.864 +				pf2->mIndices = face.mIndices;
 251.865 +
 251.866 +				if (ofs)	{
 251.867 +					// add the offset to the vertex
 251.868 +					for (unsigned int q = 0; q < face.mNumIndices; ++q)
 251.869 +						face.mIndices[q] += ofs;	
 251.870 +				}
 251.871 +				face.mIndices = NULL;
 251.872 +			}
 251.873 +			ofs += (*it)->mNumVertices;
 251.874 +		}
 251.875 +	}
 251.876 +
 251.877 +	// bones - as this is quite lengthy, I moved the code to a separate function
 251.878 +	if (out->mNumBones)
 251.879 +		MergeBones(out,begin,end);
 251.880 +
 251.881 +	// delete all source meshes
 251.882 +	for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it)
 251.883 +		delete *it;
 251.884 +}
 251.885 +
 251.886 +// ------------------------------------------------------------------------------------------------
 251.887 +template <typename Type>
 251.888 +inline void CopyPtrArray (Type**& dest, const Type* const * src, unsigned int num)
 251.889 +{
 251.890 +	if (!num)
 251.891 +	{
 251.892 +		dest = NULL;
 251.893 +		return;
 251.894 +	}
 251.895 +	dest = new Type*[num];
 251.896 +	for (unsigned int i = 0; i < num;++i) {
 251.897 +		SceneCombiner::Copy(&dest[i],src[i]);
 251.898 +	}
 251.899 +}
 251.900 +
 251.901 +// ------------------------------------------------------------------------------------------------
 251.902 +template <typename Type>
 251.903 +inline void GetArrayCopy (Type*& dest, unsigned int num )
 251.904 +{
 251.905 +	if (!dest)return;
 251.906 +	Type* old = dest;
 251.907 +
 251.908 +	dest = new Type[num];
 251.909 +	::memcpy(dest, old, sizeof(Type) * num);
 251.910 +}
 251.911 +
 251.912 +// ------------------------------------------------------------------------------------------------
 251.913 +void SceneCombiner::CopySceneFlat(aiScene** _dest,const aiScene* src)
 251.914 +{
 251.915 +	// reuse the old scene or allocate a new?
 251.916 +	if (*_dest) {
 251.917 +		(*_dest)->~aiScene();
 251.918 +		new (*_dest) aiScene();
 251.919 +	}
 251.920 +	else *_dest = new aiScene();
 251.921 +
 251.922 +	::memcpy(*_dest,src,sizeof(aiScene));
 251.923 +}
 251.924 +
 251.925 +// ------------------------------------------------------------------------------------------------
 251.926 +void SceneCombiner::CopyScene(aiScene** _dest,const aiScene* src,bool allocate)
 251.927 +{
 251.928 +	ai_assert(NULL != _dest && NULL != src);
 251.929 +
 251.930 +	if (allocate) {
 251.931 +		*_dest = new aiScene();
 251.932 +	}
 251.933 +	aiScene* dest = *_dest; 
 251.934 +	ai_assert(dest);
 251.935 +
 251.936 +	// copy animations
 251.937 +	dest->mNumAnimations = src->mNumAnimations;
 251.938 +	CopyPtrArray(dest->mAnimations,src->mAnimations,
 251.939 +		dest->mNumAnimations);
 251.940 +
 251.941 +	// copy textures
 251.942 +	dest->mNumTextures = src->mNumTextures;
 251.943 +	CopyPtrArray(dest->mTextures,src->mTextures,
 251.944 +		dest->mNumTextures);
 251.945 +
 251.946 +	// copy materials
 251.947 +	dest->mNumMaterials = src->mNumMaterials;
 251.948 +	CopyPtrArray(dest->mMaterials,src->mMaterials,
 251.949 +		dest->mNumMaterials);
 251.950 +
 251.951 +	// copy lights
 251.952 +	dest->mNumLights = src->mNumLights;
 251.953 +	CopyPtrArray(dest->mLights,src->mLights,
 251.954 +		dest->mNumLights);
 251.955 +
 251.956 +	// copy cameras
 251.957 +	dest->mNumCameras = src->mNumCameras;
 251.958 +	CopyPtrArray(dest->mCameras,src->mCameras,
 251.959 +		dest->mNumCameras);
 251.960 +
 251.961 +	// copy meshes
 251.962 +	dest->mNumMeshes = src->mNumMeshes;
 251.963 +	CopyPtrArray(dest->mMeshes,src->mMeshes,
 251.964 +		dest->mNumMeshes);
 251.965 +
 251.966 +	// now - copy the root node of the scene (deep copy, too)
 251.967 +	Copy( &dest->mRootNode, src->mRootNode);
 251.968 +
 251.969 +	// and keep the flags ...
 251.970 +	dest->mFlags = src->mFlags;
 251.971 +
 251.972 +	// source private data might be NULL if the scene is user-allocated (i.e. for use with the export API)
 251.973 +	ScenePriv(dest)->mPPStepsApplied = ScenePriv(src) ? ScenePriv(src)->mPPStepsApplied : 0;
 251.974 +}
 251.975 +
 251.976 +// ------------------------------------------------------------------------------------------------
 251.977 +void SceneCombiner::Copy     (aiMesh** _dest, const aiMesh* src)
 251.978 +{
 251.979 +	ai_assert(NULL != _dest && NULL != src);
 251.980 +
 251.981 +	aiMesh* dest = *_dest = new aiMesh();
 251.982 +
 251.983 +	// get a flat copy
 251.984 +	::memcpy(dest,src,sizeof(aiMesh));
 251.985 +
 251.986 +	// and reallocate all arrays
 251.987 +	GetArrayCopy( dest->mVertices,   dest->mNumVertices );
 251.988 +	GetArrayCopy( dest->mNormals ,   dest->mNumVertices );
 251.989 +	GetArrayCopy( dest->mTangents,   dest->mNumVertices );
 251.990 +	GetArrayCopy( dest->mBitangents, dest->mNumVertices );
 251.991 +
 251.992 +	unsigned int n = 0;
 251.993 +	while (dest->HasTextureCoords(n))
 251.994 +		GetArrayCopy( dest->mTextureCoords[n++],   dest->mNumVertices );
 251.995 +
 251.996 +	n = 0;
 251.997 +	while (dest->HasVertexColors(n))
 251.998 +		GetArrayCopy( dest->mColors[n++],   dest->mNumVertices );
 251.999 +
251.1000 +	// make a deep copy of all bones
251.1001 +	CopyPtrArray(dest->mBones,dest->mBones,dest->mNumBones);
251.1002 +
251.1003 +	// make a deep copy of all faces
251.1004 +	GetArrayCopy(dest->mFaces,dest->mNumFaces);
251.1005 +	for (unsigned int i = 0; i < dest->mNumFaces;++i)
251.1006 +	{
251.1007 +		aiFace& f = dest->mFaces[i];
251.1008 +		GetArrayCopy(f.mIndices,f.mNumIndices);
251.1009 +	}
251.1010 +}
251.1011 +
251.1012 +// ------------------------------------------------------------------------------------------------
251.1013 +void SceneCombiner::Copy (aiMaterial** _dest, const aiMaterial* src)
251.1014 +{
251.1015 +	ai_assert(NULL != _dest && NULL != src);
251.1016 +
251.1017 +	aiMaterial* dest = (aiMaterial*) ( *_dest = new aiMaterial() );
251.1018 +	dest->mNumAllocated  =  src->mNumAllocated;
251.1019 +	dest->mNumProperties =  src->mNumProperties;
251.1020 +	dest->mProperties    =  new aiMaterialProperty* [dest->mNumAllocated];
251.1021 +
251.1022 +	for (unsigned int i = 0; i < dest->mNumProperties;++i)
251.1023 +	{
251.1024 +		aiMaterialProperty* prop  = dest->mProperties[i] = new aiMaterialProperty();
251.1025 +		aiMaterialProperty* sprop = src->mProperties[i];
251.1026 +
251.1027 +		prop->mDataLength = sprop->mDataLength;
251.1028 +		prop->mData = new char[prop->mDataLength];
251.1029 +		::memcpy(prop->mData,sprop->mData,prop->mDataLength);
251.1030 +
251.1031 +		prop->mIndex    = sprop->mIndex;
251.1032 +		prop->mSemantic = sprop->mSemantic;
251.1033 +		prop->mKey      = sprop->mKey;
251.1034 +		prop->mType		= sprop->mType;
251.1035 +	}
251.1036 +}
251.1037 +	
251.1038 +// ------------------------------------------------------------------------------------------------
251.1039 +void SceneCombiner::Copy  (aiTexture** _dest, const aiTexture* src)
251.1040 +{
251.1041 +	ai_assert(NULL != _dest && NULL != src);
251.1042 +
251.1043 +	aiTexture* dest = *_dest = new aiTexture();
251.1044 +
251.1045 +	// get a flat copy
251.1046 +	::memcpy(dest,src,sizeof(aiTexture));
251.1047 +
251.1048 +	// and reallocate all arrays. We must do it manually here
251.1049 +	const char* old = (const char*)dest->pcData;
251.1050 +	if (old)
251.1051 +	{
251.1052 +		unsigned int cpy;
251.1053 +		if (!dest->mHeight)cpy = dest->mWidth;
251.1054 +		else cpy = dest->mHeight * dest->mWidth * sizeof(aiTexel);
251.1055 +
251.1056 +		if (!cpy)
251.1057 +		{
251.1058 +			dest->pcData = NULL;
251.1059 +			return;
251.1060 +		}
251.1061 +		// the cast is legal, the aiTexel c'tor does nothing important
251.1062 +		dest->pcData = (aiTexel*) new char[cpy];
251.1063 +		::memcpy(dest->pcData, old, cpy);
251.1064 +	}
251.1065 +}
251.1066 +	
251.1067 +// ------------------------------------------------------------------------------------------------
251.1068 +void SceneCombiner::Copy     (aiAnimation** _dest, const aiAnimation* src)
251.1069 +{
251.1070 +	ai_assert(NULL != _dest && NULL != src);
251.1071 +
251.1072 +	aiAnimation* dest = *_dest = new aiAnimation();
251.1073 +
251.1074 +	// get a flat copy
251.1075 +	::memcpy(dest,src,sizeof(aiAnimation));
251.1076 +
251.1077 +	// and reallocate all arrays
251.1078 +	CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels );
251.1079 +}
251.1080 +
251.1081 +// ------------------------------------------------------------------------------------------------
251.1082 +void SceneCombiner::Copy     (aiNodeAnim** _dest, const aiNodeAnim* src)
251.1083 +{
251.1084 +	ai_assert(NULL != _dest && NULL != src);
251.1085 +
251.1086 +	aiNodeAnim* dest = *_dest = new aiNodeAnim();
251.1087 +
251.1088 +	// get a flat copy
251.1089 +	::memcpy(dest,src,sizeof(aiNodeAnim));
251.1090 +
251.1091 +	// and reallocate all arrays
251.1092 +	GetArrayCopy( dest->mPositionKeys, dest->mNumPositionKeys );
251.1093 +	GetArrayCopy( dest->mScalingKeys,  dest->mNumScalingKeys );
251.1094 +	GetArrayCopy( dest->mRotationKeys, dest->mNumRotationKeys );
251.1095 +}
251.1096 +
251.1097 +// ------------------------------------------------------------------------------------------------
251.1098 +void SceneCombiner::Copy   (aiCamera** _dest,const  aiCamera* src)
251.1099 +{
251.1100 +	ai_assert(NULL != _dest && NULL != src);
251.1101 +
251.1102 +	aiCamera* dest = *_dest = new aiCamera();
251.1103 +
251.1104 +	// get a flat copy, that's already OK
251.1105 +	::memcpy(dest,src,sizeof(aiCamera));
251.1106 +}
251.1107 +
251.1108 +// ------------------------------------------------------------------------------------------------
251.1109 +void SceneCombiner::Copy   (aiLight** _dest, const aiLight* src)
251.1110 +{
251.1111 +	ai_assert(NULL != _dest && NULL != src);
251.1112 +
251.1113 +	aiLight* dest = *_dest = new aiLight();
251.1114 +
251.1115 +	// get a flat copy, that's already OK
251.1116 +	::memcpy(dest,src,sizeof(aiLight));
251.1117 +}
251.1118 +
251.1119 +// ------------------------------------------------------------------------------------------------
251.1120 +void SceneCombiner::Copy     (aiBone** _dest, const aiBone* src)
251.1121 +{
251.1122 +	ai_assert(NULL != _dest && NULL != src);
251.1123 +
251.1124 +	aiBone* dest = *_dest = new aiBone();
251.1125 +
251.1126 +	// get a flat copy
251.1127 +	::memcpy(dest,src,sizeof(aiBone));
251.1128 +
251.1129 +	// and reallocate all arrays
251.1130 +	GetArrayCopy( dest->mWeights, dest->mNumWeights );
251.1131 +}
251.1132 +
251.1133 +// ------------------------------------------------------------------------------------------------
251.1134 +void SceneCombiner::Copy     (aiNode** _dest, const aiNode* src)
251.1135 +{
251.1136 +	ai_assert(NULL != _dest && NULL != src);
251.1137 +
251.1138 +	aiNode* dest = *_dest = new aiNode();
251.1139 +
251.1140 +	// get a flat copy
251.1141 +	::memcpy(dest,src,sizeof(aiNode));
251.1142 +
251.1143 +	// and reallocate all arrays
251.1144 +	GetArrayCopy( dest->mMeshes, dest->mNumMeshes );
251.1145 +	CopyPtrArray( dest->mChildren, src->mChildren,dest->mNumChildren);
251.1146 +}
251.1147 +
251.1148 +
251.1149 +}
   252.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   252.2 +++ b/libs/assimp/SceneCombiner.h	Sat Feb 01 19:58:19 2014 +0200
   252.3 @@ -0,0 +1,365 @@
   252.4 +/*
   252.5 +Open Asset Import Library (assimp)
   252.6 +----------------------------------------------------------------------
   252.7 +
   252.8 +Copyright (c) 2006-2012, assimp team
   252.9 +All rights reserved.
  252.10 +
  252.11 +Redistribution and use of this software in source and binary forms, 
  252.12 +with or without modification, are permitted provided that the 
  252.13 +following conditions are met:
  252.14 +
  252.15 +* Redistributions of source code must retain the above
  252.16 +  copyright notice, this list of conditions and the
  252.17 +  following disclaimer.
  252.18 +
  252.19 +* Redistributions in binary form must reproduce the above
  252.20 +  copyright notice, this list of conditions and the
  252.21 +  following disclaimer in the documentation and/or other
  252.22 +  materials provided with the distribution.
  252.23 +
  252.24 +* Neither the name of the assimp team, nor the names of its
  252.25 +  contributors may be used to endorse or promote products
  252.26 +  derived from this software without specific prior
  252.27 +  written permission of the assimp team.
  252.28 +
  252.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  252.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  252.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  252.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  252.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  252.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  252.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  252.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  252.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  252.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  252.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  252.40 +
  252.41 +----------------------------------------------------------------------
  252.42 +*/
  252.43 +
  252.44 +/** @file Declares a helper class, "SceneCombiner" providing various
  252.45 + *  utilities to merge scenes.
  252.46 + */
  252.47 +#ifndef AI_SCENE_COMBINER_H_INC
  252.48 +#define AI_SCENE_COMBINER_H_INC
  252.49 +
  252.50 +#include "assimp/ai_assert.h"
  252.51 +
  252.52 +namespace Assimp	{
  252.53 +
  252.54 +// ---------------------------------------------------------------------------
  252.55 +/** \brief Helper data structure for SceneCombiner.
  252.56 + *
  252.57 + *  Describes to which node a scene must be attached to.
  252.58 + */
  252.59 +struct AttachmentInfo
  252.60 +{
  252.61 +	AttachmentInfo()
  252.62 +		:	scene			(NULL)
  252.63 +		,	attachToNode	(NULL)
  252.64 +	{}
  252.65 +
  252.66 +	AttachmentInfo(aiScene* _scene, aiNode* _attachToNode)
  252.67 +		:	scene			(_scene)
  252.68 +		,	attachToNode	(_attachToNode)
  252.69 +	{}
  252.70 +
  252.71 +	aiScene* scene;
  252.72 +	aiNode*  attachToNode;
  252.73 +};
  252.74 +
  252.75 +// ---------------------------------------------------------------------------
  252.76 +struct NodeAttachmentInfo
  252.77 +{
  252.78 +	NodeAttachmentInfo()
  252.79 +		:	node			(NULL)
  252.80 +		,	attachToNode	(NULL)
  252.81 +		,	resolved		(false)
  252.82 +		,	src_idx			(SIZE_MAX)
  252.83 +	{}
  252.84 +
  252.85 +	NodeAttachmentInfo(aiNode* _scene, aiNode* _attachToNode,size_t idx)
  252.86 +		:	node			(_scene)
  252.87 +		,	attachToNode	(_attachToNode)
  252.88 +		,	resolved		(false)
  252.89 +		,	src_idx			(idx)
  252.90 +	{}
  252.91 +
  252.92 +	aiNode*  node;
  252.93 +	aiNode*  attachToNode;
  252.94 +	bool     resolved;
  252.95 +	size_t   src_idx;
  252.96 +};
  252.97 +
  252.98 +// ---------------------------------------------------------------------------
  252.99 +/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES
 252.100 + *  Generate unique names for all named scene items
 252.101 + */
 252.102 +#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES      0x1
 252.103 +
 252.104 +/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES
 252.105 + *  Generate unique names for materials, too. 
 252.106 + *  This is not absolutely required to pass the validation.
 252.107 + */
 252.108 +#define AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES   0x2
 252.109 +
 252.110 +/** @def AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY
 252.111 + * Use deep copies of duplicate scenes
 252.112 + */
 252.113 +#define AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY   0x4
 252.114 +
 252.115 +/** @def AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS
 252.116 + * If attachment nodes are not found in the given master scene,
 252.117 + * search the other imported scenes for them in an any order.
 252.118 + */
 252.119 +#define AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS 0x8
 252.120 +
 252.121 +/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY
 252.122 + * Can be combined with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES.
 252.123 + * Unique names are generated, but only if this is absolutely
 252.124 + * required to avoid name conflicts.
 252.125 + */
 252.126 +#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10
 252.127 +
 252.128 +
 252.129 +typedef std::pair<aiBone*,unsigned int> BoneSrcIndex;
 252.130 +
 252.131 +// ---------------------------------------------------------------------------
 252.132 +/** @brief Helper data structure for SceneCombiner::MergeBones.
 252.133 + */
 252.134 +struct BoneWithHash : public std::pair<uint32_t,aiString*>	{
 252.135 +	std::vector<BoneSrcIndex> pSrcBones;
 252.136 +};
 252.137 +
 252.138 +
 252.139 +// ---------------------------------------------------------------------------
 252.140 +/** @brief Utility for SceneCombiner
 252.141 + */
 252.142 +struct SceneHelper
 252.143 +{
 252.144 +	SceneHelper ()
 252.145 +		: scene		(NULL)
 252.146 +		, idlen		(0)
 252.147 +	{
 252.148 +		id[0] = 0;
 252.149 +	}
 252.150 +
 252.151 +	SceneHelper (aiScene* _scene)
 252.152 +		: scene		(_scene)
 252.153 +		, idlen		(0)
 252.154 +	{
 252.155 +		id[0] = 0;
 252.156 +	}
 252.157 +
 252.158 +	AI_FORCE_INLINE aiScene* operator-> () const
 252.159 +	{
 252.160 +		return scene;
 252.161 +	}
 252.162 +
 252.163 +	// scene we're working on
 252.164 +	aiScene* scene;
 252.165 +
 252.166 +	// prefix to be added to all identifiers in the scene ...
 252.167 +	char id [32];
 252.168 +
 252.169 +	// and its strlen() 
 252.170 +	unsigned int idlen;
 252.171 +
 252.172 +	// hash table to quickly check whether a name is contained in the scene
 252.173 +	std::set<unsigned int> hashes;
 252.174 +};
 252.175 +
 252.176 +// ---------------------------------------------------------------------------
 252.177 +/** \brief Static helper class providing various utilities to merge two
 252.178 + *    scenes. It is intended as internal utility and NOT for use by 
 252.179 + *    applications.
 252.180 + * 
 252.181 + * The class is currently being used by various postprocessing steps
 252.182 + * and loaders (ie. LWS).
 252.183 + */
 252.184 +class SceneCombiner
 252.185 +{
 252.186 +	// class cannot be instanced
 252.187 +	SceneCombiner() {}
 252.188 +
 252.189 +public:
 252.190 +
 252.191 +	// -------------------------------------------------------------------
 252.192 +	/** Merges two or more scenes.
 252.193 +	 *
 252.194 +	 *  @param dest  Receives a pointer to the destination scene. If the
 252.195 +	 *    pointer doesn't point to NULL when the function is called, the
 252.196 +	 *    existing scene is cleared and refilled.
 252.197 +	 *  @param src Non-empty list of scenes to be merged. The function
 252.198 +	 *    deletes the input scenes afterwards. There may be duplicate scenes.
 252.199 +	 *  @param flags Combination of the AI_INT_MERGE_SCENE flags defined above
 252.200 +	 */
 252.201 +	static void MergeScenes(aiScene** dest,std::vector<aiScene*>& src,
 252.202 +		unsigned int flags = 0);
 252.203 +
 252.204 +
 252.205 +	// -------------------------------------------------------------------
 252.206 +	/** Merges two or more scenes and attaches all sceenes to a specific
 252.207 +	 *  position in the node graph of the masteer scene.
 252.208 +	 *
 252.209 +	 *  @param dest Receives a pointer to the destination scene. If the
 252.210 +	 *    pointer doesn't point to NULL when the function is called, the
 252.211 +	 *    existing scene is cleared and refilled.
 252.212 +	 *  @param master Master scene. It will be deleted afterwards. All 
 252.213 +	 *    other scenes will be inserted in its node graph.
 252.214 +	 *  @param src Non-empty list of scenes to be merged along with their
 252.215 +	 *    corresponding attachment points in the master scene. The function
 252.216 +	 *    deletes the input scenes afterwards. There may be duplicate scenes.
 252.217 +	 *  @param flags Combination of the AI_INT_MERGE_SCENE flags defined above
 252.218 +	 */
 252.219 +	static void MergeScenes(aiScene** dest, aiScene* master, 
 252.220 +		std::vector<AttachmentInfo>& src,
 252.221 +		unsigned int flags = 0);
 252.222 +
 252.223 +
 252.224 +	// -------------------------------------------------------------------
 252.225 +	/** Merges two or more meshes
 252.226 +	 *
 252.227 +	 *  The meshes should have equal vertex formats. Only components
 252.228 +	 *  that are provided by ALL meshes will be present in the output mesh.
 252.229 +	 *  An exception is made for VColors - they are set to black. The 
 252.230 +	 *  meshes should have the same material indices, too. The output
 252.231 +	 *  material index is always the material index of the first mesh.
 252.232 +	 *
 252.233 +	 *  @param dest Destination mesh. Must be empty.
 252.234 +	 *  @param flags Currently no parameters
 252.235 +	 *  @param begin First mesh to be processed
 252.236 +	 *  @param end Points to the mesh after the last mesh to be processed
 252.237 +	 */
 252.238 +	static void MergeMeshes(aiMesh** dest,unsigned int flags,
 252.239 +		std::vector<aiMesh*>::const_iterator begin,
 252.240 +		std::vector<aiMesh*>::const_iterator end);
 252.241 +
 252.242 +
 252.243 +	// -------------------------------------------------------------------
 252.244 +	/** Merges two or more bones
 252.245 +	 *
 252.246 +	 *  @param out Mesh to receive the output bone list
 252.247 +	 *  @param flags Currently no parameters
 252.248 +	 *  @param begin First mesh to be processed
 252.249 +	 *  @param end Points to the mesh after the last mesh to be processed
 252.250 +	 */
 252.251 +	static void MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it,
 252.252 +		std::vector<aiMesh*>::const_iterator end);
 252.253 +
 252.254 +
 252.255 +	// -------------------------------------------------------------------
 252.256 +	/** Builds a list of uniquely named bones in a mesh list
 252.257 +	 *
 252.258 +	 *  @param asBones Receives the output list
 252.259 +	 *  @param it First mesh to be processed
 252.260 +	 *  @param end Last mesh to be processed
 252.261 +	 */
 252.262 +	static void BuildUniqueBoneList(std::list<BoneWithHash>& asBones,
 252.263 +		std::vector<aiMesh*>::const_iterator it,
 252.264 +		std::vector<aiMesh*>::const_iterator end);
 252.265 +
 252.266 +	// -------------------------------------------------------------------
 252.267 +	/** Add a name prefix to all nodes in a scene.
 252.268 +	 *
 252.269 +	 *  @param Current node. This function is called recursively.
 252.270 +	 *  @param prefix Prefix to be added to all nodes
 252.271 +	 *  @param len STring length
 252.272 +	 */
 252.273 +	static void AddNodePrefixes(aiNode* node, const char* prefix,
 252.274 +		unsigned int len);
 252.275 +
 252.276 +	// -------------------------------------------------------------------
 252.277 +	/** Add an offset to all mesh indices in a node graph
 252.278 +	 *
 252.279 +	 *  @param Current node. This function is called recursively.
 252.280 +	 *  @param offset Offset to be added to all mesh indices
 252.281 +	 */
 252.282 +	static void OffsetNodeMeshIndices (aiNode* node, unsigned int offset);
 252.283 +
 252.284 +	// -------------------------------------------------------------------
 252.285 +	/** Attach a list of node graphs to well-defined nodes in a master
 252.286 +	 *  graph. This is a helper for MergeScenes()
 252.287 +	 *
 252.288 +	 *  @param master Master scene
 252.289 +	 *  @param srcList List of source scenes along with their attachment
 252.290 +	 *    points. If an attachment point is NULL (or does not exist in
 252.291 +	 *    the master graph), a scene is attached to the root of the master
 252.292 +	 *    graph (as an additional child node)
 252.293 +	 *  @duplicates List of duplicates. If elem[n] == n the scene is not
 252.294 +	 *    a duplicate. Otherwise elem[n] links scene n to its first occurence.
 252.295 +	 */
 252.296 +	static void AttachToGraph ( aiScene* master, 
 252.297 +		std::vector<NodeAttachmentInfo>& srcList);
 252.298 +
 252.299 +	static void AttachToGraph (aiNode* attach, 
 252.300 +		std::vector<NodeAttachmentInfo>& srcList);
 252.301 +
 252.302 +
 252.303 +	// -------------------------------------------------------------------
 252.304 +	/** Get a deep copy of a scene
 252.305 +	 *
 252.306 +	 *  @param dest Receives a pointer to the destination scene
 252.307 +	 *  @param src Source scene - remains unmodified.
 252.308 +	 */
 252.309 +	static void CopyScene(aiScene** dest,const aiScene* source,bool allocate = true);
 252.310 +
 252.311 +
 252.312 +	// -------------------------------------------------------------------
 252.313 +	/** Get a flat copy of a scene
 252.314 +	 *
 252.315 +	 *  Only the first hierarchy layer is copied. All pointer members of
 252.316 +	 *  aiScene are shared by source and destination scene.  If the
 252.317 +	 *    pointer doesn't point to NULL when the function is called, the
 252.318 +	 *    existing scene is cleared and refilled.
 252.319 +	 *  @param dest Receives a pointer to the destination scene
 252.320 +	 *  @param src Source scene - remains unmodified.
 252.321 +	 */
 252.322 +	static void CopySceneFlat(aiScene** dest,const aiScene* source);
 252.323 +
 252.324 +
 252.325 +	// -------------------------------------------------------------------
 252.326 +	/** Get a deep copy of a mesh
 252.327 +	 *
 252.328 +	 *  @param dest Receives a pointer to the destination mesh
 252.329 +	 *  @param src Source mesh - remains unmodified.
 252.330 +	 */
 252.331 +	static void Copy     (aiMesh** dest, const aiMesh* src);
 252.332 +
 252.333 +	// similar to Copy():
 252.334 +	static void Copy  (aiMaterial** dest, const aiMaterial* src);
 252.335 +	static void Copy  (aiTexture** dest, const aiTexture* src);
 252.336 +	static void Copy  (aiAnimation** dest, const aiAnimation* src);
 252.337 +	static void Copy  (aiCamera** dest, const aiCamera* src);
 252.338 +	static void Copy  (aiBone** dest, const aiBone* src);
 252.339 +	static void Copy  (aiLight** dest, const aiLight* src);
 252.340 +	static void Copy  (aiNodeAnim** dest, const aiNodeAnim* src);
 252.341 +
 252.342 +	// recursive, of course
 252.343 +	static void Copy     (aiNode** dest, const aiNode* src);
 252.344 +
 252.345 +
 252.346 +private:
 252.347 +
 252.348 +	// -------------------------------------------------------------------
 252.349 +	// Same as AddNodePrefixes, but with an additional check
 252.350 +	static void AddNodePrefixesChecked(aiNode* node, const char* prefix, 
 252.351 +		unsigned int len,
 252.352 +		std::vector<SceneHelper>& input, 
 252.353 +		unsigned int cur);
 252.354 +
 252.355 +	// -------------------------------------------------------------------
 252.356 +	// Add node identifiers to a hashing set
 252.357 +	static void AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes);
 252.358 +
 252.359 +
 252.360 +	// -------------------------------------------------------------------
 252.361 +	// Search for duplicate names
 252.362 +	static bool FindNameMatch(const aiString& name, 
 252.363 +		std::vector<SceneHelper>& input, unsigned int cur);
 252.364 +};
 252.365 +
 252.366 +}
 252.367 +
 252.368 +#endif // !! AI_SCENE_COMBINER_H_INC
   253.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   253.2 +++ b/libs/assimp/ScenePreprocessor.cpp	Sat Feb 01 19:58:19 2014 +0200
   253.3 @@ -0,0 +1,258 @@
   253.4 +/*
   253.5 +Open Asset Import Library (assimp)
   253.6 +----------------------------------------------------------------------
   253.7 +
   253.8 +Copyright (c) 2006-2012, assimp team
   253.9 +All rights reserved.
  253.10 +
  253.11 +Redistribution and use of this software in source and binary forms, 
  253.12 +with or without modification, are permitted provided that the 
  253.13 +following conditions are met:
  253.14 +
  253.15 +* Redistributions of source code must retain the above
  253.16 +  copyright notice, this list of conditions and the
  253.17 +  following disclaimer.
  253.18 +
  253.19 +* Redistributions in binary form must reproduce the above
  253.20 +  copyright notice, this list of conditions and the
  253.21 +  following disclaimer in the documentation and/or other
  253.22 +  materials provided with the distribution.
  253.23 +
  253.24 +* Neither the name of the assimp team, nor the names of its
  253.25 +  contributors may be used to endorse or promote products
  253.26 +  derived from this software without specific prior
  253.27 +  written permission of the assimp team.
  253.28 +
  253.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  253.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  253.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  253.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  253.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  253.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  253.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  253.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  253.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  253.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  253.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  253.40 +
  253.41 +----------------------------------------------------------------------
  253.42 +*/
  253.43 +
  253.44 +#include "AssimpPCH.h"
  253.45 +#include "ScenePreprocessor.h"
  253.46 +
  253.47 +using namespace Assimp;
  253.48 +
  253.49 +// ---------------------------------------------------------------------------------------------
  253.50 +void ScenePreprocessor::ProcessScene ()
  253.51 +{
  253.52 +	ai_assert(scene != NULL);
  253.53 +
  253.54 +	// Process all meshes
  253.55 +	for (unsigned int i = 0; i < scene->mNumMeshes;++i)
  253.56 +		ProcessMesh(scene->mMeshes[i]);
  253.57 +
  253.58 +	// - nothing to do for nodes for the moment
  253.59 +	// - nothing to do for textures for the moment
  253.60 +	// - nothing to do for lights for the moment
  253.61 +	// - nothing to do for cameras for the moment
  253.62 +
  253.63 +	// Process all animations
  253.64 +	for (unsigned int i = 0; i < scene->mNumAnimations;++i)
  253.65 +		ProcessAnimation(scene->mAnimations[i]);
  253.66 +
  253.67 +	// Generate a default material if none was specified
  253.68 +	if (!scene->mNumMaterials && scene->mNumMeshes)	{
  253.69 +		scene->mMaterials      = new aiMaterial*[2];
  253.70 +		aiMaterial* helper;
  253.71 +
  253.72 +		aiString name;
  253.73 +
  253.74 +		scene->mMaterials[scene->mNumMaterials] = helper = new aiMaterial();
  253.75 +		aiColor3D clr(0.6f,0.6f,0.6f);
  253.76 +		helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
  253.77 +
  253.78 +		// setup the default name to make this material identifyable
  253.79 +		name.Set(AI_DEFAULT_MATERIAL_NAME);
  253.80 +		helper->AddProperty(&name,AI_MATKEY_NAME);
  253.81 +
  253.82 +		DefaultLogger::get()->debug("ScenePreprocessor: Adding default material \'" AI_DEFAULT_MATERIAL_NAME  "\'");
  253.83 +
  253.84 +		for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
  253.85 +			scene->mMeshes[i]->mMaterialIndex = scene->mNumMaterials;
  253.86 +		}
  253.87 +
  253.88 +		scene->mNumMaterials++;
  253.89 +	}
  253.90 +}
  253.91 +
  253.92 +// ---------------------------------------------------------------------------------------------
  253.93 +void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
  253.94 +{
  253.95 +	// If aiMesh::mNumUVComponents is *not* set assign the default value of 2
  253.96 +	for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i)	{
  253.97 +		if (!mesh->mTextureCoords[i])
  253.98 +			mesh->mNumUVComponents[i] = 0;
  253.99 +
 253.100 +		else {
 253.101 +			if( !mesh->mNumUVComponents[i])
 253.102 +				mesh->mNumUVComponents[i] = 2;
 253.103 +
 253.104 +			aiVector3D* p = mesh->mTextureCoords[i], *end = p+mesh->mNumVertices;
 253.105 +
 253.106 +			// Ensure unsued components are zeroed. This will make 1D texture channels work
 253.107 +			// as if they were 2D channels .. just in case an application doesn't handle
 253.108 +			// this case
 253.109 +			if (2 == mesh->mNumUVComponents[i]) {
 253.110 +				for (; p != end; ++p)
 253.111 +					p->z = 0.f;
 253.112 +			}
 253.113 +			else if (1 == mesh->mNumUVComponents[i]) {
 253.114 +				for (; p != end; ++p)
 253.115 +					p->z = p->y = 0.f;
 253.116 +			}
 253.117 +			else if (3 == mesh->mNumUVComponents[i]) {
 253.118 +			
 253.119 +				// Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
 253.120 +				for (; p != end; ++p) {
 253.121 +					if (p->z != 0)
 253.122 +						break;
 253.123 +				}
 253.124 +				if (p == end) {
 253.125 +					DefaultLogger::get()->warn("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D.");
 253.126 +					mesh->mNumUVComponents[i] = 2;
 253.127 +				}
 253.128 +			}
 253.129 +		}
 253.130 +	}
 253.131 +
 253.132 +	// If the information which primitive types are there in the
 253.133 +	// mesh is currently not available, compute it.
 253.134 +	if (!mesh->mPrimitiveTypes)	{
 253.135 +		for (unsigned int a = 0; a < mesh->mNumFaces; ++a)	{
 253.136 +			aiFace& face = mesh->mFaces[a];
 253.137 +			switch (face.mNumIndices)
 253.138 +			{
 253.139 +			case 3u:
 253.140 +				mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
 253.141 +				break;
 253.142 +
 253.143 +			case 2u:
 253.144 +				mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
 253.145 +				break;
 253.146 +
 253.147 +			case 1u:
 253.148 +				mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
 253.149 +				break;
 253.150 +
 253.151 +			default:
 253.152 +				mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
 253.153 +				break;
 253.154 +			}
 253.155 +		}
 253.156 +	}
 253.157 +
 253.158 +	// If tangents and normals are given but no bitangents compute them
 253.159 +	if (mesh->mTangents && mesh->mNormals && !mesh->mBitangents)	{
 253.160 +
 253.161 +		mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
 253.162 +		for (unsigned int i = 0; i < mesh->mNumVertices;++i)	{
 253.163 +			mesh->mBitangents[i] = mesh->mNormals[i] ^ mesh->mTangents[i];
 253.164 +		}
 253.165 +	}
 253.166 +}
 253.167 +
 253.168 +// ---------------------------------------------------------------------------------------------
 253.169 +void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
 253.170 +{
 253.171 +	double first = 10e10, last = -10e10;
 253.172 +	for (unsigned int i = 0; i < anim->mNumChannels;++i)	{
 253.173 +		aiNodeAnim* channel = anim->mChannels[i];
 253.174 +
 253.175 +		/*  If the exact duration of the animation is not given
 253.176 +		 *  compute it now.
 253.177 +		 */
 253.178 +		if (anim->mDuration == -1.)	{
 253.179 +
 253.180 +			// Position keys
 253.181 +			for (unsigned int i = 0; i < channel->mNumPositionKeys;++i)	{
 253.182 +				aiVectorKey& key = channel->mPositionKeys[i];
 253.183 +				first = std::min (first, key.mTime);
 253.184 +				last  = std::max (last,  key.mTime);
 253.185 +			}
 253.186 +
 253.187 +			// Scaling keys
 253.188 +			for (unsigned int i = 0; i < channel->mNumScalingKeys;++i)	{
 253.189 +				aiVectorKey& key = channel->mScalingKeys[i];
 253.190 +				first = std::min (first, key.mTime);
 253.191 +				last  = std::max (last,  key.mTime);
 253.192 +			}
 253.193 +
 253.194 +			// Rotation keys
 253.195 +			for (unsigned int i = 0; i < channel->mNumRotationKeys;++i)	{
 253.196 +				aiQuatKey& key = channel->mRotationKeys[i];
 253.197 +				first = std::min (first, key.mTime);
 253.198 +				last  = std::max (last,  key.mTime);
 253.199 +			}
 253.200 +		}
 253.201 +
 253.202 +		/*  Check whether the animation channel has no rotation
 253.203 +		 *  or position tracks. In this case we generate a dummy
 253.204 +		 *  track from the information we have in the transformation
 253.205 +		 *  matrix of the corresponding node.
 253.206 +		 */
 253.207 +		if (!channel->mNumRotationKeys || !channel->mNumPositionKeys || !channel->mNumScalingKeys)	{
 253.208 +			// Find the node that belongs to this animation
 253.209 +			aiNode* node = scene->mRootNode->FindNode(channel->mNodeName);
 253.210 +			if (node) // ValidateDS will complain later if 'node' is NULL
 253.211 +			{
 253.212 +				// Decompose the transformation matrix of the node
 253.213 +				aiVector3D scaling, position;
 253.214 +				aiQuaternion rotation;
 253.215 +
 253.216 +				node->mTransformation.Decompose(scaling, rotation,position);
 253.217 +
 253.218 +				// No rotation keys? Generate a dummy track
 253.219 +				if (!channel->mNumRotationKeys)	{
 253.220 +					channel->mNumRotationKeys = 1;
 253.221 +					channel->mRotationKeys = new aiQuatKey[1];
 253.222 +					aiQuatKey& q = channel->mRotationKeys[0];
 253.223 +
 253.224 +					q.mTime  = 0.;
 253.225 +					q.mValue = rotation;
 253.226 +
 253.227 +					DefaultLogger::get()->debug("ScenePreprocessor: Dummy rotation track has been generated");
 253.228 +				}
 253.229 +
 253.230 +				// No scaling keys? Generate a dummy track
 253.231 +				if (!channel->mNumScalingKeys)	{
 253.232 +					channel->mNumScalingKeys = 1;
 253.233 +					channel->mScalingKeys = new aiVectorKey[1];
 253.234 +					aiVectorKey& q = channel->mScalingKeys[0];
 253.235 +
 253.236 +					q.mTime  = 0.;
 253.237 +					q.mValue = scaling;
 253.238 +
 253.239 +					DefaultLogger::get()->debug("ScenePreprocessor: Dummy scaling track has been generated");
 253.240 +				}
 253.241 +
 253.242 +				// No position keys? Generate a dummy track
 253.243 +				if (!channel->mNumPositionKeys)	{
 253.244 +					channel->mNumPositionKeys = 1;
 253.245 +					channel->mPositionKeys = new aiVectorKey[1];
 253.246 +					aiVectorKey& q = channel->mPositionKeys[0];
 253.247 +
 253.248 +					q.mTime  = 0.;
 253.249 +					q.mValue = position;
 253.250 +
 253.251 +					DefaultLogger::get()->debug("ScenePreprocessor: Dummy position track has been generated");
 253.252 +				}
 253.253 +			}
 253.254 +		}
 253.255 +	}
 253.256 +
 253.257 +	if (anim->mDuration == -1.)		{
 253.258 +		DefaultLogger::get()->debug("ScenePreprocessor: Setting animation duration");
 253.259 +		anim->mDuration = last - std::min( first, 0. );
 253.260 +	}
 253.261 +}
   254.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   254.2 +++ b/libs/assimp/ScenePreprocessor.h	Sat Feb 01 19:58:19 2014 +0200
   254.3 @@ -0,0 +1,116 @@
   254.4 +/*
   254.5 +Open Asset Import Library (assimp)
   254.6 +----------------------------------------------------------------------
   254.7 +
   254.8 +Copyright (c) 2006-2012, assimp team
   254.9 +All rights reserved.
  254.10 +
  254.11 +Redistribution and use of this software in source and binary forms, 
  254.12 +with or without modification, are permitted provided that the 
  254.13 +following conditions are met:
  254.14 +
  254.15 +* Redistributions of source code must retain the above
  254.16 +  copyright notice, this list of conditions and the
  254.17 +  following disclaimer.
  254.18 +
  254.19 +* Redistributions in binary form must reproduce the above
  254.20 +  copyright notice, this list of conditions and the
  254.21 +  following disclaimer in the documentation and/or other
  254.22 +  materials provided with the distribution.
  254.23 +
  254.24 +* Neither the name of the assimp team, nor the names of its
  254.25 +  contributors may be used to endorse or promote products
  254.26 +  derived from this software without specific prior
  254.27 +  written permission of the assimp team.
  254.28 +
  254.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  254.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  254.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  254.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  254.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  254.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  254.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  254.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  254.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  254.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  254.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  254.40 +
  254.41 +----------------------------------------------------------------------
  254.42 +*/
  254.43 +
  254.44 +/** @file Defines a post processing step to search all meshes for
  254.45 +  degenerated faces */
  254.46 +#ifndef AI_SCENE_PREPROCESSOR_H_INC
  254.47 +#define AI_SCENE_PREPROCESSOR_H_INC
  254.48 +
  254.49 +class ScenePreprocessorTest;
  254.50 +namespace Assimp	{
  254.51 +
  254.52 +// ----------------------------------------------------------------------------------
  254.53 +/** ScenePreprocessor: Preprocess a scene before any post-processing
  254.54 + *  steps are executed.
  254.55 + *
  254.56 + *  The step computes data that needn't necessarily be provided by the
  254.57 + *  importer, such as aiMesh::mPrimitiveTypes.
  254.58 +*/
  254.59 +// ----------------------------------------------------------------------------------
  254.60 +class ScenePreprocessor
  254.61 +{
  254.62 +	// Make ourselves a friend of the corresponding test unit.
  254.63 +	friend class ::ScenePreprocessorTest;
  254.64 +public:
  254.65 +
  254.66 +	// ----------------------------------------------------------------
  254.67 +	/** Default c'tpr. Use SetScene() to assign a scene to the object.
  254.68 +	 */
  254.69 +	ScenePreprocessor()	
  254.70 +		:	scene	(NULL)
  254.71 +	{}
  254.72 +
  254.73 +	/** Constructs the object and assigns a specific scene to it
  254.74 +	 */
  254.75 +	ScenePreprocessor(aiScene* _scene)
  254.76 +		:	scene	(_scene)
  254.77 +	{}
  254.78 +
  254.79 +	// ----------------------------------------------------------------
  254.80 +	/** Assign a (new) scene to the object.
  254.81 +	 *  
  254.82 +	 *  One 'SceneProcessor' can be used for multiple scenes.
  254.83 +	 *  Call ProcessScene to have the scene preprocessed.
  254.84 +	 *  @param sc Scene to be processed.
  254.85 +	 */
  254.86 +	void SetScene (aiScene* sc)	{
  254.87 +		scene = sc;
  254.88 +	}
  254.89 +
  254.90 +	// ----------------------------------------------------------------
  254.91 +	/** Preprocess the current scene
  254.92 +	 */
  254.93 +	void ProcessScene ();
  254.94 +
  254.95 +protected:
  254.96 +
  254.97 +	// ----------------------------------------------------------------
  254.98 +	/** Preprocess an animation in the scene
  254.99 +	 *  @param anim Anim to be preprocessed.
 254.100 +	 */
 254.101 +	void ProcessAnimation (aiAnimation* anim);
 254.102 +	
 254.103 +	
 254.104 +	// ----------------------------------------------------------------
 254.105 +	/** Preprocess a mesh in the scene
 254.106 +	 *  @param mesh Mesh to be preprocessed.
 254.107 +	 */
 254.108 +	void ProcessMesh (aiMesh* mesh);
 254.109 +
 254.110 +protected:
 254.111 +
 254.112 +	//! Scene we're currently working on
 254.113 +	aiScene* scene;
 254.114 +};
 254.115 +
 254.116 +
 254.117 +} // ! end namespace Assimp
 254.118 +
 254.119 +#endif // include guard
   255.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   255.2 +++ b/libs/assimp/ScenePrivate.h	Sat Feb 01 19:58:19 2014 +0200
   255.3 @@ -0,0 +1,77 @@
   255.4 +/*
   255.5 +Open Asset Import Library (assimp)
   255.6 +----------------------------------------------------------------------
   255.7 +
   255.8 +Copyright (c) 2006-2012, assimp team
   255.9 +All rights reserved.
  255.10 +
  255.11 +Redistribution and use of this software in source and binary forms, 
  255.12 +with or without modification, are permitted provided that the 
  255.13 +following conditions are met:
  255.14 +
  255.15 +* Redistributions of source code must retain the above
  255.16 +  copyright notice, this list of conditions and the
  255.17 +  following disclaimer.
  255.18 +
  255.19 +* Redistributions in binary form must reproduce the above
  255.20 +  copyright notice, this list of conditions and the
  255.21 +  following disclaimer in the documentation and/or other
  255.22 +  materials provided with the distribution.
  255.23 +
  255.24 +* Neither the name of the assimp team, nor the names of its
  255.25 +  contributors may be used to endorse or promote products
  255.26 +  derived from this software without specific prior
  255.27 +  written permission of the assimp team.
  255.28 +
  255.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  255.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  255.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  255.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  255.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  255.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  255.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  255.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  255.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  255.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  255.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  255.40 +
  255.41 +----------------------------------------------------------------------
  255.42 +*/
  255.43 +
  255.44 +/** @file Stuff to deal with aiScene::mPrivate
  255.45 + */
  255.46 +#ifndef AI_SCENEPRIVATE_H_INCLUDED
  255.47 +#define AI_SCENEPRIVATE_H_INCLUDED
  255.48 +
  255.49 +
  255.50 +namespace Assimp	{
  255.51 +
  255.52 +	class Importer;
  255.53 +
  255.54 +struct ScenePrivateData {
  255.55 +	
  255.56 +	ScenePrivateData()
  255.57 +		: mOrigImporter()
  255.58 +		, mPPStepsApplied()
  255.59 +	{}
  255.60 +
  255.61 +	// Importer that originally loaded the scene though the C-API
  255.62 +	// If set, this object is owned by this private data instance.
  255.63 +	Assimp::Importer* mOrigImporter;
  255.64 +
  255.65 +	// List of postprocessing steps already applied to the scene.
  255.66 +	unsigned int mPPStepsApplied;
  255.67 +};
  255.68 +
  255.69 +// Access private data stored in the scene
  255.70 +inline ScenePrivateData* ScenePriv(aiScene* in) {
  255.71 +	return static_cast<ScenePrivateData*>(in->mPrivate);
  255.72 +}
  255.73 +
  255.74 +inline const ScenePrivateData* ScenePriv(const aiScene* in) {
  255.75 +	return static_cast<const ScenePrivateData*>(in->mPrivate);
  255.76 +}
  255.77 +
  255.78 +}
  255.79 +
  255.80 +#endif
   256.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   256.2 +++ b/libs/assimp/SkeletonMeshBuilder.cpp	Sat Feb 01 19:58:19 2014 +0200
   256.3 @@ -0,0 +1,267 @@
   256.4 +/*
   256.5 +Open Asset Import Library (assimp)
   256.6 +----------------------------------------------------------------------
   256.7 +
   256.8 +Copyright (c) 2006-2012, assimp team
   256.9 +All rights reserved.
  256.10 +
  256.11 +Redistribution and use of this software in source and binary forms, 
  256.12 +with or without modification, are permitted provided that the 
  256.13 +following conditions are met:
  256.14 +
  256.15 +* Redistributions of source code must retain the above
  256.16 +copyright notice, this list of conditions and the
  256.17 +following disclaimer.
  256.18 +
  256.19 +* Redistributions in binary form must reproduce the above
  256.20 +copyright notice, this list of conditions and the
  256.21 +following disclaimer in the documentation and/or other
  256.22 +materials provided with the distribution.
  256.23 +
  256.24 +* Neither the name of the assimp team, nor the names of its
  256.25 +contributors may be used to endorse or promote products
  256.26 +derived from this software without specific prior
  256.27 +written permission of the assimp team.
  256.28 +
  256.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  256.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  256.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  256.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  256.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  256.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  256.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  256.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  256.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  256.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  256.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  256.40 +
  256.41 +----------------------------------------------------------------------
  256.42 +*/
  256.43 +
  256.44 +/** @file  SkeletonMeshBuilder.cpp
  256.45 + *  @brief Implementation of a little class to construct a dummy mesh for a skeleton 
  256.46 + */
  256.47 +
  256.48 +#include "AssimpPCH.h"
  256.49 +#include "assimp/scene.h"
  256.50 +#include "SkeletonMeshBuilder.h"
  256.51 +
  256.52 +using namespace Assimp;
  256.53 +
  256.54 +// ------------------------------------------------------------------------------------------------
  256.55 +// The constructor processes the given scene and adds a mesh there. 
  256.56 +SkeletonMeshBuilder::SkeletonMeshBuilder( aiScene* pScene, aiNode* root, bool bKnobsOnly)
  256.57 +{
  256.58 +	// nothing to do if there's mesh data already present at the scene
  256.59 +	if( pScene->mNumMeshes > 0 || pScene->mRootNode == NULL)
  256.60 +		return;
  256.61 +
  256.62 +	if (!root)
  256.63 +		root = pScene->mRootNode;
  256.64 +
  256.65 +	mKnobsOnly = bKnobsOnly;
  256.66 +
  256.67 +	// build some faces around each node 
  256.68 +	CreateGeometry( root );
  256.69 +
  256.70 +	// create a mesh to hold all the generated faces
  256.71 +	pScene->mNumMeshes = 1;
  256.72 +	pScene->mMeshes = new aiMesh*[1];
  256.73 +	pScene->mMeshes[0] = CreateMesh();
  256.74 +	// and install it at the root node
  256.75 +	root->mNumMeshes = 1;
  256.76 +	root->mMeshes = new unsigned int[1];
  256.77 +	root->mMeshes[0] = 0;
  256.78 +
  256.79 +	// create a dummy material for the mesh
  256.80 +	pScene->mNumMaterials = 1;
  256.81 +	pScene->mMaterials = new aiMaterial*[1];
  256.82 +	pScene->mMaterials[0] = CreateMaterial();
  256.83 +}
  256.84 +
  256.85 +// ------------------------------------------------------------------------------------------------
  256.86 +// Recursively builds a simple mesh representation for the given node 
  256.87 +void SkeletonMeshBuilder::CreateGeometry( const aiNode* pNode)
  256.88 +{
  256.89 +	// add a joint entry for the node. 
  256.90 +	const unsigned int vertexStartIndex = mVertices.size();
  256.91 +
  256.92 +	// now build the geometry. 
  256.93 +	if( pNode->mNumChildren > 0 && !mKnobsOnly)
  256.94 +	{
  256.95 +		// If the node has children, we build little pointers to each of them
  256.96 +		for( unsigned int a = 0; a < pNode->mNumChildren; a++)
  256.97 +		{
  256.98 +			// find a suitable coordinate system
  256.99 +			const aiMatrix4x4& childTransform = pNode->mChildren[a]->mTransformation;
 256.100 +			aiVector3D childpos( childTransform.a4, childTransform.b4, childTransform.c4);
 256.101 +			float distanceToChild = childpos.Length();
 256.102 +			if( distanceToChild < 0.0001f)
 256.103 +				continue;
 256.104 +			aiVector3D up = aiVector3D( childpos).Normalize();
 256.105 +
 256.106 +			aiVector3D orth( 1.0f, 0.0f, 0.0f);
 256.107 +			if( fabs( orth * up) > 0.99f)
 256.108 +				orth.Set( 0.0f, 1.0f, 0.0f);
 256.109 +
 256.110 +			aiVector3D front = (up ^ orth).Normalize();
 256.111 +			aiVector3D side = (front ^ up).Normalize();
 256.112 +
 256.113 +			unsigned int localVertexStart = mVertices.size();
 256.114 +			mVertices.push_back( -front * distanceToChild * 0.1f);
 256.115 +			mVertices.push_back( childpos);
 256.116 +			mVertices.push_back( -side * distanceToChild * 0.1f);
 256.117 +			mVertices.push_back( -side * distanceToChild * 0.1f);
 256.118 +			mVertices.push_back( childpos);
 256.119 +			mVertices.push_back( front * distanceToChild * 0.1f);
 256.120 +			mVertices.push_back( front * distanceToChild * 0.1f);
 256.121 +			mVertices.push_back( childpos);
 256.122 +			mVertices.push_back( side * distanceToChild * 0.1f);
 256.123 +			mVertices.push_back( side * distanceToChild * 0.1f);
 256.124 +			mVertices.push_back( childpos);
 256.125 +			mVertices.push_back( -front * distanceToChild * 0.1f);
 256.126 +
 256.127 +			mFaces.push_back( Face( localVertexStart + 0, localVertexStart + 1, localVertexStart + 2));
 256.128 +			mFaces.push_back( Face( localVertexStart + 3, localVertexStart + 4, localVertexStart + 5));
 256.129 +			mFaces.push_back( Face( localVertexStart + 6, localVertexStart + 7, localVertexStart + 8));
 256.130 +			mFaces.push_back( Face( localVertexStart + 9, localVertexStart + 10, localVertexStart + 11));
 256.131 +		}
 256.132 +	} 
 256.133 +	else
 256.134 +	{
 256.135 +		// if the node has no children, it's an end node. Put a little knob there instead
 256.136 +		aiVector3D ownpos( pNode->mTransformation.a4, pNode->mTransformation.b4, pNode->mTransformation.c4);
 256.137 +		float sizeEstimate = ownpos.Length() * 0.18f;
 256.138 +
 256.139 +		mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f));
 256.140 +		mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f));
 256.141 +		mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate));
 256.142 +		mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f));
 256.143 +		mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f));
 256.144 +		mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate));
 256.145 +		mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f));
 256.146 +		mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f));
 256.147 +		mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate));
 256.148 +		mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f));
 256.149 +		mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f));
 256.150 +		mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate));
 256.151 +
 256.152 +		mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f));
 256.153 +		mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate));
 256.154 +		mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f));
 256.155 +		mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f));
 256.156 +		mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate));
 256.157 +		mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f));
 256.158 +		mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f));
 256.159 +		mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate));
 256.160 +		mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f));
 256.161 +		mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f));
 256.162 +		mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate));
 256.163 +		mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f));
 256.164 +
 256.165 +		mFaces.push_back( Face( vertexStartIndex + 0, vertexStartIndex + 1, vertexStartIndex + 2));
 256.166 +		mFaces.push_back( Face( vertexStartIndex + 3, vertexStartIndex + 4, vertexStartIndex + 5));
 256.167 +		mFaces.push_back( Face( vertexStartIndex + 6, vertexStartIndex + 7, vertexStartIndex + 8));
 256.168 +		mFaces.push_back( Face( vertexStartIndex + 9, vertexStartIndex + 10, vertexStartIndex + 11));
 256.169 +		mFaces.push_back( Face( vertexStartIndex + 12, vertexStartIndex + 13, vertexStartIndex + 14));
 256.170 +		mFaces.push_back( Face( vertexStartIndex + 15, vertexStartIndex + 16, vertexStartIndex + 17));
 256.171 +		mFaces.push_back( Face( vertexStartIndex + 18, vertexStartIndex + 19, vertexStartIndex + 20));
 256.172 +		mFaces.push_back( Face( vertexStartIndex + 21, vertexStartIndex + 22, vertexStartIndex + 23));
 256.173 +	}
 256.174 +
 256.175 +	unsigned int numVertices = mVertices.size() - vertexStartIndex;
 256.176 +	if( numVertices > 0)
 256.177 +	{
 256.178 +		// create a bone affecting all the newly created vertices
 256.179 +		aiBone* bone = new aiBone;
 256.180 +		mBones.push_back( bone);
 256.181 +		bone->mName = pNode->mName;
 256.182 +
 256.183 +		// calculate the bone offset matrix by concatenating the inverse transformations of all parents
 256.184 +		bone->mOffsetMatrix = aiMatrix4x4( pNode->mTransformation).Inverse();
 256.185 +		for( aiNode* parent = pNode->mParent; parent != NULL; parent = parent->mParent)
 256.186 +			bone->mOffsetMatrix = aiMatrix4x4( parent->mTransformation).Inverse() * bone->mOffsetMatrix;
 256.187 +
 256.188 +		// add all the vertices to the bone's influences
 256.189 +		bone->mNumWeights = numVertices;
 256.190 +		bone->mWeights = new aiVertexWeight[numVertices];
 256.191 +		for( unsigned int a = 0; a < numVertices; a++)
 256.192 +			bone->mWeights[a] = aiVertexWeight( vertexStartIndex + a, 1.0f);
 256.193 +
 256.194 +		// HACK: (thom) transform all vertices to the bone's local space. Should be done before adding
 256.195 +		// them to the array, but I'm tired now and I'm annoyed.
 256.196 +		aiMatrix4x4 boneToMeshTransform = aiMatrix4x4( bone->mOffsetMatrix).Inverse();
 256.197 +		for( unsigned int a = vertexStartIndex; a < mVertices.size(); a++)
 256.198 +			mVertices[a] = boneToMeshTransform * mVertices[a];
 256.199 +	}
 256.200 +
 256.201 +	// and finally recurse into the children list
 256.202 +	for( unsigned int a = 0; a < pNode->mNumChildren; a++)
 256.203 +		CreateGeometry( pNode->mChildren[a]);
 256.204 +}
 256.205 +
 256.206 +// ------------------------------------------------------------------------------------------------
 256.207 +// Creates the mesh from the internally accumulated stuff and returns it.
 256.208 +aiMesh* SkeletonMeshBuilder::CreateMesh()
 256.209 +{
 256.210 +	aiMesh* mesh = new aiMesh();
 256.211 +
 256.212 +	// add points
 256.213 +	mesh->mNumVertices = mVertices.size();
 256.214 +	mesh->mVertices = new aiVector3D[mesh->mNumVertices];
 256.215 +	std::copy( mVertices.begin(), mVertices.end(), mesh->mVertices);
 256.216 +
 256.217 +	mesh->mNormals = new aiVector3D[mesh->mNumVertices];
 256.218 +
 256.219 +	// add faces
 256.220 +	mesh->mNumFaces = mFaces.size();
 256.221 +	mesh->mFaces = new aiFace[mesh->mNumFaces];
 256.222 +	for( unsigned int a = 0; a < mesh->mNumFaces; a++)
 256.223 +	{
 256.224 +		const Face& inface = mFaces[a];
 256.225 +		aiFace& outface = mesh->mFaces[a];
 256.226 +		outface.mNumIndices = 3;
 256.227 +		outface.mIndices = new unsigned int[3];
 256.228 +		outface.mIndices[0] = inface.mIndices[0];
 256.229 +		outface.mIndices[1] = inface.mIndices[1];
 256.230 +		outface.mIndices[2] = inface.mIndices[2];
 256.231 +
 256.232 +		// Compute per-face normals ... we don't want the bones to be smoothed ... they're built to visualize
 256.233 +		// the skeleton, so it's good if there's a visual difference to the rest of the geometry
 256.234 +		aiVector3D nor = ((mVertices[inface.mIndices[2]] - mVertices[inface.mIndices[0]]) ^ 
 256.235 +			(mVertices[inface.mIndices[1]] - mVertices[inface.mIndices[0]]));
 256.236 +
 256.237 +		if (nor.Length() < 1e-5f) /* ensure that FindInvalidData won't remove us ...*/
 256.238 +			nor = aiVector3D(1.f,0.f,0.f);
 256.239 +
 256.240 +		for (unsigned int n = 0; n < 3; ++n)
 256.241 +			mesh->mNormals[inface.mIndices[n]] = nor;
 256.242 +	}
 256.243 +
 256.244 +	// add the bones
 256.245 +	mesh->mNumBones = mBones.size();
 256.246 +	mesh->mBones = new aiBone*[mesh->mNumBones];
 256.247 +	std::copy( mBones.begin(), mBones.end(), mesh->mBones);
 256.248 +
 256.249 +	// default
 256.250 +	mesh->mMaterialIndex = 0;
 256.251 +
 256.252 +	return mesh;
 256.253 +}
 256.254 +
 256.255 +// ------------------------------------------------------------------------------------------------
 256.256 +// Creates a dummy material and returns it.
 256.257 +aiMaterial* SkeletonMeshBuilder::CreateMaterial()
 256.258 +{
 256.259 +	aiMaterial* matHelper = new aiMaterial;
 256.260 +
 256.261 +	// Name
 256.262 +	aiString matName( std::string( "SkeletonMaterial"));
 256.263 +	matHelper->AddProperty( &matName, AI_MATKEY_NAME);
 256.264 +
 256.265 +	// Prevent backface culling
 256.266 +	const int no_cull = 1;
 256.267 +	matHelper->AddProperty(&no_cull,1,AI_MATKEY_TWOSIDED);
 256.268 +
 256.269 +	return matHelper;
 256.270 +}
   257.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   257.2 +++ b/libs/assimp/SkeletonMeshBuilder.h	Sat Feb 01 19:58:19 2014 +0200
   257.3 @@ -0,0 +1,122 @@
   257.4 +/** Helper class to construct a dummy mesh for file formats containing only motion data */
   257.5 +
   257.6 +/*
   257.7 +Open Asset Import Library (assimp)
   257.8 +----------------------------------------------------------------------
   257.9 +
  257.10 +Copyright (c) 2006-2012, assimp team
  257.11 +All rights reserved.
  257.12 +
  257.13 +Redistribution and use of this software in source and binary forms, 
  257.14 +with or without modification, are permitted provided that the 
  257.15 +following conditions are met:
  257.16 +
  257.17 +* Redistributions of source code must retain the above
  257.18 +copyright notice, this list of conditions and the
  257.19 +following disclaimer.
  257.20 +
  257.21 +* Redistributions in binary form must reproduce the above
  257.22 +copyright notice, this list of conditions and the
  257.23 +following disclaimer in the documentation and/or other
  257.24 +materials provided with the distribution.
  257.25 +
  257.26 +* Neither the name of the assimp team, nor the names of its
  257.27 +contributors may be used to endorse or promote products
  257.28 +derived from this software without specific prior
  257.29 +written permission of the assimp team.
  257.30 +
  257.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  257.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  257.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  257.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  257.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  257.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  257.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  257.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  257.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  257.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  257.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  257.42 +
  257.43 +----------------------------------------------------------------------
  257.44 +*/
  257.45 +
  257.46 +/** @file SkeletonMeshBuilder.h
  257.47 + *  Declares SkeletonMeshBuilder, a tiny utility to build dummy meshes
  257.48 + *  for animation skeletons.
  257.49 + */
  257.50 +
  257.51 +#ifndef AI_SKELETONMESHBUILDER_H_INC
  257.52 +#define AI_SKELETONMESHBUILDER_H_INC
  257.53 +
  257.54 +#include <vector>
  257.55 +#include "assimp/mesh.h"
  257.56 +
  257.57 +struct aiScene;
  257.58 +struct aiNode;
  257.59 +
  257.60 +namespace Assimp	{
  257.61 +
  257.62 +// ---------------------------------------------------------------------------
  257.63 +/** 
  257.64 + * This little helper class constructs a dummy mesh for a given scene
  257.65 + * the resembles the node hierarchy. This is useful for file formats
  257.66 + * that don't carry any mesh data but only animation data.
  257.67 + */
  257.68 +class SkeletonMeshBuilder
  257.69 +{
  257.70 +public:
  257.71 +
  257.72 +	// -------------------------------------------------------------------
  257.73 +	/** The constructor processes the given scene and adds a mesh there. 
  257.74 +	 *
  257.75 +	 * Does nothing if the scene already has mesh data. 
  257.76 +	 * @param pScene The scene for which a skeleton mesh should be constructed.
  257.77 +	 * @param root The node to start with. NULL is the scene root
  257.78 +	 * @param bKnobsOnly Set this to true if you don't want the connectors
  257.79 +	 *   between the knobs representing the nodes.
  257.80 +	 */
  257.81 +	SkeletonMeshBuilder( aiScene* pScene, aiNode* root = NULL,
  257.82 +		bool bKnobsOnly = false);
  257.83 +
  257.84 +protected:
  257.85 +
  257.86 +	// -------------------------------------------------------------------
  257.87 +	/** Recursively builds a simple mesh representation for the given node
  257.88 +	 * and also creates a joint for the node that affects this part of 
  257.89 +	 * the mesh.
  257.90 +	 * @param pNode The node to build geometry for.
  257.91 +	 */
  257.92 +	void CreateGeometry( const aiNode* pNode);
  257.93 +
  257.94 +	// -------------------------------------------------------------------
  257.95 +	/** Creates the mesh from the internally accumulated stuff and returns it. 
  257.96 +	 */
  257.97 +	aiMesh* CreateMesh();
  257.98 +
  257.99 +	// -------------------------------------------------------------------
 257.100 +	/** Creates a dummy material and returns it. */
 257.101 +	aiMaterial* CreateMaterial();
 257.102 +
 257.103 +protected:
 257.104 +	/** space to assemble the mesh data: points */
 257.105 +	std::vector<aiVector3D> mVertices;
 257.106 +
 257.107 +	/** faces */
 257.108 +	struct Face 
 257.109 +	{ 
 257.110 +		unsigned int mIndices[3]; 
 257.111 +		Face();
 257.112 +		Face( unsigned int p0, unsigned int p1, unsigned int p2)
 257.113 +		{ mIndices[0] = p0; mIndices[1] = p1; mIndices[2] = p2; } 
 257.114 +	};
 257.115 +	std::vector<Face> mFaces;
 257.116 +
 257.117 +	/** bones */
 257.118 +	std::vector<aiBone*> mBones;
 257.119 +
 257.120 +	bool mKnobsOnly;
 257.121 +};
 257.122 +
 257.123 +} // end of namespace Assimp
 257.124 +
 257.125 +#endif // AI_SKELETONMESHBUILDER_H_INC
   258.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   258.2 +++ b/libs/assimp/SmoothingGroups.h	Sat Feb 01 19:58:19 2014 +0200
   258.3 @@ -0,0 +1,103 @@
   258.4 +/*
   258.5 +Open Asset Import Library (assimp)
   258.6 +----------------------------------------------------------------------
   258.7 +
   258.8 +Copyright (c) 2006-2012, assimp team
   258.9 +All rights reserved.
  258.10 +
  258.11 +Redistribution and use of this software in source and binary forms, 
  258.12 +with or without modification, are permitted provided that the 
  258.13 +following conditions are met:
  258.14 +
  258.15 +* Redistributions of source code must retain the above
  258.16 +  copyright notice, this list of conditions and the
  258.17 +  following disclaimer.
  258.18 +
  258.19 +* Redistributions in binary form must reproduce the above
  258.20 +  copyright notice, this list of conditions and the
  258.21 +  following disclaimer in the documentation and/or other
  258.22 +  materials provided with the distribution.
  258.23 +
  258.24 +* Neither the name of the assimp team, nor the names of its
  258.25 +  contributors may be used to endorse or promote products
  258.26 +  derived from this software without specific prior
  258.27 +  written permission of the assimp team.
  258.28 +
  258.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  258.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  258.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  258.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  258.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  258.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  258.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  258.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  258.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  258.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  258.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  258.40 +
  258.41 +----------------------------------------------------------------------
  258.42 +*/
  258.43 +
  258.44 +/** @file Defines the helper data structures for importing 3DS files.
  258.45 +http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */
  258.46 +
  258.47 +#ifndef AI_SMOOTHINGGROUPS_H_INC
  258.48 +#define AI_SMOOTHINGGROUPS_H_INC
  258.49 +
  258.50 +// ---------------------------------------------------------------------------
  258.51 +/** Helper structure representing a face with smoothing groups assigned */
  258.52 +struct FaceWithSmoothingGroup
  258.53 +{
  258.54 +	FaceWithSmoothingGroup() : iSmoothGroup(0)
  258.55 +	{
  258.56 +		// let the rest uninitialized for performance - in release builds.
  258.57 +		// in debug builds set all indices to a common magic value
  258.58 +#ifdef _DEBUG
  258.59 +		this->mIndices[0] = 0xffffffff;
  258.60 +		this->mIndices[1] = 0xffffffff;
  258.61 +		this->mIndices[2] = 0xffffffff;
  258.62 +#endif
  258.63 +	}
  258.64 +
  258.65 +	
  258.66 +	//! Indices. .3ds is using uint16. However, after
  258.67 +	//! an unique vrtex set has been generated,
  258.68 +	//! individual index values might exceed 2^16
  258.69 +	uint32_t mIndices[3];
  258.70 +
  258.71 +	//! specifies to which smoothing group the face belongs to
  258.72 +	uint32_t iSmoothGroup;
  258.73 +};
  258.74 +
  258.75 +// ---------------------------------------------------------------------------
  258.76 +/** Helper structure representing a mesh whose faces have smoothing
  258.77 +    groups assigned. This allows us to reuse the code for normal computations 
  258.78 +	from smoothings groups for several loaders (3DS, ASE). All of them 
  258.79 +	use face structures which inherit from #FaceWithSmoothingGroup,
  258.80 +	but as they add extra members and need to be copied by value we
  258.81 +	need to use a template here.
  258.82 +	*/
  258.83 +template <class T>
  258.84 +struct MeshWithSmoothingGroups
  258.85 +{
  258.86 +	//! Vertex positions
  258.87 +	std::vector<aiVector3D> mPositions;
  258.88 +
  258.89 +	//! Face lists
  258.90 +	std::vector<T> mFaces;
  258.91 +
  258.92 +	//! List of normal vectors
  258.93 +	std::vector<aiVector3D> mNormals;
  258.94 +};
  258.95 +
  258.96 +// ---------------------------------------------------------------------------
  258.97 +/** Computes normal vectors for the mesh
  258.98 + */
  258.99 +template <class T>
 258.100 +void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh);
 258.101 +
 258.102 +
 258.103 +// include implementations
 258.104 +#include "SmoothingGroups.inl"
 258.105 +
 258.106 +#endif // !! AI_SMOOTHINGGROUPS_H_INC
   259.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   259.2 +++ b/libs/assimp/SmoothingGroups.inl	Sat Feb 01 19:58:19 2014 +0200
   259.3 @@ -0,0 +1,138 @@
   259.4 +/*
   259.5 +---------------------------------------------------------------------------
   259.6 +Open Asset Import Library (assimp)
   259.7 +---------------------------------------------------------------------------
   259.8 +
   259.9 +Copyright (c) 2006-2012, assimp team
  259.10 +
  259.11 +All rights reserved.
  259.12 +
  259.13 +Redistribution and use of this software in source and binary forms, 
  259.14 +with or without modification, are permitted provided that the following 
  259.15 +conditions are met:
  259.16 +
  259.17 +* Redistributions of source code must retain the above
  259.18 +  copyright notice, this list of conditions and the
  259.19 +  following disclaimer.
  259.20 +
  259.21 +* Redistributions in binary form must reproduce the above
  259.22 +  copyright notice, this list of conditions and the
  259.23 +  following disclaimer in the documentation and/or other
  259.24 +  materials provided with the distribution.
  259.25 +
  259.26 +* Neither the name of the assimp team, nor the names of its
  259.27 +  contributors may be used to endorse or promote products
  259.28 +  derived from this software without specific prior
  259.29 +  written permission of the assimp team.
  259.30 +
  259.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  259.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  259.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  259.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  259.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  259.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  259.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  259.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  259.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  259.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  259.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  259.42 +---------------------------------------------------------------------------
  259.43 +*/
  259.44 +
  259.45 +/** @file Generation of normal vectors basing on smoothing groups */
  259.46 +
  259.47 +#ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED
  259.48 +#define AI_SMOOTHINGGROUPS_INL_INCLUDED
  259.49 +
  259.50 +// internal headers
  259.51 +#include "SGSpatialSort.h"
  259.52 +
  259.53 +// CRT header
  259.54 +#include <algorithm>
  259.55 +
  259.56 +using namespace Assimp;
  259.57 +
  259.58 +// ------------------------------------------------------------------------------------------------
  259.59 +template <class T>
  259.60 +void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
  259.61 +{
  259.62 +	// First generate face normals
  259.63 +	sMesh.mNormals.resize(sMesh.mPositions.size(),aiVector3D());
  259.64 +	for( unsigned int a = 0; a < sMesh.mFaces.size(); a++)
  259.65 +	{
  259.66 +		T& face = sMesh.mFaces[a];
  259.67 +
  259.68 +		aiVector3D* pV1 = &sMesh.mPositions[face.mIndices[0]];
  259.69 +		aiVector3D* pV2 = &sMesh.mPositions[face.mIndices[1]];
  259.70 +		aiVector3D* pV3 = &sMesh.mPositions[face.mIndices[2]];
  259.71 +
  259.72 +		aiVector3D pDelta1 = *pV2 - *pV1;
  259.73 +		aiVector3D pDelta2 = *pV3 - *pV1;
  259.74 +		aiVector3D vNor = pDelta1 ^ pDelta2;
  259.75 +
  259.76 +		for (unsigned int c = 0; c < 3;++c)
  259.77 +			sMesh.mNormals[face.mIndices[c]] = vNor;
  259.78 +	}
  259.79 +
  259.80 +	// calculate the position bounds so we have a reliable epsilon to check position differences against 
  259.81 +	aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
  259.82 +	for( unsigned int a = 0; a < sMesh.mPositions.size(); a++)
  259.83 +	{
  259.84 +		minVec.x = std::min( minVec.x, sMesh.mPositions[a].x);
  259.85 +		minVec.y = std::min( minVec.y, sMesh.mPositions[a].y);
  259.86 +		minVec.z = std::min( minVec.z, sMesh.mPositions[a].z);
  259.87 +		maxVec.x = std::max( maxVec.x, sMesh.mPositions[a].x);
  259.88 +		maxVec.y = std::max( maxVec.y, sMesh.mPositions[a].y);
  259.89 +		maxVec.z = std::max( maxVec.z, sMesh.mPositions[a].z);
  259.90 +	}
  259.91 +	const float posEpsilon = (maxVec - minVec).Length() * 1e-5f;
  259.92 +	std::vector<aiVector3D> avNormals;
  259.93 +	avNormals.resize(sMesh.mNormals.size());
  259.94 +	
  259.95 +	// now generate the spatial sort tree
  259.96 +	SGSpatialSort sSort;
  259.97 +	for( typename std::vector<T>::iterator i =  sMesh.mFaces.begin();
  259.98 +		i != sMesh.mFaces.end();++i)
  259.99 +	{
 259.100 +		for (unsigned int c = 0; c < 3;++c)
 259.101 +			sSort.Add(sMesh.mPositions[(*i).mIndices[c]],(*i).mIndices[c],(*i).iSmoothGroup);
 259.102 +	}
 259.103 +	sSort.Prepare();
 259.104 +
 259.105 +	std::vector<bool> vertexDone(sMesh.mPositions.size(),false);
 259.106 +	for( typename std::vector<T>::iterator i =  sMesh.mFaces.begin();
 259.107 +		i != sMesh.mFaces.end();++i)
 259.108 +	{
 259.109 +		std::vector<unsigned int> poResult;
 259.110 +		for (unsigned int c = 0; c < 3;++c)
 259.111 +		{
 259.112 +			register unsigned int idx = (*i).mIndices[c];
 259.113 +			if (vertexDone[idx])continue;
 259.114 +
 259.115 +			sSort.FindPositions(sMesh.mPositions[idx],(*i).iSmoothGroup,
 259.116 +				posEpsilon,poResult);
 259.117 +
 259.118 +			aiVector3D vNormals;
 259.119 +			for (std::vector<unsigned int>::const_iterator
 259.120 +				a =  poResult.begin();
 259.121 +				a != poResult.end();++a)
 259.122 +			{
 259.123 +				vNormals += sMesh.mNormals[(*a)];
 259.124 +			}
 259.125 +			vNormals.Normalize();
 259.126 +
 259.127 +			// write back into all affected normals
 259.128 +			for (std::vector<unsigned int>::const_iterator
 259.129 +				a =  poResult.begin();
 259.130 +				a != poResult.end();++a)
 259.131 +			{
 259.132 +				idx = *a;
 259.133 +				avNormals [idx] = vNormals;
 259.134 +				vertexDone[idx] = true;
 259.135 +			}
 259.136 +		}
 259.137 +	}
 259.138 +	sMesh.mNormals = avNormals;
 259.139 +}
 259.140 +
 259.141 +#endif // !! AI_SMOOTHINGGROUPS_INL_INCLUDED
   260.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   260.2 +++ b/libs/assimp/SortByPTypeProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
   260.3 @@ -0,0 +1,405 @@
   260.4 +/*
   260.5 +---------------------------------------------------------------------------
   260.6 +Open Asset Import Library (assimp)
   260.7 +---------------------------------------------------------------------------
   260.8 +
   260.9 +Copyright (c) 2006-2012, assimp team
  260.10 +
  260.11 +All rights reserved.
  260.12 +
  260.13 +Redistribution and use of this software in source and binary forms, 
  260.14 +with or without modification, are permitted provided that the following 
  260.15 +conditions are met:
  260.16 +
  260.17 +* Redistributions of source code must retain the above
  260.18 +  copyright notice, this list of conditions and the
  260.19 +  following disclaimer.
  260.20 +
  260.21 +* Redistributions in binary form must reproduce the above
  260.22 +  copyright notice, this list of conditions and the
  260.23 +  following disclaimer in the documentation and/or other
  260.24 +  materials provided with the distribution.
  260.25 +
  260.26 +* Neither the name of the assimp team, nor the names of its
  260.27 +  contributors may be used to endorse or promote products
  260.28 +  derived from this software without specific prior
  260.29 +  written permission of the assimp team.
  260.30 +
  260.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  260.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  260.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  260.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  260.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  260.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  260.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  260.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  260.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  260.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  260.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  260.42 +---------------------------------------------------------------------------
  260.43 +*/
  260.44 +
  260.45 +/** @file Implementation of the DeterminePTypeHelperProcess and
  260.46 + *  SortByPTypeProcess post-process steps.
  260.47 +*/
  260.48 +
  260.49 +#include "AssimpPCH.h"
  260.50 +
  260.51 +// internal headers
  260.52 +#include "ProcessHelper.h"
  260.53 +#include "SortByPTypeProcess.h"
  260.54 +
  260.55 +using namespace Assimp;
  260.56 +
  260.57 +// ------------------------------------------------------------------------------------------------
  260.58 +// Constructor to be privately used by Importer
  260.59 +SortByPTypeProcess::SortByPTypeProcess()
  260.60 +{
  260.61 +	configRemoveMeshes = 0;
  260.62 +}
  260.63 +
  260.64 +// ------------------------------------------------------------------------------------------------
  260.65 +// Destructor, private as well
  260.66 +SortByPTypeProcess::~SortByPTypeProcess()
  260.67 +{
  260.68 +	// nothing to do here
  260.69 +}
  260.70 +
  260.71 +// ------------------------------------------------------------------------------------------------
  260.72 +// Returns whether the processing step is present in the given flag field.
  260.73 +bool SortByPTypeProcess::IsActive( unsigned int pFlags) const
  260.74 +{
  260.75 +	return	(pFlags & aiProcess_SortByPType) != 0;
  260.76 +}
  260.77 +
  260.78 +// ------------------------------------------------------------------------------------------------
  260.79 +void SortByPTypeProcess::SetupProperties(const Importer* pImp)
  260.80 +{
  260.81 +	configRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,0);
  260.82 +}
  260.83 +
  260.84 +// ------------------------------------------------------------------------------------------------
  260.85 +// Update changed meshes in all nodes
  260.86 +void UpdateNodes(const std::vector<unsigned int>& replaceMeshIndex, aiNode* node)
  260.87 +{
  260.88 +//	std::vector<unsigned int>::const_iterator it;
  260.89 +
  260.90 +	if (node->mNumMeshes)
  260.91 +	{
  260.92 +		unsigned int newSize = 0;
  260.93 +		for (unsigned int m = 0; m< node->mNumMeshes; ++m)
  260.94 +		{
  260.95 +			unsigned int add = node->mMeshes[m]<<2;
  260.96 +			for (unsigned int i = 0; i < 4;++i)
  260.97 +			{
  260.98 +				if (UINT_MAX != replaceMeshIndex[add+i])++newSize;
  260.99 +			}
 260.100 +		}
 260.101 +		if (!newSize)
 260.102 +		{
 260.103 +			delete[] node->mMeshes;
 260.104 +			node->mNumMeshes = 0;
 260.105 +			node->mMeshes    = NULL;
 260.106 +		}
 260.107 +		else
 260.108 +		{
 260.109 +			// Try to reuse the old array if possible
 260.110 +			unsigned int* newMeshes = (newSize > node->mNumMeshes 
 260.111 +				? new unsigned int[newSize] : node->mMeshes);
 260.112 +
 260.113 +			for (unsigned int m = 0; m< node->mNumMeshes; ++m)
 260.114 +			{
 260.115 +				unsigned int add = node->mMeshes[m]<<2;
 260.116 +				for (unsigned int i = 0; i < 4;++i)
 260.117 +				{
 260.118 +					if (UINT_MAX != replaceMeshIndex[add+i])
 260.119 +						*newMeshes++ = replaceMeshIndex[add+i];
 260.120 +				}
 260.121 +			}
 260.122 +			if (newSize > node->mNumMeshes)
 260.123 +				delete[] node->mMeshes;
 260.124 +
 260.125 +			node->mMeshes = newMeshes-(node->mNumMeshes = newSize);
 260.126 +		}
 260.127 +	}
 260.128 +
 260.129 +	// call all subnodes recursively
 260.130 +	for (unsigned int m = 0; m < node->mNumChildren; ++m)
 260.131 +		UpdateNodes(replaceMeshIndex,node->mChildren[m]);
 260.132 +}
 260.133 +
 260.134 +// ------------------------------------------------------------------------------------------------
 260.135 +// Executes the post processing step on the given imported data.
 260.136 +void SortByPTypeProcess::Execute( aiScene* pScene)
 260.137 +{
 260.138 +	if (!pScene->mNumMeshes)
 260.139 +	{
 260.140 +		DefaultLogger::get()->debug("SortByPTypeProcess skipped, there are no meshes");
 260.141 +		return;
 260.142 +	}
 260.143 +
 260.144 +	DefaultLogger::get()->debug("SortByPTypeProcess begin");
 260.145 +
 260.146 +	unsigned int aiNumMeshesPerPType[4] = {0,0,0,0};
 260.147 +
 260.148 +	std::vector<aiMesh*> outMeshes;
 260.149 +	outMeshes.reserve(pScene->mNumMeshes<<1u);
 260.150 +
 260.151 +	bool bAnyChanges = false;
 260.152 +
 260.153 +	std::vector<unsigned int> replaceMeshIndex(pScene->mNumMeshes*4,UINT_MAX);
 260.154 +	std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
 260.155 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
 260.156 +	{
 260.157 +		aiMesh* mesh = pScene->mMeshes[i];
 260.158 +		ai_assert(0 != mesh->mPrimitiveTypes);
 260.159 +
 260.160 +		// if there's just one primitive type in the mesh there's nothing to do for us
 260.161 +		unsigned int num = 0;
 260.162 +		if (mesh->mPrimitiveTypes & aiPrimitiveType_POINT) 
 260.163 +		{
 260.164 +			++aiNumMeshesPerPType[0];
 260.165 +			++num;
 260.166 +		}
 260.167 +		if (mesh->mPrimitiveTypes & aiPrimitiveType_LINE)   
 260.168 +		{
 260.169 +			++aiNumMeshesPerPType[1];
 260.170 +			++num;
 260.171 +		}
 260.172 +		if (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE)
 260.173 +		{
 260.174 +			++aiNumMeshesPerPType[2];
 260.175 +			++num;
 260.176 +		}
 260.177 +		if (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)
 260.178 +		{
 260.179 +			++aiNumMeshesPerPType[3];
 260.180 +			++num;
 260.181 +		}
 260.182 +
 260.183 +		if (1 == num)
 260.184 +		{
 260.185 +			if (!(configRemoveMeshes & mesh->mPrimitiveTypes))
 260.186 +			{
 260.187 +				*meshIdx = (unsigned int) outMeshes.size();
 260.188 +				outMeshes.push_back(mesh);
 260.189 +			}
 260.190 +			else bAnyChanges = true;
 260.191 +
 260.192 +			meshIdx += 4;
 260.193 +			continue;
 260.194 +		}
 260.195 +		bAnyChanges = true;
 260.196 +
 260.197 +		// reuse our current mesh arrays for the submesh 
 260.198 +		// with the largest numer of primitives
 260.199 +		unsigned int aiNumPerPType[4] = {0,0,0,0};
 260.200 +		aiFace* pFirstFace = mesh->mFaces;
 260.201 +		aiFace* const pLastFace = pFirstFace + mesh->mNumFaces;
 260.202 +
 260.203 +		unsigned int numPolyVerts = 0;
 260.204 +		for (;pFirstFace != pLastFace; ++pFirstFace)
 260.205 +		{
 260.206 +			if (pFirstFace->mNumIndices <= 3)
 260.207 +				++aiNumPerPType[pFirstFace->mNumIndices-1];
 260.208 +			else
 260.209 +			{
 260.210 +				++aiNumPerPType[3];
 260.211 +				numPolyVerts += pFirstFace-> mNumIndices;
 260.212 +			}
 260.213 +		}
 260.214 +
 260.215 +		VertexWeightTable* avw = ComputeVertexBoneWeightTable(mesh);
 260.216 +		for (unsigned int real = 0; real < 4; ++real,++meshIdx)
 260.217 +		{
 260.218 +			if ( !aiNumPerPType[real] || configRemoveMeshes & (1u << real))
 260.219 +			{
 260.220 +				continue;
 260.221 +			}
 260.222 +
 260.223 +			*meshIdx = (unsigned int) outMeshes.size();
 260.224 +			outMeshes.push_back(new aiMesh());
 260.225 +			aiMesh* out = outMeshes.back();
 260.226 +
 260.227 +			// the name carries the adjacency information between the meshes
 260.228 +			out->mName = mesh->mName;
 260.229 +
 260.230 +			// copy data members
 260.231 +			out->mPrimitiveTypes = 1u << real;
 260.232 +			out->mMaterialIndex = mesh->mMaterialIndex;
 260.233 +
 260.234 +			// allocate output storage
 260.235 +			out->mNumFaces = aiNumPerPType[real];
 260.236 +			aiFace* outFaces = out->mFaces = new aiFace[out->mNumFaces];
 260.237 +
 260.238 +			out->mNumVertices = (3 == real ? numPolyVerts : out->mNumFaces * (real+1));
 260.239 +
 260.240 +			aiVector3D *vert(NULL), *nor(NULL), *tan(NULL), *bit(NULL);
 260.241 +			aiVector3D *uv   [AI_MAX_NUMBER_OF_TEXTURECOORDS];
 260.242 +			aiColor4D  *cols [AI_MAX_NUMBER_OF_COLOR_SETS];
 260.243 +		
 260.244 +			if (mesh->mVertices)
 260.245 +				vert = out->mVertices = new aiVector3D[out->mNumVertices];
 260.246 +
 260.247 +			if (mesh->mNormals)
 260.248 +				nor  = out->mNormals  = new aiVector3D[out->mNumVertices];
 260.249 +
 260.250 +			if (mesh->mTangents)
 260.251 +			{
 260.252 +				tan = out->mTangents   = new aiVector3D[out->mNumVertices];
 260.253 +				bit = out->mBitangents = new aiVector3D[out->mNumVertices];
 260.254 +			}
 260.255 +
 260.256 +			for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
 260.257 +			{
 260.258 +				if (mesh->mTextureCoords[i])
 260.259 +					uv[i] = out->mTextureCoords[i] = new aiVector3D[out->mNumVertices];
 260.260 +				else uv[i] = NULL;
 260.261 +
 260.262 +				out->mNumUVComponents[i] = mesh->mNumUVComponents[i];
 260.263 +			}
 260.264 +
 260.265 +			for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
 260.266 +			{
 260.267 +				if (mesh->mColors[i])
 260.268 +					cols[i] = out->mColors[i] = new aiColor4D[out->mNumVertices];
 260.269 +				else cols[i] = NULL;
 260.270 +			}
 260.271 +
 260.272 +			typedef std::vector< aiVertexWeight > TempBoneInfo;
 260.273 +			std::vector< TempBoneInfo > tempBones(mesh->mNumBones);
 260.274 +
 260.275 +			// try to guess how much storage we'll need
 260.276 +			for (unsigned int q = 0; q < mesh->mNumBones;++q)
 260.277 +			{
 260.278 +				tempBones[q].reserve(mesh->mBones[q]->mNumWeights / (num-1));
 260.279 +			}
 260.280 +
 260.281 +			unsigned int outIdx = 0;
 260.282 +			for (unsigned int m = 0; m < mesh->mNumFaces; ++m)
 260.283 +			{
 260.284 +				aiFace& in = mesh->mFaces[m];
 260.285 +				if ((real == 3  && in.mNumIndices <= 3) || (real != 3 && in.mNumIndices != real+1))
 260.286 +				{
 260.287 +					continue;
 260.288 +				}
 260.289 +				
 260.290 +				outFaces->mNumIndices = in.mNumIndices;
 260.291 +				outFaces->mIndices    = in.mIndices;
 260.292 +
 260.293 +				for (unsigned int q = 0; q < in.mNumIndices; ++q)
 260.294 +				{
 260.295 +					register unsigned int idx = in.mIndices[q];
 260.296 +
 260.297 +					// process all bones of this index
 260.298 +					if (avw)
 260.299 +					{
 260.300 +						VertexWeightTable& tbl = avw[idx];
 260.301 +						for (VertexWeightTable::const_iterator it = tbl.begin(), end = tbl.end();
 260.302 +							 it != end; ++it)
 260.303 +						{
 260.304 +							tempBones[ (*it).first ].push_back( aiVertexWeight(outIdx, (*it).second) );
 260.305 +						}
 260.306 +					}
 260.307 +
 260.308 +					if (vert)
 260.309 +					{
 260.310 +						*vert++ = mesh->mVertices[idx];
 260.311 +						//mesh->mVertices[idx].x = get_qnan();
 260.312 +					}
 260.313 +					if (nor )*nor++  = mesh->mNormals[idx];
 260.314 +					if (tan )
 260.315 +					{
 260.316 +						*tan++  = mesh->mTangents[idx];
 260.317 +						*bit++  = mesh->mBitangents[idx];
 260.318 +					}
 260.319 +
 260.320 +					for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp)
 260.321 +					{
 260.322 +						if (!uv[pp])break;
 260.323 +						*uv[pp]++ = mesh->mTextureCoords[pp][idx];
 260.324 +					}
 260.325 +
 260.326 +					for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp)
 260.327 +					{
 260.328 +						if (!cols[pp])break;
 260.329 +						*cols[pp]++ = mesh->mColors[pp][idx];
 260.330 +					}
 260.331 +
 260.332 +					in.mIndices[q] = outIdx++;
 260.333 +				}
 260.334 +
 260.335 +				in.mIndices = NULL;
 260.336 +				++outFaces;
 260.337 +			}
 260.338 +			ai_assert(outFaces == out->mFaces + out->mNumFaces);
 260.339 +
 260.340 +			// now generate output bones
 260.341 +			for (unsigned int q = 0; q < mesh->mNumBones;++q)
 260.342 +				if (!tempBones[q].empty())++out->mNumBones;
 260.343 +
 260.344 +			if (out->mNumBones)
 260.345 +			{
 260.346 +				out->mBones = new aiBone*[out->mNumBones];
 260.347 +				for (unsigned int q = 0, real = 0; q < mesh->mNumBones;++q)
 260.348 +				{
 260.349 +					TempBoneInfo& in = tempBones[q];
 260.350 +					if (in.empty())continue;
 260.351 +
 260.352 +					aiBone* srcBone = mesh->mBones[q];
 260.353 +					aiBone* bone = out->mBones[real] = new aiBone();
 260.354 +
 260.355 +					bone->mName = srcBone->mName;
 260.356 +					bone->mOffsetMatrix = srcBone->mOffsetMatrix;
 260.357 +
 260.358 +					bone->mNumWeights = (unsigned int)in.size();
 260.359 +					bone->mWeights = new aiVertexWeight[bone->mNumWeights];
 260.360 +
 260.361 +					::memcpy(bone->mWeights,&in[0],bone->mNumWeights*sizeof(aiVertexWeight));
 260.362 +
 260.363 +					++real;
 260.364 +				}
 260.365 +			}
 260.366 +		}
 260.367 +
 260.368 +		// delete the per-vertex bone weights table
 260.369 +		delete[] avw;
 260.370 +
 260.371 +		// delete the input mesh
 260.372 +		delete mesh;
 260.373 +	}
 260.374 +
 260.375 +	if (outMeshes.empty())
 260.376 +	{
 260.377 +		// This should not occur
 260.378 +		throw DeadlyImportError("No meshes remaining");
 260.379 +	}
 260.380 +
 260.381 +	// If we added at least one mesh process all nodes in the node
 260.382 +	// graph and update their respective mesh indices.
 260.383 +	if (bAnyChanges)
 260.384 +	{
 260.385 +		UpdateNodes(replaceMeshIndex,pScene->mRootNode);
 260.386 +	}
 260.387 +
 260.388 +	if (outMeshes.size() != pScene->mNumMeshes)
 260.389 +	{
 260.390 +		delete[] pScene->mMeshes;
 260.391 +		pScene->mNumMeshes = (unsigned int)outMeshes.size();
 260.392 +		pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
 260.393 +	}
 260.394 +	::memcpy(pScene->mMeshes,&outMeshes[0],pScene->mNumMeshes*sizeof(void*));
 260.395 +
 260.396 +	if (!DefaultLogger::isNullLogger())
 260.397 +	{
 260.398 +		char buffer[1024];
 260.399 +		::sprintf(buffer,"Points: %i%s, Lines: %i%s, Triangles: %i%s, Polygons: %i%s (Meshes, X = removed)",
 260.400 +			aiNumMeshesPerPType[0], (configRemoveMeshes & aiPrimitiveType_POINT     ? "X" : ""),
 260.401 +			aiNumMeshesPerPType[1], (configRemoveMeshes & aiPrimitiveType_LINE      ? "X" : ""),
 260.402 +			aiNumMeshesPerPType[2], (configRemoveMeshes & aiPrimitiveType_TRIANGLE  ? "X" : ""),
 260.403 +			aiNumMeshesPerPType[3], (configRemoveMeshes & aiPrimitiveType_POLYGON   ? "X" : ""));
 260.404 +		DefaultLogger::get()->info(buffer);
 260.405 +		DefaultLogger::get()->debug("SortByPTypeProcess finished");
 260.406 +	}
 260.407 +}
 260.408 +
   261.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   261.2 +++ b/libs/assimp/SortByPTypeProcess.h	Sat Feb 01 19:58:19 2014 +0200
   261.3 @@ -0,0 +1,83 @@
   261.4 +/*
   261.5 +Open Asset Import Library (assimp)
   261.6 +----------------------------------------------------------------------
   261.7 +
   261.8 +Copyright (c) 2006-2012, assimp team
   261.9 +All rights reserved.
  261.10 +
  261.11 +Redistribution and use of this software in source and binary forms, 
  261.12 +with or without modification, are permitted provided that the 
  261.13 +following conditions are met:
  261.14 +
  261.15 +* Redistributions of source code must retain the above
  261.16 +  copyright notice, this list of conditions and the
  261.17 +  following disclaimer.
  261.18 +
  261.19 +* Redistributions in binary form must reproduce the above
  261.20 +  copyright notice, this list of conditions and the
  261.21 +  following disclaimer in the documentation and/or other
  261.22 +  materials provided with the distribution.
  261.23 +
  261.24 +* Neither the name of the assimp team, nor the names of its
  261.25 +  contributors may be used to endorse or promote products
  261.26 +  derived from this software without specific prior
  261.27 +  written permission of the assimp team.
  261.28 +
  261.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  261.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  261.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  261.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  261.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  261.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  261.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  261.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  261.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  261.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  261.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  261.40 +
  261.41 +----------------------------------------------------------------------
  261.42 +*/
  261.43 +
  261.44 +/** @file Defines a post processing step to sort meshes by the types 
  261.45 +    of primitives they contain */
  261.46 +#ifndef AI_SORTBYPTYPEPROCESS_H_INC
  261.47 +#define AI_SORTBYPTYPEPROCESS_H_INC
  261.48 +
  261.49 +#include "BaseProcess.h"
  261.50 +#include "assimp/mesh.h"
  261.51 +
  261.52 +class SortByPTypeProcessTest;
  261.53 +namespace Assimp	{
  261.54 +
  261.55 +
  261.56 +// ---------------------------------------------------------------------------
  261.57 +/** SortByPTypeProcess: Sorts meshes by the types of primitives they contain.
  261.58 + *  A mesh with 5 lines, 3 points and 145 triangles would be split in 3 
  261.59 + * submeshes.
  261.60 +*/
  261.61 +class SortByPTypeProcess : public BaseProcess
  261.62 +{
  261.63 +public:
  261.64 +
  261.65 +	SortByPTypeProcess();
  261.66 +	~SortByPTypeProcess();
  261.67 +
  261.68 +public:
  261.69 +	// -------------------------------------------------------------------
  261.70 +	bool IsActive( unsigned int pFlags) const;
  261.71 +
  261.72 +	// -------------------------------------------------------------------
  261.73 +	void Execute( aiScene* pScene);
  261.74 +
  261.75 +	// -------------------------------------------------------------------
  261.76 +	void SetupProperties(const Importer* pImp);
  261.77 +
  261.78 +private:
  261.79 +
  261.80 +	int configRemoveMeshes;
  261.81 +};
  261.82 +
  261.83 +
  261.84 +} // end of namespace Assimp
  261.85 +
  261.86 +#endif // !!AI_SORTBYPTYPEPROCESS_H_INC
   262.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   262.2 +++ b/libs/assimp/SpatialSort.cpp	Sat Feb 01 19:58:19 2014 +0200
   262.3 @@ -0,0 +1,342 @@
   262.4 +/*
   262.5 +---------------------------------------------------------------------------
   262.6 +Open Asset Import Library (assimp)
   262.7 +---------------------------------------------------------------------------
   262.8 +
   262.9 +Copyright (c) 2006-2012, assimp team
  262.10 +
  262.11 +All rights reserved.
  262.12 +
  262.13 +Redistribution and use of this software in source and binary forms, 
  262.14 +with or without modification, are permitted provided that the following 
  262.15 +conditions are met:
  262.16 +
  262.17 +* Redistributions of source code must retain the above
  262.18 +  copyright notice, this list of conditions and the
  262.19 +  following disclaimer.
  262.20 +
  262.21 +* Redistributions in binary form must reproduce the above
  262.22 +  copyright notice, this list of conditions and the
  262.23 +  following disclaimer in the documentation and/or other
  262.24 +  materials provided with the distribution.
  262.25 +
  262.26 +* Neither the name of the assimp team, nor the names of its
  262.27 +  contributors may be used to endorse or promote products
  262.28 +  derived from this software without specific prior
  262.29 +  written permission of the assimp team.
  262.30 +
  262.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  262.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  262.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  262.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  262.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  262.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  262.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  262.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  262.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  262.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  262.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  262.42 +---------------------------------------------------------------------------
  262.43 +*/
  262.44 +
  262.45 +/** @file Implementation of the helper class to quickly find vertices close to a given position */
  262.46 +
  262.47 +#include "AssimpPCH.h"
  262.48 +#include "SpatialSort.h"
  262.49 +
  262.50 +using namespace Assimp;
  262.51 +
  262.52 +// CHAR_BIT seems to be defined under MVSC, but not under GCC. Pray that the correct value is 8.
  262.53 +#ifndef CHAR_BIT
  262.54 +#	define CHAR_BIT 8
  262.55 +#endif
  262.56 +
  262.57 +// ------------------------------------------------------------------------------------------------
  262.58 +// Constructs a spatially sorted representation from the given position array.
  262.59 +SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions, 
  262.60 +	unsigned int pElementOffset)
  262.61 +
  262.62 +	// define the reference plane. We choose some arbitrary vector away from all basic axises 
  262.63 +	// in the hope that no model spreads all its vertices along this plane.
  262.64 +	: mPlaneNormal(0.8523f, 0.34321f, 0.5736f)
  262.65 +{
  262.66 +	mPlaneNormal.Normalize();
  262.67 +	Fill(pPositions,pNumPositions,pElementOffset);
  262.68 +}
  262.69 +
  262.70 +// ------------------------------------------------------------------------------------------------
  262.71 +SpatialSort :: SpatialSort()
  262.72 +: mPlaneNormal(0.8523f, 0.34321f, 0.5736f)
  262.73 +{
  262.74 +	mPlaneNormal.Normalize();
  262.75 +}
  262.76 +
  262.77 +// ------------------------------------------------------------------------------------------------
  262.78 +// Destructor
  262.79 +SpatialSort::~SpatialSort()
  262.80 +{
  262.81 +	// nothing to do here, everything destructs automatically
  262.82 +}
  262.83 +
  262.84 +// ------------------------------------------------------------------------------------------------
  262.85 +void SpatialSort::Fill( const aiVector3D* pPositions, unsigned int pNumPositions, 
  262.86 +	unsigned int pElementOffset,
  262.87 +	bool pFinalize /*= true */)
  262.88 +{
  262.89 +	mPositions.clear();
  262.90 +	Append(pPositions,pNumPositions,pElementOffset,pFinalize);
  262.91 +}
  262.92 +
  262.93 +// ------------------------------------------------------------------------------------------------
  262.94 +void SpatialSort :: Finalize()
  262.95 +{
  262.96 +	std::sort( mPositions.begin(), mPositions.end());
  262.97 +}
  262.98 +
  262.99 +// ------------------------------------------------------------------------------------------------
 262.100 +void SpatialSort::Append( const aiVector3D* pPositions, unsigned int pNumPositions, 
 262.101 +	unsigned int pElementOffset,
 262.102 +	bool pFinalize /*= true */)
 262.103 +{
 262.104 +	// store references to all given positions along with their distance to the reference plane
 262.105 +	const size_t initial = mPositions.size();
 262.106 +	mPositions.reserve(initial + (pFinalize?pNumPositions:pNumPositions*2));
 262.107 +	for( unsigned int a = 0; a < pNumPositions; a++)
 262.108 +	{
 262.109 +		const char* tempPointer = reinterpret_cast<const char*> (pPositions);
 262.110 +		const aiVector3D* vec   = reinterpret_cast<const aiVector3D*> (tempPointer + a * pElementOffset);
 262.111 +
 262.112 +		// store position by index and distance
 262.113 +		float distance = *vec * mPlaneNormal;
 262.114 +		mPositions.push_back( Entry( a+initial, *vec, distance));
 262.115 +	}
 262.116 +
 262.117 +	if (pFinalize) {
 262.118 +		// now sort the array ascending by distance.
 262.119 +		Finalize();
 262.120 +	}
 262.121 +}
 262.122 +
 262.123 +// ------------------------------------------------------------------------------------------------
 262.124 +// Returns an iterator for all positions close to the given position.
 262.125 +void SpatialSort::FindPositions( const aiVector3D& pPosition, 
 262.126 +	float pRadius, std::vector<unsigned int>& poResults) const
 262.127 +{
 262.128 +	const float dist = pPosition * mPlaneNormal;
 262.129 +	const float minDist = dist - pRadius, maxDist = dist + pRadius;
 262.130 +
 262.131 +	// clear the array in this strange fashion because a simple clear() would also deallocate
 262.132 +    // the array which we want to avoid
 262.133 +	poResults.erase( poResults.begin(), poResults.end());
 262.134 +
 262.135 +	// quick check for positions outside the range
 262.136 +	if( mPositions.size() == 0)
 262.137 +		return;
 262.138 +	if( maxDist < mPositions.front().mDistance)
 262.139 +		return;
 262.140 +	if( minDist > mPositions.back().mDistance)
 262.141 +		return;
 262.142 +
 262.143 +	// do a binary search for the minimal distance to start the iteration there
 262.144 +	unsigned int index = (unsigned int)mPositions.size() / 2;
 262.145 +	unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
 262.146 +	while( binaryStepSize > 1)
 262.147 +	{
 262.148 +		if( mPositions[index].mDistance < minDist)
 262.149 +			index += binaryStepSize;
 262.150 +		else
 262.151 +			index -= binaryStepSize;
 262.152 +
 262.153 +		binaryStepSize /= 2;
 262.154 +	}
 262.155 +
 262.156 +	// depending on the direction of the last step we need to single step a bit back or forth
 262.157 +	// to find the actual beginning element of the range
 262.158 +	while( index > 0 && mPositions[index].mDistance > minDist)
 262.159 +		index--;
 262.160 +	while( index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist)
 262.161 +		index++;
 262.162 +	
 262.163 +	// Mow start iterating from there until the first position lays outside of the distance range.
 262.164 +	// Add all positions inside the distance range within the given radius to the result aray
 262.165 +	std::vector<Entry>::const_iterator it = mPositions.begin() + index;
 262.166 +	const float pSquared = pRadius*pRadius;
 262.167 +	while( it->mDistance < maxDist)
 262.168 +	{
 262.169 +		if( (it->mPosition - pPosition).SquareLength() < pSquared)
 262.170 +			poResults.push_back( it->mIndex);
 262.171 +		++it;
 262.172 +		if( it == mPositions.end())
 262.173 +			break;
 262.174 +	}
 262.175 +
 262.176 +	// that's it
 262.177 +}
 262.178 +
 262.179 +namespace {
 262.180 +
 262.181 +	// Binary, signed-integer representation of a single-precision floating-point value.
 262.182 +	// IEEE 754 says: "If two floating-point numbers in the same format are ordered then they are
 262.183 +	//	ordered the same way when their bits are reinterpreted as sign-magnitude integers."
 262.184 +	// This allows us to convert all floating-point numbers to signed integers of arbitrary size
 262.185 +	//	and then use them to work with ULPs (Units in the Last Place, for high-precision
 262.186 +	//	computations) or to compare them (integer comparisons are faster than floating-point
 262.187 +	//	comparisons on many platforms).
 262.188 +	typedef signed int BinFloat;
 262.189 +
 262.190 +	// --------------------------------------------------------------------------------------------
 262.191 +	// Converts the bit pattern of a floating-point number to its signed integer representation.
 262.192 +	BinFloat ToBinary( const float & pValue) {
 262.193 +
 262.194 +		// If this assertion fails, signed int is not big enough to store a float on your platform.
 262.195 +		//	Please correct the declaration of BinFloat a few lines above - but do it in a portable,
 262.196 +		//	#ifdef'd manner!
 262.197 +		BOOST_STATIC_ASSERT( sizeof(BinFloat) >= sizeof(float));
 262.198 +
 262.199 +		#if defined( _MSC_VER)
 262.200 +			// If this assertion fails, Visual C++ has finally moved to ILP64. This means that this
 262.201 +			//	code has just become legacy code! Find out the current value of _MSC_VER and modify
 262.202 +			//	the #if above so it evaluates false on the current and all upcoming VC versions (or
 262.203 +			//	on the current platform, if LP64 or LLP64 are still used on other platforms).
 262.204 +			BOOST_STATIC_ASSERT( sizeof(BinFloat) == sizeof(float));
 262.205 +
 262.206 +			// This works best on Visual C++, but other compilers have their problems with it.
 262.207 +			const BinFloat binValue = reinterpret_cast<BinFloat const &>(pValue);
 262.208 +		#else
 262.209 +			// On many compilers, reinterpreting a float address as an integer causes aliasing
 262.210 +			// problems. This is an ugly but more or less safe way of doing it.
 262.211 +			union {
 262.212 +				float		asFloat;
 262.213 +				BinFloat	asBin;
 262.214 +			} conversion;
 262.215 +			conversion.asBin	= 0; // zero empty space in case sizeof(BinFloat) > sizeof(float)
 262.216 +			conversion.asFloat	= pValue;
 262.217 +			const BinFloat binValue = conversion.asBin;
 262.218 +		#endif
 262.219 +
 262.220 +		// floating-point numbers are of sign-magnitude format, so find out what signed number
 262.221 +		//	representation we must convert negative values to.
 262.222 +		// See http://en.wikipedia.org/wiki/Signed_number_representations.
 262.223 +
 262.224 +		// Two's complement?
 262.225 +		if( (-42 == (~42 + 1)) && (binValue & 0x80000000))
 262.226 +			return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
 262.227 +		// One's complement?
 262.228 +		else if( (-42 == ~42) && (binValue & 0x80000000))
 262.229 +			return BinFloat(-0) - binValue;
 262.230 +		// Sign-magnitude?
 262.231 +		else if( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary
 262.232 +			return binValue;
 262.233 +		else
 262.234 +			return binValue;
 262.235 +	}
 262.236 +
 262.237 +} // namespace
 262.238 +
 262.239 +// ------------------------------------------------------------------------------------------------
 262.240 +// Fills an array with indices of all positions indentical to the given position. In opposite to
 262.241 +// FindPositions(), not an epsilon is used but a (very low) tolerance of four floating-point units.
 262.242 +void SpatialSort::FindIdenticalPositions( const aiVector3D& pPosition, 
 262.243 +	std::vector<unsigned int>& poResults) const
 262.244 +{
 262.245 +	// Epsilons have a huge disadvantage: they are of constant precision, while floating-point
 262.246 +	//	values are of log2 precision. If you apply e=0.01 to 100, the epsilon is rather small, but
 262.247 +	//	if you apply it to 0.001, it is enormous.
 262.248 +
 262.249 +	// The best way to overcome this is the unit in the last place (ULP). A precision of 2 ULPs
 262.250 +	//	tells us that a float does not differ more than 2 bits from the "real" value. ULPs are of
 262.251 +	//	logarithmic precision - around 1, they are 1÷(2^24) and around 10000, they are 0.00125.
 262.252 +
 262.253 +	// For standard C math, we can assume a precision of 0.5 ULPs according to IEEE 754. The
 262.254 +	//	incoming vertex positions might have already been transformed, probably using rather
 262.255 +	//	inaccurate SSE instructions, so we assume a tolerance of 4 ULPs to safely identify
 262.256 +	//	identical vertex positions.
 262.257 +	static const int toleranceInULPs = 4;
 262.258 +	// An interesting point is that the inaccuracy grows linear with the number of operations:
 262.259 +	//	multiplying to numbers, each inaccurate to four ULPs, results in an inaccuracy of four ULPs
 262.260 +	//	plus 0.5 ULPs for the multiplication.
 262.261 +	// To compute the distance to the plane, a dot product is needed - that is a multiplication and
 262.262 +	//	an addition on each number.
 262.263 +	static const int distanceToleranceInULPs = toleranceInULPs + 1;
 262.264 +	// The squared distance between two 3D vectors is computed the same way, but with an additional
 262.265 +	//	subtraction.
 262.266 +	static const int distance3DToleranceInULPs = distanceToleranceInULPs + 1;
 262.267 +
 262.268 +	// Convert the plane distance to its signed integer representation so the ULPs tolerance can be
 262.269 +	//	applied. For some reason, VC won't optimize two calls of the bit pattern conversion.
 262.270 +	const BinFloat minDistBinary = ToBinary( pPosition * mPlaneNormal) - distanceToleranceInULPs;
 262.271 +	const BinFloat maxDistBinary = minDistBinary + 2 * distanceToleranceInULPs;
 262.272 +
 262.273 +	// clear the array in this strange fashion because a simple clear() would also deallocate
 262.274 +    // the array which we want to avoid
 262.275 +	poResults.erase( poResults.begin(), poResults.end());
 262.276 +
 262.277 +	// do a binary search for the minimal distance to start the iteration there
 262.278 +	unsigned int index = (unsigned int)mPositions.size() / 2;
 262.279 +	unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
 262.280 +	while( binaryStepSize > 1)
 262.281 +	{
 262.282 +		// Ugly, but conditional jumps are faster with integers than with floats
 262.283 +		if( minDistBinary > ToBinary(mPositions[index].mDistance))
 262.284 +			index += binaryStepSize;
 262.285 +		else
 262.286 +			index -= binaryStepSize;
 262.287 +
 262.288 +		binaryStepSize /= 2;
 262.289 +	}
 262.290 +
 262.291 +	// depending on the direction of the last step we need to single step a bit back or forth
 262.292 +	// to find the actual beginning element of the range
 262.293 +	while( index > 0 && minDistBinary < ToBinary(mPositions[index].mDistance) )
 262.294 +		index--;
 262.295 +	while( index < (mPositions.size() - 1) && minDistBinary > ToBinary(mPositions[index].mDistance))
 262.296 +		index++;
 262.297 +
 262.298 +	// Now start iterating from there until the first position lays outside of the distance range.
 262.299 +	// Add all positions inside the distance range within the tolerance to the result aray
 262.300 +	std::vector<Entry>::const_iterator it = mPositions.begin() + index;
 262.301 +	while( ToBinary(it->mDistance) < maxDistBinary)
 262.302 +	{
 262.303 +		if( distance3DToleranceInULPs >= ToBinary((it->mPosition - pPosition).SquareLength()))
 262.304 +			poResults.push_back(it->mIndex);
 262.305 +		++it;
 262.306 +		if( it == mPositions.end())
 262.307 +			break;
 262.308 +	}
 262.309 +
 262.310 +	// that's it
 262.311 +}
 262.312 +
 262.313 +// ------------------------------------------------------------------------------------------------
 262.314 +unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int>& fill,float pRadius) const
 262.315 +{
 262.316 +	fill.resize(mPositions.size(),UINT_MAX);
 262.317 +	float dist, maxDist;
 262.318 +
 262.319 +	unsigned int t=0;
 262.320 +	const float pSquared = pRadius*pRadius;
 262.321 +	for (size_t i = 0; i < mPositions.size();) {
 262.322 +		dist = mPositions[i].mPosition * mPlaneNormal;
 262.323 +		maxDist = dist + pRadius;
 262.324 +
 262.325 +		fill[mPositions[i].mIndex] = t;
 262.326 +		const aiVector3D& oldpos = mPositions[i].mPosition;
 262.327 +		for (++i; i < fill.size() && mPositions[i].mDistance < maxDist 
 262.328 +			&& (mPositions[i].mPosition - oldpos).SquareLength() < pSquared; ++i) 
 262.329 +		{
 262.330 +			fill[mPositions[i].mIndex] = t;
 262.331 +		}
 262.332 +		++t;
 262.333 +	}
 262.334 +
 262.335 +#ifdef _DEBUG
 262.336 +
 262.337 +	// debug invariant: mPositions[i].mIndex values must range from 0 to mPositions.size()-1
 262.338 +	for (size_t i = 0; i < fill.size(); ++i) {
 262.339 +		ai_assert(fill[i]<mPositions.size());
 262.340 +	}
 262.341 +
 262.342 +#endif
 262.343 +	return t;
 262.344 +}
 262.345 +
   263.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   263.2 +++ b/libs/assimp/SpatialSort.h	Sat Feb 01 19:58:19 2014 +0200
   263.3 @@ -0,0 +1,170 @@
   263.4 +/*
   263.5 +Open Asset Import Library (assimp)
   263.6 +----------------------------------------------------------------------
   263.7 +
   263.8 +Copyright (c) 2006-2012, assimp team
   263.9 +All rights reserved.
  263.10 +
  263.11 +Redistribution and use of this software in source and binary forms, 
  263.12 +with or without modification, are permitted provided that the 
  263.13 +following conditions are met:
  263.14 +
  263.15 +* Redistributions of source code must retain the above
  263.16 +  copyright notice, this list of conditions and the
  263.17 +  following disclaimer.
  263.18 +
  263.19 +* Redistributions in binary form must reproduce the above
  263.20 +  copyright notice, this list of conditions and the
  263.21 +  following disclaimer in the documentation and/or other
  263.22 +  materials provided with the distribution.
  263.23 +
  263.24 +* Neither the name of the assimp team, nor the names of its
  263.25 +  contributors may be used to endorse or promote products
  263.26 +  derived from this software without specific prior
  263.27 +  written permission of the assimp team.
  263.28 +
  263.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  263.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  263.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  263.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  263.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  263.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  263.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  263.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  263.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  263.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  263.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  263.40 +
  263.41 +----------------------------------------------------------------------
  263.42 +*/
  263.43 +
  263.44 +/** Small helper classes to optimise finding vertizes close to a given location */
  263.45 +#ifndef AI_SPATIALSORT_H_INC
  263.46 +#define AI_SPATIALSORT_H_INC
  263.47 +
  263.48 +#include <vector>
  263.49 +#include "assimp/types.h"
  263.50 +
  263.51 +namespace Assimp
  263.52 +{
  263.53 +
  263.54 +// ------------------------------------------------------------------------------------------------
  263.55 +/** A little helper class to quickly find all vertices in the epsilon environment of a given
  263.56 + * position. Construct an instance with an array of positions. The class stores the given positions
  263.57 + * by their indices and sorts them by their distance to an arbitrary chosen plane.
  263.58 + * You can then query the instance for all vertices close to a given position in an average O(log n) 
  263.59 + * time, with O(n) worst case complexity when all vertices lay on the plane. The plane is chosen
  263.60 + * so that it avoids common planes in usual data sets. */
  263.61 +// ------------------------------------------------------------------------------------------------
  263.62 +class SpatialSort
  263.63 +{
  263.64 +public:
  263.65 +
  263.66 +	SpatialSort();
  263.67 +
  263.68 +	// ------------------------------------------------------------------------------------
  263.69 +	/** Constructs a spatially sorted representation from the given position array.
  263.70 +	 * Supply the positions in its layout in memory, the class will only refer to them
  263.71 +	 * by index.
  263.72 +	 * @param pPositions Pointer to the first position vector of the array.
  263.73 +	 * @param pNumPositions Number of vectors to expect in that array.
  263.74 +	 * @param pElementOffset Offset in bytes from the beginning of one vector in memory 
  263.75 +	 *   to the beginning of the next vector. */
  263.76 +	SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions, 
  263.77 +		unsigned int pElementOffset);
  263.78 +
  263.79 +	/** Destructor */
  263.80 +	~SpatialSort();
  263.81 +
  263.82 +public:
  263.83 +
  263.84 +	// ------------------------------------------------------------------------------------
  263.85 +	/** Sets the input data for the SpatialSort. This replaces existing data, if any.
  263.86 +	 *  The new data receives new indices in ascending order.
  263.87 +	 *
  263.88 +	 * @param pPositions Pointer to the first position vector of the array.
  263.89 +	 * @param pNumPositions Number of vectors to expect in that array.
  263.90 +	 * @param pElementOffset Offset in bytes from the beginning of one vector in memory 
  263.91 +	 *   to the beginning of the next vector. 
  263.92 +	 * @param pFinalize Specifies whether the SpatialSort's internal representation
  263.93 +	 *   is finalized after the new data has been added. Finalization is
  263.94 +	 *   required in order to use #FindPosition() or #GenerateMappingTable().
  263.95 +	 *   If you don't finalize yet, you can use #Append() to add data from
  263.96 +	 *   other sources.*/
  263.97 +	void Fill( const aiVector3D* pPositions, unsigned int pNumPositions, 
  263.98 +		unsigned int pElementOffset,
  263.99 +		bool pFinalize = true);
 263.100 +
 263.101 +
 263.102 +	// ------------------------------------------------------------------------------------
 263.103 +	/** Same as #Fill(), except the method appends to existing data in the #SpatialSort. */
 263.104 +	void Append( const aiVector3D* pPositions, unsigned int pNumPositions, 
 263.105 +		unsigned int pElementOffset,
 263.106 +		bool pFinalize = true);
 263.107 +
 263.108 +
 263.109 +	// ------------------------------------------------------------------------------------
 263.110 +	/** Finalize the spatial hash data structure. This can be useful after
 263.111 +	 *  multiple calls to #Append() with the pFinalize parameter set to false.
 263.112 +	 *  This is finally required before one of #FindPositions() and #GenerateMappingTable()
 263.113 +	 *  can be called to query the spatial sort.*/
 263.114 +	void Finalize();
 263.115 +
 263.116 +	// ------------------------------------------------------------------------------------
 263.117 +	/** Returns an iterator for all positions close to the given position.
 263.118 +	 * @param pPosition The position to look for vertices.
 263.119 +	 * @param pRadius Maximal distance from the position a vertex may have to be counted in.
 263.120 +	 * @param poResults The container to store the indices of the found positions. 
 263.121 +	 *   Will be emptied by the call so it may contain anything.
 263.122 +	 * @return An iterator to iterate over all vertices in the given area.*/
 263.123 +	void FindPositions( const aiVector3D& pPosition, float pRadius, 
 263.124 +		std::vector<unsigned int>& poResults) const;
 263.125 +
 263.126 +	// ------------------------------------------------------------------------------------
 263.127 +	/** Fills an array with indices of all positions indentical to the given position. In
 263.128 +	 *  opposite to FindPositions(), not an epsilon is used but a (very low) tolerance of
 263.129 +	 *  four floating-point units.
 263.130 +	 * @param pPosition The position to look for vertices.
 263.131 +	 * @param poResults The container to store the indices of the found positions. 
 263.132 +	 *   Will be emptied by the call so it may contain anything.*/
 263.133 +	void FindIdenticalPositions( const aiVector3D& pPosition,
 263.134 +		std::vector<unsigned int>& poResults) const;
 263.135 +
 263.136 +	// ------------------------------------------------------------------------------------
 263.137 +	/** Compute a table that maps each vertex ID referring to a spatially close
 263.138 +	 *  enough position to the same output ID. Output IDs are assigned in ascending order
 263.139 +	 *  from 0...n.
 263.140 +	 * @param fill Will be filled with numPositions entries. 
 263.141 +	 * @param pRadius Maximal distance from the position a vertex may have to
 263.142 +	 *   be counted in.
 263.143 +	 *  @return Number of unique vertices (n).  */
 263.144 +	unsigned int GenerateMappingTable(std::vector<unsigned int>& fill,
 263.145 +		float pRadius) const;
 263.146 +
 263.147 +protected:
 263.148 +	/** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */
 263.149 +	aiVector3D mPlaneNormal;
 263.150 +
 263.151 +	/** An entry in a spatially sorted position array. Consists of a vertex index,
 263.152 +	 * its position and its precalculated distance from the reference plane */
 263.153 +	struct Entry
 263.154 +	{
 263.155 +		unsigned int mIndex; ///< The vertex referred by this entry
 263.156 +		aiVector3D mPosition; ///< Position
 263.157 +		float mDistance; ///< Distance of this vertex to the sorting plane
 263.158 +
 263.159 +		Entry() { /** intentionally not initialized.*/ }
 263.160 +		Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance) 
 263.161 +			: mIndex( pIndex), mPosition( pPosition), mDistance( pDistance)
 263.162 +		{ 	}
 263.163 +
 263.164 +		bool operator < (const Entry& e) const { return mDistance < e.mDistance; }
 263.165 +	};
 263.166 +
 263.167 +	// all positions, sorted by distance to the sorting plane
 263.168 +	std::vector<Entry> mPositions;
 263.169 +};
 263.170 +
 263.171 +} // end of namespace Assimp
 263.172 +
 263.173 +#endif // AI_SPATIALSORT_H_INC
   264.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   264.2 +++ b/libs/assimp/SplitByBoneCountProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
   264.3 @@ -0,0 +1,403 @@
   264.4 +/*
   264.5 +Open Asset Import Library (assimp)
   264.6 +----------------------------------------------------------------------
   264.7 +
   264.8 +Copyright (c) 2006-2012, assimp team
   264.9 +All rights reserved.
  264.10 +
  264.11 +Redistribution and use of this software in source and binary forms, 
  264.12 +with or without modification, are permitted provided that the 
  264.13 +following conditions are met:
  264.14 +
  264.15 +* Redistributions of source code must retain the above
  264.16 +  copyright notice, this list of conditions and the
  264.17 +  following disclaimer.
  264.18 +
  264.19 +* Redistributions in binary form must reproduce the above
  264.20 +  copyright notice, this list of conditions and the
  264.21 +  following disclaimer in the documentation and/or other
  264.22 +  materials provided with the distribution.
  264.23 +
  264.24 +* Neither the name of the assimp team, nor the names of its
  264.25 +  contributors may be used to endorse or promote products
  264.26 +  derived from this software without specific prior
  264.27 +  written permission of the assimp team.
  264.28 +
  264.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  264.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  264.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  264.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  264.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  264.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  264.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  264.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  264.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  264.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  264.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  264.40 +
  264.41 +----------------------------------------------------------------------
  264.42 +*/
  264.43 +
  264.44 +
  264.45 +/// @file SplitByBoneCountProcess.cpp 
  264.46 +/// Implementation of the SplitByBoneCount postprocessing step
  264.47 +
  264.48 +#include "AssimpPCH.h"
  264.49 +
  264.50 +// internal headers of the post-processing framework
  264.51 +#include "SplitByBoneCountProcess.h"
  264.52 +
  264.53 +#include <limits>
  264.54 +
  264.55 +using namespace Assimp;
  264.56 +
  264.57 +// ------------------------------------------------------------------------------------------------
  264.58 +// Constructor
  264.59 +SplitByBoneCountProcess::SplitByBoneCountProcess()
  264.60 +{
  264.61 +	// set default, might be overriden by importer config
  264.62 +	mMaxBoneCount = AI_SBBC_DEFAULT_MAX_BONES;
  264.63 +}
  264.64 +
  264.65 +// ------------------------------------------------------------------------------------------------
  264.66 +// Destructor
  264.67 +SplitByBoneCountProcess::~SplitByBoneCountProcess()
  264.68 +{
  264.69 +	// nothing to do here
  264.70 +}
  264.71 +
  264.72 +// ------------------------------------------------------------------------------------------------
  264.73 +// Returns whether the processing step is present in the given flag.
  264.74 +bool SplitByBoneCountProcess::IsActive( unsigned int pFlags) const
  264.75 +{
  264.76 +	return !!(pFlags & aiProcess_SplitByBoneCount);
  264.77 +}
  264.78 +
  264.79 +// ------------------------------------------------------------------------------------------------
  264.80 +// Updates internal properties
  264.81 +void SplitByBoneCountProcess::SetupProperties(const Importer* pImp)
  264.82 +{
  264.83 +	mMaxBoneCount = pImp->GetPropertyInteger(AI_CONFIG_PP_SBBC_MAX_BONES,AI_SBBC_DEFAULT_MAX_BONES);
  264.84 +}
  264.85 +
  264.86 +// ------------------------------------------------------------------------------------------------
  264.87 +// Executes the post processing step on the given imported data.
  264.88 +void SplitByBoneCountProcess::Execute( aiScene* pScene)
  264.89 +{
  264.90 +	DefaultLogger::get()->debug("SplitByBoneCountProcess begin");
  264.91 +
  264.92 +	// early out 
  264.93 +	bool isNecessary = false;
  264.94 +	for( size_t a = 0; a < pScene->mNumMeshes; ++a)
  264.95 +		if( pScene->mMeshes[a]->mNumBones > mMaxBoneCount )
  264.96 +			isNecessary = true;
  264.97 +
  264.98 +	if( !isNecessary )
  264.99 +	{
 264.100 +		DefaultLogger::get()->debug( boost::str( boost::format( "SplitByBoneCountProcess early-out: no meshes with more than %d bones.") % mMaxBoneCount));
 264.101 +		return;
 264.102 +	}
 264.103 +
 264.104 +	// we need to do something. Let's go.
 264.105 +	mSubMeshIndices.clear();
 264.106 +	mSubMeshIndices.resize( pScene->mNumMeshes);
 264.107 +
 264.108 +	// build a new array of meshes for the scene
 264.109 +	std::vector<aiMesh*> meshes;
 264.110 +
 264.111 +	for( size_t a = 0; a < pScene->mNumMeshes; ++a)
 264.112 +	{
 264.113 +		aiMesh* srcMesh = pScene->mMeshes[a];
 264.114 +
 264.115 +		std::vector<aiMesh*> newMeshes;
 264.116 +		SplitMesh( pScene->mMeshes[a], newMeshes);
 264.117 +
 264.118 +		// mesh was split
 264.119 +		if( !newMeshes.empty() )
 264.120 +		{
 264.121 +			// store new meshes and indices of the new meshes
 264.122 +			for( size_t b = 0; b < newMeshes.size(); ++b)
 264.123 +			{
 264.124 +				mSubMeshIndices[a].push_back( meshes.size());
 264.125 +				meshes.push_back( newMeshes[b]);
 264.126 +			}
 264.127 +
 264.128 +			// and destroy the source mesh. It should be completely contained inside the new submeshes
 264.129 +			delete srcMesh;
 264.130 +		}
 264.131 +		else
 264.132 +		{
 264.133 +			// Mesh is kept unchanged - store it's new place in the mesh array
 264.134 +			mSubMeshIndices[a].push_back( meshes.size());
 264.135 +			meshes.push_back( srcMesh);
 264.136 +		}
 264.137 +	}
 264.138 +
 264.139 +	// rebuild the scene's mesh array
 264.140 +	pScene->mNumMeshes = meshes.size();
 264.141 +	delete [] pScene->mMeshes;
 264.142 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
 264.143 +	std::copy( meshes.begin(), meshes.end(), pScene->mMeshes);
 264.144 +
 264.145 +	// recurse through all nodes and translate the node's mesh indices to fit the new mesh array
 264.146 +	UpdateNode( pScene->mRootNode);
 264.147 +
 264.148 +	DefaultLogger::get()->debug( boost::str( boost::format( "SplitByBoneCountProcess end: split %d meshes into %d submeshes.") % mSubMeshIndices.size() % meshes.size()));
 264.149 +}
 264.150 +
 264.151 +// ------------------------------------------------------------------------------------------------
 264.152 +// Splits the given mesh by bone count.
 264.153 +void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const
 264.154 +{
 264.155 +	// skip if not necessary
 264.156 +	if( pMesh->mNumBones <= mMaxBoneCount )
 264.157 +		return;
 264.158 +
 264.159 +	// necessary optimisation: build a list of all affecting bones for each vertex
 264.160 +	// TODO: (thom) maybe add a custom allocator here to avoid allocating tens of thousands of small arrays
 264.161 +	typedef std::pair<size_t, float> BoneWeight;
 264.162 +	std::vector< std::vector<BoneWeight> > vertexBones( pMesh->mNumVertices);
 264.163 +	for( size_t a = 0; a < pMesh->mNumBones; ++a)
 264.164 +	{
 264.165 +		const aiBone* bone = pMesh->mBones[a];
 264.166 +		for( size_t b = 0; b < bone->mNumWeights; ++b)
 264.167 +			vertexBones[ bone->mWeights[b].mVertexId ].push_back( BoneWeight( a, bone->mWeights[b].mWeight));
 264.168 +	}
 264.169 +
 264.170 +	size_t numFacesHandled = 0;
 264.171 +	std::vector<bool> isFaceHandled( pMesh->mNumFaces, false);
 264.172 +	while( numFacesHandled < pMesh->mNumFaces )
 264.173 +	{
 264.174 +		// which bones are used in the current submesh
 264.175 +		size_t numBones = 0;
 264.176 +		std::vector<bool> isBoneUsed( pMesh->mNumBones, false);
 264.177 +		// indices of the faces which are going to go into this submesh
 264.178 +		std::vector<size_t> subMeshFaces;
 264.179 +		subMeshFaces.reserve( pMesh->mNumFaces);
 264.180 +		// accumulated vertex count of all the faces in this submesh
 264.181 +		size_t numSubMeshVertices = 0;
 264.182 +		// a small local array of new bones for the current face. State of all used bones for that face
 264.183 +		// can only be updated AFTER the face is completely analysed. Thanks to imre for the fix.
 264.184 +		std::vector<size_t> newBonesAtCurrentFace;
 264.185 +
 264.186 +		// add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit
 264.187 +		for( size_t a = 0; a < pMesh->mNumFaces; ++a)
 264.188 +		{
 264.189 +			// skip if the face is already stored in a submesh
 264.190 +			if( isFaceHandled[a] )
 264.191 +				continue;
 264.192 +
 264.193 +			const aiFace& face = pMesh->mFaces[a];
 264.194 +			// check every vertex if its bones would still fit into the current submesh
 264.195 +			for( size_t b = 0; b < face.mNumIndices; ++b )
 264.196 +			{
 264.197 +				const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
 264.198 +				for( size_t c = 0; c < vb.size(); ++c)
 264.199 +				{
 264.200 +					size_t boneIndex = vb[c].first;
 264.201 +					// if the bone is already used in this submesh, it's ok
 264.202 +					if( isBoneUsed[boneIndex] )
 264.203 +						continue;
 264.204 +
 264.205 +					// if it's not used, yet, we would need to add it. Store its bone index
 264.206 +					if( std::find( newBonesAtCurrentFace.begin(), newBonesAtCurrentFace.end(), boneIndex) == newBonesAtCurrentFace.end() )
 264.207 +						newBonesAtCurrentFace.push_back( boneIndex);
 264.208 +				}
 264.209 +			}
 264.210 +
 264.211 +			// leave out the face if the new bones required for this face don't fit the bone count limit anymore
 264.212 +			if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount )
 264.213 +				continue;
 264.214 +
 264.215 +			// mark all new bones as necessary
 264.216 +			while( !newBonesAtCurrentFace.empty() )
 264.217 +			{
 264.218 +				size_t newIndex = newBonesAtCurrentFace.back();
 264.219 +				newBonesAtCurrentFace.pop_back(); // this also avoids the deallocation which comes with a clear()
 264.220 +				if( isBoneUsed[newIndex] ) 
 264.221 +					continue;
 264.222 +
 264.223 +				isBoneUsed[newIndex] = true;
 264.224 +				numBones++;
 264.225 +			}
 264.226 +
 264.227 +			// store the face index and the vertex count
 264.228 +			subMeshFaces.push_back( a);
 264.229 +			numSubMeshVertices += face.mNumIndices;
 264.230 +
 264.231 +			// remember that this face is handled
 264.232 +			isFaceHandled[a] = true;
 264.233 +			numFacesHandled++;
 264.234 +		}
 264.235 +
 264.236 +		// create a new mesh to hold this subset of the source mesh
 264.237 +		aiMesh* newMesh = new aiMesh;
 264.238 +		if( pMesh->mName.length > 0 )
 264.239 +			newMesh->mName.Set( boost::str( boost::format( "%s_sub%d") % pMesh->mName.data % poNewMeshes.size()));
 264.240 +		newMesh->mMaterialIndex = pMesh->mMaterialIndex;
 264.241 +		newMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes;
 264.242 +		poNewMeshes.push_back( newMesh);
 264.243 +
 264.244 +		// create all the arrays for this mesh if the old mesh contained them
 264.245 +		newMesh->mNumVertices = numSubMeshVertices;
 264.246 +		newMesh->mNumFaces = subMeshFaces.size();
 264.247 +		newMesh->mVertices = new aiVector3D[newMesh->mNumVertices];
 264.248 +		if( pMesh->HasNormals() )
 264.249 +			newMesh->mNormals = new aiVector3D[newMesh->mNumVertices];
 264.250 +		if( pMesh->HasTangentsAndBitangents() )
 264.251 +		{
 264.252 +			newMesh->mTangents = new aiVector3D[newMesh->mNumVertices];
 264.253 +			newMesh->mBitangents = new aiVector3D[newMesh->mNumVertices];
 264.254 +		}
 264.255 +		for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
 264.256 +		{
 264.257 +			if( pMesh->HasTextureCoords( a) )
 264.258 +				newMesh->mTextureCoords[a] = new aiVector3D[newMesh->mNumVertices];
 264.259 +			newMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
 264.260 +		}
 264.261 +		for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
 264.262 +		{
 264.263 +			if( pMesh->HasVertexColors( a) )
 264.264 +				newMesh->mColors[a] = new aiColor4D[newMesh->mNumVertices];
 264.265 +		}
 264.266 +
 264.267 +		// and copy over the data, generating faces with linear indices along the way
 264.268 +		newMesh->mFaces = new aiFace[subMeshFaces.size()];
 264.269 +		size_t nvi = 0; // next vertex index
 264.270 +		std::vector<size_t> previousVertexIndices( numSubMeshVertices, std::numeric_limits<size_t>::max()); // per new vertex: its index in the source mesh
 264.271 +		for( size_t a = 0; a < subMeshFaces.size(); ++a )
 264.272 +		{
 264.273 +			const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
 264.274 +			aiFace& dstFace = newMesh->mFaces[a];
 264.275 +			dstFace.mNumIndices = srcFace.mNumIndices;
 264.276 +			dstFace.mIndices = new unsigned int[dstFace.mNumIndices];
 264.277 +
 264.278 +			// accumulate linearly all the vertices of the source face
 264.279 +			for( size_t b = 0; b < dstFace.mNumIndices; ++b )
 264.280 +			{
 264.281 +				size_t srcIndex = srcFace.mIndices[b];
 264.282 +				dstFace.mIndices[b] = nvi;
 264.283 +				previousVertexIndices[nvi] = srcIndex;
 264.284 +
 264.285 +				newMesh->mVertices[nvi] = pMesh->mVertices[srcIndex];
 264.286 +				if( pMesh->HasNormals() )
 264.287 +					newMesh->mNormals[nvi] = pMesh->mNormals[srcIndex];
 264.288 +				if( pMesh->HasTangentsAndBitangents() )
 264.289 +				{
 264.290 +					newMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
 264.291 +					newMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
 264.292 +				}
 264.293 +				for( size_t c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c )
 264.294 +				{
 264.295 +					if( pMesh->HasTextureCoords( c) )
 264.296 +						newMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
 264.297 +				}
 264.298 +				for( size_t c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c )
 264.299 +				{
 264.300 +					if( pMesh->HasVertexColors( c) )
 264.301 +						newMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
 264.302 +				}
 264.303 +
 264.304 +				nvi++;
 264.305 +			}
 264.306 +		}
 264.307 +
 264.308 +		ai_assert( nvi == numSubMeshVertices );
 264.309 +
 264.310 +		// Create the bones for the new submesh: first create the bone array
 264.311 +		newMesh->mNumBones = 0;
 264.312 +		newMesh->mBones = new aiBone*[numBones];
 264.313 +
 264.314 +		std::vector<size_t> mappedBoneIndex( pMesh->mNumBones, std::numeric_limits<size_t>::max());
 264.315 +		for( size_t a = 0; a < pMesh->mNumBones; ++a )
 264.316 +		{
 264.317 +			if( !isBoneUsed[a] )
 264.318 +				continue;
 264.319 +
 264.320 +			// create the new bone
 264.321 +			const aiBone* srcBone = pMesh->mBones[a];
 264.322 +			aiBone* dstBone = new aiBone;
 264.323 +			mappedBoneIndex[a] = newMesh->mNumBones;
 264.324 +			newMesh->mBones[newMesh->mNumBones++] = dstBone;
 264.325 +			dstBone->mName = srcBone->mName;
 264.326 +			dstBone->mOffsetMatrix = srcBone->mOffsetMatrix;
 264.327 +			dstBone->mNumWeights = 0;
 264.328 +		}
 264.329 +
 264.330 +		ai_assert( newMesh->mNumBones == numBones );
 264.331 +
 264.332 +		// iterate over all new vertices and count which bones affected its old vertex in the source mesh
 264.333 +		for( size_t a = 0; a < numSubMeshVertices; ++a )
 264.334 +		{
 264.335 +			size_t oldIndex = previousVertexIndices[a];
 264.336 +			const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[oldIndex];
 264.337 +
 264.338 +			for( size_t b = 0; b < bonesOnThisVertex.size(); ++b )
 264.339 +			{
 264.340 +				size_t newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
 264.341 +				if( newBoneIndex != std::numeric_limits<size_t>::max() )
 264.342 +					newMesh->mBones[newBoneIndex]->mNumWeights++;
 264.343 +			}
 264.344 +		}
 264.345 +
 264.346 +		// allocate all bone weight arrays accordingly
 264.347 +		for( size_t a = 0; a < newMesh->mNumBones; ++a )
 264.348 +		{
 264.349 +			aiBone* bone = newMesh->mBones[a];
 264.350 +			ai_assert( bone->mNumWeights > 0 );
 264.351 +			bone->mWeights = new aiVertexWeight[bone->mNumWeights];
 264.352 +			bone->mNumWeights = 0; // for counting up in the next step
 264.353 +		}
 264.354 +
 264.355 +		// now copy all the bone vertex weights for all the vertices which made it into the new submesh
 264.356 +		for( size_t a = 0; a < numSubMeshVertices; ++a)
 264.357 +		{
 264.358 +			// find the source vertex for it in the source mesh
 264.359 +			size_t previousIndex = previousVertexIndices[a];
 264.360 +			// these bones were affecting it
 264.361 +			const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[previousIndex];
 264.362 +			// all of the bones affecting it should be present in the new submesh, or else
 264.363 +			// the face it comprises shouldn't be present
 264.364 +			for( size_t b = 0; b < bonesOnThisVertex.size(); ++b)
 264.365 +			{
 264.366 +				size_t newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
 264.367 +				ai_assert( newBoneIndex != std::numeric_limits<size_t>::max() );
 264.368 +				aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights;
 264.369 +				newMesh->mBones[newBoneIndex]->mNumWeights++;
 264.370 +
 264.371 +				dstWeight->mVertexId = a;
 264.372 +				dstWeight->mWeight = bonesOnThisVertex[b].second;
 264.373 +			}
 264.374 +		}
 264.375 +
 264.376 +		// I have the strange feeling that this will break apart at some point in time...
 264.377 +	}
 264.378 +}
 264.379 +
 264.380 +// ------------------------------------------------------------------------------------------------
 264.381 +// Recursively updates the node's mesh list to account for the changed mesh list
 264.382 +void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
 264.383 +{
 264.384 +	// rebuild the node's mesh index list
 264.385 +	if( pNode->mNumMeshes > 0 )
 264.386 +	{
 264.387 +		std::vector<size_t> newMeshList;
 264.388 +		for( size_t a = 0; a < pNode->mNumMeshes; ++a)
 264.389 +		{
 264.390 +			size_t srcIndex = pNode->mMeshes[a];
 264.391 +			const std::vector<size_t>& replaceMeshes = mSubMeshIndices[srcIndex];
 264.392 +			newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
 264.393 +		}
 264.394 +
 264.395 +		delete pNode->mMeshes;
 264.396 +		pNode->mNumMeshes = newMeshList.size();
 264.397 +		pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
 264.398 +		std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
 264.399 +	}
 264.400 +
 264.401 +	// do that also recursively for all children
 264.402 +	for( size_t a = 0; a < pNode->mNumChildren; ++a )
 264.403 +	{
 264.404 +		UpdateNode( pNode->mChildren[a]);
 264.405 +	}
 264.406 +}
   265.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   265.2 +++ b/libs/assimp/SplitByBoneCountProcess.h	Sat Feb 01 19:58:19 2014 +0200
   265.3 @@ -0,0 +1,109 @@
   265.4 +/*
   265.5 +Open Asset Import Library (assimp)
   265.6 +----------------------------------------------------------------------
   265.7 +
   265.8 +Copyright (c) 2006-2012, assimp team
   265.9 +All rights reserved.
  265.10 +
  265.11 +Redistribution and use of this software in source and binary forms, 
  265.12 +with or without modification, are permitted provided that the 
  265.13 +following conditions are met:
  265.14 +
  265.15 +* Redistributions of source code must retain the above
  265.16 +  copyright notice, this list of conditions and the
  265.17 +  following disclaimer.
  265.18 +
  265.19 +* Redistributions in binary form must reproduce the above
  265.20 +  copyright notice, this list of conditions and the
  265.21 +  following disclaimer in the documentation and/or other
  265.22 +  materials provided with the distribution.
  265.23 +
  265.24 +* Neither the name of the assimp team, nor the names of its
  265.25 +  contributors may be used to endorse or promote products
  265.26 +  derived from this software without specific prior
  265.27 +  written permission of the assimp team.
  265.28 +
  265.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  265.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  265.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  265.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  265.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  265.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  265.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  265.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  265.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  265.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  265.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  265.40 +
  265.41 +----------------------------------------------------------------------
  265.42 +*/
  265.43 +
  265.44 +/// @file SplitByBoneCountProcess.h 
  265.45 +/// Defines a post processing step to split meshes with many bones into submeshes
  265.46 +#ifndef AI_SPLITBYBONECOUNTPROCESS_H_INC
  265.47 +#define AI_SPLITBYBONECOUNTPROCESS_H_INC
  265.48 +
  265.49 +#include <vector>
  265.50 +#include "BaseProcess.h"
  265.51 +
  265.52 +#include "assimp/mesh.h"
  265.53 +#include "assimp/scene.h"
  265.54 +
  265.55 +namespace Assimp
  265.56 +{
  265.57 +
  265.58 +
  265.59 +/** Postprocessing filter to split meshes with many bones into submeshes
  265.60 + * so that each submesh has a certain max bone count.
  265.61 + *
  265.62 + * Applied BEFORE the JoinVertices-Step occurs.
  265.63 + * Returns NON-UNIQUE vertices, splits by bone count.
  265.64 +*/
  265.65 +class SplitByBoneCountProcess : public BaseProcess
  265.66 +{
  265.67 +public:
  265.68 +
  265.69 +	SplitByBoneCountProcess();
  265.70 +	~SplitByBoneCountProcess();
  265.71 +
  265.72 +public:
  265.73 +	/** Returns whether the processing step is present in the given flag.
  265.74 +	* @param pFlags The processing flags the importer was called with. A
  265.75 + 	*   bitwise combination of #aiPostProcessSteps.
  265.76 +	* @return true if the process is present in this flag fields, 
  265.77 + 	*   false if not.
  265.78 +	*/
  265.79 +	bool IsActive( unsigned int pFlags) const;
  265.80 +
  265.81 +	/** Called prior to ExecuteOnScene().
  265.82 +	* The function is a request to the process to update its configuration
  265.83 +	* basing on the Importer's configuration property list.
  265.84 +	*/
  265.85 +	virtual void SetupProperties(const Importer* pImp);
  265.86 +
  265.87 +protected:
  265.88 +	/** Executes the post processing step on the given imported data.
  265.89 +	* At the moment a process is not supposed to fail.
  265.90 +	* @param pScene The imported data to work at.
  265.91 +	*/
  265.92 +	void Execute( aiScene* pScene);
  265.93 +
  265.94 +	/// Splits the given mesh by bone count.
  265.95 +	/// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.
  265.96 +	/// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary.
  265.97 +	void SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const;
  265.98 +
  265.99 +	/// Recursively updates the node's mesh list to account for the changed mesh list
 265.100 +	void UpdateNode( aiNode* pNode) const;
 265.101 +
 265.102 +public:
 265.103 +	/// Max bone count. Splitting occurs if a mesh has more than that number of bones.
 265.104 +	size_t mMaxBoneCount;
 265.105 +
 265.106 +	/// Per mesh index: Array of indices of the new submeshes.
 265.107 +	std::vector< std::vector<size_t> > mSubMeshIndices;
 265.108 +};
 265.109 +
 265.110 +} // end of namespace Assimp
 265.111 +
 265.112 +#endif // !!AI_SPLITBYBONECOUNTPROCESS_H_INC
   266.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   266.2 +++ b/libs/assimp/SplitLargeMeshes.cpp	Sat Feb 01 19:58:19 2014 +0200
   266.3 @@ -0,0 +1,677 @@
   266.4 +/*
   266.5 +Open Asset Import Library (assimp)
   266.6 +----------------------------------------------------------------------
   266.7 +
   266.8 +Copyright (c) 2006-2012, assimp team
   266.9 +All rights reserved.
  266.10 +
  266.11 +Redistribution and use of this software in source and binary forms, 
  266.12 +with or without modification, are permitted provided that the 
  266.13 +following conditions are met:
  266.14 +
  266.15 +* Redistributions of source code must retain the above
  266.16 +  copyright notice, this list of conditions and the
  266.17 +  following disclaimer.
  266.18 +
  266.19 +* Redistributions in binary form must reproduce the above
  266.20 +  copyright notice, this list of conditions and the
  266.21 +  following disclaimer in the documentation and/or other
  266.22 +  materials provided with the distribution.
  266.23 +
  266.24 +* Neither the name of the assimp team, nor the names of its
  266.25 +  contributors may be used to endorse or promote products
  266.26 +  derived from this software without specific prior
  266.27 +  written permission of the assimp team.
  266.28 +
  266.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  266.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  266.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  266.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  266.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  266.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  266.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  266.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  266.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  266.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  266.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  266.40 +
  266.41 +----------------------------------------------------------------------
  266.42 +*/
  266.43 +
  266.44 +
  266.45 +/** @file Implementation of the SplitLargeMeshes postprocessing step
  266.46 +*/
  266.47 +
  266.48 +#include "AssimpPCH.h"
  266.49 +
  266.50 +// internal headers of the post-processing framework
  266.51 +#include "SplitLargeMeshes.h"
  266.52 +#include "ProcessHelper.h"
  266.53 +
  266.54 +using namespace Assimp;
  266.55 +
  266.56 +
  266.57 +// ------------------------------------------------------------------------------------------------
  266.58 +SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle()
  266.59 +{
  266.60 +	LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES;
  266.61 +}
  266.62 +
  266.63 +// ------------------------------------------------------------------------------------------------
  266.64 +SplitLargeMeshesProcess_Triangle::~SplitLargeMeshesProcess_Triangle()
  266.65 +{
  266.66 +	// nothing to do here
  266.67 +}
  266.68 +
  266.69 +// ------------------------------------------------------------------------------------------------
  266.70 +// Returns whether the processing step is present in the given flag field.
  266.71 +bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const
  266.72 +{
  266.73 +	return (pFlags & aiProcess_SplitLargeMeshes) != 0;
  266.74 +}
  266.75 +
  266.76 +// ------------------------------------------------------------------------------------------------
  266.77 +// Executes the post processing step on the given imported data.
  266.78 +void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene)
  266.79 +{
  266.80 +	if (0xffffffff == this->LIMIT)return;
  266.81 +
  266.82 +	DefaultLogger::get()->debug("SplitLargeMeshesProcess_Triangle begin");
  266.83 +	std::vector<std::pair<aiMesh*, unsigned int> > avList;
  266.84 +
  266.85 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
  266.86 +		this->SplitMesh(a, pScene->mMeshes[a],avList);
  266.87 +
  266.88 +	if (avList.size() != pScene->mNumMeshes)
  266.89 +	{
  266.90 +		// it seems something has been split. rebuild the mesh list
  266.91 +		delete[] pScene->mMeshes;
  266.92 +		pScene->mNumMeshes = (unsigned int)avList.size();
  266.93 +		pScene->mMeshes = new aiMesh*[avList.size()];
  266.94 +
  266.95 +		for (unsigned int i = 0; i < avList.size();++i)
  266.96 +			pScene->mMeshes[i] = avList[i].first;
  266.97 +
  266.98 +		// now we need to update all nodes
  266.99 +		this->UpdateNode(pScene->mRootNode,avList);
 266.100 +		DefaultLogger::get()->info("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
 266.101 +	}
 266.102 +	else DefaultLogger::get()->debug("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
 266.103 +	return;
 266.104 +}
 266.105 +
 266.106 +// ------------------------------------------------------------------------------------------------
 266.107 +// Setup properties
 266.108 +void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp)
 266.109 +{
 266.110 +    // get the current value of the split property
 266.111 +	this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
 266.112 +}
 266.113 +
 266.114 +// ------------------------------------------------------------------------------------------------
 266.115 +// Update a node after some meshes have been split
 266.116 +void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode,
 266.117 +	const std::vector<std::pair<aiMesh*, unsigned int> >& avList)
 266.118 +{
 266.119 +	// for every index in out list build a new entry
 266.120 +	std::vector<unsigned int> aiEntries;
 266.121 +	aiEntries.reserve(pcNode->mNumMeshes + 1);
 266.122 +	for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
 266.123 +	{
 266.124 +		for (unsigned int a = 0; a < avList.size();++a)
 266.125 +		{
 266.126 +			if (avList[a].second == pcNode->mMeshes[i])
 266.127 +			{
 266.128 +				aiEntries.push_back(a);
 266.129 +			}
 266.130 +		}
 266.131 +	}
 266.132 +
 266.133 +	// now build the new list
 266.134 +	delete pcNode->mMeshes;
 266.135 +	pcNode->mNumMeshes = (unsigned int)aiEntries.size();
 266.136 +	pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
 266.137 +
 266.138 +	for (unsigned int b = 0; b < pcNode->mNumMeshes;++b)
 266.139 +		pcNode->mMeshes[b] = aiEntries[b];
 266.140 +
 266.141 +	// recusively update all other nodes
 266.142 +	for (unsigned int i = 0; i < pcNode->mNumChildren;++i)
 266.143 +	{
 266.144 +		UpdateNode ( pcNode->mChildren[i], avList );
 266.145 +	}
 266.146 +	return;
 266.147 +}
 266.148 +
 266.149 +// ------------------------------------------------------------------------------------------------
 266.150 +// Executes the post processing step on the given imported data.
 266.151 +void SplitLargeMeshesProcess_Triangle::SplitMesh(
 266.152 +	unsigned int a,
 266.153 +	aiMesh* pMesh,
 266.154 +	std::vector<std::pair<aiMesh*, unsigned int> >& avList)
 266.155 +{
 266.156 +	if (pMesh->mNumFaces > SplitLargeMeshesProcess_Triangle::LIMIT)
 266.157 +	{
 266.158 +		DefaultLogger::get()->info("Mesh exceeds the triangle limit. It will be split ...");
 266.159 +
 266.160 +		// we need to split this mesh into sub meshes
 266.161 +		// determine the size of a submesh
 266.162 +		const unsigned int iSubMeshes = (pMesh->mNumFaces / LIMIT) + 1;
 266.163 +
 266.164 +		const unsigned int iOutFaceNum = pMesh->mNumFaces / iSubMeshes;
 266.165 +		const unsigned int iOutVertexNum = iOutFaceNum * 3;
 266.166 +
 266.167 +		// now generate all submeshes
 266.168 +		for (unsigned int i = 0; i < iSubMeshes;++i)
 266.169 +		{
 266.170 +			aiMesh* pcMesh			= new aiMesh;			
 266.171 +			pcMesh->mNumFaces		= iOutFaceNum;
 266.172 +			pcMesh->mMaterialIndex	= pMesh->mMaterialIndex;
 266.173 +
 266.174 +			// the name carries the adjacency information between the meshes
 266.175 +			pcMesh->mName = pMesh->mName;
 266.176 +
 266.177 +			if (i == iSubMeshes-1)
 266.178 +			{
 266.179 +				pcMesh->mNumFaces = iOutFaceNum + (
 266.180 +					pMesh->mNumFaces - iOutFaceNum * iSubMeshes);
 266.181 +			}
 266.182 +			// copy the list of faces
 266.183 +			pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
 266.184 +
 266.185 +			const unsigned int iBase = iOutFaceNum * i;
 266.186 +
 266.187 +			// get the total number of indices
 266.188 +			unsigned int iCnt = 0;
 266.189 +			for (unsigned int p = iBase; p < pcMesh->mNumFaces + iBase;++p)
 266.190 +			{
 266.191 +				iCnt += pMesh->mFaces[p].mNumIndices;
 266.192 +			}
 266.193 +			pcMesh->mNumVertices = iCnt;
 266.194 +
 266.195 +			// allocate storage
 266.196 +			if (pMesh->mVertices != NULL)
 266.197 +				pcMesh->mVertices = new aiVector3D[iCnt];
 266.198 +
 266.199 +			if (pMesh->HasNormals())
 266.200 +				pcMesh->mNormals = new aiVector3D[iCnt];
 266.201 +
 266.202 +			if (pMesh->HasTangentsAndBitangents())
 266.203 +			{
 266.204 +				pcMesh->mTangents = new aiVector3D[iCnt];
 266.205 +				pcMesh->mBitangents = new aiVector3D[iCnt];
 266.206 +			}
 266.207 +
 266.208 +			// texture coordinates
 266.209 +			for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
 266.210 +			{
 266.211 +				pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
 266.212 +				if (pMesh->HasTextureCoords( c))
 266.213 +				{
 266.214 +					pcMesh->mTextureCoords[c] = new aiVector3D[iCnt];
 266.215 +				}
 266.216 +			}
 266.217 +
 266.218 +			// vertex colors
 266.219 +			for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
 266.220 +			{
 266.221 +				if (pMesh->HasVertexColors( c))
 266.222 +				{
 266.223 +					pcMesh->mColors[c] = new aiColor4D[iCnt];
 266.224 +				}
 266.225 +			}
 266.226 +
 266.227 +			if (pMesh->HasBones())
 266.228 +			{
 266.229 +				// assume the number of bones won't change in most cases
 266.230 +				pcMesh->mBones = new aiBone*[pMesh->mNumBones];
 266.231 +
 266.232 +				// iterate through all bones of the mesh and find those which
 266.233 +				// need to be copied to the split mesh
 266.234 +				std::vector<aiVertexWeight> avTempWeights;
 266.235 +				for (unsigned int p = 0; p < pcMesh->mNumBones;++p)
 266.236 +				{
 266.237 +					aiBone* const bone = pcMesh->mBones[p];
 266.238 +					avTempWeights.clear();
 266.239 +					avTempWeights.reserve(bone->mNumWeights / iSubMeshes);
 266.240 +
 266.241 +					for (unsigned int q = 0; q < bone->mNumWeights;++q)
 266.242 +					{
 266.243 +						aiVertexWeight& weight = bone->mWeights[q];
 266.244 +						if(weight.mVertexId >= iBase && weight.mVertexId < iBase + iOutVertexNum)
 266.245 +						{
 266.246 +							avTempWeights.push_back(weight);
 266.247 +							weight = avTempWeights.back();
 266.248 +							weight.mVertexId -= iBase;
 266.249 +						}
 266.250 +					}
 266.251 +
 266.252 +					if (!avTempWeights.empty())
 266.253 +					{
 266.254 +						// we'll need this bone. Copy it ...
 266.255 +						aiBone* pc = new aiBone();
 266.256 +						pcMesh->mBones[pcMesh->mNumBones++] = pc;
 266.257 +						pc->mName = aiString(bone->mName);
 266.258 +						pc->mNumWeights = (unsigned int)avTempWeights.size();
 266.259 +						pc->mOffsetMatrix = bone->mOffsetMatrix;
 266.260 +
 266.261 +						// no need to reallocate the array for the last submesh.
 266.262 +						// Here we can reuse the (large) source array, although
 266.263 +						// we'll waste some memory
 266.264 +						if (iSubMeshes-1 == i)
 266.265 +						{
 266.266 +							pc->mWeights = bone->mWeights;
 266.267 +							bone->mWeights = NULL;
 266.268 +						}
 266.269 +						else pc->mWeights = new aiVertexWeight[pc->mNumWeights];
 266.270 +
 266.271 +						// copy the weights
 266.272 +						::memcpy(pc->mWeights,&avTempWeights[0],sizeof(aiVertexWeight)*pc->mNumWeights);
 266.273 +					}
 266.274 +				}
 266.275 +			}
 266.276 +
 266.277 +			// (we will also need to copy the array of indices)
 266.278 +			unsigned int iCurrent = 0;
 266.279 +			for (unsigned int p = 0; p < pcMesh->mNumFaces;++p)
 266.280 +			{
 266.281 +				pcMesh->mFaces[p].mNumIndices = 3;
 266.282 +				// allocate a new array
 266.283 +				const unsigned int iTemp = p + iBase;
 266.284 +				const unsigned int iNumIndices = pMesh->mFaces[iTemp].mNumIndices;
 266.285 +
 266.286 +				// setup face type and number of indices
 266.287 +				pcMesh->mFaces[p].mNumIndices = iNumIndices;
 266.288 +				unsigned int* pi = pMesh->mFaces[iTemp].mIndices;
 266.289 +				unsigned int* piOut = pcMesh->mFaces[p].mIndices = new unsigned int[iNumIndices];
 266.290 +
 266.291 +				// need to update the output primitive types
 266.292 +				switch (iNumIndices)
 266.293 +				{
 266.294 +				case 1:
 266.295 +					pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
 266.296 +					break;
 266.297 +				case 2:
 266.298 +					pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
 266.299 +					break;
 266.300 +				case 3:
 266.301 +					pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
 266.302 +					break;
 266.303 +				default:
 266.304 +					pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
 266.305 +				}
 266.306 +
 266.307 +				// and copy the contents of the old array, offset by current base
 266.308 +				for (unsigned int v = 0; v < iNumIndices;++v)
 266.309 +				{
 266.310 +					unsigned int iIndex = pi[v];
 266.311 +					unsigned int iIndexOut = iCurrent++;
 266.312 +					piOut[v] = iIndexOut;
 266.313 +
 266.314 +					// copy positions
 266.315 +					if (pMesh->mVertices != NULL)
 266.316 +						pcMesh->mVertices[iIndexOut] = pMesh->mVertices[iIndex];
 266.317 +
 266.318 +					// copy normals
 266.319 +					if (pMesh->HasNormals())
 266.320 +						pcMesh->mNormals[iIndexOut] = pMesh->mNormals[iIndex];
 266.321 +
 266.322 +					// copy tangents/bitangents
 266.323 +					if (pMesh->HasTangentsAndBitangents())
 266.324 +					{
 266.325 +						pcMesh->mTangents[iIndexOut] = pMesh->mTangents[iIndex];
 266.326 +						pcMesh->mBitangents[iIndexOut] = pMesh->mBitangents[iIndex];
 266.327 +					}
 266.328 +
 266.329 +					// texture coordinates
 266.330 +					for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
 266.331 +					{
 266.332 +						if (pMesh->HasTextureCoords( c))
 266.333 +							pcMesh->mTextureCoords[c][iIndexOut] = pMesh->mTextureCoords[c][iIndex];
 266.334 +					}
 266.335 +					// vertex colors 
 266.336 +					for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
 266.337 +					{
 266.338 +						if (pMesh->HasVertexColors( c))
 266.339 +							pcMesh->mColors[c][iIndexOut] = pMesh->mColors[c][iIndex];
 266.340 +					}
 266.341 +				}
 266.342 +			}
 266.343 +
 266.344 +			// add the newly created mesh to the list
 266.345 +			avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a));
 266.346 +		}
 266.347 +
 266.348 +		// now delete the old mesh data
 266.349 +		delete pMesh;
 266.350 +	}
 266.351 +	else avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
 266.352 +	return;
 266.353 +}
 266.354 +
 266.355 +// ------------------------------------------------------------------------------------------------
 266.356 +SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex()
 266.357 +{
 266.358 +	LIMIT = AI_SLM_DEFAULT_MAX_VERTICES;
 266.359 +}
 266.360 +
 266.361 +// ------------------------------------------------------------------------------------------------
 266.362 +SplitLargeMeshesProcess_Vertex::~SplitLargeMeshesProcess_Vertex()
 266.363 +{
 266.364 +	// nothing to do here
 266.365 +}
 266.366 +
 266.367 +// ------------------------------------------------------------------------------------------------
 266.368 +// Returns whether the processing step is present in the given flag field.
 266.369 +bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const
 266.370 +{
 266.371 +	return (pFlags & aiProcess_SplitLargeMeshes) != 0;
 266.372 +}
 266.373 +
 266.374 +// ------------------------------------------------------------------------------------------------
 266.375 +// Executes the post processing step on the given imported data.
 266.376 +void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene)
 266.377 +{
 266.378 +	std::vector<std::pair<aiMesh*, unsigned int> > avList;
 266.379 +
 266.380 +  	if (0xffffffff == this->LIMIT)return;
 266.381 +
 266.382 +	DefaultLogger::get()->debug("SplitLargeMeshesProcess_Vertex begin");
 266.383 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
 266.384 +		this->SplitMesh(a, pScene->mMeshes[a],avList);
 266.385 +
 266.386 +	if (avList.size() != pScene->mNumMeshes)
 266.387 +	{
 266.388 +		// it seems something has been split. rebuild the mesh list
 266.389 +		delete[] pScene->mMeshes;
 266.390 +		pScene->mNumMeshes = (unsigned int)avList.size();
 266.391 +		pScene->mMeshes = new aiMesh*[avList.size()];
 266.392 +
 266.393 +		for (unsigned int i = 0; i < avList.size();++i)
 266.394 +			pScene->mMeshes[i] = avList[i].first;
 266.395 +
 266.396 +		// now we need to update all nodes
 266.397 +		SplitLargeMeshesProcess_Triangle::UpdateNode(pScene->mRootNode,avList);
 266.398 +		DefaultLogger::get()->info("SplitLargeMeshesProcess_Vertex finished. Meshes have been split");
 266.399 +	}
 266.400 +	else DefaultLogger::get()->debug("SplitLargeMeshesProcess_Vertex finished. There was nothing to do");
 266.401 +	return;
 266.402 +}
 266.403 +
 266.404 +// ------------------------------------------------------------------------------------------------
 266.405 +// Setup properties
 266.406 +void SplitLargeMeshesProcess_Vertex::SetupProperties( const Importer* pImp)
 266.407 +{
 266.408 +	this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
 266.409 +}
 266.410 +
 266.411 +// ------------------------------------------------------------------------------------------------
 266.412 +// Executes the post processing step on the given imported data.
 266.413 +void SplitLargeMeshesProcess_Vertex::SplitMesh(
 266.414 +	unsigned int a,
 266.415 +	aiMesh* pMesh,
 266.416 +	std::vector<std::pair<aiMesh*, unsigned int> >& avList)
 266.417 +{
 266.418 +	if (pMesh->mNumVertices > SplitLargeMeshesProcess_Vertex::LIMIT)
 266.419 +	{
 266.420 +		typedef std::vector< std::pair<unsigned int,float> > VertexWeightTable;
 266.421 +
 266.422 +		// build a per-vertex weight list if necessary
 266.423 +		VertexWeightTable* avPerVertexWeights = ComputeVertexBoneWeightTable(pMesh);
 266.424 +
 266.425 +		// we need to split this mesh into sub meshes
 266.426 +		// determine the estimated size of a submesh
 266.427 +		// (this could be too large. Max waste is a single digit percentage)
 266.428 +		const unsigned int iSubMeshes = (pMesh->mNumVertices / SplitLargeMeshesProcess_Vertex::LIMIT) + 1;
 266.429 +		//const unsigned int iOutVertexNum2 = pMesh->mNumVertices /iSubMeshes;
 266.430 +
 266.431 +		// create a std::vector<unsigned int> to indicate which vertices
 266.432 +		// have already been copied
 266.433 +		std::vector<unsigned int> avWasCopied;
 266.434 +		avWasCopied.resize(pMesh->mNumVertices,0xFFFFFFFF);
 266.435 +
 266.436 +		// try to find a good estimate for the number of output faces
 266.437 +		// per mesh. Add 12.5% as buffer
 266.438 +		unsigned int iEstimatedSize = pMesh->mNumFaces / iSubMeshes;
 266.439 +		iEstimatedSize += iEstimatedSize >> 3;
 266.440 +
 266.441 +		// now generate all submeshes
 266.442 +		unsigned int iBase = 0;
 266.443 +		while (true)
 266.444 +		{
 266.445 +			const unsigned int iOutVertexNum = SplitLargeMeshesProcess_Vertex::LIMIT;
 266.446 +
 266.447 +			aiMesh* pcMesh			= new aiMesh;			
 266.448 +			pcMesh->mNumVertices	= 0;
 266.449 +			pcMesh->mMaterialIndex	= pMesh->mMaterialIndex;
 266.450 +
 266.451 +			// the name carries the adjacency information between the meshes
 266.452 +			pcMesh->mName = pMesh->mName;
 266.453 +
 266.454 +			typedef std::vector<aiVertexWeight> BoneWeightList;
 266.455 +			if (pMesh->HasBones())
 266.456 +			{
 266.457 +				pcMesh->mBones = new aiBone*[pMesh->mNumBones];
 266.458 +				::memset(pcMesh->mBones,0,sizeof(void*)*pMesh->mNumBones);
 266.459 +			}
 266.460 +
 266.461 +			// clear the temporary helper array
 266.462 +			if (iBase)
 266.463 +			{
 266.464 +				// we can't use memset here we unsigned int needn' be 32 bits
 266.465 +				for (std::vector<unsigned int>::iterator
 266.466 +					iter = avWasCopied.begin(),end = avWasCopied.end();
 266.467 +					iter != end;++iter)
 266.468 +				{
 266.469 +					(*iter) = 0xffffffff;
 266.470 +				}
 266.471 +			}
 266.472 +
 266.473 +			// output vectors
 266.474 +			std::vector<aiFace> vFaces;
 266.475 +
 266.476 +			// reserve enough storage for most cases
 266.477 +			if (pMesh->HasPositions())
 266.478 +			{
 266.479 +				pcMesh->mVertices = new aiVector3D[iOutVertexNum];
 266.480 +			}
 266.481 +			if (pMesh->HasNormals())
 266.482 +			{
 266.483 +				pcMesh->mNormals = new aiVector3D[iOutVertexNum];
 266.484 +			}
 266.485 +			if (pMesh->HasTangentsAndBitangents())
 266.486 +			{
 266.487 +				pcMesh->mTangents = new aiVector3D[iOutVertexNum];
 266.488 +				pcMesh->mBitangents = new aiVector3D[iOutVertexNum];
 266.489 +			}
 266.490 +			for (unsigned int c = 0; pMesh->HasVertexColors(c);++c)
 266.491 +			{
 266.492 +				pcMesh->mColors[c] = new aiColor4D[iOutVertexNum];
 266.493 +			}
 266.494 +			for (unsigned int c = 0; pMesh->HasTextureCoords(c);++c)
 266.495 +			{
 266.496 +				pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
 266.497 +				pcMesh->mTextureCoords[c] = new aiVector3D[iOutVertexNum];
 266.498 +			}
 266.499 +			vFaces.reserve(iEstimatedSize);
 266.500 +
 266.501 +			// (we will also need to copy the array of indices)
 266.502 +			while (iBase < pMesh->mNumFaces)
 266.503 +			{
 266.504 +				// allocate a new array
 266.505 +				const unsigned int iNumIndices = pMesh->mFaces[iBase].mNumIndices;
 266.506 +
 266.507 +				// doesn't catch degenerates but is quite fast
 266.508 +				unsigned int iNeed = 0;
 266.509 +				for (unsigned int v = 0; v < iNumIndices;++v)
 266.510 +				{
 266.511 +					unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];
 266.512 +
 266.513 +					// check whether we do already have this vertex
 266.514 +					if (0xFFFFFFFF == avWasCopied[iIndex])
 266.515 +					{
 266.516 +						iNeed++; 
 266.517 +					}
 266.518 +				}
 266.519 +				if (pcMesh->mNumVertices + iNeed > iOutVertexNum)
 266.520 +				{
 266.521 +					// don't use this face
 266.522 +					break;
 266.523 +				}
 266.524 +
 266.525 +				vFaces.push_back(aiFace());
 266.526 +				aiFace& rFace = vFaces.back();
 266.527 +
 266.528 +				// setup face type and number of indices
 266.529 +				rFace.mNumIndices = iNumIndices;
 266.530 +				rFace.mIndices = new unsigned int[iNumIndices];
 266.531 +
 266.532 +				// need to update the output primitive types
 266.533 +				switch (rFace.mNumIndices)
 266.534 +				{
 266.535 +				case 1:
 266.536 +					pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
 266.537 +					break;
 266.538 +				case 2:
 266.539 +					pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
 266.540 +					break;
 266.541 +				case 3:
 266.542 +					pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
 266.543 +					break;
 266.544 +				default:
 266.545 +					pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
 266.546 +				}
 266.547 +
 266.548 +				// and copy the contents of the old array, offset by current base
 266.549 +				for (unsigned int v = 0; v < iNumIndices;++v)
 266.550 +				{
 266.551 +					unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];
 266.552 +
 266.553 +					// check whether we do already have this vertex
 266.554 +					if (0xFFFFFFFF != avWasCopied[iIndex])
 266.555 +					{
 266.556 +						rFace.mIndices[v] = avWasCopied[iIndex];
 266.557 +						continue;
 266.558 +					}
 266.559 +
 266.560 +					// copy positions
 266.561 +					pcMesh->mVertices[pcMesh->mNumVertices] = (pMesh->mVertices[iIndex]);
 266.562 +
 266.563 +					// copy normals
 266.564 +					if (pMesh->HasNormals())
 266.565 +					{
 266.566 +						pcMesh->mNormals[pcMesh->mNumVertices] = (pMesh->mNormals[iIndex]);
 266.567 +					}
 266.568 +
 266.569 +					// copy tangents/bitangents
 266.570 +					if (pMesh->HasTangentsAndBitangents())
 266.571 +					{
 266.572 +						pcMesh->mTangents[pcMesh->mNumVertices] = (pMesh->mTangents[iIndex]);
 266.573 +						pcMesh->mBitangents[pcMesh->mNumVertices] = (pMesh->mBitangents[iIndex]);
 266.574 +					}
 266.575 +
 266.576 +					// texture coordinates
 266.577 +					for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
 266.578 +					{
 266.579 +						if (pMesh->HasTextureCoords( c))
 266.580 +						{
 266.581 +							pcMesh->mTextureCoords[c][pcMesh->mNumVertices] = pMesh->mTextureCoords[c][iIndex];
 266.582 +						}
 266.583 +					}
 266.584 +					// vertex colors 
 266.585 +					for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
 266.586 +					{
 266.587 +						if (pMesh->HasVertexColors( c))
 266.588 +						{
 266.589 +							pcMesh->mColors[c][pcMesh->mNumVertices] = pMesh->mColors[c][iIndex];
 266.590 +						}
 266.591 +					}
 266.592 +					// check whether we have bone weights assigned to this vertex
 266.593 +					rFace.mIndices[v] = pcMesh->mNumVertices;
 266.594 +					if (avPerVertexWeights)
 266.595 +					{
 266.596 +						VertexWeightTable& table = avPerVertexWeights[ pcMesh->mNumVertices ];
 266.597 +						if( !table.empty() )
 266.598 +						{
 266.599 +							for (VertexWeightTable::const_iterator
 266.600 +								iter =  table.begin();
 266.601 +								iter != table.end();++iter)
 266.602 +							{
 266.603 +								// allocate the bone weight array if necessary
 266.604 +								BoneWeightList* pcWeightList = (BoneWeightList*)pcMesh->mBones[(*iter).first];
 266.605 +								if (!pcWeightList)
 266.606 +								{
 266.607 +									pcMesh->mBones[(*iter).first] = (aiBone*)(pcWeightList = new BoneWeightList());
 266.608 +								}
 266.609 +								pcWeightList->push_back(aiVertexWeight(pcMesh->mNumVertices,(*iter).second));
 266.610 +							}
 266.611 +						}
 266.612 +					}
 266.613 +
 266.614 +					avWasCopied[iIndex] = pcMesh->mNumVertices;
 266.615 +					pcMesh->mNumVertices++;
 266.616 +				}
 266.617 +				iBase++;
 266.618 +				if(pcMesh->mNumVertices == iOutVertexNum)
 266.619 +				{
 266.620 +					// break here. The face is only added if it was complete
 266.621 +					break;
 266.622 +				}
 266.623 +			}
 266.624 +
 266.625 +			// check which bones we'll need to create for this submesh
 266.626 +			if (pMesh->HasBones())
 266.627 +			{
 266.628 +				aiBone** ppCurrent = pcMesh->mBones;
 266.629 +				for (unsigned int k = 0; k < pMesh->mNumBones;++k)
 266.630 +				{
 266.631 +					// check whether the bone is existing
 266.632 +					BoneWeightList* pcWeightList;
 266.633 +					if ((pcWeightList = (BoneWeightList*)pcMesh->mBones[k]))
 266.634 +					{
 266.635 +						aiBone* pcOldBone = pMesh->mBones[k];
 266.636 +						aiBone* pcOut;
 266.637 +						*ppCurrent++ = pcOut = new aiBone();
 266.638 +						pcOut->mName = aiString(pcOldBone->mName);
 266.639 +						pcOut->mOffsetMatrix = pcOldBone->mOffsetMatrix;
 266.640 +						pcOut->mNumWeights = (unsigned int)pcWeightList->size();
 266.641 +						pcOut->mWeights = new aiVertexWeight[pcOut->mNumWeights];
 266.642 +
 266.643 +						// copy the vertex weights
 266.644 +						::memcpy(pcOut->mWeights,&pcWeightList->operator[](0),
 266.645 +							pcOut->mNumWeights * sizeof(aiVertexWeight));
 266.646 +
 266.647 +						// delete the temporary bone weight list
 266.648 +						delete pcWeightList;
 266.649 +						pcMesh->mNumBones++;
 266.650 +					}
 266.651 +				}
 266.652 +			}
 266.653 +
 266.654 +			// copy the face list to the mesh
 266.655 +			pcMesh->mFaces = new aiFace[vFaces.size()];
 266.656 +			pcMesh->mNumFaces = (unsigned int)vFaces.size();
 266.657 +
 266.658 +			for (unsigned int p = 0; p < pcMesh->mNumFaces;++p)
 266.659 +				pcMesh->mFaces[p] = vFaces[p];
 266.660 +
 266.661 +			// add the newly created mesh to the list
 266.662 +			avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a));
 266.663 +
 266.664 +			if (iBase == pMesh->mNumFaces)
 266.665 +			{
 266.666 +				// have all faces ... finish the outer loop, too
 266.667 +				break;
 266.668 +			}
 266.669 +		}
 266.670 +
 266.671 +		// delete the per-vertex weight list again
 266.672 +		delete[] avPerVertexWeights;
 266.673 +
 266.674 +		// now delete the old mesh data
 266.675 +		delete pMesh;
 266.676 +		return;
 266.677 +	}
 266.678 +	avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
 266.679 +	return;
 266.680 +}
   267.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   267.2 +++ b/libs/assimp/SplitLargeMeshes.h	Sat Feb 01 19:58:19 2014 +0200
   267.3 @@ -0,0 +1,207 @@
   267.4 +/*
   267.5 +Open Asset Import Library (assimp)
   267.6 +----------------------------------------------------------------------
   267.7 +
   267.8 +Copyright (c) 2006-2012, assimp team
   267.9 +All rights reserved.
  267.10 +
  267.11 +Redistribution and use of this software in source and binary forms, 
  267.12 +with or without modification, are permitted provided that the 
  267.13 +following conditions are met:
  267.14 +
  267.15 +* Redistributions of source code must retain the above
  267.16 +  copyright notice, this list of conditions and the
  267.17 +  following disclaimer.
  267.18 +
  267.19 +* Redistributions in binary form must reproduce the above
  267.20 +  copyright notice, this list of conditions and the
  267.21 +  following disclaimer in the documentation and/or other
  267.22 +  materials provided with the distribution.
  267.23 +
  267.24 +* Neither the name of the assimp team, nor the names of its
  267.25 +  contributors may be used to endorse or promote products
  267.26 +  derived from this software without specific prior
  267.27 +  written permission of the assimp team.
  267.28 +
  267.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  267.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  267.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  267.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  267.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  267.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  267.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  267.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  267.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  267.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  267.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  267.40 +
  267.41 +----------------------------------------------------------------------
  267.42 +*/
  267.43 +
  267.44 +/** @file Defines a post processing step to split large meshes into submeshes
  267.45 + */
  267.46 +#ifndef AI_SPLITLARGEMESHES_H_INC
  267.47 +#define AI_SPLITLARGEMESHES_H_INC
  267.48 +
  267.49 +#include <vector>
  267.50 +#include "BaseProcess.h"
  267.51 +
  267.52 +#include "assimp/mesh.h"
  267.53 +#include "assimp/scene.h"
  267.54 +
  267.55 +class SplitLargeMeshesTest;
  267.56 +namespace Assimp
  267.57 +{
  267.58 +
  267.59 +class SplitLargeMeshesProcess_Triangle; 
  267.60 +class SplitLargeMeshesProcess_Vertex; 
  267.61 +
  267.62 +// NOTE: If you change these limits, don't forget to change the
  267.63 +// corresponding values in all Assimp ports
  267.64 +
  267.65 +// **********************************************************
  267.66 +// Java: ConfigProperty.java, 
  267.67 +//  ConfigProperty.DEFAULT_VERTEX_SPLIT_LIMIT
  267.68 +//  ConfigProperty.DEFAULT_TRIANGLE_SPLIT_LIMIT
  267.69 +// **********************************************************
  267.70 +
  267.71 +// default limit for vertices
  267.72 +#if (!defined AI_SLM_DEFAULT_MAX_VERTICES)
  267.73 +#	define AI_SLM_DEFAULT_MAX_VERTICES		1000000
  267.74 +#endif
  267.75 +
  267.76 +// default limit for triangles
  267.77 +#if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES)
  267.78 +#	define AI_SLM_DEFAULT_MAX_TRIANGLES		1000000
  267.79 +#endif
  267.80 +
  267.81 +// ---------------------------------------------------------------------------
  267.82 +/** Postprocessing filter to split large meshes into submeshes
  267.83 + *
  267.84 + * Applied BEFORE the JoinVertices-Step occurs.
  267.85 + * Returns NON-UNIQUE vertices, splits by triangle number.
  267.86 +*/
  267.87 +class SplitLargeMeshesProcess_Triangle : public BaseProcess
  267.88 +{
  267.89 +	friend class SplitLargeMeshesProcess_Vertex;
  267.90 +
  267.91 +public:
  267.92 +
  267.93 +	SplitLargeMeshesProcess_Triangle();
  267.94 +	~SplitLargeMeshesProcess_Triangle();
  267.95 +
  267.96 +public:
  267.97 +	// -------------------------------------------------------------------
  267.98 +	/** Returns whether the processing step is present in the given flag.
  267.99 +	* @param pFlags The processing flags the importer was called with. A
 267.100 + 	*   bitwise combination of #aiPostProcessSteps.
 267.101 +	* @return true if the process is present in this flag fields, 
 267.102 + 	*   false if not.
 267.103 +	*/
 267.104 +	bool IsActive( unsigned int pFlags) const;
 267.105 +
 267.106 +
 267.107 +	// -------------------------------------------------------------------
 267.108 +	/** Called prior to ExecuteOnScene().
 267.109 +	* The function is a request to the process to update its configuration
 267.110 +	* basing on the Importer's configuration property list.
 267.111 +	*/
 267.112 +	virtual void SetupProperties(const Importer* pImp);
 267.113 +
 267.114 +
 267.115 +	//! Set the split limit - needed for unit testing
 267.116 +	inline void SetLimit(unsigned int l)
 267.117 +		{LIMIT = l;}
 267.118 +
 267.119 +	//! Get the split limit
 267.120 +	inline unsigned int GetLimit() const
 267.121 +		{return LIMIT;}
 267.122 +
 267.123 +public:
 267.124 +
 267.125 +	// -------------------------------------------------------------------
 267.126 +	/** Executes the post processing step on the given imported data.
 267.127 +	* At the moment a process is not supposed to fail.
 267.128 +	* @param pScene The imported data to work at.
 267.129 +	*/
 267.130 +	void Execute( aiScene* pScene);
 267.131 +
 267.132 +	// -------------------------------------------------------------------
 267.133 +	//! Apply the algorithm to a given mesh
 267.134 +	void SplitMesh (unsigned int a, aiMesh* pcMesh,
 267.135 +		std::vector<std::pair<aiMesh*, unsigned int> >& avList);
 267.136 +
 267.137 +	// -------------------------------------------------------------------
 267.138 +	//! Update a node in the asset after a few of its meshes 
 267.139 +	//! have been split
 267.140 +	static void UpdateNode(aiNode* pcNode,
 267.141 +		const std::vector<std::pair<aiMesh*, unsigned int> >& avList);
 267.142 +
 267.143 +public:
 267.144 +	//! Triangle limit 
 267.145 +	unsigned int LIMIT;
 267.146 +};
 267.147 +
 267.148 +
 267.149 +// ---------------------------------------------------------------------------
 267.150 +/** Postprocessing filter to split large meshes into submeshes
 267.151 + *
 267.152 + * Applied AFTER the JoinVertices-Step occurs.
 267.153 + * Returns UNIQUE vertices, splits by vertex number.
 267.154 +*/
 267.155 +class SplitLargeMeshesProcess_Vertex : public BaseProcess
 267.156 +{
 267.157 +public:
 267.158 +
 267.159 +	SplitLargeMeshesProcess_Vertex();
 267.160 +	~SplitLargeMeshesProcess_Vertex();
 267.161 +
 267.162 +public:
 267.163 +	// -------------------------------------------------------------------
 267.164 +	/** Returns whether the processing step is present in the given flag field.
 267.165 +	* @param pFlags The processing flags the importer was called with. A bitwise
 267.166 +	*   combination of #aiPostProcessSteps.
 267.167 +	* @return true if the process is present in this flag fields, false if not.
 267.168 +	*/
 267.169 +	bool IsActive( unsigned int pFlags) const;
 267.170 +
 267.171 +	// -------------------------------------------------------------------
 267.172 +	/** Called prior to ExecuteOnScene().
 267.173 +	* The function is a request to the process to update its configuration
 267.174 +	* basing on the Importer's configuration property list.
 267.175 +	*/
 267.176 +	virtual void SetupProperties(const Importer* pImp);
 267.177 +
 267.178 +
 267.179 +	//! Set the split limit - needed for unit testing
 267.180 +	inline void SetLimit(unsigned int l)
 267.181 +		{LIMIT = l;}
 267.182 +
 267.183 +	//! Get the split limit
 267.184 +	inline unsigned int GetLimit() const
 267.185 +		{return LIMIT;}
 267.186 +
 267.187 +public:
 267.188 +
 267.189 +	// -------------------------------------------------------------------
 267.190 +	/** Executes the post processing step on the given imported data.
 267.191 +	* At the moment a process is not supposed to fail.
 267.192 +	* @param pScene The imported data to work at.
 267.193 +	*/
 267.194 +	void Execute( aiScene* pScene);
 267.195 +
 267.196 +	// -------------------------------------------------------------------
 267.197 +	//! Apply the algorithm to a given mesh
 267.198 +	void SplitMesh (unsigned int a, aiMesh* pcMesh,
 267.199 +		std::vector<std::pair<aiMesh*, unsigned int> >& avList);
 267.200 +
 267.201 +	// NOTE: Reuse SplitLargeMeshesProcess_Triangle::UpdateNode()
 267.202 +
 267.203 +public:
 267.204 +	//! Triangle limit 
 267.205 +	unsigned int LIMIT;
 267.206 +};
 267.207 +
 267.208 +} // end of namespace Assimp
 267.209 +
 267.210 +#endif // !!AI_SPLITLARGEMESHES_H_INC
   268.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   268.2 +++ b/libs/assimp/StandardShapes.cpp	Sat Feb 01 19:58:19 2014 +0200
   268.3 @@ -0,0 +1,502 @@
   268.4 +/*
   268.5 +Open Asset Import Library (assimp)
   268.6 +----------------------------------------------------------------------
   268.7 +
   268.8 +Copyright (c) 2006-2012, assimp team
   268.9 +All rights reserved.
  268.10 +
  268.11 +Redistribution and use of this software in source and binary forms, 
  268.12 +with or without modification, are permitted provided that the 
  268.13 +following conditions are met:
  268.14 +
  268.15 +* Redistributions of source code must retain the above
  268.16 +  copyright notice, this list of conditions and the
  268.17 +  following disclaimer.
  268.18 +
  268.19 +* Redistributions in binary form must reproduce the above
  268.20 +  copyright notice, this list of conditions and the
  268.21 +  following disclaimer in the documentation and/or other
  268.22 +  materials provided with the distribution.
  268.23 +
  268.24 +* Neither the name of the assimp team, nor the names of its
  268.25 +  contributors may be used to endorse or promote products
  268.26 +  derived from this software without specific prior
  268.27 +  written permission of the assimp team.
  268.28 +
  268.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  268.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  268.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  268.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  268.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  268.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  268.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  268.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  268.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  268.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  268.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  268.40 +
  268.41 +----------------------------------------------------------------------
  268.42 +*/
  268.43 +
  268.44 +/** @file   StandardShapes.cpp
  268.45 + *  @brief  Implementation of the StandardShapes class
  268.46 + *
  268.47 + *  The primitive geometry data comes from 
  268.48 + *  http://geometrictools.com/Documentation/PlatonicSolids.pdf.
  268.49 + */
  268.50 +
  268.51 +#include "AssimpPCH.h"
  268.52 +#include "StandardShapes.h"
  268.53 +
  268.54 +namespace Assimp	{
  268.55 +
  268.56 +	
  268.57 +# define ADD_TRIANGLE(n0,n1,n2) \
  268.58 +	positions.push_back(n0); \
  268.59 +	positions.push_back(n1); \
  268.60 +	positions.push_back(n2);
  268.61 +
  268.62 +#	define ADD_PENTAGON(n0,n1,n2,n3,n4) \
  268.63 +	if (polygons) \
  268.64 +	{ \
  268.65 +		positions.push_back(n0); \
  268.66 +		positions.push_back(n1); \
  268.67 +		positions.push_back(n2); \
  268.68 +		positions.push_back(n3); \
  268.69 +		positions.push_back(n4); \
  268.70 +	} \
  268.71 +	else \
  268.72 +	{ \
  268.73 +		ADD_TRIANGLE(n0, n1, n2) \
  268.74 +		ADD_TRIANGLE(n0, n2, n3) \
  268.75 +		ADD_TRIANGLE(n0, n3, n4) \
  268.76 +	}
  268.77 +
  268.78 +#	define ADD_QUAD(n0,n1,n2,n3) \
  268.79 +	if (polygons) \
  268.80 +	{ \
  268.81 +		positions.push_back(n0); \
  268.82 +		positions.push_back(n1); \
  268.83 +		positions.push_back(n2); \
  268.84 +		positions.push_back(n3); \
  268.85 +	} \
  268.86 +	else \
  268.87 +	{ \
  268.88 +		ADD_TRIANGLE(n0, n1, n2) \
  268.89 +		ADD_TRIANGLE(n0, n2, n3) \
  268.90 +	}
  268.91 +
  268.92 +
  268.93 +// ------------------------------------------------------------------------------------------------
  268.94 +// Fast subdivision for a mesh whose verts have a magnitude of 1
  268.95 +void Subdivide(std::vector<aiVector3D>& positions)
  268.96 +{
  268.97 +	// assume this to be constant - (fixme: must be 1.0? I think so)
  268.98 +	const float fl1 = positions[0].Length();
  268.99 +
 268.100 +	unsigned int origSize = (unsigned int)positions.size();
 268.101 +	for (unsigned int i = 0 ; i < origSize ; i+=3)
 268.102 +	{
 268.103 +		aiVector3D& tv0 = positions[i];
 268.104 +		aiVector3D& tv1 = positions[i+1];
 268.105 +		aiVector3D& tv2 = positions[i+2];
 268.106 +
 268.107 +		aiVector3D a = tv0, b = tv1, c = tv2;
 268.108 +		aiVector3D v1 = aiVector3D(a.x+b.x, a.y+b.y, a.z+b.z).Normalize()*fl1;
 268.109 +		aiVector3D v2 = aiVector3D(a.x+c.x, a.y+c.y, a.z+c.z).Normalize()*fl1;
 268.110 +		aiVector3D v3 = aiVector3D(b.x+c.x, b.y+c.y, b.z+c.z).Normalize()*fl1;
 268.111 +
 268.112 +		tv0 = v1; tv1 = v3; tv2 = v2; // overwrite the original
 268.113 +		ADD_TRIANGLE(v1, v2, a);
 268.114 +		ADD_TRIANGLE(v2, v3, c);
 268.115 +		ADD_TRIANGLE(v3, v1, b);
 268.116 +	}
 268.117 +}
 268.118 +
 268.119 +// ------------------------------------------------------------------------------------------------
 268.120 +// Construct a mesh from given vertex positions
 268.121 +aiMesh* StandardShapes::MakeMesh(const std::vector<aiVector3D>& positions,
 268.122 +	unsigned int numIndices)
 268.123 +{
 268.124 +	if (positions.size() & numIndices || positions.empty() || !numIndices)
 268.125 +		return NULL;
 268.126 +
 268.127 +	// Determine which kinds of primitives the mesh consists of
 268.128 +	aiMesh* out = new aiMesh();
 268.129 +	switch (numIndices)
 268.130 +	{
 268.131 +	case 1: 
 268.132 +		out->mPrimitiveTypes = aiPrimitiveType_POINT;
 268.133 +		break;
 268.134 +	case 2:
 268.135 +		out->mPrimitiveTypes = aiPrimitiveType_LINE;
 268.136 +		break;
 268.137 +	case 3:
 268.138 +		out->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 268.139 +		break;
 268.140 +	default:
 268.141 +		out->mPrimitiveTypes = aiPrimitiveType_POLYGON;
 268.142 +		break;
 268.143 +	};
 268.144 +
 268.145 +	out->mNumFaces = (unsigned int)positions.size() / numIndices;
 268.146 +	out->mFaces = new aiFace[out->mNumFaces];
 268.147 +	for (unsigned int i = 0, a = 0; i < out->mNumFaces;++i)
 268.148 +	{
 268.149 +		aiFace& f = out->mFaces[i];
 268.150 +		f.mNumIndices = numIndices;
 268.151 +		f.mIndices = new unsigned int[numIndices];
 268.152 +		for (unsigned int i = 0; i < numIndices;++i,++a)
 268.153 +			f.mIndices[i] = a;
 268.154 +	}
 268.155 +	out->mNumVertices = (unsigned int)positions.size();
 268.156 +	out->mVertices = new aiVector3D[out->mNumVertices];
 268.157 +	::memcpy(out->mVertices,&positions[0],out->mNumVertices*sizeof(aiVector3D));
 268.158 +	return out;
 268.159 +}
 268.160 +
 268.161 +// ------------------------------------------------------------------------------------------------
 268.162 +// Construct a mesh with a specific shape (callback)
 268.163 +aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
 268.164 +	std::vector<aiVector3D>&))
 268.165 +{
 268.166 +	std::vector<aiVector3D> temp;
 268.167 +	unsigned num = (*GenerateFunc)(temp);
 268.168 +	return MakeMesh(temp,num);
 268.169 +}
 268.170 +
 268.171 +// ------------------------------------------------------------------------------------------------
 268.172 +// Construct a mesh with a specific shape (callback)
 268.173 +aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
 268.174 +	std::vector<aiVector3D>&, bool))
 268.175 +{
 268.176 +	std::vector<aiVector3D> temp;
 268.177 +	unsigned num = (*GenerateFunc)(temp,true);
 268.178 +	return MakeMesh(temp,num);
 268.179 +}
 268.180 +
 268.181 +// ------------------------------------------------------------------------------------------------
 268.182 +// Construct a mesh with a specific shape (callback)
 268.183 +aiMesh* StandardShapes::MakeMesh (unsigned int num,  void (*GenerateFunc)(
 268.184 +	unsigned int,std::vector<aiVector3D>&))
 268.185 +{
 268.186 +	std::vector<aiVector3D> temp;
 268.187 +	(*GenerateFunc)(num,temp);
 268.188 +	return MakeMesh(temp,3);
 268.189 +}
 268.190 +
 268.191 +// ------------------------------------------------------------------------------------------------
 268.192 +// Build an incosahedron with points.magnitude == 1
 268.193 +unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions)
 268.194 +{
 268.195 +	positions.reserve(positions.size()+60);
 268.196 +
 268.197 +	const float t = (1.f + 2.236067977f)/2.f;
 268.198 +	const float s = sqrt(1.f + t*t);
 268.199 +	
 268.200 +	const aiVector3D v0  = aiVector3D(t,1.f, 0.f)/s;
 268.201 +	const aiVector3D v1  = aiVector3D(-t,1.f, 0.f)/s;
 268.202 +	const aiVector3D v2  = aiVector3D(t,-1.f, 0.f)/s;
 268.203 +	const aiVector3D v3  = aiVector3D(-t,-1.f, 0.f)/s;
 268.204 +	const aiVector3D v4  = aiVector3D(1.f, 0.f, t)/s;
 268.205 +	const aiVector3D v5  = aiVector3D(1.f, 0.f,-t)/s;
 268.206 +	const aiVector3D v6  = aiVector3D(-1.f, 0.f,t)/s;
 268.207 +	const aiVector3D v7  = aiVector3D(-1.f, 0.f,-t)/s;
 268.208 +	const aiVector3D v8  = aiVector3D(0.f, t, 1.f)/s;
 268.209 +	const aiVector3D v9  = aiVector3D(0.f,-t, 1.f)/s;
 268.210 +	const aiVector3D v10 = aiVector3D(0.f, t,-1.f)/s;
 268.211 +	const aiVector3D v11 = aiVector3D(0.f,-t,-1.f)/s;
 268.212 +
 268.213 +	ADD_TRIANGLE(v0,v8,v4);
 268.214 +	ADD_TRIANGLE(v0,v5,v10);
 268.215 +	ADD_TRIANGLE(v2,v4,v9);
 268.216 +	ADD_TRIANGLE(v2,v11,v5);
 268.217 +
 268.218 +	ADD_TRIANGLE(v1,v6,v8);
 268.219 +	ADD_TRIANGLE(v1,v10,v7);
 268.220 +	ADD_TRIANGLE(v3,v9,v6);
 268.221 +	ADD_TRIANGLE(v3,v7,v11);
 268.222 +
 268.223 +	ADD_TRIANGLE(v0,v10,v8);
 268.224 +	ADD_TRIANGLE(v1,v8,v10);
 268.225 +	ADD_TRIANGLE(v2,v9,v11);
 268.226 +	ADD_TRIANGLE(v3,v11,v9);
 268.227 +
 268.228 +	ADD_TRIANGLE(v4,v2,v0);
 268.229 +	ADD_TRIANGLE(v5,v0,v2);
 268.230 +	ADD_TRIANGLE(v6,v1,v3);
 268.231 +	ADD_TRIANGLE(v7,v3,v1);
 268.232 +
 268.233 +	ADD_TRIANGLE(v8,v6,v4);
 268.234 +	ADD_TRIANGLE(v9,v4,v6);
 268.235 +	ADD_TRIANGLE(v10,v5,v7);
 268.236 +	ADD_TRIANGLE(v11,v7,v5);
 268.237 +	return 3;
 268.238 +}
 268.239 +
 268.240 +// ------------------------------------------------------------------------------------------------
 268.241 +// Build a dodecahedron with points.magnitude == 1
 268.242 +unsigned int StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions,
 268.243 +	bool polygons /*= false*/)
 268.244 +{
 268.245 +	positions.reserve(positions.size()+108);
 268.246 +
 268.247 +	const float a = 1.f / 1.7320508f;
 268.248 +	const float b = sqrt((3.f-2.23606797f)/6.f);
 268.249 +	const float c = sqrt((3.f+2.23606797f)/6.f);
 268.250 +
 268.251 +	const aiVector3D v0  = aiVector3D(a,a,a);
 268.252 +	const aiVector3D v1  = aiVector3D(a,a,-a);
 268.253 +	const aiVector3D v2  = aiVector3D(a,-a,a);
 268.254 +	const aiVector3D v3  = aiVector3D(a,-a,-a);
 268.255 +	const aiVector3D v4  = aiVector3D(-a,a,a);
 268.256 +	const aiVector3D v5  = aiVector3D(-a,a,-a);
 268.257 +	const aiVector3D v6  = aiVector3D(-a,-a,a);
 268.258 +	const aiVector3D v7  = aiVector3D(-a,-a,-a);
 268.259 +	const aiVector3D v8  = aiVector3D(b,c,0.f);
 268.260 +	const aiVector3D v9  = aiVector3D(-b,c,0.f);
 268.261 +	const aiVector3D v10 = aiVector3D(b,-c,0.f);
 268.262 +	const aiVector3D v11 = aiVector3D(-b,-c,0.f);
 268.263 +	const aiVector3D v12 = aiVector3D(c, 0.f, b);
 268.264 +	const aiVector3D v13 = aiVector3D(c, 0.f, -b);
 268.265 +	const aiVector3D v14 = aiVector3D(-c, 0.f, b);
 268.266 +	const aiVector3D v15 = aiVector3D(-c, 0.f, -b);
 268.267 +	const aiVector3D v16 = aiVector3D(0.f, b, c);
 268.268 +	const aiVector3D v17 = aiVector3D(0.f, -b, c);
 268.269 +	const aiVector3D v18 = aiVector3D(0.f, b, -c);
 268.270 +	const aiVector3D v19 = aiVector3D(0.f, -b, -c);
 268.271 +
 268.272 +	ADD_PENTAGON(v0, v8, v9, v4, v16);
 268.273 +	ADD_PENTAGON(v0, v12, v13, v1, v8);
 268.274 +	ADD_PENTAGON(v0, v16, v17, v2, v12);
 268.275 +	ADD_PENTAGON(v8, v1, v18, v5, v9);
 268.276 +	ADD_PENTAGON(v12, v2, v10, v3, v13);
 268.277 +	ADD_PENTAGON(v16, v4, v14, v6, v17);
 268.278 +	ADD_PENTAGON(v9, v5, v15, v14, v4);
 268.279 +
 268.280 +	ADD_PENTAGON(v6, v11, v10, v2, v17);
 268.281 +	ADD_PENTAGON(v3, v19, v18, v1, v13);
 268.282 +	ADD_PENTAGON(v7, v15, v5, v18, v19);
 268.283 +	ADD_PENTAGON(v7, v11, v6, v14, v15);
 268.284 +	ADD_PENTAGON(v7, v19, v3, v10, v11);
 268.285 +	return (polygons ? 5 : 3);
 268.286 +}
 268.287 +
 268.288 +// ------------------------------------------------------------------------------------------------
 268.289 +// Build an octahedron with points.magnitude == 1
 268.290 +unsigned int StandardShapes::MakeOctahedron(std::vector<aiVector3D>& positions)
 268.291 +{
 268.292 +	positions.reserve(positions.size()+24);
 268.293 +
 268.294 +	const aiVector3D v0  = aiVector3D(1.0f, 0.f, 0.f) ;
 268.295 +	const aiVector3D v1  = aiVector3D(-1.0f, 0.f, 0.f);
 268.296 +	const aiVector3D v2  = aiVector3D(0.f, 1.0f, 0.f);
 268.297 +	const aiVector3D v3  = aiVector3D(0.f, -1.0f, 0.f);
 268.298 +	const aiVector3D v4  = aiVector3D(0.f, 0.f, 1.0f);
 268.299 +	const aiVector3D v5  = aiVector3D(0.f, 0.f, -1.0f);
 268.300 +
 268.301 +	ADD_TRIANGLE(v4,v0,v2);
 268.302 +	ADD_TRIANGLE(v4,v2,v1);
 268.303 +	ADD_TRIANGLE(v4,v1,v3);
 268.304 +	ADD_TRIANGLE(v4,v3,v0);
 268.305 +
 268.306 +	ADD_TRIANGLE(v5,v2,v0);
 268.307 +	ADD_TRIANGLE(v5,v1,v2);
 268.308 +	ADD_TRIANGLE(v5,v3,v1);
 268.309 +	ADD_TRIANGLE(v5,v0,v3);
 268.310 +	return 3;
 268.311 +}
 268.312 +
 268.313 +// ------------------------------------------------------------------------------------------------
 268.314 +// Build a tetrahedron with points.magnitude == 1
 268.315 +unsigned int StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions)
 268.316 +{
 268.317 +	positions.reserve(positions.size()+9);
 268.318 +
 268.319 +	const float a = 1.41421f/3.f;
 268.320 +	const float b = 2.4494f/3.f;
 268.321 +
 268.322 +	const aiVector3D v0  = aiVector3D(0.f,0.f,1.f);
 268.323 +	const aiVector3D v1  = aiVector3D(2*a,0,-1.f/3.f);
 268.324 +	const aiVector3D v2  = aiVector3D(-a,b,-1.f/3.f);
 268.325 +	const aiVector3D v3  = aiVector3D(-a,-b,-1.f/3.f);
 268.326 +
 268.327 +	ADD_TRIANGLE(v0,v1,v2);
 268.328 +	ADD_TRIANGLE(v0,v2,v3);
 268.329 +	ADD_TRIANGLE(v0,v3,v1);
 268.330 +	ADD_TRIANGLE(v1,v3,v2);
 268.331 +	return 3;
 268.332 +}
 268.333 +
 268.334 +// ------------------------------------------------------------------------------------------------
 268.335 +// Build a hexahedron with points.magnitude == 1
 268.336 +unsigned int StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions,
 268.337 +	bool polygons /*= false*/)
 268.338 +{
 268.339 +	positions.reserve(positions.size()+36);
 268.340 +	const float length = 1.f/1.73205080f;
 268.341 +
 268.342 +	const aiVector3D v0  = aiVector3D(-1.f,-1.f,-1.f)*length;
 268.343 +	const aiVector3D v1  = aiVector3D(1.f,-1.f,-1.f)*length;
 268.344 +	const aiVector3D v2  = aiVector3D(1.f,1.f,-1.f)*length;
 268.345 +	const aiVector3D v3  = aiVector3D(-1.f,1.f,-1.f)*length;
 268.346 +	const aiVector3D v4  = aiVector3D(-1.f,-1.f,1.f)*length;
 268.347 +	const aiVector3D v5  = aiVector3D(1.f,-1.f,1.f)*length;
 268.348 +	const aiVector3D v6  = aiVector3D(1.f,1.f,1.f)*length;
 268.349 +	const aiVector3D v7  = aiVector3D(-1.f,1.f,1.f)*length;
 268.350 +
 268.351 +	ADD_QUAD(v0,v3,v2,v1);
 268.352 +	ADD_QUAD(v0,v1,v5,v4);
 268.353 +	ADD_QUAD(v0,v4,v7,v3);
 268.354 +	ADD_QUAD(v6,v5,v1,v2);
 268.355 +	ADD_QUAD(v6,v2,v3,v7);
 268.356 +	ADD_QUAD(v6,v7,v4,v5);
 268.357 +	return (polygons ? 4 : 3);
 268.358 +}
 268.359 +
 268.360 +// Cleanup ...
 268.361 +#undef ADD_TRIANGLE
 268.362 +#undef ADD_QUAD
 268.363 +#undef ADD_PENTAGON
 268.364 +
 268.365 +// ------------------------------------------------------------------------------------------------
 268.366 +// Create a subdivision sphere
 268.367 +void StandardShapes::MakeSphere(unsigned int	tess,
 268.368 +	std::vector<aiVector3D>& positions)
 268.369 +{
 268.370 +	// Reserve enough storage. Every subdivision
 268.371 +	// splits each triangle in 4, the icosahedron consists of 60 verts
 268.372 +	positions.reserve(positions.size()+60 * integer_pow(4, tess));
 268.373 +
 268.374 +	// Construct an icosahedron to start with 
 268.375 +	MakeIcosahedron(positions);
 268.376 +
 268.377 +	// ... and subdivide it until the requested output
 268.378 +	// tesselation is reached
 268.379 +	for (unsigned int i = 0; i<tess;++i)
 268.380 +		Subdivide(positions);
 268.381 +}
 268.382 +
 268.383 +// ------------------------------------------------------------------------------------------------
 268.384 +// Build a cone
 268.385 +void StandardShapes::MakeCone(float height,float radius1,
 268.386 +	float radius2,unsigned int tess, 
 268.387 +	std::vector<aiVector3D>& positions,bool bOpen /*= false */)
 268.388 +{
 268.389 +	// Sorry, a cone with less than 3 segments makes ABSOLUTELY NO SENSE
 268.390 +	if (tess < 3 || !height)
 268.391 +		return;
 268.392 +
 268.393 +	size_t old = positions.size();
 268.394 +
 268.395 +	// No negative radii
 268.396 +	radius1 = ::fabs(radius1);
 268.397 +	radius2 = ::fabs(radius2);
 268.398 +
 268.399 +	float halfHeight = height / 2;
 268.400 +
 268.401 +	// radius1 is always the smaller one 
 268.402 +	if (radius2 > radius1)
 268.403 +	{
 268.404 +		std::swap(radius2,radius1);
 268.405 +		halfHeight = -halfHeight;
 268.406 +	}
 268.407 +	else old = SIZE_MAX;
 268.408 +
 268.409 +	// Use a large epsilon to check whether the cone is pointy
 268.410 +	if (radius1 < (radius2-radius1)*10e-3f)radius1 = 0.f;
 268.411 +
 268.412 +	// We will need 3*2 verts per segment + 3*2 verts per segment
 268.413 +	// if the cone is closed
 268.414 +	const unsigned int mem = tess*6 + (!bOpen ? tess*3 * (radius1 ? 2 : 1) : 0);
 268.415 +	positions.reserve(positions.size () + mem);
 268.416 +
 268.417 +	// Now construct all segments
 268.418 +	const float angle_delta = (float)AI_MATH_TWO_PI / tess;
 268.419 +	const float angle_max   = (float)AI_MATH_TWO_PI;
 268.420 +
 268.421 +	float s = 1.f; // cos(angle == 0);
 268.422 +	float t = 0.f; // sin(angle == 0);
 268.423 +
 268.424 +	for (float angle = 0.f; angle < angle_max; )
 268.425 +	{
 268.426 +		const aiVector3D v1 = aiVector3D (s * radius1, -halfHeight, t * radius1 );
 268.427 +		const aiVector3D v2 = aiVector3D (s * radius2,  halfHeight, t * radius2 );
 268.428 +
 268.429 +		const float next = angle + angle_delta;
 268.430 +		float s2 = ::cos(next);
 268.431 +		float t2 = ::sin(next);
 268.432 +
 268.433 +		const aiVector3D v3 = aiVector3D (s2 * radius2,  halfHeight, t2 * radius2 );
 268.434 +		const aiVector3D v4 = aiVector3D (s2 * radius1, -halfHeight, t2 * radius1 );
 268.435 +
 268.436 +		positions.push_back(v1);
 268.437 +		positions.push_back(v2);
 268.438 +		positions.push_back(v3);
 268.439 +		positions.push_back(v4);
 268.440 +		positions.push_back(v1);
 268.441 +		positions.push_back(v3);
 268.442 +
 268.443 +		if (!bOpen)
 268.444 +		{
 268.445 +			// generate the end 'cap'
 268.446 +			positions.push_back(aiVector3D(s * radius2,  halfHeight, t * radius2 ));
 268.447 +			positions.push_back(aiVector3D(s2 * radius2,  halfHeight, t2 * radius2 ));
 268.448 +			positions.push_back(aiVector3D(0.f, halfHeight, 0.f));
 268.449 +			
 268.450 +
 268.451 +			if (radius1)
 268.452 +			{
 268.453 +				// generate the other end 'cap'
 268.454 +				positions.push_back(aiVector3D(s * radius1,  -halfHeight, t * radius1 ));
 268.455 +				positions.push_back(aiVector3D(s2 * radius1,  -halfHeight, t2 * radius1 ));
 268.456 +				positions.push_back(aiVector3D(0.f, -halfHeight, 0.f));
 268.457 +				
 268.458 +			}
 268.459 +		}
 268.460 +		s = s2;
 268.461 +		t = t2;
 268.462 +		angle = next;
 268.463 +	}
 268.464 +
 268.465 +	// Need to flip face order?
 268.466 +	if ( SIZE_MAX != old )	{
 268.467 +		for (size_t s = old; s < positions.size();s += 3) {
 268.468 +			std::swap(positions[s],positions[s+1]);
 268.469 +		}
 268.470 +	}
 268.471 +}
 268.472 +
 268.473 +// ------------------------------------------------------------------------------------------------
 268.474 +// Build a circle
 268.475 +void StandardShapes::MakeCircle(float radius, unsigned int tess,
 268.476 +	std::vector<aiVector3D>& positions)
 268.477 +{
 268.478 +	// Sorry, a circle with less than 3 segments makes ABSOLUTELY NO SENSE
 268.479 +	if (tess < 3 || !radius)
 268.480 +		return;
 268.481 +
 268.482 +	radius = ::fabs(radius);
 268.483 +
 268.484 +	// We will need 3 vertices per segment 
 268.485 +	positions.reserve(positions.size()+tess*3);
 268.486 +
 268.487 +	const float angle_delta = (float)AI_MATH_TWO_PI / tess;
 268.488 +	const float angle_max   = (float)AI_MATH_TWO_PI;
 268.489 +
 268.490 +	float s = 1.f; // cos(angle == 0);
 268.491 +	float t = 0.f; // sin(angle == 0);
 268.492 +
 268.493 +	for (float angle = 0.f; angle < angle_max;  )
 268.494 +	{
 268.495 +		positions.push_back(aiVector3D(s * radius,0.f,t * radius));
 268.496 +		angle += angle_delta;
 268.497 +		s = ::cos(angle);
 268.498 +		t = ::sin(angle);
 268.499 +		positions.push_back(aiVector3D(s * radius,0.f,t * radius));
 268.500 +
 268.501 +		positions.push_back(aiVector3D(0.f,0.f,0.f));
 268.502 +	}
 268.503 +}
 268.504 +
 268.505 +} // ! Assimp
   269.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   269.2 +++ b/libs/assimp/StandardShapes.h	Sat Feb 01 19:58:19 2014 +0200
   269.3 @@ -0,0 +1,196 @@
   269.4 +/*
   269.5 +Open Asset Import Library (assimp)
   269.6 +----------------------------------------------------------------------
   269.7 +
   269.8 +Copyright (c) 2006-2012, assimp team
   269.9 +All rights reserved.
  269.10 +
  269.11 +Redistribution and use of this software in source and binary forms, 
  269.12 +with or without modification, are permitted provided that the 
  269.13 +following conditions are met:
  269.14 +
  269.15 +* Redistributions of source code must retain the above
  269.16 +  copyright notice, this list of conditions and the
  269.17 +  following disclaimer.
  269.18 +
  269.19 +* Redistributions in binary form must reproduce the above
  269.20 +  copyright notice, this list of conditions and the
  269.21 +  following disclaimer in the documentation and/or other
  269.22 +  materials provided with the distribution.
  269.23 +
  269.24 +* Neither the name of the assimp team, nor the names of its
  269.25 +  contributors may be used to endorse or promote products
  269.26 +  derived from this software without specific prior
  269.27 +  written permission of the assimp team.
  269.28 +
  269.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  269.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  269.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  269.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  269.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  269.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  269.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  269.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  269.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  269.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  269.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  269.40 +
  269.41 +----------------------------------------------------------------------
  269.42 +*/
  269.43 +
  269.44 +/** @file Declares a helper class, "StandardShapes" which generates
  269.45 + *  vertices for standard shapes, such as cylnders, cones, spheres ..
  269.46 + */
  269.47 +#ifndef AI_STANDARD_SHAPES_H_INC
  269.48 +#define AI_STANDARD_SHAPES_H_INC
  269.49 +
  269.50 +#include <vector>
  269.51 +
  269.52 +
  269.53 +namespace Assimp	{
  269.54 +
  269.55 +// ---------------------------------------------------------------------------
  269.56 +/** \brief Helper class to generate vertex buffers for standard geometric
  269.57 + *  shapes, such as cylinders, cones, boxes, spheres, elipsoids ... .
  269.58 + */
  269.59 +class StandardShapes
  269.60 +{
  269.61 +	// class cannot be instanced
  269.62 +	StandardShapes() {}
  269.63 +
  269.64 +public:
  269.65 +
  269.66 +
  269.67 +	// ----------------------------------------------------------------
  269.68 +	/** Generates a mesh from an array of vertex positions.
  269.69 +	 *
  269.70 +	 *  @param positions List of vertex positions
  269.71 +	 *  @param numIndices Number of indices per primitive
  269.72 +	 *  @return Output mesh
  269.73 +	 */
  269.74 +	static aiMesh* MakeMesh(const std::vector<aiVector3D>& positions,
  269.75 +		unsigned int numIndices);
  269.76 +
  269.77 +
  269.78 +	static aiMesh* MakeMesh ( unsigned int (*GenerateFunc)
  269.79 +		(std::vector<aiVector3D>&));
  269.80 +
  269.81 +	static aiMesh* MakeMesh ( unsigned int (*GenerateFunc)
  269.82 +		(std::vector<aiVector3D>&, bool));
  269.83 +
  269.84 +	static aiMesh* MakeMesh ( unsigned int n,  void (*GenerateFunc)
  269.85 +		(unsigned int,std::vector<aiVector3D>&));
  269.86 +
  269.87 +	// ----------------------------------------------------------------
  269.88 +	/** @brief Generates a hexahedron (cube)
  269.89 +	 *
  269.90 +	 *  Hexahedrons can be scaled on all axes.
  269.91 +	 *  @param positions Receives output triangles.
  269.92 +	 *  @param polygons If you pass true here quads will be returned
  269.93 +	 *  @return Number of vertices per face
  269.94 +	 */
  269.95 +	static unsigned int MakeHexahedron(
  269.96 +		std::vector<aiVector3D>& positions,
  269.97 +		bool polygons = false);
  269.98 +
  269.99 +	// ----------------------------------------------------------------
 269.100 +	/** @brief Generates an icosahedron
 269.101 +	 *
 269.102 +	 *  @param positions Receives output triangles.
 269.103 +	 *  @return Number of vertices per face
 269.104 +	 */
 269.105 +	static unsigned int MakeIcosahedron(
 269.106 +		std::vector<aiVector3D>& positions);
 269.107 +
 269.108 +
 269.109 +	// ----------------------------------------------------------------
 269.110 +	/** @brief Generates a dodecahedron
 269.111 +	 *
 269.112 +	 *  @param positions Receives output triangles
 269.113 +	 *  @param polygons If you pass true here pentagons will be returned
 269.114 +	 *  @return Number of vertices per face
 269.115 +	 */
 269.116 +	static unsigned int MakeDodecahedron(
 269.117 +		std::vector<aiVector3D>& positions,
 269.118 +		bool polygons = false);
 269.119 +
 269.120 +
 269.121 +	// ----------------------------------------------------------------
 269.122 +	/** @brief Generates an octahedron
 269.123 +	 *
 269.124 +	 *  @param positions Receives output triangles.
 269.125 +	 *  @return Number of vertices per face
 269.126 +	 */
 269.127 +	static unsigned int MakeOctahedron(
 269.128 +		std::vector<aiVector3D>& positions);
 269.129 +
 269.130 +
 269.131 +	// ----------------------------------------------------------------
 269.132 +	/** @brief Generates a tetrahedron
 269.133 +	 *
 269.134 +	 *  @param positions Receives output triangles.
 269.135 +	 *  @return Number of vertices per face
 269.136 +	 */
 269.137 +	static unsigned int MakeTetrahedron(
 269.138 +		std::vector<aiVector3D>& positions);
 269.139 +
 269.140 +
 269.141 +
 269.142 +	// ----------------------------------------------------------------
 269.143 +	/** @brief Generates a sphere
 269.144 +	 *
 269.145 +	 *  @param tess Number of subdivions - 0 generates a octahedron
 269.146 +	 *  @param positions Receives output triangles.
 269.147 +	 */
 269.148 +	static void MakeSphere(unsigned int tess,
 269.149 +		std::vector<aiVector3D>& positions);
 269.150 +
 269.151 +
 269.152 +	// ----------------------------------------------------------------
 269.153 +	/** @brief Generates a cone or a cylinder, either open or closed.
 269.154 +	 *
 269.155 +	 *  @code
 269.156 +	 *
 269.157 +	 *       |-----|       <- radius 1
 269.158 +	 *
 269.159 +	 *        __x__        <- ]               ^
 269.160 +	 *       /     \          | height        |
 269.161 +	 *      /       \         |               Y                 
 269.162 +	 *     /         \        |
 269.163 +	 *    /	          \       |
 269.164 +	 *   /______x______\   <- ] <- end cap
 269.165 +	 *
 269.166 +	 *   |-------------|   <- radius 2
 269.167 +	 *
 269.168 +	 *  @endcode
 269.169 +	 *
 269.170 +	 *  @param height Height of the cone
 269.171 +	 *  @param radius1 First radius
 269.172 +	 *  @param radius2 Second radius
 269.173 +	 *  @param tess Number of triangles.
 269.174 +	 *  @param bOpened true for an open cone/cylinder. An open shape has
 269.175 +	 *    no 'end caps'
 269.176 +	 *  @param positions Receives output triangles
 269.177 +	 */
 269.178 +	static void MakeCone(float height,float radius1,
 269.179 +		float radius2,unsigned int tess, 
 269.180 +		std::vector<aiVector3D>& positions,bool bOpen= false);
 269.181 +
 269.182 +
 269.183 +	// ----------------------------------------------------------------
 269.184 +	/** @brief Generates a flat circle
 269.185 +	 *
 269.186 +	 *  The circle is constructed in the planed formed by the x,z
 269.187 +	 *  axes of the cartesian coordinate system.
 269.188 +	 *  
 269.189 +	 *  @param radius Radius of the circle
 269.190 +	 *  @param tess Number of segments.
 269.191 +	 *  @param positions Receives output triangles.
 269.192 +	 */
 269.193 +	static void MakeCircle(float radius, unsigned int tess,
 269.194 +		std::vector<aiVector3D>& positions);
 269.195 +	
 269.196 +};
 269.197 +} // ! Assimp
 269.198 +
 269.199 +#endif // !! AI_STANDARD_SHAPES_H_INC
   270.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   270.2 +++ b/libs/assimp/StdOStreamLogStream.h	Sat Feb 01 19:58:19 2014 +0200
   270.3 @@ -0,0 +1,52 @@
   270.4 +#ifndef AI_STROSTREAMLOGSTREAM_H_INC
   270.5 +#define AI_STROSTREAMLOGSTREAM_H_INC
   270.6 +
   270.7 +#include "assimp/LogStream.hpp"
   270.8 +#include <ostream>
   270.9 +
  270.10 +namespace Assimp	{
  270.11 +
  270.12 +// ---------------------------------------------------------------------------
  270.13 +/**	@class	StdOStreamLogStream
  270.14 + *	@brief	Logs into a std::ostream
  270.15 + */
  270.16 +class StdOStreamLogStream : public LogStream
  270.17 +{
  270.18 +public:
  270.19 +	/**	@brief	Construction from an existing std::ostream	
  270.20 +	 *  @param _ostream Output stream to be used
  270.21 +	*/
  270.22 +	StdOStreamLogStream(std::ostream& _ostream);
  270.23 +
  270.24 +	/**	@brief	Destructor	*/
  270.25 +	~StdOStreamLogStream();
  270.26 +	
  270.27 +	/**	@brief	Writer	*/
  270.28 +	void write(const char* message);
  270.29 +private:
  270.30 +	std::ostream& ostream;
  270.31 +};
  270.32 +
  270.33 +// ---------------------------------------------------------------------------
  270.34 +//	Default constructor
  270.35 +inline StdOStreamLogStream::StdOStreamLogStream(std::ostream& _ostream)
  270.36 +	: ostream	(_ostream)
  270.37 +{}
  270.38 +
  270.39 +// ---------------------------------------------------------------------------
  270.40 +//	Default constructor
  270.41 +inline StdOStreamLogStream::~StdOStreamLogStream()
  270.42 +{}
  270.43 +
  270.44 +// ---------------------------------------------------------------------------
  270.45 +//	Write method
  270.46 +inline void StdOStreamLogStream::write(const char* message)
  270.47 +{
  270.48 +	ostream << message;
  270.49 +	ostream.flush();
  270.50 +}
  270.51 +
  270.52 +// ---------------------------------------------------------------------------
  270.53 +}	// Namespace Assimp
  270.54 +
  270.55 +#endif // guard
   271.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   271.2 +++ b/libs/assimp/StreamReader.h	Sat Feb 01 19:58:19 2014 +0200
   271.3 @@ -0,0 +1,358 @@
   271.4 +/*
   271.5 +---------------------------------------------------------------------------
   271.6 +Open Asset Import Library (assimp)
   271.7 +---------------------------------------------------------------------------
   271.8 +
   271.9 +Copyright (c) 2006-2012, assimp team
  271.10 +
  271.11 +All rights reserved.
  271.12 +
  271.13 +Redistribution and use of this software in source and binary forms, 
  271.14 +with or without modification, are permitted provided that the following 
  271.15 +conditions are met:
  271.16 +
  271.17 +* Redistributions of source code must retain the above
  271.18 +  copyright notice, this list of conditions and the
  271.19 +  following disclaimer.
  271.20 +
  271.21 +* Redistributions in binary form must reproduce the above
  271.22 +  copyright notice, this list of conditions and the
  271.23 +  following disclaimer in the documentation and/or other
  271.24 +  materials provided with the distribution.
  271.25 +
  271.26 +* Neither the name of the assimp team, nor the names of its
  271.27 +  contributors may be used to endorse or promote products
  271.28 +  derived from this software without specific prior
  271.29 +  written permission of the assimp team.
  271.30 +
  271.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  271.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  271.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  271.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  271.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  271.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  271.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  271.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  271.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  271.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  271.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  271.42 +---------------------------------------------------------------------------
  271.43 +*/
  271.44 +
  271.45 +/** @file Defines the StreamReader class which reads data from
  271.46 + *  a binary stream with a well-defined endianess. */
  271.47 +
  271.48 +#ifndef AI_STREAMREADER_H_INCLUDED
  271.49 +#define AI_STREAMREADER_H_INCLUDED
  271.50 +
  271.51 +#include "ByteSwap.h"
  271.52 +
  271.53 +namespace Assimp {
  271.54 +
  271.55 +// --------------------------------------------------------------------------------------------
  271.56 +/** Wrapper class around IOStream to allow for consistent reading of binary data in both 
  271.57 + *  little and big endian format. Don't attempt to instance the template directly. Use 
  271.58 + *  StreamReaderLE to read from a little-endian stream and StreamReaderBE to read from a 
  271.59 + *  BE stream. The class expects that the endianess of any input data is known at 
  271.60 + *  compile-time, which should usually be true (#BaseImporter::ConvertToUTF8 implements
  271.61 + *  runtime endianess conversions for text files). 
  271.62 + *
  271.63 + *  XXX switch from unsigned int for size types to size_t? or ptrdiff_t?*/
  271.64 +// --------------------------------------------------------------------------------------------
  271.65 +template <bool SwapEndianess = false, bool RuntimeSwitch = false>
  271.66 +class StreamReader
  271.67 +{
  271.68 +
  271.69 +public:
  271.70 +
  271.71 +	// FIXME: use these data types throughout the whole library,
  271.72 +	// then change them to 64 bit values :-)
  271.73 +	
  271.74 +	typedef int diff;
  271.75 +	typedef unsigned int pos;
  271.76 +
  271.77 +public:
  271.78 +
  271.79 +
  271.80 +	// ---------------------------------------------------------------------
  271.81 +	/** Construction from a given stream with a well-defined endianess.
  271.82 +	 * 
  271.83 +	 *  The StreamReader holds a permanent strong reference to the
  271.84 +	 *  stream, which is released upon destruction.
  271.85 +	 *  @param stream Input stream. The stream is not restarted if
  271.86 +	 *    its file pointer is not at 0. Instead, the stream reader
  271.87 +	 *    reads from the current position to the end of the stream.
  271.88 +	 *  @param le If @c RuntimeSwitch is true: specifies whether the
  271.89 +	 *    stream is in little endian byte order. Otherwise the
  271.90 +	 *    endianess information is contained in the @c SwapEndianess
  271.91 +	 *    template parameter and this parameter is meaningless.  */
  271.92 +	StreamReader(boost::shared_ptr<IOStream> stream, bool le = false)
  271.93 +		: stream(stream)
  271.94 +		, le(le)
  271.95 +	{
  271.96 +		ai_assert(stream); 
  271.97 +		InternBegin();
  271.98 +	}
  271.99 +
 271.100 +	// ---------------------------------------------------------------------
 271.101 +	StreamReader(IOStream* stream, bool le = false)
 271.102 +		: stream(boost::shared_ptr<IOStream>(stream))
 271.103 +		, le(le)
 271.104 +	{
 271.105 +		ai_assert(stream);
 271.106 +		InternBegin();
 271.107 +	}
 271.108 +
 271.109 +	// ---------------------------------------------------------------------
 271.110 +	~StreamReader() {
 271.111 +		delete[] buffer;
 271.112 +	}
 271.113 +
 271.114 +public:
 271.115 +
 271.116 +	// deprecated, use overloaded operator>> instead
 271.117 +
 271.118 +	// ---------------------------------------------------------------------
 271.119 +	/** Read a float from the stream  */
 271.120 +	float GetF4()
 271.121 +	{
 271.122 +		return Get<float>();
 271.123 +	}
 271.124 +
 271.125 +	// ---------------------------------------------------------------------
 271.126 +	/** Read a double from the stream  */
 271.127 +	double GetF8()	{
 271.128 +		return Get<double>();
 271.129 +	}
 271.130 +
 271.131 +	// ---------------------------------------------------------------------
 271.132 +	/** Read a signed 16 bit integer from the stream */
 271.133 +	int16_t GetI2()	{
 271.134 +		return Get<int16_t>();
 271.135 +	}
 271.136 +
 271.137 +	// ---------------------------------------------------------------------
 271.138 +	/** Read a signed 8 bit integer from the stream */
 271.139 +	int8_t GetI1()	{
 271.140 +		return Get<int8_t>();
 271.141 +	}
 271.142 +
 271.143 +	// ---------------------------------------------------------------------
 271.144 +	/** Read an signed 32 bit integer from the stream */
 271.145 +	int32_t GetI4()	{
 271.146 +		return Get<int32_t>();
 271.147 +	}
 271.148 +
 271.149 +	// ---------------------------------------------------------------------
 271.150 +	/** Read a signed 64 bit integer from the stream */
 271.151 +	int64_t GetI8()	{
 271.152 +		return Get<int64_t>();
 271.153 +	}
 271.154 +
 271.155 +	// ---------------------------------------------------------------------
 271.156 +	/** Read a unsigned 16 bit integer from the stream */
 271.157 +	uint16_t GetU2()	{
 271.158 +		return Get<uint16_t>();
 271.159 +	}
 271.160 +
 271.161 +	// ---------------------------------------------------------------------
 271.162 +	/** Read a unsigned 8 bit integer from the stream */
 271.163 +	uint8_t GetU1()	{
 271.164 +		return Get<uint8_t>();
 271.165 +	}
 271.166 +
 271.167 +	// ---------------------------------------------------------------------
 271.168 +	/** Read an unsigned 32 bit integer from the stream */
 271.169 +	uint32_t GetU4()	{
 271.170 +		return Get<uint32_t>();
 271.171 +	}
 271.172 +
 271.173 +	// ---------------------------------------------------------------------
 271.174 +	/** Read a unsigned 64 bit integer from the stream */
 271.175 +	uint64_t GetU8()	{
 271.176 +		return Get<uint64_t>();
 271.177 +	}
 271.178 +
 271.179 +public:
 271.180 +
 271.181 +	// ---------------------------------------------------------------------
 271.182 +	/** Get the remaining stream size (to the end of the srream) */
 271.183 +	unsigned int GetRemainingSize() const {
 271.184 +		return (unsigned int)(end - current);
 271.185 +	}
 271.186 +
 271.187 +
 271.188 +	// ---------------------------------------------------------------------
 271.189 +	/** Get the remaining stream size (to the current read limit). The
 271.190 +	 *  return value is the remaining size of the stream if no custom
 271.191 +	 *  read limit has been set. */
 271.192 +	unsigned int GetRemainingSizeToLimit() const {
 271.193 +		return (unsigned int)(limit - current);
 271.194 +	}
 271.195 +
 271.196 +
 271.197 +	// ---------------------------------------------------------------------
 271.198 +	/** Increase the file pointer (relative seeking)  */
 271.199 +	void IncPtr(int plus)	{
 271.200 +		current += plus;
 271.201 +		if (current > limit) {
 271.202 +			throw DeadlyImportError("End of file or read limit was reached");
 271.203 +		}
 271.204 +	}
 271.205 +
 271.206 +	// ---------------------------------------------------------------------
 271.207 +	/** Get the current file pointer */
 271.208 +	int8_t* GetPtr() const	{
 271.209 +		return current;
 271.210 +	}
 271.211 +
 271.212 +
 271.213 +	// ---------------------------------------------------------------------
 271.214 +	/** Set current file pointer (Get it from #GetPtr). This is if you
 271.215 +	 *  prefer to do pointer arithmetics on your own or want to copy 
 271.216 +	 *  large chunks of data at once. 
 271.217 +	 *  @param p The new pointer, which is validated against the size
 271.218 +	 *    limit and buffer boundaries. */
 271.219 +	void SetPtr(int8_t* p)	{
 271.220 +
 271.221 +		current = p;
 271.222 +		if (current > limit || current < buffer) {
 271.223 +			throw DeadlyImportError("End of file or read limit was reached");
 271.224 +		}
 271.225 +	}
 271.226 +
 271.227 +	// ---------------------------------------------------------------------
 271.228 +	/** Copy n bytes to an external buffer
 271.229 +	 *  @param out Destination for copying
 271.230 +	 *  @param bytes Number of bytes to copy */
 271.231 +	void CopyAndAdvance(void* out, size_t bytes)	{
 271.232 +
 271.233 +		int8_t* ur = GetPtr();
 271.234 +		SetPtr(ur+bytes); // fire exception if eof
 271.235 +
 271.236 +		memcpy(out,ur,bytes);
 271.237 +	}
 271.238 +
 271.239 +
 271.240 +	// ---------------------------------------------------------------------
 271.241 +	/** Get the current offset from the beginning of the file */
 271.242 +	int GetCurrentPos() const	{
 271.243 +		return (unsigned int)(current - buffer);
 271.244 +	}
 271.245 +
 271.246 +	void SetCurrentPos(size_t pos) {
 271.247 +		SetPtr(buffer + pos);
 271.248 +	}
 271.249 +
 271.250 +	// ---------------------------------------------------------------------
 271.251 +	/** Setup a temporary read limit
 271.252 +	 * 
 271.253 +	 *  @param limit Maximum number of bytes to be read from
 271.254 +	 *    the beginning of the file. Specifying UINT_MAX
 271.255 +	 *    resets the limit to the original end of the stream. */
 271.256 +	void SetReadLimit(unsigned int _limit)	{
 271.257 +
 271.258 +		if (UINT_MAX == _limit) {
 271.259 +			limit = end;
 271.260 +			return;
 271.261 +		}
 271.262 +
 271.263 +		limit = buffer + _limit;
 271.264 +		if (limit > end) {
 271.265 +			throw DeadlyImportError("StreamReader: Invalid read limit");
 271.266 +		}
 271.267 +	}
 271.268 +
 271.269 +	// ---------------------------------------------------------------------
 271.270 +	/** Get the current read limit in bytes. Reading over this limit
 271.271 +	 *  accidentially raises an exception.  */
 271.272 +	int GetReadLimit() const	{
 271.273 +		return (unsigned int)(limit - buffer);
 271.274 +	}
 271.275 +
 271.276 +	// ---------------------------------------------------------------------
 271.277 +	/** Skip to the read limit in bytes. Reading over this limit
 271.278 +	 *  accidentially raises an exception. */
 271.279 +	void SkipToReadLimit()	{
 271.280 +		current = limit;
 271.281 +	}
 271.282 +
 271.283 +	// ---------------------------------------------------------------------
 271.284 +	/** overload operator>> and allow chaining of >> ops. */
 271.285 +	template <typename T>
 271.286 +	StreamReader& operator >> (T& f) {
 271.287 +		f = Get<T>(); 
 271.288 +		return *this;
 271.289 +	}
 271.290 +
 271.291 +private:
 271.292 +
 271.293 +	// ---------------------------------------------------------------------
 271.294 +	/** Generic read method. ByteSwap::Swap(T*) *must* be defined */
 271.295 +	template <typename T>
 271.296 +	T Get()	{
 271.297 +		if (current + sizeof(T) > limit) {
 271.298 +			throw DeadlyImportError("End of file or stream limit was reached");
 271.299 +		}
 271.300 +
 271.301 +#ifdef __arm__
 271.302 +		T f;
 271.303 +		memcpy (&f, current, sizeof(T));
 271.304 +#else
 271.305 +		T f = *((const T*)current);
 271.306 +#endif	
 271.307 +		Intern :: Getter<SwapEndianess,T,RuntimeSwitch>() (&f,le);
 271.308 +
 271.309 +		current += sizeof(T);
 271.310 +		return f;
 271.311 +	}
 271.312 +
 271.313 +	// ---------------------------------------------------------------------
 271.314 +	void InternBegin() {
 271.315 +		if (!stream) {
 271.316 +			// incase someone wonders: StreamReader is frequently invoked with
 271.317 +			// no prior validation whether the input stream is valid. Since
 271.318 +			// no one bothers changing the error message, this message here
 271.319 +			// is passed down to the caller and 'unable to open file'
 271.320 +			// simply describes best what happened.
 271.321 +			throw DeadlyImportError("StreamReader: Unable to open file");
 271.322 +		}
 271.323 +
 271.324 +		const size_t s = stream->FileSize() - stream->Tell();
 271.325 +		if (!s) {
 271.326 +			throw DeadlyImportError("StreamReader: File is empty or EOF is already reached");
 271.327 +		}
 271.328 +
 271.329 +		current = buffer = new int8_t[s];
 271.330 +		const size_t read = stream->Read(current,1,s);
 271.331 +		// (read < s) can only happen if the stream was opened in text mode, in which case FileSize() is not reliable
 271.332 +		ai_assert(read <= s);
 271.333 +		end = limit = &buffer[read];
 271.334 +	}
 271.335 +
 271.336 +private:
 271.337 +
 271.338 +
 271.339 +	boost::shared_ptr<IOStream> stream;
 271.340 +	int8_t *buffer, *current, *end, *limit;
 271.341 +	bool le;
 271.342 +};
 271.343 +
 271.344 +
 271.345 +// --------------------------------------------------------------------------------------------
 271.346 +// `static` StreamReaders. Their byte order is fixed and they might be a little bit faster.
 271.347 +#ifdef AI_BUILD_BIG_ENDIAN
 271.348 +	typedef StreamReader<true>  StreamReaderLE;
 271.349 +	typedef StreamReader<false> StreamReaderBE;
 271.350 +#else
 271.351 +	typedef StreamReader<true>  StreamReaderBE;
 271.352 +	typedef StreamReader<false> StreamReaderLE;
 271.353 +#endif
 271.354 +
 271.355 +// `dynamic` StreamReader. The byte order of the input data is specified in the
 271.356 +// c'tor. This involves runtime branching and might be a little bit slower.
 271.357 +typedef StreamReader<true,true> StreamReaderAny;
 271.358 +
 271.359 +} // end namespace Assimp
 271.360 +
 271.361 +#endif // !! AI_STREAMREADER_H_INCLUDED
   272.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   272.2 +++ b/libs/assimp/StringComparison.h	Sat Feb 01 19:58:19 2014 +0200
   272.3 @@ -0,0 +1,219 @@
   272.4 +/*
   272.5 +Open Asset Import Library (assimp)
   272.6 +----------------------------------------------------------------------
   272.7 +
   272.8 +Copyright (c) 2006-2012, assimp team
   272.9 +All rights reserved.
  272.10 +
  272.11 +Redistribution and use of this software in source and binary forms, 
  272.12 +with or without modification, are permitted provided that the 
  272.13 +following conditions are met:
  272.14 +
  272.15 +* Redistributions of source code must retain the above
  272.16 +  copyright notice, this list of conditions and the
  272.17 +  following disclaimer.
  272.18 +
  272.19 +* Redistributions in binary form must reproduce the above
  272.20 +  copyright notice, this list of conditions and the
  272.21 +  following disclaimer in the documentation and/or other
  272.22 +  materials provided with the distribution.
  272.23 +
  272.24 +* Neither the name of the assimp team, nor the names of its
  272.25 +  contributors may be used to endorse or promote products
  272.26 +  derived from this software without specific prior
  272.27 +  written permission of the assimp team.
  272.28 +
  272.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  272.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  272.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  272.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  272.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  272.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  272.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  272.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  272.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  272.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  272.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  272.40 +
  272.41 +----------------------------------------------------------------------
  272.42 +*/
  272.43 +
  272.44 +/** @file Definition of platform independent string workers:
  272.45 +
  272.46 +   ASSIMP_itoa10
  272.47 +   ASSIMP_stricmp
  272.48 +   ASSIMP_strincmp
  272.49 +
  272.50 +   These functions are not consistently available on all platforms,
  272.51 +   or the provided implementations behave too differently.
  272.52 +*/
  272.53 +#ifndef INCLUDED_AI_STRING_WORKERS_H
  272.54 +#define INCLUDED_AI_STRING_WORKERS_H
  272.55 +
  272.56 +#include "assimp/ai_assert.h"
  272.57 +
  272.58 +namespace Assimp	{
  272.59 +
  272.60 +// -------------------------------------------------------------------------------
  272.61 +/** @brief itoa with a fixed base 10
  272.62 + * 'itoa' is not consistently available on all platforms so it is quite useful
  272.63 + * to have a small replacement function here. No need to use a full sprintf()
  272.64 + * if we just want to print a number ...
  272.65 + * @param out Output buffer
  272.66 + * @param max Maximum number of characters to be written, including '\0'.
  272.67 + *   This parameter may not be 0.
  272.68 + * @param number Number to be written
  272.69 + * @return Length of the output string, excluding the '\0'
  272.70 + */
  272.71 +inline unsigned int ASSIMP_itoa10( char* out, unsigned int max, int32_t number)
  272.72 +{
  272.73 +	ai_assert(NULL != out);
  272.74 +
  272.75 +	// write the unary minus to indicate we have a negative number
  272.76 +	unsigned int written = 1u;
  272.77 +	if (number < 0 && written < max)	{
  272.78 +		*out++ = '-';
  272.79 +		++written;
  272.80 +		number = -number;
  272.81 +	}
  272.82 +
  272.83 +	// We begin with the largest number that is not zero. 
  272.84 +	int32_t cur = 1000000000; // 2147483648
  272.85 +	bool mustPrint = false;
  272.86 +	while (written < max)	{
  272.87 +
  272.88 +		const unsigned int digit = number / cur;
  272.89 +		if (mustPrint || digit > 0 || 1 == cur)	{
  272.90 +			// print all future zeroes from now
  272.91 +			mustPrint = true;	
  272.92 +
  272.93 +			*out++ = '0'+static_cast<char>(digit);
  272.94 +
  272.95 +			++written;
  272.96 +			number -= digit*cur;
  272.97 +			if (1 == cur) {
  272.98 +				break;
  272.99 +			}
 272.100 +		}
 272.101 +		cur /= 10;
 272.102 +	}
 272.103 +
 272.104 +	// append a terminal zero
 272.105 +	*out++ = '\0';
 272.106 +	return written-1;
 272.107 +}
 272.108 +
 272.109 +// -------------------------------------------------------------------------------
 272.110 +/** @brief itoa with a fixed base 10 (Secure template overload)
 272.111 + *  The compiler should choose this function if he or she is able to determine the
 272.112 + *  size of the array automatically.
 272.113 + */
 272.114 +template <size_t length>
 272.115 +inline unsigned int ASSIMP_itoa10( char(& out)[length], int32_t number)
 272.116 +{
 272.117 +	return ASSIMP_itoa10(out,length,number);
 272.118 +}
 272.119 +
 272.120 +// -------------------------------------------------------------------------------
 272.121 +/** @brief Helper function to do platform independent string comparison.
 272.122 + *
 272.123 + *  This is required since stricmp() is not consistently available on
 272.124 + *  all platforms. Some platforms use the '_' prefix, others don't even
 272.125 + *  have such a function. 
 272.126 + *
 272.127 + *  @param s1 First input string
 272.128 + *  @param s2 Second input string
 272.129 + *  @return 0 if the given strings are identical
 272.130 + */
 272.131 +inline int ASSIMP_stricmp(const char *s1, const char *s2)
 272.132 +{
 272.133 +	ai_assert(NULL != s1 && NULL != s2);
 272.134 +
 272.135 +#if (defined _MSC_VER)
 272.136 +
 272.137 +	return ::_stricmp(s1,s2);
 272.138 +#elif defined( __GNUC__ )
 272.139 +	
 272.140 +	return ::strcasecmp(s1,s2);
 272.141 +#else
 272.142 +	
 272.143 +	register char c1, c2;
 272.144 +	do	{
 272.145 +		c1 = tolower(*s1++);
 272.146 +		c2 = tolower(*s2++);
 272.147 +	} 
 272.148 +	while ( c1 && (c1 == c2) );
 272.149 +	return c1 - c2;
 272.150 +#endif
 272.151 +}
 272.152 +
 272.153 +// -------------------------------------------------------------------------------
 272.154 +/** @brief Case independent comparison of two std::strings
 272.155 + *
 272.156 + *  @param a First  string
 272.157 + *  @param b Second string
 272.158 + *  @return 0 if a == b
 272.159 + */
 272.160 +inline int ASSIMP_stricmp(const std::string& a, const std::string& b)
 272.161 +{
 272.162 +	register int i = (int)b.length()-(int)a.length();
 272.163 +	return (i ? i : ASSIMP_stricmp(a.c_str(),b.c_str()));
 272.164 +}
 272.165 +
 272.166 +// -------------------------------------------------------------------------------
 272.167 +/** @brief Helper function to do platform independent string comparison.
 272.168 + *
 272.169 + *  This is required since strincmp() is not consistently available on
 272.170 + *  all platforms. Some platforms use the '_' prefix, others don't even
 272.171 + *  have such a function. 
 272.172 + *
 272.173 + *  @param s1 First input string
 272.174 + *  @param s2 Second input string
 272.175 + *  @param n Macimum number of characters to compare
 272.176 + *  @return 0 if the given strings are identical
 272.177 + */
 272.178 +inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n)
 272.179 +{
 272.180 +	ai_assert(NULL != s1 && NULL != s2);
 272.181 +	if (!n)return 0;
 272.182 +
 272.183 +#if (defined _MSC_VER)
 272.184 +
 272.185 +	return ::_strnicmp(s1,s2,n);
 272.186 +
 272.187 +#elif defined( __GNUC__ )
 272.188 +
 272.189 +	return ::strncasecmp(s1,s2, n);
 272.190 +
 272.191 +#else
 272.192 +	register char c1, c2;
 272.193 +	unsigned int p = 0;
 272.194 +	do 
 272.195 +	{
 272.196 +		if (p++ >= n)return 0;
 272.197 +		c1 = tolower(*s1++);
 272.198 +		c2 = tolower(*s2++);
 272.199 +	} 
 272.200 +	while ( c1 && (c1 == c2) );
 272.201 +
 272.202 +	return c1 - c2;
 272.203 +#endif
 272.204 +}
 272.205 +
 272.206 +
 272.207 +// -------------------------------------------------------------------------------
 272.208 +/** @brief Evaluates an integer power
 272.209 + *
 272.210 + * todo: move somewhere where it fits better in than here 
 272.211 + */
 272.212 +inline unsigned int integer_pow (unsigned int base, unsigned int power)
 272.213 +{
 272.214 +	unsigned int res = 1;
 272.215 +	for (unsigned int i = 0; i < power;++i)
 272.216 +		res *= base;
 272.217 +
 272.218 +	return res;
 272.219 +}
 272.220 +} // end of namespace
 272.221 +
 272.222 +#endif // !  AI_STRINGCOMPARISON_H_INC
   273.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   273.2 +++ b/libs/assimp/Subdivision.cpp	Sat Feb 01 19:58:19 2014 +0200
   273.3 @@ -0,0 +1,587 @@
   273.4 +/*
   273.5 +Open Asset Import Library (assimp)
   273.6 +----------------------------------------------------------------------
   273.7 +
   273.8 +Copyright (c) 2006-2012, assimp team
   273.9 +All rights reserved.
  273.10 +
  273.11 +Redistribution and use of this software in source and binary forms, 
  273.12 +with or without modification, are permitted provided that the 
  273.13 +following conditions are met:
  273.14 +
  273.15 +* Redistributions of source code must retain the above
  273.16 +  copyright notice, this list of conditions and the
  273.17 +  following disclaimer.
  273.18 +
  273.19 +* Redistributions in binary form must reproduce the above
  273.20 +  copyright notice, this list of conditions and the
  273.21 +  following disclaimer in the documentation and/or other
  273.22 +  materials provided with the distribution.
  273.23 +
  273.24 +* Neither the name of the assimp team, nor the names of its
  273.25 +  contributors may be used to endorse or promote products
  273.26 +  derived from this software without specific prior
  273.27 +  written permission of the assimp team.
  273.28 +
  273.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  273.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  273.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  273.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  273.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  273.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  273.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  273.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  273.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  273.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  273.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  273.40 +
  273.41 +----------------------------------------------------------------------
  273.42 +*/
  273.43 +
  273.44 +#include "AssimpPCH.h"
  273.45 +
  273.46 +#include "Subdivision.h"
  273.47 +#include "SceneCombiner.h"
  273.48 +#include "SpatialSort.h"
  273.49 +#include "ProcessHelper.h"
  273.50 +#include "Vertex.h"
  273.51 +
  273.52 +using namespace Assimp;
  273.53 +void mydummy() {}
  273.54 +
  273.55 +// ------------------------------------------------------------------------------------------------
  273.56 +/** Subdivider stub class to implement the Catmull-Clarke subdivision algorithm. The 
  273.57 + *  implementation is basing on recursive refinement. Directly evaluating the result is also
  273.58 + *  possible and much quicker, but it depends on lengthy matrix lookup tables. */
  273.59 +// ------------------------------------------------------------------------------------------------
  273.60 +class CatmullClarkSubdivider : public Subdivider
  273.61 +{
  273.62 +
  273.63 +public:
  273.64 +
  273.65 +	void Subdivide (aiMesh* mesh, aiMesh*& out, unsigned int num, bool discard_input);
  273.66 +	void Subdivide (aiMesh** smesh, size_t nmesh,
  273.67 +		aiMesh** out, unsigned int num, bool discard_input);
  273.68 +
  273.69 +	// ---------------------------------------------------------------------------
  273.70 +	/** Intermediate description of an edge between two corners of a polygon*/
  273.71 +	// ---------------------------------------------------------------------------
  273.72 +	struct Edge
  273.73 +	{
  273.74 +		Edge()
  273.75 +			: ref(0)
  273.76 +		{}
  273.77 +		Vertex edge_point, midpoint;
  273.78 +		unsigned int ref;
  273.79 +	};
  273.80 +
  273.81 +
  273.82 +
  273.83 +	typedef std::vector<unsigned int> UIntVector;
  273.84 +	typedef std::map<uint64_t,Edge> EdgeMap;
  273.85 +
  273.86 +	// ---------------------------------------------------------------------------
  273.87 +	// Hashing function to derive an index into an #EdgeMap from two given
  273.88 +	// 'unsigned int' vertex coordinates (!!distinct coordinates - same 
  273.89 +	// vertex position == same index!!). 
  273.90 +	// NOTE - this leads to rare hash collisions if a) sizeof(unsigned int)>4
  273.91 +	// and (id[0]>2^32-1 or id[0]>2^32-1).
  273.92 +	// MAKE_EDGE_HASH() uses temporaries, so INIT_EDGE_HASH() needs to be put
  273.93 +	// at the head of every function which is about to use MAKE_EDGE_HASH().
  273.94 +	// Reason is that the hash is that hash construction needs to hold the
  273.95 +	// invariant id0<id1 to identify an edge - else two hashes would refer
  273.96 +	// to the same edge.
  273.97 +	// ---------------------------------------------------------------------------
  273.98 +#define MAKE_EDGE_HASH(id0,id1) (eh_tmp0__=id0,eh_tmp1__=id1,\
  273.99 +	(eh_tmp0__<eh_tmp1__?std::swap(eh_tmp0__,eh_tmp1__):mydummy()),(uint64_t)eh_tmp0__^((uint64_t)eh_tmp1__<<32u))
 273.100 +
 273.101 +
 273.102 +#define INIT_EDGE_HASH_TEMPORARIES()\
 273.103 +	unsigned int eh_tmp0__, eh_tmp1__;
 273.104 +
 273.105 +private:
 273.106 +
 273.107 +	void InternSubdivide (const aiMesh* const * smesh, 
 273.108 +		size_t nmesh,aiMesh** out, unsigned int num);
 273.109 +};
 273.110 +
 273.111 +
 273.112 +// ------------------------------------------------------------------------------------------------
 273.113 +// Construct a subdivider of a specific type
 273.114 +Subdivider* Subdivider::Create (Algorithm algo)
 273.115 +{
 273.116 +	switch (algo)
 273.117 +	{
 273.118 +	case CATMULL_CLARKE:
 273.119 +		return new CatmullClarkSubdivider();
 273.120 +	};
 273.121 +
 273.122 +	ai_assert(false);
 273.123 +	return NULL; // shouldn't happen
 273.124 +}
 273.125 +
 273.126 +// ------------------------------------------------------------------------------------------------
 273.127 +// Call the Catmull Clark subdivision algorithm for one mesh
 273.128 +void  CatmullClarkSubdivider::Subdivide (
 273.129 +	aiMesh* mesh, 
 273.130 +	aiMesh*& out,
 273.131 +	unsigned int num,
 273.132 +	bool discard_input
 273.133 +	)
 273.134 +{
 273.135 +	assert(mesh != out);
 273.136 +	Subdivide(&mesh,1,&out,num,discard_input);
 273.137 +}
 273.138 +
 273.139 +// ------------------------------------------------------------------------------------------------
 273.140 +// Call the Catmull Clark subdivision algorithm for multiple meshes
 273.141 +void CatmullClarkSubdivider::Subdivide (
 273.142 +	aiMesh** smesh, 
 273.143 +	size_t nmesh,
 273.144 +	aiMesh** out, 
 273.145 +	unsigned int num,
 273.146 +	bool discard_input
 273.147 +	)
 273.148 +{
 273.149 +	ai_assert(NULL != smesh && NULL != out);
 273.150 +
 273.151 +	// course, both regions may not overlap
 273.152 +	assert(smesh<out || smesh+nmesh>out+nmesh);
 273.153 +	if (!num) {
 273.154 +		
 273.155 +		// No subdivision at all. Need to copy all the meshes .. argh.
 273.156 +		if (discard_input) {
 273.157 +			for (size_t s = 0; s < nmesh; ++s) {
 273.158 +				out[s] = smesh[s];
 273.159 +				smesh[s] = NULL;
 273.160 +			}
 273.161 +		}
 273.162 +		else {
 273.163 +			for (size_t s = 0; s < nmesh; ++s) {
 273.164 +				SceneCombiner::Copy(out+s,smesh[s]);
 273.165 +			}
 273.166 +		}
 273.167 +		return;
 273.168 +	}
 273.169 +
 273.170 +	std::vector<aiMesh*> inmeshes;
 273.171 +	std::vector<aiMesh*> outmeshes;
 273.172 +	std::vector<unsigned int> maptbl;
 273.173 +
 273.174 +	inmeshes.reserve(nmesh);
 273.175 +	outmeshes.reserve(nmesh);
 273.176 +	maptbl.reserve(nmesh);
 273.177 +
 273.178 +	// Remove pure line and point meshes from the working set to reduce the 
 273.179 +	// number of edge cases the subdivider is forced to deal with. Line and 
 273.180 +	// point meshes are simply passed through.
 273.181 +	for (size_t s = 0; s < nmesh; ++s) {
 273.182 +		aiMesh* i = smesh[s];
 273.183 +		// FIX - mPrimitiveTypes might not yet be initialized
 273.184 +		if (i->mPrimitiveTypes && (i->mPrimitiveTypes & (aiPrimitiveType_LINE|aiPrimitiveType_POINT))==i->mPrimitiveTypes) {
 273.185 +			DefaultLogger::get()->debug("Catmull-Clark Subdivider: Skipping pure line/point mesh");
 273.186 +
 273.187 +			if (discard_input) {
 273.188 +				out[s] = i;
 273.189 +				smesh[s] = NULL;
 273.190 +			}
 273.191 +			else {
 273.192 +				SceneCombiner::Copy(out+s,i);
 273.193 +			}
 273.194 +			continue;
 273.195 +		}
 273.196 +
 273.197 +		outmeshes.push_back(NULL);inmeshes.push_back(i);
 273.198 +		maptbl.push_back(s);
 273.199 +	}
 273.200 +
 273.201 +	// Do the actual subdivision on the preallocated storage. InternSubdivide 
 273.202 +	// *always* assumes that enough storage is available, it does not bother
 273.203 +	// checking any ranges.
 273.204 +	ai_assert(inmeshes.size()==outmeshes.size()&&inmeshes.size()==maptbl.size());
 273.205 +	if (inmeshes.empty()) {
 273.206 +		DefaultLogger::get()->warn("Catmull-Clark Subdivider: Pure point/line scene, I can't do anything");
 273.207 +		return;
 273.208 +	}
 273.209 +	InternSubdivide(&inmeshes.front(),inmeshes.size(),&outmeshes.front(),num);
 273.210 +	for (unsigned int i = 0; i < maptbl.size(); ++i) {
 273.211 +		ai_assert(outmeshes[i]);
 273.212 +		out[maptbl[i]] = outmeshes[i];
 273.213 +	}
 273.214 +
 273.215 +	if (discard_input) {
 273.216 +		for (size_t s = 0; s < nmesh; ++s) {
 273.217 +			delete smesh[s];
 273.218 +		}
 273.219 +	}
 273.220 +}
 273.221 +
 273.222 +// ------------------------------------------------------------------------------------------------
 273.223 +// Note - this is an implementation of the standard (recursive) Cm-Cl algorithm without further 
 273.224 +// optimizations (except we're using some nice LUTs). A description of the algorithm can be found
 273.225 +// here: http://en.wikipedia.org/wiki/Catmull-Clark_subdivision_surface
 273.226 +//
 273.227 +// The code is mostly O(n), however parts are O(nlogn) which is therefore the algorithm's
 273.228 +// expected total runtime complexity. The implementation is able to work in-place on the same
 273.229 +// mesh arrays. Calling #InternSubdivide() directly is not encouraged. The code can operate
 273.230 +// in-place unless 'smesh' and 'out' are equal (no strange overlaps or reorderings). 
 273.231 +// Previous data is replaced/deleted then.
 273.232 +// ------------------------------------------------------------------------------------------------
 273.233 +void CatmullClarkSubdivider::InternSubdivide (
 273.234 +	const aiMesh* const * smesh, 
 273.235 +	size_t nmesh,
 273.236 +	aiMesh** out, 
 273.237 +	unsigned int num
 273.238 +	)
 273.239 +{
 273.240 +	ai_assert(NULL != smesh && NULL != out);
 273.241 +	INIT_EDGE_HASH_TEMPORARIES();
 273.242 +
 273.243 +	// no subdivision requested or end of recursive refinement
 273.244 +	if (!num) {
 273.245 +		return;
 273.246 +	}
 273.247 +
 273.248 +	UIntVector maptbl;
 273.249 +	SpatialSort spatial;
 273.250 +
 273.251 +	// ---------------------------------------------------------------------
 273.252 +	// 0. Offset table to index all meshes continuously, generate a spatially
 273.253 +	// sorted representation of all vertices in all meshes.
 273.254 +	// ---------------------------------------------------------------------
 273.255 +	typedef std::pair<unsigned int,unsigned int> IntPair;
 273.256 +	std::vector<IntPair> moffsets(nmesh);
 273.257 +	unsigned int totfaces = 0, totvert = 0;
 273.258 +	for (size_t t = 0; t < nmesh; ++t) {
 273.259 +		const aiMesh* mesh = smesh[t];
 273.260 +
 273.261 +		spatial.Append(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D),false);
 273.262 +		moffsets[t] = IntPair(totfaces,totvert);
 273.263 +
 273.264 +		totfaces += mesh->mNumFaces;
 273.265 +		totvert  += mesh->mNumVertices;
 273.266 +	}
 273.267 +
 273.268 +	spatial.Finalize();
 273.269 +	const unsigned int num_unique = spatial.GenerateMappingTable(maptbl,ComputePositionEpsilon(smesh,nmesh));
 273.270 +
 273.271 +
 273.272 +#define FLATTEN_VERTEX_IDX(mesh_idx, vert_idx) (moffsets[mesh_idx].second+vert_idx)
 273.273 +#define   FLATTEN_FACE_IDX(mesh_idx, face_idx) (moffsets[mesh_idx].first+face_idx)
 273.274 +
 273.275 +	// ---------------------------------------------------------------------
 273.276 +	// 1. Compute the centroid point for all faces
 273.277 +	// ---------------------------------------------------------------------
 273.278 +	std::vector<Vertex> centroids(totfaces);
 273.279 +	unsigned int nfacesout = 0;
 273.280 +	for (size_t t = 0, n = 0; t < nmesh; ++t) {
 273.281 +		const aiMesh* mesh = smesh[t];
 273.282 +		for (unsigned int i = 0; i < mesh->mNumFaces;++i,++n)
 273.283 +		{
 273.284 +			const aiFace& face = mesh->mFaces[i];
 273.285 +			Vertex& c = centroids[n];
 273.286 +
 273.287 +			for (unsigned int a = 0; a < face.mNumIndices;++a) {
 273.288 +				c += Vertex(mesh,face.mIndices[a]);
 273.289 +			}
 273.290 +
 273.291 +			c /= static_cast<float>(face.mNumIndices);
 273.292 +			nfacesout += face.mNumIndices;
 273.293 +		}
 273.294 +	}
 273.295 +	
 273.296 +	EdgeMap edges;
 273.297 +
 273.298 +	// ---------------------------------------------------------------------
 273.299 +	// 2. Set each edge point to be the average of all neighbouring 
 273.300 +	// face points and original points. Every edge exists twice
 273.301 +	// if there is a neighboring face.
 273.302 +	// ---------------------------------------------------------------------
 273.303 +	for (size_t t = 0; t < nmesh; ++t) {
 273.304 +		const aiMesh* mesh = smesh[t];
 273.305 +
 273.306 +		for (unsigned int i = 0; i < mesh->mNumFaces;++i)	{
 273.307 +			const aiFace& face = mesh->mFaces[i];
 273.308 +
 273.309 +			for (unsigned int p =0; p< face.mNumIndices; ++p) {
 273.310 +				const unsigned int id[] = { 
 273.311 +					face.mIndices[p], 
 273.312 +					face.mIndices[p==face.mNumIndices-1?0:p+1]
 273.313 +				};
 273.314 +				const unsigned int mp[] = { 
 273.315 +					maptbl[FLATTEN_VERTEX_IDX(t,id[0])], 
 273.316 +					maptbl[FLATTEN_VERTEX_IDX(t,id[1])]
 273.317 +				};
 273.318 +
 273.319 +				Edge& e = edges[MAKE_EDGE_HASH(mp[0],mp[1])];
 273.320 +				e.ref++;
 273.321 +				if (e.ref<=2) {
 273.322 +					if (e.ref==1) { // original points (end points) - add only once
 273.323 +						e.edge_point = e.midpoint = Vertex(mesh,id[0])+Vertex(mesh,id[1]);
 273.324 +						e.midpoint *= 0.5f;
 273.325 +					}
 273.326 +					e.edge_point += centroids[FLATTEN_FACE_IDX(t,i)];
 273.327 +				}
 273.328 +			}
 273.329 +		}
 273.330 +	}
 273.331 +
 273.332 +	// ---------------------------------------------------------------------
 273.333 +	// 3. Normalize edge points
 273.334 +	// ---------------------------------------------------------------------
 273.335 +	{unsigned int bad_cnt = 0;
 273.336 +	for (EdgeMap::iterator it = edges.begin(); it != edges.end(); ++it) {
 273.337 +		if ((*it).second.ref < 2) {
 273.338 +			ai_assert((*it).second.ref);
 273.339 +			++bad_cnt;
 273.340 +		}
 273.341 +		(*it).second.edge_point *= 1.f/((*it).second.ref+2.f);
 273.342 +	}
 273.343 +
 273.344 +	if (bad_cnt) {
 273.345 +		// Report the number of bad edges. bad edges are referenced by less than two
 273.346 +		// faces in the mesh. They occur at outer model boundaries in non-closed
 273.347 +		// shapes.
 273.348 +		char tmp[512];
 273.349 +		sprintf(tmp,"Catmull-Clark Subdivider: got %u bad edges touching only one face (totally %u edges). ",
 273.350 +			bad_cnt,static_cast<unsigned int>(edges.size()));
 273.351 +
 273.352 +		DefaultLogger::get()->debug(tmp);
 273.353 +	}}
 273.354 +
 273.355 +	// ---------------------------------------------------------------------
 273.356 +	// 4. Compute a vertex-face adjacency table. We can't reuse the code
 273.357 +	// from VertexTriangleAdjacency because we need the table for multiple
 273.358 +	// meshes and out vertex indices need to be mapped to distinct values 
 273.359 +	// first.
 273.360 +	// ---------------------------------------------------------------------
 273.361 +	UIntVector faceadjac(nfacesout), cntadjfac(maptbl.size(),0), ofsadjvec(maptbl.size()+1,0); {
 273.362 +	for (size_t t = 0; t < nmesh; ++t) {
 273.363 +		const aiMesh* const minp = smesh[t];
 273.364 +		for (unsigned int i = 0; i < minp->mNumFaces; ++i) {
 273.365 +			
 273.366 +			const aiFace& f = minp->mFaces[i];
 273.367 +			for (unsigned int n = 0; n < f.mNumIndices; ++n) {
 273.368 +				++cntadjfac[maptbl[FLATTEN_VERTEX_IDX(t,f.mIndices[n])]];
 273.369 +			}
 273.370 +		}
 273.371 +	}
 273.372 +	unsigned int cur = 0;
 273.373 +	for (size_t i = 0; i < cntadjfac.size(); ++i) {
 273.374 +		ofsadjvec[i+1] = cur;
 273.375 +		cur += cntadjfac[i];
 273.376 +	}
 273.377 +	for (size_t t = 0; t < nmesh; ++t) {
 273.378 +		const aiMesh* const minp = smesh[t];
 273.379 +		for (unsigned int i = 0; i < minp->mNumFaces; ++i) {
 273.380 +			
 273.381 +			const aiFace& f = minp->mFaces[i];
 273.382 +			for (unsigned int n = 0; n < f.mNumIndices; ++n) {
 273.383 +				faceadjac[ofsadjvec[1+maptbl[FLATTEN_VERTEX_IDX(t,f.mIndices[n])]]++] = FLATTEN_FACE_IDX(t,i);
 273.384 +			}
 273.385 +		}
 273.386 +	} 
 273.387 +	
 273.388 +	// check the other way round for consistency
 273.389 +#ifdef _DEBUG
 273.390 +
 273.391 +	for (size_t t = 0; t < ofsadjvec.size()-1; ++t) {
 273.392 +		for (unsigned int m = 0; m <  cntadjfac[t]; ++m) {
 273.393 +			const unsigned int fidx = faceadjac[ofsadjvec[t]+m];
 273.394 +			ai_assert(fidx < totfaces);
 273.395 +			for (size_t n = 1; n < nmesh; ++n) {
 273.396 +			
 273.397 +				if (moffsets[n].first > fidx) {
 273.398 +					const aiMesh* msh = smesh[--n];
 273.399 +					const aiFace& f = msh->mFaces[fidx-moffsets[n].first];
 273.400 +					
 273.401 +					bool haveit = false;
 273.402 +					for (unsigned int i = 0; i < f.mNumIndices; ++i) {
 273.403 +						if (maptbl[FLATTEN_VERTEX_IDX(n,f.mIndices[i])]==(unsigned int)t) {
 273.404 +							haveit = true; break;
 273.405 +						}
 273.406 +					}
 273.407 +					ai_assert(haveit);
 273.408 +					break;
 273.409 +				}
 273.410 +			}
 273.411 +		}
 273.412 +	}
 273.413 +
 273.414 +#endif
 273.415 +	}
 273.416 +
 273.417 +#define GET_ADJACENT_FACES_AND_CNT(vidx,fstartout,numout) \
 273.418 +	fstartout = &faceadjac[ofsadjvec[vidx]], numout = cntadjfac[vidx]
 273.419 +
 273.420 +	typedef std::pair<bool,Vertex> TouchedOVertex;
 273.421 +	std::vector<TouchedOVertex > new_points(num_unique,TouchedOVertex(false,Vertex()));
 273.422 +	// ---------------------------------------------------------------------
 273.423 +	// 5. Spawn a quad from each face point to the corresponding edge points
 273.424 +	// the original points being the fourth quad points.
 273.425 +	// ---------------------------------------------------------------------
 273.426 +	for (size_t t = 0; t < nmesh; ++t) {
 273.427 +		const aiMesh* const minp = smesh[t];
 273.428 +		aiMesh* const mout = out[t] = new aiMesh();
 273.429 +
 273.430 +		for (unsigned int a  = 0; a < minp->mNumFaces; ++a) {
 273.431 +			mout->mNumFaces += minp->mFaces[a].mNumIndices;
 273.432 +		}
 273.433 +
 273.434 +		// We need random access to the old face buffer, so reuse is not possible.
 273.435 +		mout->mFaces = new aiFace[mout->mNumFaces];
 273.436 +
 273.437 +		mout->mNumVertices = mout->mNumFaces*4;
 273.438 +		mout->mVertices = new aiVector3D[mout->mNumVertices];
 273.439 +
 273.440 +		// quads only, keep material index
 273.441 +		mout->mPrimitiveTypes = aiPrimitiveType_POLYGON;
 273.442 +		mout->mMaterialIndex = minp->mMaterialIndex;
 273.443 +
 273.444 +		if (minp->HasNormals()) {
 273.445 +			mout->mNormals = new aiVector3D[mout->mNumVertices];
 273.446 +		}
 273.447 +
 273.448 +		if (minp->HasTangentsAndBitangents()) {
 273.449 +			mout->mTangents = new aiVector3D[mout->mNumVertices];
 273.450 +			mout->mBitangents = new aiVector3D[mout->mNumVertices];
 273.451 +		}
 273.452 +
 273.453 +		for(unsigned int i = 0; minp->HasTextureCoords(i); ++i) {
 273.454 +			mout->mTextureCoords[i] = new aiVector3D[mout->mNumVertices];
 273.455 +			mout->mNumUVComponents[i] = minp->mNumUVComponents[i];
 273.456 +		}
 273.457 +
 273.458 +		for(unsigned int i = 0; minp->HasVertexColors(i); ++i) {
 273.459 +			mout->mColors[i] = new aiColor4D[mout->mNumVertices];
 273.460 +		}
 273.461 +
 273.462 +		mout->mNumVertices = mout->mNumFaces<<2u;
 273.463 +		for (unsigned int i = 0, v = 0, n = 0; i < minp->mNumFaces;++i)	{
 273.464 +
 273.465 +			const aiFace& face = minp->mFaces[i];
 273.466 +			for (unsigned int a = 0; a < face.mNumIndices;++a)	{
 273.467 +
 273.468 +				// Get a clean new face.
 273.469 +				aiFace& faceOut = mout->mFaces[n++];
 273.470 +				faceOut.mIndices = new unsigned int [faceOut.mNumIndices = 4];
 273.471 +
 273.472 +				// Spawn a new quadrilateral (ccw winding) for this original point between:
 273.473 +				// a) face centroid
 273.474 +				centroids[FLATTEN_FACE_IDX(t,i)].SortBack(mout,faceOut.mIndices[0]=v++); 
 273.475 +
 273.476 +				// b) adjacent edge on the left, seen from the centroid
 273.477 +				const Edge& e0 = edges[MAKE_EDGE_HASH(maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])],
 273.478 +					maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a==face.mNumIndices-1?0:a+1])
 273.479 +					])];  // fixme: replace with mod face.mNumIndices? 
 273.480 +
 273.481 +				// c) adjacent edge on the right, seen from the centroid
 273.482 +				const Edge& e1 = edges[MAKE_EDGE_HASH(maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])],
 273.483 +					maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[!a?face.mNumIndices-1:a-1])
 273.484 +					])];  // fixme: replace with mod face.mNumIndices? 
 273.485 +
 273.486 +				e0.edge_point.SortBack(mout,faceOut.mIndices[3]=v++);
 273.487 +				e1.edge_point.SortBack(mout,faceOut.mIndices[1]=v++);
 273.488 +
 273.489 +				// d= original point P with distinct index i
 273.490 +				// F := 0
 273.491 +				// R := 0
 273.492 +				// n := 0
 273.493 +				// for each face f containing i
 273.494 +				//    F := F+ centroid of f
 273.495 +				//    R := R+ midpoint of edge of f from i to i+1
 273.496 +				//    n := n+1
 273.497 +				//
 273.498 +				// (F+2R+(n-3)P)/n         
 273.499 +				const unsigned int org = maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])];
 273.500 +				TouchedOVertex& ov = new_points[org];
 273.501 +
 273.502 +				if (!ov.first) {
 273.503 +					ov.first = true;
 273.504 +
 273.505 +					const unsigned int* adj; unsigned int cnt;
 273.506 +					GET_ADJACENT_FACES_AND_CNT(org,adj,cnt);
 273.507 +
 273.508 +					if (cnt < 3) {
 273.509 +						ov.second = Vertex(minp,face.mIndices[a]);
 273.510 +					}
 273.511 +					else {
 273.512 +
 273.513 +						Vertex F,R;
 273.514 +						for (unsigned int o = 0; o < cnt; ++o) {
 273.515 +							ai_assert(adj[o] < totfaces);
 273.516 +							F += centroids[adj[o]];
 273.517 +
 273.518 +							// adj[0] is a global face index - search the face in the mesh list
 273.519 +							const aiMesh* mp = NULL;
 273.520 +							size_t nidx;
 273.521 +
 273.522 +							if (adj[o] < moffsets[0].first) {
 273.523 +								mp = smesh[nidx=0];
 273.524 +							}
 273.525 +							else {
 273.526 +								for (nidx = 1; nidx<= nmesh; ++nidx) {
 273.527 +									if (nidx == nmesh ||moffsets[nidx].first > adj[o]) {
 273.528 +										mp = smesh[--nidx];
 273.529 +										break;
 273.530 +									}
 273.531 +								}
 273.532 +							}
 273.533 +
 273.534 +							ai_assert(adj[o]-moffsets[nidx].first < mp->mNumFaces);
 273.535 +							const aiFace& f = mp->mFaces[adj[o]-moffsets[nidx].first];
 273.536 +#				ifdef _DEBUG
 273.537 +							bool haveit = false;
 273.538 +#				endif
 273.539 +
 273.540 +							// find our original point in the face
 273.541 +							for (unsigned int m = 0; m < f.mNumIndices; ++m) {
 273.542 +								if (maptbl[FLATTEN_VERTEX_IDX(nidx,f.mIndices[m])] == org) {
 273.543 +
 273.544 +									// add *both* edges. this way, we can be sure that we add
 273.545 +									// *all* adjacent edges to R. In a closed shape, every
 273.546 +									// edge is added twice - so we simply leave out the
 273.547 +									// factor 2.f in the amove formula and get the right
 273.548 +									// result.
 273.549 +
 273.550 +									const Edge& c0 = edges[MAKE_EDGE_HASH(org,maptbl[FLATTEN_VERTEX_IDX(
 273.551 +										nidx,f.mIndices[!m?f.mNumIndices-1:m-1])])];
 273.552 +									// fixme: replace with mod face.mNumIndices? 
 273.553 +
 273.554 +									const Edge& c1 = edges[MAKE_EDGE_HASH(org,maptbl[FLATTEN_VERTEX_IDX(
 273.555 +										nidx,f.mIndices[m==f.mNumIndices-1?0:m+1])])];
 273.556 +									// fixme: replace with mod face.mNumIndices? 
 273.557 +									R += c0.midpoint+c1.midpoint;
 273.558 +
 273.559 +#						ifdef _DEBUG
 273.560 +									haveit = true;
 273.561 +#						endif
 273.562 +									break;
 273.563 +								}
 273.564 +							}
 273.565 +
 273.566 +							// this invariant *must* hold if the vertex-to-face adjacency table is valid
 273.567 +							ai_assert(haveit);
 273.568 +						}
 273.569 +
 273.570 +						const float div = static_cast<float>(cnt), divsq = 1.f/(div*div);
 273.571 +						ov.second = Vertex(minp,face.mIndices[a])*((div-3.f) / div) + R*divsq + F*divsq;  
 273.572 +					}
 273.573 +				}
 273.574 +				ov.second.SortBack(mout,faceOut.mIndices[2]=v++);
 273.575 +			}
 273.576 +		}
 273.577 +	}
 273.578 +
 273.579 +	// ---------------------------------------------------------------------
 273.580 +	// 7. Apply the next subdivision step. 
 273.581 +	// ---------------------------------------------------------------------
 273.582 +	if (num != 1) {
 273.583 +		std::vector<aiMesh*> tmp(nmesh);
 273.584 +		InternSubdivide (out,nmesh,&tmp.front(),num-1);
 273.585 +		for (size_t i = 0; i < nmesh; ++i) {
 273.586 +			delete out[i];
 273.587 +			out[i] = tmp[i];
 273.588 +		}
 273.589 +	}
 273.590 +}
   274.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   274.2 +++ b/libs/assimp/Subdivision.h	Sat Feb 01 19:58:19 2014 +0200
   274.3 @@ -0,0 +1,124 @@
   274.4 +/*
   274.5 +Open Asset Import Library (assimp)
   274.6 +----------------------------------------------------------------------
   274.7 +
   274.8 +Copyright (c) 2006-2012, assimp team
   274.9 +All rights reserved.
  274.10 +
  274.11 +Redistribution and use of this software in source and binary forms, 
  274.12 +with or without modification, are permitted provided that the 
  274.13 +following conditions are met:
  274.14 +
  274.15 +* Redistributions of source code must retain the above
  274.16 +  copyright notice, this list of conditions and the
  274.17 +  following disclaimer.
  274.18 +
  274.19 +* Redistributions in binary form must reproduce the above
  274.20 +  copyright notice, this list of conditions and the
  274.21 +  following disclaimer in the documentation and/or other
  274.22 +  materials provided with the distribution.
  274.23 +
  274.24 +* Neither the name of the assimp team, nor the names of its
  274.25 +  contributors may be used to endorse or promote products
  274.26 +  derived from this software without specific prior
  274.27 +  written permission of the assimp team.
  274.28 +
  274.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  274.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  274.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  274.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  274.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  274.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  274.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  274.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  274.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  274.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  274.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  274.40 +
  274.41 +----------------------------------------------------------------------
  274.42 +*/
  274.43 +
  274.44 +/** @file Defines a helper class to evaluate subdivision surfaces.*/
  274.45 +#ifndef AI_SUBDISIVION_H_INC
  274.46 +#define AI_SUBDISIVION_H_INC
  274.47 +namespace Assimp	{
  274.48 +
  274.49 +// ------------------------------------------------------------------------------
  274.50 +/** Helper class to evaluate subdivision surfaces. Different algorithms
  274.51 + *  are provided for choice. */
  274.52 +// ------------------------------------------------------------------------------
  274.53 +class Subdivider
  274.54 +{
  274.55 +public:
  274.56 +
  274.57 +	/** Enumerates all supported subvidision algorithms */
  274.58 +	enum Algorithm	{
  274.59 +		CATMULL_CLARKE = 0x1
  274.60 +	};
  274.61 +
  274.62 +public:
  274.63 +
  274.64 +	virtual ~Subdivider() {
  274.65 +	}
  274.66 +
  274.67 +public:
  274.68 +
  274.69 +	// ---------------------------------------------------------------
  274.70 +	/** Create a subdivider of a specific type
  274.71 +	 *
  274.72 +	 *  @param algo Algorithm to be used for subdivision
  274.73 +	 *  @return Subdivider instance. */
  274.74 +	static Subdivider* Create (Algorithm algo);
  274.75 +
  274.76 +	// ---------------------------------------------------------------
  274.77 +	/** Subdivide a mesh using the selected algorithm
  274.78 +	 *
  274.79 +	 *  @param mesh First mesh to be subdivided. Must be in verbose
  274.80 +	 *    format.
  274.81 +	 *  @param out Receives the output mesh, allocated by me.
  274.82 +	 *  @param num Number of subdivisions to perform.
  274.83 +	 *  @param discard_input If true is passed, the input mesh is
  274.84 +	 *    deleted after the subdivision is complete. This can 
  274.85 +	 *    improve performance because it allows the optimization
  274.86 +	 *    to reuse the existing mesh for intermediate results.
  274.87 +	 *  @pre out!=mesh*/
  274.88 +	virtual void Subdivide ( aiMesh* mesh, 
  274.89 +		aiMesh*& out, unsigned int num,
  274.90 +		bool discard_input = false) = 0;
  274.91 +
  274.92 +	// ---------------------------------------------------------------
  274.93 +	/** Subdivide multiple meshes using the selected algorithm. This
  274.94 +	 *  avoids erroneous smoothing on objects consisting of multiple
  274.95 +	 *  per-material meshes. Usually, most 3d modellers smooth on a
  274.96 +	 *  per-object base, regardless the materials assigned to the
  274.97 +	 *  meshes.
  274.98 +	 *
  274.99 +	 *  @param smesh Array of meshes to be subdivided. Must be in
 274.100 +	 *    verbose format.
 274.101 +	 *  @param nmesh Number of meshes in smesh.
 274.102 +	 *  @param out Receives the output meshes. The array must be
 274.103 +	 *    sufficiently large (at least @c nmesh elements) and may not
 274.104 +	 *    overlap the input array. Output meshes map one-to-one to
 274.105 +	 *    their corresponding input meshes. The meshes are allocated 
 274.106 +	 *    by the function.
 274.107 +	 *  @param discard_input If true is passed, input meshes are
 274.108 +	 *    deleted after the subdivision is complete. This can 
 274.109 +	 *    improve performance because it allows the optimization
 274.110 +	 *    of reusing existing meshes for intermediate results.
 274.111 +	 *  @param num Number of subdivisions to perform.
 274.112 +	 *  @pre nmesh != 0, smesh and out may not overlap*/
 274.113 +	virtual void Subdivide (
 274.114 +		aiMesh** smesh, 
 274.115 +		size_t nmesh,
 274.116 +		aiMesh** out, 
 274.117 +		unsigned int num,
 274.118 +		bool discard_input = false) = 0;
 274.119 +
 274.120 +private:
 274.121 +};
 274.122 +
 274.123 +} // end namespace Assimp
 274.124 +
 274.125 +
 274.126 +#endif // !!  AI_SUBDISIVION_H_INC
 274.127 +
   275.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   275.2 +++ b/libs/assimp/TargetAnimation.cpp	Sat Feb 01 19:58:19 2014 +0200
   275.3 @@ -0,0 +1,246 @@
   275.4 +/*
   275.5 +Open Asset Import Library (assimp)
   275.6 +----------------------------------------------------------------------
   275.7 +
   275.8 +Copyright (c) 2006-2012, assimp team
   275.9 +All rights reserved.
  275.10 +
  275.11 +Redistribution and use of this software in source and binary forms, 
  275.12 +with or without modification, are permitted provided that the 
  275.13 +following conditions are met:
  275.14 +
  275.15 +* Redistributions of source code must retain the above
  275.16 +  copyright notice, this list of conditions and the
  275.17 +  following disclaimer.
  275.18 +
  275.19 +* Redistributions in binary form must reproduce the above
  275.20 +  copyright notice, this list of conditions and the
  275.21 +  following disclaimer in the documentation and/or other
  275.22 +  materials provided with the distribution.
  275.23 +
  275.24 +* Neither the name of the assimp team, nor the names of its
  275.25 +  contributors may be used to endorse or promote products
  275.26 +  derived from this software without specific prior
  275.27 +  written permission of the assimp team.
  275.28 +
  275.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  275.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  275.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  275.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  275.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  275.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  275.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  275.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  275.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  275.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  275.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  275.40 +
  275.41 +----------------------------------------------------------------------
  275.42 +*/
  275.43 +
  275.44 +#include "AssimpPCH.h"
  275.45 +#include "TargetAnimation.h"
  275.46 +#include <algorithm>
  275.47 +
  275.48 +using namespace Assimp;
  275.49 +
  275.50 +
  275.51 +// ------------------------------------------------------------------------------------------------
  275.52 +KeyIterator::KeyIterator(const std::vector<aiVectorKey>* _objPos,
  275.53 +	const std::vector<aiVectorKey>* _targetObjPos,
  275.54 +	const aiVector3D*  defaultObjectPos /*= NULL*/,
  275.55 +	const aiVector3D*  defaultTargetPos /*= NULL*/)
  275.56 +		
  275.57 +		:	reachedEnd		(false)
  275.58 +		,	curTime			(-1.)
  275.59 +		,	objPos			(_objPos)
  275.60 +		,	targetObjPos	(_targetObjPos)
  275.61 +		,	nextObjPos		(0)
  275.62 +		,	nextTargetObjPos(0)
  275.63 +{
  275.64 +	// Generate default transformation tracks if necessary
  275.65 +	if (!objPos || objPos->empty())
  275.66 +	{
  275.67 +		defaultObjPos.resize(1);
  275.68 +		defaultObjPos.front().mTime  = 10e10;
  275.69 +
  275.70 +		if (defaultObjectPos)
  275.71 +			defaultObjPos.front().mValue = *defaultObjectPos;
  275.72 +
  275.73 +		objPos = & defaultObjPos;
  275.74 +	}
  275.75 +	if (!targetObjPos || targetObjPos->empty())
  275.76 +	{
  275.77 +		defaultTargetObjPos.resize(1);
  275.78 +		defaultTargetObjPos.front().mTime  = 10e10;
  275.79 +
  275.80 +		if (defaultTargetPos)
  275.81 +			defaultTargetObjPos.front().mValue = *defaultTargetPos;
  275.82 +
  275.83 +		targetObjPos = & defaultTargetObjPos;
  275.84 +	}
  275.85 +}
  275.86 +
  275.87 +// ------------------------------------------------------------------------------------------------
  275.88 +template <class T>
  275.89 +inline T Interpolate(const T& one, const T& two, float val)
  275.90 +{
  275.91 +	return one + (two-one)*val;
  275.92 +}
  275.93 +
  275.94 +// ------------------------------------------------------------------------------------------------
  275.95 +void KeyIterator::operator ++()
  275.96 +{
  275.97 +	// If we are already at the end of all keyframes, return
  275.98 +	if (reachedEnd) {
  275.99 +		return;
 275.100 +	}
 275.101 +
 275.102 +	// Now search in all arrays for the time value closest
 275.103 +	// to our current position on the time line
 275.104 +	double d0,d1;
 275.105 +	
 275.106 +	d0 = objPos->at      ( std::min<unsigned int> ( nextObjPos, objPos->size()-1)             ).mTime;
 275.107 +	d1 = targetObjPos->at( std::min<unsigned int> ( nextTargetObjPos, targetObjPos->size()-1) ).mTime;	
 275.108 +	
 275.109 +	// Easiest case - all are identical. In this
 275.110 +	// case we don't need to interpolate so we can
 275.111 +	// return earlier
 275.112 +	if ( d0 == d1 )
 275.113 +	{
 275.114 +		curTime = d0;
 275.115 +		curPosition = objPos->at(nextObjPos).mValue;
 275.116 +		curTargetPosition = targetObjPos->at(nextTargetObjPos).mValue;
 275.117 +
 275.118 +		// increment counters
 275.119 +		if (objPos->size() != nextObjPos-1)
 275.120 +			++nextObjPos;
 275.121 +
 275.122 +		if (targetObjPos->size() != nextTargetObjPos-1)
 275.123 +			++nextTargetObjPos;
 275.124 +	}
 275.125 +
 275.126 +	// An object position key is closest to us
 275.127 +	else if (d0 < d1)
 275.128 +	{
 275.129 +		curTime = d0;
 275.130 +
 275.131 +		// interpolate the other
 275.132 +		if (1 == targetObjPos->size() || !nextTargetObjPos)	{
 275.133 +			curTargetPosition = targetObjPos->at(0).mValue;
 275.134 +		}
 275.135 +		else
 275.136 +		{
 275.137 +			const aiVectorKey& last  = targetObjPos->at(nextTargetObjPos);
 275.138 +			const aiVectorKey& first = targetObjPos->at(nextTargetObjPos-1);
 275.139 +
 275.140 +			curTargetPosition = Interpolate(first.mValue, last.mValue, (float) (
 275.141 +				(curTime-first.mTime) / (last.mTime-first.mTime) ));
 275.142 +		}
 275.143 +
 275.144 +		if (objPos->size() != nextObjPos-1)
 275.145 +			++nextObjPos;
 275.146 +	}
 275.147 +	// A target position key is closest to us
 275.148 +	else
 275.149 +	{
 275.150 +		curTime = d1;
 275.151 +
 275.152 +		// interpolate the other
 275.153 +		if (1 == objPos->size() || !nextObjPos)	{
 275.154 +			curPosition = objPos->at(0).mValue;
 275.155 +		}
 275.156 +		else
 275.157 +		{
 275.158 +			const aiVectorKey& last  = objPos->at(nextObjPos);
 275.159 +			const aiVectorKey& first = objPos->at(nextObjPos-1);
 275.160 +
 275.161 +			curPosition = Interpolate(first.mValue, last.mValue, (float) (
 275.162 +				(curTime-first.mTime) / (last.mTime-first.mTime)));
 275.163 +		}
 275.164 +
 275.165 +		if (targetObjPos->size() != nextTargetObjPos-1)
 275.166 +			++nextTargetObjPos;
 275.167 +	}
 275.168 +
 275.169 +	if (nextObjPos >= objPos->size()-1 &&
 275.170 +		nextTargetObjPos >= targetObjPos->size()-1)
 275.171 +	{
 275.172 +		// We reached the very last keyframe
 275.173 +		reachedEnd = true;
 275.174 +	}
 275.175 +}
 275.176 +
 275.177 +// ------------------------------------------------------------------------------------------------
 275.178 +void TargetAnimationHelper::SetTargetAnimationChannel (
 275.179 +	const std::vector<aiVectorKey>* _targetPositions)
 275.180 +{
 275.181 +	ai_assert(NULL != _targetPositions);
 275.182 +	targetPositions = _targetPositions;
 275.183 +}
 275.184 +
 275.185 +// ------------------------------------------------------------------------------------------------
 275.186 +void TargetAnimationHelper::SetMainAnimationChannel (
 275.187 +	const std::vector<aiVectorKey>* _objectPositions)
 275.188 +{
 275.189 +	ai_assert(NULL != _objectPositions);
 275.190 +	objectPositions = _objectPositions;
 275.191 +}
 275.192 +
 275.193 +// ------------------------------------------------------------------------------------------------
 275.194 +void TargetAnimationHelper::SetFixedMainAnimationChannel(
 275.195 +	const aiVector3D& fixed)
 275.196 +{
 275.197 +	objectPositions = NULL; // just to avoid confusion
 275.198 +	fixedMain = fixed;
 275.199 +}
 275.200 +
 275.201 +// ------------------------------------------------------------------------------------------------
 275.202 +void TargetAnimationHelper::Process(std::vector<aiVectorKey>* distanceTrack)
 275.203 +{
 275.204 +	ai_assert(NULL != targetPositions && NULL != distanceTrack);
 275.205 +
 275.206 +	// TODO: in most cases we won't need the extra array
 275.207 +	std::vector<aiVectorKey>  real;
 275.208 +	
 275.209 +	std::vector<aiVectorKey>* fill = (distanceTrack == objectPositions ? &real : distanceTrack);
 275.210 +	fill->reserve(std::max( objectPositions->size(), targetPositions->size() ));
 275.211 +
 275.212 +	// Iterate through all object keys and interpolate their values if necessary.
 275.213 +	// Then get the corresponding target position, compute the difference
 275.214 +	// vector between object and target position. Then compute a rotation matrix
 275.215 +	// that rotates the base vector of the object coordinate system at that time
 275.216 +	// to match the diff vector. 
 275.217 +
 275.218 +	KeyIterator iter(objectPositions,targetPositions,&fixedMain);
 275.219 +	for (;!iter.Finished();++iter)
 275.220 +	{
 275.221 +		const aiVector3D&  position  = iter.GetCurPosition();
 275.222 +		const aiVector3D&  tposition = iter.GetCurTargetPosition();
 275.223 +
 275.224 +		// diff vector
 275.225 +		aiVector3D diff = tposition - position;
 275.226 +		float f = diff.Length();
 275.227 +
 275.228 +		// output distance vector
 275.229 +		if (f)
 275.230 +		{
 275.231 +			fill->push_back(aiVectorKey());
 275.232 +			aiVectorKey& v = fill->back();
 275.233 +			v.mTime  = iter.GetCurTime();
 275.234 +			v.mValue = diff;
 275.235 +
 275.236 +			diff /= f;
 275.237 +		}
 275.238 +		else
 275.239 +		{
 275.240 +			// FIXME: handle this
 275.241 +		}
 275.242 +
 275.243 +		// diff is now the vector in which our camera is pointing
 275.244 +	}
 275.245 +
 275.246 +	if (real.size()) {
 275.247 +		*distanceTrack = real;
 275.248 +	}
 275.249 +}
   276.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   276.2 +++ b/libs/assimp/TargetAnimation.h	Sat Feb 01 19:58:19 2014 +0200
   276.3 @@ -0,0 +1,179 @@
   276.4 +/*
   276.5 +Open Asset Import Library (assimp)
   276.6 +----------------------------------------------------------------------
   276.7 +
   276.8 +Copyright (c) 2006-2012, assimp team
   276.9 +All rights reserved.
  276.10 +
  276.11 +Redistribution and use of this software in source and binary forms, 
  276.12 +with or without modification, are permitted provided that the 
  276.13 +following conditions are met:
  276.14 +
  276.15 +* Redistributions of source code must retain the above
  276.16 +  copyright notice, this list of conditions and the
  276.17 +  following disclaimer.
  276.18 +
  276.19 +* Redistributions in binary form must reproduce the above
  276.20 +  copyright notice, this list of conditions and the
  276.21 +  following disclaimer in the documentation and/or other
  276.22 +  materials provided with the distribution.
  276.23 +
  276.24 +* Neither the name of the assimp team, nor the names of its
  276.25 +  contributors may be used to endorse or promote products
  276.26 +  derived from this software without specific prior
  276.27 +  written permission of the assimp team.
  276.28 +
  276.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  276.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  276.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  276.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  276.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  276.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  276.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  276.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  276.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  276.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  276.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  276.40 +
  276.41 +----------------------------------------------------------------------
  276.42 +*/
  276.43 +
  276.44 +/** @file Defines a helper class for the ASE and 3DS loaders to
  276.45 + help them compute camera and spot light animation channels */
  276.46 +#ifndef AI_TARGET_ANIMATION_H_INC
  276.47 +#define AI_TARGET_ANIMATION_H_INC
  276.48 +
  276.49 +
  276.50 +namespace Assimp	{
  276.51 +
  276.52 +
  276.53 +
  276.54 +// ---------------------------------------------------------------------------
  276.55 +/** Helper class to iterate through all keys in an animation channel.
  276.56 + *
  276.57 + *  Missing tracks are interpolated. This is a helper class for
  276.58 + *  TargetAnimationHelper, but it can be freely used for other purposes.
  276.59 +*/
  276.60 +class KeyIterator
  276.61 +{
  276.62 +public:
  276.63 +
  276.64 +	
  276.65 +	// ------------------------------------------------------------------
  276.66 +	/** Constructs a new key iterator
  276.67 +	 *
  276.68 +	 *  @param _objPos Object position track. May be NULL.
  276.69 +	 *  @param _targetObjPos Target object position track. May be NULL.
  276.70 +	 *  @param defaultObjectPos Default object position to be used if
  276.71 +	 *	  no animated track is available. May be NULL.
  276.72 +	 *  @param defaultTargetPos Default target position to be used if
  276.73 +	 *	  no animated track is available. May be NULL.
  276.74 +	 */
  276.75 +	KeyIterator(const std::vector<aiVectorKey>* _objPos,
  276.76 +		const std::vector<aiVectorKey>* _targetObjPos,
  276.77 +		const aiVector3D*  defaultObjectPos = NULL,
  276.78 +		const aiVector3D*  defaultTargetPos = NULL);
  276.79 +
  276.80 +	// ------------------------------------------------------------------
  276.81 +	/** Returns true if all keys have been processed
  276.82 +	 */
  276.83 +	bool Finished() const
  276.84 +		{return reachedEnd;}
  276.85 +
  276.86 +	// ------------------------------------------------------------------
  276.87 +	/** Increment the iterator
  276.88 +	 */
  276.89 +	void operator++();
  276.90 +	inline void operator++(int)
  276.91 +		{return ++(*this);}
  276.92 +
  276.93 +
  276.94 +
  276.95 +	// ------------------------------------------------------------------
  276.96 +	/** Getters to retrieve the current state of the iterator
  276.97 +	 */
  276.98 +	inline const aiVector3D& GetCurPosition() const
  276.99 +		{return curPosition;}
 276.100 +
 276.101 +	inline const aiVector3D& GetCurTargetPosition() const
 276.102 +		{return curTargetPosition;}
 276.103 +
 276.104 +	inline double GetCurTime() const
 276.105 +		{return curTime;}
 276.106 +
 276.107 +private:
 276.108 +
 276.109 +	//! Did we reach the end?
 276.110 +	bool reachedEnd;
 276.111 +
 276.112 +	//! Represents the current position of the iterator
 276.113 +	aiVector3D curPosition, curTargetPosition;
 276.114 +
 276.115 +	double curTime;
 276.116 +
 276.117 +	//! Input tracks and the next key to process
 276.118 +	const std::vector<aiVectorKey>* objPos,*targetObjPos;
 276.119 +
 276.120 +	unsigned int nextObjPos, nextTargetObjPos;
 276.121 +	std::vector<aiVectorKey> defaultObjPos,defaultTargetObjPos;
 276.122 +};
 276.123 +
 276.124 +// ---------------------------------------------------------------------------
 276.125 +/** Helper class for the 3DS and ASE loaders to compute camera and spot light
 276.126 + *  animations.
 276.127 + *
 276.128 + * 3DS and ASE store the differently to Assimp - there is an animation
 276.129 + * channel for the camera/spot light itself and a separate position
 276.130 + * animation channels specifying the position of the camera/spot light
 276.131 + * look-at target */
 276.132 +class TargetAnimationHelper
 276.133 +{
 276.134 +public:
 276.135 +
 276.136 +	TargetAnimationHelper()
 276.137 +		:	targetPositions		(NULL)
 276.138 +		,	objectPositions		(NULL)
 276.139 +	{}
 276.140 +
 276.141 +
 276.142 +	// ------------------------------------------------------------------
 276.143 +	/** Sets the target animation channel
 276.144 +	 *
 276.145 +	 *  This channel specifies the position of the camera/spot light
 276.146 +	 *  target at a specific position.
 276.147 +	 *
 276.148 +	 *  @param targetPositions Translation channel*/
 276.149 +	void SetTargetAnimationChannel (const 
 276.150 +		std::vector<aiVectorKey>* targetPositions);
 276.151 +
 276.152 +
 276.153 +	// ------------------------------------------------------------------
 276.154 +	/** Sets the main animation channel
 276.155 +	 *
 276.156 +	 *  @param objectPositions Translation channel */
 276.157 +	void SetMainAnimationChannel ( const
 276.158 +		std::vector<aiVectorKey>* objectPositions);
 276.159 +
 276.160 +	// ------------------------------------------------------------------
 276.161 +	/** Sets the main animation channel to a fixed value 
 276.162 +	 *
 276.163 +	 *  @param fixed Fixed value for the main animation channel*/
 276.164 +	void SetFixedMainAnimationChannel(const aiVector3D& fixed);
 276.165 +
 276.166 +
 276.167 +	// ------------------------------------------------------------------
 276.168 +	/** Computes final animation channels
 276.169 +	 * @param distanceTrack Receive camera translation keys ... != NULL. */
 276.170 +	void Process( std::vector<aiVectorKey>* distanceTrack );
 276.171 +
 276.172 +
 276.173 +private:
 276.174 +
 276.175 +	const std::vector<aiVectorKey>* targetPositions,*objectPositions;
 276.176 +	aiVector3D fixedMain;
 276.177 +};
 276.178 +
 276.179 +
 276.180 +} // ! end namespace Assimp
 276.181 +
 276.182 +#endif // include guard
   277.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   277.2 +++ b/libs/assimp/TerragenLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   277.3 @@ -0,0 +1,268 @@
   277.4 +/*
   277.5 +---------------------------------------------------------------------------
   277.6 +Open Asset Import Library (assimp)
   277.7 +---------------------------------------------------------------------------
   277.8 +
   277.9 +Copyright (c) 2006-2012, assimp team
  277.10 +
  277.11 +All rights reserved.
  277.12 +
  277.13 +Redistribution and use of this software in source and binary forms, 
  277.14 +with or without modification, are permitted provided that the following 
  277.15 +conditions are met:
  277.16 +
  277.17 +* Redistributions of source code must retain the above
  277.18 +  copyright notice, this list of conditions and the
  277.19 +  following disclaimer.
  277.20 +
  277.21 +* Redistributions in binary form must reproduce the above
  277.22 +  copyright notice, this list of conditions and the
  277.23 +  following disclaimer in the documentation and/or other
  277.24 +  materials provided with the distribution.
  277.25 +
  277.26 +* Neither the name of the assimp team, nor the names of its
  277.27 +  contributors may be used to endorse or promote products
  277.28 +  derived from this software without specific prior
  277.29 +  written permission of the assimp team.
  277.30 +
  277.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  277.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  277.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  277.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  277.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  277.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  277.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  277.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  277.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  277.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  277.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  277.42 +---------------------------------------------------------------------------
  277.43 +*/
  277.44 +
  277.45 +/** @file Implementation of the Terragen importer class */
  277.46 +
  277.47 +#include "AssimpPCH.h"
  277.48 +
  277.49 +#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
  277.50 +#include "TerragenLoader.h"
  277.51 +
  277.52 +using namespace Assimp;
  277.53 +
  277.54 +static const aiImporterDesc desc = {
  277.55 +	"Terragen Heightmap Importer",
  277.56 +	"",
  277.57 +	"",
  277.58 +	"http://www.planetside.co.uk/",
  277.59 +	aiImporterFlags_SupportBinaryFlavour,
  277.60 +	0,
  277.61 +	0,
  277.62 +	0,
  277.63 +	0,
  277.64 +	"ter" 
  277.65 +};
  277.66 +
  277.67 +// ------------------------------------------------------------------------------------------------
  277.68 +// Constructor to be privately used by Importer
  277.69 +TerragenImporter::TerragenImporter()
  277.70 +: configComputeUVs (false)
  277.71 +{}
  277.72 +
  277.73 +// ------------------------------------------------------------------------------------------------
  277.74 +// Destructor, private as well 
  277.75 +TerragenImporter::~TerragenImporter()
  277.76 +{}
  277.77 +
  277.78 +// ------------------------------------------------------------------------------------------------
  277.79 +// Returns whether the class can handle the format of the given file. 
  277.80 +bool TerragenImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  277.81 +{
  277.82 +	// check file extension 
  277.83 +	std::string extension = GetExtension(pFile);
  277.84 +	
  277.85 +	if( extension == "ter")
  277.86 +		return true;
  277.87 +
  277.88 +	if(  !extension.length() || checkSig)	{
  277.89 +		/*  If CanRead() is called in order to check whether we
  277.90 +		 *  support a specific file extension in general pIOHandler
  277.91 +		 *  might be NULL and it's our duty to return true here.
  277.92 +		 */
  277.93 +		if (!pIOHandler)return true;
  277.94 +		const char* tokens[] = {"terragen"};
  277.95 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
  277.96 +	}
  277.97 +	return false;
  277.98 +}
  277.99 +
 277.100 +// ------------------------------------------------------------------------------------------------
 277.101 +// Build a string of all file extensions supported
 277.102 +const aiImporterDesc* TerragenImporter::GetInfo () const
 277.103 +{
 277.104 +	return &desc;
 277.105 +}
 277.106 +
 277.107 +// ------------------------------------------------------------------------------------------------
 277.108 +// Setup import properties
 277.109 +void TerragenImporter::SetupProperties(const Importer* pImp)
 277.110 +{
 277.111 +	// AI_CONFIG_IMPORT_TER_MAKE_UVS
 277.112 +	configComputeUVs = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS,0) );
 277.113 +}
 277.114 +
 277.115 +// ------------------------------------------------------------------------------------------------
 277.116 +// Imports the given file into the given scene structure. 
 277.117 +void TerragenImporter::InternReadFile( const std::string& pFile, 
 277.118 +	aiScene* pScene, IOSystem* pIOHandler)
 277.119 +{
 277.120 +	IOStream* file = pIOHandler->Open( pFile, "rb");
 277.121 +
 277.122 +	// Check whether we can read from the file
 277.123 +	if( file == NULL)
 277.124 +		throw DeadlyImportError( "Failed to open TERRAGEN TERRAIN file " + pFile + ".");
 277.125 +
 277.126 +	// Construct a stream reader to read all data in the correct endianess
 277.127 +	StreamReaderLE reader(file);
 277.128 +	if(reader.GetRemainingSize() < 16)
 277.129 +		throw DeadlyImportError( "TER: file is too small" );
 277.130 +
 277.131 +	// Check for the existence of the two magic strings 'TERRAGEN' and 'TERRAIN '
 277.132 +	if (::strncmp((const char*)reader.GetPtr(),AI_TERR_BASE_STRING,8))
 277.133 +		throw DeadlyImportError( "TER: Magic string \'TERRAGEN\' not found" );
 277.134 +
 277.135 +	if (::strncmp((const char*)reader.GetPtr()+8,AI_TERR_TERRAIN_STRING,8))
 277.136 +		throw DeadlyImportError( "TER: Magic string \'TERRAIN\' not found" );
 277.137 +
 277.138 +	unsigned int x = 0,y = 0,mode = 0;
 277.139 +	float rad  = 6370.f;
 277.140 +	(void)rad;
 277.141 +
 277.142 +
 277.143 +	aiNode* root = pScene->mRootNode = new aiNode();
 277.144 +	root->mName.Set("<TERRAGEN.TERRAIN>");
 277.145 +
 277.146 +	// Default scaling is 30
 277.147 +	root->mTransformation.a1 = root->mTransformation.b2 = root->mTransformation.c3 = 30.f;
 277.148 +
 277.149 +	// Now read all chunks until we're finished or an EOF marker is encountered
 277.150 +	reader.IncPtr(16);
 277.151 +	while (reader.GetRemainingSize() >= 4)	
 277.152 +	{
 277.153 +		const char* head = (const char*)reader.GetPtr();
 277.154 +		reader.IncPtr(4);
 277.155 +
 277.156 +		// EOF, break in every case
 277.157 +		if (!::strncmp(head,AI_TERR_EOF_STRING,4))
 277.158 +			break;
 277.159 +
 277.160 +		// Number of x-data points
 277.161 +		if (!::strncmp(head,AI_TERR_CHUNK_XPTS,4))
 277.162 +		{
 277.163 +			x = (uint16_t)reader.GetI2();
 277.164 +		}
 277.165 +		// Number of y-data points
 277.166 +		else if (!::strncmp(head,AI_TERR_CHUNK_YPTS,4))
 277.167 +		{
 277.168 +			y = (uint16_t)reader.GetI2();
 277.169 +		}
 277.170 +		// Squared terrains width-1. 
 277.171 +		else if (!::strncmp(head,AI_TERR_CHUNK_SIZE,4))
 277.172 +		{
 277.173 +			x = y = (uint16_t)reader.GetI2()+1;
 277.174 +		}
 277.175 +		// terrain scaling
 277.176 +		else if (!::strncmp(head,AI_TERR_CHUNK_SCAL,4))
 277.177 +		{
 277.178 +			root->mTransformation.a1 = reader.GetF4();
 277.179 +			root->mTransformation.b2 = reader.GetF4();
 277.180 +			root->mTransformation.c3 = reader.GetF4();
 277.181 +		}
 277.182 +		// mapping == 1: earth radius
 277.183 +		else if (!::strncmp(head,AI_TERR_CHUNK_CRAD,4))
 277.184 +		{
 277.185 +			rad = reader.GetF4();
 277.186 +		}
 277.187 +		// mapping mode
 277.188 +		else if (!::strncmp(head,AI_TERR_CHUNK_CRVM,4))
 277.189 +		{
 277.190 +			mode = reader.GetI1();
 277.191 +			if (0 != mode)
 277.192 +				DefaultLogger::get()->error("TER: Unsupported mapping mode, a flat terrain is returned");
 277.193 +		}
 277.194 +		// actual terrain data
 277.195 +		else if (!::strncmp(head,AI_TERR_CHUNK_ALTW,4))
 277.196 +		{
 277.197 +			float hscale  = (float)reader.GetI2()  / 65536;
 277.198 +			float bheight = (float)reader.GetI2();
 277.199 +
 277.200 +			if (!hscale)hscale = 1;
 277.201 +
 277.202 +			// Ensure we have enough data
 277.203 +			if (reader.GetRemainingSize() < x*y*2)
 277.204 +				throw DeadlyImportError("TER: ALTW chunk is too small");
 277.205 +
 277.206 +			if (x <= 1 || y <= 1)
 277.207 +				throw DeadlyImportError("TER: Invalid terrain size");
 277.208 +
 277.209 +			// Allocate the output mesh
 277.210 +			pScene->mMeshes = new aiMesh*[pScene->mNumMeshes = 1];
 277.211 +			aiMesh* m = pScene->mMeshes[0] = new aiMesh();
 277.212 +
 277.213 +			// We return quads
 277.214 +			aiFace* f = m->mFaces = new aiFace[m->mNumFaces = (x-1)*(y-1)];
 277.215 +			aiVector3D* pv = m->mVertices = new aiVector3D[m->mNumVertices = m->mNumFaces*4];
 277.216 +			
 277.217 +			aiVector3D *uv( NULL );
 277.218 +			float step_y( 0.0f ), step_x( 0.0f );
 277.219 +			if (configComputeUVs) {
 277.220 +				uv = m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];
 277.221 +				step_y = 1.f/y;
 277.222 +				step_x = 1.f/x;
 277.223 +			}
 277.224 +			const int16_t* data = (const int16_t*)reader.GetPtr();
 277.225 +
 277.226 +			for (unsigned int yy = 0, t = 0; yy < y-1;++yy)	{
 277.227 +				for (unsigned int xx = 0; xx < x-1;++xx,++f)	{
 277.228 +
 277.229 +					// make verts
 277.230 +					const float fy = (float)yy, fx = (float)xx;
 277.231 +					register unsigned tmp,tmp2;
 277.232 +					*pv++ = aiVector3D(fx,fy,    (float)data[(tmp2=x*yy)    + xx] * hscale + bheight);
 277.233 +					*pv++ = aiVector3D(fx,fy+1,  (float)data[(tmp=x*(yy+1)) + xx] * hscale + bheight);
 277.234 +					*pv++ = aiVector3D(fx+1,fy+1,(float)data[tmp  + xx+1]         * hscale + bheight);
 277.235 +					*pv++ = aiVector3D(fx+1,fy,  (float)data[tmp2 + xx+1]         * hscale + bheight);
 277.236 +
 277.237 +					// also make texture coordinates, if necessary
 277.238 +					if (configComputeUVs) {
 277.239 +						*uv++ = aiVector3D( step_x*xx,     step_y*yy,     0.f );
 277.240 +						*uv++ = aiVector3D( step_x*xx,     step_y*(yy+1), 0.f );
 277.241 +						*uv++ = aiVector3D( step_x*(xx+1), step_y*(yy+1), 0.f );
 277.242 +						*uv++ = aiVector3D( step_x*(xx+1), step_y*yy,     0.f );
 277.243 +					}
 277.244 +
 277.245 +					// make indices
 277.246 +					f->mIndices = new unsigned int[f->mNumIndices = 4];
 277.247 +					for (unsigned int i = 0; i < 4;++i)
 277.248 +						f->mIndices[i] = t++;
 277.249 +				}
 277.250 +			}
 277.251 +
 277.252 +			// Add the mesh to the root node
 277.253 +			root->mMeshes = new unsigned int[root->mNumMeshes = 1];
 277.254 +			root->mMeshes[0] = 0;
 277.255 +		}
 277.256 +
 277.257 +		// Get to the next chunk (4 byte aligned)
 277.258 +		unsigned dtt;
 277.259 +		if ((dtt = reader.GetCurrentPos() & 0x3))
 277.260 +			reader.IncPtr(4-dtt);
 277.261 +	}
 277.262 +
 277.263 +	// Check whether we have a mesh now
 277.264 +	if (pScene->mNumMeshes != 1)
 277.265 +		throw DeadlyImportError("TER: Unable to load terrain");
 277.266 +
 277.267 +	// Set the AI_SCENE_FLAGS_TERRAIN bit
 277.268 +	pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
 277.269 +}
 277.270 +
 277.271 +#endif // !! ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
   278.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   278.2 +++ b/libs/assimp/TerragenLoader.h	Sat Feb 01 19:58:19 2014 +0200
   278.3 @@ -0,0 +1,103 @@
   278.4 +/*
   278.5 +Open Asset Import Library (assimp)
   278.6 +----------------------------------------------------------------------
   278.7 +
   278.8 +Copyright (c) 2006-2012, assimp team
   278.9 +All rights reserved.
  278.10 +
  278.11 +Redistribution and use of this software in source and binary forms, 
  278.12 +with or without modification, are permitted provided that the 
  278.13 +following conditions are met:
  278.14 +
  278.15 +* Redistributions of source code must retain the above
  278.16 +  copyright notice, this list of conditions and the
  278.17 +  following disclaimer.
  278.18 +
  278.19 +* Redistributions in binary form must reproduce the above
  278.20 +  copyright notice, this list of conditions and the
  278.21 +  following disclaimer in the documentation and/or other
  278.22 +  materials provided with the distribution.
  278.23 +
  278.24 +* Neither the name of the assimp team, nor the names of its
  278.25 +  contributors may be used to endorse or promote products
  278.26 +  derived from this software without specific prior
  278.27 +  written permission of the assimp team.
  278.28 +
  278.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  278.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  278.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  278.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  278.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  278.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  278.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  278.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  278.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  278.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  278.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  278.40 +
  278.41 +----------------------------------------------------------------------
  278.42 +*/
  278.43 +
  278.44 +/** @file  TerragenLoader.h
  278.45 + *  @brief Declaration of the .ter importer class. 
  278.46 + */
  278.47 +#ifndef INCLUDED_AI_TERRAGEN_TERRAIN_LOADER_H
  278.48 +#define INCLUDED_AI_TERRAGEN_TERRAIN_LOADER_H
  278.49 +
  278.50 +#include "BaseImporter.h"
  278.51 +namespace Assimp	{
  278.52 +
  278.53 +// Magic strings
  278.54 +#define AI_TERR_BASE_STRING         "TERRAGEN"
  278.55 +#define AI_TERR_TERRAIN_STRING      "TERRAIN "
  278.56 +#define AI_TERR_EOF_STRING          "EOF "
  278.57 +
  278.58 +// Chunka
  278.59 +#define AI_TERR_CHUNK_XPTS          "XPTS"
  278.60 +#define AI_TERR_CHUNK_YPTS          "YPTS"
  278.61 +#define AI_TERR_CHUNK_SIZE          "SIZE"
  278.62 +#define AI_TERR_CHUNK_SCAL          "SCAL"
  278.63 +#define AI_TERR_CHUNK_CRAD          "CRAD"
  278.64 +#define AI_TERR_CHUNK_CRVM          "CRVM"
  278.65 +#define AI_TERR_CHUNK_ALTW          "ALTW"
  278.66 +
  278.67 +// ---------------------------------------------------------------------------
  278.68 +/** @brief Importer class to load Terragen (0.9) terrain files.
  278.69 + *
  278.70 + *  The loader is basing on the information found here:
  278.71 + *  http://www.planetside.co.uk/terragen/dev/tgterrain.html#chunks
  278.72 +*/
  278.73 +class TerragenImporter : public BaseImporter
  278.74 +{
  278.75 +public:
  278.76 +	TerragenImporter();
  278.77 +	~TerragenImporter();
  278.78 +
  278.79 +
  278.80 +public:
  278.81 +
  278.82 +	// -------------------------------------------------------------------
  278.83 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  278.84 +		bool checkSig) const;
  278.85 +
  278.86 +protected:
  278.87 +
  278.88 +	// -------------------------------------------------------------------
  278.89 +	const aiImporterDesc* GetInfo () const;
  278.90 +
  278.91 +	// -------------------------------------------------------------------
  278.92 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  278.93 +		IOSystem* pIOHandler);
  278.94 +
  278.95 +	// -------------------------------------------------------------------
  278.96 +	void SetupProperties(const Importer* pImp);
  278.97 +
  278.98 +private:
  278.99 +
 278.100 +	bool configComputeUVs;
 278.101 +
 278.102 +}; //! class TerragenImporter
 278.103 +
 278.104 +} // end of namespace Assimp
 278.105 +
 278.106 +#endif // AI_AC3DIMPORTER_H_INC
   279.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   279.2 +++ b/libs/assimp/TextureTransform.cpp	Sat Feb 01 19:58:19 2014 +0200
   279.3 @@ -0,0 +1,564 @@
   279.4 +/*
   279.5 +Open Asset Import Library (assimp)
   279.6 +----------------------------------------------------------------------
   279.7 +
   279.8 +Copyright (c) 2006-2012, assimp team
   279.9 +All rights reserved.
  279.10 +
  279.11 +Redistribution and use of this software in source and binary forms, 
  279.12 +with or without modification, are permitted provided that the 
  279.13 +following conditions are met:
  279.14 +
  279.15 +* Redistributions of source code must retain the above
  279.16 +  copyright notice, this list of conditions and the
  279.17 +  following disclaimer.
  279.18 +
  279.19 +* Redistributions in binary form must reproduce the above
  279.20 +  copyright notice, this list of conditions and the
  279.21 +  following disclaimer in the documentation and/or other
  279.22 +  materials provided with the distribution.
  279.23 +
  279.24 +* Neither the name of the assimp team, nor the names of its
  279.25 +  contributors may be used to endorse or promote products
  279.26 +  derived from this software without specific prior
  279.27 +  written permission of the assimp team.
  279.28 +
  279.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  279.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  279.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  279.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  279.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  279.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  279.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  279.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  279.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  279.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  279.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  279.40 +
  279.41 +----------------------------------------------------------------------
  279.42 +*/
  279.43 +
  279.44 +/** @file A helper class that processes texture transformations */
  279.45 +
  279.46 +
  279.47 +#include "AssimpPCH.h"
  279.48 +#include "TextureTransform.h"
  279.49 +
  279.50 +using namespace Assimp;
  279.51 +
  279.52 +
  279.53 +// ------------------------------------------------------------------------------------------------
  279.54 +// Constructor to be privately used by Importer
  279.55 +TextureTransformStep::TextureTransformStep()
  279.56 +{
  279.57 +	// nothing to do here
  279.58 +}
  279.59 +
  279.60 +// ------------------------------------------------------------------------------------------------
  279.61 +// Destructor, private as well
  279.62 +TextureTransformStep::~TextureTransformStep()
  279.63 +{
  279.64 +	// nothing to do here
  279.65 +}
  279.66 +
  279.67 +// ------------------------------------------------------------------------------------------------
  279.68 +// Returns whether the processing step is present in the given flag field.
  279.69 +bool TextureTransformStep::IsActive( unsigned int pFlags) const
  279.70 +{
  279.71 +	return	(pFlags & aiProcess_TransformUVCoords) != 0;
  279.72 +}
  279.73 +
  279.74 +// ------------------------------------------------------------------------------------------------
  279.75 +// Setup properties
  279.76 +void TextureTransformStep::SetupProperties(const Importer* pImp)
  279.77 +{
  279.78 +	configFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_TUV_EVALUATE,AI_UVTRAFO_ALL);
  279.79 +}
  279.80 +
  279.81 +// ------------------------------------------------------------------------------------------------
  279.82 +void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
  279.83 +{
  279.84 +	/*  This function tries to simplify the input UV transformation.
  279.85 +	 *  That's very important as it allows us to reduce the number 
  279.86 +	 *  of output UV channels. The oder in which the transformations
  279.87 +	 *  are applied is - as always - scaling, rotation, translation.
  279.88 +	 */
  279.89 +
  279.90 +	char szTemp[512];
  279.91 +	int rounded = 0;
  279.92 +
  279.93 +
  279.94 +	/* Optimize the rotation angle. That's slightly difficult as
  279.95 +	 * we have an inprecise floating-point number (when comparing
  279.96 +	 * UV transformations we'll take that into account by using
  279.97 +	 * an epsilon of 5 degrees). If there is a rotation value, we can't
  279.98 +	 * perform any further optimizations.
  279.99 +	 */
 279.100 +	if (info.mRotation)
 279.101 +	{
 279.102 +		float out = info.mRotation;
 279.103 +		if ((rounded = (int)(info.mRotation / (float)AI_MATH_TWO_PI)))
 279.104 +		{
 279.105 +			out -= rounded*(float)AI_MATH_PI;
 279.106 +
 279.107 +			sprintf(szTemp,"Texture coordinate rotation %f can be simplified to %f",info.mRotation,out);
 279.108 +			DefaultLogger::get()->info(szTemp);
 279.109 +		}
 279.110 +
 279.111 +		// Next step - convert negative rotation angles to positives
 279.112 +		if (out < 0.f)
 279.113 +			out = (float)AI_MATH_TWO_PI * 2 + out;
 279.114 +
 279.115 +		info.mRotation = out;
 279.116 +		return;
 279.117 +	}
 279.118 +
 279.119 +
 279.120 +	/* Optimize UV translation in the U direction. To determine whether
 279.121 +	 * or not we can optimize we need to look at the requested mapping
 279.122 +	 * type (e.g. if mirroring is active there IS a difference between
 279.123 +	 * offset 2 and 3)
 279.124 +	 */
 279.125 +	if ((rounded  = (int)info.mTranslation.x))	{
 279.126 +		float out;
 279.127 +		szTemp[0] = 0;
 279.128 +		if (aiTextureMapMode_Wrap == info.mapU)	{
 279.129 +			// Wrap - simple take the fraction of the field
 279.130 +			out = info.mTranslation.x-(float)rounded;
 279.131 +			sprintf(szTemp,"[w] UV U offset %f can be simplified to %f",info.mTranslation.x,out);
 279.132 +		}
 279.133 +		else if (aiTextureMapMode_Mirror == info.mapU && 1 != rounded)	{
 279.134 +			// Mirror 
 279.135 +			if (rounded % 2)
 279.136 +				rounded--;
 279.137 +			out = info.mTranslation.x-(float)rounded;
 279.138 +
 279.139 +			sprintf(szTemp,"[m/d] UV U offset %f can be simplified to %f",info.mTranslation.x,out);
 279.140 +		}
 279.141 +		else if (aiTextureMapMode_Clamp == info.mapU || aiTextureMapMode_Decal == info.mapU)	{
 279.142 +			// Clamp - translations beyond 1,1 are senseless
 279.143 +			sprintf(szTemp,"[c] UV U offset %f can be clamped to 1.0f",info.mTranslation.x);
 279.144 +
 279.145 +			out = 1.f;
 279.146 +		}
 279.147 +		if (szTemp[0])		{
 279.148 +			DefaultLogger::get()->info(szTemp);
 279.149 +			info.mTranslation.x = out;
 279.150 +		}
 279.151 +	}
 279.152 +
 279.153 +	/* Optimize UV translation in the V direction. To determine whether
 279.154 +	 * or not we can optimize we need to look at the requested mapping
 279.155 +	 * type (e.g. if mirroring is active there IS a difference between
 279.156 +	 * offset 2 and 3)
 279.157 +	 */
 279.158 +	if ((rounded  = (int)info.mTranslation.y))	{
 279.159 +		float out;
 279.160 +		szTemp[0] = 0;
 279.161 +		if (aiTextureMapMode_Wrap == info.mapV)	{
 279.162 +			// Wrap - simple take the fraction of the field
 279.163 +			out = info.mTranslation.y-(float)rounded;
 279.164 +			sprintf(szTemp,"[w] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
 279.165 +		}
 279.166 +		else if (aiTextureMapMode_Mirror == info.mapV  && 1 != rounded)	{
 279.167 +			// Mirror 
 279.168 +			if (rounded % 2)
 279.169 +				rounded--;
 279.170 +			out = info.mTranslation.x-(float)rounded;
 279.171 +
 279.172 +			sprintf(szTemp,"[m/d] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
 279.173 +		}
 279.174 +		else if (aiTextureMapMode_Clamp == info.mapV || aiTextureMapMode_Decal == info.mapV)	{
 279.175 +			// Clamp - translations beyond 1,1 are senseless
 279.176 +			sprintf(szTemp,"[c] UV V offset %f canbe clamped to 1.0f",info.mTranslation.y);
 279.177 +
 279.178 +			out = 1.f;
 279.179 +		}
 279.180 +		if (szTemp[0])	{
 279.181 +			DefaultLogger::get()->info(szTemp);
 279.182 +			info.mTranslation.y = out;
 279.183 +		}
 279.184 +	}
 279.185 +	return;
 279.186 +}
 279.187 +
 279.188 +// ------------------------------------------------------------------------------------------------
 279.189 +void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n)
 279.190 +{
 279.191 +	// Don't set if == 0 && wasn't set before
 279.192 +	for (std::list<TTUpdateInfo>::const_iterator it = l.begin();it != l.end(); ++it) {
 279.193 +		const TTUpdateInfo& info = *it;
 279.194 +
 279.195 +		if (info.directShortcut)
 279.196 +			*info.directShortcut = n;
 279.197 +		else if (!n)
 279.198 +		{
 279.199 +			info.mat->AddProperty<int>((int*)&n,1,AI_MATKEY_UVWSRC(info.semantic,info.index));
 279.200 +		}
 279.201 +	}
 279.202 +}
 279.203 +
 279.204 +// ------------------------------------------------------------------------------------------------
 279.205 +inline const char* MappingModeToChar(aiTextureMapMode map)
 279.206 +{
 279.207 +	if (aiTextureMapMode_Wrap == map)
 279.208 +		return "-w";
 279.209 +
 279.210 +	if (aiTextureMapMode_Mirror == map)
 279.211 +		return "-m";
 279.212 +	
 279.213 +	return "-c";
 279.214 +}
 279.215 +
 279.216 +// ------------------------------------------------------------------------------------------------
 279.217 +void TextureTransformStep::Execute( aiScene* pScene) 
 279.218 +{
 279.219 +	DefaultLogger::get()->debug("TransformUVCoordsProcess begin");
 279.220 +	
 279.221 +
 279.222 +	/*  We build a per-mesh list of texture transformations we'll need
 279.223 +	 *  to apply. To achieve this, we iterate through all materials, 
 279.224 +	 *  find all textures and get their transformations and UV indices. 
 279.225 +	 *  Then we search for all meshes using this material.
 279.226 +	 */
 279.227 +	typedef std::list<STransformVecInfo> MeshTrafoList;
 279.228 +	std::vector<MeshTrafoList> meshLists(pScene->mNumMeshes);
 279.229 +
 279.230 +	for (unsigned int i = 0; i < pScene->mNumMaterials;++i)	{
 279.231 +
 279.232 +		aiMaterial* mat = pScene->mMaterials[i];
 279.233 +		for (unsigned int a = 0; a < mat->mNumProperties;++a)	{
 279.234 +
 279.235 +			aiMaterialProperty* prop = mat->mProperties[a];
 279.236 +			if (!::strcmp( prop->mKey.data, "$tex.file"))	{
 279.237 +				STransformVecInfo info;
 279.238 +
 279.239 +				// Setup a shortcut structure to allow for a fast updating
 279.240 +				// of the UV index later
 279.241 +				TTUpdateInfo update;
 279.242 +				update.mat = (aiMaterial*) mat;
 279.243 +				update.semantic = prop->mSemantic;
 279.244 +				update.index = prop->mIndex;
 279.245 +
 279.246 +				// Get textured properties and transform
 279.247 +				for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)  {
 279.248 +					aiMaterialProperty* prop2 = mat->mProperties[a2];
 279.249 +					if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex) {
 279.250 +						continue;
 279.251 +					}
 279.252 +
 279.253 +					if ( !::strcmp( prop2->mKey.data, "$tex.uvwsrc")) {
 279.254 +						info.uvIndex = *((int*)prop2->mData);
 279.255 +
 279.256 +						// Store a direct pointer for later use
 279.257 +						update.directShortcut = (unsigned int*) prop2->mData;
 279.258 +					}
 279.259 +
 279.260 +					else if ( !::strcmp( prop2->mKey.data, "$tex.mapmodeu")) {
 279.261 +						info.mapU = *((aiTextureMapMode*)prop2->mData);
 279.262 +					}
 279.263 +					else if ( !::strcmp( prop2->mKey.data, "$tex.mapmodev")) {
 279.264 +						info.mapV = *((aiTextureMapMode*)prop2->mData);
 279.265 +					}
 279.266 +					else if ( !::strcmp( prop2->mKey.data, "$tex.uvtrafo"))  {
 279.267 +						// ValidateDS should check this
 279.268 +						ai_assert(prop2->mDataLength >= 20); 
 279.269 +						::memcpy(&info.mTranslation.x,prop2->mData,sizeof(float)*5);
 279.270 +
 279.271 +						// Directly remove this property from the list 
 279.272 +						mat->mNumProperties--;
 279.273 +						for (unsigned int a3 = a2; a3 < mat->mNumProperties;++a3) {
 279.274 +							mat->mProperties[a3] = mat->mProperties[a3+1];
 279.275 +						}
 279.276 +
 279.277 +						delete prop2;
 279.278 +
 279.279 +						// Warn: could be an underflow, but this does not invoke undefined behaviour
 279.280 +						--a2; 
 279.281 +					}
 279.282 +				}
 279.283 +
 279.284 +				// Find out which transformations are to be evaluated
 279.285 +				if (!(configFlags & AI_UVTRAFO_ROTATION)) {
 279.286 +					info.mRotation = 0.f;
 279.287 +				}
 279.288 +				if (!(configFlags & AI_UVTRAFO_SCALING)) {
 279.289 +					info.mScaling = aiVector2D(1.f,1.f);
 279.290 +				}
 279.291 +				if (!(configFlags & AI_UVTRAFO_TRANSLATION)) {
 279.292 +					info.mTranslation = aiVector2D(0.f,0.f);
 279.293 +				}
 279.294 +
 279.295 +				// Do some preprocessing
 279.296 +				PreProcessUVTransform(info);
 279.297 +				info.uvIndex = std::min(info.uvIndex,AI_MAX_NUMBER_OF_TEXTURECOORDS -1u);
 279.298 +
 279.299 +				// Find out whether this material is used by more than
 279.300 +				// one mesh. This will make our task much, much more difficult!
 279.301 +				unsigned int cnt = 0;
 279.302 +				for (unsigned int n = 0; n < pScene->mNumMeshes;++n)	{
 279.303 +					if (pScene->mMeshes[n]->mMaterialIndex == i)
 279.304 +						++cnt;
 279.305 +				}
 279.306 +
 279.307 +				if (!cnt)
 279.308 +					continue;
 279.309 +				else if (1 != cnt)	{
 279.310 +					// This material is referenced by more than one mesh!
 279.311 +					// So we need to make sure the UV index for the texture
 279.312 +					// is identical for each of it ...
 279.313 +					info.lockedPos = AI_TT_UV_IDX_LOCK_TBD;
 279.314 +				}
 279.315 +
 279.316 +				// Get all coresponding meshes
 279.317 +				for (unsigned int n = 0; n < pScene->mNumMeshes;++n)	{
 279.318 +					aiMesh* mesh = pScene->mMeshes[n];
 279.319 +					if (mesh->mMaterialIndex != i || !mesh->mTextureCoords[0])
 279.320 +						continue;
 279.321 +
 279.322 +					unsigned int uv = info.uvIndex;
 279.323 +					if (!mesh->mTextureCoords[uv])	{
 279.324 +						// If the requested UV index is not available, take the first one instead.
 279.325 +						uv = 0;
 279.326 +					}
 279.327 +					
 279.328 +					if (mesh->mNumUVComponents[info.uvIndex] >= 3){
 279.329 +						DefaultLogger::get()->warn("UV transformations on 3D mapping channels are not supported");
 279.330 +						continue;
 279.331 +					}
 279.332 +
 279.333 +					MeshTrafoList::iterator it;
 279.334 +
 279.335 +					// Check whether we have this transform setup already
 279.336 +					for (it = meshLists[n].begin();it != meshLists[n].end(); ++it)	{
 279.337 +
 279.338 +						if ((*it) == info && (*it).uvIndex == uv)	{
 279.339 +							(*it).updateList.push_back(update);
 279.340 +							break;
 279.341 +						}
 279.342 +					}
 279.343 +
 279.344 +					if (it == meshLists[n].end())	{
 279.345 +						meshLists[n].push_back(info);
 279.346 +						meshLists[n].back().uvIndex = uv;
 279.347 +						meshLists[n].back().updateList.push_back(update);
 279.348 +					}
 279.349 +				}
 279.350 +			}
 279.351 +		}
 279.352 +	}
 279.353 +
 279.354 +	char buffer[1024]; // should be sufficiently large
 279.355 +	unsigned int outChannels = 0, inChannels = 0, transformedChannels = 0;
 279.356 +
 279.357 +	// Now process all meshes. Important: we don't remove unreferenced UV channels.
 279.358 +	// This is a job for the RemoveUnreferencedData-Step.
 279.359 +	for (unsigned int q = 0; q < pScene->mNumMeshes;++q)	{
 279.360 +
 279.361 +		aiMesh* mesh = pScene->mMeshes[q];
 279.362 +		MeshTrafoList& trafo =  meshLists[q];
 279.363 +
 279.364 +		inChannels += mesh->GetNumUVChannels();
 279.365 +
 279.366 +		if (!mesh->mTextureCoords[0] || trafo.empty() ||  (trafo.size() == 1 && trafo.begin()->IsUntransformed())) {
 279.367 +			outChannels += mesh->GetNumUVChannels();
 279.368 +			continue;
 279.369 +		}
 279.370 +
 279.371 +		// Move untransformed UV channels to the first position in the list .... 
 279.372 +		// except if we need a new locked index which should be as small as possible
 279.373 +		bool veto = false, need = false;
 279.374 +		unsigned int cnt = 0;
 279.375 +		unsigned int untransformed = 0;
 279.376 +
 279.377 +		MeshTrafoList::iterator it,it2;
 279.378 +		for (it = trafo.begin();it != trafo.end(); ++it,++cnt)	{
 279.379 +
 279.380 +			if (!(*it).IsUntransformed()) {
 279.381 +				need = true;
 279.382 +			}
 279.383 +
 279.384 +			if ((*it).lockedPos == AI_TT_UV_IDX_LOCK_TBD)	{
 279.385 +				// Lock this index and make sure it won't be changed
 279.386 +				(*it).lockedPos = cnt;
 279.387 +				veto = true;
 279.388 +				continue;
 279.389 +			}
 279.390 +
 279.391 +			if (!veto && it != trafo.begin() && (*it).IsUntransformed())	{
 279.392 +				for (it2 = trafo.begin();it2 != it; ++it2) {
 279.393 +					if (!(*it2).IsUntransformed()) 
 279.394 +						break;
 279.395 +				}
 279.396 +				trafo.insert(it2,*it);
 279.397 +				trafo.erase(it);
 279.398 +				break;
 279.399 +			}
 279.400 +		}
 279.401 +		if (!need)
 279.402 +			continue;
 279.403 +
 279.404 +		// Find all that are not at their 'locked' position and move them to it. 
 279.405 +		// Conflicts are possible but quite unlikely.
 279.406 +		cnt = 0;
 279.407 +		for (it = trafo.begin();it != trafo.end(); ++it,++cnt) {
 279.408 +			if ((*it).lockedPos != AI_TT_UV_IDX_LOCK_NONE && (*it).lockedPos != cnt) {
 279.409 +				it2 = trafo.begin();unsigned int t = 0;
 279.410 +				while (t != (*it).lockedPos)
 279.411 +					++it2;
 279.412 +
 279.413 +				if ((*it2).lockedPos != AI_TT_UV_IDX_LOCK_NONE) {
 279.414 +					DefaultLogger::get()->error("Channel mismatch, can't compute all transformations properly [design bug]");
 279.415 +					continue;
 279.416 +				}
 279.417 +
 279.418 +				std::swap(*it2,*it);
 279.419 +				if ((*it).lockedPos == untransformed)
 279.420 +					untransformed = cnt;
 279.421 +			}
 279.422 +		}
 279.423 +
 279.424 +		// ... and add dummies for all unreferenced channels
 279.425 +		// at the end of the list
 279.426 +		bool ref[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 279.427 +		for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
 279.428 +			ref[n] = (!mesh->mTextureCoords[n] ? true : false);
 279.429 +
 279.430 +		for (it = trafo.begin();it != trafo.end(); ++it)
 279.431 +			ref[(*it).uvIndex] = true;
 279.432 +
 279.433 +		for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
 279.434 +			if (ref[n])
 279.435 +				continue;
 279.436 +			trafo.push_back(STransformVecInfo());
 279.437 +			trafo.back().uvIndex = n;
 279.438 +		}
 279.439 +
 279.440 +		// Then check whether this list breaks the channel limit.
 279.441 +		// The unimportant ones are at the end of the list, so
 279.442 +		// it shouldn't be too worse if we remove them.
 279.443 +		unsigned int size = (unsigned int)trafo.size();
 279.444 +		if (size > AI_MAX_NUMBER_OF_TEXTURECOORDS) {
 279.445 +
 279.446 +			if (!DefaultLogger::isNullLogger()) {
 279.447 +				::sprintf(buffer,"%u UV channels required but just %u available", 
 279.448 +					static_cast<unsigned int>(trafo.size()),AI_MAX_NUMBER_OF_TEXTURECOORDS);
 279.449 +
 279.450 +				DefaultLogger::get()->error(buffer);
 279.451 +			}
 279.452 +			size = AI_MAX_NUMBER_OF_TEXTURECOORDS;
 279.453 +		}
 279.454 +
 279.455 +
 279.456 +		aiVector3D* old[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 279.457 +		for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
 279.458 +			old[n] = mesh->mTextureCoords[n];
 279.459 +
 279.460 +		// Now continue and generate the output channels. Channels
 279.461 +		// that we're not going to need later can be overridden.
 279.462 +		it = trafo.begin();
 279.463 +		for (unsigned int n = 0; n < trafo.size();++n,++it)	{
 279.464 +
 279.465 +			if (n >= size)	{
 279.466 +				// Try to use an untransformed channel for all channels we threw over board
 279.467 +				UpdateUVIndex((*it).updateList,untransformed);
 279.468 +				continue;
 279.469 +			}
 279.470 +
 279.471 +			outChannels++;
 279.472 +
 279.473 +			// Write to the log
 279.474 +			if (!DefaultLogger::isNullLogger())	{
 279.475 +				sprintf(buffer,"Mesh %u, channel %u: t(%.3f,%.3f), s(%.3f,%.3f), r(%.3f), %s%s",
 279.476 +					q,n,
 279.477 +					(*it).mTranslation.x,
 279.478 +					(*it).mTranslation.y,
 279.479 +					(*it).mScaling.x,
 279.480 +					(*it).mScaling.y,
 279.481 +					AI_RAD_TO_DEG( (*it).mRotation),
 279.482 +					MappingModeToChar ((*it).mapU),
 279.483 +					MappingModeToChar ((*it).mapV));
 279.484 +
 279.485 +				DefaultLogger::get()->info(buffer);
 279.486 +			}
 279.487 +
 279.488 +			// Check whether we need a new buffer here
 279.489 +			if (mesh->mTextureCoords[n])	{
 279.490 +
 279.491 +				it2 = it;++it2;
 279.492 +				for (unsigned int m = n+1; m < size;++m, ++it2)	{
 279.493 +
 279.494 +					if ((*it2).uvIndex == n){
 279.495 +						it2 = trafo.begin();
 279.496 +						break;
 279.497 +					}
 279.498 +				}
 279.499 +				if (it2 == trafo.begin()){
 279.500 +					mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
 279.501 +				} 
 279.502 +			}
 279.503 +			else mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
 279.504 +
 279.505 +			aiVector3D* src = old[(*it).uvIndex];
 279.506 +			aiVector3D* dest, *end;
 279.507 +			dest = mesh->mTextureCoords[n];
 279.508 +
 279.509 +			ai_assert(NULL != src);
 279.510 +
 279.511 +			// Copy the data to the destination array
 279.512 +			if (dest != src)
 279.513 +				::memcpy(dest,src,sizeof(aiVector3D)*mesh->mNumVertices);
 279.514 +
 279.515 +			end = dest + mesh->mNumVertices;
 279.516 +
 279.517 +			// Build a transformation matrix and transform all UV coords with it
 279.518 +			if (!(*it).IsUntransformed()) {
 279.519 +				const aiVector2D& trl = (*it).mTranslation;
 279.520 +				const aiVector2D& scl = (*it).mScaling;
 279.521 +
 279.522 +				// fixme: simplify ..
 279.523 +				++transformedChannels;
 279.524 +				aiMatrix3x3 matrix;
 279.525 +
 279.526 +				aiMatrix3x3 m2,m3,m4,m5;
 279.527 +
 279.528 +				m4.a1 = scl.x;
 279.529 +				m4.b2 = scl.y;
 279.530 +				
 279.531 +				m2.a3 = m2.b3 = 0.5f;
 279.532 +				m3.a3 = m3.b3 = -0.5f;
 279.533 +
 279.534 +				if ((*it).mRotation > AI_TT_ROTATION_EPSILON )
 279.535 +					aiMatrix3x3::RotationZ((*it).mRotation,matrix);
 279.536 +
 279.537 +				m5.a3 += trl.x; m5.b3 += trl.y;
 279.538 +				matrix = m2 * m4 * matrix * m3 * m5;
 279.539 +				
 279.540 +				for (src = dest; src != end; ++src)	{ /* manual homogenious divide */
 279.541 +					src->z = 1.f;
 279.542 +					*src = matrix * *src;
 279.543 +					src->x /= src->z;
 279.544 +					src->y /= src->z;
 279.545 +					src->z = 0.f;
 279.546 +				}
 279.547 +			}
 279.548 +
 279.549 +			// Update all UV indices
 279.550 +			UpdateUVIndex((*it).updateList,n);
 279.551 +		}
 279.552 +	}
 279.553 +
 279.554 +	// Print some detailled statistics into the log
 279.555 +	if (!DefaultLogger::isNullLogger())	{
 279.556 +
 279.557 +		if (transformedChannels)	{
 279.558 +			::sprintf(buffer,"TransformUVCoordsProcess end: %u output channels (in: %u, modified: %u)",
 279.559 +				outChannels,inChannels,transformedChannels);
 279.560 +
 279.561 +			DefaultLogger::get()->info(buffer);
 279.562 +		}
 279.563 +		else DefaultLogger::get()->debug("TransformUVCoordsProcess finished");
 279.564 +	}
 279.565 +}
 279.566 +
 279.567 +
   280.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   280.2 +++ b/libs/assimp/TextureTransform.h	Sat Feb 01 19:58:19 2014 +0200
   280.3 @@ -0,0 +1,227 @@
   280.4 +/*
   280.5 +Open Asset Import Library (assimp)
   280.6 +----------------------------------------------------------------------
   280.7 +
   280.8 +Copyright (c) 2006-2012, assimp team
   280.9 +All rights reserved.
  280.10 +
  280.11 +Redistribution and use of this software in source and binary forms, 
  280.12 +with or without modification, are permitted provided that the 
  280.13 +following conditions are met:
  280.14 +
  280.15 +* Redistributions of source code must retain the above
  280.16 +  copyright notice, this list of conditions and the
  280.17 +  following disclaimer.
  280.18 +
  280.19 +* Redistributions in binary form must reproduce the above
  280.20 +  copyright notice, this list of conditions and the
  280.21 +  following disclaimer in the documentation and/or other
  280.22 +  materials provided with the distribution.
  280.23 +
  280.24 +* Neither the name of the assimp team, nor the names of its
  280.25 +  contributors may be used to endorse or promote products
  280.26 +  derived from this software without specific prior
  280.27 +  written permission of the assimp team.
  280.28 +
  280.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  280.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  280.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  280.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  280.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  280.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  280.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  280.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  280.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  280.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  280.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  280.40 +
  280.41 +----------------------------------------------------------------------
  280.42 +*/
  280.43 +
  280.44 +/** @file Definition of a helper step that processes texture transformations */
  280.45 +#ifndef AI_TEXTURE_TRANSFORM_H_INCLUDED
  280.46 +#define AI_TEXTURE_TRANSFORM_H_INCLUDED
  280.47 +
  280.48 +#include "BaseImporter.h"
  280.49 +#include "BaseProcess.h"
  280.50 +
  280.51 +struct aiNode;
  280.52 +
  280.53 +namespace Assimp	{
  280.54 +
  280.55 +#define AI_TT_UV_IDX_LOCK_TBD	0xffffffff
  280.56 +#define AI_TT_UV_IDX_LOCK_NONE	0xeeeeeeee
  280.57 +
  280.58 +
  280.59 +#define AI_TT_ROTATION_EPSILON	((float)AI_DEG_TO_RAD(0.5))
  280.60 +
  280.61 +// ---------------------------------------------------------------------------
  280.62 +/** Small helper structure representing a shortcut into the material list
  280.63 + *  to be able to update some values quickly.
  280.64 +*/
  280.65 +struct TTUpdateInfo
  280.66 +{
  280.67 +	TTUpdateInfo() :
  280.68 +			directShortcut	(NULL)
  280.69 +		,	mat				(NULL)
  280.70 +		,	semantic		(0)
  280.71 +		,	index			(0)
  280.72 +	{}
  280.73 +
  280.74 +	//! Direct shortcut, if available
  280.75 +	unsigned int* directShortcut;
  280.76 +
  280.77 +	//! Material 
  280.78 +	aiMaterial *mat;
  280.79 +
  280.80 +	//! Texture type and index
  280.81 +	unsigned int semantic, index;
  280.82 +};
  280.83 +
  280.84 +
  280.85 +// ---------------------------------------------------------------------------
  280.86 +/** Helper class representing texture coordinate transformations
  280.87 +*/
  280.88 +struct STransformVecInfo : public aiUVTransform
  280.89 +{
  280.90 +
  280.91 +	STransformVecInfo()
  280.92 +		:	uvIndex		(0)
  280.93 +		,	mapU		(aiTextureMapMode_Wrap)
  280.94 +		,	mapV		(aiTextureMapMode_Wrap)
  280.95 +		,	lockedPos	(AI_TT_UV_IDX_LOCK_NONE)
  280.96 +	{}
  280.97 +
  280.98 +	//! Source texture coordinate index
  280.99 +	unsigned int uvIndex;
 280.100 +
 280.101 +	//! Texture mapping mode in the u, v direction
 280.102 +	aiTextureMapMode mapU,mapV;
 280.103 +
 280.104 +	//! Locked destination UV index
 280.105 +	//! AI_TT_UV_IDX_LOCK_TBD - to be determined
 280.106 +	//! AI_TT_UV_IDX_LOCK_NONE - none (default)
 280.107 +	unsigned int lockedPos;
 280.108 +
 280.109 +	//! Update info - shortcuts into all materials
 280.110 +	//! that are referencing this transform setup
 280.111 +	std::list<TTUpdateInfo> updateList;
 280.112 +
 280.113 +
 280.114 +	// -------------------------------------------------------------------
 280.115 +	/** Compare two transform setups
 280.116 +	*/
 280.117 +	inline bool operator== (const STransformVecInfo& other) const
 280.118 +	{
 280.119 +		// We use a small epsilon here
 280.120 +		const static float epsilon = 0.05f;
 280.121 +
 280.122 +		if (fabs( mTranslation.x - other.mTranslation.x ) > epsilon ||
 280.123 +			fabs( mTranslation.y - other.mTranslation.y ) > epsilon)
 280.124 +		{
 280.125 +			return false;
 280.126 +		}
 280.127 +
 280.128 +		if (fabs( mScaling.x - other.mScaling.x ) > epsilon ||
 280.129 +			fabs( mScaling.y - other.mScaling.y ) > epsilon)
 280.130 +		{
 280.131 +			return false;
 280.132 +		}
 280.133 +
 280.134 +		if (fabs( mRotation - other.mRotation) > epsilon)
 280.135 +		{
 280.136 +			return false;
 280.137 +		}
 280.138 +		return true;
 280.139 +	}
 280.140 +
 280.141 +	inline bool operator!= (const STransformVecInfo& other) const
 280.142 +	{
 280.143 +			return !(*this == other);
 280.144 +	}
 280.145 +
 280.146 +
 280.147 +	// -------------------------------------------------------------------
 280.148 +	/** Returns whether this is an untransformed texture coordinate set
 280.149 +	*/
 280.150 +	inline bool IsUntransformed() const
 280.151 +	{
 280.152 +		return (1.0f == mScaling.x && 1.f == mScaling.y &&
 280.153 +			!mTranslation.x && !mTranslation.y && 
 280.154 +			mRotation < AI_TT_ROTATION_EPSILON);
 280.155 +	}
 280.156 +
 280.157 +	// -------------------------------------------------------------------
 280.158 +	/** Build a 3x3 matrix from the transformations
 280.159 +	*/
 280.160 +	inline void GetMatrix(aiMatrix3x3& mOut)
 280.161 +	{
 280.162 +		mOut = aiMatrix3x3();
 280.163 +
 280.164 +		if (1.0f != mScaling.x || 1.0f != mScaling.y)
 280.165 +		{
 280.166 +			aiMatrix3x3 mScale;
 280.167 +			mScale.a1 = mScaling.x;
 280.168 +			mScale.b2 = mScaling.y;
 280.169 +			mOut = mScale;
 280.170 +		}
 280.171 +		if (mRotation)
 280.172 +		{
 280.173 +			aiMatrix3x3 mRot; 
 280.174 +			mRot.a1 = mRot.b2 = cos(mRotation);
 280.175 +			mRot.a2 = mRot.b1 = sin(mRotation);
 280.176 +			mRot.a2 = -mRot.a2;
 280.177 +			mOut *= mRot;
 280.178 +		}
 280.179 +		if (mTranslation.x || mTranslation.y)
 280.180 +		{
 280.181 +			aiMatrix3x3 mTrans; 
 280.182 +			mTrans.a3 = mTranslation.x;
 280.183 +			mTrans.b3 = mTranslation.y;
 280.184 +			mOut *= mTrans;
 280.185 +		}
 280.186 +	}
 280.187 +};
 280.188 +
 280.189 +
 280.190 +// ---------------------------------------------------------------------------
 280.191 +/** Helper step to compute final UV coordinate sets if there are scalings
 280.192 + *  or rotations in the original data read from the file.
 280.193 +*/
 280.194 +class TextureTransformStep : public BaseProcess
 280.195 +{
 280.196 +public:
 280.197 +
 280.198 +	TextureTransformStep();
 280.199 +	~TextureTransformStep();
 280.200 +
 280.201 +public:
 280.202 +
 280.203 +	// -------------------------------------------------------------------
 280.204 +	bool IsActive( unsigned int pFlags) const;
 280.205 +
 280.206 +	// -------------------------------------------------------------------
 280.207 +	void Execute( aiScene* pScene);
 280.208 +
 280.209 +	// -------------------------------------------------------------------
 280.210 +	void SetupProperties(const Importer* pImp);
 280.211 +
 280.212 +
 280.213 +protected:
 280.214 +
 280.215 +
 280.216 +	// -------------------------------------------------------------------
 280.217 +	/** Preprocess a specific UV transformation setup
 280.218 +	 *
 280.219 +	 *  @param info Transformation setup to be preprocessed.
 280.220 +	*/
 280.221 +	void PreProcessUVTransform(STransformVecInfo& info);
 280.222 +
 280.223 +private:
 280.224 +
 280.225 +	unsigned int configFlags;
 280.226 +};
 280.227 +
 280.228 +}
 280.229 +
 280.230 +#endif //! AI_TEXTURE_TRANSFORM_H_INCLUDED
   281.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   281.2 +++ b/libs/assimp/TinyFormatter.h	Sat Feb 01 19:58:19 2014 +0200
   281.3 @@ -0,0 +1,163 @@
   281.4 +/*
   281.5 +Open Asset Import Library (assimp)
   281.6 +----------------------------------------------------------------------
   281.7 +
   281.8 +Copyright (c) 2006-2012, assimp team
   281.9 +All rights reserved.
  281.10 +
  281.11 +Redistribution and use of this software in source and binary forms, 
  281.12 +with or without modification, are permitted provided that the 
  281.13 +following conditions are met:
  281.14 +
  281.15 +* Redistributions of source code must retain the above
  281.16 +  copyright notice, this list of conditions and the
  281.17 +  following disclaimer.
  281.18 +
  281.19 +* Redistributions in binary form must reproduce the above
  281.20 +  copyright notice, this list of conditions and the
  281.21 +  following disclaimer in the documentation and/or other
  281.22 +  materials provided with the distribution.
  281.23 +
  281.24 +* Neither the name of the assimp team, nor the names of its
  281.25 +  contributors may be used to endorse or promote products
  281.26 +  derived from this software without specific prior
  281.27 +  written permission of the assimp team.
  281.28 +
  281.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  281.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  281.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  281.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  281.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  281.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  281.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  281.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  281.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  281.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  281.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  281.40 +
  281.41 +----------------------------------------------------------------------
  281.42 +*/
  281.43 +
  281.44 +/** @file  TinyFormatter.h
  281.45 + *  @brief Utility to format log messages more easily. Introduced
  281.46 + *    to get rid of the boost::format dependency. Much slinker,
  281.47 + *    basically just extends stringstream.
  281.48 + */
  281.49 +#ifndef INCLUDED_TINY_FORMATTER_H
  281.50 +#define INCLUDED_TINY_FORMATTER_H
  281.51 +
  281.52 +#include <sstream>
  281.53 +
  281.54 +namespace Assimp {
  281.55 +	namespace Formatter {
  281.56 +
  281.57 +// ------------------------------------------------------------------------------------------------
  281.58 +/** stringstream utility. Usage:
  281.59 + *  @code
  281.60 + *  void writelog(const std::string&s);
  281.61 + *  void writelog(const std::wstring&s);
  281.62 + *  ...
  281.63 + *  writelog(format()<< "hi! this is a number: " << 4);
  281.64 + *  writelog(wformat()<< L"hi! this is a number: " << 4);
  281.65 + *
  281.66 + *  @endcode */
  281.67 +template < typename T,
  281.68 +	typename CharTraits = std::char_traits<T>,
  281.69 +	typename Allocator  = std::allocator<T>
  281.70 +> 
  281.71 +class basic_formatter 
  281.72 +{
  281.73 +
  281.74 +public:
  281.75 +
  281.76 +	typedef class std::basic_string< 
  281.77 +		T,CharTraits,Allocator
  281.78 +	> string;
  281.79 +
  281.80 +	typedef class std::basic_ostringstream< 
  281.81 +		T,CharTraits,Allocator
  281.82 +	> stringstream;
  281.83 +
  281.84 +public:
  281.85 +
  281.86 +	basic_formatter() {}
  281.87 +
  281.88 +	/* Allow basic_formatter<T>'s to be used almost interchangeably
  281.89 +	 * with std::(w)string or const (w)char* arguments because the
  281.90 +	 * conversion c'tor is called implicitly. */
  281.91 +	template <typename TT>
  281.92 +	basic_formatter(const TT& sin)	{
  281.93 +		underlying << sin;
  281.94 +	}
  281.95 +
  281.96 +
  281.97 +	// The problem described here:
  281.98 +	// https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462
  281.99 +	// can also cause trouble here. Apparently, older gcc versions sometimes copy temporaries
 281.100 +	// being bound to const ref& function parameters. Copying streams is not permitted, though.
 281.101 +	// This workaround avoids this by manually specifying a copy ctor.
 281.102 +#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 281.103 +	basic_formatter(const basic_formatter& other) {
 281.104 +		underlying << (string)other;
 281.105 +	}
 281.106 +#endif
 281.107 +	 
 281.108 +
 281.109 +public:
 281.110 +
 281.111 +	operator string () const {
 281.112 +		return underlying.str();
 281.113 +	}
 281.114 +
 281.115 +
 281.116 +	/* note - this is declared const because binding temporaries does only
 281.117 +	 * work for const references, so many function prototypes will 
 281.118 +	 * include const basic_formatter<T>& s but might still want to
 281.119 +	 * modify the formatted string without the need for a full copy.*/
 281.120 +	template <typename TToken>
 281.121 +	const basic_formatter& operator << (const TToken& s) const {
 281.122 +		underlying << s;
 281.123 +		return *this;
 281.124 +	}
 281.125 +
 281.126 +	template <typename TToken>
 281.127 +	basic_formatter& operator << (const TToken& s) {
 281.128 +		underlying << s;
 281.129 +		return *this;
 281.130 +	}
 281.131 +
 281.132 +
 281.133 +	// comma operator overloaded as well, choose your preferred way.
 281.134 +	template <typename TToken>
 281.135 +	const basic_formatter& operator, (const TToken& s) const {
 281.136 +		underlying << s;
 281.137 +		return *this;
 281.138 +	}
 281.139 +
 281.140 +	template <typename TToken>
 281.141 +	basic_formatter& operator, (const TToken& s) {
 281.142 +		underlying << s;
 281.143 +		return *this;
 281.144 +	}
 281.145 +
 281.146 +	// Fix for MSVC8
 281.147 +	// See https://sourceforge.net/projects/assimp/forums/forum/817654/topic/4372824
 281.148 +	template <typename TToken>
 281.149 +	basic_formatter& operator, (TToken& s) {
 281.150 +		underlying << s;
 281.151 +		return *this;
 281.152 +	}
 281.153 +
 281.154 +
 281.155 +private:
 281.156 +	mutable stringstream underlying;
 281.157 +};
 281.158 +
 281.159 +
 281.160 +typedef basic_formatter< char > format;
 281.161 +typedef basic_formatter< wchar_t > wformat;
 281.162 +
 281.163 +} // ! namespace Formatter 
 281.164 +
 281.165 +} // ! namespace Assimp
 281.166 +#endif
   282.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   282.2 +++ b/libs/assimp/TriangulateProcess.cpp	Sat Feb 01 19:58:19 2014 +0200
   282.3 @@ -0,0 +1,527 @@
   282.4 +/*
   282.5 +---------------------------------------------------------------------------
   282.6 +Open Asset Import Library (assimp)
   282.7 +---------------------------------------------------------------------------
   282.8 +
   282.9 +Copyright (c) 2006-2012, assimp team
  282.10 +
  282.11 +All rights reserved.
  282.12 +
  282.13 +Redistribution and use of this software in source and binary forms, 
  282.14 +with or without modification, are permitted provided that the following 
  282.15 +conditions are met:
  282.16 +
  282.17 +* Redistributions of source code must retain the above
  282.18 +  copyright notice, this list of conditions and the
  282.19 +  following disclaimer.
  282.20 +
  282.21 +* Redistributions in binary form must reproduce the above
  282.22 +  copyright notice, this list of conditions and the
  282.23 +  following disclaimer in the documentation and/or other
  282.24 +  materials provided with the distribution.
  282.25 +
  282.26 +* Neither the name of the assimp team, nor the names of its
  282.27 +  contributors may be used to endorse or promote products
  282.28 +  derived from this software without specific prior
  282.29 +  written permission of the assimp team.
  282.30 +
  282.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  282.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  282.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  282.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  282.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  282.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  282.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  282.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  282.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  282.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  282.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  282.42 +---------------------------------------------------------------------------
  282.43 +*/
  282.44 +
  282.45 +/** @file  TriangulateProcess.cpp
  282.46 + *  @brief Implementation of the post processing step to split up
  282.47 + *    all faces with more than three indices into triangles.
  282.48 + *
  282.49 + *
  282.50 + *  The triangulation algorithm will handle concave or convex polygons.
  282.51 + *  Self-intersecting or non-planar polygons are not rejected, but
  282.52 + *  they're probably not triangulated correctly.
  282.53 + *
  282.54 + * DEBUG SWITCHES - do not enable any of them in release builds:
  282.55 + *
  282.56 + * AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
  282.57 + *   - generates vertex colors to represent the face winding order.
  282.58 + *     the first vertex of a polygon becomes red, the last blue.
  282.59 + * AI_BUILD_TRIANGULATE_DEBUG_POLYS
  282.60 + *   - dump all polygons and their triangulation sequences to
  282.61 + *     a file
  282.62 + */
  282.63 +
  282.64 +#include "AssimpPCH.h"
  282.65 +
  282.66 +#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
  282.67 +#include "TriangulateProcess.h"
  282.68 +#include "ProcessHelper.h"
  282.69 +#include "PolyTools.h"
  282.70 +
  282.71 +//#define AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
  282.72 +//#define AI_BUILD_TRIANGULATE_DEBUG_POLYS
  282.73 +
  282.74 +#define POLY_GRID_Y 40
  282.75 +#define POLY_GRID_X 70
  282.76 +#define POLY_GRID_XPAD 20
  282.77 +#define POLY_OUTPUT_FILE "assimp_polygons_debug.txt"
  282.78 +
  282.79 +using namespace Assimp;
  282.80 +
  282.81 +// ------------------------------------------------------------------------------------------------
  282.82 +// Constructor to be privately used by Importer
  282.83 +TriangulateProcess::TriangulateProcess()
  282.84 +{
  282.85 +	// nothing to do here
  282.86 +}
  282.87 +
  282.88 +// ------------------------------------------------------------------------------------------------
  282.89 +// Destructor, private as well
  282.90 +TriangulateProcess::~TriangulateProcess()
  282.91 +{
  282.92 +	// nothing to do here
  282.93 +}
  282.94 +
  282.95 +// ------------------------------------------------------------------------------------------------
  282.96 +// Returns whether the processing step is present in the given flag field.
  282.97 +bool TriangulateProcess::IsActive( unsigned int pFlags) const
  282.98 +{
  282.99 +	return (pFlags & aiProcess_Triangulate) != 0;
 282.100 +}
 282.101 +
 282.102 +// ------------------------------------------------------------------------------------------------
 282.103 +// Executes the post processing step on the given imported data.
 282.104 +void TriangulateProcess::Execute( aiScene* pScene)
 282.105 +{
 282.106 +	DefaultLogger::get()->debug("TriangulateProcess begin");
 282.107 +
 282.108 +	bool bHas = false;
 282.109 +	for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
 282.110 +	{
 282.111 +		if(	TriangulateMesh( pScene->mMeshes[a]))
 282.112 +			bHas = true;
 282.113 +	}
 282.114 +	if (bHas)DefaultLogger::get()->info ("TriangulateProcess finished. All polygons have been triangulated.");
 282.115 +	else     DefaultLogger::get()->debug("TriangulateProcess finished. There was nothing to be done.");
 282.116 +}
 282.117 +
 282.118 +
 282.119 +// ------------------------------------------------------------------------------------------------
 282.120 +// Triangulates the given mesh.
 282.121 +bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
 282.122 +{
 282.123 +	// Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
 282.124 +	if (!pMesh->mPrimitiveTypes)	{
 282.125 +		bool bNeed = false;
 282.126 +
 282.127 +		for( unsigned int a = 0; a < pMesh->mNumFaces; a++)	{
 282.128 +			const aiFace& face = pMesh->mFaces[a];
 282.129 +
 282.130 +			if( face.mNumIndices != 3)	{
 282.131 +				bNeed = true;
 282.132 +			}
 282.133 +		}
 282.134 +		if (!bNeed)
 282.135 +			return false;
 282.136 +	}
 282.137 +	else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) {
 282.138 +		return false;
 282.139 +	}
 282.140 +
 282.141 +	// Find out how many output faces we'll get
 282.142 +	unsigned int numOut = 0, max_out = 0;
 282.143 +	bool get_normals = true;
 282.144 +	for( unsigned int a = 0; a < pMesh->mNumFaces; a++)	{
 282.145 +		aiFace& face = pMesh->mFaces[a];
 282.146 +		if (face.mNumIndices <= 4) {
 282.147 +			get_normals = false;
 282.148 +		}
 282.149 +		if( face.mNumIndices <= 3) {
 282.150 +			numOut++;
 282.151 +
 282.152 +		}	
 282.153 +		else {
 282.154 +			numOut += face.mNumIndices-2;
 282.155 +			max_out = std::max(max_out,face.mNumIndices);
 282.156 +		}
 282.157 +	}
 282.158 +
 282.159 +	// Just another check whether aiMesh::mPrimitiveTypes is correct
 282.160 +	assert(numOut != pMesh->mNumFaces);
 282.161 +
 282.162 +	aiVector3D* nor_out = NULL;
 282.163 +
 282.164 +	// if we don't have normals yet, but expect them to be a cheap side
 282.165 +	// product of triangulation anyway, allocate storage for them.
 282.166 +	if (!pMesh->mNormals && get_normals) {
 282.167 +		// XXX need a mechanism to inform the GenVertexNormals process to treat these normals as preprocessed per-face normals
 282.168 +	//	nor_out = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
 282.169 +	}
 282.170 +
 282.171 +	// the output mesh will contain triangles, but no polys anymore
 282.172 +	pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
 282.173 +	pMesh->mPrimitiveTypes &= ~aiPrimitiveType_POLYGON;
 282.174 +
 282.175 +	aiFace* out = new aiFace[numOut](), *curOut = out;
 282.176 +	std::vector<aiVector3D> temp_verts3d(max_out+2); /* temporary storage for vertices */
 282.177 +	std::vector<aiVector2D> temp_verts(max_out+2);
 282.178 +
 282.179 +	// Apply vertex colors to represent the face winding?
 282.180 +#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
 282.181 +	if (!pMesh->mColors[0])
 282.182 +		pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
 282.183 +	else
 282.184 +		new(pMesh->mColors[0]) aiColor4D[pMesh->mNumVertices];
 282.185 +
 282.186 +	aiColor4D* clr = pMesh->mColors[0];
 282.187 +#endif
 282.188 +
 282.189 +	
 282.190 +#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
 282.191 +	FILE* fout = fopen(POLY_OUTPUT_FILE,"a");
 282.192 +#endif
 282.193 +
 282.194 +	const aiVector3D* verts = pMesh->mVertices;
 282.195 +
 282.196 +	// use boost::scoped_array to avoid slow std::vector<bool> specialiations
 282.197 +	boost::scoped_array<bool> done(new bool[max_out]); 
 282.198 +	for( unsigned int a = 0; a < pMesh->mNumFaces; a++)	{
 282.199 +		aiFace& face = pMesh->mFaces[a];
 282.200 +
 282.201 +		unsigned int* idx = face.mIndices;
 282.202 +		int num = (int)face.mNumIndices, ear = 0, tmp, prev = num-1, next = 0, max = num;
 282.203 +
 282.204 +		// Apply vertex colors to represent the face winding?
 282.205 +#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
 282.206 +		for (unsigned int i = 0; i < face.mNumIndices; ++i) {
 282.207 +			aiColor4D& c = clr[idx[i]];
 282.208 +			c.r = (i+1) / (float)max;
 282.209 +			c.b = 1.f - c.r;
 282.210 +		}
 282.211 +#endif
 282.212 +
 282.213 +		aiFace* const last_face = curOut; 
 282.214 +
 282.215 +		// if it's a simple point,line or triangle: just copy it
 282.216 +		if( face.mNumIndices <= 3)
 282.217 +		{
 282.218 +			aiFace& nface = *curOut++;
 282.219 +			nface.mNumIndices = face.mNumIndices;
 282.220 +			nface.mIndices    = face.mIndices;
 282.221 +
 282.222 +			face.mIndices = NULL;
 282.223 +			continue;
 282.224 +		}  
 282.225 +		// optimized code for quadrilaterals
 282.226 +		else if ( face.mNumIndices == 4) {
 282.227 +
 282.228 +			// quads can have at maximum one concave vertex. Determine
 282.229 +			// this vertex (if it exists) and start tri-fanning from
 282.230 +			// it. 
 282.231 +			unsigned int start_vertex = 0;
 282.232 +			for (unsigned int i = 0; i < 4; ++i) {
 282.233 +				const aiVector3D& v0 = verts[face.mIndices[(i+3) % 4]];
 282.234 +				const aiVector3D& v1 = verts[face.mIndices[(i+2) % 4]];
 282.235 +				const aiVector3D& v2 = verts[face.mIndices[(i+1) % 4]];
 282.236 +
 282.237 +				const aiVector3D& v = verts[face.mIndices[i]];
 282.238 +
 282.239 +				aiVector3D left = (v0-v); 
 282.240 +				aiVector3D diag = (v1-v); 
 282.241 +				aiVector3D right = (v2-v); 
 282.242 +
 282.243 +				left.Normalize();
 282.244 +				diag.Normalize();
 282.245 +				right.Normalize();
 282.246 +
 282.247 +				const float angle = acos(left*diag) + acos(right*diag);
 282.248 +				if (angle > AI_MATH_PI_F) {
 282.249 +					// this is the concave point
 282.250 +					start_vertex = i;
 282.251 +					break;
 282.252 +				}
 282.253 +			}
 282.254 +
 282.255 +			const unsigned int temp[] = {face.mIndices[0], face.mIndices[1], face.mIndices[2], face.mIndices[3]};
 282.256 +	
 282.257 +			aiFace& nface = *curOut++;
 282.258 +			nface.mNumIndices = 3;
 282.259 +			nface.mIndices = face.mIndices;
 282.260 +
 282.261 +			nface.mIndices[0] = temp[start_vertex];
 282.262 +			nface.mIndices[1] = temp[(start_vertex + 1) % 4];
 282.263 +			nface.mIndices[2] = temp[(start_vertex + 2) % 4];
 282.264 +
 282.265 +			aiFace& sface = *curOut++;
 282.266 +			sface.mNumIndices = 3;
 282.267 +			sface.mIndices = new unsigned int[3];
 282.268 +
 282.269 +			sface.mIndices[0] = temp[start_vertex];
 282.270 +			sface.mIndices[1] = temp[(start_vertex + 2) % 4];
 282.271 +			sface.mIndices[2] = temp[(start_vertex + 3) % 4];
 282.272 +		
 282.273 +			// prevent double deletion of the indices field
 282.274 +			face.mIndices = NULL;
 282.275 +			continue;
 282.276 +		} 
 282.277 +		else
 282.278 +		{
 282.279 +			// A polygon with more than 3 vertices can be either concave or convex.
 282.280 +			// Usually everything we're getting is convex and we could easily
 282.281 +			// triangulate by trifanning. However, LightWave is probably the only
 282.282 +			// modeling suite to make extensive use of highly concave, monster polygons ...
 282.283 +			// so we need to apply the full 'ear cutting' algorithm to get it right.
 282.284 +
 282.285 +			// RERQUIREMENT: polygon is expected to be simple and *nearly* planar.
 282.286 +			// We project it onto a plane to get a 2d triangle.
 282.287 +
 282.288 +			// Collect all vertices of of the polygon.
 282.289 +			for (tmp = 0; tmp < max; ++tmp) {
 282.290 +				temp_verts3d[tmp] = verts[idx[tmp]];
 282.291 +			}
 282.292 +
 282.293 +			// Get newell normal of the polygon. Store it for future use if it's a polygon-only mesh
 282.294 +			aiVector3D n;
 282.295 +			NewellNormal<3,3,3>(n,max,&temp_verts3d.front().x,&temp_verts3d.front().y,&temp_verts3d.front().z);
 282.296 +			if (nor_out) {
 282.297 +				 for (tmp = 0; tmp < max; ++tmp)
 282.298 +					 nor_out[idx[tmp]] = n;
 282.299 +			}
 282.300 +
 282.301 +			// Select largest normal coordinate to ignore for projection
 282.302 +			const float ax = (n.x>0 ? n.x : -n.x);    
 282.303 +			const float ay = (n.y>0 ? n.y : -n.y);   
 282.304 +			const float az = (n.z>0 ? n.z : -n.z);    
 282.305 +
 282.306 +			unsigned int ac = 0, bc = 1; /* no z coord. projection to xy */
 282.307 +			float inv = n.z;
 282.308 +			if (ax > ay) {
 282.309 +				if (ax > az) { /* no x coord. projection to yz */
 282.310 +					ac = 1; bc = 2;
 282.311 +					inv = n.x;
 282.312 +				}
 282.313 +			}
 282.314 +			else if (ay > az) { /* no y coord. projection to zy */
 282.315 +				ac = 2; bc = 0;
 282.316 +				inv = n.y;
 282.317 +			}
 282.318 +
 282.319 +			// Swap projection axes to take the negated projection vector into account
 282.320 +			if (inv < 0.f) {
 282.321 +				std::swap(ac,bc);
 282.322 +			}
 282.323 +
 282.324 +			for (tmp =0; tmp < max; ++tmp) {
 282.325 +				temp_verts[tmp].x = verts[idx[tmp]][ac];
 282.326 +				temp_verts[tmp].y = verts[idx[tmp]][bc];
 282.327 +				done[tmp] = false;	
 282.328 +			}
 282.329 +
 282.330 +			
 282.331 +#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
 282.332 +			// plot the plane onto which we mapped the polygon to a 2D ASCII pic
 282.333 +			aiVector2D bmin,bmax;
 282.334 +			ArrayBounds(&temp_verts[0],max,bmin,bmax);
 282.335 +
 282.336 +			char grid[POLY_GRID_Y][POLY_GRID_X+POLY_GRID_XPAD];
 282.337 +			std::fill_n((char*)grid,POLY_GRID_Y*(POLY_GRID_X+POLY_GRID_XPAD),' ');
 282.338 +
 282.339 +			for (int i =0; i < max; ++i) {
 282.340 +				const aiVector2D& v = (temp_verts[i] - bmin) / (bmax-bmin);
 282.341 +				const size_t x = static_cast<size_t>(v.x*(POLY_GRID_X-1)), y = static_cast<size_t>(v.y*(POLY_GRID_Y-1));
 282.342 +				char* loc = grid[y]+x;
 282.343 +				if (grid[y][x] != ' ') {
 282.344 +					for(;*loc != ' '; ++loc);
 282.345 +					*loc++ = '_';
 282.346 +				}
 282.347 +				*(loc+sprintf(loc,"%i",i)) = ' ';
 282.348 +			}
 282.349 +			
 282.350 +
 282.351 +			for(size_t y = 0; y < POLY_GRID_Y; ++y) {
 282.352 +				grid[y][POLY_GRID_X+POLY_GRID_XPAD-1] = '\0';
 282.353 +				fprintf(fout,"%s\n",grid[y]);
 282.354 +			}
 282.355 +
 282.356 +			fprintf(fout,"\ntriangulation sequence: ");
 282.357 +#endif
 282.358 +
 282.359 +			//
 282.360 +			// FIXME: currently this is the slow O(kn) variant with a worst case
 282.361 +			// complexity of O(n^2) (I think). Can be done in O(n).
 282.362 +			while (num > 3)	{
 282.363 +
 282.364 +				// Find the next ear of the polygon
 282.365 +				int num_found = 0;
 282.366 +				for (ear = next;;prev = ear,ear = next) {
 282.367 +				
 282.368 +					// break after we looped two times without a positive match
 282.369 +					for (next=ear+1;done[(next>=max?next=0:next)];++next);
 282.370 +					if (next < ear) {
 282.371 +						if (++num_found == 2) {
 282.372 +							break;
 282.373 +						}
 282.374 +					}
 282.375 +					const aiVector2D* pnt1 = &temp_verts[ear], 
 282.376 +						*pnt0 = &temp_verts[prev], 
 282.377 +						*pnt2 = &temp_verts[next];
 282.378 +			
 282.379 +					// Must be a convex point. Assuming ccw winding, it must be on the right of the line between p-1 and p+1.
 282.380 +					if (OnLeftSideOfLine2D(*pnt0,*pnt2,*pnt1)) {
 282.381 +						continue;
 282.382 +					}
 282.383 +
 282.384 +					// and no other point may be contained in this triangle
 282.385 +					for ( tmp = 0; tmp < max; ++tmp) {
 282.386 +
 282.387 +						// We need to compare the actual values because it's possible that multiple indexes in 
 282.388 +						// the polygon are referring to the same position. concave_polygon.obj is a sample
 282.389 +						//
 282.390 +						// FIXME: Use 'epsiloned' comparisons instead? Due to numeric inaccuracies in
 282.391 +						// PointInTriangle() I'm guessing that it's actually possible to construct
 282.392 +						// input data that would cause us to end up with no ears. The problem is,
 282.393 +						// which epsilon? If we chose a too large value, we'd get wrong results
 282.394 +						const aiVector2D& vtmp = temp_verts[tmp]; 
 282.395 +						if ( vtmp != *pnt1 && vtmp != *pnt2 && vtmp != *pnt0 && PointInTriangle2D(*pnt0,*pnt1,*pnt2,vtmp)) {
 282.396 +							break;		
 282.397 +						}
 282.398 +					}
 282.399 +					if (tmp != max) {
 282.400 +						continue;
 282.401 +					}
 282.402 +
 282.403 +					// this vertex is an ear
 282.404 +					break;
 282.405 +				}
 282.406 +				if (num_found == 2) {
 282.407 +					
 282.408 +					// Due to the 'two ear theorem', every simple polygon with more than three points must
 282.409 +					// have 2 'ears'. Here's definitely someting wrong ... but we don't give up yet.
 282.410 +					//
 282.411 +
 282.412 +					// Instead we're continuting with the standard trifanning algorithm which we'd
 282.413 +					// use if we had only convex polygons. That's life.
 282.414 +					DefaultLogger::get()->error("Failed to triangulate polygon (no ear found). Probably not a simple polygon?");
 282.415 +					
 282.416 +
 282.417 +#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
 282.418 +					fprintf(fout,"critical error here, no ear found! ");
 282.419 +#endif
 282.420 +					num = 0;
 282.421 +					break;
 282.422 +
 282.423 +					curOut -= (max-num); /* undo all previous work */
 282.424 +					for (tmp = 0; tmp < max-2; ++tmp) {
 282.425 +						aiFace& nface = *curOut++;
 282.426 +
 282.427 +						nface.mNumIndices = 3;
 282.428 +						if (!nface.mIndices)
 282.429 +							nface.mIndices = new unsigned int[3];
 282.430 +
 282.431 +						nface.mIndices[0] = 0;
 282.432 +						nface.mIndices[1] = tmp+1;
 282.433 +						nface.mIndices[2] = tmp+2;
 282.434 +
 282.435 +					}
 282.436 +					num = 0;
 282.437 +					break;
 282.438 +				}
 282.439 +
 282.440 +				aiFace& nface = *curOut++;
 282.441 +				nface.mNumIndices = 3;
 282.442 +
 282.443 +				if (!nface.mIndices) {
 282.444 +					nface.mIndices = new unsigned int[3];
 282.445 +				}
 282.446 +
 282.447 +				// setup indices for the new triangle ...
 282.448 +				nface.mIndices[0] = prev;
 282.449 +				nface.mIndices[1] = ear;
 282.450 +				nface.mIndices[2] = next;
 282.451 +
 282.452 +				// exclude the ear from most further processing
 282.453 +				done[ear] = true;
 282.454 +				--num;
 282.455 +			}
 282.456 +			if (num > 0) {
 282.457 +				// We have three indices forming the last 'ear' remaining. Collect them.
 282.458 +				aiFace& nface = *curOut++;
 282.459 +				nface.mNumIndices = 3;
 282.460 +				if (!nface.mIndices) {
 282.461 +					nface.mIndices = new unsigned int[3];
 282.462 +				}
 282.463 +
 282.464 +				for (tmp = 0; done[tmp]; ++tmp);
 282.465 +				nface.mIndices[0] = tmp;
 282.466 +
 282.467 +				for (++tmp; done[tmp]; ++tmp);
 282.468 +				nface.mIndices[1] = tmp;
 282.469 +
 282.470 +				for (++tmp; done[tmp]; ++tmp);
 282.471 +				nface.mIndices[2] = tmp;
 282.472 +
 282.473 +			}
 282.474 +		}
 282.475 +
 282.476 +#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
 282.477 +		
 282.478 +		for(aiFace* f = last_face; f != curOut; ++f) {
 282.479 +			unsigned int* i = f->mIndices;
 282.480 +			fprintf(fout," (%i %i %i)",i[0],i[1],i[2]);
 282.481 +		}
 282.482 +
 282.483 +		fprintf(fout,"\n*********************************************************************\n");
 282.484 +		fflush(fout);
 282.485 +		
 282.486 +#endif
 282.487 +
 282.488 +		for(aiFace* f = last_face; f != curOut; ) {
 282.489 +			unsigned int* i = f->mIndices;
 282.490 +
 282.491 +			//  drop dumb 0-area triangles
 282.492 +			if (fabs(GetArea2D(temp_verts[i[0]],temp_verts[i[1]],temp_verts[i[2]])) < 1e-5f) {
 282.493 +				DefaultLogger::get()->debug("Dropping triangle with area 0");
 282.494 +				--curOut;
 282.495 +
 282.496 +				delete[] f->mIndices;
 282.497 +				f->mIndices = NULL;
 282.498 +
 282.499 +				for(aiFace* ff = f; ff != curOut; ++ff) {
 282.500 +					ff->mNumIndices = (ff+1)->mNumIndices;
 282.501 +					ff->mIndices = (ff+1)->mIndices;
 282.502 +					(ff+1)->mIndices = NULL;
 282.503 +				}
 282.504 +				continue;
 282.505 +			}
 282.506 +
 282.507 +			i[0] = idx[i[0]];
 282.508 +			i[1] = idx[i[1]];
 282.509 +			i[2] = idx[i[2]];
 282.510 +			++f;
 282.511 +		}
 282.512 +
 282.513 +		delete[] face.mIndices;
 282.514 +		face.mIndices = NULL; 
 282.515 +	}
 282.516 +
 282.517 +#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
 282.518 +	fclose(fout);
 282.519 +#endif
 282.520 +
 282.521 +	// kill the old faces
 282.522 +	delete [] pMesh->mFaces;
 282.523 +
 282.524 +	// ... and store the new ones
 282.525 +	pMesh->mFaces    = out;
 282.526 +	pMesh->mNumFaces = (unsigned int)(curOut-out); /* not necessarily equal to numOut */
 282.527 +	return true;
 282.528 +}
 282.529 +
 282.530 +#endif // !! ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
   283.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   283.2 +++ b/libs/assimp/TriangulateProcess.h	Sat Feb 01 19:58:19 2014 +0200
   283.3 @@ -0,0 +1,93 @@
   283.4 +/*
   283.5 +Open Asset Import Library (assimp)
   283.6 +----------------------------------------------------------------------
   283.7 +
   283.8 +Copyright (c) 2006-2012, assimp team
   283.9 +All rights reserved.
  283.10 +
  283.11 +Redistribution and use of this software in source and binary forms, 
  283.12 +with or without modification, are permitted provided that the 
  283.13 +following conditions are met:
  283.14 +
  283.15 +* Redistributions of source code must retain the above
  283.16 +  copyright notice, this list of conditions and the
  283.17 +  following disclaimer.
  283.18 +
  283.19 +* Redistributions in binary form must reproduce the above
  283.20 +  copyright notice, this list of conditions and the
  283.21 +  following disclaimer in the documentation and/or other
  283.22 +  materials provided with the distribution.
  283.23 +
  283.24 +* Neither the name of the assimp team, nor the names of its
  283.25 +  contributors may be used to endorse or promote products
  283.26 +  derived from this software without specific prior
  283.27 +  written permission of the assimp team.
  283.28 +
  283.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  283.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  283.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  283.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  283.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  283.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  283.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  283.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  283.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  283.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  283.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  283.40 +
  283.41 +----------------------------------------------------------------------
  283.42 +*/
  283.43 +
  283.44 +/** @file Defines a post processing step to triangulate all faces 
  283.45 +          with more than three vertices.
  283.46 + */
  283.47 +#ifndef AI_TRIANGULATEPROCESS_H_INC
  283.48 +#define AI_TRIANGULATEPROCESS_H_INC
  283.49 +
  283.50 +#include "BaseProcess.h"
  283.51 +
  283.52 +struct aiMesh;
  283.53 +
  283.54 +class TriangulateProcessTest;
  283.55 +namespace Assimp
  283.56 +{
  283.57 +
  283.58 +// ---------------------------------------------------------------------------
  283.59 +/** The TriangulateProcess splits up all faces with more than three indices
  283.60 + * into triangles. You usually want this to happen because the graphics cards
  283.61 + * need their data as triangles.
  283.62 + */
  283.63 +class TriangulateProcess : public BaseProcess
  283.64 +{
  283.65 +public:
  283.66 +
  283.67 +	TriangulateProcess();
  283.68 +	~TriangulateProcess();
  283.69 +
  283.70 +public:
  283.71 +	// -------------------------------------------------------------------
  283.72 +	/** Returns whether the processing step is present in the given flag field.
  283.73 +	 * @param pFlags The processing flags the importer was called with. A bitwise
  283.74 +	 *   combination of #aiPostProcessSteps.
  283.75 +	 * @return true if the process is present in this flag fields, false if not.
  283.76 +	*/
  283.77 +	bool IsActive( unsigned int pFlags) const;
  283.78 +
  283.79 +	// -------------------------------------------------------------------
  283.80 +	/** Executes the post processing step on the given imported data.
  283.81 +	* At the moment a process is not supposed to fail.
  283.82 +	* @param pScene The imported data to work at.
  283.83 +	*/
  283.84 +	void Execute( aiScene* pScene);
  283.85 +
  283.86 +public:
  283.87 +	// -------------------------------------------------------------------
  283.88 +	/** Triangulates the given mesh.
  283.89 +	 * @param pMesh The mesh to triangulate.
  283.90 +	 */
  283.91 +	bool TriangulateMesh( aiMesh* pMesh);
  283.92 +};
  283.93 +
  283.94 +} // end of namespace Assimp
  283.95 +
  283.96 +#endif // AI_TRIANGULATEPROCESS_H_INC
   284.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   284.2 +++ b/libs/assimp/UnrealLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   284.3 @@ -0,0 +1,439 @@
   284.4 +/*
   284.5 +---------------------------------------------------------------------------
   284.6 +Open Asset Import Library (assimp)
   284.7 +---------------------------------------------------------------------------
   284.8 +
   284.9 +Copyright (c) 2006-2012, assimp team
  284.10 +
  284.11 +All rights reserved.
  284.12 +
  284.13 +Redistribution and use of this software in source and binary forms, 
  284.14 +with or without modification, are permitted provided that the following 
  284.15 +conditions are met:
  284.16 +
  284.17 +* Redistributions of source code must retain the above
  284.18 +  copyright notice, this list of conditions and the
  284.19 +  following disclaimer.
  284.20 +
  284.21 +* Redistributions in binary form must reproduce the above
  284.22 +  copyright notice, this list of conditions and the
  284.23 +  following disclaimer in the documentation and/or other
  284.24 +  materials provided with the distribution.
  284.25 +
  284.26 +* Neither the name of the assimp team, nor the names of its
  284.27 +  contributors may be used to endorse or promote products
  284.28 +  derived from this software without specific prior
  284.29 +  written permission of the assimp team.
  284.30 +
  284.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  284.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  284.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  284.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  284.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  284.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  284.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  284.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  284.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  284.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  284.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  284.42 +---------------------------------------------------------------------------
  284.43 +*/
  284.44 +
  284.45 +/** @file  UnrealLoader.cpp
  284.46 + *  @brief Implementation of the UNREAL (*.3D) importer class
  284.47 + *
  284.48 + *  Sources:
  284.49 + *    http://local.wasp.uwa.edu.au/~pbourke/dataformats/unreal/
  284.50 + */
  284.51 +
  284.52 +#include "AssimpPCH.h"
  284.53 +
  284.54 +#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
  284.55 +
  284.56 +#include "UnrealLoader.h"
  284.57 +#include "StreamReader.h"
  284.58 +#include "ParsingUtils.h"
  284.59 +#include "fast_atof.h"
  284.60 +#include "ConvertToLHProcess.h"
  284.61 +
  284.62 +using namespace Assimp;
  284.63 +
  284.64 +static const aiImporterDesc desc = {
  284.65 +	"Unreal Mesh Importer",
  284.66 +	"",
  284.67 +	"",
  284.68 +	"",
  284.69 +	aiImporterFlags_SupportTextFlavour,
  284.70 +	0,
  284.71 +	0,
  284.72 +	0,
  284.73 +	0,
  284.74 +	"3d uc" 
  284.75 +};
  284.76 +
  284.77 +
  284.78 +// ------------------------------------------------------------------------------------------------
  284.79 +// Constructor to be privately used by Importer
  284.80 +UnrealImporter::UnrealImporter()
  284.81 +:	configFrameID	(0)
  284.82 +,	configHandleFlags (true)
  284.83 +{}
  284.84 +
  284.85 +// ------------------------------------------------------------------------------------------------
  284.86 +// Destructor, private as well 
  284.87 +UnrealImporter::~UnrealImporter()
  284.88 +{}
  284.89 +
  284.90 +// ------------------------------------------------------------------------------------------------
  284.91 +// Returns whether the class can handle the format of the given file. 
  284.92 +bool UnrealImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
  284.93 +{
  284.94 +	return  SimpleExtensionCheck(pFile,"3d","uc");
  284.95 +}
  284.96 +
  284.97 +// ------------------------------------------------------------------------------------------------
  284.98 +// Build a string of all file extensions supported
  284.99 +const aiImporterDesc* UnrealImporter::GetInfo () const
 284.100 +{
 284.101 +	return &desc;
 284.102 +}
 284.103 +
 284.104 +// ------------------------------------------------------------------------------------------------
 284.105 +// Setup configuration properties for the loader
 284.106 +void UnrealImporter::SetupProperties(const Importer* pImp)
 284.107 +{
 284.108 +	// The 
 284.109 +	// AI_CONFIG_IMPORT_UNREAL_KEYFRAME option overrides the
 284.110 +	// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
 284.111 +	configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_KEYFRAME,-1);
 284.112 +	if(static_cast<unsigned int>(-1) == configFrameID)	{
 284.113 +		configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
 284.114 +	}
 284.115 +
 284.116 +	// AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS, default is true
 284.117 +	configHandleFlags = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS,1));
 284.118 +}
 284.119 +
 284.120 +// ------------------------------------------------------------------------------------------------
 284.121 +// Imports the given file into the given scene structure. 
 284.122 +void UnrealImporter::InternReadFile( const std::string& pFile, 
 284.123 +	aiScene* pScene, IOSystem* pIOHandler)
 284.124 +{
 284.125 +	// For any of the 3 files being passed get the three correct paths
 284.126 +	// First of all, determine file extension
 284.127 +	std::string::size_type pos = pFile.find_last_of('.');
 284.128 +	std::string extension = GetExtension(pFile);
 284.129 +
 284.130 +	std::string d_path,a_path,uc_path;
 284.131 +	if (extension == "3d")		{
 284.132 +		// jjjj_d.3d
 284.133 +		// jjjj_a.3d
 284.134 +		pos = pFile.find_last_of('_');
 284.135 +		if (std::string::npos == pos) {
 284.136 +			throw DeadlyImportError("UNREAL: Unexpected naming scheme");
 284.137 +		}
 284.138 +		extension = pFile.substr(0,pos);
 284.139 +	}
 284.140 +	else {
 284.141 +		extension = pFile.substr(0,pos);
 284.142 +	}
 284.143 +
 284.144 +	// build proper paths
 284.145 +	d_path  = extension+"_d.3d";
 284.146 +	a_path  = extension+"_a.3d";
 284.147 +	uc_path = extension+".uc";
 284.148 +
 284.149 +	DefaultLogger::get()->debug("UNREAL: data file is " + d_path);
 284.150 +	DefaultLogger::get()->debug("UNREAL: aniv file is " + a_path);
 284.151 +	DefaultLogger::get()->debug("UNREAL: uc file is "   + uc_path);
 284.152 +
 284.153 +	// and open the files ... we can't live without them
 284.154 +	IOStream* p = pIOHandler->Open(d_path);
 284.155 +	if (!p)
 284.156 +		throw DeadlyImportError("UNREAL: Unable to open _d file");
 284.157 +	StreamReaderLE d_reader(pIOHandler->Open(d_path));
 284.158 +
 284.159 +	const uint16_t numTris = d_reader.GetI2();
 284.160 +	const uint16_t numVert = d_reader.GetI2();
 284.161 +	d_reader.IncPtr(44);
 284.162 +	if (!numTris || numVert < 3)
 284.163 +		throw DeadlyImportError("UNREAL: Invalid number of vertices/triangles");
 284.164 +
 284.165 +	// maximum texture index
 284.166 +	unsigned int maxTexIdx = 0;
 284.167 +
 284.168 +	// collect triangles
 284.169 +	std::vector<Unreal::Triangle> triangles(numTris);
 284.170 +	for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();it != end; ++it)	{
 284.171 +		Unreal::Triangle& tri = *it;
 284.172 +
 284.173 +		for (unsigned int i = 0; i < 3;++i)	{
 284.174 +
 284.175 +			tri.mVertex[i] = d_reader.GetI2();
 284.176 +			if (tri.mVertex[i] >= numTris)	{
 284.177 +				DefaultLogger::get()->warn("UNREAL: vertex index out of range");
 284.178 +				tri.mVertex[i] = 0;
 284.179 +			}
 284.180 +		}
 284.181 +		tri.mType = d_reader.GetI1();
 284.182 +
 284.183 +		// handle mesh flagss?
 284.184 +		if (configHandleFlags)
 284.185 +			tri.mType = Unreal::MF_NORMAL_OS;
 284.186 +		else {
 284.187 +			// ignore MOD and MASKED for the moment, treat them as two-sided
 284.188 +			if (tri.mType == Unreal::MF_NORMAL_MOD_TS || tri.mType == Unreal::MF_NORMAL_MASKED_TS)
 284.189 +				tri.mType = Unreal::MF_NORMAL_TS;
 284.190 +		}
 284.191 +		d_reader.IncPtr(1);
 284.192 +
 284.193 +		for (unsigned int i = 0; i < 3;++i)
 284.194 +			for (unsigned int i2 = 0; i2 < 2;++i2)
 284.195 +				tri.mTex[i][i2] = d_reader.GetI1();
 284.196 +
 284.197 +		tri.mTextureNum = d_reader.GetI1();
 284.198 +		maxTexIdx = std::max(maxTexIdx,(unsigned int)tri.mTextureNum);
 284.199 +		d_reader.IncPtr(1);
 284.200 +	}
 284.201 +
 284.202 +	p = pIOHandler->Open(a_path);
 284.203 +	if (!p)
 284.204 +		throw DeadlyImportError("UNREAL: Unable to open _a file");
 284.205 +	StreamReaderLE a_reader(pIOHandler->Open(a_path));
 284.206 +
 284.207 +	// read number of frames
 284.208 +	const uint32_t numFrames = a_reader.GetI2();
 284.209 +	if (configFrameID >= numFrames)
 284.210 +		throw DeadlyImportError("UNREAL: The requested frame does not exist");
 284.211 +
 284.212 +	uint32_t st = a_reader.GetI2(); 
 284.213 +	if (st != numVert*4)
 284.214 +		throw DeadlyImportError("UNREAL: Unexpected aniv file length");
 284.215 +
 284.216 +	// skip to our frame
 284.217 +	a_reader.IncPtr(configFrameID *numVert*4);
 284.218 +
 284.219 +	// collect vertices
 284.220 +	std::vector<aiVector3D> vertices(numVert);
 284.221 +	for (std::vector<aiVector3D>::iterator it = vertices.begin(), end = vertices.end(); it != end; ++it)	{
 284.222 +		int32_t val = a_reader.GetI4();
 284.223 +		Unreal::DecompressVertex(*it,val);
 284.224 +	}
 284.225 +
 284.226 +	// list of textures. 
 284.227 +	std::vector< std::pair<unsigned int, std::string> > textures; 
 284.228 +
 284.229 +	// allocate the output scene
 284.230 +	aiNode* nd = pScene->mRootNode = new aiNode();
 284.231 +	nd->mName.Set("<UnrealRoot>");
 284.232 +
 284.233 +	// we can live without the uc file if necessary
 284.234 +	boost::scoped_ptr<IOStream> pb (pIOHandler->Open(uc_path));
 284.235 +	if (pb.get())	{
 284.236 +
 284.237 +		std::vector<char> _data;
 284.238 +		TextFileToBuffer(pb.get(),_data);
 284.239 +		const char* data = &_data[0];
 284.240 +
 284.241 +		std::vector< std::pair< std::string,std::string > > tempTextures;
 284.242 +
 284.243 +		// do a quick search in the UC file for some known, usually texture-related, tags
 284.244 +		for (;*data;++data)	{
 284.245 +			if (TokenMatchI(data,"#exec",5))	{
 284.246 +				SkipSpacesAndLineEnd(&data);
 284.247 +
 284.248 +				// #exec TEXTURE IMPORT [...] NAME=jjjjj [...] FILE=jjjj.pcx [...] 
 284.249 +				if (TokenMatchI(data,"TEXTURE",7))	{
 284.250 +					SkipSpacesAndLineEnd(&data);
 284.251 +
 284.252 +					if (TokenMatchI(data,"IMPORT",6))	{
 284.253 +						tempTextures.push_back(std::pair< std::string,std::string >());
 284.254 +						std::pair< std::string,std::string >& me = tempTextures.back();
 284.255 +						for (;!IsLineEnd(*data);++data)	{
 284.256 +							if (!::ASSIMP_strincmp(data,"NAME=",5))	{
 284.257 +								const char *d = data+=5;
 284.258 +								for (;!IsSpaceOrNewLine(*data);++data);
 284.259 +								me.first = std::string(d,(size_t)(data-d)); 
 284.260 +							}
 284.261 +							else if (!::ASSIMP_strincmp(data,"FILE=",5))	{
 284.262 +								const char *d = data+=5;
 284.263 +								for (;!IsSpaceOrNewLine(*data);++data);
 284.264 +								me.second = std::string(d,(size_t)(data-d)); 
 284.265 +							}
 284.266 +						}
 284.267 +						if (!me.first.length() || !me.second.length())
 284.268 +							tempTextures.pop_back();
 284.269 +					}
 284.270 +				}
 284.271 +				// #exec MESHMAP SETTEXTURE MESHMAP=box NUM=1 TEXTURE=Jtex1
 284.272 +				// #exec MESHMAP SCALE MESHMAP=box X=0.1 Y=0.1 Z=0.2
 284.273 +				else if (TokenMatchI(data,"MESHMAP",7)) {
 284.274 +					SkipSpacesAndLineEnd(&data);
 284.275 +
 284.276 +					if (TokenMatchI(data,"SETTEXTURE",10)) {
 284.277 +					
 284.278 +						textures.push_back(std::pair<unsigned int, std::string>());
 284.279 +						std::pair<unsigned int, std::string>& me = textures.back();
 284.280 +
 284.281 +						for (;!IsLineEnd(*data);++data)	{
 284.282 +							if (!::ASSIMP_strincmp(data,"NUM=",4))	{
 284.283 +								data += 4;
 284.284 +								me.first = strtoul10(data,&data);
 284.285 +							}
 284.286 +							else if (!::ASSIMP_strincmp(data,"TEXTURE=",8))	{
 284.287 +								data += 8;
 284.288 +								const char *d = data;
 284.289 +								for (;!IsSpaceOrNewLine(*data);++data);
 284.290 +								me.second = std::string(d,(size_t)(data-d)); 
 284.291 +					
 284.292 +								// try to find matching path names, doesn't care if we don't find them
 284.293 +								for (std::vector< std::pair< std::string,std::string > >::const_iterator it = tempTextures.begin();
 284.294 +									 it != tempTextures.end(); ++it)	{
 284.295 +									if ((*it).first == me.second)	{
 284.296 +										me.second = (*it).second;
 284.297 +										break;
 284.298 +									}
 284.299 +								}
 284.300 +							}	
 284.301 +						}
 284.302 +					}
 284.303 +					else if (TokenMatchI(data,"SCALE",5)) {
 284.304 +
 284.305 +						for (;!IsLineEnd(*data);++data)	{
 284.306 +							if (data[0] == 'X' && data[1] == '=')	{
 284.307 +								data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.a1);
 284.308 +							}
 284.309 +							else if (data[0] == 'Y' && data[1] == '=')	{
 284.310 +								data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.b2);
 284.311 +							}
 284.312 +							else if (data[0] == 'Z' && data[1] == '=')	{
 284.313 +								data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.c3);
 284.314 +							}
 284.315 +						}
 284.316 +					}
 284.317 +				}
 284.318 +			}
 284.319 +		}
 284.320 +	}
 284.321 +	else	{
 284.322 +		DefaultLogger::get()->error("Unable to open .uc file");
 284.323 +	}
 284.324 +
 284.325 +	std::vector<Unreal::TempMat> materials;
 284.326 +	materials.reserve(textures.size()*2+5);
 284.327 +
 284.328 +	// find out how many output meshes and materials we'll have and build material indices
 284.329 +	for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();it != end; ++it)	{
 284.330 +		Unreal::Triangle& tri = *it;
 284.331 +		Unreal::TempMat mat(tri);
 284.332 +		std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
 284.333 +		if (nt == materials.end()) {
 284.334 +			// add material
 284.335 +			tri.matIndex = materials.size();
 284.336 +			mat.numFaces = 1;
 284.337 +			materials.push_back(mat);
 284.338 +
 284.339 +			++pScene->mNumMeshes;
 284.340 +		}
 284.341 +		else {
 284.342 +			tri.matIndex = static_cast<unsigned int>(nt-materials.begin());
 284.343 +			++nt->numFaces;
 284.344 +		}
 284.345 +	}
 284.346 +
 284.347 +	if (!pScene->mNumMeshes) {
 284.348 +		throw DeadlyImportError("UNREAL: Unable to find valid mesh data");
 284.349 +	}
 284.350 +
 284.351 +	// allocate meshes and bind them to the node graph
 284.352 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
 284.353 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
 284.354 +
 284.355 +	nd->mNumMeshes  = pScene->mNumMeshes;
 284.356 +	nd->mMeshes = new unsigned int[nd->mNumMeshes];
 284.357 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
 284.358 +		aiMesh* m = pScene->mMeshes[i] =  new aiMesh();
 284.359 +		m->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
 284.360 +
 284.361 +		const unsigned int num = materials[i].numFaces;
 284.362 +		m->mFaces            = new aiFace     [num];
 284.363 +		m->mVertices         = new aiVector3D [num*3];
 284.364 +		m->mTextureCoords[0] = new aiVector3D [num*3];
 284.365 +
 284.366 +		nd->mMeshes[i] = i;
 284.367 +
 284.368 +		// create materials, too
 284.369 +		aiMaterial* mat = new aiMaterial();
 284.370 +		pScene->mMaterials[i] = mat;
 284.371 +
 284.372 +		// all white by default - texture rulez
 284.373 +		aiColor3D color(1.f,1.f,1.f);
 284.374 +
 284.375 +		aiString s;
 284.376 +		::sprintf(s.data,"mat%i_tx%i_",i,materials[i].tex);
 284.377 +
 284.378 +		// set the two-sided flag
 284.379 +		if (materials[i].type == Unreal::MF_NORMAL_TS) {
 284.380 +			const int twosided = 1;
 284.381 +			mat->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
 284.382 +			::strcat(s.data,"ts_");
 284.383 +		}
 284.384 +		else ::strcat(s.data,"os_");
 284.385 +
 284.386 +		// make TRANS faces 90% opaque that RemRedundantMaterials won't catch us
 284.387 +		if (materials[i].type == Unreal::MF_NORMAL_TRANS_TS)	{
 284.388 +			const float opac = 0.9f;
 284.389 +			mat->AddProperty(&opac,1,AI_MATKEY_OPACITY);
 284.390 +			::strcat(s.data,"tran_");
 284.391 +		}
 284.392 +		else ::strcat(s.data,"opaq_");
 284.393 +
 284.394 +		// a special name for the weapon attachment point
 284.395 +		if (materials[i].type == Unreal::MF_WEAPON_PLACEHOLDER)	{
 284.396 +			s.length = ::sprintf(s.data,"$WeaponTag$");
 284.397 +			color = aiColor3D(0.f,0.f,0.f);
 284.398 +		}
 284.399 +
 284.400 +		// set color and name
 284.401 +		mat->AddProperty(&color,1,AI_MATKEY_COLOR_DIFFUSE);
 284.402 +		s.length = ::strlen(s.data);
 284.403 +		mat->AddProperty(&s,AI_MATKEY_NAME);
 284.404 +
 284.405 +		// set texture, if any
 284.406 +		const unsigned int tex = materials[i].tex;
 284.407 +		for (std::vector< std::pair< unsigned int, std::string > >::const_iterator it = textures.begin();it != textures.end();++it)	{
 284.408 +			if ((*it).first == tex)	{
 284.409 +				s.Set((*it).second);
 284.410 +				mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
 284.411 +				break;
 284.412 +			}
 284.413 +		}
 284.414 +	}
 284.415 +
 284.416 +	// fill them.
 284.417 +	for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();it != end; ++it)	{
 284.418 +		Unreal::Triangle& tri = *it;
 284.419 +		Unreal::TempMat mat(tri);
 284.420 +		std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
 284.421 +
 284.422 +		aiMesh* mesh = pScene->mMeshes[nt-materials.begin()];
 284.423 +		aiFace& f    = mesh->mFaces[mesh->mNumFaces++];
 284.424 +		f.mIndices   = new unsigned int[f.mNumIndices = 3];
 284.425 +		
 284.426 +		for (unsigned int i = 0; i < 3;++i,mesh->mNumVertices++) {
 284.427 +			f.mIndices[i] = mesh->mNumVertices;
 284.428 +
 284.429 +			mesh->mVertices[mesh->mNumVertices] = vertices[ tri.mVertex[i] ];
 284.430 +			mesh->mTextureCoords[0][mesh->mNumVertices] = aiVector3D( tri.mTex[i][0] / 255.f, 1.f - tri.mTex[i][1] / 255.f, 0.f);
 284.431 +		}
 284.432 +	}
 284.433 +
 284.434 +	// convert to RH
 284.435 +	MakeLeftHandedProcess hero;
 284.436 +	hero.Execute(pScene);
 284.437 +
 284.438 +	FlipWindingOrderProcess flipper;
 284.439 +	flipper.Execute(pScene);
 284.440 +}
 284.441 +
 284.442 +#endif // !! ASSIMP_BUILD_NO_3D_IMPORTER
   285.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   285.2 +++ b/libs/assimp/UnrealLoader.h	Sat Feb 01 19:58:19 2014 +0200
   285.3 @@ -0,0 +1,200 @@
   285.4 +/*
   285.5 +Open Asset Import Library (assimp)
   285.6 +----------------------------------------------------------------------
   285.7 +
   285.8 +Copyright (c) 2006-2012, assimp team
   285.9 +All rights reserved.
  285.10 +
  285.11 +Redistribution and use of this software in source and binary forms, 
  285.12 +with or without modification, are permitted provided that the 
  285.13 +following conditions are met:
  285.14 +
  285.15 +* Redistributions of source code must retain the above
  285.16 +  copyright notice, this list of conditions and the
  285.17 +  following disclaimer.
  285.18 +
  285.19 +* Redistributions in binary form must reproduce the above
  285.20 +  copyright notice, this list of conditions and the
  285.21 +  following disclaimer in the documentation and/or other
  285.22 +  materials provided with the distribution.
  285.23 +
  285.24 +* Neither the name of the assimp team, nor the names of its
  285.25 +  contributors may be used to endorse or promote products
  285.26 +  derived from this software without specific prior
  285.27 +  written permission of the assimp team.
  285.28 +
  285.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  285.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  285.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  285.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  285.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  285.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  285.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  285.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  285.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  285.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  285.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  285.40 +
  285.41 +----------------------------------------------------------------------
  285.42 +*/
  285.43 +
  285.44 +/** @file  UnrealLoader.h
  285.45 + *  @brief Declaration of the .3d (UNREAL) importer class.
  285.46 + */
  285.47 +#ifndef INCLUDED_AI_3D_LOADER_H
  285.48 +#define INCLUDED_AI_3D_LOADER_H
  285.49 +
  285.50 +#include "BaseImporter.h"
  285.51 +namespace Assimp	{
  285.52 +namespace Unreal {
  285.53 +
  285.54 +	/*
  285.55 +	0 = Normal one-sided
  285.56 +	1 = Normal two-sided
  285.57 +	2 = Translucent two-sided
  285.58 +	3 = Masked two-sided
  285.59 +	4 = Modulation blended two-sided
  285.60 +	8 = Placeholder triangle for weapon positioning (invisible)
  285.61 +	*/
  285.62 +enum MeshFlags {
  285.63 +	MF_NORMAL_OS            = 0,
  285.64 +	MF_NORMAL_TS            = 1,
  285.65 +	MF_NORMAL_TRANS_TS      = 2,
  285.66 +	MF_NORMAL_MASKED_TS     = 3,
  285.67 +	MF_NORMAL_MOD_TS        = 4,
  285.68 +	MF_WEAPON_PLACEHOLDER   = 8
  285.69 +};
  285.70 +
  285.71 +	// a single triangle
  285.72 +struct Triangle {
  285.73 +   uint16_t mVertex[3];		  // Vertex indices
  285.74 +   char mType;                // James' Mesh Type
  285.75 +   char mColor;               // Color for flat and Gourand Shaded
  285.76 +   unsigned char mTex[3][2];  // Texture UV coordinates
  285.77 +   unsigned char mTextureNum; // Source texture offset
  285.78 +   char mFlags;               // Unreal Mesh Flags (unused)
  285.79 +  
  285.80 +   unsigned int matIndex;
  285.81 +};
  285.82 +
  285.83 +// temporary representation for a material
  285.84 +struct TempMat	{
  285.85 +	TempMat()
  285.86 +		:	numFaces	(0)
  285.87 +	{}
  285.88 +
  285.89 +	TempMat(const Triangle& in)
  285.90 +		:	type		((Unreal::MeshFlags)in.mType)
  285.91 +		,	tex			(in.mTextureNum)
  285.92 +		,	numFaces	(0)
  285.93 +	{}
  285.94 +
  285.95 +	// type of mesh
  285.96 +	Unreal::MeshFlags type;
  285.97 +
  285.98 +	// index of texture
  285.99 +	unsigned int tex;
 285.100 +
 285.101 +	// number of faces using us
 285.102 +	unsigned int numFaces;
 285.103 +
 285.104 +	// for std::find
 285.105 +	bool operator == (const TempMat& o )	{
 285.106 +		return (tex == o.tex && type == o.type);
 285.107 +	}
 285.108 +};
 285.109 +
 285.110 +struct Vertex
 285.111 +{
 285.112 +	int32_t X : 11;
 285.113 +	int32_t Y : 11;
 285.114 +	int32_t Z : 10;
 285.115 +};
 285.116 +
 285.117 +	// UNREAL vertex compression
 285.118 +inline void CompressVertex(const aiVector3D& v, uint32_t& out)
 285.119 +{
 285.120 +	union {
 285.121 +		Vertex n;
 285.122 +		int32_t t;
 285.123 +	};
 285.124 +	n.X = (int32_t)v.x;
 285.125 +	n.Y = (int32_t)v.y;
 285.126 +	n.Z = (int32_t)v.z;
 285.127 +	out = t;
 285.128 +}
 285.129 +
 285.130 +	// UNREAL vertex decompression
 285.131 +inline void DecompressVertex(aiVector3D& v, int32_t in)
 285.132 +{
 285.133 +	union {
 285.134 +		Vertex n;
 285.135 +		int32_t i;
 285.136 +	}; 
 285.137 +	i = in;
 285.138 +	
 285.139 +	v.x = (float)n.X;
 285.140 +	v.y = (float)n.Y;
 285.141 +	v.z = (float)n.Z;
 285.142 +}
 285.143 +
 285.144 +} // end namespace Unreal
 285.145 +
 285.146 +// ---------------------------------------------------------------------------
 285.147 +/** @brief Importer class to load UNREAL files (*.3d)
 285.148 +*/
 285.149 +class UnrealImporter : public BaseImporter
 285.150 +{
 285.151 +public:
 285.152 +	UnrealImporter();
 285.153 +	~UnrealImporter();
 285.154 +
 285.155 +
 285.156 +public:
 285.157 +
 285.158 +	// -------------------------------------------------------------------
 285.159 +	/** @brief Returns whether we can handle the format of the given file
 285.160 +	 *
 285.161 +	 *  See BaseImporter::CanRead() for details.	
 285.162 +	 **/
 285.163 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
 285.164 +		bool checkSig) const;
 285.165 +
 285.166 +protected:
 285.167 +
 285.168 +	// -------------------------------------------------------------------
 285.169 +	/** @brief Called by Importer::GetExtensionList() 
 285.170 +	 *
 285.171 +	 * See #BaseImporter::GetInfo for the details
 285.172 +	 */
 285.173 +	const aiImporterDesc* GetInfo () const;
 285.174 +
 285.175 +
 285.176 +	// -------------------------------------------------------------------
 285.177 +	/** @brief Setup properties for the importer
 285.178 +	 *
 285.179 +	 * See BaseImporter::SetupProperties() for details
 285.180 +	 */
 285.181 +	void SetupProperties(const Importer* pImp);
 285.182 +
 285.183 +
 285.184 +	// -------------------------------------------------------------------
 285.185 +	/** @brief Imports the given file into the given scene structure. 
 285.186 +	 *
 285.187 +	 * See BaseImporter::InternReadFile() for details
 285.188 +	 */
 285.189 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
 285.190 +		IOSystem* pIOHandler);
 285.191 +
 285.192 +private:
 285.193 +
 285.194 +	//! frame to be loaded
 285.195 +	uint32_t configFrameID;
 285.196 +
 285.197 +	//! process surface flags
 285.198 +	bool configHandleFlags;
 285.199 +
 285.200 +}; // !class UnrealImporter
 285.201 +
 285.202 +} // end of namespace Assimp
 285.203 +#endif // AI_UNREALIMPORTER_H_INC
   286.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   286.2 +++ b/libs/assimp/ValidateDataStructure.cpp	Sat Feb 01 19:58:19 2014 +0200
   286.3 @@ -0,0 +1,968 @@
   286.4 +/*
   286.5 +---------------------------------------------------------------------------
   286.6 +Open Asset Import Library (assimp)
   286.7 +---------------------------------------------------------------------------
   286.8 +
   286.9 +Copyright (c) 2006-2012, assimp team
  286.10 +
  286.11 +All rights reserved.
  286.12 +
  286.13 +Redistribution and use of this software in source and binary forms, 
  286.14 +with or without modification, are permitted provided that the following 
  286.15 +conditions are met:
  286.16 +
  286.17 +* Redistributions of source code must retain the above
  286.18 +  copyright notice, this list of conditions and the
  286.19 +  following disclaimer.
  286.20 +
  286.21 +* Redistributions in binary form must reproduce the above
  286.22 +  copyright notice, this list of conditions and the
  286.23 +  following disclaimer in the documentation and/or other
  286.24 +  materials provided with the distribution.
  286.25 +
  286.26 +* Neither the name of the assimp team, nor the names of its
  286.27 +  contributors may be used to endorse or promote products
  286.28 +  derived from this software without specific prior
  286.29 +  written permission of the assimp team.
  286.30 +
  286.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  286.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  286.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  286.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  286.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  286.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  286.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  286.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  286.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  286.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  286.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  286.42 +---------------------------------------------------------------------------
  286.43 +*/
  286.44 +
  286.45 +/** @file  ValidateDataStructure.cpp
  286.46 + *  @brief Implementation of the post processing step to validate 
  286.47 + *    the data structure returned by Assimp.
  286.48 + */
  286.49 +
  286.50 +#include "AssimpPCH.h"
  286.51 +
  286.52 +// internal headers
  286.53 +#include "ValidateDataStructure.h"
  286.54 +#include "BaseImporter.h"
  286.55 +#include "fast_atof.h"
  286.56 +#include "ProcessHelper.h"
  286.57 +
  286.58 +// CRT headers
  286.59 +#include <stdarg.h>
  286.60 +
  286.61 +using namespace Assimp;
  286.62 +
  286.63 +// ------------------------------------------------------------------------------------------------
  286.64 +// Constructor to be privately used by Importer
  286.65 +ValidateDSProcess::ValidateDSProcess()
  286.66 +{}
  286.67 +
  286.68 +// ------------------------------------------------------------------------------------------------
  286.69 +// Destructor, private as well
  286.70 +ValidateDSProcess::~ValidateDSProcess()
  286.71 +{}
  286.72 +
  286.73 +// ------------------------------------------------------------------------------------------------
  286.74 +// Returns whether the processing step is present in the given flag field.
  286.75 +bool ValidateDSProcess::IsActive( unsigned int pFlags) const
  286.76 +{
  286.77 +	return (pFlags & aiProcess_ValidateDataStructure) != 0;
  286.78 +}
  286.79 +// ------------------------------------------------------------------------------------------------
  286.80 +AI_WONT_RETURN void ValidateDSProcess::ReportError(const char* msg,...)
  286.81 +{
  286.82 +	ai_assert(NULL != msg);
  286.83 +
  286.84 +	va_list args;
  286.85 +	va_start(args,msg);
  286.86 +
  286.87 +	char szBuffer[3000];
  286.88 +	const int iLen = vsprintf(szBuffer,msg,args);
  286.89 +	ai_assert(iLen > 0);
  286.90 +
  286.91 +	va_end(args);
  286.92 +#ifdef _DEBUG
  286.93 +	ai_assert( false );
  286.94 +#endif
  286.95 +	throw DeadlyImportError("Validation failed: " + std::string(szBuffer,iLen));
  286.96 +}
  286.97 +// ------------------------------------------------------------------------------------------------
  286.98 +void ValidateDSProcess::ReportWarning(const char* msg,...)
  286.99 +{
 286.100 +	ai_assert(NULL != msg);
 286.101 +
 286.102 +	va_list args;
 286.103 +	va_start(args,msg);
 286.104 +
 286.105 +	char szBuffer[3000];
 286.106 +	const int iLen = vsprintf(szBuffer,msg,args);
 286.107 +	ai_assert(iLen > 0);
 286.108 +
 286.109 +	va_end(args);
 286.110 +	DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen));
 286.111 +}
 286.112 +
 286.113 +// ------------------------------------------------------------------------------------------------
 286.114 +inline int HasNameMatch(const aiString& in, aiNode* node)
 286.115 +{
 286.116 +	int result = (node->mName == in ? 1 : 0 );
 286.117 +	for (unsigned int i = 0; i < node->mNumChildren;++i)	{
 286.118 +		result += HasNameMatch(in,node->mChildren[i]);
 286.119 +	}
 286.120 +	return result;
 286.121 +}
 286.122 +
 286.123 +// ------------------------------------------------------------------------------------------------
 286.124 +template <typename T>
 286.125 +inline void ValidateDSProcess::DoValidation(T** parray, unsigned int size, 
 286.126 +	const char* firstName, const char* secondName)
 286.127 +{
 286.128 +	// validate all entries
 286.129 +	if (size)
 286.130 +	{
 286.131 +		if (!parray)
 286.132 +		{
 286.133 +			ReportError("aiScene::%s is NULL (aiScene::%s is %i)",
 286.134 +				firstName, secondName, size);
 286.135 +		}
 286.136 +		for (unsigned int i = 0; i < size;++i)
 286.137 +		{
 286.138 +			if (!parray[i])
 286.139 +			{
 286.140 +				ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
 286.141 +					firstName,i,secondName,size);
 286.142 +			}
 286.143 +			Validate(parray[i]);
 286.144 +		}
 286.145 +	}
 286.146 +}
 286.147 +
 286.148 +// ------------------------------------------------------------------------------------------------
 286.149 +template <typename T>
 286.150 +inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size, 
 286.151 +	const char* firstName, const char* secondName)
 286.152 +{
 286.153 +	// validate all entries
 286.154 +	if (size)
 286.155 +	{
 286.156 +		if (!parray)	{
 286.157 +			ReportError("aiScene::%s is NULL (aiScene::%s is %i)",
 286.158 +				firstName, secondName, size);
 286.159 +		}
 286.160 +		for (unsigned int i = 0; i < size;++i)
 286.161 +		{
 286.162 +			if (!parray[i])
 286.163 +			{
 286.164 +				ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
 286.165 +					firstName,i,secondName,size);
 286.166 +			}
 286.167 +			Validate(parray[i]);
 286.168 +
 286.169 +			// check whether there are duplicate names
 286.170 +			for (unsigned int a = i+1; a < size;++a)
 286.171 +			{
 286.172 +				if (parray[i]->mName == parray[a]->mName)
 286.173 +				{
 286.174 +					this->ReportError("aiScene::%s[%i] has the same name as "
 286.175 +						"aiScene::%s[%i]",firstName, i,secondName, a);
 286.176 +				}
 286.177 +			}
 286.178 +		}
 286.179 +	}
 286.180 +}
 286.181 +
 286.182 +// ------------------------------------------------------------------------------------------------
 286.183 +template <typename T>
 286.184 +inline void ValidateDSProcess::DoValidationWithNameCheck(T** array, 
 286.185 +	unsigned int size, const char* firstName, 
 286.186 +	const char* secondName)
 286.187 +{
 286.188 +	// validate all entries
 286.189 +	DoValidationEx(array,size,firstName,secondName);
 286.190 +	
 286.191 +	for (unsigned int i = 0; i < size;++i)
 286.192 +	{
 286.193 +		int res = HasNameMatch(array[i]->mName,mScene->mRootNode);
 286.194 +		if (!res)	{
 286.195 +			ReportError("aiScene::%s[%i] has no corresponding node in the scene graph (%s)",
 286.196 +				firstName,i,array[i]->mName.data);
 286.197 +		}
 286.198 +		else if (1 != res)	{
 286.199 +			ReportError("aiScene::%s[%i]: there are more than one nodes with %s as name",
 286.200 +				firstName,i,array[i]->mName.data);
 286.201 +		}
 286.202 +	}
 286.203 +}
 286.204 +
 286.205 +// ------------------------------------------------------------------------------------------------
 286.206 +// Executes the post processing step on the given imported data.
 286.207 +void ValidateDSProcess::Execute( aiScene* pScene)
 286.208 +{
 286.209 +	this->mScene = pScene;
 286.210 +	DefaultLogger::get()->debug("ValidateDataStructureProcess begin");
 286.211 +	
 286.212 +	// validate the node graph of the scene
 286.213 +	Validate(pScene->mRootNode);
 286.214 +	
 286.215 +	// validate all meshes
 286.216 +	if (pScene->mNumMeshes) {
 286.217 +		DoValidation(pScene->mMeshes,pScene->mNumMeshes,"mMeshes","mNumMeshes");
 286.218 +	}
 286.219 +	else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))	{
 286.220 +		ReportError("aiScene::mNumMeshes is 0. At least one mesh must be there");
 286.221 +	}
 286.222 +	else if (pScene->mMeshes)	{
 286.223 +		ReportError("aiScene::mMeshes is non-null although there are no meshes");
 286.224 +	}
 286.225 +	
 286.226 +	// validate all animations
 286.227 +	if (pScene->mNumAnimations) {
 286.228 +		DoValidation(pScene->mAnimations,pScene->mNumAnimations,
 286.229 +			"mAnimations","mNumAnimations");
 286.230 +	}
 286.231 +	else if (pScene->mAnimations)	{
 286.232 +		ReportError("aiScene::mAnimations is non-null although there are no animations");
 286.233 +	}
 286.234 +
 286.235 +	// validate all cameras
 286.236 +	if (pScene->mNumCameras) {
 286.237 +		DoValidationWithNameCheck(pScene->mCameras,pScene->mNumCameras,
 286.238 +			"mCameras","mNumCameras");
 286.239 +	}
 286.240 +	else if (pScene->mCameras)	{
 286.241 +		ReportError("aiScene::mCameras is non-null although there are no cameras");
 286.242 +	}
 286.243 +
 286.244 +	// validate all lights
 286.245 +	if (pScene->mNumLights) {
 286.246 +		DoValidationWithNameCheck(pScene->mLights,pScene->mNumLights,
 286.247 +			"mLights","mNumLights");
 286.248 +	}
 286.249 +	else if (pScene->mLights)	{
 286.250 +		ReportError("aiScene::mLights is non-null although there are no lights");
 286.251 +	}
 286.252 +
 286.253 +	// validate all textures
 286.254 +	if (pScene->mNumTextures) {
 286.255 +		DoValidation(pScene->mTextures,pScene->mNumTextures,
 286.256 +			"mTextures","mNumTextures");
 286.257 +	}
 286.258 +	else if (pScene->mTextures)	{
 286.259 +		ReportError("aiScene::mTextures is non-null although there are no textures");
 286.260 +	}
 286.261 +	
 286.262 +	// validate all materials
 286.263 +	if (pScene->mNumMaterials) {
 286.264 +		DoValidation(pScene->mMaterials,pScene->mNumMaterials,"mMaterials","mNumMaterials");
 286.265 +	}
 286.266 +#if 0
 286.267 +	// NOTE: ScenePreprocessor generates a default material if none is there
 286.268 +	else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))	{
 286.269 +		ReportError("aiScene::mNumMaterials is 0. At least one material must be there");
 286.270 +	}
 286.271 +#endif
 286.272 +	else if (pScene->mMaterials)	{
 286.273 +		ReportError("aiScene::mMaterials is non-null although there are no materials");
 286.274 +	}
 286.275 +
 286.276 +//	if (!has)ReportError("The aiScene data structure is empty");
 286.277 +	DefaultLogger::get()->debug("ValidateDataStructureProcess end");
 286.278 +}
 286.279 +
 286.280 +// ------------------------------------------------------------------------------------------------
 286.281 +void ValidateDSProcess::Validate( const aiLight* pLight)
 286.282 +{
 286.283 +	if (pLight->mType == aiLightSource_UNDEFINED)
 286.284 +		ReportWarning("aiLight::mType is aiLightSource_UNDEFINED");
 286.285 +
 286.286 +	if (!pLight->mAttenuationConstant &&
 286.287 +		!pLight->mAttenuationLinear   && 
 286.288 +		!pLight->mAttenuationQuadratic)	{
 286.289 +		ReportWarning("aiLight::mAttenuationXXX - all are zero");
 286.290 +	}
 286.291 +
 286.292 +	if (pLight->mAngleInnerCone > pLight->mAngleOuterCone)
 286.293 +		ReportError("aiLight::mAngleInnerCone is larger than aiLight::mAngleOuterCone");
 286.294 +
 286.295 +	if (pLight->mColorDiffuse.IsBlack() && pLight->mColorAmbient.IsBlack() 
 286.296 +		&& pLight->mColorSpecular.IsBlack())
 286.297 +	{
 286.298 +		ReportWarning("aiLight::mColorXXX - all are black and won't have any influence");
 286.299 +	}
 286.300 +}
 286.301 +	
 286.302 +// ------------------------------------------------------------------------------------------------
 286.303 +void ValidateDSProcess::Validate( const aiCamera* pCamera)
 286.304 +{
 286.305 +	if (pCamera->mClipPlaneFar <= pCamera->mClipPlaneNear)
 286.306 +		ReportError("aiCamera::mClipPlaneFar must be >= aiCamera::mClipPlaneNear");
 286.307 +
 286.308 +	// FIX: there are many 3ds files with invalid FOVs. No reason to
 286.309 +	// reject them at all ... a warning is appropriate.
 286.310 +	if (!pCamera->mHorizontalFOV || pCamera->mHorizontalFOV >= (float)AI_MATH_PI)
 286.311 +		ReportWarning("%f is not a valid value for aiCamera::mHorizontalFOV",pCamera->mHorizontalFOV);
 286.312 +}
 286.313 +
 286.314 +// ------------------------------------------------------------------------------------------------
 286.315 +void ValidateDSProcess::Validate( const aiMesh* pMesh)
 286.316 +{
 286.317 +	// validate the material index of the mesh
 286.318 +	if (mScene->mNumMaterials && pMesh->mMaterialIndex >= mScene->mNumMaterials)
 286.319 +	{
 286.320 +		ReportError("aiMesh::mMaterialIndex is invalid (value: %i maximum: %i)",
 286.321 +			pMesh->mMaterialIndex,mScene->mNumMaterials-1);
 286.322 +	}
 286.323 +
 286.324 +	Validate(&pMesh->mName);
 286.325 +
 286.326 +	for (unsigned int i = 0; i < pMesh->mNumFaces; ++i)
 286.327 +	{
 286.328 +		aiFace& face = pMesh->mFaces[i];
 286.329 +
 286.330 +		if (pMesh->mPrimitiveTypes)
 286.331 +		{
 286.332 +			switch (face.mNumIndices)
 286.333 +			{
 286.334 +			case 0:
 286.335 +				ReportError("aiMesh::mFaces[%i].mNumIndices is 0",i);
 286.336 +			case 1:
 286.337 +				if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT))
 286.338 +				{
 286.339 +					ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimtiveTypes "
 286.340 +						"does not report the POINT flag",i);
 286.341 +				}
 286.342 +				break;
 286.343 +			case 2:
 286.344 +				if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE))
 286.345 +				{
 286.346 +					ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimtiveTypes "
 286.347 +						"does not report the LINE flag",i);
 286.348 +				}
 286.349 +				break;
 286.350 +			case 3:
 286.351 +				if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
 286.352 +				{
 286.353 +					ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimtiveTypes "
 286.354 +						"does not report the TRIANGLE flag",i);
 286.355 +				}
 286.356 +				break;
 286.357 +			default:
 286.358 +				if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON))
 286.359 +				{
 286.360 +					this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimtiveTypes "
 286.361 +						"does not report the POLYGON flag",i);
 286.362 +				}
 286.363 +				break;
 286.364 +			};
 286.365 +		}
 286.366 +
 286.367 +		if (!face.mIndices)
 286.368 +			ReportError("aiMesh::mFaces[%i].mIndices is NULL",i);
 286.369 +	}
 286.370 +
 286.371 +	// positions must always be there ...
 286.372 +	if (!pMesh->mNumVertices || (!pMesh->mVertices && !mScene->mFlags))	{
 286.373 +		ReportError("The mesh contains no vertices");
 286.374 +	}
 286.375 +
 286.376 +	if (pMesh->mNumVertices > AI_MAX_VERTICES) {
 286.377 +		ReportError("Mesh has too many vertices: %u, but the limit is %u",pMesh->mNumVertices,AI_MAX_VERTICES);
 286.378 +	}
 286.379 +	if (pMesh->mNumFaces > AI_MAX_FACES) {
 286.380 +		ReportError("Mesh has too many faces: %u, but the limit is %u",pMesh->mNumFaces,AI_MAX_FACES);
 286.381 +	}
 286.382 +
 286.383 +	// if tangents are there there must also be bitangent vectors ...
 286.384 +	if ((pMesh->mTangents != NULL) != (pMesh->mBitangents != NULL))	{
 286.385 +		ReportError("If there are tangents, bitangent vectors must be present as well");
 286.386 +	}
 286.387 +
 286.388 +	// faces, too
 286.389 +	if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags))	{
 286.390 +		ReportError("Mesh contains no faces");
 286.391 +	}
 286.392 +
 286.393 +	// now check whether the face indexing layout is correct:
 286.394 +	// unique vertices, pseudo-indexed.
 286.395 +	std::vector<bool> abRefList;
 286.396 +	abRefList.resize(pMesh->mNumVertices,false);
 286.397 +	for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
 286.398 +	{
 286.399 +		aiFace& face = pMesh->mFaces[i];
 286.400 +		if (face.mNumIndices > AI_MAX_FACE_INDICES) {
 286.401 +			ReportError("Face %u has too many faces: %u, but the limit is %u",i,face.mNumIndices,AI_MAX_FACE_INDICES);
 286.402 +		}
 286.403 +
 286.404 +		for (unsigned int a = 0; a < face.mNumIndices;++a)
 286.405 +		{
 286.406 +			if (face.mIndices[a] >= pMesh->mNumVertices)	{
 286.407 +				ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range",i,a);
 286.408 +			}
 286.409 +			// the MSB flag is temporarily used by the extra verbose
 286.410 +			// mode to tell us that the JoinVerticesProcess might have 
 286.411 +			// been executed already.
 286.412 +			if ( !(this->mScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) && abRefList[face.mIndices[a]])
 286.413 +			{
 286.414 +				ReportError("aiMesh::mVertices[%i] is referenced twice - second "
 286.415 +					"time by aiMesh::mFaces[%i]::mIndices[%i]",face.mIndices[a],i,a);
 286.416 +			}
 286.417 +			abRefList[face.mIndices[a]] = true;
 286.418 +		}
 286.419 +	}
 286.420 +
 286.421 +	// check whether there are vertices that aren't referenced by a face
 286.422 +	bool b = false;
 286.423 +	for (unsigned int i = 0; i < pMesh->mNumVertices;++i)	{
 286.424 +		if (!abRefList[i])b = true;
 286.425 +	}
 286.426 +	abRefList.clear();
 286.427 +	if (b)ReportWarning("There are unreferenced vertices");
 286.428 +
 286.429 +	// texture channel 2 may not be set if channel 1 is zero ...
 286.430 +	{
 286.431 +		unsigned int i = 0;
 286.432 +		for (;i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
 286.433 +		{
 286.434 +			if (!pMesh->HasTextureCoords(i))break;
 286.435 +		}
 286.436 +		for (;i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
 286.437 +			if (pMesh->HasTextureCoords(i))
 286.438 +			{
 286.439 +				ReportError("Texture coordinate channel %i exists "
 286.440 +					"although the previous channel was NULL.",i);
 286.441 +			}
 286.442 +	}
 286.443 +	// the same for the vertex colors
 286.444 +	{
 286.445 +		unsigned int i = 0;
 286.446 +		for (;i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
 286.447 +		{
 286.448 +			if (!pMesh->HasVertexColors(i))break;
 286.449 +		}
 286.450 +		for (;i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
 286.451 +			if (pMesh->HasVertexColors(i))
 286.452 +			{
 286.453 +				ReportError("Vertex color channel %i is exists "
 286.454 +					"although the previous channel was NULL.",i);
 286.455 +			}
 286.456 +	}
 286.457 +
 286.458 +
 286.459 +	// now validate all bones
 286.460 +	if (pMesh->mNumBones)
 286.461 +	{
 286.462 +		if (!pMesh->mBones)
 286.463 +		{
 286.464 +			ReportError("aiMesh::mBones is NULL (aiMesh::mNumBones is %i)",
 286.465 +				pMesh->mNumBones);
 286.466 +		}
 286.467 +		boost::scoped_array<float> afSum(NULL);
 286.468 +		if (pMesh->mNumVertices)
 286.469 +		{
 286.470 +			afSum.reset(new float[pMesh->mNumVertices]);
 286.471 +			for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
 286.472 +				afSum[i] = 0.0f;
 286.473 +		}
 286.474 +
 286.475 +		// check whether there are duplicate bone names
 286.476 +		for (unsigned int i = 0; i < pMesh->mNumBones;++i)
 286.477 +		{
 286.478 +			const aiBone* bone = pMesh->mBones[i];
 286.479 +			if (bone->mNumWeights > AI_MAX_BONE_WEIGHTS) {
 286.480 +				ReportError("Bone %u has too many weights: %u, but the limit is %u",i,bone->mNumWeights,AI_MAX_BONE_WEIGHTS);
 286.481 +			}
 286.482 +
 286.483 +			if (!pMesh->mBones[i])
 286.484 +			{
 286.485 +				ReportError("aiMesh::mBones[%i] is NULL (aiMesh::mNumBones is %i)",
 286.486 +					i,pMesh->mNumBones);
 286.487 +			}
 286.488 +			Validate(pMesh,pMesh->mBones[i],afSum.get());
 286.489 +
 286.490 +			for (unsigned int a = i+1; a < pMesh->mNumBones;++a)
 286.491 +			{
 286.492 +				if (pMesh->mBones[i]->mName == pMesh->mBones[a]->mName)
 286.493 +				{
 286.494 +					ReportError("aiMesh::mBones[%i] has the same name as "
 286.495 +						"aiMesh::mBones[%i]",i,a);
 286.496 +				}
 286.497 +			}
 286.498 +		}
 286.499 +		// check whether all bone weights for a vertex sum to 1.0 ...
 286.500 +		for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
 286.501 +		{
 286.502 +			if (afSum[i] && (afSum[i] <= 0.94 || afSum[i] >= 1.05))	{
 286.503 +				ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)",i,afSum[i]);
 286.504 +			}
 286.505 +		}
 286.506 +	}
 286.507 +	else if (pMesh->mBones)
 286.508 +	{
 286.509 +		ReportError("aiMesh::mBones is non-null although there are no bones");
 286.510 +	}
 286.511 +}
 286.512 +
 286.513 +// ------------------------------------------------------------------------------------------------
 286.514 +void ValidateDSProcess::Validate( const aiMesh* pMesh,
 286.515 +	const aiBone* pBone,float* afSum)
 286.516 +{
 286.517 +	this->Validate(&pBone->mName);
 286.518 +
 286.519 +   	if (!pBone->mNumWeights)	{
 286.520 +		ReportError("aiBone::mNumWeights is zero");
 286.521 +	}
 286.522 +
 286.523 +	// check whether all vertices affected by this bone are valid
 286.524 +	for (unsigned int i = 0; i < pBone->mNumWeights;++i)
 286.525 +	{
 286.526 +		if (pBone->mWeights[i].mVertexId >= pMesh->mNumVertices)	{
 286.527 +			ReportError("aiBone::mWeights[%i].mVertexId is out of range",i);
 286.528 +		}
 286.529 +		else if (!pBone->mWeights[i].mWeight || pBone->mWeights[i].mWeight > 1.0f)	{
 286.530 +			ReportWarning("aiBone::mWeights[%i].mWeight has an invalid value",i);
 286.531 +		}
 286.532 +		afSum[pBone->mWeights[i].mVertexId] += pBone->mWeights[i].mWeight;
 286.533 +	}
 286.534 +}
 286.535 +
 286.536 +// ------------------------------------------------------------------------------------------------
 286.537 +void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
 286.538 +{
 286.539 +	Validate(&pAnimation->mName);
 286.540 +
 286.541 +	// validate all materials
 286.542 +	if (pAnimation->mNumChannels)	
 286.543 +	{
 286.544 +		if (!pAnimation->mChannels)	{
 286.545 +			ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)",
 286.546 +				pAnimation->mNumChannels);
 286.547 +		}
 286.548 +		for (unsigned int i = 0; i < pAnimation->mNumChannels;++i)
 286.549 +		{
 286.550 +			if (!pAnimation->mChannels[i])
 286.551 +			{
 286.552 +				ReportError("aiAnimation::mChannels[%i] is NULL (aiAnimation::mNumChannels is %i)",
 286.553 +					i, pAnimation->mNumChannels);
 286.554 +			}
 286.555 +			Validate(pAnimation, pAnimation->mChannels[i]);
 286.556 +		}
 286.557 +	}
 286.558 +	else ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
 286.559 +
 286.560 +	// Animation duration is allowed to be zero in cases where the anim contains only a single key frame.
 286.561 +	// if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
 286.562 +}
 286.563 +
 286.564 +// ------------------------------------------------------------------------------------------------
 286.565 +void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial* pMaterial,
 286.566 +	aiTextureType type)
 286.567 +{
 286.568 +	const char* szType = TextureTypeToString(type);
 286.569 +
 286.570 +	// ****************************************************************************
 286.571 +	// Search all keys of the material ...
 286.572 +	// textures must be specified with ascending indices 
 286.573 +	// (e.g. diffuse #2 may not be specified if diffuse #1 is not there ...)
 286.574 +	// ****************************************************************************
 286.575 +
 286.576 +	int iNumIndices = 0;
 286.577 +	int iIndex = -1;
 286.578 +	for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
 286.579 +	{
 286.580 +		aiMaterialProperty* prop = pMaterial->mProperties[i];
 286.581 +		if (!::strcmp(prop->mKey.data,"$tex.file") && prop->mSemantic == type)	{
 286.582 +			iIndex = std::max(iIndex, (int) prop->mIndex);
 286.583 +			++iNumIndices;
 286.584 +
 286.585 +			if (aiPTI_String != prop->mType)
 286.586 +				ReportError("Material property %s is expected to be a string",prop->mKey.data);
 286.587 +		}
 286.588 +	}
 286.589 +	if (iIndex +1 != iNumIndices)	{
 286.590 +		ReportError("%s #%i is set, but there are only %i %s textures",
 286.591 +			szType,iIndex,iNumIndices,szType);
 286.592 +	}
 286.593 +	if (!iNumIndices)return;
 286.594 +	std::vector<aiTextureMapping> mappings(iNumIndices);
 286.595 +
 286.596 +	// Now check whether all UV indices are valid ...
 286.597 +	bool bNoSpecified = true;
 286.598 +	for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
 286.599 +	{
 286.600 +		aiMaterialProperty* prop = pMaterial->mProperties[i];
 286.601 +		if (prop->mSemantic != type)continue;
 286.602 +
 286.603 +		if ((int)prop->mIndex >= iNumIndices)
 286.604 +		{
 286.605 +			ReportError("Found texture property with index %i, although there "
 286.606 +				"are only %i textures of type %s",
 286.607 +				prop->mIndex, iNumIndices, szType);
 286.608 +		}
 286.609 +			
 286.610 +		if (!::strcmp(prop->mKey.data,"$tex.mapping"))	{
 286.611 +			if (aiPTI_Integer != prop->mType || prop->mDataLength < sizeof(aiTextureMapping))
 286.612 +			{
 286.613 +				ReportError("Material property %s%i is expected to be an integer (size is %i)",
 286.614 +					prop->mKey.data,prop->mIndex,prop->mDataLength);
 286.615 +			}
 286.616 +			mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData);
 286.617 +		}
 286.618 +		else if (!::strcmp(prop->mKey.data,"$tex.uvtrafo"))	{
 286.619 +			if (aiPTI_Float != prop->mType || prop->mDataLength < sizeof(aiUVTransform))
 286.620 +			{
 286.621 +				ReportError("Material property %s%i is expected to be 5 floats large (size is %i)",
 286.622 +					prop->mKey.data,prop->mIndex, prop->mDataLength);
 286.623 +			}
 286.624 +			mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData);
 286.625 +		}
 286.626 +		else if (!::strcmp(prop->mKey.data,"$tex.uvwsrc")) {
 286.627 +			if (aiPTI_Integer != prop->mType || sizeof(int) > prop->mDataLength)
 286.628 +			{
 286.629 +				ReportError("Material property %s%i is expected to be an integer (size is %i)",
 286.630 +					prop->mKey.data,prop->mIndex,prop->mDataLength);
 286.631 +			}
 286.632 +			bNoSpecified = false;
 286.633 +
 286.634 +			// Ignore UV indices for texture channels that are not there ...
 286.635 +
 286.636 +			// Get the value
 286.637 +			iIndex = *((unsigned int*)prop->mData);
 286.638 +
 286.639 +			// Check whether there is a mesh using this material
 286.640 +			// which has not enough UV channels ...
 286.641 +			for (unsigned int a = 0; a < mScene->mNumMeshes;++a)
 286.642 +			{
 286.643 +				aiMesh* mesh = this->mScene->mMeshes[a];
 286.644 +				if(mesh->mMaterialIndex == (unsigned int)i)
 286.645 +				{
 286.646 +					int iChannels = 0;
 286.647 +					while (mesh->HasTextureCoords(iChannels))++iChannels;
 286.648 +					if (iIndex >= iChannels)
 286.649 +					{
 286.650 +						ReportWarning("Invalid UV index: %i (key %s). Mesh %i has only %i UV channels",
 286.651 +							iIndex,prop->mKey.data,a,iChannels);
 286.652 +					}
 286.653 +				}
 286.654 +			}
 286.655 +		}
 286.656 +	}
 286.657 +	if (bNoSpecified)
 286.658 +	{
 286.659 +		// Assume that all textures are using the first UV channel
 286.660 +		for (unsigned int a = 0; a < mScene->mNumMeshes;++a)
 286.661 +		{
 286.662 +			aiMesh* mesh = mScene->mMeshes[a];
 286.663 +			if(mesh->mMaterialIndex == (unsigned int)iIndex && mappings[0] == aiTextureMapping_UV)
 286.664 +			{
 286.665 +				if (!mesh->mTextureCoords[0])
 286.666 +				{
 286.667 +					// This is a special case ... it could be that the
 286.668 +					// original mesh format intended the use of a special
 286.669 +					// mapping here.
 286.670 +					ReportWarning("UV-mapped texture, but there are no UV coords");
 286.671 +				}
 286.672 +			}
 286.673 +		}
 286.674 +	}
 286.675 +}
 286.676 +// ------------------------------------------------------------------------------------------------
 286.677 +void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
 286.678 +{
 286.679 +	// check whether there are material keys that are obviously not legal
 286.680 +	for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
 286.681 +	{
 286.682 +		const aiMaterialProperty* prop = pMaterial->mProperties[i];
 286.683 +		if (!prop)	{
 286.684 +			ReportError("aiMaterial::mProperties[%i] is NULL (aiMaterial::mNumProperties is %i)",
 286.685 +				i,pMaterial->mNumProperties);
 286.686 +		}
 286.687 +		if (!prop->mDataLength || !prop->mData)	{
 286.688 +			ReportError("aiMaterial::mProperties[%i].mDataLength or "
 286.689 +				"aiMaterial::mProperties[%i].mData is 0",i,i);
 286.690 +		}
 286.691 +		// check all predefined types
 286.692 +		if (aiPTI_String == prop->mType)	{
 286.693 +			// FIX: strings are now stored in a less expensive way, but we can't use the
 286.694 +			// validation routine for 'normal' aiStrings
 286.695 +			uint32_t len;
 286.696 +			if (prop->mDataLength < 5 || prop->mDataLength < 4 + (len=*reinterpret_cast<uint32_t*>(prop->mData)) + 1)	{
 286.697 +				ReportError("aiMaterial::mProperties[%i].mDataLength is "
 286.698 +					"too small to contain a string (%i, needed: %i)",
 286.699 +					i,prop->mDataLength,sizeof(aiString));
 286.700 +			}
 286.701 +			if(prop->mData[prop->mDataLength-1]) {
 286.702 +				ReportError("Missing null-terminator in string material property");
 286.703 +			}
 286.704 +		//	Validate((const aiString*)prop->mData);
 286.705 +		}
 286.706 +		else if (aiPTI_Float == prop->mType)	{
 286.707 +			if (prop->mDataLength < sizeof(float))	{
 286.708 +				ReportError("aiMaterial::mProperties[%i].mDataLength is "
 286.709 +					"too small to contain a float (%i, needed: %i)",
 286.710 +					i,prop->mDataLength,sizeof(float));
 286.711 +			}
 286.712 +		}
 286.713 +		else if (aiPTI_Integer == prop->mType)	{
 286.714 +			if (prop->mDataLength < sizeof(int))	{
 286.715 +				ReportError("aiMaterial::mProperties[%i].mDataLength is "
 286.716 +					"too small to contain an integer (%i, needed: %i)",
 286.717 +					i,prop->mDataLength,sizeof(int));
 286.718 +			}
 286.719 +		}
 286.720 +		// TODO: check whether there is a key with an unknown name ...
 286.721 +	}
 286.722 +
 286.723 +	// make some more specific tests 
 286.724 +	float fTemp;
 286.725 +	int iShading;
 286.726 +	if (AI_SUCCESS == aiGetMaterialInteger( pMaterial,AI_MATKEY_SHADING_MODEL,&iShading))	{
 286.727 +		switch ((aiShadingMode)iShading)
 286.728 +		{
 286.729 +		case aiShadingMode_Blinn:
 286.730 +		case aiShadingMode_CookTorrance:
 286.731 +		case aiShadingMode_Phong:
 286.732 +
 286.733 +			if (AI_SUCCESS != aiGetMaterialFloat(pMaterial,AI_MATKEY_SHININESS,&fTemp))	{
 286.734 +				ReportWarning("A specular shading model is specified but there is no "
 286.735 +					"AI_MATKEY_SHININESS key");
 286.736 +			}
 286.737 +			if (AI_SUCCESS == aiGetMaterialFloat(pMaterial,AI_MATKEY_SHININESS_STRENGTH,&fTemp) && !fTemp)	{
 286.738 +				ReportWarning("A specular shading model is specified but the value of the "
 286.739 +					"AI_MATKEY_SHININESS_STRENGTH key is 0.0");
 286.740 +			}
 286.741 +			break;
 286.742 +		default: ;
 286.743 +		};
 286.744 +	}
 286.745 +
 286.746 +	if (AI_SUCCESS == aiGetMaterialFloat( pMaterial,AI_MATKEY_OPACITY,&fTemp) && (!fTemp || fTemp > 1.01f))	{
 286.747 +		ReportWarning("Invalid opacity value (must be 0 < opacity < 1.0)");
 286.748 +	}
 286.749 +
 286.750 +	// Check whether there are invalid texture keys
 286.751 +	// TODO: that's a relict of the past, where texture type and index were baked
 286.752 +	// into the material string ... we could do that in one single pass.
 286.753 +	SearchForInvalidTextures(pMaterial,aiTextureType_DIFFUSE);
 286.754 +	SearchForInvalidTextures(pMaterial,aiTextureType_SPECULAR);
 286.755 +	SearchForInvalidTextures(pMaterial,aiTextureType_AMBIENT);
 286.756 +	SearchForInvalidTextures(pMaterial,aiTextureType_EMISSIVE);
 286.757 +	SearchForInvalidTextures(pMaterial,aiTextureType_OPACITY);
 286.758 +	SearchForInvalidTextures(pMaterial,aiTextureType_SHININESS);
 286.759 +	SearchForInvalidTextures(pMaterial,aiTextureType_HEIGHT);
 286.760 +	SearchForInvalidTextures(pMaterial,aiTextureType_NORMALS);
 286.761 +	SearchForInvalidTextures(pMaterial,aiTextureType_DISPLACEMENT);
 286.762 +	SearchForInvalidTextures(pMaterial,aiTextureType_LIGHTMAP);
 286.763 +	SearchForInvalidTextures(pMaterial,aiTextureType_REFLECTION);
 286.764 +}
 286.765 +
 286.766 +// ------------------------------------------------------------------------------------------------
 286.767 +void ValidateDSProcess::Validate( const aiTexture* pTexture)
 286.768 +{
 286.769 +	// the data section may NEVER be NULL
 286.770 +	if (!pTexture->pcData)	{
 286.771 +		ReportError("aiTexture::pcData is NULL");
 286.772 +	}
 286.773 +	if (pTexture->mHeight)
 286.774 +	{
 286.775 +		if (!pTexture->mWidth)ReportError("aiTexture::mWidth is zero "
 286.776 +			"(aiTexture::mHeight is %i, uncompressed texture)",pTexture->mHeight);
 286.777 +	}
 286.778 +	else 
 286.779 +	{
 286.780 +		if (!pTexture->mWidth) {
 286.781 +			ReportError("aiTexture::mWidth is zero (compressed texture)");
 286.782 +		}
 286.783 +		if ('\0' != pTexture->achFormatHint[3]) {
 286.784 +			ReportWarning("aiTexture::achFormatHint must be zero-terminated");
 286.785 +		}
 286.786 +		else if ('.'  == pTexture->achFormatHint[0])	{
 286.787 +			ReportWarning("aiTexture::achFormatHint should contain a file extension "
 286.788 +				"without a leading dot (format hint: %s).",pTexture->achFormatHint);
 286.789 +		}
 286.790 +	}
 286.791 +
 286.792 +	const char* sz = pTexture->achFormatHint;
 286.793 + 	if ((sz[0] >= 'A' && sz[0] <= 'Z') ||
 286.794 +		(sz[1] >= 'A' && sz[1] <= 'Z') ||
 286.795 +		(sz[2] >= 'A' && sz[2] <= 'Z') ||
 286.796 +		(sz[3] >= 'A' && sz[3] <= 'Z'))	{
 286.797 +		ReportError("aiTexture::achFormatHint contains non-lowercase letters");
 286.798 +	}
 286.799 +}
 286.800 +
 286.801 +// ------------------------------------------------------------------------------------------------
 286.802 +void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
 286.803 +	 const aiNodeAnim* pNodeAnim)
 286.804 +{
 286.805 +	Validate(&pNodeAnim->mNodeName);
 286.806 +
 286.807 +	if (!pNodeAnim->mNumPositionKeys && !pNodeAnim->mScalingKeys && !pNodeAnim->mNumRotationKeys)
 286.808 +		ReportError("Empty node animation channel");
 286.809 +
 286.810 +	// otherwise check whether one of the keys exceeds the total duration of the animation
 286.811 +	if (pNodeAnim->mNumPositionKeys)
 286.812 +	{
 286.813 +		if (!pNodeAnim->mPositionKeys)
 286.814 +		{
 286.815 +			this->ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)",
 286.816 +				pNodeAnim->mNumPositionKeys);
 286.817 +		}
 286.818 +		double dLast = -10e10;
 286.819 +		for (unsigned int i = 0; i < pNodeAnim->mNumPositionKeys;++i)
 286.820 +		{
 286.821 +			// ScenePreprocessor will compute the duration if still the default value
 286.822 +			// (Aramis) Add small epsilon, comparison tended to fail if max_time == duration,
 286.823 +			//  seems to be due the compilers register usage/width.
 286.824 +			if (pAnimation->mDuration > 0. && pNodeAnim->mPositionKeys[i].mTime > pAnimation->mDuration+0.001)
 286.825 +			{
 286.826 +				ReportError("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is larger "
 286.827 +					"than aiAnimation::mDuration (which is %.5f)",i,
 286.828 +					(float)pNodeAnim->mPositionKeys[i].mTime,
 286.829 +					(float)pAnimation->mDuration);
 286.830 +			}
 286.831 +			if (i && pNodeAnim->mPositionKeys[i].mTime <= dLast)
 286.832 +			{
 286.833 +				ReportWarning("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is smaller "
 286.834 +					"than aiAnimation::mPositionKeys[%i] (which is %.5f)",i,
 286.835 +					(float)pNodeAnim->mPositionKeys[i].mTime,
 286.836 +					i-1, (float)dLast);
 286.837 +			}
 286.838 +			dLast = pNodeAnim->mPositionKeys[i].mTime;
 286.839 +		}
 286.840 +	}
 286.841 +	// rotation keys
 286.842 +	if (pNodeAnim->mNumRotationKeys)
 286.843 +	{
 286.844 +		if (!pNodeAnim->mRotationKeys)
 286.845 +		{
 286.846 +			this->ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)",
 286.847 +				pNodeAnim->mNumRotationKeys);
 286.848 +		}
 286.849 +		double dLast = -10e10;
 286.850 +		for (unsigned int i = 0; i < pNodeAnim->mNumRotationKeys;++i)
 286.851 +		{
 286.852 +			if (pAnimation->mDuration > 0. && pNodeAnim->mRotationKeys[i].mTime > pAnimation->mDuration+0.001)
 286.853 +			{
 286.854 +				ReportError("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is larger "
 286.855 +					"than aiAnimation::mDuration (which is %.5f)",i,
 286.856 +					(float)pNodeAnim->mRotationKeys[i].mTime,
 286.857 +					(float)pAnimation->mDuration);
 286.858 +			}
 286.859 +			if (i && pNodeAnim->mRotationKeys[i].mTime <= dLast)
 286.860 +			{
 286.861 +				ReportWarning("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is smaller "
 286.862 +					"than aiAnimation::mRotationKeys[%i] (which is %.5f)",i,
 286.863 +					(float)pNodeAnim->mRotationKeys[i].mTime,
 286.864 +					i-1, (float)dLast);
 286.865 +			}
 286.866 +			dLast = pNodeAnim->mRotationKeys[i].mTime;
 286.867 +		}
 286.868 +	}
 286.869 +	// scaling keys
 286.870 +	if (pNodeAnim->mNumScalingKeys)
 286.871 +	{
 286.872 +		if (!pNodeAnim->mScalingKeys)	{
 286.873 +			ReportError("aiNodeAnim::mScalingKeys is NULL (aiNodeAnim::mNumScalingKeys is %i)",
 286.874 +				pNodeAnim->mNumScalingKeys);
 286.875 +		}
 286.876 +		double dLast = -10e10;
 286.877 +		for (unsigned int i = 0; i < pNodeAnim->mNumScalingKeys;++i)
 286.878 +		{
 286.879 +			if (pAnimation->mDuration > 0. && pNodeAnim->mScalingKeys[i].mTime > pAnimation->mDuration+0.001)
 286.880 +			{
 286.881 +				ReportError("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is larger "
 286.882 +					"than aiAnimation::mDuration (which is %.5f)",i,
 286.883 +					(float)pNodeAnim->mScalingKeys[i].mTime,
 286.884 +					(float)pAnimation->mDuration);
 286.885 +			}
 286.886 +			if (i && pNodeAnim->mScalingKeys[i].mTime <= dLast)
 286.887 +			{
 286.888 +				ReportWarning("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is smaller "
 286.889 +					"than aiAnimation::mScalingKeys[%i] (which is %.5f)",i,
 286.890 +					(float)pNodeAnim->mScalingKeys[i].mTime,
 286.891 +					i-1, (float)dLast);
 286.892 +			}
 286.893 +			dLast = pNodeAnim->mScalingKeys[i].mTime;
 286.894 +		}
 286.895 +	}
 286.896 +
 286.897 +	if (!pNodeAnim->mNumScalingKeys && !pNodeAnim->mNumRotationKeys &&
 286.898 +		!pNodeAnim->mNumPositionKeys)
 286.899 +	{
 286.900 +		ReportError("A node animation channel must have at least one subtrack");
 286.901 +	}
 286.902 +}
 286.903 +
 286.904 +// ------------------------------------------------------------------------------------------------
 286.905 +void ValidateDSProcess::Validate( const aiNode* pNode)
 286.906 +{
 286.907 +	if (!pNode)ReportError("A node of the scenegraph is NULL");
 286.908 +	if (pNode != mScene->mRootNode && !pNode->mParent)
 286.909 +		this->ReportError("A node has no valid parent (aiNode::mParent is NULL)");
 286.910 +
 286.911 +	this->Validate(&pNode->mName);
 286.912 +
 286.913 +	// validate all meshes
 286.914 +	if (pNode->mNumMeshes)
 286.915 +	{
 286.916 +		if (!pNode->mMeshes)
 286.917 +		{
 286.918 +			ReportError("aiNode::mMeshes is NULL (aiNode::mNumMeshes is %i)",
 286.919 +				pNode->mNumMeshes);
 286.920 +		}
 286.921 +		std::vector<bool> abHadMesh;
 286.922 +		abHadMesh.resize(mScene->mNumMeshes,false);
 286.923 +		for (unsigned int i = 0; i < pNode->mNumMeshes;++i)
 286.924 +		{
 286.925 +			if (pNode->mMeshes[i] >= mScene->mNumMeshes)
 286.926 +			{
 286.927 +				ReportError("aiNode::mMeshes[%i] is out of range (maximum is %i)",
 286.928 +					pNode->mMeshes[i],mScene->mNumMeshes-1);
 286.929 +			}
 286.930 +			if (abHadMesh[pNode->mMeshes[i]])
 286.931 +			{
 286.932 +				ReportError("aiNode::mMeshes[%i] is already referenced by this node (value: %i)",
 286.933 +					i,pNode->mMeshes[i]);
 286.934 +			}
 286.935 +			abHadMesh[pNode->mMeshes[i]] = true;
 286.936 +		}
 286.937 +	}
 286.938 +	if (pNode->mNumChildren)
 286.939 +	{
 286.940 +		if (!pNode->mChildren)	{
 286.941 +			ReportError("aiNode::mChildren is NULL (aiNode::mNumChildren is %i)",
 286.942 +				pNode->mNumChildren);
 286.943 +		}
 286.944 +		for (unsigned int i = 0; i < pNode->mNumChildren;++i)	{
 286.945 +			Validate(pNode->mChildren[i]);
 286.946 +		}
 286.947 +	}
 286.948 +}
 286.949 +
 286.950 +// ------------------------------------------------------------------------------------------------
 286.951 +void ValidateDSProcess::Validate( const aiString* pString)
 286.952 +{
 286.953 +	if (pString->length > MAXLEN)
 286.954 +	{
 286.955 +		this->ReportError("aiString::length is too large (%i, maximum is %i)",
 286.956 +			pString->length,MAXLEN);
 286.957 +	}
 286.958 +	const char* sz = pString->data;
 286.959 +	while (true)
 286.960 +	{
 286.961 +		if ('\0' == *sz)
 286.962 +		{
 286.963 +			if (pString->length != (unsigned int)(sz-pString->data))
 286.964 +				ReportError("aiString::data is invalid: the terminal zero is at a wrong offset");
 286.965 +			break;
 286.966 +		}
 286.967 +		else if (sz >= &pString->data[MAXLEN])
 286.968 +			ReportError("aiString::data is invalid. There is no terminal character");
 286.969 +		++sz;
 286.970 +	}
 286.971 +}
   287.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   287.2 +++ b/libs/assimp/ValidateDataStructure.h	Sat Feb 01 19:58:19 2014 +0200
   287.3 @@ -0,0 +1,183 @@
   287.4 +/*
   287.5 +Open Asset Import Library (assimp)
   287.6 +----------------------------------------------------------------------
   287.7 +
   287.8 +Copyright (c) 2006-2012, assimp team
   287.9 +All rights reserved.
  287.10 +
  287.11 +Redistribution and use of this software in source and binary forms, 
  287.12 +with or without modification, are permitted provided that the 
  287.13 +following conditions are met:
  287.14 +
  287.15 +* Redistributions of source code must retain the above
  287.16 +  copyright notice, this list of conditions and the
  287.17 +  following disclaimer.
  287.18 +
  287.19 +* Redistributions in binary form must reproduce the above
  287.20 +  copyright notice, this list of conditions and the
  287.21 +  following disclaimer in the documentation and/or other
  287.22 +  materials provided with the distribution.
  287.23 +
  287.24 +* Neither the name of the assimp team, nor the names of its
  287.25 +  contributors may be used to endorse or promote products
  287.26 +  derived from this software without specific prior
  287.27 +  written permission of the assimp team.
  287.28 +
  287.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  287.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  287.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  287.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  287.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  287.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  287.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  287.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  287.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  287.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  287.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  287.40 +
  287.41 +----------------------------------------------------------------------
  287.42 +*/
  287.43 +
  287.44 +/** @file Defines a (dummy) post processing step to validate the loader's
  287.45 + * output data structure (for debugging)
  287.46 + */
  287.47 +#ifndef AI_VALIDATEPROCESS_H_INC
  287.48 +#define AI_VALIDATEPROCESS_H_INC
  287.49 +
  287.50 +#include "assimp/types.h"
  287.51 +#include "BaseProcess.h"
  287.52 +
  287.53 +struct aiBone;
  287.54 +struct aiMesh;
  287.55 +struct aiAnimation;
  287.56 +struct aiNodeAnim;
  287.57 +struct aiTexture;
  287.58 +struct aiMaterial;
  287.59 +struct aiNode;
  287.60 +struct aiString;
  287.61 +
  287.62 +namespace Assimp	{
  287.63 +
  287.64 +// --------------------------------------------------------------------------------------
  287.65 +/** Validates the whole ASSIMP scene data structure for correctness.
  287.66 + *  ImportErrorException is thrown of the scene is corrupt.*/
  287.67 +// --------------------------------------------------------------------------------------
  287.68 +class ValidateDSProcess : public BaseProcess
  287.69 +{
  287.70 +public:
  287.71 +
  287.72 +	ValidateDSProcess();
  287.73 +	~ValidateDSProcess();
  287.74 +
  287.75 +public:
  287.76 +	// -------------------------------------------------------------------
  287.77 +	bool IsActive( unsigned int pFlags) const;
  287.78 +
  287.79 +	// -------------------------------------------------------------------
  287.80 +	void Execute( aiScene* pScene);
  287.81 +
  287.82 +protected:
  287.83 +
  287.84 +	// -------------------------------------------------------------------
  287.85 +	/** Report a validation error. This will throw an exception,
  287.86 +	 *  control won't return.
  287.87 +	 * @param msg Format string for sprintf().*/
  287.88 +	AI_WONT_RETURN void ReportError(const char* msg,...);
  287.89 +
  287.90 +
  287.91 +	// -------------------------------------------------------------------
  287.92 +	/** Report a validation warning. This won't throw an exception,
  287.93 +	 *  control will return to the callera.
  287.94 +	 * @param msg Format string for sprintf().*/
  287.95 +	void ReportWarning(const char* msg,...);
  287.96 +
  287.97 +
  287.98 +	// -------------------------------------------------------------------
  287.99 +	/** Validates a mesh
 287.100 +	 * @param pMesh Input mesh*/
 287.101 +	void Validate( const aiMesh* pMesh);
 287.102 +
 287.103 +	// -------------------------------------------------------------------
 287.104 +	/** Validates a bone
 287.105 +	 * @param pMesh Input mesh
 287.106 +	 * @param pBone Input bone*/
 287.107 +	void Validate( const aiMesh* pMesh,const aiBone* pBone,float* afSum);
 287.108 +
 287.109 +	// -------------------------------------------------------------------
 287.110 +	/** Validates an animation
 287.111 +	 * @param pAnimation Input animation*/
 287.112 +	void Validate( const aiAnimation* pAnimation);
 287.113 +
 287.114 +	// -------------------------------------------------------------------
 287.115 +	/** Validates a material
 287.116 +	 * @param pMaterial Input material*/
 287.117 +	void Validate( const aiMaterial* pMaterial);
 287.118 +
 287.119 +	// -------------------------------------------------------------------
 287.120 +	/** Search the material data structure for invalid or corrupt
 287.121 +	 *  texture keys.
 287.122 +	 * @param pMaterial Input material
 287.123 +	 * @param type Type of the texture*/
 287.124 +	void SearchForInvalidTextures(const aiMaterial* pMaterial,
 287.125 +		aiTextureType type);
 287.126 +
 287.127 +	// -------------------------------------------------------------------
 287.128 +	/** Validates a texture
 287.129 +	 * @param pTexture Input texture*/
 287.130 +	void Validate( const aiTexture* pTexture);
 287.131 +	
 287.132 +	// -------------------------------------------------------------------
 287.133 +	/** Validates a light source
 287.134 +	 * @param pLight Input light
 287.135 +	 */
 287.136 +	void Validate( const aiLight* pLight);
 287.137 +	
 287.138 +	// -------------------------------------------------------------------
 287.139 +	/** Validates a camera
 287.140 +	 * @param pCamera Input camera*/
 287.141 +	void Validate( const aiCamera* pCamera);
 287.142 +
 287.143 +	// -------------------------------------------------------------------
 287.144 +	/** Validates a bone animation channel
 287.145 +	 * @param pAnimation Animation channel.
 287.146 +	 * @param pBoneAnim Input bone animation */
 287.147 +	void Validate( const aiAnimation* pAnimation,
 287.148 +		const aiNodeAnim* pBoneAnim);
 287.149 +
 287.150 +	// -------------------------------------------------------------------
 287.151 +	/** Validates a node and all of its subnodes
 287.152 +	 * @param Node Input node*/
 287.153 +	void Validate( const aiNode* pNode);
 287.154 +
 287.155 +	// -------------------------------------------------------------------
 287.156 +	/** Validates a string
 287.157 +	 * @param pString Input string*/
 287.158 +	void Validate( const aiString* pString);
 287.159 +
 287.160 +private:
 287.161 +
 287.162 +	// template to validate one of the aiScene::mXXX arrays
 287.163 +	template <typename T>
 287.164 +	inline void DoValidation(T** array, unsigned int size, 
 287.165 +		const char* firstName, const char* secondName);
 287.166 +
 287.167 +	// extended version: checks whethr T::mName occurs twice
 287.168 +	template <typename T>
 287.169 +	inline void DoValidationEx(T** array, unsigned int size, 
 287.170 +		const char* firstName, const char* secondName);
 287.171 +		
 287.172 +	// extension to the first template which does also search
 287.173 +	// the nodegraph for an item with the same name
 287.174 +	template <typename T>
 287.175 +	inline void DoValidationWithNameCheck(T** array, unsigned int size, 
 287.176 +		const char* firstName, const char* secondName);
 287.177 +
 287.178 +	aiScene* mScene;
 287.179 +};
 287.180 +
 287.181 +
 287.182 +
 287.183 +
 287.184 +} // end of namespace Assimp
 287.185 +
 287.186 +#endif // AI_VALIDATEPROCESS_H_INC
   288.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   288.2 +++ b/libs/assimp/Vertex.h	Sat Feb 01 19:58:19 2014 +0200
   288.3 @@ -0,0 +1,319 @@
   288.4 +/*
   288.5 +Open Asset Import Library (assimp)
   288.6 +----------------------------------------------------------------------
   288.7 +
   288.8 +Copyright (c) 2006-2012, assimp team
   288.9 +All rights reserved.
  288.10 +
  288.11 +Redistribution and use of this software in source and binary forms, 
  288.12 +with or without modification, are permitted provided that the 
  288.13 +following conditions are met:
  288.14 +
  288.15 +* Redistributions of source code must retain the above
  288.16 +  copyright notice, this list of conditions and the
  288.17 +  following disclaimer.
  288.18 +
  288.19 +* Redistributions in binary form must reproduce the above
  288.20 +  copyright notice, this list of conditions and the
  288.21 +  following disclaimer in the documentation and/or other
  288.22 +  materials provided with the distribution.
  288.23 +
  288.24 +* Neither the name of the assimp team, nor the names of its
  288.25 +  contributors may be used to endorse or promote products
  288.26 +  derived from this software without specific prior
  288.27 +  written permission of the assimp team.
  288.28 +
  288.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  288.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  288.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  288.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  288.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  288.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  288.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  288.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  288.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  288.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  288.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  288.40 +
  288.41 +----------------------------------------------------------------------
  288.42 +*/
  288.43 +/** @file Defines a helper class to represent an interleaved vertex
  288.44 +  along with arithmetic operations to support vertex operations
  288.45 +  such as subdivision, smoothing etc.
  288.46 +  
  288.47 +  While the code is kept as general as possible, arithmetic operations
  288.48 +  that are not currently well-defined (and would cause compile errors
  288.49 +  due to missing operators in the math library), are commented.
  288.50 +  */
  288.51 +#ifndef AI_VERTEX_H_INC
  288.52 +#define AI_VERTEX_H_INC
  288.53 +
  288.54 +#include <functional>
  288.55 +
  288.56 +namespace Assimp	{
  288.57 +	
  288.58 +	///////////////////////////////////////////////////////////////////////////
  288.59 +	// std::plus-family operates on operands with identical types - we need to
  288.60 +	// support all the (vectype op float) combinations in vector maths. 
  288.61 +	// Providing T(float) would open the way to endless implicit conversions.
  288.62 +	///////////////////////////////////////////////////////////////////////////
  288.63 +	namespace Intern {
  288.64 +		template <typename T0, typename T1, typename TRES = T0> struct plus {
  288.65 +			TRES operator() (const T0& t0, const T1& t1) const {
  288.66 +				return t0+t1;
  288.67 +			}
  288.68 +		};
  288.69 +		template <typename T0, typename T1, typename TRES = T0> struct minus {
  288.70 +			TRES operator() (const T0& t0, const T1& t1) const {
  288.71 +				return t0-t1;
  288.72 +			}
  288.73 +		};
  288.74 +		template <typename T0, typename T1, typename TRES = T0> struct multiplies {
  288.75 +			TRES operator() (const T0& t0, const T1& t1) const {
  288.76 +				return t0*t1;
  288.77 +			}
  288.78 +		};
  288.79 +		template <typename T0, typename T1, typename TRES = T0> struct divides {
  288.80 +			TRES operator() (const T0& t0, const T1& t1) const {
  288.81 +				return t0/t1;
  288.82 +			}
  288.83 +		};
  288.84 +	}
  288.85 +
  288.86 +// ------------------------------------------------------------------------------------------------
  288.87 +/** Intermediate description a vertex with all possible components. Defines a full set of 
  288.88 + *  operators, so you may use such a 'Vertex' in basic arithmetics. All operators are applied
  288.89 + *  to *all* vertex components equally. This is useful for stuff like interpolation
  288.90 + *  or subdivision, but won't work if special handling is required for some vertex components. */
  288.91 +// ------------------------------------------------------------------------------------------------
  288.92 +class Vertex
  288.93 +{
  288.94 +	friend Vertex operator + (const Vertex&,const Vertex&);
  288.95 +	friend Vertex operator - (const Vertex&,const Vertex&);
  288.96 +
  288.97 +//	friend Vertex operator + (const Vertex&,float);
  288.98 +//	friend Vertex operator - (const Vertex&,float);
  288.99 +	friend Vertex operator * (const Vertex&,float);
 288.100 +	friend Vertex operator / (const Vertex&,float);
 288.101 +
 288.102 +//	friend Vertex operator + (float, const Vertex&);
 288.103 +//	friend Vertex operator - (float, const Vertex&);
 288.104 +	friend Vertex operator * (float, const Vertex&);
 288.105 +//	friend Vertex operator / (float, const Vertex&);
 288.106 +
 288.107 +public:
 288.108 +
 288.109 +	Vertex() {}
 288.110 +
 288.111 +	// ----------------------------------------------------------------------------
 288.112 +	/** Extract a particular vertex from a mesh and interleave all components */
 288.113 +	explicit Vertex(const aiMesh* msh, unsigned int idx) {
 288.114 +		ai_assert(idx < msh->mNumVertices);
 288.115 +		position = msh->mVertices[idx];
 288.116 +
 288.117 +		if (msh->HasNormals()) {
 288.118 +			normal = msh->mNormals[idx];
 288.119 +		}
 288.120 +
 288.121 +		if (msh->HasTangentsAndBitangents()) {
 288.122 +			tangent = msh->mTangents[idx];
 288.123 +			bitangent = msh->mBitangents[idx];
 288.124 +		}
 288.125 +
 288.126 +		for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) {
 288.127 +			texcoords[i] = msh->mTextureCoords[i][idx];
 288.128 +		}
 288.129 +
 288.130 +		for (unsigned int i = 0; msh->HasVertexColors(i); ++i) {
 288.131 +			colors[i] = msh->mColors[i][idx];
 288.132 +		}
 288.133 +	}
 288.134 +
 288.135 +public:
 288.136 +
 288.137 +	Vertex& operator += (const Vertex& v) {
 288.138 +		*this = *this+v;
 288.139 +		return *this;
 288.140 +	}
 288.141 +
 288.142 +	Vertex& operator -= (const Vertex& v) {
 288.143 +		*this = *this-v;
 288.144 +		return *this;
 288.145 +	}
 288.146 +
 288.147 +
 288.148 +/*
 288.149 +	Vertex& operator += (float v) {
 288.150 +		*this = *this+v;
 288.151 +		return *this;
 288.152 +	}
 288.153 +
 288.154 +	Vertex& operator -= (float v) {
 288.155 +		*this = *this-v;
 288.156 +		return *this;
 288.157 +	}
 288.158 +*/
 288.159 +	Vertex& operator *= (float v) {
 288.160 +		*this = *this*v;
 288.161 +		return *this;
 288.162 +	}
 288.163 +
 288.164 +	Vertex& operator /= (float v) {
 288.165 +		*this = *this/v;
 288.166 +		return *this;
 288.167 +	}
 288.168 +
 288.169 +public:
 288.170 +
 288.171 +	// ----------------------------------------------------------------------------
 288.172 +	/** Convert back to non-interleaved storage */
 288.173 +	void SortBack(aiMesh* out, unsigned int idx) const {
 288.174 +
 288.175 +		ai_assert(idx<out->mNumVertices);
 288.176 +		out->mVertices[idx] = position;
 288.177 +
 288.178 +		if (out->HasNormals()) {
 288.179 +			out->mNormals[idx] = normal;
 288.180 +		}
 288.181 +
 288.182 +		if (out->HasTangentsAndBitangents()) {
 288.183 +			out->mTangents[idx] = tangent;
 288.184 +			out->mBitangents[idx] = bitangent;
 288.185 +		}
 288.186 +
 288.187 +		for(unsigned int i = 0; out->HasTextureCoords(i); ++i) {
 288.188 +			out->mTextureCoords[i][idx] = texcoords[i];
 288.189 +		}
 288.190 +
 288.191 +		for(unsigned int i = 0; out->HasVertexColors(i); ++i) {
 288.192 +			out->mColors[i][idx] = colors[i];
 288.193 +		}
 288.194 +	}
 288.195 +
 288.196 +private:
 288.197 +
 288.198 +	// ----------------------------------------------------------------------------
 288.199 +	/** Construct from two operands and a binary operation to combine them */
 288.200 +	template <template <typename t> class op> static Vertex BinaryOp(const Vertex& v0, const Vertex& v1) {
 288.201 +		// this is a heavy task for the compiler to optimize ... *pray*
 288.202 +
 288.203 +		Vertex res;
 288.204 +		res.position  = op<aiVector3D>()(v0.position,v1.position);
 288.205 +		res.normal    = op<aiVector3D>()(v0.normal,v1.normal);
 288.206 +		res.tangent   = op<aiVector3D>()(v0.tangent,v1.tangent);
 288.207 +		res.bitangent = op<aiVector3D>()(v0.bitangent,v1.bitangent);
 288.208 +
 288.209 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
 288.210 +			res.texcoords[i] = op<aiVector3D>()(v0.texcoords[i],v1.texcoords[i]);
 288.211 +		}
 288.212 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
 288.213 +			res.colors[i] = op<aiColor4D>()(v0.colors[i],v1.colors[i]);
 288.214 +		}
 288.215 +		return res;
 288.216 +	}
 288.217 +
 288.218 +	// ----------------------------------------------------------------------------
 288.219 +	/** This time binary arithmetics of v0 with a floating-point number */
 288.220 +	template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, float f) {
 288.221 +		// this is a heavy task for the compiler to optimize ... *pray*
 288.222 +
 288.223 +		Vertex res;
 288.224 +		res.position  = op<aiVector3D,float,aiVector3D>()(v0.position,f);
 288.225 +		res.normal    = op<aiVector3D,float,aiVector3D>()(v0.normal,f);
 288.226 +		res.tangent   = op<aiVector3D,float,aiVector3D>()(v0.tangent,f);
 288.227 +		res.bitangent = op<aiVector3D,float,aiVector3D>()(v0.bitangent,f);
 288.228 +
 288.229 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
 288.230 +			res.texcoords[i] = op<aiVector3D,float,aiVector3D>()(v0.texcoords[i],f);
 288.231 +		}
 288.232 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
 288.233 +			res.colors[i] = op<aiColor4D,float,aiColor4D>()(v0.colors[i],f);
 288.234 +		}
 288.235 +		return res;
 288.236 +	}
 288.237 +
 288.238 +	// ----------------------------------------------------------------------------
 288.239 +	/** This time binary arithmetics of v0 with a floating-point number */
 288.240 +	template <template <typename, typename, typename> class op> static Vertex BinaryOp(float f, const Vertex& v0) {
 288.241 +		// this is a heavy task for the compiler to optimize ... *pray*
 288.242 +
 288.243 +		Vertex res;
 288.244 +		res.position  = op<float,aiVector3D,aiVector3D>()(f,v0.position);
 288.245 +		res.normal    = op<float,aiVector3D,aiVector3D>()(f,v0.normal);
 288.246 +		res.tangent   = op<float,aiVector3D,aiVector3D>()(f,v0.tangent);
 288.247 +		res.bitangent = op<float,aiVector3D,aiVector3D>()(f,v0.bitangent);
 288.248 +
 288.249 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
 288.250 +			res.texcoords[i] = op<float,aiVector3D,aiVector3D>()(f,v0.texcoords[i]);
 288.251 +		}
 288.252 +		for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
 288.253 +			res.colors[i] = op<float,aiColor4D,aiColor4D>()(f,v0.colors[i]);
 288.254 +		}
 288.255 +		return res;
 288.256 +	}
 288.257 +
 288.258 +public:
 288.259 +
 288.260 +	aiVector3D position;
 288.261 +	aiVector3D normal;
 288.262 +	aiVector3D tangent, bitangent;
 288.263 +
 288.264 +	aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 288.265 +	aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
 288.266 +};
 288.267 +
 288.268 +
 288.269 +
 288.270 +// ------------------------------------------------------------------------------------------------
 288.271 +AI_FORCE_INLINE Vertex operator + (const Vertex& v0,const Vertex& v1) {
 288.272 +	return Vertex::BinaryOp<std::plus>(v0,v1);
 288.273 +}
 288.274 +
 288.275 +AI_FORCE_INLINE Vertex operator - (const Vertex& v0,const Vertex& v1) {
 288.276 +	return Vertex::BinaryOp<std::minus>(v0,v1);
 288.277 +}
 288.278 +
 288.279 +
 288.280 +// ------------------------------------------------------------------------------------------------
 288.281 +/*
 288.282 +AI_FORCE_INLINE Vertex operator + (const Vertex& v0,float f) {
 288.283 +	return Vertex::BinaryOp<Intern::plus>(v0,f);
 288.284 +}
 288.285 +
 288.286 +AI_FORCE_INLINE Vertex operator - (const Vertex& v0,float f) {
 288.287 +	return Vertex::BinaryOp<Intern::minus>(v0,f);
 288.288 +}
 288.289 +
 288.290 +*/
 288.291 +
 288.292 +AI_FORCE_INLINE Vertex operator * (const Vertex& v0,float f) {
 288.293 +	return Vertex::BinaryOp<Intern::multiplies>(v0,f);
 288.294 +}
 288.295 +
 288.296 +AI_FORCE_INLINE Vertex operator / (const Vertex& v0,float f) {
 288.297 +	return Vertex::BinaryOp<Intern::multiplies>(v0,1.f/f);
 288.298 +}
 288.299 +
 288.300 +// ------------------------------------------------------------------------------------------------
 288.301 +/*
 288.302 +AI_FORCE_INLINE Vertex operator + (float f,const Vertex& v0) {
 288.303 +	return Vertex::BinaryOp<Intern::plus>(f,v0);
 288.304 +}
 288.305 +
 288.306 +AI_FORCE_INLINE Vertex operator - (float f,const Vertex& v0) {
 288.307 +	return Vertex::BinaryOp<Intern::minus>(f,v0);
 288.308 +}
 288.309 +*/
 288.310 +
 288.311 +AI_FORCE_INLINE Vertex operator * (float f,const Vertex& v0) {
 288.312 +	return Vertex::BinaryOp<Intern::multiplies>(f,v0);
 288.313 +}
 288.314 +
 288.315 +/*
 288.316 +AI_FORCE_INLINE Vertex operator / (float f,const Vertex& v0) {
 288.317 +	return Vertex::BinaryOp<Intern::divides>(f,v0);
 288.318 +}
 288.319 +*/
 288.320 +
 288.321 +}
 288.322 +#endif
   289.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   289.2 +++ b/libs/assimp/VertexTriangleAdjacency.cpp	Sat Feb 01 19:58:19 2014 +0200
   289.3 @@ -0,0 +1,135 @@
   289.4 +/*
   289.5 +---------------------------------------------------------------------------
   289.6 +Open Asset Import Library (assimp)
   289.7 +---------------------------------------------------------------------------
   289.8 +
   289.9 +Copyright (c) 2006-2012, assimp team
  289.10 +
  289.11 +All rights reserved.
  289.12 +
  289.13 +Redistribution and use of this software in source and binary forms, 
  289.14 +with or without modification, are permitted provided that the following 
  289.15 +conditions are met:
  289.16 +
  289.17 +* Redistributions of source code must retain the above
  289.18 +  copyright notice, this list of conditions and the
  289.19 +  following disclaimer.
  289.20 +
  289.21 +* Redistributions in binary form must reproduce the above
  289.22 +  copyright notice, this list of conditions and the
  289.23 +  following disclaimer in the documentation and/or other
  289.24 +  materials provided with the distribution.
  289.25 +
  289.26 +* Neither the name of the assimp team, nor the names of its
  289.27 +  contributors may be used to endorse or promote products
  289.28 +  derived from this software without specific prior
  289.29 +  written permission of the assimp team.
  289.30 +
  289.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  289.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  289.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  289.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  289.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  289.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  289.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  289.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  289.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  289.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  289.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  289.42 +---------------------------------------------------------------------------
  289.43 +*/
  289.44 +
  289.45 +/** @file Implementation of the VertexTriangleAdjacency helper class
  289.46 + */
  289.47 +
  289.48 +#include "AssimpPCH.h"
  289.49 +
  289.50 +// internal headers
  289.51 +#include "VertexTriangleAdjacency.h"
  289.52 +
  289.53 +using namespace Assimp;
  289.54 +
  289.55 +// ------------------------------------------------------------------------------------------------
  289.56 +VertexTriangleAdjacency::VertexTriangleAdjacency(aiFace *pcFaces,
  289.57 +	unsigned int iNumFaces,
  289.58 +	unsigned int iNumVertices /*= 0*/,
  289.59 +	bool bComputeNumTriangles /*= false*/)
  289.60 +{
  289.61 +	// compute the number of referenced vertices if it wasn't specified by the caller
  289.62 +	const aiFace* const pcFaceEnd = pcFaces + iNumFaces;
  289.63 +	if (!iNumVertices)	{
  289.64 +
  289.65 +		for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace)	{
  289.66 +			ai_assert(3 == pcFace->mNumIndices);
  289.67 +			iNumVertices = std::max(iNumVertices,pcFace->mIndices[0]);
  289.68 +			iNumVertices = std::max(iNumVertices,pcFace->mIndices[1]);
  289.69 +			iNumVertices = std::max(iNumVertices,pcFace->mIndices[2]);
  289.70 +		}
  289.71 +	}
  289.72 +
  289.73 +	this->iNumVertices = iNumVertices;
  289.74 +
  289.75 +	unsigned int* pi;
  289.76 +
  289.77 +	// allocate storage
  289.78 +	if (bComputeNumTriangles)	{
  289.79 +		pi = mLiveTriangles = new unsigned int[iNumVertices+1];
  289.80 +		memset(mLiveTriangles,0,sizeof(unsigned int)*(iNumVertices+1));
  289.81 +		mOffsetTable = new unsigned int[iNumVertices+2]+1;
  289.82 +	}
  289.83 +	else {
  289.84 +		pi = mOffsetTable = new unsigned int[iNumVertices+2]+1;
  289.85 +		memset(mOffsetTable,0,sizeof(unsigned int)*(iNumVertices+1));
  289.86 +		mLiveTriangles = NULL; // important, otherwise the d'tor would crash
  289.87 +	}
  289.88 +
  289.89 +	// get a pointer to the end of the buffer
  289.90 +	unsigned int* piEnd = pi+iNumVertices;
  289.91 +	*piEnd++ = 0u;
  289.92 +
  289.93 +	// first pass: compute the number of faces referencing each vertex
  289.94 +	for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace)
  289.95 +	{
  289.96 +		pi[pcFace->mIndices[0]]++;	
  289.97 +		pi[pcFace->mIndices[1]]++;	
  289.98 +		pi[pcFace->mIndices[2]]++;	
  289.99 +	}
 289.100 +
 289.101 +	// second pass: compute the final offset table
 289.102 +	unsigned int iSum = 0;
 289.103 +	unsigned int* piCurOut = this->mOffsetTable;
 289.104 +	for (unsigned int* piCur = pi; piCur != piEnd;++piCur,++piCurOut)	{
 289.105 +
 289.106 +		unsigned int iLastSum = iSum;
 289.107 +		iSum += *piCur; 
 289.108 +		*piCurOut = iLastSum;
 289.109 +	}
 289.110 +	pi = this->mOffsetTable;
 289.111 +
 289.112 +	// third pass: compute the final table
 289.113 +	this->mAdjacencyTable = new unsigned int[iSum];
 289.114 +	iSum = 0;
 289.115 +	for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace,++iSum)	{
 289.116 +
 289.117 +		unsigned int idx = pcFace->mIndices[0];
 289.118 +		mAdjacencyTable[pi[idx]++] = iSum;
 289.119 +
 289.120 +		idx = pcFace->mIndices[1];
 289.121 +		mAdjacencyTable[pi[idx]++] = iSum;
 289.122 +
 289.123 +		idx = pcFace->mIndices[2];
 289.124 +		mAdjacencyTable[pi[idx]++] = iSum;
 289.125 +	}
 289.126 +	// fourth pass: undo the offset computations made during the third pass
 289.127 +	// We could do this in a separate buffer, but this would be TIMES slower.
 289.128 +	--mOffsetTable;
 289.129 +	*mOffsetTable = 0u;
 289.130 +}
 289.131 +// ------------------------------------------------------------------------------------------------
 289.132 +VertexTriangleAdjacency::~VertexTriangleAdjacency()
 289.133 +{
 289.134 +	// delete allocated storage
 289.135 +	delete[] mOffsetTable;
 289.136 +	delete[] mAdjacencyTable;
 289.137 +	delete[] mLiveTriangles;
 289.138 +}
   290.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   290.2 +++ b/libs/assimp/VertexTriangleAdjacency.h	Sat Feb 01 19:58:19 2014 +0200
   290.3 @@ -0,0 +1,124 @@
   290.4 +/*
   290.5 +Open Asset Import Library (assimp)
   290.6 +----------------------------------------------------------------------
   290.7 +
   290.8 +Copyright (c) 2006-2012, assimp team
   290.9 +All rights reserved.
  290.10 +
  290.11 +Redistribution and use of this software in source and binary forms, 
  290.12 +with or without modification, are permitted provided that the 
  290.13 +following conditions are met:
  290.14 +
  290.15 +* Redistributions of source code must retain the above
  290.16 +  copyright notice, this list of conditions and the
  290.17 +  following disclaimer.
  290.18 +
  290.19 +* Redistributions in binary form must reproduce the above
  290.20 +  copyright notice, this list of conditions and the
  290.21 +  following disclaimer in the documentation and/or other
  290.22 +  materials provided with the distribution.
  290.23 +
  290.24 +* Neither the name of the assimp team, nor the names of its
  290.25 +  contributors may be used to endorse or promote products
  290.26 +  derived from this software without specific prior
  290.27 +  written permission of the assimp team.
  290.28 +
  290.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  290.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  290.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  290.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  290.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  290.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  290.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  290.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  290.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  290.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  290.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  290.40 +
  290.41 +----------------------------------------------------------------------
  290.42 +*/
  290.43 +
  290.44 +/** @file Defines a helper class to compute a vertex-triangle adjacency map */
  290.45 +#ifndef AI_VTADJACENCY_H_INC
  290.46 +#define AI_VTADJACENCY_H_INC
  290.47 +
  290.48 +#include "BaseProcess.h"
  290.49 +#include "assimp/types.h"
  290.50 +#include "assimp/ai_assert.h"
  290.51 +
  290.52 +struct aiMesh;
  290.53 +namespace Assimp	{
  290.54 +
  290.55 +// --------------------------------------------------------------------------------------------
  290.56 +/** @brief The VertexTriangleAdjacency class computes a vertex-triangle
  290.57 + *  adjacency map from a given index buffer.
  290.58 + *
  290.59 + *  @note Although it is called #VertexTriangleAdjacency, the current version does also
  290.60 + *    support arbitrary polygons. */
  290.61 +// --------------------------------------------------------------------------------------------
  290.62 +class VertexTriangleAdjacency
  290.63 +{
  290.64 +public:
  290.65 +
  290.66 +	// ----------------------------------------------------------------------------
  290.67 +	/** @brief Construction from an existing index buffer
  290.68 +	 *  @param pcFaces Index buffer
  290.69 +	 *  @param iNumFaces Number of faces in the buffer
  290.70 +	 *  @param iNumVertices Number of referenced vertices. This value
  290.71 +	 *    is computed automatically if 0 is specified.
  290.72 +	 *  @param bComputeNumTriangles If you want the class to compute
  290.73 +	 *    a list containing the number of referenced triangles per vertex
  290.74 +	 *    per vertex - pass true.  */
  290.75 +	VertexTriangleAdjacency(aiFace* pcFaces,unsigned int iNumFaces,
  290.76 +		unsigned int iNumVertices = 0,
  290.77 +		bool bComputeNumTriangles = true);
  290.78 +
  290.79 +
  290.80 +	// ----------------------------------------------------------------------------
  290.81 +	/** @brief Destructor */
  290.82 +	~VertexTriangleAdjacency();
  290.83 +
  290.84 +
  290.85 +public:
  290.86 +
  290.87 +	// ----------------------------------------------------------------------------
  290.88 +	/** @brief Get all triangles adjacent to a vertex
  290.89 +	 *  @param iVertIndex Index of the vertex
  290.90 +	 *  @return A pointer to the adjacency list. */
  290.91 +	unsigned int* GetAdjacentTriangles(unsigned int iVertIndex) const
  290.92 +	{
  290.93 +		ai_assert(iVertIndex < iNumVertices);
  290.94 +		return &mAdjacencyTable[ mOffsetTable[iVertIndex]];
  290.95 +	}
  290.96 +
  290.97 +
  290.98 +	// ----------------------------------------------------------------------------
  290.99 +	/** @brief Get the number of triangles that are referenced by
 290.100 +	 *    a vertex. This function returns a reference that can be modified
 290.101 +	 *  @param iVertIndex Index of the vertex
 290.102 +	 *  @return Number of referenced triangles */
 290.103 +	unsigned int& GetNumTrianglesPtr(unsigned int iVertIndex)
 290.104 +	{
 290.105 +		ai_assert(iVertIndex < iNumVertices && NULL != mLiveTriangles);
 290.106 +		return mLiveTriangles[iVertIndex];
 290.107 +	}
 290.108 +
 290.109 +
 290.110 +public:
 290.111 +
 290.112 +	//! Offset table
 290.113 +	unsigned int* mOffsetTable;
 290.114 +
 290.115 +	//! Adjacency table
 290.116 +	unsigned int* mAdjacencyTable;
 290.117 +
 290.118 +	//! Table containing the number of referenced triangles per vertex
 290.119 +	unsigned int* mLiveTriangles;
 290.120 +
 290.121 +	//! Debug: Number of referenced vertices
 290.122 +	unsigned int iNumVertices;
 290.123 +
 290.124 +};
 290.125 +}
 290.126 +
 290.127 +#endif // !! AI_VTADJACENCY_H_INC
   291.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   291.2 +++ b/libs/assimp/Win32DebugLogStream.h	Sat Feb 01 19:58:19 2014 +0200
   291.3 @@ -0,0 +1,50 @@
   291.4 +#ifndef AI_WIN32DEBUGLOGSTREAM_H_INC
   291.5 +#define AI_WIN32DEBUGLOGSTREAM_H_INC
   291.6 +
   291.7 +#ifdef WIN32
   291.8 +
   291.9 +#include "assimp/LogStream.hpp"
  291.10 +#include "windows.h"
  291.11 +
  291.12 +namespace Assimp	{
  291.13 +
  291.14 +// ---------------------------------------------------------------------------
  291.15 +/**	@class	Win32DebugLogStream
  291.16 + *	@brief	Logs into the debug stream from win32.
  291.17 + */
  291.18 +class Win32DebugLogStream :
  291.19 +	public LogStream
  291.20 +{
  291.21 +public:
  291.22 +	/**	@brief	Default constructor	*/
  291.23 +	Win32DebugLogStream();
  291.24 +
  291.25 +	/**	@brief	Destructor	*/
  291.26 +	~Win32DebugLogStream();
  291.27 +	
  291.28 +	/**	@brief	Writer	*/
  291.29 +	void write(const char* messgae);
  291.30 +};
  291.31 +
  291.32 +// ---------------------------------------------------------------------------
  291.33 +//	Default constructor
  291.34 +inline Win32DebugLogStream::Win32DebugLogStream()
  291.35 +{}
  291.36 +
  291.37 +// ---------------------------------------------------------------------------
  291.38 +//	Default constructor
  291.39 +inline Win32DebugLogStream::~Win32DebugLogStream()
  291.40 +{}
  291.41 +
  291.42 +// ---------------------------------------------------------------------------
  291.43 +//	Write method
  291.44 +inline void Win32DebugLogStream::write(const char* message)
  291.45 +{
  291.46 +	OutputDebugStringA( message);
  291.47 +}
  291.48 +
  291.49 +// ---------------------------------------------------------------------------
  291.50 +}	// Namespace Assimp
  291.51 +
  291.52 +#endif // ! WIN32
  291.53 +#endif // guard
   292.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   292.2 +++ b/libs/assimp/XFileHelper.h	Sat Feb 01 19:58:19 2014 +0200
   292.3 @@ -0,0 +1,202 @@
   292.4 +/*
   292.5 +Open Asset Import Library (assimp)
   292.6 +----------------------------------------------------------------------
   292.7 +
   292.8 +Copyright (c) 2006-2012, assimp team
   292.9 +All rights reserved.
  292.10 +
  292.11 +Redistribution and use of this software in source and binary forms, 
  292.12 +with or without modification, are permitted provided that the 
  292.13 +following conditions are met:
  292.14 +
  292.15 +* Redistributions of source code must retain the above
  292.16 +  copyright notice, this list of conditions and the
  292.17 +  following disclaimer.
  292.18 +
  292.19 +* Redistributions in binary form must reproduce the above
  292.20 +  copyright notice, this list of conditions and the
  292.21 +  following disclaimer in the documentation and/or other
  292.22 +  materials provided with the distribution.
  292.23 +
  292.24 +* Neither the name of the assimp team, nor the names of its
  292.25 +  contributors may be used to endorse or promote products
  292.26 +  derived from this software without specific prior
  292.27 +  written permission of the assimp team.
  292.28 +
  292.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  292.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  292.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  292.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  292.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  292.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  292.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  292.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  292.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  292.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  292.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  292.40 +
  292.41 +----------------------------------------------------------------------
  292.42 +*/
  292.43 +
  292.44 +
  292.45 +/** @file Defines the helper data structures for importing XFiles */
  292.46 +#ifndef AI_XFILEHELPER_H_INC
  292.47 +#define AI_XFILEHELPER_H_INC
  292.48 +
  292.49 +#include <string>
  292.50 +#include <vector>
  292.51 +
  292.52 +#include "assimp/types.h"
  292.53 +#include "assimp/quaternion.h"
  292.54 +#include "assimp/mesh.h"
  292.55 +#include "assimp/anim.h"
  292.56 +
  292.57 +namespace Assimp
  292.58 +{
  292.59 +namespace XFile
  292.60 +{
  292.61 +
  292.62 +/** Helper structure representing a XFile mesh face */
  292.63 +struct Face
  292.64 +{
  292.65 +	std::vector<unsigned int> mIndices;
  292.66 +};
  292.67 +
  292.68 +/** Helper structure representing a texture filename inside a material and its potential source */
  292.69 +struct TexEntry
  292.70 +{
  292.71 +	std::string mName;
  292.72 +	bool mIsNormalMap; // true if the texname was specified in a NormalmapFilename tag
  292.73 +
  292.74 +	TexEntry() { mIsNormalMap = false; }
  292.75 +	TexEntry( const std::string& pName, bool pIsNormalMap = false) 
  292.76 +		: mName( pName), mIsNormalMap( pIsNormalMap) 
  292.77 +	{ /* done */ }
  292.78 +};
  292.79 +
  292.80 +/** Helper structure representing a XFile material */
  292.81 +struct Material
  292.82 +{
  292.83 +	std::string mName;
  292.84 +	bool mIsReference; // if true, mName holds a name by which the actual material can be found in the material list
  292.85 +	aiColor4D mDiffuse;
  292.86 +	float mSpecularExponent;
  292.87 +	aiColor3D mSpecular;
  292.88 +	aiColor3D mEmissive;
  292.89 +	std::vector<TexEntry> mTextures;
  292.90 +
  292.91 +  size_t sceneIndex; ///< the index under which it was stored in the scene's material list
  292.92 +
  292.93 +	Material() { mIsReference = false; sceneIndex = SIZE_MAX; }
  292.94 +};
  292.95 +
  292.96 +/** Helper structure to represent a bone weight */
  292.97 +struct BoneWeight
  292.98 +{
  292.99 +	unsigned int mVertex;
 292.100 +	float mWeight;
 292.101 +};
 292.102 +
 292.103 +/** Helper structure to represent a bone in a mesh */
 292.104 +struct Bone
 292.105 +{
 292.106 +	std::string mName;
 292.107 +	std::vector<BoneWeight> mWeights;
 292.108 +	aiMatrix4x4 mOffsetMatrix;
 292.109 +};
 292.110 +
 292.111 +/** Helper structure to represent an XFile mesh */
 292.112 +struct Mesh
 292.113 +{
 292.114 +	std::vector<aiVector3D> mPositions;
 292.115 +	std::vector<Face> mPosFaces;
 292.116 +	std::vector<aiVector3D> mNormals;
 292.117 +	std::vector<Face> mNormFaces;
 292.118 +	unsigned int mNumTextures;
 292.119 +	std::vector<aiVector2D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 292.120 +	unsigned int mNumColorSets;
 292.121 +	std::vector<aiColor4D> mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
 292.122 +
 292.123 +	std::vector<unsigned int> mFaceMaterials;
 292.124 +	std::vector<Material> mMaterials;
 292.125 +
 292.126 +	std::vector<Bone> mBones;
 292.127 +
 292.128 +	Mesh() { mNumTextures = 0; mNumColorSets = 0; }
 292.129 +};
 292.130 +
 292.131 +/** Helper structure to represent a XFile frame */
 292.132 +struct Node
 292.133 +{
 292.134 +	std::string mName;
 292.135 +	aiMatrix4x4 mTrafoMatrix;
 292.136 +	Node* mParent;
 292.137 +	std::vector<Node*> mChildren;
 292.138 +	std::vector<Mesh*> mMeshes;
 292.139 +
 292.140 +	Node() { mParent = NULL; }
 292.141 +	Node( Node* pParent) { mParent = pParent; }
 292.142 +	~Node() 
 292.143 +	{
 292.144 +		for( unsigned int a = 0; a < mChildren.size(); a++)
 292.145 +			delete mChildren[a];
 292.146 +		for( unsigned int a = 0; a < mMeshes.size(); a++)
 292.147 +			delete mMeshes[a];
 292.148 +	}
 292.149 +};
 292.150 +
 292.151 +struct MatrixKey
 292.152 +{
 292.153 +	double mTime;
 292.154 +	aiMatrix4x4 mMatrix;
 292.155 +};
 292.156 +
 292.157 +/** Helper structure representing a single animated bone in a XFile */
 292.158 +struct AnimBone
 292.159 +{
 292.160 +	std::string mBoneName;
 292.161 +	std::vector<aiVectorKey> mPosKeys;  // either three separate key sequences for position, rotation, scaling
 292.162 +	std::vector<aiQuatKey> mRotKeys;
 292.163 +	std::vector<aiVectorKey> mScaleKeys;
 292.164 +	std::vector<MatrixKey> mTrafoKeys; // or a combined key sequence of transformation matrices.
 292.165 +};
 292.166 +
 292.167 +/** Helper structure to represent an animation set in a XFile */
 292.168 +struct Animation
 292.169 +{
 292.170 +	std::string mName;
 292.171 +	std::vector<AnimBone*> mAnims;
 292.172 +
 292.173 +	~Animation() 
 292.174 +	{
 292.175 +		for( unsigned int a = 0; a < mAnims.size(); a++)
 292.176 +			delete mAnims[a];
 292.177 +	}
 292.178 +};
 292.179 +
 292.180 +/** Helper structure analogue to aiScene */
 292.181 +struct Scene
 292.182 +{
 292.183 +	Node* mRootNode;
 292.184 +
 292.185 +	std::vector<Mesh*> mGlobalMeshes; // global meshes found outside of any frames
 292.186 +	std::vector<Material> mGlobalMaterials; // global materials found outside of any meshes.
 292.187 +
 292.188 +	std::vector<Animation*> mAnims;
 292.189 +	unsigned int mAnimTicksPerSecond;
 292.190 +
 292.191 +	Scene() { mRootNode = NULL; mAnimTicksPerSecond = 0; }
 292.192 +	~Scene()
 292.193 +	{
 292.194 +		delete mRootNode;
 292.195 +		for( unsigned int a = 0; a < mGlobalMeshes.size(); a++)
 292.196 +			delete mGlobalMeshes[a];
 292.197 +		for( unsigned int a = 0; a < mAnims.size(); a++)
 292.198 +			delete mAnims[a];
 292.199 +	}
 292.200 +};
 292.201 +
 292.202 +} // end of namespace XFile
 292.203 +} // end of namespace Assimp
 292.204 +
 292.205 +#endif // AI_XFILEHELPER_H_INC
   293.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   293.2 +++ b/libs/assimp/XFileImporter.cpp	Sat Feb 01 19:58:19 2014 +0200
   293.3 @@ -0,0 +1,699 @@
   293.4 +/*
   293.5 +---------------------------------------------------------------------------
   293.6 +Open Asset Import Library (assimp)
   293.7 +---------------------------------------------------------------------------
   293.8 +
   293.9 +Copyright (c) 2006-2012, assimp team
  293.10 +
  293.11 +All rights reserved.
  293.12 +
  293.13 +Redistribution and use of this software in source and binary forms, 
  293.14 +with or without modification, are permitted provided that the following 
  293.15 +conditions are met:
  293.16 +
  293.17 +* Redistributions of source code must retain the above
  293.18 +copyright notice, this list of conditions and the
  293.19 +following disclaimer.
  293.20 +
  293.21 +* Redistributions in binary form must reproduce the above
  293.22 +copyright notice, this list of conditions and the
  293.23 +following disclaimer in the documentation and/or other
  293.24 +materials provided with the distribution.
  293.25 +
  293.26 +* Neither the name of the assimp team, nor the names of its
  293.27 +contributors may be used to endorse or promote products
  293.28 +derived from this software without specific prior
  293.29 +written permission of the assimp team.
  293.30 +
  293.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  293.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  293.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  293.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  293.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  293.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  293.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  293.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  293.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  293.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  293.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  293.42 +---------------------------------------------------------------------------
  293.43 +*/
  293.44 +/** @file  XFileImporter.cpp
  293.45 + *  @brief Implementation of the XFile importer class 
  293.46 + */
  293.47 +
  293.48 +#include "AssimpPCH.h"
  293.49 +#ifndef ASSIMP_BUILD_NO_X_IMPORTER
  293.50 +
  293.51 +#include "XFileImporter.h"
  293.52 +#include "XFileParser.h"
  293.53 +#include "ConvertToLHProcess.h"
  293.54 +
  293.55 +using namespace Assimp;
  293.56 +
  293.57 +static const aiImporterDesc desc = {
  293.58 +	"Direct3D XFile Importer",
  293.59 +	"",
  293.60 +	"",
  293.61 +	"",
  293.62 +	aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour,
  293.63 +	1,
  293.64 +	3,
  293.65 +	1,
  293.66 +	5,
  293.67 +	"x" 
  293.68 +};
  293.69 +
  293.70 +// ------------------------------------------------------------------------------------------------
  293.71 +// Constructor to be privately used by Importer
  293.72 +XFileImporter::XFileImporter()
  293.73 +{}
  293.74 +
  293.75 +// ------------------------------------------------------------------------------------------------
  293.76 +// Destructor, private as well 
  293.77 +XFileImporter::~XFileImporter()
  293.78 +{}
  293.79 +
  293.80 +// ------------------------------------------------------------------------------------------------
  293.81 +// Returns whether the class can handle the format of the given file. 
  293.82 +bool XFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
  293.83 +{
  293.84 +	std::string extension = GetExtension(pFile);
  293.85 +	if(extension == "x") {
  293.86 +		return true;
  293.87 +	}
  293.88 +	if (!extension.length() || checkSig) {
  293.89 +		uint32_t token[1];
  293.90 +		token[0] = AI_MAKE_MAGIC("xof ");
  293.91 +		return CheckMagicToken(pIOHandler,pFile,token,1,0);
  293.92 +	}
  293.93 +	return false;
  293.94 +}
  293.95 +
  293.96 +// ------------------------------------------------------------------------------------------------
  293.97 +// Get file extension list
  293.98 +const aiImporterDesc* XFileImporter::GetInfo () const
  293.99 +{
 293.100 +	return &desc;
 293.101 +}
 293.102 +
 293.103 +// ------------------------------------------------------------------------------------------------
 293.104 +// Imports the given file into the given scene structure. 
 293.105 +void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
 293.106 +{
 293.107 +	// read file into memory
 293.108 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
 293.109 +	if( file.get() == NULL)
 293.110 +		throw DeadlyImportError( "Failed to open file " + pFile + ".");
 293.111 +
 293.112 +	size_t fileSize = file->FileSize();
 293.113 +	if( fileSize < 16)
 293.114 +		throw DeadlyImportError( "XFile is too small.");
 293.115 +
 293.116 +	// in the hope that binary files will never start with a BOM ...
 293.117 +	mBuffer.resize( fileSize + 1);
 293.118 +	file->Read( &mBuffer.front(), 1, fileSize);
 293.119 +	ConvertToUTF8(mBuffer);
 293.120 +
 293.121 +	// parse the file into a temporary representation
 293.122 +	XFileParser parser( mBuffer);
 293.123 +
 293.124 +	// and create the proper return structures out of it
 293.125 +	CreateDataRepresentationFromImport( pScene, parser.GetImportedData());
 293.126 +
 293.127 +	// if nothing came from it, report it as error
 293.128 +	if( !pScene->mRootNode)
 293.129 +		throw DeadlyImportError( "XFile is ill-formatted - no content imported.");
 293.130 +}
 293.131 +
 293.132 +// ------------------------------------------------------------------------------------------------
 293.133 +// Constructs the return data structure out of the imported data.
 293.134 +void XFileImporter::CreateDataRepresentationFromImport( aiScene* pScene, XFile::Scene* pData)
 293.135 +{
 293.136 +	// Read the global materials first so that meshes referring to them can find them later
 293.137 +	ConvertMaterials( pScene, pData->mGlobalMaterials);
 293.138 +
 293.139 +	// copy nodes, extracting meshes and materials on the way
 293.140 +	pScene->mRootNode = CreateNodes( pScene, NULL, pData->mRootNode);
 293.141 +
 293.142 +	// extract animations
 293.143 +	CreateAnimations( pScene, pData);
 293.144 +
 293.145 +	// read the global meshes that were stored outside of any node
 293.146 +	if( pData->mGlobalMeshes.size() > 0)
 293.147 +	{
 293.148 +		// create a root node to hold them if there isn't any, yet
 293.149 +		if( pScene->mRootNode == NULL)
 293.150 +		{
 293.151 +			pScene->mRootNode = new aiNode;
 293.152 +			pScene->mRootNode->mName.Set( "$dummy_node");
 293.153 +		}
 293.154 +
 293.155 +		// convert all global meshes and store them in the root node.
 293.156 +		// If there was one before, the global meshes now suddenly have its transformation matrix...
 293.157 +		// Don't know what to do there, I don't want to insert another node under the present root node
 293.158 +		// just to avoid this.
 293.159 +		CreateMeshes( pScene, pScene->mRootNode, pData->mGlobalMeshes);
 293.160 +	}
 293.161 +
 293.162 +	// Convert everything to OpenGL space... it's the same operation as the conversion back, so we can reuse the step directly
 293.163 +	MakeLeftHandedProcess convertProcess;
 293.164 +	convertProcess.Execute( pScene);
 293.165 +
 293.166 +	FlipWindingOrderProcess flipper;
 293.167 +	flipper.Execute(pScene);
 293.168 +
 293.169 +	// finally: create a dummy material if not material was imported
 293.170 +	if( pScene->mNumMaterials == 0)
 293.171 +	{
 293.172 +		pScene->mNumMaterials = 1;
 293.173 +		// create the Material
 293.174 +		aiMaterial* mat = new aiMaterial;
 293.175 +		int shadeMode = (int) aiShadingMode_Gouraud;
 293.176 +		mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
 293.177 +		// material colours
 293.178 +		int specExp = 1;
 293.179 +
 293.180 +		aiColor3D clr = aiColor3D( 0, 0, 0);
 293.181 +		mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_EMISSIVE);
 293.182 +		mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_SPECULAR);
 293.183 +
 293.184 +		clr = aiColor3D( 0.5f, 0.5f, 0.5f);
 293.185 +		mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_DIFFUSE);
 293.186 +		mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS);
 293.187 +
 293.188 +		pScene->mMaterials = new aiMaterial*[1];
 293.189 +		pScene->mMaterials[0] = mat;
 293.190 +	}
 293.191 +}
 293.192 +
 293.193 +// ------------------------------------------------------------------------------------------------
 293.194 +// Recursively creates scene nodes from the imported hierarchy. 
 293.195 +aiNode* XFileImporter::CreateNodes( aiScene* pScene, aiNode* pParent, const XFile::Node* pNode)
 293.196 +{
 293.197 +	if( !pNode)
 293.198 +		return NULL;
 293.199 +
 293.200 +	// create node
 293.201 +	aiNode* node = new aiNode;
 293.202 +	node->mName.length = pNode->mName.length();
 293.203 +	node->mParent = pParent;
 293.204 +	memcpy( node->mName.data, pNode->mName.c_str(), pNode->mName.length());
 293.205 +	node->mName.data[node->mName.length] = 0;
 293.206 +	node->mTransformation = pNode->mTrafoMatrix;
 293.207 +
 293.208 +	// convert meshes from the source node 
 293.209 +	CreateMeshes( pScene, node, pNode->mMeshes);
 293.210 +
 293.211 +	// handle childs
 293.212 +	if( pNode->mChildren.size() > 0)
 293.213 +	{
 293.214 +		node->mNumChildren = (unsigned int)pNode->mChildren.size();
 293.215 +		node->mChildren = new aiNode* [node->mNumChildren];
 293.216 +
 293.217 +		for( unsigned int a = 0; a < pNode->mChildren.size(); a++)
 293.218 +			node->mChildren[a] = CreateNodes( pScene, node, pNode->mChildren[a]);
 293.219 +	}
 293.220 +
 293.221 +	return node;
 293.222 +}
 293.223 +
 293.224 +// ------------------------------------------------------------------------------------------------
 293.225 +// Creates the meshes for the given node. 
 293.226 +void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vector<XFile::Mesh*>& pMeshes)
 293.227 +{
 293.228 +	if( pMeshes.size() == 0)
 293.229 +		return;
 293.230 +
 293.231 +	// create a mesh for each mesh-material combination in the source node
 293.232 +	std::vector<aiMesh*> meshes;
 293.233 +	for( unsigned int a = 0; a < pMeshes.size(); a++)
 293.234 +	{
 293.235 +		XFile::Mesh* sourceMesh = pMeshes[a];
 293.236 +		// first convert its materials so that we can find them with their index afterwards
 293.237 +		ConvertMaterials( pScene, sourceMesh->mMaterials);
 293.238 +
 293.239 +		unsigned int numMaterials = std::max( (unsigned int)sourceMesh->mMaterials.size(), 1u);
 293.240 +		for( unsigned int b = 0; b < numMaterials; b++)
 293.241 +		{
 293.242 +			// collect the faces belonging to this material
 293.243 +			std::vector<unsigned int> faces;
 293.244 +			unsigned int numVertices = 0;
 293.245 +			if( sourceMesh->mFaceMaterials.size() > 0)
 293.246 +			{
 293.247 +				// if there is a per-face material defined, select the faces with the corresponding material
 293.248 +				for( unsigned int c = 0; c < sourceMesh->mFaceMaterials.size(); c++)
 293.249 +				{
 293.250 +					if( sourceMesh->mFaceMaterials[c] == b)
 293.251 +					{
 293.252 +						faces.push_back( c);
 293.253 +						numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size();
 293.254 +					}
 293.255 +				}
 293.256 +			} else
 293.257 +			{
 293.258 +				// if there is no per-face material, place everything into one mesh
 293.259 +				for( unsigned int c = 0; c < sourceMesh->mPosFaces.size(); c++)
 293.260 +				{
 293.261 +					faces.push_back( c);
 293.262 +					numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size();
 293.263 +				}
 293.264 +			}
 293.265 +
 293.266 +			// no faces/vertices using this material? strange...
 293.267 +			if( numVertices == 0)
 293.268 +				continue;
 293.269 +
 293.270 +			// create a submesh using this material
 293.271 +			aiMesh* mesh = new aiMesh;
 293.272 +			meshes.push_back( mesh);
 293.273 +
 293.274 +			// find the material in the scene's material list. Either own material
 293.275 +			// or referenced material, it should already have a valid index
 293.276 +			if( sourceMesh->mFaceMaterials.size() > 0)
 293.277 +			{
 293.278 +        mesh->mMaterialIndex = sourceMesh->mMaterials[b].sceneIndex;
 293.279 +			} else
 293.280 +			{
 293.281 +				mesh->mMaterialIndex = 0;
 293.282 +			}
 293.283 +
 293.284 +			// Create properly sized data arrays in the mesh. We store unique vertices per face,
 293.285 +			// as specified 
 293.286 +			mesh->mNumVertices = numVertices;
 293.287 +			mesh->mVertices = new aiVector3D[numVertices];
 293.288 +			mesh->mNumFaces = (unsigned int)faces.size();
 293.289 +			mesh->mFaces = new aiFace[mesh->mNumFaces];
 293.290 +
 293.291 +			// normals?
 293.292 +			if( sourceMesh->mNormals.size() > 0)
 293.293 +				mesh->mNormals = new aiVector3D[numVertices];
 293.294 +			// texture coords
 293.295 +			for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; c++)
 293.296 +			{
 293.297 +				if( sourceMesh->mTexCoords[c].size() > 0)
 293.298 +					mesh->mTextureCoords[c] = new aiVector3D[numVertices];
 293.299 +			}
 293.300 +			// vertex colors
 293.301 +			for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; c++)
 293.302 +			{
 293.303 +				if( sourceMesh->mColors[c].size() > 0)
 293.304 +					mesh->mColors[c] = new aiColor4D[numVertices];
 293.305 +			}
 293.306 +
 293.307 +			// now collect the vertex data of all data streams present in the imported mesh
 293.308 +			unsigned int newIndex = 0;
 293.309 +			std::vector<unsigned int> orgPoints; // from which original point each new vertex stems
 293.310 +			orgPoints.resize( numVertices, 0);
 293.311 +
 293.312 +			for( unsigned int c = 0; c < faces.size(); c++)
 293.313 +			{
 293.314 +				unsigned int f = faces[c]; // index of the source face
 293.315 +				const XFile::Face& pf = sourceMesh->mPosFaces[f]; // position source face
 293.316 +
 293.317 +				// create face. either triangle or triangle fan depending on the index count
 293.318 +				aiFace& df = mesh->mFaces[c]; // destination face
 293.319 +				df.mNumIndices = (unsigned int)pf.mIndices.size();
 293.320 +				df.mIndices = new unsigned int[ df.mNumIndices];
 293.321 +
 293.322 +				// collect vertex data for indices of this face
 293.323 +				for( unsigned int d = 0; d < df.mNumIndices; d++)
 293.324 +				{
 293.325 +					df.mIndices[d] = newIndex; 
 293.326 +					orgPoints[newIndex] = pf.mIndices[d];
 293.327 +
 293.328 +					// Position
 293.329 +					mesh->mVertices[newIndex] = sourceMesh->mPositions[pf.mIndices[d]];
 293.330 +					// Normal, if present
 293.331 +					if( mesh->HasNormals())
 293.332 +						mesh->mNormals[newIndex] = sourceMesh->mNormals[sourceMesh->mNormFaces[f].mIndices[d]];
 293.333 +
 293.334 +					// texture coord sets
 293.335 +					for( unsigned int e = 0; e < AI_MAX_NUMBER_OF_TEXTURECOORDS; e++)
 293.336 +					{
 293.337 +						if( mesh->HasTextureCoords( e))
 293.338 +						{
 293.339 +							aiVector2D tex = sourceMesh->mTexCoords[e][pf.mIndices[d]];
 293.340 +							mesh->mTextureCoords[e][newIndex] = aiVector3D( tex.x, 1.0f - tex.y, 0.0f);
 293.341 +						}
 293.342 +					}
 293.343 +					// vertex color sets
 293.344 +					for( unsigned int e = 0; e < AI_MAX_NUMBER_OF_COLOR_SETS; e++)
 293.345 +						if( mesh->HasVertexColors( e))
 293.346 +							mesh->mColors[e][newIndex] = sourceMesh->mColors[e][pf.mIndices[d]];
 293.347 +
 293.348 +					newIndex++;
 293.349 +				}
 293.350 +			}
 293.351 +
 293.352 +			// there should be as much new vertices as we calculated before
 293.353 +			ai_assert( newIndex == numVertices);
 293.354 +
 293.355 +			// convert all bones of the source mesh which influence vertices in this newly created mesh
 293.356 +			const std::vector<XFile::Bone>& bones = sourceMesh->mBones;
 293.357 +			std::vector<aiBone*> newBones;
 293.358 +			for( unsigned int c = 0; c < bones.size(); c++)
 293.359 +			{
 293.360 +				const XFile::Bone& obone = bones[c];
 293.361 +				// set up a vertex-linear array of the weights for quick searching if a bone influences a vertex
 293.362 +				std::vector<float> oldWeights( sourceMesh->mPositions.size(), 0.0f);
 293.363 +				for( unsigned int d = 0; d < obone.mWeights.size(); d++)
 293.364 +					oldWeights[obone.mWeights[d].mVertex] = obone.mWeights[d].mWeight;
 293.365 +
 293.366 +				// collect all vertex weights that influence a vertex in the new mesh
 293.367 +				std::vector<aiVertexWeight> newWeights;
 293.368 +				newWeights.reserve( numVertices);
 293.369 +				for( unsigned int d = 0; d < orgPoints.size(); d++)
 293.370 +				{
 293.371 +					// does the new vertex stem from an old vertex which was influenced by this bone?
 293.372 +					float w = oldWeights[orgPoints[d]];
 293.373 +					if( w > 0.0f)
 293.374 +						newWeights.push_back( aiVertexWeight( d, w));
 293.375 +				}
 293.376 +
 293.377 +				// if the bone has no weights in the newly created mesh, ignore it
 293.378 +				if( newWeights.size() == 0)
 293.379 +					continue;
 293.380 +
 293.381 +				// create
 293.382 +				aiBone* nbone = new aiBone;
 293.383 +				newBones.push_back( nbone);
 293.384 +				// copy name and matrix
 293.385 +				nbone->mName.Set( obone.mName);
 293.386 +				nbone->mOffsetMatrix = obone.mOffsetMatrix;
 293.387 +				nbone->mNumWeights = (unsigned int)newWeights.size();
 293.388 +				nbone->mWeights = new aiVertexWeight[nbone->mNumWeights];
 293.389 +				for( unsigned int d = 0; d < newWeights.size(); d++)
 293.390 +					nbone->mWeights[d] = newWeights[d];
 293.391 +			}
 293.392 +
 293.393 +			// store the bones in the mesh
 293.394 +			mesh->mNumBones = (unsigned int)newBones.size();
 293.395 +			if( newBones.size() > 0)
 293.396 +			{
 293.397 +				mesh->mBones = new aiBone*[mesh->mNumBones];
 293.398 +				std::copy( newBones.begin(), newBones.end(), mesh->mBones);
 293.399 +			}
 293.400 +		}
 293.401 +	}
 293.402 +
 293.403 +	// reallocate scene mesh array to be large enough
 293.404 +	aiMesh** prevArray = pScene->mMeshes;
 293.405 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes + meshes.size()];
 293.406 +	if( prevArray)
 293.407 +	{
 293.408 +		memcpy( pScene->mMeshes, prevArray, pScene->mNumMeshes * sizeof( aiMesh*));
 293.409 +		delete [] prevArray;
 293.410 +	}
 293.411 +
 293.412 +	// allocate mesh index array in the node
 293.413 +	pNode->mNumMeshes = (unsigned int)meshes.size();
 293.414 +	pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
 293.415 +
 293.416 +	// store all meshes in the mesh library of the scene and store their indices in the node
 293.417 +	for( unsigned int a = 0; a < meshes.size(); a++)
 293.418 +	{
 293.419 +		pScene->mMeshes[pScene->mNumMeshes] = meshes[a];		
 293.420 +		pNode->mMeshes[a] = pScene->mNumMeshes;
 293.421 +		pScene->mNumMeshes++;
 293.422 +	}
 293.423 +}
 293.424 +
 293.425 +// ------------------------------------------------------------------------------------------------
 293.426 +// Converts the animations from the given imported data and creates them in the scene.
 293.427 +void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData)
 293.428 +{
 293.429 +	std::vector<aiAnimation*> newAnims;
 293.430 +
 293.431 +	for( unsigned int a = 0; a < pData->mAnims.size(); a++)
 293.432 +	{
 293.433 +		const XFile::Animation* anim = pData->mAnims[a];
 293.434 +		// some exporters mock me with empty animation tags.
 293.435 +		if( anim->mAnims.size() == 0)
 293.436 +			continue;
 293.437 +
 293.438 +		// create a new animation to hold the data
 293.439 +		aiAnimation* nanim = new aiAnimation;
 293.440 +		newAnims.push_back( nanim);
 293.441 +		nanim->mName.Set( anim->mName);
 293.442 +		// duration will be determined by the maximum length
 293.443 +		nanim->mDuration = 0;
 293.444 +		nanim->mTicksPerSecond = pData->mAnimTicksPerSecond;
 293.445 +		nanim->mNumChannels = (unsigned int)anim->mAnims.size();
 293.446 +		nanim->mChannels = new aiNodeAnim*[nanim->mNumChannels];
 293.447 +
 293.448 +		for( unsigned int b = 0; b < anim->mAnims.size(); b++)
 293.449 +		{
 293.450 +			const XFile::AnimBone* bone = anim->mAnims[b];
 293.451 +			aiNodeAnim* nbone = new aiNodeAnim;
 293.452 +			nbone->mNodeName.Set( bone->mBoneName);
 293.453 +			nanim->mChannels[b] = nbone;
 293.454 +
 293.455 +			// keyframes are given as combined transformation matrix keys
 293.456 +			if( bone->mTrafoKeys.size() > 0)
 293.457 +			{
 293.458 +				nbone->mNumPositionKeys = (unsigned int)bone->mTrafoKeys.size();
 293.459 +				nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys];
 293.460 +				nbone->mNumRotationKeys = (unsigned int)bone->mTrafoKeys.size();
 293.461 +				nbone->mRotationKeys = new aiQuatKey[nbone->mNumRotationKeys];
 293.462 +				nbone->mNumScalingKeys = (unsigned int)bone->mTrafoKeys.size();
 293.463 +				nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys];
 293.464 +
 293.465 +				for( unsigned int c = 0; c < bone->mTrafoKeys.size(); c++)
 293.466 +				{
 293.467 +					// deconstruct each matrix into separate position, rotation and scaling
 293.468 +					double time = bone->mTrafoKeys[c].mTime;
 293.469 +					aiMatrix4x4 trafo = bone->mTrafoKeys[c].mMatrix;
 293.470 +
 293.471 +					// extract position
 293.472 +					aiVector3D pos( trafo.a4, trafo.b4, trafo.c4);
 293.473 +
 293.474 +					nbone->mPositionKeys[c].mTime = time;
 293.475 +					nbone->mPositionKeys[c].mValue = pos;
 293.476 +
 293.477 +					// extract scaling
 293.478 +					aiVector3D scale;
 293.479 +					scale.x = aiVector3D( trafo.a1, trafo.b1, trafo.c1).Length();
 293.480 +					scale.y = aiVector3D( trafo.a2, trafo.b2, trafo.c2).Length();
 293.481 +					scale.z = aiVector3D( trafo.a3, trafo.b3, trafo.c3).Length();
 293.482 +					nbone->mScalingKeys[c].mTime = time;
 293.483 +					nbone->mScalingKeys[c].mValue = scale;
 293.484 +
 293.485 +					// reconstruct rotation matrix without scaling
 293.486 +					aiMatrix3x3 rotmat( 
 293.487 +						trafo.a1 / scale.x, trafo.a2 / scale.y, trafo.a3 / scale.z,
 293.488 +						trafo.b1 / scale.x, trafo.b2 / scale.y, trafo.b3 / scale.z,
 293.489 +						trafo.c1 / scale.x, trafo.c2 / scale.y, trafo.c3 / scale.z);
 293.490 +
 293.491 +					// and convert it into a quaternion
 293.492 +					nbone->mRotationKeys[c].mTime = time;
 293.493 +					nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat);
 293.494 +				}
 293.495 +
 293.496 +				// longest lasting key sequence determines duration
 293.497 +				nanim->mDuration = std::max( nanim->mDuration, bone->mTrafoKeys.back().mTime);
 293.498 +			} else
 293.499 +			{
 293.500 +				// separate key sequences for position, rotation, scaling
 293.501 +				nbone->mNumPositionKeys = (unsigned int)bone->mPosKeys.size(); 
 293.502 +				nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys];
 293.503 +				for( unsigned int c = 0; c < nbone->mNumPositionKeys; c++)
 293.504 +				{
 293.505 +					aiVector3D pos = bone->mPosKeys[c].mValue;
 293.506 +
 293.507 +					nbone->mPositionKeys[c].mTime = bone->mPosKeys[c].mTime;
 293.508 +					nbone->mPositionKeys[c].mValue = pos;
 293.509 +				}
 293.510 +
 293.511 +				// rotation
 293.512 +				nbone->mNumRotationKeys = (unsigned int)bone->mRotKeys.size(); 
 293.513 +				nbone->mRotationKeys = new aiQuatKey[nbone->mNumRotationKeys];
 293.514 +				for( unsigned int c = 0; c < nbone->mNumRotationKeys; c++)
 293.515 +				{
 293.516 +					aiMatrix3x3 rotmat = bone->mRotKeys[c].mValue.GetMatrix();
 293.517 +
 293.518 +					nbone->mRotationKeys[c].mTime = bone->mRotKeys[c].mTime;
 293.519 +					nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat);
 293.520 +					nbone->mRotationKeys[c].mValue.w *= -1.0f; // needs quat inversion
 293.521 +				}
 293.522 +
 293.523 +				// scaling
 293.524 +				nbone->mNumScalingKeys = (unsigned int)bone->mScaleKeys.size(); 
 293.525 +				nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys];
 293.526 +				for( unsigned int c = 0; c < nbone->mNumScalingKeys; c++)
 293.527 +					nbone->mScalingKeys[c] = bone->mScaleKeys[c];
 293.528 +
 293.529 +				// longest lasting key sequence determines duration
 293.530 +				if( bone->mPosKeys.size() > 0)
 293.531 +					nanim->mDuration = std::max( nanim->mDuration, bone->mPosKeys.back().mTime);
 293.532 +				if( bone->mRotKeys.size() > 0)
 293.533 +					nanim->mDuration = std::max( nanim->mDuration, bone->mRotKeys.back().mTime);
 293.534 +				if( bone->mScaleKeys.size() > 0)
 293.535 +					nanim->mDuration = std::max( nanim->mDuration, bone->mScaleKeys.back().mTime);
 293.536 +			}
 293.537 +		}
 293.538 +	}
 293.539 +
 293.540 +	// store all converted animations in the scene
 293.541 +	if( newAnims.size() > 0)
 293.542 +	{
 293.543 +		pScene->mNumAnimations = (unsigned int)newAnims.size();
 293.544 +		pScene->mAnimations = new aiAnimation* [pScene->mNumAnimations];
 293.545 +		for( unsigned int a = 0; a < newAnims.size(); a++)
 293.546 +			pScene->mAnimations[a] = newAnims[a];
 293.547 +	}
 293.548 +}
 293.549 +
 293.550 +// ------------------------------------------------------------------------------------------------
 293.551 +// Converts all materials in the given array and stores them in the scene's material list.
 293.552 +void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Material>& pMaterials)
 293.553 +{
 293.554 +	// count the non-referrer materials in the array
 293.555 +	unsigned int numNewMaterials = 0;
 293.556 +	for( unsigned int a = 0; a < pMaterials.size(); a++)
 293.557 +		if( !pMaterials[a].mIsReference)
 293.558 +			numNewMaterials++;
 293.559 +
 293.560 +	// resize the scene's material list to offer enough space for the new materials
 293.561 +  if( numNewMaterials > 0 )
 293.562 +  {
 293.563 +	  aiMaterial** prevMats = pScene->mMaterials;
 293.564 +	  pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials + numNewMaterials];
 293.565 +	  if( prevMats)
 293.566 +	  {
 293.567 +		  memcpy( pScene->mMaterials, prevMats, pScene->mNumMaterials * sizeof( aiMaterial*));
 293.568 +		  delete [] prevMats;
 293.569 +	  }
 293.570 +  }
 293.571 +
 293.572 +	// convert all the materials given in the array
 293.573 +	for( unsigned int a = 0; a < pMaterials.size(); a++)
 293.574 +	{
 293.575 +		XFile::Material& oldMat = pMaterials[a];
 293.576 +		if( oldMat.mIsReference)
 293.577 +    {
 293.578 +      // find the material it refers to by name, and store its index
 293.579 +      for( size_t a = 0; a < pScene->mNumMaterials; ++a )
 293.580 +      {
 293.581 +        aiString name;
 293.582 +        pScene->mMaterials[a]->Get( AI_MATKEY_NAME, name);
 293.583 +        if( strcmp( name.C_Str(), oldMat.mName.data()) == 0 )
 293.584 +        {
 293.585 +          oldMat.sceneIndex = a;
 293.586 +          break;
 293.587 +        }
 293.588 +      }
 293.589 +
 293.590 +      if( oldMat.sceneIndex == SIZE_MAX )
 293.591 +      {
 293.592 +        DefaultLogger::get()->warn( boost::str( boost::format( "Could not resolve global material reference \"%s\"") % oldMat.mName));
 293.593 +        oldMat.sceneIndex = 0;
 293.594 +      }
 293.595 +
 293.596 +      continue;
 293.597 +    }
 293.598 +
 293.599 +		aiMaterial* mat = new aiMaterial;
 293.600 +		aiString name;
 293.601 +		name.Set( oldMat.mName);
 293.602 +		mat->AddProperty( &name, AI_MATKEY_NAME);
 293.603 +
 293.604 +		// Shading model: hardcoded to PHONG, there is no such information in an XFile
 293.605 +		// FIX (aramis): If the specular exponent is 0, use gouraud shading. This is a bugfix
 293.606 +		// for some models in the SDK (e.g. good old tiny.x)
 293.607 +		int shadeMode = (int)oldMat.mSpecularExponent == 0.0f 
 293.608 +			? aiShadingMode_Gouraud : aiShadingMode_Phong;
 293.609 +
 293.610 +		mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
 293.611 +		// material colours
 293.612 +    // Unclear: there's no ambient colour, but emissive. What to put for ambient?
 293.613 +    // Probably nothing at all, let the user select a suitable default.
 293.614 +		mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
 293.615 +		mat->AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
 293.616 +		mat->AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
 293.617 +		mat->AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
 293.618 +
 293.619 +
 293.620 +		// texture, if there is one
 293.621 +		if (1 == oldMat.mTextures.size())
 293.622 +		{
 293.623 +			const XFile::TexEntry& otex = oldMat.mTextures.back();
 293.624 +			if (otex.mName.length())
 293.625 +			{
 293.626 +				// if there is only one texture assume it contains the diffuse color
 293.627 +				aiString tex( otex.mName);
 293.628 +				if( otex.mIsNormalMap)
 293.629 +					mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(0));
 293.630 +				else
 293.631 +					mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
 293.632 +			}
 293.633 +		}
 293.634 +		else
 293.635 +		{
 293.636 +			// Otherwise ... try to search for typical strings in the
 293.637 +			// texture's file name like 'bump' or 'diffuse'
 293.638 +			unsigned int iHM = 0,iNM = 0,iDM = 0,iSM = 0,iAM = 0,iEM = 0;
 293.639 +			for( unsigned int b = 0; b < oldMat.mTextures.size(); b++)
 293.640 +			{
 293.641 +				const XFile::TexEntry& otex = oldMat.mTextures[b];
 293.642 +				std::string sz = otex.mName;
 293.643 +				if (!sz.length())continue;
 293.644 +
 293.645 +
 293.646 +				// find the file name
 293.647 +				//const size_t iLen = sz.length();
 293.648 +				std::string::size_type s = sz.find_last_of("\\/");
 293.649 +				if (std::string::npos == s)
 293.650 +					s = 0;
 293.651 +
 293.652 +				// cut off the file extension
 293.653 +				std::string::size_type sExt = sz.find_last_of('.');
 293.654 +				if (std::string::npos != sExt){
 293.655 +					sz[sExt] = '\0';
 293.656 +				}
 293.657 +
 293.658 +				// convert to lower case for easier comparision
 293.659 +				for( unsigned int c = 0; c < sz.length(); c++)
 293.660 +					if( isalpha( sz[c]))
 293.661 +						sz[c] = tolower( sz[c]);
 293.662 +
 293.663 +
 293.664 +				// Place texture filename property under the corresponding name
 293.665 +				aiString tex( oldMat.mTextures[b].mName);
 293.666 +
 293.667 +				// bump map
 293.668 +				if (std::string::npos != sz.find("bump", s) || std::string::npos != sz.find("height", s))
 293.669 +				{
 293.670 +					mat->AddProperty( &tex, AI_MATKEY_TEXTURE_HEIGHT(iHM++));
 293.671 +				} else
 293.672 +				if (otex.mIsNormalMap || std::string::npos != sz.find( "normal", s) || std::string::npos != sz.find("nm", s))
 293.673 +				{
 293.674 +					mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(iNM++));
 293.675 +				} else
 293.676 +				if (std::string::npos != sz.find( "spec", s) || std::string::npos != sz.find( "glanz", s))
 293.677 +				{
 293.678 +					mat->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR(iSM++));
 293.679 +				} else
 293.680 +				if (std::string::npos != sz.find( "ambi", s) || std::string::npos != sz.find( "env", s))
 293.681 +				{
 293.682 +					mat->AddProperty( &tex, AI_MATKEY_TEXTURE_AMBIENT(iAM++));
 293.683 +				} else
 293.684 +				if (std::string::npos != sz.find( "emissive", s) || std::string::npos != sz.find( "self", s))
 293.685 +				{
 293.686 +					mat->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE(iEM++));
 293.687 +				} else
 293.688 +				{
 293.689 +					// Assume it is a diffuse texture
 293.690 +					mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(iDM++));
 293.691 +				}
 293.692 +			}
 293.693 +		}
 293.694 +
 293.695 +		pScene->mMaterials[pScene->mNumMaterials] = mat;
 293.696 +		oldMat.sceneIndex = pScene->mNumMaterials;
 293.697 +		pScene->mNumMaterials++;
 293.698 +	}
 293.699 +}
 293.700 +
 293.701 +#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
 293.702 +
   294.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   294.2 +++ b/libs/assimp/XFileImporter.h	Sat Feb 01 19:58:19 2014 +0200
   294.3 @@ -0,0 +1,150 @@
   294.4 +/*
   294.5 +Open Asset Import Library (assimp)
   294.6 +----------------------------------------------------------------------
   294.7 +
   294.8 +Copyright (c) 2006-2012, assimp team
   294.9 +All rights reserved.
  294.10 +
  294.11 +Redistribution and use of this software in source and binary forms, 
  294.12 +with or without modification, are permitted provided that the 
  294.13 +following conditions are met:
  294.14 +
  294.15 +* Redistributions of source code must retain the above
  294.16 +  copyright notice, this list of conditions and the
  294.17 +  following disclaimer.
  294.18 +
  294.19 +* Redistributions in binary form must reproduce the above
  294.20 +  copyright notice, this list of conditions and the
  294.21 +  following disclaimer in the documentation and/or other
  294.22 +  materials provided with the distribution.
  294.23 +
  294.24 +* Neither the name of the assimp team, nor the names of its
  294.25 +  contributors may be used to endorse or promote products
  294.26 +  derived from this software without specific prior
  294.27 +  written permission of the assimp team.
  294.28 +
  294.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  294.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  294.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  294.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  294.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  294.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  294.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  294.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  294.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  294.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  294.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  294.40 +
  294.41 +----------------------------------------------------------------------
  294.42 +*/
  294.43 +
  294.44 +/** @file  XFileImporter.h 
  294.45 + *  @brief Definition of the XFile importer class. 
  294.46 + */
  294.47 +#ifndef AI_XFILEIMPORTER_H_INC
  294.48 +#define AI_XFILEIMPORTER_H_INC
  294.49 +
  294.50 +#include <map>
  294.51 +
  294.52 +#include "XFileHelper.h"
  294.53 +#include "BaseImporter.h"
  294.54 +
  294.55 +#include "assimp/types.h"
  294.56 +
  294.57 +struct aiNode;
  294.58 +
  294.59 +namespace Assimp	{
  294.60 +
  294.61 +namespace XFile {
  294.62 +struct Scene;
  294.63 +struct Node;
  294.64 +}
  294.65 +
  294.66 +// ---------------------------------------------------------------------------
  294.67 +/** The XFileImporter is a worker class capable of importing a scene from a
  294.68 + * DirectX file .x
  294.69 + */
  294.70 +class XFileImporter : public BaseImporter
  294.71 +{
  294.72 +public:
  294.73 +	XFileImporter();
  294.74 +	~XFileImporter();
  294.75 +
  294.76 +
  294.77 +public:
  294.78 +	// -------------------------------------------------------------------
  294.79 +	/** Returns whether the class can handle the format of the given file. 
  294.80 +	 * See BaseImporter::CanRead() for details.	*/
  294.81 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  294.82 +		bool CheckSig) const;
  294.83 +
  294.84 +protected:
  294.85 +
  294.86 +	// -------------------------------------------------------------------
  294.87 +	/** Return importer meta information.
  294.88 +	 * See #BaseImporter::GetInfo for the details
  294.89 +	 */
  294.90 +	const aiImporterDesc* GetInfo () const;
  294.91 +
  294.92 +	// -------------------------------------------------------------------
  294.93 +	/** Imports the given file into the given scene structure. 
  294.94 +	 * See BaseImporter::InternReadFile() for details
  294.95 +	 */
  294.96 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  294.97 +		IOSystem* pIOHandler);
  294.98 +
  294.99 +	// -------------------------------------------------------------------
 294.100 +	/** Constructs the return data structure out of the imported data.
 294.101 +	 * @param pScene The scene to construct the return data in.
 294.102 +	 * @param pData The imported data in the internal temporary 
 294.103 +	 *   representation.
 294.104 +	 */
 294.105 +	void CreateDataRepresentationFromImport( aiScene* pScene, XFile::Scene* pData);
 294.106 +
 294.107 +	// -------------------------------------------------------------------
 294.108 +	/** Recursively creates scene nodes from the imported hierarchy.
 294.109 +	 * The meshes and materials of the nodes will be extracted on the way.
 294.110 +	 * @param pScene The scene to construct the return data in.
 294.111 +	 * @param pParent The parent node where to create new child nodes
 294.112 +	 * @param pNode The temporary node to copy.
 294.113 +	 * @return The created node 
 294.114 +	 */
 294.115 +	aiNode* CreateNodes( aiScene* pScene, aiNode* pParent, 
 294.116 +		const XFile::Node* pNode);
 294.117 +
 294.118 +	// -------------------------------------------------------------------
 294.119 +	/** Converts all meshes in the given mesh array. Each mesh is split 
 294.120 +	 * up per material, the indices of the generated meshes are stored in 
 294.121 +	 * the node structure.
 294.122 +	 * @param pScene The scene to construct the return data in.
 294.123 +	 * @param pNode The target node structure that references the
 294.124 +	 *   constructed meshes.
 294.125 +	 * @param pMeshes The array of meshes to convert
 294.126 +	 */
 294.127 +	void CreateMeshes( aiScene* pScene, aiNode* pNode, 
 294.128 +		const std::vector<XFile::Mesh*>& pMeshes);
 294.129 +
 294.130 +	// -------------------------------------------------------------------
 294.131 +	/** Converts the animations from the given imported data and creates 
 294.132 +	*  them in the scene.
 294.133 +	 * @param pScene The scene to hold to converted animations
 294.134 +	 * @param pData The data to read the animations from
 294.135 +	 */
 294.136 +	void CreateAnimations( aiScene* pScene, const XFile::Scene* pData);
 294.137 +
 294.138 +	// -------------------------------------------------------------------
 294.139 +	/** Converts all materials in the given array and stores them in the
 294.140 +	 *  scene's material list.
 294.141 +	 * @param pScene The scene to hold the converted materials.
 294.142 +	 * @param pMaterials The material array to convert.
 294.143 +	 */
 294.144 +	void ConvertMaterials( aiScene* pScene, std::vector<XFile::Material>& pMaterials);
 294.145 +
 294.146 +protected:
 294.147 +	/** Buffer to hold the loaded file */
 294.148 +	std::vector<char> mBuffer;
 294.149 +};
 294.150 +
 294.151 +} // end of namespace Assimp
 294.152 +
 294.153 +#endif // AI_BASEIMPORTER_H_INC
   295.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   295.2 +++ b/libs/assimp/XFileParser.cpp	Sat Feb 01 19:58:19 2014 +0200
   295.3 @@ -0,0 +1,1468 @@
   295.4 +/*
   295.5 +---------------------------------------------------------------------------
   295.6 +Open Asset Import Library (assimp)
   295.7 +---------------------------------------------------------------------------
   295.8 +
   295.9 +Copyright (c) 2006-2012, assimp team
  295.10 +
  295.11 +All rights reserved.
  295.12 +
  295.13 +Redistribution and use of this software in source and binary forms, 
  295.14 +with or without modification, are permitted provided that the following 
  295.15 +conditions are met:
  295.16 +
  295.17 +* Redistributions of source code must retain the above
  295.18 +  copyright notice, this list of conditions and the
  295.19 +  following disclaimer.
  295.20 +
  295.21 +* Redistributions in binary form must reproduce the above
  295.22 +  copyright notice, this list of conditions and the
  295.23 +  following disclaimer in the documentation and/or other
  295.24 +  materials provided with the distribution.
  295.25 +
  295.26 +* Neither the name of the assimp team, nor the names of its
  295.27 +  contributors may be used to endorse or promote products
  295.28 +  derived from this software without specific prior
  295.29 +  written permission of the assimp team.
  295.30 +
  295.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  295.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  295.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  295.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  295.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  295.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  295.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  295.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  295.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  295.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  295.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  295.42 +---------------------------------------------------------------------------
  295.43 +*/
  295.44 +
  295.45 +/** @file Implementation of the XFile parser helper class */
  295.46 +
  295.47 +#include "AssimpPCH.h"
  295.48 +#ifndef ASSIMP_BUILD_NO_X_IMPORTER
  295.49 +
  295.50 +#include "XFileParser.h"
  295.51 +#include "XFileHelper.h"
  295.52 +#include "fast_atof.h"
  295.53 +
  295.54 +using namespace Assimp;
  295.55 +using namespace Assimp::XFile;
  295.56 +
  295.57 +#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
  295.58 +
  295.59 +#	ifdef ASSIMP_BUILD_NO_OWN_ZLIB
  295.60 +#		include <zlib.h>
  295.61 +#	else
  295.62 +#		include "../contrib/zlib/zlib.h"
  295.63 +#	endif
  295.64 +
  295.65 +// Magic identifier for MSZIP compressed data
  295.66 +#define MSZIP_MAGIC 0x4B43
  295.67 +#define MSZIP_BLOCK 32786
  295.68 +
  295.69 +// ------------------------------------------------------------------------------------------------
  295.70 +// Dummy memory wrappers for use with zlib
  295.71 +static void* dummy_alloc (void* /*opaque*/, unsigned int items, unsigned int size)	{
  295.72 +	return ::operator new(items*size);
  295.73 +}
  295.74 +
  295.75 +static void  dummy_free  (void* /*opaque*/, void* address)	{
  295.76 +	return ::operator delete(address);
  295.77 +}
  295.78 +
  295.79 +#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
  295.80 +
  295.81 +// ------------------------------------------------------------------------------------------------
  295.82 +// Constructor. Creates a data structure out of the XFile given in the memory block. 
  295.83 +XFileParser::XFileParser( const std::vector<char>& pBuffer)
  295.84 +{
  295.85 +	mMajorVersion = mMinorVersion = 0;
  295.86 +	mIsBinaryFormat = false;
  295.87 +	mBinaryNumCount = 0;
  295.88 +	P = End = NULL;
  295.89 +	mLineNumber = 0;
  295.90 +	mScene = NULL;
  295.91 +
  295.92 +	// vector to store uncompressed file for INFLATE'd X files
  295.93 +	std::vector<char> uncompressed;
  295.94 +
  295.95 +	// set up memory pointers
  295.96 +	P = &pBuffer.front();
  295.97 +	End = P + pBuffer.size() - 1;
  295.98 +
  295.99 +	// check header
 295.100 +	if( strncmp( P, "xof ", 4) != 0)
 295.101 +		throw DeadlyImportError( "Header mismatch, file is not an XFile.");
 295.102 +
 295.103 +	// read version. It comes in a four byte format such as "0302"
 295.104 +	mMajorVersion = (unsigned int)(P[4] - 48) * 10 + (unsigned int)(P[5] - 48);
 295.105 +	mMinorVersion = (unsigned int)(P[6] - 48) * 10 + (unsigned int)(P[7] - 48);
 295.106 +
 295.107 +	bool compressed = false;
 295.108 +
 295.109 +	// txt - pure ASCII text format
 295.110 +	if( strncmp( P + 8, "txt ", 4) == 0)
 295.111 +		mIsBinaryFormat = false;
 295.112 +
 295.113 +	// bin - Binary format
 295.114 +	else if( strncmp( P + 8, "bin ", 4) == 0)
 295.115 +		mIsBinaryFormat = true;
 295.116 +
 295.117 +	// tzip - Inflate compressed text format
 295.118 +	else if( strncmp( P + 8, "tzip", 4) == 0)
 295.119 +	{
 295.120 +		mIsBinaryFormat = false;
 295.121 +		compressed = true;
 295.122 +	}
 295.123 +	// bzip - Inflate compressed binary format
 295.124 +	else if( strncmp( P + 8, "bzip", 4) == 0)
 295.125 +	{
 295.126 +		mIsBinaryFormat = true;
 295.127 +		compressed = true;
 295.128 +	}
 295.129 +	else ThrowException( boost::str(boost::format("Unsupported xfile format '%c%c%c%c'") 
 295.130 +		% P[8] % P[9] % P[10] % P[11]));
 295.131 +
 295.132 +	// float size
 295.133 +	mBinaryFloatSize = (unsigned int)(P[12] - 48) * 1000
 295.134 +		+ (unsigned int)(P[13] - 48) * 100
 295.135 +		+ (unsigned int)(P[14] - 48) * 10
 295.136 +		+ (unsigned int)(P[15] - 48);
 295.137 +
 295.138 +	if( mBinaryFloatSize != 32 && mBinaryFloatSize != 64)
 295.139 +		ThrowException( boost::str( boost::format( "Unknown float size %1% specified in xfile header.")
 295.140 +			% mBinaryFloatSize));
 295.141 +
 295.142 +	P += 16;
 295.143 +
 295.144 +	// If this is a compressed X file, apply the inflate algorithm to it
 295.145 +	if (compressed)
 295.146 +	{
 295.147 +#ifdef ASSIMP_BUILD_NO_COMPRESSED_X
 295.148 +		throw DeadlyImportError("Assimp was built without compressed X support");
 295.149 +#else
 295.150 +		/* ///////////////////////////////////////////////////////////////////////  
 295.151 +		 * COMPRESSED X FILE FORMAT
 295.152 +		 * ///////////////////////////////////////////////////////////////////////
 295.153 +		 *    [xhead]
 295.154 +		 *    2 major
 295.155 +		 *    2 minor
 295.156 +		 *    4 type    // bzip,tzip
 295.157 +		 *    [mszip_master_head]
 295.158 +		 *    4 unkn    // checksum?
 295.159 +		 *    2 unkn    // flags? (seems to be constant)
 295.160 +		 *    [mszip_head]
 295.161 +		 *    2 ofs     // offset to next section
 295.162 +		 *    2 magic   // 'CK'
 295.163 +		 *    ... ofs bytes of data
 295.164 +		 *    ... next mszip_head
 295.165 +		 *
 295.166 +		 *  http://www.kdedevelopers.org/node/3181 has been very helpful.
 295.167 +		 * ///////////////////////////////////////////////////////////////////////
 295.168 +		 */
 295.169 +
 295.170 +		// build a zlib stream
 295.171 +		z_stream stream;
 295.172 +		stream.opaque = NULL;
 295.173 +		stream.zalloc = &dummy_alloc;
 295.174 +		stream.zfree  = &dummy_free;
 295.175 +		stream.data_type = (mIsBinaryFormat ? Z_BINARY : Z_ASCII);
 295.176 +
 295.177 +		// initialize the inflation algorithm
 295.178 +		::inflateInit2(&stream, -MAX_WBITS);
 295.179 +
 295.180 +		// skip unknown data (checksum, flags?)
 295.181 +		P += 6;
 295.182 +
 295.183 +		// First find out how much storage we'll need. Count sections.
 295.184 +		const char* P1       = P;
 295.185 +		unsigned int est_out = 0;
 295.186 +
 295.187 +		while (P1 + 3 < End)
 295.188 +		{
 295.189 +			// read next offset
 295.190 +			uint16_t ofs = *((uint16_t*)P1);
 295.191 +			AI_SWAP2(ofs); P1 += 2;
 295.192 +
 295.193 +			if (ofs >= MSZIP_BLOCK)
 295.194 +				throw DeadlyImportError("X: Invalid offset to next MSZIP compressed block");
 295.195 +
 295.196 +			// check magic word
 295.197 +			uint16_t magic = *((uint16_t*)P1);
 295.198 +			AI_SWAP2(magic); P1 += 2;
 295.199 +
 295.200 +			if (magic != MSZIP_MAGIC)
 295.201 +				throw DeadlyImportError("X: Unsupported compressed format, expected MSZIP header");
 295.202 +
 295.203 +			// and advance to the next offset
 295.204 +			P1 += ofs;
 295.205 +			est_out += MSZIP_BLOCK; // one decompressed block is 32786 in size
 295.206 +		}
 295.207 +		
 295.208 +		// Allocate storage and terminating zero and do the actual uncompressing
 295.209 +		uncompressed.resize(est_out + 1);
 295.210 +		char* out = &uncompressed.front();
 295.211 +		while (P + 3 < End)
 295.212 +		{
 295.213 +			uint16_t ofs = *((uint16_t*)P);
 295.214 +			AI_SWAP2(ofs); 
 295.215 +			P += 4;
 295.216 +
 295.217 +			// push data to the stream
 295.218 +			stream.next_in   = (Bytef*)P;
 295.219 +			stream.avail_in  = ofs;
 295.220 +			stream.next_out  = (Bytef*)out;
 295.221 +			stream.avail_out = MSZIP_BLOCK;
 295.222 +
 295.223 +			// and decompress the data ....
 295.224 +			int ret = ::inflate( &stream, Z_SYNC_FLUSH );
 295.225 +			if (ret != Z_OK && ret != Z_STREAM_END)
 295.226 +				throw DeadlyImportError("X: Failed to decompress MSZIP-compressed data");
 295.227 +
 295.228 +			::inflateReset( &stream );
 295.229 +			::inflateSetDictionary( &stream, (const Bytef*)out , MSZIP_BLOCK - stream.avail_out );
 295.230 +
 295.231 +			// and advance to the next offset
 295.232 +			out +=  MSZIP_BLOCK - stream.avail_out;
 295.233 +			P   += ofs;
 295.234 +		}
 295.235 +
 295.236 +		// terminate zlib
 295.237 +		::inflateEnd(&stream);
 295.238 +		
 295.239 +		// ok, update pointers to point to the uncompressed file data
 295.240 +		P = &uncompressed[0];
 295.241 +		End = out;
 295.242 +
 295.243 +		// FIXME: we don't need the compressed data anymore, could release
 295.244 +		// it already for better memory usage. Consider breaking const-co.
 295.245 +		DefaultLogger::get()->info("Successfully decompressed MSZIP-compressed file");
 295.246 +#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
 295.247 +	}
 295.248 +	else
 295.249 +	{
 295.250 +		// start reading here
 295.251 +		ReadUntilEndOfLine();
 295.252 +	}
 295.253 +
 295.254 +	mScene = new Scene;
 295.255 +	ParseFile();
 295.256 +
 295.257 +	// filter the imported hierarchy for some degenerated cases
 295.258 +	if( mScene->mRootNode) {
 295.259 +		FilterHierarchy( mScene->mRootNode);
 295.260 +	}
 295.261 +}
 295.262 +
 295.263 +// ------------------------------------------------------------------------------------------------
 295.264 +// Destructor. Destroys all imported data along with it 
 295.265 +XFileParser::~XFileParser()
 295.266 +{
 295.267 +	// kill everything we created
 295.268 +	delete mScene;
 295.269 +}
 295.270 +
 295.271 +// ------------------------------------------------------------------------------------------------
 295.272 +void XFileParser::ParseFile()
 295.273 +{
 295.274 +	bool running = true;
 295.275 +	while( running )
 295.276 +	{
 295.277 +		// read name of next object
 295.278 +		std::string objectName = GetNextToken();
 295.279 +		if (objectName.length() == 0)
 295.280 +			break;
 295.281 +
 295.282 +		// parse specific object
 295.283 +		if( objectName == "template")
 295.284 +			ParseDataObjectTemplate();
 295.285 +		else
 295.286 +		if( objectName == "Frame")
 295.287 +			ParseDataObjectFrame( NULL);
 295.288 +		else
 295.289 +		if( objectName == "Mesh")
 295.290 +		{
 295.291 +			// some meshes have no frames at all
 295.292 +			Mesh* mesh = new Mesh;
 295.293 +			ParseDataObjectMesh( mesh);
 295.294 +			mScene->mGlobalMeshes.push_back( mesh);
 295.295 +		} else
 295.296 +		if( objectName == "AnimTicksPerSecond")
 295.297 +			ParseDataObjectAnimTicksPerSecond();
 295.298 +		else
 295.299 +		if( objectName == "AnimationSet")
 295.300 +			ParseDataObjectAnimationSet();
 295.301 +		else
 295.302 +		if( objectName == "Material")
 295.303 +		{
 295.304 +			// Material outside of a mesh or node
 295.305 +			Material material; 
 295.306 +			ParseDataObjectMaterial( &material);
 295.307 +			mScene->mGlobalMaterials.push_back( material);
 295.308 +		} else
 295.309 +		if( objectName == "}")
 295.310 +		{
 295.311 +			// whatever?
 295.312 +			DefaultLogger::get()->warn("} found in dataObject");
 295.313 +		} else
 295.314 +		{
 295.315 +			// unknown format
 295.316 +			DefaultLogger::get()->warn("Unknown data object in animation of .x file");
 295.317 +			ParseUnknownDataObject();
 295.318 +		}
 295.319 +	}
 295.320 +}
 295.321 +
 295.322 +// ------------------------------------------------------------------------------------------------
 295.323 +void XFileParser::ParseDataObjectTemplate()
 295.324 +{
 295.325 +	// parse a template data object. Currently not stored.
 295.326 +	std::string name;
 295.327 +	readHeadOfDataObject( &name);
 295.328 +
 295.329 +	// read GUID
 295.330 +	std::string guid = GetNextToken();
 295.331 +
 295.332 +	// read and ignore data members
 295.333 +	bool running = true;
 295.334 +	while ( running )
 295.335 +	{
 295.336 +		std::string s = GetNextToken();
 295.337 +
 295.338 +		if( s == "}")
 295.339 +			break;
 295.340 +
 295.341 +		if( s.length() == 0)
 295.342 +			ThrowException( "Unexpected end of file reached while parsing template definition");
 295.343 +	}
 295.344 +}
 295.345 +
 295.346 +// ------------------------------------------------------------------------------------------------
 295.347 +void XFileParser::ParseDataObjectFrame( Node* pParent)
 295.348 +{
 295.349 +	// A coordinate frame, or "frame of reference." The Frame template
 295.350 +	// is open and can contain any object. The Direct3D extensions (D3DX)
 295.351 +	// mesh-loading functions recognize Mesh, FrameTransformMatrix, and
 295.352 +	// Frame template instances as child objects when loading a Frame
 295.353 +	// instance.
 295.354 +	std::string name;
 295.355 +	readHeadOfDataObject(&name);
 295.356 +
 295.357 +	// create a named node and place it at its parent, if given
 295.358 +	Node* node = new Node( pParent);
 295.359 +	node->mName = name;
 295.360 +	if( pParent)
 295.361 +	{
 295.362 +		pParent->mChildren.push_back( node);
 295.363 +	} else
 295.364 +	{
 295.365 +		// there might be multiple root nodes
 295.366 +		if( mScene->mRootNode != NULL)
 295.367 +		{
 295.368 +			// place a dummy root if not there
 295.369 +			if( mScene->mRootNode->mName != "$dummy_root")
 295.370 +			{
 295.371 +				Node* exroot = mScene->mRootNode;
 295.372 +				mScene->mRootNode = new Node( NULL);
 295.373 +				mScene->mRootNode->mName = "$dummy_root";
 295.374 +				mScene->mRootNode->mChildren.push_back( exroot);
 295.375 +				exroot->mParent = mScene->mRootNode;
 295.376 +			}
 295.377 +			// put the new node as its child instead
 295.378 +			mScene->mRootNode->mChildren.push_back( node);
 295.379 +			node->mParent = mScene->mRootNode;
 295.380 +		} else
 295.381 +		{
 295.382 +			// it's the first node imported. place it as root
 295.383 +			mScene->mRootNode = node;
 295.384 +		}
 295.385 +	}
 295.386 +
 295.387 +	// Now inside a frame.
 295.388 +	// read tokens until closing brace is reached.
 295.389 +	bool running = true;
 295.390 +	while ( running )
 295.391 +	{
 295.392 +		std::string objectName = GetNextToken();
 295.393 +		if (objectName.size() == 0)
 295.394 +			ThrowException( "Unexpected end of file reached while parsing frame");
 295.395 +
 295.396 +		if( objectName == "}")
 295.397 +			break; // frame finished
 295.398 +		else
 295.399 +		if( objectName == "Frame")
 295.400 +			ParseDataObjectFrame( node); // child frame
 295.401 +		else
 295.402 +		if( objectName == "FrameTransformMatrix")
 295.403 +			ParseDataObjectTransformationMatrix( node->mTrafoMatrix);
 295.404 +		else
 295.405 +		if( objectName == "Mesh")
 295.406 +		{
 295.407 +			Mesh* mesh = new Mesh;
 295.408 +			node->mMeshes.push_back( mesh);
 295.409 +			ParseDataObjectMesh( mesh);
 295.410 +		} else
 295.411 +		{
 295.412 +			DefaultLogger::get()->warn("Unknown data object in frame in x file");
 295.413 +			ParseUnknownDataObject();
 295.414 +		}
 295.415 +	}
 295.416 +}
 295.417 +
 295.418 +// ------------------------------------------------------------------------------------------------
 295.419 +void XFileParser::ParseDataObjectTransformationMatrix( aiMatrix4x4& pMatrix)
 295.420 +{
 295.421 +	// read header, we're not interested if it has a name
 295.422 +	readHeadOfDataObject();
 295.423 +
 295.424 +	// read its components
 295.425 +	pMatrix.a1 = ReadFloat(); pMatrix.b1 = ReadFloat();
 295.426 +	pMatrix.c1 = ReadFloat(); pMatrix.d1 = ReadFloat();
 295.427 +	pMatrix.a2 = ReadFloat(); pMatrix.b2 = ReadFloat();
 295.428 +	pMatrix.c2 = ReadFloat(); pMatrix.d2 = ReadFloat();
 295.429 +	pMatrix.a3 = ReadFloat(); pMatrix.b3 = ReadFloat();
 295.430 +	pMatrix.c3 = ReadFloat(); pMatrix.d3 = ReadFloat();
 295.431 +	pMatrix.a4 = ReadFloat(); pMatrix.b4 = ReadFloat();
 295.432 +	pMatrix.c4 = ReadFloat(); pMatrix.d4 = ReadFloat();
 295.433 +
 295.434 +	// trailing symbols
 295.435 +	CheckForSemicolon();
 295.436 +	CheckForClosingBrace();
 295.437 +}
 295.438 +
 295.439 +// ------------------------------------------------------------------------------------------------
 295.440 +void XFileParser::ParseDataObjectMesh( Mesh* pMesh)
 295.441 +{
 295.442 +	std::string name;
 295.443 +	readHeadOfDataObject( &name);
 295.444 +
 295.445 +	// read vertex count
 295.446 +	unsigned int numVertices = ReadInt();
 295.447 +	pMesh->mPositions.resize( numVertices);
 295.448 +
 295.449 +	// read vertices
 295.450 +	for( unsigned int a = 0; a < numVertices; a++)
 295.451 +		pMesh->mPositions[a] = ReadVector3();
 295.452 +
 295.453 +	// read position faces
 295.454 +	unsigned int numPosFaces = ReadInt();
 295.455 +	pMesh->mPosFaces.resize( numPosFaces);
 295.456 +	for( unsigned int a = 0; a < numPosFaces; a++)
 295.457 +	{
 295.458 +		unsigned int numIndices = ReadInt();
 295.459 +		if( numIndices < 3)
 295.460 +			ThrowException( boost::str( boost::format( "Invalid index count %1% for face %2%.") % numIndices % a));
 295.461 +
 295.462 +		// read indices
 295.463 +		Face& face = pMesh->mPosFaces[a];
 295.464 +		for( unsigned int b = 0; b < numIndices; b++)
 295.465 +			face.mIndices.push_back( ReadInt());
 295.466 +		TestForSeparator();
 295.467 +	}
 295.468 +
 295.469 +	// here, other data objects may follow
 295.470 +	bool running = true;
 295.471 +	while ( running )
 295.472 +	{
 295.473 +		std::string objectName = GetNextToken();
 295.474 +
 295.475 +		if( objectName.size() == 0)
 295.476 +			ThrowException( "Unexpected end of file while parsing mesh structure");
 295.477 +		else
 295.478 +		if( objectName == "}")
 295.479 +			break; // mesh finished
 295.480 +		else
 295.481 +		if( objectName == "MeshNormals")
 295.482 +			ParseDataObjectMeshNormals( pMesh);
 295.483 +		else
 295.484 +		if( objectName == "MeshTextureCoords")
 295.485 +			ParseDataObjectMeshTextureCoords( pMesh);
 295.486 +		else
 295.487 +		if( objectName == "MeshVertexColors")
 295.488 +			ParseDataObjectMeshVertexColors( pMesh);
 295.489 +		else
 295.490 +		if( objectName == "MeshMaterialList")
 295.491 +			ParseDataObjectMeshMaterialList( pMesh);
 295.492 +		else
 295.493 +		if( objectName == "VertexDuplicationIndices")
 295.494 +			ParseUnknownDataObject(); // we'll ignore vertex duplication indices
 295.495 +		else
 295.496 +		if( objectName == "XSkinMeshHeader")
 295.497 +			ParseDataObjectSkinMeshHeader( pMesh);
 295.498 +		else
 295.499 +		if( objectName == "SkinWeights")
 295.500 +			ParseDataObjectSkinWeights( pMesh);
 295.501 +		else
 295.502 +		{
 295.503 +			DefaultLogger::get()->warn("Unknown data object in mesh in x file");
 295.504 +			ParseUnknownDataObject();
 295.505 +		}
 295.506 +	}
 295.507 +}
 295.508 +
 295.509 +// ------------------------------------------------------------------------------------------------
 295.510 +void XFileParser::ParseDataObjectSkinWeights( Mesh *pMesh)
 295.511 +{
 295.512 +	readHeadOfDataObject();
 295.513 +
 295.514 +	std::string transformNodeName;
 295.515 +	GetNextTokenAsString( transformNodeName);
 295.516 +
 295.517 +	pMesh->mBones.push_back( Bone());
 295.518 +	Bone& bone = pMesh->mBones.back();
 295.519 +	bone.mName = transformNodeName;
 295.520 +
 295.521 +	// read vertex weights
 295.522 +	unsigned int numWeights = ReadInt();
 295.523 +	bone.mWeights.reserve( numWeights);
 295.524 +
 295.525 +	for( unsigned int a = 0; a < numWeights; a++)
 295.526 +	{
 295.527 +		BoneWeight weight;
 295.528 +		weight.mVertex = ReadInt();
 295.529 +		bone.mWeights.push_back( weight);
 295.530 +	}
 295.531 +
 295.532 +	// read vertex weights
 295.533 +	for( unsigned int a = 0; a < numWeights; a++)
 295.534 +		bone.mWeights[a].mWeight = ReadFloat();
 295.535 +
 295.536 +	// read matrix offset
 295.537 +	bone.mOffsetMatrix.a1 = ReadFloat(); bone.mOffsetMatrix.b1 = ReadFloat();
 295.538 +	bone.mOffsetMatrix.c1 = ReadFloat(); bone.mOffsetMatrix.d1 = ReadFloat();
 295.539 +	bone.mOffsetMatrix.a2 = ReadFloat(); bone.mOffsetMatrix.b2 = ReadFloat();
 295.540 +	bone.mOffsetMatrix.c2 = ReadFloat(); bone.mOffsetMatrix.d2 = ReadFloat();
 295.541 +	bone.mOffsetMatrix.a3 = ReadFloat(); bone.mOffsetMatrix.b3 = ReadFloat();
 295.542 +	bone.mOffsetMatrix.c3 = ReadFloat(); bone.mOffsetMatrix.d3 = ReadFloat();
 295.543 +	bone.mOffsetMatrix.a4 = ReadFloat(); bone.mOffsetMatrix.b4 = ReadFloat();
 295.544 +	bone.mOffsetMatrix.c4 = ReadFloat(); bone.mOffsetMatrix.d4 = ReadFloat();
 295.545 +
 295.546 +	CheckForSemicolon();
 295.547 +	CheckForClosingBrace();
 295.548 +}
 295.549 +
 295.550 +// ------------------------------------------------------------------------------------------------
 295.551 +void XFileParser::ParseDataObjectSkinMeshHeader( Mesh* /*pMesh*/ )
 295.552 +{
 295.553 +	readHeadOfDataObject();
 295.554 +
 295.555 +	/*unsigned int maxSkinWeightsPerVertex =*/ ReadInt();
 295.556 +	/*unsigned int maxSkinWeightsPerFace =*/ ReadInt();
 295.557 +	/*unsigned int numBonesInMesh = */ReadInt();
 295.558 +
 295.559 +	CheckForClosingBrace();
 295.560 +}
 295.561 +
 295.562 +// ------------------------------------------------------------------------------------------------
 295.563 +void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
 295.564 +{
 295.565 +	readHeadOfDataObject();
 295.566 +
 295.567 +	// read count
 295.568 +	unsigned int numNormals = ReadInt();
 295.569 +	pMesh->mNormals.resize( numNormals);
 295.570 +
 295.571 +	// read normal vectors
 295.572 +	for( unsigned int a = 0; a < numNormals; a++)
 295.573 +		pMesh->mNormals[a] = ReadVector3();
 295.574 +
 295.575 +	// read normal indices
 295.576 +	unsigned int numFaces = ReadInt();
 295.577 +	if( numFaces != pMesh->mPosFaces.size())
 295.578 +		ThrowException( "Normal face count does not match vertex face count.");
 295.579 +
 295.580 +	for( unsigned int a = 0; a < numFaces; a++)
 295.581 +	{
 295.582 +		unsigned int numIndices = ReadInt();
 295.583 +		pMesh->mNormFaces.push_back( Face());
 295.584 +		Face& face = pMesh->mNormFaces.back();
 295.585 +
 295.586 +		for( unsigned int b = 0; b < numIndices; b++)
 295.587 +			face.mIndices.push_back( ReadInt());
 295.588 +
 295.589 +		TestForSeparator();
 295.590 +	}
 295.591 +
 295.592 +	CheckForClosingBrace();
 295.593 +}
 295.594 +
 295.595 +// ------------------------------------------------------------------------------------------------
 295.596 +void XFileParser::ParseDataObjectMeshTextureCoords( Mesh* pMesh)
 295.597 +{
 295.598 +	readHeadOfDataObject();
 295.599 +	if( pMesh->mNumTextures + 1 > AI_MAX_NUMBER_OF_TEXTURECOORDS)
 295.600 +		ThrowException( "Too many sets of texture coordinates");
 295.601 +
 295.602 +	std::vector<aiVector2D>& coords = pMesh->mTexCoords[pMesh->mNumTextures++];
 295.603 +
 295.604 +	unsigned int numCoords = ReadInt();
 295.605 +	if( numCoords != pMesh->mPositions.size())
 295.606 +		ThrowException( "Texture coord count does not match vertex count");
 295.607 +
 295.608 +	coords.resize( numCoords);
 295.609 +	for( unsigned int a = 0; a < numCoords; a++)
 295.610 +		coords[a] = ReadVector2();
 295.611 +
 295.612 +	CheckForClosingBrace();
 295.613 +}
 295.614 +
 295.615 +// ------------------------------------------------------------------------------------------------
 295.616 +void XFileParser::ParseDataObjectMeshVertexColors( Mesh* pMesh)
 295.617 +{
 295.618 +	readHeadOfDataObject();
 295.619 +	if( pMesh->mNumColorSets + 1 > AI_MAX_NUMBER_OF_COLOR_SETS)
 295.620 +		ThrowException( "Too many colorsets");
 295.621 +	std::vector<aiColor4D>& colors = pMesh->mColors[pMesh->mNumColorSets++];
 295.622 +
 295.623 +	unsigned int numColors = ReadInt();
 295.624 +	if( numColors != pMesh->mPositions.size())
 295.625 +		ThrowException( "Vertex color count does not match vertex count");
 295.626 +
 295.627 +	colors.resize( numColors, aiColor4D( 0, 0, 0, 1));
 295.628 +	for( unsigned int a = 0; a < numColors; a++)
 295.629 +	{
 295.630 +		unsigned int index = ReadInt();
 295.631 +		if( index >= pMesh->mPositions.size())
 295.632 +			ThrowException( "Vertex color index out of bounds");
 295.633 +
 295.634 +		colors[index] = ReadRGBA();
 295.635 +		// HACK: (thom) Maxon Cinema XPort plugin puts a third separator here, kwxPort puts a comma.
 295.636 +		// Ignore gracefully.
 295.637 +		if( !mIsBinaryFormat)
 295.638 +		{
 295.639 +			FindNextNoneWhiteSpace();
 295.640 +			if( *P == ';' || *P == ',')
 295.641 +				P++;
 295.642 +		}
 295.643 +	}
 295.644 +
 295.645 +	CheckForClosingBrace();
 295.646 +}
 295.647 +
 295.648 +// ------------------------------------------------------------------------------------------------
 295.649 +void XFileParser::ParseDataObjectMeshMaterialList( Mesh* pMesh)
 295.650 +{
 295.651 +	readHeadOfDataObject();
 295.652 +
 295.653 +	// read material count
 295.654 +	/*unsigned int numMaterials =*/ ReadInt();
 295.655 +	// read non triangulated face material index count
 295.656 +	unsigned int numMatIndices = ReadInt();
 295.657 +
 295.658 +	// some models have a material index count of 1... to be able to read them we
 295.659 +	// replicate this single material index on every face
 295.660 +	if( numMatIndices != pMesh->mPosFaces.size() && numMatIndices != 1)
 295.661 +		ThrowException( "Per-Face material index count does not match face count.");
 295.662 +
 295.663 +	// read per-face material indices
 295.664 +	for( unsigned int a = 0; a < numMatIndices; a++)
 295.665 +		pMesh->mFaceMaterials.push_back( ReadInt());
 295.666 +
 295.667 +	// in version 03.02, the face indices end with two semicolons.
 295.668 +	// commented out version check, as version 03.03 exported from blender also has 2 semicolons
 295.669 +	if( !mIsBinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2)
 295.670 +	{
 295.671 +		if(P < End && *P == ';')
 295.672 +			++P;
 295.673 +	}
 295.674 +
 295.675 +	// if there was only a single material index, replicate it on all faces
 295.676 +	while( pMesh->mFaceMaterials.size() < pMesh->mPosFaces.size())
 295.677 +		pMesh->mFaceMaterials.push_back( pMesh->mFaceMaterials.front());
 295.678 +
 295.679 +	// read following data objects
 295.680 +	bool running = true;
 295.681 +	while ( running )
 295.682 +	{
 295.683 +		std::string objectName = GetNextToken();
 295.684 +		if( objectName.size() == 0)
 295.685 +			ThrowException( "Unexpected end of file while parsing mesh material list.");
 295.686 +		else
 295.687 +		if( objectName == "}")
 295.688 +			break; // material list finished
 295.689 +		else
 295.690 +		if( objectName == "{")
 295.691 +		{
 295.692 +			// template materials 
 295.693 +			std::string matName = GetNextToken();
 295.694 +			Material material;
 295.695 +			material.mIsReference = true;
 295.696 +			material.mName = matName;
 295.697 +			pMesh->mMaterials.push_back( material);
 295.698 +
 295.699 +			CheckForClosingBrace(); // skip }
 295.700 +		} else
 295.701 +		if( objectName == "Material")
 295.702 +		{
 295.703 +			pMesh->mMaterials.push_back( Material());
 295.704 +			ParseDataObjectMaterial( &pMesh->mMaterials.back());
 295.705 +		} else
 295.706 +		if( objectName == ";")
 295.707 +		{
 295.708 +			// ignore
 295.709 +		} else
 295.710 +		{
 295.711 +			DefaultLogger::get()->warn("Unknown data object in material list in x file");
 295.712 +			ParseUnknownDataObject();
 295.713 +		}
 295.714 +	}
 295.715 +}
 295.716 +
 295.717 +// ------------------------------------------------------------------------------------------------
 295.718 +void XFileParser::ParseDataObjectMaterial( Material* pMaterial)
 295.719 +{
 295.720 +	std::string matName;
 295.721 +	readHeadOfDataObject( &matName);
 295.722 +	if( matName.empty())
 295.723 +		matName = std::string( "material") + boost::lexical_cast<std::string>( mLineNumber);
 295.724 +	pMaterial->mName = matName;
 295.725 +	pMaterial->mIsReference = false;
 295.726 +
 295.727 +	// read material values
 295.728 +	pMaterial->mDiffuse = ReadRGBA(); 
 295.729 +	pMaterial->mSpecularExponent = ReadFloat();
 295.730 +	pMaterial->mSpecular = ReadRGB(); 
 295.731 +	pMaterial->mEmissive = ReadRGB(); 
 295.732 +
 295.733 +	// read other data objects
 295.734 +	bool running = true;
 295.735 +	while ( running )
 295.736 +	{
 295.737 +		std::string objectName = GetNextToken();
 295.738 +		if( objectName.size() == 0)
 295.739 +			ThrowException( "Unexpected end of file while parsing mesh material");
 295.740 +		else
 295.741 +		if( objectName == "}")
 295.742 +			break; // material finished
 295.743 +		else
 295.744 +		if( objectName == "TextureFilename" || objectName == "TextureFileName")
 295.745 +		{
 295.746 +			// some exporters write "TextureFileName" instead.
 295.747 +			std::string texname;
 295.748 +			ParseDataObjectTextureFilename( texname);
 295.749 +			pMaterial->mTextures.push_back( TexEntry( texname));
 295.750 +		} else
 295.751 +		if( objectName == "NormalmapFilename" || objectName == "NormalmapFileName")
 295.752 +		{
 295.753 +			// one exporter writes out the normal map in a separate filename tag
 295.754 +			std::string texname;
 295.755 +			ParseDataObjectTextureFilename( texname);
 295.756 +			pMaterial->mTextures.push_back( TexEntry( texname, true));
 295.757 +		} else
 295.758 +		{
 295.759 +			DefaultLogger::get()->warn("Unknown data object in material in x file");
 295.760 +			ParseUnknownDataObject();
 295.761 +		}
 295.762 +	}
 295.763 +}
 295.764 +
 295.765 +// ------------------------------------------------------------------------------------------------
 295.766 +void XFileParser::ParseDataObjectAnimTicksPerSecond()
 295.767 +{
 295.768 +	readHeadOfDataObject();
 295.769 +	mScene->mAnimTicksPerSecond = ReadInt();
 295.770 +	CheckForClosingBrace();
 295.771 +}
 295.772 +
 295.773 +// ------------------------------------------------------------------------------------------------
 295.774 +void XFileParser::ParseDataObjectAnimationSet()
 295.775 +{
 295.776 +	std::string animName;
 295.777 +	readHeadOfDataObject( &animName);
 295.778 +
 295.779 +	Animation* anim = new Animation;
 295.780 +	mScene->mAnims.push_back( anim);
 295.781 +	anim->mName = animName;
 295.782 +
 295.783 +	bool running = true;
 295.784 +	while ( running )
 295.785 +	{
 295.786 +		std::string objectName = GetNextToken();
 295.787 +		if( objectName.length() == 0)
 295.788 +			ThrowException( "Unexpected end of file while parsing animation set.");
 295.789 +		else
 295.790 +		if( objectName == "}")
 295.791 +			break; // animation set finished
 295.792 +		else
 295.793 +		if( objectName == "Animation")
 295.794 +			ParseDataObjectAnimation( anim);
 295.795 +		else
 295.796 +		{
 295.797 +			DefaultLogger::get()->warn("Unknown data object in animation set in x file");
 295.798 +			ParseUnknownDataObject();
 295.799 +		}
 295.800 +	}
 295.801 +}
 295.802 +
 295.803 +// ------------------------------------------------------------------------------------------------
 295.804 +void XFileParser::ParseDataObjectAnimation( Animation* pAnim)
 295.805 +{
 295.806 +	readHeadOfDataObject();
 295.807 +	AnimBone* banim = new AnimBone;
 295.808 +	pAnim->mAnims.push_back( banim);
 295.809 +
 295.810 +	bool running = true;
 295.811 +	while( running )
 295.812 +	{
 295.813 +		std::string objectName = GetNextToken();
 295.814 +
 295.815 +		if( objectName.length() == 0)
 295.816 +			ThrowException( "Unexpected end of file while parsing animation.");
 295.817 +		else
 295.818 +		if( objectName == "}")
 295.819 +			break; // animation finished
 295.820 +		else
 295.821 +		if( objectName == "AnimationKey")
 295.822 +			ParseDataObjectAnimationKey( banim);
 295.823 +		else
 295.824 +		if( objectName == "AnimationOptions")
 295.825 +			ParseUnknownDataObject(); // not interested
 295.826 +		else
 295.827 +		if( objectName == "{")
 295.828 +		{
 295.829 +			// read frame name
 295.830 +			banim->mBoneName = GetNextToken();
 295.831 +			CheckForClosingBrace();
 295.832 +		} else
 295.833 +		{
 295.834 +			DefaultLogger::get()->warn("Unknown data object in animation in x file");
 295.835 +			ParseUnknownDataObject();
 295.836 +		}
 295.837 +	}
 295.838 +}
 295.839 +
 295.840 +// ------------------------------------------------------------------------------------------------
 295.841 +void XFileParser::ParseDataObjectAnimationKey( AnimBone* pAnimBone)
 295.842 +{
 295.843 +	readHeadOfDataObject();
 295.844 +
 295.845 +	// read key type
 295.846 +	unsigned int keyType = ReadInt();
 295.847 +
 295.848 +	// read number of keys
 295.849 +	unsigned int numKeys = ReadInt();
 295.850 +
 295.851 +	for( unsigned int a = 0; a < numKeys; a++)
 295.852 +	{
 295.853 +		// read time
 295.854 +		unsigned int time = ReadInt();
 295.855 +
 295.856 +		// read keys
 295.857 +		switch( keyType)
 295.858 +		{
 295.859 +			case 0: // rotation quaternion
 295.860 +			{
 295.861 +				// read count
 295.862 +				if( ReadInt() != 4)
 295.863 +					ThrowException( "Invalid number of arguments for quaternion key in animation");
 295.864 +
 295.865 +				aiQuatKey key;
 295.866 +				key.mTime = double( time);
 295.867 +				key.mValue.w = ReadFloat();
 295.868 +				key.mValue.x = ReadFloat();
 295.869 +				key.mValue.y = ReadFloat();
 295.870 +				key.mValue.z = ReadFloat();
 295.871 +				pAnimBone->mRotKeys.push_back( key);
 295.872 +
 295.873 +				CheckForSemicolon();
 295.874 +				break;
 295.875 +			}
 295.876 +
 295.877 +			case 1: // scale vector
 295.878 +			case 2: // position vector
 295.879 +			{
 295.880 +				// read count
 295.881 +				if( ReadInt() != 3)
 295.882 +					ThrowException( "Invalid number of arguments for vector key in animation");
 295.883 +
 295.884 +				aiVectorKey key;
 295.885 +				key.mTime = double( time);
 295.886 +				key.mValue = ReadVector3();
 295.887 +
 295.888 +				if( keyType == 2)
 295.889 +					pAnimBone->mPosKeys.push_back( key);
 295.890 +				else
 295.891 +					pAnimBone->mScaleKeys.push_back( key);
 295.892 +
 295.893 +				break;
 295.894 +			}
 295.895 +
 295.896 +			case 3: // combined transformation matrix
 295.897 +			case 4: // denoted both as 3 or as 4
 295.898 +			{
 295.899 +				// read count
 295.900 +				if( ReadInt() != 16)
 295.901 +					ThrowException( "Invalid number of arguments for matrix key in animation");
 295.902 +
 295.903 +				// read matrix
 295.904 +				MatrixKey key;
 295.905 +				key.mTime = double( time);
 295.906 +				key.mMatrix.a1 = ReadFloat(); key.mMatrix.b1 = ReadFloat();
 295.907 +				key.mMatrix.c1 = ReadFloat(); key.mMatrix.d1 = ReadFloat();
 295.908 +				key.mMatrix.a2 = ReadFloat(); key.mMatrix.b2 = ReadFloat();
 295.909 +				key.mMatrix.c2 = ReadFloat(); key.mMatrix.d2 = ReadFloat();
 295.910 +				key.mMatrix.a3 = ReadFloat(); key.mMatrix.b3 = ReadFloat();
 295.911 +				key.mMatrix.c3 = ReadFloat(); key.mMatrix.d3 = ReadFloat();
 295.912 +				key.mMatrix.a4 = ReadFloat(); key.mMatrix.b4 = ReadFloat();
 295.913 +				key.mMatrix.c4 = ReadFloat(); key.mMatrix.d4 = ReadFloat();
 295.914 +				pAnimBone->mTrafoKeys.push_back( key);
 295.915 +
 295.916 +				CheckForSemicolon();
 295.917 +				break;
 295.918 +			}
 295.919 +
 295.920 +			default:
 295.921 +				ThrowException( boost::str( boost::format( "Unknown key type %1% in animation.") % keyType));
 295.922 +				break;
 295.923 +		} // end switch
 295.924 +
 295.925 +		// key separator
 295.926 +		CheckForSeparator();
 295.927 +	}
 295.928 +
 295.929 +	CheckForClosingBrace();
 295.930 +}
 295.931 +
 295.932 +// ------------------------------------------------------------------------------------------------
 295.933 +void XFileParser::ParseDataObjectTextureFilename( std::string& pName)
 295.934 +{
 295.935 +	readHeadOfDataObject();
 295.936 +	GetNextTokenAsString( pName);
 295.937 +	CheckForClosingBrace();
 295.938 +
 295.939 +	// FIX: some files (e.g. AnimationTest.x) have "" as texture file name
 295.940 +	if (!pName.length())
 295.941 +	{
 295.942 +		DefaultLogger::get()->warn("Length of texture file name is zero. Skipping this texture.");
 295.943 +	}
 295.944 +
 295.945 +	// some exporters write double backslash paths out. We simply replace them if we find them
 295.946 +	while( pName.find( "\\\\") != std::string::npos)
 295.947 +		pName.replace( pName.find( "\\\\"), 2, "\\");
 295.948 +}
 295.949 +
 295.950 +// ------------------------------------------------------------------------------------------------
 295.951 +void XFileParser::ParseUnknownDataObject()
 295.952 +{
 295.953 +	// find opening delimiter
 295.954 +	bool running = true;
 295.955 +	while( running )
 295.956 +	{
 295.957 +		std::string t = GetNextToken();
 295.958 +		if( t.length() == 0)
 295.959 +			ThrowException( "Unexpected end of file while parsing unknown segment.");
 295.960 +
 295.961 +		if( t == "{")
 295.962 +			break;
 295.963 +	}
 295.964 +
 295.965 +	unsigned int counter = 1;
 295.966 +
 295.967 +	// parse until closing delimiter
 295.968 +	while( counter > 0)
 295.969 +	{
 295.970 +		std::string t = GetNextToken();
 295.971 +
 295.972 +		if( t.length() == 0)
 295.973 +			ThrowException( "Unexpected end of file while parsing unknown segment.");
 295.974 +
 295.975 +		if( t == "{")
 295.976 +			++counter;
 295.977 +		else
 295.978 +		if( t == "}")
 295.979 +			--counter;
 295.980 +	}
 295.981 +}
 295.982 +
 295.983 +// ------------------------------------------------------------------------------------------------
 295.984 +//! checks for closing curly brace
 295.985 +void XFileParser::CheckForClosingBrace()
 295.986 +{
 295.987 +	if( GetNextToken() != "}")
 295.988 +		ThrowException( "Closing brace expected.");
 295.989 +}
 295.990 +
 295.991 +// ------------------------------------------------------------------------------------------------
 295.992 +//! checks for one following semicolon
 295.993 +void XFileParser::CheckForSemicolon()
 295.994 +{
 295.995 +	if( mIsBinaryFormat)
 295.996 +		return;
 295.997 +
 295.998 +	if( GetNextToken() != ";")
 295.999 +		ThrowException( "Semicolon expected.");
295.1000 +}
295.1001 +
295.1002 +// ------------------------------------------------------------------------------------------------
295.1003 +//! checks for a separator char, either a ',' or a ';'
295.1004 +void XFileParser::CheckForSeparator()
295.1005 +{
295.1006 +	if( mIsBinaryFormat)
295.1007 +		return;
295.1008 +
295.1009 +	std::string token = GetNextToken();
295.1010 +	if( token != "," && token != ";")
295.1011 +		ThrowException( "Separator character (';' or ',') expected.");
295.1012 +}
295.1013 +
295.1014 +// ------------------------------------------------------------------------------------------------
295.1015 +// tests and possibly consumes a separator char, but does nothing if there was no separator
295.1016 +void XFileParser::TestForSeparator()
295.1017 +{
295.1018 +  if( mIsBinaryFormat)
295.1019 +    return;
295.1020 +
295.1021 +  FindNextNoneWhiteSpace();
295.1022 +  if( P >= End)
295.1023 +    return;
295.1024 +
295.1025 +  // test and skip
295.1026 +  if( *P == ';' || *P == ',')
295.1027 +    P++;
295.1028 +}
295.1029 +
295.1030 +// ------------------------------------------------------------------------------------------------
295.1031 +void XFileParser::readHeadOfDataObject( std::string* poName)
295.1032 +{
295.1033 +	std::string nameOrBrace = GetNextToken();
295.1034 +	if( nameOrBrace != "{")
295.1035 +	{
295.1036 +		if( poName)
295.1037 +			*poName = nameOrBrace;
295.1038 +
295.1039 +		if( GetNextToken() != "{")
295.1040 +			ThrowException( "Opening brace expected.");
295.1041 +	}
295.1042 +}
295.1043 +
295.1044 +// ------------------------------------------------------------------------------------------------
295.1045 +std::string XFileParser::GetNextToken()
295.1046 +{
295.1047 +	std::string s;
295.1048 +
295.1049 +	// process binary-formatted file
295.1050 +	if( mIsBinaryFormat)
295.1051 +	{
295.1052 +		// in binary mode it will only return NAME and STRING token
295.1053 +		// and (correctly) skip over other tokens.
295.1054 +
295.1055 +		if( End - P < 2) return s;
295.1056 +		unsigned int tok = ReadBinWord();
295.1057 +		unsigned int len;
295.1058 +
295.1059 +		// standalone tokens
295.1060 +		switch( tok) 
295.1061 +		{
295.1062 +			case 1:
295.1063 +				// name token
295.1064 +				if( End - P < 4) return s;
295.1065 +				len = ReadBinDWord();
295.1066 +				if( End - P < int(len)) return s;
295.1067 +				s = std::string(P, len);
295.1068 +				P += len;
295.1069 +				return s;
295.1070 +			case 2:
295.1071 +				// string token
295.1072 +				if( End - P < 4) return s;
295.1073 +				len = ReadBinDWord();
295.1074 +				if( End - P < int(len)) return s;
295.1075 +				s = std::string(P, len);
295.1076 +				P += (len + 2);
295.1077 +				return s;
295.1078 +			case 3:
295.1079 +				// integer token
295.1080 +				P += 4;
295.1081 +				return "<integer>";
295.1082 +			case 5:
295.1083 +				// GUID token
295.1084 +				P += 16;
295.1085 +				return "<guid>";
295.1086 +			case 6:
295.1087 +				if( End - P < 4) return s;
295.1088 +				len = ReadBinDWord();
295.1089 +				P += (len * 4);
295.1090 +				return "<int_list>";
295.1091 +			case 7:
295.1092 +				if( End - P < 4) return s;
295.1093 +				len = ReadBinDWord();
295.1094 +				P += (len * mBinaryFloatSize);
295.1095 +				return "<flt_list>";
295.1096 +			case 0x0a:
295.1097 +				return "{";
295.1098 +			case 0x0b:
295.1099 +				return "}";
295.1100 +			case 0x0c:
295.1101 +				return "(";
295.1102 +			case 0x0d:
295.1103 +				return ")";
295.1104 +			case 0x0e:
295.1105 +				return "[";
295.1106 +			case 0x0f:
295.1107 +				return "]";
295.1108 +			case 0x10:
295.1109 +				return "<";
295.1110 +			case 0x11:
295.1111 +				return ">";
295.1112 +			case 0x12:
295.1113 +				return ".";
295.1114 +			case 0x13:
295.1115 +				return ",";
295.1116 +			case 0x14:
295.1117 +				return ";";
295.1118 +			case 0x1f:
295.1119 +				return "template";
295.1120 +			case 0x28:
295.1121 +				return "WORD";
295.1122 +			case 0x29:
295.1123 +				return "DWORD";
295.1124 +			case 0x2a:
295.1125 +				return "FLOAT";
295.1126 +			case 0x2b:
295.1127 +				return "DOUBLE";
295.1128 +			case 0x2c:
295.1129 +				return "CHAR";
295.1130 +			case 0x2d:
295.1131 +				return "UCHAR";
295.1132 +			case 0x2e:
295.1133 +				return "SWORD";
295.1134 +			case 0x2f:
295.1135 +				return "SDWORD";
295.1136 +			case 0x30:
295.1137 +				return "void";
295.1138 +			case 0x31:
295.1139 +				return "string";
295.1140 +			case 0x32:
295.1141 +				return "unicode";
295.1142 +			case 0x33:
295.1143 +				return "cstring";
295.1144 +			case 0x34:
295.1145 +				return "array";
295.1146 +		}
295.1147 +	}
295.1148 +	// process text-formatted file
295.1149 +	else
295.1150 +	{
295.1151 +		FindNextNoneWhiteSpace();
295.1152 +		if( P >= End)
295.1153 +			return s;
295.1154 +
295.1155 +		while( (P < End) && !isspace( (unsigned char) *P))
295.1156 +		{
295.1157 +			// either keep token delimiters when already holding a token, or return if first valid char
295.1158 +			if( *P == ';' || *P == '}' || *P == '{' || *P == ',')
295.1159 +			{
295.1160 +				if( !s.size())
295.1161 +					s.append( P++, 1);
295.1162 +				break; // stop for delimiter
295.1163 +			}
295.1164 +			s.append( P++, 1);
295.1165 +		}
295.1166 +	}
295.1167 +	return s;
295.1168 +}
295.1169 +
295.1170 +// ------------------------------------------------------------------------------------------------
295.1171 +void XFileParser::FindNextNoneWhiteSpace()
295.1172 +{
295.1173 +	if( mIsBinaryFormat)
295.1174 +		return;
295.1175 +
295.1176 +	bool running = true;
295.1177 +	while( running )
295.1178 +	{
295.1179 +		while( P < End && isspace( (unsigned char) *P))
295.1180 +		{
295.1181 +			if( *P == '\n')
295.1182 +				mLineNumber++;
295.1183 +			++P;
295.1184 +		}
295.1185 +
295.1186 +		if( P >= End)
295.1187 +			return;
295.1188 +
295.1189 +		// check if this is a comment
295.1190 +		if( (P[0] == '/' && P[1] == '/') ||	P[0] == '#')
295.1191 +			ReadUntilEndOfLine();
295.1192 +		else
295.1193 +			break;
295.1194 +	}
295.1195 +}
295.1196 +
295.1197 +// ------------------------------------------------------------------------------------------------
295.1198 +void XFileParser::GetNextTokenAsString( std::string& poString)
295.1199 +{
295.1200 +	if( mIsBinaryFormat)
295.1201 +	{
295.1202 +		poString = GetNextToken();
295.1203 +		return;
295.1204 +	}
295.1205 +
295.1206 +	FindNextNoneWhiteSpace();
295.1207 +	if( P >= End)
295.1208 +		ThrowException( "Unexpected end of file while parsing string");
295.1209 +
295.1210 +	if( *P != '"')
295.1211 +		ThrowException( "Expected quotation mark.");
295.1212 +	++P;
295.1213 +
295.1214 +	while( P < End && *P != '"')
295.1215 +		poString.append( P++, 1);
295.1216 +
295.1217 +	if( P >= End-1)
295.1218 +		ThrowException( "Unexpected end of file while parsing string");
295.1219 +
295.1220 +	if( P[1] != ';' || P[0] != '"')
295.1221 +		ThrowException( "Expected quotation mark and semicolon at the end of a string.");
295.1222 +	P+=2;
295.1223 +}
295.1224 +
295.1225 +// ------------------------------------------------------------------------------------------------
295.1226 +void XFileParser::ReadUntilEndOfLine()
295.1227 +{
295.1228 +	if( mIsBinaryFormat)
295.1229 +		return;
295.1230 +
295.1231 +	while( P < End)
295.1232 +	{
295.1233 +		if( *P == '\n' || *P == '\r')
295.1234 +		{
295.1235 +			++P; mLineNumber++;
295.1236 +			return;
295.1237 +		}
295.1238 +
295.1239 +		++P;
295.1240 +	}
295.1241 +}
295.1242 +
295.1243 +// ------------------------------------------------------------------------------------------------
295.1244 +unsigned short XFileParser::ReadBinWord()
295.1245 +{
295.1246 +	ai_assert(End - P >= 2);
295.1247 +	const unsigned char* q = (const unsigned char*) P;
295.1248 +	unsigned short tmp = q[0] | (q[1] << 8);
295.1249 +	P += 2;
295.1250 +	return tmp;
295.1251 +}
295.1252 +
295.1253 +// ------------------------------------------------------------------------------------------------
295.1254 +unsigned int XFileParser::ReadBinDWord()
295.1255 +{
295.1256 +	ai_assert(End - P >= 4);
295.1257 +	const unsigned char* q = (const unsigned char*) P;
295.1258 +	unsigned int tmp = q[0] | (q[1] << 8) | (q[2] << 16) | (q[3] << 24);
295.1259 +	P += 4;
295.1260 +	return tmp;
295.1261 +}
295.1262 +
295.1263 +// ------------------------------------------------------------------------------------------------
295.1264 +unsigned int XFileParser::ReadInt()
295.1265 +{
295.1266 +	if( mIsBinaryFormat)
295.1267 +	{
295.1268 +		if( mBinaryNumCount == 0 && End - P >= 2)
295.1269 +		{
295.1270 +			unsigned short tmp = ReadBinWord(); // 0x06 or 0x03
295.1271 +			if( tmp == 0x06 && End - P >= 4) // array of ints follows
295.1272 +				mBinaryNumCount = ReadBinDWord();
295.1273 +			else // single int follows
295.1274 +				mBinaryNumCount = 1; 
295.1275 +		}
295.1276 +
295.1277 +		--mBinaryNumCount;
295.1278 +		if ( End - P >= 4) {
295.1279 +			return ReadBinDWord();
295.1280 +		} else {
295.1281 +			P = End;
295.1282 +			return 0;
295.1283 +		}
295.1284 +	} else
295.1285 +	{
295.1286 +		FindNextNoneWhiteSpace();
295.1287 +
295.1288 +		// TODO: consider using strtol10 instead???
295.1289 +
295.1290 +		// check preceeding minus sign
295.1291 +		bool isNegative = false;
295.1292 +		if( *P == '-')
295.1293 +		{
295.1294 +			isNegative = true;
295.1295 +			P++;
295.1296 +		}
295.1297 +
295.1298 +		// at least one digit expected
295.1299 +		if( !isdigit( *P))
295.1300 +			ThrowException( "Number expected.");
295.1301 +
295.1302 +		// read digits
295.1303 +		unsigned int number = 0;
295.1304 +		while( P < End)
295.1305 +		{
295.1306 +			if( !isdigit( *P))
295.1307 +				break;
295.1308 +			number = number * 10 + (*P - 48);
295.1309 +			P++;
295.1310 +		}
295.1311 +		
295.1312 +		CheckForSeparator();
295.1313 +		return isNegative ? ((unsigned int) -int( number)) : number;
295.1314 +	}
295.1315 +}
295.1316 +
295.1317 +// ------------------------------------------------------------------------------------------------
295.1318 +float XFileParser::ReadFloat()
295.1319 +{
295.1320 +	if( mIsBinaryFormat)
295.1321 +	{
295.1322 +		if( mBinaryNumCount == 0 && End - P >= 2)
295.1323 +		{
295.1324 +			unsigned short tmp = ReadBinWord(); // 0x07 or 0x42
295.1325 +			if( tmp == 0x07 && End - P >= 4) // array of floats following
295.1326 +				mBinaryNumCount = ReadBinDWord();
295.1327 +			else // single float following
295.1328 +				mBinaryNumCount = 1; 
295.1329 +		}
295.1330 +
295.1331 +		--mBinaryNumCount;
295.1332 +		if( mBinaryFloatSize == 8)
295.1333 +		{
295.1334 +			if( End - P >= 8) {
295.1335 +				float result = (float) (*(double*) P);
295.1336 +				P += 8;
295.1337 +				return result;
295.1338 +			} else {
295.1339 +				P = End;
295.1340 +				return 0;
295.1341 +			}
295.1342 +		} else
295.1343 +		{
295.1344 +			if( End - P >= 4) {
295.1345 +				float result = *(float*) P;
295.1346 +				P += 4;
295.1347 +				return result;
295.1348 +			} else {
295.1349 +				P = End;
295.1350 +				return 0;
295.1351 +			}
295.1352 +		}
295.1353 +	}
295.1354 +
295.1355 +	// text version
295.1356 +	FindNextNoneWhiteSpace();
295.1357 +	// check for various special strings to allow reading files from faulty exporters
295.1358 +	// I mean you, Blender!
295.1359 +	// Reading is safe because of the terminating zero
295.1360 +	if( strncmp( P, "-1.#IND00", 9) == 0 || strncmp( P, "1.#IND00", 8) == 0)
295.1361 +	{ 
295.1362 +		P += 9;
295.1363 +		CheckForSeparator();
295.1364 +		return 0.0f;
295.1365 +	} else
295.1366 +	if( strncmp( P, "1.#QNAN0", 8) == 0)
295.1367 +	{
295.1368 +		P += 8;
295.1369 +		CheckForSeparator();
295.1370 +		return 0.0f;
295.1371 +	}
295.1372 +
295.1373 +	float result = 0.0f;
295.1374 +	P = fast_atoreal_move<float>( P, result);
295.1375 +
295.1376 +	CheckForSeparator();
295.1377 +
295.1378 +	return result;
295.1379 +}
295.1380 +
295.1381 +// ------------------------------------------------------------------------------------------------
295.1382 +aiVector2D XFileParser::ReadVector2()
295.1383 +{
295.1384 +	aiVector2D vector;
295.1385 +	vector.x = ReadFloat();
295.1386 +	vector.y = ReadFloat();
295.1387 +	TestForSeparator();
295.1388 +
295.1389 +	return vector;
295.1390 +}
295.1391 +
295.1392 +// ------------------------------------------------------------------------------------------------
295.1393 +aiVector3D XFileParser::ReadVector3()
295.1394 +{
295.1395 +	aiVector3D vector;
295.1396 +	vector.x = ReadFloat();
295.1397 +	vector.y = ReadFloat();
295.1398 +	vector.z = ReadFloat();
295.1399 +	TestForSeparator();
295.1400 +
295.1401 +	return vector;
295.1402 +}
295.1403 +
295.1404 +// ------------------------------------------------------------------------------------------------
295.1405 +aiColor4D XFileParser::ReadRGBA()
295.1406 +{
295.1407 +	aiColor4D color;
295.1408 +	color.r = ReadFloat();
295.1409 +	color.g = ReadFloat();
295.1410 +	color.b = ReadFloat();
295.1411 +	color.a = ReadFloat();
295.1412 +	TestForSeparator();
295.1413 +
295.1414 +	return color;
295.1415 +}
295.1416 +
295.1417 +// ------------------------------------------------------------------------------------------------
295.1418 +aiColor3D XFileParser::ReadRGB()
295.1419 +{
295.1420 +	aiColor3D color;
295.1421 +	color.r = ReadFloat();
295.1422 +	color.g = ReadFloat();
295.1423 +	color.b = ReadFloat();
295.1424 +	TestForSeparator();
295.1425 +
295.1426 +	return color;
295.1427 +}
295.1428 +
295.1429 +// ------------------------------------------------------------------------------------------------
295.1430 +// Throws an exception with a line number and the given text.
295.1431 +void XFileParser::ThrowException( const std::string& pText)
295.1432 +{
295.1433 +	if( mIsBinaryFormat)
295.1434 +		throw DeadlyImportError( pText);
295.1435 +	else
295.1436 +		throw DeadlyImportError( boost::str( boost::format( "Line %d: %s") % mLineNumber % pText));
295.1437 +}
295.1438 +
295.1439 +
295.1440 +// ------------------------------------------------------------------------------------------------
295.1441 +// Filters the imported hierarchy for some degenerated cases that some exporters produce.
295.1442 +void XFileParser::FilterHierarchy( XFile::Node* pNode)
295.1443 +{
295.1444 +	// if the node has just a single unnamed child containing a mesh, remove
295.1445 +	// the anonymous node inbetween. The 3DSMax kwXport plugin seems to produce this
295.1446 +	// mess in some cases
295.1447 +	if( pNode->mChildren.size() == 1 && pNode->mMeshes.empty() )
295.1448 +	{
295.1449 +		XFile::Node* child = pNode->mChildren.front();
295.1450 +		if( child->mName.length() == 0 && child->mMeshes.size() > 0)
295.1451 +		{
295.1452 +			// transfer its meshes to us
295.1453 +			for( unsigned int a = 0; a < child->mMeshes.size(); a++)
295.1454 +				pNode->mMeshes.push_back( child->mMeshes[a]);
295.1455 +			child->mMeshes.clear();
295.1456 +
295.1457 +			// transfer the transform as well
295.1458 +			pNode->mTrafoMatrix = pNode->mTrafoMatrix * child->mTrafoMatrix;
295.1459 +
295.1460 +			// then kill it
295.1461 +			delete child;
295.1462 +			pNode->mChildren.clear();
295.1463 +		}
295.1464 +	}
295.1465 +
295.1466 +	// recurse
295.1467 +	for( unsigned int a = 0; a < pNode->mChildren.size(); a++)
295.1468 +		FilterHierarchy( pNode->mChildren[a]);
295.1469 +}
295.1470 +
295.1471 +#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
   296.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   296.2 +++ b/libs/assimp/XFileParser.h	Sat Feb 01 19:58:19 2014 +0200
   296.3 @@ -0,0 +1,162 @@
   296.4 +/*
   296.5 +Open Asset Import Library (assimp)
   296.6 +----------------------------------------------------------------------
   296.7 +
   296.8 +Copyright (c) 2006-2012, assimp team
   296.9 +All rights reserved.
  296.10 +
  296.11 +Redistribution and use of this software in source and binary forms, 
  296.12 +with or without modification, are permitted provided that the 
  296.13 +following conditions are met:
  296.14 +
  296.15 +* Redistributions of source code must retain the above
  296.16 +  copyright notice, this list of conditions and the
  296.17 +  following disclaimer.
  296.18 +
  296.19 +* Redistributions in binary form must reproduce the above
  296.20 +  copyright notice, this list of conditions and the
  296.21 +  following disclaimer in the documentation and/or other
  296.22 +  materials provided with the distribution.
  296.23 +
  296.24 +* Neither the name of the assimp team, nor the names of its
  296.25 +  contributors may be used to endorse or promote products
  296.26 +  derived from this software without specific prior
  296.27 +  written permission of the assimp team.
  296.28 +
  296.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  296.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  296.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  296.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  296.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  296.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  296.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  296.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  296.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  296.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  296.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  296.40 +
  296.41 +----------------------------------------------------------------------
  296.42 +*/
  296.43 +
  296.44 +/** @file Helper class to parse a XFile into a temporary structure */
  296.45 +#ifndef AI_XFILEPARSER_H_INC
  296.46 +#define AI_XFILEPARSER_H_INC
  296.47 +
  296.48 +#include <string>
  296.49 +#include <vector>
  296.50 +
  296.51 +#include "assimp/types.h"
  296.52 +
  296.53 +namespace Assimp
  296.54 +{
  296.55 +	namespace XFile
  296.56 +	{
  296.57 +		struct Node;
  296.58 +		struct Mesh;
  296.59 +		struct Scene;
  296.60 +		struct Material;
  296.61 +		struct Animation;
  296.62 +		struct AnimBone;
  296.63 +	}
  296.64 +
  296.65 +/** The XFileParser reads a XFile either in text or binary form and builds a temporary 
  296.66 + * data structure out of it. 
  296.67 + */
  296.68 +class XFileParser
  296.69 +{
  296.70 +public:
  296.71 +	/** Constructor. Creates a data structure out of the XFile given in the memory block. 
  296.72 +	 * @param pBuffer Null-terminated memory buffer containing the XFile
  296.73 +	 */
  296.74 +	XFileParser( const std::vector<char>& pBuffer);
  296.75 +
  296.76 +	/** Destructor. Destroys all imported data along with it */
  296.77 +	~XFileParser();
  296.78 +
  296.79 +	/** Returns the temporary representation of the imported data */
  296.80 +	XFile::Scene* GetImportedData() const { return mScene; }
  296.81 +
  296.82 +protected:
  296.83 +	void ParseFile();
  296.84 +	void ParseDataObjectTemplate();
  296.85 +	void ParseDataObjectFrame( XFile::Node *pParent);
  296.86 +	void ParseDataObjectTransformationMatrix( aiMatrix4x4& pMatrix);
  296.87 +	void ParseDataObjectMesh( XFile::Mesh* pMesh);
  296.88 +	void ParseDataObjectSkinWeights( XFile::Mesh* pMesh);
  296.89 +	void ParseDataObjectSkinMeshHeader( XFile::Mesh* pMesh);
  296.90 +	void ParseDataObjectMeshNormals( XFile::Mesh* pMesh);
  296.91 +	void ParseDataObjectMeshTextureCoords( XFile::Mesh* pMesh);
  296.92 +	void ParseDataObjectMeshVertexColors( XFile::Mesh* pMesh);
  296.93 +	void ParseDataObjectMeshMaterialList( XFile::Mesh* pMesh);
  296.94 +	void ParseDataObjectMaterial( XFile::Material* pMaterial);
  296.95 +	void ParseDataObjectAnimTicksPerSecond();
  296.96 +	void ParseDataObjectAnimationSet();
  296.97 +	void ParseDataObjectAnimation( XFile::Animation* pAnim);
  296.98 +	void ParseDataObjectAnimationKey( XFile::AnimBone *pAnimBone);
  296.99 +	void ParseDataObjectTextureFilename( std::string& pName);
 296.100 +	void ParseUnknownDataObject();
 296.101 +
 296.102 +	//! places pointer to next begin of a token, and ignores comments
 296.103 +	void FindNextNoneWhiteSpace();
 296.104 +
 296.105 +	//! returns next parseable token. Returns empty string if no token there
 296.106 +	std::string GetNextToken();
 296.107 +
 296.108 +	//! reads header of dataobject including the opening brace.
 296.109 +	//! returns false if error happened, and writes name of object
 296.110 +	//! if there is one
 296.111 +	void readHeadOfDataObject( std::string* poName = NULL);
 296.112 +
 296.113 +	//! checks for closing curly brace, throws exception if not there
 296.114 +	void CheckForClosingBrace();
 296.115 +
 296.116 +	//! checks for one following semicolon, throws exception if not there
 296.117 +	void CheckForSemicolon();
 296.118 +
 296.119 +	//! checks for a separator char, either a ',' or a ';'
 296.120 +	void CheckForSeparator();
 296.121 +
 296.122 +  /// tests and possibly consumes a separator char, but does nothing if there was no separator
 296.123 +  void TestForSeparator();
 296.124 +
 296.125 +	//! reads a x file style string
 296.126 +	void GetNextTokenAsString( std::string& poString);
 296.127 +
 296.128 +	void ReadUntilEndOfLine();
 296.129 +
 296.130 +	unsigned short ReadBinWord();
 296.131 +	unsigned int ReadBinDWord();
 296.132 +	unsigned int ReadInt();
 296.133 +	float ReadFloat();
 296.134 +	aiVector2D ReadVector2();
 296.135 +	aiVector3D ReadVector3();
 296.136 +	aiColor3D ReadRGB();
 296.137 +	aiColor4D ReadRGBA();
 296.138 +
 296.139 +	/** Throws an exception with a line number and the given text. */
 296.140 +	void ThrowException( const std::string& pText);
 296.141 +
 296.142 +	/** Filters the imported hierarchy for some degenerated cases that some exporters produce.
 296.143 +	 * @param pData The sub-hierarchy to filter
 296.144 +	 */
 296.145 +	void FilterHierarchy( XFile::Node* pNode);
 296.146 +
 296.147 +protected:
 296.148 +	unsigned int mMajorVersion, mMinorVersion; ///< version numbers
 296.149 +	bool mIsBinaryFormat; ///< true if the file is in binary, false if it's in text form
 296.150 +	unsigned int mBinaryFloatSize; ///< float size, either 32 or 64 bits
 296.151 +	// counter for number arrays in binary format
 296.152 +	unsigned int mBinaryNumCount;
 296.153 +
 296.154 +	const char* P;
 296.155 +	const char* End;
 296.156 +
 296.157 +	/// Line number when reading in text format
 296.158 +	unsigned int mLineNumber;
 296.159 +
 296.160 +	/// Imported data
 296.161 +	XFile::Scene* mScene;	
 296.162 +};
 296.163 +
 296.164 +}
 296.165 +#endif // AI_XFILEPARSER_H_INC
   297.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   297.2 +++ b/libs/assimp/XGLLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
   297.3 @@ -0,0 +1,947 @@
   297.4 +/*
   297.5 +---------------------------------------------------------------------------
   297.6 +Open Asset Import Library (assimp)
   297.7 +---------------------------------------------------------------------------
   297.8 +
   297.9 +Copyright (c) 2006-2012, assimp team
  297.10 +
  297.11 +All rights reserved.
  297.12 +
  297.13 +Redistribution and use of this software in source and binary forms, 
  297.14 +with or without modification, are permitted provided that the following 
  297.15 +conditions are met:
  297.16 +
  297.17 +* Redistributions of source code must retain the above
  297.18 +  copyright notice, this list of conditions and the
  297.19 +  following disclaimer.
  297.20 +
  297.21 +* Redistributions in binary form must reproduce the above
  297.22 +  copyright notice, this list of conditions and the
  297.23 +  following disclaimer in the documentation and/or other
  297.24 +  materials provided with the distribution.
  297.25 +
  297.26 +* Neither the name of the assimp team, nor the names of its
  297.27 +  contributors may be used to endorse or promote products
  297.28 +  derived from this software without specific prior
  297.29 +  written permission of the assimp team.
  297.30 +
  297.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  297.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  297.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  297.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  297.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  297.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  297.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  297.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  297.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  297.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  297.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  297.42 +---------------------------------------------------------------------------
  297.43 +*/
  297.44 +
  297.45 +/** @file Implementation of the XGL/ZGL importer class */
  297.46 +
  297.47 +#include "AssimpPCH.h"
  297.48 +#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
  297.49 +
  297.50 +#include "XGLLoader.h"
  297.51 +#include "ParsingUtils.h"
  297.52 +#include "fast_atof.h"
  297.53 +
  297.54 +#include "StreamReader.h"
  297.55 +#include "MemoryIOWrapper.h"
  297.56 +
  297.57 +using namespace Assimp;
  297.58 +using namespace irr;
  297.59 +using namespace irr::io;
  297.60 +
  297.61 +
  297.62 +// zlib is needed for compressed XGL files 
  297.63 +#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
  297.64 +#	ifdef ASSIMP_BUILD_NO_OWN_ZLIB
  297.65 +#		include <zlib.h>
  297.66 +#	else
  297.67 +#		include "../contrib/zlib/zlib.h"
  297.68 +#	endif
  297.69 +#endif
  297.70 +
  297.71 +
  297.72 +// scopeguard for a malloc'ed buffer
  297.73 +struct free_it
  297.74 +{
  297.75 +	free_it(void* free) : free(free) {}
  297.76 +	~free_it() {
  297.77 +		::free(this->free);
  297.78 +	}
  297.79 +
  297.80 +	void* free;
  297.81 +};
  297.82 +
  297.83 +namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
  297.84 +template<> const std::string LogFunctions<XGLImporter>::log_prefix = "XGL: ";
  297.85 +
  297.86 +}
  297.87 +
  297.88 +static const aiImporterDesc desc = {
  297.89 +	"XGL Importer",
  297.90 +	"",
  297.91 +	"",
  297.92 +	"",
  297.93 +	aiImporterFlags_SupportTextFlavour,
  297.94 +	0,
  297.95 +	0,
  297.96 +	0,
  297.97 +	0,
  297.98 +	"xgl zgl" 
  297.99 +};
 297.100 +
 297.101 +
 297.102 +// ------------------------------------------------------------------------------------------------
 297.103 +// Constructor to be privately used by Importer
 297.104 +XGLImporter::XGLImporter()
 297.105 +{}
 297.106 +
 297.107 +// ------------------------------------------------------------------------------------------------
 297.108 +// Destructor, private as well 
 297.109 +XGLImporter::~XGLImporter()
 297.110 +{}
 297.111 +
 297.112 +// ------------------------------------------------------------------------------------------------
 297.113 +// Returns whether the class can handle the format of the given file. 
 297.114 +bool XGLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
 297.115 +{
 297.116 +	/* NOTE: A simple check for the file extension is not enough
 297.117 +	 * here. XGL and ZGL are ok, but xml is too generic
 297.118 +	 * and might be collada as well. So open the file and
 297.119 +	 * look for typical signal tokens.
 297.120 +	 */
 297.121 +	const std::string extension = GetExtension(pFile);
 297.122 +
 297.123 +	if (extension == "xgl" || extension == "zgl") {
 297.124 +		return true;
 297.125 +	}
 297.126 +	else if (extension == "xml" || checkSig) {
 297.127 +		ai_assert(pIOHandler != NULL);
 297.128 +
 297.129 +		const char* tokens[] = {"<world>","<World>","<WORLD>"};
 297.130 +		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,3);
 297.131 +	}
 297.132 +	return false;
 297.133 +}
 297.134 +
 297.135 +// ------------------------------------------------------------------------------------------------
 297.136 +// Get a list of all file extensions which are handled by this class
 297.137 +const aiImporterDesc* XGLImporter::GetInfo () const
 297.138 +{
 297.139 +	return &desc;
 297.140 +}
 297.141 +
 297.142 +// ------------------------------------------------------------------------------------------------
 297.143 +// Imports the given file into the given scene structure. 
 297.144 +void XGLImporter::InternReadFile( const std::string& pFile, 
 297.145 +	aiScene* pScene, IOSystem* pIOHandler)
 297.146 +{
 297.147 +#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
 297.148 +	Bytef* dest = NULL;
 297.149 +	free_it free_it_really(dest);
 297.150 +#endif
 297.151 +
 297.152 +	scene = pScene;
 297.153 +	boost::shared_ptr<IOStream> stream( pIOHandler->Open( pFile, "rb"));
 297.154 +
 297.155 +	// check whether we can read from the file
 297.156 +	if( stream.get() == NULL) {
 297.157 +		throw DeadlyImportError( "Failed to open XGL/ZGL file " + pFile + "");
 297.158 +	}
 297.159 +
 297.160 +	// see if its compressed, if so uncompress it
 297.161 +	if (GetExtension(pFile) == "zgl") {
 297.162 +#ifdef ASSIMP_BUILD_NO_COMPRESSED_XGL
 297.163 +		ThrowException("Cannot read ZGL file since Assimp was built without compression support");
 297.164 +#else
 297.165 +		boost::scoped_ptr<StreamReaderLE> raw_reader(new StreamReaderLE(stream));	
 297.166 +
 297.167 +		// build a zlib stream
 297.168 +		z_stream zstream;
 297.169 +		zstream.opaque = Z_NULL;
 297.170 +		zstream.zalloc = Z_NULL;
 297.171 +		zstream.zfree  = Z_NULL;
 297.172 +		zstream.data_type = Z_BINARY;
 297.173 +
 297.174 +		// raw decompression without a zlib or gzip header
 297.175 +		inflateInit2(&zstream, -MAX_WBITS);
 297.176 +
 297.177 +		// skip two extra bytes, zgl files do carry a crc16 upfront (I think)
 297.178 +		raw_reader->IncPtr(2);
 297.179 +
 297.180 +		zstream.next_in   = reinterpret_cast<Bytef*>( raw_reader->GetPtr() );
 297.181 +		zstream.avail_in  = raw_reader->GetRemainingSize();
 297.182 +		
 297.183 +		size_t total = 0l;
 297.184 +
 297.185 +		// and decompress the data .... do 1k chunks in the hope that we won't kill the stack
 297.186 +	#define MYBLOCK 1024
 297.187 +		Bytef block[MYBLOCK];
 297.188 +		int ret;
 297.189 +		do {
 297.190 +			zstream.avail_out = MYBLOCK;
 297.191 +			zstream.next_out = block;
 297.192 +			ret = inflate(&zstream, Z_NO_FLUSH);
 297.193 +
 297.194 +			if (ret != Z_STREAM_END && ret != Z_OK) {
 297.195 +				ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .XGL file");
 297.196 +			}
 297.197 +			const size_t have = MYBLOCK - zstream.avail_out;
 297.198 +			total += have;
 297.199 +			dest = reinterpret_cast<Bytef*>( realloc(dest,total) );
 297.200 +			memcpy(dest + total - have,block,have);
 297.201 +		} 
 297.202 +		while (ret != Z_STREAM_END);
 297.203 +
 297.204 +		// terminate zlib
 297.205 +		inflateEnd(&zstream);
 297.206 +
 297.207 +		// replace the input stream with a memory stream
 297.208 +		stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(dest),total)); 
 297.209 +#endif
 297.210 +	}
 297.211 +
 297.212 +	// construct the irrXML parser
 297.213 +	CIrrXML_IOStreamReader st(stream.get());
 297.214 +	boost::scoped_ptr<IrrXMLReader> read( createIrrXMLReader((IFileReadCallBack*) &st) );
 297.215 +	reader = read.get();
 297.216 +
 297.217 +	// parse the XML file
 297.218 +	TempScope scope;
 297.219 +
 297.220 +	while (ReadElement())	{	
 297.221 +		if (!ASSIMP_stricmp(reader->getNodeName(),"world")) {
 297.222 +			ReadWorld(scope);
 297.223 +		}
 297.224 +	}
 297.225 +	
 297.226 +
 297.227 +	std::vector<aiMesh*>& meshes = scope.meshes_linear;
 297.228 +	std::vector<aiMaterial*>& materials = scope.materials_linear;
 297.229 +	if(!meshes.size() || !materials.size()) {
 297.230 +		ThrowException("failed to extract data from XGL file, no meshes loaded");
 297.231 +	}
 297.232 +
 297.233 +	// copy meshes
 297.234 +	scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
 297.235 +	scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
 297.236 +	std::copy(meshes.begin(),meshes.end(),scene->mMeshes);
 297.237 +
 297.238 +	// copy materials
 297.239 +	scene->mNumMaterials = static_cast<unsigned int>(materials.size());
 297.240 +	scene->mMaterials = new aiMaterial*[scene->mNumMaterials]();
 297.241 +	std::copy(materials.begin(),materials.end(),scene->mMaterials);
 297.242 +
 297.243 +	if (scope.light) {
 297.244 +		scene->mNumLights = 1;
 297.245 +		scene->mLights = new aiLight*[1];
 297.246 +		scene->mLights[0] = scope.light;
 297.247 +
 297.248 +		scope.light->mName = scene->mRootNode->mName;
 297.249 +	}
 297.250 +
 297.251 +	scope.dismiss();
 297.252 +}
 297.253 +
 297.254 +// ------------------------------------------------------------------------------------------------
 297.255 +bool XGLImporter::ReadElement()
 297.256 +{
 297.257 +	while(reader->read()) {
 297.258 +		if (reader->getNodeType() == EXN_ELEMENT) {
 297.259 +			return true;
 297.260 +		}
 297.261 +	}
 297.262 +	return false;
 297.263 +}
 297.264 +
 297.265 +// ------------------------------------------------------------------------------------------------
 297.266 +bool XGLImporter::ReadElementUpToClosing(const char* closetag)
 297.267 +{
 297.268 +	while(reader->read()) {
 297.269 +		if (reader->getNodeType() == EXN_ELEMENT) {
 297.270 +			return true;
 297.271 +		}
 297.272 +		else if (reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(reader->getNodeName(),closetag)) {
 297.273 +			return false;
 297.274 +		}
 297.275 +	}
 297.276 +	LogError("unexpected EOF, expected closing <" + std::string(closetag) + "> tag");
 297.277 +	return false;
 297.278 +}
 297.279 +
 297.280 +// ------------------------------------------------------------------------------------------------
 297.281 +bool XGLImporter::SkipToText()
 297.282 +{
 297.283 +	while(reader->read()) {
 297.284 +		if (reader->getNodeType() == EXN_TEXT) {
 297.285 +			return true;
 297.286 +		}
 297.287 +		else if (reader->getNodeType() == EXN_ELEMENT || reader->getNodeType() == EXN_ELEMENT_END) {
 297.288 +			ThrowException("expected text contents but found another element (or element end)");
 297.289 +		}
 297.290 +	}
 297.291 +	return false;
 297.292 +}
 297.293 +
 297.294 +// ------------------------------------------------------------------------------------------------
 297.295 +std::string XGLImporter::GetElementName()
 297.296 +{
 297.297 +	const char* s  = reader->getNodeName();
 297.298 +	size_t len = strlen(s);
 297.299 +
 297.300 +	std::string ret;
 297.301 +	ret.resize(len);
 297.302 +
 297.303 +	std::transform(s,s+len,ret.begin(),::tolower);
 297.304 +	return ret;
 297.305 +}
 297.306 +
 297.307 +// ------------------------------------------------------------------------------------------------
 297.308 +void XGLImporter::ReadWorld(TempScope& scope)
 297.309 +{
 297.310 +	while (ReadElementUpToClosing("world"))	{	
 297.311 +		const std::string& s = GetElementName();
 297.312 +		// XXX right now we'd skip <lighting> if it comes after
 297.313 +		// <object> or <mesh>
 297.314 +		if (s == "lighting") {
 297.315 +			ReadLighting(scope);
 297.316 +		}
 297.317 +		else if (s == "object" || s == "mesh" || s == "mat") {
 297.318 +			break;
 297.319 +		}
 297.320 +	}
 297.321 +
 297.322 +	
 297.323 +	aiNode* const nd = ReadObject(scope,true,"world");
 297.324 +	if(!nd) {
 297.325 +		ThrowException("failure reading <world>");
 297.326 +	}
 297.327 +	if(!nd->mName.length) {
 297.328 +		nd->mName.Set("WORLD");
 297.329 +	}
 297.330 +
 297.331 +	scene->mRootNode = nd;
 297.332 +}
 297.333 +
 297.334 +// ------------------------------------------------------------------------------------------------
 297.335 +void XGLImporter::ReadLighting(TempScope& scope)
 297.336 +{
 297.337 +	while (ReadElementUpToClosing("lighting"))	{
 297.338 +		const std::string& s = GetElementName();
 297.339 +		if (s == "directionallight") {
 297.340 +			scope.light = ReadDirectionalLight();
 297.341 +		}
 297.342 +		else if (s == "ambient") {
 297.343 +			LogWarn("ignoring <ambient> tag");
 297.344 +		}
 297.345 +		else if (s == "spheremap") {
 297.346 +			LogWarn("ignoring <spheremap> tag");
 297.347 +		}
 297.348 +	}
 297.349 +}
 297.350 +
 297.351 +// ------------------------------------------------------------------------------------------------
 297.352 +aiLight* XGLImporter::ReadDirectionalLight()
 297.353 +{
 297.354 +	ScopeGuard<aiLight> l(new aiLight());
 297.355 +	l->mType = aiLightSource_DIRECTIONAL;
 297.356 +
 297.357 +	while (ReadElementUpToClosing("directionallight"))	{	
 297.358 +		const std::string& s = GetElementName();
 297.359 +		if (s == "direction") {
 297.360 +			l->mDirection = ReadVec3();
 297.361 +		}
 297.362 +		else if (s == "diffuse") {
 297.363 +			l->mColorDiffuse = ReadCol3();
 297.364 +		}
 297.365 +		else if (s == "specular") {
 297.366 +			l->mColorSpecular = ReadCol3();
 297.367 +		}
 297.368 +	}
 297.369 +	return l.dismiss();
 297.370 +}
 297.371 +
 297.372 +// ------------------------------------------------------------------------------------------------
 297.373 +aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* closetag)
 297.374 +{
 297.375 +	ScopeGuard<aiNode> nd(new aiNode());
 297.376 +	std::vector<aiNode*> children;
 297.377 +	std::vector<unsigned int> meshes;
 297.378 +
 297.379 +	try {
 297.380 +		while (skipFirst || ReadElementUpToClosing(closetag))	{
 297.381 +			skipFirst = false;
 297.382 +
 297.383 +			const std::string& s = GetElementName();
 297.384 +			if (s == "mesh") {
 297.385 +				const size_t prev = scope.meshes_linear.size();
 297.386 +				if(ReadMesh(scope)) {
 297.387 +					const size_t newc = scope.meshes_linear.size();
 297.388 +					for(size_t i = 0; i < newc-prev; ++i) {
 297.389 +						meshes.push_back(static_cast<unsigned int>(i+prev));
 297.390 +					}
 297.391 +				}
 297.392 +			}
 297.393 +			else if (s == "mat") {
 297.394 +				ReadMaterial(scope);
 297.395 +			}
 297.396 +			else if (s == "object") {
 297.397 +				children.push_back(ReadObject(scope));
 297.398 +			}
 297.399 +			else if (s == "objectref") {
 297.400 +				// XXX
 297.401 +			}
 297.402 +			else if (s == "meshref") {
 297.403 +				const unsigned int id = static_cast<unsigned int>( ReadIndexFromText() );
 297.404 +
 297.405 +				std::multimap<unsigned int, aiMesh*>::iterator it = scope.meshes.find(id), end = scope.meshes.end();
 297.406 +				if (it == end) {
 297.407 +					ThrowException("<meshref> index out of range");
 297.408 +				}
 297.409 +
 297.410 +				for(; it != end && (*it).first == id; ++it) {
 297.411 +					// ok, this is n^2 and should get optimized one day
 297.412 +					aiMesh* const m = (*it).second;
 297.413 +
 297.414 +					unsigned int i = 0, mcount = static_cast<unsigned int>(scope.meshes_linear.size());
 297.415 +					for(; i < mcount; ++i) {
 297.416 +						if (scope.meshes_linear[i] == m) {
 297.417 +							meshes.push_back(i);
 297.418 +							break;
 297.419 +						}
 297.420 +					}
 297.421 +
 297.422 +					ai_assert(i < mcount);
 297.423 +				}
 297.424 +			}
 297.425 +			else if (s == "transform") {
 297.426 +				nd->mTransformation = ReadTrafo();
 297.427 +			}
 297.428 +		}
 297.429 +
 297.430 +	} catch(...) {
 297.431 +		BOOST_FOREACH(aiNode* ch, children) {
 297.432 +			delete ch;
 297.433 +		}
 297.434 +		throw;
 297.435 +	}
 297.436 +
 297.437 +	// link meshes to node
 297.438 +	nd->mNumMeshes = static_cast<unsigned int>(meshes.size());
 297.439 +	if (nd->mNumMeshes) {
 297.440 +		nd->mMeshes = new unsigned int[nd->mNumMeshes]();
 297.441 +		for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
 297.442 +			nd->mMeshes[i] = meshes[i];
 297.443 +		}
 297.444 +	}
 297.445 +
 297.446 +	// link children to parent
 297.447 +	nd->mNumChildren = static_cast<unsigned int>(children.size());
 297.448 +	if (nd->mNumChildren) {
 297.449 +		nd->mChildren = new aiNode*[nd->mNumChildren]();
 297.450 +		for(unsigned int i = 0; i < nd->mNumChildren; ++i) {
 297.451 +			nd->mChildren[i] = children[i];
 297.452 +			children[i]->mParent = nd;
 297.453 +		}
 297.454 +	}
 297.455 +
 297.456 +	return nd.dismiss();
 297.457 +}
 297.458 +
 297.459 +// ------------------------------------------------------------------------------------------------
 297.460 +aiMatrix4x4 XGLImporter::ReadTrafo()
 297.461 +{
 297.462 +	aiVector3D forward, up, right, position;
 297.463 +	float scale = 1.0f;
 297.464 +
 297.465 +	while (ReadElementUpToClosing("transform"))	{	
 297.466 +		const std::string& s = GetElementName();
 297.467 +		if (s == "forward") {
 297.468 +			forward = ReadVec3();
 297.469 +		}
 297.470 +		else if (s == "up") {
 297.471 +			up = ReadVec3();
 297.472 +		}
 297.473 +		else if (s == "position") {
 297.474 +			position = ReadVec3();
 297.475 +		}
 297.476 +		if (s == "scale") {
 297.477 +			scale = ReadFloat();
 297.478 +			if(scale < 0.f) {
 297.479 +				// this is wrong, but we can leave the value and pass it to the caller
 297.480 +				LogError("found negative scaling in <transform>, ignoring");
 297.481 +			}
 297.482 +		}
 297.483 +	}
 297.484 +
 297.485 +	aiMatrix4x4 m;
 297.486 +	if(forward.SquareLength() < 1e-4 || up.SquareLength() < 1e-4) {
 297.487 +		LogError("A direction vector in <transform> is zero, ignoring trafo");
 297.488 +		return m;
 297.489 +	}
 297.490 +
 297.491 +	forward.Normalize();
 297.492 +	up.Normalize();
 297.493 +
 297.494 +	right = forward ^ up;
 297.495 +	if (fabs(up * forward) > 1e-4) {
 297.496 +		// this is definitely wrong - a degenerate coordinate space ruins everything
 297.497 +		// so subtitute identity transform.
 297.498 +		LogError("<forward> and <up> vectors in <transform> are skewing, ignoring trafo");
 297.499 +		return m;
 297.500 +	}
 297.501 +
 297.502 +	right *= scale;
 297.503 +	up *= scale;
 297.504 +	forward *= scale;
 297.505 +
 297.506 +	m.a1 = right.x;
 297.507 +	m.b1 = right.y;
 297.508 +	m.c1 = right.z;
 297.509 +
 297.510 +	m.a2 = up.x;
 297.511 +	m.b2 = up.y;
 297.512 +	m.c2 = up.z;
 297.513 +
 297.514 +	m.a3 = forward.x;
 297.515 +	m.b3 = forward.y;
 297.516 +	m.c3 = forward.z;
 297.517 +
 297.518 +	m.a4 = position.x;
 297.519 +	m.b4 = position.y;
 297.520 +	m.c4 = position.z;
 297.521 +
 297.522 +	return m;
 297.523 +}
 297.524 +
 297.525 +// ------------------------------------------------------------------------------------------------
 297.526 +aiMesh* XGLImporter::ToOutputMesh(const TempMaterialMesh& m)
 297.527 +{
 297.528 +	ScopeGuard<aiMesh> mesh(new aiMesh());
 297.529 +
 297.530 +	mesh->mNumVertices = static_cast<unsigned int>(m.positions.size());
 297.531 +	mesh->mVertices = new aiVector3D[mesh->mNumVertices];
 297.532 +	std::copy(m.positions.begin(),m.positions.end(),mesh->mVertices);
 297.533 +
 297.534 +	if(m.normals.size()) {
 297.535 +		mesh->mNormals = new aiVector3D[mesh->mNumVertices];
 297.536 +		std::copy(m.normals.begin(),m.normals.end(),mesh->mNormals);
 297.537 +	}
 297.538 +
 297.539 +	if(m.uvs.size()) {
 297.540 +		mesh->mNumUVComponents[0] = 2;
 297.541 +		mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
 297.542 +
 297.543 +		for(unsigned int i = 0; i < mesh->mNumVertices; ++i) {
 297.544 +			mesh->mTextureCoords[0][i] = aiVector3D(m.uvs[i].x,m.uvs[i].y,0.f);
 297.545 +		}
 297.546 +	}
 297.547 +
 297.548 +	mesh->mNumFaces =  static_cast<unsigned int>(m.vcounts.size());
 297.549 +	mesh->mFaces = new aiFace[m.vcounts.size()];
 297.550 +
 297.551 +	unsigned int idx = 0;
 297.552 +	for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
 297.553 +		aiFace& f = mesh->mFaces[i];
 297.554 +		f.mNumIndices = m.vcounts[i];
 297.555 +		f.mIndices = new unsigned int[f.mNumIndices];
 297.556 +		for(unsigned int c = 0; c < f.mNumIndices; ++c) {
 297.557 +			f.mIndices[c] = idx++;
 297.558 +		}
 297.559 +	}
 297.560 +
 297.561 +	ai_assert(idx == mesh->mNumVertices);
 297.562 +
 297.563 +	mesh->mPrimitiveTypes = m.pflags;
 297.564 +	mesh->mMaterialIndex = m.matid;
 297.565 +	return mesh.dismiss();
 297.566 +}
 297.567 +
 297.568 +// ------------------------------------------------------------------------------------------------
 297.569 +bool XGLImporter::ReadMesh(TempScope& scope)
 297.570 +{
 297.571 +	TempMesh t;
 297.572 +
 297.573 +	std::map<unsigned int, TempMaterialMesh> bymat;
 297.574 +	const unsigned int mesh_id = ReadIDAttr();
 297.575 +
 297.576 +	while (ReadElementUpToClosing("mesh"))	{	
 297.577 +		const std::string& s = GetElementName();
 297.578 +
 297.579 +		if (s == "mat") {
 297.580 +			ReadMaterial(scope);
 297.581 +		}
 297.582 +		else if (s == "p") {
 297.583 +			if (!reader->getAttributeValue("ID")) {
 297.584 +				LogWarn("no ID attribute on <p>, ignoring");
 297.585 +			}
 297.586 +			else {
 297.587 +				int id = reader->getAttributeValueAsInt("ID");
 297.588 +				t.points[id] = ReadVec3();
 297.589 +			}
 297.590 +		}
 297.591 +		else if (s == "n") {
 297.592 +			if (!reader->getAttributeValue("ID")) {
 297.593 +				LogWarn("no ID attribute on <n>, ignoring");
 297.594 +			}
 297.595 +			else {
 297.596 +				int id = reader->getAttributeValueAsInt("ID");
 297.597 +				t.normals[id] = ReadVec3();
 297.598 +			}
 297.599 +		}
 297.600 +		else if (s == "tc") {
 297.601 +			if (!reader->getAttributeValue("ID")) {
 297.602 +				LogWarn("no ID attribute on <tc>, ignoring");
 297.603 +			}
 297.604 +			else {
 297.605 +				int id = reader->getAttributeValueAsInt("ID");
 297.606 +				t.uvs[id] = ReadVec2();
 297.607 +			}
 297.608 +		}
 297.609 +		else if (s == "f" || s == "l" || s == "p") {
 297.610 +			const unsigned int vcount = s == "f" ? 3 : (s == "l" ? 2 : 1);
 297.611 +
 297.612 +			unsigned int mid = ~0u;
 297.613 +			TempFace tf[3];
 297.614 +			bool has[3] = {0};
 297.615 +
 297.616 +			while (ReadElementUpToClosing(s.c_str()))	{
 297.617 +				const std::string& s = GetElementName();
 297.618 +				if (s == "fv1" || s == "lv1" || s == "pv1") {
 297.619 +					ReadFaceVertex(t,tf[0]);
 297.620 +					has[0] = true;
 297.621 +				}
 297.622 +				else if (s == "fv2" || s == "lv2") {
 297.623 +					ReadFaceVertex(t,tf[1]);
 297.624 +					has[1] = true;
 297.625 +				}
 297.626 +				else if (s == "fv3") {
 297.627 +					ReadFaceVertex(t,tf[2]);
 297.628 +					has[2] = true;
 297.629 +				}
 297.630 +				else if (s == "mat") {
 297.631 +					if (mid != ~0u) {
 297.632 +						LogWarn("only one material tag allowed per <f>");
 297.633 +					}
 297.634 +					mid = ResolveMaterialRef(scope);
 297.635 +				}
 297.636 +				else if (s == "matref") {
 297.637 +					if (mid != ~0u) {
 297.638 +						LogWarn("only one material tag allowed per <f>");
 297.639 +					}
 297.640 +					mid = ResolveMaterialRef(scope);
 297.641 +				}
 297.642 +			}
 297.643 +
 297.644 +			if (mid == ~0u) {
 297.645 +				ThrowException("missing material index");
 297.646 +			}
 297.647 +
 297.648 +			bool nor = false;
 297.649 +			bool uv = false;
 297.650 +			for(unsigned int i = 0; i < vcount; ++i) {
 297.651 +				if (!has[i]) {
 297.652 +					ThrowException("missing face vertex data");
 297.653 +				}
 297.654 +
 297.655 +				nor = nor || tf[i].has_normal;
 297.656 +				uv = uv || tf[i].has_uv;
 297.657 +			}			
 297.658 +
 297.659 +			if (mid >= (1<<30)) {
 297.660 +				LogWarn("material indices exhausted, this may cause errors in the output");
 297.661 +			}
 297.662 +			unsigned int meshId = mid | ((nor?1:0)<<31) | ((uv?1:0)<<30);
 297.663 +
 297.664 +			TempMaterialMesh& mesh = bymat[meshId];
 297.665 +			mesh.matid = mid;
 297.666 +
 297.667 +			for(unsigned int i = 0; i < vcount; ++i) {
 297.668 +				mesh.positions.push_back(tf[i].pos);
 297.669 +				if(nor) {
 297.670 +					mesh.normals.push_back(tf[i].normal);
 297.671 +				}
 297.672 +				if(uv) {
 297.673 +					mesh.uvs.push_back(tf[i].uv);
 297.674 +				}
 297.675 +				
 297.676 +				mesh.pflags |= 1 << (vcount-1);
 297.677 +			}
 297.678 +
 297.679 +			mesh.vcounts.push_back(vcount);
 297.680 +		}		
 297.681 +	}
 297.682 +
 297.683 +	// finally extract output meshes and add them to the scope 
 297.684 +	typedef std::pair<unsigned int, TempMaterialMesh> pairt;
 297.685 +	BOOST_FOREACH(const pairt& p, bymat) {
 297.686 +		aiMesh* const m  = ToOutputMesh(p.second);
 297.687 +		scope.meshes_linear.push_back(m);
 297.688 +
 297.689 +		// if this is a definition, keep it on the stack
 297.690 +		if(mesh_id != ~0u) {
 297.691 +			scope.meshes.insert(std::pair<unsigned int, aiMesh*>(mesh_id,m));
 297.692 +		}
 297.693 +	}
 297.694 +
 297.695 +	// no id == not a reference, insert this mesh right *here*
 297.696 +	return mesh_id == ~0u;
 297.697 +}
 297.698 +
 297.699 +// ----------------------------------------------------------------------------------------------
 297.700 +unsigned int XGLImporter::ResolveMaterialRef(TempScope& scope)
 297.701 +{
 297.702 +	const std::string& s = GetElementName();
 297.703 +	if (s == "mat") {
 297.704 +		ReadMaterial(scope);
 297.705 +		return scope.materials_linear.size()-1;
 297.706 +	}
 297.707 +
 297.708 +	const int id = ReadIndexFromText();
 297.709 +
 297.710 +	std::map<unsigned int, aiMaterial*>::iterator it = scope.materials.find(id), end = scope.materials.end();
 297.711 +	if (it == end) {
 297.712 +		ThrowException("<matref> index out of range");
 297.713 +	}
 297.714 +	
 297.715 +	// ok, this is n^2 and should get optimized one day
 297.716 +	aiMaterial* const m = (*it).second;
 297.717 +
 297.718 +	unsigned int i = 0, mcount = static_cast<unsigned int>(scope.materials_linear.size());
 297.719 +	for(; i < mcount; ++i) {
 297.720 +		if (scope.materials_linear[i] == m) {
 297.721 +			return i;
 297.722 +		}
 297.723 +	}
 297.724 +
 297.725 +	ai_assert(false);
 297.726 +	return 0;
 297.727 +}
 297.728 +
 297.729 +// ------------------------------------------------------------------------------------------------
 297.730 +void XGLImporter::ReadMaterial(TempScope& scope)
 297.731 +{
 297.732 +	const unsigned int mat_id = ReadIDAttr();
 297.733 +
 297.734 +	ScopeGuard<aiMaterial> mat(new aiMaterial());
 297.735 +	while (ReadElementUpToClosing("mat"))  {
 297.736 +		const std::string& s = GetElementName();
 297.737 +		if (s == "amb") {
 297.738 +			const aiColor3D c = ReadCol3();
 297.739 +			mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT);
 297.740 +		}
 297.741 +		else if (s == "diff") {
 297.742 +			const aiColor3D c = ReadCol3();
 297.743 +			mat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE);
 297.744 +		}
 297.745 +		else if (s == "spec") {
 297.746 +			const aiColor3D c = ReadCol3();
 297.747 +			mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
 297.748 +		}
 297.749 +		else if (s == "emiss") {
 297.750 +			const aiColor3D c = ReadCol3();
 297.751 +			mat->AddProperty(&c,1,AI_MATKEY_COLOR_EMISSIVE);
 297.752 +		}
 297.753 +		else if (s == "alpha") {
 297.754 +			const float f = ReadFloat();
 297.755 +			mat->AddProperty(&f,1,AI_MATKEY_OPACITY);
 297.756 +		}
 297.757 +		else if (s == "shine") {
 297.758 +			const float f = ReadFloat();
 297.759 +			mat->AddProperty(&f,1,AI_MATKEY_SHININESS);
 297.760 +		}
 297.761 +	}
 297.762 +
 297.763 +	scope.materials[mat_id] = mat;
 297.764 +	scope.materials_linear.push_back(mat.dismiss());
 297.765 +}
 297.766 +
 297.767 +
 297.768 +// ----------------------------------------------------------------------------------------------
 297.769 +void XGLImporter::ReadFaceVertex(const TempMesh& t, TempFace& out)
 297.770 +{
 297.771 +	const std::string& end = GetElementName();
 297.772 +
 297.773 +	bool havep = false;
 297.774 +	while (ReadElementUpToClosing(end.c_str()))  {
 297.775 +		const std::string& s = GetElementName();
 297.776 +		if (s == "pref") {
 297.777 +			const unsigned int id = ReadIndexFromText();
 297.778 +			std::map<unsigned int, aiVector3D>::const_iterator it = t.points.find(id);
 297.779 +			if (it == t.points.end()) {
 297.780 +				ThrowException("point index out of range");
 297.781 +			}
 297.782 +
 297.783 +			out.pos = (*it).second;
 297.784 +			havep = true;
 297.785 +		}
 297.786 +		else if (s == "nref") {
 297.787 +			const unsigned int id = ReadIndexFromText();
 297.788 +			std::map<unsigned int, aiVector3D>::const_iterator it = t.normals.find(id);
 297.789 +			if (it == t.normals.end()) {
 297.790 +				ThrowException("normal index out of range");
 297.791 +			}
 297.792 +
 297.793 +			out.normal = (*it).second;
 297.794 +			out.has_normal = true;
 297.795 +		}
 297.796 +		else if (s == "tcref") {
 297.797 +			const unsigned int id = ReadIndexFromText();
 297.798 +			std::map<unsigned int, aiVector2D>::const_iterator it = t.uvs.find(id);
 297.799 +			if (it == t.uvs.end()) {
 297.800 +				ThrowException("uv index out of range");
 297.801 +			}
 297.802 +
 297.803 +			out.uv = (*it).second;
 297.804 +			out.has_uv = true;
 297.805 +		}
 297.806 +		else if (s == "p") {
 297.807 +			out.pos = ReadVec3();
 297.808 +		}
 297.809 +		else if (s == "n") {
 297.810 +			out.normal = ReadVec3();
 297.811 +		}
 297.812 +		else if (s == "tc") {
 297.813 +			out.uv = ReadVec2();
 297.814 +		}
 297.815 +	}
 297.816 +
 297.817 +	if (!havep) {
 297.818 +		ThrowException("missing <pref> in <fvN> element");
 297.819 +	}
 297.820 +}
 297.821 +
 297.822 +// ------------------------------------------------------------------------------------------------
 297.823 +unsigned int XGLImporter::ReadIDAttr()
 297.824 +{
 297.825 +	for(int i = 0, e = reader->getAttributeCount(); i < e; ++i) {
 297.826 +	
 297.827 +		if(!ASSIMP_stricmp(reader->getAttributeName(i),"id")) {
 297.828 +			return reader->getAttributeValueAsInt(i);
 297.829 +		}
 297.830 +	}	
 297.831 +	return ~0u;
 297.832 +}
 297.833 +
 297.834 +// ------------------------------------------------------------------------------------------------
 297.835 +float XGLImporter::ReadFloat()
 297.836 +{
 297.837 +	if(!SkipToText()) {
 297.838 +		LogError("unexpected EOF reading float element contents");
 297.839 +		return 0.f;
 297.840 +	}
 297.841 +	const char* s = reader->getNodeData(), *se;
 297.842 +
 297.843 +	if(!SkipSpaces(&s)) {
 297.844 +		LogError("unexpected EOL, failed to parse float");
 297.845 +		return 0.f;
 297.846 +	}
 297.847 +
 297.848 +	float t;
 297.849 +	se = fast_atoreal_move(s,t);
 297.850 +
 297.851 +	if (se == s) {
 297.852 +		LogError("failed to read float text");
 297.853 +		return 0.f;
 297.854 +	}
 297.855 +
 297.856 +	return t;
 297.857 +}
 297.858 +
 297.859 +// ------------------------------------------------------------------------------------------------
 297.860 +unsigned int XGLImporter::ReadIndexFromText()
 297.861 +{
 297.862 +	if(!SkipToText()) {
 297.863 +		LogError("unexpected EOF reading index element contents");
 297.864 +		return ~0u;
 297.865 +	}
 297.866 +	const char* s = reader->getNodeData(), *se;
 297.867 +	if(!SkipSpaces(&s)) {
 297.868 +		LogError("unexpected EOL, failed to parse index element");
 297.869 +		return ~0u;
 297.870 +	}
 297.871 +
 297.872 +	const unsigned int t = strtoul10(s,&se);
 297.873 +
 297.874 +	if (se == s) {
 297.875 +		LogError("failed to read index");
 297.876 +		return ~0u;
 297.877 +	}
 297.878 +
 297.879 +	return t;
 297.880 +}
 297.881 +
 297.882 +// ------------------------------------------------------------------------------------------------
 297.883 +aiVector2D XGLImporter::ReadVec2()
 297.884 +{
 297.885 +	aiVector2D vec;
 297.886 +
 297.887 +	if(!SkipToText()) {
 297.888 +		LogError("unexpected EOF reading vec2 contents");
 297.889 +		return vec;
 297.890 +	}
 297.891 +	const char* s = reader->getNodeData();
 297.892 +
 297.893 +	for(int i = 0; i < 2; ++i) {
 297.894 +		if(!SkipSpaces(&s)) {
 297.895 +			LogError("unexpected EOL, failed to parse vec2");
 297.896 +			return vec;
 297.897 +		}
 297.898 +		vec[i] = fast_atof(&s);
 297.899 +
 297.900 +		SkipSpaces(&s);
 297.901 +		if (i != 1 && *s != ',') {
 297.902 +			LogError("expected comma, failed to parse vec2");
 297.903 +			return vec;
 297.904 +		}
 297.905 +		++s;
 297.906 +	}
 297.907 +
 297.908 +	return vec;
 297.909 +}
 297.910 +
 297.911 +// ------------------------------------------------------------------------------------------------
 297.912 +aiVector3D XGLImporter::ReadVec3()
 297.913 +{
 297.914 +	aiVector3D vec;
 297.915 +
 297.916 +	if(!SkipToText()) {
 297.917 +		LogError("unexpected EOF reading vec3 contents");
 297.918 +		return vec;
 297.919 +	}
 297.920 +	const char* s = reader->getNodeData();
 297.921 +
 297.922 +	for(int i = 0; i < 3; ++i) {
 297.923 +		if(!SkipSpaces(&s)) {
 297.924 +			LogError("unexpected EOL, failed to parse vec3");
 297.925 +			return vec;
 297.926 +		}
 297.927 +		vec[i] = fast_atof(&s);
 297.928 +
 297.929 +		SkipSpaces(&s);
 297.930 +		if (i != 2 && *s != ',') {
 297.931 +			LogError("expected comma, failed to parse vec3");
 297.932 +			return vec;
 297.933 +		}
 297.934 +		++s;
 297.935 +	}
 297.936 +
 297.937 +	return vec;
 297.938 +}
 297.939 +
 297.940 +// ------------------------------------------------------------------------------------------------
 297.941 +aiColor3D XGLImporter::ReadCol3()
 297.942 +{
 297.943 +	const aiVector3D& v = ReadVec3();
 297.944 +	if (v.x < 0.f || v.x > 1.0f || v.y < 0.f || v.y > 1.0f || v.z < 0.f || v.z > 1.0f) {
 297.945 +		LogWarn("color values out of range, ignoring");
 297.946 +	}
 297.947 +	return aiColor3D(v.x,v.y,v.z);
 297.948 +}
 297.949 +
 297.950 +#endif 
   298.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   298.2 +++ b/libs/assimp/XGLLoader.h	Sat Feb 01 19:58:19 2014 +0200
   298.3 @@ -0,0 +1,199 @@
   298.4 +/*
   298.5 +Open Asset Import Library (assimp)
   298.6 +----------------------------------------------------------------------
   298.7 +
   298.8 +Copyright (c) 2006-2012, assimp team
   298.9 +All rights reserved.
  298.10 +
  298.11 +Redistribution and use of this software in source and binary forms, 
  298.12 +with or without modification, are permitted provided that the 
  298.13 +following conditions are met:
  298.14 +
  298.15 +* Redistributions of source code must retain the above
  298.16 +  copyright notice, this list of conditions and the
  298.17 +  following disclaimer.
  298.18 +
  298.19 +* Redistributions in binary form must reproduce the above
  298.20 +  copyright notice, this list of conditions and the
  298.21 +  following disclaimer in the documentation and/or other
  298.22 +  materials provided with the distribution.
  298.23 +
  298.24 +* Neither the name of the assimp team, nor the names of its
  298.25 +  contributors may be used to endorse or promote products
  298.26 +  derived from this software without specific prior
  298.27 +  written permission of the assimp team.
  298.28 +
  298.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  298.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  298.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  298.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  298.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  298.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  298.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  298.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  298.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  298.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  298.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  298.40 +
  298.41 +----------------------------------------------------------------------
  298.42 +*/
  298.43 +
  298.44 +/** @file XGLLoader.h
  298.45 + *  @brief Declaration of the .xgl/.zgl
  298.46 + */
  298.47 +#ifndef AI_XGLLOADER_H_INCLUDED
  298.48 +#define AI_XGLLOADER_H_INCLUDED
  298.49 +
  298.50 +#include "BaseImporter.h"
  298.51 +#include "irrXMLWrapper.h"
  298.52 +#include "LogAux.h"
  298.53 +
  298.54 +namespace Assimp	{
  298.55 +
  298.56 +// ---------------------------------------------------------------------------
  298.57 +/** XGL/ZGL importer.
  298.58 + *
  298.59 + * Spec: http://vizstream.aveva.com/release/vsplatform/XGLSpec.htm
  298.60 + */
  298.61 +class XGLImporter : public BaseImporter, public LogFunctions<XGLImporter>
  298.62 +{
  298.63 +public:
  298.64 +
  298.65 +	XGLImporter();
  298.66 +	~XGLImporter();
  298.67 +
  298.68 +
  298.69 +public:
  298.70 +
  298.71 +	// -------------------------------------------------------------------
  298.72 +	/** Returns whether the class can handle the format of the given file. 
  298.73 +	 *  See BaseImporter::CanRead() for details.	*/
  298.74 +	bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
  298.75 +		bool checkSig) const;
  298.76 +
  298.77 +protected:
  298.78 +
  298.79 +	// -------------------------------------------------------------------
  298.80 +	/** Return importer meta information.
  298.81 +	 * See #BaseImporter::GetInfo for the details  */
  298.82 +	const aiImporterDesc* GetInfo () const;
  298.83 +
  298.84 +	// -------------------------------------------------------------------
  298.85 +	/** Imports the given file into the given scene structure. 
  298.86 +	 * See BaseImporter::InternReadFile() for details */
  298.87 +	void InternReadFile( const std::string& pFile, aiScene* pScene, 
  298.88 +		IOSystem* pIOHandler);
  298.89 +
  298.90 +private:
  298.91 +
  298.92 +	struct TempScope
  298.93 +	{
  298.94 +		TempScope()
  298.95 +			: light()
  298.96 +		{}
  298.97 +
  298.98 +		~TempScope()
  298.99 +		{
 298.100 +			BOOST_FOREACH(aiMesh* m, meshes_linear) {
 298.101 +				delete m;
 298.102 +			}
 298.103 +
 298.104 +			BOOST_FOREACH(aiMaterial* m, materials_linear) {
 298.105 +				delete m;
 298.106 +			}
 298.107 +
 298.108 +			delete light;
 298.109 +		}
 298.110 +
 298.111 +		void dismiss() {
 298.112 +			light = NULL;
 298.113 +			meshes_linear.clear();
 298.114 +			materials_linear.clear();
 298.115 +			meshes.clear();
 298.116 +			materials.clear();
 298.117 +		}
 298.118 +
 298.119 +		std::multimap<unsigned int, aiMesh*> meshes;
 298.120 +		std::map<unsigned int, aiMaterial*> materials;
 298.121 +
 298.122 +		std::vector<aiMesh*> meshes_linear;
 298.123 +		std::vector<aiMaterial*> materials_linear;
 298.124 +
 298.125 +		aiLight* light;
 298.126 +	};
 298.127 +
 298.128 +	struct TempMesh
 298.129 +	{
 298.130 +		std::map<unsigned int, aiVector3D> points;
 298.131 +		std::map<unsigned int, aiVector3D> normals;
 298.132 +		std::map<unsigned int, aiVector2D> uvs;
 298.133 +	};
 298.134 +
 298.135 +	struct TempMaterialMesh
 298.136 +	{
 298.137 +		TempMaterialMesh()
 298.138 +			: pflags()
 298.139 +			, matid()
 298.140 +		{}
 298.141 +
 298.142 +		std::vector<aiVector3D> positions, normals;
 298.143 +		std::vector<aiVector2D> uvs;
 298.144 +
 298.145 +		std::vector<unsigned int> vcounts;
 298.146 +		unsigned int pflags;
 298.147 +		unsigned int matid;
 298.148 +	};
 298.149 +
 298.150 +	struct TempFace
 298.151 +	{
 298.152 +		TempFace()
 298.153 +			: has_uv()
 298.154 +			, has_normal()
 298.155 +		{}
 298.156 +
 298.157 +		aiVector3D pos;
 298.158 +		aiVector3D normal;
 298.159 +		aiVector2D uv;
 298.160 +		bool has_uv;
 298.161 +		bool has_normal;
 298.162 +	};
 298.163 +
 298.164 +private:
 298.165 +
 298.166 +	void Cleanup();
 298.167 +
 298.168 +	std::string GetElementName();
 298.169 +	bool ReadElement();
 298.170 +	bool ReadElementUpToClosing(const char* closetag);
 298.171 +	bool SkipToText();
 298.172 +	unsigned int ReadIDAttr();
 298.173 +
 298.174 +	void ReadWorld(TempScope& scope);
 298.175 +	void ReadLighting(TempScope& scope);
 298.176 +	aiLight* ReadDirectionalLight();
 298.177 +	aiNode* ReadObject(TempScope& scope,bool skipFirst = false,const char* closetag = "object");
 298.178 +	bool ReadMesh(TempScope& scope);
 298.179 +	void ReadMaterial(TempScope& scope);
 298.180 +	aiVector2D ReadVec2();
 298.181 +	aiVector3D ReadVec3();
 298.182 +	aiColor3D ReadCol3();
 298.183 +	aiMatrix4x4 ReadTrafo();
 298.184 +	unsigned int ReadIndexFromText();
 298.185 +	float ReadFloat();
 298.186 +
 298.187 +	aiMesh* ToOutputMesh(const TempMaterialMesh& m);
 298.188 +	void ReadFaceVertex(const TempMesh& t, TempFace& out);
 298.189 +	unsigned int ResolveMaterialRef(TempScope& scope);
 298.190 +
 298.191 +private:
 298.192 +
 298.193 +
 298.194 +private:
 298.195 +
 298.196 +	irr::io::IrrXMLReader* reader;
 298.197 +	aiScene* scene;
 298.198 +};
 298.199 +
 298.200 +} // end of namespace Assimp
 298.201 +
 298.202 +#endif // AI_IRRMESHIMPORTER_H_INC
   299.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   299.2 +++ b/libs/assimp/assbin_chunks.h	Sat Feb 01 19:58:19 2014 +0200
   299.3 @@ -0,0 +1,196 @@
   299.4 +
   299.5 +#ifndef INCLUDED_ASSBIN_CHUNKS_H
   299.6 +#define INCLUDED_ASSBIN_CHUNKS_H
   299.7 +
   299.8 +#define ASSBIN_VERSION_MAJOR 1
   299.9 +#define ASSBIN_VERSION_MINOR 0
  299.10 +
  299.11 +/** 
  299.12 +@page assfile .ASS File formats
  299.13 +
  299.14 +@section over Overview
  299.15 +Assimp provides its own interchange format, which is intended to applications which need
  299.16 +to serialize 3D-models and to reload them quickly. Assimp's file formats are designed to
  299.17 +be read by Assimp itself. They encode additional information needed by Assimp to optimize
  299.18 +its postprocessing pipeline. If you once apply specific steps to a scene, then save it
  299.19 +and reread it from an ASS format using the same post processing settings, they won't
  299.20 +be executed again.
  299.21 +
  299.22 +The format comes in two flavours: XML and binary - both of them hold a complete dump of
  299.23 +the 'aiScene' data structure returned by the APIs. The focus for the binary format
  299.24 +(<tt>.assbin</tt>) is fast loading. Optional deflate compression helps reduce file size. The XML
  299.25 +flavour, <tt>.assxml</tt> or simply .xml, is just a plain-to-xml conversion of aiScene.
  299.26 +
  299.27 +ASSBIN is Assimp's binary interchange format. assimp_cmd (<tt>&lt;root&gt;/tools/assimp_cmd</tt>) is able to 
  299.28 +write it and the core library provides a loader for it.
  299.29 +
  299.30 +@section assxml XML File format
  299.31 +
  299.32 +The format is pretty much self-explanatory due to its similarity to the in-memory aiScene structure.
  299.33 +With few exceptions, C structures are wrapped in XML elements.
  299.34 +
  299.35 +The DTD for ASSXML can be found in <tt>&lt;root&gt;/doc/AssXML_Scheme.xml</tt>. Or have   look
  299.36 +at the output files generated by assimp_cmd.
  299.37 +
  299.38 +@section assbin Binary file format
  299.39 +
  299.40 +The ASSBIN file format is composed of chunks to represent the hierarchical aiScene data structure.
  299.41 +This makes the format extensible and allows backward-compatibility with future data structure
  299.42 +versions. The <tt>&lt;root&gt;/code/assbin_chunks.h</tt> header contains some magic constants
  299.43 +for use by stand-alone ASSBIN loaders. Also, Assimp's own file writer can be found
  299.44 +in <tt>&lt;root&gt;/tools/assimp_cmd/WriteDumb.cpp</tt> (yes, the 'b' is no typo ...).
  299.45 +
  299.46 +@verbatim
  299.47 +
  299.48 +-------------------------------------------------------------------------------
  299.49 +1. File structure:
  299.50 +-------------------------------------------------------------------------------
  299.51 +
  299.52 +----------------------
  299.53 +| Header (500 bytes) |
  299.54 +----------------------
  299.55 +| Variable chunks    |
  299.56 +----------------------
  299.57 +
  299.58 +-------------------------------------------------------------------------------
  299.59 +2. Definitions:
  299.60 +-------------------------------------------------------------------------------
  299.61 +
  299.62 +integer	is four bytes wide, stored in little-endian byte order.
  299.63 +short	is two bytes wide, stored in little-endian byte order.
  299.64 +byte	is a single byte.
  299.65 +string  is an integer n followed by n UTF-8 characters, not terminated by zero
  299.66 +float	is an IEEE 754 single-precision floating-point value 
  299.67 +double	is an IEEE 754 double-precision floating-point value 
  299.68 +t[n]    is an array of n elements of type t
  299.69 +
  299.70 +-------------------------------------------------------------------------------
  299.71 +2. Header:
  299.72 +-------------------------------------------------------------------------------
  299.73 +
  299.74 +byte[44]	Magic identification string for ASSBIN files.
  299.75 +                'ASSIMP.binary'
  299.76 +
  299.77 +integer		Major version of the Assimp library which wrote the file
  299.78 +integer		Minor version of the Assimp library which wrote the file
  299.79 +                match these against ASSBIN_VERSION_MAJOR and ASSBIN_VERSION_MINOR
  299.80 +
  299.81 +integer		SVN revision of the Assimp library (intended for our internal
  299.82 +            debugging - if you write Ass files from your own APPs, set this value to 0.
  299.83 +integer		Assimp compile flags
  299.84 +
  299.85 +short		0 for normal files, 1 for shortened dumps for regression tests 
  299.86 +                these should have the file extension assbin.regress
  299.87 +
  299.88 +short       1 if the data after the header is compressed with the DEFLATE algorithm,
  299.89 +            0 for uncompressed files.
  299.90 +                   For compressed files, the first integer after the header is
  299.91 +                   always the uncompressed data size
  299.92 +                
  299.93 +byte[256]	Zero-terminated source file name, UTF-8
  299.94 +byte[128]	Zero-terminated command line parameters passed to assimp_cmd, UTF-8 
  299.95 +
  299.96 +byte[64]	Reserved for future use
  299.97 +---> Total length: 512 bytes
  299.98 +
  299.99 +-------------------------------------------------------------------------------
 299.100 +3. Chunks:
 299.101 +-------------------------------------------------------------------------------
 299.102 +
 299.103 +integer		Magic chunk ID (ASSBIN_CHUNK_XXX)
 299.104 +integer		Chunk data length, in bytes 
 299.105 +                (unknown chunks are possible, a good reader skips over them)
 299.106 +
 299.107 +byte[n]		length-of-chunk bytes of data, depending on the chunk type
 299.108 +
 299.109 +Chunks can contain nested chunks. Nested chunks are ALWAYS at the end of the chunk,
 299.110 +their size is included in length-of-chunk.
 299.111 +
 299.112 +The chunk layout for all ASSIMP data structures is derived from their C declarations.
 299.113 +The general 'rule' to get from Assimp headers to the serialized layout is:
 299.114 +
 299.115 +   1. POD members (i.e. aiMesh::mPrimitiveTypes, aiMesh::mNumVertices), 
 299.116 +        in order of declaration.
 299.117 +
 299.118 +   2. Array-members (aiMesh::mFaces, aiMesh::mVertices, aiBone::mWeights), 
 299.119 +        in order of declaration.
 299.120 +
 299.121 +   2. Object array members (i.e aiMesh::mBones, aiScene::mMeshes) are stored in 
 299.122 +      subchunks directly following the data written in 1.) and 2.)
 299.123 +
 299.124 +
 299.125 +	Of course, there are some exceptions to this general order:
 299.126 +
 299.127 +[[aiScene]]
 299.128 +
 299.129 +   - The root node holding the scene structure is naturally stored in
 299.130 +     a ASSBIN_CHUNK_AINODE subchunk following 1.) and 2.) (which is 
 299.131 +	 empty for aiScene).
 299.132 +
 299.133 +[[aiMesh]]
 299.134 +
 299.135 +   - mTextureCoords and mNumUVComponents are serialized as follows:
 299.136 +
 299.137 +   [number of used uv channels times]
 299.138 +       integer mNumUVComponents[n]
 299.139 +       float mTextureCoords[n][mNumUVComponents[n]]
 299.140 +
 299.141 +       -> more than AI_MAX_TEXCOORD_CHANNELS can be stored. This allows Assimp 
 299.142 +	   builds with different settings for AI_MAX_TEXCOORD_CHANNELS to exchange
 299.143 +	   data. Unlike the in-memory format, only the used components of the 
 299.144 +	   UV coordinates are written to disk. If mNumUVComponents[0] is 1, the
 299.145 +	   corresponding mTextureCoords array consists of mNumTextureCoords*1 
 299.146 +	   single floats.
 299.147 +
 299.148 +   - The array member block of aiMesh is prefixed with an integer that specifies 
 299.149 +     the kinds of vertex components actually present in the mesh. This is a 
 299.150 +	 bitwise combination of the ASSBIN_MESH_HAS_xxx constants.
 299.151 +
 299.152 +[[aiFace]]
 299.153 +
 299.154 +   - mNumIndices is stored as short
 299.155 +   - mIndices are written as short, if aiMesh::mNumVertices<65536
 299.156 +
 299.157 +[[aiNode]]
 299.158 +
 299.159 +   - mParent is omitted
 299.160 +
 299.161 +[[aiLight]]
 299.162 +
 299.163 +   - mAttenuationXXX not written if aiLight::mType == aiLightSource_DIRECTIONAL
 299.164 +   - mAngleXXX not written if aiLight::mType != aiLightSource_SPOT
 299.165 +
 299.166 +[[aiMaterial]]
 299.167 +
 299.168 +   - mNumAllocated is omitted, for obvious reasons :-)
 299.169 +
 299.170 +
 299.171 + @endverbatim*/
 299.172 +
 299.173 +
 299.174 +#define ASSBIN_HEADER_LENGTH 512
 299.175 +
 299.176 +// these are the magic chunk identifiers for the binary ASS file format
 299.177 +#define ASSBIN_CHUNK_AICAMERA					0x1234
 299.178 +#define ASSBIN_CHUNK_AILIGHT					0x1235
 299.179 +#define ASSBIN_CHUNK_AITEXTURE					0x1236
 299.180 +#define ASSBIN_CHUNK_AIMESH						0x1237
 299.181 +#define ASSBIN_CHUNK_AINODEANIM					0x1238
 299.182 +#define ASSBIN_CHUNK_AISCENE					0x1239
 299.183 +#define ASSBIN_CHUNK_AIBONE						0x123a
 299.184 +#define ASSBIN_CHUNK_AIANIMATION				0x123b
 299.185 +#define ASSBIN_CHUNK_AINODE						0x123c
 299.186 +#define ASSBIN_CHUNK_AIMATERIAL					0x123d
 299.187 +#define ASSBIN_CHUNK_AIMATERIALPROPERTY			0x123e
 299.188 +
 299.189 +#define ASSBIN_MESH_HAS_POSITIONS					0x1
 299.190 +#define ASSBIN_MESH_HAS_NORMALS						0x2
 299.191 +#define ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS		0x4
 299.192 +#define ASSBIN_MESH_HAS_TEXCOORD_BASE				0x100
 299.193 +#define ASSBIN_MESH_HAS_COLOR_BASE					0x10000
 299.194 +
 299.195 +#define ASSBIN_MESH_HAS_TEXCOORD(n)	(ASSBIN_MESH_HAS_TEXCOORD_BASE << n)
 299.196 +#define ASSBIN_MESH_HAS_COLOR(n)	(ASSBIN_MESH_HAS_COLOR_BASE << n)
 299.197 +
 299.198 +
 299.199 +#endif // INCLUDED_ASSBIN_CHUNKS_H
   300.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   300.2 +++ b/libs/assimp/assimp/Compiler/poppack1.h	Sat Feb 01 19:58:19 2014 +0200
   300.3 @@ -0,0 +1,22 @@
   300.4 +
   300.5 +// ===============================================================================
   300.6 +// May be included multiple times - resets structure packing to the defaults 
   300.7 +// for all supported compilers. Reverts the changes made by #include <pushpack1.h> 
   300.8 +//
   300.9 +// Currently this works on the following compilers:
  300.10 +// MSVC 7,8,9
  300.11 +// GCC
  300.12 +// BORLAND (complains about 'pack state changed but not reverted', but works)
  300.13 +// ===============================================================================
  300.14 +
  300.15 +#ifndef AI_PUSHPACK_IS_DEFINED
  300.16 +#	error pushpack1.h must be included after poppack1.h
  300.17 +#endif
  300.18 +
  300.19 +// reset packing to the original value
  300.20 +#if defined(_MSC_VER) ||  defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
  300.21 +#	pragma pack( pop )
  300.22 +#endif
  300.23 +#undef PACK_STRUCT
  300.24 +
  300.25 +#undef AI_PUSHPACK_IS_DEFINED
   301.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   301.2 +++ b/libs/assimp/assimp/Compiler/pushpack1.h	Sat Feb 01 19:58:19 2014 +0200
   301.3 @@ -0,0 +1,41 @@
   301.4 +
   301.5 +
   301.6 +// ===============================================================================
   301.7 +// May be included multiple times - sets structure packing to 1 
   301.8 +// for all supported compilers. #include <poppack1.h> reverts the changes.
   301.9 +//
  301.10 +// Currently this works on the following compilers:
  301.11 +// MSVC 7,8,9
  301.12 +// GCC
  301.13 +// BORLAND (complains about 'pack state changed but not reverted', but works)
  301.14 +//
  301.15 +//
  301.16 +// USAGE:
  301.17 +//
  301.18 +// struct StructToBePacked {
  301.19 +// } PACK_STRUCT;
  301.20 +//
  301.21 +// ===============================================================================
  301.22 +
  301.23 +#ifdef AI_PUSHPACK_IS_DEFINED
  301.24 +#	error poppack1.h must be included after pushpack1.h
  301.25 +#endif
  301.26 +
  301.27 +#if defined(_MSC_VER) ||  defined(__BORLANDC__) ||	defined (__BCPLUSPLUS__)
  301.28 +#	pragma pack(push,1)
  301.29 +#	define PACK_STRUCT
  301.30 +#elif defined( __GNUC__ )
  301.31 +#	define PACK_STRUCT	__attribute__((packed))
  301.32 +#else
  301.33 +#	error Compiler not supported
  301.34 +#endif
  301.35 +
  301.36 +#if defined(_MSC_VER)
  301.37 +
  301.38 +// C4103: Packing was changed after the inclusion of the header, propably missing #pragma pop
  301.39 +#	pragma warning (disable : 4103) 
  301.40 +#endif
  301.41 +
  301.42 +#define AI_PUSHPACK_IS_DEFINED
  301.43 +
  301.44 +
   302.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   302.2 +++ b/libs/assimp/assimp/DefaultLogger.hpp	Sat Feb 01 19:58:19 2014 +0200
   302.3 @@ -0,0 +1,190 @@
   302.4 +/*
   302.5 +Open Asset Import Library (assimp)
   302.6 +----------------------------------------------------------------------
   302.7 +
   302.8 +Copyright (c) 2006-2012, assimp team
   302.9 +All rights reserved.
  302.10 +
  302.11 +Redistribution and use of this software in source and binary forms, 
  302.12 +with or without modification, are permitted provided that the 
  302.13 +following conditions are met:
  302.14 +
  302.15 +* Redistributions of source code must retain the above
  302.16 +  copyright notice, this list of conditions and the
  302.17 +  following disclaimer.
  302.18 +
  302.19 +* Redistributions in binary form must reproduce the above
  302.20 +  copyright notice, this list of conditions and the
  302.21 +  following disclaimer in the documentation and/or other
  302.22 +  materials provided with the distribution.
  302.23 +
  302.24 +* Neither the name of the assimp team, nor the names of its
  302.25 +  contributors may be used to endorse or promote products
  302.26 +  derived from this software without specific prior
  302.27 +  written permission of the assimp team.
  302.28 +
  302.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  302.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  302.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  302.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  302.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  302.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  302.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  302.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  302.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  302.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  302.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  302.40 +
  302.41 +----------------------------------------------------------------------
  302.42 +*/
  302.43 +/** @file DefaultLogger.h
  302.44 +*/
  302.45 +
  302.46 +#ifndef INCLUDED_AI_DEFAULTLOGGER
  302.47 +#define INCLUDED_AI_DEFAULTLOGGER
  302.48 +
  302.49 +#include "Logger.hpp"
  302.50 +#include "LogStream.hpp"
  302.51 +#include "NullLogger.hpp"
  302.52 +#include <vector>
  302.53 +
  302.54 +namespace Assimp	{
  302.55 +// ------------------------------------------------------------------------------------
  302.56 +class IOStream;
  302.57 +struct LogStreamInfo;
  302.58 +
  302.59 +/** default name of logfile */
  302.60 +#define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt"
  302.61 +
  302.62 +// ------------------------------------------------------------------------------------
  302.63 +/** @brief CPP-API: Primary logging facility of Assimp. 
  302.64 + *
  302.65 + *  The library stores its primary #Logger as a static member of this class.
  302.66 + *  #get() returns this primary logger. By default the underlying implementation is
  302.67 + *  just a #NullLogger which rejects all log messages. By calling #create(), logging
  302.68 + *  is turned on. To capture the log output multiple log streams (#LogStream) can be
  302.69 + *  attach to the logger. Some default streams for common streaming locations (such as
  302.70 + *  a file, std::cout, OutputDebugString()) are also provided.
  302.71 + *  
  302.72 + *  If you wish to customize the logging at an even deeper level supply your own
  302.73 + *  implementation of #Logger to #set().
  302.74 + *  @note The whole logging stuff causes a small extra overhead for all imports. */
  302.75 +class ASSIMP_API DefaultLogger :
  302.76 +	public Logger	{
  302.77 +
  302.78 +public:
  302.79 +
  302.80 +	// ----------------------------------------------------------------------
  302.81 +	/** @brief Creates a logging instance.
  302.82 +	 *  @param name Name for log file. Only valid in combination
  302.83 +	 *    with the aiDefaultLogStream_FILE flag. 
  302.84 +	 *  @param severity	Log severity, VERBOSE turns on debug messages
  302.85 +	 *  @param defStreams  Default log streams to be attached. Any bitwise
  302.86 +	 *    combination of the aiDefaultLogStream enumerated values. 
  302.87 +	 *    If #aiDefaultLogStream_FILE is specified but an empty string is
  302.88 +	 *    passed for 'name', no log file is created at all.
  302.89 +	 *  @param  io IOSystem to be used to open external files (such as the 
  302.90 +	 *   log file). Pass NULL to rely on the default implementation.
  302.91 +	 *  This replaces the default #NullLogger with a #DefaultLogger instance. */
  302.92 +	static Logger *create(const char* name = ASSIMP_DEFAULT_LOG_NAME,
  302.93 +		LogSeverity severity    = NORMAL,
  302.94 +		unsigned int defStreams = aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE,
  302.95 +		IOSystem* io		    = NULL);
  302.96 +
  302.97 +	// ----------------------------------------------------------------------
  302.98 +	/** @brief Setup a custom #Logger implementation.
  302.99 +	 *
 302.100 +	 *  Use this if the provided #DefaultLogger class doesn't fit into
 302.101 +	 *  your needs. If the provided message formatting is OK for you,
 302.102 +	 *  it's much easier to use #create() and to attach your own custom 
 302.103 +	 *  output streams to it.
 302.104 +	 *  @param logger Pass NULL to setup a default NullLogger*/
 302.105 +	static void set (Logger *logger);
 302.106 +	
 302.107 +	// ----------------------------------------------------------------------
 302.108 +	/** @brief	Getter for singleton instance
 302.109 +	 *	 @return Only instance. This is never null, but it could be a 
 302.110 +	 *  NullLogger. Use isNullLogger to check this.*/
 302.111 +	static Logger *get();
 302.112 +
 302.113 +	// ----------------------------------------------------------------------
 302.114 +	/** @brief  Return whether a #NullLogger is currently active
 302.115 +	 *  @return true if the current logger is a #NullLogger.
 302.116 +	 *  Use create() or set() to setup a logger that does actually do
 302.117 +	 *  something else than just rejecting all log messages. */
 302.118 +	static bool isNullLogger();
 302.119 +	
 302.120 +	// ----------------------------------------------------------------------
 302.121 +	/** @brief	Kills the current singleton logger and replaces it with a
 302.122 +	 *  #NullLogger instance. */
 302.123 +	static void kill();
 302.124 +	
 302.125 +	// ----------------------------------------------------------------------
 302.126 +	/**	@copydoc Logger::attachStream   */
 302.127 +	bool attachStream(LogStream *pStream,
 302.128 +		unsigned int severity);
 302.129 +
 302.130 +	// ----------------------------------------------------------------------
 302.131 +	/**	@copydoc Logger::detatchStream */
 302.132 +	bool detatchStream(LogStream *pStream, 
 302.133 +		unsigned int severity);
 302.134 +
 302.135 +
 302.136 +private:
 302.137 +
 302.138 +	// ----------------------------------------------------------------------
 302.139 +	/** @briefPrivate construction for internal use by create().
 302.140 +	 *  @param severity Logging granularity  */
 302.141 +	DefaultLogger(LogSeverity severity);
 302.142 +	
 302.143 +	// ----------------------------------------------------------------------
 302.144 +	/**	@briefDestructor	*/
 302.145 +	~DefaultLogger();
 302.146 +
 302.147 +private:
 302.148 +
 302.149 +	/**	@brief	Logs debug infos, only been written when severity level VERBOSE is set */
 302.150 +	void OnDebug(const char* message);
 302.151 +
 302.152 +	/**	@brief	Logs an info message */
 302.153 +	void OnInfo(const char*  message);
 302.154 +
 302.155 +	/**	@brief	Logs a warning message */
 302.156 +	void OnWarn(const char*  message);
 302.157 +	
 302.158 +	/**	@brief	Logs an error message */
 302.159 +	void OnError(const char* message);
 302.160 +
 302.161 +	// ----------------------------------------------------------------------
 302.162 +	/**	@brief Writes a message to all streams */
 302.163 +	void WriteToStreams(const char* message, ErrorSeverity ErrorSev );
 302.164 +
 302.165 +	// ----------------------------------------------------------------------
 302.166 +	/** @brief Returns the thread id.
 302.167 +	 *	@note This is an OS specific feature, if not supported, a 
 302.168 +	 *    zero will be returned.
 302.169 +	 */
 302.170 +	unsigned int GetThreadID();
 302.171 +
 302.172 +private:
 302.173 +	//	Aliases for stream container
 302.174 +	typedef std::vector<LogStreamInfo*>	StreamArray;
 302.175 +	typedef std::vector<LogStreamInfo*>::iterator StreamIt;
 302.176 +	typedef std::vector<LogStreamInfo*>::const_iterator ConstStreamIt;
 302.177 +
 302.178 +	//!	only logging instance
 302.179 +	static Logger *m_pLogger;
 302.180 +	static NullLogger s_pNullLogger;
 302.181 +
 302.182 +	//!	Attached streams
 302.183 +	StreamArray	m_StreamArray;
 302.184 +
 302.185 +	bool noRepeatMsg;
 302.186 +	char lastMsg[MAX_LOG_MESSAGE_LENGTH*2];
 302.187 +	size_t lastLen;
 302.188 +};
 302.189 +// ------------------------------------------------------------------------------------
 302.190 +
 302.191 +} // Namespace Assimp
 302.192 +
 302.193 +#endif // !! INCLUDED_AI_DEFAULTLOGGER
   303.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   303.2 +++ b/libs/assimp/assimp/Exporter.hpp	Sat Feb 01 19:58:19 2014 +0200
   303.3 @@ -0,0 +1,305 @@
   303.4 +/*
   303.5 +---------------------------------------------------------------------------
   303.6 +Open Asset Import Library (assimp)
   303.7 +---------------------------------------------------------------------------
   303.8 +
   303.9 +Copyright (c) 2006-2011, assimp team
  303.10 +
  303.11 +All rights reserved.
  303.12 +
  303.13 +Redistribution and use of this software in source and binary forms, 
  303.14 +with or without modification, are permitted provided that the following 
  303.15 +conditions are met:
  303.16 +
  303.17 +* Redistributions of source code must retain the above
  303.18 +copyright notice, this list of conditions and the
  303.19 +following disclaimer.
  303.20 +
  303.21 +* Redistributions in binary form must reproduce the above
  303.22 +copyright notice, this list of conditions and the
  303.23 +following disclaimer in the documentation and/or other
  303.24 +materials provided with the distribution.
  303.25 +
  303.26 +* Neither the name of the assimp team, nor the names of its
  303.27 +contributors may be used to endorse or promote products
  303.28 +derived from this software without specific prior
  303.29 +written permission of the assimp team.
  303.30 +
  303.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  303.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  303.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  303.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  303.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  303.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  303.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  303.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  303.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  303.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  303.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  303.42 +---------------------------------------------------------------------------
  303.43 +*/
  303.44 +
  303.45 +/** @file  export.hpp
  303.46 +*  @brief Defines the CPP-API for the Assimp export interface
  303.47 +*/
  303.48 +#ifndef AI_EXPORT_HPP_INC
  303.49 +#define AI_EXPORT_HPP_INC
  303.50 +
  303.51 +#ifndef ASSIMP_BUILD_NO_EXPORT
  303.52 +
  303.53 +#include "cexport.h"
  303.54 +
  303.55 +namespace Assimp	{
  303.56 +	class ExporterPimpl;
  303.57 +	class IOSystem;
  303.58 +
  303.59 +
  303.60 +// ----------------------------------------------------------------------------------
  303.61 +/** CPP-API: The Exporter class forms an C++ interface to the export functionality 
  303.62 + * of the Open Asset Import Library. Note that the export interface is available
  303.63 + * only if Assimp has been built with ASSIMP_BUILD_NO_EXPORT not defined.
  303.64 + * 
  303.65 + * The interface is modelled after the importer interface and mostly
  303.66 + * symmetric. The same rules for threading etc. apply.
  303.67 + *
  303.68 + * In a nutshell, there are two export interfaces: #Export, which writes the
  303.69 + * output file(s) either to the regular file system or to a user-supplied 
  303.70 + * #IOSystem, and #ExportToBlob which returns a linked list of memory
  303.71 + * buffers (blob), each referring to one output file (in most cases
  303.72 + * there will be only one output file of course, but this extra complexity is
  303.73 + * needed since Assimp aims at supporting a wide range of file formats). 
  303.74 + * 
  303.75 + * #ExportToBlob is especially useful if you intend to work 
  303.76 + * with the data in-memory. 
  303.77 +*/
  303.78 +class ASSIMP_API Exporter
  303.79 +	// TODO: causes good ol' base class has no dll interface warning
  303.80 +//#ifdef __cplusplus
  303.81 +//	: public boost::noncopyable
  303.82 +//#endif // __cplusplus
  303.83 +{
  303.84 +public:
  303.85 +
  303.86 +	/** Function pointer type of a Export worker function */
  303.87 +	typedef void (*fpExportFunc)(const char*,IOSystem*,const aiScene*);
  303.88 +
  303.89 +	/** Internal description of an Assimp export format option */
  303.90 +	struct ExportFormatEntry
  303.91 +	{
  303.92 +		/// Public description structure to be returned by aiGetExportFormatDescription()
  303.93 +		aiExportFormatDesc mDescription;
  303.94 +
  303.95 +		// Worker function to do the actual exporting
  303.96 +		fpExportFunc mExportFunction;
  303.97 +
  303.98 +		// Postprocessing steps to be executed PRIOR to invoking mExportFunction
  303.99 +		unsigned int mEnforcePP;
 303.100 +
 303.101 +		// Constructor to fill all entries
 303.102 +		ExportFormatEntry( const char* pId, const char* pDesc, const char* pExtension, fpExportFunc pFunction, unsigned int pEnforcePP = 0u)
 303.103 +		{
 303.104 +			mDescription.id = pId;
 303.105 +			mDescription.description = pDesc;
 303.106 +			mDescription.fileExtension = pExtension;
 303.107 +			mExportFunction = pFunction;
 303.108 +			mEnforcePP = pEnforcePP;
 303.109 +		}
 303.110 +
 303.111 +		ExportFormatEntry() : mExportFunction(), mEnforcePP() {}
 303.112 +	};
 303.113 +
 303.114 +
 303.115 +public:
 303.116 +
 303.117 +	
 303.118 +	Exporter();
 303.119 +	~Exporter();
 303.120 +
 303.121 +public:
 303.122 +
 303.123 +
 303.124 +	// -------------------------------------------------------------------
 303.125 +	/** Supplies a custom IO handler to the exporter to use to open and
 303.126 +	 * access files. 
 303.127 +	 * 
 303.128 +	 * If you need #Export to use custom IO logic to access the files, 
 303.129 +	 * you need to supply a custom implementation of IOSystem and 
 303.130 +	 * IOFile to the exporter. 
 303.131 +	 *
 303.132 +	 * #Exporter takes ownership of the object and will destroy it 
 303.133 +	 * afterwards. The previously assigned handler will be deleted.
 303.134 +	 * Pass NULL to take again ownership of your IOSystem and reset Assimp
 303.135 +	 * to use its default implementation, which uses plain file IO.
 303.136 +	 *
 303.137 +	 * @param pIOHandler The IO handler to be used in all file accesses 
 303.138 +	 *   of the Importer. */
 303.139 +	void SetIOHandler( IOSystem* pIOHandler);
 303.140 +
 303.141 +	// -------------------------------------------------------------------
 303.142 +	/** Retrieves the IO handler that is currently set.
 303.143 +	 * You can use #IsDefaultIOHandler() to check whether the returned
 303.144 +	 * interface is the default IO handler provided by ASSIMP. The default
 303.145 +	 * handler is active as long the application doesn't supply its own
 303.146 +	 * custom IO handler via #SetIOHandler().
 303.147 +	 * @return A valid IOSystem interface, never NULL. */
 303.148 +	IOSystem* GetIOHandler() const;
 303.149 +
 303.150 +	// -------------------------------------------------------------------
 303.151 +	/** Checks whether a default IO handler is active 
 303.152 +	 * A default handler is active as long the application doesn't 
 303.153 +	 * supply its own custom IO handler via #SetIOHandler().
 303.154 +	 * @return true by default */
 303.155 +	bool IsDefaultIOHandler() const;
 303.156 +
 303.157 +
 303.158 +
 303.159 +	// -------------------------------------------------------------------
 303.160 +	/** Exports the given scene to a chosen file format. Returns the exported 
 303.161 +	* data as a binary blob which you can write into a file or something.
 303.162 +	* When you're done with the data, simply let the #Exporter instance go 
 303.163 +	* out of scope to have it released automatically.
 303.164 +	* @param pScene The scene to export. Stays in possession of the caller,
 303.165 +	*   is not changed by the function.
 303.166 +	* @param pFormatId ID string to specify to which format you want to 
 303.167 +	*   export to. Use 
 303.168 +	* #GetExportFormatCount / #GetExportFormatDescription to learn which 
 303.169 +	*   export formats are available.
 303.170 +	* @param pPreprocessing See the documentation for #Export
 303.171 +	* @return the exported data or NULL in case of error.
 303.172 +	* @note If the Exporter instance did already hold a blob from
 303.173 +	*   a previous call to #ExportToBlob, it will be disposed. 
 303.174 +	*   Any IO handlers set via #SetIOHandler are ignored here.*/
 303.175 +	const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u );
 303.176 +	inline const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u );
 303.177 +
 303.178 +
 303.179 +	// -------------------------------------------------------------------
 303.180 +	/** Convenience function to export directly to a file. Use
 303.181 +	 *  #SetIOSystem to supply a custom IOSystem to gain fine-grained control
 303.182 +	 *  about the output data flow of the export process.
 303.183 +	 * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL.
 303.184 +	 * @param pPath Full target file name. Target must be accessible.
 303.185 +	 * @param pPreprocessing Accepts any choice of the #aiPostProcessing enumerated
 303.186 +	 *   flags, but in reality only a subset of them makes sense here. Specifying
 303.187 +	 *   'preprocessing' flags is useful if the input scene does not conform to 
 303.188 +	 *   Assimp's default conventions as specified in the @link data Data Structures Page @endlink. 
 303.189 +	 *   In short, this means the geometry data should use a right-handed coordinate systems, face 
 303.190 +	 *   winding should be counter-clockwise and the UV coordinate origin is assumed to be in
 303.191 +	 *   the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and 
 303.192 +	 *   #aiProcess_FlipWindingOrder flags are used in the import side to allow users
 303.193 +	 *   to have those defaults automatically adapted to their conventions. Specifying those flags
 303.194 +	 *   for exporting has the opposite effect, respectively. Some other of the
 303.195 +	 *   #aiPostProcessSteps enumerated values may be useful as well, but you'll need
 303.196 +	 *   to try out what their effect on the exported file is. Many formats impose
 303.197 +	 *   their own restrictions on the structure of the geometry stored therein,
 303.198 +	 *   so some preprocessing may have little or no effect at all, or may be
 303.199 +	 *   redundant as exporters would apply them anyhow. A good example 
 303.200 +	 *   is triangulation - whilst you can enforce it by specifying
 303.201 +	 *   the #aiProcess_Triangulate flag, most export formats support only
 303.202 +	 *  triangulate data so they would run the step even if it wasn't requested.
 303.203 +	 * @return AI_SUCCESS if everything was fine. */
 303.204 +	aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u);
 303.205 +	inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath,  unsigned int pPreprocessing = 0u);
 303.206 +
 303.207 +
 303.208 +	// -------------------------------------------------------------------
 303.209 +	/** Returns an error description of an error that occurred in #Export
 303.210 +	 *    or #ExportToBlob
 303.211 +	 *
 303.212 +	 * Returns an empty string if no error occurred.
 303.213 +	 * @return A description of the last error, an empty string if no 
 303.214 +	 *   error occurred. The string is never NULL.
 303.215 +	 *
 303.216 +	 * @note The returned function remains valid until one of the 
 303.217 +	 * following methods is called: #Export, #ExportToBlob, #FreeBlob */
 303.218 +	const char* GetErrorString() const;
 303.219 +
 303.220 +
 303.221 +	// -------------------------------------------------------------------
 303.222 +	/** Return the blob obtained from the last call to #ExportToBlob */
 303.223 +	const aiExportDataBlob* GetBlob() const;
 303.224 +
 303.225 +
 303.226 +	// -------------------------------------------------------------------
 303.227 +	/** Orphan the blob from the last call to #ExportToBlob. This means
 303.228 +	 *  the caller takes ownership and is thus responsible for calling
 303.229 +	 *  the C API function #aiReleaseExportBlob to release it. */
 303.230 +	const aiExportDataBlob* GetOrphanedBlob() const;
 303.231 +
 303.232 +
 303.233 +	// -------------------------------------------------------------------
 303.234 +	/** Frees the current blob.
 303.235 +	 *
 303.236 +	 *  The function does nothing if no blob has previously been 
 303.237 +	 *  previously produced via #ExportToBlob. #FreeBlob is called
 303.238 +	 *  automatically by the destructor. The only reason to call
 303.239 +	 *  it manually would be to reclain as much storage as possible
 303.240 +	 *  without giving up the #Exporter instance yet. */
 303.241 +	void FreeBlob( );
 303.242 +
 303.243 +
 303.244 +	// -------------------------------------------------------------------
 303.245 +	/** Returns the number of export file formats available in the current
 303.246 +	 *  Assimp build. Use #Exporter::GetExportFormatDescription to
 303.247 +	 *  retrieve infos of a specific export format */
 303.248 +	size_t GetExportFormatCount() const;
 303.249 +
 303.250 +
 303.251 +	// -------------------------------------------------------------------
 303.252 +	/** Returns a description of the nth export file format. Use #
 303.253 +	 *  #Exporter::GetExportFormatCount to learn how many export 
 303.254 +	 *  formats are supported. 
 303.255 +	 * @param pIndex Index of the export format to retrieve information 
 303.256 +	 *  for. Valid range is 0 to #Exporter::GetExportFormatCount
 303.257 +	 * @return A description of that specific export format. 
 303.258 +	 *  NULL if pIndex is out of range. */
 303.259 +	const aiExportFormatDesc* GetExportFormatDescription( size_t pIndex ) const;
 303.260 +
 303.261 +
 303.262 +	// -------------------------------------------------------------------
 303.263 +	/** Register a custom exporter. Custom export formats are limited to
 303.264 +	 *    to the current #Exporter instance and do not affect the
 303.265 +	 *    library globally.
 303.266 +	 *  @param desc Exporter description.
 303.267 +	 *  @return aiReturn_SUCCESS if the export format was successfully
 303.268 +	 *    registered. A common cause that would prevent an exporter
 303.269 +	 *    from being registered is that its format id is already
 303.270 +	 *    occupied by another format. */
 303.271 +	aiReturn RegisterExporter(const ExportFormatEntry& desc);
 303.272 +
 303.273 +
 303.274 +	// -------------------------------------------------------------------
 303.275 +	/** Remove an export format previously registered with #RegisterExporter
 303.276 +	 *  from the #Exporter instance (this can also be used to drop
 303.277 +	 *  builtin exporters because those are implicitly registered
 303.278 +	 *  using #RegisterExporter).
 303.279 +	 *  @param id Format id to be unregistered, this refers to the
 303.280 +	 *    'id' field of #aiExportFormatDesc. 
 303.281 +	 *  @note Calling this method on a format description not yet registered
 303.282 +	 *    has no effect.*/
 303.283 +	void UnregisterExporter(const char* id);
 303.284 +
 303.285 +
 303.286 +protected:
 303.287 +
 303.288 +	// Just because we don't want you to know how we're hacking around.
 303.289 +	ExporterPimpl* pimpl;
 303.290 +};
 303.291 +
 303.292 +
 303.293 +// ----------------------------------------------------------------------------------
 303.294 +inline const aiExportDataBlob* Exporter :: ExportToBlob(  const aiScene* pScene, const std::string& pFormatId,unsigned int pPreprocessing ) 
 303.295 +{
 303.296 +	return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing);
 303.297 +}
 303.298 +
 303.299 +// ----------------------------------------------------------------------------------
 303.300 +inline aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing )
 303.301 +{
 303.302 +	return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing);
 303.303 +}
 303.304 +
 303.305 +} // namespace Assimp
 303.306 +#endif // ASSIMP_BUILD_NO_EXPORT
 303.307 +#endif // AI_EXPORT_HPP_INC
 303.308 +
   304.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   304.2 +++ b/libs/assimp/assimp/IOStream.hpp	Sat Feb 01 19:58:19 2014 +0200
   304.3 @@ -0,0 +1,135 @@
   304.4 +/*
   304.5 +---------------------------------------------------------------------------
   304.6 +Open Asset Import Library (assimp)
   304.7 +---------------------------------------------------------------------------
   304.8 +
   304.9 +Copyright (c) 2006-2012, assimp team
  304.10 +
  304.11 +All rights reserved.
  304.12 +
  304.13 +Redistribution and use of this software in source and binary forms, 
  304.14 +with or without modification, are permitted provided that the following 
  304.15 +conditions are met:
  304.16 +
  304.17 +* Redistributions of source code must retain the above
  304.18 +  copyright notice, this list of conditions and the
  304.19 +  following disclaimer.
  304.20 +
  304.21 +* Redistributions in binary form must reproduce the above
  304.22 +  copyright notice, this list of conditions and the
  304.23 +  following disclaimer in the documentation and/or other
  304.24 +  materials provided with the distribution.
  304.25 +
  304.26 +* Neither the name of the assimp team, nor the names of its
  304.27 +  contributors may be used to endorse or promote products
  304.28 +  derived from this software without specific prior
  304.29 +  written permission of the assimp team.
  304.30 +
  304.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  304.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  304.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  304.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  304.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  304.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  304.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  304.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  304.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  304.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  304.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  304.42 +---------------------------------------------------------------------------
  304.43 +*/
  304.44 +/** @file IOStream.h
  304.45 + *  @brief File I/O wrappers for C++. 
  304.46 + */
  304.47 +
  304.48 +#ifndef AI_IOSTREAM_H_INC
  304.49 +#define AI_IOSTREAM_H_INC
  304.50 +
  304.51 +#include "types.h"
  304.52 +
  304.53 +#ifndef __cplusplus
  304.54 +#	error This header requires C++ to be used. aiFileIO.h is the \
  304.55 +	corresponding C interface.
  304.56 +#endif
  304.57 +
  304.58 +namespace Assimp	{
  304.59 +
  304.60 +// ----------------------------------------------------------------------------------
  304.61 +/** @brief CPP-API: Class to handle file I/O for C++
  304.62 + *
  304.63 + *  Derive an own implementation from this interface to provide custom IO handling
  304.64 + *  to the Importer. If you implement this interface, be sure to also provide an
  304.65 + *  implementation for IOSystem that creates instances of your custom IO class.
  304.66 +*/
  304.67 +class ASSIMP_API IOStream : public Intern::AllocateFromAssimpHeap
  304.68 +{
  304.69 +protected:
  304.70 +	/** Constructor protected, use IOSystem::Open() to create an instance. */
  304.71 +	IOStream(void);
  304.72 +
  304.73 +public:
  304.74 +	// -------------------------------------------------------------------
  304.75 +	/** @brief Destructor. Deleting the object closes the underlying file, 
  304.76 +	 * alternatively you may use IOSystem::Close() to release the file. 
  304.77 +	 */
  304.78 +	virtual ~IOStream();
  304.79 +
  304.80 +	// -------------------------------------------------------------------
  304.81 +	/** @brief Read from the file
  304.82 +	 *
  304.83 +	 * See fread() for more details
  304.84 +	 * This fails for write-only files */
  304.85 +    virtual size_t Read(void* pvBuffer, 
  304.86 +		size_t pSize, 
  304.87 +		size_t pCount) = 0;
  304.88 +
  304.89 +	// -------------------------------------------------------------------
  304.90 +	/** @brief Write to the file
  304.91 +	*
  304.92 +	* See fwrite() for more details
  304.93 +	* This fails for read-only files */
  304.94 +    virtual size_t Write(const void* pvBuffer, 
  304.95 +		size_t pSize,
  304.96 +		size_t pCount) = 0;
  304.97 +
  304.98 +	// -------------------------------------------------------------------
  304.99 +	/** @brief Set the read/write cursor of the file
 304.100 +	 *
 304.101 +	 * Note that the offset is _negative_ for aiOrigin_END.
 304.102 +	 * See fseek() for more details */
 304.103 +	virtual aiReturn Seek(size_t pOffset,
 304.104 +		aiOrigin pOrigin) = 0;
 304.105 +
 304.106 +	// -------------------------------------------------------------------
 304.107 +	/** @brief Get the current position of the read/write cursor
 304.108 +	 *
 304.109 +	 * See ftell() for more details */
 304.110 +    virtual size_t Tell() const = 0;
 304.111 +
 304.112 +	// -------------------------------------------------------------------
 304.113 +	/**	@brief Returns filesize
 304.114 +	 *	Returns the filesize. */
 304.115 +	virtual size_t FileSize() const = 0;
 304.116 +
 304.117 +	// -------------------------------------------------------------------
 304.118 +	/**	@brief Flush the contents of the file buffer (for writers) 
 304.119 +	 *	See fflush() for more details.
 304.120 +	 */
 304.121 +	virtual void Flush() = 0;
 304.122 +}; //! class IOStream
 304.123 +
 304.124 +// ----------------------------------------------------------------------------------
 304.125 +inline IOStream::IOStream()
 304.126 +{
 304.127 +	// empty
 304.128 +}
 304.129 +
 304.130 +// ----------------------------------------------------------------------------------
 304.131 +inline IOStream::~IOStream()
 304.132 +{
 304.133 +	// empty
 304.134 +}
 304.135 +// ----------------------------------------------------------------------------------
 304.136 +} //!namespace Assimp
 304.137 +
 304.138 +#endif //!!AI_IOSTREAM_H_INC
   305.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   305.2 +++ b/libs/assimp/assimp/IOSystem.hpp	Sat Feb 01 19:58:19 2014 +0200
   305.3 @@ -0,0 +1,222 @@
   305.4 +/*
   305.5 +---------------------------------------------------------------------------
   305.6 +Open Asset Import Library (assimp)
   305.7 +---------------------------------------------------------------------------
   305.8 +
   305.9 +Copyright (c) 2006-2012, assimp team
  305.10 +
  305.11 +All rights reserved.
  305.12 +
  305.13 +Redistribution and use of this software in source and binary forms, 
  305.14 +with or without modification, are permitted provided that the following 
  305.15 +conditions are met:
  305.16 +
  305.17 +* Redistributions of source code must retain the above
  305.18 +  copyright notice, this list of conditions and the
  305.19 +  following disclaimer.
  305.20 +
  305.21 +* Redistributions in binary form must reproduce the above
  305.22 +  copyright notice, this list of conditions and the
  305.23 +  following disclaimer in the documentation and/or other
  305.24 +  materials provided with the distribution.
  305.25 +
  305.26 +* Neither the name of the assimp team, nor the names of its
  305.27 +  contributors may be used to endorse or promote products
  305.28 +  derived from this software without specific prior
  305.29 +  written permission of the assimp team.
  305.30 +
  305.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  305.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  305.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  305.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  305.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  305.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  305.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  305.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  305.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  305.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  305.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  305.42 +---------------------------------------------------------------------------
  305.43 +*/
  305.44 +
  305.45 +/** @file IOSystem.h
  305.46 + *  @brief File system wrapper for C++. Inherit this class to supply
  305.47 + *  custom file handling logic to the Import library.
  305.48 +*/
  305.49 +
  305.50 +#ifndef AI_IOSYSTEM_H_INC
  305.51 +#define AI_IOSYSTEM_H_INC
  305.52 +
  305.53 +#ifndef __cplusplus
  305.54 +#	error This header requires C++ to be used. aiFileIO.h is the \
  305.55 +	corresponding C interface.
  305.56 +#endif
  305.57 +
  305.58 +#include "types.h"
  305.59 +namespace Assimp	{
  305.60 +class IOStream;
  305.61 +
  305.62 +// ---------------------------------------------------------------------------
  305.63 +/** @brief CPP-API: Interface to the file system.
  305.64 + *
  305.65 + *  Derive an own implementation from this interface to supply custom file handling
  305.66 + *  to the importer library. If you implement this interface, you also want to
  305.67 + *  supply a custom implementation for IOStream.
  305.68 + *
  305.69 + *  @see Importer::SetIOHandler() */
  305.70 +class ASSIMP_API IOSystem : public Intern::AllocateFromAssimpHeap
  305.71 +{
  305.72 +public:
  305.73 +
  305.74 +	// -------------------------------------------------------------------
  305.75 +	/** @brief Default constructor.
  305.76 +	 *
  305.77 +	 *  Create an instance of your derived class and assign it to an 
  305.78 +	 *  #Assimp::Importer instance by calling Importer::SetIOHandler().
  305.79 +	 */
  305.80 +	IOSystem();
  305.81 +
  305.82 +	// -------------------------------------------------------------------
  305.83 +	/** @brief Virtual destructor.
  305.84 +	 *
  305.85 +	 *  It is safe to be called from within DLL Assimp, we're constructed
  305.86 +	 *  on Assimp's heap.
  305.87 +	 */
  305.88 +	virtual ~IOSystem();
  305.89 +
  305.90 +
  305.91 +public:
  305.92 +
  305.93 +	// -------------------------------------------------------------------
  305.94 +	/** @brief For backward compatibility
  305.95 +	 *  @see Exists(const char*)
  305.96 +	 */
  305.97 +	AI_FORCE_INLINE bool Exists( const std::string& pFile) const;
  305.98 +
  305.99 +	// -------------------------------------------------------------------
 305.100 +	/** @brief Tests for the existence of a file at the given path. 
 305.101 +	 *
 305.102 +	 * @param pFile Path to the file
 305.103 +	 * @return true if there is a file with this path, else false.
 305.104 +	 */
 305.105 +
 305.106 +	virtual bool Exists( const char* pFile) const = 0;
 305.107 +
 305.108 +
 305.109 +
 305.110 +	// -------------------------------------------------------------------
 305.111 +	/**	@brief Returns the system specific directory separator
 305.112 +	 *	@return	System specific directory separator
 305.113 +	 */
 305.114 +	virtual char getOsSeparator() const = 0;
 305.115 +
 305.116 +
 305.117 +	// -------------------------------------------------------------------
 305.118 +	/** @brief Open a new file with a given path.
 305.119 +	 *
 305.120 +	 *  When the access to the file is finished, call Close() to release
 305.121 +	 *  all associated resources (or the virtual dtor of the IOStream).
 305.122 +	 *
 305.123 +	 *  @param pFile Path to the file
 305.124 +	 *  @param pMode Desired file I/O mode. Required are: "wb", "w", "wt",
 305.125 +	 *         "rb", "r", "rt".
 305.126 +	 *
 305.127 +	 *  @return New IOStream interface allowing the lib to access
 305.128 +	 *         the underlying file. 
 305.129 +	 *  @note When implementing this class to provide custom IO handling, 
 305.130 +	 *  you probably have to supply an own implementation of IOStream as well. 
 305.131 +	 */
 305.132 +	virtual IOStream* Open(const char* pFile,
 305.133 +		const char* pMode = "rb") = 0;
 305.134 +
 305.135 +	// -------------------------------------------------------------------
 305.136 +	/** @brief For backward compatibility
 305.137 +	 *  @see Open(const char*, const char*)
 305.138 +	 */
 305.139 +	inline IOStream* Open(const std::string& pFile,
 305.140 +		const std::string& pMode = std::string("rb"));
 305.141 +
 305.142 +
 305.143 +
 305.144 +	// -------------------------------------------------------------------
 305.145 +	/** @brief Closes the given file and releases all resources 
 305.146 +	 *    associated with it.
 305.147 +	 *  @param pFile The file instance previously created by Open().
 305.148 +	 */
 305.149 +	virtual void Close( IOStream* pFile) = 0;
 305.150 +
 305.151 +	// -------------------------------------------------------------------
 305.152 +	/** @brief Compares two paths and check whether the point to
 305.153 +	 *         identical files.
 305.154 +	 *  
 305.155 +	 * The dummy implementation of this virtual member performs a 
 305.156 +	 * case-insensitive comparison of the given strings. The default IO
 305.157 +	 * system implementation uses OS mechanisms to convert relative into
 305.158 +	 * absolute paths, so the result can be trusted.
 305.159 +	 * @param one First file
 305.160 +	 * @param second Second file
 305.161 +	 * @return true if the paths point to the same file. The file needn't
 305.162 +	 *   be existing, however.
 305.163 +	 */
 305.164 +	virtual bool ComparePaths (const char* one, 
 305.165 +		const char* second) const;
 305.166 +
 305.167 +	// -------------------------------------------------------------------
 305.168 +	/** @brief For backward compatibility
 305.169 +	 *  @see ComparePaths(const char*, const char*)
 305.170 +	 */
 305.171 +	inline bool ComparePaths (const std::string& one, 
 305.172 +		const std::string& second) const;
 305.173 +};
 305.174 +
 305.175 +// ----------------------------------------------------------------------------
 305.176 +AI_FORCE_INLINE IOSystem::IOSystem() 
 305.177 +{
 305.178 +	// empty
 305.179 +}
 305.180 +
 305.181 +// ----------------------------------------------------------------------------
 305.182 +AI_FORCE_INLINE IOSystem::~IOSystem() 
 305.183 +{
 305.184 +	// empty
 305.185 +}
 305.186 +
 305.187 +// ----------------------------------------------------------------------------
 305.188 +// For compatibility, the interface of some functions taking a std::string was
 305.189 +// changed to const char* to avoid crashes between binary incompatible STL 
 305.190 +// versions. This code her is inlined,  so it shouldn't cause any problems.
 305.191 +// ----------------------------------------------------------------------------
 305.192 +
 305.193 +// ----------------------------------------------------------------------------
 305.194 +AI_FORCE_INLINE IOStream* IOSystem::Open(const std::string& pFile,
 305.195 +	const std::string& pMode)
 305.196 +{
 305.197 +	// NOTE:
 305.198 +	// For compatibility, interface was changed to const char* to
 305.199 +	// avoid crashes between binary incompatible STL versions 
 305.200 +	return Open(pFile.c_str(),pMode.c_str());
 305.201 +}
 305.202 +
 305.203 +// ----------------------------------------------------------------------------
 305.204 +AI_FORCE_INLINE bool IOSystem::Exists( const std::string& pFile) const
 305.205 +{
 305.206 +	// NOTE:
 305.207 +	// For compatibility, interface was changed to const char* to
 305.208 +	// avoid crashes between binary incompatible STL versions 
 305.209 +	return Exists(pFile.c_str());
 305.210 +}
 305.211 +
 305.212 +// ----------------------------------------------------------------------------
 305.213 +inline bool IOSystem::ComparePaths (const std::string& one, 
 305.214 +	const std::string& second) const
 305.215 +{
 305.216 +	// NOTE:
 305.217 +	// For compatibility, interface was changed to const char* to
 305.218 +	// avoid crashes between binary incompatible STL versions 
 305.219 +	return ComparePaths(one.c_str(),second.c_str());
 305.220 +}
 305.221 +
 305.222 +// ----------------------------------------------------------------------------
 305.223 +} //!ns Assimp
 305.224 +
 305.225 +#endif //AI_IOSYSTEM_H_INC
   306.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   306.2 +++ b/libs/assimp/assimp/Importer.hpp	Sat Feb 01 19:58:19 2014 +0200
   306.3 @@ -0,0 +1,643 @@
   306.4 +/*
   306.5 +---------------------------------------------------------------------------
   306.6 +Open Asset Import Library (assimp)
   306.7 +---------------------------------------------------------------------------
   306.8 +
   306.9 +Copyright (c) 2006-2012, assimp team
  306.10 +
  306.11 +All rights reserved.
  306.12 +
  306.13 +Redistribution and use of this software in source and binary forms, 
  306.14 +with or without modification, are permitted provided that the following 
  306.15 +conditions are met:
  306.16 +
  306.17 +* Redistributions of source code must retain the above
  306.18 +  copyright notice, this list of conditions and the
  306.19 +  following disclaimer.
  306.20 +
  306.21 +* Redistributions in binary form must reproduce the above
  306.22 +  copyright notice, this list of conditions and the
  306.23 +  following disclaimer in the documentation and/or other
  306.24 +  materials provided with the distribution.
  306.25 +
  306.26 +* Neither the name of the assimp team, nor the names of its
  306.27 +  contributors may be used to endorse or promote products
  306.28 +  derived from this software without specific prior
  306.29 +  written permission of the assimp team.
  306.30 +
  306.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  306.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  306.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  306.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  306.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  306.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  306.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  306.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  306.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  306.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  306.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  306.42 +---------------------------------------------------------------------------
  306.43 +*/
  306.44 +
  306.45 +/** @file  assimp.hpp
  306.46 + *  @brief Defines the C++-API to the Open Asset Import Library.
  306.47 + */
  306.48 +#ifndef INCLUDED_AI_ASSIMP_HPP
  306.49 +#define INCLUDED_AI_ASSIMP_HPP
  306.50 +
  306.51 +#ifndef __cplusplus
  306.52 +#	error This header requires C++ to be used. Use assimp.h for plain C. 
  306.53 +#endif
  306.54 +
  306.55 +// Public ASSIMP data structures
  306.56 +#include "types.h"
  306.57 +#include "config.h"
  306.58 +
  306.59 +namespace Assimp	{
  306.60 +	// =======================================================================
  306.61 +	// Public interface to Assimp 
  306.62 +	class Importer;
  306.63 +	class Exporter; // export.hpp
  306.64 +	class IOStream;
  306.65 +	class IOSystem;
  306.66 +	class ProgressHandler;
  306.67 +
  306.68 +	// =======================================================================
  306.69 +	// Plugin development
  306.70 +	//
  306.71 +	// Include the following headers for the declarations:
  306.72 +	// BaseImporter.h
  306.73 +	// BaseProcess.h
  306.74 +	class BaseImporter;
  306.75 +	class BaseProcess;
  306.76 +	class SharedPostProcessInfo;
  306.77 +	class BatchLoader; 
  306.78 +
  306.79 +	// =======================================================================
  306.80 +	// Holy stuff, only for members of the high council of the Jedi.
  306.81 +	class ImporterPimpl;
  306.82 +	class ExporterPimpl; // export.hpp
  306.83 +} //! namespace Assimp
  306.84 +
  306.85 +#define AI_PROPERTY_WAS_NOT_EXISTING 0xffffffff
  306.86 +
  306.87 +struct aiScene;
  306.88 +
  306.89 +// importerdesc.h
  306.90 +struct aiImporterDesc;
  306.91 +
  306.92 +/** @namespace Assimp Assimp's CPP-API and all internal APIs */
  306.93 +namespace Assimp	{
  306.94 +
  306.95 +// ----------------------------------------------------------------------------------
  306.96 +/** CPP-API: The Importer class forms an C++ interface to the functionality of the 
  306.97 +*   Open Asset Import Library.
  306.98 +*
  306.99 +* Create an object of this class and call ReadFile() to import a file. 
 306.100 +* If the import succeeds, the function returns a pointer to the imported data. 
 306.101 +* The data remains property of the object, it is intended to be accessed 
 306.102 +* read-only. The imported data will be destroyed along with the Importer 
 306.103 +* object. If the import fails, ReadFile() returns a NULL pointer. In this
 306.104 +* case you can retrieve a human-readable error description be calling 
 306.105 +* GetErrorString(). You can call ReadFile() multiple times with a single Importer
 306.106 +* instance. Actually, constructing Importer objects involves quite many
 306.107 +* allocations and may take some time, so it's better to reuse them as often as
 306.108 +* possible.
 306.109 +*
 306.110 +* If you need the Importer to do custom file handling to access the files,
 306.111 +* implement IOSystem and IOStream and supply an instance of your custom 
 306.112 +* IOSystem implementation by calling SetIOHandler() before calling ReadFile().
 306.113 +* If you do not assign a custion IO handler, a default handler using the 
 306.114 +* standard C++ IO logic will be used.
 306.115 +*
 306.116 +* @note One Importer instance is not thread-safe. If you use multiple
 306.117 +* threads for loading, each thread should maintain its own Importer instance.
 306.118 +*/
 306.119 +class ASSIMP_API Importer	{
 306.120 +
 306.121 +public:
 306.122 +
 306.123 +	// -------------------------------------------------------------------
 306.124 +	/** Constructor. Creates an empty importer object. 
 306.125 +	 * 
 306.126 +	 * Call ReadFile() to start the import process. The configuration
 306.127 +	 * property table is initially empty.
 306.128 +	 */
 306.129 +	Importer();
 306.130 +
 306.131 +	// -------------------------------------------------------------------
 306.132 +	/** Copy constructor.
 306.133 +	 * 
 306.134 +	 * This copies the configuration properties of another Importer.
 306.135 +	 * If this Importer owns a scene it won't be copied.
 306.136 +	 * Call ReadFile() to start the import process.
 306.137 +	 */
 306.138 +	Importer(const Importer& other);
 306.139 +
 306.140 +	// -------------------------------------------------------------------
 306.141 +	/** Destructor. The object kept ownership of the imported data,
 306.142 +	 * which now will be destroyed along with the object. 
 306.143 +	 */
 306.144 +	~Importer();
 306.145 +
 306.146 +
 306.147 +	// -------------------------------------------------------------------
 306.148 +	/** Registers a new loader.
 306.149 +	 *
 306.150 +	 * @param pImp Importer to be added. The Importer instance takes 
 306.151 +	 *   ownership of the pointer, so it will be automatically deleted
 306.152 +	 *   with the Importer instance.
 306.153 +	 * @return AI_SUCCESS if the loader has been added. The registration
 306.154 +	 *   fails if there is already a loader for a specific file extension.
 306.155 +	 */
 306.156 +	aiReturn RegisterLoader(BaseImporter* pImp);
 306.157 +
 306.158 +	// -------------------------------------------------------------------
 306.159 +	/** Unregisters a loader.
 306.160 +	 *
 306.161 +	 * @param pImp Importer to be unregistered.
 306.162 +	 * @return AI_SUCCESS if the loader has been removed. The function
 306.163 +	 *   fails if the loader is currently in use (this could happen
 306.164 +	 *   if the #Importer instance is used by more than one thread) or
 306.165 +	 *   if it has not yet been registered.
 306.166 +	 */
 306.167 +	aiReturn UnregisterLoader(BaseImporter* pImp);
 306.168 +
 306.169 +	// -------------------------------------------------------------------
 306.170 +	/** Registers a new post-process step.
 306.171 +	 *
 306.172 +	 * At the moment, there's a small limitation: new post processing 
 306.173 +	 * steps are added to end of the list, or in other words, executed 
 306.174 +	 * last, after all built-in steps.
 306.175 +	 * @param pImp Post-process step to be added. The Importer instance 
 306.176 +	 *   takes ownership of the pointer, so it will be automatically 
 306.177 +	 *   deleted with the Importer instance.
 306.178 +	 * @return AI_SUCCESS if the step has been added correctly.
 306.179 +	 */
 306.180 +	aiReturn RegisterPPStep(BaseProcess* pImp);
 306.181 +
 306.182 +	// -------------------------------------------------------------------
 306.183 +	/** Unregisters a post-process step.
 306.184 +	 *
 306.185 +	 * @param pImp Step to be unregistered. 
 306.186 +	 * @return AI_SUCCESS if the step has been removed. The function
 306.187 +	 *   fails if the step is currently in use (this could happen
 306.188 +	 *   if the #Importer instance is used by more than one thread) or
 306.189 +	 *   if it has not yet been registered.
 306.190 +	 */
 306.191 +	aiReturn UnregisterPPStep(BaseProcess* pImp);
 306.192 +
 306.193 +
 306.194 +	// -------------------------------------------------------------------
 306.195 +	/** Set an integer configuration property.
 306.196 +	 * @param szName Name of the property. All supported properties
 306.197 +	 *   are defined in the aiConfig.g header (all constants share the
 306.198 +	 *   prefix AI_CONFIG_XXX and are simple strings).
 306.199 +	 * @param iValue New value of the property
 306.200 +	 * @param bWasExisting Optional pointer to receive true if the
 306.201 +	 *   property was set before. The new value replaces the previous value
 306.202 +	 *   in this case.
 306.203 +	 * @note Property of different types (float, int, string ..) are kept
 306.204 +	 *   on different stacks, so calling SetPropertyInteger() for a 
 306.205 +	 *   floating-point property has no effect - the loader will call
 306.206 +	 *   GetPropertyFloat() to read the property, but it won't be there.
 306.207 +	 */
 306.208 +	void SetPropertyInteger(const char* szName, int iValue, 
 306.209 +		bool* bWasExisting = NULL);
 306.210 +
 306.211 +	// -------------------------------------------------------------------
 306.212 +	/** Set a boolean configuration property. Boolean properties
 306.213 +	 *  are stored on the integer stack internally so it's possible
 306.214 +	 *  to set them via #SetPropertyBool and query them with
 306.215 +	 *  #GetPropertyBool and vice versa.
 306.216 +	 * @see SetPropertyInteger()
 306.217 +	 */
 306.218 +	void SetPropertyBool(const char* szName, bool value, bool* bWasExisting = NULL)	{
 306.219 +		SetPropertyInteger(szName,value,bWasExisting);
 306.220 +	}
 306.221 +
 306.222 +	// -------------------------------------------------------------------
 306.223 +	/** Set a floating-point configuration property.
 306.224 +	 * @see SetPropertyInteger()
 306.225 +	 */
 306.226 +	void SetPropertyFloat(const char* szName, float fValue, 
 306.227 +		bool* bWasExisting = NULL);
 306.228 +
 306.229 +	// -------------------------------------------------------------------
 306.230 +	/** Set a string configuration property.
 306.231 +	 * @see SetPropertyInteger()
 306.232 +	 */
 306.233 +	void SetPropertyString(const char* szName, const std::string& sValue, 
 306.234 +		bool* bWasExisting = NULL);
 306.235 +
 306.236 +	// -------------------------------------------------------------------
 306.237 +	/** Get a configuration property.
 306.238 +	 * @param szName Name of the property. All supported properties
 306.239 +	 *   are defined in the aiConfig.g header (all constants share the
 306.240 +	 *   prefix AI_CONFIG_XXX).
 306.241 +	 * @param iErrorReturn Value that is returned if the property 
 306.242 +	 *   is not found. 
 306.243 +	 * @return Current value of the property
 306.244 +	 * @note Property of different types (float, int, string ..) are kept
 306.245 +	 *   on different lists, so calling SetPropertyInteger() for a 
 306.246 +	 *   floating-point property has no effect - the loader will call
 306.247 +	 *   GetPropertyFloat() to read the property, but it won't be there.
 306.248 +	 */
 306.249 +	int GetPropertyInteger(const char* szName, 
 306.250 +		int iErrorReturn = 0xffffffff) const;
 306.251 +
 306.252 +	// -------------------------------------------------------------------
 306.253 +	/** Get a boolean configuration property. Boolean properties
 306.254 +	 *  are stored on the integer stack internally so it's possible
 306.255 +	 *  to set them via #SetPropertyBool and query them with
 306.256 +	 *  #GetPropertyBool and vice versa.
 306.257 +	 * @see GetPropertyInteger()
 306.258 +	 */
 306.259 +	bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
 306.260 +		return GetPropertyInteger(szName,bErrorReturn)!=0;
 306.261 +	}
 306.262 +
 306.263 +	// -------------------------------------------------------------------
 306.264 +	/** Get a floating-point configuration property
 306.265 +	 * @see GetPropertyInteger()
 306.266 +	 */
 306.267 +	float GetPropertyFloat(const char* szName, 
 306.268 +		float fErrorReturn = 10e10f) const;
 306.269 +
 306.270 +	// -------------------------------------------------------------------
 306.271 +	/** Get a string configuration property
 306.272 +	 *
 306.273 +	 *  The return value remains valid until the property is modified.
 306.274 +	 * @see GetPropertyInteger()
 306.275 +	 */
 306.276 +	const std::string& GetPropertyString(const char* szName,
 306.277 +		const std::string& sErrorReturn = "") const;
 306.278 +
 306.279 +	// -------------------------------------------------------------------
 306.280 +	/** Supplies a custom IO handler to the importer to use to open and
 306.281 +	 * access files. If you need the importer to use custion IO logic to 
 306.282 +	 * access the files, you need to provide a custom implementation of 
 306.283 +	 * IOSystem and IOFile to the importer. Then create an instance of 
 306.284 +	 * your custion IOSystem implementation and supply it by this function.
 306.285 +	 *
 306.286 +	 * The Importer takes ownership of the object and will destroy it 
 306.287 +	 * afterwards. The previously assigned handler will be deleted.
 306.288 +	 * Pass NULL to take again ownership of your IOSystem and reset Assimp
 306.289 +	 * to use its default implementation.
 306.290 +	 *
 306.291 +	 * @param pIOHandler The IO handler to be used in all file accesses 
 306.292 +	 *   of the Importer. 
 306.293 +	 */
 306.294 +	void SetIOHandler( IOSystem* pIOHandler);
 306.295 +
 306.296 +	// -------------------------------------------------------------------
 306.297 +	/** Retrieves the IO handler that is currently set.
 306.298 +	 * You can use #IsDefaultIOHandler() to check whether the returned
 306.299 +	 * interface is the default IO handler provided by ASSIMP. The default
 306.300 +	 * handler is active as long the application doesn't supply its own
 306.301 +	 * custom IO handler via #SetIOHandler().
 306.302 +	 * @return A valid IOSystem interface, never NULL.
 306.303 +	 */
 306.304 +	IOSystem* GetIOHandler() const;
 306.305 +
 306.306 +	// -------------------------------------------------------------------
 306.307 +	/** Checks whether a default IO handler is active 
 306.308 +	 * A default handler is active as long the application doesn't 
 306.309 +	 * supply its own custom IO handler via #SetIOHandler().
 306.310 +	 * @return true by default
 306.311 +	 */
 306.312 +	bool IsDefaultIOHandler() const;
 306.313 +
 306.314 +	// -------------------------------------------------------------------
 306.315 +	/** Supplies a custom progress handler to the importer. This 
 306.316 +	 *  interface exposes a #Update() callback, which is called
 306.317 +	 *  more or less periodically (please don't sue us if it
 306.318 +	 *  isn't as periodically as you'd like it to have ...).
 306.319 +	 *  This can be used to implement progress bars and loading
 306.320 +	 *  timeouts. 
 306.321 +	 *  @param pHandler Progress callback interface. Pass NULL to 
 306.322 +	 *    disable progress reporting. 
 306.323 +	 *  @note Progress handlers can be used to abort the loading
 306.324 +	 *    at almost any time.*/
 306.325 +	void SetProgressHandler ( ProgressHandler* pHandler );
 306.326 +
 306.327 +	// -------------------------------------------------------------------
 306.328 +	/** Retrieves the progress handler that is currently set. 
 306.329 +	 * You can use #IsDefaultProgressHandler() to check whether the returned
 306.330 +	 * interface is the default handler provided by ASSIMP. The default
 306.331 +	 * handler is active as long the application doesn't supply its own
 306.332 +	 * custom handler via #SetProgressHandler().
 306.333 +	 * @return A valid ProgressHandler interface, never NULL.
 306.334 +	 */
 306.335 +	ProgressHandler* GetProgressHandler() const;
 306.336 +
 306.337 +	// -------------------------------------------------------------------
 306.338 +	/** Checks whether a default progress handler is active 
 306.339 +	 * A default handler is active as long the application doesn't 
 306.340 +	 * supply its own custom progress handler via #SetProgressHandler().
 306.341 +	 * @return true by default
 306.342 +	 */
 306.343 +	bool IsDefaultProgressHandler() const;
 306.344 +
 306.345 +	// -------------------------------------------------------------------
 306.346 +	/** @brief Check whether a given set of postprocessing flags
 306.347 +	 *  is supported.
 306.348 +	 *
 306.349 +	 *  Some flags are mutually exclusive, others are probably
 306.350 +	 *  not available because your excluded them from your
 306.351 +	 *  Assimp builds. Calling this function is recommended if 
 306.352 +	 *  you're unsure.
 306.353 +	 *
 306.354 +	 *  @param pFlags Bitwise combination of the aiPostProcess flags.
 306.355 +	 *  @return true if this flag combination is fine.
 306.356 +	 */
 306.357 +	bool ValidateFlags(unsigned int pFlags) const;
 306.358 +
 306.359 +	// -------------------------------------------------------------------
 306.360 +	/** Reads the given file and returns its contents if successful. 
 306.361 +	 * 
 306.362 +	 * If the call succeeds, the contents of the file are returned as a 
 306.363 +	 * pointer to an aiScene object. The returned data is intended to be 
 306.364 +	 * read-only, the importer object keeps ownership of the data and will
 306.365 +	 * destroy it upon destruction. If the import fails, NULL is returned.
 306.366 +	 * A human-readable error description can be retrieved by calling 
 306.367 +	 * GetErrorString(). The previous scene will be deleted during this call.
 306.368 +	 * @param pFile Path and filename to the file to be imported.
 306.369 +	 * @param pFlags Optional post processing steps to be executed after 
 306.370 +	 *   a successful import. Provide a bitwise combination of the 
 306.371 +	 *   #aiPostProcessSteps flags. If you wish to inspect the imported
 306.372 +	 *   scene first in order to fine-tune your post-processing setup,
 306.373 +	 *   consider to use #ApplyPostProcessing().
 306.374 +	 * @return A pointer to the imported data, NULL if the import failed.
 306.375 +	 *   The pointer to the scene remains in possession of the Importer
 306.376 +	 *   instance. Use GetOrphanedScene() to take ownership of it.
 306.377 +	 *
 306.378 +	 * @note Assimp is able to determine the file format of a file
 306.379 +	 * automatically. 
 306.380 +	 */
 306.381 +	const aiScene* ReadFile(
 306.382 +		const char* pFile, 
 306.383 +		unsigned int pFlags);
 306.384 +
 306.385 +	// -------------------------------------------------------------------
 306.386 +	/** Reads the given file from a memory buffer and returns its
 306.387 +	 *  contents if successful.
 306.388 +	 * 
 306.389 +	 * If the call succeeds, the contents of the file are returned as a 
 306.390 +	 * pointer to an aiScene object. The returned data is intended to be 
 306.391 +	 * read-only, the importer object keeps ownership of the data and will
 306.392 +	 * destroy it upon destruction. If the import fails, NULL is returned.
 306.393 +	 * A human-readable error description can be retrieved by calling 
 306.394 +	 * GetErrorString(). The previous scene will be deleted during this call.
 306.395 +	 * Calling this method doesn't affect the active IOSystem.
 306.396 +	 * @param pBuffer Pointer to the file data
 306.397 +	 * @param pLength Length of pBuffer, in bytes
 306.398 +	 * @param pFlags Optional post processing steps to be executed after 
 306.399 +	 *   a successful import. Provide a bitwise combination of the 
 306.400 +	 *   #aiPostProcessSteps flags. If you wish to inspect the imported
 306.401 +	 *   scene first in order to fine-tune your post-processing setup,
 306.402 +	 *   consider to use #ApplyPostProcessing().
 306.403 +	 * @param pHint An additional hint to the library. If this is a non
 306.404 +	 *   empty string, the library looks for a loader to support 
 306.405 +	 *   the file extension specified by pHint and passes the file to
 306.406 +	 *   the first matching loader. If this loader is unable to completely
 306.407 +	 *   the request, the library continues and tries to determine the
 306.408 +	 *   file format on its own, a task that may or may not be successful.
 306.409 +	 *   Check the return value, and you'll know ...
 306.410 +	 * @return A pointer to the imported data, NULL if the import failed.
 306.411 +	 *   The pointer to the scene remains in possession of the Importer
 306.412 +	 *   instance. Use GetOrphanedScene() to take ownership of it.
 306.413 +	 *
 306.414 +	 * @note This is a straightforward way to decode models from memory
 306.415 +	 * buffers, but it doesn't handle model formats that spread their 
 306.416 +	 * data across multiple files or even directories. Examples include
 306.417 +	 * OBJ or MD3, which outsource parts of their material info into
 306.418 +	 * external scripts. If you need full functionality, provide
 306.419 +	 * a custom IOSystem to make Assimp find these files and use
 306.420 +	 * the regular ReadFile() API.
 306.421 +	 */
 306.422 +	const aiScene* ReadFileFromMemory( 
 306.423 +		const void* pBuffer,
 306.424 +		size_t pLength,
 306.425 +		unsigned int pFlags,
 306.426 +		const char* pHint = "");
 306.427 +
 306.428 +	// -------------------------------------------------------------------
 306.429 +	/** Apply post-processing to an already-imported scene.
 306.430 +	 *
 306.431 +	 *  This is strictly equivalent to calling #ReadFile() with the same
 306.432 +	 *  flags. However, you can use this separate function to inspect
 306.433 +	 *  the imported scene first to fine-tune your post-processing setup.
 306.434 +	 *  @param pFlags Provide a bitwise combination of the 
 306.435 +	 *   #aiPostProcessSteps flags.
 306.436 +	 *  @return A pointer to the post-processed data. This is still the
 306.437 +	 *   same as the pointer returned by #ReadFile(). However, if
 306.438 +	 *   post-processing fails, the scene could now be NULL.
 306.439 +	 *   That's quite a rare case, post processing steps are not really
 306.440 +	 *   designed to 'fail'. To be exact, the #aiProcess_ValidateDS
 306.441 +	 *   flag is currently the only post processing step which can actually
 306.442 +	 *   cause the scene to be reset to NULL.
 306.443 +	 *
 306.444 +	 *  @note The method does nothing if no scene is currently bound
 306.445 +	 *    to the #Importer instance.  */
 306.446 +	const aiScene* ApplyPostProcessing(unsigned int pFlags);
 306.447 +
 306.448 +	// -------------------------------------------------------------------
 306.449 +	/** @brief Reads the given file and returns its contents if successful. 
 306.450 +	 *
 306.451 +	 * This function is provided for backward compatibility.
 306.452 +	 * See the const char* version for detailled docs.
 306.453 +	 * @see ReadFile(const char*, pFlags)  */
 306.454 +	const aiScene* ReadFile(
 306.455 +		const std::string& pFile, 
 306.456 +		unsigned int pFlags);
 306.457 +
 306.458 +	// -------------------------------------------------------------------
 306.459 +	/** Frees the current scene.
 306.460 +	 *
 306.461 +	 *  The function does nothing if no scene has previously been 
 306.462 +	 *  read via ReadFile(). FreeScene() is called automatically by the
 306.463 +	 *  destructor and ReadFile() itself.  */
 306.464 +	void FreeScene( );
 306.465 +
 306.466 +	// -------------------------------------------------------------------
 306.467 +	/** Returns an error description of an error that occurred in ReadFile(). 
 306.468 +	 *
 306.469 +	 * Returns an empty string if no error occurred.
 306.470 +	 * @return A description of the last error, an empty string if no 
 306.471 +	 *   error occurred. The string is never NULL.
 306.472 +	 *
 306.473 +	 * @note The returned function remains valid until one of the 
 306.474 +	 * following methods is called: #ReadFile(), #FreeScene(). */
 306.475 +	const char* GetErrorString() const;
 306.476 +
 306.477 +	// -------------------------------------------------------------------
 306.478 +	/** Returns the scene loaded by the last successful call to ReadFile()
 306.479 +	 *
 306.480 +	 * @return Current scene or NULL if there is currently no scene loaded */
 306.481 +	const aiScene* GetScene() const;
 306.482 +
 306.483 +	// -------------------------------------------------------------------
 306.484 +	/** Returns the scene loaded by the last successful call to ReadFile()
 306.485 +	 *  and releases the scene from the ownership of the Importer 
 306.486 +	 *  instance. The application is now responsible for deleting the
 306.487 +	 *  scene. Any further calls to GetScene() or GetOrphanedScene()
 306.488 +	 *  will return NULL - until a new scene has been loaded via ReadFile().
 306.489 +	 *
 306.490 +	 * @return Current scene or NULL if there is currently no scene loaded
 306.491 +	 * @note Use this method with maximal caution, and only if you have to.
 306.492 +	 *   By design, aiScene's are exclusively maintained, allocated and
 306.493 +	 *   deallocated by Assimp and no one else. The reasoning behind this
 306.494 +	 *   is the golden rule that deallocations should always be done
 306.495 +	 *   by the module that did the original allocation because heaps
 306.496 +	 *   are not necessarily shared. GetOrphanedScene() enforces you
 306.497 +	 *   to delete the returned scene by yourself, but this will only
 306.498 +	 *   be fine if and only if you're using the same heap as assimp.
 306.499 +	 *   On Windows, it's typically fine provided everything is linked
 306.500 +	 *   against the multithreaded-dll version of the runtime library.
 306.501 +	 *   It will work as well for static linkage with Assimp.*/
 306.502 +	aiScene* GetOrphanedScene();
 306.503 +
 306.504 +
 306.505 +
 306.506 +
 306.507 +	// -------------------------------------------------------------------
 306.508 +	/** Returns whether a given file extension is supported by ASSIMP.
 306.509 +	 *
 306.510 +	 * @param szExtension Extension to be checked.
 306.511 +	 *   Must include a trailing dot '.'. Example: ".3ds", ".md3".
 306.512 +	 *   Cases-insensitive.
 306.513 +	 * @return true if the extension is supported, false otherwise */
 306.514 +	bool IsExtensionSupported(const char* szExtension) const;
 306.515 +
 306.516 +	// -------------------------------------------------------------------
 306.517 +	/** @brief Returns whether a given file extension is supported by ASSIMP.
 306.518 +	 *
 306.519 +	 * This function is provided for backward compatibility.
 306.520 +	 * See the const char* version for detailed and up-to-date docs.
 306.521 +	 * @see IsExtensionSupported(const char*) */
 306.522 +	inline bool IsExtensionSupported(const std::string& szExtension) const;
 306.523 +
 306.524 +	// -------------------------------------------------------------------
 306.525 +	/** Get a full list of all file extensions supported by ASSIMP.
 306.526 +	 *
 306.527 +	 * If a file extension is contained in the list this does of course not
 306.528 +	 * mean that ASSIMP is able to load all files with this extension ---
 306.529 +     * it simply means there is an importer loaded which claims to handle
 306.530 +	 * files with this file extension.
 306.531 +	 * @param szOut String to receive the extension list. 
 306.532 +	 *   Format of the list: "*.3ds;*.obj;*.dae". This is useful for
 306.533 +	 *   use with the WinAPI call GetOpenFileName(Ex). */
 306.534 +	void GetExtensionList(aiString& szOut) const;
 306.535 +
 306.536 +	// -------------------------------------------------------------------
 306.537 +	/** @brief Get a full list of all file extensions supported by ASSIMP.
 306.538 +	 *
 306.539 +	 * This function is provided for backward compatibility.
 306.540 +	 * See the aiString version for detailed and up-to-date docs.
 306.541 +	 * @see GetExtensionList(aiString&)*/
 306.542 +	inline void GetExtensionList(std::string& szOut) const;
 306.543 +
 306.544 +	// -------------------------------------------------------------------
 306.545 +	/** Get the number of importrs currently registered with Assimp. */
 306.546 +	size_t GetImporterCount() const;
 306.547 +
 306.548 +	// -------------------------------------------------------------------
 306.549 +	/** Get meta data for the importer corresponding to a specific index..
 306.550 +	*
 306.551 +	*  For the declaration of #aiImporterDesc, include <assimp/importerdesc.h>.
 306.552 +	*  @param index Index to query, must be within [0,GetImporterCount())
 306.553 +	*  @return Importer meta data structure, NULL if the index does not
 306.554 +	*     exist or if the importer doesn't offer meta information (
 306.555 +	*     importers may do this at the cost of being hated by their peers).*/
 306.556 +	const aiImporterDesc* GetImporterInfo(size_t index) const;
 306.557 +
 306.558 +	// -------------------------------------------------------------------
 306.559 +	/** Find the importer corresponding to a specific index.
 306.560 +	*
 306.561 +	*  @param index Index to query, must be within [0,GetImporterCount())
 306.562 +	*  @return Importer instance. NULL if the index does not
 306.563 +	*     exist. */
 306.564 +	BaseImporter* GetImporter(size_t index) const;
 306.565 +
 306.566 +	// -------------------------------------------------------------------
 306.567 +	/** Find the importer corresponding to a specific file extension.
 306.568 +	*
 306.569 +	*  This is quite similar to #IsExtensionSupported except a
 306.570 +	*  BaseImporter instance is returned.
 306.571 +	*  @param szExtension Extension to check for. The following formats
 306.572 +	*    are recognized (BAH being the file extension): "BAH" (comparison
 306.573 +	*    is case-insensitive), ".bah", "*.bah" (wild card and dot
 306.574 +	*    characters at the beginning of the extension are skipped).
 306.575 +	*  @return NULL if no importer is found*/
 306.576 +	BaseImporter* GetImporter (const char* szExtension) const;
 306.577 +
 306.578 +	// -------------------------------------------------------------------
 306.579 +	/** Find the importer index corresponding to a specific file extension.
 306.580 +	*
 306.581 +	*  @param szExtension Extension to check for. The following formats
 306.582 +	*    are recognized (BAH being the file extension): "BAH" (comparison
 306.583 +	*    is case-insensitive), ".bah", "*.bah" (wild card and dot
 306.584 +	*    characters at the beginning of the extension are skipped).
 306.585 +	*  @return (size_t)-1 if no importer is found */
 306.586 +	size_t GetImporterIndex (const char* szExtension) const;
 306.587 +
 306.588 +
 306.589 +
 306.590 +
 306.591 +	// -------------------------------------------------------------------
 306.592 +	/** Returns the storage allocated by ASSIMP to hold the scene data
 306.593 +	 * in memory.
 306.594 +	 *
 306.595 +	 * This refers to the currently loaded file, see #ReadFile().
 306.596 +	 * @param in Data structure to be filled. 
 306.597 +	 * @note The returned memory statistics refer to the actual
 306.598 +	 *   size of the use data of the aiScene. Heap-related overhead
 306.599 +	 *   is (naturally) not included.*/
 306.600 +	void GetMemoryRequirements(aiMemoryInfo& in) const;
 306.601 +
 306.602 +	// -------------------------------------------------------------------
 306.603 +	/** Enables "extra verbose" mode. 
 306.604 +	 *
 306.605 +	 * 'Extra verbose' means the data structure is validated after *every*
 306.606 +	 * single post processing step to make sure everyone modifies the data
 306.607 +	 * structure in a well-defined manner. This is a debug feature and not
 306.608 +	 * intended for use in production environments. */
 306.609 +	void SetExtraVerbose(bool bDo);
 306.610 +
 306.611 +
 306.612 +	// -------------------------------------------------------------------
 306.613 +	/** Private, do not use. */
 306.614 +	ImporterPimpl* Pimpl() { return pimpl; };
 306.615 +	const ImporterPimpl* Pimpl() const { return pimpl; };
 306.616 +
 306.617 +protected:
 306.618 +
 306.619 +	// Just because we don't want you to know how we're hacking around.
 306.620 +	ImporterPimpl* pimpl;
 306.621 +}; //! class Importer
 306.622 +
 306.623 +
 306.624 +// ----------------------------------------------------------------------------
 306.625 +// For compatibility, the interface of some functions taking a std::string was
 306.626 +// changed to const char* to avoid crashes between binary incompatible STL 
 306.627 +// versions. This code her is inlined,  so it shouldn't cause any problems.
 306.628 +// ----------------------------------------------------------------------------
 306.629 +
 306.630 +// ----------------------------------------------------------------------------
 306.631 +AI_FORCE_INLINE const aiScene* Importer::ReadFile( const std::string& pFile,unsigned int pFlags){
 306.632 +	return ReadFile(pFile.c_str(),pFlags);
 306.633 +}
 306.634 +// ----------------------------------------------------------------------------
 306.635 +AI_FORCE_INLINE void Importer::GetExtensionList(std::string& szOut) const	{
 306.636 +	aiString s;
 306.637 +	GetExtensionList(s);
 306.638 +	szOut = s.data;
 306.639 +}
 306.640 +// ----------------------------------------------------------------------------
 306.641 +AI_FORCE_INLINE bool Importer::IsExtensionSupported(const std::string& szExtension) const	{
 306.642 +	return IsExtensionSupported(szExtension.c_str());
 306.643 +}
 306.644 +
 306.645 +} // !namespace Assimp
 306.646 +#endif // INCLUDED_AI_ASSIMP_HPP
   307.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   307.2 +++ b/libs/assimp/assimp/LogStream.hpp	Sat Feb 01 19:58:19 2014 +0200
   307.3 @@ -0,0 +1,93 @@
   307.4 +/*
   307.5 +Open Asset Import Library (assimp)
   307.6 +----------------------------------------------------------------------
   307.7 +
   307.8 +Copyright (c) 2006-2012, assimp team
   307.9 +All rights reserved.
  307.10 +
  307.11 +Redistribution and use of this software in source and binary forms, 
  307.12 +with or without modification, are permitted provided that the 
  307.13 +following conditions are met:
  307.14 +
  307.15 +* Redistributions of source code must retain the above
  307.16 +  copyright notice, this list of conditions and the
  307.17 +  following disclaimer.
  307.18 +
  307.19 +* Redistributions in binary form must reproduce the above
  307.20 +  copyright notice, this list of conditions and the
  307.21 +  following disclaimer in the documentation and/or other
  307.22 +  materials provided with the distribution.
  307.23 +
  307.24 +* Neither the name of the assimp team, nor the names of its
  307.25 +  contributors may be used to endorse or promote products
  307.26 +  derived from this software without specific prior
  307.27 +  written permission of the assimp team.
  307.28 +
  307.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  307.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  307.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  307.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  307.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  307.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  307.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  307.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  307.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  307.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  307.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  307.40 +
  307.41 +----------------------------------------------------------------------
  307.42 +*/
  307.43 +
  307.44 +/** @file LogStream.h
  307.45 + *  @brief Abstract base class 'LogStream', representing an output log stream.
  307.46 + */
  307.47 +#ifndef INCLUDED_AI_LOGSTREAM_H
  307.48 +#define INCLUDED_AI_LOGSTREAM_H
  307.49 +#include "types.h"
  307.50 +namespace Assimp	{
  307.51 +class IOSystem;
  307.52 +
  307.53 +// ------------------------------------------------------------------------------------
  307.54 +/** @brief CPP-API: Abstract interface for log stream implementations.
  307.55 + *
  307.56 + *  Several default implementations are provided, see #aiDefaultLogStream for more
  307.57 + *  details. Writing your own implementation of LogStream is just necessary if these
  307.58 + *  are not enough for your purpose. */
  307.59 +class ASSIMP_API LogStream 
  307.60 +	: public Intern::AllocateFromAssimpHeap	{
  307.61 +protected:
  307.62 +	/** @brief	Default constructor	*/
  307.63 +	LogStream() {
  307.64 +	}
  307.65 +public:
  307.66 +	/** @brief	Virtual destructor	*/
  307.67 +	virtual ~LogStream() {
  307.68 +	}
  307.69 +
  307.70 +	// -------------------------------------------------------------------
  307.71 +	/** @brief	Overwrite this for your own output methods
  307.72 +	 *
  307.73 +	 *  Log messages *may* consist of multiple lines and you shouldn't
  307.74 +	 *  expect a consistent formatting. If you want custom formatting 
  307.75 +	 *  (e.g. generate HTML), supply a custom instance of Logger to
  307.76 +	 *  #DefaultLogger:set(). Usually you can *expect* that a log message
  307.77 +	 *  is exactly one line and terminated with a single \n character.
  307.78 +	 *  @param message Message to be written */
  307.79 +	virtual void write(const char* message) = 0;
  307.80 +
  307.81 +	// -------------------------------------------------------------------
  307.82 +	/** @brief Creates a default log stream
  307.83 +	 *  @param streams Type of the default stream
  307.84 +	 *  @param name For aiDefaultLogStream_FILE: name of the output file
  307.85 +	 *  @param io For aiDefaultLogStream_FILE: IOSystem to be used to open the output 
  307.86 +	 *   file. Pass NULL for the default implementation.
  307.87 +	 *  @return New LogStream instance.  */
  307.88 +	static LogStream* createDefaultStream(aiDefaultLogStream stream,
  307.89 +		const char* name = "AssimpLog.txt",
  307.90 +		IOSystem* io = NULL);
  307.91 +
  307.92 +}; // !class LogStream
  307.93 +// ------------------------------------------------------------------------------------
  307.94 +} // Namespace Assimp
  307.95 +
  307.96 +#endif
   308.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   308.2 +++ b/libs/assimp/assimp/Logger.hpp	Sat Feb 01 19:58:19 2014 +0200
   308.3 @@ -0,0 +1,262 @@
   308.4 +/*
   308.5 +Open Asset Import Library (assimp)
   308.6 +----------------------------------------------------------------------
   308.7 +
   308.8 +Copyright (c) 2006-2012, assimp team
   308.9 +All rights reserved.
  308.10 +
  308.11 +Redistribution and use of this software in source and binary forms, 
  308.12 +with or without modification, are permitted provided that the 
  308.13 +following conditions are met:
  308.14 +
  308.15 +* Redistributions of source code must retain the above
  308.16 +  copyright notice, this list of conditions and the
  308.17 +  following disclaimer.
  308.18 +
  308.19 +* Redistributions in binary form must reproduce the above
  308.20 +  copyright notice, this list of conditions and the
  308.21 +  following disclaimer in the documentation and/or other
  308.22 +  materials provided with the distribution.
  308.23 +
  308.24 +* Neither the name of the assimp team, nor the names of its
  308.25 +  contributors may be used to endorse or promote products
  308.26 +  derived from this software without specific prior
  308.27 +  written permission of the assimp team.
  308.28 +
  308.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  308.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  308.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  308.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  308.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  308.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  308.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  308.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  308.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  308.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  308.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  308.40 +
  308.41 +----------------------------------------------------------------------
  308.42 +*/
  308.43 +
  308.44 +/** @file Logger.hpp
  308.45 + *  @brief Abstract base class 'Logger', base of the logging system. 
  308.46 + */
  308.47 +#ifndef INCLUDED_AI_LOGGER_H
  308.48 +#define INCLUDED_AI_LOGGER_H
  308.49 +
  308.50 +#include "types.h"
  308.51 +namespace Assimp	{
  308.52 +class LogStream;
  308.53 +
  308.54 +// Maximum length of a log message. Longer messages are rejected.
  308.55 +#define MAX_LOG_MESSAGE_LENGTH 1024u
  308.56 +
  308.57 +// ----------------------------------------------------------------------------------
  308.58 +/**	@brief CPP-API: Abstract interface for logger implementations.
  308.59 + *  Assimp provides a default implementation and uses it for almost all 
  308.60 + *  logging stuff ('DefaultLogger'). This class defines just basic logging
  308.61 + *  behaviour and is not of interest for you. Instead, take a look at #DefaultLogger. */
  308.62 +class ASSIMP_API Logger 
  308.63 +	: public Intern::AllocateFromAssimpHeap	{
  308.64 +public:
  308.65 +
  308.66 +	// ----------------------------------------------------------------------
  308.67 +	/**	@enum	LogSeverity
  308.68 +	 *	@brief	Log severity to describe the granularity of logging.
  308.69 +	 */
  308.70 +	enum LogSeverity
  308.71 +	{
  308.72 +		NORMAL,		//!< Normal granularity of logging
  308.73 +		VERBOSE		//!< Debug infos will be logged, too
  308.74 +	};
  308.75 +
  308.76 +	// ----------------------------------------------------------------------
  308.77 +	/**	@enum	ErrorSeverity
  308.78 +	 *	@brief	Description for severity of a log message.
  308.79 +	 *
  308.80 +	 *  Every LogStream has a bitwise combination of these flags.
  308.81 +	 *  A LogStream doesn't receive any messages of a specific type
  308.82 +	 *  if it doesn't specify the corresponding ErrorSeverity flag.
  308.83 +	 */
  308.84 +	enum ErrorSeverity
  308.85 +	{
  308.86 +		Debugging	= 1,	//!< Debug log message
  308.87 +		Info		= 2, 	//!< Info log message
  308.88 +		Warn		= 4,	//!< Warn log message
  308.89 +		Err			= 8		//!< Error log message
  308.90 +	};
  308.91 +
  308.92 +public:
  308.93 +
  308.94 +	/** @brief	Virtual destructor */
  308.95 +	virtual ~Logger();
  308.96 +
  308.97 +	// ----------------------------------------------------------------------
  308.98 +	/** @brief	Writes a debug message
  308.99 +	 *	 @param	message	Debug message*/
 308.100 +	void debug(const char* message);
 308.101 +	inline void debug(const std::string &message);
 308.102 +
 308.103 +	// ----------------------------------------------------------------------
 308.104 +	/** @brief	Writes a info message
 308.105 +	 *	@param	message Info message*/
 308.106 +	void info(const char* message);
 308.107 +	inline void info(const std::string &message);
 308.108 +
 308.109 +	// ----------------------------------------------------------------------
 308.110 +	/** @brief	Writes a warning message
 308.111 +	 *	@param	message Warn message*/
 308.112 +	void warn(const char* message);
 308.113 +	inline void warn(const std::string &message);
 308.114 +
 308.115 +	// ----------------------------------------------------------------------
 308.116 +	/** @brief	Writes an error message
 308.117 +	 *	@param	message	Error message*/
 308.118 +	void error(const char* message);
 308.119 +	inline void error(const std::string &message);
 308.120 +
 308.121 +	// ----------------------------------------------------------------------
 308.122 +	/** @brief	Set a new log severity.
 308.123 +	 *	@param	log_severity New severity for logging*/
 308.124 +	void setLogSeverity(LogSeverity log_severity);
 308.125 +
 308.126 +	// ----------------------------------------------------------------------
 308.127 +	/** @brief Get the current log severity*/
 308.128 +	LogSeverity getLogSeverity() const;
 308.129 +
 308.130 +	// ----------------------------------------------------------------------
 308.131 +	/** @brief	Attach a new log-stream
 308.132 +	 *
 308.133 +	 *  The logger takes ownership of the stream and is responsible
 308.134 +	 *  for its destruction (which is done using ::delete when the logger
 308.135 +	 *  itself is destroyed). Call detachStream to detach a stream and to
 308.136 +	 *  gain ownership of it again.
 308.137 +	 *	 @param	pStream	 Log-stream to attach
 308.138 +	 *  @param severity  Message filter, specified which types of log
 308.139 +	 *    messages are dispatched to the stream. Provide a bitwise
 308.140 +	 *    combination of the ErrorSeverity flags.
 308.141 +	 *  @return true if the stream has been attached, false otherwise.*/
 308.142 +	virtual bool attachStream(LogStream *pStream, 
 308.143 +		unsigned int severity = Debugging | Err | Warn | Info) = 0;
 308.144 +
 308.145 +	// ----------------------------------------------------------------------
 308.146 +	/** @brief	Detach a still attached stream from the logger (or 
 308.147 +	 *          modify the filter flags bits)
 308.148 +	 *	 @param	pStream	Log-stream instance for detaching
 308.149 +	 *  @param severity Provide a bitwise combination of the ErrorSeverity
 308.150 +	 *    flags. This value is &~ed with the current flags of the stream,
 308.151 +	 *    if the result is 0 the stream is detached from the Logger and
 308.152 +	 *    the caller retakes the possession of the stream.
 308.153 +	 *  @return true if the stream has been detached, false otherwise.*/
 308.154 +	virtual bool detatchStream(LogStream *pStream, 
 308.155 +		unsigned int severity = Debugging | Err | Warn | Info) = 0;
 308.156 +
 308.157 +protected:
 308.158 +
 308.159 +	/** Default constructor */
 308.160 +	Logger();
 308.161 +
 308.162 +	/** Construction with a given log severity */
 308.163 +	Logger(LogSeverity severity);
 308.164 +
 308.165 +	// ----------------------------------------------------------------------
 308.166 +	/** @brief Called as a request to write a specific debug message
 308.167 +	 *	@param	message	Debug message. Never longer than
 308.168 +	 *    MAX_LOG_MESSAGE_LENGTH characters (excluding the '0').
 308.169 +	 *  @note  The message string is only valid until the scope of
 308.170 +	 *    the function is left.
 308.171 +	 */
 308.172 +	virtual void OnDebug(const char* message)= 0;
 308.173 +
 308.174 +	// ----------------------------------------------------------------------
 308.175 +	/** @brief Called as a request to write a specific info message
 308.176 +	 *	@param	message	Info message. Never longer than
 308.177 +	 *    MAX_LOG_MESSAGE_LENGTH characters (ecxluding the '0').
 308.178 +	 *  @note  The message string is only valid until the scope of
 308.179 +	 *    the function is left.
 308.180 +	 */
 308.181 +	virtual void OnInfo(const char* message) = 0;
 308.182 +
 308.183 +	// ----------------------------------------------------------------------
 308.184 +	/** @brief Called as a request to write a specific warn message
 308.185 +	 *	@param	message	Warn message. Never longer than
 308.186 +	 *    MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
 308.187 +	 *  @note  The message string is only valid until the scope of
 308.188 +	 *    the function is left.
 308.189 +	 */
 308.190 +	virtual void OnWarn(const char* essage) = 0;
 308.191 +
 308.192 +	// ----------------------------------------------------------------------
 308.193 +	/** @brief Called as a request to write a specific error message
 308.194 +	 *	@param	message Error message. Never longer than
 308.195 +	 *    MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
 308.196 +	 *  @note  The message string is only valid until the scope of
 308.197 +	 *    the function is left.
 308.198 +	 */
 308.199 +	virtual void OnError(const char* message) = 0;
 308.200 +
 308.201 +protected:
 308.202 +
 308.203 +	//!	Logger severity
 308.204 +	LogSeverity m_Severity;
 308.205 +};
 308.206 +
 308.207 +// ----------------------------------------------------------------------------------
 308.208 +//	Default constructor
 308.209 +inline Logger::Logger()	{
 308.210 +	setLogSeverity(NORMAL);
 308.211 +}
 308.212 +
 308.213 +// ----------------------------------------------------------------------------------
 308.214 +//	Virtual destructor
 308.215 +inline  Logger::~Logger()
 308.216 +{
 308.217 +}
 308.218 +
 308.219 +// ----------------------------------------------------------------------------------
 308.220 +// Construction with given logging severity
 308.221 +inline Logger::Logger(LogSeverity severity)	{
 308.222 +	setLogSeverity(severity);
 308.223 +}
 308.224 +
 308.225 +// ----------------------------------------------------------------------------------
 308.226 +// Log severity setter
 308.227 +inline void Logger::setLogSeverity(LogSeverity log_severity){
 308.228 +	m_Severity = log_severity;
 308.229 +}
 308.230 +
 308.231 +// ----------------------------------------------------------------------------------
 308.232 +// Log severity getter
 308.233 +inline Logger::LogSeverity Logger::getLogSeverity() const {
 308.234 +	return m_Severity;
 308.235 +}
 308.236 +
 308.237 +// ----------------------------------------------------------------------------------
 308.238 +inline void Logger::debug(const std::string &message)
 308.239 +{
 308.240 +	return debug(message.c_str());
 308.241 +}
 308.242 +
 308.243 +// ----------------------------------------------------------------------------------
 308.244 +inline void Logger::error(const std::string &message)
 308.245 +{
 308.246 +	return error(message.c_str());
 308.247 +}
 308.248 +
 308.249 +// ----------------------------------------------------------------------------------
 308.250 +inline void Logger::warn(const std::string &message)
 308.251 +{
 308.252 +	return warn(message.c_str());
 308.253 +}
 308.254 +
 308.255 +// ----------------------------------------------------------------------------------
 308.256 +inline void Logger::info(const std::string &message)
 308.257 +{
 308.258 +	return info(message.c_str());
 308.259 +}
 308.260 +
 308.261 +// ----------------------------------------------------------------------------------
 308.262 +
 308.263 +} // Namespace Assimp
 308.264 +
 308.265 +#endif // !! INCLUDED_AI_LOGGER_H
   309.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   309.2 +++ b/libs/assimp/assimp/NullLogger.hpp	Sat Feb 01 19:58:19 2014 +0200
   309.3 @@ -0,0 +1,95 @@
   309.4 +/*
   309.5 +Open Asset Import Library (assimp)
   309.6 +----------------------------------------------------------------------
   309.7 +
   309.8 +Copyright (c) 2006-2012, assimp team
   309.9 +All rights reserved.
  309.10 +
  309.11 +Redistribution and use of this software in source and binary forms, 
  309.12 +with or without modification, are permitted provided that the 
  309.13 +following conditions are met:
  309.14 +
  309.15 +* Redistributions of source code must retain the above
  309.16 +  copyright notice, this list of conditions and the
  309.17 +  following disclaimer.
  309.18 +
  309.19 +* Redistributions in binary form must reproduce the above
  309.20 +  copyright notice, this list of conditions and the
  309.21 +  following disclaimer in the documentation and/or other
  309.22 +  materials provided with the distribution.
  309.23 +
  309.24 +* Neither the name of the assimp team, nor the names of its
  309.25 +  contributors may be used to endorse or promote products
  309.26 +  derived from this software without specific prior
  309.27 +  written permission of the assimp team.
  309.28 +
  309.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  309.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  309.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  309.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  309.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  309.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  309.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  309.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  309.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  309.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  309.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  309.40 +
  309.41 +----------------------------------------------------------------------
  309.42 +*/
  309.43 +
  309.44 +/** @file  NullLogger.h
  309.45 + *  @brief Dummy logger
  309.46 +*/
  309.47 +
  309.48 +#ifndef INCLUDED_AI_NULLLOGGER_H
  309.49 +#define INCLUDED_AI_NULLLOGGER_H
  309.50 +
  309.51 +#include "Logger.hpp"
  309.52 +namespace Assimp	{
  309.53 +// ---------------------------------------------------------------------------
  309.54 +/** @brief CPP-API: Empty logging implementation.
  309.55 + *
  309.56 + * Does nothing! Used by default if the application hasn't requested a 
  309.57 + * custom logger via #DefaultLogger::set() or #DefaultLogger::create(); */
  309.58 +class ASSIMP_API NullLogger 
  309.59 +	: public Logger	{
  309.60 +
  309.61 +public:
  309.62 +
  309.63 +	/**	@brief	Logs a debug message */
  309.64 +	void OnDebug(const char* message) { 
  309.65 +		(void)message; //this avoids compiler warnings
  309.66 +	}
  309.67 +
  309.68 +	/**	@brief	Logs an info message */
  309.69 +	void OnInfo(const char* message) { 
  309.70 +		(void)message; //this avoids compiler warnings
  309.71 +	}
  309.72 +
  309.73 +	/**	@brief	Logs a warning message */
  309.74 +	void OnWarn(const char* message) { 
  309.75 +		(void)message; //this avoids compiler warnings
  309.76 +	}
  309.77 +	
  309.78 +	/**	@brief	Logs an error message */
  309.79 +	void OnError(const char* message) { 
  309.80 +		(void)message; //this avoids compiler warnings
  309.81 +	}
  309.82 +
  309.83 +	/**	@brief	Detach a still attached stream from logger */
  309.84 +	bool attachStream(LogStream *pStream, unsigned int severity) {
  309.85 +		(void)pStream; (void)severity; //this avoids compiler warnings
  309.86 +		return false;
  309.87 +	}
  309.88 +
  309.89 +	/**	@brief	Detach a still attached stream from logger */
  309.90 +	bool detatchStream(LogStream *pStream, unsigned int severity) {
  309.91 +		(void)pStream; (void)severity; //this avoids compiler warnings
  309.92 +		return false;
  309.93 +	}
  309.94 +
  309.95 +private:
  309.96 +};
  309.97 +}
  309.98 +#endif // !! AI_NULLLOGGER_H_INCLUDED
   310.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   310.2 +++ b/libs/assimp/assimp/ProgressHandler.hpp	Sat Feb 01 19:58:19 2014 +0200
   310.3 @@ -0,0 +1,93 @@
   310.4 +/*
   310.5 +Open Asset Import Library (assimp)
   310.6 +----------------------------------------------------------------------
   310.7 +
   310.8 +Copyright (c) 2006-2012, assimp team
   310.9 +All rights reserved.
  310.10 +
  310.11 +Redistribution and use of this software in source and binary forms, 
  310.12 +with or without modification, are permitted provided that the 
  310.13 +following conditions are met:
  310.14 +
  310.15 +* Redistributions of source code must retain the above
  310.16 +  copyright notice, this list of conditions and the
  310.17 +  following disclaimer.
  310.18 +
  310.19 +* Redistributions in binary form must reproduce the above
  310.20 +  copyright notice, this list of conditions and the
  310.21 +  following disclaimer in the documentation and/or other
  310.22 +  materials provided with the distribution.
  310.23 +
  310.24 +* Neither the name of the assimp team, nor the names of its
  310.25 +  contributors may be used to endorse or promote products
  310.26 +  derived from this software without specific prior
  310.27 +  written permission of the assimp team.
  310.28 +
  310.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  310.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  310.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  310.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  310.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  310.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  310.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  310.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  310.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  310.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  310.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  310.40 +
  310.41 +----------------------------------------------------------------------
  310.42 +*/
  310.43 +
  310.44 +/** @file ProgressHandler.h
  310.45 + *  @brief Abstract base class 'ProgressHandler'.
  310.46 + */
  310.47 +#ifndef INCLUDED_AI_PROGRESSHANDLER_H
  310.48 +#define INCLUDED_AI_PROGRESSHANDLER_H
  310.49 +#include "types.h"
  310.50 +namespace Assimp	{
  310.51 +
  310.52 +// ------------------------------------------------------------------------------------
  310.53 +/** @brief CPP-API: Abstract interface for custom progress report receivers.
  310.54 + *
  310.55 + *  Each #Importer instance maintains its own #ProgressHandler. The default 
  310.56 + *  implementation provided by Assimp doesn't do anything at all. */
  310.57 +class ASSIMP_API ProgressHandler 
  310.58 +	: public Intern::AllocateFromAssimpHeap	{
  310.59 +protected:
  310.60 +	/** @brief	Default constructor	*/
  310.61 +	ProgressHandler () {
  310.62 +	}
  310.63 +public:
  310.64 +	/** @brief	Virtual destructor	*/
  310.65 +	virtual ~ProgressHandler () {
  310.66 +	}
  310.67 +
  310.68 +	// -------------------------------------------------------------------
  310.69 +	/** @brief Progress callback.
  310.70 +	 *  @param percentage An estimate of the current loading progress,
  310.71 +	 *    in percent. Or -1.f if such an estimate is not available.
  310.72 +	 *
  310.73 +	 *  There are restriction on what you may do from within your 
  310.74 +	 *  implementation of this method: no exceptions may be thrown and no
  310.75 +	 *  non-const #Importer methods may be called. It is 
  310.76 +	 *  not generally possible to predict the number of callbacks 
  310.77 +	 *  fired during a single import.
  310.78 +	 *
  310.79 +	 *  @return Return false to abort loading at the next possible
  310.80 +	 *   occasion (loaders and Assimp are generally allowed to perform
  310.81 +	 *   all needed cleanup tasks prior to returning control to the
  310.82 +	 *   caller). If the loading is aborted, #Importer::ReadFile()
  310.83 +	 *   returns always NULL.
  310.84 +	 *
  310.85 +	 *  @note Currently, percentage is always -1.f because there is 
  310.86 +	 *   no reliable way to compute it.
  310.87 +	 *   */
  310.88 +	virtual bool Update(float percentage = -1.f) = 0;
  310.89 +
  310.90 +
  310.91 +
  310.92 +}; // !class ProgressHandler 
  310.93 +// ------------------------------------------------------------------------------------
  310.94 +} // Namespace Assimp
  310.95 +
  310.96 +#endif
   311.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   311.2 +++ b/libs/assimp/assimp/ai_assert.h	Sat Feb 01 19:58:19 2014 +0200
   311.3 @@ -0,0 +1,14 @@
   311.4 +/** @file assert.h
   311.5 + */
   311.6 +#ifndef AI_DEBUG_H_INC
   311.7 +#define AI_DEBUG_H_INC
   311.8 +
   311.9 +#ifdef _DEBUG  
  311.10 +#	include <assert.h>
  311.11 +#	define	ai_assert(expression) assert(expression)
  311.12 +#else
  311.13 +#	define	ai_assert(expression)
  311.14 +#endif
  311.15 +
  311.16 +
  311.17 +#endif
   312.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   312.2 +++ b/libs/assimp/assimp/anim.h	Sat Feb 01 19:58:19 2014 +0200
   312.3 @@ -0,0 +1,484 @@
   312.4 +/*
   312.5 +---------------------------------------------------------------------------
   312.6 +Open Asset Import Library (assimp)
   312.7 +---------------------------------------------------------------------------
   312.8 +
   312.9 +Copyright (c) 2006-2012, assimp team
  312.10 +
  312.11 +All rights reserved.
  312.12 +
  312.13 +Redistribution and use of this software in source and binary forms, 
  312.14 +with or without modification, are permitted provided that the following 
  312.15 +conditions are met:
  312.16 +
  312.17 +* Redistributions of source code must retain the above
  312.18 +  copyright notice, this list of conditions and the
  312.19 +  following disclaimer.
  312.20 +
  312.21 +* Redistributions in binary form must reproduce the above
  312.22 +  copyright notice, this list of conditions and the
  312.23 +  following disclaimer in the documentation and/or other
  312.24 +  materials provided with the distribution.
  312.25 +
  312.26 +* Neither the name of the assimp team, nor the names of its
  312.27 +  contributors may be used to endorse or promote products
  312.28 +  derived from this software without specific prior
  312.29 +  written permission of the assimp team.
  312.30 +
  312.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  312.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  312.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  312.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  312.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  312.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  312.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  312.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  312.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  312.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  312.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  312.42 +---------------------------------------------------------------------------
  312.43 +*/
  312.44 +
  312.45 +/** @file anim.h
  312.46 + *  @brief Defines the data structures in which the imported animations
  312.47 + *  are returned.
  312.48 + */
  312.49 +#ifndef AI_ANIM_H_INC
  312.50 +#define AI_ANIM_H_INC
  312.51 +
  312.52 +#include "types.h"
  312.53 +#include "quaternion.h"
  312.54 +
  312.55 +#ifdef __cplusplus
  312.56 +extern "C" {
  312.57 +#endif
  312.58 +
  312.59 +// ---------------------------------------------------------------------------
  312.60 +/** A time-value pair specifying a certain 3D vector for the given time. */
  312.61 +struct aiVectorKey
  312.62 +{
  312.63 +	/** The time of this key */
  312.64 +	double mTime;     
  312.65 +	
  312.66 +	/** The value of this key */
  312.67 +	C_STRUCT aiVector3D mValue; 
  312.68 +
  312.69 +#ifdef __cplusplus
  312.70 +
  312.71 +	//! Default constructor
  312.72 +	aiVectorKey(){}
  312.73 +
  312.74 +	//! Construction from a given time and key value
  312.75 +	aiVectorKey(double time, const aiVector3D& value)
  312.76 +		:	mTime	(time)
  312.77 +		,	mValue	(value)
  312.78 +	{}
  312.79 +
  312.80 +
  312.81 +	typedef aiVector3D elem_type;
  312.82 +
  312.83 +	// Comparison operators. For use with std::find();
  312.84 +	bool operator == (const aiVectorKey& o) const {
  312.85 +		return o.mValue == this->mValue;
  312.86 +	}
  312.87 +	bool operator != (const aiVectorKey& o) const {
  312.88 +		return o.mValue != this->mValue;
  312.89 +	}
  312.90 +
  312.91 +	// Relational operators. For use with std::sort();
  312.92 +	bool operator < (const aiVectorKey& o) const {
  312.93 +		return mTime < o.mTime;
  312.94 +	}
  312.95 +	bool operator > (const aiVectorKey& o) const {
  312.96 +		return mTime > o.mTime;
  312.97 +	}
  312.98 +#endif
  312.99 +};
 312.100 +
 312.101 +// ---------------------------------------------------------------------------
 312.102 +/** A time-value pair specifying a rotation for the given time. 
 312.103 + *  Rotations are expressed with quaternions. */
 312.104 +struct aiQuatKey
 312.105 +{
 312.106 +	/** The time of this key */
 312.107 +	double mTime;     
 312.108 +
 312.109 +	/** The value of this key */
 312.110 +	C_STRUCT aiQuaternion mValue; 
 312.111 +
 312.112 +#ifdef __cplusplus
 312.113 +	aiQuatKey(){
 312.114 +	}
 312.115 +
 312.116 +	/** Construction from a given time and key value */
 312.117 +	aiQuatKey(double time, const aiQuaternion& value)
 312.118 +		:	mTime	(time)
 312.119 +		,	mValue	(value)
 312.120 +	{}
 312.121 +
 312.122 +	typedef aiQuaternion elem_type;
 312.123 +
 312.124 +	// Comparison operators. For use with std::find();
 312.125 +	bool operator == (const aiQuatKey& o) const {
 312.126 +		return o.mValue == this->mValue;
 312.127 +	}
 312.128 +	bool operator != (const aiQuatKey& o) const {
 312.129 +		return o.mValue != this->mValue;
 312.130 +	}
 312.131 +
 312.132 +	// Relational operators. For use with std::sort();
 312.133 +	bool operator < (const aiQuatKey& o) const {
 312.134 +		return mTime < o.mTime;
 312.135 +	}
 312.136 +	bool operator > (const aiQuatKey& o) const {
 312.137 +		return mTime > o.mTime;
 312.138 +	}
 312.139 +#endif
 312.140 +};
 312.141 +
 312.142 +// ---------------------------------------------------------------------------
 312.143 +/** Binds a anim mesh to a specific point in time. */
 312.144 +struct aiMeshKey 
 312.145 +{
 312.146 +	/** The time of this key */
 312.147 +	double mTime;
 312.148 +
 312.149 +	/** Index into the aiMesh::mAnimMeshes array of the 
 312.150 +	 *  mesh coresponding to the #aiMeshAnim hosting this
 312.151 +	 *  key frame. The referenced anim mesh is evaluated
 312.152 +	 *  according to the rules defined in the docs for #aiAnimMesh.*/
 312.153 +	unsigned int mValue;
 312.154 +
 312.155 +#ifdef __cplusplus
 312.156 +
 312.157 +	aiMeshKey() {
 312.158 +	}
 312.159 +
 312.160 +	/** Construction from a given time and key value */
 312.161 +	aiMeshKey(double time, const unsigned int value)
 312.162 +		:	mTime	(time)
 312.163 +		,	mValue	(value)
 312.164 +	{}
 312.165 +
 312.166 +	typedef unsigned int elem_type;
 312.167 +
 312.168 +	// Comparison operators. For use with std::find();
 312.169 +	bool operator == (const aiMeshKey& o) const {
 312.170 +		return o.mValue == this->mValue;
 312.171 +	}
 312.172 +	bool operator != (const aiMeshKey& o) const {
 312.173 +		return o.mValue != this->mValue;
 312.174 +	}
 312.175 +
 312.176 +	// Relational operators. For use with std::sort();
 312.177 +	bool operator < (const aiMeshKey& o) const {
 312.178 +		return mTime < o.mTime;
 312.179 +	}
 312.180 +	bool operator > (const aiMeshKey& o) const {
 312.181 +		return mTime > o.mTime;
 312.182 +	}
 312.183 +
 312.184 +#endif
 312.185 +};
 312.186 +
 312.187 +// ---------------------------------------------------------------------------
 312.188 +/** Defines how an animation channel behaves outside the defined time
 312.189 + *  range. This corresponds to aiNodeAnim::mPreState and 
 312.190 + *  aiNodeAnim::mPostState.*/
 312.191 +enum aiAnimBehaviour
 312.192 +{
 312.193 +	/** The value from the default node transformation is taken*/
 312.194 +	aiAnimBehaviour_DEFAULT  = 0x0,  
 312.195 +
 312.196 +	/** The nearest key value is used without interpolation */
 312.197 +	aiAnimBehaviour_CONSTANT = 0x1,
 312.198 +
 312.199 +	/** The value of the nearest two keys is linearly
 312.200 +	 *  extrapolated for the current time value.*/
 312.201 +	aiAnimBehaviour_LINEAR   = 0x2,
 312.202 +
 312.203 +	/** The animation is repeated.
 312.204 +	 *
 312.205 +	 *  If the animation key go from n to m and the current
 312.206 +	 *  time is t, use the value at (t-n) % (|m-n|).*/
 312.207 +	aiAnimBehaviour_REPEAT   = 0x3,
 312.208 +
 312.209 +
 312.210 +
 312.211 +	/** This value is not used, it is just here to force the
 312.212 +	 *  the compiler to map this enum to a 32 Bit integer  */
 312.213 +#ifndef SWIG
 312.214 +	_aiAnimBehaviour_Force32Bit = INT_MAX
 312.215 +#endif
 312.216 +};
 312.217 +
 312.218 +// ---------------------------------------------------------------------------
 312.219 +/** Describes the animation of a single node. The name specifies the 
 312.220 + *  bone/node which is affected by this animation channel. The keyframes
 312.221 + *  are given in three separate series of values, one each for position, 
 312.222 + *  rotation and scaling. The transformation matrix computed from these
 312.223 + *  values replaces the node's original transformation matrix at a
 312.224 + *  specific time.
 312.225 + *  This means all keys are absolute and not relative to the bone default pose.
 312.226 + *  The order in which the transformations are applied is
 312.227 + *  - as usual - scaling, rotation, translation.
 312.228 + *
 312.229 + *  @note All keys are returned in their correct, chronological order.
 312.230 + *  Duplicate keys don't pass the validation step. Most likely there
 312.231 + *  will be no negative time values, but they are not forbidden also ( so 
 312.232 + *  implementations need to cope with them! ) */
 312.233 +struct aiNodeAnim
 312.234 +{
 312.235 +	/** The name of the node affected by this animation. The node 
 312.236 +	 *  must exist and it must be unique.*/
 312.237 +	C_STRUCT aiString mNodeName;
 312.238 +
 312.239 +	/** The number of position keys */
 312.240 +	unsigned int mNumPositionKeys;
 312.241 +
 312.242 +	/** The position keys of this animation channel. Positions are 
 312.243 +	 * specified as 3D vector. The array is mNumPositionKeys in size.
 312.244 +	 *
 312.245 +	 * If there are position keys, there will also be at least one
 312.246 +	 * scaling and one rotation key.*/
 312.247 +	C_STRUCT aiVectorKey* mPositionKeys;
 312.248 +
 312.249 +	/** The number of rotation keys */
 312.250 +	unsigned int mNumRotationKeys;
 312.251 +
 312.252 +	/** The rotation keys of this animation channel. Rotations are 
 312.253 +	 *  given as quaternions,  which are 4D vectors. The array is 
 312.254 +	 *  mNumRotationKeys in size.
 312.255 +	 *
 312.256 +	 * If there are rotation keys, there will also be at least one
 312.257 +	 * scaling and one position key. */
 312.258 +	C_STRUCT aiQuatKey* mRotationKeys;
 312.259 +
 312.260 +
 312.261 +	/** The number of scaling keys */
 312.262 +	unsigned int mNumScalingKeys;
 312.263 +
 312.264 +	/** The scaling keys of this animation channel. Scalings are 
 312.265 +	 *  specified as 3D vector. The array is mNumScalingKeys in size.
 312.266 +	 *
 312.267 +	 * If there are scaling keys, there will also be at least one
 312.268 +	 * position and one rotation key.*/
 312.269 +	C_STRUCT aiVectorKey* mScalingKeys;
 312.270 +
 312.271 +
 312.272 +	/** Defines how the animation behaves before the first
 312.273 +	 *  key is encountered.
 312.274 +	 *
 312.275 +	 *  The default value is aiAnimBehaviour_DEFAULT (the original
 312.276 +	 *  transformation matrix of the affected node is used).*/
 312.277 +	C_ENUM aiAnimBehaviour mPreState;
 312.278 +
 312.279 +	/** Defines how the animation behaves after the last 
 312.280 +	 *  key was processed.
 312.281 +	 *
 312.282 +	 *  The default value is aiAnimBehaviour_DEFAULT (the original
 312.283 +	 *  transformation matrix of the affected node is taken).*/
 312.284 +	C_ENUM aiAnimBehaviour mPostState;
 312.285 +
 312.286 +#ifdef __cplusplus
 312.287 +	aiNodeAnim()
 312.288 +	{
 312.289 +		mNumPositionKeys = 0; mPositionKeys = NULL; 
 312.290 +		mNumRotationKeys = 0; mRotationKeys = NULL; 
 312.291 +		mNumScalingKeys  = 0; mScalingKeys  = NULL; 
 312.292 +
 312.293 +		mPreState = mPostState = aiAnimBehaviour_DEFAULT;
 312.294 +	}
 312.295 +
 312.296 +	~aiNodeAnim()
 312.297 +	{
 312.298 +		delete [] mPositionKeys;
 312.299 +		delete [] mRotationKeys;
 312.300 +		delete [] mScalingKeys;
 312.301 +	}
 312.302 +#endif // __cplusplus
 312.303 +};
 312.304 +
 312.305 +// ---------------------------------------------------------------------------
 312.306 +/** Describes vertex-based animations for a single mesh or a group of
 312.307 + *  meshes. Meshes carry the animation data for each frame in their
 312.308 + *  aiMesh::mAnimMeshes array. The purpose of aiMeshAnim is to 
 312.309 + *  define keyframes linking each mesh attachment to a particular
 312.310 + *  point in time. */
 312.311 +struct aiMeshAnim
 312.312 +{
 312.313 +	/** Name of the mesh to be animated. An empty string is not allowed,
 312.314 +	 *  animated meshes need to be named (not necessarily uniquely,
 312.315 +	 *  the name can basically serve as wildcard to select a group
 312.316 +	 *  of meshes with similar animation setup)*/
 312.317 +	C_STRUCT aiString mName;
 312.318 +
 312.319 +	/** Size of the #mKeys array. Must be 1, at least. */
 312.320 +	unsigned int mNumKeys;
 312.321 +
 312.322 +	/** Key frames of the animation. May not be NULL. */
 312.323 +	C_STRUCT aiMeshKey* mKeys;
 312.324 +
 312.325 +#ifdef __cplusplus
 312.326 +
 312.327 +	aiMeshAnim()
 312.328 +		: mNumKeys()
 312.329 +		, mKeys()
 312.330 +	{}
 312.331 +
 312.332 +	~aiMeshAnim()
 312.333 +	{
 312.334 +		delete[] mKeys;
 312.335 +	}
 312.336 +
 312.337 +#endif
 312.338 +};
 312.339 +
 312.340 +// ---------------------------------------------------------------------------
 312.341 +/** An animation consists of keyframe data for a number of nodes. For 
 312.342 + *  each node affected by the animation a separate series of data is given.*/
 312.343 +struct aiAnimation
 312.344 +{
 312.345 +	/** The name of the animation. If the modeling package this data was 
 312.346 +	 *  exported from does support only a single animation channel, this 
 312.347 +	 *  name is usually empty (length is zero). */
 312.348 +	C_STRUCT aiString mName;
 312.349 +
 312.350 +	/** Duration of the animation in ticks.  */
 312.351 +	double mDuration;
 312.352 +
 312.353 +	/** Ticks per second. 0 if not specified in the imported file */
 312.354 +	double mTicksPerSecond;
 312.355 +
 312.356 +	/** The number of bone animation channels. Each channel affects
 312.357 +	 *  a single node. */
 312.358 +	unsigned int mNumChannels;
 312.359 +
 312.360 +	/** The node animation channels. Each channel affects a single node. 
 312.361 +	 *  The array is mNumChannels in size. */
 312.362 +	C_STRUCT aiNodeAnim** mChannels;
 312.363 +
 312.364 +
 312.365 +	/** The number of mesh animation channels. Each channel affects
 312.366 +	 *  a single mesh and defines vertex-based animation. */
 312.367 +	unsigned int mNumMeshChannels;
 312.368 +
 312.369 +	/** The mesh animation channels. Each channel affects a single mesh. 
 312.370 +	 *  The array is mNumMeshChannels in size. */
 312.371 +	C_STRUCT aiMeshAnim** mMeshChannels;
 312.372 +
 312.373 +#ifdef __cplusplus
 312.374 +	aiAnimation()
 312.375 +		: mDuration(-1.)
 312.376 +		, mTicksPerSecond()
 312.377 +		, mNumChannels()
 312.378 +		, mChannels()
 312.379 +		, mNumMeshChannels()
 312.380 +		, mMeshChannels()
 312.381 +	{
 312.382 +	}
 312.383 +
 312.384 +	~aiAnimation()
 312.385 +	{
 312.386 +		// DO NOT REMOVE THIS ADDITIONAL CHECK
 312.387 +		if (mNumChannels && mChannels)	{
 312.388 +			for( unsigned int a = 0; a < mNumChannels; a++) {
 312.389 +				delete mChannels[a];
 312.390 +			}
 312.391 +
 312.392 +		delete [] mChannels;
 312.393 +		}
 312.394 +		if (mNumMeshChannels && mMeshChannels)	{
 312.395 +			for( unsigned int a = 0; a < mNumMeshChannels; a++) {
 312.396 +				delete mMeshChannels[a];
 312.397 +			}
 312.398 +
 312.399 +		delete [] mMeshChannels;
 312.400 +		}
 312.401 +	}
 312.402 +#endif // __cplusplus
 312.403 +};
 312.404 +
 312.405 +#ifdef __cplusplus
 312.406 +}
 312.407 +
 312.408 +
 312.409 +// some C++ utilities for inter- and extrapolation
 312.410 +namespace Assimp {
 312.411 +
 312.412 +// ---------------------------------------------------------------------------
 312.413 +/** @brief CPP-API: Utility class to simplify interpolations of various data types.
 312.414 + *
 312.415 + *  The type of interpolation is choosen automatically depending on the
 312.416 + *  types of the arguments. */
 312.417 +template <typename T>
 312.418 +struct Interpolator		
 312.419 +{	
 312.420 +	// ------------------------------------------------------------------
 312.421 +	/** @brief Get the result of the interpolation between a,b.
 312.422 +	 *
 312.423 +	 *  The interpolation algorithm depends on the type of the operands.
 312.424 +	 *  aiQuaternion's and aiQuatKey's SLERP, the rest does a simple
 312.425 +	 *  linear interpolation. */
 312.426 +	void operator () (T& out,const T& a, const T& b, float d) const {
 312.427 +		out = a + (b-a)*d;
 312.428 +	}
 312.429 +}; // ! Interpolator <T>
 312.430 +
 312.431 +//! @cond Never
 312.432 +
 312.433 +template <>
 312.434 +struct Interpolator	<aiQuaternion>	{	
 312.435 +	void operator () (aiQuaternion& out,const aiQuaternion& a, 
 312.436 +		const aiQuaternion& b, float d) const
 312.437 +	{
 312.438 +		aiQuaternion::Interpolate(out,a,b,d);
 312.439 +	}
 312.440 +}; // ! Interpolator <aiQuaternion>
 312.441 +
 312.442 +template <>
 312.443 +struct Interpolator	<unsigned int>	{	
 312.444 +	void operator () (unsigned int& out,unsigned int a, 
 312.445 +		unsigned int b, float d) const
 312.446 +	{
 312.447 +		out = d>0.5f ? b : a;
 312.448 +	}
 312.449 +}; // ! Interpolator <aiQuaternion>
 312.450 +
 312.451 +template <>
 312.452 +struct Interpolator	 <aiVectorKey>	{	
 312.453 +	void operator () (aiVector3D& out,const aiVectorKey& a,
 312.454 +		const aiVectorKey& b, float d) const	
 312.455 +	{
 312.456 +		Interpolator<aiVector3D> ipl;
 312.457 +		ipl(out,a.mValue,b.mValue,d);
 312.458 +	}
 312.459 +}; // ! Interpolator <aiVectorKey>
 312.460 +
 312.461 +template <>
 312.462 +struct Interpolator <aiQuatKey>		{
 312.463 +	void operator () (aiQuaternion& out, const aiQuatKey& a,
 312.464 +		const aiQuatKey& b, float d) const
 312.465 +	{
 312.466 +		Interpolator<aiQuaternion> ipl;
 312.467 +		ipl(out,a.mValue,b.mValue,d);
 312.468 +	}
 312.469 +}; // ! Interpolator <aiQuatKey>
 312.470 +
 312.471 +template <>
 312.472 +struct Interpolator <aiMeshKey>		{
 312.473 +	void operator () (unsigned int& out, const aiMeshKey& a,
 312.474 +		const aiMeshKey& b, float d) const
 312.475 +	{
 312.476 +		Interpolator<unsigned int> ipl;
 312.477 +		ipl(out,a.mValue,b.mValue,d);
 312.478 +	}
 312.479 +}; // ! Interpolator <aiQuatKey>
 312.480 +
 312.481 +//! @endcond
 312.482 +} //  ! end namespace Assimp
 312.483 +
 312.484 +
 312.485 +
 312.486 +#endif // __cplusplus
 312.487 +#endif // AI_ANIM_H_INC
   313.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   313.2 +++ b/libs/assimp/assimp/camera.h	Sat Feb 01 19:58:19 2014 +0200
   313.3 @@ -0,0 +1,223 @@
   313.4 +/*
   313.5 +---------------------------------------------------------------------------
   313.6 +Open Asset Import Library (assimp)
   313.7 +---------------------------------------------------------------------------
   313.8 +
   313.9 +Copyright (c) 2006-2012, assimp team
  313.10 +
  313.11 +All rights reserved.
  313.12 +
  313.13 +Redistribution and use of this software in source and binary forms, 
  313.14 +with or without modification, are permitted provided that the following 
  313.15 +conditions are met:
  313.16 +
  313.17 +* Redistributions of source code must retain the above
  313.18 +  copyright notice, this list of conditions and the
  313.19 +  following disclaimer.
  313.20 +
  313.21 +* Redistributions in binary form must reproduce the above
  313.22 +  copyright notice, this list of conditions and the
  313.23 +  following disclaimer in the documentation and/or other
  313.24 +  materials provided with the distribution.
  313.25 +
  313.26 +* Neither the name of the assimp team, nor the names of its
  313.27 +  contributors may be used to endorse or promote products
  313.28 +  derived from this software without specific prior
  313.29 +  written permission of the assimp team.
  313.30 +
  313.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  313.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  313.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  313.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  313.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  313.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  313.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  313.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  313.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  313.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  313.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  313.42 +---------------------------------------------------------------------------
  313.43 +*/
  313.44 +
  313.45 +/** @file camera.h
  313.46 + *  @brief Defines the aiCamera data structure
  313.47 + */
  313.48 +
  313.49 +#ifndef AI_CAMERA_H_INC
  313.50 +#define AI_CAMERA_H_INC
  313.51 +
  313.52 +#include "types.h"
  313.53 +
  313.54 +#ifdef __cplusplus
  313.55 +extern "C" {
  313.56 +#endif
  313.57 +
  313.58 +// ---------------------------------------------------------------------------
  313.59 +/** Helper structure to describe a virtual camera. 
  313.60 + *
  313.61 + * Cameras have a representation in the node graph and can be animated.
  313.62 + * An important aspect is that the camera itself is also part of the
  313.63 + * scenegraph. This means, any values such as the look-at vector are not 
  313.64 + * *absolute*, they're <b>relative</b> to the coordinate system defined
  313.65 + * by the node which corresponds to the camera. This allows for camera
  313.66 + * animations. For static cameras parameters like the 'look-at' or 'up' vectors
  313.67 + * are usually specified directly in aiCamera, but beware, they could also
  313.68 + * be encoded in the node transformation. The following (pseudo)code sample 
  313.69 + * shows how to do it: <br><br>
  313.70 + * @code
  313.71 + * // Get the camera matrix for a camera at a specific time
  313.72 + * // if the node hierarchy for the camera does not contain
  313.73 + * // at least one animated node this is a static computation
  313.74 + * get-camera-matrix (node sceneRoot, camera cam) : matrix
  313.75 + * {
  313.76 + *    node   cnd = find-node-for-camera(cam)
  313.77 + *    matrix cmt = identity()
  313.78 + *
  313.79 + *    // as usual - get the absolute camera transformation for this frame
  313.80 + *    for each node nd in hierarchy from sceneRoot to cnd
  313.81 + *      matrix cur
  313.82 + *      if (is-animated(nd))
  313.83 + *         cur = eval-animation(nd)
  313.84 + *      else cur = nd->mTransformation;
  313.85 + *      cmt = mult-matrices( cmt, cur )
  313.86 + *    end for
  313.87 + *
  313.88 + *    // now multiply with the camera's own local transform
  313.89 + *    cam = mult-matrices (cam, get-camera-matrix(cmt) )
  313.90 + * }
  313.91 + * @endcode
  313.92 + *
  313.93 + * @note some file formats (such as 3DS, ASE) export a "target point" -
  313.94 + * the point the camera is looking at (it can even be animated). Assimp
  313.95 + * writes the target point as a subnode of the camera's main node,
  313.96 + * called "<camName>.Target". However this is just additional information
  313.97 + * then the transformation tracks of the camera main node make the
  313.98 + * camera already look in the right direction.
  313.99 + * 
 313.100 +*/
 313.101 +struct aiCamera
 313.102 +{
 313.103 +	/** The name of the camera.
 313.104 +	 *
 313.105 +	 *  There must be a node in the scenegraph with the same name.
 313.106 +	 *  This node specifies the position of the camera in the scene
 313.107 +	 *  hierarchy and can be animated.
 313.108 +	 */
 313.109 +	C_STRUCT aiString mName;
 313.110 +
 313.111 +	/** Position of the camera relative to the coordinate space
 313.112 +	 *  defined by the corresponding node.
 313.113 +	 *
 313.114 +	 *  The default value is 0|0|0.
 313.115 +	 */
 313.116 +	C_STRUCT aiVector3D mPosition;
 313.117 +
 313.118 +
 313.119 +	/** 'Up' - vector of the camera coordinate system relative to
 313.120 +	 *  the coordinate space defined by the corresponding node.
 313.121 +	 *
 313.122 +	 *  The 'right' vector of the camera coordinate system is
 313.123 +	 *  the cross product of  the up and lookAt vectors.
 313.124 +	 *  The default value is 0|1|0. The vector
 313.125 +	 *  may be normalized, but it needn't.
 313.126 +	 */
 313.127 +	C_STRUCT aiVector3D mUp;
 313.128 +
 313.129 +
 313.130 +	/** 'LookAt' - vector of the camera coordinate system relative to
 313.131 +	 *  the coordinate space defined by the corresponding node.
 313.132 +	 *
 313.133 +	 *  This is the viewing direction of the user.
 313.134 +	 *  The default value is 0|0|1. The vector
 313.135 +	 *  may be normalized, but it needn't.
 313.136 +	 */
 313.137 +	C_STRUCT aiVector3D mLookAt;
 313.138 +
 313.139 +
 313.140 +	/** Half horizontal field of view angle, in radians. 
 313.141 +	 *
 313.142 +	 *  The field of view angle is the angle between the center
 313.143 +	 *  line of the screen and the left or right border.
 313.144 +	 *  The default value is 1/4PI.
 313.145 +	 */
 313.146 +	float mHorizontalFOV;
 313.147 +
 313.148 +	/** Distance of the near clipping plane from the camera.
 313.149 +	 *
 313.150 +	 * The value may not be 0.f (for arithmetic reasons to prevent
 313.151 +	 * a division through zero). The default value is 0.1f.
 313.152 +	 */
 313.153 +	float mClipPlaneNear;
 313.154 +
 313.155 +	/** Distance of the far clipping plane from the camera.
 313.156 +	 *
 313.157 +	 * The far clipping plane must, of course, be further away than the
 313.158 +	 * near clipping plane. The default value is 1000.f. The ratio
 313.159 +	 * between the near and the far plane should not be too
 313.160 +	 * large (between 1000-10000 should be ok) to avoid floating-point
 313.161 +	 * inaccuracies which could lead to z-fighting.
 313.162 +	 */
 313.163 +	float mClipPlaneFar;
 313.164 +
 313.165 +
 313.166 +	/** Screen aspect ratio.
 313.167 +	 *
 313.168 +	 * This is the ration between the width and the height of the
 313.169 +	 * screen. Typical values are 4/3, 1/2 or 1/1. This value is
 313.170 +	 * 0 if the aspect ratio is not defined in the source file.
 313.171 +	 * 0 is also the default value.
 313.172 +	 */
 313.173 +	float mAspect;
 313.174 +
 313.175 +#ifdef __cplusplus
 313.176 +
 313.177 +	aiCamera()
 313.178 +		: mUp				(0.f,1.f,0.f)
 313.179 +		, mLookAt			(0.f,0.f,1.f)
 313.180 +		, mHorizontalFOV	(0.25f * (float)AI_MATH_PI)
 313.181 +		, mClipPlaneNear	(0.1f)
 313.182 +		, mClipPlaneFar		(1000.f)
 313.183 +		, mAspect			(0.f)
 313.184 +	{}
 313.185 +
 313.186 +	/** @brief Get a *right-handed* camera matrix from me
 313.187 +	 *  @param out Camera matrix to be filled
 313.188 +	 */
 313.189 +	void GetCameraMatrix (aiMatrix4x4& out) const 
 313.190 +	{
 313.191 +		/** todo: test ... should work, but i'm not absolutely sure */
 313.192 +
 313.193 +		/** We don't know whether these vectors are already normalized ...*/
 313.194 +		aiVector3D zaxis = mLookAt;     zaxis.Normalize();
 313.195 +		aiVector3D yaxis = mUp;         yaxis.Normalize();
 313.196 +		aiVector3D xaxis = mUp^mLookAt; xaxis.Normalize();
 313.197 +
 313.198 +		out.a4 = -(xaxis * mPosition);
 313.199 +		out.b4 = -(yaxis * mPosition);
 313.200 +		out.c4 = -(zaxis * mPosition);
 313.201 +
 313.202 +		out.a1 = xaxis.x;
 313.203 +		out.a2 = xaxis.y;
 313.204 +		out.a3 = xaxis.z;
 313.205 +		
 313.206 +		out.b1 = yaxis.x;
 313.207 +		out.b2 = yaxis.y;
 313.208 +		out.b3 = yaxis.z;
 313.209 +
 313.210 +		out.c1 = zaxis.x;
 313.211 +		out.c2 = zaxis.y;
 313.212 +		out.c3 = zaxis.z;
 313.213 +
 313.214 +		out.d1 = out.d2 = out.d3 = 0.f;
 313.215 +		out.d4 = 1.f;
 313.216 +	}
 313.217 +
 313.218 +#endif
 313.219 +};
 313.220 +
 313.221 +
 313.222 +#ifdef __cplusplus
 313.223 +}
 313.224 +#endif
 313.225 +
 313.226 +#endif // AI_CAMERA_H_INC
   314.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   314.2 +++ b/libs/assimp/assimp/cexport.h	Sat Feb 01 19:58:19 2014 +0200
   314.3 @@ -0,0 +1,242 @@
   314.4 +/*
   314.5 +---------------------------------------------------------------------------
   314.6 +Open Asset Import Library (assimp)
   314.7 +---------------------------------------------------------------------------
   314.8 +
   314.9 +Copyright (c) 2006-2011, assimp team
  314.10 +
  314.11 +All rights reserved.
  314.12 +
  314.13 +Redistribution and use of this software in source and binary forms, 
  314.14 +with or without modification, are permitted provided that the following 
  314.15 +conditions are met:
  314.16 +
  314.17 +* Redistributions of source code must retain the above
  314.18 +copyright notice, this list of conditions and the
  314.19 +following disclaimer.
  314.20 +
  314.21 +* Redistributions in binary form must reproduce the above
  314.22 +copyright notice, this list of conditions and the
  314.23 +following disclaimer in the documentation and/or other
  314.24 +materials provided with the distribution.
  314.25 +
  314.26 +* Neither the name of the assimp team, nor the names of its
  314.27 +contributors may be used to endorse or promote products
  314.28 +derived from this software without specific prior
  314.29 +written permission of the assimp team.
  314.30 +
  314.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  314.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  314.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  314.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  314.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  314.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  314.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  314.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  314.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  314.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  314.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  314.42 +---------------------------------------------------------------------------
  314.43 +*/
  314.44 +
  314.45 +/** @file  cexport.h
  314.46 +*  @brief Defines the C-API for the Assimp export interface
  314.47 +*/
  314.48 +#ifndef AI_EXPORT_H_INC
  314.49 +#define AI_EXPORT_H_INC
  314.50 +
  314.51 +#ifndef ASSIMP_BUILD_NO_EXPORT
  314.52 +
  314.53 +#include "types.h"
  314.54 +
  314.55 +#ifdef __cplusplus
  314.56 +extern "C" {
  314.57 +#endif
  314.58 +
  314.59 +struct aiScene;  // aiScene.h
  314.60 +struct aiFileIO; // aiFileIO.h
  314.61 +
  314.62 +// --------------------------------------------------------------------------------
  314.63 +/** Describes an file format which Assimp can export to. Use #aiGetExportFormatCount() to 
  314.64 +* learn how many export formats the current Assimp build supports and #aiGetExportFormatDescription()
  314.65 +* to retrieve a description of an export format option.
  314.66 +*/
  314.67 +struct aiExportFormatDesc
  314.68 +{
  314.69 +	/// a short string ID to uniquely identify the export format. Use this ID string to 
  314.70 +	/// specify which file format you want to export to when calling #aiExportScene().
  314.71 +	/// Example: "dae" or "obj"
  314.72 +	const char* id; 
  314.73 +
  314.74 +	/// A short description of the file format to present to users. Useful if you want
  314.75 +	/// to allow the user to select an export format.
  314.76 +	const char* description;
  314.77 +
  314.78 +	/// Recommended file extension for the exported file in lower case. 
  314.79 +	const char* fileExtension;
  314.80 +};
  314.81 +
  314.82 +
  314.83 +// --------------------------------------------------------------------------------
  314.84 +/** Returns the number of export file formats available in the current Assimp build.
  314.85 + * Use aiGetExportFormatDescription() to retrieve infos of a specific export format.
  314.86 + */
  314.87 +ASSIMP_API size_t aiGetExportFormatCount(void);
  314.88 +
  314.89 +
  314.90 +// --------------------------------------------------------------------------------
  314.91 +/** Returns a description of the nth export file format. Use #aiGetExportFormatCount()
  314.92 + * to learn how many export formats are supported. 
  314.93 + * @param pIndex Index of the export format to retrieve information for. Valid range is
  314.94 + *    0 to #aiGetExportFormatCount()
  314.95 + * @return A description of that specific export format. NULL if pIndex is out of range.
  314.96 + */
  314.97 +ASSIMP_API const C_STRUCT aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex);
  314.98 +
  314.99 +
 314.100 +// --------------------------------------------------------------------------------
 314.101 +/** Create a modifyable copy of a scene.
 314.102 + *  This is useful to import files via Assimp, change their topology and 
 314.103 + *  export them again. Since the scene returned by the various importer functions
 314.104 + *  is const, a modifyable copy is needed.
 314.105 + *  @param pIn Valid scene to be copied
 314.106 + *  @param pOut Receives a modifyable copy of the scene.
 314.107 + */
 314.108 +ASSIMP_API void aiCopyScene(const C_STRUCT aiScene* pIn, 
 314.109 +	C_STRUCT aiScene** pOut);
 314.110 +
 314.111 +// --------------------------------------------------------------------------------
 314.112 +/** Exports the given scene to a chosen file format and writes the result file(s) to disk.
 314.113 +* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
 314.114 +*   The scene is expected to conform to Assimp's Importer output format as specified
 314.115 +*   in the @link data Data Structures Page @endlink. In short, this means the model data
 314.116 +*   should use a right-handed coordinate systems, face winding should be counter-clockwise
 314.117 +*   and the UV coordinate origin is assumed to be in the upper left. If your input data
 314.118 +*   uses different conventions, have a look at the last parameter.
 314.119 +* @param pFormatId ID string to specify to which format you want to export to. Use 
 314.120 +* aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available.
 314.121 +* @param pFileName Output file to write
 314.122 +* @param pIO custom IO implementation to be used. Use this if you use your own storage methods.
 314.123 +*   If none is supplied, a default implementation using standard file IO is used. Note that
 314.124 +*   #aiExportSceneToBlob is provided as convenience function to export to memory buffers.
 314.125 +* @param pPreprocessing Accepts any choice of the #aiPostProcessing enumerated
 314.126 +*   flags, but in reality only a subset of them makes sense here. Specifying
 314.127 +*   'preprocessing' flags is useful if the input scene does not conform to 
 314.128 +*   Assimp's default conventions as specified in the @link data Data Structures Page @endlink. 
 314.129 +*   In short, this means the geometry data should use a right-handed coordinate systems, face 
 314.130 +*   winding should be counter-clockwise and the UV coordinate origin is assumed to be in
 314.131 +*   the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and 
 314.132 +*   #aiProcess_FlipWindingOrder flags are used in the import side to allow users
 314.133 +*   to have those defaults automatically adapted to their conventions. Specifying those flags
 314.134 +*   for exporting has the opposite effect, respectively. Some other of the
 314.135 +*   #aiPostProcessSteps enumerated values may be useful as well, but you'll need
 314.136 +*   to try out what their effect on the exported file is. Many formats impose
 314.137 +*   their own restrictions on the structure of the geometry stored therein,
 314.138 +*   so some preprocessing may have little or no effect at all, or may be
 314.139 +*   redundant as exporters would apply them anyhow. A good example 
 314.140 +*   is triangulation - whilst you can enforce it by specifying
 314.141 +*   the #aiProcess_Triangulate flag, most export formats support only
 314.142 +*   triangulate data so they would run the step anyway.
 314.143 +* @return a status code indicating the result of the export
 314.144 +*/
 314.145 +ASSIMP_API aiReturn aiExportScene( const C_STRUCT aiScene* pScene, 
 314.146 +	const char* pFormatId, 
 314.147 +	const char* pFileName,  
 314.148 +	unsigned int pPreprocessing);
 314.149 +
 314.150 +
 314.151 +// --------------------------------------------------------------------------------
 314.152 +/** Exports the given scene to a chosen file format using custom IO logic supplied by you.
 314.153 +* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
 314.154 +* @param pFormatId ID string to specify to which format you want to export to. Use 
 314.155 +* aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available.
 314.156 +* @param pFileName Output file to write
 314.157 +* @param pIO custom IO implementation to be used. Use this if you use your own storage methods.
 314.158 +*   If none is supplied, a default implementation using standard file IO is used. Note that
 314.159 +*   #aiExportSceneToBlob is provided as convenience function to export to memory buffers.
 314.160 +* @param pPreprocessing Please see the documentation for #aiExportScene
 314.161 +* @return a status code indicating the result of the export
 314.162 +* @note Include <aiFileIO.h> for the definition of #aiFileIO.
 314.163 +*/
 314.164 +ASSIMP_API aiReturn aiExportSceneEx( const C_STRUCT aiScene* pScene, 
 314.165 +	const char* pFormatId, 
 314.166 +	const char* pFileName, 
 314.167 +	C_STRUCT aiFileIO* pIO,  
 314.168 +	unsigned int pPreprocessing );
 314.169 +
 314.170 +
 314.171 +// --------------------------------------------------------------------------------
 314.172 +/** Describes a blob of exported scene data. Use #aiExportSceneToBlob() to create a blob containing an
 314.173 +* exported scene. The memory referred by this structure is owned by Assimp. Use #aiReleaseExportedFile()
 314.174 +* to free its resources. Don't try to free the memory on your side - it will crash for most build configurations
 314.175 +* due to conflicting heaps.
 314.176 +*
 314.177 +* Blobs can be nested - each blob may reference another blob, which may in turn reference another blob and so on.
 314.178 +* This is used when exporters write more than one output file for a given #aiScene. See the remarks for
 314.179 +* #aiExportDataBlob::name for more information.
 314.180 +*/
 314.181 +struct aiExportDataBlob 
 314.182 +{
 314.183 +	/// Size of the data in bytes
 314.184 +	size_t size;
 314.185 +
 314.186 +	/// The data. 
 314.187 +	void* data;
 314.188 +
 314.189 +	/** Name of the blob. An empty string always
 314.190 +	    indicates the first (and primary) blob,
 314.191 +	    which contains the actual file data.
 314.192 +        Any other blobs are auxiliary files produced
 314.193 +	    by exporters (i.e. material files). Existence
 314.194 +	    of such files depends on the file format. Most
 314.195 +	    formats don't split assets across multiple files.
 314.196 +
 314.197 +		If used, blob names usually contain the file
 314.198 +		extension that should be used when writing 
 314.199 +		the data to disc.
 314.200 +	 */
 314.201 +	aiString name;
 314.202 +
 314.203 +	/** Pointer to the next blob in the chain or NULL if there is none. */
 314.204 +	aiExportDataBlob * next;
 314.205 +
 314.206 +#ifdef __cplusplus
 314.207 +	/// Default constructor
 314.208 +	aiExportDataBlob() { size = 0; data = next = NULL; }
 314.209 +	/// Releases the data
 314.210 +	~aiExportDataBlob() { delete [] static_cast<unsigned char*>( data ); delete next; }
 314.211 +
 314.212 +private:
 314.213 +	// no copying
 314.214 +	aiExportDataBlob(const aiExportDataBlob& );
 314.215 +	aiExportDataBlob& operator= (const aiExportDataBlob& );
 314.216 +#endif // __cplusplus
 314.217 +};
 314.218 +
 314.219 +// --------------------------------------------------------------------------------
 314.220 +/** Exports the given scene to a chosen file format. Returns the exported data as a binary blob which
 314.221 +* you can write into a file or something. When you're done with the data, use #aiReleaseExportBlob()
 314.222 +* to free the resources associated with the export. 
 314.223 +* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
 314.224 +* @param pFormatId ID string to specify to which format you want to export to. Use 
 314.225 +* #aiGetExportFormatCount() / #aiGetExportFormatDescription() to learn which export formats are available.
 314.226 +* @param pPreprocessing Please see the documentation for #aiExportScene
 314.227 +* @return the exported data or NULL in case of error
 314.228 +*/
 314.229 +ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const C_STRUCT aiScene* pScene, const char* pFormatId,  unsigned int pPreprocessing );
 314.230 +
 314.231 +
 314.232 +// --------------------------------------------------------------------------------
 314.233 +/** Releases the memory associated with the given exported data. Use this function to free a data blob
 314.234 +* returned by aiExportScene(). 
 314.235 +* @param pData the data blob returned by #aiExportSceneToBlob
 314.236 +*/
 314.237 +ASSIMP_API C_STRUCT void aiReleaseExportBlob( const C_STRUCT aiExportDataBlob* pData );
 314.238 +
 314.239 +#ifdef __cplusplus
 314.240 +}
 314.241 +#endif
 314.242 +
 314.243 +#endif // ASSIMP_BUILD_NO_EXPORT
 314.244 +#endif // AI_EXPORT_H_INC
 314.245 +
   315.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   315.2 +++ b/libs/assimp/assimp/cfileio.h	Sat Feb 01 19:58:19 2014 +0200
   315.3 @@ -0,0 +1,135 @@
   315.4 +/*
   315.5 +---------------------------------------------------------------------------
   315.6 +Open Asset Import Library (assimp)
   315.7 +---------------------------------------------------------------------------
   315.8 +
   315.9 +Copyright (c) 2006-2012, assimp team
  315.10 +
  315.11 +All rights reserved.
  315.12 +
  315.13 +Redistribution and use of this software in source and binary forms, 
  315.14 +with or without modification, are permitted provided that the following 
  315.15 +conditions are met:
  315.16 +
  315.17 +* Redistributions of source code must retain the above
  315.18 +  copyright notice, this list of conditions and the
  315.19 +  following disclaimer.
  315.20 +
  315.21 +* Redistributions in binary form must reproduce the above
  315.22 +  copyright notice, this list of conditions and the
  315.23 +  following disclaimer in the documentation and/or other
  315.24 +  materials provided with the distribution.
  315.25 +
  315.26 +* Neither the name of the assimp team, nor the names of its
  315.27 +  contributors may be used to endorse or promote products
  315.28 +  derived from this software without specific prior
  315.29 +  written permission of the assimp team.
  315.30 +
  315.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  315.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  315.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  315.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  315.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  315.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  315.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  315.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  315.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  315.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  315.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  315.42 +---------------------------------------------------------------------------
  315.43 +*/
  315.44 +
  315.45 +/** @file aiFileIO.h
  315.46 + *  @brief Defines generic C routines to access memory-mapped files
  315.47 + */
  315.48 +#ifndef AI_FILEIO_H_INC
  315.49 +#define AI_FILEIO_H_INC
  315.50 +
  315.51 +#include "types.h"
  315.52 +#ifdef __cplusplus
  315.53 +extern "C" {
  315.54 +#endif
  315.55 +struct aiFileIO;
  315.56 +struct aiFile;
  315.57 +
  315.58 +// aiFile callbacks
  315.59 +typedef size_t   (*aiFileWriteProc) (C_STRUCT aiFile*,   const char*, size_t, size_t);
  315.60 +typedef size_t   (*aiFileReadProc)  (C_STRUCT aiFile*,   char*, size_t,size_t);
  315.61 +typedef size_t   (*aiFileTellProc)  (C_STRUCT aiFile*);
  315.62 +typedef void     (*aiFileFlushProc) (C_STRUCT aiFile*);
  315.63 +typedef aiReturn (*aiFileSeek)(C_STRUCT aiFile*, size_t, aiOrigin);
  315.64 +
  315.65 +// aiFileIO callbacks
  315.66 +typedef aiFile* (*aiFileOpenProc)  (C_STRUCT aiFileIO*, const char*, const char*);
  315.67 +typedef void    (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*);
  315.68 +
  315.69 +// Represents user-defined data
  315.70 +typedef char* aiUserData;
  315.71 +
  315.72 +// ----------------------------------------------------------------------------------
  315.73 +/** @brief C-API: File system callbacks
  315.74 + *
  315.75 + *  Provided are functions to open and close files. Supply a custom structure to
  315.76 + *  the import function. If you don't, a default implementation is used. Use custom
  315.77 + *  file systems to enable reading from other sources, such as ZIPs 
  315.78 + *  or memory locations. */
  315.79 +struct aiFileIO
  315.80 +{
  315.81 +	/** Function used to open a new file
  315.82 +	 */
  315.83 +	aiFileOpenProc OpenProc;
  315.84 +
  315.85 +	/** Function used to close an existing file
  315.86 +	 */
  315.87 +	aiFileCloseProc CloseProc;
  315.88 +
  315.89 +	/** User-defined, opaque data */
  315.90 +	aiUserData UserData;
  315.91 +};
  315.92 +
  315.93 +// ----------------------------------------------------------------------------------
  315.94 +/** @brief C-API: File callbacks
  315.95 + *
  315.96 + *  Actually, it's a data structure to wrap a set of fXXXX (e.g fopen) 
  315.97 + *  replacement functions.
  315.98 + *
  315.99 + *  The default implementation of the functions utilizes the fXXX functions from 
 315.100 + *  the CRT. However, you can supply a custom implementation to Assimp by
 315.101 + *  delivering a custom aiFileIO. Use this to enable reading from other sources, 
 315.102 + *  such as ZIP archives or memory locations. */
 315.103 +struct aiFile
 315.104 +{
 315.105 +	/** Callback to read from a file */
 315.106 +	aiFileReadProc ReadProc;
 315.107 +
 315.108 +	/** Callback to write to a file */
 315.109 +	aiFileWriteProc WriteProc;
 315.110 +
 315.111 +	/** Callback to retrieve the current position of 
 315.112 +	 *  the file cursor (ftell())
 315.113 +	 */
 315.114 +	aiFileTellProc TellProc;
 315.115 +
 315.116 +	/** Callback to retrieve the size of the file, 
 315.117 +	 *  in bytes
 315.118 +	 */
 315.119 +	aiFileTellProc FileSizeProc;
 315.120 +
 315.121 +	/** Callback to set the current position
 315.122 +	 * of the file cursor (fseek())
 315.123 +	 */
 315.124 +	aiFileSeek SeekProc;
 315.125 +
 315.126 +	/** Callback to flush the file contents
 315.127 +	 */
 315.128 +	aiFileFlushProc FlushProc;
 315.129 +
 315.130 +	/** User-defined, opaque data
 315.131 +	 */
 315.132 +	aiUserData UserData;
 315.133 +};
 315.134 +
 315.135 +#ifdef __cplusplus
 315.136 +}
 315.137 +#endif
 315.138 +#endif // AI_FILEIO_H_INC
   316.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   316.2 +++ b/libs/assimp/assimp/cimport.h	Sat Feb 01 19:58:19 2014 +0200
   316.3 @@ -0,0 +1,495 @@
   316.4 +/*
   316.5 +---------------------------------------------------------------------------
   316.6 +Open Asset Import Library (assimp)
   316.7 +---------------------------------------------------------------------------
   316.8 +
   316.9 +Copyright (c) 2006-2012, assimp team
  316.10 +
  316.11 +All rights reserved.
  316.12 +
  316.13 +Redistribution and use of this software in source and binary forms, 
  316.14 +with or without modification, are permitted provided that the following 
  316.15 +conditions are met:
  316.16 +
  316.17 +* Redistributions of source code must retain the above
  316.18 +  copyright notice, this list of conditions and the
  316.19 +  following disclaimer.
  316.20 +
  316.21 +* Redistributions in binary form must reproduce the above
  316.22 +  copyright notice, this list of conditions and the
  316.23 +  following disclaimer in the documentation and/or other
  316.24 +  materials provided with the distribution.
  316.25 +
  316.26 +* Neither the name of the assimp team, nor the names of its
  316.27 +  contributors may be used to endorse or promote products
  316.28 +  derived from this software without specific prior
  316.29 +  written permission of the assimp team.
  316.30 +
  316.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  316.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  316.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  316.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  316.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  316.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  316.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  316.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  316.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  316.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  316.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  316.42 +---------------------------------------------------------------------------
  316.43 +*/
  316.44 +
  316.45 +/** @file  assimp.h
  316.46 + *  @brief Defines the C-API to the Open Asset Import Library. 
  316.47 + */
  316.48 +#ifndef AI_ASSIMP_H_INC
  316.49 +#define AI_ASSIMP_H_INC
  316.50 +#include "types.h"
  316.51 +
  316.52 +#ifdef __cplusplus
  316.53 +extern "C" {
  316.54 +#endif
  316.55 +
  316.56 +struct aiScene;  // aiScene.h
  316.57 +struct aiFileIO; // aiFileIO.h
  316.58 +typedef void (*aiLogStreamCallback)(const char* /* message */, char* /* user */);
  316.59 +
  316.60 +// --------------------------------------------------------------------------------
  316.61 +/** C-API: Represents a log stream. A log stream receives all log messages and
  316.62 + *  streams them _somewhere_.
  316.63 + *  @see aiGetPredefinedLogStream
  316.64 + *  @see aiAttachLogStream
  316.65 + *  @see aiDetachLogStream */
  316.66 +// --------------------------------------------------------------------------------
  316.67 +struct aiLogStream
  316.68 +{
  316.69 +	/** callback to be called */
  316.70 +	aiLogStreamCallback callback;
  316.71 +
  316.72 +	/** user data to be passed to the callback */
  316.73 +	char* user;
  316.74 +};
  316.75 +
  316.76 +
  316.77 +// --------------------------------------------------------------------------------
  316.78 +/** C-API: Represents an opaque set of settings to be used during importing.
  316.79 + *  @see aiCreatePropertyStore
  316.80 + *  @see aiReleasePropertyStore
  316.81 + *  @see aiImportFileExWithProperties
  316.82 + *  @see aiSetPropertyInteger
  316.83 + *  @see aiSetPropertyFloat
  316.84 + *  @see aiSetPropertyString
  316.85 + */
  316.86 +// --------------------------------------------------------------------------------
  316.87 +struct aiPropertyStore { char sentinel; };
  316.88 +
  316.89 +/** Our own C boolean type */
  316.90 +typedef int aiBool;
  316.91 +
  316.92 +#define AI_FALSE 0
  316.93 +#define AI_TRUE 1
  316.94 +
  316.95 +// --------------------------------------------------------------------------------
  316.96 +/** Reads the given file and returns its content.
  316.97 + * 
  316.98 + * If the call succeeds, the imported data is returned in an aiScene structure. 
  316.99 + * The data is intended to be read-only, it stays property of the ASSIMP 
 316.100 + * library and will be stable until aiReleaseImport() is called. After you're 
 316.101 + * done with it, call aiReleaseImport() to free the resources associated with 
 316.102 + * this file. If the import fails, NULL is returned instead. Call 
 316.103 + * aiGetErrorString() to retrieve a human-readable error text.
 316.104 + * @param pFile Path and filename of the file to be imported, 
 316.105 + *   expected to be a null-terminated c-string. NULL is not a valid value.
 316.106 + * @param pFlags Optional post processing steps to be executed after 
 316.107 + *   a successful import. Provide a bitwise combination of the 
 316.108 + *   #aiPostProcessSteps flags.
 316.109 + * @return Pointer to the imported data or NULL if the import failed. 
 316.110 + */
 316.111 +ASSIMP_API const C_STRUCT aiScene* aiImportFile( 
 316.112 +	const char* pFile, 
 316.113 +	unsigned int pFlags);
 316.114 +
 316.115 +// --------------------------------------------------------------------------------
 316.116 +/** Reads the given file using user-defined I/O functions and returns 
 316.117 + *   its content.
 316.118 + * 
 316.119 + * If the call succeeds, the imported data is returned in an aiScene structure. 
 316.120 + * The data is intended to be read-only, it stays property of the ASSIMP 
 316.121 + * library and will be stable until aiReleaseImport() is called. After you're 
 316.122 + * done with it, call aiReleaseImport() to free the resources associated with 
 316.123 + * this file. If the import fails, NULL is returned instead. Call 
 316.124 + * aiGetErrorString() to retrieve a human-readable error text.
 316.125 + * @param pFile Path and filename of the file to be imported, 
 316.126 + *   expected to be a null-terminated c-string. NULL is not a valid value.
 316.127 + * @param pFlags Optional post processing steps to be executed after 
 316.128 + *   a successful import. Provide a bitwise combination of the
 316.129 + *   #aiPostProcessSteps flags.
 316.130 + * @param pFS aiFileIO structure. Will be used to open the model file itself
 316.131 + *   and any other files the loader needs to open.  Pass NULL to use the default
 316.132 + *   implementation.
 316.133 + * @return Pointer to the imported data or NULL if the import failed.  
 316.134 + * @note Include <aiFileIO.h> for the definition of #aiFileIO.
 316.135 + */
 316.136 +ASSIMP_API const C_STRUCT aiScene* aiImportFileEx( 
 316.137 +	const char* pFile,
 316.138 +	unsigned int pFlags,
 316.139 +	C_STRUCT aiFileIO* pFS);
 316.140 +
 316.141 +// --------------------------------------------------------------------------------
 316.142 +/** Same as #aiImportFileEx, but adds an extra parameter containing importer settings.
 316.143 + *
 316.144 + * @param pProps #aiPropertyStore instance containing import settings. 
 316.145 + * @see aiImportFileEx
 316.146 + */
 316.147 +ASSIMP_API const C_STRUCT aiScene* aiImportFileExWithProperties( 
 316.148 +	const char* pFile,
 316.149 +	unsigned int pFlags,
 316.150 +	C_STRUCT aiFileIO* pFS,
 316.151 +	const C_STRUCT aiPropertyStore* pProps);
 316.152 +
 316.153 +// --------------------------------------------------------------------------------
 316.154 +/** Reads the given file from a given memory buffer,
 316.155 + * 
 316.156 + * If the call succeeds, the contents of the file are returned as a pointer to an
 316.157 + * aiScene object. The returned data is intended to be read-only, the importer keeps 
 316.158 + * ownership of the data and will destroy it upon destruction. If the import fails, 
 316.159 + * NULL is returned.
 316.160 + * A human-readable error description can be retrieved by calling aiGetErrorString(). 
 316.161 + * @param pBuffer Pointer to the file data
 316.162 + * @param pLength Length of pBuffer, in bytes
 316.163 + * @param pFlags Optional post processing steps to be executed after 
 316.164 + *   a successful import. Provide a bitwise combination of the 
 316.165 + *   #aiPostProcessSteps flags. If you wish to inspect the imported
 316.166 + *   scene first in order to fine-tune your post-processing setup,
 316.167 + *   consider to use #aiApplyPostProcessing().
 316.168 + * @param pHint An additional hint to the library. If this is a non empty string,
 316.169 + *   the library looks for a loader to support the file extension specified by pHint
 316.170 + *   and passes the file to the first matching loader. If this loader is unable to 
 316.171 + *   completely the request, the library continues and tries to determine the file
 316.172 + *   format on its own, a task that may or may not be successful. 
 316.173 + *   Check the return value, and you'll know ...
 316.174 + * @return A pointer to the imported data, NULL if the import failed.
 316.175 + *
 316.176 + * @note This is a straightforward way to decode models from memory
 316.177 + * buffers, but it doesn't handle model formats that spread their 
 316.178 + * data across multiple files or even directories. Examples include
 316.179 + * OBJ or MD3, which outsource parts of their material info into
 316.180 + * external scripts. If you need full functionality, provide
 316.181 + * a custom IOSystem to make Assimp find these files and use
 316.182 + * the regular aiImportFileEx()/aiImportFileExWithProperties() API.
 316.183 + */
 316.184 +ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemory( 
 316.185 +	const char* pBuffer,
 316.186 +	unsigned int pLength,
 316.187 +	unsigned int pFlags,
 316.188 +	const char* pHint);
 316.189 +
 316.190 +// --------------------------------------------------------------------------------
 316.191 +/** Same as #aiImportFileFromMemory, but adds an extra parameter containing importer settings.
 316.192 + *
 316.193 + * @param pProps #aiPropertyStore instance containing import settings. 
 316.194 + * @see aiImportFileFromMemory
 316.195 + */
 316.196 +ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemoryWithProperties( 
 316.197 +	const char* pBuffer,
 316.198 +	unsigned int pLength,
 316.199 +	unsigned int pFlags,
 316.200 +	const char* pHint,
 316.201 +	const C_STRUCT aiPropertyStore* pProps);
 316.202 +
 316.203 +// --------------------------------------------------------------------------------
 316.204 +/** Apply post-processing to an already-imported scene.
 316.205 + *
 316.206 + * This is strictly equivalent to calling #aiImportFile()/#aiImportFileEx with the
 316.207 + * same flags. However, you can use this separate function to inspect the imported 
 316.208 + * scene first to fine-tune your post-processing setup. 
 316.209 + * @param pScene Scene to work on.
 316.210 + * @param pFlags Provide a bitwise combination of the #aiPostProcessSteps flags.
 316.211 + * @return A pointer to the post-processed data. Post processing is done in-place,
 316.212 + *   meaning this is still the same #aiScene which you passed for pScene. However,
 316.213 + *   _if_ post-processing failed, the scene could now be NULL. That's quite a rare
 316.214 + *   case, post processing steps are not really designed to 'fail'. To be exact, 
 316.215 + *   the #aiProcess_ValidateDS flag is currently the only post processing step 
 316.216 + *   which can actually cause the scene to be reset to NULL.
 316.217 + */
 316.218 +ASSIMP_API const C_STRUCT aiScene* aiApplyPostProcessing(
 316.219 +	const C_STRUCT aiScene* pScene,
 316.220 +	unsigned int pFlags);
 316.221 +
 316.222 +// --------------------------------------------------------------------------------
 316.223 +/** Get one of the predefine log streams. This is the quick'n'easy solution to 
 316.224 + *  access Assimp's log system. Attaching a log stream can slightly reduce Assimp's
 316.225 + *  overall import performance. 
 316.226 + *
 316.227 + *  Usage is rather simple (this will stream the log to a file, named log.txt, and
 316.228 + *  the stdout stream of the process:
 316.229 + *  @code
 316.230 + *    struct aiLogStream c;
 316.231 + *    c = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"log.txt");
 316.232 + *    aiAttachLogStream(&c);
 316.233 + *    c = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
 316.234 + *    aiAttachLogStream(&c);
 316.235 + *  @endcode
 316.236 + *
 316.237 + *  @param pStreams One of the #aiDefaultLogStream enumerated values. 
 316.238 + *  @param file Solely for the #aiDefaultLogStream_FILE flag: specifies the file to write to.
 316.239 + *    Pass NULL for all other flags.
 316.240 + *  @return The log stream. callback is set to NULL if something went wrong.
 316.241 + */
 316.242 +ASSIMP_API C_STRUCT aiLogStream aiGetPredefinedLogStream(
 316.243 +	C_ENUM aiDefaultLogStream pStreams,
 316.244 +	const char* file);
 316.245 +
 316.246 +// --------------------------------------------------------------------------------
 316.247 +/** Attach a custom log stream to the libraries' logging system.
 316.248 + *
 316.249 + *  Attaching a log stream can slightly reduce Assimp's overall import
 316.250 + *  performance. Multiple log-streams can be attached. 
 316.251 + *  @param stream Describes the new log stream.
 316.252 + *  @note To ensure proepr destruction of the logging system, you need to manually
 316.253 + *    call aiDetachLogStream() on every single log stream you attach. 
 316.254 + *    Alternatively (for the lazy folks) #aiDetachAllLogStreams is provided.
 316.255 + */
 316.256 +ASSIMP_API void aiAttachLogStream(
 316.257 +	const C_STRUCT aiLogStream* stream);
 316.258 +
 316.259 +// --------------------------------------------------------------------------------
 316.260 +/** Enable verbose logging. Verbose logging includes debug-related stuff and
 316.261 + *  detailed import statistics. This can have severe impact on import performance
 316.262 + *  and memory consumption. However, it might be useful to find out why a file
 316.263 + *  didn't read correctly.
 316.264 + *  @param d AI_TRUE or AI_FALSE, your decision.
 316.265 + */
 316.266 +ASSIMP_API void aiEnableVerboseLogging(aiBool d);
 316.267 +
 316.268 +// --------------------------------------------------------------------------------
 316.269 +/** Detach a custom log stream from the libraries' logging system.
 316.270 + *
 316.271 + *  This is the counterpart of #aiAttachPredefinedLogStream. If you attached a stream,
 316.272 + *  don't forget to detach it again.
 316.273 + *  @param stream The log stream to be detached.
 316.274 + *  @return AI_SUCCESS if the log stream has been detached successfully.
 316.275 + *  @see aiDetachAllLogStreams
 316.276 + */
 316.277 +ASSIMP_API C_ENUM aiReturn aiDetachLogStream(
 316.278 +	const C_STRUCT aiLogStream* stream);
 316.279 +
 316.280 +// --------------------------------------------------------------------------------
 316.281 +/** Detach all active log streams from the libraries' logging system.
 316.282 + *  This ensures that the logging system is terminated properly and all
 316.283 + *  resources allocated by it are actually freed. If you attached a stream,
 316.284 + *  don't forget to detach it again.
 316.285 + *  @see aiAttachLogStream
 316.286 + *  @see aiDetachLogStream
 316.287 + */
 316.288 +ASSIMP_API void aiDetachAllLogStreams(void);
 316.289 +
 316.290 +// --------------------------------------------------------------------------------
 316.291 +/** Releases all resources associated with the given import process.
 316.292 + *
 316.293 + * Call this function after you're done with the imported data.
 316.294 + * @param pScene The imported data to release. NULL is a valid value.
 316.295 + */
 316.296 +ASSIMP_API void aiReleaseImport( 
 316.297 +	const C_STRUCT aiScene* pScene);
 316.298 +
 316.299 +// --------------------------------------------------------------------------------
 316.300 +/** Returns the error text of the last failed import process. 
 316.301 + *
 316.302 + * @return A textual description of the error that occurred at the last
 316.303 + * import process. NULL if there was no error. There can't be an error if you
 316.304 + * got a non-NULL #aiScene from #aiImportFile/#aiImportFileEx/#aiApplyPostProcessing.
 316.305 + */
 316.306 +ASSIMP_API const char* aiGetErrorString();
 316.307 +
 316.308 +// --------------------------------------------------------------------------------
 316.309 +/** Returns whether a given file extension is supported by ASSIMP
 316.310 + *
 316.311 + * @param szExtension Extension for which the function queries support for.
 316.312 + * Must include a leading dot '.'. Example: ".3ds", ".md3"
 316.313 + * @return AI_TRUE if the file extension is supported.
 316.314 + */
 316.315 +ASSIMP_API aiBool aiIsExtensionSupported(
 316.316 +	const char* szExtension);
 316.317 +
 316.318 +// --------------------------------------------------------------------------------
 316.319 +/** Get a list of all file extensions supported by ASSIMP.
 316.320 + *
 316.321 + * If a file extension is contained in the list this does, of course, not
 316.322 + * mean that ASSIMP is able to load all files with this extension.
 316.323 + * @param szOut String to receive the extension list.
 316.324 + * Format of the list: "*.3ds;*.obj;*.dae". NULL is not a valid parameter.
 316.325 + */
 316.326 +ASSIMP_API void aiGetExtensionList(
 316.327 +	C_STRUCT aiString* szOut);
 316.328 +
 316.329 +// --------------------------------------------------------------------------------
 316.330 +/** Get the approximated storage required by an imported asset
 316.331 + * @param pIn Input asset.
 316.332 + * @param in Data structure to be filled. 
 316.333 + */
 316.334 +ASSIMP_API void aiGetMemoryRequirements(
 316.335 +	const C_STRUCT aiScene* pIn,
 316.336 +	C_STRUCT aiMemoryInfo* in);
 316.337 +
 316.338 +
 316.339 +
 316.340 +// --------------------------------------------------------------------------------
 316.341 +/** Create an empty property store. Property stores are used to collect import
 316.342 + *  settings.
 316.343 + * @return New property store. Property stores need to be manually destroyed using
 316.344 + *   the #aiReleasePropertyStore API function.
 316.345 + */
 316.346 +ASSIMP_API C_STRUCT aiPropertyStore* aiCreatePropertyStore(void);
 316.347 +
 316.348 +// --------------------------------------------------------------------------------
 316.349 +/** Delete a property store.
 316.350 + * @param p Property store to be deleted.
 316.351 + */
 316.352 +ASSIMP_API void aiReleasePropertyStore(C_STRUCT aiPropertyStore* p);
 316.353 +
 316.354 +// --------------------------------------------------------------------------------
 316.355 +/** Set an integer property. 
 316.356 + *
 316.357 + *  This is the C-version of #Assimp::Importer::SetPropertyInteger(). In the C 
 316.358 + *  interface, properties are always shared by all imports. It is not possible to 
 316.359 + *  specify them per import.
 316.360 + *
 316.361 + * @param szName Name of the configuration property to be set. All supported 
 316.362 + *   public properties are defined in the config.h header file (#AI_CONFIG_XXX).
 316.363 + * @param value New value for the property
 316.364 + */
 316.365 +ASSIMP_API void aiSetImportPropertyInteger(
 316.366 +	C_STRUCT aiPropertyStore* store,
 316.367 +	const char* szName, 
 316.368 +	int value);
 316.369 +
 316.370 +// --------------------------------------------------------------------------------
 316.371 +/** Set a floating-point property. 
 316.372 + *
 316.373 + *  This is the C-version of #Assimp::Importer::SetPropertyFloat(). In the C 
 316.374 + *  interface, properties are always shared by all imports. It is not possible to 
 316.375 + *  specify them per import.
 316.376 + *
 316.377 + * @param szName Name of the configuration property to be set. All supported 
 316.378 + *   public properties are defined in the config.h header file (#AI_CONFIG_XXX).
 316.379 + * @param value New value for the property
 316.380 + */
 316.381 +ASSIMP_API void aiSetImportPropertyFloat(
 316.382 +	C_STRUCT aiPropertyStore* store,
 316.383 +	const char* szName,
 316.384 +	float value);
 316.385 +
 316.386 +// --------------------------------------------------------------------------------
 316.387 +/** Set a string property. 
 316.388 + *
 316.389 + *  This is the C-version of #Assimp::Importer::SetPropertyString(). In the C 
 316.390 + *  interface, properties are always shared by all imports. It is not possible to 
 316.391 + *  specify them per import.
 316.392 + *
 316.393 + * @param property store to modify. Use #aiCreatePropertyStore to obtain a store.
 316.394 + * @param szName Name of the configuration property to be set. All supported 
 316.395 + *   public properties are defined in the config.h header file (#AI_CONFIG_XXX).
 316.396 + * @param value New value for the property
 316.397 + */
 316.398 +ASSIMP_API void aiSetImportPropertyString(
 316.399 +	C_STRUCT aiPropertyStore* store,
 316.400 +	const char* szName,
 316.401 +	const C_STRUCT aiString* st);
 316.402 +
 316.403 +// --------------------------------------------------------------------------------
 316.404 +/** Construct a quaternion from a 3x3 rotation matrix.
 316.405 + *  @param quat Receives the output quaternion.
 316.406 + *  @param mat Matrix to 'quaternionize'.
 316.407 + *  @see aiQuaternion(const aiMatrix3x3& pRotMatrix)
 316.408 + */
 316.409 +ASSIMP_API void aiCreateQuaternionFromMatrix(
 316.410 +	C_STRUCT aiQuaternion* quat,
 316.411 +	const C_STRUCT aiMatrix3x3* mat);
 316.412 +
 316.413 +// --------------------------------------------------------------------------------
 316.414 +/** Decompose a transformation matrix into its rotational, translational and
 316.415 + *  scaling components.
 316.416 + * 
 316.417 + * @param mat Matrix to decompose
 316.418 + * @param scaling Receives the scaling component
 316.419 + * @param rotation Receives the rotational component
 316.420 + * @param position Receives the translational component.
 316.421 + * @see aiMatrix4x4::Decompose (aiVector3D&, aiQuaternion&, aiVector3D&) const;
 316.422 + */
 316.423 +ASSIMP_API void aiDecomposeMatrix(
 316.424 +	const C_STRUCT aiMatrix4x4* mat,
 316.425 +	C_STRUCT aiVector3D* scaling, 
 316.426 +	C_STRUCT aiQuaternion* rotation,
 316.427 +	C_STRUCT aiVector3D* position);
 316.428 +
 316.429 +// --------------------------------------------------------------------------------
 316.430 +/** Transpose a 4x4 matrix.
 316.431 + *  @param mat Pointer to the matrix to be transposed
 316.432 + */
 316.433 +ASSIMP_API void aiTransposeMatrix4(
 316.434 +	C_STRUCT aiMatrix4x4* mat);
 316.435 +
 316.436 +// --------------------------------------------------------------------------------
 316.437 +/** Transpose a 3x3 matrix.
 316.438 + *  @param mat Pointer to the matrix to be transposed
 316.439 + */
 316.440 +ASSIMP_API void aiTransposeMatrix3(
 316.441 +	C_STRUCT aiMatrix3x3* mat);
 316.442 +
 316.443 +// --------------------------------------------------------------------------------
 316.444 +/** Transform a vector by a 3x3 matrix
 316.445 + *  @param vec Vector to be transformed.
 316.446 + *  @param mat Matrix to transform the vector with.
 316.447 + */
 316.448 +ASSIMP_API void aiTransformVecByMatrix3(
 316.449 +	C_STRUCT aiVector3D* vec, 
 316.450 +	const C_STRUCT aiMatrix3x3* mat);
 316.451 +
 316.452 +// --------------------------------------------------------------------------------
 316.453 +/** Transform a vector by a 4x4 matrix
 316.454 + *  @param vec Vector to be transformed.
 316.455 + *  @param mat Matrix to transform the vector with.
 316.456 + */
 316.457 +ASSIMP_API void aiTransformVecByMatrix4(
 316.458 +	C_STRUCT aiVector3D* vec, 
 316.459 +	const C_STRUCT aiMatrix4x4* mat);
 316.460 +
 316.461 +// --------------------------------------------------------------------------------
 316.462 +/** Multiply two 4x4 matrices.
 316.463 + *  @param dst First factor, receives result.
 316.464 + *  @param src Matrix to be multiplied with 'dst'.
 316.465 + */
 316.466 +ASSIMP_API void aiMultiplyMatrix4(
 316.467 +	C_STRUCT aiMatrix4x4* dst, 
 316.468 +	const C_STRUCT aiMatrix4x4* src);
 316.469 +
 316.470 +// --------------------------------------------------------------------------------
 316.471 +/** Multiply two 3x3 matrices.
 316.472 + *  @param dst First factor, receives result.
 316.473 + *  @param src Matrix to be multiplied with 'dst'.
 316.474 + */
 316.475 +ASSIMP_API void aiMultiplyMatrix3(
 316.476 +	C_STRUCT aiMatrix3x3* dst, 
 316.477 +	const C_STRUCT aiMatrix3x3* src);
 316.478 +
 316.479 +// --------------------------------------------------------------------------------
 316.480 +/** Get a 3x3 identity matrix.
 316.481 + *  @param mat Matrix to receive its personal identity
 316.482 + */
 316.483 +ASSIMP_API void aiIdentityMatrix3(
 316.484 +	C_STRUCT aiMatrix3x3* mat);
 316.485 +
 316.486 +// --------------------------------------------------------------------------------
 316.487 +/** Get a 4x4 identity matrix.
 316.488 + *  @param mat Matrix to receive its personal identity
 316.489 + */
 316.490 +ASSIMP_API void aiIdentityMatrix4(
 316.491 +	C_STRUCT aiMatrix4x4* mat);
 316.492 +
 316.493 +
 316.494 +#ifdef __cplusplus
 316.495 +}
 316.496 +#endif
 316.497 +
 316.498 +#endif // AI_ASSIMP_H_INC
   317.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   317.2 +++ b/libs/assimp/assimp/color4.h	Sat Feb 01 19:58:19 2014 +0200
   317.3 @@ -0,0 +1,103 @@
   317.4 +/*
   317.5 +---------------------------------------------------------------------------
   317.6 +Open Asset Import Library (assimp)
   317.7 +---------------------------------------------------------------------------
   317.8 +
   317.9 +Copyright (c) 2006-2012, assimp team
  317.10 +
  317.11 +All rights reserved.
  317.12 +
  317.13 +Redistribution and use of this software in source and binary forms, 
  317.14 +with or without modification, are permitted provided that the following 
  317.15 +conditions are met:
  317.16 +
  317.17 +* Redistributions of source code must retain the above
  317.18 +  copyright notice, this list of conditions and the
  317.19 +  following disclaimer.
  317.20 +
  317.21 +* Redistributions in binary form must reproduce the above
  317.22 +  copyright notice, this list of conditions and the
  317.23 +  following disclaimer in the documentation and/or other
  317.24 +  materials provided with the distribution.
  317.25 +
  317.26 +* Neither the name of the assimp team, nor the names of its
  317.27 +  contributors may be used to endorse or promote products
  317.28 +  derived from this software without specific prior
  317.29 +  written permission of the assimp team.
  317.30 +
  317.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  317.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  317.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  317.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  317.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  317.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  317.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  317.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  317.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  317.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  317.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  317.42 +---------------------------------------------------------------------------
  317.43 +*/
  317.44 +/** @file aiColor4D.h
  317.45 + *  @brief RGBA color structure, including operators when compiling in C++
  317.46 + */
  317.47 +#ifndef AI_COLOR4D_H_INC
  317.48 +#define AI_COLOR4D_H_INC
  317.49 +
  317.50 +#include "./Compiler/pushpack1.h"
  317.51 +
  317.52 +#ifdef __cplusplus
  317.53 +
  317.54 +// ----------------------------------------------------------------------------------
  317.55 +/** Represents a color in Red-Green-Blue space including an 
  317.56 +*   alpha component. Color values range from 0 to 1. */
  317.57 +// ----------------------------------------------------------------------------------
  317.58 +template <typename TReal>
  317.59 +class aiColor4t
  317.60 +{
  317.61 +public:
  317.62 +	aiColor4t () : r(), g(), b(), a() {}
  317.63 +	aiColor4t (TReal _r, TReal _g, TReal _b, TReal _a) 
  317.64 +		: r(_r), g(_g), b(_b), a(_a) {}
  317.65 +	aiColor4t (TReal _r) : r(_r), g(_r), b(_r), a(_r) {}
  317.66 +	aiColor4t (const aiColor4t& o) 
  317.67 +		: r(o.r), g(o.g), b(o.b), a(o.a) {}
  317.68 +
  317.69 +public:
  317.70 +	// combined operators
  317.71 +	const aiColor4t& operator += (const aiColor4t& o);
  317.72 +	const aiColor4t& operator -= (const aiColor4t& o);
  317.73 +	const aiColor4t& operator *= (TReal f);
  317.74 +	const aiColor4t& operator /= (TReal f);
  317.75 +
  317.76 +public:
  317.77 +	// comparison
  317.78 +	bool operator == (const aiColor4t& other) const;
  317.79 +	bool operator != (const aiColor4t& other) const;
  317.80 +
  317.81 +	// color tuple access, rgba order
  317.82 +	inline TReal operator[](unsigned int i) const;
  317.83 +	inline TReal& operator[](unsigned int i);
  317.84 +
  317.85 +	/** check whether a color is (close to) black */
  317.86 +	inline bool IsBlack() const;
  317.87 +
  317.88 +public:
  317.89 +
  317.90 +	// Red, green, blue and alpha color values 
  317.91 +	TReal r, g, b, a;
  317.92 +} PACK_STRUCT;  // !struct aiColor4D
  317.93 +
  317.94 +typedef aiColor4t<float> aiColor4D;
  317.95 +
  317.96 +#else
  317.97 +
  317.98 +struct aiColor4D {
  317.99 +	float r, g, b, a;
 317.100 +} PACK_STRUCT;
 317.101 +
 317.102 +#endif // __cplusplus
 317.103 +
 317.104 +#include "./Compiler/poppack1.h"
 317.105 +
 317.106 +#endif // AI_COLOR4D_H_INC
   318.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   318.2 +++ b/libs/assimp/assimp/color4.inl	Sat Feb 01 19:58:19 2014 +0200
   318.3 @@ -0,0 +1,165 @@
   318.4 +/*
   318.5 +---------------------------------------------------------------------------
   318.6 +Open Asset Import Library (assimp)
   318.7 +---------------------------------------------------------------------------
   318.8 +
   318.9 +Copyright (c) 2006-2012, assimp team
  318.10 +
  318.11 +All rights reserved.
  318.12 +
  318.13 +Redistribution and use of this software in source and binary forms, 
  318.14 +with or without modification, are permitted provided that the following 
  318.15 +conditions are met:
  318.16 +
  318.17 +* Redistributions of source code must retain the above
  318.18 +  copyright notice, this list of conditions and the
  318.19 +  following disclaimer.
  318.20 +
  318.21 +* Redistributions in binary form must reproduce the above
  318.22 +  copyright notice, this list of conditions and the
  318.23 +  following disclaimer in the documentation and/or other
  318.24 +  materials provided with the distribution.
  318.25 +
  318.26 +* Neither the name of the assimp team, nor the names of its
  318.27 +  contributors may be used to endorse or promote products
  318.28 +  derived from this software without specific prior
  318.29 +  written permission of the assimp team.
  318.30 +
  318.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  318.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  318.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  318.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  318.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  318.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  318.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  318.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  318.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  318.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  318.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  318.42 +---------------------------------------------------------------------------
  318.43 +*/
  318.44 +
  318.45 +/** @file  aiColor4D.inl
  318.46 + *  @brief Inline implementation of aiColor4t<TReal> operators
  318.47 + */
  318.48 +#ifndef AI_COLOR4D_INL_INC
  318.49 +#define AI_COLOR4D_INL_INC
  318.50 +
  318.51 +#ifdef __cplusplus
  318.52 +#include "color4.h"
  318.53 +
  318.54 +// ------------------------------------------------------------------------------------------------
  318.55 +template <typename TReal>
  318.56 +AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator += (const aiColor4t<TReal>& o) {
  318.57 +	r += o.r; g += o.g; b += o.b; a += o.a; 
  318.58 +	return *this; 
  318.59 +}
  318.60 +// ------------------------------------------------------------------------------------------------
  318.61 +template <typename TReal>
  318.62 +AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator -= (const aiColor4t<TReal>& o) {
  318.63 +	r -= o.r; g -= o.g; b -= o.b; a -= o.a; 
  318.64 +	return *this;
  318.65 +}
  318.66 +// ------------------------------------------------------------------------------------------------
  318.67 +template <typename TReal>
  318.68 +AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator *= (TReal f) {
  318.69 +	r *= f; g *= f; b *= f; a *= f; 
  318.70 +	return *this; 
  318.71 +}
  318.72 +// ------------------------------------------------------------------------------------------------
  318.73 +template <typename TReal>
  318.74 +AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f) {
  318.75 +	r /= f; g /= f; b /= f; a /= f; 
  318.76 +	return *this; 
  318.77 +}
  318.78 +// ------------------------------------------------------------------------------------------------
  318.79 +template <typename TReal>
  318.80 +AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
  318.81 +	return *(&r + i);
  318.82 +}
  318.83 +// ------------------------------------------------------------------------------------------------
  318.84 +template <typename TReal>
  318.85 +AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
  318.86 +	return *(&r + i);
  318.87 +}
  318.88 +// ------------------------------------------------------------------------------------------------
  318.89 +template <typename TReal>
  318.90 +AI_FORCE_INLINE bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const {
  318.91 +	return r == other.r && g == other.g && b == other.b && a == other.a;
  318.92 +}
  318.93 +// ------------------------------------------------------------------------------------------------
  318.94 +template <typename TReal>
  318.95 +AI_FORCE_INLINE bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other) const {
  318.96 +	return r != other.r || g != other.g || b != other.b || a != other.a;
  318.97 +}
  318.98 +// ------------------------------------------------------------------------------------------------
  318.99 +template <typename TReal>
 318.100 +AI_FORCE_INLINE aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2)	{
 318.101 +	return aiColor4t<TReal>( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a);
 318.102 +}
 318.103 +// ------------------------------------------------------------------------------------------------
 318.104 +template <typename TReal>
 318.105 +AI_FORCE_INLINE aiColor4t<TReal> operator - (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2)	{
 318.106 +	return aiColor4t<TReal>( v1.r - v2.r, v1.g - v2.g, v1.b - v2.b, v1.a - v2.a);
 318.107 +}
 318.108 +// ------------------------------------------------------------------------------------------------
 318.109 +template <typename TReal>
 318.110 +AI_FORCE_INLINE aiColor4t<TReal> operator * (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2)	{
 318.111 +	return aiColor4t<TReal>( v1.r * v2.r, v1.g * v2.g, v1.b * v2.b, v1.a * v2.a);
 318.112 +}
 318.113 +// ------------------------------------------------------------------------------------------------
 318.114 +template <typename TReal>
 318.115 +AI_FORCE_INLINE aiColor4t<TReal> operator / (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2)	{
 318.116 +	return aiColor4t<TReal>( v1.r / v2.r, v1.g / v2.g, v1.b / v2.b, v1.a / v2.a);
 318.117 +}
 318.118 +// ------------------------------------------------------------------------------------------------
 318.119 +template <typename TReal>
 318.120 +AI_FORCE_INLINE aiColor4t<TReal> operator * ( TReal f, const aiColor4t<TReal>& v)	{
 318.121 +	return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
 318.122 +}
 318.123 +// ------------------------------------------------------------------------------------------------
 318.124 +template <typename TReal>
 318.125 +AI_FORCE_INLINE  aiColor4t<TReal> operator * ( const aiColor4t<TReal>& v, TReal f)	{
 318.126 +	return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
 318.127 +}
 318.128 +// ------------------------------------------------------------------------------------------------
 318.129 +template <typename TReal>
 318.130 +AI_FORCE_INLINE  aiColor4t<TReal> operator / ( const aiColor4t<TReal>& v, TReal f)	{
 318.131 +	return v * (1/f);
 318.132 +}
 318.133 +// ------------------------------------------------------------------------------------------------
 318.134 +template <typename TReal>
 318.135 +AI_FORCE_INLINE  aiColor4t<TReal> operator / ( TReal f,const aiColor4t<TReal>& v)	{
 318.136 +	return aiColor4t<TReal>(f,f,f,f)/v;
 318.137 +}
 318.138 +// ------------------------------------------------------------------------------------------------
 318.139 +template <typename TReal>
 318.140 +AI_FORCE_INLINE  aiColor4t<TReal> operator + ( const aiColor4t<TReal>& v, TReal f)	{
 318.141 +	return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
 318.142 +}
 318.143 +// ------------------------------------------------------------------------------------------------
 318.144 +template <typename TReal>
 318.145 +AI_FORCE_INLINE  aiColor4t<TReal> operator - ( const aiColor4t<TReal>& v, TReal f)	{
 318.146 +	return aiColor4t<TReal>( v.r-f, v.g-f, v.b-f, v.a-f);
 318.147 +}
 318.148 +// ------------------------------------------------------------------------------------------------
 318.149 +template <typename TReal>
 318.150 +AI_FORCE_INLINE  aiColor4t<TReal> operator + ( TReal f, const aiColor4t<TReal>& v)	{
 318.151 +	return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
 318.152 +}
 318.153 +// ------------------------------------------------------------------------------------------------
 318.154 +template <typename TReal>
 318.155 +AI_FORCE_INLINE  aiColor4t<TReal> operator - ( TReal f, const aiColor4t<TReal>& v)	{
 318.156 +	return aiColor4t<TReal>( f-v.r, f-v.g, f-v.b, f-v.a);
 318.157 +}
 318.158 +
 318.159 +// ------------------------------------------------------------------------------------------------
 318.160 +template <typename TReal>
 318.161 +inline bool aiColor4t<TReal> :: IsBlack() const	{
 318.162 +	// The alpha component doesn't care here. black is black.
 318.163 +	static const TReal epsilon = 10e-3f;
 318.164 +	return fabs( r ) < epsilon && fabs( g ) < epsilon && fabs( b ) < epsilon;
 318.165 +}
 318.166 +
 318.167 +#endif // __cplusplus
 318.168 +#endif // AI_VECTOR3D_INL_INC
   319.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   319.2 +++ b/libs/assimp/assimp/config.h	Sat Feb 01 19:58:19 2014 +0200
   319.3 @@ -0,0 +1,844 @@
   319.4 +/*
   319.5 +---------------------------------------------------------------------------
   319.6 +Open Asset Import Library (assimp)
   319.7 +---------------------------------------------------------------------------
   319.8 +
   319.9 +Copyright (c) 2006-2012, assimp team
  319.10 +
  319.11 +All rights reserved.
  319.12 +
  319.13 +Redistribution and use of this software in source and binary forms, 
  319.14 +with or without modification, are permitted provided that the following 
  319.15 +conditions are met:
  319.16 +
  319.17 +* Redistributions of source code must retain the above
  319.18 +  copyright notice, this list of conditions and the
  319.19 +  following disclaimer.
  319.20 +
  319.21 +* Redistributions in binary form must reproduce the above
  319.22 +  copyright notice, this list of conditions and the
  319.23 +  following disclaimer in the documentation and/or other
  319.24 +  materials provided with the distribution.
  319.25 +
  319.26 +* Neither the name of the assimp team, nor the names of its
  319.27 +  contributors may be used to endorse or promote products
  319.28 +  derived from this software without specific prior
  319.29 +  written permission of the assimp team.
  319.30 +
  319.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  319.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  319.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  319.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  319.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  319.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  319.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  319.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  319.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  319.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  319.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  319.42 +---------------------------------------------------------------------------
  319.43 +*/
  319.44 +
  319.45 +/** @file config.h
  319.46 + *  @brief Defines constants for configurable properties for the library
  319.47 + *
  319.48 + *  Typically these properties are set via 
  319.49 + *  #Assimp::Importer::SetPropertyFloat,
  319.50 + *  #Assimp::Importer::SetPropertyInteger or
  319.51 + *  #Assimp::Importer::SetPropertyString, 
  319.52 + *  depending on the data type of a property. All properties have a 
  319.53 + *  default value. See the doc for the mentioned methods for more details.
  319.54 + *
  319.55 + *  <br><br>
  319.56 + *  The corresponding functions for use with the plain-c API are:
  319.57 + *  #aiSetImportPropertyInteger,
  319.58 + *  #aiSetImportPropertyFloat,
  319.59 + *  #aiSetImportPropertyString
  319.60 + */
  319.61 +#ifndef INCLUDED_AI_CONFIG_H
  319.62 +#define INCLUDED_AI_CONFIG_H
  319.63 +
  319.64 +
  319.65 +// ###########################################################################
  319.66 +// LIBRARY SETTINGS
  319.67 +// General, global settings
  319.68 +// ###########################################################################
  319.69 +
  319.70 +// ---------------------------------------------------------------------------
  319.71 +/** @brief Enables time measurements.
  319.72 + *
  319.73 + *  If enabled, measures the time needed for each part of the loading
  319.74 + *  process (i.e. IO time, importing, postprocessing, ..) and dumps
  319.75 + *  these timings to the DefaultLogger. See the @link perf Performance
  319.76 + *  Page@endlink for more information on this topic.
  319.77 + * 
  319.78 + * Property type: bool. Default value: false.
  319.79 + */
  319.80 +#define AI_CONFIG_GLOB_MEASURE_TIME  \
  319.81 +	"GLOB_MEASURE_TIME"
  319.82 +
  319.83 +
  319.84 +// ---------------------------------------------------------------------------
  319.85 +/** @brief Global setting to disable generation of skeleton dummy meshes
  319.86 + *
  319.87 + * Skeleton dummy meshes are generated as a visualization aid in cases which
  319.88 + * the input data contains no geometry, but only animation data.
  319.89 + * Property data type: bool. Default value: false
  319.90 + */
  319.91 +// ---------------------------------------------------------------------------
  319.92 +#define AI_CONFIG_IMPORT_NO_SKELETON_MESHES \
  319.93 +	"IMPORT_NO_SKELETON_MESHES"
  319.94 +
  319.95 +
  319.96 +
  319.97 +# if 0 // not implemented yet
  319.98 +// ---------------------------------------------------------------------------
  319.99 +/** @brief Set Assimp's multithreading policy.
 319.100 + *
 319.101 + * This setting is ignored if Assimp was built without boost.thread
 319.102 + * support (ASSIMP_BUILD_NO_THREADING, which is implied by ASSIMP_BUILD_BOOST_WORKAROUND).
 319.103 + * Possible values are: -1 to let Assimp decide what to do, 0 to disable
 319.104 + * multithreading entirely and any number larger than 0 to force a specific
 319.105 + * number of threads. Assimp is always free to ignore this settings, which is
 319.106 + * merely a hint. Usually, the default value (-1) will be fine. However, if
 319.107 + * Assimp is used concurrently from multiple user threads, it might be useful
 319.108 + * to limit each Importer instance to a specific number of cores.
 319.109 + *
 319.110 + * For more information, see the @link threading Threading page@endlink.
 319.111 + * Property type: int, default value: -1.
 319.112 + */
 319.113 +#define AI_CONFIG_GLOB_MULTITHREADING  \
 319.114 +	"GLOB_MULTITHREADING"
 319.115 +#endif
 319.116 +
 319.117 +// ###########################################################################
 319.118 +// POST PROCESSING SETTINGS
 319.119 +// Various stuff to fine-tune the behavior of a specific post processing step.
 319.120 +// ###########################################################################
 319.121 +
 319.122 +
 319.123 +// ---------------------------------------------------------------------------
 319.124 +/** @brief Maximum bone count per mesh for the SplitbyBoneCount step.
 319.125 + *
 319.126 + * Meshes are split until the maximum number of bones is reached. The default
 319.127 + * value is AI_SBBC_DEFAULT_MAX_BONES, which may be altered at
 319.128 + * compile-time.
 319.129 + * Property data type: integer.
 319.130 + */
 319.131 +// ---------------------------------------------------------------------------
 319.132 +#define AI_CONFIG_PP_SBBC_MAX_BONES \
 319.133 +	"PP_SBBC_MAX_BONES"
 319.134 +
 319.135 +
 319.136 +// default limit for bone count 
 319.137 +#if (!defined AI_SBBC_DEFAULT_MAX_BONES)
 319.138 +#	define AI_SBBC_DEFAULT_MAX_BONES		60
 319.139 +#endif
 319.140 +
 319.141 +
 319.142 +// ---------------------------------------------------------------------------
 319.143 +/** @brief  Specifies the maximum angle that may be between two vertex tangents
 319.144 + *         that their tangents and bi-tangents are smoothed.
 319.145 + *
 319.146 + * This applies to the CalcTangentSpace-Step. The angle is specified
 319.147 + * in degrees. The maximum value is 175.
 319.148 + * Property type: float. Default value: 45 degrees
 319.149 + */
 319.150 +#define AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE \
 319.151 +	"PP_CT_MAX_SMOOTHING_ANGLE"
 319.152 +
 319.153 +// ---------------------------------------------------------------------------
 319.154 +/** @brief Source UV channel for tangent space computation.
 319.155 + *
 319.156 + * The specified channel must exist or an error will be raised. 
 319.157 + * Property type: integer. Default value: 0
 319.158 + */
 319.159 +// ---------------------------------------------------------------------------
 319.160 +#define AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX \
 319.161 +	"PP_CT_TEXTURE_CHANNEL_INDEX"
 319.162 +
 319.163 +// ---------------------------------------------------------------------------
 319.164 +/** @brief  Specifies the maximum angle that may be between two face normals
 319.165 + *          at the same vertex position that their are smoothed together.
 319.166 + *
 319.167 + * Sometimes referred to as 'crease angle'.
 319.168 + * This applies to the GenSmoothNormals-Step. The angle is specified
 319.169 + * in degrees, so 180 is PI. The default value is 175 degrees (all vertex 
 319.170 + * normals are smoothed). The maximum value is 175, too. Property type: float. 
 319.171 + * Warning: setting this option may cause a severe loss of performance. The
 319.172 + * performance is unaffected if the #AI_CONFIG_FAVOUR_SPEED flag is set but
 319.173 + * the output quality may be reduced.
 319.174 + */
 319.175 +#define AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE \
 319.176 +	"PP_GSN_MAX_SMOOTHING_ANGLE"
 319.177 +
 319.178 +
 319.179 +// ---------------------------------------------------------------------------
 319.180 +/** @brief Sets the colormap (= palette) to be used to decode embedded
 319.181 + *         textures in MDL (Quake or 3DGS) files.
 319.182 + *
 319.183 + * This must be a valid path to a file. The file is 768 (256*3) bytes
 319.184 + * large and contains RGB triplets for each of the 256 palette entries.
 319.185 + * The default value is colormap.lmp. If the file is not found,
 319.186 + * a default palette (from Quake 1) is used. 
 319.187 + * Property type: string.
 319.188 + */
 319.189 +#define AI_CONFIG_IMPORT_MDL_COLORMAP		\
 319.190 +	"IMPORT_MDL_COLORMAP"
 319.191 +
 319.192 +// ---------------------------------------------------------------------------
 319.193 +/** @brief Configures the #aiProcess_RemoveRedundantMaterials step to 
 319.194 + *  keep materials matching a name in a given list.
 319.195 + *
 319.196 + * This is a list of 1 to n strings, ' ' serves as delimiter character.
 319.197 + * Identifiers containing whitespaces must be enclosed in *single*
 319.198 + * quotation marks. For example:<tt>
 319.199 + * "keep-me and_me_to anotherMaterialToBeKept \'name with whitespace\'"</tt>.
 319.200 + * If a material matches on of these names, it will not be modified or
 319.201 + * removed by the postprocessing step nor will other materials be replaced
 319.202 + * by a reference to it. <br> 
 319.203 + * This option might be useful if you are using some magic material names
 319.204 + * to pass additional semantics through the content pipeline. This ensures
 319.205 + * they won't be optimized away, but a general optimization is still 
 319.206 + * performed for materials not contained in the list.
 319.207 + * Property type: String. Default value: n/a
 319.208 + * @note Linefeeds, tabs or carriage returns are treated as whitespace.
 319.209 + *   Material names are case sensitive.
 319.210 + */
 319.211 +#define AI_CONFIG_PP_RRM_EXCLUDE_LIST	\
 319.212 +	"PP_RRM_EXCLUDE_LIST"
 319.213 +
 319.214 +// ---------------------------------------------------------------------------
 319.215 +/** @brief Configures the #aiProcess_PretransformVertices step to
 319.216 + *  keep the scene hierarchy. Meshes are moved to worldspace, but
 319.217 + *  no optimization is performed (read: meshes with equal materials are not 
 319.218 + *  joined. The total number of meshes won't change).
 319.219 + *
 319.220 + * This option could be of use for you if the scene hierarchy contains
 319.221 + * important additional information which you intend to parse. 
 319.222 + * For rendering, you can still render all meshes in the scene without
 319.223 + * any transformations.
 319.224 + * Property type: bool. Default value: false.
 319.225 + */
 319.226 +#define AI_CONFIG_PP_PTV_KEEP_HIERARCHY		\
 319.227 +	"PP_PTV_KEEP_HIERARCHY"
 319.228 +
 319.229 +// ---------------------------------------------------------------------------
 319.230 +/** @brief Configures the #aiProcess_PretransformVertices step to normalize
 319.231 + *  all vertex components into the [-1,1] range. That is, a bounding box
 319.232 + *  for the whole scene is computed, the maximum component is taken and all
 319.233 + *  meshes are scaled appropriately (uniformly of course!).
 319.234 + *  This might be useful if you don't know the spatial dimension of the input 
 319.235 + *  data*/
 319.236 +#define AI_CONFIG_PP_PTV_NORMALIZE	\
 319.237 +	"PP_PTV_NORMALIZE"
 319.238 +
 319.239 +// ---------------------------------------------------------------------------
 319.240 +/** @brief Configures the #aiProcess_FindDegenerates step to
 319.241 + *  remove degenerated primitives from the import - immediately.
 319.242 + *
 319.243 + * The default behaviour converts degenerated triangles to lines and
 319.244 + * degenerated lines to points. See the documentation to the
 319.245 + * #aiProcess_FindDegenerates step for a detailed example of the various ways
 319.246 + * to get rid of these lines and points if you don't want them.
 319.247 + * Property type: bool. Default value: false.
 319.248 + */
 319.249 +#define AI_CONFIG_PP_FD_REMOVE \
 319.250 +	"PP_FD_REMOVE"
 319.251 +
 319.252 +// ---------------------------------------------------------------------------
 319.253 +/** @brief Configures the #aiProcess_OptimizeGraph step to preserve nodes
 319.254 + * matching a name in a given list.
 319.255 + *
 319.256 + * This is a list of 1 to n strings, ' ' serves as delimiter character.
 319.257 + * Identifiers containing whitespaces must be enclosed in *single*
 319.258 + * quotation marks. For example:<tt>
 319.259 + * "keep-me and_me_to anotherNodeToBeKept \'name with whitespace\'"</tt>.
 319.260 + * If a node matches on of these names, it will not be modified or
 319.261 + * removed by the postprocessing step.<br> 
 319.262 + * This option might be useful if you are using some magic node names
 319.263 + * to pass additional semantics through the content pipeline. This ensures
 319.264 + * they won't be optimized away, but a general optimization is still 
 319.265 + * performed for nodes not contained in the list.
 319.266 + * Property type: String. Default value: n/a
 319.267 + * @note Linefeeds, tabs or carriage returns are treated as whitespace.
 319.268 + *   Node names are case sensitive.
 319.269 + */
 319.270 +#define AI_CONFIG_PP_OG_EXCLUDE_LIST	\
 319.271 +	"PP_OG_EXCLUDE_LIST"
 319.272 +
 319.273 +// ---------------------------------------------------------------------------
 319.274 +/** @brief  Set the maximum number of triangles in a mesh.
 319.275 + *
 319.276 + * This is used by the "SplitLargeMeshes" PostProcess-Step to determine
 319.277 + * whether a mesh must be split or not.
 319.278 + * @note The default value is AI_SLM_DEFAULT_MAX_TRIANGLES
 319.279 + * Property type: integer.
 319.280 + */
 319.281 +#define AI_CONFIG_PP_SLM_TRIANGLE_LIMIT	\
 319.282 +	"PP_SLM_TRIANGLE_LIMIT"
 319.283 +
 319.284 +// default value for AI_CONFIG_PP_SLM_TRIANGLE_LIMIT
 319.285 +#if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES)
 319.286 +#	define AI_SLM_DEFAULT_MAX_TRIANGLES		1000000
 319.287 +#endif
 319.288 +
 319.289 +// ---------------------------------------------------------------------------
 319.290 +/** @brief  Set the maximum number of vertices in a mesh.
 319.291 + *
 319.292 + * This is used by the "SplitLargeMeshes" PostProcess-Step to determine
 319.293 + * whether a mesh must be split or not.
 319.294 + * @note The default value is AI_SLM_DEFAULT_MAX_VERTICES
 319.295 + * Property type: integer. 
 319.296 + */
 319.297 +#define AI_CONFIG_PP_SLM_VERTEX_LIMIT \
 319.298 +	"PP_SLM_VERTEX_LIMIT"
 319.299 +
 319.300 +// default value for AI_CONFIG_PP_SLM_VERTEX_LIMIT
 319.301 +#if (!defined AI_SLM_DEFAULT_MAX_VERTICES)
 319.302 +#	define AI_SLM_DEFAULT_MAX_VERTICES		1000000
 319.303 +#endif
 319.304 +
 319.305 +// ---------------------------------------------------------------------------
 319.306 +/** @brief Set the maximum number of bones affecting a single vertex
 319.307 + *
 319.308 + * This is used by the #aiProcess_LimitBoneWeights PostProcess-Step.
 319.309 + * @note The default value is AI_LBW_MAX_WEIGHTS
 319.310 + * Property type: integer.*/
 319.311 +#define AI_CONFIG_PP_LBW_MAX_WEIGHTS	\
 319.312 +	"PP_LBW_MAX_WEIGHTS"
 319.313 +
 319.314 +// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS
 319.315 +#if (!defined AI_LMW_MAX_WEIGHTS)
 319.316 +#	define AI_LMW_MAX_WEIGHTS	0x4
 319.317 +#endif // !! AI_LMW_MAX_WEIGHTS
 319.318 +
 319.319 +// ---------------------------------------------------------------------------
 319.320 +/** @brief Lower the deboning threshold in order to remove more bones.
 319.321 + *
 319.322 + * This is used by the #aiProcess_Debone PostProcess-Step.
 319.323 + * @note The default value is AI_DEBONE_THRESHOLD
 319.324 + * Property type: float.*/
 319.325 +#define AI_CONFIG_PP_DB_THRESHOLD \
 319.326 +	"PP_DB_THRESHOLD"
 319.327 +
 319.328 +// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS
 319.329 +#if (!defined AI_DEBONE_THRESHOLD)
 319.330 +#	define AI_DEBONE_THRESHOLD	1.0f
 319.331 +#endif // !! AI_DEBONE_THRESHOLD
 319.332 +
 319.333 +// ---------------------------------------------------------------------------
 319.334 +/** @brief Require all bones qualify for deboning before removing any
 319.335 + *
 319.336 + * This is used by the #aiProcess_Debone PostProcess-Step.
 319.337 + * @note The default value is 0
 319.338 + * Property type: bool.*/
 319.339 +#define AI_CONFIG_PP_DB_ALL_OR_NONE \
 319.340 +	"PP_DB_ALL_OR_NONE"
 319.341 +
 319.342 +/** @brief Default value for the #AI_CONFIG_PP_ICL_PTCACHE_SIZE property
 319.343 + */
 319.344 +#ifndef PP_ICL_PTCACHE_SIZE
 319.345 +#	define PP_ICL_PTCACHE_SIZE 12
 319.346 +#endif
 319.347 +
 319.348 +// ---------------------------------------------------------------------------
 319.349 +/** @brief Set the size of the post-transform vertex cache to optimize the
 319.350 + *    vertices for. This configures the #aiProcess_ImproveCacheLocality step.
 319.351 + *
 319.352 + * The size is given in vertices. Of course you can't know how the vertex
 319.353 + * format will exactly look like after the import returns, but you can still
 319.354 + * guess what your meshes will probably have.
 319.355 + * @note The default value is #PP_ICL_PTCACHE_SIZE. That results in slight
 319.356 + * performance improvements for most nVidia/AMD cards since 2002.
 319.357 + * Property type: integer.
 319.358 + */
 319.359 +#define AI_CONFIG_PP_ICL_PTCACHE_SIZE	"PP_ICL_PTCACHE_SIZE"
 319.360 +
 319.361 +// ---------------------------------------------------------------------------
 319.362 +/** @brief Enumerates components of the aiScene and aiMesh data structures
 319.363 + *  that can be excluded from the import using the #aiPrpcess_RemoveComponent step.
 319.364 + *
 319.365 + *  See the documentation to #aiProcess_RemoveComponent for more details.
 319.366 + */
 319.367 +enum aiComponent
 319.368 +{
 319.369 +	/** Normal vectors */
 319.370 +#ifdef SWIG
 319.371 +	aiComponent_NORMALS = 0x2,
 319.372 +#else
 319.373 +	aiComponent_NORMALS = 0x2u,
 319.374 +#endif
 319.375 +
 319.376 +	/** Tangents and bitangents go always together ... */
 319.377 +#ifdef SWIG
 319.378 +	aiComponent_TANGENTS_AND_BITANGENTS = 0x4,
 319.379 +#else
 319.380 +	aiComponent_TANGENTS_AND_BITANGENTS = 0x4u,
 319.381 +#endif
 319.382 +
 319.383 +	/** ALL color sets
 319.384 +	 * Use aiComponent_COLORn(N) to specify the N'th set */
 319.385 +	aiComponent_COLORS = 0x8,
 319.386 +
 319.387 +	/** ALL texture UV sets
 319.388 +	 * aiComponent_TEXCOORDn(N) to specify the N'th set  */
 319.389 +	aiComponent_TEXCOORDS = 0x10,
 319.390 +
 319.391 +	/** Removes all bone weights from all meshes.
 319.392 +	 * The scenegraph nodes corresponding to the bones are NOT removed.
 319.393 +	 * use the #aiProcess_OptimizeGraph step to do this */
 319.394 +	aiComponent_BONEWEIGHTS = 0x20,
 319.395 +
 319.396 +	/** Removes all node animations (aiScene::mAnimations).
 319.397 +	 * The corresponding scenegraph nodes are NOT removed.
 319.398 +	 * use the #aiProcess_OptimizeGraph step to do this */
 319.399 +	aiComponent_ANIMATIONS = 0x40,
 319.400 +
 319.401 +	/** Removes all embedded textures (aiScene::mTextures) */
 319.402 +	aiComponent_TEXTURES = 0x80,
 319.403 +
 319.404 +	/** Removes all light sources (aiScene::mLights).
 319.405 +	 * The corresponding scenegraph nodes are NOT removed.
 319.406 +	 * use the #aiProcess_OptimizeGraph step to do this */
 319.407 +	aiComponent_LIGHTS = 0x100,
 319.408 +
 319.409 +	/** Removes all cameras (aiScene::mCameras).
 319.410 +	 * The corresponding scenegraph nodes are NOT removed.
 319.411 +	 * use the #aiProcess_OptimizeGraph step to do this */
 319.412 +	aiComponent_CAMERAS = 0x200,
 319.413 +
 319.414 +	/** Removes all meshes (aiScene::mMeshes). */
 319.415 +	aiComponent_MESHES = 0x400,
 319.416 +
 319.417 +	/** Removes all materials. One default material will
 319.418 +	 * be generated, so aiScene::mNumMaterials will be 1. */
 319.419 +	aiComponent_MATERIALS = 0x800,
 319.420 +
 319.421 +
 319.422 +	/** This value is not used. It is just there to force the
 319.423 +	 *  compiler to map this enum to a 32 Bit integer. */
 319.424 +#ifndef SWIG
 319.425 +	_aiComponent_Force32Bit = 0x9fffffff
 319.426 +#endif
 319.427 +};
 319.428 +
 319.429 +// Remove a specific color channel 'n'
 319.430 +#define aiComponent_COLORSn(n) (1u << (n+20u))
 319.431 +
 319.432 +// Remove a specific UV channel 'n'
 319.433 +#define aiComponent_TEXCOORDSn(n) (1u << (n+25u))
 319.434 +
 319.435 +// ---------------------------------------------------------------------------
 319.436 +/** @brief Input parameter to the #aiProcess_RemoveComponent step:
 319.437 + *  Specifies the parts of the data structure to be removed.
 319.438 + *
 319.439 + * See the documentation to this step for further details. The property
 319.440 + * is expected to be an integer, a bitwise combination of the
 319.441 + * #aiComponent flags defined above in this header. The default
 319.442 + * value is 0. Important: if no valid mesh is remaining after the
 319.443 + * step has been executed (e.g you thought it was funny to specify ALL
 319.444 + * of the flags defined above) the import FAILS. Mainly because there is
 319.445 + * no data to work on anymore ...
 319.446 + */
 319.447 +#define AI_CONFIG_PP_RVC_FLAGS				\
 319.448 +	"PP_RVC_FLAGS"
 319.449 +
 319.450 +// ---------------------------------------------------------------------------
 319.451 +/** @brief Input parameter to the #aiProcess_SortByPType step:
 319.452 + *  Specifies which primitive types are removed by the step.
 319.453 + *
 319.454 + *  This is a bitwise combination of the aiPrimitiveType flags.
 319.455 + *  Specifying all of them is illegal, of course. A typical use would
 319.456 + *  be to exclude all line and point meshes from the import. This
 319.457 + *  is an integer property, its default value is 0.
 319.458 + */
 319.459 +#define AI_CONFIG_PP_SBP_REMOVE				\
 319.460 +	"PP_SBP_REMOVE"
 319.461 +
 319.462 +// ---------------------------------------------------------------------------
 319.463 +/** @brief Input parameter to the #aiProcess_FindInvalidData step:
 319.464 + *  Specifies the floating-point accuracy for animation values. The step
 319.465 + *  checks for animation tracks where all frame values are absolutely equal
 319.466 + *  and removes them. This tweakable controls the epsilon for floating-point
 319.467 + *  comparisons - two keys are considered equal if the invariant 
 319.468 + *  abs(n0-n1)>epsilon holds true for all vector respectively quaternion
 319.469 + *  components. The default value is 0.f - comparisons are exact then.
 319.470 + */
 319.471 +#define AI_CONFIG_PP_FID_ANIM_ACCURACY				\
 319.472 +	"PP_FID_ANIM_ACCURACY"
 319.473 +
 319.474 +
 319.475 +// TransformUVCoords evaluates UV scalings
 319.476 +#define AI_UVTRAFO_SCALING 0x1
 319.477 +
 319.478 +// TransformUVCoords evaluates UV rotations
 319.479 +#define AI_UVTRAFO_ROTATION 0x2
 319.480 +
 319.481 +// TransformUVCoords evaluates UV translation
 319.482 +#define AI_UVTRAFO_TRANSLATION 0x4
 319.483 +
 319.484 +// Everything baked together -> default value
 319.485 +#define AI_UVTRAFO_ALL (AI_UVTRAFO_SCALING | AI_UVTRAFO_ROTATION | AI_UVTRAFO_TRANSLATION)
 319.486 +
 319.487 +// ---------------------------------------------------------------------------
 319.488 +/** @brief Input parameter to the #aiProcess_TransformUVCoords step:
 319.489 + *  Specifies which UV transformations are evaluated.
 319.490 + *
 319.491 + *  This is a bitwise combination of the AI_UVTRAFO_XXX flags (integer
 319.492 + *  property, of course). By default all transformations are enabled 
 319.493 + * (AI_UVTRAFO_ALL).
 319.494 + */
 319.495 +#define AI_CONFIG_PP_TUV_EVALUATE				\
 319.496 +	"PP_TUV_EVALUATE"
 319.497 +
 319.498 +// ---------------------------------------------------------------------------
 319.499 +/** @brief A hint to assimp to favour speed against import quality.
 319.500 + *
 319.501 + * Enabling this option may result in faster loading, but it needn't.
 319.502 + * It represents just a hint to loaders and post-processing steps to use
 319.503 + * faster code paths, if possible. 
 319.504 + * This property is expected to be an integer, != 0 stands for true.
 319.505 + * The default value is 0.
 319.506 + */
 319.507 +#define AI_CONFIG_FAVOUR_SPEED				\
 319.508 + "FAVOUR_SPEED"
 319.509 +
 319.510 +
 319.511 +// ###########################################################################
 319.512 +// IMPORTER SETTINGS
 319.513 +// Various stuff to fine-tune the behaviour of specific importer plugins.
 319.514 +// ###########################################################################
 319.515 +
 319.516 +
 319.517 +// ---------------------------------------------------------------------------
 319.518 +/** @brief Set whether the fbx importer will merge all geometry layers present
 319.519 + *    in the source file or take only the first.
 319.520 + *
 319.521 + * The default value is true (1)
 319.522 + * Property type: bool
 319.523 + */
 319.524 +#define AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS \
 319.525 +	"IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS"
 319.526 +
 319.527 +// ---------------------------------------------------------------------------
 319.528 +/** @brief Set whether the fbx importer will read all materials present in the
 319.529 + *    source file or take only the referenced materials.
 319.530 + *
 319.531 + * This is void unless IMPORT_FBX_READ_MATERIALS=1.
 319.532 + *
 319.533 + * The default value is false (0)
 319.534 + * Property type: bool
 319.535 + */
 319.536 +#define AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS \
 319.537 +	"IMPORT_FBX_READ_ALL_MATERIALS"
 319.538 +
 319.539 +// ---------------------------------------------------------------------------
 319.540 +/** @brief Set whether the fbx importer will read materials.
 319.541 + *
 319.542 + * The default value is true (1)
 319.543 + * Property type: bool
 319.544 + */
 319.545 +#define AI_CONFIG_IMPORT_FBX_READ_MATERIALS \
 319.546 +	"IMPORT_FBX_READ_MATERIALS"
 319.547 +
 319.548 +// ---------------------------------------------------------------------------
 319.549 +/** @brief Set whether the fbx importer will read cameras.
 319.550 + *
 319.551 + * The default value is true (1)
 319.552 + * Property type: bool
 319.553 + */
 319.554 +#define AI_CONFIG_IMPORT_FBX_READ_CAMERAS \
 319.555 +	"IMPORT_FBX_READ_CAMERAS"
 319.556 +
 319.557 +// ---------------------------------------------------------------------------
 319.558 +/** @brief Set whether the fbx importer will read light sources.
 319.559 + *
 319.560 + * The default value is true (1)
 319.561 + * Property type: bool
 319.562 + */
 319.563 +#define AI_CONFIG_IMPORT_FBX_READ_LIGHTS \
 319.564 +	"IMPORT_FBX_READ_LIGHTS"
 319.565 +
 319.566 +// ---------------------------------------------------------------------------
 319.567 +/** @brief Set whether the fbx importer will read animations.
 319.568 + *
 319.569 + * The default value is true (1)
 319.570 + * Property type: bool
 319.571 + */
 319.572 +#define AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS \
 319.573 +	"IMPORT_FBX_READ_ANIMATIONS"
 319.574 +
 319.575 +// ---------------------------------------------------------------------------
 319.576 +/** @brief Set whether the fbx importer will act in strict mode in which only
 319.577 + *    FBX 2013 is supported and any other sub formats are rejected. FBX 2013
 319.578 + *    is the primary target for the importer, so this format is best
 319.579 + *    supported and well-tested.
 319.580 + *
 319.581 + * The default value is false (0)
 319.582 + * Property type: bool
 319.583 + */
 319.584 +#define AI_CONFIG_IMPORT_FBX_STRICT_MODE \
 319.585 +	"IMPORT_FBX_STRICT_MODE"
 319.586 +
 319.587 +// ---------------------------------------------------------------------------
 319.588 +/** @brief Set whether the fbx importer will preserve pivot points for
 319.589 + *    transformations (as extra nodes). If set to false, pivots and offsets
 319.590 + *    will be evaluated whenever possible.
 319.591 + *
 319.592 + * The default value is true (1)
 319.593 + * Property type: bool
 319.594 + */
 319.595 +#define AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS \
 319.596 +	"IMPORT_FBX_PRESERVE_PIVOTS"
 319.597 +
 319.598 +// ---------------------------------------------------------------------------
 319.599 +/** @brief Specifies whether the importer will drop empty animation curves or
 319.600 + *    animation curves which match the bind pose transformation over their
 319.601 + *    entire defined range.
 319.602 + *
 319.603 + * The default value is true (1)
 319.604 + * Property type: bool
 319.605 + */
 319.606 +#define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \
 319.607 +	"IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES"
 319.608 +
 319.609 +
 319.610 +
 319.611 +// ---------------------------------------------------------------------------
 319.612 +/** @brief  Set the vertex animation keyframe to be imported
 319.613 + *
 319.614 + * ASSIMP does not support vertex keyframes (only bone animation is supported).
 319.615 + * The library reads only one frame of models with vertex animations.
 319.616 + * By default this is the first frame.
 319.617 + * \note The default value is 0. This option applies to all importers.
 319.618 + *   However, it is also possible to override the global setting
 319.619 + *   for a specific loader. You can use the AI_CONFIG_IMPORT_XXX_KEYFRAME
 319.620 + *   options (where XXX is a placeholder for the file format for which you
 319.621 + *   want to override the global setting).
 319.622 + * Property type: integer.
 319.623 + */
 319.624 +#define AI_CONFIG_IMPORT_GLOBAL_KEYFRAME	"IMPORT_GLOBAL_KEYFRAME"
 319.625 +
 319.626 +#define AI_CONFIG_IMPORT_MD3_KEYFRAME		"IMPORT_MD3_KEYFRAME"
 319.627 +#define AI_CONFIG_IMPORT_MD2_KEYFRAME		"IMPORT_MD2_KEYFRAME"
 319.628 +#define AI_CONFIG_IMPORT_MDL_KEYFRAME		"IMPORT_MDL_KEYFRAME"
 319.629 +#define AI_CONFIG_IMPORT_MDC_KEYFRAME		"IMPORT_MDC_KEYFRAME"
 319.630 +#define AI_CONFIG_IMPORT_SMD_KEYFRAME		"IMPORT_SMD_KEYFRAME"
 319.631 +#define AI_CONFIG_IMPORT_UNREAL_KEYFRAME	"IMPORT_UNREAL_KEYFRAME"
 319.632 +
 319.633 +
 319.634 +// ---------------------------------------------------------------------------
 319.635 +/** @brief  Configures the AC loader to collect all surfaces which have the
 319.636 + *    "Backface cull" flag set in separate meshes. 
 319.637 + *
 319.638 + *  Property type: bool. Default value: true.
 319.639 + */
 319.640 +#define AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL	\
 319.641 +	"IMPORT_AC_SEPARATE_BFCULL"
 319.642 +
 319.643 +// ---------------------------------------------------------------------------
 319.644 +/** @brief  Configures whether the AC loader evaluates subdivision surfaces (
 319.645 + *  indicated by the presence of the 'subdiv' attribute in the file). By
 319.646 + *  default, Assimp performs the subdivision using the standard 
 319.647 + *  Catmull-Clark algorithm
 319.648 + *
 319.649 + * * Property type: bool. Default value: true.
 319.650 + */
 319.651 +#define AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION	\
 319.652 +	"IMPORT_AC_EVAL_SUBDIVISION"
 319.653 +
 319.654 +// ---------------------------------------------------------------------------
 319.655 +/** @brief  Configures the UNREAL 3D loader to separate faces with different
 319.656 + *    surface flags (e.g. two-sided vs. single-sided).
 319.657 + *
 319.658 + * * Property type: bool. Default value: true.
 319.659 + */
 319.660 +#define AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS \
 319.661 +	"UNREAL_HANDLE_FLAGS"
 319.662 +
 319.663 +// ---------------------------------------------------------------------------
 319.664 +/** @brief Configures the terragen import plugin to compute uv's for 
 319.665 + *  terrains, if not given. Furthermore a default texture is assigned.
 319.666 + *
 319.667 + * UV coordinates for terrains are so simple to compute that you'll usually
 319.668 + * want to compute them on your own, if you need them. This option is intended
 319.669 + * for model viewers which want to offer an easy way to apply textures to
 319.670 + * terrains.
 319.671 + * * Property type: bool. Default value: false.
 319.672 + */
 319.673 +#define AI_CONFIG_IMPORT_TER_MAKE_UVS \
 319.674 +	"IMPORT_TER_MAKE_UVS"
 319.675 +
 319.676 +// ---------------------------------------------------------------------------
 319.677 +/** @brief  Configures the ASE loader to always reconstruct normal vectors
 319.678 + *	basing on the smoothing groups loaded from the file.
 319.679 + * 
 319.680 + * Some ASE files have carry invalid normals, other don't.
 319.681 + * * Property type: bool. Default value: true.
 319.682 + */
 319.683 +#define AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS	\
 319.684 +	"IMPORT_ASE_RECONSTRUCT_NORMALS"
 319.685 +
 319.686 +// ---------------------------------------------------------------------------
 319.687 +/** @brief  Configures the M3D loader to detect and process multi-part 
 319.688 + *    Quake player models.
 319.689 + *
 319.690 + * These models usually consist of 3 files, lower.md3, upper.md3 and
 319.691 + * head.md3. If this property is set to true, Assimp will try to load and
 319.692 + * combine all three files if one of them is loaded. 
 319.693 + * Property type: bool. Default value: true.
 319.694 + */
 319.695 +#define AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART \
 319.696 +	"IMPORT_MD3_HANDLE_MULTIPART"
 319.697 +
 319.698 +// ---------------------------------------------------------------------------
 319.699 +/** @brief  Tells the MD3 loader which skin files to load.
 319.700 + *
 319.701 + * When loading MD3 files, Assimp checks whether a file 
 319.702 + * <md3_file_name>_<skin_name>.skin is existing. These files are used by
 319.703 + * Quake III to be able to assign different skins (e.g. red and blue team) 
 319.704 + * to models. 'default', 'red', 'blue' are typical skin names.
 319.705 + * Property type: String. Default value: "default".
 319.706 + */
 319.707 +#define AI_CONFIG_IMPORT_MD3_SKIN_NAME \
 319.708 +	"IMPORT_MD3_SKIN_NAME"
 319.709 +
 319.710 +// ---------------------------------------------------------------------------
 319.711 +/** @brief  Specify the Quake 3 shader file to be used for a particular
 319.712 + *  MD3 file. This can also be a search path.
 319.713 + *
 319.714 + * By default Assimp's behaviour is as follows: If a MD3 file 
 319.715 + * <tt><any_path>/models/<any_q3_subdir>/<model_name>/<file_name>.md3</tt> is 
 319.716 + * loaded, the library tries to locate the corresponding shader file in
 319.717 + * <tt><any_path>/scripts/<model_name>.shader</tt>. This property overrides this
 319.718 + * behaviour. It can either specify a full path to the shader to be loaded
 319.719 + * or alternatively the path (relative or absolute) to the directory where
 319.720 + * the shaders for all MD3s to be loaded reside. Assimp attempts to open 
 319.721 + * <tt><dir>/<model_name>.shader</tt> first, <tt><dir>/<file_name>.shader</tt> 
 319.722 + * is the fallback file. Note that <dir> should have a terminal (back)slash.
 319.723 + * Property type: String. Default value: n/a.
 319.724 + */
 319.725 +#define AI_CONFIG_IMPORT_MD3_SHADER_SRC \
 319.726 +	"IMPORT_MD3_SHADER_SRC"
 319.727 +
 319.728 +// ---------------------------------------------------------------------------
 319.729 +/** @brief  Configures the LWO loader to load just one layer from the model.
 319.730 + * 
 319.731 + * LWO files consist of layers and in some cases it could be useful to load
 319.732 + * only one of them. This property can be either a string - which specifies
 319.733 + * the name of the layer - or an integer - the index of the layer. If the
 319.734 + * property is not set the whole LWO model is loaded. Loading fails if the
 319.735 + * requested layer is not available. The layer index is zero-based and the
 319.736 + * layer name may not be empty.<br>
 319.737 + * Property type: Integer. Default value: all layers are loaded.
 319.738 + */
 319.739 +#define AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY			\
 319.740 +	"IMPORT_LWO_ONE_LAYER_ONLY"
 319.741 +
 319.742 +// ---------------------------------------------------------------------------
 319.743 +/** @brief  Configures the MD5 loader to not load the MD5ANIM file for
 319.744 + *  a MD5MESH file automatically.
 319.745 + * 
 319.746 + * The default strategy is to look for a file with the same name but the
 319.747 + * MD5ANIM extension in the same directory. If it is found, it is loaded
 319.748 + * and combined with the MD5MESH file. This configuration option can be
 319.749 + * used to disable this behaviour.
 319.750 + * 
 319.751 + * * Property type: bool. Default value: false.
 319.752 + */
 319.753 +#define AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD			\
 319.754 +	"IMPORT_MD5_NO_ANIM_AUTOLOAD"
 319.755 +
 319.756 +// ---------------------------------------------------------------------------
 319.757 +/** @brief Defines the begin of the time range for which the LWS loader
 319.758 + *    evaluates animations and computes aiNodeAnim's.
 319.759 + * 
 319.760 + * Assimp provides full conversion of LightWave's envelope system, including
 319.761 + * pre and post conditions. The loader computes linearly subsampled animation
 319.762 + * chanels with the frame rate given in the LWS file. This property defines
 319.763 + * the start time. Note: animation channels are only generated if a node
 319.764 + * has at least one envelope with more tan one key assigned. This property.
 319.765 + * is given in frames, '0' is the first frame. By default, if this property
 319.766 + * is not set, the importer takes the animation start from the input LWS
 319.767 + * file ('FirstFrame' line)<br>
 319.768 + * Property type: Integer. Default value: taken from file.
 319.769 + *
 319.770 + * @see AI_CONFIG_IMPORT_LWS_ANIM_END - end of the imported time range
 319.771 + */
 319.772 +#define AI_CONFIG_IMPORT_LWS_ANIM_START			\
 319.773 +	"IMPORT_LWS_ANIM_START"
 319.774 +#define AI_CONFIG_IMPORT_LWS_ANIM_END			\
 319.775 +	"IMPORT_LWS_ANIM_END"
 319.776 +
 319.777 +// ---------------------------------------------------------------------------
 319.778 +/** @brief Defines the output frame rate of the IRR loader.
 319.779 + * 
 319.780 + * IRR animations are difficult to convert for Assimp and there will
 319.781 + * always be a loss of quality. This setting defines how many keys per second
 319.782 + * are returned by the converter.<br>
 319.783 + * Property type: integer. Default value: 100
 319.784 + */
 319.785 +#define AI_CONFIG_IMPORT_IRR_ANIM_FPS				\
 319.786 +	"IMPORT_IRR_ANIM_FPS"
 319.787 +
 319.788 +
 319.789 +// ---------------------------------------------------------------------------
 319.790 +/** @brief Ogre Importer will try to load this Materialfile.
 319.791 + *
 319.792 + * Ogre Meshes contain only the MaterialName, not the MaterialFile. If there 
 319.793 + * is no material file with the same name as the material, Ogre Importer will 
 319.794 + * try to load this file and search the material in it.
 319.795 + * <br>
 319.796 + * Property type: String. Default value: guessed.
 319.797 + */
 319.798 +#define AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE "IMPORT_OGRE_MATERIAL_FILE"
 319.799 +
 319.800 +
 319.801 +// ---------------------------------------------------------------------------
 319.802 +/** @brief Ogre Importer detect the texture usage from its filename
 319.803 + *
 319.804 + * Normally, a texture is loaded as a colormap, if no target is specified in the
 319.805 + * materialfile. Is this switch is enabled, texture names ending with _n, _l, _s
 319.806 + * are used as normalmaps, lightmaps or specularmaps. 
 319.807 + * <br>
 319.808 + * Property type: Bool. Default value: false.
 319.809 + */
 319.810 +#define AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME "IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME"
 319.811 +
 319.812 +/** @brief Specifies whether the IFC loader skips over IfcSpace elements.
 319.813 + *
 319.814 + * IfcSpace elements (and their geometric representations) are used to
 319.815 + * represent, well, free space in a building storey.<br>
 319.816 + * Property type: Bool. Default value: true.
 319.817 + */
 319.818 +#define AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS "IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS"
 319.819 +
 319.820 +
 319.821 +// ---------------------------------------------------------------------------
 319.822 +/** @brief Specifies whether the IFC loader skips over 
 319.823 + *    shape representations of type 'Curve2D'.
 319.824 + *
 319.825 + * A lot of files contain both a faceted mesh representation and a outline
 319.826 + * with a presentation type of 'Curve2D'. Currently Assimp doesn't convert those,
 319.827 + * so turning this option off just clutters the log with errors.<br>
 319.828 + * Property type: Bool. Default value: true.
 319.829 + */
 319.830 +#define AI_CONFIG_IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS "IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS"
 319.831 +
 319.832 +// ---------------------------------------------------------------------------
 319.833 +/** @brief Specifies whether the IFC loader will use its own, custom triangulation
 319.834 + *   algorithm to triangulate wall and floor meshes.
 319.835 + *
 319.836 + * If this property is set to false, walls will be either triangulated by
 319.837 + * #aiProcess_Triangulate or will be passed through as huge polygons with 
 319.838 + * faked holes (i.e. holes that are connected with the outer boundary using
 319.839 + * a dummy edge). It is highly recommended to set this property to true
 319.840 + * if you want triangulated data because #aiProcess_Triangulate is known to
 319.841 + * have problems with the kind of polygons that the IFC loader spits out for
 319.842 + * complicated meshes.
 319.843 + * Property type: Bool. Default value: true.
 319.844 + */
 319.845 +#define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION"
 319.846 +
 319.847 +#endif // !! AI_CONFIG_H_INC
 319.848 \ No newline at end of file
   320.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   320.2 +++ b/libs/assimp/assimp/defs.h	Sat Feb 01 19:58:19 2014 +0200
   320.3 @@ -0,0 +1,318 @@
   320.4 +/*
   320.5 +---------------------------------------------------------------------------
   320.6 +Open Asset Import Library (assimp)
   320.7 +---------------------------------------------------------------------------
   320.8 +
   320.9 +Copyright (c) 2006-2012, assimp team
  320.10 +
  320.11 +All rights reserved.
  320.12 +
  320.13 +Redistribution and use of this software in source and binary forms, 
  320.14 +with or without modification, are permitted provided that the following 
  320.15 +conditions are met:
  320.16 +
  320.17 +* Redistributions of source code must retain the above
  320.18 +  copyright notice, this list of conditions and the
  320.19 +  following disclaimer.
  320.20 +
  320.21 +* Redistributions in binary form must reproduce the above
  320.22 +  copyright notice, this list of conditions and the
  320.23 +  following disclaimer in the documentation and/or other
  320.24 +  materials provided with the distribution.
  320.25 +
  320.26 +* Neither the name of the assimp team, nor the names of its
  320.27 +  contributors may be used to endorse or promote products
  320.28 +  derived from this software without specific prior
  320.29 +  written permission of the assimp team.
  320.30 +
  320.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  320.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  320.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  320.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  320.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  320.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  320.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  320.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  320.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  320.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  320.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  320.42 +---------------------------------------------------------------------------
  320.43 +*/
  320.44 +
  320.45 +/** @file aiDefines.h
  320.46 + *  @brief Assimp build configuration setup. See the notes in the comment
  320.47 + *  blocks to find out how to customize _your_ Assimp build.
  320.48 + */
  320.49 +
  320.50 +#ifndef INCLUDED_AI_DEFINES_H
  320.51 +#define INCLUDED_AI_DEFINES_H
  320.52 +
  320.53 +	//////////////////////////////////////////////////////////////////////////
  320.54 +	/* Define ASSIMP_BUILD_NO_XX_IMPORTER to disable a specific
  320.55 +	 * file format loader. The loader is be excluded from the
  320.56 +	 * build in this case. 'XX' stands for the most common file
  320.57 +	 * extension of the file format. E.g.: 
  320.58 +	 * ASSIMP_BUILD_NO_X_IMPORTER disables the X loader.
  320.59 +	 *
  320.60 +	 * If you're unsure about that, take a look at the implementation of the
  320.61 +	 * import plugin you wish to disable. You'll find the right define in the
  320.62 +	 * first lines of the corresponding unit.
  320.63 +	 *
  320.64 +	 * Other (mixed) configuration switches are listed here:
  320.65 +	 *    ASSIMP_BUILD_NO_COMPRESSED_X 
  320.66 +	 *      - Disable support for compressed X files (zip)
  320.67 +	 *    ASSIMP_BUILD_NO_COMPRESSED_BLEND
  320.68 +	 *      - Disable support for compressed Blender files (zip)
  320.69 +	 *    ASSIMP_BUILD_NO_COMPRESSED_IFC
  320.70 +	 *      - Disable support for IFCZIP files (unzip)
  320.71 +	 */
  320.72 +	//////////////////////////////////////////////////////////////////////////
  320.73 +
  320.74 +#define ASSIMP_BUILD_NO_OWN_ZLIB
  320.75 +
  320.76 +// let's disable anything we don't really need
  320.77 +#define ASSIMP_BUILD_NO_COMPRESSED_X
  320.78 +#define ASSIMP_BUILD_NO_COMPRESSED_BLEND
  320.79 +#define ASSIMP_BUILD_NO_COMPRESSED_IFC
  320.80 +#define ASSIMP_BUILD_NO_Q3BSP_IMPORTER
  320.81 +
  320.82 +// disable various formats
  320.83 +#define ASSIMP_BUILD_NO_B3D_IMPORTER
  320.84 +#define ASSIMP_BUILD_NO_BVH_IMPORTER
  320.85 +#define ASSIMP_BUILD_NO_COB_IMPORTER
  320.86 +#define ASSIMP_BUILD_NO_CSM_IMPORTER
  320.87 +#define ASSIMP_BUILD_NO_DXF_IMPORTER
  320.88 +#define ASSIMP_BUILD_NO_HMP_IMPORTER
  320.89 +#define ASSIMP_BUILD_NO_IFC_IMPORTER
  320.90 +#define ASSIMP_BUILD_NO_IRR_IMPORTER
  320.91 +#define ASSIMP_BUILD_NO_IRRMESH_IMPORTER
  320.92 +#define ASSIMP_BUILD_NO_LWO_IMPORTER
  320.93 +#define ASSIMP_BUILD_NO_LWS_IMPORTER
  320.94 +#define ASSIMP_BUILD_NO_MD2_IMPORTER
  320.95 +#define ASSIMP_BUILD_NO_MDC_IMPORTER
  320.96 +#define ASSIMP_BUILD_NO_MDL_IMPORTER
  320.97 +#define ASSIMP_BUILD_NO_NDO_IMPORTER
  320.98 +#define ASSIMP_BUILD_NO_NFF_IMPORTER
  320.99 +#define ASSIMP_BUILD_NO_OFF_IMPORTER
 320.100 +#define ASSIMP_BUILD_NO_OGRE_IMPORTER
 320.101 +#define ASSIMP_BUILD_NO_PLY_IMPORTER
 320.102 +#define ASSIMP_BUILD_NO_Q3D_IMPORTER
 320.103 +#define ASSIMP_BUILD_NO_RAW_IMPORTER
 320.104 +#define ASSIMP_BUILD_NO_SMD_IMPORTER
 320.105 +#define ASSIMP_BUILD_NO_STL_IMPORTER
 320.106 +#define ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
 320.107 +#define ASSIMP_BUILD_NO_3D_IMPORTER
 320.108 +#define ASSIMP_BUILD_NO_X_IMPORTER
 320.109 +#define ASSIMP_BUILD_NO_XGL_IMPORTER
 320.110 +
 320.111 +// we don't really need assimp to be thread-safe (I think)
 320.112 +#define ASSIMP_BUILD_SINGLETHREADED
 320.113 +
 320.114 +
 320.115 +#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
 320.116 +#	define ASSIMP_BUILD_NEED_Z_INFLATE
 320.117 +#endif
 320.118 +
 320.119 +#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
 320.120 +#	define ASSIMP_BUILD_NEED_Z_INFLATE
 320.121 +#endif
 320.122 +
 320.123 +#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
 320.124 +#	define ASSIMP_BUILD_NEED_Z_INFLATE
 320.125 +#	define ASSIMP_BUILD_NEED_UNZIP
 320.126 +#endif
 320.127 +
 320.128 +#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
 320.129 +#	define ASSIMP_BUILD_NEED_Z_INFLATE
 320.130 +#	define ASSIMP_BUILD_NEED_UNZIP
 320.131 +#endif
 320.132 +
 320.133 +	//////////////////////////////////////////////////////////////////////////
 320.134 +	/* Define ASSIMP_BUILD_NO_XX_PROCESS to disable a specific
 320.135 +	 * post processing step. This is the current list of process names ('XX'):
 320.136 +	 * CALCTANGENTS
 320.137 +	 * JOINVERTICES
 320.138 +	 * TRIANGULATE
 320.139 +	 * GENFACENORMALS
 320.140 +	 * GENVERTEXNORMALS
 320.141 +	 * REMOVEVC
 320.142 +	 * SPLITLARGEMESHES
 320.143 +	 * PRETRANSFORMVERTICES
 320.144 +	 * LIMITBONEWEIGHTS
 320.145 +	 * VALIDATEDS
 320.146 +	 * IMPROVECACHELOCALITY
 320.147 +	 * FIXINFACINGNORMALS
 320.148 +	 * REMOVE_REDUNDANTMATERIALS
 320.149 +	 * OPTIMIZEGRAPH
 320.150 +	 * SORTBYPTYPE
 320.151 +	 * FINDINVALIDDATA
 320.152 +	 * TRANSFORMTEXCOORDS
 320.153 +	 * GENUVCOORDS
 320.154 +	 * ENTITYMESHBUILDER
 320.155 +	 * MAKELEFTHANDED
 320.156 +	 * FLIPUVS
 320.157 +	 * FLIPWINDINGORDER
 320.158 +	 * OPTIMIZEMESHES
 320.159 +	 * OPTIMIZEANIMS
 320.160 +	 * OPTIMIZEGRAPH
 320.161 +	 * GENENTITYMESHES
 320.162 +	 * FIXTEXTUREPATHS */
 320.163 +	//////////////////////////////////////////////////////////////////////////
 320.164 +
 320.165 +#ifdef _MSC_VER
 320.166 +#	undef ASSIMP_API
 320.167 +
 320.168 +	//////////////////////////////////////////////////////////////////////////
 320.169 +	/* Define 'ASSIMP_BUILD_DLL_EXPORT' to build a DLL of the library */
 320.170 +	//////////////////////////////////////////////////////////////////////////
 320.171 +#	ifdef ASSIMP_BUILD_DLL_EXPORT
 320.172 +#		define ASSIMP_API __declspec(dllexport)
 320.173 +#		define ASSIMP_API_WINONLY __declspec(dllexport)
 320.174 +#		pragma warning (disable : 4251)
 320.175 +
 320.176 +	//////////////////////////////////////////////////////////////////////////
 320.177 +	/* Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in
 320.178 +	 * an external DLL under Windows. Default is static linkage. */
 320.179 +	//////////////////////////////////////////////////////////////////////////
 320.180 +#	elif (defined ASSIMP_DLL)
 320.181 +#		define ASSIMP_API __declspec(dllimport)
 320.182 +#		define ASSIMP_API_WINONLY __declspec(dllimport)
 320.183 +#	else
 320.184 +#		define ASSIMP_API 
 320.185 +#		define ASSIMP_API_WINONLY
 320.186 +#	endif
 320.187 +
 320.188 +	/* Force the compiler to inline a function, if possible
 320.189 +	 */
 320.190 +#	define AI_FORCE_INLINE __forceinline
 320.191 +
 320.192 +	/* Tells the compiler that a function never returns. Used in code analysis
 320.193 +	 * to skip dead paths (e.g. after an assertion evaluated to false). */
 320.194 +#	define AI_WONT_RETURN __declspec(noreturn)
 320.195 +
 320.196 +#elif defined(SWIG)
 320.197 +
 320.198 +	/* Do nothing, the relevant defines are all in AssimpSwigPort.i */
 320.199 +
 320.200 +#else
 320.201 +	
 320.202 +#	define AI_WONT_RETURN
 320.203 +
 320.204 +#	define ASSIMP_API __attribute__ ((visibility("default")))
 320.205 +#	define ASSIMP_API_WINONLY
 320.206 +#	define AI_FORCE_INLINE inline
 320.207 +#endif // (defined _MSC_VER)
 320.208 +
 320.209 +#ifdef __cplusplus
 320.210 +	/* No explicit 'struct' and 'enum' tags for C++, this keeps showing up
 320.211 +	 * in doxydocs.
 320.212 +	 */
 320.213 +#	define C_STRUCT
 320.214 +#	define C_ENUM
 320.215 +#else
 320.216 +	//////////////////////////////////////////////////////////////////////////
 320.217 +	/* To build the documentation, make sure ASSIMP_DOXYGEN_BUILD
 320.218 +	 * is defined by Doxygen's preprocessor. The corresponding
 320.219 +	 * entries in the DOXYFILE are: */
 320.220 +	//////////////////////////////////////////////////////////////////////////
 320.221 +#if 0
 320.222 +	ENABLE_PREPROCESSING   = YES
 320.223 +	MACRO_EXPANSION        = YES
 320.224 +	EXPAND_ONLY_PREDEF     = YES
 320.225 +	SEARCH_INCLUDES        = YES
 320.226 +	INCLUDE_PATH           = 
 320.227 +	INCLUDE_FILE_PATTERNS  = 
 320.228 +	PREDEFINED             = ASSIMP_DOXYGEN_BUILD=1
 320.229 +	EXPAND_AS_DEFINED      = C_STRUCT C_ENUM
 320.230 +	SKIP_FUNCTION_MACROS   = YES
 320.231 +#endif
 320.232 +	//////////////////////////////////////////////////////////////////////////
 320.233 +	/* Doxygen gets confused if we use c-struct typedefs to avoid
 320.234 +	 * the explicit 'struct' notation. This trick here has the same
 320.235 +	 * effect as the TYPEDEF_HIDES_STRUCT option, but we don't need
 320.236 +	 * to typedef all structs/enums. */
 320.237 +	 //////////////////////////////////////////////////////////////////////////
 320.238 +#	if (defined ASSIMP_DOXYGEN_BUILD)
 320.239 +#		define C_STRUCT 
 320.240 +#		define C_ENUM   
 320.241 +#	else
 320.242 +#		define C_STRUCT struct
 320.243 +#		define C_ENUM   enum
 320.244 +#	endif
 320.245 +#endif
 320.246 +
 320.247 +#if (defined(__BORLANDC__) || defined (__BCPLUSPLUS__))
 320.248 +#error Currently, Borland is unsupported. Feel free to port Assimp.
 320.249 +
 320.250 +// "W8059 Packgröße der Struktur geändert"
 320.251 +
 320.252 +#endif
 320.253 +	//////////////////////////////////////////////////////////////////////////
 320.254 +	/* Define 'ASSIMP_BUILD_BOOST_WORKAROUND' to compile assimp
 320.255 +	 * without boost. This is done by using a few workaround
 320.256 +	 * classes and brings some limitations (e.g. some logging won't be done,
 320.257 +	 * the library won't utilize threads or be threadsafe at all). 
 320.258 +	 * This implies the 'ASSIMP_BUILD_SINGLETHREADED' setting. */
 320.259 +	 //////////////////////////////////////////////////////////////////////////
 320.260 +#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
 320.261 +
 320.262 +	// threading support requires boost
 320.263 +#ifndef ASSIMP_BUILD_SINGLETHREADED
 320.264 +#	define ASSIMP_BUILD_SINGLETHREADED
 320.265 +#endif
 320.266 +
 320.267 +#endif // !! ASSIMP_BUILD_BOOST_WORKAROUND
 320.268 +
 320.269 +	//////////////////////////////////////////////////////////////////////////
 320.270 +	/* Define ASSIMP_BUILD_SINGLETHREADED to compile assimp
 320.271 +	 * without threading support. The library doesn't utilize
 320.272 +	 * threads then and is itself not threadsafe.
 320.273 +	 * If this flag is specified boost::threads is *not* required. */
 320.274 +	//////////////////////////////////////////////////////////////////////////
 320.275 +#ifndef ASSIMP_BUILD_SINGLETHREADED
 320.276 +#	define ASSIMP_BUILD_SINGLETHREADED
 320.277 +#endif
 320.278 +
 320.279 +#ifndef ASSIMP_BUILD_SINGLETHREADED
 320.280 +#	define AI_C_THREADSAFE
 320.281 +#endif // !! ASSIMP_BUILD_SINGLETHREADED
 320.282 +
 320.283 +#ifdef _DEBUG 
 320.284 +#	define ASSIMP_BUILD_DEBUG
 320.285 +#endif
 320.286 +
 320.287 +	//////////////////////////////////////////////////////////////////////////
 320.288 +	/* Useful constants */
 320.289 +	//////////////////////////////////////////////////////////////////////////
 320.290 +
 320.291 +/* This is PI. Hi PI. */
 320.292 +#define AI_MATH_PI			(3.141592653589793238462643383279 )
 320.293 +#define AI_MATH_TWO_PI		(AI_MATH_PI * 2.0)
 320.294 +#define AI_MATH_HALF_PI		(AI_MATH_PI * 0.5)
 320.295 +
 320.296 +/* And this is to avoid endless casts to float */
 320.297 +#define AI_MATH_PI_F		(3.1415926538f)
 320.298 +#define AI_MATH_TWO_PI_F	(AI_MATH_PI_F * 2.0f)
 320.299 +#define AI_MATH_HALF_PI_F	(AI_MATH_PI_F * 0.5f)
 320.300 +
 320.301 +/* Tiny macro to convert from radians to degrees and back */
 320.302 +#define AI_DEG_TO_RAD(x) (x*0.0174532925f)
 320.303 +#define AI_RAD_TO_DEG(x) (x*57.2957795f)
 320.304 +
 320.305 +/* Support for big-endian builds */
 320.306 +#if defined(__BYTE_ORDER__)
 320.307 +#	if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 
 320.308 +#		if !defined(__BIG_ENDIAN__)
 320.309 +#			define __BIG_ENDIAN__
 320.310 +#		endif
 320.311 +#	else /* little endian */
 320.312 +#		if defined (__BIG_ENDIAN__)
 320.313 +#			undef __BIG_ENDIAN__
 320.314 +#		endif
 320.315 +#	endif
 320.316 +#endif
 320.317 +#if defined(__BIG_ENDIAN__)
 320.318 +#	define AI_BUILD_BIG_ENDIAN
 320.319 +#endif
 320.320 +
 320.321 +#endif // !! INCLUDED_AI_DEFINES_H
   321.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   321.2 +++ b/libs/assimp/assimp/importerdesc.h	Sat Feb 01 19:58:19 2014 +0200
   321.3 @@ -0,0 +1,136 @@
   321.4 +/*
   321.5 +---------------------------------------------------------------------------
   321.6 +Open Asset Import Library (assimp)
   321.7 +---------------------------------------------------------------------------
   321.8 +
   321.9 +Copyright (c) 2006-2012, assimp team
  321.10 +
  321.11 +All rights reserved.
  321.12 +
  321.13 +Redistribution and use of this software in source and binary forms, 
  321.14 +with or without modification, are permitted provided that the following 
  321.15 +conditions are met:
  321.16 +
  321.17 +* Redistributions of source code must retain the above
  321.18 +  copyright notice, this list of conditions and the
  321.19 +  following disclaimer.
  321.20 +
  321.21 +* Redistributions in binary form must reproduce the above
  321.22 +  copyright notice, this list of conditions and the
  321.23 +  following disclaimer in the documentation and/or other
  321.24 +  materials provided with the distribution.
  321.25 +
  321.26 +* Neither the name of the assimp team, nor the names of its
  321.27 +  contributors may be used to endorse or promote products
  321.28 +  derived from this software without specific prior
  321.29 +  written permission of the assimp team.
  321.30 +
  321.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  321.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  321.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  321.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  321.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  321.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  321.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  321.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  321.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  321.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  321.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  321.42 +---------------------------------------------------------------------------
  321.43 +*/
  321.44 +
  321.45 +/** @file importerdesc.h
  321.46 + *  @brief #aiImporterFlags, aiImporterDesc implementation.
  321.47 + */
  321.48 +#ifndef INCLUDED_AI_IMPORTER_DESC_H
  321.49 +#define INCLUDED_AI_IMPORTER_DESC_H
  321.50 +
  321.51 +
  321.52 +/** Mixed set of flags for #aiImporterDesc, indicating some features
  321.53 +  *  common to many importers*/
  321.54 +enum aiImporterFlags 
  321.55 +{
  321.56 +	/** Indicates that there is a textual encoding of the
  321.57 +	 *  file format; and that it is supported.*/
  321.58 +	aiImporterFlags_SupportTextFlavour = 0x1,
  321.59 +
  321.60 +	/** Indicates that there is a binary encoding of the
  321.61 +	 *  file format; and that it is supported.*/
  321.62 +	aiImporterFlags_SupportBinaryFlavour = 0x2,
  321.63 +
  321.64 +	/** Indicates that there is a compressed encoding of the
  321.65 +	 *  file format; and that it is supported.*/
  321.66 +	aiImporterFlags_SupportCompressedFlavour = 0x4,
  321.67 +
  321.68 +	/** Indicates that the importer reads only a very particular
  321.69 +	  * subset of the file format. This happens commonly for
  321.70 +	  * declarative or procedural formats which cannot easily
  321.71 +	  * be mapped to #aiScene */
  321.72 +	aiImporterFlags_LimitedSupport = 0x8,
  321.73 +
  321.74 +	/** Indicates that the importer is highly experimental and
  321.75 +	  * should be used with care. This only happens for trunk
  321.76 +	  * (i.e. SVN) versions, experimental code is not included
  321.77 +	  * in releases. */
  321.78 +	aiImporterFlags_Experimental = 0x10,
  321.79 +};
  321.80 +
  321.81 +
  321.82 +/** Meta information about a particular importer. Importers need to fill
  321.83 + *  this structure, but they can freely decide how talkative they are. 
  321.84 + *  A common use case for loader meta info is a user interface
  321.85 + *  in which the user can choose between various import/export file
  321.86 + *  formats. Building such an UI by hand means a lot of maintenance
  321.87 + *  as importers/exporters are added to Assimp, so it might be useful
  321.88 + *  to have a common mechanism to query some rough importer
  321.89 + *  characteristics. */
  321.90 +struct aiImporterDesc 
  321.91 +{
  321.92 +	/** Full name of the importer (i.e. Blender3D importer)*/
  321.93 +	const char* mName;
  321.94 +
  321.95 +	/** Original author (left blank if unknown or whole assimp team) */
  321.96 +	const char* mAuthor;
  321.97 +
  321.98 +	/** Current maintainer, left blank if the author maintains */
  321.99 +	const char* mMaintainer;
 321.100 +
 321.101 +	/** Implementation comments, i.e. unimplemented features*/
 321.102 +	const char* mComments;
 321.103 +
 321.104 +	/** Any combination of the #aiLoaderFlags enumerated values.
 321.105 +	    These flags indicate some characteristics common to many
 321.106 +		importers. */
 321.107 +	unsigned int mFlags;
 321.108 +
 321.109 +	/** Minimum format version that can be loaded im major.minor format,
 321.110 +	    both are set to 0 if there is either no version scheme 
 321.111 +		or if the loader doesn't care. */
 321.112 +	unsigned int mMinMajor;
 321.113 +	unsigned int mMinMinor;
 321.114 +
 321.115 +	/** Maximum format version that can be loaded im major.minor format,
 321.116 +	    both are set to 0 if there is either no version scheme 
 321.117 +		or if the loader doesn't care. Loaders that expect to be
 321.118 +		forward-compatible to potential future format versions should 
 321.119 +		indicate  zero, otherwise they should specify the current
 321.120 +		maximum version.*/
 321.121 +	unsigned int mMaxMajor;
 321.122 +	unsigned int mMaxMinor;
 321.123 +
 321.124 +	/** List of file extensions this importer can handle.
 321.125 +	    List entries are separated by space characters.
 321.126 +		All entries are lower case without a leading dot (i.e.
 321.127 +		"xml dae" would be a valid value. Note that multiple
 321.128 +		importers may respond to the same file extension -
 321.129 +		assimp calls all importers in the order in which they
 321.130 +		are registered and each importer gets the opportunity
 321.131 +		to load the file until one importer "claims" the file. Apart
 321.132 +		from file extension checks, importers typically use
 321.133 +		other methods to quickly reject files (i.e. magic
 321.134 +		words) so this does not mean that common or generic
 321.135 +		file extensions such as XML would be tediously slow. */
 321.136 +	const char* mFileExtensions;
 321.137 +};
 321.138 +
 321.139 +#endif 
   322.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   322.2 +++ b/libs/assimp/assimp/light.h	Sat Feb 01 19:58:19 2014 +0200
   322.3 @@ -0,0 +1,233 @@
   322.4 +/*
   322.5 +---------------------------------------------------------------------------
   322.6 +Open Asset Import Library (assimp)
   322.7 +---------------------------------------------------------------------------
   322.8 +
   322.9 +Copyright (c) 2006-2012, assimp team
  322.10 +
  322.11 +All rights reserved.
  322.12 +
  322.13 +Redistribution and use of this software in source and binary forms, 
  322.14 +with or without modification, are permitted provided that the following 
  322.15 +conditions are met:
  322.16 +
  322.17 +* Redistributions of source code must retain the above
  322.18 +  copyright notice, this list of conditions and the
  322.19 +  following disclaimer.
  322.20 +
  322.21 +* Redistributions in binary form must reproduce the above
  322.22 +  copyright notice, this list of conditions and the
  322.23 +  following disclaimer in the documentation and/or other
  322.24 +  materials provided with the distribution.
  322.25 +
  322.26 +* Neither the name of the assimp team, nor the names of its
  322.27 +  contributors may be used to endorse or promote products
  322.28 +  derived from this software without specific prior
  322.29 +  written permission of the assimp team.
  322.30 +
  322.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  322.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  322.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  322.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  322.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  322.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  322.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  322.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  322.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  322.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  322.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  322.42 +---------------------------------------------------------------------------
  322.43 +*/
  322.44 +
  322.45 +/** @file light.h
  322.46 + *  @brief Defines the aiLight data structure
  322.47 + */
  322.48 +
  322.49 +#ifndef __AI_LIGHT_H_INC__
  322.50 +#define __AI_LIGHT_H_INC__
  322.51 +
  322.52 +#include "types.h"
  322.53 +
  322.54 +#ifdef __cplusplus
  322.55 +extern "C" {
  322.56 +#endif
  322.57 +
  322.58 +// ---------------------------------------------------------------------------
  322.59 +/** Enumerates all supported types of light sources.
  322.60 + */
  322.61 +enum aiLightSourceType
  322.62 +{
  322.63 +	aiLightSource_UNDEFINED     = 0x0,
  322.64 +
  322.65 +	//! A directional light source has a well-defined direction
  322.66 +	//! but is infinitely far away. That's quite a good 
  322.67 +	//! approximation for sun light.
  322.68 +	aiLightSource_DIRECTIONAL   = 0x1,
  322.69 +
  322.70 +	//! A point light source has a well-defined position
  322.71 +	//! in space but no direction - it emits light in all
  322.72 +	//! directions. A normal bulb is a point light.
  322.73 +	aiLightSource_POINT         = 0x2,
  322.74 +
  322.75 +	//! A spot light source emits light in a specific 
  322.76 +	//! angle. It has a position and a direction it is pointing to.
  322.77 +	//! A good example for a spot light is a light spot in
  322.78 +	//! sport arenas.
  322.79 +	aiLightSource_SPOT          = 0x3,
  322.80 +
  322.81 +
  322.82 +	/** This value is not used. It is just there to force the
  322.83 +	 *  compiler to map this enum to a 32 Bit integer.
  322.84 +	 */
  322.85 +#ifndef SWIG
  322.86 +	_aiLightSource_Force32Bit = INT_MAX
  322.87 +#endif
  322.88 +};
  322.89 +
  322.90 +// ---------------------------------------------------------------------------
  322.91 +/** Helper structure to describe a light source.
  322.92 + *
  322.93 + *  Assimp supports multiple sorts of light sources, including
  322.94 + *  directional, point and spot lights. All of them are defined with just
  322.95 + *  a single structure and distinguished by their parameters.
  322.96 + *  Note - some file formats (such as 3DS, ASE) export a "target point" -
  322.97 + *  the point a spot light is looking at (it can even be animated). Assimp
  322.98 + *  writes the target point as a subnode of a spotlights's main node,
  322.99 + *  called "<spotName>.Target". However, this is just additional information
 322.100 + *  then, the transformation tracks of the main node make the
 322.101 + *  spot light already point in the right direction.
 322.102 +*/
 322.103 +struct aiLight
 322.104 +{
 322.105 +	/** The name of the light source.
 322.106 +	 *
 322.107 +	 *  There must be a node in the scenegraph with the same name.
 322.108 +	 *  This node specifies the position of the light in the scene
 322.109 +	 *  hierarchy and can be animated.
 322.110 +	 */
 322.111 +	C_STRUCT aiString mName;
 322.112 +
 322.113 +	/** The type of the light source.
 322.114 + 	 *
 322.115 +	 * aiLightSource_UNDEFINED is not a valid value for this member.
 322.116 +	 */
 322.117 +	C_ENUM aiLightSourceType mType;
 322.118 +
 322.119 +	/** Position of the light source in space. Relative to the
 322.120 +	 *  transformation of the node corresponding to the light.
 322.121 +	 *
 322.122 +	 *  The position is undefined for directional lights.
 322.123 +	 */
 322.124 +	C_STRUCT aiVector3D mPosition;
 322.125 +
 322.126 +	/** Direction of the light source in space. Relative to the
 322.127 +	 *  transformation of the node corresponding to the light.
 322.128 +	 *
 322.129 +	 *  The direction is undefined for point lights. The vector
 322.130 +	 *  may be normalized, but it needn't.
 322.131 +	 */
 322.132 +	C_STRUCT aiVector3D mDirection;
 322.133 +
 322.134 +	/** Constant light attenuation factor. 
 322.135 +	 *
 322.136 +	 *  The intensity of the light source at a given distance 'd' from
 322.137 +	 *  the light's position is
 322.138 +	 *  @code
 322.139 +	 *  Atten = 1/( att0 + att1 * d + att2 * d*d)
 322.140 +	 *  @endcode
 322.141 +	 *  This member corresponds to the att0 variable in the equation.
 322.142 +	 *  Naturally undefined for directional lights.
 322.143 +	 */
 322.144 +	float mAttenuationConstant;
 322.145 +
 322.146 +	/** Linear light attenuation factor. 
 322.147 +	 *
 322.148 +	 *  The intensity of the light source at a given distance 'd' from
 322.149 +	 *  the light's position is
 322.150 +	 *  @code
 322.151 +	 *  Atten = 1/( att0 + att1 * d + att2 * d*d)
 322.152 +	 *  @endcode
 322.153 +	 *  This member corresponds to the att1 variable in the equation.
 322.154 +	 *  Naturally undefined for directional lights.
 322.155 +	 */
 322.156 +	float mAttenuationLinear;
 322.157 +
 322.158 +	/** Quadratic light attenuation factor. 
 322.159 +	 *  
 322.160 +	 *  The intensity of the light source at a given distance 'd' from
 322.161 +	 *  the light's position is
 322.162 +	 *  @code
 322.163 +	 *  Atten = 1/( att0 + att1 * d + att2 * d*d)
 322.164 +	 *  @endcode
 322.165 +	 *  This member corresponds to the att2 variable in the equation.
 322.166 +	 *  Naturally undefined for directional lights.
 322.167 +	 */
 322.168 +	float mAttenuationQuadratic;
 322.169 +
 322.170 +	/** Diffuse color of the light source
 322.171 +	 *
 322.172 +	 *  The diffuse light color is multiplied with the diffuse 
 322.173 +	 *  material color to obtain the final color that contributes
 322.174 +	 *  to the diffuse shading term.
 322.175 +	 */
 322.176 +	C_STRUCT aiColor3D mColorDiffuse;
 322.177 +
 322.178 +	/** Specular color of the light source
 322.179 +	 *
 322.180 +	 *  The specular light color is multiplied with the specular
 322.181 +	 *  material color to obtain the final color that contributes
 322.182 +	 *  to the specular shading term.
 322.183 +	 */
 322.184 +	C_STRUCT aiColor3D mColorSpecular;
 322.185 +
 322.186 +	/** Ambient color of the light source
 322.187 +	 *
 322.188 +	 *  The ambient light color is multiplied with the ambient
 322.189 +	 *  material color to obtain the final color that contributes
 322.190 +	 *  to the ambient shading term. Most renderers will ignore
 322.191 +	 *  this value it, is just a remaining of the fixed-function pipeline
 322.192 +	 *  that is still supported by quite many file formats.
 322.193 +	 */
 322.194 +	C_STRUCT aiColor3D mColorAmbient;
 322.195 +
 322.196 +	/** Inner angle of a spot light's light cone.
 322.197 +	 *
 322.198 +	 *  The spot light has maximum influence on objects inside this
 322.199 +	 *  angle. The angle is given in radians. It is 2PI for point 
 322.200 +	 *  lights and undefined for directional lights.
 322.201 +	 */
 322.202 +	float mAngleInnerCone;
 322.203 +
 322.204 +	/** Outer angle of a spot light's light cone.
 322.205 +	 *
 322.206 +	 *  The spot light does not affect objects outside this angle.
 322.207 +	 *  The angle is given in radians. It is 2PI for point lights and 
 322.208 +	 *  undefined for directional lights. The outer angle must be
 322.209 +	 *  greater than or equal to the inner angle.
 322.210 +	 *  It is assumed that the application uses a smooth
 322.211 +	 *  interpolation between the inner and the outer cone of the
 322.212 +	 *  spot light. 
 322.213 +	 */
 322.214 +	float mAngleOuterCone;
 322.215 +
 322.216 +#ifdef __cplusplus
 322.217 +
 322.218 +	aiLight()
 322.219 +		:	mType                 (aiLightSource_UNDEFINED)
 322.220 +		,	mAttenuationConstant  (0.f)
 322.221 +		,   mAttenuationLinear    (1.f)
 322.222 +		,   mAttenuationQuadratic (0.f)
 322.223 +		,	mAngleInnerCone       ((float)AI_MATH_TWO_PI)
 322.224 +		,	mAngleOuterCone       ((float)AI_MATH_TWO_PI)
 322.225 +	{
 322.226 +	}
 322.227 +
 322.228 +#endif
 322.229 +};
 322.230 +
 322.231 +#ifdef __cplusplus
 322.232 +}
 322.233 +#endif
 322.234 +
 322.235 +
 322.236 +#endif // !! __AI_LIGHT_H_INC__
   323.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   323.2 +++ b/libs/assimp/assimp/material.h	Sat Feb 01 19:58:19 2014 +0200
   323.3 @@ -0,0 +1,1499 @@
   323.4 +/*
   323.5 +---------------------------------------------------------------------------
   323.6 +Open Asset Import Library (assimp)
   323.7 +---------------------------------------------------------------------------
   323.8 +
   323.9 +Copyright (c) 2006-2012, assimp team
  323.10 +
  323.11 +All rights reserved.
  323.12 +
  323.13 +Redistribution and use of this software in source and binary forms, 
  323.14 +with or without modification, are permitted provided that the following 
  323.15 +conditions are met:
  323.16 +
  323.17 +* Redistributions of source code must retain the above
  323.18 +  copyright notice, this list of conditions and the
  323.19 +  following disclaimer.
  323.20 +
  323.21 +* Redistributions in binary form must reproduce the above
  323.22 +  copyright notice, this list of conditions and the
  323.23 +  following disclaimer in the documentation and/or other
  323.24 +  materials provided with the distribution.
  323.25 +
  323.26 +* Neither the name of the assimp team, nor the names of its
  323.27 +  contributors may be used to endorse or promote products
  323.28 +  derived from this software without specific prior
  323.29 +  written permission of the assimp team.
  323.30 +
  323.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  323.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  323.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  323.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  323.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  323.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  323.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  323.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  323.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  323.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  323.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  323.42 +---------------------------------------------------------------------------
  323.43 +*/
  323.44 +
  323.45 +/** @file material.h
  323.46 + *  @brief Defines the material system of the library
  323.47 + */
  323.48 +
  323.49 +#ifndef AI_MATERIAL_H_INC
  323.50 +#define AI_MATERIAL_H_INC
  323.51 +
  323.52 +#include "types.h"
  323.53 +
  323.54 +#ifdef __cplusplus
  323.55 +extern "C" {
  323.56 +#endif
  323.57 +
  323.58 +// Name for default materials (2nd is used if meshes have UV coords)
  323.59 +#define AI_DEFAULT_MATERIAL_NAME          "DefaultMaterial"
  323.60 +
  323.61 +// ---------------------------------------------------------------------------
  323.62 +/** @brief Defines how the Nth texture of a specific type is combined with
  323.63 + *  the result of all previous layers.
  323.64 + *
  323.65 + *  Example (left: key, right: value): <br>
  323.66 + *  @code
  323.67 + *  DiffColor0     - gray
  323.68 + *  DiffTextureOp0 - aiTextureOpMultiply
  323.69 + *  DiffTexture0   - tex1.png
  323.70 + *  DiffTextureOp0 - aiTextureOpAdd
  323.71 + *  DiffTexture1   - tex2.png
  323.72 + *  @endcode
  323.73 + *  Written as equation, the final diffuse term for a specific pixel would be: 
  323.74 + *  @code
  323.75 + *  diffFinal = DiffColor0 * sampleTex(DiffTexture0,UV0) + 
  323.76 + *     sampleTex(DiffTexture1,UV0) * diffContrib;
  323.77 + *  @endcode
  323.78 + *  where 'diffContrib' is the intensity of the incoming light for that pixel.
  323.79 + */
  323.80 +enum aiTextureOp
  323.81 +{
  323.82 +	/** T = T1 * T2 */
  323.83 +	aiTextureOp_Multiply = 0x0,
  323.84 +
  323.85 +	/** T = T1 + T2 */
  323.86 +	aiTextureOp_Add = 0x1,
  323.87 +
  323.88 +	/** T = T1 - T2 */
  323.89 +	aiTextureOp_Subtract = 0x2,
  323.90 +
  323.91 +	/** T = T1 / T2 */
  323.92 +	aiTextureOp_Divide = 0x3,
  323.93 +
  323.94 +	/** T = (T1 + T2) - (T1 * T2) */
  323.95 +	aiTextureOp_SmoothAdd = 0x4,
  323.96 +
  323.97 +	/** T = T1 + (T2-0.5) */
  323.98 +	aiTextureOp_SignedAdd = 0x5,
  323.99 +
 323.100 +
 323.101 +	/** @cond never 
 323.102 +	 *  This value is not used. It forces the compiler to use at least
 323.103 +	 *  32 Bit integers to represent this enum.
 323.104 +	 */
 323.105 +#ifndef SWIG
 323.106 +	_aiTextureOp_Force32Bit = INT_MAX
 323.107 +#endif
 323.108 +	//! @endcond
 323.109 +};
 323.110 +
 323.111 +// ---------------------------------------------------------------------------
 323.112 +/** @brief Defines how UV coordinates outside the [0...1] range are handled.
 323.113 + *
 323.114 + *  Commonly refered to as 'wrapping mode'.
 323.115 + */
 323.116 +enum aiTextureMapMode
 323.117 +{
 323.118 +    /** A texture coordinate u|v is translated to u%1|v%1 
 323.119 +     */
 323.120 +    aiTextureMapMode_Wrap = 0x0,
 323.121 +
 323.122 +    /** Texture coordinates outside [0...1]
 323.123 +     *  are clamped to the nearest valid value.
 323.124 +     */
 323.125 +    aiTextureMapMode_Clamp = 0x1,
 323.126 +
 323.127 +	/** If the texture coordinates for a pixel are outside [0...1]
 323.128 +	 *  the texture is not applied to that pixel
 323.129 +     */
 323.130 +    aiTextureMapMode_Decal = 0x3,
 323.131 +
 323.132 +    /** A texture coordinate u|v becomes u%1|v%1 if (u-(u%1))%2 is zero and
 323.133 +     *  1-(u%1)|1-(v%1) otherwise
 323.134 +     */
 323.135 +    aiTextureMapMode_Mirror = 0x2,
 323.136 +
 323.137 +	 /** @cond never 
 323.138 +	  *  This value is not used. It forces the compiler to use at least
 323.139 +	  *  32 Bit integers to represent this enum.
 323.140 +	  */
 323.141 +#ifndef SWIG
 323.142 +	_aiTextureMapMode_Force32Bit = INT_MAX
 323.143 +#endif
 323.144 +	//! @endcond
 323.145 +};
 323.146 +
 323.147 +// ---------------------------------------------------------------------------
 323.148 +/** @brief Defines how the mapping coords for a texture are generated.
 323.149 + *
 323.150 + *  Real-time applications typically require full UV coordinates, so the use of
 323.151 + *  the aiProcess_GenUVCoords step is highly recommended. It generates proper
 323.152 + *  UV channels for non-UV mapped objects, as long as an accurate description
 323.153 + *  how the mapping should look like (e.g spherical) is given.
 323.154 + *  See the #AI_MATKEY_MAPPING property for more details.
 323.155 + */
 323.156 +enum aiTextureMapping
 323.157 +{
 323.158 +    /** The mapping coordinates are taken from an UV channel.
 323.159 +	 *
 323.160 +	 *  The #AI_MATKEY_UVWSRC key specifies from which UV channel
 323.161 +	 *  the texture coordinates are to be taken from (remember,
 323.162 +	 *  meshes can have more than one UV channel). 
 323.163 +    */
 323.164 +    aiTextureMapping_UV = 0x0,
 323.165 +
 323.166 +	 /** Spherical mapping */
 323.167 +    aiTextureMapping_SPHERE = 0x1,
 323.168 +
 323.169 +	 /** Cylindrical mapping */
 323.170 +    aiTextureMapping_CYLINDER = 0x2,
 323.171 +
 323.172 +	 /** Cubic mapping */
 323.173 +    aiTextureMapping_BOX = 0x3,
 323.174 +
 323.175 +	 /** Planar mapping */
 323.176 +    aiTextureMapping_PLANE = 0x4,
 323.177 +
 323.178 +	 /** Undefined mapping. Have fun. */
 323.179 +    aiTextureMapping_OTHER = 0x5,
 323.180 +
 323.181 +
 323.182 +	 /** @cond never 
 323.183 +	  *  This value is not used. It forces the compiler to use at least
 323.184 +	  *  32 Bit integers to represent this enum.
 323.185 +	  */
 323.186 +#ifndef SWIG
 323.187 +	_aiTextureMapping_Force32Bit = INT_MAX
 323.188 +#endif
 323.189 +	//! @endcond
 323.190 +};
 323.191 +
 323.192 +// ---------------------------------------------------------------------------
 323.193 +/** @brief Defines the purpose of a texture 
 323.194 + *
 323.195 + *  This is a very difficult topic. Different 3D packages support different
 323.196 + *  kinds of textures. For very common texture types, such as bumpmaps, the
 323.197 + *  rendering results depend on implementation details in the rendering 
 323.198 + *  pipelines of these applications. Assimp loads all texture references from
 323.199 + *  the model file and tries to determine which of the predefined texture
 323.200 + *  types below is the best choice to match the original use of the texture
 323.201 + *  as closely as possible.<br>
 323.202 + *  
 323.203 + *  In content pipelines you'll usually define how textures have to be handled,
 323.204 + *  and the artists working on models have to conform to this specification,
 323.205 + *  regardless which 3D tool they're using.
 323.206 + */
 323.207 +enum aiTextureType
 323.208 +{
 323.209 +	/** Dummy value.
 323.210 +	 *
 323.211 +	 *  No texture, but the value to be used as 'texture semantic' 
 323.212 +	 *  (#aiMaterialProperty::mSemantic) for all material properties 
 323.213 +	 *  *not* related to textures.
 323.214 +	 */
 323.215 +	aiTextureType_NONE = 0x0,
 323.216 +
 323.217 +
 323.218 +
 323.219 +    /** The texture is combined with the result of the diffuse
 323.220 +	 *  lighting equation.
 323.221 +     */
 323.222 +    aiTextureType_DIFFUSE = 0x1,
 323.223 +
 323.224 +	/** The texture is combined with the result of the specular
 323.225 +	 *  lighting equation.
 323.226 +     */
 323.227 +    aiTextureType_SPECULAR = 0x2,
 323.228 +
 323.229 +	/** The texture is combined with the result of the ambient
 323.230 +	 *  lighting equation.
 323.231 +     */
 323.232 +    aiTextureType_AMBIENT = 0x3,
 323.233 +
 323.234 +	/** The texture is added to the result of the lighting
 323.235 +	 *  calculation. It isn't influenced by incoming light.
 323.236 +     */
 323.237 +    aiTextureType_EMISSIVE = 0x4,
 323.238 +
 323.239 +	/** The texture is a height map.
 323.240 +	 *
 323.241 +	 *  By convention, higher gray-scale values stand for
 323.242 +	 *  higher elevations from the base height.
 323.243 +     */
 323.244 +    aiTextureType_HEIGHT = 0x5,
 323.245 +
 323.246 +	/** The texture is a (tangent space) normal-map.
 323.247 +	 *
 323.248 +	 *  Again, there are several conventions for tangent-space
 323.249 +	 *  normal maps. Assimp does (intentionally) not 
 323.250 +	 *  distinguish here.
 323.251 +     */
 323.252 +    aiTextureType_NORMALS = 0x6,
 323.253 +
 323.254 +	/** The texture defines the glossiness of the material.
 323.255 +	 *
 323.256 +	 *  The glossiness is in fact the exponent of the specular
 323.257 +	 *  (phong) lighting equation. Usually there is a conversion
 323.258 +	 *  function defined to map the linear color values in the
 323.259 +	 *  texture to a suitable exponent. Have fun.
 323.260 +    */
 323.261 +    aiTextureType_SHININESS = 0x7,
 323.262 +
 323.263 +	/** The texture defines per-pixel opacity.
 323.264 +	 *
 323.265 +	 *  Usually 'white' means opaque and 'black' means 
 323.266 +	 *  'transparency'. Or quite the opposite. Have fun.
 323.267 +    */
 323.268 +    aiTextureType_OPACITY = 0x8,
 323.269 +
 323.270 +	/** Displacement texture
 323.271 +	 *
 323.272 +	 *  The exact purpose and format is application-dependent.
 323.273 +     *  Higher color values stand for higher vertex displacements.
 323.274 +    */
 323.275 +    aiTextureType_DISPLACEMENT = 0x9,
 323.276 +
 323.277 +	/** Lightmap texture (aka Ambient Occlusion)
 323.278 +	 *
 323.279 +	 *  Both 'Lightmaps' and dedicated 'ambient occlusion maps' are
 323.280 +	 *  covered by this material property. The texture contains a
 323.281 +	 *  scaling value for the final color value of a pixel. Its
 323.282 +	 *  intensity is not affected by incoming light.
 323.283 +    */
 323.284 +    aiTextureType_LIGHTMAP = 0xA,
 323.285 +
 323.286 +	/** Reflection texture
 323.287 +	 *
 323.288 +	 * Contains the color of a perfect mirror reflection.
 323.289 +	 * Rarely used, almost never for real-time applications.
 323.290 +    */
 323.291 +    aiTextureType_REFLECTION = 0xB,
 323.292 +
 323.293 +	/** Unknown texture
 323.294 +	 *
 323.295 +	 *  A texture reference that does not match any of the definitions 
 323.296 +	 *  above is considered to be 'unknown'. It is still imported,
 323.297 +	 *  but is excluded from any further postprocessing.
 323.298 +    */
 323.299 +    aiTextureType_UNKNOWN = 0xC,
 323.300 +
 323.301 +
 323.302 +	 /** @cond never 
 323.303 +	  *  This value is not used. It forces the compiler to use at least
 323.304 +	  *  32 Bit integers to represent this enum.
 323.305 +	  */
 323.306 +#ifndef SWIG
 323.307 +	_aiTextureType_Force32Bit = INT_MAX
 323.308 +#endif
 323.309 +	//! @endcond
 323.310 +};
 323.311 +
 323.312 +#define AI_TEXTURE_TYPE_MAX  aiTextureType_UNKNOWN
 323.313 +
 323.314 +// ---------------------------------------------------------------------------
 323.315 +/** @brief Defines all shading models supported by the library
 323.316 + *
 323.317 + *  The list of shading modes has been taken from Blender.
 323.318 + *  See Blender documentation for more information. The API does
 323.319 + *  not distinguish between "specular" and "diffuse" shaders (thus the
 323.320 + *  specular term for diffuse shading models like Oren-Nayar remains
 323.321 + *  undefined). <br>
 323.322 + *  Again, this value is just a hint. Assimp tries to select the shader whose
 323.323 + *  most common implementation matches the original rendering results of the
 323.324 + *  3D modeller which wrote a particular model as closely as possible.
 323.325 + */
 323.326 +enum aiShadingMode
 323.327 +{
 323.328 +    /** Flat shading. Shading is done on per-face base, 
 323.329 +     *  diffuse only. Also known as 'faceted shading'.
 323.330 +     */
 323.331 +    aiShadingMode_Flat = 0x1,
 323.332 +
 323.333 +    /** Simple Gouraud shading. 
 323.334 +     */
 323.335 +    aiShadingMode_Gouraud =	0x2,
 323.336 +
 323.337 +    /** Phong-Shading -
 323.338 +     */
 323.339 +    aiShadingMode_Phong = 0x3,
 323.340 +
 323.341 +    /** Phong-Blinn-Shading
 323.342 +     */
 323.343 +    aiShadingMode_Blinn	= 0x4,
 323.344 +
 323.345 +    /** Toon-Shading per pixel
 323.346 +     *
 323.347 +	 *  Also known as 'comic' shader.
 323.348 +     */
 323.349 +    aiShadingMode_Toon = 0x5,
 323.350 +
 323.351 +    /** OrenNayar-Shading per pixel
 323.352 +     *
 323.353 +     *  Extension to standard Lambertian shading, taking the
 323.354 +     *  roughness of the material into account
 323.355 +     */
 323.356 +    aiShadingMode_OrenNayar = 0x6,
 323.357 +
 323.358 +    /** Minnaert-Shading per pixel
 323.359 +     *
 323.360 +     *  Extension to standard Lambertian shading, taking the
 323.361 +     *  "darkness" of the material into account
 323.362 +     */
 323.363 +    aiShadingMode_Minnaert = 0x7,
 323.364 +
 323.365 +    /** CookTorrance-Shading per pixel
 323.366 +	 *
 323.367 +	 *  Special shader for metallic surfaces.
 323.368 +     */
 323.369 +    aiShadingMode_CookTorrance = 0x8,
 323.370 +
 323.371 +    /** No shading at all. Constant light influence of 1.0.
 323.372 +    */
 323.373 +    aiShadingMode_NoShading = 0x9,
 323.374 +
 323.375 +	 /** Fresnel shading
 323.376 +     */
 323.377 +    aiShadingMode_Fresnel = 0xa,
 323.378 +
 323.379 +
 323.380 +	 /** @cond never 
 323.381 +	  *  This value is not used. It forces the compiler to use at least
 323.382 +	  *  32 Bit integers to represent this enum.
 323.383 +	  */
 323.384 +#ifndef SWIG
 323.385 +	_aiShadingMode_Force32Bit = INT_MAX
 323.386 +#endif
 323.387 +	//! @endcond
 323.388 +};
 323.389 +
 323.390 +
 323.391 +// ---------------------------------------------------------------------------
 323.392 +/** @brief Defines some mixed flags for a particular texture.
 323.393 + *
 323.394 + *  Usually you'll instruct your cg artists how textures have to look like ...
 323.395 + *  and how they will be processed in your application. However, if you use
 323.396 + *  Assimp for completely generic loading purposes you might also need to 
 323.397 + *  process these flags in order to display as many 'unknown' 3D models as 
 323.398 + *  possible correctly.
 323.399 + *
 323.400 + *  This corresponds to the #AI_MATKEY_TEXFLAGS property.
 323.401 +*/
 323.402 +enum aiTextureFlags
 323.403 +{
 323.404 +	/** The texture's color values have to be inverted (componentwise 1-n)
 323.405 +	 */
 323.406 +	aiTextureFlags_Invert = 0x1,
 323.407 +
 323.408 +	/** Explicit request to the application to process the alpha channel
 323.409 +	 *  of the texture.
 323.410 +	 *
 323.411 +	 *  Mutually exclusive with #aiTextureFlags_IgnoreAlpha. These
 323.412 +	 *  flags are set if the library can say for sure that the alpha
 323.413 +	 *  channel is used/is not used. If the model format does not
 323.414 +	 *  define this, it is left to the application to decide whether
 323.415 +	 *  the texture alpha channel - if any - is evaluated or not.
 323.416 +	 */
 323.417 +	aiTextureFlags_UseAlpha = 0x2,
 323.418 +
 323.419 +	/** Explicit request to the application to ignore the alpha channel
 323.420 +	 *  of the texture.
 323.421 +	 *
 323.422 +	 *  Mutually exclusive with #aiTextureFlags_UseAlpha. 
 323.423 +	 */
 323.424 +	aiTextureFlags_IgnoreAlpha = 0x4,
 323.425 +	
 323.426 +	 /** @cond never 
 323.427 +	  *  This value is not used. It forces the compiler to use at least
 323.428 +	  *  32 Bit integers to represent this enum.
 323.429 +	  */
 323.430 +#ifndef SWIG
 323.431 +	  _aiTextureFlags_Force32Bit = INT_MAX
 323.432 +#endif
 323.433 +	//! @endcond
 323.434 +};
 323.435 +
 323.436 +
 323.437 +// ---------------------------------------------------------------------------
 323.438 +/** @brief Defines alpha-blend flags.
 323.439 + *
 323.440 + *  If you're familiar with OpenGL or D3D, these flags aren't new to you.
 323.441 + *  They define *how* the final color value of a pixel is computed, basing
 323.442 + *  on the previous color at that pixel and the new color value from the
 323.443 + *  material.
 323.444 + *  The blend formula is:
 323.445 + *  @code
 323.446 + *    SourceColor * SourceBlend + DestColor * DestBlend
 323.447 + *  @endcode
 323.448 + *  where <DestColor> is the previous color in the framebuffer at this
 323.449 + *  position and <SourceColor> is the material colro before the transparency
 323.450 + *  calculation.<br>
 323.451 + *  This corresponds to the #AI_MATKEY_BLEND_FUNC property.
 323.452 +*/
 323.453 +enum aiBlendMode
 323.454 +{
 323.455 +	/** 
 323.456 +	 *  Formula:
 323.457 +	 *  @code
 323.458 +	 *  SourceColor*SourceAlpha + DestColor*(1-SourceAlpha)
 323.459 +	 *  @endcode
 323.460 +	 */
 323.461 +	aiBlendMode_Default = 0x0,
 323.462 +
 323.463 +	/** Additive blending
 323.464 +	 *
 323.465 +	 *  Formula:
 323.466 +	 *  @code
 323.467 +	 *  SourceColor*1 + DestColor*1
 323.468 +	 *  @endcode
 323.469 +	 */
 323.470 +	aiBlendMode_Additive = 0x1,
 323.471 +
 323.472 +	// we don't need more for the moment, but we might need them
 323.473 +	// in future versions ...
 323.474 +
 323.475 +	 /** @cond never 
 323.476 +	  *  This value is not used. It forces the compiler to use at least
 323.477 +	  *  32 Bit integers to represent this enum.
 323.478 +	  */
 323.479 +#ifndef SWIG
 323.480 +	_aiBlendMode_Force32Bit = INT_MAX
 323.481 +#endif
 323.482 +	//! @endcond
 323.483 +};
 323.484 +
 323.485 +
 323.486 +#include "./Compiler/pushpack1.h"
 323.487 +
 323.488 +// ---------------------------------------------------------------------------
 323.489 +/** @brief Defines how an UV channel is transformed.
 323.490 + *
 323.491 + *  This is just a helper structure for the #AI_MATKEY_UVTRANSFORM key.
 323.492 + *  See its documentation for more details. 
 323.493 + *
 323.494 + *  Typically you'll want to build a matrix of this information. However,
 323.495 + *  we keep separate scaling/translation/rotation values to make it
 323.496 + *  easier to process and optimize UV transformations internally.
 323.497 + */
 323.498 +struct aiUVTransform
 323.499 +{
 323.500 +	/** Translation on the u and v axes. 
 323.501 +	 *
 323.502 +	 *  The default value is (0|0).
 323.503 +	 */
 323.504 +	C_STRUCT aiVector2D mTranslation;
 323.505 +
 323.506 +	/** Scaling on the u and v axes. 
 323.507 +	 *
 323.508 +	 *  The default value is (1|1).
 323.509 +	 */
 323.510 +	C_STRUCT aiVector2D mScaling;
 323.511 +
 323.512 +	/** Rotation - in counter-clockwise direction.
 323.513 +	 *
 323.514 +	 *  The rotation angle is specified in radians. The
 323.515 +	 *  rotation center is 0.5f|0.5f. The default value
 323.516 +     *  0.f.
 323.517 +	 */
 323.518 +	float mRotation;
 323.519 +
 323.520 +
 323.521 +#ifdef __cplusplus
 323.522 +	aiUVTransform()
 323.523 +		:	mScaling	(1.f,1.f)
 323.524 +		,	mRotation	(0.f)
 323.525 +	{
 323.526 +		// nothing to be done here ...
 323.527 +	}
 323.528 +#endif
 323.529 +
 323.530 +} PACK_STRUCT;
 323.531 +
 323.532 +#include "./Compiler/poppack1.h"
 323.533 +
 323.534 +//! @cond AI_DOX_INCLUDE_INTERNAL
 323.535 +// ---------------------------------------------------------------------------
 323.536 +/** @brief A very primitive RTTI system for the contents of material 
 323.537 + *  properties.
 323.538 + */
 323.539 +enum aiPropertyTypeInfo
 323.540 +{
 323.541 +    /** Array of single-precision (32 Bit) floats
 323.542 +	 *
 323.543 +	 *  It is possible to use aiGetMaterialInteger[Array]() (or the C++-API 
 323.544 +	 *  aiMaterial::Get()) to query properties stored in floating-point format. 
 323.545 +	 *  The material system performs the type conversion automatically.
 323.546 +    */
 323.547 +    aiPTI_Float   = 0x1,
 323.548 +
 323.549 +    /** The material property is an aiString.
 323.550 +	 *
 323.551 +	 *  Arrays of strings aren't possible, aiGetMaterialString() (or the 
 323.552 +	 *  C++-API aiMaterial::Get()) *must* be used to query a string property.
 323.553 +    */
 323.554 +    aiPTI_String  = 0x3,
 323.555 +
 323.556 +    /** Array of (32 Bit) integers
 323.557 +	 *
 323.558 +	 *  It is possible to use aiGetMaterialFloat[Array]() (or the C++-API 
 323.559 +	 *  aiMaterial::Get()) to query properties stored in integer format. 
 323.560 +	 *  The material system performs the type conversion automatically.
 323.561 +    */
 323.562 +    aiPTI_Integer = 0x4,
 323.563 +
 323.564 +
 323.565 +    /** Simple binary buffer, content undefined. Not convertible to anything.
 323.566 +    */
 323.567 +    aiPTI_Buffer  = 0x5,
 323.568 +
 323.569 +
 323.570 +	 /** This value is not used. It is just there to force the
 323.571 +	 *  compiler to map this enum to a 32 Bit integer.
 323.572 +	 */
 323.573 +#ifndef SWIG
 323.574 +	 _aiPTI_Force32Bit = INT_MAX
 323.575 +#endif
 323.576 +};
 323.577 +
 323.578 +// ---------------------------------------------------------------------------
 323.579 +/** @brief Data structure for a single material property
 323.580 + *
 323.581 + *  As an user, you'll probably never need to deal with this data structure.
 323.582 + *  Just use the provided aiGetMaterialXXX() or aiMaterial::Get() family
 323.583 + *  of functions to query material properties easily. Processing them 
 323.584 + *  manually is faster, but it is not the recommended way. It isn't worth
 323.585 + *  the effort. <br>
 323.586 + *  Material property names follow a simple scheme:
 323.587 + *  @code
 323.588 + *    $<name>
 323.589 + *    ?<name>
 323.590 + *       A public property, there must be corresponding AI_MATKEY_XXX define
 323.591 + *       2nd: Public, but ignored by the #aiProcess_RemoveRedundantMaterials 
 323.592 + *       post-processing step.
 323.593 + *    ~<name>
 323.594 + *       A temporary property for internal use. 
 323.595 + *  @endcode
 323.596 + *  @see aiMaterial
 323.597 + */
 323.598 +struct aiMaterialProperty
 323.599 +{
 323.600 +    /** Specifies the name of the property (key)
 323.601 +     *  Keys are generally case insensitive. 
 323.602 +     */
 323.603 +    C_STRUCT aiString mKey;
 323.604 +
 323.605 +	/** Textures: Specifies their exact usage semantic.
 323.606 +	 * For non-texture properties, this member is always 0 
 323.607 +	 * (or, better-said, #aiTextureType_NONE).
 323.608 +	 */
 323.609 +	unsigned int mSemantic;
 323.610 +
 323.611 +	/** Textures: Specifies the index of the texture.
 323.612 +	 *  For non-texture properties, this member is always 0.
 323.613 +	 */
 323.614 +	unsigned int mIndex;
 323.615 +
 323.616 +    /**	Size of the buffer mData is pointing to, in bytes.
 323.617 +	 *  This value may not be 0.
 323.618 +     */
 323.619 +    unsigned int mDataLength;
 323.620 +
 323.621 +    /** Type information for the property.
 323.622 +     *
 323.623 +     * Defines the data layout inside the data buffer. This is used
 323.624 +	 * by the library internally to perform debug checks and to 
 323.625 +	 * utilize proper type conversions. 
 323.626 +	 * (It's probably a hacky solution, but it works.)
 323.627 +     */
 323.628 +    C_ENUM aiPropertyTypeInfo mType;
 323.629 +
 323.630 +    /**	Binary buffer to hold the property's value.
 323.631 +     * The size of the buffer is always mDataLength.
 323.632 +     */
 323.633 +    char* mData;
 323.634 +
 323.635 +#ifdef __cplusplus
 323.636 +
 323.637 +	aiMaterialProperty()
 323.638 +		: mSemantic( 0 )
 323.639 +		, mIndex( 0 )
 323.640 +		, mDataLength( 0 )
 323.641 +		, mType( aiPTI_Float )
 323.642 +		, mData( NULL )
 323.643 +	{
 323.644 +	}
 323.645 +
 323.646 +	~aiMaterialProperty()	{
 323.647 +		delete[] mData;
 323.648 +	}
 323.649 +
 323.650 +#endif
 323.651 +};
 323.652 +//! @endcond
 323.653 +
 323.654 +#ifdef __cplusplus
 323.655 +} // We need to leave the "C" block here to allow template member functions
 323.656 +#endif
 323.657 +
 323.658 +// ---------------------------------------------------------------------------
 323.659 +/** @brief Data structure for a material
 323.660 +*
 323.661 +*  Material data is stored using a key-value structure. A single key-value
 323.662 +*  pair is called a 'material property'. C++ users should use the provided
 323.663 +*  member functions of aiMaterial to process material properties, C users
 323.664 +*  have to stick with the aiMaterialGetXXX family of unbound functions.
 323.665 +*  The library defines a set of standard keys (AI_MATKEY_XXX).
 323.666 +*/
 323.667 +#ifdef __cplusplus
 323.668 +struct ASSIMP_API aiMaterial
 323.669 +#else
 323.670 +struct aiMaterial
 323.671 +#endif
 323.672 +{
 323.673 +
 323.674 +#ifdef __cplusplus
 323.675 +
 323.676 +public:
 323.677 +
 323.678 +	aiMaterial();
 323.679 +	~aiMaterial();
 323.680 +
 323.681 +	// -------------------------------------------------------------------
 323.682 +    /** @brief Retrieve an array of Type values with a specific key 
 323.683 +     *  from the material
 323.684 +     *
 323.685 +     * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
 323.686 +     * @param type .. set by AI_MATKEY_XXX
 323.687 +     * @param idx .. set by AI_MATKEY_XXX
 323.688 +     * @param pOut Pointer to a buffer to receive the result. 
 323.689 +     * @param pMax Specifies the size of the given buffer, in Type's.
 323.690 +     * Receives the number of values (not bytes!) read. 
 323.691 +     * NULL is a valid value for this parameter.
 323.692 +     */
 323.693 +    template <typename Type>
 323.694 +    aiReturn Get(const char* pKey,unsigned int type,
 323.695 +		unsigned int idx, Type* pOut, unsigned int* pMax) const;
 323.696 +
 323.697 +    // -------------------------------------------------------------------
 323.698 +    /** @brief Retrieve a Type value with a specific key 
 323.699 +     *  from the material
 323.700 +	 *
 323.701 +	 * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
 323.702 +    * @param type Specifies the type of the texture to be retrieved (
 323.703 +    *    e.g. diffuse, specular, height map ...)
 323.704 +    * @param idx Index of the texture to be retrieved.
 323.705 +	 * @param pOut Reference to receive the output value
 323.706 +	 */
 323.707 +	template <typename Type>
 323.708 +	aiReturn Get(const char* pKey,unsigned int type,
 323.709 +		unsigned int idx,Type& pOut) const;
 323.710 +
 323.711 +	// -------------------------------------------------------------------
 323.712 +	/** Get the number of textures for a particular texture type.
 323.713 +	 *  @param type Texture type to check for
 323.714 +	 *  @return Number of textures for this type.
 323.715 +	 *  @note A texture can be easily queried using #GetTexture() */
 323.716 +	unsigned int GetTextureCount(aiTextureType type) const;
 323.717 +
 323.718 +	// -------------------------------------------------------------------
 323.719 +	/** Helper function to get all parameters pertaining to a 
 323.720 +	 *  particular texture slot from a material.
 323.721 +	*
 323.722 +	*  This function is provided just for convenience, you could also
 323.723 +	*  read the single material properties manually.
 323.724 +	*  @param type Specifies the type of the texture to be retrieved (
 323.725 +	*    e.g. diffuse, specular, height map ...)
 323.726 +	*  @param index Index of the texture to be retrieved. The function fails
 323.727 +	*    if there is no texture of that type with this index. 
 323.728 +	*    #GetTextureCount() can be used to determine the number of textures
 323.729 +	*    per texture type.
 323.730 +	*  @param path Receives the path to the texture.
 323.731 +	*	 NULL is a valid value.
 323.732 +   *  @param mapping The texture mapping.
 323.733 +   *		NULL is allowed as value.
 323.734 +	*  @param uvindex Receives the UV index of the texture. 
 323.735 +	*    NULL is a valid value.
 323.736 +	*  @param blend Receives the blend factor for the texture
 323.737 +	*	 NULL is a valid value.
 323.738 +	*  @param op Receives the texture operation to be performed between
 323.739 +	*	 this texture and the previous texture. NULL is allowed as value.
 323.740 +	*  @param mapmode Receives the mapping modes to be used for the texture.
 323.741 +	*    The parameter may be NULL but if it is a valid pointer it MUST
 323.742 +	*    point to an array of 3 aiTextureMapMode's (one for each
 323.743 +	*    axis: UVW order (=XYZ)). 
 323.744 +	*/
 323.745 +	// -------------------------------------------------------------------
 323.746 +	aiReturn GetTexture(aiTextureType type,
 323.747 +		unsigned int  index,
 323.748 +		C_STRUCT aiString* path,
 323.749 +		aiTextureMapping* mapping	= NULL,
 323.750 +		unsigned int* uvindex		= NULL,
 323.751 +		float* blend				   = NULL,
 323.752 +		aiTextureOp* op				= NULL,
 323.753 +		aiTextureMapMode* mapmode	= NULL) const; 
 323.754 +
 323.755 +
 323.756 +	// Setters
 323.757 +
 323.758 +
 323.759 +	// ------------------------------------------------------------------------------
 323.760 +	/** @brief Add a property with a given key and type info to the material
 323.761 +	 *  structure 
 323.762 +	 *
 323.763 +	 *  @param pInput Pointer to input data
 323.764 +	 *  @param pSizeInBytes Size of input data
 323.765 +	 *  @param pKey Key/Usage of the property (AI_MATKEY_XXX)
 323.766 +	 *  @param type Set by the AI_MATKEY_XXX macro
 323.767 +	 *  @param index Set by the AI_MATKEY_XXX macro
 323.768 +	 *  @param pType Type information hint */
 323.769 +	aiReturn AddBinaryProperty (const void* pInput,
 323.770 +		unsigned int pSizeInBytes,
 323.771 +		const char* pKey,
 323.772 +		unsigned int type ,
 323.773 +		unsigned int index ,
 323.774 +		aiPropertyTypeInfo pType);
 323.775 +
 323.776 +	// ------------------------------------------------------------------------------
 323.777 +	/** @brief Add a string property with a given key and type info to the 
 323.778 +	 *  material structure 
 323.779 +	 *
 323.780 +	 *  @param pInput Input string
 323.781 +	 *  @param pKey Key/Usage of the property (AI_MATKEY_XXX)
 323.782 +	 *  @param type Set by the AI_MATKEY_XXX macro
 323.783 +	 *  @param index Set by the AI_MATKEY_XXX macro */
 323.784 +	aiReturn AddProperty (const aiString* pInput,
 323.785 +		const char* pKey,
 323.786 +		unsigned int type  = 0,
 323.787 +		unsigned int index = 0);
 323.788 +
 323.789 +	// ------------------------------------------------------------------------------
 323.790 +	/** @brief Add a property with a given key to the material structure 
 323.791 +	 *  @param pInput Pointer to the input data
 323.792 +	 *  @param pNumValues Number of values in the array
 323.793 +	 *  @param pKey Key/Usage of the property (AI_MATKEY_XXX)
 323.794 +	 *  @param type Set by the AI_MATKEY_XXX macro
 323.795 +	 *  @param index Set by the AI_MATKEY_XXX macro  */
 323.796 +	template<class TYPE>
 323.797 +	aiReturn AddProperty (const TYPE* pInput,
 323.798 +		unsigned int pNumValues,
 323.799 +		const char* pKey,
 323.800 +		unsigned int type  = 0,
 323.801 +		unsigned int index = 0);
 323.802 +
 323.803 +	// ------------------------------------------------------------------------------
 323.804 +	/** @brief Remove a given key from the list.
 323.805 +	 *
 323.806 +	 *  The function fails if the key isn't found
 323.807 +	 *  @param pKey Key to be deleted */
 323.808 +	aiReturn RemoveProperty (const char* pKey,
 323.809 +		unsigned int type  = 0,
 323.810 +		unsigned int index = 0);
 323.811 +
 323.812 +	// ------------------------------------------------------------------------------
 323.813 +	/** @brief Removes all properties from the material.
 323.814 +	 *
 323.815 +	 *  The data array remains allocated so adding new properties is quite fast.  */
 323.816 +	void Clear();
 323.817 +
 323.818 +	// ------------------------------------------------------------------------------
 323.819 +	/** Copy the property list of a material
 323.820 +	 *  @param pcDest Destination material
 323.821 +	 *  @param pcSrc Source material
 323.822 +	 */
 323.823 +	static void CopyPropertyList(aiMaterial* pcDest, 
 323.824 +		const aiMaterial* pcSrc);
 323.825 +
 323.826 +
 323.827 +#endif
 323.828 +
 323.829 +    /** List of all material properties loaded. */
 323.830 +    C_STRUCT aiMaterialProperty** mProperties;
 323.831 +
 323.832 +    /** Number of properties in the data base */
 323.833 +    unsigned int mNumProperties;
 323.834 +
 323.835 +	 /** Storage allocated */
 323.836 +    unsigned int mNumAllocated;
 323.837 +};
 323.838 +
 323.839 +// Go back to extern "C" again
 323.840 +#ifdef __cplusplus
 323.841 +extern "C" {
 323.842 +#endif
 323.843 +
 323.844 +// ---------------------------------------------------------------------------
 323.845 +#define AI_MATKEY_NAME "?mat.name",0,0
 323.846 +#define AI_MATKEY_TWOSIDED "$mat.twosided",0,0
 323.847 +#define AI_MATKEY_SHADING_MODEL "$mat.shadingm",0,0
 323.848 +#define AI_MATKEY_ENABLE_WIREFRAME "$mat.wireframe",0,0
 323.849 +#define AI_MATKEY_BLEND_FUNC "$mat.blend",0,0
 323.850 +#define AI_MATKEY_OPACITY "$mat.opacity",0,0
 323.851 +#define AI_MATKEY_BUMPSCALING "$mat.bumpscaling",0,0
 323.852 +#define AI_MATKEY_SHININESS "$mat.shininess",0,0
 323.853 +#define AI_MATKEY_REFLECTIVITY "$mat.reflectivity",0,0
 323.854 +#define AI_MATKEY_SHININESS_STRENGTH "$mat.shinpercent",0,0
 323.855 +#define AI_MATKEY_REFRACTI "$mat.refracti",0,0
 323.856 +#define AI_MATKEY_COLOR_DIFFUSE "$clr.diffuse",0,0
 323.857 +#define AI_MATKEY_COLOR_AMBIENT "$clr.ambient",0,0
 323.858 +#define AI_MATKEY_COLOR_SPECULAR "$clr.specular",0,0
 323.859 +#define AI_MATKEY_COLOR_EMISSIVE "$clr.emissive",0,0
 323.860 +#define AI_MATKEY_COLOR_TRANSPARENT "$clr.transparent",0,0
 323.861 +#define AI_MATKEY_COLOR_REFLECTIVE "$clr.reflective",0,0
 323.862 +#define AI_MATKEY_GLOBAL_BACKGROUND_IMAGE "?bg.global",0,0
 323.863 +
 323.864 +// ---------------------------------------------------------------------------
 323.865 +// Pure key names for all texture-related properties
 323.866 +//! @cond MATS_DOC_FULL
 323.867 +#define _AI_MATKEY_TEXTURE_BASE			"$tex.file"
 323.868 +#define _AI_MATKEY_UVWSRC_BASE			"$tex.uvwsrc"
 323.869 +#define _AI_MATKEY_TEXOP_BASE			"$tex.op"
 323.870 +#define _AI_MATKEY_MAPPING_BASE			"$tex.mapping"
 323.871 +#define _AI_MATKEY_TEXBLEND_BASE		"$tex.blend"
 323.872 +#define _AI_MATKEY_MAPPINGMODE_U_BASE	"$tex.mapmodeu"
 323.873 +#define _AI_MATKEY_MAPPINGMODE_V_BASE	"$tex.mapmodev"
 323.874 +#define _AI_MATKEY_TEXMAP_AXIS_BASE		"$tex.mapaxis"
 323.875 +#define _AI_MATKEY_UVTRANSFORM_BASE		"$tex.uvtrafo"
 323.876 +#define _AI_MATKEY_TEXFLAGS_BASE		"$tex.flags"
 323.877 +//! @endcond
 323.878 +
 323.879 +// ---------------------------------------------------------------------------
 323.880 +#define AI_MATKEY_TEXTURE(type, N) _AI_MATKEY_TEXTURE_BASE,type,N
 323.881 +
 323.882 +// For backward compatibility and simplicity
 323.883 +//! @cond MATS_DOC_FULL
 323.884 +#define AI_MATKEY_TEXTURE_DIFFUSE(N)	\
 323.885 +	AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE,N)
 323.886 +
 323.887 +#define AI_MATKEY_TEXTURE_SPECULAR(N)	\
 323.888 +	AI_MATKEY_TEXTURE(aiTextureType_SPECULAR,N)
 323.889 +
 323.890 +#define AI_MATKEY_TEXTURE_AMBIENT(N)	\
 323.891 +	AI_MATKEY_TEXTURE(aiTextureType_AMBIENT,N)
 323.892 +
 323.893 +#define AI_MATKEY_TEXTURE_EMISSIVE(N)	\
 323.894 +	AI_MATKEY_TEXTURE(aiTextureType_EMISSIVE,N)
 323.895 +
 323.896 +#define AI_MATKEY_TEXTURE_NORMALS(N)	\
 323.897 +	AI_MATKEY_TEXTURE(aiTextureType_NORMALS,N)
 323.898 +
 323.899 +#define AI_MATKEY_TEXTURE_HEIGHT(N)	\
 323.900 +	AI_MATKEY_TEXTURE(aiTextureType_HEIGHT,N)
 323.901 +
 323.902 +#define AI_MATKEY_TEXTURE_SHININESS(N)	\
 323.903 +	AI_MATKEY_TEXTURE(aiTextureType_SHININESS,N)
 323.904 +
 323.905 +#define AI_MATKEY_TEXTURE_OPACITY(N)	\
 323.906 +	AI_MATKEY_TEXTURE(aiTextureType_OPACITY,N)
 323.907 +
 323.908 +#define AI_MATKEY_TEXTURE_DISPLACEMENT(N)	\
 323.909 +	AI_MATKEY_TEXTURE(aiTextureType_DISPLACEMENT,N)
 323.910 +
 323.911 +#define AI_MATKEY_TEXTURE_LIGHTMAP(N)	\
 323.912 +	AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP,N)
 323.913 +
 323.914 +#define AI_MATKEY_TEXTURE_REFLECTION(N)	\
 323.915 +	AI_MATKEY_TEXTURE(aiTextureType_REFLECTION,N)
 323.916 +
 323.917 +//! @endcond
 323.918 +
 323.919 +// ---------------------------------------------------------------------------
 323.920 +#define AI_MATKEY_UVWSRC(type, N) _AI_MATKEY_UVWSRC_BASE,type,N
 323.921 +
 323.922 +// For backward compatibility and simplicity
 323.923 +//! @cond MATS_DOC_FULL
 323.924 +#define AI_MATKEY_UVWSRC_DIFFUSE(N)	\
 323.925 +	AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE,N)
 323.926 +
 323.927 +#define AI_MATKEY_UVWSRC_SPECULAR(N)	\
 323.928 +	AI_MATKEY_UVWSRC(aiTextureType_SPECULAR,N)
 323.929 +
 323.930 +#define AI_MATKEY_UVWSRC_AMBIENT(N)	\
 323.931 +	AI_MATKEY_UVWSRC(aiTextureType_AMBIENT,N)
 323.932 +
 323.933 +#define AI_MATKEY_UVWSRC_EMISSIVE(N)	\
 323.934 +	AI_MATKEY_UVWSRC(aiTextureType_EMISSIVE,N)
 323.935 +
 323.936 +#define AI_MATKEY_UVWSRC_NORMALS(N)	\
 323.937 +	AI_MATKEY_UVWSRC(aiTextureType_NORMALS,N)
 323.938 +
 323.939 +#define AI_MATKEY_UVWSRC_HEIGHT(N)	\
 323.940 +	AI_MATKEY_UVWSRC(aiTextureType_HEIGHT,N)
 323.941 +
 323.942 +#define AI_MATKEY_UVWSRC_SHININESS(N)	\
 323.943 +	AI_MATKEY_UVWSRC(aiTextureType_SHININESS,N)
 323.944 +
 323.945 +#define AI_MATKEY_UVWSRC_OPACITY(N)	\
 323.946 +	AI_MATKEY_UVWSRC(aiTextureType_OPACITY,N)
 323.947 +
 323.948 +#define AI_MATKEY_UVWSRC_DISPLACEMENT(N)	\
 323.949 +	AI_MATKEY_UVWSRC(aiTextureType_DISPLACEMENT,N)
 323.950 +
 323.951 +#define AI_MATKEY_UVWSRC_LIGHTMAP(N)	\
 323.952 +	AI_MATKEY_UVWSRC(aiTextureType_LIGHTMAP,N)
 323.953 +
 323.954 +#define AI_MATKEY_UVWSRC_REFLECTION(N)	\
 323.955 +	AI_MATKEY_UVWSRC(aiTextureType_REFLECTION,N)
 323.956 +
 323.957 +//! @endcond
 323.958 +// ---------------------------------------------------------------------------
 323.959 +#define AI_MATKEY_TEXOP(type, N) _AI_MATKEY_TEXOP_BASE,type,N
 323.960 +
 323.961 +// For backward compatibility and simplicity
 323.962 +//! @cond MATS_DOC_FULL
 323.963 +#define AI_MATKEY_TEXOP_DIFFUSE(N)	\
 323.964 +	AI_MATKEY_TEXOP(aiTextureType_DIFFUSE,N)
 323.965 +
 323.966 +#define AI_MATKEY_TEXOP_SPECULAR(N)	\
 323.967 +	AI_MATKEY_TEXOP(aiTextureType_SPECULAR,N)
 323.968 +
 323.969 +#define AI_MATKEY_TEXOP_AMBIENT(N)	\
 323.970 +	AI_MATKEY_TEXOP(aiTextureType_AMBIENT,N)
 323.971 +
 323.972 +#define AI_MATKEY_TEXOP_EMISSIVE(N)	\
 323.973 +	AI_MATKEY_TEXOP(aiTextureType_EMISSIVE,N)
 323.974 +
 323.975 +#define AI_MATKEY_TEXOP_NORMALS(N)	\
 323.976 +	AI_MATKEY_TEXOP(aiTextureType_NORMALS,N)
 323.977 +
 323.978 +#define AI_MATKEY_TEXOP_HEIGHT(N)	\
 323.979 +	AI_MATKEY_TEXOP(aiTextureType_HEIGHT,N)
 323.980 +
 323.981 +#define AI_MATKEY_TEXOP_SHININESS(N)	\
 323.982 +	AI_MATKEY_TEXOP(aiTextureType_SHININESS,N)
 323.983 +
 323.984 +#define AI_MATKEY_TEXOP_OPACITY(N)	\
 323.985 +	AI_MATKEY_TEXOP(aiTextureType_OPACITY,N)
 323.986 +
 323.987 +#define AI_MATKEY_TEXOP_DISPLACEMENT(N)	\
 323.988 +	AI_MATKEY_TEXOP(aiTextureType_DISPLACEMENT,N)
 323.989 +
 323.990 +#define AI_MATKEY_TEXOP_LIGHTMAP(N)	\
 323.991 +	AI_MATKEY_TEXOP(aiTextureType_LIGHTMAP,N)
 323.992 +
 323.993 +#define AI_MATKEY_TEXOP_REFLECTION(N)	\
 323.994 +	AI_MATKEY_TEXOP(aiTextureType_REFLECTION,N)
 323.995 +
 323.996 +//! @endcond
 323.997 +// ---------------------------------------------------------------------------
 323.998 +#define AI_MATKEY_MAPPING(type, N) _AI_MATKEY_MAPPING_BASE,type,N
 323.999 +
323.1000 +// For backward compatibility and simplicity
323.1001 +//! @cond MATS_DOC_FULL
323.1002 +#define AI_MATKEY_MAPPING_DIFFUSE(N)	\
323.1003 +	AI_MATKEY_MAPPING(aiTextureType_DIFFUSE,N)
323.1004 +
323.1005 +#define AI_MATKEY_MAPPING_SPECULAR(N)	\
323.1006 +	AI_MATKEY_MAPPING(aiTextureType_SPECULAR,N)
323.1007 +
323.1008 +#define AI_MATKEY_MAPPING_AMBIENT(N)	\
323.1009 +	AI_MATKEY_MAPPING(aiTextureType_AMBIENT,N)
323.1010 +
323.1011 +#define AI_MATKEY_MAPPING_EMISSIVE(N)	\
323.1012 +	AI_MATKEY_MAPPING(aiTextureType_EMISSIVE,N)
323.1013 +
323.1014 +#define AI_MATKEY_MAPPING_NORMALS(N)	\
323.1015 +	AI_MATKEY_MAPPING(aiTextureType_NORMALS,N)
323.1016 +
323.1017 +#define AI_MATKEY_MAPPING_HEIGHT(N)	\
323.1018 +	AI_MATKEY_MAPPING(aiTextureType_HEIGHT,N)
323.1019 +
323.1020 +#define AI_MATKEY_MAPPING_SHININESS(N)	\
323.1021 +	AI_MATKEY_MAPPING(aiTextureType_SHININESS,N)
323.1022 +
323.1023 +#define AI_MATKEY_MAPPING_OPACITY(N)	\
323.1024 +	AI_MATKEY_MAPPING(aiTextureType_OPACITY,N)
323.1025 +
323.1026 +#define AI_MATKEY_MAPPING_DISPLACEMENT(N)	\
323.1027 +	AI_MATKEY_MAPPING(aiTextureType_DISPLACEMENT,N)
323.1028 +
323.1029 +#define AI_MATKEY_MAPPING_LIGHTMAP(N)	\
323.1030 +	AI_MATKEY_MAPPING(aiTextureType_LIGHTMAP,N)
323.1031 +
323.1032 +#define AI_MATKEY_MAPPING_REFLECTION(N)	\
323.1033 +	AI_MATKEY_MAPPING(aiTextureType_REFLECTION,N)
323.1034 +
323.1035 +//! @endcond
323.1036 +// ---------------------------------------------------------------------------
323.1037 +#define AI_MATKEY_TEXBLEND(type, N) _AI_MATKEY_TEXBLEND_BASE,type,N
323.1038 +
323.1039 +// For backward compatibility and simplicity
323.1040 +//! @cond MATS_DOC_FULL
323.1041 +#define AI_MATKEY_TEXBLEND_DIFFUSE(N)	\
323.1042 +	AI_MATKEY_TEXBLEND(aiTextureType_DIFFUSE,N)
323.1043 +
323.1044 +#define AI_MATKEY_TEXBLEND_SPECULAR(N)	\
323.1045 +	AI_MATKEY_TEXBLEND(aiTextureType_SPECULAR,N)
323.1046 +
323.1047 +#define AI_MATKEY_TEXBLEND_AMBIENT(N)	\
323.1048 +	AI_MATKEY_TEXBLEND(aiTextureType_AMBIENT,N)
323.1049 +
323.1050 +#define AI_MATKEY_TEXBLEND_EMISSIVE(N)	\
323.1051 +	AI_MATKEY_TEXBLEND(aiTextureType_EMISSIVE,N)
323.1052 +
323.1053 +#define AI_MATKEY_TEXBLEND_NORMALS(N)	\
323.1054 +	AI_MATKEY_TEXBLEND(aiTextureType_NORMALS,N)
323.1055 +
323.1056 +#define AI_MATKEY_TEXBLEND_HEIGHT(N)	\
323.1057 +	AI_MATKEY_TEXBLEND(aiTextureType_HEIGHT,N)
323.1058 +
323.1059 +#define AI_MATKEY_TEXBLEND_SHININESS(N)	\
323.1060 +	AI_MATKEY_TEXBLEND(aiTextureType_SHININESS,N)
323.1061 +
323.1062 +#define AI_MATKEY_TEXBLEND_OPACITY(N)	\
323.1063 +	AI_MATKEY_TEXBLEND(aiTextureType_OPACITY,N)
323.1064 +
323.1065 +#define AI_MATKEY_TEXBLEND_DISPLACEMENT(N)	\
323.1066 +	AI_MATKEY_TEXBLEND(aiTextureType_DISPLACEMENT,N)
323.1067 +
323.1068 +#define AI_MATKEY_TEXBLEND_LIGHTMAP(N)	\
323.1069 +	AI_MATKEY_TEXBLEND(aiTextureType_LIGHTMAP,N)
323.1070 +
323.1071 +#define AI_MATKEY_TEXBLEND_REFLECTION(N)	\
323.1072 +	AI_MATKEY_TEXBLEND(aiTextureType_REFLECTION,N)
323.1073 +
323.1074 +//! @endcond
323.1075 +// ---------------------------------------------------------------------------
323.1076 +#define AI_MATKEY_MAPPINGMODE_U(type, N) _AI_MATKEY_MAPPINGMODE_U_BASE,type,N
323.1077 +
323.1078 +// For backward compatibility and simplicity
323.1079 +//! @cond MATS_DOC_FULL
323.1080 +#define AI_MATKEY_MAPPINGMODE_U_DIFFUSE(N)	\
323.1081 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_DIFFUSE,N)
323.1082 +
323.1083 +#define AI_MATKEY_MAPPINGMODE_U_SPECULAR(N)	\
323.1084 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_SPECULAR,N)
323.1085 +
323.1086 +#define AI_MATKEY_MAPPINGMODE_U_AMBIENT(N)	\
323.1087 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_AMBIENT,N)
323.1088 +
323.1089 +#define AI_MATKEY_MAPPINGMODE_U_EMISSIVE(N)	\
323.1090 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_EMISSIVE,N)
323.1091 +
323.1092 +#define AI_MATKEY_MAPPINGMODE_U_NORMALS(N)	\
323.1093 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_NORMALS,N)
323.1094 +
323.1095 +#define AI_MATKEY_MAPPINGMODE_U_HEIGHT(N)	\
323.1096 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_HEIGHT,N)
323.1097 +
323.1098 +#define AI_MATKEY_MAPPINGMODE_U_SHININESS(N)	\
323.1099 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_SHININESS,N)
323.1100 +
323.1101 +#define AI_MATKEY_MAPPINGMODE_U_OPACITY(N)	\
323.1102 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_OPACITY,N)
323.1103 +
323.1104 +#define AI_MATKEY_MAPPINGMODE_U_DISPLACEMENT(N)	\
323.1105 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_DISPLACEMENT,N)
323.1106 +
323.1107 +#define AI_MATKEY_MAPPINGMODE_U_LIGHTMAP(N)	\
323.1108 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_LIGHTMAP,N)
323.1109 +
323.1110 +#define AI_MATKEY_MAPPINGMODE_U_REFLECTION(N)	\
323.1111 +	AI_MATKEY_MAPPINGMODE_U(aiTextureType_REFLECTION,N)
323.1112 +
323.1113 +//! @endcond
323.1114 +// ---------------------------------------------------------------------------
323.1115 +#define AI_MATKEY_MAPPINGMODE_V(type, N) _AI_MATKEY_MAPPINGMODE_V_BASE,type,N
323.1116 +
323.1117 +// For backward compatibility and simplicity
323.1118 +//! @cond MATS_DOC_FULL
323.1119 +#define AI_MATKEY_MAPPINGMODE_V_DIFFUSE(N)	\
323.1120 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_DIFFUSE,N)
323.1121 +
323.1122 +#define AI_MATKEY_MAPPINGMODE_V_SPECULAR(N)	\
323.1123 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_SPECULAR,N)
323.1124 +
323.1125 +#define AI_MATKEY_MAPPINGMODE_V_AMBIENT(N)	\
323.1126 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_AMBIENT,N)
323.1127 +
323.1128 +#define AI_MATKEY_MAPPINGMODE_V_EMISSIVE(N)	\
323.1129 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_EMISSIVE,N)
323.1130 +
323.1131 +#define AI_MATKEY_MAPPINGMODE_V_NORMALS(N)	\
323.1132 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_NORMALS,N)
323.1133 +
323.1134 +#define AI_MATKEY_MAPPINGMODE_V_HEIGHT(N)	\
323.1135 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_HEIGHT,N)
323.1136 +
323.1137 +#define AI_MATKEY_MAPPINGMODE_V_SHININESS(N)	\
323.1138 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_SHININESS,N)
323.1139 +
323.1140 +#define AI_MATKEY_MAPPINGMODE_V_OPACITY(N)	\
323.1141 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_OPACITY,N)
323.1142 +
323.1143 +#define AI_MATKEY_MAPPINGMODE_V_DISPLACEMENT(N)	\
323.1144 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_DISPLACEMENT,N)
323.1145 +
323.1146 +#define AI_MATKEY_MAPPINGMODE_V_LIGHTMAP(N)	\
323.1147 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_LIGHTMAP,N)
323.1148 +
323.1149 +#define AI_MATKEY_MAPPINGMODE_V_REFLECTION(N)	\
323.1150 +	AI_MATKEY_MAPPINGMODE_V(aiTextureType_REFLECTION,N)
323.1151 +
323.1152 +//! @endcond
323.1153 +// ---------------------------------------------------------------------------
323.1154 +#define AI_MATKEY_TEXMAP_AXIS(type, N) _AI_MATKEY_TEXMAP_AXIS_BASE,type,N
323.1155 +
323.1156 +// For backward compatibility and simplicity
323.1157 +//! @cond MATS_DOC_FULL
323.1158 +#define AI_MATKEY_TEXMAP_AXIS_DIFFUSE(N)	\
323.1159 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_DIFFUSE,N)
323.1160 +
323.1161 +#define AI_MATKEY_TEXMAP_AXIS_SPECULAR(N)	\
323.1162 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_SPECULAR,N)
323.1163 +
323.1164 +#define AI_MATKEY_TEXMAP_AXIS_AMBIENT(N)	\
323.1165 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_AMBIENT,N)
323.1166 +
323.1167 +#define AI_MATKEY_TEXMAP_AXIS_EMISSIVE(N)	\
323.1168 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_EMISSIVE,N)
323.1169 +
323.1170 +#define AI_MATKEY_TEXMAP_AXIS_NORMALS(N)	\
323.1171 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_NORMALS,N)
323.1172 +
323.1173 +#define AI_MATKEY_TEXMAP_AXIS_HEIGHT(N)	\
323.1174 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_HEIGHT,N)
323.1175 +
323.1176 +#define AI_MATKEY_TEXMAP_AXIS_SHININESS(N)	\
323.1177 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_SHININESS,N)
323.1178 +
323.1179 +#define AI_MATKEY_TEXMAP_AXIS_OPACITY(N)	\
323.1180 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_OPACITY,N)
323.1181 +
323.1182 +#define AI_MATKEY_TEXMAP_AXIS_DISPLACEMENT(N)	\
323.1183 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_DISPLACEMENT,N)
323.1184 +
323.1185 +#define AI_MATKEY_TEXMAP_AXIS_LIGHTMAP(N)	\
323.1186 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_LIGHTMAP,N)
323.1187 +
323.1188 +#define AI_MATKEY_TEXMAP_AXIS_REFLECTION(N)	\
323.1189 +	AI_MATKEY_TEXMAP_AXIS(aiTextureType_REFLECTION,N)
323.1190 +
323.1191 +//! @endcond
323.1192 +// ---------------------------------------------------------------------------
323.1193 +#define AI_MATKEY_UVTRANSFORM(type, N) _AI_MATKEY_UVTRANSFORM_BASE,type,N
323.1194 +
323.1195 +// For backward compatibility and simplicity
323.1196 +//! @cond MATS_DOC_FULL
323.1197 +#define AI_MATKEY_UVTRANSFORM_DIFFUSE(N)	\
323.1198 +	AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,N)
323.1199 +
323.1200 +#define AI_MATKEY_UVTRANSFORM_SPECULAR(N)	\
323.1201 +	AI_MATKEY_UVTRANSFORM(aiTextureType_SPECULAR,N)
323.1202 +
323.1203 +#define AI_MATKEY_UVTRANSFORM_AMBIENT(N)	\
323.1204 +	AI_MATKEY_UVTRANSFORM(aiTextureType_AMBIENT,N)
323.1205 +
323.1206 +#define AI_MATKEY_UVTRANSFORM_EMISSIVE(N)	\
323.1207 +	AI_MATKEY_UVTRANSFORM(aiTextureType_EMISSIVE,N)
323.1208 +
323.1209 +#define AI_MATKEY_UVTRANSFORM_NORMALS(N)	\
323.1210 +	AI_MATKEY_UVTRANSFORM(aiTextureType_NORMALS,N)
323.1211 +
323.1212 +#define AI_MATKEY_UVTRANSFORM_HEIGHT(N)	\
323.1213 +	AI_MATKEY_UVTRANSFORM(aiTextureType_HEIGHT,N)
323.1214 +
323.1215 +#define AI_MATKEY_UVTRANSFORM_SHININESS(N)	\
323.1216 +	AI_MATKEY_UVTRANSFORM(aiTextureType_SHININESS,N)
323.1217 +
323.1218 +#define AI_MATKEY_UVTRANSFORM_OPACITY(N)	\
323.1219 +	AI_MATKEY_UVTRANSFORM(aiTextureType_OPACITY,N)
323.1220 +
323.1221 +#define AI_MATKEY_UVTRANSFORM_DISPLACEMENT(N)	\
323.1222 +	AI_MATKEY_UVTRANSFORM(aiTextureType_DISPLACEMENT,N)
323.1223 +
323.1224 +#define AI_MATKEY_UVTRANSFORM_LIGHTMAP(N)	\
323.1225 +	AI_MATKEY_UVTRANSFORM(aiTextureType_LIGHTMAP,N)
323.1226 +
323.1227 +#define AI_MATKEY_UVTRANSFORM_REFLECTION(N)	\
323.1228 +	AI_MATKEY_UVTRANSFORM(aiTextureType_REFLECTION,N)
323.1229 +
323.1230 +#define AI_MATKEY_UVTRANSFORM_UNKNOWN(N)	\
323.1231 +	AI_MATKEY_UVTRANSFORM(aiTextureType_UNKNOWN,N)
323.1232 +
323.1233 +//! @endcond
323.1234 +// ---------------------------------------------------------------------------
323.1235 +#define AI_MATKEY_TEXFLAGS(type, N) _AI_MATKEY_TEXFLAGS_BASE,type,N
323.1236 +
323.1237 +// For backward compatibility and simplicity
323.1238 +//! @cond MATS_DOC_FULL
323.1239 +#define AI_MATKEY_TEXFLAGS_DIFFUSE(N)	\
323.1240 +	AI_MATKEY_TEXFLAGS(aiTextureType_DIFFUSE,N)
323.1241 +
323.1242 +#define AI_MATKEY_TEXFLAGS_SPECULAR(N)	\
323.1243 +	AI_MATKEY_TEXFLAGS(aiTextureType_SPECULAR,N)
323.1244 +
323.1245 +#define AI_MATKEY_TEXFLAGS_AMBIENT(N)	\
323.1246 +	AI_MATKEY_TEXFLAGS(aiTextureType_AMBIENT,N)
323.1247 +
323.1248 +#define AI_MATKEY_TEXFLAGS_EMISSIVE(N)	\
323.1249 +	AI_MATKEY_TEXFLAGS(aiTextureType_EMISSIVE,N)
323.1250 +
323.1251 +#define AI_MATKEY_TEXFLAGS_NORMALS(N)	\
323.1252 +	AI_MATKEY_TEXFLAGS(aiTextureType_NORMALS,N)
323.1253 +
323.1254 +#define AI_MATKEY_TEXFLAGS_HEIGHT(N)	\
323.1255 +	AI_MATKEY_TEXFLAGS(aiTextureType_HEIGHT,N)
323.1256 +
323.1257 +#define AI_MATKEY_TEXFLAGS_SHININESS(N)	\
323.1258 +	AI_MATKEY_TEXFLAGS(aiTextureType_SHININESS,N)
323.1259 +
323.1260 +#define AI_MATKEY_TEXFLAGS_OPACITY(N)	\
323.1261 +	AI_MATKEY_TEXFLAGS(aiTextureType_OPACITY,N)
323.1262 +
323.1263 +#define AI_MATKEY_TEXFLAGS_DISPLACEMENT(N)	\
323.1264 +	AI_MATKEY_TEXFLAGS(aiTextureType_DISPLACEMENT,N)
323.1265 +
323.1266 +#define AI_MATKEY_TEXFLAGS_LIGHTMAP(N)	\
323.1267 +	AI_MATKEY_TEXFLAGS(aiTextureType_LIGHTMAP,N)
323.1268 +
323.1269 +#define AI_MATKEY_TEXFLAGS_REFLECTION(N)	\
323.1270 +	AI_MATKEY_TEXFLAGS(aiTextureType_REFLECTION,N)
323.1271 +
323.1272 +#define AI_MATKEY_TEXFLAGS_UNKNOWN(N)	\
323.1273 +	AI_MATKEY_TEXFLAGS(aiTextureType_UNKNOWN,N)
323.1274 +
323.1275 +// ---------------------------------------------------------------------------
323.1276 +/** @brief Retrieve a material property with a specific key from the material
323.1277 + *
323.1278 + * @param pMat Pointer to the input material. May not be NULL
323.1279 + * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
323.1280 + * @param type Specifies the type of the texture to be retrieved (
323.1281 + *    e.g. diffuse, specular, height map ...)
323.1282 + * @param index Index of the texture to be retrieved.
323.1283 + * @param pPropOut Pointer to receive a pointer to a valid aiMaterialProperty
323.1284 + *        structure or NULL if the key has not been found. */
323.1285 +// ---------------------------------------------------------------------------
323.1286 +ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty(
323.1287 +	 const C_STRUCT aiMaterial* pMat, 
323.1288 +    const char* pKey,
323.1289 +	 unsigned int type,
323.1290 +    unsigned int  index,
323.1291 +    const C_STRUCT aiMaterialProperty** pPropOut);
323.1292 +
323.1293 +// ---------------------------------------------------------------------------
323.1294 +/** @brief Retrieve an array of float values with a specific key 
323.1295 + *  from the material
323.1296 + *
323.1297 + * Pass one of the AI_MATKEY_XXX constants for the last three parameters (the
323.1298 + * example reads the #AI_MATKEY_UVTRANSFORM property of the first diffuse texture)
323.1299 + * @code
323.1300 + * aiUVTransform trafo;
323.1301 + * unsigned int max = sizeof(aiUVTransform);
323.1302 + * if (AI_SUCCESS != aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,0),
323.1303 + *    (float*)&trafo, &max) || sizeof(aiUVTransform) != max)
323.1304 + * {
323.1305 + *   // error handling 
323.1306 + * }
323.1307 + * @endcode
323.1308 + *
323.1309 + * @param pMat Pointer to the input material. May not be NULL
323.1310 + * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
323.1311 + * @param pOut Pointer to a buffer to receive the result. 
323.1312 + * @param pMax Specifies the size of the given buffer, in float's.
323.1313 + *        Receives the number of values (not bytes!) read. 
323.1314 + * @param type (see the code sample above)
323.1315 + * @param index (see the code sample above)
323.1316 + * @return Specifies whether the key has been found. If not, the output
323.1317 + *   arrays remains unmodified and pMax is set to 0.*/
323.1318 +// ---------------------------------------------------------------------------
323.1319 +ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray(
323.1320 +	 const C_STRUCT aiMaterial* pMat, 
323.1321 +    const char* pKey,
323.1322 +	 unsigned int type,
323.1323 +    unsigned int index,
323.1324 +    float* pOut,
323.1325 +    unsigned int* pMax);
323.1326 +
323.1327 +
323.1328 +#ifdef __cplusplus
323.1329 +
323.1330 +// ---------------------------------------------------------------------------
323.1331 +/** @brief Retrieve a single float property with a specific key from the material.
323.1332 +*
323.1333 +* Pass one of the AI_MATKEY_XXX constants for the last three parameters (the
323.1334 +* example reads the #AI_MATKEY_SHININESS_STRENGTH property of the first diffuse texture)
323.1335 +* @code
323.1336 +* float specStrength = 1.f; // default value, remains unmodified if we fail.
323.1337 +* aiGetMaterialFloat(mat, AI_MATKEY_SHININESS_STRENGTH,
323.1338 +*    (float*)&specStrength);
323.1339 +* @endcode
323.1340 +*
323.1341 +* @param pMat Pointer to the input material. May not be NULL
323.1342 +* @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
323.1343 +* @param pOut Receives the output float.
323.1344 +* @param type (see the code sample above)
323.1345 +* @param index (see the code sample above)
323.1346 +* @return Specifies whether the key has been found. If not, the output
323.1347 +*   float remains unmodified.*/
323.1348 +// ---------------------------------------------------------------------------
323.1349 +inline aiReturn aiGetMaterialFloat(const aiMaterial* pMat, 
323.1350 +	const char* pKey,
323.1351 +	unsigned int type,
323.1352 +   unsigned int index,
323.1353 +	float* pOut)
323.1354 +{
323.1355 +	return aiGetMaterialFloatArray(pMat,pKey,type,index,pOut,(unsigned int*)0x0);
323.1356 +}
323.1357 +
323.1358 +#else 
323.1359 +
323.1360 +// Use our friend, the C preprocessor
323.1361 +#define aiGetMaterialFloat (pMat, type, index, pKey, pOut) \
323.1362 +    aiGetMaterialFloatArray(pMat, type, index, pKey, pOut, NULL)
323.1363 +
323.1364 +#endif //!__cplusplus
323.1365 +
323.1366 +
323.1367 +// ---------------------------------------------------------------------------
323.1368 +/** @brief Retrieve an array of integer values with a specific key 
323.1369 + *  from a material
323.1370 + *
323.1371 + * See the sample for aiGetMaterialFloatArray for more information.*/
323.1372 +ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* pMat, 
323.1373 +    const char* pKey,
323.1374 +	 unsigned int  type,
323.1375 +	 unsigned int  index,
323.1376 +    int* pOut,
323.1377 +    unsigned int* pMax);
323.1378 +
323.1379 +
323.1380 +#ifdef __cplusplus
323.1381 +
323.1382 +// ---------------------------------------------------------------------------
323.1383 +/** @brief Retrieve an integer property with a specific key from a material
323.1384 + *
323.1385 + * See the sample for aiGetMaterialFloat for more information.*/
323.1386 +// ---------------------------------------------------------------------------
323.1387 +inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat, 
323.1388 +	const char* pKey,
323.1389 +	unsigned int type,
323.1390 +   unsigned int index,
323.1391 +	int* pOut)
323.1392 +{
323.1393 +	return aiGetMaterialIntegerArray(pMat,pKey,type,index,pOut,(unsigned int*)0x0);
323.1394 +}
323.1395 +
323.1396 +#else 
323.1397 +
323.1398 +// use our friend, the C preprocessor
323.1399 +#define aiGetMaterialInteger (pMat, type, index, pKey, pOut) \
323.1400 +    aiGetMaterialIntegerArray(pMat, type, index, pKey, pOut, NULL)
323.1401 +
323.1402 +#endif //!__cplusplus
323.1403 +
323.1404 +
323.1405 +
323.1406 +// ---------------------------------------------------------------------------
323.1407 +/** @brief Retrieve a color value from the material property table
323.1408 +*
323.1409 +* See the sample for aiGetMaterialFloat for more information*/
323.1410 +// ---------------------------------------------------------------------------
323.1411 +ASSIMP_API C_ENUM aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat, 
323.1412 +    const char* pKey,
323.1413 +	 unsigned int type,
323.1414 +    unsigned int index,
323.1415 +	 C_STRUCT aiColor4D* pOut);
323.1416 +
323.1417 +
323.1418 +// ---------------------------------------------------------------------------
323.1419 +/** @brief Retrieve a string from the material property table
323.1420 +*
323.1421 +* See the sample for aiGetMaterialFloat for more information.*/
323.1422 +// ---------------------------------------------------------------------------
323.1423 +ASSIMP_API C_ENUM aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat, 
323.1424 +    const char* pKey,
323.1425 +	 unsigned int type,
323.1426 +    unsigned int index,
323.1427 +    C_STRUCT aiString* pOut);
323.1428 +
323.1429 +// ---------------------------------------------------------------------------
323.1430 +/** Get the number of textures for a particular texture type.
323.1431 + *  @param[in] pMat Pointer to the input material. May not be NULL
323.1432 + *  @param type Texture type to check for
323.1433 + *  @return Number of textures for this type.
323.1434 + *  @note A texture can be easily queried using #aiGetMaterialTexture() */
323.1435 +// ---------------------------------------------------------------------------
323.1436 +ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,  
323.1437 +	C_ENUM aiTextureType type);
323.1438 +
323.1439 +// ---------------------------------------------------------------------------
323.1440 +/** @brief Helper function to get all values pertaining to a particular
323.1441 + *  texture slot from a material structure.
323.1442 + *
323.1443 + *  This function is provided just for convenience. You could also read the
323.1444 + *  texture by parsing all of its properties manually. This function bundles
323.1445 + *  all of them in a huge function monster.
323.1446 + *
323.1447 + *  @param[in] mat Pointer to the input material. May not be NULL
323.1448 + *  @param[in] type Specifies the texture stack to read from (e.g. diffuse,
323.1449 + *     specular, height map ...). 
323.1450 + *  @param[in] index Index of the texture. The function fails if the 
323.1451 + *     requested index is not available for this texture type. 
323.1452 + *     #aiGetMaterialTextureCount() can be used to determine the number of
323.1453 + *     textures in a particular texture stack.
323.1454 + *  @param[out] path Receives the output path
323.1455 + *      This parameter must be non-null.
323.1456 + *  @param mapping The texture mapping mode to be used.
323.1457 + *      Pass NULL if you're not interested in this information.
323.1458 + *  @param[out] uvindex For UV-mapped textures: receives the index of the UV
323.1459 + *      source channel. Unmodified otherwise.
323.1460 + *      Pass NULL if you're not interested in this information.
323.1461 + *  @param[out] blend Receives the blend factor for the texture
323.1462 + *      Pass NULL if you're not interested in this information.
323.1463 + *  @param[out] op Receives the texture blend operation to be perform between
323.1464 + *		this texture and the previous texture.
323.1465 + *      Pass NULL if you're not interested in this information.
323.1466 + *  @param[out] mapmode Receives the mapping modes to be used for the texture.
323.1467 + *      Pass NULL if you're not interested in this information. Otherwise,
323.1468 + *      pass a pointer to an array of two aiTextureMapMode's (one for each
323.1469 + *      axis, UV order).
323.1470 + *  @return AI_SUCCESS on success, otherwise something else. Have fun.*/
323.1471 +// ---------------------------------------------------------------------------
323.1472 +#ifdef __cplusplus
323.1473 +ASSIMP_API aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
323.1474 +	aiTextureType type,
323.1475 +    unsigned int  index,
323.1476 +    aiString* path,
323.1477 +	aiTextureMapping* mapping	= NULL,
323.1478 +    unsigned int* uvindex		= NULL,
323.1479 +    float* blend				= NULL,
323.1480 +    aiTextureOp* op				= NULL,
323.1481 +	aiTextureMapMode* mapmode	= NULL,
323.1482 +	unsigned int* flags         = NULL); 
323.1483 +#else
323.1484 +C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
323.1485 +    C_ENUM aiTextureType type,
323.1486 +    unsigned int  index,
323.1487 +    C_STRUCT aiString* path,
323.1488 +	C_ENUM aiTextureMapping* mapping	/*= NULL*/,
323.1489 +    unsigned int* uvindex				/*= NULL*/,
323.1490 +    float* blend						/*= NULL*/,
323.1491 +    C_ENUM aiTextureOp* op				/*= NULL*/,
323.1492 +	C_ENUM aiTextureMapMode* mapmode	/*= NULL*/,
323.1493 +	unsigned int* flags                 /*= NULL*/); 
323.1494 +#endif // !#ifdef __cplusplus
323.1495 +
323.1496 +#ifdef __cplusplus
323.1497 +}
323.1498 +
323.1499 +#include "material.inl"
323.1500 +
323.1501 +#endif //!__cplusplus
323.1502 +#endif //!!AI_MATERIAL_H_INC
   324.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   324.2 +++ b/libs/assimp/assimp/material.inl	Sat Feb 01 19:58:19 2014 +0200
   324.3 @@ -0,0 +1,272 @@
   324.4 +/*
   324.5 +---------------------------------------------------------------------------
   324.6 +Open Asset Import Library (assimp)
   324.7 +---------------------------------------------------------------------------
   324.8 +
   324.9 +Copyright (c) 2006-2012, assimp team
  324.10 +
  324.11 +All rights reserved.
  324.12 +
  324.13 +Redistribution and use of this software in source and binary forms, 
  324.14 +with or without modification, are permitted provided that the following 
  324.15 +conditions are met:
  324.16 +
  324.17 +* Redistributions of source code must retain the above
  324.18 +  copyright notice, this list of conditions and the
  324.19 +  following disclaimer.
  324.20 +
  324.21 +* Redistributions in binary form must reproduce the above
  324.22 +  copyright notice, this list of conditions and the
  324.23 +  following disclaimer in the documentation and/or other
  324.24 +  materials provided with the distribution.
  324.25 +
  324.26 +* Neither the name of the assimp team, nor the names of its
  324.27 +  contributors may be used to endorse or promote products
  324.28 +  derived from this software without specific prior
  324.29 +  written permission of the assimp team.
  324.30 +
  324.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  324.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  324.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  324.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  324.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  324.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  324.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  324.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  324.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  324.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  324.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  324.42 +---------------------------------------------------------------------------
  324.43 +*/
  324.44 +
  324.45 +/** @file aiMaterial.inl
  324.46 + *  @brief Defines the C++ getters for the material system
  324.47 + */
  324.48 +
  324.49 +#ifndef AI_MATERIAL_INL_INC
  324.50 +#define AI_MATERIAL_INL_INC
  324.51 +
  324.52 +//! @cond never
  324.53 +
  324.54 +// ---------------------------------------------------------------------------
  324.55 +inline aiReturn aiMaterial::GetTexture( aiTextureType type,
  324.56 +   unsigned int  index,
  324.57 +   C_STRUCT aiString* path,
  324.58 +   aiTextureMapping* mapping	/*= NULL*/,
  324.59 +   unsigned int* uvindex		/*= NULL*/,
  324.60 +   float* blend				   /*= NULL*/,
  324.61 +   aiTextureOp* op				/*= NULL*/,
  324.62 +   aiTextureMapMode* mapmode	/*= NULL*/) const
  324.63 +{
  324.64 +	return ::aiGetMaterialTexture(this,type,index,path,mapping,uvindex,blend,op,mapmode);
  324.65 +}
  324.66 +
  324.67 +// ---------------------------------------------------------------------------
  324.68 +inline unsigned int aiMaterial::GetTextureCount(aiTextureType type) const
  324.69 +{
  324.70 +	return ::aiGetMaterialTextureCount(this,type);
  324.71 +}
  324.72 +
  324.73 +// ---------------------------------------------------------------------------
  324.74 +template <typename Type>
  324.75 +inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
  324.76 +	unsigned int idx, Type* pOut,
  324.77 +	unsigned int* pMax) const
  324.78 +{
  324.79 +	unsigned int iNum = pMax ? *pMax : 1;
  324.80 +
  324.81 +	const aiMaterialProperty* prop;
  324.82 +	const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,
  324.83 +		(const aiMaterialProperty**)&prop);
  324.84 +	if ( AI_SUCCESS == ret )	{
  324.85 +
  324.86 +		if (prop->mDataLength < sizeof(Type)*iNum) {
  324.87 +			return AI_FAILURE;
  324.88 +		}
  324.89 +
  324.90 +		if (prop->mType != aiPTI_Buffer) {
  324.91 +			return AI_FAILURE;
  324.92 +		}
  324.93 +
  324.94 +		iNum = std::min((size_t)iNum,prop->mDataLength / sizeof(Type));
  324.95 +		memcpy(pOut,prop->mData,iNum * sizeof(Type));
  324.96 +		if (pMax) {
  324.97 +			*pMax = iNum;
  324.98 +		}
  324.99 +	}
 324.100 +	return ret;
 324.101 +}
 324.102 +
 324.103 +// ---------------------------------------------------------------------------
 324.104 +template <typename Type>
 324.105 +inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
 324.106 +	unsigned int idx,Type& pOut) const
 324.107 +{
 324.108 +	const aiMaterialProperty* prop;
 324.109 +	const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,
 324.110 +		(const aiMaterialProperty**)&prop);
 324.111 +	if ( AI_SUCCESS == ret )	{
 324.112 +
 324.113 +		if (prop->mDataLength < sizeof(Type)) {
 324.114 +			return AI_FAILURE;
 324.115 +		}
 324.116 +
 324.117 +		if (prop->mType != aiPTI_Buffer) {
 324.118 +			return AI_FAILURE;
 324.119 +		}
 324.120 +
 324.121 +		memcpy(&pOut,prop->mData,sizeof(Type));
 324.122 +	}
 324.123 +	return ret;
 324.124 +}
 324.125 +
 324.126 +// ---------------------------------------------------------------------------
 324.127 +template <>
 324.128 +inline aiReturn aiMaterial::Get<float>(const char* pKey,unsigned int type,
 324.129 +	unsigned int idx,float* pOut,
 324.130 +	unsigned int* pMax) const
 324.131 +{
 324.132 +	return ::aiGetMaterialFloatArray(this,pKey,type,idx,pOut,pMax);
 324.133 +}
 324.134 +// ---------------------------------------------------------------------------
 324.135 +template <>
 324.136 +inline aiReturn aiMaterial::Get<int>(const char* pKey,unsigned int type,
 324.137 +	unsigned int idx,int* pOut,
 324.138 +	unsigned int* pMax) const
 324.139 +{
 324.140 +	return ::aiGetMaterialIntegerArray(this,pKey,type,idx,pOut,pMax);
 324.141 +}
 324.142 +// ---------------------------------------------------------------------------
 324.143 +template <>
 324.144 +inline aiReturn aiMaterial::Get<float>(const char* pKey,unsigned int type,
 324.145 +	unsigned int idx,float& pOut) const
 324.146 +{
 324.147 +	return aiGetMaterialFloat(this,pKey,type,idx,&pOut);
 324.148 +}
 324.149 +// ---------------------------------------------------------------------------
 324.150 +template <>
 324.151 +inline aiReturn aiMaterial::Get<int>(const char* pKey,unsigned int type,
 324.152 +	unsigned int idx,int& pOut) const
 324.153 +{
 324.154 +	return aiGetMaterialInteger(this,pKey,type,idx,&pOut);
 324.155 +}
 324.156 +// ---------------------------------------------------------------------------
 324.157 +template <>
 324.158 +inline aiReturn aiMaterial::Get<aiColor4D>(const char* pKey,unsigned int type,
 324.159 +	unsigned int idx,aiColor4D& pOut) const
 324.160 +{
 324.161 +	return aiGetMaterialColor(this,pKey,type,idx,&pOut);
 324.162 +}
 324.163 +// ---------------------------------------------------------------------------
 324.164 +template <>
 324.165 +inline aiReturn aiMaterial::Get<aiColor3D>(const char* pKey,unsigned int type,
 324.166 +	unsigned int idx,aiColor3D& pOut) const
 324.167 +{
 324.168 +	aiColor4D c;
 324.169 +	const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c);
 324.170 +	pOut = aiColor3D(c.r,c.g,c.b);
 324.171 +	return ret;
 324.172 +}
 324.173 +// ---------------------------------------------------------------------------
 324.174 +template <>
 324.175 +inline aiReturn aiMaterial::Get<aiString>(const char* pKey,unsigned int type,
 324.176 +	unsigned int idx,aiString& pOut) const
 324.177 +{
 324.178 +	return aiGetMaterialString(this,pKey,type,idx,&pOut);
 324.179 +}
 324.180 +
 324.181 +
 324.182 +// ---------------------------------------------------------------------------
 324.183 +template<class TYPE>
 324.184 +aiReturn aiMaterial::AddProperty (const TYPE* pInput,
 324.185 +	const unsigned int pNumValues,
 324.186 +	const char* pKey,
 324.187 +	unsigned int type,
 324.188 +	unsigned int index)
 324.189 +{
 324.190 +	return AddBinaryProperty((const void*)pInput,
 324.191 +		pNumValues * sizeof(TYPE),
 324.192 +		pKey,type,index,aiPTI_Buffer);
 324.193 +}
 324.194 +
 324.195 +// ---------------------------------------------------------------------------
 324.196 +template<>
 324.197 +inline aiReturn aiMaterial::AddProperty<float> (const float* pInput,
 324.198 +	const unsigned int pNumValues,
 324.199 +	const char* pKey,
 324.200 +	unsigned int type,
 324.201 +	unsigned int index)
 324.202 +{
 324.203 +	return AddBinaryProperty((const void*)pInput,
 324.204 +		pNumValues * sizeof(float),
 324.205 +		pKey,type,index,aiPTI_Float);
 324.206 +}
 324.207 +
 324.208 +// ---------------------------------------------------------------------------
 324.209 +template<>
 324.210 +inline aiReturn aiMaterial::AddProperty<aiUVTransform> (const aiUVTransform* pInput,
 324.211 +	const unsigned int pNumValues,
 324.212 +	const char* pKey,
 324.213 +	unsigned int type,
 324.214 +	unsigned int index)
 324.215 +{
 324.216 +	return AddBinaryProperty((const void*)pInput,
 324.217 +		pNumValues * sizeof(aiUVTransform),
 324.218 +		pKey,type,index,aiPTI_Float);
 324.219 +}
 324.220 +
 324.221 +// ---------------------------------------------------------------------------
 324.222 +template<>
 324.223 +inline aiReturn aiMaterial::AddProperty<aiColor4D> (const aiColor4D* pInput,
 324.224 +	const unsigned int pNumValues,
 324.225 +	const char* pKey,
 324.226 +	unsigned int type,
 324.227 +	unsigned int index)
 324.228 +{
 324.229 +	return AddBinaryProperty((const void*)pInput,
 324.230 +		pNumValues * sizeof(aiColor4D),
 324.231 +		pKey,type,index,aiPTI_Float);
 324.232 +}
 324.233 +
 324.234 +// ---------------------------------------------------------------------------
 324.235 +template<>
 324.236 +inline aiReturn aiMaterial::AddProperty<aiColor3D> (const aiColor3D* pInput,
 324.237 +	const unsigned int pNumValues,
 324.238 +	const char* pKey,
 324.239 +	unsigned int type,
 324.240 +	unsigned int index)
 324.241 +{
 324.242 +	return AddBinaryProperty((const void*)pInput,
 324.243 +		pNumValues * sizeof(aiColor3D),
 324.244 +		pKey,type,index,aiPTI_Float);
 324.245 +}
 324.246 +
 324.247 +// ---------------------------------------------------------------------------
 324.248 +template<>
 324.249 +inline aiReturn aiMaterial::AddProperty<aiVector3D> (const aiVector3D* pInput,
 324.250 +	const unsigned int pNumValues,
 324.251 +	const char* pKey,
 324.252 +	unsigned int type,
 324.253 +	unsigned int index)
 324.254 +{
 324.255 +	return AddBinaryProperty((const void*)pInput,
 324.256 +		pNumValues * sizeof(aiVector3D),
 324.257 +		pKey,type,index,aiPTI_Float);
 324.258 +}
 324.259 +
 324.260 +// ---------------------------------------------------------------------------
 324.261 +template<>
 324.262 +inline aiReturn aiMaterial::AddProperty<int> (const int* pInput,
 324.263 +	const unsigned int pNumValues,
 324.264 +	const char* pKey,
 324.265 +	unsigned int type,
 324.266 +	unsigned int index)
 324.267 +{
 324.268 +	return AddBinaryProperty((const void*)pInput,
 324.269 +		pNumValues * sizeof(int),
 324.270 +		pKey,type,index,aiPTI_Integer);
 324.271 +}
 324.272 +
 324.273 +//! @endcond
 324.274 +
 324.275 +#endif //! AI_MATERIAL_INL_INC
   325.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   325.2 +++ b/libs/assimp/assimp/matrix3x3.h	Sat Feb 01 19:58:19 2014 +0200
   325.3 @@ -0,0 +1,183 @@
   325.4 +/*
   325.5 +---------------------------------------------------------------------------
   325.6 +Open Asset Import Library (assimp)
   325.7 +---------------------------------------------------------------------------
   325.8 +
   325.9 +Copyright (c) 2006-2012, assimp team
  325.10 +
  325.11 +All rights reserved.
  325.12 +
  325.13 +Redistribution and use of this software in source and binary forms, 
  325.14 +with or without modification, are permitted provided that the following 
  325.15 +conditions are met:
  325.16 +
  325.17 +* Redistributions of source code must retain the above
  325.18 +  copyright notice, this list of conditions and the
  325.19 +  following disclaimer.
  325.20 +
  325.21 +* Redistributions in binary form must reproduce the above
  325.22 +  copyright notice, this list of conditions and the
  325.23 +  following disclaimer in the documentation and/or other
  325.24 +  materials provided with the distribution.
  325.25 +
  325.26 +* Neither the name of the assimp team, nor the names of its
  325.27 +  contributors may be used to endorse or promote products
  325.28 +  derived from this software without specific prior
  325.29 +  written permission of the assimp team.
  325.30 +
  325.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  325.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  325.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  325.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  325.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  325.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  325.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  325.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  325.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  325.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  325.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  325.42 +---------------------------------------------------------------------------
  325.43 +*/
  325.44 +
  325.45 +/** @file matrix3x3.h
  325.46 + *  @brief Definition of a 3x3 matrix, including operators when compiling in C++
  325.47 + */
  325.48 +#ifndef AI_MATRIX3x3_H_INC
  325.49 +#define AI_MATRIX3x3_H_INC
  325.50 +
  325.51 +#include "./Compiler/pushpack1.h"
  325.52 +
  325.53 +#ifdef __cplusplus
  325.54 +
  325.55 +template <typename T> class aiMatrix4x4t;
  325.56 +template <typename T> class aiVector2t;
  325.57 +
  325.58 +// ---------------------------------------------------------------------------
  325.59 +/** @brief Represents a row-major 3x3 matrix
  325.60 + *
  325.61 + *  There's much confusion about matrix layouts (column vs. row order). 
  325.62 + *  This is *always* a row-major matrix. Not even with the
  325.63 + *  #aiProcess_ConvertToLeftHanded flag, which absolutely does not affect
  325.64 + *  matrix order - it just affects the handedness of the coordinate system
  325.65 + *  defined thereby.
  325.66 + */
  325.67 +template <typename TReal>
  325.68 +class aiMatrix3x3t
  325.69 +{
  325.70 +public:
  325.71 +
  325.72 +	aiMatrix3x3t () :	
  325.73 +		a1(static_cast<TReal>(1.0f)), a2(), a3(), 
  325.74 +		b1(), b2(static_cast<TReal>(1.0f)), b3(), 
  325.75 +		c1(), c2(), c3(static_cast<TReal>(1.0f)) {}
  325.76 +
  325.77 +	aiMatrix3x3t (	TReal _a1, TReal _a2, TReal _a3,
  325.78 +					TReal _b1, TReal _b2, TReal _b3,
  325.79 +					TReal _c1, TReal _c2, TReal _c3) :	
  325.80 +		a1(_a1), a2(_a2), a3(_a3), 
  325.81 +		b1(_b1), b2(_b2), b3(_b3), 
  325.82 +		c1(_c1), c2(_c2), c3(_c3)
  325.83 +	{}
  325.84 +
  325.85 +public:
  325.86 +
  325.87 +	// matrix multiplication. 
  325.88 +	aiMatrix3x3t& operator *= (const aiMatrix3x3t& m);
  325.89 +	aiMatrix3x3t  operator  * (const aiMatrix3x3t& m) const;
  325.90 +
  325.91 +	// array access operators
  325.92 +	TReal* operator[]       (unsigned int p_iIndex);
  325.93 +	const TReal* operator[] (unsigned int p_iIndex) const;
  325.94 +
  325.95 +	// comparison operators
  325.96 +	bool operator== (const aiMatrix4x4t<TReal> m) const;
  325.97 +	bool operator!= (const aiMatrix4x4t<TReal> m) const;
  325.98 +
  325.99 +	template <typename TOther>
 325.100 +	operator aiMatrix3x3t<TOther> () const;
 325.101 +
 325.102 +public:
 325.103 +
 325.104 +	// -------------------------------------------------------------------
 325.105 +	/** @brief Construction from a 4x4 matrix. The remaining parts 
 325.106 +	 *  of the matrix are ignored.
 325.107 +	 */
 325.108 +	explicit aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix);
 325.109 +
 325.110 +	// -------------------------------------------------------------------
 325.111 +	/** @brief Transpose the matrix
 325.112 +	 */
 325.113 +	aiMatrix3x3t& Transpose();
 325.114 +
 325.115 +	// -------------------------------------------------------------------
 325.116 +	/** @brief Invert the matrix.
 325.117 +	 *  If the matrix is not invertible all elements are set to qnan.
 325.118 +	 *  Beware, use (f != f) to check whether a TReal f is qnan.
 325.119 +	 */
 325.120 +	aiMatrix3x3t& Inverse();
 325.121 +	TReal Determinant() const;
 325.122 +
 325.123 +public:
 325.124 +	// -------------------------------------------------------------------
 325.125 +	/** @brief Returns a rotation matrix for a rotation around z
 325.126 +	 *  @param a Rotation angle, in radians
 325.127 +	 *  @param out Receives the output matrix
 325.128 +	 *  @return Reference to the output matrix
 325.129 +	 */
 325.130 +	static aiMatrix3x3t& RotationZ(TReal a, aiMatrix3x3t& out);
 325.131 +
 325.132 +	// -------------------------------------------------------------------
 325.133 +	/** @brief Returns a rotation matrix for a rotation around
 325.134 +	 *    an arbitrary axis.
 325.135 +	 *
 325.136 +	 *  @param a Rotation angle, in radians
 325.137 +	 *  @param axis Axis to rotate around
 325.138 +	 *  @param out To be filled
 325.139 +	 */
 325.140 +	static aiMatrix3x3t& Rotation( TReal a, 
 325.141 +		const aiVector3t<TReal>& axis, aiMatrix3x3t& out);
 325.142 +
 325.143 +	// -------------------------------------------------------------------
 325.144 +	/** @brief Returns a translation matrix 
 325.145 +	 *  @param v Translation vector
 325.146 +	 *  @param out Receives the output matrix
 325.147 +	 *  @return Reference to the output matrix
 325.148 +	 */
 325.149 +	static aiMatrix3x3t& Translation( const aiVector2t<TReal>& v, aiMatrix3x3t& out);
 325.150 +
 325.151 +	// -------------------------------------------------------------------
 325.152 +	/** @brief A function for creating a rotation matrix that rotates a
 325.153 +	 *  vector called "from" into another vector called "to".
 325.154 +	 * Input : from[3], to[3] which both must be *normalized* non-zero vectors
 325.155 +	 * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
 325.156 +	 * Authors: Tomas Möller, John Hughes
 325.157 +	 *          "Efficiently Building a Matrix to Rotate One Vector to Another"
 325.158 +	 *          Journal of Graphics Tools, 4(4):1-4, 1999
 325.159 +	 */
 325.160 +	static aiMatrix3x3t& FromToMatrix(const aiVector3t<TReal>& from, 
 325.161 +		const aiVector3t<TReal>& to, aiMatrix3x3t& out);
 325.162 +
 325.163 +public:
 325.164 +
 325.165 +
 325.166 +	TReal a1, a2, a3;
 325.167 +	TReal b1, b2, b3;
 325.168 +	TReal c1, c2, c3;
 325.169 +} PACK_STRUCT;
 325.170 +
 325.171 +typedef aiMatrix3x3t<float> aiMatrix3x3;
 325.172 +
 325.173 +#else
 325.174 +
 325.175 +struct aiMatrix3x3 {
 325.176 +
 325.177 +	float a1, a2, a3;
 325.178 +	float b1, b2, b3;
 325.179 +	float c1, c2, c3;
 325.180 +} PACK_STRUCT;
 325.181 +
 325.182 +#endif
 325.183 +
 325.184 +#include "./Compiler/poppack1.h"
 325.185 +
 325.186 +#endif // AI_MATRIX3x3_H_INC
   326.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   326.2 +++ b/libs/assimp/assimp/matrix3x3.inl	Sat Feb 01 19:58:19 2014 +0200
   326.3 @@ -0,0 +1,316 @@
   326.4 +/*
   326.5 +---------------------------------------------------------------------------
   326.6 +Open Asset Import Library (assimp)
   326.7 +---------------------------------------------------------------------------
   326.8 +
   326.9 +Copyright (c) 2006-2012, assimp team
  326.10 +
  326.11 +All rights reserved.
  326.12 +
  326.13 +Redistribution and use of this software in source and binary forms, 
  326.14 +with or without modification, are permitted provided that the following 
  326.15 +conditions are met:
  326.16 +
  326.17 +* Redistributions of source code must retain the above
  326.18 +  copyright notice, this list of conditions and the
  326.19 +  following disclaimer.
  326.20 +
  326.21 +* Redistributions in binary form must reproduce the above
  326.22 +  copyright notice, this list of conditions and the
  326.23 +  following disclaimer in the documentation and/or other
  326.24 +  materials provided with the distribution.
  326.25 +
  326.26 +* Neither the name of the assimp team, nor the names of its
  326.27 +  contributors may be used to endorse or promote products
  326.28 +  derived from this software without specific prior
  326.29 +  written permission of the assimp team.
  326.30 +
  326.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  326.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  326.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  326.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  326.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  326.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  326.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  326.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  326.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  326.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  326.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  326.42 +---------------------------------------------------------------------------
  326.43 +*/
  326.44 +
  326.45 +/** @file aiMatrix3x3.inl
  326.46 + *  @brief Inline implementation of the 3x3 matrix operators
  326.47 + */
  326.48 +#ifndef AI_MATRIX3x3_INL_INC
  326.49 +#define AI_MATRIX3x3_INL_INC
  326.50 +
  326.51 +#ifdef __cplusplus
  326.52 +#include "matrix3x3.h"
  326.53 +
  326.54 +#include "matrix4x4.h"
  326.55 +#include <algorithm>
  326.56 +#include <limits>
  326.57 +
  326.58 +// ------------------------------------------------------------------------------------------------
  326.59 +// Construction from a 4x4 matrix. The remaining parts of the matrix are ignored.
  326.60 +template <typename TReal>
  326.61 +inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
  326.62 +{
  326.63 +	a1 = pMatrix.a1; a2 = pMatrix.a2; a3 = pMatrix.a3;
  326.64 +	b1 = pMatrix.b1; b2 = pMatrix.b2; b3 = pMatrix.b3;
  326.65 +	c1 = pMatrix.c1; c2 = pMatrix.c2; c3 = pMatrix.c3;
  326.66 +}
  326.67 +
  326.68 +// ------------------------------------------------------------------------------------------------
  326.69 +template <typename TReal>
  326.70 +inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m)
  326.71 +{
  326.72 +	*this = aiMatrix3x3t<TReal>(m.a1 * a1 + m.b1 * a2 + m.c1 * a3,
  326.73 +		m.a2 * a1 + m.b2 * a2 + m.c2 * a3,
  326.74 +		m.a3 * a1 + m.b3 * a2 + m.c3 * a3,
  326.75 +		m.a1 * b1 + m.b1 * b2 + m.c1 * b3,
  326.76 +		m.a2 * b1 + m.b2 * b2 + m.c2 * b3,
  326.77 +		m.a3 * b1 + m.b3 * b2 + m.c3 * b3,
  326.78 +		m.a1 * c1 + m.b1 * c2 + m.c1 * c3,
  326.79 +		m.a2 * c1 + m.b2 * c2 + m.c2 * c3,
  326.80 +		m.a3 * c1 + m.b3 * c2 + m.c3 * c3);
  326.81 +	return *this;
  326.82 +}
  326.83 +
  326.84 +// ------------------------------------------------------------------------------------------------
  326.85 +template <typename TReal>
  326.86 +template <typename TOther>
  326.87 +aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
  326.88 +{
  326.89 +	return aiMatrix3x3t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),
  326.90 +		static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),
  326.91 +		static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3));
  326.92 +}
  326.93 +
  326.94 +// ------------------------------------------------------------------------------------------------
  326.95 +template <typename TReal>
  326.96 +inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const
  326.97 +{
  326.98 +	aiMatrix3x3t<TReal> temp( *this);
  326.99 +	temp *= m;
 326.100 +	return temp;
 326.101 +}
 326.102 +
 326.103 +// ------------------------------------------------------------------------------------------------
 326.104 +template <typename TReal>
 326.105 +inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex)
 326.106 +{
 326.107 +	return &this->a1 + p_iIndex * 3;
 326.108 +}
 326.109 +
 326.110 +// ------------------------------------------------------------------------------------------------
 326.111 +template <typename TReal>
 326.112 +inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const
 326.113 +{
 326.114 +	return &this->a1 + p_iIndex * 3;
 326.115 +}
 326.116 +
 326.117 +// ------------------------------------------------------------------------------------------------
 326.118 +template <typename TReal>
 326.119 +inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
 326.120 +{
 326.121 +	return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 &&
 326.122 +		   b1 == m.b1 && b2 == m.b2 && b3 == m.b3 &&
 326.123 +		   c1 == m.c1 && c2 == m.c2 && c3 == m.c3;
 326.124 +}
 326.125 +
 326.126 +// ------------------------------------------------------------------------------------------------
 326.127 +template <typename TReal>
 326.128 +inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const
 326.129 +{
 326.130 +	return !(*this == m);
 326.131 +}
 326.132 +
 326.133 +// ------------------------------------------------------------------------------------------------
 326.134 +template <typename TReal>
 326.135 +inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()
 326.136 +{
 326.137 +	// (TReal&) don't remove, GCC complains cause of packed fields
 326.138 +	std::swap( (TReal&)a2, (TReal&)b1);
 326.139 +	std::swap( (TReal&)a3, (TReal&)c1);
 326.140 +	std::swap( (TReal&)b3, (TReal&)c2);
 326.141 +	return *this;
 326.142 +}
 326.143 +
 326.144 +// ----------------------------------------------------------------------------------------
 326.145 +template <typename TReal>
 326.146 +inline TReal aiMatrix3x3t<TReal>::Determinant() const
 326.147 +{
 326.148 +	return a1*b2*c3 - a1*b3*c2 + a2*b3*c1 - a2*b1*c3 + a3*b1*c2 - a3*b2*c1;
 326.149 +}
 326.150 +
 326.151 +// ----------------------------------------------------------------------------------------
 326.152 +template <typename TReal>
 326.153 +inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse()
 326.154 +{
 326.155 +	// Compute the reciprocal determinant
 326.156 +	TReal det = Determinant();
 326.157 +	if(det == static_cast<TReal>(0.0)) 
 326.158 +	{
 326.159 +		// Matrix not invertible. Setting all elements to nan is not really
 326.160 +		// correct in a mathematical sense; but at least qnans are easy to 
 326.161 +		// spot. XXX we might throw an exception instead, which would
 326.162 +		// be even much better to spot :/.
 326.163 +		const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
 326.164 +		*this = aiMatrix3x3t<TReal>( nan,nan,nan,nan,nan,nan,nan,nan,nan);
 326.165 +
 326.166 +		return *this;
 326.167 +	}
 326.168 +
 326.169 +	TReal invdet = static_cast<TReal>(1.0) / det;
 326.170 +
 326.171 +	aiMatrix3x3t<TReal> res;
 326.172 +	res.a1 = invdet  * (b2 * c3 - b3 * c2);
 326.173 +	res.a2 = -invdet * (a2 * c3 - a3 * c2);
 326.174 +	res.a3 = invdet  * (a2 * b3 - a3 * b2);
 326.175 +	res.b1 = -invdet * (b1 * c3 - b3 * c1);
 326.176 +	res.b2 = invdet  * (a1 * c3 - a3 * c1);
 326.177 +	res.b3 = -invdet * (a1 * b3 - a3 * b1);
 326.178 +	res.c1 = invdet  * (b1 * c2 - b2 * c1);
 326.179 +	res.c2 = -invdet * (a1 * c2 - a2 * c1);
 326.180 +	res.c3 = invdet  * (a1 * b2 - a2 * b1);
 326.181 +	*this = res;
 326.182 +
 326.183 +	return *this;
 326.184 +}
 326.185 +
 326.186 +// ------------------------------------------------------------------------------------------------
 326.187 +template <typename TReal>
 326.188 +inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out)
 326.189 +{
 326.190 +	out.a1 = out.b2 = ::cos(a);
 326.191 +	out.b1 = ::sin(a);
 326.192 +	out.a2 = - out.b1;
 326.193 +
 326.194 +	out.a3 = out.b3 = out.c1 = out.c2 = 0.f;
 326.195 +	out.c3 = 1.f;
 326.196 +
 326.197 +	return out;
 326.198 +}
 326.199 +
 326.200 +// ------------------------------------------------------------------------------------------------
 326.201 +// Returns a rotation matrix for a rotation around an arbitrary axis.
 326.202 +template <typename TReal>
 326.203 +inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out)
 326.204 +{
 326.205 +  TReal c = cos( a), s = sin( a), t = 1 - c;
 326.206 +  TReal x = axis.x, y = axis.y, z = axis.z;
 326.207 +
 326.208 +  // Many thanks to MathWorld and Wikipedia
 326.209 +  out.a1 = t*x*x + c;   out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
 326.210 +  out.b1 = t*x*y + s*z; out.b2 = t*y*y + c;   out.b3 = t*y*z - s*x;
 326.211 +  out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
 326.212 +
 326.213 +  return out;
 326.214 +}
 326.215 +
 326.216 +// ------------------------------------------------------------------------------------------------
 326.217 +template <typename TReal>
 326.218 +inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out)
 326.219 +{
 326.220 +	out = aiMatrix3x3t<TReal>();
 326.221 +	out.a3 = v.x;
 326.222 +	out.b3 = v.y;
 326.223 +	return out;
 326.224 +}
 326.225 +
 326.226 +// ----------------------------------------------------------------------------------------
 326.227 +/** A function for creating a rotation matrix that rotates a vector called
 326.228 + * "from" into another vector called "to".
 326.229 + * Input : from[3], to[3] which both must be *normalized* non-zero vectors
 326.230 + * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
 326.231 + * Authors: Tomas Möller, John Hughes
 326.232 + *          "Efficiently Building a Matrix to Rotate One Vector to Another"
 326.233 + *          Journal of Graphics Tools, 4(4):1-4, 1999
 326.234 + */
 326.235 +// ----------------------------------------------------------------------------------------
 326.236 +template <typename TReal>
 326.237 +inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from, 
 326.238 +	const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx)
 326.239 +{
 326.240 +	const TReal e = from * to;
 326.241 +	const TReal f = (e < 0)? -e:e;
 326.242 +
 326.243 +	if (f > static_cast<TReal>(1.0) - static_cast<TReal>(0.00001))     /* "from" and "to"-vector almost parallel */
 326.244 +	{
 326.245 +		aiVector3D u,v;     /* temporary storage vectors */
 326.246 +		aiVector3D x;       /* vector most nearly orthogonal to "from" */
 326.247 +
 326.248 +		x.x = (from.x > 0.0)? from.x : -from.x;
 326.249 +		x.y = (from.y > 0.0)? from.y : -from.y;
 326.250 +		x.z = (from.z > 0.0)? from.z : -from.z;
 326.251 +
 326.252 +		if (x.x < x.y)
 326.253 +		{
 326.254 +			if (x.x < x.z)
 326.255 +			{
 326.256 +				x.x = static_cast<TReal>(1.0); x.y = x.z = static_cast<TReal>(0.0);
 326.257 +			}
 326.258 +			else
 326.259 +			{
 326.260 +				x.z = static_cast<TReal>(1.0); x.y = x.z = static_cast<TReal>(0.0);
 326.261 +			}
 326.262 +		}
 326.263 +		else
 326.264 +		{
 326.265 +			if (x.y < x.z)
 326.266 +			{
 326.267 +				x.y = static_cast<TReal>(1.0); x.x = x.z = static_cast<TReal>(0.0);
 326.268 +			}
 326.269 +			else
 326.270 +			{
 326.271 +				x.z = static_cast<TReal>(1.0); x.x = x.y = static_cast<TReal>(0.0);
 326.272 +			}
 326.273 +		}
 326.274 +
 326.275 +		u.x = x.x - from.x; u.y = x.y - from.y; u.z = x.z - from.z;
 326.276 +		v.x = x.x - to.x;   v.y = x.y - to.y;   v.z = x.z - to.z;
 326.277 +
 326.278 +		const TReal c1 = static_cast<TReal>(2.0) / (u * u);
 326.279 +		const TReal c2 = static_cast<TReal>(2.0) / (v * v);
 326.280 +		const TReal c3 = c1 * c2  * (u * v);
 326.281 +
 326.282 +		for (unsigned int i = 0; i < 3; i++) 
 326.283 +		{
 326.284 +			for (unsigned int j = 0; j < 3; j++) 
 326.285 +			{
 326.286 +				mtx[i][j] =  - c1 * u[i] * u[j] - c2 * v[i] * v[j]
 326.287 +					+ c3 * v[i] * u[j];
 326.288 +			}
 326.289 +			mtx[i][i] += static_cast<TReal>(1.0);
 326.290 +		}
 326.291 +	}
 326.292 +	else  /* the most common case, unless "from"="to", or "from"=-"to" */
 326.293 +	{
 326.294 +		const aiVector3D v = from ^ to;
 326.295 +		/* ... use this hand optimized version (9 mults less) */
 326.296 +		const TReal h = static_cast<TReal>(1.0)/(static_cast<TReal>(1.0) + e);      /* optimization by Gottfried Chen */
 326.297 +		const TReal hvx = h * v.x;
 326.298 +		const TReal hvz = h * v.z;
 326.299 +		const TReal hvxy = hvx * v.y;
 326.300 +		const TReal hvxz = hvx * v.z;
 326.301 +		const TReal hvyz = hvz * v.y;
 326.302 +		mtx[0][0] = e + hvx * v.x;
 326.303 +		mtx[0][1] = hvxy - v.z;
 326.304 +		mtx[0][2] = hvxz + v.y;
 326.305 +
 326.306 +		mtx[1][0] = hvxy + v.z;
 326.307 +		mtx[1][1] = e + h * v.y * v.y;
 326.308 +		mtx[1][2] = hvyz - v.x;
 326.309 +
 326.310 +		mtx[2][0] = hvxz - v.y;
 326.311 +		mtx[2][1] = hvyz + v.x;
 326.312 +		mtx[2][2] = e + hvz * v.z;
 326.313 +	}
 326.314 +	return mtx;
 326.315 +}
 326.316 +
 326.317 +
 326.318 +#endif // __cplusplus
 326.319 +#endif // AI_MATRIX3x3_INL_INC
   327.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   327.2 +++ b/libs/assimp/assimp/matrix4x4.h	Sat Feb 01 19:58:19 2014 +0200
   327.3 @@ -0,0 +1,238 @@
   327.4 +/*
   327.5 +---------------------------------------------------------------------------
   327.6 +Open Asset Import Library (assimp)
   327.7 +---------------------------------------------------------------------------
   327.8 +
   327.9 +Copyright (c) 2006-2012, assimp team
  327.10 +
  327.11 +All rights reserved.
  327.12 +
  327.13 +Redistribution and use of this software in source and binary forms, 
  327.14 +with or without modification, are permitted provided that the following 
  327.15 +conditions are met:
  327.16 +
  327.17 +* Redistributions of source code must retain the above
  327.18 +  copyright notice, this list of conditions and the
  327.19 +  following disclaimer.
  327.20 +
  327.21 +* Redistributions in binary form must reproduce the above
  327.22 +  copyright notice, this list of conditions and the
  327.23 +  following disclaimer in the documentation and/or other
  327.24 +  materials provided with the distribution.
  327.25 +
  327.26 +* Neither the name of the assimp team, nor the names of its
  327.27 +  contributors may be used to endorse or promote products
  327.28 +  derived from this software without specific prior
  327.29 +  written permission of the assimp team.
  327.30 +
  327.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  327.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  327.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  327.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  327.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  327.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  327.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  327.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  327.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  327.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  327.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  327.42 +---------------------------------------------------------------------------
  327.43 +*/
  327.44 +/** @file matrix4x4.h
  327.45 + *  @brief 4x4 matrix structure, including operators when compiling in C++
  327.46 + */
  327.47 +#ifndef AI_MATRIX4X4_H_INC
  327.48 +#define AI_MATRIX4X4_H_INC
  327.49 +
  327.50 +#include "./Compiler/pushpack1.h"
  327.51 +
  327.52 +#ifdef __cplusplus
  327.53 +
  327.54 +template<typename TReal> class aiMatrix3x3t;
  327.55 +template<typename TReal> class aiQuaterniont;
  327.56 +
  327.57 +// ---------------------------------------------------------------------------
  327.58 +/** @brief Represents a row-major 4x4 matrix, use this for homogeneous
  327.59 + *   coordinates.
  327.60 + *
  327.61 + *  There's much confusion about matrix layouts (column vs. row order). 
  327.62 + *  This is *always* a row-major matrix. Not even with the
  327.63 + *  #aiProcess_ConvertToLeftHanded flag, which absolutely does not affect
  327.64 + *  matrix order - it just affects the handedness of the coordinate system
  327.65 + *  defined thereby.
  327.66 + */
  327.67 +template<typename TReal>
  327.68 +class aiMatrix4x4t
  327.69 +{
  327.70 +public:
  327.71 +	
  327.72 +	/** set to identity */
  327.73 +	aiMatrix4x4t ();
  327.74 +
  327.75 +	/** construction from single values */
  327.76 +	aiMatrix4x4t (	TReal _a1, TReal _a2, TReal _a3, TReal _a4,
  327.77 +					TReal _b1, TReal _b2, TReal _b3, TReal _b4,
  327.78 +					TReal _c1, TReal _c2, TReal _c3, TReal _c4,
  327.79 +					TReal _d1, TReal _d2, TReal _d3, TReal _d4);
  327.80 +
  327.81 +
  327.82 +	/** construction from 3x3 matrix, remaining elements are set to identity */
  327.83 +	explicit aiMatrix4x4t( const aiMatrix3x3t<TReal>& m);
  327.84 +
  327.85 +public:
  327.86 +
  327.87 +	// array access operators
  327.88 +	TReal* operator[]       (unsigned int p_iIndex);
  327.89 +	const TReal* operator[] (unsigned int p_iIndex) const;
  327.90 +
  327.91 +	// comparison operators
  327.92 +	bool operator== (const aiMatrix4x4t m) const;
  327.93 +	bool operator!= (const aiMatrix4x4t m) const;
  327.94 +
  327.95 +	// matrix multiplication. 
  327.96 +	aiMatrix4x4t& operator *= (const aiMatrix4x4t& m);
  327.97 +	aiMatrix4x4t  operator *  (const aiMatrix4x4t& m) const;
  327.98 +
  327.99 +	template <typename TOther>
 327.100 +	operator aiMatrix4x4t<TOther> () const;
 327.101 +
 327.102 +public:
 327.103 +
 327.104 +	// -------------------------------------------------------------------
 327.105 +	/** @brief Transpose the matrix */
 327.106 +	aiMatrix4x4t& Transpose();
 327.107 +
 327.108 +	// -------------------------------------------------------------------
 327.109 +	/** @brief Invert the matrix.
 327.110 +	 *  If the matrix is not invertible all elements are set to qnan.
 327.111 +	 *  Beware, use (f != f) to check whether a TReal f is qnan.
 327.112 +	 */
 327.113 +	aiMatrix4x4t& Inverse();
 327.114 +	TReal Determinant() const;
 327.115 +
 327.116 +
 327.117 +	// -------------------------------------------------------------------
 327.118 +	/** @brief Returns true of the matrix is the identity matrix.
 327.119 +	 *  The check is performed against a not so small epsilon.
 327.120 +	 */
 327.121 +	inline bool IsIdentity() const;
 327.122 +
 327.123 +	// -------------------------------------------------------------------
 327.124 +	/** @brief Decompose a trafo matrix into its original components
 327.125 +	 *  @param scaling Receives the output scaling for the x,y,z axes
 327.126 +	 *  @param rotation Receives the output rotation as a hamilton
 327.127 +	 *   quaternion 
 327.128 +	 *  @param position Receives the output position for the x,y,z axes
 327.129 +	 */
 327.130 +	void Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
 327.131 +		aiVector3t<TReal>& position) const;
 327.132 +
 327.133 +	// -------------------------------------------------------------------
 327.134 +	/** @brief Decompose a trafo matrix with no scaling into its 
 327.135 +	 *    original components
 327.136 +	 *  @param rotation Receives the output rotation as a hamilton
 327.137 +	 *    quaternion 
 327.138 +	 *  @param position Receives the output position for the x,y,z axes
 327.139 +	 */
 327.140 +	void DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
 327.141 +		aiVector3t<TReal>& position) const;
 327.142 +
 327.143 +
 327.144 +	// -------------------------------------------------------------------
 327.145 +	/** @brief Creates a trafo matrix from a set of euler angles
 327.146 +	 *  @param x Rotation angle for the x-axis, in radians
 327.147 +	 *  @param y Rotation angle for the y-axis, in radians
 327.148 +	 *  @param z Rotation angle for the z-axis, in radians
 327.149 +	 */
 327.150 +	aiMatrix4x4t& FromEulerAnglesXYZ(TReal x, TReal y, TReal z);
 327.151 +	aiMatrix4x4t& FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb);
 327.152 +
 327.153 +public:
 327.154 +	// -------------------------------------------------------------------
 327.155 +	/** @brief Returns a rotation matrix for a rotation around the x axis
 327.156 +	 *  @param a Rotation angle, in radians
 327.157 +	 *  @param out Receives the output matrix
 327.158 +	 *  @return Reference to the output matrix
 327.159 +	 */
 327.160 +	static aiMatrix4x4t& RotationX(TReal a, aiMatrix4x4t& out);
 327.161 +
 327.162 +	// -------------------------------------------------------------------
 327.163 +	/** @brief Returns a rotation matrix for a rotation around the y axis
 327.164 +	 *  @param a Rotation angle, in radians
 327.165 +	 *  @param out Receives the output matrix
 327.166 +	 *  @return Reference to the output matrix
 327.167 +	 */
 327.168 +	static aiMatrix4x4t& RotationY(TReal a, aiMatrix4x4t& out);
 327.169 +
 327.170 +	// -------------------------------------------------------------------
 327.171 +	/** @brief Returns a rotation matrix for a rotation around the z axis
 327.172 +	 *  @param a Rotation angle, in radians
 327.173 +	 *  @param out Receives the output matrix
 327.174 +	 *  @return Reference to the output matrix
 327.175 +	 */
 327.176 +	static aiMatrix4x4t& RotationZ(TReal a, aiMatrix4x4t& out);
 327.177 +
 327.178 +	// -------------------------------------------------------------------
 327.179 +	/** Returns a rotation matrix for a rotation around an arbitrary axis.
 327.180 +	 *  @param a Rotation angle, in radians
 327.181 +	 *  @param axis Rotation axis, should be a normalized vector.
 327.182 +	 *  @param out Receives the output matrix
 327.183 +	 *  @return Reference to the output matrix
 327.184 +	 */
 327.185 +	static aiMatrix4x4t& Rotation(TReal a, const aiVector3t<TReal>& axis, 
 327.186 +		aiMatrix4x4t& out);
 327.187 +
 327.188 +	// -------------------------------------------------------------------
 327.189 +	/** @brief Returns a translation matrix 
 327.190 +	 *  @param v Translation vector
 327.191 +	 *  @param out Receives the output matrix
 327.192 +	 *  @return Reference to the output matrix
 327.193 +	 */
 327.194 +	static aiMatrix4x4t& Translation( const aiVector3t<TReal>& v, aiMatrix4x4t& out);
 327.195 +
 327.196 +	// -------------------------------------------------------------------
 327.197 +	/** @brief Returns a scaling matrix 
 327.198 +	 *  @param v Scaling vector
 327.199 +	 *  @param out Receives the output matrix
 327.200 +	 *  @return Reference to the output matrix
 327.201 +	 */
 327.202 +	static aiMatrix4x4t& Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t& out);
 327.203 +
 327.204 +	// -------------------------------------------------------------------
 327.205 +	/** @brief A function for creating a rotation matrix that rotates a
 327.206 +	 *  vector called "from" into another vector called "to".
 327.207 +	 * Input : from[3], to[3] which both must be *normalized* non-zero vectors
 327.208 +	 * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
 327.209 +	 * Authors: Tomas Möller, John Hughes
 327.210 +	 *          "Efficiently Building a Matrix to Rotate One Vector to Another"
 327.211 +	 *          Journal of Graphics Tools, 4(4):1-4, 1999
 327.212 +	 */
 327.213 +	static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from, 
 327.214 +		const aiVector3t<TReal>& to, aiMatrix4x4t& out);
 327.215 +
 327.216 +public:
 327.217 +
 327.218 +	TReal a1, a2, a3, a4;
 327.219 +	TReal b1, b2, b3, b4;
 327.220 +	TReal c1, c2, c3, c4;
 327.221 +	TReal d1, d2, d3, d4;
 327.222 +
 327.223 +} PACK_STRUCT; 
 327.224 +
 327.225 +typedef aiMatrix4x4t<float> aiMatrix4x4;
 327.226 +
 327.227 +#else
 327.228 +
 327.229 +struct aiMatrix4x4 {
 327.230 +	float a1, a2, a3, a4;
 327.231 +	float b1, b2, b3, b4;
 327.232 +	float c1, c2, c3, c4;
 327.233 +	float d1, d2, d3, d4;
 327.234 +};
 327.235 +
 327.236 +
 327.237 +#endif // __cplusplus
 327.238 +
 327.239 +#include "./Compiler/poppack1.h"
 327.240 +
 327.241 +#endif // AI_MATRIX4X4_H_INC
   328.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   328.2 +++ b/libs/assimp/assimp/matrix4x4.inl	Sat Feb 01 19:58:19 2014 +0200
   328.3 @@ -0,0 +1,485 @@
   328.4 +/*
   328.5 +---------------------------------------------------------------------------
   328.6 +Open Asset Import Library (assimp)
   328.7 +---------------------------------------------------------------------------
   328.8 +
   328.9 +Copyright (c) 2006-2012, assimp team
  328.10 +
  328.11 +All rights reserved.
  328.12 +
  328.13 +Redistribution and use of this software in source and binary forms, 
  328.14 +with or without modification, are permitted provided that the following 
  328.15 +conditions are met:
  328.16 +
  328.17 +* Redistributions of source code must retain the above
  328.18 +  copyright notice, this list of conditions and the
  328.19 +  following disclaimer.
  328.20 +
  328.21 +* Redistributions in binary form must reproduce the above
  328.22 +  copyright notice, this list of conditions and the
  328.23 +  following disclaimer in the documentation and/or other
  328.24 +  materials provided with the distribution.
  328.25 +
  328.26 +* Neither the name of the assimp team, nor the names of its
  328.27 +  contributors may be used to endorse or promote products
  328.28 +  derived from this software without specific prior
  328.29 +  written permission of the assimp team.
  328.30 +
  328.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  328.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  328.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  328.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  328.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  328.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  328.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  328.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  328.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  328.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  328.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  328.42 +---------------------------------------------------------------------------
  328.43 +*/
  328.44 +
  328.45 +/** @file aiMatrix4x4t<TReal>.inl
  328.46 + *  @brief Inline implementation of the 4x4 matrix operators
  328.47 + */
  328.48 +#ifndef AI_MATRIX4x4_INL_INC
  328.49 +#define AI_MATRIX4x4_INL_INC
  328.50 +
  328.51 +#ifdef __cplusplus
  328.52 +
  328.53 +#include "matrix4x4.h"
  328.54 +#include "matrix3x3.h"
  328.55 +#include "quaternion.h"
  328.56 +
  328.57 +#include <algorithm>
  328.58 +#include <limits>
  328.59 +#include <math.h>
  328.60 +
  328.61 +// ----------------------------------------------------------------------------------------
  328.62 +template <typename TReal>
  328.63 +aiMatrix4x4t<TReal> ::aiMatrix4x4t () :	
  328.64 +	a1(1.0f), a2(), a3(), a4(), 
  328.65 +	b1(), b2(1.0f), b3(), b4(), 
  328.66 +	c1(), c2(), c3(1.0f), c4(),
  328.67 +	d1(), d2(), d3(), d4(1.0f)
  328.68 +{
  328.69 +
  328.70 +}
  328.71 +
  328.72 +// ----------------------------------------------------------------------------------------
  328.73 +template <typename TReal>
  328.74 +aiMatrix4x4t<TReal> ::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4,
  328.75 +			  TReal _b1, TReal _b2, TReal _b3, TReal _b4,
  328.76 +			  TReal _c1, TReal _c2, TReal _c3, TReal _c4,
  328.77 +			  TReal _d1, TReal _d2, TReal _d3, TReal _d4) :	
  328.78 +	a1(_a1), a2(_a2), a3(_a3), a4(_a4),  
  328.79 +	b1(_b1), b2(_b2), b3(_b3), b4(_b4), 
  328.80 +	c1(_c1), c2(_c2), c3(_c3), c4(_c4),
  328.81 +	d1(_d1), d2(_d2), d3(_d3), d4(_d4)
  328.82 +{
  328.83 +	
  328.84 +}
  328.85 +
  328.86 +// ------------------------------------------------------------------------------------------------
  328.87 +template <typename TReal>
  328.88 +template <typename TOther>
  328.89 +aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
  328.90 +{
  328.91 +	return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4),
  328.92 +		static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4),
  328.93 +		static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4),
  328.94 +		static_cast<TOther>(d1),static_cast<TOther>(d2),static_cast<TOther>(d3),static_cast<TOther>(d4));
  328.95 +}
  328.96 +
  328.97 +
  328.98 +// ----------------------------------------------------------------------------------------
  328.99 +template <typename TReal>
 328.100 +inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
 328.101 +{
 328.102 +	a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0);
 328.103 +	b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0);
 328.104 +	c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0);
 328.105 +	d1 = static_cast<TReal>(0.0); d2 = static_cast<TReal>(0.0); d3 = static_cast<TReal>(0.0); d4 = static_cast<TReal>(1.0);
 328.106 +}
 328.107 +
 328.108 +// ----------------------------------------------------------------------------------------
 328.109 +template <typename TReal>
 328.110 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m)
 328.111 +{
 328.112 +	*this = aiMatrix4x4t<TReal>(
 328.113 +		m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4,
 328.114 +		m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4,
 328.115 +		m.a3 * a1 + m.b3 * a2 + m.c3 * a3 + m.d3 * a4,
 328.116 +		m.a4 * a1 + m.b4 * a2 + m.c4 * a3 + m.d4 * a4,
 328.117 +		m.a1 * b1 + m.b1 * b2 + m.c1 * b3 + m.d1 * b4,
 328.118 +		m.a2 * b1 + m.b2 * b2 + m.c2 * b3 + m.d2 * b4,
 328.119 +		m.a3 * b1 + m.b3 * b2 + m.c3 * b3 + m.d3 * b4,
 328.120 +		m.a4 * b1 + m.b4 * b2 + m.c4 * b3 + m.d4 * b4,
 328.121 +		m.a1 * c1 + m.b1 * c2 + m.c1 * c3 + m.d1 * c4,
 328.122 +		m.a2 * c1 + m.b2 * c2 + m.c2 * c3 + m.d2 * c4,
 328.123 +		m.a3 * c1 + m.b3 * c2 + m.c3 * c3 + m.d3 * c4,
 328.124 +		m.a4 * c1 + m.b4 * c2 + m.c4 * c3 + m.d4 * c4,
 328.125 +		m.a1 * d1 + m.b1 * d2 + m.c1 * d3 + m.d1 * d4,
 328.126 +		m.a2 * d1 + m.b2 * d2 + m.c2 * d3 + m.d2 * d4,
 328.127 +		m.a3 * d1 + m.b3 * d2 + m.c3 * d3 + m.d3 * d4,
 328.128 +		m.a4 * d1 + m.b4 * d2 + m.c4 * d3 + m.d4 * d4);
 328.129 +	return *this;
 328.130 +}
 328.131 +
 328.132 +// ----------------------------------------------------------------------------------------
 328.133 +template <typename TReal>
 328.134 +inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const
 328.135 +{
 328.136 +	aiMatrix4x4t<TReal> temp( *this);
 328.137 +	temp *= m;
 328.138 +	return temp;
 328.139 +}
 328.140 +
 328.141 +
 328.142 +// ----------------------------------------------------------------------------------------
 328.143 +template <typename TReal>
 328.144 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
 328.145 +{
 328.146 +	// (TReal&) don't remove, GCC complains cause of packed fields
 328.147 +	std::swap( (TReal&)b1, (TReal&)a2);
 328.148 +	std::swap( (TReal&)c1, (TReal&)a3);
 328.149 +	std::swap( (TReal&)c2, (TReal&)b3);
 328.150 +	std::swap( (TReal&)d1, (TReal&)a4);
 328.151 +	std::swap( (TReal&)d2, (TReal&)b4);
 328.152 +	std::swap( (TReal&)d3, (TReal&)c4);
 328.153 +	return *this;
 328.154 +}
 328.155 +
 328.156 +
 328.157 +// ----------------------------------------------------------------------------------------
 328.158 +template <typename TReal>
 328.159 +inline TReal aiMatrix4x4t<TReal>::Determinant() const
 328.160 +{
 328.161 +	return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4 
 328.162 +		+ a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4 
 328.163 +		- a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3 
 328.164 +		+ a3*b4*c1*d2 - a3*b4*c2*d1 + a3*b1*c2*d4 - a3*b1*c4*d2 
 328.165 +		+ a3*b2*c4*d1 - a3*b2*c1*d4 - a4*b1*c2*d3 + a4*b1*c3*d2
 328.166 +		- a4*b2*c3*d1 + a4*b2*c1*d3 - a4*b3*c1*d2 + a4*b3*c2*d1;
 328.167 +}
 328.168 +
 328.169 +// ----------------------------------------------------------------------------------------
 328.170 +template <typename TReal>
 328.171 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
 328.172 +{
 328.173 +	// Compute the reciprocal determinant
 328.174 +	const TReal det = Determinant();
 328.175 +	if(det == static_cast<TReal>(0.0)) 
 328.176 +	{
 328.177 +		// Matrix not invertible. Setting all elements to nan is not really
 328.178 +		// correct in a mathematical sense but it is easy to debug for the
 328.179 +		// programmer.
 328.180 +		const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
 328.181 +		*this = aiMatrix4x4t<TReal>(
 328.182 +			nan,nan,nan,nan,
 328.183 +			nan,nan,nan,nan,
 328.184 +			nan,nan,nan,nan,
 328.185 +			nan,nan,nan,nan);
 328.186 +
 328.187 +		return *this;
 328.188 +	}
 328.189 +
 328.190 +	const TReal invdet = static_cast<TReal>(1.0) / det;
 328.191 +
 328.192 +	aiMatrix4x4t<TReal> res;
 328.193 +	res.a1 = invdet  * (b2 * (c3 * d4 - c4 * d3) + b3 * (c4 * d2 - c2 * d4) + b4 * (c2 * d3 - c3 * d2));
 328.194 +	res.a2 = -invdet * (a2 * (c3 * d4 - c4 * d3) + a3 * (c4 * d2 - c2 * d4) + a4 * (c2 * d3 - c3 * d2));
 328.195 +	res.a3 = invdet  * (a2 * (b3 * d4 - b4 * d3) + a3 * (b4 * d2 - b2 * d4) + a4 * (b2 * d3 - b3 * d2));
 328.196 +	res.a4 = -invdet * (a2 * (b3 * c4 - b4 * c3) + a3 * (b4 * c2 - b2 * c4) + a4 * (b2 * c3 - b3 * c2));
 328.197 +	res.b1 = -invdet * (b1 * (c3 * d4 - c4 * d3) + b3 * (c4 * d1 - c1 * d4) + b4 * (c1 * d3 - c3 * d1));
 328.198 +	res.b2 = invdet  * (a1 * (c3 * d4 - c4 * d3) + a3 * (c4 * d1 - c1 * d4) + a4 * (c1 * d3 - c3 * d1));
 328.199 +	res.b3 = -invdet * (a1 * (b3 * d4 - b4 * d3) + a3 * (b4 * d1 - b1 * d4) + a4 * (b1 * d3 - b3 * d1));
 328.200 +	res.b4 = invdet  * (a1 * (b3 * c4 - b4 * c3) + a3 * (b4 * c1 - b1 * c4) + a4 * (b1 * c3 - b3 * c1));
 328.201 +	res.c1 = invdet  * (b1 * (c2 * d4 - c4 * d2) + b2 * (c4 * d1 - c1 * d4) + b4 * (c1 * d2 - c2 * d1));
 328.202 +	res.c2 = -invdet * (a1 * (c2 * d4 - c4 * d2) + a2 * (c4 * d1 - c1 * d4) + a4 * (c1 * d2 - c2 * d1));
 328.203 +	res.c3 = invdet  * (a1 * (b2 * d4 - b4 * d2) + a2 * (b4 * d1 - b1 * d4) + a4 * (b1 * d2 - b2 * d1));
 328.204 +	res.c4 = -invdet * (a1 * (b2 * c4 - b4 * c2) + a2 * (b4 * c1 - b1 * c4) + a4 * (b1 * c2 - b2 * c1));
 328.205 +	res.d1 = -invdet * (b1 * (c2 * d3 - c3 * d2) + b2 * (c3 * d1 - c1 * d3) + b3 * (c1 * d2 - c2 * d1));
 328.206 +	res.d2 = invdet  * (a1 * (c2 * d3 - c3 * d2) + a2 * (c3 * d1 - c1 * d3) + a3 * (c1 * d2 - c2 * d1));
 328.207 +	res.d3 = -invdet * (a1 * (b2 * d3 - b3 * d2) + a2 * (b3 * d1 - b1 * d3) + a3 * (b1 * d2 - b2 * d1));
 328.208 +	res.d4 = invdet  * (a1 * (b2 * c3 - b3 * c2) + a2 * (b3 * c1 - b1 * c3) + a3 * (b1 * c2 - b2 * c1)); 
 328.209 +	*this = res;
 328.210 +
 328.211 +	return *this;
 328.212 +}
 328.213 +
 328.214 +// ----------------------------------------------------------------------------------------
 328.215 +template <typename TReal>
 328.216 +inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex)
 328.217 +{
 328.218 +	// XXX this is UB. Has been for years. The fact that it works now does not make it better.
 328.219 +	return &this->a1 + p_iIndex * 4;
 328.220 +}
 328.221 +
 328.222 +// ----------------------------------------------------------------------------------------
 328.223 +template <typename TReal>
 328.224 +inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const
 328.225 +{
 328.226 +	// XXX same
 328.227 +	return &this->a1 + p_iIndex * 4;
 328.228 +}
 328.229 +
 328.230 +// ----------------------------------------------------------------------------------------
 328.231 +template <typename TReal>
 328.232 +inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
 328.233 +{
 328.234 +	return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
 328.235 +			b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
 328.236 +			c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 &&
 328.237 +			d1 == m.d1 && d2 == m.d2 && d3 == m.d3 && d4 == m.d4);
 328.238 +}
 328.239 +
 328.240 +// ----------------------------------------------------------------------------------------
 328.241 +template <typename TReal>
 328.242 +inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const
 328.243 +{
 328.244 +	return !(*this == m);
 328.245 +}
 328.246 +
 328.247 +// ----------------------------------------------------------------------------------------
 328.248 +template <typename TReal>
 328.249 +inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
 328.250 +	aiVector3t<TReal>& position) const
 328.251 +{
 328.252 +	const aiMatrix4x4t<TReal>& _this = *this;
 328.253 +
 328.254 +	// extract translation
 328.255 +	position.x = _this[0][3];
 328.256 +	position.y = _this[1][3];
 328.257 +	position.z = _this[2][3];
 328.258 +
 328.259 +	// extract the rows of the matrix
 328.260 +	aiVector3t<TReal> vRows[3] = {
 328.261 +		aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]),
 328.262 +		aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]),
 328.263 +		aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2])
 328.264 +	};
 328.265 +
 328.266 +	// extract the scaling factors
 328.267 +	scaling.x = vRows[0].Length();
 328.268 +	scaling.y = vRows[1].Length();
 328.269 +	scaling.z = vRows[2].Length();
 328.270 +
 328.271 +	// and the sign of the scaling
 328.272 +	if (Determinant() < 0) {
 328.273 +		scaling.x = -scaling.x;
 328.274 +		scaling.y = -scaling.y;
 328.275 +		scaling.z = -scaling.z;
 328.276 +	}
 328.277 +
 328.278 +	// and remove all scaling from the matrix
 328.279 +	if(scaling.x)
 328.280 +	{
 328.281 +		vRows[0] /= scaling.x;
 328.282 +	}
 328.283 +	if(scaling.y)
 328.284 +	{
 328.285 +		vRows[1] /= scaling.y;
 328.286 +	}
 328.287 +	if(scaling.z)
 328.288 +	{
 328.289 +		vRows[2] /= scaling.z;
 328.290 +	}
 328.291 +
 328.292 +	// build a 3x3 rotation matrix
 328.293 +	aiMatrix3x3t<TReal> m(vRows[0].x,vRows[1].x,vRows[2].x,
 328.294 +		vRows[0].y,vRows[1].y,vRows[2].y,
 328.295 +		vRows[0].z,vRows[1].z,vRows[2].z);
 328.296 +
 328.297 +	// and generate the rotation quaternion from it
 328.298 +	rotation = aiQuaterniont<TReal>(m);
 328.299 +}
 328.300 +
 328.301 +// ----------------------------------------------------------------------------------------
 328.302 +template <typename TReal>
 328.303 +inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
 328.304 +	aiVector3t<TReal>& position) const
 328.305 +{
 328.306 +	const aiMatrix4x4t<TReal>& _this = *this;
 328.307 +
 328.308 +	// extract translation
 328.309 +	position.x = _this[0][3];
 328.310 +	position.y = _this[1][3];
 328.311 +	position.z = _this[2][3];
 328.312 +
 328.313 +	// extract rotation
 328.314 +	rotation = aiQuaterniont<TReal>((aiMatrix3x3t<TReal>)_this);
 328.315 +}
 328.316 +
 328.317 +// ----------------------------------------------------------------------------------------
 328.318 +template <typename TReal>
 328.319 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb)
 328.320 +{
 328.321 +	return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z);
 328.322 +}
 328.323 +
 328.324 +// ----------------------------------------------------------------------------------------
 328.325 +template <typename TReal>
 328.326 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z)
 328.327 +{
 328.328 +	aiMatrix4x4t<TReal>& _this = *this;
 328.329 +
 328.330 +	TReal cr = cos( x );
 328.331 +	TReal sr = sin( x );
 328.332 +	TReal cp = cos( y );
 328.333 +	TReal sp = sin( y );
 328.334 +	TReal cy = cos( z );
 328.335 +	TReal sy = sin( z );
 328.336 +
 328.337 +	_this.a1 = cp*cy ;
 328.338 +	_this.a2 = cp*sy;
 328.339 +	_this.a3 = -sp ;
 328.340 +
 328.341 +	TReal srsp = sr*sp;
 328.342 +	TReal crsp = cr*sp;
 328.343 +
 328.344 +	_this.b1 = srsp*cy-cr*sy ;
 328.345 +	_this.b2 = srsp*sy+cr*cy ;
 328.346 +	_this.b3 = sr*cp ;
 328.347 +
 328.348 +	_this.c1 =  crsp*cy+sr*sy ;
 328.349 +	_this.c2 =  crsp*sy-sr*cy ;
 328.350 +	_this.c3 = cr*cp ;
 328.351 +
 328.352 +	return *this;
 328.353 +}
 328.354 +
 328.355 +// ----------------------------------------------------------------------------------------
 328.356 +template <typename TReal>
 328.357 +inline bool aiMatrix4x4t<TReal>::IsIdentity() const
 328.358 +{
 328.359 +	// Use a small epsilon to solve floating-point inaccuracies
 328.360 +	const static TReal epsilon = 10e-3f;
 328.361 +
 328.362 +	return (a2 <= epsilon && a2 >= -epsilon &&
 328.363 +			a3 <= epsilon && a3 >= -epsilon &&
 328.364 +			a4 <= epsilon && a4 >= -epsilon &&
 328.365 +			b1 <= epsilon && b1 >= -epsilon &&
 328.366 +			b3 <= epsilon && b3 >= -epsilon &&
 328.367 +			b4 <= epsilon && b4 >= -epsilon &&
 328.368 +			c1 <= epsilon && c1 >= -epsilon &&
 328.369 +			c2 <= epsilon && c2 >= -epsilon &&
 328.370 +			c4 <= epsilon && c4 >= -epsilon &&
 328.371 +			d1 <= epsilon && d1 >= -epsilon &&
 328.372 +			d2 <= epsilon && d2 >= -epsilon &&
 328.373 +			d3 <= epsilon && d3 >= -epsilon &&
 328.374 +			a1 <= 1.f+epsilon && a1 >= 1.f-epsilon && 
 328.375 +			b2 <= 1.f+epsilon && b2 >= 1.f-epsilon && 
 328.376 +			c3 <= 1.f+epsilon && c3 >= 1.f-epsilon && 
 328.377 +			d4 <= 1.f+epsilon && d4 >= 1.f-epsilon);
 328.378 +}
 328.379 +
 328.380 +// ----------------------------------------------------------------------------------------
 328.381 +template <typename TReal>
 328.382 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out)
 328.383 +{
 328.384 +	/*
 328.385 +	     |  1  0       0       0 |
 328.386 +     M = |  0  cos(A) -sin(A)  0 |
 328.387 +         |  0  sin(A)  cos(A)  0 |
 328.388 +         |  0  0       0       1 |	*/
 328.389 +	out = aiMatrix4x4t<TReal>();
 328.390 +	out.b2 = out.c3 = cos(a);
 328.391 +	out.b3 = -(out.c2 = sin(a));
 328.392 +	return out;
 328.393 +}
 328.394 +
 328.395 +// ----------------------------------------------------------------------------------------
 328.396 +template <typename TReal>
 328.397 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out)
 328.398 +{
 328.399 +	/*
 328.400 +	     |  cos(A)  0   sin(A)  0 |
 328.401 +     M = |  0       1   0       0 |
 328.402 +         | -sin(A)  0   cos(A)  0 |
 328.403 +         |  0       0   0       1 |
 328.404 +		*/
 328.405 +	out = aiMatrix4x4t<TReal>();
 328.406 +	out.a1 = out.c3 = cos(a);
 328.407 +	out.c1 = -(out.a3 = sin(a));
 328.408 +	return out;
 328.409 +}
 328.410 +
 328.411 +// ----------------------------------------------------------------------------------------
 328.412 +template <typename TReal>
 328.413 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out)
 328.414 +{
 328.415 +	/*
 328.416 +	     |  cos(A)  -sin(A)   0   0 |
 328.417 +     M = |  sin(A)   cos(A)   0   0 |
 328.418 +         |  0        0        1   0 |
 328.419 +         |  0        0        0   1 |	*/
 328.420 +	out = aiMatrix4x4t<TReal>();
 328.421 +	out.a1 = out.b2 = cos(a);
 328.422 +	out.a2 = -(out.b1 = sin(a));
 328.423 +	return out;
 328.424 +}
 328.425 +
 328.426 +// ----------------------------------------------------------------------------------------
 328.427 +// Returns a rotation matrix for a rotation around an arbitrary axis.
 328.428 +template <typename TReal>
 328.429 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out)
 328.430 +{
 328.431 +  TReal c = cos( a), s = sin( a), t = 1 - c;
 328.432 +  TReal x = axis.x, y = axis.y, z = axis.z;
 328.433 +
 328.434 +  // Many thanks to MathWorld and Wikipedia
 328.435 +  out.a1 = t*x*x + c;   out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
 328.436 +  out.b1 = t*x*y + s*z; out.b2 = t*y*y + c;   out.b3 = t*y*z - s*x;
 328.437 +  out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
 328.438 +  out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
 328.439 +  out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
 328.440 +  out.d4 = static_cast<TReal>(1.0);
 328.441 +
 328.442 +  return out;
 328.443 +}
 328.444 +
 328.445 +// ----------------------------------------------------------------------------------------
 328.446 +template <typename TReal>
 328.447 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
 328.448 +{
 328.449 +	out = aiMatrix4x4t<TReal>();
 328.450 +	out.a4 = v.x;
 328.451 +	out.b4 = v.y;
 328.452 +	out.c4 = v.z;
 328.453 +	return out;
 328.454 +}
 328.455 +
 328.456 +// ----------------------------------------------------------------------------------------
 328.457 +template <typename TReal>
 328.458 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
 328.459 +{
 328.460 +	out = aiMatrix4x4t<TReal>();
 328.461 +	out.a1 = v.x;
 328.462 +	out.b2 = v.y;
 328.463 +	out.c3 = v.z;
 328.464 +	return out;
 328.465 +}
 328.466 +
 328.467 +// ----------------------------------------------------------------------------------------
 328.468 +/** A function for creating a rotation matrix that rotates a vector called
 328.469 + * "from" into another vector called "to".
 328.470 + * Input : from[3], to[3] which both must be *normalized* non-zero vectors
 328.471 + * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
 328.472 + * Authors: Tomas Möller, John Hughes
 328.473 + *          "Efficiently Building a Matrix to Rotate One Vector to Another"
 328.474 + *          Journal of Graphics Tools, 4(4):1-4, 1999
 328.475 + */
 328.476 +// ----------------------------------------------------------------------------------------
 328.477 +template <typename TReal>
 328.478 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from, 
 328.479 +	const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx)
 328.480 +{	
 328.481 +	aiMatrix3x3t<TReal> m3;
 328.482 +	aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3);
 328.483 +	mtx = aiMatrix4x4t<TReal>(m3);
 328.484 +	return mtx;
 328.485 +}
 328.486 +
 328.487 +#endif // __cplusplus
 328.488 +#endif // AI_MATRIX4x4_INL_INC
   329.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   329.2 +++ b/libs/assimp/assimp/mesh.h	Sat Feb 01 19:58:19 2014 +0200
   329.3 @@ -0,0 +1,740 @@
   329.4 +/*
   329.5 +---------------------------------------------------------------------------
   329.6 +Open Asset Import Library (assimp)
   329.7 +---------------------------------------------------------------------------
   329.8 +
   329.9 +Copyright (c) 2006-2012, assimp team
  329.10 +
  329.11 +All rights reserved.
  329.12 +
  329.13 +Redistribution and use of this software in source and binary forms, 
  329.14 +with or without modification, are permitted provided that the following 
  329.15 +conditions are met:
  329.16 +
  329.17 +* Redistributions of source code must retain the above
  329.18 +  copyright notice, this list of conditions and the
  329.19 +  following disclaimer.
  329.20 +
  329.21 +* Redistributions in binary form must reproduce the above
  329.22 +  copyright notice, this list of conditions and the
  329.23 +  following disclaimer in the documentation and/or other
  329.24 +  materials provided with the distribution.
  329.25 +
  329.26 +* Neither the name of the assimp team, nor the names of its
  329.27 +  contributors may be used to endorse or promote products
  329.28 +  derived from this software without specific prior
  329.29 +  written permission of the assimp team.
  329.30 +
  329.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  329.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  329.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  329.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  329.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  329.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  329.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  329.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  329.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  329.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  329.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  329.42 +---------------------------------------------------------------------------
  329.43 +*/
  329.44 +
  329.45 +/** @file mesh.h
  329.46 + *  @brief Declares the data structures in which the imported geometry is 
  329.47 +    returned by ASSIMP: aiMesh, aiFace and aiBone data structures.
  329.48 + */
  329.49 +#ifndef INCLUDED_AI_MESH_H
  329.50 +#define INCLUDED_AI_MESH_H
  329.51 +
  329.52 +#include "types.h"
  329.53 +
  329.54 +#ifdef __cplusplus
  329.55 +extern "C" {
  329.56 +#endif
  329.57 +
  329.58 +// ---------------------------------------------------------------------------
  329.59 +// Limits. These values are required to match the settings Assimp was 
  329.60 +// compiled against. Therfore, do not redefine them unless you build the 
  329.61 +// library from source using the same definitions.
  329.62 +// ---------------------------------------------------------------------------
  329.63 +
  329.64 +/** @def AI_MAX_FACE_INDICES
  329.65 + *  Maximum number of indices per face (polygon). */
  329.66 +
  329.67 +#ifndef AI_MAX_FACE_INDICES 
  329.68 +#	define AI_MAX_FACE_INDICES 0x7fff
  329.69 +#endif
  329.70 +
  329.71 +/** @def AI_MAX_BONE_WEIGHTS
  329.72 + *  Maximum number of indices per face (polygon). */
  329.73 +
  329.74 +#ifndef AI_MAX_BONE_WEIGHTS
  329.75 +#	define AI_MAX_BONE_WEIGHTS 0x7fffffff
  329.76 +#endif
  329.77 +
  329.78 +/** @def AI_MAX_VERTICES
  329.79 + *  Maximum number of vertices per mesh.  */
  329.80 +
  329.81 +#ifndef AI_MAX_VERTICES
  329.82 +#	define AI_MAX_VERTICES 0x7fffffff
  329.83 +#endif
  329.84 +
  329.85 +/** @def AI_MAX_FACES
  329.86 + *  Maximum number of faces per mesh. */
  329.87 +
  329.88 +#ifndef AI_MAX_FACES
  329.89 +#	define AI_MAX_FACES 0x7fffffff
  329.90 +#endif
  329.91 +
  329.92 +/** @def AI_MAX_NUMBER_OF_COLOR_SETS
  329.93 + *  Supported number of vertex color sets per mesh. */
  329.94 +
  329.95 +#ifndef AI_MAX_NUMBER_OF_COLOR_SETS
  329.96 +#	define AI_MAX_NUMBER_OF_COLOR_SETS 0x8
  329.97 +#endif // !! AI_MAX_NUMBER_OF_COLOR_SETS
  329.98 +
  329.99 +/** @def AI_MAX_NUMBER_OF_TEXTURECOORDS
 329.100 + *  Supported number of texture coord sets (UV(W) channels) per mesh */
 329.101 +
 329.102 +#ifndef AI_MAX_NUMBER_OF_TEXTURECOORDS
 329.103 +#	define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x8
 329.104 +#endif // !! AI_MAX_NUMBER_OF_TEXTURECOORDS
 329.105 +
 329.106 +// ---------------------------------------------------------------------------
 329.107 +/** @brief A single face in a mesh, referring to multiple vertices. 
 329.108 + *
 329.109 + * If mNumIndices is 3, we call the face 'triangle', for mNumIndices > 3 
 329.110 + * it's called 'polygon' (hey, that's just a definition!).
 329.111 + * <br>
 329.112 + * aiMesh::mPrimitiveTypes can be queried to quickly examine which types of
 329.113 + * primitive are actually present in a mesh. The #aiProcess_SortByPType flag 
 329.114 + * executes a special post-processing algorithm which splits meshes with
 329.115 + * *different* primitive types mixed up (e.g. lines and triangles) in several
 329.116 + * 'clean' submeshes. Furthermore there is a configuration option (
 329.117 + * #AI_CONFIG_PP_SBP_REMOVE) to force #aiProcess_SortByPType to remove 
 329.118 + * specific kinds of primitives from the imported scene, completely and forever.
 329.119 + * In many cases you'll probably want to set this setting to 
 329.120 + * @code 
 329.121 + * aiPrimitiveType_LINE|aiPrimitiveType_POINT
 329.122 + * @endcode
 329.123 + * Together with the #aiProcess_Triangulate flag you can then be sure that
 329.124 + * #aiFace::mNumIndices is always 3. 
 329.125 + * @note Take a look at the @link data Data Structures page @endlink for
 329.126 + * more information on the layout and winding order of a face.
 329.127 + */
 329.128 +struct aiFace
 329.129 +{
 329.130 +	//! Number of indices defining this face. 
 329.131 +	//! The maximum value for this member is #AI_MAX_FACE_INDICES.
 329.132 +	unsigned int mNumIndices; 
 329.133 +
 329.134 +	//! Pointer to the indices array. Size of the array is given in numIndices.
 329.135 +	unsigned int* mIndices;   
 329.136 +
 329.137 +#ifdef __cplusplus
 329.138 +
 329.139 +	//! Default constructor
 329.140 +	aiFace()
 329.141 +      : mNumIndices( 0 )
 329.142 +      , mIndices( NULL )
 329.143 +	{
 329.144 +	}
 329.145 +
 329.146 +	//! Default destructor. Delete the index array
 329.147 +	~aiFace()
 329.148 +	{
 329.149 +		delete [] mIndices;
 329.150 +	}
 329.151 +
 329.152 +	//! Copy constructor. Copy the index array
 329.153 +	aiFace( const aiFace& o)
 329.154 +      : mIndices( NULL )
 329.155 +	{
 329.156 +		*this = o;
 329.157 +	}
 329.158 +
 329.159 +	//! Assignment operator. Copy the index array
 329.160 +	aiFace& operator = ( const aiFace& o)
 329.161 +	{
 329.162 +		if (&o == this)
 329.163 +			return *this;
 329.164 +
 329.165 +		delete[] mIndices;
 329.166 +		mNumIndices = o.mNumIndices;
 329.167 +		if (mNumIndices) {
 329.168 +			mIndices = new unsigned int[mNumIndices];
 329.169 +			::memcpy( mIndices, o.mIndices, mNumIndices * sizeof( unsigned int));
 329.170 +		}
 329.171 +		else {
 329.172 +			mIndices = NULL;
 329.173 +		}
 329.174 +		return *this;
 329.175 +	}
 329.176 +
 329.177 +	//! Comparison operator. Checks whether the index array 
 329.178 +	//! of two faces is identical
 329.179 +	bool operator== (const aiFace& o) const
 329.180 +	{
 329.181 +		if (mIndices == o.mIndices)return true;
 329.182 +		else if (mIndices && mNumIndices == o.mNumIndices)
 329.183 +		{
 329.184 +			for (unsigned int i = 0;i < this->mNumIndices;++i)
 329.185 +				if (mIndices[i] != o.mIndices[i])return false;
 329.186 +			return true;
 329.187 +		}
 329.188 +		return false;
 329.189 +	}
 329.190 +
 329.191 +	//! Inverse comparison operator. Checks whether the index 
 329.192 +	//! array of two faces is NOT identical
 329.193 +	bool operator != (const aiFace& o) const
 329.194 +	{
 329.195 +		return !(*this == o);
 329.196 +	}
 329.197 +#endif // __cplusplus
 329.198 +}; // struct aiFace
 329.199 +
 329.200 +
 329.201 +// ---------------------------------------------------------------------------
 329.202 +/** @brief A single influence of a bone on a vertex.
 329.203 + */
 329.204 +struct aiVertexWeight
 329.205 +{
 329.206 +	//! Index of the vertex which is influenced by the bone.
 329.207 +	unsigned int mVertexId;
 329.208 +
 329.209 +	//! The strength of the influence in the range (0...1).
 329.210 +	//! The influence from all bones at one vertex amounts to 1.
 329.211 +	float mWeight;     
 329.212 +
 329.213 +#ifdef __cplusplus
 329.214 +
 329.215 +	//! Default constructor
 329.216 +	aiVertexWeight() { }
 329.217 +
 329.218 +	//! Initialisation from a given index and vertex weight factor
 329.219 +	//! \param pID ID
 329.220 +	//! \param pWeight Vertex weight factor
 329.221 +	aiVertexWeight( unsigned int pID, float pWeight) 
 329.222 +		: mVertexId( pID), mWeight( pWeight) 
 329.223 +	{ /* nothing to do here */ }
 329.224 +
 329.225 +#endif // __cplusplus
 329.226 +};
 329.227 +
 329.228 +
 329.229 +// ---------------------------------------------------------------------------
 329.230 +/** @brief A single bone of a mesh.
 329.231 + *
 329.232 + *  A bone has a name by which it can be found in the frame hierarchy and by
 329.233 + *  which it can be addressed by animations. In addition it has a number of 
 329.234 + *  influences on vertices.
 329.235 + */
 329.236 +struct aiBone
 329.237 +{
 329.238 +	//! The name of the bone. 
 329.239 +	C_STRUCT aiString mName;
 329.240 +
 329.241 +	//! The number of vertices affected by this bone
 329.242 +	//! The maximum value for this member is #AI_MAX_BONE_WEIGHTS.
 329.243 +	unsigned int mNumWeights;
 329.244 +
 329.245 +	//! The vertices affected by this bone
 329.246 +	C_STRUCT aiVertexWeight* mWeights;
 329.247 +
 329.248 +	//! Matrix that transforms from mesh space to bone space in bind pose
 329.249 +	C_STRUCT aiMatrix4x4 mOffsetMatrix;
 329.250 +
 329.251 +#ifdef __cplusplus
 329.252 +
 329.253 +	//! Default constructor
 329.254 +	aiBone()
 329.255 +      : mNumWeights( 0 )
 329.256 +      , mWeights( NULL )
 329.257 +	{
 329.258 +	}
 329.259 +
 329.260 +	//! Copy constructor
 329.261 +	aiBone(const aiBone& other)
 329.262 +      : mName( other.mName )
 329.263 +      , mNumWeights( other.mNumWeights )
 329.264 +      , mOffsetMatrix( other.mOffsetMatrix )
 329.265 +	{
 329.266 +		if (other.mWeights && other.mNumWeights)
 329.267 +		{
 329.268 +			mWeights = new aiVertexWeight[mNumWeights];
 329.269 +			::memcpy(mWeights,other.mWeights,mNumWeights * sizeof(aiVertexWeight));
 329.270 +		}
 329.271 +	}
 329.272 +
 329.273 +	//! Destructor - deletes the array of vertex weights
 329.274 +	~aiBone()
 329.275 +	{
 329.276 +		delete [] mWeights;
 329.277 +	}
 329.278 +#endif // __cplusplus
 329.279 +};
 329.280 +
 329.281 +
 329.282 +// ---------------------------------------------------------------------------
 329.283 +/** @brief Enumerates the types of geometric primitives supported by Assimp.
 329.284 + *  
 329.285 + *  @see aiFace Face data structure
 329.286 + *  @see aiProcess_SortByPType Per-primitive sorting of meshes
 329.287 + *  @see aiProcess_Triangulate Automatic triangulation
 329.288 + *  @see AI_CONFIG_PP_SBP_REMOVE Removal of specific primitive types.
 329.289 + */
 329.290 +enum aiPrimitiveType
 329.291 +{
 329.292 +	/** A point primitive. 
 329.293 +	 *
 329.294 +	 * This is just a single vertex in the virtual world, 
 329.295 +	 * #aiFace contains just one index for such a primitive.
 329.296 +	 */
 329.297 +	aiPrimitiveType_POINT       = 0x1,
 329.298 +
 329.299 +	/** A line primitive. 
 329.300 +	 *
 329.301 +	 * This is a line defined through a start and an end position.
 329.302 +	 * #aiFace contains exactly two indices for such a primitive.
 329.303 +	 */
 329.304 +	aiPrimitiveType_LINE        = 0x2,
 329.305 +
 329.306 +	/** A triangular primitive. 
 329.307 +	 *
 329.308 +	 * A triangle consists of three indices.
 329.309 +	 */
 329.310 +	aiPrimitiveType_TRIANGLE    = 0x4,
 329.311 +
 329.312 +	/** A higher-level polygon with more than 3 edges.
 329.313 +	 *
 329.314 +	 * A triangle is a polygon, but polygon in this context means
 329.315 +	 * "all polygons that are not triangles". The "Triangulate"-Step
 329.316 +	 * is provided for your convenience, it splits all polygons in
 329.317 +	 * triangles (which are much easier to handle).
 329.318 +	 */
 329.319 +	aiPrimitiveType_POLYGON     = 0x8,
 329.320 +
 329.321 +
 329.322 +	/** This value is not used. It is just here to force the
 329.323 +	 *  compiler to map this enum to a 32 Bit integer.
 329.324 +	 */
 329.325 +#ifndef SWIG
 329.326 +	_aiPrimitiveType_Force32Bit = INT_MAX
 329.327 +#endif
 329.328 +}; //! enum aiPrimitiveType
 329.329 +
 329.330 +// Get the #aiPrimitiveType flag for a specific number of face indices
 329.331 +#define AI_PRIMITIVE_TYPE_FOR_N_INDICES(n) \
 329.332 +	((n) > 3 ? aiPrimitiveType_POLYGON : (aiPrimitiveType)(1u << ((n)-1)))
 329.333 +
 329.334 +
 329.335 +
 329.336 +// ---------------------------------------------------------------------------
 329.337 +/** @brief NOT CURRENTLY IN USE. An AnimMesh is an attachment to an #aiMesh stores per-vertex 
 329.338 + *  animations for a particular frame.
 329.339 + *  
 329.340 + *  You may think of an #aiAnimMesh as a `patch` for the host mesh, which
 329.341 + *  replaces only certain vertex data streams at a particular time. 
 329.342 + *  Each mesh stores n attached attached meshes (#aiMesh::mAnimMeshes).
 329.343 + *  The actual relationship between the time line and anim meshes is 
 329.344 + *  established by #aiMeshAnim, which references singular mesh attachments
 329.345 + *  by their ID and binds them to a time offset.
 329.346 +*/
 329.347 +struct aiAnimMesh
 329.348 +{
 329.349 +	/** Replacement for aiMesh::mVertices. If this array is non-NULL, 
 329.350 +	 *  it *must* contain mNumVertices entries. The corresponding
 329.351 +	 *  array in the host mesh must be non-NULL as well - animation
 329.352 +	 *  meshes may neither add or nor remove vertex components (if
 329.353 +	 *  a replacement array is NULL and the corresponding source
 329.354 +	 *  array is not, the source data is taken instead)*/
 329.355 +	C_STRUCT aiVector3D* mVertices;
 329.356 +
 329.357 +	/** Replacement for aiMesh::mNormals.  */
 329.358 +	C_STRUCT aiVector3D* mNormals;
 329.359 +
 329.360 +	/** Replacement for aiMesh::mTangents. */
 329.361 +	C_STRUCT aiVector3D* mTangents;
 329.362 +
 329.363 +	/** Replacement for aiMesh::mBitangents. */
 329.364 +	C_STRUCT aiVector3D* mBitangents;
 329.365 +
 329.366 +	/** Replacement for aiMesh::mColors */
 329.367 +	C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
 329.368 +
 329.369 +	/** Replacement for aiMesh::mTextureCoords */
 329.370 +	C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 329.371 +
 329.372 +	/** The number of vertices in the aiAnimMesh, and thus the length of all
 329.373 +	 * the member arrays.
 329.374 +	 *
 329.375 +	 * This has always the same value as the mNumVertices property in the
 329.376 +	 * corresponding aiMesh. It is duplicated here merely to make the length
 329.377 +	 * of the member arrays accessible even if the aiMesh is not known, e.g.
 329.378 +	 * from language bindings.
 329.379 +	 */
 329.380 +	unsigned int mNumVertices;
 329.381 +
 329.382 +#ifdef __cplusplus
 329.383 +
 329.384 +	aiAnimMesh()
 329.385 +		: mVertices( NULL )
 329.386 +		, mNormals( NULL )
 329.387 +		, mTangents( NULL )
 329.388 +		, mBitangents( NULL )
 329.389 +		, mNumVertices( 0 )
 329.390 +	{
 329.391 +		// fixme consider moving this to the ctor initializer list as well
 329.392 +		for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++){
 329.393 +			mTextureCoords[a] = NULL;
 329.394 +		}
 329.395 +		for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
 329.396 +			mColors[a] = NULL;
 329.397 +		}
 329.398 +	}
 329.399 +	
 329.400 +	~aiAnimMesh()
 329.401 +	{
 329.402 +		delete [] mVertices; 
 329.403 +		delete [] mNormals;
 329.404 +		delete [] mTangents;
 329.405 +		delete [] mBitangents;
 329.406 +		for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
 329.407 +			delete [] mTextureCoords[a];
 329.408 +		}
 329.409 +		for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
 329.410 +			delete [] mColors[a];
 329.411 +		}
 329.412 +	}
 329.413 +
 329.414 +	/** Check whether the anim mesh overrides the vertex positions 
 329.415 +	 *  of its host mesh*/ 
 329.416 +	bool HasPositions() const {
 329.417 +		return mVertices != NULL; 
 329.418 +	}
 329.419 +
 329.420 +	/** Check whether the anim mesh overrides the vertex normals
 329.421 +	 *  of its host mesh*/ 
 329.422 +	bool HasNormals() const { 
 329.423 +		return mNormals != NULL; 
 329.424 +	}
 329.425 +
 329.426 +	/** Check whether the anim mesh overrides the vertex tangents
 329.427 +	 *  and bitangents of its host mesh. As for aiMesh,
 329.428 +	 *  tangents and bitangents always go together. */ 
 329.429 +	bool HasTangentsAndBitangents() const { 
 329.430 +		return mTangents != NULL; 
 329.431 +	}
 329.432 +
 329.433 +	/** Check whether the anim mesh overrides a particular
 329.434 +	 * set of vertex colors on his host mesh. 
 329.435 +	 *  @param pIndex 0<index<AI_MAX_NUMBER_OF_COLOR_SETS */ 
 329.436 +	bool HasVertexColors( unsigned int pIndex) const	{ 
 329.437 +		return pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS ? false : mColors[pIndex] != NULL; 
 329.438 +	}
 329.439 +
 329.440 +	/** Check whether the anim mesh overrides a particular
 329.441 +	 * set of texture coordinates on his host mesh. 
 329.442 +	 *  @param pIndex 0<index<AI_MAX_NUMBER_OF_TEXTURECOORDS */ 
 329.443 +	bool HasTextureCoords( unsigned int pIndex) const	{ 
 329.444 +		return pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? false : mTextureCoords[pIndex] != NULL; 
 329.445 +	}
 329.446 +
 329.447 +#endif
 329.448 +};
 329.449 +
 329.450 +
 329.451 +// ---------------------------------------------------------------------------
 329.452 +/** @brief A mesh represents a geometry or model with a single material. 
 329.453 +*
 329.454 +* It usually consists of a number of vertices and a series of primitives/faces 
 329.455 +* referencing the vertices. In addition there might be a series of bones, each 
 329.456 +* of them addressing a number of vertices with a certain weight. Vertex data 
 329.457 +* is presented in channels with each channel containing a single per-vertex 
 329.458 +* information such as a set of texture coords or a normal vector.
 329.459 +* If a data pointer is non-null, the corresponding data stream is present.
 329.460 +* From C++-programs you can also use the comfort functions Has*() to
 329.461 +* test for the presence of various data streams.
 329.462 +*
 329.463 +* A Mesh uses only a single material which is referenced by a material ID.
 329.464 +* @note The mPositions member is usually not optional. However, vertex positions 
 329.465 +* *could* be missing if the #AI_SCENE_FLAGS_INCOMPLETE flag is set in 
 329.466 +* @code
 329.467 +* aiScene::mFlags
 329.468 +* @endcode
 329.469 +*/
 329.470 +struct aiMesh
 329.471 +{
 329.472 +	/** Bitwise combination of the members of the #aiPrimitiveType enum.
 329.473 +	 * This specifies which types of primitives are present in the mesh.
 329.474 +	 * The "SortByPrimitiveType"-Step can be used to make sure the 
 329.475 +	 * output meshes consist of one primitive type each.
 329.476 +	 */
 329.477 +	unsigned int mPrimitiveTypes;
 329.478 +
 329.479 +	/** The number of vertices in this mesh. 
 329.480 +	* This is also the size of all of the per-vertex data arrays.
 329.481 +	* The maximum value for this member is #AI_MAX_VERTICES.
 329.482 +	*/
 329.483 +	unsigned int mNumVertices;
 329.484 +
 329.485 +	/** The number of primitives (triangles, polygons, lines) in this  mesh. 
 329.486 +	* This is also the size of the mFaces array.
 329.487 +	* The maximum value for this member is #AI_MAX_FACES.
 329.488 +	*/
 329.489 +	unsigned int mNumFaces;
 329.490 +
 329.491 +	/** Vertex positions. 
 329.492 +	* This array is always present in a mesh. The array is 
 329.493 +	* mNumVertices in size. 
 329.494 +	*/
 329.495 +	C_STRUCT aiVector3D* mVertices;
 329.496 +
 329.497 +	/** Vertex normals. 
 329.498 +	* The array contains normalized vectors, NULL if not present. 
 329.499 +	* The array is mNumVertices in size. Normals are undefined for
 329.500 +	* point and line primitives. A mesh consisting of points and
 329.501 +	* lines only may not have normal vectors. Meshes with mixed
 329.502 +	* primitive types (i.e. lines and triangles) may have normals,
 329.503 +	* but the normals for vertices that are only referenced by
 329.504 +	* point or line primitives are undefined and set to QNaN (WARN:
 329.505 +	* qNaN compares to inequal to *everything*, even to qNaN itself.
 329.506 +	* Using code like this to check whether a field is qnan is:
 329.507 +	* @code
 329.508 +	* #define IS_QNAN(f) (f != f)
 329.509 +	* @endcode
 329.510 +	* still dangerous because even 1.f == 1.f could evaluate to false! (
 329.511 +	* remember the subtleties of IEEE754 artithmetics). Use stuff like
 329.512 +	* @c fpclassify instead.
 329.513 +	* @note Normal vectors computed by Assimp are always unit-length.
 329.514 +	* However, this needn't apply for normals that have been taken
 329.515 +	*   directly from the model file.
 329.516 +	*/
 329.517 +	C_STRUCT aiVector3D* mNormals;
 329.518 +
 329.519 +	/** Vertex tangents. 
 329.520 +	* The tangent of a vertex points in the direction of the positive 
 329.521 +	* X texture axis. The array contains normalized vectors, NULL if
 329.522 +	* not present. The array is mNumVertices in size. A mesh consisting 
 329.523 +	* of points and lines only may not have normal vectors. Meshes with 
 329.524 +	* mixed primitive types (i.e. lines and triangles) may have 
 329.525 +	* normals, but the normals for vertices that are only referenced by
 329.526 +	* point or line primitives are undefined and set to qNaN.  See
 329.527 +	* the #mNormals member for a detailled discussion of qNaNs.
 329.528 +	* @note If the mesh contains tangents, it automatically also 
 329.529 +	* contains bitangents.
 329.530 +	*/
 329.531 +	C_STRUCT aiVector3D* mTangents;
 329.532 +
 329.533 +	/** Vertex bitangents. 
 329.534 +	* The bitangent of a vertex points in the direction of the positive 
 329.535 +	* Y texture axis. The array contains normalized vectors, NULL if not
 329.536 +	* present. The array is mNumVertices in size. 
 329.537 +	* @note If the mesh contains tangents, it automatically also contains
 329.538 +	* bitangents.  
 329.539 +	*/
 329.540 +	C_STRUCT aiVector3D* mBitangents;
 329.541 +
 329.542 +	/** Vertex color sets. 
 329.543 +	* A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex 
 329.544 +	* colors per vertex. NULL if not present. Each array is
 329.545 +	* mNumVertices in size if present.
 329.546 +	*/
 329.547 +	C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
 329.548 +
 329.549 +	/** Vertex texture coords, also known as UV channels.
 329.550 +	* A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per
 329.551 +	* vertex. NULL if not present. The array is mNumVertices in size. 
 329.552 +	*/
 329.553 +	C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 329.554 +
 329.555 +	/** Specifies the number of components for a given UV channel.
 329.556 +	* Up to three channels are supported (UVW, for accessing volume
 329.557 +	* or cube maps). If the value is 2 for a given channel n, the
 329.558 +	* component p.z of mTextureCoords[n][p] is set to 0.0f.
 329.559 +	* If the value is 1 for a given channel, p.y is set to 0.0f, too.
 329.560 +	* @note 4D coords are not supported 
 329.561 +	*/
 329.562 +	unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 329.563 +
 329.564 +	/** The faces the mesh is constructed from. 
 329.565 +	* Each face refers to a number of vertices by their indices. 
 329.566 +	* This array is always present in a mesh, its size is given 
 329.567 +	* in mNumFaces. If the #AI_SCENE_FLAGS_NON_VERBOSE_FORMAT
 329.568 +	* is NOT set each face references an unique set of vertices.
 329.569 +	*/
 329.570 +	C_STRUCT aiFace* mFaces;
 329.571 +
 329.572 +	/** The number of bones this mesh contains. 
 329.573 +	* Can be 0, in which case the mBones array is NULL. 
 329.574 +	*/
 329.575 +	unsigned int mNumBones;
 329.576 +
 329.577 +	/** The bones of this mesh. 
 329.578 +	* A bone consists of a name by which it can be found in the
 329.579 +	* frame hierarchy and a set of vertex weights.
 329.580 +	*/
 329.581 +	C_STRUCT aiBone** mBones;
 329.582 +
 329.583 +	/** The material used by this mesh. 
 329.584 +	 * A mesh does use only a single material. If an imported model uses
 329.585 +	 * multiple materials, the import splits up the mesh. Use this value 
 329.586 +	 * as index into the scene's material list.
 329.587 +	 */
 329.588 +	unsigned int mMaterialIndex;
 329.589 +
 329.590 +	/** Name of the mesh. Meshes can be named, but this is not a
 329.591 +	 *  requirement and leaving this field empty is totally fine.
 329.592 +	 *  There are mainly three uses for mesh names: 
 329.593 +	 *   - some formats name nodes and meshes independently.
 329.594 +	 *   - importers tend to split meshes up to meet the
 329.595 +	 *      one-material-per-mesh requirement. Assigning
 329.596 +	 *      the same (dummy) name to each of the result meshes
 329.597 +	 *      aids the caller at recovering the original mesh
 329.598 +	 *      partitioning.
 329.599 +	 *   - Vertex animations refer to meshes by their names.
 329.600 +	 **/
 329.601 +	C_STRUCT aiString mName;
 329.602 +
 329.603 +
 329.604 +	/** NOT CURRENTLY IN USE. The number of attachment meshes */
 329.605 +	unsigned int mNumAnimMeshes;
 329.606 +
 329.607 +	/** NOT CURRENTLY IN USE. Attachment meshes for this mesh, for vertex-based animation. 
 329.608 +	 *  Attachment meshes carry replacement data for some of the
 329.609 +	 *  mesh'es vertex components (usually positions, normals). */
 329.610 +	C_STRUCT aiAnimMesh** mAnimMeshes;
 329.611 +
 329.612 +
 329.613 +#ifdef __cplusplus
 329.614 +
 329.615 +	//! Default constructor. Initializes all members to 0
 329.616 +	aiMesh()
 329.617 +		: mPrimitiveTypes( 0 )
 329.618 +		, mNumVertices( 0 )
 329.619 +		, mNumFaces( 0 )
 329.620 +		, mVertices( NULL )
 329.621 +		, mNormals( NULL )
 329.622 +		, mTangents( NULL )
 329.623 +		, mBitangents( NULL )
 329.624 +		, mFaces( NULL )
 329.625 +		, mNumBones( 0 )
 329.626 +		, mBones( 0 )
 329.627 +		, mMaterialIndex( 0 )
 329.628 +		, mNumAnimMeshes( 0 )
 329.629 +		, mAnimMeshes( NULL )
 329.630 +	{
 329.631 +		for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
 329.632 +		{
 329.633 +			mNumUVComponents[a] = 0;
 329.634 +			mTextureCoords[a] = NULL;
 329.635 +		}
 329.636 +      
 329.637 +		for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
 329.638 +			mColors[a] = NULL;
 329.639 +	}
 329.640 +
 329.641 +	//! Deletes all storage allocated for the mesh
 329.642 +	~aiMesh()
 329.643 +	{
 329.644 +		delete [] mVertices; 
 329.645 +		delete [] mNormals;
 329.646 +		delete [] mTangents;
 329.647 +		delete [] mBitangents;
 329.648 +		for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
 329.649 +			delete [] mTextureCoords[a];
 329.650 +		}
 329.651 +		for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
 329.652 +			delete [] mColors[a];
 329.653 +		}
 329.654 +
 329.655 +		// DO NOT REMOVE THIS ADDITIONAL CHECK
 329.656 +		if (mNumBones && mBones)	{
 329.657 +			for( unsigned int a = 0; a < mNumBones; a++) {
 329.658 +				delete mBones[a];
 329.659 +			}
 329.660 +			delete [] mBones;
 329.661 +		}
 329.662 +
 329.663 +		if (mNumAnimMeshes && mAnimMeshes)	{
 329.664 +			for( unsigned int a = 0; a < mNumAnimMeshes; a++) {
 329.665 +				delete mAnimMeshes[a];
 329.666 +			}
 329.667 +			delete [] mAnimMeshes;
 329.668 +		}
 329.669 +
 329.670 +		delete [] mFaces;
 329.671 +	}
 329.672 +
 329.673 +	//! Check whether the mesh contains positions. Provided no special
 329.674 +	//! scene flags are set (such as #AI_SCENE_FLAGS_ANIM_SKELETON_ONLY), 
 329.675 +	//! this will always be true 
 329.676 +	bool HasPositions() const 
 329.677 +		{ return mVertices != NULL && mNumVertices > 0; }
 329.678 +
 329.679 +	//! Check whether the mesh contains faces. If no special scene flags
 329.680 +	//! are set this should always return true
 329.681 +	bool HasFaces() const 
 329.682 +		{ return mFaces != NULL && mNumFaces > 0; }
 329.683 +
 329.684 +	//! Check whether the mesh contains normal vectors
 329.685 +	bool HasNormals() const 
 329.686 +		{ return mNormals != NULL && mNumVertices > 0; }
 329.687 +
 329.688 +	//! Check whether the mesh contains tangent and bitangent vectors
 329.689 +	//! It is not possible that it contains tangents and no bitangents
 329.690 +	//! (or the other way round). The existence of one of them
 329.691 +	//! implies that the second is there, too.
 329.692 +	bool HasTangentsAndBitangents() const 
 329.693 +		{ return mTangents != NULL && mBitangents != NULL && mNumVertices > 0; }
 329.694 +
 329.695 +	//! Check whether the mesh contains a vertex color set
 329.696 +	//! \param pIndex Index of the vertex color set
 329.697 +	bool HasVertexColors( unsigned int pIndex) const
 329.698 +	{ 
 329.699 +		if( pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS) 
 329.700 +			return false; 
 329.701 +		else 
 329.702 +			return mColors[pIndex] != NULL && mNumVertices > 0; 
 329.703 +	}
 329.704 +
 329.705 +	//! Check whether the mesh contains a texture coordinate set
 329.706 +	//! \param pIndex Index of the texture coordinates set
 329.707 +	bool HasTextureCoords( unsigned int pIndex) const
 329.708 +	{ 
 329.709 +		if( pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) 
 329.710 +			return false; 
 329.711 +		else 
 329.712 +			return mTextureCoords[pIndex] != NULL && mNumVertices > 0; 
 329.713 +	}
 329.714 +
 329.715 +	//! Get the number of UV channels the mesh contains
 329.716 +	unsigned int GetNumUVChannels() const 
 329.717 +	{
 329.718 +		unsigned int n = 0;
 329.719 +		while (n < AI_MAX_NUMBER_OF_TEXTURECOORDS && mTextureCoords[n])++n;
 329.720 +		return n;
 329.721 +	}
 329.722 +
 329.723 +	//! Get the number of vertex color channels the mesh contains
 329.724 +	unsigned int GetNumColorChannels() const 
 329.725 +	{
 329.726 +		unsigned int n = 0;
 329.727 +		while (n < AI_MAX_NUMBER_OF_COLOR_SETS && mColors[n])++n;
 329.728 +		return n;
 329.729 +	}
 329.730 +
 329.731 +	//! Check whether the mesh contains bones
 329.732 +	inline bool HasBones() const
 329.733 +		{ return mBones != NULL && mNumBones > 0; }
 329.734 +
 329.735 +#endif // __cplusplus
 329.736 +};
 329.737 +
 329.738 +
 329.739 +#ifdef __cplusplus
 329.740 +}
 329.741 +#endif //! extern "C"
 329.742 +#endif // __AI_MESH_H_INC
 329.743 +
   330.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   330.2 +++ b/libs/assimp/assimp/metadata.h	Sat Feb 01 19:58:19 2014 +0200
   330.3 @@ -0,0 +1,120 @@
   330.4 +/*
   330.5 +---------------------------------------------------------------------------
   330.6 +Open Asset Import Library (assimp)
   330.7 +---------------------------------------------------------------------------
   330.8 +
   330.9 +Copyright (c) 2006-2012, assimp team
  330.10 +
  330.11 +All rights reserved.
  330.12 +
  330.13 +Redistribution and use of this software in source and binary forms, 
  330.14 +with or without modification, are permitted provided that the following 
  330.15 +conditions are met:
  330.16 +
  330.17 +* Redistributions of source code must retain the above
  330.18 +  copyright notice, this list of conditions and the
  330.19 +  following disclaimer.
  330.20 +
  330.21 +* Redistributions in binary form must reproduce the above
  330.22 +  copyright notice, this list of conditions and the
  330.23 +  following disclaimer in the documentation and/or other
  330.24 +  materials provided with the distribution.
  330.25 +
  330.26 +* Neither the name of the assimp team, nor the names of its
  330.27 +  contributors may be used to endorse or promote products
  330.28 +  derived from this software without specific prior
  330.29 +  written permission of the assimp team.
  330.30 +
  330.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  330.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  330.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  330.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  330.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  330.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  330.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  330.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  330.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  330.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  330.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  330.42 +---------------------------------------------------------------------------
  330.43 +*/
  330.44 +
  330.45 +/** @file metadata.h
  330.46 + *  @brief Defines the data structures for holding node meta information.
  330.47 + */
  330.48 +#ifndef __AI_METADATA_H_INC__
  330.49 +#define __AI_METADATA_H_INC__
  330.50 +
  330.51 +#ifdef __cplusplus
  330.52 +extern "C" {
  330.53 +#endif
  330.54 +
  330.55 +// -------------------------------------------------------------------------------
  330.56 +/**
  330.57 +  * Container for holding metadata.
  330.58 +  *
  330.59 +  * Metadata is a key-value store using string keys and values.
  330.60 +  */
  330.61 + // -------------------------------------------------------------------------------
  330.62 +struct aiMetadata 
  330.63 +{
  330.64 +	/** Length of the mKeys and mValues arrays, respectively */
  330.65 +	unsigned int mNumProperties;
  330.66 +
  330.67 +	/** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */
  330.68 +	C_STRUCT aiString** mKeys;
  330.69 +
  330.70 +	/** Arrays of values, may not be NULL. Entries in this array may be NULL if the
  330.71 +	  * corresponding property key has no assigned value. */
  330.72 +	C_STRUCT aiString** mValues;
  330.73 +
  330.74 +#ifdef __cplusplus
  330.75 +
  330.76 +	/** Constructor */
  330.77 +	aiMetadata()
  330.78 +	{
  330.79 +		// set all members to zero by default
  330.80 +		mKeys = NULL;
  330.81 +		mValues = NULL;
  330.82 +		mNumProperties = 0;
  330.83 +	}
  330.84 +
  330.85 +
  330.86 +	/** Destructor */
  330.87 +	~aiMetadata()
  330.88 +	{
  330.89 +		if (mKeys && mValues) {
  330.90 +			for (unsigned i=0; i<mNumProperties; ++i) {
  330.91 +				if (mKeys[i]) {
  330.92 +					delete mKeys[i];
  330.93 +				}
  330.94 +				if (mValues[i]) {
  330.95 +					delete mValues[i];
  330.96 +				}
  330.97 +			}
  330.98 +			delete [] mKeys;
  330.99 +			delete [] mValues;
 330.100 +		}
 330.101 +	}
 330.102 +
 330.103 +
 330.104 +	inline bool Get(const aiString& key, aiString& value)
 330.105 +	{
 330.106 +		for (unsigned i=0; i<mNumProperties; ++i) {
 330.107 +			if (mKeys[i] && *mKeys[i]==key) {
 330.108 +				value=*mValues[i];
 330.109 +				return true;
 330.110 +			}
 330.111 +		}
 330.112 +		return false;
 330.113 +	}
 330.114 +#endif // __cplusplus
 330.115 +};
 330.116 +
 330.117 +#ifdef __cplusplus
 330.118 +} //extern "C" {
 330.119 +#endif
 330.120 +
 330.121 +#endif // __AI_METADATA_H_INC__
 330.122 +
 330.123 +
   331.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   331.2 +++ b/libs/assimp/assimp/postprocess.h	Sat Feb 01 19:58:19 2014 +0200
   331.3 @@ -0,0 +1,630 @@
   331.4 +/*
   331.5 +Open Asset Import Library (assimp)
   331.6 +----------------------------------------------------------------------
   331.7 +
   331.8 +Copyright (c) 2006-2012, assimp team
   331.9 +All rights reserved.
  331.10 +
  331.11 +Redistribution and use of this software in source and binary forms, 
  331.12 +with or without modification, are permitted provided that the 
  331.13 +following conditions are met:
  331.14 +
  331.15 +* Redistributions of source code must retain the above
  331.16 +  copyright notice, this list of conditions and the
  331.17 +  following disclaimer.
  331.18 +
  331.19 +* Redistributions in binary form must reproduce the above
  331.20 +  copyright notice, this list of conditions and the
  331.21 +  following disclaimer in the documentation and/or other
  331.22 +  materials provided with the distribution.
  331.23 +
  331.24 +* Neither the name of the assimp team, nor the names of its
  331.25 +  contributors may be used to endorse or promote products
  331.26 +  derived from this software without specific prior
  331.27 +  written permission of the assimp team.
  331.28 +
  331.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  331.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  331.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  331.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  331.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  331.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  331.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  331.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  331.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  331.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  331.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  331.40 +
  331.41 +----------------------------------------------------------------------
  331.42 +*/
  331.43 +
  331.44 +/** @file postprocess.h
  331.45 + *  @brief Definitions for import post processing steps
  331.46 + */
  331.47 +#ifndef AI_POSTPROCESS_H_INC
  331.48 +#define AI_POSTPROCESS_H_INC
  331.49 +
  331.50 +#include "types.h"
  331.51 +
  331.52 +#ifdef __cplusplus
  331.53 +extern "C" {
  331.54 +#endif
  331.55 +
  331.56 +// -----------------------------------------------------------------------------------
  331.57 +/** @enum  aiPostProcessSteps
  331.58 + *  @brief Defines the flags for all possible post processing steps.
  331.59 + *
  331.60 + *  @see Importer::ReadFile
  331.61 + *  @see aiImportFile
  331.62 + *  @see aiImportFileEx
  331.63 + */
  331.64 +// -----------------------------------------------------------------------------------
  331.65 +enum aiPostProcessSteps
  331.66 +{
  331.67 +
  331.68 +	// -------------------------------------------------------------------------
  331.69 +	/** <hr>Calculates the tangents and bitangents for the imported meshes. 
  331.70 +	 *
  331.71 +	 * Does nothing if a mesh does not have normals. You might want this post 
  331.72 +	 * processing step to be executed if you plan to use tangent space calculations 
  331.73 +	 * such as normal mapping  applied to the meshes. There's a config setting,
  331.74 +	 * <tt>#AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE</tt>, which allows you to specify
  331.75 +	 * a maximum smoothing angle for the algorithm. However, usually you'll
  331.76 +	 * want to leave it at the default value.
  331.77 +	 */
  331.78 +	aiProcess_CalcTangentSpace = 0x1,
  331.79 +
  331.80 +	// -------------------------------------------------------------------------
  331.81 +	/** <hr>Identifies and joins identical vertex data sets within all 
  331.82 +	 *  imported meshes. 
  331.83 +	 * 
  331.84 +	 * After this step is run, each mesh contains unique vertices,
  331.85 +	 * so a vertex may be used by multiple faces. You usually want
  331.86 +	 * to use this post processing step. If your application deals with
  331.87 +	 * indexed geometry, this step is compulsory or you'll just waste rendering
  331.88 +	 * time. <b>If this flag is not specified</b>, no vertices are referenced by
  331.89 +	 * more than one face and <b>no index buffer is required</b> for rendering.
  331.90 +	 */
  331.91 +	aiProcess_JoinIdenticalVertices = 0x2,
  331.92 +
  331.93 +	// -------------------------------------------------------------------------
  331.94 +	/** <hr>Converts all the imported data to a left-handed coordinate space. 
  331.95 +	 *
  331.96 +	 * By default the data is returned in a right-handed coordinate space (which 
  331.97 +	 * OpenGL prefers). In this space, +X points to the right, 
  331.98 +	 * +Z points towards the viewer, and +Y points upwards. In the DirectX 
  331.99 +     * coordinate space +X points to the right, +Y points upwards, and +Z points 
 331.100 +     * away from the viewer.
 331.101 +	 *
 331.102 +	 * You'll probably want to consider this flag if you use Direct3D for
 331.103 +	 * rendering. The #aiProcess_ConvertToLeftHanded flag supersedes this
 331.104 +	 * setting and bundles all conversions typically required for D3D-based
 331.105 +	 * applications.
 331.106 +	 */
 331.107 +	aiProcess_MakeLeftHanded = 0x4,
 331.108 +
 331.109 +	// -------------------------------------------------------------------------
 331.110 +	/** <hr>Triangulates all faces of all meshes. 
 331.111 +	 *
 331.112 +	 * By default the imported mesh data might contain faces with more than 3
 331.113 +	 * indices. For rendering you'll usually want all faces to be triangles. 
 331.114 +	 * This post processing step splits up faces with more than 3 indices into 
 331.115 +	 * triangles. Line and point primitives are *not* modified! If you want
 331.116 +	 * 'triangles only' with no other kinds of primitives, try the following
 331.117 +	 * solution:
 331.118 +	 * <ul>
 331.119 +	 * <li>Specify both #aiProcess_Triangulate and #aiProcess_SortByPType </li>
 331.120 +	 * </li>Ignore all point and line meshes when you process assimp's output</li>
 331.121 +	 * </ul>
 331.122 +	 */
 331.123 +	aiProcess_Triangulate = 0x8,
 331.124 +
 331.125 +	// -------------------------------------------------------------------------
 331.126 +	/** <hr>Removes some parts of the data structure (animations, materials, 
 331.127 +	 *  light sources, cameras, textures, vertex components).
 331.128 +	 *
 331.129 +	 * The  components to be removed are specified in a separate
 331.130 +	 * configuration option, <tt>#AI_CONFIG_PP_RVC_FLAGS</tt>. This is quite useful
 331.131 +	 * if you don't need all parts of the output structure. Vertex colors
 331.132 +	 * are rarely used today for example... Calling this step to remove unneeded
 331.133 +	 * data from the pipeline as early as possible results in increased 
 331.134 +	 * performance and a more optimized output data structure.
 331.135 +	 * This step is also useful if you want to force Assimp to recompute 
 331.136 +	 * normals or tangents. The corresponding steps don't recompute them if 
 331.137 +	 * they're already there (loaded from the source asset). By using this 
 331.138 +	 * step you can make sure they are NOT there.
 331.139 +	 *
 331.140 +	 * This flag is a poor one, mainly because its purpose is usually
 331.141 +     * misunderstood. Consider the following case: a 3D model has been exported
 331.142 +	 * from a CAD app, and it has per-face vertex colors. Vertex positions can't be
 331.143 +	 * shared, thus the #aiProcess_JoinIdenticalVertices step fails to
 331.144 +	 * optimize the data because of these nasty little vertex colors.
 331.145 +	 * Most apps don't even process them, so it's all for nothing. By using
 331.146 +	 * this step, unneeded components are excluded as early as possible
 331.147 +	 * thus opening more room for internal optimizations. 
 331.148 +	 */
 331.149 +	aiProcess_RemoveComponent = 0x10,
 331.150 +
 331.151 +	// -------------------------------------------------------------------------
 331.152 +	/** <hr>Generates normals for all faces of all meshes. 
 331.153 +	 *
 331.154 +	 * This is ignored if normals are already there at the time this flag 
 331.155 +	 * is evaluated. Model importers try to load them from the source file, so
 331.156 +	 * they're usually already there. Face normals are shared between all points
 331.157 +	 * of a single face, so a single point can have multiple normals, which
 331.158 +	 * forces the library to duplicate vertices in some cases.
 331.159 +	 * #aiProcess_JoinIdenticalVertices is *senseless* then.
 331.160 +	 *
 331.161 +	 * This flag may not be specified together with #aiProcess_GenSmoothNormals.
 331.162 +	 */
 331.163 +	aiProcess_GenNormals = 0x20,
 331.164 +
 331.165 +	// -------------------------------------------------------------------------
 331.166 +	/** <hr>Generates smooth normals for all vertices in the mesh.
 331.167 +	*
 331.168 +	* This is ignored if normals are already there at the time this flag 
 331.169 +	* is evaluated. Model importers try to load them from the source file, so
 331.170 +	* they're usually already there. 
 331.171 +	*
 331.172 +	* This flag may not be specified together with 
 331.173 +	* #aiProcess_GenNormals. There's a configuration option, 
 331.174 +	* <tt>#AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE</tt> which allows you to specify
 331.175 +	* an angle maximum for the normal smoothing algorithm. Normals exceeding
 331.176 +	* this limit are not smoothed, resulting in a 'hard' seam between two faces.
 331.177 +	* Using a decent angle here (e.g. 80 degrees) results in very good visual
 331.178 +	* appearance.
 331.179 +	*/
 331.180 +	aiProcess_GenSmoothNormals = 0x40,
 331.181 +
 331.182 +	// -------------------------------------------------------------------------
 331.183 +	/** <hr>Splits large meshes into smaller sub-meshes.
 331.184 +	*
 331.185 +	* This is quite useful for real-time rendering, where the number of triangles
 331.186 +	* which can be maximally processed in a single draw-call is limited 
 331.187 +	* by the video driver/hardware. The maximum vertex buffer is usually limited
 331.188 +	* too. Both requirements can be met with this step: you may specify both a 
 331.189 +	* triangle and vertex limit for a single mesh.
 331.190 +	*
 331.191 +	* The split limits can (and should!) be set through the 
 331.192 +	* <tt>#AI_CONFIG_PP_SLM_VERTEX_LIMIT</tt> and <tt>#AI_CONFIG_PP_SLM_TRIANGLE_LIMIT</tt> 
 331.193 +	* settings. The default values are <tt>#AI_SLM_DEFAULT_MAX_VERTICES</tt> and 
 331.194 +	* <tt>#AI_SLM_DEFAULT_MAX_TRIANGLES</tt>. 
 331.195 +	*
 331.196 +	* Note that splitting is generally a time-consuming task, but only if there's
 331.197 +	* something to split. The use of this step is recommended for most users.
 331.198 +	*/
 331.199 +	aiProcess_SplitLargeMeshes = 0x80,
 331.200 +
 331.201 +	// -------------------------------------------------------------------------
 331.202 +	/** <hr>Removes the node graph and pre-transforms all vertices with
 331.203 +	* the local transformation matrices of their nodes.
 331.204 +	*
 331.205 +	* The output scene still contains nodes, however there is only a
 331.206 +	* root node with children, each one referencing only one mesh,
 331.207 +	* and each mesh referencing one material. For rendering, you can
 331.208 +	* simply render all meshes in order - you don't need to pay
 331.209 +	* attention to local transformations and the node hierarchy.
 331.210 +	* Animations are removed during this step.
 331.211 +	* This step is intended for applications without a scenegraph.
 331.212 +	* The step CAN cause some problems: if e.g. a mesh of the asset
 331.213 +	* contains normals and another, using the same material index, does not, 
 331.214 +	* they will be brought together, but the first meshes's part of
 331.215 +	* the normal list is zeroed. However, these artifacts are rare.
 331.216 +	* @note The <tt>#AI_CONFIG_PP_PTV_NORMALIZE</tt> configuration property
 331.217 +	* can be set to normalize the scene's spatial dimension to the -1...1
 331.218 +	* range. 
 331.219 +	*/
 331.220 +	aiProcess_PreTransformVertices = 0x100,
 331.221 +
 331.222 +	// -------------------------------------------------------------------------
 331.223 +	/** <hr>Limits the number of bones simultaneously affecting a single vertex
 331.224 +	*  to a maximum value.
 331.225 +	*
 331.226 +	* If any vertex is affected by more than the maximum number of bones, the least 
 331.227 +	* important vertex weights are removed and the remaining vertex weights are
 331.228 +	* renormalized so that the weights still sum up to 1.
 331.229 +	* The default bone weight limit is 4 (defined as <tt>#AI_LMW_MAX_WEIGHTS</tt> in
 331.230 +	* config.h), but you can use the <tt>#AI_CONFIG_PP_LBW_MAX_WEIGHTS</tt> setting to
 331.231 +	* supply your own limit to the post processing step.
 331.232 +	*
 331.233 +	* If you intend to perform the skinning in hardware, this post processing 
 331.234 +	* step might be of interest to you.
 331.235 +	*/
 331.236 +	aiProcess_LimitBoneWeights = 0x200,
 331.237 +
 331.238 +	// -------------------------------------------------------------------------
 331.239 +	/** <hr>Validates the imported scene data structure.
 331.240 +	 * This makes sure that all indices are valid, all animations and
 331.241 +	 * bones are linked correctly, all material references are correct .. etc.
 331.242 +	 *
 331.243 +	 * It is recommended that you capture Assimp's log output if you use this flag,
 331.244 +	 * so you can easily find out what's wrong if a file fails the
 331.245 +	 * validation. The validator is quite strict and will find *all*
 331.246 +	 * inconsistencies in the data structure... It is recommended that plugin 
 331.247 +	 * developers use it to debug their loaders. There are two types of
 331.248 +	 * validation failures:
 331.249 +	 * <ul>
 331.250 +	 * <li>Error: There's something wrong with the imported data. Further
 331.251 +	 *   postprocessing is not possible and the data is not usable at all.
 331.252 +	 *   The import fails. #Importer::GetErrorString() or #aiGetErrorString()
 331.253 +	 *   carry the error message around.</li>
 331.254 +	 * <li>Warning: There are some minor issues (e.g. 1000000 animation 
 331.255 +	 *   keyframes with the same time), but further postprocessing and use
 331.256 +	 *   of the data structure is still safe. Warning details are written
 331.257 +	 *   to the log file, <tt>#AI_SCENE_FLAGS_VALIDATION_WARNING</tt> is set
 331.258 +	 *   in #aiScene::mFlags</li>
 331.259 +	 * </ul>
 331.260 +	 *
 331.261 +	 * This post-processing step is not time-consuming. Its use is not
 331.262 +	 * compulsory, but recommended. 
 331.263 +	*/
 331.264 +	aiProcess_ValidateDataStructure = 0x400,
 331.265 +
 331.266 +	// -------------------------------------------------------------------------
 331.267 +	/** <hr>Reorders triangles for better vertex cache locality.
 331.268 +	 *
 331.269 +	 * The step tries to improve the ACMR (average post-transform vertex cache
 331.270 +	 * miss ratio) for all meshes. The implementation runs in O(n) and is 
 331.271 +	 * roughly based on the 'tipsify' algorithm (see <a href="
 331.272 +	 * http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf">this
 331.273 +	 * paper</a>).
 331.274 +	 *
 331.275 +	 * If you intend to render huge models in hardware, this step might
 331.276 +	 * be of interest to you. The <tt>#AI_CONFIG_PP_ICL_PTCACHE_SIZE</tt>config
 331.277 +	 * setting can be used to fine-tune the cache optimization.
 331.278 +	 */
 331.279 +	aiProcess_ImproveCacheLocality = 0x800,
 331.280 +
 331.281 +	// -------------------------------------------------------------------------
 331.282 +	/** <hr>Searches for redundant/unreferenced materials and removes them.
 331.283 +	 *
 331.284 +	 * This is especially useful in combination with the 
 331.285 +	 * #aiProcess_PretransformVertices and #aiProcess_OptimizeMeshes flags. 
 331.286 +	 * Both join small meshes with equal characteristics, but they can't do 
 331.287 +	 * their work if two meshes have different materials. Because several
 331.288 +	 * material settings are lost during Assimp's import filters,
 331.289 +	 * (and because many exporters don't check for redundant materials), huge
 331.290 +	 * models often have materials which are are defined several times with
 331.291 +	 * exactly the same settings.
 331.292 +	 *
 331.293 +	 * Several material settings not contributing to the final appearance of
 331.294 +	 * a surface are ignored in all comparisons (e.g. the material name).
 331.295 +	 * So, if you're passing additional information through the
 331.296 +	 * content pipeline (probably using *magic* material names), don't 
 331.297 +	 * specify this flag. Alternatively take a look at the
 331.298 +	 * <tt>#AI_CONFIG_PP_RRM_EXCLUDE_LIST</tt> setting.
 331.299 +	 */ 
 331.300 +	aiProcess_RemoveRedundantMaterials = 0x1000,
 331.301 +
 331.302 +	// -------------------------------------------------------------------------
 331.303 +	/** <hr>This step tries to determine which meshes have normal vectors 
 331.304 +	 * that are facing inwards and inverts them.
 331.305 +	 *
 331.306 +	 * The algorithm is simple but effective:
 331.307 +	 * the bounding box of all vertices + their normals is compared against
 331.308 +	 * the volume of the bounding box of all vertices without their normals.
 331.309 +	 * This works well for most objects, problems might occur with planar
 331.310 +	 * surfaces. However, the step tries to filter such cases.
 331.311 +	 * The step inverts all in-facing normals. Generally it is recommended
 331.312 +	 * to enable this step, although the result is not always correct.
 331.313 +	*/
 331.314 +	aiProcess_FixInfacingNormals = 0x2000,
 331.315 +
 331.316 +	// -------------------------------------------------------------------------
 331.317 +	/** <hr>This step splits meshes with more than one primitive type in 
 331.318 +	 *  homogeneous sub-meshes. 
 331.319 +	 *
 331.320 +	 *  The step is executed after the triangulation step. After the step
 331.321 +	 *  returns, just one bit is set in aiMesh::mPrimitiveTypes. This is 
 331.322 +	 *  especially useful for real-time rendering where point and line
 331.323 +	 *  primitives are often ignored or rendered separately.
 331.324 +	 *  You can use the <tt>#AI_CONFIG_PP_SBP_REMOVE</tt> option to specify which
 331.325 +	 *  primitive types you need. This can be used to easily exclude
 331.326 +	 *  lines and points, which are rarely used, from the import.
 331.327 +	*/
 331.328 +	aiProcess_SortByPType = 0x8000,
 331.329 +
 331.330 +	// -------------------------------------------------------------------------
 331.331 +	/** <hr>This step searches all meshes for degenerate primitives and
 331.332 +	 *  converts them to proper lines or points.
 331.333 +	 *
 331.334 +	 * A face is 'degenerate' if one or more of its points are identical.
 331.335 +	 * To have the degenerate stuff not only detected and collapsed but
 331.336 +	 * removed, try one of the following procedures:
 331.337 +	 * <br><b>1.</b> (if you support lines and points for rendering but don't
 331.338 +	 *    want the degenerates)</br>
 331.339 +	 * <ul>
 331.340 +	 *   <li>Specify the #aiProcess_FindDegenerates flag.
 331.341 +	 *   </li>
 331.342 +	 *   <li>Set the <tt>AI_CONFIG_PP_FD_REMOVE</tt> option to 1. This will 
 331.343 +	 *       cause the step to remove degenerate triangles from the import
 331.344 +	 *       as soon as they're detected. They won't pass any further
 331.345 +	 *       pipeline steps.
 331.346 +	 *   </li>
 331.347 +	 * </ul>
 331.348 +	 * <br><b>2.</b>(if you don't support lines and points at all)</br>
 331.349 +	 * <ul>
 331.350 +	 *   <li>Specify the #aiProcess_FindDegenerates flag.
 331.351 +	 *   </li>
 331.352 +	 *   <li>Specify the #aiProcess_SortByPType flag. This moves line and
 331.353 +	 *     point primitives to separate meshes.
 331.354 +	 *   </li>
 331.355 +	 *   <li>Set the <tt>AI_CONFIG_PP_SBP_REMOVE</tt> option to 
 331.356 +	 *       @code aiPrimitiveType_POINTS | aiPrimitiveType_LINES
 331.357 +	 *       @endcode to cause SortByPType to reject point
 331.358 +	 *       and line meshes from the scene.
 331.359 +	 *   </li>
 331.360 +	 * </ul>
 331.361 +	 * @note Degenerate polygons are not necessarily evil and that's why
 331.362 +	 * they're not removed by default. There are several file formats which 
 331.363 +	 * don't support lines or points, and some exporters bypass the
 331.364 +	 * format specification and write them as degenerate triangles instead.
 331.365 +	*/
 331.366 +	aiProcess_FindDegenerates = 0x10000,
 331.367 +
 331.368 +	// -------------------------------------------------------------------------
 331.369 +	/** <hr>This step searches all meshes for invalid data, such as zeroed
 331.370 +	 *  normal vectors or invalid UV coords and removes/fixes them. This is
 331.371 +	 *  intended to get rid of some common exporter errors.
 331.372 +	 *
 331.373 +	 * This is especially useful for normals. If they are invalid, and
 331.374 +	 * the step recognizes this, they will be removed and can later
 331.375 +	 * be recomputed, i.e. by the #aiProcess_GenSmoothNormals flag.<br>
 331.376 +	 * The step will also remove meshes that are infinitely small and reduce
 331.377 +	 * animation tracks consisting of hundreds if redundant keys to a single
 331.378 +	 * key. The <tt>AI_CONFIG_PP_FID_ANIM_ACCURACY</tt> config property decides
 331.379 +	 * the accuracy of the check for duplicate animation tracks.
 331.380 +	*/
 331.381 +	aiProcess_FindInvalidData = 0x20000,
 331.382 +
 331.383 +	// -------------------------------------------------------------------------
 331.384 +	/** <hr>This step converts non-UV mappings (such as spherical or
 331.385 +	 *  cylindrical mapping) to proper texture coordinate channels.
 331.386 +	 *
 331.387 +	 * Most applications will support UV mapping only, so you will
 331.388 +	 * probably want to specify this step in every case. Note that Assimp is not
 331.389 +	 * always able to match the original mapping implementation of the 
 331.390 +	 * 3D app which produced a model perfectly. It's always better to let the
 331.391 +	 * modelling app compute the UV channels - 3ds max, Maya, Blender, 
 331.392 +	 * LightWave, and Modo do this for example.
 331.393 +	 *
 331.394 +	 * @note If this step is not requested, you'll need to process the
 331.395 +	 * <tt>#AI_MATKEY_MAPPING</tt> material property in order to display all assets
 331.396 +	 * properly.
 331.397 +	 */
 331.398 +	aiProcess_GenUVCoords = 0x40000,
 331.399 +
 331.400 +	// -------------------------------------------------------------------------
 331.401 +	/** <hr>This step applies per-texture UV transformations and bakes
 331.402 +	 *  them into stand-alone vtexture coordinate channels.
 331.403 +	 *  
 331.404 +	 * UV transformations are specified per-texture - see the 
 331.405 +	 * <tt>#AI_MATKEY_UVTRANSFORM</tt> material key for more information. 
 331.406 +	 * This step processes all textures with 
 331.407 +	 * transformed input UV coordinates and generates a new (pre-transformed) UV channel 
 331.408 +	 * which replaces the old channel. Most applications won't support UV 
 331.409 +	 * transformations, so you will probably want to specify this step.
 331.410 +     *
 331.411 +	 * @note UV transformations are usually implemented in real-time apps by 
 331.412 +	 * transforming texture coordinates at vertex shader stage with a 3x3
 331.413 +	 * (homogenous) transformation matrix.
 331.414 +	*/
 331.415 +	aiProcess_TransformUVCoords = 0x80000,
 331.416 +
 331.417 +	// -------------------------------------------------------------------------
 331.418 +	/** <hr>This step searches for duplicate meshes and replaces them
 331.419 +	 *  with references to the first mesh.
 331.420 +	 *
 331.421 +	 *  This step takes a while, so don't use it if speed is a concern.
 331.422 +	 *  Its main purpose is to workaround the fact that many export
 331.423 +	 *  file formats don't support instanced meshes, so exporters need to
 331.424 +	 *  duplicate meshes. This step removes the duplicates again. Please 
 331.425 + 	 *  note that Assimp does not currently support per-node material
 331.426 +	 *  assignment to meshes, which means that identical meshes with
 331.427 +	 *  different materials are currently *not* joined, although this is 
 331.428 +	 *  planned for future versions.
 331.429 +	 */
 331.430 +	aiProcess_FindInstances = 0x100000,
 331.431 +
 331.432 +	// -------------------------------------------------------------------------
 331.433 +	/** <hr>A postprocessing step to reduce the number of meshes.
 331.434 +	 *
 331.435 +	 *  This will, in fact, reduce the number of draw calls.
 331.436 +	 *
 331.437 +	 *  This is a very effective optimization and is recommended to be used
 331.438 +	 *  together with #aiProcess_OptimizeGraph, if possible. The flag is fully
 331.439 +	 *  compatible with both #aiProcess_SplitLargeMeshes and #aiProcess_SortByPType.
 331.440 +	*/
 331.441 +	aiProcess_OptimizeMeshes  = 0x200000, 
 331.442 +
 331.443 +
 331.444 +	// -------------------------------------------------------------------------
 331.445 +	/** <hr>A postprocessing step to optimize the scene hierarchy. 
 331.446 +	 *
 331.447 +	 *  Nodes without animations, bones, lights or cameras assigned are 
 331.448 +	 *  collapsed and joined.
 331.449 +	 *
 331.450 +	 *  Node names can be lost during this step. If you use special 'tag nodes'
 331.451 +	 *  to pass additional information through your content pipeline, use the
 331.452 +	 *  <tt>#AI_CONFIG_PP_OG_EXCLUDE_LIST</tt> setting to specify a list of node 
 331.453 +	 *  names you want to be kept. Nodes matching one of the names in this list won't
 331.454 +	 *  be touched or modified.
 331.455 +	 *
 331.456 +	 *  Use this flag with caution. Most simple files will be collapsed to a 
 331.457 +	 *  single node, so complex hierarchies are usually completely lost. This is not
 331.458 +	 *  useful for editor environments, but probably a very effective
 331.459 +	 *  optimization if you just want to get the model data, convert it to your
 331.460 +	 *  own format, and render it as fast as possible. 
 331.461 +	 *
 331.462 +	 *  This flag is designed to be used with #aiProcess_OptimizeMeshes for best
 331.463 +	 *  results.
 331.464 +	 *
 331.465 +	 *  @note 'Crappy' scenes with thousands of extremely small meshes packed
 331.466 +	 *  in deeply nested nodes exist for almost all file formats.
 331.467 +	 *  #aiProcess_OptimizeMeshes in combination with #aiProcess_OptimizeGraph 
 331.468 +	 *  usually fixes them all and makes them renderable. 
 331.469 +	*/
 331.470 +	aiProcess_OptimizeGraph  = 0x400000, 
 331.471 +
 331.472 +	// -------------------------------------------------------------------------
 331.473 +	/** <hr>This step flips all UV coordinates along the y-axis and adjusts
 331.474 +	 * material settings and bitangents accordingly.
 331.475 +	 *
 331.476 +	 * <b>Output UV coordinate system:</b>
 331.477 +	 * @code
 331.478 +	 * 0y|0y ---------- 1x|0y 
 331.479 +     * |                 |
 331.480 +     * |                 |
 331.481 +     * |                 |
 331.482 +     * 0x|1y ---------- 1x|1y
 331.483 +	 * @endcode
 331.484 +	 *
 331.485 +	 * You'll probably want to consider this flag if you use Direct3D for
 331.486 +	 * rendering. The #aiProcess_ConvertToLeftHanded flag supersedes this
 331.487 +	 * setting and bundles all conversions typically required for D3D-based
 331.488 +	 * applications.
 331.489 +	*/
 331.490 +	aiProcess_FlipUVs = 0x800000, 
 331.491 +
 331.492 +	// -------------------------------------------------------------------------
 331.493 +	/** <hr>This step adjusts the output face winding order to be CW.
 331.494 +	 *
 331.495 +	 * The default face winding order is counter clockwise (CCW).
 331.496 +	 *
 331.497 +	 * <b>Output face order:</b>
 331.498 +	 * @code
 331.499 +	 *       x2
 331.500 +	 *           
 331.501 +	 *                         x0
 331.502 +	 *  x1
 331.503 +	 * @endcode
 331.504 +	*/
 331.505 +	aiProcess_FlipWindingOrder  = 0x1000000,
 331.506 +
 331.507 +	// -------------------------------------------------------------------------
 331.508 +	/** <hr>This step splits meshes with many bones into sub-meshes so that each
 331.509 +	 * su-bmesh has fewer or as many bones as a given limit. 
 331.510 +    */
 331.511 +	aiProcess_SplitByBoneCount  = 0x2000000,
 331.512 +
 331.513 +	// -------------------------------------------------------------------------
 331.514 +	/** <hr>This step removes bones losslessly or according to some threshold.
 331.515 +	 *
 331.516 +	 *  In some cases (i.e. formats that require it) exporters are forced to
 331.517 +	 *  assign dummy bone weights to otherwise static meshes assigned to
 331.518 +	 *  animated meshes. Full, weight-based skinning is expensive while
 331.519 +	 *  animating nodes is extremely cheap, so this step is offered to clean up
 331.520 +	 *  the data in that regard. 
 331.521 +	 *																
 331.522 +	 *  Use <tt>#AI_CONFIG_PP_DB_THRESHOLD</tt> to control this. 
 331.523 +	 *  Use <tt>#AI_CONFIG_PP_DB_ALL_OR_NONE</tt> if you want bones removed if and 
 331.524 +	 *	only if all bones within the scene qualify for removal.
 331.525 +    */
 331.526 +	aiProcess_Debone  = 0x4000000
 331.527 +
 331.528 +	// aiProcess_GenEntityMeshes = 0x100000,
 331.529 +	// aiProcess_OptimizeAnimations = 0x200000
 331.530 +	// aiProcess_FixTexturePaths = 0x200000
 331.531 +};
 331.532 +
 331.533 +
 331.534 +// ---------------------------------------------------------------------------------------
 331.535 +/** @def aiProcess_ConvertToLeftHanded
 331.536 + *  @brief Shortcut flag for Direct3D-based applications. 
 331.537 + *
 331.538 + *  Supersedes the #aiProcess_MakeLeftHanded and #aiProcess_FlipUVs and
 331.539 + *  #aiProcess_FlipWindingOrder flags.
 331.540 + *  The output data matches Direct3D's conventions: left-handed geometry, upper-left
 331.541 + *  origin for UV coordinates and finally clockwise face order, suitable for CCW culling.
 331.542 + *
 331.543 + *  @deprecated 
 331.544 + */
 331.545 +#define aiProcess_ConvertToLeftHanded ( \
 331.546 +	aiProcess_MakeLeftHanded     | \
 331.547 +	aiProcess_FlipUVs            | \
 331.548 +	aiProcess_FlipWindingOrder   | \
 331.549 +	0 ) 
 331.550 +
 331.551 +
 331.552 +// ---------------------------------------------------------------------------------------
 331.553 +/** @def aiProcessPreset_TargetRealtimeUse_Fast
 331.554 + *  @brief Default postprocess configuration optimizing the data for real-time rendering.
 331.555 + *  
 331.556 + *  Applications would want to use this preset to load models on end-user PCs,
 331.557 + *  maybe for direct use in game.
 331.558 + *
 331.559 + * If you're using DirectX, don't forget to combine this value with
 331.560 + * the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations
 331.561 + * in your application apply the #aiProcess_TransformUVCoords step, too.
 331.562 + *  @note Please take the time to read the docs for the steps enabled by this preset. 
 331.563 + *  Some of them offer further configurable properties, while some of them might not be of
 331.564 + *  use for you so it might be better to not specify them.
 331.565 + */
 331.566 +#define aiProcessPreset_TargetRealtime_Fast ( \
 331.567 +	aiProcess_CalcTangentSpace		|  \
 331.568 +	aiProcess_GenNormals			|  \
 331.569 +	aiProcess_JoinIdenticalVertices |  \
 331.570 +	aiProcess_Triangulate			|  \
 331.571 +	aiProcess_GenUVCoords           |  \
 331.572 +	aiProcess_SortByPType           |  \
 331.573 +	0 )
 331.574 +
 331.575 + // ---------------------------------------------------------------------------------------
 331.576 + /** @def aiProcessPreset_TargetRealtime_Quality
 331.577 +  *  @brief Default postprocess configuration optimizing the data for real-time rendering.
 331.578 +  *
 331.579 +  *  Unlike #aiProcessPreset_TargetRealtime_Fast, this configuration
 331.580 +  *  performs some extra optimizations to improve rendering speed and
 331.581 +  *  to minimize memory usage. It could be a good choice for a level editor
 331.582 +  *  environment where import speed is not so important.
 331.583 +  *  
 331.584 +  *  If you're using DirectX, don't forget to combine this value with
 331.585 +  *  the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations
 331.586 +  *  in your application apply the #aiProcess_TransformUVCoords step, too.
 331.587 +  *  @note Please take the time to read the docs for the steps enabled by this preset. 
 331.588 +  *  Some of them offer further configurable properties, while some of them might not be
 331.589 +  *  of use for you so it might be better to not specify them.
 331.590 +  */
 331.591 +#define aiProcessPreset_TargetRealtime_Quality ( \
 331.592 +	aiProcess_CalcTangentSpace				|  \
 331.593 +	aiProcess_GenSmoothNormals				|  \
 331.594 +	aiProcess_JoinIdenticalVertices			|  \
 331.595 +	aiProcess_ImproveCacheLocality			|  \
 331.596 +	aiProcess_LimitBoneWeights				|  \
 331.597 +	aiProcess_RemoveRedundantMaterials      |  \
 331.598 +	aiProcess_SplitLargeMeshes				|  \
 331.599 +	aiProcess_Triangulate					|  \
 331.600 +	aiProcess_GenUVCoords                   |  \
 331.601 +	aiProcess_SortByPType                   |  \
 331.602 +	aiProcess_FindDegenerates               |  \
 331.603 +	aiProcess_FindInvalidData               |  \
 331.604 +	0 )
 331.605 +
 331.606 + // ---------------------------------------------------------------------------------------
 331.607 + /** @def aiProcessPreset_TargetRealtime_MaxQuality
 331.608 +  *  @brief Default postprocess configuration optimizing the data for real-time rendering.
 331.609 +  *
 331.610 +  *  This preset enables almost every optimization step to achieve perfectly
 331.611 +  *  optimized data. It's your choice for level editor environments where import speed 
 331.612 +  *  is not important.
 331.613 +  *  
 331.614 +  *  If you're using DirectX, don't forget to combine this value with
 331.615 +  *  the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations
 331.616 +  *  in your application, apply the #aiProcess_TransformUVCoords step, too.
 331.617 +  *  @note Please take the time to read the docs for the steps enabled by this preset. 
 331.618 +  *  Some of them offer further configurable properties, while some of them might not be
 331.619 +  *  of use for you so it might be better to not specify them.
 331.620 +  */
 331.621 +#define aiProcessPreset_TargetRealtime_MaxQuality ( \
 331.622 +	aiProcessPreset_TargetRealtime_Quality   |  \
 331.623 +	aiProcess_FindInstances                  |  \
 331.624 +	aiProcess_ValidateDataStructure          |  \
 331.625 +	aiProcess_OptimizeMeshes                 |  \
 331.626 +	0 )
 331.627 +
 331.628 +
 331.629 +#ifdef __cplusplus
 331.630 +} // end of extern "C"
 331.631 +#endif
 331.632 +
 331.633 +#endif // AI_POSTPROCESS_H_INC
 331.634 \ No newline at end of file
   332.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   332.2 +++ b/libs/assimp/assimp/quaternion.h	Sat Feb 01 19:58:19 2014 +0200
   332.3 @@ -0,0 +1,124 @@
   332.4 +/*
   332.5 +Open Asset Import Library (assimp)
   332.6 +----------------------------------------------------------------------
   332.7 +
   332.8 +Copyright (c) 2006-2012, assimp team
   332.9 +All rights reserved.
  332.10 +
  332.11 +Redistribution and use of this software in source and binary forms, 
  332.12 +with or without modification, are permitted provided that the 
  332.13 +following conditions are met:
  332.14 +
  332.15 +* Redistributions of source code must retain the above
  332.16 +  copyright notice, this list of conditions and the
  332.17 +  following disclaimer.
  332.18 +
  332.19 +* Redistributions in binary form must reproduce the above
  332.20 +  copyright notice, this list of conditions and the
  332.21 +  following disclaimer in the documentation and/or other
  332.22 +  materials provided with the distribution.
  332.23 +
  332.24 +* Neither the name of the assimp team, nor the names of its
  332.25 +  contributors may be used to endorse or promote products
  332.26 +  derived from this software without specific prior
  332.27 +  written permission of the assimp team.
  332.28 +
  332.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  332.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  332.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  332.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  332.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  332.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  332.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  332.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  332.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  332.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  332.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  332.40 +
  332.41 +----------------------------------------------------------------------
  332.42 +*/
  332.43 +
  332.44 +/** @file quaternion.h
  332.45 + *  @brief Quaternion structure, including operators when compiling in C++
  332.46 + */
  332.47 +#ifndef AI_QUATERNION_H_INC
  332.48 +#define AI_QUATERNION_H_INC
  332.49 +
  332.50 +#ifdef __cplusplus
  332.51 +
  332.52 +template <typename TReal> class aiVector3t;
  332.53 +template <typename TReal> class aiMatrix3x3t;
  332.54 +
  332.55 +// ---------------------------------------------------------------------------
  332.56 +/** Represents a quaternion in a 4D vector. */
  332.57 +template <typename TReal>
  332.58 +class aiQuaterniont
  332.59 +{
  332.60 +public:
  332.61 +	aiQuaterniont() : w(), x(), y(), z() {}
  332.62 +	aiQuaterniont(TReal pw, TReal px, TReal py, TReal pz) 
  332.63 +		: w(pw), x(px), y(py), z(pz) {}
  332.64 +
  332.65 +	/** Construct from rotation matrix. Result is undefined if the matrix is not orthonormal. */
  332.66 +	aiQuaterniont( const aiMatrix3x3t<TReal>& pRotMatrix);
  332.67 +
  332.68 +	/** Construct from euler angles */
  332.69 +	aiQuaterniont( TReal rotx, TReal roty, TReal rotz);
  332.70 +
  332.71 +	/** Construct from an axis-angle pair */
  332.72 +	aiQuaterniont( aiVector3t<TReal> axis, TReal angle);
  332.73 +
  332.74 +	/** Construct from a normalized quaternion stored in a vec3 */
  332.75 +	aiQuaterniont( aiVector3t<TReal> normalized);
  332.76 +
  332.77 +	/** Returns a matrix representation of the quaternion */
  332.78 +	aiMatrix3x3t<TReal> GetMatrix() const;
  332.79 +
  332.80 +public:
  332.81 +
  332.82 +	bool operator== (const aiQuaterniont& o) const;
  332.83 +	bool operator!= (const aiQuaterniont& o) const;
  332.84 +
  332.85 +public:
  332.86 +
  332.87 +	/** Normalize the quaternion */
  332.88 +	aiQuaterniont& Normalize();
  332.89 +
  332.90 +	/** Compute quaternion conjugate */
  332.91 +	aiQuaterniont& Conjugate ();
  332.92 +
  332.93 +	/** Rotate a point by this quaternion */
  332.94 +	aiVector3t<TReal> Rotate (const aiVector3t<TReal>& in);
  332.95 +
  332.96 +	/** Multiply two quaternions */
  332.97 +	aiQuaterniont operator* (const aiQuaterniont& two) const;
  332.98 +
  332.99 +public:
 332.100 +
 332.101 +	/** Performs a spherical interpolation between two quaternions and writes the result into the third.
 332.102 +	 * @param pOut Target object to received the interpolated rotation.
 332.103 +	 * @param pStart Start rotation of the interpolation at factor == 0.
 332.104 +	 * @param pEnd End rotation, factor == 1.
 332.105 +	 * @param pFactor Interpolation factor between 0 and 1. Values outside of this range yield undefined results.
 332.106 +	 */
 332.107 +	static void Interpolate( aiQuaterniont& pOut, const aiQuaterniont& pStart, 
 332.108 +		const aiQuaterniont& pEnd, TReal pFactor);
 332.109 +
 332.110 +public:
 332.111 +
 332.112 +	//! w,x,y,z components of the quaternion
 332.113 +	TReal w, x, y, z;	
 332.114 +} ;
 332.115 +
 332.116 +typedef aiQuaterniont<float> aiQuaternion;
 332.117 +
 332.118 +#else
 332.119 +
 332.120 +struct aiQuaternion {
 332.121 +	float w, x, y, z;	
 332.122 +};
 332.123 +
 332.124 +#endif
 332.125 +
 332.126 +
 332.127 +#endif // AI_QUATERNION_H_INC
   333.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   333.2 +++ b/libs/assimp/assimp/quaternion.inl	Sat Feb 01 19:58:19 2014 +0200
   333.3 @@ -0,0 +1,274 @@
   333.4 +/*
   333.5 +---------------------------------------------------------------------------
   333.6 +Open Asset Import Library (assimp)
   333.7 +---------------------------------------------------------------------------
   333.8 +
   333.9 +Copyright (c) 2006-2012, assimp team
  333.10 +
  333.11 +All rights reserved.
  333.12 +
  333.13 +Redistribution and use of this software in source and binary forms, 
  333.14 +with or without modification, are permitted provided that the following 
  333.15 +conditions are met:
  333.16 +
  333.17 +* Redistributions of source code must retain the above
  333.18 +  copyright notice, this list of conditions and the
  333.19 +  following disclaimer.
  333.20 +
  333.21 +* Redistributions in binary form must reproduce the above
  333.22 +  copyright notice, this list of conditions and the
  333.23 +  following disclaimer in the documentation and/or other
  333.24 +  materials provided with the distribution.
  333.25 +
  333.26 +* Neither the name of the assimp team, nor the names of its
  333.27 +  contributors may be used to endorse or promote products
  333.28 +  derived from this software without specific prior
  333.29 +  written permission of the assimp team.
  333.30 +
  333.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  333.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  333.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  333.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  333.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  333.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  333.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  333.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  333.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  333.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  333.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  333.42 +---------------------------------------------------------------------------
  333.43 +*/
  333.44 +
  333.45 +/** @file  aiQuaterniont.inl
  333.46 + *  @brief Inline implementation of aiQuaterniont<TReal> operators
  333.47 + */
  333.48 +#ifndef AI_QUATERNION_INL_INC
  333.49 +#define AI_QUATERNION_INL_INC
  333.50 +
  333.51 +#ifdef __cplusplus
  333.52 +#include "quaternion.h"
  333.53 +
  333.54 +// ---------------------------------------------------------------------------
  333.55 +template<typename TReal>
  333.56 +bool aiQuaterniont<TReal>::operator== (const aiQuaterniont& o) const
  333.57 +{
  333.58 +	return x == o.x && y == o.y && z == o.z && w == o.w;
  333.59 +}
  333.60 +
  333.61 +// ---------------------------------------------------------------------------
  333.62 +template<typename TReal>
  333.63 +bool aiQuaterniont<TReal>::operator!= (const aiQuaterniont& o) const
  333.64 +{
  333.65 +	return !(*this == o);
  333.66 +}
  333.67 +
  333.68 +
  333.69 +
  333.70 +// ---------------------------------------------------------------------------
  333.71 +// Constructs a quaternion from a rotation matrix
  333.72 +template<typename TReal>
  333.73 +inline aiQuaterniont<TReal>::aiQuaterniont( const aiMatrix3x3t<TReal> &pRotMatrix)
  333.74 +{
  333.75 +	TReal t = pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3;
  333.76 +
  333.77 +	// large enough
  333.78 +	if( t > static_cast<TReal>(0))
  333.79 +	{
  333.80 +		TReal s = sqrt(1 + t) * static_cast<TReal>(2.0);
  333.81 +		x = (pRotMatrix.c2 - pRotMatrix.b3) / s;
  333.82 +		y = (pRotMatrix.a3 - pRotMatrix.c1) / s;
  333.83 +		z = (pRotMatrix.b1 - pRotMatrix.a2) / s;
  333.84 +		w = static_cast<TReal>(0.25) * s;
  333.85 +	} // else we have to check several cases
  333.86 +	else if( pRotMatrix.a1 > pRotMatrix.b2 && pRotMatrix.a1 > pRotMatrix.c3 )  
  333.87 +	{	
  333.88 +		// Column 0: 
  333.89 +		TReal s = sqrt( static_cast<TReal>(1.0) + pRotMatrix.a1 - pRotMatrix.b2 - pRotMatrix.c3) * static_cast<TReal>(2.0);
  333.90 +		x = static_cast<TReal>(0.25) * s;
  333.91 +		y = (pRotMatrix.b1 + pRotMatrix.a2) / s;
  333.92 +		z = (pRotMatrix.a3 + pRotMatrix.c1) / s;
  333.93 +		w = (pRotMatrix.c2 - pRotMatrix.b3) / s;
  333.94 +	} 
  333.95 +	else if( pRotMatrix.b2 > pRotMatrix.c3) 
  333.96 +	{ 
  333.97 +		// Column 1: 
  333.98 +		TReal s = sqrt( static_cast<TReal>(1.0) + pRotMatrix.b2 - pRotMatrix.a1 - pRotMatrix.c3) * static_cast<TReal>(2.0);
  333.99 +		x = (pRotMatrix.b1 + pRotMatrix.a2) / s;
 333.100 +		y = static_cast<TReal>(0.25) * s;
 333.101 +		z = (pRotMatrix.c2 + pRotMatrix.b3) / s;
 333.102 +		w = (pRotMatrix.a3 - pRotMatrix.c1) / s;
 333.103 +	} else 
 333.104 +	{ 
 333.105 +		// Column 2:
 333.106 +		TReal s = sqrt( static_cast<TReal>(1.0) + pRotMatrix.c3 - pRotMatrix.a1 - pRotMatrix.b2) * static_cast<TReal>(2.0);
 333.107 +		x = (pRotMatrix.a3 + pRotMatrix.c1) / s;
 333.108 +		y = (pRotMatrix.c2 + pRotMatrix.b3) / s;
 333.109 +		z = static_cast<TReal>(0.25) * s;
 333.110 +		w = (pRotMatrix.b1 - pRotMatrix.a2) / s;
 333.111 +	}
 333.112 +}
 333.113 +
 333.114 +// ---------------------------------------------------------------------------
 333.115 +// Construction from euler angles
 333.116 +template<typename TReal>
 333.117 +inline aiQuaterniont<TReal>::aiQuaterniont( TReal fPitch, TReal fYaw, TReal fRoll )
 333.118 +{
 333.119 +	const TReal fSinPitch(sin(fPitch*static_cast<TReal>(0.5)));
 333.120 +	const TReal fCosPitch(cos(fPitch*static_cast<TReal>(0.5)));
 333.121 +	const TReal fSinYaw(sin(fYaw*static_cast<TReal>(0.5)));
 333.122 +	const TReal fCosYaw(cos(fYaw*static_cast<TReal>(0.5)));
 333.123 +	const TReal fSinRoll(sin(fRoll*static_cast<TReal>(0.5)));
 333.124 +	const TReal fCosRoll(cos(fRoll*static_cast<TReal>(0.5)));
 333.125 +	const TReal fCosPitchCosYaw(fCosPitch*fCosYaw);
 333.126 +	const TReal fSinPitchSinYaw(fSinPitch*fSinYaw);
 333.127 +	x = fSinRoll * fCosPitchCosYaw     - fCosRoll * fSinPitchSinYaw;
 333.128 +	y = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw;
 333.129 +	z = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw;
 333.130 +	w = fCosRoll * fCosPitchCosYaw     + fSinRoll * fSinPitchSinYaw;
 333.131 +}
 333.132 +
 333.133 +// ---------------------------------------------------------------------------
 333.134 +// Returns a matrix representation of the quaternion
 333.135 +template<typename TReal>
 333.136 +inline aiMatrix3x3t<TReal> aiQuaterniont<TReal>::GetMatrix() const
 333.137 +{
 333.138 +	aiMatrix3x3t<TReal> resMatrix;
 333.139 +	resMatrix.a1 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (y * y + z * z);
 333.140 +	resMatrix.a2 = static_cast<TReal>(2.0) * (x * y - z * w);
 333.141 +	resMatrix.a3 = static_cast<TReal>(2.0) * (x * z + y * w);
 333.142 +	resMatrix.b1 = static_cast<TReal>(2.0) * (x * y + z * w);
 333.143 +	resMatrix.b2 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (x * x + z * z);
 333.144 +	resMatrix.b3 = static_cast<TReal>(2.0) * (y * z - x * w);
 333.145 +	resMatrix.c1 = static_cast<TReal>(2.0) * (x * z - y * w);
 333.146 +	resMatrix.c2 = static_cast<TReal>(2.0) * (y * z + x * w);
 333.147 +	resMatrix.c3 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (x * x + y * y);
 333.148 +
 333.149 +	return resMatrix;
 333.150 +}
 333.151 +
 333.152 +// ---------------------------------------------------------------------------
 333.153 +// Construction from an axis-angle pair
 333.154 +template<typename TReal>
 333.155 +inline aiQuaterniont<TReal>::aiQuaterniont( aiVector3t<TReal> axis, TReal angle)
 333.156 +{
 333.157 +	axis.Normalize();
 333.158 +
 333.159 +	const TReal sin_a = sin( angle / 2 );
 333.160 +	const TReal cos_a = cos( angle / 2 );
 333.161 +	x    = axis.x * sin_a;
 333.162 +	y    = axis.y * sin_a;
 333.163 +	z    = axis.z * sin_a;
 333.164 +	w    = cos_a;
 333.165 +}
 333.166 +// ---------------------------------------------------------------------------
 333.167 +// Construction from am existing, normalized quaternion
 333.168 +template<typename TReal>
 333.169 +inline aiQuaterniont<TReal>::aiQuaterniont( aiVector3t<TReal> normalized)
 333.170 +{
 333.171 +	x = normalized.x;
 333.172 +	y = normalized.y;
 333.173 +	z = normalized.z;
 333.174 +
 333.175 +	const TReal t = static_cast<TReal>(1.0) - (x*x) - (y*y) - (z*z);
 333.176 +
 333.177 +	if (t < static_cast<TReal>(0.0)) {
 333.178 +		w = static_cast<TReal>(0.0);
 333.179 +	}
 333.180 +	else w = sqrt (t);
 333.181 +}
 333.182 +
 333.183 +// ---------------------------------------------------------------------------
 333.184 +// Performs a spherical interpolation between two quaternions 
 333.185 +// Implementation adopted from the gmtl project. All others I found on the net fail in some cases.
 333.186 +// Congrats, gmtl!
 333.187 +template<typename TReal>
 333.188 +inline void aiQuaterniont<TReal>::Interpolate( aiQuaterniont& pOut, const aiQuaterniont& pStart, const aiQuaterniont& pEnd, TReal pFactor)
 333.189 +{
 333.190 +	// calc cosine theta
 333.191 +	TReal cosom = pStart.x * pEnd.x + pStart.y * pEnd.y + pStart.z * pEnd.z + pStart.w * pEnd.w;
 333.192 +
 333.193 +	// adjust signs (if necessary)
 333.194 +	aiQuaterniont end = pEnd;
 333.195 +	if( cosom < static_cast<TReal>(0.0))
 333.196 +	{
 333.197 +		cosom = -cosom;
 333.198 +		end.x = -end.x;   // Reverse all signs
 333.199 +		end.y = -end.y;
 333.200 +		end.z = -end.z;
 333.201 +		end.w = -end.w;
 333.202 +	} 
 333.203 +
 333.204 +	// Calculate coefficients
 333.205 +	TReal sclp, sclq;
 333.206 +	if( (static_cast<TReal>(1.0) - cosom) > static_cast<TReal>(0.0001)) // 0.0001 -> some epsillon
 333.207 +	{
 333.208 +		// Standard case (slerp)
 333.209 +		TReal omega, sinom;
 333.210 +		omega = acos( cosom); // extract theta from dot product's cos theta
 333.211 +		sinom = sin( omega);
 333.212 +		sclp  = sin( (static_cast<TReal>(1.0) - pFactor) * omega) / sinom;
 333.213 +		sclq  = sin( pFactor * omega) / sinom;
 333.214 +	} else
 333.215 +	{
 333.216 +		// Very close, do linear interp (because it's faster)
 333.217 +		sclp = static_cast<TReal>(1.0) - pFactor;
 333.218 +		sclq = pFactor;
 333.219 +	}
 333.220 +
 333.221 +	pOut.x = sclp * pStart.x + sclq * end.x;
 333.222 +	pOut.y = sclp * pStart.y + sclq * end.y;
 333.223 +	pOut.z = sclp * pStart.z + sclq * end.z;
 333.224 +	pOut.w = sclp * pStart.w + sclq * end.w;
 333.225 +}
 333.226 +
 333.227 +// ---------------------------------------------------------------------------
 333.228 +template<typename TReal>
 333.229 +inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Normalize()
 333.230 +{
 333.231 +	// compute the magnitude and divide through it
 333.232 +	const TReal mag = sqrt(x*x + y*y + z*z + w*w);
 333.233 +	if (mag)
 333.234 +	{
 333.235 +		const TReal invMag = static_cast<TReal>(1.0)/mag;
 333.236 +		x *= invMag;
 333.237 +		y *= invMag;
 333.238 +		z *= invMag;
 333.239 +		w *= invMag;
 333.240 +	}
 333.241 +	return *this;
 333.242 +}
 333.243 +
 333.244 +// ---------------------------------------------------------------------------
 333.245 +template<typename TReal>
 333.246 +inline aiQuaterniont<TReal> aiQuaterniont<TReal>::operator* (const aiQuaterniont& t) const
 333.247 +{
 333.248 +	return aiQuaterniont(w*t.w - x*t.x - y*t.y - z*t.z,
 333.249 +		w*t.x + x*t.w + y*t.z - z*t.y,
 333.250 +		w*t.y + y*t.w + z*t.x - x*t.z,
 333.251 +		w*t.z + z*t.w + x*t.y - y*t.x);
 333.252 +}
 333.253 +
 333.254 +// ---------------------------------------------------------------------------
 333.255 +template<typename TReal>
 333.256 +inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Conjugate ()
 333.257 +{
 333.258 +	x = -x;
 333.259 +	y = -y;
 333.260 +	z = -z;
 333.261 +	return *this;
 333.262 +}
 333.263 +
 333.264 +// ---------------------------------------------------------------------------
 333.265 +template<typename TReal>
 333.266 +inline aiVector3t<TReal> aiQuaterniont<TReal>::Rotate (const aiVector3t<TReal>& v)
 333.267 +{
 333.268 +	aiQuaterniont q2(0.f,v.x,v.y,v.z), q = *this, qinv = q;
 333.269 +	q.Conjugate();
 333.270 +
 333.271 +	q = q*q2*qinv;
 333.272 +	return aiVector3t<TReal>(q.x,q.y,q.z);
 333.273 +
 333.274 +}
 333.275 +
 333.276 +#endif
 333.277 +#endif
   334.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   334.2 +++ b/libs/assimp/assimp/scene.h	Sat Feb 01 19:58:19 2014 +0200
   334.3 @@ -0,0 +1,428 @@
   334.4 +/*
   334.5 +---------------------------------------------------------------------------
   334.6 +Open Asset Import Library (assimp)
   334.7 +---------------------------------------------------------------------------
   334.8 +
   334.9 +Copyright (c) 2006-2012, assimp team
  334.10 +
  334.11 +All rights reserved.
  334.12 +
  334.13 +Redistribution and use of this software in source and binary forms, 
  334.14 +with or without modification, are permitted provided that the following 
  334.15 +conditions are met:
  334.16 +
  334.17 +* Redistributions of source code must retain the above
  334.18 +  copyright notice, this list of conditions and the
  334.19 +  following disclaimer.
  334.20 +
  334.21 +* Redistributions in binary form must reproduce the above
  334.22 +  copyright notice, this list of conditions and the
  334.23 +  following disclaimer in the documentation and/or other
  334.24 +  materials provided with the distribution.
  334.25 +
  334.26 +* Neither the name of the assimp team, nor the names of its
  334.27 +  contributors may be used to endorse or promote products
  334.28 +  derived from this software without specific prior
  334.29 +  written permission of the assimp team.
  334.30 +
  334.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  334.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  334.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  334.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  334.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  334.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  334.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  334.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  334.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  334.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  334.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  334.42 +---------------------------------------------------------------------------
  334.43 +*/
  334.44 +
  334.45 +/** @file aiScene.h
  334.46 + *  @brief Defines the data structures in which the imported scene is returned.
  334.47 + */
  334.48 +#ifndef __AI_SCENE_H_INC__
  334.49 +#define __AI_SCENE_H_INC__
  334.50 +
  334.51 +#include "types.h"
  334.52 +#include "texture.h"
  334.53 +#include "mesh.h"
  334.54 +#include "light.h"
  334.55 +#include "camera.h"
  334.56 +#include "material.h"
  334.57 +#include "anim.h"
  334.58 +#include "metadata.h"
  334.59 +
  334.60 +#ifdef __cplusplus
  334.61 +extern "C" {
  334.62 +#endif
  334.63 +
  334.64 +
  334.65 +// -------------------------------------------------------------------------------
  334.66 +/** A node in the imported hierarchy. 
  334.67 + *
  334.68 + * Each node has name, a parent node (except for the root node), 
  334.69 + * a transformation relative to its parent and possibly several child nodes.
  334.70 + * Simple file formats don't support hierarchical structures - for these formats 
  334.71 + * the imported scene does consist of only a single root node without children.
  334.72 + */
  334.73 +// -------------------------------------------------------------------------------
  334.74 +struct aiNode
  334.75 +{
  334.76 +	/** The name of the node. 
  334.77 +	 *
  334.78 +	 * The name might be empty (length of zero) but all nodes which 
  334.79 +	 * need to be referenced by either bones or animations are named.
  334.80 +	 * Multiple nodes may have the same name, except for nodes which are referenced
  334.81 +	 * by bones (see #aiBone and #aiMesh::mBones). Their names *must* be unique.
  334.82 +	 * 
  334.83 +	 * Cameras and lights reference a specific node by name - if there
  334.84 +	 * are multiple nodes with this name, they are assigned to each of them.
  334.85 +	 * <br>
  334.86 +	 * There are no limitations with regard to the characters contained in
  334.87 +	 * the name string as it is usually taken directly from the source file. 
  334.88 +	 * 
  334.89 +	 * Implementations should be able to handle tokens such as whitespace, tabs,
  334.90 +	 * line feeds, quotation marks, ampersands etc.
  334.91 +	 *
  334.92 +	 * Sometimes assimp introduces new nodes not present in the source file
  334.93 +	 * into the hierarchy (usually out of necessity because sometimes the
  334.94 +	 * source hierarchy format is simply not compatible). Their names are
  334.95 +	 * surrounded by @verbatim <> @endverbatim e.g.
  334.96 +	 *  @verbatim<DummyRootNode> @endverbatim.
  334.97 +	 */
  334.98 +	C_STRUCT aiString mName;
  334.99 +
 334.100 +	/** The transformation relative to the node's parent. */
 334.101 +	C_STRUCT aiMatrix4x4 mTransformation;
 334.102 +
 334.103 +	/** Parent node. NULL if this node is the root node. */
 334.104 +	C_STRUCT aiNode* mParent;
 334.105 +
 334.106 +	/** The number of child nodes of this node. */
 334.107 +	unsigned int mNumChildren;
 334.108 +
 334.109 +	/** The child nodes of this node. NULL if mNumChildren is 0. */
 334.110 +	C_STRUCT aiNode** mChildren;
 334.111 +
 334.112 +	/** The number of meshes of this node. */
 334.113 +	unsigned int mNumMeshes;
 334.114 +
 334.115 +	/** The meshes of this node. Each entry is an index into the mesh */
 334.116 +	unsigned int* mMeshes;
 334.117 +
 334.118 +	/** Metadata associated with this node or NULL if there is no metadata.
 334.119 +	  *  Whether any metadata is generated depends on the source file format. See the
 334.120 +	  * @link importer_notes @endlink page for more information on every source file
 334.121 +	  * format. Importers that don't document any metadata don't write any. 
 334.122 +	  */
 334.123 +	C_STRUCT aiMetadata* mMetaData;
 334.124 +
 334.125 +#ifdef __cplusplus
 334.126 +	/** Constructor */
 334.127 +	aiNode() 
 334.128 +		// set all members to zero by default
 334.129 +		: mName()
 334.130 +		, mParent()
 334.131 +		, mNumChildren()
 334.132 +		, mChildren()
 334.133 +		, mNumMeshes()
 334.134 +		, mMeshes()
 334.135 +		, mMetaData()
 334.136 +	{
 334.137 +	}
 334.138 +	
 334.139 +
 334.140 +	/** Construction from a specific name */
 334.141 +	aiNode(const std::string& name) 
 334.142 +		// set all members to zero by default
 334.143 +		: mName(name)
 334.144 +		, mParent()
 334.145 +		, mNumChildren()
 334.146 +		, mChildren()
 334.147 +		, mNumMeshes()
 334.148 +		, mMeshes()
 334.149 +		, mMetaData()
 334.150 +	{
 334.151 +	}
 334.152 +
 334.153 +	/** Destructor */
 334.154 +	~aiNode()
 334.155 +	{
 334.156 +		// delete all children recursively
 334.157 +		// to make sure we won't crash if the data is invalid ...
 334.158 +		if (mChildren && mNumChildren)  
 334.159 +		{
 334.160 +			for( unsigned int a = 0; a < mNumChildren; a++)
 334.161 +				delete mChildren[a];
 334.162 +		}
 334.163 +		delete [] mChildren;
 334.164 +		delete [] mMeshes;
 334.165 +		delete mMetaData;
 334.166 +	}
 334.167 +
 334.168 +
 334.169 +	/** Searches for a node with a specific name, beginning at this
 334.170 +	 *  nodes. Normally you will call this method on the root node
 334.171 +	 *  of the scene.
 334.172 +	 * 
 334.173 +	 *  @param name Name to search for
 334.174 +	 *  @return NULL or a valid Node if the search was successful.
 334.175 +	 */
 334.176 +	inline const aiNode* FindNode(const aiString& name) const
 334.177 +	{
 334.178 +		return FindNode(name.data);
 334.179 +	}
 334.180 +
 334.181 +
 334.182 +	inline aiNode* FindNode(const aiString& name)
 334.183 +	{
 334.184 +		return FindNode(name.data);
 334.185 +	}
 334.186 +
 334.187 +
 334.188 +	/** @override
 334.189 +	 */
 334.190 +	inline const aiNode* FindNode(const char* name) const
 334.191 +	{
 334.192 +		if (!::strcmp( mName.data,name))return this;
 334.193 +		for (unsigned int i = 0; i < mNumChildren;++i)
 334.194 +		{
 334.195 +			const aiNode* const p = mChildren[i]->FindNode(name);
 334.196 +			if (p) {
 334.197 +				return p;
 334.198 +			}
 334.199 +		}
 334.200 +		// there is definitely no sub-node with this name
 334.201 +		return NULL;
 334.202 +	}
 334.203 +
 334.204 +	inline aiNode* FindNode(const char* name) 
 334.205 +	{
 334.206 +		if (!::strcmp( mName.data,name))return this;
 334.207 +		for (unsigned int i = 0; i < mNumChildren;++i)
 334.208 +		{
 334.209 +			aiNode* const p = mChildren[i]->FindNode(name);
 334.210 +			if (p) {
 334.211 +				return p;
 334.212 +			}
 334.213 +		}
 334.214 +		// there is definitely no sub-node with this name
 334.215 +		return NULL;
 334.216 +	}
 334.217 +
 334.218 +#endif // __cplusplus
 334.219 +};
 334.220 +
 334.221 +
 334.222 +// -------------------------------------------------------------------------------
 334.223 +/** @def AI_SCENE_FLAGS_INCOMPLETE
 334.224 + * Specifies that the scene data structure that was imported is not complete.
 334.225 + * This flag bypasses some internal validations and allows the import 
 334.226 + * of animation skeletons, material libraries or camera animation paths 
 334.227 + * using Assimp. Most applications won't support such data. 
 334.228 + */
 334.229 +#define AI_SCENE_FLAGS_INCOMPLETE	0x1
 334.230 +
 334.231 +/** @def AI_SCENE_FLAGS_VALIDATED
 334.232 + * This flag is set by the validation postprocess-step (aiPostProcess_ValidateDS)
 334.233 + * if the validation is successful. In a validated scene you can be sure that
 334.234 + * any cross references in the data structure (e.g. vertex indices) are valid.
 334.235 + */
 334.236 +#define AI_SCENE_FLAGS_VALIDATED	0x2
 334.237 +
 334.238 +/** @def AI_SCENE_FLAGS_VALIDATION_WARNING
 334.239 + * This flag is set by the validation postprocess-step (aiPostProcess_ValidateDS)
 334.240 + * if the validation is successful but some issues have been found.
 334.241 + * This can for example mean that a texture that does not exist is referenced 
 334.242 + * by a material or that the bone weights for a vertex don't sum to 1.0 ... .
 334.243 + * In most cases you should still be able to use the import. This flag could
 334.244 + * be useful for applications which don't capture Assimp's log output.
 334.245 + */
 334.246 +#define AI_SCENE_FLAGS_VALIDATION_WARNING  	0x4
 334.247 +
 334.248 +/** @def AI_SCENE_FLAGS_NON_VERBOSE_FORMAT
 334.249 + * This flag is currently only set by the aiProcess_JoinIdenticalVertices step.
 334.250 + * It indicates that the vertices of the output meshes aren't in the internal
 334.251 + * verbose format anymore. In the verbose format all vertices are unique,
 334.252 + * no vertex is ever referenced by more than one face.
 334.253 + */
 334.254 +#define AI_SCENE_FLAGS_NON_VERBOSE_FORMAT  	0x8
 334.255 +
 334.256 + /** @def AI_SCENE_FLAGS_TERRAIN
 334.257 + * Denotes pure height-map terrain data. Pure terrains usually consist of quads, 
 334.258 + * sometimes triangles, in a regular grid. The x,y coordinates of all vertex 
 334.259 + * positions refer to the x,y coordinates on the terrain height map, the z-axis
 334.260 + * stores the elevation at a specific point.
 334.261 + *
 334.262 + * TER (Terragen) and HMP (3D Game Studio) are height map formats.
 334.263 + * @note Assimp is probably not the best choice for loading *huge* terrains -
 334.264 + * fully triangulated data takes extremely much free store and should be avoided
 334.265 + * as long as possible (typically you'll do the triangulation when you actually
 334.266 + * need to render it).
 334.267 + */
 334.268 +#define AI_SCENE_FLAGS_TERRAIN 0x10
 334.269 +
 334.270 +
 334.271 +// -------------------------------------------------------------------------------
 334.272 +/** The root structure of the imported data. 
 334.273 + * 
 334.274 + *  Everything that was imported from the given file can be accessed from here.
 334.275 + *  Objects of this class are generally maintained and owned by Assimp, not
 334.276 + *  by the caller. You shouldn't want to instance it, nor should you ever try to
 334.277 + *  delete a given scene on your own.
 334.278 + */
 334.279 +// -------------------------------------------------------------------------------
 334.280 +struct aiScene
 334.281 +{
 334.282 +
 334.283 +	/** Any combination of the AI_SCENE_FLAGS_XXX flags. By default 
 334.284 +	* this value is 0, no flags are set. Most applications will
 334.285 +	* want to reject all scenes with the AI_SCENE_FLAGS_INCOMPLETE 
 334.286 +	* bit set.
 334.287 +	*/
 334.288 +	unsigned int mFlags;
 334.289 +
 334.290 +
 334.291 +	/** The root node of the hierarchy. 
 334.292 +	* 
 334.293 +	* There will always be at least the root node if the import
 334.294 +	* was successful (and no special flags have been set). 
 334.295 +	* Presence of further nodes depends on the format and content 
 334.296 +	* of the imported file.
 334.297 +	*/
 334.298 +	C_STRUCT aiNode* mRootNode;
 334.299 +
 334.300 +
 334.301 +
 334.302 +	/** The number of meshes in the scene. */
 334.303 +	unsigned int mNumMeshes;
 334.304 +
 334.305 +	/** The array of meshes. 
 334.306 +	*
 334.307 +	* Use the indices given in the aiNode structure to access 
 334.308 +	* this array. The array is mNumMeshes in size. If the
 334.309 +	* AI_SCENE_FLAGS_INCOMPLETE flag is not set there will always 
 334.310 +	* be at least ONE material.
 334.311 +	*/
 334.312 +	C_STRUCT aiMesh** mMeshes;
 334.313 +
 334.314 +
 334.315 +
 334.316 +	/** The number of materials in the scene. */
 334.317 +	unsigned int mNumMaterials;
 334.318 +
 334.319 +	/** The array of materials. 
 334.320 +	* 
 334.321 +	* Use the index given in each aiMesh structure to access this
 334.322 +	* array. The array is mNumMaterials in size. If the
 334.323 +	* AI_SCENE_FLAGS_INCOMPLETE flag is not set there will always 
 334.324 +	* be at least ONE material.
 334.325 +	*/
 334.326 +	C_STRUCT aiMaterial** mMaterials;
 334.327 +
 334.328 +
 334.329 +
 334.330 +	/** The number of animations in the scene. */
 334.331 +	unsigned int mNumAnimations; 
 334.332 +
 334.333 +	/** The array of animations. 
 334.334 +	*
 334.335 +	* All animations imported from the given file are listed here.
 334.336 +	* The array is mNumAnimations in size.
 334.337 +	*/
 334.338 +	C_STRUCT aiAnimation** mAnimations;
 334.339 +
 334.340 +
 334.341 +
 334.342 +	/** The number of textures embedded into the file */
 334.343 +	unsigned int mNumTextures;
 334.344 +
 334.345 +	/** The array of embedded textures.
 334.346 +	* 
 334.347 +	* Not many file formats embed their textures into the file.
 334.348 +	* An example is Quake's MDL format (which is also used by
 334.349 +	* some GameStudio versions)
 334.350 +	*/
 334.351 +	C_STRUCT aiTexture** mTextures;
 334.352 +
 334.353 +
 334.354 +	/** The number of light sources in the scene. Light sources
 334.355 +	* are fully optional, in most cases this attribute will be 0 
 334.356 +        */
 334.357 +	unsigned int mNumLights;
 334.358 +
 334.359 +	/** The array of light sources.
 334.360 +	* 
 334.361 +	* All light sources imported from the given file are
 334.362 +	* listed here. The array is mNumLights in size.
 334.363 +	*/
 334.364 +	C_STRUCT aiLight** mLights;
 334.365 +
 334.366 +
 334.367 +	/** The number of cameras in the scene. Cameras
 334.368 +	* are fully optional, in most cases this attribute will be 0 
 334.369 +        */
 334.370 +	unsigned int mNumCameras;
 334.371 +
 334.372 +	/** The array of cameras.
 334.373 +	* 
 334.374 +	* All cameras imported from the given file are listed here.
 334.375 +	* The array is mNumCameras in size. The first camera in the
 334.376 +	* array (if existing) is the default camera view into
 334.377 +	* the scene.
 334.378 +	*/
 334.379 +	C_STRUCT aiCamera** mCameras;
 334.380 +
 334.381 +#ifdef __cplusplus
 334.382 +
 334.383 +	//! Default constructor - set everything to 0/NULL
 334.384 +	aiScene();
 334.385 +
 334.386 +	//! Destructor
 334.387 +	~aiScene();
 334.388 +
 334.389 +	//! Check whether the scene contains meshes
 334.390 +	//! Unless no special scene flags are set this will always be true.
 334.391 +	inline bool HasMeshes() const 
 334.392 +		{ return mMeshes != NULL && mNumMeshes > 0; }
 334.393 +
 334.394 +	//! Check whether the scene contains materials
 334.395 +	//! Unless no special scene flags are set this will always be true.
 334.396 +	inline bool HasMaterials() const 
 334.397 +		{ return mMaterials != NULL && mNumMaterials > 0; }
 334.398 +
 334.399 +	//! Check whether the scene contains lights
 334.400 +	inline bool HasLights() const 
 334.401 +		{ return mLights != NULL && mNumLights > 0; }
 334.402 +
 334.403 +	//! Check whether the scene contains textures
 334.404 +	inline bool HasTextures() const 
 334.405 +		{ return mTextures != NULL && mNumTextures > 0; }
 334.406 +
 334.407 +	//! Check whether the scene contains cameras
 334.408 +	inline bool HasCameras() const 
 334.409 +		{ return mCameras != NULL && mNumCameras > 0; }
 334.410 +
 334.411 +	//! Check whether the scene contains animations
 334.412 +	inline bool HasAnimations() const 
 334.413 +		{ return mAnimations != NULL && mNumAnimations > 0; }
 334.414 +
 334.415 +#endif // __cplusplus
 334.416 +
 334.417 +
 334.418 +	/**  Internal data, do not touch */
 334.419 +#ifdef __cplusplus
 334.420 +	void* mPrivate;
 334.421 +#else
 334.422 +	char* mPrivate;
 334.423 +#endif
 334.424 +
 334.425 +};
 334.426 +
 334.427 +#ifdef __cplusplus
 334.428 +} //! namespace Assimp
 334.429 +#endif
 334.430 +
 334.431 +#endif // __AI_SCENE_H_INC__
   335.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   335.2 +++ b/libs/assimp/assimp/texture.h	Sat Feb 01 19:58:19 2014 +0200
   335.3 @@ -0,0 +1,197 @@
   335.4 +/*
   335.5 +---------------------------------------------------------------------------
   335.6 +Open Asset Import Library (assimp)
   335.7 +---------------------------------------------------------------------------
   335.8 +
   335.9 +Copyright (c) 2006-2012, assimp team
  335.10 +
  335.11 +All rights reserved.
  335.12 +
  335.13 +Redistribution and use of this software in source and binary forms, 
  335.14 +with or without modification, are permitted provided that the following 
  335.15 +conditions are met:
  335.16 +
  335.17 +* Redistributions of source code must retain the above
  335.18 +  copyright notice, this list of conditions and the
  335.19 +  following disclaimer.
  335.20 +
  335.21 +* Redistributions in binary form must reproduce the above
  335.22 +  copyright notice, this list of conditions and the
  335.23 +  following disclaimer in the documentation and/or other
  335.24 +  materials provided with the distribution.
  335.25 +
  335.26 +* Neither the name of the assimp team, nor the names of its
  335.27 +  contributors may be used to endorse or promote products
  335.28 +  derived from this software without specific prior
  335.29 +  written permission of the assimp team.
  335.30 +
  335.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  335.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  335.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  335.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  335.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  335.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  335.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  335.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  335.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  335.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  335.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  335.42 +---------------------------------------------------------------------------
  335.43 +*/
  335.44 +
  335.45 +/** @file texture.h
  335.46 + *  @brief Defines texture helper structures for the library
  335.47 + *
  335.48 + * Used for file formats which embed their textures into the model file.
  335.49 + * Supported are both normal textures, which are stored as uncompressed
  335.50 + * pixels, and "compressed" textures, which are stored in a file format
  335.51 + * such as PNG or TGA.
  335.52 + */
  335.53 +
  335.54 +#ifndef AI_TEXTURE_H_INC
  335.55 +#define AI_TEXTURE_H_INC
  335.56 +
  335.57 +#include "types.h"
  335.58 +
  335.59 +#ifdef __cplusplus
  335.60 +extern "C" {
  335.61 +#endif
  335.62 +
  335.63 +
  335.64 +// --------------------------------------------------------------------------------
  335.65 +/** @def AI_MAKE_EMBEDDED_TEXNAME
  335.66 + *  Used to build the reserved path name used by the material system to 
  335.67 + *  reference textures that are embedded into their corresponding
  335.68 + *  model files. The parameter specifies the index of the texture
  335.69 + *  (zero-based, in the aiScene::mTextures array)
  335.70 + */
  335.71 +#if (!defined AI_MAKE_EMBEDDED_TEXNAME)
  335.72 +#	define AI_MAKE_EMBEDDED_TEXNAME(_n_) "*" # _n_
  335.73 +#endif
  335.74 +
  335.75 +
  335.76 +#include "./Compiler/pushpack1.h"
  335.77 +
  335.78 +// --------------------------------------------------------------------------------
  335.79 +/** @brief Helper structure to represent a texel in a ARGB8888 format
  335.80 +* 
  335.81 +*  Used by aiTexture.
  335.82 +*/
  335.83 +struct aiTexel
  335.84 +{
  335.85 +	unsigned char b,g,r,a;
  335.86 +
  335.87 +#ifdef __cplusplus
  335.88 +	//! Comparison operator
  335.89 +	bool operator== (const aiTexel& other) const
  335.90 +	{
  335.91 +		return b == other.b && r == other.r &&
  335.92 +			   g == other.g && a == other.a;
  335.93 +	}
  335.94 +
  335.95 +	//! Inverse comparison operator
  335.96 +	bool operator!= (const aiTexel& other) const
  335.97 +	{
  335.98 +		return b != other.b || r != other.r ||
  335.99 +			   g != other.g || a != other.a;
 335.100 +	}
 335.101 +
 335.102 +	//! Conversion to a floating-point 4d color
 335.103 +	operator aiColor4D() const
 335.104 +	{
 335.105 +		return aiColor4D(r/255.f,g/255.f,b/255.f,a/255.f);
 335.106 +	}
 335.107 +#endif // __cplusplus
 335.108 +
 335.109 +} PACK_STRUCT;
 335.110 +
 335.111 +#include "./Compiler/poppack1.h"
 335.112 +
 335.113 +// --------------------------------------------------------------------------------
 335.114 +/** Helper structure to describe an embedded texture
 335.115 + * 
 335.116 + * Normally textures are contained in external files but some file formats embed
 335.117 + * them directly in the model file. There are two types of embedded textures: 
 335.118 + * 1. Uncompressed textures. The color data is given in an uncompressed format. 
 335.119 + * 2. Compressed textures stored in a file format like png or jpg. The raw file 
 335.120 + * bytes are given so the application must utilize an image decoder (e.g. DevIL) to
 335.121 + * get access to the actual color data.
 335.122 + */
 335.123 +struct aiTexture
 335.124 +{
 335.125 +	/** Width of the texture, in pixels
 335.126 +	 *
 335.127 +	 * If mHeight is zero the texture is compressed in a format
 335.128 +	 * like JPEG. In this case mWidth specifies the size of the
 335.129 +	 * memory area pcData is pointing to, in bytes.
 335.130 +	 */
 335.131 +	unsigned int mWidth;
 335.132 +
 335.133 +	/** Height of the texture, in pixels
 335.134 +	 *
 335.135 +	 * If this value is zero, pcData points to an compressed texture
 335.136 +	 * in any format (e.g. JPEG).
 335.137 +	 */
 335.138 +	unsigned int mHeight;
 335.139 +
 335.140 +	/** A hint from the loader to make it easier for applications
 335.141 +	 *  to determine the type of embedded compressed textures.
 335.142 +	 *
 335.143 +	 * If mHeight != 0 this member is undefined. Otherwise it
 335.144 +	 * is set set to '\\0\\0\\0\\0' if the loader has no additional
 335.145 +	 * information about the texture file format used OR the
 335.146 +	 * file extension of the format without a trailing dot. If there 
 335.147 +	 * are multiple file extensions for a format, the shortest 
 335.148 +	 * extension is chosen (JPEG maps to 'jpg', not to 'jpeg').
 335.149 +	 * E.g. 'dds\\0', 'pcx\\0', 'jpg\\0'.  All characters are lower-case.
 335.150 +	 * The fourth character will always be '\\0'.
 335.151 +	 */
 335.152 +	char achFormatHint[4];
 335.153 +
 335.154 +	/** Data of the texture.
 335.155 +	 *
 335.156 +	 * Points to an array of mWidth * mHeight aiTexel's.
 335.157 +	 * The format of the texture data is always ARGB8888 to
 335.158 +	 * make the implementation for user of the library as easy
 335.159 +	 * as possible. If mHeight = 0 this is a pointer to a memory
 335.160 +	 * buffer of size mWidth containing the compressed texture
 335.161 +	 * data. Good luck, have fun!
 335.162 +	 */
 335.163 +	C_STRUCT aiTexel* pcData;
 335.164 +
 335.165 +#ifdef __cplusplus
 335.166 +
 335.167 +	//! For compressed textures (mHeight == 0): compare the
 335.168 +	//! format hint against a given string.
 335.169 +	//! @param s Input string. 3 characters are maximally processed.
 335.170 +	//!        Example values: "jpg", "png"
 335.171 +	//! @return true if the given string matches the format hint
 335.172 +	bool CheckFormat(const char* s) const
 335.173 +	{
 335.174 +		return (0 == ::strncmp(achFormatHint,s,3));
 335.175 +	}
 335.176 +
 335.177 +	// Construction
 335.178 +	aiTexture ()
 335.179 +		: mWidth  (0)
 335.180 +		, mHeight (0)
 335.181 +		, pcData  (NULL)
 335.182 +	{
 335.183 +		achFormatHint[0] = achFormatHint[1] = 0;
 335.184 +		achFormatHint[2] = achFormatHint[3] = 0;
 335.185 +	}
 335.186 +
 335.187 +	// Destruction
 335.188 +	~aiTexture ()
 335.189 +	{
 335.190 +		delete[] pcData;
 335.191 +	}
 335.192 +#endif
 335.193 +};
 335.194 +
 335.195 +
 335.196 +#ifdef __cplusplus
 335.197 +}
 335.198 +#endif
 335.199 +
 335.200 +#endif // AI_TEXTURE_H_INC
   336.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   336.2 +++ b/libs/assimp/assimp/types.h	Sat Feb 01 19:58:19 2014 +0200
   336.3 @@ -0,0 +1,500 @@
   336.4 +/*
   336.5 +---------------------------------------------------------------------------
   336.6 +Open Asset Import Library (assimp)
   336.7 +---------------------------------------------------------------------------
   336.8 +
   336.9 +Copyright (c) 2006-2012, assimp team
  336.10 +
  336.11 +All rights reserved.
  336.12 +
  336.13 +Redistribution and use of this software in source and binary forms, 
  336.14 +with or without modification, are permitted provided that the following 
  336.15 +conditions are met:
  336.16 +
  336.17 +* Redistributions of source code must retain the above
  336.18 +  copyright notice, this list of conditions and the
  336.19 +  following disclaimer.
  336.20 +
  336.21 +* Redistributions in binary form must reproduce the above
  336.22 +  copyright notice, this list of conditions and the
  336.23 +  following disclaimer in the documentation and/or other
  336.24 +  materials provided with the distribution.
  336.25 +
  336.26 +* Neither the name of the assimp team, nor the names of its
  336.27 +  contributors may be used to endorse or promote products
  336.28 +  derived from this software without specific prior
  336.29 +  written permission of the assimp team.
  336.30 +
  336.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  336.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  336.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  336.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  336.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  336.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  336.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  336.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  336.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  336.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  336.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  336.42 +---------------------------------------------------------------------------
  336.43 +*/
  336.44 +
  336.45 +/** @file types.h
  336.46 + *  Basic data types and primitives, such as vectors or colors. 
  336.47 + */
  336.48 +#ifndef AI_TYPES_H_INC
  336.49 +#define AI_TYPES_H_INC
  336.50 +
  336.51 +// Some runtime headers
  336.52 +#include <sys/types.h>
  336.53 +#include <memory.h>
  336.54 +#include <math.h>
  336.55 +#include <stddef.h>
  336.56 +#include <limits.h>
  336.57 +
  336.58 +// Our compile configuration
  336.59 +#include "defs.h"
  336.60 +
  336.61 +// Some types moved to separate header due to size of operators
  336.62 +#include "vector3.h"
  336.63 +#include "vector2.h"
  336.64 +#include "color4.h"
  336.65 +#include "matrix3x3.h"
  336.66 +#include "matrix4x4.h"
  336.67 +#include "quaternion.h"
  336.68 +
  336.69 +#ifdef __cplusplus
  336.70 +#include <new>		// for std::nothrow_t
  336.71 +#include <string>	// for aiString::Set(const std::string&)
  336.72 +
  336.73 +namespace Assimp	{
  336.74 +	//! @cond never
  336.75 +namespace Intern		{
  336.76 +	// --------------------------------------------------------------------
  336.77 +	/** @brief Internal helper class to utilize our internal new/delete 
  336.78 +	 *    routines for allocating object of this and derived classes.
  336.79 +	 *
  336.80 +	 * By doing this you can safely share class objects between Assimp
  336.81 +	 * and the application - it works even over DLL boundaries. A good
  336.82 +	 * example is the #IOSystem where the application allocates its custom
  336.83 +	 * #IOSystem, then calls #Importer::SetIOSystem(). When the Importer
  336.84 +	 * destructs, Assimp calls operator delete on the stored #IOSystem.
  336.85 +	 * If it lies on a different heap than Assimp is working with,
  336.86 +	 * the application is determined to crash.
  336.87 +	 */
  336.88 +	// --------------------------------------------------------------------
  336.89 +#ifndef SWIG
  336.90 +	struct ASSIMP_API AllocateFromAssimpHeap	{
  336.91 +		// http://www.gotw.ca/publications/mill15.htm
  336.92 +
  336.93 +		// new/delete overload
  336.94 +		void *operator new    ( size_t num_bytes) /* throw( std::bad_alloc ) */;
  336.95 +		void *operator new    ( size_t num_bytes, const std::nothrow_t& ) throw();
  336.96 +		void  operator delete ( void* data);
  336.97 +
  336.98 +		// array new/delete overload
  336.99 +		void *operator new[]    ( size_t num_bytes) /* throw( std::bad_alloc ) */;
 336.100 +		void *operator new[]    ( size_t num_bytes, const std::nothrow_t& )  throw();
 336.101 +		void  operator delete[] ( void* data);
 336.102 +
 336.103 +	}; // struct AllocateFromAssimpHeap
 336.104 +#endif
 336.105 +} // namespace Intern
 336.106 +	//! @endcond
 336.107 +} // namespace Assimp
 336.108 +
 336.109 +extern "C" {
 336.110 +#endif
 336.111 +
 336.112 +/** Maximum dimension for strings, ASSIMP strings are zero terminated. */
 336.113 +#ifdef __cplusplus
 336.114 +const size_t MAXLEN = 1024;
 336.115 +#else
 336.116 +#	define MAXLEN 1024
 336.117 +#endif
 336.118 +
 336.119 +#include "./Compiler/pushpack1.h"
 336.120 +
 336.121 +// ----------------------------------------------------------------------------------
 336.122 +/** Represents a plane in a three-dimensional, euclidean space
 336.123 +*/
 336.124 +struct aiPlane
 336.125 +{
 336.126 +#ifdef __cplusplus
 336.127 +	aiPlane () : a(0.f), b(0.f), c(0.f), d(0.f) {}
 336.128 +	aiPlane (float _a, float _b, float _c, float _d) 
 336.129 +		: a(_a), b(_b), c(_c), d(_d) {}
 336.130 +
 336.131 +	aiPlane (const aiPlane& o) : a(o.a), b(o.b), c(o.c), d(o.d) {}
 336.132 +
 336.133 +#endif // !__cplusplus
 336.134 +
 336.135 +	//! Plane equation
 336.136 +	float a,b,c,d;
 336.137 +} PACK_STRUCT; // !struct aiPlane
 336.138 +
 336.139 +// ----------------------------------------------------------------------------------
 336.140 +/** Represents a ray
 336.141 +*/
 336.142 +struct aiRay
 336.143 +{
 336.144 +#ifdef __cplusplus
 336.145 +	aiRay () {}
 336.146 +	aiRay (const aiVector3D& _pos, const aiVector3D& _dir)
 336.147 +		: pos(_pos), dir(_dir) {}
 336.148 +
 336.149 +	aiRay (const aiRay& o) : pos (o.pos), dir (o.dir) {}
 336.150 +
 336.151 +#endif // !__cplusplus
 336.152 +
 336.153 +	//! Position and direction of the ray
 336.154 +	C_STRUCT aiVector3D pos, dir;
 336.155 +} PACK_STRUCT; // !struct aiRay
 336.156 +
 336.157 +// ----------------------------------------------------------------------------------
 336.158 +/** Represents a color in Red-Green-Blue space. 
 336.159 +*/
 336.160 +struct aiColor3D
 336.161 +{
 336.162 +#ifdef __cplusplus
 336.163 +	aiColor3D () : r(0.0f), g(0.0f), b(0.0f) {}
 336.164 +	aiColor3D (float _r, float _g, float _b) : r(_r), g(_g), b(_b) {}
 336.165 +	aiColor3D (float _r) : r(_r), g(_r), b(_r) {}
 336.166 +	aiColor3D (const aiColor3D& o) : r(o.r), g(o.g), b(o.b) {}
 336.167 +	
 336.168 +	/** Component-wise comparison */
 336.169 +	// TODO: add epsilon?
 336.170 +	bool operator == (const aiColor3D& other) const
 336.171 +		{return r == other.r && g == other.g && b == other.b;}
 336.172 +
 336.173 +	/** Component-wise inverse comparison */
 336.174 +	// TODO: add epsilon?
 336.175 +	bool operator != (const aiColor3D& other) const
 336.176 +		{return r != other.r || g != other.g || b != other.b;}
 336.177 +
 336.178 +	/** Component-wise addition */
 336.179 +	aiColor3D operator+(const aiColor3D& c) const {
 336.180 +		return aiColor3D(r+c.r,g+c.g,b+c.b);
 336.181 +	}
 336.182 +
 336.183 +	/** Component-wise subtraction */
 336.184 +	aiColor3D operator-(const aiColor3D& c) const {
 336.185 +		return aiColor3D(r-c.r,g-c.g,b-c.b);
 336.186 +	}
 336.187 +
 336.188 +	/** Component-wise multiplication */
 336.189 +	aiColor3D operator*(const aiColor3D& c) const {
 336.190 +		return aiColor3D(r*c.r,g*c.g,b*c.b);
 336.191 +	}
 336.192 +	
 336.193 +	/** Multiply with a scalar */
 336.194 +	aiColor3D operator*(float f) const {
 336.195 +		return aiColor3D(r*f,g*f,b*f);
 336.196 +	}
 336.197 +
 336.198 +	/** Access a specific color component */
 336.199 +	float operator[](unsigned int i) const {
 336.200 +		return *(&r + i);
 336.201 +	}
 336.202 +
 336.203 +	/** Access a specific color component */
 336.204 +	float& operator[](unsigned int i) {
 336.205 +		return *(&r + i);
 336.206 +	}
 336.207 +
 336.208 +	/** Check whether a color is black */
 336.209 +	bool IsBlack() const {
 336.210 +		static const float epsilon = 10e-3f;
 336.211 +		return fabs( r ) < epsilon && fabs( g ) < epsilon && fabs( b ) < epsilon;
 336.212 +	}
 336.213 +
 336.214 +#endif // !__cplusplus
 336.215 +
 336.216 +	//! Red, green and blue color values
 336.217 +	float r, g, b;
 336.218 +} PACK_STRUCT;  // !struct aiColor3D
 336.219 +#include "./Compiler/poppack1.h"
 336.220 +
 336.221 +// ----------------------------------------------------------------------------------
 336.222 +/** Represents an UTF-8 string, zero byte terminated.
 336.223 + *
 336.224 + *  The character set of an aiString is explicitly defined to be UTF-8. This Unicode
 336.225 + *  transformation was chosen in the belief that most strings in 3d files are limited
 336.226 + *  to ASCII, thus the character set needed to be strictly ASCII compatible.
 336.227 + *  
 336.228 + *  Most text file loaders provide proper Unicode input file handling, special unicode
 336.229 + *  characters are correctly transcoded to UTF8 and are kept throughout the libraries'
 336.230 + *  import pipeline. 
 336.231 + *
 336.232 + *  For most applications, it will be absolutely sufficient to interpret the
 336.233 + *  aiString as ASCII data and work with it as one would work with a plain char*. 
 336.234 + *  Windows users in need of proper support for i.e asian characters can use the
 336.235 + *  #MultiByteToWideChar(), #WideCharToMultiByte() WinAPI functionality to convert the
 336.236 + *  UTF-8 strings to their working character set (i.e. MBCS, WideChar).
 336.237 + *
 336.238 + *  We use this representation instead of std::string to be C-compatible. The 
 336.239 + *  (binary) length of such a string is limited to MAXLEN characters (including the
 336.240 + *  the terminating zero).
 336.241 +*/
 336.242 +struct aiString
 336.243 +{
 336.244 +#ifdef __cplusplus
 336.245 +	/** Default constructor, the string is set to have zero length */
 336.246 +	aiString() :
 336.247 +		length(0) 
 336.248 +	{
 336.249 +		data[0] = '\0';
 336.250 +
 336.251 +#ifdef _DEBUG
 336.252 +		// Debug build: overwrite the string on its full length with ESC (27)
 336.253 +		memset(data+1,27,MAXLEN-1);
 336.254 +#endif
 336.255 +	}
 336.256 +
 336.257 +	/** Copy constructor */
 336.258 +	aiString(const aiString& rOther) : 
 336.259 +		length(rOther.length) 
 336.260 +	{
 336.261 +		// Crop the string to the maximum length
 336.262 +		length = length>=MAXLEN?MAXLEN-1:length;
 336.263 +		memcpy( data, rOther.data, length);
 336.264 +		data[length] = '\0';
 336.265 +	}
 336.266 +
 336.267 +	/** Constructor from std::string */
 336.268 +	explicit aiString(const std::string& pString) : 
 336.269 +		length(pString.length()) 
 336.270 +	{
 336.271 +		length = length>=MAXLEN?MAXLEN-1:length;
 336.272 +		memcpy( data, pString.c_str(), length);
 336.273 +		data[length] = '\0';
 336.274 +	}
 336.275 +
 336.276 +	/** Copy a std::string to the aiString */
 336.277 +	void Set( const std::string& pString) {
 336.278 +		if( pString.length() > MAXLEN - 1) {
 336.279 +			return;
 336.280 +		}
 336.281 +		length = pString.length();
 336.282 +		memcpy( data, pString.c_str(), length);
 336.283 +		data[length] = 0;
 336.284 +	}
 336.285 +
 336.286 +	/** Copy a const char* to the aiString */
 336.287 +	void Set( const char* sz) {
 336.288 +		const size_t len = ::strlen(sz);
 336.289 +		if( len > MAXLEN - 1) {
 336.290 +			return;
 336.291 +		}
 336.292 +		length = len;
 336.293 +		memcpy( data, sz, len);
 336.294 +		data[len] = 0;
 336.295 +	}
 336.296 +
 336.297 +	/** Assign a const char* to the string */
 336.298 +	aiString& operator = (const char* sz) {
 336.299 +		Set(sz);
 336.300 +		return *this;
 336.301 +	}
 336.302 +
 336.303 +	/** Assign a cstd::string to the string */
 336.304 +	aiString& operator = ( const std::string& pString) {
 336.305 +		Set(pString);
 336.306 +		return *this;
 336.307 +	}
 336.308 +
 336.309 +	/** Comparison operator */
 336.310 +	bool operator==(const aiString& other) const {
 336.311 +		return  (length == other.length && 0 == memcmp(data,other.data,length));
 336.312 +	}
 336.313 +
 336.314 +	/** Inverse comparison operator */
 336.315 +	bool operator!=(const aiString& other) const {
 336.316 +		return  (length != other.length || 0 != memcmp(data,other.data,length));
 336.317 +	}
 336.318 +
 336.319 +	/** Append a string to the string */
 336.320 +	void Append (const char* app)	{
 336.321 +		const size_t len = ::strlen(app);
 336.322 +		if (!len) {
 336.323 +			return;
 336.324 +		}
 336.325 +		if (length + len >= MAXLEN) {
 336.326 +			return;
 336.327 +		}
 336.328 +
 336.329 +		memcpy(&data[length],app,len+1);
 336.330 +		length += len;
 336.331 +	}
 336.332 +
 336.333 +	/** Clear the string - reset its length to zero */
 336.334 +	void Clear ()	{
 336.335 +		length  = 0;
 336.336 +		data[0] = '\0';
 336.337 +
 336.338 +#ifdef _DEBUG
 336.339 +		// Debug build: overwrite the string on its full length with ESC (27)
 336.340 +		memset(data+1,27,MAXLEN-1);
 336.341 +#endif
 336.342 +	}
 336.343 +
 336.344 +	/** Returns a pointer to the underlying zero-terminated array of characters */
 336.345 +	const char* C_Str() const {
 336.346 +		return data;
 336.347 +	}
 336.348 +
 336.349 +#endif // !__cplusplus
 336.350 +
 336.351 +	/** Binary length of the string excluding the terminal 0. This is NOT the 
 336.352 +	 *  logical length of strings containing UTF-8 multibyte sequences! It's
 336.353 +	 *  the number of bytes from the beginning of the string to its end.*/
 336.354 +	size_t length;
 336.355 +
 336.356 +	/** String buffer. Size limit is MAXLEN */
 336.357 +	char data[MAXLEN];
 336.358 +} ;  // !struct aiString
 336.359 +
 336.360 +
 336.361 +// ----------------------------------------------------------------------------------
 336.362 +/**	Standard return type for some library functions.
 336.363 + * Rarely used, and if, mostly in the C API.
 336.364 + */
 336.365 +enum aiReturn
 336.366 +{
 336.367 +	/** Indicates that a function was successful */
 336.368 +	aiReturn_SUCCESS = 0x0,
 336.369 +
 336.370 +	/** Indicates that a function failed */
 336.371 +	aiReturn_FAILURE = -0x1,
 336.372 +
 336.373 +	/** Indicates that not enough memory was available
 336.374 +	 * to perform the requested operation 
 336.375 +	 */
 336.376 +	aiReturn_OUTOFMEMORY = -0x3,
 336.377 +
 336.378 +	/** @cond never 
 336.379 +	 *  Force 32-bit size enum
 336.380 +	 */
 336.381 +	_AI_ENFORCE_ENUM_SIZE = 0x7fffffff 
 336.382 +};  // !enum aiReturn
 336.383 +
 336.384 +// just for backwards compatibility, don't use these constants anymore
 336.385 +#define AI_SUCCESS     aiReturn_SUCCESS
 336.386 +#define AI_FAILURE     aiReturn_FAILURE
 336.387 +#define AI_OUTOFMEMORY aiReturn_OUTOFMEMORY
 336.388 +
 336.389 +// ----------------------------------------------------------------------------------
 336.390 +/** Seek origins (for the virtual file system API).
 336.391 + *  Much cooler than using SEEK_SET, SEEK_CUR or SEEK_END.
 336.392 + */
 336.393 +enum aiOrigin
 336.394 +{
 336.395 +	/** Beginning of the file */
 336.396 +	aiOrigin_SET = 0x0,	
 336.397 +
 336.398 +	/** Current position of the file pointer */
 336.399 +	aiOrigin_CUR = 0x1,		
 336.400 +
 336.401 +	/** End of the file, offsets must be negative */
 336.402 +	aiOrigin_END = 0x2,
 336.403 +
 336.404 +	/**  @cond never 
 336.405 +	 *   Force 32-bit size enum 
 336.406 +	 */
 336.407 +	_AI_ORIGIN_ENFORCE_ENUM_SIZE = 0x7fffffff 
 336.408 +}; // !enum aiOrigin
 336.409 +
 336.410 +// ----------------------------------------------------------------------------------
 336.411 +/** @brief Enumerates predefined log streaming destinations. 
 336.412 + *  Logging to these streams can be enabled with a single call to 
 336.413 + *   #LogStream::createDefaultStream or #aiAttachPredefinedLogStream(),
 336.414 + *   respectively.
 336.415 + */
 336.416 +enum aiDefaultLogStream	
 336.417 +{
 336.418 +	/** Stream the log to a file */
 336.419 +	aiDefaultLogStream_FILE = 0x1,
 336.420 +
 336.421 +	/** Stream the log to std::cout */
 336.422 +	aiDefaultLogStream_STDOUT = 0x2,
 336.423 +
 336.424 +	/** Stream the log to std::cerr */
 336.425 +	aiDefaultLogStream_STDERR = 0x4,
 336.426 +
 336.427 +	/** MSVC only: Stream the log the the debugger
 336.428 +	 * (this relies on OutputDebugString from the Win32 SDK)
 336.429 +	 */
 336.430 +	aiDefaultLogStream_DEBUGGER = 0x8,
 336.431 +
 336.432 +	/** @cond never 
 336.433 +	 *  Force 32-bit size enum 
 336.434 +	 */
 336.435 +	_AI_DLS_ENFORCE_ENUM_SIZE = 0x7fffffff 
 336.436 +}; // !enum aiDefaultLogStream
 336.437 +
 336.438 +// just for backwards compatibility, don't use these constants anymore
 336.439 +#define DLS_FILE     aiDefaultLogStream_FILE
 336.440 +#define DLS_STDOUT   aiDefaultLogStream_STDOUT
 336.441 +#define DLS_STDERR   aiDefaultLogStream_STDERR
 336.442 +#define DLS_DEBUGGER aiDefaultLogStream_DEBUGGER
 336.443 +
 336.444 +// ----------------------------------------------------------------------------------
 336.445 +/** Stores the memory requirements for different components (e.g. meshes, materials,
 336.446 + *  animations) of an import. All sizes are in bytes.
 336.447 + *  @see Importer::GetMemoryRequirements()
 336.448 +*/
 336.449 +struct aiMemoryInfo
 336.450 +{
 336.451 +#ifdef __cplusplus
 336.452 +
 336.453 +	/** Default constructor */
 336.454 +	aiMemoryInfo()
 336.455 +		: textures   (0)
 336.456 +		, materials  (0)
 336.457 +		, meshes     (0)
 336.458 +		, nodes      (0)
 336.459 +		, animations (0)
 336.460 +		, cameras	 (0)
 336.461 +		, lights	 (0)
 336.462 +		, total      (0)
 336.463 +	{}
 336.464 +
 336.465 +#endif
 336.466 +
 336.467 +	/** Storage allocated for texture data */
 336.468 +	unsigned int textures;
 336.469 +
 336.470 +	/** Storage allocated for material data  */
 336.471 +	unsigned int materials;
 336.472 +
 336.473 +	/** Storage allocated for mesh data */
 336.474 +	unsigned int meshes;
 336.475 +
 336.476 +	/** Storage allocated for node data */
 336.477 +	unsigned int nodes;
 336.478 +
 336.479 +	/** Storage allocated for animation data */
 336.480 +	unsigned int animations;
 336.481 +
 336.482 +	/** Storage allocated for camera data */
 336.483 +	unsigned int cameras;
 336.484 +
 336.485 +	/** Storage allocated for light data */
 336.486 +	unsigned int lights;
 336.487 +
 336.488 +	/** Total storage allocated for the full import. */
 336.489 +	unsigned int total;
 336.490 +}; // !struct aiMemoryInfo 
 336.491 +
 336.492 +#ifdef __cplusplus
 336.493 +}
 336.494 +#endif //!  __cplusplus
 336.495 +
 336.496 +// Include implementation files
 336.497 +#include "vector2.inl"
 336.498 +#include "vector3.inl"
 336.499 +#include "color4.inl"
 336.500 +#include "quaternion.inl"
 336.501 +#include "matrix3x3.inl"
 336.502 +#include "matrix4x4.inl"
 336.503 +#endif 
   337.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   337.2 +++ b/libs/assimp/assimp/vector2.h	Sat Feb 01 19:58:19 2014 +0200
   337.3 @@ -0,0 +1,107 @@
   337.4 +/*
   337.5 +---------------------------------------------------------------------------
   337.6 +Open Asset Import Library (assimp)
   337.7 +---------------------------------------------------------------------------
   337.8 +
   337.9 +Copyright (c) 2006-2012, assimp team
  337.10 +
  337.11 +All rights reserved.
  337.12 +
  337.13 +Redistribution and use of this software in source and binary forms, 
  337.14 +with or without modification, are permitted provided that the following 
  337.15 +conditions are met:
  337.16 +
  337.17 +* Redistributions of source code must retain the above
  337.18 +  copyright notice, this list of conditions and the
  337.19 +  following disclaimer.
  337.20 +
  337.21 +* Redistributions in binary form must reproduce the above
  337.22 +  copyright notice, this list of conditions and the
  337.23 +  following disclaimer in the documentation and/or other
  337.24 +  materials provided with the distribution.
  337.25 +
  337.26 +* Neither the name of the assimp team, nor the names of its
  337.27 +  contributors may be used to endorse or promote products
  337.28 +  derived from this software without specific prior
  337.29 +  written permission of the assimp team.
  337.30 +
  337.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  337.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  337.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  337.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  337.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  337.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  337.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  337.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  337.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  337.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  337.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  337.42 +---------------------------------------------------------------------------
  337.43 +*/
  337.44 +/** @file aiVector2t.h
  337.45 + *  @brief 2D vector structure, including operators when compiling in C++
  337.46 + */
  337.47 +#ifndef AI_VECTOR2D_H_INC
  337.48 +#define AI_VECTOR2D_H_INC
  337.49 +
  337.50 +#include <math.h>
  337.51 +
  337.52 +#include "./Compiler/pushpack1.h"
  337.53 +
  337.54 +// ----------------------------------------------------------------------------------
  337.55 +/** Represents a two-dimensional vector. 
  337.56 + */
  337.57 +
  337.58 +#ifdef __cplusplus
  337.59 +template <typename TReal>
  337.60 +class aiVector2t
  337.61 +{
  337.62 +public:
  337.63 +
  337.64 +	aiVector2t () : x(), y() {}
  337.65 +	aiVector2t (TReal _x, TReal _y) : x(_x), y(_y) {}
  337.66 +	explicit aiVector2t (TReal _xyz) : x(_xyz), y(_xyz) {}
  337.67 +	aiVector2t (const aiVector2t& o) : x(o.x), y(o.y) {}
  337.68 +
  337.69 +public:
  337.70 +
  337.71 +	void Set( TReal pX, TReal pY);
  337.72 +	TReal SquareLength() const ;
  337.73 +	TReal Length() const ;
  337.74 +	aiVector2t& Normalize();
  337.75 +
  337.76 +public:
  337.77 +
  337.78 +	const aiVector2t& operator += (const aiVector2t& o);
  337.79 +	const aiVector2t& operator -= (const aiVector2t& o);
  337.80 +	const aiVector2t& operator *= (TReal f);
  337.81 +	const aiVector2t& operator /= (TReal f);
  337.82 +
  337.83 +	TReal operator[](unsigned int i) const;
  337.84 +	TReal& operator[](unsigned int i);
  337.85 +
  337.86 +	bool operator== (const aiVector2t& other) const;
  337.87 +	bool operator!= (const aiVector2t& other) const;
  337.88 +
  337.89 +	aiVector2t& operator= (TReal f);
  337.90 +	const aiVector2t SymMul(const aiVector2t& o);
  337.91 +
  337.92 +	template <typename TOther>
  337.93 +	operator aiVector2t<TOther> () const;
  337.94 +
  337.95 +	TReal x, y;	
  337.96 +} PACK_STRUCT;
  337.97 +
  337.98 +typedef aiVector2t<float> aiVector2D;
  337.99 +
 337.100 +#else
 337.101 +
 337.102 +struct aiVector2D {
 337.103 +	float x,y;
 337.104 +};
 337.105 +
 337.106 +#endif // __cplusplus
 337.107 +
 337.108 +#include "./Compiler/poppack1.h"
 337.109 +
 337.110 +#endif // AI_VECTOR2D_H_INC
   338.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   338.2 +++ b/libs/assimp/assimp/vector2.inl	Sat Feb 01 19:58:19 2014 +0200
   338.3 @@ -0,0 +1,214 @@
   338.4 +/*
   338.5 +---------------------------------------------------------------------------
   338.6 +Open Asset Import Library (assimp)
   338.7 +---------------------------------------------------------------------------
   338.8 +
   338.9 +Copyright (c) 2006-2012, assimp team
  338.10 +
  338.11 +All rights reserved.
  338.12 +
  338.13 +Redistribution and use of this software in source and binary forms, 
  338.14 +with or without modification, are permitted provided that the following 
  338.15 +conditions are met:
  338.16 +
  338.17 +* Redistributions of source code must retain the above
  338.18 +  copyright notice, this list of conditions and the
  338.19 +  following disclaimer.
  338.20 +
  338.21 +* Redistributions in binary form must reproduce the above
  338.22 +  copyright notice, this list of conditions and the
  338.23 +  following disclaimer in the documentation and/or other
  338.24 +  materials provided with the distribution.
  338.25 +
  338.26 +* Neither the name of the assimp team, nor the names of its
  338.27 +  contributors may be used to endorse or promote products
  338.28 +  derived from this software without specific prior
  338.29 +  written permission of the assimp team.
  338.30 +
  338.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  338.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  338.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  338.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  338.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  338.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  338.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  338.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  338.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  338.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  338.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  338.42 +---------------------------------------------------------------------------
  338.43 +*/
  338.44 +
  338.45 +/** @file  aiVector2D.inl
  338.46 + *  @brief Inline implementation of aiVector2t<TReal> operators
  338.47 + */
  338.48 +#ifndef AI_VECTOR2D_INL_INC
  338.49 +#define AI_VECTOR2D_INL_INC
  338.50 +
  338.51 +#ifdef __cplusplus
  338.52 +#include "vector2.h"
  338.53 +
  338.54 +// ------------------------------------------------------------------------------------------------
  338.55 +template <typename TReal>
  338.56 +template <typename TOther>
  338.57 +aiVector2t<TReal>::operator aiVector2t<TOther> () const {
  338.58 +	return aiVector2t<TOther>(static_cast<TOther>(x),static_cast<TOther>(y));
  338.59 +}
  338.60 +// ------------------------------------------------------------------------------------------------
  338.61 +template <typename TReal>
  338.62 +void aiVector2t<TReal>::Set( TReal pX, TReal pY) { 
  338.63 +	x = pX; y = pY;
  338.64 +}
  338.65 +
  338.66 +// ------------------------------------------------------------------------------------------------
  338.67 +template <typename TReal>
  338.68 +TReal aiVector2t<TReal>::SquareLength() const {
  338.69 +	return x*x + y*y; 
  338.70 +}
  338.71 +
  338.72 +// ------------------------------------------------------------------------------------------------
  338.73 +template <typename TReal>
  338.74 +TReal aiVector2t<TReal>::Length() const {
  338.75 +	return ::sqrt( SquareLength());
  338.76 +}
  338.77 +
  338.78 +// ------------------------------------------------------------------------------------------------
  338.79 +template <typename TReal>
  338.80 +aiVector2t<TReal>& aiVector2t<TReal>::Normalize() { 
  338.81 +	*this /= Length(); 
  338.82 +	return *this;
  338.83 +}
  338.84 +
  338.85 +// ------------------------------------------------------------------------------------------------
  338.86 +template <typename TReal>
  338.87 +const aiVector2t<TReal>& aiVector2t<TReal>::operator += (const aiVector2t& o) {
  338.88 +	x += o.x; y += o.y;  
  338.89 +	return *this; 
  338.90 +}
  338.91 +
  338.92 +// ------------------------------------------------------------------------------------------------
  338.93 +template <typename TReal>
  338.94 +const aiVector2t<TReal>& aiVector2t<TReal>::operator -= (const aiVector2t& o) {
  338.95 +	x -= o.x; y -= o.y;  
  338.96 +	return *this; 
  338.97 +}
  338.98 +
  338.99 +// ------------------------------------------------------------------------------------------------
 338.100 +template <typename TReal>
 338.101 +const aiVector2t<TReal>& aiVector2t<TReal>::operator *= (TReal f) { 
 338.102 +	x *= f; y *= f;  
 338.103 +	return *this; 
 338.104 +}
 338.105 +
 338.106 +// ------------------------------------------------------------------------------------------------
 338.107 +template <typename TReal>
 338.108 +const aiVector2t<TReal>& aiVector2t<TReal>::operator /= (TReal f) {
 338.109 +	x /= f; y /= f;  
 338.110 +	return *this; 
 338.111 +}
 338.112 +
 338.113 +// ------------------------------------------------------------------------------------------------
 338.114 +template <typename TReal>
 338.115 +TReal aiVector2t<TReal>::operator[](unsigned int i) const {
 338.116 +	return *(&x + i);
 338.117 +}
 338.118 +
 338.119 +// ------------------------------------------------------------------------------------------------
 338.120 +template <typename TReal>
 338.121 +TReal& aiVector2t<TReal>::operator[](unsigned int i) {
 338.122 +	return *(&x + i);
 338.123 +}
 338.124 +
 338.125 +// ------------------------------------------------------------------------------------------------
 338.126 +template <typename TReal>
 338.127 +bool aiVector2t<TReal>::operator== (const aiVector2t& other) const {
 338.128 +	return x == other.x && y == other.y;
 338.129 +}
 338.130 +
 338.131 +// ------------------------------------------------------------------------------------------------
 338.132 +template <typename TReal>
 338.133 +bool aiVector2t<TReal>::operator!= (const aiVector2t& other) const {
 338.134 +	return x != other.x || y != other.y;
 338.135 +}
 338.136 +
 338.137 +// ------------------------------------------------------------------------------------------------
 338.138 +template <typename TReal>
 338.139 +aiVector2t<TReal>& aiVector2t<TReal>::operator= (TReal f)	{
 338.140 +	x = y = f;
 338.141 +	return *this;
 338.142 +}
 338.143 +
 338.144 +// ------------------------------------------------------------------------------------------------
 338.145 +template <typename TReal>
 338.146 +const aiVector2t<TReal> aiVector2t<TReal>::SymMul(const aiVector2t& o) {
 338.147 +	return aiVector2t(x*o.x,y*o.y);
 338.148 +}
 338.149 +
 338.150 +
 338.151 +// ------------------------------------------------------------------------------------------------
 338.152 +// symmetric addition
 338.153 +template <typename TReal>
 338.154 +inline aiVector2t<TReal> operator + (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
 338.155 +{
 338.156 +	return aiVector2t<TReal>( v1.x + v2.x, v1.y + v2.y);
 338.157 +}
 338.158 +
 338.159 +// ------------------------------------------------------------------------------------------------
 338.160 +// symmetric subtraction
 338.161 +template <typename TReal>
 338.162 +inline aiVector2t<TReal> operator - (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
 338.163 +{
 338.164 +	return aiVector2t<TReal>( v1.x - v2.x, v1.y - v2.y);
 338.165 +}
 338.166 +
 338.167 +// ------------------------------------------------------------------------------------------------
 338.168 +// scalar product
 338.169 +template <typename TReal>
 338.170 +inline TReal operator * (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
 338.171 +{
 338.172 +	return v1.x*v2.x + v1.y*v2.y;
 338.173 +}
 338.174 +
 338.175 +// ------------------------------------------------------------------------------------------------
 338.176 +// scalar multiplication
 338.177 +template <typename TReal>
 338.178 +inline aiVector2t<TReal> operator * ( TReal f, const aiVector2t<TReal>& v)
 338.179 +{
 338.180 +	return aiVector2t<TReal>( f*v.x, f*v.y);
 338.181 +}
 338.182 +
 338.183 +// ------------------------------------------------------------------------------------------------
 338.184 +// and the other way around
 338.185 +template <typename TReal>
 338.186 +inline aiVector2t<TReal> operator * ( const aiVector2t<TReal>& v, TReal f)
 338.187 +{
 338.188 +	return aiVector2t<TReal>( f*v.x, f*v.y);
 338.189 +}
 338.190 +
 338.191 +// ------------------------------------------------------------------------------------------------
 338.192 +// scalar division
 338.193 +template <typename TReal>
 338.194 +inline aiVector2t<TReal> operator / ( const aiVector2t<TReal>& v, TReal f)
 338.195 +{
 338.196 +
 338.197 +	return v * (1/f);
 338.198 +}
 338.199 +
 338.200 +// ------------------------------------------------------------------------------------------------
 338.201 +// vector division
 338.202 +template <typename TReal>
 338.203 +inline aiVector2t<TReal> operator / ( const aiVector2t<TReal>& v, const aiVector2t<TReal>& v2)
 338.204 +{
 338.205 +	return aiVector2t<TReal>(v.x / v2.x,v.y / v2.y);
 338.206 +}
 338.207 +
 338.208 +// ------------------------------------------------------------------------------------------------
 338.209 +// vector negation
 338.210 +template <typename TReal>
 338.211 +inline aiVector2t<TReal> operator - ( const aiVector2t<TReal>& v)
 338.212 +{
 338.213 +	return aiVector2t<TReal>( -v.x, -v.y);
 338.214 +}
 338.215 +
 338.216 +#endif 
 338.217 +#endif
   339.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   339.2 +++ b/libs/assimp/assimp/vector3.h	Sat Feb 01 19:58:19 2014 +0200
   339.3 @@ -0,0 +1,143 @@
   339.4 +/*
   339.5 +---------------------------------------------------------------------------
   339.6 +Open Asset Import Library (assimp)
   339.7 +---------------------------------------------------------------------------
   339.8 +
   339.9 +Copyright (c) 2006-2012, assimp team
  339.10 +
  339.11 +All rights reserved.
  339.12 +
  339.13 +Redistribution and use of this software in source and binary forms, 
  339.14 +with or without modification, are permitted provided that the following 
  339.15 +conditions are met:
  339.16 +
  339.17 +* Redistributions of source code must retain the above
  339.18 +  copyright notice, this list of conditions and the
  339.19 +  following disclaimer.
  339.20 +
  339.21 +* Redistributions in binary form must reproduce the above
  339.22 +  copyright notice, this list of conditions and the
  339.23 +  following disclaimer in the documentation and/or other
  339.24 +  materials provided with the distribution.
  339.25 +
  339.26 +* Neither the name of the assimp team, nor the names of its
  339.27 +  contributors may be used to endorse or promote products
  339.28 +  derived from this software without specific prior
  339.29 +  written permission of the assimp team.
  339.30 +
  339.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  339.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  339.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  339.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  339.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  339.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  339.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  339.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  339.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  339.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  339.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  339.42 +---------------------------------------------------------------------------
  339.43 +*/
  339.44 +/** @file aiVector3D.h
  339.45 + *  @brief 3D vector structure, including operators when compiling in C++
  339.46 + */
  339.47 +#ifndef AI_VECTOR3D_H_INC
  339.48 +#define AI_VECTOR3D_H_INC
  339.49 +
  339.50 +#include <math.h>
  339.51 +
  339.52 +
  339.53 +#include "./Compiler/pushpack1.h"
  339.54 +
  339.55 +#ifdef __cplusplus
  339.56 +
  339.57 +template<typename TReal> class aiMatrix3x3t;
  339.58 +template<typename TReal> class aiMatrix4x4t;
  339.59 +
  339.60 +// ---------------------------------------------------------------------------
  339.61 +/** Represents a three-dimensional vector. */
  339.62 +template <typename TReal>
  339.63 +class aiVector3t 
  339.64 +{
  339.65 +public:
  339.66 +
  339.67 +	aiVector3t () : x(), y(), z() {}
  339.68 +	aiVector3t (TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
  339.69 +	explicit aiVector3t (TReal _xyz) : x(_xyz), y(_xyz), z(_xyz) {}
  339.70 +	aiVector3t (const aiVector3t& o) : x(o.x), y(o.y), z(o.z) {}
  339.71 +
  339.72 +public:
  339.73 +
  339.74 +	// combined operators
  339.75 +	const aiVector3t& operator += (const aiVector3t& o);
  339.76 +	const aiVector3t& operator -= (const aiVector3t& o);
  339.77 +	const aiVector3t& operator *= (TReal f);
  339.78 +	const aiVector3t& operator /= (TReal f);
  339.79 +
  339.80 +	// transform vector by matrix
  339.81 +	aiVector3t& operator *= (const aiMatrix3x3t<TReal>& mat);
  339.82 +	aiVector3t& operator *= (const aiMatrix4x4t<TReal>& mat);
  339.83 +
  339.84 +	// access a single element
  339.85 +	TReal operator[](unsigned int i) const;
  339.86 +	TReal& operator[](unsigned int i);
  339.87 +
  339.88 +	// comparison
  339.89 +	bool operator== (const aiVector3t& other) const;
  339.90 +	bool operator!= (const aiVector3t& other) const;
  339.91 +
  339.92 +	template <typename TOther>
  339.93 +	operator aiVector3t<TOther> () const;
  339.94 +
  339.95 +public:
  339.96 +
  339.97 +	/** @brief Set the components of a vector
  339.98 +	 *  @param pX X component
  339.99 +	 *  @param pY Y component
 339.100 +	 *  @param pZ Z component  */
 339.101 +	void Set( TReal pX, TReal pY, TReal pZ);
 339.102 +
 339.103 +	/** @brief Get the squared length of the vector
 339.104 +	 *  @return Square length */
 339.105 +	TReal SquareLength() const;
 339.106 +
 339.107 +
 339.108 +	/** @brief Get the length of the vector
 339.109 +	 *  @return length */
 339.110 +	TReal Length() const;
 339.111 +
 339.112 +
 339.113 +	/** @brief Normalize the vector */
 339.114 +	aiVector3t& Normalize();
 339.115 +
 339.116 +	
 339.117 +	/** @brief Componentwise multiplication of two vectors
 339.118 +	 *  
 339.119 +	 *  Note that vec*vec yields the dot product.
 339.120 +	 *  @param o Second factor */
 339.121 +	const aiVector3t SymMul(const aiVector3t& o);
 339.122 +
 339.123 +	TReal x, y, z;	
 339.124 +} PACK_STRUCT;
 339.125 +
 339.126 +
 339.127 +typedef aiVector3t<float> aiVector3D;
 339.128 +
 339.129 +#else
 339.130 +
 339.131 +struct aiVector3D {
 339.132 +
 339.133 +	float x,y,z;
 339.134 +} PACK_STRUCT;
 339.135 +
 339.136 +#endif // __cplusplus
 339.137 +
 339.138 +#include "./Compiler/poppack1.h"
 339.139 +
 339.140 +#ifdef __cplusplus
 339.141 +
 339.142 +
 339.143 +
 339.144 +#endif // __cplusplus
 339.145 +
 339.146 +#endif // AI_VECTOR3D_H_INC
   340.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   340.2 +++ b/libs/assimp/assimp/vector3.inl	Sat Feb 01 19:58:19 2014 +0200
   340.3 @@ -0,0 +1,212 @@
   340.4 +/*
   340.5 +---------------------------------------------------------------------------
   340.6 +Open Asset Import Library (assimp)
   340.7 +---------------------------------------------------------------------------
   340.8 +
   340.9 +Copyright (c) 2006-2012, assimp team
  340.10 +
  340.11 +All rights reserved.
  340.12 +
  340.13 +Redistribution and use of this software in source and binary forms, 
  340.14 +with or without modification, are permitted provided that the following 
  340.15 +conditions are met:
  340.16 +
  340.17 +* Redistributions of source code must retain the above
  340.18 +  copyright notice, this list of conditions and the
  340.19 +  following disclaimer.
  340.20 +
  340.21 +* Redistributions in binary form must reproduce the above
  340.22 +  copyright notice, this list of conditions and the
  340.23 +  following disclaimer in the documentation and/or other
  340.24 +  materials provided with the distribution.
  340.25 +
  340.26 +* Neither the name of the assimp team, nor the names of its
  340.27 +  contributors may be used to endorse or promote products
  340.28 +  derived from this software without specific prior
  340.29 +  written permission of the assimp team.
  340.30 +
  340.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  340.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  340.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  340.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  340.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  340.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  340.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  340.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  340.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  340.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  340.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  340.42 +---------------------------------------------------------------------------
  340.43 +*/
  340.44 +
  340.45 +/** @file  aiVector3D.inl
  340.46 + *  @brief Inline implementation of aiVector3t<TReal> operators
  340.47 + */
  340.48 +#ifndef AI_VECTOR3D_INL_INC
  340.49 +#define AI_VECTOR3D_INL_INC
  340.50 +
  340.51 +#ifdef __cplusplus
  340.52 +#include "vector3.h"
  340.53 +
  340.54 +// ------------------------------------------------------------------------------------------------
  340.55 +/** Transformation of a vector by a 3x3 matrix */
  340.56 +template <typename TReal>
  340.57 +inline aiVector3t<TReal> operator * (const aiMatrix3x3t<TReal>& pMatrix, const aiVector3t<TReal>& pVector)
  340.58 +{
  340.59 +	aiVector3t<TReal> res;
  340.60 +	res.x = pMatrix.a1 * pVector.x + pMatrix.a2 * pVector.y + pMatrix.a3 * pVector.z;
  340.61 +	res.y = pMatrix.b1 * pVector.x + pMatrix.b2 * pVector.y + pMatrix.b3 * pVector.z;
  340.62 +	res.z = pMatrix.c1 * pVector.x + pMatrix.c2 * pVector.y + pMatrix.c3 * pVector.z;
  340.63 +	return res;
  340.64 +}
  340.65 +
  340.66 +// ------------------------------------------------------------------------------------------------
  340.67 +/** Transformation of a vector by a 4x4 matrix */
  340.68 +template <typename TReal>
  340.69 +inline aiVector3t<TReal> operator * (const aiMatrix4x4t<TReal>& pMatrix, const aiVector3t<TReal>& pVector)
  340.70 +{
  340.71 +	aiVector3t<TReal> res;
  340.72 +	res.x = pMatrix.a1 * pVector.x + pMatrix.a2 * pVector.y + pMatrix.a3 * pVector.z + pMatrix.a4;
  340.73 +	res.y = pMatrix.b1 * pVector.x + pMatrix.b2 * pVector.y + pMatrix.b3 * pVector.z + pMatrix.b4;
  340.74 +	res.z = pMatrix.c1 * pVector.x + pMatrix.c2 * pVector.y + pMatrix.c3 * pVector.z + pMatrix.c4;
  340.75 +	return res;
  340.76 +}
  340.77 +// ------------------------------------------------------------------------------------------------
  340.78 +template <typename TReal>
  340.79 +template <typename TOther>
  340.80 +aiVector3t<TReal>::operator aiVector3t<TOther> () const {
  340.81 +	return aiVector3t<TOther>(static_cast<TOther>(x),static_cast<TOther>(y),static_cast<TOther>(z));
  340.82 +}
  340.83 +// ------------------------------------------------------------------------------------------------
  340.84 +template <typename TReal>
  340.85 +AI_FORCE_INLINE void aiVector3t<TReal>::Set( TReal pX, TReal pY, TReal pZ) { 
  340.86 +	x = pX; y = pY; z = pZ; 
  340.87 +}
  340.88 +// ------------------------------------------------------------------------------------------------
  340.89 +template <typename TReal>
  340.90 +AI_FORCE_INLINE TReal aiVector3t<TReal>::SquareLength() const {
  340.91 +	return x*x + y*y + z*z; 
  340.92 +}
  340.93 +// ------------------------------------------------------------------------------------------------
  340.94 +template <typename TReal>
  340.95 +AI_FORCE_INLINE TReal aiVector3t<TReal>::Length() const {
  340.96 +	return sqrt( SquareLength()); 
  340.97 +}
  340.98 +// ------------------------------------------------------------------------------------------------
  340.99 +template <typename TReal>
 340.100 +AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::Normalize() { 
 340.101 +	*this /= Length(); return *this;
 340.102 +}
 340.103 +// ------------------------------------------------------------------------------------------------
 340.104 +template <typename TReal>
 340.105 +AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator += (const aiVector3t<TReal>& o) {
 340.106 +	x += o.x; y += o.y; z += o.z; return *this; 
 340.107 +}
 340.108 +// ------------------------------------------------------------------------------------------------
 340.109 +template <typename TReal>
 340.110 +AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator -= (const aiVector3t<TReal>& o) {
 340.111 +	x -= o.x; y -= o.y; z -= o.z; return *this;
 340.112 +}
 340.113 +// ------------------------------------------------------------------------------------------------
 340.114 +template <typename TReal>
 340.115 +AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator *= (TReal f) {
 340.116 +	x *= f; y *= f; z *= f; return *this; 
 340.117 +}
 340.118 +// ------------------------------------------------------------------------------------------------
 340.119 +template <typename TReal>
 340.120 +AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator /= (TReal f) {
 340.121 +	x /= f; y /= f; z /= f; return *this; 
 340.122 +}
 340.123 +// ------------------------------------------------------------------------------------------------
 340.124 +template <typename TReal>
 340.125 +AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& mat){
 340.126 +	return(*this =  mat * (*this));
 340.127 +}
 340.128 +// ------------------------------------------------------------------------------------------------
 340.129 +template <typename TReal>
 340.130 +AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::operator *= (const aiMatrix4x4t<TReal>& mat){
 340.131 +	return(*this = mat * (*this));
 340.132 +}
 340.133 +// ------------------------------------------------------------------------------------------------
 340.134 +template <typename TReal>
 340.135 +AI_FORCE_INLINE TReal aiVector3t<TReal>::operator[](unsigned int i) const {
 340.136 +	return *(&x + i);
 340.137 +}
 340.138 +// ------------------------------------------------------------------------------------------------
 340.139 +template <typename TReal>
 340.140 +AI_FORCE_INLINE TReal& aiVector3t<TReal>::operator[](unsigned int i) {
 340.141 +	return *(&x + i);
 340.142 +}
 340.143 +// ------------------------------------------------------------------------------------------------
 340.144 +template <typename TReal>
 340.145 +AI_FORCE_INLINE bool aiVector3t<TReal>::operator== (const aiVector3t<TReal>& other) const {
 340.146 +	return x == other.x && y == other.y && z == other.z;
 340.147 +}
 340.148 +// ------------------------------------------------------------------------------------------------
 340.149 +template <typename TReal>
 340.150 +AI_FORCE_INLINE bool aiVector3t<TReal>::operator!= (const aiVector3t<TReal>& other) const {
 340.151 +	return x != other.x || y != other.y || z != other.z;
 340.152 +}
 340.153 +// ------------------------------------------------------------------------------------------------
 340.154 +template <typename TReal>
 340.155 +AI_FORCE_INLINE const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) {
 340.156 +	return aiVector3t<TReal>(x*o.x,y*o.y,z*o.z);
 340.157 +}
 340.158 +// ------------------------------------------------------------------------------------------------
 340.159 +// symmetric addition
 340.160 +template <typename TReal>
 340.161 +AI_FORCE_INLINE aiVector3t<TReal> operator + (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2)	{
 340.162 +	return aiVector3t<TReal>( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
 340.163 +}
 340.164 +// ------------------------------------------------------------------------------------------------
 340.165 +// symmetric subtraction
 340.166 +template <typename TReal>
 340.167 +AI_FORCE_INLINE aiVector3t<TReal> operator - (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2)	{
 340.168 +	return aiVector3t<TReal>( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
 340.169 +}
 340.170 +// ------------------------------------------------------------------------------------------------
 340.171 +// scalar product
 340.172 +template <typename TReal>
 340.173 +AI_FORCE_INLINE TReal operator * (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2)	{
 340.174 +	return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
 340.175 +}
 340.176 +// ------------------------------------------------------------------------------------------------
 340.177 +// scalar multiplication
 340.178 +template <typename TReal>
 340.179 +AI_FORCE_INLINE aiVector3t<TReal> operator * ( TReal f, const aiVector3t<TReal>& v)	{
 340.180 +	return aiVector3t<TReal>( f*v.x, f*v.y, f*v.z);
 340.181 +}
 340.182 +// ------------------------------------------------------------------------------------------------
 340.183 +// and the other way around
 340.184 +template <typename TReal>
 340.185 +AI_FORCE_INLINE  aiVector3t<TReal> operator * ( const aiVector3t<TReal>& v, TReal f)	{
 340.186 +	return aiVector3t<TReal>( f*v.x, f*v.y, f*v.z);
 340.187 +}
 340.188 +// ------------------------------------------------------------------------------------------------
 340.189 +// scalar division
 340.190 +template <typename TReal>
 340.191 +AI_FORCE_INLINE  aiVector3t<TReal> operator / ( const aiVector3t<TReal>& v, TReal f)	{
 340.192 +	return v * (1/f);
 340.193 +}
 340.194 +// ------------------------------------------------------------------------------------------------
 340.195 +// vector division
 340.196 +template <typename TReal>
 340.197 +AI_FORCE_INLINE  aiVector3t<TReal> operator / ( const aiVector3t<TReal>& v, const aiVector3t<TReal>& v2)	{
 340.198 +	return aiVector3t<TReal>(v.x / v2.x,v.y / v2.y,v.z / v2.z);
 340.199 +}
 340.200 +// ------------------------------------------------------------------------------------------------
 340.201 +// cross product
 340.202 +template <typename TReal>
 340.203 +AI_FORCE_INLINE  aiVector3t<TReal> operator ^ ( const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2)	{
 340.204 +	return aiVector3t<TReal>( v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
 340.205 +}
 340.206 +// ------------------------------------------------------------------------------------------------
 340.207 +// vector negation
 340.208 +template <typename TReal>
 340.209 +AI_FORCE_INLINE  aiVector3t<TReal> operator - ( const aiVector3t<TReal>& v)	{
 340.210 +	return aiVector3t<TReal>( -v.x, -v.y, -v.z);
 340.211 +}
 340.212 +
 340.213 +
 340.214 +#endif // __cplusplus
 340.215 +#endif // AI_VECTOR3D_INL_INC
   341.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   341.2 +++ b/libs/assimp/assimp/version.h	Sat Feb 01 19:58:19 2014 +0200
   341.3 @@ -0,0 +1,104 @@
   341.4 +/*
   341.5 +---------------------------------------------------------------------------
   341.6 +Open Asset Import Library (assimp)
   341.7 +---------------------------------------------------------------------------
   341.8 +
   341.9 +Copyright (c) 2006-2012, assimp team
  341.10 +
  341.11 +All rights reserved.
  341.12 +
  341.13 +Redistribution and use of this software in source and binary forms, 
  341.14 +with or without modification, are permitted provided that the following 
  341.15 +conditions are met:
  341.16 +
  341.17 +* Redistributions of source code must retain the above
  341.18 +  copyright notice, this list of conditions and the
  341.19 +  following disclaimer.
  341.20 +
  341.21 +* Redistributions in binary form must reproduce the above
  341.22 +  copyright notice, this list of conditions and the
  341.23 +  following disclaimer in the documentation and/or other
  341.24 +  materials provided with the distribution.
  341.25 +
  341.26 +* Neither the name of the assimp team, nor the names of its
  341.27 +  contributors may be used to endorse or promote products
  341.28 +  derived from this software without specific prior
  341.29 +  written permission of the assimp team.
  341.30 +
  341.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  341.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  341.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  341.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  341.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  341.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  341.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  341.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  341.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  341.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  341.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  341.42 +---------------------------------------------------------------------------
  341.43 +*/
  341.44 +
  341.45 +/** @file  aiVersion.h
  341.46 + *  @brief Functions to query the version of the Assimp runtime, check
  341.47 + *    compile flags, ...
  341.48 + */
  341.49 +#ifndef INCLUDED_AI_VERSION_H
  341.50 +#define INCLUDED_AI_VERSION_H
  341.51 +
  341.52 +#ifdef __cplusplus
  341.53 +extern "C" {
  341.54 +#endif
  341.55 +
  341.56 +// ---------------------------------------------------------------------------
  341.57 +/** @brief Returns a string with legal copyright and licensing information 
  341.58 + *  about Assimp. The string may include multiple lines.
  341.59 + *  @return Pointer to static string.
  341.60 + */
  341.61 +ASSIMP_API const char*  aiGetLegalString  (void);
  341.62 +
  341.63 +// ---------------------------------------------------------------------------
  341.64 +/** @brief Returns the current minor version number of Assimp.
  341.65 + *  @return Minor version of the Assimp runtime the application was
  341.66 + *    linked/built against
  341.67 + */
  341.68 +ASSIMP_API unsigned int aiGetVersionMinor (void);
  341.69 +
  341.70 +// ---------------------------------------------------------------------------
  341.71 +/** @brief Returns the current major version number of Assimp.
  341.72 + *  @return Major version of the Assimp runtime the application was
  341.73 + *    linked/built against
  341.74 + */
  341.75 +ASSIMP_API unsigned int aiGetVersionMajor (void);
  341.76 +
  341.77 +// ---------------------------------------------------------------------------
  341.78 +/** @brief Returns the repository revision of the Assimp runtime.
  341.79 + *  @return SVN Repository revision number of the Assimp runtime the 
  341.80 + *    application was linked/built against
  341.81 + */
  341.82 +ASSIMP_API unsigned int aiGetVersionRevision (void);
  341.83 +
  341.84 +
  341.85 +//! Assimp was compiled as a shared object (Windows: DLL)
  341.86 +#define ASSIMP_CFLAGS_SHARED  0x1 
  341.87 +//! Assimp was compiled against STLport
  341.88 +#define ASSIMP_CFLAGS_STLPORT 0x2
  341.89 +//! Assimp was compiled as a debug build
  341.90 +#define ASSIMP_CFLAGS_DEBUG   0x4
  341.91 +
  341.92 +//! Assimp was compiled with ASSIMP_BUILD_BOOST_WORKAROUND defined
  341.93 +#define ASSIMP_CFLAGS_NOBOOST           0x8
  341.94 +//! Assimp was compiled with ASSIMP_BUILD_SINGLETHREADED defined
  341.95 +#define ASSIMP_CFLAGS_SINGLETHREADED    0x10
  341.96 +
  341.97 +// ---------------------------------------------------------------------------
  341.98 +/** @brief Returns assimp's compile flags
  341.99 + *  @return Any bitwise combination of the ASSIMP_CFLAGS_xxx constants.
 341.100 + */
 341.101 +ASSIMP_API unsigned int aiGetCompileFlags (void);
 341.102 +
 341.103 +#ifdef __cplusplus
 341.104 +} // end extern "C"
 341.105 +#endif
 341.106 +
 341.107 +#endif // !! #ifndef INCLUDED_AI_VERSION_H
   342.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   342.2 +++ b/libs/assimp/boost/LICENSE_1_0.txt	Sat Feb 01 19:58:19 2014 +0200
   342.3 @@ -0,0 +1,23 @@
   342.4 +Boost Software License - Version 1.0 - August 17th, 2003
   342.5 +
   342.6 +Permission is hereby granted, free of charge, to any person or organization
   342.7 +obtaining a copy of the software and accompanying documentation covered by
   342.8 +this license (the "Software") to use, reproduce, display, distribute,
   342.9 +execute, and transmit the Software, and to prepare derivative works of the
  342.10 +Software, and to permit third-parties to whom the Software is furnished to
  342.11 +do so, all subject to the following:
  342.12 +
  342.13 +The copyright notices in the Software and this entire statement, including
  342.14 +the above license grant, this restriction and the following disclaimer,
  342.15 +must be included in all copies of the Software, in whole or in part, and
  342.16 +all derivative works of the Software, unless such copies or derivative
  342.17 +works are solely in the form of machine-executable object code generated by
  342.18 +a source language processor.
  342.19 +
  342.20 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  342.21 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  342.22 +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  342.23 +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  342.24 +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  342.25 +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  342.26 +DEALINGS IN THE SOFTWARE.
  342.27 \ No newline at end of file
   343.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   343.2 +++ b/libs/assimp/boost/foreach.hpp	Sat Feb 01 19:58:19 2014 +0200
   343.3 @@ -0,0 +1,99 @@
   343.4 +
   343.5 +#ifndef BOOST_FOREACH
   343.6 +
   343.7 +///////////////////////////////////////////////////////////////////////////////
   343.8 +// A stripped down version of FOREACH for
   343.9 +// illustration purposes. NOT FOR GENERAL USE.
  343.10 +// For a complete implementation, see BOOST_FOREACH at
  343.11 +// http://boost-sandbox.sourceforge.net/vault/index.php?directory=eric_niebler
  343.12 +//
  343.13 +// Copyright 2004 Eric Niebler.
  343.14 +// Distributed under the Boost Software License, Version 1.0. (See
  343.15 +// accompanying file LICENSE_1_0.txt or copy at
  343.16 +// http://www.boost.org/LICENSE_1_0.txt)
  343.17 +//
  343.18 +// Adapted to Assimp November 29th, 2008 (Alexander Gessler).
  343.19 +// Added code to handle both const and non-const iterators, simplified some
  343.20 +// parts.
  343.21 +///////////////////////////////////////////////////////////////////////////////
  343.22 +
  343.23 +namespace boost {
  343.24 +namespace foreach_detail {
  343.25 +
  343.26 +///////////////////////////////////////////////////////////////////////////////
  343.27 +// auto_any
  343.28 +
  343.29 +struct auto_any_base
  343.30 +{
  343.31 +    operator bool() const { return false; }
  343.32 +};
  343.33 +
  343.34 +template<typename T>
  343.35 +struct auto_any : auto_any_base
  343.36 +{
  343.37 +    auto_any(T const& t) : item(t) {}
  343.38 +    mutable T item;
  343.39 +};
  343.40 +
  343.41 +template<typename T>
  343.42 +T& auto_any_cast(auto_any_base const& any)
  343.43 +{
  343.44 +    return static_cast<auto_any<T> const&>(any).item;
  343.45 +}
  343.46 +
  343.47 +///////////////////////////////////////////////////////////////////////////////
  343.48 +// FOREACH helper function
  343.49 +
  343.50 +template<typename T>
  343.51 +auto_any<typename T::const_iterator> begin(T const& t)
  343.52 +{
  343.53 +    return t.begin();
  343.54 +}
  343.55 +
  343.56 +template<typename T>
  343.57 +auto_any<typename T::const_iterator> end(T const& t)
  343.58 +{
  343.59 +    return t.end();
  343.60 +}
  343.61 +
  343.62 +// iterator
  343.63 +template<typename T>
  343.64 +bool done(auto_any_base const& cur, auto_any_base const& end, T&)
  343.65 +{
  343.66 +    typedef typename T::iterator iter_type;
  343.67 +    return auto_any_cast<iter_type>(cur) == auto_any_cast<iter_type>(end);
  343.68 +}
  343.69 +
  343.70 +template<typename T>
  343.71 +void next(auto_any_base const& cur, T&)
  343.72 +{
  343.73 +    ++auto_any_cast<typename T::iterator>(cur);
  343.74 +}
  343.75 +
  343.76 +template<typename T>
  343.77 +typename T::reference deref(auto_any_base const& cur, T&)
  343.78 +{
  343.79 +    return *auto_any_cast<typename T::iterator>(cur);
  343.80 +}
  343.81 +
  343.82 +template<typename T>
  343.83 +typename T::const_reference deref(auto_any_base const& cur, const T&)
  343.84 +{
  343.85 +    return *auto_any_cast<typename T::iterator>(cur);
  343.86 +}
  343.87 +
  343.88 +} // end foreach_detail
  343.89 +
  343.90 +///////////////////////////////////////////////////////////////////////////////
  343.91 +// FOREACH
  343.92 +
  343.93 +#define BOOST_FOREACH(item, container)                      \
  343.94 +	if(boost::foreach_detail::auto_any_base const& foreach_magic_b = boost::foreach_detail::begin(container)) {} else       \
  343.95 +    if(boost::foreach_detail::auto_any_base const& foreach_magic_e = boost::foreach_detail::end(container))   {} else       \
  343.96 +    for(;!boost::foreach_detail::done(foreach_magic_b,foreach_magic_e,container);  boost::foreach_detail::next(foreach_magic_b,container))   \
  343.97 +        if (bool ugly_and_unique_break = false) {} else							\
  343.98 +        for(item = boost::foreach_detail::deref(foreach_magic_b,container); !ugly_and_unique_break; ugly_and_unique_break = true)
  343.99 +
 343.100 +} // end boost
 343.101 +
 343.102 +#endif
   344.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   344.2 +++ b/libs/assimp/boost/format.hpp	Sat Feb 01 19:58:19 2014 +0200
   344.3 @@ -0,0 +1,81 @@
   344.4 +
   344.5 +
   344.6 +
   344.7 +/* DEPRECATED! - use code/TinyFormatter.h instead.
   344.8 + *
   344.9 + *
  344.10 + * */
  344.11 +
  344.12 +#ifndef AI_BOOST_FORMAT_DUMMY_INCLUDED
  344.13 +#define AI_BOOST_FORMAT_DUMMY_INCLUDED
  344.14 +
  344.15 +#if (!defined BOOST_FORMAT_HPP) || (defined ASSIMP_FORCE_NOBOOST)
  344.16 +
  344.17 +#include <string>
  344.18 +#include <vector>
  344.19 +
  344.20 +namespace boost
  344.21 +{
  344.22 +
  344.23 +
  344.24 +	class format
  344.25 +	{
  344.26 +	public:
  344.27 +		format (const std::string& _d)
  344.28 +			: d(_d)
  344.29 +		{
  344.30 +		}
  344.31 +
  344.32 +		template <typename T>
  344.33 +		format& operator % (T in) 
  344.34 +		{
  344.35 +			// XXX add replacement for boost::lexical_cast?
  344.36 +			
  344.37 +			std::ostringstream ss;
  344.38 +			ss << in; // note: ss cannot be an rvalue, or  the global operator << (const char*) is not called for T == const char*.
  344.39 +			chunks.push_back( ss.str());
  344.40 +			return *this;
  344.41 +		}
  344.42 +
  344.43 +
  344.44 +		operator std::string () const {
  344.45 +			std::string res; // pray for NRVO to kick in
  344.46 +
  344.47 +			size_t start = 0, last = 0;
  344.48 +
  344.49 +			std::vector<std::string>::const_iterator chunkin = chunks.begin();
  344.50 +
  344.51 +			for ( start = d.find('%');start != std::string::npos;  start = d.find('%',last)) {
  344.52 +				res += d.substr(last,start-last);
  344.53 +				last = start+2;
  344.54 +				if (d[start+1] == '%') {
  344.55 +					res += "%";
  344.56 +					continue;
  344.57 +				}
  344.58 +
  344.59 +				if (chunkin == chunks.end()) {
  344.60 +					break;
  344.61 +				}
  344.62 +
  344.63 +				res += *chunkin++;
  344.64 +			}
  344.65 +			res += d.substr(last);
  344.66 +			return res;
  344.67 +		}
  344.68 +
  344.69 +	private:
  344.70 +		std::string d;
  344.71 +		std::vector<std::string> chunks;
  344.72 +	};
  344.73 +
  344.74 +	inline std::string str(const std::string& s) {
  344.75 +		return s;
  344.76 +	} 
  344.77 +}
  344.78 +
  344.79 +
  344.80 +#else
  344.81 +#	error "format.h was already included"
  344.82 +#endif //
  344.83 +#endif // !! AI_BOOST_FORMAT_DUMMY_INCLUDED
  344.84 +
   345.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   345.2 +++ b/libs/assimp/boost/lexical_cast.hpp	Sat Feb 01 19:58:19 2014 +0200
   345.3 @@ -0,0 +1,24 @@
   345.4 +/// A quick replacement for boost::lexical_cast for all the Boost haters out there
   345.5 +
   345.6 +#ifndef __AI_BOOST_WORKAROUND_LEXICAL_CAST
   345.7 +#define __AI_BOOST_WORKAROUND_LEXICAL_CAST
   345.8 +
   345.9 +namespace boost
  345.10 +{
  345.11 +
  345.12 +	/// A quick replacement for boost::lexical_cast - should work for all types a stringstream can handle
  345.13 +	template <typename TargetType, typename SourceType>
  345.14 +	TargetType lexical_cast( const SourceType& source)
  345.15 +	{
  345.16 +		std::stringstream stream;
  345.17 +		TargetType result;
  345.18 +
  345.19 +		stream << source;
  345.20 +		stream >> result;
  345.21 +		return result;
  345.22 +	}
  345.23 +
  345.24 +} // namespace boost
  345.25 +
  345.26 +#endif // __AI_BOOST_WORKAROUND_LEXICAL_CAST
  345.27 +
   346.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   346.2 +++ b/libs/assimp/boost/make_shared.hpp	Sat Feb 01 19:58:19 2014 +0200
   346.3 @@ -0,0 +1,57 @@
   346.4 +
   346.5 +// please note that this replacement implementation does not
   346.6 +// provide the performance benefit of the original, which
   346.7 +// makes only one allocation as opposed to two allocations
   346.8 +// (smart pointer counter and payload) which are usually
   346.9 +// required if object and smart pointer are constructed
  346.10 +// independently.
  346.11 +
  346.12 +#ifndef INCLUDED_AI_BOOST_MAKE_SHARED
  346.13 +#define INCLUDED_AI_BOOST_MAKE_SHARED
  346.14 +
  346.15 +
  346.16 +namespace boost {
  346.17 +
  346.18 +	template <typename T>
  346.19 +	shared_ptr<T> make_shared() {
  346.20 +		return shared_ptr<T>(new T());
  346.21 +	}
  346.22 +
  346.23 +	template <typename T, typename T0>
  346.24 +	shared_ptr<T> make_shared(const T0& t0) {
  346.25 +		return shared_ptr<T>(new T(t0));
  346.26 +	}
  346.27 +
  346.28 +	template <typename T, typename T0,typename T1>
  346.29 +	shared_ptr<T> make_shared(const T0& t0, const T1& t1) {
  346.30 +		return shared_ptr<T>(new T(t0,t1));
  346.31 +	}
  346.32 +
  346.33 +	template <typename T, typename T0,typename T1,typename T2>
  346.34 +	shared_ptr<T> make_shared(const T0& t0, const T1& t1, const T2& t2) {
  346.35 +		return shared_ptr<T>(new T(t0,t1,t2));
  346.36 +	}
  346.37 +
  346.38 +	template <typename T, typename T0,typename T1,typename T2,typename T3>
  346.39 +	shared_ptr<T> make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3) {
  346.40 +		return shared_ptr<T>(new T(t0,t1,t2,t3));
  346.41 +	}
  346.42 +
  346.43 +	template <typename T, typename T0,typename T1,typename T2,typename T3, typename T4>
  346.44 +	shared_ptr<T> make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4) {
  346.45 +		return shared_ptr<T>(new T(t0,t1,t2,t3,t4));
  346.46 +	}
  346.47 +
  346.48 +	template <typename T, typename T0,typename T1,typename T2,typename T3, typename T4, typename T5>
  346.49 +	shared_ptr<T> make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) {
  346.50 +		return shared_ptr<T>(new T(t0,t1,t2,t3,t4,t5));
  346.51 +	}
  346.52 +
  346.53 +	template <typename T, typename T0,typename T1,typename T2,typename T3, typename T4, typename T5, typename T6>
  346.54 +	shared_ptr<T> make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6) {
  346.55 +		return shared_ptr<T>(new T(t0,t1,t2,t3,t4,t5,t6));
  346.56 +	}
  346.57 +}
  346.58 +
  346.59 +
  346.60 +#endif 
   347.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   347.2 +++ b/libs/assimp/boost/math/common_factor_rt.hpp	Sat Feb 01 19:58:19 2014 +0200
   347.3 @@ -0,0 +1,37 @@
   347.4 +
   347.5 +
   347.6 +#ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP
   347.7 +#define BOOST_MATH_COMMON_FACTOR_RT_HPP
   347.8 +
   347.9 +
  347.10 +namespace boost	{
  347.11 +namespace math	{
  347.12 +
  347.13 +// TODO: use binary GCD for unsigned integers ....
  347.14 +template < typename IntegerType >
  347.15 +IntegerType  gcd( IntegerType a, IntegerType b )
  347.16 +{
  347.17 +	const IntegerType zero = (IntegerType)0;
  347.18 +	while ( true )
  347.19 +	{
  347.20 +		if ( a == zero )
  347.21 +			return b;
  347.22 +		b %= a;
  347.23 +
  347.24 +		if ( b == zero )
  347.25 +			return a;
  347.26 +		a %= b;
  347.27 +	}
  347.28 +}
  347.29 +
  347.30 +template < typename IntegerType >
  347.31 +IntegerType  lcm( IntegerType a, IntegerType b )
  347.32 +{
  347.33 +	const IntegerType t = gcd (a,b);
  347.34 +	if (!t)return t;
  347.35 +	return a / t * b;
  347.36 +}
  347.37 +
  347.38 +}}
  347.39 +
  347.40 +#endif
   348.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   348.2 +++ b/libs/assimp/boost/noncopyable.hpp	Sat Feb 01 19:58:19 2014 +0200
   348.3 @@ -0,0 +1,36 @@
   348.4 +//  Boost noncopyable.hpp header file  --------------------------------------//
   348.5 +
   348.6 +//  (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost
   348.7 +//  Software License, Version 1.0. (See accompanying file
   348.8 +//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
   348.9 +
  348.10 +//  See http://www.boost.org/libs/utility for documentation.
  348.11 +
  348.12 +#ifndef BOOST_NONCOPYABLE_HPP_INCLUDED
  348.13 +#define BOOST_NONCOPYABLE_HPP_INCLUDED
  348.14 +
  348.15 +namespace boost {
  348.16 +
  348.17 +//  Private copy constructor and copy assignment ensure classes derived from
  348.18 +//  class noncopyable cannot be copied.
  348.19 +
  348.20 +//  Contributed by Dave Abrahams
  348.21 +
  348.22 +namespace noncopyable_  // protection from unintended ADL
  348.23 +{
  348.24 +  class noncopyable
  348.25 +  {
  348.26 +   protected:
  348.27 +      noncopyable() {}
  348.28 +      ~noncopyable() {}
  348.29 +   private:  // emphasize the following members are private
  348.30 +      noncopyable( const noncopyable& );
  348.31 +      const noncopyable& operator=( const noncopyable& );
  348.32 +  };
  348.33 +}
  348.34 +
  348.35 +typedef noncopyable_::noncopyable noncopyable;
  348.36 +
  348.37 +} // namespace boost
  348.38 +
  348.39 +#endif  // BOOST_NONCOPYABLE_HPP_INCLUDED
   349.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   349.2 +++ b/libs/assimp/boost/pointer_cast.hpp	Sat Feb 01 19:58:19 2014 +0200
   349.3 @@ -0,0 +1,45 @@
   349.4 +//////////////////////////////////////////////////////////////////////////////
   349.5 +//
   349.6 +// (C) Copyright Ion Gaztanaga 2005. 
   349.7 +// Distributed under the Boost Software License, Version 1.0. 
   349.8 +// (See accompanying file LICENSE_1_0.txt or copy at 
   349.9 +//  http://www.boost.org/LICENSE_1_0.txt)
  349.10 +//
  349.11 +//////////////////////////////////////////////////////////////////////////////
  349.12 +
  349.13 +#ifndef BOOST_POINTER_CAST_HPP
  349.14 +#define BOOST_POINTER_CAST_HPP
  349.15 +
  349.16 +namespace boost { 
  349.17 +
  349.18 +//static_pointer_cast overload for raw pointers
  349.19 +template<class T, class U>
  349.20 +inline T* static_pointer_cast(U *ptr)
  349.21 +{  
  349.22 +   return static_cast<T*>(ptr);
  349.23 +}
  349.24 +
  349.25 +//dynamic_pointer_cast overload for raw pointers
  349.26 +template<class T, class U>
  349.27 +inline T* dynamic_pointer_cast(U *ptr)
  349.28 +{  
  349.29 +   return dynamic_cast<T*>(ptr);
  349.30 +}
  349.31 +
  349.32 +//const_pointer_cast overload for raw pointers
  349.33 +template<class T, class U>
  349.34 +inline T* const_pointer_cast(U *ptr)
  349.35 +{  
  349.36 +   return const_cast<T*>(ptr);
  349.37 +}
  349.38 +
  349.39 +//reinterpret_pointer_cast overload for raw pointers
  349.40 +template<class T, class U>
  349.41 +inline T* reinterpret_pointer_cast(U *ptr)
  349.42 +{  
  349.43 +   return reinterpret_cast<T*>(ptr);
  349.44 +}
  349.45 +
  349.46 +} // namespace boost
  349.47 +
  349.48 +#endif   //BOOST_POINTER_CAST_HPP
   350.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   350.2 +++ b/libs/assimp/boost/scoped_array.hpp	Sat Feb 01 19:58:19 2014 +0200
   350.3 @@ -0,0 +1,79 @@
   350.4 +
   350.5 +#ifndef __AI_BOOST_SCOPED_ARRAY_INCLUDED
   350.6 +#define __AI_BOOST_SCOPED_ARRAY_INCLUDED
   350.7 +
   350.8 +#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
   350.9 +
  350.10 +namespace boost {
  350.11 +
  350.12 +// small replacement for boost::scoped_array
  350.13 +template <class T>
  350.14 +class scoped_array
  350.15 +{
  350.16 +public:
  350.17 +
  350.18 +	// provide a default construtctor
  350.19 +	scoped_array()
  350.20 +		: ptr(0)
  350.21 +	{
  350.22 +	}
  350.23 +
  350.24 +	// construction from an existing heap object of type T
  350.25 +	scoped_array(T* _ptr)
  350.26 +		: ptr(_ptr)
  350.27 +	{
  350.28 +	}
  350.29 +
  350.30 +	// automatic destruction of the wrapped object at the
  350.31 +	// end of our lifetime
  350.32 +	~scoped_array()
  350.33 +	{
  350.34 +		delete[] ptr;
  350.35 +	}
  350.36 +
  350.37 +	inline T* get()
  350.38 +	{
  350.39 +		return ptr;
  350.40 +	}
  350.41 +
  350.42 +	inline T* operator-> ()
  350.43 +	{
  350.44 +		return ptr;
  350.45 +	}
  350.46 +
  350.47 +	inline void reset (T* t = 0)
  350.48 +	{
  350.49 +		delete[] ptr;
  350.50 +		ptr = t;
  350.51 +	}
  350.52 +
  350.53 +	T & operator[](std::ptrdiff_t i) const
  350.54 +	{
  350.55 +		return ptr[i];
  350.56 +	}
  350.57 +
  350.58 +	void swap(scoped_array & b)
  350.59 +	{
  350.60 +		std::swap(ptr, b.ptr);
  350.61 +	}
  350.62 +
  350.63 +private:
  350.64 +
  350.65 +	// encapsulated object pointer
  350.66 +	T* ptr;
  350.67 +
  350.68 +};
  350.69 +
  350.70 +template<class T>
  350.71 +inline void swap(scoped_array<T> & a, scoped_array<T> & b)
  350.72 +{
  350.73 +	a.swap(b);
  350.74 +}
  350.75 +
  350.76 +} // end of namespace boost
  350.77 +
  350.78 +#else
  350.79 +#	error "scoped_array.h was already included"
  350.80 +#endif
  350.81 +#endif // __AI_BOOST_SCOPED_ARRAY_INCLUDED
  350.82 +
   351.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   351.2 +++ b/libs/assimp/boost/scoped_ptr.hpp	Sat Feb 01 19:58:19 2014 +0200
   351.3 @@ -0,0 +1,79 @@
   351.4 +
   351.5 +#ifndef __AI_BOOST_SCOPED_PTR_INCLUDED
   351.6 +#define __AI_BOOST_SCOPED_PTR_INCLUDED
   351.7 +
   351.8 +#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
   351.9 +
  351.10 +namespace boost {
  351.11 +
  351.12 +// small replacement for boost::scoped_ptr
  351.13 +template <class T>
  351.14 +class scoped_ptr
  351.15 +{
  351.16 +public:
  351.17 +
  351.18 +	// provide a default construtctor
  351.19 +	scoped_ptr()
  351.20 +		: ptr(0)
  351.21 +	{
  351.22 +	}
  351.23 +
  351.24 +	// construction from an existing heap object of type T
  351.25 +	scoped_ptr(T* _ptr)
  351.26 +		: ptr(_ptr)
  351.27 +	{
  351.28 +	}
  351.29 +
  351.30 +	// automatic destruction of the wrapped object at the
  351.31 +	// end of our lifetime
  351.32 +	~scoped_ptr()
  351.33 +	{
  351.34 +		delete ptr;
  351.35 +	}
  351.36 +
  351.37 +	inline T* get() const
  351.38 +	{
  351.39 +		return ptr;
  351.40 +	}
  351.41 +
  351.42 +	inline operator T*()
  351.43 +	{
  351.44 +		return ptr;
  351.45 +	}
  351.46 +
  351.47 +	inline T* operator-> ()
  351.48 +	{
  351.49 +		return ptr;
  351.50 +	}
  351.51 +
  351.52 +	inline void reset (T* t = 0)
  351.53 +	{
  351.54 +		delete ptr;
  351.55 +		ptr = t;
  351.56 +	}
  351.57 +
  351.58 +	void swap(scoped_ptr & b)
  351.59 +	{
  351.60 +		std::swap(ptr, b.ptr);
  351.61 +	}
  351.62 +
  351.63 +private:
  351.64 +
  351.65 +	// encapsulated object pointer
  351.66 +	T* ptr;
  351.67 +
  351.68 +};
  351.69 +
  351.70 +template<class T>
  351.71 +inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b)
  351.72 +{
  351.73 +	a.swap(b);
  351.74 +}
  351.75 +
  351.76 +} // end of namespace boost
  351.77 +
  351.78 +#else
  351.79 +#	error "scoped_ptr.h was already included"
  351.80 +#endif
  351.81 +#endif // __AI_BOOST_SCOPED_PTR_INCLUDED
  351.82 +
   352.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   352.2 +++ b/libs/assimp/boost/shared_array.hpp	Sat Feb 01 19:58:19 2014 +0200
   352.3 @@ -0,0 +1,228 @@
   352.4 +
   352.5 +#ifndef INCLUDED_AI_BOOST_SHARED_ARRAY
   352.6 +#define INCLUDED_AI_BOOST_SHARED_ARRAY
   352.7 +
   352.8 +#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
   352.9 +
  352.10 +// ------------------------------
  352.11 +// Internal stub
  352.12 +namespace boost {
  352.13 +	namespace array_detail {
  352.14 +		class controller {
  352.15 +		public:
  352.16 +
  352.17 +			controller()
  352.18 +				: cnt(1)
  352.19 +			{}
  352.20 +		
  352.21 +		public:
  352.22 +
  352.23 +			template <typename T>
  352.24 +			controller* decref(T* pt) {
  352.25 +				if (--cnt <= 0) {
  352.26 +					delete this;
  352.27 +					delete[] pt;
  352.28 +				}
  352.29 +				return NULL;
  352.30 +			}
  352.31 +		
  352.32 +			controller* incref() {
  352.33 +				++cnt;
  352.34 +				return this;
  352.35 +			}
  352.36 +
  352.37 +			long get() const {
  352.38 +				return cnt;
  352.39 +			}
  352.40 +
  352.41 +		private:
  352.42 +			long cnt;
  352.43 +		};
  352.44 +
  352.45 +		struct empty {};
  352.46 +		
  352.47 +		template <typename DEST, typename SRC>
  352.48 +		struct is_convertible_stub {
  352.49 +			
  352.50 +			struct yes {char s[1];};
  352.51 +			struct no  {char s[2];};
  352.52 +
  352.53 +			static yes foo(DEST*);
  352.54 +			static no  foo(...);
  352.55 +
  352.56 +			enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};	
  352.57 +		};
  352.58 +
  352.59 +		template <bool> struct enable_if {};
  352.60 +		template <> struct enable_if<true> {
  352.61 +			typedef empty result;
  352.62 +		};
  352.63 +
  352.64 +		template <typename DEST, typename SRC>
  352.65 +		struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
  352.66 +		};
  352.67 +	}
  352.68 +
  352.69 +// ------------------------------
  352.70 +// Small replacement for boost::shared_array, not threadsafe because no
  352.71 +// atomic reference counter is in use.
  352.72 +// ------------------------------
  352.73 +template <class T>
  352.74 +class shared_array
  352.75 +{
  352.76 +	template <typename TT> friend class shared_array;
  352.77 +
  352.78 +	template<class TT> friend bool operator== (const shared_array<TT>& a, const shared_array<TT>& b);
  352.79 +	template<class TT> friend bool operator!= (const shared_array<TT>& a, const shared_array<TT>& b);
  352.80 +	template<class TT> friend bool operator<  (const shared_array<TT>& a, const shared_array<TT>& b);
  352.81 +
  352.82 +public:
  352.83 +
  352.84 +	typedef T element_type;
  352.85 +
  352.86 +public:
  352.87 +
  352.88 +	// provide a default constructor
  352.89 +	shared_array()
  352.90 +		: ptr()
  352.91 +		, ctr(NULL)
  352.92 +	{
  352.93 +	}
  352.94 +
  352.95 +	// construction from an existing object of type T
  352.96 +	explicit shared_array(T* ptr)
  352.97 +		: ptr(ptr)
  352.98 +		, ctr(ptr ? new array_detail::controller() : NULL)
  352.99 +	{
 352.100 +	}
 352.101 +
 352.102 +	shared_array(const shared_array& r)
 352.103 +		: ptr(r.ptr)
 352.104 +		, ctr(r.ctr ? r.ctr->incref() : NULL)
 352.105 +	{
 352.106 +	}
 352.107 +
 352.108 +	template <typename Y>
 352.109 +	shared_array(const shared_array<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
 352.110 +		: ptr(r.ptr)
 352.111 +		, ctr(r.ctr ? r.ctr->incref() : NULL)
 352.112 +	{
 352.113 +	}
 352.114 +
 352.115 +	// automatic destruction of the wrapped object when all
 352.116 +	// references are freed.
 352.117 +	~shared_array()	{
 352.118 +		if (ctr) {
 352.119 +			ctr = ctr->decref(ptr);
 352.120 +		}
 352.121 +	}
 352.122 +
 352.123 +	shared_array& operator=(const shared_array& r) {
 352.124 +		if (this == &r) {
 352.125 +			return *this;
 352.126 +		}
 352.127 +		if (ctr) {
 352.128 +			ctr->decref(ptr);
 352.129 +		}
 352.130 +		ptr = r.ptr;
 352.131 +		ctr = ptr?r.ctr->incref():NULL;
 352.132 +		return *this;
 352.133 +	}
 352.134 +
 352.135 +	template <typename Y>
 352.136 +	shared_array& operator=(const shared_array<Y>& r) {
 352.137 +		if (this == &r) {
 352.138 +			return *this;
 352.139 +		}
 352.140 +		if (ctr) {
 352.141 +			ctr->decref(ptr);
 352.142 +		}
 352.143 +		ptr = r.ptr;
 352.144 +		ctr = ptr?r.ctr->incref():NULL;
 352.145 +		return *this;
 352.146 +	}
 352.147 +
 352.148 +	// pointer access
 352.149 +	inline operator T*()	{
 352.150 +		return ptr;
 352.151 +	}
 352.152 +
 352.153 +	inline T* operator-> () const	{
 352.154 +		return ptr;
 352.155 +	}
 352.156 +
 352.157 +	// standard semantics
 352.158 +	inline T* get() {
 352.159 +		return ptr;
 352.160 +	}
 352.161 +
 352.162 +	T& operator[] (std::ptrdiff_t index) const {
 352.163 +		return ptr[index];
 352.164 +	}
 352.165 +
 352.166 +	inline const T* get() const	{
 352.167 +		return ptr;
 352.168 +	}
 352.169 +
 352.170 +	inline operator bool () const {
 352.171 +		return ptr != NULL;
 352.172 +	}
 352.173 +
 352.174 +	inline bool unique() const {
 352.175 +		return use_count() == 1;
 352.176 +	}
 352.177 +
 352.178 +	inline long use_count() const {
 352.179 +		return ctr->get();
 352.180 +	}
 352.181 +
 352.182 +	inline void reset (T* t = 0)	{
 352.183 +		if (ctr) {
 352.184 +			ctr->decref(ptr);
 352.185 +		}
 352.186 +		ptr = t;
 352.187 +		ctr = ptr?new array_detail::controller():NULL;
 352.188 +	}
 352.189 +
 352.190 +	void swap(shared_array & b)	{
 352.191 +		std::swap(ptr, b.ptr);
 352.192 +		std::swap(ctr, b.ctr);
 352.193 +	}
 352.194 +
 352.195 +
 352.196 +private:
 352.197 +
 352.198 +	// encapsulated object pointer
 352.199 +	T* ptr;
 352.200 +
 352.201 +	// control block
 352.202 +	array_detail::controller* ctr;
 352.203 +};
 352.204 +
 352.205 +template<class T>
 352.206 +inline void swap(shared_array<T> & a, shared_array<T> & b)
 352.207 +{
 352.208 +	a.swap(b);
 352.209 +}
 352.210 +
 352.211 +template<class T>
 352.212 +bool operator== (const shared_array<T>& a, const shared_array<T>& b) {
 352.213 +	return a.ptr == b.ptr;
 352.214 +}
 352.215 +template<class T>
 352.216 +bool operator!= (const shared_array<T>& a, const shared_array<T>& b) {
 352.217 +	return a.ptr != b.ptr;
 352.218 +}
 352.219 +	
 352.220 +template<class T>
 352.221 +bool operator< (const shared_array<T>& a, const shared_array<T>& b) {
 352.222 +	return a.ptr < b.ptr;
 352.223 +}
 352.224 +
 352.225 +
 352.226 +} // end of namespace boost
 352.227 +
 352.228 +#else
 352.229 +#	error "shared_array.h was already included"
 352.230 +#endif
 352.231 +#endif // INCLUDED_AI_BOOST_SHARED_ARRAY
   353.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   353.2 +++ b/libs/assimp/boost/shared_ptr.hpp	Sat Feb 01 19:58:19 2014 +0200
   353.3 @@ -0,0 +1,257 @@
   353.4 +
   353.5 +#ifndef INCLUDED_AI_BOOST_SHARED_PTR
   353.6 +#define INCLUDED_AI_BOOST_SHARED_PTR
   353.7 +
   353.8 +#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
   353.9 +
  353.10 +// ------------------------------
  353.11 +// Internal stub
  353.12 +namespace boost {
  353.13 +	namespace detail {
  353.14 +		class controller {
  353.15 +		public:
  353.16 +
  353.17 +			controller()
  353.18 +				: cnt(1)
  353.19 +			{}
  353.20 +		
  353.21 +		public:
  353.22 +
  353.23 +			template <typename T>
  353.24 +			controller* decref(T* pt) {
  353.25 +				if (--cnt <= 0) {
  353.26 +					delete this;
  353.27 +					delete pt;
  353.28 +				}
  353.29 +				return NULL;
  353.30 +			}
  353.31 +		
  353.32 +			controller* incref() {
  353.33 +				++cnt;
  353.34 +				return this;
  353.35 +			}
  353.36 +
  353.37 +			long get() const {
  353.38 +				return cnt;
  353.39 +			}
  353.40 +
  353.41 +		private:
  353.42 +			long cnt;
  353.43 +		};
  353.44 +
  353.45 +		struct empty {};
  353.46 +		
  353.47 +		template <typename DEST, typename SRC>
  353.48 +		struct is_convertible_stub {
  353.49 +			
  353.50 +			struct yes {char s[1];};
  353.51 +			struct no  {char s[2];};
  353.52 +
  353.53 +			static yes foo(DEST*);
  353.54 +			static no  foo(...);
  353.55 +
  353.56 +			enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};	
  353.57 +		};
  353.58 +
  353.59 +		template <bool> struct enable_if {};
  353.60 +		template <> struct enable_if<true> {
  353.61 +			typedef empty result;
  353.62 +		};
  353.63 +
  353.64 +		template <typename DEST, typename SRC>
  353.65 +		struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
  353.66 +		};
  353.67 +	}
  353.68 +
  353.69 +// ------------------------------
  353.70 +// Small replacement for boost::shared_ptr, not threadsafe because no
  353.71 +// atomic reference counter is in use.
  353.72 +// ------------------------------
  353.73 +template <class T>
  353.74 +class shared_ptr
  353.75 +{
  353.76 +	template <typename TT> friend class shared_ptr;
  353.77 +
  353.78 +	template<class TT, class U> friend shared_ptr<TT> static_pointer_cast   (shared_ptr<U> ptr);
  353.79 +	template<class TT, class U> friend shared_ptr<TT> dynamic_pointer_cast  (shared_ptr<U> ptr);
  353.80 +	template<class TT, class U> friend shared_ptr<TT> const_pointer_cast    (shared_ptr<U> ptr);
  353.81 +
  353.82 +	template<class TT> friend bool operator== (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
  353.83 +	template<class TT> friend bool operator!= (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
  353.84 +	template<class TT> friend bool operator<  (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
  353.85 +
  353.86 +public:
  353.87 +
  353.88 +	typedef T element_type;
  353.89 +
  353.90 +public:
  353.91 +
  353.92 +	// provide a default constructor
  353.93 +	shared_ptr()
  353.94 +		: ptr()
  353.95 +		, ctr(NULL)
  353.96 +	{
  353.97 +	}
  353.98 +
  353.99 +	// construction from an existing object of type T
 353.100 +	explicit shared_ptr(T* ptr)
 353.101 +		: ptr(ptr)
 353.102 +		, ctr(ptr ? new detail::controller() : NULL)
 353.103 +	{
 353.104 +	}
 353.105 +
 353.106 +	shared_ptr(const shared_ptr& r)
 353.107 +		: ptr(r.ptr)
 353.108 +		, ctr(r.ctr ? r.ctr->incref() : NULL)
 353.109 +	{
 353.110 +	}
 353.111 +
 353.112 +	template <typename Y>
 353.113 +	shared_ptr(const shared_ptr<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
 353.114 +		: ptr(r.ptr)
 353.115 +		, ctr(r.ctr ? r.ctr->incref() : NULL)
 353.116 +	{
 353.117 +	}
 353.118 +
 353.119 +	// automatic destruction of the wrapped object when all
 353.120 +	// references are freed.
 353.121 +	~shared_ptr()	{
 353.122 +		if (ctr) {
 353.123 +			ctr = ctr->decref(ptr);
 353.124 +		}
 353.125 +	}
 353.126 +
 353.127 +	shared_ptr& operator=(const shared_ptr& r) {
 353.128 +		if (this == &r) {
 353.129 +			return *this;
 353.130 +		}
 353.131 +		if (ctr) {
 353.132 +			ctr->decref(ptr);
 353.133 +		}
 353.134 +		ptr = r.ptr;
 353.135 +		ctr = ptr?r.ctr->incref():NULL;
 353.136 +		return *this;
 353.137 +	}
 353.138 +
 353.139 +	template <typename Y>
 353.140 +	shared_ptr& operator=(const shared_ptr<Y>& r) {
 353.141 +		if (this == &r) {
 353.142 +			return *this;
 353.143 +		}
 353.144 +		if (ctr) {
 353.145 +			ctr->decref(ptr);
 353.146 +		}
 353.147 +		ptr = r.ptr;
 353.148 +		ctr = ptr?r.ctr->incref():NULL;
 353.149 +		return *this;
 353.150 +	}
 353.151 +
 353.152 +	// pointer access
 353.153 +	inline operator T*() const {
 353.154 +		return ptr;
 353.155 +	}
 353.156 +
 353.157 +	inline T* operator-> () const	{
 353.158 +		return ptr;
 353.159 +	}
 353.160 +
 353.161 +	// standard semantics
 353.162 +	inline T* get() {
 353.163 +		return ptr;
 353.164 +	}
 353.165 +
 353.166 +	inline const T* get() const	{
 353.167 +		return ptr;
 353.168 +	}
 353.169 +
 353.170 +	inline operator bool () const {
 353.171 +		return ptr != NULL;
 353.172 +	}
 353.173 +
 353.174 +	inline bool unique() const {
 353.175 +		return use_count() == 1;
 353.176 +	}
 353.177 +
 353.178 +	inline long use_count() const {
 353.179 +		return ctr->get();
 353.180 +	}
 353.181 +
 353.182 +	inline void reset (T* t = 0)	{
 353.183 +		if (ctr) {
 353.184 +			ctr->decref(ptr);
 353.185 +		}
 353.186 +		ptr = t;
 353.187 +		ctr = ptr?new detail::controller():NULL;
 353.188 +	}
 353.189 +
 353.190 +	void swap(shared_ptr & b)	{
 353.191 +		std::swap(ptr, b.ptr);
 353.192 +		std::swap(ctr, b.ctr);
 353.193 +	}
 353.194 +
 353.195 +private:
 353.196 +
 353.197 +
 353.198 +	// for use by the various xxx_pointer_cast helper templates
 353.199 +	explicit shared_ptr(T* ptr, detail::controller* ctr)
 353.200 +		: ptr(ptr)
 353.201 +		, ctr(ctr->incref())
 353.202 +	{
 353.203 +	}
 353.204 +
 353.205 +private:
 353.206 +
 353.207 +	// encapsulated object pointer
 353.208 +	T* ptr;
 353.209 +
 353.210 +	// control block
 353.211 +	detail::controller* ctr;
 353.212 +};
 353.213 +
 353.214 +template<class T>
 353.215 +inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
 353.216 +{
 353.217 +	a.swap(b);
 353.218 +}
 353.219 +
 353.220 +template<class T>
 353.221 +bool operator== (const shared_ptr<T>& a, const shared_ptr<T>& b) {
 353.222 +	return a.ptr == b.ptr;
 353.223 +}
 353.224 +template<class T>
 353.225 +bool operator!= (const shared_ptr<T>& a, const shared_ptr<T>& b) {
 353.226 +	return a.ptr != b.ptr;
 353.227 +}
 353.228 +	
 353.229 +template<class T>
 353.230 +bool operator< (const shared_ptr<T>& a, const shared_ptr<T>& b) {
 353.231 +	return a.ptr < b.ptr;
 353.232 +}
 353.233 +
 353.234 +
 353.235 +template<class T, class U>
 353.236 +inline shared_ptr<T> static_pointer_cast( shared_ptr<U> ptr)
 353.237 +{  
 353.238 +   return shared_ptr<T>(static_cast<T*>(ptr.ptr),ptr.ctr);
 353.239 +}
 353.240 +
 353.241 +template<class T, class U>
 353.242 +inline shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> ptr)
 353.243 +{  
 353.244 +   return shared_ptr<T>(dynamic_cast<T*>(ptr.ptr),ptr.ctr);
 353.245 +}
 353.246 +
 353.247 +template<class T, class U>
 353.248 +inline shared_ptr<T> const_pointer_cast( shared_ptr<U> ptr)
 353.249 +{  
 353.250 +   return shared_ptr<T>(const_cast<T*>(ptr.ptr),ptr.ctr);
 353.251 +}
 353.252 +
 353.253 +
 353.254 +
 353.255 +} // end of namespace boost
 353.256 +
 353.257 +#else
 353.258 +#	error "shared_ptr.h was already included"
 353.259 +#endif
 353.260 +#endif // INCLUDED_AI_BOOST_SCOPED_PTR
   354.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   354.2 +++ b/libs/assimp/boost/static_assert.hpp	Sat Feb 01 19:58:19 2014 +0200
   354.3 @@ -0,0 +1,20 @@
   354.4 +
   354.5 +#ifndef AI_BOOST_STATIC_ASSERT_INCLUDED
   354.6 +#define AI_BOOST_STATIC_ASSERT_INCLUDED
   354.7 +
   354.8 +#ifndef BOOST_STATIC_ASSERT
   354.9 +
  354.10 +namespace boost {
  354.11 +	namespace detail {
  354.12 +
  354.13 +		template <bool b>  class static_assertion_failure;
  354.14 +		template <>        class static_assertion_failure<true> {};
  354.15 +	}
  354.16 +}
  354.17 +
  354.18 +
  354.19 +#define BOOST_STATIC_ASSERT(eval) \
  354.20 +{boost::detail::static_assertion_failure<(eval)> assert_dummy;(void)assert_dummy;}
  354.21 +
  354.22 +#endif
  354.23 +#endif // !! AI_BOOST_STATIC_ASSERT_INCLUDED
   355.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   355.2 +++ b/libs/assimp/boost/timer.hpp	Sat Feb 01 19:58:19 2014 +0200
   355.3 @@ -0,0 +1,72 @@
   355.4 +//  boost timer.hpp header file  ---------------------------------------------//
   355.5 +
   355.6 +//  Copyright Beman Dawes 1994-99.  Distributed under the Boost
   355.7 +//  Software License, Version 1.0. (See accompanying file
   355.8 +//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
   355.9 +
  355.10 +//  See http://www.boost.org/libs/timer for documentation.
  355.11 +
  355.12 +//  Revision History
  355.13 +//  01 Apr 01  Modified to use new <boost/limits.hpp> header. (JMaddock)
  355.14 +//  12 Jan 01  Change to inline implementation to allow use without library
  355.15 +//             builds. See docs for more rationale. (Beman Dawes) 
  355.16 +//  25 Sep 99  elapsed_max() and elapsed_min() added (John Maddock)
  355.17 +//  16 Jul 99  Second beta
  355.18 +//   6 Jul 99  Initial boost version
  355.19 +
  355.20 +#ifndef BOOST_TIMER_HPP
  355.21 +#define BOOST_TIMER_HPP
  355.22 +
  355.23 +//#include <boost/config.hpp>
  355.24 +#include <ctime>
  355.25 +//#include <boost/limits.hpp>
  355.26 +
  355.27 +# ifdef BOOST_NO_STDC_NAMESPACE
  355.28 +    namespace std { using ::clock_t; using ::clock; }
  355.29 +# endif
  355.30 +
  355.31 +
  355.32 +namespace boost {
  355.33 +
  355.34 +//  timer  -------------------------------------------------------------------//
  355.35 +
  355.36 +//  A timer object measures elapsed time.
  355.37 +
  355.38 +//  It is recommended that implementations measure wall clock rather than CPU
  355.39 +//  time since the intended use is performance measurement on systems where
  355.40 +//  total elapsed time is more important than just process or CPU time.
  355.41 +
  355.42 +//  Warnings: The maximum measurable elapsed time may well be only 596.5+ hours
  355.43 +//  due to implementation limitations.  The accuracy of timings depends on the
  355.44 +//  accuracy of timing information provided by the underlying platform, and
  355.45 +//  this varies a great deal from platform to platform.
  355.46 +
  355.47 +class timer
  355.48 +{
  355.49 + public:
  355.50 +         timer() { _start_time = std::clock(); } // postcondition: elapsed()==0
  355.51 +//         timer( const timer& src );      // post: elapsed()==src.elapsed()
  355.52 +//        ~timer(){}
  355.53 +//  timer& operator=( const timer& src );  // post: elapsed()==src.elapsed()
  355.54 +  void   restart() { _start_time = std::clock(); } // post: elapsed()==0
  355.55 +  double elapsed() const                  // return elapsed time in seconds
  355.56 +    { return  double(std::clock() - _start_time) / CLOCKS_PER_SEC; }
  355.57 +
  355.58 +  double elapsed_max() const   // return estimated maximum value for elapsed()
  355.59 +  // Portability warning: elapsed_max() may return too high a value on systems
  355.60 +  // where std::clock_t overflows or resets at surprising values.
  355.61 +  {
  355.62 +    return (double((std::numeric_limits<std::clock_t>::max)())
  355.63 +       - double(_start_time)) / double(CLOCKS_PER_SEC); 
  355.64 +  }
  355.65 +
  355.66 +  double elapsed_min() const            // return minimum value for elapsed()
  355.67 +   { return double(1)/double(CLOCKS_PER_SEC); }
  355.68 +
  355.69 + private:
  355.70 +  std::clock_t _start_time;
  355.71 +}; // timer
  355.72 +
  355.73 +} // namespace boost
  355.74 +
  355.75 +#endif  // BOOST_TIMER_HPP
  355.76 \ No newline at end of file
   356.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   356.2 +++ b/libs/assimp/boost/tuple/tuple.hpp	Sat Feb 01 19:58:19 2014 +0200
   356.3 @@ -0,0 +1,283 @@
   356.4 +// A very small replacement for boost::tuple
   356.5 +// (c) Alexander Gessler, 2008 [alexander.gessler@gmx.net]
   356.6 +
   356.7 +#ifndef BOOST_TUPLE_INCLUDED
   356.8 +#define BOOST_TUPLE_INCLUDED
   356.9 +
  356.10 +namespace boost	{
  356.11 +	namespace detail	{
  356.12 +
  356.13 +		// Represents an empty tuple slot (up to 5 supported)
  356.14 +		struct nulltype {};
  356.15 +
  356.16 +		// For readable error messages
  356.17 +		struct tuple_component_idx_out_of_bounds;
  356.18 +
  356.19 +		// To share some code for the const/nonconst versions of the getters
  356.20 +		template <bool b, typename T>
  356.21 +		struct ConstIf {
  356.22 +			typedef T t;
  356.23 +		};
  356.24 +
  356.25 +		template <typename T>
  356.26 +		struct ConstIf<true,T> {
  356.27 +			typedef const T t;
  356.28 +		};
  356.29 +
  356.30 +		// Predeclare some stuff
  356.31 +		template <typename, unsigned, typename, bool, unsigned> struct value_getter;
  356.32 +
  356.33 +		// Helper to obtain the type of a tuple element
  356.34 +		template <typename T, unsigned NIDX, typename TNEXT, unsigned N /*= 0*/>
  356.35 +		struct type_getter	{
  356.36 +			typedef type_getter<typename TNEXT::type,NIDX+1,typename TNEXT::next_type,N> next_elem_getter;
  356.37 +			typedef typename next_elem_getter::type type;
  356.38 +		};
  356.39 +
  356.40 +		template <typename T, unsigned NIDX, typename TNEXT >
  356.41 +		struct type_getter <T,NIDX,TNEXT,NIDX>	{
  356.42 +			typedef T type;
  356.43 +		};
  356.44 +
  356.45 +		// Base class for all explicit specializations of list_elem
  356.46 +		template <typename T, unsigned NIDX, typename TNEXT >
  356.47 +		struct list_elem_base {
  356.48 +
  356.49 +			// Store template parameters
  356.50 +			typedef TNEXT next_type;
  356.51 +			typedef T type;
  356.52 +
  356.53 +			static const unsigned nidx = NIDX;
  356.54 +		};
  356.55 +
  356.56 +		// Represents an element in the tuple component list
  356.57 +		template <typename T, unsigned NIDX, typename TNEXT >
  356.58 +		struct list_elem : list_elem_base<T,NIDX,TNEXT>{
  356.59 +
  356.60 +			// Real members
  356.61 +			T me;
  356.62 +			TNEXT next;
  356.63 +
  356.64 +			// Get the value of a specific tuple element
  356.65 +			template <unsigned N>
  356.66 +			typename type_getter<T,NIDX,TNEXT,N>::type& get () {
  356.67 +				value_getter <T,NIDX,TNEXT,false,N> s;
  356.68 +				return s(*this);
  356.69 +			}
  356.70 +
  356.71 +			// Get the value of a specific tuple element
  356.72 +			template <unsigned N>
  356.73 +			const typename type_getter<T,NIDX,TNEXT,N>::type& get () const {
  356.74 +				value_getter <T,NIDX,TNEXT,true,N> s;
  356.75 +				return s(*this);
  356.76 +			}
  356.77 +
  356.78 +			// Explicit cast
  356.79 +			template <typename T2, typename TNEXT2 >
  356.80 +			operator list_elem<T2,NIDX,TNEXT2> () const	{
  356.81 +				list_elem<T2,NIDX,TNEXT2> ret;
  356.82 +				ret.me   = (T2)me;
  356.83 +				ret.next = next;
  356.84 +				return ret;
  356.85 +			}
  356.86 +
  356.87 +			// Recursively compare two elements (last element returns always true)
  356.88 +			bool operator == (const list_elem& s) const	{
  356.89 +				return (me == s.me && next == s.next);
  356.90 +			}
  356.91 +		};
  356.92 +
  356.93 +		// Represents a non-used tuple element - the very last element processed
  356.94 +		template <typename TNEXT, unsigned NIDX  >
  356.95 +		struct list_elem<nulltype,NIDX,TNEXT> : list_elem_base<nulltype,NIDX,TNEXT> {
  356.96 +			template <unsigned N, bool IS_CONST = true> struct value_getter		{
  356.97 +				/* just dummy members to produce readable error messages */
  356.98 +				tuple_component_idx_out_of_bounds operator () (typename ConstIf<IS_CONST,list_elem>::t& me);
  356.99 +			};
 356.100 +			template <unsigned N> struct type_getter  {
 356.101 +				/* just dummy members to produce readable error messages */
 356.102 +				typedef tuple_component_idx_out_of_bounds type;
 356.103 +			};
 356.104 +
 356.105 +			// dummy
 356.106 +			list_elem& operator = (const list_elem& other)	{
 356.107 +				return *this;
 356.108 +			}
 356.109 +
 356.110 +			// dummy
 356.111 +			bool operator == (const list_elem& other)	{
 356.112 +				return true;
 356.113 +			}
 356.114 +		};
 356.115 +
 356.116 +		// Represents the absolute end of the list
 356.117 +		typedef list_elem<nulltype,0,int> list_end;
 356.118 +
 356.119 +		// Helper obtain to query the value of a tuple element
 356.120 +		// NOTE: This can't be a nested class as the compiler won't accept a full or
 356.121 +		// partial specialization of a nested class of a non-specialized template
 356.122 +		template <typename T, unsigned NIDX, typename TNEXT, bool IS_CONST, unsigned N>
 356.123 +		struct value_getter	 {
 356.124 +
 356.125 +			// calling list_elem
 356.126 +			typedef list_elem<T,NIDX,TNEXT> outer_elem;
 356.127 +
 356.128 +			// typedef for the getter for next element
 356.129 +			typedef value_getter<typename TNEXT::type,NIDX+1,typename TNEXT::next_type,
 356.130 +				IS_CONST, N> next_value_getter;
 356.131 +
 356.132 +			typename ConstIf<IS_CONST,typename type_getter<T,NIDX,TNEXT,N>::type>::t&
 356.133 +				operator () (typename ConstIf<IS_CONST,outer_elem >::t& me) {
 356.134 +
 356.135 +				next_value_getter s;
 356.136 +				return s(me.next);
 356.137 +			}
 356.138 +		};
 356.139 +
 356.140 +		template <typename T, unsigned NIDX, typename TNEXT, bool IS_CONST>
 356.141 +		struct value_getter <T,NIDX,TNEXT,IS_CONST,NIDX>	{
 356.142 +			typedef list_elem<T,NIDX,TNEXT> outer_elem;
 356.143 +
 356.144 +			typename ConstIf<IS_CONST,T>::t& operator () (typename ConstIf<IS_CONST,outer_elem >::t& me) {
 356.145 +				return me.me;
 356.146 +			}
 356.147 +		};
 356.148 +	};
 356.149 +
 356.150 +	// A very minimal implementation for up to 5 elements
 356.151 +	template <typename T0  = detail::nulltype,
 356.152 +		      typename T1  = detail::nulltype,
 356.153 +			  typename T2  = detail::nulltype,
 356.154 +			  typename T3  = detail::nulltype,
 356.155 +			  typename T4  = detail::nulltype>
 356.156 +	class tuple	{
 356.157 +
 356.158 +		template <typename T0b,
 356.159 +		      typename T1b,
 356.160 +			  typename T2b,
 356.161 +			  typename T3b,
 356.162 +			  typename T4b >
 356.163 +		friend class tuple;
 356.164 +
 356.165 +	private:
 356.166 +
 356.167 +		typedef detail::list_elem<T0,0,
 356.168 +					detail::list_elem<T1,1,
 356.169 +						detail::list_elem<T2,2,
 356.170 +							detail::list_elem<T3,3,
 356.171 +								detail::list_elem<T4,4,
 356.172 +									detail::list_end > > > > > very_long;
 356.173 +
 356.174 +		very_long m;
 356.175 +
 356.176 +	public:
 356.177 +
 356.178 +		// Get a specific tuple element
 356.179 +		template <unsigned N>
 356.180 +		typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get ()	{
 356.181 +			return m.template get<N>();
 356.182 +		}
 356.183 +
 356.184 +		// ... and the const version
 356.185 +		template <unsigned N>
 356.186 +		const typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () const	{
 356.187 +			return m.template get<N>();
 356.188 +		}
 356.189 +
 356.190 +
 356.191 +		// comparison operators
 356.192 +		bool operator== (const tuple& other) const	{
 356.193 +			return m == other.m;
 356.194 +		}
 356.195 +
 356.196 +		// ... and the other way round
 356.197 +		bool operator!= (const tuple& other) const	{
 356.198 +			return !(m == other.m);
 356.199 +		}
 356.200 +
 356.201 +		// cast to another tuple - all single elements must be convertible
 356.202 +		template <typename T0b, typename T1b,typename T2b,typename T3b, typename T4b>
 356.203 +		operator tuple <T0b,T1b,T2b,T3b,T4b> () const {
 356.204 +			tuple <T0b,T1b,T2b,T3b,T4b> s;
 356.205 +			s.m = (typename tuple <T0b,T1b,T2b,T3b,T4b>::very_long)m;
 356.206 +			return s;
 356.207 +		}
 356.208 +	};
 356.209 +
 356.210 +	// Another way to access an element ...
 356.211 +	template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
 356.212 +	inline typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
 356.213 +			tuple<T0,T1,T2,T3,T4>& m)	{
 356.214 +			return m.template get<N>();
 356.215 +		}
 356.216 +
 356.217 +	// ... and the const version
 356.218 +	template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
 356.219 +	inline const typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
 356.220 +			const tuple<T0,T1,T2,T3,T4>& m)	{
 356.221 +			return m.template get<N>();
 356.222 +		}
 356.223 +
 356.224 +	// Constructs a tuple with 5 elements
 356.225 +	template <typename T0,typename T1,typename T2,typename T3,typename T4>
 356.226 +	inline tuple <T0,T1,T2,T3,T4> make_tuple (const T0& t0,
 356.227 +		const T1& t1,const T2& t2,const T3& t3,const T4& t4) {
 356.228 +
 356.229 +		tuple <T0,T1,T2,T3,T4> t;
 356.230 +		t.template get<0>() = t0;
 356.231 +		t.template get<1>() = t1;
 356.232 +		t.template get<2>() = t2;
 356.233 +		t.template get<3>() = t3;
 356.234 +		t.template get<4>() = t4;
 356.235 +		return t;
 356.236 +	}
 356.237 +
 356.238 +	// Constructs a tuple with 4 elements
 356.239 +	template <typename T0,typename T1,typename T2,typename T3>
 356.240 +	inline tuple <T0,T1,T2,T3> make_tuple (const T0& t0,
 356.241 +		const T1& t1,const T2& t2,const T3& t3) {
 356.242 +		tuple <T0,T1,T2,T3> t;
 356.243 +		t.template get<0>() = t0;
 356.244 +		t.template get<1>() = t1;
 356.245 +		t.template get<2>() = t2;
 356.246 +		t.template get<3>() = t3;
 356.247 +		return t;
 356.248 +	}
 356.249 +
 356.250 +	// Constructs a tuple with 3 elements
 356.251 +	template <typename T0,typename T1,typename T2>
 356.252 +	inline tuple <T0,T1,T2> make_tuple (const T0& t0,
 356.253 +		const T1& t1,const T2& t2) {
 356.254 +		tuple <T0,T1,T2> t;
 356.255 +		t.template get<0>() = t0;
 356.256 +		t.template get<1>() = t1;
 356.257 +		t.template get<2>() = t2;
 356.258 +		return t;
 356.259 +	}
 356.260 +
 356.261 +	// Constructs a tuple with 2 elements 
 356.262 +	template <typename T0,typename T1>
 356.263 +	inline tuple <T0,T1> make_tuple (const T0& t0,
 356.264 +		const T1& t1) {
 356.265 +		tuple <T0,T1> t;
 356.266 +		t.template get<0>() = t0;
 356.267 +		t.template get<1>() = t1;
 356.268 +		return t;
 356.269 +	}
 356.270 +
 356.271 +	// Constructs a tuple with 1 elements (well ...)
 356.272 +	template <typename T0>
 356.273 +	inline tuple <T0> make_tuple (const T0& t0) {
 356.274 +		tuple <T0> t;
 356.275 +		t.template get<0>() = t0;
 356.276 +		return t;
 356.277 +	}
 356.278 +
 356.279 +	// Constructs a tuple with 0 elements (well ...)
 356.280 +	inline tuple <> make_tuple () {
 356.281 +		tuple <> t;
 356.282 +		return t;
 356.283 +	}
 356.284 +};
 356.285 +
 356.286 +#endif // !! BOOST_TUPLE_INCLUDED
   357.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   357.2 +++ b/libs/assimp/fast_atof.h	Sat Feb 01 19:58:19 2014 +0200
   357.3 @@ -0,0 +1,336 @@
   357.4 +// Copyright (C) 2002-2007 Nikolaus Gebhardt
   357.5 +// This file is part of the "Irrlicht Engine" and the "irrXML" project.
   357.6 +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
   357.7 +
   357.8 +// ------------------------------------------------------------------------------------
   357.9 +// Original description: (Schrompf)
  357.10 +// Adapted to the ASSIMP library because the builtin atof indeed takes AGES to parse a
  357.11 +// float inside a large string. Before parsing, it does a strlen on the given point.
  357.12 +// Changes:
  357.13 +//  22nd October 08 (Aramis_acg): Added temporary cast to double, added strtoul10_64
  357.14 +//     to ensure long numbers are handled correctly
  357.15 +// ------------------------------------------------------------------------------------
  357.16 +
  357.17 +
  357.18 +#ifndef __FAST_A_TO_F_H_INCLUDED__
  357.19 +#define __FAST_A_TO_F_H_INCLUDED__
  357.20 +
  357.21 +#include <math.h>
  357.22 +
  357.23 +namespace Assimp
  357.24 +{
  357.25 +
  357.26 +const float fast_atof_table[16] =	{  // we write [16] here instead of [] to work around a swig bug
  357.27 +	0.f,
  357.28 +	0.1f,
  357.29 +	0.01f,
  357.30 +	0.001f,
  357.31 +	0.0001f,
  357.32 +	0.00001f,
  357.33 +	0.000001f,
  357.34 +	0.0000001f,
  357.35 +	0.00000001f,
  357.36 +	0.000000001f,
  357.37 +	0.0000000001f,
  357.38 +	0.00000000001f,
  357.39 +	0.000000000001f,
  357.40 +	0.0000000000001f,
  357.41 +	0.00000000000001f,
  357.42 +	0.000000000000001f
  357.43 +};
  357.44 +
  357.45 +
  357.46 +// ------------------------------------------------------------------------------------
  357.47 +// Convert a string in decimal format to a number
  357.48 +// ------------------------------------------------------------------------------------
  357.49 +inline unsigned int strtoul10( const char* in, const char** out=0)
  357.50 +{
  357.51 +	unsigned int value = 0;
  357.52 +
  357.53 +	bool running = true;
  357.54 +	while ( running )
  357.55 +	{
  357.56 +		if ( *in < '0' || *in > '9' )
  357.57 +			break;
  357.58 +
  357.59 +		value = ( value * 10 ) + ( *in - '0' );
  357.60 +		++in;
  357.61 +	}
  357.62 +	if (out)*out = in;
  357.63 +	return value;
  357.64 +}
  357.65 +
  357.66 +// ------------------------------------------------------------------------------------
  357.67 +// Convert a string in octal format to a number
  357.68 +// ------------------------------------------------------------------------------------
  357.69 +inline unsigned int strtoul8( const char* in, const char** out=0)
  357.70 +{
  357.71 +	unsigned int value = 0;
  357.72 +
  357.73 +	bool running = true;
  357.74 +	while ( running )
  357.75 +	{
  357.76 +		if ( *in < '0' || *in > '7' )
  357.77 +			break;
  357.78 +
  357.79 +		value = ( value << 3 ) + ( *in - '0' );
  357.80 +		++in;
  357.81 +	}
  357.82 +	if (out)*out = in;
  357.83 +	return value;
  357.84 +}
  357.85 +
  357.86 +// ------------------------------------------------------------------------------------
  357.87 +// Convert a string in hex format to a number
  357.88 +// ------------------------------------------------------------------------------------
  357.89 +inline unsigned int strtoul16( const char* in, const char** out=0)
  357.90 +{
  357.91 +	unsigned int value = 0;
  357.92 +
  357.93 +	bool running = true;
  357.94 +	while ( running )
  357.95 +	{
  357.96 +		if ( *in >= '0' && *in <= '9' )
  357.97 +		{
  357.98 +			value = ( value << 4u ) + ( *in - '0' );
  357.99 +		}
 357.100 +		else if (*in >= 'A' && *in <= 'F')
 357.101 +		{
 357.102 +			value = ( value << 4u ) + ( *in - 'A' ) + 10;
 357.103 +		}
 357.104 +		else if (*in >= 'a' && *in <= 'f')
 357.105 +		{
 357.106 +			value = ( value << 4u ) + ( *in - 'a' ) + 10;
 357.107 +		}
 357.108 +		else break;
 357.109 +		++in;
 357.110 +	}
 357.111 +	if (out)*out = in;
 357.112 +	return value;
 357.113 +}
 357.114 +
 357.115 +// ------------------------------------------------------------------------------------
 357.116 +// Convert just one hex digit
 357.117 +// Return value is UINT_MAX if the input character is not a hex digit.
 357.118 +// ------------------------------------------------------------------------------------
 357.119 +inline unsigned int HexDigitToDecimal(char in)
 357.120 +{
 357.121 +	unsigned int out = UINT_MAX;
 357.122 +	if (in >= '0' && in <= '9')
 357.123 +		out = in - '0';
 357.124 +
 357.125 +	else if (in >= 'a' && in <= 'f')
 357.126 +		out = 10u + in - 'a';
 357.127 +
 357.128 +	else if (in >= 'A' && in <= 'F')
 357.129 +		out = 10u + in - 'A';
 357.130 +
 357.131 +	// return value is UINT_MAX if the input is not a hex digit
 357.132 +	return out;
 357.133 +}
 357.134 +
 357.135 +// ------------------------------------------------------------------------------------
 357.136 +// Convert a hex-encoded octet (2 characters, i.e. df or 1a).
 357.137 +// ------------------------------------------------------------------------------------
 357.138 +inline uint8_t HexOctetToDecimal(const char* in)
 357.139 +{
 357.140 +	return ((uint8_t)HexDigitToDecimal(in[0])<<4)+(uint8_t)HexDigitToDecimal(in[1]);
 357.141 +}
 357.142 +
 357.143 +
 357.144 +// ------------------------------------------------------------------------------------
 357.145 +// signed variant of strtoul10
 357.146 +// ------------------------------------------------------------------------------------
 357.147 +inline int strtol10( const char* in, const char** out=0)
 357.148 +{
 357.149 +	bool inv = (*in=='-');
 357.150 +	if (inv || *in=='+')
 357.151 +		++in;
 357.152 +
 357.153 +	int value = strtoul10(in,out);
 357.154 +	if (inv) {
 357.155 +		value = -value;
 357.156 +	}
 357.157 +	return value;
 357.158 +}
 357.159 +
 357.160 +// ------------------------------------------------------------------------------------
 357.161 +// Parse a C++-like integer literal - hex and oct prefixes.
 357.162 +// 0xNNNN - hex
 357.163 +// 0NNN   - oct
 357.164 +// NNN    - dec
 357.165 +// ------------------------------------------------------------------------------------
 357.166 +inline unsigned int strtoul_cppstyle( const char* in, const char** out=0)
 357.167 +{
 357.168 +	if ('0' == in[0])
 357.169 +	{
 357.170 +		return 'x' == in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out);
 357.171 +	}
 357.172 +	return strtoul10(in, out);
 357.173 +}
 357.174 +
 357.175 +// ------------------------------------------------------------------------------------
 357.176 +// Special version of the function, providing higher accuracy and safety
 357.177 +// It is mainly used by fast_atof to prevent ugly and unwanted integer overflows.
 357.178 +// ------------------------------------------------------------------------------------
 357.179 +inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_inout=0)
 357.180 +{
 357.181 +	unsigned int cur = 0;
 357.182 +	uint64_t value = 0;
 357.183 +
 357.184 +	bool running = true;
 357.185 +	while ( running )
 357.186 +	{
 357.187 +		if ( *in < '0' || *in > '9' )
 357.188 +			break;
 357.189 +
 357.190 +		const uint64_t new_value = ( value * 10 ) + ( *in - '0' );
 357.191 +		
 357.192 +		if (new_value < value) /* numeric overflow, we rely on you */
 357.193 +			return value;
 357.194 +
 357.195 +		value = new_value;
 357.196 +
 357.197 +		++in;
 357.198 +		++cur;
 357.199 +
 357.200 +		if (max_inout && *max_inout == cur) {
 357.201 +					
 357.202 +			if (out) { /* skip to end */
 357.203 +				while (*in >= '0' && *in <= '9')
 357.204 +					++in;
 357.205 +				*out = in;
 357.206 +			}
 357.207 +
 357.208 +			return value;
 357.209 +		}
 357.210 +	}
 357.211 +	if (out)
 357.212 +		*out = in;
 357.213 +
 357.214 +	if (max_inout)
 357.215 +		*max_inout = cur;
 357.216 +
 357.217 +	return value;
 357.218 +}
 357.219 +
 357.220 +// Number of relevant decimals for floating-point parsing.
 357.221 +#define AI_FAST_ATOF_RELAVANT_DECIMALS 15
 357.222 +
 357.223 +// ------------------------------------------------------------------------------------
 357.224 +//! Provides a fast function for converting a string into a float,
 357.225 +//! about 6 times faster than atof in win32.
 357.226 +// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
 357.227 +// ------------------------------------------------------------------------------------
 357.228 +template <typename Real>
 357.229 +inline const char* fast_atoreal_move( const char* c, Real& out)
 357.230 +{
 357.231 +	Real f;
 357.232 +
 357.233 +	bool inv = (*c=='-');
 357.234 +	if (inv || *c=='+') {
 357.235 +		++c;
 357.236 +	}
 357.237 +
 357.238 +	f = static_cast<Real>( strtoul10_64 ( c, &c) );
 357.239 +	if (*c == '.' || (c[0] == ',' && c[1] >= '0' && c[1] <= '9')) // allow for commas, too
 357.240 +	{
 357.241 +		++c;
 357.242 +
 357.243 +		// NOTE: The original implementation is highly inaccurate here. The precision of a single
 357.244 +		// IEEE 754 float is not high enough, everything behind the 6th digit tends to be more 
 357.245 +		// inaccurate than it would need to be. Casting to double seems to solve the problem.
 357.246 +		// strtol_64 is used to prevent integer overflow.
 357.247 +
 357.248 +		// Another fix: this tends to become 0 for long numbers if we don't limit the maximum 
 357.249 +		// number of digits to be read. AI_FAST_ATOF_RELAVANT_DECIMALS can be a value between
 357.250 +		// 1 and 15.
 357.251 +		unsigned int diff = AI_FAST_ATOF_RELAVANT_DECIMALS;
 357.252 +		double pl = static_cast<double>( strtoul10_64 ( c, &c, &diff ));
 357.253 +
 357.254 +		pl *= fast_atof_table[diff];
 357.255 +		f += static_cast<Real>( pl );
 357.256 +	}
 357.257 +
 357.258 +	// A major 'E' must be allowed. Necessary for proper reading of some DXF files.
 357.259 +	// Thanks to Zhao Lei to point out that this if() must be outside the if (*c == '.' ..)
 357.260 +	if (*c == 'e' || *c == 'E')	{
 357.261 +
 357.262 +		++c;
 357.263 +		const bool einv = (*c=='-');
 357.264 +		if (einv || *c=='+') {
 357.265 +			++c;
 357.266 +		}
 357.267 +
 357.268 +		// The reason float constants are used here is that we've seen cases where compilers
 357.269 +		// would perform such casts on compile-time constants at runtime, which would be
 357.270 +		// bad considering how frequently fast_atoreal_move<float> is called in Assimp.
 357.271 +		Real exp = static_cast<Real>( strtoul10_64(c, &c) );
 357.272 +		if (einv) {
 357.273 +			exp = -exp;
 357.274 +		}
 357.275 +		f *= pow(static_cast<Real>(10.0f), exp);
 357.276 +	}
 357.277 +
 357.278 +	if (inv) {
 357.279 +		f = -f;
 357.280 +	}
 357.281 +	out = f;
 357.282 +	return c;
 357.283 +}
 357.284 +
 357.285 +// ------------------------------------------------------------------------------------
 357.286 +// The same but more human.
 357.287 +inline float fast_atof(const char* c)
 357.288 +{
 357.289 +	float ret;
 357.290 +	fast_atoreal_move<float>(c, ret);
 357.291 +	return ret;
 357.292 +}
 357.293 +
 357.294 +
 357.295 +inline float fast_atof( const char* c, const char** cout)
 357.296 +{
 357.297 +	float ret;
 357.298 +	*cout = fast_atoreal_move<float>(c, ret);
 357.299 +
 357.300 +	return ret;
 357.301 +}
 357.302 +
 357.303 +inline float fast_atof( const char** inout)
 357.304 +{
 357.305 +	float ret;
 357.306 +	*inout = fast_atoreal_move<float>(*inout, ret);
 357.307 +
 357.308 +	return ret;
 357.309 +}
 357.310 +
 357.311 +
 357.312 +inline double fast_atod(const char* c)
 357.313 +{
 357.314 +	double ret;
 357.315 +	fast_atoreal_move<double>(c, ret);
 357.316 +	return ret;
 357.317 +}
 357.318 +
 357.319 +
 357.320 +inline double fast_atod( const char* c, const char** cout)
 357.321 +{
 357.322 +	double ret;
 357.323 +	*cout = fast_atoreal_move<double>(c, ret);
 357.324 +
 357.325 +	return ret;
 357.326 +}
 357.327 +
 357.328 +inline double fast_atod( const char** inout)
 357.329 +{
 357.330 +	double ret;
 357.331 +	*inout = fast_atoreal_move<double>(*inout, ret);
 357.332 +
 357.333 +	return ret;
 357.334 +}
 357.335 +
 357.336 +} // end of namespace Assimp
 357.337 +
 357.338 +#endif
 357.339 +
   358.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   358.2 +++ b/libs/assimp/irrXML/CXMLReaderImpl.h	Sat Feb 01 19:58:19 2014 +0200
   358.3 @@ -0,0 +1,809 @@
   358.4 +// Copyright (C) 2002-2005 Nikolaus Gebhardt
   358.5 +// This file is part of the "Irrlicht Engine" and the "irrXML" project.
   358.6 +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
   358.7 +
   358.8 +#ifndef __ICXML_READER_IMPL_H_INCLUDED__
   358.9 +#define __ICXML_READER_IMPL_H_INCLUDED__
  358.10 +
  358.11 +#include "irrXML.h"
  358.12 +#include "irrString.h"
  358.13 +#include "irrArray.h"
  358.14 +
  358.15 +using namespace Assimp;
  358.16 +
  358.17 +#ifdef _DEBUG
  358.18 +#define IRR_DEBUGPRINT(x) printf((x));
  358.19 +#else // _DEBUG 
  358.20 +#define IRR_DEBUGPRINT(x)
  358.21 +#endif // _DEBUG
  358.22 +
  358.23 +
  358.24 +namespace irr
  358.25 +{
  358.26 +namespace io
  358.27 +{
  358.28 +
  358.29 +
  358.30 +//! implementation of the IrrXMLReader
  358.31 +template<class char_type, class superclass>
  358.32 +class CXMLReaderImpl : public IIrrXMLReader<char_type, superclass>
  358.33 +{
  358.34 +public:
  358.35 +
  358.36 +	//! Constructor
  358.37 +	CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true)
  358.38 +		: TextData(0), P(0), TextBegin(0), TextSize(0), CurrentNodeType(EXN_NONE),
  358.39 +		SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII)
  358.40 +	{
  358.41 +		if (!callback)
  358.42 +			return;
  358.43 +
  358.44 +		storeTargetFormat();
  358.45 +
  358.46 +		// read whole xml file
  358.47 +
  358.48 +		readFile(callback);
  358.49 +		
  358.50 +		// clean up
  358.51 +
  358.52 +		if (deleteCallBack)
  358.53 +			delete callback;
  358.54 +
  358.55 +		// create list with special characters
  358.56 +
  358.57 +		createSpecialCharacterList();
  358.58 +
  358.59 +		// set pointer to text begin
  358.60 +		P = TextBegin;
  358.61 +	}
  358.62 +    	
  358.63 +
  358.64 +	//! Destructor
  358.65 +	virtual ~CXMLReaderImpl()
  358.66 +	{
  358.67 +		delete [] TextData;
  358.68 +	}
  358.69 +
  358.70 +
  358.71 +	//! Reads forward to the next xml node. 
  358.72 +	//! \return Returns false, if there was no further node. 
  358.73 +	virtual bool read()
  358.74 +	{
  358.75 +		// if not end reached, parse the node
  358.76 +		if (P && (unsigned int)(P - TextBegin) < TextSize - 1 && *P != 0)
  358.77 +		{
  358.78 +			parseCurrentNode();
  358.79 +			return true;
  358.80 +		}
  358.81 +
  358.82 +		_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
  358.83 +		return false;
  358.84 +	}
  358.85 +
  358.86 +
  358.87 +	//! Returns the type of the current XML node.
  358.88 +	virtual EXML_NODE getNodeType() const
  358.89 +	{
  358.90 +		return CurrentNodeType;
  358.91 +	}
  358.92 +
  358.93 +
  358.94 +	//! Returns attribute count of the current XML node.
  358.95 +	virtual int getAttributeCount() const
  358.96 +	{
  358.97 +		return Attributes.size();
  358.98 +	}
  358.99 +
 358.100 +
 358.101 +	//! Returns name of an attribute.
 358.102 +	virtual const char_type* getAttributeName(int idx) const
 358.103 +	{
 358.104 +		if (idx < 0 || idx >= (int)Attributes.size())
 358.105 +			return 0;
 358.106 +
 358.107 +		return Attributes[idx].Name.c_str();
 358.108 +	}
 358.109 +
 358.110 +
 358.111 +	//! Returns the value of an attribute. 
 358.112 +	virtual const char_type* getAttributeValue(int idx) const
 358.113 +	{
 358.114 +		if (idx < 0 || idx >= (int)Attributes.size())
 358.115 +			return 0;
 358.116 +
 358.117 +		return Attributes[idx].Value.c_str();
 358.118 +	}
 358.119 +
 358.120 +
 358.121 +	//! Returns the value of an attribute. 
 358.122 +	virtual const char_type* getAttributeValue(const char_type* name) const
 358.123 +	{
 358.124 +		const SAttribute* attr = getAttributeByName(name);
 358.125 +		if (!attr)
 358.126 +			return 0;
 358.127 +
 358.128 +		return attr->Value.c_str();
 358.129 +	}
 358.130 +
 358.131 +
 358.132 +	//! Returns the value of an attribute
 358.133 +	virtual const char_type* getAttributeValueSafe(const char_type* name) const
 358.134 +	{
 358.135 +		const SAttribute* attr = getAttributeByName(name);
 358.136 +		if (!attr)
 358.137 +			return EmptyString.c_str();
 358.138 +
 358.139 +		return attr->Value.c_str();
 358.140 +	}
 358.141 +
 358.142 +
 358.143 +
 358.144 +	//! Returns the value of an attribute as integer. 
 358.145 +	int getAttributeValueAsInt(const char_type* name) const
 358.146 +	{
 358.147 +		return (int)getAttributeValueAsFloat(name);
 358.148 +	}
 358.149 +
 358.150 +
 358.151 +	//! Returns the value of an attribute as integer. 
 358.152 +	int getAttributeValueAsInt(int idx) const
 358.153 +	{
 358.154 +		return (int)getAttributeValueAsFloat(idx);
 358.155 +	}
 358.156 +
 358.157 +
 358.158 +	//! Returns the value of an attribute as float. 
 358.159 +	float getAttributeValueAsFloat(const char_type* name) const
 358.160 +	{
 358.161 +		const SAttribute* attr = getAttributeByName(name);
 358.162 +		if (!attr)
 358.163 +			return 0;
 358.164 +
 358.165 +		core::stringc c = attr->Value.c_str();
 358.166 +		return fast_atof(c.c_str());
 358.167 +	}
 358.168 +
 358.169 +
 358.170 +	//! Returns the value of an attribute as float. 
 358.171 +	float getAttributeValueAsFloat(int idx) const
 358.172 +	{
 358.173 +		const char_type* attrvalue = getAttributeValue(idx);
 358.174 +		if (!attrvalue)
 358.175 +			return 0;
 358.176 +
 358.177 +		core::stringc c = attrvalue;
 358.178 +		return fast_atof(c.c_str());
 358.179 +	}
 358.180 +
 358.181 +
 358.182 +	//! Returns the name of the current node.
 358.183 +	virtual const char_type* getNodeName() const
 358.184 +	{
 358.185 +		return NodeName.c_str();
 358.186 +	}
 358.187 +
 358.188 +
 358.189 +	//! Returns data of the current node.
 358.190 +	virtual const char_type* getNodeData() const
 358.191 +	{
 358.192 +		return NodeName.c_str();
 358.193 +	}
 358.194 +
 358.195 +
 358.196 +	//! Returns if an element is an empty element, like <foo />
 358.197 +	virtual bool isEmptyElement() const
 358.198 +	{
 358.199 +		return IsEmptyElement;
 358.200 +	}
 358.201 +
 358.202 +	//! Returns format of the source xml file.
 358.203 +	virtual ETEXT_FORMAT getSourceFormat() const
 358.204 +	{
 358.205 +		return SourceFormat;
 358.206 +	}
 358.207 +
 358.208 +	//! Returns format of the strings returned by the parser.
 358.209 +	virtual ETEXT_FORMAT getParserFormat() const
 358.210 +	{
 358.211 +		return TargetFormat;
 358.212 +	}
 358.213 +
 358.214 +private:
 358.215 +
 358.216 +	// Reads the current xml node
 358.217 +	void parseCurrentNode()
 358.218 +	{
 358.219 +		char_type* start = P;
 358.220 +
 358.221 +		// more forward until '<' found
 358.222 +		while(*P != L'<' && *P)
 358.223 +			++P;
 358.224 +
 358.225 +		if (!*P)
 358.226 +			return;
 358.227 +
 358.228 +		if (P - start > 0)
 358.229 +		{
 358.230 +			// we found some text, store it
 358.231 +			if (setText(start, P))
 358.232 +				return;
 358.233 +		}
 358.234 +
 358.235 +		++P;
 358.236 +
 358.237 +		// based on current token, parse and report next element
 358.238 +		switch(*P)
 358.239 +		{
 358.240 +		case L'/':
 358.241 +			parseClosingXMLElement(); 
 358.242 +			break;
 358.243 +		case L'?':
 358.244 +			ignoreDefinition();	
 358.245 +			break;
 358.246 +		case L'!':
 358.247 +			if (!parseCDATA())
 358.248 +				parseComment();	
 358.249 +			break;
 358.250 +		default:
 358.251 +			parseOpeningXMLElement();
 358.252 +			break;
 358.253 +		}
 358.254 +	}
 358.255 +
 358.256 +
 358.257 +	//! sets the state that text was found. Returns true if set should be set
 358.258 +	bool setText(char_type* start, char_type* end)
 358.259 +	{
 358.260 +		// check if text is more than 2 characters, and if not, check if there is 
 358.261 +		// only white space, so that this text won't be reported
 358.262 +		if (end - start < 3)
 358.263 +		{
 358.264 +			char_type* p = start;
 358.265 +			for(; p != end; ++p)
 358.266 +				if (!isWhiteSpace(*p))
 358.267 +					break;
 358.268 +
 358.269 +			if (p == end)
 358.270 +				return false;
 358.271 +		}
 358.272 +
 358.273 +		// set current text to the parsed text, and replace xml special characters
 358.274 +		core::string<char_type> s(start, (int)(end - start));
 358.275 +		NodeName = replaceSpecialCharacters(s);
 358.276 +
 358.277 +		// current XML node type is text
 358.278 +		CurrentNodeType = EXN_TEXT;
 358.279 +
 358.280 +		return true;
 358.281 +	}
 358.282 +
 358.283 +
 358.284 +
 358.285 +	//! ignores an xml definition like <?xml something />
 358.286 +	void ignoreDefinition()
 358.287 +	{
 358.288 +		CurrentNodeType = EXN_UNKNOWN;
 358.289 +
 358.290 +		// move until end marked with '>' reached
 358.291 +		while(*P != L'>')
 358.292 +			++P;
 358.293 +
 358.294 +		++P;
 358.295 +	}
 358.296 +
 358.297 +
 358.298 +	//! parses a comment
 358.299 +	void parseComment()
 358.300 +	{
 358.301 +		CurrentNodeType = EXN_COMMENT;
 358.302 +		P += 1;
 358.303 +
 358.304 +		char_type *pCommentBegin = P;
 358.305 +
 358.306 +		int count = 1;
 358.307 +
 358.308 +		// move until end of comment reached
 358.309 +		while(count)
 358.310 +		{
 358.311 +			if (*P == L'>')
 358.312 +				--count;
 358.313 +			else
 358.314 +			if (*P == L'<')
 358.315 +				++count;
 358.316 +
 358.317 +			++P;
 358.318 +		}
 358.319 +
 358.320 +		P -= 3;
 358.321 +		NodeName = core::string<char_type>(pCommentBegin+2, (int)(P - pCommentBegin-2));
 358.322 +		P += 3;
 358.323 +	}
 358.324 +
 358.325 +
 358.326 +	//! parses an opening xml element and reads attributes
 358.327 +	void parseOpeningXMLElement()
 358.328 +	{
 358.329 +		CurrentNodeType = EXN_ELEMENT;
 358.330 +		IsEmptyElement = false;
 358.331 +		Attributes.clear();
 358.332 +
 358.333 +		// find name
 358.334 +		const char_type* startName = P;
 358.335 +
 358.336 +		// find end of element
 358.337 +		while(*P != L'>' && !isWhiteSpace(*P))
 358.338 +			++P;
 358.339 +
 358.340 +		const char_type* endName = P;
 358.341 +
 358.342 +		// find Attributes
 358.343 +		while(*P != L'>')
 358.344 +		{
 358.345 +			if (isWhiteSpace(*P))
 358.346 +				++P;
 358.347 +			else
 358.348 +			{
 358.349 +				if (*P != L'/')
 358.350 +				{
 358.351 +					// we've got an attribute
 358.352 +
 358.353 +					// read the attribute names
 358.354 +					const char_type* attributeNameBegin = P;
 358.355 +
 358.356 +					while(!isWhiteSpace(*P) && *P != L'=')
 358.357 +						++P;
 358.358 +
 358.359 +					const char_type* attributeNameEnd = P;
 358.360 +					++P;
 358.361 +
 358.362 +					// read the attribute value
 358.363 +					// check for quotes and single quotes, thx to murphy
 358.364 +					while( (*P != L'\"') && (*P != L'\'') && *P) 
 358.365 +						++P;
 358.366 +
 358.367 +					if (!*P) // malformatted xml file
 358.368 +						return;
 358.369 +
 358.370 +					const char_type attributeQuoteChar = *P;
 358.371 +
 358.372 +					++P;
 358.373 +					const char_type* attributeValueBegin = P;
 358.374 +					
 358.375 +					while(*P != attributeQuoteChar && *P)
 358.376 +						++P;
 358.377 +
 358.378 +					if (!*P) // malformatted xml file
 358.379 +						return;
 358.380 +
 358.381 +					const char_type* attributeValueEnd = P;
 358.382 +					++P;
 358.383 +
 358.384 +					SAttribute attr;
 358.385 +					attr.Name = core::string<char_type>(attributeNameBegin, 
 358.386 +						(int)(attributeNameEnd - attributeNameBegin));
 358.387 +
 358.388 +					core::string<char_type> s(attributeValueBegin, 
 358.389 +						(int)(attributeValueEnd - attributeValueBegin));
 358.390 +
 358.391 +					attr.Value = replaceSpecialCharacters(s);
 358.392 +					Attributes.push_back(attr);
 358.393 +				}
 358.394 +				else
 358.395 +				{
 358.396 +					// tag is closed directly
 358.397 +					++P;
 358.398 +					IsEmptyElement = true;
 358.399 +					break;
 358.400 +				}
 358.401 +			}
 358.402 +		}
 358.403 +
 358.404 +		// check if this tag is closing directly
 358.405 +		if (endName > startName && *(endName-1) == L'/')
 358.406 +		{
 358.407 +			// directly closing tag
 358.408 +			IsEmptyElement = true;
 358.409 +			endName--;
 358.410 +		}
 358.411 +		
 358.412 +		NodeName = core::string<char_type>(startName, (int)(endName - startName));
 358.413 +
 358.414 +		++P;
 358.415 +	}
 358.416 +
 358.417 +
 358.418 +	//! parses an closing xml tag
 358.419 +	void parseClosingXMLElement()
 358.420 +	{
 358.421 +		CurrentNodeType = EXN_ELEMENT_END;
 358.422 +		IsEmptyElement = false;
 358.423 +		Attributes.clear();
 358.424 +
 358.425 +		++P;
 358.426 +		const char_type* pBeginClose = P;
 358.427 +
 358.428 +		while(*P != L'>')
 358.429 +			++P;
 358.430 +
 358.431 +    // remove trailing whitespace, if any
 358.432 +    while( isspace( P[-1]))
 358.433 +      --P;
 358.434 +
 358.435 +		NodeName = core::string<char_type>(pBeginClose, (int)(P - pBeginClose));
 358.436 +		++P;
 358.437 +	}
 358.438 +
 358.439 +	//! parses a possible CDATA section, returns false if begin was not a CDATA section
 358.440 +	bool parseCDATA()
 358.441 +	{
 358.442 +		if (*(P+1) != L'[')
 358.443 +			return false;
 358.444 +
 358.445 +		CurrentNodeType = EXN_CDATA;
 358.446 +
 358.447 +		// skip '<![CDATA['
 358.448 +		int count=0;
 358.449 +		while( *P && count<8 )
 358.450 +		{
 358.451 +			++P;
 358.452 +			++count;
 358.453 +		}
 358.454 +
 358.455 +		if (!*P)
 358.456 +			return true;
 358.457 +
 358.458 +		char_type *cDataBegin = P;
 358.459 +		char_type *cDataEnd = 0;
 358.460 +
 358.461 +		// find end of CDATA
 358.462 +		while(*P && !cDataEnd)
 358.463 +		{
 358.464 +			if (*P == L'>' && 
 358.465 +			   (*(P-1) == L']') &&
 358.466 +			   (*(P-2) == L']'))
 358.467 +			{
 358.468 +				cDataEnd = P - 2;
 358.469 +			}
 358.470 +
 358.471 +			++P;
 358.472 +		}
 358.473 +
 358.474 +		if ( cDataEnd )
 358.475 +			NodeName = core::string<char_type>(cDataBegin, (int)(cDataEnd - cDataBegin));
 358.476 +		else
 358.477 +			NodeName = "";
 358.478 +
 358.479 +		return true;
 358.480 +	}
 358.481 +
 358.482 +
 358.483 +	// structure for storing attribute-name pairs
 358.484 +	struct SAttribute
 358.485 +	{
 358.486 +		core::string<char_type> Name;
 358.487 +		core::string<char_type> Value;
 358.488 +	};
 358.489 +
 358.490 +	// finds a current attribute by name, returns 0 if not found
 358.491 +	const SAttribute* getAttributeByName(const char_type* name) const
 358.492 +	{
 358.493 +		if (!name)
 358.494 +			return 0;
 358.495 +
 358.496 +		core::string<char_type> n = name;
 358.497 +
 358.498 +		for (int i=0; i<(int)Attributes.size(); ++i)
 358.499 +			if (Attributes[i].Name == n)
 358.500 +				return &Attributes[i];
 358.501 +
 358.502 +		return 0;
 358.503 +	}
 358.504 +
 358.505 +	// replaces xml special characters in a string and creates a new one
 358.506 +	core::string<char_type> replaceSpecialCharacters(
 358.507 +		core::string<char_type>& origstr)
 358.508 +	{
 358.509 +		int pos = origstr.findFirst(L'&');
 358.510 +		int oldPos = 0;
 358.511 +
 358.512 +		if (pos == -1)
 358.513 +			return origstr;
 358.514 +
 358.515 +		core::string<char_type> newstr;
 358.516 +
 358.517 +		while(pos != -1 && pos < origstr.size()-2)
 358.518 +		{
 358.519 +			// check if it is one of the special characters
 358.520 +
 358.521 +			int specialChar = -1;
 358.522 +			for (int i=0; i<(int)SpecialCharacters.size(); ++i)
 358.523 +			{
 358.524 +				const char_type* p = &origstr.c_str()[pos]+1;
 358.525 +
 358.526 +				if (equalsn(&SpecialCharacters[i][1], p, SpecialCharacters[i].size()-1))
 358.527 +				{
 358.528 +					specialChar = i;
 358.529 +					break;
 358.530 +				}
 358.531 +			}
 358.532 +
 358.533 +			if (specialChar != -1)
 358.534 +			{
 358.535 +				newstr.append(origstr.subString(oldPos, pos - oldPos));
 358.536 +				newstr.append(SpecialCharacters[specialChar][0]);
 358.537 +				pos += SpecialCharacters[specialChar].size();
 358.538 +			}
 358.539 +			else
 358.540 +			{
 358.541 +				newstr.append(origstr.subString(oldPos, pos - oldPos + 1));
 358.542 +				pos += 1;
 358.543 +			}
 358.544 +
 358.545 +			// find next &
 358.546 +			oldPos = pos;
 358.547 +			pos = origstr.findNext(L'&', pos);		
 358.548 +		}
 358.549 +
 358.550 +		if (oldPos < origstr.size()-1)
 358.551 +			newstr.append(origstr.subString(oldPos, origstr.size()-oldPos));
 358.552 +
 358.553 +		return newstr;
 358.554 +	}
 358.555 +
 358.556 +
 358.557 +
 358.558 +	//! reads the xml file and converts it into the wanted character format.
 358.559 +	bool readFile(IFileReadCallBack* callback)
 358.560 +	{
 358.561 +		int size = callback->getSize();		
 358.562 +		size += 4; // We need two terminating 0's at the end.
 358.563 +		           // For ASCII we need 1 0's, for UTF-16 2, for UTF-32 4.
 358.564 +
 358.565 +		char* data8 = new char[size];
 358.566 +
 358.567 +		if (!callback->read(data8, size-4))
 358.568 +		{
 358.569 +			delete [] data8;
 358.570 +			return false;
 358.571 +		}
 358.572 +
 358.573 +		// add zeros at end
 358.574 +
 358.575 +		data8[size-1] = 0;
 358.576 +		data8[size-2] = 0;
 358.577 +		data8[size-3] = 0;
 358.578 +		data8[size-4] = 0;
 358.579 +
 358.580 +		char16* data16 = reinterpret_cast<char16*>(data8);
 358.581 +		char32* data32 = reinterpret_cast<char32*>(data8);	
 358.582 +
 358.583 +		// now we need to convert the data to the desired target format
 358.584 +		// based on the byte order mark.
 358.585 +
 358.586 +		const unsigned char UTF8[] = {0xEF, 0xBB, 0xBF}; // 0xEFBBBF;
 358.587 +		const int UTF16_BE = 0xFFFE;
 358.588 +		const int UTF16_LE = 0xFEFF;
 358.589 +		const int UTF32_BE = 0xFFFE0000;
 358.590 +		const int UTF32_LE = 0x0000FEFF;
 358.591 +
 358.592 +		// check source for all utf versions and convert to target data format
 358.593 +		
 358.594 +		if (size >= 4 && data32[0] == (char32)UTF32_BE)
 358.595 +		{
 358.596 +			// UTF-32, big endian
 358.597 +			SourceFormat = ETF_UTF32_BE;
 358.598 +			convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header
 358.599 +		}
 358.600 +		else
 358.601 +		if (size >= 4 && data32[0] == (char32)UTF32_LE)
 358.602 +		{
 358.603 +			// UTF-32, little endian
 358.604 +			SourceFormat = ETF_UTF32_LE;
 358.605 +			convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header
 358.606 +		}
 358.607 +		else
 358.608 +		if (size >= 2 && data16[0] == UTF16_BE)
 358.609 +		{
 358.610 +			// UTF-16, big endian
 358.611 +			SourceFormat = ETF_UTF16_BE;
 358.612 +			convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header
 358.613 +		}
 358.614 +		else
 358.615 +		if (size >= 2 && data16[0] == UTF16_LE)
 358.616 +		{
 358.617 +			// UTF-16, little endian
 358.618 +			SourceFormat = ETF_UTF16_LE;
 358.619 +			convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header
 358.620 +		}
 358.621 +		else
 358.622 +		if (size >= 3 && data8[0] == UTF8[0] && data8[1] == UTF8[1] && data8[2] == UTF8[2])
 358.623 +		{
 358.624 +			// UTF-8
 358.625 +			SourceFormat = ETF_UTF8;
 358.626 +			convertTextData(data8+3, data8, size); // data8+3 because we need to skip the header
 358.627 +		}
 358.628 +		else
 358.629 +		{
 358.630 +			// ASCII
 358.631 +			SourceFormat = ETF_ASCII;
 358.632 +			convertTextData(data8, data8, size);
 358.633 +		}
 358.634 +
 358.635 +		return true;
 358.636 +	}
 358.637 +
 358.638 +
 358.639 +	//! converts the text file into the desired format.
 358.640 +	//! \param source: begin of the text (without byte order mark)
 358.641 +	//! \param pointerToStore: pointer to text data block which can be
 358.642 +	//! stored or deleted based on the nesessary conversion.
 358.643 +	//! \param sizeWithoutHeader: Text size in characters without header
 358.644 +	template<class src_char_type>
 358.645 +	void convertTextData(src_char_type* source, char* pointerToStore, int sizeWithoutHeader)
 358.646 +	{
 358.647 +		// convert little to big endian if necessary
 358.648 +		if (sizeof(src_char_type) > 1 && 
 358.649 +			isLittleEndian(TargetFormat) != isLittleEndian(SourceFormat))
 358.650 +			convertToLittleEndian(source);
 358.651 +
 358.652 +		// check if conversion is necessary:
 358.653 +		if (sizeof(src_char_type) == sizeof(char_type))
 358.654 +		{
 358.655 +			// no need to convert
 358.656 +			TextBegin = (char_type*)source;
 358.657 +			TextData = (char_type*)pointerToStore;
 358.658 +			TextSize = sizeWithoutHeader;
 358.659 +		}
 358.660 +		else
 358.661 +		{
 358.662 +			// convert source into target data format. 
 358.663 +			// TODO: implement a real conversion. This one just 
 358.664 +			// copies bytes. This is a problem when there are 
 358.665 +			// unicode symbols using more than one character.
 358.666 +
 358.667 +			TextData = new char_type[sizeWithoutHeader];
 358.668 +
 358.669 +			// MSVC debugger complains here about loss of data ...
 358.670 +
 358.671 +
 358.672 +			// FIXME - gcc complains about 'shift width larger than width of type'
 358.673 +			// for T == unsigned long. Avoid it by messing around volatile ..
 358.674 +			volatile unsigned int c = 3;
 358.675 +			const src_char_type cc = (src_char_type)((((uint64_t)1u << (sizeof( char_type)<<c)) - 1));
 358.676 +			for (int i=0; i<sizeWithoutHeader; ++i)
 358.677 +				TextData[i] = char_type( source[i] & cc); 
 358.678 +
 358.679 +			TextBegin = TextData;
 358.680 +			TextSize = sizeWithoutHeader;
 358.681 +
 358.682 +			// delete original data because no longer needed
 358.683 +			delete [] pointerToStore;
 358.684 +		}
 358.685 +	}
 358.686 +
 358.687 +	//! converts whole text buffer to little endian
 358.688 +	template<class src_char_type>
 358.689 +	void convertToLittleEndian(src_char_type* t)
 358.690 +	{
 358.691 +		if (sizeof(src_char_type) == 4) 
 358.692 +		{
 358.693 +			// 32 bit
 358.694 +
 358.695 +			while(*t)
 358.696 +			{
 358.697 +				*t = ((*t & 0xff000000) >> 24) |
 358.698 +				     ((*t & 0x00ff0000) >> 8)  |
 358.699 +				     ((*t & 0x0000ff00) << 8)  |
 358.700 +				     ((*t & 0x000000ff) << 24);
 358.701 +				++t;
 358.702 +			}
 358.703 +		}
 358.704 +		else
 358.705 +		{
 358.706 +			// 16 bit 
 358.707 +
 358.708 +			while(*t)
 358.709 +			{
 358.710 +				*t = (*t >> 8) | (*t << 8);
 358.711 +				++t;
 358.712 +			}
 358.713 +		}
 358.714 +	}
 358.715 +
 358.716 +	//! returns if a format is little endian
 358.717 +	inline bool isLittleEndian(ETEXT_FORMAT f)
 358.718 +	{
 358.719 +		return f == ETF_ASCII ||
 358.720 +		       f == ETF_UTF8 ||
 358.721 +		       f == ETF_UTF16_LE ||
 358.722 +		       f == ETF_UTF32_LE;
 358.723 +	}
 358.724 +
 358.725 +
 358.726 +	//! returns true if a character is whitespace
 358.727 +	inline bool isWhiteSpace(char_type c)
 358.728 +	{
 358.729 +		return (c==' ' || c=='\t' || c=='\n' || c=='\r');
 358.730 +	}
 358.731 +
 358.732 +
 358.733 +	//! generates a list with xml special characters
 358.734 +	void createSpecialCharacterList()
 358.735 +	{
 358.736 +		// list of strings containing special symbols, 
 358.737 +		// the first character is the special character,
 358.738 +		// the following is the symbol string without trailing &.
 358.739 +
 358.740 +		SpecialCharacters.push_back("&amp;");
 358.741 +		SpecialCharacters.push_back("<lt;");
 358.742 +		SpecialCharacters.push_back(">gt;");
 358.743 +		SpecialCharacters.push_back("\"quot;");
 358.744 +		SpecialCharacters.push_back("'apos;");
 358.745 +		
 358.746 +	}
 358.747 +
 358.748 +
 358.749 +	//! compares the first n characters of the strings
 358.750 +	bool equalsn(const char_type* str1, const char_type* str2, int len)
 358.751 +	{
 358.752 +		int i;
 358.753 +		for(i=0; str1[i] && str2[i] && i < len; ++i)
 358.754 +			if (str1[i] != str2[i])
 358.755 +				return false;
 358.756 +
 358.757 +		// if one (or both) of the strings was smaller then they
 358.758 +		// are only equal if they have the same lenght
 358.759 +		return (i == len) || (str1[i] == 0 && str2[i] == 0);
 358.760 +	}
 358.761 +
 358.762 +
 358.763 +	//! stores the target text format
 358.764 +	void storeTargetFormat()
 358.765 +	{
 358.766 +		// get target format. We could have done this using template specialization,
 358.767 +		// but VisualStudio 6 don't like it and we want to support it.
 358.768 +
 358.769 +		switch(sizeof(char_type))
 358.770 +		{
 358.771 +		case 1: 
 358.772 +			TargetFormat = ETF_UTF8;
 358.773 +			break;
 358.774 +		case 2: 
 358.775 +			TargetFormat = ETF_UTF16_LE;
 358.776 +			break;
 358.777 +		case 4: 
 358.778 +			TargetFormat = ETF_UTF32_LE;
 358.779 +			break;
 358.780 +		default:
 358.781 +			TargetFormat = ETF_ASCII; // should never happen.
 358.782 +		}
 358.783 +	}
 358.784 +
 358.785 +
 358.786 +	// instance variables:
 358.787 +
 358.788 +	char_type* TextData;         // data block of the text file
 358.789 +	char_type* P;                // current point in text to parse
 358.790 +	char_type* TextBegin;        // start of text to parse
 358.791 +	unsigned int TextSize;       // size of text to parse in characters, not bytes
 358.792 +
 358.793 +	EXML_NODE CurrentNodeType;   // type of the currently parsed node
 358.794 +	ETEXT_FORMAT SourceFormat;   // source format of the xml file
 358.795 +	ETEXT_FORMAT TargetFormat;   // output format of this parser
 358.796 +
 358.797 +	core::string<char_type> NodeName;    // name of the node currently in
 358.798 +	core::string<char_type> EmptyString; // empty string to be returned by getSafe() methods
 358.799 +
 358.800 +	bool IsEmptyElement;       // is the currently parsed node empty?
 358.801 +
 358.802 +	core::array< core::string<char_type> > SpecialCharacters; // see createSpecialCharacterList()
 358.803 +
 358.804 +	core::array<SAttribute> Attributes; // attributes of current element
 358.805 +	
 358.806 +}; // end CXMLReaderImpl
 358.807 +
 358.808 +
 358.809 +} // end namespace
 358.810 +} // end namespace
 358.811 +
 358.812 +#endif
   359.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   359.2 +++ b/libs/assimp/irrXML/heapsort.h	Sat Feb 01 19:58:19 2014 +0200
   359.3 @@ -0,0 +1,73 @@
   359.4 +// Copyright (C) 2002-2005 Nikolaus Gebhardt
   359.5 +// This file is part of the "Irrlicht Engine".
   359.6 +// For conditions of distribution and use, see copyright notice in irrlicht.h
   359.7 +
   359.8 +#ifndef __IRR_HEAPSORT_H_INCLUDED__
   359.9 +#define __IRR_HEAPSORT_H_INCLUDED__
  359.10 +
  359.11 +#include "irrTypes.h"
  359.12 +
  359.13 +namespace irr
  359.14 +{
  359.15 +namespace core
  359.16 +{
  359.17 +
  359.18 +//! Sinks an element into the heap.
  359.19 +template<class T>
  359.20 +inline void heapsink(T*array, s32 element, s32 max)
  359.21 +{
  359.22 +	while ((element<<1) < max)	// there is a left child
  359.23 +	{
  359.24 +		s32 j = (element<<1);
  359.25 +	
  359.26 +		if (j+1 < max && array[j] < array[j+1])
  359.27 +			j = j+1;							// take right child
  359.28 +
  359.29 +		if (array[element] < array[j])
  359.30 +		{
  359.31 +			T t = array[j];						// swap elements
  359.32 +			array[j] = array[element];
  359.33 +			array[element] = t;
  359.34 +			element = j;
  359.35 +		}
  359.36 +		else
  359.37 +			return;
  359.38 +	}
  359.39 +}
  359.40 +
  359.41 +
  359.42 +//! Sorts an array with size 'size' using heapsort.
  359.43 +template<class T>
  359.44 +inline void heapsort(T* array_, s32 size)
  359.45 +{
  359.46 +	// for heapsink we pretent this is not c++, where
  359.47 +	// arrays start with index 0. So we decrease the array pointer,
  359.48 +	// the maximum always +2 and the element always +1
  359.49 +
  359.50 +	T* virtualArray = array_ - 1;
  359.51 +	s32 virtualSize = size + 2;
  359.52 +	s32 i;
  359.53 +
  359.54 +	// build heap
  359.55 +
  359.56 +	for (i=((size-1)/2); i>=0; --i)	
  359.57 +		heapsink(virtualArray, i+1, virtualSize-1);
  359.58 +
  359.59 +	// sort array
  359.60 +
  359.61 +	for (i=size-1; i>=0; --i)	
  359.62 +	{
  359.63 +		T t = array_[0];
  359.64 +		array_[0] = array_[i];
  359.65 +		array_[i] = t;
  359.66 +		heapsink(virtualArray, 1, i + 1);
  359.67 +	}
  359.68 +}
  359.69 +
  359.70 +} // end namespace core
  359.71 +} // end namespace irr
  359.72 +
  359.73 +
  359.74 +
  359.75 +#endif
  359.76 +
   360.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   360.2 +++ b/libs/assimp/irrXML/irrArray.h	Sat Feb 01 19:58:19 2014 +0200
   360.3 @@ -0,0 +1,444 @@
   360.4 +// Copyright (C) 2002-2005 Nikolaus Gebhardt
   360.5 +// This file is part of the "Irrlicht Engine" and the "irrXML" project.
   360.6 +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
   360.7 +
   360.8 +#ifndef __IRR_ARRAY_H_INCLUDED__
   360.9 +#define __IRR_ARRAY_H_INCLUDED__
  360.10 +
  360.11 +#include "irrTypes.h"
  360.12 +#include "heapsort.h"
  360.13 +
  360.14 +namespace irr
  360.15 +{
  360.16 +namespace core
  360.17 +{
  360.18 +
  360.19 +//!	Self reallocating template array (like stl vector) with additional features.
  360.20 +/** Some features are: Heap sorting, binary search methods, easier debugging.
  360.21 +*/
  360.22 +template <class T>
  360.23 +class array
  360.24 +{
  360.25 +
  360.26 +public:
  360.27 +
  360.28 +	array()
  360.29 +		: data(0), allocated(0), used(0),
  360.30 +			free_when_destroyed(true), is_sorted(true)
  360.31 +	{
  360.32 +	}
  360.33 +
  360.34 +	//! Constructs a array and allocates an initial chunk of memory.
  360.35 +	//! \param start_count: Amount of elements to allocate.
  360.36 +	array(u32 start_count)
  360.37 +		: data(0), allocated(0), used(0),
  360.38 +			free_when_destroyed(true),	is_sorted(true)
  360.39 +	{
  360.40 +		reallocate(start_count);
  360.41 +	}
  360.42 +
  360.43 +
  360.44 +	//! Copy constructor
  360.45 +	array(const array<T>& other)
  360.46 +		: data(0)
  360.47 +	{
  360.48 +		*this = other;
  360.49 +	}
  360.50 +
  360.51 +
  360.52 +
  360.53 +	//! Destructor. Frees allocated memory, if set_free_when_destroyed
  360.54 +	//! was not set to false by the user before.
  360.55 +	~array()
  360.56 +	{
  360.57 +		if (free_when_destroyed)
  360.58 +			delete [] data;
  360.59 +	}
  360.60 +
  360.61 +
  360.62 +
  360.63 +	//! Reallocates the array, make it bigger or smaller.
  360.64 +	//! \param new_size: New size of array.
  360.65 +	void reallocate(u32 new_size)
  360.66 +	{
  360.67 +		T* old_data = data;
  360.68 +
  360.69 +		data = new T[new_size];
  360.70 +		allocated = new_size;
  360.71 +		
  360.72 +		s32 end = used < new_size ? used : new_size;
  360.73 +		for (s32 i=0; i<end; ++i)
  360.74 +			data[i] = old_data[i];
  360.75 +
  360.76 +		if (allocated < used)
  360.77 +			used = allocated;
  360.78 +		
  360.79 +		delete [] old_data;
  360.80 +	}
  360.81 +
  360.82 +	//! Adds an element at back of array. If the array is to small to 
  360.83 +	//! add this new element, the array is made bigger.
  360.84 +	//! \param element: Element to add at the back of the array.
  360.85 +	void push_back(const T& element)
  360.86 +	{
  360.87 +		if (used + 1 > allocated)
  360.88 +		{
  360.89 +			// reallocate(used * 2 +1);
  360.90 +			// this doesn't work if the element is in the same array. So
  360.91 +			// we'll copy the element first to be sure we'll get no data
  360.92 +			// corruption
  360.93 +
  360.94 +			T e;
  360.95 +			e = element;           // copy element
  360.96 +			reallocate(used * 2 +1); // increase data block
  360.97 +			data[used++] = e;        // push_back
  360.98 +			is_sorted = false; 
  360.99 +			return;
 360.100 +		}
 360.101 +
 360.102 +		data[used++] = element;
 360.103 +		is_sorted = false;
 360.104 +	}
 360.105 +
 360.106 +
 360.107 +	//! Adds an element at the front of the array. If the array is to small to 
 360.108 +	//! add this new element, the array is made bigger. Please note that this
 360.109 +	//! is slow, because the whole array needs to be copied for this.
 360.110 +	//! \param element: Element to add at the back of the array.
 360.111 +	void push_front(const T& element)
 360.112 +	{
 360.113 +		if (used + 1 > allocated)
 360.114 +			reallocate(used * 2 +1);
 360.115 +
 360.116 +		for (int i=(int)used; i>0; --i)
 360.117 +			data[i] = data[i-1];
 360.118 +
 360.119 +		data[0] = element;
 360.120 +		is_sorted = false;
 360.121 +		++used;
 360.122 +	}
 360.123 +
 360.124 +	
 360.125 +	//! Insert item into array at specified position. Please use this
 360.126 +	//! only if you know what you are doing (possible performance loss). 
 360.127 +	//! The preferred method of adding elements should be push_back().
 360.128 +	//! \param element: Element to be inserted
 360.129 +	//! \param index: Where position to insert the new element.
 360.130 +	void insert(const T& element, u32 index=0) 
 360.131 +	{
 360.132 +		_IRR_DEBUG_BREAK_IF(index>used) // access violation
 360.133 +
 360.134 +		if (used + 1 > allocated)
 360.135 +			reallocate(used * 2 +1);
 360.136 +
 360.137 +		for (u32 i=used++; i>index; i--) 
 360.138 +			data[i] = data[i-1];
 360.139 +
 360.140 +		data[index] = element;
 360.141 +		is_sorted = false;
 360.142 +	}
 360.143 +
 360.144 +
 360.145 +
 360.146 +
 360.147 +	//! Clears the array and deletes all allocated memory.
 360.148 +	void clear()
 360.149 +	{
 360.150 +		delete [] data;
 360.151 +		data = 0;
 360.152 +		used = 0;
 360.153 +		allocated = 0;
 360.154 +		is_sorted = true;
 360.155 +	}
 360.156 +
 360.157 +
 360.158 +
 360.159 +	//! Sets pointer to new array, using this as new workspace.
 360.160 +	//! \param newPointer: Pointer to new array of elements.
 360.161 +	//! \param size: Size of the new array.
 360.162 +	void set_pointer(T* newPointer, u32 size)
 360.163 +	{
 360.164 +		delete [] data;
 360.165 +		data = newPointer;
 360.166 +		allocated = size;
 360.167 +		used = size;
 360.168 +		is_sorted = false;
 360.169 +	}
 360.170 +
 360.171 +
 360.172 +
 360.173 +	//! Sets if the array should delete the memory it used.
 360.174 +	//! \param f: If true, the array frees the allocated memory in its
 360.175 +	//! destructor, otherwise not. The default is true.
 360.176 +	void set_free_when_destroyed(bool f)
 360.177 +	{
 360.178 +		free_when_destroyed = f;
 360.179 +	}
 360.180 +
 360.181 +
 360.182 +
 360.183 +	//! Sets the size of the array.
 360.184 +	//! \param usedNow: Amount of elements now used.
 360.185 +	void set_used(u32 usedNow)
 360.186 +	{
 360.187 +		if (allocated < usedNow)
 360.188 +			reallocate(usedNow);
 360.189 +
 360.190 +		used = usedNow;
 360.191 +	}
 360.192 +
 360.193 +
 360.194 +
 360.195 +	//! Assignement operator
 360.196 +	void operator=(const array<T>& other)
 360.197 +	{
 360.198 +		if (data)
 360.199 +			delete [] data;
 360.200 +
 360.201 +		//if (allocated < other.allocated)
 360.202 +		if (other.allocated == 0)
 360.203 +			data = 0;
 360.204 +		else
 360.205 +			data = new T[other.allocated];
 360.206 +
 360.207 +		used = other.used;
 360.208 +		free_when_destroyed = other.free_when_destroyed;
 360.209 +		is_sorted = other.is_sorted;
 360.210 +		allocated = other.allocated;
 360.211 +
 360.212 +		for (u32 i=0; i<other.used; ++i)
 360.213 +			data[i] = other.data[i];
 360.214 +	}
 360.215 +
 360.216 +
 360.217 +	//! Direct access operator
 360.218 +	T& operator [](u32 index)
 360.219 +	{
 360.220 +		_IRR_DEBUG_BREAK_IF(index>=used) // access violation
 360.221 +
 360.222 +		return data[index];
 360.223 +	}
 360.224 +
 360.225 +
 360.226 +
 360.227 +	//! Direct access operator
 360.228 +	const T& operator [](u32 index) const
 360.229 +	{
 360.230 +		_IRR_DEBUG_BREAK_IF(index>=used) // access violation
 360.231 +
 360.232 +		return data[index];
 360.233 +	}
 360.234 +
 360.235 +    //! Gets last frame
 360.236 +	const T& getLast() const
 360.237 +	{
 360.238 +		_IRR_DEBUG_BREAK_IF(!used) // access violation
 360.239 +
 360.240 +		return data[used-1];
 360.241 +	}
 360.242 +
 360.243 +    //! Gets last frame
 360.244 +	T& getLast()
 360.245 +	{
 360.246 +		_IRR_DEBUG_BREAK_IF(!used) // access violation
 360.247 +
 360.248 +		return data[used-1];
 360.249 +	}
 360.250 +    
 360.251 +
 360.252 +	//! Returns a pointer to the array.
 360.253 +	//! \return Pointer to the array.
 360.254 +	T* pointer()
 360.255 +	{
 360.256 +		return data;
 360.257 +	}
 360.258 +
 360.259 +
 360.260 +
 360.261 +	//! Returns a const pointer to the array.
 360.262 +	//! \return Pointer to the array.
 360.263 +	const T* const_pointer() const
 360.264 +	{
 360.265 +		return data;
 360.266 +	}
 360.267 +
 360.268 +
 360.269 +
 360.270 +	//! Returns size of used array.
 360.271 +	//! \return Size of elements in the array.
 360.272 +	u32 size() const
 360.273 +	{
 360.274 +		return used;
 360.275 +	}
 360.276 +
 360.277 +
 360.278 +
 360.279 +	//! Returns amount memory allocated.
 360.280 +	//! \return Returns amount of memory allocated. The amount of bytes
 360.281 +	//! allocated would  be allocated_size() * sizeof(ElementsUsed);
 360.282 +	u32 allocated_size() const
 360.283 +	{
 360.284 +		return allocated;
 360.285 +	}
 360.286 +
 360.287 +
 360.288 +
 360.289 +	//! Returns true if array is empty
 360.290 +	//! \return True if the array is empty, false if not.
 360.291 +	bool empty() const
 360.292 +	{
 360.293 +		return used == 0;
 360.294 +	}
 360.295 +
 360.296 +
 360.297 +
 360.298 +	//! Sorts the array using heapsort. There is no additional memory waste and
 360.299 +	//! the algorithm performs (O) n log n in worst case.
 360.300 +	void sort()
 360.301 +	{
 360.302 +		if (is_sorted || used<2)
 360.303 +			return;
 360.304 +
 360.305 +		heapsort(data, used);
 360.306 +		is_sorted = true;
 360.307 +	}
 360.308 +
 360.309 +
 360.310 +
 360.311 +	//! Performs a binary search for an element, returns -1 if not found.
 360.312 +	//! The array will be sorted before the binary search if it is not
 360.313 +	//! already sorted.
 360.314 +	//! \param element: Element to search for.
 360.315 +	//! \return Returns position of the searched element if it was found,
 360.316 +	//! otherwise -1 is returned.
 360.317 +	s32 binary_search(const T& element)
 360.318 +	{
 360.319 +		return binary_search(element, 0, used-1);
 360.320 +	}
 360.321 +
 360.322 +
 360.323 +
 360.324 +	//! Performs a binary search for an element, returns -1 if not found.
 360.325 +	//! The array will be sorted before the binary search if it is not
 360.326 +	//! already sorted.
 360.327 +	//! \param element: Element to search for.
 360.328 +	//! \param left: First left index
 360.329 +	//! \param right: Last right index.
 360.330 +	//! \return Returns position of the searched element if it was found,
 360.331 +	//! otherwise -1 is returned.
 360.332 +	s32 binary_search(const T& element, s32 left, s32 right)
 360.333 +	{
 360.334 +		if (!used)
 360.335 +			return -1;
 360.336 +
 360.337 +		sort();
 360.338 +
 360.339 +		s32 m;
 360.340 +
 360.341 +		do
 360.342 +		{
 360.343 +			m = (left+right)>>1;
 360.344 +
 360.345 +			if (element < data[m])
 360.346 +				right = m - 1;
 360.347 +			else
 360.348 +				left = m + 1;
 360.349 +
 360.350 +		} while((element < data[m] || data[m] < element) && left<=right);
 360.351 +
 360.352 +		// this last line equals to:
 360.353 +		// " while((element != array[m]) && left<=right);"
 360.354 +		// but we only want to use the '<' operator.
 360.355 +		// the same in next line, it is "(element == array[m])"
 360.356 +
 360.357 +		if (!(element < data[m]) && !(data[m] < element))
 360.358 +			return m;
 360.359 +
 360.360 +		return -1;
 360.361 +	}
 360.362 +
 360.363 +
 360.364 +	//! Finds an element in linear time, which is very slow. Use
 360.365 +	//! binary_search for faster finding. Only works if =operator is implemented.
 360.366 +	//! \param element: Element to search for.
 360.367 +	//! \return Returns position of the searched element if it was found,
 360.368 +	//! otherwise -1 is returned.
 360.369 +	s32 linear_search(T& element)
 360.370 +	{
 360.371 +		for (u32 i=0; i<used; ++i)
 360.372 +			if (!(element < data[i]) && !(data[i] < element))
 360.373 +				return (s32)i;
 360.374 +
 360.375 +		return -1;
 360.376 +	}
 360.377 +
 360.378 +
 360.379 +	//! Finds an element in linear time, which is very slow. Use
 360.380 +	//! binary_search for faster finding. Only works if =operator is implemented.
 360.381 +	//! \param element: Element to search for.
 360.382 +	//! \return Returns position of the searched element if it was found,
 360.383 +	//! otherwise -1 is returned.
 360.384 +	s32 linear_reverse_search(T& element)
 360.385 +	{
 360.386 +		for (s32 i=used-1; i>=0; --i)
 360.387 +			if (data[i] == element)
 360.388 +				return (s32)i;
 360.389 +
 360.390 +		return -1;
 360.391 +	}
 360.392 +
 360.393 +
 360.394 +
 360.395 +	//! Erases an element from the array. May be slow, because all elements 
 360.396 +	//! following after the erased element have to be copied.
 360.397 +	//! \param index: Index of element to be erased.
 360.398 +	void erase(u32 index)
 360.399 +	{
 360.400 +		_IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation
 360.401 +
 360.402 +		for (u32 i=index+1; i<used; ++i)
 360.403 +			data[i-1] = data[i];
 360.404 +
 360.405 +		--used;
 360.406 +	}
 360.407 +
 360.408 +
 360.409 +	//! Erases some elements from the array. may be slow, because all elements 
 360.410 +	//! following after the erased element have to be copied.
 360.411 +	//! \param index: Index of the first element to be erased.
 360.412 +	//! \param count: Amount of elements to be erased.
 360.413 +	void erase(u32 index, s32 count)
 360.414 +	{
 360.415 +		_IRR_DEBUG_BREAK_IF(index>=used || index<0 || count<1 || index+count>used) // access violation
 360.416 +
 360.417 +		for (u32 i=index+count; i<used; ++i)
 360.418 +			data[i-count] = data[i];
 360.419 +
 360.420 +		used-= count;
 360.421 +	}
 360.422 +
 360.423 +
 360.424 +	//! Sets if the array is sorted
 360.425 +	void set_sorted(bool _is_sorted)
 360.426 +	{
 360.427 +		is_sorted = _is_sorted;
 360.428 +	}
 360.429 +
 360.430 +			
 360.431 +	private:
 360.432 +
 360.433 +		T* data;
 360.434 +		u32 allocated;
 360.435 +		u32 used;
 360.436 +		bool free_when_destroyed;
 360.437 +		bool is_sorted;
 360.438 +};
 360.439 +
 360.440 +
 360.441 +} // end namespace core
 360.442 +} // end namespace irr
 360.443 +
 360.444 +
 360.445 +
 360.446 +#endif
 360.447 +
   361.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   361.2 +++ b/libs/assimp/irrXML/irrString.h	Sat Feb 01 19:58:19 2014 +0200
   361.3 @@ -0,0 +1,664 @@
   361.4 +// Copyright (C) 2002-2005 Nikolaus Gebhardt
   361.5 +// This file is part of the "Irrlicht Engine" and the "irrXML" project.
   361.6 +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
   361.7 +
   361.8 +#ifndef __IRR_STRING_H_INCLUDED__
   361.9 +#define __IRR_STRING_H_INCLUDED__
  361.10 +
  361.11 +#include "irrTypes.h"
  361.12 +
  361.13 +namespace irr
  361.14 +{
  361.15 +namespace core
  361.16 +{
  361.17 +
  361.18 +//!	Very simple string class with some useful features.
  361.19 +/**	string<c8> and string<wchar_t> work both with unicode AND ascii,
  361.20 +so you can assign unicode to string<c8> and ascii to string<wchar_t> 
  361.21 +(and the other way round) if your ever would want to. 
  361.22 +Note that the conversation between both is not done using an encoding.
  361.23 +
  361.24 +Known bugs:
  361.25 +Special characters like 'Ä', 'Ü' and 'Ö' are ignored in the
  361.26 +methods make_upper, make_lower and equals_ignore_case.
  361.27 +*/
  361.28 +template <class T>
  361.29 +class string
  361.30 +{
  361.31 +public:
  361.32 +
  361.33 +	//! Default constructor
  361.34 +	string()
  361.35 +	: array(0), allocated(1), used(1)
  361.36 +	{
  361.37 +		array = new T[1];
  361.38 +		array[0] = 0x0;
  361.39 +	}
  361.40 +
  361.41 +
  361.42 +
  361.43 +	//! Constructor
  361.44 +	string(const string<T>& other)
  361.45 +	: array(0), allocated(0), used(0)
  361.46 +	{
  361.47 +		*this = other;
  361.48 +	}
  361.49 +
  361.50 +
  361.51 +	//! Constructs a string from an int
  361.52 +	string(int number)
  361.53 +	: array(0), allocated(0), used(0)
  361.54 +	{
  361.55 +		// store if negative and make positive
  361.56 +
  361.57 +		bool negative = false;
  361.58 +		if (number < 0)
  361.59 +		{
  361.60 +			number *= -1;
  361.61 +			negative = true;
  361.62 +		}
  361.63 +
  361.64 +		// temporary buffer for 16 numbers
  361.65 +
  361.66 +		c8 tmpbuf[16];
  361.67 +		tmpbuf[15] = 0;
  361.68 +		s32 idx = 15;	
  361.69 +
  361.70 +		// special case '0'
  361.71 +
  361.72 +		if (!number) 
  361.73 +		{
  361.74 +			tmpbuf[14] = '0';
  361.75 +			*this = &tmpbuf[14];
  361.76 +			return;
  361.77 +		}
  361.78 +
  361.79 +		// add numbers
  361.80 +
  361.81 +		while(number && idx)
  361.82 +		{
  361.83 +			idx--;	
  361.84 +			tmpbuf[idx] = (c8)('0' + (number % 10));
  361.85 +			number = number / 10;					
  361.86 +		}
  361.87 +
  361.88 +		// add sign
  361.89 +
  361.90 +		if (negative)
  361.91 +		{
  361.92 +			idx--;
  361.93 +			tmpbuf[idx] = '-';			
  361.94 +		}
  361.95 +
  361.96 +		*this = &tmpbuf[idx];
  361.97 +	}
  361.98 +
  361.99 +
 361.100 +
 361.101 +	//! Constructor for copying a string from a pointer with a given lenght
 361.102 +	template <class B>
 361.103 +	string(const B* c, s32 lenght)
 361.104 +	: array(0), allocated(0), used(0)
 361.105 +	{
 361.106 +		if (!c)
 361.107 +			return;
 361.108 +
 361.109 +        allocated = used = lenght+1;
 361.110 +		array = new T[used];
 361.111 +
 361.112 +		for (s32 l = 0; l<lenght; ++l)
 361.113 +			array[l] = (T)c[l];
 361.114 +
 361.115 +		array[lenght] = 0;
 361.116 +	}
 361.117 +
 361.118 +
 361.119 +
 361.120 +	//! Constructor for unicode and ascii strings
 361.121 +	template <class B>
 361.122 +	string(const B* c)
 361.123 +	: array(0),allocated(0), used(0)
 361.124 +	{
 361.125 +		*this = c;
 361.126 +	}
 361.127 +
 361.128 +
 361.129 +
 361.130 +	//! destructor
 361.131 +	~string()
 361.132 +	{
 361.133 +		delete [] array;
 361.134 +	}
 361.135 +
 361.136 +
 361.137 +
 361.138 +	//! Assignment operator
 361.139 +	string<T>& operator=(const string<T>& other) 
 361.140 +	{
 361.141 +		if (this == &other)
 361.142 +			return *this;
 361.143 +
 361.144 +		delete [] array;
 361.145 +		allocated = used = other.size()+1;
 361.146 +		array = new T[used];
 361.147 +
 361.148 +		const T* p = other.c_str();
 361.149 +		for (s32 i=0; i<used; ++i, ++p)
 361.150 +			array[i] = *p;
 361.151 +
 361.152 +		return *this;
 361.153 +	}
 361.154 +
 361.155 +
 361.156 +
 361.157 +	//! Assignment operator for strings, ascii and unicode
 361.158 +	template <class B>
 361.159 +	string<T>& operator=(const B* c) 
 361.160 +	{
 361.161 +		if (!c)
 361.162 +		{
 361.163 +			if (!array)
 361.164 +			{
 361.165 +				array = new T[1];
 361.166 +				allocated = 1;
 361.167 +				used = 1;
 361.168 +			}
 361.169 +			array[0] = 0x0;
 361.170 +			return *this;
 361.171 +		}
 361.172 +
 361.173 +		if ((void*)c == (void*)array)
 361.174 +			return *this;
 361.175 +
 361.176 +		s32 len = 0;
 361.177 +		const B* p = c;
 361.178 +		while(*p)
 361.179 +		{
 361.180 +			++len;
 361.181 +			++p;
 361.182 +		}
 361.183 +
 361.184 +		// we'll take the old string for a while, because the new string could be
 361.185 +		// a part of the current string.
 361.186 +		T* oldArray = array;
 361.187 +
 361.188 +        allocated = used = len+1;
 361.189 +		array = new T[used];
 361.190 +
 361.191 +		for (s32 l = 0; l<len+1; ++l)
 361.192 +			array[l] = (T)c[l];
 361.193 +
 361.194 +		delete [] oldArray;
 361.195 +		return *this;
 361.196 +	}
 361.197 +
 361.198 +	//! Add operator for other strings
 361.199 +	string<T> operator+(const string<T>& other) 
 361.200 +	{ 
 361.201 +		string<T> str(*this); 
 361.202 +		str.append(other); 
 361.203 +
 361.204 +		return str; 
 361.205 +	} 
 361.206 +
 361.207 +	//! Add operator for strings, ascii and unicode 
 361.208 +	template <class B> 
 361.209 +	string<T> operator+(const B* c) 
 361.210 +	{ 
 361.211 +		string<T> str(*this); 
 361.212 +		str.append(c); 
 361.213 +
 361.214 +		return str; 
 361.215 +	}
 361.216 +
 361.217 +
 361.218 +
 361.219 +	//! Direct access operator
 361.220 +	T& operator [](const s32 index)  const
 361.221 +	{
 361.222 +		_IRR_DEBUG_BREAK_IF(index>=used) // bad index
 361.223 +
 361.224 +		return array[index];
 361.225 +	}
 361.226 +
 361.227 +
 361.228 +	//! Comparison operator
 361.229 +	bool operator ==(const T* str) const
 361.230 +	{
 361.231 +		int i;
 361.232 +		for(i=0; array[i] && str[i]; ++i)
 361.233 +			if (array[i] != str[i])
 361.234 +				return false;
 361.235 +
 361.236 +		return !array[i] && !str[i];
 361.237 +	}
 361.238 +
 361.239 +
 361.240 +
 361.241 +	//! Comparison operator
 361.242 +	bool operator ==(const string<T>& other) const
 361.243 +	{
 361.244 +		for(s32 i=0; array[i] && other.array[i]; ++i)
 361.245 +			if (array[i] != other.array[i])
 361.246 +				return false;
 361.247 +
 361.248 +		return used == other.used;
 361.249 +	}
 361.250 +
 361.251 +
 361.252 +
 361.253 +	//! Is smaller operator
 361.254 +	bool operator <(const string<T>& other) const
 361.255 +	{
 361.256 +		for(s32 i=0; array[i] && other.array[i]; ++i)
 361.257 +			if (array[i] != other.array[i])
 361.258 +				return (array[i] < other.array[i]);
 361.259 +
 361.260 +		return used < other.used;
 361.261 +	}
 361.262 +
 361.263 +
 361.264 +
 361.265 +	//! Equals not operator
 361.266 +	bool operator !=(const string<T>& other) const
 361.267 +	{
 361.268 +		return !(*this == other);
 361.269 +	}
 361.270 +
 361.271 +
 361.272 +    
 361.273 +	//! Returns length of string
 361.274 +	/** \return Returns length of the string in characters. */
 361.275 +	s32 size() const
 361.276 +	{
 361.277 +		return used-1;
 361.278 +	}
 361.279 +
 361.280 +
 361.281 +
 361.282 +	//! Returns character string
 361.283 +	/** \return Returns pointer to C-style zero terminated string. */
 361.284 +	const T* c_str() const
 361.285 +	{
 361.286 +		return array;
 361.287 +	}
 361.288 +
 361.289 +
 361.290 +
 361.291 +	//! Makes the string lower case.
 361.292 +	void make_lower()
 361.293 +	{
 361.294 +		const T A = (T)'A';
 361.295 +		const T Z = (T)'Z';
 361.296 +		const T diff = (T)'a' - A;
 361.297 +
 361.298 +		for (s32 i=0; i<used; ++i)
 361.299 +		{
 361.300 +			if (array[i]>=A && array[i]<=Z)
 361.301 +				array[i] += diff;
 361.302 +		}
 361.303 +	}
 361.304 +
 361.305 +
 361.306 +
 361.307 +	//! Makes the string upper case.
 361.308 +	void make_upper()
 361.309 +	{
 361.310 +		const T a = (T)'a';
 361.311 +		const T z = (T)'z';
 361.312 +		const T diff = (T)'A' - a;
 361.313 +
 361.314 +		for (s32 i=0; i<used; ++i)
 361.315 +		{
 361.316 +			if (array[i]>=a && array[i]<=z)
 361.317 +				array[i] += diff;
 361.318 +		}
 361.319 +	}
 361.320 +
 361.321 +
 361.322 +
 361.323 +	//! Compares the string ignoring case.
 361.324 +	/** \param other: Other string to compare.
 361.325 +	\return Returns true if the string are equal ignoring case. */
 361.326 +	bool equals_ignore_case(const string<T>& other) const
 361.327 +	{
 361.328 +		for(s32 i=0; array[i] && other[i]; ++i)
 361.329 +			if (toLower(array[i]) != toLower(other[i]))
 361.330 +				return false;
 361.331 +
 361.332 +		return used == other.used;
 361.333 +	}
 361.334 +
 361.335 +
 361.336 +	//! compares the first n characters of the strings
 361.337 +	bool equalsn(const string<T>& other, int len)
 361.338 +	{
 361.339 +		int i;
 361.340 +		for(i=0; array[i] && other[i] && i < len; ++i)
 361.341 +			if (array[i] != other[i])
 361.342 +				return false;
 361.343 +
 361.344 +		// if one (or both) of the strings was smaller then they
 361.345 +		// are only equal if they have the same lenght
 361.346 +		return (i == len) || (used == other.used);
 361.347 +	}
 361.348 +
 361.349 +
 361.350 +	//! compares the first n characters of the strings
 361.351 +	bool equalsn(const T* str, int len)
 361.352 +	{
 361.353 +		int i;	
 361.354 +		for(i=0; array[i] && str[i] && i < len; ++i)
 361.355 +			if (array[i] != str[i])
 361.356 +				return false;
 361.357 +
 361.358 +		// if one (or both) of the strings was smaller then they
 361.359 +		// are only equal if they have the same lenght
 361.360 +		return (i == len) || (array[i] == 0 && str[i] == 0);
 361.361 +	}
 361.362 +
 361.363 +
 361.364 +	//! Appends a character to this string
 361.365 +	/** \param character: Character to append. */
 361.366 +	void append(T character)
 361.367 +	{
 361.368 +		if (used + 1 > allocated)
 361.369 +			reallocate((s32)used + 1);
 361.370 +
 361.371 +		used += 1;
 361.372 +
 361.373 +		array[used-2] = character;
 361.374 +		array[used-1] = 0;
 361.375 +	}
 361.376 +
 361.377 +	//! Appends a string to this string
 361.378 +	/** \param other: String to append. */
 361.379 +	void append(const string<T>& other)
 361.380 +	{
 361.381 +		--used;
 361.382 +
 361.383 +		s32 len = other.size();
 361.384 +		
 361.385 +		if (used + len + 1 > allocated)
 361.386 +			reallocate((s32)used + (s32)len + 1);
 361.387 +
 361.388 +		for (s32 l=0; l<len+1; ++l)
 361.389 +			array[l+used] = other[l];
 361.390 +
 361.391 +		used = used + len + 1;
 361.392 +	}
 361.393 +
 361.394 +
 361.395 +	//! Appends a string of the length l to this string.
 361.396 +	/** \param other: other String to append to this string.
 361.397 +	 \param length: How much characters of the other string to add to this one. */
 361.398 +	void append(const string<T>& other, s32 length)
 361.399 +	{
 361.400 +		s32 len = other.size();
 361.401 +
 361.402 +		if (len < length)
 361.403 +		{
 361.404 +			append(other);
 361.405 +			return;
 361.406 +		}
 361.407 +
 361.408 +		len = length;
 361.409 +		--used;
 361.410 +		
 361.411 +		if (used + len > allocated)
 361.412 +			reallocate((s32)used + (s32)len);
 361.413 +
 361.414 +		for (s32 l=0; l<len; ++l)
 361.415 +			array[l+used] = other[l];
 361.416 +
 361.417 +		used = used + len;
 361.418 +	}
 361.419 +
 361.420 +
 361.421 +	//! Reserves some memory.
 361.422 +	/** \param count: Amount of characters to reserve. */
 361.423 +	void reserve(s32 count)
 361.424 +	{
 361.425 +		if (count < allocated)
 361.426 +			return;
 361.427 +
 361.428 +		reallocate(count);
 361.429 +	}
 361.430 +
 361.431 +
 361.432 +	//! finds first occurrence of character in string
 361.433 +	/** \param c: Character to search for.
 361.434 +	\return Returns position where the character has been found,
 361.435 +	or -1 if not found. */
 361.436 +	s32 findFirst(T c) const
 361.437 +	{
 361.438 +		for (s32 i=0; i<used; ++i)
 361.439 +			if (array[i] == c)
 361.440 +				return i;
 361.441 +
 361.442 +		return -1;
 361.443 +	}
 361.444 +
 361.445 +	//! finds first occurrence of a character of a list in string
 361.446 +	/** \param c: List of strings to find. For example if the method
 361.447 +	should find the first occurance of 'a' or 'b', this parameter should be "ab".
 361.448 +	\param count: Amount of characters in the list. Ususally, 
 361.449 +	this should be strlen(ofParameter1)
 361.450 +	\return Returns position where one of the character has been found,
 361.451 +	or -1 if not found. */
 361.452 +	s32 findFirstChar(T* c, int count) const
 361.453 +	{
 361.454 +		for (s32 i=0; i<used; ++i)
 361.455 +			for (int j=0; j<count; ++j)
 361.456 +				if (array[i] == c[j])
 361.457 +					return i;
 361.458 +
 361.459 +		return -1;
 361.460 +	}
 361.461 +
 361.462 +
 361.463 +	//! Finds first position of a character not in a given list.
 361.464 +	/** \param c: List of characters not to find. For example if the method
 361.465 +	 should find the first occurance of a character not 'a' or 'b', this parameter should be "ab".
 361.466 +	\param count: Amount of characters in the list. Ususally, 
 361.467 +	this should be strlen(ofParameter1)
 361.468 +	\return Returns position where the character has been found,
 361.469 +	or -1 if not found. */
 361.470 +	template <class B> 
 361.471 +	s32 findFirstCharNotInList(B* c, int count) const
 361.472 +	{
 361.473 +		for (int i=0; i<used; ++i)
 361.474 +		{
 361.475 +            int j;
 361.476 +			for (j=0; j<count; ++j)
 361.477 +				if (array[i] == c[j])
 361.478 +					break;
 361.479 +
 361.480 +			if (j==count)
 361.481 +				return i;
 361.482 +		}
 361.483 +
 361.484 +		return -1;
 361.485 +	}
 361.486 +
 361.487 +	//! Finds last position of a character not in a given list.
 361.488 +	/** \param c: List of characters not to find. For example if the method
 361.489 +	 should find the first occurance of a character not 'a' or 'b', this parameter should be "ab".
 361.490 +	\param count: Amount of characters in the list. Ususally, 
 361.491 +	this should be strlen(ofParameter1)
 361.492 +	\return Returns position where the character has been found,
 361.493 +	or -1 if not found. */
 361.494 +	template <class B> 
 361.495 +	s32 findLastCharNotInList(B* c, int count) const
 361.496 +	{
 361.497 +		for (int i=used-2; i>=0; --i)
 361.498 +		{
 361.499 +            int j;
 361.500 +			for (j=0; j<count; ++j)
 361.501 +				if (array[i] == c[j])
 361.502 +					break;
 361.503 +
 361.504 +			if (j==count)
 361.505 +				return i;
 361.506 +		}
 361.507 +
 361.508 +		return -1;
 361.509 +	}
 361.510 +
 361.511 +	//! finds next occurrence of character in string
 361.512 +	/** \param c: Character to search for.
 361.513 +	\param startPos: Position in string to start searching. 
 361.514 +	\return Returns position where the character has been found,
 361.515 +	or -1 if not found. */
 361.516 +	s32 findNext(T c, s32 startPos) const
 361.517 +	{
 361.518 +		for (s32 i=startPos; i<used; ++i)
 361.519 +			if (array[i] == c)
 361.520 +				return i;
 361.521 +
 361.522 +		return -1;
 361.523 +	}
 361.524 +
 361.525 +
 361.526 +	//! finds last occurrence of character in string
 361.527 +	//! \param c: Character to search for.
 361.528 +	//! \return Returns position where the character has been found,
 361.529 +	//! or -1 if not found.
 361.530 +	s32 findLast(T c) const
 361.531 +	{
 361.532 +		for (s32 i=used-1; i>=0; --i)
 361.533 +			if (array[i] == c)
 361.534 +				return i;
 361.535 +
 361.536 +		return -1;
 361.537 +	}
 361.538 +
 361.539 +
 361.540 +	//! Returns a substring
 361.541 +	//! \param begin: Start of substring.
 361.542 +	//! \param length: Length of substring.
 361.543 +	string<T> subString(s32 begin, s32 length)
 361.544 +	{
 361.545 +		if (length <= 0)
 361.546 +			return string<T>("");
 361.547 +
 361.548 +		string<T> o;
 361.549 +		o.reserve(length+1);
 361.550 +
 361.551 +		for (s32 i=0; i<length; ++i)
 361.552 +			o.array[i] = array[i+begin];
 361.553 +
 361.554 +		o.array[length] = 0;
 361.555 +		o.used = o.allocated;
 361.556 +
 361.557 +		return o;
 361.558 +	}
 361.559 +
 361.560 +
 361.561 +	void operator += (T c)
 361.562 +	{
 361.563 +		append(c);
 361.564 +	}
 361.565 +
 361.566 +	void operator += (const string<T>& other)
 361.567 +	{
 361.568 +		append(other);
 361.569 +	}
 361.570 +
 361.571 +	void operator += (int i)
 361.572 +	{
 361.573 +		append(string<T>(i));
 361.574 +	}
 361.575 +
 361.576 +	//! replaces all characters of a special type with another one
 361.577 +	void replace(T toReplace, T replaceWith)
 361.578 +	{
 361.579 +		for (s32 i=0; i<used; ++i)
 361.580 +			if (array[i] == toReplace)
 361.581 +				array[i] = replaceWith;
 361.582 +	}
 361.583 +
 361.584 +	//! trims the string.
 361.585 +	/** Removes whitespace from begin and end of the string. */
 361.586 +	void trim()
 361.587 +	{
 361.588 +		const char whitespace[] = " \t\n";
 361.589 +		const int whitespacecount = 3;
 361.590 +
 361.591 +		// find start and end of real string without whitespace
 361.592 +		int begin = findFirstCharNotInList(whitespace, whitespacecount);
 361.593 +		if (begin == -1)
 361.594 +			return;
 361.595 +
 361.596 +		int end = findLastCharNotInList(whitespace, whitespacecount);
 361.597 +		if (end == -1)
 361.598 +			return;
 361.599 +
 361.600 +		*this = subString(begin, (end +1) - begin);
 361.601 +	}
 361.602 +
 361.603 +
 361.604 +	//! Erases a character from the string. May be slow, because all elements 
 361.605 +	//! following after the erased element have to be copied.
 361.606 +	//! \param index: Index of element to be erased.
 361.607 +	void erase(int index)
 361.608 +	{
 361.609 +		_IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation
 361.610 +
 361.611 +		for (int i=index+1; i<used; ++i)
 361.612 +			array[i-1] = array[i];
 361.613 +
 361.614 +		--used;
 361.615 +	}
 361.616 +
 361.617 +    	
 361.618 +
 361.619 +private:
 361.620 +
 361.621 +	//! Returns a character converted to lower case
 361.622 +	T toLower(const T& t) const
 361.623 +	{
 361.624 +		if (t>=(T)'A' && t<=(T)'Z')
 361.625 +			return t + ((T)'a' - (T)'A');
 361.626 +		else
 361.627 +			return t;
 361.628 +	}
 361.629 +
 361.630 +	//! Reallocate the array, make it bigger or smaler
 361.631 +	void reallocate(s32 new_size)
 361.632 +	{
 361.633 +		T* old_array = array;
 361.634 +
 361.635 +		array = new T[new_size];
 361.636 +		allocated = new_size;
 361.637 +		
 361.638 +		s32 amount = used < new_size ? used : new_size;
 361.639 +		for (s32 i=0; i<amount; ++i)
 361.640 +			array[i] = old_array[i];
 361.641 +
 361.642 +		if (allocated < used)
 361.643 +			used = allocated;
 361.644 +		
 361.645 +		delete [] old_array;
 361.646 +	}
 361.647 +
 361.648 +
 361.649 +	//--- member variables
 361.650 +
 361.651 +	T* array;
 361.652 +	s32 allocated;
 361.653 +	s32 used;
 361.654 +};
 361.655 +
 361.656 +
 361.657 +//! Typedef for character strings
 361.658 +typedef string<irr::c8> stringc;
 361.659 +
 361.660 +//! Typedef for wide character strings
 361.661 +typedef string<wchar_t> stringw;
 361.662 +
 361.663 +} // end namespace core
 361.664 +} // end namespace irr
 361.665 +
 361.666 +#endif
 361.667 +
   362.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   362.2 +++ b/libs/assimp/irrXML/irrTypes.h	Sat Feb 01 19:58:19 2014 +0200
   362.3 @@ -0,0 +1,108 @@
   362.4 +// Copyright (C) 2002-2005 Nikolaus Gebhardt
   362.5 +// This file is part of the "Irrlicht Engine".
   362.6 +// For conditions of distribution and use, see copyright notice in irrlicht.h
   362.7 +
   362.8 +#ifndef __IRR_TYPES_H_INCLUDED__
   362.9 +#define __IRR_TYPES_H_INCLUDED__
  362.10 +
  362.11 +namespace irr
  362.12 +{
  362.13 +
  362.14 +//! 8 bit unsigned variable.
  362.15 +/** This is a typedef for unsigned char, it ensures portability of the engine. */
  362.16 +typedef unsigned char		u8; 
  362.17 +
  362.18 +//! 8 bit signed variable.
  362.19 +/** This is a typedef for signed char, it ensures portability of the engine. */
  362.20 +typedef signed char			s8; 
  362.21 +
  362.22 +//! 8 bit character variable.
  362.23 +/** This is a typedef for char, it ensures portability of the engine. */
  362.24 +typedef char				c8; 
  362.25 +
  362.26 +
  362.27 +
  362.28 +//! 16 bit unsigned variable.
  362.29 +/** This is a typedef for unsigned short, it ensures portability of the engine. */
  362.30 +typedef unsigned short		u16;
  362.31 +
  362.32 +//! 16 bit signed variable.
  362.33 +/** This is a typedef for signed short, it ensures portability of the engine. */
  362.34 +typedef signed short		s16; 
  362.35 +
  362.36 +
  362.37 +
  362.38 +//! 32 bit unsigned variable.
  362.39 +/** This is a typedef for unsigned int, it ensures portability of the engine. */
  362.40 +typedef unsigned int		u32;
  362.41 +
  362.42 +//! 32 bit signed variable.
  362.43 +/** This is a typedef for signed int, it ensures portability of the engine. */
  362.44 +typedef signed int			s32; 
  362.45 +
  362.46 +
  362.47 +
  362.48 +// 64 bit signed variable.
  362.49 +// This is a typedef for __int64, it ensures portability of the engine. 
  362.50 +// This type is currently not used by the engine and not supported by compilers
  362.51 +// other than Microsoft Compilers, so it is outcommented.
  362.52 +//typedef __int64				s64; 
  362.53 +
  362.54 +
  362.55 +
  362.56 +//! 32 bit floating point variable.
  362.57 +/** This is a typedef for float, it ensures portability of the engine. */
  362.58 +typedef float				f32; 
  362.59 +
  362.60 +//! 64 bit floating point variable.
  362.61 +/** This is a typedef for double, it ensures portability of the engine. */
  362.62 +typedef double				f64; 
  362.63 +
  362.64 +
  362.65 +} // end namespace
  362.66 +
  362.67 +
  362.68 +// define the wchar_t type if not already built in.
  362.69 +#ifdef _MSC_VER 
  362.70 +#ifndef _WCHAR_T_DEFINED
  362.71 +//! A 16 bit wide character type.
  362.72 +/**
  362.73 +	Defines the wchar_t-type.
  362.74 +	In VS6, its not possible to tell
  362.75 +	the standard compiler to treat wchar_t as a built-in type, and 
  362.76 +	sometimes we just don't want to include the huge stdlib.h or wchar.h,
  362.77 +	so we'll use this.
  362.78 +*/
  362.79 +typedef unsigned short wchar_t;
  362.80 +#define _WCHAR_T_DEFINED
  362.81 +#endif // wchar is not defined
  362.82 +#endif // microsoft compiler
  362.83 +
  362.84 +//! define a break macro for debugging only in Win32 mode.
  362.85 +// WORKAROUND (assimp): remove __asm
  362.86 +#if defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG)
  362.87 +#if defined(_M_IX86)
  362.88 +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) /*if (_CONDITION_) {_asm int 3}*/
  362.89 +#else
  362.90 +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ )
  362.91 +#endif
  362.92 +#else 
  362.93 +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ )
  362.94 +#endif
  362.95 +
  362.96 +//! Defines a small statement to work around a microsoft compiler bug.
  362.97 +/** The microsft compiler 7.0 - 7.1 has a bug:
  362.98 +When you call unmanaged code that returns a bool type value of false from managed code, 
  362.99 +the return value may appear as true. See 
 362.100 +http://support.microsoft.com/default.aspx?kbid=823071 for details. 
 362.101 +Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/
 362.102 +
 362.103 +// WORKAROUND (assimp): remove __asm 
 362.104 +#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400)
 362.105 +#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX /*__asm mov eax,100*/
 362.106 +#else
 362.107 +#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX
 362.108 +#endif // _IRR_MANAGED_MARSHALLING_BUGFIX
 362.109 +
 362.110 +#endif // __IRR_TYPES_H_INCLUDED__
 362.111 +
   363.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   363.2 +++ b/libs/assimp/irrXML/irrXML.cpp	Sat Feb 01 19:58:19 2014 +0200
   363.3 @@ -0,0 +1,152 @@
   363.4 +// Copyright (C) 2002-2005 Nikolaus Gebhardt
   363.5 +// This file is part of the "Irrlicht Engine" and the "irrXML" project.
   363.6 +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
   363.7 +
   363.8 +// Need to include Assimp, too. We're using Assimp's version of fast_atof
   363.9 +// so we need stdint.h. But no PCH.
  363.10 +
  363.11 +#include "AssimpPCH.h"
  363.12 +
  363.13 +#include "irrXML.h"
  363.14 +#include "irrString.h"
  363.15 +#include "irrArray.h"
  363.16 +#include "fast_atof.h"
  363.17 +#include "CXMLReaderImpl.h"
  363.18 +
  363.19 +namespace irr
  363.20 +{
  363.21 +namespace io
  363.22 +{
  363.23 +
  363.24 +//! Implementation of the file read callback for ordinary files
  363.25 +class CFileReadCallBack : public IFileReadCallBack
  363.26 +{
  363.27 +public:
  363.28 +
  363.29 +	//! construct from filename
  363.30 +	CFileReadCallBack(const char* filename)
  363.31 +		: File(0), Size(0), Close(true)
  363.32 +	{
  363.33 +		// open file
  363.34 +		File = fopen(filename, "rb");
  363.35 +
  363.36 +		if (File)
  363.37 +			getFileSize();
  363.38 +	}
  363.39 +
  363.40 +	//! construct from FILE pointer
  363.41 +	CFileReadCallBack(FILE* file)
  363.42 +		: File(file), Size(0), Close(false)
  363.43 +	{
  363.44 +		if (File)
  363.45 +			getFileSize();
  363.46 +	}
  363.47 +
  363.48 +	//! destructor
  363.49 +	virtual ~CFileReadCallBack()
  363.50 +	{
  363.51 +		if (Close && File)
  363.52 +			fclose(File);
  363.53 +	}
  363.54 +
  363.55 +	//! Reads an amount of bytes from the file.
  363.56 +	virtual int read(void* buffer, int sizeToRead)
  363.57 +	{
  363.58 +		if (!File)
  363.59 +			return 0;
  363.60 +
  363.61 +		return (int)fread(buffer, 1, sizeToRead, File);
  363.62 +	}
  363.63 +
  363.64 +	//! Returns size of file in bytes
  363.65 +	virtual int getSize()
  363.66 +	{
  363.67 +		return Size;
  363.68 +	}
  363.69 +
  363.70 +private:
  363.71 +
  363.72 +	//! retrieves the file size of the open file
  363.73 +	void getFileSize()
  363.74 +	{
  363.75 +		fseek(File, 0, SEEK_END);
  363.76 +		Size = ftell(File);
  363.77 +		fseek(File, 0, SEEK_SET);
  363.78 +	}
  363.79 +
  363.80 +	FILE* File;
  363.81 +	int Size;
  363.82 +	bool Close;
  363.83 +
  363.84 +}; // end class CFileReadCallBack
  363.85 +
  363.86 +
  363.87 +
  363.88 +// FACTORY FUNCTIONS:
  363.89 +
  363.90 +
  363.91 +//! Creates an instance of an UFT-8 or ASCII character xml parser. 
  363.92 +IrrXMLReader* createIrrXMLReader(const char* filename)
  363.93 +{
  363.94 +	return new CXMLReaderImpl<char, IXMLBase>(new CFileReadCallBack(filename)); 
  363.95 +}
  363.96 +
  363.97 +
  363.98 +//! Creates an instance of an UFT-8 or ASCII character xml parser. 
  363.99 +IrrXMLReader* createIrrXMLReader(FILE* file)
 363.100 +{
 363.101 +	return new CXMLReaderImpl<char, IXMLBase>(new CFileReadCallBack(file)); 
 363.102 +}
 363.103 +
 363.104 +
 363.105 +//! Creates an instance of an UFT-8 or ASCII character xml parser. 
 363.106 +IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback)
 363.107 +{
 363.108 +	return new CXMLReaderImpl<char, IXMLBase>(callback, false); 
 363.109 +}
 363.110 +
 363.111 +
 363.112 +//! Creates an instance of an UTF-16 xml parser. 
 363.113 +IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename)
 363.114 +{
 363.115 +	return new CXMLReaderImpl<char16, IXMLBase>(new CFileReadCallBack(filename)); 
 363.116 +}
 363.117 +
 363.118 +
 363.119 +//! Creates an instance of an UTF-16 xml parser. 
 363.120 +IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file)
 363.121 +{
 363.122 +	return new CXMLReaderImpl<char16, IXMLBase>(new CFileReadCallBack(file)); 
 363.123 +}
 363.124 +
 363.125 +
 363.126 +//! Creates an instance of an UTF-16 xml parser. 
 363.127 +IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback)
 363.128 +{
 363.129 +	return new CXMLReaderImpl<char16, IXMLBase>(callback, false); 
 363.130 +}
 363.131 +
 363.132 +
 363.133 +//! Creates an instance of an UTF-32 xml parser. 
 363.134 +IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename)
 363.135 +{
 363.136 +	return new CXMLReaderImpl<char32, IXMLBase>(new CFileReadCallBack(filename)); 
 363.137 +}
 363.138 +
 363.139 +
 363.140 +//! Creates an instance of an UTF-32 xml parser. 
 363.141 +IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file)
 363.142 +{
 363.143 +	return new CXMLReaderImpl<char32, IXMLBase>(new CFileReadCallBack(file)); 
 363.144 +}
 363.145 +
 363.146 +
 363.147 +//! Creates an instance of an UTF-32 xml parser. 
 363.148 +IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback)
 363.149 +{
 363.150 +	return new CXMLReaderImpl<char32, IXMLBase>(callback, false); 
 363.151 +}
 363.152 +
 363.153 +
 363.154 +} // end namespace io
 363.155 +} // end namespace irr
   364.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   364.2 +++ b/libs/assimp/irrXML/irrXML.h	Sat Feb 01 19:58:19 2014 +0200
   364.3 @@ -0,0 +1,540 @@
   364.4 +// Copyright (C) 2002-2005 Nikolaus Gebhardt
   364.5 +// This file is part of the "Irrlicht Engine" and the "irrXML" project.
   364.6 +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
   364.7 +
   364.8 +#ifndef __IRR_XML_H_INCLUDED__
   364.9 +#define __IRR_XML_H_INCLUDED__
  364.10 +
  364.11 +#include <stdio.h>
  364.12 +
  364.13 +/** \mainpage irrXML 1.2 API documentation
  364.14 + <div align="center"><img src="logobig.png" ></div>
  364.15 +
  364.16 + \section intro Introduction
  364.17 +
  364.18 +  Welcome to the irrXML API documentation.
  364.19 +  Here you'll find any information you'll need to develop applications with
  364.20 +  irrXML. If you look for a tutorial on how to start, take a look at the \ref irrxmlexample,
  364.21 +  at the homepage of irrXML at <A HREF="http://xml.irrlicht3d.org" >xml.irrlicht3d.org</A> 
  364.22 +  or into the SDK in the directory \example.
  364.23 + 
  364.24 +  irrXML is intended to be a high speed and easy-to-use XML Parser for C++, and
  364.25 +  this documentation is an important part of it. If you have any questions or
  364.26 +  suggestions, just send a email to the author of the engine, Nikolaus Gebhardt
  364.27 +  (niko (at) irrlicht3d.org). For more informations about this parser, see \ref history.
  364.28 +
  364.29 +  \section features Features
  364.30 +
  364.31 +  irrXML provides forward-only, read-only 
  364.32 +     access to a stream of non validated XML data. It was fully implemented by
  364.33 +	 Nikolaus Gebhardt. Its current features are:
  364.34 +
  364.35 +	 - It it fast as lighting and has very low memory usage. It was 
  364.36 +	   developed with the intention of being used in 3D games, as it already has been.
  364.37 +	 - irrXML is very small: It only consists of 60 KB of code and can be added easily
  364.38 +	   to your existing project.
  364.39 +	 - Of course, it is platform independent and works with lots of compilers.
  364.40 +	 - It is able to parse ASCII, UTF-8, UTF-16 and UTF-32 text files, both in 
  364.41 +	   little and big endian format. 
  364.42 +	 - Independent of the input file format, the parser can return all strings in ASCII, UTF-8,
  364.43 +	   UTF-16 and UTF-32 format. 
  364.44 +	 - With its optional file access abstraction it has the advantage that it can read not
  364.45 +	   only from files but from any type of data (memory, network, ...). For example when 
  364.46 +	   used with the Irrlicht Engine, it directly reads from compressed .zip files. 
  364.47 +	 - Just like the Irrlicht Engine for which it was originally created, it is extremely easy 
  364.48 +	   to use.
  364.49 +	 - It has no external dependencies, it does not even need the STL. 
  364.50 +
  364.51 +	 Although irrXML has some strenghts, it currently also has the following limitations:
  364.52 +
  364.53 +	 - The input xml file is not validated and assumed to be correct. 
  364.54 +
  364.55 +    \section irrxmlexample Example
  364.56 +
  364.57 +    The following code demonstrates the basic usage of irrXML. A simple xml
  364.58 +	file like this is parsed:
  364.59 +    \code
  364.60 +	<?xml version="1.0"?>
  364.61 +	<config>
  364.62 +		<!-- This is a config file for the mesh viewer -->
  364.63 +		<model file="dwarf.dea" />
  364.64 +		<messageText caption="Irrlicht Engine Mesh Viewer">
  364.65 +		Welcome to the Mesh Viewer of the &quot;Irrlicht Engine&quot;.
  364.66 +		</messageText>
  364.67 +	</config>
  364.68 +	\endcode
  364.69 +
  364.70 +	The code for parsing this file would look like this:
  364.71 +	\code
  364.72 +	#include <irrXML.h>
  364.73 +	using namespace irr; // irrXML is located in the namespace irr::io
  364.74 +	using namespace io;
  364.75 +
  364.76 +	#include <string> // we use STL strings to store data in this example
  364.77 +
  364.78 +	void main()
  364.79 +	{
  364.80 +		// create the reader using one of the factory functions
  364.81 +
  364.82 +		IrrXMLReader* xml = createIrrXMLReader("config.xml");
  364.83 +
  364.84 +		// strings for storing the data we want to get out of the file
  364.85 +		std::string modelFile;
  364.86 +		std::string messageText;
  364.87 +		std::string caption;
  364.88 +
  364.89 +		// parse the file until end reached
  364.90 +
  364.91 +		while(xml && xml->read())
  364.92 +		{
  364.93 +			switch(xml->getNodeType())
  364.94 +			{
  364.95 +			case EXN_TEXT:
  364.96 +				// in this xml file, the only text which occurs is the messageText
  364.97 +				messageText = xml->getNodeData();
  364.98 +				break;
  364.99 +			case EXN_ELEMENT:
 364.100 +				{
 364.101 +					if (!strcmp("model", xml->getNodeName()))
 364.102 +						modelFile = xml->getAttributeValue("file");
 364.103 +					else
 364.104 +					if (!strcmp("messageText", xml->getNodeName()))
 364.105 +						caption = xml->getAttributeValue("caption");
 364.106 +				}
 364.107 +				break;
 364.108 +			}
 364.109 +		}
 364.110 +
 364.111 +		// delete the xml parser after usage
 364.112 +		delete xml;
 364.113 +	}
 364.114 +	\endcode
 364.115 +
 364.116 +	\section howto How to use
 364.117 +
 364.118 +	Simply add the source files in the /src directory of irrXML to your project. Done.
 364.119 +
 364.120 +	\section license License
 364.121 +
 364.122 +	The irrXML license is based on the zlib license. Basicly, this means you can do with
 364.123 +	irrXML whatever you want:
 364.124 +
 364.125 +	Copyright (C) 2002-2005 Nikolaus Gebhardt
 364.126 +
 364.127 +	This software is provided 'as-is', without any express or implied
 364.128 +	warranty.  In no event will the authors be held liable for any damages
 364.129 +	arising from the use of this software.
 364.130 +
 364.131 +	Permission is granted to anyone to use this software for any purpose,
 364.132 +	including commercial applications, and to alter it and redistribute it
 364.133 +	freely, subject to the following restrictions:
 364.134 +
 364.135 +	1. The origin of this software must not be misrepresented; you must not
 364.136 +		claim that you wrote the original software. If you use this software
 364.137 +		in a product, an acknowledgment in the product documentation would be
 364.138 +		appreciated but is not required.
 364.139 +
 364.140 +	2. Altered source versions must be plainly marked as such, and must not be
 364.141 +		misrepresented as being the original software.
 364.142 +
 364.143 +	3. This notice may not be removed or altered from any source distribution.
 364.144 +
 364.145 +	\section history History
 364.146 +
 364.147 +	As lots of references in this documentation and the source show, this xml 
 364.148 +	parser has originally been a part of the 
 364.149 +	<A HREF="http://irrlicht.sourceforge.net" >Irrlicht Engine</A>. But because
 364.150 +	the parser has become very useful with the latest release, people asked for a 
 364.151 +	separate version of it, to be able to use it in non Irrlicht projects. With
 364.152 +	irrXML 1.0, this has now been done.
 364.153 +*/
 364.154 +
 364.155 +namespace irr
 364.156 +{
 364.157 +namespace io
 364.158 +{
 364.159 +	//! Enumeration of all supported source text file formats 
 364.160 +	enum ETEXT_FORMAT
 364.161 +	{
 364.162 +		//! ASCII, file without byte order mark, or not a text file
 364.163 +		ETF_ASCII,
 364.164 +
 364.165 +		//! UTF-8 format
 364.166 +		ETF_UTF8,
 364.167 +
 364.168 +		//! UTF-16 format, big endian
 364.169 +		ETF_UTF16_BE,
 364.170 +
 364.171 +		//! UTF-16 format, little endian
 364.172 +		ETF_UTF16_LE,
 364.173 +
 364.174 +		//! UTF-32 format, big endian
 364.175 +		ETF_UTF32_BE,
 364.176 +
 364.177 +		//! UTF-32 format, little endian
 364.178 +		ETF_UTF32_LE
 364.179 +	};
 364.180 +
 364.181 +
 364.182 +	//! Enumeration for all xml nodes which are parsed by IrrXMLReader
 364.183 +	enum EXML_NODE
 364.184 +	{
 364.185 +		//! No xml node. This is usually the node if you did not read anything yet.
 364.186 +		EXN_NONE,
 364.187 +
 364.188 +		//! A xml element, like <foo>
 364.189 +		EXN_ELEMENT,
 364.190 +
 364.191 +		//! End of an xml element, like </foo>
 364.192 +		EXN_ELEMENT_END,
 364.193 +
 364.194 +		//! Text within a xml element: <foo> this is the text. </foo>
 364.195 +		EXN_TEXT,
 364.196 +
 364.197 +		//! An xml comment like &lt;!-- I am a comment --&gt; or a DTD definition.
 364.198 +		EXN_COMMENT,
 364.199 +
 364.200 +		//! An xml cdata section like &lt;![CDATA[ this is some CDATA ]]&gt;
 364.201 +		EXN_CDATA,
 364.202 +
 364.203 +		//! Unknown element.
 364.204 +		EXN_UNKNOWN
 364.205 +	};
 364.206 +
 364.207 +	//! Callback class for file read abstraction. 
 364.208 +	/** With this, it is possible to make the xml parser read in other things 
 364.209 +	than just files. The Irrlicht engine is using this for example to 
 364.210 +	read xml from compressed .zip files. To make the parser read in 
 364.211 +	any other data, derive a class from this interface, implement the 
 364.212 +	two methods to read your data and give a pointer to an instance of
 364.213 +	your implementation when calling createIrrXMLReader(), 
 364.214 +	createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */
 364.215 +	class IFileReadCallBack
 364.216 +	{
 364.217 +	public:
 364.218 +
 364.219 +		//! virtual destructor
 364.220 +		virtual ~IFileReadCallBack() {};
 364.221 +
 364.222 +		//! Reads an amount of bytes from the file.
 364.223 +		/** \param buffer: Pointer to buffer where to read bytes will be written to.
 364.224 +		\param sizeToRead: Amount of bytes to read from the file.
 364.225 +		\return Returns how much bytes were read. */
 364.226 +		virtual int read(void* buffer, int sizeToRead) = 0;
 364.227 +
 364.228 +		//! Returns size of file in bytes
 364.229 +		virtual int getSize() = 0;
 364.230 +	};
 364.231 +
 364.232 +	//! Empty class to be used as parent class for IrrXMLReader.
 364.233 +	/** If you need another class as base class for the xml reader, you can do this by creating
 364.234 +	the reader using for example new CXMLReaderImpl<char, YourBaseClass>(yourcallback);
 364.235 +	The Irrlicht Engine for example needs IUnknown as base class for every object to
 364.236 +	let it automaticly reference countend, hence it replaces IXMLBase with IUnknown.
 364.237 +	See irrXML.cpp on how this can be done in detail. */
 364.238 +	class IXMLBase
 364.239 +	{
 364.240 +	};	
 364.241 +
 364.242 +	//! Interface providing easy read access to a XML file.
 364.243 +	/** You can create an instance of this reader using one of the factory functions
 364.244 +	createIrrXMLReader(), createIrrXMLReaderUTF16() and createIrrXMLReaderUTF32().
 364.245 +	If using the parser from the Irrlicht Engine, please use IFileSystem::createXMLReader() 
 364.246 +	instead.
 364.247 +	For a detailed intro how to use the parser, see \ref irrxmlexample and \ref features.
 364.248 +
 364.249 +	The typical usage of this parser looks like this:
 364.250 +	\code
 364.251 +	#include <irrXML.h>
 364.252 +	using namespace irr; // irrXML is located in the namespace irr::io
 364.253 +	using namespace io;
 364.254 +
 364.255 +	void main()
 364.256 +	{
 364.257 +		// create the reader using one of the factory functions
 364.258 +		IrrXMLReader* xml = createIrrXMLReader("config.xml");
 364.259 +
 364.260 +		if (xml == 0)
 364.261 +			return; // file could not be opened
 364.262 +
 364.263 +		// parse the file until end reached
 364.264 +		while(xml->read())
 364.265 +		{
 364.266 +			// based on xml->getNodeType(), do something.
 364.267 +		}
 364.268 +
 364.269 +		// delete the xml parser after usage
 364.270 +		delete xml;
 364.271 +	}
 364.272 +	\endcode
 364.273 +	See \ref irrxmlexample for a more detailed example.
 364.274 +	*/
 364.275 +	template<class char_type, class super_class>
 364.276 +	class IIrrXMLReader : public super_class
 364.277 +	{
 364.278 +	public:
 364.279 +
 364.280 +		//! Destructor
 364.281 +		virtual ~IIrrXMLReader() {};
 364.282 +
 364.283 +		//! Reads forward to the next xml node. 
 364.284 +		/** \return Returns false, if there was no further node.  */
 364.285 +		virtual bool read() = 0;
 364.286 +
 364.287 +		//! Returns the type of the current XML node.
 364.288 +		virtual EXML_NODE getNodeType() const = 0;
 364.289 +
 364.290 +        //! Returns attribute count of the current XML node. 
 364.291 +		/** This is usually
 364.292 +		non null if the current node is EXN_ELEMENT, and the element has attributes.
 364.293 +		\return Returns amount of attributes of this xml node. */
 364.294 +		virtual int getAttributeCount() const = 0;
 364.295 +
 364.296 +		//! Returns name of an attribute. 
 364.297 +		/** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
 364.298 +		\return Name of the attribute, 0 if an attribute with this index does not exist. */
 364.299 +		virtual const char_type* getAttributeName(int idx) const = 0;
 364.300 +
 364.301 +		//! Returns the value of an attribute. 
 364.302 +		/** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
 364.303 +		\return Value of the attribute, 0 if an attribute with this index does not exist. */
 364.304 +		virtual const char_type* getAttributeValue(int idx) const = 0;
 364.305 +
 364.306 +		//! Returns the value of an attribute. 
 364.307 +		/** \param name: Name of the attribute.
 364.308 +		\return Value of the attribute, 0 if an attribute with this name does not exist. */
 364.309 +		virtual const char_type* getAttributeValue(const char_type* name) const = 0;
 364.310 +
 364.311 +		//! Returns the value of an attribute in a safe way.
 364.312 +		/** Like getAttributeValue(), but does not 
 364.313 +		return 0 if the attribute does not exist. An empty string ("") is returned then.
 364.314 +		\param name: Name of the attribute.
 364.315 +		\return Value of the attribute, and "" if an attribute with this name does not exist */
 364.316 +		virtual const char_type* getAttributeValueSafe(const char_type* name) const = 0;
 364.317 +
 364.318 +		//! Returns the value of an attribute as integer. 
 364.319 +		/** \param name Name of the attribute.
 364.320 +		\return Value of the attribute as integer, and 0 if an attribute with this name does not exist or
 364.321 +		the value could not be interpreted as integer. */
 364.322 +		virtual int getAttributeValueAsInt(const char_type* name) const = 0;
 364.323 +
 364.324 +		//! Returns the value of an attribute as integer. 
 364.325 +		/** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
 364.326 +		\return Value of the attribute as integer, and 0 if an attribute with this index does not exist or
 364.327 +		the value could not be interpreted as integer. */
 364.328 +		virtual int getAttributeValueAsInt(int idx) const = 0;
 364.329 +
 364.330 +		//! Returns the value of an attribute as float. 
 364.331 +		/** \param name: Name of the attribute.
 364.332 +		\return Value of the attribute as float, and 0 if an attribute with this name does not exist or
 364.333 +		the value could not be interpreted as float. */
 364.334 +		virtual float getAttributeValueAsFloat(const char_type* name) const = 0;
 364.335 +
 364.336 +		//! Returns the value of an attribute as float. 
 364.337 +		/** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
 364.338 +		\return Value of the attribute as float, and 0 if an attribute with this index does not exist or
 364.339 +		the value could not be interpreted as float. */
 364.340 +		virtual float getAttributeValueAsFloat(int idx) const = 0;
 364.341 +
 364.342 +		//! Returns the name of the current node. 
 364.343 +		/** Only non null, if the node type is EXN_ELEMENT.
 364.344 +		\return Name of the current node or 0 if the node has no name. */
 364.345 +		virtual const char_type* getNodeName() const = 0;
 364.346 +
 364.347 +		//! Returns data of the current node. 
 364.348 +		/** Only non null if the node has some
 364.349 +		data and it is of type EXN_TEXT or EXN_UNKNOWN. */
 364.350 +		virtual const char_type* getNodeData() const = 0;
 364.351 +
 364.352 +		//! Returns if an element is an empty element, like <foo />
 364.353 +		virtual bool isEmptyElement() const = 0;
 364.354 +
 364.355 +		//! Returns format of the source xml file. 
 364.356 +		/** It is not necessary to use
 364.357 +		this method because the parser will convert the input file format
 364.358 +		to the format wanted by the user when creating the parser. This
 364.359 +		method is useful to get/display additional informations. */
 364.360 +		virtual ETEXT_FORMAT getSourceFormat() const = 0;
 364.361 +
 364.362 +		//! Returns format of the strings returned by the parser. 
 364.363 +		/** This will be UTF8 for example when you created a parser with
 364.364 +		IrrXMLReaderUTF8() and UTF32 when it has been created using 
 364.365 +		IrrXMLReaderUTF32. It should not be necessary to call this
 364.366 +		method and only exists for informational purposes. */
 364.367 +		virtual ETEXT_FORMAT getParserFormat() const = 0;
 364.368 +	};
 364.369 +
 364.370 +
 364.371 +	//! defines the utf-16 type.
 364.372 +	/** Not using wchar_t for this because 
 364.373 +	wchar_t has 16 bit on windows and 32 bit on other operating systems. */
 364.374 +	typedef unsigned short char16;
 364.375 +
 364.376 +	//! defines the utf-32 type. 
 364.377 +	/** Not using wchar_t for this because 
 364.378 +	wchar_t has 16 bit on windows and 32 bit on other operating systems. */
 364.379 +	typedef unsigned long char32;
 364.380 +
 364.381 +	//! A UTF-8 or ASCII character xml parser.
 364.382 +	/** This means that all character data will be returned in 8 bit ASCII or UTF-8 by this parser. 
 364.383 +	The file to read can be in any format, it will be converted to UTF-8 if it is not
 364.384 +	in this format.
 364.385 +	Create an instance of this with createIrrXMLReader(); 
 364.386 +	See IIrrXMLReader for description on how to use it. */
 364.387 +	typedef IIrrXMLReader<char, IXMLBase> IrrXMLReader;
 364.388 +
 364.389 +	//! A UTF-16 xml parser. 
 364.390 +	/** This means that all character data will be returned in UTF-16 by this parser. 
 364.391 +	The file to read can be in any format, it will be converted to UTF-16 if it is not
 364.392 +	in this format.
 364.393 +	Create an instance of this with createIrrXMLReaderUTF16(); 
 364.394 +	See IIrrXMLReader for description on how to use it.  */
 364.395 +	typedef IIrrXMLReader<char16, IXMLBase> IrrXMLReaderUTF16;
 364.396 +
 364.397 +	//! A UTF-32 xml parser. 
 364.398 +	/** This means that all character data will be returned in UTF-32 by this parser. 
 364.399 +	The file to read can be in any format, it will be converted to UTF-32 if it is not
 364.400 +	in this format.
 364.401 +	Create an instance of this with createIrrXMLReaderUTF32(); 
 364.402 +	See IIrrXMLReader for description on how to use it. */
 364.403 +	typedef IIrrXMLReader<char32, IXMLBase> IrrXMLReaderUTF32;
 364.404 +
 364.405 +
 364.406 +	//! Creates an instance of an UFT-8 or ASCII character xml parser.
 364.407 +	/** This means that all character data will be returned in 8 bit ASCII or UTF-8. 
 364.408 +	The file to read can be in any format, it will be converted to UTF-8 if it is not in this format.
 364.409 +	If you are using the Irrlicht Engine, it is better not to use this function but
 364.410 +	IFileSystem::createXMLReaderUTF8() instead.
 364.411 +	\param filename: Name of file to be opened.
 364.412 +	\return Returns a pointer to the created xml parser. This pointer should be 
 364.413 +	deleted using 'delete' after no longer needed. Returns 0 if an error occured
 364.414 +	and the file could not be opened. */
 364.415 +	IrrXMLReader* createIrrXMLReader(const char* filename);
 364.416 +
 364.417 +	//! Creates an instance of an UFT-8 or ASCII character xml parser.
 364.418 +	/** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can 
 364.419 +	be in any format, it will be converted to UTF-8 if it is not in this format.
 364.420 +	If you are using the Irrlicht Engine, it is better not to use this function but
 364.421 +	IFileSystem::createXMLReaderUTF8() instead.
 364.422 +	\param file: Pointer to opened file, must have been opened in binary mode, e.g.
 364.423 +	using fopen("foo.bar", "wb"); The file will not be closed after it has been read.
 364.424 +	\return Returns a pointer to the created xml parser. This pointer should be 
 364.425 +	deleted using 'delete' after no longer needed. Returns 0 if an error occured
 364.426 +	and the file could not be opened. */
 364.427 +	IrrXMLReader* createIrrXMLReader(FILE* file);
 364.428 +
 364.429 +	//! Creates an instance of an UFT-8 or ASCII character xml parser. 
 364.430 +	/** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can 
 364.431 +	 be in any format, it will be converted to UTF-8 if it is not in this format.
 364.432 +	 If you are using the Irrlicht Engine, it is better not to use this function but
 364.433 +	 IFileSystem::createXMLReaderUTF8() instead.
 364.434 +	 \param callback: Callback for file read abstraction. Implement your own
 364.435 +	 callback to make the xml parser read in other things than just files. See
 364.436 +	 IFileReadCallBack for more information about this.
 364.437 +	 \return Returns a pointer to the created xml parser. This pointer should be 
 364.438 +	 deleted using 'delete' after no longer needed. Returns 0 if an error occured
 364.439 +	 and the file could not be opened. */
 364.440 +	IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback);
 364.441 +
 364.442 +	//! Creates an instance of an UFT-16 xml parser. 
 364.443 +	/** This means that
 364.444 +	all character data will be returned in UTF-16. The file to read can 
 364.445 +	be in any format, it will be converted to UTF-16 if it is not in this format.
 364.446 +	If you are using the Irrlicht Engine, it is better not to use this function but
 364.447 +	IFileSystem::createXMLReader() instead.
 364.448 +	\param filename: Name of file to be opened.
 364.449 +	\return Returns a pointer to the created xml parser. This pointer should be 
 364.450 +	deleted using 'delete' after no longer needed. Returns 0 if an error occured
 364.451 +	and the file could not be opened. */
 364.452 +	IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename);
 364.453 +
 364.454 +	//! Creates an instance of an UFT-16 xml parser. 
 364.455 +	/** This means that all character data will be returned in UTF-16. The file to read can 
 364.456 +	be in any format, it will be converted to UTF-16 if it is not in this format.
 364.457 +	If you are using the Irrlicht Engine, it is better not to use this function but
 364.458 +	IFileSystem::createXMLReader() instead.
 364.459 +	\param file: Pointer to opened file, must have been opened in binary mode, e.g.
 364.460 +	using fopen("foo.bar", "wb"); The file will not be closed after it has been read.
 364.461 +	\return Returns a pointer to the created xml parser. This pointer should be 
 364.462 +	deleted using 'delete' after no longer needed. Returns 0 if an error occured
 364.463 +	and the file could not be opened. */
 364.464 +	IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file);
 364.465 +
 364.466 +	//! Creates an instance of an UFT-16 xml parser. 
 364.467 +	/** This means that all character data will be returned in UTF-16. The file to read can 
 364.468 +	be in any format, it will be converted to UTF-16 if it is not in this format.
 364.469 +	If you are using the Irrlicht Engine, it is better not to use this function but
 364.470 +	IFileSystem::createXMLReader() instead.
 364.471 +	\param callback: Callback for file read abstraction. Implement your own
 364.472 +	callback to make the xml parser read in other things than just files. See
 364.473 +	IFileReadCallBack for more information about this.
 364.474 +	\return Returns a pointer to the created xml parser. This pointer should be 
 364.475 +	deleted using 'delete' after no longer needed. Returns 0 if an error occured
 364.476 +	and the file could not be opened. */
 364.477 +	IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback);
 364.478 +
 364.479 +
 364.480 +	//! Creates an instance of an UFT-32 xml parser. 
 364.481 +	/** This means that all character data will be returned in UTF-32. The file to read can 
 364.482 +	be in any format, it will be converted to UTF-32 if it is not in this format.
 364.483 +	If you are using the Irrlicht Engine, it is better not to use this function but
 364.484 +	IFileSystem::createXMLReader() instead.
 364.485 +	\param filename: Name of file to be opened.
 364.486 +	\return Returns a pointer to the created xml parser. This pointer should be 
 364.487 +	deleted using 'delete' after no longer needed. Returns 0 if an error occured
 364.488 +	and the file could not be opened. */
 364.489 +	IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename);
 364.490 +
 364.491 +	//! Creates an instance of an UFT-32 xml parser. 
 364.492 +	/** This means that all character data will be returned in UTF-32. The file to read can 
 364.493 +	be in any format, it will be converted to UTF-32 if it is not in this format.
 364.494 +	if you are using the Irrlicht Engine, it is better not to use this function but
 364.495 +	IFileSystem::createXMLReader() instead.
 364.496 +	\param file: Pointer to opened file, must have been opened in binary mode, e.g.
 364.497 +	using fopen("foo.bar", "wb"); The file will not be closed after it has been read.
 364.498 +	\return Returns a pointer to the created xml parser. This pointer should be 
 364.499 +	deleted using 'delete' after no longer needed. Returns 0 if an error occured
 364.500 +	and the file could not be opened. */
 364.501 +	IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file);
 364.502 +
 364.503 +	//! Creates an instance of an UFT-32 xml parser. 
 364.504 +	/** This means that
 364.505 +	all character data will be returned in UTF-32. The file to read can 
 364.506 +	be in any format, it will be converted to UTF-32 if it is not in this format.
 364.507 +	If you are using the Irrlicht Engine, it is better not to use this function but
 364.508 +	IFileSystem::createXMLReader() instead.
 364.509 +	\param callback: Callback for file read abstraction. Implement your own
 364.510 +	callback to make the xml parser read in other things than just files. See
 364.511 +	IFileReadCallBack for more information about this.
 364.512 +	\return Returns a pointer to the created xml parser. This pointer should be 
 364.513 +	deleted using 'delete' after no longer needed. Returns 0 if an error occured
 364.514 +	and the file could not be opened. */
 364.515 +	IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback);
 364.516 +	
 364.517 +
 364.518 +	/*! \file irrxml.h
 364.519 +    \brief Header file of the irrXML, the Irrlicht XML parser.
 364.520 +    
 364.521 +    This file includes everything needed for using irrXML, 
 364.522 +    the XML parser of the Irrlicht Engine. To use irrXML,
 364.523 +	you only need to include this file in your project:
 364.524 +
 364.525 +	\code
 364.526 +	#include <irrXML.h>
 364.527 +	\endcode
 364.528 +
 364.529 +	It is also common to use the two namespaces in which irrXML is included, 
 364.530 +	directly after #including irrXML.h:
 364.531 +
 364.532 +	\code
 364.533 +	#include <irrXML.h>
 364.534 +	using namespace irr;
 364.535 +	using namespace io;
 364.536 +	\endcode
 364.537 +	*/
 364.538 +
 364.539 +} // end namespace io
 364.540 +} // end namespace irr
 364.541 +
 364.542 +#endif // __IRR_XML_H_INCLUDED__
 364.543 +
   365.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   365.2 +++ b/libs/assimp/irrXMLWrapper.h	Sat Feb 01 19:58:19 2014 +0200
   365.3 @@ -0,0 +1,131 @@
   365.4 +/*
   365.5 +Open Asset Import Library (assimp)
   365.6 +----------------------------------------------------------------------
   365.7 +
   365.8 +Copyright (c) 2006-2012, assimp team
   365.9 +All rights reserved.
  365.10 +
  365.11 +Redistribution and use of this software in source and binary forms, 
  365.12 +with or without modification, are permitted provided that the 
  365.13 +following conditions are met:
  365.14 +
  365.15 +* Redistributions of source code must retain the above
  365.16 +copyright notice, this list of conditions and the
  365.17 +following disclaimer.
  365.18 +
  365.19 +* Redistributions in binary form must reproduce the above
  365.20 +copyright notice, this list of conditions and the
  365.21 +following disclaimer in the documentation and/or other
  365.22 +materials provided with the distribution.
  365.23 +
  365.24 +* Neither the name of the assimp team, nor the names of its
  365.25 +contributors may be used to endorse or promote products
  365.26 +derived from this software without specific prior
  365.27 +written permission of the assimp team.
  365.28 +
  365.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  365.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  365.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  365.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  365.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  365.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  365.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  365.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  365.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  365.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  365.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  365.40 +
  365.41 +----------------------------------------------------------------------
  365.42 +*/
  365.43 +
  365.44 +#ifndef INCLUDED_AI_IRRXML_WRAPPER
  365.45 +#define INCLUDED_AI_IRRXML_WRAPPER
  365.46 +
  365.47 +// some long includes ....
  365.48 +#include "irrXML/irrXML.h"
  365.49 +#include "assimp/IOStream.hpp"
  365.50 +namespace Assimp	{
  365.51 +
  365.52 +// ---------------------------------------------------------------------------------
  365.53 +/** @brief Utility class to make IrrXML work together with our custom IO system
  365.54 + *  See the IrrXML docs for more details.
  365.55 + *
  365.56 + *  Construct IrrXML-Reader in BaseImporter::InternReadFile():
  365.57 + *  @code
  365.58 + * // open the file
  365.59 + * boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
  365.60 + * if( file.get() == NULL) {
  365.61 + *	  throw DeadlyImportError( "Failed to open file " + pFile + ".");
  365.62 + * }
  365.63 + *
  365.64 + * // generate a XML reader for it
  365.65 + * boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
  365.66 + * mReader = irr::io::createIrrXMLReader( mIOWrapper.get());
  365.67 + * if( !mReader) {
  365.68 + *    ThrowException( "xxxx: Unable to open file.");
  365.69 + * }
  365.70 + * @endcode
  365.71 + **/
  365.72 +class CIrrXML_IOStreamReader 
  365.73 +	: public irr::io::IFileReadCallBack
  365.74 +{
  365.75 +public:
  365.76 +
  365.77 +	// ----------------------------------------------------------------------------------
  365.78 +	//! Construction from an existing IOStream
  365.79 +	CIrrXML_IOStreamReader(IOStream* _stream)
  365.80 +		: stream (_stream)
  365.81 +		, t (0)
  365.82 +	{
  365.83 +
  365.84 +		// Map the buffer into memory and convert it to UTF8. IrrXML provides its
  365.85 +		// own conversion, which is merely a cast from uintNN_t to uint8_t. Thus,
  365.86 +		// it is not suitable for our purposes and we have to do it BEFORE IrrXML
  365.87 +		// gets the buffer. Sadly, this forces as to map the whole file into
  365.88 +		// memory.
  365.89 +
  365.90 +		data.resize(stream->FileSize());
  365.91 +		stream->Read(&data[0],data.size(),1);
  365.92 +
  365.93 +		BaseImporter::ConvertToUTF8(data);
  365.94 +	}
  365.95 +
  365.96 +	// ----------------------------------------------------------------------------------
  365.97 +	//! Virtual destructor
  365.98 +	virtual ~CIrrXML_IOStreamReader() {};
  365.99 +
 365.100 +	// ----------------------------------------------------------------------------------
 365.101 +	//!   Reads an amount of bytes from the file.
 365.102 +	/**  @param buffer:       Pointer to output buffer.
 365.103 +	 *   @param sizeToRead:   Amount of bytes to read 
 365.104 +	 *   @return              Returns how much bytes were read.  */
 365.105 +	virtual int read(void* buffer, int sizeToRead)	{
 365.106 +		if(sizeToRead<0) {
 365.107 +			return 0;
 365.108 +		}
 365.109 +		if(t+sizeToRead>data.size()) {
 365.110 +			sizeToRead = data.size()-t;
 365.111 +		}
 365.112 +
 365.113 +		memcpy(buffer,&data.front()+t,sizeToRead);
 365.114 +
 365.115 +		t += sizeToRead;
 365.116 +		return sizeToRead;
 365.117 +	}
 365.118 +
 365.119 +	// ----------------------------------------------------------------------------------
 365.120 +	//! Returns size of file in bytes
 365.121 +	virtual int getSize()	{
 365.122 +		return (int)data.size();
 365.123 +	}
 365.124 +
 365.125 +private:
 365.126 +	IOStream* stream;
 365.127 +	std::vector<char> data;
 365.128 +	size_t t;
 365.129 +
 365.130 +}; // ! class CIrrXML_IOStreamReader
 365.131 +
 365.132 +} // ! Assimp
 365.133 +
 365.134 +#endif // !! INCLUDED_AI_IRRXML_WRAPPER
   366.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   366.2 +++ b/libs/assimp/pstdint.h	Sat Feb 01 19:58:19 2014 +0200
   366.3 @@ -0,0 +1,729 @@
   366.4 +/*  A portable stdint.h
   366.5 + ****************************************************************************
   366.6 + *  BSD License:
   366.7 + ****************************************************************************
   366.8 + *
   366.9 + *  Copyright (c) 2005-2007 Paul Hsieh
  366.10 + *  All rights reserved.
  366.11 + *
  366.12 + *  Redistribution and use in source and binary forms, with or without
  366.13 + *  modification, are permitted provided that the following conditions
  366.14 + *  are met:
  366.15 + *
  366.16 + *  1. Redistributions of source code must retain the above copyright
  366.17 + *     notice, this list of conditions and the following disclaimer.
  366.18 + *  2. Redistributions in binary form must reproduce the above copyright
  366.19 + *     notice, this list of conditions and the following disclaimer in the
  366.20 + *     documentation and/or other materials provided with the distribution.
  366.21 + *  3. The name of the author may not be used to endorse or promote products
  366.22 + *     derived from this software without specific prior written permission.
  366.23 + *
  366.24 + *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  366.25 + *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  366.26 + *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  366.27 + *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  366.28 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  366.29 + *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  366.30 + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  366.31 + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  366.32 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  366.33 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  366.34 + *
  366.35 + ****************************************************************************
  366.36 + *
  366.37 + *  Version 0.1.10
  366.38 + *
  366.39 + *  The ANSI C standard committee, for the C99 standard, specified the
  366.40 + *  inclusion of a new standard include file called stdint.h.  This is
  366.41 + *  a very useful and long desired include file which contains several
  366.42 + *  very precise definitions for integer scalar types that is
  366.43 + *  critically important for making portable several classes of
  366.44 + *  applications including cryptography, hashing, variable length
  366.45 + *  integer libraries and so on.  But for most developers its likely
  366.46 + *  useful just for programming sanity.
  366.47 + *
  366.48 + *  The problem is that most compiler vendors have decided not to
  366.49 + *  implement the C99 standard, and the next C++ language standard
  366.50 + *  (which has a lot more mindshare these days) will be a long time in
  366.51 + *  coming and its unknown whether or not it will include stdint.h or
  366.52 + *  how much adoption it will have.  Either way, it will be a long time
  366.53 + *  before all compilers come with a stdint.h and it also does nothing
  366.54 + *  for the extremely large number of compilers available today which
  366.55 + *  do not include this file, or anything comparable to it.
  366.56 + *
  366.57 + *  So that's what this file is all about.  Its an attempt to build a
  366.58 + *  single universal include file that works on as many platforms as
  366.59 + *  possible to deliver what stdint.h is supposed to.  A few things
  366.60 + *  that should be noted about this file:
  366.61 + *
  366.62 + *    1) It is not guaranteed to be portable and/or present an identical
  366.63 + *       interface on all platforms.  The extreme variability of the
  366.64 + *       ANSI C standard makes this an impossibility right from the
  366.65 + *       very get go. Its really only meant to be useful for the vast
  366.66 + *       majority of platforms that possess the capability of
  366.67 + *       implementing usefully and precisely defined, standard sized
  366.68 + *       integer scalars.  Systems which are not intrinsically 2s
  366.69 + *       complement may produce invalid constants.
  366.70 + *
  366.71 + *    2) There is an unavoidable use of non-reserved symbols.
  366.72 + *
  366.73 + *    3) Other standard include files are invoked.
  366.74 + *
  366.75 + *    4) This file may come in conflict with future platforms that do
  366.76 + *       include stdint.h.  The hope is that one or the other can be
  366.77 + *       used with no real difference.
  366.78 + *
  366.79 + *    5) In the current verison, if your platform can't represent
  366.80 + *       int32_t, int16_t and int8_t, it just dumps out with a compiler
  366.81 + *       error.
  366.82 + *
  366.83 + *    6) 64 bit integers may or may not be defined.  Test for their
  366.84 + *       presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
  366.85 + *       Note that this is different from the C99 specification which
  366.86 + *       requires the existence of 64 bit support in the compiler.  If
  366.87 + *       this is not defined for your platform, yet it is capable of
  366.88 + *       dealing with 64 bits then it is because this file has not yet
  366.89 + *       been extended to cover all of your system's capabilities.
  366.90 + *
  366.91 + *    7) (u)intptr_t may or may not be defined.  Test for its presence
  366.92 + *       with the test: #ifdef PTRDIFF_MAX.  If this is not defined
  366.93 + *       for your platform, then it is because this file has not yet
  366.94 + *       been extended to cover all of your system's capabilities, not
  366.95 + *       because its optional.
  366.96 + *
  366.97 + *    8) The following might not been defined even if your platform is
  366.98 + *       capable of defining it:
  366.99 + *
 366.100 + *       WCHAR_MIN
 366.101 + *       WCHAR_MAX
 366.102 + *       (u)int64_t
 366.103 + *       PTRDIFF_MIN
 366.104 + *       PTRDIFF_MAX
 366.105 + *       (u)intptr_t
 366.106 + *
 366.107 + *    9) The following have not been defined:
 366.108 + *
 366.109 + *       WINT_MIN
 366.110 + *       WINT_MAX
 366.111 + *
 366.112 + *   10) The criteria for defining (u)int_least(*)_t isn't clear,
 366.113 + *       except for systems which don't have a type that precisely
 366.114 + *       defined 8, 16, or 32 bit types (which this include file does
 366.115 + *       not support anyways). Default definitions have been given.
 366.116 + *
 366.117 + *   11) The criteria for defining (u)int_fast(*)_t isn't something I
 366.118 + *       would trust to any particular compiler vendor or the ANSI C
 366.119 + *       committee.  It is well known that "compatible systems" are
 366.120 + *       commonly created that have very different performance
 366.121 + *       characteristics from the systems they are compatible with,
 366.122 + *       especially those whose vendors make both the compiler and the
 366.123 + *       system.  Default definitions have been given, but its strongly
 366.124 + *       recommended that users never use these definitions for any
 366.125 + *       reason (they do *NOT* deliver any serious guarantee of
 366.126 + *       improved performance -- not in this file, nor any vendor's
 366.127 + *       stdint.h).
 366.128 + *
 366.129 + *   12) The following macros:
 366.130 + *
 366.131 + *       PRINTF_INTMAX_MODIFIER
 366.132 + *       PRINTF_INT64_MODIFIER
 366.133 + *       PRINTF_INT32_MODIFIER
 366.134 + *       PRINTF_INT16_MODIFIER
 366.135 + *       PRINTF_LEAST64_MODIFIER
 366.136 + *       PRINTF_LEAST32_MODIFIER
 366.137 + *       PRINTF_LEAST16_MODIFIER
 366.138 + *       PRINTF_INTPTR_MODIFIER
 366.139 + *
 366.140 + *       are strings which have been defined as the modifiers required
 366.141 + *       for the "d", "u" and "x" printf formats to correctly output
 366.142 + *       (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
 366.143 + *       (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
 366.144 + *       PRINTF_INTPTR_MODIFIER is not defined for some systems which
 366.145 + *       provide their own stdint.h.  PRINTF_INT64_MODIFIER is not
 366.146 + *       defined if INT64_MAX is not defined.  These are an extension
 366.147 + *       beyond what C99 specifies must be in stdint.h.
 366.148 + *
 366.149 + *       In addition, the following macros are defined:
 366.150 + *
 366.151 + *       PRINTF_INTMAX_HEX_WIDTH
 366.152 + *       PRINTF_INT64_HEX_WIDTH
 366.153 + *       PRINTF_INT32_HEX_WIDTH
 366.154 + *       PRINTF_INT16_HEX_WIDTH
 366.155 + *       PRINTF_INT8_HEX_WIDTH
 366.156 + *       PRINTF_INTMAX_DEC_WIDTH
 366.157 + *       PRINTF_INT64_DEC_WIDTH
 366.158 + *       PRINTF_INT32_DEC_WIDTH
 366.159 + *       PRINTF_INT16_DEC_WIDTH
 366.160 + *       PRINTF_INT8_DEC_WIDTH
 366.161 + *
 366.162 + *       Which specifies the maximum number of characters required to
 366.163 + *       print the number of that type in either hexadecimal or decimal.
 366.164 + *       These are an extension beyond what C99 specifies must be in
 366.165 + *       stdint.h.
 366.166 + *
 366.167 + *  Compilers tested (all with 0 warnings at their highest respective
 366.168 + *  settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
 366.169 + *  bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
 366.170 + *  .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
 366.171 + *
 366.172 + *  This file should be considered a work in progress.  Suggestions for
 366.173 + *  improvements, especially those which increase coverage are strongly
 366.174 + *  encouraged.
 366.175 + *
 366.176 + *  Acknowledgements
 366.177 + *
 366.178 + *  The following people have made significant contributions to the
 366.179 + *  development and testing of this file:
 366.180 + *
 366.181 + *  Chris Howie
 366.182 + *  John Steele Scott
 366.183 + *  Dave Thorup
 366.184 + *
 366.185 + */
 366.186 +
 366.187 +#include <stddef.h>
 366.188 +#include <limits.h>
 366.189 +#include <signal.h>
 366.190 +
 366.191 +/*
 366.192 + *  For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
 366.193 + *  do nothing else.  On the Mac OS X version of gcc this is _STDINT_H_.
 366.194 + */
 366.195 +
 366.196 +#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)))) && !defined (_PSTDINT_H_INCLUDED) && !defined(_STDINT)
 366.197 +#include <stdint.h>
 366.198 +#define _PSTDINT_H_INCLUDED
 366.199 +# ifndef PRINTF_INT64_MODIFIER
 366.200 +#  define PRINTF_INT64_MODIFIER "ll"
 366.201 +# endif
 366.202 +# ifndef PRINTF_INT32_MODIFIER
 366.203 +#  define PRINTF_INT32_MODIFIER "l"
 366.204 +# endif
 366.205 +# ifndef PRINTF_INT16_MODIFIER
 366.206 +#  define PRINTF_INT16_MODIFIER "h"
 366.207 +# endif
 366.208 +# ifndef PRINTF_INTMAX_MODIFIER
 366.209 +#  define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
 366.210 +# endif
 366.211 +# ifndef PRINTF_INT64_HEX_WIDTH
 366.212 +#  define PRINTF_INT64_HEX_WIDTH "16"
 366.213 +# endif
 366.214 +# ifndef PRINTF_INT32_HEX_WIDTH
 366.215 +#  define PRINTF_INT32_HEX_WIDTH "8"
 366.216 +# endif
 366.217 +# ifndef PRINTF_INT16_HEX_WIDTH
 366.218 +#  define PRINTF_INT16_HEX_WIDTH "4"
 366.219 +# endif
 366.220 +# ifndef PRINTF_INT8_HEX_WIDTH
 366.221 +#  define PRINTF_INT8_HEX_WIDTH "2"
 366.222 +# endif
 366.223 +# ifndef PRINTF_INT64_DEC_WIDTH
 366.224 +#  define PRINTF_INT64_DEC_WIDTH "20"
 366.225 +# endif
 366.226 +# ifndef PRINTF_INT32_DEC_WIDTH
 366.227 +#  define PRINTF_INT32_DEC_WIDTH "10"
 366.228 +# endif
 366.229 +# ifndef PRINTF_INT16_DEC_WIDTH
 366.230 +#  define PRINTF_INT16_DEC_WIDTH "5"
 366.231 +# endif
 366.232 +# ifndef PRINTF_INT8_DEC_WIDTH
 366.233 +#  define PRINTF_INT8_DEC_WIDTH "3"
 366.234 +# endif
 366.235 +# ifndef PRINTF_INTMAX_HEX_WIDTH
 366.236 +#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
 366.237 +# endif
 366.238 +# ifndef PRINTF_INTMAX_DEC_WIDTH
 366.239 +#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
 366.240 +# endif
 366.241 +
 366.242 +/*
 366.243 + *  Something really weird is going on with Open Watcom.  Just pull some of
 366.244 + *  these duplicated definitions from Open Watcom's stdint.h file for now.
 366.245 + */
 366.246 +
 366.247 +# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
 366.248 +#  if !defined (INT64_C)
 366.249 +#   define INT64_C(x)   (x + (INT64_MAX - INT64_MAX))
 366.250 +#  endif
 366.251 +#  if !defined (UINT64_C)
 366.252 +#   define UINT64_C(x)  (x + (UINT64_MAX - UINT64_MAX))
 366.253 +#  endif
 366.254 +#  if !defined (INT32_C)
 366.255 +#   define INT32_C(x)   (x + (INT32_MAX - INT32_MAX))
 366.256 +#  endif
 366.257 +#  if !defined (UINT32_C)
 366.258 +#   define UINT32_C(x)  (x + (UINT32_MAX - UINT32_MAX))
 366.259 +#  endif
 366.260 +#  if !defined (INT16_C)
 366.261 +#   define INT16_C(x)   (x)
 366.262 +#  endif
 366.263 +#  if !defined (UINT16_C)
 366.264 +#   define UINT16_C(x)  (x)
 366.265 +#  endif
 366.266 +#  if !defined (INT8_C)
 366.267 +#   define INT8_C(x)   (x)
 366.268 +#  endif
 366.269 +#  if !defined (UINT8_C)
 366.270 +#   define UINT8_C(x)  (x)
 366.271 +#  endif
 366.272 +#  if !defined (UINT64_MAX)
 366.273 +#   define UINT64_MAX  18446744073709551615ULL
 366.274 +#  endif
 366.275 +#  if !defined (INT64_MAX)
 366.276 +#   define INT64_MAX  9223372036854775807LL
 366.277 +#  endif
 366.278 +#  if !defined (UINT32_MAX)
 366.279 +#   define UINT32_MAX  4294967295UL
 366.280 +#  endif
 366.281 +#  if !defined (INT32_MAX)
 366.282 +#   define INT32_MAX  2147483647L
 366.283 +#  endif
 366.284 +#  if !defined (INTMAX_MAX)
 366.285 +#   define INTMAX_MAX INT64_MAX
 366.286 +#  endif
 366.287 +#  if !defined (INTMAX_MIN)
 366.288 +#   define INTMAX_MIN INT64_MIN
 366.289 +#  endif
 366.290 +# endif
 366.291 +#endif
 366.292 +
 366.293 +#ifndef _PSTDINT_H_INCLUDED
 366.294 +#define _PSTDINT_H_INCLUDED
 366.295 +
 366.296 +#ifndef SIZE_MAX
 366.297 +# define SIZE_MAX (~(size_t)0)
 366.298 +#endif
 366.299 +
 366.300 +/*
 366.301 + *  Deduce the type assignments from limits.h under the assumption that
 366.302 + *  integer sizes in bits are powers of 2, and follow the ANSI
 366.303 + *  definitions.
 366.304 + */
 366.305 +
 366.306 +#ifndef UINT8_MAX
 366.307 +# define UINT8_MAX 0xff
 366.308 +#endif
 366.309 +#ifndef uint8_t
 366.310 +# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
 366.311 +    typedef unsigned char uint8_t;
 366.312 +#   define UINT8_C(v) ((uint8_t) v)
 366.313 +# else
 366.314 +#   error "Platform not supported"
 366.315 +# endif
 366.316 +#endif
 366.317 +
 366.318 +#ifndef INT8_MAX
 366.319 +# define INT8_MAX 0x7f
 366.320 +#endif
 366.321 +#ifndef INT8_MIN
 366.322 +# define INT8_MIN INT8_C(0x80)
 366.323 +#endif
 366.324 +#ifndef int8_t
 366.325 +# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
 366.326 +    typedef signed char int8_t;
 366.327 +#   define INT8_C(v) ((int8_t) v)
 366.328 +# else
 366.329 +#   error "Platform not supported"
 366.330 +# endif
 366.331 +#endif
 366.332 +
 366.333 +#ifndef UINT16_MAX
 366.334 +# define UINT16_MAX 0xffff
 366.335 +#endif
 366.336 +#ifndef uint16_t
 366.337 +#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
 366.338 +  typedef unsigned int uint16_t;
 366.339 +# ifndef PRINTF_INT16_MODIFIER
 366.340 +#  define PRINTF_INT16_MODIFIER ""
 366.341 +# endif
 366.342 +# define UINT16_C(v) ((uint16_t) (v))
 366.343 +#elif (USHRT_MAX == UINT16_MAX)
 366.344 +  typedef unsigned short uint16_t;
 366.345 +# define UINT16_C(v) ((uint16_t) (v))
 366.346 +# ifndef PRINTF_INT16_MODIFIER
 366.347 +#  define PRINTF_INT16_MODIFIER "h"
 366.348 +# endif
 366.349 +#else
 366.350 +#error "Platform not supported"
 366.351 +#endif
 366.352 +#endif
 366.353 +
 366.354 +#ifndef INT16_MAX
 366.355 +# define INT16_MAX 0x7fff
 366.356 +#endif
 366.357 +#ifndef INT16_MIN
 366.358 +# define INT16_MIN INT16_C(0x8000)
 366.359 +#endif
 366.360 +#ifndef int16_t
 366.361 +#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
 366.362 +  typedef signed int int16_t;
 366.363 +# define INT16_C(v) ((int16_t) (v))
 366.364 +# ifndef PRINTF_INT16_MODIFIER
 366.365 +#  define PRINTF_INT16_MODIFIER ""
 366.366 +# endif
 366.367 +#elif (SHRT_MAX == INT16_MAX)
 366.368 +  typedef signed short int16_t;
 366.369 +# define INT16_C(v) ((int16_t) (v))
 366.370 +# ifndef PRINTF_INT16_MODIFIER
 366.371 +#  define PRINTF_INT16_MODIFIER "h"
 366.372 +# endif
 366.373 +#else
 366.374 +#error "Platform not supported"
 366.375 +#endif
 366.376 +#endif
 366.377 +
 366.378 +#ifndef UINT32_MAX
 366.379 +# define UINT32_MAX (0xffffffffUL)
 366.380 +#endif
 366.381 +#ifndef uint32_t
 366.382 +#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
 366.383 +  typedef unsigned long uint32_t;
 366.384 +# define UINT32_C(v) v ## UL
 366.385 +# ifndef PRINTF_INT32_MODIFIER
 366.386 +#  define PRINTF_INT32_MODIFIER "l"
 366.387 +# endif
 366.388 +#elif (UINT_MAX == UINT32_MAX)
 366.389 +  typedef unsigned int uint32_t;
 366.390 +# ifndef PRINTF_INT32_MODIFIER
 366.391 +#  define PRINTF_INT32_MODIFIER ""
 366.392 +# endif
 366.393 +# define UINT32_C(v) v ## U
 366.394 +#elif (USHRT_MAX == UINT32_MAX)
 366.395 +  typedef unsigned short uint32_t;
 366.396 +# define UINT32_C(v) ((unsigned short) (v))
 366.397 +# ifndef PRINTF_INT32_MODIFIER
 366.398 +#  define PRINTF_INT32_MODIFIER ""
 366.399 +# endif
 366.400 +#else
 366.401 +#error "Platform not supported"
 366.402 +#endif
 366.403 +#endif
 366.404 +
 366.405 +#ifndef INT32_MAX
 366.406 +# define INT32_MAX (0x7fffffffL)
 366.407 +#endif
 366.408 +#ifndef INT32_MIN
 366.409 +# define INT32_MIN INT32_C(0x80000000)
 366.410 +#endif
 366.411 +#ifndef int32_t
 366.412 +#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
 366.413 +  typedef signed long int32_t;
 366.414 +# define INT32_C(v) v ## L
 366.415 +# ifndef PRINTF_INT32_MODIFIER
 366.416 +#  define PRINTF_INT32_MODIFIER "l"
 366.417 +# endif
 366.418 +#elif (INT_MAX == INT32_MAX)
 366.419 +  typedef signed int int32_t;
 366.420 +# define INT32_C(v) v
 366.421 +# ifndef PRINTF_INT32_MODIFIER
 366.422 +#  define PRINTF_INT32_MODIFIER ""
 366.423 +# endif
 366.424 +#elif (SHRT_MAX == INT32_MAX)
 366.425 +  typedef signed short int32_t;
 366.426 +# define INT32_C(v) ((short) (v))
 366.427 +# ifndef PRINTF_INT32_MODIFIER
 366.428 +#  define PRINTF_INT32_MODIFIER ""
 366.429 +# endif
 366.430 +#else
 366.431 +#error "Platform not supported"
 366.432 +#endif
 366.433 +#endif
 366.434 +
 366.435 +/*
 366.436 + *  The macro stdint_int64_defined is temporarily used to record
 366.437 + *  whether or not 64 integer support is available.  It must be
 366.438 + *  defined for any 64 integer extensions for new platforms that are
 366.439 + *  added.
 366.440 + */
 366.441 +
 366.442 +#undef stdint_int64_defined
 366.443 +#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
 366.444 +# if (__STDC__ && __STDC_VERSION >= 199901L) || defined (S_SPLINT_S)
 366.445 +#  define stdint_int64_defined
 366.446 +   typedef long long int64_t;
 366.447 +   typedef unsigned long long uint64_t;
 366.448 +#  define UINT64_C(v) v ## ULL
 366.449 +#  define  INT64_C(v) v ## LL
 366.450 +#  ifndef PRINTF_INT64_MODIFIER
 366.451 +#   define PRINTF_INT64_MODIFIER "ll"
 366.452 +#  endif
 366.453 +# endif
 366.454 +#endif
 366.455 +
 366.456 +#if !defined (stdint_int64_defined)
 366.457 +# if defined(__GNUC__)
 366.458 +#  define stdint_int64_defined
 366.459 +   __extension__ typedef long long int64_t;
 366.460 +   __extension__ typedef unsigned long long uint64_t;
 366.461 +#  define UINT64_C(v) v ## ULL
 366.462 +#  define  INT64_C(v) v ## LL
 366.463 +#  ifndef PRINTF_INT64_MODIFIER
 366.464 +#   define PRINTF_INT64_MODIFIER "ll"
 366.465 +#  endif
 366.466 +# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
 366.467 +#  define stdint_int64_defined
 366.468 +   typedef long long int64_t;
 366.469 +   typedef unsigned long long uint64_t;
 366.470 +#  define UINT64_C(v) v ## ULL
 366.471 +#  define  INT64_C(v) v ## LL
 366.472 +#  ifndef PRINTF_INT64_MODIFIER
 366.473 +#   define PRINTF_INT64_MODIFIER "ll"
 366.474 +#  endif
 366.475 +# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
 366.476 +#  define stdint_int64_defined
 366.477 +   typedef __int64 int64_t;
 366.478 +   typedef unsigned __int64 uint64_t;
 366.479 +#  define UINT64_C(v) v ## UI64
 366.480 +#  define  INT64_C(v) v ## I64
 366.481 +#  ifndef PRINTF_INT64_MODIFIER
 366.482 +#   define PRINTF_INT64_MODIFIER "I64"
 366.483 +#  endif
 366.484 +# endif
 366.485 +#endif
 366.486 +
 366.487 +#if !defined (LONG_LONG_MAX) && defined (INT64_C)
 366.488 +# define LONG_LONG_MAX INT64_C (9223372036854775807)
 366.489 +#endif
 366.490 +#ifndef ULONG_LONG_MAX
 366.491 +# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
 366.492 +#endif
 366.493 +
 366.494 +#if !defined (INT64_MAX) && defined (INT64_C)
 366.495 +# define INT64_MAX INT64_C (9223372036854775807)
 366.496 +#endif
 366.497 +#if !defined (INT64_MIN) && defined (INT64_C)
 366.498 +# define INT64_MIN INT64_C (-9223372036854775808)
 366.499 +#endif
 366.500 +#if !defined (UINT64_MAX) && defined (INT64_C)
 366.501 +# define UINT64_MAX UINT64_C (18446744073709551615)
 366.502 +#endif
 366.503 +
 366.504 +/*
 366.505 + *  Width of hexadecimal for number field.
 366.506 + */
 366.507 +
 366.508 +#ifndef PRINTF_INT64_HEX_WIDTH
 366.509 +# define PRINTF_INT64_HEX_WIDTH "16"
 366.510 +#endif
 366.511 +#ifndef PRINTF_INT32_HEX_WIDTH
 366.512 +# define PRINTF_INT32_HEX_WIDTH "8"
 366.513 +#endif
 366.514 +#ifndef PRINTF_INT16_HEX_WIDTH
 366.515 +# define PRINTF_INT16_HEX_WIDTH "4"
 366.516 +#endif
 366.517 +#ifndef PRINTF_INT8_HEX_WIDTH
 366.518 +# define PRINTF_INT8_HEX_WIDTH "2"
 366.519 +#endif
 366.520 +
 366.521 +#ifndef PRINTF_INT64_DEC_WIDTH
 366.522 +# define PRINTF_INT64_DEC_WIDTH "20"
 366.523 +#endif
 366.524 +#ifndef PRINTF_INT32_DEC_WIDTH
 366.525 +# define PRINTF_INT32_DEC_WIDTH "10"
 366.526 +#endif
 366.527 +#ifndef PRINTF_INT16_DEC_WIDTH
 366.528 +# define PRINTF_INT16_DEC_WIDTH "5"
 366.529 +#endif
 366.530 +#ifndef PRINTF_INT8_DEC_WIDTH
 366.531 +# define PRINTF_INT8_DEC_WIDTH "3"
 366.532 +#endif
 366.533 +
 366.534 +/*
 366.535 + *  Ok, lets not worry about 128 bit integers for now.  Moore's law says
 366.536 + *  we don't need to worry about that until about 2040 at which point
 366.537 + *  we'll have bigger things to worry about.
 366.538 + */
 366.539 +
 366.540 +#ifdef stdint_int64_defined
 366.541 +  typedef int64_t intmax_t;
 366.542 +  typedef uint64_t uintmax_t;
 366.543 +# define  INTMAX_MAX   INT64_MAX
 366.544 +# define  INTMAX_MIN   INT64_MIN
 366.545 +# define UINTMAX_MAX  UINT64_MAX
 366.546 +# define UINTMAX_C(v) UINT64_C(v)
 366.547 +# define  INTMAX_C(v)  INT64_C(v)
 366.548 +# ifndef PRINTF_INTMAX_MODIFIER
 366.549 +#   define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
 366.550 +# endif
 366.551 +# ifndef PRINTF_INTMAX_HEX_WIDTH
 366.552 +#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
 366.553 +# endif
 366.554 +# ifndef PRINTF_INTMAX_DEC_WIDTH
 366.555 +#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
 366.556 +# endif
 366.557 +#else
 366.558 +  typedef int32_t intmax_t;
 366.559 +  typedef uint32_t uintmax_t;
 366.560 +# define  INTMAX_MAX   INT32_MAX
 366.561 +# define UINTMAX_MAX  UINT32_MAX
 366.562 +# define UINTMAX_C(v) UINT32_C(v)
 366.563 +# define  INTMAX_C(v)  INT32_C(v)
 366.564 +# ifndef PRINTF_INTMAX_MODIFIER
 366.565 +#   define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
 366.566 +# endif
 366.567 +# ifndef PRINTF_INTMAX_HEX_WIDTH
 366.568 +#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
 366.569 +# endif
 366.570 +# ifndef PRINTF_INTMAX_DEC_WIDTH
 366.571 +#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
 366.572 +# endif
 366.573 +#endif
 366.574 +
 366.575 +/*
 366.576 + *  Because this file currently only supports platforms which have
 366.577 + *  precise powers of 2 as bit sizes for the default integers, the
 366.578 + *  least definitions are all trivial.  Its possible that a future
 366.579 + *  version of this file could have different definitions.
 366.580 + */
 366.581 +
 366.582 +#ifndef stdint_least_defined
 366.583 +  typedef   int8_t   int_least8_t;
 366.584 +  typedef  uint8_t  uint_least8_t;
 366.585 +  typedef  int16_t  int_least16_t;
 366.586 +  typedef uint16_t uint_least16_t;
 366.587 +  typedef  int32_t  int_least32_t;
 366.588 +  typedef uint32_t uint_least32_t;
 366.589 +# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
 366.590 +# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
 366.591 +# define  UINT_LEAST8_MAX  UINT8_MAX
 366.592 +# define   INT_LEAST8_MAX   INT8_MAX
 366.593 +# define UINT_LEAST16_MAX UINT16_MAX
 366.594 +# define  INT_LEAST16_MAX  INT16_MAX
 366.595 +# define UINT_LEAST32_MAX UINT32_MAX
 366.596 +# define  INT_LEAST32_MAX  INT32_MAX
 366.597 +# define   INT_LEAST8_MIN   INT8_MIN
 366.598 +# define  INT_LEAST16_MIN  INT16_MIN
 366.599 +# define  INT_LEAST32_MIN  INT32_MIN
 366.600 +# ifdef stdint_int64_defined
 366.601 +    typedef  int64_t  int_least64_t;
 366.602 +    typedef uint64_t uint_least64_t;
 366.603 +#   define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
 366.604 +#   define UINT_LEAST64_MAX UINT64_MAX
 366.605 +#   define  INT_LEAST64_MAX  INT64_MAX
 366.606 +#   define  INT_LEAST64_MIN  INT64_MIN
 366.607 +# endif
 366.608 +#endif
 366.609 +#undef stdint_least_defined
 366.610 +
 366.611 +/*
 366.612 + *  The ANSI C committee pretending to know or specify anything about
 366.613 + *  performance is the epitome of misguided arrogance.  The mandate of
 366.614 + *  this file is to *ONLY* ever support that absolute minimum
 366.615 + *  definition of the fast integer types, for compatibility purposes.
 366.616 + *  No extensions, and no attempt to suggest what may or may not be a
 366.617 + *  faster integer type will ever be made in this file.  Developers are
 366.618 + *  warned to stay away from these types when using this or any other
 366.619 + *  stdint.h.
 366.620 + */
 366.621 +
 366.622 +typedef   int_least8_t   int_fast8_t;
 366.623 +typedef  uint_least8_t  uint_fast8_t;
 366.624 +typedef  int_least16_t  int_fast16_t;
 366.625 +typedef uint_least16_t uint_fast16_t;
 366.626 +typedef  int_least32_t  int_fast32_t;
 366.627 +typedef uint_least32_t uint_fast32_t;
 366.628 +#define  UINT_FAST8_MAX  UINT_LEAST8_MAX
 366.629 +#define   INT_FAST8_MAX   INT_LEAST8_MAX
 366.630 +#define UINT_FAST16_MAX UINT_LEAST16_MAX
 366.631 +#define  INT_FAST16_MAX  INT_LEAST16_MAX
 366.632 +#define UINT_FAST32_MAX UINT_LEAST32_MAX
 366.633 +#define  INT_FAST32_MAX  INT_LEAST32_MAX
 366.634 +#define   INT_FAST8_MIN   INT_LEAST8_MIN
 366.635 +#define  INT_FAST16_MIN  INT_LEAST16_MIN
 366.636 +#define  INT_FAST32_MIN  INT_LEAST32_MIN
 366.637 +#ifdef stdint_int64_defined
 366.638 +  typedef  int_least64_t  int_fast64_t;
 366.639 +  typedef uint_least64_t uint_fast64_t;
 366.640 +# define UINT_FAST64_MAX UINT_LEAST64_MAX
 366.641 +# define  INT_FAST64_MAX  INT_LEAST64_MAX
 366.642 +# define  INT_FAST64_MIN  INT_LEAST64_MIN
 366.643 +#endif
 366.644 +
 366.645 +#undef stdint_int64_defined
 366.646 +
 366.647 +/*
 366.648 + *  Whatever piecemeal, per compiler thing we can do about the wchar_t
 366.649 + *  type limits.
 366.650 + */
 366.651 +
 366.652 +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__)
 366.653 +# include <wchar.h>
 366.654 +# ifndef WCHAR_MIN
 366.655 +#  define WCHAR_MIN 0
 366.656 +# endif
 366.657 +# ifndef WCHAR_MAX
 366.658 +#  define WCHAR_MAX ((wchar_t)-1)
 366.659 +# endif
 366.660 +#endif
 366.661 +
 366.662 +/*
 366.663 + *  Whatever piecemeal, per compiler/platform thing we can do about the
 366.664 + *  (u)intptr_t types and limits.
 366.665 + */
 366.666 +
 366.667 +#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)
 366.668 +# define STDINT_H_UINTPTR_T_DEFINED
 366.669 +#endif
 366.670 +
 366.671 +#ifndef STDINT_H_UINTPTR_T_DEFINED
 366.672 +# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64)
 366.673 +#  define stdint_intptr_bits 64
 366.674 +# elif defined (__WATCOMC__) || defined (__TURBOC__)
 366.675 +#  if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
 366.676 +#    define stdint_intptr_bits 16
 366.677 +#  else
 366.678 +#    define stdint_intptr_bits 32
 366.679 +#  endif
 366.680 +# elif defined (__i386__) || defined (_WIN32) || defined (WIN32)
 366.681 +#  define stdint_intptr_bits 32
 366.682 +# elif defined (__INTEL_COMPILER)
 366.683 +/* TODO -- what will Intel do about x86-64? */
 366.684 +# endif
 366.685 +
 366.686 +# ifdef stdint_intptr_bits
 366.687 +#  define stdint_intptr_glue3_i(a,b,c)  a##b##c
 366.688 +#  define stdint_intptr_glue3(a,b,c)    stdint_intptr_glue3_i(a,b,c)
 366.689 +#  ifndef PRINTF_INTPTR_MODIFIER
 366.690 +#    define PRINTF_INTPTR_MODIFIER      stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
 366.691 +#  endif
 366.692 +#  ifndef PTRDIFF_MAX
 366.693 +#    define PTRDIFF_MAX                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
 366.694 +#  endif
 366.695 +#  ifndef PTRDIFF_MIN
 366.696 +#    define PTRDIFF_MIN                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
 366.697 +#  endif
 366.698 +#  ifndef UINTPTR_MAX
 366.699 +#    define UINTPTR_MAX                 stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
 366.700 +#  endif
 366.701 +#  ifndef INTPTR_MAX
 366.702 +#    define INTPTR_MAX                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
 366.703 +#  endif
 366.704 +#  ifndef INTPTR_MIN
 366.705 +#    define INTPTR_MIN                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
 366.706 +#  endif
 366.707 +#  ifndef INTPTR_C
 366.708 +#    define INTPTR_C(x)                 stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
 366.709 +#  endif
 366.710 +#  ifndef UINTPTR_C
 366.711 +#    define UINTPTR_C(x)                stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
 366.712 +#  endif
 366.713 +  typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
 366.714 +  typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t)  intptr_t;
 366.715 +# else
 366.716 +/* TODO -- This following is likely wrong for some platforms, and does
 366.717 +   nothing for the definition of uintptr_t. */
 366.718 +  typedef ptrdiff_t intptr_t;
 366.719 +# endif
 366.720 +# define STDINT_H_UINTPTR_T_DEFINED
 366.721 +#endif
 366.722 +
 366.723 +/*
 366.724 + *  Assumes sig_atomic_t is signed and we have a 2s complement machine.
 366.725 + */
 366.726 +
 366.727 +#ifndef SIG_ATOMIC_MAX
 366.728 +# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
 366.729 +#endif
 366.730 +
 366.731 +#endif
 366.732 +
   367.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   367.2 +++ b/libs/assimp/qnan.h	Sat Feb 01 19:58:19 2014 +0200
   367.3 @@ -0,0 +1,110 @@
   367.4 +/*
   367.5 +---------------------------------------------------------------------------
   367.6 +Open Asset Import Library (assimp)
   367.7 +---------------------------------------------------------------------------
   367.8 +
   367.9 +Copyright (c) 2006-2012, assimp team
  367.10 +
  367.11 +All rights reserved.
  367.12 +
  367.13 +Redistribution and use of this software in source and binary forms, 
  367.14 +with or without modification, are permitted provided that the following 
  367.15 +conditions are met:
  367.16 +
  367.17 +* Redistributions of source code must retain the above
  367.18 +  copyright notice, this list of conditions and the
  367.19 +  following disclaimer.
  367.20 +
  367.21 +* Redistributions in binary form must reproduce the above
  367.22 +  copyright notice, this list of conditions and the
  367.23 +  following disclaimer in the documentation and/or other
  367.24 +  materials provided with the distribution.
  367.25 +
  367.26 +* Neither the name of the assimp team, nor the names of its
  367.27 +  contributors may be used to endorse or promote products
  367.28 +  derived from this software without specific prior
  367.29 +  written permission of the assimp team.
  367.30 +
  367.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  367.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  367.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  367.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
  367.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  367.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  367.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  367.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  367.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  367.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  367.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  367.42 +---------------------------------------------------------------------------
  367.43 +*/
  367.44 +
  367.45 +/**  @file  qnan.h
  367.46 + *   @brief Some utilities for our dealings with qnans.
  367.47 + *
  367.48 + *   @note Some loaders use qnans to mark invalid values tempoarily, also
  367.49 + *     Assimp explicitly enforces undefined normals to be set to qnan.
  367.50 + *     qnan utilities are available in standard libraries (C99 for example)
  367.51 + *     but last time I checked compiler coverage was so bad that I decided
  367.52 + *     to reinvent the wheel.
  367.53 + */
  367.54 +
  367.55 +#ifndef AI_QNAN_H_INCLUDED
  367.56 +#define AI_QNAN_H_INCLUDED
  367.57 +
  367.58 +// ---------------------------------------------------------------------------
  367.59 +/** Data structure to represent the bit pattern of a 32 Bit 
  367.60 + *         IEEE 754 floating-point number. */
  367.61 +union _IEEESingle
  367.62 +{
  367.63 +	float Float;
  367.64 +	struct
  367.65 +	{
  367.66 +		uint32_t Frac : 23;
  367.67 +		uint32_t Exp  : 8;
  367.68 +		uint32_t Sign : 1;
  367.69 +	} IEEE;
  367.70 +} ;
  367.71 +
  367.72 +// ---------------------------------------------------------------------------
  367.73 +/** Check whether a given float is qNaN. 
  367.74 + *  @param in Input value */
  367.75 +AI_FORCE_INLINE bool is_qnan(float in)	
  367.76 +{
  367.77 +	// the straightforward solution does not work:
  367.78 +	//   return (in != in);
  367.79 +	// compiler generates code like this
  367.80 +	//   load <in> to <register-with-different-width>
  367.81 +	//   compare <register-with-different-width> against <in>
  367.82 +
  367.83 +	// FIXME: Use <float> stuff instead? I think fpclassify needs C99
  367.84 +	return (reinterpret_cast<_IEEESingle*>(&in)->IEEE.Exp == (1u << 8)-1 &&
  367.85 +		reinterpret_cast<_IEEESingle*>(&in)->IEEE.Frac);
  367.86 +}
  367.87 +
  367.88 +// ---------------------------------------------------------------------------
  367.89 +/** Check whether a float is NOT qNaN. 
  367.90 + *  @param in Input value */
  367.91 +AI_FORCE_INLINE bool is_not_qnan(float in)	
  367.92 +{
  367.93 +	return !is_qnan(in);
  367.94 +}
  367.95 +
  367.96 +// ---------------------------------------------------------------------------
  367.97 +/** @brief check whether a float is either NaN or (+/-) INF. 
  367.98 + *
  367.99 + *  Denorms return false, they're treated like normal values.
 367.100 + *  @param in Input value */
 367.101 +AI_FORCE_INLINE bool is_special_float(float in)
 367.102 +{
 367.103 +	return (reinterpret_cast<_IEEESingle*>(&in)->IEEE.Exp == (1u << 8)-1);
 367.104 +}
 367.105 +
 367.106 +// ---------------------------------------------------------------------------
 367.107 +/** @brief Get a fresh qnan.  */
 367.108 +AI_FORCE_INLINE float get_qnan()
 367.109 +{
 367.110 +	return std::numeric_limits<float>::quiet_NaN();
 367.111 +}
 367.112 +
 367.113 +#endif // !! AI_QNAN_H_INCLUDED
   368.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   368.2 +++ b/libs/assimp/revision.h	Sat Feb 01 19:58:19 2014 +0200
   368.3 @@ -0,0 +1,1 @@
   368.4 +#define SVNRevision  1270 
   369.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   369.2 +++ b/libs/drawtext/drawgl.c	Sat Feb 01 19:58:19 2014 +0200
   369.3 @@ -0,0 +1,307 @@
   369.4 +/*
   369.5 +libdrawtext - a simple library for fast text rendering in OpenGL
   369.6 +Copyright (C) 2011-2012  John Tsiombikas <nuclear@member.fsf.org>
   369.7 +
   369.8 +This program is free software: you can redistribute it and/or modify
   369.9 +it under the terms of the GNU Lesser General Public License as published by
  369.10 +the Free Software Foundation, either version 3 of the License, or
  369.11 +(at your option) any later version.
  369.12 +
  369.13 +This program is distributed in the hope that it will be useful,
  369.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  369.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  369.16 +GNU Lesser General Public License for more details.
  369.17 +
  369.18 +You should have received a copy of the GNU Lesser General Public License
  369.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  369.20 +*/
  369.21 +#ifndef NO_OPENGL
  369.22 +#include <stdarg.h>
  369.23 +#include <math.h>
  369.24 +#include <ctype.h>
  369.25 +
  369.26 +#include <stdlib.h>
  369.27 +
  369.28 +#ifdef _MSC_VER
  369.29 +#include <malloc.h>
  369.30 +#else
  369.31 +#include <alloca.h>
  369.32 +#endif
  369.33 +
  369.34 +#ifdef TARGET_IPHONE
  369.35 +#include <OpenGLES/ES2/gl.h>
  369.36 +
  369.37 +#define GL_CLAMP	GL_CLAMP_TO_EDGE
  369.38 +
  369.39 +#else
  369.40 +#include <GL/glew.h>
  369.41 +#endif
  369.42 +
  369.43 +#include "drawtext.h"
  369.44 +#include "drawtext_impl.h"
  369.45 +
  369.46 +struct vertex {
  369.47 +	float x, y;
  369.48 +	float s, t;
  369.49 +};
  369.50 +
  369.51 +struct quad {
  369.52 +	struct vertex v[6];
  369.53 +};
  369.54 +
  369.55 +static void cleanup(void);
  369.56 +static void add_glyph(struct glyph *g, float x, float y);
  369.57 +
  369.58 +#define QBUF_SZ		512
  369.59 +static struct quad *qbuf;
  369.60 +static int num_quads;
  369.61 +static int vattr = -1;
  369.62 +static int tattr = -1;
  369.63 +static unsigned int font_tex;
  369.64 +static int buf_mode = DTX_NBF;
  369.65 +
  369.66 +
  369.67 +int dtx_gl_init(void)
  369.68 +{
  369.69 +	if(qbuf) {
  369.70 +		return 0;	/* already initialized */
  369.71 +	}
  369.72 +
  369.73 +	/*glewInit();*/
  369.74 +
  369.75 +	if(!(qbuf = malloc(QBUF_SZ * sizeof *qbuf))) {
  369.76 +		return -1;
  369.77 +	}
  369.78 +	num_quads = 0;
  369.79 +
  369.80 +	atexit(cleanup);
  369.81 +	return 0;
  369.82 +}
  369.83 +
  369.84 +static void cleanup(void)
  369.85 +{
  369.86 +	free(qbuf);
  369.87 +}
  369.88 +
  369.89 +
  369.90 +void dtx_vertex_attribs(int vert_attr, int tex_attr)
  369.91 +{
  369.92 +	vattr = vert_attr;
  369.93 +	tattr = tex_attr;
  369.94 +}
  369.95 +
  369.96 +static void set_glyphmap_texture(struct dtx_glyphmap *gmap)
  369.97 +{
  369.98 +	if(!gmap->tex) {
  369.99 +		glGenTextures(1, &gmap->tex);
 369.100 +		glBindTexture(GL_TEXTURE_2D, gmap->tex);
 369.101 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 369.102 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 369.103 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
 369.104 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 369.105 +
 369.106 +#ifdef GL_ES_VERSION_2_0
 369.107 +		glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gmap->xsz, gmap->ysz, 0, GL_ALPHA, GL_UNSIGNED_BYTE, gmap->pixels);
 369.108 +		glGenerateMipmap(GL_TEXTURE_2D);
 369.109 +#else
 369.110 +		gluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, gmap->xsz, gmap->ysz, GL_ALPHA, GL_UNSIGNED_BYTE, gmap->pixels);
 369.111 +#endif
 369.112 +	}
 369.113 +
 369.114 +	if(font_tex != gmap->tex) {
 369.115 +		dtx_flush();
 369.116 +	}
 369.117 +	font_tex = gmap->tex;
 369.118 +}
 369.119 +
 369.120 +void dtx_glyph(int code)
 369.121 +{
 369.122 +	struct dtx_glyphmap *gmap;
 369.123 +
 369.124 +	if(!dtx_font || !(gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code))) {
 369.125 +		return;
 369.126 +	}
 369.127 +	set_glyphmap_texture(gmap);
 369.128 +
 369.129 +	add_glyph(gmap->glyphs + code - gmap->cstart, 0, 0);
 369.130 +	dtx_flush();
 369.131 +}
 369.132 +
 369.133 +static const char *put_char(const char *str, float *pos_x, float *pos_y, int *should_flush)
 369.134 +{
 369.135 +	struct dtx_glyphmap *gmap;
 369.136 +	float px, py;
 369.137 +	int code = dtx_utf8_char_code(str);
 369.138 +	str = dtx_utf8_next_char((char*)str);
 369.139 +
 369.140 +	if(buf_mode == DTX_LBF && code == '\n') {
 369.141 +		*should_flush = 1;
 369.142 +	}
 369.143 +
 369.144 +	px = *pos_x;
 369.145 +	py = *pos_y;
 369.146 +
 369.147 +	if((gmap = dtx_proc_char(code, pos_x, pos_y))) {
 369.148 +		int idx = code - gmap->cstart;
 369.149 +
 369.150 +		set_glyphmap_texture(gmap);
 369.151 +		add_glyph(gmap->glyphs + idx, px, py);
 369.152 +	}
 369.153 +	return str;
 369.154 +}
 369.155 +
 369.156 +void dtx_string(const char *str)
 369.157 +{
 369.158 +	int should_flush = buf_mode == DTX_NBF;
 369.159 +	float pos_x = 0.0f;
 369.160 +	float pos_y = 0.0f;
 369.161 +
 369.162 +	if(!dtx_font) {
 369.163 +		return;
 369.164 +	}
 369.165 +
 369.166 +	while(*str) {
 369.167 +		str = put_char(str, &pos_x, &pos_y, &should_flush);
 369.168 +	}
 369.169 +
 369.170 +	if(should_flush) {
 369.171 +		dtx_flush();
 369.172 +	}
 369.173 +}
 369.174 +
 369.175 +void dtx_printf(const char *fmt, ...)
 369.176 +{
 369.177 +	va_list ap;
 369.178 +	int buf_size;
 369.179 +	char *buf, tmp;
 369.180 +
 369.181 +	if(!dtx_font) {
 369.182 +		return;
 369.183 +	}
 369.184 +
 369.185 +	va_start(ap, fmt);
 369.186 +	buf_size = vsnprintf(&tmp, 0, fmt, ap);
 369.187 +	va_end(ap);
 369.188 +
 369.189 +	if(buf_size == -1) {
 369.190 +		buf_size = 512;
 369.191 +	}
 369.192 +
 369.193 +	buf = alloca(buf_size + 1);
 369.194 +	va_start(ap, fmt);
 369.195 +	vsnprintf(buf, buf_size + 1, fmt, ap);
 369.196 +	va_end(ap);
 369.197 +
 369.198 +	dtx_string(buf);
 369.199 +}
 369.200 +
 369.201 +static void qvertex(struct vertex *v, float x, float y, float s, float t)
 369.202 +{
 369.203 +	v->x = x;
 369.204 +	v->y = y;
 369.205 +	v->s = s;
 369.206 +	v->t = t;
 369.207 +}
 369.208 +
 369.209 +static void add_glyph(struct glyph *g, float x, float y)
 369.210 +{
 369.211 +	struct quad *qptr = qbuf + num_quads;
 369.212 +
 369.213 +	x -= g->orig_x;
 369.214 +	y -= g->orig_y;
 369.215 +
 369.216 +	qvertex(qptr->v + 0, x, y, g->nx, g->ny + g->nheight);
 369.217 +	qvertex(qptr->v + 1, x + g->width, y, g->nx + g->nwidth, g->ny + g->nheight);
 369.218 +	qvertex(qptr->v + 2, x + g->width, y + g->height, g->nx + g->nwidth, g->ny);
 369.219 +
 369.220 +	qvertex(qptr->v + 3, x, y, g->nx, g->ny + g->nheight);
 369.221 +	qvertex(qptr->v + 4, x + g->width, y + g->height, g->nx + g->nwidth, g->ny);
 369.222 +	qvertex(qptr->v + 5, x, y + g->height, g->nx, g->ny);
 369.223 +
 369.224 +	if(++num_quads >= QBUF_SZ) {
 369.225 +		dtx_flush();
 369.226 +	}
 369.227 +}
 369.228 +
 369.229 +void dtx_draw_buffering(int mode)
 369.230 +{
 369.231 +	dtx_flush();
 369.232 +	buf_mode = mode;
 369.233 +}
 369.234 +
 369.235 +void dtx_flush(void)
 369.236 +{
 369.237 +	int vbo;
 369.238 +
 369.239 +	if(!num_quads) {
 369.240 +		return;
 369.241 +	}
 369.242 +
 369.243 +	if(glBindBuffer) {
 369.244 +		glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vbo);
 369.245 +		glBindBuffer(GL_ARRAY_BUFFER, 0);
 369.246 +	}
 369.247 +
 369.248 +#ifndef GL_ES_VERSION_2_0
 369.249 +	glPushAttrib(GL_ENABLE_BIT);
 369.250 +	glEnable(GL_TEXTURE_2D);
 369.251 +#endif
 369.252 +	glBindTexture(GL_TEXTURE_2D, font_tex);
 369.253 +
 369.254 +	if(vattr != -1 && glEnableVertexAttribArray) {
 369.255 +		glEnableVertexAttribArray(vattr);
 369.256 +		glVertexAttribPointer(vattr, 2, GL_FLOAT, 0, sizeof(struct vertex), qbuf);
 369.257 +#ifndef GL_ES_VERSION_2_0
 369.258 +	} else {
 369.259 +		glEnableClientState(GL_VERTEX_ARRAY);
 369.260 +		glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), qbuf);
 369.261 +#endif
 369.262 +	}
 369.263 +	if(tattr != -1 && glEnableVertexAttribArray) {
 369.264 +		glEnableVertexAttribArray(tattr);
 369.265 +		glVertexAttribPointer(tattr, 2, GL_FLOAT, 0, sizeof(struct vertex), &qbuf->v[0].s);
 369.266 +#ifndef GL_ES_VERSION_2_0
 369.267 +	} else {
 369.268 +		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 369.269 +		glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), &qbuf->v[0].s);
 369.270 +#endif
 369.271 +	}
 369.272 +
 369.273 +	glEnable(GL_BLEND);
 369.274 +	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 369.275 +
 369.276 +	glDepthMask(0);
 369.277 +
 369.278 +	glDrawArrays(GL_TRIANGLES, 0, num_quads * 6);
 369.279 +
 369.280 +	glDepthMask(1);
 369.281 +
 369.282 +	if(vattr != -1 && glDisableVertexAttribArray) {
 369.283 +		glDisableVertexAttribArray(vattr);
 369.284 +#ifndef GL_ES_VERSION_2_0
 369.285 +	} else {
 369.286 +		glDisableClientState(GL_VERTEX_ARRAY);
 369.287 +#endif
 369.288 +	}
 369.289 +	if(tattr != -1 && glDisableVertexAttribArray) {
 369.290 +		glDisableVertexAttribArray(tattr);
 369.291 +#ifndef GL_ES_VERSION_2_0
 369.292 +	} else {
 369.293 +		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 369.294 +#endif
 369.295 +	}
 369.296 +
 369.297 +#ifndef GL_ES_VERSION_2_0
 369.298 +	glPopAttrib();
 369.299 +#else
 369.300 +	glDisable(GL_BLEND);
 369.301 +#endif
 369.302 +
 369.303 +	if(glBindBuffer && vbo) {
 369.304 +		glBindBuffer(GL_ARRAY_BUFFER, vbo);
 369.305 +	}
 369.306 +
 369.307 +	num_quads = 0;
 369.308 +}
 369.309 +
 369.310 +#endif	/* !def NO_OPENGL */
   370.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   370.2 +++ b/libs/drawtext/drawtext.h	Sat Feb 01 19:58:19 2014 +0200
   370.3 @@ -0,0 +1,182 @@
   370.4 +/*
   370.5 +libdrawtext - a simple library for fast text rendering in OpenGL
   370.6 +Copyright (C) 2011-2012  John Tsiombikas <nuclear@member.fsf.org>
   370.7 +
   370.8 +This program is free software: you can redistribute it and/or modify
   370.9 +it under the terms of the GNU Lesser General Public License as published by
  370.10 +the Free Software Foundation, either version 3 of the License, or
  370.11 +(at your option) any later version.
  370.12 +
  370.13 +This program is distributed in the hope that it will be useful,
  370.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  370.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  370.16 +GNU Lesser General Public License for more details.
  370.17 +
  370.18 +You should have received a copy of the GNU Lesser General Public License
  370.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  370.20 +*/
  370.21 +#ifndef TEXT_H_
  370.22 +#define TEXT_H_
  370.23 +
  370.24 +#include <stdio.h>
  370.25 +#include <stdlib.h>
  370.26 +
  370.27 +struct dtx_font;
  370.28 +struct dtx_glyphmap;
  370.29 +
  370.30 +/* draw buffering modes */
  370.31 +enum {
  370.32 +	DTX_NBF,	/* unbuffered */
  370.33 +	DTX_LBF,	/* line buffered */
  370.34 +	DTX_FBF		/* fully buffered */
  370.35 +};
  370.36 +
  370.37 +struct dtx_box {
  370.38 +	float x, y;
  370.39 +	float width, height;
  370.40 +};
  370.41 +
  370.42 +#ifdef __cplusplus
  370.43 +extern "C" {
  370.44 +#endif
  370.45 +
  370.46 +/* Open a truetype/opentype/whatever font.
  370.47 + *
  370.48 + * If sz is non-zero, the default ASCII glyphmap at the requested point size is
  370.49 + * automatically created as well, and ready to use.
  370.50 + *
  370.51 + * To use other unicode ranges and different font sizes you must first call
  370.52 + * dtx_prepare or dtx_prepare_range before issuing any drawing calls, otherwise
  370.53 + * nothing will be rendered.
  370.54 + */
  370.55 +struct dtx_font *dtx_open_font(const char *fname, int sz);
  370.56 +void dtx_close_font(struct dtx_font *fnt);
  370.57 +
  370.58 +/* prepare an ASCII glyphmap for the specified font size */
  370.59 +void dtx_prepare(struct dtx_font *fnt, int sz);
  370.60 +/* prepare an arbitrary unicode range glyphmap for the specified font size */
  370.61 +void dtx_prepare_range(struct dtx_font *fnt, int sz, int cstart, int cend);
  370.62 +
  370.63 +/* Finds the glyphmap that contains the specified character code and matches the requested size
  370.64 + * Returns null if it hasn't been created (you should call dtx_prepare/dtx_prepare_range).
  370.65 + */
  370.66 +struct dtx_glyphmap *dtx_get_font_glyphmap(struct dtx_font *fnt, int sz, int code);
  370.67 +
  370.68 +/* Finds the glyphmap that contains the specified unicode range and matches the requested font size
  370.69 + * Will automatically generate one if it can't find it.
  370.70 + */
  370.71 +struct dtx_glyphmap *dtx_get_font_glyphmap_range(struct dtx_font *fnt, int sz, int cstart, int cend);
  370.72 +
  370.73 +/* Creates and returns a glyphmap for a particular unicode range and font size.
  370.74 + * The generated glyphmap is added to the font's list of glyphmaps.
  370.75 + */
  370.76 +struct dtx_glyphmap *dtx_create_glyphmap_range(struct dtx_font *fnt, int sz, int cstart, int cend);
  370.77 +/* free a glyphmap */
  370.78 +void dtx_free_glyphmap(struct dtx_glyphmap *gmap);
  370.79 +
  370.80 +/* returns a pointer to the raster image of a glyphmap (1 byte per pixel grayscale) */
  370.81 +unsigned char *dtx_get_glyphmap_image(struct dtx_glyphmap *gmap);
  370.82 +/* returns the width of the glyphmap image in pixels */
  370.83 +int dtx_get_glyphmap_width(struct dtx_glyphmap *gmap);
  370.84 +/* returns the height of the glyphmap image in pixels */
  370.85 +int dtx_get_glyphmap_height(struct dtx_glyphmap *gmap);
  370.86 +
  370.87 +/* The following functions can be used even when the library is compiled without
  370.88 + * freetype support. (TODO)
  370.89 + */
  370.90 +struct dtx_glyphmap *dtx_load_glyphmap(const char *fname);
  370.91 +struct dtx_glyphmap *dtx_load_glyphmap_stream(FILE *fp);
  370.92 +int dtx_save_glyphmap(const char *fname, const struct dtx_glyphmap *gmap);
  370.93 +int dtx_save_glyphmap_stream(FILE *fp, const struct dtx_glyphmap *gmap);
  370.94 +
  370.95 +
  370.96 +/* ---- rendering ---- */
  370.97 +
  370.98 +/* before drawing anything this function must set the font to use */
  370.99 +void dtx_use_font(struct dtx_font *fnt, int sz);
 370.100 +
 370.101 +/* sets the buffering mode
 370.102 + * - DTX_NBF: every call to dtx_string gets rendered immediately.
 370.103 + * - DTX_LBF: renders when the buffer is full or the string contains a newline.
 370.104 + * - DTX_FBF: renders only when the buffer is full (you must call dtx_flush explicitly).
 370.105 + */
 370.106 +void dtx_draw_buffering(int mode);
 370.107 +
 370.108 +/* Sets the vertex attribute indices to use for passing vertex and texture coordinate
 370.109 + * data. By default both are -1 which means you don't have to use a shader, and if you
 370.110 + * do they are accessible through gl_Vertex and gl_MultiTexCoord0, as usual.
 370.111 + *
 370.112 + * NOTE: If you are using OpenGL ES 2.x or OpenGL >= 3.1 pure (non-compatibility) context
 370.113 + * you must specify valid attribute indices.
 370.114 + */
 370.115 +void dtx_vertex_attribs(int vert_attr, int tex_attr);
 370.116 +
 370.117 +/* draws a single glyph at the origin */
 370.118 +void dtx_glyph(int code);
 370.119 +/* draws a utf-8 string starting at the origin. \n \r and \t are handled appropriately. */
 370.120 +void dtx_string(const char *str);
 370.121 +
 370.122 +void dtx_printf(const char *fmt, ...);
 370.123 +
 370.124 +/* render any pending glyphs (see dtx_draw_buffering) */
 370.125 +void dtx_flush(void);
 370.126 +
 370.127 +
 370.128 +/* ---- encodings ---- */
 370.129 +
 370.130 +/* returns a pointer to the next character in a utf-8 stream */
 370.131 +char *dtx_utf8_next_char(char *str);
 370.132 +
 370.133 +/* returns the unicode character codepoint of the utf-8 character starting at str */
 370.134 +int dtx_utf8_char_code(const char *str);
 370.135 +
 370.136 +/* returns the number of bytes of the utf-8 character starting at str */
 370.137 +int dtx_utf8_nbytes(const char *str);
 370.138 +
 370.139 +/* returns the number of utf-8 character in a zero-terminated utf-8 string */
 370.140 +int dtx_utf8_char_count(const char *str);
 370.141 +
 370.142 +/* Converts a unicode code-point to a utf-8 character by filling in the buffer
 370.143 + * passed at the second argument, and returns the number of bytes taken by that
 370.144 + * utf-8 character.
 370.145 + * It's valid to pass a null buffer pointer, in which case only the byte count is
 370.146 + * returned (useful to figure out how much memory to allocate for a buffer).
 370.147 + */
 370.148 +size_t dtx_utf8_from_char_code(int code, char *buf);
 370.149 +
 370.150 +/* Converts a unicode utf-16 wchar_t string to utf-8, filling in the buffer passed
 370.151 + * at the second argument. Returns the size of the resulting string in bytes.
 370.152 + *
 370.153 + * It's valid to pass a null buffer pointer, in which case only the size gets
 370.154 + * calculated and returned, which is useful for figuring out how much memory to
 370.155 + * allocate for the utf-8 buffer.
 370.156 + */
 370.157 +size_t dtx_utf8_from_string(const wchar_t *str, char *buf);
 370.158 +
 370.159 +
 370.160 +/* ---- metrics ---- */
 370.161 +float dtx_line_height(void);
 370.162 +float dtx_baseline(void);
 370.163 +
 370.164 +/* rendered dimensions of a single glyph */
 370.165 +void dtx_glyph_box(int code, struct dtx_box *box);
 370.166 +float dtx_glyph_width(int code);
 370.167 +float dtx_glyph_height(int code);
 370.168 +
 370.169 +/* rendered dimensions of a string */
 370.170 +void dtx_string_box(const char *str, struct dtx_box *box);
 370.171 +float dtx_string_width(const char *str);
 370.172 +float dtx_string_height(const char *str);
 370.173 +
 370.174 +/* returns the horizontal position of the n-th character of the rendered string
 370.175 + * (useful for placing cursors)
 370.176 + */
 370.177 +float dtx_char_pos(const char *str, int n);
 370.178 +
 370.179 +int dtx_char_at_pt(const char *str, float pt);
 370.180 +
 370.181 +#ifdef __cplusplus
 370.182 +}
 370.183 +#endif
 370.184 +
 370.185 +#endif	/* TEXT_H_ */
   371.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   371.2 +++ b/libs/drawtext/drawtext_impl.h	Sat Feb 01 19:58:19 2014 +0200
   371.3 @@ -0,0 +1,73 @@
   371.4 +/*
   371.5 +libdrawtext - a simple library for fast text rendering in OpenGL
   371.6 +Copyright (C) 2011-2012  John Tsiombikas <nuclear@member.fsf.org>
   371.7 +
   371.8 +This program is free software: you can redistribute it and/or modify
   371.9 +it under the terms of the GNU Lesser General Public License as published by
  371.10 +the Free Software Foundation, either version 3 of the License, or
  371.11 +(at your option) any later version.
  371.12 +
  371.13 +This program is distributed in the hope that it will be useful,
  371.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  371.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  371.16 +GNU Lesser General Public License for more details.
  371.17 +
  371.18 +You should have received a copy of the GNU Lesser General Public License
  371.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  371.20 +*/
  371.21 +#ifndef TEXT_IMPL_H_
  371.22 +#define TEXT_IMPL_H_
  371.23 +
  371.24 +struct glyph {
  371.25 +	int code;
  371.26 +	float x, y, width, height;
  371.27 +	/* normalized coords [0, 1] */
  371.28 +	float nx, ny, nwidth, nheight;
  371.29 +	float orig_x, orig_y;
  371.30 +	float advance;
  371.31 +	struct glyph *next;
  371.32 +};
  371.33 +
  371.34 +struct dtx_glyphmap {
  371.35 +	int ptsize;
  371.36 +
  371.37 +	int xsz, ysz;
  371.38 +	unsigned char *pixels;
  371.39 +	unsigned int tex;
  371.40 +
  371.41 +	int cstart, cend;	/* character range */
  371.42 +	int crange;
  371.43 +
  371.44 +	float line_advance;
  371.45 +	float baseline;
  371.46 +
  371.47 +	struct glyph *glyphs;
  371.48 +	struct dtx_glyphmap *next;
  371.49 +};
  371.50 +
  371.51 +struct dtx_font {
  371.52 +	/* freetype FT_Face */
  371.53 +	void *face;
  371.54 +
  371.55 +	/* list of glyphmaps */
  371.56 +	struct dtx_glyphmap *gmaps;
  371.57 +
  371.58 +	/* last returned glyphmap (cache) */
  371.59 +	struct dtx_glyphmap *last_gmap;
  371.60 +};
  371.61 +
  371.62 +
  371.63 +struct dtx_font *dtx_font;
  371.64 +int dtx_font_sz;
  371.65 +
  371.66 +
  371.67 +#define fperror(str) \
  371.68 +	fprintf(stderr, "%s: %s: %s\n", __FUNCTION__, (str), strerror(errno))
  371.69 +
  371.70 +int dtx_gl_init(void);
  371.71 +
  371.72 +/* returns zero if it should NOT be printed and modifies xpos/ypos */
  371.73 +/* implemented in font.c */
  371.74 +struct dtx_glyphmap *dtx_proc_char(int code, float *xpos, float *ypos);
  371.75 +
  371.76 +#endif	/* TEXT_IMPL_H_ */
   372.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   372.2 +++ b/libs/drawtext/font.c	Sat Feb 01 19:58:19 2014 +0200
   372.3 @@ -0,0 +1,697 @@
   372.4 +/*
   372.5 +libdrawtext - a simple library for fast text rendering in OpenGL
   372.6 +Copyright (C) 2011  John Tsiombikas <nuclear@member.fsf.org>
   372.7 +
   372.8 +This program is free software: you can redistribute it and/or modify
   372.9 +it under the terms of the GNU Lesser General Public License as published by
  372.10 +the Free Software Foundation, either version 3 of the License, or
  372.11 +(at your option) any later version.
  372.12 +
  372.13 +This program is distributed in the hope that it will be useful,
  372.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  372.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  372.16 +GNU Lesser General Public License for more details.
  372.17 +
  372.18 +You should have received a copy of the GNU Lesser General Public License
  372.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  372.20 +*/
  372.21 +#ifndef NO_FREETYPE
  372.22 +#define USE_FREETYPE
  372.23 +#endif
  372.24 +
  372.25 +#include <stdio.h>
  372.26 +#include <stdlib.h>
  372.27 +#include <string.h>
  372.28 +#include <math.h>
  372.29 +#include <limits.h>
  372.30 +#include <ctype.h>
  372.31 +#include <float.h>
  372.32 +#include <errno.h>
  372.33 +#ifdef USE_FREETYPE
  372.34 +#include <ft2build.h>
  372.35 +#include FT_FREETYPE_H
  372.36 +#endif
  372.37 +#include "drawtext.h"
  372.38 +#include "drawtext_impl.h"
  372.39 +
  372.40 +#define FTSZ_TO_PIXELS(x)	((x) / 64)
  372.41 +#define MAX_IMG_WIDTH		4096
  372.42 +
  372.43 +
  372.44 +#ifdef USE_FREETYPE
  372.45 +static int init_freetype(void);
  372.46 +static void cleanup(void);
  372.47 +
  372.48 +static void calc_best_size(int total_width, int max_glyph_height, int padding, int pow2, int *imgw, int *imgh);
  372.49 +static int next_pow2(int x);
  372.50 +
  372.51 +static FT_Library ft;
  372.52 +
  372.53 +
  372.54 +static int init_done;
  372.55 +
  372.56 +static int init_freetype(void)
  372.57 +{
  372.58 +	if(!init_done) {
  372.59 +		if(FT_Init_FreeType(&ft) != 0) {
  372.60 +			return -1;
  372.61 +		}
  372.62 +		atexit(cleanup);
  372.63 +		init_done = 1;
  372.64 +	}
  372.65 +	return 0;
  372.66 +}
  372.67 +
  372.68 +static void cleanup(void)
  372.69 +{
  372.70 +	if(init_done) {
  372.71 +		FT_Done_FreeType(ft);
  372.72 +	}
  372.73 +}
  372.74 +
  372.75 +struct dtx_font *dtx_open_font(const char *fname, int sz)
  372.76 +{
  372.77 +	struct dtx_font *fnt;
  372.78 +
  372.79 +	init_freetype();
  372.80 +
  372.81 +	if(!(fnt = calloc(1, sizeof *fnt))) {
  372.82 +		fperror("failed to allocate font structure");
  372.83 +		return 0;
  372.84 +	}
  372.85 +
  372.86 +	if(FT_New_Face(ft, fname, 0, (FT_Face*)&fnt->face) != 0) {
  372.87 +		fprintf(stderr, "failed to open font file: %s\n", fname);
  372.88 +		return 0;
  372.89 +	}
  372.90 +
  372.91 +	/* pre-create the extended ASCII range glyphmap */
  372.92 +	if(sz) {
  372.93 +		dtx_prepare_range(fnt, sz, 0, 256);
  372.94 +
  372.95 +		if(!dtx_font) {
  372.96 +			dtx_use_font(fnt, sz);
  372.97 +		}
  372.98 +	}
  372.99 +
 372.100 +	return fnt;
 372.101 +}
 372.102 +
 372.103 +void dtx_close_font(struct dtx_font *fnt)
 372.104 +{
 372.105 +	if(!fnt) return;
 372.106 +
 372.107 +	FT_Done_Face(fnt->face);
 372.108 +
 372.109 +	/* destroy the glyphmaps */
 372.110 +	while(fnt->gmaps) {
 372.111 +		void *tmp = fnt->gmaps;
 372.112 +		fnt->gmaps = fnt->gmaps->next;
 372.113 +		dtx_free_glyphmap(tmp);
 372.114 +	}
 372.115 +
 372.116 +	free(fnt);
 372.117 +}
 372.118 +
 372.119 +void dtx_prepare(struct dtx_font *fnt, int sz)
 372.120 +{
 372.121 +	dtx_get_font_glyphmap_range(fnt, sz, 0, 256);
 372.122 +}
 372.123 +
 372.124 +void dtx_prepare_range(struct dtx_font *fnt, int sz, int cstart, int cend)
 372.125 +{
 372.126 +	dtx_get_font_glyphmap_range(fnt, sz, cstart, cend);
 372.127 +}
 372.128 +
 372.129 +struct dtx_glyphmap *dtx_get_font_glyphmap(struct dtx_font *fnt, int sz, int code)
 372.130 +{
 372.131 +	struct dtx_glyphmap *gm;
 372.132 +
 372.133 +	/* check to see if the last we've given out fits the bill */
 372.134 +	if(fnt->last_gmap && code >= fnt->last_gmap->cstart && code < fnt->last_gmap->cend && fnt->last_gmap->ptsize == sz) {
 372.135 +		return fnt->last_gmap;
 372.136 +	}
 372.137 +
 372.138 +	/* otherwise search for the appropriate glyphmap */
 372.139 +	gm = fnt->gmaps;
 372.140 +	while(gm) {
 372.141 +		if(code >= gm->cstart && code < gm->cend && sz == gm->ptsize) {
 372.142 +			fnt->last_gmap = gm;
 372.143 +			return gm;
 372.144 +		}
 372.145 +		gm = gm->next;
 372.146 +	}
 372.147 +	return 0;
 372.148 +}
 372.149 +
 372.150 +struct dtx_glyphmap *dtx_get_font_glyphmap_range(struct dtx_font *fnt, int sz, int cstart, int cend)
 372.151 +{
 372.152 +	struct dtx_glyphmap *gm;
 372.153 +
 372.154 +	/* search the available glyphmaps to see if we've got one that includes
 372.155 +	 * the requested range
 372.156 +	 */
 372.157 +	gm = fnt->gmaps;
 372.158 +	while(gm) {
 372.159 +		if(gm->cstart <= cstart && gm->cend >= cend && gm->ptsize == sz) {
 372.160 +			return gm;
 372.161 +		}
 372.162 +		gm = gm->next;
 372.163 +	}
 372.164 +
 372.165 +	/* not found, create one and add it to the list */
 372.166 +	if(!(gm = dtx_create_glyphmap_range(fnt, sz, cstart, cend))) {
 372.167 +		return 0;
 372.168 +	}
 372.169 +	return gm;
 372.170 +}
 372.171 +
 372.172 +struct dtx_glyphmap *dtx_create_glyphmap_range(struct dtx_font *fnt, int sz, int cstart, int cend)
 372.173 +{
 372.174 +	FT_Face face = fnt->face;
 372.175 +	struct dtx_glyphmap *gmap;
 372.176 +	int i, j;
 372.177 +	int gx, gy;
 372.178 +	int padding = 4;
 372.179 +	int total_width = padding;
 372.180 +	int max_height = 0;
 372.181 +
 372.182 +	FT_Set_Char_Size(fnt->face, 0, sz * 64, 72, 72);
 372.183 +
 372.184 +	if(!(gmap = calloc(1, sizeof *gmap))) {
 372.185 +		return 0;
 372.186 +	}
 372.187 +
 372.188 +	gmap->ptsize = sz;
 372.189 +	gmap->cstart = cstart;
 372.190 +	gmap->cend = cend;
 372.191 +	gmap->crange = cend - cstart;
 372.192 +	gmap->line_advance = FTSZ_TO_PIXELS((float)face->size->metrics.height);
 372.193 +	gmap->baseline = -FTSZ_TO_PIXELS((float)face->size->metrics.descender);
 372.194 +
 372.195 +	if(!(gmap->glyphs = malloc(gmap->crange * sizeof *gmap->glyphs))) {
 372.196 +		free(gmap);
 372.197 +		return 0;
 372.198 +	}
 372.199 +
 372.200 +	for(i=0; i<gmap->crange; i++) {
 372.201 +		int h;
 372.202 +
 372.203 +		FT_Load_Char(face, i + cstart, 0);
 372.204 +		h = FTSZ_TO_PIXELS(face->glyph->metrics.height);
 372.205 +
 372.206 +		if(h > max_height) {
 372.207 +			max_height = h;
 372.208 +		}
 372.209 +		total_width += FTSZ_TO_PIXELS(face->glyph->metrics.width) + padding;
 372.210 +	}
 372.211 +
 372.212 +	calc_best_size(total_width, max_height, padding, 1, &gmap->xsz, &gmap->ysz);
 372.213 +
 372.214 +	if(!(gmap->pixels = malloc(gmap->xsz * gmap->ysz))) {
 372.215 +		free(gmap->glyphs);
 372.216 +		free(gmap);
 372.217 +		return 0;
 372.218 +	}
 372.219 +	memset(gmap->pixels, 0, gmap->xsz * gmap->ysz);
 372.220 +
 372.221 +	gx = padding;
 372.222 +	gy = padding;
 372.223 +
 372.224 +	for(i=0; i<gmap->crange; i++) {
 372.225 +		float gwidth, gheight;
 372.226 +		unsigned char *src, *dst;
 372.227 +		FT_GlyphSlot glyph;
 372.228 +
 372.229 +		FT_Load_Char(face, i + cstart, FT_LOAD_RENDER);
 372.230 +		glyph = face->glyph;
 372.231 +		gwidth = FTSZ_TO_PIXELS((float)glyph->metrics.width);
 372.232 +		gheight = FTSZ_TO_PIXELS((float)glyph->metrics.height);
 372.233 +
 372.234 +		if(gx > gmap->xsz - gwidth - padding) {
 372.235 +			gx = padding;
 372.236 +			gy += max_height + padding;
 372.237 +		}
 372.238 +
 372.239 +		src = glyph->bitmap.buffer;
 372.240 +		dst = gmap->pixels + gy * gmap->xsz + gx;
 372.241 +
 372.242 +		for(j=0; j<glyph->bitmap.rows; j++) {
 372.243 +			memcpy(dst, src, glyph->bitmap.width);
 372.244 +			dst += gmap->xsz;
 372.245 +			src += glyph->bitmap.pitch;
 372.246 +		}
 372.247 +
 372.248 +		gmap->glyphs[i].code = i;
 372.249 +		gmap->glyphs[i].x = gx - 1;
 372.250 +		gmap->glyphs[i].y = gy - 1;
 372.251 +		gmap->glyphs[i].width = gwidth + 2;
 372.252 +		gmap->glyphs[i].height = gheight + 2;
 372.253 +		gmap->glyphs[i].orig_x = -FTSZ_TO_PIXELS((float)glyph->metrics.horiBearingX) + 1;
 372.254 +		gmap->glyphs[i].orig_y = FTSZ_TO_PIXELS((float)glyph->metrics.height - glyph->metrics.horiBearingY) + 1;
 372.255 +		gmap->glyphs[i].advance = FTSZ_TO_PIXELS((float)glyph->metrics.horiAdvance);
 372.256 +		/* also precalc normalized */
 372.257 +		gmap->glyphs[i].nx = (float)gmap->glyphs[i].x / (float)gmap->xsz;
 372.258 +		gmap->glyphs[i].ny = (float)gmap->glyphs[i].y / (float)gmap->ysz;
 372.259 +		gmap->glyphs[i].nwidth = (float)gmap->glyphs[i].width / (float)gmap->xsz;
 372.260 +		gmap->glyphs[i].nheight = (float)gmap->glyphs[i].height / (float)gmap->ysz;
 372.261 +
 372.262 +		gx += gwidth + padding;
 372.263 +	}
 372.264 +
 372.265 +	/* add it to the glyphmaps list of the font */
 372.266 +	gmap->next = fnt->gmaps;
 372.267 +	fnt->gmaps = gmap;
 372.268 +
 372.269 +	return gmap;
 372.270 +}
 372.271 +#endif	/* USE_FREETYPE */
 372.272 +
 372.273 +void dtx_free_glyphmap(struct dtx_glyphmap *gmap)
 372.274 +{
 372.275 +	if(gmap) {
 372.276 +		free(gmap->pixels);
 372.277 +		free(gmap->glyphs);
 372.278 +		free(gmap);
 372.279 +	}
 372.280 +}
 372.281 +
 372.282 +unsigned char *dtx_get_glyphmap_pixels(struct dtx_glyphmap *gmap)
 372.283 +{
 372.284 +	return gmap->pixels;
 372.285 +}
 372.286 +
 372.287 +int dtx_get_glyphmap_width(struct dtx_glyphmap *gmap)
 372.288 +{
 372.289 +	return gmap->xsz;
 372.290 +}
 372.291 +
 372.292 +int dtx_get_glyphmap_height(struct dtx_glyphmap *gmap)
 372.293 +{
 372.294 +	return gmap->ysz;
 372.295 +}
 372.296 +
 372.297 +struct dtx_glyphmap *dtx_load_glyphmap(const char *fname)
 372.298 +{
 372.299 +	FILE *fp;
 372.300 +	struct dtx_glyphmap *gmap;
 372.301 +
 372.302 +	if(!(fp = fopen(fname, "r"))) {
 372.303 +		return 0;
 372.304 +	}
 372.305 +	gmap = dtx_load_glyphmap_stream(fp);
 372.306 +	fclose(fp);
 372.307 +	return gmap;
 372.308 +}
 372.309 +
 372.310 +struct dtx_glyphmap *dtx_load_glyphmap_stream(FILE *fp)
 372.311 +{
 372.312 +	char buf[512];
 372.313 +	int hdr_lines = 0;
 372.314 +	struct dtx_glyphmap *gmap;
 372.315 +	struct glyph *glyphs = 0;
 372.316 +	int min_code = INT_MAX;
 372.317 +	int max_code = INT_MIN;
 372.318 +	int i, max_pixval, num_pixels;
 372.319 +
 372.320 +	if(!(gmap = calloc(1, sizeof *gmap))) {
 372.321 +		fperror("failed to allocate glyphmap");
 372.322 +		return 0;
 372.323 +	}
 372.324 +
 372.325 +	while(hdr_lines < 3) {
 372.326 +		char *line = buf;
 372.327 +		if(!fgets(buf, sizeof buf, fp)) {
 372.328 +			fperror("unexpected end of file");
 372.329 +			goto err;
 372.330 +		}
 372.331 +
 372.332 +		while(isspace(*line)) {
 372.333 +			line++;
 372.334 +		}
 372.335 +
 372.336 +		if(line[0] == '#') {
 372.337 +			struct glyph *g;
 372.338 +			int c;
 372.339 +			float x, y, xsz, ysz, res;
 372.340 +
 372.341 +			res = sscanf(line + 1, "%d: %fx%f+%f+%f\n", &c, &xsz, &ysz, &x, &y);
 372.342 +			if(res != 5) {
 372.343 +				fprintf(stderr, "%s: invalid glyph info line\n", __FUNCTION__);
 372.344 +				goto err;
 372.345 +			}
 372.346 +
 372.347 +			if(!(g = malloc(sizeof *g))) {
 372.348 +				fperror("failed to allocate glyph");
 372.349 +				goto err;
 372.350 +			}
 372.351 +			g->code = c;
 372.352 +			g->x = x;
 372.353 +			g->y = y;
 372.354 +			g->width = xsz;
 372.355 +			g->height = ysz;
 372.356 +			g->next = glyphs;
 372.357 +			glyphs = g;
 372.358 +
 372.359 +			if(c < min_code) {
 372.360 +				min_code = c;
 372.361 +			}
 372.362 +			if(c > max_code) {
 372.363 +				max_code = c;
 372.364 +			}
 372.365 +		} else {
 372.366 +			switch(hdr_lines) {
 372.367 +			case 0:
 372.368 +				if(0[line] != 'P' || 1[line] != '6') {
 372.369 +					fprintf(stderr, "%s: invalid file format (magic)\n", __FUNCTION__);
 372.370 +					goto err;
 372.371 +				}
 372.372 +				break;
 372.373 +
 372.374 +			case 1:
 372.375 +				if(sscanf(line, "%d %d", &gmap->xsz, &gmap->ysz) != 2) {
 372.376 +					fprintf(stderr, "%s: invalid file format (dim)\n", __FUNCTION__);
 372.377 +					goto err;
 372.378 +				}
 372.379 +				break;
 372.380 +
 372.381 +			case 2:
 372.382 +				{
 372.383 +					char *endp;
 372.384 +					max_pixval = strtol(line, &endp, 10);
 372.385 +					if(endp == line) {
 372.386 +						fprintf(stderr, "%s: invalid file format (maxval)\n", __FUNCTION__);
 372.387 +						goto err;
 372.388 +					}
 372.389 +				}
 372.390 +				break;
 372.391 +
 372.392 +			default:
 372.393 +				break;	/* can't happen */
 372.394 +			}
 372.395 +			hdr_lines++;
 372.396 +		}
 372.397 +	}
 372.398 +
 372.399 +	num_pixels = gmap->xsz * gmap->ysz;
 372.400 +	if(!(gmap->pixels = malloc(num_pixels))) {
 372.401 +		fperror("failed to allocate pixels");
 372.402 +		goto err;
 372.403 +	}
 372.404 +
 372.405 +	for(i=0; i<num_pixels; i++) {
 372.406 +		long c = fgetc(fp);
 372.407 +		if(c == -1) {
 372.408 +			fprintf(stderr, "unexpected end of file while reading pixels\n");
 372.409 +			goto err;
 372.410 +		}
 372.411 +		gmap->pixels[i] = 255 * c / max_pixval;
 372.412 +		fseek(fp, 2, SEEK_CUR);
 372.413 +	}
 372.414 +
 372.415 +	gmap->cstart = min_code;
 372.416 +	gmap->cend = max_code + 1;
 372.417 +	gmap->crange = gmap->cend - gmap->cstart;
 372.418 +
 372.419 +	if(!(gmap->glyphs = calloc(gmap->crange, sizeof *gmap->glyphs))) {
 372.420 +		fperror("failed to allocate glyph info");
 372.421 +		goto err;
 372.422 +	}
 372.423 +
 372.424 +	while(glyphs) {
 372.425 +		struct glyph *g = glyphs;
 372.426 +		glyphs = glyphs->next;
 372.427 +
 372.428 +		gmap->glyphs[g->code - gmap->cstart] = *g;
 372.429 +		free(g);
 372.430 +	}
 372.431 +	return gmap;
 372.432 +
 372.433 +err:
 372.434 +	dtx_free_glyphmap(gmap);
 372.435 +	while(glyphs) {
 372.436 +		void *tmp = glyphs;
 372.437 +		glyphs = glyphs->next;
 372.438 +		free(tmp);
 372.439 +	}
 372.440 +	return 0;
 372.441 +}
 372.442 +
 372.443 +int dtx_save_glyphmap(const char *fname, const struct dtx_glyphmap *gmap)
 372.444 +{
 372.445 +	FILE *fp;
 372.446 +	int res;
 372.447 +
 372.448 +	if(!(fp = fopen(fname, "wb"))) {
 372.449 +		fprintf(stderr, "%s: failed to open file: %s: %s\n", __FUNCTION__, fname, strerror(errno));
 372.450 +		return -1;
 372.451 +	}
 372.452 +	res = dtx_save_glyphmap_stream(fp, gmap);
 372.453 +	fclose(fp);
 372.454 +	return res;
 372.455 +}
 372.456 +
 372.457 +int dtx_save_glyphmap_stream(FILE *fp, const struct dtx_glyphmap *gmap)
 372.458 +{
 372.459 +	int i, num_pixels;
 372.460 +	struct glyph *g = gmap->glyphs;
 372.461 +
 372.462 +	fprintf(fp, "P6\n%d %d\n", gmap->xsz, gmap->ysz);
 372.463 +	for(i=0; i<gmap->crange; i++) {
 372.464 +		fprintf(fp, "# %d: %fx%f+%f+%f\n", g->code, g->width, g->height, g->x, g->y);
 372.465 +		g++;
 372.466 +	}
 372.467 +	fprintf(fp, "255\n");
 372.468 +
 372.469 +	num_pixels = gmap->xsz * gmap->ysz;
 372.470 +	for(i=0; i<num_pixels; i++) {
 372.471 +		int c = gmap->pixels[i];
 372.472 +		fputc(c, fp);
 372.473 +		fputc(c, fp);
 372.474 +		fputc(c, fp);
 372.475 +	}
 372.476 +	return 0;
 372.477 +}
 372.478 +
 372.479 +
 372.480 +void dtx_use_font(struct dtx_font *fnt, int sz)
 372.481 +{
 372.482 +	dtx_gl_init();
 372.483 +
 372.484 +	dtx_font = fnt;
 372.485 +	dtx_font_sz = sz;
 372.486 +}
 372.487 +
 372.488 +float dtx_line_height(void)
 372.489 +{
 372.490 +	struct dtx_glyphmap *gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, '\n');
 372.491 +
 372.492 +	return gmap->line_advance;
 372.493 +}
 372.494 +
 372.495 +float dtx_baseline(void)
 372.496 +{
 372.497 +	struct dtx_glyphmap *gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, '\n');
 372.498 +
 372.499 +	return gmap->baseline;
 372.500 +}
 372.501 +
 372.502 +void dtx_glyph_box(int code, struct dtx_box *box)
 372.503 +{
 372.504 +	int cidx;
 372.505 +	struct dtx_glyphmap *gmap;
 372.506 +	gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code);
 372.507 +
 372.508 +	cidx = code - gmap->cstart;
 372.509 +
 372.510 +	box->x = gmap->glyphs[cidx].orig_x;
 372.511 +	box->y = gmap->glyphs[cidx].orig_y;
 372.512 +	box->width = gmap->glyphs[cidx].width;
 372.513 +	box->height = gmap->glyphs[cidx].height;
 372.514 +}
 372.515 +
 372.516 +float dtx_glyph_width(int code)
 372.517 +{
 372.518 +	struct dtx_box box;
 372.519 +	dtx_glyph_box(code, &box);
 372.520 +	return box.width;
 372.521 +}
 372.522 +
 372.523 +float dtx_glyph_height(int code)
 372.524 +{
 372.525 +	struct dtx_box box;
 372.526 +	dtx_glyph_box(code, &box);
 372.527 +	return box.height;
 372.528 +}
 372.529 +
 372.530 +void dtx_string_box(const char *str, struct dtx_box *box)
 372.531 +{
 372.532 +	int code;
 372.533 +	float pos_x = 0.0f, pos_y = 0.0f;
 372.534 +	struct glyph *g = 0;
 372.535 +	float x0, y0, x1, y1;
 372.536 +
 372.537 +	x0 = y0 = FLT_MAX;
 372.538 +	x1 = y1 = -FLT_MAX;
 372.539 +
 372.540 +	while(*str) {
 372.541 +		float px, py;
 372.542 +		struct dtx_glyphmap *gmap;
 372.543 +
 372.544 +		code = dtx_utf8_char_code(str);
 372.545 +		str = dtx_utf8_next_char((char*)str);
 372.546 +
 372.547 +		px = pos_x;
 372.548 +		py = pos_y;
 372.549 +
 372.550 +		if((gmap = dtx_proc_char(code, &pos_x, &pos_y))) {
 372.551 +			g = gmap->glyphs + code - gmap->cstart;
 372.552 +
 372.553 +			if(px + g->orig_x < x0) {
 372.554 +				x0 = px + g->orig_x;
 372.555 +			}
 372.556 +			if(py - g->orig_y < y0) {
 372.557 +				y0 = py - g->orig_y;
 372.558 +			}
 372.559 +			if(px + g->orig_x + g->width > x1) {
 372.560 +				x1 = px + g->orig_x + g->width;
 372.561 +			}
 372.562 +			if(py - g->orig_y + g->height > y1) {
 372.563 +				y1 = py - g->orig_y + g->height;
 372.564 +			}
 372.565 +		}
 372.566 +	}
 372.567 +
 372.568 +	box->x = x0;
 372.569 +	box->y = y0;
 372.570 +	box->width = x1 - x0;
 372.571 +	box->height = y1 - y0;
 372.572 +}
 372.573 +
 372.574 +float dtx_string_width(const char *str)
 372.575 +{
 372.576 +	struct dtx_box box;
 372.577 +
 372.578 +	dtx_string_box(str, &box);
 372.579 +	return box.width;
 372.580 +}
 372.581 +
 372.582 +float dtx_string_height(const char *str)
 372.583 +{
 372.584 +	struct dtx_box box;
 372.585 +
 372.586 +	dtx_string_box(str, &box);
 372.587 +	return box.height;
 372.588 +}
 372.589 +
 372.590 +float dtx_char_pos(const char *str, int n)
 372.591 +{
 372.592 +	int i;
 372.593 +	float pos = 0.0;
 372.594 +	struct dtx_glyphmap *gmap;
 372.595 +
 372.596 +	for(i=0; i<n; i++) {
 372.597 +		int code = dtx_utf8_char_code(str);
 372.598 +		str = dtx_utf8_next_char((char*)str);
 372.599 +
 372.600 +		gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code);
 372.601 +		pos += gmap->glyphs[i].advance;
 372.602 +	}
 372.603 +	return pos;
 372.604 +}
 372.605 +
 372.606 +int dtx_char_at_pt(const char *str, float pt)
 372.607 +{
 372.608 +	int i;
 372.609 +	float prev_pos = 0.0f, pos = 0.0f;
 372.610 +	struct dtx_glyphmap *gmap;
 372.611 +
 372.612 +	for(i=0; *str; i++) {
 372.613 +		int code = dtx_utf8_char_code(str);
 372.614 +		str = dtx_utf8_next_char((char*)str);
 372.615 +
 372.616 +		gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code);
 372.617 +		pos += gmap->glyphs[i].advance;
 372.618 +
 372.619 +		if(fabs(pt - prev_pos) < fabs(pt - pos)) {
 372.620 +			break;
 372.621 +		}
 372.622 +		prev_pos = pos;
 372.623 +	}
 372.624 +	return i;
 372.625 +}
 372.626 +
 372.627 +struct dtx_glyphmap *dtx_proc_char(int code, float *xpos, float *ypos)
 372.628 +{
 372.629 +	struct dtx_glyphmap *gmap;
 372.630 +	gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code);
 372.631 +
 372.632 +	switch(code) {
 372.633 +	case '\n':
 372.634 +		*xpos = 0.0;
 372.635 +		if(gmap) {
 372.636 +			*ypos -= gmap->line_advance;
 372.637 +		}
 372.638 +		return 0;
 372.639 +
 372.640 +	case '\t':
 372.641 +		if(gmap) {
 372.642 +			*xpos = (fmod(*xpos, 4.0) + 4.0) * gmap->glyphs[0].advance;
 372.643 +		}
 372.644 +		return 0;
 372.645 +
 372.646 +	case '\r':
 372.647 +		*xpos = 0.0;
 372.648 +		return 0;
 372.649 +
 372.650 +	default:
 372.651 +		break;
 372.652 +	}
 372.653 +
 372.654 +	if(gmap) {
 372.655 +		*xpos += gmap->glyphs[code - gmap->cstart].advance;
 372.656 +	}
 372.657 +	return gmap;
 372.658 +}
 372.659 +
 372.660 +static void calc_best_size(int total_width, int max_glyph_height, int padding, int pow2, int *imgw, int *imgh)
 372.661 +{
 372.662 +	int xsz, ysz, num_rows;
 372.663 +	float aspect;
 372.664 +
 372.665 +	for(xsz=2; xsz<=MAX_IMG_WIDTH; xsz *= 2) {
 372.666 +		num_rows = total_width / xsz + 1;
 372.667 +
 372.668 +		/* take into account the one extra padding for each row after the first */
 372.669 +		num_rows = (total_width + padding * (num_rows - 1)) / xsz + 1;
 372.670 +
 372.671 +		ysz = num_rows * (max_glyph_height + padding) + padding;
 372.672 +		if(pow2) {
 372.673 +			ysz = next_pow2(ysz);
 372.674 +		}
 372.675 +		aspect = (float)xsz / (float)ysz;
 372.676 +
 372.677 +		if(aspect >= 1.0) {
 372.678 +			break;
 372.679 +		}
 372.680 +	}
 372.681 +
 372.682 +	if(xsz > MAX_IMG_WIDTH) {
 372.683 +		xsz = MAX_IMG_WIDTH;
 372.684 +	}
 372.685 +
 372.686 +	*imgw = xsz;
 372.687 +	*imgh = ysz;
 372.688 +}
 372.689 +
 372.690 +
 372.691 +static int next_pow2(int x)
 372.692 +{
 372.693 +	x--;
 372.694 +	x = (x >> 1) | x;
 372.695 +	x = (x >> 2) | x;
 372.696 +	x = (x >> 4) | x;
 372.697 +	x = (x >> 8) | x;
 372.698 +	x = (x >> 16) | x;
 372.699 +	return x + 1;
 372.700 +}
   373.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   373.2 +++ b/libs/drawtext/utf8.c	Sat Feb 01 19:58:19 2014 +0200
   373.3 @@ -0,0 +1,154 @@
   373.4 +/*
   373.5 +libdrawtext - a simple library for fast text rendering in OpenGL
   373.6 +Copyright (C) 2011  John Tsiombikas <nuclear@member.fsf.org>
   373.7 +
   373.8 +This program is free software: you can redistribute it and/or modify
   373.9 +it under the terms of the GNU Lesser General Public License as published by
  373.10 +the Free Software Foundation, either version 3 of the License, or
  373.11 +(at your option) any later version.
  373.12 +
  373.13 +This program is distributed in the hope that it will be useful,
  373.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  373.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  373.16 +GNU Lesser General Public License for more details.
  373.17 +
  373.18 +You should have received a copy of the GNU Lesser General Public License
  373.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  373.20 +*/
  373.21 +#include "drawtext.h"
  373.22 +
  373.23 +#define	U8_IS_FIRST(x)		(((((x) >> 7) & 1) == 0) || ((((x) >> 6) & 3) == 3))
  373.24 +
  373.25 +static const char first_mask[] = {
  373.26 +	0,
  373.27 +	0x7f,	/* single byte, 7 bits valid */
  373.28 +	0x1f,	/* two-bytes, 5 bits valid */
  373.29 +	0xf,	/* three-bytes, 4 bits valid */
  373.30 +	0x7		/* four-bytes, 3 bits valid */
  373.31 +};
  373.32 +static const char first_shift[] = { 0, 7, 5, 4, 3 };	/* see above */
  373.33 +
  373.34 +#define CONT_PREFIX	0x80
  373.35 +#define CONT_MASK	0x3f
  373.36 +#define CONT_SHIFT	6
  373.37 +
  373.38 +/* last charcodes for 1, 2, 3 or 4-byte utf8 chars */
  373.39 +static const int utf8_lastcode[] = { 0x7f, 0x7ff, 0xfff, 0x1fffff };
  373.40 +
  373.41 +#define prefix_mask(x)	(~first_mask[x])
  373.42 +#define prefix(x)		((prefix_mask(x) << 1) & 0xff)
  373.43 +
  373.44 +
  373.45 +char *dtx_utf8_next_char(char *str)
  373.46 +{
  373.47 +	return str + dtx_utf8_nbytes(str);
  373.48 +}
  373.49 +
  373.50 +int dtx_utf8_char_code(const char *str)
  373.51 +{
  373.52 +	int i, nbytes, shift, code = 0;
  373.53 +	int mask;
  373.54 +
  373.55 +	if(!U8_IS_FIRST(*str)) {
  373.56 +		return -1;
  373.57 +	}
  373.58 +
  373.59 +	nbytes = dtx_utf8_nbytes(str);
  373.60 +	mask = first_mask[nbytes];
  373.61 +	shift = 0;
  373.62 +
  373.63 +	for(i=0; i<nbytes; i++) {
  373.64 +		if(!*str) {
  373.65 +			break;
  373.66 +		}
  373.67 +
  373.68 +		code = (code << shift) | (*str++ & mask);
  373.69 +		mask = 0x3f;
  373.70 +		shift = 6;
  373.71 +	}
  373.72 +	return code;
  373.73 +}
  373.74 +
  373.75 +int dtx_utf8_nbytes(const char *str)
  373.76 +{
  373.77 +	int i, numset = 0;
  373.78 +	int c = *str;
  373.79 +
  373.80 +	if(!U8_IS_FIRST(c)) {
  373.81 +		for(i=0; !U8_IS_FIRST(str[i]); i++);
  373.82 +		return i;
  373.83 +	}
  373.84 +
  373.85 +	/* count the leading 1s */
  373.86 +	for(i=0; i<4; i++) {
  373.87 +		if(((c >> (7 - i)) & 1) == 0) {
  373.88 +			break;
  373.89 +		}
  373.90 +		numset++;
  373.91 +	}
  373.92 +
  373.93 +	if(!numset) {
  373.94 +		return 1;
  373.95 +	}
  373.96 +	return numset;
  373.97 +}
  373.98 +
  373.99 +int dtx_utf8_char_count(const char *str)
 373.100 +{
 373.101 +	int n = 0;
 373.102 +
 373.103 +	while(*str) {
 373.104 +		n++;
 373.105 +		str = dtx_utf8_next_char((char*)str);
 373.106 +	}
 373.107 +	return n;
 373.108 +}
 373.109 +
 373.110 +size_t dtx_utf8_from_char_code(int code, char *buf)
 373.111 +{
 373.112 +	size_t nbytes = 0;
 373.113 +	int i;
 373.114 +
 373.115 +	for(i=0; i<4; i++) {
 373.116 +		if(code <= utf8_lastcode[i]) {
 373.117 +			nbytes = i + 1;
 373.118 +			break;
 373.119 +		}
 373.120 +	}
 373.121 +
 373.122 +	if(!nbytes && buf) {
 373.123 +		for(i=0; i<(int)nbytes; i++) {
 373.124 +			int idx = nbytes - i - 1;
 373.125 +			int mask, shift, prefix;
 373.126 +
 373.127 +			if(idx > 0) {
 373.128 +				mask = CONT_MASK;
 373.129 +				shift = CONT_SHIFT;
 373.130 +				prefix = CONT_PREFIX;
 373.131 +			} else {
 373.132 +				mask = first_mask[nbytes];
 373.133 +				shift = first_shift[nbytes];
 373.134 +				prefix = prefix(nbytes);
 373.135 +			}
 373.136 +
 373.137 +			buf[idx] = (code & mask) | (prefix & ~mask);
 373.138 +			code >>= shift;
 373.139 +		}
 373.140 +	}
 373.141 +	return nbytes;
 373.142 +}
 373.143 +
 373.144 +size_t dtx_utf8_from_string(const wchar_t *str, char *buf)
 373.145 +{
 373.146 +	size_t nbytes = 0;
 373.147 +	char *ptr = buf;
 373.148 +
 373.149 +	while(*str) {
 373.150 +		int cbytes = dtx_utf8_from_char_code(*str++, ptr);
 373.151 +		if(ptr) {
 373.152 +			ptr += cbytes;
 373.153 +		}
 373.154 +		nbytes += cbytes;
 373.155 +	}
 373.156 +	return nbytes;
 373.157 +}
   374.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   374.2 +++ b/libs/ft2static/freetype/config/ftconfig.h	Sat Feb 01 19:58:19 2014 +0200
   374.3 @@ -0,0 +1,528 @@
   374.4 +/***************************************************************************/
   374.5 +/*                                                                         */
   374.6 +/*  ftconfig.h                                                             */
   374.7 +/*                                                                         */
   374.8 +/*    ANSI-specific configuration file (specification only).               */
   374.9 +/*                                                                         */
  374.10 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2010 by       */
  374.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  374.12 +/*                                                                         */
  374.13 +/*  This file is part of the FreeType project, and may only be used,       */
  374.14 +/*  modified, and distributed under the terms of the FreeType project      */
  374.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  374.16 +/*  this file you indicate that you have read the license and              */
  374.17 +/*  understand and accept it fully.                                        */
  374.18 +/*                                                                         */
  374.19 +/***************************************************************************/
  374.20 +
  374.21 +
  374.22 +  /*************************************************************************/
  374.23 +  /*                                                                       */
  374.24 +  /* This header file contains a number of macro definitions that are used */
  374.25 +  /* by the rest of the engine.  Most of the macros here are automatically */
  374.26 +  /* determined at compile time, and you should not need to change it to   */
  374.27 +  /* port FreeType, except to compile the library with a non-ANSI          */
  374.28 +  /* compiler.                                                             */
  374.29 +  /*                                                                       */
  374.30 +  /* Note however that if some specific modifications are needed, we       */
  374.31 +  /* advise you to place a modified copy in your build directory.          */
  374.32 +  /*                                                                       */
  374.33 +  /* The build directory is usually `freetype/builds/<system>', and        */
  374.34 +  /* contains system-specific files that are always included first when    */
  374.35 +  /* building the library.                                                 */
  374.36 +  /*                                                                       */
  374.37 +  /* This ANSI version should stay in `include/freetype/config'.           */
  374.38 +  /*                                                                       */
  374.39 +  /*************************************************************************/
  374.40 +
  374.41 +#ifndef __FTCONFIG_H__
  374.42 +#define __FTCONFIG_H__
  374.43 +
  374.44 +#include <ft2build.h>
  374.45 +#include FT_CONFIG_OPTIONS_H
  374.46 +#include FT_CONFIG_STANDARD_LIBRARY_H
  374.47 +
  374.48 +
  374.49 +FT_BEGIN_HEADER
  374.50 +
  374.51 +
  374.52 +  /*************************************************************************/
  374.53 +  /*                                                                       */
  374.54 +  /*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */
  374.55 +  /*                                                                       */
  374.56 +  /* These macros can be toggled to suit a specific system.  The current   */
  374.57 +  /* ones are defaults used to compile FreeType in an ANSI C environment   */
  374.58 +  /* (16bit compilers are also supported).  Copy this file to your own     */
  374.59 +  /* `freetype/builds/<system>' directory, and edit it to port the engine. */
  374.60 +  /*                                                                       */
  374.61 +  /*************************************************************************/
  374.62 +
  374.63 +
  374.64 +  /* There are systems (like the Texas Instruments 'C54x) where a `char' */
  374.65 +  /* has 16 bits.  ANSI C says that sizeof(char) is always 1.  Since an  */
  374.66 +  /* `int' has 16 bits also for this system, sizeof(int) gives 1 which   */
  374.67 +  /* is probably unexpected.                                             */
  374.68 +  /*                                                                     */
  374.69 +  /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a      */
  374.70 +  /* `char' type.                                                        */
  374.71 +
  374.72 +#ifndef FT_CHAR_BIT
  374.73 +#define FT_CHAR_BIT  CHAR_BIT
  374.74 +#endif
  374.75 +
  374.76 +
  374.77 +  /* The size of an `int' type.  */
  374.78 +#if                                 FT_UINT_MAX == 0xFFFFUL
  374.79 +#define FT_SIZEOF_INT  (16 / FT_CHAR_BIT)
  374.80 +#elif                               FT_UINT_MAX == 0xFFFFFFFFUL
  374.81 +#define FT_SIZEOF_INT  (32 / FT_CHAR_BIT)
  374.82 +#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
  374.83 +#define FT_SIZEOF_INT  (64 / FT_CHAR_BIT)
  374.84 +#else
  374.85 +#error "Unsupported size of `int' type!"
  374.86 +#endif
  374.87 +
  374.88 +  /* The size of a `long' type.  A five-byte `long' (as used e.g. on the */
  374.89 +  /* DM642) is recognized but avoided.                                   */
  374.90 +#if                                  FT_ULONG_MAX == 0xFFFFFFFFUL
  374.91 +#define FT_SIZEOF_LONG  (32 / FT_CHAR_BIT)
  374.92 +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
  374.93 +#define FT_SIZEOF_LONG  (32 / FT_CHAR_BIT)
  374.94 +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
  374.95 +#define FT_SIZEOF_LONG  (64 / FT_CHAR_BIT)
  374.96 +#else
  374.97 +#error "Unsupported size of `long' type!"
  374.98 +#endif
  374.99 +
 374.100 +
 374.101 +  /* Preferred alignment of data */
 374.102 +#define FT_ALIGNMENT  8
 374.103 +
 374.104 +
 374.105 +  /* FT_UNUSED is a macro used to indicate that a given parameter is not  */
 374.106 +  /* used -- this is only used to get rid of unpleasant compiler warnings */
 374.107 +#ifndef FT_UNUSED
 374.108 +#define FT_UNUSED( arg )  ( (arg) = (arg) )
 374.109 +#endif
 374.110 +
 374.111 +
 374.112 +  /*************************************************************************/
 374.113 +  /*                                                                       */
 374.114 +  /*                     AUTOMATIC CONFIGURATION MACROS                    */
 374.115 +  /*                                                                       */
 374.116 +  /* These macros are computed from the ones defined above.  Don't touch   */
 374.117 +  /* their definition, unless you know precisely what you are doing.  No   */
 374.118 +  /* porter should need to mess with them.                                 */
 374.119 +  /*                                                                       */
 374.120 +  /*************************************************************************/
 374.121 +
 374.122 +
 374.123 +  /*************************************************************************/
 374.124 +  /*                                                                       */
 374.125 +  /* Mac support                                                           */
 374.126 +  /*                                                                       */
 374.127 +  /*   This is the only necessary change, so it is defined here instead    */
 374.128 +  /*   providing a new configuration file.                                 */
 374.129 +  /*                                                                       */
 374.130 +#if ( defined( __APPLE__ ) && !defined( DARWIN_NO_CARBON ) ) || \
 374.131 +    ( defined( __MWERKS__ ) && defined( macintosh )        )
 374.132 +  /* no Carbon frameworks for 64bit 10.4.x */
 374.133 +#include "AvailabilityMacros.h"
 374.134 +#if defined( __LP64__ ) && \
 374.135 +    ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
 374.136 +#define DARWIN_NO_CARBON 1
 374.137 +#else
 374.138 +#define FT_MACINTOSH 1
 374.139 +#endif
 374.140 +
 374.141 +#elif defined( __SC__ ) || defined( __MRC__ )
 374.142 +  /* Classic MacOS compilers */
 374.143 +#include "ConditionalMacros.h"
 374.144 +#if TARGET_OS_MAC
 374.145 +#define FT_MACINTOSH 1
 374.146 +#endif
 374.147 +
 374.148 +#endif
 374.149 +
 374.150 +
 374.151 +  /*************************************************************************/
 374.152 +  /*                                                                       */
 374.153 +  /* <Section>                                                             */
 374.154 +  /*    basic_types                                                        */
 374.155 +  /*                                                                       */
 374.156 +  /*************************************************************************/
 374.157 +
 374.158 +
 374.159 +  /*************************************************************************/
 374.160 +  /*                                                                       */
 374.161 +  /* <Type>                                                                */
 374.162 +  /*    FT_Int16                                                           */
 374.163 +  /*                                                                       */
 374.164 +  /* <Description>                                                         */
 374.165 +  /*    A typedef for a 16bit signed integer type.                         */
 374.166 +  /*                                                                       */
 374.167 +  typedef signed short  FT_Int16;
 374.168 +
 374.169 +
 374.170 +  /*************************************************************************/
 374.171 +  /*                                                                       */
 374.172 +  /* <Type>                                                                */
 374.173 +  /*    FT_UInt16                                                          */
 374.174 +  /*                                                                       */
 374.175 +  /* <Description>                                                         */
 374.176 +  /*    A typedef for a 16bit unsigned integer type.                       */
 374.177 +  /*                                                                       */
 374.178 +  typedef unsigned short  FT_UInt16;
 374.179 +
 374.180 +  /* */
 374.181 +
 374.182 +
 374.183 +  /* this #if 0 ... #endif clause is for documentation purposes */
 374.184 +#if 0
 374.185 +
 374.186 +  /*************************************************************************/
 374.187 +  /*                                                                       */
 374.188 +  /* <Type>                                                                */
 374.189 +  /*    FT_Int32                                                           */
 374.190 +  /*                                                                       */
 374.191 +  /* <Description>                                                         */
 374.192 +  /*    A typedef for a 32bit signed integer type.  The size depends on    */
 374.193 +  /*    the configuration.                                                 */
 374.194 +  /*                                                                       */
 374.195 +  typedef signed XXX  FT_Int32;
 374.196 +
 374.197 +
 374.198 +  /*************************************************************************/
 374.199 +  /*                                                                       */
 374.200 +  /* <Type>                                                                */
 374.201 +  /*    FT_UInt32                                                          */
 374.202 +  /*                                                                       */
 374.203 +  /*    A typedef for a 32bit unsigned integer type.  The size depends on  */
 374.204 +  /*    the configuration.                                                 */
 374.205 +  /*                                                                       */
 374.206 +  typedef unsigned XXX  FT_UInt32;
 374.207 +
 374.208 +  /* */
 374.209 +
 374.210 +#endif
 374.211 +
 374.212 +#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT)
 374.213 +
 374.214 +  typedef signed int      FT_Int32;
 374.215 +  typedef unsigned int    FT_UInt32;
 374.216 +
 374.217 +#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT)
 374.218 +
 374.219 +  typedef signed long     FT_Int32;
 374.220 +  typedef unsigned long   FT_UInt32;
 374.221 +
 374.222 +#else
 374.223 +#error "no 32bit type found -- please check your configuration files"
 374.224 +#endif
 374.225 +
 374.226 +
 374.227 +  /* look up an integer type that is at least 32 bits */
 374.228 +#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT)
 374.229 +
 374.230 +  typedef int            FT_Fast;
 374.231 +  typedef unsigned int   FT_UFast;
 374.232 +
 374.233 +#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT)
 374.234 +
 374.235 +  typedef long           FT_Fast;
 374.236 +  typedef unsigned long  FT_UFast;
 374.237 +
 374.238 +#endif
 374.239 +
 374.240 +
 374.241 +  /* determine whether we have a 64-bit int type for platforms without */
 374.242 +  /* Autoconf                                                          */
 374.243 +#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT)
 374.244 +
 374.245 +  /* FT_LONG64 must be defined if a 64-bit type is available */
 374.246 +#define FT_LONG64
 374.247 +#define FT_INT64  long
 374.248 +
 374.249 +#elif defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */
 374.250 +
 374.251 +  /* this compiler provides the __int64 type */
 374.252 +#define FT_LONG64
 374.253 +#define FT_INT64  __int64
 374.254 +
 374.255 +#elif defined( __BORLANDC__ )  /* Borland C++ */
 374.256 +
 374.257 +  /* XXXX: We should probably check the value of __BORLANDC__ in order */
 374.258 +  /*       to test the compiler version.                               */
 374.259 +
 374.260 +  /* this compiler provides the __int64 type */
 374.261 +#define FT_LONG64
 374.262 +#define FT_INT64  __int64
 374.263 +
 374.264 +#elif defined( __WATCOMC__ )   /* Watcom C++ */
 374.265 +
 374.266 +  /* Watcom doesn't provide 64-bit data types */
 374.267 +
 374.268 +#elif defined( __MWERKS__ )    /* Metrowerks CodeWarrior */
 374.269 +
 374.270 +#define FT_LONG64
 374.271 +#define FT_INT64  long long int
 374.272 +
 374.273 +#elif defined( __GNUC__ )
 374.274 +
 374.275 +  /* GCC provides the `long long' type */
 374.276 +#define FT_LONG64
 374.277 +#define FT_INT64  long long int
 374.278 +
 374.279 +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
 374.280 +
 374.281 +
 374.282 +  /*************************************************************************/
 374.283 +  /*                                                                       */
 374.284 +  /* A 64-bit data type will create compilation problems if you compile    */
 374.285 +  /* in strict ANSI mode.  To avoid them, we disable its use if __STDC__   */
 374.286 +  /* is defined.  You can however ignore this rule by defining the         */
 374.287 +  /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro.                     */
 374.288 +  /*                                                                       */
 374.289 +#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 )
 374.290 +
 374.291 +#ifdef __STDC__
 374.292 +
 374.293 +  /* undefine the 64-bit macros in strict ANSI compilation mode */
 374.294 +#undef FT_LONG64
 374.295 +#undef FT_INT64
 374.296 +
 374.297 +#endif /* __STDC__ */
 374.298 +
 374.299 +#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */
 374.300 +
 374.301 +
 374.302 +#define FT_BEGIN_STMNT  do {
 374.303 +#define FT_END_STMNT    } while ( 0 )
 374.304 +#define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
 374.305 +
 374.306 +
 374.307 +#ifndef  FT_CONFIG_OPTION_NO_ASSEMBLER
 374.308 +  /* Provide assembler fragments for performance-critical functions. */
 374.309 +  /* These must be defined `static __inline__' with GCC.             */
 374.310 +
 374.311 +#if defined( __CC_ARM ) || defined( __ARMCC__ )  /* RVCT */
 374.312 +#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
 374.313 +
 374.314 +  /* documentation is in freetype.h */
 374.315 +
 374.316 +  static __inline FT_Int32
 374.317 +  FT_MulFix_arm( FT_Int32  a,
 374.318 +                 FT_Int32  b )
 374.319 +  {
 374.320 +    register FT_Int32  t, t2;
 374.321 +
 374.322 +
 374.323 +    __asm
 374.324 +    {
 374.325 +      smull t2, t,  b,  a           /* (lo=t2,hi=t) = a*b */
 374.326 +      mov   a,  t,  asr #31         /* a   = (hi >> 31) */
 374.327 +      add   a,  a,  #0x8000         /* a  += 0x8000 */
 374.328 +      adds  t2, t2, a               /* t2 += a */
 374.329 +      adc   t,  t,  #0              /* t  += carry */
 374.330 +      mov   a,  t2, lsr #16         /* a   = t2 >> 16 */
 374.331 +      orr   a,  a,  t,  lsl #16     /* a  |= t << 16 */
 374.332 +    }
 374.333 +    return a;
 374.334 +  }
 374.335 +
 374.336 +#endif /* __CC_ARM || __ARMCC__ */
 374.337 +
 374.338 +
 374.339 +#ifdef __GNUC__
 374.340 +
 374.341 +#if defined( __arm__ ) && !defined( __thumb__ )    && \
 374.342 +    !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
 374.343 +#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
 374.344 +
 374.345 +  /* documentation is in freetype.h */
 374.346 +
 374.347 +  static __inline__ FT_Int32
 374.348 +  FT_MulFix_arm( FT_Int32  a,
 374.349 +                 FT_Int32  b )
 374.350 +  {
 374.351 +    register FT_Int32  t, t2;
 374.352 +
 374.353 +
 374.354 +    __asm__ __volatile__ (
 374.355 +      "smull  %1, %2, %4, %3\n\t"   /* (lo=%1,hi=%2) = a*b */
 374.356 +      "mov    %0, %2, asr #31\n\t"  /* %0  = (hi >> 31) */
 374.357 +      "add    %0, %0, #0x8000\n\t"  /* %0 += 0x8000 */
 374.358 +      "adds   %1, %1, %0\n\t"       /* %1 += %0 */
 374.359 +      "adc    %2, %2, #0\n\t"       /* %2 += carry */
 374.360 +      "mov    %0, %1, lsr #16\n\t"  /* %0  = %1 >> 16 */
 374.361 +      "orr    %0, %2, lsl #16\n\t"  /* %0 |= %2 << 16 */
 374.362 +      : "=r"(a), "=&r"(t2), "=&r"(t)
 374.363 +      : "r"(a), "r"(b) );
 374.364 +    return a;
 374.365 +  }
 374.366 +
 374.367 +#endif /* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */
 374.368 +
 374.369 +#if defined( __i386__ )
 374.370 +#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
 374.371 +
 374.372 +  /* documentation is in freetype.h */
 374.373 +
 374.374 +  static __inline__ FT_Int32
 374.375 +  FT_MulFix_i386( FT_Int32  a,
 374.376 +                  FT_Int32  b )
 374.377 +  {
 374.378 +    register FT_Int32  result;
 374.379 +
 374.380 +
 374.381 +    __asm__ __volatile__ (
 374.382 +      "imul  %%edx\n"
 374.383 +      "movl  %%edx, %%ecx\n"
 374.384 +      "sarl  $31, %%ecx\n"
 374.385 +      "addl  $0x8000, %%ecx\n"
 374.386 +      "addl  %%ecx, %%eax\n"
 374.387 +      "adcl  $0, %%edx\n"
 374.388 +      "shrl  $16, %%eax\n"
 374.389 +      "shll  $16, %%edx\n"
 374.390 +      "addl  %%edx, %%eax\n"
 374.391 +      : "=a"(result), "=d"(b)
 374.392 +      : "a"(a), "d"(b)
 374.393 +      : "%ecx", "cc" );
 374.394 +    return result;
 374.395 +  }
 374.396 +
 374.397 +#endif /* i386 */
 374.398 +
 374.399 +#endif /* __GNUC__ */
 374.400 +
 374.401 +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
 374.402 +
 374.403 +
 374.404 +#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
 374.405 +#ifdef FT_MULFIX_ASSEMBLER
 374.406 +#define FT_MULFIX_INLINED  FT_MULFIX_ASSEMBLER
 374.407 +#endif
 374.408 +#endif
 374.409 +
 374.410 +
 374.411 +#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
 374.412 +
 374.413 +#define FT_LOCAL( x )      static  x
 374.414 +#define FT_LOCAL_DEF( x )  static  x
 374.415 +
 374.416 +#else
 374.417 +
 374.418 +#ifdef __cplusplus
 374.419 +#define FT_LOCAL( x )      extern "C"  x
 374.420 +#define FT_LOCAL_DEF( x )  extern "C"  x
 374.421 +#else
 374.422 +#define FT_LOCAL( x )      extern  x
 374.423 +#define FT_LOCAL_DEF( x )  x
 374.424 +#endif
 374.425 +
 374.426 +#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */
 374.427 +
 374.428 +
 374.429 +#ifndef FT_BASE
 374.430 +
 374.431 +#ifdef __cplusplus
 374.432 +#define FT_BASE( x )  extern "C"  x
 374.433 +#else
 374.434 +#define FT_BASE( x )  extern  x
 374.435 +#endif
 374.436 +
 374.437 +#endif /* !FT_BASE */
 374.438 +
 374.439 +
 374.440 +#ifndef FT_BASE_DEF
 374.441 +
 374.442 +#ifdef __cplusplus
 374.443 +#define FT_BASE_DEF( x )  x
 374.444 +#else
 374.445 +#define FT_BASE_DEF( x )  x
 374.446 +#endif
 374.447 +
 374.448 +#endif /* !FT_BASE_DEF */
 374.449 +
 374.450 +
 374.451 +#ifndef FT_EXPORT
 374.452 +
 374.453 +#ifdef __cplusplus
 374.454 +#define FT_EXPORT( x )  extern "C"  x
 374.455 +#else
 374.456 +#define FT_EXPORT( x )  extern  x
 374.457 +#endif
 374.458 +
 374.459 +#endif /* !FT_EXPORT */
 374.460 +
 374.461 +
 374.462 +#ifndef FT_EXPORT_DEF
 374.463 +
 374.464 +#ifdef __cplusplus
 374.465 +#define FT_EXPORT_DEF( x )  extern "C"  x
 374.466 +#else
 374.467 +#define FT_EXPORT_DEF( x )  extern  x
 374.468 +#endif
 374.469 +
 374.470 +#endif /* !FT_EXPORT_DEF */
 374.471 +
 374.472 +
 374.473 +#ifndef FT_EXPORT_VAR
 374.474 +
 374.475 +#ifdef __cplusplus
 374.476 +#define FT_EXPORT_VAR( x )  extern "C"  x
 374.477 +#else
 374.478 +#define FT_EXPORT_VAR( x )  extern  x
 374.479 +#endif
 374.480 +
 374.481 +#endif /* !FT_EXPORT_VAR */
 374.482 +
 374.483 +  /* The following macros are needed to compile the library with a   */
 374.484 +  /* C++ compiler and with 16bit compilers.                          */
 374.485 +  /*                                                                 */
 374.486 +
 374.487 +  /* This is special.  Within C++, you must specify `extern "C"' for */
 374.488 +  /* functions which are used via function pointers, and you also    */
 374.489 +  /* must do that for structures which contain function pointers to  */
 374.490 +  /* assure C linkage -- it's not possible to have (local) anonymous */
 374.491 +  /* functions which are accessed by (global) function pointers.     */
 374.492 +  /*                                                                 */
 374.493 +  /*                                                                 */
 374.494 +  /* FT_CALLBACK_DEF is used to _define_ a callback function.        */
 374.495 +  /*                                                                 */
 374.496 +  /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */
 374.497 +  /* contains pointers to callback functions.                        */
 374.498 +  /*                                                                 */
 374.499 +  /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable   */
 374.500 +  /* that contains pointers to callback functions.                   */
 374.501 +  /*                                                                 */
 374.502 +  /*                                                                 */
 374.503 +  /* Some 16bit compilers have to redefine these macros to insert    */
 374.504 +  /* the infamous `_cdecl' or `__fastcall' declarations.             */
 374.505 +  /*                                                                 */
 374.506 +#ifndef FT_CALLBACK_DEF
 374.507 +#ifdef __cplusplus
 374.508 +#define FT_CALLBACK_DEF( x )  extern "C"  x
 374.509 +#else
 374.510 +#define FT_CALLBACK_DEF( x )  static  x
 374.511 +#endif
 374.512 +#endif /* FT_CALLBACK_DEF */
 374.513 +
 374.514 +#ifndef FT_CALLBACK_TABLE
 374.515 +#ifdef __cplusplus
 374.516 +#define FT_CALLBACK_TABLE      extern "C"
 374.517 +#define FT_CALLBACK_TABLE_DEF  extern "C"
 374.518 +#else
 374.519 +#define FT_CALLBACK_TABLE      extern
 374.520 +#define FT_CALLBACK_TABLE_DEF  /* nothing */
 374.521 +#endif
 374.522 +#endif /* FT_CALLBACK_TABLE */
 374.523 +
 374.524 +
 374.525 +FT_END_HEADER
 374.526 +
 374.527 +
 374.528 +#endif /* __FTCONFIG_H__ */
 374.529 +
 374.530 +
 374.531 +/* END */
   375.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   375.2 +++ b/libs/ft2static/freetype/config/ftheader.h	Sat Feb 01 19:58:19 2014 +0200
   375.3 @@ -0,0 +1,780 @@
   375.4 +/***************************************************************************/
   375.5 +/*                                                                         */
   375.6 +/*  ftheader.h                                                             */
   375.7 +/*                                                                         */
   375.8 +/*    Build macros of the FreeType 2 library.                              */
   375.9 +/*                                                                         */
  375.10 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by       */
  375.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  375.12 +/*                                                                         */
  375.13 +/*  This file is part of the FreeType project, and may only be used,       */
  375.14 +/*  modified, and distributed under the terms of the FreeType project      */
  375.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  375.16 +/*  this file you indicate that you have read the license and              */
  375.17 +/*  understand and accept it fully.                                        */
  375.18 +/*                                                                         */
  375.19 +/***************************************************************************/
  375.20 +
  375.21 +#ifndef __FT_HEADER_H__
  375.22 +#define __FT_HEADER_H__
  375.23 +
  375.24 +
  375.25 +  /*@***********************************************************************/
  375.26 +  /*                                                                       */
  375.27 +  /* <Macro>                                                               */
  375.28 +  /*    FT_BEGIN_HEADER                                                    */
  375.29 +  /*                                                                       */
  375.30 +  /* <Description>                                                         */
  375.31 +  /*    This macro is used in association with @FT_END_HEADER in header    */
  375.32 +  /*    files to ensure that the declarations within are properly          */
  375.33 +  /*    encapsulated in an `extern "C" { .. }' block when included from a  */
  375.34 +  /*    C++ compiler.                                                      */
  375.35 +  /*                                                                       */
  375.36 +#ifdef __cplusplus
  375.37 +#define FT_BEGIN_HEADER  extern "C" {
  375.38 +#else
  375.39 +#define FT_BEGIN_HEADER  /* nothing */
  375.40 +#endif
  375.41 +
  375.42 +
  375.43 +  /*@***********************************************************************/
  375.44 +  /*                                                                       */
  375.45 +  /* <Macro>                                                               */
  375.46 +  /*    FT_END_HEADER                                                      */
  375.47 +  /*                                                                       */
  375.48 +  /* <Description>                                                         */
  375.49 +  /*    This macro is used in association with @FT_BEGIN_HEADER in header  */
  375.50 +  /*    files to ensure that the declarations within are properly          */
  375.51 +  /*    encapsulated in an `extern "C" { .. }' block when included from a  */
  375.52 +  /*    C++ compiler.                                                      */
  375.53 +  /*                                                                       */
  375.54 +#ifdef __cplusplus
  375.55 +#define FT_END_HEADER  }
  375.56 +#else
  375.57 +#define FT_END_HEADER  /* nothing */
  375.58 +#endif
  375.59 +
  375.60 +
  375.61 +  /*************************************************************************/
  375.62 +  /*                                                                       */
  375.63 +  /* Aliases for the FreeType 2 public and configuration files.            */
  375.64 +  /*                                                                       */
  375.65 +  /*************************************************************************/
  375.66 +
  375.67 +  /*************************************************************************/
  375.68 +  /*                                                                       */
  375.69 +  /* <Section>                                                             */
  375.70 +  /*    header_file_macros                                                 */
  375.71 +  /*                                                                       */
  375.72 +  /* <Title>                                                               */
  375.73 +  /*    Header File Macros                                                 */
  375.74 +  /*                                                                       */
  375.75 +  /* <Abstract>                                                            */
  375.76 +  /*    Macro definitions used to #include specific header files.          */
  375.77 +  /*                                                                       */
  375.78 +  /* <Description>                                                         */
  375.79 +  /*    The following macros are defined to the name of specific           */
  375.80 +  /*    FreeType~2 header files.  They can be used directly in #include    */
  375.81 +  /*    statements as in:                                                  */
  375.82 +  /*                                                                       */
  375.83 +  /*    {                                                                  */
  375.84 +  /*      #include FT_FREETYPE_H                                           */
  375.85 +  /*      #include FT_MULTIPLE_MASTERS_H                                   */
  375.86 +  /*      #include FT_GLYPH_H                                              */
  375.87 +  /*    }                                                                  */
  375.88 +  /*                                                                       */
  375.89 +  /*    There are several reasons why we are now using macros to name      */
  375.90 +  /*    public header files.  The first one is that such macros are not    */
  375.91 +  /*    limited to the infamous 8.3~naming rule required by DOS (and       */
  375.92 +  /*    `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h').   */
  375.93 +  /*                                                                       */
  375.94 +  /*    The second reason is that it allows for more flexibility in the    */
  375.95 +  /*    way FreeType~2 is installed on a given system.                     */
  375.96 +  /*                                                                       */
  375.97 +  /*************************************************************************/
  375.98 +
  375.99 +
 375.100 +  /* configuration files */
 375.101 +
 375.102 +  /*************************************************************************
 375.103 +   *
 375.104 +   * @macro:
 375.105 +   *   FT_CONFIG_CONFIG_H
 375.106 +   *
 375.107 +   * @description:
 375.108 +   *   A macro used in #include statements to name the file containing
 375.109 +   *   FreeType~2 configuration data.
 375.110 +   *
 375.111 +   */
 375.112 +#ifndef FT_CONFIG_CONFIG_H
 375.113 +#define FT_CONFIG_CONFIG_H  <freetype/config/ftconfig.h>
 375.114 +#endif
 375.115 +
 375.116 +
 375.117 +  /*************************************************************************
 375.118 +   *
 375.119 +   * @macro:
 375.120 +   *   FT_CONFIG_STANDARD_LIBRARY_H
 375.121 +   *
 375.122 +   * @description:
 375.123 +   *   A macro used in #include statements to name the file containing
 375.124 +   *   FreeType~2 interface to the standard C library functions.
 375.125 +   *
 375.126 +   */
 375.127 +#ifndef FT_CONFIG_STANDARD_LIBRARY_H
 375.128 +#define FT_CONFIG_STANDARD_LIBRARY_H  <freetype/config/ftstdlib.h>
 375.129 +#endif
 375.130 +
 375.131 +
 375.132 +  /*************************************************************************
 375.133 +   *
 375.134 +   * @macro:
 375.135 +   *   FT_CONFIG_OPTIONS_H
 375.136 +   *
 375.137 +   * @description:
 375.138 +   *   A macro used in #include statements to name the file containing
 375.139 +   *   FreeType~2 project-specific configuration options.
 375.140 +   *
 375.141 +   */
 375.142 +#ifndef FT_CONFIG_OPTIONS_H
 375.143 +#define FT_CONFIG_OPTIONS_H  <freetype/config/ftoption.h>
 375.144 +#endif
 375.145 +
 375.146 +
 375.147 +  /*************************************************************************
 375.148 +   *
 375.149 +   * @macro:
 375.150 +   *   FT_CONFIG_MODULES_H
 375.151 +   *
 375.152 +   * @description:
 375.153 +   *   A macro used in #include statements to name the file containing the
 375.154 +   *   list of FreeType~2 modules that are statically linked to new library
 375.155 +   *   instances in @FT_Init_FreeType.
 375.156 +   *
 375.157 +   */
 375.158 +#ifndef FT_CONFIG_MODULES_H
 375.159 +#define FT_CONFIG_MODULES_H  <freetype/config/ftmodule.h>
 375.160 +#endif
 375.161 +
 375.162 +  /* */
 375.163 +
 375.164 +  /* public headers */
 375.165 +
 375.166 +  /*************************************************************************
 375.167 +   *
 375.168 +   * @macro:
 375.169 +   *   FT_FREETYPE_H
 375.170 +   *
 375.171 +   * @description:
 375.172 +   *   A macro used in #include statements to name the file containing the
 375.173 +   *   base FreeType~2 API.
 375.174 +   *
 375.175 +   */
 375.176 +#define FT_FREETYPE_H  <freetype/freetype.h>
 375.177 +
 375.178 +
 375.179 +  /*************************************************************************
 375.180 +   *
 375.181 +   * @macro:
 375.182 +   *   FT_ERRORS_H
 375.183 +   *
 375.184 +   * @description:
 375.185 +   *   A macro used in #include statements to name the file containing the
 375.186 +   *   list of FreeType~2 error codes (and messages).
 375.187 +   *
 375.188 +   *   It is included by @FT_FREETYPE_H.
 375.189 +   *
 375.190 +   */
 375.191 +#define FT_ERRORS_H  <freetype/fterrors.h>
 375.192 +
 375.193 +
 375.194 +  /*************************************************************************
 375.195 +   *
 375.196 +   * @macro:
 375.197 +   *   FT_MODULE_ERRORS_H
 375.198 +   *
 375.199 +   * @description:
 375.200 +   *   A macro used in #include statements to name the file containing the
 375.201 +   *   list of FreeType~2 module error offsets (and messages).
 375.202 +   *
 375.203 +   */
 375.204 +#define FT_MODULE_ERRORS_H  <freetype/ftmoderr.h>
 375.205 +
 375.206 +
 375.207 +  /*************************************************************************
 375.208 +   *
 375.209 +   * @macro:
 375.210 +   *   FT_SYSTEM_H
 375.211 +   *
 375.212 +   * @description:
 375.213 +   *   A macro used in #include statements to name the file containing the
 375.214 +   *   FreeType~2 interface to low-level operations (i.e., memory management
 375.215 +   *   and stream i/o).
 375.216 +   *
 375.217 +   *   It is included by @FT_FREETYPE_H.
 375.218 +   *
 375.219 +   */
 375.220 +#define FT_SYSTEM_H  <freetype/ftsystem.h>
 375.221 +
 375.222 +
 375.223 +  /*************************************************************************
 375.224 +   *
 375.225 +   * @macro:
 375.226 +   *   FT_IMAGE_H
 375.227 +   *
 375.228 +   * @description:
 375.229 +   *   A macro used in #include statements to name the file containing type
 375.230 +   *   definitions related to glyph images (i.e., bitmaps, outlines,
 375.231 +   *   scan-converter parameters).
 375.232 +   *
 375.233 +   *   It is included by @FT_FREETYPE_H.
 375.234 +   *
 375.235 +   */
 375.236 +#define FT_IMAGE_H  <freetype/ftimage.h>
 375.237 +
 375.238 +
 375.239 +  /*************************************************************************
 375.240 +   *
 375.241 +   * @macro:
 375.242 +   *   FT_TYPES_H
 375.243 +   *
 375.244 +   * @description:
 375.245 +   *   A macro used in #include statements to name the file containing the
 375.246 +   *   basic data types defined by FreeType~2.
 375.247 +   *
 375.248 +   *   It is included by @FT_FREETYPE_H.
 375.249 +   *
 375.250 +   */
 375.251 +#define FT_TYPES_H  <freetype/fttypes.h>
 375.252 +
 375.253 +
 375.254 +  /*************************************************************************
 375.255 +   *
 375.256 +   * @macro:
 375.257 +   *   FT_LIST_H
 375.258 +   *
 375.259 +   * @description:
 375.260 +   *   A macro used in #include statements to name the file containing the
 375.261 +   *   list management API of FreeType~2.
 375.262 +   *
 375.263 +   *   (Most applications will never need to include this file.)
 375.264 +   *
 375.265 +   */
 375.266 +#define FT_LIST_H  <freetype/ftlist.h>
 375.267 +
 375.268 +
 375.269 +  /*************************************************************************
 375.270 +   *
 375.271 +   * @macro:
 375.272 +   *   FT_OUTLINE_H
 375.273 +   *
 375.274 +   * @description:
 375.275 +   *   A macro used in #include statements to name the file containing the
 375.276 +   *   scalable outline management API of FreeType~2.
 375.277 +   *
 375.278 +   */
 375.279 +#define FT_OUTLINE_H  <freetype/ftoutln.h>
 375.280 +
 375.281 +
 375.282 +  /*************************************************************************
 375.283 +   *
 375.284 +   * @macro:
 375.285 +   *   FT_SIZES_H
 375.286 +   *
 375.287 +   * @description:
 375.288 +   *   A macro used in #include statements to name the file containing the
 375.289 +   *   API which manages multiple @FT_Size objects per face.
 375.290 +   *
 375.291 +   */
 375.292 +#define FT_SIZES_H  <freetype/ftsizes.h>
 375.293 +
 375.294 +
 375.295 +  /*************************************************************************
 375.296 +   *
 375.297 +   * @macro:
 375.298 +   *   FT_MODULE_H
 375.299 +   *
 375.300 +   * @description:
 375.301 +   *   A macro used in #include statements to name the file containing the
 375.302 +   *   module management API of FreeType~2.
 375.303 +   *
 375.304 +   */
 375.305 +#define FT_MODULE_H  <freetype/ftmodapi.h>
 375.306 +
 375.307 +
 375.308 +  /*************************************************************************
 375.309 +   *
 375.310 +   * @macro:
 375.311 +   *   FT_RENDER_H
 375.312 +   *
 375.313 +   * @description:
 375.314 +   *   A macro used in #include statements to name the file containing the
 375.315 +   *   renderer module management API of FreeType~2.
 375.316 +   *
 375.317 +   */
 375.318 +#define FT_RENDER_H  <freetype/ftrender.h>
 375.319 +
 375.320 +
 375.321 +  /*************************************************************************
 375.322 +   *
 375.323 +   * @macro:
 375.324 +   *   FT_TYPE1_TABLES_H
 375.325 +   *
 375.326 +   * @description:
 375.327 +   *   A macro used in #include statements to name the file containing the
 375.328 +   *   types and API specific to the Type~1 format.
 375.329 +   *
 375.330 +   */
 375.331 +#define FT_TYPE1_TABLES_H  <freetype/t1tables.h>
 375.332 +
 375.333 +
 375.334 +  /*************************************************************************
 375.335 +   *
 375.336 +   * @macro:
 375.337 +   *   FT_TRUETYPE_IDS_H
 375.338 +   *
 375.339 +   * @description:
 375.340 +   *   A macro used in #include statements to name the file containing the
 375.341 +   *   enumeration values which identify name strings, languages, encodings,
 375.342 +   *   etc.  This file really contains a _large_ set of constant macro
 375.343 +   *   definitions, taken from the TrueType and OpenType specifications.
 375.344 +   *
 375.345 +   */
 375.346 +#define FT_TRUETYPE_IDS_H  <freetype/ttnameid.h>
 375.347 +
 375.348 +
 375.349 +  /*************************************************************************
 375.350 +   *
 375.351 +   * @macro:
 375.352 +   *   FT_TRUETYPE_TABLES_H
 375.353 +   *
 375.354 +   * @description:
 375.355 +   *   A macro used in #include statements to name the file containing the
 375.356 +   *   types and API specific to the TrueType (as well as OpenType) format.
 375.357 +   *
 375.358 +   */
 375.359 +#define FT_TRUETYPE_TABLES_H  <freetype/tttables.h>
 375.360 +
 375.361 +
 375.362 +  /*************************************************************************
 375.363 +   *
 375.364 +   * @macro:
 375.365 +   *   FT_TRUETYPE_TAGS_H
 375.366 +   *
 375.367 +   * @description:
 375.368 +   *   A macro used in #include statements to name the file containing the
 375.369 +   *   definitions of TrueType four-byte `tags' which identify blocks in
 375.370 +   *   SFNT-based font formats (i.e., TrueType and OpenType).
 375.371 +   *
 375.372 +   */
 375.373 +#define FT_TRUETYPE_TAGS_H  <freetype/tttags.h>
 375.374 +
 375.375 +
 375.376 +  /*************************************************************************
 375.377 +   *
 375.378 +   * @macro:
 375.379 +   *   FT_BDF_H
 375.380 +   *
 375.381 +   * @description:
 375.382 +   *   A macro used in #include statements to name the file containing the
 375.383 +   *   definitions of an API which accesses BDF-specific strings from a
 375.384 +   *   face.
 375.385 +   *
 375.386 +   */
 375.387 +#define FT_BDF_H  <freetype/ftbdf.h>
 375.388 +
 375.389 +
 375.390 +  /*************************************************************************
 375.391 +   *
 375.392 +   * @macro:
 375.393 +   *   FT_CID_H
 375.394 +   *
 375.395 +   * @description:
 375.396 +   *   A macro used in #include statements to name the file containing the
 375.397 +   *   definitions of an API which access CID font information from a
 375.398 +   *   face.
 375.399 +   *
 375.400 +   */
 375.401 +#define FT_CID_H  <freetype/ftcid.h>
 375.402 +
 375.403 +
 375.404 +  /*************************************************************************
 375.405 +   *
 375.406 +   * @macro:
 375.407 +   *   FT_GZIP_H
 375.408 +   *
 375.409 +   * @description:
 375.410 +   *   A macro used in #include statements to name the file containing the
 375.411 +   *   definitions of an API which supports gzip-compressed files.
 375.412 +   *
 375.413 +   */
 375.414 +#define FT_GZIP_H  <freetype/ftgzip.h>
 375.415 +
 375.416 +
 375.417 +  /*************************************************************************
 375.418 +   *
 375.419 +   * @macro:
 375.420 +   *   FT_LZW_H
 375.421 +   *
 375.422 +   * @description:
 375.423 +   *   A macro used in #include statements to name the file containing the
 375.424 +   *   definitions of an API which supports LZW-compressed files.
 375.425 +   *
 375.426 +   */
 375.427 +#define FT_LZW_H  <freetype/ftlzw.h>
 375.428 +
 375.429 +
 375.430 +  /*************************************************************************
 375.431 +   *
 375.432 +   * @macro:
 375.433 +   *   FT_WINFONTS_H
 375.434 +   *
 375.435 +   * @description:
 375.436 +   *   A macro used in #include statements to name the file containing the
 375.437 +   *   definitions of an API which supports Windows FNT files.
 375.438 +   *
 375.439 +   */
 375.440 +#define FT_WINFONTS_H   <freetype/ftwinfnt.h>
 375.441 +
 375.442 +
 375.443 +  /*************************************************************************
 375.444 +   *
 375.445 +   * @macro:
 375.446 +   *   FT_GLYPH_H
 375.447 +   *
 375.448 +   * @description:
 375.449 +   *   A macro used in #include statements to name the file containing the
 375.450 +   *   API of the optional glyph management component.
 375.451 +   *
 375.452 +   */
 375.453 +#define FT_GLYPH_H  <freetype/ftglyph.h>
 375.454 +
 375.455 +
 375.456 +  /*************************************************************************
 375.457 +   *
 375.458 +   * @macro:
 375.459 +   *   FT_BITMAP_H
 375.460 +   *
 375.461 +   * @description:
 375.462 +   *   A macro used in #include statements to name the file containing the
 375.463 +   *   API of the optional bitmap conversion component.
 375.464 +   *
 375.465 +   */
 375.466 +#define FT_BITMAP_H  <freetype/ftbitmap.h>
 375.467 +
 375.468 +
 375.469 +  /*************************************************************************
 375.470 +   *
 375.471 +   * @macro:
 375.472 +   *   FT_BBOX_H
 375.473 +   *
 375.474 +   * @description:
 375.475 +   *   A macro used in #include statements to name the file containing the
 375.476 +   *   API of the optional exact bounding box computation routines.
 375.477 +   *
 375.478 +   */
 375.479 +#define FT_BBOX_H  <freetype/ftbbox.h>
 375.480 +
 375.481 +
 375.482 +  /*************************************************************************
 375.483 +   *
 375.484 +   * @macro:
 375.485 +   *   FT_CACHE_H
 375.486 +   *
 375.487 +   * @description:
 375.488 +   *   A macro used in #include statements to name the file containing the
 375.489 +   *   API of the optional FreeType~2 cache sub-system.
 375.490 +   *
 375.491 +   */
 375.492 +#define FT_CACHE_H  <freetype/ftcache.h>
 375.493 +
 375.494 +
 375.495 +  /*************************************************************************
 375.496 +   *
 375.497 +   * @macro:
 375.498 +   *   FT_CACHE_IMAGE_H
 375.499 +   *
 375.500 +   * @description:
 375.501 +   *   A macro used in #include statements to name the file containing the
 375.502 +   *   `glyph image' API of the FreeType~2 cache sub-system.
 375.503 +   *
 375.504 +   *   It is used to define a cache for @FT_Glyph elements.  You can also
 375.505 +   *   use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to
 375.506 +   *   store small glyph bitmaps, as it will use less memory.
 375.507 +   *
 375.508 +   *   This macro is deprecated.  Simply include @FT_CACHE_H to have all
 375.509 +   *   glyph image-related cache declarations.
 375.510 +   *
 375.511 +   */
 375.512 +#define FT_CACHE_IMAGE_H  FT_CACHE_H
 375.513 +
 375.514 +
 375.515 +  /*************************************************************************
 375.516 +   *
 375.517 +   * @macro:
 375.518 +   *   FT_CACHE_SMALL_BITMAPS_H
 375.519 +   *
 375.520 +   * @description:
 375.521 +   *   A macro used in #include statements to name the file containing the
 375.522 +   *   `small bitmaps' API of the FreeType~2 cache sub-system.
 375.523 +   *
 375.524 +   *   It is used to define a cache for small glyph bitmaps in a relatively
 375.525 +   *   memory-efficient way.  You can also use the API defined in
 375.526 +   *   @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images,
 375.527 +   *   including scalable outlines.
 375.528 +   *
 375.529 +   *   This macro is deprecated.  Simply include @FT_CACHE_H to have all
 375.530 +   *   small bitmaps-related cache declarations.
 375.531 +   *
 375.532 +   */
 375.533 +#define FT_CACHE_SMALL_BITMAPS_H  FT_CACHE_H
 375.534 +
 375.535 +
 375.536 +  /*************************************************************************
 375.537 +   *
 375.538 +   * @macro:
 375.539 +   *   FT_CACHE_CHARMAP_H
 375.540 +   *
 375.541 +   * @description:
 375.542 +   *   A macro used in #include statements to name the file containing the
 375.543 +   *   `charmap' API of the FreeType~2 cache sub-system.
 375.544 +   *
 375.545 +   *   This macro is deprecated.  Simply include @FT_CACHE_H to have all
 375.546 +   *   charmap-based cache declarations.
 375.547 +   *
 375.548 +   */
 375.549 +#define FT_CACHE_CHARMAP_H  FT_CACHE_H
 375.550 +
 375.551 +
 375.552 +  /*************************************************************************
 375.553 +   *
 375.554 +   * @macro:
 375.555 +   *   FT_MAC_H
 375.556 +   *
 375.557 +   * @description:
 375.558 +   *   A macro used in #include statements to name the file containing the
 375.559 +   *   Macintosh-specific FreeType~2 API.  The latter is used to access
 375.560 +   *   fonts embedded in resource forks.
 375.561 +   *
 375.562 +   *   This header file must be explicitly included by client applications
 375.563 +   *   compiled on the Mac (note that the base API still works though).
 375.564 +   *
 375.565 +   */
 375.566 +#define FT_MAC_H  <freetype/ftmac.h>
 375.567 +
 375.568 +
 375.569 +  /*************************************************************************
 375.570 +   *
 375.571 +   * @macro:
 375.572 +   *   FT_MULTIPLE_MASTERS_H
 375.573 +   *
 375.574 +   * @description:
 375.575 +   *   A macro used in #include statements to name the file containing the
 375.576 +   *   optional multiple-masters management API of FreeType~2.
 375.577 +   *
 375.578 +   */
 375.579 +#define FT_MULTIPLE_MASTERS_H  <freetype/ftmm.h>
 375.580 +
 375.581 +
 375.582 +  /*************************************************************************
 375.583 +   *
 375.584 +   * @macro:
 375.585 +   *   FT_SFNT_NAMES_H
 375.586 +   *
 375.587 +   * @description:
 375.588 +   *   A macro used in #include statements to name the file containing the
 375.589 +   *   optional FreeType~2 API which accesses embedded `name' strings in
 375.590 +   *   SFNT-based font formats (i.e., TrueType and OpenType).
 375.591 +   *
 375.592 +   */
 375.593 +#define FT_SFNT_NAMES_H  <freetype/ftsnames.h>
 375.594 +
 375.595 +
 375.596 +  /*************************************************************************
 375.597 +   *
 375.598 +   * @macro:
 375.599 +   *   FT_OPENTYPE_VALIDATE_H
 375.600 +   *
 375.601 +   * @description:
 375.602 +   *   A macro used in #include statements to name the file containing the
 375.603 +   *   optional FreeType~2 API which validates OpenType tables (BASE, GDEF,
 375.604 +   *   GPOS, GSUB, JSTF).
 375.605 +   *
 375.606 +   */
 375.607 +#define FT_OPENTYPE_VALIDATE_H  <freetype/ftotval.h>
 375.608 +
 375.609 +
 375.610 +  /*************************************************************************
 375.611 +   *
 375.612 +   * @macro:
 375.613 +   *   FT_GX_VALIDATE_H
 375.614 +   *
 375.615 +   * @description:
 375.616 +   *   A macro used in #include statements to name the file containing the
 375.617 +   *   optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat,
 375.618 +   *   mort, morx, bsln, just, kern, opbd, trak, prop).
 375.619 +   *
 375.620 +   */
 375.621 +#define FT_GX_VALIDATE_H  <freetype/ftgxval.h>
 375.622 +
 375.623 +
 375.624 +  /*************************************************************************
 375.625 +   *
 375.626 +   * @macro:
 375.627 +   *   FT_PFR_H
 375.628 +   *
 375.629 +   * @description:
 375.630 +   *   A macro used in #include statements to name the file containing the
 375.631 +   *   FreeType~2 API which accesses PFR-specific data.
 375.632 +   *
 375.633 +   */
 375.634 +#define FT_PFR_H  <freetype/ftpfr.h>
 375.635 +
 375.636 +
 375.637 +  /*************************************************************************
 375.638 +   *
 375.639 +   * @macro:
 375.640 +   *   FT_STROKER_H
 375.641 +   *
 375.642 +   * @description:
 375.643 +   *   A macro used in #include statements to name the file containing the
 375.644 +   *   FreeType~2 API which provides functions to stroke outline paths.
 375.645 +   */
 375.646 +#define FT_STROKER_H  <freetype/ftstroke.h>
 375.647 +
 375.648 +
 375.649 +  /*************************************************************************
 375.650 +   *
 375.651 +   * @macro:
 375.652 +   *   FT_SYNTHESIS_H
 375.653 +   *
 375.654 +   * @description:
 375.655 +   *   A macro used in #include statements to name the file containing the
 375.656 +   *   FreeType~2 API which performs artificial obliquing and emboldening.
 375.657 +   */
 375.658 +#define FT_SYNTHESIS_H  <freetype/ftsynth.h>
 375.659 +
 375.660 +
 375.661 +  /*************************************************************************
 375.662 +   *
 375.663 +   * @macro:
 375.664 +   *   FT_XFREE86_H
 375.665 +   *
 375.666 +   * @description:
 375.667 +   *   A macro used in #include statements to name the file containing the
 375.668 +   *   FreeType~2 API which provides functions specific to the XFree86 and
 375.669 +   *   X.Org X11 servers.
 375.670 +   */
 375.671 +#define FT_XFREE86_H  <freetype/ftxf86.h>
 375.672 +
 375.673 +
 375.674 +  /*************************************************************************
 375.675 +   *
 375.676 +   * @macro:
 375.677 +   *   FT_TRIGONOMETRY_H
 375.678 +   *
 375.679 +   * @description:
 375.680 +   *   A macro used in #include statements to name the file containing the
 375.681 +   *   FreeType~2 API which performs trigonometric computations (e.g.,
 375.682 +   *   cosines and arc tangents).
 375.683 +   */
 375.684 +#define FT_TRIGONOMETRY_H  <freetype/fttrigon.h>
 375.685 +
 375.686 +
 375.687 +  /*************************************************************************
 375.688 +   *
 375.689 +   * @macro:
 375.690 +   *   FT_LCD_FILTER_H
 375.691 +   *
 375.692 +   * @description:
 375.693 +   *   A macro used in #include statements to name the file containing the
 375.694 +   *   FreeType~2 API which performs color filtering for subpixel rendering.
 375.695 +   */
 375.696 +#define FT_LCD_FILTER_H  <freetype/ftlcdfil.h>
 375.697 +
 375.698 +
 375.699 +  /*************************************************************************
 375.700 +   *
 375.701 +   * @macro:
 375.702 +   *   FT_UNPATENTED_HINTING_H
 375.703 +   *
 375.704 +   * @description:
 375.705 +   *   A macro used in #include statements to name the file containing the
 375.706 +   *   FreeType~2 API which performs color filtering for subpixel rendering.
 375.707 +   */
 375.708 +#define FT_UNPATENTED_HINTING_H  <freetype/ttunpat.h>
 375.709 +
 375.710 +
 375.711 +  /*************************************************************************
 375.712 +   *
 375.713 +   * @macro:
 375.714 +   *   FT_INCREMENTAL_H
 375.715 +   *
 375.716 +   * @description:
 375.717 +   *   A macro used in #include statements to name the file containing the
 375.718 +   *   FreeType~2 API which performs color filtering for subpixel rendering.
 375.719 +   */
 375.720 +#define FT_INCREMENTAL_H  <freetype/ftincrem.h>
 375.721 +
 375.722 +
 375.723 +  /*************************************************************************
 375.724 +   *
 375.725 +   * @macro:
 375.726 +   *   FT_GASP_H
 375.727 +   *
 375.728 +   * @description:
 375.729 +   *   A macro used in #include statements to name the file containing the
 375.730 +   *   FreeType~2 API which returns entries from the TrueType GASP table.
 375.731 +   */
 375.732 +#define FT_GASP_H  <freetype/ftgasp.h>
 375.733 +
 375.734 +
 375.735 +  /*************************************************************************
 375.736 +   *
 375.737 +   * @macro:
 375.738 +   *   FT_ADVANCES_H
 375.739 +   *
 375.740 +   * @description:
 375.741 +   *   A macro used in #include statements to name the file containing the
 375.742 +   *   FreeType~2 API which returns individual and ranged glyph advances.
 375.743 +   */
 375.744 +#define FT_ADVANCES_H  <freetype/ftadvanc.h>
 375.745 +
 375.746 +
 375.747 +  /* */
 375.748 +
 375.749 +#define FT_ERROR_DEFINITIONS_H  <freetype/fterrdef.h>
 375.750 +
 375.751 +
 375.752 +  /* The internals of the cache sub-system are no longer exposed.  We */
 375.753 +  /* default to FT_CACHE_H at the moment just in case, but we know of */
 375.754 +  /* no rogue client that uses them.                                  */
 375.755 +  /*                                                                  */
 375.756 +#define FT_CACHE_MANAGER_H           <freetype/ftcache.h>
 375.757 +#define FT_CACHE_INTERNAL_MRU_H      <freetype/ftcache.h>
 375.758 +#define FT_CACHE_INTERNAL_MANAGER_H  <freetype/ftcache.h>
 375.759 +#define FT_CACHE_INTERNAL_CACHE_H    <freetype/ftcache.h>
 375.760 +#define FT_CACHE_INTERNAL_GLYPH_H    <freetype/ftcache.h>
 375.761 +#define FT_CACHE_INTERNAL_IMAGE_H    <freetype/ftcache.h>
 375.762 +#define FT_CACHE_INTERNAL_SBITS_H    <freetype/ftcache.h>
 375.763 +
 375.764 +
 375.765 +#define FT_INCREMENTAL_H          <freetype/ftincrem.h>
 375.766 +
 375.767 +#define FT_TRUETYPE_UNPATENTED_H  <freetype/ttunpat.h>
 375.768 +
 375.769 +
 375.770 +  /*
 375.771 +   * Include internal headers definitions from <freetype/internal/...>
 375.772 +   * only when building the library.
 375.773 +   */
 375.774 +#ifdef FT2_BUILD_LIBRARY
 375.775 +#define  FT_INTERNAL_INTERNAL_H  <freetype/internal/internal.h>
 375.776 +#include FT_INTERNAL_INTERNAL_H
 375.777 +#endif /* FT2_BUILD_LIBRARY */
 375.778 +
 375.779 +
 375.780 +#endif /* __FT2_BUILD_H__ */
 375.781 +
 375.782 +
 375.783 +/* END */
   376.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   376.2 +++ b/libs/ft2static/freetype/config/ftmodule.h	Sat Feb 01 19:58:19 2014 +0200
   376.3 @@ -0,0 +1,32 @@
   376.4 +/*
   376.5 + *  This file registers the FreeType modules compiled into the library.
   376.6 + *
   376.7 + *  If you use GNU make, this file IS NOT USED!  Instead, it is created in
   376.8 + *  the objects directory (normally `<topdir>/objs/') based on information
   376.9 + *  from `<topdir>/modules.cfg'.
  376.10 + *
  376.11 + *  Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile
  376.12 + *  FreeType without GNU make.
  376.13 + *
  376.14 + */
  376.15 +
  376.16 +//FT_USE_MODULE( FT_Module_Class, autofit_module_class )
  376.17 +FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
  376.18 +//FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )
  376.19 +FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )
  376.20 +//FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )
  376.21 +//FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )
  376.22 +//FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )
  376.23 +//FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )
  376.24 +//FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )
  376.25 +//FT_USE_MODULE( FT_Module_Class, psaux_module_class )
  376.26 +FT_USE_MODULE( FT_Module_Class, psnames_module_class )
  376.27 +FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
  376.28 +FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
  376.29 +FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
  376.30 +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
  376.31 +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )
  376.32 +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )
  376.33 +//FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
  376.34 +
  376.35 +/* EOF */
   377.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   377.2 +++ b/libs/ft2static/freetype/config/ftoption.h	Sat Feb 01 19:58:19 2014 +0200
   377.3 @@ -0,0 +1,733 @@
   377.4 +/***************************************************************************/
   377.5 +/*                                                                         */
   377.6 +/*  ftoption.h                                                             */
   377.7 +/*                                                                         */
   377.8 +/*    User-selectable configuration macros (specification only).           */
   377.9 +/*                                                                         */
  377.10 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
  377.11 +/*            2010 by                                                      */
  377.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  377.13 +/*                                                                         */
  377.14 +/*  This file is part of the FreeType project, and may only be used,       */
  377.15 +/*  modified, and distributed under the terms of the FreeType project      */
  377.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  377.17 +/*  this file you indicate that you have read the license and              */
  377.18 +/*  understand and accept it fully.                                        */
  377.19 +/*                                                                         */
  377.20 +/***************************************************************************/
  377.21 +
  377.22 +
  377.23 +#ifndef __FTOPTION_H__
  377.24 +#define __FTOPTION_H__
  377.25 +
  377.26 +
  377.27 +#include <ft2build.h>
  377.28 +
  377.29 +
  377.30 +FT_BEGIN_HEADER
  377.31 +
  377.32 +  /*************************************************************************/
  377.33 +  /*                                                                       */
  377.34 +  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */
  377.35 +  /*                                                                       */
  377.36 +  /* This file contains the default configuration macro definitions for    */
  377.37 +  /* a standard build of the FreeType library.  There are three ways to    */
  377.38 +  /* use this file to build project-specific versions of the library:      */
  377.39 +  /*                                                                       */
  377.40 +  /*  - You can modify this file by hand, but this is not recommended in   */
  377.41 +  /*    cases where you would like to build several versions of the        */
  377.42 +  /*    library from a single source directory.                            */
  377.43 +  /*                                                                       */
  377.44 +  /*  - You can put a copy of this file in your build directory, more      */
  377.45 +  /*    precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD'   */
  377.46 +  /*    is the name of a directory that is included _before_ the FreeType  */
  377.47 +  /*    include path during compilation.                                   */
  377.48 +  /*                                                                       */
  377.49 +  /*    The default FreeType Makefiles and Jamfiles use the build          */
  377.50 +  /*    directory `builds/<system>' by default, but you can easily change  */
  377.51 +  /*    that for your own projects.                                        */
  377.52 +  /*                                                                       */
  377.53 +  /*  - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it    */
  377.54 +  /*    slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to       */
  377.55 +  /*    locate this file during the build.  For example,                   */
  377.56 +  /*                                                                       */
  377.57 +  /*      #define FT_CONFIG_OPTIONS_H  <myftoptions.h>                     */
  377.58 +  /*      #include <freetype/config/ftheader.h>                            */
  377.59 +  /*                                                                       */
  377.60 +  /*    will use `$BUILD/myftoptions.h' instead of this file for macro     */
  377.61 +  /*    definitions.                                                       */
  377.62 +  /*                                                                       */
  377.63 +  /*    Note also that you can similarly pre-define the macro              */
  377.64 +  /*    FT_CONFIG_MODULES_H used to locate the file listing of the modules */
  377.65 +  /*    that are statically linked to the library at compile time.  By     */
  377.66 +  /*    default, this file is <freetype/config/ftmodule.h>.                */
  377.67 +  /*                                                                       */
  377.68 +  /*  We highly recommend using the third method whenever possible.        */
  377.69 +  /*                                                                       */
  377.70 +  /*************************************************************************/
  377.71 +
  377.72 +
  377.73 +  /*************************************************************************/
  377.74 +  /*************************************************************************/
  377.75 +  /****                                                                 ****/
  377.76 +  /**** G E N E R A L   F R E E T Y P E   2   C O N F I G U R A T I O N ****/
  377.77 +  /****                                                                 ****/
  377.78 +  /*************************************************************************/
  377.79 +  /*************************************************************************/
  377.80 +
  377.81 +
  377.82 +  /*************************************************************************/
  377.83 +  /*                                                                       */
  377.84 +  /* Uncomment the line below if you want to activate sub-pixel rendering  */
  377.85 +  /* (a.k.a. LCD rendering, or ClearType) in this build of the library.    */
  377.86 +  /*                                                                       */
  377.87 +  /* Note that this feature is covered by several Microsoft patents        */
  377.88 +  /* and should not be activated in any default build of the library.      */
  377.89 +  /*                                                                       */
  377.90 +  /* This macro has no impact on the FreeType API, only on its             */
  377.91 +  /* _implementation_.  For example, using FT_RENDER_MODE_LCD when calling */
  377.92 +  /* FT_Render_Glyph still generates a bitmap that is 3 times wider than   */
  377.93 +  /* the original size in case this macro isn't defined; however, each     */
  377.94 +  /* triplet of subpixels has R=G=B.                                       */
  377.95 +  /*                                                                       */
  377.96 +  /* This is done to allow FreeType clients to run unmodified, forcing     */
  377.97 +  /* them to display normal gray-level anti-aliased glyphs.                */
  377.98 +  /*                                                                       */
  377.99 +/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
 377.100 +
 377.101 +
 377.102 +  /*************************************************************************/
 377.103 +  /*                                                                       */
 377.104 +  /* Many compilers provide a non-ANSI 64-bit data type that can be used   */
 377.105 +  /* by FreeType to speed up some computations.  However, this will create */
 377.106 +  /* some problems when compiling the library in strict ANSI mode.         */
 377.107 +  /*                                                                       */
 377.108 +  /* For this reason, the use of 64-bit integers is normally disabled when */
 377.109 +  /* the __STDC__ macro is defined.  You can however disable this by       */
 377.110 +  /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here.                 */
 377.111 +  /*                                                                       */
 377.112 +  /* For most compilers, this will only create compilation warnings when   */
 377.113 +  /* building the library.                                                 */
 377.114 +  /*                                                                       */
 377.115 +  /* ObNote: The compiler-specific 64-bit integers are detected in the     */
 377.116 +  /*         file `ftconfig.h' either statically or through the            */
 377.117 +  /*         `configure' script on supported platforms.                    */
 377.118 +  /*                                                                       */
 377.119 +#undef FT_CONFIG_OPTION_FORCE_INT64
 377.120 +
 377.121 +
 377.122 +  /*************************************************************************/
 377.123 +  /*                                                                       */
 377.124 +  /* If this macro is defined, do not try to use an assembler version of   */
 377.125 +  /* performance-critical functions (e.g. FT_MulFix).  You should only do  */
 377.126 +  /* that to verify that the assembler function works properly, or to      */
 377.127 +  /* execute benchmark tests of the various implementations.               */
 377.128 +/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */
 377.129 +
 377.130 +
 377.131 +  /*************************************************************************/
 377.132 +  /*                                                                       */
 377.133 +  /* If this macro is defined, try to use an inlined assembler version of  */
 377.134 +  /* the `FT_MulFix' function, which is a `hotspot' when loading and       */
 377.135 +  /* hinting glyphs, and which should be executed as fast as possible.     */
 377.136 +  /*                                                                       */
 377.137 +  /* Note that if your compiler or CPU is not supported, this will default */
 377.138 +  /* to the standard and portable implementation found in `ftcalc.c'.      */
 377.139 +  /*                                                                       */
 377.140 +#define FT_CONFIG_OPTION_INLINE_MULFIX
 377.141 +
 377.142 +
 377.143 +  /*************************************************************************/
 377.144 +  /*                                                                       */
 377.145 +  /* LZW-compressed file support.                                          */
 377.146 +  /*                                                                       */
 377.147 +  /*   FreeType now handles font files that have been compressed with the  */
 377.148 +  /*   `compress' program.  This is mostly used to parse many of the PCF   */
 377.149 +  /*   files that come with various X11 distributions.  The implementation */
 377.150 +  /*   uses NetBSD's `zopen' to partially uncompress the file on the fly   */
 377.151 +  /*   (see src/lzw/ftgzip.c).                                             */
 377.152 +  /*                                                                       */
 377.153 +  /*   Define this macro if you want to enable this `feature'.             */
 377.154 +  /*                                                                       */
 377.155 +#define FT_CONFIG_OPTION_USE_LZW
 377.156 +
 377.157 +
 377.158 +  /*************************************************************************/
 377.159 +  /*                                                                       */
 377.160 +  /* Gzip-compressed file support.                                         */
 377.161 +  /*                                                                       */
 377.162 +  /*   FreeType now handles font files that have been compressed with the  */
 377.163 +  /*   `gzip' program.  This is mostly used to parse many of the PCF files */
 377.164 +  /*   that come with XFree86.  The implementation uses `zlib' to          */
 377.165 +  /*   partially uncompress the file on the fly (see src/gzip/ftgzip.c).   */
 377.166 +  /*                                                                       */
 377.167 +  /*   Define this macro if you want to enable this `feature'.  See also   */
 377.168 +  /*   the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below.                       */
 377.169 +  /*                                                                       */
 377.170 +#define FT_CONFIG_OPTION_USE_ZLIB
 377.171 +
 377.172 +
 377.173 +  /*************************************************************************/
 377.174 +  /*                                                                       */
 377.175 +  /* ZLib library selection                                                */
 377.176 +  /*                                                                       */
 377.177 +  /*   This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined.  */
 377.178 +  /*   It allows FreeType's `ftgzip' component to link to the system's     */
 377.179 +  /*   installation of the ZLib library.  This is useful on systems like   */
 377.180 +  /*   Unix or VMS where it generally is already available.                */
 377.181 +  /*                                                                       */
 377.182 +  /*   If you let it undefined, the component will use its own copy        */
 377.183 +  /*   of the zlib sources instead.  These have been modified to be        */
 377.184 +  /*   included directly within the component and *not* export external    */
 377.185 +  /*   function names.  This allows you to link any program with FreeType  */
 377.186 +  /*   _and_ ZLib without linking conflicts.                               */
 377.187 +  /*                                                                       */
 377.188 +  /*   Do not #undef this macro here since the build system might define   */
 377.189 +  /*   it for certain configurations only.                                 */
 377.190 +  /*                                                                       */
 377.191 +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */
 377.192 +
 377.193 +
 377.194 +  /*************************************************************************/
 377.195 +  /*                                                                       */
 377.196 +  /* DLL export compilation                                                */
 377.197 +  /*                                                                       */
 377.198 +  /*   When compiling FreeType as a DLL, some systems/compilers need a     */
 377.199 +  /*   special keyword in front OR after the return type of function       */
 377.200 +  /*   declarations.                                                       */
 377.201 +  /*                                                                       */
 377.202 +  /*   Two macros are used within the FreeType source code to define       */
 377.203 +  /*   exported library functions: FT_EXPORT and FT_EXPORT_DEF.            */
 377.204 +  /*                                                                       */
 377.205 +  /*     FT_EXPORT( return_type )                                          */
 377.206 +  /*                                                                       */
 377.207 +  /*       is used in a function declaration, as in                        */
 377.208 +  /*                                                                       */
 377.209 +  /*         FT_EXPORT( FT_Error )                                         */
 377.210 +  /*         FT_Init_FreeType( FT_Library*  alibrary );                    */
 377.211 +  /*                                                                       */
 377.212 +  /*                                                                       */
 377.213 +  /*     FT_EXPORT_DEF( return_type )                                      */
 377.214 +  /*                                                                       */
 377.215 +  /*       is used in a function definition, as in                         */
 377.216 +  /*                                                                       */
 377.217 +  /*         FT_EXPORT_DEF( FT_Error )                                     */
 377.218 +  /*         FT_Init_FreeType( FT_Library*  alibrary )                     */
 377.219 +  /*         {                                                             */
 377.220 +  /*           ... some code ...                                           */
 377.221 +  /*           return FT_Err_Ok;                                           */
 377.222 +  /*         }                                                             */
 377.223 +  /*                                                                       */
 377.224 +  /*   You can provide your own implementation of FT_EXPORT and            */
 377.225 +  /*   FT_EXPORT_DEF here if you want.  If you leave them undefined, they  */
 377.226 +  /*   will be later automatically defined as `extern return_type' to      */
 377.227 +  /*   allow normal compilation.                                           */
 377.228 +  /*                                                                       */
 377.229 +  /*   Do not #undef these macros here since the build system might define */
 377.230 +  /*   them for certain configurations only.                               */
 377.231 +  /*                                                                       */
 377.232 +/* #define FT_EXPORT(x)      extern x */
 377.233 +/* #define FT_EXPORT_DEF(x)  x */
 377.234 +
 377.235 +
 377.236 +  /*************************************************************************/
 377.237 +  /*                                                                       */
 377.238 +  /* Glyph Postscript Names handling                                       */
 377.239 +  /*                                                                       */
 377.240 +  /*   By default, FreeType 2 is compiled with the `psnames' module.  This */
 377.241 +  /*   module is in charge of converting a glyph name string into a        */
 377.242 +  /*   Unicode value, or return a Macintosh standard glyph name for the    */
 377.243 +  /*   use with the TrueType `post' table.                                 */
 377.244 +  /*                                                                       */
 377.245 +  /*   Undefine this macro if you do not want `psnames' compiled in your   */
 377.246 +  /*   build of FreeType.  This has the following effects:                 */
 377.247 +  /*                                                                       */
 377.248 +  /*   - The TrueType driver will provide its own set of glyph names,      */
 377.249 +  /*     if you build it to support postscript names in the TrueType       */
 377.250 +  /*     `post' table.                                                     */
 377.251 +  /*                                                                       */
 377.252 +  /*   - The Type 1 driver will not be able to synthesize a Unicode        */
 377.253 +  /*     charmap out of the glyphs found in the fonts.                     */
 377.254 +  /*                                                                       */
 377.255 +  /*   You would normally undefine this configuration macro when building  */
 377.256 +  /*   a version of FreeType that doesn't contain a Type 1 or CFF driver.  */
 377.257 +  /*                                                                       */
 377.258 +#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES
 377.259 +
 377.260 +
 377.261 +  /*************************************************************************/
 377.262 +  /*                                                                       */
 377.263 +  /* Postscript Names to Unicode Values support                            */
 377.264 +  /*                                                                       */
 377.265 +  /*   By default, FreeType 2 is built with the `PSNames' module compiled  */
 377.266 +  /*   in.  Among other things, the module is used to convert a glyph name */
 377.267 +  /*   into a Unicode value.  This is especially useful in order to        */
 377.268 +  /*   synthesize on the fly a Unicode charmap from the CFF/Type 1 driver  */
 377.269 +  /*   through a big table named the `Adobe Glyph List' (AGL).             */
 377.270 +  /*                                                                       */
 377.271 +  /*   Undefine this macro if you do not want the Adobe Glyph List         */
 377.272 +  /*   compiled in your `PSNames' module.  The Type 1 driver will not be   */
 377.273 +  /*   able to synthesize a Unicode charmap out of the glyphs found in the */
 377.274 +  /*   fonts.                                                              */
 377.275 +  /*                                                                       */
 377.276 +#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
 377.277 +
 377.278 +
 377.279 +  /*************************************************************************/
 377.280 +  /*                                                                       */
 377.281 +  /* Support for Mac fonts                                                 */
 377.282 +  /*                                                                       */
 377.283 +  /*   Define this macro if you want support for outline fonts in Mac      */
 377.284 +  /*   format (mac dfont, mac resource, macbinary containing a mac         */
 377.285 +  /*   resource) on non-Mac platforms.                                     */
 377.286 +  /*                                                                       */
 377.287 +  /*   Note that the `FOND' resource isn't checked.                        */
 377.288 +  /*                                                                       */
 377.289 +#define FT_CONFIG_OPTION_MAC_FONTS
 377.290 +
 377.291 +
 377.292 +  /*************************************************************************/
 377.293 +  /*                                                                       */
 377.294 +  /* Guessing methods to access embedded resource forks                    */
 377.295 +  /*                                                                       */
 377.296 +  /*   Enable extra Mac fonts support on non-Mac platforms (e.g.           */
 377.297 +  /*   GNU/Linux).                                                         */
 377.298 +  /*                                                                       */
 377.299 +  /*   Resource forks which include fonts data are stored sometimes in     */
 377.300 +  /*   locations which users or developers don't expected.  In some cases, */
 377.301 +  /*   resource forks start with some offset from the head of a file.  In  */
 377.302 +  /*   other cases, the actual resource fork is stored in file different   */
 377.303 +  /*   from what the user specifies.  If this option is activated,         */
 377.304 +  /*   FreeType tries to guess whether such offsets or different file      */
 377.305 +  /*   names must be used.                                                 */
 377.306 +  /*                                                                       */
 377.307 +  /*   Note that normal, direct access of resource forks is controlled via */
 377.308 +  /*   the FT_CONFIG_OPTION_MAC_FONTS option.                              */
 377.309 +  /*                                                                       */
 377.310 +#ifdef FT_CONFIG_OPTION_MAC_FONTS
 377.311 +#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
 377.312 +#endif
 377.313 +
 377.314 +
 377.315 +  /*************************************************************************/
 377.316 +  /*                                                                       */
 377.317 +  /* Allow the use of FT_Incremental_Interface to load typefaces that      */
 377.318 +  /* contain no glyph data, but supply it via a callback function.         */
 377.319 +  /* This is required by clients supporting document formats which         */
 377.320 +  /* supply font data incrementally as the document is parsed, such        */
 377.321 +  /* as the Ghostscript interpreter for the PostScript language.           */
 377.322 +  /*                                                                       */
 377.323 +#define FT_CONFIG_OPTION_INCREMENTAL
 377.324 +
 377.325 +
 377.326 +  /*************************************************************************/
 377.327 +  /*                                                                       */
 377.328 +  /* The size in bytes of the render pool used by the scan-line converter  */
 377.329 +  /* to do all of its work.                                                */
 377.330 +  /*                                                                       */
 377.331 +  /* This must be greater than 4KByte if you use FreeType to rasterize     */
 377.332 +  /* glyphs; otherwise, you may set it to zero to avoid unnecessary        */
 377.333 +  /* allocation of the render pool.                                        */
 377.334 +  /*                                                                       */
 377.335 +#define FT_RENDER_POOL_SIZE  16384L
 377.336 +
 377.337 +
 377.338 +  /*************************************************************************/
 377.339 +  /*                                                                       */
 377.340 +  /* FT_MAX_MODULES                                                        */
 377.341 +  /*                                                                       */
 377.342 +  /*   The maximum number of modules that can be registered in a single    */
 377.343 +  /*   FreeType library object.  32 is the default.                        */
 377.344 +  /*                                                                       */
 377.345 +#define FT_MAX_MODULES  32
 377.346 +
 377.347 +
 377.348 +  /*************************************************************************/
 377.349 +  /*                                                                       */
 377.350 +  /* Debug level                                                           */
 377.351 +  /*                                                                       */
 377.352 +  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
 377.353 +  /*   errors are reported through the `ftdebug' component.  In trace      */
 377.354 +  /*   mode, additional messages are sent to the standard output during    */
 377.355 +  /*   execution.                                                          */
 377.356 +  /*                                                                       */
 377.357 +  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
 377.358 +  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
 377.359 +  /*                                                                       */
 377.360 +  /*   Don't define any of these macros to compile in `release' mode!      */
 377.361 +  /*                                                                       */
 377.362 +  /*   Do not #undef these macros here since the build system might define */
 377.363 +  /*   them for certain configurations only.                               */
 377.364 +  /*                                                                       */
 377.365 +/* #define FT_DEBUG_LEVEL_ERROR */
 377.366 +/* #define FT_DEBUG_LEVEL_TRACE */
 377.367 +
 377.368 +
 377.369 +  /*************************************************************************/
 377.370 +  /*                                                                       */
 377.371 +  /* Memory Debugging                                                      */
 377.372 +  /*                                                                       */
 377.373 +  /*   FreeType now comes with an integrated memory debugger that is       */
 377.374 +  /*   capable of detecting simple errors like memory leaks or double      */
 377.375 +  /*   deletes.  To compile it within your build of the library, you       */
 377.376 +  /*   should define FT_DEBUG_MEMORY here.                                 */
 377.377 +  /*                                                                       */
 377.378 +  /*   Note that the memory debugger is only activated at runtime when     */
 377.379 +  /*   when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */
 377.380 +  /*                                                                       */
 377.381 +  /*   Do not #undef this macro here since the build system might define   */
 377.382 +  /*   it for certain configurations only.                                 */
 377.383 +  /*                                                                       */
 377.384 +/* #define FT_DEBUG_MEMORY */
 377.385 +
 377.386 +
 377.387 +  /*************************************************************************/
 377.388 +  /*                                                                       */
 377.389 +  /* Module errors                                                         */
 377.390 +  /*                                                                       */
 377.391 +  /*   If this macro is set (which is _not_ the default), the higher byte  */
 377.392 +  /*   of an error code gives the module in which the error has occurred,  */
 377.393 +  /*   while the lower byte is the real error code.                        */
 377.394 +  /*                                                                       */
 377.395 +  /*   Setting this macro makes sense for debugging purposes only, since   */
 377.396 +  /*   it would break source compatibility of certain programs that use    */
 377.397 +  /*   FreeType 2.                                                         */
 377.398 +  /*                                                                       */
 377.399 +  /*   More details can be found in the files ftmoderr.h and fterrors.h.   */
 377.400 +  /*                                                                       */
 377.401 +#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
 377.402 +
 377.403 +
 377.404 +  /*************************************************************************/
 377.405 +  /*                                                                       */
 377.406 +  /* Position Independent Code                                             */
 377.407 +  /*                                                                       */
 377.408 +  /*   If this macro is set (which is _not_ the default), FreeType2 will   */
 377.409 +  /*   avoid creating constants that require address fixups.  Instead the  */
 377.410 +  /*   constants will be moved into a struct and additional intialization  */
 377.411 +  /*   code will be used.                                                  */
 377.412 +  /*                                                                       */
 377.413 +  /*   Setting this macro is needed for systems that prohibit address      */
 377.414 +  /*   fixups, such as BREW.                                               */
 377.415 +  /*                                                                       */
 377.416 +/* #define FT_CONFIG_OPTION_PIC */
 377.417 +
 377.418 +
 377.419 +  /*************************************************************************/
 377.420 +  /*************************************************************************/
 377.421 +  /****                                                                 ****/
 377.422 +  /****        S F N T   D R I V E R    C O N F I G U R A T I O N       ****/
 377.423 +  /****                                                                 ****/
 377.424 +  /*************************************************************************/
 377.425 +  /*************************************************************************/
 377.426 +
 377.427 +
 377.428 +  /*************************************************************************/
 377.429 +  /*                                                                       */
 377.430 +  /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support       */
 377.431 +  /* embedded bitmaps in all formats using the SFNT module (namely         */
 377.432 +  /* TrueType & OpenType).                                                 */
 377.433 +  /*                                                                       */
 377.434 +#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 377.435 +
 377.436 +
 377.437 +  /*************************************************************************/
 377.438 +  /*                                                                       */
 377.439 +  /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to    */
 377.440 +  /* load and enumerate the glyph Postscript names in a TrueType or        */
 377.441 +  /* OpenType file.                                                        */
 377.442 +  /*                                                                       */
 377.443 +  /* Note that when you do not compile the `PSNames' module by undefining  */
 377.444 +  /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will   */
 377.445 +  /* contain additional code used to read the PS Names table from a font.  */
 377.446 +  /*                                                                       */
 377.447 +  /* (By default, the module uses `PSNames' to extract glyph names.)       */
 377.448 +  /*                                                                       */
 377.449 +#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
 377.450 +
 377.451 +
 377.452 +  /*************************************************************************/
 377.453 +  /*                                                                       */
 377.454 +  /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to       */
 377.455 +  /* access the internal name table in a SFNT-based format like TrueType   */
 377.456 +  /* or OpenType.  The name table contains various strings used to         */
 377.457 +  /* describe the font, like family name, copyright, version, etc.  It     */
 377.458 +  /* does not contain any glyph name though.                               */
 377.459 +  /*                                                                       */
 377.460 +  /* Accessing SFNT names is done through the functions declared in        */
 377.461 +  /* `freetype/ftsnames.h'.                                                */
 377.462 +  /*                                                                       */
 377.463 +#define TT_CONFIG_OPTION_SFNT_NAMES
 377.464 +
 377.465 +
 377.466 +  /*************************************************************************/
 377.467 +  /*                                                                       */
 377.468 +  /* TrueType CMap support                                                 */
 377.469 +  /*                                                                       */
 377.470 +  /*   Here you can fine-tune which TrueType CMap table format shall be    */
 377.471 +  /*   supported.                                                          */
 377.472 +#define TT_CONFIG_CMAP_FORMAT_0
 377.473 +#define TT_CONFIG_CMAP_FORMAT_2
 377.474 +#define TT_CONFIG_CMAP_FORMAT_4
 377.475 +#define TT_CONFIG_CMAP_FORMAT_6
 377.476 +#define TT_CONFIG_CMAP_FORMAT_8
 377.477 +#define TT_CONFIG_CMAP_FORMAT_10
 377.478 +#define TT_CONFIG_CMAP_FORMAT_12
 377.479 +#define TT_CONFIG_CMAP_FORMAT_13
 377.480 +#define TT_CONFIG_CMAP_FORMAT_14
 377.481 +
 377.482 +
 377.483 +  /*************************************************************************/
 377.484 +  /*************************************************************************/
 377.485 +  /****                                                                 ****/
 377.486 +  /****    T R U E T Y P E   D R I V E R    C O N F I G U R A T I O N   ****/
 377.487 +  /****                                                                 ****/
 377.488 +  /*************************************************************************/
 377.489 +  /*************************************************************************/
 377.490 +
 377.491 +  /*************************************************************************/
 377.492 +  /*                                                                       */
 377.493 +  /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile   */
 377.494 +  /* a bytecode interpreter in the TrueType driver.                        */
 377.495 +  /*                                                                       */
 377.496 +  /* By undefining this, you will only compile the code necessary to load  */
 377.497 +  /* TrueType glyphs without hinting.                                      */
 377.498 +  /*                                                                       */
 377.499 +  /*   Do not #undef this macro here, since the build system might         */
 377.500 +  /*   define it for certain configurations only.                          */
 377.501 +  /*                                                                       */
 377.502 +#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 377.503 +
 377.504 +
 377.505 +  /*************************************************************************/
 377.506 +  /*                                                                       */
 377.507 +  /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version  */
 377.508 +  /* of the TrueType bytecode interpreter is used that doesn't implement   */
 377.509 +  /* any of the patented opcodes and algorithms.  The patents related to   */
 377.510 +  /* TrueType hinting have expired worldwide since May 2010; this option   */
 377.511 +  /* is now deprecated.                                                    */
 377.512 +  /*                                                                       */
 377.513 +  /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored*  */
 377.514 +  /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words,  */
 377.515 +  /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or                */
 377.516 +  /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time.    */
 377.517 +  /*                                                                       */
 377.518 +  /* This macro is only useful for a small number of font files (mostly    */
 377.519 +  /* for Asian scripts) that require bytecode interpretation to properly   */
 377.520 +  /* load glyphs.  For all other fonts, this produces unpleasant results,  */
 377.521 +  /* thus the unpatented interpreter is never used to load glyphs from     */
 377.522 +  /* TrueType fonts unless one of the following two options is used.       */
 377.523 +  /*                                                                       */
 377.524 +  /*   - The unpatented interpreter is explicitly activated by the user    */
 377.525 +  /*     through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag         */
 377.526 +  /*     when opening the FT_Face.                                         */
 377.527 +  /*                                                                       */
 377.528 +  /*   - FreeType detects that the FT_Face corresponds to one of the       */
 377.529 +  /*     `trick' fonts (e.g., `Mingliu') it knows about.  The font engine  */
 377.530 +  /*     contains a hard-coded list of font names and other matching       */
 377.531 +  /*     parameters (see function `tt_face_init' in file                   */
 377.532 +  /*     `src/truetype/ttobjs.c').                                         */
 377.533 +  /*                                                                       */
 377.534 +  /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */
 377.535 +  /*                                                                       */
 377.536 +  /*   {                                                                   */
 377.537 +  /*     FT_Parameter  parameter;                                          */
 377.538 +  /*     FT_Open_Args  open_args;                                          */
 377.539 +  /*                                                                       */
 377.540 +  /*                                                                       */
 377.541 +  /*     parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING;                  */
 377.542 +  /*                                                                       */
 377.543 +  /*     open_args.flags      = FT_OPEN_PATHNAME | FT_OPEN_PARAMS;         */
 377.544 +  /*     open_args.pathname   = my_font_pathname;                          */
 377.545 +  /*     open_args.num_params = 1;                                         */
 377.546 +  /*     open_args.params     = &parameter;                                */
 377.547 +  /*                                                                       */
 377.548 +  /*     error = FT_Open_Face( library, &open_args, index, &face );        */
 377.549 +  /*     ...                                                               */
 377.550 +  /*   }                                                                   */
 377.551 +  /*                                                                       */
 377.552 +/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */
 377.553 +
 377.554 +
 377.555 +  /*************************************************************************/
 377.556 +  /*                                                                       */
 377.557 +  /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType    */
 377.558 +  /* bytecode interpreter with a huge switch statement, rather than a call */
 377.559 +  /* table.  This results in smaller and faster code for a number of       */
 377.560 +  /* architectures.                                                        */
 377.561 +  /*                                                                       */
 377.562 +  /* Note however that on some compiler/processor combinations, undefining */
 377.563 +  /* this macro will generate faster, though larger, code.                 */
 377.564 +  /*                                                                       */
 377.565 +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH
 377.566 +
 377.567 +
 377.568 +  /*************************************************************************/
 377.569 +  /*                                                                       */
 377.570 +  /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the        */
 377.571 +  /* TrueType glyph loader to use Apple's definition of how to handle      */
 377.572 +  /* component offsets in composite glyphs.                                */
 377.573 +  /*                                                                       */
 377.574 +  /* Apple and MS disagree on the default behavior of component offsets    */
 377.575 +  /* in composites.  Apple says that they should be scaled by the scaling  */
 377.576 +  /* factors in the transformation matrix (roughly, it's more complex)     */
 377.577 +  /* while MS says they should not.  OpenType defines two bits in the      */
 377.578 +  /* composite flags array which can be used to disambiguate, but old      */
 377.579 +  /* fonts will not have them.                                             */
 377.580 +  /*                                                                       */
 377.581 +  /*   http://partners.adobe.com/asn/developer/opentype/glyf.html          */
 377.582 +  /*   http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html                 */
 377.583 +  /*                                                                       */
 377.584 +#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
 377.585 +
 377.586 +
 377.587 +  /*************************************************************************/
 377.588 +  /*                                                                       */
 377.589 +  /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include         */
 377.590 +  /* support for Apple's distortable font technology (fvar, gvar, cvar,    */
 377.591 +  /* and avar tables).  This has many similarities to Type 1 Multiple      */
 377.592 +  /* Masters support.                                                      */
 377.593 +  /*                                                                       */
 377.594 +#define TT_CONFIG_OPTION_GX_VAR_SUPPORT
 377.595 +
 377.596 +
 377.597 +  /*************************************************************************/
 377.598 +  /*                                                                       */
 377.599 +  /* Define TT_CONFIG_OPTION_BDF if you want to include support for        */
 377.600 +  /* an embedded `BDF ' table within SFNT-based bitmap formats.            */
 377.601 +  /*                                                                       */
 377.602 +#define TT_CONFIG_OPTION_BDF
 377.603 +
 377.604 +
 377.605 +  /*************************************************************************/
 377.606 +  /*************************************************************************/
 377.607 +  /****                                                                 ****/
 377.608 +  /****      T Y P E 1   D R I V E R    C O N F I G U R A T I O N       ****/
 377.609 +  /****                                                                 ****/
 377.610 +  /*************************************************************************/
 377.611 +  /*************************************************************************/
 377.612 +
 377.613 +
 377.614 +  /*************************************************************************/
 377.615 +  /*                                                                       */
 377.616 +  /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and       */
 377.617 +  /* arrays in the Type 1 stream (see t1load.c).  A minimum of 4 is        */
 377.618 +  /* required.                                                             */
 377.619 +  /*                                                                       */
 377.620 +#define T1_MAX_DICT_DEPTH  5
 377.621 +
 377.622 +
 377.623 +  /*************************************************************************/
 377.624 +  /*                                                                       */
 377.625 +  /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine   */
 377.626 +  /* calls during glyph loading.                                           */
 377.627 +  /*                                                                       */
 377.628 +#define T1_MAX_SUBRS_CALLS  16
 377.629 +
 377.630 +
 377.631 +  /*************************************************************************/
 377.632 +  /*                                                                       */
 377.633 +  /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity.  A     */
 377.634 +  /* minimum of 16 is required.                                            */
 377.635 +  /*                                                                       */
 377.636 +  /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */
 377.637 +  /*                                                                       */
 377.638 +#define T1_MAX_CHARSTRINGS_OPERANDS  256
 377.639 +
 377.640 +
 377.641 +  /*************************************************************************/
 377.642 +  /*                                                                       */
 377.643 +  /* Define this configuration macro if you want to prevent the            */
 377.644 +  /* compilation of `t1afm', which is in charge of reading Type 1 AFM      */
 377.645 +  /* files into an existing face.  Note that if set, the T1 driver will be */
 377.646 +  /* unable to produce kerning distances.                                  */
 377.647 +  /*                                                                       */
 377.648 +#undef T1_CONFIG_OPTION_NO_AFM
 377.649 +
 377.650 +
 377.651 +  /*************************************************************************/
 377.652 +  /*                                                                       */
 377.653 +  /* Define this configuration macro if you want to prevent the            */
 377.654 +  /* compilation of the Multiple Masters font support in the Type 1        */
 377.655 +  /* driver.                                                               */
 377.656 +  /*                                                                       */
 377.657 +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT
 377.658 +
 377.659 +
 377.660 +  /*************************************************************************/
 377.661 +  /*************************************************************************/
 377.662 +  /****                                                                 ****/
 377.663 +  /****    A U T O F I T   M O D U L E    C O N F I G U R A T I O N     ****/
 377.664 +  /****                                                                 ****/
 377.665 +  /*************************************************************************/
 377.666 +  /*************************************************************************/
 377.667 +
 377.668 +
 377.669 +  /*************************************************************************/
 377.670 +  /*                                                                       */
 377.671 +  /* Compile autofit module with CJK (Chinese, Japanese, Korean) script    */
 377.672 +  /* support.                                                              */
 377.673 +  /*                                                                       */
 377.674 +#define AF_CONFIG_OPTION_CJK
 377.675 +
 377.676 +  /*************************************************************************/
 377.677 +  /*                                                                       */
 377.678 +  /* Compile autofit module with Indic script support.                     */
 377.679 +  /*                                                                       */
 377.680 +#define AF_CONFIG_OPTION_INDIC
 377.681 +
 377.682 +  /* */
 377.683 +
 377.684 +
 377.685 +  /*
 377.686 +   * Define this variable if you want to keep the layout of internal
 377.687 +   * structures that was used prior to FreeType 2.2.  This also compiles in
 377.688 +   * a few obsolete functions to avoid linking problems on typical Unix
 377.689 +   * distributions.
 377.690 +   *
 377.691 +   * For embedded systems or building a new distribution from scratch, it
 377.692 +   * is recommended to disable the macro since it reduces the library's code
 377.693 +   * size and activates a few memory-saving optimizations as well.
 377.694 +   */
 377.695 +#define FT_CONFIG_OPTION_OLD_INTERNALS
 377.696 +
 377.697 +
 377.698 +  /*
 377.699 +   *  To detect legacy cache-lookup call from a rogue client (<= 2.1.7),
 377.700 +   *  we restrict the number of charmaps in a font.  The current API of
 377.701 +   *  FTC_CMapCache_Lookup() takes cmap_index & charcode, but old API
 377.702 +   *  takes charcode only.  To determine the passed value is for cmap_index
 377.703 +   *  or charcode, the possible cmap_index is restricted not to exceed
 377.704 +   *  the minimum possible charcode by a rogue client.  It is also very
 377.705 +   *  unlikely that a rogue client is interested in Unicode values 0 to 15.
 377.706 +   *
 377.707 +   *  NOTE: The original threshold was 4 deduced from popular number of
 377.708 +   *        cmap subtables in UCS-4 TrueType fonts, but now it is not
 377.709 +   *        irregular for OpenType fonts to have more than 4 subtables,
 377.710 +   *        because variation selector subtables are available for Apple
 377.711 +   *        and Microsoft platforms.
 377.712 +   */
 377.713 +
 377.714 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 377.715 +#define FT_MAX_CHARMAP_CACHEABLE 15
 377.716 +#endif
 377.717 +
 377.718 +
 377.719 +  /*
 377.720 +   * This macro is defined if either unpatented or native TrueType
 377.721 +   * hinting is requested by the definitions above.
 377.722 +   */
 377.723 +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 377.724 +#define  TT_USE_BYTECODE_INTERPRETER
 377.725 +#undef   TT_CONFIG_OPTION_UNPATENTED_HINTING
 377.726 +#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING
 377.727 +#define  TT_USE_BYTECODE_INTERPRETER
 377.728 +#endif
 377.729 +
 377.730 +FT_END_HEADER
 377.731 +
 377.732 +
 377.733 +#endif /* __FTOPTION_H__ */
 377.734 +
 377.735 +
 377.736 +/* END */
   378.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   378.2 +++ b/libs/ft2static/freetype/config/ftstdlib.h	Sat Feb 01 19:58:19 2014 +0200
   378.3 @@ -0,0 +1,173 @@
   378.4 +/***************************************************************************/
   378.5 +/*                                                                         */
   378.6 +/*  ftstdlib.h                                                             */
   378.7 +/*                                                                         */
   378.8 +/*    ANSI-specific library and header configuration file (specification   */
   378.9 +/*    only).                                                               */
  378.10 +/*                                                                         */
  378.11 +/*  Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2009 by                  */
  378.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  378.13 +/*                                                                         */
  378.14 +/*  This file is part of the FreeType project, and may only be used,       */
  378.15 +/*  modified, and distributed under the terms of the FreeType project      */
  378.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  378.17 +/*  this file you indicate that you have read the license and              */
  378.18 +/*  understand and accept it fully.                                        */
  378.19 +/*                                                                         */
  378.20 +/***************************************************************************/
  378.21 +
  378.22 +
  378.23 +  /*************************************************************************/
  378.24 +  /*                                                                       */
  378.25 +  /* This file is used to group all #includes to the ANSI C library that   */
  378.26 +  /* FreeType normally requires.  It also defines macros to rename the     */
  378.27 +  /* standard functions within the FreeType source code.                   */
  378.28 +  /*                                                                       */
  378.29 +  /* Load a file which defines __FTSTDLIB_H__ before this one to override  */
  378.30 +  /* it.                                                                   */
  378.31 +  /*                                                                       */
  378.32 +  /*************************************************************************/
  378.33 +
  378.34 +
  378.35 +#ifndef __FTSTDLIB_H__
  378.36 +#define __FTSTDLIB_H__
  378.37 +
  378.38 +
  378.39 +#include <stddef.h>
  378.40 +
  378.41 +#define ft_ptrdiff_t  ptrdiff_t
  378.42 +
  378.43 +
  378.44 +  /**********************************************************************/
  378.45 +  /*                                                                    */
  378.46 +  /*                           integer limits                           */
  378.47 +  /*                                                                    */
  378.48 +  /* UINT_MAX and ULONG_MAX are used to automatically compute the size  */
  378.49 +  /* of `int' and `long' in bytes at compile-time.  So far, this works  */
  378.50 +  /* for all platforms the library has been tested on.                  */
  378.51 +  /*                                                                    */
  378.52 +  /* Note that on the extremely rare platforms that do not provide      */
  378.53 +  /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some    */
  378.54 +  /* old Crays where `int' is 36 bits), we do not make any guarantee    */
  378.55 +  /* about the correct behaviour of FT2 with all fonts.                 */
  378.56 +  /*                                                                    */
  378.57 +  /* In these case, `ftconfig.h' will refuse to compile anyway with a   */
  378.58 +  /* message like `couldn't find 32-bit type' or something similar.     */
  378.59 +  /*                                                                    */
  378.60 +  /**********************************************************************/
  378.61 +
  378.62 +
  378.63 +#include <limits.h>
  378.64 +
  378.65 +#define FT_CHAR_BIT   CHAR_BIT
  378.66 +#define FT_INT_MAX    INT_MAX
  378.67 +#define FT_INT_MIN    INT_MIN
  378.68 +#define FT_UINT_MAX   UINT_MAX
  378.69 +#define FT_ULONG_MAX  ULONG_MAX
  378.70 +
  378.71 +
  378.72 +  /**********************************************************************/
  378.73 +  /*                                                                    */
  378.74 +  /*                 character and string processing                    */
  378.75 +  /*                                                                    */
  378.76 +  /**********************************************************************/
  378.77 +
  378.78 +
  378.79 +#include <string.h>
  378.80 +
  378.81 +#define ft_memchr   memchr
  378.82 +#define ft_memcmp   memcmp
  378.83 +#define ft_memcpy   memcpy
  378.84 +#define ft_memmove  memmove
  378.85 +#define ft_memset   memset
  378.86 +#define ft_strcat   strcat
  378.87 +#define ft_strcmp   strcmp
  378.88 +#define ft_strcpy   strcpy
  378.89 +#define ft_strlen   strlen
  378.90 +#define ft_strncmp  strncmp
  378.91 +#define ft_strncpy  strncpy
  378.92 +#define ft_strrchr  strrchr
  378.93 +#define ft_strstr   strstr
  378.94 +
  378.95 +
  378.96 +  /**********************************************************************/
  378.97 +  /*                                                                    */
  378.98 +  /*                           file handling                            */
  378.99 +  /*                                                                    */
 378.100 +  /**********************************************************************/
 378.101 +
 378.102 +
 378.103 +#include <stdio.h>
 378.104 +
 378.105 +#define FT_FILE     FILE
 378.106 +#define ft_fclose   fclose
 378.107 +#define ft_fopen    fopen
 378.108 +#define ft_fread    fread
 378.109 +#define ft_fseek    fseek
 378.110 +#define ft_ftell    ftell
 378.111 +#define ft_sprintf  sprintf
 378.112 +
 378.113 +
 378.114 +  /**********************************************************************/
 378.115 +  /*                                                                    */
 378.116 +  /*                             sorting                                */
 378.117 +  /*                                                                    */
 378.118 +  /**********************************************************************/
 378.119 +
 378.120 +
 378.121 +#include <stdlib.h>
 378.122 +
 378.123 +#define ft_qsort  qsort
 378.124 +
 378.125 +
 378.126 +  /**********************************************************************/
 378.127 +  /*                                                                    */
 378.128 +  /*                        memory allocation                           */
 378.129 +  /*                                                                    */
 378.130 +  /**********************************************************************/
 378.131 +
 378.132 +
 378.133 +#define ft_scalloc   calloc
 378.134 +#define ft_sfree     free
 378.135 +#define ft_smalloc   malloc
 378.136 +#define ft_srealloc  realloc
 378.137 +
 378.138 +
 378.139 +  /**********************************************************************/
 378.140 +  /*                                                                    */
 378.141 +  /*                          miscellaneous                             */
 378.142 +  /*                                                                    */
 378.143 +  /**********************************************************************/
 378.144 +
 378.145 +
 378.146 +#define ft_atol   atol
 378.147 +#define ft_labs   labs
 378.148 +
 378.149 +
 378.150 +  /**********************************************************************/
 378.151 +  /*                                                                    */
 378.152 +  /*                         execution control                          */
 378.153 +  /*                                                                    */
 378.154 +  /**********************************************************************/
 378.155 +
 378.156 +
 378.157 +#include <setjmp.h>
 378.158 +
 378.159 +#define ft_jmp_buf     jmp_buf  /* note: this cannot be a typedef since */
 378.160 +                                /*       jmp_buf is defined as a macro  */
 378.161 +                                /*       on certain platforms           */
 378.162 +
 378.163 +#define ft_longjmp     longjmp
 378.164 +#define ft_setjmp( b ) setjmp( *(jmp_buf*) &(b) )    /* same thing here */
 378.165 +
 378.166 +
 378.167 +  /* the following is only used for debugging purposes, i.e., if */
 378.168 +  /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined    */
 378.169 +
 378.170 +#include <stdarg.h>
 378.171 +
 378.172 +
 378.173 +#endif /* __FTSTDLIB_H__ */
 378.174 +
 378.175 +
 378.176 +/* END */
   379.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   379.2 +++ b/libs/ft2static/freetype/freetype.h	Sat Feb 01 19:58:19 2014 +0200
   379.3 @@ -0,0 +1,3919 @@
   379.4 +/***************************************************************************/
   379.5 +/*                                                                         */
   379.6 +/*  freetype.h                                                             */
   379.7 +/*                                                                         */
   379.8 +/*    FreeType high-level API and common types (specification only).       */
   379.9 +/*                                                                         */
  379.10 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
  379.11 +/*            2010 by                                                      */
  379.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  379.13 +/*                                                                         */
  379.14 +/*  This file is part of the FreeType project, and may only be used,       */
  379.15 +/*  modified, and distributed under the terms of the FreeType project      */
  379.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  379.17 +/*  this file you indicate that you have read the license and              */
  379.18 +/*  understand and accept it fully.                                        */
  379.19 +/*                                                                         */
  379.20 +/***************************************************************************/
  379.21 +
  379.22 +
  379.23 +#ifndef FT_FREETYPE_H
  379.24 +#error "`ft2build.h' hasn't been included yet!"
  379.25 +#error "Please always use macros to include FreeType header files."
  379.26 +#error "Example:"
  379.27 +#error "  #include <ft2build.h>"
  379.28 +#error "  #include FT_FREETYPE_H"
  379.29 +#endif
  379.30 +
  379.31 +
  379.32 +#ifndef __FREETYPE_H__
  379.33 +#define __FREETYPE_H__
  379.34 +
  379.35 +
  379.36 +#include <ft2build.h>
  379.37 +#include FT_CONFIG_CONFIG_H
  379.38 +#include FT_ERRORS_H
  379.39 +#include FT_TYPES_H
  379.40 +
  379.41 +
  379.42 +FT_BEGIN_HEADER
  379.43 +
  379.44 +
  379.45 +
  379.46 +  /*************************************************************************/
  379.47 +  /*                                                                       */
  379.48 +  /* <Section>                                                             */
  379.49 +  /*    user_allocation                                                    */
  379.50 +  /*                                                                       */
  379.51 +  /* <Title>                                                               */
  379.52 +  /*    User allocation                                                    */
  379.53 +  /*                                                                       */
  379.54 +  /* <Abstract>                                                            */
  379.55 +  /*    How client applications should allocate FreeType data structures.  */
  379.56 +  /*                                                                       */
  379.57 +  /* <Description>                                                         */
  379.58 +  /*    FreeType assumes that structures allocated by the user and passed  */
  379.59 +  /*    as arguments are zeroed out except for the actual data.  In other  */
  379.60 +  /*    words, it is recommended to use `calloc' (or variants of it)       */
  379.61 +  /*    instead of `malloc' for allocation.                                */
  379.62 +  /*                                                                       */
  379.63 +  /*************************************************************************/
  379.64 +
  379.65 +
  379.66 +
  379.67 +  /*************************************************************************/
  379.68 +  /*************************************************************************/
  379.69 +  /*                                                                       */
  379.70 +  /*                        B A S I C   T Y P E S                          */
  379.71 +  /*                                                                       */
  379.72 +  /*************************************************************************/
  379.73 +  /*************************************************************************/
  379.74 +
  379.75 +
  379.76 +  /*************************************************************************/
  379.77 +  /*                                                                       */
  379.78 +  /* <Section>                                                             */
  379.79 +  /*    base_interface                                                     */
  379.80 +  /*                                                                       */
  379.81 +  /* <Title>                                                               */
  379.82 +  /*    Base Interface                                                     */
  379.83 +  /*                                                                       */
  379.84 +  /* <Abstract>                                                            */
  379.85 +  /*    The FreeType~2 base font interface.                                */
  379.86 +  /*                                                                       */
  379.87 +  /* <Description>                                                         */
  379.88 +  /*    This section describes the public high-level API of FreeType~2.    */
  379.89 +  /*                                                                       */
  379.90 +  /* <Order>                                                               */
  379.91 +  /*    FT_Library                                                         */
  379.92 +  /*    FT_Face                                                            */
  379.93 +  /*    FT_Size                                                            */
  379.94 +  /*    FT_GlyphSlot                                                       */
  379.95 +  /*    FT_CharMap                                                         */
  379.96 +  /*    FT_Encoding                                                        */
  379.97 +  /*                                                                       */
  379.98 +  /*    FT_FaceRec                                                         */
  379.99 +  /*                                                                       */
 379.100 +  /*    FT_FACE_FLAG_SCALABLE                                              */
 379.101 +  /*    FT_FACE_FLAG_FIXED_SIZES                                           */
 379.102 +  /*    FT_FACE_FLAG_FIXED_WIDTH                                           */
 379.103 +  /*    FT_FACE_FLAG_HORIZONTAL                                            */
 379.104 +  /*    FT_FACE_FLAG_VERTICAL                                              */
 379.105 +  /*    FT_FACE_FLAG_SFNT                                                  */
 379.106 +  /*    FT_FACE_FLAG_KERNING                                               */
 379.107 +  /*    FT_FACE_FLAG_MULTIPLE_MASTERS                                      */
 379.108 +  /*    FT_FACE_FLAG_GLYPH_NAMES                                           */
 379.109 +  /*    FT_FACE_FLAG_EXTERNAL_STREAM                                       */
 379.110 +  /*    FT_FACE_FLAG_FAST_GLYPHS                                           */
 379.111 +  /*    FT_FACE_FLAG_HINTER                                                */
 379.112 +  /*                                                                       */
 379.113 +  /*    FT_STYLE_FLAG_BOLD                                                 */
 379.114 +  /*    FT_STYLE_FLAG_ITALIC                                               */
 379.115 +  /*                                                                       */
 379.116 +  /*    FT_SizeRec                                                         */
 379.117 +  /*    FT_Size_Metrics                                                    */
 379.118 +  /*                                                                       */
 379.119 +  /*    FT_GlyphSlotRec                                                    */
 379.120 +  /*    FT_Glyph_Metrics                                                   */
 379.121 +  /*    FT_SubGlyph                                                        */
 379.122 +  /*                                                                       */
 379.123 +  /*    FT_Bitmap_Size                                                     */
 379.124 +  /*                                                                       */
 379.125 +  /*    FT_Init_FreeType                                                   */
 379.126 +  /*    FT_Done_FreeType                                                   */
 379.127 +  /*                                                                       */
 379.128 +  /*    FT_New_Face                                                        */
 379.129 +  /*    FT_Done_Face                                                       */
 379.130 +  /*    FT_New_Memory_Face                                                 */
 379.131 +  /*    FT_Open_Face                                                       */
 379.132 +  /*    FT_Open_Args                                                       */
 379.133 +  /*    FT_Parameter                                                       */
 379.134 +  /*    FT_Attach_File                                                     */
 379.135 +  /*    FT_Attach_Stream                                                   */
 379.136 +  /*                                                                       */
 379.137 +  /*    FT_Set_Char_Size                                                   */
 379.138 +  /*    FT_Set_Pixel_Sizes                                                 */
 379.139 +  /*    FT_Request_Size                                                    */
 379.140 +  /*    FT_Select_Size                                                     */
 379.141 +  /*    FT_Size_Request_Type                                               */
 379.142 +  /*    FT_Size_Request                                                    */
 379.143 +  /*    FT_Set_Transform                                                   */
 379.144 +  /*    FT_Load_Glyph                                                      */
 379.145 +  /*    FT_Get_Char_Index                                                  */
 379.146 +  /*    FT_Get_Name_Index                                                  */
 379.147 +  /*    FT_Load_Char                                                       */
 379.148 +  /*                                                                       */
 379.149 +  /*    FT_OPEN_MEMORY                                                     */
 379.150 +  /*    FT_OPEN_STREAM                                                     */
 379.151 +  /*    FT_OPEN_PATHNAME                                                   */
 379.152 +  /*    FT_OPEN_DRIVER                                                     */
 379.153 +  /*    FT_OPEN_PARAMS                                                     */
 379.154 +  /*                                                                       */
 379.155 +  /*    FT_LOAD_DEFAULT                                                    */
 379.156 +  /*    FT_LOAD_RENDER                                                     */
 379.157 +  /*    FT_LOAD_MONOCHROME                                                 */
 379.158 +  /*    FT_LOAD_LINEAR_DESIGN                                              */
 379.159 +  /*    FT_LOAD_NO_SCALE                                                   */
 379.160 +  /*    FT_LOAD_NO_HINTING                                                 */
 379.161 +  /*    FT_LOAD_NO_BITMAP                                                  */
 379.162 +  /*    FT_LOAD_CROP_BITMAP                                                */
 379.163 +  /*                                                                       */
 379.164 +  /*    FT_LOAD_VERTICAL_LAYOUT                                            */
 379.165 +  /*    FT_LOAD_IGNORE_TRANSFORM                                           */
 379.166 +  /*    FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH                                */
 379.167 +  /*    FT_LOAD_FORCE_AUTOHINT                                             */
 379.168 +  /*    FT_LOAD_NO_RECURSE                                                 */
 379.169 +  /*    FT_LOAD_PEDANTIC                                                   */
 379.170 +  /*                                                                       */
 379.171 +  /*    FT_LOAD_TARGET_NORMAL                                              */
 379.172 +  /*    FT_LOAD_TARGET_LIGHT                                               */
 379.173 +  /*    FT_LOAD_TARGET_MONO                                                */
 379.174 +  /*    FT_LOAD_TARGET_LCD                                                 */
 379.175 +  /*    FT_LOAD_TARGET_LCD_V                                               */
 379.176 +  /*                                                                       */
 379.177 +  /*    FT_Render_Glyph                                                    */
 379.178 +  /*    FT_Render_Mode                                                     */
 379.179 +  /*    FT_Get_Kerning                                                     */
 379.180 +  /*    FT_Kerning_Mode                                                    */
 379.181 +  /*    FT_Get_Track_Kerning                                               */
 379.182 +  /*    FT_Get_Glyph_Name                                                  */
 379.183 +  /*    FT_Get_Postscript_Name                                             */
 379.184 +  /*                                                                       */
 379.185 +  /*    FT_CharMapRec                                                      */
 379.186 +  /*    FT_Select_Charmap                                                  */
 379.187 +  /*    FT_Set_Charmap                                                     */
 379.188 +  /*    FT_Get_Charmap_Index                                               */
 379.189 +  /*                                                                       */
 379.190 +  /*    FT_FSTYPE_INSTALLABLE_EMBEDDING                                    */
 379.191 +  /*    FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING                             */
 379.192 +  /*    FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING                              */
 379.193 +  /*    FT_FSTYPE_EDITABLE_EMBEDDING                                       */
 379.194 +  /*    FT_FSTYPE_NO_SUBSETTING                                            */
 379.195 +  /*    FT_FSTYPE_BITMAP_EMBEDDING_ONLY                                    */
 379.196 +  /*                                                                       */
 379.197 +  /*    FT_Get_FSType_Flags                                                */
 379.198 +  /*                                                                       */
 379.199 +  /*************************************************************************/
 379.200 +
 379.201 +
 379.202 +  /*************************************************************************/
 379.203 +  /*                                                                       */
 379.204 +  /* <Struct>                                                              */
 379.205 +  /*    FT_Glyph_Metrics                                                   */
 379.206 +  /*                                                                       */
 379.207 +  /* <Description>                                                         */
 379.208 +  /*    A structure used to model the metrics of a single glyph.  The      */
 379.209 +  /*    values are expressed in 26.6 fractional pixel format; if the flag  */
 379.210 +  /*    @FT_LOAD_NO_SCALE has been used while loading the glyph, values    */
 379.211 +  /*    are expressed in font units instead.                               */
 379.212 +  /*                                                                       */
 379.213 +  /* <Fields>                                                              */
 379.214 +  /*    width ::                                                           */
 379.215 +  /*      The glyph's width.                                               */
 379.216 +  /*                                                                       */
 379.217 +  /*    height ::                                                          */
 379.218 +  /*      The glyph's height.                                              */
 379.219 +  /*                                                                       */
 379.220 +  /*    horiBearingX ::                                                    */
 379.221 +  /*      Left side bearing for horizontal layout.                         */
 379.222 +  /*                                                                       */
 379.223 +  /*    horiBearingY ::                                                    */
 379.224 +  /*      Top side bearing for horizontal layout.                          */
 379.225 +  /*                                                                       */
 379.226 +  /*    horiAdvance ::                                                     */
 379.227 +  /*      Advance width for horizontal layout.                             */
 379.228 +  /*                                                                       */
 379.229 +  /*    vertBearingX ::                                                    */
 379.230 +  /*      Left side bearing for vertical layout.                           */
 379.231 +  /*                                                                       */
 379.232 +  /*    vertBearingY ::                                                    */
 379.233 +  /*      Top side bearing for vertical layout.                            */
 379.234 +  /*                                                                       */
 379.235 +  /*    vertAdvance ::                                                     */
 379.236 +  /*      Advance height for vertical layout.                              */
 379.237 +  /*                                                                       */
 379.238 +  /* <Note>                                                                */
 379.239 +  /*    If not disabled with @FT_LOAD_NO_HINTING, the values represent     */
 379.240 +  /*    dimensions of the hinted glyph (in case hinting is applicable).    */
 379.241 +  /*                                                                       */
 379.242 +  typedef struct  FT_Glyph_Metrics_
 379.243 +  {
 379.244 +    FT_Pos  width;
 379.245 +    FT_Pos  height;
 379.246 +
 379.247 +    FT_Pos  horiBearingX;
 379.248 +    FT_Pos  horiBearingY;
 379.249 +    FT_Pos  horiAdvance;
 379.250 +
 379.251 +    FT_Pos  vertBearingX;
 379.252 +    FT_Pos  vertBearingY;
 379.253 +    FT_Pos  vertAdvance;
 379.254 +
 379.255 +  } FT_Glyph_Metrics;
 379.256 +
 379.257 +
 379.258 +  /*************************************************************************/
 379.259 +  /*                                                                       */
 379.260 +  /* <Struct>                                                              */
 379.261 +  /*    FT_Bitmap_Size                                                     */
 379.262 +  /*                                                                       */
 379.263 +  /* <Description>                                                         */
 379.264 +  /*    This structure models the metrics of a bitmap strike (i.e., a set  */
 379.265 +  /*    of glyphs for a given point size and resolution) in a bitmap font. */
 379.266 +  /*    It is used for the `available_sizes' field of @FT_Face.            */
 379.267 +  /*                                                                       */
 379.268 +  /* <Fields>                                                              */
 379.269 +  /*    height :: The vertical distance, in pixels, between two            */
 379.270 +  /*              consecutive baselines.  It is always positive.           */
 379.271 +  /*                                                                       */
 379.272 +  /*    width  :: The average width, in pixels, of all glyphs in the       */
 379.273 +  /*              strike.                                                  */
 379.274 +  /*                                                                       */
 379.275 +  /*    size   :: The nominal size of the strike in 26.6 fractional        */
 379.276 +  /*              points.  This field is not very useful.                  */
 379.277 +  /*                                                                       */
 379.278 +  /*    x_ppem :: The horizontal ppem (nominal width) in 26.6 fractional   */
 379.279 +  /*              pixels.                                                  */
 379.280 +  /*                                                                       */
 379.281 +  /*    y_ppem :: The vertical ppem (nominal height) in 26.6 fractional    */
 379.282 +  /*              pixels.                                                  */
 379.283 +  /*                                                                       */
 379.284 +  /* <Note>                                                                */
 379.285 +  /*    Windows FNT:                                                       */
 379.286 +  /*      The nominal size given in a FNT font is not reliable.  Thus when */
 379.287 +  /*      the driver finds it incorrect, it sets `size' to some calculated */
 379.288 +  /*      values and sets `x_ppem' and `y_ppem' to the pixel width and     */
 379.289 +  /*      height given in the font, respectively.                          */
 379.290 +  /*                                                                       */
 379.291 +  /*    TrueType embedded bitmaps:                                         */
 379.292 +  /*      `size', `width', and `height' values are not contained in the    */
 379.293 +  /*      bitmap strike itself.  They are computed from the global font    */
 379.294 +  /*      parameters.                                                      */
 379.295 +  /*                                                                       */
 379.296 +  typedef struct  FT_Bitmap_Size_
 379.297 +  {
 379.298 +    FT_Short  height;
 379.299 +    FT_Short  width;
 379.300 +
 379.301 +    FT_Pos    size;
 379.302 +
 379.303 +    FT_Pos    x_ppem;
 379.304 +    FT_Pos    y_ppem;
 379.305 +
 379.306 +  } FT_Bitmap_Size;
 379.307 +
 379.308 +
 379.309 +  /*************************************************************************/
 379.310 +  /*************************************************************************/
 379.311 +  /*                                                                       */
 379.312 +  /*                     O B J E C T   C L A S S E S                       */
 379.313 +  /*                                                                       */
 379.314 +  /*************************************************************************/
 379.315 +  /*************************************************************************/
 379.316 +
 379.317 +  /*************************************************************************/
 379.318 +  /*                                                                       */
 379.319 +  /* <Type>                                                                */
 379.320 +  /*    FT_Library                                                         */
 379.321 +  /*                                                                       */
 379.322 +  /* <Description>                                                         */
 379.323 +  /*    A handle to a FreeType library instance.  Each `library' is        */
 379.324 +  /*    completely independent from the others; it is the `root' of a set  */
 379.325 +  /*    of objects like fonts, faces, sizes, etc.                          */
 379.326 +  /*                                                                       */
 379.327 +  /*    It also embeds a memory manager (see @FT_Memory), as well as a     */
 379.328 +  /*    scan-line converter object (see @FT_Raster).                       */
 379.329 +  /*                                                                       */
 379.330 +  /*    For multi-threading applications each thread should have its own   */
 379.331 +  /*    FT_Library object.                                                 */
 379.332 +  /*                                                                       */
 379.333 +  /* <Note>                                                                */
 379.334 +  /*    Library objects are normally created by @FT_Init_FreeType, and     */
 379.335 +  /*    destroyed with @FT_Done_FreeType.                                  */
 379.336 +  /*                                                                       */
 379.337 +  typedef struct FT_LibraryRec_  *FT_Library;
 379.338 +
 379.339 +
 379.340 +  /*************************************************************************/
 379.341 +  /*                                                                       */
 379.342 +  /* <Type>                                                                */
 379.343 +  /*    FT_Module                                                          */
 379.344 +  /*                                                                       */
 379.345 +  /* <Description>                                                         */
 379.346 +  /*    A handle to a given FreeType module object.  Each module can be a  */
 379.347 +  /*    font driver, a renderer, or anything else that provides services   */
 379.348 +  /*    to the formers.                                                    */
 379.349 +  /*                                                                       */
 379.350 +  typedef struct FT_ModuleRec_*  FT_Module;
 379.351 +
 379.352 +
 379.353 +  /*************************************************************************/
 379.354 +  /*                                                                       */
 379.355 +  /* <Type>                                                                */
 379.356 +  /*    FT_Driver                                                          */
 379.357 +  /*                                                                       */
 379.358 +  /* <Description>                                                         */
 379.359 +  /*    A handle to a given FreeType font driver object.  Each font driver */
 379.360 +  /*    is a special module capable of creating faces from font files.     */
 379.361 +  /*                                                                       */
 379.362 +  typedef struct FT_DriverRec_*  FT_Driver;
 379.363 +
 379.364 +
 379.365 +  /*************************************************************************/
 379.366 +  /*                                                                       */
 379.367 +  /* <Type>                                                                */
 379.368 +  /*    FT_Renderer                                                        */
 379.369 +  /*                                                                       */
 379.370 +  /* <Description>                                                         */
 379.371 +  /*    A handle to a given FreeType renderer.  A renderer is a special    */
 379.372 +  /*    module in charge of converting a glyph image to a bitmap, when     */
 379.373 +  /*    necessary.  Each renderer supports a given glyph image format, and */
 379.374 +  /*    one or more target surface depths.                                 */
 379.375 +  /*                                                                       */
 379.376 +  typedef struct FT_RendererRec_*  FT_Renderer;
 379.377 +
 379.378 +
 379.379 +  /*************************************************************************/
 379.380 +  /*                                                                       */
 379.381 +  /* <Type>                                                                */
 379.382 +  /*    FT_Face                                                            */
 379.383 +  /*                                                                       */
 379.384 +  /* <Description>                                                         */
 379.385 +  /*    A handle to a given typographic face object.  A face object models */
 379.386 +  /*    a given typeface, in a given style.                                */
 379.387 +  /*                                                                       */
 379.388 +  /* <Note>                                                                */
 379.389 +  /*    Each face object also owns a single @FT_GlyphSlot object, as well  */
 379.390 +  /*    as one or more @FT_Size objects.                                   */
 379.391 +  /*                                                                       */
 379.392 +  /*    Use @FT_New_Face or @FT_Open_Face to create a new face object from */
 379.393 +  /*    a given filepathname or a custom input stream.                     */
 379.394 +  /*                                                                       */
 379.395 +  /*    Use @FT_Done_Face to destroy it (along with its slot and sizes).   */
 379.396 +  /*                                                                       */
 379.397 +  /* <Also>                                                                */
 379.398 +  /*    See @FT_FaceRec for the publicly accessible fields of a given face */
 379.399 +  /*    object.                                                            */
 379.400 +  /*                                                                       */
 379.401 +  typedef struct FT_FaceRec_*  FT_Face;
 379.402 +
 379.403 +
 379.404 +  /*************************************************************************/
 379.405 +  /*                                                                       */
 379.406 +  /* <Type>                                                                */
 379.407 +  /*    FT_Size                                                            */
 379.408 +  /*                                                                       */
 379.409 +  /* <Description>                                                         */
 379.410 +  /*    A handle to an object used to model a face scaled to a given       */
 379.411 +  /*    character size.                                                    */
 379.412 +  /*                                                                       */
 379.413 +  /* <Note>                                                                */
 379.414 +  /*    Each @FT_Face has an _active_ @FT_Size object that is used by      */
 379.415 +  /*    functions like @FT_Load_Glyph to determine the scaling             */
 379.416 +  /*    transformation which is used to load and hint glyphs and metrics.  */
 379.417 +  /*                                                                       */
 379.418 +  /*    You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes,                */
 379.419 +  /*    @FT_Request_Size or even @FT_Select_Size to change the content     */
 379.420 +  /*    (i.e., the scaling values) of the active @FT_Size.                 */
 379.421 +  /*                                                                       */
 379.422 +  /*    You can use @FT_New_Size to create additional size objects for a   */
 379.423 +  /*    given @FT_Face, but they won't be used by other functions until    */
 379.424 +  /*    you activate it through @FT_Activate_Size.  Only one size can be   */
 379.425 +  /*    activated at any given time per face.                              */
 379.426 +  /*                                                                       */
 379.427 +  /* <Also>                                                                */
 379.428 +  /*    See @FT_SizeRec for the publicly accessible fields of a given size */
 379.429 +  /*    object.                                                            */
 379.430 +  /*                                                                       */
 379.431 +  typedef struct FT_SizeRec_*  FT_Size;
 379.432 +
 379.433 +
 379.434 +  /*************************************************************************/
 379.435 +  /*                                                                       */
 379.436 +  /* <Type>                                                                */
 379.437 +  /*    FT_GlyphSlot                                                       */
 379.438 +  /*                                                                       */
 379.439 +  /* <Description>                                                         */
 379.440 +  /*    A handle to a given `glyph slot'.  A slot is a container where it  */
 379.441 +  /*    is possible to load any of the glyphs contained in its parent      */
 379.442 +  /*    face.                                                              */
 379.443 +  /*                                                                       */
 379.444 +  /*    In other words, each time you call @FT_Load_Glyph or               */
 379.445 +  /*    @FT_Load_Char, the slot's content is erased by the new glyph data, */
 379.446 +  /*    i.e., the glyph's metrics, its image (bitmap or outline), and      */
 379.447 +  /*    other control information.                                         */
 379.448 +  /*                                                                       */
 379.449 +  /* <Also>                                                                */
 379.450 +  /*    See @FT_GlyphSlotRec for the publicly accessible glyph fields.     */
 379.451 +  /*                                                                       */
 379.452 +  typedef struct FT_GlyphSlotRec_*  FT_GlyphSlot;
 379.453 +
 379.454 +
 379.455 +  /*************************************************************************/
 379.456 +  /*                                                                       */
 379.457 +  /* <Type>                                                                */
 379.458 +  /*    FT_CharMap                                                         */
 379.459 +  /*                                                                       */
 379.460 +  /* <Description>                                                         */
 379.461 +  /*    A handle to a given character map.  A charmap is used to translate */
 379.462 +  /*    character codes in a given encoding into glyph indexes for its     */
 379.463 +  /*    parent's face.  Some font formats may provide several charmaps per */
 379.464 +  /*    font.                                                              */
 379.465 +  /*                                                                       */
 379.466 +  /*    Each face object owns zero or more charmaps, but only one of them  */
 379.467 +  /*    can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char.   */
 379.468 +  /*                                                                       */
 379.469 +  /*    The list of available charmaps in a face is available through the  */
 379.470 +  /*    `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec.   */
 379.471 +  /*                                                                       */
 379.472 +  /*    The currently active charmap is available as `face->charmap'.      */
 379.473 +  /*    You should call @FT_Set_Charmap to change it.                      */
 379.474 +  /*                                                                       */
 379.475 +  /* <Note>                                                                */
 379.476 +  /*    When a new face is created (either through @FT_New_Face or         */
 379.477 +  /*    @FT_Open_Face), the library looks for a Unicode charmap within     */
 379.478 +  /*    the list and automatically activates it.                           */
 379.479 +  /*                                                                       */
 379.480 +  /* <Also>                                                                */
 379.481 +  /*    See @FT_CharMapRec for the publicly accessible fields of a given   */
 379.482 +  /*    character map.                                                     */
 379.483 +  /*                                                                       */
 379.484 +  typedef struct FT_CharMapRec_*  FT_CharMap;
 379.485 +
 379.486 +
 379.487 +  /*************************************************************************/
 379.488 +  /*                                                                       */
 379.489 +  /* <Macro>                                                               */
 379.490 +  /*    FT_ENC_TAG                                                         */
 379.491 +  /*                                                                       */
 379.492 +  /* <Description>                                                         */
 379.493 +  /*    This macro converts four-letter tags into an unsigned long.  It is */
 379.494 +  /*    used to define `encoding' identifiers (see @FT_Encoding).          */
 379.495 +  /*                                                                       */
 379.496 +  /* <Note>                                                                */
 379.497 +  /*    Since many 16-bit compilers don't like 32-bit enumerations, you    */
 379.498 +  /*    should redefine this macro in case of problems to something like   */
 379.499 +  /*    this:                                                              */
 379.500 +  /*                                                                       */
 379.501 +  /*    {                                                                  */
 379.502 +  /*      #define FT_ENC_TAG( value, a, b, c, d )  value                   */
 379.503 +  /*    }                                                                  */
 379.504 +  /*                                                                       */
 379.505 +  /*    to get a simple enumeration without assigning special numbers.     */
 379.506 +  /*                                                                       */
 379.507 +
 379.508 +#ifndef FT_ENC_TAG
 379.509 +#define FT_ENC_TAG( value, a, b, c, d )         \
 379.510 +          value = ( ( (FT_UInt32)(a) << 24 ) |  \
 379.511 +                    ( (FT_UInt32)(b) << 16 ) |  \
 379.512 +                    ( (FT_UInt32)(c) <<  8 ) |  \
 379.513 +                      (FT_UInt32)(d)         )
 379.514 +
 379.515 +#endif /* FT_ENC_TAG */
 379.516 +
 379.517 +
 379.518 +  /*************************************************************************/
 379.519 +  /*                                                                       */
 379.520 +  /* <Enum>                                                                */
 379.521 +  /*    FT_Encoding                                                        */
 379.522 +  /*                                                                       */
 379.523 +  /* <Description>                                                         */
 379.524 +  /*    An enumeration used to specify character sets supported by         */
 379.525 +  /*    charmaps.  Used in the @FT_Select_Charmap API function.            */
 379.526 +  /*                                                                       */
 379.527 +  /* <Note>                                                                */
 379.528 +  /*    Despite the name, this enumeration lists specific character        */
 379.529 +  /*    repertories (i.e., charsets), and not text encoding methods (e.g., */
 379.530 +  /*    UTF-8, UTF-16, etc.).                                              */
 379.531 +  /*                                                                       */
 379.532 +  /*    Other encodings might be defined in the future.                    */
 379.533 +  /*                                                                       */
 379.534 +  /* <Values>                                                              */
 379.535 +  /*    FT_ENCODING_NONE ::                                                */
 379.536 +  /*      The encoding value~0 is reserved.                                */
 379.537 +  /*                                                                       */
 379.538 +  /*    FT_ENCODING_UNICODE ::                                             */
 379.539 +  /*      Corresponds to the Unicode character set.  This value covers     */
 379.540 +  /*      all versions of the Unicode repertoire, including ASCII and      */
 379.541 +  /*      Latin-1.  Most fonts include a Unicode charmap, but not all      */
 379.542 +  /*      of them.                                                         */
 379.543 +  /*                                                                       */
 379.544 +  /*      For example, if you want to access Unicode value U+1F028 (and    */
 379.545 +  /*      the font contains it), use value 0x1F028 as the input value for  */
 379.546 +  /*      @FT_Get_Char_Index.                                              */
 379.547 +  /*                                                                       */
 379.548 +  /*    FT_ENCODING_MS_SYMBOL ::                                           */
 379.549 +  /*      Corresponds to the Microsoft Symbol encoding, used to encode     */
 379.550 +  /*      mathematical symbols in the 32..255 character code range.  For   */
 379.551 +  /*      more information, see `http://www.ceviz.net/symbol.htm'.         */
 379.552 +  /*                                                                       */
 379.553 +  /*    FT_ENCODING_SJIS ::                                                */
 379.554 +  /*      Corresponds to Japanese SJIS encoding.  More info at             */
 379.555 +  /*      at `http://langsupport.japanreference.com/encoding.shtml'.       */
 379.556 +  /*      See note on multi-byte encodings below.                          */
 379.557 +  /*                                                                       */
 379.558 +  /*    FT_ENCODING_GB2312 ::                                              */
 379.559 +  /*      Corresponds to an encoding system for Simplified Chinese as used */
 379.560 +  /*      used in mainland China.                                          */
 379.561 +  /*                                                                       */
 379.562 +  /*    FT_ENCODING_BIG5 ::                                                */
 379.563 +  /*      Corresponds to an encoding system for Traditional Chinese as     */
 379.564 +  /*      used in Taiwan and Hong Kong.                                    */
 379.565 +  /*                                                                       */
 379.566 +  /*    FT_ENCODING_WANSUNG ::                                             */
 379.567 +  /*      Corresponds to the Korean encoding system known as Wansung.      */
 379.568 +  /*      For more information see                                         */
 379.569 +  /*      `http://www.microsoft.com/typography/unicode/949.txt'.           */
 379.570 +  /*                                                                       */
 379.571 +  /*    FT_ENCODING_JOHAB ::                                               */
 379.572 +  /*      The Korean standard character set (KS~C 5601-1992), which        */
 379.573 +  /*      corresponds to MS Windows code page 1361.  This character set    */
 379.574 +  /*      includes all possible Hangeul character combinations.            */
 379.575 +  /*                                                                       */
 379.576 +  /*    FT_ENCODING_ADOBE_LATIN_1 ::                                       */
 379.577 +  /*      Corresponds to a Latin-1 encoding as defined in a Type~1         */
 379.578 +  /*      PostScript font.  It is limited to 256 character codes.          */
 379.579 +  /*                                                                       */
 379.580 +  /*    FT_ENCODING_ADOBE_STANDARD ::                                      */
 379.581 +  /*      Corresponds to the Adobe Standard encoding, as found in Type~1,  */
 379.582 +  /*      CFF, and OpenType/CFF fonts.  It is limited to 256 character     */
 379.583 +  /*      codes.                                                           */
 379.584 +  /*                                                                       */
 379.585 +  /*    FT_ENCODING_ADOBE_EXPERT ::                                        */
 379.586 +  /*      Corresponds to the Adobe Expert encoding, as found in Type~1,    */
 379.587 +  /*      CFF, and OpenType/CFF fonts.  It is limited to 256 character     */
 379.588 +  /*      codes.                                                           */
 379.589 +  /*                                                                       */
 379.590 +  /*    FT_ENCODING_ADOBE_CUSTOM ::                                        */
 379.591 +  /*      Corresponds to a custom encoding, as found in Type~1, CFF, and   */
 379.592 +  /*      OpenType/CFF fonts.  It is limited to 256 character codes.       */
 379.593 +  /*                                                                       */
 379.594 +  /*    FT_ENCODING_APPLE_ROMAN ::                                         */
 379.595 +  /*      Corresponds to the 8-bit Apple roman encoding.  Many TrueType    */
 379.596 +  /*      and OpenType fonts contain a charmap for this encoding, since    */
 379.597 +  /*      older versions of Mac OS are able to use it.                     */
 379.598 +  /*                                                                       */
 379.599 +  /*    FT_ENCODING_OLD_LATIN_2 ::                                         */
 379.600 +  /*      This value is deprecated and was never used nor reported by      */
 379.601 +  /*      FreeType.  Don't use or test for it.                             */
 379.602 +  /*                                                                       */
 379.603 +  /*    FT_ENCODING_MS_SJIS ::                                             */
 379.604 +  /*      Same as FT_ENCODING_SJIS.  Deprecated.                           */
 379.605 +  /*                                                                       */
 379.606 +  /*    FT_ENCODING_MS_GB2312 ::                                           */
 379.607 +  /*      Same as FT_ENCODING_GB2312.  Deprecated.                         */
 379.608 +  /*                                                                       */
 379.609 +  /*    FT_ENCODING_MS_BIG5 ::                                             */
 379.610 +  /*      Same as FT_ENCODING_BIG5.  Deprecated.                           */
 379.611 +  /*                                                                       */
 379.612 +  /*    FT_ENCODING_MS_WANSUNG ::                                          */
 379.613 +  /*      Same as FT_ENCODING_WANSUNG.  Deprecated.                        */
 379.614 +  /*                                                                       */
 379.615 +  /*    FT_ENCODING_MS_JOHAB ::                                            */
 379.616 +  /*      Same as FT_ENCODING_JOHAB.  Deprecated.                          */
 379.617 +  /*                                                                       */
 379.618 +  /* <Note>                                                                */
 379.619 +  /*    By default, FreeType automatically synthesizes a Unicode charmap   */
 379.620 +  /*    for PostScript fonts, using their glyph names dictionaries.        */
 379.621 +  /*    However, it also reports the encodings defined explicitly in the   */
 379.622 +  /*    font file, for the cases when they are needed, with the Adobe      */
 379.623 +  /*    values as well.                                                    */
 379.624 +  /*                                                                       */
 379.625 +  /*    FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap  */
 379.626 +  /*    is neither Unicode nor ISO-8859-1 (otherwise it is set to          */
 379.627 +  /*    FT_ENCODING_UNICODE).  Use @FT_Get_BDF_Charset_ID to find out      */
 379.628 +  /*    which encoding is really present.  If, for example, the            */
 379.629 +  /*    `cs_registry' field is `KOI8' and the `cs_encoding' field is `R',  */
 379.630 +  /*    the font is encoded in KOI8-R.                                     */
 379.631 +  /*                                                                       */
 379.632 +  /*    FT_ENCODING_NONE is always set (with a single exception) by the    */
 379.633 +  /*    winfonts driver.  Use @FT_Get_WinFNT_Header and examine the        */
 379.634 +  /*    `charset' field of the @FT_WinFNT_HeaderRec structure to find out  */
 379.635 +  /*    which encoding is really present.  For example,                    */
 379.636 +  /*    @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for       */
 379.637 +  /*    Russian).                                                          */
 379.638 +  /*                                                                       */
 379.639 +  /*    FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */
 379.640 +  /*    and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to  */
 379.641 +  /*    FT_ENCODING_APPLE_ROMAN).                                          */
 379.642 +  /*                                                                       */
 379.643 +  /*    If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function       */
 379.644 +  /*    @FT_Get_CMap_Language_ID  to query the Mac language ID which may   */
 379.645 +  /*    be needed to be able to distinguish Apple encoding variants.  See  */
 379.646 +  /*                                                                       */
 379.647 +  /*      http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT  */
 379.648 +  /*                                                                       */
 379.649 +  /*    to get an idea how to do that.  Basically, if the language ID      */
 379.650 +  /*    is~0, don't use it, otherwise subtract 1 from the language ID.     */
 379.651 +  /*    Then examine `encoding_id'.  If, for example, `encoding_id' is     */
 379.652 +  /*    @TT_MAC_ID_ROMAN and the language ID (minus~1) is                  */
 379.653 +  /*    `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman.        */
 379.654 +  /*    @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi       */
 379.655 +  /*    variant the Arabic encoding.                                       */
 379.656 +  /*                                                                       */
 379.657 +  typedef enum  FT_Encoding_
 379.658 +  {
 379.659 +    FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ),
 379.660 +
 379.661 +    FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ),
 379.662 +    FT_ENC_TAG( FT_ENCODING_UNICODE,   'u', 'n', 'i', 'c' ),
 379.663 +
 379.664 +    FT_ENC_TAG( FT_ENCODING_SJIS,    's', 'j', 'i', 's' ),
 379.665 +    FT_ENC_TAG( FT_ENCODING_GB2312,  'g', 'b', ' ', ' ' ),
 379.666 +    FT_ENC_TAG( FT_ENCODING_BIG5,    'b', 'i', 'g', '5' ),
 379.667 +    FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ),
 379.668 +    FT_ENC_TAG( FT_ENCODING_JOHAB,   'j', 'o', 'h', 'a' ),
 379.669 +
 379.670 +    /* for backwards compatibility */
 379.671 +    FT_ENCODING_MS_SJIS    = FT_ENCODING_SJIS,
 379.672 +    FT_ENCODING_MS_GB2312  = FT_ENCODING_GB2312,
 379.673 +    FT_ENCODING_MS_BIG5    = FT_ENCODING_BIG5,
 379.674 +    FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG,
 379.675 +    FT_ENCODING_MS_JOHAB   = FT_ENCODING_JOHAB,
 379.676 +
 379.677 +    FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ),
 379.678 +    FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT,   'A', 'D', 'B', 'E' ),
 379.679 +    FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM,   'A', 'D', 'B', 'C' ),
 379.680 +    FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1,  'l', 'a', 't', '1' ),
 379.681 +
 379.682 +    FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ),
 379.683 +
 379.684 +    FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' )
 379.685 +
 379.686 +  } FT_Encoding;
 379.687 +
 379.688 +
 379.689 +  /*************************************************************************/
 379.690 +  /*                                                                       */
 379.691 +  /* <Enum>                                                                */
 379.692 +  /*    ft_encoding_xxx                                                    */
 379.693 +  /*                                                                       */
 379.694 +  /* <Description>                                                         */
 379.695 +  /*    These constants are deprecated; use the corresponding @FT_Encoding */
 379.696 +  /*    values instead.                                                    */
 379.697 +  /*                                                                       */
 379.698 +#define ft_encoding_none            FT_ENCODING_NONE
 379.699 +#define ft_encoding_unicode         FT_ENCODING_UNICODE
 379.700 +#define ft_encoding_symbol          FT_ENCODING_MS_SYMBOL
 379.701 +#define ft_encoding_latin_1         FT_ENCODING_ADOBE_LATIN_1
 379.702 +#define ft_encoding_latin_2         FT_ENCODING_OLD_LATIN_2
 379.703 +#define ft_encoding_sjis            FT_ENCODING_SJIS
 379.704 +#define ft_encoding_gb2312          FT_ENCODING_GB2312
 379.705 +#define ft_encoding_big5            FT_ENCODING_BIG5
 379.706 +#define ft_encoding_wansung         FT_ENCODING_WANSUNG
 379.707 +#define ft_encoding_johab           FT_ENCODING_JOHAB
 379.708 +
 379.709 +#define ft_encoding_adobe_standard  FT_ENCODING_ADOBE_STANDARD
 379.710 +#define ft_encoding_adobe_expert    FT_ENCODING_ADOBE_EXPERT
 379.711 +#define ft_encoding_adobe_custom    FT_ENCODING_ADOBE_CUSTOM
 379.712 +#define ft_encoding_apple_roman     FT_ENCODING_APPLE_ROMAN
 379.713 +
 379.714 +
 379.715 +  /*************************************************************************/
 379.716 +  /*                                                                       */
 379.717 +  /* <Struct>                                                              */
 379.718 +  /*    FT_CharMapRec                                                      */
 379.719 +  /*                                                                       */
 379.720 +  /* <Description>                                                         */
 379.721 +  /*    The base charmap structure.                                        */
 379.722 +  /*                                                                       */
 379.723 +  /* <Fields>                                                              */
 379.724 +  /*    face        :: A handle to the parent face object.                 */
 379.725 +  /*                                                                       */
 379.726 +  /*    encoding    :: An @FT_Encoding tag identifying the charmap.  Use   */
 379.727 +  /*                   this with @FT_Select_Charmap.                       */
 379.728 +  /*                                                                       */
 379.729 +  /*    platform_id :: An ID number describing the platform for the        */
 379.730 +  /*                   following encoding ID.  This comes directly from    */
 379.731 +  /*                   the TrueType specification and should be emulated   */
 379.732 +  /*                   for other formats.                                  */
 379.733 +  /*                                                                       */
 379.734 +  /*    encoding_id :: A platform specific encoding number.  This also     */
 379.735 +  /*                   comes from the TrueType specification and should be */
 379.736 +  /*                   emulated similarly.                                 */
 379.737 +  /*                                                                       */
 379.738 +  typedef struct  FT_CharMapRec_
 379.739 +  {
 379.740 +    FT_Face      face;
 379.741 +    FT_Encoding  encoding;
 379.742 +    FT_UShort    platform_id;
 379.743 +    FT_UShort    encoding_id;
 379.744 +
 379.745 +  } FT_CharMapRec;
 379.746 +
 379.747 +
 379.748 +  /*************************************************************************/
 379.749 +  /*************************************************************************/
 379.750 +  /*                                                                       */
 379.751 +  /*                 B A S E   O B J E C T   C L A S S E S                 */
 379.752 +  /*                                                                       */
 379.753 +  /*************************************************************************/
 379.754 +  /*************************************************************************/
 379.755 +
 379.756 +
 379.757 +  /*************************************************************************/
 379.758 +  /*                                                                       */
 379.759 +  /* <Type>                                                                */
 379.760 +  /*    FT_Face_Internal                                                   */
 379.761 +  /*                                                                       */
 379.762 +  /* <Description>                                                         */
 379.763 +  /*    An opaque handle to an `FT_Face_InternalRec' structure, used to    */
 379.764 +  /*    model private data of a given @FT_Face object.                     */
 379.765 +  /*                                                                       */
 379.766 +  /*    This structure might change between releases of FreeType~2 and is  */
 379.767 +  /*    not generally available to client applications.                    */
 379.768 +  /*                                                                       */
 379.769 +  typedef struct FT_Face_InternalRec_*  FT_Face_Internal;
 379.770 +
 379.771 +
 379.772 +  /*************************************************************************/
 379.773 +  /*                                                                       */
 379.774 +  /* <Struct>                                                              */
 379.775 +  /*    FT_FaceRec                                                         */
 379.776 +  /*                                                                       */
 379.777 +  /* <Description>                                                         */
 379.778 +  /*    FreeType root face class structure.  A face object models a        */
 379.779 +  /*    typeface in a font file.                                           */
 379.780 +  /*                                                                       */
 379.781 +  /* <Fields>                                                              */
 379.782 +  /*    num_faces           :: The number of faces in the font file.  Some */
 379.783 +  /*                           font formats can have multiple faces in     */
 379.784 +  /*                           a font file.                                */
 379.785 +  /*                                                                       */
 379.786 +  /*    face_index          :: The index of the face in the font file.  It */
 379.787 +  /*                           is set to~0 if there is only one face in    */
 379.788 +  /*                           the font file.                              */
 379.789 +  /*                                                                       */
 379.790 +  /*    face_flags          :: A set of bit flags that give important      */
 379.791 +  /*                           information about the face; see             */
 379.792 +  /*                           @FT_FACE_FLAG_XXX for the details.          */
 379.793 +  /*                                                                       */
 379.794 +  /*    style_flags         :: A set of bit flags indicating the style of  */
 379.795 +  /*                           the face; see @FT_STYLE_FLAG_XXX for the    */
 379.796 +  /*                           details.                                    */
 379.797 +  /*                                                                       */
 379.798 +  /*    num_glyphs          :: The number of glyphs in the face.  If the   */
 379.799 +  /*                           face is scalable and has sbits (see         */
 379.800 +  /*                           `num_fixed_sizes'), it is set to the number */
 379.801 +  /*                           of outline glyphs.                          */
 379.802 +  /*                                                                       */
 379.803 +  /*                           For CID-keyed fonts, this value gives the   */
 379.804 +  /*                           highest CID used in the font.               */
 379.805 +  /*                                                                       */
 379.806 +  /*    family_name         :: The face's family name.  This is an ASCII   */
 379.807 +  /*                           string, usually in English, which describes */
 379.808 +  /*                           the typeface's family (like `Times New      */
 379.809 +  /*                           Roman', `Bodoni', `Garamond', etc).  This   */
 379.810 +  /*                           is a least common denominator used to list  */
 379.811 +  /*                           fonts.  Some formats (TrueType & OpenType)  */
 379.812 +  /*                           provide localized and Unicode versions of   */
 379.813 +  /*                           this string.  Applications should use the   */
 379.814 +  /*                           format specific interface to access them.   */
 379.815 +  /*                           Can be NULL (e.g., in fonts embedded in a   */
 379.816 +  /*                           PDF file).                                  */
 379.817 +  /*                                                                       */
 379.818 +  /*    style_name          :: The face's style name.  This is an ASCII    */
 379.819 +  /*                           string, usually in English, which describes */
 379.820 +  /*                           the typeface's style (like `Italic',        */
 379.821 +  /*                           `Bold', `Condensed', etc).  Not all font    */
 379.822 +  /*                           formats provide a style name, so this field */
 379.823 +  /*                           is optional, and can be set to NULL.  As    */
 379.824 +  /*                           for `family_name', some formats provide     */
 379.825 +  /*                           localized and Unicode versions of this      */
 379.826 +  /*                           string.  Applications should use the format */
 379.827 +  /*                           specific interface to access them.          */
 379.828 +  /*                                                                       */
 379.829 +  /*    num_fixed_sizes     :: The number of bitmap strikes in the face.   */
 379.830 +  /*                           Even if the face is scalable, there might   */
 379.831 +  /*                           still be bitmap strikes, which are called   */
 379.832 +  /*                           `sbits' in that case.                       */
 379.833 +  /*                                                                       */
 379.834 +  /*    available_sizes     :: An array of @FT_Bitmap_Size for all bitmap  */
 379.835 +  /*                           strikes in the face.  It is set to NULL if  */
 379.836 +  /*                           there is no bitmap strike.                  */
 379.837 +  /*                                                                       */
 379.838 +  /*    num_charmaps        :: The number of charmaps in the face.         */
 379.839 +  /*                                                                       */
 379.840 +  /*    charmaps            :: An array of the charmaps of the face.       */
 379.841 +  /*                                                                       */
 379.842 +  /*    generic             :: A field reserved for client uses.  See the  */
 379.843 +  /*                           @FT_Generic type description.               */
 379.844 +  /*                                                                       */
 379.845 +  /*    bbox                :: The font bounding box.  Coordinates are     */
 379.846 +  /*                           expressed in font units (see                */
 379.847 +  /*                           `units_per_EM').  The box is large enough   */
 379.848 +  /*                           to contain any glyph from the font.  Thus,  */
 379.849 +  /*                           `bbox.yMax' can be seen as the `maximal     */
 379.850 +  /*                           ascender', and `bbox.yMin' as the `minimal  */
 379.851 +  /*                           descender'.  Only relevant for scalable     */
 379.852 +  /*                           formats.                                    */
 379.853 +  /*                                                                       */
 379.854 +  /*                           Note that the bounding box might be off by  */
 379.855 +  /*                           (at least) one pixel for hinted fonts.  See */
 379.856 +  /*                           @FT_Size_Metrics for further discussion.    */
 379.857 +  /*                                                                       */
 379.858 +  /*    units_per_EM        :: The number of font units per EM square for  */
 379.859 +  /*                           this face.  This is typically 2048 for      */
 379.860 +  /*                           TrueType fonts, and 1000 for Type~1 fonts.  */
 379.861 +  /*                           Only relevant for scalable formats.         */
 379.862 +  /*                                                                       */
 379.863 +  /*    ascender            :: The typographic ascender of the face,       */
 379.864 +  /*                           expressed in font units.  For font formats  */
 379.865 +  /*                           not having this information, it is set to   */
 379.866 +  /*                           `bbox.yMax'.  Only relevant for scalable    */
 379.867 +  /*                           formats.                                    */
 379.868 +  /*                                                                       */
 379.869 +  /*    descender           :: The typographic descender of the face,      */
 379.870 +  /*                           expressed in font units.  For font formats  */
 379.871 +  /*                           not having this information, it is set to   */
 379.872 +  /*                           `bbox.yMin'.  Note that this field is       */
 379.873 +  /*                           usually negative.  Only relevant for        */
 379.874 +  /*                           scalable formats.                           */
 379.875 +  /*                                                                       */
 379.876 +  /*    height              :: The height is the vertical distance         */
 379.877 +  /*                           between two consecutive baselines,          */
 379.878 +  /*                           expressed in font units.  It is always      */
 379.879 +  /*                           positive.  Only relevant for scalable       */
 379.880 +  /*                           formats.                                    */
 379.881 +  /*                                                                       */
 379.882 +  /*    max_advance_width   :: The maximal advance width, in font units,   */
 379.883 +  /*                           for all glyphs in this face.  This can be   */
 379.884 +  /*                           used to make word wrapping computations     */
 379.885 +  /*                           faster.  Only relevant for scalable         */
 379.886 +  /*                           formats.                                    */
 379.887 +  /*                                                                       */
 379.888 +  /*    max_advance_height  :: The maximal advance height, in font units,  */
 379.889 +  /*                           for all glyphs in this face.  This is only  */
 379.890 +  /*                           relevant for vertical layouts, and is set   */
 379.891 +  /*                           to `height' for fonts that do not provide   */
 379.892 +  /*                           vertical metrics.  Only relevant for        */
 379.893 +  /*                           scalable formats.                           */
 379.894 +  /*                                                                       */
 379.895 +  /*    underline_position  :: The position, in font units, of the         */
 379.896 +  /*                           underline line for this face.  It is the    */
 379.897 +  /*                           center of the underlining stem.  Only       */
 379.898 +  /*                           relevant for scalable formats.              */
 379.899 +  /*                                                                       */
 379.900 +  /*    underline_thickness :: The thickness, in font units, of the        */
 379.901 +  /*                           underline for this face.  Only relevant for */
 379.902 +  /*                           scalable formats.                           */
 379.903 +  /*                                                                       */
 379.904 +  /*    glyph               :: The face's associated glyph slot(s).        */
 379.905 +  /*                                                                       */
 379.906 +  /*    size                :: The current active size for this face.      */
 379.907 +  /*                                                                       */
 379.908 +  /*    charmap             :: The current active charmap for this face.   */
 379.909 +  /*                                                                       */
 379.910 +  /* <Note>                                                                */
 379.911 +  /*    Fields may be changed after a call to @FT_Attach_File or           */
 379.912 +  /*    @FT_Attach_Stream.                                                 */
 379.913 +  /*                                                                       */
 379.914 +  typedef struct  FT_FaceRec_
 379.915 +  {
 379.916 +    FT_Long           num_faces;
 379.917 +    FT_Long           face_index;
 379.918 +
 379.919 +    FT_Long           face_flags;
 379.920 +    FT_Long           style_flags;
 379.921 +
 379.922 +    FT_Long           num_glyphs;
 379.923 +
 379.924 +    FT_String*        family_name;
 379.925 +    FT_String*        style_name;
 379.926 +
 379.927 +    FT_Int            num_fixed_sizes;
 379.928 +    FT_Bitmap_Size*   available_sizes;
 379.929 +
 379.930 +    FT_Int            num_charmaps;
 379.931 +    FT_CharMap*       charmaps;
 379.932 +
 379.933 +    FT_Generic        generic;
 379.934 +
 379.935 +    /*# The following member variables (down to `underline_thickness') */
 379.936 +    /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size    */
 379.937 +    /*# for bitmap fonts.                                              */
 379.938 +    FT_BBox           bbox;
 379.939 +
 379.940 +    FT_UShort         units_per_EM;
 379.941 +    FT_Short          ascender;
 379.942 +    FT_Short          descender;
 379.943 +    FT_Short          height;
 379.944 +
 379.945 +    FT_Short          max_advance_width;
 379.946 +    FT_Short          max_advance_height;
 379.947 +
 379.948 +    FT_Short          underline_position;
 379.949 +    FT_Short          underline_thickness;
 379.950 +
 379.951 +    FT_GlyphSlot      glyph;
 379.952 +    FT_Size           size;
 379.953 +    FT_CharMap        charmap;
 379.954 +
 379.955 +    /*@private begin */
 379.956 +
 379.957 +    FT_Driver         driver;
 379.958 +    FT_Memory         memory;
 379.959 +    FT_Stream         stream;
 379.960 +
 379.961 +    FT_ListRec        sizes_list;
 379.962 +
 379.963 +    FT_Generic        autohint;
 379.964 +    void*             extensions;
 379.965 +
 379.966 +    FT_Face_Internal  internal;
 379.967 +
 379.968 +    /*@private end */
 379.969 +
 379.970 +  } FT_FaceRec;
 379.971 +
 379.972 +
 379.973 +  /*************************************************************************/
 379.974 +  /*                                                                       */
 379.975 +  /* <Enum>                                                                */
 379.976 +  /*    FT_FACE_FLAG_XXX                                                   */
 379.977 +  /*                                                                       */
 379.978 +  /* <Description>                                                         */
 379.979 +  /*    A list of bit flags used in the `face_flags' field of the          */
 379.980 +  /*    @FT_FaceRec structure.  They inform client applications of         */
 379.981 +  /*    properties of the corresponding face.                              */
 379.982 +  /*                                                                       */
 379.983 +  /* <Values>                                                              */
 379.984 +  /*    FT_FACE_FLAG_SCALABLE ::                                           */
 379.985 +  /*      Indicates that the face contains outline glyphs.  This doesn't   */
 379.986 +  /*      prevent bitmap strikes, i.e., a face can have both this and      */
 379.987 +  /*      and @FT_FACE_FLAG_FIXED_SIZES set.                               */
 379.988 +  /*                                                                       */
 379.989 +  /*    FT_FACE_FLAG_FIXED_SIZES ::                                        */
 379.990 +  /*      Indicates that the face contains bitmap strikes.  See also the   */
 379.991 +  /*      `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec.   */
 379.992 +  /*                                                                       */
 379.993 +  /*    FT_FACE_FLAG_FIXED_WIDTH ::                                        */
 379.994 +  /*      Indicates that the face contains fixed-width characters (like    */
 379.995 +  /*      Courier, Lucido, MonoType, etc.).                                */
 379.996 +  /*                                                                       */
 379.997 +  /*    FT_FACE_FLAG_SFNT ::                                               */
 379.998 +  /*      Indicates that the face uses the `sfnt' storage scheme.  For     */
 379.999 +  /*      now, this means TrueType and OpenType.                           */
379.1000 +  /*                                                                       */
379.1001 +  /*    FT_FACE_FLAG_HORIZONTAL ::                                         */
379.1002 +  /*      Indicates that the face contains horizontal glyph metrics.  This */
379.1003 +  /*      should be set for all common formats.                            */
379.1004 +  /*                                                                       */
379.1005 +  /*    FT_FACE_FLAG_VERTICAL ::                                           */
379.1006 +  /*      Indicates that the face contains vertical glyph metrics.  This   */
379.1007 +  /*      is only available in some formats, not all of them.              */
379.1008 +  /*                                                                       */
379.1009 +  /*    FT_FACE_FLAG_KERNING ::                                            */
379.1010 +  /*      Indicates that the face contains kerning information.  If set,   */
379.1011 +  /*      the kerning distance can be retrieved through the function       */
379.1012 +  /*      @FT_Get_Kerning.  Otherwise the function always return the       */
379.1013 +  /*      vector (0,0).  Note that FreeType doesn't handle kerning data    */
379.1014 +  /*      from the `GPOS' table (as present in some OpenType fonts).       */
379.1015 +  /*                                                                       */
379.1016 +  /*    FT_FACE_FLAG_FAST_GLYPHS ::                                        */
379.1017 +  /*      THIS FLAG IS DEPRECATED.  DO NOT USE OR TEST IT.                 */
379.1018 +  /*                                                                       */
379.1019 +  /*    FT_FACE_FLAG_MULTIPLE_MASTERS ::                                   */
379.1020 +  /*      Indicates that the font contains multiple masters and is capable */
379.1021 +  /*      of interpolating between them.  See the multiple-masters         */
379.1022 +  /*      specific API for details.                                        */
379.1023 +  /*                                                                       */
379.1024 +  /*    FT_FACE_FLAG_GLYPH_NAMES ::                                        */
379.1025 +  /*      Indicates that the font contains glyph names that can be         */
379.1026 +  /*      retrieved through @FT_Get_Glyph_Name.  Note that some TrueType   */
379.1027 +  /*      fonts contain broken glyph name tables.  Use the function        */
379.1028 +  /*      @FT_Has_PS_Glyph_Names when needed.                              */
379.1029 +  /*                                                                       */
379.1030 +  /*    FT_FACE_FLAG_EXTERNAL_STREAM ::                                    */
379.1031 +  /*      Used internally by FreeType to indicate that a face's stream was */
379.1032 +  /*      provided by the client application and should not be destroyed   */
379.1033 +  /*      when @FT_Done_Face is called.  Don't read or test this flag.     */
379.1034 +  /*                                                                       */
379.1035 +  /*    FT_FACE_FLAG_HINTER ::                                             */
379.1036 +  /*      Set if the font driver has a hinting machine of its own.  For    */
379.1037 +  /*      example, with TrueType fonts, it makes sense to use data from    */
379.1038 +  /*      the SFNT `gasp' table only if the native TrueType hinting engine */
379.1039 +  /*      (with the bytecode interpreter) is available and active.         */
379.1040 +  /*                                                                       */
379.1041 +  /*    FT_FACE_FLAG_CID_KEYED ::                                          */
379.1042 +  /*      Set if the font is CID-keyed.  In that case, the font is not     */
379.1043 +  /*      accessed by glyph indices but by CID values.  For subsetted      */
379.1044 +  /*      CID-keyed fonts this has the consequence that not all index      */
379.1045 +  /*      values are a valid argument to FT_Load_Glyph.  Only the CID      */
379.1046 +  /*      values for which corresponding glyphs in the subsetted font      */
379.1047 +  /*      exist make FT_Load_Glyph return successfully; in all other cases */
379.1048 +  /*      you get an `FT_Err_Invalid_Argument' error.                      */
379.1049 +  /*                                                                       */
379.1050 +  /*      Note that CID-keyed fonts which are in an SFNT wrapper don't     */
379.1051 +  /*      have this flag set since the glyphs are accessed in the normal   */
379.1052 +  /*      way (using contiguous indices); the `CID-ness' isn't visible to  */
379.1053 +  /*      the application.                                                 */
379.1054 +  /*                                                                       */
379.1055 +  /*    FT_FACE_FLAG_TRICKY ::                                             */
379.1056 +  /*      Set if the font is `tricky', this is, it always needs the        */
379.1057 +  /*      font format's native hinting engine to get a reasonable result.  */
379.1058 +  /*      A typical example is the Chinese font `mingli.ttf' which uses    */
379.1059 +  /*      TrueType bytecode instructions to move and scale all of its      */
379.1060 +  /*      subglyphs.                                                       */
379.1061 +  /*                                                                       */
379.1062 +  /*      It is not possible to autohint such fonts using                  */
379.1063 +  /*      @FT_LOAD_FORCE_AUTOHINT; it will also ignore                     */
379.1064 +  /*      @FT_LOAD_NO_HINTING.  You have to set both FT_LOAD_NO_HINTING    */
379.1065 +  /*      and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */
379.1066 +  /*      probably never want this except for demonstration purposes.      */
379.1067 +  /*                                                                       */
379.1068 +  /*      Currently, there are six TrueType fonts in the list of tricky    */
379.1069 +  /*      fonts; they are hard-coded in file `ttobjs.c'.                   */
379.1070 +  /*                                                                       */
379.1071 +#define FT_FACE_FLAG_SCALABLE          ( 1L <<  0 )
379.1072 +#define FT_FACE_FLAG_FIXED_SIZES       ( 1L <<  1 )
379.1073 +#define FT_FACE_FLAG_FIXED_WIDTH       ( 1L <<  2 )
379.1074 +#define FT_FACE_FLAG_SFNT              ( 1L <<  3 )
379.1075 +#define FT_FACE_FLAG_HORIZONTAL        ( 1L <<  4 )
379.1076 +#define FT_FACE_FLAG_VERTICAL          ( 1L <<  5 )
379.1077 +#define FT_FACE_FLAG_KERNING           ( 1L <<  6 )
379.1078 +#define FT_FACE_FLAG_FAST_GLYPHS       ( 1L <<  7 )
379.1079 +#define FT_FACE_FLAG_MULTIPLE_MASTERS  ( 1L <<  8 )
379.1080 +#define FT_FACE_FLAG_GLYPH_NAMES       ( 1L <<  9 )
379.1081 +#define FT_FACE_FLAG_EXTERNAL_STREAM   ( 1L << 10 )
379.1082 +#define FT_FACE_FLAG_HINTER            ( 1L << 11 )
379.1083 +#define FT_FACE_FLAG_CID_KEYED         ( 1L << 12 )
379.1084 +#define FT_FACE_FLAG_TRICKY            ( 1L << 13 )
379.1085 +
379.1086 +
379.1087 +  /*************************************************************************
379.1088 +   *
379.1089 +   * @macro:
379.1090 +   *   FT_HAS_HORIZONTAL( face )
379.1091 +   *
379.1092 +   * @description:
379.1093 +   *   A macro that returns true whenever a face object contains
379.1094 +   *   horizontal metrics (this is true for all font formats though).
379.1095 +   *
379.1096 +   * @also:
379.1097 +   *   @FT_HAS_VERTICAL can be used to check for vertical metrics.
379.1098 +   *
379.1099 +   */
379.1100 +#define FT_HAS_HORIZONTAL( face ) \
379.1101 +          ( face->face_flags & FT_FACE_FLAG_HORIZONTAL )
379.1102 +
379.1103 +
379.1104 +  /*************************************************************************
379.1105 +   *
379.1106 +   * @macro:
379.1107 +   *   FT_HAS_VERTICAL( face )
379.1108 +   *
379.1109 +   * @description:
379.1110 +   *   A macro that returns true whenever a face object contains vertical
379.1111 +   *   metrics.
379.1112 +   *
379.1113 +   */
379.1114 +#define FT_HAS_VERTICAL( face ) \
379.1115 +          ( face->face_flags & FT_FACE_FLAG_VERTICAL )
379.1116 +
379.1117 +
379.1118 +  /*************************************************************************
379.1119 +   *
379.1120 +   * @macro:
379.1121 +   *   FT_HAS_KERNING( face )
379.1122 +   *
379.1123 +   * @description:
379.1124 +   *   A macro that returns true whenever a face object contains kerning
379.1125 +   *   data that can be accessed with @FT_Get_Kerning.
379.1126 +   *
379.1127 +   */
379.1128 +#define FT_HAS_KERNING( face ) \
379.1129 +          ( face->face_flags & FT_FACE_FLAG_KERNING )
379.1130 +
379.1131 +
379.1132 +  /*************************************************************************
379.1133 +   *
379.1134 +   * @macro:
379.1135 +   *   FT_IS_SCALABLE( face )
379.1136 +   *
379.1137 +   * @description:
379.1138 +   *   A macro that returns true whenever a face object contains a scalable
379.1139 +   *   font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF,
379.1140 +   *   and PFR font formats.
379.1141 +   *
379.1142 +   */
379.1143 +#define FT_IS_SCALABLE( face ) \
379.1144 +          ( face->face_flags & FT_FACE_FLAG_SCALABLE )
379.1145 +
379.1146 +
379.1147 +  /*************************************************************************
379.1148 +   *
379.1149 +   * @macro:
379.1150 +   *   FT_IS_SFNT( face )
379.1151 +   *
379.1152 +   * @description:
379.1153 +   *   A macro that returns true whenever a face object contains a font
379.1154 +   *   whose format is based on the SFNT storage scheme.  This usually
379.1155 +   *   means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded
379.1156 +   *   bitmap fonts.
379.1157 +   *
379.1158 +   *   If this macro is true, all functions defined in @FT_SFNT_NAMES_H and
379.1159 +   *   @FT_TRUETYPE_TABLES_H are available.
379.1160 +   *
379.1161 +   */
379.1162 +#define FT_IS_SFNT( face ) \
379.1163 +          ( face->face_flags & FT_FACE_FLAG_SFNT )
379.1164 +
379.1165 +
379.1166 +  /*************************************************************************
379.1167 +   *
379.1168 +   * @macro:
379.1169 +   *   FT_IS_FIXED_WIDTH( face )
379.1170 +   *
379.1171 +   * @description:
379.1172 +   *   A macro that returns true whenever a face object contains a font face
379.1173 +   *   that contains fixed-width (or `monospace', `fixed-pitch', etc.)
379.1174 +   *   glyphs.
379.1175 +   *
379.1176 +   */
379.1177 +#define FT_IS_FIXED_WIDTH( face ) \
379.1178 +          ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH )
379.1179 +
379.1180 +
379.1181 +  /*************************************************************************
379.1182 +   *
379.1183 +   * @macro:
379.1184 +   *   FT_HAS_FIXED_SIZES( face )
379.1185 +   *
379.1186 +   * @description:
379.1187 +   *   A macro that returns true whenever a face object contains some
379.1188 +   *   embedded bitmaps.  See the `available_sizes' field of the
379.1189 +   *   @FT_FaceRec structure.
379.1190 +   *
379.1191 +   */
379.1192 +#define FT_HAS_FIXED_SIZES( face ) \
379.1193 +          ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
379.1194 +
379.1195 +
379.1196 +  /*************************************************************************
379.1197 +   *
379.1198 +   * @macro:
379.1199 +   *   FT_HAS_FAST_GLYPHS( face )
379.1200 +   *
379.1201 +   * @description:
379.1202 +   *   Deprecated.
379.1203 +   *
379.1204 +   */
379.1205 +#define FT_HAS_FAST_GLYPHS( face )  0
379.1206 +
379.1207 +
379.1208 +  /*************************************************************************
379.1209 +   *
379.1210 +   * @macro:
379.1211 +   *   FT_HAS_GLYPH_NAMES( face )
379.1212 +   *
379.1213 +   * @description:
379.1214 +   *   A macro that returns true whenever a face object contains some glyph
379.1215 +   *   names that can be accessed through @FT_Get_Glyph_Name.
379.1216 +   *
379.1217 +   */
379.1218 +#define FT_HAS_GLYPH_NAMES( face ) \
379.1219 +          ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
379.1220 +
379.1221 +
379.1222 +  /*************************************************************************
379.1223 +   *
379.1224 +   * @macro:
379.1225 +   *   FT_HAS_MULTIPLE_MASTERS( face )
379.1226 +   *
379.1227 +   * @description:
379.1228 +   *   A macro that returns true whenever a face object contains some
379.1229 +   *   multiple masters.  The functions provided by @FT_MULTIPLE_MASTERS_H
379.1230 +   *   are then available to choose the exact design you want.
379.1231 +   *
379.1232 +   */
379.1233 +#define FT_HAS_MULTIPLE_MASTERS( face ) \
379.1234 +          ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )
379.1235 +
379.1236 +
379.1237 +  /*************************************************************************
379.1238 +   *
379.1239 +   * @macro:
379.1240 +   *   FT_IS_CID_KEYED( face )
379.1241 +   *
379.1242 +   * @description:
379.1243 +   *   A macro that returns true whenever a face object contains a CID-keyed
379.1244 +   *   font.  See the discussion of @FT_FACE_FLAG_CID_KEYED for more
379.1245 +   *   details.
379.1246 +   *
379.1247 +   *   If this macro is true, all functions defined in @FT_CID_H are
379.1248 +   *   available.
379.1249 +   *
379.1250 +   */
379.1251 +#define FT_IS_CID_KEYED( face ) \
379.1252 +          ( face->face_flags & FT_FACE_FLAG_CID_KEYED )
379.1253 +
379.1254 +
379.1255 +  /*************************************************************************
379.1256 +   *
379.1257 +   * @macro:
379.1258 +   *   FT_IS_TRICKY( face )
379.1259 +   *
379.1260 +   * @description:
379.1261 +   *   A macro that returns true whenever a face represents a `tricky' font.
379.1262 +   *   See the discussion of @FT_FACE_FLAG_TRICKY for more details.
379.1263 +   *
379.1264 +   */
379.1265 +#define FT_IS_TRICKY( face ) \
379.1266 +          ( face->face_flags & FT_FACE_FLAG_TRICKY )
379.1267 +
379.1268 +
379.1269 +  /*************************************************************************/
379.1270 +  /*                                                                       */
379.1271 +  /* <Const>                                                               */
379.1272 +  /*    FT_STYLE_FLAG_XXX                                                  */
379.1273 +  /*                                                                       */
379.1274 +  /* <Description>                                                         */
379.1275 +  /*    A list of bit-flags used to indicate the style of a given face.    */
379.1276 +  /*    These are used in the `style_flags' field of @FT_FaceRec.          */
379.1277 +  /*                                                                       */
379.1278 +  /* <Values>                                                              */
379.1279 +  /*    FT_STYLE_FLAG_ITALIC ::                                            */
379.1280 +  /*      Indicates that a given face style is italic or oblique.          */
379.1281 +  /*                                                                       */
379.1282 +  /*    FT_STYLE_FLAG_BOLD ::                                              */
379.1283 +  /*      Indicates that a given face is bold.                             */
379.1284 +  /*                                                                       */
379.1285 +  /* <Note>                                                                */
379.1286 +  /*    The style information as provided by FreeType is very basic.  More */
379.1287 +  /*    details are beyond the scope and should be done on a higher level  */
379.1288 +  /*    (for example, by analyzing various fields of the `OS/2' table in   */
379.1289 +  /*    SFNT based fonts).                                                 */
379.1290 +  /*                                                                       */
379.1291 +#define FT_STYLE_FLAG_ITALIC  ( 1 << 0 )
379.1292 +#define FT_STYLE_FLAG_BOLD    ( 1 << 1 )
379.1293 +
379.1294 +
379.1295 +  /*************************************************************************/
379.1296 +  /*                                                                       */
379.1297 +  /* <Type>                                                                */
379.1298 +  /*    FT_Size_Internal                                                   */
379.1299 +  /*                                                                       */
379.1300 +  /* <Description>                                                         */
379.1301 +  /*    An opaque handle to an `FT_Size_InternalRec' structure, used to    */
379.1302 +  /*    model private data of a given @FT_Size object.                     */
379.1303 +  /*                                                                       */
379.1304 +  typedef struct FT_Size_InternalRec_*  FT_Size_Internal;
379.1305 +
379.1306 +
379.1307 +  /*************************************************************************/
379.1308 +  /*                                                                       */
379.1309 +  /* <Struct>                                                              */
379.1310 +  /*    FT_Size_Metrics                                                    */
379.1311 +  /*                                                                       */
379.1312 +  /* <Description>                                                         */
379.1313 +  /*    The size metrics structure gives the metrics of a size object.     */
379.1314 +  /*                                                                       */
379.1315 +  /* <Fields>                                                              */
379.1316 +  /*    x_ppem       :: The width of the scaled EM square in pixels, hence */
379.1317 +  /*                    the term `ppem' (pixels per EM).  It is also       */
379.1318 +  /*                    referred to as `nominal width'.                    */
379.1319 +  /*                                                                       */
379.1320 +  /*    y_ppem       :: The height of the scaled EM square in pixels,      */
379.1321 +  /*                    hence the term `ppem' (pixels per EM).  It is also */
379.1322 +  /*                    referred to as `nominal height'.                   */
379.1323 +  /*                                                                       */
379.1324 +  /*    x_scale      :: A 16.16 fractional scaling value used to convert   */
379.1325 +  /*                    horizontal metrics from font units to 26.6         */
379.1326 +  /*                    fractional pixels.  Only relevant for scalable     */
379.1327 +  /*                    font formats.                                      */
379.1328 +  /*                                                                       */
379.1329 +  /*    y_scale      :: A 16.16 fractional scaling value used to convert   */
379.1330 +  /*                    vertical metrics from font units to 26.6           */
379.1331 +  /*                    fractional pixels.  Only relevant for scalable     */
379.1332 +  /*                    font formats.                                      */
379.1333 +  /*                                                                       */
379.1334 +  /*    ascender     :: The ascender in 26.6 fractional pixels.  See       */
379.1335 +  /*                    @FT_FaceRec for the details.                       */
379.1336 +  /*                                                                       */
379.1337 +  /*    descender    :: The descender in 26.6 fractional pixels.  See      */
379.1338 +  /*                    @FT_FaceRec for the details.                       */
379.1339 +  /*                                                                       */
379.1340 +  /*    height       :: The height in 26.6 fractional pixels.  See         */
379.1341 +  /*                    @FT_FaceRec for the details.                       */
379.1342 +  /*                                                                       */
379.1343 +  /*    max_advance  :: The maximal advance width in 26.6 fractional       */
379.1344 +  /*                    pixels.  See @FT_FaceRec for the details.          */
379.1345 +  /*                                                                       */
379.1346 +  /* <Note>                                                                */
379.1347 +  /*    The scaling values, if relevant, are determined first during a     */
379.1348 +  /*    size changing operation.  The remaining fields are then set by the */
379.1349 +  /*    driver.  For scalable formats, they are usually set to scaled      */
379.1350 +  /*    values of the corresponding fields in @FT_FaceRec.                 */
379.1351 +  /*                                                                       */
379.1352 +  /*    Note that due to glyph hinting, these values might not be exact    */
379.1353 +  /*    for certain fonts.  Thus they must be treated as unreliable        */
379.1354 +  /*    with an error margin of at least one pixel!                        */
379.1355 +  /*                                                                       */
379.1356 +  /*    Indeed, the only way to get the exact metrics is to render _all_   */
379.1357 +  /*    glyphs.  As this would be a definite performance hit, it is up to  */
379.1358 +  /*    client applications to perform such computations.                  */
379.1359 +  /*                                                                       */
379.1360 +  /*    The FT_Size_Metrics structure is valid for bitmap fonts also.      */
379.1361 +  /*                                                                       */
379.1362 +  typedef struct  FT_Size_Metrics_
379.1363 +  {
379.1364 +    FT_UShort  x_ppem;      /* horizontal pixels per EM               */
379.1365 +    FT_UShort  y_ppem;      /* vertical pixels per EM                 */
379.1366 +
379.1367 +    FT_Fixed   x_scale;     /* scaling values used to convert font    */
379.1368 +    FT_Fixed   y_scale;     /* units to 26.6 fractional pixels        */
379.1369 +
379.1370 +    FT_Pos     ascender;    /* ascender in 26.6 frac. pixels          */
379.1371 +    FT_Pos     descender;   /* descender in 26.6 frac. pixels         */
379.1372 +    FT_Pos     height;      /* text height in 26.6 frac. pixels       */
379.1373 +    FT_Pos     max_advance; /* max horizontal advance, in 26.6 pixels */
379.1374 +
379.1375 +  } FT_Size_Metrics;
379.1376 +
379.1377 +
379.1378 +  /*************************************************************************/
379.1379 +  /*                                                                       */
379.1380 +  /* <Struct>                                                              */
379.1381 +  /*    FT_SizeRec                                                         */
379.1382 +  /*                                                                       */
379.1383 +  /* <Description>                                                         */
379.1384 +  /*    FreeType root size class structure.  A size object models a face   */
379.1385 +  /*    object at a given size.                                            */
379.1386 +  /*                                                                       */
379.1387 +  /* <Fields>                                                              */
379.1388 +  /*    face    :: Handle to the parent face object.                       */
379.1389 +  /*                                                                       */
379.1390 +  /*    generic :: A typeless pointer, which is unused by the FreeType     */
379.1391 +  /*               library or any of its drivers.  It can be used by       */
379.1392 +  /*               client applications to link their own data to each size */
379.1393 +  /*               object.                                                 */
379.1394 +  /*                                                                       */
379.1395 +  /*    metrics :: Metrics for this size object.  This field is read-only. */
379.1396 +  /*                                                                       */
379.1397 +  typedef struct  FT_SizeRec_
379.1398 +  {
379.1399 +    FT_Face           face;      /* parent face object              */
379.1400 +    FT_Generic        generic;   /* generic pointer for client uses */
379.1401 +    FT_Size_Metrics   metrics;   /* size metrics                    */
379.1402 +    FT_Size_Internal  internal;
379.1403 +
379.1404 +  } FT_SizeRec;
379.1405 +
379.1406 +
379.1407 +  /*************************************************************************/
379.1408 +  /*                                                                       */
379.1409 +  /* <Struct>                                                              */
379.1410 +  /*    FT_SubGlyph                                                        */
379.1411 +  /*                                                                       */
379.1412 +  /* <Description>                                                         */
379.1413 +  /*    The subglyph structure is an internal object used to describe      */
379.1414 +  /*    subglyphs (for example, in the case of composites).                */
379.1415 +  /*                                                                       */
379.1416 +  /* <Note>                                                                */
379.1417 +  /*    The subglyph implementation is not part of the high-level API,     */
379.1418 +  /*    hence the forward structure declaration.                           */
379.1419 +  /*                                                                       */
379.1420 +  /*    You can however retrieve subglyph information with                 */
379.1421 +  /*    @FT_Get_SubGlyph_Info.                                             */
379.1422 +  /*                                                                       */
379.1423 +  typedef struct FT_SubGlyphRec_*  FT_SubGlyph;
379.1424 +
379.1425 +
379.1426 +  /*************************************************************************/
379.1427 +  /*                                                                       */
379.1428 +  /* <Type>                                                                */
379.1429 +  /*    FT_Slot_Internal                                                   */
379.1430 +  /*                                                                       */
379.1431 +  /* <Description>                                                         */
379.1432 +  /*    An opaque handle to an `FT_Slot_InternalRec' structure, used to    */
379.1433 +  /*    model private data of a given @FT_GlyphSlot object.                */
379.1434 +  /*                                                                       */
379.1435 +  typedef struct FT_Slot_InternalRec_*  FT_Slot_Internal;
379.1436 +
379.1437 +
379.1438 +  /*************************************************************************/
379.1439 +  /*                                                                       */
379.1440 +  /* <Struct>                                                              */
379.1441 +  /*    FT_GlyphSlotRec                                                    */
379.1442 +  /*                                                                       */
379.1443 +  /* <Description>                                                         */
379.1444 +  /*    FreeType root glyph slot class structure.  A glyph slot is a       */
379.1445 +  /*    container where individual glyphs can be loaded, be they in        */
379.1446 +  /*    outline or bitmap format.                                          */
379.1447 +  /*                                                                       */
379.1448 +  /* <Fields>                                                              */
379.1449 +  /*    library           :: A handle to the FreeType library instance     */
379.1450 +  /*                         this slot belongs to.                         */
379.1451 +  /*                                                                       */
379.1452 +  /*    face              :: A handle to the parent face object.           */
379.1453 +  /*                                                                       */
379.1454 +  /*    next              :: In some cases (like some font tools), several */
379.1455 +  /*                         glyph slots per face object can be a good     */
379.1456 +  /*                         thing.  As this is rare, the glyph slots are  */
379.1457 +  /*                         listed through a direct, single-linked list   */
379.1458 +  /*                         using its `next' field.                       */
379.1459 +  /*                                                                       */
379.1460 +  /*    generic           :: A typeless pointer which is unused by the     */
379.1461 +  /*                         FreeType library or any of its drivers.  It   */
379.1462 +  /*                         can be used by client applications to link    */
379.1463 +  /*                         their own data to each glyph slot object.     */
379.1464 +  /*                                                                       */
379.1465 +  /*    metrics           :: The metrics of the last loaded glyph in the   */
379.1466 +  /*                         slot.  The returned values depend on the last */
379.1467 +  /*                         load flags (see the @FT_Load_Glyph API        */
379.1468 +  /*                         function) and can be expressed either in 26.6 */
379.1469 +  /*                         fractional pixels or font units.              */
379.1470 +  /*                                                                       */
379.1471 +  /*                         Note that even when the glyph image is        */
379.1472 +  /*                         transformed, the metrics are not.             */
379.1473 +  /*                                                                       */
379.1474 +  /*    linearHoriAdvance :: The advance width of the unhinted glyph.      */
379.1475 +  /*                         Its value is expressed in 16.16 fractional    */
379.1476 +  /*                         pixels, unless @FT_LOAD_LINEAR_DESIGN is set  */
379.1477 +  /*                         when loading the glyph.  This field can be    */
379.1478 +  /*                         important to perform correct WYSIWYG layout.  */
379.1479 +  /*                         Only relevant for outline glyphs.             */
379.1480 +  /*                                                                       */
379.1481 +  /*    linearVertAdvance :: The advance height of the unhinted glyph.     */
379.1482 +  /*                         Its value is expressed in 16.16 fractional    */
379.1483 +  /*                         pixels, unless @FT_LOAD_LINEAR_DESIGN is set  */
379.1484 +  /*                         when loading the glyph.  This field can be    */
379.1485 +  /*                         important to perform correct WYSIWYG layout.  */
379.1486 +  /*                         Only relevant for outline glyphs.             */
379.1487 +  /*                                                                       */
379.1488 +  /*    advance           :: This shorthand is, depending on               */
379.1489 +  /*                         @FT_LOAD_IGNORE_TRANSFORM, the transformed    */
379.1490 +  /*                         advance width for the glyph (in 26.6          */
379.1491 +  /*                         fractional pixel format).  As specified with  */
379.1492 +  /*                         @FT_LOAD_VERTICAL_LAYOUT, it uses either the  */
379.1493 +  /*                         `horiAdvance' or the `vertAdvance' value of   */
379.1494 +  /*                         `metrics' field.                              */
379.1495 +  /*                                                                       */
379.1496 +  /*    format            :: This field indicates the format of the image  */
379.1497 +  /*                         contained in the glyph slot.  Typically       */
379.1498 +  /*                         @FT_GLYPH_FORMAT_BITMAP,                      */
379.1499 +  /*                         @FT_GLYPH_FORMAT_OUTLINE, or                  */
379.1500 +  /*                         @FT_GLYPH_FORMAT_COMPOSITE, but others are    */
379.1501 +  /*                         possible.                                     */
379.1502 +  /*                                                                       */
379.1503 +  /*    bitmap            :: This field is used as a bitmap descriptor     */
379.1504 +  /*                         when the slot format is                       */
379.1505 +  /*                         @FT_GLYPH_FORMAT_BITMAP.  Note that the       */
379.1506 +  /*                         address and content of the bitmap buffer can  */
379.1507 +  /*                         change between calls of @FT_Load_Glyph and a  */
379.1508 +  /*                         few other functions.                          */
379.1509 +  /*                                                                       */
379.1510 +  /*    bitmap_left       :: This is the bitmap's left bearing expressed   */
379.1511 +  /*                         in integer pixels.  Of course, this is only   */
379.1512 +  /*                         valid if the format is                        */
379.1513 +  /*                         @FT_GLYPH_FORMAT_BITMAP.                      */
379.1514 +  /*                                                                       */
379.1515 +  /*    bitmap_top        :: This is the bitmap's top bearing expressed in */
379.1516 +  /*                         integer pixels.  Remember that this is the    */
379.1517 +  /*                         distance from the baseline to the top-most    */
379.1518 +  /*                         glyph scanline, upwards y~coordinates being   */
379.1519 +  /*                         *positive*.                                   */
379.1520 +  /*                                                                       */
379.1521 +  /*    outline           :: The outline descriptor for the current glyph  */
379.1522 +  /*                         image if its format is                        */
379.1523 +  /*                         @FT_GLYPH_FORMAT_OUTLINE.  Once a glyph is    */
379.1524 +  /*                         loaded, `outline' can be transformed,         */
379.1525 +  /*                         distorted, embolded, etc.  However, it must   */
379.1526 +  /*                         not be freed.                                 */
379.1527 +  /*                                                                       */
379.1528 +  /*    num_subglyphs     :: The number of subglyphs in a composite glyph. */
379.1529 +  /*                         This field is only valid for the composite    */
379.1530 +  /*                         glyph format that should normally only be     */
379.1531 +  /*                         loaded with the @FT_LOAD_NO_RECURSE flag.     */
379.1532 +  /*                         For now this is internal to FreeType.         */
379.1533 +  /*                                                                       */
379.1534 +  /*    subglyphs         :: An array of subglyph descriptors for          */
379.1535 +  /*                         composite glyphs.  There are `num_subglyphs'  */
379.1536 +  /*                         elements in there.  Currently internal to     */
379.1537 +  /*                         FreeType.                                     */
379.1538 +  /*                                                                       */
379.1539 +  /*    control_data      :: Certain font drivers can also return the      */
379.1540 +  /*                         control data for a given glyph image (e.g.    */
379.1541 +  /*                         TrueType bytecode, Type~1 charstrings, etc.). */
379.1542 +  /*                         This field is a pointer to such data.         */
379.1543 +  /*                                                                       */
379.1544 +  /*    control_len       :: This is the length in bytes of the control    */
379.1545 +  /*                         data.                                         */
379.1546 +  /*                                                                       */
379.1547 +  /*    other             :: Really wicked formats can use this pointer to */
379.1548 +  /*                         present their own glyph image to client       */
379.1549 +  /*                         applications.  Note that the application      */
379.1550 +  /*                         needs to know about the image format.         */
379.1551 +  /*                                                                       */
379.1552 +  /*    lsb_delta         :: The difference between hinted and unhinted    */
379.1553 +  /*                         left side bearing while autohinting is        */
379.1554 +  /*                         active.  Zero otherwise.                      */
379.1555 +  /*                                                                       */
379.1556 +  /*    rsb_delta         :: The difference between hinted and unhinted    */
379.1557 +  /*                         right side bearing while autohinting is       */
379.1558 +  /*                         active.  Zero otherwise.                      */
379.1559 +  /*                                                                       */
379.1560 +  /* <Note>                                                                */
379.1561 +  /*    If @FT_Load_Glyph is called with default flags (see                */
379.1562 +  /*    @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in   */
379.1563 +  /*    its native format (e.g., an outline glyph for TrueType and Type~1  */
379.1564 +  /*    formats).                                                          */
379.1565 +  /*                                                                       */
379.1566 +  /*    This image can later be converted into a bitmap by calling         */
379.1567 +  /*    @FT_Render_Glyph.  This function finds the current renderer for    */
379.1568 +  /*    the native image's format, then invokes it.                        */
379.1569 +  /*                                                                       */
379.1570 +  /*    The renderer is in charge of transforming the native image through */
379.1571 +  /*    the slot's face transformation fields, then converting it into a   */
379.1572 +  /*    bitmap that is returned in `slot->bitmap'.                         */
379.1573 +  /*                                                                       */
379.1574 +  /*    Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */
379.1575 +  /*    to specify the position of the bitmap relative to the current pen  */
379.1576 +  /*    position (e.g., coordinates (0,0) on the baseline).  Of course,    */
379.1577 +  /*    `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP.         */
379.1578 +  /*                                                                       */
379.1579 +  /* <Note>                                                                */
379.1580 +  /*    Here a small pseudo code fragment which shows how to use           */
379.1581 +  /*    `lsb_delta' and `rsb_delta':                                       */
379.1582 +  /*                                                                       */
379.1583 +  /*    {                                                                  */
379.1584 +  /*      FT_Pos  origin_x       = 0;                                      */
379.1585 +  /*      FT_Pos  prev_rsb_delta = 0;                                      */
379.1586 +  /*                                                                       */
379.1587 +  /*                                                                       */
379.1588 +  /*      for all glyphs do                                                */
379.1589 +  /*        <compute kern between current and previous glyph and add it to */
379.1590 +  /*         `origin_x'>                                                   */
379.1591 +  /*                                                                       */
379.1592 +  /*        <load glyph with `FT_Load_Glyph'>                              */
379.1593 +  /*                                                                       */
379.1594 +  /*        if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 )           */
379.1595 +  /*          origin_x -= 64;                                              */
379.1596 +  /*        else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 )      */
379.1597 +  /*          origin_x += 64;                                              */
379.1598 +  /*                                                                       */
379.1599 +  /*        prev_rsb_delta = face->glyph->rsb_delta;                       */
379.1600 +  /*                                                                       */
379.1601 +  /*        <save glyph image, or render glyph, or ...>                    */
379.1602 +  /*                                                                       */
379.1603 +  /*        origin_x += face->glyph->advance.x;                            */
379.1604 +  /*      endfor                                                           */
379.1605 +  /*    }                                                                  */
379.1606 +  /*                                                                       */
379.1607 +  typedef struct  FT_GlyphSlotRec_
379.1608 +  {
379.1609 +    FT_Library        library;
379.1610 +    FT_Face           face;
379.1611 +    FT_GlyphSlot      next;
379.1612 +    FT_UInt           reserved;       /* retained for binary compatibility */
379.1613 +    FT_Generic        generic;
379.1614 +
379.1615 +    FT_Glyph_Metrics  metrics;
379.1616 +    FT_Fixed          linearHoriAdvance;
379.1617 +    FT_Fixed          linearVertAdvance;
379.1618 +    FT_Vector         advance;
379.1619 +
379.1620 +    FT_Glyph_Format   format;
379.1621 +
379.1622 +    FT_Bitmap         bitmap;
379.1623 +    FT_Int            bitmap_left;
379.1624 +    FT_Int            bitmap_top;
379.1625 +
379.1626 +    FT_Outline        outline;
379.1627 +
379.1628 +    FT_UInt           num_subglyphs;
379.1629 +    FT_SubGlyph       subglyphs;
379.1630 +
379.1631 +    void*             control_data;
379.1632 +    long              control_len;
379.1633 +
379.1634 +    FT_Pos            lsb_delta;
379.1635 +    FT_Pos            rsb_delta;
379.1636 +
379.1637 +    void*             other;
379.1638 +
379.1639 +    FT_Slot_Internal  internal;
379.1640 +
379.1641 +  } FT_GlyphSlotRec;
379.1642 +
379.1643 +
379.1644 +  /*************************************************************************/
379.1645 +  /*************************************************************************/
379.1646 +  /*                                                                       */
379.1647 +  /*                         F U N C T I O N S                             */
379.1648 +  /*                                                                       */
379.1649 +  /*************************************************************************/
379.1650 +  /*************************************************************************/
379.1651 +
379.1652 +
379.1653 +  /*************************************************************************/
379.1654 +  /*                                                                       */
379.1655 +  /* <Function>                                                            */
379.1656 +  /*    FT_Init_FreeType                                                   */
379.1657 +  /*                                                                       */
379.1658 +  /* <Description>                                                         */
379.1659 +  /*    Initialize a new FreeType library object.  The set of modules      */
379.1660 +  /*    that are registered by this function is determined at build time.  */
379.1661 +  /*                                                                       */
379.1662 +  /* <Output>                                                              */
379.1663 +  /*    alibrary :: A handle to a new library object.                      */
379.1664 +  /*                                                                       */
379.1665 +  /* <Return>                                                              */
379.1666 +  /*    FreeType error code.  0~means success.                             */
379.1667 +  /*                                                                       */
379.1668 +  /* <Note>                                                                */
379.1669 +  /*    In case you want to provide your own memory allocating routines,   */
379.1670 +  /*    use @FT_New_Library instead, followed by a call to                 */
379.1671 +  /*    @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module).  */
379.1672 +  /*                                                                       */
379.1673 +  FT_EXPORT( FT_Error )
379.1674 +  FT_Init_FreeType( FT_Library  *alibrary );
379.1675 +
379.1676 +
379.1677 +  /*************************************************************************/
379.1678 +  /*                                                                       */
379.1679 +  /* <Function>                                                            */
379.1680 +  /*    FT_Done_FreeType                                                   */
379.1681 +  /*                                                                       */
379.1682 +  /* <Description>                                                         */
379.1683 +  /*    Destroy a given FreeType library object and all of its children,   */
379.1684 +  /*    including resources, drivers, faces, sizes, etc.                   */
379.1685 +  /*                                                                       */
379.1686 +  /* <Input>                                                               */
379.1687 +  /*    library :: A handle to the target library object.                  */
379.1688 +  /*                                                                       */
379.1689 +  /* <Return>                                                              */
379.1690 +  /*    FreeType error code.  0~means success.                             */
379.1691 +  /*                                                                       */
379.1692 +  FT_EXPORT( FT_Error )
379.1693 +  FT_Done_FreeType( FT_Library  library );
379.1694 +
379.1695 +
379.1696 +  /*************************************************************************/
379.1697 +  /*                                                                       */
379.1698 +  /* <Enum>                                                                */
379.1699 +  /*    FT_OPEN_XXX                                                        */
379.1700 +  /*                                                                       */
379.1701 +  /* <Description>                                                         */
379.1702 +  /*    A list of bit-field constants used within the `flags' field of the */
379.1703 +  /*    @FT_Open_Args structure.                                           */
379.1704 +  /*                                                                       */
379.1705 +  /* <Values>                                                              */
379.1706 +  /*    FT_OPEN_MEMORY   :: This is a memory-based stream.                 */
379.1707 +  /*                                                                       */
379.1708 +  /*    FT_OPEN_STREAM   :: Copy the stream from the `stream' field.       */
379.1709 +  /*                                                                       */
379.1710 +  /*    FT_OPEN_PATHNAME :: Create a new input stream from a C~path        */
379.1711 +  /*                        name.                                          */
379.1712 +  /*                                                                       */
379.1713 +  /*    FT_OPEN_DRIVER   :: Use the `driver' field.                        */
379.1714 +  /*                                                                       */
379.1715 +  /*    FT_OPEN_PARAMS   :: Use the `num_params' and `params' fields.      */
379.1716 +  /*                                                                       */
379.1717 +  /*    ft_open_memory   :: Deprecated; use @FT_OPEN_MEMORY instead.       */
379.1718 +  /*                                                                       */
379.1719 +  /*    ft_open_stream   :: Deprecated; use @FT_OPEN_STREAM instead.       */
379.1720 +  /*                                                                       */
379.1721 +  /*    ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead.     */
379.1722 +  /*                                                                       */
379.1723 +  /*    ft_open_driver   :: Deprecated; use @FT_OPEN_DRIVER instead.       */
379.1724 +  /*                                                                       */
379.1725 +  /*    ft_open_params   :: Deprecated; use @FT_OPEN_PARAMS instead.       */
379.1726 +  /*                                                                       */
379.1727 +  /* <Note>                                                                */
379.1728 +  /*    The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME'     */
379.1729 +  /*    flags are mutually exclusive.                                      */
379.1730 +  /*                                                                       */
379.1731 +#define FT_OPEN_MEMORY    0x1
379.1732 +#define FT_OPEN_STREAM    0x2
379.1733 +#define FT_OPEN_PATHNAME  0x4
379.1734 +#define FT_OPEN_DRIVER    0x8
379.1735 +#define FT_OPEN_PARAMS    0x10
379.1736 +
379.1737 +#define ft_open_memory    FT_OPEN_MEMORY     /* deprecated */
379.1738 +#define ft_open_stream    FT_OPEN_STREAM     /* deprecated */
379.1739 +#define ft_open_pathname  FT_OPEN_PATHNAME   /* deprecated */
379.1740 +#define ft_open_driver    FT_OPEN_DRIVER     /* deprecated */
379.1741 +#define ft_open_params    FT_OPEN_PARAMS     /* deprecated */
379.1742 +
379.1743 +
379.1744 +  /*************************************************************************/
379.1745 +  /*                                                                       */
379.1746 +  /* <Struct>                                                              */
379.1747 +  /*    FT_Parameter                                                       */
379.1748 +  /*                                                                       */
379.1749 +  /* <Description>                                                         */
379.1750 +  /*    A simple structure used to pass more or less generic parameters to */
379.1751 +  /*    @FT_Open_Face.                                                     */
379.1752 +  /*                                                                       */
379.1753 +  /* <Fields>                                                              */
379.1754 +  /*    tag  :: A four-byte identification tag.                            */
379.1755 +  /*                                                                       */
379.1756 +  /*    data :: A pointer to the parameter data.                           */
379.1757 +  /*                                                                       */
379.1758 +  /* <Note>                                                                */
379.1759 +  /*    The ID and function of parameters are driver-specific.  See the    */
379.1760 +  /*    various FT_PARAM_TAG_XXX flags for more information.               */
379.1761 +  /*                                                                       */
379.1762 +  typedef struct  FT_Parameter_
379.1763 +  {
379.1764 +    FT_ULong    tag;
379.1765 +    FT_Pointer  data;
379.1766 +
379.1767 +  } FT_Parameter;
379.1768 +
379.1769 +
379.1770 +  /*************************************************************************/
379.1771 +  /*                                                                       */
379.1772 +  /* <Struct>                                                              */
379.1773 +  /*    FT_Open_Args                                                       */
379.1774 +  /*                                                                       */
379.1775 +  /* <Description>                                                         */
379.1776 +  /*    A structure used to indicate how to open a new font file or        */
379.1777 +  /*    stream.  A pointer to such a structure can be used as a parameter  */
379.1778 +  /*    for the functions @FT_Open_Face and @FT_Attach_Stream.             */
379.1779 +  /*                                                                       */
379.1780 +  /* <Fields>                                                              */
379.1781 +  /*    flags       :: A set of bit flags indicating how to use the        */
379.1782 +  /*                   structure.                                          */
379.1783 +  /*                                                                       */
379.1784 +  /*    memory_base :: The first byte of the file in memory.               */
379.1785 +  /*                                                                       */
379.1786 +  /*    memory_size :: The size in bytes of the file in memory.            */
379.1787 +  /*                                                                       */
379.1788 +  /*    pathname    :: A pointer to an 8-bit file pathname.                */
379.1789 +  /*                                                                       */
379.1790 +  /*    stream      :: A handle to a source stream object.                 */
379.1791 +  /*                                                                       */
379.1792 +  /*    driver      :: This field is exclusively used by @FT_Open_Face;    */
379.1793 +  /*                   it simply specifies the font driver to use to open  */
379.1794 +  /*                   the face.  If set to~0, FreeType tries to load the  */
379.1795 +  /*                   face with each one of the drivers in its list.      */
379.1796 +  /*                                                                       */
379.1797 +  /*    num_params  :: The number of extra parameters.                     */
379.1798 +  /*                                                                       */
379.1799 +  /*    params      :: Extra parameters passed to the font driver when     */
379.1800 +  /*                   opening a new face.                                 */
379.1801 +  /*                                                                       */
379.1802 +  /* <Note>                                                                */
379.1803 +  /*    The stream type is determined by the contents of `flags' which     */
379.1804 +  /*    are tested in the following order by @FT_Open_Face:                */
379.1805 +  /*                                                                       */
379.1806 +  /*    If the `FT_OPEN_MEMORY' bit is set, assume that this is a          */
379.1807 +  /*    memory file of `memory_size' bytes, located at `memory_address'.   */
379.1808 +  /*    The data are are not copied, and the client is responsible for     */
379.1809 +  /*    releasing and destroying them _after_ the corresponding call to    */
379.1810 +  /*    @FT_Done_Face.                                                     */
379.1811 +  /*                                                                       */
379.1812 +  /*    Otherwise, if the `FT_OPEN_STREAM' bit is set, assume that a       */
379.1813 +  /*    custom input stream `stream' is used.                              */
379.1814 +  /*                                                                       */
379.1815 +  /*    Otherwise, if the `FT_OPEN_PATHNAME' bit is set, assume that this  */
379.1816 +  /*    is a normal file and use `pathname' to open it.                    */
379.1817 +  /*                                                                       */
379.1818 +  /*    If the `FT_OPEN_DRIVER' bit is set, @FT_Open_Face only tries to    */
379.1819 +  /*    open the file with the driver whose handler is in `driver'.        */
379.1820 +  /*                                                                       */
379.1821 +  /*    If the `FT_OPEN_PARAMS' bit is set, the parameters given by        */
379.1822 +  /*    `num_params' and `params' is used.  They are ignored otherwise.    */
379.1823 +  /*                                                                       */
379.1824 +  /*    Ideally, both the `pathname' and `params' fields should be tagged  */
379.1825 +  /*    as `const'; this is missing for API backwards compatibility.  In   */
379.1826 +  /*    other words, applications should treat them as read-only.          */
379.1827 +  /*                                                                       */
379.1828 +  typedef struct  FT_Open_Args_
379.1829 +  {
379.1830 +    FT_UInt         flags;
379.1831 +    const FT_Byte*  memory_base;
379.1832 +    FT_Long         memory_size;
379.1833 +    FT_String*      pathname;
379.1834 +    FT_Stream       stream;
379.1835 +    FT_Module       driver;
379.1836 +    FT_Int          num_params;
379.1837 +    FT_Parameter*   params;
379.1838 +
379.1839 +  } FT_Open_Args;
379.1840 +
379.1841 +
379.1842 +  /*************************************************************************/
379.1843 +  /*                                                                       */
379.1844 +  /* <Function>                                                            */
379.1845 +  /*    FT_New_Face                                                        */
379.1846 +  /*                                                                       */
379.1847 +  /* <Description>                                                         */
379.1848 +  /*    This function calls @FT_Open_Face to open a font by its pathname.  */
379.1849 +  /*                                                                       */
379.1850 +  /* <InOut>                                                               */
379.1851 +  /*    library    :: A handle to the library resource.                    */
379.1852 +  /*                                                                       */
379.1853 +  /* <Input>                                                               */
379.1854 +  /*    pathname   :: A path to the font file.                             */
379.1855 +  /*                                                                       */
379.1856 +  /*    face_index :: The index of the face within the font.  The first    */
379.1857 +  /*                  face has index~0.                                    */
379.1858 +  /*                                                                       */
379.1859 +  /* <Output>                                                              */
379.1860 +  /*    aface      :: A handle to a new face object.  If `face_index' is   */
379.1861 +  /*                  greater than or equal to zero, it must be non-NULL.  */
379.1862 +  /*                  See @FT_Open_Face for more details.                  */
379.1863 +  /*                                                                       */
379.1864 +  /* <Return>                                                              */
379.1865 +  /*    FreeType error code.  0~means success.                             */
379.1866 +  /*                                                                       */
379.1867 +  FT_EXPORT( FT_Error )
379.1868 +  FT_New_Face( FT_Library   library,
379.1869 +               const char*  filepathname,
379.1870 +               FT_Long      face_index,
379.1871 +               FT_Face     *aface );
379.1872 +
379.1873 +
379.1874 +  /*************************************************************************/
379.1875 +  /*                                                                       */
379.1876 +  /* <Function>                                                            */
379.1877 +  /*    FT_New_Memory_Face                                                 */
379.1878 +  /*                                                                       */
379.1879 +  /* <Description>                                                         */
379.1880 +  /*    This function calls @FT_Open_Face to open a font which has been    */
379.1881 +  /*    loaded into memory.                                                */
379.1882 +  /*                                                                       */
379.1883 +  /* <InOut>                                                               */
379.1884 +  /*    library    :: A handle to the library resource.                    */
379.1885 +  /*                                                                       */
379.1886 +  /* <Input>                                                               */
379.1887 +  /*    file_base  :: A pointer to the beginning of the font data.         */
379.1888 +  /*                                                                       */
379.1889 +  /*    file_size  :: The size of the memory chunk used by the font data.  */
379.1890 +  /*                                                                       */
379.1891 +  /*    face_index :: The index of the face within the font.  The first    */
379.1892 +  /*                  face has index~0.                                    */
379.1893 +  /*                                                                       */
379.1894 +  /* <Output>                                                              */
379.1895 +  /*    aface      :: A handle to a new face object.  If `face_index' is   */
379.1896 +  /*                  greater than or equal to zero, it must be non-NULL.  */
379.1897 +  /*                  See @FT_Open_Face for more details.                  */
379.1898 +  /*                                                                       */
379.1899 +  /* <Return>                                                              */
379.1900 +  /*    FreeType error code.  0~means success.                             */
379.1901 +  /*                                                                       */
379.1902 +  /* <Note>                                                                */
379.1903 +  /*    You must not deallocate the memory before calling @FT_Done_Face.   */
379.1904 +  /*                                                                       */
379.1905 +  FT_EXPORT( FT_Error )
379.1906 +  FT_New_Memory_Face( FT_Library      library,
379.1907 +                      const FT_Byte*  file_base,
379.1908 +                      FT_Long         file_size,
379.1909 +                      FT_Long         face_index,
379.1910 +                      FT_Face        *aface );
379.1911 +
379.1912 +
379.1913 +  /*************************************************************************/
379.1914 +  /*                                                                       */
379.1915 +  /* <Function>                                                            */
379.1916 +  /*    FT_Open_Face                                                       */
379.1917 +  /*                                                                       */
379.1918 +  /* <Description>                                                         */
379.1919 +  /*    Create a face object from a given resource described by            */
379.1920 +  /*    @FT_Open_Args.                                                     */
379.1921 +  /*                                                                       */
379.1922 +  /* <InOut>                                                               */
379.1923 +  /*    library    :: A handle to the library resource.                    */
379.1924 +  /*                                                                       */
379.1925 +  /* <Input>                                                               */
379.1926 +  /*    args       :: A pointer to an `FT_Open_Args' structure which must  */
379.1927 +  /*                  be filled by the caller.                             */
379.1928 +  /*                                                                       */
379.1929 +  /*    face_index :: The index of the face within the font.  The first    */
379.1930 +  /*                  face has index~0.                                    */
379.1931 +  /*                                                                       */
379.1932 +  /* <Output>                                                              */
379.1933 +  /*    aface      :: A handle to a new face object.  If `face_index' is   */
379.1934 +  /*                  greater than or equal to zero, it must be non-NULL.  */
379.1935 +  /*                  See note below.                                      */
379.1936 +  /*                                                                       */
379.1937 +  /* <Return>                                                              */
379.1938 +  /*    FreeType error code.  0~means success.                             */
379.1939 +  /*                                                                       */
379.1940 +  /* <Note>                                                                */
379.1941 +  /*    Unlike FreeType 1.x, this function automatically creates a glyph   */
379.1942 +  /*    slot for the face object which can be accessed directly through    */
379.1943 +  /*    `face->glyph'.                                                     */
379.1944 +  /*                                                                       */
379.1945 +  /*    FT_Open_Face can be used to quickly check whether the font         */
379.1946 +  /*    format of a given font resource is supported by FreeType.  If the  */
379.1947 +  /*    `face_index' field is negative, the function's return value is~0   */
379.1948 +  /*    if the font format is recognized, or non-zero otherwise;           */
379.1949 +  /*    the function returns a more or less empty face handle in `*aface'  */
379.1950 +  /*    (if `aface' isn't NULL).  The only useful field in this special    */
379.1951 +  /*    case is `face->num_faces' which gives the number of faces within   */
379.1952 +  /*    the font file.  After examination, the returned @FT_Face structure */
379.1953 +  /*    should be deallocated with a call to @FT_Done_Face.                */
379.1954 +  /*                                                                       */
379.1955 +  /*    Each new face object created with this function also owns a        */
379.1956 +  /*    default @FT_Size object, accessible as `face->size'.               */
379.1957 +  /*                                                                       */
379.1958 +  /*    See the discussion of reference counters in the description of     */
379.1959 +  /*    @FT_Reference_Face.                                                */
379.1960 +  /*                                                                       */
379.1961 +  FT_EXPORT( FT_Error )
379.1962 +  FT_Open_Face( FT_Library           library,
379.1963 +                const FT_Open_Args*  args,
379.1964 +                FT_Long              face_index,
379.1965 +                FT_Face             *aface );
379.1966 +
379.1967 +
379.1968 +  /*************************************************************************/
379.1969 +  /*                                                                       */
379.1970 +  /* <Function>                                                            */
379.1971 +  /*    FT_Attach_File                                                     */
379.1972 +  /*                                                                       */
379.1973 +  /* <Description>                                                         */
379.1974 +  /*    This function calls @FT_Attach_Stream to attach a file.            */
379.1975 +  /*                                                                       */
379.1976 +  /* <InOut>                                                               */
379.1977 +  /*    face         :: The target face object.                            */
379.1978 +  /*                                                                       */
379.1979 +  /* <Input>                                                               */
379.1980 +  /*    filepathname :: The pathname.                                      */
379.1981 +  /*                                                                       */
379.1982 +  /* <Return>                                                              */
379.1983 +  /*    FreeType error code.  0~means success.                             */
379.1984 +  /*                                                                       */
379.1985 +  FT_EXPORT( FT_Error )
379.1986 +  FT_Attach_File( FT_Face      face,
379.1987 +                  const char*  filepathname );
379.1988 +
379.1989 +
379.1990 +  /*************************************************************************/
379.1991 +  /*                                                                       */
379.1992 +  /* <Function>                                                            */
379.1993 +  /*    FT_Attach_Stream                                                   */
379.1994 +  /*                                                                       */
379.1995 +  /* <Description>                                                         */
379.1996 +  /*    `Attach' data to a face object.  Normally, this is used to read    */
379.1997 +  /*    additional information for the face object.  For example, you can  */
379.1998 +  /*    attach an AFM file that comes with a Type~1 font to get the        */
379.1999 +  /*    kerning values and other metrics.                                  */
379.2000 +  /*                                                                       */
379.2001 +  /* <InOut>                                                               */
379.2002 +  /*    face       :: The target face object.                              */
379.2003 +  /*                                                                       */
379.2004 +  /* <Input>                                                               */
379.2005 +  /*    parameters :: A pointer to @FT_Open_Args which must be filled by   */
379.2006 +  /*                  the caller.                                          */
379.2007 +  /*                                                                       */
379.2008 +  /* <Return>                                                              */
379.2009 +  /*    FreeType error code.  0~means success.                             */
379.2010 +  /*                                                                       */
379.2011 +  /* <Note>                                                                */
379.2012 +  /*    The meaning of the `attach' (i.e., what really happens when the    */
379.2013 +  /*    new file is read) is not fixed by FreeType itself.  It really      */
379.2014 +  /*    depends on the font format (and thus the font driver).             */
379.2015 +  /*                                                                       */
379.2016 +  /*    Client applications are expected to know what they are doing       */
379.2017 +  /*    when invoking this function.  Most drivers simply do not implement */
379.2018 +  /*    file attachments.                                                  */
379.2019 +  /*                                                                       */
379.2020 +  FT_EXPORT( FT_Error )
379.2021 +  FT_Attach_Stream( FT_Face        face,
379.2022 +                    FT_Open_Args*  parameters );
379.2023 +
379.2024 +
379.2025 +  /*************************************************************************/
379.2026 +  /*                                                                       */
379.2027 +  /* <Function>                                                            */
379.2028 +  /*    FT_Reference_Face                                                  */
379.2029 +  /*                                                                       */
379.2030 +  /* <Description>                                                         */
379.2031 +  /*    A counter gets initialized to~1 at the time an @FT_Face structure  */
379.2032 +  /*    is created.  This function increments the counter.  @FT_Done_Face  */
379.2033 +  /*    then only destroys a face if the counter is~1, otherwise it simply */
379.2034 +  /*    decrements the counter.                                            */
379.2035 +  /*                                                                       */
379.2036 +  /*    This function helps in managing life-cycles of structures which    */
379.2037 +  /*    reference @FT_Face objects.                                        */
379.2038 +  /*                                                                       */
379.2039 +  /* <Input>                                                               */
379.2040 +  /*    face :: A handle to a target face object.                          */
379.2041 +  /*                                                                       */
379.2042 +  /* <Return>                                                              */
379.2043 +  /*    FreeType error code.  0~means success.                             */
379.2044 +  /*                                                                       */
379.2045 +  /* <Since>                                                               */
379.2046 +  /*    2.4.2                                                              */
379.2047 +  /*                                                                       */
379.2048 +  FT_EXPORT( FT_Error )
379.2049 +  FT_Reference_Face( FT_Face  face );
379.2050 +
379.2051 +
379.2052 +  /*************************************************************************/
379.2053 +  /*                                                                       */
379.2054 +  /* <Function>                                                            */
379.2055 +  /*    FT_Done_Face                                                       */
379.2056 +  /*                                                                       */
379.2057 +  /* <Description>                                                         */
379.2058 +  /*    Discard a given face object, as well as all of its child slots and */
379.2059 +  /*    sizes.                                                             */
379.2060 +  /*                                                                       */
379.2061 +  /* <Input>                                                               */
379.2062 +  /*    face :: A handle to a target face object.                          */
379.2063 +  /*                                                                       */
379.2064 +  /* <Return>                                                              */
379.2065 +  /*    FreeType error code.  0~means success.                             */
379.2066 +  /*                                                                       */
379.2067 +  /* <Note>                                                                */
379.2068 +  /*    See the discussion of reference counters in the description of     */
379.2069 +  /*    @FT_Reference_Face.                                                */
379.2070 +  /*                                                                       */
379.2071 +  FT_EXPORT( FT_Error )
379.2072 +  FT_Done_Face( FT_Face  face );
379.2073 +
379.2074 +
379.2075 +  /*************************************************************************/
379.2076 +  /*                                                                       */
379.2077 +  /* <Function>                                                            */
379.2078 +  /*    FT_Select_Size                                                     */
379.2079 +  /*                                                                       */
379.2080 +  /* <Description>                                                         */
379.2081 +  /*    Select a bitmap strike.                                            */
379.2082 +  /*                                                                       */
379.2083 +  /* <InOut>                                                               */
379.2084 +  /*    face         :: A handle to a target face object.                  */
379.2085 +  /*                                                                       */
379.2086 +  /* <Input>                                                               */
379.2087 +  /*    strike_index :: The index of the bitmap strike in the              */
379.2088 +  /*                    `available_sizes' field of @FT_FaceRec structure.  */
379.2089 +  /*                                                                       */
379.2090 +  /* <Return>                                                              */
379.2091 +  /*    FreeType error code.  0~means success.                             */
379.2092 +  /*                                                                       */
379.2093 +  FT_EXPORT( FT_Error )
379.2094 +  FT_Select_Size( FT_Face  face,
379.2095 +                  FT_Int   strike_index );
379.2096 +
379.2097 +
379.2098 +  /*************************************************************************/
379.2099 +  /*                                                                       */
379.2100 +  /* <Enum>                                                                */
379.2101 +  /*    FT_Size_Request_Type                                               */
379.2102 +  /*                                                                       */
379.2103 +  /* <Description>                                                         */
379.2104 +  /*    An enumeration type that lists the supported size request types.   */
379.2105 +  /*                                                                       */
379.2106 +  /* <Values>                                                              */
379.2107 +  /*    FT_SIZE_REQUEST_TYPE_NOMINAL ::                                    */
379.2108 +  /*      The nominal size.  The `units_per_EM' field of @FT_FaceRec is    */
379.2109 +  /*      used to determine both scaling values.                           */
379.2110 +  /*                                                                       */
379.2111 +  /*    FT_SIZE_REQUEST_TYPE_REAL_DIM ::                                   */
379.2112 +  /*      The real dimension.  The sum of the the `Ascender' and (minus    */
379.2113 +  /*      of) the `Descender' fields of @FT_FaceRec are used to determine  */
379.2114 +  /*      both scaling values.                                             */
379.2115 +  /*                                                                       */
379.2116 +  /*    FT_SIZE_REQUEST_TYPE_BBOX ::                                       */
379.2117 +  /*      The font bounding box.  The width and height of the `bbox' field */
379.2118 +  /*      of @FT_FaceRec are used to determine the horizontal and vertical */
379.2119 +  /*      scaling value, respectively.                                     */
379.2120 +  /*                                                                       */
379.2121 +  /*    FT_SIZE_REQUEST_TYPE_CELL ::                                       */
379.2122 +  /*      The `max_advance_width' field of @FT_FaceRec is used to          */
379.2123 +  /*      determine the horizontal scaling value; the vertical scaling     */
379.2124 +  /*      value is determined the same way as                              */
379.2125 +  /*      @FT_SIZE_REQUEST_TYPE_REAL_DIM does.  Finally, both scaling      */
379.2126 +  /*      values are set to the smaller one.  This type is useful if you   */
379.2127 +  /*      want to specify the font size for, say, a window of a given      */
379.2128 +  /*      dimension and 80x24 cells.                                       */
379.2129 +  /*                                                                       */
379.2130 +  /*    FT_SIZE_REQUEST_TYPE_SCALES ::                                     */
379.2131 +  /*      Specify the scaling values directly.                             */
379.2132 +  /*                                                                       */
379.2133 +  /* <Note>                                                                */
379.2134 +  /*    The above descriptions only apply to scalable formats.  For bitmap */
379.2135 +  /*    formats, the behaviour is up to the driver.                        */
379.2136 +  /*                                                                       */
379.2137 +  /*    See the note section of @FT_Size_Metrics if you wonder how size    */
379.2138 +  /*    requesting relates to scaling values.                              */
379.2139 +  /*                                                                       */
379.2140 +  typedef enum  FT_Size_Request_Type_
379.2141 +  {
379.2142 +    FT_SIZE_REQUEST_TYPE_NOMINAL,
379.2143 +    FT_SIZE_REQUEST_TYPE_REAL_DIM,
379.2144 +    FT_SIZE_REQUEST_TYPE_BBOX,
379.2145 +    FT_SIZE_REQUEST_TYPE_CELL,
379.2146 +    FT_SIZE_REQUEST_TYPE_SCALES,
379.2147 +
379.2148 +    FT_SIZE_REQUEST_TYPE_MAX
379.2149 +
379.2150 +  } FT_Size_Request_Type;
379.2151 +
379.2152 +
379.2153 +  /*************************************************************************/
379.2154 +  /*                                                                       */
379.2155 +  /* <Struct>                                                              */
379.2156 +  /*    FT_Size_RequestRec                                                 */
379.2157 +  /*                                                                       */
379.2158 +  /* <Description>                                                         */
379.2159 +  /*    A structure used to model a size request.                          */
379.2160 +  /*                                                                       */
379.2161 +  /* <Fields>                                                              */
379.2162 +  /*    type           :: See @FT_Size_Request_Type.                       */
379.2163 +  /*                                                                       */
379.2164 +  /*    width          :: The desired width.                               */
379.2165 +  /*                                                                       */
379.2166 +  /*    height         :: The desired height.                              */
379.2167 +  /*                                                                       */
379.2168 +  /*    horiResolution :: The horizontal resolution.  If set to zero,      */
379.2169 +  /*                      `width' is treated as a 26.6 fractional pixel    */
379.2170 +  /*                      value.                                           */
379.2171 +  /*                                                                       */
379.2172 +  /*    vertResolution :: The vertical resolution.  If set to zero,        */
379.2173 +  /*                      `height' is treated as a 26.6 fractional pixel   */
379.2174 +  /*                      value.                                           */
379.2175 +  /*                                                                       */
379.2176 +  /* <Note>                                                                */
379.2177 +  /*    If `width' is zero, then the horizontal scaling value is set equal */
379.2178 +  /*    to the vertical scaling value, and vice versa.                     */
379.2179 +  /*                                                                       */
379.2180 +  typedef struct  FT_Size_RequestRec_
379.2181 +  {
379.2182 +    FT_Size_Request_Type  type;
379.2183 +    FT_Long               width;
379.2184 +    FT_Long               height;
379.2185 +    FT_UInt               horiResolution;
379.2186 +    FT_UInt               vertResolution;
379.2187 +
379.2188 +  } FT_Size_RequestRec;
379.2189 +
379.2190 +
379.2191 +  /*************************************************************************/
379.2192 +  /*                                                                       */
379.2193 +  /* <Struct>                                                              */
379.2194 +  /*    FT_Size_Request                                                    */
379.2195 +  /*                                                                       */
379.2196 +  /* <Description>                                                         */
379.2197 +  /*    A handle to a size request structure.                              */
379.2198 +  /*                                                                       */
379.2199 +  typedef struct FT_Size_RequestRec_  *FT_Size_Request;
379.2200 +
379.2201 +
379.2202 +  /*************************************************************************/
379.2203 +  /*                                                                       */
379.2204 +  /* <Function>                                                            */
379.2205 +  /*    FT_Request_Size                                                    */
379.2206 +  /*                                                                       */
379.2207 +  /* <Description>                                                         */
379.2208 +  /*    Resize the scale of the active @FT_Size object in a face.          */
379.2209 +  /*                                                                       */
379.2210 +  /* <InOut>                                                               */
379.2211 +  /*    face :: A handle to a target face object.                          */
379.2212 +  /*                                                                       */
379.2213 +  /* <Input>                                                               */
379.2214 +  /*    req  :: A pointer to a @FT_Size_RequestRec.                        */
379.2215 +  /*                                                                       */
379.2216 +  /* <Return>                                                              */
379.2217 +  /*    FreeType error code.  0~means success.                             */
379.2218 +  /*                                                                       */
379.2219 +  /* <Note>                                                                */
379.2220 +  /*    Although drivers may select the bitmap strike matching the         */
379.2221 +  /*    request, you should not rely on this if you intend to select a     */
379.2222 +  /*    particular bitmap strike.  Use @FT_Select_Size instead in that     */
379.2223 +  /*    case.                                                              */
379.2224 +  /*                                                                       */
379.2225 +  FT_EXPORT( FT_Error )
379.2226 +  FT_Request_Size( FT_Face          face,
379.2227 +                   FT_Size_Request  req );
379.2228 +
379.2229 +
379.2230 +  /*************************************************************************/
379.2231 +  /*                                                                       */
379.2232 +  /* <Function>                                                            */
379.2233 +  /*    FT_Set_Char_Size                                                   */
379.2234 +  /*                                                                       */
379.2235 +  /* <Description>                                                         */
379.2236 +  /*    This function calls @FT_Request_Size to request the nominal size   */
379.2237 +  /*    (in points).                                                       */
379.2238 +  /*                                                                       */
379.2239 +  /* <InOut>                                                               */
379.2240 +  /*    face            :: A handle to a target face object.               */
379.2241 +  /*                                                                       */
379.2242 +  /* <Input>                                                               */
379.2243 +  /*    char_width      :: The nominal width, in 26.6 fractional points.   */
379.2244 +  /*                                                                       */
379.2245 +  /*    char_height     :: The nominal height, in 26.6 fractional points.  */
379.2246 +  /*                                                                       */
379.2247 +  /*    horz_resolution :: The horizontal resolution in dpi.               */
379.2248 +  /*                                                                       */
379.2249 +  /*    vert_resolution :: The vertical resolution in dpi.                 */
379.2250 +  /*                                                                       */
379.2251 +  /* <Return>                                                              */
379.2252 +  /*    FreeType error code.  0~means success.                             */
379.2253 +  /*                                                                       */
379.2254 +  /* <Note>                                                                */
379.2255 +  /*    If either the character width or height is zero, it is set equal   */
379.2256 +  /*    to the other value.                                                */
379.2257 +  /*                                                                       */
379.2258 +  /*    If either the horizontal or vertical resolution is zero, it is set */
379.2259 +  /*    equal to the other value.                                          */
379.2260 +  /*                                                                       */
379.2261 +  /*    A character width or height smaller than 1pt is set to 1pt; if     */
379.2262 +  /*    both resolution values are zero, they are set to 72dpi.            */
379.2263 +  /*                                                                       */
379.2264 +  /*    Don't use this function if you are using the FreeType cache API.   */
379.2265 +  /*                                                                       */
379.2266 +  FT_EXPORT( FT_Error )
379.2267 +  FT_Set_Char_Size( FT_Face     face,
379.2268 +                    FT_F26Dot6  char_width,
379.2269 +                    FT_F26Dot6  char_height,
379.2270 +                    FT_UInt     horz_resolution,
379.2271 +                    FT_UInt     vert_resolution );
379.2272 +
379.2273 +
379.2274 +  /*************************************************************************/
379.2275 +  /*                                                                       */
379.2276 +  /* <Function>                                                            */
379.2277 +  /*    FT_Set_Pixel_Sizes                                                 */
379.2278 +  /*                                                                       */
379.2279 +  /* <Description>                                                         */
379.2280 +  /*    This function calls @FT_Request_Size to request the nominal size   */
379.2281 +  /*    (in pixels).                                                       */
379.2282 +  /*                                                                       */
379.2283 +  /* <InOut>                                                               */
379.2284 +  /*    face         :: A handle to the target face object.                */
379.2285 +  /*                                                                       */
379.2286 +  /* <Input>                                                               */
379.2287 +  /*    pixel_width  :: The nominal width, in pixels.                      */
379.2288 +  /*                                                                       */
379.2289 +  /*    pixel_height :: The nominal height, in pixels.                     */
379.2290 +  /*                                                                       */
379.2291 +  /* <Return>                                                              */
379.2292 +  /*    FreeType error code.  0~means success.                             */
379.2293 +  /*                                                                       */
379.2294 +  FT_EXPORT( FT_Error )
379.2295 +  FT_Set_Pixel_Sizes( FT_Face  face,
379.2296 +                      FT_UInt  pixel_width,
379.2297 +                      FT_UInt  pixel_height );
379.2298 +
379.2299 +
379.2300 +  /*************************************************************************/
379.2301 +  /*                                                                       */
379.2302 +  /* <Function>                                                            */
379.2303 +  /*    FT_Load_Glyph                                                      */
379.2304 +  /*                                                                       */
379.2305 +  /* <Description>                                                         */
379.2306 +  /*    A function used to load a single glyph into the glyph slot of a    */
379.2307 +  /*    face object.                                                       */
379.2308 +  /*                                                                       */
379.2309 +  /* <InOut>                                                               */
379.2310 +  /*    face        :: A handle to the target face object where the glyph  */
379.2311 +  /*                   is loaded.                                          */
379.2312 +  /*                                                                       */
379.2313 +  /* <Input>                                                               */
379.2314 +  /*    glyph_index :: The index of the glyph in the font file.  For       */
379.2315 +  /*                   CID-keyed fonts (either in PS or in CFF format)     */
379.2316 +  /*                   this argument specifies the CID value.              */
379.2317 +  /*                                                                       */
379.2318 +  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
379.2319 +  /*                   @FT_LOAD_XXX constants can be used to control the   */
379.2320 +  /*                   glyph loading process (e.g., whether the outline    */
379.2321 +  /*                   should be scaled, whether to load bitmaps or not,   */
379.2322 +  /*                   whether to hint the outline, etc).                  */
379.2323 +  /*                                                                       */
379.2324 +  /* <Return>                                                              */
379.2325 +  /*    FreeType error code.  0~means success.                             */
379.2326 +  /*                                                                       */
379.2327 +  /* <Note>                                                                */
379.2328 +  /*    The loaded glyph may be transformed.  See @FT_Set_Transform for    */
379.2329 +  /*    the details.                                                       */
379.2330 +  /*                                                                       */
379.2331 +  /*    For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is        */
379.2332 +  /*    returned for invalid CID values (this is, for CID values which     */
379.2333 +  /*    don't have a corresponding glyph in the font).  See the discussion */
379.2334 +  /*    of the @FT_FACE_FLAG_CID_KEYED flag for more details.              */
379.2335 +  /*                                                                       */
379.2336 +  FT_EXPORT( FT_Error )
379.2337 +  FT_Load_Glyph( FT_Face   face,
379.2338 +                 FT_UInt   glyph_index,
379.2339 +                 FT_Int32  load_flags );
379.2340 +
379.2341 +
379.2342 +  /*************************************************************************/
379.2343 +  /*                                                                       */
379.2344 +  /* <Function>                                                            */
379.2345 +  /*    FT_Load_Char                                                       */
379.2346 +  /*                                                                       */
379.2347 +  /* <Description>                                                         */
379.2348 +  /*    A function used to load a single glyph into the glyph slot of a    */
379.2349 +  /*    face object, according to its character code.                      */
379.2350 +  /*                                                                       */
379.2351 +  /* <InOut>                                                               */
379.2352 +  /*    face        :: A handle to a target face object where the glyph    */
379.2353 +  /*                   is loaded.                                          */
379.2354 +  /*                                                                       */
379.2355 +  /* <Input>                                                               */
379.2356 +  /*    char_code   :: The glyph's character code, according to the        */
379.2357 +  /*                   current charmap used in the face.                   */
379.2358 +  /*                                                                       */
379.2359 +  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
379.2360 +  /*                   @FT_LOAD_XXX constants can be used to control the   */
379.2361 +  /*                   glyph loading process (e.g., whether the outline    */
379.2362 +  /*                   should be scaled, whether to load bitmaps or not,   */
379.2363 +  /*                   whether to hint the outline, etc).                  */
379.2364 +  /*                                                                       */
379.2365 +  /* <Return>                                                              */
379.2366 +  /*    FreeType error code.  0~means success.                             */
379.2367 +  /*                                                                       */
379.2368 +  /* <Note>                                                                */
379.2369 +  /*    This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph.  */
379.2370 +  /*                                                                       */
379.2371 +  FT_EXPORT( FT_Error )
379.2372 +  FT_Load_Char( FT_Face   face,
379.2373 +                FT_ULong  char_code,
379.2374 +                FT_Int32  load_flags );
379.2375 +
379.2376 +
379.2377 +  /*************************************************************************
379.2378 +   *
379.2379 +   * @enum:
379.2380 +   *   FT_LOAD_XXX
379.2381 +   *
379.2382 +   * @description:
379.2383 +   *   A list of bit-field constants used with @FT_Load_Glyph to indicate
379.2384 +   *   what kind of operations to perform during glyph loading.
379.2385 +   *
379.2386 +   * @values:
379.2387 +   *   FT_LOAD_DEFAULT ::
379.2388 +   *     Corresponding to~0, this value is used as the default glyph load
379.2389 +   *     operation.  In this case, the following happens:
379.2390 +   *
379.2391 +   *     1. FreeType looks for a bitmap for the glyph corresponding to the
379.2392 +   *        face's current size.  If one is found, the function returns.
379.2393 +   *        The bitmap data can be accessed from the glyph slot (see note
379.2394 +   *        below).
379.2395 +   *
379.2396 +   *     2. If no embedded bitmap is searched or found, FreeType looks for a
379.2397 +   *        scalable outline.  If one is found, it is loaded from the font
379.2398 +   *        file, scaled to device pixels, then `hinted' to the pixel grid
379.2399 +   *        in order to optimize it.  The outline data can be accessed from
379.2400 +   *        the glyph slot (see note below).
379.2401 +   *
379.2402 +   *     Note that by default, the glyph loader doesn't render outlines into
379.2403 +   *     bitmaps.  The following flags are used to modify this default
379.2404 +   *     behaviour to more specific and useful cases.
379.2405 +   *
379.2406 +   *   FT_LOAD_NO_SCALE ::
379.2407 +   *     Don't scale the outline glyph loaded, but keep it in font units.
379.2408 +   *
379.2409 +   *     This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and
379.2410 +   *     unsets @FT_LOAD_RENDER.
379.2411 +   *
379.2412 +   *   FT_LOAD_NO_HINTING ::
379.2413 +   *     Disable hinting.  This generally generates `blurrier' bitmap glyph
379.2414 +   *     when the glyph is rendered in any of the anti-aliased modes.  See
379.2415 +   *     also the note below.
379.2416 +   *
379.2417 +   *     This flag is implied by @FT_LOAD_NO_SCALE.
379.2418 +   *
379.2419 +   *   FT_LOAD_RENDER ::
379.2420 +   *     Call @FT_Render_Glyph after the glyph is loaded.  By default, the
379.2421 +   *     glyph is rendered in @FT_RENDER_MODE_NORMAL mode.  This can be
379.2422 +   *     overridden by @FT_LOAD_TARGET_XXX or @FT_LOAD_MONOCHROME.
379.2423 +   *
379.2424 +   *     This flag is unset by @FT_LOAD_NO_SCALE.
379.2425 +   *
379.2426 +   *   FT_LOAD_NO_BITMAP ::
379.2427 +   *     Ignore bitmap strikes when loading.  Bitmap-only fonts ignore this
379.2428 +   *     flag.
379.2429 +   *
379.2430 +   *     @FT_LOAD_NO_SCALE always sets this flag.
379.2431 +   *
379.2432 +   *   FT_LOAD_VERTICAL_LAYOUT ::
379.2433 +   *     Load the glyph for vertical text layout.  _Don't_ use it as it is
379.2434 +   *     problematic currently.
379.2435 +   *
379.2436 +   *   FT_LOAD_FORCE_AUTOHINT ::
379.2437 +   *     Indicates that the auto-hinter is preferred over the font's native
379.2438 +   *     hinter.  See also the note below.
379.2439 +   *
379.2440 +   *   FT_LOAD_CROP_BITMAP ::
379.2441 +   *     Indicates that the font driver should crop the loaded bitmap glyph
379.2442 +   *     (i.e., remove all space around its black bits).  Not all drivers
379.2443 +   *     implement this.
379.2444 +   *
379.2445 +   *   FT_LOAD_PEDANTIC ::
379.2446 +   *     Indicates that the font driver should perform pedantic verifications
379.2447 +   *     during glyph loading.  This is mostly used to detect broken glyphs
379.2448 +   *     in fonts.  By default, FreeType tries to handle broken fonts also.
379.2449 +   *
379.2450 +   *   FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ::
379.2451 +   *     Indicates that the font driver should ignore the global advance
379.2452 +   *     width defined in the font.  By default, that value is used as the
379.2453 +   *     advance width for all glyphs when the face has
379.2454 +   *     @FT_FACE_FLAG_FIXED_WIDTH set.
379.2455 +   *
379.2456 +   *     This flag exists for historical reasons (to support buggy CJK
379.2457 +   *     fonts).
379.2458 +   *
379.2459 +   *   FT_LOAD_NO_RECURSE ::
379.2460 +   *     This flag is only used internally.  It merely indicates that the
379.2461 +   *     font driver should not load composite glyphs recursively.  Instead,
379.2462 +   *     it should set the `num_subglyph' and `subglyphs' values of the
379.2463 +   *     glyph slot accordingly, and set `glyph->format' to
379.2464 +   *     @FT_GLYPH_FORMAT_COMPOSITE.
379.2465 +   *
379.2466 +   *     The description of sub-glyphs is not available to client
379.2467 +   *     applications for now.
379.2468 +   *
379.2469 +   *     This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM.
379.2470 +   *
379.2471 +   *   FT_LOAD_IGNORE_TRANSFORM ::
379.2472 +   *     Indicates that the transform matrix set by @FT_Set_Transform should
379.2473 +   *     be ignored.
379.2474 +   *
379.2475 +   *   FT_LOAD_MONOCHROME ::
379.2476 +   *     This flag is used with @FT_LOAD_RENDER to indicate that you want to
379.2477 +   *     render an outline glyph to a 1-bit monochrome bitmap glyph, with
379.2478 +   *     8~pixels packed into each byte of the bitmap data.
379.2479 +   *
379.2480 +   *     Note that this has no effect on the hinting algorithm used.  You
379.2481 +   *     should rather use @FT_LOAD_TARGET_MONO so that the
379.2482 +   *     monochrome-optimized hinting algorithm is used.
379.2483 +   *
379.2484 +   *   FT_LOAD_LINEAR_DESIGN ::
379.2485 +   *     Indicates that the `linearHoriAdvance' and `linearVertAdvance'
379.2486 +   *     fields of @FT_GlyphSlotRec should be kept in font units.  See
379.2487 +   *     @FT_GlyphSlotRec for details.
379.2488 +   *
379.2489 +   *   FT_LOAD_NO_AUTOHINT ::
379.2490 +   *     Disable auto-hinter.  See also the note below.
379.2491 +   *
379.2492 +   * @note:
379.2493 +   *   By default, hinting is enabled and the font's native hinter (see
379.2494 +   *   @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter.  You can
379.2495 +   *   disable hinting by setting @FT_LOAD_NO_HINTING or change the
379.2496 +   *   precedence by setting @FT_LOAD_FORCE_AUTOHINT.  You can also set
379.2497 +   *   @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be
379.2498 +   *   used at all.
379.2499 +   *
379.2500 +   *   See the description of @FT_FACE_FLAG_TRICKY for a special exception
379.2501 +   *   (affecting only a handful of Asian fonts).
379.2502 +   *
379.2503 +   *   Besides deciding which hinter to use, you can also decide which
379.2504 +   *   hinting algorithm to use.  See @FT_LOAD_TARGET_XXX for details.
379.2505 +   *
379.2506 +   */
379.2507 +#define FT_LOAD_DEFAULT                      0x0
379.2508 +#define FT_LOAD_NO_SCALE                     0x1
379.2509 +#define FT_LOAD_NO_HINTING                   0x2
379.2510 +#define FT_LOAD_RENDER                       0x4
379.2511 +#define FT_LOAD_NO_BITMAP                    0x8
379.2512 +#define FT_LOAD_VERTICAL_LAYOUT              0x10
379.2513 +#define FT_LOAD_FORCE_AUTOHINT               0x20
379.2514 +#define FT_LOAD_CROP_BITMAP                  0x40
379.2515 +#define FT_LOAD_PEDANTIC                     0x80
379.2516 +#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH  0x200
379.2517 +#define FT_LOAD_NO_RECURSE                   0x400
379.2518 +#define FT_LOAD_IGNORE_TRANSFORM             0x800
379.2519 +#define FT_LOAD_MONOCHROME                   0x1000
379.2520 +#define FT_LOAD_LINEAR_DESIGN                0x2000
379.2521 +#define FT_LOAD_NO_AUTOHINT                  0x8000U
379.2522 +
379.2523 +  /* */
379.2524 +
379.2525 +  /* used internally only by certain font drivers! */
379.2526 +#define FT_LOAD_ADVANCE_ONLY                 0x100
379.2527 +#define FT_LOAD_SBITS_ONLY                   0x4000
379.2528 +
379.2529 +
379.2530 +  /**************************************************************************
379.2531 +   *
379.2532 +   * @enum:
379.2533 +   *   FT_LOAD_TARGET_XXX
379.2534 +   *
379.2535 +   * @description:
379.2536 +   *   A list of values that are used to select a specific hinting algorithm
379.2537 +   *   to use by the hinter.  You should OR one of these values to your
379.2538 +   *   `load_flags' when calling @FT_Load_Glyph.
379.2539 +   *
379.2540 +   *   Note that font's native hinters may ignore the hinting algorithm you
379.2541 +   *   have specified (e.g., the TrueType bytecode interpreter).  You can set
379.2542 +   *   @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used.
379.2543 +   *
379.2544 +   *   Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it
379.2545 +   *   always implies @FT_LOAD_FORCE_AUTOHINT.
379.2546 +   *
379.2547 +   * @values:
379.2548 +   *   FT_LOAD_TARGET_NORMAL ::
379.2549 +   *     This corresponds to the default hinting algorithm, optimized for
379.2550 +   *     standard gray-level rendering.  For monochrome output, use
379.2551 +   *     @FT_LOAD_TARGET_MONO instead.
379.2552 +   *
379.2553 +   *   FT_LOAD_TARGET_LIGHT ::
379.2554 +   *     A lighter hinting algorithm for non-monochrome modes.  Many
379.2555 +   *     generated glyphs are more fuzzy but better resemble its original
379.2556 +   *     shape.  A bit like rendering on Mac OS~X.
379.2557 +   *
379.2558 +   *     As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT.
379.2559 +   *
379.2560 +   *   FT_LOAD_TARGET_MONO ::
379.2561 +   *     Strong hinting algorithm that should only be used for monochrome
379.2562 +   *     output.  The result is probably unpleasant if the glyph is rendered
379.2563 +   *     in non-monochrome modes.
379.2564 +   *
379.2565 +   *   FT_LOAD_TARGET_LCD ::
379.2566 +   *     A variant of @FT_LOAD_TARGET_NORMAL optimized for horizontally
379.2567 +   *     decimated LCD displays.
379.2568 +   *
379.2569 +   *   FT_LOAD_TARGET_LCD_V ::
379.2570 +   *     A variant of @FT_LOAD_TARGET_NORMAL optimized for vertically
379.2571 +   *     decimated LCD displays.
379.2572 +   *
379.2573 +   * @note:
379.2574 +   *   You should use only _one_ of the FT_LOAD_TARGET_XXX values in your
379.2575 +   *   `load_flags'.  They can't be ORed.
379.2576 +   *
379.2577 +   *   If @FT_LOAD_RENDER is also set, the glyph is rendered in the
379.2578 +   *   corresponding mode (i.e., the mode which matches the used algorithm
379.2579 +   *   best) unless @FT_LOAD_MONOCHROME is set.
379.2580 +   *
379.2581 +   *   You can use a hinting algorithm that doesn't correspond to the same
379.2582 +   *   rendering mode.  As an example, it is possible to use the `light'
379.2583 +   *   hinting algorithm and have the results rendered in horizontal LCD
379.2584 +   *   pixel mode, with code like
379.2585 +   *
379.2586 +   *     {
379.2587 +   *       FT_Load_Glyph( face, glyph_index,
379.2588 +   *                      load_flags | FT_LOAD_TARGET_LIGHT );
379.2589 +   *
379.2590 +   *       FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD );
379.2591 +   *     }
379.2592 +   *
379.2593 +   */
379.2594 +#define FT_LOAD_TARGET_( x )   ( (FT_Int32)( (x) & 15 ) << 16 )
379.2595 +
379.2596 +#define FT_LOAD_TARGET_NORMAL  FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL )
379.2597 +#define FT_LOAD_TARGET_LIGHT   FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT  )
379.2598 +#define FT_LOAD_TARGET_MONO    FT_LOAD_TARGET_( FT_RENDER_MODE_MONO   )
379.2599 +#define FT_LOAD_TARGET_LCD     FT_LOAD_TARGET_( FT_RENDER_MODE_LCD    )
379.2600 +#define FT_LOAD_TARGET_LCD_V   FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V  )
379.2601 +
379.2602 +
379.2603 +  /**************************************************************************
379.2604 +   *
379.2605 +   * @macro:
379.2606 +   *   FT_LOAD_TARGET_MODE
379.2607 +   *
379.2608 +   * @description:
379.2609 +   *   Return the @FT_Render_Mode corresponding to a given
379.2610 +   *   @FT_LOAD_TARGET_XXX value.
379.2611 +   *
379.2612 +   */
379.2613 +#define FT_LOAD_TARGET_MODE( x )  ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) )
379.2614 +
379.2615 +
379.2616 +  /*************************************************************************/
379.2617 +  /*                                                                       */
379.2618 +  /* <Function>                                                            */
379.2619 +  /*    FT_Set_Transform                                                   */
379.2620 +  /*                                                                       */
379.2621 +  /* <Description>                                                         */
379.2622 +  /*    A function used to set the transformation that is applied to glyph */
379.2623 +  /*    images when they are loaded into a glyph slot through              */
379.2624 +  /*    @FT_Load_Glyph.                                                    */
379.2625 +  /*                                                                       */
379.2626 +  /* <InOut>                                                               */
379.2627 +  /*    face   :: A handle to the source face object.                      */
379.2628 +  /*                                                                       */
379.2629 +  /* <Input>                                                               */
379.2630 +  /*    matrix :: A pointer to the transformation's 2x2 matrix.  Use~0 for */
379.2631 +  /*              the identity matrix.                                     */
379.2632 +  /*    delta  :: A pointer to the translation vector.  Use~0 for the null */
379.2633 +  /*              vector.                                                  */
379.2634 +  /*                                                                       */
379.2635 +  /* <Note>                                                                */
379.2636 +  /*    The transformation is only applied to scalable image formats after */
379.2637 +  /*    the glyph has been loaded.  It means that hinting is unaltered by  */
379.2638 +  /*    the transformation and is performed on the character size given in */
379.2639 +  /*    the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes.         */
379.2640 +  /*                                                                       */
379.2641 +  /*    Note that this also transforms the `face.glyph.advance' field, but */
379.2642 +  /*    *not* the values in `face.glyph.metrics'.                          */
379.2643 +  /*                                                                       */
379.2644 +  FT_EXPORT( void )
379.2645 +  FT_Set_Transform( FT_Face     face,
379.2646 +                    FT_Matrix*  matrix,
379.2647 +                    FT_Vector*  delta );
379.2648 +
379.2649 +
379.2650 +  /*************************************************************************/
379.2651 +  /*                                                                       */
379.2652 +  /* <Enum>                                                                */
379.2653 +  /*    FT_Render_Mode                                                     */
379.2654 +  /*                                                                       */
379.2655 +  /* <Description>                                                         */
379.2656 +  /*    An enumeration type that lists the render modes supported by       */
379.2657 +  /*    FreeType~2.  Each mode corresponds to a specific type of scanline  */
379.2658 +  /*    conversion performed on the outline.                               */
379.2659 +  /*                                                                       */
379.2660 +  /*    For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode'     */
379.2661 +  /*    field in the @FT_GlyphSlotRec structure gives the format of the    */
379.2662 +  /*    returned bitmap.                                                   */
379.2663 +  /*                                                                       */
379.2664 +  /*    All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity.   */
379.2665 +  /*                                                                       */
379.2666 +  /* <Values>                                                              */
379.2667 +  /*    FT_RENDER_MODE_NORMAL ::                                           */
379.2668 +  /*      This is the default render mode; it corresponds to 8-bit         */
379.2669 +  /*      anti-aliased bitmaps.                                            */
379.2670 +  /*                                                                       */
379.2671 +  /*    FT_RENDER_MODE_LIGHT ::                                            */
379.2672 +  /*      This is equivalent to @FT_RENDER_MODE_NORMAL.  It is only        */
379.2673 +  /*      defined as a separate value because render modes are also used   */
379.2674 +  /*      indirectly to define hinting algorithm selectors.  See           */
379.2675 +  /*      @FT_LOAD_TARGET_XXX for details.                                 */
379.2676 +  /*                                                                       */
379.2677 +  /*    FT_RENDER_MODE_MONO ::                                             */
379.2678 +  /*      This mode corresponds to 1-bit bitmaps (with 2~levels of         */
379.2679 +  /*      opacity).                                                        */
379.2680 +  /*                                                                       */
379.2681 +  /*    FT_RENDER_MODE_LCD ::                                              */
379.2682 +  /*      This mode corresponds to horizontal RGB and BGR sub-pixel        */
379.2683 +  /*      displays like LCD screens.  It produces 8-bit bitmaps that are   */
379.2684 +  /*      3~times the width of the original glyph outline in pixels, and   */
379.2685 +  /*      which use the @FT_PIXEL_MODE_LCD mode.                           */
379.2686 +  /*                                                                       */
379.2687 +  /*    FT_RENDER_MODE_LCD_V ::                                            */
379.2688 +  /*      This mode corresponds to vertical RGB and BGR sub-pixel displays */
379.2689 +  /*      (like PDA screens, rotated LCD displays, etc.).  It produces     */
379.2690 +  /*      8-bit bitmaps that are 3~times the height of the original        */
379.2691 +  /*      glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode.   */
379.2692 +  /*                                                                       */
379.2693 +  /* <Note>                                                                */
379.2694 +  /*    The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */
379.2695 +  /*    filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */
379.2696 +  /*    (not active in the default builds).  It is up to the caller to     */
379.2697 +  /*    either call @FT_Library_SetLcdFilter (if available) or do the      */
379.2698 +  /*    filtering itself.                                                  */
379.2699 +  /*                                                                       */
379.2700 +  /*    The selected render mode only affects vector glyphs of a font.     */
379.2701 +  /*    Embedded bitmaps often have a different pixel mode like            */
379.2702 +  /*    @FT_PIXEL_MODE_MONO.  You can use @FT_Bitmap_Convert to transform  */
379.2703 +  /*    them into 8-bit pixmaps.                                           */
379.2704 +  /*                                                                       */
379.2705 +  typedef enum  FT_Render_Mode_
379.2706 +  {
379.2707 +    FT_RENDER_MODE_NORMAL = 0,
379.2708 +    FT_RENDER_MODE_LIGHT,
379.2709 +    FT_RENDER_MODE_MONO,
379.2710 +    FT_RENDER_MODE_LCD,
379.2711 +    FT_RENDER_MODE_LCD_V,
379.2712 +
379.2713 +    FT_RENDER_MODE_MAX
379.2714 +
379.2715 +  } FT_Render_Mode;
379.2716 +
379.2717 +
379.2718 +  /*************************************************************************/
379.2719 +  /*                                                                       */
379.2720 +  /* <Enum>                                                                */
379.2721 +  /*    ft_render_mode_xxx                                                 */
379.2722 +  /*                                                                       */
379.2723 +  /* <Description>                                                         */
379.2724 +  /*    These constants are deprecated.  Use the corresponding             */
379.2725 +  /*    @FT_Render_Mode values instead.                                    */
379.2726 +  /*                                                                       */
379.2727 +  /* <Values>                                                              */
379.2728 +  /*    ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL                */
379.2729 +  /*    ft_render_mode_mono   :: see @FT_RENDER_MODE_MONO                  */
379.2730 +  /*                                                                       */
379.2731 +#define ft_render_mode_normal  FT_RENDER_MODE_NORMAL
379.2732 +#define ft_render_mode_mono    FT_RENDER_MODE_MONO
379.2733 +
379.2734 +
379.2735 +  /*************************************************************************/
379.2736 +  /*                                                                       */
379.2737 +  /* <Function>                                                            */
379.2738 +  /*    FT_Render_Glyph                                                    */
379.2739 +  /*                                                                       */
379.2740 +  /* <Description>                                                         */
379.2741 +  /*    Convert a given glyph image to a bitmap.  It does so by inspecting */
379.2742 +  /*    the glyph image format, finding the relevant renderer, and         */
379.2743 +  /*    invoking it.                                                       */
379.2744 +  /*                                                                       */
379.2745 +  /* <InOut>                                                               */
379.2746 +  /*    slot        :: A handle to the glyph slot containing the image to  */
379.2747 +  /*                   convert.                                            */
379.2748 +  /*                                                                       */
379.2749 +  /* <Input>                                                               */
379.2750 +  /*    render_mode :: This is the render mode used to render the glyph    */
379.2751 +  /*                   image into a bitmap.  See @FT_Render_Mode for a     */
379.2752 +  /*                   list of possible values.                            */
379.2753 +  /*                                                                       */
379.2754 +  /* <Return>                                                              */
379.2755 +  /*    FreeType error code.  0~means success.                             */
379.2756 +  /*                                                                       */
379.2757 +  FT_EXPORT( FT_Error )
379.2758 +  FT_Render_Glyph( FT_GlyphSlot    slot,
379.2759 +                   FT_Render_Mode  render_mode );
379.2760 +
379.2761 +
379.2762 +  /*************************************************************************/
379.2763 +  /*                                                                       */
379.2764 +  /* <Enum>                                                                */
379.2765 +  /*    FT_Kerning_Mode                                                    */
379.2766 +  /*                                                                       */
379.2767 +  /* <Description>                                                         */
379.2768 +  /*    An enumeration used to specify which kerning values to return in   */
379.2769 +  /*    @FT_Get_Kerning.                                                   */
379.2770 +  /*                                                                       */
379.2771 +  /* <Values>                                                              */
379.2772 +  /*    FT_KERNING_DEFAULT  :: Return scaled and grid-fitted kerning       */
379.2773 +  /*                           distances (value is~0).                     */
379.2774 +  /*                                                                       */
379.2775 +  /*    FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning    */
379.2776 +  /*                           distances.                                  */
379.2777 +  /*                                                                       */
379.2778 +  /*    FT_KERNING_UNSCALED :: Return the kerning vector in original font  */
379.2779 +  /*                           units.                                      */
379.2780 +  /*                                                                       */
379.2781 +  typedef enum  FT_Kerning_Mode_
379.2782 +  {
379.2783 +    FT_KERNING_DEFAULT  = 0,
379.2784 +    FT_KERNING_UNFITTED,
379.2785 +    FT_KERNING_UNSCALED
379.2786 +
379.2787 +  } FT_Kerning_Mode;
379.2788 +
379.2789 +
379.2790 +  /*************************************************************************/
379.2791 +  /*                                                                       */
379.2792 +  /* <Const>                                                               */
379.2793 +  /*    ft_kerning_default                                                 */
379.2794 +  /*                                                                       */
379.2795 +  /* <Description>                                                         */
379.2796 +  /*    This constant is deprecated.  Please use @FT_KERNING_DEFAULT       */
379.2797 +  /*    instead.                                                           */
379.2798 +  /*                                                                       */
379.2799 +#define ft_kerning_default   FT_KERNING_DEFAULT
379.2800 +
379.2801 +
379.2802 +  /*************************************************************************/
379.2803 +  /*                                                                       */
379.2804 +  /* <Const>                                                               */
379.2805 +  /*    ft_kerning_unfitted                                                */
379.2806 +  /*                                                                       */
379.2807 +  /* <Description>                                                         */
379.2808 +  /*    This constant is deprecated.  Please use @FT_KERNING_UNFITTED      */
379.2809 +  /*    instead.                                                           */
379.2810 +  /*                                                                       */
379.2811 +#define ft_kerning_unfitted  FT_KERNING_UNFITTED
379.2812 +
379.2813 +
379.2814 +  /*************************************************************************/
379.2815 +  /*                                                                       */
379.2816 +  /* <Const>                                                               */
379.2817 +  /*    ft_kerning_unscaled                                                */
379.2818 +  /*                                                                       */
379.2819 +  /* <Description>                                                         */
379.2820 +  /*    This constant is deprecated.  Please use @FT_KERNING_UNSCALED      */
379.2821 +  /*    instead.                                                           */
379.2822 +  /*                                                                       */
379.2823 +#define ft_kerning_unscaled  FT_KERNING_UNSCALED
379.2824 +
379.2825 +
379.2826 +  /*************************************************************************/
379.2827 +  /*                                                                       */
379.2828 +  /* <Function>                                                            */
379.2829 +  /*    FT_Get_Kerning                                                     */
379.2830 +  /*                                                                       */
379.2831 +  /* <Description>                                                         */
379.2832 +  /*    Return the kerning vector between two glyphs of a same face.       */
379.2833 +  /*                                                                       */
379.2834 +  /* <Input>                                                               */
379.2835 +  /*    face        :: A handle to a source face object.                   */
379.2836 +  /*                                                                       */
379.2837 +  /*    left_glyph  :: The index of the left glyph in the kern pair.       */
379.2838 +  /*                                                                       */
379.2839 +  /*    right_glyph :: The index of the right glyph in the kern pair.      */
379.2840 +  /*                                                                       */
379.2841 +  /*    kern_mode   :: See @FT_Kerning_Mode for more information.          */
379.2842 +  /*                   Determines the scale and dimension of the returned  */
379.2843 +  /*                   kerning vector.                                     */
379.2844 +  /*                                                                       */
379.2845 +  /* <Output>                                                              */
379.2846 +  /*    akerning    :: The kerning vector.  This is either in font units   */
379.2847 +  /*                   or in pixels (26.6 format) for scalable formats,    */
379.2848 +  /*                   and in pixels for fixed-sizes formats.              */
379.2849 +  /*                                                                       */
379.2850 +  /* <Return>                                                              */
379.2851 +  /*    FreeType error code.  0~means success.                             */
379.2852 +  /*                                                                       */
379.2853 +  /* <Note>                                                                */
379.2854 +  /*    Only horizontal layouts (left-to-right & right-to-left) are        */
379.2855 +  /*    supported by this method.  Other layouts, or more sophisticated    */
379.2856 +  /*    kernings, are out of the scope of this API function -- they can be */
379.2857 +  /*    implemented through format-specific interfaces.                    */
379.2858 +  /*                                                                       */
379.2859 +  FT_EXPORT( FT_Error )
379.2860 +  FT_Get_Kerning( FT_Face     face,
379.2861 +                  FT_UInt     left_glyph,
379.2862 +                  FT_UInt     right_glyph,
379.2863 +                  FT_UInt     kern_mode,
379.2864 +                  FT_Vector  *akerning );
379.2865 +
379.2866 +
379.2867 +  /*************************************************************************/
379.2868 +  /*                                                                       */
379.2869 +  /* <Function>                                                            */
379.2870 +  /*    FT_Get_Track_Kerning                                               */
379.2871 +  /*                                                                       */
379.2872 +  /* <Description>                                                         */
379.2873 +  /*    Return the track kerning for a given face object at a given size.  */
379.2874 +  /*                                                                       */
379.2875 +  /* <Input>                                                               */
379.2876 +  /*    face       :: A handle to a source face object.                    */
379.2877 +  /*                                                                       */
379.2878 +  /*    point_size :: The point size in 16.16 fractional points.           */
379.2879 +  /*                                                                       */
379.2880 +  /*    degree     :: The degree of tightness.                             */
379.2881 +  /*                                                                       */
379.2882 +  /* <Output>                                                              */
379.2883 +  /*    akerning   :: The kerning in 16.16 fractional points.              */
379.2884 +  /*                                                                       */
379.2885 +  /* <Return>                                                              */
379.2886 +  /*    FreeType error code.  0~means success.                             */
379.2887 +  /*                                                                       */
379.2888 +  FT_EXPORT( FT_Error )
379.2889 +  FT_Get_Track_Kerning( FT_Face    face,
379.2890 +                        FT_Fixed   point_size,
379.2891 +                        FT_Int     degree,
379.2892 +                        FT_Fixed*  akerning );
379.2893 +
379.2894 +
379.2895 +  /*************************************************************************/
379.2896 +  /*                                                                       */
379.2897 +  /* <Function>                                                            */
379.2898 +  /*    FT_Get_Glyph_Name                                                  */
379.2899 +  /*                                                                       */
379.2900 +  /* <Description>                                                         */
379.2901 +  /*    Retrieve the ASCII name of a given glyph in a face.  This only     */
379.2902 +  /*    works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1.   */
379.2903 +  /*                                                                       */
379.2904 +  /* <Input>                                                               */
379.2905 +  /*    face        :: A handle to a source face object.                   */
379.2906 +  /*                                                                       */
379.2907 +  /*    glyph_index :: The glyph index.                                    */
379.2908 +  /*                                                                       */
379.2909 +  /*    buffer_max  :: The maximal number of bytes available in the        */
379.2910 +  /*                   buffer.                                             */
379.2911 +  /*                                                                       */
379.2912 +  /* <Output>                                                              */
379.2913 +  /*    buffer      :: A pointer to a target buffer where the name is      */
379.2914 +  /*                   copied to.                                          */
379.2915 +  /*                                                                       */
379.2916 +  /* <Return>                                                              */
379.2917 +  /*    FreeType error code.  0~means success.                             */
379.2918 +  /*                                                                       */
379.2919 +  /* <Note>                                                                */
379.2920 +  /*    An error is returned if the face doesn't provide glyph names or if */
379.2921 +  /*    the glyph index is invalid.  In all cases of failure, the first    */
379.2922 +  /*    byte of `buffer' is set to~0 to indicate an empty name.            */
379.2923 +  /*                                                                       */
379.2924 +  /*    The glyph name is truncated to fit within the buffer if it is too  */
379.2925 +  /*    long.  The returned string is always zero-terminated.              */
379.2926 +  /*                                                                       */
379.2927 +  /*    This function is not compiled within the library if the config     */
379.2928 +  /*    macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in              */
379.2929 +  /*    `include/freetype/config/ftoptions.h'.                             */
379.2930 +  /*                                                                       */
379.2931 +  FT_EXPORT( FT_Error )
379.2932 +  FT_Get_Glyph_Name( FT_Face     face,
379.2933 +                     FT_UInt     glyph_index,
379.2934 +                     FT_Pointer  buffer,
379.2935 +                     FT_UInt     buffer_max );
379.2936 +
379.2937 +
379.2938 +  /*************************************************************************/
379.2939 +  /*                                                                       */
379.2940 +  /* <Function>                                                            */
379.2941 +  /*    FT_Get_Postscript_Name                                             */
379.2942 +  /*                                                                       */
379.2943 +  /* <Description>                                                         */
379.2944 +  /*    Retrieve the ASCII PostScript name of a given face, if available.  */
379.2945 +  /*    This only works with PostScript and TrueType fonts.                */
379.2946 +  /*                                                                       */
379.2947 +  /* <Input>                                                               */
379.2948 +  /*    face :: A handle to the source face object.                        */
379.2949 +  /*                                                                       */
379.2950 +  /* <Return>                                                              */
379.2951 +  /*    A pointer to the face's PostScript name.  NULL if unavailable.     */
379.2952 +  /*                                                                       */
379.2953 +  /* <Note>                                                                */
379.2954 +  /*    The returned pointer is owned by the face and is destroyed with    */
379.2955 +  /*    it.                                                                */
379.2956 +  /*                                                                       */
379.2957 +  FT_EXPORT( const char* )
379.2958 +  FT_Get_Postscript_Name( FT_Face  face );
379.2959 +
379.2960 +
379.2961 +  /*************************************************************************/
379.2962 +  /*                                                                       */
379.2963 +  /* <Function>                                                            */
379.2964 +  /*    FT_Select_Charmap                                                  */
379.2965 +  /*                                                                       */
379.2966 +  /* <Description>                                                         */
379.2967 +  /*    Select a given charmap by its encoding tag (as listed in           */
379.2968 +  /*    `freetype.h').                                                     */
379.2969 +  /*                                                                       */
379.2970 +  /* <InOut>                                                               */
379.2971 +  /*    face     :: A handle to the source face object.                    */
379.2972 +  /*                                                                       */
379.2973 +  /* <Input>                                                               */
379.2974 +  /*    encoding :: A handle to the selected encoding.                     */
379.2975 +  /*                                                                       */
379.2976 +  /* <Return>                                                              */
379.2977 +  /*    FreeType error code.  0~means success.                             */
379.2978 +  /*                                                                       */
379.2979 +  /* <Note>                                                                */
379.2980 +  /*    This function returns an error if no charmap in the face           */
379.2981 +  /*    corresponds to the encoding queried here.                          */
379.2982 +  /*                                                                       */
379.2983 +  /*    Because many fonts contain more than a single cmap for Unicode     */
379.2984 +  /*    encoding, this function has some special code to select the one    */
379.2985 +  /*    which covers Unicode best (`best' in the sense that a UCS-4 cmap   */
379.2986 +  /*    is preferred to a UCS-2 cmap).  It is thus preferable to           */
379.2987 +  /*    @FT_Set_Charmap in this case.                                      */
379.2988 +  /*                                                                       */
379.2989 +  FT_EXPORT( FT_Error )
379.2990 +  FT_Select_Charmap( FT_Face      face,
379.2991 +                     FT_Encoding  encoding );
379.2992 +
379.2993 +
379.2994 +  /*************************************************************************/
379.2995 +  /*                                                                       */
379.2996 +  /* <Function>                                                            */
379.2997 +  /*    FT_Set_Charmap                                                     */
379.2998 +  /*                                                                       */
379.2999 +  /* <Description>                                                         */
379.3000 +  /*    Select a given charmap for character code to glyph index mapping.  */
379.3001 +  /*                                                                       */
379.3002 +  /* <InOut>                                                               */
379.3003 +  /*    face    :: A handle to the source face object.                     */
379.3004 +  /*                                                                       */
379.3005 +  /* <Input>                                                               */
379.3006 +  /*    charmap :: A handle to the selected charmap.                       */
379.3007 +  /*                                                                       */
379.3008 +  /* <Return>                                                              */
379.3009 +  /*    FreeType error code.  0~means success.                             */
379.3010 +  /*                                                                       */
379.3011 +  /* <Note>                                                                */
379.3012 +  /*    This function returns an error if the charmap is not part of       */
379.3013 +  /*    the face (i.e., if it is not listed in the `face->charmaps'        */
379.3014 +  /*    table).                                                            */
379.3015 +  /*                                                                       */
379.3016 +  /*    It also fails if a type~14 charmap is selected.                    */
379.3017 +  /*                                                                       */
379.3018 +  FT_EXPORT( FT_Error )
379.3019 +  FT_Set_Charmap( FT_Face     face,
379.3020 +                  FT_CharMap  charmap );
379.3021 +
379.3022 +
379.3023 +  /*************************************************************************
379.3024 +   *
379.3025 +   * @function:
379.3026 +   *   FT_Get_Charmap_Index
379.3027 +   *
379.3028 +   * @description:
379.3029 +   *   Retrieve index of a given charmap.
379.3030 +   *
379.3031 +   * @input:
379.3032 +   *   charmap ::
379.3033 +   *     A handle to a charmap.
379.3034 +   *
379.3035 +   * @return:
379.3036 +   *   The index into the array of character maps within the face to which
379.3037 +   *   `charmap' belongs.  If an error occurs, -1 is returned.
379.3038 +   *
379.3039 +   */
379.3040 +  FT_EXPORT( FT_Int )
379.3041 +  FT_Get_Charmap_Index( FT_CharMap  charmap );
379.3042 +
379.3043 +
379.3044 +  /*************************************************************************/
379.3045 +  /*                                                                       */
379.3046 +  /* <Function>                                                            */
379.3047 +  /*    FT_Get_Char_Index                                                  */
379.3048 +  /*                                                                       */
379.3049 +  /* <Description>                                                         */
379.3050 +  /*    Return the glyph index of a given character code.  This function   */
379.3051 +  /*    uses a charmap object to do the mapping.                           */
379.3052 +  /*                                                                       */
379.3053 +  /* <Input>                                                               */
379.3054 +  /*    face     :: A handle to the source face object.                    */
379.3055 +  /*                                                                       */
379.3056 +  /*    charcode :: The character code.                                    */
379.3057 +  /*                                                                       */
379.3058 +  /* <Return>                                                              */
379.3059 +  /*    The glyph index.  0~means `undefined character code'.              */
379.3060 +  /*                                                                       */
379.3061 +  /* <Note>                                                                */
379.3062 +  /*    If you use FreeType to manipulate the contents of font files       */
379.3063 +  /*    directly, be aware that the glyph index returned by this function  */
379.3064 +  /*    doesn't always correspond to the internal indices used within      */
379.3065 +  /*    the file.  This is done to ensure that value~0 always corresponds  */
379.3066 +  /*    to the `missing glyph'.                                            */
379.3067 +  /*                                                                       */
379.3068 +  FT_EXPORT( FT_UInt )
379.3069 +  FT_Get_Char_Index( FT_Face   face,
379.3070 +                     FT_ULong  charcode );
379.3071 +
379.3072 +
379.3073 +  /*************************************************************************/
379.3074 +  /*                                                                       */
379.3075 +  /* <Function>                                                            */
379.3076 +  /*    FT_Get_First_Char                                                  */
379.3077 +  /*                                                                       */
379.3078 +  /* <Description>                                                         */
379.3079 +  /*    This function is used to return the first character code in the    */
379.3080 +  /*    current charmap of a given face.  It also returns the              */
379.3081 +  /*    corresponding glyph index.                                         */
379.3082 +  /*                                                                       */
379.3083 +  /* <Input>                                                               */
379.3084 +  /*    face    :: A handle to the source face object.                     */
379.3085 +  /*                                                                       */
379.3086 +  /* <Output>                                                              */
379.3087 +  /*    agindex :: Glyph index of first character code.  0~if charmap is   */
379.3088 +  /*               empty.                                                  */
379.3089 +  /*                                                                       */
379.3090 +  /* <Return>                                                              */
379.3091 +  /*    The charmap's first character code.                                */
379.3092 +  /*                                                                       */
379.3093 +  /* <Note>                                                                */
379.3094 +  /*    You should use this function with @FT_Get_Next_Char to be able to  */
379.3095 +  /*    parse all character codes available in a given charmap.  The code  */
379.3096 +  /*    should look like this:                                             */
379.3097 +  /*                                                                       */
379.3098 +  /*    {                                                                  */
379.3099 +  /*      FT_ULong  charcode;                                              */
379.3100 +  /*      FT_UInt   gindex;                                                */
379.3101 +  /*                                                                       */
379.3102 +  /*                                                                       */
379.3103 +  /*      charcode = FT_Get_First_Char( face, &gindex );                   */
379.3104 +  /*      while ( gindex != 0 )                                            */
379.3105 +  /*      {                                                                */
379.3106 +  /*        ... do something with (charcode,gindex) pair ...               */
379.3107 +  /*                                                                       */
379.3108 +  /*        charcode = FT_Get_Next_Char( face, charcode, &gindex );        */
379.3109 +  /*      }                                                                */
379.3110 +  /*    }                                                                  */
379.3111 +  /*                                                                       */
379.3112 +  /*    Note that `*agindex' is set to~0 if the charmap is empty.  The     */
379.3113 +  /*    result itself can be~0 in two cases: if the charmap is empty or    */
379.3114 +  /*    if the value~0 is the first valid character code.                  */
379.3115 +  /*                                                                       */
379.3116 +  FT_EXPORT( FT_ULong )
379.3117 +  FT_Get_First_Char( FT_Face   face,
379.3118 +                     FT_UInt  *agindex );
379.3119 +
379.3120 +
379.3121 +  /*************************************************************************/
379.3122 +  /*                                                                       */
379.3123 +  /* <Function>                                                            */
379.3124 +  /*    FT_Get_Next_Char                                                   */
379.3125 +  /*                                                                       */
379.3126 +  /* <Description>                                                         */
379.3127 +  /*    This function is used to return the next character code in the     */
379.3128 +  /*    current charmap of a given face following the value `char_code',   */
379.3129 +  /*    as well as the corresponding glyph index.                          */
379.3130 +  /*                                                                       */
379.3131 +  /* <Input>                                                               */
379.3132 +  /*    face      :: A handle to the source face object.                   */
379.3133 +  /*    char_code :: The starting character code.                          */
379.3134 +  /*                                                                       */
379.3135 +  /* <Output>                                                              */
379.3136 +  /*    agindex   :: Glyph index of next character code.  0~if charmap     */
379.3137 +  /*                 is empty.                                             */
379.3138 +  /*                                                                       */
379.3139 +  /* <Return>                                                              */
379.3140 +  /*    The charmap's next character code.                                 */
379.3141 +  /*                                                                       */
379.3142 +  /* <Note>                                                                */
379.3143 +  /*    You should use this function with @FT_Get_First_Char to walk       */
379.3144 +  /*    over all character codes available in a given charmap.  See the    */
379.3145 +  /*    note for this function for a simple code example.                  */
379.3146 +  /*                                                                       */
379.3147 +  /*    Note that `*agindex' is set to~0 when there are no more codes in   */
379.3148 +  /*    the charmap.                                                       */
379.3149 +  /*                                                                       */
379.3150 +  FT_EXPORT( FT_ULong )
379.3151 +  FT_Get_Next_Char( FT_Face    face,
379.3152 +                    FT_ULong   char_code,
379.3153 +                    FT_UInt   *agindex );
379.3154 +
379.3155 +
379.3156 +  /*************************************************************************/
379.3157 +  /*                                                                       */
379.3158 +  /* <Function>                                                            */
379.3159 +  /*    FT_Get_Name_Index                                                  */
379.3160 +  /*                                                                       */
379.3161 +  /* <Description>                                                         */
379.3162 +  /*    Return the glyph index of a given glyph name.  This function uses  */
379.3163 +  /*    driver specific objects to do the translation.                     */
379.3164 +  /*                                                                       */
379.3165 +  /* <Input>                                                               */
379.3166 +  /*    face       :: A handle to the source face object.                  */
379.3167 +  /*                                                                       */
379.3168 +  /*    glyph_name :: The glyph name.                                      */
379.3169 +  /*                                                                       */
379.3170 +  /* <Return>                                                              */
379.3171 +  /*    The glyph index.  0~means `undefined character code'.              */
379.3172 +  /*                                                                       */
379.3173 +  FT_EXPORT( FT_UInt )
379.3174 +  FT_Get_Name_Index( FT_Face     face,
379.3175 +                     FT_String*  glyph_name );
379.3176 +
379.3177 +
379.3178 +  /*************************************************************************
379.3179 +   *
379.3180 +   * @macro:
379.3181 +   *   FT_SUBGLYPH_FLAG_XXX
379.3182 +   *
379.3183 +   * @description:
379.3184 +   *   A list of constants used to describe subglyphs.  Please refer to the
379.3185 +   *   TrueType specification for the meaning of the various flags.
379.3186 +   *
379.3187 +   * @values:
379.3188 +   *   FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS ::
379.3189 +   *   FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ::
379.3190 +   *   FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID ::
379.3191 +   *   FT_SUBGLYPH_FLAG_SCALE ::
379.3192 +   *   FT_SUBGLYPH_FLAG_XY_SCALE ::
379.3193 +   *   FT_SUBGLYPH_FLAG_2X2 ::
379.3194 +   *   FT_SUBGLYPH_FLAG_USE_MY_METRICS ::
379.3195 +   *
379.3196 +   */
379.3197 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS          1
379.3198 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES      2
379.3199 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID        4
379.3200 +#define FT_SUBGLYPH_FLAG_SCALE                   8
379.3201 +#define FT_SUBGLYPH_FLAG_XY_SCALE             0x40
379.3202 +#define FT_SUBGLYPH_FLAG_2X2                  0x80
379.3203 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS      0x200
379.3204 +
379.3205 +
379.3206 +  /*************************************************************************
379.3207 +   *
379.3208 +   * @func:
379.3209 +   *   FT_Get_SubGlyph_Info
379.3210 +   *
379.3211 +   * @description:
379.3212 +   *   Retrieve a description of a given subglyph.  Only use it if
379.3213 +   *   `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is
379.3214 +   *   returned otherwise.
379.3215 +   *
379.3216 +   * @input:
379.3217 +   *   glyph ::
379.3218 +   *     The source glyph slot.
379.3219 +   *
379.3220 +   *   sub_index ::
379.3221 +   *     The index of the subglyph.  Must be less than
379.3222 +   *     `glyph->num_subglyphs'.
379.3223 +   *
379.3224 +   * @output:
379.3225 +   *   p_index ::
379.3226 +   *     The glyph index of the subglyph.
379.3227 +   *
379.3228 +   *   p_flags ::
379.3229 +   *     The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX.
379.3230 +   *
379.3231 +   *   p_arg1 ::
379.3232 +   *     The subglyph's first argument (if any).
379.3233 +   *
379.3234 +   *   p_arg2 ::
379.3235 +   *     The subglyph's second argument (if any).
379.3236 +   *
379.3237 +   *   p_transform ::
379.3238 +   *     The subglyph transformation (if any).
379.3239 +   *
379.3240 +   * @return:
379.3241 +   *   FreeType error code.  0~means success.
379.3242 +   *
379.3243 +   * @note:
379.3244 +   *   The values of `*p_arg1', `*p_arg2', and `*p_transform' must be
379.3245 +   *   interpreted depending on the flags returned in `*p_flags'.  See the
379.3246 +   *   TrueType specification for details.
379.3247 +   *
379.3248 +   */
379.3249 +  FT_EXPORT( FT_Error )
379.3250 +  FT_Get_SubGlyph_Info( FT_GlyphSlot  glyph,
379.3251 +                        FT_UInt       sub_index,
379.3252 +                        FT_Int       *p_index,
379.3253 +                        FT_UInt      *p_flags,
379.3254 +                        FT_Int       *p_arg1,
379.3255 +                        FT_Int       *p_arg2,
379.3256 +                        FT_Matrix    *p_transform );
379.3257 +
379.3258 +
379.3259 +  /*************************************************************************/
379.3260 +  /*                                                                       */
379.3261 +  /* <Enum>                                                                */
379.3262 +  /*    FT_FSTYPE_XXX                                                      */
379.3263 +  /*                                                                       */
379.3264 +  /* <Description>                                                         */
379.3265 +  /*    A list of bit flags used in the `fsType' field of the OS/2 table   */
379.3266 +  /*    in a TrueType or OpenType font and the `FSType' entry in a         */
379.3267 +  /*    PostScript font.  These bit flags are returned by                  */
379.3268 +  /*    @FT_Get_FSType_Flags; they inform client applications of embedding */
379.3269 +  /*    and subsetting restrictions associated with a font.                */
379.3270 +  /*                                                                       */
379.3271 +  /*    See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for  */
379.3272 +  /*    more details.                                                      */
379.3273 +  /*                                                                       */
379.3274 +  /* <Values>                                                              */
379.3275 +  /*    FT_FSTYPE_INSTALLABLE_EMBEDDING ::                                 */
379.3276 +  /*      Fonts with no fsType bit set may be embedded and permanently     */
379.3277 +  /*      installed on the remote system by an application.                */
379.3278 +  /*                                                                       */
379.3279 +  /*    FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING ::                          */
379.3280 +  /*      Fonts that have only this bit set must not be modified, embedded */
379.3281 +  /*      or exchanged in any manner without first obtaining permission of */
379.3282 +  /*      the font software copyright owner.                               */
379.3283 +  /*                                                                       */
379.3284 +  /*    FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING ::                           */
379.3285 +  /*      If this bit is set, the font may be embedded and temporarily     */
379.3286 +  /*      loaded on the remote system.  Documents containing Preview &     */
379.3287 +  /*      Print fonts must be opened `read-only'; no edits can be applied  */
379.3288 +  /*      to the document.                                                 */
379.3289 +  /*                                                                       */
379.3290 +  /*    FT_FSTYPE_EDITABLE_EMBEDDING ::                                    */
379.3291 +  /*      If this bit is set, the font may be embedded but must only be    */
379.3292 +  /*      installed temporarily on other systems.  In contrast to Preview  */
379.3293 +  /*      & Print fonts, documents containing editable fonts may be opened */
379.3294 +  /*      for reading, editing is permitted, and changes may be saved.     */
379.3295 +  /*                                                                       */
379.3296 +  /*    FT_FSTYPE_NO_SUBSETTING ::                                         */
379.3297 +  /*      If this bit is set, the font may not be subsetted prior to       */
379.3298 +  /*      embedding.                                                       */
379.3299 +  /*                                                                       */
379.3300 +  /*    FT_FSTYPE_BITMAP_EMBEDDING_ONLY ::                                 */
379.3301 +  /*      If this bit is set, only bitmaps contained in the font may be    */
379.3302 +  /*      embedded; no outline data may be embedded.  If there are no      */
379.3303 +  /*      bitmaps available in the font, then the font is unembeddable.    */
379.3304 +  /*                                                                       */
379.3305 +  /* <Note>                                                                */
379.3306 +  /*    While the fsType flags can indicate that a font may be embedded, a */
379.3307 +  /*    license with the font vendor may be separately required to use the */
379.3308 +  /*    font in this way.                                                  */
379.3309 +  /*                                                                       */
379.3310 +#define FT_FSTYPE_INSTALLABLE_EMBEDDING         0x0000
379.3311 +#define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING  0x0002
379.3312 +#define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING   0x0004
379.3313 +#define FT_FSTYPE_EDITABLE_EMBEDDING            0x0008
379.3314 +#define FT_FSTYPE_NO_SUBSETTING                 0x0100
379.3315 +#define FT_FSTYPE_BITMAP_EMBEDDING_ONLY         0x0200
379.3316 +
379.3317 +
379.3318 +  /*************************************************************************/
379.3319 +  /*                                                                       */
379.3320 +  /* <Function>                                                            */
379.3321 +  /*    FT_Get_FSType_Flags                                                */
379.3322 +  /*                                                                       */
379.3323 +  /* <Description>                                                         */
379.3324 +  /*    Return the fsType flags for a font.                                */
379.3325 +  /*                                                                       */
379.3326 +  /* <Input>                                                               */
379.3327 +  /*    face :: A handle to the source face object.                        */
379.3328 +  /*                                                                       */
379.3329 +  /* <Return>                                                              */
379.3330 +  /*    The fsType flags, @FT_FSTYPE_XXX.                                  */
379.3331 +  /*                                                                       */
379.3332 +  /* <Note>                                                                */
379.3333 +  /*    Use this function rather than directly reading the `fs_type' field */
379.3334 +  /*    in the @PS_FontInfoRec structure which is only guaranteed to       */
379.3335 +  /*    return the correct results for Type~1 fonts.                       */
379.3336 +  /*                                                                       */
379.3337 +  FT_EXPORT( FT_UShort )
379.3338 +  FT_Get_FSType_Flags( FT_Face  face );
379.3339 +
379.3340 +
379.3341 +  /*************************************************************************/
379.3342 +  /*                                                                       */
379.3343 +  /* <Section>                                                             */
379.3344 +  /*    glyph_variants                                                     */
379.3345 +  /*                                                                       */
379.3346 +  /* <Title>                                                               */
379.3347 +  /*    Glyph Variants                                                     */
379.3348 +  /*                                                                       */
379.3349 +  /* <Abstract>                                                            */
379.3350 +  /*    The FreeType~2 interface to Unicode Ideographic Variation          */
379.3351 +  /*    Sequences (IVS), using the SFNT cmap format~14.                    */
379.3352 +  /*                                                                       */
379.3353 +  /* <Description>                                                         */
379.3354 +  /*    Many CJK characters have variant forms.  They are a sort of grey   */
379.3355 +  /*    area somewhere between being totally irrelevant and semantically   */
379.3356 +  /*    distinct; for this reason, the Unicode consortium decided to       */
379.3357 +  /*    introduce Ideographic Variation Sequences (IVS), consisting of a   */
379.3358 +  /*    Unicode base character and one of 240 variant selectors            */
379.3359 +  /*    (U+E0100-U+E01EF), instead of further extending the already huge   */
379.3360 +  /*    code range for CJK characters.                                     */
379.3361 +  /*                                                                       */
379.3362 +  /*    An IVS is registered and unique; for further details please refer  */
379.3363 +  /*    to Unicode Technical Report #37, the Ideographic Variation         */
379.3364 +  /*    Database.  To date (October 2007), the character with the most     */
379.3365 +  /*    variants is U+908A, having 8~such IVS.                             */
379.3366 +  /*                                                                       */
379.3367 +  /*    Adobe and MS decided to support IVS with a new cmap subtable       */
379.3368 +  /*    (format~14).  It is an odd subtable because it is not a mapping of */
379.3369 +  /*    input code points to glyphs, but contains lists of all variants    */
379.3370 +  /*    supported by the font.                                             */
379.3371 +  /*                                                                       */
379.3372 +  /*    A variant may be either `default' or `non-default'.  A default     */
379.3373 +  /*    variant is the one you will get for that code point if you look it */
379.3374 +  /*    up in the standard Unicode cmap.  A non-default variant is a       */
379.3375 +  /*    different glyph.                                                   */
379.3376 +  /*                                                                       */
379.3377 +  /*************************************************************************/
379.3378 +
379.3379 +
379.3380 +  /*************************************************************************/
379.3381 +  /*                                                                       */
379.3382 +  /* <Function>                                                            */
379.3383 +  /*    FT_Face_GetCharVariantIndex                                        */
379.3384 +  /*                                                                       */
379.3385 +  /* <Description>                                                         */
379.3386 +  /*    Return the glyph index of a given character code as modified by    */
379.3387 +  /*    the variation selector.                                            */
379.3388 +  /*                                                                       */
379.3389 +  /* <Input>                                                               */
379.3390 +  /*    face ::                                                            */
379.3391 +  /*      A handle to the source face object.                              */
379.3392 +  /*                                                                       */
379.3393 +  /*    charcode ::                                                        */
379.3394 +  /*      The character code point in Unicode.                             */
379.3395 +  /*                                                                       */
379.3396 +  /*    variantSelector ::                                                 */
379.3397 +  /*      The Unicode code point of the variation selector.                */
379.3398 +  /*                                                                       */
379.3399 +  /* <Return>                                                              */
379.3400 +  /*    The glyph index.  0~means either `undefined character code', or    */
379.3401 +  /*    `undefined selector code', or `no variation selector cmap          */
379.3402 +  /*    subtable', or `current CharMap is not Unicode'.                    */
379.3403 +  /*                                                                       */
379.3404 +  /* <Note>                                                                */
379.3405 +  /*    If you use FreeType to manipulate the contents of font files       */
379.3406 +  /*    directly, be aware that the glyph index returned by this function  */
379.3407 +  /*    doesn't always correspond to the internal indices used within      */
379.3408 +  /*    the file.  This is done to ensure that value~0 always corresponds  */
379.3409 +  /*    to the `missing glyph'.                                            */
379.3410 +  /*                                                                       */
379.3411 +  /*    This function is only meaningful if                                */
379.3412 +  /*      a) the font has a variation selector cmap sub table,             */
379.3413 +  /*    and                                                                */
379.3414 +  /*      b) the current charmap has a Unicode encoding.                   */
379.3415 +  /*                                                                       */
379.3416 +  /* <Since>                                                               */
379.3417 +  /*    2.3.6                                                              */
379.3418 +  /*                                                                       */
379.3419 +  FT_EXPORT( FT_UInt )
379.3420 +  FT_Face_GetCharVariantIndex( FT_Face   face,
379.3421 +                               FT_ULong  charcode,
379.3422 +                               FT_ULong  variantSelector );
379.3423 +
379.3424 +
379.3425 +  /*************************************************************************/
379.3426 +  /*                                                                       */
379.3427 +  /* <Function>                                                            */
379.3428 +  /*    FT_Face_GetCharVariantIsDefault                                    */
379.3429 +  /*                                                                       */
379.3430 +  /* <Description>                                                         */
379.3431 +  /*    Check whether this variant of this Unicode character is the one to */
379.3432 +  /*    be found in the `cmap'.                                            */
379.3433 +  /*                                                                       */
379.3434 +  /* <Input>                                                               */
379.3435 +  /*    face ::                                                            */
379.3436 +  /*      A handle to the source face object.                              */
379.3437 +  /*                                                                       */
379.3438 +  /*    charcode ::                                                        */
379.3439 +  /*      The character codepoint in Unicode.                              */
379.3440 +  /*                                                                       */
379.3441 +  /*    variantSelector ::                                                 */
379.3442 +  /*      The Unicode codepoint of the variation selector.                 */
379.3443 +  /*                                                                       */
379.3444 +  /* <Return>                                                              */
379.3445 +  /*    1~if found in the standard (Unicode) cmap, 0~if found in the       */
379.3446 +  /*    variation selector cmap, or -1 if it is not a variant.             */
379.3447 +  /*                                                                       */
379.3448 +  /* <Note>                                                                */
379.3449 +  /*    This function is only meaningful if the font has a variation       */
379.3450 +  /*    selector cmap subtable.                                            */
379.3451 +  /*                                                                       */
379.3452 +  /* <Since>                                                               */
379.3453 +  /*    2.3.6                                                              */
379.3454 +  /*                                                                       */
379.3455 +  FT_EXPORT( FT_Int )
379.3456 +  FT_Face_GetCharVariantIsDefault( FT_Face   face,
379.3457 +                                   FT_ULong  charcode,
379.3458 +                                   FT_ULong  variantSelector );
379.3459 +
379.3460 +
379.3461 +  /*************************************************************************/
379.3462 +  /*                                                                       */
379.3463 +  /* <Function>                                                            */
379.3464 +  /*    FT_Face_GetVariantSelectors                                        */
379.3465 +  /*                                                                       */
379.3466 +  /* <Description>                                                         */
379.3467 +  /*    Return a zero-terminated list of Unicode variant selectors found   */
379.3468 +  /*    in the font.                                                       */
379.3469 +  /*                                                                       */
379.3470 +  /* <Input>                                                               */
379.3471 +  /*    face ::                                                            */
379.3472 +  /*      A handle to the source face object.                              */
379.3473 +  /*                                                                       */
379.3474 +  /* <Return>                                                              */
379.3475 +  /*    A pointer to an array of selector code points, or NULL if there is */
379.3476 +  /*    no valid variant selector cmap subtable.                           */
379.3477 +  /*                                                                       */
379.3478 +  /* <Note>                                                                */
379.3479 +  /*    The last item in the array is~0; the array is owned by the         */
379.3480 +  /*    @FT_Face object but can be overwritten or released on the next     */
379.3481 +  /*    call to a FreeType function.                                       */
379.3482 +  /*                                                                       */
379.3483 +  /* <Since>                                                               */
379.3484 +  /*    2.3.6                                                              */
379.3485 +  /*                                                                       */
379.3486 +  FT_EXPORT( FT_UInt32* )
379.3487 +  FT_Face_GetVariantSelectors( FT_Face  face );
379.3488 +
379.3489 +
379.3490 +  /*************************************************************************/
379.3491 +  /*                                                                       */
379.3492 +  /* <Function>                                                            */
379.3493 +  /*    FT_Face_GetVariantsOfChar                                          */
379.3494 +  /*                                                                       */
379.3495 +  /* <Description>                                                         */
379.3496 +  /*    Return a zero-terminated list of Unicode variant selectors found   */
379.3497 +  /*    for the specified character code.                                  */
379.3498 +  /*                                                                       */
379.3499 +  /* <Input>                                                               */
379.3500 +  /*    face ::                                                            */
379.3501 +  /*      A handle to the source face object.                              */
379.3502 +  /*                                                                       */
379.3503 +  /*    charcode ::                                                        */
379.3504 +  /*      The character codepoint in Unicode.                              */
379.3505 +  /*                                                                       */
379.3506 +  /* <Return>                                                              */
379.3507 +  /*    A pointer to an array of variant selector code points which are    */
379.3508 +  /*    active for the given character, or NULL if the corresponding list  */
379.3509 +  /*    is empty.                                                          */
379.3510 +  /*                                                                       */
379.3511 +  /* <Note>                                                                */
379.3512 +  /*    The last item in the array is~0; the array is owned by the         */
379.3513 +  /*    @FT_Face object but can be overwritten or released on the next     */
379.3514 +  /*    call to a FreeType function.                                       */
379.3515 +  /*                                                                       */
379.3516 +  /* <Since>                                                               */
379.3517 +  /*    2.3.6                                                              */
379.3518 +  /*                                                                       */
379.3519 +  FT_EXPORT( FT_UInt32* )
379.3520 +  FT_Face_GetVariantsOfChar( FT_Face   face,
379.3521 +                             FT_ULong  charcode );
379.3522 +
379.3523 +
379.3524 +  /*************************************************************************/
379.3525 +  /*                                                                       */
379.3526 +  /* <Function>                                                            */
379.3527 +  /*    FT_Face_GetCharsOfVariant                                          */
379.3528 +  /*                                                                       */
379.3529 +  /* <Description>                                                         */
379.3530 +  /*    Return a zero-terminated list of Unicode character codes found for */
379.3531 +  /*    the specified variant selector.                                    */
379.3532 +  /*                                                                       */
379.3533 +  /* <Input>                                                               */
379.3534 +  /*    face ::                                                            */
379.3535 +  /*      A handle to the source face object.                              */
379.3536 +  /*                                                                       */
379.3537 +  /*    variantSelector ::                                                 */
379.3538 +  /*      The variant selector code point in Unicode.                      */
379.3539 +  /*                                                                       */
379.3540 +  /* <Return>                                                              */
379.3541 +  /*    A list of all the code points which are specified by this selector */
379.3542 +  /*    (both default and non-default codes are returned) or NULL if there */
379.3543 +  /*    is no valid cmap or the variant selector is invalid.               */
379.3544 +  /*                                                                       */
379.3545 +  /* <Note>                                                                */
379.3546 +  /*    The last item in the array is~0; the array is owned by the         */
379.3547 +  /*    @FT_Face object but can be overwritten or released on the next     */
379.3548 +  /*    call to a FreeType function.                                       */
379.3549 +  /*                                                                       */
379.3550 +  /* <Since>                                                               */
379.3551 +  /*    2.3.6                                                              */
379.3552 +  /*                                                                       */
379.3553 +  FT_EXPORT( FT_UInt32* )
379.3554 +  FT_Face_GetCharsOfVariant( FT_Face   face,
379.3555 +                             FT_ULong  variantSelector );
379.3556 +
379.3557 +
379.3558 +  /*************************************************************************/
379.3559 +  /*                                                                       */
379.3560 +  /* <Section>                                                             */
379.3561 +  /*    computations                                                       */
379.3562 +  /*                                                                       */
379.3563 +  /* <Title>                                                               */
379.3564 +  /*    Computations                                                       */
379.3565 +  /*                                                                       */
379.3566 +  /* <Abstract>                                                            */
379.3567 +  /*    Crunching fixed numbers and vectors.                               */
379.3568 +  /*                                                                       */
379.3569 +  /* <Description>                                                         */
379.3570 +  /*    This section contains various functions used to perform            */
379.3571 +  /*    computations on 16.16 fixed-float numbers or 2d vectors.           */
379.3572 +  /*                                                                       */
379.3573 +  /* <Order>                                                               */
379.3574 +  /*    FT_MulDiv                                                          */
379.3575 +  /*    FT_MulFix                                                          */
379.3576 +  /*    FT_DivFix                                                          */
379.3577 +  /*    FT_RoundFix                                                        */
379.3578 +  /*    FT_CeilFix                                                         */
379.3579 +  /*    FT_FloorFix                                                        */
379.3580 +  /*    FT_Vector_Transform                                                */
379.3581 +  /*    FT_Matrix_Multiply                                                 */
379.3582 +  /*    FT_Matrix_Invert                                                   */
379.3583 +  /*                                                                       */
379.3584 +  /*************************************************************************/
379.3585 +
379.3586 +
379.3587 +  /*************************************************************************/
379.3588 +  /*                                                                       */
379.3589 +  /* <Function>                                                            */
379.3590 +  /*    FT_MulDiv                                                          */
379.3591 +  /*                                                                       */
379.3592 +  /* <Description>                                                         */
379.3593 +  /*    A very simple function used to perform the computation `(a*b)/c'   */
379.3594 +  /*    with maximal accuracy (it uses a 64-bit intermediate integer       */
379.3595 +  /*    whenever necessary).                                               */
379.3596 +  /*                                                                       */
379.3597 +  /*    This function isn't necessarily as fast as some processor specific */
379.3598 +  /*    operations, but is at least completely portable.                   */
379.3599 +  /*                                                                       */
379.3600 +  /* <Input>                                                               */
379.3601 +  /*    a :: The first multiplier.                                         */
379.3602 +  /*    b :: The second multiplier.                                        */
379.3603 +  /*    c :: The divisor.                                                  */
379.3604 +  /*                                                                       */
379.3605 +  /* <Return>                                                              */
379.3606 +  /*    The result of `(a*b)/c'.  This function never traps when trying to */
379.3607 +  /*    divide by zero; it simply returns `MaxInt' or `MinInt' depending   */
379.3608 +  /*    on the signs of `a' and `b'.                                       */
379.3609 +  /*                                                                       */
379.3610 +  FT_EXPORT( FT_Long )
379.3611 +  FT_MulDiv( FT_Long  a,
379.3612 +             FT_Long  b,
379.3613 +             FT_Long  c );
379.3614 +
379.3615 +
379.3616 +  /* */
379.3617 +
379.3618 +  /* The following #if 0 ... #endif is for the documentation formatter, */
379.3619 +  /* hiding the internal `FT_MULFIX_INLINED' macro.                     */
379.3620 +
379.3621 +#if 0
379.3622 +  /*************************************************************************/
379.3623 +  /*                                                                       */
379.3624 +  /* <Function>                                                            */
379.3625 +  /*    FT_MulFix                                                          */
379.3626 +  /*                                                                       */
379.3627 +  /* <Description>                                                         */
379.3628 +  /*    A very simple function used to perform the computation             */
379.3629 +  /*    `(a*b)/0x10000' with maximal accuracy.  Most of the time this is   */
379.3630 +  /*    used to multiply a given value by a 16.16 fixed float factor.      */
379.3631 +  /*                                                                       */
379.3632 +  /* <Input>                                                               */
379.3633 +  /*    a :: The first multiplier.                                         */
379.3634 +  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */
379.3635 +  /*         possible (see note below).                                    */
379.3636 +  /*                                                                       */
379.3637 +  /* <Return>                                                              */
379.3638 +  /*    The result of `(a*b)/0x10000'.                                     */
379.3639 +  /*                                                                       */
379.3640 +  /* <Note>                                                                */
379.3641 +  /*    This function has been optimized for the case where the absolute   */
379.3642 +  /*    value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */
379.3643 +  /*    As this happens mainly when scaling from notional units to         */
379.3644 +  /*    fractional pixels in FreeType, it resulted in noticeable speed     */
379.3645 +  /*    improvements between versions 2.x and 1.x.                         */
379.3646 +  /*                                                                       */
379.3647 +  /*    As a conclusion, always try to place a 16.16 factor as the         */
379.3648 +  /*    _second_ argument of this function; this can make a great          */
379.3649 +  /*    difference.                                                        */
379.3650 +  /*                                                                       */
379.3651 +  FT_EXPORT( FT_Long )
379.3652 +  FT_MulFix( FT_Long  a,
379.3653 +             FT_Long  b );
379.3654 +
379.3655 +  /* */
379.3656 +#endif
379.3657 +
379.3658 +#ifdef FT_MULFIX_INLINED
379.3659 +#define FT_MulFix( a, b )  FT_MULFIX_INLINED( a, b )
379.3660 +#else
379.3661 +  FT_EXPORT( FT_Long )
379.3662 +  FT_MulFix( FT_Long  a,
379.3663 +             FT_Long  b );
379.3664 +#endif
379.3665 +
379.3666 +
379.3667 +  /*************************************************************************/
379.3668 +  /*                                                                       */
379.3669 +  /* <Function>                                                            */
379.3670 +  /*    FT_DivFix                                                          */
379.3671 +  /*                                                                       */
379.3672 +  /* <Description>                                                         */
379.3673 +  /*    A very simple function used to perform the computation             */
379.3674 +  /*    `(a*0x10000)/b' with maximal accuracy.  Most of the time, this is  */
379.3675 +  /*    used to divide a given value by a 16.16 fixed float factor.        */
379.3676 +  /*                                                                       */
379.3677 +  /* <Input>                                                               */
379.3678 +  /*    a :: The first multiplier.                                         */
379.3679 +  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */
379.3680 +  /*         possible (see note below).                                    */
379.3681 +  /*                                                                       */
379.3682 +  /* <Return>                                                              */
379.3683 +  /*    The result of `(a*0x10000)/b'.                                     */
379.3684 +  /*                                                                       */
379.3685 +  /* <Note>                                                                */
379.3686 +  /*    The optimization for FT_DivFix() is simple: If (a~<<~16) fits in   */
379.3687 +  /*    32~bits, then the division is computed directly.  Otherwise, we    */
379.3688 +  /*    use a specialized version of @FT_MulDiv.                           */
379.3689 +  /*                                                                       */
379.3690 +  FT_EXPORT( FT_Long )
379.3691 +  FT_DivFix( FT_Long  a,
379.3692 +             FT_Long  b );
379.3693 +
379.3694 +
379.3695 +  /*************************************************************************/
379.3696 +  /*                                                                       */
379.3697 +  /* <Function>                                                            */
379.3698 +  /*    FT_RoundFix                                                        */
379.3699 +  /*                                                                       */
379.3700 +  /* <Description>                                                         */
379.3701 +  /*    A very simple function used to round a 16.16 fixed number.         */
379.3702 +  /*                                                                       */
379.3703 +  /* <Input>                                                               */
379.3704 +  /*    a :: The number to be rounded.                                     */
379.3705 +  /*                                                                       */
379.3706 +  /* <Return>                                                              */
379.3707 +  /*    The result of `(a + 0x8000) & -0x10000'.                           */
379.3708 +  /*                                                                       */
379.3709 +  FT_EXPORT( FT_Fixed )
379.3710 +  FT_RoundFix( FT_Fixed  a );
379.3711 +
379.3712 +
379.3713 +  /*************************************************************************/
379.3714 +  /*                                                                       */
379.3715 +  /* <Function>                                                            */
379.3716 +  /*    FT_CeilFix                                                         */
379.3717 +  /*                                                                       */
379.3718 +  /* <Description>                                                         */
379.3719 +  /*    A very simple function used to compute the ceiling function of a   */
379.3720 +  /*    16.16 fixed number.                                                */
379.3721 +  /*                                                                       */
379.3722 +  /* <Input>                                                               */
379.3723 +  /*    a :: The number for which the ceiling function is to be computed.  */
379.3724 +  /*                                                                       */
379.3725 +  /* <Return>                                                              */
379.3726 +  /*    The result of `(a + 0x10000 - 1) & -0x10000'.                      */
379.3727 +  /*                                                                       */
379.3728 +  FT_EXPORT( FT_Fixed )
379.3729 +  FT_CeilFix( FT_Fixed  a );
379.3730 +
379.3731 +
379.3732 +  /*************************************************************************/
379.3733 +  /*                                                                       */
379.3734 +  /* <Function>                                                            */
379.3735 +  /*    FT_FloorFix                                                        */
379.3736 +  /*                                                                       */
379.3737 +  /* <Description>                                                         */
379.3738 +  /*    A very simple function used to compute the floor function of a     */
379.3739 +  /*    16.16 fixed number.                                                */
379.3740 +  /*                                                                       */
379.3741 +  /* <Input>                                                               */
379.3742 +  /*    a :: The number for which the floor function is to be computed.    */
379.3743 +  /*                                                                       */
379.3744 +  /* <Return>                                                              */
379.3745 +  /*    The result of `a & -0x10000'.                                      */
379.3746 +  /*                                                                       */
379.3747 +  FT_EXPORT( FT_Fixed )
379.3748 +  FT_FloorFix( FT_Fixed  a );
379.3749 +
379.3750 +
379.3751 +  /*************************************************************************/
379.3752 +  /*                                                                       */
379.3753 +  /* <Function>                                                            */
379.3754 +  /*    FT_Vector_Transform                                                */
379.3755 +  /*                                                                       */
379.3756 +  /* <Description>                                                         */
379.3757 +  /*    Transform a single vector through a 2x2 matrix.                    */
379.3758 +  /*                                                                       */
379.3759 +  /* <InOut>                                                               */
379.3760 +  /*    vector :: The target vector to transform.                          */
379.3761 +  /*                                                                       */
379.3762 +  /* <Input>                                                               */
379.3763 +  /*    matrix :: A pointer to the source 2x2 matrix.                      */
379.3764 +  /*                                                                       */
379.3765 +  /* <Note>                                                                */
379.3766 +  /*    The result is undefined if either `vector' or `matrix' is invalid. */
379.3767 +  /*                                                                       */
379.3768 +  FT_EXPORT( void )
379.3769 +  FT_Vector_Transform( FT_Vector*        vec,
379.3770 +                       const FT_Matrix*  matrix );
379.3771 +
379.3772 +
379.3773 +  /*************************************************************************/
379.3774 +  /*                                                                       */
379.3775 +  /* <Section>                                                             */
379.3776 +  /*    version                                                            */
379.3777 +  /*                                                                       */
379.3778 +  /* <Title>                                                               */
379.3779 +  /*    FreeType Version                                                   */
379.3780 +  /*                                                                       */
379.3781 +  /* <Abstract>                                                            */
379.3782 +  /*    Functions and macros related to FreeType versions.                 */
379.3783 +  /*                                                                       */
379.3784 +  /* <Description>                                                         */
379.3785 +  /*    Note that those functions and macros are of limited use because    */
379.3786 +  /*    even a new release of FreeType with only documentation changes     */
379.3787 +  /*    increases the version number.                                      */
379.3788 +  /*                                                                       */
379.3789 +  /*************************************************************************/
379.3790 +
379.3791 +
379.3792 +  /*************************************************************************
379.3793 +   *
379.3794 +   * @enum:
379.3795 +   *   FREETYPE_XXX
379.3796 +   *
379.3797 +   * @description:
379.3798 +   *   These three macros identify the FreeType source code version.
379.3799 +   *   Use @FT_Library_Version to access them at runtime.
379.3800 +   *
379.3801 +   * @values:
379.3802 +   *   FREETYPE_MAJOR :: The major version number.
379.3803 +   *   FREETYPE_MINOR :: The minor version number.
379.3804 +   *   FREETYPE_PATCH :: The patch level.
379.3805 +   *
379.3806 +   * @note:
379.3807 +   *   The version number of FreeType if built as a dynamic link library
379.3808 +   *   with the `libtool' package is _not_ controlled by these three
379.3809 +   *   macros.
379.3810 +   *
379.3811 +   */
379.3812 +#define FREETYPE_MAJOR  2
379.3813 +#define FREETYPE_MINOR  4
379.3814 +#define FREETYPE_PATCH  4
379.3815 +
379.3816 +
379.3817 +  /*************************************************************************/
379.3818 +  /*                                                                       */
379.3819 +  /* <Function>                                                            */
379.3820 +  /*    FT_Library_Version                                                 */
379.3821 +  /*                                                                       */
379.3822 +  /* <Description>                                                         */
379.3823 +  /*    Return the version of the FreeType library being used.  This is    */
379.3824 +  /*    useful when dynamically linking to the library, since one cannot   */
379.3825 +  /*    use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and               */
379.3826 +  /*    @FREETYPE_PATCH.                                                   */
379.3827 +  /*                                                                       */
379.3828 +  /* <Input>                                                               */
379.3829 +  /*    library :: A source library handle.                                */
379.3830 +  /*                                                                       */
379.3831 +  /* <Output>                                                              */
379.3832 +  /*    amajor  :: The major version number.                               */
379.3833 +  /*                                                                       */
379.3834 +  /*    aminor  :: The minor version number.                               */
379.3835 +  /*                                                                       */
379.3836 +  /*    apatch  :: The patch version number.                               */
379.3837 +  /*                                                                       */
379.3838 +  /* <Note>                                                                */
379.3839 +  /*    The reason why this function takes a `library' argument is because */
379.3840 +  /*    certain programs implement library initialization in a custom way  */
379.3841 +  /*    that doesn't use @FT_Init_FreeType.                                */
379.3842 +  /*                                                                       */
379.3843 +  /*    In such cases, the library version might not be available before   */
379.3844 +  /*    the library object has been created.                               */
379.3845 +  /*                                                                       */
379.3846 +  FT_EXPORT( void )
379.3847 +  FT_Library_Version( FT_Library   library,
379.3848 +                      FT_Int      *amajor,
379.3849 +                      FT_Int      *aminor,
379.3850 +                      FT_Int      *apatch );
379.3851 +
379.3852 +
379.3853 +  /*************************************************************************/
379.3854 +  /*                                                                       */
379.3855 +  /* <Function>                                                            */
379.3856 +  /*    FT_Face_CheckTrueTypePatents                                       */
379.3857 +  /*                                                                       */
379.3858 +  /* <Description>                                                         */
379.3859 +  /*    Parse all bytecode instructions of a TrueType font file to check   */
379.3860 +  /*    whether any of the patented opcodes are used.  This is only useful */
379.3861 +  /*    if you want to be able to use the unpatented hinter with           */
379.3862 +  /*    fonts that do *not* use these opcodes.                             */
379.3863 +  /*                                                                       */
379.3864 +  /*    Note that this function parses *all* glyph instructions in the     */
379.3865 +  /*    font file, which may be slow.                                      */
379.3866 +  /*                                                                       */
379.3867 +  /* <Input>                                                               */
379.3868 +  /*    face :: A face handle.                                             */
379.3869 +  /*                                                                       */
379.3870 +  /* <Return>                                                              */
379.3871 +  /*    1~if this is a TrueType font that uses one of the patented         */
379.3872 +  /*    opcodes, 0~otherwise.                                              */
379.3873 +  /*                                                                       */
379.3874 +  /* <Note>                                                                */
379.3875 +  /*    Since May 2010, TrueType hinting is no longer patented.            */
379.3876 +  /*                                                                       */
379.3877 +  /* <Since>                                                               */
379.3878 +  /*    2.3.5                                                              */
379.3879 +  /*                                                                       */
379.3880 +  FT_EXPORT( FT_Bool )
379.3881 +  FT_Face_CheckTrueTypePatents( FT_Face  face );
379.3882 +
379.3883 +
379.3884 +  /*************************************************************************/
379.3885 +  /*                                                                       */
379.3886 +  /* <Function>                                                            */
379.3887 +  /*    FT_Face_SetUnpatentedHinting                                       */
379.3888 +  /*                                                                       */
379.3889 +  /* <Description>                                                         */
379.3890 +  /*    Enable or disable the unpatented hinter for a given face.          */
379.3891 +  /*    Only enable it if you have determined that the face doesn't        */
379.3892 +  /*    use any patented opcodes (see @FT_Face_CheckTrueTypePatents).      */
379.3893 +  /*                                                                       */
379.3894 +  /* <Input>                                                               */
379.3895 +  /*    face  :: A face handle.                                            */
379.3896 +  /*                                                                       */
379.3897 +  /*    value :: New boolean setting.                                      */
379.3898 +  /*                                                                       */
379.3899 +  /* <Return>                                                              */
379.3900 +  /*    The old setting value.  This will always be false if this is not   */
379.3901 +  /*    an SFNT font, or if the unpatented hinter is not compiled in this  */
379.3902 +  /*    instance of the library.                                           */
379.3903 +  /*                                                                       */
379.3904 +  /* <Note>                                                                */
379.3905 +  /*    Since May 2010, TrueType hinting is no longer patented.            */
379.3906 +  /*                                                                       */
379.3907 +  /* <Since>                                                               */
379.3908 +  /*    2.3.5                                                              */
379.3909 +  /*                                                                       */
379.3910 +  FT_EXPORT( FT_Bool )
379.3911 +  FT_Face_SetUnpatentedHinting( FT_Face  face,
379.3912 +                                FT_Bool  value );
379.3913 +
379.3914 +  /* */
379.3915 +
379.3916 +
379.3917 +FT_END_HEADER
379.3918 +
379.3919 +#endif /* __FREETYPE_H__ */
379.3920 +
379.3921 +
379.3922 +/* END */
   380.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   380.2 +++ b/libs/ft2static/freetype/ftadvanc.h	Sat Feb 01 19:58:19 2014 +0200
   380.3 @@ -0,0 +1,179 @@
   380.4 +/***************************************************************************/
   380.5 +/*                                                                         */
   380.6 +/*  ftadvanc.h                                                             */
   380.7 +/*                                                                         */
   380.8 +/*    Quick computation of advance widths (specification only).            */
   380.9 +/*                                                                         */
  380.10 +/*  Copyright 2008 by                                                      */
  380.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  380.12 +/*                                                                         */
  380.13 +/*  This file is part of the FreeType project, and may only be used,       */
  380.14 +/*  modified, and distributed under the terms of the FreeType project      */
  380.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  380.16 +/*  this file you indicate that you have read the license and              */
  380.17 +/*  understand and accept it fully.                                        */
  380.18 +/*                                                                         */
  380.19 +/***************************************************************************/
  380.20 +
  380.21 +
  380.22 +#ifndef __FTADVANC_H__
  380.23 +#define __FTADVANC_H__
  380.24 +
  380.25 +
  380.26 +#include <ft2build.h>
  380.27 +#include FT_FREETYPE_H
  380.28 +
  380.29 +#ifdef FREETYPE_H
  380.30 +#error "freetype.h of FreeType 1 has been loaded!"
  380.31 +#error "Please fix the directory search order for header files"
  380.32 +#error "so that freetype.h of FreeType 2 is found first."
  380.33 +#endif
  380.34 +
  380.35 +
  380.36 +FT_BEGIN_HEADER
  380.37 +
  380.38 +
  380.39 +  /**************************************************************************
  380.40 +   *
  380.41 +   * @section:
  380.42 +   *   quick_advance
  380.43 +   *
  380.44 +   * @title:
  380.45 +   *   Quick retrieval of advance values
  380.46 +   *
  380.47 +   * @abstract:
  380.48 +   *   Retrieve horizontal and vertical advance values without processing
  380.49 +   *   glyph outlines, if possible.
  380.50 +   *
  380.51 +   * @description:
  380.52 +   *   This section contains functions to quickly extract advance values
  380.53 +   *   without handling glyph outlines, if possible.
  380.54 +   */
  380.55 +
  380.56 +
  380.57 +  /*************************************************************************/
  380.58 +  /*                                                                       */
  380.59 +  /* <Const>                                                               */
  380.60 +  /*    FT_ADVANCE_FLAG_FAST_ONLY                                          */
  380.61 +  /*                                                                       */
  380.62 +  /* <Description>                                                         */
  380.63 +  /*    A bit-flag to be OR-ed with the `flags' parameter of the           */
  380.64 +  /*    @FT_Get_Advance and @FT_Get_Advances functions.                    */
  380.65 +  /*                                                                       */
  380.66 +  /*    If set, it indicates that you want these functions to fail if the  */
  380.67 +  /*    corresponding hinting mode or font driver doesn't allow for very   */
  380.68 +  /*    quick advance computation.                                         */
  380.69 +  /*                                                                       */
  380.70 +  /*    Typically, glyphs which are either unscaled, unhinted, bitmapped,  */
  380.71 +  /*    or light-hinted can have their advance width computed very         */
  380.72 +  /*    quickly.                                                           */
  380.73 +  /*                                                                       */
  380.74 +  /*    Normal and bytecode hinted modes, which require loading, scaling,  */
  380.75 +  /*    and hinting of the glyph outline, are extremely slow by            */
  380.76 +  /*    comparison.                                                        */
  380.77 +  /*                                                                       */
  380.78 +#define FT_ADVANCE_FLAG_FAST_ONLY  0x20000000UL
  380.79 +
  380.80 +
  380.81 +  /*************************************************************************/
  380.82 +  /*                                                                       */
  380.83 +  /* <Function>                                                            */
  380.84 +  /*    FT_Get_Advance                                                     */
  380.85 +  /*                                                                       */
  380.86 +  /* <Description>                                                         */
  380.87 +  /*    Retrieve the advance value of a given glyph outline in an          */
  380.88 +  /*    @FT_Face.  By default, the unhinted advance is returned in font    */
  380.89 +  /*    units.                                                             */
  380.90 +  /*                                                                       */
  380.91 +  /* <Input>                                                               */
  380.92 +  /*    face       :: The source @FT_Face handle.                          */
  380.93 +  /*                                                                       */
  380.94 +  /*    gindex     :: The glyph index.                                     */
  380.95 +  /*                                                                       */
  380.96 +  /*    load_flags :: A set of bit flags similar to those used when        */
  380.97 +  /*                  calling @FT_Load_Glyph, used to determine what kind  */
  380.98 +  /*                  of advances you need.                                */
  380.99 +  /* <Output>                                                              */
 380.100 +  /*    padvance :: The advance value, in either font units or 16.16       */
 380.101 +  /*                format.                                                */
 380.102 +  /*                                                                       */
 380.103 +  /*                If @FT_LOAD_VERTICAL_LAYOUT is set, this is the        */
 380.104 +  /*                vertical advance corresponding to a vertical layout.   */
 380.105 +  /*                Otherwise, it is the horizontal advance in a           */
 380.106 +  /*                horizontal layout.                                     */
 380.107 +  /*                                                                       */
 380.108 +  /* <Return>                                                              */
 380.109 +  /*    FreeType error code.  0 means success.                             */
 380.110 +  /*                                                                       */
 380.111 +  /* <Note>                                                                */
 380.112 +  /*    This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and   */
 380.113 +  /*    if the corresponding font backend doesn't have a quick way to      */
 380.114 +  /*    retrieve the advances.                                             */
 380.115 +  /*                                                                       */
 380.116 +  /*    A scaled advance is returned in 16.16 format but isn't transformed */
 380.117 +  /*    by the affine transformation specified by @FT_Set_Transform.       */
 380.118 +  /*                                                                       */
 380.119 +  FT_EXPORT( FT_Error )
 380.120 +  FT_Get_Advance( FT_Face    face,
 380.121 +                  FT_UInt    gindex,
 380.122 +                  FT_Int32   load_flags,
 380.123 +                  FT_Fixed  *padvance );
 380.124 +
 380.125 +
 380.126 +  /*************************************************************************/
 380.127 +  /*                                                                       */
 380.128 +  /* <Function>                                                            */
 380.129 +  /*    FT_Get_Advances                                                    */
 380.130 +  /*                                                                       */
 380.131 +  /* <Description>                                                         */
 380.132 +  /*    Retrieve the advance values of several glyph outlines in an        */
 380.133 +  /*    @FT_Face.  By default, the unhinted advances are returned in font  */
 380.134 +  /*    units.                                                             */
 380.135 +  /*                                                                       */
 380.136 +  /* <Input>                                                               */
 380.137 +  /*    face        :: The source @FT_Face handle.                         */
 380.138 +  /*                                                                       */
 380.139 +  /*    start       :: The first glyph index.                              */
 380.140 +  /*                                                                       */
 380.141 +  /*    count       :: The number of advance values you want to retrieve.  */
 380.142 +  /*                                                                       */
 380.143 +  /*    load_flags  :: A set of bit flags similar to those used when       */
 380.144 +  /*                   calling @FT_Load_Glyph.                             */
 380.145 +  /*                                                                       */
 380.146 +  /* <Output>                                                              */
 380.147 +  /*    padvance :: The advances, in either font units or 16.16 format.    */
 380.148 +  /*                This array must contain at least `count' elements.     */
 380.149 +  /*                                                                       */
 380.150 +  /*                If @FT_LOAD_VERTICAL_LAYOUT is set, these are the      */
 380.151 +  /*                vertical advances corresponding to a vertical layout.  */
 380.152 +  /*                Otherwise, they are the horizontal advances in a       */
 380.153 +  /*                horizontal layout.                                     */
 380.154 +  /*                                                                       */
 380.155 +  /* <Return>                                                              */
 380.156 +  /*    FreeType error code.  0 means success.                             */
 380.157 +  /*                                                                       */
 380.158 +  /* <Note>                                                                */
 380.159 +  /*    This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and   */
 380.160 +  /*    if the corresponding font backend doesn't have a quick way to      */
 380.161 +  /*    retrieve the advances.                                             */
 380.162 +  /*                                                                       */
 380.163 +  /*    Scaled advances are returned in 16.16 format but aren't            */
 380.164 +  /*    transformed by the affine transformation specified by              */
 380.165 +  /*    @FT_Set_Transform.                                                 */
 380.166 +  /*                                                                       */
 380.167 +  FT_EXPORT( FT_Error )
 380.168 +  FT_Get_Advances( FT_Face    face,
 380.169 +                   FT_UInt    start,
 380.170 +                   FT_UInt    count,
 380.171 +                   FT_Int32   load_flags,
 380.172 +                   FT_Fixed  *padvances );
 380.173 +
 380.174 +/* */
 380.175 +
 380.176 +
 380.177 +FT_END_HEADER
 380.178 +
 380.179 +#endif /* __FTADVANC_H__ */
 380.180 +
 380.181 +
 380.182 +/* END */
   381.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   381.2 +++ b/libs/ft2static/freetype/ftbbox.h	Sat Feb 01 19:58:19 2014 +0200
   381.3 @@ -0,0 +1,94 @@
   381.4 +/***************************************************************************/
   381.5 +/*                                                                         */
   381.6 +/*  ftbbox.h                                                               */
   381.7 +/*                                                                         */
   381.8 +/*    FreeType exact bbox computation (specification).                     */
   381.9 +/*                                                                         */
  381.10 +/*  Copyright 1996-2001, 2003, 2007 by                                     */
  381.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  381.12 +/*                                                                         */
  381.13 +/*  This file is part of the FreeType project, and may only be used,       */
  381.14 +/*  modified, and distributed under the terms of the FreeType project      */
  381.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  381.16 +/*  this file you indicate that you have read the license and              */
  381.17 +/*  understand and accept it fully.                                        */
  381.18 +/*                                                                         */
  381.19 +/***************************************************************************/
  381.20 +
  381.21 +
  381.22 +  /*************************************************************************/
  381.23 +  /*                                                                       */
  381.24 +  /* This component has a _single_ role: to compute exact outline bounding */
  381.25 +  /* boxes.                                                                */
  381.26 +  /*                                                                       */
  381.27 +  /* It is separated from the rest of the engine for various technical     */
  381.28 +  /* reasons.  It may well be integrated in `ftoutln' later.               */
  381.29 +  /*                                                                       */
  381.30 +  /*************************************************************************/
  381.31 +
  381.32 +
  381.33 +#ifndef __FTBBOX_H__
  381.34 +#define __FTBBOX_H__
  381.35 +
  381.36 +
  381.37 +#include <ft2build.h>
  381.38 +#include FT_FREETYPE_H
  381.39 +
  381.40 +#ifdef FREETYPE_H
  381.41 +#error "freetype.h of FreeType 1 has been loaded!"
  381.42 +#error "Please fix the directory search order for header files"
  381.43 +#error "so that freetype.h of FreeType 2 is found first."
  381.44 +#endif
  381.45 +
  381.46 +
  381.47 +FT_BEGIN_HEADER
  381.48 +
  381.49 +
  381.50 +  /*************************************************************************/
  381.51 +  /*                                                                       */
  381.52 +  /* <Section>                                                             */
  381.53 +  /*    outline_processing                                                 */
  381.54 +  /*                                                                       */
  381.55 +  /*************************************************************************/
  381.56 +
  381.57 +
  381.58 +  /*************************************************************************/
  381.59 +  /*                                                                       */
  381.60 +  /* <Function>                                                            */
  381.61 +  /*    FT_Outline_Get_BBox                                                */
  381.62 +  /*                                                                       */
  381.63 +  /* <Description>                                                         */
  381.64 +  /*    Compute the exact bounding box of an outline.  This is slower      */
  381.65 +  /*    than computing the control box.  However, it uses an advanced      */
  381.66 +  /*    algorithm which returns _very_ quickly when the two boxes          */
  381.67 +  /*    coincide.  Otherwise, the outline Bézier arcs are traversed to     */
  381.68 +  /*    extract their extrema.                                             */
  381.69 +  /*                                                                       */
  381.70 +  /* <Input>                                                               */
  381.71 +  /*    outline :: A pointer to the source outline.                        */
  381.72 +  /*                                                                       */
  381.73 +  /* <Output>                                                              */
  381.74 +  /*    abbox   :: The outline's exact bounding box.                       */
  381.75 +  /*                                                                       */
  381.76 +  /* <Return>                                                              */
  381.77 +  /*    FreeType error code.  0~means success.                             */
  381.78 +  /*                                                                       */
  381.79 +  FT_EXPORT( FT_Error )
  381.80 +  FT_Outline_Get_BBox( FT_Outline*  outline,
  381.81 +                       FT_BBox     *abbox );
  381.82 +
  381.83 +
  381.84 +  /* */
  381.85 +
  381.86 +
  381.87 +FT_END_HEADER
  381.88 +
  381.89 +#endif /* __FTBBOX_H__ */
  381.90 +
  381.91 +
  381.92 +/* END */
  381.93 +
  381.94 +
  381.95 +/* Local Variables: */
  381.96 +/* coding: utf-8    */
  381.97 +/* End:             */
   382.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   382.2 +++ b/libs/ft2static/freetype/ftbdf.h	Sat Feb 01 19:58:19 2014 +0200
   382.3 @@ -0,0 +1,209 @@
   382.4 +/***************************************************************************/
   382.5 +/*                                                                         */
   382.6 +/*  ftbdf.h                                                                */
   382.7 +/*                                                                         */
   382.8 +/*    FreeType API for accessing BDF-specific strings (specification).     */
   382.9 +/*                                                                         */
  382.10 +/*  Copyright 2002, 2003, 2004, 2006, 2009 by                              */
  382.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  382.12 +/*                                                                         */
  382.13 +/*  This file is part of the FreeType project, and may only be used,       */
  382.14 +/*  modified, and distributed under the terms of the FreeType project      */
  382.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  382.16 +/*  this file you indicate that you have read the license and              */
  382.17 +/*  understand and accept it fully.                                        */
  382.18 +/*                                                                         */
  382.19 +/***************************************************************************/
  382.20 +
  382.21 +
  382.22 +#ifndef __FTBDF_H__
  382.23 +#define __FTBDF_H__
  382.24 +
  382.25 +#include <ft2build.h>
  382.26 +#include FT_FREETYPE_H
  382.27 +
  382.28 +#ifdef FREETYPE_H
  382.29 +#error "freetype.h of FreeType 1 has been loaded!"
  382.30 +#error "Please fix the directory search order for header files"
  382.31 +#error "so that freetype.h of FreeType 2 is found first."
  382.32 +#endif
  382.33 +
  382.34 +
  382.35 +FT_BEGIN_HEADER
  382.36 +
  382.37 +
  382.38 +  /*************************************************************************/
  382.39 +  /*                                                                       */
  382.40 +  /* <Section>                                                             */
  382.41 +  /*    bdf_fonts                                                          */
  382.42 +  /*                                                                       */
  382.43 +  /* <Title>                                                               */
  382.44 +  /*    BDF and PCF Files                                                  */
  382.45 +  /*                                                                       */
  382.46 +  /* <Abstract>                                                            */
  382.47 +  /*    BDF and PCF specific API.                                          */
  382.48 +  /*                                                                       */
  382.49 +  /* <Description>                                                         */
  382.50 +  /*    This section contains the declaration of functions specific to BDF */
  382.51 +  /*    and PCF fonts.                                                     */
  382.52 +  /*                                                                       */
  382.53 +  /*************************************************************************/
  382.54 +
  382.55 +
  382.56 +  /**********************************************************************
  382.57 +   *
  382.58 +   * @enum:
  382.59 +   *    FT_PropertyType
  382.60 +   *
  382.61 +   * @description:
  382.62 +   *    A list of BDF property types.
  382.63 +   *
  382.64 +   * @values:
  382.65 +   *    BDF_PROPERTY_TYPE_NONE ::
  382.66 +   *      Value~0 is used to indicate a missing property.
  382.67 +   *
  382.68 +   *    BDF_PROPERTY_TYPE_ATOM ::
  382.69 +   *      Property is a string atom.
  382.70 +   *
  382.71 +   *    BDF_PROPERTY_TYPE_INTEGER ::
  382.72 +   *      Property is a 32-bit signed integer.
  382.73 +   *
  382.74 +   *    BDF_PROPERTY_TYPE_CARDINAL ::
  382.75 +   *      Property is a 32-bit unsigned integer.
  382.76 +   */
  382.77 +  typedef enum  BDF_PropertyType_
  382.78 +  {
  382.79 +    BDF_PROPERTY_TYPE_NONE     = 0,
  382.80 +    BDF_PROPERTY_TYPE_ATOM     = 1,
  382.81 +    BDF_PROPERTY_TYPE_INTEGER  = 2,
  382.82 +    BDF_PROPERTY_TYPE_CARDINAL = 3
  382.83 +
  382.84 +  } BDF_PropertyType;
  382.85 +
  382.86 +
  382.87 +  /**********************************************************************
  382.88 +   *
  382.89 +   * @type:
  382.90 +   *    BDF_Property
  382.91 +   *
  382.92 +   * @description:
  382.93 +   *    A handle to a @BDF_PropertyRec structure to model a given
  382.94 +   *    BDF/PCF property.
  382.95 +   */
  382.96 +  typedef struct BDF_PropertyRec_*  BDF_Property;
  382.97 +
  382.98 +
  382.99 + /**********************************************************************
 382.100 +  *
 382.101 +  * @struct:
 382.102 +  *    BDF_PropertyRec
 382.103 +  *
 382.104 +  * @description:
 382.105 +  *    This structure models a given BDF/PCF property.
 382.106 +  *
 382.107 +  * @fields:
 382.108 +  *    type ::
 382.109 +  *      The property type.
 382.110 +  *
 382.111 +  *    u.atom ::
 382.112 +  *      The atom string, if type is @BDF_PROPERTY_TYPE_ATOM.
 382.113 +  *
 382.114 +  *    u.integer ::
 382.115 +  *      A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER.
 382.116 +  *
 382.117 +  *    u.cardinal ::
 382.118 +  *      An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL.
 382.119 +  */
 382.120 +  typedef struct  BDF_PropertyRec_
 382.121 +  {
 382.122 +    BDF_PropertyType  type;
 382.123 +    union {
 382.124 +      const char*     atom;
 382.125 +      FT_Int32        integer;
 382.126 +      FT_UInt32       cardinal;
 382.127 +
 382.128 +    } u;
 382.129 +
 382.130 +  } BDF_PropertyRec;
 382.131 +
 382.132 +
 382.133 + /**********************************************************************
 382.134 +  *
 382.135 +  * @function:
 382.136 +  *    FT_Get_BDF_Charset_ID
 382.137 +  *
 382.138 +  * @description:
 382.139 +  *    Retrieve a BDF font character set identity, according to
 382.140 +  *    the BDF specification.
 382.141 +  *
 382.142 +  * @input:
 382.143 +  *    face ::
 382.144 +  *       A handle to the input face.
 382.145 +  *
 382.146 +  * @output:
 382.147 +  *    acharset_encoding ::
 382.148 +  *       Charset encoding, as a C~string, owned by the face.
 382.149 +  *
 382.150 +  *    acharset_registry ::
 382.151 +  *       Charset registry, as a C~string, owned by the face.
 382.152 +  *
 382.153 +  * @return:
 382.154 +  *   FreeType error code.  0~means success.
 382.155 +  *
 382.156 +  * @note:
 382.157 +  *   This function only works with BDF faces, returning an error otherwise.
 382.158 +  */
 382.159 +  FT_EXPORT( FT_Error )
 382.160 +  FT_Get_BDF_Charset_ID( FT_Face       face,
 382.161 +                         const char*  *acharset_encoding,
 382.162 +                         const char*  *acharset_registry );
 382.163 +
 382.164 +
 382.165 + /**********************************************************************
 382.166 +  *
 382.167 +  * @function:
 382.168 +  *    FT_Get_BDF_Property
 382.169 +  *
 382.170 +  * @description:
 382.171 +  *    Retrieve a BDF property from a BDF or PCF font file.
 382.172 +  *
 382.173 +  * @input:
 382.174 +  *    face :: A handle to the input face.
 382.175 +  *
 382.176 +  *    name :: The property name.
 382.177 +  *
 382.178 +  * @output:
 382.179 +  *    aproperty :: The property.
 382.180 +  *
 382.181 +  * @return:
 382.182 +  *   FreeType error code.  0~means success.
 382.183 +  *
 382.184 +  * @note:
 382.185 +  *   This function works with BDF _and_ PCF fonts.  It returns an error
 382.186 +  *   otherwise.  It also returns an error if the property is not in the
 382.187 +  *   font.
 382.188 +  *
 382.189 +  *   A `property' is a either key-value pair within the STARTPROPERTIES
 382.190 +  *   ... ENDPROPERTIES block of a BDF font or a key-value pair from the
 382.191 +  *   `info->props' array within a `FontRec' structure of a PCF font.
 382.192 +  *
 382.193 +  *   Integer properties are always stored as `signed' within PCF fonts;
 382.194 +  *   consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value
 382.195 +  *   for BDF fonts only.
 382.196 +  *
 382.197 +  *   In case of error, `aproperty->type' is always set to
 382.198 +  *   @BDF_PROPERTY_TYPE_NONE.
 382.199 +  */
 382.200 +  FT_EXPORT( FT_Error )
 382.201 +  FT_Get_BDF_Property( FT_Face           face,
 382.202 +                       const char*       prop_name,
 382.203 +                       BDF_PropertyRec  *aproperty );
 382.204 +
 382.205 + /* */
 382.206 +
 382.207 +FT_END_HEADER
 382.208 +
 382.209 +#endif /* __FTBDF_H__ */
 382.210 +
 382.211 +
 382.212 +/* END */
   383.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   383.2 +++ b/libs/ft2static/freetype/ftbitmap.h	Sat Feb 01 19:58:19 2014 +0200
   383.3 @@ -0,0 +1,227 @@
   383.4 +/***************************************************************************/
   383.5 +/*                                                                         */
   383.6 +/*  ftbitmap.h                                                             */
   383.7 +/*                                                                         */
   383.8 +/*    FreeType utility functions for bitmaps (specification).              */
   383.9 +/*                                                                         */
  383.10 +/*  Copyright 2004, 2005, 2006, 2008 by                                    */
  383.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  383.12 +/*                                                                         */
  383.13 +/*  This file is part of the FreeType project, and may only be used,       */
  383.14 +/*  modified, and distributed under the terms of the FreeType project      */
  383.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  383.16 +/*  this file you indicate that you have read the license and              */
  383.17 +/*  understand and accept it fully.                                        */
  383.18 +/*                                                                         */
  383.19 +/***************************************************************************/
  383.20 +
  383.21 +
  383.22 +#ifndef __FTBITMAP_H__
  383.23 +#define __FTBITMAP_H__
  383.24 +
  383.25 +
  383.26 +#include <ft2build.h>
  383.27 +#include FT_FREETYPE_H
  383.28 +
  383.29 +#ifdef FREETYPE_H
  383.30 +#error "freetype.h of FreeType 1 has been loaded!"
  383.31 +#error "Please fix the directory search order for header files"
  383.32 +#error "so that freetype.h of FreeType 2 is found first."
  383.33 +#endif
  383.34 +
  383.35 +
  383.36 +FT_BEGIN_HEADER
  383.37 +
  383.38 +
  383.39 +  /*************************************************************************/
  383.40 +  /*                                                                       */
  383.41 +  /* <Section>                                                             */
  383.42 +  /*    bitmap_handling                                                    */
  383.43 +  /*                                                                       */
  383.44 +  /* <Title>                                                               */
  383.45 +  /*    Bitmap Handling                                                    */
  383.46 +  /*                                                                       */
  383.47 +  /* <Abstract>                                                            */
  383.48 +  /*    Handling FT_Bitmap objects.                                        */
  383.49 +  /*                                                                       */
  383.50 +  /* <Description>                                                         */
  383.51 +  /*    This section contains functions for converting FT_Bitmap objects.  */
  383.52 +  /*                                                                       */
  383.53 +  /*************************************************************************/
  383.54 +
  383.55 +
  383.56 +  /*************************************************************************/
  383.57 +  /*                                                                       */
  383.58 +  /* <Function>                                                            */
  383.59 +  /*    FT_Bitmap_New                                                      */
  383.60 +  /*                                                                       */
  383.61 +  /* <Description>                                                         */
  383.62 +  /*    Initialize a pointer to an @FT_Bitmap structure.                   */
  383.63 +  /*                                                                       */
  383.64 +  /* <InOut>                                                               */
  383.65 +  /*    abitmap :: A pointer to the bitmap structure.                      */
  383.66 +  /*                                                                       */
  383.67 +  FT_EXPORT( void )
  383.68 +  FT_Bitmap_New( FT_Bitmap  *abitmap );
  383.69 +
  383.70 +
  383.71 +  /*************************************************************************/
  383.72 +  /*                                                                       */
  383.73 +  /* <Function>                                                            */
  383.74 +  /*    FT_Bitmap_Copy                                                     */
  383.75 +  /*                                                                       */
  383.76 +  /* <Description>                                                         */
  383.77 +  /*    Copy a bitmap into another one.                                    */
  383.78 +  /*                                                                       */
  383.79 +  /* <Input>                                                               */
  383.80 +  /*    library :: A handle to a library object.                           */
  383.81 +  /*                                                                       */
  383.82 +  /*    source  :: A handle to the source bitmap.                          */
  383.83 +  /*                                                                       */
  383.84 +  /* <Output>                                                              */
  383.85 +  /*    target  :: A handle to the target bitmap.                          */
  383.86 +  /*                                                                       */
  383.87 +  /* <Return>                                                              */
  383.88 +  /*    FreeType error code.  0~means success.                             */
  383.89 +  /*                                                                       */
  383.90 +  FT_EXPORT( FT_Error )
  383.91 +  FT_Bitmap_Copy( FT_Library        library,
  383.92 +                  const FT_Bitmap  *source,
  383.93 +                  FT_Bitmap        *target);
  383.94 +
  383.95 +
  383.96 +  /*************************************************************************/
  383.97 +  /*                                                                       */
  383.98 +  /* <Function>                                                            */
  383.99 +  /*    FT_Bitmap_Embolden                                                 */
 383.100 +  /*                                                                       */
 383.101 +  /* <Description>                                                         */
 383.102 +  /*    Embolden a bitmap.  The new bitmap will be about `xStrength'       */
 383.103 +  /*    pixels wider and `yStrength' pixels higher.  The left and bottom   */
 383.104 +  /*    borders are kept unchanged.                                        */
 383.105 +  /*                                                                       */
 383.106 +  /* <Input>                                                               */
 383.107 +  /*    library   :: A handle to a library object.                         */
 383.108 +  /*                                                                       */
 383.109 +  /*    xStrength :: How strong the glyph is emboldened horizontally.      */
 383.110 +  /*                 Expressed in 26.6 pixel format.                       */
 383.111 +  /*                                                                       */
 383.112 +  /*    yStrength :: How strong the glyph is emboldened vertically.        */
 383.113 +  /*                 Expressed in 26.6 pixel format.                       */
 383.114 +  /*                                                                       */
 383.115 +  /* <InOut>                                                               */
 383.116 +  /*    bitmap    :: A handle to the target bitmap.                        */
 383.117 +  /*                                                                       */
 383.118 +  /* <Return>                                                              */
 383.119 +  /*    FreeType error code.  0~means success.                             */
 383.120 +  /*                                                                       */
 383.121 +  /* <Note>                                                                */
 383.122 +  /*    The current implementation restricts `xStrength' to be less than   */
 383.123 +  /*    or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO.      */
 383.124 +  /*                                                                       */
 383.125 +  /*    If you want to embolden the bitmap owned by a @FT_GlyphSlotRec,    */
 383.126 +  /*    you should call @FT_GlyphSlot_Own_Bitmap on the slot first.        */
 383.127 +  /*                                                                       */
 383.128 +  FT_EXPORT( FT_Error )
 383.129 +  FT_Bitmap_Embolden( FT_Library  library,
 383.130 +                      FT_Bitmap*  bitmap,
 383.131 +                      FT_Pos      xStrength,
 383.132 +                      FT_Pos      yStrength );
 383.133 +
 383.134 +
 383.135 +  /*************************************************************************/
 383.136 +  /*                                                                       */
 383.137 +  /* <Function>                                                            */
 383.138 +  /*    FT_Bitmap_Convert                                                  */
 383.139 +  /*                                                                       */
 383.140 +  /* <Description>                                                         */
 383.141 +  /*    Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, or 8bpp to a  */
 383.142 +  /*    bitmap object with depth 8bpp, making the number of used bytes per */
 383.143 +  /*    line (a.k.a. the `pitch') a multiple of `alignment'.               */
 383.144 +  /*                                                                       */
 383.145 +  /* <Input>                                                               */
 383.146 +  /*    library   :: A handle to a library object.                         */
 383.147 +  /*                                                                       */
 383.148 +  /*    source    :: The source bitmap.                                    */
 383.149 +  /*                                                                       */
 383.150 +  /*    alignment :: The pitch of the bitmap is a multiple of this         */
 383.151 +  /*                 parameter.  Common values are 1, 2, or 4.             */
 383.152 +  /*                                                                       */
 383.153 +  /* <Output>                                                              */
 383.154 +  /*    target    :: The target bitmap.                                    */
 383.155 +  /*                                                                       */
 383.156 +  /* <Return>                                                              */
 383.157 +  /*    FreeType error code.  0~means success.                             */
 383.158 +  /*                                                                       */
 383.159 +  /* <Note>                                                                */
 383.160 +  /*    It is possible to call @FT_Bitmap_Convert multiple times without   */
 383.161 +  /*    calling @FT_Bitmap_Done (the memory is simply reallocated).        */
 383.162 +  /*                                                                       */
 383.163 +  /*    Use @FT_Bitmap_Done to finally remove the bitmap object.           */
 383.164 +  /*                                                                       */
 383.165 +  /*    The `library' argument is taken to have access to FreeType's       */
 383.166 +  /*    memory handling functions.                                         */
 383.167 +  /*                                                                       */
 383.168 +  FT_EXPORT( FT_Error )
 383.169 +  FT_Bitmap_Convert( FT_Library        library,
 383.170 +                     const FT_Bitmap  *source,
 383.171 +                     FT_Bitmap        *target,
 383.172 +                     FT_Int            alignment );
 383.173 +
 383.174 +
 383.175 +  /*************************************************************************/
 383.176 +  /*                                                                       */
 383.177 +  /* <Function>                                                            */
 383.178 +  /*    FT_GlyphSlot_Own_Bitmap                                            */
 383.179 +  /*                                                                       */
 383.180 +  /* <Description>                                                         */
 383.181 +  /*    Make sure that a glyph slot owns `slot->bitmap'.                   */
 383.182 +  /*                                                                       */
 383.183 +  /* <Input>                                                               */
 383.184 +  /*    slot :: The glyph slot.                                            */
 383.185 +  /*                                                                       */
 383.186 +  /* <Return>                                                              */
 383.187 +  /*    FreeType error code.  0~means success.                             */
 383.188 +  /*                                                                       */
 383.189 +  /* <Note>                                                                */
 383.190 +  /*    This function is to be used in combination with                    */
 383.191 +  /*    @FT_Bitmap_Embolden.                                               */
 383.192 +  /*                                                                       */
 383.193 +  FT_EXPORT( FT_Error )
 383.194 +  FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot  slot );
 383.195 +
 383.196 +
 383.197 +  /*************************************************************************/
 383.198 +  /*                                                                       */
 383.199 +  /* <Function>                                                            */
 383.200 +  /*    FT_Bitmap_Done                                                     */
 383.201 +  /*                                                                       */
 383.202 +  /* <Description>                                                         */
 383.203 +  /*    Destroy a bitmap object created with @FT_Bitmap_New.               */
 383.204 +  /*                                                                       */
 383.205 +  /* <Input>                                                               */
 383.206 +  /*    library :: A handle to a library object.                           */
 383.207 +  /*                                                                       */
 383.208 +  /*    bitmap  :: The bitmap object to be freed.                          */
 383.209 +  /*                                                                       */
 383.210 +  /* <Return>                                                              */
 383.211 +  /*    FreeType error code.  0~means success.                             */
 383.212 +  /*                                                                       */
 383.213 +  /* <Note>                                                                */
 383.214 +  /*    The `library' argument is taken to have access to FreeType's       */
 383.215 +  /*    memory handling functions.                                         */
 383.216 +  /*                                                                       */
 383.217 +  FT_EXPORT( FT_Error )
 383.218 +  FT_Bitmap_Done( FT_Library  library,
 383.219 +                  FT_Bitmap  *bitmap );
 383.220 +
 383.221 +
 383.222 +  /* */
 383.223 +
 383.224 +
 383.225 +FT_END_HEADER
 383.226 +
 383.227 +#endif /* __FTBITMAP_H__ */
 383.228 +
 383.229 +
 383.230 +/* END */
   384.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   384.2 +++ b/libs/ft2static/freetype/ftcache.h	Sat Feb 01 19:58:19 2014 +0200
   384.3 @@ -0,0 +1,1140 @@
   384.4 +/***************************************************************************/
   384.5 +/*                                                                         */
   384.6 +/*  ftcache.h                                                              */
   384.7 +/*                                                                         */
   384.8 +/*    FreeType Cache subsystem (specification).                            */
   384.9 +/*                                                                         */
  384.10 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */
  384.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  384.12 +/*                                                                         */
  384.13 +/*  This file is part of the FreeType project, and may only be used,       */
  384.14 +/*  modified, and distributed under the terms of the FreeType project      */
  384.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  384.16 +/*  this file you indicate that you have read the license and              */
  384.17 +/*  understand and accept it fully.                                        */
  384.18 +/*                                                                         */
  384.19 +/***************************************************************************/
  384.20 +
  384.21 +
  384.22 +#ifndef __FTCACHE_H__
  384.23 +#define __FTCACHE_H__
  384.24 +
  384.25 +
  384.26 +#include <ft2build.h>
  384.27 +#include FT_GLYPH_H
  384.28 +
  384.29 +
  384.30 +FT_BEGIN_HEADER
  384.31 +
  384.32 +
  384.33 +  /*************************************************************************
  384.34 +   *
  384.35 +   * <Section>
  384.36 +   *    cache_subsystem
  384.37 +   *
  384.38 +   * <Title>
  384.39 +   *    Cache Sub-System
  384.40 +   *
  384.41 +   * <Abstract>
  384.42 +   *    How to cache face, size, and glyph data with FreeType~2.
  384.43 +   *
  384.44 +   * <Description>
  384.45 +   *   This section describes the FreeType~2 cache sub-system, which is used
  384.46 +   *   to limit the number of concurrently opened @FT_Face and @FT_Size
  384.47 +   *   objects, as well as caching information like character maps and glyph
  384.48 +   *   images while limiting their maximum memory usage.
  384.49 +   *
  384.50 +   *   Note that all types and functions begin with the `FTC_' prefix.
  384.51 +   *
  384.52 +   *   The cache is highly portable and thus doesn't know anything about the
  384.53 +   *   fonts installed on your system, or how to access them.  This implies
  384.54 +   *   the following scheme:
  384.55 +   *
  384.56 +   *   First, available or installed font faces are uniquely identified by
  384.57 +   *   @FTC_FaceID values, provided to the cache by the client.  Note that
  384.58 +   *   the cache only stores and compares these values, and doesn't try to
  384.59 +   *   interpret them in any way.
  384.60 +   *
  384.61 +   *   Second, the cache calls, only when needed, a client-provided function
  384.62 +   *   to convert an @FTC_FaceID into a new @FT_Face object.  The latter is
  384.63 +   *   then completely managed by the cache, including its termination
  384.64 +   *   through @FT_Done_Face.  To monitor termination of face objects, the
  384.65 +   *   finalizer callback in the `generic' field of the @FT_Face object can
  384.66 +   *   be used, which might also be used to store the @FTC_FaceID of the
  384.67 +   *   face.
  384.68 +   *
  384.69 +   *   Clients are free to map face IDs to anything else.  The most simple
  384.70 +   *   usage is to associate them to a (pathname,face_index) pair that is
  384.71 +   *   used to call @FT_New_Face.  However, more complex schemes are also
  384.72 +   *   possible.
  384.73 +   *
  384.74 +   *   Note that for the cache to work correctly, the face ID values must be
  384.75 +   *   *persistent*, which means that the contents they point to should not
  384.76 +   *   change at runtime, or that their value should not become invalid.
  384.77 +   *
  384.78 +   *   If this is unavoidable (e.g., when a font is uninstalled at runtime),
  384.79 +   *   you should call @FTC_Manager_RemoveFaceID as soon as possible, to let
  384.80 +   *   the cache get rid of any references to the old @FTC_FaceID it may
  384.81 +   *   keep internally.  Failure to do so will lead to incorrect behaviour
  384.82 +   *   or even crashes.
  384.83 +   *
  384.84 +   *   To use the cache, start with calling @FTC_Manager_New to create a new
  384.85 +   *   @FTC_Manager object, which models a single cache instance.  You can
  384.86 +   *   then look up @FT_Face and @FT_Size objects with
  384.87 +   *   @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively.
  384.88 +   *
  384.89 +   *   If you want to use the charmap caching, call @FTC_CMapCache_New, then
  384.90 +   *   later use @FTC_CMapCache_Lookup to perform the equivalent of
  384.91 +   *   @FT_Get_Char_Index, only much faster.
  384.92 +   *
  384.93 +   *   If you want to use the @FT_Glyph caching, call @FTC_ImageCache, then
  384.94 +   *   later use @FTC_ImageCache_Lookup to retrieve the corresponding
  384.95 +   *   @FT_Glyph objects from the cache.
  384.96 +   *
  384.97 +   *   If you need lots of small bitmaps, it is much more memory efficient
  384.98 +   *   to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup.  This
  384.99 +   *   returns @FTC_SBitRec structures, which are used to store small
 384.100 +   *   bitmaps directly.  (A small bitmap is one whose metrics and
 384.101 +   *   dimensions all fit into 8-bit integers).
 384.102 +   *
 384.103 +   *   We hope to also provide a kerning cache in the near future.
 384.104 +   *
 384.105 +   *
 384.106 +   * <Order>
 384.107 +   *   FTC_Manager
 384.108 +   *   FTC_FaceID
 384.109 +   *   FTC_Face_Requester
 384.110 +   *
 384.111 +   *   FTC_Manager_New
 384.112 +   *   FTC_Manager_Reset
 384.113 +   *   FTC_Manager_Done
 384.114 +   *   FTC_Manager_LookupFace
 384.115 +   *   FTC_Manager_LookupSize
 384.116 +   *   FTC_Manager_RemoveFaceID
 384.117 +   *
 384.118 +   *   FTC_Node
 384.119 +   *   FTC_Node_Unref
 384.120 +   *
 384.121 +   *   FTC_ImageCache
 384.122 +   *   FTC_ImageCache_New
 384.123 +   *   FTC_ImageCache_Lookup
 384.124 +   *
 384.125 +   *   FTC_SBit
 384.126 +   *   FTC_SBitCache
 384.127 +   *   FTC_SBitCache_New
 384.128 +   *   FTC_SBitCache_Lookup
 384.129 +   *
 384.130 +   *   FTC_CMapCache
 384.131 +   *   FTC_CMapCache_New
 384.132 +   *   FTC_CMapCache_Lookup
 384.133 +   *
 384.134 +   *************************************************************************/
 384.135 +
 384.136 +
 384.137 +  /*************************************************************************/
 384.138 +  /*************************************************************************/
 384.139 +  /*************************************************************************/
 384.140 +  /*****                                                               *****/
 384.141 +  /*****                    BASIC TYPE DEFINITIONS                     *****/
 384.142 +  /*****                                                               *****/
 384.143 +  /*************************************************************************/
 384.144 +  /*************************************************************************/
 384.145 +  /*************************************************************************/
 384.146 +
 384.147 +
 384.148 +  /*************************************************************************
 384.149 +   *
 384.150 +   * @type: FTC_FaceID
 384.151 +   *
 384.152 +   * @description:
 384.153 +   *   An opaque pointer type that is used to identity face objects.  The
 384.154 +   *   contents of such objects is application-dependent.
 384.155 +   *
 384.156 +   *   These pointers are typically used to point to a user-defined
 384.157 +   *   structure containing a font file path, and face index.
 384.158 +   *
 384.159 +   * @note:
 384.160 +   *   Never use NULL as a valid @FTC_FaceID.
 384.161 +   *
 384.162 +   *   Face IDs are passed by the client to the cache manager, which calls,
 384.163 +   *   when needed, the @FTC_Face_Requester to translate them into new
 384.164 +   *   @FT_Face objects.
 384.165 +   *
 384.166 +   *   If the content of a given face ID changes at runtime, or if the value
 384.167 +   *   becomes invalid (e.g., when uninstalling a font), you should
 384.168 +   *   immediately call @FTC_Manager_RemoveFaceID before any other cache
 384.169 +   *   function.
 384.170 +   *
 384.171 +   *   Failure to do so will result in incorrect behaviour or even
 384.172 +   *   memory leaks and crashes.
 384.173 +   */
 384.174 +  typedef FT_Pointer  FTC_FaceID;
 384.175 +
 384.176 +
 384.177 +  /************************************************************************
 384.178 +   *
 384.179 +   * @functype:
 384.180 +   *   FTC_Face_Requester
 384.181 +   *
 384.182 +   * @description:
 384.183 +   *   A callback function provided by client applications.  It is used by
 384.184 +   *   the cache manager to translate a given @FTC_FaceID into a new valid
 384.185 +   *   @FT_Face object, on demand.
 384.186 +   *
 384.187 +   * <Input>
 384.188 +   *   face_id ::
 384.189 +   *     The face ID to resolve.
 384.190 +   *
 384.191 +   *   library ::
 384.192 +   *     A handle to a FreeType library object.
 384.193 +   *
 384.194 +   *   req_data ::
 384.195 +   *     Application-provided request data (see note below).
 384.196 +   *
 384.197 +   * <Output>
 384.198 +   *   aface ::
 384.199 +   *     A new @FT_Face handle.
 384.200 +   *
 384.201 +   * <Return>
 384.202 +   *   FreeType error code.  0~means success.
 384.203 +   *
 384.204 +   * <Note>
 384.205 +   *   The third parameter `req_data' is the same as the one passed by the
 384.206 +   *   client when @FTC_Manager_New is called.
 384.207 +   *
 384.208 +   *   The face requester should not perform funny things on the returned
 384.209 +   *   face object, like creating a new @FT_Size for it, or setting a
 384.210 +   *   transformation through @FT_Set_Transform!
 384.211 +   */
 384.212 +  typedef FT_Error
 384.213 +  (*FTC_Face_Requester)( FTC_FaceID  face_id,
 384.214 +                         FT_Library  library,
 384.215 +                         FT_Pointer  request_data,
 384.216 +                         FT_Face*    aface );
 384.217 +
 384.218 + /* */
 384.219 +
 384.220 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 384.221 +
 384.222 +  /* these macros are incompatible with LLP64, should not be used */
 384.223 +
 384.224 +#define FT_POINTER_TO_ULONG( p )  ( (FT_ULong)(FT_Pointer)(p) )
 384.225 +
 384.226 +#define FTC_FACE_ID_HASH( i )                                \
 384.227 +          ((FT_UInt32)(( FT_POINTER_TO_ULONG( i ) >> 3 ) ^   \
 384.228 +                       ( FT_POINTER_TO_ULONG( i ) << 7 ) ) )
 384.229 +
 384.230 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
 384.231 +
 384.232 +  /*************************************************************************/
 384.233 +  /*************************************************************************/
 384.234 +  /*************************************************************************/
 384.235 +  /*****                                                               *****/
 384.236 +  /*****                      CACHE MANAGER OBJECT                     *****/
 384.237 +  /*****                                                               *****/
 384.238 +  /*************************************************************************/
 384.239 +  /*************************************************************************/
 384.240 +  /*************************************************************************/
 384.241 +
 384.242 +
 384.243 +  /*************************************************************************/
 384.244 +  /*                                                                       */
 384.245 +  /* <Type>                                                                */
 384.246 +  /*    FTC_Manager                                                        */
 384.247 +  /*                                                                       */
 384.248 +  /* <Description>                                                         */
 384.249 +  /*    This object corresponds to one instance of the cache-subsystem.    */
 384.250 +  /*    It is used to cache one or more @FT_Face objects, along with       */
 384.251 +  /*    corresponding @FT_Size objects.                                    */
 384.252 +  /*                                                                       */
 384.253 +  /*    The manager intentionally limits the total number of opened        */
 384.254 +  /*    @FT_Face and @FT_Size objects to control memory usage.  See the    */
 384.255 +  /*    `max_faces' and `max_sizes' parameters of @FTC_Manager_New.        */
 384.256 +  /*                                                                       */
 384.257 +  /*    The manager is also used to cache `nodes' of various types while   */
 384.258 +  /*    limiting their total memory usage.                                 */
 384.259 +  /*                                                                       */
 384.260 +  /*    All limitations are enforced by keeping lists of managed objects   */
 384.261 +  /*    in most-recently-used order, and flushing old nodes to make room   */
 384.262 +  /*    for new ones.                                                      */
 384.263 +  /*                                                                       */
 384.264 +  typedef struct FTC_ManagerRec_*  FTC_Manager;
 384.265 +
 384.266 +
 384.267 +  /*************************************************************************/
 384.268 +  /*                                                                       */
 384.269 +  /* <Type>                                                                */
 384.270 +  /*    FTC_Node                                                           */
 384.271 +  /*                                                                       */
 384.272 +  /* <Description>                                                         */
 384.273 +  /*    An opaque handle to a cache node object.  Each cache node is       */
 384.274 +  /*    reference-counted.  A node with a count of~0 might be flushed      */
 384.275 +  /*    out of a full cache whenever a lookup request is performed.        */
 384.276 +  /*                                                                       */
 384.277 +  /*    If you look up nodes, you have the ability to `acquire' them,      */
 384.278 +  /*    i.e., to increment their reference count.  This will prevent the   */
 384.279 +  /*    node from being flushed out of the cache until you explicitly      */
 384.280 +  /*    `release' it (see @FTC_Node_Unref).                                */
 384.281 +  /*                                                                       */
 384.282 +  /*    See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup.         */
 384.283 +  /*                                                                       */
 384.284 +  typedef struct FTC_NodeRec_*  FTC_Node;
 384.285 +
 384.286 +
 384.287 +  /*************************************************************************/
 384.288 +  /*                                                                       */
 384.289 +  /* <Function>                                                            */
 384.290 +  /*    FTC_Manager_New                                                    */
 384.291 +  /*                                                                       */
 384.292 +  /* <Description>                                                         */
 384.293 +  /*    Create a new cache manager.                                        */
 384.294 +  /*                                                                       */
 384.295 +  /* <Input>                                                               */
 384.296 +  /*    library   :: The parent FreeType library handle to use.            */
 384.297 +  /*                                                                       */
 384.298 +  /*    max_faces :: Maximum number of opened @FT_Face objects managed by  */
 384.299 +  /*                 this cache instance.  Use~0 for defaults.             */
 384.300 +  /*                                                                       */
 384.301 +  /*    max_sizes :: Maximum number of opened @FT_Size objects managed by  */
 384.302 +  /*                 this cache instance.  Use~0 for defaults.             */
 384.303 +  /*                                                                       */
 384.304 +  /*    max_bytes :: Maximum number of bytes to use for cached data nodes. */
 384.305 +  /*                 Use~0 for defaults.  Note that this value does not    */
 384.306 +  /*                 account for managed @FT_Face and @FT_Size objects.    */
 384.307 +  /*                                                                       */
 384.308 +  /*    requester :: An application-provided callback used to translate    */
 384.309 +  /*                 face IDs into real @FT_Face objects.                  */
 384.310 +  /*                                                                       */
 384.311 +  /*    req_data  :: A generic pointer that is passed to the requester     */
 384.312 +  /*                 each time it is called (see @FTC_Face_Requester).     */
 384.313 +  /*                                                                       */
 384.314 +  /* <Output>                                                              */
 384.315 +  /*    amanager  :: A handle to a new manager object.  0~in case of       */
 384.316 +  /*                 failure.                                              */
 384.317 +  /*                                                                       */
 384.318 +  /* <Return>                                                              */
 384.319 +  /*    FreeType error code.  0~means success.                             */
 384.320 +  /*                                                                       */
 384.321 +  FT_EXPORT( FT_Error )
 384.322 +  FTC_Manager_New( FT_Library          library,
 384.323 +                   FT_UInt             max_faces,
 384.324 +                   FT_UInt             max_sizes,
 384.325 +                   FT_ULong            max_bytes,
 384.326 +                   FTC_Face_Requester  requester,
 384.327 +                   FT_Pointer          req_data,
 384.328 +                   FTC_Manager        *amanager );
 384.329 +
 384.330 +
 384.331 +  /*************************************************************************/
 384.332 +  /*                                                                       */
 384.333 +  /* <Function>                                                            */
 384.334 +  /*    FTC_Manager_Reset                                                  */
 384.335 +  /*                                                                       */
 384.336 +  /* <Description>                                                         */
 384.337 +  /*    Empty a given cache manager.  This simply gets rid of all the      */
 384.338 +  /*    currently cached @FT_Face and @FT_Size objects within the manager. */
 384.339 +  /*                                                                       */
 384.340 +  /* <InOut>                                                               */
 384.341 +  /*    manager :: A handle to the manager.                                */
 384.342 +  /*                                                                       */
 384.343 +  FT_EXPORT( void )
 384.344 +  FTC_Manager_Reset( FTC_Manager  manager );
 384.345 +
 384.346 +
 384.347 +  /*************************************************************************/
 384.348 +  /*                                                                       */
 384.349 +  /* <Function>                                                            */
 384.350 +  /*    FTC_Manager_Done                                                   */
 384.351 +  /*                                                                       */
 384.352 +  /* <Description>                                                         */
 384.353 +  /*    Destroy a given manager after emptying it.                         */
 384.354 +  /*                                                                       */
 384.355 +  /* <Input>                                                               */
 384.356 +  /*    manager :: A handle to the target cache manager object.            */
 384.357 +  /*                                                                       */
 384.358 +  FT_EXPORT( void )
 384.359 +  FTC_Manager_Done( FTC_Manager  manager );
 384.360 +
 384.361 +
 384.362 +  /*************************************************************************/
 384.363 +  /*                                                                       */
 384.364 +  /* <Function>                                                            */
 384.365 +  /*    FTC_Manager_LookupFace                                             */
 384.366 +  /*                                                                       */
 384.367 +  /* <Description>                                                         */
 384.368 +  /*    Retrieve the @FT_Face object that corresponds to a given face ID   */
 384.369 +  /*    through a cache manager.                                           */
 384.370 +  /*                                                                       */
 384.371 +  /* <Input>                                                               */
 384.372 +  /*    manager :: A handle to the cache manager.                          */
 384.373 +  /*                                                                       */
 384.374 +  /*    face_id :: The ID of the face object.                              */
 384.375 +  /*                                                                       */
 384.376 +  /* <Output>                                                              */
 384.377 +  /*    aface   :: A handle to the face object.                            */
 384.378 +  /*                                                                       */
 384.379 +  /* <Return>                                                              */
 384.380 +  /*    FreeType error code.  0~means success.                             */
 384.381 +  /*                                                                       */
 384.382 +  /* <Note>                                                                */
 384.383 +  /*    The returned @FT_Face object is always owned by the manager.  You  */
 384.384 +  /*    should never try to discard it yourself.                           */
 384.385 +  /*                                                                       */
 384.386 +  /*    The @FT_Face object doesn't necessarily have a current size object */
 384.387 +  /*    (i.e., face->size can be 0).  If you need a specific `font size',  */
 384.388 +  /*    use @FTC_Manager_LookupSize instead.                               */
 384.389 +  /*                                                                       */
 384.390 +  /*    Never change the face's transformation matrix (i.e., never call    */
 384.391 +  /*    the @FT_Set_Transform function) on a returned face!  If you need   */
 384.392 +  /*    to transform glyphs, do it yourself after glyph loading.           */
 384.393 +  /*                                                                       */
 384.394 +  /*    When you perform a lookup, out-of-memory errors are detected       */
 384.395 +  /*    _within_ the lookup and force incremental flushes of the cache     */
 384.396 +  /*    until enough memory is released for the lookup to succeed.         */
 384.397 +  /*                                                                       */
 384.398 +  /*    If a lookup fails with `FT_Err_Out_Of_Memory' the cache has        */
 384.399 +  /*    already been completely flushed, and still no memory was available */
 384.400 +  /*    for the operation.                                                 */
 384.401 +  /*                                                                       */
 384.402 +  FT_EXPORT( FT_Error )
 384.403 +  FTC_Manager_LookupFace( FTC_Manager  manager,
 384.404 +                          FTC_FaceID   face_id,
 384.405 +                          FT_Face     *aface );
 384.406 +
 384.407 +
 384.408 +  /*************************************************************************/
 384.409 +  /*                                                                       */
 384.410 +  /* <Struct>                                                              */
 384.411 +  /*    FTC_ScalerRec                                                      */
 384.412 +  /*                                                                       */
 384.413 +  /* <Description>                                                         */
 384.414 +  /*    A structure used to describe a given character size in either      */
 384.415 +  /*    pixels or points to the cache manager.  See                        */
 384.416 +  /*    @FTC_Manager_LookupSize.                                           */
 384.417 +  /*                                                                       */
 384.418 +  /* <Fields>                                                              */
 384.419 +  /*    face_id :: The source face ID.                                     */
 384.420 +  /*                                                                       */
 384.421 +  /*    width   :: The character width.                                    */
 384.422 +  /*                                                                       */
 384.423 +  /*    height  :: The character height.                                   */
 384.424 +  /*                                                                       */
 384.425 +  /*    pixel   :: A Boolean.  If 1, the `width' and `height' fields are   */
 384.426 +  /*               interpreted as integer pixel character sizes.           */
 384.427 +  /*               Otherwise, they are expressed as 1/64th of points.      */
 384.428 +  /*                                                                       */
 384.429 +  /*    x_res   :: Only used when `pixel' is value~0 to indicate the       */
 384.430 +  /*               horizontal resolution in dpi.                           */
 384.431 +  /*                                                                       */
 384.432 +  /*    y_res   :: Only used when `pixel' is value~0 to indicate the       */
 384.433 +  /*               vertical resolution in dpi.                             */
 384.434 +  /*                                                                       */
 384.435 +  /* <Note>                                                                */
 384.436 +  /*    This type is mainly used to retrieve @FT_Size objects through the  */
 384.437 +  /*    cache manager.                                                     */
 384.438 +  /*                                                                       */
 384.439 +  typedef struct  FTC_ScalerRec_
 384.440 +  {
 384.441 +    FTC_FaceID  face_id;
 384.442 +    FT_UInt     width;
 384.443 +    FT_UInt     height;
 384.444 +    FT_Int      pixel;
 384.445 +    FT_UInt     x_res;
 384.446 +    FT_UInt     y_res;
 384.447 +
 384.448 +  } FTC_ScalerRec;
 384.449 +
 384.450 +
 384.451 +  /*************************************************************************/
 384.452 +  /*                                                                       */
 384.453 +  /* <Struct>                                                              */
 384.454 +  /*    FTC_Scaler                                                         */
 384.455 +  /*                                                                       */
 384.456 +  /* <Description>                                                         */
 384.457 +  /*    A handle to an @FTC_ScalerRec structure.                           */
 384.458 +  /*                                                                       */
 384.459 +  typedef struct FTC_ScalerRec_*  FTC_Scaler;
 384.460 +
 384.461 +
 384.462 +  /*************************************************************************/
 384.463 +  /*                                                                       */
 384.464 +  /* <Function>                                                            */
 384.465 +  /*    FTC_Manager_LookupSize                                             */
 384.466 +  /*                                                                       */
 384.467 +  /* <Description>                                                         */
 384.468 +  /*    Retrieve the @FT_Size object that corresponds to a given           */
 384.469 +  /*    @FTC_ScalerRec pointer through a cache manager.                    */
 384.470 +  /*                                                                       */
 384.471 +  /* <Input>                                                               */
 384.472 +  /*    manager :: A handle to the cache manager.                          */
 384.473 +  /*                                                                       */
 384.474 +  /*    scaler  :: A scaler handle.                                        */
 384.475 +  /*                                                                       */
 384.476 +  /* <Output>                                                              */
 384.477 +  /*    asize   :: A handle to the size object.                            */
 384.478 +  /*                                                                       */
 384.479 +  /* <Return>                                                              */
 384.480 +  /*    FreeType error code.  0~means success.                             */
 384.481 +  /*                                                                       */
 384.482 +  /* <Note>                                                                */
 384.483 +  /*    The returned @FT_Size object is always owned by the manager.  You  */
 384.484 +  /*    should never try to discard it by yourself.                        */
 384.485 +  /*                                                                       */
 384.486 +  /*    You can access the parent @FT_Face object simply as `size->face'   */
 384.487 +  /*    if you need it.  Note that this object is also owned by the        */
 384.488 +  /*    manager.                                                           */
 384.489 +  /*                                                                       */
 384.490 +  /* <Note>                                                                */
 384.491 +  /*    When you perform a lookup, out-of-memory errors are detected       */
 384.492 +  /*    _within_ the lookup and force incremental flushes of the cache     */
 384.493 +  /*    until enough memory is released for the lookup to succeed.         */
 384.494 +  /*                                                                       */
 384.495 +  /*    If a lookup fails with `FT_Err_Out_Of_Memory' the cache has        */
 384.496 +  /*    already been completely flushed, and still no memory is available  */
 384.497 +  /*    for the operation.                                                 */
 384.498 +  /*                                                                       */
 384.499 +  FT_EXPORT( FT_Error )
 384.500 +  FTC_Manager_LookupSize( FTC_Manager  manager,
 384.501 +                          FTC_Scaler   scaler,
 384.502 +                          FT_Size     *asize );
 384.503 +
 384.504 +
 384.505 +  /*************************************************************************/
 384.506 +  /*                                                                       */
 384.507 +  /* <Function>                                                            */
 384.508 +  /*    FTC_Node_Unref                                                     */
 384.509 +  /*                                                                       */
 384.510 +  /* <Description>                                                         */
 384.511 +  /*    Decrement a cache node's internal reference count.  When the count */
 384.512 +  /*    reaches 0, it is not destroyed but becomes eligible for subsequent */
 384.513 +  /*    cache flushes.                                                     */
 384.514 +  /*                                                                       */
 384.515 +  /* <Input>                                                               */
 384.516 +  /*    node    :: The cache node handle.                                  */
 384.517 +  /*                                                                       */
 384.518 +  /*    manager :: The cache manager handle.                               */
 384.519 +  /*                                                                       */
 384.520 +  FT_EXPORT( void )
 384.521 +  FTC_Node_Unref( FTC_Node     node,
 384.522 +                  FTC_Manager  manager );
 384.523 +
 384.524 +
 384.525 +  /*************************************************************************
 384.526 +   *
 384.527 +   * @function:
 384.528 +   *   FTC_Manager_RemoveFaceID
 384.529 +   *
 384.530 +   * @description:
 384.531 +   *   A special function used to indicate to the cache manager that
 384.532 +   *   a given @FTC_FaceID is no longer valid, either because its
 384.533 +   *   content changed, or because it was deallocated or uninstalled.
 384.534 +   *
 384.535 +   * @input:
 384.536 +   *   manager ::
 384.537 +   *     The cache manager handle.
 384.538 +   *
 384.539 +   *   face_id ::
 384.540 +   *     The @FTC_FaceID to be removed.
 384.541 +   *
 384.542 +   * @note:
 384.543 +   *   This function flushes all nodes from the cache corresponding to this
 384.544 +   *   `face_id', with the exception of nodes with a non-null reference
 384.545 +   *   count.
 384.546 +   *
 384.547 +   *   Such nodes are however modified internally so as to never appear
 384.548 +   *   in later lookups with the same `face_id' value, and to be immediately
 384.549 +   *   destroyed when released by all their users.
 384.550 +   *
 384.551 +   */
 384.552 +  FT_EXPORT( void )
 384.553 +  FTC_Manager_RemoveFaceID( FTC_Manager  manager,
 384.554 +                            FTC_FaceID   face_id );
 384.555 +
 384.556 +
 384.557 +  /*************************************************************************/
 384.558 +  /*                                                                       */
 384.559 +  /* <Section>                                                             */
 384.560 +  /*    cache_subsystem                                                    */
 384.561 +  /*                                                                       */
 384.562 +  /*************************************************************************/
 384.563 +
 384.564 +  /*************************************************************************
 384.565 +   *
 384.566 +   * @type:
 384.567 +   *   FTC_CMapCache
 384.568 +   *
 384.569 +   * @description:
 384.570 +   *   An opaque handle used to model a charmap cache.  This cache is to
 384.571 +   *   hold character codes -> glyph indices mappings.
 384.572 +   *
 384.573 +   */
 384.574 +  typedef struct FTC_CMapCacheRec_*  FTC_CMapCache;
 384.575 +
 384.576 +
 384.577 +  /*************************************************************************
 384.578 +   *
 384.579 +   * @function:
 384.580 +   *   FTC_CMapCache_New
 384.581 +   *
 384.582 +   * @description:
 384.583 +   *   Create a new charmap cache.
 384.584 +   *
 384.585 +   * @input:
 384.586 +   *   manager ::
 384.587 +   *     A handle to the cache manager.
 384.588 +   *
 384.589 +   * @output:
 384.590 +   *   acache ::
 384.591 +   *     A new cache handle.  NULL in case of error.
 384.592 +   *
 384.593 +   * @return:
 384.594 +   *   FreeType error code.  0~means success.
 384.595 +   *
 384.596 +   * @note:
 384.597 +   *   Like all other caches, this one will be destroyed with the cache
 384.598 +   *   manager.
 384.599 +   *
 384.600 +   */
 384.601 +  FT_EXPORT( FT_Error )
 384.602 +  FTC_CMapCache_New( FTC_Manager     manager,
 384.603 +                     FTC_CMapCache  *acache );
 384.604 +
 384.605 +
 384.606 +  /************************************************************************
 384.607 +   *
 384.608 +   * @function:
 384.609 +   *   FTC_CMapCache_Lookup
 384.610 +   *
 384.611 +   * @description:
 384.612 +   *   Translate a character code into a glyph index, using the charmap
 384.613 +   *   cache.
 384.614 +   *
 384.615 +   * @input:
 384.616 +   *   cache ::
 384.617 +   *     A charmap cache handle.
 384.618 +   *
 384.619 +   *   face_id ::
 384.620 +   *     The source face ID.
 384.621 +   *
 384.622 +   *   cmap_index ::
 384.623 +   *     The index of the charmap in the source face.  Any negative value
 384.624 +   *     means to use the cache @FT_Face's default charmap.
 384.625 +   *
 384.626 +   *   char_code ::
 384.627 +   *     The character code (in the corresponding charmap).
 384.628 +   *
 384.629 +   * @return:
 384.630 +   *    Glyph index.  0~means `no glyph'.
 384.631 +   *
 384.632 +   */
 384.633 +  FT_EXPORT( FT_UInt )
 384.634 +  FTC_CMapCache_Lookup( FTC_CMapCache  cache,
 384.635 +                        FTC_FaceID     face_id,
 384.636 +                        FT_Int         cmap_index,
 384.637 +                        FT_UInt32      char_code );
 384.638 +
 384.639 +
 384.640 +  /*************************************************************************/
 384.641 +  /*                                                                       */
 384.642 +  /* <Section>                                                             */
 384.643 +  /*    cache_subsystem                                                    */
 384.644 +  /*                                                                       */
 384.645 +  /*************************************************************************/
 384.646 +
 384.647 +
 384.648 +  /*************************************************************************/
 384.649 +  /*************************************************************************/
 384.650 +  /*************************************************************************/
 384.651 +  /*****                                                               *****/
 384.652 +  /*****                       IMAGE CACHE OBJECT                      *****/
 384.653 +  /*****                                                               *****/
 384.654 +  /*************************************************************************/
 384.655 +  /*************************************************************************/
 384.656 +  /*************************************************************************/
 384.657 +
 384.658 +
 384.659 +  /*************************************************************************
 384.660 +   *
 384.661 +   * @struct:
 384.662 +   *   FTC_ImageTypeRec
 384.663 +   *
 384.664 +   * @description:
 384.665 +   *   A structure used to model the type of images in a glyph cache.
 384.666 +   *
 384.667 +   * @fields:
 384.668 +   *   face_id ::
 384.669 +   *     The face ID.
 384.670 +   *
 384.671 +   *   width ::
 384.672 +   *     The width in pixels.
 384.673 +   *
 384.674 +   *   height ::
 384.675 +   *     The height in pixels.
 384.676 +   *
 384.677 +   *   flags ::
 384.678 +   *     The load flags, as in @FT_Load_Glyph.
 384.679 +   *
 384.680 +   */
 384.681 +  typedef struct  FTC_ImageTypeRec_
 384.682 +  {
 384.683 +    FTC_FaceID  face_id;
 384.684 +    FT_Int      width;
 384.685 +    FT_Int      height;
 384.686 +    FT_Int32    flags;
 384.687 +
 384.688 +  } FTC_ImageTypeRec;
 384.689 +
 384.690 +
 384.691 +  /*************************************************************************
 384.692 +   *
 384.693 +   * @type:
 384.694 +   *   FTC_ImageType
 384.695 +   *
 384.696 +   * @description:
 384.697 +   *   A handle to an @FTC_ImageTypeRec structure.
 384.698 +   *
 384.699 +   */
 384.700 +  typedef struct FTC_ImageTypeRec_*  FTC_ImageType;
 384.701 +
 384.702 +
 384.703 +  /* */
 384.704 +
 384.705 +
 384.706 +#define FTC_IMAGE_TYPE_COMPARE( d1, d2 )      \
 384.707 +          ( (d1)->face_id == (d2)->face_id && \
 384.708 +            (d1)->width   == (d2)->width   && \
 384.709 +            (d1)->flags   == (d2)->flags   )
 384.710 +
 384.711 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 384.712 +
 384.713 +  /* this macro is incompatible with LLP64, should not be used */
 384.714 +
 384.715 +#define FTC_IMAGE_TYPE_HASH( d )                          \
 384.716 +          (FT_UFast)( FTC_FACE_ID_HASH( (d)->face_id )  ^ \
 384.717 +                      ( (d)->width << 8 ) ^ (d)->height ^ \
 384.718 +                      ( (d)->flags << 4 )               )
 384.719 +
 384.720 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
 384.721 +
 384.722 +
 384.723 +  /*************************************************************************/
 384.724 +  /*                                                                       */
 384.725 +  /* <Type>                                                                */
 384.726 +  /*    FTC_ImageCache                                                     */
 384.727 +  /*                                                                       */
 384.728 +  /* <Description>                                                         */
 384.729 +  /*    A handle to an glyph image cache object.  They are designed to     */
 384.730 +  /*    hold many distinct glyph images while not exceeding a certain      */
 384.731 +  /*    memory threshold.                                                  */
 384.732 +  /*                                                                       */
 384.733 +  typedef struct FTC_ImageCacheRec_*  FTC_ImageCache;
 384.734 +
 384.735 +
 384.736 +  /*************************************************************************/
 384.737 +  /*                                                                       */
 384.738 +  /* <Function>                                                            */
 384.739 +  /*    FTC_ImageCache_New                                                 */
 384.740 +  /*                                                                       */
 384.741 +  /* <Description>                                                         */
 384.742 +  /*    Create a new glyph image cache.                                    */
 384.743 +  /*                                                                       */
 384.744 +  /* <Input>                                                               */
 384.745 +  /*    manager :: The parent manager for the image cache.                 */
 384.746 +  /*                                                                       */
 384.747 +  /* <Output>                                                              */
 384.748 +  /*    acache  :: A handle to the new glyph image cache object.           */
 384.749 +  /*                                                                       */
 384.750 +  /* <Return>                                                              */
 384.751 +  /*    FreeType error code.  0~means success.                             */
 384.752 +  /*                                                                       */
 384.753 +  FT_EXPORT( FT_Error )
 384.754 +  FTC_ImageCache_New( FTC_Manager      manager,
 384.755 +                      FTC_ImageCache  *acache );
 384.756 +
 384.757 +
 384.758 +  /*************************************************************************/
 384.759 +  /*                                                                       */
 384.760 +  /* <Function>                                                            */
 384.761 +  /*    FTC_ImageCache_Lookup                                              */
 384.762 +  /*                                                                       */
 384.763 +  /* <Description>                                                         */
 384.764 +  /*    Retrieve a given glyph image from a glyph image cache.             */
 384.765 +  /*                                                                       */
 384.766 +  /* <Input>                                                               */
 384.767 +  /*    cache  :: A handle to the source glyph image cache.                */
 384.768 +  /*                                                                       */
 384.769 +  /*    type   :: A pointer to a glyph image type descriptor.              */
 384.770 +  /*                                                                       */
 384.771 +  /*    gindex :: The glyph index to retrieve.                             */
 384.772 +  /*                                                                       */
 384.773 +  /* <Output>                                                              */
 384.774 +  /*    aglyph :: The corresponding @FT_Glyph object.  0~in case of        */
 384.775 +  /*              failure.                                                 */
 384.776 +  /*                                                                       */
 384.777 +  /*    anode  :: Used to return the address of of the corresponding cache */
 384.778 +  /*              node after incrementing its reference count (see note    */
 384.779 +  /*              below).                                                  */
 384.780 +  /*                                                                       */
 384.781 +  /* <Return>                                                              */
 384.782 +  /*    FreeType error code.  0~means success.                             */
 384.783 +  /*                                                                       */
 384.784 +  /* <Note>                                                                */
 384.785 +  /*    The returned glyph is owned and managed by the glyph image cache.  */
 384.786 +  /*    Never try to transform or discard it manually!  You can however    */
 384.787 +  /*    create a copy with @FT_Glyph_Copy and modify the new one.          */
 384.788 +  /*                                                                       */
 384.789 +  /*    If `anode' is _not_ NULL, it receives the address of the cache     */
 384.790 +  /*    node containing the glyph image, after increasing its reference    */
 384.791 +  /*    count.  This ensures that the node (as well as the @FT_Glyph) will */
 384.792 +  /*    always be kept in the cache until you call @FTC_Node_Unref to      */
 384.793 +  /*    `release' it.                                                      */
 384.794 +  /*                                                                       */
 384.795 +  /*    If `anode' is NULL, the cache node is left unchanged, which means  */
 384.796 +  /*    that the @FT_Glyph could be flushed out of the cache on the next   */
 384.797 +  /*    call to one of the caching sub-system APIs.  Don't assume that it  */
 384.798 +  /*    is persistent!                                                     */
 384.799 +  /*                                                                       */
 384.800 +  FT_EXPORT( FT_Error )
 384.801 +  FTC_ImageCache_Lookup( FTC_ImageCache  cache,
 384.802 +                         FTC_ImageType   type,
 384.803 +                         FT_UInt         gindex,
 384.804 +                         FT_Glyph       *aglyph,
 384.805 +                         FTC_Node       *anode );
 384.806 +
 384.807 +
 384.808 +  /*************************************************************************/
 384.809 +  /*                                                                       */
 384.810 +  /* <Function>                                                            */
 384.811 +  /*    FTC_ImageCache_LookupScaler                                        */
 384.812 +  /*                                                                       */
 384.813 +  /* <Description>                                                         */
 384.814 +  /*    A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec    */
 384.815 +  /*    to specify the face ID and its size.                               */
 384.816 +  /*                                                                       */
 384.817 +  /* <Input>                                                               */
 384.818 +  /*    cache      :: A handle to the source glyph image cache.            */
 384.819 +  /*                                                                       */
 384.820 +  /*    scaler     :: A pointer to a scaler descriptor.                    */
 384.821 +  /*                                                                       */
 384.822 +  /*    load_flags :: The corresponding load flags.                        */
 384.823 +  /*                                                                       */
 384.824 +  /*    gindex     :: The glyph index to retrieve.                         */
 384.825 +  /*                                                                       */
 384.826 +  /* <Output>                                                              */
 384.827 +  /*    aglyph     :: The corresponding @FT_Glyph object.  0~in case of    */
 384.828 +  /*                  failure.                                             */
 384.829 +  /*                                                                       */
 384.830 +  /*    anode      :: Used to return the address of of the corresponding   */
 384.831 +  /*                  cache node after incrementing its reference count    */
 384.832 +  /*                  (see note below).                                    */
 384.833 +  /*                                                                       */
 384.834 +  /* <Return>                                                              */
 384.835 +  /*    FreeType error code.  0~means success.                             */
 384.836 +  /*                                                                       */
 384.837 +  /* <Note>                                                                */
 384.838 +  /*    The returned glyph is owned and managed by the glyph image cache.  */
 384.839 +  /*    Never try to transform or discard it manually!  You can however    */
 384.840 +  /*    create a copy with @FT_Glyph_Copy and modify the new one.          */
 384.841 +  /*                                                                       */
 384.842 +  /*    If `anode' is _not_ NULL, it receives the address of the cache     */
 384.843 +  /*    node containing the glyph image, after increasing its reference    */
 384.844 +  /*    count.  This ensures that the node (as well as the @FT_Glyph) will */
 384.845 +  /*    always be kept in the cache until you call @FTC_Node_Unref to      */
 384.846 +  /*    `release' it.                                                      */
 384.847 +  /*                                                                       */
 384.848 +  /*    If `anode' is NULL, the cache node is left unchanged, which means  */
 384.849 +  /*    that the @FT_Glyph could be flushed out of the cache on the next   */
 384.850 +  /*    call to one of the caching sub-system APIs.  Don't assume that it  */
 384.851 +  /*    is persistent!                                                     */
 384.852 +  /*                                                                       */
 384.853 +  /*    Calls to @FT_Set_Char_Size and friends have no effect on cached    */
 384.854 +  /*    glyphs; you should always use the FreeType cache API instead.      */
 384.855 +  /*                                                                       */
 384.856 +  FT_EXPORT( FT_Error )
 384.857 +  FTC_ImageCache_LookupScaler( FTC_ImageCache  cache,
 384.858 +                               FTC_Scaler      scaler,
 384.859 +                               FT_ULong        load_flags,
 384.860 +                               FT_UInt         gindex,
 384.861 +                               FT_Glyph       *aglyph,
 384.862 +                               FTC_Node       *anode );
 384.863 +
 384.864 +
 384.865 +  /*************************************************************************/
 384.866 +  /*                                                                       */
 384.867 +  /* <Type>                                                                */
 384.868 +  /*    FTC_SBit                                                           */
 384.869 +  /*                                                                       */
 384.870 +  /* <Description>                                                         */
 384.871 +  /*    A handle to a small bitmap descriptor.  See the @FTC_SBitRec       */
 384.872 +  /*    structure for details.                                             */
 384.873 +  /*                                                                       */
 384.874 +  typedef struct FTC_SBitRec_*  FTC_SBit;
 384.875 +
 384.876 +
 384.877 +  /*************************************************************************/
 384.878 +  /*                                                                       */
 384.879 +  /* <Struct>                                                              */
 384.880 +  /*    FTC_SBitRec                                                        */
 384.881 +  /*                                                                       */
 384.882 +  /* <Description>                                                         */
 384.883 +  /*    A very compact structure used to describe a small glyph bitmap.    */
 384.884 +  /*                                                                       */
 384.885 +  /* <Fields>                                                              */
 384.886 +  /*    width     :: The bitmap width in pixels.                           */
 384.887 +  /*                                                                       */
 384.888 +  /*    height    :: The bitmap height in pixels.                          */
 384.889 +  /*                                                                       */
 384.890 +  /*    left      :: The horizontal distance from the pen position to the  */
 384.891 +  /*                 left bitmap border (a.k.a. `left side bearing', or    */
 384.892 +  /*                 `lsb').                                               */
 384.893 +  /*                                                                       */
 384.894 +  /*    top       :: The vertical distance from the pen position (on the   */
 384.895 +  /*                 baseline) to the upper bitmap border (a.k.a. `top     */
 384.896 +  /*                 side bearing').  The distance is positive for upwards */
 384.897 +  /*                 y~coordinates.                                        */
 384.898 +  /*                                                                       */
 384.899 +  /*    format    :: The format of the glyph bitmap (monochrome or gray).  */
 384.900 +  /*                                                                       */
 384.901 +  /*    max_grays :: Maximum gray level value (in the range 1 to~255).     */
 384.902 +  /*                                                                       */
 384.903 +  /*    pitch     :: The number of bytes per bitmap line.  May be positive */
 384.904 +  /*                 or negative.                                          */
 384.905 +  /*                                                                       */
 384.906 +  /*    xadvance  :: The horizontal advance width in pixels.               */
 384.907 +  /*                                                                       */
 384.908 +  /*    yadvance  :: The vertical advance height in pixels.                */
 384.909 +  /*                                                                       */
 384.910 +  /*    buffer    :: A pointer to the bitmap pixels.                       */
 384.911 +  /*                                                                       */
 384.912 +  typedef struct  FTC_SBitRec_
 384.913 +  {
 384.914 +    FT_Byte   width;
 384.915 +    FT_Byte   height;
 384.916 +    FT_Char   left;
 384.917 +    FT_Char   top;
 384.918 +
 384.919 +    FT_Byte   format;
 384.920 +    FT_Byte   max_grays;
 384.921 +    FT_Short  pitch;
 384.922 +    FT_Char   xadvance;
 384.923 +    FT_Char   yadvance;
 384.924 +
 384.925 +    FT_Byte*  buffer;
 384.926 +
 384.927 +  } FTC_SBitRec;
 384.928 +
 384.929 +
 384.930 +  /*************************************************************************/
 384.931 +  /*                                                                       */
 384.932 +  /* <Type>                                                                */
 384.933 +  /*    FTC_SBitCache                                                      */
 384.934 +  /*                                                                       */
 384.935 +  /* <Description>                                                         */
 384.936 +  /*    A handle to a small bitmap cache.  These are special cache objects */
 384.937 +  /*    used to store small glyph bitmaps (and anti-aliased pixmaps) in a  */
 384.938 +  /*    much more efficient way than the traditional glyph image cache     */
 384.939 +  /*    implemented by @FTC_ImageCache.                                    */
 384.940 +  /*                                                                       */
 384.941 +  typedef struct FTC_SBitCacheRec_*  FTC_SBitCache;
 384.942 +
 384.943 +
 384.944 +  /*************************************************************************/
 384.945 +  /*                                                                       */
 384.946 +  /* <Function>                                                            */
 384.947 +  /*    FTC_SBitCache_New                                                  */
 384.948 +  /*                                                                       */
 384.949 +  /* <Description>                                                         */
 384.950 +  /*    Create a new cache to store small glyph bitmaps.                   */
 384.951 +  /*                                                                       */
 384.952 +  /* <Input>                                                               */
 384.953 +  /*    manager :: A handle to the source cache manager.                   */
 384.954 +  /*                                                                       */
 384.955 +  /* <Output>                                                              */
 384.956 +  /*    acache  :: A handle to the new sbit cache.  NULL in case of error. */
 384.957 +  /*                                                                       */
 384.958 +  /* <Return>                                                              */
 384.959 +  /*    FreeType error code.  0~means success.                             */
 384.960 +  /*                                                                       */
 384.961 +  FT_EXPORT( FT_Error )
 384.962 +  FTC_SBitCache_New( FTC_Manager     manager,
 384.963 +                     FTC_SBitCache  *acache );
 384.964 +
 384.965 +
 384.966 +  /*************************************************************************/
 384.967 +  /*                                                                       */
 384.968 +  /* <Function>                                                            */
 384.969 +  /*    FTC_SBitCache_Lookup                                               */
 384.970 +  /*                                                                       */
 384.971 +  /* <Description>                                                         */
 384.972 +  /*    Look up a given small glyph bitmap in a given sbit cache and       */
 384.973 +  /*    `lock' it to prevent its flushing from the cache until needed.     */
 384.974 +  /*                                                                       */
 384.975 +  /* <Input>                                                               */
 384.976 +  /*    cache  :: A handle to the source sbit cache.                       */
 384.977 +  /*                                                                       */
 384.978 +  /*    type   :: A pointer to the glyph image type descriptor.            */
 384.979 +  /*                                                                       */
 384.980 +  /*    gindex :: The glyph index.                                         */
 384.981 +  /*                                                                       */
 384.982 +  /* <Output>                                                              */
 384.983 +  /*    sbit   :: A handle to a small bitmap descriptor.                   */
 384.984 +  /*                                                                       */
 384.985 +  /*    anode  :: Used to return the address of of the corresponding cache */
 384.986 +  /*              node after incrementing its reference count (see note    */
 384.987 +  /*              below).                                                  */
 384.988 +  /*                                                                       */
 384.989 +  /* <Return>                                                              */
 384.990 +  /*    FreeType error code.  0~means success.                             */
 384.991 +  /*                                                                       */
 384.992 +  /* <Note>                                                                */
 384.993 +  /*    The small bitmap descriptor and its bit buffer are owned by the    */
 384.994 +  /*    cache and should never be freed by the application.  They might    */
 384.995 +  /*    as well disappear from memory on the next cache lookup, so don't   */
 384.996 +  /*    treat them as persistent data.                                     */
 384.997 +  /*                                                                       */
 384.998 +  /*    The descriptor's `buffer' field is set to~0 to indicate a missing  */
 384.999 +  /*    glyph bitmap.                                                      */
384.1000 +  /*                                                                       */
384.1001 +  /*    If `anode' is _not_ NULL, it receives the address of the cache     */
384.1002 +  /*    node containing the bitmap, after increasing its reference count.  */
384.1003 +  /*    This ensures that the node (as well as the image) will always be   */
384.1004 +  /*    kept in the cache until you call @FTC_Node_Unref to `release' it.  */
384.1005 +  /*                                                                       */
384.1006 +  /*    If `anode' is NULL, the cache node is left unchanged, which means  */
384.1007 +  /*    that the bitmap could be flushed out of the cache on the next      */
384.1008 +  /*    call to one of the caching sub-system APIs.  Don't assume that it  */
384.1009 +  /*    is persistent!                                                     */
384.1010 +  /*                                                                       */
384.1011 +  FT_EXPORT( FT_Error )
384.1012 +  FTC_SBitCache_Lookup( FTC_SBitCache    cache,
384.1013 +                        FTC_ImageType    type,
384.1014 +                        FT_UInt          gindex,
384.1015 +                        FTC_SBit        *sbit,
384.1016 +                        FTC_Node        *anode );
384.1017 +
384.1018 +
384.1019 +  /*************************************************************************/
384.1020 +  /*                                                                       */
384.1021 +  /* <Function>                                                            */
384.1022 +  /*    FTC_SBitCache_LookupScaler                                         */
384.1023 +  /*                                                                       */
384.1024 +  /* <Description>                                                         */
384.1025 +  /*    A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec     */
384.1026 +  /*    to specify the face ID and its size.                               */
384.1027 +  /*                                                                       */
384.1028 +  /* <Input>                                                               */
384.1029 +  /*    cache      :: A handle to the source sbit cache.                   */
384.1030 +  /*                                                                       */
384.1031 +  /*    scaler     :: A pointer to the scaler descriptor.                  */
384.1032 +  /*                                                                       */
384.1033 +  /*    load_flags :: The corresponding load flags.                        */
384.1034 +  /*                                                                       */
384.1035 +  /*    gindex     :: The glyph index.                                     */
384.1036 +  /*                                                                       */
384.1037 +  /* <Output>                                                              */
384.1038 +  /*    sbit       :: A handle to a small bitmap descriptor.               */
384.1039 +  /*                                                                       */
384.1040 +  /*    anode      :: Used to return the address of of the corresponding   */
384.1041 +  /*                  cache node after incrementing its reference count    */
384.1042 +  /*                  (see note below).                                    */
384.1043 +  /*                                                                       */
384.1044 +  /* <Return>                                                              */
384.1045 +  /*    FreeType error code.  0~means success.                             */
384.1046 +  /*                                                                       */
384.1047 +  /* <Note>                                                                */
384.1048 +  /*    The small bitmap descriptor and its bit buffer are owned by the    */
384.1049 +  /*    cache and should never be freed by the application.  They might    */
384.1050 +  /*    as well disappear from memory on the next cache lookup, so don't   */
384.1051 +  /*    treat them as persistent data.                                     */
384.1052 +  /*                                                                       */
384.1053 +  /*    The descriptor's `buffer' field is set to~0 to indicate a missing  */
384.1054 +  /*    glyph bitmap.                                                      */
384.1055 +  /*                                                                       */
384.1056 +  /*    If `anode' is _not_ NULL, it receives the address of the cache     */
384.1057 +  /*    node containing the bitmap, after increasing its reference count.  */
384.1058 +  /*    This ensures that the node (as well as the image) will always be   */
384.1059 +  /*    kept in the cache until you call @FTC_Node_Unref to `release' it.  */
384.1060 +  /*                                                                       */
384.1061 +  /*    If `anode' is NULL, the cache node is left unchanged, which means  */
384.1062 +  /*    that the bitmap could be flushed out of the cache on the next      */
384.1063 +  /*    call to one of the caching sub-system APIs.  Don't assume that it  */
384.1064 +  /*    is persistent!                                                     */
384.1065 +  /*                                                                       */
384.1066 +  FT_EXPORT( FT_Error )
384.1067 +  FTC_SBitCache_LookupScaler( FTC_SBitCache  cache,
384.1068 +                              FTC_Scaler     scaler,
384.1069 +                              FT_ULong       load_flags,
384.1070 +                              FT_UInt        gindex,
384.1071 +                              FTC_SBit      *sbit,
384.1072 +                              FTC_Node      *anode );
384.1073 +
384.1074 +
384.1075 + /* */
384.1076 +
384.1077 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
384.1078 +
384.1079 +  /*@***********************************************************************/
384.1080 +  /*                                                                       */
384.1081 +  /* <Struct>                                                              */
384.1082 +  /*    FTC_FontRec                                                        */
384.1083 +  /*                                                                       */
384.1084 +  /* <Description>                                                         */
384.1085 +  /*    A simple structure used to describe a given `font' to the cache    */
384.1086 +  /*    manager.  Note that a `font' is the combination of a given face    */
384.1087 +  /*    with a given character size.                                       */
384.1088 +  /*                                                                       */
384.1089 +  /* <Fields>                                                              */
384.1090 +  /*    face_id    :: The ID of the face to use.                           */
384.1091 +  /*                                                                       */
384.1092 +  /*    pix_width  :: The character width in integer pixels.               */
384.1093 +  /*                                                                       */
384.1094 +  /*    pix_height :: The character height in integer pixels.              */
384.1095 +  /*                                                                       */
384.1096 +  typedef struct  FTC_FontRec_
384.1097 +  {
384.1098 +    FTC_FaceID  face_id;
384.1099 +    FT_UShort   pix_width;
384.1100 +    FT_UShort   pix_height;
384.1101 +
384.1102 +  } FTC_FontRec;
384.1103 +
384.1104 +
384.1105 +  /* */
384.1106 +
384.1107 +
384.1108 +#define FTC_FONT_COMPARE( f1, f2 )                  \
384.1109 +          ( (f1)->face_id    == (f2)->face_id    && \
384.1110 +            (f1)->pix_width  == (f2)->pix_width  && \
384.1111 +            (f1)->pix_height == (f2)->pix_height )
384.1112 +
384.1113 +  /* this macro is incompatible with LLP64, should not be used */
384.1114 +#define FTC_FONT_HASH( f )                              \
384.1115 +          (FT_UInt32)( FTC_FACE_ID_HASH((f)->face_id) ^ \
384.1116 +                       ((f)->pix_width << 8)          ^ \
384.1117 +                       ((f)->pix_height)              )
384.1118 +
384.1119 +  typedef FTC_FontRec*  FTC_Font;
384.1120 +
384.1121 +
384.1122 +  FT_EXPORT( FT_Error )
384.1123 +  FTC_Manager_Lookup_Face( FTC_Manager  manager,
384.1124 +                           FTC_FaceID   face_id,
384.1125 +                           FT_Face     *aface );
384.1126 +
384.1127 +  FT_EXPORT( FT_Error )
384.1128 +  FTC_Manager_Lookup_Size( FTC_Manager  manager,
384.1129 +                           FTC_Font     font,
384.1130 +                           FT_Face     *aface,
384.1131 +                           FT_Size     *asize );
384.1132 +
384.1133 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
384.1134 +
384.1135 +
384.1136 + /* */
384.1137 +
384.1138 +FT_END_HEADER
384.1139 +
384.1140 +#endif /* __FTCACHE_H__ */
384.1141 +
384.1142 +
384.1143 +/* END */
   385.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   385.2 +++ b/libs/ft2static/freetype/ftchapters.h	Sat Feb 01 19:58:19 2014 +0200
   385.3 @@ -0,0 +1,103 @@
   385.4 +/***************************************************************************/
   385.5 +/*                                                                         */
   385.6 +/* This file defines the structure of the FreeType reference.              */
   385.7 +/* It is used by the python script which generates the HTML files.         */
   385.8 +/*                                                                         */
   385.9 +/***************************************************************************/
  385.10 +
  385.11 +
  385.12 +/***************************************************************************/
  385.13 +/*                                                                         */
  385.14 +/* <Chapter>                                                               */
  385.15 +/*    general_remarks                                                      */
  385.16 +/*                                                                         */
  385.17 +/* <Title>                                                                 */
  385.18 +/*    General Remarks                                                      */
  385.19 +/*                                                                         */
  385.20 +/* <Sections>                                                              */
  385.21 +/*    user_allocation                                                      */
  385.22 +/*                                                                         */
  385.23 +/***************************************************************************/
  385.24 +
  385.25 +
  385.26 +/***************************************************************************/
  385.27 +/*                                                                         */
  385.28 +/* <Chapter>                                                               */
  385.29 +/*    core_api                                                             */
  385.30 +/*                                                                         */
  385.31 +/* <Title>                                                                 */
  385.32 +/*    Core API                                                             */
  385.33 +/*                                                                         */
  385.34 +/* <Sections>                                                              */
  385.35 +/*    version                                                              */
  385.36 +/*    basic_types                                                          */
  385.37 +/*    base_interface                                                       */
  385.38 +/*    glyph_variants                                                       */
  385.39 +/*    glyph_management                                                     */
  385.40 +/*    mac_specific                                                         */
  385.41 +/*    sizes_management                                                     */
  385.42 +/*    header_file_macros                                                   */
  385.43 +/*                                                                         */
  385.44 +/***************************************************************************/
  385.45 +
  385.46 +
  385.47 +/***************************************************************************/
  385.48 +/*                                                                         */
  385.49 +/* <Chapter>                                                               */
  385.50 +/*    format_specific                                                      */
  385.51 +/*                                                                         */
  385.52 +/* <Title>                                                                 */
  385.53 +/*    Format-Specific API                                                  */
  385.54 +/*                                                                         */
  385.55 +/* <Sections>                                                              */
  385.56 +/*    multiple_masters                                                     */
  385.57 +/*    truetype_tables                                                      */
  385.58 +/*    type1_tables                                                         */
  385.59 +/*    sfnt_names                                                           */
  385.60 +/*    bdf_fonts                                                            */
  385.61 +/*    cid_fonts                                                            */
  385.62 +/*    pfr_fonts                                                            */
  385.63 +/*    winfnt_fonts                                                         */
  385.64 +/*    font_formats                                                         */
  385.65 +/*    gasp_table                                                           */
  385.66 +/*                                                                         */
  385.67 +/***************************************************************************/
  385.68 +
  385.69 +
  385.70 +/***************************************************************************/
  385.71 +/*                                                                         */
  385.72 +/* <Chapter>                                                               */
  385.73 +/*    cache_subsystem                                                      */
  385.74 +/*                                                                         */
  385.75 +/* <Title>                                                                 */
  385.76 +/*    Cache Sub-System                                                     */
  385.77 +/*                                                                         */
  385.78 +/* <Sections>                                                              */
  385.79 +/*    cache_subsystem                                                      */
  385.80 +/*                                                                         */
  385.81 +/***************************************************************************/
  385.82 +
  385.83 +
  385.84 +/***************************************************************************/
  385.85 +/*                                                                         */
  385.86 +/* <Chapter>                                                               */
  385.87 +/*    support_api                                                          */
  385.88 +/*                                                                         */
  385.89 +/* <Title>                                                                 */
  385.90 +/*    Support API                                                          */
  385.91 +/*                                                                         */
  385.92 +/* <Sections>                                                              */
  385.93 +/*    computations                                                         */
  385.94 +/*    list_processing                                                      */
  385.95 +/*    outline_processing                                                   */
  385.96 +/*    quick_advance                                                        */
  385.97 +/*    bitmap_handling                                                      */
  385.98 +/*    raster                                                               */
  385.99 +/*    glyph_stroker                                                        */
 385.100 +/*    system_interface                                                     */
 385.101 +/*    module_management                                                    */
 385.102 +/*    gzip                                                                 */
 385.103 +/*    lzw                                                                  */
 385.104 +/*    lcd_filtering                                                        */
 385.105 +/*                                                                         */
 385.106 +/***************************************************************************/
   386.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   386.2 +++ b/libs/ft2static/freetype/ftcid.h	Sat Feb 01 19:58:19 2014 +0200
   386.3 @@ -0,0 +1,166 @@
   386.4 +/***************************************************************************/
   386.5 +/*                                                                         */
   386.6 +/*  ftcid.h                                                                */
   386.7 +/*                                                                         */
   386.8 +/*    FreeType API for accessing CID font information (specification).     */
   386.9 +/*                                                                         */
  386.10 +/*  Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal.                  */
  386.11 +/*                                                                         */
  386.12 +/*  This file is part of the FreeType project, and may only be used,       */
  386.13 +/*  modified, and distributed under the terms of the FreeType project      */
  386.14 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  386.15 +/*  this file you indicate that you have read the license and              */
  386.16 +/*  understand and accept it fully.                                        */
  386.17 +/*                                                                         */
  386.18 +/***************************************************************************/
  386.19 +
  386.20 +
  386.21 +#ifndef __FTCID_H__
  386.22 +#define __FTCID_H__
  386.23 +
  386.24 +#include <ft2build.h>
  386.25 +#include FT_FREETYPE_H
  386.26 +
  386.27 +#ifdef FREETYPE_H
  386.28 +#error "freetype.h of FreeType 1 has been loaded!"
  386.29 +#error "Please fix the directory search order for header files"
  386.30 +#error "so that freetype.h of FreeType 2 is found first."
  386.31 +#endif
  386.32 +
  386.33 +
  386.34 +FT_BEGIN_HEADER
  386.35 +
  386.36 +
  386.37 +  /*************************************************************************/
  386.38 +  /*                                                                       */
  386.39 +  /* <Section>                                                             */
  386.40 +  /*    cid_fonts                                                          */
  386.41 +  /*                                                                       */
  386.42 +  /* <Title>                                                               */
  386.43 +  /*    CID Fonts                                                          */
  386.44 +  /*                                                                       */
  386.45 +  /* <Abstract>                                                            */
  386.46 +  /*    CID-keyed font specific API.                                       */
  386.47 +  /*                                                                       */
  386.48 +  /* <Description>                                                         */
  386.49 +  /*    This section contains the declaration of CID-keyed font specific   */
  386.50 +  /*    functions.                                                         */
  386.51 +  /*                                                                       */
  386.52 +  /*************************************************************************/
  386.53 +
  386.54 +
  386.55 +  /**********************************************************************
  386.56 +   *
  386.57 +   * @function:
  386.58 +   *    FT_Get_CID_Registry_Ordering_Supplement
  386.59 +   *
  386.60 +   * @description:
  386.61 +   *    Retrieve the Registry/Ordering/Supplement triple (also known as the
  386.62 +   *    "R/O/S") from a CID-keyed font.
  386.63 +   *
  386.64 +   * @input:
  386.65 +   *    face ::
  386.66 +   *       A handle to the input face.
  386.67 +   *
  386.68 +   * @output:
  386.69 +   *    registry ::
  386.70 +   *       The registry, as a C~string, owned by the face.
  386.71 +   *
  386.72 +   *    ordering ::
  386.73 +   *       The ordering, as a C~string, owned by the face.
  386.74 +   *
  386.75 +   *    supplement ::
  386.76 +   *       The supplement.
  386.77 +   *
  386.78 +   * @return:
  386.79 +   *    FreeType error code.  0~means success.
  386.80 +   *
  386.81 +   * @note:
  386.82 +   *    This function only works with CID faces, returning an error
  386.83 +   *    otherwise.
  386.84 +   *
  386.85 +   * @since:
  386.86 +   *    2.3.6
  386.87 +   */
  386.88 +  FT_EXPORT( FT_Error )
  386.89 +  FT_Get_CID_Registry_Ordering_Supplement( FT_Face       face,
  386.90 +                                           const char*  *registry,
  386.91 +                                           const char*  *ordering,
  386.92 +                                           FT_Int       *supplement);
  386.93 +
  386.94 +
  386.95 +  /**********************************************************************
  386.96 +   *
  386.97 +   * @function:
  386.98 +   *    FT_Get_CID_Is_Internally_CID_Keyed
  386.99 +   *
 386.100 +   * @description:
 386.101 +   *    Retrieve the type of the input face, CID keyed or not.  In
 386.102 +   *    constrast to the @FT_IS_CID_KEYED macro this function returns
 386.103 +   *    successfully also for CID-keyed fonts in an SNFT wrapper.
 386.104 +   *
 386.105 +   * @input:
 386.106 +   *    face ::
 386.107 +   *       A handle to the input face.
 386.108 +   *
 386.109 +   * @output:
 386.110 +   *    is_cid ::
 386.111 +   *       The type of the face as an @FT_Bool.
 386.112 +   *
 386.113 +   * @return:
 386.114 +   *    FreeType error code.  0~means success.
 386.115 +   *
 386.116 +   * @note:
 386.117 +   *    This function only works with CID faces and OpenType fonts,
 386.118 +   *    returning an error otherwise.
 386.119 +   *
 386.120 +   * @since:
 386.121 +   *    2.3.9
 386.122 +   */
 386.123 +  FT_EXPORT( FT_Error )
 386.124 +  FT_Get_CID_Is_Internally_CID_Keyed( FT_Face   face,
 386.125 +                                      FT_Bool  *is_cid );
 386.126 +
 386.127 +
 386.128 +  /**********************************************************************
 386.129 +   *
 386.130 +   * @function:
 386.131 +   *    FT_Get_CID_From_Glyph_Index
 386.132 +   *
 386.133 +   * @description:
 386.134 +   *    Retrieve the CID of the input glyph index.
 386.135 +   *
 386.136 +   * @input:
 386.137 +   *    face ::
 386.138 +   *       A handle to the input face.
 386.139 +   *
 386.140 +   *    glyph_index ::
 386.141 +   *       The input glyph index.
 386.142 +   *
 386.143 +   * @output:
 386.144 +   *    cid ::
 386.145 +   *       The CID as an @FT_UInt.
 386.146 +   *
 386.147 +   * @return:
 386.148 +   *    FreeType error code.  0~means success.
 386.149 +   *
 386.150 +   * @note:
 386.151 +   *    This function only works with CID faces and OpenType fonts,
 386.152 +   *    returning an error otherwise.
 386.153 +   *
 386.154 +   * @since:
 386.155 +   *    2.3.9
 386.156 +   */
 386.157 +  FT_EXPORT( FT_Error )
 386.158 +  FT_Get_CID_From_Glyph_Index( FT_Face   face,
 386.159 +                               FT_UInt   glyph_index,
 386.160 +                               FT_UInt  *cid );
 386.161 +
 386.162 + /* */
 386.163 +
 386.164 +FT_END_HEADER
 386.165 +
 386.166 +#endif /* __FTCID_H__ */
 386.167 +
 386.168 +
 386.169 +/* END */
   387.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   387.2 +++ b/libs/ft2static/freetype/fterrdef.h	Sat Feb 01 19:58:19 2014 +0200
   387.3 @@ -0,0 +1,244 @@
   387.4 +/***************************************************************************/
   387.5 +/*                                                                         */
   387.6 +/*  fterrdef.h                                                             */
   387.7 +/*                                                                         */
   387.8 +/*    FreeType error codes (specification).                                */
   387.9 +/*                                                                         */
  387.10 +/*  Copyright 2002, 2004, 2006, 2007, 2010 by                              */
  387.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  387.12 +/*                                                                         */
  387.13 +/*  This file is part of the FreeType project, and may only be used,       */
  387.14 +/*  modified, and distributed under the terms of the FreeType project      */
  387.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  387.16 +/*  this file you indicate that you have read the license and              */
  387.17 +/*  understand and accept it fully.                                        */
  387.18 +/*                                                                         */
  387.19 +/***************************************************************************/
  387.20 +
  387.21 +
  387.22 +  /*******************************************************************/
  387.23 +  /*******************************************************************/
  387.24 +  /*****                                                         *****/
  387.25 +  /*****                LIST OF ERROR CODES/MESSAGES             *****/
  387.26 +  /*****                                                         *****/
  387.27 +  /*******************************************************************/
  387.28 +  /*******************************************************************/
  387.29 +
  387.30 +
  387.31 +  /* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */
  387.32 +  /* including this file.                                           */
  387.33 +
  387.34 +
  387.35 +  /* generic errors */
  387.36 +
  387.37 +  FT_NOERRORDEF_( Ok,                                        0x00, \
  387.38 +                  "no error" )
  387.39 +
  387.40 +  FT_ERRORDEF_( Cannot_Open_Resource,                        0x01, \
  387.41 +                "cannot open resource" )
  387.42 +  FT_ERRORDEF_( Unknown_File_Format,                         0x02, \
  387.43 +                "unknown file format" )
  387.44 +  FT_ERRORDEF_( Invalid_File_Format,                         0x03, \
  387.45 +                "broken file" )
  387.46 +  FT_ERRORDEF_( Invalid_Version,                             0x04, \
  387.47 +                "invalid FreeType version" )
  387.48 +  FT_ERRORDEF_( Lower_Module_Version,                        0x05, \
  387.49 +                "module version is too low" )
  387.50 +  FT_ERRORDEF_( Invalid_Argument,                            0x06, \
  387.51 +                "invalid argument" )
  387.52 +  FT_ERRORDEF_( Unimplemented_Feature,                       0x07, \
  387.53 +                "unimplemented feature" )
  387.54 +  FT_ERRORDEF_( Invalid_Table,                               0x08, \
  387.55 +                "broken table" )
  387.56 +  FT_ERRORDEF_( Invalid_Offset,                              0x09, \
  387.57 +                "broken offset within table" )
  387.58 +  FT_ERRORDEF_( Array_Too_Large,                             0x0A, \
  387.59 +                "array allocation size too large" )
  387.60 +
  387.61 +  /* glyph/character errors */
  387.62 +
  387.63 +  FT_ERRORDEF_( Invalid_Glyph_Index,                         0x10, \
  387.64 +                "invalid glyph index" )
  387.65 +  FT_ERRORDEF_( Invalid_Character_Code,                      0x11, \
  387.66 +                "invalid character code" )
  387.67 +  FT_ERRORDEF_( Invalid_Glyph_Format,                        0x12, \
  387.68 +                "unsupported glyph image format" )
  387.69 +  FT_ERRORDEF_( Cannot_Render_Glyph,                         0x13, \
  387.70 +                "cannot render this glyph format" )
  387.71 +  FT_ERRORDEF_( Invalid_Outline,                             0x14, \
  387.72 +                "invalid outline" )
  387.73 +  FT_ERRORDEF_( Invalid_Composite,                           0x15, \
  387.74 +                "invalid composite glyph" )
  387.75 +  FT_ERRORDEF_( Too_Many_Hints,                              0x16, \
  387.76 +                "too many hints" )
  387.77 +  FT_ERRORDEF_( Invalid_Pixel_Size,                          0x17, \
  387.78 +                "invalid pixel size" )
  387.79 +
  387.80 +  /* handle errors */
  387.81 +
  387.82 +  FT_ERRORDEF_( Invalid_Handle,                              0x20, \
  387.83 +                "invalid object handle" )
  387.84 +  FT_ERRORDEF_( Invalid_Library_Handle,                      0x21, \
  387.85 +                "invalid library handle" )
  387.86 +  FT_ERRORDEF_( Invalid_Driver_Handle,                       0x22, \
  387.87 +                "invalid module handle" )
  387.88 +  FT_ERRORDEF_( Invalid_Face_Handle,                         0x23, \
  387.89 +                "invalid face handle" )
  387.90 +  FT_ERRORDEF_( Invalid_Size_Handle,                         0x24, \
  387.91 +                "invalid size handle" )
  387.92 +  FT_ERRORDEF_( Invalid_Slot_Handle,                         0x25, \
  387.93 +                "invalid glyph slot handle" )
  387.94 +  FT_ERRORDEF_( Invalid_CharMap_Handle,                      0x26, \
  387.95 +                "invalid charmap handle" )
  387.96 +  FT_ERRORDEF_( Invalid_Cache_Handle,                        0x27, \
  387.97 +                "invalid cache manager handle" )
  387.98 +  FT_ERRORDEF_( Invalid_Stream_Handle,                       0x28, \
  387.99 +                "invalid stream handle" )
 387.100 +
 387.101 +  /* driver errors */
 387.102 +
 387.103 +  FT_ERRORDEF_( Too_Many_Drivers,                            0x30, \
 387.104 +                "too many modules" )
 387.105 +  FT_ERRORDEF_( Too_Many_Extensions,                         0x31, \
 387.106 +                "too many extensions" )
 387.107 +
 387.108 +  /* memory errors */
 387.109 +
 387.110 +  FT_ERRORDEF_( Out_Of_Memory,                               0x40, \
 387.111 +                "out of memory" )
 387.112 +  FT_ERRORDEF_( Unlisted_Object,                             0x41, \
 387.113 +                "unlisted object" )
 387.114 +
 387.115 +  /* stream errors */
 387.116 +
 387.117 +  FT_ERRORDEF_( Cannot_Open_Stream,                          0x51, \
 387.118 +                "cannot open stream" )
 387.119 +  FT_ERRORDEF_( Invalid_Stream_Seek,                         0x52, \
 387.120 +                "invalid stream seek" )
 387.121 +  FT_ERRORDEF_( Invalid_Stream_Skip,                         0x53, \
 387.122 +                "invalid stream skip" )
 387.123 +  FT_ERRORDEF_( Invalid_Stream_Read,                         0x54, \
 387.124 +                "invalid stream read" )
 387.125 +  FT_ERRORDEF_( Invalid_Stream_Operation,                    0x55, \
 387.126 +                "invalid stream operation" )
 387.127 +  FT_ERRORDEF_( Invalid_Frame_Operation,                     0x56, \
 387.128 +                "invalid frame operation" )
 387.129 +  FT_ERRORDEF_( Nested_Frame_Access,                         0x57, \
 387.130 +                "nested frame access" )
 387.131 +  FT_ERRORDEF_( Invalid_Frame_Read,                          0x58, \
 387.132 +                "invalid frame read" )
 387.133 +
 387.134 +  /* raster errors */
 387.135 +
 387.136 +  FT_ERRORDEF_( Raster_Uninitialized,                        0x60, \
 387.137 +                "raster uninitialized" )
 387.138 +  FT_ERRORDEF_( Raster_Corrupted,                            0x61, \
 387.139 +                "raster corrupted" )
 387.140 +  FT_ERRORDEF_( Raster_Overflow,                             0x62, \
 387.141 +                "raster overflow" )
 387.142 +  FT_ERRORDEF_( Raster_Negative_Height,                      0x63, \
 387.143 +                "negative height while rastering" )
 387.144 +
 387.145 +  /* cache errors */
 387.146 +
 387.147 +  FT_ERRORDEF_( Too_Many_Caches,                             0x70, \
 387.148 +                "too many registered caches" )
 387.149 +
 387.150 +  /* TrueType and SFNT errors */
 387.151 +
 387.152 +  FT_ERRORDEF_( Invalid_Opcode,                              0x80, \
 387.153 +                "invalid opcode" )
 387.154 +  FT_ERRORDEF_( Too_Few_Arguments,                           0x81, \
 387.155 +                "too few arguments" )
 387.156 +  FT_ERRORDEF_( Stack_Overflow,                              0x82, \
 387.157 +                "stack overflow" )
 387.158 +  FT_ERRORDEF_( Code_Overflow,                               0x83, \
 387.159 +                "code overflow" )
 387.160 +  FT_ERRORDEF_( Bad_Argument,                                0x84, \
 387.161 +                "bad argument" )
 387.162 +  FT_ERRORDEF_( Divide_By_Zero,                              0x85, \
 387.163 +                "division by zero" )
 387.164 +  FT_ERRORDEF_( Invalid_Reference,                           0x86, \
 387.165 +                "invalid reference" )
 387.166 +  FT_ERRORDEF_( Debug_OpCode,                                0x87, \
 387.167 +                "found debug opcode" )
 387.168 +  FT_ERRORDEF_( ENDF_In_Exec_Stream,                         0x88, \
 387.169 +                "found ENDF opcode in execution stream" )
 387.170 +  FT_ERRORDEF_( Nested_DEFS,                                 0x89, \
 387.171 +                "nested DEFS" )
 387.172 +  FT_ERRORDEF_( Invalid_CodeRange,                           0x8A, \
 387.173 +                "invalid code range" )
 387.174 +  FT_ERRORDEF_( Execution_Too_Long,                          0x8B, \
 387.175 +                "execution context too long" )
 387.176 +  FT_ERRORDEF_( Too_Many_Function_Defs,                      0x8C, \
 387.177 +                "too many function definitions" )
 387.178 +  FT_ERRORDEF_( Too_Many_Instruction_Defs,                   0x8D, \
 387.179 +                "too many instruction definitions" )
 387.180 +  FT_ERRORDEF_( Table_Missing,                               0x8E, \
 387.181 +                "SFNT font table missing" )
 387.182 +  FT_ERRORDEF_( Horiz_Header_Missing,                        0x8F, \
 387.183 +                "horizontal header (hhea) table missing" )
 387.184 +  FT_ERRORDEF_( Locations_Missing,                           0x90, \
 387.185 +                "locations (loca) table missing" )
 387.186 +  FT_ERRORDEF_( Name_Table_Missing,                          0x91, \
 387.187 +                "name table missing" )
 387.188 +  FT_ERRORDEF_( CMap_Table_Missing,                          0x92, \
 387.189 +                "character map (cmap) table missing" )
 387.190 +  FT_ERRORDEF_( Hmtx_Table_Missing,                          0x93, \
 387.191 +                "horizontal metrics (hmtx) table missing" )
 387.192 +  FT_ERRORDEF_( Post_Table_Missing,                          0x94, \
 387.193 +                "PostScript (post) table missing" )
 387.194 +  FT_ERRORDEF_( Invalid_Horiz_Metrics,                       0x95, \
 387.195 +                "invalid horizontal metrics" )
 387.196 +  FT_ERRORDEF_( Invalid_CharMap_Format,                      0x96, \
 387.197 +                "invalid character map (cmap) format" )
 387.198 +  FT_ERRORDEF_( Invalid_PPem,                                0x97, \
 387.199 +                "invalid ppem value" )
 387.200 +  FT_ERRORDEF_( Invalid_Vert_Metrics,                        0x98, \
 387.201 +                "invalid vertical metrics" )
 387.202 +  FT_ERRORDEF_( Could_Not_Find_Context,                      0x99, \
 387.203 +                "could not find context" )
 387.204 +  FT_ERRORDEF_( Invalid_Post_Table_Format,                   0x9A, \
 387.205 +                "invalid PostScript (post) table format" )
 387.206 +  FT_ERRORDEF_( Invalid_Post_Table,                          0x9B, \
 387.207 +                "invalid PostScript (post) table" )
 387.208 +
 387.209 +  /* CFF, CID, and Type 1 errors */
 387.210 +
 387.211 +  FT_ERRORDEF_( Syntax_Error,                                0xA0, \
 387.212 +                "opcode syntax error" )
 387.213 +  FT_ERRORDEF_( Stack_Underflow,                             0xA1, \
 387.214 +                "argument stack underflow" )
 387.215 +  FT_ERRORDEF_( Ignore,                                      0xA2, \
 387.216 +                "ignore" )
 387.217 +  FT_ERRORDEF_( No_Unicode_Glyph_Name,                       0xA3, \
 387.218 +                "no Unicode glyph name found" )
 387.219 +
 387.220 +
 387.221 +  /* BDF errors */
 387.222 +
 387.223 +  FT_ERRORDEF_( Missing_Startfont_Field,                     0xB0, \
 387.224 +                "`STARTFONT' field missing" )
 387.225 +  FT_ERRORDEF_( Missing_Font_Field,                          0xB1, \
 387.226 +                "`FONT' field missing" )
 387.227 +  FT_ERRORDEF_( Missing_Size_Field,                          0xB2, \
 387.228 +                "`SIZE' field missing" )
 387.229 +  FT_ERRORDEF_( Missing_Fontboundingbox_Field,               0xB3, \
 387.230 +                "`FONTBOUNDINGBOX' field missing" )
 387.231 +  FT_ERRORDEF_( Missing_Chars_Field,                         0xB4, \
 387.232 +                "`CHARS' field missing" )
 387.233 +  FT_ERRORDEF_( Missing_Startchar_Field,                     0xB5, \
 387.234 +                "`STARTCHAR' field missing" )
 387.235 +  FT_ERRORDEF_( Missing_Encoding_Field,                      0xB6, \
 387.236 +                "`ENCODING' field missing" )
 387.237 +  FT_ERRORDEF_( Missing_Bbx_Field,                           0xB7, \
 387.238 +                "`BBX' field missing" )
 387.239 +  FT_ERRORDEF_( Bbx_Too_Big,                                 0xB8, \
 387.240 +                "`BBX' too big" )
 387.241 +  FT_ERRORDEF_( Corrupted_Font_Header,                       0xB9, \
 387.242 +                "Font header corrupted or missing fields" )
 387.243 +  FT_ERRORDEF_( Corrupted_Font_Glyphs,                       0xBA, \
 387.244 +                "Font glyphs corrupted or missing fields" )
 387.245 +
 387.246 +
 387.247 +/* END */
   388.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   388.2 +++ b/libs/ft2static/freetype/fterrors.h	Sat Feb 01 19:58:19 2014 +0200
   388.3 @@ -0,0 +1,206 @@
   388.4 +/***************************************************************************/
   388.5 +/*                                                                         */
   388.6 +/*  fterrors.h                                                             */
   388.7 +/*                                                                         */
   388.8 +/*    FreeType error code handling (specification).                        */
   388.9 +/*                                                                         */
  388.10 +/*  Copyright 1996-2001, 2002, 2004, 2007 by                               */
  388.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  388.12 +/*                                                                         */
  388.13 +/*  This file is part of the FreeType project, and may only be used,       */
  388.14 +/*  modified, and distributed under the terms of the FreeType project      */
  388.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  388.16 +/*  this file you indicate that you have read the license and              */
  388.17 +/*  understand and accept it fully.                                        */
  388.18 +/*                                                                         */
  388.19 +/***************************************************************************/
  388.20 +
  388.21 +
  388.22 +  /*************************************************************************/
  388.23 +  /*                                                                       */
  388.24 +  /* This special header file is used to define the handling of FT2        */
  388.25 +  /* enumeration constants.  It can also be used to generate error message */
  388.26 +  /* strings with a small macro trick explained below.                     */
  388.27 +  /*                                                                       */
  388.28 +  /* I - Error Formats                                                     */
  388.29 +  /* -----------------                                                     */
  388.30 +  /*                                                                       */
  388.31 +  /*   The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be   */
  388.32 +  /*   defined in ftoption.h in order to make the higher byte indicate     */
  388.33 +  /*   the module where the error has happened (this is not compatible     */
  388.34 +  /*   with standard builds of FreeType 2).  You can then use the macro    */
  388.35 +  /*   FT_ERROR_BASE macro to extract the generic error code from an       */
  388.36 +  /*   FT_Error value.                                                     */
  388.37 +  /*                                                                       */
  388.38 +  /*                                                                       */
  388.39 +  /* II - Error Message strings                                            */
  388.40 +  /* --------------------------                                            */
  388.41 +  /*                                                                       */
  388.42 +  /*   The error definitions below are made through special macros that    */
  388.43 +  /*   allow client applications to build a table of error message strings */
  388.44 +  /*   if they need it.  The strings are not included in a normal build of */
  388.45 +  /*   FreeType 2 to save space (most client applications do not use       */
  388.46 +  /*   them).                                                              */
  388.47 +  /*                                                                       */
  388.48 +  /*   To do so, you have to define the following macros before including  */
  388.49 +  /*   this file:                                                          */
  388.50 +  /*                                                                       */
  388.51 +  /*   FT_ERROR_START_LIST ::                                              */
  388.52 +  /*     This macro is called before anything else to define the start of  */
  388.53 +  /*     the error list.  It is followed by several FT_ERROR_DEF calls     */
  388.54 +  /*     (see below).                                                      */
  388.55 +  /*                                                                       */
  388.56 +  /*   FT_ERROR_DEF( e, v, s ) ::                                          */
  388.57 +  /*     This macro is called to define one single error.                  */
  388.58 +  /*     `e' is the error code identifier (e.g. FT_Err_Invalid_Argument).  */
  388.59 +  /*     `v' is the error numerical value.                                 */
  388.60 +  /*     `s' is the corresponding error string.                            */
  388.61 +  /*                                                                       */
  388.62 +  /*   FT_ERROR_END_LIST ::                                                */
  388.63 +  /*     This macro ends the list.                                         */
  388.64 +  /*                                                                       */
  388.65 +  /*   Additionally, you have to undefine __FTERRORS_H__ before #including */
  388.66 +  /*   this file.                                                          */
  388.67 +  /*                                                                       */
  388.68 +  /*   Here is a simple example:                                           */
  388.69 +  /*                                                                       */
  388.70 +  /*     {                                                                 */
  388.71 +  /*       #undef __FTERRORS_H__                                           */
  388.72 +  /*       #define FT_ERRORDEF( e, v, s )  { e, s },                       */
  388.73 +  /*       #define FT_ERROR_START_LIST     {                               */
  388.74 +  /*       #define FT_ERROR_END_LIST       { 0, 0 } };                     */
  388.75 +  /*                                                                       */
  388.76 +  /*       const struct                                                    */
  388.77 +  /*       {                                                               */
  388.78 +  /*         int          err_code;                                        */
  388.79 +  /*         const char*  err_msg;                                         */
  388.80 +  /*       } ft_errors[] =                                                 */
  388.81 +  /*                                                                       */
  388.82 +  /*       #include FT_ERRORS_H                                            */
  388.83 +  /*     }                                                                 */
  388.84 +  /*                                                                       */
  388.85 +  /*************************************************************************/
  388.86 +
  388.87 +
  388.88 +#ifndef __FTERRORS_H__
  388.89 +#define __FTERRORS_H__
  388.90 +
  388.91 +
  388.92 +  /* include module base error codes */
  388.93 +#include FT_MODULE_ERRORS_H
  388.94 +
  388.95 +
  388.96 +  /*******************************************************************/
  388.97 +  /*******************************************************************/
  388.98 +  /*****                                                         *****/
  388.99 +  /*****                       SETUP MACROS                      *****/
 388.100 +  /*****                                                         *****/
 388.101 +  /*******************************************************************/
 388.102 +  /*******************************************************************/
 388.103 +
 388.104 +
 388.105 +#undef  FT_NEED_EXTERN_C
 388.106 +
 388.107 +#undef  FT_ERR_XCAT
 388.108 +#undef  FT_ERR_CAT
 388.109 +
 388.110 +#define FT_ERR_XCAT( x, y )  x ## y
 388.111 +#define FT_ERR_CAT( x, y )   FT_ERR_XCAT( x, y )
 388.112 +
 388.113 +
 388.114 +  /* FT_ERR_PREFIX is used as a prefix for error identifiers. */
 388.115 +  /* By default, we use `FT_Err_'.                            */
 388.116 +  /*                                                          */
 388.117 +#ifndef FT_ERR_PREFIX
 388.118 +#define FT_ERR_PREFIX  FT_Err_
 388.119 +#endif
 388.120 +
 388.121 +
 388.122 +  /* FT_ERR_BASE is used as the base for module-specific errors. */
 388.123 +  /*                                                             */
 388.124 +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS
 388.125 +
 388.126 +#ifndef FT_ERR_BASE
 388.127 +#define FT_ERR_BASE  FT_Mod_Err_Base
 388.128 +#endif
 388.129 +
 388.130 +#else
 388.131 +
 388.132 +#undef FT_ERR_BASE
 388.133 +#define FT_ERR_BASE  0
 388.134 +
 388.135 +#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */
 388.136 +
 388.137 +
 388.138 +  /* If FT_ERRORDEF is not defined, we need to define a simple */
 388.139 +  /* enumeration type.                                         */
 388.140 +  /*                                                           */
 388.141 +#ifndef FT_ERRORDEF
 388.142 +
 388.143 +#define FT_ERRORDEF( e, v, s )  e = v,
 388.144 +#define FT_ERROR_START_LIST     enum {
 388.145 +#define FT_ERROR_END_LIST       FT_ERR_CAT( FT_ERR_PREFIX, Max ) };
 388.146 +
 388.147 +#ifdef __cplusplus
 388.148 +#define FT_NEED_EXTERN_C
 388.149 +  extern "C" {
 388.150 +#endif
 388.151 +
 388.152 +#endif /* !FT_ERRORDEF */
 388.153 +
 388.154 +
 388.155 +  /* this macro is used to define an error */
 388.156 +#define FT_ERRORDEF_( e, v, s )   \
 388.157 +          FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s )
 388.158 +
 388.159 +  /* this is only used for <module>_Err_Ok, which must be 0! */
 388.160 +#define FT_NOERRORDEF_( e, v, s ) \
 388.161 +          FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s )
 388.162 +
 388.163 +
 388.164 +#ifdef FT_ERROR_START_LIST
 388.165 +  FT_ERROR_START_LIST
 388.166 +#endif
 388.167 +
 388.168 +
 388.169 +  /* now include the error codes */
 388.170 +#include FT_ERROR_DEFINITIONS_H
 388.171 +
 388.172 +
 388.173 +#ifdef FT_ERROR_END_LIST
 388.174 +  FT_ERROR_END_LIST
 388.175 +#endif
 388.176 +
 388.177 +
 388.178 +  /*******************************************************************/
 388.179 +  /*******************************************************************/
 388.180 +  /*****                                                         *****/
 388.181 +  /*****                      SIMPLE CLEANUP                     *****/
 388.182 +  /*****                                                         *****/
 388.183 +  /*******************************************************************/
 388.184 +  /*******************************************************************/
 388.185 +
 388.186 +#ifdef FT_NEED_EXTERN_C
 388.187 +  }
 388.188 +#endif
 388.189 +
 388.190 +#undef FT_ERROR_START_LIST
 388.191 +#undef FT_ERROR_END_LIST
 388.192 +
 388.193 +#undef FT_ERRORDEF
 388.194 +#undef FT_ERRORDEF_
 388.195 +#undef FT_NOERRORDEF_
 388.196 +
 388.197 +#undef FT_NEED_EXTERN_C
 388.198 +#undef FT_ERR_CONCAT
 388.199 +#undef FT_ERR_BASE
 388.200 +
 388.201 +  /* FT_KEEP_ERR_PREFIX is needed for ftvalid.h */
 388.202 +#ifndef FT_KEEP_ERR_PREFIX
 388.203 +#undef FT_ERR_PREFIX
 388.204 +#endif
 388.205 +
 388.206 +#endif /* __FTERRORS_H__ */
 388.207 +
 388.208 +
 388.209 +/* END */
   389.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   389.2 +++ b/libs/ft2static/freetype/ftgasp.h	Sat Feb 01 19:58:19 2014 +0200
   389.3 @@ -0,0 +1,120 @@
   389.4 +/***************************************************************************/
   389.5 +/*                                                                         */
   389.6 +/*  ftgasp.h                                                               */
   389.7 +/*                                                                         */
   389.8 +/*    Access of TrueType's `gasp' table (specification).                   */
   389.9 +/*                                                                         */
  389.10 +/*  Copyright 2007, 2008 by                                                */
  389.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  389.12 +/*                                                                         */
  389.13 +/*  This file is part of the FreeType project, and may only be used,       */
  389.14 +/*  modified, and distributed under the terms of the FreeType project      */
  389.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  389.16 +/*  this file you indicate that you have read the license and              */
  389.17 +/*  understand and accept it fully.                                        */
  389.18 +/*                                                                         */
  389.19 +/***************************************************************************/
  389.20 +
  389.21 +
  389.22 +#ifndef _FT_GASP_H_
  389.23 +#define _FT_GASP_H_
  389.24 +
  389.25 +#include <ft2build.h>
  389.26 +#include FT_FREETYPE_H
  389.27 +
  389.28 +#ifdef FREETYPE_H
  389.29 +#error "freetype.h of FreeType 1 has been loaded!"
  389.30 +#error "Please fix the directory search order for header files"
  389.31 +#error "so that freetype.h of FreeType 2 is found first."
  389.32 +#endif
  389.33 +
  389.34 +
  389.35 +  /***************************************************************************
  389.36 +   *
  389.37 +   * @section:
  389.38 +   *   gasp_table
  389.39 +   *
  389.40 +   * @title:
  389.41 +   *   Gasp Table
  389.42 +   *
  389.43 +   * @abstract:
  389.44 +   *   Retrieving TrueType `gasp' table entries.
  389.45 +   *
  389.46 +   * @description:
  389.47 +   *   The function @FT_Get_Gasp can be used to query a TrueType or OpenType
  389.48 +   *   font for specific entries in its `gasp' table, if any.  This is
  389.49 +   *   mainly useful when implementing native TrueType hinting with the
  389.50 +   *   bytecode interpreter to duplicate the Windows text rendering results.
  389.51 +   */
  389.52 +
  389.53 +  /*************************************************************************
  389.54 +   *
  389.55 +   * @enum:
  389.56 +   *   FT_GASP_XXX
  389.57 +   *
  389.58 +   * @description:
  389.59 +   *   A list of values and/or bit-flags returned by the @FT_Get_Gasp
  389.60 +   *   function.
  389.61 +   *
  389.62 +   * @values:
  389.63 +   *   FT_GASP_NO_TABLE ::
  389.64 +   *     This special value means that there is no GASP table in this face.
  389.65 +   *     It is up to the client to decide what to do.
  389.66 +   *
  389.67 +   *   FT_GASP_DO_GRIDFIT ::
  389.68 +   *     Grid-fitting and hinting should be performed at the specified ppem.
  389.69 +   *     This *really* means TrueType bytecode interpretation.
  389.70 +   *
  389.71 +   *   FT_GASP_DO_GRAY ::
  389.72 +   *     Anti-aliased rendering should be performed at the specified ppem.
  389.73 +   *
  389.74 +   *   FT_GASP_SYMMETRIC_SMOOTHING ::
  389.75 +   *     Smoothing along multiple axes must be used with ClearType.
  389.76 +   *
  389.77 +   *   FT_GASP_SYMMETRIC_GRIDFIT ::
  389.78 +   *     Grid-fitting must be used with ClearType's symmetric smoothing.
  389.79 +   *
  389.80 +   * @note:
  389.81 +   *   `ClearType' is Microsoft's implementation of LCD rendering, partly
  389.82 +   *   protected by patents.
  389.83 +   *
  389.84 +   * @since:
  389.85 +   *   2.3.0
  389.86 +   */
  389.87 +#define FT_GASP_NO_TABLE               -1
  389.88 +#define FT_GASP_DO_GRIDFIT           0x01
  389.89 +#define FT_GASP_DO_GRAY              0x02
  389.90 +#define FT_GASP_SYMMETRIC_SMOOTHING  0x08
  389.91 +#define FT_GASP_SYMMETRIC_GRIDFIT    0x10
  389.92 +
  389.93 +
  389.94 +  /*************************************************************************
  389.95 +   *
  389.96 +   * @func:
  389.97 +   *   FT_Get_Gasp
  389.98 +   *
  389.99 +   * @description:
 389.100 +   *   Read the `gasp' table from a TrueType or OpenType font file and
 389.101 +   *   return the entry corresponding to a given character pixel size.
 389.102 +   *
 389.103 +   * @input:
 389.104 +   *   face :: The source face handle.
 389.105 +   *   ppem :: The vertical character pixel size.
 389.106 +   *
 389.107 +   * @return:
 389.108 +   *   Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no
 389.109 +   *   `gasp' table in the face.
 389.110 +   *
 389.111 +   * @since:
 389.112 +   *   2.3.0
 389.113 +   */
 389.114 +  FT_EXPORT( FT_Int )
 389.115 +  FT_Get_Gasp( FT_Face  face,
 389.116 +               FT_UInt  ppem );
 389.117 +
 389.118 +/* */
 389.119 +
 389.120 +#endif /* _FT_GASP_H_ */
 389.121 +
 389.122 +
 389.123 +/* END */
   390.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   390.2 +++ b/libs/ft2static/freetype/ftglyph.h	Sat Feb 01 19:58:19 2014 +0200
   390.3 @@ -0,0 +1,613 @@
   390.4 +/***************************************************************************/
   390.5 +/*                                                                         */
   390.6 +/*  ftglyph.h                                                              */
   390.7 +/*                                                                         */
   390.8 +/*    FreeType convenience functions to handle glyphs (specification).     */
   390.9 +/*                                                                         */
  390.10 +/*  Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by                   */
  390.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  390.12 +/*                                                                         */
  390.13 +/*  This file is part of the FreeType project, and may only be used,       */
  390.14 +/*  modified, and distributed under the terms of the FreeType project      */
  390.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  390.16 +/*  this file you indicate that you have read the license and              */
  390.17 +/*  understand and accept it fully.                                        */
  390.18 +/*                                                                         */
  390.19 +/***************************************************************************/
  390.20 +
  390.21 +
  390.22 +  /*************************************************************************/
  390.23 +  /*                                                                       */
  390.24 +  /* This file contains the definition of several convenience functions    */
  390.25 +  /* that can be used by client applications to easily retrieve glyph      */
  390.26 +  /* bitmaps and outlines from a given face.                               */
  390.27 +  /*                                                                       */
  390.28 +  /* These functions should be optional if you are writing a font server   */
  390.29 +  /* or text layout engine on top of FreeType.  However, they are pretty   */
  390.30 +  /* handy for many other simple uses of the library.                      */
  390.31 +  /*                                                                       */
  390.32 +  /*************************************************************************/
  390.33 +
  390.34 +
  390.35 +#ifndef __FTGLYPH_H__
  390.36 +#define __FTGLYPH_H__
  390.37 +
  390.38 +
  390.39 +#include <ft2build.h>
  390.40 +#include FT_FREETYPE_H
  390.41 +
  390.42 +#ifdef FREETYPE_H
  390.43 +#error "freetype.h of FreeType 1 has been loaded!"
  390.44 +#error "Please fix the directory search order for header files"
  390.45 +#error "so that freetype.h of FreeType 2 is found first."
  390.46 +#endif
  390.47 +
  390.48 +
  390.49 +FT_BEGIN_HEADER
  390.50 +
  390.51 +
  390.52 +  /*************************************************************************/
  390.53 +  /*                                                                       */
  390.54 +  /* <Section>                                                             */
  390.55 +  /*    glyph_management                                                   */
  390.56 +  /*                                                                       */
  390.57 +  /* <Title>                                                               */
  390.58 +  /*    Glyph Management                                                   */
  390.59 +  /*                                                                       */
  390.60 +  /* <Abstract>                                                            */
  390.61 +  /*    Generic interface to manage individual glyph data.                 */
  390.62 +  /*                                                                       */
  390.63 +  /* <Description>                                                         */
  390.64 +  /*    This section contains definitions used to manage glyph data        */
  390.65 +  /*    through generic FT_Glyph objects.  Each of them can contain a      */
  390.66 +  /*    bitmap, a vector outline, or even images in other formats.         */
  390.67 +  /*                                                                       */
  390.68 +  /*************************************************************************/
  390.69 +
  390.70 +
  390.71 +  /* forward declaration to a private type */
  390.72 +  typedef struct FT_Glyph_Class_  FT_Glyph_Class;
  390.73 +
  390.74 +
  390.75 +  /*************************************************************************/
  390.76 +  /*                                                                       */
  390.77 +  /* <Type>                                                                */
  390.78 +  /*    FT_Glyph                                                           */
  390.79 +  /*                                                                       */
  390.80 +  /* <Description>                                                         */
  390.81 +  /*    Handle to an object used to model generic glyph images.  It is a   */
  390.82 +  /*    pointer to the @FT_GlyphRec structure and can contain a glyph      */
  390.83 +  /*    bitmap or pointer.                                                 */
  390.84 +  /*                                                                       */
  390.85 +  /* <Note>                                                                */
  390.86 +  /*    Glyph objects are not owned by the library.  You must thus release */
  390.87 +  /*    them manually (through @FT_Done_Glyph) _before_ calling            */
  390.88 +  /*    @FT_Done_FreeType.                                                 */
  390.89 +  /*                                                                       */
  390.90 +  typedef struct FT_GlyphRec_*  FT_Glyph;
  390.91 +
  390.92 +
  390.93 +  /*************************************************************************/
  390.94 +  /*                                                                       */
  390.95 +  /* <Struct>                                                              */
  390.96 +  /*    FT_GlyphRec                                                        */
  390.97 +  /*                                                                       */
  390.98 +  /* <Description>                                                         */
  390.99 +  /*    The root glyph structure contains a given glyph image plus its     */
 390.100 +  /*    advance width in 16.16 fixed float format.                         */
 390.101 +  /*                                                                       */
 390.102 +  /* <Fields>                                                              */
 390.103 +  /*    library :: A handle to the FreeType library object.                */
 390.104 +  /*                                                                       */
 390.105 +  /*    clazz   :: A pointer to the glyph's class.  Private.               */
 390.106 +  /*                                                                       */
 390.107 +  /*    format  :: The format of the glyph's image.                        */
 390.108 +  /*                                                                       */
 390.109 +  /*    advance :: A 16.16 vector that gives the glyph's advance width.    */
 390.110 +  /*                                                                       */
 390.111 +  typedef struct  FT_GlyphRec_
 390.112 +  {
 390.113 +    FT_Library             library;
 390.114 +    const FT_Glyph_Class*  clazz;
 390.115 +    FT_Glyph_Format        format;
 390.116 +    FT_Vector              advance;
 390.117 +
 390.118 +  } FT_GlyphRec;
 390.119 +
 390.120 +
 390.121 +  /*************************************************************************/
 390.122 +  /*                                                                       */
 390.123 +  /* <Type>                                                                */
 390.124 +  /*    FT_BitmapGlyph                                                     */
 390.125 +  /*                                                                       */
 390.126 +  /* <Description>                                                         */
 390.127 +  /*    A handle to an object used to model a bitmap glyph image.  This is */
 390.128 +  /*    a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec.     */
 390.129 +  /*                                                                       */
 390.130 +  typedef struct FT_BitmapGlyphRec_*  FT_BitmapGlyph;
 390.131 +
 390.132 +
 390.133 +  /*************************************************************************/
 390.134 +  /*                                                                       */
 390.135 +  /* <Struct>                                                              */
 390.136 +  /*    FT_BitmapGlyphRec                                                  */
 390.137 +  /*                                                                       */
 390.138 +  /* <Description>                                                         */
 390.139 +  /*    A structure used for bitmap glyph images.  This really is a        */
 390.140 +  /*    `sub-class' of @FT_GlyphRec.                                       */
 390.141 +  /*                                                                       */
 390.142 +  /* <Fields>                                                              */
 390.143 +  /*    root   :: The root @FT_Glyph fields.                               */
 390.144 +  /*                                                                       */
 390.145 +  /*    left   :: The left-side bearing, i.e., the horizontal distance     */
 390.146 +  /*              from the current pen position to the left border of the  */
 390.147 +  /*              glyph bitmap.                                            */
 390.148 +  /*                                                                       */
 390.149 +  /*    top    :: The top-side bearing, i.e., the vertical distance from   */
 390.150 +  /*              the current pen position to the top border of the glyph  */
 390.151 +  /*              bitmap.  This distance is positive for upwards~y!        */
 390.152 +  /*                                                                       */
 390.153 +  /*    bitmap :: A descriptor for the bitmap.                             */
 390.154 +  /*                                                                       */
 390.155 +  /* <Note>                                                                */
 390.156 +  /*    You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have       */
 390.157 +  /*    `glyph->format == FT_GLYPH_FORMAT_BITMAP'.  This lets you access   */
 390.158 +  /*    the bitmap's contents easily.                                      */
 390.159 +  /*                                                                       */
 390.160 +  /*    The corresponding pixel buffer is always owned by @FT_BitmapGlyph  */
 390.161 +  /*    and is thus created and destroyed with it.                         */
 390.162 +  /*                                                                       */
 390.163 +  typedef struct  FT_BitmapGlyphRec_
 390.164 +  {
 390.165 +    FT_GlyphRec  root;
 390.166 +    FT_Int       left;
 390.167 +    FT_Int       top;
 390.168 +    FT_Bitmap    bitmap;
 390.169 +
 390.170 +  } FT_BitmapGlyphRec;
 390.171 +
 390.172 +
 390.173 +  /*************************************************************************/
 390.174 +  /*                                                                       */
 390.175 +  /* <Type>                                                                */
 390.176 +  /*    FT_OutlineGlyph                                                    */
 390.177 +  /*                                                                       */
 390.178 +  /* <Description>                                                         */
 390.179 +  /*    A handle to an object used to model an outline glyph image.  This  */
 390.180 +  /*    is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */
 390.181 +  /*                                                                       */
 390.182 +  typedef struct FT_OutlineGlyphRec_*  FT_OutlineGlyph;
 390.183 +
 390.184 +
 390.185 +  /*************************************************************************/
 390.186 +  /*                                                                       */
 390.187 +  /* <Struct>                                                              */
 390.188 +  /*    FT_OutlineGlyphRec                                                 */
 390.189 +  /*                                                                       */
 390.190 +  /* <Description>                                                         */
 390.191 +  /*    A structure used for outline (vectorial) glyph images.  This       */
 390.192 +  /*    really is a `sub-class' of @FT_GlyphRec.                           */
 390.193 +  /*                                                                       */
 390.194 +  /* <Fields>                                                              */
 390.195 +  /*    root    :: The root @FT_Glyph fields.                              */
 390.196 +  /*                                                                       */
 390.197 +  /*    outline :: A descriptor for the outline.                           */
 390.198 +  /*                                                                       */
 390.199 +  /* <Note>                                                                */
 390.200 +  /*    You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have      */
 390.201 +  /*    `glyph->format == FT_GLYPH_FORMAT_OUTLINE'.  This lets you access  */
 390.202 +  /*    the outline's content easily.                                      */
 390.203 +  /*                                                                       */
 390.204 +  /*    As the outline is extracted from a glyph slot, its coordinates are */
 390.205 +  /*    expressed normally in 26.6 pixels, unless the flag                 */
 390.206 +  /*    @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char(). */
 390.207 +  /*                                                                       */
 390.208 +  /*    The outline's tables are always owned by the object and are        */
 390.209 +  /*    destroyed with it.                                                 */
 390.210 +  /*                                                                       */
 390.211 +  typedef struct  FT_OutlineGlyphRec_
 390.212 +  {
 390.213 +    FT_GlyphRec  root;
 390.214 +    FT_Outline   outline;
 390.215 +
 390.216 +  } FT_OutlineGlyphRec;
 390.217 +
 390.218 +
 390.219 +  /*************************************************************************/
 390.220 +  /*                                                                       */
 390.221 +  /* <Function>                                                            */
 390.222 +  /*    FT_Get_Glyph                                                       */
 390.223 +  /*                                                                       */
 390.224 +  /* <Description>                                                         */
 390.225 +  /*    A function used to extract a glyph image from a slot.  Note that   */
 390.226 +  /*    the created @FT_Glyph object must be released with @FT_Done_Glyph. */
 390.227 +  /*                                                                       */
 390.228 +  /* <Input>                                                               */
 390.229 +  /*    slot   :: A handle to the source glyph slot.                       */
 390.230 +  /*                                                                       */
 390.231 +  /* <Output>                                                              */
 390.232 +  /*    aglyph :: A handle to the glyph object.                            */
 390.233 +  /*                                                                       */
 390.234 +  /* <Return>                                                              */
 390.235 +  /*    FreeType error code.  0~means success.                             */
 390.236 +  /*                                                                       */
 390.237 +  FT_EXPORT( FT_Error )
 390.238 +  FT_Get_Glyph( FT_GlyphSlot  slot,
 390.239 +                FT_Glyph     *aglyph );
 390.240 +
 390.241 +
 390.242 +  /*************************************************************************/
 390.243 +  /*                                                                       */
 390.244 +  /* <Function>                                                            */
 390.245 +  /*    FT_Glyph_Copy                                                      */
 390.246 +  /*                                                                       */
 390.247 +  /* <Description>                                                         */
 390.248 +  /*    A function used to copy a glyph image.  Note that the created      */
 390.249 +  /*    @FT_Glyph object must be released with @FT_Done_Glyph.             */
 390.250 +  /*                                                                       */
 390.251 +  /* <Input>                                                               */
 390.252 +  /*    source :: A handle to the source glyph object.                     */
 390.253 +  /*                                                                       */
 390.254 +  /* <Output>                                                              */
 390.255 +  /*    target :: A handle to the target glyph object.  0~in case of       */
 390.256 +  /*              error.                                                   */
 390.257 +  /*                                                                       */
 390.258 +  /* <Return>                                                              */
 390.259 +  /*    FreeType error code.  0~means success.                             */
 390.260 +  /*                                                                       */
 390.261 +  FT_EXPORT( FT_Error )
 390.262 +  FT_Glyph_Copy( FT_Glyph   source,
 390.263 +                 FT_Glyph  *target );
 390.264 +
 390.265 +
 390.266 +  /*************************************************************************/
 390.267 +  /*                                                                       */
 390.268 +  /* <Function>                                                            */
 390.269 +  /*    FT_Glyph_Transform                                                 */
 390.270 +  /*                                                                       */
 390.271 +  /* <Description>                                                         */
 390.272 +  /*    Transform a glyph image if its format is scalable.                 */
 390.273 +  /*                                                                       */
 390.274 +  /* <InOut>                                                               */
 390.275 +  /*    glyph  :: A handle to the target glyph object.                     */
 390.276 +  /*                                                                       */
 390.277 +  /* <Input>                                                               */
 390.278 +  /*    matrix :: A pointer to a 2x2 matrix to apply.                      */
 390.279 +  /*                                                                       */
 390.280 +  /*    delta  :: A pointer to a 2d vector to apply.  Coordinates are      */
 390.281 +  /*              expressed in 1/64th of a pixel.                          */
 390.282 +  /*                                                                       */
 390.283 +  /* <Return>                                                              */
 390.284 +  /*    FreeType error code (if not 0, the glyph format is not scalable).  */
 390.285 +  /*                                                                       */
 390.286 +  /* <Note>                                                                */
 390.287 +  /*    The 2x2 transformation matrix is also applied to the glyph's       */
 390.288 +  /*    advance vector.                                                    */
 390.289 +  /*                                                                       */
 390.290 +  FT_EXPORT( FT_Error )
 390.291 +  FT_Glyph_Transform( FT_Glyph    glyph,
 390.292 +                      FT_Matrix*  matrix,
 390.293 +                      FT_Vector*  delta );
 390.294 +
 390.295 +
 390.296 +  /*************************************************************************/
 390.297 +  /*                                                                       */
 390.298 +  /* <Enum>                                                                */
 390.299 +  /*    FT_Glyph_BBox_Mode                                                 */
 390.300 +  /*                                                                       */
 390.301 +  /* <Description>                                                         */
 390.302 +  /*    The mode how the values of @FT_Glyph_Get_CBox are returned.        */
 390.303 +  /*                                                                       */
 390.304 +  /* <Values>                                                              */
 390.305 +  /*    FT_GLYPH_BBOX_UNSCALED ::                                          */
 390.306 +  /*      Return unscaled font units.                                      */
 390.307 +  /*                                                                       */
 390.308 +  /*    FT_GLYPH_BBOX_SUBPIXELS ::                                         */
 390.309 +  /*      Return unfitted 26.6 coordinates.                                */
 390.310 +  /*                                                                       */
 390.311 +  /*    FT_GLYPH_BBOX_GRIDFIT ::                                           */
 390.312 +  /*      Return grid-fitted 26.6 coordinates.                             */
 390.313 +  /*                                                                       */
 390.314 +  /*    FT_GLYPH_BBOX_TRUNCATE ::                                          */
 390.315 +  /*      Return coordinates in integer pixels.                            */
 390.316 +  /*                                                                       */
 390.317 +  /*    FT_GLYPH_BBOX_PIXELS ::                                            */
 390.318 +  /*      Return grid-fitted pixel coordinates.                            */
 390.319 +  /*                                                                       */
 390.320 +  typedef enum  FT_Glyph_BBox_Mode_
 390.321 +  {
 390.322 +    FT_GLYPH_BBOX_UNSCALED  = 0,
 390.323 +    FT_GLYPH_BBOX_SUBPIXELS = 0,
 390.324 +    FT_GLYPH_BBOX_GRIDFIT   = 1,
 390.325 +    FT_GLYPH_BBOX_TRUNCATE  = 2,
 390.326 +    FT_GLYPH_BBOX_PIXELS    = 3
 390.327 +
 390.328 +  } FT_Glyph_BBox_Mode;
 390.329 +
 390.330 +
 390.331 +  /*************************************************************************/
 390.332 +  /*                                                                       */
 390.333 +  /* <Enum>                                                                */
 390.334 +  /*    ft_glyph_bbox_xxx                                                  */
 390.335 +  /*                                                                       */
 390.336 +  /* <Description>                                                         */
 390.337 +  /*    These constants are deprecated.  Use the corresponding             */
 390.338 +  /*    @FT_Glyph_BBox_Mode values instead.                                */
 390.339 +  /*                                                                       */
 390.340 +  /* <Values>                                                              */
 390.341 +  /*   ft_glyph_bbox_unscaled  :: See @FT_GLYPH_BBOX_UNSCALED.             */
 390.342 +  /*   ft_glyph_bbox_subpixels :: See @FT_GLYPH_BBOX_SUBPIXELS.            */
 390.343 +  /*   ft_glyph_bbox_gridfit   :: See @FT_GLYPH_BBOX_GRIDFIT.              */
 390.344 +  /*   ft_glyph_bbox_truncate  :: See @FT_GLYPH_BBOX_TRUNCATE.             */
 390.345 +  /*   ft_glyph_bbox_pixels    :: See @FT_GLYPH_BBOX_PIXELS.               */
 390.346 +  /*                                                                       */
 390.347 +#define ft_glyph_bbox_unscaled   FT_GLYPH_BBOX_UNSCALED
 390.348 +#define ft_glyph_bbox_subpixels  FT_GLYPH_BBOX_SUBPIXELS
 390.349 +#define ft_glyph_bbox_gridfit    FT_GLYPH_BBOX_GRIDFIT
 390.350 +#define ft_glyph_bbox_truncate   FT_GLYPH_BBOX_TRUNCATE
 390.351 +#define ft_glyph_bbox_pixels     FT_GLYPH_BBOX_PIXELS
 390.352 +
 390.353 +
 390.354 +  /*************************************************************************/
 390.355 +  /*                                                                       */
 390.356 +  /* <Function>                                                            */
 390.357 +  /*    FT_Glyph_Get_CBox                                                  */
 390.358 +  /*                                                                       */
 390.359 +  /* <Description>                                                         */
 390.360 +  /*    Return a glyph's `control box'.  The control box encloses all the  */
 390.361 +  /*    outline's points, including Bézier control points.  Though it      */
 390.362 +  /*    coincides with the exact bounding box for most glyphs, it can be   */
 390.363 +  /*    slightly larger in some situations (like when rotating an outline  */
 390.364 +  /*    which contains Bézier outside arcs).                               */
 390.365 +  /*                                                                       */
 390.366 +  /*    Computing the control box is very fast, while getting the bounding */
 390.367 +  /*    box can take much more time as it needs to walk over all segments  */
 390.368 +  /*    and arcs in the outline.  To get the latter, you can use the       */
 390.369 +  /*    `ftbbox' component which is dedicated to this single task.         */
 390.370 +  /*                                                                       */
 390.371 +  /* <Input>                                                               */
 390.372 +  /*    glyph :: A handle to the source glyph object.                      */
 390.373 +  /*                                                                       */
 390.374 +  /*    mode  :: The mode which indicates how to interpret the returned    */
 390.375 +  /*             bounding box values.                                      */
 390.376 +  /*                                                                       */
 390.377 +  /* <Output>                                                              */
 390.378 +  /*    acbox :: The glyph coordinate bounding box.  Coordinates are       */
 390.379 +  /*             expressed in 1/64th of pixels if it is grid-fitted.       */
 390.380 +  /*                                                                       */
 390.381 +  /* <Note>                                                                */
 390.382 +  /*    Coordinates are relative to the glyph origin, using the y~upwards  */
 390.383 +  /*    convention.                                                        */
 390.384 +  /*                                                                       */
 390.385 +  /*    If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode'   */
 390.386 +  /*    must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font        */
 390.387 +  /*    units in 26.6 pixel format.  The value @FT_GLYPH_BBOX_SUBPIXELS    */
 390.388 +  /*    is another name for this constant.                                 */
 390.389 +  /*                                                                       */
 390.390 +  /*    Note that the maximum coordinates are exclusive, which means that  */
 390.391 +  /*    one can compute the width and height of the glyph image (be it in  */
 390.392 +  /*    integer or 26.6 pixels) as:                                        */
 390.393 +  /*                                                                       */
 390.394 +  /*    {                                                                  */
 390.395 +  /*      width  = bbox.xMax - bbox.xMin;                                  */
 390.396 +  /*      height = bbox.yMax - bbox.yMin;                                  */
 390.397 +  /*    }                                                                  */
 390.398 +  /*                                                                       */
 390.399 +  /*    Note also that for 26.6 coordinates, if `bbox_mode' is set to      */
 390.400 +  /*    @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted,  */
 390.401 +  /*    which corresponds to:                                              */
 390.402 +  /*                                                                       */
 390.403 +  /*    {                                                                  */
 390.404 +  /*      bbox.xMin = FLOOR(bbox.xMin);                                    */
 390.405 +  /*      bbox.yMin = FLOOR(bbox.yMin);                                    */
 390.406 +  /*      bbox.xMax = CEILING(bbox.xMax);                                  */
 390.407 +  /*      bbox.yMax = CEILING(bbox.yMax);                                  */
 390.408 +  /*    }                                                                  */
 390.409 +  /*                                                                       */
 390.410 +  /*    To get the bbox in pixel coordinates, set `bbox_mode' to           */
 390.411 +  /*    @FT_GLYPH_BBOX_TRUNCATE.                                           */
 390.412 +  /*                                                                       */
 390.413 +  /*    To get the bbox in grid-fitted pixel coordinates, set `bbox_mode'  */
 390.414 +  /*    to @FT_GLYPH_BBOX_PIXELS.                                          */
 390.415 +  /*                                                                       */
 390.416 +  FT_EXPORT( void )
 390.417 +  FT_Glyph_Get_CBox( FT_Glyph  glyph,
 390.418 +                     FT_UInt   bbox_mode,
 390.419 +                     FT_BBox  *acbox );
 390.420 +
 390.421 +
 390.422 +  /*************************************************************************/
 390.423 +  /*                                                                       */
 390.424 +  /* <Function>                                                            */
 390.425 +  /*    FT_Glyph_To_Bitmap                                                 */
 390.426 +  /*                                                                       */
 390.427 +  /* <Description>                                                         */
 390.428 +  /*    Convert a given glyph object to a bitmap glyph object.             */
 390.429 +  /*                                                                       */
 390.430 +  /* <InOut>                                                               */
 390.431 +  /*    the_glyph   :: A pointer to a handle to the target glyph.          */
 390.432 +  /*                                                                       */
 390.433 +  /* <Input>                                                               */
 390.434 +  /*    render_mode :: An enumeration that describes how the data is       */
 390.435 +  /*                   rendered.                                           */
 390.436 +  /*                                                                       */
 390.437 +  /*    origin      :: A pointer to a vector used to translate the glyph   */
 390.438 +  /*                   image before rendering.  Can be~0 (if no            */
 390.439 +  /*                   translation).  The origin is expressed in           */
 390.440 +  /*                   26.6 pixels.                                        */
 390.441 +  /*                                                                       */
 390.442 +  /*    destroy     :: A boolean that indicates that the original glyph    */
 390.443 +  /*                   image should be destroyed by this function.  It is  */
 390.444 +  /*                   never destroyed in case of error.                   */
 390.445 +  /*                                                                       */
 390.446 +  /* <Return>                                                              */
 390.447 +  /*    FreeType error code.  0~means success.                             */
 390.448 +  /*                                                                       */
 390.449 +  /* <Note>                                                                */
 390.450 +  /*    This function does nothing if the glyph format isn't scalable.     */
 390.451 +  /*                                                                       */
 390.452 +  /*    The glyph image is translated with the `origin' vector before      */
 390.453 +  /*    rendering.                                                         */
 390.454 +  /*                                                                       */
 390.455 +  /*    The first parameter is a pointer to an @FT_Glyph handle, that will */
 390.456 +  /*    be _replaced_ by this function (with newly allocated data).        */
 390.457 +  /*    Typically, you would use (omitting error handling):                */
 390.458 +  /*                                                                       */
 390.459 +  /*                                                                       */
 390.460 +  /*      {                                                                */
 390.461 +  /*        FT_Glyph        glyph;                                         */
 390.462 +  /*        FT_BitmapGlyph  glyph_bitmap;                                  */
 390.463 +  /*                                                                       */
 390.464 +  /*                                                                       */
 390.465 +  /*        // load glyph                                                  */
 390.466 +  /*        error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT );     */
 390.467 +  /*                                                                       */
 390.468 +  /*        // extract glyph image                                         */
 390.469 +  /*        error = FT_Get_Glyph( face->glyph, &glyph );                   */
 390.470 +  /*                                                                       */
 390.471 +  /*        // convert to a bitmap (default render mode + destroying old)  */
 390.472 +  /*        if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )                 */
 390.473 +  /*        {                                                              */
 390.474 +  /*          error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL,   */
 390.475 +  /*                                      0, 1 );                          */
 390.476 +  /*          if ( error ) // `glyph' unchanged                            */
 390.477 +  /*            ...                                                        */
 390.478 +  /*        }                                                              */
 390.479 +  /*                                                                       */
 390.480 +  /*        // access bitmap content by typecasting                        */
 390.481 +  /*        glyph_bitmap = (FT_BitmapGlyph)glyph;                          */
 390.482 +  /*                                                                       */
 390.483 +  /*        // do funny stuff with it, like blitting/drawing               */
 390.484 +  /*        ...                                                            */
 390.485 +  /*                                                                       */
 390.486 +  /*        // discard glyph image (bitmap or not)                         */
 390.487 +  /*        FT_Done_Glyph( glyph );                                        */
 390.488 +  /*      }                                                                */
 390.489 +  /*                                                                       */
 390.490 +  /*                                                                       */
 390.491 +  /*    Here another example, again without error handling:                */
 390.492 +  /*                                                                       */
 390.493 +  /*                                                                       */
 390.494 +  /*      {                                                                */
 390.495 +  /*        FT_Glyph  glyphs[MAX_GLYPHS]                                   */
 390.496 +  /*                                                                       */
 390.497 +  /*                                                                       */
 390.498 +  /*        ...                                                            */
 390.499 +  /*                                                                       */
 390.500 +  /*        for ( idx = 0; i < MAX_GLYPHS; i++ )                           */
 390.501 +  /*          error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) ||       */
 390.502 +  /*                  FT_Get_Glyph ( face->glyph, &glyph[idx] );           */
 390.503 +  /*                                                                       */
 390.504 +  /*        ...                                                            */
 390.505 +  /*                                                                       */
 390.506 +  /*        for ( idx = 0; i < MAX_GLYPHS; i++ )                           */
 390.507 +  /*        {                                                              */
 390.508 +  /*          FT_Glyph  bitmap = glyphs[idx];                              */
 390.509 +  /*                                                                       */
 390.510 +  /*                                                                       */
 390.511 +  /*          ...                                                          */
 390.512 +  /*                                                                       */
 390.513 +  /*          // after this call, `bitmap' no longer points into           */
 390.514 +  /*          // the `glyphs' array (and the old value isn't destroyed)    */
 390.515 +  /*          FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 );    */
 390.516 +  /*                                                                       */
 390.517 +  /*          ...                                                          */
 390.518 +  /*                                                                       */
 390.519 +  /*          FT_Done_Glyph( bitmap );                                     */
 390.520 +  /*        }                                                              */
 390.521 +  /*                                                                       */
 390.522 +  /*        ...                                                            */
 390.523 +  /*                                                                       */
 390.524 +  /*        for ( idx = 0; i < MAX_GLYPHS; i++ )                           */
 390.525 +  /*          FT_Done_Glyph( glyphs[idx] );                                */
 390.526 +  /*      }                                                                */
 390.527 +  /*                                                                       */
 390.528 +  FT_EXPORT( FT_Error )
 390.529 +  FT_Glyph_To_Bitmap( FT_Glyph*       the_glyph,
 390.530 +                      FT_Render_Mode  render_mode,
 390.531 +                      FT_Vector*      origin,
 390.532 +                      FT_Bool         destroy );
 390.533 +
 390.534 +
 390.535 +  /*************************************************************************/
 390.536 +  /*                                                                       */
 390.537 +  /* <Function>                                                            */
 390.538 +  /*    FT_Done_Glyph                                                      */
 390.539 +  /*                                                                       */
 390.540 +  /* <Description>                                                         */
 390.541 +  /*    Destroy a given glyph.                                             */
 390.542 +  /*                                                                       */
 390.543 +  /* <Input>                                                               */
 390.544 +  /*    glyph :: A handle to the target glyph object.                      */
 390.545 +  /*                                                                       */
 390.546 +  FT_EXPORT( void )
 390.547 +  FT_Done_Glyph( FT_Glyph  glyph );
 390.548 +
 390.549 +  /* */
 390.550 +
 390.551 +
 390.552 +  /* other helpful functions */
 390.553 +
 390.554 +  /*************************************************************************/
 390.555 +  /*                                                                       */
 390.556 +  /* <Section>                                                             */
 390.557 +  /*    computations                                                       */
 390.558 +  /*                                                                       */
 390.559 +  /*************************************************************************/
 390.560 +
 390.561 +
 390.562 +  /*************************************************************************/
 390.563 +  /*                                                                       */
 390.564 +  /* <Function>                                                            */
 390.565 +  /*    FT_Matrix_Multiply                                                 */
 390.566 +  /*                                                                       */
 390.567 +  /* <Description>                                                         */
 390.568 +  /*    Perform the matrix operation `b = a*b'.                            */
 390.569 +  /*                                                                       */
 390.570 +  /* <Input>                                                               */
 390.571 +  /*    a :: A pointer to matrix `a'.                                      */
 390.572 +  /*                                                                       */
 390.573 +  /* <InOut>                                                               */
 390.574 +  /*    b :: A pointer to matrix `b'.                                      */
 390.575 +  /*                                                                       */
 390.576 +  /* <Note>                                                                */
 390.577 +  /*    The result is undefined if either `a' or `b' is zero.              */
 390.578 +  /*                                                                       */
 390.579 +  FT_EXPORT( void )
 390.580 +  FT_Matrix_Multiply( const FT_Matrix*  a,
 390.581 +                      FT_Matrix*        b );
 390.582 +
 390.583 +
 390.584 +  /*************************************************************************/
 390.585 +  /*                                                                       */
 390.586 +  /* <Function>                                                            */
 390.587 +  /*    FT_Matrix_Invert                                                   */
 390.588 +  /*                                                                       */
 390.589 +  /* <Description>                                                         */
 390.590 +  /*    Invert a 2x2 matrix.  Return an error if it can't be inverted.     */
 390.591 +  /*                                                                       */
 390.592 +  /* <InOut>                                                               */
 390.593 +  /*    matrix :: A pointer to the target matrix.  Remains untouched in    */
 390.594 +  /*              case of error.                                           */
 390.595 +  /*                                                                       */
 390.596 +  /* <Return>                                                              */
 390.597 +  /*    FreeType error code.  0~means success.                             */
 390.598 +  /*                                                                       */
 390.599 +  FT_EXPORT( FT_Error )
 390.600 +  FT_Matrix_Invert( FT_Matrix*  matrix );
 390.601 +
 390.602 +
 390.603 +  /* */
 390.604 +
 390.605 +
 390.606 +FT_END_HEADER
 390.607 +
 390.608 +#endif /* __FTGLYPH_H__ */
 390.609 +
 390.610 +
 390.611 +/* END */
 390.612 +
 390.613 +
 390.614 +/* Local Variables: */
 390.615 +/* coding: utf-8    */
 390.616 +/* End:             */
   391.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   391.2 +++ b/libs/ft2static/freetype/ftgxval.h	Sat Feb 01 19:58:19 2014 +0200
   391.3 @@ -0,0 +1,358 @@
   391.4 +/***************************************************************************/
   391.5 +/*                                                                         */
   391.6 +/*  ftgxval.h                                                              */
   391.7 +/*                                                                         */
   391.8 +/*    FreeType API for validating TrueTypeGX/AAT tables (specification).   */
   391.9 +/*                                                                         */
  391.10 +/*  Copyright 2004, 2005, 2006 by                                          */
  391.11 +/*  Masatake YAMATO, Redhat K.K,                                           */
  391.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  391.13 +/*                                                                         */
  391.14 +/*  This file is part of the FreeType project, and may only be used,       */
  391.15 +/*  modified, and distributed under the terms of the FreeType project      */
  391.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  391.17 +/*  this file you indicate that you have read the license and              */
  391.18 +/*  understand and accept it fully.                                        */
  391.19 +/*                                                                         */
  391.20 +/***************************************************************************/
  391.21 +
  391.22 +/***************************************************************************/
  391.23 +/*                                                                         */
  391.24 +/* gxvalid is derived from both gxlayout module and otvalid module.        */
  391.25 +/* Development of gxlayout is supported by the Information-technology      */
  391.26 +/* Promotion Agency(IPA), Japan.                                           */
  391.27 +/*                                                                         */
  391.28 +/***************************************************************************/
  391.29 +
  391.30 +
  391.31 +#ifndef __FTGXVAL_H__
  391.32 +#define __FTGXVAL_H__
  391.33 +
  391.34 +#include <ft2build.h>
  391.35 +#include FT_FREETYPE_H
  391.36 +
  391.37 +#ifdef FREETYPE_H
  391.38 +#error "freetype.h of FreeType 1 has been loaded!"
  391.39 +#error "Please fix the directory search order for header files"
  391.40 +#error "so that freetype.h of FreeType 2 is found first."
  391.41 +#endif
  391.42 +
  391.43 +
  391.44 +FT_BEGIN_HEADER
  391.45 +
  391.46 +
  391.47 +  /*************************************************************************/
  391.48 +  /*                                                                       */
  391.49 +  /* <Section>                                                             */
  391.50 +  /*    gx_validation                                                      */
  391.51 +  /*                                                                       */
  391.52 +  /* <Title>                                                               */
  391.53 +  /*    TrueTypeGX/AAT Validation                                          */
  391.54 +  /*                                                                       */
  391.55 +  /* <Abstract>                                                            */
  391.56 +  /*    An API to validate TrueTypeGX/AAT tables.                          */
  391.57 +  /*                                                                       */
  391.58 +  /* <Description>                                                         */
  391.59 +  /*    This section contains the declaration of functions to validate     */
  391.60 +  /*    some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd,  */
  391.61 +  /*    trak, prop, lcar).                                                 */
  391.62 +  /*                                                                       */
  391.63 +  /*************************************************************************/
  391.64 +
  391.65 +
  391.66 +  /*************************************************************************/
  391.67 +  /*                                                                       */
  391.68 +  /*                                                                       */
  391.69 +  /* Warning: Use FT_VALIDATE_XXX to validate a table.                     */
  391.70 +  /*          Following definitions are for gxvalid developers.            */
  391.71 +  /*                                                                       */
  391.72 +  /*                                                                       */
  391.73 +  /*************************************************************************/
  391.74 +
  391.75 +#define FT_VALIDATE_feat_INDEX     0
  391.76 +#define FT_VALIDATE_mort_INDEX     1
  391.77 +#define FT_VALIDATE_morx_INDEX     2
  391.78 +#define FT_VALIDATE_bsln_INDEX     3
  391.79 +#define FT_VALIDATE_just_INDEX     4
  391.80 +#define FT_VALIDATE_kern_INDEX     5
  391.81 +#define FT_VALIDATE_opbd_INDEX     6
  391.82 +#define FT_VALIDATE_trak_INDEX     7
  391.83 +#define FT_VALIDATE_prop_INDEX     8
  391.84 +#define FT_VALIDATE_lcar_INDEX     9
  391.85 +#define FT_VALIDATE_GX_LAST_INDEX  FT_VALIDATE_lcar_INDEX
  391.86 +
  391.87 +
  391.88 +  /*************************************************************************
  391.89 +   *
  391.90 +   * @macro:
  391.91 +   *   FT_VALIDATE_GX_LENGTH
  391.92 +   *
  391.93 +   * @description:
  391.94 +   *   The number of tables checked in this module.  Use it as a parameter
  391.95 +   *   for the `table-length' argument of function @FT_TrueTypeGX_Validate.
  391.96 +   */
  391.97 +#define FT_VALIDATE_GX_LENGTH     (FT_VALIDATE_GX_LAST_INDEX + 1)
  391.98 +
  391.99 +  /* */
 391.100 +
 391.101 +  /* Up to 0x1000 is used by otvalid.
 391.102 +     Ox2xxx is reserved for feature OT extension. */
 391.103 +#define FT_VALIDATE_GX_START 0x4000
 391.104 +#define FT_VALIDATE_GX_BITFIELD( tag )                  \
 391.105 +  ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX )
 391.106 +
 391.107 +
 391.108 + /**********************************************************************
 391.109 +  *
 391.110 +  * @enum:
 391.111 +  *    FT_VALIDATE_GXXXX
 391.112 +  *
 391.113 +  * @description:
 391.114 +  *    A list of bit-field constants used with @FT_TrueTypeGX_Validate to
 391.115 +  *    indicate which TrueTypeGX/AAT Type tables should be validated.
 391.116 +  *
 391.117 +  * @values:
 391.118 +  *    FT_VALIDATE_feat ::
 391.119 +  *      Validate `feat' table.
 391.120 +  *
 391.121 +  *    FT_VALIDATE_mort ::
 391.122 +  *      Validate `mort' table.
 391.123 +  *
 391.124 +  *    FT_VALIDATE_morx ::
 391.125 +  *      Validate `morx' table.
 391.126 +  *
 391.127 +  *    FT_VALIDATE_bsln ::
 391.128 +  *      Validate `bsln' table.
 391.129 +  *
 391.130 +  *    FT_VALIDATE_just ::
 391.131 +  *      Validate `just' table.
 391.132 +  *
 391.133 +  *    FT_VALIDATE_kern ::
 391.134 +  *      Validate `kern' table.
 391.135 +  *
 391.136 +  *    FT_VALIDATE_opbd ::
 391.137 +  *      Validate `opbd' table.
 391.138 +  *
 391.139 +  *    FT_VALIDATE_trak ::
 391.140 +  *      Validate `trak' table.
 391.141 +  *
 391.142 +  *    FT_VALIDATE_prop ::
 391.143 +  *      Validate `prop' table.
 391.144 +  *
 391.145 +  *    FT_VALIDATE_lcar ::
 391.146 +  *      Validate `lcar' table.
 391.147 +  *
 391.148 +  *    FT_VALIDATE_GX ::
 391.149 +  *      Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern,
 391.150 +  *      opbd, trak, prop and lcar).
 391.151 +  *
 391.152 +  */
 391.153 +
 391.154 +#define FT_VALIDATE_feat  FT_VALIDATE_GX_BITFIELD( feat )
 391.155 +#define FT_VALIDATE_mort  FT_VALIDATE_GX_BITFIELD( mort )
 391.156 +#define FT_VALIDATE_morx  FT_VALIDATE_GX_BITFIELD( morx )
 391.157 +#define FT_VALIDATE_bsln  FT_VALIDATE_GX_BITFIELD( bsln )
 391.158 +#define FT_VALIDATE_just  FT_VALIDATE_GX_BITFIELD( just )
 391.159 +#define FT_VALIDATE_kern  FT_VALIDATE_GX_BITFIELD( kern )
 391.160 +#define FT_VALIDATE_opbd  FT_VALIDATE_GX_BITFIELD( opbd )
 391.161 +#define FT_VALIDATE_trak  FT_VALIDATE_GX_BITFIELD( trak )
 391.162 +#define FT_VALIDATE_prop  FT_VALIDATE_GX_BITFIELD( prop )
 391.163 +#define FT_VALIDATE_lcar  FT_VALIDATE_GX_BITFIELD( lcar )
 391.164 +
 391.165 +#define FT_VALIDATE_GX  ( FT_VALIDATE_feat | \
 391.166 +                          FT_VALIDATE_mort | \
 391.167 +                          FT_VALIDATE_morx | \
 391.168 +                          FT_VALIDATE_bsln | \
 391.169 +                          FT_VALIDATE_just | \
 391.170 +                          FT_VALIDATE_kern | \
 391.171 +                          FT_VALIDATE_opbd | \
 391.172 +                          FT_VALIDATE_trak | \
 391.173 +                          FT_VALIDATE_prop | \
 391.174 +                          FT_VALIDATE_lcar )
 391.175 +
 391.176 +
 391.177 +  /* */
 391.178 +
 391.179 + /**********************************************************************
 391.180 +  *
 391.181 +  * @function:
 391.182 +  *    FT_TrueTypeGX_Validate
 391.183 +  *
 391.184 +  * @description:
 391.185 +  *    Validate various TrueTypeGX tables to assure that all offsets and
 391.186 +  *    indices are valid.  The idea is that a higher-level library which
 391.187 +  *    actually does the text layout can access those tables without
 391.188 +  *    error checking (which can be quite time consuming).
 391.189 +  *
 391.190 +  * @input:
 391.191 +  *    face ::
 391.192 +  *       A handle to the input face.
 391.193 +  *
 391.194 +  *    validation_flags ::
 391.195 +  *       A bit field which specifies the tables to be validated.  See
 391.196 +  *       @FT_VALIDATE_GXXXX for possible values.
 391.197 +  *
 391.198 +  *    table_length ::
 391.199 +  *       The size of the `tables' array.  Normally, @FT_VALIDATE_GX_LENGTH
 391.200 +  *       should be passed.
 391.201 +  *
 391.202 +  * @output:
 391.203 +  *    tables ::
 391.204 +  *       The array where all validated sfnt tables are stored.
 391.205 +  *       The array itself must be allocated by a client.
 391.206 +  *
 391.207 +  * @return:
 391.208 +  *   FreeType error code.  0~means success.
 391.209 +  *
 391.210 +  * @note:
 391.211 +  *   This function only works with TrueTypeGX fonts, returning an error
 391.212 +  *   otherwise.
 391.213 +  *
 391.214 +  *   After use, the application should deallocate the buffers pointed to by
 391.215 +  *   each `tables' element, by calling @FT_TrueTypeGX_Free.  A NULL value
 391.216 +  *   indicates that the table either doesn't exist in the font, the
 391.217 +  *   application hasn't asked for validation, or the validator doesn't have
 391.218 +  *   the ability to validate the sfnt table.
 391.219 +  */
 391.220 +  FT_EXPORT( FT_Error )
 391.221 +  FT_TrueTypeGX_Validate( FT_Face   face,
 391.222 +                          FT_UInt   validation_flags,
 391.223 +                          FT_Bytes  tables[FT_VALIDATE_GX_LENGTH],
 391.224 +                          FT_UInt   table_length );
 391.225 +
 391.226 +
 391.227 +  /* */
 391.228 +
 391.229 + /**********************************************************************
 391.230 +  *
 391.231 +  * @function:
 391.232 +  *    FT_TrueTypeGX_Free
 391.233 +  *
 391.234 +  * @description:
 391.235 +  *    Free the buffer allocated by TrueTypeGX validator.
 391.236 +  *
 391.237 +  * @input:
 391.238 +  *    face ::
 391.239 +  *       A handle to the input face.
 391.240 +  *
 391.241 +  *    table ::
 391.242 +  *       The pointer to the buffer allocated by
 391.243 +  *       @FT_TrueTypeGX_Validate.
 391.244 +  *
 391.245 +  * @note:
 391.246 +  *   This function must be used to free the buffer allocated by
 391.247 +  *   @FT_TrueTypeGX_Validate only.
 391.248 +  */
 391.249 +  FT_EXPORT( void )
 391.250 +  FT_TrueTypeGX_Free( FT_Face   face,
 391.251 +                      FT_Bytes  table );
 391.252 +
 391.253 +
 391.254 +  /* */
 391.255 +
 391.256 + /**********************************************************************
 391.257 +  *
 391.258 +  * @enum:
 391.259 +  *    FT_VALIDATE_CKERNXXX
 391.260 +  *
 391.261 +  * @description:
 391.262 +  *    A list of bit-field constants used with @FT_ClassicKern_Validate
 391.263 +  *    to indicate the classic kern dialect or dialects.  If the selected
 391.264 +  *    type doesn't fit, @FT_ClassicKern_Validate regards the table as
 391.265 +  *    invalid.
 391.266 +  *
 391.267 +  * @values:
 391.268 +  *    FT_VALIDATE_MS ::
 391.269 +  *      Handle the `kern' table as a classic Microsoft kern table.
 391.270 +  *
 391.271 +  *    FT_VALIDATE_APPLE ::
 391.272 +  *      Handle the `kern' table as a classic Apple kern table.
 391.273 +  *
 391.274 +  *    FT_VALIDATE_CKERN ::
 391.275 +  *      Handle the `kern' as either classic Apple or Microsoft kern table.
 391.276 +  */
 391.277 +#define FT_VALIDATE_MS     ( FT_VALIDATE_GX_START << 0 )
 391.278 +#define FT_VALIDATE_APPLE  ( FT_VALIDATE_GX_START << 1 )
 391.279 +
 391.280 +#define FT_VALIDATE_CKERN  ( FT_VALIDATE_MS | FT_VALIDATE_APPLE )
 391.281 +
 391.282 +
 391.283 +  /* */
 391.284 +
 391.285 + /**********************************************************************
 391.286 +  *
 391.287 +  * @function:
 391.288 +  *    FT_ClassicKern_Validate
 391.289 +  *
 391.290 +  * @description:
 391.291 +  *    Validate classic (16-bit format) kern table to assure that the offsets
 391.292 +  *    and indices are valid.  The idea is that a higher-level library which
 391.293 +  *    actually does the text layout can access those tables without error
 391.294 +  *    checking (which can be quite time consuming).
 391.295 +  *
 391.296 +  *    The `kern' table validator in @FT_TrueTypeGX_Validate deals with both
 391.297 +  *    the new 32-bit format and the classic 16-bit format, while
 391.298 +  *    FT_ClassicKern_Validate only supports the classic 16-bit format.
 391.299 +  *
 391.300 +  * @input:
 391.301 +  *    face ::
 391.302 +  *       A handle to the input face.
 391.303 +  *
 391.304 +  *    validation_flags ::
 391.305 +  *       A bit field which specifies the dialect to be validated.  See
 391.306 +  *       @FT_VALIDATE_CKERNXXX for possible values.
 391.307 +  *
 391.308 +  * @output:
 391.309 +  *    ckern_table ::
 391.310 +  *       A pointer to the kern table.
 391.311 +  *
 391.312 +  * @return:
 391.313 +  *   FreeType error code.  0~means success.
 391.314 +  *
 391.315 +  * @note:
 391.316 +  *   After use, the application should deallocate the buffers pointed to by
 391.317 +  *   `ckern_table', by calling @FT_ClassicKern_Free.  A NULL value
 391.318 +  *   indicates that the table doesn't exist in the font.
 391.319 +  */
 391.320 +  FT_EXPORT( FT_Error )
 391.321 +  FT_ClassicKern_Validate( FT_Face    face,
 391.322 +                           FT_UInt    validation_flags,
 391.323 +                           FT_Bytes  *ckern_table );
 391.324 +
 391.325 +
 391.326 +  /* */
 391.327 +
 391.328 + /**********************************************************************
 391.329 +  *
 391.330 +  * @function:
 391.331 +  *    FT_ClassicKern_Free
 391.332 +  *
 391.333 +  * @description:
 391.334 +  *    Free the buffer allocated by classic Kern validator.
 391.335 +  *
 391.336 +  * @input:
 391.337 +  *    face ::
 391.338 +  *       A handle to the input face.
 391.339 +  *
 391.340 +  *    table ::
 391.341 +  *       The pointer to the buffer that is allocated by
 391.342 +  *       @FT_ClassicKern_Validate.
 391.343 +  *
 391.344 +  * @note:
 391.345 +  *   This function must be used to free the buffer allocated by
 391.346 +  *   @FT_ClassicKern_Validate only.
 391.347 +  */
 391.348 +  FT_EXPORT( void )
 391.349 +  FT_ClassicKern_Free( FT_Face   face,
 391.350 +                       FT_Bytes  table );
 391.351 +
 391.352 +
 391.353 + /* */
 391.354 +
 391.355 +
 391.356 +FT_END_HEADER
 391.357 +
 391.358 +#endif /* __FTGXVAL_H__ */
 391.359 +
 391.360 +
 391.361 +/* END */
   392.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   392.2 +++ b/libs/ft2static/freetype/ftgzip.h	Sat Feb 01 19:58:19 2014 +0200
   392.3 @@ -0,0 +1,102 @@
   392.4 +/***************************************************************************/
   392.5 +/*                                                                         */
   392.6 +/*  ftgzip.h                                                               */
   392.7 +/*                                                                         */
   392.8 +/*    Gzip-compressed stream support.                                      */
   392.9 +/*                                                                         */
  392.10 +/*  Copyright 2002, 2003, 2004, 2006 by                                    */
  392.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  392.12 +/*                                                                         */
  392.13 +/*  This file is part of the FreeType project, and may only be used,       */
  392.14 +/*  modified, and distributed under the terms of the FreeType project      */
  392.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  392.16 +/*  this file you indicate that you have read the license and              */
  392.17 +/*  understand and accept it fully.                                        */
  392.18 +/*                                                                         */
  392.19 +/***************************************************************************/
  392.20 +
  392.21 +
  392.22 +#ifndef __FTGZIP_H__
  392.23 +#define __FTGZIP_H__
  392.24 +
  392.25 +#include <ft2build.h>
  392.26 +#include FT_FREETYPE_H
  392.27 +
  392.28 +#ifdef FREETYPE_H
  392.29 +#error "freetype.h of FreeType 1 has been loaded!"
  392.30 +#error "Please fix the directory search order for header files"
  392.31 +#error "so that freetype.h of FreeType 2 is found first."
  392.32 +#endif
  392.33 +
  392.34 +
  392.35 +FT_BEGIN_HEADER
  392.36 +
  392.37 +  /*************************************************************************/
  392.38 +  /*                                                                       */
  392.39 +  /* <Section>                                                             */
  392.40 +  /*    gzip                                                               */
  392.41 +  /*                                                                       */
  392.42 +  /* <Title>                                                               */
  392.43 +  /*    GZIP Streams                                                       */
  392.44 +  /*                                                                       */
  392.45 +  /* <Abstract>                                                            */
  392.46 +  /*    Using gzip-compressed font files.                                  */
  392.47 +  /*                                                                       */
  392.48 +  /* <Description>                                                         */
  392.49 +  /*    This section contains the declaration of Gzip-specific functions.  */
  392.50 +  /*                                                                       */
  392.51 +  /*************************************************************************/
  392.52 +
  392.53 +
  392.54 + /************************************************************************
  392.55 +  *
  392.56 +  * @function:
  392.57 +  *   FT_Stream_OpenGzip
  392.58 +  *
  392.59 +  * @description:
  392.60 +  *   Open a new stream to parse gzip-compressed font files.  This is
  392.61 +  *   mainly used to support the compressed `*.pcf.gz' fonts that come
  392.62 +  *   with XFree86.
  392.63 +  *
  392.64 +  * @input:
  392.65 +  *   stream ::
  392.66 +  *     The target embedding stream.
  392.67 +  *
  392.68 +  *   source ::
  392.69 +  *     The source stream.
  392.70 +  *
  392.71 +  * @return:
  392.72 +  *   FreeType error code.  0~means success.
  392.73 +  *
  392.74 +  * @note:
  392.75 +  *   The source stream must be opened _before_ calling this function.
  392.76 +  *
  392.77 +  *   Calling the internal function `FT_Stream_Close' on the new stream will
  392.78 +  *   *not* call `FT_Stream_Close' on the source stream.  None of the stream
  392.79 +  *   objects will be released to the heap.
  392.80 +  *
  392.81 +  *   The stream implementation is very basic and resets the decompression
  392.82 +  *   process each time seeking backwards is needed within the stream.
  392.83 +  *
  392.84 +  *   In certain builds of the library, gzip compression recognition is
  392.85 +  *   automatically handled when calling @FT_New_Face or @FT_Open_Face.
  392.86 +  *   This means that if no font driver is capable of handling the raw
  392.87 +  *   compressed file, the library will try to open a gzipped stream from
  392.88 +  *   it and re-open the face with it.
  392.89 +  *
  392.90 +  *   This function may return `FT_Err_Unimplemented_Feature' if your build
  392.91 +  *   of FreeType was not compiled with zlib support.
  392.92 +  */
  392.93 +  FT_EXPORT( FT_Error )
  392.94 +  FT_Stream_OpenGzip( FT_Stream  stream,
  392.95 +                      FT_Stream  source );
  392.96 +
  392.97 + /* */
  392.98 +
  392.99 +
 392.100 +FT_END_HEADER
 392.101 +
 392.102 +#endif /* __FTGZIP_H__ */
 392.103 +
 392.104 +
 392.105 +/* END */
   393.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   393.2 +++ b/libs/ft2static/freetype/ftimage.h	Sat Feb 01 19:58:19 2014 +0200
   393.3 @@ -0,0 +1,1313 @@
   393.4 +/***************************************************************************/
   393.5 +/*                                                                         */
   393.6 +/*  ftimage.h                                                              */
   393.7 +/*                                                                         */
   393.8 +/*    FreeType glyph image formats and default raster interface            */
   393.9 +/*    (specification).                                                     */
  393.10 +/*                                                                         */
  393.11 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
  393.12 +/*            2010 by                                                      */
  393.13 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  393.14 +/*                                                                         */
  393.15 +/*  This file is part of the FreeType project, and may only be used,       */
  393.16 +/*  modified, and distributed under the terms of the FreeType project      */
  393.17 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  393.18 +/*  this file you indicate that you have read the license and              */
  393.19 +/*  understand and accept it fully.                                        */
  393.20 +/*                                                                         */
  393.21 +/***************************************************************************/
  393.22 +
  393.23 +  /*************************************************************************/
  393.24 +  /*                                                                       */
  393.25 +  /* Note: A `raster' is simply a scan-line converter, used to render      */
  393.26 +  /*       FT_Outlines into FT_Bitmaps.                                    */
  393.27 +  /*                                                                       */
  393.28 +  /*************************************************************************/
  393.29 +
  393.30 +
  393.31 +#ifndef __FTIMAGE_H__
  393.32 +#define __FTIMAGE_H__
  393.33 +
  393.34 +
  393.35 +  /* _STANDALONE_ is from ftgrays.c */
  393.36 +#ifndef _STANDALONE_
  393.37 +#include <ft2build.h>
  393.38 +#endif
  393.39 +
  393.40 +
  393.41 +FT_BEGIN_HEADER
  393.42 +
  393.43 +
  393.44 +  /*************************************************************************/
  393.45 +  /*                                                                       */
  393.46 +  /* <Section>                                                             */
  393.47 +  /*    basic_types                                                        */
  393.48 +  /*                                                                       */
  393.49 +  /*************************************************************************/
  393.50 +
  393.51 +
  393.52 +  /*************************************************************************/
  393.53 +  /*                                                                       */
  393.54 +  /* <Type>                                                                */
  393.55 +  /*    FT_Pos                                                             */
  393.56 +  /*                                                                       */
  393.57 +  /* <Description>                                                         */
  393.58 +  /*    The type FT_Pos is used to store vectorial coordinates.  Depending */
  393.59 +  /*    on the context, these can represent distances in integer font      */
  393.60 +  /*    units, or 16.16, or 26.6 fixed float pixel coordinates.            */
  393.61 +  /*                                                                       */
  393.62 +  typedef signed long  FT_Pos;
  393.63 +
  393.64 +
  393.65 +  /*************************************************************************/
  393.66 +  /*                                                                       */
  393.67 +  /* <Struct>                                                              */
  393.68 +  /*    FT_Vector                                                          */
  393.69 +  /*                                                                       */
  393.70 +  /* <Description>                                                         */
  393.71 +  /*    A simple structure used to store a 2D vector; coordinates are of   */
  393.72 +  /*    the FT_Pos type.                                                   */
  393.73 +  /*                                                                       */
  393.74 +  /* <Fields>                                                              */
  393.75 +  /*    x :: The horizontal coordinate.                                    */
  393.76 +  /*    y :: The vertical coordinate.                                      */
  393.77 +  /*                                                                       */
  393.78 +  typedef struct  FT_Vector_
  393.79 +  {
  393.80 +    FT_Pos  x;
  393.81 +    FT_Pos  y;
  393.82 +
  393.83 +  } FT_Vector;
  393.84 +
  393.85 +
  393.86 +  /*************************************************************************/
  393.87 +  /*                                                                       */
  393.88 +  /* <Struct>                                                              */
  393.89 +  /*    FT_BBox                                                            */
  393.90 +  /*                                                                       */
  393.91 +  /* <Description>                                                         */
  393.92 +  /*    A structure used to hold an outline's bounding box, i.e., the      */
  393.93 +  /*    coordinates of its extrema in the horizontal and vertical          */
  393.94 +  /*    directions.                                                        */
  393.95 +  /*                                                                       */
  393.96 +  /* <Fields>                                                              */
  393.97 +  /*    xMin :: The horizontal minimum (left-most).                        */
  393.98 +  /*                                                                       */
  393.99 +  /*    yMin :: The vertical minimum (bottom-most).                        */
 393.100 +  /*                                                                       */
 393.101 +  /*    xMax :: The horizontal maximum (right-most).                       */
 393.102 +  /*                                                                       */
 393.103 +  /*    yMax :: The vertical maximum (top-most).                           */
 393.104 +  /*                                                                       */
 393.105 +  /* <Note>                                                                */
 393.106 +  /*    The bounding box is specified with the coordinates of the lower    */
 393.107 +  /*    left and the upper right corner.  In PostScript, those values are  */
 393.108 +  /*    often called (llx,lly) and (urx,ury), respectively.                */
 393.109 +  /*                                                                       */
 393.110 +  /*    If `yMin' is negative, this value gives the glyph's descender.     */
 393.111 +  /*    Otherwise, the glyph doesn't descend below the baseline.           */
 393.112 +  /*    Similarly, if `ymax' is positive, this value gives the glyph's     */
 393.113 +  /*    ascender.                                                          */
 393.114 +  /*                                                                       */
 393.115 +  /*    `xMin' gives the horizontal distance from the glyph's origin to    */
 393.116 +  /*    the left edge of the glyph's bounding box.  If `xMin' is negative, */
 393.117 +  /*    the glyph extends to the left of the origin.                       */
 393.118 +  /*                                                                       */
 393.119 +  typedef struct  FT_BBox_
 393.120 +  {
 393.121 +    FT_Pos  xMin, yMin;
 393.122 +    FT_Pos  xMax, yMax;
 393.123 +
 393.124 +  } FT_BBox;
 393.125 +
 393.126 +
 393.127 +  /*************************************************************************/
 393.128 +  /*                                                                       */
 393.129 +  /* <Enum>                                                                */
 393.130 +  /*    FT_Pixel_Mode                                                      */
 393.131 +  /*                                                                       */
 393.132 +  /* <Description>                                                         */
 393.133 +  /*    An enumeration type used to describe the format of pixels in a     */
 393.134 +  /*    given bitmap.  Note that additional formats may be added in the    */
 393.135 +  /*    future.                                                            */
 393.136 +  /*                                                                       */
 393.137 +  /* <Values>                                                              */
 393.138 +  /*    FT_PIXEL_MODE_NONE ::                                              */
 393.139 +  /*      Value~0 is reserved.                                             */
 393.140 +  /*                                                                       */
 393.141 +  /*    FT_PIXEL_MODE_MONO ::                                              */
 393.142 +  /*      A monochrome bitmap, using 1~bit per pixel.  Note that pixels    */
 393.143 +  /*      are stored in most-significant order (MSB), which means that     */
 393.144 +  /*      the left-most pixel in a byte has value 128.                     */
 393.145 +  /*                                                                       */
 393.146 +  /*    FT_PIXEL_MODE_GRAY ::                                              */
 393.147 +  /*      An 8-bit bitmap, generally used to represent anti-aliased glyph  */
 393.148 +  /*      images.  Each pixel is stored in one byte.  Note that the number */
 393.149 +  /*      of `gray' levels is stored in the `num_grays' field of the       */
 393.150 +  /*      @FT_Bitmap structure (it generally is 256).                      */
 393.151 +  /*                                                                       */
 393.152 +  /*    FT_PIXEL_MODE_GRAY2 ::                                             */
 393.153 +  /*      A 2-bit per pixel bitmap, used to represent embedded             */
 393.154 +  /*      anti-aliased bitmaps in font files according to the OpenType     */
 393.155 +  /*      specification.  We haven't found a single font using this        */
 393.156 +  /*      format, however.                                                 */
 393.157 +  /*                                                                       */
 393.158 +  /*    FT_PIXEL_MODE_GRAY4 ::                                             */
 393.159 +  /*      A 4-bit per pixel bitmap, representing embedded anti-aliased     */
 393.160 +  /*      bitmaps in font files according to the OpenType specification.   */
 393.161 +  /*      We haven't found a single font using this format, however.       */
 393.162 +  /*                                                                       */
 393.163 +  /*    FT_PIXEL_MODE_LCD ::                                               */
 393.164 +  /*      An 8-bit bitmap, representing RGB or BGR decimated glyph images  */
 393.165 +  /*      used for display on LCD displays; the bitmap is three times      */
 393.166 +  /*      wider than the original glyph image.  See also                   */
 393.167 +  /*      @FT_RENDER_MODE_LCD.                                             */
 393.168 +  /*                                                                       */
 393.169 +  /*    FT_PIXEL_MODE_LCD_V ::                                             */
 393.170 +  /*      An 8-bit bitmap, representing RGB or BGR decimated glyph images  */
 393.171 +  /*      used for display on rotated LCD displays; the bitmap is three    */
 393.172 +  /*      times taller than the original glyph image.  See also            */
 393.173 +  /*      @FT_RENDER_MODE_LCD_V.                                           */
 393.174 +  /*                                                                       */
 393.175 +  typedef enum  FT_Pixel_Mode_
 393.176 +  {
 393.177 +    FT_PIXEL_MODE_NONE = 0,
 393.178 +    FT_PIXEL_MODE_MONO,
 393.179 +    FT_PIXEL_MODE_GRAY,
 393.180 +    FT_PIXEL_MODE_GRAY2,
 393.181 +    FT_PIXEL_MODE_GRAY4,
 393.182 +    FT_PIXEL_MODE_LCD,
 393.183 +    FT_PIXEL_MODE_LCD_V,
 393.184 +
 393.185 +    FT_PIXEL_MODE_MAX      /* do not remove */
 393.186 +
 393.187 +  } FT_Pixel_Mode;
 393.188 +
 393.189 +
 393.190 +  /*************************************************************************/
 393.191 +  /*                                                                       */
 393.192 +  /* <Enum>                                                                */
 393.193 +  /*    ft_pixel_mode_xxx                                                  */
 393.194 +  /*                                                                       */
 393.195 +  /* <Description>                                                         */
 393.196 +  /*    A list of deprecated constants.  Use the corresponding             */
 393.197 +  /*    @FT_Pixel_Mode values instead.                                     */
 393.198 +  /*                                                                       */
 393.199 +  /* <Values>                                                              */
 393.200 +  /*    ft_pixel_mode_none  :: See @FT_PIXEL_MODE_NONE.                    */
 393.201 +  /*    ft_pixel_mode_mono  :: See @FT_PIXEL_MODE_MONO.                    */
 393.202 +  /*    ft_pixel_mode_grays :: See @FT_PIXEL_MODE_GRAY.                    */
 393.203 +  /*    ft_pixel_mode_pal2  :: See @FT_PIXEL_MODE_GRAY2.                   */
 393.204 +  /*    ft_pixel_mode_pal4  :: See @FT_PIXEL_MODE_GRAY4.                   */
 393.205 +  /*                                                                       */
 393.206 +#define ft_pixel_mode_none   FT_PIXEL_MODE_NONE
 393.207 +#define ft_pixel_mode_mono   FT_PIXEL_MODE_MONO
 393.208 +#define ft_pixel_mode_grays  FT_PIXEL_MODE_GRAY
 393.209 +#define ft_pixel_mode_pal2   FT_PIXEL_MODE_GRAY2
 393.210 +#define ft_pixel_mode_pal4   FT_PIXEL_MODE_GRAY4
 393.211 +
 393.212 + /* */
 393.213 +
 393.214 +#if 0
 393.215 +
 393.216 +  /*************************************************************************/
 393.217 +  /*                                                                       */
 393.218 +  /* <Enum>                                                                */
 393.219 +  /*    FT_Palette_Mode                                                    */
 393.220 +  /*                                                                       */
 393.221 +  /* <Description>                                                         */
 393.222 +  /*    THIS TYPE IS DEPRECATED.  DO NOT USE IT!                           */
 393.223 +  /*                                                                       */
 393.224 +  /*    An enumeration type to describe the format of a bitmap palette,    */
 393.225 +  /*    used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8.               */
 393.226 +  /*                                                                       */
 393.227 +  /* <Values>                                                              */
 393.228 +  /*    ft_palette_mode_rgb  :: The palette is an array of 3-byte RGB      */
 393.229 +  /*                            records.                                   */
 393.230 +  /*                                                                       */
 393.231 +  /*    ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA     */
 393.232 +  /*                            records.                                   */
 393.233 +  /*                                                                       */
 393.234 +  /* <Note>                                                                */
 393.235 +  /*    As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by       */
 393.236 +  /*    FreeType, these types are not handled by the library itself.       */
 393.237 +  /*                                                                       */
 393.238 +  typedef enum  FT_Palette_Mode_
 393.239 +  {
 393.240 +    ft_palette_mode_rgb = 0,
 393.241 +    ft_palette_mode_rgba,
 393.242 +
 393.243 +    ft_palette_mode_max   /* do not remove */
 393.244 +
 393.245 +  } FT_Palette_Mode;
 393.246 +
 393.247 +  /* */
 393.248 +
 393.249 +#endif
 393.250 +
 393.251 +
 393.252 +  /*************************************************************************/
 393.253 +  /*                                                                       */
 393.254 +  /* <Struct>                                                              */
 393.255 +  /*    FT_Bitmap                                                          */
 393.256 +  /*                                                                       */
 393.257 +  /* <Description>                                                         */
 393.258 +  /*    A structure used to describe a bitmap or pixmap to the raster.     */
 393.259 +  /*    Note that we now manage pixmaps of various depths through the      */
 393.260 +  /*    `pixel_mode' field.                                                */
 393.261 +  /*                                                                       */
 393.262 +  /* <Fields>                                                              */
 393.263 +  /*    rows         :: The number of bitmap rows.                         */
 393.264 +  /*                                                                       */
 393.265 +  /*    width        :: The number of pixels in bitmap row.                */
 393.266 +  /*                                                                       */
 393.267 +  /*    pitch        :: The pitch's absolute value is the number of bytes  */
 393.268 +  /*                    taken by one bitmap row, including padding.        */
 393.269 +  /*                    However, the pitch is positive when the bitmap has */
 393.270 +  /*                    a `down' flow, and negative when it has an `up'    */
 393.271 +  /*                    flow.  In all cases, the pitch is an offset to add */
 393.272 +  /*                    to a bitmap pointer in order to go down one row.   */
 393.273 +  /*                                                                       */
 393.274 +  /*                    Note that `padding' means the alignment of a       */
 393.275 +  /*                    bitmap to a byte border, and FreeType functions    */
 393.276 +  /*                    normally align to the smallest possible integer    */
 393.277 +  /*                    value.                                             */
 393.278 +  /*                                                                       */
 393.279 +  /*                    For the B/W rasterizer, `pitch' is always an even  */
 393.280 +  /*                    number.                                            */
 393.281 +  /*                                                                       */
 393.282 +  /*                    To change the pitch of a bitmap (say, to make it a */
 393.283 +  /*                    multiple of 4), use @FT_Bitmap_Convert.            */
 393.284 +  /*                    Alternatively, you might use callback functions to */
 393.285 +  /*                    directly render to the application's surface; see  */
 393.286 +  /*                    the file `example2.cpp' in the tutorial for a      */
 393.287 +  /*                    demonstration.                                     */
 393.288 +  /*                                                                       */
 393.289 +  /*    buffer       :: A typeless pointer to the bitmap buffer.  This     */
 393.290 +  /*                    value should be aligned on 32-bit boundaries in    */
 393.291 +  /*                    most cases.                                        */
 393.292 +  /*                                                                       */
 393.293 +  /*    num_grays    :: This field is only used with                       */
 393.294 +  /*                    @FT_PIXEL_MODE_GRAY; it gives the number of gray   */
 393.295 +  /*                    levels used in the bitmap.                         */
 393.296 +  /*                                                                       */
 393.297 +  /*    pixel_mode   :: The pixel mode, i.e., how pixel bits are stored.   */
 393.298 +  /*                    See @FT_Pixel_Mode for possible values.            */
 393.299 +  /*                                                                       */
 393.300 +  /*    palette_mode :: This field is intended for paletted pixel modes;   */
 393.301 +  /*                    it indicates how the palette is stored.  Not       */
 393.302 +  /*                    used currently.                                    */
 393.303 +  /*                                                                       */
 393.304 +  /*    palette      :: A typeless pointer to the bitmap palette; this     */
 393.305 +  /*                    field is intended for paletted pixel modes.  Not   */
 393.306 +  /*                    used currently.                                    */
 393.307 +  /*                                                                       */
 393.308 +  /* <Note>                                                                */
 393.309 +  /*   For now, the only pixel modes supported by FreeType are mono and    */
 393.310 +  /*   grays.  However, drivers might be added in the future to support    */
 393.311 +  /*   more `colorful' options.                                            */
 393.312 +  /*                                                                       */
 393.313 +  typedef struct  FT_Bitmap_
 393.314 +  {
 393.315 +    int             rows;
 393.316 +    int             width;
 393.317 +    int             pitch;
 393.318 +    unsigned char*  buffer;
 393.319 +    short           num_grays;
 393.320 +    char            pixel_mode;
 393.321 +    char            palette_mode;
 393.322 +    void*           palette;
 393.323 +
 393.324 +  } FT_Bitmap;
 393.325 +
 393.326 +
 393.327 +  /*************************************************************************/
 393.328 +  /*                                                                       */
 393.329 +  /* <Section>                                                             */
 393.330 +  /*    outline_processing                                                 */
 393.331 +  /*                                                                       */
 393.332 +  /*************************************************************************/
 393.333 +
 393.334 +
 393.335 +  /*************************************************************************/
 393.336 +  /*                                                                       */
 393.337 +  /* <Struct>                                                              */
 393.338 +  /*    FT_Outline                                                         */
 393.339 +  /*                                                                       */
 393.340 +  /* <Description>                                                         */
 393.341 +  /*    This structure is used to describe an outline to the scan-line     */
 393.342 +  /*    converter.                                                         */
 393.343 +  /*                                                                       */
 393.344 +  /* <Fields>                                                              */
 393.345 +  /*    n_contours :: The number of contours in the outline.               */
 393.346 +  /*                                                                       */
 393.347 +  /*    n_points   :: The number of points in the outline.                 */
 393.348 +  /*                                                                       */
 393.349 +  /*    points     :: A pointer to an array of `n_points' @FT_Vector       */
 393.350 +  /*                  elements, giving the outline's point coordinates.    */
 393.351 +  /*                                                                       */
 393.352 +  /*    tags       :: A pointer to an array of `n_points' chars, giving    */
 393.353 +  /*                  each outline point's type.                           */
 393.354 +  /*                                                                       */
 393.355 +  /*                  If bit~0 is unset, the point is `off' the curve,     */
 393.356 +  /*                  i.e., a Bézier control point, while it is `on' if    */
 393.357 +  /*                  set.                                                 */
 393.358 +  /*                                                                       */
 393.359 +  /*                  Bit~1 is meaningful for `off' points only.  If set,  */
 393.360 +  /*                  it indicates a third-order Bézier arc control point; */
 393.361 +  /*                  and a second-order control point if unset.           */
 393.362 +  /*                                                                       */
 393.363 +  /*                  If bit~2 is set, bits 5-7 contain the drop-out mode  */
 393.364 +  /*                  (as defined in the OpenType specification; the value */
 393.365 +  /*                  is the same as the argument to the SCANMODE          */
 393.366 +  /*                  instruction).                                        */
 393.367 +  /*                                                                       */
 393.368 +  /*                  Bits 3 and~4 are reserved for internal purposes.     */
 393.369 +  /*                                                                       */
 393.370 +  /*    contours   :: An array of `n_contours' shorts, giving the end      */
 393.371 +  /*                  point of each contour within the outline.  For       */
 393.372 +  /*                  example, the first contour is defined by the points  */
 393.373 +  /*                  `0' to `contours[0]', the second one is defined by   */
 393.374 +  /*                  the points `contours[0]+1' to `contours[1]', etc.    */
 393.375 +  /*                                                                       */
 393.376 +  /*    flags      :: A set of bit flags used to characterize the outline  */
 393.377 +  /*                  and give hints to the scan-converter and hinter on   */
 393.378 +  /*                  how to convert/grid-fit it.  See @FT_OUTLINE_FLAGS.  */
 393.379 +  /*                                                                       */
 393.380 +  /* <Note>                                                                */
 393.381 +  /*    The B/W rasterizer only checks bit~2 in the `tags' array for the   */
 393.382 +  /*    first point of each contour.  The drop-out mode as given with      */
 393.383 +  /*    @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and       */
 393.384 +  /*    @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden.           */
 393.385 +  /*                                                                       */
 393.386 +  typedef struct  FT_Outline_
 393.387 +  {
 393.388 +    short       n_contours;      /* number of contours in glyph        */
 393.389 +    short       n_points;        /* number of points in the glyph      */
 393.390 +
 393.391 +    FT_Vector*  points;          /* the outline's points               */
 393.392 +    char*       tags;            /* the points flags                   */
 393.393 +    short*      contours;        /* the contour end points             */
 393.394 +
 393.395 +    int         flags;           /* outline masks                      */
 393.396 +
 393.397 +  } FT_Outline;
 393.398 +
 393.399 +  /* Following limits must be consistent with */
 393.400 +  /* FT_Outline.{n_contours,n_points}         */
 393.401 +#define FT_OUTLINE_CONTOURS_MAX  SHRT_MAX
 393.402 +#define FT_OUTLINE_POINTS_MAX    SHRT_MAX
 393.403 +
 393.404 +
 393.405 +  /*************************************************************************/
 393.406 +  /*                                                                       */
 393.407 +  /* <Enum>                                                                */
 393.408 +  /*    FT_OUTLINE_FLAGS                                                   */
 393.409 +  /*                                                                       */
 393.410 +  /* <Description>                                                         */
 393.411 +  /*    A list of bit-field constants use for the flags in an outline's    */
 393.412 +  /*    `flags' field.                                                     */
 393.413 +  /*                                                                       */
 393.414 +  /* <Values>                                                              */
 393.415 +  /*    FT_OUTLINE_NONE ::                                                 */
 393.416 +  /*      Value~0 is reserved.                                             */
 393.417 +  /*                                                                       */
 393.418 +  /*    FT_OUTLINE_OWNER ::                                                */
 393.419 +  /*      If set, this flag indicates that the outline's field arrays      */
 393.420 +  /*      (i.e., `points', `flags', and `contours') are `owned' by the     */
 393.421 +  /*      outline object, and should thus be freed when it is destroyed.   */
 393.422 +  /*                                                                       */
 393.423 +  /*    FT_OUTLINE_EVEN_ODD_FILL ::                                        */
 393.424 +  /*      By default, outlines are filled using the non-zero winding rule. */
 393.425 +  /*      If set to 1, the outline will be filled using the even-odd fill  */
 393.426 +  /*      rule (only works with the smooth rasterizer).                    */
 393.427 +  /*                                                                       */
 393.428 +  /*    FT_OUTLINE_REVERSE_FILL ::                                         */
 393.429 +  /*      By default, outside contours of an outline are oriented in       */
 393.430 +  /*      clock-wise direction, as defined in the TrueType specification.  */
 393.431 +  /*      This flag is set if the outline uses the opposite direction      */
 393.432 +  /*      (typically for Type~1 fonts).  This flag is ignored by the scan  */
 393.433 +  /*      converter.                                                       */
 393.434 +  /*                                                                       */
 393.435 +  /*    FT_OUTLINE_IGNORE_DROPOUTS ::                                      */
 393.436 +  /*      By default, the scan converter will try to detect drop-outs in   */
 393.437 +  /*      an outline and correct the glyph bitmap to ensure consistent     */
 393.438 +  /*      shape continuity.  If set, this flag hints the scan-line         */
 393.439 +  /*      converter to ignore such cases.  See below for more information. */
 393.440 +  /*                                                                       */
 393.441 +  /*    FT_OUTLINE_SMART_DROPOUTS ::                                       */
 393.442 +  /*      Select smart dropout control.  If unset, use simple dropout      */
 393.443 +  /*      control.  Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.  See    */
 393.444 +  /*      below for more information.                                      */
 393.445 +  /*                                                                       */
 393.446 +  /*    FT_OUTLINE_INCLUDE_STUBS ::                                        */
 393.447 +  /*      If set, turn pixels on for `stubs', otherwise exclude them.      */
 393.448 +  /*      Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.  See below for    */
 393.449 +  /*      more information.                                                */
 393.450 +  /*                                                                       */
 393.451 +  /*    FT_OUTLINE_HIGH_PRECISION ::                                       */
 393.452 +  /*      This flag indicates that the scan-line converter should try to   */
 393.453 +  /*      convert this outline to bitmaps with the highest possible        */
 393.454 +  /*      quality.  It is typically set for small character sizes.  Note   */
 393.455 +  /*      that this is only a hint that might be completely ignored by a   */
 393.456 +  /*      given scan-converter.                                            */
 393.457 +  /*                                                                       */
 393.458 +  /*    FT_OUTLINE_SINGLE_PASS ::                                          */
 393.459 +  /*      This flag is set to force a given scan-converter to only use a   */
 393.460 +  /*      single pass over the outline to render a bitmap glyph image.     */
 393.461 +  /*      Normally, it is set for very large character sizes.  It is only  */
 393.462 +  /*      a hint that might be completely ignored by a given               */
 393.463 +  /*      scan-converter.                                                  */
 393.464 +  /*                                                                       */
 393.465 +  /* <Note>                                                                */
 393.466 +  /*    The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */
 393.467 +  /*    and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth            */
 393.468 +  /*    rasterizer.                                                        */
 393.469 +  /*                                                                       */
 393.470 +  /*    There exists a second mechanism to pass the drop-out mode to the   */
 393.471 +  /*    B/W rasterizer; see the `tags' field in @FT_Outline.               */
 393.472 +  /*                                                                       */
 393.473 +  /*    Please refer to the description of the `SCANTYPE' instruction in   */
 393.474 +  /*    the OpenType specification (in file `ttinst1.doc') how simple      */
 393.475 +  /*    drop-outs, smart drop-outs, and stubs are defined.                 */
 393.476 +  /*                                                                       */
 393.477 +#define FT_OUTLINE_NONE             0x0
 393.478 +#define FT_OUTLINE_OWNER            0x1
 393.479 +#define FT_OUTLINE_EVEN_ODD_FILL    0x2
 393.480 +#define FT_OUTLINE_REVERSE_FILL     0x4
 393.481 +#define FT_OUTLINE_IGNORE_DROPOUTS  0x8
 393.482 +#define FT_OUTLINE_SMART_DROPOUTS   0x10
 393.483 +#define FT_OUTLINE_INCLUDE_STUBS    0x20
 393.484 +
 393.485 +#define FT_OUTLINE_HIGH_PRECISION   0x100
 393.486 +#define FT_OUTLINE_SINGLE_PASS      0x200
 393.487 +
 393.488 +
 393.489 + /*************************************************************************
 393.490 +  *
 393.491 +  * @enum:
 393.492 +  *   ft_outline_flags
 393.493 +  *
 393.494 +  * @description:
 393.495 +  *   These constants are deprecated.  Please use the corresponding
 393.496 +  *   @FT_OUTLINE_FLAGS values.
 393.497 +  *
 393.498 +  * @values:
 393.499 +  *   ft_outline_none            :: See @FT_OUTLINE_NONE.
 393.500 +  *   ft_outline_owner           :: See @FT_OUTLINE_OWNER.
 393.501 +  *   ft_outline_even_odd_fill   :: See @FT_OUTLINE_EVEN_ODD_FILL.
 393.502 +  *   ft_outline_reverse_fill    :: See @FT_OUTLINE_REVERSE_FILL.
 393.503 +  *   ft_outline_ignore_dropouts :: See @FT_OUTLINE_IGNORE_DROPOUTS.
 393.504 +  *   ft_outline_high_precision  :: See @FT_OUTLINE_HIGH_PRECISION.
 393.505 +  *   ft_outline_single_pass     :: See @FT_OUTLINE_SINGLE_PASS.
 393.506 +  */
 393.507 +#define ft_outline_none             FT_OUTLINE_NONE
 393.508 +#define ft_outline_owner            FT_OUTLINE_OWNER
 393.509 +#define ft_outline_even_odd_fill    FT_OUTLINE_EVEN_ODD_FILL
 393.510 +#define ft_outline_reverse_fill     FT_OUTLINE_REVERSE_FILL
 393.511 +#define ft_outline_ignore_dropouts  FT_OUTLINE_IGNORE_DROPOUTS
 393.512 +#define ft_outline_high_precision   FT_OUTLINE_HIGH_PRECISION
 393.513 +#define ft_outline_single_pass      FT_OUTLINE_SINGLE_PASS
 393.514 +
 393.515 +  /* */
 393.516 +
 393.517 +#define FT_CURVE_TAG( flag )  ( flag & 3 )
 393.518 +
 393.519 +#define FT_CURVE_TAG_ON            1
 393.520 +#define FT_CURVE_TAG_CONIC         0
 393.521 +#define FT_CURVE_TAG_CUBIC         2
 393.522 +
 393.523 +#define FT_CURVE_TAG_HAS_SCANMODE  4
 393.524 +
 393.525 +#define FT_CURVE_TAG_TOUCH_X       8  /* reserved for the TrueType hinter */
 393.526 +#define FT_CURVE_TAG_TOUCH_Y      16  /* reserved for the TrueType hinter */
 393.527 +
 393.528 +#define FT_CURVE_TAG_TOUCH_BOTH    ( FT_CURVE_TAG_TOUCH_X | \
 393.529 +                                     FT_CURVE_TAG_TOUCH_Y )
 393.530 +
 393.531 +#define FT_Curve_Tag_On       FT_CURVE_TAG_ON
 393.532 +#define FT_Curve_Tag_Conic    FT_CURVE_TAG_CONIC
 393.533 +#define FT_Curve_Tag_Cubic    FT_CURVE_TAG_CUBIC
 393.534 +#define FT_Curve_Tag_Touch_X  FT_CURVE_TAG_TOUCH_X
 393.535 +#define FT_Curve_Tag_Touch_Y  FT_CURVE_TAG_TOUCH_Y
 393.536 +
 393.537 +
 393.538 +  /*************************************************************************/
 393.539 +  /*                                                                       */
 393.540 +  /* <FuncType>                                                            */
 393.541 +  /*    FT_Outline_MoveToFunc                                              */
 393.542 +  /*                                                                       */
 393.543 +  /* <Description>                                                         */
 393.544 +  /*    A function pointer type used to describe the signature of a `move  */
 393.545 +  /*    to' function during outline walking/decomposition.                 */
 393.546 +  /*                                                                       */
 393.547 +  /*    A `move to' is emitted to start a new contour in an outline.       */
 393.548 +  /*                                                                       */
 393.549 +  /* <Input>                                                               */
 393.550 +  /*    to   :: A pointer to the target point of the `move to'.            */
 393.551 +  /*                                                                       */
 393.552 +  /*    user :: A typeless pointer which is passed from the caller of the  */
 393.553 +  /*            decomposition function.                                    */
 393.554 +  /*                                                                       */
 393.555 +  /* <Return>                                                              */
 393.556 +  /*    Error code.  0~means success.                                      */
 393.557 +  /*                                                                       */
 393.558 +  typedef int
 393.559 +  (*FT_Outline_MoveToFunc)( const FT_Vector*  to,
 393.560 +                            void*             user );
 393.561 +
 393.562 +#define FT_Outline_MoveTo_Func  FT_Outline_MoveToFunc
 393.563 +
 393.564 +
 393.565 +  /*************************************************************************/
 393.566 +  /*                                                                       */
 393.567 +  /* <FuncType>                                                            */
 393.568 +  /*    FT_Outline_LineToFunc                                              */
 393.569 +  /*                                                                       */
 393.570 +  /* <Description>                                                         */
 393.571 +  /*    A function pointer type used to describe the signature of a `line  */
 393.572 +  /*    to' function during outline walking/decomposition.                 */
 393.573 +  /*                                                                       */
 393.574 +  /*    A `line to' is emitted to indicate a segment in the outline.       */
 393.575 +  /*                                                                       */
 393.576 +  /* <Input>                                                               */
 393.577 +  /*    to   :: A pointer to the target point of the `line to'.            */
 393.578 +  /*                                                                       */
 393.579 +  /*    user :: A typeless pointer which is passed from the caller of the  */
 393.580 +  /*            decomposition function.                                    */
 393.581 +  /*                                                                       */
 393.582 +  /* <Return>                                                              */
 393.583 +  /*    Error code.  0~means success.                                      */
 393.584 +  /*                                                                       */
 393.585 +  typedef int
 393.586 +  (*FT_Outline_LineToFunc)( const FT_Vector*  to,
 393.587 +                            void*             user );
 393.588 +
 393.589 +#define FT_Outline_LineTo_Func  FT_Outline_LineToFunc
 393.590 +
 393.591 +
 393.592 +  /*************************************************************************/
 393.593 +  /*                                                                       */
 393.594 +  /* <FuncType>                                                            */
 393.595 +  /*    FT_Outline_ConicToFunc                                             */
 393.596 +  /*                                                                       */
 393.597 +  /* <Description>                                                         */
 393.598 +  /*    A function pointer type used to describe the signature of a `conic */
 393.599 +  /*    to' function during outline walking or decomposition.              */
 393.600 +  /*                                                                       */
 393.601 +  /*    A `conic to' is emitted to indicate a second-order Bézier arc in   */
 393.602 +  /*    the outline.                                                       */
 393.603 +  /*                                                                       */
 393.604 +  /* <Input>                                                               */
 393.605 +  /*    control :: An intermediate control point between the last position */
 393.606 +  /*               and the new target in `to'.                             */
 393.607 +  /*                                                                       */
 393.608 +  /*    to      :: A pointer to the target end point of the conic arc.     */
 393.609 +  /*                                                                       */
 393.610 +  /*    user    :: A typeless pointer which is passed from the caller of   */
 393.611 +  /*               the decomposition function.                             */
 393.612 +  /*                                                                       */
 393.613 +  /* <Return>                                                              */
 393.614 +  /*    Error code.  0~means success.                                      */
 393.615 +  /*                                                                       */
 393.616 +  typedef int
 393.617 +  (*FT_Outline_ConicToFunc)( const FT_Vector*  control,
 393.618 +                             const FT_Vector*  to,
 393.619 +                             void*             user );
 393.620 +
 393.621 +#define FT_Outline_ConicTo_Func  FT_Outline_ConicToFunc
 393.622 +
 393.623 +
 393.624 +  /*************************************************************************/
 393.625 +  /*                                                                       */
 393.626 +  /* <FuncType>                                                            */
 393.627 +  /*    FT_Outline_CubicToFunc                                             */
 393.628 +  /*                                                                       */
 393.629 +  /* <Description>                                                         */
 393.630 +  /*    A function pointer type used to describe the signature of a `cubic */
 393.631 +  /*    to' function during outline walking or decomposition.              */
 393.632 +  /*                                                                       */
 393.633 +  /*    A `cubic to' is emitted to indicate a third-order Bézier arc.      */
 393.634 +  /*                                                                       */
 393.635 +  /* <Input>                                                               */
 393.636 +  /*    control1 :: A pointer to the first Bézier control point.           */
 393.637 +  /*                                                                       */
 393.638 +  /*    control2 :: A pointer to the second Bézier control point.          */
 393.639 +  /*                                                                       */
 393.640 +  /*    to       :: A pointer to the target end point.                     */
 393.641 +  /*                                                                       */
 393.642 +  /*    user     :: A typeless pointer which is passed from the caller of  */
 393.643 +  /*                the decomposition function.                            */
 393.644 +  /*                                                                       */
 393.645 +  /* <Return>                                                              */
 393.646 +  /*    Error code.  0~means success.                                      */
 393.647 +  /*                                                                       */
 393.648 +  typedef int
 393.649 +  (*FT_Outline_CubicToFunc)( const FT_Vector*  control1,
 393.650 +                             const FT_Vector*  control2,
 393.651 +                             const FT_Vector*  to,
 393.652 +                             void*             user );
 393.653 +
 393.654 +#define FT_Outline_CubicTo_Func  FT_Outline_CubicToFunc
 393.655 +
 393.656 +
 393.657 +  /*************************************************************************/
 393.658 +  /*                                                                       */
 393.659 +  /* <Struct>                                                              */
 393.660 +  /*    FT_Outline_Funcs                                                   */
 393.661 +  /*                                                                       */
 393.662 +  /* <Description>                                                         */
 393.663 +  /*    A structure to hold various function pointers used during outline  */
 393.664 +  /*    decomposition in order to emit segments, conic, and cubic Béziers. */
 393.665 +  /*                                                                       */
 393.666 +  /* <Fields>                                                              */
 393.667 +  /*    move_to  :: The `move to' emitter.                                 */
 393.668 +  /*                                                                       */
 393.669 +  /*    line_to  :: The segment emitter.                                   */
 393.670 +  /*                                                                       */
 393.671 +  /*    conic_to :: The second-order Bézier arc emitter.                   */
 393.672 +  /*                                                                       */
 393.673 +  /*    cubic_to :: The third-order Bézier arc emitter.                    */
 393.674 +  /*                                                                       */
 393.675 +  /*    shift    :: The shift that is applied to coordinates before they   */
 393.676 +  /*                are sent to the emitter.                               */
 393.677 +  /*                                                                       */
 393.678 +  /*    delta    :: The delta that is applied to coordinates before they   */
 393.679 +  /*                are sent to the emitter, but after the shift.          */
 393.680 +  /*                                                                       */
 393.681 +  /* <Note>                                                                */
 393.682 +  /*    The point coordinates sent to the emitters are the transformed     */
 393.683 +  /*    version of the original coordinates (this is important for high    */
 393.684 +  /*    accuracy during scan-conversion).  The transformation is simple:   */
 393.685 +  /*                                                                       */
 393.686 +  /*    {                                                                  */
 393.687 +  /*      x' = (x << shift) - delta                                        */
 393.688 +  /*      y' = (x << shift) - delta                                        */
 393.689 +  /*    }                                                                  */
 393.690 +  /*                                                                       */
 393.691 +  /*    Set the values of `shift' and `delta' to~0 to get the original     */
 393.692 +  /*    point coordinates.                                                 */
 393.693 +  /*                                                                       */
 393.694 +  typedef struct  FT_Outline_Funcs_
 393.695 +  {
 393.696 +    FT_Outline_MoveToFunc   move_to;
 393.697 +    FT_Outline_LineToFunc   line_to;
 393.698 +    FT_Outline_ConicToFunc  conic_to;
 393.699 +    FT_Outline_CubicToFunc  cubic_to;
 393.700 +
 393.701 +    int                     shift;
 393.702 +    FT_Pos                  delta;
 393.703 +
 393.704 +  } FT_Outline_Funcs;
 393.705 +
 393.706 +
 393.707 +  /*************************************************************************/
 393.708 +  /*                                                                       */
 393.709 +  /* <Section>                                                             */
 393.710 +  /*    basic_types                                                        */
 393.711 +  /*                                                                       */
 393.712 +  /*************************************************************************/
 393.713 +
 393.714 +
 393.715 +  /*************************************************************************/
 393.716 +  /*                                                                       */
 393.717 +  /* <Macro>                                                               */
 393.718 +  /*    FT_IMAGE_TAG                                                       */
 393.719 +  /*                                                                       */
 393.720 +  /* <Description>                                                         */
 393.721 +  /*    This macro converts four-letter tags to an unsigned long type.     */
 393.722 +  /*                                                                       */
 393.723 +  /* <Note>                                                                */
 393.724 +  /*    Since many 16-bit compilers don't like 32-bit enumerations, you    */
 393.725 +  /*    should redefine this macro in case of problems to something like   */
 393.726 +  /*    this:                                                              */
 393.727 +  /*                                                                       */
 393.728 +  /*    {                                                                  */
 393.729 +  /*      #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 )  value         */
 393.730 +  /*    }                                                                  */
 393.731 +  /*                                                                       */
 393.732 +  /*    to get a simple enumeration without assigning special numbers.     */
 393.733 +  /*                                                                       */
 393.734 +#ifndef FT_IMAGE_TAG
 393.735 +#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 )  \
 393.736 +          value = ( ( (unsigned long)_x1 << 24 ) | \
 393.737 +                    ( (unsigned long)_x2 << 16 ) | \
 393.738 +                    ( (unsigned long)_x3 << 8  ) | \
 393.739 +                      (unsigned long)_x4         )
 393.740 +#endif /* FT_IMAGE_TAG */
 393.741 +
 393.742 +
 393.743 +  /*************************************************************************/
 393.744 +  /*                                                                       */
 393.745 +  /* <Enum>                                                                */
 393.746 +  /*    FT_Glyph_Format                                                    */
 393.747 +  /*                                                                       */
 393.748 +  /* <Description>                                                         */
 393.749 +  /*    An enumeration type used to describe the format of a given glyph   */
 393.750 +  /*    image.  Note that this version of FreeType only supports two image */
 393.751 +  /*    formats, even though future font drivers will be able to register  */
 393.752 +  /*    their own format.                                                  */
 393.753 +  /*                                                                       */
 393.754 +  /* <Values>                                                              */
 393.755 +  /*    FT_GLYPH_FORMAT_NONE ::                                            */
 393.756 +  /*      The value~0 is reserved.                                         */
 393.757 +  /*                                                                       */
 393.758 +  /*    FT_GLYPH_FORMAT_COMPOSITE ::                                       */
 393.759 +  /*      The glyph image is a composite of several other images.  This    */
 393.760 +  /*      format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to   */
 393.761 +  /*      report compound glyphs (like accented characters).               */
 393.762 +  /*                                                                       */
 393.763 +  /*    FT_GLYPH_FORMAT_BITMAP ::                                          */
 393.764 +  /*      The glyph image is a bitmap, and can be described as an          */
 393.765 +  /*      @FT_Bitmap.  You generally need to access the `bitmap' field of  */
 393.766 +  /*      the @FT_GlyphSlotRec structure to read it.                       */
 393.767 +  /*                                                                       */
 393.768 +  /*    FT_GLYPH_FORMAT_OUTLINE ::                                         */
 393.769 +  /*      The glyph image is a vectorial outline made of line segments     */
 393.770 +  /*      and Bézier arcs; it can be described as an @FT_Outline; you      */
 393.771 +  /*      generally want to access the `outline' field of the              */
 393.772 +  /*      @FT_GlyphSlotRec structure to read it.                           */
 393.773 +  /*                                                                       */
 393.774 +  /*    FT_GLYPH_FORMAT_PLOTTER ::                                         */
 393.775 +  /*      The glyph image is a vectorial path with no inside and outside   */
 393.776 +  /*      contours.  Some Type~1 fonts, like those in the Hershey family,  */
 393.777 +  /*      contain glyphs in this format.  These are described as           */
 393.778 +  /*      @FT_Outline, but FreeType isn't currently capable of rendering   */
 393.779 +  /*      them correctly.                                                  */
 393.780 +  /*                                                                       */
 393.781 +  typedef enum  FT_Glyph_Format_
 393.782 +  {
 393.783 +    FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ),
 393.784 +
 393.785 +    FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ),
 393.786 +    FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP,    'b', 'i', 't', 's' ),
 393.787 +    FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE,   'o', 'u', 't', 'l' ),
 393.788 +    FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER,   'p', 'l', 'o', 't' )
 393.789 +
 393.790 +  } FT_Glyph_Format;
 393.791 +
 393.792 +
 393.793 +  /*************************************************************************/
 393.794 +  /*                                                                       */
 393.795 +  /* <Enum>                                                                */
 393.796 +  /*    ft_glyph_format_xxx                                                */
 393.797 +  /*                                                                       */
 393.798 +  /* <Description>                                                         */
 393.799 +  /*    A list of deprecated constants.  Use the corresponding             */
 393.800 +  /*    @FT_Glyph_Format values instead.                                   */
 393.801 +  /*                                                                       */
 393.802 +  /* <Values>                                                              */
 393.803 +  /*    ft_glyph_format_none      :: See @FT_GLYPH_FORMAT_NONE.            */
 393.804 +  /*    ft_glyph_format_composite :: See @FT_GLYPH_FORMAT_COMPOSITE.       */
 393.805 +  /*    ft_glyph_format_bitmap    :: See @FT_GLYPH_FORMAT_BITMAP.          */
 393.806 +  /*    ft_glyph_format_outline   :: See @FT_GLYPH_FORMAT_OUTLINE.         */
 393.807 +  /*    ft_glyph_format_plotter   :: See @FT_GLYPH_FORMAT_PLOTTER.         */
 393.808 +  /*                                                                       */
 393.809 +#define ft_glyph_format_none       FT_GLYPH_FORMAT_NONE
 393.810 +#define ft_glyph_format_composite  FT_GLYPH_FORMAT_COMPOSITE
 393.811 +#define ft_glyph_format_bitmap     FT_GLYPH_FORMAT_BITMAP
 393.812 +#define ft_glyph_format_outline    FT_GLYPH_FORMAT_OUTLINE
 393.813 +#define ft_glyph_format_plotter    FT_GLYPH_FORMAT_PLOTTER
 393.814 +
 393.815 +
 393.816 +  /*************************************************************************/
 393.817 +  /*************************************************************************/
 393.818 +  /*************************************************************************/
 393.819 +  /*****                                                               *****/
 393.820 +  /*****            R A S T E R   D E F I N I T I O N S                *****/
 393.821 +  /*****                                                               *****/
 393.822 +  /*************************************************************************/
 393.823 +  /*************************************************************************/
 393.824 +  /*************************************************************************/
 393.825 +
 393.826 +
 393.827 +  /*************************************************************************/
 393.828 +  /*                                                                       */
 393.829 +  /* A raster is a scan converter, in charge of rendering an outline into  */
 393.830 +  /* a a bitmap.  This section contains the public API for rasters.        */
 393.831 +  /*                                                                       */
 393.832 +  /* Note that in FreeType 2, all rasters are now encapsulated within      */
 393.833 +  /* specific modules called `renderers'.  See `freetype/ftrender.h' for   */
 393.834 +  /* more details on renderers.                                            */
 393.835 +  /*                                                                       */
 393.836 +  /*************************************************************************/
 393.837 +
 393.838 +
 393.839 +  /*************************************************************************/
 393.840 +  /*                                                                       */
 393.841 +  /* <Section>                                                             */
 393.842 +  /*    raster                                                             */
 393.843 +  /*                                                                       */
 393.844 +  /* <Title>                                                               */
 393.845 +  /*    Scanline Converter                                                 */
 393.846 +  /*                                                                       */
 393.847 +  /* <Abstract>                                                            */
 393.848 +  /*    How vectorial outlines are converted into bitmaps and pixmaps.     */
 393.849 +  /*                                                                       */
 393.850 +  /* <Description>                                                         */
 393.851 +  /*    This section contains technical definitions.                       */
 393.852 +  /*                                                                       */
 393.853 +  /*************************************************************************/
 393.854 +
 393.855 +
 393.856 +  /*************************************************************************/
 393.857 +  /*                                                                       */
 393.858 +  /* <Type>                                                                */
 393.859 +  /*    FT_Raster                                                          */
 393.860 +  /*                                                                       */
 393.861 +  /* <Description>                                                         */
 393.862 +  /*    A handle (pointer) to a raster object.  Each object can be used    */
 393.863 +  /*    independently to convert an outline into a bitmap or pixmap.       */
 393.864 +  /*                                                                       */
 393.865 +  typedef struct FT_RasterRec_*  FT_Raster;
 393.866 +
 393.867 +
 393.868 +  /*************************************************************************/
 393.869 +  /*                                                                       */
 393.870 +  /* <Struct>                                                              */
 393.871 +  /*    FT_Span                                                            */
 393.872 +  /*                                                                       */
 393.873 +  /* <Description>                                                         */
 393.874 +  /*    A structure used to model a single span of gray (or black) pixels  */
 393.875 +  /*    when rendering a monochrome or anti-aliased bitmap.                */
 393.876 +  /*                                                                       */
 393.877 +  /* <Fields>                                                              */
 393.878 +  /*    x        :: The span's horizontal start position.                  */
 393.879 +  /*                                                                       */
 393.880 +  /*    len      :: The span's length in pixels.                           */
 393.881 +  /*                                                                       */
 393.882 +  /*    coverage :: The span color/coverage, ranging from 0 (background)   */
 393.883 +  /*                to 255 (foreground).  Only used for anti-aliased       */
 393.884 +  /*                rendering.                                             */
 393.885 +  /*                                                                       */
 393.886 +  /* <Note>                                                                */
 393.887 +  /*    This structure is used by the span drawing callback type named     */
 393.888 +  /*    @FT_SpanFunc which takes the y~coordinate of the span as a         */
 393.889 +  /*    a parameter.                                                       */
 393.890 +  /*                                                                       */
 393.891 +  /*    The coverage value is always between 0 and 255.  If you want less  */
 393.892 +  /*    gray values, the callback function has to reduce them.             */
 393.893 +  /*                                                                       */
 393.894 +  typedef struct  FT_Span_
 393.895 +  {
 393.896 +    short           x;
 393.897 +    unsigned short  len;
 393.898 +    unsigned char   coverage;
 393.899 +
 393.900 +  } FT_Span;
 393.901 +
 393.902 +
 393.903 +  /*************************************************************************/
 393.904 +  /*                                                                       */
 393.905 +  /* <FuncType>                                                            */
 393.906 +  /*    FT_SpanFunc                                                        */
 393.907 +  /*                                                                       */
 393.908 +  /* <Description>                                                         */
 393.909 +  /*    A function used as a call-back by the anti-aliased renderer in     */
 393.910 +  /*    order to let client applications draw themselves the gray pixel    */
 393.911 +  /*    spans on each scan line.                                           */
 393.912 +  /*                                                                       */
 393.913 +  /* <Input>                                                               */
 393.914 +  /*    y     :: The scanline's y~coordinate.                              */
 393.915 +  /*                                                                       */
 393.916 +  /*    count :: The number of spans to draw on this scanline.             */
 393.917 +  /*                                                                       */
 393.918 +  /*    spans :: A table of `count' spans to draw on the scanline.         */
 393.919 +  /*                                                                       */
 393.920 +  /*    user  :: User-supplied data that is passed to the callback.        */
 393.921 +  /*                                                                       */
 393.922 +  /* <Note>                                                                */
 393.923 +  /*    This callback allows client applications to directly render the    */
 393.924 +  /*    gray spans of the anti-aliased bitmap to any kind of surfaces.     */
 393.925 +  /*                                                                       */
 393.926 +  /*    This can be used to write anti-aliased outlines directly to a      */
 393.927 +  /*    given background bitmap, and even perform translucency.            */
 393.928 +  /*                                                                       */
 393.929 +  /*    Note that the `count' field cannot be greater than a fixed value   */
 393.930 +  /*    defined by the `FT_MAX_GRAY_SPANS' configuration macro in          */
 393.931 +  /*    `ftoption.h'.  By default, this value is set to~32, which means    */
 393.932 +  /*    that if there are more than 32~spans on a given scanline, the      */
 393.933 +  /*    callback is called several times with the same `y' parameter in    */
 393.934 +  /*    order to draw all callbacks.                                       */
 393.935 +  /*                                                                       */
 393.936 +  /*    Otherwise, the callback is only called once per scan-line, and     */
 393.937 +  /*    only for those scanlines that do have `gray' pixels on them.       */
 393.938 +  /*                                                                       */
 393.939 +  typedef void
 393.940 +  (*FT_SpanFunc)( int             y,
 393.941 +                  int             count,
 393.942 +                  const FT_Span*  spans,
 393.943 +                  void*           user );
 393.944 +
 393.945 +#define FT_Raster_Span_Func  FT_SpanFunc
 393.946 +
 393.947 +
 393.948 +  /*************************************************************************/
 393.949 +  /*                                                                       */
 393.950 +  /* <FuncType>                                                            */
 393.951 +  /*    FT_Raster_BitTest_Func                                             */
 393.952 +  /*                                                                       */
 393.953 +  /* <Description>                                                         */
 393.954 +  /*    THIS TYPE IS DEPRECATED.  DO NOT USE IT.                           */
 393.955 +  /*                                                                       */
 393.956 +  /*    A function used as a call-back by the monochrome scan-converter    */
 393.957 +  /*    to test whether a given target pixel is already set to the drawing */
 393.958 +  /*    `color'.  These tests are crucial to implement drop-out control    */
 393.959 +  /*    per-se the TrueType spec.                                          */
 393.960 +  /*                                                                       */
 393.961 +  /* <Input>                                                               */
 393.962 +  /*    y     :: The pixel's y~coordinate.                                 */
 393.963 +  /*                                                                       */
 393.964 +  /*    x     :: The pixel's x~coordinate.                                 */
 393.965 +  /*                                                                       */
 393.966 +  /*    user  :: User-supplied data that is passed to the callback.        */
 393.967 +  /*                                                                       */
 393.968 +  /* <Return>                                                              */
 393.969 +  /*   1~if the pixel is `set', 0~otherwise.                               */
 393.970 +  /*                                                                       */
 393.971 +  typedef int
 393.972 +  (*FT_Raster_BitTest_Func)( int    y,
 393.973 +                             int    x,
 393.974 +                             void*  user );
 393.975 +
 393.976 +
 393.977 +  /*************************************************************************/
 393.978 +  /*                                                                       */
 393.979 +  /* <FuncType>                                                            */
 393.980 +  /*    FT_Raster_BitSet_Func                                              */
 393.981 +  /*                                                                       */
 393.982 +  /* <Description>                                                         */
 393.983 +  /*    THIS TYPE IS DEPRECATED.  DO NOT USE IT.                           */
 393.984 +  /*                                                                       */
 393.985 +  /*    A function used as a call-back by the monochrome scan-converter    */
 393.986 +  /*    to set an individual target pixel.  This is crucial to implement   */
 393.987 +  /*    drop-out control according to the TrueType specification.          */
 393.988 +  /*                                                                       */
 393.989 +  /* <Input>                                                               */
 393.990 +  /*    y     :: The pixel's y~coordinate.                                 */
 393.991 +  /*                                                                       */
 393.992 +  /*    x     :: The pixel's x~coordinate.                                 */
 393.993 +  /*                                                                       */
 393.994 +  /*    user  :: User-supplied data that is passed to the callback.        */
 393.995 +  /*                                                                       */
 393.996 +  /* <Return>                                                              */
 393.997 +  /*    1~if the pixel is `set', 0~otherwise.                              */
 393.998 +  /*                                                                       */
 393.999 +  typedef void
393.1000 +  (*FT_Raster_BitSet_Func)( int    y,
393.1001 +                            int    x,
393.1002 +                            void*  user );
393.1003 +
393.1004 +
393.1005 +  /*************************************************************************/
393.1006 +  /*                                                                       */
393.1007 +  /* <Enum>                                                                */
393.1008 +  /*    FT_RASTER_FLAG_XXX                                                 */
393.1009 +  /*                                                                       */
393.1010 +  /* <Description>                                                         */
393.1011 +  /*    A list of bit flag constants as used in the `flags' field of a     */
393.1012 +  /*    @FT_Raster_Params structure.                                       */
393.1013 +  /*                                                                       */
393.1014 +  /* <Values>                                                              */
393.1015 +  /*    FT_RASTER_FLAG_DEFAULT :: This value is 0.                         */
393.1016 +  /*                                                                       */
393.1017 +  /*    FT_RASTER_FLAG_AA      :: This flag is set to indicate that an     */
393.1018 +  /*                              anti-aliased glyph image should be       */
393.1019 +  /*                              generated.  Otherwise, it will be        */
393.1020 +  /*                              monochrome (1-bit).                      */
393.1021 +  /*                                                                       */
393.1022 +  /*    FT_RASTER_FLAG_DIRECT  :: This flag is set to indicate direct      */
393.1023 +  /*                              rendering.  In this mode, client         */
393.1024 +  /*                              applications must provide their own span */
393.1025 +  /*                              callback.  This lets them directly       */
393.1026 +  /*                              draw or compose over an existing bitmap. */
393.1027 +  /*                              If this bit is not set, the target       */
393.1028 +  /*                              pixmap's buffer _must_ be zeroed before  */
393.1029 +  /*                              rendering.                               */
393.1030 +  /*                                                                       */
393.1031 +  /*                              Note that for now, direct rendering is   */
393.1032 +  /*                              only possible with anti-aliased glyphs.  */
393.1033 +  /*                                                                       */
393.1034 +  /*    FT_RASTER_FLAG_CLIP    :: This flag is only used in direct         */
393.1035 +  /*                              rendering mode.  If set, the output will */
393.1036 +  /*                              be clipped to a box specified in the     */
393.1037 +  /*                              `clip_box' field of the                  */
393.1038 +  /*                              @FT_Raster_Params structure.             */
393.1039 +  /*                                                                       */
393.1040 +  /*                              Note that by default, the glyph bitmap   */
393.1041 +  /*                              is clipped to the target pixmap, except  */
393.1042 +  /*                              in direct rendering mode where all spans */
393.1043 +  /*                              are generated if no clipping box is set. */
393.1044 +  /*                                                                       */
393.1045 +#define FT_RASTER_FLAG_DEFAULT  0x0
393.1046 +#define FT_RASTER_FLAG_AA       0x1
393.1047 +#define FT_RASTER_FLAG_DIRECT   0x2
393.1048 +#define FT_RASTER_FLAG_CLIP     0x4
393.1049 +
393.1050 +  /* deprecated */
393.1051 +#define ft_raster_flag_default  FT_RASTER_FLAG_DEFAULT
393.1052 +#define ft_raster_flag_aa       FT_RASTER_FLAG_AA
393.1053 +#define ft_raster_flag_direct   FT_RASTER_FLAG_DIRECT
393.1054 +#define ft_raster_flag_clip     FT_RASTER_FLAG_CLIP
393.1055 +
393.1056 +
393.1057 +  /*************************************************************************/
393.1058 +  /*                                                                       */
393.1059 +  /* <Struct>                                                              */
393.1060 +  /*    FT_Raster_Params                                                   */
393.1061 +  /*                                                                       */
393.1062 +  /* <Description>                                                         */
393.1063 +  /*    A structure to hold the arguments used by a raster's render        */
393.1064 +  /*    function.                                                          */
393.1065 +  /*                                                                       */
393.1066 +  /* <Fields>                                                              */
393.1067 +  /*    target      :: The target bitmap.                                  */
393.1068 +  /*                                                                       */
393.1069 +  /*    source      :: A pointer to the source glyph image (e.g., an       */
393.1070 +  /*                   @FT_Outline).                                       */
393.1071 +  /*                                                                       */
393.1072 +  /*    flags       :: The rendering flags.                                */
393.1073 +  /*                                                                       */
393.1074 +  /*    gray_spans  :: The gray span drawing callback.                     */
393.1075 +  /*                                                                       */
393.1076 +  /*    black_spans :: The black span drawing callback.  UNIMPLEMENTED!    */
393.1077 +  /*                                                                       */
393.1078 +  /*    bit_test    :: The bit test callback.  UNIMPLEMENTED!              */
393.1079 +  /*                                                                       */
393.1080 +  /*    bit_set     :: The bit set callback.  UNIMPLEMENTED!               */
393.1081 +  /*                                                                       */
393.1082 +  /*    user        :: User-supplied data that is passed to each drawing   */
393.1083 +  /*                   callback.                                           */
393.1084 +  /*                                                                       */
393.1085 +  /*    clip_box    :: An optional clipping box.  It is only used in       */
393.1086 +  /*                   direct rendering mode.  Note that coordinates here  */
393.1087 +  /*                   should be expressed in _integer_ pixels (and not in */
393.1088 +  /*                   26.6 fixed-point units).                            */
393.1089 +  /*                                                                       */
393.1090 +  /* <Note>                                                                */
393.1091 +  /*    An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA    */
393.1092 +  /*    bit flag is set in the `flags' field, otherwise a monochrome       */
393.1093 +  /*    bitmap is generated.                                               */
393.1094 +  /*                                                                       */
393.1095 +  /*    If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the      */
393.1096 +  /*    raster will call the `gray_spans' callback to draw gray pixel      */
393.1097 +  /*    spans, in the case of an aa glyph bitmap, it will call             */
393.1098 +  /*    `black_spans', and `bit_test' and `bit_set' in the case of a       */
393.1099 +  /*    monochrome bitmap.  This allows direct composition over a          */
393.1100 +  /*    pre-existing bitmap through user-provided callbacks to perform the */
393.1101 +  /*    span drawing/composition.                                          */
393.1102 +  /*                                                                       */
393.1103 +  /*    Note that the `bit_test' and `bit_set' callbacks are required when */
393.1104 +  /*    rendering a monochrome bitmap, as they are crucial to implement    */
393.1105 +  /*    correct drop-out control as defined in the TrueType specification. */
393.1106 +  /*                                                                       */
393.1107 +  typedef struct  FT_Raster_Params_
393.1108 +  {
393.1109 +    const FT_Bitmap*        target;
393.1110 +    const void*             source;
393.1111 +    int                     flags;
393.1112 +    FT_SpanFunc             gray_spans;
393.1113 +    FT_SpanFunc             black_spans;  /* doesn't work! */
393.1114 +    FT_Raster_BitTest_Func  bit_test;     /* doesn't work! */
393.1115 +    FT_Raster_BitSet_Func   bit_set;      /* doesn't work! */
393.1116 +    void*                   user;
393.1117 +    FT_BBox                 clip_box;
393.1118 +
393.1119 +  } FT_Raster_Params;
393.1120 +
393.1121 +
393.1122 +  /*************************************************************************/
393.1123 +  /*                                                                       */
393.1124 +  /* <FuncType>                                                            */
393.1125 +  /*    FT_Raster_NewFunc                                                  */
393.1126 +  /*                                                                       */
393.1127 +  /* <Description>                                                         */
393.1128 +  /*    A function used to create a new raster object.                     */
393.1129 +  /*                                                                       */
393.1130 +  /* <Input>                                                               */
393.1131 +  /*    memory :: A handle to the memory allocator.                        */
393.1132 +  /*                                                                       */
393.1133 +  /* <Output>                                                              */
393.1134 +  /*    raster :: A handle to the new raster object.                       */
393.1135 +  /*                                                                       */
393.1136 +  /* <Return>                                                              */
393.1137 +  /*    Error code.  0~means success.                                      */
393.1138 +  /*                                                                       */
393.1139 +  /* <Note>                                                                */
393.1140 +  /*    The `memory' parameter is a typeless pointer in order to avoid     */
393.1141 +  /*    un-wanted dependencies on the rest of the FreeType code.  In       */
393.1142 +  /*    practice, it is an @FT_Memory object, i.e., a handle to the        */
393.1143 +  /*    standard FreeType memory allocator.  However, this field can be    */
393.1144 +  /*    completely ignored by a given raster implementation.               */
393.1145 +  /*                                                                       */
393.1146 +  typedef int
393.1147 +  (*FT_Raster_NewFunc)( void*       memory,
393.1148 +                        FT_Raster*  raster );
393.1149 +
393.1150 +#define FT_Raster_New_Func  FT_Raster_NewFunc
393.1151 +
393.1152 +
393.1153 +  /*************************************************************************/
393.1154 +  /*                                                                       */
393.1155 +  /* <FuncType>                                                            */
393.1156 +  /*    FT_Raster_DoneFunc                                                 */
393.1157 +  /*                                                                       */
393.1158 +  /* <Description>                                                         */
393.1159 +  /*    A function used to destroy a given raster object.                  */
393.1160 +  /*                                                                       */
393.1161 +  /* <Input>                                                               */
393.1162 +  /*    raster :: A handle to the raster object.                           */
393.1163 +  /*                                                                       */
393.1164 +  typedef void
393.1165 +  (*FT_Raster_DoneFunc)( FT_Raster  raster );
393.1166 +
393.1167 +#define FT_Raster_Done_Func  FT_Raster_DoneFunc
393.1168 +
393.1169 +
393.1170 +  /*************************************************************************/
393.1171 +  /*                                                                       */
393.1172 +  /* <FuncType>                                                            */
393.1173 +  /*    FT_Raster_ResetFunc                                                */
393.1174 +  /*                                                                       */
393.1175 +  /* <Description>                                                         */
393.1176 +  /*    FreeType provides an area of memory called the `render pool',      */
393.1177 +  /*    available to all registered rasters.  This pool can be freely used */
393.1178 +  /*    during a given scan-conversion but is shared by all rasters.  Its  */
393.1179 +  /*    content is thus transient.                                         */
393.1180 +  /*                                                                       */
393.1181 +  /*    This function is called each time the render pool changes, or just */
393.1182 +  /*    after a new raster object is created.                              */
393.1183 +  /*                                                                       */
393.1184 +  /* <Input>                                                               */
393.1185 +  /*    raster    :: A handle to the new raster object.                    */
393.1186 +  /*                                                                       */
393.1187 +  /*    pool_base :: The address in memory of the render pool.             */
393.1188 +  /*                                                                       */
393.1189 +  /*    pool_size :: The size in bytes of the render pool.                 */
393.1190 +  /*                                                                       */
393.1191 +  /* <Note>                                                                */
393.1192 +  /*    Rasters can ignore the render pool and rely on dynamic memory      */
393.1193 +  /*    allocation if they want to (a handle to the memory allocator is    */
393.1194 +  /*    passed to the raster constructor).  However, this is not           */
393.1195 +  /*    recommended for efficiency purposes.                               */
393.1196 +  /*                                                                       */
393.1197 +  typedef void
393.1198 +  (*FT_Raster_ResetFunc)( FT_Raster       raster,
393.1199 +                          unsigned char*  pool_base,
393.1200 +                          unsigned long   pool_size );
393.1201 +
393.1202 +#define FT_Raster_Reset_Func  FT_Raster_ResetFunc
393.1203 +
393.1204 +
393.1205 +  /*************************************************************************/
393.1206 +  /*                                                                       */
393.1207 +  /* <FuncType>                                                            */
393.1208 +  /*    FT_Raster_SetModeFunc                                              */
393.1209 +  /*                                                                       */
393.1210 +  /* <Description>                                                         */
393.1211 +  /*    This function is a generic facility to change modes or attributes  */
393.1212 +  /*    in a given raster.  This can be used for debugging purposes, or    */
393.1213 +  /*    simply to allow implementation-specific `features' in a given      */
393.1214 +  /*    raster module.                                                     */
393.1215 +  /*                                                                       */
393.1216 +  /* <Input>                                                               */
393.1217 +  /*    raster :: A handle to the new raster object.                       */
393.1218 +  /*                                                                       */
393.1219 +  /*    mode   :: A 4-byte tag used to name the mode or property.          */
393.1220 +  /*                                                                       */
393.1221 +  /*    args   :: A pointer to the new mode/property to use.               */
393.1222 +  /*                                                                       */
393.1223 +  typedef int
393.1224 +  (*FT_Raster_SetModeFunc)( FT_Raster      raster,
393.1225 +                            unsigned long  mode,
393.1226 +                            void*          args );
393.1227 +
393.1228 +#define FT_Raster_Set_Mode_Func  FT_Raster_SetModeFunc
393.1229 +
393.1230 +
393.1231 +  /*************************************************************************/
393.1232 +  /*                                                                       */
393.1233 +  /* <FuncType>                                                            */
393.1234 +  /*    FT_Raster_RenderFunc                                               */
393.1235 +  /*                                                                       */
393.1236 +  /* <Description>                                                         */
393.1237 +  /*    Invoke a given raster to scan-convert a given glyph image into a   */
393.1238 +  /*    target bitmap.                                                     */
393.1239 +  /*                                                                       */
393.1240 +  /* <Input>                                                               */
393.1241 +  /*    raster :: A handle to the raster object.                           */
393.1242 +  /*                                                                       */
393.1243 +  /*    params :: A pointer to an @FT_Raster_Params structure used to      */
393.1244 +  /*              store the rendering parameters.                          */
393.1245 +  /*                                                                       */
393.1246 +  /* <Return>                                                              */
393.1247 +  /*    Error code.  0~means success.                                      */
393.1248 +  /*                                                                       */
393.1249 +  /* <Note>                                                                */
393.1250 +  /*    The exact format of the source image depends on the raster's glyph */
393.1251 +  /*    format defined in its @FT_Raster_Funcs structure.  It can be an    */
393.1252 +  /*    @FT_Outline or anything else in order to support a large array of  */
393.1253 +  /*    glyph formats.                                                     */
393.1254 +  /*                                                                       */
393.1255 +  /*    Note also that the render function can fail and return a           */
393.1256 +  /*    `FT_Err_Unimplemented_Feature' error code if the raster used does  */
393.1257 +  /*    not support direct composition.                                    */
393.1258 +  /*                                                                       */
393.1259 +  /*    XXX: For now, the standard raster doesn't support direct           */
393.1260 +  /*         composition but this should change for the final release (see */
393.1261 +  /*         the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c'    */
393.1262 +  /*         for examples of distinct implementations which support direct */
393.1263 +  /*         composition).                                                 */
393.1264 +  /*                                                                       */
393.1265 +  typedef int
393.1266 +  (*FT_Raster_RenderFunc)( FT_Raster                raster,
393.1267 +                           const FT_Raster_Params*  params );
393.1268 +
393.1269 +#define FT_Raster_Render_Func  FT_Raster_RenderFunc
393.1270 +
393.1271 +
393.1272 +  /*************************************************************************/
393.1273 +  /*                                                                       */
393.1274 +  /* <Struct>                                                              */
393.1275 +  /*    FT_Raster_Funcs                                                    */
393.1276 +  /*                                                                       */
393.1277 +  /* <Description>                                                         */
393.1278 +  /*   A structure used to describe a given raster class to the library.   */
393.1279 +  /*                                                                       */
393.1280 +  /* <Fields>                                                              */
393.1281 +  /*    glyph_format  :: The supported glyph format for this raster.       */
393.1282 +  /*                                                                       */
393.1283 +  /*    raster_new    :: The raster constructor.                           */
393.1284 +  /*                                                                       */
393.1285 +  /*    raster_reset  :: Used to reset the render pool within the raster.  */
393.1286 +  /*                                                                       */
393.1287 +  /*    raster_render :: A function to render a glyph into a given bitmap. */
393.1288 +  /*                                                                       */
393.1289 +  /*    raster_done   :: The raster destructor.                            */
393.1290 +  /*                                                                       */
393.1291 +  typedef struct  FT_Raster_Funcs_
393.1292 +  {
393.1293 +    FT_Glyph_Format        glyph_format;
393.1294 +    FT_Raster_NewFunc      raster_new;
393.1295 +    FT_Raster_ResetFunc    raster_reset;
393.1296 +    FT_Raster_SetModeFunc  raster_set_mode;
393.1297 +    FT_Raster_RenderFunc   raster_render;
393.1298 +    FT_Raster_DoneFunc     raster_done;
393.1299 +
393.1300 +  } FT_Raster_Funcs;
393.1301 +
393.1302 +
393.1303 +  /* */
393.1304 +
393.1305 +
393.1306 +FT_END_HEADER
393.1307 +
393.1308 +#endif /* __FTIMAGE_H__ */
393.1309 +
393.1310 +
393.1311 +/* END */
393.1312 +
393.1313 +
393.1314 +/* Local Variables: */
393.1315 +/* coding: utf-8    */
393.1316 +/* End:             */
   394.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   394.2 +++ b/libs/ft2static/freetype/ftincrem.h	Sat Feb 01 19:58:19 2014 +0200
   394.3 @@ -0,0 +1,353 @@
   394.4 +/***************************************************************************/
   394.5 +/*                                                                         */
   394.6 +/*  ftincrem.h                                                             */
   394.7 +/*                                                                         */
   394.8 +/*    FreeType incremental loading (specification).                        */
   394.9 +/*                                                                         */
  394.10 +/*  Copyright 2002, 2003, 2006, 2007, 2008, 2010 by                        */
  394.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  394.12 +/*                                                                         */
  394.13 +/*  This file is part of the FreeType project, and may only be used,       */
  394.14 +/*  modified, and distributed under the terms of the FreeType project      */
  394.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  394.16 +/*  this file you indicate that you have read the license and              */
  394.17 +/*  understand and accept it fully.                                        */
  394.18 +/*                                                                         */
  394.19 +/***************************************************************************/
  394.20 +
  394.21 +
  394.22 +#ifndef __FTINCREM_H__
  394.23 +#define __FTINCREM_H__
  394.24 +
  394.25 +#include <ft2build.h>
  394.26 +#include FT_FREETYPE_H
  394.27 +
  394.28 +#ifdef FREETYPE_H
  394.29 +#error "freetype.h of FreeType 1 has been loaded!"
  394.30 +#error "Please fix the directory search order for header files"
  394.31 +#error "so that freetype.h of FreeType 2 is found first."
  394.32 +#endif
  394.33 +
  394.34 +
  394.35 +FT_BEGIN_HEADER
  394.36 +
  394.37 +  /***************************************************************************
  394.38 +   *
  394.39 +   * @section:
  394.40 +   *    incremental
  394.41 +   *
  394.42 +   * @title:
  394.43 +   *    Incremental Loading
  394.44 +   *
  394.45 +   * @abstract:
  394.46 +   *    Custom Glyph Loading.
  394.47 +   *
  394.48 +   * @description:
  394.49 +   *   This section contains various functions used to perform so-called
  394.50 +   *   `incremental' glyph loading.  This is a mode where all glyphs loaded
  394.51 +   *   from a given @FT_Face are provided by the client application,
  394.52 +   *
  394.53 +   *   Apart from that, all other tables are loaded normally from the font
  394.54 +   *   file.  This mode is useful when FreeType is used within another
  394.55 +   *   engine, e.g., a PostScript Imaging Processor.
  394.56 +   *
  394.57 +   *   To enable this mode, you must use @FT_Open_Face, passing an
  394.58 +   *   @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an
  394.59 +   *   @FT_Incremental_Interface value.  See the comments for
  394.60 +   *   @FT_Incremental_InterfaceRec for an example.
  394.61 +   *
  394.62 +   */
  394.63 +
  394.64 +
  394.65 +  /***************************************************************************
  394.66 +   *
  394.67 +   * @type:
  394.68 +   *   FT_Incremental
  394.69 +   *
  394.70 +   * @description:
  394.71 +   *   An opaque type describing a user-provided object used to implement
  394.72 +   *   `incremental' glyph loading within FreeType.  This is used to support
  394.73 +   *   embedded fonts in certain environments (e.g., PostScript interpreters),
  394.74 +   *   where the glyph data isn't in the font file, or must be overridden by
  394.75 +   *   different values.
  394.76 +   *
  394.77 +   * @note:
  394.78 +   *   It is up to client applications to create and implement @FT_Incremental
  394.79 +   *   objects, as long as they provide implementations for the methods
  394.80 +   *   @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc
  394.81 +   *   and @FT_Incremental_GetGlyphMetricsFunc.
  394.82 +   *
  394.83 +   *   See the description of @FT_Incremental_InterfaceRec to understand how
  394.84 +   *   to use incremental objects with FreeType.
  394.85 +   *
  394.86 +   */
  394.87 +  typedef struct FT_IncrementalRec_*  FT_Incremental;
  394.88 +
  394.89 +
  394.90 +  /***************************************************************************
  394.91 +   *
  394.92 +   * @struct:
  394.93 +   *   FT_Incremental_MetricsRec
  394.94 +   *
  394.95 +   * @description:
  394.96 +   *   A small structure used to contain the basic glyph metrics returned
  394.97 +   *   by the @FT_Incremental_GetGlyphMetricsFunc method.
  394.98 +   *
  394.99 +   * @fields:
 394.100 +   *   bearing_x ::
 394.101 +   *     Left bearing, in font units.
 394.102 +   *
 394.103 +   *   bearing_y ::
 394.104 +   *     Top bearing, in font units.
 394.105 +   *
 394.106 +   *   advance ::
 394.107 +   *     Horizontal component of glyph advance, in font units.
 394.108 +   *
 394.109 +   *   advance_v ::
 394.110 +   *     Vertical component of glyph advance, in font units.
 394.111 +   *
 394.112 +   * @note:
 394.113 +   *   These correspond to horizontal or vertical metrics depending on the
 394.114 +   *   value of the `vertical' argument to the function
 394.115 +   *   @FT_Incremental_GetGlyphMetricsFunc.
 394.116 +   *
 394.117 +   */
 394.118 +  typedef struct  FT_Incremental_MetricsRec_
 394.119 +  {
 394.120 +    FT_Long  bearing_x;
 394.121 +    FT_Long  bearing_y;
 394.122 +    FT_Long  advance;
 394.123 +    FT_Long  advance_v;     /* since 2.3.12 */
 394.124 +
 394.125 +  } FT_Incremental_MetricsRec;
 394.126 +
 394.127 +
 394.128 +  /***************************************************************************
 394.129 +   *
 394.130 +   * @struct:
 394.131 +   *   FT_Incremental_Metrics
 394.132 +   *
 394.133 +   * @description:
 394.134 +   *   A handle to an @FT_Incremental_MetricsRec structure.
 394.135 +   *
 394.136 +   */
 394.137 +   typedef struct FT_Incremental_MetricsRec_*  FT_Incremental_Metrics;
 394.138 +
 394.139 +
 394.140 +  /***************************************************************************
 394.141 +   *
 394.142 +   * @type:
 394.143 +   *   FT_Incremental_GetGlyphDataFunc
 394.144 +   *
 394.145 +   * @description:
 394.146 +   *   A function called by FreeType to access a given glyph's data bytes
 394.147 +   *   during @FT_Load_Glyph or @FT_Load_Char if incremental loading is
 394.148 +   *   enabled.
 394.149 +   *
 394.150 +   *   Note that the format of the glyph's data bytes depends on the font
 394.151 +   *   file format.  For TrueType, it must correspond to the raw bytes within
 394.152 +   *   the `glyf' table.  For PostScript formats, it must correspond to the
 394.153 +   *   *unencrypted* charstring bytes, without any `lenIV' header.  It is
 394.154 +   *   undefined for any other format.
 394.155 +   *
 394.156 +   * @input:
 394.157 +   *   incremental ::
 394.158 +   *     Handle to an opaque @FT_Incremental handle provided by the client
 394.159 +   *     application.
 394.160 +   *
 394.161 +   *   glyph_index ::
 394.162 +   *     Index of relevant glyph.
 394.163 +   *
 394.164 +   * @output:
 394.165 +   *   adata ::
 394.166 +   *     A structure describing the returned glyph data bytes (which will be
 394.167 +   *     accessed as a read-only byte block).
 394.168 +   *
 394.169 +   * @return:
 394.170 +   *   FreeType error code.  0~means success.
 394.171 +   *
 394.172 +   * @note:
 394.173 +   *   If this function returns successfully the method
 394.174 +   *   @FT_Incremental_FreeGlyphDataFunc will be called later to release
 394.175 +   *   the data bytes.
 394.176 +   *
 394.177 +   *   Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for
 394.178 +   *   compound glyphs.
 394.179 +   *
 394.180 +   */
 394.181 +  typedef FT_Error
 394.182 +  (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental  incremental,
 394.183 +                                      FT_UInt         glyph_index,
 394.184 +                                      FT_Data*        adata );
 394.185 +
 394.186 +
 394.187 +  /***************************************************************************
 394.188 +   *
 394.189 +   * @type:
 394.190 +   *   FT_Incremental_FreeGlyphDataFunc
 394.191 +   *
 394.192 +   * @description:
 394.193 +   *   A function used to release the glyph data bytes returned by a
 394.194 +   *   successful call to @FT_Incremental_GetGlyphDataFunc.
 394.195 +   *
 394.196 +   * @input:
 394.197 +   *   incremental ::
 394.198 +   *     A handle to an opaque @FT_Incremental handle provided by the client
 394.199 +   *     application.
 394.200 +   *
 394.201 +   *   data ::
 394.202 +   *     A structure describing the glyph data bytes (which will be accessed
 394.203 +   *     as a read-only byte block).
 394.204 +   *
 394.205 +   */
 394.206 +  typedef void
 394.207 +  (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental  incremental,
 394.208 +                                       FT_Data*        data );
 394.209 +
 394.210 +
 394.211 +  /***************************************************************************
 394.212 +   *
 394.213 +   * @type:
 394.214 +   *   FT_Incremental_GetGlyphMetricsFunc
 394.215 +   *
 394.216 +   * @description:
 394.217 +   *   A function used to retrieve the basic metrics of a given glyph index
 394.218 +   *   before accessing its data.  This is necessary because, in certain
 394.219 +   *   formats like TrueType, the metrics are stored in a different place from
 394.220 +   *   the glyph images proper.
 394.221 +   *
 394.222 +   * @input:
 394.223 +   *   incremental ::
 394.224 +   *     A handle to an opaque @FT_Incremental handle provided by the client
 394.225 +   *     application.
 394.226 +   *
 394.227 +   *   glyph_index ::
 394.228 +   *     Index of relevant glyph.
 394.229 +   *
 394.230 +   *   vertical ::
 394.231 +   *     If true, return vertical metrics.
 394.232 +   *
 394.233 +   *   ametrics ::
 394.234 +   *     This parameter is used for both input and output.
 394.235 +   *     The original glyph metrics, if any, in font units.  If metrics are
 394.236 +   *     not available all the values must be set to zero.
 394.237 +   *
 394.238 +   * @output:
 394.239 +   *   ametrics ::
 394.240 +   *     The replacement glyph metrics in font units.
 394.241 +   *
 394.242 +   */
 394.243 +  typedef FT_Error
 394.244 +  (*FT_Incremental_GetGlyphMetricsFunc)
 394.245 +                      ( FT_Incremental              incremental,
 394.246 +                        FT_UInt                     glyph_index,
 394.247 +                        FT_Bool                     vertical,
 394.248 +                        FT_Incremental_MetricsRec  *ametrics );
 394.249 +
 394.250 +
 394.251 +  /**************************************************************************
 394.252 +   *
 394.253 +   * @struct:
 394.254 +   *   FT_Incremental_FuncsRec
 394.255 +   *
 394.256 +   * @description:
 394.257 +   *   A table of functions for accessing fonts that load data
 394.258 +   *   incrementally.  Used in @FT_Incremental_InterfaceRec.
 394.259 +   *
 394.260 +   * @fields:
 394.261 +   *   get_glyph_data ::
 394.262 +   *     The function to get glyph data.  Must not be null.
 394.263 +   *
 394.264 +   *   free_glyph_data ::
 394.265 +   *     The function to release glyph data.  Must not be null.
 394.266 +   *
 394.267 +   *   get_glyph_metrics ::
 394.268 +   *     The function to get glyph metrics.  May be null if the font does
 394.269 +   *     not provide overriding glyph metrics.
 394.270 +   *
 394.271 +   */
 394.272 +  typedef struct  FT_Incremental_FuncsRec_
 394.273 +  {
 394.274 +    FT_Incremental_GetGlyphDataFunc     get_glyph_data;
 394.275 +    FT_Incremental_FreeGlyphDataFunc    free_glyph_data;
 394.276 +    FT_Incremental_GetGlyphMetricsFunc  get_glyph_metrics;
 394.277 +
 394.278 +  } FT_Incremental_FuncsRec;
 394.279 +
 394.280 +
 394.281 +  /***************************************************************************
 394.282 +   *
 394.283 +   * @struct:
 394.284 +   *   FT_Incremental_InterfaceRec
 394.285 +   *
 394.286 +   * @description:
 394.287 +   *   A structure to be used with @FT_Open_Face to indicate that the user
 394.288 +   *   wants to support incremental glyph loading.  You should use it with
 394.289 +   *   @FT_PARAM_TAG_INCREMENTAL as in the following example:
 394.290 +   *
 394.291 +   *     {
 394.292 +   *       FT_Incremental_InterfaceRec  inc_int;
 394.293 +   *       FT_Parameter                 parameter;
 394.294 +   *       FT_Open_Args                 open_args;
 394.295 +   *
 394.296 +   *
 394.297 +   *       // set up incremental descriptor
 394.298 +   *       inc_int.funcs  = my_funcs;
 394.299 +   *       inc_int.object = my_object;
 394.300 +   *
 394.301 +   *       // set up optional parameter
 394.302 +   *       parameter.tag  = FT_PARAM_TAG_INCREMENTAL;
 394.303 +   *       parameter.data = &inc_int;
 394.304 +   *
 394.305 +   *       // set up FT_Open_Args structure
 394.306 +   *       open_args.flags      = FT_OPEN_PATHNAME | FT_OPEN_PARAMS;
 394.307 +   *       open_args.pathname   = my_font_pathname;
 394.308 +   *       open_args.num_params = 1;
 394.309 +   *       open_args.params     = &parameter; // we use one optional argument
 394.310 +   *
 394.311 +   *       // open the font
 394.312 +   *       error = FT_Open_Face( library, &open_args, index, &face );
 394.313 +   *       ...
 394.314 +   *     }
 394.315 +   *
 394.316 +   */
 394.317 +  typedef struct  FT_Incremental_InterfaceRec_
 394.318 +  {
 394.319 +    const FT_Incremental_FuncsRec*  funcs;
 394.320 +    FT_Incremental                  object;
 394.321 +
 394.322 +  } FT_Incremental_InterfaceRec;
 394.323 +
 394.324 +
 394.325 +  /***************************************************************************
 394.326 +   *
 394.327 +   * @type:
 394.328 +   *   FT_Incremental_Interface
 394.329 +   *
 394.330 +   * @description:
 394.331 +   *   A pointer to an @FT_Incremental_InterfaceRec structure.
 394.332 +   *
 394.333 +   */
 394.334 +  typedef FT_Incremental_InterfaceRec*   FT_Incremental_Interface;
 394.335 +
 394.336 +
 394.337 +  /***************************************************************************
 394.338 +   *
 394.339 +   * @constant:
 394.340 +   *   FT_PARAM_TAG_INCREMENTAL
 394.341 +   *
 394.342 +   * @description:
 394.343 +   *   A constant used as the tag of @FT_Parameter structures to indicate
 394.344 +   *   an incremental loading object to be used by FreeType.
 394.345 +   *
 394.346 +   */
 394.347 +#define FT_PARAM_TAG_INCREMENTAL  FT_MAKE_TAG( 'i', 'n', 'c', 'r' )
 394.348 +
 394.349 +  /* */
 394.350 +
 394.351 +FT_END_HEADER
 394.352 +
 394.353 +#endif /* __FTINCREM_H__ */
 394.354 +
 394.355 +
 394.356 +/* END */
   395.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   395.2 +++ b/libs/ft2static/freetype/ftlcdfil.h	Sat Feb 01 19:58:19 2014 +0200
   395.3 @@ -0,0 +1,213 @@
   395.4 +/***************************************************************************/
   395.5 +/*                                                                         */
   395.6 +/*  ftlcdfil.h                                                             */
   395.7 +/*                                                                         */
   395.8 +/*    FreeType API for color filtering of subpixel bitmap glyphs           */
   395.9 +/*    (specification).                                                     */
  395.10 +/*                                                                         */
  395.11 +/*  Copyright 2006, 2007, 2008, 2010 by                                    */
  395.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  395.13 +/*                                                                         */
  395.14 +/*  This file is part of the FreeType project, and may only be used,       */
  395.15 +/*  modified, and distributed under the terms of the FreeType project      */
  395.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  395.17 +/*  this file you indicate that you have read the license and              */
  395.18 +/*  understand and accept it fully.                                        */
  395.19 +/*                                                                         */
  395.20 +/***************************************************************************/
  395.21 +
  395.22 +
  395.23 +#ifndef __FT_LCD_FILTER_H__
  395.24 +#define __FT_LCD_FILTER_H__
  395.25 +
  395.26 +#include <ft2build.h>
  395.27 +#include FT_FREETYPE_H
  395.28 +
  395.29 +#ifdef FREETYPE_H
  395.30 +#error "freetype.h of FreeType 1 has been loaded!"
  395.31 +#error "Please fix the directory search order for header files"
  395.32 +#error "so that freetype.h of FreeType 2 is found first."
  395.33 +#endif
  395.34 +
  395.35 +
  395.36 +FT_BEGIN_HEADER
  395.37 +
  395.38 +  /***************************************************************************
  395.39 +   *
  395.40 +   * @section:
  395.41 +   *   lcd_filtering
  395.42 +   *
  395.43 +   * @title:
  395.44 +   *   LCD Filtering
  395.45 +   *
  395.46 +   * @abstract:
  395.47 +   *   Reduce color fringes of LCD-optimized bitmaps.
  395.48 +   *
  395.49 +   * @description:
  395.50 +   *   The @FT_Library_SetLcdFilter API can be used to specify a low-pass
  395.51 +   *   filter which is then applied to LCD-optimized bitmaps generated
  395.52 +   *   through @FT_Render_Glyph.  This is useful to reduce color fringes
  395.53 +   *   which would occur with unfiltered rendering.
  395.54 +   *
  395.55 +   *   Note that no filter is active by default, and that this function is
  395.56 +   *   *not* implemented in default builds of the library.  You need to
  395.57 +   *   #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file
  395.58 +   *   in order to activate it.
  395.59 +   */
  395.60 +
  395.61 +
  395.62 +  /****************************************************************************
  395.63 +   *
  395.64 +   * @enum:
  395.65 +   *   FT_LcdFilter
  395.66 +   *
  395.67 +   * @description:
  395.68 +   *   A list of values to identify various types of LCD filters.
  395.69 +   *
  395.70 +   * @values:
  395.71 +   *   FT_LCD_FILTER_NONE ::
  395.72 +   *     Do not perform filtering.  When used with subpixel rendering, this
  395.73 +   *     results in sometimes severe color fringes.
  395.74 +   *
  395.75 +   *   FT_LCD_FILTER_DEFAULT ::
  395.76 +   *     The default filter reduces color fringes considerably, at the cost
  395.77 +   *     of a slight blurriness in the output.
  395.78 +   *
  395.79 +   *   FT_LCD_FILTER_LIGHT ::
  395.80 +   *     The light filter is a variant that produces less blurriness at the
  395.81 +   *     cost of slightly more color fringes than the default one.  It might
  395.82 +   *     be better, depending on taste, your monitor, or your personal vision.
  395.83 +   *
  395.84 +   *   FT_LCD_FILTER_LEGACY ::
  395.85 +   *     This filter corresponds to the original libXft color filter.  It
  395.86 +   *     provides high contrast output but can exhibit really bad color
  395.87 +   *     fringes if glyphs are not extremely well hinted to the pixel grid.
  395.88 +   *     In other words, it only works well if the TrueType bytecode
  395.89 +   *     interpreter is enabled *and* high-quality hinted fonts are used.
  395.90 +   *
  395.91 +   *     This filter is only provided for comparison purposes, and might be
  395.92 +   *     disabled or stay unsupported in the future.
  395.93 +   *
  395.94 +   * @since:
  395.95 +   *   2.3.0
  395.96 +   */
  395.97 +  typedef enum  FT_LcdFilter_
  395.98 +  {
  395.99 +    FT_LCD_FILTER_NONE    = 0,
 395.100 +    FT_LCD_FILTER_DEFAULT = 1,
 395.101 +    FT_LCD_FILTER_LIGHT   = 2,
 395.102 +    FT_LCD_FILTER_LEGACY  = 16,
 395.103 +
 395.104 +    FT_LCD_FILTER_MAX   /* do not remove */
 395.105 +
 395.106 +  } FT_LcdFilter;
 395.107 +
 395.108 +
 395.109 +  /**************************************************************************
 395.110 +   *
 395.111 +   * @func:
 395.112 +   *   FT_Library_SetLcdFilter
 395.113 +   *
 395.114 +   * @description:
 395.115 +   *   This function is used to apply color filtering to LCD decimated
 395.116 +   *   bitmaps, like the ones used when calling @FT_Render_Glyph with
 395.117 +   *   @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V.
 395.118 +   *
 395.119 +   * @input:
 395.120 +   *   library ::
 395.121 +   *     A handle to the target library instance.
 395.122 +   *
 395.123 +   *   filter ::
 395.124 +   *     The filter type.
 395.125 +   *
 395.126 +   *     You can use @FT_LCD_FILTER_NONE here to disable this feature, or
 395.127 +   *     @FT_LCD_FILTER_DEFAULT to use a default filter that should work
 395.128 +   *     well on most LCD screens.
 395.129 +   *
 395.130 +   * @return:
 395.131 +   *   FreeType error code.  0~means success.
 395.132 +   *
 395.133 +   * @note:
 395.134 +   *   This feature is always disabled by default.  Clients must make an
 395.135 +   *   explicit call to this function with a `filter' value other than
 395.136 +   *   @FT_LCD_FILTER_NONE in order to enable it.
 395.137 +   *
 395.138 +   *   Due to *PATENTS* covering subpixel rendering, this function doesn't
 395.139 +   *   do anything except returning `FT_Err_Unimplemented_Feature' if the
 395.140 +   *   configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not
 395.141 +   *   defined in your build of the library, which should correspond to all
 395.142 +   *   default builds of FreeType.
 395.143 +   *
 395.144 +   *   The filter affects glyph bitmaps rendered through @FT_Render_Glyph,
 395.145 +   *   @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char.
 395.146 +   *
 395.147 +   *   It does _not_ affect the output of @FT_Outline_Render and
 395.148 +   *   @FT_Outline_Get_Bitmap.
 395.149 +   *
 395.150 +   *   If this feature is activated, the dimensions of LCD glyph bitmaps are
 395.151 +   *   either larger or taller than the dimensions of the corresponding
 395.152 +   *   outline with regards to the pixel grid.  For example, for
 395.153 +   *   @FT_RENDER_MODE_LCD, the filter adds up to 3~pixels to the left, and
 395.154 +   *   up to 3~pixels to the right.
 395.155 +   *
 395.156 +   *   The bitmap offset values are adjusted correctly, so clients shouldn't
 395.157 +   *   need to modify their layout and glyph positioning code when enabling
 395.158 +   *   the filter.
 395.159 +   *
 395.160 +   * @since:
 395.161 +   *   2.3.0
 395.162 +   */
 395.163 +  FT_EXPORT( FT_Error )
 395.164 +  FT_Library_SetLcdFilter( FT_Library    library,
 395.165 +                           FT_LcdFilter  filter );
 395.166 +
 395.167 +
 395.168 +  /**************************************************************************
 395.169 +   *
 395.170 +   * @func:
 395.171 +   *   FT_Library_SetLcdFilterWeights
 395.172 +   *
 395.173 +   * @description:
 395.174 +   *   Use this function to override the filter weights selected by
 395.175 +   *   @FT_Library_SetLcdFilter.  By default, FreeType uses the quintuple
 395.176 +   *   (0x00, 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10,
 395.177 +   *   0x40, 0x70, 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and
 395.178 +   *   FT_LCD_FILTER_LEGACY.
 395.179 +   *
 395.180 +   * @input:
 395.181 +   *   library ::
 395.182 +   *     A handle to the target library instance.
 395.183 +   *
 395.184 +   *   weights ::
 395.185 +   *     A pointer to an array; the function copies the first five bytes and
 395.186 +   *     uses them to specify the filter weights.
 395.187 +   *
 395.188 +   * @return:
 395.189 +   *   FreeType error code.  0~means success.
 395.190 +   *
 395.191 +   * @note:
 395.192 +   *   Due to *PATENTS* covering subpixel rendering, this function doesn't
 395.193 +   *   do anything except returning `FT_Err_Unimplemented_Feature' if the
 395.194 +   *   configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not
 395.195 +   *   defined in your build of the library, which should correspond to all
 395.196 +   *   default builds of FreeType.
 395.197 +   *
 395.198 +   *   This function must be called after @FT_Library_SetLcdFilter to have
 395.199 +   *   any effect.
 395.200 +   *
 395.201 +   * @since:
 395.202 +   *   2.4.0
 395.203 +   */
 395.204 +  FT_EXPORT( FT_Error )
 395.205 +  FT_Library_SetLcdFilterWeights( FT_Library      library,
 395.206 +                                  unsigned char  *weights );
 395.207 +
 395.208 +  /* */
 395.209 +
 395.210 +
 395.211 +FT_END_HEADER
 395.212 +
 395.213 +#endif /* __FT_LCD_FILTER_H__ */
 395.214 +
 395.215 +
 395.216 +/* END */
   396.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   396.2 +++ b/libs/ft2static/freetype/ftlist.h	Sat Feb 01 19:58:19 2014 +0200
   396.3 @@ -0,0 +1,277 @@
   396.4 +/***************************************************************************/
   396.5 +/*                                                                         */
   396.6 +/*  ftlist.h                                                               */
   396.7 +/*                                                                         */
   396.8 +/*    Generic list support for FreeType (specification).                   */
   396.9 +/*                                                                         */
  396.10 +/*  Copyright 1996-2001, 2003, 2007, 2010 by                               */
  396.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  396.12 +/*                                                                         */
  396.13 +/*  This file is part of the FreeType project, and may only be used,       */
  396.14 +/*  modified, and distributed under the terms of the FreeType project      */
  396.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  396.16 +/*  this file you indicate that you have read the license and              */
  396.17 +/*  understand and accept it fully.                                        */
  396.18 +/*                                                                         */
  396.19 +/***************************************************************************/
  396.20 +
  396.21 +
  396.22 +  /*************************************************************************/
  396.23 +  /*                                                                       */
  396.24 +  /*  This file implements functions relative to list processing.  Its     */
  396.25 +  /*  data structures are defined in `freetype.h'.                         */
  396.26 +  /*                                                                       */
  396.27 +  /*************************************************************************/
  396.28 +
  396.29 +
  396.30 +#ifndef __FTLIST_H__
  396.31 +#define __FTLIST_H__
  396.32 +
  396.33 +
  396.34 +#include <ft2build.h>
  396.35 +#include FT_FREETYPE_H
  396.36 +
  396.37 +#ifdef FREETYPE_H
  396.38 +#error "freetype.h of FreeType 1 has been loaded!"
  396.39 +#error "Please fix the directory search order for header files"
  396.40 +#error "so that freetype.h of FreeType 2 is found first."
  396.41 +#endif
  396.42 +
  396.43 +
  396.44 +FT_BEGIN_HEADER
  396.45 +
  396.46 +
  396.47 +  /*************************************************************************/
  396.48 +  /*                                                                       */
  396.49 +  /* <Section>                                                             */
  396.50 +  /*    list_processing                                                    */
  396.51 +  /*                                                                       */
  396.52 +  /* <Title>                                                               */
  396.53 +  /*    List Processing                                                    */
  396.54 +  /*                                                                       */
  396.55 +  /* <Abstract>                                                            */
  396.56 +  /*    Simple management of lists.                                        */
  396.57 +  /*                                                                       */
  396.58 +  /* <Description>                                                         */
  396.59 +  /*    This section contains various definitions related to list          */
  396.60 +  /*    processing using doubly-linked nodes.                              */
  396.61 +  /*                                                                       */
  396.62 +  /* <Order>                                                               */
  396.63 +  /*    FT_List                                                            */
  396.64 +  /*    FT_ListNode                                                        */
  396.65 +  /*    FT_ListRec                                                         */
  396.66 +  /*    FT_ListNodeRec                                                     */
  396.67 +  /*                                                                       */
  396.68 +  /*    FT_List_Add                                                        */
  396.69 +  /*    FT_List_Insert                                                     */
  396.70 +  /*    FT_List_Find                                                       */
  396.71 +  /*    FT_List_Remove                                                     */
  396.72 +  /*    FT_List_Up                                                         */
  396.73 +  /*    FT_List_Iterate                                                    */
  396.74 +  /*    FT_List_Iterator                                                   */
  396.75 +  /*    FT_List_Finalize                                                   */
  396.76 +  /*    FT_List_Destructor                                                 */
  396.77 +  /*                                                                       */
  396.78 +  /*************************************************************************/
  396.79 +
  396.80 +
  396.81 +  /*************************************************************************/
  396.82 +  /*                                                                       */
  396.83 +  /* <Function>                                                            */
  396.84 +  /*    FT_List_Find                                                       */
  396.85 +  /*                                                                       */
  396.86 +  /* <Description>                                                         */
  396.87 +  /*    Find the list node for a given listed object.                      */
  396.88 +  /*                                                                       */
  396.89 +  /* <Input>                                                               */
  396.90 +  /*    list :: A pointer to the parent list.                              */
  396.91 +  /*    data :: The address of the listed object.                          */
  396.92 +  /*                                                                       */
  396.93 +  /* <Return>                                                              */
  396.94 +  /*    List node.  NULL if it wasn't found.                               */
  396.95 +  /*                                                                       */
  396.96 +  FT_EXPORT( FT_ListNode )
  396.97 +  FT_List_Find( FT_List  list,
  396.98 +                void*    data );
  396.99 +
 396.100 +
 396.101 +  /*************************************************************************/
 396.102 +  /*                                                                       */
 396.103 +  /* <Function>                                                            */
 396.104 +  /*    FT_List_Add                                                        */
 396.105 +  /*                                                                       */
 396.106 +  /* <Description>                                                         */
 396.107 +  /*    Append an element to the end of a list.                            */
 396.108 +  /*                                                                       */
 396.109 +  /* <InOut>                                                               */
 396.110 +  /*    list :: A pointer to the parent list.                              */
 396.111 +  /*    node :: The node to append.                                        */
 396.112 +  /*                                                                       */
 396.113 +  FT_EXPORT( void )
 396.114 +  FT_List_Add( FT_List      list,
 396.115 +               FT_ListNode  node );
 396.116 +
 396.117 +
 396.118 +  /*************************************************************************/
 396.119 +  /*                                                                       */
 396.120 +  /* <Function>                                                            */
 396.121 +  /*    FT_List_Insert                                                     */
 396.122 +  /*                                                                       */
 396.123 +  /* <Description>                                                         */
 396.124 +  /*    Insert an element at the head of a list.                           */
 396.125 +  /*                                                                       */
 396.126 +  /* <InOut>                                                               */
 396.127 +  /*    list :: A pointer to parent list.                                  */
 396.128 +  /*    node :: The node to insert.                                        */
 396.129 +  /*                                                                       */
 396.130 +  FT_EXPORT( void )
 396.131 +  FT_List_Insert( FT_List      list,
 396.132 +                  FT_ListNode  node );
 396.133 +
 396.134 +
 396.135 +  /*************************************************************************/
 396.136 +  /*                                                                       */
 396.137 +  /* <Function>                                                            */
 396.138 +  /*    FT_List_Remove                                                     */
 396.139 +  /*                                                                       */
 396.140 +  /* <Description>                                                         */
 396.141 +  /*    Remove a node from a list.  This function doesn't check whether    */
 396.142 +  /*    the node is in the list!                                           */
 396.143 +  /*                                                                       */
 396.144 +  /* <Input>                                                               */
 396.145 +  /*    node :: The node to remove.                                        */
 396.146 +  /*                                                                       */
 396.147 +  /* <InOut>                                                               */
 396.148 +  /*    list :: A pointer to the parent list.                              */
 396.149 +  /*                                                                       */
 396.150 +  FT_EXPORT( void )
 396.151 +  FT_List_Remove( FT_List      list,
 396.152 +                  FT_ListNode  node );
 396.153 +
 396.154 +
 396.155 +  /*************************************************************************/
 396.156 +  /*                                                                       */
 396.157 +  /* <Function>                                                            */
 396.158 +  /*    FT_List_Up                                                         */
 396.159 +  /*                                                                       */
 396.160 +  /* <Description>                                                         */
 396.161 +  /*    Move a node to the head/top of a list.  Used to maintain LRU       */
 396.162 +  /*    lists.                                                             */
 396.163 +  /*                                                                       */
 396.164 +  /* <InOut>                                                               */
 396.165 +  /*    list :: A pointer to the parent list.                              */
 396.166 +  /*    node :: The node to move.                                          */
 396.167 +  /*                                                                       */
 396.168 +  FT_EXPORT( void )
 396.169 +  FT_List_Up( FT_List      list,
 396.170 +              FT_ListNode  node );
 396.171 +
 396.172 +
 396.173 +  /*************************************************************************/
 396.174 +  /*                                                                       */
 396.175 +  /* <FuncType>                                                            */
 396.176 +  /*    FT_List_Iterator                                                   */
 396.177 +  /*                                                                       */
 396.178 +  /* <Description>                                                         */
 396.179 +  /*    An FT_List iterator function which is called during a list parse   */
 396.180 +  /*    by @FT_List_Iterate.                                               */
 396.181 +  /*                                                                       */
 396.182 +  /* <Input>                                                               */
 396.183 +  /*    node :: The current iteration list node.                           */
 396.184 +  /*                                                                       */
 396.185 +  /*    user :: A typeless pointer passed to @FT_List_Iterate.             */
 396.186 +  /*            Can be used to point to the iteration's state.             */
 396.187 +  /*                                                                       */
 396.188 +  typedef FT_Error
 396.189 +  (*FT_List_Iterator)( FT_ListNode  node,
 396.190 +                       void*        user );
 396.191 +
 396.192 +
 396.193 +  /*************************************************************************/
 396.194 +  /*                                                                       */
 396.195 +  /* <Function>                                                            */
 396.196 +  /*    FT_List_Iterate                                                    */
 396.197 +  /*                                                                       */
 396.198 +  /* <Description>                                                         */
 396.199 +  /*    Parse a list and calls a given iterator function on each element.  */
 396.200 +  /*    Note that parsing is stopped as soon as one of the iterator calls  */
 396.201 +  /*    returns a non-zero value.                                          */
 396.202 +  /*                                                                       */
 396.203 +  /* <Input>                                                               */
 396.204 +  /*    list     :: A handle to the list.                                  */
 396.205 +  /*    iterator :: An iterator function, called on each node of the list. */
 396.206 +  /*    user     :: A user-supplied field which is passed as the second    */
 396.207 +  /*                argument to the iterator.                              */
 396.208 +  /*                                                                       */
 396.209 +  /* <Return>                                                              */
 396.210 +  /*    The result (a FreeType error code) of the last iterator call.      */
 396.211 +  /*                                                                       */
 396.212 +  FT_EXPORT( FT_Error )
 396.213 +  FT_List_Iterate( FT_List           list,
 396.214 +                   FT_List_Iterator  iterator,
 396.215 +                   void*             user );
 396.216 +
 396.217 +
 396.218 +  /*************************************************************************/
 396.219 +  /*                                                                       */
 396.220 +  /* <FuncType>                                                            */
 396.221 +  /*    FT_List_Destructor                                                 */
 396.222 +  /*                                                                       */
 396.223 +  /* <Description>                                                         */
 396.224 +  /*    An @FT_List iterator function which is called during a list        */
 396.225 +  /*    finalization by @FT_List_Finalize to destroy all elements in a     */
 396.226 +  /*    given list.                                                        */
 396.227 +  /*                                                                       */
 396.228 +  /* <Input>                                                               */
 396.229 +  /*    system :: The current system object.                               */
 396.230 +  /*                                                                       */
 396.231 +  /*    data   :: The current object to destroy.                           */
 396.232 +  /*                                                                       */
 396.233 +  /*    user   :: A typeless pointer passed to @FT_List_Iterate.  It can   */
 396.234 +  /*              be used to point to the iteration's state.               */
 396.235 +  /*                                                                       */
 396.236 +  typedef void
 396.237 +  (*FT_List_Destructor)( FT_Memory  memory,
 396.238 +                         void*      data,
 396.239 +                         void*      user );
 396.240 +
 396.241 +
 396.242 +  /*************************************************************************/
 396.243 +  /*                                                                       */
 396.244 +  /* <Function>                                                            */
 396.245 +  /*    FT_List_Finalize                                                   */
 396.246 +  /*                                                                       */
 396.247 +  /* <Description>                                                         */
 396.248 +  /*    Destroy all elements in the list as well as the list itself.       */
 396.249 +  /*                                                                       */
 396.250 +  /* <Input>                                                               */
 396.251 +  /*    list    :: A handle to the list.                                   */
 396.252 +  /*                                                                       */
 396.253 +  /*    destroy :: A list destructor that will be applied to each element  */
 396.254 +  /*               of the list.                                            */
 396.255 +  /*                                                                       */
 396.256 +  /*    memory  :: The current memory object which handles deallocation.   */
 396.257 +  /*                                                                       */
 396.258 +  /*    user    :: A user-supplied field which is passed as the last       */
 396.259 +  /*               argument to the destructor.                             */
 396.260 +  /*                                                                       */
 396.261 +  /* <Note>                                                                */
 396.262 +  /*    This function expects that all nodes added by @FT_List_Add or      */
 396.263 +  /*    @FT_List_Insert have been dynamically allocated.                   */
 396.264 +  /*                                                                       */
 396.265 +  FT_EXPORT( void )
 396.266 +  FT_List_Finalize( FT_List             list,
 396.267 +                    FT_List_Destructor  destroy,
 396.268 +                    FT_Memory           memory,
 396.269 +                    void*               user );
 396.270 +
 396.271 +
 396.272 +  /* */
 396.273 +
 396.274 +
 396.275 +FT_END_HEADER
 396.276 +
 396.277 +#endif /* __FTLIST_H__ */
 396.278 +
 396.279 +
 396.280 +/* END */
   397.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   397.2 +++ b/libs/ft2static/freetype/ftlzw.h	Sat Feb 01 19:58:19 2014 +0200
   397.3 @@ -0,0 +1,99 @@
   397.4 +/***************************************************************************/
   397.5 +/*                                                                         */
   397.6 +/*  ftlzw.h                                                                */
   397.7 +/*                                                                         */
   397.8 +/*    LZW-compressed stream support.                                       */
   397.9 +/*                                                                         */
  397.10 +/*  Copyright 2004, 2006 by                                                */
  397.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  397.12 +/*                                                                         */
  397.13 +/*  This file is part of the FreeType project, and may only be used,       */
  397.14 +/*  modified, and distributed under the terms of the FreeType project      */
  397.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  397.16 +/*  this file you indicate that you have read the license and              */
  397.17 +/*  understand and accept it fully.                                        */
  397.18 +/*                                                                         */
  397.19 +/***************************************************************************/
  397.20 +
  397.21 +
  397.22 +#ifndef __FTLZW_H__
  397.23 +#define __FTLZW_H__
  397.24 +
  397.25 +#include <ft2build.h>
  397.26 +#include FT_FREETYPE_H
  397.27 +
  397.28 +#ifdef FREETYPE_H
  397.29 +#error "freetype.h of FreeType 1 has been loaded!"
  397.30 +#error "Please fix the directory search order for header files"
  397.31 +#error "so that freetype.h of FreeType 2 is found first."
  397.32 +#endif
  397.33 +
  397.34 +
  397.35 +FT_BEGIN_HEADER
  397.36 +
  397.37 +  /*************************************************************************/
  397.38 +  /*                                                                       */
  397.39 +  /* <Section>                                                             */
  397.40 +  /*    lzw                                                                */
  397.41 +  /*                                                                       */
  397.42 +  /* <Title>                                                               */
  397.43 +  /*    LZW Streams                                                        */
  397.44 +  /*                                                                       */
  397.45 +  /* <Abstract>                                                            */
  397.46 +  /*    Using LZW-compressed font files.                                   */
  397.47 +  /*                                                                       */
  397.48 +  /* <Description>                                                         */
  397.49 +  /*    This section contains the declaration of LZW-specific functions.   */
  397.50 +  /*                                                                       */
  397.51 +  /*************************************************************************/
  397.52 +
  397.53 + /************************************************************************
  397.54 +  *
  397.55 +  * @function:
  397.56 +  *   FT_Stream_OpenLZW
  397.57 +  *
  397.58 +  * @description:
  397.59 +  *   Open a new stream to parse LZW-compressed font files.  This is
  397.60 +  *   mainly used to support the compressed `*.pcf.Z' fonts that come
  397.61 +  *   with XFree86.
  397.62 +  *
  397.63 +  * @input:
  397.64 +  *   stream :: The target embedding stream.
  397.65 +  *
  397.66 +  *   source :: The source stream.
  397.67 +  *
  397.68 +  * @return:
  397.69 +  *   FreeType error code.  0~means success.
  397.70 +  *
  397.71 +  * @note:
  397.72 +  *   The source stream must be opened _before_ calling this function.
  397.73 +  *
  397.74 +  *   Calling the internal function `FT_Stream_Close' on the new stream will
  397.75 +  *   *not* call `FT_Stream_Close' on the source stream.  None of the stream
  397.76 +  *   objects will be released to the heap.
  397.77 +  *
  397.78 +  *   The stream implementation is very basic and resets the decompression
  397.79 +  *   process each time seeking backwards is needed within the stream
  397.80 +  *
  397.81 +  *   In certain builds of the library, LZW compression recognition is
  397.82 +  *   automatically handled when calling @FT_New_Face or @FT_Open_Face.
  397.83 +  *   This means that if no font driver is capable of handling the raw
  397.84 +  *   compressed file, the library will try to open a LZW stream from it
  397.85 +  *   and re-open the face with it.
  397.86 +  *
  397.87 +  *   This function may return `FT_Err_Unimplemented_Feature' if your build
  397.88 +  *   of FreeType was not compiled with LZW support.
  397.89 +  */
  397.90 +  FT_EXPORT( FT_Error )
  397.91 +  FT_Stream_OpenLZW( FT_Stream  stream,
  397.92 +                     FT_Stream  source );
  397.93 +
  397.94 + /* */
  397.95 +
  397.96 +
  397.97 +FT_END_HEADER
  397.98 +
  397.99 +#endif /* __FTLZW_H__ */
 397.100 +
 397.101 +
 397.102 +/* END */
   398.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   398.2 +++ b/libs/ft2static/freetype/ftmac.h	Sat Feb 01 19:58:19 2014 +0200
   398.3 @@ -0,0 +1,274 @@
   398.4 +/***************************************************************************/
   398.5 +/*                                                                         */
   398.6 +/*  ftmac.h                                                                */
   398.7 +/*                                                                         */
   398.8 +/*    Additional Mac-specific API.                                         */
   398.9 +/*                                                                         */
  398.10 +/*  Copyright 1996-2001, 2004, 2006, 2007 by                               */
  398.11 +/*  Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.     */
  398.12 +/*                                                                         */
  398.13 +/*  This file is part of the FreeType project, and may only be used,       */
  398.14 +/*  modified, and distributed under the terms of the FreeType project      */
  398.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  398.16 +/*  this file you indicate that you have read the license and              */
  398.17 +/*  understand and accept it fully.                                        */
  398.18 +/*                                                                         */
  398.19 +/***************************************************************************/
  398.20 +
  398.21 +
  398.22 +/***************************************************************************/
  398.23 +/*                                                                         */
  398.24 +/* NOTE: Include this file after <freetype/freetype.h> and after any       */
  398.25 +/*       Mac-specific headers (because this header uses Mac types such as  */
  398.26 +/*       Handle, FSSpec, FSRef, etc.)                                      */
  398.27 +/*                                                                         */
  398.28 +/***************************************************************************/
  398.29 +
  398.30 +
  398.31 +#ifndef __FTMAC_H__
  398.32 +#define __FTMAC_H__
  398.33 +
  398.34 +
  398.35 +#include <ft2build.h>
  398.36 +
  398.37 +
  398.38 +FT_BEGIN_HEADER
  398.39 +
  398.40 +
  398.41 +/* gcc-3.4.1 and later can warn about functions tagged as deprecated */
  398.42 +#ifndef FT_DEPRECATED_ATTRIBUTE
  398.43 +#if defined(__GNUC__)                                               && \
  398.44 +    ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
  398.45 +#define FT_DEPRECATED_ATTRIBUTE  __attribute__((deprecated))
  398.46 +#else
  398.47 +#define FT_DEPRECATED_ATTRIBUTE
  398.48 +#endif
  398.49 +#endif
  398.50 +
  398.51 +
  398.52 +  /*************************************************************************/
  398.53 +  /*                                                                       */
  398.54 +  /* <Section>                                                             */
  398.55 +  /*    mac_specific                                                       */
  398.56 +  /*                                                                       */
  398.57 +  /* <Title>                                                               */
  398.58 +  /*    Mac Specific Interface                                             */
  398.59 +  /*                                                                       */
  398.60 +  /* <Abstract>                                                            */
  398.61 +  /*    Only available on the Macintosh.                                   */
  398.62 +  /*                                                                       */
  398.63 +  /* <Description>                                                         */
  398.64 +  /*    The following definitions are only available if FreeType is        */
  398.65 +  /*    compiled on a Macintosh.                                           */
  398.66 +  /*                                                                       */
  398.67 +  /*************************************************************************/
  398.68 +
  398.69 +
  398.70 +  /*************************************************************************/
  398.71 +  /*                                                                       */
  398.72 +  /* <Function>                                                            */
  398.73 +  /*    FT_New_Face_From_FOND                                              */
  398.74 +  /*                                                                       */
  398.75 +  /* <Description>                                                         */
  398.76 +  /*    Create a new face object from a FOND resource.                     */
  398.77 +  /*                                                                       */
  398.78 +  /* <InOut>                                                               */
  398.79 +  /*    library    :: A handle to the library resource.                    */
  398.80 +  /*                                                                       */
  398.81 +  /* <Input>                                                               */
  398.82 +  /*    fond       :: A FOND resource.                                     */
  398.83 +  /*                                                                       */
  398.84 +  /*    face_index :: Only supported for the -1 `sanity check' special     */
  398.85 +  /*                  case.                                                */
  398.86 +  /*                                                                       */
  398.87 +  /* <Output>                                                              */
  398.88 +  /*    aface      :: A handle to a new face object.                       */
  398.89 +  /*                                                                       */
  398.90 +  /* <Return>                                                              */
  398.91 +  /*    FreeType error code.  0~means success.                             */
  398.92 +  /*                                                                       */
  398.93 +  /* <Notes>                                                               */
  398.94 +  /*    This function can be used to create @FT_Face objects from fonts    */
  398.95 +  /*    that are installed in the system as follows.                       */
  398.96 +  /*                                                                       */
  398.97 +  /*    {                                                                  */
  398.98 +  /*      fond = GetResource( 'FOND', fontName );                          */
  398.99 +  /*      error = FT_New_Face_From_FOND( library, fond, 0, &face );        */
 398.100 +  /*    }                                                                  */
 398.101 +  /*                                                                       */
 398.102 +  FT_EXPORT( FT_Error )
 398.103 +  FT_New_Face_From_FOND( FT_Library  library,
 398.104 +                         Handle      fond,
 398.105 +                         FT_Long     face_index,
 398.106 +                         FT_Face    *aface )
 398.107 +                       FT_DEPRECATED_ATTRIBUTE;
 398.108 +
 398.109 +
 398.110 +  /*************************************************************************/
 398.111 +  /*                                                                       */
 398.112 +  /* <Function>                                                            */
 398.113 +  /*    FT_GetFile_From_Mac_Name                                           */
 398.114 +  /*                                                                       */
 398.115 +  /* <Description>                                                         */
 398.116 +  /*    Return an FSSpec for the disk file containing the named font.      */
 398.117 +  /*                                                                       */
 398.118 +  /* <Input>                                                               */
 398.119 +  /*    fontName   :: Mac OS name of the font (e.g., Times New Roman       */
 398.120 +  /*                  Bold).                                               */
 398.121 +  /*                                                                       */
 398.122 +  /* <Output>                                                              */
 398.123 +  /*    pathSpec   :: FSSpec to the file.  For passing to                  */
 398.124 +  /*                  @FT_New_Face_From_FSSpec.                            */
 398.125 +  /*                                                                       */
 398.126 +  /*    face_index :: Index of the face.  For passing to                   */
 398.127 +  /*                  @FT_New_Face_From_FSSpec.                            */
 398.128 +  /*                                                                       */
 398.129 +  /* <Return>                                                              */
 398.130 +  /*    FreeType error code.  0~means success.                             */
 398.131 +  /*                                                                       */
 398.132 +  FT_EXPORT( FT_Error )
 398.133 +  FT_GetFile_From_Mac_Name( const char*  fontName,
 398.134 +                            FSSpec*      pathSpec,
 398.135 +                            FT_Long*     face_index )
 398.136 +                          FT_DEPRECATED_ATTRIBUTE;
 398.137 +
 398.138 +
 398.139 +  /*************************************************************************/
 398.140 +  /*                                                                       */
 398.141 +  /* <Function>                                                            */
 398.142 +  /*    FT_GetFile_From_Mac_ATS_Name                                       */
 398.143 +  /*                                                                       */
 398.144 +  /* <Description>                                                         */
 398.145 +  /*    Return an FSSpec for the disk file containing the named font.      */
 398.146 +  /*                                                                       */
 398.147 +  /* <Input>                                                               */
 398.148 +  /*    fontName   :: Mac OS name of the font in ATS framework.            */
 398.149 +  /*                                                                       */
 398.150 +  /* <Output>                                                              */
 398.151 +  /*    pathSpec   :: FSSpec to the file. For passing to                   */
 398.152 +  /*                  @FT_New_Face_From_FSSpec.                            */
 398.153 +  /*                                                                       */
 398.154 +  /*    face_index :: Index of the face. For passing to                    */
 398.155 +  /*                  @FT_New_Face_From_FSSpec.                            */
 398.156 +  /*                                                                       */
 398.157 +  /* <Return>                                                              */
 398.158 +  /*    FreeType error code.  0~means success.                             */
 398.159 +  /*                                                                       */
 398.160 +  FT_EXPORT( FT_Error )
 398.161 +  FT_GetFile_From_Mac_ATS_Name( const char*  fontName,
 398.162 +                                FSSpec*      pathSpec,
 398.163 +                                FT_Long*     face_index )
 398.164 +                              FT_DEPRECATED_ATTRIBUTE;
 398.165 +
 398.166 +
 398.167 +  /*************************************************************************/
 398.168 +  /*                                                                       */
 398.169 +  /* <Function>                                                            */
 398.170 +  /*    FT_GetFilePath_From_Mac_ATS_Name                                   */
 398.171 +  /*                                                                       */
 398.172 +  /* <Description>                                                         */
 398.173 +  /*    Return a pathname of the disk file and face index for given font   */
 398.174 +  /*    name which is handled by ATS framework.                            */
 398.175 +  /*                                                                       */
 398.176 +  /* <Input>                                                               */
 398.177 +  /*    fontName    :: Mac OS name of the font in ATS framework.           */
 398.178 +  /*                                                                       */
 398.179 +  /* <Output>                                                              */
 398.180 +  /*    path        :: Buffer to store pathname of the file.  For passing  */
 398.181 +  /*                   to @FT_New_Face.  The client must allocate this     */
 398.182 +  /*                   buffer before calling this function.                */
 398.183 +  /*                                                                       */
 398.184 +  /*    maxPathSize :: Lengths of the buffer `path' that client allocated. */
 398.185 +  /*                                                                       */
 398.186 +  /*    face_index  :: Index of the face.  For passing to @FT_New_Face.    */
 398.187 +  /*                                                                       */
 398.188 +  /* <Return>                                                              */
 398.189 +  /*    FreeType error code.  0~means success.                             */
 398.190 +  /*                                                                       */
 398.191 +  FT_EXPORT( FT_Error )
 398.192 +  FT_GetFilePath_From_Mac_ATS_Name( const char*  fontName,
 398.193 +                                    UInt8*       path,
 398.194 +                                    UInt32       maxPathSize,
 398.195 +                                    FT_Long*     face_index )
 398.196 +                                  FT_DEPRECATED_ATTRIBUTE;
 398.197 +
 398.198 +
 398.199 +  /*************************************************************************/
 398.200 +  /*                                                                       */
 398.201 +  /* <Function>                                                            */
 398.202 +  /*    FT_New_Face_From_FSSpec                                            */
 398.203 +  /*                                                                       */
 398.204 +  /* <Description>                                                         */
 398.205 +  /*    Create a new face object from a given resource and typeface index  */
 398.206 +  /*    using an FSSpec to the font file.                                  */
 398.207 +  /*                                                                       */
 398.208 +  /* <InOut>                                                               */
 398.209 +  /*    library    :: A handle to the library resource.                    */
 398.210 +  /*                                                                       */
 398.211 +  /* <Input>                                                               */
 398.212 +  /*    spec       :: FSSpec to the font file.                             */
 398.213 +  /*                                                                       */
 398.214 +  /*    face_index :: The index of the face within the resource.  The      */
 398.215 +  /*                  first face has index~0.                              */
 398.216 +  /* <Output>                                                              */
 398.217 +  /*    aface      :: A handle to a new face object.                       */
 398.218 +  /*                                                                       */
 398.219 +  /* <Return>                                                              */
 398.220 +  /*    FreeType error code.  0~means success.                             */
 398.221 +  /*                                                                       */
 398.222 +  /* <Note>                                                                */
 398.223 +  /*    @FT_New_Face_From_FSSpec is identical to @FT_New_Face except       */
 398.224 +  /*    it accepts an FSSpec instead of a path.                            */
 398.225 +  /*                                                                       */
 398.226 +  FT_EXPORT( FT_Error )
 398.227 +  FT_New_Face_From_FSSpec( FT_Library     library,
 398.228 +                           const FSSpec  *spec,
 398.229 +                           FT_Long        face_index,
 398.230 +                           FT_Face       *aface )
 398.231 +                         FT_DEPRECATED_ATTRIBUTE;
 398.232 +
 398.233 +
 398.234 +  /*************************************************************************/
 398.235 +  /*                                                                       */
 398.236 +  /* <Function>                                                            */
 398.237 +  /*    FT_New_Face_From_FSRef                                             */
 398.238 +  /*                                                                       */
 398.239 +  /* <Description>                                                         */
 398.240 +  /*    Create a new face object from a given resource and typeface index  */
 398.241 +  /*    using an FSRef to the font file.                                   */
 398.242 +  /*                                                                       */
 398.243 +  /* <InOut>                                                               */
 398.244 +  /*    library    :: A handle to the library resource.                    */
 398.245 +  /*                                                                       */
 398.246 +  /* <Input>                                                               */
 398.247 +  /*    spec       :: FSRef to the font file.                              */
 398.248 +  /*                                                                       */
 398.249 +  /*    face_index :: The index of the face within the resource.  The      */
 398.250 +  /*                  first face has index~0.                              */
 398.251 +  /* <Output>                                                              */
 398.252 +  /*    aface      :: A handle to a new face object.                       */
 398.253 +  /*                                                                       */
 398.254 +  /* <Return>                                                              */
 398.255 +  /*    FreeType error code.  0~means success.                             */
 398.256 +  /*                                                                       */
 398.257 +  /* <Note>                                                                */
 398.258 +  /*    @FT_New_Face_From_FSRef is identical to @FT_New_Face except        */
 398.259 +  /*    it accepts an FSRef instead of a path.                             */
 398.260 +  /*                                                                       */
 398.261 +  FT_EXPORT( FT_Error )
 398.262 +  FT_New_Face_From_FSRef( FT_Library    library,
 398.263 +                          const FSRef  *ref,
 398.264 +                          FT_Long       face_index,
 398.265 +                          FT_Face      *aface )
 398.266 +                        FT_DEPRECATED_ATTRIBUTE;
 398.267 +
 398.268 +  /* */
 398.269 +
 398.270 +
 398.271 +FT_END_HEADER
 398.272 +
 398.273 +
 398.274 +#endif /* __FTMAC_H__ */
 398.275 +
 398.276 +
 398.277 +/* END */
   399.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   399.2 +++ b/libs/ft2static/freetype/ftmm.h	Sat Feb 01 19:58:19 2014 +0200
   399.3 @@ -0,0 +1,378 @@
   399.4 +/***************************************************************************/
   399.5 +/*                                                                         */
   399.6 +/*  ftmm.h                                                                 */
   399.7 +/*                                                                         */
   399.8 +/*    FreeType Multiple Master font interface (specification).             */
   399.9 +/*                                                                         */
  399.10 +/*  Copyright 1996-2001, 2003, 2004, 2006, 2009 by                         */
  399.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  399.12 +/*                                                                         */
  399.13 +/*  This file is part of the FreeType project, and may only be used,       */
  399.14 +/*  modified, and distributed under the terms of the FreeType project      */
  399.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  399.16 +/*  this file you indicate that you have read the license and              */
  399.17 +/*  understand and accept it fully.                                        */
  399.18 +/*                                                                         */
  399.19 +/***************************************************************************/
  399.20 +
  399.21 +
  399.22 +#ifndef __FTMM_H__
  399.23 +#define __FTMM_H__
  399.24 +
  399.25 +
  399.26 +#include <ft2build.h>
  399.27 +#include FT_TYPE1_TABLES_H
  399.28 +
  399.29 +
  399.30 +FT_BEGIN_HEADER
  399.31 +
  399.32 +
  399.33 +  /*************************************************************************/
  399.34 +  /*                                                                       */
  399.35 +  /* <Section>                                                             */
  399.36 +  /*    multiple_masters                                                   */
  399.37 +  /*                                                                       */
  399.38 +  /* <Title>                                                               */
  399.39 +  /*    Multiple Masters                                                   */
  399.40 +  /*                                                                       */
  399.41 +  /* <Abstract>                                                            */
  399.42 +  /*    How to manage Multiple Masters fonts.                              */
  399.43 +  /*                                                                       */
  399.44 +  /* <Description>                                                         */
  399.45 +  /*    The following types and functions are used to manage Multiple      */
  399.46 +  /*    Master fonts, i.e., the selection of specific design instances by  */
  399.47 +  /*    setting design axis coordinates.                                   */
  399.48 +  /*                                                                       */
  399.49 +  /*    George Williams has extended this interface to make it work with   */
  399.50 +  /*    both Type~1 Multiple Masters fonts and GX distortable (var)        */
  399.51 +  /*    fonts.  Some of these routines only work with MM fonts, others     */
  399.52 +  /*    will work with both types.  They are similar enough that a         */
  399.53 +  /*    consistent interface makes sense.                                  */
  399.54 +  /*                                                                       */
  399.55 +  /*************************************************************************/
  399.56 +
  399.57 +
  399.58 +  /*************************************************************************/
  399.59 +  /*                                                                       */
  399.60 +  /* <Struct>                                                              */
  399.61 +  /*    FT_MM_Axis                                                         */
  399.62 +  /*                                                                       */
  399.63 +  /* <Description>                                                         */
  399.64 +  /*    A simple structure used to model a given axis in design space for  */
  399.65 +  /*    Multiple Masters fonts.                                            */
  399.66 +  /*                                                                       */
  399.67 +  /*    This structure can't be used for GX var fonts.                     */
  399.68 +  /*                                                                       */
  399.69 +  /* <Fields>                                                              */
  399.70 +  /*    name    :: The axis's name.                                        */
  399.71 +  /*                                                                       */
  399.72 +  /*    minimum :: The axis's minimum design coordinate.                   */
  399.73 +  /*                                                                       */
  399.74 +  /*    maximum :: The axis's maximum design coordinate.                   */
  399.75 +  /*                                                                       */
  399.76 +  typedef struct  FT_MM_Axis_
  399.77 +  {
  399.78 +    FT_String*  name;
  399.79 +    FT_Long     minimum;
  399.80 +    FT_Long     maximum;
  399.81 +
  399.82 +  } FT_MM_Axis;
  399.83 +
  399.84 +
  399.85 +  /*************************************************************************/
  399.86 +  /*                                                                       */
  399.87 +  /* <Struct>                                                              */
  399.88 +  /*    FT_Multi_Master                                                    */
  399.89 +  /*                                                                       */
  399.90 +  /* <Description>                                                         */
  399.91 +  /*    A structure used to model the axes and space of a Multiple Masters */
  399.92 +  /*    font.                                                              */
  399.93 +  /*                                                                       */
  399.94 +  /*    This structure can't be used for GX var fonts.                     */
  399.95 +  /*                                                                       */
  399.96 +  /* <Fields>                                                              */
  399.97 +  /*    num_axis    :: Number of axes.  Cannot exceed~4.                   */
  399.98 +  /*                                                                       */
  399.99 +  /*    num_designs :: Number of designs; should be normally 2^num_axis    */
 399.100 +  /*                   even though the Type~1 specification strangely      */
 399.101 +  /*                   allows for intermediate designs to be present. This */
 399.102 +  /*                   number cannot exceed~16.                            */
 399.103 +  /*                                                                       */
 399.104 +  /*    axis        :: A table of axis descriptors.                        */
 399.105 +  /*                                                                       */
 399.106 +  typedef struct  FT_Multi_Master_
 399.107 +  {
 399.108 +    FT_UInt     num_axis;
 399.109 +    FT_UInt     num_designs;
 399.110 +    FT_MM_Axis  axis[T1_MAX_MM_AXIS];
 399.111 +
 399.112 +  } FT_Multi_Master;
 399.113 +
 399.114 +
 399.115 +  /*************************************************************************/
 399.116 +  /*                                                                       */
 399.117 +  /* <Struct>                                                              */
 399.118 +  /*    FT_Var_Axis                                                        */
 399.119 +  /*                                                                       */
 399.120 +  /* <Description>                                                         */
 399.121 +  /*    A simple structure used to model a given axis in design space for  */
 399.122 +  /*    Multiple Masters and GX var fonts.                                 */
 399.123 +  /*                                                                       */
 399.124 +  /* <Fields>                                                              */
 399.125 +  /*    name    :: The axis's name.                                        */
 399.126 +  /*               Not always meaningful for GX.                           */
 399.127 +  /*                                                                       */
 399.128 +  /*    minimum :: The axis's minimum design coordinate.                   */
 399.129 +  /*                                                                       */
 399.130 +  /*    def     :: The axis's default design coordinate.                   */
 399.131 +  /*               FreeType computes meaningful default values for MM; it  */
 399.132 +  /*               is then an integer value, not in 16.16 format.          */
 399.133 +  /*                                                                       */
 399.134 +  /*    maximum :: The axis's maximum design coordinate.                   */
 399.135 +  /*                                                                       */
 399.136 +  /*    tag     :: The axis's tag (the GX equivalent to `name').           */
 399.137 +  /*               FreeType provides default values for MM if possible.    */
 399.138 +  /*                                                                       */
 399.139 +  /*    strid   :: The entry in `name' table (another GX version of        */
 399.140 +  /*               `name').                                                */
 399.141 +  /*               Not meaningful for MM.                                  */
 399.142 +  /*                                                                       */
 399.143 +  typedef struct  FT_Var_Axis_
 399.144 +  {
 399.145 +    FT_String*  name;
 399.146 +
 399.147 +    FT_Fixed    minimum;
 399.148 +    FT_Fixed    def;
 399.149 +    FT_Fixed    maximum;
 399.150 +
 399.151 +    FT_ULong    tag;
 399.152 +    FT_UInt     strid;
 399.153 +
 399.154 +  } FT_Var_Axis;
 399.155 +
 399.156 +
 399.157 +  /*************************************************************************/
 399.158 +  /*                                                                       */
 399.159 +  /* <Struct>                                                              */
 399.160 +  /*    FT_Var_Named_Style                                                 */
 399.161 +  /*                                                                       */
 399.162 +  /* <Description>                                                         */
 399.163 +  /*    A simple structure used to model a named style in a GX var font.   */
 399.164 +  /*                                                                       */
 399.165 +  /*    This structure can't be used for MM fonts.                         */
 399.166 +  /*                                                                       */
 399.167 +  /* <Fields>                                                              */
 399.168 +  /*    coords :: The design coordinates for this style.                   */
 399.169 +  /*              This is an array with one entry for each axis.           */
 399.170 +  /*                                                                       */
 399.171 +  /*    strid  :: The entry in `name' table identifying this style.        */
 399.172 +  /*                                                                       */
 399.173 +  typedef struct  FT_Var_Named_Style_
 399.174 +  {
 399.175 +    FT_Fixed*  coords;
 399.176 +    FT_UInt    strid;
 399.177 +
 399.178 +  } FT_Var_Named_Style;
 399.179 +
 399.180 +
 399.181 +  /*************************************************************************/
 399.182 +  /*                                                                       */
 399.183 +  /* <Struct>                                                              */
 399.184 +  /*    FT_MM_Var                                                          */
 399.185 +  /*                                                                       */
 399.186 +  /* <Description>                                                         */
 399.187 +  /*    A structure used to model the axes and space of a Multiple Masters */
 399.188 +  /*    or GX var distortable font.                                        */
 399.189 +  /*                                                                       */
 399.190 +  /*    Some fields are specific to one format and not to the other.       */
 399.191 +  /*                                                                       */
 399.192 +  /* <Fields>                                                              */
 399.193 +  /*    num_axis        :: The number of axes.  The maximum value is~4 for */
 399.194 +  /*                       MM; no limit in GX.                             */
 399.195 +  /*                                                                       */
 399.196 +  /*    num_designs     :: The number of designs; should be normally       */
 399.197 +  /*                       2^num_axis for MM fonts.  Not meaningful for GX */
 399.198 +  /*                       (where every glyph could have a different       */
 399.199 +  /*                       number of designs).                             */
 399.200 +  /*                                                                       */
 399.201 +  /*    num_namedstyles :: The number of named styles; only meaningful for */
 399.202 +  /*                       GX which allows certain design coordinates to   */
 399.203 +  /*                       have a string ID (in the `name' table)          */
 399.204 +  /*                       associated with them.  The font can tell the    */
 399.205 +  /*                       user that, for example, Weight=1.5 is `Bold'.   */
 399.206 +  /*                                                                       */
 399.207 +  /*    axis            :: A table of axis descriptors.                    */
 399.208 +  /*                       GX fonts contain slightly more data than MM.    */
 399.209 +  /*                                                                       */
 399.210 +  /*    namedstyles     :: A table of named styles.                        */
 399.211 +  /*                       Only meaningful with GX.                        */
 399.212 +  /*                                                                       */
 399.213 +  typedef struct  FT_MM_Var_
 399.214 +  {
 399.215 +    FT_UInt              num_axis;
 399.216 +    FT_UInt              num_designs;
 399.217 +    FT_UInt              num_namedstyles;
 399.218 +    FT_Var_Axis*         axis;
 399.219 +    FT_Var_Named_Style*  namedstyle;
 399.220 +
 399.221 +  } FT_MM_Var;
 399.222 +
 399.223 +
 399.224 +  /* */
 399.225 +
 399.226 +
 399.227 +  /*************************************************************************/
 399.228 +  /*                                                                       */
 399.229 +  /* <Function>                                                            */
 399.230 +  /*    FT_Get_Multi_Master                                                */
 399.231 +  /*                                                                       */
 399.232 +  /* <Description>                                                         */
 399.233 +  /*    Retrieve the Multiple Master descriptor of a given font.           */
 399.234 +  /*                                                                       */
 399.235 +  /*    This function can't be used with GX fonts.                         */
 399.236 +  /*                                                                       */
 399.237 +  /* <Input>                                                               */
 399.238 +  /*    face    :: A handle to the source face.                            */
 399.239 +  /*                                                                       */
 399.240 +  /* <Output>                                                              */
 399.241 +  /*    amaster :: The Multiple Masters descriptor.                        */
 399.242 +  /*                                                                       */
 399.243 +  /* <Return>                                                              */
 399.244 +  /*    FreeType error code.  0~means success.                             */
 399.245 +  /*                                                                       */
 399.246 +  FT_EXPORT( FT_Error )
 399.247 +  FT_Get_Multi_Master( FT_Face           face,
 399.248 +                       FT_Multi_Master  *amaster );
 399.249 +
 399.250 +
 399.251 +  /*************************************************************************/
 399.252 +  /*                                                                       */
 399.253 +  /* <Function>                                                            */
 399.254 +  /*    FT_Get_MM_Var                                                      */
 399.255 +  /*                                                                       */
 399.256 +  /* <Description>                                                         */
 399.257 +  /*    Retrieve the Multiple Master/GX var descriptor of a given font.    */
 399.258 +  /*                                                                       */
 399.259 +  /* <Input>                                                               */
 399.260 +  /*    face    :: A handle to the source face.                            */
 399.261 +  /*                                                                       */
 399.262 +  /* <Output>                                                              */
 399.263 +  /*    amaster :: The Multiple Masters/GX var descriptor.                 */
 399.264 +  /*               Allocates a data structure, which the user must free    */
 399.265 +  /*               (a single call to FT_FREE will do it).                  */
 399.266 +  /*                                                                       */
 399.267 +  /* <Return>                                                              */
 399.268 +  /*    FreeType error code.  0~means success.                             */
 399.269 +  /*                                                                       */
 399.270 +  FT_EXPORT( FT_Error )
 399.271 +  FT_Get_MM_Var( FT_Face      face,
 399.272 +                 FT_MM_Var*  *amaster );
 399.273 +
 399.274 +
 399.275 +  /*************************************************************************/
 399.276 +  /*                                                                       */
 399.277 +  /* <Function>                                                            */
 399.278 +  /*    FT_Set_MM_Design_Coordinates                                       */
 399.279 +  /*                                                                       */
 399.280 +  /* <Description>                                                         */
 399.281 +  /*    For Multiple Masters fonts, choose an interpolated font design     */
 399.282 +  /*    through design coordinates.                                        */
 399.283 +  /*                                                                       */
 399.284 +  /*    This function can't be used with GX fonts.                         */
 399.285 +  /*                                                                       */
 399.286 +  /* <InOut>                                                               */
 399.287 +  /*    face       :: A handle to the source face.                         */
 399.288 +  /*                                                                       */
 399.289 +  /* <Input>                                                               */
 399.290 +  /*    num_coords :: The number of design coordinates (must be equal to   */
 399.291 +  /*                  the number of axes in the font).                     */
 399.292 +  /*                                                                       */
 399.293 +  /*    coords     :: An array of design coordinates.                      */
 399.294 +  /*                                                                       */
 399.295 +  /* <Return>                                                              */
 399.296 +  /*    FreeType error code.  0~means success.                             */
 399.297 +  /*                                                                       */
 399.298 +  FT_EXPORT( FT_Error )
 399.299 +  FT_Set_MM_Design_Coordinates( FT_Face   face,
 399.300 +                                FT_UInt   num_coords,
 399.301 +                                FT_Long*  coords );
 399.302 +
 399.303 +
 399.304 +  /*************************************************************************/
 399.305 +  /*                                                                       */
 399.306 +  /* <Function>                                                            */
 399.307 +  /*    FT_Set_Var_Design_Coordinates                                      */
 399.308 +  /*                                                                       */
 399.309 +  /* <Description>                                                         */
 399.310 +  /*    For Multiple Master or GX Var fonts, choose an interpolated font   */
 399.311 +  /*    design through design coordinates.                                 */
 399.312 +  /*                                                                       */
 399.313 +  /* <InOut>                                                               */
 399.314 +  /*    face       :: A handle to the source face.                         */
 399.315 +  /*                                                                       */
 399.316 +  /* <Input>                                                               */
 399.317 +  /*    num_coords :: The number of design coordinates (must be equal to   */
 399.318 +  /*                  the number of axes in the font).                     */
 399.319 +  /*                                                                       */
 399.320 +  /*    coords     :: An array of design coordinates.                      */
 399.321 +  /*                                                                       */
 399.322 +  /* <Return>                                                              */
 399.323 +  /*    FreeType error code.  0~means success.                             */
 399.324 +  /*                                                                       */
 399.325 +  FT_EXPORT( FT_Error )
 399.326 +  FT_Set_Var_Design_Coordinates( FT_Face    face,
 399.327 +                                 FT_UInt    num_coords,
 399.328 +                                 FT_Fixed*  coords );
 399.329 +
 399.330 +
 399.331 +  /*************************************************************************/
 399.332 +  /*                                                                       */
 399.333 +  /* <Function>                                                            */
 399.334 +  /*    FT_Set_MM_Blend_Coordinates                                        */
 399.335 +  /*                                                                       */
 399.336 +  /* <Description>                                                         */
 399.337 +  /*    For Multiple Masters and GX var fonts, choose an interpolated font */
 399.338 +  /*    design through normalized blend coordinates.                       */
 399.339 +  /*                                                                       */
 399.340 +  /* <InOut>                                                               */
 399.341 +  /*    face       :: A handle to the source face.                         */
 399.342 +  /*                                                                       */
 399.343 +  /* <Input>                                                               */
 399.344 +  /*    num_coords :: The number of design coordinates (must be equal to   */
 399.345 +  /*                  the number of axes in the font).                     */
 399.346 +  /*                                                                       */
 399.347 +  /*    coords     :: The design coordinates array (each element must be   */
 399.348 +  /*                  between 0 and 1.0).                                  */
 399.349 +  /*                                                                       */
 399.350 +  /* <Return>                                                              */
 399.351 +  /*    FreeType error code.  0~means success.                             */
 399.352 +  /*                                                                       */
 399.353 +  FT_EXPORT( FT_Error )
 399.354 +  FT_Set_MM_Blend_Coordinates( FT_Face    face,
 399.355 +                               FT_UInt    num_coords,
 399.356 +                               FT_Fixed*  coords );
 399.357 +
 399.358 +
 399.359 +  /*************************************************************************/
 399.360 +  /*                                                                       */
 399.361 +  /* <Function>                                                            */
 399.362 +  /*    FT_Set_Var_Blend_Coordinates                                       */
 399.363 +  /*                                                                       */
 399.364 +  /* <Description>                                                         */
 399.365 +  /*    This is another name of @FT_Set_MM_Blend_Coordinates.              */
 399.366 +  /*                                                                       */
 399.367 +  FT_EXPORT( FT_Error )
 399.368 +  FT_Set_Var_Blend_Coordinates( FT_Face    face,
 399.369 +                                FT_UInt    num_coords,
 399.370 +                                FT_Fixed*  coords );
 399.371 +
 399.372 +
 399.373 +  /* */
 399.374 +
 399.375 +
 399.376 +FT_END_HEADER
 399.377 +
 399.378 +#endif /* __FTMM_H__ */
 399.379 +
 399.380 +
 399.381 +/* END */
   400.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   400.2 +++ b/libs/ft2static/freetype/ftmodapi.h	Sat Feb 01 19:58:19 2014 +0200
   400.3 @@ -0,0 +1,483 @@
   400.4 +/***************************************************************************/
   400.5 +/*                                                                         */
   400.6 +/*  ftmodapi.h                                                             */
   400.7 +/*                                                                         */
   400.8 +/*    FreeType modules public interface (specification).                   */
   400.9 +/*                                                                         */
  400.10 +/*  Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009, 2010 by             */
  400.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  400.12 +/*                                                                         */
  400.13 +/*  This file is part of the FreeType project, and may only be used,       */
  400.14 +/*  modified, and distributed under the terms of the FreeType project      */
  400.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  400.16 +/*  this file you indicate that you have read the license and              */
  400.17 +/*  understand and accept it fully.                                        */
  400.18 +/*                                                                         */
  400.19 +/***************************************************************************/
  400.20 +
  400.21 +
  400.22 +#ifndef __FTMODAPI_H__
  400.23 +#define __FTMODAPI_H__
  400.24 +
  400.25 +
  400.26 +#include <ft2build.h>
  400.27 +#include FT_FREETYPE_H
  400.28 +
  400.29 +#ifdef FREETYPE_H
  400.30 +#error "freetype.h of FreeType 1 has been loaded!"
  400.31 +#error "Please fix the directory search order for header files"
  400.32 +#error "so that freetype.h of FreeType 2 is found first."
  400.33 +#endif
  400.34 +
  400.35 +
  400.36 +FT_BEGIN_HEADER
  400.37 +
  400.38 +
  400.39 +  /*************************************************************************/
  400.40 +  /*                                                                       */
  400.41 +  /* <Section>                                                             */
  400.42 +  /*    module_management                                                  */
  400.43 +  /*                                                                       */
  400.44 +  /* <Title>                                                               */
  400.45 +  /*    Module Management                                                  */
  400.46 +  /*                                                                       */
  400.47 +  /* <Abstract>                                                            */
  400.48 +  /*    How to add, upgrade, and remove modules from FreeType.             */
  400.49 +  /*                                                                       */
  400.50 +  /* <Description>                                                         */
  400.51 +  /*    The definitions below are used to manage modules within FreeType.  */
  400.52 +  /*    Modules can be added, upgraded, and removed at runtime.            */
  400.53 +  /*                                                                       */
  400.54 +  /*************************************************************************/
  400.55 +
  400.56 +
  400.57 +  /* module bit flags */
  400.58 +#define FT_MODULE_FONT_DRIVER         1  /* this module is a font driver  */
  400.59 +#define FT_MODULE_RENDERER            2  /* this module is a renderer     */
  400.60 +#define FT_MODULE_HINTER              4  /* this module is a glyph hinter */
  400.61 +#define FT_MODULE_STYLER              8  /* this module is a styler       */
  400.62 +
  400.63 +#define FT_MODULE_DRIVER_SCALABLE     0x100   /* the driver supports      */
  400.64 +                                              /* scalable fonts           */
  400.65 +#define FT_MODULE_DRIVER_NO_OUTLINES  0x200   /* the driver does not      */
  400.66 +                                              /* support vector outlines  */
  400.67 +#define FT_MODULE_DRIVER_HAS_HINTER   0x400   /* the driver provides its  */
  400.68 +                                              /* own hinter               */
  400.69 +
  400.70 +
  400.71 +  /* deprecated values */
  400.72 +#define ft_module_font_driver         FT_MODULE_FONT_DRIVER
  400.73 +#define ft_module_renderer            FT_MODULE_RENDERER
  400.74 +#define ft_module_hinter              FT_MODULE_HINTER
  400.75 +#define ft_module_styler              FT_MODULE_STYLER
  400.76 +
  400.77 +#define ft_module_driver_scalable     FT_MODULE_DRIVER_SCALABLE
  400.78 +#define ft_module_driver_no_outlines  FT_MODULE_DRIVER_NO_OUTLINES
  400.79 +#define ft_module_driver_has_hinter   FT_MODULE_DRIVER_HAS_HINTER
  400.80 +
  400.81 +
  400.82 +  typedef FT_Pointer  FT_Module_Interface;
  400.83 +
  400.84 +
  400.85 +  /*************************************************************************/
  400.86 +  /*                                                                       */
  400.87 +  /* <FuncType>                                                            */
  400.88 +  /*    FT_Module_Constructor                                              */
  400.89 +  /*                                                                       */
  400.90 +  /* <Description>                                                         */
  400.91 +  /*    A function used to initialize (not create) a new module object.    */
  400.92 +  /*                                                                       */
  400.93 +  /* <Input>                                                               */
  400.94 +  /*    module :: The module to initialize.                                */
  400.95 +  /*                                                                       */
  400.96 +  typedef FT_Error
  400.97 +  (*FT_Module_Constructor)( FT_Module  module );
  400.98 +
  400.99 +
 400.100 +  /*************************************************************************/
 400.101 +  /*                                                                       */
 400.102 +  /* <FuncType>                                                            */
 400.103 +  /*    FT_Module_Destructor                                               */
 400.104 +  /*                                                                       */
 400.105 +  /* <Description>                                                         */
 400.106 +  /*    A function used to finalize (not destroy) a given module object.   */
 400.107 +  /*                                                                       */
 400.108 +  /* <Input>                                                               */
 400.109 +  /*    module :: The module to finalize.                                  */
 400.110 +  /*                                                                       */
 400.111 +  typedef void
 400.112 +  (*FT_Module_Destructor)( FT_Module  module );
 400.113 +
 400.114 +
 400.115 +  /*************************************************************************/
 400.116 +  /*                                                                       */
 400.117 +  /* <FuncType>                                                            */
 400.118 +  /*    FT_Module_Requester                                                */
 400.119 +  /*                                                                       */
 400.120 +  /* <Description>                                                         */
 400.121 +  /*    A function used to query a given module for a specific interface.  */
 400.122 +  /*                                                                       */
 400.123 +  /* <Input>                                                               */
 400.124 +  /*    module :: The module to finalize.                                  */
 400.125 +  /*                                                                       */
 400.126 +  /*    name ::   The name of the interface in the module.                 */
 400.127 +  /*                                                                       */
 400.128 +  typedef FT_Module_Interface
 400.129 +  (*FT_Module_Requester)( FT_Module    module,
 400.130 +                          const char*  name );
 400.131 +
 400.132 +
 400.133 +  /*************************************************************************/
 400.134 +  /*                                                                       */
 400.135 +  /* <Struct>                                                              */
 400.136 +  /*    FT_Module_Class                                                    */
 400.137 +  /*                                                                       */
 400.138 +  /* <Description>                                                         */
 400.139 +  /*    The module class descriptor.                                       */
 400.140 +  /*                                                                       */
 400.141 +  /* <Fields>                                                              */
 400.142 +  /*    module_flags    :: Bit flags describing the module.                */
 400.143 +  /*                                                                       */
 400.144 +  /*    module_size     :: The size of one module object/instance in       */
 400.145 +  /*                       bytes.                                          */
 400.146 +  /*                                                                       */
 400.147 +  /*    module_name     :: The name of the module.                         */
 400.148 +  /*                                                                       */
 400.149 +  /*    module_version  :: The version, as a 16.16 fixed number            */
 400.150 +  /*                       (major.minor).                                  */
 400.151 +  /*                                                                       */
 400.152 +  /*    module_requires :: The version of FreeType this module requires,   */
 400.153 +  /*                       as a 16.16 fixed number (major.minor).  Starts  */
 400.154 +  /*                       at version 2.0, i.e., 0x20000.                  */
 400.155 +  /*                                                                       */
 400.156 +  /*    module_init     :: The initializing function.                      */
 400.157 +  /*                                                                       */
 400.158 +  /*    module_done     :: The finalizing function.                        */
 400.159 +  /*                                                                       */
 400.160 +  /*    get_interface   :: The interface requesting function.              */
 400.161 +  /*                                                                       */
 400.162 +  typedef struct  FT_Module_Class_
 400.163 +  {
 400.164 +    FT_ULong               module_flags;
 400.165 +    FT_Long                module_size;
 400.166 +    const FT_String*       module_name;
 400.167 +    FT_Fixed               module_version;
 400.168 +    FT_Fixed               module_requires;
 400.169 +
 400.170 +    const void*            module_interface;
 400.171 +
 400.172 +    FT_Module_Constructor  module_init;
 400.173 +    FT_Module_Destructor   module_done;
 400.174 +    FT_Module_Requester    get_interface;
 400.175 +
 400.176 +  } FT_Module_Class;
 400.177 +
 400.178 +
 400.179 +  /*************************************************************************/
 400.180 +  /*                                                                       */
 400.181 +  /* <Function>                                                            */
 400.182 +  /*    FT_Add_Module                                                      */
 400.183 +  /*                                                                       */
 400.184 +  /* <Description>                                                         */
 400.185 +  /*    Add a new module to a given library instance.                      */
 400.186 +  /*                                                                       */
 400.187 +  /* <InOut>                                                               */
 400.188 +  /*    library :: A handle to the library object.                         */
 400.189 +  /*                                                                       */
 400.190 +  /* <Input>                                                               */
 400.191 +  /*    clazz   :: A pointer to class descriptor for the module.           */
 400.192 +  /*                                                                       */
 400.193 +  /* <Return>                                                              */
 400.194 +  /*    FreeType error code.  0~means success.                             */
 400.195 +  /*                                                                       */
 400.196 +  /* <Note>                                                                */
 400.197 +  /*    An error will be returned if a module already exists by that name, */
 400.198 +  /*    or if the module requires a version of FreeType that is too great. */
 400.199 +  /*                                                                       */
 400.200 +  FT_EXPORT( FT_Error )
 400.201 +  FT_Add_Module( FT_Library              library,
 400.202 +                 const FT_Module_Class*  clazz );
 400.203 +
 400.204 +
 400.205 +  /*************************************************************************/
 400.206 +  /*                                                                       */
 400.207 +  /* <Function>                                                            */
 400.208 +  /*    FT_Get_Module                                                      */
 400.209 +  /*                                                                       */
 400.210 +  /* <Description>                                                         */
 400.211 +  /*    Find a module by its name.                                         */
 400.212 +  /*                                                                       */
 400.213 +  /* <Input>                                                               */
 400.214 +  /*    library     :: A handle to the library object.                     */
 400.215 +  /*                                                                       */
 400.216 +  /*    module_name :: The module's name (as an ASCII string).             */
 400.217 +  /*                                                                       */
 400.218 +  /* <Return>                                                              */
 400.219 +  /*    A module handle.  0~if none was found.                             */
 400.220 +  /*                                                                       */
 400.221 +  /* <Note>                                                                */
 400.222 +  /*    FreeType's internal modules aren't documented very well, and you   */
 400.223 +  /*    should look up the source code for details.                        */
 400.224 +  /*                                                                       */
 400.225 +  FT_EXPORT( FT_Module )
 400.226 +  FT_Get_Module( FT_Library   library,
 400.227 +                 const char*  module_name );
 400.228 +
 400.229 +
 400.230 +  /*************************************************************************/
 400.231 +  /*                                                                       */
 400.232 +  /* <Function>                                                            */
 400.233 +  /*    FT_Remove_Module                                                   */
 400.234 +  /*                                                                       */
 400.235 +  /* <Description>                                                         */
 400.236 +  /*    Remove a given module from a library instance.                     */
 400.237 +  /*                                                                       */
 400.238 +  /* <InOut>                                                               */
 400.239 +  /*    library :: A handle to a library object.                           */
 400.240 +  /*                                                                       */
 400.241 +  /* <Input>                                                               */
 400.242 +  /*    module  :: A handle to a module object.                            */
 400.243 +  /*                                                                       */
 400.244 +  /* <Return>                                                              */
 400.245 +  /*    FreeType error code.  0~means success.                             */
 400.246 +  /*                                                                       */
 400.247 +  /* <Note>                                                                */
 400.248 +  /*    The module object is destroyed by the function in case of success. */
 400.249 +  /*                                                                       */
 400.250 +  FT_EXPORT( FT_Error )
 400.251 +  FT_Remove_Module( FT_Library  library,
 400.252 +                    FT_Module   module );
 400.253 +
 400.254 +
 400.255 +  /*************************************************************************/
 400.256 +  /*                                                                       */
 400.257 +  /* <Function>                                                            */
 400.258 +  /*    FT_Reference_Library                                               */
 400.259 +  /*                                                                       */
 400.260 +  /* <Description>                                                         */
 400.261 +  /*    A counter gets initialized to~1 at the time an @FT_Library         */
 400.262 +  /*    structure is created.  This function increments the counter.       */
 400.263 +  /*    @FT_Done_Library then only destroys a library if the counter is~1, */
 400.264 +  /*    otherwise it simply decrements the counter.                        */
 400.265 +  /*                                                                       */
 400.266 +  /*    This function helps in managing life-cycles of structures which    */
 400.267 +  /*    reference @FT_Library objects.                                     */
 400.268 +  /*                                                                       */
 400.269 +  /* <Input>                                                               */
 400.270 +  /*    library :: A handle to a target library object.                    */
 400.271 +  /*                                                                       */
 400.272 +  /* <Return>                                                              */
 400.273 +  /*    FreeType error code.  0~means success.                             */
 400.274 +  /*                                                                       */
 400.275 +  /* <Since>                                                               */
 400.276 +  /*    2.4.2                                                              */
 400.277 +  /*                                                                       */
 400.278 +  FT_EXPORT( FT_Error )
 400.279 +  FT_Reference_Library( FT_Library  library );
 400.280 +
 400.281 +
 400.282 +  /*************************************************************************/
 400.283 +  /*                                                                       */
 400.284 +  /* <Function>                                                            */
 400.285 +  /*    FT_New_Library                                                     */
 400.286 +  /*                                                                       */
 400.287 +  /* <Description>                                                         */
 400.288 +  /*    This function is used to create a new FreeType library instance    */
 400.289 +  /*    from a given memory object.  It is thus possible to use libraries  */
 400.290 +  /*    with distinct memory allocators within the same program.           */
 400.291 +  /*                                                                       */
 400.292 +  /*    Normally, you would call this function (followed by a call to      */
 400.293 +  /*    @FT_Add_Default_Modules or a series of calls to @FT_Add_Module)    */
 400.294 +  /*    instead of @FT_Init_FreeType to initialize the FreeType library.   */
 400.295 +  /*                                                                       */
 400.296 +  /*    Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a      */
 400.297 +  /*    library instance.                                                  */
 400.298 +  /*                                                                       */
 400.299 +  /* <Input>                                                               */
 400.300 +  /*    memory   :: A handle to the original memory object.                */
 400.301 +  /*                                                                       */
 400.302 +  /* <Output>                                                              */
 400.303 +  /*    alibrary :: A pointer to handle of a new library object.           */
 400.304 +  /*                                                                       */
 400.305 +  /* <Return>                                                              */
 400.306 +  /*    FreeType error code.  0~means success.                             */
 400.307 +  /*                                                                       */
 400.308 +  /* <Note>                                                                */
 400.309 +  /*    See the discussion of reference counters in the description of     */
 400.310 +  /*    @FT_Reference_Library.                                             */
 400.311 +  /*                                                                       */
 400.312 +  FT_EXPORT( FT_Error )
 400.313 +  FT_New_Library( FT_Memory    memory,
 400.314 +                  FT_Library  *alibrary );
 400.315 +
 400.316 +
 400.317 +  /*************************************************************************/
 400.318 +  /*                                                                       */
 400.319 +  /* <Function>                                                            */
 400.320 +  /*    FT_Done_Library                                                    */
 400.321 +  /*                                                                       */
 400.322 +  /* <Description>                                                         */
 400.323 +  /*    Discard a given library object.  This closes all drivers and       */
 400.324 +  /*    discards all resource objects.                                     */
 400.325 +  /*                                                                       */
 400.326 +  /* <Input>                                                               */
 400.327 +  /*    library :: A handle to the target library.                         */
 400.328 +  /*                                                                       */
 400.329 +  /* <Return>                                                              */
 400.330 +  /*    FreeType error code.  0~means success.                             */
 400.331 +  /*                                                                       */
 400.332 +  /* <Note>                                                                */
 400.333 +  /*    See the discussion of reference counters in the description of     */
 400.334 +  /*    @FT_Reference_Library.                                             */
 400.335 +  /*                                                                       */
 400.336 +  FT_EXPORT( FT_Error )
 400.337 +  FT_Done_Library( FT_Library  library );
 400.338 +
 400.339 +/* */
 400.340 +
 400.341 +  typedef void
 400.342 +  (*FT_DebugHook_Func)( void*  arg );
 400.343 +
 400.344 +
 400.345 +  /*************************************************************************/
 400.346 +  /*                                                                       */
 400.347 +  /* <Function>                                                            */
 400.348 +  /*    FT_Set_Debug_Hook                                                  */
 400.349 +  /*                                                                       */
 400.350 +  /* <Description>                                                         */
 400.351 +  /*    Set a debug hook function for debugging the interpreter of a font  */
 400.352 +  /*    format.                                                            */
 400.353 +  /*                                                                       */
 400.354 +  /* <InOut>                                                               */
 400.355 +  /*    library    :: A handle to the library object.                      */
 400.356 +  /*                                                                       */
 400.357 +  /* <Input>                                                               */
 400.358 +  /*    hook_index :: The index of the debug hook.  You should use the     */
 400.359 +  /*                  values defined in `ftobjs.h', e.g.,                  */
 400.360 +  /*                  `FT_DEBUG_HOOK_TRUETYPE'.                            */
 400.361 +  /*                                                                       */
 400.362 +  /*    debug_hook :: The function used to debug the interpreter.          */
 400.363 +  /*                                                                       */
 400.364 +  /* <Note>                                                                */
 400.365 +  /*    Currently, four debug hook slots are available, but only two (for  */
 400.366 +  /*    the TrueType and the Type~1 interpreter) are defined.              */
 400.367 +  /*                                                                       */
 400.368 +  /*    Since the internal headers of FreeType are no longer installed,    */
 400.369 +  /*    the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly.      */
 400.370 +  /*    This is a bug and will be fixed in a forthcoming release.          */
 400.371 +  /*                                                                       */
 400.372 +  FT_EXPORT( void )
 400.373 +  FT_Set_Debug_Hook( FT_Library         library,
 400.374 +                     FT_UInt            hook_index,
 400.375 +                     FT_DebugHook_Func  debug_hook );
 400.376 +
 400.377 +
 400.378 +  /*************************************************************************/
 400.379 +  /*                                                                       */
 400.380 +  /* <Function>                                                            */
 400.381 +  /*    FT_Add_Default_Modules                                             */
 400.382 +  /*                                                                       */
 400.383 +  /* <Description>                                                         */
 400.384 +  /*    Add the set of default drivers to a given library object.          */
 400.385 +  /*    This is only useful when you create a library object with          */
 400.386 +  /*    @FT_New_Library (usually to plug a custom memory manager).         */
 400.387 +  /*                                                                       */
 400.388 +  /* <InOut>                                                               */
 400.389 +  /*    library :: A handle to a new library object.                       */
 400.390 +  /*                                                                       */
 400.391 +  FT_EXPORT( void )
 400.392 +  FT_Add_Default_Modules( FT_Library  library );
 400.393 +
 400.394 +
 400.395 +
 400.396 +  /**************************************************************************
 400.397 +   *
 400.398 +   * @section:
 400.399 +   *   truetype_engine
 400.400 +   *
 400.401 +   * @title:
 400.402 +   *   The TrueType Engine
 400.403 +   *
 400.404 +   * @abstract:
 400.405 +   *   TrueType bytecode support.
 400.406 +   *
 400.407 +   * @description:
 400.408 +   *   This section contains a function used to query the level of TrueType
 400.409 +   *   bytecode support compiled in this version of the library.
 400.410 +   *
 400.411 +   */
 400.412 +
 400.413 +
 400.414 +  /**************************************************************************
 400.415 +   *
 400.416 +   *  @enum:
 400.417 +   *     FT_TrueTypeEngineType
 400.418 +   *
 400.419 +   *  @description:
 400.420 +   *     A list of values describing which kind of TrueType bytecode
 400.421 +   *     engine is implemented in a given FT_Library instance.  It is used
 400.422 +   *     by the @FT_Get_TrueType_Engine_Type function.
 400.423 +   *
 400.424 +   *  @values:
 400.425 +   *     FT_TRUETYPE_ENGINE_TYPE_NONE ::
 400.426 +   *       The library doesn't implement any kind of bytecode interpreter.
 400.427 +   *
 400.428 +   *     FT_TRUETYPE_ENGINE_TYPE_UNPATENTED ::
 400.429 +   *       The library implements a bytecode interpreter that doesn't
 400.430 +   *       support the patented operations of the TrueType virtual machine.
 400.431 +   *
 400.432 +   *       Its main use is to load certain Asian fonts which position and
 400.433 +   *       scale glyph components with bytecode instructions.  It produces
 400.434 +   *       bad output for most other fonts.
 400.435 +   *
 400.436 +   *    FT_TRUETYPE_ENGINE_TYPE_PATENTED ::
 400.437 +   *       The library implements a bytecode interpreter that covers
 400.438 +   *       the full instruction set of the TrueType virtual machine (this
 400.439 +   *       was governed by patents until May 2010, hence the name).
 400.440 +   *
 400.441 +   *  @since:
 400.442 +   *       2.2
 400.443 +   *
 400.444 +   */
 400.445 +  typedef enum  FT_TrueTypeEngineType_
 400.446 +  {
 400.447 +    FT_TRUETYPE_ENGINE_TYPE_NONE = 0,
 400.448 +    FT_TRUETYPE_ENGINE_TYPE_UNPATENTED,
 400.449 +    FT_TRUETYPE_ENGINE_TYPE_PATENTED
 400.450 +
 400.451 +  } FT_TrueTypeEngineType;
 400.452 +
 400.453 +
 400.454 +  /**************************************************************************
 400.455 +   *
 400.456 +   *  @func:
 400.457 +   *     FT_Get_TrueType_Engine_Type
 400.458 +   *
 400.459 +   *  @description:
 400.460 +   *     Return an @FT_TrueTypeEngineType value to indicate which level of
 400.461 +   *     the TrueType virtual machine a given library instance supports.
 400.462 +   *
 400.463 +   *  @input:
 400.464 +   *     library ::
 400.465 +   *       A library instance.
 400.466 +   *
 400.467 +   *  @return:
 400.468 +   *     A value indicating which level is supported.
 400.469 +   *
 400.470 +   *  @since:
 400.471 +   *     2.2
 400.472 +   *
 400.473 +   */
 400.474 +  FT_EXPORT( FT_TrueTypeEngineType )
 400.475 +  FT_Get_TrueType_Engine_Type( FT_Library  library );
 400.476 +
 400.477 +
 400.478 +  /* */
 400.479 +
 400.480 +
 400.481 +FT_END_HEADER
 400.482 +
 400.483 +#endif /* __FTMODAPI_H__ */
 400.484 +
 400.485 +
 400.486 +/* END */
   401.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   401.2 +++ b/libs/ft2static/freetype/ftmoderr.h	Sat Feb 01 19:58:19 2014 +0200
   401.3 @@ -0,0 +1,155 @@
   401.4 +/***************************************************************************/
   401.5 +/*                                                                         */
   401.6 +/*  ftmoderr.h                                                             */
   401.7 +/*                                                                         */
   401.8 +/*    FreeType module error offsets (specification).                       */
   401.9 +/*                                                                         */
  401.10 +/*  Copyright 2001, 2002, 2003, 2004, 2005 by                              */
  401.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  401.12 +/*                                                                         */
  401.13 +/*  This file is part of the FreeType project, and may only be used,       */
  401.14 +/*  modified, and distributed under the terms of the FreeType project      */
  401.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  401.16 +/*  this file you indicate that you have read the license and              */
  401.17 +/*  understand and accept it fully.                                        */
  401.18 +/*                                                                         */
  401.19 +/***************************************************************************/
  401.20 +
  401.21 +
  401.22 +  /*************************************************************************/
  401.23 +  /*                                                                       */
  401.24 +  /* This file is used to define the FreeType module error offsets.        */
  401.25 +  /*                                                                       */
  401.26 +  /* The lower byte gives the error code, the higher byte gives the        */
  401.27 +  /* module.  The base module has error offset 0.  For example, the error  */
  401.28 +  /* `FT_Err_Invalid_File_Format' has value 0x003, the error               */
  401.29 +  /* `TT_Err_Invalid_File_Format' has value 0x1103, the error              */
  401.30 +  /* `T1_Err_Invalid_File_Format' has value 0x1203, etc.                   */
  401.31 +  /*                                                                       */
  401.32 +  /* Undefine the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in ftoption.h   */
  401.33 +  /* to make the higher byte always zero (disabling the module error       */
  401.34 +  /* mechanism).                                                           */
  401.35 +  /*                                                                       */
  401.36 +  /* It can also be used to create a module error message table easily     */
  401.37 +  /* with something like                                                   */
  401.38 +  /*                                                                       */
  401.39 +  /*   {                                                                   */
  401.40 +  /*     #undef __FTMODERR_H__                                             */
  401.41 +  /*     #define FT_MODERRDEF( e, v, s )  { FT_Mod_Err_ ## e, s },         */
  401.42 +  /*     #define FT_MODERR_START_LIST     {                                */
  401.43 +  /*     #define FT_MODERR_END_LIST       { 0, 0 } };                      */
  401.44 +  /*                                                                       */
  401.45 +  /*     const struct                                                      */
  401.46 +  /*     {                                                                 */
  401.47 +  /*       int          mod_err_offset;                                    */
  401.48 +  /*       const char*  mod_err_msg                                        */
  401.49 +  /*     } ft_mod_errors[] =                                               */
  401.50 +  /*                                                                       */
  401.51 +  /*     #include FT_MODULE_ERRORS_H                                       */
  401.52 +  /*   }                                                                   */
  401.53 +  /*                                                                       */
  401.54 +  /* To use such a table, all errors must be ANDed with 0xFF00 to remove   */
  401.55 +  /* the error code.                                                       */
  401.56 +  /*                                                                       */
  401.57 +  /*************************************************************************/
  401.58 +
  401.59 +
  401.60 +#ifndef __FTMODERR_H__
  401.61 +#define __FTMODERR_H__
  401.62 +
  401.63 +
  401.64 +  /*******************************************************************/
  401.65 +  /*******************************************************************/
  401.66 +  /*****                                                         *****/
  401.67 +  /*****                       SETUP MACROS                      *****/
  401.68 +  /*****                                                         *****/
  401.69 +  /*******************************************************************/
  401.70 +  /*******************************************************************/
  401.71 +
  401.72 +
  401.73 +#undef  FT_NEED_EXTERN_C
  401.74 +
  401.75 +#ifndef FT_MODERRDEF
  401.76 +
  401.77 +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS
  401.78 +#define FT_MODERRDEF( e, v, s )  FT_Mod_Err_ ## e = v,
  401.79 +#else
  401.80 +#define FT_MODERRDEF( e, v, s )  FT_Mod_Err_ ## e = 0,
  401.81 +#endif
  401.82 +
  401.83 +#define FT_MODERR_START_LIST  enum {
  401.84 +#define FT_MODERR_END_LIST    FT_Mod_Err_Max };
  401.85 +
  401.86 +#ifdef __cplusplus
  401.87 +#define FT_NEED_EXTERN_C
  401.88 +  extern "C" {
  401.89 +#endif
  401.90 +
  401.91 +#endif /* !FT_MODERRDEF */
  401.92 +
  401.93 +
  401.94 +  /*******************************************************************/
  401.95 +  /*******************************************************************/
  401.96 +  /*****                                                         *****/
  401.97 +  /*****               LIST MODULE ERROR BASES                   *****/
  401.98 +  /*****                                                         *****/
  401.99 +  /*******************************************************************/
 401.100 +  /*******************************************************************/
 401.101 +
 401.102 +
 401.103 +#ifdef FT_MODERR_START_LIST
 401.104 +  FT_MODERR_START_LIST
 401.105 +#endif
 401.106 +
 401.107 +
 401.108 +  FT_MODERRDEF( Base,      0x000, "base module" )
 401.109 +  FT_MODERRDEF( Autofit,   0x100, "autofitter module" )
 401.110 +  FT_MODERRDEF( BDF,       0x200, "BDF module" )
 401.111 +  FT_MODERRDEF( Cache,     0x300, "cache module" )
 401.112 +  FT_MODERRDEF( CFF,       0x400, "CFF module" )
 401.113 +  FT_MODERRDEF( CID,       0x500, "CID module" )
 401.114 +  FT_MODERRDEF( Gzip,      0x600, "Gzip module" )
 401.115 +  FT_MODERRDEF( LZW,       0x700, "LZW module" )
 401.116 +  FT_MODERRDEF( OTvalid,   0x800, "OpenType validation module" )
 401.117 +  FT_MODERRDEF( PCF,       0x900, "PCF module" )
 401.118 +  FT_MODERRDEF( PFR,       0xA00, "PFR module" )
 401.119 +  FT_MODERRDEF( PSaux,     0xB00, "PS auxiliary module" )
 401.120 +  FT_MODERRDEF( PShinter,  0xC00, "PS hinter module" )
 401.121 +  FT_MODERRDEF( PSnames,   0xD00, "PS names module" )
 401.122 +  FT_MODERRDEF( Raster,    0xE00, "raster module" )
 401.123 +  FT_MODERRDEF( SFNT,      0xF00, "SFNT module" )
 401.124 +  FT_MODERRDEF( Smooth,   0x1000, "smooth raster module" )
 401.125 +  FT_MODERRDEF( TrueType, 0x1100, "TrueType module" )
 401.126 +  FT_MODERRDEF( Type1,    0x1200, "Type 1 module" )
 401.127 +  FT_MODERRDEF( Type42,   0x1300, "Type 42 module" )
 401.128 +  FT_MODERRDEF( Winfonts, 0x1400, "Windows FON/FNT module" )
 401.129 +
 401.130 +
 401.131 +#ifdef FT_MODERR_END_LIST
 401.132 +  FT_MODERR_END_LIST
 401.133 +#endif
 401.134 +
 401.135 +
 401.136 +  /*******************************************************************/
 401.137 +  /*******************************************************************/
 401.138 +  /*****                                                         *****/
 401.139 +  /*****                      CLEANUP                            *****/
 401.140 +  /*****                                                         *****/
 401.141 +  /*******************************************************************/
 401.142 +  /*******************************************************************/
 401.143 +
 401.144 +
 401.145 +#ifdef FT_NEED_EXTERN_C
 401.146 +  }
 401.147 +#endif
 401.148 +
 401.149 +#undef FT_MODERR_START_LIST
 401.150 +#undef FT_MODERR_END_LIST
 401.151 +#undef FT_MODERRDEF
 401.152 +#undef FT_NEED_EXTERN_C
 401.153 +
 401.154 +
 401.155 +#endif /* __FTMODERR_H__ */
 401.156 +
 401.157 +
 401.158 +/* END */
   402.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   402.2 +++ b/libs/ft2static/freetype/ftotval.h	Sat Feb 01 19:58:19 2014 +0200
   402.3 @@ -0,0 +1,203 @@
   402.4 +/***************************************************************************/
   402.5 +/*                                                                         */
   402.6 +/*  ftotval.h                                                              */
   402.7 +/*                                                                         */
   402.8 +/*    FreeType API for validating OpenType tables (specification).         */
   402.9 +/*                                                                         */
  402.10 +/*  Copyright 2004, 2005, 2006, 2007 by                                    */
  402.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  402.12 +/*                                                                         */
  402.13 +/*  This file is part of the FreeType project, and may only be used,       */
  402.14 +/*  modified, and distributed under the terms of the FreeType project      */
  402.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  402.16 +/*  this file you indicate that you have read the license and              */
  402.17 +/*  understand and accept it fully.                                        */
  402.18 +/*                                                                         */
  402.19 +/***************************************************************************/
  402.20 +
  402.21 +
  402.22 +/***************************************************************************/
  402.23 +/*                                                                         */
  402.24 +/*                                                                         */
  402.25 +/* Warning: This module might be moved to a different library in the       */
  402.26 +/*          future to avoid a tight dependency between FreeType and the    */
  402.27 +/*          OpenType specification.                                        */
  402.28 +/*                                                                         */
  402.29 +/*                                                                         */
  402.30 +/***************************************************************************/
  402.31 +
  402.32 +
  402.33 +#ifndef __FTOTVAL_H__
  402.34 +#define __FTOTVAL_H__
  402.35 +
  402.36 +#include <ft2build.h>
  402.37 +#include FT_FREETYPE_H
  402.38 +
  402.39 +#ifdef FREETYPE_H
  402.40 +#error "freetype.h of FreeType 1 has been loaded!"
  402.41 +#error "Please fix the directory search order for header files"
  402.42 +#error "so that freetype.h of FreeType 2 is found first."
  402.43 +#endif
  402.44 +
  402.45 +
  402.46 +FT_BEGIN_HEADER
  402.47 +
  402.48 +
  402.49 +  /*************************************************************************/
  402.50 +  /*                                                                       */
  402.51 +  /* <Section>                                                             */
  402.52 +  /*    ot_validation                                                      */
  402.53 +  /*                                                                       */
  402.54 +  /* <Title>                                                               */
  402.55 +  /*    OpenType Validation                                                */
  402.56 +  /*                                                                       */
  402.57 +  /* <Abstract>                                                            */
  402.58 +  /*    An API to validate OpenType tables.                                */
  402.59 +  /*                                                                       */
  402.60 +  /* <Description>                                                         */
  402.61 +  /*    This section contains the declaration of functions to validate     */
  402.62 +  /*    some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH).         */
  402.63 +  /*                                                                       */
  402.64 +  /*************************************************************************/
  402.65 +
  402.66 +
  402.67 + /**********************************************************************
  402.68 +  *
  402.69 +  * @enum:
  402.70 +  *    FT_VALIDATE_OTXXX
  402.71 +  *
  402.72 +  * @description:
  402.73 +  *    A list of bit-field constants used with @FT_OpenType_Validate to
  402.74 +  *    indicate which OpenType tables should be validated.
  402.75 +  *
  402.76 +  * @values:
  402.77 +  *    FT_VALIDATE_BASE ::
  402.78 +  *      Validate BASE table.
  402.79 +  *
  402.80 +  *    FT_VALIDATE_GDEF ::
  402.81 +  *      Validate GDEF table.
  402.82 +  *
  402.83 +  *    FT_VALIDATE_GPOS ::
  402.84 +  *      Validate GPOS table.
  402.85 +  *
  402.86 +  *    FT_VALIDATE_GSUB ::
  402.87 +  *      Validate GSUB table.
  402.88 +  *
  402.89 +  *    FT_VALIDATE_JSTF ::
  402.90 +  *      Validate JSTF table.
  402.91 +  *
  402.92 +  *    FT_VALIDATE_MATH ::
  402.93 +  *      Validate MATH table.
  402.94 +  *
  402.95 +  *    FT_VALIDATE_OT ::
  402.96 +  *      Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH).
  402.97 +  *
  402.98 +  */
  402.99 +#define FT_VALIDATE_BASE  0x0100
 402.100 +#define FT_VALIDATE_GDEF  0x0200
 402.101 +#define FT_VALIDATE_GPOS  0x0400
 402.102 +#define FT_VALIDATE_GSUB  0x0800
 402.103 +#define FT_VALIDATE_JSTF  0x1000
 402.104 +#define FT_VALIDATE_MATH  0x2000
 402.105 +
 402.106 +#define FT_VALIDATE_OT  FT_VALIDATE_BASE | \
 402.107 +                        FT_VALIDATE_GDEF | \
 402.108 +                        FT_VALIDATE_GPOS | \
 402.109 +                        FT_VALIDATE_GSUB | \
 402.110 +                        FT_VALIDATE_JSTF | \
 402.111 +                        FT_VALIDATE_MATH
 402.112 +
 402.113 +  /* */
 402.114 +
 402.115 + /**********************************************************************
 402.116 +  *
 402.117 +  * @function:
 402.118 +  *    FT_OpenType_Validate
 402.119 +  *
 402.120 +  * @description:
 402.121 +  *    Validate various OpenType tables to assure that all offsets and
 402.122 +  *    indices are valid.  The idea is that a higher-level library which
 402.123 +  *    actually does the text layout can access those tables without
 402.124 +  *    error checking (which can be quite time consuming).
 402.125 +  *
 402.126 +  * @input:
 402.127 +  *    face ::
 402.128 +  *       A handle to the input face.
 402.129 +  *
 402.130 +  *    validation_flags ::
 402.131 +  *       A bit field which specifies the tables to be validated.  See
 402.132 +  *       @FT_VALIDATE_OTXXX for possible values.
 402.133 +  *
 402.134 +  * @output:
 402.135 +  *    BASE_table ::
 402.136 +  *       A pointer to the BASE table.
 402.137 +  *
 402.138 +  *    GDEF_table ::
 402.139 +  *       A pointer to the GDEF table.
 402.140 +  *
 402.141 +  *    GPOS_table ::
 402.142 +  *       A pointer to the GPOS table.
 402.143 +  *
 402.144 +  *    GSUB_table ::
 402.145 +  *       A pointer to the GSUB table.
 402.146 +  *
 402.147 +  *    JSTF_table ::
 402.148 +  *       A pointer to the JSTF table.
 402.149 +  *
 402.150 +  * @return:
 402.151 +  *   FreeType error code.  0~means success.
 402.152 +  *
 402.153 +  * @note:
 402.154 +  *   This function only works with OpenType fonts, returning an error
 402.155 +  *   otherwise.
 402.156 +  *
 402.157 +  *   After use, the application should deallocate the five tables with
 402.158 +  *   @FT_OpenType_Free.  A NULL value indicates that the table either
 402.159 +  *   doesn't exist in the font, or the application hasn't asked for
 402.160 +  *   validation.
 402.161 +  */
 402.162 +  FT_EXPORT( FT_Error )
 402.163 +  FT_OpenType_Validate( FT_Face    face,
 402.164 +                        FT_UInt    validation_flags,
 402.165 +                        FT_Bytes  *BASE_table,
 402.166 +                        FT_Bytes  *GDEF_table,
 402.167 +                        FT_Bytes  *GPOS_table,
 402.168 +                        FT_Bytes  *GSUB_table,
 402.169 +                        FT_Bytes  *JSTF_table );
 402.170 +
 402.171 +  /* */
 402.172 +
 402.173 + /**********************************************************************
 402.174 +  *
 402.175 +  * @function:
 402.176 +  *    FT_OpenType_Free
 402.177 +  *
 402.178 +  * @description:
 402.179 +  *    Free the buffer allocated by OpenType validator.
 402.180 +  *
 402.181 +  * @input:
 402.182 +  *    face ::
 402.183 +  *       A handle to the input face.
 402.184 +  *
 402.185 +  *    table ::
 402.186 +  *       The pointer to the buffer that is allocated by
 402.187 +  *       @FT_OpenType_Validate.
 402.188 +  *
 402.189 +  * @note:
 402.190 +  *   This function must be used to free the buffer allocated by
 402.191 +  *   @FT_OpenType_Validate only.
 402.192 +  */
 402.193 +  FT_EXPORT( void )
 402.194 +  FT_OpenType_Free( FT_Face   face,
 402.195 +                    FT_Bytes  table );
 402.196 +
 402.197 +
 402.198 + /* */
 402.199 +
 402.200 +
 402.201 +FT_END_HEADER
 402.202 +
 402.203 +#endif /* __FTOTVAL_H__ */
 402.204 +
 402.205 +
 402.206 +/* END */
   403.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   403.2 +++ b/libs/ft2static/freetype/ftoutln.h	Sat Feb 01 19:58:19 2014 +0200
   403.3 @@ -0,0 +1,537 @@
   403.4 +/***************************************************************************/
   403.5 +/*                                                                         */
   403.6 +/*  ftoutln.h                                                              */
   403.7 +/*                                                                         */
   403.8 +/*    Support for the FT_Outline type used to store glyph shapes of        */
   403.9 +/*    most scalable font formats (specification).                          */
  403.10 +/*                                                                         */
  403.11 +/*  Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 by */
  403.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  403.13 +/*                                                                         */
  403.14 +/*  This file is part of the FreeType project, and may only be used,       */
  403.15 +/*  modified, and distributed under the terms of the FreeType project      */
  403.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  403.17 +/*  this file you indicate that you have read the license and              */
  403.18 +/*  understand and accept it fully.                                        */
  403.19 +/*                                                                         */
  403.20 +/***************************************************************************/
  403.21 +
  403.22 +
  403.23 +#ifndef __FTOUTLN_H__
  403.24 +#define __FTOUTLN_H__
  403.25 +
  403.26 +
  403.27 +#include <ft2build.h>
  403.28 +#include FT_FREETYPE_H
  403.29 +
  403.30 +#ifdef FREETYPE_H
  403.31 +#error "freetype.h of FreeType 1 has been loaded!"
  403.32 +#error "Please fix the directory search order for header files"
  403.33 +#error "so that freetype.h of FreeType 2 is found first."
  403.34 +#endif
  403.35 +
  403.36 +
  403.37 +FT_BEGIN_HEADER
  403.38 +
  403.39 +
  403.40 +  /*************************************************************************/
  403.41 +  /*                                                                       */
  403.42 +  /* <Section>                                                             */
  403.43 +  /*    outline_processing                                                 */
  403.44 +  /*                                                                       */
  403.45 +  /* <Title>                                                               */
  403.46 +  /*    Outline Processing                                                 */
  403.47 +  /*                                                                       */
  403.48 +  /* <Abstract>                                                            */
  403.49 +  /*    Functions to create, transform, and render vectorial glyph images. */
  403.50 +  /*                                                                       */
  403.51 +  /* <Description>                                                         */
  403.52 +  /*    This section contains routines used to create and destroy scalable */
  403.53 +  /*    glyph images known as `outlines'.  These can also be measured,     */
  403.54 +  /*    transformed, and converted into bitmaps and pixmaps.               */
  403.55 +  /*                                                                       */
  403.56 +  /* <Order>                                                               */
  403.57 +  /*    FT_Outline                                                         */
  403.58 +  /*    FT_OUTLINE_FLAGS                                                   */
  403.59 +  /*    FT_Outline_New                                                     */
  403.60 +  /*    FT_Outline_Done                                                    */
  403.61 +  /*    FT_Outline_Copy                                                    */
  403.62 +  /*    FT_Outline_Translate                                               */
  403.63 +  /*    FT_Outline_Transform                                               */
  403.64 +  /*    FT_Outline_Embolden                                                */
  403.65 +  /*    FT_Outline_Reverse                                                 */
  403.66 +  /*    FT_Outline_Check                                                   */
  403.67 +  /*                                                                       */
  403.68 +  /*    FT_Outline_Get_CBox                                                */
  403.69 +  /*    FT_Outline_Get_BBox                                                */
  403.70 +  /*                                                                       */
  403.71 +  /*    FT_Outline_Get_Bitmap                                              */
  403.72 +  /*    FT_Outline_Render                                                  */
  403.73 +  /*                                                                       */
  403.74 +  /*    FT_Outline_Decompose                                               */
  403.75 +  /*    FT_Outline_Funcs                                                   */
  403.76 +  /*    FT_Outline_MoveTo_Func                                             */
  403.77 +  /*    FT_Outline_LineTo_Func                                             */
  403.78 +  /*    FT_Outline_ConicTo_Func                                            */
  403.79 +  /*    FT_Outline_CubicTo_Func                                            */
  403.80 +  /*                                                                       */
  403.81 +  /*************************************************************************/
  403.82 +
  403.83 +
  403.84 +  /*************************************************************************/
  403.85 +  /*                                                                       */
  403.86 +  /* <Function>                                                            */
  403.87 +  /*    FT_Outline_Decompose                                               */
  403.88 +  /*                                                                       */
  403.89 +  /* <Description>                                                         */
  403.90 +  /*    Walk over an outline's structure to decompose it into individual   */
  403.91 +  /*    segments and Bézier arcs.  This function also emits `move to'      */
  403.92 +  /*    operations to indicate the start of new contours in the outline.   */
  403.93 +  /*                                                                       */
  403.94 +  /* <Input>                                                               */
  403.95 +  /*    outline        :: A pointer to the source target.                  */
  403.96 +  /*                                                                       */
  403.97 +  /*    func_interface :: A table of `emitters', i.e., function pointers   */
  403.98 +  /*                      called during decomposition to indicate path     */
  403.99 +  /*                      operations.                                      */
 403.100 +  /*                                                                       */
 403.101 +  /* <InOut>                                                               */
 403.102 +  /*    user           :: A typeless pointer which is passed to each       */
 403.103 +  /*                      emitter during the decomposition.  It can be     */
 403.104 +  /*                      used to store the state during the               */
 403.105 +  /*                      decomposition.                                   */
 403.106 +  /*                                                                       */
 403.107 +  /* <Return>                                                              */
 403.108 +  /*    FreeType error code.  0~means success.                             */
 403.109 +  /*                                                                       */
 403.110 +  FT_EXPORT( FT_Error )
 403.111 +  FT_Outline_Decompose( FT_Outline*              outline,
 403.112 +                        const FT_Outline_Funcs*  func_interface,
 403.113 +                        void*                    user );
 403.114 +
 403.115 +
 403.116 +  /*************************************************************************/
 403.117 +  /*                                                                       */
 403.118 +  /* <Function>                                                            */
 403.119 +  /*    FT_Outline_New                                                     */
 403.120 +  /*                                                                       */
 403.121 +  /* <Description>                                                         */
 403.122 +  /*    Create a new outline of a given size.                              */
 403.123 +  /*                                                                       */
 403.124 +  /* <Input>                                                               */
 403.125 +  /*    library     :: A handle to the library object from where the       */
 403.126 +  /*                   outline is allocated.  Note however that the new    */
 403.127 +  /*                   outline will *not* necessarily be *freed*, when     */
 403.128 +  /*                   destroying the library, by @FT_Done_FreeType.       */
 403.129 +  /*                                                                       */
 403.130 +  /*    numPoints   :: The maximal number of points within the outline.    */
 403.131 +  /*                                                                       */
 403.132 +  /*    numContours :: The maximal number of contours within the outline.  */
 403.133 +  /*                                                                       */
 403.134 +  /* <Output>                                                              */
 403.135 +  /*    anoutline   :: A handle to the new outline.                        */
 403.136 +  /*                                                                       */
 403.137 +  /* <Return>                                                              */
 403.138 +  /*    FreeType error code.  0~means success.                             */
 403.139 +  /*                                                                       */
 403.140 +  /* <Note>                                                                */
 403.141 +  /*    The reason why this function takes a `library' parameter is simply */
 403.142 +  /*    to use the library's memory allocator.                             */
 403.143 +  /*                                                                       */
 403.144 +  FT_EXPORT( FT_Error )
 403.145 +  FT_Outline_New( FT_Library   library,
 403.146 +                  FT_UInt      numPoints,
 403.147 +                  FT_Int       numContours,
 403.148 +                  FT_Outline  *anoutline );
 403.149 +
 403.150 +
 403.151 +  FT_EXPORT( FT_Error )
 403.152 +  FT_Outline_New_Internal( FT_Memory    memory,
 403.153 +                           FT_UInt      numPoints,
 403.154 +                           FT_Int       numContours,
 403.155 +                           FT_Outline  *anoutline );
 403.156 +
 403.157 +
 403.158 +  /*************************************************************************/
 403.159 +  /*                                                                       */
 403.160 +  /* <Function>                                                            */
 403.161 +  /*    FT_Outline_Done                                                    */
 403.162 +  /*                                                                       */
 403.163 +  /* <Description>                                                         */
 403.164 +  /*    Destroy an outline created with @FT_Outline_New.                   */
 403.165 +  /*                                                                       */
 403.166 +  /* <Input>                                                               */
 403.167 +  /*    library :: A handle of the library object used to allocate the     */
 403.168 +  /*               outline.                                                */
 403.169 +  /*                                                                       */
 403.170 +  /*    outline :: A pointer to the outline object to be discarded.        */
 403.171 +  /*                                                                       */
 403.172 +  /* <Return>                                                              */
 403.173 +  /*    FreeType error code.  0~means success.                             */
 403.174 +  /*                                                                       */
 403.175 +  /* <Note>                                                                */
 403.176 +  /*    If the outline's `owner' field is not set, only the outline        */
 403.177 +  /*    descriptor will be released.                                       */
 403.178 +  /*                                                                       */
 403.179 +  /*    The reason why this function takes an `library' parameter is       */
 403.180 +  /*    simply to use ft_mem_free().                                       */
 403.181 +  /*                                                                       */
 403.182 +  FT_EXPORT( FT_Error )
 403.183 +  FT_Outline_Done( FT_Library   library,
 403.184 +                   FT_Outline*  outline );
 403.185 +
 403.186 +
 403.187 +  FT_EXPORT( FT_Error )
 403.188 +  FT_Outline_Done_Internal( FT_Memory    memory,
 403.189 +                            FT_Outline*  outline );
 403.190 +
 403.191 +
 403.192 +  /*************************************************************************/
 403.193 +  /*                                                                       */
 403.194 +  /* <Function>                                                            */
 403.195 +  /*    FT_Outline_Check                                                   */
 403.196 +  /*                                                                       */
 403.197 +  /* <Description>                                                         */
 403.198 +  /*    Check the contents of an outline descriptor.                       */
 403.199 +  /*                                                                       */
 403.200 +  /* <Input>                                                               */
 403.201 +  /*    outline :: A handle to a source outline.                           */
 403.202 +  /*                                                                       */
 403.203 +  /* <Return>                                                              */
 403.204 +  /*    FreeType error code.  0~means success.                             */
 403.205 +  /*                                                                       */
 403.206 +  FT_EXPORT( FT_Error )
 403.207 +  FT_Outline_Check( FT_Outline*  outline );
 403.208 +
 403.209 +
 403.210 +  /*************************************************************************/
 403.211 +  /*                                                                       */
 403.212 +  /* <Function>                                                            */
 403.213 +  /*    FT_Outline_Get_CBox                                                */
 403.214 +  /*                                                                       */
 403.215 +  /* <Description>                                                         */
 403.216 +  /*    Return an outline's `control box'.  The control box encloses all   */
 403.217 +  /*    the outline's points, including Bézier control points.  Though it  */
 403.218 +  /*    coincides with the exact bounding box for most glyphs, it can be   */
 403.219 +  /*    slightly larger in some situations (like when rotating an outline  */
 403.220 +  /*    which contains Bézier outside arcs).                               */
 403.221 +  /*                                                                       */
 403.222 +  /*    Computing the control box is very fast, while getting the bounding */
 403.223 +  /*    box can take much more time as it needs to walk over all segments  */
 403.224 +  /*    and arcs in the outline.  To get the latter, you can use the       */
 403.225 +  /*    `ftbbox' component which is dedicated to this single task.         */
 403.226 +  /*                                                                       */
 403.227 +  /* <Input>                                                               */
 403.228 +  /*    outline :: A pointer to the source outline descriptor.             */
 403.229 +  /*                                                                       */
 403.230 +  /* <Output>                                                              */
 403.231 +  /*    acbox   :: The outline's control box.                              */
 403.232 +  /*                                                                       */
 403.233 +  FT_EXPORT( void )
 403.234 +  FT_Outline_Get_CBox( const FT_Outline*  outline,
 403.235 +                       FT_BBox           *acbox );
 403.236 +
 403.237 +
 403.238 +  /*************************************************************************/
 403.239 +  /*                                                                       */
 403.240 +  /* <Function>                                                            */
 403.241 +  /*    FT_Outline_Translate                                               */
 403.242 +  /*                                                                       */
 403.243 +  /* <Description>                                                         */
 403.244 +  /*    Apply a simple translation to the points of an outline.            */
 403.245 +  /*                                                                       */
 403.246 +  /* <InOut>                                                               */
 403.247 +  /*    outline :: A pointer to the target outline descriptor.             */
 403.248 +  /*                                                                       */
 403.249 +  /* <Input>                                                               */
 403.250 +  /*    xOffset :: The horizontal offset.                                  */
 403.251 +  /*                                                                       */
 403.252 +  /*    yOffset :: The vertical offset.                                    */
 403.253 +  /*                                                                       */
 403.254 +  FT_EXPORT( void )
 403.255 +  FT_Outline_Translate( const FT_Outline*  outline,
 403.256 +                        FT_Pos             xOffset,
 403.257 +                        FT_Pos             yOffset );
 403.258 +
 403.259 +
 403.260 +  /*************************************************************************/
 403.261 +  /*                                                                       */
 403.262 +  /* <Function>                                                            */
 403.263 +  /*    FT_Outline_Copy                                                    */
 403.264 +  /*                                                                       */
 403.265 +  /* <Description>                                                         */
 403.266 +  /*    Copy an outline into another one.  Both objects must have the      */
 403.267 +  /*    same sizes (number of points & number of contours) when this       */
 403.268 +  /*    function is called.                                                */
 403.269 +  /*                                                                       */
 403.270 +  /* <Input>                                                               */
 403.271 +  /*    source :: A handle to the source outline.                          */
 403.272 +  /*                                                                       */
 403.273 +  /* <Output>                                                              */
 403.274 +  /*    target :: A handle to the target outline.                          */
 403.275 +  /*                                                                       */
 403.276 +  /* <Return>                                                              */
 403.277 +  /*    FreeType error code.  0~means success.                             */
 403.278 +  /*                                                                       */
 403.279 +  FT_EXPORT( FT_Error )
 403.280 +  FT_Outline_Copy( const FT_Outline*  source,
 403.281 +                   FT_Outline        *target );
 403.282 +
 403.283 +
 403.284 +  /*************************************************************************/
 403.285 +  /*                                                                       */
 403.286 +  /* <Function>                                                            */
 403.287 +  /*    FT_Outline_Transform                                               */
 403.288 +  /*                                                                       */
 403.289 +  /* <Description>                                                         */
 403.290 +  /*    Apply a simple 2x2 matrix to all of an outline's points.  Useful   */
 403.291 +  /*    for applying rotations, slanting, flipping, etc.                   */
 403.292 +  /*                                                                       */
 403.293 +  /* <InOut>                                                               */
 403.294 +  /*    outline :: A pointer to the target outline descriptor.             */
 403.295 +  /*                                                                       */
 403.296 +  /* <Input>                                                               */
 403.297 +  /*    matrix  :: A pointer to the transformation matrix.                 */
 403.298 +  /*                                                                       */
 403.299 +  /* <Note>                                                                */
 403.300 +  /*    You can use @FT_Outline_Translate if you need to translate the     */
 403.301 +  /*    outline's points.                                                  */
 403.302 +  /*                                                                       */
 403.303 +  FT_EXPORT( void )
 403.304 +  FT_Outline_Transform( const FT_Outline*  outline,
 403.305 +                        const FT_Matrix*   matrix );
 403.306 +
 403.307 +
 403.308 +  /*************************************************************************/
 403.309 +  /*                                                                       */
 403.310 +  /* <Function>                                                            */
 403.311 +  /*    FT_Outline_Embolden                                                */
 403.312 +  /*                                                                       */
 403.313 +  /* <Description>                                                         */
 403.314 +  /*    Embolden an outline.  The new outline will be at most 4~times      */
 403.315 +  /*    `strength' pixels wider and higher.  You may think of the left and */
 403.316 +  /*    bottom borders as unchanged.                                       */
 403.317 +  /*                                                                       */
 403.318 +  /*    Negative `strength' values to reduce the outline thickness are     */
 403.319 +  /*    possible also.                                                     */
 403.320 +  /*                                                                       */
 403.321 +  /* <InOut>                                                               */
 403.322 +  /*    outline  :: A handle to the target outline.                        */
 403.323 +  /*                                                                       */
 403.324 +  /* <Input>                                                               */
 403.325 +  /*    strength :: How strong the glyph is emboldened.  Expressed in      */
 403.326 +  /*                26.6 pixel format.                                     */
 403.327 +  /*                                                                       */
 403.328 +  /* <Return>                                                              */
 403.329 +  /*    FreeType error code.  0~means success.                             */
 403.330 +  /*                                                                       */
 403.331 +  /* <Note>                                                                */
 403.332 +  /*    The used algorithm to increase or decrease the thickness of the    */
 403.333 +  /*    glyph doesn't change the number of points; this means that certain */
 403.334 +  /*    situations like acute angles or intersections are sometimes        */
 403.335 +  /*    handled incorrectly.                                               */
 403.336 +  /*                                                                       */
 403.337 +  /*    If you need `better' metrics values you should call                */
 403.338 +  /*    @FT_Outline_Get_CBox ot @FT_Outline_Get_BBox.                      */
 403.339 +  /*                                                                       */
 403.340 +  /*    Example call:                                                      */
 403.341 +  /*                                                                       */
 403.342 +  /*    {                                                                  */
 403.343 +  /*      FT_Load_Glyph( face, index, FT_LOAD_DEFAULT );                   */
 403.344 +  /*      if ( face->slot->format == FT_GLYPH_FORMAT_OUTLINE )             */
 403.345 +  /*        FT_Outline_Embolden( &face->slot->outline, strength );         */
 403.346 +  /*    }                                                                  */
 403.347 +  /*                                                                       */
 403.348 +  FT_EXPORT( FT_Error )
 403.349 +  FT_Outline_Embolden( FT_Outline*  outline,
 403.350 +                       FT_Pos       strength );
 403.351 +
 403.352 +
 403.353 +  /*************************************************************************/
 403.354 +  /*                                                                       */
 403.355 +  /* <Function>                                                            */
 403.356 +  /*    FT_Outline_Reverse                                                 */
 403.357 +  /*                                                                       */
 403.358 +  /* <Description>                                                         */
 403.359 +  /*    Reverse the drawing direction of an outline.  This is used to      */
 403.360 +  /*    ensure consistent fill conventions for mirrored glyphs.            */
 403.361 +  /*                                                                       */
 403.362 +  /* <InOut>                                                               */
 403.363 +  /*    outline :: A pointer to the target outline descriptor.             */
 403.364 +  /*                                                                       */
 403.365 +  /* <Note>                                                                */
 403.366 +  /*    This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in     */
 403.367 +  /*    the outline's `flags' field.                                       */
 403.368 +  /*                                                                       */
 403.369 +  /*    It shouldn't be used by a normal client application, unless it     */
 403.370 +  /*    knows what it is doing.                                            */
 403.371 +  /*                                                                       */
 403.372 +  FT_EXPORT( void )
 403.373 +  FT_Outline_Reverse( FT_Outline*  outline );
 403.374 +
 403.375 +
 403.376 +  /*************************************************************************/
 403.377 +  /*                                                                       */
 403.378 +  /* <Function>                                                            */
 403.379 +  /*    FT_Outline_Get_Bitmap                                              */
 403.380 +  /*                                                                       */
 403.381 +  /* <Description>                                                         */
 403.382 +  /*    Render an outline within a bitmap.  The outline's image is simply  */
 403.383 +  /*    OR-ed to the target bitmap.                                        */
 403.384 +  /*                                                                       */
 403.385 +  /* <Input>                                                               */
 403.386 +  /*    library :: A handle to a FreeType library object.                  */
 403.387 +  /*                                                                       */
 403.388 +  /*    outline :: A pointer to the source outline descriptor.             */
 403.389 +  /*                                                                       */
 403.390 +  /* <InOut>                                                               */
 403.391 +  /*    abitmap :: A pointer to the target bitmap descriptor.              */
 403.392 +  /*                                                                       */
 403.393 +  /* <Return>                                                              */
 403.394 +  /*    FreeType error code.  0~means success.                             */
 403.395 +  /*                                                                       */
 403.396 +  /* <Note>                                                                */
 403.397 +  /*    This function does NOT CREATE the bitmap, it only renders an       */
 403.398 +  /*    outline image within the one you pass to it!  Consequently, the    */
 403.399 +  /*    various fields in `abitmap' should be set accordingly.             */
 403.400 +  /*                                                                       */
 403.401 +  /*    It will use the raster corresponding to the default glyph format.  */
 403.402 +  /*                                                                       */
 403.403 +  /*    The value of the `num_grays' field in `abitmap' is ignored.  If    */
 403.404 +  /*    you select the gray-level rasterizer, and you want less than 256   */
 403.405 +  /*    gray levels, you have to use @FT_Outline_Render directly.          */
 403.406 +  /*                                                                       */
 403.407 +  FT_EXPORT( FT_Error )
 403.408 +  FT_Outline_Get_Bitmap( FT_Library        library,
 403.409 +                         FT_Outline*       outline,
 403.410 +                         const FT_Bitmap  *abitmap );
 403.411 +
 403.412 +
 403.413 +  /*************************************************************************/
 403.414 +  /*                                                                       */
 403.415 +  /* <Function>                                                            */
 403.416 +  /*    FT_Outline_Render                                                  */
 403.417 +  /*                                                                       */
 403.418 +  /* <Description>                                                         */
 403.419 +  /*    Render an outline within a bitmap using the current scan-convert.  */
 403.420 +  /*    This function uses an @FT_Raster_Params structure as an argument,  */
 403.421 +  /*    allowing advanced features like direct composition, translucency,  */
 403.422 +  /*    etc.                                                               */
 403.423 +  /*                                                                       */
 403.424 +  /* <Input>                                                               */
 403.425 +  /*    library :: A handle to a FreeType library object.                  */
 403.426 +  /*                                                                       */
 403.427 +  /*    outline :: A pointer to the source outline descriptor.             */
 403.428 +  /*                                                                       */
 403.429 +  /* <InOut>                                                               */
 403.430 +  /*    params  :: A pointer to an @FT_Raster_Params structure used to     */
 403.431 +  /*               describe the rendering operation.                       */
 403.432 +  /*                                                                       */
 403.433 +  /* <Return>                                                              */
 403.434 +  /*    FreeType error code.  0~means success.                             */
 403.435 +  /*                                                                       */
 403.436 +  /* <Note>                                                                */
 403.437 +  /*    You should know what you are doing and how @FT_Raster_Params works */
 403.438 +  /*    to use this function.                                              */
 403.439 +  /*                                                                       */
 403.440 +  /*    The field `params.source' will be set to `outline' before the scan */
 403.441 +  /*    converter is called, which means that the value you give to it is  */
 403.442 +  /*    actually ignored.                                                  */
 403.443 +  /*                                                                       */
 403.444 +  /*    The gray-level rasterizer always uses 256 gray levels.  If you     */
 403.445 +  /*    want less gray levels, you have to provide your own span callback. */
 403.446 +  /*    See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the   */
 403.447 +  /*    @FT_Raster_Params structure for more details.                      */
 403.448 +  /*                                                                       */
 403.449 +  FT_EXPORT( FT_Error )
 403.450 +  FT_Outline_Render( FT_Library         library,
 403.451 +                     FT_Outline*        outline,
 403.452 +                     FT_Raster_Params*  params );
 403.453 +
 403.454 +
 403.455 + /**************************************************************************
 403.456 +  *
 403.457 +  * @enum:
 403.458 +  *   FT_Orientation
 403.459 +  *
 403.460 +  * @description:
 403.461 +  *   A list of values used to describe an outline's contour orientation.
 403.462 +  *
 403.463 +  *   The TrueType and PostScript specifications use different conventions
 403.464 +  *   to determine whether outline contours should be filled or unfilled.
 403.465 +  *
 403.466 +  * @values:
 403.467 +  *   FT_ORIENTATION_TRUETYPE ::
 403.468 +  *     According to the TrueType specification, clockwise contours must
 403.469 +  *     be filled, and counter-clockwise ones must be unfilled.
 403.470 +  *
 403.471 +  *   FT_ORIENTATION_POSTSCRIPT ::
 403.472 +  *     According to the PostScript specification, counter-clockwise contours
 403.473 +  *     must be filled, and clockwise ones must be unfilled.
 403.474 +  *
 403.475 +  *   FT_ORIENTATION_FILL_RIGHT ::
 403.476 +  *     This is identical to @FT_ORIENTATION_TRUETYPE, but is used to
 403.477 +  *     remember that in TrueType, everything that is to the right of
 403.478 +  *     the drawing direction of a contour must be filled.
 403.479 +  *
 403.480 +  *   FT_ORIENTATION_FILL_LEFT ::
 403.481 +  *     This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to
 403.482 +  *     remember that in PostScript, everything that is to the left of
 403.483 +  *     the drawing direction of a contour must be filled.
 403.484 +  *
 403.485 +  *   FT_ORIENTATION_NONE ::
 403.486 +  *     The orientation cannot be determined.  That is, different parts of
 403.487 +  *     the glyph have different orientation.
 403.488 +  *
 403.489 +  */
 403.490 +  typedef enum  FT_Orientation_
 403.491 +  {
 403.492 +    FT_ORIENTATION_TRUETYPE   = 0,
 403.493 +    FT_ORIENTATION_POSTSCRIPT = 1,
 403.494 +    FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE,
 403.495 +    FT_ORIENTATION_FILL_LEFT  = FT_ORIENTATION_POSTSCRIPT,
 403.496 +    FT_ORIENTATION_NONE
 403.497 +
 403.498 +  } FT_Orientation;
 403.499 +
 403.500 +
 403.501 + /**************************************************************************
 403.502 +  *
 403.503 +  * @function:
 403.504 +  *   FT_Outline_Get_Orientation
 403.505 +  *
 403.506 +  * @description:
 403.507 +  *   This function analyzes a glyph outline and tries to compute its
 403.508 +  *   fill orientation (see @FT_Orientation).  This is done by computing
 403.509 +  *   the direction of each global horizontal and/or vertical extrema
 403.510 +  *   within the outline.
 403.511 +  *
 403.512 +  *   Note that this will return @FT_ORIENTATION_TRUETYPE for empty
 403.513 +  *   outlines.
 403.514 +  *
 403.515 +  * @input:
 403.516 +  *   outline ::
 403.517 +  *     A handle to the source outline.
 403.518 +  *
 403.519 +  * @return:
 403.520 +  *   The orientation.
 403.521 +  *
 403.522 +  */
 403.523 +  FT_EXPORT( FT_Orientation )
 403.524 +  FT_Outline_Get_Orientation( FT_Outline*  outline );
 403.525 +
 403.526 +
 403.527 +  /* */
 403.528 +
 403.529 +
 403.530 +FT_END_HEADER
 403.531 +
 403.532 +#endif /* __FTOUTLN_H__ */
 403.533 +
 403.534 +
 403.535 +/* END */
 403.536 +
 403.537 +
 403.538 +/* Local Variables: */
 403.539 +/* coding: utf-8    */
 403.540 +/* End:             */
   404.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   404.2 +++ b/libs/ft2static/freetype/ftpfr.h	Sat Feb 01 19:58:19 2014 +0200
   404.3 @@ -0,0 +1,172 @@
   404.4 +/***************************************************************************/
   404.5 +/*                                                                         */
   404.6 +/*  ftpfr.h                                                                */
   404.7 +/*                                                                         */
   404.8 +/*    FreeType API for accessing PFR-specific data (specification only).   */
   404.9 +/*                                                                         */
  404.10 +/*  Copyright 2002, 2003, 2004, 2006, 2008, 2009 by                        */
  404.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  404.12 +/*                                                                         */
  404.13 +/*  This file is part of the FreeType project, and may only be used,       */
  404.14 +/*  modified, and distributed under the terms of the FreeType project      */
  404.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  404.16 +/*  this file you indicate that you have read the license and              */
  404.17 +/*  understand and accept it fully.                                        */
  404.18 +/*                                                                         */
  404.19 +/***************************************************************************/
  404.20 +
  404.21 +
  404.22 +#ifndef __FTPFR_H__
  404.23 +#define __FTPFR_H__
  404.24 +
  404.25 +#include <ft2build.h>
  404.26 +#include FT_FREETYPE_H
  404.27 +
  404.28 +#ifdef FREETYPE_H
  404.29 +#error "freetype.h of FreeType 1 has been loaded!"
  404.30 +#error "Please fix the directory search order for header files"
  404.31 +#error "so that freetype.h of FreeType 2 is found first."
  404.32 +#endif
  404.33 +
  404.34 +
  404.35 +FT_BEGIN_HEADER
  404.36 +
  404.37 +
  404.38 +  /*************************************************************************/
  404.39 +  /*                                                                       */
  404.40 +  /* <Section>                                                             */
  404.41 +  /*    pfr_fonts                                                          */
  404.42 +  /*                                                                       */
  404.43 +  /* <Title>                                                               */
  404.44 +  /*    PFR Fonts                                                          */
  404.45 +  /*                                                                       */
  404.46 +  /* <Abstract>                                                            */
  404.47 +  /*    PFR/TrueDoc specific API.                                          */
  404.48 +  /*                                                                       */
  404.49 +  /* <Description>                                                         */
  404.50 +  /*    This section contains the declaration of PFR-specific functions.   */
  404.51 +  /*                                                                       */
  404.52 +  /*************************************************************************/
  404.53 +
  404.54 +
  404.55 + /**********************************************************************
  404.56 +  *
  404.57 +  * @function:
  404.58 +  *    FT_Get_PFR_Metrics
  404.59 +  *
  404.60 +  * @description:
  404.61 +  *    Return the outline and metrics resolutions of a given PFR face.
  404.62 +  *
  404.63 +  * @input:
  404.64 +  *    face :: Handle to the input face.  It can be a non-PFR face.
  404.65 +  *
  404.66 +  * @output:
  404.67 +  *    aoutline_resolution ::
  404.68 +  *      Outline resolution.  This is equivalent to `face->units_per_EM'
  404.69 +  *      for non-PFR fonts.  Optional (parameter can be NULL).
  404.70 +  *
  404.71 +  *    ametrics_resolution ::
  404.72 +  *      Metrics resolution.  This is equivalent to `outline_resolution'
  404.73 +  *      for non-PFR fonts.  Optional (parameter can be NULL).
  404.74 +  *
  404.75 +  *    ametrics_x_scale ::
  404.76 +  *      A 16.16 fixed-point number used to scale distance expressed
  404.77 +  *      in metrics units to device sub-pixels.  This is equivalent to
  404.78 +  *      `face->size->x_scale', but for metrics only.  Optional (parameter
  404.79 +  *      can be NULL).
  404.80 +  *
  404.81 +  *    ametrics_y_scale ::
  404.82 +  *      Same as `ametrics_x_scale' but for the vertical direction.
  404.83 +  *      optional (parameter can be NULL).
  404.84 +  *
  404.85 +  * @return:
  404.86 +  *    FreeType error code.  0~means success.
  404.87 +  *
  404.88 +  * @note:
  404.89 +  *   If the input face is not a PFR, this function will return an error.
  404.90 +  *   However, in all cases, it will return valid values.
  404.91 +  */
  404.92 +  FT_EXPORT( FT_Error )
  404.93 +  FT_Get_PFR_Metrics( FT_Face    face,
  404.94 +                      FT_UInt   *aoutline_resolution,
  404.95 +                      FT_UInt   *ametrics_resolution,
  404.96 +                      FT_Fixed  *ametrics_x_scale,
  404.97 +                      FT_Fixed  *ametrics_y_scale );
  404.98 +
  404.99 +
 404.100 + /**********************************************************************
 404.101 +  *
 404.102 +  * @function:
 404.103 +  *    FT_Get_PFR_Kerning
 404.104 +  *
 404.105 +  * @description:
 404.106 +  *    Return the kerning pair corresponding to two glyphs in a PFR face.
 404.107 +  *    The distance is expressed in metrics units, unlike the result of
 404.108 +  *    @FT_Get_Kerning.
 404.109 +  *
 404.110 +  * @input:
 404.111 +  *    face  :: A handle to the input face.
 404.112 +  *
 404.113 +  *    left  :: Index of the left glyph.
 404.114 +  *
 404.115 +  *    right :: Index of the right glyph.
 404.116 +  *
 404.117 +  * @output:
 404.118 +  *    avector :: A kerning vector.
 404.119 +  *
 404.120 +  * @return:
 404.121 +  *    FreeType error code.  0~means success.
 404.122 +  *
 404.123 +  * @note:
 404.124 +  *    This function always return distances in original PFR metrics
 404.125 +  *    units.  This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED
 404.126 +  *    mode, which always returns distances converted to outline units.
 404.127 +  *
 404.128 +  *    You can use the value of the `x_scale' and `y_scale' parameters
 404.129 +  *    returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels.
 404.130 +  */
 404.131 +  FT_EXPORT( FT_Error )
 404.132 +  FT_Get_PFR_Kerning( FT_Face     face,
 404.133 +                      FT_UInt     left,
 404.134 +                      FT_UInt     right,
 404.135 +                      FT_Vector  *avector );
 404.136 +
 404.137 +
 404.138 + /**********************************************************************
 404.139 +  *
 404.140 +  * @function:
 404.141 +  *    FT_Get_PFR_Advance
 404.142 +  *
 404.143 +  * @description:
 404.144 +  *    Return a given glyph advance, expressed in original metrics units,
 404.145 +  *    from a PFR font.
 404.146 +  *
 404.147 +  * @input:
 404.148 +  *    face   :: A handle to the input face.
 404.149 +  *
 404.150 +  *    gindex :: The glyph index.
 404.151 +  *
 404.152 +  * @output:
 404.153 +  *    aadvance :: The glyph advance in metrics units.
 404.154 +  *
 404.155 +  * @return:
 404.156 +  *    FreeType error code.  0~means success.
 404.157 +  *
 404.158 +  * @note:
 404.159 +  *    You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics
 404.160 +  *    to convert the advance to device sub-pixels (i.e., 1/64th of pixels).
 404.161 +  */
 404.162 +  FT_EXPORT( FT_Error )
 404.163 +  FT_Get_PFR_Advance( FT_Face   face,
 404.164 +                      FT_UInt   gindex,
 404.165 +                      FT_Pos   *aadvance );
 404.166 +
 404.167 + /* */
 404.168 +
 404.169 +
 404.170 +FT_END_HEADER
 404.171 +
 404.172 +#endif /* __FTPFR_H__ */
 404.173 +
 404.174 +
 404.175 +/* END */
   405.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   405.2 +++ b/libs/ft2static/freetype/ftrender.h	Sat Feb 01 19:58:19 2014 +0200
   405.3 @@ -0,0 +1,230 @@
   405.4 +/***************************************************************************/
   405.5 +/*                                                                         */
   405.6 +/*  ftrender.h                                                             */
   405.7 +/*                                                                         */
   405.8 +/*    FreeType renderer modules public interface (specification).          */
   405.9 +/*                                                                         */
  405.10 +/*  Copyright 1996-2001, 2005, 2006, 2010 by                               */
  405.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  405.12 +/*                                                                         */
  405.13 +/*  This file is part of the FreeType project, and may only be used,       */
  405.14 +/*  modified, and distributed under the terms of the FreeType project      */
  405.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  405.16 +/*  this file you indicate that you have read the license and              */
  405.17 +/*  understand and accept it fully.                                        */
  405.18 +/*                                                                         */
  405.19 +/***************************************************************************/
  405.20 +
  405.21 +
  405.22 +#ifndef __FTRENDER_H__
  405.23 +#define __FTRENDER_H__
  405.24 +
  405.25 +
  405.26 +#include <ft2build.h>
  405.27 +#include FT_MODULE_H
  405.28 +#include FT_GLYPH_H
  405.29 +
  405.30 +
  405.31 +FT_BEGIN_HEADER
  405.32 +
  405.33 +
  405.34 +  /*************************************************************************/
  405.35 +  /*                                                                       */
  405.36 +  /* <Section>                                                             */
  405.37 +  /*    module_management                                                  */
  405.38 +  /*                                                                       */
  405.39 +  /*************************************************************************/
  405.40 +
  405.41 +
  405.42 +  /* create a new glyph object */
  405.43 +  typedef FT_Error
  405.44 +  (*FT_Glyph_InitFunc)( FT_Glyph      glyph,
  405.45 +                        FT_GlyphSlot  slot );
  405.46 +
  405.47 +  /* destroys a given glyph object */
  405.48 +  typedef void
  405.49 +  (*FT_Glyph_DoneFunc)( FT_Glyph  glyph );
  405.50 +
  405.51 +  typedef void
  405.52 +  (*FT_Glyph_TransformFunc)( FT_Glyph          glyph,
  405.53 +                             const FT_Matrix*  matrix,
  405.54 +                             const FT_Vector*  delta );
  405.55 +
  405.56 +  typedef void
  405.57 +  (*FT_Glyph_GetBBoxFunc)( FT_Glyph  glyph,
  405.58 +                           FT_BBox*  abbox );
  405.59 +
  405.60 +  typedef FT_Error
  405.61 +  (*FT_Glyph_CopyFunc)( FT_Glyph   source,
  405.62 +                        FT_Glyph   target );
  405.63 +
  405.64 +  typedef FT_Error
  405.65 +  (*FT_Glyph_PrepareFunc)( FT_Glyph      glyph,
  405.66 +                           FT_GlyphSlot  slot );
  405.67 +
  405.68 +/* deprecated */
  405.69 +#define FT_Glyph_Init_Func       FT_Glyph_InitFunc
  405.70 +#define FT_Glyph_Done_Func       FT_Glyph_DoneFunc
  405.71 +#define FT_Glyph_Transform_Func  FT_Glyph_TransformFunc
  405.72 +#define FT_Glyph_BBox_Func       FT_Glyph_GetBBoxFunc
  405.73 +#define FT_Glyph_Copy_Func       FT_Glyph_CopyFunc
  405.74 +#define FT_Glyph_Prepare_Func    FT_Glyph_PrepareFunc
  405.75 +
  405.76 +
  405.77 +  struct  FT_Glyph_Class_
  405.78 +  {
  405.79 +    FT_Long                 glyph_size;
  405.80 +    FT_Glyph_Format         glyph_format;
  405.81 +    FT_Glyph_InitFunc       glyph_init;
  405.82 +    FT_Glyph_DoneFunc       glyph_done;
  405.83 +    FT_Glyph_CopyFunc       glyph_copy;
  405.84 +    FT_Glyph_TransformFunc  glyph_transform;
  405.85 +    FT_Glyph_GetBBoxFunc    glyph_bbox;
  405.86 +    FT_Glyph_PrepareFunc    glyph_prepare;
  405.87 +  };
  405.88 +
  405.89 +
  405.90 +  typedef FT_Error
  405.91 +  (*FT_Renderer_RenderFunc)( FT_Renderer       renderer,
  405.92 +                             FT_GlyphSlot      slot,
  405.93 +                             FT_UInt           mode,
  405.94 +                             const FT_Vector*  origin );
  405.95 +
  405.96 +  typedef FT_Error
  405.97 +  (*FT_Renderer_TransformFunc)( FT_Renderer       renderer,
  405.98 +                                FT_GlyphSlot      slot,
  405.99 +                                const FT_Matrix*  matrix,
 405.100 +                                const FT_Vector*  delta );
 405.101 +
 405.102 +
 405.103 +  typedef void
 405.104 +  (*FT_Renderer_GetCBoxFunc)( FT_Renderer   renderer,
 405.105 +                              FT_GlyphSlot  slot,
 405.106 +                              FT_BBox*      cbox );
 405.107 +
 405.108 +
 405.109 +  typedef FT_Error
 405.110 +  (*FT_Renderer_SetModeFunc)( FT_Renderer  renderer,
 405.111 +                              FT_ULong     mode_tag,
 405.112 +                              FT_Pointer   mode_ptr );
 405.113 +
 405.114 +/* deprecated identifiers */
 405.115 +#define FTRenderer_render  FT_Renderer_RenderFunc
 405.116 +#define FTRenderer_transform  FT_Renderer_TransformFunc
 405.117 +#define FTRenderer_getCBox  FT_Renderer_GetCBoxFunc
 405.118 +#define FTRenderer_setMode  FT_Renderer_SetModeFunc
 405.119 +
 405.120 +
 405.121 +  /*************************************************************************/
 405.122 +  /*                                                                       */
 405.123 +  /* <Struct>                                                              */
 405.124 +  /*    FT_Renderer_Class                                                  */
 405.125 +  /*                                                                       */
 405.126 +  /* <Description>                                                         */
 405.127 +  /*    The renderer module class descriptor.                              */
 405.128 +  /*                                                                       */
 405.129 +  /* <Fields>                                                              */
 405.130 +  /*    root            :: The root @FT_Module_Class fields.               */
 405.131 +  /*                                                                       */
 405.132 +  /*    glyph_format    :: The glyph image format this renderer handles.   */
 405.133 +  /*                                                                       */
 405.134 +  /*    render_glyph    :: A method used to render the image that is in a  */
 405.135 +  /*                       given glyph slot into a bitmap.                 */
 405.136 +  /*                                                                       */
 405.137 +  /*    transform_glyph :: A method used to transform the image that is in */
 405.138 +  /*                       a given glyph slot.                             */
 405.139 +  /*                                                                       */
 405.140 +  /*    get_glyph_cbox  :: A method used to access the glyph's cbox.       */
 405.141 +  /*                                                                       */
 405.142 +  /*    set_mode        :: A method used to pass additional parameters.    */
 405.143 +  /*                                                                       */
 405.144 +  /*    raster_class    :: For @FT_GLYPH_FORMAT_OUTLINE renderers only.    */
 405.145 +  /*                       This is a pointer to its raster's class.        */
 405.146 +  /*                                                                       */
 405.147 +  typedef struct  FT_Renderer_Class_
 405.148 +  {
 405.149 +    FT_Module_Class            root;
 405.150 +
 405.151 +    FT_Glyph_Format            glyph_format;
 405.152 +
 405.153 +    FT_Renderer_RenderFunc     render_glyph;
 405.154 +    FT_Renderer_TransformFunc  transform_glyph;
 405.155 +    FT_Renderer_GetCBoxFunc    get_glyph_cbox;
 405.156 +    FT_Renderer_SetModeFunc    set_mode;
 405.157 +
 405.158 +    FT_Raster_Funcs*           raster_class;
 405.159 +
 405.160 +  } FT_Renderer_Class;
 405.161 +
 405.162 +
 405.163 +  /*************************************************************************/
 405.164 +  /*                                                                       */
 405.165 +  /* <Function>                                                            */
 405.166 +  /*    FT_Get_Renderer                                                    */
 405.167 +  /*                                                                       */
 405.168 +  /* <Description>                                                         */
 405.169 +  /*    Retrieve the current renderer for a given glyph format.            */
 405.170 +  /*                                                                       */
 405.171 +  /* <Input>                                                               */
 405.172 +  /*    library :: A handle to the library object.                         */
 405.173 +  /*                                                                       */
 405.174 +  /*    format  :: The glyph format.                                       */
 405.175 +  /*                                                                       */
 405.176 +  /* <Return>                                                              */
 405.177 +  /*    A renderer handle.  0~if none found.                               */
 405.178 +  /*                                                                       */
 405.179 +  /* <Note>                                                                */
 405.180 +  /*    An error will be returned if a module already exists by that name, */
 405.181 +  /*    or if the module requires a version of FreeType that is too great. */
 405.182 +  /*                                                                       */
 405.183 +  /*    To add a new renderer, simply use @FT_Add_Module.  To retrieve a   */
 405.184 +  /*    renderer by its name, use @FT_Get_Module.                          */
 405.185 +  /*                                                                       */
 405.186 +  FT_EXPORT( FT_Renderer )
 405.187 +  FT_Get_Renderer( FT_Library       library,
 405.188 +                   FT_Glyph_Format  format );
 405.189 +
 405.190 +
 405.191 +  /*************************************************************************/
 405.192 +  /*                                                                       */
 405.193 +  /* <Function>                                                            */
 405.194 +  /*    FT_Set_Renderer                                                    */
 405.195 +  /*                                                                       */
 405.196 +  /* <Description>                                                         */
 405.197 +  /*    Set the current renderer to use, and set additional mode.          */
 405.198 +  /*                                                                       */
 405.199 +  /* <InOut>                                                               */
 405.200 +  /*    library    :: A handle to the library object.                      */
 405.201 +  /*                                                                       */
 405.202 +  /* <Input>                                                               */
 405.203 +  /*    renderer   :: A handle to the renderer object.                     */
 405.204 +  /*                                                                       */
 405.205 +  /*    num_params :: The number of additional parameters.                 */
 405.206 +  /*                                                                       */
 405.207 +  /*    parameters :: Additional parameters.                               */
 405.208 +  /*                                                                       */
 405.209 +  /* <Return>                                                              */
 405.210 +  /*    FreeType error code.  0~means success.                             */
 405.211 +  /*                                                                       */
 405.212 +  /* <Note>                                                                */
 405.213 +  /*    In case of success, the renderer will be used to convert glyph     */
 405.214 +  /*    images in the renderer's known format into bitmaps.                */
 405.215 +  /*                                                                       */
 405.216 +  /*    This doesn't change the current renderer for other formats.        */
 405.217 +  /*                                                                       */
 405.218 +  FT_EXPORT( FT_Error )
 405.219 +  FT_Set_Renderer( FT_Library     library,
 405.220 +                   FT_Renderer    renderer,
 405.221 +                   FT_UInt        num_params,
 405.222 +                   FT_Parameter*  parameters );
 405.223 +
 405.224 +
 405.225 +  /* */
 405.226 +
 405.227 +
 405.228 +FT_END_HEADER
 405.229 +
 405.230 +#endif /* __FTRENDER_H__ */
 405.231 +
 405.232 +
 405.233 +/* END */
   406.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   406.2 +++ b/libs/ft2static/freetype/ftsizes.h	Sat Feb 01 19:58:19 2014 +0200
   406.3 @@ -0,0 +1,159 @@
   406.4 +/***************************************************************************/
   406.5 +/*                                                                         */
   406.6 +/*  ftsizes.h                                                              */
   406.7 +/*                                                                         */
   406.8 +/*    FreeType size objects management (specification).                    */
   406.9 +/*                                                                         */
  406.10 +/*  Copyright 1996-2001, 2003, 2004, 2006, 2009 by                         */
  406.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  406.12 +/*                                                                         */
  406.13 +/*  This file is part of the FreeType project, and may only be used,       */
  406.14 +/*  modified, and distributed under the terms of the FreeType project      */
  406.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  406.16 +/*  this file you indicate that you have read the license and              */
  406.17 +/*  understand and accept it fully.                                        */
  406.18 +/*                                                                         */
  406.19 +/***************************************************************************/
  406.20 +
  406.21 +
  406.22 +  /*************************************************************************/
  406.23 +  /*                                                                       */
  406.24 +  /* Typical application would normally not need to use these functions.   */
  406.25 +  /* However, they have been placed in a public API for the rare cases     */
  406.26 +  /* where they are needed.                                                */
  406.27 +  /*                                                                       */
  406.28 +  /*************************************************************************/
  406.29 +
  406.30 +
  406.31 +#ifndef __FTSIZES_H__
  406.32 +#define __FTSIZES_H__
  406.33 +
  406.34 +
  406.35 +#include <ft2build.h>
  406.36 +#include FT_FREETYPE_H
  406.37 +
  406.38 +#ifdef FREETYPE_H
  406.39 +#error "freetype.h of FreeType 1 has been loaded!"
  406.40 +#error "Please fix the directory search order for header files"
  406.41 +#error "so that freetype.h of FreeType 2 is found first."
  406.42 +#endif
  406.43 +
  406.44 +
  406.45 +FT_BEGIN_HEADER
  406.46 +
  406.47 +
  406.48 +  /*************************************************************************/
  406.49 +  /*                                                                       */
  406.50 +  /* <Section>                                                             */
  406.51 +  /*    sizes_management                                                   */
  406.52 +  /*                                                                       */
  406.53 +  /* <Title>                                                               */
  406.54 +  /*    Size Management                                                    */
  406.55 +  /*                                                                       */
  406.56 +  /* <Abstract>                                                            */
  406.57 +  /*    Managing multiple sizes per face.                                  */
  406.58 +  /*                                                                       */
  406.59 +  /* <Description>                                                         */
  406.60 +  /*    When creating a new face object (e.g., with @FT_New_Face), an      */
  406.61 +  /*    @FT_Size object is automatically created and used to store all     */
  406.62 +  /*    pixel-size dependent information, available in the `face->size'    */
  406.63 +  /*    field.                                                             */
  406.64 +  /*                                                                       */
  406.65 +  /*    It is however possible to create more sizes for a given face,      */
  406.66 +  /*    mostly in order to manage several character pixel sizes of the     */
  406.67 +  /*    same font family and style.  See @FT_New_Size and @FT_Done_Size.   */
  406.68 +  /*                                                                       */
  406.69 +  /*    Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only           */
  406.70 +  /*    modify the contents of the current `active' size; you thus need    */
  406.71 +  /*    to use @FT_Activate_Size to change it.                             */
  406.72 +  /*                                                                       */
  406.73 +  /*    99% of applications won't need the functions provided here,        */
  406.74 +  /*    especially if they use the caching sub-system, so be cautious      */
  406.75 +  /*    when using these.                                                  */
  406.76 +  /*                                                                       */
  406.77 +  /*************************************************************************/
  406.78 +
  406.79 +
  406.80 +  /*************************************************************************/
  406.81 +  /*                                                                       */
  406.82 +  /* <Function>                                                            */
  406.83 +  /*    FT_New_Size                                                        */
  406.84 +  /*                                                                       */
  406.85 +  /* <Description>                                                         */
  406.86 +  /*    Create a new size object from a given face object.                 */
  406.87 +  /*                                                                       */
  406.88 +  /* <Input>                                                               */
  406.89 +  /*    face :: A handle to a parent face object.                          */
  406.90 +  /*                                                                       */
  406.91 +  /* <Output>                                                              */
  406.92 +  /*    asize :: A handle to a new size object.                            */
  406.93 +  /*                                                                       */
  406.94 +  /* <Return>                                                              */
  406.95 +  /*    FreeType error code.  0~means success.                             */
  406.96 +  /*                                                                       */
  406.97 +  /* <Note>                                                                */
  406.98 +  /*    You need to call @FT_Activate_Size in order to select the new size */
  406.99 +  /*    for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size,      */
 406.100 +  /*    @FT_Load_Glyph, @FT_Load_Char, etc.                                */
 406.101 +  /*                                                                       */
 406.102 +  FT_EXPORT( FT_Error )
 406.103 +  FT_New_Size( FT_Face   face,
 406.104 +               FT_Size*  size );
 406.105 +
 406.106 +
 406.107 +  /*************************************************************************/
 406.108 +  /*                                                                       */
 406.109 +  /* <Function>                                                            */
 406.110 +  /*    FT_Done_Size                                                       */
 406.111 +  /*                                                                       */
 406.112 +  /* <Description>                                                         */
 406.113 +  /*    Discard a given size object.  Note that @FT_Done_Face              */
 406.114 +  /*    automatically discards all size objects allocated with             */
 406.115 +  /*    @FT_New_Size.                                                      */
 406.116 +  /*                                                                       */
 406.117 +  /* <Input>                                                               */
 406.118 +  /*    size :: A handle to a target size object.                          */
 406.119 +  /*                                                                       */
 406.120 +  /* <Return>                                                              */
 406.121 +  /*    FreeType error code.  0~means success.                             */
 406.122 +  /*                                                                       */
 406.123 +  FT_EXPORT( FT_Error )
 406.124 +  FT_Done_Size( FT_Size  size );
 406.125 +
 406.126 +
 406.127 +  /*************************************************************************/
 406.128 +  /*                                                                       */
 406.129 +  /* <Function>                                                            */
 406.130 +  /*    FT_Activate_Size                                                   */
 406.131 +  /*                                                                       */
 406.132 +  /* <Description>                                                         */
 406.133 +  /*    Even though it is possible to create several size objects for a    */
 406.134 +  /*    given face (see @FT_New_Size for details), functions like          */
 406.135 +  /*    @FT_Load_Glyph or @FT_Load_Char only use the one which has been    */
 406.136 +  /*    activated last to determine the `current character pixel size'.    */
 406.137 +  /*                                                                       */
 406.138 +  /*    This function can be used to `activate' a previously created size  */
 406.139 +  /*    object.                                                            */
 406.140 +  /*                                                                       */
 406.141 +  /* <Input>                                                               */
 406.142 +  /*    size :: A handle to a target size object.                          */
 406.143 +  /*                                                                       */
 406.144 +  /* <Return>                                                              */
 406.145 +  /*    FreeType error code.  0~means success.                             */
 406.146 +  /*                                                                       */
 406.147 +  /* <Note>                                                                */
 406.148 +  /*    If `face' is the size's parent face object, this function changes  */
 406.149 +  /*    the value of `face->size' to the input size handle.                */
 406.150 +  /*                                                                       */
 406.151 +  FT_EXPORT( FT_Error )
 406.152 +  FT_Activate_Size( FT_Size  size );
 406.153 +
 406.154 +  /* */
 406.155 +
 406.156 +
 406.157 +FT_END_HEADER
 406.158 +
 406.159 +#endif /* __FTSIZES_H__ */
 406.160 +
 406.161 +
 406.162 +/* END */
   407.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   407.2 +++ b/libs/ft2static/freetype/ftsnames.h	Sat Feb 01 19:58:19 2014 +0200
   407.3 @@ -0,0 +1,200 @@
   407.4 +/***************************************************************************/
   407.5 +/*                                                                         */
   407.6 +/*  ftsnames.h                                                             */
   407.7 +/*                                                                         */
   407.8 +/*    Simple interface to access SFNT name tables (which are used          */
   407.9 +/*    to hold font names, copyright info, notices, etc.) (specification).  */
  407.10 +/*                                                                         */
  407.11 +/*    This is _not_ used to retrieve glyph names!                          */
  407.12 +/*                                                                         */
  407.13 +/*  Copyright 1996-2001, 2002, 2003, 2006, 2009, 2010 by                   */
  407.14 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  407.15 +/*                                                                         */
  407.16 +/*  This file is part of the FreeType project, and may only be used,       */
  407.17 +/*  modified, and distributed under the terms of the FreeType project      */
  407.18 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  407.19 +/*  this file you indicate that you have read the license and              */
  407.20 +/*  understand and accept it fully.                                        */
  407.21 +/*                                                                         */
  407.22 +/***************************************************************************/
  407.23 +
  407.24 +
  407.25 +#ifndef __FT_SFNT_NAMES_H__
  407.26 +#define __FT_SFNT_NAMES_H__
  407.27 +
  407.28 +
  407.29 +#include <ft2build.h>
  407.30 +#include FT_FREETYPE_H
  407.31 +
  407.32 +#ifdef FREETYPE_H
  407.33 +#error "freetype.h of FreeType 1 has been loaded!"
  407.34 +#error "Please fix the directory search order for header files"
  407.35 +#error "so that freetype.h of FreeType 2 is found first."
  407.36 +#endif
  407.37 +
  407.38 +
  407.39 +FT_BEGIN_HEADER
  407.40 +
  407.41 +
  407.42 +  /*************************************************************************/
  407.43 +  /*                                                                       */
  407.44 +  /* <Section>                                                             */
  407.45 +  /*    sfnt_names                                                         */
  407.46 +  /*                                                                       */
  407.47 +  /* <Title>                                                               */
  407.48 +  /*    SFNT Names                                                         */
  407.49 +  /*                                                                       */
  407.50 +  /* <Abstract>                                                            */
  407.51 +  /*    Access the names embedded in TrueType and OpenType files.          */
  407.52 +  /*                                                                       */
  407.53 +  /* <Description>                                                         */
  407.54 +  /*    The TrueType and OpenType specifications allow the inclusion of    */
  407.55 +  /*    a special `names table' in font files.  This table contains        */
  407.56 +  /*    textual (and internationalized) information regarding the font,    */
  407.57 +  /*    like family name, copyright, version, etc.                         */
  407.58 +  /*                                                                       */
  407.59 +  /*    The definitions below are used to access them if available.        */
  407.60 +  /*                                                                       */
  407.61 +  /*    Note that this has nothing to do with glyph names!                 */
  407.62 +  /*                                                                       */
  407.63 +  /*************************************************************************/
  407.64 +
  407.65 +
  407.66 +  /*************************************************************************/
  407.67 +  /*                                                                       */
  407.68 +  /* <Struct>                                                              */
  407.69 +  /*    FT_SfntName                                                        */
  407.70 +  /*                                                                       */
  407.71 +  /* <Description>                                                         */
  407.72 +  /*    A structure used to model an SFNT `name' table entry.              */
  407.73 +  /*                                                                       */
  407.74 +  /* <Fields>                                                              */
  407.75 +  /*    platform_id :: The platform ID for `string'.                       */
  407.76 +  /*                                                                       */
  407.77 +  /*    encoding_id :: The encoding ID for `string'.                       */
  407.78 +  /*                                                                       */
  407.79 +  /*    language_id :: The language ID for `string'.                       */
  407.80 +  /*                                                                       */
  407.81 +  /*    name_id     :: An identifier for `string'.                         */
  407.82 +  /*                                                                       */
  407.83 +  /*    string      :: The `name' string.  Note that its format differs    */
  407.84 +  /*                   depending on the (platform,encoding) pair.  It can  */
  407.85 +  /*                   be a Pascal String, a UTF-16 one, etc.              */
  407.86 +  /*                                                                       */
  407.87 +  /*                   Generally speaking, the string is not               */
  407.88 +  /*                   zero-terminated.  Please refer to the TrueType      */
  407.89 +  /*                   specification for details.                          */
  407.90 +  /*                                                                       */
  407.91 +  /*    string_len  :: The length of `string' in bytes.                    */
  407.92 +  /*                                                                       */
  407.93 +  /* <Note>                                                                */
  407.94 +  /*    Possible values for `platform_id', `encoding_id', `language_id',   */
  407.95 +  /*    and `name_id' are given in the file `ttnameid.h'.  For details     */
  407.96 +  /*    please refer to the TrueType or OpenType specification.            */
  407.97 +  /*                                                                       */
  407.98 +  /*    See also @TT_PLATFORM_XXX, @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX,       */
  407.99 +  /*    @TT_ISO_ID_XXX, and @TT_MS_ID_XXX.                                 */
 407.100 +  /*                                                                       */
 407.101 +  typedef struct  FT_SfntName_
 407.102 +  {
 407.103 +    FT_UShort  platform_id;
 407.104 +    FT_UShort  encoding_id;
 407.105 +    FT_UShort  language_id;
 407.106 +    FT_UShort  name_id;
 407.107 +
 407.108 +    FT_Byte*   string;      /* this string is *not* null-terminated! */
 407.109 +    FT_UInt    string_len;  /* in bytes */
 407.110 +
 407.111 +  } FT_SfntName;
 407.112 +
 407.113 +
 407.114 +  /*************************************************************************/
 407.115 +  /*                                                                       */
 407.116 +  /* <Function>                                                            */
 407.117 +  /*    FT_Get_Sfnt_Name_Count                                             */
 407.118 +  /*                                                                       */
 407.119 +  /* <Description>                                                         */
 407.120 +  /*    Retrieve the number of name strings in the SFNT `name' table.      */
 407.121 +  /*                                                                       */
 407.122 +  /* <Input>                                                               */
 407.123 +  /*    face :: A handle to the source face.                               */
 407.124 +  /*                                                                       */
 407.125 +  /* <Return>                                                              */
 407.126 +  /*    The number of strings in the `name' table.                         */
 407.127 +  /*                                                                       */
 407.128 +  FT_EXPORT( FT_UInt )
 407.129 +  FT_Get_Sfnt_Name_Count( FT_Face  face );
 407.130 +
 407.131 +
 407.132 +  /*************************************************************************/
 407.133 +  /*                                                                       */
 407.134 +  /* <Function>                                                            */
 407.135 +  /*    FT_Get_Sfnt_Name                                                   */
 407.136 +  /*                                                                       */
 407.137 +  /* <Description>                                                         */
 407.138 +  /*    Retrieve a string of the SFNT `name' table for a given index.      */
 407.139 +  /*                                                                       */
 407.140 +  /* <Input>                                                               */
 407.141 +  /*    face  :: A handle to the source face.                              */
 407.142 +  /*                                                                       */
 407.143 +  /*    idx   :: The index of the `name' string.                           */
 407.144 +  /*                                                                       */
 407.145 +  /* <Output>                                                              */
 407.146 +  /*    aname :: The indexed @FT_SfntName structure.                       */
 407.147 +  /*                                                                       */
 407.148 +  /* <Return>                                                              */
 407.149 +  /*    FreeType error code.  0~means success.                             */
 407.150 +  /*                                                                       */
 407.151 +  /* <Note>                                                                */
 407.152 +  /*    The `string' array returned in the `aname' structure is not        */
 407.153 +  /*    null-terminated.  The application should deallocate it if it is no */
 407.154 +  /*    longer in use.                                                     */
 407.155 +  /*                                                                       */
 407.156 +  /*    Use @FT_Get_Sfnt_Name_Count to get the total number of available   */
 407.157 +  /*    `name' table entries, then do a loop until you get the right       */
 407.158 +  /*    platform, encoding, and name ID.                                   */
 407.159 +  /*                                                                       */
 407.160 +  FT_EXPORT( FT_Error )
 407.161 +  FT_Get_Sfnt_Name( FT_Face       face,
 407.162 +                    FT_UInt       idx,
 407.163 +                    FT_SfntName  *aname );
 407.164 +
 407.165 +
 407.166 +  /***************************************************************************
 407.167 +   *
 407.168 +   * @constant:
 407.169 +   *   FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY
 407.170 +   *
 407.171 +   * @description:
 407.172 +   *   A constant used as the tag of @FT_Parameter structures to make
 407.173 +   *   FT_Open_Face() ignore preferred family subfamily names in `name'
 407.174 +   *   table since OpenType version 1.4.  For backwards compatibility with
 407.175 +   *   legacy systems which has 4-face-per-family restriction.
 407.176 +   *
 407.177 +   */
 407.178 +#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY  FT_MAKE_TAG( 'i', 'g', 'p', 'f' )
 407.179 +
 407.180 +
 407.181 +  /***************************************************************************
 407.182 +   *
 407.183 +   * @constant:
 407.184 +   *   FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY
 407.185 +   *
 407.186 +   * @description:
 407.187 +   *   A constant used as the tag of @FT_Parameter structures to make
 407.188 +   *   FT_Open_Face() ignore preferred subfamily names in `name' table since
 407.189 +   *   OpenType version 1.4.  For backwards compatibility with legacy
 407.190 +   *   systems which has 4-face-per-family restriction.
 407.191 +   *
 407.192 +   */
 407.193 +#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY  FT_MAKE_TAG( 'i', 'g', 'p', 's' )
 407.194 +
 407.195 +  /* */
 407.196 +
 407.197 +
 407.198 +FT_END_HEADER
 407.199 +
 407.200 +#endif /* __FT_SFNT_NAMES_H__ */
 407.201 +
 407.202 +
 407.203 +/* END */
   408.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   408.2 +++ b/libs/ft2static/freetype/ftstroke.h	Sat Feb 01 19:58:19 2014 +0200
   408.3 @@ -0,0 +1,716 @@
   408.4 +/***************************************************************************/
   408.5 +/*                                                                         */
   408.6 +/*  ftstroke.h                                                             */
   408.7 +/*                                                                         */
   408.8 +/*    FreeType path stroker (specification).                               */
   408.9 +/*                                                                         */
  408.10 +/*  Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by                  */
  408.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  408.12 +/*                                                                         */
  408.13 +/*  This file is part of the FreeType project, and may only be used,       */
  408.14 +/*  modified, and distributed under the terms of the FreeType project      */
  408.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  408.16 +/*  this file you indicate that you have read the license and              */
  408.17 +/*  understand and accept it fully.                                        */
  408.18 +/*                                                                         */
  408.19 +/***************************************************************************/
  408.20 +
  408.21 +
  408.22 +#ifndef __FT_STROKE_H__
  408.23 +#define __FT_STROKE_H__
  408.24 +
  408.25 +#include <ft2build.h>
  408.26 +#include FT_OUTLINE_H
  408.27 +#include FT_GLYPH_H
  408.28 +
  408.29 +
  408.30 +FT_BEGIN_HEADER
  408.31 +
  408.32 +
  408.33 + /************************************************************************
  408.34 +  *
  408.35 +  * @section:
  408.36 +  *    glyph_stroker
  408.37 +  *
  408.38 +  * @title:
  408.39 +  *    Glyph Stroker
  408.40 +  *
  408.41 +  * @abstract:
  408.42 +  *    Generating bordered and stroked glyphs.
  408.43 +  *
  408.44 +  * @description:
  408.45 +  *    This component generates stroked outlines of a given vectorial
  408.46 +  *    glyph.  It also allows you to retrieve the `outside' and/or the
  408.47 +  *    `inside' borders of the stroke.
  408.48 +  *
  408.49 +  *    This can be useful to generate `bordered' glyph, i.e., glyphs
  408.50 +  *    displayed with a coloured (and anti-aliased) border around their
  408.51 +  *    shape.
  408.52 +  */
  408.53 +
  408.54 +
  408.55 + /**************************************************************
  408.56 +  *
  408.57 +  * @type:
  408.58 +  *   FT_Stroker
  408.59 +  *
  408.60 +  * @description:
  408.61 +  *   Opaque handler to a path stroker object.
  408.62 +  */
  408.63 +  typedef struct FT_StrokerRec_*  FT_Stroker;
  408.64 +
  408.65 +
  408.66 +  /**************************************************************
  408.67 +   *
  408.68 +   * @enum:
  408.69 +   *   FT_Stroker_LineJoin
  408.70 +   *
  408.71 +   * @description:
  408.72 +   *   These values determine how two joining lines are rendered
  408.73 +   *   in a stroker.
  408.74 +   *
  408.75 +   * @values:
  408.76 +   *   FT_STROKER_LINEJOIN_ROUND ::
  408.77 +   *     Used to render rounded line joins.  Circular arcs are used
  408.78 +   *     to join two lines smoothly.
  408.79 +   *
  408.80 +   *   FT_STROKER_LINEJOIN_BEVEL ::
  408.81 +   *     Used to render beveled line joins; i.e., the two joining lines
  408.82 +   *     are extended until they intersect.
  408.83 +   *
  408.84 +   *   FT_STROKER_LINEJOIN_MITER ::
  408.85 +   *     Same as beveled rendering, except that an additional line
  408.86 +   *     break is added if the angle between the two joining lines
  408.87 +   *     is too closed (this is useful to avoid unpleasant spikes
  408.88 +   *     in beveled rendering).
  408.89 +   */
  408.90 +  typedef enum  FT_Stroker_LineJoin_
  408.91 +  {
  408.92 +    FT_STROKER_LINEJOIN_ROUND = 0,
  408.93 +    FT_STROKER_LINEJOIN_BEVEL,
  408.94 +    FT_STROKER_LINEJOIN_MITER
  408.95 +
  408.96 +  } FT_Stroker_LineJoin;
  408.97 +
  408.98 +
  408.99 +  /**************************************************************
 408.100 +   *
 408.101 +   * @enum:
 408.102 +   *   FT_Stroker_LineCap
 408.103 +   *
 408.104 +   * @description:
 408.105 +   *   These values determine how the end of opened sub-paths are
 408.106 +   *   rendered in a stroke.
 408.107 +   *
 408.108 +   * @values:
 408.109 +   *   FT_STROKER_LINECAP_BUTT ::
 408.110 +   *     The end of lines is rendered as a full stop on the last
 408.111 +   *     point itself.
 408.112 +   *
 408.113 +   *   FT_STROKER_LINECAP_ROUND ::
 408.114 +   *     The end of lines is rendered as a half-circle around the
 408.115 +   *     last point.
 408.116 +   *
 408.117 +   *   FT_STROKER_LINECAP_SQUARE ::
 408.118 +   *     The end of lines is rendered as a square around the
 408.119 +   *     last point.
 408.120 +   */
 408.121 +  typedef enum  FT_Stroker_LineCap_
 408.122 +  {
 408.123 +    FT_STROKER_LINECAP_BUTT = 0,
 408.124 +    FT_STROKER_LINECAP_ROUND,
 408.125 +    FT_STROKER_LINECAP_SQUARE
 408.126 +
 408.127 +  } FT_Stroker_LineCap;
 408.128 +
 408.129 +
 408.130 +  /**************************************************************
 408.131 +   *
 408.132 +   * @enum:
 408.133 +   *   FT_StrokerBorder
 408.134 +   *
 408.135 +   * @description:
 408.136 +   *   These values are used to select a given stroke border
 408.137 +   *   in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder.
 408.138 +   *
 408.139 +   * @values:
 408.140 +   *   FT_STROKER_BORDER_LEFT ::
 408.141 +   *     Select the left border, relative to the drawing direction.
 408.142 +   *
 408.143 +   *   FT_STROKER_BORDER_RIGHT ::
 408.144 +   *     Select the right border, relative to the drawing direction.
 408.145 +   *
 408.146 +   * @note:
 408.147 +   *   Applications are generally interested in the `inside' and `outside'
 408.148 +   *   borders.  However, there is no direct mapping between these and the
 408.149 +   *   `left' and `right' ones, since this really depends on the glyph's
 408.150 +   *   drawing orientation, which varies between font formats.
 408.151 +   *
 408.152 +   *   You can however use @FT_Outline_GetInsideBorder and
 408.153 +   *   @FT_Outline_GetOutsideBorder to get these.
 408.154 +   */
 408.155 +  typedef enum  FT_StrokerBorder_
 408.156 +  {
 408.157 +    FT_STROKER_BORDER_LEFT = 0,
 408.158 +    FT_STROKER_BORDER_RIGHT
 408.159 +
 408.160 +  } FT_StrokerBorder;
 408.161 +
 408.162 +
 408.163 +  /**************************************************************
 408.164 +   *
 408.165 +   * @function:
 408.166 +   *   FT_Outline_GetInsideBorder
 408.167 +   *
 408.168 +   * @description:
 408.169 +   *   Retrieve the @FT_StrokerBorder value corresponding to the
 408.170 +   *   `inside' borders of a given outline.
 408.171 +   *
 408.172 +   * @input:
 408.173 +   *   outline ::
 408.174 +   *     The source outline handle.
 408.175 +   *
 408.176 +   * @return:
 408.177 +   *   The border index.  @FT_STROKER_BORDER_RIGHT for empty or invalid
 408.178 +   *   outlines.
 408.179 +   */
 408.180 +  FT_EXPORT( FT_StrokerBorder )
 408.181 +  FT_Outline_GetInsideBorder( FT_Outline*  outline );
 408.182 +
 408.183 +
 408.184 +  /**************************************************************
 408.185 +   *
 408.186 +   * @function:
 408.187 +   *   FT_Outline_GetOutsideBorder
 408.188 +   *
 408.189 +   * @description:
 408.190 +   *   Retrieve the @FT_StrokerBorder value corresponding to the
 408.191 +   *   `outside' borders of a given outline.
 408.192 +   *
 408.193 +   * @input:
 408.194 +   *   outline ::
 408.195 +   *     The source outline handle.
 408.196 +   *
 408.197 +   * @return:
 408.198 +   *   The border index.  @FT_STROKER_BORDER_LEFT for empty or invalid
 408.199 +   *   outlines.
 408.200 +   */
 408.201 +  FT_EXPORT( FT_StrokerBorder )
 408.202 +  FT_Outline_GetOutsideBorder( FT_Outline*  outline );
 408.203 +
 408.204 +
 408.205 +  /**************************************************************
 408.206 +   *
 408.207 +   * @function:
 408.208 +   *   FT_Stroker_New
 408.209 +   *
 408.210 +   * @description:
 408.211 +   *   Create a new stroker object.
 408.212 +   *
 408.213 +   * @input:
 408.214 +   *   library ::
 408.215 +   *     FreeType library handle.
 408.216 +   *
 408.217 +   * @output:
 408.218 +   *   astroker ::
 408.219 +   *     A new stroker object handle.  NULL in case of error.
 408.220 +   *
 408.221 +   * @return:
 408.222 +   *    FreeType error code.  0~means success.
 408.223 +   */
 408.224 +  FT_EXPORT( FT_Error )
 408.225 +  FT_Stroker_New( FT_Library   library,
 408.226 +                  FT_Stroker  *astroker );
 408.227 +
 408.228 +
 408.229 +  /**************************************************************
 408.230 +   *
 408.231 +   * @function:
 408.232 +   *   FT_Stroker_Set
 408.233 +   *
 408.234 +   * @description:
 408.235 +   *   Reset a stroker object's attributes.
 408.236 +   *
 408.237 +   * @input:
 408.238 +   *   stroker ::
 408.239 +   *     The target stroker handle.
 408.240 +   *
 408.241 +   *   radius ::
 408.242 +   *     The border radius.
 408.243 +   *
 408.244 +   *   line_cap ::
 408.245 +   *     The line cap style.
 408.246 +   *
 408.247 +   *   line_join ::
 408.248 +   *     The line join style.
 408.249 +   *
 408.250 +   *   miter_limit ::
 408.251 +   *     The miter limit for the FT_STROKER_LINEJOIN_MITER style,
 408.252 +   *     expressed as 16.16 fixed point value.
 408.253 +   *
 408.254 +   * @note:
 408.255 +   *   The radius is expressed in the same units as the outline
 408.256 +   *   coordinates.
 408.257 +   */
 408.258 +  FT_EXPORT( void )
 408.259 +  FT_Stroker_Set( FT_Stroker           stroker,
 408.260 +                  FT_Fixed             radius,
 408.261 +                  FT_Stroker_LineCap   line_cap,
 408.262 +                  FT_Stroker_LineJoin  line_join,
 408.263 +                  FT_Fixed             miter_limit );
 408.264 +
 408.265 +
 408.266 +  /**************************************************************
 408.267 +   *
 408.268 +   * @function:
 408.269 +   *   FT_Stroker_Rewind
 408.270 +   *
 408.271 +   * @description:
 408.272 +   *   Reset a stroker object without changing its attributes.
 408.273 +   *   You should call this function before beginning a new
 408.274 +   *   series of calls to @FT_Stroker_BeginSubPath or
 408.275 +   *   @FT_Stroker_EndSubPath.
 408.276 +   *
 408.277 +   * @input:
 408.278 +   *   stroker ::
 408.279 +   *     The target stroker handle.
 408.280 +   */
 408.281 +  FT_EXPORT( void )
 408.282 +  FT_Stroker_Rewind( FT_Stroker  stroker );
 408.283 +
 408.284 +
 408.285 +  /**************************************************************
 408.286 +   *
 408.287 +   * @function:
 408.288 +   *   FT_Stroker_ParseOutline
 408.289 +   *
 408.290 +   * @description:
 408.291 +   *   A convenience function used to parse a whole outline with
 408.292 +   *   the stroker.  The resulting outline(s) can be retrieved
 408.293 +   *   later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export.
 408.294 +   *
 408.295 +   * @input:
 408.296 +   *   stroker ::
 408.297 +   *     The target stroker handle.
 408.298 +   *
 408.299 +   *   outline ::
 408.300 +   *     The source outline.
 408.301 +   *
 408.302 +   *   opened ::
 408.303 +   *     A boolean.  If~1, the outline is treated as an open path instead
 408.304 +   *     of a closed one.
 408.305 +   *
 408.306 +   * @return:
 408.307 +   *   FreeType error code.  0~means success.
 408.308 +   *
 408.309 +   * @note:
 408.310 +   *   If `opened' is~0 (the default), the outline is treated as a closed
 408.311 +   *   path, and the stroker generates two distinct `border' outlines.
 408.312 +   *
 408.313 +   *   If `opened' is~1, the outline is processed as an open path, and the
 408.314 +   *   stroker generates a single `stroke' outline.
 408.315 +   *
 408.316 +   *   This function calls @FT_Stroker_Rewind automatically.
 408.317 +   */
 408.318 +  FT_EXPORT( FT_Error )
 408.319 +  FT_Stroker_ParseOutline( FT_Stroker   stroker,
 408.320 +                           FT_Outline*  outline,
 408.321 +                           FT_Bool      opened );
 408.322 +
 408.323 +
 408.324 +  /**************************************************************
 408.325 +   *
 408.326 +   * @function:
 408.327 +   *   FT_Stroker_BeginSubPath
 408.328 +   *
 408.329 +   * @description:
 408.330 +   *   Start a new sub-path in the stroker.
 408.331 +   *
 408.332 +   * @input:
 408.333 +   *   stroker ::
 408.334 +   *     The target stroker handle.
 408.335 +   *
 408.336 +   *   to ::
 408.337 +   *     A pointer to the start vector.
 408.338 +   *
 408.339 +   *   open ::
 408.340 +   *     A boolean.  If~1, the sub-path is treated as an open one.
 408.341 +   *
 408.342 +   * @return:
 408.343 +   *   FreeType error code.  0~means success.
 408.344 +   *
 408.345 +   * @note:
 408.346 +   *   This function is useful when you need to stroke a path that is
 408.347 +   *   not stored as an @FT_Outline object.
 408.348 +   */
 408.349 +  FT_EXPORT( FT_Error )
 408.350 +  FT_Stroker_BeginSubPath( FT_Stroker  stroker,
 408.351 +                           FT_Vector*  to,
 408.352 +                           FT_Bool     open );
 408.353 +
 408.354 +
 408.355 +  /**************************************************************
 408.356 +   *
 408.357 +   * @function:
 408.358 +   *   FT_Stroker_EndSubPath
 408.359 +   *
 408.360 +   * @description:
 408.361 +   *   Close the current sub-path in the stroker.
 408.362 +   *
 408.363 +   * @input:
 408.364 +   *   stroker ::
 408.365 +   *     The target stroker handle.
 408.366 +   *
 408.367 +   * @return:
 408.368 +   *   FreeType error code.  0~means success.
 408.369 +   *
 408.370 +   * @note:
 408.371 +   *   You should call this function after @FT_Stroker_BeginSubPath.
 408.372 +   *   If the subpath was not `opened', this function `draws' a
 408.373 +   *   single line segment to the start position when needed.
 408.374 +   */
 408.375 +  FT_EXPORT( FT_Error )
 408.376 +  FT_Stroker_EndSubPath( FT_Stroker  stroker );
 408.377 +
 408.378 +
 408.379 +  /**************************************************************
 408.380 +   *
 408.381 +   * @function:
 408.382 +   *   FT_Stroker_LineTo
 408.383 +   *
 408.384 +   * @description:
 408.385 +   *   `Draw' a single line segment in the stroker's current sub-path,
 408.386 +   *   from the last position.
 408.387 +   *
 408.388 +   * @input:
 408.389 +   *   stroker ::
 408.390 +   *     The target stroker handle.
 408.391 +   *
 408.392 +   *   to ::
 408.393 +   *     A pointer to the destination point.
 408.394 +   *
 408.395 +   * @return:
 408.396 +   *   FreeType error code.  0~means success.
 408.397 +   *
 408.398 +   * @note:
 408.399 +   *   You should call this function between @FT_Stroker_BeginSubPath and
 408.400 +   *   @FT_Stroker_EndSubPath.
 408.401 +   */
 408.402 +  FT_EXPORT( FT_Error )
 408.403 +  FT_Stroker_LineTo( FT_Stroker  stroker,
 408.404 +                     FT_Vector*  to );
 408.405 +
 408.406 +
 408.407 +  /**************************************************************
 408.408 +   *
 408.409 +   * @function:
 408.410 +   *   FT_Stroker_ConicTo
 408.411 +   *
 408.412 +   * @description:
 408.413 +   *   `Draw' a single quadratic Bézier in the stroker's current sub-path,
 408.414 +   *   from the last position.
 408.415 +   *
 408.416 +   * @input:
 408.417 +   *   stroker ::
 408.418 +   *     The target stroker handle.
 408.419 +   *
 408.420 +   *   control ::
 408.421 +   *     A pointer to a Bézier control point.
 408.422 +   *
 408.423 +   *   to ::
 408.424 +   *     A pointer to the destination point.
 408.425 +   *
 408.426 +   * @return:
 408.427 +   *   FreeType error code.  0~means success.
 408.428 +   *
 408.429 +   * @note:
 408.430 +   *   You should call this function between @FT_Stroker_BeginSubPath and
 408.431 +   *   @FT_Stroker_EndSubPath.
 408.432 +   */
 408.433 +  FT_EXPORT( FT_Error )
 408.434 +  FT_Stroker_ConicTo( FT_Stroker  stroker,
 408.435 +                      FT_Vector*  control,
 408.436 +                      FT_Vector*  to );
 408.437 +
 408.438 +
 408.439 +  /**************************************************************
 408.440 +   *
 408.441 +   * @function:
 408.442 +   *   FT_Stroker_CubicTo
 408.443 +   *
 408.444 +   * @description:
 408.445 +   *   `Draw' a single cubic Bézier in the stroker's current sub-path,
 408.446 +   *   from the last position.
 408.447 +   *
 408.448 +   * @input:
 408.449 +   *   stroker ::
 408.450 +   *     The target stroker handle.
 408.451 +   *
 408.452 +   *   control1 ::
 408.453 +   *     A pointer to the first Bézier control point.
 408.454 +   *
 408.455 +   *   control2 ::
 408.456 +   *     A pointer to second Bézier control point.
 408.457 +   *
 408.458 +   *   to ::
 408.459 +   *     A pointer to the destination point.
 408.460 +   *
 408.461 +   * @return:
 408.462 +   *   FreeType error code.  0~means success.
 408.463 +   *
 408.464 +   * @note:
 408.465 +   *   You should call this function between @FT_Stroker_BeginSubPath and
 408.466 +   *   @FT_Stroker_EndSubPath.
 408.467 +   */
 408.468 +  FT_EXPORT( FT_Error )
 408.469 +  FT_Stroker_CubicTo( FT_Stroker  stroker,
 408.470 +                      FT_Vector*  control1,
 408.471 +                      FT_Vector*  control2,
 408.472 +                      FT_Vector*  to );
 408.473 +
 408.474 +
 408.475 +  /**************************************************************
 408.476 +   *
 408.477 +   * @function:
 408.478 +   *   FT_Stroker_GetBorderCounts
 408.479 +   *
 408.480 +   * @description:
 408.481 +   *   Call this function once you have finished parsing your paths
 408.482 +   *   with the stroker.  It returns the number of points and
 408.483 +   *   contours necessary to export one of the `border' or `stroke'
 408.484 +   *   outlines generated by the stroker.
 408.485 +   *
 408.486 +   * @input:
 408.487 +   *   stroker ::
 408.488 +   *     The target stroker handle.
 408.489 +   *
 408.490 +   *   border ::
 408.491 +   *     The border index.
 408.492 +   *
 408.493 +   * @output:
 408.494 +   *   anum_points ::
 408.495 +   *     The number of points.
 408.496 +   *
 408.497 +   *   anum_contours ::
 408.498 +   *     The number of contours.
 408.499 +   *
 408.500 +   * @return:
 408.501 +   *   FreeType error code.  0~means success.
 408.502 +   *
 408.503 +   * @note:
 408.504 +   *   When an outline, or a sub-path, is `closed', the stroker generates
 408.505 +   *   two independent `border' outlines, named `left' and `right'.
 408.506 +   *
 408.507 +   *   When the outline, or a sub-path, is `opened', the stroker merges
 408.508 +   *   the `border' outlines with caps.  The `left' border receives all
 408.509 +   *   points, while the `right' border becomes empty.
 408.510 +   *
 408.511 +   *   Use the function @FT_Stroker_GetCounts instead if you want to
 408.512 +   *   retrieve the counts associated to both borders.
 408.513 +   */
 408.514 +  FT_EXPORT( FT_Error )
 408.515 +  FT_Stroker_GetBorderCounts( FT_Stroker        stroker,
 408.516 +                              FT_StrokerBorder  border,
 408.517 +                              FT_UInt          *anum_points,
 408.518 +                              FT_UInt          *anum_contours );
 408.519 +
 408.520 +
 408.521 +  /**************************************************************
 408.522 +   *
 408.523 +   * @function:
 408.524 +   *   FT_Stroker_ExportBorder
 408.525 +   *
 408.526 +   * @description:
 408.527 +   *   Call this function after @FT_Stroker_GetBorderCounts to
 408.528 +   *   export the corresponding border to your own @FT_Outline
 408.529 +   *   structure.
 408.530 +   *
 408.531 +   *   Note that this function appends the border points and
 408.532 +   *   contours to your outline, but does not try to resize its
 408.533 +   *   arrays.
 408.534 +   *
 408.535 +   * @input:
 408.536 +   *   stroker ::
 408.537 +   *     The target stroker handle.
 408.538 +   *
 408.539 +   *   border ::
 408.540 +   *     The border index.
 408.541 +   *
 408.542 +   *   outline ::
 408.543 +   *     The target outline handle.
 408.544 +   *
 408.545 +   * @note:
 408.546 +   *   Always call this function after @FT_Stroker_GetBorderCounts to
 408.547 +   *   get sure that there is enough room in your @FT_Outline object to
 408.548 +   *   receive all new data.
 408.549 +   *
 408.550 +   *   When an outline, or a sub-path, is `closed', the stroker generates
 408.551 +   *   two independent `border' outlines, named `left' and `right'
 408.552 +   *
 408.553 +   *   When the outline, or a sub-path, is `opened', the stroker merges
 408.554 +   *   the `border' outlines with caps. The `left' border receives all
 408.555 +   *   points, while the `right' border becomes empty.
 408.556 +   *
 408.557 +   *   Use the function @FT_Stroker_Export instead if you want to
 408.558 +   *   retrieve all borders at once.
 408.559 +   */
 408.560 +  FT_EXPORT( void )
 408.561 +  FT_Stroker_ExportBorder( FT_Stroker        stroker,
 408.562 +                           FT_StrokerBorder  border,
 408.563 +                           FT_Outline*       outline );
 408.564 +
 408.565 +
 408.566 +  /**************************************************************
 408.567 +   *
 408.568 +   * @function:
 408.569 +   *   FT_Stroker_GetCounts
 408.570 +   *
 408.571 +   * @description:
 408.572 +   *   Call this function once you have finished parsing your paths
 408.573 +   *   with the stroker.  It returns the number of points and
 408.574 +   *   contours necessary to export all points/borders from the stroked
 408.575 +   *   outline/path.
 408.576 +   *
 408.577 +   * @input:
 408.578 +   *   stroker ::
 408.579 +   *     The target stroker handle.
 408.580 +   *
 408.581 +   * @output:
 408.582 +   *   anum_points ::
 408.583 +   *     The number of points.
 408.584 +   *
 408.585 +   *   anum_contours ::
 408.586 +   *     The number of contours.
 408.587 +   *
 408.588 +   * @return:
 408.589 +   *   FreeType error code.  0~means success.
 408.590 +   */
 408.591 +  FT_EXPORT( FT_Error )
 408.592 +  FT_Stroker_GetCounts( FT_Stroker  stroker,
 408.593 +                        FT_UInt    *anum_points,
 408.594 +                        FT_UInt    *anum_contours );
 408.595 +
 408.596 +
 408.597 +  /**************************************************************
 408.598 +   *
 408.599 +   * @function:
 408.600 +   *   FT_Stroker_Export
 408.601 +   *
 408.602 +   * @description:
 408.603 +   *   Call this function after @FT_Stroker_GetBorderCounts to
 408.604 +   *   export all borders to your own @FT_Outline structure.
 408.605 +   *
 408.606 +   *   Note that this function appends the border points and
 408.607 +   *   contours to your outline, but does not try to resize its
 408.608 +   *   arrays.
 408.609 +   *
 408.610 +   * @input:
 408.611 +   *   stroker ::
 408.612 +   *     The target stroker handle.
 408.613 +   *
 408.614 +   *   outline ::
 408.615 +   *     The target outline handle.
 408.616 +   */
 408.617 +  FT_EXPORT( void )
 408.618 +  FT_Stroker_Export( FT_Stroker   stroker,
 408.619 +                     FT_Outline*  outline );
 408.620 +
 408.621 +
 408.622 +  /**************************************************************
 408.623 +   *
 408.624 +   * @function:
 408.625 +   *   FT_Stroker_Done
 408.626 +   *
 408.627 +   * @description:
 408.628 +   *   Destroy a stroker object.
 408.629 +   *
 408.630 +   * @input:
 408.631 +   *   stroker ::
 408.632 +   *     A stroker handle.  Can be NULL.
 408.633 +   */
 408.634 +  FT_EXPORT( void )
 408.635 +  FT_Stroker_Done( FT_Stroker  stroker );
 408.636 +
 408.637 +
 408.638 +  /**************************************************************
 408.639 +   *
 408.640 +   * @function:
 408.641 +   *   FT_Glyph_Stroke
 408.642 +   *
 408.643 +   * @description:
 408.644 +   *   Stroke a given outline glyph object with a given stroker.
 408.645 +   *
 408.646 +   * @inout:
 408.647 +   *   pglyph ::
 408.648 +   *     Source glyph handle on input, new glyph handle on output.
 408.649 +   *
 408.650 +   * @input:
 408.651 +   *   stroker ::
 408.652 +   *     A stroker handle.
 408.653 +   *
 408.654 +   *   destroy ::
 408.655 +   *     A Boolean.  If~1, the source glyph object is destroyed
 408.656 +   *     on success.
 408.657 +   *
 408.658 +   * @return:
 408.659 +   *    FreeType error code.  0~means success.
 408.660 +   *
 408.661 +   * @note:
 408.662 +   *   The source glyph is untouched in case of error.
 408.663 +   */
 408.664 +  FT_EXPORT( FT_Error )
 408.665 +  FT_Glyph_Stroke( FT_Glyph    *pglyph,
 408.666 +                   FT_Stroker   stroker,
 408.667 +                   FT_Bool      destroy );
 408.668 +
 408.669 +
 408.670 +  /**************************************************************
 408.671 +   *
 408.672 +   * @function:
 408.673 +   *   FT_Glyph_StrokeBorder
 408.674 +   *
 408.675 +   * @description:
 408.676 +   *   Stroke a given outline glyph object with a given stroker, but
 408.677 +   *   only return either its inside or outside border.
 408.678 +   *
 408.679 +   * @inout:
 408.680 +   *   pglyph ::
 408.681 +   *     Source glyph handle on input, new glyph handle on output.
 408.682 +   *
 408.683 +   * @input:
 408.684 +   *   stroker ::
 408.685 +   *     A stroker handle.
 408.686 +   *
 408.687 +   *   inside ::
 408.688 +   *     A Boolean.  If~1, return the inside border, otherwise
 408.689 +   *     the outside border.
 408.690 +   *
 408.691 +   *   destroy ::
 408.692 +   *     A Boolean.  If~1, the source glyph object is destroyed
 408.693 +   *     on success.
 408.694 +   *
 408.695 +   * @return:
 408.696 +   *    FreeType error code.  0~means success.
 408.697 +   *
 408.698 +   * @note:
 408.699 +   *   The source glyph is untouched in case of error.
 408.700 +   */
 408.701 +  FT_EXPORT( FT_Error )
 408.702 +  FT_Glyph_StrokeBorder( FT_Glyph    *pglyph,
 408.703 +                         FT_Stroker   stroker,
 408.704 +                         FT_Bool      inside,
 408.705 +                         FT_Bool      destroy );
 408.706 +
 408.707 + /* */
 408.708 +
 408.709 +FT_END_HEADER
 408.710 +
 408.711 +#endif /* __FT_STROKE_H__ */
 408.712 +
 408.713 +
 408.714 +/* END */
 408.715 +
 408.716 +
 408.717 +/* Local Variables: */
 408.718 +/* coding: utf-8    */
 408.719 +/* End:             */
   409.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   409.2 +++ b/libs/ft2static/freetype/ftsynth.h	Sat Feb 01 19:58:19 2014 +0200
   409.3 @@ -0,0 +1,80 @@
   409.4 +/***************************************************************************/
   409.5 +/*                                                                         */
   409.6 +/*  ftsynth.h                                                              */
   409.7 +/*                                                                         */
   409.8 +/*    FreeType synthesizing code for emboldening and slanting              */
   409.9 +/*    (specification).                                                     */
  409.10 +/*                                                                         */
  409.11 +/*  Copyright 2000-2001, 2003, 2006, 2008 by                               */
  409.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  409.13 +/*                                                                         */
  409.14 +/*  This file is part of the FreeType project, and may only be used,       */
  409.15 +/*  modified, and distributed under the terms of the FreeType project      */
  409.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  409.17 +/*  this file you indicate that you have read the license and              */
  409.18 +/*  understand and accept it fully.                                        */
  409.19 +/*                                                                         */
  409.20 +/***************************************************************************/
  409.21 +
  409.22 +
  409.23 +  /*************************************************************************/
  409.24 +  /*************************************************************************/
  409.25 +  /*************************************************************************/
  409.26 +  /*************************************************************************/
  409.27 +  /*************************************************************************/
  409.28 +  /*********                                                       *********/
  409.29 +  /*********        WARNING, THIS IS ALPHA CODE!  THIS API         *********/
  409.30 +  /*********    IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE    *********/
  409.31 +  /*********            FREETYPE DEVELOPMENT TEAM                  *********/
  409.32 +  /*********                                                       *********/
  409.33 +  /*************************************************************************/
  409.34 +  /*************************************************************************/
  409.35 +  /*************************************************************************/
  409.36 +  /*************************************************************************/
  409.37 +  /*************************************************************************/
  409.38 +
  409.39 +
  409.40 +  /* Main reason for not lifting the functions in this module to a  */
  409.41 +  /* `standard' API is that the used parameters for emboldening and */
  409.42 +  /* slanting are not configurable.  Consider the functions as a    */
  409.43 +  /* code resource which should be copied into the application and  */
  409.44 +  /* adapted to the particular needs.                               */
  409.45 +
  409.46 +
  409.47 +#ifndef __FTSYNTH_H__
  409.48 +#define __FTSYNTH_H__
  409.49 +
  409.50 +
  409.51 +#include <ft2build.h>
  409.52 +#include FT_FREETYPE_H
  409.53 +
  409.54 +#ifdef FREETYPE_H
  409.55 +#error "freetype.h of FreeType 1 has been loaded!"
  409.56 +#error "Please fix the directory search order for header files"
  409.57 +#error "so that freetype.h of FreeType 2 is found first."
  409.58 +#endif
  409.59 +
  409.60 +
  409.61 +FT_BEGIN_HEADER
  409.62 +
  409.63 +  /* Embolden a glyph by a `reasonable' value (which is highly a matter of */
  409.64 +  /* taste).  This function is actually a convenience function, providing  */
  409.65 +  /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden.           */
  409.66 +  /*                                                                       */
  409.67 +  /* For emboldened outlines the metrics are estimates only; if you need   */
  409.68 +  /* precise values you should call @FT_Outline_Get_CBox.                  */
  409.69 +  FT_EXPORT( void )
  409.70 +  FT_GlyphSlot_Embolden( FT_GlyphSlot  slot );
  409.71 +
  409.72 +  /* Slant an outline glyph to the right by about 12 degrees. */
  409.73 +  FT_EXPORT( void )
  409.74 +  FT_GlyphSlot_Oblique( FT_GlyphSlot  slot );
  409.75 +
  409.76 +  /* */
  409.77 +
  409.78 +FT_END_HEADER
  409.79 +
  409.80 +#endif /* __FTSYNTH_H__ */
  409.81 +
  409.82 +
  409.83 +/* END */
   410.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   410.2 +++ b/libs/ft2static/freetype/ftsystem.h	Sat Feb 01 19:58:19 2014 +0200
   410.3 @@ -0,0 +1,347 @@
   410.4 +/***************************************************************************/
   410.5 +/*                                                                         */
   410.6 +/*  ftsystem.h                                                             */
   410.7 +/*                                                                         */
   410.8 +/*    FreeType low-level system interface definition (specification).      */
   410.9 +/*                                                                         */
  410.10 +/*  Copyright 1996-2001, 2002, 2005, 2010 by                               */
  410.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  410.12 +/*                                                                         */
  410.13 +/*  This file is part of the FreeType project, and may only be used,       */
  410.14 +/*  modified, and distributed under the terms of the FreeType project      */
  410.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  410.16 +/*  this file you indicate that you have read the license and              */
  410.17 +/*  understand and accept it fully.                                        */
  410.18 +/*                                                                         */
  410.19 +/***************************************************************************/
  410.20 +
  410.21 +
  410.22 +#ifndef __FTSYSTEM_H__
  410.23 +#define __FTSYSTEM_H__
  410.24 +
  410.25 +
  410.26 +#include <ft2build.h>
  410.27 +
  410.28 +
  410.29 +FT_BEGIN_HEADER
  410.30 +
  410.31 +
  410.32 +  /*************************************************************************/
  410.33 +  /*                                                                       */
  410.34 +  /* <Section>                                                             */
  410.35 +  /*   system_interface                                                    */
  410.36 +  /*                                                                       */
  410.37 +  /* <Title>                                                               */
  410.38 +  /*   System Interface                                                    */
  410.39 +  /*                                                                       */
  410.40 +  /* <Abstract>                                                            */
  410.41 +  /*   How FreeType manages memory and i/o.                                */
  410.42 +  /*                                                                       */
  410.43 +  /* <Description>                                                         */
  410.44 +  /*   This section contains various definitions related to memory         */
  410.45 +  /*   management and i/o access.  You need to understand this             */
  410.46 +  /*   information if you want to use a custom memory manager or you own   */
  410.47 +  /*   i/o streams.                                                        */
  410.48 +  /*                                                                       */
  410.49 +  /*************************************************************************/
  410.50 +
  410.51 +
  410.52 +  /*************************************************************************/
  410.53 +  /*                                                                       */
  410.54 +  /*                  M E M O R Y   M A N A G E M E N T                    */
  410.55 +  /*                                                                       */
  410.56 +  /*************************************************************************/
  410.57 +
  410.58 +
  410.59 +  /*************************************************************************
  410.60 +   *
  410.61 +   * @type:
  410.62 +   *   FT_Memory
  410.63 +   *
  410.64 +   * @description:
  410.65 +   *   A handle to a given memory manager object, defined with an
  410.66 +   *   @FT_MemoryRec structure.
  410.67 +   *
  410.68 +   */
  410.69 +  typedef struct FT_MemoryRec_*  FT_Memory;
  410.70 +
  410.71 +
  410.72 +  /*************************************************************************
  410.73 +   *
  410.74 +   * @functype:
  410.75 +   *   FT_Alloc_Func
  410.76 +   *
  410.77 +   * @description:
  410.78 +   *   A function used to allocate `size' bytes from `memory'.
  410.79 +   *
  410.80 +   * @input:
  410.81 +   *   memory ::
  410.82 +   *     A handle to the source memory manager.
  410.83 +   *
  410.84 +   *   size ::
  410.85 +   *     The size in bytes to allocate.
  410.86 +   *
  410.87 +   * @return:
  410.88 +   *   Address of new memory block.  0~in case of failure.
  410.89 +   *
  410.90 +   */
  410.91 +  typedef void*
  410.92 +  (*FT_Alloc_Func)( FT_Memory  memory,
  410.93 +                    long       size );
  410.94 +
  410.95 +
  410.96 +  /*************************************************************************
  410.97 +   *
  410.98 +   * @functype:
  410.99 +   *   FT_Free_Func
 410.100 +   *
 410.101 +   * @description:
 410.102 +   *   A function used to release a given block of memory.
 410.103 +   *
 410.104 +   * @input:
 410.105 +   *   memory ::
 410.106 +   *     A handle to the source memory manager.
 410.107 +   *
 410.108 +   *   block ::
 410.109 +   *     The address of the target memory block.
 410.110 +   *
 410.111 +   */
 410.112 +  typedef void
 410.113 +  (*FT_Free_Func)( FT_Memory  memory,
 410.114 +                   void*      block );
 410.115 +
 410.116 +
 410.117 +  /*************************************************************************
 410.118 +   *
 410.119 +   * @functype:
 410.120 +   *   FT_Realloc_Func
 410.121 +   *
 410.122 +   * @description:
 410.123 +   *   A function used to re-allocate a given block of memory.
 410.124 +   *
 410.125 +   * @input:
 410.126 +   *   memory ::
 410.127 +   *     A handle to the source memory manager.
 410.128 +   *
 410.129 +   *   cur_size ::
 410.130 +   *     The block's current size in bytes.
 410.131 +   *
 410.132 +   *   new_size ::
 410.133 +   *     The block's requested new size.
 410.134 +   *
 410.135 +   *   block ::
 410.136 +   *     The block's current address.
 410.137 +   *
 410.138 +   * @return:
 410.139 +   *   New block address.  0~in case of memory shortage.
 410.140 +   *
 410.141 +   * @note:
 410.142 +   *   In case of error, the old block must still be available.
 410.143 +   *
 410.144 +   */
 410.145 +  typedef void*
 410.146 +  (*FT_Realloc_Func)( FT_Memory  memory,
 410.147 +                      long       cur_size,
 410.148 +                      long       new_size,
 410.149 +                      void*      block );
 410.150 +
 410.151 +
 410.152 +  /*************************************************************************
 410.153 +   *
 410.154 +   * @struct:
 410.155 +   *   FT_MemoryRec
 410.156 +   *
 410.157 +   * @description:
 410.158 +   *   A structure used to describe a given memory manager to FreeType~2.
 410.159 +   *
 410.160 +   * @fields:
 410.161 +   *   user ::
 410.162 +   *     A generic typeless pointer for user data.
 410.163 +   *
 410.164 +   *   alloc ::
 410.165 +   *     A pointer type to an allocation function.
 410.166 +   *
 410.167 +   *   free ::
 410.168 +   *     A pointer type to an memory freeing function.
 410.169 +   *
 410.170 +   *   realloc ::
 410.171 +   *     A pointer type to a reallocation function.
 410.172 +   *
 410.173 +   */
 410.174 +  struct  FT_MemoryRec_
 410.175 +  {
 410.176 +    void*            user;
 410.177 +    FT_Alloc_Func    alloc;
 410.178 +    FT_Free_Func     free;
 410.179 +    FT_Realloc_Func  realloc;
 410.180 +  };
 410.181 +
 410.182 +
 410.183 +  /*************************************************************************/
 410.184 +  /*                                                                       */
 410.185 +  /*                       I / O   M A N A G E M E N T                     */
 410.186 +  /*                                                                       */
 410.187 +  /*************************************************************************/
 410.188 +
 410.189 +
 410.190 +  /*************************************************************************
 410.191 +   *
 410.192 +   * @type:
 410.193 +   *   FT_Stream
 410.194 +   *
 410.195 +   * @description:
 410.196 +   *   A handle to an input stream.
 410.197 +   *
 410.198 +   */
 410.199 +  typedef struct FT_StreamRec_*  FT_Stream;
 410.200 +
 410.201 +
 410.202 +  /*************************************************************************
 410.203 +   *
 410.204 +   * @struct:
 410.205 +   *   FT_StreamDesc
 410.206 +   *
 410.207 +   * @description:
 410.208 +   *   A union type used to store either a long or a pointer.  This is used
 410.209 +   *   to store a file descriptor or a `FILE*' in an input stream.
 410.210 +   *
 410.211 +   */
 410.212 +  typedef union  FT_StreamDesc_
 410.213 +  {
 410.214 +    long   value;
 410.215 +    void*  pointer;
 410.216 +
 410.217 +  } FT_StreamDesc;
 410.218 +
 410.219 +
 410.220 +  /*************************************************************************
 410.221 +   *
 410.222 +   * @functype:
 410.223 +   *   FT_Stream_IoFunc
 410.224 +   *
 410.225 +   * @description:
 410.226 +   *   A function used to seek and read data from a given input stream.
 410.227 +   *
 410.228 +   * @input:
 410.229 +   *   stream ::
 410.230 +   *     A handle to the source stream.
 410.231 +   *
 410.232 +   *   offset ::
 410.233 +   *     The offset of read in stream (always from start).
 410.234 +   *
 410.235 +   *   buffer ::
 410.236 +   *     The address of the read buffer.
 410.237 +   *
 410.238 +   *   count ::
 410.239 +   *     The number of bytes to read from the stream.
 410.240 +   *
 410.241 +   * @return:
 410.242 +   *   The number of bytes effectively read by the stream.
 410.243 +   *
 410.244 +   * @note:
 410.245 +   *   This function might be called to perform a seek or skip operation
 410.246 +   *   with a `count' of~0.  A non-zero return value then indicates an
 410.247 +   *   error.
 410.248 +   *
 410.249 +   */
 410.250 +  typedef unsigned long
 410.251 +  (*FT_Stream_IoFunc)( FT_Stream       stream,
 410.252 +                       unsigned long   offset,
 410.253 +                       unsigned char*  buffer,
 410.254 +                       unsigned long   count );
 410.255 +
 410.256 +
 410.257 +  /*************************************************************************
 410.258 +   *
 410.259 +   * @functype:
 410.260 +   *   FT_Stream_CloseFunc
 410.261 +   *
 410.262 +   * @description:
 410.263 +   *   A function used to close a given input stream.
 410.264 +   *
 410.265 +   * @input:
 410.266 +   *  stream ::
 410.267 +   *     A handle to the target stream.
 410.268 +   *
 410.269 +   */
 410.270 +  typedef void
 410.271 +  (*FT_Stream_CloseFunc)( FT_Stream  stream );
 410.272 +
 410.273 +
 410.274 +  /*************************************************************************
 410.275 +   *
 410.276 +   * @struct:
 410.277 +   *   FT_StreamRec
 410.278 +   *
 410.279 +   * @description:
 410.280 +   *   A structure used to describe an input stream.
 410.281 +   *
 410.282 +   * @input:
 410.283 +   *   base ::
 410.284 +   *     For memory-based streams, this is the address of the first stream
 410.285 +   *     byte in memory.  This field should always be set to NULL for
 410.286 +   *     disk-based streams.
 410.287 +   *
 410.288 +   *   size ::
 410.289 +   *     The stream size in bytes.
 410.290 +   *
 410.291 +   *   pos ::
 410.292 +   *     The current position within the stream.
 410.293 +   *
 410.294 +   *   descriptor ::
 410.295 +   *     This field is a union that can hold an integer or a pointer.  It is
 410.296 +   *     used by stream implementations to store file descriptors or `FILE*'
 410.297 +   *     pointers.
 410.298 +   *
 410.299 +   *   pathname ::
 410.300 +   *     This field is completely ignored by FreeType.  However, it is often
 410.301 +   *     useful during debugging to use it to store the stream's filename
 410.302 +   *     (where available).
 410.303 +   *
 410.304 +   *   read ::
 410.305 +   *     The stream's input function.
 410.306 +   *
 410.307 +   *   close ::
 410.308 +   *     The stream's close function.
 410.309 +   *
 410.310 +   *   memory ::
 410.311 +   *     The memory manager to use to preload frames.  This is set
 410.312 +   *     internally by FreeType and shouldn't be touched by stream
 410.313 +   *     implementations.
 410.314 +   *
 410.315 +   *   cursor ::
 410.316 +   *     This field is set and used internally by FreeType when parsing
 410.317 +   *     frames.
 410.318 +   *
 410.319 +   *   limit ::
 410.320 +   *     This field is set and used internally by FreeType when parsing
 410.321 +   *     frames.
 410.322 +   *
 410.323 +   */
 410.324 +  typedef struct  FT_StreamRec_
 410.325 +  {
 410.326 +    unsigned char*       base;
 410.327 +    unsigned long        size;
 410.328 +    unsigned long        pos;
 410.329 +
 410.330 +    FT_StreamDesc        descriptor;
 410.331 +    FT_StreamDesc        pathname;
 410.332 +    FT_Stream_IoFunc     read;
 410.333 +    FT_Stream_CloseFunc  close;
 410.334 +
 410.335 +    FT_Memory            memory;
 410.336 +    unsigned char*       cursor;
 410.337 +    unsigned char*       limit;
 410.338 +
 410.339 +  } FT_StreamRec;
 410.340 +
 410.341 +
 410.342 +  /* */
 410.343 +
 410.344 +
 410.345 +FT_END_HEADER
 410.346 +
 410.347 +#endif /* __FTSYSTEM_H__ */
 410.348 +
 410.349 +
 410.350 +/* END */
   411.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   411.2 +++ b/libs/ft2static/freetype/fttrigon.h	Sat Feb 01 19:58:19 2014 +0200
   411.3 @@ -0,0 +1,350 @@
   411.4 +/***************************************************************************/
   411.5 +/*                                                                         */
   411.6 +/*  fttrigon.h                                                             */
   411.7 +/*                                                                         */
   411.8 +/*    FreeType trigonometric functions (specification).                    */
   411.9 +/*                                                                         */
  411.10 +/*  Copyright 2001, 2003, 2005, 2007 by                                    */
  411.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  411.12 +/*                                                                         */
  411.13 +/*  This file is part of the FreeType project, and may only be used,       */
  411.14 +/*  modified, and distributed under the terms of the FreeType project      */
  411.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  411.16 +/*  this file you indicate that you have read the license and              */
  411.17 +/*  understand and accept it fully.                                        */
  411.18 +/*                                                                         */
  411.19 +/***************************************************************************/
  411.20 +
  411.21 +
  411.22 +#ifndef __FTTRIGON_H__
  411.23 +#define __FTTRIGON_H__
  411.24 +
  411.25 +#include FT_FREETYPE_H
  411.26 +
  411.27 +#ifdef FREETYPE_H
  411.28 +#error "freetype.h of FreeType 1 has been loaded!"
  411.29 +#error "Please fix the directory search order for header files"
  411.30 +#error "so that freetype.h of FreeType 2 is found first."
  411.31 +#endif
  411.32 +
  411.33 +
  411.34 +FT_BEGIN_HEADER
  411.35 +
  411.36 +
  411.37 +  /*************************************************************************/
  411.38 +  /*                                                                       */
  411.39 +  /* <Section>                                                             */
  411.40 +  /*   computations                                                        */
  411.41 +  /*                                                                       */
  411.42 +  /*************************************************************************/
  411.43 +
  411.44 +
  411.45 +  /*************************************************************************
  411.46 +   *
  411.47 +   * @type:
  411.48 +   *   FT_Angle
  411.49 +   *
  411.50 +   * @description:
  411.51 +   *   This type is used to model angle values in FreeType.  Note that the
  411.52 +   *   angle is a 16.16 fixed float value expressed in degrees.
  411.53 +   *
  411.54 +   */
  411.55 +  typedef FT_Fixed  FT_Angle;
  411.56 +
  411.57 +
  411.58 +  /*************************************************************************
  411.59 +   *
  411.60 +   * @macro:
  411.61 +   *   FT_ANGLE_PI
  411.62 +   *
  411.63 +   * @description:
  411.64 +   *   The angle pi expressed in @FT_Angle units.
  411.65 +   *
  411.66 +   */
  411.67 +#define FT_ANGLE_PI  ( 180L << 16 )
  411.68 +
  411.69 +
  411.70 +  /*************************************************************************
  411.71 +   *
  411.72 +   * @macro:
  411.73 +   *   FT_ANGLE_2PI
  411.74 +   *
  411.75 +   * @description:
  411.76 +   *   The angle 2*pi expressed in @FT_Angle units.
  411.77 +   *
  411.78 +   */
  411.79 +#define FT_ANGLE_2PI  ( FT_ANGLE_PI * 2 )
  411.80 +
  411.81 +
  411.82 +  /*************************************************************************
  411.83 +   *
  411.84 +   * @macro:
  411.85 +   *   FT_ANGLE_PI2
  411.86 +   *
  411.87 +   * @description:
  411.88 +   *   The angle pi/2 expressed in @FT_Angle units.
  411.89 +   *
  411.90 +   */
  411.91 +#define FT_ANGLE_PI2  ( FT_ANGLE_PI / 2 )
  411.92 +
  411.93 +
  411.94 +  /*************************************************************************
  411.95 +   *
  411.96 +   * @macro:
  411.97 +   *   FT_ANGLE_PI4
  411.98 +   *
  411.99 +   * @description:
 411.100 +   *   The angle pi/4 expressed in @FT_Angle units.
 411.101 +   *
 411.102 +   */
 411.103 +#define FT_ANGLE_PI4  ( FT_ANGLE_PI / 4 )
 411.104 +
 411.105 +
 411.106 +  /*************************************************************************
 411.107 +   *
 411.108 +   * @function:
 411.109 +   *   FT_Sin
 411.110 +   *
 411.111 +   * @description:
 411.112 +   *   Return the sinus of a given angle in fixed point format.
 411.113 +   *
 411.114 +   * @input:
 411.115 +   *   angle ::
 411.116 +   *     The input angle.
 411.117 +   *
 411.118 +   * @return:
 411.119 +   *   The sinus value.
 411.120 +   *
 411.121 +   * @note:
 411.122 +   *   If you need both the sinus and cosinus for a given angle, use the
 411.123 +   *   function @FT_Vector_Unit.
 411.124 +   *
 411.125 +   */
 411.126 +  FT_EXPORT( FT_Fixed )
 411.127 +  FT_Sin( FT_Angle  angle );
 411.128 +
 411.129 +
 411.130 +  /*************************************************************************
 411.131 +   *
 411.132 +   * @function:
 411.133 +   *   FT_Cos
 411.134 +   *
 411.135 +   * @description:
 411.136 +   *   Return the cosinus of a given angle in fixed point format.
 411.137 +   *
 411.138 +   * @input:
 411.139 +   *   angle ::
 411.140 +   *     The input angle.
 411.141 +   *
 411.142 +   * @return:
 411.143 +   *   The cosinus value.
 411.144 +   *
 411.145 +   * @note:
 411.146 +   *   If you need both the sinus and cosinus for a given angle, use the
 411.147 +   *   function @FT_Vector_Unit.
 411.148 +   *
 411.149 +   */
 411.150 +  FT_EXPORT( FT_Fixed )
 411.151 +  FT_Cos( FT_Angle  angle );
 411.152 +
 411.153 +
 411.154 +  /*************************************************************************
 411.155 +   *
 411.156 +   * @function:
 411.157 +   *   FT_Tan
 411.158 +   *
 411.159 +   * @description:
 411.160 +   *   Return the tangent of a given angle in fixed point format.
 411.161 +   *
 411.162 +   * @input:
 411.163 +   *   angle ::
 411.164 +   *     The input angle.
 411.165 +   *
 411.166 +   * @return:
 411.167 +   *   The tangent value.
 411.168 +   *
 411.169 +   */
 411.170 +  FT_EXPORT( FT_Fixed )
 411.171 +  FT_Tan( FT_Angle  angle );
 411.172 +
 411.173 +
 411.174 +  /*************************************************************************
 411.175 +   *
 411.176 +   * @function:
 411.177 +   *   FT_Atan2
 411.178 +   *
 411.179 +   * @description:
 411.180 +   *   Return the arc-tangent corresponding to a given vector (x,y) in
 411.181 +   *   the 2d plane.
 411.182 +   *
 411.183 +   * @input:
 411.184 +   *   x ::
 411.185 +   *     The horizontal vector coordinate.
 411.186 +   *
 411.187 +   *   y ::
 411.188 +   *     The vertical vector coordinate.
 411.189 +   *
 411.190 +   * @return:
 411.191 +   *   The arc-tangent value (i.e. angle).
 411.192 +   *
 411.193 +   */
 411.194 +  FT_EXPORT( FT_Angle )
 411.195 +  FT_Atan2( FT_Fixed  x,
 411.196 +            FT_Fixed  y );
 411.197 +
 411.198 +
 411.199 +  /*************************************************************************
 411.200 +   *
 411.201 +   * @function:
 411.202 +   *   FT_Angle_Diff
 411.203 +   *
 411.204 +   * @description:
 411.205 +   *   Return the difference between two angles.  The result is always
 411.206 +   *   constrained to the ]-PI..PI] interval.
 411.207 +   *
 411.208 +   * @input:
 411.209 +   *   angle1 ::
 411.210 +   *     First angle.
 411.211 +   *
 411.212 +   *   angle2 ::
 411.213 +   *     Second angle.
 411.214 +   *
 411.215 +   * @return:
 411.216 +   *   Constrained value of `value2-value1'.
 411.217 +   *
 411.218 +   */
 411.219 +  FT_EXPORT( FT_Angle )
 411.220 +  FT_Angle_Diff( FT_Angle  angle1,
 411.221 +                 FT_Angle  angle2 );
 411.222 +
 411.223 +
 411.224 +  /*************************************************************************
 411.225 +   *
 411.226 +   * @function:
 411.227 +   *   FT_Vector_Unit
 411.228 +   *
 411.229 +   * @description:
 411.230 +   *   Return the unit vector corresponding to a given angle.  After the
 411.231 +   *   call, the value of `vec.x' will be `sin(angle)', and the value of
 411.232 +   *   `vec.y' will be `cos(angle)'.
 411.233 +   *
 411.234 +   *   This function is useful to retrieve both the sinus and cosinus of a
 411.235 +   *   given angle quickly.
 411.236 +   *
 411.237 +   * @output:
 411.238 +   *   vec ::
 411.239 +   *     The address of target vector.
 411.240 +   *
 411.241 +   * @input:
 411.242 +   *   angle ::
 411.243 +   *     The address of angle.
 411.244 +   *
 411.245 +   */
 411.246 +  FT_EXPORT( void )
 411.247 +  FT_Vector_Unit( FT_Vector*  vec,
 411.248 +                  FT_Angle    angle );
 411.249 +
 411.250 +
 411.251 +  /*************************************************************************
 411.252 +   *
 411.253 +   * @function:
 411.254 +   *   FT_Vector_Rotate
 411.255 +   *
 411.256 +   * @description:
 411.257 +   *   Rotate a vector by a given angle.
 411.258 +   *
 411.259 +   * @inout:
 411.260 +   *   vec ::
 411.261 +   *     The address of target vector.
 411.262 +   *
 411.263 +   * @input:
 411.264 +   *   angle ::
 411.265 +   *     The address of angle.
 411.266 +   *
 411.267 +   */
 411.268 +  FT_EXPORT( void )
 411.269 +  FT_Vector_Rotate( FT_Vector*  vec,
 411.270 +                    FT_Angle    angle );
 411.271 +
 411.272 +
 411.273 +  /*************************************************************************
 411.274 +   *
 411.275 +   * @function:
 411.276 +   *   FT_Vector_Length
 411.277 +   *
 411.278 +   * @description:
 411.279 +   *   Return the length of a given vector.
 411.280 +   *
 411.281 +   * @input:
 411.282 +   *   vec ::
 411.283 +   *     The address of target vector.
 411.284 +   *
 411.285 +   * @return:
 411.286 +   *   The vector length, expressed in the same units that the original
 411.287 +   *   vector coordinates.
 411.288 +   *
 411.289 +   */
 411.290 +  FT_EXPORT( FT_Fixed )
 411.291 +  FT_Vector_Length( FT_Vector*  vec );
 411.292 +
 411.293 +
 411.294 +  /*************************************************************************
 411.295 +   *
 411.296 +   * @function:
 411.297 +   *   FT_Vector_Polarize
 411.298 +   *
 411.299 +   * @description:
 411.300 +   *   Compute both the length and angle of a given vector.
 411.301 +   *
 411.302 +   * @input:
 411.303 +   *   vec ::
 411.304 +   *     The address of source vector.
 411.305 +   *
 411.306 +   * @output:
 411.307 +   *   length ::
 411.308 +   *     The vector length.
 411.309 +   *
 411.310 +   *   angle ::
 411.311 +   *     The vector angle.
 411.312 +   *
 411.313 +   */
 411.314 +  FT_EXPORT( void )
 411.315 +  FT_Vector_Polarize( FT_Vector*  vec,
 411.316 +                      FT_Fixed   *length,
 411.317 +                      FT_Angle   *angle );
 411.318 +
 411.319 +
 411.320 +  /*************************************************************************
 411.321 +   *
 411.322 +   * @function:
 411.323 +   *   FT_Vector_From_Polar
 411.324 +   *
 411.325 +   * @description:
 411.326 +   *   Compute vector coordinates from a length and angle.
 411.327 +   *
 411.328 +   * @output:
 411.329 +   *   vec ::
 411.330 +   *     The address of source vector.
 411.331 +   *
 411.332 +   * @input:
 411.333 +   *   length ::
 411.334 +   *     The vector length.
 411.335 +   *
 411.336 +   *   angle ::
 411.337 +   *     The vector angle.
 411.338 +   *
 411.339 +   */
 411.340 +  FT_EXPORT( void )
 411.341 +  FT_Vector_From_Polar( FT_Vector*  vec,
 411.342 +                        FT_Fixed    length,
 411.343 +                        FT_Angle    angle );
 411.344 +
 411.345 +  /* */
 411.346 +
 411.347 +
 411.348 +FT_END_HEADER
 411.349 +
 411.350 +#endif /* __FTTRIGON_H__ */
 411.351 +
 411.352 +
 411.353 +/* END */
   412.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   412.2 +++ b/libs/ft2static/freetype/fttypes.h	Sat Feb 01 19:58:19 2014 +0200
   412.3 @@ -0,0 +1,588 @@
   412.4 +/***************************************************************************/
   412.5 +/*                                                                         */
   412.6 +/*  fttypes.h                                                              */
   412.7 +/*                                                                         */
   412.8 +/*    FreeType simple types definitions (specification only).              */
   412.9 +/*                                                                         */
  412.10 +/*  Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008 by                   */
  412.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  412.12 +/*                                                                         */
  412.13 +/*  This file is part of the FreeType project, and may only be used,       */
  412.14 +/*  modified, and distributed under the terms of the FreeType project      */
  412.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  412.16 +/*  this file you indicate that you have read the license and              */
  412.17 +/*  understand and accept it fully.                                        */
  412.18 +/*                                                                         */
  412.19 +/***************************************************************************/
  412.20 +
  412.21 +
  412.22 +#ifndef __FTTYPES_H__
  412.23 +#define __FTTYPES_H__
  412.24 +
  412.25 +
  412.26 +#include <ft2build.h>
  412.27 +#include FT_CONFIG_CONFIG_H
  412.28 +#include FT_SYSTEM_H
  412.29 +#include FT_IMAGE_H
  412.30 +
  412.31 +#include <stddef.h>
  412.32 +
  412.33 +
  412.34 +FT_BEGIN_HEADER
  412.35 +
  412.36 +
  412.37 +  /*************************************************************************/
  412.38 +  /*                                                                       */
  412.39 +  /* <Section>                                                             */
  412.40 +  /*    basic_types                                                        */
  412.41 +  /*                                                                       */
  412.42 +  /* <Title>                                                               */
  412.43 +  /*    Basic Data Types                                                   */
  412.44 +  /*                                                                       */
  412.45 +  /* <Abstract>                                                            */
  412.46 +  /*    The basic data types defined by the library.                       */
  412.47 +  /*                                                                       */
  412.48 +  /* <Description>                                                         */
  412.49 +  /*    This section contains the basic data types defined by FreeType~2,  */
  412.50 +  /*    ranging from simple scalar types to bitmap descriptors.  More      */
  412.51 +  /*    font-specific structures are defined in a different section.       */
  412.52 +  /*                                                                       */
  412.53 +  /* <Order>                                                               */
  412.54 +  /*    FT_Byte                                                            */
  412.55 +  /*    FT_Bytes                                                           */
  412.56 +  /*    FT_Char                                                            */
  412.57 +  /*    FT_Int                                                             */
  412.58 +  /*    FT_UInt                                                            */
  412.59 +  /*    FT_Int16                                                           */
  412.60 +  /*    FT_UInt16                                                          */
  412.61 +  /*    FT_Int32                                                           */
  412.62 +  /*    FT_UInt32                                                          */
  412.63 +  /*    FT_Short                                                           */
  412.64 +  /*    FT_UShort                                                          */
  412.65 +  /*    FT_Long                                                            */
  412.66 +  /*    FT_ULong                                                           */
  412.67 +  /*    FT_Bool                                                            */
  412.68 +  /*    FT_Offset                                                          */
  412.69 +  /*    FT_PtrDist                                                         */
  412.70 +  /*    FT_String                                                          */
  412.71 +  /*    FT_Tag                                                             */
  412.72 +  /*    FT_Error                                                           */
  412.73 +  /*    FT_Fixed                                                           */
  412.74 +  /*    FT_Pointer                                                         */
  412.75 +  /*    FT_Pos                                                             */
  412.76 +  /*    FT_Vector                                                          */
  412.77 +  /*    FT_BBox                                                            */
  412.78 +  /*    FT_Matrix                                                          */
  412.79 +  /*    FT_FWord                                                           */
  412.80 +  /*    FT_UFWord                                                          */
  412.81 +  /*    FT_F2Dot14                                                         */
  412.82 +  /*    FT_UnitVector                                                      */
  412.83 +  /*    FT_F26Dot6                                                         */
  412.84 +  /*                                                                       */
  412.85 +  /*                                                                       */
  412.86 +  /*    FT_Generic                                                         */
  412.87 +  /*    FT_Generic_Finalizer                                               */
  412.88 +  /*                                                                       */
  412.89 +  /*    FT_Bitmap                                                          */
  412.90 +  /*    FT_Pixel_Mode                                                      */
  412.91 +  /*    FT_Palette_Mode                                                    */
  412.92 +  /*    FT_Glyph_Format                                                    */
  412.93 +  /*    FT_IMAGE_TAG                                                       */
  412.94 +  /*                                                                       */
  412.95 +  /*************************************************************************/
  412.96 +
  412.97 +
  412.98 +  /*************************************************************************/
  412.99 +  /*                                                                       */
 412.100 +  /* <Type>                                                                */
 412.101 +  /*    FT_Bool                                                            */
 412.102 +  /*                                                                       */
 412.103 +  /* <Description>                                                         */
 412.104 +  /*    A typedef of unsigned char, used for simple booleans.  As usual,   */
 412.105 +  /*    values 1 and~0 represent true and false, respectively.             */
 412.106 +  /*                                                                       */
 412.107 +  typedef unsigned char  FT_Bool;
 412.108 +
 412.109 +
 412.110 +  /*************************************************************************/
 412.111 +  /*                                                                       */
 412.112 +  /* <Type>                                                                */
 412.113 +  /*    FT_FWord                                                           */
 412.114 +  /*                                                                       */
 412.115 +  /* <Description>                                                         */
 412.116 +  /*    A signed 16-bit integer used to store a distance in original font  */
 412.117 +  /*    units.                                                             */
 412.118 +  /*                                                                       */
 412.119 +  typedef signed short  FT_FWord;   /* distance in FUnits */
 412.120 +
 412.121 +
 412.122 +  /*************************************************************************/
 412.123 +  /*                                                                       */
 412.124 +  /* <Type>                                                                */
 412.125 +  /*    FT_UFWord                                                          */
 412.126 +  /*                                                                       */
 412.127 +  /* <Description>                                                         */
 412.128 +  /*    An unsigned 16-bit integer used to store a distance in original    */
 412.129 +  /*    font units.                                                        */
 412.130 +  /*                                                                       */
 412.131 +  typedef unsigned short  FT_UFWord;  /* unsigned distance */
 412.132 +
 412.133 +
 412.134 +  /*************************************************************************/
 412.135 +  /*                                                                       */
 412.136 +  /* <Type>                                                                */
 412.137 +  /*    FT_Char                                                            */
 412.138 +  /*                                                                       */
 412.139 +  /* <Description>                                                         */
 412.140 +  /*    A simple typedef for the _signed_ char type.                       */
 412.141 +  /*                                                                       */
 412.142 +  typedef signed char  FT_Char;
 412.143 +
 412.144 +
 412.145 +  /*************************************************************************/
 412.146 +  /*                                                                       */
 412.147 +  /* <Type>                                                                */
 412.148 +  /*    FT_Byte                                                            */
 412.149 +  /*                                                                       */
 412.150 +  /* <Description>                                                         */
 412.151 +  /*    A simple typedef for the _unsigned_ char type.                     */
 412.152 +  /*                                                                       */
 412.153 +  typedef unsigned char  FT_Byte;
 412.154 +
 412.155 +
 412.156 +  /*************************************************************************/
 412.157 +  /*                                                                       */
 412.158 +  /* <Type>                                                                */
 412.159 +  /*    FT_Bytes                                                           */
 412.160 +  /*                                                                       */
 412.161 +  /* <Description>                                                         */
 412.162 +  /*    A typedef for constant memory areas.                               */
 412.163 +  /*                                                                       */
 412.164 +  typedef const FT_Byte*  FT_Bytes;
 412.165 +
 412.166 +
 412.167 +  /*************************************************************************/
 412.168 +  /*                                                                       */
 412.169 +  /* <Type>                                                                */
 412.170 +  /*    FT_Tag                                                             */
 412.171 +  /*                                                                       */
 412.172 +  /* <Description>                                                         */
 412.173 +  /*    A typedef for 32-bit tags (as used in the SFNT format).            */
 412.174 +  /*                                                                       */
 412.175 +  typedef FT_UInt32  FT_Tag;
 412.176 +
 412.177 +
 412.178 +  /*************************************************************************/
 412.179 +  /*                                                                       */
 412.180 +  /* <Type>                                                                */
 412.181 +  /*    FT_String                                                          */
 412.182 +  /*                                                                       */
 412.183 +  /* <Description>                                                         */
 412.184 +  /*    A simple typedef for the char type, usually used for strings.      */
 412.185 +  /*                                                                       */
 412.186 +  typedef char  FT_String;
 412.187 +
 412.188 +
 412.189 +  /*************************************************************************/
 412.190 +  /*                                                                       */
 412.191 +  /* <Type>                                                                */
 412.192 +  /*    FT_Short                                                           */
 412.193 +  /*                                                                       */
 412.194 +  /* <Description>                                                         */
 412.195 +  /*    A typedef for signed short.                                        */
 412.196 +  /*                                                                       */
 412.197 +  typedef signed short  FT_Short;
 412.198 +
 412.199 +
 412.200 +  /*************************************************************************/
 412.201 +  /*                                                                       */
 412.202 +  /* <Type>                                                                */
 412.203 +  /*    FT_UShort                                                          */
 412.204 +  /*                                                                       */
 412.205 +  /* <Description>                                                         */
 412.206 +  /*    A typedef for unsigned short.                                      */
 412.207 +  /*                                                                       */
 412.208 +  typedef unsigned short  FT_UShort;
 412.209 +
 412.210 +
 412.211 +  /*************************************************************************/
 412.212 +  /*                                                                       */
 412.213 +  /* <Type>                                                                */
 412.214 +  /*    FT_Int                                                             */
 412.215 +  /*                                                                       */
 412.216 +  /* <Description>                                                         */
 412.217 +  /*    A typedef for the int type.                                        */
 412.218 +  /*                                                                       */
 412.219 +  typedef signed int  FT_Int;
 412.220 +
 412.221 +
 412.222 +  /*************************************************************************/
 412.223 +  /*                                                                       */
 412.224 +  /* <Type>                                                                */
 412.225 +  /*    FT_UInt                                                            */
 412.226 +  /*                                                                       */
 412.227 +  /* <Description>                                                         */
 412.228 +  /*    A typedef for the unsigned int type.                               */
 412.229 +  /*                                                                       */
 412.230 +  typedef unsigned int  FT_UInt;
 412.231 +
 412.232 +
 412.233 +  /*************************************************************************/
 412.234 +  /*                                                                       */
 412.235 +  /* <Type>                                                                */
 412.236 +  /*    FT_Long                                                            */
 412.237 +  /*                                                                       */
 412.238 +  /* <Description>                                                         */
 412.239 +  /*    A typedef for signed long.                                         */
 412.240 +  /*                                                                       */
 412.241 +  typedef signed long  FT_Long;
 412.242 +
 412.243 +
 412.244 +  /*************************************************************************/
 412.245 +  /*                                                                       */
 412.246 +  /* <Type>                                                                */
 412.247 +  /*    FT_ULong                                                           */
 412.248 +  /*                                                                       */
 412.249 +  /* <Description>                                                         */
 412.250 +  /*    A typedef for unsigned long.                                       */
 412.251 +  /*                                                                       */
 412.252 +  typedef unsigned long  FT_ULong;
 412.253 +
 412.254 +
 412.255 +  /*************************************************************************/
 412.256 +  /*                                                                       */
 412.257 +  /* <Type>                                                                */
 412.258 +  /*    FT_F2Dot14                                                         */
 412.259 +  /*                                                                       */
 412.260 +  /* <Description>                                                         */
 412.261 +  /*    A signed 2.14 fixed float type used for unit vectors.              */
 412.262 +  /*                                                                       */
 412.263 +  typedef signed short  FT_F2Dot14;
 412.264 +
 412.265 +
 412.266 +  /*************************************************************************/
 412.267 +  /*                                                                       */
 412.268 +  /* <Type>                                                                */
 412.269 +  /*    FT_F26Dot6                                                         */
 412.270 +  /*                                                                       */
 412.271 +  /* <Description>                                                         */
 412.272 +  /*    A signed 26.6 fixed float type used for vectorial pixel            */
 412.273 +  /*    coordinates.                                                       */
 412.274 +  /*                                                                       */
 412.275 +  typedef signed long  FT_F26Dot6;
 412.276 +
 412.277 +
 412.278 +  /*************************************************************************/
 412.279 +  /*                                                                       */
 412.280 +  /* <Type>                                                                */
 412.281 +  /*    FT_Fixed                                                           */
 412.282 +  /*                                                                       */
 412.283 +  /* <Description>                                                         */
 412.284 +  /*    This type is used to store 16.16 fixed float values, like scaling  */
 412.285 +  /*    values or matrix coefficients.                                     */
 412.286 +  /*                                                                       */
 412.287 +  typedef signed long  FT_Fixed;
 412.288 +
 412.289 +
 412.290 +  /*************************************************************************/
 412.291 +  /*                                                                       */
 412.292 +  /* <Type>                                                                */
 412.293 +  /*    FT_Error                                                           */
 412.294 +  /*                                                                       */
 412.295 +  /* <Description>                                                         */
 412.296 +  /*    The FreeType error code type.  A value of~0 is always interpreted  */
 412.297 +  /*    as a successful operation.                                         */
 412.298 +  /*                                                                       */
 412.299 +  typedef int  FT_Error;
 412.300 +
 412.301 +
 412.302 +  /*************************************************************************/
 412.303 +  /*                                                                       */
 412.304 +  /* <Type>                                                                */
 412.305 +  /*    FT_Pointer                                                         */
 412.306 +  /*                                                                       */
 412.307 +  /* <Description>                                                         */
 412.308 +  /*    A simple typedef for a typeless pointer.                           */
 412.309 +  /*                                                                       */
 412.310 +  typedef void*  FT_Pointer;
 412.311 +
 412.312 +
 412.313 +  /*************************************************************************/
 412.314 +  /*                                                                       */
 412.315 +  /* <Type>                                                                */
 412.316 +  /*    FT_Offset                                                          */
 412.317 +  /*                                                                       */
 412.318 +  /* <Description>                                                         */
 412.319 +  /*    This is equivalent to the ANSI~C `size_t' type, i.e., the largest  */
 412.320 +  /*    _unsigned_ integer type used to express a file size or position,   */
 412.321 +  /*    or a memory block size.                                            */
 412.322 +  /*                                                                       */
 412.323 +  typedef size_t  FT_Offset;
 412.324 +
 412.325 +
 412.326 +  /*************************************************************************/
 412.327 +  /*                                                                       */
 412.328 +  /* <Type>                                                                */
 412.329 +  /*    FT_PtrDist                                                         */
 412.330 +  /*                                                                       */
 412.331 +  /* <Description>                                                         */
 412.332 +  /*    This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the       */
 412.333 +  /*    largest _signed_ integer type used to express the distance         */
 412.334 +  /*    between two pointers.                                              */
 412.335 +  /*                                                                       */
 412.336 +  typedef ft_ptrdiff_t  FT_PtrDist;
 412.337 +
 412.338 +
 412.339 +  /*************************************************************************/
 412.340 +  /*                                                                       */
 412.341 +  /* <Struct>                                                              */
 412.342 +  /*    FT_UnitVector                                                      */
 412.343 +  /*                                                                       */
 412.344 +  /* <Description>                                                         */
 412.345 +  /*    A simple structure used to store a 2D vector unit vector.  Uses    */
 412.346 +  /*    FT_F2Dot14 types.                                                  */
 412.347 +  /*                                                                       */
 412.348 +  /* <Fields>                                                              */
 412.349 +  /*    x :: Horizontal coordinate.                                        */
 412.350 +  /*                                                                       */
 412.351 +  /*    y :: Vertical coordinate.                                          */
 412.352 +  /*                                                                       */
 412.353 +  typedef struct  FT_UnitVector_
 412.354 +  {
 412.355 +    FT_F2Dot14  x;
 412.356 +    FT_F2Dot14  y;
 412.357 +
 412.358 +  } FT_UnitVector;
 412.359 +
 412.360 +
 412.361 +  /*************************************************************************/
 412.362 +  /*                                                                       */
 412.363 +  /* <Struct>                                                              */
 412.364 +  /*    FT_Matrix                                                          */
 412.365 +  /*                                                                       */
 412.366 +  /* <Description>                                                         */
 412.367 +  /*    A simple structure used to store a 2x2 matrix.  Coefficients are   */
 412.368 +  /*    in 16.16 fixed float format.  The computation performed is:        */
 412.369 +  /*                                                                       */
 412.370 +  /*       {                                                               */
 412.371 +  /*          x' = x*xx + y*xy                                             */
 412.372 +  /*          y' = x*yx + y*yy                                             */
 412.373 +  /*       }                                                               */
 412.374 +  /*                                                                       */
 412.375 +  /* <Fields>                                                              */
 412.376 +  /*    xx :: Matrix coefficient.                                          */
 412.377 +  /*                                                                       */
 412.378 +  /*    xy :: Matrix coefficient.                                          */
 412.379 +  /*                                                                       */
 412.380 +  /*    yx :: Matrix coefficient.                                          */
 412.381 +  /*                                                                       */
 412.382 +  /*    yy :: Matrix coefficient.                                          */
 412.383 +  /*                                                                       */
 412.384 +  typedef struct  FT_Matrix_
 412.385 +  {
 412.386 +    FT_Fixed  xx, xy;
 412.387 +    FT_Fixed  yx, yy;
 412.388 +
 412.389 +  } FT_Matrix;
 412.390 +
 412.391 +
 412.392 +  /*************************************************************************/
 412.393 +  /*                                                                       */
 412.394 +  /* <Struct>                                                              */
 412.395 +  /*    FT_Data                                                            */
 412.396 +  /*                                                                       */
 412.397 +  /* <Description>                                                         */
 412.398 +  /*    Read-only binary data represented as a pointer and a length.       */
 412.399 +  /*                                                                       */
 412.400 +  /* <Fields>                                                              */
 412.401 +  /*    pointer :: The data.                                               */
 412.402 +  /*                                                                       */
 412.403 +  /*    length  :: The length of the data in bytes.                        */
 412.404 +  /*                                                                       */
 412.405 +  typedef struct  FT_Data_
 412.406 +  {
 412.407 +    const FT_Byte*  pointer;
 412.408 +    FT_Int          length;
 412.409 +
 412.410 +  } FT_Data;
 412.411 +
 412.412 +
 412.413 +  /*************************************************************************/
 412.414 +  /*                                                                       */
 412.415 +  /* <FuncType>                                                            */
 412.416 +  /*    FT_Generic_Finalizer                                               */
 412.417 +  /*                                                                       */
 412.418 +  /* <Description>                                                         */
 412.419 +  /*    Describe a function used to destroy the `client' data of any       */
 412.420 +  /*    FreeType object.  See the description of the @FT_Generic type for  */
 412.421 +  /*    details of usage.                                                  */
 412.422 +  /*                                                                       */
 412.423 +  /* <Input>                                                               */
 412.424 +  /*    The address of the FreeType object which is under finalization.    */
 412.425 +  /*    Its client data is accessed through its `generic' field.           */
 412.426 +  /*                                                                       */
 412.427 +  typedef void  (*FT_Generic_Finalizer)(void*  object);
 412.428 +
 412.429 +
 412.430 +  /*************************************************************************/
 412.431 +  /*                                                                       */
 412.432 +  /* <Struct>                                                              */
 412.433 +  /*    FT_Generic                                                         */
 412.434 +  /*                                                                       */
 412.435 +  /* <Description>                                                         */
 412.436 +  /*    Client applications often need to associate their own data to a    */
 412.437 +  /*    variety of FreeType core objects.  For example, a text layout API  */
 412.438 +  /*    might want to associate a glyph cache to a given size object.      */
 412.439 +  /*                                                                       */
 412.440 +  /*    Most FreeType object contains a `generic' field, of type           */
 412.441 +  /*    FT_Generic, which usage is left to client applications and font    */
 412.442 +  /*    servers.                                                           */
 412.443 +  /*                                                                       */
 412.444 +  /*    It can be used to store a pointer to client-specific data, as well */
 412.445 +  /*    as the address of a `finalizer' function, which will be called by  */
 412.446 +  /*    FreeType when the object is destroyed (for example, the previous   */
 412.447 +  /*    client example would put the address of the glyph cache destructor */
 412.448 +  /*    in the `finalizer' field).                                         */
 412.449 +  /*                                                                       */
 412.450 +  /* <Fields>                                                              */
 412.451 +  /*    data      :: A typeless pointer to any client-specified data. This */
 412.452 +  /*                 field is completely ignored by the FreeType library.  */
 412.453 +  /*                                                                       */
 412.454 +  /*    finalizer :: A pointer to a `generic finalizer' function, which    */
 412.455 +  /*                 will be called when the object is destroyed.  If this */
 412.456 +  /*                 field is set to NULL, no code will be called.         */
 412.457 +  /*                                                                       */
 412.458 +  typedef struct  FT_Generic_
 412.459 +  {
 412.460 +    void*                 data;
 412.461 +    FT_Generic_Finalizer  finalizer;
 412.462 +
 412.463 +  } FT_Generic;
 412.464 +
 412.465 +
 412.466 +  /*************************************************************************/
 412.467 +  /*                                                                       */
 412.468 +  /* <Macro>                                                               */
 412.469 +  /*    FT_MAKE_TAG                                                        */
 412.470 +  /*                                                                       */
 412.471 +  /* <Description>                                                         */
 412.472 +  /*    This macro converts four-letter tags which are used to label       */
 412.473 +  /*    TrueType tables into an unsigned long to be used within FreeType.  */
 412.474 +  /*                                                                       */
 412.475 +  /* <Note>                                                                */
 412.476 +  /*    The produced values *must* be 32-bit integers.  Don't redefine     */
 412.477 +  /*    this macro.                                                        */
 412.478 +  /*                                                                       */
 412.479 +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
 412.480 +          (FT_Tag)                        \
 412.481 +          ( ( (FT_ULong)_x1 << 24 ) |     \
 412.482 +            ( (FT_ULong)_x2 << 16 ) |     \
 412.483 +            ( (FT_ULong)_x3 <<  8 ) |     \
 412.484 +              (FT_ULong)_x4         )
 412.485 +
 412.486 +
 412.487 +  /*************************************************************************/
 412.488 +  /*************************************************************************/
 412.489 +  /*                                                                       */
 412.490 +  /*                    L I S T   M A N A G E M E N T                      */
 412.491 +  /*                                                                       */
 412.492 +  /*************************************************************************/
 412.493 +  /*************************************************************************/
 412.494 +
 412.495 +
 412.496 +  /*************************************************************************/
 412.497 +  /*                                                                       */
 412.498 +  /* <Section>                                                             */
 412.499 +  /*    list_processing                                                    */
 412.500 +  /*                                                                       */
 412.501 +  /*************************************************************************/
 412.502 +
 412.503 +
 412.504 +  /*************************************************************************/
 412.505 +  /*                                                                       */
 412.506 +  /* <Type>                                                                */
 412.507 +  /*    FT_ListNode                                                        */
 412.508 +  /*                                                                       */
 412.509 +  /* <Description>                                                         */
 412.510 +  /*     Many elements and objects in FreeType are listed through an       */
 412.511 +  /*     @FT_List record (see @FT_ListRec).  As its name suggests, an      */
 412.512 +  /*     FT_ListNode is a handle to a single list element.                 */
 412.513 +  /*                                                                       */
 412.514 +  typedef struct FT_ListNodeRec_*  FT_ListNode;
 412.515 +
 412.516 +
 412.517 +  /*************************************************************************/
 412.518 +  /*                                                                       */
 412.519 +  /* <Type>                                                                */
 412.520 +  /*    FT_List                                                            */
 412.521 +  /*                                                                       */
 412.522 +  /* <Description>                                                         */
 412.523 +  /*    A handle to a list record (see @FT_ListRec).                       */
 412.524 +  /*                                                                       */
 412.525 +  typedef struct FT_ListRec_*  FT_List;
 412.526 +
 412.527 +
 412.528 +  /*************************************************************************/
 412.529 +  /*                                                                       */
 412.530 +  /* <Struct>                                                              */
 412.531 +  /*    FT_ListNodeRec                                                     */
 412.532 +  /*                                                                       */
 412.533 +  /* <Description>                                                         */
 412.534 +  /*    A structure used to hold a single list element.                    */
 412.535 +  /*                                                                       */
 412.536 +  /* <Fields>                                                              */
 412.537 +  /*    prev :: The previous element in the list.  NULL if first.          */
 412.538 +  /*                                                                       */
 412.539 +  /*    next :: The next element in the list.  NULL if last.               */
 412.540 +  /*                                                                       */
 412.541 +  /*    data :: A typeless pointer to the listed object.                   */
 412.542 +  /*                                                                       */
 412.543 +  typedef struct  FT_ListNodeRec_
 412.544 +  {
 412.545 +    FT_ListNode  prev;
 412.546 +    FT_ListNode  next;
 412.547 +    void*        data;
 412.548 +
 412.549 +  } FT_ListNodeRec;
 412.550 +
 412.551 +
 412.552 +  /*************************************************************************/
 412.553 +  /*                                                                       */
 412.554 +  /* <Struct>                                                              */
 412.555 +  /*    FT_ListRec                                                         */
 412.556 +  /*                                                                       */
 412.557 +  /* <Description>                                                         */
 412.558 +  /*    A structure used to hold a simple doubly-linked list.  These are   */
 412.559 +  /*    used in many parts of FreeType.                                    */
 412.560 +  /*                                                                       */
 412.561 +  /* <Fields>                                                              */
 412.562 +  /*    head :: The head (first element) of doubly-linked list.            */
 412.563 +  /*                                                                       */
 412.564 +  /*    tail :: The tail (last element) of doubly-linked list.             */
 412.565 +  /*                                                                       */
 412.566 +  typedef struct  FT_ListRec_
 412.567 +  {
 412.568 +    FT_ListNode  head;
 412.569 +    FT_ListNode  tail;
 412.570 +
 412.571 +  } FT_ListRec;
 412.572 +
 412.573 +
 412.574 +  /* */
 412.575 +
 412.576 +#define FT_IS_EMPTY( list )  ( (list).head == 0 )
 412.577 +
 412.578 +  /* return base error code (without module-specific prefix) */
 412.579 +#define FT_ERROR_BASE( x )    ( (x) & 0xFF )
 412.580 +
 412.581 +  /* return module error code */
 412.582 +#define FT_ERROR_MODULE( x )  ( (x) & 0xFF00U )
 412.583 +
 412.584 +#define FT_BOOL( x )  ( (FT_Bool)( x ) )
 412.585 +
 412.586 +FT_END_HEADER
 412.587 +
 412.588 +#endif /* __FTTYPES_H__ */
 412.589 +
 412.590 +
 412.591 +/* END */
   413.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   413.2 +++ b/libs/ft2static/freetype/ftwinfnt.h	Sat Feb 01 19:58:19 2014 +0200
   413.3 @@ -0,0 +1,274 @@
   413.4 +/***************************************************************************/
   413.5 +/*                                                                         */
   413.6 +/*  ftwinfnt.h                                                             */
   413.7 +/*                                                                         */
   413.8 +/*    FreeType API for accessing Windows fnt-specific data.                */
   413.9 +/*                                                                         */
  413.10 +/*  Copyright 2003, 2004, 2008 by                                          */
  413.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  413.12 +/*                                                                         */
  413.13 +/*  This file is part of the FreeType project, and may only be used,       */
  413.14 +/*  modified, and distributed under the terms of the FreeType project      */
  413.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  413.16 +/*  this file you indicate that you have read the license and              */
  413.17 +/*  understand and accept it fully.                                        */
  413.18 +/*                                                                         */
  413.19 +/***************************************************************************/
  413.20 +
  413.21 +
  413.22 +#ifndef __FTWINFNT_H__
  413.23 +#define __FTWINFNT_H__
  413.24 +
  413.25 +#include <ft2build.h>
  413.26 +#include FT_FREETYPE_H
  413.27 +
  413.28 +#ifdef FREETYPE_H
  413.29 +#error "freetype.h of FreeType 1 has been loaded!"
  413.30 +#error "Please fix the directory search order for header files"
  413.31 +#error "so that freetype.h of FreeType 2 is found first."
  413.32 +#endif
  413.33 +
  413.34 +
  413.35 +FT_BEGIN_HEADER
  413.36 +
  413.37 +
  413.38 +  /*************************************************************************/
  413.39 +  /*                                                                       */
  413.40 +  /* <Section>                                                             */
  413.41 +  /*    winfnt_fonts                                                       */
  413.42 +  /*                                                                       */
  413.43 +  /* <Title>                                                               */
  413.44 +  /*    Window FNT Files                                                   */
  413.45 +  /*                                                                       */
  413.46 +  /* <Abstract>                                                            */
  413.47 +  /*    Windows FNT specific API.                                          */
  413.48 +  /*                                                                       */
  413.49 +  /* <Description>                                                         */
  413.50 +  /*    This section contains the declaration of Windows FNT specific      */
  413.51 +  /*    functions.                                                         */
  413.52 +  /*                                                                       */
  413.53 +  /*************************************************************************/
  413.54 +
  413.55 +
  413.56 +  /*************************************************************************
  413.57 +   *
  413.58 +   * @enum:
  413.59 +   *   FT_WinFNT_ID_XXX
  413.60 +   *
  413.61 +   * @description:
  413.62 +   *   A list of valid values for the `charset' byte in
  413.63 +   *   @FT_WinFNT_HeaderRec.  Exact mapping tables for the various cpXXXX
  413.64 +   *   encodings (except for cp1361) can be found at ftp://ftp.unicode.org
  413.65 +   *   in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory.  cp1361 is
  413.66 +   *   roughly a superset of MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT.
  413.67 +   *
  413.68 +   * @values:
  413.69 +   *   FT_WinFNT_ID_DEFAULT ::
  413.70 +   *     This is used for font enumeration and font creation as a
  413.71 +   *     `don't care' value.  Valid font files don't contain this value.
  413.72 +   *     When querying for information about the character set of the font
  413.73 +   *     that is currently selected into a specified device context, this
  413.74 +   *     return value (of the related Windows API) simply denotes failure.
  413.75 +   *
  413.76 +   *   FT_WinFNT_ID_SYMBOL ::
  413.77 +   *     There is no known mapping table available.
  413.78 +   *
  413.79 +   *   FT_WinFNT_ID_MAC ::
  413.80 +   *     Mac Roman encoding.
  413.81 +   *
  413.82 +   *   FT_WinFNT_ID_OEM ::
  413.83 +   *     From Michael Pöttgen <michael@poettgen.de>:
  413.84 +   *
  413.85 +   *       The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM
  413.86 +   *       is used for the charset of vector fonts, like `modern.fon',
  413.87 +   *       `roman.fon', and `script.fon' on Windows.
  413.88 +   *
  413.89 +   *       The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value
  413.90 +   *       specifies a character set that is operating-system dependent.
  413.91 +   *
  413.92 +   *       The `IFIMETRICS' documentation from the `Windows Driver
  413.93 +   *       Development Kit' says: This font supports an OEM-specific
  413.94 +   *       character set.  The OEM character set is system dependent.
  413.95 +   *
  413.96 +   *       In general OEM, as opposed to ANSI (i.e., cp1252), denotes the
  413.97 +   *       second default codepage that most international versions of
  413.98 +   *       Windows have.  It is one of the OEM codepages from
  413.99 +   *
 413.100 +   *         http://www.microsoft.com/globaldev/reference/cphome.mspx,
 413.101 +   *
 413.102 +   *       and is used for the `DOS boxes', to support legacy applications.
 413.103 +   *       A German Windows version for example usually uses ANSI codepage
 413.104 +   *       1252 and OEM codepage 850.
 413.105 +   *
 413.106 +   *   FT_WinFNT_ID_CP874 ::
 413.107 +   *     A superset of Thai TIS 620 and ISO 8859-11.
 413.108 +   *
 413.109 +   *   FT_WinFNT_ID_CP932 ::
 413.110 +   *     A superset of Japanese Shift-JIS (with minor deviations).
 413.111 +   *
 413.112 +   *   FT_WinFNT_ID_CP936 ::
 413.113 +   *     A superset of simplified Chinese GB 2312-1980 (with different
 413.114 +   *     ordering and minor deviations).
 413.115 +   *
 413.116 +   *   FT_WinFNT_ID_CP949 ::
 413.117 +   *     A superset of Korean Hangul KS~C 5601-1987 (with different
 413.118 +   *     ordering and minor deviations).
 413.119 +   *
 413.120 +   *   FT_WinFNT_ID_CP950 ::
 413.121 +   *     A superset of traditional Chinese Big~5 ETen (with different
 413.122 +   *     ordering and minor deviations).
 413.123 +   *
 413.124 +   *   FT_WinFNT_ID_CP1250 ::
 413.125 +   *     A superset of East European ISO 8859-2 (with slightly different
 413.126 +   *     ordering).
 413.127 +   *
 413.128 +   *   FT_WinFNT_ID_CP1251 ::
 413.129 +   *     A superset of Russian ISO 8859-5 (with different ordering).
 413.130 +   *
 413.131 +   *   FT_WinFNT_ID_CP1252 ::
 413.132 +   *     ANSI encoding.  A superset of ISO 8859-1.
 413.133 +   *
 413.134 +   *   FT_WinFNT_ID_CP1253 ::
 413.135 +   *     A superset of Greek ISO 8859-7 (with minor modifications).
 413.136 +   *
 413.137 +   *   FT_WinFNT_ID_CP1254 ::
 413.138 +   *     A superset of Turkish ISO 8859-9.
 413.139 +   *
 413.140 +   *   FT_WinFNT_ID_CP1255 ::
 413.141 +   *     A superset of Hebrew ISO 8859-8 (with some modifications).
 413.142 +   *
 413.143 +   *   FT_WinFNT_ID_CP1256 ::
 413.144 +   *     A superset of Arabic ISO 8859-6 (with different ordering).
 413.145 +   *
 413.146 +   *   FT_WinFNT_ID_CP1257 ::
 413.147 +   *     A superset of Baltic ISO 8859-13 (with some deviations).
 413.148 +   *
 413.149 +   *   FT_WinFNT_ID_CP1258 ::
 413.150 +   *     For Vietnamese.  This encoding doesn't cover all necessary
 413.151 +   *     characters.
 413.152 +   *
 413.153 +   *   FT_WinFNT_ID_CP1361 ::
 413.154 +   *     Korean (Johab).
 413.155 +   */
 413.156 +
 413.157 +#define FT_WinFNT_ID_CP1252    0
 413.158 +#define FT_WinFNT_ID_DEFAULT   1
 413.159 +#define FT_WinFNT_ID_SYMBOL    2
 413.160 +#define FT_WinFNT_ID_MAC      77
 413.161 +#define FT_WinFNT_ID_CP932   128
 413.162 +#define FT_WinFNT_ID_CP949   129
 413.163 +#define FT_WinFNT_ID_CP1361  130
 413.164 +#define FT_WinFNT_ID_CP936   134
 413.165 +#define FT_WinFNT_ID_CP950   136
 413.166 +#define FT_WinFNT_ID_CP1253  161
 413.167 +#define FT_WinFNT_ID_CP1254  162
 413.168 +#define FT_WinFNT_ID_CP1258  163
 413.169 +#define FT_WinFNT_ID_CP1255  177
 413.170 +#define FT_WinFNT_ID_CP1256  178
 413.171 +#define FT_WinFNT_ID_CP1257  186
 413.172 +#define FT_WinFNT_ID_CP1251  204
 413.173 +#define FT_WinFNT_ID_CP874   222
 413.174 +#define FT_WinFNT_ID_CP1250  238
 413.175 +#define FT_WinFNT_ID_OEM     255
 413.176 +
 413.177 +
 413.178 +  /*************************************************************************/
 413.179 +  /*                                                                       */
 413.180 +  /* <Struct>                                                              */
 413.181 +  /*    FT_WinFNT_HeaderRec                                                */
 413.182 +  /*                                                                       */
 413.183 +  /* <Description>                                                         */
 413.184 +  /*    Windows FNT Header info.                                           */
 413.185 +  /*                                                                       */
 413.186 +  typedef struct  FT_WinFNT_HeaderRec_
 413.187 +  {
 413.188 +    FT_UShort  version;
 413.189 +    FT_ULong   file_size;
 413.190 +    FT_Byte    copyright[60];
 413.191 +    FT_UShort  file_type;
 413.192 +    FT_UShort  nominal_point_size;
 413.193 +    FT_UShort  vertical_resolution;
 413.194 +    FT_UShort  horizontal_resolution;
 413.195 +    FT_UShort  ascent;
 413.196 +    FT_UShort  internal_leading;
 413.197 +    FT_UShort  external_leading;
 413.198 +    FT_Byte    italic;
 413.199 +    FT_Byte    underline;
 413.200 +    FT_Byte    strike_out;
 413.201 +    FT_UShort  weight;
 413.202 +    FT_Byte    charset;
 413.203 +    FT_UShort  pixel_width;
 413.204 +    FT_UShort  pixel_height;
 413.205 +    FT_Byte    pitch_and_family;
 413.206 +    FT_UShort  avg_width;
 413.207 +    FT_UShort  max_width;
 413.208 +    FT_Byte    first_char;
 413.209 +    FT_Byte    last_char;
 413.210 +    FT_Byte    default_char;
 413.211 +    FT_Byte    break_char;
 413.212 +    FT_UShort  bytes_per_row;
 413.213 +    FT_ULong   device_offset;
 413.214 +    FT_ULong   face_name_offset;
 413.215 +    FT_ULong   bits_pointer;
 413.216 +    FT_ULong   bits_offset;
 413.217 +    FT_Byte    reserved;
 413.218 +    FT_ULong   flags;
 413.219 +    FT_UShort  A_space;
 413.220 +    FT_UShort  B_space;
 413.221 +    FT_UShort  C_space;
 413.222 +    FT_UShort  color_table_offset;
 413.223 +    FT_ULong   reserved1[4];
 413.224 +
 413.225 +  } FT_WinFNT_HeaderRec;
 413.226 +
 413.227 +
 413.228 +  /*************************************************************************/
 413.229 +  /*                                                                       */
 413.230 +  /* <Struct>                                                              */
 413.231 +  /*    FT_WinFNT_Header                                                   */
 413.232 +  /*                                                                       */
 413.233 +  /* <Description>                                                         */
 413.234 +  /*    A handle to an @FT_WinFNT_HeaderRec structure.                     */
 413.235 +  /*                                                                       */
 413.236 +  typedef struct FT_WinFNT_HeaderRec_*  FT_WinFNT_Header;
 413.237 +
 413.238 +
 413.239 +  /**********************************************************************
 413.240 +   *
 413.241 +   * @function:
 413.242 +   *    FT_Get_WinFNT_Header
 413.243 +   *
 413.244 +   * @description:
 413.245 +   *    Retrieve a Windows FNT font info header.
 413.246 +   *
 413.247 +   * @input:
 413.248 +   *    face    :: A handle to the input face.
 413.249 +   *
 413.250 +   * @output:
 413.251 +   *    aheader :: The WinFNT header.
 413.252 +   *
 413.253 +   * @return:
 413.254 +   *   FreeType error code.  0~means success.
 413.255 +   *
 413.256 +   * @note:
 413.257 +   *   This function only works with Windows FNT faces, returning an error
 413.258 +   *   otherwise.
 413.259 +   */
 413.260 +  FT_EXPORT( FT_Error )
 413.261 +  FT_Get_WinFNT_Header( FT_Face               face,
 413.262 +                        FT_WinFNT_HeaderRec  *aheader );
 413.263 +
 413.264 +
 413.265 +  /* */
 413.266 +
 413.267 +FT_END_HEADER
 413.268 +
 413.269 +#endif /* __FTWINFNT_H__ */
 413.270 +
 413.271 +
 413.272 +/* END */
 413.273 +
 413.274 +
 413.275 +/* Local Variables: */
 413.276 +/* coding: utf-8    */
 413.277 +/* End:             */
   414.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   414.2 +++ b/libs/ft2static/freetype/ftxf86.h	Sat Feb 01 19:58:19 2014 +0200
   414.3 @@ -0,0 +1,83 @@
   414.4 +/***************************************************************************/
   414.5 +/*                                                                         */
   414.6 +/*  ftxf86.h                                                               */
   414.7 +/*                                                                         */
   414.8 +/*    Support functions for X11.                                           */
   414.9 +/*                                                                         */
  414.10 +/*  Copyright 2002, 2003, 2004, 2006, 2007 by                              */
  414.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  414.12 +/*                                                                         */
  414.13 +/*  This file is part of the FreeType project, and may only be used,       */
  414.14 +/*  modified, and distributed under the terms of the FreeType project      */
  414.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  414.16 +/*  this file you indicate that you have read the license and              */
  414.17 +/*  understand and accept it fully.                                        */
  414.18 +/*                                                                         */
  414.19 +/***************************************************************************/
  414.20 +
  414.21 +
  414.22 +#ifndef __FTXF86_H__
  414.23 +#define __FTXF86_H__
  414.24 +
  414.25 +#include <ft2build.h>
  414.26 +#include FT_FREETYPE_H
  414.27 +
  414.28 +#ifdef FREETYPE_H
  414.29 +#error "freetype.h of FreeType 1 has been loaded!"
  414.30 +#error "Please fix the directory search order for header files"
  414.31 +#error "so that freetype.h of FreeType 2 is found first."
  414.32 +#endif
  414.33 +
  414.34 +
  414.35 +FT_BEGIN_HEADER
  414.36 +
  414.37 +
  414.38 +  /*************************************************************************/
  414.39 +  /*                                                                       */
  414.40 +  /* <Section>                                                             */
  414.41 +  /*   font_formats                                                        */
  414.42 +  /*                                                                       */
  414.43 +  /* <Title>                                                               */
  414.44 +  /*   Font Formats                                                        */
  414.45 +  /*                                                                       */
  414.46 +  /* <Abstract>                                                            */
  414.47 +  /*   Getting the font format.                                            */
  414.48 +  /*                                                                       */
  414.49 +  /* <Description>                                                         */
  414.50 +  /*   The single function in this section can be used to get the font     */
  414.51 +  /*   format.  Note that this information is not needed normally;         */
  414.52 +  /*   however, there are special cases (like in PDF devices) where it is  */
  414.53 +  /*   important to differentiate, in spite of FreeType's uniform API.     */
  414.54 +  /*                                                                       */
  414.55 +  /*   This function is in the X11/xf86 namespace for historical reasons   */
  414.56 +  /*   and in no way depends on that windowing system.                     */
  414.57 +  /*                                                                       */
  414.58 +  /*************************************************************************/
  414.59 +
  414.60 +
  414.61 +  /*************************************************************************/
  414.62 +  /*                                                                       */
  414.63 +  /* <Function>                                                            */
  414.64 +  /*   FT_Get_X11_Font_Format                                              */
  414.65 +  /*                                                                       */
  414.66 +  /* <Description>                                                         */
  414.67 +  /*   Return a string describing the format of a given face, using values */
  414.68 +  /*   which can be used as an X11 FONT_PROPERTY.  Possible values are     */
  414.69 +  /*   `TrueType', `Type~1', `BDF', `PCF', `Type~42', `CID~Type~1', `CFF', */
  414.70 +  /*   `PFR', and `Windows~FNT'.                                           */
  414.71 +  /*                                                                       */
  414.72 +  /* <Input>                                                               */
  414.73 +  /*   face ::                                                             */
  414.74 +  /*     Input face handle.                                                */
  414.75 +  /*                                                                       */
  414.76 +  /* <Return>                                                              */
  414.77 +  /*   Font format string.  NULL in case of error.                         */
  414.78 +  /*                                                                       */
  414.79 +  FT_EXPORT( const char* )
  414.80 +  FT_Get_X11_Font_Format( FT_Face  face );
  414.81 +
  414.82 + /* */
  414.83 +
  414.84 +FT_END_HEADER
  414.85 +
  414.86 +#endif /* __FTXF86_H__ */
   415.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   415.2 +++ b/libs/ft2static/freetype/internal/autohint.h	Sat Feb 01 19:58:19 2014 +0200
   415.3 @@ -0,0 +1,231 @@
   415.4 +/***************************************************************************/
   415.5 +/*                                                                         */
   415.6 +/*  autohint.h                                                             */
   415.7 +/*                                                                         */
   415.8 +/*    High-level `autohint' module-specific interface (specification).     */
   415.9 +/*                                                                         */
  415.10 +/*  Copyright 1996-2001, 2002, 2007 by                                     */
  415.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  415.12 +/*                                                                         */
  415.13 +/*  This file is part of the FreeType project, and may only be used,       */
  415.14 +/*  modified, and distributed under the terms of the FreeType project      */
  415.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  415.16 +/*  this file you indicate that you have read the license and              */
  415.17 +/*  understand and accept it fully.                                        */
  415.18 +/*                                                                         */
  415.19 +/***************************************************************************/
  415.20 +
  415.21 +
  415.22 +  /*************************************************************************/
  415.23 +  /*                                                                       */
  415.24 +  /* The auto-hinter is used to load and automatically hint glyphs if a    */
  415.25 +  /* format-specific hinter isn't available.                               */
  415.26 +  /*                                                                       */
  415.27 +  /*************************************************************************/
  415.28 +
  415.29 +
  415.30 +#ifndef __AUTOHINT_H__
  415.31 +#define __AUTOHINT_H__
  415.32 +
  415.33 +
  415.34 +  /*************************************************************************/
  415.35 +  /*                                                                       */
  415.36 +  /* A small technical note regarding automatic hinting in order to        */
  415.37 +  /* clarify this module interface.                                        */
  415.38 +  /*                                                                       */
  415.39 +  /* An automatic hinter might compute two kinds of data for a given face: */
  415.40 +  /*                                                                       */
  415.41 +  /* - global hints: Usually some metrics that describe global properties  */
  415.42 +  /*                 of the face.  It is computed by scanning more or less */
  415.43 +  /*                 aggressively the glyphs in the face, and thus can be  */
  415.44 +  /*                 very slow to compute (even if the size of global      */
  415.45 +  /*                 hints is really small).                               */
  415.46 +  /*                                                                       */
  415.47 +  /* - glyph hints:  These describe some important features of the glyph   */
  415.48 +  /*                 outline, as well as how to align them.  They are      */
  415.49 +  /*                 generally much faster to compute than global hints.   */
  415.50 +  /*                                                                       */
  415.51 +  /* The current FreeType auto-hinter does a pretty good job while         */
  415.52 +  /* performing fast computations for both global and glyph hints.         */
  415.53 +  /* However, we might be interested in introducing more complex and       */
  415.54 +  /* powerful algorithms in the future, like the one described in the John */
  415.55 +  /* D. Hobby paper, which unfortunately requires a lot more horsepower.   */
  415.56 +  /*                                                                       */
  415.57 +  /* Because a sufficiently sophisticated font management system would     */
  415.58 +  /* typically implement an LRU cache of opened face objects to reduce     */
  415.59 +  /* memory usage, it is a good idea to be able to avoid recomputing       */
  415.60 +  /* global hints every time the same face is re-opened.                   */
  415.61 +  /*                                                                       */
  415.62 +  /* We thus provide the ability to cache global hints outside of the face */
  415.63 +  /* object, in order to speed up font re-opening time.  Of course, this   */
  415.64 +  /* feature is purely optional, so most client programs won't even notice */
  415.65 +  /* it.                                                                   */
  415.66 +  /*                                                                       */
  415.67 +  /* I initially thought that it would be a good idea to cache the glyph   */
  415.68 +  /* hints too.  However, my general idea now is that if you really need   */
  415.69 +  /* to cache these too, you are simply in need of a new font format,      */
  415.70 +  /* where all this information could be stored within the font file and   */
  415.71 +  /* decoded on the fly.                                                   */
  415.72 +  /*                                                                       */
  415.73 +  /*************************************************************************/
  415.74 +
  415.75 +
  415.76 +#include <ft2build.h>
  415.77 +#include FT_FREETYPE_H
  415.78 +
  415.79 +
  415.80 +FT_BEGIN_HEADER
  415.81 +
  415.82 +
  415.83 +  typedef struct FT_AutoHinterRec_  *FT_AutoHinter;
  415.84 +
  415.85 +
  415.86 +  /*************************************************************************/
  415.87 +  /*                                                                       */
  415.88 +  /* <FuncType>                                                            */
  415.89 +  /*    FT_AutoHinter_GlobalGetFunc                                        */
  415.90 +  /*                                                                       */
  415.91 +  /* <Description>                                                         */
  415.92 +  /*    Retrieves the global hints computed for a given face object the    */
  415.93 +  /*    resulting data is dissociated from the face and will survive a     */
  415.94 +  /*    call to FT_Done_Face().  It must be discarded through the API      */
  415.95 +  /*    FT_AutoHinter_GlobalDoneFunc().                                    */
  415.96 +  /*                                                                       */
  415.97 +  /* <Input>                                                               */
  415.98 +  /*    hinter        :: A handle to the source auto-hinter.               */
  415.99 +  /*                                                                       */
 415.100 +  /*    face          :: A handle to the source face object.               */
 415.101 +  /*                                                                       */
 415.102 +  /* <Output>                                                              */
 415.103 +  /*    global_hints  :: A typeless pointer to the global hints.           */
 415.104 +  /*                                                                       */
 415.105 +  /*    global_len    :: The size in bytes of the global hints.            */
 415.106 +  /*                                                                       */
 415.107 +  typedef void
 415.108 +  (*FT_AutoHinter_GlobalGetFunc)( FT_AutoHinter  hinter,
 415.109 +                                  FT_Face        face,
 415.110 +                                  void**         global_hints,
 415.111 +                                  long*          global_len );
 415.112 +
 415.113 +
 415.114 +  /*************************************************************************/
 415.115 +  /*                                                                       */
 415.116 +  /* <FuncType>                                                            */
 415.117 +  /*    FT_AutoHinter_GlobalDoneFunc                                       */
 415.118 +  /*                                                                       */
 415.119 +  /* <Description>                                                         */
 415.120 +  /*    Discards the global hints retrieved through                        */
 415.121 +  /*    FT_AutoHinter_GlobalGetFunc().  This is the only way these hints   */
 415.122 +  /*    are freed from memory.                                             */
 415.123 +  /*                                                                       */
 415.124 +  /* <Input>                                                               */
 415.125 +  /*    hinter :: A handle to the auto-hinter module.                      */
 415.126 +  /*                                                                       */
 415.127 +  /*    global :: A pointer to retrieved global hints to discard.          */
 415.128 +  /*                                                                       */
 415.129 +  typedef void
 415.130 +  (*FT_AutoHinter_GlobalDoneFunc)( FT_AutoHinter  hinter,
 415.131 +                                   void*          global );
 415.132 +
 415.133 +
 415.134 +  /*************************************************************************/
 415.135 +  /*                                                                       */
 415.136 +  /* <FuncType>                                                            */
 415.137 +  /*    FT_AutoHinter_GlobalResetFunc                                      */
 415.138 +  /*                                                                       */
 415.139 +  /* <Description>                                                         */
 415.140 +  /*    This function is used to recompute the global metrics in a given   */
 415.141 +  /*    font.  This is useful when global font data changes (e.g. Multiple */
 415.142 +  /*    Masters fonts where blend coordinates change).                     */
 415.143 +  /*                                                                       */
 415.144 +  /* <Input>                                                               */
 415.145 +  /*    hinter :: A handle to the source auto-hinter.                      */
 415.146 +  /*                                                                       */
 415.147 +  /*    face   :: A handle to the face.                                    */
 415.148 +  /*                                                                       */
 415.149 +  typedef void
 415.150 +  (*FT_AutoHinter_GlobalResetFunc)( FT_AutoHinter  hinter,
 415.151 +                                    FT_Face        face );
 415.152 +
 415.153 +
 415.154 +  /*************************************************************************/
 415.155 +  /*                                                                       */
 415.156 +  /* <FuncType>                                                            */
 415.157 +  /*    FT_AutoHinter_GlyphLoadFunc                                        */
 415.158 +  /*                                                                       */
 415.159 +  /* <Description>                                                         */
 415.160 +  /*    This function is used to load, scale, and automatically hint a     */
 415.161 +  /*    glyph from a given face.                                           */
 415.162 +  /*                                                                       */
 415.163 +  /* <Input>                                                               */
 415.164 +  /*    face        :: A handle to the face.                               */
 415.165 +  /*                                                                       */
 415.166 +  /*    glyph_index :: The glyph index.                                    */
 415.167 +  /*                                                                       */
 415.168 +  /*    load_flags  :: The load flags.                                     */
 415.169 +  /*                                                                       */
 415.170 +  /* <Note>                                                                */
 415.171 +  /*    This function is capable of loading composite glyphs by hinting    */
 415.172 +  /*    each sub-glyph independently (which improves quality).             */
 415.173 +  /*                                                                       */
 415.174 +  /*    It will call the font driver with FT_Load_Glyph(), with            */
 415.175 +  /*    FT_LOAD_NO_SCALE set.                                              */
 415.176 +  /*                                                                       */
 415.177 +  typedef FT_Error
 415.178 +  (*FT_AutoHinter_GlyphLoadFunc)( FT_AutoHinter  hinter,
 415.179 +                                  FT_GlyphSlot   slot,
 415.180 +                                  FT_Size        size,
 415.181 +                                  FT_UInt        glyph_index,
 415.182 +                                  FT_Int32       load_flags );
 415.183 +
 415.184 +
 415.185 +  /*************************************************************************/
 415.186 +  /*                                                                       */
 415.187 +  /* <Struct>                                                              */
 415.188 +  /*    FT_AutoHinter_ServiceRec                                           */
 415.189 +  /*                                                                       */
 415.190 +  /* <Description>                                                         */
 415.191 +  /*    The auto-hinter module's interface.                                */
 415.192 +  /*                                                                       */
 415.193 +  typedef struct  FT_AutoHinter_ServiceRec_
 415.194 +  {
 415.195 +    FT_AutoHinter_GlobalResetFunc  reset_face;
 415.196 +    FT_AutoHinter_GlobalGetFunc    get_global_hints;
 415.197 +    FT_AutoHinter_GlobalDoneFunc   done_global_hints;
 415.198 +    FT_AutoHinter_GlyphLoadFunc    load_glyph;
 415.199 +
 415.200 +  } FT_AutoHinter_ServiceRec, *FT_AutoHinter_Service;
 415.201 +
 415.202 +#ifndef FT_CONFIG_OPTION_PIC
 415.203 +
 415.204 +#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \
 415.205 +                                     done_global_hints_, load_glyph_)        \
 415.206 +  FT_CALLBACK_TABLE_DEF                                                      \
 415.207 +  const FT_AutoHinter_ServiceRec class_ =                                    \
 415.208 +  {                                                                          \
 415.209 +    reset_face_, get_global_hints_, done_global_hints_, load_glyph_          \
 415.210 +  };
 415.211 +
 415.212 +#else /* FT_CONFIG_OPTION_PIC */ 
 415.213 +
 415.214 +#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \
 415.215 +                                     done_global_hints_, load_glyph_)        \
 415.216 +  void                                                                       \
 415.217 +  FT_Init_Class_##class_( FT_Library library,                                \
 415.218 +                          FT_AutoHinter_ServiceRec* clazz)                   \
 415.219 +  {                                                                          \
 415.220 +    FT_UNUSED(library);                                                      \
 415.221 +    clazz->reset_face = reset_face_;                                         \
 415.222 +    clazz->get_global_hints = get_global_hints_;                             \
 415.223 +    clazz->done_global_hints = done_global_hints_;                           \
 415.224 +    clazz->load_glyph = load_glyph_;                                         \
 415.225 +  } 
 415.226 +
 415.227 +#endif /* FT_CONFIG_OPTION_PIC */ 
 415.228 +
 415.229 +FT_END_HEADER
 415.230 +
 415.231 +#endif /* __AUTOHINT_H__ */
 415.232 +
 415.233 +
 415.234 +/* END */
   416.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   416.2 +++ b/libs/ft2static/freetype/internal/ftcalc.h	Sat Feb 01 19:58:19 2014 +0200
   416.3 @@ -0,0 +1,179 @@
   416.4 +/***************************************************************************/
   416.5 +/*                                                                         */
   416.6 +/*  ftcalc.h                                                               */
   416.7 +/*                                                                         */
   416.8 +/*    Arithmetic computations (specification).                             */
   416.9 +/*                                                                         */
  416.10 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by       */
  416.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  416.12 +/*                                                                         */
  416.13 +/*  This file is part of the FreeType project, and may only be used,       */
  416.14 +/*  modified, and distributed under the terms of the FreeType project      */
  416.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  416.16 +/*  this file you indicate that you have read the license and              */
  416.17 +/*  understand and accept it fully.                                        */
  416.18 +/*                                                                         */
  416.19 +/***************************************************************************/
  416.20 +
  416.21 +
  416.22 +#ifndef __FTCALC_H__
  416.23 +#define __FTCALC_H__
  416.24 +
  416.25 +
  416.26 +#include <ft2build.h>
  416.27 +#include FT_FREETYPE_H
  416.28 +
  416.29 +
  416.30 +FT_BEGIN_HEADER
  416.31 +
  416.32 +
  416.33 +  /*************************************************************************/
  416.34 +  /*                                                                       */
  416.35 +  /* <Function>                                                            */
  416.36 +  /*    FT_FixedSqrt                                                       */
  416.37 +  /*                                                                       */
  416.38 +  /* <Description>                                                         */
  416.39 +  /*    Computes the square root of a 16.16 fixed point value.             */
  416.40 +  /*                                                                       */
  416.41 +  /* <Input>                                                               */
  416.42 +  /*    x :: The value to compute the root for.                            */
  416.43 +  /*                                                                       */
  416.44 +  /* <Return>                                                              */
  416.45 +  /*    The result of `sqrt(x)'.                                           */
  416.46 +  /*                                                                       */
  416.47 +  /* <Note>                                                                */
  416.48 +  /*    This function is not very fast.                                    */
  416.49 +  /*                                                                       */
  416.50 +  FT_BASE( FT_Int32 )
  416.51 +  FT_SqrtFixed( FT_Int32  x );
  416.52 +
  416.53 +
  416.54 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
  416.55 +
  416.56 +  /*************************************************************************/
  416.57 +  /*                                                                       */
  416.58 +  /* <Function>                                                            */
  416.59 +  /*    FT_Sqrt32                                                          */
  416.60 +  /*                                                                       */
  416.61 +  /* <Description>                                                         */
  416.62 +  /*    Computes the square root of an Int32 integer (which will be        */
  416.63 +  /*    handled as an unsigned long value).                                */
  416.64 +  /*                                                                       */
  416.65 +  /* <Input>                                                               */
  416.66 +  /*    x :: The value to compute the root for.                            */
  416.67 +  /*                                                                       */
  416.68 +  /* <Return>                                                              */
  416.69 +  /*    The result of `sqrt(x)'.                                           */
  416.70 +  /*                                                                       */
  416.71 +  FT_EXPORT( FT_Int32 )
  416.72 +  FT_Sqrt32( FT_Int32  x );
  416.73 +
  416.74 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
  416.75 +
  416.76 +
  416.77 +  /*************************************************************************/
  416.78 +  /*                                                                       */
  416.79 +  /* FT_MulDiv() and FT_MulFix() are declared in freetype.h.               */
  416.80 +  /*                                                                       */
  416.81 +  /*************************************************************************/
  416.82 +
  416.83 +
  416.84 +#ifdef TT_USE_BYTECODE_INTERPRETER
  416.85 +
  416.86 +  /*************************************************************************/
  416.87 +  /*                                                                       */
  416.88 +  /* <Function>                                                            */
  416.89 +  /*    FT_MulDiv_No_Round                                                 */
  416.90 +  /*                                                                       */
  416.91 +  /* <Description>                                                         */
  416.92 +  /*    A very simple function used to perform the computation `(a*b)/c'   */
  416.93 +  /*    (without rounding) with maximal accuracy (it uses a 64-bit         */
  416.94 +  /*    intermediate integer whenever necessary).                          */
  416.95 +  /*                                                                       */
  416.96 +  /*    This function isn't necessarily as fast as some processor specific */
  416.97 +  /*    operations, but is at least completely portable.                   */
  416.98 +  /*                                                                       */
  416.99 +  /* <Input>                                                               */
 416.100 +  /*    a :: The first multiplier.                                         */
 416.101 +  /*    b :: The second multiplier.                                        */
 416.102 +  /*    c :: The divisor.                                                  */
 416.103 +  /*                                                                       */
 416.104 +  /* <Return>                                                              */
 416.105 +  /*    The result of `(a*b)/c'.  This function never traps when trying to */
 416.106 +  /*    divide by zero; it simply returns `MaxInt' or `MinInt' depending   */
 416.107 +  /*    on the signs of `a' and `b'.                                       */
 416.108 +  /*                                                                       */
 416.109 +  FT_BASE( FT_Long )
 416.110 +  FT_MulDiv_No_Round( FT_Long  a,
 416.111 +                      FT_Long  b,
 416.112 +                      FT_Long  c );
 416.113 +
 416.114 +#endif /* TT_USE_BYTECODE_INTERPRETER */
 416.115 +
 416.116 +
 416.117 +  /*
 416.118 +   *  A variant of FT_Matrix_Multiply which scales its result afterwards.
 416.119 +   *  The idea is that both `a' and `b' are scaled by factors of 10 so that
 416.120 +   *  the values are as precise as possible to get a correct result during
 416.121 +   *  the 64bit multiplication.  Let `sa' and `sb' be the scaling factors of
 416.122 +   *  `a' and `b', respectively, then the scaling factor of the result is
 416.123 +   *  `sa*sb'.
 416.124 +   */
 416.125 +  FT_BASE( void )
 416.126 +  FT_Matrix_Multiply_Scaled( const FT_Matrix*  a,
 416.127 +                             FT_Matrix        *b,
 416.128 +                             FT_Long           scaling );
 416.129 +
 416.130 +
 416.131 +  /*
 416.132 +   *  A variant of FT_Vector_Transform.  See comments for
 416.133 +   *  FT_Matrix_Multiply_Scaled.
 416.134 +   */
 416.135 +
 416.136 +  FT_BASE( void )
 416.137 +  FT_Vector_Transform_Scaled( FT_Vector*        vector,
 416.138 +                              const FT_Matrix*  matrix,
 416.139 +                              FT_Long           scaling );
 416.140 +
 416.141 +
 416.142 +  /*
 416.143 +   *  Return -1, 0, or +1, depending on the orientation of a given corner.
 416.144 +   *  We use the Cartesian coordinate system, with positive vertical values
 416.145 +   *  going upwards.  The function returns +1 if the corner turns to the
 416.146 +   *  left, -1 to the right, and 0 for undecidable cases.
 416.147 +   */
 416.148 +  FT_BASE( FT_Int )
 416.149 +  ft_corner_orientation( FT_Pos  in_x,
 416.150 +                         FT_Pos  in_y,
 416.151 +                         FT_Pos  out_x,
 416.152 +                         FT_Pos  out_y );
 416.153 +
 416.154 +  /*
 416.155 +   *  Return TRUE if a corner is flat or nearly flat.  This is equivalent to
 416.156 +   *  saying that the angle difference between the `in' and `out' vectors is
 416.157 +   *  very small.
 416.158 +   */
 416.159 +  FT_BASE( FT_Int )
 416.160 +  ft_corner_is_flat( FT_Pos  in_x,
 416.161 +                     FT_Pos  in_y,
 416.162 +                     FT_Pos  out_x,
 416.163 +                     FT_Pos  out_y );
 416.164 +
 416.165 +
 416.166 +#define INT_TO_F26DOT6( x )    ( (FT_Long)(x) << 6  )
 416.167 +#define INT_TO_F2DOT14( x )    ( (FT_Long)(x) << 14 )
 416.168 +#define INT_TO_FIXED( x )      ( (FT_Long)(x) << 16 )
 416.169 +#define F2DOT14_TO_FIXED( x )  ( (FT_Long)(x) << 2  )
 416.170 +#define FLOAT_TO_FIXED( x )    ( (FT_Long)( x * 65536.0 ) )
 416.171 +#define FIXED_TO_INT( x )      ( FT_RoundFix( x ) >> 16 )
 416.172 +
 416.173 +#define ROUND_F26DOT6( x )     ( x >= 0 ? (    ( (x) + 32 ) & -64 )     \
 416.174 +                                        : ( -( ( 32 - (x) ) & -64 ) ) )
 416.175 +
 416.176 +
 416.177 +FT_END_HEADER
 416.178 +
 416.179 +#endif /* __FTCALC_H__ */
 416.180 +
 416.181 +
 416.182 +/* END */
   417.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   417.2 +++ b/libs/ft2static/freetype/internal/ftdebug.h	Sat Feb 01 19:58:19 2014 +0200
   417.3 @@ -0,0 +1,250 @@
   417.4 +/***************************************************************************/
   417.5 +/*                                                                         */
   417.6 +/*  ftdebug.h                                                              */
   417.7 +/*                                                                         */
   417.8 +/*    Debugging and logging component (specification).                     */
   417.9 +/*                                                                         */
  417.10 +/*  Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008, 2009 by             */
  417.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  417.12 +/*                                                                         */
  417.13 +/*  This file is part of the FreeType project, and may only be used,       */
  417.14 +/*  modified, and distributed under the terms of the FreeType project      */
  417.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  417.16 +/*  this file you indicate that you have read the license and              */
  417.17 +/*  understand and accept it fully.                                        */
  417.18 +/*                                                                         */
  417.19 +/*                                                                         */
  417.20 +/*  IMPORTANT: A description of FreeType's debugging support can be        */
  417.21 +/*             found in `docs/DEBUG.TXT'.  Read it if you need to use or   */
  417.22 +/*             understand this code.                                       */
  417.23 +/*                                                                         */
  417.24 +/***************************************************************************/
  417.25 +
  417.26 +
  417.27 +#ifndef __FTDEBUG_H__
  417.28 +#define __FTDEBUG_H__
  417.29 +
  417.30 +
  417.31 +#include <ft2build.h>
  417.32 +#include FT_CONFIG_CONFIG_H
  417.33 +#include FT_FREETYPE_H
  417.34 +
  417.35 +
  417.36 +FT_BEGIN_HEADER
  417.37 +
  417.38 +
  417.39 +  /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */
  417.40 +  /* is already defined; this simplifies the following #ifdefs            */
  417.41 +  /*                                                                      */
  417.42 +#ifdef FT_DEBUG_LEVEL_TRACE
  417.43 +#undef  FT_DEBUG_LEVEL_ERROR
  417.44 +#define FT_DEBUG_LEVEL_ERROR
  417.45 +#endif
  417.46 +
  417.47 +
  417.48 +  /*************************************************************************/
  417.49 +  /*                                                                       */
  417.50 +  /* Define the trace enums as well as the trace levels array when they    */
  417.51 +  /* are needed.                                                           */
  417.52 +  /*                                                                       */
  417.53 +  /*************************************************************************/
  417.54 +
  417.55 +#ifdef FT_DEBUG_LEVEL_TRACE
  417.56 +
  417.57 +#define FT_TRACE_DEF( x )  trace_ ## x ,
  417.58 +
  417.59 +  /* defining the enumeration */
  417.60 +  typedef enum  FT_Trace_
  417.61 +  {
  417.62 +#include FT_INTERNAL_TRACE_H
  417.63 +    trace_count
  417.64 +
  417.65 +  } FT_Trace;
  417.66 +
  417.67 +
  417.68 +  /* defining the array of trace levels, provided by `src/base/ftdebug.c' */
  417.69 +  extern int  ft_trace_levels[trace_count];
  417.70 +
  417.71 +#undef FT_TRACE_DEF
  417.72 +
  417.73 +#endif /* FT_DEBUG_LEVEL_TRACE */
  417.74 +
  417.75 +
  417.76 +  /*************************************************************************/
  417.77 +  /*                                                                       */
  417.78 +  /* Define the FT_TRACE macro                                             */
  417.79 +  /*                                                                       */
  417.80 +  /* IMPORTANT!                                                            */
  417.81 +  /*                                                                       */
  417.82 +  /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */
  417.83 +  /* value before using any TRACE macro.                                   */
  417.84 +  /*                                                                       */
  417.85 +  /*************************************************************************/
  417.86 +
  417.87 +#ifdef FT_DEBUG_LEVEL_TRACE
  417.88 +
  417.89 +#define FT_TRACE( level, varformat )                      \
  417.90 +          do                                              \
  417.91 +          {                                               \
  417.92 +            if ( ft_trace_levels[FT_COMPONENT] >= level ) \
  417.93 +              FT_Message varformat;                       \
  417.94 +          } while ( 0 )
  417.95 +
  417.96 +#else /* !FT_DEBUG_LEVEL_TRACE */
  417.97 +
  417.98 +#define FT_TRACE( level, varformat )  do { } while ( 0 )      /* nothing */
  417.99 +
 417.100 +#endif /* !FT_DEBUG_LEVEL_TRACE */
 417.101 +
 417.102 +
 417.103 +  /*************************************************************************/
 417.104 +  /*                                                                       */
 417.105 +  /* <Function>                                                            */
 417.106 +  /*    FT_Trace_Get_Count                                                 */
 417.107 +  /*                                                                       */
 417.108 +  /* <Description>                                                         */
 417.109 +  /*    Return the number of available trace components.                   */
 417.110 +  /*                                                                       */
 417.111 +  /* <Return>                                                              */
 417.112 +  /*    The number of trace components.  0 if FreeType 2 is not built with */
 417.113 +  /*    FT_DEBUG_LEVEL_TRACE definition.                                   */
 417.114 +  /*                                                                       */
 417.115 +  /* <Note>                                                                */
 417.116 +  /*    This function may be useful if you want to access elements of      */
 417.117 +  /*    the internal `ft_trace_levels' array by an index.                  */
 417.118 +  /*                                                                       */
 417.119 +  FT_BASE( FT_Int )
 417.120 +  FT_Trace_Get_Count( void );
 417.121 +
 417.122 +
 417.123 +  /*************************************************************************/
 417.124 +  /*                                                                       */
 417.125 +  /* <Function>                                                            */
 417.126 +  /*    FT_Trace_Get_Name                                                  */
 417.127 +  /*                                                                       */
 417.128 +  /* <Description>                                                         */
 417.129 +  /*    Return the name of a trace component.                              */
 417.130 +  /*                                                                       */
 417.131 +  /* <Input>                                                               */
 417.132 +  /*    The index of the trace component.                                  */
 417.133 +  /*                                                                       */
 417.134 +  /* <Return>                                                              */
 417.135 +  /*    The name of the trace component.  This is a statically allocated   */
 417.136 +  /*    C string, so do not free it after use.  NULL if FreeType 2 is not  */
 417.137 +  /*    built with FT_DEBUG_LEVEL_TRACE definition.                        */
 417.138 +  /*                                                                       */
 417.139 +  /* <Note>                                                                */
 417.140 +  /*    Use @FT_Trace_Get_Count to get the number of available trace       */
 417.141 +  /*    components.                                                        */
 417.142 +  /*                                                                       */
 417.143 +  /*    This function may be useful if you want to control FreeType 2's    */
 417.144 +  /*    debug level in your application.                                   */
 417.145 +  /*                                                                       */
 417.146 +  FT_BASE( const char * )
 417.147 +  FT_Trace_Get_Name( FT_Int  idx );
 417.148 +
 417.149 +
 417.150 +  /*************************************************************************/
 417.151 +  /*                                                                       */
 417.152 +  /* You need two opening and closing parentheses!                         */
 417.153 +  /*                                                                       */
 417.154 +  /* Example: FT_TRACE0(( "Value is %i", foo ))                            */
 417.155 +  /*                                                                       */
 417.156 +  /* Output of the FT_TRACEX macros is sent to stderr.                     */
 417.157 +  /*                                                                       */
 417.158 +  /*************************************************************************/
 417.159 +
 417.160 +#define FT_TRACE0( varformat )  FT_TRACE( 0, varformat )
 417.161 +#define FT_TRACE1( varformat )  FT_TRACE( 1, varformat )
 417.162 +#define FT_TRACE2( varformat )  FT_TRACE( 2, varformat )
 417.163 +#define FT_TRACE3( varformat )  FT_TRACE( 3, varformat )
 417.164 +#define FT_TRACE4( varformat )  FT_TRACE( 4, varformat )
 417.165 +#define FT_TRACE5( varformat )  FT_TRACE( 5, varformat )
 417.166 +#define FT_TRACE6( varformat )  FT_TRACE( 6, varformat )
 417.167 +#define FT_TRACE7( varformat )  FT_TRACE( 7, varformat )
 417.168 +
 417.169 +
 417.170 +  /*************************************************************************/
 417.171 +  /*                                                                       */
 417.172 +  /* Define the FT_ERROR macro.                                            */
 417.173 +  /*                                                                       */
 417.174 +  /* Output of this macro is sent to stderr.                               */
 417.175 +  /*                                                                       */
 417.176 +  /*************************************************************************/
 417.177 +
 417.178 +#ifdef FT_DEBUG_LEVEL_ERROR
 417.179 +
 417.180 +#define FT_ERROR( varformat )  FT_Message  varformat
 417.181 +
 417.182 +#else  /* !FT_DEBUG_LEVEL_ERROR */
 417.183 +
 417.184 +#define FT_ERROR( varformat )  do { } while ( 0 )      /* nothing */
 417.185 +
 417.186 +#endif /* !FT_DEBUG_LEVEL_ERROR */
 417.187 +
 417.188 +
 417.189 +  /*************************************************************************/
 417.190 +  /*                                                                       */
 417.191 +  /* Define the FT_ASSERT macro.                                           */
 417.192 +  /*                                                                       */
 417.193 +  /*************************************************************************/
 417.194 +
 417.195 +#ifdef FT_DEBUG_LEVEL_ERROR
 417.196 +
 417.197 +#define FT_ASSERT( condition )                                      \
 417.198 +          do                                                        \
 417.199 +          {                                                         \
 417.200 +            if ( !( condition ) )                                   \
 417.201 +              FT_Panic( "assertion failed on line %d of file %s\n", \
 417.202 +                        __LINE__, __FILE__ );                       \
 417.203 +          } while ( 0 )
 417.204 +
 417.205 +#else /* !FT_DEBUG_LEVEL_ERROR */
 417.206 +
 417.207 +#define FT_ASSERT( condition )  do { } while ( 0 )
 417.208 +
 417.209 +#endif /* !FT_DEBUG_LEVEL_ERROR */
 417.210 +
 417.211 +
 417.212 +  /*************************************************************************/
 417.213 +  /*                                                                       */
 417.214 +  /* Define `FT_Message' and `FT_Panic' when needed.                       */
 417.215 +  /*                                                                       */
 417.216 +  /*************************************************************************/
 417.217 +
 417.218 +#ifdef FT_DEBUG_LEVEL_ERROR
 417.219 +
 417.220 +#include "stdio.h"  /* for vfprintf() */
 417.221 +
 417.222 +  /* print a message */
 417.223 +  FT_BASE( void )
 417.224 +  FT_Message( const char*  fmt,
 417.225 +              ... );
 417.226 +
 417.227 +  /* print a message and exit */
 417.228 +  FT_BASE( void )
 417.229 +  FT_Panic( const char*  fmt,
 417.230 +            ... );
 417.231 +
 417.232 +#endif /* FT_DEBUG_LEVEL_ERROR */
 417.233 +
 417.234 +
 417.235 +  FT_BASE( void )
 417.236 +  ft_debug_init( void );
 417.237 +
 417.238 +
 417.239 +#if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
 417.240 +
 417.241 +  /* We disable the warning `conditional expression is constant' here */
 417.242 +  /* in order to compile cleanly with the maximum level of warnings.  */
 417.243 +#pragma warning( disable : 4127 )
 417.244 +
 417.245 +#endif /* _MSC_VER */
 417.246 +
 417.247 +
 417.248 +FT_END_HEADER
 417.249 +
 417.250 +#endif /* __FTDEBUG_H__ */
 417.251 +
 417.252 +
 417.253 +/* END */
   418.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   418.2 +++ b/libs/ft2static/freetype/internal/ftdriver.h	Sat Feb 01 19:58:19 2014 +0200
   418.3 @@ -0,0 +1,422 @@
   418.4 +/***************************************************************************/
   418.5 +/*                                                                         */
   418.6 +/*  ftdriver.h                                                             */
   418.7 +/*                                                                         */
   418.8 +/*    FreeType font driver interface (specification).                      */
   418.9 +/*                                                                         */
  418.10 +/*  Copyright 1996-2001, 2002, 2003, 2006, 2008 by                         */
  418.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  418.12 +/*                                                                         */
  418.13 +/*  This file is part of the FreeType project, and may only be used,       */
  418.14 +/*  modified, and distributed under the terms of the FreeType project      */
  418.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  418.16 +/*  this file you indicate that you have read the license and              */
  418.17 +/*  understand and accept it fully.                                        */
  418.18 +/*                                                                         */
  418.19 +/***************************************************************************/
  418.20 +
  418.21 +
  418.22 +#ifndef __FTDRIVER_H__
  418.23 +#define __FTDRIVER_H__
  418.24 +
  418.25 +
  418.26 +#include <ft2build.h>
  418.27 +#include FT_MODULE_H
  418.28 +
  418.29 +
  418.30 +FT_BEGIN_HEADER
  418.31 +
  418.32 +
  418.33 +  typedef FT_Error
  418.34 +  (*FT_Face_InitFunc)( FT_Stream      stream,
  418.35 +                       FT_Face        face,
  418.36 +                       FT_Int         typeface_index,
  418.37 +                       FT_Int         num_params,
  418.38 +                       FT_Parameter*  parameters );
  418.39 +
  418.40 +  typedef void
  418.41 +  (*FT_Face_DoneFunc)( FT_Face  face );
  418.42 +
  418.43 +
  418.44 +  typedef FT_Error
  418.45 +  (*FT_Size_InitFunc)( FT_Size  size );
  418.46 +
  418.47 +  typedef void
  418.48 +  (*FT_Size_DoneFunc)( FT_Size  size );
  418.49 +
  418.50 +
  418.51 +  typedef FT_Error
  418.52 +  (*FT_Slot_InitFunc)( FT_GlyphSlot  slot );
  418.53 +
  418.54 +  typedef void
  418.55 +  (*FT_Slot_DoneFunc)( FT_GlyphSlot  slot );
  418.56 +
  418.57 +
  418.58 +  typedef FT_Error
  418.59 +  (*FT_Size_RequestFunc)( FT_Size          size,
  418.60 +                          FT_Size_Request  req );
  418.61 +
  418.62 +  typedef FT_Error
  418.63 +  (*FT_Size_SelectFunc)( FT_Size   size,
  418.64 +                         FT_ULong  size_index );
  418.65 +
  418.66 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
  418.67 +
  418.68 +  typedef FT_Error
  418.69 +  (*FT_Size_ResetPointsFunc)( FT_Size     size,
  418.70 +                              FT_F26Dot6  char_width,
  418.71 +                              FT_F26Dot6  char_height,
  418.72 +                              FT_UInt     horz_resolution,
  418.73 +                              FT_UInt     vert_resolution );
  418.74 +
  418.75 +  typedef FT_Error
  418.76 +  (*FT_Size_ResetPixelsFunc)( FT_Size  size,
  418.77 +                              FT_UInt  pixel_width,
  418.78 +                              FT_UInt  pixel_height );
  418.79 +
  418.80 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
  418.81 +
  418.82 +  typedef FT_Error
  418.83 +  (*FT_Slot_LoadFunc)( FT_GlyphSlot  slot,
  418.84 +                       FT_Size       size,
  418.85 +                       FT_UInt       glyph_index,
  418.86 +                       FT_Int32      load_flags );
  418.87 +
  418.88 +
  418.89 +  typedef FT_UInt
  418.90 +  (*FT_CharMap_CharIndexFunc)( FT_CharMap  charmap,
  418.91 +                               FT_Long     charcode );
  418.92 +
  418.93 +  typedef FT_Long
  418.94 +  (*FT_CharMap_CharNextFunc)( FT_CharMap  charmap,
  418.95 +                              FT_Long     charcode );
  418.96 +
  418.97 +
  418.98 +  typedef FT_Error
  418.99 +  (*FT_Face_GetKerningFunc)( FT_Face     face,
 418.100 +                             FT_UInt     left_glyph,
 418.101 +                             FT_UInt     right_glyph,
 418.102 +                             FT_Vector*  kerning );
 418.103 +
 418.104 +
 418.105 +  typedef FT_Error
 418.106 +  (*FT_Face_AttachFunc)( FT_Face    face,
 418.107 +                         FT_Stream  stream );
 418.108 +
 418.109 +
 418.110 +  typedef FT_Error
 418.111 +  (*FT_Face_GetAdvancesFunc)( FT_Face    face,
 418.112 +                              FT_UInt    first,
 418.113 +                              FT_UInt    count,
 418.114 +                              FT_Int32   flags,
 418.115 +                              FT_Fixed*  advances );
 418.116 +
 418.117 +
 418.118 +  /*************************************************************************/
 418.119 +  /*                                                                       */
 418.120 +  /* <Struct>                                                              */
 418.121 +  /*    FT_Driver_ClassRec                                                 */
 418.122 +  /*                                                                       */
 418.123 +  /* <Description>                                                         */
 418.124 +  /*    The font driver class.  This structure mostly contains pointers to */
 418.125 +  /*    driver methods.                                                    */
 418.126 +  /*                                                                       */
 418.127 +  /* <Fields>                                                              */
 418.128 +  /*    root             :: The parent module.                             */
 418.129 +  /*                                                                       */
 418.130 +  /*    face_object_size :: The size of a face object in bytes.            */
 418.131 +  /*                                                                       */
 418.132 +  /*    size_object_size :: The size of a size object in bytes.            */
 418.133 +  /*                                                                       */
 418.134 +  /*    slot_object_size :: The size of a glyph object in bytes.           */
 418.135 +  /*                                                                       */
 418.136 +  /*    init_face        :: The format-specific face constructor.          */
 418.137 +  /*                                                                       */
 418.138 +  /*    done_face        :: The format-specific face destructor.           */
 418.139 +  /*                                                                       */
 418.140 +  /*    init_size        :: The format-specific size constructor.          */
 418.141 +  /*                                                                       */
 418.142 +  /*    done_size        :: The format-specific size destructor.           */
 418.143 +  /*                                                                       */
 418.144 +  /*    init_slot        :: The format-specific slot constructor.          */
 418.145 +  /*                                                                       */
 418.146 +  /*    done_slot        :: The format-specific slot destructor.           */
 418.147 +  /*                                                                       */
 418.148 +  /*                                                                       */
 418.149 +  /*    load_glyph       :: A function handle to load a glyph to a slot.   */
 418.150 +  /*                        This field is mandatory!                       */
 418.151 +  /*                                                                       */
 418.152 +  /*    get_kerning      :: A function handle to return the unscaled       */
 418.153 +  /*                        kerning for a given pair of glyphs.  Can be    */
 418.154 +  /*                        set to 0 if the format doesn't support         */
 418.155 +  /*                        kerning.                                       */
 418.156 +  /*                                                                       */
 418.157 +  /*    attach_file      :: This function handle is used to read           */
 418.158 +  /*                        additional data for a face from another        */
 418.159 +  /*                        file/stream.  For example, this can be used to */
 418.160 +  /*                        add data from AFM or PFM files on a Type 1     */
 418.161 +  /*                        face, or a CIDMap on a CID-keyed face.         */
 418.162 +  /*                                                                       */
 418.163 +  /*    get_advances     :: A function handle used to return advance       */
 418.164 +  /*                        widths of `count' glyphs (in font units),      */
 418.165 +  /*                        starting at `first'.  The `vertical' flag must */
 418.166 +  /*                        be set to get vertical advance heights.  The   */
 418.167 +  /*                        `advances' buffer is caller-allocated.         */
 418.168 +  /*                        Currently not implemented.  The idea of this   */
 418.169 +  /*                        function is to be able to perform              */
 418.170 +  /*                        device-independent text layout without loading */
 418.171 +  /*                        a single glyph image.                          */
 418.172 +  /*                                                                       */
 418.173 +  /*    request_size     :: A handle to a function used to request the new */
 418.174 +  /*                        character size.  Can be set to 0 if the        */
 418.175 +  /*                        scaling done in the base layer suffices.       */
 418.176 +  /*                                                                       */
 418.177 +  /*    select_size      :: A handle to a function used to select a new    */
 418.178 +  /*                        fixed size.  It is used only if                */
 418.179 +  /*                        @FT_FACE_FLAG_FIXED_SIZES is set.  Can be set  */
 418.180 +  /*                        to 0 if the scaling done in the base layer     */
 418.181 +  /*                        suffices.                                      */
 418.182 +  /* <Note>                                                                */
 418.183 +  /*    Most function pointers, with the exception of `load_glyph', can be */
 418.184 +  /*    set to 0 to indicate a default behaviour.                          */
 418.185 +  /*                                                                       */
 418.186 +  typedef struct  FT_Driver_ClassRec_
 418.187 +  {
 418.188 +    FT_Module_Class           root;
 418.189 +
 418.190 +    FT_Long                   face_object_size;
 418.191 +    FT_Long                   size_object_size;
 418.192 +    FT_Long                   slot_object_size;
 418.193 +
 418.194 +    FT_Face_InitFunc          init_face;
 418.195 +    FT_Face_DoneFunc          done_face;
 418.196 +
 418.197 +    FT_Size_InitFunc          init_size;
 418.198 +    FT_Size_DoneFunc          done_size;
 418.199 +
 418.200 +    FT_Slot_InitFunc          init_slot;
 418.201 +    FT_Slot_DoneFunc          done_slot;
 418.202 +
 418.203 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 418.204 +
 418.205 +    FT_Size_ResetPointsFunc   set_char_sizes;
 418.206 +    FT_Size_ResetPixelsFunc   set_pixel_sizes;
 418.207 +
 418.208 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
 418.209 +
 418.210 +    FT_Slot_LoadFunc          load_glyph;
 418.211 +
 418.212 +    FT_Face_GetKerningFunc    get_kerning;
 418.213 +    FT_Face_AttachFunc        attach_file;
 418.214 +    FT_Face_GetAdvancesFunc   get_advances;
 418.215 +
 418.216 +    /* since version 2.2 */
 418.217 +    FT_Size_RequestFunc       request_size;
 418.218 +    FT_Size_SelectFunc        select_size;
 418.219 +
 418.220 +  } FT_Driver_ClassRec, *FT_Driver_Class;
 418.221 +
 418.222 +
 418.223 +  /*
 418.224 +   *  The following functions are used as stubs for `set_char_sizes' and
 418.225 +   *  `set_pixel_sizes'; the code uses `request_size' and `select_size'
 418.226 +   *  functions instead.
 418.227 +   *
 418.228 +   *  Implementation is in `src/base/ftobjs.c'.
 418.229 +   */
 418.230 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 418.231 +
 418.232 +  FT_BASE( FT_Error )
 418.233 +  ft_stub_set_char_sizes( FT_Size     size,
 418.234 +                          FT_F26Dot6  width,
 418.235 +                          FT_F26Dot6  height,
 418.236 +                          FT_UInt     horz_res,
 418.237 +                          FT_UInt     vert_res );
 418.238 +
 418.239 +  FT_BASE( FT_Error )
 418.240 +  ft_stub_set_pixel_sizes( FT_Size  size,
 418.241 +                           FT_UInt  width,
 418.242 +                           FT_UInt  height );
 418.243 +
 418.244 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
 418.245 +
 418.246 +  /*************************************************************************/
 418.247 +  /*                                                                       */
 418.248 +  /* <Macro>                                                               */
 418.249 +  /*    FT_DECLARE_DRIVER                                                  */
 418.250 +  /*                                                                       */
 418.251 +  /* <Description>                                                         */
 418.252 +  /*    Used to create a forward declaration of a                          */
 418.253 +  /*    FT_Driver_ClassRec stract instance.                                */
 418.254 +  /*                                                                       */
 418.255 +  /* <Macro>                                                               */
 418.256 +  /*    FT_DEFINE_DRIVER                                                   */
 418.257 +  /*                                                                       */
 418.258 +  /* <Description>                                                         */
 418.259 +  /*    Used to initialize an instance of FT_Driver_ClassRec struct.       */
 418.260 +  /*                                                                       */
 418.261 +  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */
 418.262 +  /*    to called with a pointer where the allocated stracture is returned.*/
 418.263 +  /*    And when it is no longer needed a Destroy function needs           */
 418.264 +  /*    to be called to release that allocation.                           */
 418.265 +  /*    fcinit.c (ft_create_default_module_classes) already contains       */
 418.266 +  /*    a mechanism to call these functions for the default modules        */
 418.267 +  /*    described in ftmodule.h                                            */
 418.268 +  /*                                                                       */
 418.269 +  /*    Notice that the created Create and Destroy functions call          */
 418.270 +  /*    pic_init and pic_free function to allow you to manually allocate   */
 418.271 +  /*    and initialize any additional global data, like module specific    */
 418.272 +  /*    interface, and put them in the global pic container defined in     */
 418.273 +  /*    ftpic.h. if you don't need them just implement the functions as    */
 418.274 +  /*    empty to resolve the link error.                                   */
 418.275 +  /*                                                                       */
 418.276 +  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
 418.277 +  /*    allocated in the global scope (or the scope where the macro        */
 418.278 +  /*    is used).                                                          */
 418.279 +  /*                                                                       */
 418.280 +#ifndef FT_CONFIG_OPTION_PIC
 418.281 +
 418.282 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 418.283 +#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \
 418.284 +  a_, b_,
 418.285 +#else
 418.286 +  #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_)
 418.287 +#endif
 418.288 +
 418.289 +#define FT_DECLARE_DRIVER(class_)    \
 418.290 +  FT_CALLBACK_TABLE                  \
 418.291 +  const FT_Driver_ClassRec  class_;  
 418.292 +
 418.293 +#define FT_DEFINE_DRIVER(class_,                                             \
 418.294 +                         flags_, size_, name_, version_, requires_,          \
 418.295 +                         interface_, init_, done_, get_interface_,           \
 418.296 +                         face_object_size_, size_object_size_,               \
 418.297 +                         slot_object_size_, init_face_, done_face_,          \
 418.298 +                         init_size_, done_size_, init_slot_, done_slot_,     \
 418.299 +                         old_set_char_sizes_, old_set_pixel_sizes_,          \
 418.300 +                         load_glyph_, get_kerning_, attach_file_,            \
 418.301 +                         get_advances_, request_size_, select_size_ )        \
 418.302 +  FT_CALLBACK_TABLE_DEF                                                      \
 418.303 +  const FT_Driver_ClassRec class_ =                                          \
 418.304 +  {                                                                          \
 418.305 +    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_,  \
 418.306 +                          init_,done_,get_interface_)                        \
 418.307 +                                                                             \
 418.308 +    face_object_size_,                                                       \
 418.309 +    size_object_size_,                                                       \
 418.310 +    slot_object_size_,                                                       \
 418.311 +                                                                             \
 418.312 +    init_face_,                                                              \
 418.313 +    done_face_,                                                              \
 418.314 +                                                                             \
 418.315 +    init_size_,                                                              \
 418.316 +    done_size_,                                                              \
 418.317 +                                                                             \
 418.318 +    init_slot_,                                                              \
 418.319 +    done_slot_,                                                              \
 418.320 +                                                                             \
 418.321 +    FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \
 418.322 +                                                                             \
 418.323 +    load_glyph_,                                                             \
 418.324 +                                                                             \
 418.325 +    get_kerning_,                                                            \
 418.326 +    attach_file_,                                                            \
 418.327 +    get_advances_,                                                           \
 418.328 +                                                                             \
 418.329 +    request_size_,                                                           \
 418.330 +    select_size_                                                             \
 418.331 +  };
 418.332 +
 418.333 +#else /* FT_CONFIG_OPTION_PIC */ 
 418.334 +
 418.335 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 418.336 +#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \
 418.337 +  clazz->set_char_sizes = a_; \
 418.338 +  clazz->set_pixel_sizes = b_;
 418.339 +#else
 418.340 +  #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_)
 418.341 +#endif
 418.342 +
 418.343 +#define FT_DECLARE_DRIVER(class_)    FT_DECLARE_MODULE(class_)
 418.344 +
 418.345 +#define FT_DEFINE_DRIVER(class_,                                             \
 418.346 +                         flags_, size_, name_, version_, requires_,          \
 418.347 +                         interface_, init_, done_, get_interface_,           \
 418.348 +                         face_object_size_, size_object_size_,               \
 418.349 +                         slot_object_size_, init_face_, done_face_,          \
 418.350 +                         init_size_, done_size_, init_slot_, done_slot_,     \
 418.351 +                         old_set_char_sizes_, old_set_pixel_sizes_,          \
 418.352 +                         load_glyph_, get_kerning_, attach_file_,            \
 418.353 +                         get_advances_, request_size_, select_size_ )        \
 418.354 +  void class_##_pic_free( FT_Library library );                              \
 418.355 +  FT_Error class_##_pic_init( FT_Library library );                          \
 418.356 +                                                                             \
 418.357 +  void                                                                       \
 418.358 +  FT_Destroy_Class_##class_( FT_Library        library,                      \
 418.359 +                             FT_Module_Class*  clazz )                       \
 418.360 +  {                                                                          \
 418.361 +    FT_Memory       memory = library->memory;                                \
 418.362 +    FT_Driver_Class dclazz = (FT_Driver_Class)clazz;                         \
 418.363 +    class_##_pic_free( library );                                            \
 418.364 +    if ( dclazz )                                                            \
 418.365 +      FT_FREE( dclazz );                                                     \
 418.366 +  }                                                                          \
 418.367 +                                                                             \
 418.368 +  FT_Error                                                                   \
 418.369 +  FT_Create_Class_##class_( FT_Library        library,                       \
 418.370 +                            FT_Module_Class**  output_class )                \
 418.371 +  {                                                                          \
 418.372 +    FT_Driver_Class  clazz;                                                  \
 418.373 +    FT_Error         error;                                                  \
 418.374 +    FT_Memory        memory = library->memory;                               \
 418.375 +                                                                             \
 418.376 +    if ( FT_ALLOC( clazz, sizeof(*clazz) ) )                                 \
 418.377 +      return error;                                                          \
 418.378 +                                                                             \
 418.379 +    error = class_##_pic_init( library );                                    \
 418.380 +    if(error)                                                                \
 418.381 +    {                                                                        \
 418.382 +      FT_FREE( clazz );                                                      \
 418.383 +      return error;                                                          \
 418.384 +    }                                                                        \
 418.385 +                                                                             \
 418.386 +    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_,  \
 418.387 +                          init_,done_,get_interface_)                        \
 418.388 +                                                                             \
 418.389 +    clazz->face_object_size    = face_object_size_;                          \
 418.390 +    clazz->size_object_size    = size_object_size_;                          \
 418.391 +    clazz->slot_object_size    = slot_object_size_;                          \
 418.392 +                                                                             \
 418.393 +    clazz->init_face           = init_face_;                                 \
 418.394 +    clazz->done_face           = done_face_;                                 \
 418.395 +                                                                             \
 418.396 +    clazz->init_size           = init_size_;                                 \
 418.397 +    clazz->done_size           = done_size_;                                 \
 418.398 +                                                                             \
 418.399 +    clazz->init_slot           = init_slot_;                                 \
 418.400 +    clazz->done_slot           = done_slot_;                                 \
 418.401 +                                                                             \
 418.402 +    FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \
 418.403 +                                                                             \
 418.404 +    clazz->load_glyph          = load_glyph_;                                \
 418.405 +                                                                             \
 418.406 +    clazz->get_kerning         = get_kerning_;                               \
 418.407 +    clazz->attach_file         = attach_file_;                               \
 418.408 +    clazz->get_advances        = get_advances_;                              \
 418.409 +                                                                             \
 418.410 +    clazz->request_size        = request_size_;                              \
 418.411 +    clazz->select_size         = select_size_;                               \
 418.412 +                                                                             \
 418.413 +    *output_class = (FT_Module_Class*)clazz;                                 \
 418.414 +    return FT_Err_Ok;                                                        \
 418.415 +  }                
 418.416 +
 418.417 +
 418.418 +#endif /* FT_CONFIG_OPTION_PIC */
 418.419 +
 418.420 +FT_END_HEADER
 418.421 +
 418.422 +#endif /* __FTDRIVER_H__ */
 418.423 +
 418.424 +
 418.425 +/* END */
   419.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   419.2 +++ b/libs/ft2static/freetype/internal/ftgloadr.h	Sat Feb 01 19:58:19 2014 +0200
   419.3 @@ -0,0 +1,168 @@
   419.4 +/***************************************************************************/
   419.5 +/*                                                                         */
   419.6 +/*  ftgloadr.h                                                             */
   419.7 +/*                                                                         */
   419.8 +/*    The FreeType glyph loader (specification).                           */
   419.9 +/*                                                                         */
  419.10 +/*  Copyright 2002, 2003, 2005, 2006 by                                    */
  419.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
  419.12 +/*                                                                         */
  419.13 +/*  This file is part of the FreeType project, and may only be used,       */
  419.14 +/*  modified, and distributed under the terms of the FreeType project      */
  419.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  419.16 +/*  this file you indicate that you have read the license and              */
  419.17 +/*  understand and accept it fully.                                        */
  419.18 +/*                                                                         */
  419.19 +/***************************************************************************/
  419.20 +
  419.21 +
  419.22 +#ifndef __FTGLOADR_H__
  419.23 +#define __FTGLOADR_H__
  419.24 +
  419.25 +
  419.26 +#include <ft2build.h>
  419.27 +#include FT_FREETYPE_H
  419.28 +
  419.29 +
  419.30 +FT_BEGIN_HEADER
  419.31 +
  419.32 +
  419.33 +  /*************************************************************************/
  419.34 +  /*                                                                       */
  419.35 +  /* <Struct>                                                              */
  419.36 +  /*    FT_GlyphLoader                                                     */
  419.37 +  /*                                                                       */
  419.38 +  /* <Description>                                                         */
  419.39 +  /*    The glyph loader is an internal object used to load several glyphs */
  419.40 +  /*    together (for example, in the case of composites).                 */
  419.41 +  /*                                                                       */
  419.42 +  /* <Note>                                                                */
  419.43 +  /*    The glyph loader implementation is not part of the high-level API, */
  419.44 +  /*    hence the forward structure declaration.                           */
  419.45 +  /*                                                                       */
  419.46 +  typedef struct FT_GlyphLoaderRec_*  FT_GlyphLoader ;
  419.47 +
  419.48 +
  419.49 +#if 0  /* moved to freetype.h in version 2.2 */
  419.50 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS          1
  419.51 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES      2
  419.52 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID        4
  419.53 +#define FT_SUBGLYPH_FLAG_SCALE                   8
  419.54 +#define FT_SUBGLYPH_FLAG_XY_SCALE             0x40
  419.55 +#define FT_SUBGLYPH_FLAG_2X2                  0x80
  419.56 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS      0x200
  419.57 +#endif
  419.58 +
  419.59 +
  419.60 +  typedef struct  FT_SubGlyphRec_
  419.61 +  {
  419.62 +    FT_Int     index;
  419.63 +    FT_UShort  flags;
  419.64 +    FT_Int     arg1;
  419.65 +    FT_Int     arg2;
  419.66 +    FT_Matrix  transform;
  419.67 +
  419.68 +  } FT_SubGlyphRec;
  419.69 +
  419.70 +
  419.71 +  typedef struct  FT_GlyphLoadRec_
  419.72 +  {
  419.73 +    FT_Outline   outline;       /* outline                   */
  419.74 +    FT_Vector*   extra_points;  /* extra points table        */
  419.75 +    FT_Vector*   extra_points2; /* second extra points table */
  419.76 +    FT_UInt      num_subglyphs; /* number of subglyphs       */
  419.77 +    FT_SubGlyph  subglyphs;     /* subglyphs                 */
  419.78 +
  419.79 +  } FT_GlyphLoadRec, *FT_GlyphLoad;
  419.80 +
  419.81 +
  419.82 +  typedef struct  FT_GlyphLoaderRec_
  419.83 +  {
  419.84 +    FT_Memory        memory;
  419.85 +    FT_UInt          max_points;
  419.86 +    FT_UInt          max_contours;
  419.87 +    FT_UInt          max_subglyphs;
  419.88 +    FT_Bool          use_extra;
  419.89 +
  419.90 +    FT_GlyphLoadRec  base;
  419.91 +    FT_GlyphLoadRec  current;
  419.92 +
  419.93 +    void*            other;            /* for possible future extension? */
  419.94 +
  419.95 +  } FT_GlyphLoaderRec;
  419.96 +
  419.97 +
  419.98 +  /* create new empty glyph loader */
  419.99 +  FT_BASE( FT_Error )
 419.100 +  FT_GlyphLoader_New( FT_Memory        memory,
 419.101 +                      FT_GlyphLoader  *aloader );
 419.102 +
 419.103 +  /* add an extra points table to a glyph loader */
 419.104 +  FT_BASE( FT_Error )
 419.105 +  FT_GlyphLoader_CreateExtra( FT_GlyphLoader  loader );
 419.106 +
 419.107 +  /* destroy a glyph loader */
 419.108 +  FT_BASE( void )
 419.109 +  FT_GlyphLoader_Done( FT_GlyphLoader  loader );
 419.110 +
 419.111 +  /* reset a glyph loader (frees everything int it) */
 419.112 +  FT_BASE( void )
 419.113 +  FT_GlyphLoader_Reset( FT_GlyphLoader  loader );
 419.114 +
 419.115 +  /* rewind a glyph loader */
 419.116 +  FT_BASE( void )
 419.117 +  FT_GlyphLoader_Rewind( FT_GlyphLoader  loader );
 419.118 +
 419.119 +  /* check that there is enough space to add `n_points' and `n_contours' */
 419.120 +  /* to the glyph loader                                                 */
 419.121 +  FT_BASE( FT_Error )
 419.122 +  FT_GlyphLoader_CheckPoints( FT_GlyphLoader  loader,
 419.123 +                              FT_UInt         n_points,
 419.124 +                              FT_UInt         n_contours );
 419.125 +
 419.126 +
 419.127 +#define FT_GLYPHLOADER_CHECK_P( _loader, _count )                         \
 419.128 +   ( (_count) == 0 || ((_loader)->base.outline.n_points    +              \
 419.129 +                       (_loader)->current.outline.n_points +              \
 419.130 +                       (unsigned long)(_count)) <= (_loader)->max_points )
 419.131 +
 419.132 +#define FT_GLYPHLOADER_CHECK_C( _loader, _count )                          \
 419.133 +  ( (_count) == 0 || ((_loader)->base.outline.n_contours    +              \
 419.134 +                      (_loader)->current.outline.n_contours +              \
 419.135 +                      (unsigned long)(_count)) <= (_loader)->max_contours )
 419.136 +
 419.137 +#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours )      \
 419.138 +  ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points )   &&                  \
 419.139 +      FT_GLYPHLOADER_CHECK_C( _loader, _contours ) )                   \
 419.140 +    ? 0                                                                \
 419.141 +    : FT_GlyphLoader_CheckPoints( (_loader), (_points), (_contours) ) )
 419.142 +
 419.143 +
 419.144 +  /* check that there is enough space to add `n_subs' sub-glyphs to */
 419.145 +  /* a glyph loader                                                 */
 419.146 +  FT_BASE( FT_Error )
 419.147 +  FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader  loader,
 419.148 +                                 FT_UInt         n_subs );
 419.149 +
 419.150 +  /* prepare a glyph loader, i.e. empty the current glyph */
 419.151 +  FT_BASE( void )
 419.152 +  FT_GlyphLoader_Prepare( FT_GlyphLoader  loader );
 419.153 +
 419.154 +  /* add the current glyph to the base glyph */
 419.155 +  FT_BASE( void )
 419.156 +  FT_GlyphLoader_Add( FT_GlyphLoader  loader );
 419.157 +
 419.158 +  /* copy points from one glyph loader to another */
 419.159 +  FT_BASE( FT_Error )
 419.160 +  FT_GlyphLoader_CopyPoints( FT_GlyphLoader  target,
 419.161 +                             FT_GlyphLoader  source );
 419.162 +
 419.163 + /* */
 419.164 +
 419.165 +
 419.166 +FT_END_HEADER
 419.167 +
 419.168 +#endif /* __FTGLOADR_H__ */
 419.169 +
 419.170 +
 419.171 +/* END */
   420.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   420.2 +++ b/libs/ft2static/freetype/internal/ftmemory.h	Sat Feb 01 19:58:19 2014 +0200
   420.3 @@ -0,0 +1,380 @@
   420.4 +/***************************************************************************/
   420.5 +/*                                                                         */
   420.6 +/*  ftmemory.h                                                             */
   420.7 +/*                                                                         */
   420.8 +/*    The FreeType memory management macros (specification).               */
   420.9 +/*                                                                         */
  420.10 +/*  Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2010 by             */
  420.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
  420.12 +/*                                                                         */
  420.13 +/*  This file is part of the FreeType project, and may only be used,       */
  420.14 +/*  modified, and distributed under the terms of the FreeType project      */
  420.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  420.16 +/*  this file you indicate that you have read the license and              */
  420.17 +/*  understand and accept it fully.                                        */
  420.18 +/*                                                                         */
  420.19 +/***************************************************************************/
  420.20 +
  420.21 +
  420.22 +#ifndef __FTMEMORY_H__
  420.23 +#define __FTMEMORY_H__
  420.24 +
  420.25 +
  420.26 +#include <ft2build.h>
  420.27 +#include FT_CONFIG_CONFIG_H
  420.28 +#include FT_TYPES_H
  420.29 +
  420.30 +
  420.31 +FT_BEGIN_HEADER
  420.32 +
  420.33 +
  420.34 +  /*************************************************************************/
  420.35 +  /*                                                                       */
  420.36 +  /* <Macro>                                                               */
  420.37 +  /*    FT_SET_ERROR                                                       */
  420.38 +  /*                                                                       */
  420.39 +  /* <Description>                                                         */
  420.40 +  /*    This macro is used to set an implicit `error' variable to a given  */
  420.41 +  /*    expression's value (usually a function call), and convert it to a  */
  420.42 +  /*    boolean which is set whenever the value is != 0.                   */
  420.43 +  /*                                                                       */
  420.44 +#undef  FT_SET_ERROR
  420.45 +#define FT_SET_ERROR( expression ) \
  420.46 +          ( ( error = (expression) ) != 0 )
  420.47 +
  420.48 +
  420.49 +
  420.50 +  /*************************************************************************/
  420.51 +  /*************************************************************************/
  420.52 +  /*************************************************************************/
  420.53 +  /****                                                                 ****/
  420.54 +  /****                                                                 ****/
  420.55 +  /****                           M E M O R Y                           ****/
  420.56 +  /****                                                                 ****/
  420.57 +  /****                                                                 ****/
  420.58 +  /*************************************************************************/
  420.59 +  /*************************************************************************/
  420.60 +  /*************************************************************************/
  420.61 +
  420.62 +
  420.63 +  /*
  420.64 +   *  C++ refuses to handle statements like p = (void*)anything, with `p' a
  420.65 +   *  typed pointer.  Since we don't have a `typeof' operator in standard
  420.66 +   *  C++, we have to use a template to emulate it.
  420.67 +   */
  420.68 +
  420.69 +#ifdef __cplusplus
  420.70 +
  420.71 +  extern "C++"
  420.72 +  template <typename T> inline T*
  420.73 +  cplusplus_typeof(        T*,
  420.74 +                    void  *v )
  420.75 +  {
  420.76 +    return static_cast <T*> ( v );
  420.77 +  }
  420.78 +
  420.79 +#define FT_ASSIGNP( p, val )  (p) = cplusplus_typeof( (p), (val) )
  420.80 +
  420.81 +#else
  420.82 +
  420.83 +#define FT_ASSIGNP( p, val )  (p) = (val)
  420.84 +
  420.85 +#endif
  420.86 +
  420.87 +
  420.88 +
  420.89 +#ifdef FT_DEBUG_MEMORY
  420.90 +
  420.91 +  FT_BASE( const char* )  _ft_debug_file;
  420.92 +  FT_BASE( long )         _ft_debug_lineno;
  420.93 +
  420.94 +#define FT_DEBUG_INNER( exp )  ( _ft_debug_file   = __FILE__, \
  420.95 +                                 _ft_debug_lineno = __LINE__, \
  420.96 +                                 (exp) )
  420.97 +
  420.98 +#define FT_ASSIGNP_INNER( p, exp )  ( _ft_debug_file   = __FILE__, \
  420.99 +                                      _ft_debug_lineno = __LINE__, \
 420.100 +                                      FT_ASSIGNP( p, exp ) )
 420.101 +
 420.102 +#else /* !FT_DEBUG_MEMORY */
 420.103 +
 420.104 +#define FT_DEBUG_INNER( exp )       (exp)
 420.105 +#define FT_ASSIGNP_INNER( p, exp )  FT_ASSIGNP( p, exp )
 420.106 +
 420.107 +#endif /* !FT_DEBUG_MEMORY */
 420.108 +
 420.109 +
 420.110 +  /*
 420.111 +   *  The allocation functions return a pointer, and the error code
 420.112 +   *  is written to through the `p_error' parameter.  See below for
 420.113 +   *  for documentation.
 420.114 +   */
 420.115 +
 420.116 +  FT_BASE( FT_Pointer )
 420.117 +  ft_mem_alloc( FT_Memory  memory,
 420.118 +                FT_Long    size,
 420.119 +                FT_Error  *p_error );
 420.120 +
 420.121 +  FT_BASE( FT_Pointer )
 420.122 +  ft_mem_qalloc( FT_Memory  memory,
 420.123 +                 FT_Long    size,
 420.124 +                 FT_Error  *p_error );
 420.125 +
 420.126 +  FT_BASE( FT_Pointer )
 420.127 +  ft_mem_realloc( FT_Memory  memory,
 420.128 +                  FT_Long    item_size,
 420.129 +                  FT_Long    cur_count,
 420.130 +                  FT_Long    new_count,
 420.131 +                  void*      block,
 420.132 +                  FT_Error  *p_error );
 420.133 +
 420.134 +  FT_BASE( FT_Pointer )
 420.135 +  ft_mem_qrealloc( FT_Memory  memory,
 420.136 +                   FT_Long    item_size,
 420.137 +                   FT_Long    cur_count,
 420.138 +                   FT_Long    new_count,
 420.139 +                   void*      block,
 420.140 +                   FT_Error  *p_error );
 420.141 +
 420.142 +  FT_BASE( void )
 420.143 +  ft_mem_free( FT_Memory    memory,
 420.144 +               const void*  P );
 420.145 +
 420.146 +
 420.147 +#define FT_MEM_ALLOC( ptr, size )                                         \
 420.148 +          FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, (size), &error ) )
 420.149 +
 420.150 +#define FT_MEM_FREE( ptr )                \
 420.151 +          FT_BEGIN_STMNT                  \
 420.152 +            ft_mem_free( memory, (ptr) ); \
 420.153 +            (ptr) = NULL;                 \
 420.154 +          FT_END_STMNT
 420.155 +
 420.156 +#define FT_MEM_NEW( ptr )                        \
 420.157 +          FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) )
 420.158 +
 420.159 +#define FT_MEM_REALLOC( ptr, cursz, newsz )                        \
 420.160 +          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, 1,        \
 420.161 +                                                 (cursz), (newsz), \
 420.162 +                                                 (ptr), &error ) )
 420.163 +
 420.164 +#define FT_MEM_QALLOC( ptr, size )                                         \
 420.165 +          FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, (size), &error ) )
 420.166 +
 420.167 +#define FT_MEM_QNEW( ptr )                        \
 420.168 +          FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) )
 420.169 +
 420.170 +#define FT_MEM_QREALLOC( ptr, cursz, newsz )                         \
 420.171 +          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, 1,        \
 420.172 +                                                  (cursz), (newsz), \
 420.173 +                                                  (ptr), &error ) )
 420.174 +
 420.175 +#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz )                             \
 420.176 +          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \
 420.177 +                                                  (cursz), (newsz),          \
 420.178 +                                                  (ptr), &error ) )
 420.179 +
 420.180 +#define FT_MEM_ALLOC_MULT( ptr, count, item_size )                    \
 420.181 +          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (item_size), \
 420.182 +                                                 0, (count),          \
 420.183 +                                                 NULL, &error ) )
 420.184 +
 420.185 +#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz )            \
 420.186 +          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (itmsz),    \
 420.187 +                                                 (oldcnt), (newcnt), \
 420.188 +                                                 (ptr), &error ) )
 420.189 +
 420.190 +#define FT_MEM_QALLOC_MULT( ptr, count, item_size )                    \
 420.191 +          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (item_size), \
 420.192 +                                                  0, (count),          \
 420.193 +                                                  NULL, &error ) )
 420.194 +
 420.195 +#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz)             \
 420.196 +          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (itmsz),    \
 420.197 +                                                  (oldcnt), (newcnt), \
 420.198 +                                                  (ptr), &error ) )
 420.199 +
 420.200 +
 420.201 +#define FT_MEM_SET_ERROR( cond )  ( (cond), error != 0 )
 420.202 +
 420.203 +
 420.204 +#define FT_MEM_SET( dest, byte, count )     ft_memset( dest, byte, count )
 420.205 +
 420.206 +#define FT_MEM_COPY( dest, source, count )  ft_memcpy( dest, source, count )
 420.207 +
 420.208 +#define FT_MEM_MOVE( dest, source, count )  ft_memmove( dest, source, count )
 420.209 +
 420.210 +
 420.211 +#define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )
 420.212 +
 420.213 +#define FT_ZERO( p )                FT_MEM_ZERO( p, sizeof ( *(p) ) )
 420.214 +
 420.215 +
 420.216 +#define FT_ARRAY_ZERO( dest, count )                        \
 420.217 +          FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) )
 420.218 +
 420.219 +#define FT_ARRAY_COPY( dest, source, count )                        \
 420.220 +          FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) )
 420.221 +
 420.222 +#define FT_ARRAY_MOVE( dest, source, count )                        \
 420.223 +          FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) )
 420.224 +
 420.225 +
 420.226 +  /*
 420.227 +   *  Return the maximum number of addressable elements in an array.
 420.228 +   *  We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid
 420.229 +   *  any problems.
 420.230 +   */
 420.231 +#define FT_ARRAY_MAX( ptr )           ( FT_INT_MAX / sizeof ( *(ptr) ) )
 420.232 +
 420.233 +#define FT_ARRAY_CHECK( ptr, count )  ( (count) <= FT_ARRAY_MAX( ptr ) )
 420.234 +
 420.235 +
 420.236 +  /*************************************************************************/
 420.237 +  /*                                                                       */
 420.238 +  /* The following functions macros expect that their pointer argument is  */
 420.239 +  /* _typed_ in order to automatically compute array element sizes.        */
 420.240 +  /*                                                                       */
 420.241 +
 420.242 +#define FT_MEM_NEW_ARRAY( ptr, count )                                      \
 420.243 +          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \
 420.244 +                                                 0, (count),                \
 420.245 +                                                 NULL, &error ) )
 420.246 +
 420.247 +#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz )                             \
 420.248 +          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \
 420.249 +                                                 (cursz), (newsz),          \
 420.250 +                                                 (ptr), &error ) )
 420.251 +
 420.252 +#define FT_MEM_QNEW_ARRAY( ptr, count )                                      \
 420.253 +          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \
 420.254 +                                                  0, (count),                \
 420.255 +                                                  NULL, &error ) )
 420.256 +
 420.257 +#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz )                             \
 420.258 +          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \
 420.259 +                                                  (cursz), (newsz),          \
 420.260 +                                                  (ptr), &error ) )
 420.261 +
 420.262 +
 420.263 +#define FT_ALLOC( ptr, size )                           \
 420.264 +          FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) )
 420.265 +
 420.266 +#define FT_REALLOC( ptr, cursz, newsz )                           \
 420.267 +          FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) )
 420.268 +
 420.269 +#define FT_ALLOC_MULT( ptr, count, item_size )                           \
 420.270 +          FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) )
 420.271 +
 420.272 +#define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz )              \
 420.273 +          FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt,      \
 420.274 +                                                 newcnt, itmsz ) )
 420.275 +
 420.276 +#define FT_QALLOC( ptr, size )                           \
 420.277 +          FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) )
 420.278 +
 420.279 +#define FT_QREALLOC( ptr, cursz, newsz )                           \
 420.280 +          FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) )
 420.281 +
 420.282 +#define FT_QALLOC_MULT( ptr, count, item_size )                           \
 420.283 +          FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) )
 420.284 +
 420.285 +#define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz )              \
 420.286 +          FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt,      \
 420.287 +                                                  newcnt, itmsz ) )
 420.288 +
 420.289 +#define FT_FREE( ptr )  FT_MEM_FREE( ptr )
 420.290 +
 420.291 +#define FT_NEW( ptr )  FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) )
 420.292 +
 420.293 +#define FT_NEW_ARRAY( ptr, count )                           \
 420.294 +          FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) )
 420.295 +
 420.296 +#define FT_RENEW_ARRAY( ptr, curcnt, newcnt )                           \
 420.297 +          FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )
 420.298 +
 420.299 +#define FT_QNEW( ptr )                           \
 420.300 +          FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) )
 420.301 +
 420.302 +#define FT_QNEW_ARRAY( ptr, count )                          \
 420.303 +          FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) )
 420.304 +
 420.305 +#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt )                          \
 420.306 +          FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )
 420.307 +
 420.308 +
 420.309 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 420.310 +
 420.311 +  FT_BASE( FT_Error )
 420.312 +  FT_Alloc( FT_Memory  memory,
 420.313 +            FT_Long    size,
 420.314 +            void*     *P );
 420.315 +
 420.316 +  FT_BASE( FT_Error )
 420.317 +  FT_QAlloc( FT_Memory  memory,
 420.318 +             FT_Long    size,
 420.319 +             void*     *p );
 420.320 +
 420.321 +  FT_BASE( FT_Error )
 420.322 +  FT_Realloc( FT_Memory  memory,
 420.323 +              FT_Long    current,
 420.324 +              FT_Long    size,
 420.325 +              void*     *P );
 420.326 +
 420.327 +  FT_BASE( FT_Error )
 420.328 +  FT_QRealloc( FT_Memory  memory,
 420.329 +               FT_Long    current,
 420.330 +               FT_Long    size,
 420.331 +               void*     *p );
 420.332 +
 420.333 +  FT_BASE( void )
 420.334 +  FT_Free( FT_Memory  memory,
 420.335 +           void*     *P );
 420.336 +
 420.337 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
 420.338 +
 420.339 +
 420.340 +  FT_BASE( FT_Pointer )
 420.341 +  ft_mem_strdup( FT_Memory    memory,
 420.342 +                 const char*  str,
 420.343 +                 FT_Error    *p_error );
 420.344 +
 420.345 +  FT_BASE( FT_Pointer )
 420.346 +  ft_mem_dup( FT_Memory    memory,
 420.347 +              const void*  address,
 420.348 +              FT_ULong     size,
 420.349 +              FT_Error    *p_error );
 420.350 +
 420.351 +#define FT_MEM_STRDUP( dst, str )                                            \
 420.352 +          (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error )
 420.353 +
 420.354 +#define FT_STRDUP( dst, str )                           \
 420.355 +          FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) )
 420.356 +
 420.357 +#define FT_MEM_DUP( dst, address, size )                                    \
 420.358 +          (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error )
 420.359 +
 420.360 +#define FT_DUP( dst, address, size )                           \
 420.361 +          FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) )
 420.362 +
 420.363 +
 420.364 +  /* Return >= 1 if a truncation occurs.            */
 420.365 +  /* Return 0 if the source string fits the buffer. */
 420.366 +  /* This is *not* the same as strlcpy().           */
 420.367 +  FT_BASE( FT_Int )
 420.368 +  ft_mem_strcpyn( char*        dst,
 420.369 +                  const char*  src,
 420.370 +                  FT_ULong     size );
 420.371 +
 420.372 +#define FT_STRCPYN( dst, src, size )                                         \
 420.373 +          ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) )
 420.374 +
 420.375 + /* */
 420.376 +
 420.377 +
 420.378 +FT_END_HEADER
 420.379 +
 420.380 +#endif /* __FTMEMORY_H__ */
 420.381 +
 420.382 +
 420.383 +/* END */
   421.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   421.2 +++ b/libs/ft2static/freetype/internal/ftobjs.h	Sat Feb 01 19:58:19 2014 +0200
   421.3 @@ -0,0 +1,1428 @@
   421.4 +/***************************************************************************/
   421.5 +/*                                                                         */
   421.6 +/*  ftobjs.h                                                               */
   421.7 +/*                                                                         */
   421.8 +/*    The FreeType private base classes (specification).                   */
   421.9 +/*                                                                         */
  421.10 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010 by       */
  421.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  421.12 +/*                                                                         */
  421.13 +/*  This file is part of the FreeType project, and may only be used,       */
  421.14 +/*  modified, and distributed under the terms of the FreeType project      */
  421.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  421.16 +/*  this file you indicate that you have read the license and              */
  421.17 +/*  understand and accept it fully.                                        */
  421.18 +/*                                                                         */
  421.19 +/***************************************************************************/
  421.20 +
  421.21 +
  421.22 +  /*************************************************************************/
  421.23 +  /*                                                                       */
  421.24 +  /*  This file contains the definition of all internal FreeType classes.  */
  421.25 +  /*                                                                       */
  421.26 +  /*************************************************************************/
  421.27 +
  421.28 +
  421.29 +#ifndef __FTOBJS_H__
  421.30 +#define __FTOBJS_H__
  421.31 +
  421.32 +#include <ft2build.h>
  421.33 +#include FT_RENDER_H
  421.34 +#include FT_SIZES_H
  421.35 +#include FT_LCD_FILTER_H
  421.36 +#include FT_INTERNAL_MEMORY_H
  421.37 +#include FT_INTERNAL_GLYPH_LOADER_H
  421.38 +#include FT_INTERNAL_DRIVER_H
  421.39 +#include FT_INTERNAL_AUTOHINT_H
  421.40 +#include FT_INTERNAL_SERVICE_H
  421.41 +#include FT_INTERNAL_PIC_H
  421.42 +
  421.43 +#ifdef FT_CONFIG_OPTION_INCREMENTAL
  421.44 +#include FT_INCREMENTAL_H
  421.45 +#endif
  421.46 +
  421.47 +
  421.48 +FT_BEGIN_HEADER
  421.49 +
  421.50 +
  421.51 +  /*************************************************************************/
  421.52 +  /*                                                                       */
  421.53 +  /* Some generic definitions.                                             */
  421.54 +  /*                                                                       */
  421.55 +#ifndef TRUE
  421.56 +#define TRUE  1
  421.57 +#endif
  421.58 +
  421.59 +#ifndef FALSE
  421.60 +#define FALSE  0
  421.61 +#endif
  421.62 +
  421.63 +#ifndef NULL
  421.64 +#define NULL  (void*)0
  421.65 +#endif
  421.66 +
  421.67 +
  421.68 +  /*************************************************************************/
  421.69 +  /*                                                                       */
  421.70 +  /* The min and max functions missing in C.  As usual, be careful not to  */
  421.71 +  /* write things like FT_MIN( a++, b++ ) to avoid side effects.           */
  421.72 +  /*                                                                       */
  421.73 +#define FT_MIN( a, b )  ( (a) < (b) ? (a) : (b) )
  421.74 +#define FT_MAX( a, b )  ( (a) > (b) ? (a) : (b) )
  421.75 +
  421.76 +#define FT_ABS( a )     ( (a) < 0 ? -(a) : (a) )
  421.77 +
  421.78 +
  421.79 +#define FT_PAD_FLOOR( x, n )  ( (x) & ~((n)-1) )
  421.80 +#define FT_PAD_ROUND( x, n )  FT_PAD_FLOOR( (x) + ((n)/2), n )
  421.81 +#define FT_PAD_CEIL( x, n )   FT_PAD_FLOOR( (x) + ((n)-1), n )
  421.82 +
  421.83 +#define FT_PIX_FLOOR( x )     ( (x) & ~63 )
  421.84 +#define FT_PIX_ROUND( x )     FT_PIX_FLOOR( (x) + 32 )
  421.85 +#define FT_PIX_CEIL( x )      FT_PIX_FLOOR( (x) + 63 )
  421.86 +
  421.87 +
  421.88 +  /*
  421.89 +   *  Return the highest power of 2 that is <= value; this correspond to
  421.90 +   *  the highest bit in a given 32-bit value.
  421.91 +   */
  421.92 +  FT_BASE( FT_UInt32 )
  421.93 +  ft_highpow2( FT_UInt32  value );
  421.94 +
  421.95 +
  421.96 +  /*
  421.97 +   *  character classification functions -- since these are used to parse
  421.98 +   *  font files, we must not use those in <ctypes.h> which are
  421.99 +   *  locale-dependent
 421.100 +   */
 421.101 +#define  ft_isdigit( x )   ( ( (unsigned)(x) - '0' ) < 10U )
 421.102 +
 421.103 +#define  ft_isxdigit( x )  ( ( (unsigned)(x) - '0' ) < 10U || \
 421.104 +                             ( (unsigned)(x) - 'a' ) < 6U  || \
 421.105 +                             ( (unsigned)(x) - 'A' ) < 6U  )
 421.106 +
 421.107 +  /* the next two macros assume ASCII representation */
 421.108 +#define  ft_isupper( x )  ( ( (unsigned)(x) - 'A' ) < 26U )
 421.109 +#define  ft_islower( x )  ( ( (unsigned)(x) - 'a' ) < 26U )
 421.110 +
 421.111 +#define  ft_isalpha( x )  ( ft_isupper( x ) || ft_islower( x ) )
 421.112 +#define  ft_isalnum( x )  ( ft_isdigit( x ) || ft_isalpha( x ) )
 421.113 +
 421.114 +
 421.115 +  /*************************************************************************/
 421.116 +  /*************************************************************************/
 421.117 +  /*************************************************************************/
 421.118 +  /****                                                                 ****/
 421.119 +  /****                                                                 ****/
 421.120 +  /****                       C H A R M A P S                           ****/
 421.121 +  /****                                                                 ****/
 421.122 +  /****                                                                 ****/
 421.123 +  /*************************************************************************/
 421.124 +  /*************************************************************************/
 421.125 +  /*************************************************************************/
 421.126 +
 421.127 +  /* handle to internal charmap object */
 421.128 +  typedef struct FT_CMapRec_*              FT_CMap;
 421.129 +
 421.130 +  /* handle to charmap class structure */
 421.131 +  typedef const struct FT_CMap_ClassRec_*  FT_CMap_Class;
 421.132 +
 421.133 +  /* internal charmap object structure */
 421.134 +  typedef struct  FT_CMapRec_
 421.135 +  {
 421.136 +    FT_CharMapRec  charmap;
 421.137 +    FT_CMap_Class  clazz;
 421.138 +
 421.139 +  } FT_CMapRec;
 421.140 +
 421.141 +  /* typecase any pointer to a charmap handle */
 421.142 +#define FT_CMAP( x )              ((FT_CMap)( x ))
 421.143 +
 421.144 +  /* obvious macros */
 421.145 +#define FT_CMAP_PLATFORM_ID( x )  FT_CMAP( x )->charmap.platform_id
 421.146 +#define FT_CMAP_ENCODING_ID( x )  FT_CMAP( x )->charmap.encoding_id
 421.147 +#define FT_CMAP_ENCODING( x )     FT_CMAP( x )->charmap.encoding
 421.148 +#define FT_CMAP_FACE( x )         FT_CMAP( x )->charmap.face
 421.149 +
 421.150 +
 421.151 +  /* class method definitions */
 421.152 +  typedef FT_Error
 421.153 +  (*FT_CMap_InitFunc)( FT_CMap     cmap,
 421.154 +                       FT_Pointer  init_data );
 421.155 +
 421.156 +  typedef void
 421.157 +  (*FT_CMap_DoneFunc)( FT_CMap  cmap );
 421.158 +
 421.159 +  typedef FT_UInt
 421.160 +  (*FT_CMap_CharIndexFunc)( FT_CMap    cmap,
 421.161 +                            FT_UInt32  char_code );
 421.162 +
 421.163 +  typedef FT_UInt
 421.164 +  (*FT_CMap_CharNextFunc)( FT_CMap     cmap,
 421.165 +                           FT_UInt32  *achar_code );
 421.166 +
 421.167 +  typedef FT_UInt
 421.168 +  (*FT_CMap_CharVarIndexFunc)( FT_CMap    cmap,
 421.169 +                               FT_CMap    unicode_cmap,
 421.170 +                               FT_UInt32  char_code,
 421.171 +                               FT_UInt32  variant_selector );
 421.172 +
 421.173 +  typedef FT_Bool
 421.174 +  (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap    cmap,
 421.175 +                                   FT_UInt32  char_code,
 421.176 +                                   FT_UInt32  variant_selector );
 421.177 +
 421.178 +  typedef FT_UInt32 *
 421.179 +  (*FT_CMap_VariantListFunc)( FT_CMap    cmap,
 421.180 +                              FT_Memory  mem );
 421.181 +
 421.182 +  typedef FT_UInt32 *
 421.183 +  (*FT_CMap_CharVariantListFunc)( FT_CMap    cmap,
 421.184 +                                  FT_Memory  mem,
 421.185 +                                  FT_UInt32  char_code );
 421.186 +
 421.187 +  typedef FT_UInt32 *
 421.188 +  (*FT_CMap_VariantCharListFunc)( FT_CMap    cmap,
 421.189 +                                  FT_Memory  mem,
 421.190 +                                  FT_UInt32  variant_selector );
 421.191 +
 421.192 +
 421.193 +  typedef struct  FT_CMap_ClassRec_
 421.194 +  {
 421.195 +    FT_ULong               size;
 421.196 +    FT_CMap_InitFunc       init;
 421.197 +    FT_CMap_DoneFunc       done;
 421.198 +    FT_CMap_CharIndexFunc  char_index;
 421.199 +    FT_CMap_CharNextFunc   char_next;
 421.200 +
 421.201 +    /* Subsequent entries are special ones for format 14 -- the variant */
 421.202 +    /* selector subtable which behaves like no other                    */
 421.203 +
 421.204 +    FT_CMap_CharVarIndexFunc      char_var_index;
 421.205 +    FT_CMap_CharVarIsDefaultFunc  char_var_default;
 421.206 +    FT_CMap_VariantListFunc       variant_list;
 421.207 +    FT_CMap_CharVariantListFunc   charvariant_list;
 421.208 +    FT_CMap_VariantCharListFunc   variantchar_list;
 421.209 +
 421.210 +  } FT_CMap_ClassRec;
 421.211 +
 421.212 +#ifndef FT_CONFIG_OPTION_PIC
 421.213 +
 421.214 +#define FT_DECLARE_CMAP_CLASS(class_) \
 421.215 +    FT_CALLBACK_TABLE const FT_CMap_ClassRec class_;
 421.216 +
 421.217 +#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_,       \
 421.218 +        char_next_, char_var_index_, char_var_default_, variant_list_,       \
 421.219 +        charvariant_list_, variantchar_list_)                                \
 421.220 +  FT_CALLBACK_TABLE_DEF                                                      \
 421.221 +  const FT_CMap_ClassRec class_ =                                            \
 421.222 +  {                                                                          \
 421.223 +    size_, init_, done_, char_index_, char_next_, char_var_index_,           \
 421.224 +    char_var_default_, variant_list_, charvariant_list_, variantchar_list_   \
 421.225 +  };
 421.226 +#else /* FT_CONFIG_OPTION_PIC */
 421.227 +
 421.228 +#define FT_DECLARE_CMAP_CLASS(class_) \
 421.229 +    void FT_Init_Class_##class_( FT_Library library, FT_CMap_ClassRec*  clazz);
 421.230 +
 421.231 +#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_,       \
 421.232 +        char_next_, char_var_index_, char_var_default_, variant_list_,       \
 421.233 +        charvariant_list_, variantchar_list_)                                \
 421.234 +  void                                                                       \
 421.235 +  FT_Init_Class_##class_( FT_Library library,                                \
 421.236 +                          FT_CMap_ClassRec*  clazz)                          \
 421.237 +  {                                                                          \
 421.238 +    FT_UNUSED(library);                                                      \
 421.239 +    clazz->size = size_;                                                     \
 421.240 +    clazz->init = init_;                                                     \
 421.241 +    clazz->done = done_;                                                     \
 421.242 +    clazz->char_index = char_index_;                                         \
 421.243 +    clazz->char_next = char_next_;                                           \
 421.244 +    clazz->char_var_index = char_var_index_;                                 \
 421.245 +    clazz->char_var_default = char_var_default_;                             \
 421.246 +    clazz->variant_list = variant_list_;                                     \
 421.247 +    clazz->charvariant_list = charvariant_list_;                             \
 421.248 +    clazz->variantchar_list = variantchar_list_;                             \
 421.249 +  } 
 421.250 +#endif /* FT_CONFIG_OPTION_PIC */
 421.251 +
 421.252 +  /* create a new charmap and add it to charmap->face */
 421.253 +  FT_BASE( FT_Error )
 421.254 +  FT_CMap_New( FT_CMap_Class  clazz,
 421.255 +               FT_Pointer     init_data,
 421.256 +               FT_CharMap     charmap,
 421.257 +               FT_CMap       *acmap );
 421.258 +
 421.259 +  /* destroy a charmap and remove it from face's list */
 421.260 +  FT_BASE( void )
 421.261 +  FT_CMap_Done( FT_CMap  cmap );
 421.262 +
 421.263 +
 421.264 +  /*************************************************************************/
 421.265 +  /*                                                                       */
 421.266 +  /* <Struct>                                                              */
 421.267 +  /*    FT_Face_InternalRec                                                */
 421.268 +  /*                                                                       */
 421.269 +  /* <Description>                                                         */
 421.270 +  /*    This structure contains the internal fields of each FT_Face        */
 421.271 +  /*    object.  These fields may change between different releases of     */
 421.272 +  /*    FreeType.                                                          */
 421.273 +  /*                                                                       */
 421.274 +  /* <Fields>                                                              */
 421.275 +  /*    max_points ::                                                      */
 421.276 +  /*      The maximal number of points used to store the vectorial outline */
 421.277 +  /*      of any glyph in this face.  If this value cannot be known in     */
 421.278 +  /*      advance, or if the face isn't scalable, this should be set to 0. */
 421.279 +  /*      Only relevant for scalable formats.                              */
 421.280 +  /*                                                                       */
 421.281 +  /*    max_contours ::                                                    */
 421.282 +  /*      The maximal number of contours used to store the vectorial       */
 421.283 +  /*      outline of any glyph in this face.  If this value cannot be      */
 421.284 +  /*      known in advance, or if the face isn't scalable, this should be  */
 421.285 +  /*      set to 0.  Only relevant for scalable formats.                   */
 421.286 +  /*                                                                       */
 421.287 +  /*    transform_matrix ::                                                */
 421.288 +  /*      A 2x2 matrix of 16.16 coefficients used to transform glyph       */
 421.289 +  /*      outlines after they are loaded from the font.  Only used by the  */
 421.290 +  /*      convenience functions.                                           */
 421.291 +  /*                                                                       */
 421.292 +  /*    transform_delta ::                                                 */
 421.293 +  /*      A translation vector used to transform glyph outlines after they */
 421.294 +  /*      are loaded from the font.  Only used by the convenience          */
 421.295 +  /*      functions.                                                       */
 421.296 +  /*                                                                       */
 421.297 +  /*    transform_flags ::                                                 */
 421.298 +  /*      Some flags used to classify the transform.  Only used by the     */
 421.299 +  /*      convenience functions.                                           */
 421.300 +  /*                                                                       */
 421.301 +  /*    services ::                                                        */
 421.302 +  /*      A cache for frequently used services.  It should be only         */
 421.303 +  /*      accessed with the macro `FT_FACE_LOOKUP_SERVICE'.                */
 421.304 +  /*                                                                       */
 421.305 +  /*    incremental_interface ::                                           */
 421.306 +  /*      If non-null, the interface through which glyph data and metrics  */
 421.307 +  /*      are loaded incrementally for faces that do not provide all of    */
 421.308 +  /*      this data when first opened.  This field exists only if          */
 421.309 +  /*      @FT_CONFIG_OPTION_INCREMENTAL is defined.                        */
 421.310 +  /*                                                                       */
 421.311 +  /*    ignore_unpatented_hinter ::                                        */
 421.312 +  /*      This boolean flag instructs the glyph loader to ignore the       */
 421.313 +  /*      native font hinter, if one is found.  This is exclusively used   */
 421.314 +  /*      in the case when the unpatented hinter is compiled within the    */
 421.315 +  /*      library.                                                         */
 421.316 +  /*                                                                       */
 421.317 +  /*    refcount ::                                                        */
 421.318 +  /*      A counter initialized to~1 at the time an @FT_Face structure is  */
 421.319 +  /*      created.  @FT_Reference_Face increments this counter, and        */
 421.320 +  /*      @FT_Done_Face only destroys a face if the counter is~1,          */
 421.321 +  /*      otherwise it simply decrements it.                               */
 421.322 +  /*                                                                       */
 421.323 +  typedef struct  FT_Face_InternalRec_
 421.324 +  {
 421.325 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 421.326 +    FT_UShort           reserved1;
 421.327 +    FT_Short            reserved2;
 421.328 +#endif
 421.329 +    FT_Matrix           transform_matrix;
 421.330 +    FT_Vector           transform_delta;
 421.331 +    FT_Int              transform_flags;
 421.332 +
 421.333 +    FT_ServiceCacheRec  services;
 421.334 +
 421.335 +#ifdef FT_CONFIG_OPTION_INCREMENTAL
 421.336 +    FT_Incremental_InterfaceRec*  incremental_interface;
 421.337 +#endif
 421.338 +
 421.339 +    FT_Bool             ignore_unpatented_hinter;
 421.340 +    FT_UInt             refcount;
 421.341 +
 421.342 +  } FT_Face_InternalRec;
 421.343 +
 421.344 +
 421.345 +  /*************************************************************************/
 421.346 +  /*                                                                       */
 421.347 +  /* <Struct>                                                              */
 421.348 +  /*    FT_Slot_InternalRec                                                */
 421.349 +  /*                                                                       */
 421.350 +  /* <Description>                                                         */
 421.351 +  /*    This structure contains the internal fields of each FT_GlyphSlot   */
 421.352 +  /*    object.  These fields may change between different releases of     */
 421.353 +  /*    FreeType.                                                          */
 421.354 +  /*                                                                       */
 421.355 +  /* <Fields>                                                              */
 421.356 +  /*    loader            :: The glyph loader object used to load outlines */
 421.357 +  /*                         into the glyph slot.                          */
 421.358 +  /*                                                                       */
 421.359 +  /*    flags             :: Possible values are zero or                   */
 421.360 +  /*                         FT_GLYPH_OWN_BITMAP.  The latter indicates    */
 421.361 +  /*                         that the FT_GlyphSlot structure owns the      */
 421.362 +  /*                         bitmap buffer.                                */
 421.363 +  /*                                                                       */
 421.364 +  /*    glyph_transformed :: Boolean.  Set to TRUE when the loaded glyph   */
 421.365 +  /*                         must be transformed through a specific        */
 421.366 +  /*                         font transformation.  This is _not_ the same  */
 421.367 +  /*                         as the face transform set through             */
 421.368 +  /*                         FT_Set_Transform().                           */
 421.369 +  /*                                                                       */
 421.370 +  /*    glyph_matrix      :: The 2x2 matrix corresponding to the glyph     */
 421.371 +  /*                         transformation, if necessary.                 */
 421.372 +  /*                                                                       */
 421.373 +  /*    glyph_delta       :: The 2d translation vector corresponding to    */
 421.374 +  /*                         the glyph transformation, if necessary.       */
 421.375 +  /*                                                                       */
 421.376 +  /*    glyph_hints       :: Format-specific glyph hints management.       */
 421.377 +  /*                                                                       */
 421.378 +
 421.379 +#define FT_GLYPH_OWN_BITMAP  0x1
 421.380 +
 421.381 +  typedef struct  FT_Slot_InternalRec_
 421.382 +  {
 421.383 +    FT_GlyphLoader  loader;
 421.384 +    FT_UInt         flags;
 421.385 +    FT_Bool         glyph_transformed;
 421.386 +    FT_Matrix       glyph_matrix;
 421.387 +    FT_Vector       glyph_delta;
 421.388 +    void*           glyph_hints;
 421.389 +
 421.390 +  } FT_GlyphSlot_InternalRec;
 421.391 +
 421.392 +
 421.393 +#if 0
 421.394 +
 421.395 +  /*************************************************************************/
 421.396 +  /*                                                                       */
 421.397 +  /* <Struct>                                                              */
 421.398 +  /*    FT_Size_InternalRec                                                */
 421.399 +  /*                                                                       */
 421.400 +  /* <Description>                                                         */
 421.401 +  /*    This structure contains the internal fields of each FT_Size        */
 421.402 +  /*    object.  Currently, it's empty.                                    */
 421.403 +  /*                                                                       */
 421.404 +  /*************************************************************************/
 421.405 +
 421.406 +  typedef struct  FT_Size_InternalRec_
 421.407 +  {
 421.408 +    /* empty */
 421.409 +
 421.410 +  } FT_Size_InternalRec;
 421.411 +
 421.412 +#endif
 421.413 +
 421.414 +
 421.415 +  /*************************************************************************/
 421.416 +  /*************************************************************************/
 421.417 +  /****                                                                 ****/
 421.418 +  /****                                                                 ****/
 421.419 +  /****                         M O D U L E S                           ****/
 421.420 +  /****                                                                 ****/
 421.421 +  /****                                                                 ****/
 421.422 +  /*************************************************************************/
 421.423 +  /*************************************************************************/
 421.424 +  /*************************************************************************/
 421.425 +
 421.426 +
 421.427 +  /*************************************************************************/
 421.428 +  /*                                                                       */
 421.429 +  /* <Struct>                                                              */
 421.430 +  /*    FT_ModuleRec                                                       */
 421.431 +  /*                                                                       */
 421.432 +  /* <Description>                                                         */
 421.433 +  /*    A module object instance.                                          */
 421.434 +  /*                                                                       */
 421.435 +  /* <Fields>                                                              */
 421.436 +  /*    clazz   :: A pointer to the module's class.                        */
 421.437 +  /*                                                                       */
 421.438 +  /*    library :: A handle to the parent library object.                  */
 421.439 +  /*                                                                       */
 421.440 +  /*    memory  :: A handle to the memory manager.                         */
 421.441 +  /*                                                                       */
 421.442 +  /*    generic :: A generic structure for user-level extensibility (?).   */
 421.443 +  /*                                                                       */
 421.444 +  typedef struct  FT_ModuleRec_
 421.445 +  {
 421.446 +    FT_Module_Class*  clazz;
 421.447 +    FT_Library        library;
 421.448 +    FT_Memory         memory;
 421.449 +    FT_Generic        generic;
 421.450 +
 421.451 +  } FT_ModuleRec;
 421.452 +
 421.453 +
 421.454 +  /* typecast an object to a FT_Module */
 421.455 +#define FT_MODULE( x )          ((FT_Module)( x ))
 421.456 +#define FT_MODULE_CLASS( x )    FT_MODULE( x )->clazz
 421.457 +#define FT_MODULE_LIBRARY( x )  FT_MODULE( x )->library
 421.458 +#define FT_MODULE_MEMORY( x )   FT_MODULE( x )->memory
 421.459 +
 421.460 +
 421.461 +#define FT_MODULE_IS_DRIVER( x )  ( FT_MODULE_CLASS( x )->module_flags & \
 421.462 +                                    FT_MODULE_FONT_DRIVER )
 421.463 +
 421.464 +#define FT_MODULE_IS_RENDERER( x )  ( FT_MODULE_CLASS( x )->module_flags & \
 421.465 +                                      FT_MODULE_RENDERER )
 421.466 +
 421.467 +#define FT_MODULE_IS_HINTER( x )  ( FT_MODULE_CLASS( x )->module_flags & \
 421.468 +                                    FT_MODULE_HINTER )
 421.469 +
 421.470 +#define FT_MODULE_IS_STYLER( x )  ( FT_MODULE_CLASS( x )->module_flags & \
 421.471 +                                    FT_MODULE_STYLER )
 421.472 +
 421.473 +#define FT_DRIVER_IS_SCALABLE( x )  ( FT_MODULE_CLASS( x )->module_flags & \
 421.474 +                                      FT_MODULE_DRIVER_SCALABLE )
 421.475 +
 421.476 +#define FT_DRIVER_USES_OUTLINES( x )  !( FT_MODULE_CLASS( x )->module_flags & \
 421.477 +                                         FT_MODULE_DRIVER_NO_OUTLINES )
 421.478 +
 421.479 +#define FT_DRIVER_HAS_HINTER( x )  ( FT_MODULE_CLASS( x )->module_flags & \
 421.480 +                                     FT_MODULE_DRIVER_HAS_HINTER )
 421.481 +
 421.482 +
 421.483 +  /*************************************************************************/
 421.484 +  /*                                                                       */
 421.485 +  /* <Function>                                                            */
 421.486 +  /*    FT_Get_Module_Interface                                            */
 421.487 +  /*                                                                       */
 421.488 +  /* <Description>                                                         */
 421.489 +  /*    Finds a module and returns its specific interface as a typeless    */
 421.490 +  /*    pointer.                                                           */
 421.491 +  /*                                                                       */
 421.492 +  /* <Input>                                                               */
 421.493 +  /*    library     :: A handle to the library object.                     */
 421.494 +  /*                                                                       */
 421.495 +  /*    module_name :: The module's name (as an ASCII string).             */
 421.496 +  /*                                                                       */
 421.497 +  /* <Return>                                                              */
 421.498 +  /*    A module-specific interface if available, 0 otherwise.             */
 421.499 +  /*                                                                       */
 421.500 +  /* <Note>                                                                */
 421.501 +  /*    You should better be familiar with FreeType internals to know      */
 421.502 +  /*    which module to look for, and what its interface is :-)            */
 421.503 +  /*                                                                       */
 421.504 +  FT_BASE( const void* )
 421.505 +  FT_Get_Module_Interface( FT_Library   library,
 421.506 +                           const char*  mod_name );
 421.507 +
 421.508 +  FT_BASE( FT_Pointer )
 421.509 +  ft_module_get_service( FT_Module    module,
 421.510 +                         const char*  service_id );
 421.511 +
 421.512 + /* */
 421.513 +
 421.514 +
 421.515 +  /*************************************************************************/
 421.516 +  /*************************************************************************/
 421.517 +  /*************************************************************************/
 421.518 +  /****                                                                 ****/
 421.519 +  /****                                                                 ****/
 421.520 +  /****               FACE, SIZE & GLYPH SLOT OBJECTS                   ****/
 421.521 +  /****                                                                 ****/
 421.522 +  /****                                                                 ****/
 421.523 +  /*************************************************************************/
 421.524 +  /*************************************************************************/
 421.525 +  /*************************************************************************/
 421.526 +
 421.527 +  /* a few macros used to perform easy typecasts with minimal brain damage */
 421.528 +
 421.529 +#define FT_FACE( x )          ((FT_Face)(x))
 421.530 +#define FT_SIZE( x )          ((FT_Size)(x))
 421.531 +#define FT_SLOT( x )          ((FT_GlyphSlot)(x))
 421.532 +
 421.533 +#define FT_FACE_DRIVER( x )   FT_FACE( x )->driver
 421.534 +#define FT_FACE_LIBRARY( x )  FT_FACE_DRIVER( x )->root.library
 421.535 +#define FT_FACE_MEMORY( x )   FT_FACE( x )->memory
 421.536 +#define FT_FACE_STREAM( x )   FT_FACE( x )->stream
 421.537 +
 421.538 +#define FT_SIZE_FACE( x )     FT_SIZE( x )->face
 421.539 +#define FT_SLOT_FACE( x )     FT_SLOT( x )->face
 421.540 +
 421.541 +#define FT_FACE_SLOT( x )     FT_FACE( x )->glyph
 421.542 +#define FT_FACE_SIZE( x )     FT_FACE( x )->size
 421.543 +
 421.544 +
 421.545 +  /*************************************************************************/
 421.546 +  /*                                                                       */
 421.547 +  /* <Function>                                                            */
 421.548 +  /*    FT_New_GlyphSlot                                                   */
 421.549 +  /*                                                                       */
 421.550 +  /* <Description>                                                         */
 421.551 +  /*    It is sometimes useful to have more than one glyph slot for a      */
 421.552 +  /*    given face object.  This function is used to create additional     */
 421.553 +  /*    slots.  All of them are automatically discarded when the face is   */
 421.554 +  /*    destroyed.                                                         */
 421.555 +  /*                                                                       */
 421.556 +  /* <Input>                                                               */
 421.557 +  /*    face  :: A handle to a parent face object.                         */
 421.558 +  /*                                                                       */
 421.559 +  /* <Output>                                                              */
 421.560 +  /*    aslot :: A handle to a new glyph slot object.                      */
 421.561 +  /*                                                                       */
 421.562 +  /* <Return>                                                              */
 421.563 +  /*    FreeType error code.  0 means success.                             */
 421.564 +  /*                                                                       */
 421.565 +  FT_BASE( FT_Error )
 421.566 +  FT_New_GlyphSlot( FT_Face        face,
 421.567 +                    FT_GlyphSlot  *aslot );
 421.568 +
 421.569 +
 421.570 +  /*************************************************************************/
 421.571 +  /*                                                                       */
 421.572 +  /* <Function>                                                            */
 421.573 +  /*    FT_Done_GlyphSlot                                                  */
 421.574 +  /*                                                                       */
 421.575 +  /* <Description>                                                         */
 421.576 +  /*    Destroys a given glyph slot.  Remember however that all slots are  */
 421.577 +  /*    automatically destroyed with its parent.  Using this function is   */
 421.578 +  /*    not always mandatory.                                              */
 421.579 +  /*                                                                       */
 421.580 +  /* <Input>                                                               */
 421.581 +  /*    slot :: A handle to a target glyph slot.                           */
 421.582 +  /*                                                                       */
 421.583 +  FT_BASE( void )
 421.584 +  FT_Done_GlyphSlot( FT_GlyphSlot  slot );
 421.585 +
 421.586 + /* */
 421.587 +
 421.588 +#define FT_REQUEST_WIDTH( req )                                            \
 421.589 +          ( (req)->horiResolution                                          \
 421.590 +              ? (FT_Pos)( (req)->width * (req)->horiResolution + 36 ) / 72 \
 421.591 +              : (req)->width )
 421.592 +
 421.593 +#define FT_REQUEST_HEIGHT( req )                                            \
 421.594 +          ( (req)->vertResolution                                           \
 421.595 +              ? (FT_Pos)( (req)->height * (req)->vertResolution + 36 ) / 72 \
 421.596 +              : (req)->height )
 421.597 +
 421.598 +
 421.599 +  /* Set the metrics according to a bitmap strike. */
 421.600 +  FT_BASE( void )
 421.601 +  FT_Select_Metrics( FT_Face   face,
 421.602 +                     FT_ULong  strike_index );
 421.603 +
 421.604 +
 421.605 +  /* Set the metrics according to a size request. */
 421.606 +  FT_BASE( void )
 421.607 +  FT_Request_Metrics( FT_Face          face,
 421.608 +                      FT_Size_Request  req );
 421.609 +
 421.610 +
 421.611 +  /* Match a size request against `available_sizes'. */
 421.612 +  FT_BASE( FT_Error )
 421.613 +  FT_Match_Size( FT_Face          face,
 421.614 +                 FT_Size_Request  req,
 421.615 +                 FT_Bool          ignore_width,
 421.616 +                 FT_ULong*        size_index );
 421.617 +
 421.618 +
 421.619 +  /* Use the horizontal metrics to synthesize the vertical metrics. */
 421.620 +  /* If `advance' is zero, it is also synthesized.                  */
 421.621 +  FT_BASE( void )
 421.622 +  ft_synthesize_vertical_metrics( FT_Glyph_Metrics*  metrics,
 421.623 +                                  FT_Pos             advance );
 421.624 +
 421.625 +
 421.626 +  /* Free the bitmap of a given glyphslot when needed (i.e., only when it */
 421.627 +  /* was allocated with ft_glyphslot_alloc_bitmap).                       */
 421.628 +  FT_BASE( void )
 421.629 +  ft_glyphslot_free_bitmap( FT_GlyphSlot  slot );
 421.630 +
 421.631 +
 421.632 +  /* Allocate a new bitmap buffer in a glyph slot. */
 421.633 +  FT_BASE( FT_Error )
 421.634 +  ft_glyphslot_alloc_bitmap( FT_GlyphSlot  slot,
 421.635 +                             FT_ULong      size );
 421.636 +
 421.637 +
 421.638 +  /* Set the bitmap buffer in a glyph slot to a given pointer.  The buffer */
 421.639 +  /* will not be freed by a later call to ft_glyphslot_free_bitmap.        */
 421.640 +  FT_BASE( void )
 421.641 +  ft_glyphslot_set_bitmap( FT_GlyphSlot  slot,
 421.642 +                           FT_Byte*      buffer );
 421.643 +
 421.644 +
 421.645 +  /*************************************************************************/
 421.646 +  /*************************************************************************/
 421.647 +  /*************************************************************************/
 421.648 +  /****                                                                 ****/
 421.649 +  /****                                                                 ****/
 421.650 +  /****                        R E N D E R E R S                        ****/
 421.651 +  /****                                                                 ****/
 421.652 +  /****                                                                 ****/
 421.653 +  /*************************************************************************/
 421.654 +  /*************************************************************************/
 421.655 +  /*************************************************************************/
 421.656 +
 421.657 +
 421.658 +#define FT_RENDERER( x )      ((FT_Renderer)( x ))
 421.659 +#define FT_GLYPH( x )         ((FT_Glyph)( x ))
 421.660 +#define FT_BITMAP_GLYPH( x )  ((FT_BitmapGlyph)( x ))
 421.661 +#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x ))
 421.662 +
 421.663 +
 421.664 +  typedef struct  FT_RendererRec_
 421.665 +  {
 421.666 +    FT_ModuleRec            root;
 421.667 +    FT_Renderer_Class*      clazz;
 421.668 +    FT_Glyph_Format         glyph_format;
 421.669 +    FT_Glyph_Class          glyph_class;
 421.670 +
 421.671 +    FT_Raster               raster;
 421.672 +    FT_Raster_Render_Func   raster_render;
 421.673 +    FT_Renderer_RenderFunc  render;
 421.674 +
 421.675 +  } FT_RendererRec;
 421.676 +
 421.677 +
 421.678 +  /*************************************************************************/
 421.679 +  /*************************************************************************/
 421.680 +  /*************************************************************************/
 421.681 +  /****                                                                 ****/
 421.682 +  /****                                                                 ****/
 421.683 +  /****                    F O N T   D R I V E R S                      ****/
 421.684 +  /****                                                                 ****/
 421.685 +  /****                                                                 ****/
 421.686 +  /*************************************************************************/
 421.687 +  /*************************************************************************/
 421.688 +  /*************************************************************************/
 421.689 +
 421.690 +
 421.691 +  /* typecast a module into a driver easily */
 421.692 +#define FT_DRIVER( x )        ((FT_Driver)(x))
 421.693 +
 421.694 +  /* typecast a module as a driver, and get its driver class */
 421.695 +#define FT_DRIVER_CLASS( x )  FT_DRIVER( x )->clazz
 421.696 +
 421.697 +
 421.698 +  /*************************************************************************/
 421.699 +  /*                                                                       */
 421.700 +  /* <Struct>                                                              */
 421.701 +  /*    FT_DriverRec                                                       */
 421.702 +  /*                                                                       */
 421.703 +  /* <Description>                                                         */
 421.704 +  /*    The root font driver class.  A font driver is responsible for      */
 421.705 +  /*    managing and loading font files of a given format.                 */
 421.706 +  /*                                                                       */
 421.707 +  /*  <Fields>                                                             */
 421.708 +  /*     root         :: Contains the fields of the root module class.     */
 421.709 +  /*                                                                       */
 421.710 +  /*     clazz        :: A pointer to the font driver's class.  Note that  */
 421.711 +  /*                     this is NOT root.clazz.  `class' wasn't used      */
 421.712 +  /*                     as it is a reserved word in C++.                  */
 421.713 +  /*                                                                       */
 421.714 +  /*     faces_list   :: The list of faces currently opened by this        */
 421.715 +  /*                     driver.                                           */
 421.716 +  /*                                                                       */
 421.717 +  /*     extensions   :: A typeless pointer to the driver's extensions     */
 421.718 +  /*                     registry, if they are supported through the       */
 421.719 +  /*                     configuration macro FT_CONFIG_OPTION_EXTENSIONS.  */
 421.720 +  /*                                                                       */
 421.721 +  /*     glyph_loader :: The glyph loader for all faces managed by this    */
 421.722 +  /*                     driver.  This object isn't defined for unscalable */
 421.723 +  /*                     formats.                                          */
 421.724 +  /*                                                                       */
 421.725 +  typedef struct  FT_DriverRec_
 421.726 +  {
 421.727 +    FT_ModuleRec     root;
 421.728 +    FT_Driver_Class  clazz;
 421.729 +
 421.730 +    FT_ListRec       faces_list;
 421.731 +    void*            extensions;
 421.732 +
 421.733 +    FT_GlyphLoader   glyph_loader;
 421.734 +
 421.735 +  } FT_DriverRec;
 421.736 +
 421.737 +
 421.738 +  /*************************************************************************/
 421.739 +  /*************************************************************************/
 421.740 +  /*************************************************************************/
 421.741 +  /****                                                                 ****/
 421.742 +  /****                                                                 ****/
 421.743 +  /****                       L I B R A R I E S                         ****/
 421.744 +  /****                                                                 ****/
 421.745 +  /****                                                                 ****/
 421.746 +  /*************************************************************************/
 421.747 +  /*************************************************************************/
 421.748 +  /*************************************************************************/
 421.749 +
 421.750 +
 421.751 +  /* This hook is used by the TrueType debugger.  It must be set to an */
 421.752 +  /* alternate truetype bytecode interpreter function.                 */
 421.753 +#define FT_DEBUG_HOOK_TRUETYPE            0
 421.754 +
 421.755 +
 421.756 +  /* Set this debug hook to a non-null pointer to force unpatented hinting */
 421.757 +  /* for all faces when both TT_USE_BYTECODE_INTERPRETER and               */
 421.758 +  /* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined.  This is only used   */
 421.759 +  /* during debugging.                                                     */
 421.760 +#define FT_DEBUG_HOOK_UNPATENTED_HINTING  1
 421.761 +
 421.762 +
 421.763 +  typedef void  (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap*      bitmap,
 421.764 +                                            FT_Render_Mode  render_mode,
 421.765 +                                            FT_Library      library );
 421.766 +
 421.767 +
 421.768 +  /*************************************************************************/
 421.769 +  /*                                                                       */
 421.770 +  /* <Struct>                                                              */
 421.771 +  /*    FT_LibraryRec                                                      */
 421.772 +  /*                                                                       */
 421.773 +  /* <Description>                                                         */
 421.774 +  /*    The FreeType library class.  This is the root of all FreeType      */
 421.775 +  /*    data.  Use FT_New_Library() to create a library object, and        */
 421.776 +  /*    FT_Done_Library() to discard it and all child objects.             */
 421.777 +  /*                                                                       */
 421.778 +  /* <Fields>                                                              */
 421.779 +  /*    memory           :: The library's memory object.  Manages memory   */
 421.780 +  /*                        allocation.                                    */
 421.781 +  /*                                                                       */
 421.782 +  /*    generic          :: Client data variable.  Used to extend the      */
 421.783 +  /*                        Library class by higher levels and clients.    */
 421.784 +  /*                                                                       */
 421.785 +  /*    version_major    :: The major version number of the library.       */
 421.786 +  /*                                                                       */
 421.787 +  /*    version_minor    :: The minor version number of the library.       */
 421.788 +  /*                                                                       */
 421.789 +  /*    version_patch    :: The current patch level of the library.        */
 421.790 +  /*                                                                       */
 421.791 +  /*    num_modules      :: The number of modules currently registered     */
 421.792 +  /*                        within this library.  This is set to 0 for new */
 421.793 +  /*                        libraries.  New modules are added through the  */
 421.794 +  /*                        FT_Add_Module() API function.                  */
 421.795 +  /*                                                                       */
 421.796 +  /*    modules          :: A table used to store handles to the currently */
 421.797 +  /*                        registered modules. Note that each font driver */
 421.798 +  /*                        contains a list of its opened faces.           */
 421.799 +  /*                                                                       */
 421.800 +  /*    renderers        :: The list of renderers currently registered     */
 421.801 +  /*                        within the library.                            */
 421.802 +  /*                                                                       */
 421.803 +  /*    cur_renderer     :: The current outline renderer.  This is a       */
 421.804 +  /*                        shortcut used to avoid parsing the list on     */
 421.805 +  /*                        each call to FT_Outline_Render().  It is a     */
 421.806 +  /*                        handle to the current renderer for the         */
 421.807 +  /*                        FT_GLYPH_FORMAT_OUTLINE format.                */
 421.808 +  /*                                                                       */
 421.809 +  /*    auto_hinter      :: XXX                                            */
 421.810 +  /*                                                                       */
 421.811 +  /*    raster_pool      :: The raster object's render pool.  This can     */
 421.812 +  /*                        ideally be changed dynamically at run-time.    */
 421.813 +  /*                                                                       */
 421.814 +  /*    raster_pool_size :: The size of the render pool in bytes.          */
 421.815 +  /*                                                                       */
 421.816 +  /*    debug_hooks      :: XXX                                            */
 421.817 +  /*                                                                       */
 421.818 +  /*    lcd_filter       :: If subpixel rendering is activated, the        */
 421.819 +  /*                        selected LCD filter mode.                      */
 421.820 +  /*                                                                       */
 421.821 +  /*    lcd_extra        :: If subpixel rendering is activated, the number */
 421.822 +  /*                        of extra pixels needed for the LCD filter.     */
 421.823 +  /*                                                                       */
 421.824 +  /*    lcd_weights      :: If subpixel rendering is activated, the LCD    */
 421.825 +  /*                        filter weights, if any.                        */
 421.826 +  /*                                                                       */
 421.827 +  /*    lcd_filter_func  :: If subpixel rendering is activated, the LCD    */
 421.828 +  /*                        filtering callback function.                   */
 421.829 +  /*                                                                       */
 421.830 +  /*    pic_container    :: Contains global structs and tables, instead    */
 421.831 +  /*                        of defining them globallly.                    */
 421.832 +  /*                                                                       */
 421.833 +  /*    refcount         :: A counter initialized to~1 at the time an      */
 421.834 +  /*                        @FT_Library structure is created.              */
 421.835 +  /*                        @FT_Reference_Library increments this counter, */
 421.836 +  /*                        and @FT_Done_Library only destroys a library   */
 421.837 +  /*                        if the counter is~1, otherwise it simply       */
 421.838 +  /*                        decrements it.                                 */
 421.839 +  /*                                                                       */
 421.840 +  typedef struct  FT_LibraryRec_
 421.841 +  {
 421.842 +    FT_Memory          memory;           /* library's memory manager */
 421.843 +
 421.844 +    FT_Generic         generic;
 421.845 +
 421.846 +    FT_Int             version_major;
 421.847 +    FT_Int             version_minor;
 421.848 +    FT_Int             version_patch;
 421.849 +
 421.850 +    FT_UInt            num_modules;
 421.851 +    FT_Module          modules[FT_MAX_MODULES];  /* module objects  */
 421.852 +
 421.853 +    FT_ListRec         renderers;        /* list of renderers        */
 421.854 +    FT_Renderer        cur_renderer;     /* current outline renderer */
 421.855 +    FT_Module          auto_hinter;
 421.856 +
 421.857 +    FT_Byte*           raster_pool;      /* scan-line conversion */
 421.858 +                                         /* render pool          */
 421.859 +    FT_ULong           raster_pool_size; /* size of render pool in bytes */
 421.860 +
 421.861 +    FT_DebugHook_Func  debug_hooks[4];
 421.862 +
 421.863 +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
 421.864 +    FT_LcdFilter             lcd_filter;
 421.865 +    FT_Int                   lcd_extra;        /* number of extra pixels */
 421.866 +    FT_Byte                  lcd_weights[7];   /* filter weights, if any */
 421.867 +    FT_Bitmap_LcdFilterFunc  lcd_filter_func;  /* filtering callback     */
 421.868 +#endif
 421.869 +
 421.870 +#ifdef FT_CONFIG_OPTION_PIC
 421.871 +    FT_PIC_Container   pic_container;
 421.872 +#endif
 421.873 +
 421.874 +    FT_UInt            refcount;
 421.875 +
 421.876 +  } FT_LibraryRec;
 421.877 +
 421.878 +
 421.879 +  FT_BASE( FT_Renderer )
 421.880 +  FT_Lookup_Renderer( FT_Library       library,
 421.881 +                      FT_Glyph_Format  format,
 421.882 +                      FT_ListNode*     node );
 421.883 +
 421.884 +  FT_BASE( FT_Error )
 421.885 +  FT_Render_Glyph_Internal( FT_Library      library,
 421.886 +                            FT_GlyphSlot    slot,
 421.887 +                            FT_Render_Mode  render_mode );
 421.888 +
 421.889 +  typedef const char*
 421.890 +  (*FT_Face_GetPostscriptNameFunc)( FT_Face  face );
 421.891 +
 421.892 +  typedef FT_Error
 421.893 +  (*FT_Face_GetGlyphNameFunc)( FT_Face     face,
 421.894 +                               FT_UInt     glyph_index,
 421.895 +                               FT_Pointer  buffer,
 421.896 +                               FT_UInt     buffer_max );
 421.897 +
 421.898 +  typedef FT_UInt
 421.899 +  (*FT_Face_GetGlyphNameIndexFunc)( FT_Face     face,
 421.900 +                                    FT_String*  glyph_name );
 421.901 +
 421.902 +
 421.903 +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
 421.904 +
 421.905 +  /*************************************************************************/
 421.906 +  /*                                                                       */
 421.907 +  /* <Function>                                                            */
 421.908 +  /*    FT_New_Memory                                                      */
 421.909 +  /*                                                                       */
 421.910 +  /* <Description>                                                         */
 421.911 +  /*    Creates a new memory object.                                       */
 421.912 +  /*                                                                       */
 421.913 +  /* <Return>                                                              */
 421.914 +  /*    A pointer to the new memory object.  0 in case of error.           */
 421.915 +  /*                                                                       */
 421.916 +  FT_BASE( FT_Memory )
 421.917 +  FT_New_Memory( void );
 421.918 +
 421.919 +
 421.920 +  /*************************************************************************/
 421.921 +  /*                                                                       */
 421.922 +  /* <Function>                                                            */
 421.923 +  /*    FT_Done_Memory                                                     */
 421.924 +  /*                                                                       */
 421.925 +  /* <Description>                                                         */
 421.926 +  /*    Discards memory manager.                                           */
 421.927 +  /*                                                                       */
 421.928 +  /* <Input>                                                               */
 421.929 +  /*    memory :: A handle to the memory manager.                          */
 421.930 +  /*                                                                       */
 421.931 +  FT_BASE( void )
 421.932 +  FT_Done_Memory( FT_Memory  memory );
 421.933 +
 421.934 +#endif /* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */
 421.935 +
 421.936 +
 421.937 +  /* Define default raster's interface.  The default raster is located in  */
 421.938 +  /* `src/base/ftraster.c'.                                                */
 421.939 +  /*                                                                       */
 421.940 +  /* Client applications can register new rasters through the              */
 421.941 +  /* FT_Set_Raster() API.                                                  */
 421.942 +
 421.943 +#ifndef FT_NO_DEFAULT_RASTER
 421.944 +  FT_EXPORT_VAR( FT_Raster_Funcs )  ft_default_raster;
 421.945 +#endif
 421.946 +
 421.947 +  /*************************************************************************/
 421.948 +  /*************************************************************************/
 421.949 +  /*************************************************************************/
 421.950 +  /****                                                                 ****/
 421.951 +  /****                                                                 ****/
 421.952 +  /****              PIC-Support Macros for ftimage.h                   ****/
 421.953 +  /****                                                                 ****/
 421.954 +  /****                                                                 ****/
 421.955 +  /*************************************************************************/
 421.956 +  /*************************************************************************/
 421.957 +  /*************************************************************************/
 421.958 +
 421.959 +
 421.960 +  /*************************************************************************/
 421.961 +  /*                                                                       */
 421.962 +  /* <Macro>                                                               */
 421.963 +  /*    FT_DEFINE_OUTLINE_FUNCS                                            */
 421.964 +  /*                                                                       */
 421.965 +  /* <Description>                                                         */
 421.966 +  /*    Used to initialize an instance of FT_Outline_Funcs struct.         */
 421.967 +  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */
 421.968 +  /*    called with a pre-allocated stracture to be filled.                */
 421.969 +  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
 421.970 +  /*    allocated in the global scope (or the scope where the macro        */
 421.971 +  /*    is used).                                                          */
 421.972 +  /*                                                                       */
 421.973 +#ifndef FT_CONFIG_OPTION_PIC
 421.974 +
 421.975 +#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_,       \
 421.976 +                                cubic_to_, shift_, delta_)                   \
 421.977 +  static const FT_Outline_Funcs class_ =                                     \
 421.978 +  {                                                                          \
 421.979 +    move_to_, line_to_, conic_to_, cubic_to_, shift_, delta_                 \
 421.980 +  };
 421.981 +
 421.982 +#else /* FT_CONFIG_OPTION_PIC */ 
 421.983 +
 421.984 +#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_,       \
 421.985 +                                cubic_to_, shift_, delta_)                   \
 421.986 +  static FT_Error                                                            \
 421.987 +  Init_Class_##class_( FT_Outline_Funcs*  clazz )                            \
 421.988 +  {                                                                          \
 421.989 +    clazz->move_to = move_to_;                                               \
 421.990 +    clazz->line_to = line_to_;                                               \
 421.991 +    clazz->conic_to = conic_to_;                                             \
 421.992 +    clazz->cubic_to = cubic_to_;                                             \
 421.993 +    clazz->shift = shift_;                                                   \
 421.994 +    clazz->delta = delta_;                                                   \
 421.995 +    return FT_Err_Ok;                                                        \
 421.996 +  } 
 421.997 +
 421.998 +#endif /* FT_CONFIG_OPTION_PIC */ 
 421.999 +
421.1000 +  /*************************************************************************/
421.1001 +  /*                                                                       */
421.1002 +  /* <Macro>                                                               */
421.1003 +  /*    FT_DEFINE_RASTER_FUNCS                                             */
421.1004 +  /*                                                                       */
421.1005 +  /* <Description>                                                         */
421.1006 +  /*    Used to initialize an instance of FT_Raster_Funcs struct.          */
421.1007 +  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */
421.1008 +  /*    called with a pre-allocated stracture to be filled.                */
421.1009 +  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
421.1010 +  /*    allocated in the global scope (or the scope where the macro        */
421.1011 +  /*    is used).                                                          */
421.1012 +  /*                                                                       */
421.1013 +#ifndef FT_CONFIG_OPTION_PIC
421.1014 +
421.1015 +#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_,           \
421.1016 +                               raster_reset_, raster_set_mode_,              \
421.1017 +                               raster_render_, raster_done_)                 \
421.1018 +  const FT_Raster_Funcs class_ =                                      \
421.1019 +  {                                                                          \
421.1020 +    glyph_format_, raster_new_, raster_reset_,                               \
421.1021 +    raster_set_mode_, raster_render_, raster_done_                           \
421.1022 +  };
421.1023 +
421.1024 +#else /* FT_CONFIG_OPTION_PIC */ 
421.1025 +
421.1026 +#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_,           \
421.1027 +    raster_reset_, raster_set_mode_, raster_render_, raster_done_)           \
421.1028 +  void                                                                       \
421.1029 +  FT_Init_Class_##class_( FT_Raster_Funcs*  clazz )                          \
421.1030 +  {                                                                          \
421.1031 +    clazz->glyph_format = glyph_format_;                                     \
421.1032 +    clazz->raster_new = raster_new_;                                         \
421.1033 +    clazz->raster_reset = raster_reset_;                                     \
421.1034 +    clazz->raster_set_mode = raster_set_mode_;                               \
421.1035 +    clazz->raster_render = raster_render_;                                   \
421.1036 +    clazz->raster_done = raster_done_;                                       \
421.1037 +  } 
421.1038 +
421.1039 +#endif /* FT_CONFIG_OPTION_PIC */ 
421.1040 +
421.1041 +  /*************************************************************************/
421.1042 +  /*************************************************************************/
421.1043 +  /*************************************************************************/
421.1044 +  /****                                                                 ****/
421.1045 +  /****                                                                 ****/
421.1046 +  /****              PIC-Support Macros for ftrender.h                  ****/
421.1047 +  /****                                                                 ****/
421.1048 +  /****                                                                 ****/
421.1049 +  /*************************************************************************/
421.1050 +  /*************************************************************************/
421.1051 +  /*************************************************************************/
421.1052 +
421.1053 +
421.1054 +
421.1055 +  /*************************************************************************/
421.1056 +  /*                                                                       */
421.1057 +  /* <Macro>                                                               */
421.1058 +  /*    FT_DEFINE_GLYPH                                                    */
421.1059 +  /*                                                                       */
421.1060 +  /* <Description>                                                         */
421.1061 +  /*    Used to initialize an instance of FT_Glyph_Class struct.           */
421.1062 +  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */
421.1063 +  /*    called with a pre-allocated stracture to be filled.                */
421.1064 +  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
421.1065 +  /*    allocated in the global scope (or the scope where the macro        */
421.1066 +  /*    is used).                                                          */
421.1067 +  /*                                                                       */
421.1068 +#ifndef FT_CONFIG_OPTION_PIC
421.1069 +
421.1070 +#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_,         \
421.1071 +                        transform_, bbox_, prepare_)                         \
421.1072 +  FT_CALLBACK_TABLE_DEF                                                      \
421.1073 +  const FT_Glyph_Class class_ =                                              \
421.1074 +  {                                                                          \
421.1075 +    size_, format_, init_, done_, copy_, transform_, bbox_, prepare_         \
421.1076 +  };
421.1077 +
421.1078 +#else /* FT_CONFIG_OPTION_PIC */ 
421.1079 +
421.1080 +#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_,         \
421.1081 +                        transform_, bbox_, prepare_)                         \
421.1082 +  void                                                                       \
421.1083 +  FT_Init_Class_##class_( FT_Glyph_Class*  clazz )                           \
421.1084 +  {                                                                          \
421.1085 +    clazz->glyph_size = size_;                                               \
421.1086 +    clazz->glyph_format = format_;                                           \
421.1087 +    clazz->glyph_init = init_;                                               \
421.1088 +    clazz->glyph_done = done_;                                               \
421.1089 +    clazz->glyph_copy = copy_;                                               \
421.1090 +    clazz->glyph_transform = transform_;                                     \
421.1091 +    clazz->glyph_bbox = bbox_;                                               \
421.1092 +    clazz->glyph_prepare = prepare_;                                         \
421.1093 +  } 
421.1094 +
421.1095 +#endif /* FT_CONFIG_OPTION_PIC */ 
421.1096 +
421.1097 +  /*************************************************************************/
421.1098 +  /*                                                                       */
421.1099 +  /* <Macro>                                                               */
421.1100 +  /*    FT_DECLARE_RENDERER                                                */
421.1101 +  /*                                                                       */
421.1102 +  /* <Description>                                                         */
421.1103 +  /*    Used to create a forward declaration of a                          */
421.1104 +  /*    FT_Renderer_Class stract instance.                                 */
421.1105 +  /*                                                                       */
421.1106 +  /* <Macro>                                                               */
421.1107 +  /*    FT_DEFINE_RENDERER                                                 */
421.1108 +  /*                                                                       */
421.1109 +  /* <Description>                                                         */
421.1110 +  /*    Used to initialize an instance of FT_Renderer_Class struct.        */
421.1111 +  /*                                                                       */
421.1112 +  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */
421.1113 +  /*    to called with a pointer where the allocated stracture is returned.*/
421.1114 +  /*    And when it is no longer needed a Destroy function needs           */
421.1115 +  /*    to be called to release that allocation.                           */
421.1116 +  /*    fcinit.c (ft_create_default_module_classes) already contains       */
421.1117 +  /*    a mechanism to call these functions for the default modules        */
421.1118 +  /*    described in ftmodule.h                                            */
421.1119 +  /*                                                                       */
421.1120 +  /*    Notice that the created Create and Destroy functions call          */
421.1121 +  /*    pic_init and pic_free function to allow you to manually allocate   */
421.1122 +  /*    and initialize any additional global data, like module specific    */
421.1123 +  /*    interface, and put them in the global pic container defined in     */
421.1124 +  /*    ftpic.h. if you don't need them just implement the functions as    */
421.1125 +  /*    empty to resolve the link error.                                   */
421.1126 +  /*                                                                       */
421.1127 +  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
421.1128 +  /*    allocated in the global scope (or the scope where the macro        */
421.1129 +  /*    is used).                                                          */
421.1130 +  /*                                                                       */
421.1131 +#ifndef FT_CONFIG_OPTION_PIC
421.1132 +
421.1133 +#define FT_DECLARE_RENDERER(class_)                                          \
421.1134 +    FT_EXPORT_VAR( const FT_Renderer_Class ) class_;
421.1135 +
421.1136 +#define FT_DEFINE_RENDERER(class_,                                           \
421.1137 +                           flags_, size_, name_, version_, requires_,        \
421.1138 +                           interface_, init_, done_, get_interface_,         \
421.1139 +                           glyph_format_, render_glyph_, transform_glyph_,   \
421.1140 +                           get_glyph_cbox_, set_mode_, raster_class_ )       \
421.1141 +  FT_CALLBACK_TABLE_DEF                                                      \
421.1142 +  const FT_Renderer_Class  class_ =                                          \
421.1143 +  {                                                                          \
421.1144 +    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,             \
421.1145 +                          interface_,init_,done_,get_interface_)             \
421.1146 +    glyph_format_,                                                           \
421.1147 +                                                                             \
421.1148 +    render_glyph_,                                                           \
421.1149 +    transform_glyph_,                                                        \
421.1150 +    get_glyph_cbox_,                                                         \
421.1151 +    set_mode_,                                                               \
421.1152 +                                                                             \
421.1153 +    raster_class_                                                            \
421.1154 +  };
421.1155 +
421.1156 +#else /* FT_CONFIG_OPTION_PIC */ 
421.1157 +
421.1158 +#define FT_DECLARE_RENDERER(class_)  FT_DECLARE_MODULE(class_)
421.1159 +
421.1160 +#define FT_DEFINE_RENDERER(class_, \
421.1161 +                           flags_, size_, name_, version_, requires_,        \
421.1162 +                           interface_, init_, done_, get_interface_,         \
421.1163 +                           glyph_format_, render_glyph_, transform_glyph_,   \
421.1164 +                           get_glyph_cbox_, set_mode_, raster_class_ )       \
421.1165 +  void class_##_pic_free( FT_Library library );                              \
421.1166 +  FT_Error class_##_pic_init( FT_Library library );                          \
421.1167 +                                                                             \
421.1168 +  void                                                                       \
421.1169 +  FT_Destroy_Class_##class_( FT_Library        library,                      \
421.1170 +                        FT_Module_Class*  clazz )                            \
421.1171 +  {                                                                          \
421.1172 +    FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz;                   \
421.1173 +    FT_Memory         memory = library->memory;                              \
421.1174 +    class_##_pic_free( library );                                            \
421.1175 +    if ( rclazz )                                                            \
421.1176 +      FT_FREE( rclazz );                                                     \
421.1177 +  }                                                                          \
421.1178 +                                                                             \
421.1179 +  FT_Error                                                                   \
421.1180 +  FT_Create_Class_##class_( FT_Library         library,                      \
421.1181 +                            FT_Module_Class**  output_class )                \
421.1182 +  {                                                                          \
421.1183 +    FT_Renderer_Class*  clazz;                                               \
421.1184 +    FT_Error            error;                                               \
421.1185 +    FT_Memory           memory = library->memory;                            \
421.1186 +                                                                             \
421.1187 +    if ( FT_ALLOC( clazz, sizeof(*clazz) ) )                                 \
421.1188 +      return error;                                                          \
421.1189 +                                                                             \
421.1190 +    error = class_##_pic_init( library );                                    \
421.1191 +    if(error)                                                                \
421.1192 +    {                                                                        \
421.1193 +      FT_FREE( clazz );                                                      \
421.1194 +      return error;                                                          \
421.1195 +    }                                                                        \
421.1196 +                                                                             \
421.1197 +    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,             \
421.1198 +                          interface_,init_,done_,get_interface_)             \
421.1199 +                                                                             \
421.1200 +    clazz->glyph_format       = glyph_format_;                               \
421.1201 +                                                                             \
421.1202 +    clazz->render_glyph       = render_glyph_;                               \
421.1203 +    clazz->transform_glyph    = transform_glyph_;                            \
421.1204 +    clazz->get_glyph_cbox     = get_glyph_cbox_;                             \
421.1205 +    clazz->set_mode           = set_mode_;                                   \
421.1206 +                                                                             \
421.1207 +    clazz->raster_class       = raster_class_;                               \
421.1208 +                                                                             \
421.1209 +    *output_class = (FT_Module_Class*)clazz;                                 \
421.1210 +    return FT_Err_Ok;                                                        \
421.1211 +  } 
421.1212 +
421.1213 +
421.1214 +
421.1215 +#endif /* FT_CONFIG_OPTION_PIC */ 
421.1216 +
421.1217 +  /*************************************************************************/
421.1218 +  /*************************************************************************/
421.1219 +  /*************************************************************************/
421.1220 +  /****                                                                 ****/
421.1221 +  /****                                                                 ****/
421.1222 +  /****              PIC-Support Macros for ftmodapi.h                  ****/
421.1223 +  /****                                                                 ****/
421.1224 +  /****                                                                 ****/
421.1225 +  /*************************************************************************/
421.1226 +  /*************************************************************************/
421.1227 +  /*************************************************************************/
421.1228 +
421.1229 +
421.1230 +#ifdef FT_CONFIG_OPTION_PIC
421.1231 +
421.1232 +  /*************************************************************************/
421.1233 +  /*                                                                       */
421.1234 +  /* <FuncType>                                                            */
421.1235 +  /*    FT_Module_Creator                                                  */
421.1236 +  /*                                                                       */
421.1237 +  /* <Description>                                                         */
421.1238 +  /*    A function used to create (allocate) a new module class object.    */
421.1239 +  /*    The object's members are initialized, but the module itself is     */
421.1240 +  /*    not.                                                               */
421.1241 +  /*                                                                       */
421.1242 +  /* <Input>                                                               */
421.1243 +  /*    memory       :: A handle to the memory manager.                    */
421.1244 +  /*    output_class :: Initialized with the newly allocated class.        */
421.1245 +  /*                                                                       */
421.1246 +  typedef FT_Error
421.1247 +  (*FT_Module_Creator)( FT_Memory          memory,
421.1248 +                        FT_Module_Class**  output_class );
421.1249 +
421.1250 +  /*************************************************************************/
421.1251 +  /*                                                                       */
421.1252 +  /* <FuncType>                                                            */
421.1253 +  /*    FT_Module_Destroyer                                                */
421.1254 +  /*                                                                       */
421.1255 +  /* <Description>                                                         */
421.1256 +  /*    A function used to destroy (deallocate) a module class object.     */
421.1257 +  /*                                                                       */
421.1258 +  /* <Input>                                                               */
421.1259 +  /*    memory :: A handle to the memory manager.                          */
421.1260 +  /*    clazz  :: Module class to destroy.                                 */
421.1261 +  /*                                                                       */
421.1262 +  typedef void
421.1263 +  (*FT_Module_Destroyer)( FT_Memory         memory,
421.1264 +                          FT_Module_Class*  clazz );
421.1265 +
421.1266 +#endif
421.1267 +
421.1268 +  /*************************************************************************/
421.1269 +  /*                                                                       */
421.1270 +  /* <Macro>                                                               */
421.1271 +  /*    FT_DECLARE_MODULE                                                  */
421.1272 +  /*                                                                       */
421.1273 +  /* <Description>                                                         */
421.1274 +  /*    Used to create a forward declaration of a                          */
421.1275 +  /*    FT_Module_Class stract instance.                                   */
421.1276 +  /*                                                                       */
421.1277 +  /* <Macro>                                                               */
421.1278 +  /*    FT_DEFINE_MODULE                                                   */
421.1279 +  /*                                                                       */
421.1280 +  /* <Description>                                                         */
421.1281 +  /*    Used to initialize an instance of FT_Module_Class struct.          */
421.1282 +  /*                                                                       */
421.1283 +  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */
421.1284 +  /*    to called with a pointer where the allocated stracture is returned.*/
421.1285 +  /*    And when it is no longer needed a Destroy function needs           */
421.1286 +  /*    to be called to release that allocation.                           */
421.1287 +  /*    fcinit.c (ft_create_default_module_classes) already contains       */
421.1288 +  /*    a mechanism to call these functions for the default modules        */
421.1289 +  /*    described in ftmodule.h                                            */
421.1290 +  /*                                                                       */
421.1291 +  /*    Notice that the created Create and Destroy functions call          */
421.1292 +  /*    pic_init and pic_free function to allow you to manually allocate   */
421.1293 +  /*    and initialize any additional global data, like module specific    */
421.1294 +  /*    interface, and put them in the global pic container defined in     */
421.1295 +  /*    ftpic.h. if you don't need them just implement the functions as    */
421.1296 +  /*    empty to resolve the link error.                                   */
421.1297 +  /*                                                                       */
421.1298 +  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
421.1299 +  /*    allocated in the global scope (or the scope where the macro        */
421.1300 +  /*    is used).                                                          */
421.1301 +  /*                                                                       */
421.1302 +  /* <Macro>                                                               */
421.1303 +  /*    FT_DEFINE_ROOT_MODULE                                              */
421.1304 +  /*                                                                       */
421.1305 +  /* <Description>                                                         */
421.1306 +  /*    Used to initialize an instance of FT_Module_Class struct inside    */
421.1307 +  /*    another stract that contains it or in a function that initializes  */
421.1308 +  /*    that containing stract                                             */
421.1309 +  /*                                                                       */
421.1310 +#ifndef FT_CONFIG_OPTION_PIC
421.1311 +
421.1312 +#define FT_DECLARE_MODULE(class_)                                            \
421.1313 +  FT_CALLBACK_TABLE                                                          \
421.1314 +  const FT_Module_Class  class_;                                             \
421.1315 +
421.1316 +#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_,     \
421.1317 +                              interface_, init_, done_, get_interface_)      \
421.1318 +  {                                                                          \
421.1319 +    flags_,                                                                  \
421.1320 +    size_,                                                                   \
421.1321 +                                                                             \
421.1322 +    name_,                                                                   \
421.1323 +    version_,                                                                \
421.1324 +    requires_,                                                               \
421.1325 +                                                                             \
421.1326 +    interface_,                                                              \
421.1327 +                                                                             \
421.1328 +    init_,                                                                   \
421.1329 +    done_,                                                                   \
421.1330 +    get_interface_,                                                          \
421.1331 +  },
421.1332 +
421.1333 +#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_,  \
421.1334 +                         interface_, init_, done_, get_interface_)           \
421.1335 +  FT_CALLBACK_TABLE_DEF                                                      \
421.1336 +  const FT_Module_Class class_ =                                             \
421.1337 +  {                                                                          \
421.1338 +    flags_,                                                                  \
421.1339 +    size_,                                                                   \
421.1340 +                                                                             \
421.1341 +    name_,                                                                   \
421.1342 +    version_,                                                                \
421.1343 +    requires_,                                                               \
421.1344 +                                                                             \
421.1345 +    interface_,                                                              \
421.1346 +                                                                             \
421.1347 +    init_,                                                                   \
421.1348 +    done_,                                                                   \
421.1349 +    get_interface_,                                                          \
421.1350 +  };
421.1351 +
421.1352 +
421.1353 +#else /* FT_CONFIG_OPTION_PIC */
421.1354 +
421.1355 +#define FT_DECLARE_MODULE(class_)                                            \
421.1356 +  FT_Error FT_Create_Class_##class_( FT_Library library,                     \
421.1357 +                                     FT_Module_Class** output_class );       \
421.1358 +  void     FT_Destroy_Class_##class_( FT_Library library,                    \
421.1359 +                                      FT_Module_Class*  clazz );
421.1360 +
421.1361 +#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_,     \
421.1362 +                              interface_, init_, done_, get_interface_)      \
421.1363 +    clazz->root.module_flags       = flags_;                                 \
421.1364 +    clazz->root.module_size        = size_;                                  \
421.1365 +    clazz->root.module_name        = name_;                                  \
421.1366 +    clazz->root.module_version     = version_;                               \
421.1367 +    clazz->root.module_requires    = requires_;                              \
421.1368 +                                                                             \
421.1369 +    clazz->root.module_interface   = interface_;                             \
421.1370 +                                                                             \
421.1371 +    clazz->root.module_init        = init_;                                  \
421.1372 +    clazz->root.module_done        = done_;                                  \
421.1373 +    clazz->root.get_interface      = get_interface_;               
421.1374 +
421.1375 +#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_,  \
421.1376 +                         interface_, init_, done_, get_interface_)           \
421.1377 +  void class_##_pic_free( FT_Library library );                              \
421.1378 +  FT_Error class_##_pic_init( FT_Library library );                          \
421.1379 +                                                                             \
421.1380 +  void                                                                       \
421.1381 +  FT_Destroy_Class_##class_( FT_Library library,                             \
421.1382 +                             FT_Module_Class*  clazz )                       \
421.1383 +  {                                                                          \
421.1384 +    FT_Memory memory = library->memory;                                      \
421.1385 +    class_##_pic_free( library );                                            \
421.1386 +    if ( clazz )                                                             \
421.1387 +      FT_FREE( clazz );                                                      \
421.1388 +  }                                                                          \
421.1389 +                                                                             \
421.1390 +  FT_Error                                                                   \
421.1391 +  FT_Create_Class_##class_( FT_Library library,                              \
421.1392 +                            FT_Module_Class**  output_class )                \
421.1393 +  {                                                                          \
421.1394 +    FT_Memory memory = library->memory;                                      \
421.1395 +    FT_Module_Class*  clazz;                                                 \
421.1396 +    FT_Error          error;                                                 \
421.1397 +                                                                             \
421.1398 +    if ( FT_ALLOC( clazz, sizeof(*clazz) ) )                                 \
421.1399 +      return error;                                                          \
421.1400 +    error = class_##_pic_init( library );                                    \
421.1401 +    if(error)                                                                \
421.1402 +    {                                                                        \
421.1403 +      FT_FREE( clazz );                                                      \
421.1404 +      return error;                                                          \
421.1405 +    }                                                                        \
421.1406 +                                                                             \
421.1407 +    clazz->module_flags       = flags_;                                      \
421.1408 +    clazz->module_size        = size_;                                       \
421.1409 +    clazz->module_name        = name_;                                       \
421.1410 +    clazz->module_version     = version_;                                    \
421.1411 +    clazz->module_requires    = requires_;                                   \
421.1412 +                                                                             \
421.1413 +    clazz->module_interface   = interface_;                                  \
421.1414 +                                                                             \
421.1415 +    clazz->module_init        = init_;                                       \
421.1416 +    clazz->module_done        = done_;                                       \
421.1417 +    clazz->get_interface      = get_interface_;                              \
421.1418 +                                                                             \
421.1419 +    *output_class = clazz;                                                   \
421.1420 +    return FT_Err_Ok;                                                        \
421.1421 +  } 
421.1422 +
421.1423 +#endif /* FT_CONFIG_OPTION_PIC */
421.1424 +
421.1425 +
421.1426 +FT_END_HEADER
421.1427 +
421.1428 +#endif /* __FTOBJS_H__ */
421.1429 +
421.1430 +
421.1431 +/* END */
   422.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   422.2 +++ b/libs/ft2static/freetype/internal/ftpic.h	Sat Feb 01 19:58:19 2014 +0200
   422.3 @@ -0,0 +1,67 @@
   422.4 +/***************************************************************************/
   422.5 +/*                                                                         */
   422.6 +/*  ftpic.h                                                                */
   422.7 +/*                                                                         */
   422.8 +/*    The FreeType position independent code services (declaration).       */
   422.9 +/*                                                                         */
  422.10 +/*  Copyright 2009 by                                                      */
  422.11 +/*  Oran Agra and Mickey Gabel.                                            */
  422.12 +/*                                                                         */
  422.13 +/*  This file is part of the FreeType project, and may only be used,       */
  422.14 +/*  modified, and distributed under the terms of the FreeType project      */
  422.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  422.16 +/*  this file you indicate that you have read the license and              */
  422.17 +/*  understand and accept it fully.                                        */
  422.18 +/*                                                                         */
  422.19 +/***************************************************************************/
  422.20 +
  422.21 +  /*************************************************************************/
  422.22 +  /*                                                                       */
  422.23 +  /*  Modules that ordinarily have const global data that need address     */
  422.24 +  /*  can instead define pointers here.                                    */
  422.25 +  /*                                                                       */
  422.26 +  /*************************************************************************/
  422.27 +
  422.28 +
  422.29 +#ifndef __FTPIC_H__
  422.30 +#define __FTPIC_H__
  422.31 +
  422.32 +  
  422.33 +FT_BEGIN_HEADER
  422.34 +
  422.35 +#ifdef FT_CONFIG_OPTION_PIC
  422.36 +
  422.37 +  typedef struct FT_PIC_Container_
  422.38 +  {
  422.39 +    /* pic containers for base */
  422.40 +    void* base;
  422.41 +    /* pic containers for modules */
  422.42 +    void* autofit;   
  422.43 +    void* cff;    
  422.44 +    void* pshinter;    
  422.45 +    void* psnames;    
  422.46 +    void* raster;     
  422.47 +    void* sfnt;     
  422.48 +    void* smooth;     
  422.49 +    void* truetype;     
  422.50 +  } FT_PIC_Container;
  422.51 +
  422.52 +  /* Initialize the various function tables, structs, etc. stored in the container. */
  422.53 +  FT_BASE( FT_Error )
  422.54 +  ft_pic_container_init( FT_Library library );
  422.55 +
  422.56 +
  422.57 +  /* Destroy the contents of the container. */
  422.58 +  FT_BASE( void )
  422.59 +  ft_pic_container_destroy( FT_Library library );
  422.60 +
  422.61 +#endif /* FT_CONFIG_OPTION_PIC */
  422.62 +
  422.63 + /* */
  422.64 +
  422.65 +FT_END_HEADER
  422.66 +
  422.67 +#endif /* __FTPIC_H__ */
  422.68 +
  422.69 +
  422.70 +/* END */
   423.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   423.2 +++ b/libs/ft2static/freetype/internal/ftrfork.h	Sat Feb 01 19:58:19 2014 +0200
   423.3 @@ -0,0 +1,196 @@
   423.4 +/***************************************************************************/
   423.5 +/*                                                                         */
   423.6 +/*  ftrfork.h                                                              */
   423.7 +/*                                                                         */
   423.8 +/*    Embedded resource forks accessor (specification).                    */
   423.9 +/*                                                                         */
  423.10 +/*  Copyright 2004, 2006, 2007 by                                          */
  423.11 +/*  Masatake YAMATO and Redhat K.K.                                        */
  423.12 +/*                                                                         */
  423.13 +/*  This file is part of the FreeType project, and may only be used,       */
  423.14 +/*  modified, and distributed under the terms of the FreeType project      */
  423.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  423.16 +/*  this file you indicate that you have read the license and              */
  423.17 +/*  understand and accept it fully.                                        */
  423.18 +/*                                                                         */
  423.19 +/***************************************************************************/
  423.20 +
  423.21 +/***************************************************************************/
  423.22 +/* Development of the code in this file is support of                      */
  423.23 +/* Information-technology Promotion Agency, Japan.                         */
  423.24 +/***************************************************************************/
  423.25 +
  423.26 +
  423.27 +#ifndef __FTRFORK_H__
  423.28 +#define __FTRFORK_H__
  423.29 +
  423.30 +
  423.31 +#include <ft2build.h>
  423.32 +#include FT_INTERNAL_OBJECTS_H
  423.33 +
  423.34 +
  423.35 +FT_BEGIN_HEADER
  423.36 +
  423.37 +
  423.38 +  /* Number of guessing rules supported in `FT_Raccess_Guess'.            */
  423.39 +  /* Don't forget to increment the number if you add a new guessing rule. */
  423.40 +#define FT_RACCESS_N_RULES  9
  423.41 +
  423.42 +
  423.43 +  /* A structure to describe a reference in a resource by its resource ID */
  423.44 +  /* and internal offset.  The `POST' resource expects to be concatenated */
  423.45 +  /* by the order of resource IDs instead of its appearance in the file.  */
  423.46 +
  423.47 +  typedef struct  FT_RFork_Ref_
  423.48 +  {
  423.49 +    FT_UShort  res_id;
  423.50 +    FT_ULong   offset;
  423.51 +
  423.52 +  } FT_RFork_Ref;
  423.53 +
  423.54 +
  423.55 +  /*************************************************************************/
  423.56 +  /*                                                                       */
  423.57 +  /* <Function>                                                            */
  423.58 +  /*    FT_Raccess_Guess                                                   */
  423.59 +  /*                                                                       */
  423.60 +  /* <Description>                                                         */
  423.61 +  /*    Guess a file name and offset where the actual resource fork is     */
  423.62 +  /*    stored.  The macro FT_RACCESS_N_RULES holds the number of          */
  423.63 +  /*    guessing rules;  the guessed result for the Nth rule is            */
  423.64 +  /*    represented as a triplet: a new file name (new_names[N]), a file   */
  423.65 +  /*    offset (offsets[N]), and an error code (errors[N]).                */
  423.66 +  /*                                                                       */
  423.67 +  /* <Input>                                                               */
  423.68 +  /*    library ::                                                         */
  423.69 +  /*      A FreeType library instance.                                     */
  423.70 +  /*                                                                       */
  423.71 +  /*    stream ::                                                          */
  423.72 +  /*      A file stream containing the resource fork.                      */
  423.73 +  /*                                                                       */
  423.74 +  /*    base_name ::                                                       */
  423.75 +  /*      The (base) file name of the resource fork used for some          */
  423.76 +  /*      guessing rules.                                                  */
  423.77 +  /*                                                                       */
  423.78 +  /* <Output>                                                              */
  423.79 +  /*    new_names ::                                                       */
  423.80 +  /*      An array of guessed file names in which the resource forks may   */
  423.81 +  /*      exist.  If `new_names[N]' is NULL, the guessed file name is      */
  423.82 +  /*      equal to `base_name'.                                            */
  423.83 +  /*                                                                       */
  423.84 +  /*    offsets ::                                                         */
  423.85 +  /*      An array of guessed file offsets.  `offsets[N]' holds the file   */
  423.86 +  /*      offset of the possible start of the resource fork in file        */
  423.87 +  /*      `new_names[N]'.                                                  */
  423.88 +  /*                                                                       */
  423.89 +  /*    errors ::                                                          */
  423.90 +  /*      An array of FreeType error codes.  `errors[N]' is the error      */
  423.91 +  /*      code of Nth guessing rule function.  If `errors[N]' is not       */
  423.92 +  /*      FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless.      */
  423.93 +  /*                                                                       */
  423.94 +  FT_BASE( void )
  423.95 +  FT_Raccess_Guess( FT_Library  library,
  423.96 +                    FT_Stream   stream,
  423.97 +                    char*       base_name,
  423.98 +                    char**      new_names,
  423.99 +                    FT_Long*    offsets,
 423.100 +                    FT_Error*   errors );
 423.101 +
 423.102 +
 423.103 +  /*************************************************************************/
 423.104 +  /*                                                                       */
 423.105 +  /* <Function>                                                            */
 423.106 +  /*    FT_Raccess_Get_HeaderInfo                                          */
 423.107 +  /*                                                                       */
 423.108 +  /* <Description>                                                         */
 423.109 +  /*    Get the information from the header of resource fork.  The         */
 423.110 +  /*    information includes the file offset where the resource map        */
 423.111 +  /*    starts, and the file offset where the resource data starts.        */
 423.112 +  /*    `FT_Raccess_Get_DataOffsets' requires these two data.              */
 423.113 +  /*                                                                       */
 423.114 +  /* <Input>                                                               */
 423.115 +  /*    library ::                                                         */
 423.116 +  /*      A FreeType library instance.                                     */
 423.117 +  /*                                                                       */
 423.118 +  /*    stream ::                                                          */
 423.119 +  /*      A file stream containing the resource fork.                      */
 423.120 +  /*                                                                       */
 423.121 +  /*    rfork_offset ::                                                    */
 423.122 +  /*      The file offset where the resource fork starts.                  */
 423.123 +  /*                                                                       */
 423.124 +  /* <Output>                                                              */
 423.125 +  /*    map_offset ::                                                      */
 423.126 +  /*      The file offset where the resource map starts.                   */
 423.127 +  /*                                                                       */
 423.128 +  /*    rdata_pos ::                                                       */
 423.129 +  /*      The file offset where the resource data starts.                  */
 423.130 +  /*                                                                       */
 423.131 +  /* <Return>                                                              */
 423.132 +  /*    FreeType error code.  FT_Err_Ok means success.                     */
 423.133 +  /*                                                                       */
 423.134 +  FT_BASE( FT_Error )
 423.135 +  FT_Raccess_Get_HeaderInfo( FT_Library  library,
 423.136 +                             FT_Stream   stream,
 423.137 +                             FT_Long     rfork_offset,
 423.138 +                             FT_Long    *map_offset,
 423.139 +                             FT_Long    *rdata_pos );
 423.140 +
 423.141 +
 423.142 +  /*************************************************************************/
 423.143 +  /*                                                                       */
 423.144 +  /* <Function>                                                            */
 423.145 +  /*    FT_Raccess_Get_DataOffsets                                         */
 423.146 +  /*                                                                       */
 423.147 +  /* <Description>                                                         */
 423.148 +  /*    Get the data offsets for a tag in a resource fork.  Offsets are    */
 423.149 +  /*    stored in an array because, in some cases, resources in a resource */
 423.150 +  /*    fork have the same tag.                                            */
 423.151 +  /*                                                                       */
 423.152 +  /* <Input>                                                               */
 423.153 +  /*    library ::                                                         */
 423.154 +  /*      A FreeType library instance.                                     */
 423.155 +  /*                                                                       */
 423.156 +  /*    stream ::                                                          */
 423.157 +  /*      A file stream containing the resource fork.                      */
 423.158 +  /*                                                                       */
 423.159 +  /*    map_offset ::                                                      */
 423.160 +  /*      The file offset where the resource map starts.                   */
 423.161 +  /*                                                                       */
 423.162 +  /*    rdata_pos ::                                                       */
 423.163 +  /*      The file offset where the resource data starts.                  */
 423.164 +  /*                                                                       */
 423.165 +  /*    tag ::                                                             */
 423.166 +  /*      The resource tag.                                                */
 423.167 +  /*                                                                       */
 423.168 +  /* <Output>                                                              */
 423.169 +  /*    offsets ::                                                         */
 423.170 +  /*      The stream offsets for the resource data specified by `tag'.     */
 423.171 +  /*      This array is allocated by the function, so you have to call     */
 423.172 +  /*      @ft_mem_free after use.                                          */
 423.173 +  /*                                                                       */
 423.174 +  /*    count ::                                                           */
 423.175 +  /*      The length of offsets array.                                     */
 423.176 +  /*                                                                       */
 423.177 +  /* <Return>                                                              */
 423.178 +  /*    FreeType error code.  FT_Err_Ok means success.                     */
 423.179 +  /*                                                                       */
 423.180 +  /* <Note>                                                                */
 423.181 +  /*    Normally you should use `FT_Raccess_Get_HeaderInfo' to get the     */
 423.182 +  /*    value for `map_offset' and `rdata_pos'.                            */
 423.183 +  /*                                                                       */
 423.184 +  FT_BASE( FT_Error )
 423.185 +  FT_Raccess_Get_DataOffsets( FT_Library  library,
 423.186 +                              FT_Stream   stream,
 423.187 +                              FT_Long     map_offset,
 423.188 +                              FT_Long     rdata_pos,
 423.189 +                              FT_Long     tag,
 423.190 +                              FT_Long   **offsets,
 423.191 +                              FT_Long    *count );
 423.192 +
 423.193 +
 423.194 +FT_END_HEADER
 423.195 +
 423.196 +#endif /* __FTRFORK_H__ */
 423.197 +
 423.198 +
 423.199 +/* END */
   424.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   424.2 +++ b/libs/ft2static/freetype/internal/ftserv.h	Sat Feb 01 19:58:19 2014 +0200
   424.3 @@ -0,0 +1,620 @@
   424.4 +/***************************************************************************/
   424.5 +/*                                                                         */
   424.6 +/*  ftserv.h                                                               */
   424.7 +/*                                                                         */
   424.8 +/*    The FreeType services (specification only).                          */
   424.9 +/*                                                                         */
  424.10 +/*  Copyright 2003, 2004, 2005, 2006, 2007 by                              */
  424.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  424.12 +/*                                                                         */
  424.13 +/*  This file is part of the FreeType project, and may only be used,       */
  424.14 +/*  modified, and distributed under the terms of the FreeType project      */
  424.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  424.16 +/*  this file you indicate that you have read the license and              */
  424.17 +/*  understand and accept it fully.                                        */
  424.18 +/*                                                                         */
  424.19 +/***************************************************************************/
  424.20 +
  424.21 +  /*************************************************************************/
  424.22 +  /*                                                                       */
  424.23 +  /*  Each module can export one or more `services'.  Each service is      */
  424.24 +  /*  identified by a constant string and modeled by a pointer; the latter */
  424.25 +  /*  generally corresponds to a structure containing function pointers.   */
  424.26 +  /*                                                                       */
  424.27 +  /*  Note that a service's data cannot be a mere function pointer because */
  424.28 +  /*  in C it is possible that function pointers might be implemented      */
  424.29 +  /*  differently than data pointers (e.g. 48 bits instead of 32).         */
  424.30 +  /*                                                                       */
  424.31 +  /*************************************************************************/
  424.32 +
  424.33 +
  424.34 +#ifndef __FTSERV_H__
  424.35 +#define __FTSERV_H__
  424.36 +
  424.37 +
  424.38 +FT_BEGIN_HEADER
  424.39 +
  424.40 +#if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
  424.41 +
  424.42 +  /* we disable the warning `conditional expression is constant' here */
  424.43 +  /* in order to compile cleanly with the maximum level of warnings   */
  424.44 +#pragma warning( disable : 4127 )
  424.45 +
  424.46 +#endif /* _MSC_VER */
  424.47 +
  424.48 +  /*
  424.49 +   * @macro:
  424.50 +   *   FT_FACE_FIND_SERVICE
  424.51 +   *
  424.52 +   * @description:
  424.53 +   *   This macro is used to look up a service from a face's driver module.
  424.54 +   *
  424.55 +   * @input:
  424.56 +   *   face ::
  424.57 +   *     The source face handle.
  424.58 +   *
  424.59 +   *   id ::
  424.60 +   *     A string describing the service as defined in the service's
  424.61 +   *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
  424.62 +   *     `multi-masters').  It is automatically prefixed with
  424.63 +   *     `FT_SERVICE_ID_'.
  424.64 +   *
  424.65 +   * @output:
  424.66 +   *   ptr ::
  424.67 +   *     A variable that receives the service pointer.  Will be NULL
  424.68 +   *     if not found.
  424.69 +   */
  424.70 +#ifdef __cplusplus
  424.71 +
  424.72 +#define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
  424.73 +  FT_BEGIN_STMNT                                                            \
  424.74 +    FT_Module    module = FT_MODULE( FT_FACE( face )->driver );             \
  424.75 +    FT_Pointer   _tmp_  = NULL;                                             \
  424.76 +    FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                              \
  424.77 +                                                                            \
  424.78 +                                                                            \
  424.79 +    if ( module->clazz->get_interface )                                     \
  424.80 +      _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
  424.81 +    *_pptr_ = _tmp_;                                                        \
  424.82 +  FT_END_STMNT
  424.83 +
  424.84 +#else /* !C++ */
  424.85 +
  424.86 +#define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
  424.87 +  FT_BEGIN_STMNT                                                            \
  424.88 +    FT_Module   module = FT_MODULE( FT_FACE( face )->driver );              \
  424.89 +    FT_Pointer  _tmp_  = NULL;                                              \
  424.90 +                                                                            \
  424.91 +    if ( module->clazz->get_interface )                                     \
  424.92 +      _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
  424.93 +    ptr = _tmp_;                                                            \
  424.94 +  FT_END_STMNT
  424.95 +
  424.96 +#endif /* !C++ */
  424.97 +
  424.98 +  /*
  424.99 +   * @macro:
 424.100 +   *   FT_FACE_FIND_GLOBAL_SERVICE
 424.101 +   *
 424.102 +   * @description:
 424.103 +   *   This macro is used to look up a service from all modules.
 424.104 +   *
 424.105 +   * @input:
 424.106 +   *   face ::
 424.107 +   *     The source face handle.
 424.108 +   *
 424.109 +   *   id ::
 424.110 +   *     A string describing the service as defined in the service's
 424.111 +   *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
 424.112 +   *     `multi-masters').  It is automatically prefixed with
 424.113 +   *     `FT_SERVICE_ID_'.
 424.114 +   *
 424.115 +   * @output:
 424.116 +   *   ptr ::
 424.117 +   *     A variable that receives the service pointer.  Will be NULL
 424.118 +   *     if not found.
 424.119 +   */
 424.120 +#ifdef __cplusplus
 424.121 +
 424.122 +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
 424.123 +  FT_BEGIN_STMNT                                                   \
 424.124 +    FT_Module    module = FT_MODULE( FT_FACE( face )->driver );    \
 424.125 +    FT_Pointer   _tmp_;                                            \
 424.126 +    FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                     \
 424.127 +                                                                   \
 424.128 +                                                                   \
 424.129 +    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
 424.130 +    *_pptr_ = _tmp_;                                               \
 424.131 +  FT_END_STMNT
 424.132 +
 424.133 +#else /* !C++ */
 424.134 +
 424.135 +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
 424.136 +  FT_BEGIN_STMNT                                                   \
 424.137 +    FT_Module   module = FT_MODULE( FT_FACE( face )->driver );     \
 424.138 +    FT_Pointer  _tmp_;                                             \
 424.139 +                                                                   \
 424.140 +                                                                   \
 424.141 +    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
 424.142 +    ptr   = _tmp_;                                                 \
 424.143 +  FT_END_STMNT
 424.144 +
 424.145 +#endif /* !C++ */
 424.146 +
 424.147 +
 424.148 +  /*************************************************************************/
 424.149 +  /*************************************************************************/
 424.150 +  /*****                                                               *****/
 424.151 +  /*****         S E R V I C E   D E S C R I P T O R S                 *****/
 424.152 +  /*****                                                               *****/
 424.153 +  /*************************************************************************/
 424.154 +  /*************************************************************************/
 424.155 +
 424.156 +  /*
 424.157 +   *  The following structure is used to _describe_ a given service
 424.158 +   *  to the library.  This is useful to build simple static service lists.
 424.159 +   */
 424.160 +  typedef struct  FT_ServiceDescRec_
 424.161 +  {
 424.162 +    const char*  serv_id;     /* service name         */
 424.163 +    const void*  serv_data;   /* service pointer/data */
 424.164 +
 424.165 +  } FT_ServiceDescRec;
 424.166 +
 424.167 +  typedef const FT_ServiceDescRec*  FT_ServiceDesc;
 424.168 +
 424.169 +  /*************************************************************************/
 424.170 +  /*                                                                       */
 424.171 +  /* <Macro>                                                               */
 424.172 +  /*    FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6             */
 424.173 +  /*                                                                       */
 424.174 +  /* <Description>                                                         */
 424.175 +  /*    Used to initialize an array of FT_ServiceDescRec structs.          */
 424.176 +  /*                                                                       */
 424.177 +  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */
 424.178 +  /*    to called with a pointer where the allocated array is returned.    */
 424.179 +  /*    And when it is no longer needed a Destroy function needs           */
 424.180 +  /*    to be called to release that allocation.                           */
 424.181 +  /*                                                                       */
 424.182 +  /*    These functions should be manyally called from the pic_init and    */
 424.183 +  /*    pic_free functions of your module (see FT_DEFINE_MODULE)           */
 424.184 +  /*                                                                       */
 424.185 +  /*    When FT_CONFIG_OPTION_PIC is not defined the array will be         */
 424.186 +  /*    allocated in the global scope (or the scope where the macro        */
 424.187 +  /*    is used).                                                          */
 424.188 +  /*                                                                       */
 424.189 +#ifndef FT_CONFIG_OPTION_PIC
 424.190 +
 424.191 +#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1)            \
 424.192 +  static const FT_ServiceDescRec class_[] =                                  \
 424.193 +  {                                                                          \
 424.194 +  {serv_id_1, serv_data_1},                                                  \
 424.195 +  {NULL, NULL}                                                               \
 424.196 +  };
 424.197 +#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1,            \
 424.198 +        serv_id_2, serv_data_2)                                              \
 424.199 +  static const FT_ServiceDescRec class_[] =                                  \
 424.200 +  {                                                                          \
 424.201 +  {serv_id_1, serv_data_1},                                                  \
 424.202 +  {serv_id_2, serv_data_2},                                                  \
 424.203 +  {NULL, NULL}                                                               \
 424.204 +  };
 424.205 +#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1,            \
 424.206 +        serv_id_2, serv_data_2, serv_id_3, serv_data_3)                      \
 424.207 +  static const FT_ServiceDescRec class_[] =                                  \
 424.208 +  {                                                                          \
 424.209 +  {serv_id_1, serv_data_1},                                                  \
 424.210 +  {serv_id_2, serv_data_2},                                                  \
 424.211 +  {serv_id_3, serv_data_3},                                                  \
 424.212 +  {NULL, NULL}                                                               \
 424.213 +  };
 424.214 +#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1,            \
 424.215 +        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
 424.216 +        serv_id_4, serv_data_4)                                              \
 424.217 +  static const FT_ServiceDescRec class_[] =                                  \
 424.218 +  {                                                                          \
 424.219 +  {serv_id_1, serv_data_1},                                                  \
 424.220 +  {serv_id_2, serv_data_2},                                                  \
 424.221 +  {serv_id_3, serv_data_3},                                                  \
 424.222 +  {serv_id_4, serv_data_4},                                                  \
 424.223 +  {NULL, NULL}                                                               \
 424.224 +  };
 424.225 +#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1,            \
 424.226 +        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
 424.227 +        serv_id_4, serv_data_4, serv_id_5, serv_data_5)                      \
 424.228 +  static const FT_ServiceDescRec class_[] =                                  \
 424.229 +  {                                                                          \
 424.230 +  {serv_id_1, serv_data_1},                                                  \
 424.231 +  {serv_id_2, serv_data_2},                                                  \
 424.232 +  {serv_id_3, serv_data_3},                                                  \
 424.233 +  {serv_id_4, serv_data_4},                                                  \
 424.234 +  {serv_id_5, serv_data_5},                                                  \
 424.235 +  {NULL, NULL}                                                               \
 424.236 +  };
 424.237 +#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1,            \
 424.238 +        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
 424.239 +        serv_id_4, serv_data_4, serv_id_5, serv_data_5,                      \
 424.240 +        serv_id_6, serv_data_6)                                              \
 424.241 +  static const FT_ServiceDescRec class_[] =                                  \
 424.242 +  {                                                                          \
 424.243 +  {serv_id_1, serv_data_1},                                                  \
 424.244 +  {serv_id_2, serv_data_2},                                                  \
 424.245 +  {serv_id_3, serv_data_3},                                                  \
 424.246 +  {serv_id_4, serv_data_4},                                                  \
 424.247 +  {serv_id_5, serv_data_5},                                                  \
 424.248 +  {serv_id_6, serv_data_6},                                                  \
 424.249 +  {NULL, NULL}                                                               \
 424.250 +  };
 424.251 +
 424.252 +#else /* FT_CONFIG_OPTION_PIC */ 
 424.253 +
 424.254 +#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1)            \
 424.255 +  void                                                                       \
 424.256 +  FT_Destroy_Class_##class_( FT_Library library,                             \
 424.257 +                             FT_ServiceDescRec* clazz )                      \
 424.258 +  {                                                                          \
 424.259 +    FT_Memory memory = library->memory;                                      \
 424.260 +    if ( clazz )                                                             \
 424.261 +      FT_FREE( clazz );                                                      \
 424.262 +  }                                                                          \
 424.263 +                                                                             \
 424.264 +  FT_Error                                                                   \
 424.265 +  FT_Create_Class_##class_( FT_Library library,                              \
 424.266 +                            FT_ServiceDescRec** output_class)                \
 424.267 +  {                                                                          \
 424.268 +    FT_ServiceDescRec*  clazz;                                               \
 424.269 +    FT_Error          error;                                                 \
 424.270 +    FT_Memory memory = library->memory;                                      \
 424.271 +                                                                             \
 424.272 +    if ( FT_ALLOC( clazz, sizeof(*clazz)*2 ) )                               \
 424.273 +      return error;                                                          \
 424.274 +    clazz[0].serv_id = serv_id_1;                                            \
 424.275 +    clazz[0].serv_data = serv_data_1;                                        \
 424.276 +    clazz[1].serv_id = NULL;                                                 \
 424.277 +    clazz[1].serv_data = NULL;                                               \
 424.278 +    *output_class = clazz;                                                   \
 424.279 +    return FT_Err_Ok;                                                        \
 424.280 +  } 
 424.281 +
 424.282 +#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1,            \
 424.283 +        serv_id_2, serv_data_2)                                              \
 424.284 +  void                                                                       \
 424.285 +  FT_Destroy_Class_##class_( FT_Library library,                             \
 424.286 +                             FT_ServiceDescRec* clazz )                      \
 424.287 +  {                                                                          \
 424.288 +    FT_Memory memory = library->memory;                                      \
 424.289 +    if ( clazz )                                                             \
 424.290 +      FT_FREE( clazz );                                                      \
 424.291 +  }                                                                          \
 424.292 +                                                                             \
 424.293 +  FT_Error                                                                   \
 424.294 +  FT_Create_Class_##class_( FT_Library library,                              \
 424.295 +                            FT_ServiceDescRec** output_class)                \
 424.296 +  {                                                                          \
 424.297 +    FT_ServiceDescRec*  clazz;                                               \
 424.298 +    FT_Error          error;                                                 \
 424.299 +    FT_Memory memory = library->memory;                                      \
 424.300 +                                                                             \
 424.301 +    if ( FT_ALLOC( clazz, sizeof(*clazz)*3 ) )                               \
 424.302 +      return error;                                                          \
 424.303 +    clazz[0].serv_id = serv_id_1;                                            \
 424.304 +    clazz[0].serv_data = serv_data_1;                                        \
 424.305 +    clazz[1].serv_id = serv_id_2;                                            \
 424.306 +    clazz[1].serv_data = serv_data_2;                                        \
 424.307 +    clazz[2].serv_id = NULL;                                                 \
 424.308 +    clazz[2].serv_data = NULL;                                               \
 424.309 +    *output_class = clazz;                                                   \
 424.310 +    return FT_Err_Ok;                                                        \
 424.311 +  } 
 424.312 +
 424.313 +#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1,            \
 424.314 +        serv_id_2, serv_data_2, serv_id_3, serv_data_3)                      \
 424.315 +  void                                                                       \
 424.316 +  FT_Destroy_Class_##class_( FT_Library library,                             \
 424.317 +                             FT_ServiceDescRec* clazz )                      \
 424.318 +  {                                                                          \
 424.319 +    FT_Memory memory = library->memory;                                      \
 424.320 +    if ( clazz )                                                             \
 424.321 +      FT_FREE( clazz );                                                      \
 424.322 +  }                                                                          \
 424.323 +                                                                             \
 424.324 +  FT_Error                                                                   \
 424.325 +  FT_Create_Class_##class_( FT_Library library,                              \
 424.326 +                            FT_ServiceDescRec** output_class)                \
 424.327 +  {                                                                          \
 424.328 +    FT_ServiceDescRec*  clazz;                                               \
 424.329 +    FT_Error          error;                                                 \
 424.330 +    FT_Memory memory = library->memory;                                      \
 424.331 +                                                                             \
 424.332 +    if ( FT_ALLOC( clazz, sizeof(*clazz)*4 ) )                               \
 424.333 +      return error;                                                          \
 424.334 +    clazz[0].serv_id = serv_id_1;                                            \
 424.335 +    clazz[0].serv_data = serv_data_1;                                        \
 424.336 +    clazz[1].serv_id = serv_id_2;                                            \
 424.337 +    clazz[1].serv_data = serv_data_2;                                        \
 424.338 +    clazz[2].serv_id = serv_id_3;                                            \
 424.339 +    clazz[2].serv_data = serv_data_3;                                        \
 424.340 +    clazz[3].serv_id = NULL;                                                 \
 424.341 +    clazz[3].serv_data = NULL;                                               \
 424.342 +    *output_class = clazz;                                                   \
 424.343 +    return FT_Err_Ok;                                                        \
 424.344 +  } 
 424.345 +
 424.346 +#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1,            \
 424.347 +        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
 424.348 +        serv_id_4, serv_data_4)                                              \
 424.349 +  void                                                                       \
 424.350 +  FT_Destroy_Class_##class_( FT_Library library,                             \
 424.351 +                             FT_ServiceDescRec* clazz )                      \
 424.352 +  {                                                                          \
 424.353 +    FT_Memory memory = library->memory;                                      \
 424.354 +    if ( clazz )                                                             \
 424.355 +      FT_FREE( clazz );                                                      \
 424.356 +  }                                                                          \
 424.357 +                                                                             \
 424.358 +  FT_Error                                                                   \
 424.359 +  FT_Create_Class_##class_( FT_Library library,                              \
 424.360 +                            FT_ServiceDescRec** output_class)                \
 424.361 +  {                                                                          \
 424.362 +    FT_ServiceDescRec*  clazz;                                               \
 424.363 +    FT_Error          error;                                                 \
 424.364 +    FT_Memory memory = library->memory;                                      \
 424.365 +                                                                             \
 424.366 +    if ( FT_ALLOC( clazz, sizeof(*clazz)*5 ) )                               \
 424.367 +      return error;                                                          \
 424.368 +    clazz[0].serv_id = serv_id_1;                                            \
 424.369 +    clazz[0].serv_data = serv_data_1;                                        \
 424.370 +    clazz[1].serv_id = serv_id_2;                                            \
 424.371 +    clazz[1].serv_data = serv_data_2;                                        \
 424.372 +    clazz[2].serv_id = serv_id_3;                                            \
 424.373 +    clazz[2].serv_data = serv_data_3;                                        \
 424.374 +    clazz[3].serv_id = serv_id_4;                                            \
 424.375 +    clazz[3].serv_data = serv_data_4;                                        \
 424.376 +    clazz[4].serv_id = NULL;                                                 \
 424.377 +    clazz[4].serv_data = NULL;                                               \
 424.378 +    *output_class = clazz;                                                   \
 424.379 +    return FT_Err_Ok;                                                        \
 424.380 +  } 
 424.381 +
 424.382 +#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1,            \
 424.383 +        serv_id_2, serv_data_2, serv_id_3, serv_data_3, serv_id_4,           \
 424.384 +        serv_data_4, serv_id_5, serv_data_5)                                 \
 424.385 +  void                                                                       \
 424.386 +  FT_Destroy_Class_##class_( FT_Library library,                             \
 424.387 +                             FT_ServiceDescRec* clazz )                      \
 424.388 +  {                                                                          \
 424.389 +    FT_Memory memory = library->memory;                                      \
 424.390 +    if ( clazz )                                                             \
 424.391 +      FT_FREE( clazz );                                                      \
 424.392 +  }                                                                          \
 424.393 +                                                                             \
 424.394 +  FT_Error                                                                   \
 424.395 +  FT_Create_Class_##class_( FT_Library library,                              \
 424.396 +                            FT_ServiceDescRec** output_class)                \
 424.397 +  {                                                                          \
 424.398 +    FT_ServiceDescRec*  clazz;                                               \
 424.399 +    FT_Error          error;                                                 \
 424.400 +    FT_Memory memory = library->memory;                                      \
 424.401 +                                                                             \
 424.402 +    if ( FT_ALLOC( clazz, sizeof(*clazz)*6 ) )                               \
 424.403 +      return error;                                                          \
 424.404 +    clazz[0].serv_id = serv_id_1;                                            \
 424.405 +    clazz[0].serv_data = serv_data_1;                                        \
 424.406 +    clazz[1].serv_id = serv_id_2;                                            \
 424.407 +    clazz[1].serv_data = serv_data_2;                                        \
 424.408 +    clazz[2].serv_id = serv_id_3;                                            \
 424.409 +    clazz[2].serv_data = serv_data_3;                                        \
 424.410 +    clazz[3].serv_id = serv_id_4;                                            \
 424.411 +    clazz[3].serv_data = serv_data_4;                                        \
 424.412 +    clazz[4].serv_id = serv_id_5;                                            \
 424.413 +    clazz[4].serv_data = serv_data_5;                                        \
 424.414 +    clazz[5].serv_id = NULL;                                                 \
 424.415 +    clazz[5].serv_data = NULL;                                               \
 424.416 +    *output_class = clazz;                                                   \
 424.417 +    return FT_Err_Ok;                                                        \
 424.418 +  } 
 424.419 +
 424.420 +#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1,            \
 424.421 +        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
 424.422 +        serv_id_4, serv_data_4, serv_id_5, serv_data_5,                      \
 424.423 +        serv_id_6, serv_data_6)                                              \
 424.424 +  void                                                                       \
 424.425 +  FT_Destroy_Class_##class_( FT_Library library,                             \
 424.426 +                             FT_ServiceDescRec* clazz )                      \
 424.427 +  {                                                                          \
 424.428 +    FT_Memory memory = library->memory;                                      \
 424.429 +    if ( clazz )                                                             \
 424.430 +      FT_FREE( clazz );                                                      \
 424.431 +  }                                                                          \
 424.432 +                                                                             \
 424.433 +  FT_Error                                                                   \
 424.434 +  FT_Create_Class_##class_( FT_Library library,                              \
 424.435 +                            FT_ServiceDescRec** output_class)                \
 424.436 +  {                                                                          \
 424.437 +    FT_ServiceDescRec*  clazz;                                               \
 424.438 +    FT_Error          error;                                                 \
 424.439 +    FT_Memory memory = library->memory;                                      \
 424.440 +                                                                             \
 424.441 +    if ( FT_ALLOC( clazz, sizeof(*clazz)*7 ) )                               \
 424.442 +      return error;                                                          \
 424.443 +    clazz[0].serv_id = serv_id_1;                                            \
 424.444 +    clazz[0].serv_data = serv_data_1;                                        \
 424.445 +    clazz[1].serv_id = serv_id_2;                                            \
 424.446 +    clazz[1].serv_data = serv_data_2;                                        \
 424.447 +    clazz[2].serv_id = serv_id_3;                                            \
 424.448 +    clazz[2].serv_data = serv_data_3;                                        \
 424.449 +    clazz[3].serv_id = serv_id_4;                                            \
 424.450 +    clazz[3].serv_data = serv_data_4;                                        \
 424.451 +    clazz[4].serv_id = serv_id_5;                                            \
 424.452 +    clazz[4].serv_data = serv_data_5;                                        \
 424.453 +    clazz[5].serv_id = serv_id_6;                                            \
 424.454 +    clazz[5].serv_data = serv_data_6;                                        \
 424.455 +    clazz[6].serv_id = NULL;                                                 \
 424.456 +    clazz[6].serv_data = NULL;                                               \
 424.457 +    *output_class = clazz;                                                   \
 424.458 +    return FT_Err_Ok;                                                        \
 424.459 +  } 
 424.460 +#endif /* FT_CONFIG_OPTION_PIC */ 
 424.461 +
 424.462 +  /*
 424.463 +   *  Parse a list of FT_ServiceDescRec descriptors and look for
 424.464 +   *  a specific service by ID.  Note that the last element in the
 424.465 +   *  array must be { NULL, NULL }, and that the function should
 424.466 +   *  return NULL if the service isn't available.
 424.467 +   *
 424.468 +   *  This function can be used by modules to implement their
 424.469 +   *  `get_service' method.
 424.470 +   */
 424.471 +  FT_BASE( FT_Pointer )
 424.472 +  ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
 424.473 +                          const char*     service_id );
 424.474 +
 424.475 +
 424.476 +  /*************************************************************************/
 424.477 +  /*************************************************************************/
 424.478 +  /*****                                                               *****/
 424.479 +  /*****             S E R V I C E S   C A C H E                       *****/
 424.480 +  /*****                                                               *****/
 424.481 +  /*************************************************************************/
 424.482 +  /*************************************************************************/
 424.483 +
 424.484 +  /*
 424.485 +   *  This structure is used to store a cache for several frequently used
 424.486 +   *  services.  It is the type of `face->internal->services'.  You
 424.487 +   *  should only use FT_FACE_LOOKUP_SERVICE to access it.
 424.488 +   *
 424.489 +   *  All fields should have the type FT_Pointer to relax compilation
 424.490 +   *  dependencies.  We assume the developer isn't completely stupid.
 424.491 +   *
 424.492 +   *  Each field must be named `service_XXXX' where `XXX' corresponds to
 424.493 +   *  the correct FT_SERVICE_ID_XXXX macro.  See the definition of
 424.494 +   *  FT_FACE_LOOKUP_SERVICE below how this is implemented.
 424.495 +   *
 424.496 +   */
 424.497 +  typedef struct  FT_ServiceCacheRec_
 424.498 +  {
 424.499 +    FT_Pointer  service_POSTSCRIPT_FONT_NAME;
 424.500 +    FT_Pointer  service_MULTI_MASTERS;
 424.501 +    FT_Pointer  service_GLYPH_DICT;
 424.502 +    FT_Pointer  service_PFR_METRICS;
 424.503 +    FT_Pointer  service_WINFNT;
 424.504 +
 424.505 +  } FT_ServiceCacheRec, *FT_ServiceCache;
 424.506 +
 424.507 +
 424.508 +  /*
 424.509 +   *  A magic number used within the services cache.
 424.510 +   */
 424.511 +#define FT_SERVICE_UNAVAILABLE  ((FT_Pointer)-2)  /* magic number */
 424.512 +
 424.513 +
 424.514 +  /*
 424.515 +   * @macro:
 424.516 +   *   FT_FACE_LOOKUP_SERVICE
 424.517 +   *
 424.518 +   * @description:
 424.519 +   *   This macro is used to lookup a service from a face's driver module
 424.520 +   *   using its cache.
 424.521 +   *
 424.522 +   * @input:
 424.523 +   *   face::
 424.524 +   *     The source face handle containing the cache.
 424.525 +   *
 424.526 +   *   field ::
 424.527 +   *     The field name in the cache.
 424.528 +   *
 424.529 +   *   id ::
 424.530 +   *     The service ID.
 424.531 +   *
 424.532 +   * @output:
 424.533 +   *   ptr ::
 424.534 +   *     A variable receiving the service data.  NULL if not available.
 424.535 +   */
 424.536 +#ifdef __cplusplus
 424.537 +
 424.538 +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
 424.539 +  FT_BEGIN_STMNT                                               \
 424.540 +    FT_Pointer   svc;                                          \
 424.541 +    FT_Pointer*  Pptr = (FT_Pointer*)&(ptr);                   \
 424.542 +                                                               \
 424.543 +                                                               \
 424.544 +    svc = FT_FACE( face )->internal->services. service_ ## id; \
 424.545 +    if ( svc == FT_SERVICE_UNAVAILABLE )                       \
 424.546 +      svc = NULL;                                              \
 424.547 +    else if ( svc == NULL )                                    \
 424.548 +    {                                                          \
 424.549 +      FT_FACE_FIND_SERVICE( face, svc, id );                   \
 424.550 +                                                               \
 424.551 +      FT_FACE( face )->internal->services. service_ ## id =    \
 424.552 +        (FT_Pointer)( svc != NULL ? svc                        \
 424.553 +                                  : FT_SERVICE_UNAVAILABLE );  \
 424.554 +    }                                                          \
 424.555 +    *Pptr = svc;                                               \
 424.556 +  FT_END_STMNT
 424.557 +
 424.558 +#else /* !C++ */
 424.559 +
 424.560 +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
 424.561 +  FT_BEGIN_STMNT                                               \
 424.562 +    FT_Pointer  svc;                                           \
 424.563 +                                                               \
 424.564 +                                                               \
 424.565 +    svc = FT_FACE( face )->internal->services. service_ ## id; \
 424.566 +    if ( svc == FT_SERVICE_UNAVAILABLE )                       \
 424.567 +      svc = NULL;                                              \
 424.568 +    else if ( svc == NULL )                                    \
 424.569 +    {                                                          \
 424.570 +      FT_FACE_FIND_SERVICE( face, svc, id );                   \
 424.571 +                                                               \
 424.572 +      FT_FACE( face )->internal->services. service_ ## id =    \
 424.573 +        (FT_Pointer)( svc != NULL ? svc                        \
 424.574 +                                  : FT_SERVICE_UNAVAILABLE );  \
 424.575 +    }                                                          \
 424.576 +    ptr = svc;                                                 \
 424.577 +  FT_END_STMNT
 424.578 +
 424.579 +#endif /* !C++ */
 424.580 +
 424.581 +  /*
 424.582 +   *  A macro used to define new service structure types.
 424.583 +   */
 424.584 +
 424.585 +#define FT_DEFINE_SERVICE( name )            \
 424.586 +  typedef struct FT_Service_ ## name ## Rec_ \
 424.587 +    FT_Service_ ## name ## Rec ;             \
 424.588 +  typedef struct FT_Service_ ## name ## Rec_ \
 424.589 +    const * FT_Service_ ## name ;            \
 424.590 +  struct FT_Service_ ## name ## Rec_
 424.591 +
 424.592 +  /* */
 424.593 +
 424.594 +  /*
 424.595 +   *  The header files containing the services.
 424.596 +   */
 424.597 +
 424.598 +#define FT_SERVICE_BDF_H                <freetype/internal/services/svbdf.h>
 424.599 +#define FT_SERVICE_CID_H                <freetype/internal/services/svcid.h>
 424.600 +#define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>
 424.601 +#define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>
 424.602 +#define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>
 424.603 +#define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>
 424.604 +#define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>
 424.605 +#define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>
 424.606 +#define FT_SERVICE_POSTSCRIPT_CMAPS_H   <freetype/internal/services/svpscmap.h>
 424.607 +#define FT_SERVICE_POSTSCRIPT_INFO_H    <freetype/internal/services/svpsinfo.h>
 424.608 +#define FT_SERVICE_POSTSCRIPT_NAME_H    <freetype/internal/services/svpostnm.h>
 424.609 +#define FT_SERVICE_SFNT_H               <freetype/internal/services/svsfnt.h>
 424.610 +#define FT_SERVICE_TRUETYPE_ENGINE_H    <freetype/internal/services/svtteng.h>
 424.611 +#define FT_SERVICE_TT_CMAP_H            <freetype/internal/services/svttcmap.h>
 424.612 +#define FT_SERVICE_WINFNT_H             <freetype/internal/services/svwinfnt.h>
 424.613 +#define FT_SERVICE_XFREE86_NAME_H       <freetype/internal/services/svxf86nm.h>
 424.614 +#define FT_SERVICE_TRUETYPE_GLYF_H      <freetype/internal/services/svttglyf.h>
 424.615 +
 424.616 + /* */
 424.617 +
 424.618 +FT_END_HEADER
 424.619 +
 424.620 +#endif /* __FTSERV_H__ */
 424.621 +
 424.622 +
 424.623 +/* END */
   425.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   425.2 +++ b/libs/ft2static/freetype/internal/ftstream.h	Sat Feb 01 19:58:19 2014 +0200
   425.3 @@ -0,0 +1,539 @@
   425.4 +/***************************************************************************/
   425.5 +/*                                                                         */
   425.6 +/*  ftstream.h                                                             */
   425.7 +/*                                                                         */
   425.8 +/*    Stream handling (specification).                                     */
   425.9 +/*                                                                         */
  425.10 +/*  Copyright 1996-2001, 2002, 2004, 2005, 2006 by                         */
  425.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  425.12 +/*                                                                         */
  425.13 +/*  This file is part of the FreeType project, and may only be used,       */
  425.14 +/*  modified, and distributed under the terms of the FreeType project      */
  425.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  425.16 +/*  this file you indicate that you have read the license and              */
  425.17 +/*  understand and accept it fully.                                        */
  425.18 +/*                                                                         */
  425.19 +/***************************************************************************/
  425.20 +
  425.21 +
  425.22 +#ifndef __FTSTREAM_H__
  425.23 +#define __FTSTREAM_H__
  425.24 +
  425.25 +
  425.26 +#include <ft2build.h>
  425.27 +#include FT_SYSTEM_H
  425.28 +#include FT_INTERNAL_OBJECTS_H
  425.29 +
  425.30 +
  425.31 +FT_BEGIN_HEADER
  425.32 +
  425.33 +
  425.34 +  /* format of an 8-bit frame_op value:           */
  425.35 +  /*                                              */
  425.36 +  /* bit  76543210                                */
  425.37 +  /*      xxxxxxes                                */
  425.38 +  /*                                              */
  425.39 +  /* s is set to 1 if the value is signed.        */
  425.40 +  /* e is set to 1 if the value is little-endian. */
  425.41 +  /* xxx is a command.                            */
  425.42 +
  425.43 +#define FT_FRAME_OP_SHIFT         2
  425.44 +#define FT_FRAME_OP_SIGNED        1
  425.45 +#define FT_FRAME_OP_LITTLE        2
  425.46 +#define FT_FRAME_OP_COMMAND( x )  ( x >> FT_FRAME_OP_SHIFT )
  425.47 +
  425.48 +#define FT_MAKE_FRAME_OP( command, little, sign ) \
  425.49 +          ( ( command << FT_FRAME_OP_SHIFT ) | ( little << 1 ) | sign )
  425.50 +
  425.51 +#define FT_FRAME_OP_END    0
  425.52 +#define FT_FRAME_OP_START  1  /* start a new frame     */
  425.53 +#define FT_FRAME_OP_BYTE   2  /* read 1-byte value     */
  425.54 +#define FT_FRAME_OP_SHORT  3  /* read 2-byte value     */
  425.55 +#define FT_FRAME_OP_LONG   4  /* read 4-byte value     */
  425.56 +#define FT_FRAME_OP_OFF3   5  /* read 3-byte value     */
  425.57 +#define FT_FRAME_OP_BYTES  6  /* read a bytes sequence */
  425.58 +
  425.59 +
  425.60 +  typedef enum  FT_Frame_Op_
  425.61 +  {
  425.62 +    ft_frame_end       = 0,
  425.63 +    ft_frame_start     = FT_MAKE_FRAME_OP( FT_FRAME_OP_START, 0, 0 ),
  425.64 +
  425.65 +    ft_frame_byte      = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE,  0, 0 ),
  425.66 +    ft_frame_schar     = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE,  0, 1 ),
  425.67 +
  425.68 +    ft_frame_ushort_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 0 ),
  425.69 +    ft_frame_short_be  = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 1 ),
  425.70 +    ft_frame_ushort_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 0 ),
  425.71 +    ft_frame_short_le  = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 1 ),
  425.72 +
  425.73 +    ft_frame_ulong_be  = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 0 ),
  425.74 +    ft_frame_long_be   = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 1 ),
  425.75 +    ft_frame_ulong_le  = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 0 ),
  425.76 +    ft_frame_long_le   = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 1 ),
  425.77 +
  425.78 +    ft_frame_uoff3_be  = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 0 ),
  425.79 +    ft_frame_off3_be   = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 1 ),
  425.80 +    ft_frame_uoff3_le  = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 0 ),
  425.81 +    ft_frame_off3_le   = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 1 ),
  425.82 +
  425.83 +    ft_frame_bytes     = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 0 ),
  425.84 +    ft_frame_skip      = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 1 )
  425.85 +
  425.86 +  } FT_Frame_Op;
  425.87 +
  425.88 +
  425.89 +  typedef struct  FT_Frame_Field_
  425.90 +  {
  425.91 +    FT_Byte    value;
  425.92 +    FT_Byte    size;
  425.93 +    FT_UShort  offset;
  425.94 +
  425.95 +  } FT_Frame_Field;
  425.96 +
  425.97 +
  425.98 +  /* Construct an FT_Frame_Field out of a structure type and a field name. */
  425.99 +  /* The structure type must be set in the FT_STRUCTURE macro before       */
 425.100 +  /* calling the FT_FRAME_START() macro.                                   */
 425.101 +  /*                                                                       */
 425.102 +#define FT_FIELD_SIZE( f ) \
 425.103 +          (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f )
 425.104 +
 425.105 +#define FT_FIELD_SIZE_DELTA( f ) \
 425.106 +          (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f[0] )
 425.107 +
 425.108 +#define FT_FIELD_OFFSET( f ) \
 425.109 +          (FT_UShort)( offsetof( FT_STRUCTURE, f ) )
 425.110 +
 425.111 +#define FT_FRAME_FIELD( frame_op, field ) \
 425.112 +          {                               \
 425.113 +            frame_op,                     \
 425.114 +            FT_FIELD_SIZE( field ),       \
 425.115 +            FT_FIELD_OFFSET( field )      \
 425.116 +          }
 425.117 +
 425.118 +#define FT_MAKE_EMPTY_FIELD( frame_op )  { frame_op, 0, 0 }
 425.119 +
 425.120 +#define FT_FRAME_START( size )   { ft_frame_start, 0, size }
 425.121 +#define FT_FRAME_END             { ft_frame_end, 0, 0 }
 425.122 +
 425.123 +#define FT_FRAME_LONG( f )       FT_FRAME_FIELD( ft_frame_long_be, f )
 425.124 +#define FT_FRAME_ULONG( f )      FT_FRAME_FIELD( ft_frame_ulong_be, f )
 425.125 +#define FT_FRAME_SHORT( f )      FT_FRAME_FIELD( ft_frame_short_be, f )
 425.126 +#define FT_FRAME_USHORT( f )     FT_FRAME_FIELD( ft_frame_ushort_be, f )
 425.127 +#define FT_FRAME_OFF3( f )       FT_FRAME_FIELD( ft_frame_off3_be, f )
 425.128 +#define FT_FRAME_UOFF3( f )      FT_FRAME_FIELD( ft_frame_uoff3_be, f )
 425.129 +#define FT_FRAME_BYTE( f )       FT_FRAME_FIELD( ft_frame_byte, f )
 425.130 +#define FT_FRAME_CHAR( f )       FT_FRAME_FIELD( ft_frame_schar, f )
 425.131 +
 425.132 +#define FT_FRAME_LONG_LE( f )    FT_FRAME_FIELD( ft_frame_long_le, f )
 425.133 +#define FT_FRAME_ULONG_LE( f )   FT_FRAME_FIELD( ft_frame_ulong_le, f )
 425.134 +#define FT_FRAME_SHORT_LE( f )   FT_FRAME_FIELD( ft_frame_short_le, f )
 425.135 +#define FT_FRAME_USHORT_LE( f )  FT_FRAME_FIELD( ft_frame_ushort_le, f )
 425.136 +#define FT_FRAME_OFF3_LE( f )    FT_FRAME_FIELD( ft_frame_off3_le, f )
 425.137 +#define FT_FRAME_UOFF3_LE( f )   FT_FRAME_FIELD( ft_frame_uoff3_le, f )
 425.138 +
 425.139 +#define FT_FRAME_SKIP_LONG       { ft_frame_long_be, 0, 0 }
 425.140 +#define FT_FRAME_SKIP_SHORT      { ft_frame_short_be, 0, 0 }
 425.141 +#define FT_FRAME_SKIP_BYTE       { ft_frame_byte, 0, 0 }
 425.142 +
 425.143 +#define FT_FRAME_BYTES( field, count ) \
 425.144 +          {                            \
 425.145 +            ft_frame_bytes,            \
 425.146 +            count,                     \
 425.147 +            FT_FIELD_OFFSET( field )   \
 425.148 +          }
 425.149 +
 425.150 +#define FT_FRAME_SKIP_BYTES( count )  { ft_frame_skip, count, 0 }
 425.151 +
 425.152 +
 425.153 +  /*************************************************************************/
 425.154 +  /*                                                                       */
 425.155 +  /* Integer extraction macros -- the `buffer' parameter must ALWAYS be of */
 425.156 +  /* type `char*' or equivalent (1-byte elements).                         */
 425.157 +  /*                                                                       */
 425.158 +
 425.159 +#define FT_BYTE_( p, i )  ( ((const FT_Byte*)(p))[(i)] )
 425.160 +#define FT_INT8_( p, i )  ( ((const FT_Char*)(p))[(i)] )
 425.161 +
 425.162 +#define FT_INT16( x )   ( (FT_Int16)(x)  )
 425.163 +#define FT_UINT16( x )  ( (FT_UInt16)(x) )
 425.164 +#define FT_INT32( x )   ( (FT_Int32)(x)  )
 425.165 +#define FT_UINT32( x )  ( (FT_UInt32)(x) )
 425.166 +
 425.167 +#define FT_BYTE_I16( p, i, s )  ( FT_INT16(  FT_BYTE_( p, i ) ) << (s) )
 425.168 +#define FT_BYTE_U16( p, i, s )  ( FT_UINT16( FT_BYTE_( p, i ) ) << (s) )
 425.169 +#define FT_BYTE_I32( p, i, s )  ( FT_INT32(  FT_BYTE_( p, i ) ) << (s) )
 425.170 +#define FT_BYTE_U32( p, i, s )  ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) )
 425.171 +
 425.172 +#define FT_INT8_I16( p, i, s )  ( FT_INT16(  FT_INT8_( p, i ) ) << (s) )
 425.173 +#define FT_INT8_U16( p, i, s )  ( FT_UINT16( FT_INT8_( p, i ) ) << (s) )
 425.174 +#define FT_INT8_I32( p, i, s )  ( FT_INT32(  FT_INT8_( p, i ) ) << (s) )
 425.175 +#define FT_INT8_U32( p, i, s )  ( FT_UINT32( FT_INT8_( p, i ) ) << (s) )
 425.176 +
 425.177 +
 425.178 +#define FT_PEEK_SHORT( p )  FT_INT16( FT_INT8_I16( p, 0, 8) | \
 425.179 +                                      FT_BYTE_I16( p, 1, 0) )
 425.180 +
 425.181 +#define FT_PEEK_USHORT( p )  FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \
 425.182 +                                        FT_BYTE_U16( p, 1, 0 ) )
 425.183 +
 425.184 +#define FT_PEEK_LONG( p )  FT_INT32( FT_INT8_I32( p, 0, 24 ) | \
 425.185 +                                     FT_BYTE_I32( p, 1, 16 ) | \
 425.186 +                                     FT_BYTE_I32( p, 2,  8 ) | \
 425.187 +                                     FT_BYTE_I32( p, 3,  0 ) )
 425.188 +
 425.189 +#define FT_PEEK_ULONG( p )  FT_UINT32( FT_BYTE_U32( p, 0, 24 ) | \
 425.190 +                                       FT_BYTE_U32( p, 1, 16 ) | \
 425.191 +                                       FT_BYTE_U32( p, 2,  8 ) | \
 425.192 +                                       FT_BYTE_U32( p, 3,  0 ) )
 425.193 +
 425.194 +#define FT_PEEK_OFF3( p )  FT_INT32( FT_INT8_I32( p, 0, 16 ) | \
 425.195 +                                     FT_BYTE_I32( p, 1,  8 ) | \
 425.196 +                                     FT_BYTE_I32( p, 2,  0 ) )
 425.197 +
 425.198 +#define FT_PEEK_UOFF3( p )  FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \
 425.199 +                                       FT_BYTE_U32( p, 1,  8 ) | \
 425.200 +                                       FT_BYTE_U32( p, 2,  0 ) )
 425.201 +
 425.202 +#define FT_PEEK_SHORT_LE( p )  FT_INT16( FT_INT8_I16( p, 1, 8 ) | \
 425.203 +                                         FT_BYTE_I16( p, 0, 0 ) )
 425.204 +
 425.205 +#define FT_PEEK_USHORT_LE( p )  FT_UINT16( FT_BYTE_U16( p, 1, 8 ) |  \
 425.206 +                                           FT_BYTE_U16( p, 0, 0 ) )
 425.207 +
 425.208 +#define FT_PEEK_LONG_LE( p )  FT_INT32( FT_INT8_I32( p, 3, 24 ) | \
 425.209 +                                        FT_BYTE_I32( p, 2, 16 ) | \
 425.210 +                                        FT_BYTE_I32( p, 1,  8 ) | \
 425.211 +                                        FT_BYTE_I32( p, 0,  0 ) )
 425.212 +
 425.213 +#define FT_PEEK_ULONG_LE( p )  FT_UINT32( FT_BYTE_U32( p, 3, 24 ) | \
 425.214 +                                          FT_BYTE_U32( p, 2, 16 ) | \
 425.215 +                                          FT_BYTE_U32( p, 1,  8 ) | \
 425.216 +                                          FT_BYTE_U32( p, 0,  0 ) )
 425.217 +
 425.218 +#define FT_PEEK_OFF3_LE( p )  FT_INT32( FT_INT8_I32( p, 2, 16 ) | \
 425.219 +                                        FT_BYTE_I32( p, 1,  8 ) | \
 425.220 +                                        FT_BYTE_I32( p, 0,  0 ) )
 425.221 +
 425.222 +#define FT_PEEK_UOFF3_LE( p )  FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \
 425.223 +                                          FT_BYTE_U32( p, 1,  8 ) | \
 425.224 +                                          FT_BYTE_U32( p, 0,  0 ) )
 425.225 +
 425.226 +
 425.227 +#define FT_NEXT_CHAR( buffer )       \
 425.228 +          ( (signed char)*buffer++ )
 425.229 +
 425.230 +#define FT_NEXT_BYTE( buffer )         \
 425.231 +          ( (unsigned char)*buffer++ )
 425.232 +
 425.233 +#define FT_NEXT_SHORT( buffer )                                   \
 425.234 +          ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) )
 425.235 +
 425.236 +#define FT_NEXT_USHORT( buffer )                                            \
 425.237 +          ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) )
 425.238 +
 425.239 +#define FT_NEXT_OFF3( buffer )                                  \
 425.240 +          ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) )
 425.241 +
 425.242 +#define FT_NEXT_UOFF3( buffer )                                           \
 425.243 +          ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) )
 425.244 +
 425.245 +#define FT_NEXT_LONG( buffer )                                  \
 425.246 +          ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) )
 425.247 +
 425.248 +#define FT_NEXT_ULONG( buffer )                                           \
 425.249 +          ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) )
 425.250 +
 425.251 +
 425.252 +#define FT_NEXT_SHORT_LE( buffer )                                   \
 425.253 +          ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) )
 425.254 +
 425.255 +#define FT_NEXT_USHORT_LE( buffer )                                            \
 425.256 +          ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) )
 425.257 +
 425.258 +#define FT_NEXT_OFF3_LE( buffer )                                  \
 425.259 +          ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) )
 425.260 +
 425.261 +#define FT_NEXT_UOFF3_LE( buffer )                                           \
 425.262 +          ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) )
 425.263 +
 425.264 +#define FT_NEXT_LONG_LE( buffer )                                  \
 425.265 +          ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) )
 425.266 +
 425.267 +#define FT_NEXT_ULONG_LE( buffer )                                           \
 425.268 +          ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) )
 425.269 +
 425.270 +
 425.271 +  /*************************************************************************/
 425.272 +  /*                                                                       */
 425.273 +  /* Each GET_xxxx() macro uses an implicit `stream' variable.             */
 425.274 +  /*                                                                       */
 425.275 +#if 0
 425.276 +#define FT_GET_MACRO( type )    FT_NEXT_ ## type ( stream->cursor )
 425.277 +
 425.278 +#define FT_GET_CHAR()       FT_GET_MACRO( CHAR )
 425.279 +#define FT_GET_BYTE()       FT_GET_MACRO( BYTE )
 425.280 +#define FT_GET_SHORT()      FT_GET_MACRO( SHORT )
 425.281 +#define FT_GET_USHORT()     FT_GET_MACRO( USHORT )
 425.282 +#define FT_GET_OFF3()       FT_GET_MACRO( OFF3 )
 425.283 +#define FT_GET_UOFF3()      FT_GET_MACRO( UOFF3 )
 425.284 +#define FT_GET_LONG()       FT_GET_MACRO( LONG )
 425.285 +#define FT_GET_ULONG()      FT_GET_MACRO( ULONG )
 425.286 +#define FT_GET_TAG4()       FT_GET_MACRO( ULONG )
 425.287 +
 425.288 +#define FT_GET_SHORT_LE()   FT_GET_MACRO( SHORT_LE )
 425.289 +#define FT_GET_USHORT_LE()  FT_GET_MACRO( USHORT_LE )
 425.290 +#define FT_GET_LONG_LE()    FT_GET_MACRO( LONG_LE )
 425.291 +#define FT_GET_ULONG_LE()   FT_GET_MACRO( ULONG_LE )
 425.292 +
 425.293 +#else
 425.294 +#define FT_GET_MACRO( func, type )        ( (type)func( stream ) )
 425.295 +
 425.296 +#define FT_GET_CHAR()       FT_GET_MACRO( FT_Stream_GetChar, FT_Char )
 425.297 +#define FT_GET_BYTE()       FT_GET_MACRO( FT_Stream_GetChar, FT_Byte )
 425.298 +#define FT_GET_SHORT()      FT_GET_MACRO( FT_Stream_GetShort, FT_Short )
 425.299 +#define FT_GET_USHORT()     FT_GET_MACRO( FT_Stream_GetShort, FT_UShort )
 425.300 +#define FT_GET_OFF3()       FT_GET_MACRO( FT_Stream_GetOffset, FT_Long )
 425.301 +#define FT_GET_UOFF3()      FT_GET_MACRO( FT_Stream_GetOffset, FT_ULong )
 425.302 +#define FT_GET_LONG()       FT_GET_MACRO( FT_Stream_GetLong, FT_Long )
 425.303 +#define FT_GET_ULONG()      FT_GET_MACRO( FT_Stream_GetLong, FT_ULong )
 425.304 +#define FT_GET_TAG4()       FT_GET_MACRO( FT_Stream_GetLong, FT_ULong )
 425.305 +
 425.306 +#define FT_GET_SHORT_LE()   FT_GET_MACRO( FT_Stream_GetShortLE, FT_Short )
 425.307 +#define FT_GET_USHORT_LE()  FT_GET_MACRO( FT_Stream_GetShortLE, FT_UShort )
 425.308 +#define FT_GET_LONG_LE()    FT_GET_MACRO( FT_Stream_GetLongLE, FT_Long )
 425.309 +#define FT_GET_ULONG_LE()   FT_GET_MACRO( FT_Stream_GetLongLE, FT_ULong )
 425.310 +#endif
 425.311 +
 425.312 +#define FT_READ_MACRO( func, type, var )        \
 425.313 +          ( var = (type)func( stream, &error ), \
 425.314 +            error != FT_Err_Ok )
 425.315 +
 425.316 +#define FT_READ_BYTE( var )       FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var )
 425.317 +#define FT_READ_CHAR( var )       FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var )
 425.318 +#define FT_READ_SHORT( var )      FT_READ_MACRO( FT_Stream_ReadShort, FT_Short, var )
 425.319 +#define FT_READ_USHORT( var )     FT_READ_MACRO( FT_Stream_ReadShort, FT_UShort, var )
 425.320 +#define FT_READ_OFF3( var )       FT_READ_MACRO( FT_Stream_ReadOffset, FT_Long, var )
 425.321 +#define FT_READ_UOFF3( var )      FT_READ_MACRO( FT_Stream_ReadOffset, FT_ULong, var )
 425.322 +#define FT_READ_LONG( var )       FT_READ_MACRO( FT_Stream_ReadLong, FT_Long, var )
 425.323 +#define FT_READ_ULONG( var )      FT_READ_MACRO( FT_Stream_ReadLong, FT_ULong, var )
 425.324 +
 425.325 +#define FT_READ_SHORT_LE( var )   FT_READ_MACRO( FT_Stream_ReadShortLE, FT_Short, var )
 425.326 +#define FT_READ_USHORT_LE( var )  FT_READ_MACRO( FT_Stream_ReadShortLE, FT_UShort, var )
 425.327 +#define FT_READ_LONG_LE( var )    FT_READ_MACRO( FT_Stream_ReadLongLE, FT_Long, var )
 425.328 +#define FT_READ_ULONG_LE( var )   FT_READ_MACRO( FT_Stream_ReadLongLE, FT_ULong, var )
 425.329 +
 425.330 +
 425.331 +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
 425.332 +
 425.333 +  /* initialize a stream for reading a regular system stream */
 425.334 +  FT_BASE( FT_Error )
 425.335 +  FT_Stream_Open( FT_Stream    stream,
 425.336 +                  const char*  filepathname );
 425.337 +
 425.338 +#endif /* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */
 425.339 +
 425.340 +
 425.341 +  /* create a new (input) stream from an FT_Open_Args structure */
 425.342 +  FT_BASE( FT_Error )
 425.343 +  FT_Stream_New( FT_Library           library,
 425.344 +                 const FT_Open_Args*  args,
 425.345 +                 FT_Stream           *astream );
 425.346 +
 425.347 +  /* free a stream */
 425.348 +  FT_BASE( void )
 425.349 +  FT_Stream_Free( FT_Stream  stream,
 425.350 +                  FT_Int     external );
 425.351 +
 425.352 +  /* initialize a stream for reading in-memory data */
 425.353 +  FT_BASE( void )
 425.354 +  FT_Stream_OpenMemory( FT_Stream       stream,
 425.355 +                        const FT_Byte*  base,
 425.356 +                        FT_ULong        size );
 425.357 +
 425.358 +  /* close a stream (does not destroy the stream structure) */
 425.359 +  FT_BASE( void )
 425.360 +  FT_Stream_Close( FT_Stream  stream );
 425.361 +
 425.362 +
 425.363 +  /* seek within a stream. position is relative to start of stream */
 425.364 +  FT_BASE( FT_Error )
 425.365 +  FT_Stream_Seek( FT_Stream  stream,
 425.366 +                  FT_ULong   pos );
 425.367 +
 425.368 +  /* skip bytes in a stream */
 425.369 +  FT_BASE( FT_Error )
 425.370 +  FT_Stream_Skip( FT_Stream  stream,
 425.371 +                  FT_Long    distance );
 425.372 +
 425.373 +  /* return current stream position */
 425.374 +  FT_BASE( FT_Long )
 425.375 +  FT_Stream_Pos( FT_Stream  stream );
 425.376 +
 425.377 +  /* read bytes from a stream into a user-allocated buffer, returns an */
 425.378 +  /* error if not all bytes could be read.                             */
 425.379 +  FT_BASE( FT_Error )
 425.380 +  FT_Stream_Read( FT_Stream  stream,
 425.381 +                  FT_Byte*   buffer,
 425.382 +                  FT_ULong   count );
 425.383 +
 425.384 +  /* read bytes from a stream at a given position */
 425.385 +  FT_BASE( FT_Error )
 425.386 +  FT_Stream_ReadAt( FT_Stream  stream,
 425.387 +                    FT_ULong   pos,
 425.388 +                    FT_Byte*   buffer,
 425.389 +                    FT_ULong   count );
 425.390 +
 425.391 +  /* try to read bytes at the end of a stream; return number of bytes */
 425.392 +  /* really available                                                 */
 425.393 +  FT_BASE( FT_ULong )
 425.394 +  FT_Stream_TryRead( FT_Stream  stream,
 425.395 +                     FT_Byte*   buffer,
 425.396 +                     FT_ULong   count );
 425.397 +
 425.398 +  /* Enter a frame of `count' consecutive bytes in a stream.  Returns an */
 425.399 +  /* error if the frame could not be read/accessed.  The caller can use  */
 425.400 +  /* the FT_Stream_Get_XXX functions to retrieve frame data without      */
 425.401 +  /* error checks.                                                       */
 425.402 +  /*                                                                     */
 425.403 +  /* You must _always_ call FT_Stream_ExitFrame() once you have entered  */
 425.404 +  /* a stream frame!                                                     */
 425.405 +  /*                                                                     */
 425.406 +  FT_BASE( FT_Error )
 425.407 +  FT_Stream_EnterFrame( FT_Stream  stream,
 425.408 +                        FT_ULong   count );
 425.409 +
 425.410 +  /* exit a stream frame */
 425.411 +  FT_BASE( void )
 425.412 +  FT_Stream_ExitFrame( FT_Stream  stream );
 425.413 +
 425.414 +  /* Extract a stream frame.  If the stream is disk-based, a heap block */
 425.415 +  /* is allocated and the frame bytes are read into it.  If the stream  */
 425.416 +  /* is memory-based, this function simply set a pointer to the data.   */
 425.417 +  /*                                                                    */
 425.418 +  /* Useful to optimize access to memory-based streams transparently.   */
 425.419 +  /*                                                                    */
 425.420 +  /* All extracted frames must be `freed' with a call to the function   */
 425.421 +  /* FT_Stream_ReleaseFrame().                                          */
 425.422 +  /*                                                                    */
 425.423 +  FT_BASE( FT_Error )
 425.424 +  FT_Stream_ExtractFrame( FT_Stream  stream,
 425.425 +                          FT_ULong   count,
 425.426 +                          FT_Byte**  pbytes );
 425.427 +
 425.428 +  /* release an extract frame (see FT_Stream_ExtractFrame) */
 425.429 +  FT_BASE( void )
 425.430 +  FT_Stream_ReleaseFrame( FT_Stream  stream,
 425.431 +                          FT_Byte**  pbytes );
 425.432 +
 425.433 +  /* read a byte from an entered frame */
 425.434 +  FT_BASE( FT_Char )
 425.435 +  FT_Stream_GetChar( FT_Stream  stream );
 425.436 +
 425.437 +  /* read a 16-bit big-endian integer from an entered frame */
 425.438 +  FT_BASE( FT_Short )
 425.439 +  FT_Stream_GetShort( FT_Stream  stream );
 425.440 +
 425.441 +  /* read a 24-bit big-endian integer from an entered frame */
 425.442 +  FT_BASE( FT_Long )
 425.443 +  FT_Stream_GetOffset( FT_Stream  stream );
 425.444 +
 425.445 +  /* read a 32-bit big-endian integer from an entered frame */
 425.446 +  FT_BASE( FT_Long )
 425.447 +  FT_Stream_GetLong( FT_Stream  stream );
 425.448 +
 425.449 +  /* read a 16-bit little-endian integer from an entered frame */
 425.450 +  FT_BASE( FT_Short )
 425.451 +  FT_Stream_GetShortLE( FT_Stream  stream );
 425.452 +
 425.453 +  /* read a 32-bit little-endian integer from an entered frame */
 425.454 +  FT_BASE( FT_Long )
 425.455 +  FT_Stream_GetLongLE( FT_Stream  stream );
 425.456 +
 425.457 +
 425.458 +  /* read a byte from a stream */
 425.459 +  FT_BASE( FT_Char )
 425.460 +  FT_Stream_ReadChar( FT_Stream  stream,
 425.461 +                      FT_Error*  error );
 425.462 +
 425.463 +  /* read a 16-bit big-endian integer from a stream */
 425.464 +  FT_BASE( FT_Short )
 425.465 +  FT_Stream_ReadShort( FT_Stream  stream,
 425.466 +                       FT_Error*  error );
 425.467 +
 425.468 +  /* read a 24-bit big-endian integer from a stream */
 425.469 +  FT_BASE( FT_Long )
 425.470 +  FT_Stream_ReadOffset( FT_Stream  stream,
 425.471 +                        FT_Error*  error );
 425.472 +
 425.473 +  /* read a 32-bit big-endian integer from a stream */
 425.474 +  FT_BASE( FT_Long )
 425.475 +  FT_Stream_ReadLong( FT_Stream  stream,
 425.476 +                      FT_Error*  error );
 425.477 +
 425.478 +  /* read a 16-bit little-endian integer from a stream */
 425.479 +  FT_BASE( FT_Short )
 425.480 +  FT_Stream_ReadShortLE( FT_Stream  stream,
 425.481 +                         FT_Error*  error );
 425.482 +
 425.483 +  /* read a 32-bit little-endian integer from a stream */
 425.484 +  FT_BASE( FT_Long )
 425.485 +  FT_Stream_ReadLongLE( FT_Stream  stream,
 425.486 +                        FT_Error*  error );
 425.487 +
 425.488 +  /* Read a structure from a stream.  The structure must be described */
 425.489 +  /* by an array of FT_Frame_Field records.                           */
 425.490 +  FT_BASE( FT_Error )
 425.491 +  FT_Stream_ReadFields( FT_Stream              stream,
 425.492 +                        const FT_Frame_Field*  fields,
 425.493 +                        void*                  structure );
 425.494 +
 425.495 +
 425.496 +#define FT_STREAM_POS()           \
 425.497 +          FT_Stream_Pos( stream )
 425.498 +
 425.499 +#define FT_STREAM_SEEK( position )                           \
 425.500 +          FT_SET_ERROR( FT_Stream_Seek( stream, position ) )
 425.501 +
 425.502 +#define FT_STREAM_SKIP( distance )                           \
 425.503 +          FT_SET_ERROR( FT_Stream_Skip( stream, distance ) )
 425.504 +
 425.505 +#define FT_STREAM_READ( buffer, count )                   \
 425.506 +          FT_SET_ERROR( FT_Stream_Read( stream,           \
 425.507 +                                        (FT_Byte*)buffer, \
 425.508 +                                        count ) )
 425.509 +
 425.510 +#define FT_STREAM_READ_AT( position, buffer, count )         \
 425.511 +          FT_SET_ERROR( FT_Stream_ReadAt( stream,            \
 425.512 +                                           position,         \
 425.513 +                                           (FT_Byte*)buffer, \
 425.514 +                                           count ) )
 425.515 +
 425.516 +#define FT_STREAM_READ_FIELDS( fields, object )                          \
 425.517 +          FT_SET_ERROR( FT_Stream_ReadFields( stream, fields, object ) )
 425.518 +
 425.519 +
 425.520 +#define FT_FRAME_ENTER( size )                                       \
 425.521 +          FT_SET_ERROR(                                              \
 425.522 +            FT_DEBUG_INNER( FT_Stream_EnterFrame( stream, size ) ) )
 425.523 +
 425.524 +#define FT_FRAME_EXIT()                 \
 425.525 +          FT_DEBUG_INNER( FT_Stream_ExitFrame( stream ) )
 425.526 +
 425.527 +#define FT_FRAME_EXTRACT( size, bytes )                                       \
 425.528 +          FT_SET_ERROR(                                                       \
 425.529 +            FT_DEBUG_INNER( FT_Stream_ExtractFrame( stream, size,             \
 425.530 +                                                    (FT_Byte**)&(bytes) ) ) )
 425.531 +
 425.532 +#define FT_FRAME_RELEASE( bytes )                                         \
 425.533 +          FT_DEBUG_INNER( FT_Stream_ReleaseFrame( stream,                 \
 425.534 +                                                  (FT_Byte**)&(bytes) ) )
 425.535 +
 425.536 +
 425.537 +FT_END_HEADER
 425.538 +
 425.539 +#endif /* __FTSTREAM_H__ */
 425.540 +
 425.541 +
 425.542 +/* END */
   426.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   426.2 +++ b/libs/ft2static/freetype/internal/fttrace.h	Sat Feb 01 19:58:19 2014 +0200
   426.3 @@ -0,0 +1,139 @@
   426.4 +/***************************************************************************/
   426.5 +/*                                                                         */
   426.6 +/*  fttrace.h                                                              */
   426.7 +/*                                                                         */
   426.8 +/*    Tracing handling (specification only).                               */
   426.9 +/*                                                                         */
  426.10 +/*  Copyright 2002, 2004, 2005, 2006, 2007 by                              */
  426.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  426.12 +/*                                                                         */
  426.13 +/*  This file is part of the FreeType project, and may only be used,       */
  426.14 +/*  modified, and distributed under the terms of the FreeType project      */
  426.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  426.16 +/*  this file you indicate that you have read the license and              */
  426.17 +/*  understand and accept it fully.                                        */
  426.18 +/*                                                                         */
  426.19 +/***************************************************************************/
  426.20 +
  426.21 +
  426.22 +  /* definitions of trace levels for FreeType 2 */
  426.23 +
  426.24 +  /* the first level must always be `trace_any' */
  426.25 +FT_TRACE_DEF( any )
  426.26 +
  426.27 +  /* base components */
  426.28 +FT_TRACE_DEF( calc )      /* calculations            (ftcalc.c)   */
  426.29 +FT_TRACE_DEF( memory )    /* memory manager          (ftobjs.c)   */
  426.30 +FT_TRACE_DEF( stream )    /* stream manager          (ftstream.c) */
  426.31 +FT_TRACE_DEF( io )        /* i/o interface           (ftsystem.c) */
  426.32 +FT_TRACE_DEF( list )      /* list management         (ftlist.c)   */
  426.33 +FT_TRACE_DEF( init )      /* initialization          (ftinit.c)   */
  426.34 +FT_TRACE_DEF( objs )      /* base objects            (ftobjs.c)   */
  426.35 +FT_TRACE_DEF( outline )   /* outline management      (ftoutln.c)  */
  426.36 +FT_TRACE_DEF( glyph )     /* glyph management        (ftglyph.c)  */
  426.37 +FT_TRACE_DEF( gloader )   /* glyph loader            (ftgloadr.c) */
  426.38 +
  426.39 +FT_TRACE_DEF( raster )    /* monochrome rasterizer   (ftraster.c) */
  426.40 +FT_TRACE_DEF( smooth )    /* anti-aliasing raster    (ftgrays.c)  */
  426.41 +FT_TRACE_DEF( mm )        /* MM interface            (ftmm.c)     */
  426.42 +FT_TRACE_DEF( raccess )   /* resource fork accessor  (ftrfork.c)  */
  426.43 +FT_TRACE_DEF( synth )     /* bold/slant synthesizer  (ftsynth.c)  */
  426.44 +
  426.45 +  /* Cache sub-system */
  426.46 +FT_TRACE_DEF( cache )     /* cache sub-system        (ftcache.c, etc.) */
  426.47 +
  426.48 +  /* SFNT driver components */
  426.49 +FT_TRACE_DEF( sfdriver )  /* SFNT font driver        (sfdriver.c) */
  426.50 +FT_TRACE_DEF( sfobjs )    /* SFNT object handler     (sfobjs.c)   */
  426.51 +FT_TRACE_DEF( ttcmap )    /* charmap handler         (ttcmap.c)   */
  426.52 +FT_TRACE_DEF( ttkern )    /* kerning handler         (ttkern.c)   */
  426.53 +FT_TRACE_DEF( ttload )    /* basic TrueType tables   (ttload.c)   */
  426.54 +FT_TRACE_DEF( ttmtx )     /* metrics-related tables  (ttmtx.c)    */
  426.55 +FT_TRACE_DEF( ttpost )    /* PS table processing     (ttpost.c)   */
  426.56 +FT_TRACE_DEF( ttsbit )    /* TrueType sbit handling  (ttsbit.c)   */
  426.57 +FT_TRACE_DEF( ttbdf )     /* TrueType embedded BDF   (ttbdf.c)    */
  426.58 +
  426.59 +  /* TrueType driver components */
  426.60 +FT_TRACE_DEF( ttdriver )  /* TT font driver          (ttdriver.c) */
  426.61 +FT_TRACE_DEF( ttgload )   /* TT glyph loader         (ttgload.c)  */
  426.62 +FT_TRACE_DEF( ttinterp )  /* bytecode interpreter    (ttinterp.c) */
  426.63 +FT_TRACE_DEF( ttobjs )    /* TT objects manager      (ttobjs.c)   */
  426.64 +FT_TRACE_DEF( ttpload )   /* TT data/program loader  (ttpload.c)  */
  426.65 +FT_TRACE_DEF( ttgxvar )   /* TrueType GX var handler (ttgxvar.c)  */
  426.66 +
  426.67 +  /* Type 1 driver components */
  426.68 +FT_TRACE_DEF( t1afm )
  426.69 +FT_TRACE_DEF( t1driver )
  426.70 +FT_TRACE_DEF( t1gload )
  426.71 +FT_TRACE_DEF( t1hint )
  426.72 +FT_TRACE_DEF( t1load )
  426.73 +FT_TRACE_DEF( t1objs )
  426.74 +FT_TRACE_DEF( t1parse )
  426.75 +
  426.76 +  /* PostScript helper module `psaux' */
  426.77 +FT_TRACE_DEF( t1decode )
  426.78 +FT_TRACE_DEF( psobjs )
  426.79 +
  426.80 +  /* PostScript hinting module `pshinter' */
  426.81 +FT_TRACE_DEF( pshrec )
  426.82 +FT_TRACE_DEF( pshalgo1 )
  426.83 +FT_TRACE_DEF( pshalgo2 )
  426.84 +
  426.85 +  /* Type 2 driver components */
  426.86 +FT_TRACE_DEF( cffdriver )
  426.87 +FT_TRACE_DEF( cffgload )
  426.88 +FT_TRACE_DEF( cffload )
  426.89 +FT_TRACE_DEF( cffobjs )
  426.90 +FT_TRACE_DEF( cffparse )
  426.91 +
  426.92 +  /* Type 42 driver component */
  426.93 +FT_TRACE_DEF( t42 )
  426.94 +
  426.95 +  /* CID driver components */
  426.96 +FT_TRACE_DEF( cidafm )
  426.97 +FT_TRACE_DEF( ciddriver )
  426.98 +FT_TRACE_DEF( cidgload )
  426.99 +FT_TRACE_DEF( cidload )
 426.100 +FT_TRACE_DEF( cidobjs )
 426.101 +FT_TRACE_DEF( cidparse )
 426.102 +
 426.103 +  /* Windows font component */
 426.104 +FT_TRACE_DEF( winfnt )
 426.105 +
 426.106 +  /* PCF font components */
 426.107 +FT_TRACE_DEF( pcfdriver )
 426.108 +FT_TRACE_DEF( pcfread )
 426.109 +
 426.110 +  /* BDF font components */
 426.111 +FT_TRACE_DEF( bdfdriver )
 426.112 +FT_TRACE_DEF( bdflib )
 426.113 +
 426.114 +  /* PFR font component */
 426.115 +FT_TRACE_DEF( pfr )
 426.116 +
 426.117 +  /* OpenType validation components */
 426.118 +FT_TRACE_DEF( otvmodule )
 426.119 +FT_TRACE_DEF( otvcommon )
 426.120 +FT_TRACE_DEF( otvbase )
 426.121 +FT_TRACE_DEF( otvgdef )
 426.122 +FT_TRACE_DEF( otvgpos )
 426.123 +FT_TRACE_DEF( otvgsub )
 426.124 +FT_TRACE_DEF( otvjstf )
 426.125 +FT_TRACE_DEF( otvmath )
 426.126 +
 426.127 +  /* TrueTypeGX/AAT validation components */
 426.128 +FT_TRACE_DEF( gxvmodule )
 426.129 +FT_TRACE_DEF( gxvcommon )
 426.130 +FT_TRACE_DEF( gxvfeat )
 426.131 +FT_TRACE_DEF( gxvmort )
 426.132 +FT_TRACE_DEF( gxvmorx )
 426.133 +FT_TRACE_DEF( gxvbsln )
 426.134 +FT_TRACE_DEF( gxvjust )
 426.135 +FT_TRACE_DEF( gxvkern )
 426.136 +FT_TRACE_DEF( gxvopbd )
 426.137 +FT_TRACE_DEF( gxvtrak )
 426.138 +FT_TRACE_DEF( gxvprop )
 426.139 +FT_TRACE_DEF( gxvlcar )
 426.140 +
 426.141 +
 426.142 +/* END */
   427.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   427.2 +++ b/libs/ft2static/freetype/internal/ftvalid.h	Sat Feb 01 19:58:19 2014 +0200
   427.3 @@ -0,0 +1,150 @@
   427.4 +/***************************************************************************/
   427.5 +/*                                                                         */
   427.6 +/*  ftvalid.h                                                              */
   427.7 +/*                                                                         */
   427.8 +/*    FreeType validation support (specification).                         */
   427.9 +/*                                                                         */
  427.10 +/*  Copyright 2004 by                                                      */
  427.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  427.12 +/*                                                                         */
  427.13 +/*  This file is part of the FreeType project, and may only be used,       */
  427.14 +/*  modified, and distributed under the terms of the FreeType project      */
  427.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  427.16 +/*  this file you indicate that you have read the license and              */
  427.17 +/*  understand and accept it fully.                                        */
  427.18 +/*                                                                         */
  427.19 +/***************************************************************************/
  427.20 +
  427.21 +
  427.22 +#ifndef __FTVALID_H__
  427.23 +#define __FTVALID_H__
  427.24 +
  427.25 +#include <ft2build.h>
  427.26 +#include FT_CONFIG_STANDARD_LIBRARY_H   /* for ft_setjmp and ft_longjmp */
  427.27 +
  427.28 +
  427.29 +FT_BEGIN_HEADER
  427.30 +
  427.31 +
  427.32 +  /*************************************************************************/
  427.33 +  /*************************************************************************/
  427.34 +  /*************************************************************************/
  427.35 +  /****                                                                 ****/
  427.36 +  /****                                                                 ****/
  427.37 +  /****                    V A L I D A T I O N                          ****/
  427.38 +  /****                                                                 ****/
  427.39 +  /****                                                                 ****/
  427.40 +  /*************************************************************************/
  427.41 +  /*************************************************************************/
  427.42 +  /*************************************************************************/
  427.43 +
  427.44 +  /* handle to a validation object */
  427.45 +  typedef struct FT_ValidatorRec_ volatile*  FT_Validator;
  427.46 +
  427.47 +
  427.48 +  /*************************************************************************/
  427.49 +  /*                                                                       */
  427.50 +  /* There are three distinct validation levels defined here:              */
  427.51 +  /*                                                                       */
  427.52 +  /* FT_VALIDATE_DEFAULT ::                                                */
  427.53 +  /*   A table that passes this validation level can be used reliably by   */
  427.54 +  /*   FreeType.  It generally means that all offsets have been checked to */
  427.55 +  /*   prevent out-of-bound reads, that array counts are correct, etc.     */
  427.56 +  /*                                                                       */
  427.57 +  /* FT_VALIDATE_TIGHT ::                                                  */
  427.58 +  /*   A table that passes this validation level can be used reliably and  */
  427.59 +  /*   doesn't contain invalid data.  For example, a charmap table that    */
  427.60 +  /*   returns invalid glyph indices will not pass, even though it can     */
  427.61 +  /*   be used with FreeType in default mode (the library will simply      */
  427.62 +  /*   return an error later when trying to load the glyph).               */
  427.63 +  /*                                                                       */
  427.64 +  /*   It also checks that fields which must be a multiple of 2, 4, or 8,  */
  427.65 +  /*   don't have incorrect values, etc.                                   */
  427.66 +  /*                                                                       */
  427.67 +  /* FT_VALIDATE_PARANOID ::                                               */
  427.68 +  /*   Only for font debugging.  Checks that a table follows the           */
  427.69 +  /*   specification by 100%.  Very few fonts will be able to pass this    */
  427.70 +  /*   level anyway but it can be useful for certain tools like font       */
  427.71 +  /*   editors/converters.                                                 */
  427.72 +  /*                                                                       */
  427.73 +  typedef enum  FT_ValidationLevel_
  427.74 +  {
  427.75 +    FT_VALIDATE_DEFAULT = 0,
  427.76 +    FT_VALIDATE_TIGHT,
  427.77 +    FT_VALIDATE_PARANOID
  427.78 +
  427.79 +  } FT_ValidationLevel;
  427.80 +
  427.81 +
  427.82 +  /* validator structure */
  427.83 +  typedef struct  FT_ValidatorRec_
  427.84 +  {
  427.85 +    const FT_Byte*      base;        /* address of table in memory       */
  427.86 +    const FT_Byte*      limit;       /* `base' + sizeof(table) in memory */
  427.87 +    FT_ValidationLevel  level;       /* validation level                 */
  427.88 +    FT_Error            error;       /* error returned. 0 means success  */
  427.89 +
  427.90 +    ft_jmp_buf          jump_buffer; /* used for exception handling      */
  427.91 +
  427.92 +  } FT_ValidatorRec;
  427.93 +
  427.94 +
  427.95 +#define FT_VALIDATOR( x )  ((FT_Validator)( x ))
  427.96 +
  427.97 +
  427.98 +  FT_BASE( void )
  427.99 +  ft_validator_init( FT_Validator        valid,
 427.100 +                     const FT_Byte*      base,
 427.101 +                     const FT_Byte*      limit,
 427.102 +                     FT_ValidationLevel  level );
 427.103 +
 427.104 +  /* Do not use this. It's broken and will cause your validator to crash */
 427.105 +  /* if you run it on an invalid font.                                   */
 427.106 +  FT_BASE( FT_Int )
 427.107 +  ft_validator_run( FT_Validator  valid );
 427.108 +
 427.109 +  /* Sets the error field in a validator, then calls `longjmp' to return */
 427.110 +  /* to high-level caller.  Using `setjmp/longjmp' avoids many stupid    */
 427.111 +  /* error checks within the validation routines.                        */
 427.112 +  /*                                                                     */
 427.113 +  FT_BASE( void )
 427.114 +  ft_validator_error( FT_Validator  valid,
 427.115 +                      FT_Error      error );
 427.116 +
 427.117 +
 427.118 +  /* Calls ft_validate_error.  Assumes that the `valid' local variable */
 427.119 +  /* holds a pointer to the current validator object.                  */
 427.120 +  /*                                                                   */
 427.121 +  /* Use preprocessor prescan to pass FT_ERR_PREFIX.                   */
 427.122 +  /*                                                                   */
 427.123 +#define FT_INVALID( _prefix, _error )  FT_INVALID_( _prefix, _error )
 427.124 +#define FT_INVALID_( _prefix, _error ) \
 427.125 +          ft_validator_error( valid, _prefix ## _error )
 427.126 +
 427.127 +  /* called when a broken table is detected */
 427.128 +#define FT_INVALID_TOO_SHORT \
 427.129 +          FT_INVALID( FT_ERR_PREFIX, Invalid_Table )
 427.130 +
 427.131 +  /* called when an invalid offset is detected */
 427.132 +#define FT_INVALID_OFFSET \
 427.133 +          FT_INVALID( FT_ERR_PREFIX, Invalid_Offset )
 427.134 +
 427.135 +  /* called when an invalid format/value is detected */
 427.136 +#define FT_INVALID_FORMAT \
 427.137 +          FT_INVALID( FT_ERR_PREFIX, Invalid_Table )
 427.138 +
 427.139 +  /* called when an invalid glyph index is detected */
 427.140 +#define FT_INVALID_GLYPH_ID \
 427.141 +          FT_INVALID( FT_ERR_PREFIX, Invalid_Glyph_Index )
 427.142 +
 427.143 +  /* called when an invalid field value is detected */
 427.144 +#define FT_INVALID_DATA \
 427.145 +          FT_INVALID( FT_ERR_PREFIX, Invalid_Table )
 427.146 +
 427.147 +
 427.148 +FT_END_HEADER
 427.149 +
 427.150 +#endif /* __FTVALID_H__ */
 427.151 +
 427.152 +
 427.153 +/* END */
   428.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   428.2 +++ b/libs/ft2static/freetype/internal/internal.h	Sat Feb 01 19:58:19 2014 +0200
   428.3 @@ -0,0 +1,51 @@
   428.4 +/***************************************************************************/
   428.5 +/*                                                                         */
   428.6 +/*  internal.h                                                             */
   428.7 +/*                                                                         */
   428.8 +/*    Internal header files (specification only).                          */
   428.9 +/*                                                                         */
  428.10 +/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */
  428.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  428.12 +/*                                                                         */
  428.13 +/*  This file is part of the FreeType project, and may only be used,       */
  428.14 +/*  modified, and distributed under the terms of the FreeType project      */
  428.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  428.16 +/*  this file you indicate that you have read the license and              */
  428.17 +/*  understand and accept it fully.                                        */
  428.18 +/*                                                                         */
  428.19 +/***************************************************************************/
  428.20 +
  428.21 +
  428.22 +  /*************************************************************************/
  428.23 +  /*                                                                       */
  428.24 +  /* This file is automatically included by `ft2build.h'.                  */
  428.25 +  /* Do not include it manually!                                           */
  428.26 +  /*                                                                       */
  428.27 +  /*************************************************************************/
  428.28 +
  428.29 +
  428.30 +#define FT_INTERNAL_OBJECTS_H             <freetype/internal/ftobjs.h>
  428.31 +#define FT_INTERNAL_PIC_H                 <freetype/internal/ftpic.h>
  428.32 +#define FT_INTERNAL_STREAM_H              <freetype/internal/ftstream.h>
  428.33 +#define FT_INTERNAL_MEMORY_H              <freetype/internal/ftmemory.h>
  428.34 +#define FT_INTERNAL_DEBUG_H               <freetype/internal/ftdebug.h>
  428.35 +#define FT_INTERNAL_CALC_H                <freetype/internal/ftcalc.h>
  428.36 +#define FT_INTERNAL_DRIVER_H              <freetype/internal/ftdriver.h>
  428.37 +#define FT_INTERNAL_TRACE_H               <freetype/internal/fttrace.h>
  428.38 +#define FT_INTERNAL_GLYPH_LOADER_H        <freetype/internal/ftgloadr.h>
  428.39 +#define FT_INTERNAL_SFNT_H                <freetype/internal/sfnt.h>
  428.40 +#define FT_INTERNAL_SERVICE_H             <freetype/internal/ftserv.h>
  428.41 +#define FT_INTERNAL_RFORK_H               <freetype/internal/ftrfork.h>
  428.42 +#define FT_INTERNAL_VALIDATE_H            <freetype/internal/ftvalid.h>
  428.43 +
  428.44 +#define FT_INTERNAL_TRUETYPE_TYPES_H      <freetype/internal/tttypes.h>
  428.45 +#define FT_INTERNAL_TYPE1_TYPES_H         <freetype/internal/t1types.h>
  428.46 +
  428.47 +#define FT_INTERNAL_POSTSCRIPT_AUX_H      <freetype/internal/psaux.h>
  428.48 +#define FT_INTERNAL_POSTSCRIPT_HINTS_H    <freetype/internal/pshints.h>
  428.49 +#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H  <freetype/internal/psglobal.h>
  428.50 +
  428.51 +#define FT_INTERNAL_AUTOHINT_H            <freetype/internal/autohint.h>
  428.52 +
  428.53 +
  428.54 +/* END */
   429.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   429.2 +++ b/libs/ft2static/freetype/internal/pcftypes.h	Sat Feb 01 19:58:19 2014 +0200
   429.3 @@ -0,0 +1,56 @@
   429.4 +/*  pcftypes.h
   429.5 +
   429.6 +  FreeType font driver for pcf fonts
   429.7 +
   429.8 +  Copyright (C) 2000, 2001, 2002 by
   429.9 +  Francesco Zappa Nardelli
  429.10 +
  429.11 +Permission is hereby granted, free of charge, to any person obtaining a copy
  429.12 +of this software and associated documentation files (the "Software"), to deal
  429.13 +in the Software without restriction, including without limitation the rights
  429.14 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  429.15 +copies of the Software, and to permit persons to whom the Software is
  429.16 +furnished to do so, subject to the following conditions:
  429.17 +
  429.18 +The above copyright notice and this permission notice shall be included in
  429.19 +all copies or substantial portions of the Software.
  429.20 +
  429.21 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  429.22 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  429.23 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
  429.24 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  429.25 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  429.26 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  429.27 +THE SOFTWARE.
  429.28 +*/
  429.29 +
  429.30 +
  429.31 +#ifndef __PCFTYPES_H__
  429.32 +#define __PCFTYPES_H__
  429.33 +
  429.34 +
  429.35 +#include <ft2build.h>
  429.36 +#include FT_FREETYPE_H
  429.37 +
  429.38 +
  429.39 +FT_BEGIN_HEADER
  429.40 +
  429.41 +
  429.42 +  typedef struct  PCF_Public_FaceRec_
  429.43 +  {
  429.44 +    FT_FaceRec    root;
  429.45 +    FT_StreamRec  gzip_stream;
  429.46 +    FT_Stream     gzip_source;
  429.47 +
  429.48 +    char*         charset_encoding;
  429.49 +    char*         charset_registry;
  429.50 +
  429.51 +  } PCF_Public_FaceRec, *PCF_Public_Face;
  429.52 +
  429.53 +
  429.54 +FT_END_HEADER
  429.55 +
  429.56 +#endif  /* __PCFTYPES_H__ */
  429.57 +
  429.58 +
  429.59 +/* END */
   430.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   430.2 +++ b/libs/ft2static/freetype/internal/psaux.h	Sat Feb 01 19:58:19 2014 +0200
   430.3 @@ -0,0 +1,873 @@
   430.4 +/***************************************************************************/
   430.5 +/*                                                                         */
   430.6 +/*  psaux.h                                                                */
   430.7 +/*                                                                         */
   430.8 +/*    Auxiliary functions and data structures related to PostScript fonts  */
   430.9 +/*    (specification).                                                     */
  430.10 +/*                                                                         */
  430.11 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */
  430.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  430.13 +/*                                                                         */
  430.14 +/*  This file is part of the FreeType project, and may only be used,       */
  430.15 +/*  modified, and distributed under the terms of the FreeType project      */
  430.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  430.17 +/*  this file you indicate that you have read the license and              */
  430.18 +/*  understand and accept it fully.                                        */
  430.19 +/*                                                                         */
  430.20 +/***************************************************************************/
  430.21 +
  430.22 +
  430.23 +#ifndef __PSAUX_H__
  430.24 +#define __PSAUX_H__
  430.25 +
  430.26 +
  430.27 +#include <ft2build.h>
  430.28 +#include FT_INTERNAL_OBJECTS_H
  430.29 +#include FT_INTERNAL_TYPE1_TYPES_H
  430.30 +#include FT_SERVICE_POSTSCRIPT_CMAPS_H
  430.31 +
  430.32 +
  430.33 +FT_BEGIN_HEADER
  430.34 +
  430.35 +
  430.36 +  /*************************************************************************/
  430.37 +  /*************************************************************************/
  430.38 +  /*****                                                               *****/
  430.39 +  /*****                             T1_TABLE                          *****/
  430.40 +  /*****                                                               *****/
  430.41 +  /*************************************************************************/
  430.42 +  /*************************************************************************/
  430.43 +
  430.44 +
  430.45 +  typedef struct PS_TableRec_*              PS_Table;
  430.46 +  typedef const struct PS_Table_FuncsRec_*  PS_Table_Funcs;
  430.47 +
  430.48 +
  430.49 +  /*************************************************************************/
  430.50 +  /*                                                                       */
  430.51 +  /* <Struct>                                                              */
  430.52 +  /*    PS_Table_FuncsRec                                                  */
  430.53 +  /*                                                                       */
  430.54 +  /* <Description>                                                         */
  430.55 +  /*    A set of function pointers to manage PS_Table objects.             */
  430.56 +  /*                                                                       */
  430.57 +  /* <Fields>                                                              */
  430.58 +  /*    table_init    :: Used to initialize a table.                       */
  430.59 +  /*                                                                       */
  430.60 +  /*    table_done    :: Finalizes resp. destroy a given table.            */
  430.61 +  /*                                                                       */
  430.62 +  /*    table_add     :: Adds a new object to a table.                     */
  430.63 +  /*                                                                       */
  430.64 +  /*    table_release :: Releases table data, then finalizes it.           */
  430.65 +  /*                                                                       */
  430.66 +  typedef struct  PS_Table_FuncsRec_
  430.67 +  {
  430.68 +    FT_Error
  430.69 +    (*init)( PS_Table   table,
  430.70 +             FT_Int     count,
  430.71 +             FT_Memory  memory );
  430.72 +
  430.73 +    void
  430.74 +    (*done)( PS_Table  table );
  430.75 +
  430.76 +    FT_Error
  430.77 +    (*add)( PS_Table    table,
  430.78 +            FT_Int      idx,
  430.79 +            void*       object,
  430.80 +            FT_PtrDist  length );
  430.81 +
  430.82 +    void
  430.83 +    (*release)( PS_Table  table );
  430.84 +
  430.85 +  } PS_Table_FuncsRec;
  430.86 +
  430.87 +
  430.88 +  /*************************************************************************/
  430.89 +  /*                                                                       */
  430.90 +  /* <Struct>                                                              */
  430.91 +  /*    PS_TableRec                                                        */
  430.92 +  /*                                                                       */
  430.93 +  /* <Description>                                                         */
  430.94 +  /*    A PS_Table is a simple object used to store an array of objects in */
  430.95 +  /*    a single memory block.                                             */
  430.96 +  /*                                                                       */
  430.97 +  /* <Fields>                                                              */
  430.98 +  /*    block     :: The address in memory of the growheap's block.  This  */
  430.99 +  /*                 can change between two object adds, due to            */
 430.100 +  /*                 reallocation.                                         */
 430.101 +  /*                                                                       */
 430.102 +  /*    cursor    :: The current top of the grow heap within its block.    */
 430.103 +  /*                                                                       */
 430.104 +  /*    capacity  :: The current size of the heap block.  Increments by    */
 430.105 +  /*                 1kByte chunks.                                        */
 430.106 +  /*                                                                       */
 430.107 +  /*    max_elems :: The maximum number of elements in table.              */
 430.108 +  /*                                                                       */
 430.109 +  /*    num_elems :: The current number of elements in table.              */
 430.110 +  /*                                                                       */
 430.111 +  /*    elements  :: A table of element addresses within the block.        */
 430.112 +  /*                                                                       */
 430.113 +  /*    lengths   :: A table of element sizes within the block.            */
 430.114 +  /*                                                                       */
 430.115 +  /*    memory    :: The object used for memory operations                 */
 430.116 +  /*                 (alloc/realloc).                                      */
 430.117 +  /*                                                                       */
 430.118 +  /*    funcs     :: A table of method pointers for this object.           */
 430.119 +  /*                                                                       */
 430.120 +  typedef struct  PS_TableRec_
 430.121 +  {
 430.122 +    FT_Byte*           block;          /* current memory block           */
 430.123 +    FT_Offset          cursor;         /* current cursor in memory block */
 430.124 +    FT_Offset          capacity;       /* current size of memory block   */
 430.125 +    FT_Long            init;
 430.126 +
 430.127 +    FT_Int             max_elems;
 430.128 +    FT_Int             num_elems;
 430.129 +    FT_Byte**          elements;       /* addresses of table elements */
 430.130 +    FT_PtrDist*        lengths;        /* lengths of table elements   */
 430.131 +
 430.132 +    FT_Memory          memory;
 430.133 +    PS_Table_FuncsRec  funcs;
 430.134 +
 430.135 +  } PS_TableRec;
 430.136 +
 430.137 +
 430.138 +  /*************************************************************************/
 430.139 +  /*************************************************************************/
 430.140 +  /*****                                                               *****/
 430.141 +  /*****                       T1 FIELDS & TOKENS                      *****/
 430.142 +  /*****                                                               *****/
 430.143 +  /*************************************************************************/
 430.144 +  /*************************************************************************/
 430.145 +
 430.146 +  typedef struct PS_ParserRec_*  PS_Parser;
 430.147 +
 430.148 +  typedef struct T1_TokenRec_*   T1_Token;
 430.149 +
 430.150 +  typedef struct T1_FieldRec_*   T1_Field;
 430.151 +
 430.152 +
 430.153 +  /* simple enumeration type used to identify token types */
 430.154 +  typedef enum  T1_TokenType_
 430.155 +  {
 430.156 +    T1_TOKEN_TYPE_NONE = 0,
 430.157 +    T1_TOKEN_TYPE_ANY,
 430.158 +    T1_TOKEN_TYPE_STRING,
 430.159 +    T1_TOKEN_TYPE_ARRAY,
 430.160 +    T1_TOKEN_TYPE_KEY, /* aka `name' */
 430.161 +
 430.162 +    /* do not remove */
 430.163 +    T1_TOKEN_TYPE_MAX
 430.164 +
 430.165 +  } T1_TokenType;
 430.166 +
 430.167 +
 430.168 +  /* a simple structure used to identify tokens */
 430.169 +  typedef struct  T1_TokenRec_
 430.170 +  {
 430.171 +    FT_Byte*      start;   /* first character of token in input stream */
 430.172 +    FT_Byte*      limit;   /* first character after the token          */
 430.173 +    T1_TokenType  type;    /* type of token                            */
 430.174 +
 430.175 +  } T1_TokenRec;
 430.176 +
 430.177 +
 430.178 +  /* enumeration type used to identify object fields */
 430.179 +  typedef enum  T1_FieldType_
 430.180 +  {
 430.181 +    T1_FIELD_TYPE_NONE = 0,
 430.182 +    T1_FIELD_TYPE_BOOL,
 430.183 +    T1_FIELD_TYPE_INTEGER,
 430.184 +    T1_FIELD_TYPE_FIXED,
 430.185 +    T1_FIELD_TYPE_FIXED_1000,
 430.186 +    T1_FIELD_TYPE_STRING,
 430.187 +    T1_FIELD_TYPE_KEY,
 430.188 +    T1_FIELD_TYPE_BBOX,
 430.189 +    T1_FIELD_TYPE_INTEGER_ARRAY,
 430.190 +    T1_FIELD_TYPE_FIXED_ARRAY,
 430.191 +    T1_FIELD_TYPE_CALLBACK,
 430.192 +
 430.193 +    /* do not remove */
 430.194 +    T1_FIELD_TYPE_MAX
 430.195 +
 430.196 +  } T1_FieldType;
 430.197 +
 430.198 +
 430.199 +  typedef enum  T1_FieldLocation_
 430.200 +  {
 430.201 +    T1_FIELD_LOCATION_CID_INFO,
 430.202 +    T1_FIELD_LOCATION_FONT_DICT,
 430.203 +    T1_FIELD_LOCATION_FONT_EXTRA,
 430.204 +    T1_FIELD_LOCATION_FONT_INFO,
 430.205 +    T1_FIELD_LOCATION_PRIVATE,
 430.206 +    T1_FIELD_LOCATION_BBOX,
 430.207 +    T1_FIELD_LOCATION_LOADER,
 430.208 +    T1_FIELD_LOCATION_FACE,
 430.209 +    T1_FIELD_LOCATION_BLEND,
 430.210 +
 430.211 +    /* do not remove */
 430.212 +    T1_FIELD_LOCATION_MAX
 430.213 +
 430.214 +  } T1_FieldLocation;
 430.215 +
 430.216 +
 430.217 +  typedef void
 430.218 +  (*T1_Field_ParseFunc)( FT_Face     face,
 430.219 +                         FT_Pointer  parser );
 430.220 +
 430.221 +
 430.222 +  /* structure type used to model object fields */
 430.223 +  typedef struct  T1_FieldRec_
 430.224 +  {
 430.225 +    const char*         ident;        /* field identifier               */
 430.226 +    T1_FieldLocation    location;
 430.227 +    T1_FieldType        type;         /* type of field                  */
 430.228 +    T1_Field_ParseFunc  reader;
 430.229 +    FT_UInt             offset;       /* offset of field in object      */
 430.230 +    FT_Byte             size;         /* size of field in bytes         */
 430.231 +    FT_UInt             array_max;    /* maximal number of elements for */
 430.232 +                                      /* array                          */
 430.233 +    FT_UInt             count_offset; /* offset of element count for    */
 430.234 +                                      /* arrays; must not be zero if in */
 430.235 +                                      /* use -- in other words, a       */
 430.236 +                                      /* `num_FOO' element must not     */
 430.237 +                                      /* start the used structure if we */
 430.238 +                                      /* parse a `FOO' array            */
 430.239 +    FT_UInt             dict;         /* where we expect it             */
 430.240 +  } T1_FieldRec;
 430.241 +
 430.242 +#define T1_FIELD_DICT_FONTDICT ( 1 << 0 ) /* also FontInfo and FDArray */
 430.243 +#define T1_FIELD_DICT_PRIVATE  ( 1 << 1 )
 430.244 +
 430.245 +
 430.246 +
 430.247 +#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname, _dict ) \
 430.248 +          {                                                 \
 430.249 +            _ident, T1CODE, _type,                          \
 430.250 +            0,                                              \
 430.251 +            FT_FIELD_OFFSET( _fname ),                      \
 430.252 +            FT_FIELD_SIZE( _fname ),                        \
 430.253 +            0, 0,                                           \
 430.254 +            _dict                                           \
 430.255 +          },
 430.256 +
 430.257 +#define T1_NEW_CALLBACK_FIELD( _ident, _reader, _dict ) \
 430.258 +          {                                             \
 430.259 +            _ident, T1CODE, T1_FIELD_TYPE_CALLBACK,     \
 430.260 +            (T1_Field_ParseFunc)_reader,                \
 430.261 +            0, 0,                                       \
 430.262 +            0, 0,                                       \
 430.263 +            _dict                                       \
 430.264 +          },
 430.265 +
 430.266 +#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max, _dict ) \
 430.267 +          {                                                      \
 430.268 +            _ident, T1CODE, _type,                               \
 430.269 +            0,                                                   \
 430.270 +            FT_FIELD_OFFSET( _fname ),                           \
 430.271 +            FT_FIELD_SIZE_DELTA( _fname ),                       \
 430.272 +            _max,                                                \
 430.273 +            FT_FIELD_OFFSET( num_ ## _fname ),                   \
 430.274 +            _dict                                                \
 430.275 +          },
 430.276 +
 430.277 +#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max, _dict ) \
 430.278 +          {                                                       \
 430.279 +            _ident, T1CODE, _type,                                \
 430.280 +            0,                                                    \
 430.281 +            FT_FIELD_OFFSET( _fname ),                            \
 430.282 +            FT_FIELD_SIZE_DELTA( _fname ),                        \
 430.283 +            _max, 0,                                              \
 430.284 +            _dict                                                 \
 430.285 +          },
 430.286 +
 430.287 +
 430.288 +#define T1_FIELD_BOOL( _ident, _fname, _dict )                             \
 430.289 +          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict )
 430.290 +
 430.291 +#define T1_FIELD_NUM( _ident, _fname, _dict )                                 \
 430.292 +          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict )
 430.293 +
 430.294 +#define T1_FIELD_FIXED( _ident, _fname, _dict )                             \
 430.295 +          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname, _dict )
 430.296 +
 430.297 +#define T1_FIELD_FIXED_1000( _ident, _fname, _dict )                     \
 430.298 +          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \
 430.299 +                               _dict )
 430.300 +
 430.301 +#define T1_FIELD_STRING( _ident, _fname, _dict )                             \
 430.302 +          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict )
 430.303 +
 430.304 +#define T1_FIELD_KEY( _ident, _fname, _dict )                             \
 430.305 +          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict )
 430.306 +
 430.307 +#define T1_FIELD_BBOX( _ident, _fname, _dict )                             \
 430.308 +          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname, _dict )
 430.309 +
 430.310 +
 430.311 +#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax, _dict )         \
 430.312 +          T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \
 430.313 +                              _fname, _fmax, _dict )
 430.314 +
 430.315 +#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict )     \
 430.316 +          T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \
 430.317 +                              _fname, _fmax, _dict )
 430.318 +
 430.319 +#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict )         \
 430.320 +          T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \
 430.321 +                               _fname, _fmax, _dict )
 430.322 +
 430.323 +#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict )     \
 430.324 +          T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \
 430.325 +                               _fname, _fmax, _dict )
 430.326 +
 430.327 +#define T1_FIELD_CALLBACK( _ident, _name, _dict )       \
 430.328 +          T1_NEW_CALLBACK_FIELD( _ident, _name, _dict )
 430.329 +
 430.330 +
 430.331 +  /*************************************************************************/
 430.332 +  /*************************************************************************/
 430.333 +  /*****                                                               *****/
 430.334 +  /*****                            T1 PARSER                          *****/
 430.335 +  /*****                                                               *****/
 430.336 +  /*************************************************************************/
 430.337 +  /*************************************************************************/
 430.338 +
 430.339 +  typedef const struct PS_Parser_FuncsRec_*  PS_Parser_Funcs;
 430.340 +
 430.341 +  typedef struct  PS_Parser_FuncsRec_
 430.342 +  {
 430.343 +    void
 430.344 +    (*init)( PS_Parser  parser,
 430.345 +             FT_Byte*   base,
 430.346 +             FT_Byte*   limit,
 430.347 +             FT_Memory  memory );
 430.348 +
 430.349 +    void
 430.350 +    (*done)( PS_Parser  parser );
 430.351 +
 430.352 +    void
 430.353 +    (*skip_spaces)( PS_Parser  parser );
 430.354 +    void
 430.355 +    (*skip_PS_token)( PS_Parser  parser );
 430.356 +
 430.357 +    FT_Long
 430.358 +    (*to_int)( PS_Parser  parser );
 430.359 +    FT_Fixed
 430.360 +    (*to_fixed)( PS_Parser  parser,
 430.361 +                 FT_Int     power_ten );
 430.362 +
 430.363 +    FT_Error
 430.364 +    (*to_bytes)( PS_Parser  parser,
 430.365 +                 FT_Byte*   bytes,
 430.366 +                 FT_Offset  max_bytes,
 430.367 +                 FT_Long*   pnum_bytes,
 430.368 +                 FT_Bool    delimiters );
 430.369 +
 430.370 +    FT_Int
 430.371 +    (*to_coord_array)( PS_Parser  parser,
 430.372 +                       FT_Int     max_coords,
 430.373 +                       FT_Short*  coords );
 430.374 +    FT_Int
 430.375 +    (*to_fixed_array)( PS_Parser  parser,
 430.376 +                       FT_Int     max_values,
 430.377 +                       FT_Fixed*  values,
 430.378 +                       FT_Int     power_ten );
 430.379 +
 430.380 +    void
 430.381 +    (*to_token)( PS_Parser  parser,
 430.382 +                 T1_Token   token );
 430.383 +    void
 430.384 +    (*to_token_array)( PS_Parser  parser,
 430.385 +                       T1_Token   tokens,
 430.386 +                       FT_UInt    max_tokens,
 430.387 +                       FT_Int*    pnum_tokens );
 430.388 +
 430.389 +    FT_Error
 430.390 +    (*load_field)( PS_Parser       parser,
 430.391 +                   const T1_Field  field,
 430.392 +                   void**          objects,
 430.393 +                   FT_UInt         max_objects,
 430.394 +                   FT_ULong*       pflags );
 430.395 +
 430.396 +    FT_Error
 430.397 +    (*load_field_table)( PS_Parser       parser,
 430.398 +                         const T1_Field  field,
 430.399 +                         void**          objects,
 430.400 +                         FT_UInt         max_objects,
 430.401 +                         FT_ULong*       pflags );
 430.402 +
 430.403 +  } PS_Parser_FuncsRec;
 430.404 +
 430.405 +
 430.406 +  /*************************************************************************/
 430.407 +  /*                                                                       */
 430.408 +  /* <Struct>                                                              */
 430.409 +  /*    PS_ParserRec                                                       */
 430.410 +  /*                                                                       */
 430.411 +  /* <Description>                                                         */
 430.412 +  /*    A PS_Parser is an object used to parse a Type 1 font very quickly. */
 430.413 +  /*                                                                       */
 430.414 +  /* <Fields>                                                              */
 430.415 +  /*    cursor :: The current position in the text.                        */
 430.416 +  /*                                                                       */
 430.417 +  /*    base   :: Start of the processed text.                             */
 430.418 +  /*                                                                       */
 430.419 +  /*    limit  :: End of the processed text.                               */
 430.420 +  /*                                                                       */
 430.421 +  /*    error  :: The last error returned.                                 */
 430.422 +  /*                                                                       */
 430.423 +  /*    memory :: The object used for memory operations (alloc/realloc).   */
 430.424 +  /*                                                                       */
 430.425 +  /*    funcs  :: A table of functions for the parser.                     */
 430.426 +  /*                                                                       */
 430.427 +  typedef struct  PS_ParserRec_
 430.428 +  {
 430.429 +    FT_Byte*   cursor;
 430.430 +    FT_Byte*   base;
 430.431 +    FT_Byte*   limit;
 430.432 +    FT_Error   error;
 430.433 +    FT_Memory  memory;
 430.434 +
 430.435 +    PS_Parser_FuncsRec  funcs;
 430.436 +
 430.437 +  } PS_ParserRec;
 430.438 +
 430.439 +
 430.440 +  /*************************************************************************/
 430.441 +  /*************************************************************************/
 430.442 +  /*****                                                               *****/
 430.443 +  /*****                         T1 BUILDER                            *****/
 430.444 +  /*****                                                               *****/
 430.445 +  /*************************************************************************/
 430.446 +  /*************************************************************************/
 430.447 +
 430.448 +
 430.449 +  typedef struct T1_BuilderRec_*  T1_Builder;
 430.450 +
 430.451 +
 430.452 +  typedef FT_Error
 430.453 +  (*T1_Builder_Check_Points_Func)( T1_Builder  builder,
 430.454 +                                   FT_Int      count );
 430.455 +
 430.456 +  typedef void
 430.457 +  (*T1_Builder_Add_Point_Func)( T1_Builder  builder,
 430.458 +                                FT_Pos      x,
 430.459 +                                FT_Pos      y,
 430.460 +                                FT_Byte     flag );
 430.461 +
 430.462 +  typedef FT_Error
 430.463 +  (*T1_Builder_Add_Point1_Func)( T1_Builder  builder,
 430.464 +                                 FT_Pos      x,
 430.465 +                                 FT_Pos      y );
 430.466 +
 430.467 +  typedef FT_Error
 430.468 +  (*T1_Builder_Add_Contour_Func)( T1_Builder  builder );
 430.469 +
 430.470 +  typedef FT_Error
 430.471 +  (*T1_Builder_Start_Point_Func)( T1_Builder  builder,
 430.472 +                                  FT_Pos      x,
 430.473 +                                  FT_Pos      y );
 430.474 +
 430.475 +  typedef void
 430.476 +  (*T1_Builder_Close_Contour_Func)( T1_Builder  builder );
 430.477 +
 430.478 +
 430.479 +  typedef const struct T1_Builder_FuncsRec_*  T1_Builder_Funcs;
 430.480 +
 430.481 +  typedef struct  T1_Builder_FuncsRec_
 430.482 +  {
 430.483 +    void
 430.484 +    (*init)( T1_Builder    builder,
 430.485 +             FT_Face       face,
 430.486 +             FT_Size       size,
 430.487 +             FT_GlyphSlot  slot,
 430.488 +             FT_Bool       hinting );
 430.489 +
 430.490 +    void
 430.491 +    (*done)( T1_Builder   builder );
 430.492 +
 430.493 +    T1_Builder_Check_Points_Func   check_points;
 430.494 +    T1_Builder_Add_Point_Func      add_point;
 430.495 +    T1_Builder_Add_Point1_Func     add_point1;
 430.496 +    T1_Builder_Add_Contour_Func    add_contour;
 430.497 +    T1_Builder_Start_Point_Func    start_point;
 430.498 +    T1_Builder_Close_Contour_Func  close_contour;
 430.499 +
 430.500 +  } T1_Builder_FuncsRec;
 430.501 +
 430.502 +
 430.503 +  /* an enumeration type to handle charstring parsing states */
 430.504 +  typedef enum  T1_ParseState_
 430.505 +  {
 430.506 +    T1_Parse_Start,
 430.507 +    T1_Parse_Have_Width,
 430.508 +    T1_Parse_Have_Moveto,
 430.509 +    T1_Parse_Have_Path
 430.510 +
 430.511 +  } T1_ParseState;
 430.512 +
 430.513 +
 430.514 +  /*************************************************************************/
 430.515 +  /*                                                                       */
 430.516 +  /* <Structure>                                                           */
 430.517 +  /*    T1_BuilderRec                                                      */
 430.518 +  /*                                                                       */
 430.519 +  /* <Description>                                                         */
 430.520 +  /*     A structure used during glyph loading to store its outline.       */
 430.521 +  /*                                                                       */
 430.522 +  /* <Fields>                                                              */
 430.523 +  /*    memory       :: The current memory object.                         */
 430.524 +  /*                                                                       */
 430.525 +  /*    face         :: The current face object.                           */
 430.526 +  /*                                                                       */
 430.527 +  /*    glyph        :: The current glyph slot.                            */
 430.528 +  /*                                                                       */
 430.529 +  /*    loader       :: XXX                                                */
 430.530 +  /*                                                                       */
 430.531 +  /*    base         :: The base glyph outline.                            */
 430.532 +  /*                                                                       */
 430.533 +  /*    current      :: The current glyph outline.                         */
 430.534 +  /*                                                                       */
 430.535 +  /*    max_points   :: maximum points in builder outline                  */
 430.536 +  /*                                                                       */
 430.537 +  /*    max_contours :: Maximal number of contours in builder outline.     */
 430.538 +  /*                                                                       */
 430.539 +  /*    pos_x        :: The horizontal translation (if composite glyph).   */
 430.540 +  /*                                                                       */
 430.541 +  /*    pos_y        :: The vertical translation (if composite glyph).     */
 430.542 +  /*                                                                       */
 430.543 +  /*    left_bearing :: The left side bearing point.                       */
 430.544 +  /*                                                                       */
 430.545 +  /*    advance      :: The horizontal advance vector.                     */
 430.546 +  /*                                                                       */
 430.547 +  /*    bbox         :: Unused.                                            */
 430.548 +  /*                                                                       */
 430.549 +  /*    parse_state  :: An enumeration which controls the charstring       */
 430.550 +  /*                    parsing state.                                     */
 430.551 +  /*                                                                       */
 430.552 +  /*    load_points  :: If this flag is not set, no points are loaded.     */
 430.553 +  /*                                                                       */
 430.554 +  /*    no_recurse   :: Set but not used.                                  */
 430.555 +  /*                                                                       */
 430.556 +  /*    metrics_only :: A boolean indicating that we only want to compute  */
 430.557 +  /*                    the metrics of a given glyph, not load all of its  */
 430.558 +  /*                    points.                                            */
 430.559 +  /*                                                                       */
 430.560 +  /*    funcs        :: An array of function pointers for the builder.     */
 430.561 +  /*                                                                       */
 430.562 +  typedef struct  T1_BuilderRec_
 430.563 +  {
 430.564 +    FT_Memory       memory;
 430.565 +    FT_Face         face;
 430.566 +    FT_GlyphSlot    glyph;
 430.567 +    FT_GlyphLoader  loader;
 430.568 +    FT_Outline*     base;
 430.569 +    FT_Outline*     current;
 430.570 +
 430.571 +    FT_Pos          pos_x;
 430.572 +    FT_Pos          pos_y;
 430.573 +
 430.574 +    FT_Vector       left_bearing;
 430.575 +    FT_Vector       advance;
 430.576 +
 430.577 +    FT_BBox         bbox;          /* bounding box */
 430.578 +    T1_ParseState   parse_state;
 430.579 +    FT_Bool         load_points;
 430.580 +    FT_Bool         no_recurse;
 430.581 +
 430.582 +    FT_Bool         metrics_only;
 430.583 +
 430.584 +    void*           hints_funcs;    /* hinter-specific */
 430.585 +    void*           hints_globals;  /* hinter-specific */
 430.586 +
 430.587 +    T1_Builder_FuncsRec  funcs;
 430.588 +
 430.589 +  } T1_BuilderRec;
 430.590 +
 430.591 +
 430.592 +  /*************************************************************************/
 430.593 +  /*************************************************************************/
 430.594 +  /*****                                                               *****/
 430.595 +  /*****                         T1 DECODER                            *****/
 430.596 +  /*****                                                               *****/
 430.597 +  /*************************************************************************/
 430.598 +  /*************************************************************************/
 430.599 +
 430.600 +#if 0
 430.601 +
 430.602 +  /*************************************************************************/
 430.603 +  /*                                                                       */
 430.604 +  /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine   */
 430.605 +  /* calls during glyph loading.                                           */
 430.606 +  /*                                                                       */
 430.607 +#define T1_MAX_SUBRS_CALLS  8
 430.608 +
 430.609 +
 430.610 +  /*************************************************************************/
 430.611 +  /*                                                                       */
 430.612 +  /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity.  A     */
 430.613 +  /* minimum of 16 is required.                                            */
 430.614 +  /*                                                                       */
 430.615 +#define T1_MAX_CHARSTRINGS_OPERANDS  32
 430.616 +
 430.617 +#endif /* 0 */
 430.618 +
 430.619 +
 430.620 +  typedef struct  T1_Decoder_ZoneRec_
 430.621 +  {
 430.622 +    FT_Byte*  cursor;
 430.623 +    FT_Byte*  base;
 430.624 +    FT_Byte*  limit;
 430.625 +
 430.626 +  } T1_Decoder_ZoneRec, *T1_Decoder_Zone;
 430.627 +
 430.628 +
 430.629 +  typedef struct T1_DecoderRec_*              T1_Decoder;
 430.630 +  typedef const struct T1_Decoder_FuncsRec_*  T1_Decoder_Funcs;
 430.631 +
 430.632 +
 430.633 +  typedef FT_Error
 430.634 +  (*T1_Decoder_Callback)( T1_Decoder  decoder,
 430.635 +                          FT_UInt     glyph_index );
 430.636 +
 430.637 +
 430.638 +  typedef struct  T1_Decoder_FuncsRec_
 430.639 +  {
 430.640 +    FT_Error
 430.641 +    (*init)( T1_Decoder           decoder,
 430.642 +             FT_Face              face,
 430.643 +             FT_Size              size,
 430.644 +             FT_GlyphSlot         slot,
 430.645 +             FT_Byte**            glyph_names,
 430.646 +             PS_Blend             blend,
 430.647 +             FT_Bool              hinting,
 430.648 +             FT_Render_Mode       hint_mode,
 430.649 +             T1_Decoder_Callback  callback );
 430.650 +
 430.651 +    void
 430.652 +    (*done)( T1_Decoder  decoder );
 430.653 +
 430.654 +    FT_Error
 430.655 +    (*parse_charstrings)( T1_Decoder  decoder,
 430.656 +                          FT_Byte*    base,
 430.657 +                          FT_UInt     len );
 430.658 +
 430.659 +  } T1_Decoder_FuncsRec;
 430.660 +
 430.661 +
 430.662 +  typedef struct  T1_DecoderRec_
 430.663 +  {
 430.664 +    T1_BuilderRec        builder;
 430.665 +
 430.666 +    FT_Long              stack[T1_MAX_CHARSTRINGS_OPERANDS];
 430.667 +    FT_Long*             top;
 430.668 +
 430.669 +    T1_Decoder_ZoneRec   zones[T1_MAX_SUBRS_CALLS + 1];
 430.670 +    T1_Decoder_Zone      zone;
 430.671 +
 430.672 +    FT_Service_PsCMaps   psnames;      /* for seac */
 430.673 +    FT_UInt              num_glyphs;
 430.674 +    FT_Byte**            glyph_names;
 430.675 +
 430.676 +    FT_Int               lenIV;        /* internal for sub routine calls */
 430.677 +    FT_UInt              num_subrs;
 430.678 +    FT_Byte**            subrs;
 430.679 +    FT_PtrDist*          subrs_len;    /* array of subrs length (optional) */
 430.680 +
 430.681 +    FT_Matrix            font_matrix;
 430.682 +    FT_Vector            font_offset;
 430.683 +
 430.684 +    FT_Int               flex_state;
 430.685 +    FT_Int               num_flex_vectors;
 430.686 +    FT_Vector            flex_vectors[7];
 430.687 +
 430.688 +    PS_Blend             blend;       /* for multiple master support */
 430.689 +
 430.690 +    FT_Render_Mode       hint_mode;
 430.691 +
 430.692 +    T1_Decoder_Callback  parse_callback;
 430.693 +    T1_Decoder_FuncsRec  funcs;
 430.694 +
 430.695 +    FT_Long*             buildchar;
 430.696 +    FT_UInt              len_buildchar;
 430.697 +
 430.698 +    FT_Bool              seac;
 430.699 +
 430.700 +  } T1_DecoderRec;
 430.701 +
 430.702 +
 430.703 +  /*************************************************************************/
 430.704 +  /*************************************************************************/
 430.705 +  /*****                                                               *****/
 430.706 +  /*****                            AFM PARSER                         *****/
 430.707 +  /*****                                                               *****/
 430.708 +  /*************************************************************************/
 430.709 +  /*************************************************************************/
 430.710 +
 430.711 +  typedef struct AFM_ParserRec_*  AFM_Parser;
 430.712 +
 430.713 +  typedef struct  AFM_Parser_FuncsRec_
 430.714 +  {
 430.715 +    FT_Error
 430.716 +    (*init)( AFM_Parser  parser,
 430.717 +             FT_Memory   memory,
 430.718 +             FT_Byte*    base,
 430.719 +             FT_Byte*    limit );
 430.720 +
 430.721 +    void
 430.722 +    (*done)( AFM_Parser  parser );
 430.723 +
 430.724 +    FT_Error
 430.725 +    (*parse)( AFM_Parser  parser );
 430.726 +
 430.727 +  } AFM_Parser_FuncsRec;
 430.728 +
 430.729 +
 430.730 +  typedef struct AFM_StreamRec_*  AFM_Stream;
 430.731 +
 430.732 +
 430.733 +  /*************************************************************************/
 430.734 +  /*                                                                       */
 430.735 +  /* <Struct>                                                              */
 430.736 +  /*    AFM_ParserRec                                                      */
 430.737 +  /*                                                                       */
 430.738 +  /* <Description>                                                         */
 430.739 +  /*    An AFM_Parser is a parser for the AFM files.                       */
 430.740 +  /*                                                                       */
 430.741 +  /* <Fields>                                                              */
 430.742 +  /*    memory    :: The object used for memory operations (alloc and      */
 430.743 +  /*                 realloc).                                             */
 430.744 +  /*                                                                       */
 430.745 +  /*    stream    :: This is an opaque object.                             */
 430.746 +  /*                                                                       */
 430.747 +  /*    FontInfo  :: The result will be stored here.                       */
 430.748 +  /*                                                                       */
 430.749 +  /*    get_index :: A user provided function to get a glyph index by its  */
 430.750 +  /*                 name.                                                 */
 430.751 +  /*                                                                       */
 430.752 +  typedef struct  AFM_ParserRec_
 430.753 +  {
 430.754 +    FT_Memory     memory;
 430.755 +    AFM_Stream    stream;
 430.756 +
 430.757 +    AFM_FontInfo  FontInfo;
 430.758 +
 430.759 +    FT_Int
 430.760 +    (*get_index)( const char*  name,
 430.761 +                  FT_Offset    len,
 430.762 +                  void*        user_data );
 430.763 +
 430.764 +    void*         user_data;
 430.765 +
 430.766 +  } AFM_ParserRec;
 430.767 +
 430.768 +
 430.769 +  /*************************************************************************/
 430.770 +  /*************************************************************************/
 430.771 +  /*****                                                               *****/
 430.772 +  /*****                     TYPE1 CHARMAPS                            *****/
 430.773 +  /*****                                                               *****/
 430.774 +  /*************************************************************************/
 430.775 +  /*************************************************************************/
 430.776 +
 430.777 +  typedef const struct T1_CMap_ClassesRec_*  T1_CMap_Classes;
 430.778 +
 430.779 +  typedef struct T1_CMap_ClassesRec_
 430.780 +  {
 430.781 +    FT_CMap_Class  standard;
 430.782 +    FT_CMap_Class  expert;
 430.783 +    FT_CMap_Class  custom;
 430.784 +    FT_CMap_Class  unicode;
 430.785 +
 430.786 +  } T1_CMap_ClassesRec;
 430.787 +
 430.788 +
 430.789 +  /*************************************************************************/
 430.790 +  /*************************************************************************/
 430.791 +  /*****                                                               *****/
 430.792 +  /*****                        PSAux Module Interface                 *****/
 430.793 +  /*****                                                               *****/
 430.794 +  /*************************************************************************/
 430.795 +  /*************************************************************************/
 430.796 +
 430.797 +  typedef struct  PSAux_ServiceRec_
 430.798 +  {
 430.799 +    /* don't use `PS_Table_Funcs' and friends to avoid compiler warnings */
 430.800 +    const PS_Table_FuncsRec*    ps_table_funcs;
 430.801 +    const PS_Parser_FuncsRec*   ps_parser_funcs;
 430.802 +    const T1_Builder_FuncsRec*  t1_builder_funcs;
 430.803 +    const T1_Decoder_FuncsRec*  t1_decoder_funcs;
 430.804 +
 430.805 +    void
 430.806 +    (*t1_decrypt)( FT_Byte*   buffer,
 430.807 +                   FT_Offset  length,
 430.808 +                   FT_UShort  seed );
 430.809 +
 430.810 +    T1_CMap_Classes  t1_cmap_classes;
 430.811 +
 430.812 +    /* fields after this comment line were added after version 2.1.10 */
 430.813 +    const AFM_Parser_FuncsRec*  afm_parser_funcs;
 430.814 +
 430.815 +  } PSAux_ServiceRec, *PSAux_Service;
 430.816 +
 430.817 +  /* backwards-compatible type definition */
 430.818 +  typedef PSAux_ServiceRec   PSAux_Interface;
 430.819 +
 430.820 +
 430.821 +  /*************************************************************************/
 430.822 +  /*************************************************************************/
 430.823 +  /*****                                                               *****/
 430.824 +  /*****                 Some convenience functions                    *****/
 430.825 +  /*****                                                               *****/
 430.826 +  /*************************************************************************/
 430.827 +  /*************************************************************************/
 430.828 +
 430.829 +#define IS_PS_NEWLINE( ch ) \
 430.830 +  ( (ch) == '\r' ||         \
 430.831 +    (ch) == '\n' )
 430.832 +
 430.833 +#define IS_PS_SPACE( ch )  \
 430.834 +  ( (ch) == ' '         || \
 430.835 +    IS_PS_NEWLINE( ch ) || \
 430.836 +    (ch) == '\t'        || \
 430.837 +    (ch) == '\f'        || \
 430.838 +    (ch) == '\0' )
 430.839 +
 430.840 +#define IS_PS_SPECIAL( ch )       \
 430.841 +  ( (ch) == '/'                || \
 430.842 +    (ch) == '(' || (ch) == ')' || \
 430.843 +    (ch) == '<' || (ch) == '>' || \
 430.844 +    (ch) == '[' || (ch) == ']' || \
 430.845 +    (ch) == '{' || (ch) == '}' || \
 430.846 +    (ch) == '%'                )
 430.847 +
 430.848 +#define IS_PS_DELIM( ch )  \
 430.849 +  ( IS_PS_SPACE( ch )   || \
 430.850 +    IS_PS_SPECIAL( ch ) )
 430.851 +
 430.852 +#define IS_PS_DIGIT( ch )        \
 430.853 +  ( (ch) >= '0' && (ch) <= '9' )
 430.854 +
 430.855 +#define IS_PS_XDIGIT( ch )            \
 430.856 +  ( IS_PS_DIGIT( ch )              || \
 430.857 +    ( (ch) >= 'A' && (ch) <= 'F' ) || \
 430.858 +    ( (ch) >= 'a' && (ch) <= 'f' ) )
 430.859 +
 430.860 +#define IS_PS_BASE85( ch )       \
 430.861 +  ( (ch) >= '!' && (ch) <= 'u' )
 430.862 +
 430.863 +#define IS_PS_TOKEN( cur, limit, token )                                \
 430.864 +  ( (char)(cur)[0] == (token)[0]                                     && \
 430.865 +    ( (cur) + sizeof ( (token) ) == (limit) ||                          \
 430.866 +      ( (cur) + sizeof( (token) ) < (limit)          &&                 \
 430.867 +        IS_PS_DELIM( (cur)[sizeof ( (token) ) - 1] ) ) )             && \
 430.868 +    ft_strncmp( (char*)(cur), (token), sizeof ( (token) ) - 1 ) == 0 )
 430.869 +
 430.870 +
 430.871 +FT_END_HEADER
 430.872 +
 430.873 +#endif /* __PSAUX_H__ */
 430.874 +
 430.875 +
 430.876 +/* END */
   431.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   431.2 +++ b/libs/ft2static/freetype/internal/pshints.h	Sat Feb 01 19:58:19 2014 +0200
   431.3 @@ -0,0 +1,712 @@
   431.4 +/***************************************************************************/
   431.5 +/*                                                                         */
   431.6 +/*  pshints.h                                                              */
   431.7 +/*                                                                         */
   431.8 +/*    Interface to Postscript-specific (Type 1 and Type 2) hints           */
   431.9 +/*    recorders (specification only).  These are used to support native    */
  431.10 +/*    T1/T2 hints in the `type1', `cid', and `cff' font drivers.           */
  431.11 +/*                                                                         */
  431.12 +/*  Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009 by                  */
  431.13 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  431.14 +/*                                                                         */
  431.15 +/*  This file is part of the FreeType project, and may only be used,       */
  431.16 +/*  modified, and distributed under the terms of the FreeType project      */
  431.17 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  431.18 +/*  this file you indicate that you have read the license and              */
  431.19 +/*  understand and accept it fully.                                        */
  431.20 +/*                                                                         */
  431.21 +/***************************************************************************/
  431.22 +
  431.23 +
  431.24 +#ifndef __PSHINTS_H__
  431.25 +#define __PSHINTS_H__
  431.26 +
  431.27 +
  431.28 +#include <ft2build.h>
  431.29 +#include FT_FREETYPE_H
  431.30 +#include FT_TYPE1_TABLES_H
  431.31 +
  431.32 +
  431.33 +FT_BEGIN_HEADER
  431.34 +
  431.35 +
  431.36 +  /*************************************************************************/
  431.37 +  /*************************************************************************/
  431.38 +  /*****                                                               *****/
  431.39 +  /*****               INTERNAL REPRESENTATION OF GLOBALS              *****/
  431.40 +  /*****                                                               *****/
  431.41 +  /*************************************************************************/
  431.42 +  /*************************************************************************/
  431.43 +
  431.44 +  typedef struct PSH_GlobalsRec_*  PSH_Globals;
  431.45 +
  431.46 +  typedef FT_Error
  431.47 +  (*PSH_Globals_NewFunc)( FT_Memory     memory,
  431.48 +                          T1_Private*   private_dict,
  431.49 +                          PSH_Globals*  aglobals );
  431.50 +
  431.51 +  typedef FT_Error
  431.52 +  (*PSH_Globals_SetScaleFunc)( PSH_Globals  globals,
  431.53 +                               FT_Fixed     x_scale,
  431.54 +                               FT_Fixed     y_scale,
  431.55 +                               FT_Fixed     x_delta,
  431.56 +                               FT_Fixed     y_delta );
  431.57 +
  431.58 +  typedef void
  431.59 +  (*PSH_Globals_DestroyFunc)( PSH_Globals  globals );
  431.60 +
  431.61 +
  431.62 +  typedef struct  PSH_Globals_FuncsRec_
  431.63 +  {
  431.64 +    PSH_Globals_NewFunc       create;
  431.65 +    PSH_Globals_SetScaleFunc  set_scale;
  431.66 +    PSH_Globals_DestroyFunc   destroy;
  431.67 +
  431.68 +  } PSH_Globals_FuncsRec, *PSH_Globals_Funcs;
  431.69 +
  431.70 +
  431.71 +  /*************************************************************************/
  431.72 +  /*************************************************************************/
  431.73 +  /*****                                                               *****/
  431.74 +  /*****                  PUBLIC TYPE 1 HINTS RECORDER                 *****/
  431.75 +  /*****                                                               *****/
  431.76 +  /*************************************************************************/
  431.77 +  /*************************************************************************/
  431.78 +
  431.79 +  /*************************************************************************
  431.80 +   *
  431.81 +   * @type:
  431.82 +   *   T1_Hints
  431.83 +   *
  431.84 +   * @description:
  431.85 +   *   This is a handle to an opaque structure used to record glyph hints
  431.86 +   *   from a Type 1 character glyph character string.
  431.87 +   *
  431.88 +   *   The methods used to operate on this object are defined by the
  431.89 +   *   @T1_Hints_FuncsRec structure.  Recording glyph hints is normally
  431.90 +   *   achieved through the following scheme:
  431.91 +   *
  431.92 +   *   - Open a new hint recording session by calling the `open' method.
  431.93 +   *     This rewinds the recorder and prepare it for new input.
  431.94 +   *
  431.95 +   *   - For each hint found in the glyph charstring, call the corresponding
  431.96 +   *     method (`stem', `stem3', or `reset').  Note that these functions do
  431.97 +   *     not return an error code.
  431.98 +   *
  431.99 +   *   - Close the recording session by calling the `close' method.  It
 431.100 +   *     returns an error code if the hints were invalid or something
 431.101 +   *     strange happened (e.g., memory shortage).
 431.102 +   *
 431.103 +   *   The hints accumulated in the object can later be used by the
 431.104 +   *   PostScript hinter.
 431.105 +   *
 431.106 +   */
 431.107 +  typedef struct T1_HintsRec_*  T1_Hints;
 431.108 +
 431.109 +
 431.110 +  /*************************************************************************
 431.111 +   *
 431.112 +   * @type:
 431.113 +   *   T1_Hints_Funcs
 431.114 +   *
 431.115 +   * @description:
 431.116 +   *   A pointer to the @T1_Hints_FuncsRec structure that defines the API of
 431.117 +   *   a given @T1_Hints object.
 431.118 +   *
 431.119 +   */
 431.120 +  typedef const struct T1_Hints_FuncsRec_*  T1_Hints_Funcs;
 431.121 +
 431.122 +
 431.123 +  /*************************************************************************
 431.124 +   *
 431.125 +   * @functype:
 431.126 +   *   T1_Hints_OpenFunc
 431.127 +   *
 431.128 +   * @description:
 431.129 +   *   A method of the @T1_Hints class used to prepare it for a new Type 1
 431.130 +   *   hints recording session.
 431.131 +   *
 431.132 +   * @input:
 431.133 +   *   hints ::
 431.134 +   *     A handle to the Type 1 hints recorder.
 431.135 +   *
 431.136 +   * @note:
 431.137 +   *   You should always call the @T1_Hints_CloseFunc method in order to
 431.138 +   *   close an opened recording session.
 431.139 +   *
 431.140 +   */
 431.141 +  typedef void
 431.142 +  (*T1_Hints_OpenFunc)( T1_Hints  hints );
 431.143 +
 431.144 +
 431.145 +  /*************************************************************************
 431.146 +   *
 431.147 +   * @functype:
 431.148 +   *   T1_Hints_SetStemFunc
 431.149 +   *
 431.150 +   * @description:
 431.151 +   *   A method of the @T1_Hints class used to record a new horizontal or
 431.152 +   *   vertical stem.  This corresponds to the Type 1 `hstem' and `vstem'
 431.153 +   *   operators.
 431.154 +   *
 431.155 +   * @input:
 431.156 +   *   hints ::
 431.157 +   *     A handle to the Type 1 hints recorder.
 431.158 +   *
 431.159 +   *   dimension ::
 431.160 +   *     0 for horizontal stems (hstem), 1 for vertical ones (vstem).
 431.161 +   *
 431.162 +   *   coords ::
 431.163 +   *     Array of 2 coordinates in 16.16 format, used as (position,length)
 431.164 +   *     stem descriptor.
 431.165 +   *
 431.166 +   * @note:
 431.167 +   *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use
 431.168 +   *   horizontal coordinates (x) for vertical stems (dim=1).
 431.169 +   *
 431.170 +   *   `coords[0]' is the absolute stem position (lowest coordinate);
 431.171 +   *   `coords[1]' is the length.
 431.172 +   *
 431.173 +   *   The length can be negative, in which case it must be either -20 or
 431.174 +   *   -21.  It is interpreted as a `ghost' stem, according to the Type 1
 431.175 +   *   specification.
 431.176 +   *
 431.177 +   *   If the length is -21 (corresponding to a bottom ghost stem), then
 431.178 +   *   the real stem position is `coords[0]+coords[1]'.
 431.179 +   *
 431.180 +   */
 431.181 +  typedef void
 431.182 +  (*T1_Hints_SetStemFunc)( T1_Hints   hints,
 431.183 +                           FT_UInt    dimension,
 431.184 +                           FT_Fixed*  coords );
 431.185 +
 431.186 +
 431.187 +  /*************************************************************************
 431.188 +   *
 431.189 +   * @functype:
 431.190 +   *   T1_Hints_SetStem3Func
 431.191 +   *
 431.192 +   * @description:
 431.193 +   *   A method of the @T1_Hints class used to record three
 431.194 +   *   counter-controlled horizontal or vertical stems at once.
 431.195 +   *
 431.196 +   * @input:
 431.197 +   *   hints ::
 431.198 +   *     A handle to the Type 1 hints recorder.
 431.199 +   *
 431.200 +   *   dimension ::
 431.201 +   *     0 for horizontal stems, 1 for vertical ones.
 431.202 +   *
 431.203 +   *   coords ::
 431.204 +   *     An array of 6 values in 16.16 format, holding 3 (position,length)
 431.205 +   *     pairs for the counter-controlled stems.
 431.206 +   *
 431.207 +   * @note:
 431.208 +   *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use
 431.209 +   *   horizontal coordinates (x) for vertical stems (dim=1).
 431.210 +   *
 431.211 +   *   The lengths cannot be negative (ghost stems are never
 431.212 +   *   counter-controlled).
 431.213 +   *
 431.214 +   */
 431.215 +  typedef void
 431.216 +  (*T1_Hints_SetStem3Func)( T1_Hints   hints,
 431.217 +                            FT_UInt    dimension,
 431.218 +                            FT_Fixed*  coords );
 431.219 +
 431.220 +
 431.221 +  /*************************************************************************
 431.222 +   *
 431.223 +   * @functype:
 431.224 +   *   T1_Hints_ResetFunc
 431.225 +   *
 431.226 +   * @description:
 431.227 +   *   A method of the @T1_Hints class used to reset the stems hints in a
 431.228 +   *   recording session.
 431.229 +   *
 431.230 +   * @input:
 431.231 +   *   hints ::
 431.232 +   *     A handle to the Type 1 hints recorder.
 431.233 +   *
 431.234 +   *   end_point ::
 431.235 +   *     The index of the last point in the input glyph in which the
 431.236 +   *     previously defined hints apply.
 431.237 +   *
 431.238 +   */
 431.239 +  typedef void
 431.240 +  (*T1_Hints_ResetFunc)( T1_Hints  hints,
 431.241 +                         FT_UInt   end_point );
 431.242 +
 431.243 +
 431.244 +  /*************************************************************************
 431.245 +   *
 431.246 +   * @functype:
 431.247 +   *   T1_Hints_CloseFunc
 431.248 +   *
 431.249 +   * @description:
 431.250 +   *   A method of the @T1_Hints class used to close a hint recording
 431.251 +   *   session.
 431.252 +   *
 431.253 +   * @input:
 431.254 +   *   hints ::
 431.255 +   *     A handle to the Type 1 hints recorder.
 431.256 +   *
 431.257 +   *   end_point ::
 431.258 +   *     The index of the last point in the input glyph.
 431.259 +   *
 431.260 +   * @return:
 431.261 +   *   FreeType error code.  0 means success.
 431.262 +   *
 431.263 +   * @note:
 431.264 +   *   The error code is set to indicate that an error occurred during the
 431.265 +   *   recording session.
 431.266 +   *
 431.267 +   */
 431.268 +  typedef FT_Error
 431.269 +  (*T1_Hints_CloseFunc)( T1_Hints  hints,
 431.270 +                         FT_UInt   end_point );
 431.271 +
 431.272 +
 431.273 +  /*************************************************************************
 431.274 +   *
 431.275 +   * @functype:
 431.276 +   *   T1_Hints_ApplyFunc
 431.277 +   *
 431.278 +   * @description:
 431.279 +   *   A method of the @T1_Hints class used to apply hints to the
 431.280 +   *   corresponding glyph outline.  Must be called once all hints have been
 431.281 +   *   recorded.
 431.282 +   *
 431.283 +   * @input:
 431.284 +   *   hints ::
 431.285 +   *     A handle to the Type 1 hints recorder.
 431.286 +   *
 431.287 +   *   outline ::
 431.288 +   *     A pointer to the target outline descriptor.
 431.289 +   *
 431.290 +   *   globals ::
 431.291 +   *     The hinter globals for this font.
 431.292 +   *
 431.293 +   *   hint_mode ::
 431.294 +   *     Hinting information.
 431.295 +   *
 431.296 +   * @return:
 431.297 +   *   FreeType error code.  0 means success.
 431.298 +   *
 431.299 +   * @note:
 431.300 +   *   On input, all points within the outline are in font coordinates. On
 431.301 +   *   output, they are in 1/64th of pixels.
 431.302 +   *
 431.303 +   *   The scaling transformation is taken from the `globals' object which
 431.304 +   *   must correspond to the same font as the glyph.
 431.305 +   *
 431.306 +   */
 431.307 +  typedef FT_Error
 431.308 +  (*T1_Hints_ApplyFunc)( T1_Hints        hints,
 431.309 +                         FT_Outline*     outline,
 431.310 +                         PSH_Globals     globals,
 431.311 +                         FT_Render_Mode  hint_mode );
 431.312 +
 431.313 +
 431.314 +  /*************************************************************************
 431.315 +   *
 431.316 +   * @struct:
 431.317 +   *   T1_Hints_FuncsRec
 431.318 +   *
 431.319 +   * @description:
 431.320 +   *   The structure used to provide the API to @T1_Hints objects.
 431.321 +   *
 431.322 +   * @fields:
 431.323 +   *   hints ::
 431.324 +   *     A handle to the T1 Hints recorder.
 431.325 +   *
 431.326 +   *   open ::
 431.327 +   *     The function to open a recording session.
 431.328 +   *
 431.329 +   *   close ::
 431.330 +   *     The function to close a recording session.
 431.331 +   *
 431.332 +   *   stem ::
 431.333 +   *     The function to set a simple stem.
 431.334 +   *
 431.335 +   *   stem3 ::
 431.336 +   *     The function to set counter-controlled stems.
 431.337 +   *
 431.338 +   *   reset ::
 431.339 +   *     The function to reset stem hints.
 431.340 +   *
 431.341 +   *   apply ::
 431.342 +   *     The function to apply the hints to the corresponding glyph outline.
 431.343 +   *
 431.344 +   */
 431.345 +  typedef struct  T1_Hints_FuncsRec_
 431.346 +  {
 431.347 +    T1_Hints               hints;
 431.348 +    T1_Hints_OpenFunc      open;
 431.349 +    T1_Hints_CloseFunc     close;
 431.350 +    T1_Hints_SetStemFunc   stem;
 431.351 +    T1_Hints_SetStem3Func  stem3;
 431.352 +    T1_Hints_ResetFunc     reset;
 431.353 +    T1_Hints_ApplyFunc     apply;
 431.354 +
 431.355 +  } T1_Hints_FuncsRec;
 431.356 +
 431.357 +
 431.358 +  /*************************************************************************/
 431.359 +  /*************************************************************************/
 431.360 +  /*****                                                               *****/
 431.361 +  /*****                  PUBLIC TYPE 2 HINTS RECORDER                 *****/
 431.362 +  /*****                                                               *****/
 431.363 +  /*************************************************************************/
 431.364 +  /*************************************************************************/
 431.365 +
 431.366 +  /*************************************************************************
 431.367 +   *
 431.368 +   * @type:
 431.369 +   *   T2_Hints
 431.370 +   *
 431.371 +   * @description:
 431.372 +   *   This is a handle to an opaque structure used to record glyph hints
 431.373 +   *   from a Type 2 character glyph character string.
 431.374 +   *
 431.375 +   *   The methods used to operate on this object are defined by the
 431.376 +   *   @T2_Hints_FuncsRec structure.  Recording glyph hints is normally
 431.377 +   *   achieved through the following scheme:
 431.378 +   *
 431.379 +   *   - Open a new hint recording session by calling the `open' method.
 431.380 +   *     This rewinds the recorder and prepare it for new input.
 431.381 +   *
 431.382 +   *   - For each hint found in the glyph charstring, call the corresponding
 431.383 +   *     method (`stems', `hintmask', `counters').  Note that these
 431.384 +   *     functions do not return an error code.
 431.385 +   *
 431.386 +   *   - Close the recording session by calling the `close' method.  It
 431.387 +   *     returns an error code if the hints were invalid or something
 431.388 +   *     strange happened (e.g., memory shortage).
 431.389 +   *
 431.390 +   *   The hints accumulated in the object can later be used by the
 431.391 +   *   Postscript hinter.
 431.392 +   *
 431.393 +   */
 431.394 +  typedef struct T2_HintsRec_*  T2_Hints;
 431.395 +
 431.396 +
 431.397 +  /*************************************************************************
 431.398 +   *
 431.399 +   * @type:
 431.400 +   *   T2_Hints_Funcs
 431.401 +   *
 431.402 +   * @description:
 431.403 +   *   A pointer to the @T2_Hints_FuncsRec structure that defines the API of
 431.404 +   *   a given @T2_Hints object.
 431.405 +   *
 431.406 +   */
 431.407 +  typedef const struct T2_Hints_FuncsRec_*  T2_Hints_Funcs;
 431.408 +
 431.409 +
 431.410 +  /*************************************************************************
 431.411 +   *
 431.412 +   * @functype:
 431.413 +   *   T2_Hints_OpenFunc
 431.414 +   *
 431.415 +   * @description:
 431.416 +   *   A method of the @T2_Hints class used to prepare it for a new Type 2
 431.417 +   *   hints recording session.
 431.418 +   *
 431.419 +   * @input:
 431.420 +   *   hints ::
 431.421 +   *     A handle to the Type 2 hints recorder.
 431.422 +   *
 431.423 +   * @note:
 431.424 +   *   You should always call the @T2_Hints_CloseFunc method in order to
 431.425 +   *   close an opened recording session.
 431.426 +   *
 431.427 +   */
 431.428 +  typedef void
 431.429 +  (*T2_Hints_OpenFunc)( T2_Hints  hints );
 431.430 +
 431.431 +
 431.432 +  /*************************************************************************
 431.433 +   *
 431.434 +   * @functype:
 431.435 +   *   T2_Hints_StemsFunc
 431.436 +   *
 431.437 +   * @description:
 431.438 +   *   A method of the @T2_Hints class used to set the table of stems in
 431.439 +   *   either the vertical or horizontal dimension.  Equivalent to the
 431.440 +   *   `hstem', `vstem', `hstemhm', and `vstemhm' Type 2 operators.
 431.441 +   *
 431.442 +   * @input:
 431.443 +   *   hints ::
 431.444 +   *     A handle to the Type 2 hints recorder.
 431.445 +   *
 431.446 +   *   dimension ::
 431.447 +   *     0 for horizontal stems (hstem), 1 for vertical ones (vstem).
 431.448 +   *
 431.449 +   *   count ::
 431.450 +   *     The number of stems.
 431.451 +   *
 431.452 +   *   coords ::
 431.453 +   *     An array of `count' (position,length) pairs in 16.16 format.
 431.454 +   *
 431.455 +   * @note:
 431.456 +   *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use
 431.457 +   *   horizontal coordinates (x) for vertical stems (dim=1).
 431.458 +   *
 431.459 +   *   There are `2*count' elements in the `coords' array.  Each even
 431.460 +   *   element is an absolute position in font units, each odd element is a
 431.461 +   *   length in font units.
 431.462 +   *
 431.463 +   *   A length can be negative, in which case it must be either -20 or
 431.464 +   *   -21.  It is interpreted as a `ghost' stem, according to the Type 1
 431.465 +   *   specification.
 431.466 +   *
 431.467 +   */
 431.468 +  typedef void
 431.469 +  (*T2_Hints_StemsFunc)( T2_Hints   hints,
 431.470 +                         FT_UInt    dimension,
 431.471 +                         FT_UInt    count,
 431.472 +                         FT_Fixed*  coordinates );
 431.473 +
 431.474 +
 431.475 +  /*************************************************************************
 431.476 +   *
 431.477 +   * @functype:
 431.478 +   *   T2_Hints_MaskFunc
 431.479 +   *
 431.480 +   * @description:
 431.481 +   *   A method of the @T2_Hints class used to set a given hintmask (this
 431.482 +   *   corresponds to the `hintmask' Type 2 operator).
 431.483 +   *
 431.484 +   * @input:
 431.485 +   *   hints ::
 431.486 +   *     A handle to the Type 2 hints recorder.
 431.487 +   *
 431.488 +   *   end_point ::
 431.489 +   *     The glyph index of the last point to which the previously defined
 431.490 +   *     or activated hints apply.
 431.491 +   *
 431.492 +   *   bit_count ::
 431.493 +   *     The number of bits in the hint mask.
 431.494 +   *
 431.495 +   *   bytes ::
 431.496 +   *     An array of bytes modelling the hint mask.
 431.497 +   *
 431.498 +   * @note:
 431.499 +   *   If the hintmask starts the charstring (before any glyph point
 431.500 +   *   definition), the value of `end_point' should be 0.
 431.501 +   *
 431.502 +   *   `bit_count' is the number of meaningful bits in the `bytes' array; it
 431.503 +   *   must be equal to the total number of hints defined so far (i.e.,
 431.504 +   *   horizontal+verticals).
 431.505 +   *
 431.506 +   *   The `bytes' array can come directly from the Type 2 charstring and
 431.507 +   *   respects the same format.
 431.508 +   *
 431.509 +   */
 431.510 +  typedef void
 431.511 +  (*T2_Hints_MaskFunc)( T2_Hints        hints,
 431.512 +                        FT_UInt         end_point,
 431.513 +                        FT_UInt         bit_count,
 431.514 +                        const FT_Byte*  bytes );
 431.515 +
 431.516 +
 431.517 +  /*************************************************************************
 431.518 +   *
 431.519 +   * @functype:
 431.520 +   *   T2_Hints_CounterFunc
 431.521 +   *
 431.522 +   * @description:
 431.523 +   *   A method of the @T2_Hints class used to set a given counter mask
 431.524 +   *   (this corresponds to the `hintmask' Type 2 operator).
 431.525 +   *
 431.526 +   * @input:
 431.527 +   *   hints ::
 431.528 +   *     A handle to the Type 2 hints recorder.
 431.529 +   *
 431.530 +   *   end_point ::
 431.531 +   *     A glyph index of the last point to which the previously defined or
 431.532 +   *     active hints apply.
 431.533 +   *
 431.534 +   *   bit_count ::
 431.535 +   *     The number of bits in the hint mask.
 431.536 +   *
 431.537 +   *   bytes ::
 431.538 +   *     An array of bytes modelling the hint mask.
 431.539 +   *
 431.540 +   * @note:
 431.541 +   *   If the hintmask starts the charstring (before any glyph point
 431.542 +   *   definition), the value of `end_point' should be 0.
 431.543 +   *
 431.544 +   *   `bit_count' is the number of meaningful bits in the `bytes' array; it
 431.545 +   *   must be equal to the total number of hints defined so far (i.e.,
 431.546 +   *   horizontal+verticals).
 431.547 +   *
 431.548 +   *    The `bytes' array can come directly from the Type 2 charstring and
 431.549 +   *    respects the same format.
 431.550 +   *
 431.551 +   */
 431.552 +  typedef void
 431.553 +  (*T2_Hints_CounterFunc)( T2_Hints        hints,
 431.554 +                           FT_UInt         bit_count,
 431.555 +                           const FT_Byte*  bytes );
 431.556 +
 431.557 +
 431.558 +  /*************************************************************************
 431.559 +   *
 431.560 +   * @functype:
 431.561 +   *   T2_Hints_CloseFunc
 431.562 +   *
 431.563 +   * @description:
 431.564 +   *   A method of the @T2_Hints class used to close a hint recording
 431.565 +   *   session.
 431.566 +   *
 431.567 +   * @input:
 431.568 +   *   hints ::
 431.569 +   *     A handle to the Type 2 hints recorder.
 431.570 +   *
 431.571 +   *   end_point ::
 431.572 +   *     The index of the last point in the input glyph.
 431.573 +   *
 431.574 +   * @return:
 431.575 +   *   FreeType error code.  0 means success.
 431.576 +   *
 431.577 +   * @note:
 431.578 +   *   The error code is set to indicate that an error occurred during the
 431.579 +   *   recording session.
 431.580 +   *
 431.581 +   */
 431.582 +  typedef FT_Error
 431.583 +  (*T2_Hints_CloseFunc)( T2_Hints  hints,
 431.584 +                         FT_UInt   end_point );
 431.585 +
 431.586 +
 431.587 +  /*************************************************************************
 431.588 +   *
 431.589 +   * @functype:
 431.590 +   *   T2_Hints_ApplyFunc
 431.591 +   *
 431.592 +   * @description:
 431.593 +   *   A method of the @T2_Hints class used to apply hints to the
 431.594 +   *   corresponding glyph outline.  Must be called after the `close'
 431.595 +   *   method.
 431.596 +   *
 431.597 +   * @input:
 431.598 +   *   hints ::
 431.599 +   *     A handle to the Type 2 hints recorder.
 431.600 +   *
 431.601 +   *   outline ::
 431.602 +   *     A pointer to the target outline descriptor.
 431.603 +   *
 431.604 +   *   globals ::
 431.605 +   *     The hinter globals for this font.
 431.606 +   *
 431.607 +   *   hint_mode ::
 431.608 +   *     Hinting information.
 431.609 +   *
 431.610 +   * @return:
 431.611 +   *   FreeType error code.  0 means success.
 431.612 +   *
 431.613 +   * @note:
 431.614 +   *   On input, all points within the outline are in font coordinates. On
 431.615 +   *   output, they are in 1/64th of pixels.
 431.616 +   *
 431.617 +   *   The scaling transformation is taken from the `globals' object which
 431.618 +   *   must correspond to the same font than the glyph.
 431.619 +   *
 431.620 +   */
 431.621 +  typedef FT_Error
 431.622 +  (*T2_Hints_ApplyFunc)( T2_Hints        hints,
 431.623 +                         FT_Outline*     outline,
 431.624 +                         PSH_Globals     globals,
 431.625 +                         FT_Render_Mode  hint_mode );
 431.626 +
 431.627 +
 431.628 +  /*************************************************************************
 431.629 +   *
 431.630 +   * @struct:
 431.631 +   *   T2_Hints_FuncsRec
 431.632 +   *
 431.633 +   * @description:
 431.634 +   *   The structure used to provide the API to @T2_Hints objects.
 431.635 +   *
 431.636 +   * @fields:
 431.637 +   *   hints ::
 431.638 +   *     A handle to the T2 hints recorder object.
 431.639 +   *
 431.640 +   *   open ::
 431.641 +   *     The function to open a recording session.
 431.642 +   *
 431.643 +   *   close ::
 431.644 +   *     The function to close a recording session.
 431.645 +   *
 431.646 +   *   stems ::
 431.647 +   *     The function to set the dimension's stems table.
 431.648 +   *
 431.649 +   *   hintmask ::
 431.650 +   *     The function to set hint masks.
 431.651 +   *
 431.652 +   *   counter ::
 431.653 +   *     The function to set counter masks.
 431.654 +   *
 431.655 +   *   apply ::
 431.656 +   *     The function to apply the hints on the corresponding glyph outline.
 431.657 +   *
 431.658 +   */
 431.659 +  typedef struct  T2_Hints_FuncsRec_
 431.660 +  {
 431.661 +    T2_Hints              hints;
 431.662 +    T2_Hints_OpenFunc     open;
 431.663 +    T2_Hints_CloseFunc    close;
 431.664 +    T2_Hints_StemsFunc    stems;
 431.665 +    T2_Hints_MaskFunc     hintmask;
 431.666 +    T2_Hints_CounterFunc  counter;
 431.667 +    T2_Hints_ApplyFunc    apply;
 431.668 +
 431.669 +  } T2_Hints_FuncsRec;
 431.670 +
 431.671 +
 431.672 +  /* */
 431.673 +
 431.674 +
 431.675 +  typedef struct  PSHinter_Interface_
 431.676 +  {
 431.677 +    PSH_Globals_Funcs  (*get_globals_funcs)( FT_Module  module );
 431.678 +    T1_Hints_Funcs     (*get_t1_funcs)     ( FT_Module  module );
 431.679 +    T2_Hints_Funcs     (*get_t2_funcs)     ( FT_Module  module );
 431.680 +
 431.681 +  } PSHinter_Interface;
 431.682 +
 431.683 +  typedef PSHinter_Interface*  PSHinter_Service;
 431.684 +
 431.685 +#ifndef FT_CONFIG_OPTION_PIC
 431.686 +
 431.687 +#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_,             \
 431.688 +                                     get_t1_funcs_, get_t2_funcs_)           \
 431.689 +  static const PSHinter_Interface class_ =                                   \
 431.690 +  {                                                                          \
 431.691 +    get_globals_funcs_, get_t1_funcs_, get_t2_funcs_                         \
 431.692 +  };
 431.693 +
 431.694 +#else /* FT_CONFIG_OPTION_PIC */ 
 431.695 +
 431.696 +#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_,             \
 431.697 +                                     get_t1_funcs_, get_t2_funcs_)           \
 431.698 +  void                                                                       \
 431.699 +  FT_Init_Class_##class_( FT_Library library,                                \
 431.700 +                          PSHinter_Interface*  clazz)                        \
 431.701 +  {                                                                          \
 431.702 +    FT_UNUSED(library);                                                      \
 431.703 +    clazz->get_globals_funcs = get_globals_funcs_;                           \
 431.704 +    clazz->get_t1_funcs = get_t1_funcs_;                                     \
 431.705 +    clazz->get_t2_funcs = get_t2_funcs_;                                     \
 431.706 +  } 
 431.707 +
 431.708 +#endif /* FT_CONFIG_OPTION_PIC */ 
 431.709 +
 431.710 +FT_END_HEADER
 431.711 +
 431.712 +#endif /* __PSHINTS_H__ */
 431.713 +
 431.714 +
 431.715 +/* END */
   432.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   432.2 +++ b/libs/ft2static/freetype/internal/services/svbdf.h	Sat Feb 01 19:58:19 2014 +0200
   432.3 @@ -0,0 +1,77 @@
   432.4 +/***************************************************************************/
   432.5 +/*                                                                         */
   432.6 +/*  svbdf.h                                                                */
   432.7 +/*                                                                         */
   432.8 +/*    The FreeType BDF services (specification).                           */
   432.9 +/*                                                                         */
  432.10 +/*  Copyright 2003 by                                                      */
  432.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  432.12 +/*                                                                         */
  432.13 +/*  This file is part of the FreeType project, and may only be used,       */
  432.14 +/*  modified, and distributed under the terms of the FreeType project      */
  432.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  432.16 +/*  this file you indicate that you have read the license and              */
  432.17 +/*  understand and accept it fully.                                        */
  432.18 +/*                                                                         */
  432.19 +/***************************************************************************/
  432.20 +
  432.21 +
  432.22 +#ifndef __SVBDF_H__
  432.23 +#define __SVBDF_H__
  432.24 +
  432.25 +#include FT_BDF_H
  432.26 +#include FT_INTERNAL_SERVICE_H
  432.27 +
  432.28 +
  432.29 +FT_BEGIN_HEADER
  432.30 +
  432.31 +
  432.32 +#define FT_SERVICE_ID_BDF  "bdf"
  432.33 +
  432.34 +  typedef FT_Error
  432.35 +  (*FT_BDF_GetCharsetIdFunc)( FT_Face       face,
  432.36 +                              const char*  *acharset_encoding,
  432.37 +                              const char*  *acharset_registry );
  432.38 +
  432.39 +  typedef FT_Error
  432.40 +  (*FT_BDF_GetPropertyFunc)( FT_Face           face,
  432.41 +                             const char*       prop_name,
  432.42 +                             BDF_PropertyRec  *aproperty );
  432.43 +
  432.44 +
  432.45 +  FT_DEFINE_SERVICE( BDF )
  432.46 +  {
  432.47 +    FT_BDF_GetCharsetIdFunc  get_charset_id;
  432.48 +    FT_BDF_GetPropertyFunc   get_property;
  432.49 +  };
  432.50 +
  432.51 +#ifndef FT_CONFIG_OPTION_PIC
  432.52 +
  432.53 +#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \
  432.54 +  static const FT_Service_BDFRec class_ =                                \
  432.55 +  {                                                                      \
  432.56 +    get_charset_id_, get_property_                                       \
  432.57 +  };
  432.58 +
  432.59 +#else /* FT_CONFIG_OPTION_PIC */ 
  432.60 +
  432.61 +#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \
  432.62 +  void                                                                   \
  432.63 +  FT_Init_Class_##class_( FT_Service_BDFRec*  clazz )                    \
  432.64 +  {                                                                      \
  432.65 +    clazz->get_charset_id = get_charset_id_;                             \
  432.66 +    clazz->get_property = get_property_;                                 \
  432.67 +  } 
  432.68 +
  432.69 +#endif /* FT_CONFIG_OPTION_PIC */ 
  432.70 +
  432.71 +  /* */
  432.72 +
  432.73 +
  432.74 +FT_END_HEADER
  432.75 +
  432.76 +
  432.77 +#endif /* __SVBDF_H__ */
  432.78 +
  432.79 +
  432.80 +/* END */
   433.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   433.2 +++ b/libs/ft2static/freetype/internal/services/svcid.h	Sat Feb 01 19:58:19 2014 +0200
   433.3 @@ -0,0 +1,83 @@
   433.4 +/***************************************************************************/
   433.5 +/*                                                                         */
   433.6 +/*  svcid.h                                                                */
   433.7 +/*                                                                         */
   433.8 +/*    The FreeType CID font services (specification).                      */
   433.9 +/*                                                                         */
  433.10 +/*  Copyright 2007, 2009 by Derek Clegg, Michael Toftdal.                  */
  433.11 +/*                                                                         */
  433.12 +/*  This file is part of the FreeType project, and may only be used,       */
  433.13 +/*  modified, and distributed under the terms of the FreeType project      */
  433.14 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  433.15 +/*  this file you indicate that you have read the license and              */
  433.16 +/*  understand and accept it fully.                                        */
  433.17 +/*                                                                         */
  433.18 +/***************************************************************************/
  433.19 +
  433.20 +
  433.21 +#ifndef __SVCID_H__
  433.22 +#define __SVCID_H__
  433.23 +
  433.24 +#include FT_INTERNAL_SERVICE_H
  433.25 +
  433.26 +
  433.27 +FT_BEGIN_HEADER
  433.28 +
  433.29 +
  433.30 +#define FT_SERVICE_ID_CID  "CID"
  433.31 +
  433.32 +  typedef FT_Error
  433.33 +  (*FT_CID_GetRegistryOrderingSupplementFunc)( FT_Face       face,
  433.34 +                                               const char*  *registry,
  433.35 +                                               const char*  *ordering,
  433.36 +                                               FT_Int       *supplement );
  433.37 +  typedef FT_Error
  433.38 +  (*FT_CID_GetIsInternallyCIDKeyedFunc)( FT_Face   face,
  433.39 +                                         FT_Bool  *is_cid );
  433.40 +  typedef FT_Error
  433.41 +  (*FT_CID_GetCIDFromGlyphIndexFunc)( FT_Face   face,
  433.42 +                                      FT_UInt   glyph_index,
  433.43 +                                      FT_UInt  *cid );
  433.44 +
  433.45 +  FT_DEFINE_SERVICE( CID )
  433.46 +  {
  433.47 +    FT_CID_GetRegistryOrderingSupplementFunc  get_ros;
  433.48 +    FT_CID_GetIsInternallyCIDKeyedFunc        get_is_cid;
  433.49 +    FT_CID_GetCIDFromGlyphIndexFunc           get_cid_from_glyph_index;
  433.50 +  };
  433.51 +
  433.52 +#ifndef FT_CONFIG_OPTION_PIC
  433.53 +
  433.54 +#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_,                           \
  433.55 +        get_is_cid_, get_cid_from_glyph_index_ )                             \
  433.56 +  static const FT_Service_CIDRec class_ =                                    \
  433.57 +  {                                                                          \
  433.58 +    get_ros_, get_is_cid_, get_cid_from_glyph_index_                         \
  433.59 +  };
  433.60 +
  433.61 +#else /* FT_CONFIG_OPTION_PIC */ 
  433.62 +
  433.63 +#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_,                           \
  433.64 +        get_is_cid_, get_cid_from_glyph_index_ )                             \
  433.65 +  void                                                                       \
  433.66 +  FT_Init_Class_##class_( FT_Library library,                                \
  433.67 +                          FT_Service_CIDRec* clazz)                          \
  433.68 +  {                                                                          \
  433.69 +    FT_UNUSED(library);                                                      \
  433.70 +    clazz->get_ros = get_ros_;                                               \
  433.71 +    clazz->get_is_cid = get_is_cid_;                                         \
  433.72 +    clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_;             \
  433.73 +  } 
  433.74 +
  433.75 +#endif /* FT_CONFIG_OPTION_PIC */ 
  433.76 +
  433.77 +  /* */
  433.78 +
  433.79 +
  433.80 +FT_END_HEADER
  433.81 +
  433.82 +
  433.83 +#endif /* __SVCID_H__ */
  433.84 +
  433.85 +
  433.86 +/* END */
   434.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   434.2 +++ b/libs/ft2static/freetype/internal/services/svgldict.h	Sat Feb 01 19:58:19 2014 +0200
   434.3 @@ -0,0 +1,82 @@
   434.4 +/***************************************************************************/
   434.5 +/*                                                                         */
   434.6 +/*  svgldict.h                                                             */
   434.7 +/*                                                                         */
   434.8 +/*    The FreeType glyph dictionary services (specification).              */
   434.9 +/*                                                                         */
  434.10 +/*  Copyright 2003 by                                                      */
  434.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  434.12 +/*                                                                         */
  434.13 +/*  This file is part of the FreeType project, and may only be used,       */
  434.14 +/*  modified, and distributed under the terms of the FreeType project      */
  434.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  434.16 +/*  this file you indicate that you have read the license and              */
  434.17 +/*  understand and accept it fully.                                        */
  434.18 +/*                                                                         */
  434.19 +/***************************************************************************/
  434.20 +
  434.21 +
  434.22 +#ifndef __SVGLDICT_H__
  434.23 +#define __SVGLDICT_H__
  434.24 +
  434.25 +#include FT_INTERNAL_SERVICE_H
  434.26 +
  434.27 +
  434.28 +FT_BEGIN_HEADER
  434.29 +
  434.30 +
  434.31 +  /*
  434.32 +   *  A service used to retrieve glyph names, as well as to find the
  434.33 +   *  index of a given glyph name in a font.
  434.34 +   *
  434.35 +   */
  434.36 +
  434.37 +#define FT_SERVICE_ID_GLYPH_DICT  "glyph-dict"
  434.38 +
  434.39 +
  434.40 +  typedef FT_Error
  434.41 +  (*FT_GlyphDict_GetNameFunc)( FT_Face     face,
  434.42 +                               FT_UInt     glyph_index,
  434.43 +                               FT_Pointer  buffer,
  434.44 +                               FT_UInt     buffer_max );
  434.45 +
  434.46 +  typedef FT_UInt
  434.47 +  (*FT_GlyphDict_NameIndexFunc)( FT_Face     face,
  434.48 +                                 FT_String*  glyph_name );
  434.49 +
  434.50 +
  434.51 +  FT_DEFINE_SERVICE( GlyphDict )
  434.52 +  {
  434.53 +    FT_GlyphDict_GetNameFunc    get_name;
  434.54 +    FT_GlyphDict_NameIndexFunc  name_index;  /* optional */
  434.55 +  };
  434.56 +
  434.57 +#ifndef FT_CONFIG_OPTION_PIC
  434.58 +
  434.59 +#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \
  434.60 +  static const FT_Service_GlyphDictRec class_ =                        \
  434.61 +  {                                                                    \
  434.62 +    get_name_, name_index_                                             \
  434.63 +  };
  434.64 +
  434.65 +#else /* FT_CONFIG_OPTION_PIC */ 
  434.66 +
  434.67 +#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \
  434.68 +  void                                                                 \
  434.69 +  FT_Init_Class_##class_( FT_Library library,                          \
  434.70 +                          FT_Service_GlyphDictRec* clazz)              \
  434.71 +  {                                                                    \
  434.72 +    FT_UNUSED(library);                                                \
  434.73 +    clazz->get_name = get_name_;                                       \
  434.74 +    clazz->name_index = name_index_;                                   \
  434.75 +  } 
  434.76 +
  434.77 +#endif /* FT_CONFIG_OPTION_PIC */ 
  434.78 +
  434.79 +  /* */
  434.80 +
  434.81 +
  434.82 +FT_END_HEADER
  434.83 +
  434.84 +
  434.85 +#endif /* __SVGLDICT_H__ */
   435.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   435.2 +++ b/libs/ft2static/freetype/internal/services/svgxval.h	Sat Feb 01 19:58:19 2014 +0200
   435.3 @@ -0,0 +1,72 @@
   435.4 +/***************************************************************************/
   435.5 +/*                                                                         */
   435.6 +/*  svgxval.h                                                              */
   435.7 +/*                                                                         */
   435.8 +/*    FreeType API for validating TrueTypeGX/AAT tables (specification).   */
   435.9 +/*                                                                         */
  435.10 +/*  Copyright 2004, 2005 by                                                */
  435.11 +/*  Masatake YAMATO, Red Hat K.K.,                                         */
  435.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  435.13 +/*                                                                         */
  435.14 +/*  This file is part of the FreeType project, and may only be used,       */
  435.15 +/*  modified, and distributed under the terms of the FreeType project      */
  435.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  435.17 +/*  this file you indicate that you have read the license and              */
  435.18 +/*  understand and accept it fully.                                        */
  435.19 +/*                                                                         */
  435.20 +/***************************************************************************/
  435.21 +
  435.22 +/***************************************************************************/
  435.23 +/*                                                                         */
  435.24 +/* gxvalid is derived from both gxlayout module and otvalid module.        */
  435.25 +/* Development of gxlayout is supported by the Information-technology      */
  435.26 +/* Promotion Agency(IPA), Japan.                                           */
  435.27 +/*                                                                         */
  435.28 +/***************************************************************************/
  435.29 +
  435.30 +
  435.31 +#ifndef __SVGXVAL_H__
  435.32 +#define __SVGXVAL_H__
  435.33 +
  435.34 +#include FT_GX_VALIDATE_H
  435.35 +#include FT_INTERNAL_VALIDATE_H
  435.36 +
  435.37 +FT_BEGIN_HEADER
  435.38 +
  435.39 +
  435.40 +#define FT_SERVICE_ID_GX_VALIDATE           "truetypegx-validate"
  435.41 +#define FT_SERVICE_ID_CLASSICKERN_VALIDATE  "classickern-validate"
  435.42 +
  435.43 +  typedef FT_Error
  435.44 +  (*gxv_validate_func)( FT_Face   face,
  435.45 +                        FT_UInt   gx_flags,
  435.46 +                        FT_Bytes  tables[FT_VALIDATE_GX_LENGTH],
  435.47 +                        FT_UInt   table_length );
  435.48 +
  435.49 +
  435.50 +  typedef FT_Error
  435.51 +  (*ckern_validate_func)( FT_Face   face,
  435.52 +                          FT_UInt   ckern_flags,
  435.53 +                          FT_Bytes  *ckern_table );
  435.54 +
  435.55 +
  435.56 +  FT_DEFINE_SERVICE( GXvalidate )
  435.57 +  {
  435.58 +    gxv_validate_func  validate;
  435.59 +  };
  435.60 +
  435.61 +  FT_DEFINE_SERVICE( CKERNvalidate )
  435.62 +  {
  435.63 +    ckern_validate_func  validate;
  435.64 +  };
  435.65 +
  435.66 +  /* */
  435.67 +
  435.68 +
  435.69 +FT_END_HEADER
  435.70 +
  435.71 +
  435.72 +#endif /* __SVGXVAL_H__ */
  435.73 +
  435.74 +
  435.75 +/* END */
   436.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   436.2 +++ b/libs/ft2static/freetype/internal/services/svkern.h	Sat Feb 01 19:58:19 2014 +0200
   436.3 @@ -0,0 +1,51 @@
   436.4 +/***************************************************************************/
   436.5 +/*                                                                         */
   436.6 +/*  svkern.h                                                               */
   436.7 +/*                                                                         */
   436.8 +/*    The FreeType Kerning service (specification).                        */
   436.9 +/*                                                                         */
  436.10 +/*  Copyright 2006 by                                                      */
  436.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  436.12 +/*                                                                         */
  436.13 +/*  This file is part of the FreeType project, and may only be used,       */
  436.14 +/*  modified, and distributed under the terms of the FreeType project      */
  436.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  436.16 +/*  this file you indicate that you have read the license and              */
  436.17 +/*  understand and accept it fully.                                        */
  436.18 +/*                                                                         */
  436.19 +/***************************************************************************/
  436.20 +
  436.21 +
  436.22 +#ifndef __SVKERN_H__
  436.23 +#define __SVKERN_H__
  436.24 +
  436.25 +#include FT_INTERNAL_SERVICE_H
  436.26 +#include FT_TRUETYPE_TABLES_H
  436.27 +
  436.28 +
  436.29 +FT_BEGIN_HEADER
  436.30 +
  436.31 +#define FT_SERVICE_ID_KERNING  "kerning"
  436.32 +
  436.33 +
  436.34 +  typedef FT_Error
  436.35 +  (*FT_Kerning_TrackGetFunc)( FT_Face    face,
  436.36 +                              FT_Fixed   point_size,
  436.37 +                              FT_Int     degree,
  436.38 +                              FT_Fixed*  akerning );
  436.39 +
  436.40 +  FT_DEFINE_SERVICE( Kerning )
  436.41 +  {
  436.42 +    FT_Kerning_TrackGetFunc  get_track;
  436.43 +  };
  436.44 +
  436.45 +  /* */
  436.46 +
  436.47 +
  436.48 +FT_END_HEADER
  436.49 +
  436.50 +
  436.51 +#endif /* __SVKERN_H__ */
  436.52 +
  436.53 +
  436.54 +/* END */
   437.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   437.2 +++ b/libs/ft2static/freetype/internal/services/svmm.h	Sat Feb 01 19:58:19 2014 +0200
   437.3 @@ -0,0 +1,104 @@
   437.4 +/***************************************************************************/
   437.5 +/*                                                                         */
   437.6 +/*  svmm.h                                                                 */
   437.7 +/*                                                                         */
   437.8 +/*    The FreeType Multiple Masters and GX var services (specification).   */
   437.9 +/*                                                                         */
  437.10 +/*  Copyright 2003, 2004 by                                                */
  437.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  437.12 +/*                                                                         */
  437.13 +/*  This file is part of the FreeType project, and may only be used,       */
  437.14 +/*  modified, and distributed under the terms of the FreeType project      */
  437.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  437.16 +/*  this file you indicate that you have read the license and              */
  437.17 +/*  understand and accept it fully.                                        */
  437.18 +/*                                                                         */
  437.19 +/***************************************************************************/
  437.20 +
  437.21 +
  437.22 +#ifndef __SVMM_H__
  437.23 +#define __SVMM_H__
  437.24 +
  437.25 +#include FT_INTERNAL_SERVICE_H
  437.26 +
  437.27 +
  437.28 +FT_BEGIN_HEADER
  437.29 +
  437.30 +
  437.31 +  /*
  437.32 +   *  A service used to manage multiple-masters data in a given face.
  437.33 +   *
  437.34 +   *  See the related APIs in `ftmm.h' (FT_MULTIPLE_MASTERS_H).
  437.35 +   *
  437.36 +   */
  437.37 +
  437.38 +#define FT_SERVICE_ID_MULTI_MASTERS  "multi-masters"
  437.39 +
  437.40 +
  437.41 +  typedef FT_Error
  437.42 +  (*FT_Get_MM_Func)( FT_Face           face,
  437.43 +                     FT_Multi_Master*  master );
  437.44 +
  437.45 +  typedef FT_Error
  437.46 +  (*FT_Get_MM_Var_Func)( FT_Face      face,
  437.47 +                         FT_MM_Var*  *master );
  437.48 +
  437.49 +  typedef FT_Error
  437.50 +  (*FT_Set_MM_Design_Func)( FT_Face   face,
  437.51 +                            FT_UInt   num_coords,
  437.52 +                            FT_Long*  coords );
  437.53 +
  437.54 +  typedef FT_Error
  437.55 +  (*FT_Set_Var_Design_Func)( FT_Face    face,
  437.56 +                             FT_UInt    num_coords,
  437.57 +                             FT_Fixed*  coords );
  437.58 +
  437.59 +  typedef FT_Error
  437.60 +  (*FT_Set_MM_Blend_Func)( FT_Face   face,
  437.61 +                           FT_UInt   num_coords,
  437.62 +                           FT_Long*  coords );
  437.63 +
  437.64 +
  437.65 +  FT_DEFINE_SERVICE( MultiMasters )
  437.66 +  {
  437.67 +    FT_Get_MM_Func          get_mm;
  437.68 +    FT_Set_MM_Design_Func   set_mm_design;
  437.69 +    FT_Set_MM_Blend_Func    set_mm_blend;
  437.70 +    FT_Get_MM_Var_Func      get_mm_var;
  437.71 +    FT_Set_Var_Design_Func  set_var_design;
  437.72 +  };
  437.73 +
  437.74 +#ifndef FT_CONFIG_OPTION_PIC
  437.75 +
  437.76 +#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_,   \
  437.77 +        set_mm_blend_, get_mm_var_, set_var_design_)                         \
  437.78 +  static const FT_Service_MultiMastersRec class_ =                           \
  437.79 +  {                                                                          \
  437.80 +    get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_     \
  437.81 +  };
  437.82 +
  437.83 +#else /* FT_CONFIG_OPTION_PIC */ 
  437.84 +
  437.85 +#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_,   \
  437.86 +        set_mm_blend_, get_mm_var_, set_var_design_)                         \
  437.87 +  void                                                                       \
  437.88 +  FT_Init_Class_##class_( FT_Service_MultiMastersRec*  clazz )               \
  437.89 +  {                                                                          \
  437.90 +    clazz->get_mm = get_mm_;                                                 \
  437.91 +    clazz->set_mm_design = set_mm_design_;                                   \
  437.92 +    clazz->set_mm_blend = set_mm_blend_;                                     \
  437.93 +    clazz->get_mm_var = get_mm_var_;                                         \
  437.94 +    clazz->set_var_design = set_var_design_;                                 \
  437.95 +  } 
  437.96 +
  437.97 +#endif /* FT_CONFIG_OPTION_PIC */ 
  437.98 +
  437.99 +  /* */
 437.100 +
 437.101 +
 437.102 +FT_END_HEADER
 437.103 +
 437.104 +#endif /* __SVMM_H__ */
 437.105 +
 437.106 +
 437.107 +/* END */
   438.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   438.2 +++ b/libs/ft2static/freetype/internal/services/svotval.h	Sat Feb 01 19:58:19 2014 +0200
   438.3 @@ -0,0 +1,55 @@
   438.4 +/***************************************************************************/
   438.5 +/*                                                                         */
   438.6 +/*  svotval.h                                                              */
   438.7 +/*                                                                         */
   438.8 +/*    The FreeType OpenType validation service (specification).            */
   438.9 +/*                                                                         */
  438.10 +/*  Copyright 2004, 2006 by                                                */
  438.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  438.12 +/*                                                                         */
  438.13 +/*  This file is part of the FreeType project, and may only be used,       */
  438.14 +/*  modified, and distributed under the terms of the FreeType project      */
  438.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  438.16 +/*  this file you indicate that you have read the license and              */
  438.17 +/*  understand and accept it fully.                                        */
  438.18 +/*                                                                         */
  438.19 +/***************************************************************************/
  438.20 +
  438.21 +
  438.22 +#ifndef __SVOTVAL_H__
  438.23 +#define __SVOTVAL_H__
  438.24 +
  438.25 +#include FT_OPENTYPE_VALIDATE_H
  438.26 +#include FT_INTERNAL_VALIDATE_H
  438.27 +
  438.28 +FT_BEGIN_HEADER
  438.29 +
  438.30 +
  438.31 +#define FT_SERVICE_ID_OPENTYPE_VALIDATE  "opentype-validate"
  438.32 +
  438.33 +
  438.34 +  typedef FT_Error
  438.35 +  (*otv_validate_func)( FT_Face volatile  face,
  438.36 +                        FT_UInt           ot_flags,
  438.37 +                        FT_Bytes         *base,
  438.38 +                        FT_Bytes         *gdef,
  438.39 +                        FT_Bytes         *gpos,
  438.40 +                        FT_Bytes         *gsub,
  438.41 +                        FT_Bytes         *jstf );
  438.42 +
  438.43 +
  438.44 +  FT_DEFINE_SERVICE( OTvalidate )
  438.45 +  {
  438.46 +    otv_validate_func  validate;
  438.47 +  };
  438.48 +
  438.49 +  /* */
  438.50 +
  438.51 +
  438.52 +FT_END_HEADER
  438.53 +
  438.54 +
  438.55 +#endif /* __SVOTVAL_H__ */
  438.56 +
  438.57 +
  438.58 +/* END */
   439.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   439.2 +++ b/libs/ft2static/freetype/internal/services/svpfr.h	Sat Feb 01 19:58:19 2014 +0200
   439.3 @@ -0,0 +1,66 @@
   439.4 +/***************************************************************************/
   439.5 +/*                                                                         */
   439.6 +/*  svpfr.h                                                                */
   439.7 +/*                                                                         */
   439.8 +/*    Internal PFR service functions (specification).                      */
   439.9 +/*                                                                         */
  439.10 +/*  Copyright 2003, 2006 by                                                */
  439.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  439.12 +/*                                                                         */
  439.13 +/*  This file is part of the FreeType project, and may only be used,       */
  439.14 +/*  modified, and distributed under the terms of the FreeType project      */
  439.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  439.16 +/*  this file you indicate that you have read the license and              */
  439.17 +/*  understand and accept it fully.                                        */
  439.18 +/*                                                                         */
  439.19 +/***************************************************************************/
  439.20 +
  439.21 +
  439.22 +#ifndef __SVPFR_H__
  439.23 +#define __SVPFR_H__
  439.24 +
  439.25 +#include FT_PFR_H
  439.26 +#include FT_INTERNAL_SERVICE_H
  439.27 +
  439.28 +
  439.29 +FT_BEGIN_HEADER
  439.30 +
  439.31 +
  439.32 +#define FT_SERVICE_ID_PFR_METRICS  "pfr-metrics"
  439.33 +
  439.34 +
  439.35 +  typedef FT_Error
  439.36 +  (*FT_PFR_GetMetricsFunc)( FT_Face    face,
  439.37 +                            FT_UInt   *aoutline,
  439.38 +                            FT_UInt   *ametrics,
  439.39 +                            FT_Fixed  *ax_scale,
  439.40 +                            FT_Fixed  *ay_scale );
  439.41 +
  439.42 +  typedef FT_Error
  439.43 +  (*FT_PFR_GetKerningFunc)( FT_Face     face,
  439.44 +                            FT_UInt     left,
  439.45 +                            FT_UInt     right,
  439.46 +                            FT_Vector  *avector );
  439.47 +
  439.48 +  typedef FT_Error
  439.49 +  (*FT_PFR_GetAdvanceFunc)( FT_Face   face,
  439.50 +                            FT_UInt   gindex,
  439.51 +                            FT_Pos   *aadvance );
  439.52 +
  439.53 +
  439.54 +  FT_DEFINE_SERVICE( PfrMetrics )
  439.55 +  {
  439.56 +    FT_PFR_GetMetricsFunc  get_metrics;
  439.57 +    FT_PFR_GetKerningFunc  get_kerning;
  439.58 +    FT_PFR_GetAdvanceFunc  get_advance;
  439.59 +
  439.60 +  };
  439.61 +
  439.62 + /* */
  439.63 +
  439.64 +FT_END_HEADER
  439.65 +
  439.66 +#endif /* __SVPFR_H__ */
  439.67 +
  439.68 +
  439.69 +/* END */
   440.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   440.2 +++ b/libs/ft2static/freetype/internal/services/svpostnm.h	Sat Feb 01 19:58:19 2014 +0200
   440.3 @@ -0,0 +1,79 @@
   440.4 +/***************************************************************************/
   440.5 +/*                                                                         */
   440.6 +/*  svpostnm.h                                                             */
   440.7 +/*                                                                         */
   440.8 +/*    The FreeType PostScript name services (specification).               */
   440.9 +/*                                                                         */
  440.10 +/*  Copyright 2003, 2007 by                                                */
  440.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  440.12 +/*                                                                         */
  440.13 +/*  This file is part of the FreeType project, and may only be used,       */
  440.14 +/*  modified, and distributed under the terms of the FreeType project      */
  440.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  440.16 +/*  this file you indicate that you have read the license and              */
  440.17 +/*  understand and accept it fully.                                        */
  440.18 +/*                                                                         */
  440.19 +/***************************************************************************/
  440.20 +
  440.21 +
  440.22 +#ifndef __SVPOSTNM_H__
  440.23 +#define __SVPOSTNM_H__
  440.24 +
  440.25 +#include FT_INTERNAL_SERVICE_H
  440.26 +
  440.27 +
  440.28 +FT_BEGIN_HEADER
  440.29 +
  440.30 +  /*
  440.31 +   *  A trivial service used to retrieve the PostScript name of a given
  440.32 +   *  font when available.  The `get_name' field should never be NULL.
  440.33 +   *
  440.34 +   *  The corresponding function can return NULL to indicate that the
  440.35 +   *  PostScript name is not available.
  440.36 +   *
  440.37 +   *  The name is owned by the face and will be destroyed with it.
  440.38 +   */
  440.39 +
  440.40 +#define FT_SERVICE_ID_POSTSCRIPT_FONT_NAME  "postscript-font-name"
  440.41 +
  440.42 +
  440.43 +  typedef const char*
  440.44 +  (*FT_PsName_GetFunc)( FT_Face  face );
  440.45 +
  440.46 +
  440.47 +  FT_DEFINE_SERVICE( PsFontName )
  440.48 +  {
  440.49 +    FT_PsName_GetFunc  get_ps_font_name;
  440.50 +  };
  440.51 +
  440.52 +#ifndef FT_CONFIG_OPTION_PIC
  440.53 +
  440.54 +#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \
  440.55 +  static const FT_Service_PsFontNameRec class_ =                   \
  440.56 +  {                                                                \
  440.57 +    get_ps_font_name_                                              \
  440.58 +  };
  440.59 +
  440.60 +#else /* FT_CONFIG_OPTION_PIC */ 
  440.61 +
  440.62 +#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \
  440.63 +  void                                                             \
  440.64 +  FT_Init_Class_##class_( FT_Library library,                      \
  440.65 +                          FT_Service_PsFontNameRec* clazz)         \
  440.66 +  {                                                                \
  440.67 +    FT_UNUSED(library);                                            \
  440.68 +    clazz->get_ps_font_name = get_ps_font_name_;                   \
  440.69 +  } 
  440.70 +
  440.71 +#endif /* FT_CONFIG_OPTION_PIC */ 
  440.72 +
  440.73 +  /* */
  440.74 +
  440.75 +
  440.76 +FT_END_HEADER
  440.77 +
  440.78 +
  440.79 +#endif /* __SVPOSTNM_H__ */
  440.80 +
  440.81 +
  440.82 +/* END */
   441.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   441.2 +++ b/libs/ft2static/freetype/internal/services/svpscmap.h	Sat Feb 01 19:58:19 2014 +0200
   441.3 @@ -0,0 +1,164 @@
   441.4 +/***************************************************************************/
   441.5 +/*                                                                         */
   441.6 +/*  svpscmap.h                                                             */
   441.7 +/*                                                                         */
   441.8 +/*    The FreeType PostScript charmap service (specification).             */
   441.9 +/*                                                                         */
  441.10 +/*  Copyright 2003, 2006 by                                                */
  441.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  441.12 +/*                                                                         */
  441.13 +/*  This file is part of the FreeType project, and may only be used,       */
  441.14 +/*  modified, and distributed under the terms of the FreeType project      */
  441.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  441.16 +/*  this file you indicate that you have read the license and              */
  441.17 +/*  understand and accept it fully.                                        */
  441.18 +/*                                                                         */
  441.19 +/***************************************************************************/
  441.20 +
  441.21 +
  441.22 +#ifndef __SVPSCMAP_H__
  441.23 +#define __SVPSCMAP_H__
  441.24 +
  441.25 +#include FT_INTERNAL_OBJECTS_H
  441.26 +
  441.27 +
  441.28 +FT_BEGIN_HEADER
  441.29 +
  441.30 +
  441.31 +#define FT_SERVICE_ID_POSTSCRIPT_CMAPS  "postscript-cmaps"
  441.32 +
  441.33 +
  441.34 +  /*
  441.35 +   *  Adobe glyph name to unicode value.
  441.36 +   */
  441.37 +  typedef FT_UInt32
  441.38 +  (*PS_Unicode_ValueFunc)( const char*  glyph_name );
  441.39 +
  441.40 +  /*
  441.41 +   *  Macintosh name id to glyph name.  NULL if invalid index.
  441.42 +   */
  441.43 +  typedef const char*
  441.44 +  (*PS_Macintosh_NameFunc)( FT_UInt  name_index );
  441.45 +
  441.46 +  /*
  441.47 +   *  Adobe standard string ID to glyph name.  NULL if invalid index.
  441.48 +   */
  441.49 +  typedef const char*
  441.50 +  (*PS_Adobe_Std_StringsFunc)( FT_UInt  string_index );
  441.51 +
  441.52 +
  441.53 +  /*
  441.54 +   *  Simple unicode -> glyph index charmap built from font glyph names
  441.55 +   *  table.
  441.56 +   */
  441.57 +  typedef struct  PS_UniMap_
  441.58 +  {
  441.59 +    FT_UInt32  unicode;      /* bit 31 set: is glyph variant */
  441.60 +    FT_UInt    glyph_index;
  441.61 +
  441.62 +  } PS_UniMap;
  441.63 +
  441.64 +
  441.65 +  typedef struct PS_UnicodesRec_*  PS_Unicodes;
  441.66 +
  441.67 +  typedef struct  PS_UnicodesRec_
  441.68 +  {
  441.69 +    FT_CMapRec  cmap;
  441.70 +    FT_UInt     num_maps;
  441.71 +    PS_UniMap*  maps;
  441.72 +
  441.73 +  } PS_UnicodesRec;
  441.74 +
  441.75 +
  441.76 +  /*
  441.77 +   *  A function which returns a glyph name for a given index.  Returns
  441.78 +   *  NULL if invalid index.
  441.79 +   */
  441.80 +  typedef const char*
  441.81 +  (*PS_GetGlyphNameFunc)( FT_Pointer  data,
  441.82 +                          FT_UInt     string_index );
  441.83 +
  441.84 +  /*
  441.85 +   *  A function used to release the glyph name returned by
  441.86 +   *  PS_GetGlyphNameFunc, when needed
  441.87 +   */
  441.88 +  typedef void
  441.89 +  (*PS_FreeGlyphNameFunc)( FT_Pointer  data,
  441.90 +                           const char*  name );
  441.91 +
  441.92 +  typedef FT_Error
  441.93 +  (*PS_Unicodes_InitFunc)( FT_Memory             memory,
  441.94 +                           PS_Unicodes           unicodes,
  441.95 +                           FT_UInt               num_glyphs,
  441.96 +                           PS_GetGlyphNameFunc   get_glyph_name,
  441.97 +                           PS_FreeGlyphNameFunc  free_glyph_name,
  441.98 +                           FT_Pointer            glyph_data );
  441.99 +
 441.100 +  typedef FT_UInt
 441.101 +  (*PS_Unicodes_CharIndexFunc)( PS_Unicodes  unicodes,
 441.102 +                                FT_UInt32    unicode );
 441.103 +
 441.104 +  typedef FT_UInt32
 441.105 +  (*PS_Unicodes_CharNextFunc)( PS_Unicodes  unicodes,
 441.106 +                               FT_UInt32   *unicode );
 441.107 +
 441.108 +
 441.109 +  FT_DEFINE_SERVICE( PsCMaps )
 441.110 +  {
 441.111 +    PS_Unicode_ValueFunc       unicode_value;
 441.112 +
 441.113 +    PS_Unicodes_InitFunc       unicodes_init;
 441.114 +    PS_Unicodes_CharIndexFunc  unicodes_char_index;
 441.115 +    PS_Unicodes_CharNextFunc   unicodes_char_next;
 441.116 +
 441.117 +    PS_Macintosh_NameFunc      macintosh_name;
 441.118 +    PS_Adobe_Std_StringsFunc   adobe_std_strings;
 441.119 +    const unsigned short*      adobe_std_encoding;
 441.120 +    const unsigned short*      adobe_expert_encoding;
 441.121 +  };
 441.122 +
 441.123 +
 441.124 +#ifndef FT_CONFIG_OPTION_PIC
 441.125 +
 441.126 +#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \
 441.127 +        unicodes_char_index_, unicodes_char_next_, macintosh_name_,          \
 441.128 +        adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_)     \
 441.129 +  static const FT_Service_PsCMapsRec class_ =                                \
 441.130 +  {                                                                          \
 441.131 +    unicode_value_, unicodes_init_,                                          \
 441.132 +    unicodes_char_index_, unicodes_char_next_, macintosh_name_,              \
 441.133 +    adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_          \
 441.134 +  };
 441.135 +
 441.136 +#else /* FT_CONFIG_OPTION_PIC */ 
 441.137 +
 441.138 +#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \
 441.139 +        unicodes_char_index_, unicodes_char_next_, macintosh_name_,          \
 441.140 +        adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_)     \
 441.141 +  void                                                                       \
 441.142 +  FT_Init_Class_##class_( FT_Library library,                                \
 441.143 +                          FT_Service_PsCMapsRec* clazz)                      \
 441.144 +  {                                                                          \
 441.145 +    FT_UNUSED(library);                                                      \
 441.146 +    clazz->unicode_value = unicode_value_;                                   \
 441.147 +    clazz->unicodes_init = unicodes_init_;                                   \
 441.148 +    clazz->unicodes_char_index = unicodes_char_index_;                       \
 441.149 +    clazz->unicodes_char_next = unicodes_char_next_;                         \
 441.150 +    clazz->macintosh_name = macintosh_name_;                                 \
 441.151 +    clazz->adobe_std_strings = adobe_std_strings_;                           \
 441.152 +    clazz->adobe_std_encoding = adobe_std_encoding_;                         \
 441.153 +    clazz->adobe_expert_encoding = adobe_expert_encoding_;                   \
 441.154 +  } 
 441.155 +
 441.156 +#endif /* FT_CONFIG_OPTION_PIC */ 
 441.157 +
 441.158 +  /* */
 441.159 +
 441.160 +
 441.161 +FT_END_HEADER
 441.162 +
 441.163 +
 441.164 +#endif /* __SVPSCMAP_H__ */
 441.165 +
 441.166 +
 441.167 +/* END */
   442.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   442.2 +++ b/libs/ft2static/freetype/internal/services/svpsinfo.h	Sat Feb 01 19:58:19 2014 +0200
   442.3 @@ -0,0 +1,92 @@
   442.4 +/***************************************************************************/
   442.5 +/*                                                                         */
   442.6 +/*  svpsinfo.h                                                             */
   442.7 +/*                                                                         */
   442.8 +/*    The FreeType PostScript info service (specification).                */
   442.9 +/*                                                                         */
  442.10 +/*  Copyright 2003, 2004, 2009 by                                          */
  442.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  442.12 +/*                                                                         */
  442.13 +/*  This file is part of the FreeType project, and may only be used,       */
  442.14 +/*  modified, and distributed under the terms of the FreeType project      */
  442.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  442.16 +/*  this file you indicate that you have read the license and              */
  442.17 +/*  understand and accept it fully.                                        */
  442.18 +/*                                                                         */
  442.19 +/***************************************************************************/
  442.20 +
  442.21 +
  442.22 +#ifndef __SVPSINFO_H__
  442.23 +#define __SVPSINFO_H__
  442.24 +
  442.25 +#include FT_INTERNAL_SERVICE_H
  442.26 +#include FT_INTERNAL_TYPE1_TYPES_H
  442.27 +
  442.28 +
  442.29 +FT_BEGIN_HEADER
  442.30 +
  442.31 +
  442.32 +#define FT_SERVICE_ID_POSTSCRIPT_INFO  "postscript-info"
  442.33 +
  442.34 +
  442.35 +  typedef FT_Error
  442.36 +  (*PS_GetFontInfoFunc)( FT_Face          face,
  442.37 +                         PS_FontInfoRec*  afont_info );
  442.38 +
  442.39 +  typedef FT_Error
  442.40 +  (*PS_GetFontExtraFunc)( FT_Face           face,
  442.41 +                          PS_FontExtraRec*  afont_extra );
  442.42 +
  442.43 +  typedef FT_Int
  442.44 +  (*PS_HasGlyphNamesFunc)( FT_Face   face );
  442.45 +
  442.46 +  typedef FT_Error
  442.47 +  (*PS_GetFontPrivateFunc)( FT_Face         face,
  442.48 +                            PS_PrivateRec*  afont_private );
  442.49 +
  442.50 +
  442.51 +  FT_DEFINE_SERVICE( PsInfo )
  442.52 +  {
  442.53 +    PS_GetFontInfoFunc     ps_get_font_info;
  442.54 +    PS_GetFontExtraFunc    ps_get_font_extra;
  442.55 +    PS_HasGlyphNamesFunc   ps_has_glyph_names;
  442.56 +    PS_GetFontPrivateFunc  ps_get_font_private;
  442.57 +  };
  442.58 +
  442.59 +#ifndef FT_CONFIG_OPTION_PIC
  442.60 +
  442.61 +#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_,      \
  442.62 +        ps_get_font_extra_, has_glyph_names_, get_font_private_) \
  442.63 +  static const FT_Service_PsInfoRec class_ =                     \
  442.64 +  {                                                              \
  442.65 +    get_font_info_, ps_get_font_extra_, has_glyph_names_,        \
  442.66 +    get_font_private_                                            \
  442.67 +  };
  442.68 +
  442.69 +#else /* FT_CONFIG_OPTION_PIC */ 
  442.70 +
  442.71 +#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_,      \
  442.72 +        ps_get_font_extra_, has_glyph_names_, get_font_private_) \
  442.73 +  void                                                           \
  442.74 +  FT_Init_Class_##class_( FT_Library library,                    \
  442.75 +                          FT_Service_PsInfoRec*  clazz)          \
  442.76 +  {                                                              \
  442.77 +    FT_UNUSED(library);                                          \
  442.78 +    clazz->ps_get_font_info = get_font_info_;                    \
  442.79 +    clazz->ps_get_font_extra = ps_get_font_extra_;               \
  442.80 +    clazz->ps_has_glyph_names = has_glyph_names_;                \
  442.81 +    clazz->ps_get_font_private = get_font_private_;              \
  442.82 +  } 
  442.83 +
  442.84 +#endif /* FT_CONFIG_OPTION_PIC */ 
  442.85 +
  442.86 +  /* */
  442.87 +
  442.88 +
  442.89 +FT_END_HEADER
  442.90 +
  442.91 +
  442.92 +#endif /* __SVPSINFO_H__ */
  442.93 +
  442.94 +
  442.95 +/* END */
   443.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   443.2 +++ b/libs/ft2static/freetype/internal/services/svsfnt.h	Sat Feb 01 19:58:19 2014 +0200
   443.3 @@ -0,0 +1,102 @@
   443.4 +/***************************************************************************/
   443.5 +/*                                                                         */
   443.6 +/*  svsfnt.h                                                               */
   443.7 +/*                                                                         */
   443.8 +/*    The FreeType SFNT table loading service (specification).             */
   443.9 +/*                                                                         */
  443.10 +/*  Copyright 2003, 2004 by                                                */
  443.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  443.12 +/*                                                                         */
  443.13 +/*  This file is part of the FreeType project, and may only be used,       */
  443.14 +/*  modified, and distributed under the terms of the FreeType project      */
  443.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  443.16 +/*  this file you indicate that you have read the license and              */
  443.17 +/*  understand and accept it fully.                                        */
  443.18 +/*                                                                         */
  443.19 +/***************************************************************************/
  443.20 +
  443.21 +
  443.22 +#ifndef __SVSFNT_H__
  443.23 +#define __SVSFNT_H__
  443.24 +
  443.25 +#include FT_INTERNAL_SERVICE_H
  443.26 +#include FT_TRUETYPE_TABLES_H
  443.27 +
  443.28 +
  443.29 +FT_BEGIN_HEADER
  443.30 +
  443.31 +
  443.32 +  /*
  443.33 +   *  SFNT table loading service.
  443.34 +   */
  443.35 +
  443.36 +#define FT_SERVICE_ID_SFNT_TABLE  "sfnt-table"
  443.37 +
  443.38 +
  443.39 +  /*
  443.40 +   * Used to implement FT_Load_Sfnt_Table().
  443.41 +   */
  443.42 +  typedef FT_Error
  443.43 +  (*FT_SFNT_TableLoadFunc)( FT_Face    face,
  443.44 +                            FT_ULong   tag,
  443.45 +                            FT_Long    offset,
  443.46 +                            FT_Byte*   buffer,
  443.47 +                            FT_ULong*  length );
  443.48 +
  443.49 +  /*
  443.50 +   * Used to implement FT_Get_Sfnt_Table().
  443.51 +   */
  443.52 +  typedef void*
  443.53 +  (*FT_SFNT_TableGetFunc)( FT_Face      face,
  443.54 +                           FT_Sfnt_Tag  tag );
  443.55 +
  443.56 +
  443.57 +  /*
  443.58 +   * Used to implement FT_Sfnt_Table_Info().
  443.59 +   */
  443.60 +  typedef FT_Error
  443.61 +  (*FT_SFNT_TableInfoFunc)( FT_Face    face,
  443.62 +                            FT_UInt    idx,
  443.63 +                            FT_ULong  *tag,
  443.64 +                            FT_ULong  *offset,
  443.65 +                            FT_ULong  *length );
  443.66 +
  443.67 +
  443.68 +  FT_DEFINE_SERVICE( SFNT_Table )
  443.69 +  {
  443.70 +    FT_SFNT_TableLoadFunc  load_table;
  443.71 +    FT_SFNT_TableGetFunc   get_table;
  443.72 +    FT_SFNT_TableInfoFunc  table_info;
  443.73 +  };
  443.74 +
  443.75 +#ifndef FT_CONFIG_OPTION_PIC
  443.76 +
  443.77 +#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_)  \
  443.78 +  static const FT_Service_SFNT_TableRec class_ =                     \
  443.79 +  {                                                                  \
  443.80 +    load_, get_, info_                                               \
  443.81 +  };
  443.82 +
  443.83 +#else /* FT_CONFIG_OPTION_PIC */ 
  443.84 +
  443.85 +#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \
  443.86 +  void                                                              \
  443.87 +  FT_Init_Class_##class_( FT_Service_SFNT_TableRec*  clazz )        \
  443.88 +  {                                                                 \
  443.89 +    clazz->load_table = load_;                                      \
  443.90 +    clazz->get_table = get_;                                        \
  443.91 +    clazz->table_info = info_;                                      \
  443.92 +  } 
  443.93 +
  443.94 +#endif /* FT_CONFIG_OPTION_PIC */ 
  443.95 +
  443.96 +  /* */
  443.97 +
  443.98 +
  443.99 +FT_END_HEADER
 443.100 +
 443.101 +
 443.102 +#endif /* __SVSFNT_H__ */
 443.103 +
 443.104 +
 443.105 +/* END */
   444.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   444.2 +++ b/libs/ft2static/freetype/internal/services/svttcmap.h	Sat Feb 01 19:58:19 2014 +0200
   444.3 @@ -0,0 +1,106 @@
   444.4 +/***************************************************************************/
   444.5 +/*                                                                         */
   444.6 +/*  svttcmap.h                                                             */
   444.7 +/*                                                                         */
   444.8 +/*    The FreeType TrueType/sfnt cmap extra information service.           */
   444.9 +/*                                                                         */
  444.10 +/*  Copyright 2003 by                                                      */
  444.11 +/*  Masatake YAMATO, Redhat K.K.                                           */
  444.12 +/*                                                                         */
  444.13 +/*  Copyright 2003, 2008 by                                                */
  444.14 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  444.15 +/*                                                                         */
  444.16 +/*  This file is part of the FreeType project, and may only be used,       */
  444.17 +/*  modified, and distributed under the terms of the FreeType project      */
  444.18 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  444.19 +/*  this file you indicate that you have read the license and              */
  444.20 +/*  understand and accept it fully.                                        */
  444.21 +/*                                                                         */
  444.22 +/***************************************************************************/
  444.23 +
  444.24 +/* Development of this service is support of
  444.25 +   Information-technology Promotion Agency, Japan. */
  444.26 +
  444.27 +#ifndef __SVTTCMAP_H__
  444.28 +#define __SVTTCMAP_H__
  444.29 +
  444.30 +#include FT_INTERNAL_SERVICE_H
  444.31 +#include FT_TRUETYPE_TABLES_H
  444.32 +
  444.33 +
  444.34 +FT_BEGIN_HEADER
  444.35 +
  444.36 +
  444.37 +#define FT_SERVICE_ID_TT_CMAP "tt-cmaps"
  444.38 +
  444.39 +
  444.40 +  /*************************************************************************/
  444.41 +  /*                                                                       */
  444.42 +  /* <Struct>                                                              */
  444.43 +  /*    TT_CMapInfo                                                        */
  444.44 +  /*                                                                       */
  444.45 +  /* <Description>                                                         */
  444.46 +  /*    A structure used to store TrueType/sfnt specific cmap information  */
  444.47 +  /*    which is not covered by the generic @FT_CharMap structure.  This   */
  444.48 +  /*    structure can be accessed with the @FT_Get_TT_CMap_Info function.  */
  444.49 +  /*                                                                       */
  444.50 +  /* <Fields>                                                              */
  444.51 +  /*    language ::                                                        */
  444.52 +  /*      The language ID used in Mac fonts.  Definitions of values are in */
  444.53 +  /*      freetype/ttnameid.h.                                             */
  444.54 +  /*                                                                       */
  444.55 +  /*    format ::                                                          */
  444.56 +  /*      The cmap format.  OpenType 1.5 defines the formats 0 (byte       */
  444.57 +  /*      encoding table), 2~(high-byte mapping through table), 4~(segment */
  444.58 +  /*      mapping to delta values), 6~(trimmed table mapping), 8~(mixed    */
  444.59 +  /*      16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented   */
  444.60 +  /*      coverage), and 14 (Unicode Variation Sequences).                 */
  444.61 +  /*                                                                       */
  444.62 +  typedef struct  TT_CMapInfo_
  444.63 +  {
  444.64 +    FT_ULong language;
  444.65 +    FT_Long  format;
  444.66 +
  444.67 +  } TT_CMapInfo;
  444.68 +
  444.69 +
  444.70 +  typedef FT_Error
  444.71 +  (*TT_CMap_Info_GetFunc)( FT_CharMap    charmap,
  444.72 +                           TT_CMapInfo  *cmap_info );
  444.73 +
  444.74 +
  444.75 +  FT_DEFINE_SERVICE( TTCMaps )
  444.76 +  {
  444.77 +    TT_CMap_Info_GetFunc  get_cmap_info;
  444.78 +  };
  444.79 +
  444.80 +#ifndef FT_CONFIG_OPTION_PIC
  444.81 +
  444.82 +#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_)  \
  444.83 +  static const FT_Service_TTCMapsRec class_ =                 \
  444.84 +  {                                                           \
  444.85 +    get_cmap_info_                                            \
  444.86 +  };
  444.87 +
  444.88 +#else /* FT_CONFIG_OPTION_PIC */ 
  444.89 +
  444.90 +#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \
  444.91 +  void                                                       \
  444.92 +  FT_Init_Class_##class_( FT_Library library,                \
  444.93 +                          FT_Service_TTCMapsRec*  clazz)     \
  444.94 +  {                                                          \
  444.95 +    FT_UNUSED(library);                                      \
  444.96 +    clazz->get_cmap_info = get_cmap_info_;                   \
  444.97 +  } 
  444.98 +
  444.99 +#endif /* FT_CONFIG_OPTION_PIC */ 
 444.100 +
 444.101 +  /* */
 444.102 +
 444.103 +
 444.104 +FT_END_HEADER
 444.105 +
 444.106 +#endif /* __SVTTCMAP_H__ */
 444.107 +
 444.108 +
 444.109 +/* END */
   445.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   445.2 +++ b/libs/ft2static/freetype/internal/services/svtteng.h	Sat Feb 01 19:58:19 2014 +0200
   445.3 @@ -0,0 +1,53 @@
   445.4 +/***************************************************************************/
   445.5 +/*                                                                         */
   445.6 +/*  svtteng.h                                                              */
   445.7 +/*                                                                         */
   445.8 +/*    The FreeType TrueType engine query service (specification).          */
   445.9 +/*                                                                         */
  445.10 +/*  Copyright 2006 by                                                      */
  445.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  445.12 +/*                                                                         */
  445.13 +/*  This file is part of the FreeType project, and may only be used,       */
  445.14 +/*  modified, and distributed under the terms of the FreeType project      */
  445.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  445.16 +/*  this file you indicate that you have read the license and              */
  445.17 +/*  understand and accept it fully.                                        */
  445.18 +/*                                                                         */
  445.19 +/***************************************************************************/
  445.20 +
  445.21 +
  445.22 +#ifndef __SVTTENG_H__
  445.23 +#define __SVTTENG_H__
  445.24 +
  445.25 +#include FT_INTERNAL_SERVICE_H
  445.26 +#include FT_MODULE_H
  445.27 +
  445.28 +
  445.29 +FT_BEGIN_HEADER
  445.30 +
  445.31 +
  445.32 +  /*
  445.33 +   *  SFNT table loading service.
  445.34 +   */
  445.35 +
  445.36 +#define FT_SERVICE_ID_TRUETYPE_ENGINE  "truetype-engine"
  445.37 +
  445.38 +  /*
  445.39 +   * Used to implement FT_Get_TrueType_Engine_Type
  445.40 +   */
  445.41 +
  445.42 +  FT_DEFINE_SERVICE( TrueTypeEngine )
  445.43 +  {
  445.44 +    FT_TrueTypeEngineType  engine_type;
  445.45 +  };
  445.46 +
  445.47 +  /* */
  445.48 +
  445.49 +
  445.50 +FT_END_HEADER
  445.51 +
  445.52 +
  445.53 +#endif /* __SVTTENG_H__ */
  445.54 +
  445.55 +
  445.56 +/* END */
   446.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   446.2 +++ b/libs/ft2static/freetype/internal/services/svttglyf.h	Sat Feb 01 19:58:19 2014 +0200
   446.3 @@ -0,0 +1,67 @@
   446.4 +/***************************************************************************/
   446.5 +/*                                                                         */
   446.6 +/*  svttglyf.h                                                             */
   446.7 +/*                                                                         */
   446.8 +/*    The FreeType TrueType glyph service.                                 */
   446.9 +/*                                                                         */
  446.10 +/*  Copyright 2007 by David Turner.                                        */
  446.11 +/*                                                                         */
  446.12 +/*  This file is part of the FreeType project, and may only be used,       */
  446.13 +/*  modified, and distributed under the terms of the FreeType project      */
  446.14 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  446.15 +/*  this file you indicate that you have read the license and              */
  446.16 +/*  understand and accept it fully.                                        */
  446.17 +/*                                                                         */
  446.18 +/***************************************************************************/
  446.19 +
  446.20 +#ifndef __SVTTGLYF_H__
  446.21 +#define __SVTTGLYF_H__
  446.22 +
  446.23 +#include FT_INTERNAL_SERVICE_H
  446.24 +#include FT_TRUETYPE_TABLES_H
  446.25 +
  446.26 +
  446.27 +FT_BEGIN_HEADER
  446.28 +
  446.29 +
  446.30 +#define FT_SERVICE_ID_TT_GLYF "tt-glyf"
  446.31 +
  446.32 +
  446.33 +  typedef FT_ULong
  446.34 +  (*TT_Glyf_GetLocationFunc)( FT_Face    face,
  446.35 +                              FT_UInt    gindex,
  446.36 +                              FT_ULong  *psize );
  446.37 +
  446.38 +  FT_DEFINE_SERVICE( TTGlyf )
  446.39 +  {
  446.40 +    TT_Glyf_GetLocationFunc  get_location;
  446.41 +  };
  446.42 +
  446.43 +#ifndef FT_CONFIG_OPTION_PIC
  446.44 +
  446.45 +#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ )   \
  446.46 +  static const FT_Service_TTGlyfRec class_ =                  \
  446.47 +  {                                                           \
  446.48 +    get_location_                                             \
  446.49 +  };
  446.50 +
  446.51 +#else /* FT_CONFIG_OPTION_PIC */ 
  446.52 +
  446.53 +#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ )   \
  446.54 +  void                                                        \
  446.55 +  FT_Init_Class_##class_( FT_Service_TTGlyfRec*  clazz )      \
  446.56 +  {                                                           \
  446.57 +    clazz->get_location = get_location_;                      \
  446.58 +  } 
  446.59 +
  446.60 +#endif /* FT_CONFIG_OPTION_PIC */ 
  446.61 +
  446.62 +  /* */
  446.63 +
  446.64 +
  446.65 +FT_END_HEADER
  446.66 +
  446.67 +#endif /* __SVTTGLYF_H__ */
  446.68 +
  446.69 +
  446.70 +/* END */
   447.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   447.2 +++ b/libs/ft2static/freetype/internal/services/svwinfnt.h	Sat Feb 01 19:58:19 2014 +0200
   447.3 @@ -0,0 +1,50 @@
   447.4 +/***************************************************************************/
   447.5 +/*                                                                         */
   447.6 +/*  svwinfnt.h                                                             */
   447.7 +/*                                                                         */
   447.8 +/*    The FreeType Windows FNT/FONT service (specification).               */
   447.9 +/*                                                                         */
  447.10 +/*  Copyright 2003 by                                                      */
  447.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  447.12 +/*                                                                         */
  447.13 +/*  This file is part of the FreeType project, and may only be used,       */
  447.14 +/*  modified, and distributed under the terms of the FreeType project      */
  447.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  447.16 +/*  this file you indicate that you have read the license and              */
  447.17 +/*  understand and accept it fully.                                        */
  447.18 +/*                                                                         */
  447.19 +/***************************************************************************/
  447.20 +
  447.21 +
  447.22 +#ifndef __SVWINFNT_H__
  447.23 +#define __SVWINFNT_H__
  447.24 +
  447.25 +#include FT_INTERNAL_SERVICE_H
  447.26 +#include FT_WINFONTS_H
  447.27 +
  447.28 +
  447.29 +FT_BEGIN_HEADER
  447.30 +
  447.31 +
  447.32 +#define FT_SERVICE_ID_WINFNT  "winfonts"
  447.33 +
  447.34 +  typedef FT_Error
  447.35 +  (*FT_WinFnt_GetHeaderFunc)( FT_Face               face,
  447.36 +                              FT_WinFNT_HeaderRec  *aheader );
  447.37 +
  447.38 +
  447.39 +  FT_DEFINE_SERVICE( WinFnt )
  447.40 +  {
  447.41 +    FT_WinFnt_GetHeaderFunc  get_header;
  447.42 +  };
  447.43 +
  447.44 +  /* */
  447.45 +
  447.46 +
  447.47 +FT_END_HEADER
  447.48 +
  447.49 +
  447.50 +#endif /* __SVWINFNT_H__ */
  447.51 +
  447.52 +
  447.53 +/* END */
   448.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   448.2 +++ b/libs/ft2static/freetype/internal/services/svxf86nm.h	Sat Feb 01 19:58:19 2014 +0200
   448.3 @@ -0,0 +1,55 @@
   448.4 +/***************************************************************************/
   448.5 +/*                                                                         */
   448.6 +/*  svxf86nm.h                                                             */
   448.7 +/*                                                                         */
   448.8 +/*    The FreeType XFree86 services (specification only).                  */
   448.9 +/*                                                                         */
  448.10 +/*  Copyright 2003 by                                                      */
  448.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  448.12 +/*                                                                         */
  448.13 +/*  This file is part of the FreeType project, and may only be used,       */
  448.14 +/*  modified, and distributed under the terms of the FreeType project      */
  448.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  448.16 +/*  this file you indicate that you have read the license and              */
  448.17 +/*  understand and accept it fully.                                        */
  448.18 +/*                                                                         */
  448.19 +/***************************************************************************/
  448.20 +
  448.21 +
  448.22 +#ifndef __SVXF86NM_H__
  448.23 +#define __SVXF86NM_H__
  448.24 +
  448.25 +#include FT_INTERNAL_SERVICE_H
  448.26 +
  448.27 +
  448.28 +FT_BEGIN_HEADER
  448.29 +
  448.30 +
  448.31 +  /*
  448.32 +   *  A trivial service used to return the name of a face's font driver,
  448.33 +   *  according to the XFree86 nomenclature.  Note that the service data
  448.34 +   *  is a simple constant string pointer.
  448.35 +   */
  448.36 +
  448.37 +#define FT_SERVICE_ID_XF86_NAME  "xf86-driver-name"
  448.38 +
  448.39 +#define FT_XF86_FORMAT_TRUETYPE  "TrueType"
  448.40 +#define FT_XF86_FORMAT_TYPE_1    "Type 1"
  448.41 +#define FT_XF86_FORMAT_BDF       "BDF"
  448.42 +#define FT_XF86_FORMAT_PCF       "PCF"
  448.43 +#define FT_XF86_FORMAT_TYPE_42   "Type 42"
  448.44 +#define FT_XF86_FORMAT_CID       "CID Type 1"
  448.45 +#define FT_XF86_FORMAT_CFF       "CFF"
  448.46 +#define FT_XF86_FORMAT_PFR       "PFR"
  448.47 +#define FT_XF86_FORMAT_WINFNT    "Windows FNT"
  448.48 +
  448.49 +  /* */
  448.50 +
  448.51 +
  448.52 +FT_END_HEADER
  448.53 +
  448.54 +
  448.55 +#endif /* __SVXF86NM_H__ */
  448.56 +
  448.57 +
  448.58 +/* END */
   449.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   449.2 +++ b/libs/ft2static/freetype/internal/sfnt.h	Sat Feb 01 19:58:19 2014 +0200
   449.3 @@ -0,0 +1,897 @@
   449.4 +/***************************************************************************/
   449.5 +/*                                                                         */
   449.6 +/*  sfnt.h                                                                 */
   449.7 +/*                                                                         */
   449.8 +/*    High-level `sfnt' driver interface (specification).                  */
   449.9 +/*                                                                         */
  449.10 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */
  449.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  449.12 +/*                                                                         */
  449.13 +/*  This file is part of the FreeType project, and may only be used,       */
  449.14 +/*  modified, and distributed under the terms of the FreeType project      */
  449.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  449.16 +/*  this file you indicate that you have read the license and              */
  449.17 +/*  understand and accept it fully.                                        */
  449.18 +/*                                                                         */
  449.19 +/***************************************************************************/
  449.20 +
  449.21 +
  449.22 +#ifndef __SFNT_H__
  449.23 +#define __SFNT_H__
  449.24 +
  449.25 +
  449.26 +#include <ft2build.h>
  449.27 +#include FT_INTERNAL_DRIVER_H
  449.28 +#include FT_INTERNAL_TRUETYPE_TYPES_H
  449.29 +
  449.30 +
  449.31 +FT_BEGIN_HEADER
  449.32 +
  449.33 +
  449.34 +  /*************************************************************************/
  449.35 +  /*                                                                       */
  449.36 +  /* <FuncType>                                                            */
  449.37 +  /*    TT_Init_Face_Func                                                  */
  449.38 +  /*                                                                       */
  449.39 +  /* <Description>                                                         */
  449.40 +  /*    First part of the SFNT face object initialization.  This finds     */
  449.41 +  /*    the face in a SFNT file or collection, and load its format tag in  */
  449.42 +  /*    face->format_tag.                                                  */
  449.43 +  /*                                                                       */
  449.44 +  /* <Input>                                                               */
  449.45 +  /*    stream     :: The input stream.                                    */
  449.46 +  /*                                                                       */
  449.47 +  /*    face       :: A handle to the target face object.                  */
  449.48 +  /*                                                                       */
  449.49 +  /*    face_index :: The index of the TrueType font, if we are opening a  */
  449.50 +  /*                  collection.                                          */
  449.51 +  /*                                                                       */
  449.52 +  /*    num_params :: The number of additional parameters.                 */
  449.53 +  /*                                                                       */
  449.54 +  /*    params     :: Optional additional parameters.                      */
  449.55 +  /*                                                                       */
  449.56 +  /* <Return>                                                              */
  449.57 +  /*    FreeType error code.  0 means success.                             */
  449.58 +  /*                                                                       */
  449.59 +  /* <Note>                                                                */
  449.60 +  /*    The stream cursor must be at the font file's origin.               */
  449.61 +  /*                                                                       */
  449.62 +  /*    This function recognizes fonts embedded in a `TrueType             */
  449.63 +  /*    collection'.                                                       */
  449.64 +  /*                                                                       */
  449.65 +  /*    Once the format tag has been validated by the font driver, it      */
  449.66 +  /*    should then call the TT_Load_Face_Func() callback to read the rest */
  449.67 +  /*    of the SFNT tables in the object.                                  */
  449.68 +  /*                                                                       */
  449.69 +  typedef FT_Error
  449.70 +  (*TT_Init_Face_Func)( FT_Stream      stream,
  449.71 +                        TT_Face        face,
  449.72 +                        FT_Int         face_index,
  449.73 +                        FT_Int         num_params,
  449.74 +                        FT_Parameter*  params );
  449.75 +
  449.76 +
  449.77 +  /*************************************************************************/
  449.78 +  /*                                                                       */
  449.79 +  /* <FuncType>                                                            */
  449.80 +  /*    TT_Load_Face_Func                                                  */
  449.81 +  /*                                                                       */
  449.82 +  /* <Description>                                                         */
  449.83 +  /*    Second part of the SFNT face object initialization.  This loads    */
  449.84 +  /*    the common SFNT tables (head, OS/2, maxp, metrics, etc.) in the    */
  449.85 +  /*    face object.                                                       */
  449.86 +  /*                                                                       */
  449.87 +  /* <Input>                                                               */
  449.88 +  /*    stream     :: The input stream.                                    */
  449.89 +  /*                                                                       */
  449.90 +  /*    face       :: A handle to the target face object.                  */
  449.91 +  /*                                                                       */
  449.92 +  /*    face_index :: The index of the TrueType font, if we are opening a  */
  449.93 +  /*                  collection.                                          */
  449.94 +  /*                                                                       */
  449.95 +  /*    num_params :: The number of additional parameters.                 */
  449.96 +  /*                                                                       */
  449.97 +  /*    params     :: Optional additional parameters.                      */
  449.98 +  /*                                                                       */
  449.99 +  /* <Return>                                                              */
 449.100 +  /*    FreeType error code.  0 means success.                             */
 449.101 +  /*                                                                       */
 449.102 +  /* <Note>                                                                */
 449.103 +  /*    This function must be called after TT_Init_Face_Func().            */
 449.104 +  /*                                                                       */
 449.105 +  typedef FT_Error
 449.106 +  (*TT_Load_Face_Func)( FT_Stream      stream,
 449.107 +                        TT_Face        face,
 449.108 +                        FT_Int         face_index,
 449.109 +                        FT_Int         num_params,
 449.110 +                        FT_Parameter*  params );
 449.111 +
 449.112 +
 449.113 +  /*************************************************************************/
 449.114 +  /*                                                                       */
 449.115 +  /* <FuncType>                                                            */
 449.116 +  /*    TT_Done_Face_Func                                                  */
 449.117 +  /*                                                                       */
 449.118 +  /* <Description>                                                         */
 449.119 +  /*    A callback used to delete the common SFNT data from a face.        */
 449.120 +  /*                                                                       */
 449.121 +  /* <Input>                                                               */
 449.122 +  /*    face :: A handle to the target face object.                        */
 449.123 +  /*                                                                       */
 449.124 +  /* <Note>                                                                */
 449.125 +  /*    This function does NOT destroy the face object.                    */
 449.126 +  /*                                                                       */
 449.127 +  typedef void
 449.128 +  (*TT_Done_Face_Func)( TT_Face  face );
 449.129 +
 449.130 +
 449.131 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 449.132 +
 449.133 +  /*************************************************************************/
 449.134 +  /*                                                                       */
 449.135 +  /* <FuncType>                                                            */
 449.136 +  /*    TT_Load_SFNT_HeaderRec_Func                                        */
 449.137 +  /*                                                                       */
 449.138 +  /* <Description>                                                         */
 449.139 +  /*    Loads the header of a SFNT font file.  Supports collections.       */
 449.140 +  /*                                                                       */
 449.141 +  /* <Input>                                                               */
 449.142 +  /*    face       :: A handle to the target face object.                  */
 449.143 +  /*                                                                       */
 449.144 +  /*    stream     :: The input stream.                                    */
 449.145 +  /*                                                                       */
 449.146 +  /*    face_index :: The index of the TrueType font, if we are opening a  */
 449.147 +  /*                  collection.                                          */
 449.148 +  /*                                                                       */
 449.149 +  /* <Output>                                                              */
 449.150 +  /*    sfnt       :: The SFNT header.                                     */
 449.151 +  /*                                                                       */
 449.152 +  /* <Return>                                                              */
 449.153 +  /*    FreeType error code.  0 means success.                             */
 449.154 +  /*                                                                       */
 449.155 +  /* <Note>                                                                */
 449.156 +  /*    The stream cursor must be at the font file's origin.               */
 449.157 +  /*                                                                       */
 449.158 +  /*    This function recognizes fonts embedded in a `TrueType             */
 449.159 +  /*    collection'.                                                       */
 449.160 +  /*                                                                       */
 449.161 +  /*    This function checks that the header is valid by looking at the    */
 449.162 +  /*    values of `search_range', `entry_selector', and `range_shift'.     */
 449.163 +  /*                                                                       */
 449.164 +  typedef FT_Error
 449.165 +  (*TT_Load_SFNT_HeaderRec_Func)( TT_Face      face,
 449.166 +                                  FT_Stream    stream,
 449.167 +                                  FT_Long      face_index,
 449.168 +                                  SFNT_Header  sfnt );
 449.169 +
 449.170 +
 449.171 +  /*************************************************************************/
 449.172 +  /*                                                                       */
 449.173 +  /* <FuncType>                                                            */
 449.174 +  /*    TT_Load_Directory_Func                                             */
 449.175 +  /*                                                                       */
 449.176 +  /* <Description>                                                         */
 449.177 +  /*    Loads the table directory into a face object.                      */
 449.178 +  /*                                                                       */
 449.179 +  /* <Input>                                                               */
 449.180 +  /*    face   :: A handle to the target face object.                      */
 449.181 +  /*                                                                       */
 449.182 +  /*    stream :: The input stream.                                        */
 449.183 +  /*                                                                       */
 449.184 +  /*    sfnt   :: The SFNT header.                                         */
 449.185 +  /*                                                                       */
 449.186 +  /* <Return>                                                              */
 449.187 +  /*    FreeType error code.  0 means success.                             */
 449.188 +  /*                                                                       */
 449.189 +  /* <Note>                                                                */
 449.190 +  /*    The stream cursor must be on the first byte after the 4-byte font  */
 449.191 +  /*    format tag.  This is the case just after a call to                 */
 449.192 +  /*    TT_Load_Format_Tag().                                              */
 449.193 +  /*                                                                       */
 449.194 +  typedef FT_Error
 449.195 +  (*TT_Load_Directory_Func)( TT_Face      face,
 449.196 +                             FT_Stream    stream,
 449.197 +                             SFNT_Header  sfnt );
 449.198 +
 449.199 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
 449.200 +
 449.201 +
 449.202 +  /*************************************************************************/
 449.203 +  /*                                                                       */
 449.204 +  /* <FuncType>                                                            */
 449.205 +  /*    TT_Load_Any_Func                                                   */
 449.206 +  /*                                                                       */
 449.207 +  /* <Description>                                                         */
 449.208 +  /*    Load any font table into client memory.                            */
 449.209 +  /*                                                                       */
 449.210 +  /* <Input>                                                               */
 449.211 +  /*    face   :: The face object to look for.                             */
 449.212 +  /*                                                                       */
 449.213 +  /*    tag    :: The tag of table to load.  Use the value 0 if you want   */
 449.214 +  /*              to access the whole font file, else set this parameter   */
 449.215 +  /*              to a valid TrueType table tag that you can forge with    */
 449.216 +  /*              the MAKE_TT_TAG macro.                                   */
 449.217 +  /*                                                                       */
 449.218 +  /*    offset :: The starting offset in the table (or the file if         */
 449.219 +  /*              tag == 0).                                               */
 449.220 +  /*                                                                       */
 449.221 +  /*    length :: The address of the decision variable:                    */
 449.222 +  /*                                                                       */
 449.223 +  /*                If length == NULL:                                     */
 449.224 +  /*                  Loads the whole table.  Returns an error if          */
 449.225 +  /*                  `offset' == 0!                                       */
 449.226 +  /*                                                                       */
 449.227 +  /*                If *length == 0:                                       */
 449.228 +  /*                  Exits immediately; returning the length of the given */
 449.229 +  /*                  table or of the font file, depending on the value of */
 449.230 +  /*                  `tag'.                                               */
 449.231 +  /*                                                                       */
 449.232 +  /*                If *length != 0:                                       */
 449.233 +  /*                  Loads the next `length' bytes of table or font,      */
 449.234 +  /*                  starting at offset `offset' (in table or font too).  */
 449.235 +  /*                                                                       */
 449.236 +  /* <Output>                                                              */
 449.237 +  /*    buffer :: The address of target buffer.                            */
 449.238 +  /*                                                                       */
 449.239 +  /* <Return>                                                              */
 449.240 +  /*    TrueType error code.  0 means success.                             */
 449.241 +  /*                                                                       */
 449.242 +  typedef FT_Error
 449.243 +  (*TT_Load_Any_Func)( TT_Face    face,
 449.244 +                       FT_ULong   tag,
 449.245 +                       FT_Long    offset,
 449.246 +                       FT_Byte   *buffer,
 449.247 +                       FT_ULong*  length );
 449.248 +
 449.249 +
 449.250 +  /*************************************************************************/
 449.251 +  /*                                                                       */
 449.252 +  /* <FuncType>                                                            */
 449.253 +  /*    TT_Find_SBit_Image_Func                                            */
 449.254 +  /*                                                                       */
 449.255 +  /* <Description>                                                         */
 449.256 +  /*    Check whether an embedded bitmap (an `sbit') exists for a given    */
 449.257 +  /*    glyph, at a given strike.                                          */
 449.258 +  /*                                                                       */
 449.259 +  /* <Input>                                                               */
 449.260 +  /*    face          :: The target face object.                           */
 449.261 +  /*                                                                       */
 449.262 +  /*    glyph_index   :: The glyph index.                                  */
 449.263 +  /*                                                                       */
 449.264 +  /*    strike_index  :: The current strike index.                         */
 449.265 +  /*                                                                       */
 449.266 +  /* <Output>                                                              */
 449.267 +  /*    arange        :: The SBit range containing the glyph index.        */
 449.268 +  /*                                                                       */
 449.269 +  /*    astrike       :: The SBit strike containing the glyph index.       */
 449.270 +  /*                                                                       */
 449.271 +  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
 449.272 +  /*                                                                       */
 449.273 +  /* <Return>                                                              */
 449.274 +  /*    FreeType error code.  0 means success.  Returns                    */
 449.275 +  /*    SFNT_Err_Invalid_Argument if no sbit exists for the requested      */
 449.276 +  /*    glyph.                                                             */
 449.277 +  /*                                                                       */
 449.278 +  typedef FT_Error
 449.279 +  (*TT_Find_SBit_Image_Func)( TT_Face          face,
 449.280 +                              FT_UInt          glyph_index,
 449.281 +                              FT_ULong         strike_index,
 449.282 +                              TT_SBit_Range   *arange,
 449.283 +                              TT_SBit_Strike  *astrike,
 449.284 +                              FT_ULong        *aglyph_offset );
 449.285 +
 449.286 +
 449.287 +  /*************************************************************************/
 449.288 +  /*                                                                       */
 449.289 +  /* <FuncType>                                                            */
 449.290 +  /*    TT_Load_SBit_Metrics_Func                                          */
 449.291 +  /*                                                                       */
 449.292 +  /* <Description>                                                         */
 449.293 +  /*    Get the big metrics for a given embedded bitmap.                   */
 449.294 +  /*                                                                       */
 449.295 +  /* <Input>                                                               */
 449.296 +  /*    stream      :: The input stream.                                   */
 449.297 +  /*                                                                       */
 449.298 +  /*    range       :: The SBit range containing the glyph.                */
 449.299 +  /*                                                                       */
 449.300 +  /* <Output>                                                              */
 449.301 +  /*    big_metrics :: A big SBit metrics structure for the glyph.         */
 449.302 +  /*                                                                       */
 449.303 +  /* <Return>                                                              */
 449.304 +  /*    FreeType error code.  0 means success.                             */
 449.305 +  /*                                                                       */
 449.306 +  /* <Note>                                                                */
 449.307 +  /*    The stream cursor must be positioned at the glyph's offset within  */
 449.308 +  /*    the `EBDT' table before the call.                                  */
 449.309 +  /*                                                                       */
 449.310 +  /*    If the image format uses variable metrics, the stream cursor is    */
 449.311 +  /*    positioned just after the metrics header in the `EBDT' table on    */
 449.312 +  /*    function exit.                                                     */
 449.313 +  /*                                                                       */
 449.314 +  typedef FT_Error
 449.315 +  (*TT_Load_SBit_Metrics_Func)( FT_Stream        stream,
 449.316 +                                TT_SBit_Range    range,
 449.317 +                                TT_SBit_Metrics  metrics );
 449.318 +
 449.319 +
 449.320 +  /*************************************************************************/
 449.321 +  /*                                                                       */
 449.322 +  /* <FuncType>                                                            */
 449.323 +  /*    TT_Load_SBit_Image_Func                                            */
 449.324 +  /*                                                                       */
 449.325 +  /* <Description>                                                         */
 449.326 +  /*    Load a given glyph sbit image from the font resource.  This also   */
 449.327 +  /*    returns its metrics.                                               */
 449.328 +  /*                                                                       */
 449.329 +  /* <Input>                                                               */
 449.330 +  /*    face ::                                                            */
 449.331 +  /*      The target face object.                                          */
 449.332 +  /*                                                                       */
 449.333 +  /*    strike_index ::                                                    */
 449.334 +  /*      The strike index.                                                */
 449.335 +  /*                                                                       */
 449.336 +  /*    glyph_index ::                                                     */
 449.337 +  /*      The current glyph index.                                         */
 449.338 +  /*                                                                       */
 449.339 +  /*    load_flags ::                                                      */
 449.340 +  /*      The current load flags.                                          */
 449.341 +  /*                                                                       */
 449.342 +  /*    stream ::                                                          */
 449.343 +  /*      The input stream.                                                */
 449.344 +  /*                                                                       */
 449.345 +  /* <Output>                                                              */
 449.346 +  /*    amap ::                                                            */
 449.347 +  /*      The target pixmap.                                               */
 449.348 +  /*                                                                       */
 449.349 +  /*    ametrics ::                                                        */
 449.350 +  /*      A big sbit metrics structure for the glyph image.                */
 449.351 +  /*                                                                       */
 449.352 +  /* <Return>                                                              */
 449.353 +  /*    FreeType error code.  0 means success.  Returns an error if no     */
 449.354 +  /*    glyph sbit exists for the index.                                   */
 449.355 +  /*                                                                       */
 449.356 +  /*  <Note>                                                               */
 449.357 +  /*    The `map.buffer' field is always freed before the glyph is loaded. */
 449.358 +  /*                                                                       */
 449.359 +  typedef FT_Error
 449.360 +  (*TT_Load_SBit_Image_Func)( TT_Face              face,
 449.361 +                              FT_ULong             strike_index,
 449.362 +                              FT_UInt              glyph_index,
 449.363 +                              FT_UInt              load_flags,
 449.364 +                              FT_Stream            stream,
 449.365 +                              FT_Bitmap           *amap,
 449.366 +                              TT_SBit_MetricsRec  *ametrics );
 449.367 +
 449.368 +
 449.369 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 449.370 +
 449.371 +  /*************************************************************************/
 449.372 +  /*                                                                       */
 449.373 +  /* <FuncType>                                                            */
 449.374 +  /*    TT_Set_SBit_Strike_OldFunc                                         */
 449.375 +  /*                                                                       */
 449.376 +  /* <Description>                                                         */
 449.377 +  /*    Select an sbit strike for a given size request.                    */
 449.378 +  /*                                                                       */
 449.379 +  /* <Input>                                                               */
 449.380 +  /*    face          :: The target face object.                           */
 449.381 +  /*                                                                       */
 449.382 +  /*    req           :: The size request.                                 */
 449.383 +  /*                                                                       */
 449.384 +  /* <Output>                                                              */
 449.385 +  /*    astrike_index :: The index of the sbit strike.                     */
 449.386 +  /*                                                                       */
 449.387 +  /* <Return>                                                              */
 449.388 +  /*    FreeType error code.  0 means success.  Returns an error if no     */
 449.389 +  /*    sbit strike exists for the selected ppem values.                   */
 449.390 +  /*                                                                       */
 449.391 +  typedef FT_Error
 449.392 +  (*TT_Set_SBit_Strike_OldFunc)( TT_Face    face,
 449.393 +                                 FT_UInt    x_ppem,
 449.394 +                                 FT_UInt    y_ppem,
 449.395 +                                 FT_ULong*  astrike_index );
 449.396 +
 449.397 +
 449.398 +  /*************************************************************************/
 449.399 +  /*                                                                       */
 449.400 +  /* <FuncType>                                                            */
 449.401 +  /*    TT_CharMap_Load_Func                                               */
 449.402 +  /*                                                                       */
 449.403 +  /* <Description>                                                         */
 449.404 +  /*    Loads a given TrueType character map into memory.                  */
 449.405 +  /*                                                                       */
 449.406 +  /* <Input>                                                               */
 449.407 +  /*    face   :: A handle to the parent face object.                      */
 449.408 +  /*                                                                       */
 449.409 +  /*    stream :: A handle to the current stream object.                   */
 449.410 +  /*                                                                       */
 449.411 +  /* <InOut>                                                               */
 449.412 +  /*    cmap   :: A pointer to a cmap object.                              */
 449.413 +  /*                                                                       */
 449.414 +  /* <Return>                                                              */
 449.415 +  /*    FreeType error code.  0 means success.                             */
 449.416 +  /*                                                                       */
 449.417 +  /* <Note>                                                                */
 449.418 +  /*    The function assumes that the stream is already in use (i.e.,      */
 449.419 +  /*    opened).  In case of error, all partially allocated tables are     */
 449.420 +  /*    released.                                                          */
 449.421 +  /*                                                                       */
 449.422 +  typedef FT_Error
 449.423 +  (*TT_CharMap_Load_Func)( TT_Face    face,
 449.424 +                           void*      cmap,
 449.425 +                           FT_Stream  input );
 449.426 +
 449.427 +
 449.428 +  /*************************************************************************/
 449.429 +  /*                                                                       */
 449.430 +  /* <FuncType>                                                            */
 449.431 +  /*    TT_CharMap_Free_Func                                               */
 449.432 +  /*                                                                       */
 449.433 +  /* <Description>                                                         */
 449.434 +  /*    Destroys a character mapping table.                                */
 449.435 +  /*                                                                       */
 449.436 +  /* <Input>                                                               */
 449.437 +  /*    face :: A handle to the parent face object.                        */
 449.438 +  /*                                                                       */
 449.439 +  /*    cmap :: A handle to a cmap object.                                 */
 449.440 +  /*                                                                       */
 449.441 +  /* <Return>                                                              */
 449.442 +  /*    FreeType error code.  0 means success.                             */
 449.443 +  /*                                                                       */
 449.444 +  typedef FT_Error
 449.445 +  (*TT_CharMap_Free_Func)( TT_Face       face,
 449.446 +                           void*         cmap );
 449.447 +
 449.448 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
 449.449 +
 449.450 +
 449.451 +  /*************************************************************************/
 449.452 +  /*                                                                       */
 449.453 +  /* <FuncType>                                                            */
 449.454 +  /*    TT_Set_SBit_Strike_Func                                            */
 449.455 +  /*                                                                       */
 449.456 +  /* <Description>                                                         */
 449.457 +  /*    Select an sbit strike for a given size request.                    */
 449.458 +  /*                                                                       */
 449.459 +  /* <Input>                                                               */
 449.460 +  /*    face          :: The target face object.                           */
 449.461 +  /*                                                                       */
 449.462 +  /*    req           :: The size request.                                 */
 449.463 +  /*                                                                       */
 449.464 +  /* <Output>                                                              */
 449.465 +  /*    astrike_index :: The index of the sbit strike.                     */
 449.466 +  /*                                                                       */
 449.467 +  /* <Return>                                                              */
 449.468 +  /*    FreeType error code.  0 means success.  Returns an error if no     */
 449.469 +  /*    sbit strike exists for the selected ppem values.                   */
 449.470 +  /*                                                                       */
 449.471 +  typedef FT_Error
 449.472 +  (*TT_Set_SBit_Strike_Func)( TT_Face          face,
 449.473 +                              FT_Size_Request  req,
 449.474 +                              FT_ULong*        astrike_index );
 449.475 +
 449.476 +
 449.477 +  /*************************************************************************/
 449.478 +  /*                                                                       */
 449.479 +  /* <FuncType>                                                            */
 449.480 +  /*    TT_Load_Strike_Metrics_Func                                        */
 449.481 +  /*                                                                       */
 449.482 +  /* <Description>                                                         */
 449.483 +  /*    Load the metrics of a given strike.                                */
 449.484 +  /*                                                                       */
 449.485 +  /* <Input>                                                               */
 449.486 +  /*    face          :: The target face object.                           */
 449.487 +  /*                                                                       */
 449.488 +  /*    strike_index  :: The strike index.                                 */
 449.489 +  /*                                                                       */
 449.490 +  /* <Output>                                                              */
 449.491 +  /*    metrics       :: the metrics of the strike.                        */
 449.492 +  /*                                                                       */
 449.493 +  /* <Return>                                                              */
 449.494 +  /*    FreeType error code.  0 means success.  Returns an error if no     */
 449.495 +  /*    such sbit strike exists.                                           */
 449.496 +  /*                                                                       */
 449.497 +  typedef FT_Error
 449.498 +  (*TT_Load_Strike_Metrics_Func)( TT_Face           face,
 449.499 +                                  FT_ULong          strike_index,
 449.500 +                                  FT_Size_Metrics*  metrics );
 449.501 +
 449.502 +
 449.503 +  /*************************************************************************/
 449.504 +  /*                                                                       */
 449.505 +  /* <FuncType>                                                            */
 449.506 +  /*    TT_Get_PS_Name_Func                                                */
 449.507 +  /*                                                                       */
 449.508 +  /* <Description>                                                         */
 449.509 +  /*    Get the PostScript glyph name of a glyph.                          */
 449.510 +  /*                                                                       */
 449.511 +  /* <Input>                                                               */
 449.512 +  /*    idx  :: The glyph index.                                           */
 449.513 +  /*                                                                       */
 449.514 +  /*    PSname :: The address of a string pointer.  Will be NULL in case   */
 449.515 +  /*              of error, otherwise it is a pointer to the glyph name.   */
 449.516 +  /*                                                                       */
 449.517 +  /*              You must not modify the returned string!                 */
 449.518 +  /*                                                                       */
 449.519 +  /* <Output>                                                              */
 449.520 +  /*    FreeType error code.  0 means success.                             */
 449.521 +  /*                                                                       */
 449.522 +  typedef FT_Error
 449.523 +  (*TT_Get_PS_Name_Func)( TT_Face      face,
 449.524 +                          FT_UInt      idx,
 449.525 +                          FT_String**  PSname );
 449.526 +
 449.527 +
 449.528 +  /*************************************************************************/
 449.529 +  /*                                                                       */
 449.530 +  /* <FuncType>                                                            */
 449.531 +  /*    TT_Load_Metrics_Func                                               */
 449.532 +  /*                                                                       */
 449.533 +  /* <Description>                                                         */
 449.534 +  /*    Load a metrics table, which is a table with a horizontal and a     */
 449.535 +  /*    vertical version.                                                  */
 449.536 +  /*                                                                       */
 449.537 +  /* <Input>                                                               */
 449.538 +  /*    face     :: A handle to the target face object.                    */
 449.539 +  /*                                                                       */
 449.540 +  /*    stream   :: The input stream.                                      */
 449.541 +  /*                                                                       */
 449.542 +  /*    vertical :: A boolean flag.  If set, load the vertical one.        */
 449.543 +  /*                                                                       */
 449.544 +  /* <Return>                                                              */
 449.545 +  /*    FreeType error code.  0 means success.                             */
 449.546 +  /*                                                                       */
 449.547 +  typedef FT_Error
 449.548 +  (*TT_Load_Metrics_Func)( TT_Face    face,
 449.549 +                           FT_Stream  stream,
 449.550 +                           FT_Bool    vertical );
 449.551 +
 449.552 +
 449.553 +  /*************************************************************************/
 449.554 +  /*                                                                       */
 449.555 +  /* <FuncType>                                                            */
 449.556 +  /*    TT_Get_Metrics_Func                                                */
 449.557 +  /*                                                                       */
 449.558 +  /* <Description>                                                         */
 449.559 +  /*    Load the horizontal or vertical header in a face object.           */
 449.560 +  /*                                                                       */
 449.561 +  /* <Input>                                                               */
 449.562 +  /*    face     :: A handle to the target face object.                    */
 449.563 +  /*                                                                       */
 449.564 +  /*    stream   :: The input stream.                                      */
 449.565 +  /*                                                                       */
 449.566 +  /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
 449.567 +  /*                                                                       */
 449.568 +  /* <Return>                                                              */
 449.569 +  /*    FreeType error code.  0 means success.                             */
 449.570 +  /*                                                                       */
 449.571 +  typedef FT_Error
 449.572 +  (*TT_Get_Metrics_Func)( TT_Face     face,
 449.573 +                          FT_Bool     vertical,
 449.574 +                          FT_UInt     gindex,
 449.575 +                          FT_Short*   abearing,
 449.576 +                          FT_UShort*  aadvance );
 449.577 +
 449.578 +
 449.579 +  /*************************************************************************/
 449.580 +  /*                                                                       */
 449.581 +  /* <FuncType>                                                            */
 449.582 +  /*    TT_Load_Table_Func                                                 */
 449.583 +  /*                                                                       */
 449.584 +  /* <Description>                                                         */
 449.585 +  /*    Load a given TrueType table.                                       */
 449.586 +  /*                                                                       */
 449.587 +  /* <Input>                                                               */
 449.588 +  /*    face   :: A handle to the target face object.                      */
 449.589 +  /*                                                                       */
 449.590 +  /*    stream :: The input stream.                                        */
 449.591 +  /*                                                                       */
 449.592 +  /* <Return>                                                              */
 449.593 +  /*    FreeType error code.  0 means success.                             */
 449.594 +  /*                                                                       */
 449.595 +  /* <Note>                                                                */
 449.596 +  /*    The function uses `face->goto_table' to seek the stream to the     */
 449.597 +  /*    start of the table, except while loading the font directory.       */
 449.598 +  /*                                                                       */
 449.599 +  typedef FT_Error
 449.600 +  (*TT_Load_Table_Func)( TT_Face    face,
 449.601 +                         FT_Stream  stream );
 449.602 +
 449.603 +
 449.604 +  /*************************************************************************/
 449.605 +  /*                                                                       */
 449.606 +  /* <FuncType>                                                            */
 449.607 +  /*    TT_Free_Table_Func                                                 */
 449.608 +  /*                                                                       */
 449.609 +  /* <Description>                                                         */
 449.610 +  /*    Free a given TrueType table.                                       */
 449.611 +  /*                                                                       */
 449.612 +  /* <Input>                                                               */
 449.613 +  /*    face :: A handle to the target face object.                        */
 449.614 +  /*                                                                       */
 449.615 +  typedef void
 449.616 +  (*TT_Free_Table_Func)( TT_Face  face );
 449.617 +
 449.618 +
 449.619 +  /*
 449.620 +   * @functype:
 449.621 +   *    TT_Face_GetKerningFunc
 449.622 +   *
 449.623 +   * @description:
 449.624 +   *    Return the horizontal kerning value between two glyphs.
 449.625 +   *
 449.626 +   * @input:
 449.627 +   *    face        :: A handle to the source face object.
 449.628 +   *    left_glyph  :: The left glyph index.
 449.629 +   *    right_glyph :: The right glyph index.
 449.630 +   *
 449.631 +   * @return:
 449.632 +   *    The kerning value in font units.
 449.633 +   */
 449.634 +  typedef FT_Int
 449.635 +  (*TT_Face_GetKerningFunc)( TT_Face  face,
 449.636 +                             FT_UInt  left_glyph,
 449.637 +                             FT_UInt  right_glyph );
 449.638 +
 449.639 +
 449.640 +  /*************************************************************************/
 449.641 +  /*                                                                       */
 449.642 +  /* <Struct>                                                              */
 449.643 +  /*    SFNT_Interface                                                     */
 449.644 +  /*                                                                       */
 449.645 +  /* <Description>                                                         */
 449.646 +  /*    This structure holds pointers to the functions used to load and    */
 449.647 +  /*    free the basic tables that are required in a `sfnt' font file.     */
 449.648 +  /*                                                                       */
 449.649 +  /* <Fields>                                                              */
 449.650 +  /*    Check the various xxx_Func() descriptions for details.             */
 449.651 +  /*                                                                       */
 449.652 +  typedef struct  SFNT_Interface_
 449.653 +  {
 449.654 +    TT_Loader_GotoTableFunc      goto_table;
 449.655 +
 449.656 +    TT_Init_Face_Func            init_face;
 449.657 +    TT_Load_Face_Func            load_face;
 449.658 +    TT_Done_Face_Func            done_face;
 449.659 +    FT_Module_Requester          get_interface;
 449.660 +
 449.661 +    TT_Load_Any_Func             load_any;
 449.662 +
 449.663 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 449.664 +    TT_Load_SFNT_HeaderRec_Func  load_sfnt_header;
 449.665 +    TT_Load_Directory_Func       load_directory;
 449.666 +#endif
 449.667 +
 449.668 +    /* these functions are called by `load_face' but they can also  */
 449.669 +    /* be called from external modules, if there is a need to do so */
 449.670 +    TT_Load_Table_Func           load_head;
 449.671 +    TT_Load_Metrics_Func         load_hhea;
 449.672 +    TT_Load_Table_Func           load_cmap;
 449.673 +    TT_Load_Table_Func           load_maxp;
 449.674 +    TT_Load_Table_Func           load_os2;
 449.675 +    TT_Load_Table_Func           load_post;
 449.676 +
 449.677 +    TT_Load_Table_Func           load_name;
 449.678 +    TT_Free_Table_Func           free_name;
 449.679 +
 449.680 +    /* optional tables */
 449.681 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 449.682 +    TT_Load_Table_Func           load_hdmx_stub;
 449.683 +    TT_Free_Table_Func           free_hdmx_stub;
 449.684 +#endif
 449.685 +
 449.686 +    /* this field was called `load_kerning' up to version 2.1.10 */
 449.687 +    TT_Load_Table_Func           load_kern;
 449.688 +
 449.689 +    TT_Load_Table_Func           load_gasp;
 449.690 +    TT_Load_Table_Func           load_pclt;
 449.691 +
 449.692 +    /* see `ttload.h'; this field was called `load_bitmap_header' up to */
 449.693 +    /* version 2.1.10                                                   */
 449.694 +    TT_Load_Table_Func           load_bhed;
 449.695 +
 449.696 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 449.697 +
 449.698 +    /* see `ttsbit.h' */
 449.699 +    TT_Set_SBit_Strike_OldFunc   set_sbit_strike_stub;
 449.700 +    TT_Load_Table_Func           load_sbits_stub;
 449.701 +
 449.702 +    /*
 449.703 +     *  The following two fields appeared in version 2.1.8, and were placed
 449.704 +     *  between `load_sbits' and `load_sbit_image'.  We support them as a
 449.705 +     *  special exception since they are used by Xfont library within the
 449.706 +     *  X.Org xserver, and because the probability that other rogue clients
 449.707 +     *  use the other version 2.1.7 fields below is _extremely_ low.
 449.708 +     *
 449.709 +     *  Note that this forces us to disable an interesting memory-saving
 449.710 +     *  optimization though...
 449.711 +     */
 449.712 +
 449.713 +    TT_Find_SBit_Image_Func      find_sbit_image;
 449.714 +    TT_Load_SBit_Metrics_Func    load_sbit_metrics;
 449.715 +
 449.716 +#endif
 449.717 +
 449.718 +    TT_Load_SBit_Image_Func      load_sbit_image;
 449.719 +
 449.720 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 449.721 +    TT_Free_Table_Func           free_sbits_stub;
 449.722 +#endif
 449.723 +
 449.724 +    /* see `ttpost.h' */
 449.725 +    TT_Get_PS_Name_Func          get_psname;
 449.726 +    TT_Free_Table_Func           free_psnames;
 449.727 +
 449.728 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 449.729 +    TT_CharMap_Load_Func         load_charmap_stub;
 449.730 +    TT_CharMap_Free_Func         free_charmap_stub;
 449.731 +#endif
 449.732 +
 449.733 +    /* starting here, the structure differs from version 2.1.7 */
 449.734 +
 449.735 +    /* this field was introduced in version 2.1.8, named `get_psname' */
 449.736 +    TT_Face_GetKerningFunc       get_kerning;
 449.737 +
 449.738 +    /* new elements introduced after version 2.1.10 */
 449.739 +
 449.740 +    /* load the font directory, i.e., the offset table and */
 449.741 +    /* the table directory                                 */
 449.742 +    TT_Load_Table_Func           load_font_dir;
 449.743 +    TT_Load_Metrics_Func         load_hmtx;
 449.744 +
 449.745 +    TT_Load_Table_Func           load_eblc;
 449.746 +    TT_Free_Table_Func           free_eblc;
 449.747 +
 449.748 +    TT_Set_SBit_Strike_Func      set_sbit_strike;
 449.749 +    TT_Load_Strike_Metrics_Func  load_strike_metrics;
 449.750 +
 449.751 +    TT_Get_Metrics_Func          get_metrics;
 449.752 +
 449.753 +  } SFNT_Interface;
 449.754 +
 449.755 +
 449.756 +  /* transitional */
 449.757 +  typedef SFNT_Interface*   SFNT_Service;
 449.758 +
 449.759 +#ifndef FT_CONFIG_OPTION_PIC
 449.760 +
 449.761 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 449.762 +#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a) \
 449.763 +  a, 
 449.764 +#else
 449.765 +  #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a)
 449.766 +#endif
 449.767 +#define FT_INTERNAL(a) \
 449.768 +  a, 
 449.769 +
 449.770 +#define FT_DEFINE_SFNT_INTERFACE(class_,                                     \
 449.771 +    goto_table_, init_face_, load_face_, done_face_, get_interface_,         \
 449.772 +    load_any_, load_sfnt_header_, load_directory_, load_head_,               \
 449.773 +    load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_,               \
 449.774 +    load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_,                \
 449.775 +    load_kern_, load_gasp_, load_pclt_, load_bhed_,                          \
 449.776 +    set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_,               \
 449.777 +    load_sbit_metrics_, load_sbit_image_, free_sbits_stub_,                  \
 449.778 +    get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_,      \
 449.779 +    get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_,        \
 449.780 +    set_sbit_strike_, load_strike_metrics_, get_metrics_ )                   \
 449.781 +  static const SFNT_Interface class_ =                                       \
 449.782 +  {                                                                          \
 449.783 +    FT_INTERNAL(goto_table_) \
 449.784 +    FT_INTERNAL(init_face_) \
 449.785 +    FT_INTERNAL(load_face_) \
 449.786 +    FT_INTERNAL(done_face_) \
 449.787 +    FT_INTERNAL(get_interface_) \
 449.788 +    FT_INTERNAL(load_any_) \
 449.789 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header_) \
 449.790 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory_) \
 449.791 +    FT_INTERNAL(load_head_) \
 449.792 +    FT_INTERNAL(load_hhea_) \
 449.793 +    FT_INTERNAL(load_cmap_) \
 449.794 +    FT_INTERNAL(load_maxp_) \
 449.795 +    FT_INTERNAL(load_os2_) \
 449.796 +    FT_INTERNAL(load_post_) \
 449.797 +    FT_INTERNAL(load_name_) \
 449.798 +    FT_INTERNAL(free_name_) \
 449.799 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub_) \
 449.800 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub_) \
 449.801 +    FT_INTERNAL(load_kern_) \
 449.802 +    FT_INTERNAL(load_gasp_) \
 449.803 +    FT_INTERNAL(load_pclt_) \
 449.804 +    FT_INTERNAL(load_bhed_) \
 449.805 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub_) \
 449.806 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub_) \
 449.807 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image_) \
 449.808 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics_) \
 449.809 +    FT_INTERNAL(load_sbit_image_) \
 449.810 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub_) \
 449.811 +    FT_INTERNAL(get_psname_) \
 449.812 +    FT_INTERNAL(free_psnames_) \
 449.813 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub_) \
 449.814 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub_) \
 449.815 +    FT_INTERNAL(get_kerning_) \
 449.816 +    FT_INTERNAL(load_font_dir_) \
 449.817 +    FT_INTERNAL(load_hmtx_) \
 449.818 +    FT_INTERNAL(load_eblc_) \
 449.819 +    FT_INTERNAL(free_eblc_) \
 449.820 +    FT_INTERNAL(set_sbit_strike_) \
 449.821 +    FT_INTERNAL(load_strike_metrics_) \
 449.822 +    FT_INTERNAL(get_metrics_) \
 449.823 +  };
 449.824 +
 449.825 +#else /* FT_CONFIG_OPTION_PIC */ 
 449.826 +
 449.827 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 449.828 +#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_) \
 449.829 +  clazz->a = a_;
 449.830 +#else
 449.831 +  #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_)
 449.832 +#endif
 449.833 +#define FT_INTERNAL(a, a_) \
 449.834 +  clazz->a = a_;
 449.835 +
 449.836 +#define FT_DEFINE_SFNT_INTERFACE(class_,                                     \
 449.837 +    goto_table_, init_face_, load_face_, done_face_, get_interface_,         \
 449.838 +    load_any_, load_sfnt_header_, load_directory_, load_head_,               \
 449.839 +    load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_,               \
 449.840 +    load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_,                \
 449.841 +    load_kern_, load_gasp_, load_pclt_, load_bhed_,                          \
 449.842 +    set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_,               \
 449.843 +    load_sbit_metrics_, load_sbit_image_, free_sbits_stub_,                  \
 449.844 +    get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_,      \
 449.845 +    get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_,        \
 449.846 +    set_sbit_strike_, load_strike_metrics_, get_metrics_ )                   \
 449.847 +  void                                                                       \
 449.848 +  FT_Init_Class_##class_( FT_Library library, SFNT_Interface*  clazz )       \
 449.849 +  {                                                                          \
 449.850 +    FT_UNUSED(library);                                                      \
 449.851 +    FT_INTERNAL(goto_table,goto_table_) \
 449.852 +    FT_INTERNAL(init_face,init_face_) \
 449.853 +    FT_INTERNAL(load_face,load_face_) \
 449.854 +    FT_INTERNAL(done_face,done_face_) \
 449.855 +    FT_INTERNAL(get_interface,get_interface_) \
 449.856 +    FT_INTERNAL(load_any,load_any_) \
 449.857 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header,load_sfnt_header_) \
 449.858 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory,load_directory_) \
 449.859 +    FT_INTERNAL(load_head,load_head_) \
 449.860 +    FT_INTERNAL(load_hhea,load_hhea_) \
 449.861 +    FT_INTERNAL(load_cmap,load_cmap_) \
 449.862 +    FT_INTERNAL(load_maxp,load_maxp_) \
 449.863 +    FT_INTERNAL(load_os2,load_os2_) \
 449.864 +    FT_INTERNAL(load_post,load_post_) \
 449.865 +    FT_INTERNAL(load_name,load_name_) \
 449.866 +    FT_INTERNAL(free_name,free_name_) \
 449.867 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub,load_hdmx_stub_) \
 449.868 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub,free_hdmx_stub_) \
 449.869 +    FT_INTERNAL(load_kern,load_kern_) \
 449.870 +    FT_INTERNAL(load_gasp,load_gasp_) \
 449.871 +    FT_INTERNAL(load_pclt,load_pclt_) \
 449.872 +    FT_INTERNAL(load_bhed,load_bhed_) \
 449.873 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub,set_sbit_strike_stub_) \
 449.874 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub,load_sbits_stub_) \
 449.875 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image,find_sbit_image_) \
 449.876 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics,load_sbit_metrics_) \
 449.877 +    FT_INTERNAL(load_sbit_image,load_sbit_image_) \
 449.878 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub,free_sbits_stub_) \
 449.879 +    FT_INTERNAL(get_psname,get_psname_) \
 449.880 +    FT_INTERNAL(free_psnames,free_psnames_) \
 449.881 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub,load_charmap_stub_) \
 449.882 +    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub,free_charmap_stub_) \
 449.883 +    FT_INTERNAL(get_kerning,get_kerning_) \
 449.884 +    FT_INTERNAL(load_font_dir,load_font_dir_) \
 449.885 +    FT_INTERNAL(load_hmtx,load_hmtx_) \
 449.886 +    FT_INTERNAL(load_eblc,load_eblc_) \
 449.887 +    FT_INTERNAL(free_eblc,free_eblc_) \
 449.888 +    FT_INTERNAL(set_sbit_strike,set_sbit_strike_) \
 449.889 +    FT_INTERNAL(load_strike_metrics,load_strike_metrics_) \
 449.890 +    FT_INTERNAL(get_metrics,get_metrics_) \
 449.891 +  } 
 449.892 +
 449.893 +#endif /* FT_CONFIG_OPTION_PIC */ 
 449.894 +
 449.895 +FT_END_HEADER
 449.896 +
 449.897 +#endif /* __SFNT_H__ */
 449.898 +
 449.899 +
 449.900 +/* END */
   450.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   450.2 +++ b/libs/ft2static/freetype/internal/t1types.h	Sat Feb 01 19:58:19 2014 +0200
   450.3 @@ -0,0 +1,270 @@
   450.4 +/***************************************************************************/
   450.5 +/*                                                                         */
   450.6 +/*  t1types.h                                                              */
   450.7 +/*                                                                         */
   450.8 +/*    Basic Type1/Type2 type definitions and interface (specification      */
   450.9 +/*    only).                                                               */
  450.10 +/*                                                                         */
  450.11 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */
  450.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  450.13 +/*                                                                         */
  450.14 +/*  This file is part of the FreeType project, and may only be used,       */
  450.15 +/*  modified, and distributed under the terms of the FreeType project      */
  450.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  450.17 +/*  this file you indicate that you have read the license and              */
  450.18 +/*  understand and accept it fully.                                        */
  450.19 +/*                                                                         */
  450.20 +/***************************************************************************/
  450.21 +
  450.22 +
  450.23 +#ifndef __T1TYPES_H__
  450.24 +#define __T1TYPES_H__
  450.25 +
  450.26 +
  450.27 +#include <ft2build.h>
  450.28 +#include FT_TYPE1_TABLES_H
  450.29 +#include FT_INTERNAL_POSTSCRIPT_HINTS_H
  450.30 +#include FT_INTERNAL_SERVICE_H
  450.31 +#include FT_SERVICE_POSTSCRIPT_CMAPS_H
  450.32 +
  450.33 +
  450.34 +FT_BEGIN_HEADER
  450.35 +
  450.36 +
  450.37 +  /*************************************************************************/
  450.38 +  /*************************************************************************/
  450.39 +  /*************************************************************************/
  450.40 +  /***                                                                   ***/
  450.41 +  /***                                                                   ***/
  450.42 +  /***              REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS              ***/
  450.43 +  /***                                                                   ***/
  450.44 +  /***                                                                   ***/
  450.45 +  /*************************************************************************/
  450.46 +  /*************************************************************************/
  450.47 +  /*************************************************************************/
  450.48 +
  450.49 +
  450.50 +  /*************************************************************************/
  450.51 +  /*                                                                       */
  450.52 +  /* <Struct>                                                              */
  450.53 +  /*    T1_EncodingRec                                                     */
  450.54 +  /*                                                                       */
  450.55 +  /* <Description>                                                         */
  450.56 +  /*    A structure modeling a custom encoding.                            */
  450.57 +  /*                                                                       */
  450.58 +  /* <Fields>                                                              */
  450.59 +  /*    num_chars  :: The number of character codes in the encoding.       */
  450.60 +  /*                  Usually 256.                                         */
  450.61 +  /*                                                                       */
  450.62 +  /*    code_first :: The lowest valid character code in the encoding.     */
  450.63 +  /*                                                                       */
  450.64 +  /*    code_last  :: The highest valid character code in the encoding     */
  450.65 +  /*                  + 1. When equal to code_first there are no valid     */
  450.66 +  /*                  character codes.                                     */
  450.67 +  /*                                                                       */
  450.68 +  /*    char_index :: An array of corresponding glyph indices.             */
  450.69 +  /*                                                                       */
  450.70 +  /*    char_name  :: An array of corresponding glyph names.               */
  450.71 +  /*                                                                       */
  450.72 +  typedef struct  T1_EncodingRecRec_
  450.73 +  {
  450.74 +    FT_Int       num_chars;
  450.75 +    FT_Int       code_first;
  450.76 +    FT_Int       code_last;
  450.77 +
  450.78 +    FT_UShort*   char_index;
  450.79 +    FT_String**  char_name;
  450.80 +
  450.81 +  } T1_EncodingRec, *T1_Encoding;
  450.82 +
  450.83 +
  450.84 +  typedef enum  T1_EncodingType_
  450.85 +  {
  450.86 +    T1_ENCODING_TYPE_NONE = 0,
  450.87 +    T1_ENCODING_TYPE_ARRAY,
  450.88 +    T1_ENCODING_TYPE_STANDARD,
  450.89 +    T1_ENCODING_TYPE_ISOLATIN1,
  450.90 +    T1_ENCODING_TYPE_EXPERT
  450.91 +
  450.92 +  } T1_EncodingType;
  450.93 +
  450.94 +
  450.95 +  /* used to hold extra data of PS_FontInfoRec that
  450.96 +   * cannot be stored in the publicly defined structure.
  450.97 +   *
  450.98 +   * Note these can't be blended with multiple-masters.
  450.99 +   */
 450.100 +  typedef struct  PS_FontExtraRec_
 450.101 +  {
 450.102 +    FT_UShort  fs_type;
 450.103 +
 450.104 +  } PS_FontExtraRec;
 450.105 +
 450.106 +
 450.107 +  typedef struct  T1_FontRec_
 450.108 +  {
 450.109 +    PS_FontInfoRec   font_info;         /* font info dictionary   */
 450.110 +    PS_FontExtraRec  font_extra;        /* font info extra fields */
 450.111 +    PS_PrivateRec    private_dict;      /* private dictionary     */
 450.112 +    FT_String*       font_name;         /* top-level dictionary   */
 450.113 +
 450.114 +    T1_EncodingType  encoding_type;
 450.115 +    T1_EncodingRec   encoding;
 450.116 +
 450.117 +    FT_Byte*         subrs_block;
 450.118 +    FT_Byte*         charstrings_block;
 450.119 +    FT_Byte*         glyph_names_block;
 450.120 +
 450.121 +    FT_Int           num_subrs;
 450.122 +    FT_Byte**        subrs;
 450.123 +    FT_PtrDist*      subrs_len;
 450.124 +
 450.125 +    FT_Int           num_glyphs;
 450.126 +    FT_String**      glyph_names;       /* array of glyph names       */
 450.127 +    FT_Byte**        charstrings;       /* array of glyph charstrings */
 450.128 +    FT_PtrDist*      charstrings_len;
 450.129 +
 450.130 +    FT_Byte          paint_type;
 450.131 +    FT_Byte          font_type;
 450.132 +    FT_Matrix        font_matrix;
 450.133 +    FT_Vector        font_offset;
 450.134 +    FT_BBox          font_bbox;
 450.135 +    FT_Long          font_id;
 450.136 +
 450.137 +    FT_Fixed         stroke_width;
 450.138 +
 450.139 +  } T1_FontRec, *T1_Font;
 450.140 +
 450.141 +
 450.142 +  typedef struct  CID_SubrsRec_
 450.143 +  {
 450.144 +    FT_UInt    num_subrs;
 450.145 +    FT_Byte**  code;
 450.146 +
 450.147 +  } CID_SubrsRec, *CID_Subrs;
 450.148 +
 450.149 +
 450.150 +  /*************************************************************************/
 450.151 +  /*************************************************************************/
 450.152 +  /*************************************************************************/
 450.153 +  /***                                                                   ***/
 450.154 +  /***                                                                   ***/
 450.155 +  /***                AFM FONT INFORMATION STRUCTURES                    ***/
 450.156 +  /***                                                                   ***/
 450.157 +  /***                                                                   ***/
 450.158 +  /*************************************************************************/
 450.159 +  /*************************************************************************/
 450.160 +  /*************************************************************************/
 450.161 +
 450.162 +  typedef struct  AFM_TrackKernRec_
 450.163 +  {
 450.164 +    FT_Int    degree;
 450.165 +    FT_Fixed  min_ptsize;
 450.166 +    FT_Fixed  min_kern;
 450.167 +    FT_Fixed  max_ptsize;
 450.168 +    FT_Fixed  max_kern;
 450.169 +
 450.170 +  } AFM_TrackKernRec, *AFM_TrackKern;
 450.171 +
 450.172 +  typedef struct  AFM_KernPairRec_
 450.173 +  {
 450.174 +    FT_Int  index1;
 450.175 +    FT_Int  index2;
 450.176 +    FT_Int  x;
 450.177 +    FT_Int  y;
 450.178 +
 450.179 +  } AFM_KernPairRec, *AFM_KernPair;
 450.180 +
 450.181 +  typedef struct  AFM_FontInfoRec_
 450.182 +  {
 450.183 +    FT_Bool        IsCIDFont;
 450.184 +    FT_BBox        FontBBox;
 450.185 +    FT_Fixed       Ascender;
 450.186 +    FT_Fixed       Descender;
 450.187 +    AFM_TrackKern  TrackKerns;   /* free if non-NULL */
 450.188 +    FT_Int         NumTrackKern;
 450.189 +    AFM_KernPair   KernPairs;    /* free if non-NULL */
 450.190 +    FT_Int         NumKernPair;
 450.191 +
 450.192 +  } AFM_FontInfoRec, *AFM_FontInfo;
 450.193 +
 450.194 +
 450.195 +  /*************************************************************************/
 450.196 +  /*************************************************************************/
 450.197 +  /*************************************************************************/
 450.198 +  /***                                                                   ***/
 450.199 +  /***                                                                   ***/
 450.200 +  /***                ORIGINAL T1_FACE CLASS DEFINITION                  ***/
 450.201 +  /***                                                                   ***/
 450.202 +  /***                                                                   ***/
 450.203 +  /*************************************************************************/
 450.204 +  /*************************************************************************/
 450.205 +  /*************************************************************************/
 450.206 +
 450.207 +
 450.208 +  typedef struct T1_FaceRec_*   T1_Face;
 450.209 +  typedef struct CID_FaceRec_*  CID_Face;
 450.210 +
 450.211 +
 450.212 +  typedef struct  T1_FaceRec_
 450.213 +  {
 450.214 +    FT_FaceRec      root;
 450.215 +    T1_FontRec      type1;
 450.216 +    const void*     psnames;
 450.217 +    const void*     psaux;
 450.218 +    const void*     afm_data;
 450.219 +    FT_CharMapRec   charmaprecs[2];
 450.220 +    FT_CharMap      charmaps[2];
 450.221 +
 450.222 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 450.223 +    PS_Unicodes     unicode_map;
 450.224 +#endif
 450.225 +
 450.226 +    /* support for Multiple Masters fonts */
 450.227 +    PS_Blend        blend;
 450.228 +
 450.229 +    /* undocumented, optional: indices of subroutines that express      */
 450.230 +    /* the NormalizeDesignVector and the ConvertDesignVector procedure, */
 450.231 +    /* respectively, as Type 2 charstrings; -1 if keywords not present  */
 450.232 +    FT_Int           ndv_idx;
 450.233 +    FT_Int           cdv_idx;
 450.234 +
 450.235 +    /* undocumented, optional: has the same meaning as len_buildchar */
 450.236 +    /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25    */
 450.237 +    FT_UInt          len_buildchar;
 450.238 +    FT_Long*         buildchar;
 450.239 +
 450.240 +    /* since version 2.1 - interface to PostScript hinter */
 450.241 +    const void*     pshinter;
 450.242 +
 450.243 +  } T1_FaceRec;
 450.244 +
 450.245 +
 450.246 +  typedef struct  CID_FaceRec_
 450.247 +  {
 450.248 +    FT_FaceRec       root;
 450.249 +    void*            psnames;
 450.250 +    void*            psaux;
 450.251 +    CID_FaceInfoRec  cid;
 450.252 +    PS_FontExtraRec  font_extra;
 450.253 +#if 0
 450.254 +    void*            afm_data;
 450.255 +#endif
 450.256 +    CID_Subrs        subrs;
 450.257 +
 450.258 +    /* since version 2.1 - interface to PostScript hinter */
 450.259 +    void*            pshinter;
 450.260 +
 450.261 +    /* since version 2.1.8, but was originally positioned after `afm_data' */
 450.262 +    FT_Byte*         binary_data; /* used if hex data has been converted */
 450.263 +    FT_Stream        cid_stream;
 450.264 +
 450.265 +  } CID_FaceRec;
 450.266 +
 450.267 +
 450.268 +FT_END_HEADER
 450.269 +
 450.270 +#endif /* __T1TYPES_H__ */
 450.271 +
 450.272 +
 450.273 +/* END */
   451.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   451.2 +++ b/libs/ft2static/freetype/internal/tttypes.h	Sat Feb 01 19:58:19 2014 +0200
   451.3 @@ -0,0 +1,1543 @@
   451.4 +/***************************************************************************/
   451.5 +/*                                                                         */
   451.6 +/*  tttypes.h                                                              */
   451.7 +/*                                                                         */
   451.8 +/*    Basic SFNT/TrueType type definitions and interface (specification    */
   451.9 +/*    only).                                                               */
  451.10 +/*                                                                         */
  451.11 +/*  Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by             */
  451.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  451.13 +/*                                                                         */
  451.14 +/*  This file is part of the FreeType project, and may only be used,       */
  451.15 +/*  modified, and distributed under the terms of the FreeType project      */
  451.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  451.17 +/*  this file you indicate that you have read the license and              */
  451.18 +/*  understand and accept it fully.                                        */
  451.19 +/*                                                                         */
  451.20 +/***************************************************************************/
  451.21 +
  451.22 +
  451.23 +#ifndef __TTTYPES_H__
  451.24 +#define __TTTYPES_H__
  451.25 +
  451.26 +
  451.27 +#include <ft2build.h>
  451.28 +#include FT_TRUETYPE_TABLES_H
  451.29 +#include FT_INTERNAL_OBJECTS_H
  451.30 +
  451.31 +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  451.32 +#include FT_MULTIPLE_MASTERS_H
  451.33 +#endif
  451.34 +
  451.35 +
  451.36 +FT_BEGIN_HEADER
  451.37 +
  451.38 +
  451.39 +  /*************************************************************************/
  451.40 +  /*************************************************************************/
  451.41 +  /*************************************************************************/
  451.42 +  /***                                                                   ***/
  451.43 +  /***                                                                   ***/
  451.44 +  /***             REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS         ***/
  451.45 +  /***                                                                   ***/
  451.46 +  /***                                                                   ***/
  451.47 +  /*************************************************************************/
  451.48 +  /*************************************************************************/
  451.49 +  /*************************************************************************/
  451.50 +
  451.51 +
  451.52 +  /*************************************************************************/
  451.53 +  /*                                                                       */
  451.54 +  /* <Struct>                                                              */
  451.55 +  /*    TTC_HeaderRec                                                      */
  451.56 +  /*                                                                       */
  451.57 +  /* <Description>                                                         */
  451.58 +  /*    TrueType collection header.  This table contains the offsets of    */
  451.59 +  /*    the font headers of each distinct TrueType face in the file.       */
  451.60 +  /*                                                                       */
  451.61 +  /* <Fields>                                                              */
  451.62 +  /*    tag     :: Must be `ttc ' to indicate a TrueType collection.       */
  451.63 +  /*                                                                       */
  451.64 +  /*    version :: The version number.                                     */
  451.65 +  /*                                                                       */
  451.66 +  /*    count   :: The number of faces in the collection.  The             */
  451.67 +  /*               specification says this should be an unsigned long, but */
  451.68 +  /*               we use a signed long since we need the value -1 for     */
  451.69 +  /*               specific purposes.                                      */
  451.70 +  /*                                                                       */
  451.71 +  /*    offsets :: The offsets of the font headers, one per face.          */
  451.72 +  /*                                                                       */
  451.73 +  typedef struct  TTC_HeaderRec_
  451.74 +  {
  451.75 +    FT_ULong   tag;
  451.76 +    FT_Fixed   version;
  451.77 +    FT_Long    count;
  451.78 +    FT_ULong*  offsets;
  451.79 +
  451.80 +  } TTC_HeaderRec;
  451.81 +
  451.82 +
  451.83 +  /*************************************************************************/
  451.84 +  /*                                                                       */
  451.85 +  /* <Struct>                                                              */
  451.86 +  /*    SFNT_HeaderRec                                                     */
  451.87 +  /*                                                                       */
  451.88 +  /* <Description>                                                         */
  451.89 +  /*    SFNT file format header.                                           */
  451.90 +  /*                                                                       */
  451.91 +  /* <Fields>                                                              */
  451.92 +  /*    format_tag     :: The font format tag.                             */
  451.93 +  /*                                                                       */
  451.94 +  /*    num_tables     :: The number of tables in file.                    */
  451.95 +  /*                                                                       */
  451.96 +  /*    search_range   :: Must be `16 * (max power of 2 <= num_tables)'.   */
  451.97 +  /*                                                                       */
  451.98 +  /*    entry_selector :: Must be log2 of `search_range / 16'.             */
  451.99 +  /*                                                                       */
 451.100 +  /*    range_shift    :: Must be `num_tables * 16 - search_range'.        */
 451.101 +  /*                                                                       */
 451.102 +  typedef struct  SFNT_HeaderRec_
 451.103 +  {
 451.104 +    FT_ULong   format_tag;
 451.105 +    FT_UShort  num_tables;
 451.106 +    FT_UShort  search_range;
 451.107 +    FT_UShort  entry_selector;
 451.108 +    FT_UShort  range_shift;
 451.109 +
 451.110 +    FT_ULong   offset;  /* not in file */
 451.111 +
 451.112 +  } SFNT_HeaderRec, *SFNT_Header;
 451.113 +
 451.114 +
 451.115 +  /*************************************************************************/
 451.116 +  /*                                                                       */
 451.117 +  /* <Struct>                                                              */
 451.118 +  /*    TT_TableRec                                                        */
 451.119 +  /*                                                                       */
 451.120 +  /* <Description>                                                         */
 451.121 +  /*    This structure describes a given table of a TrueType font.         */
 451.122 +  /*                                                                       */
 451.123 +  /* <Fields>                                                              */
 451.124 +  /*    Tag      :: A four-bytes tag describing the table.                 */
 451.125 +  /*                                                                       */
 451.126 +  /*    CheckSum :: The table checksum.  This value can be ignored.        */
 451.127 +  /*                                                                       */
 451.128 +  /*    Offset   :: The offset of the table from the start of the TrueType */
 451.129 +  /*                font in its resource.                                  */
 451.130 +  /*                                                                       */
 451.131 +  /*    Length   :: The table length (in bytes).                           */
 451.132 +  /*                                                                       */
 451.133 +  typedef struct  TT_TableRec_
 451.134 +  {
 451.135 +    FT_ULong  Tag;        /*        table type */
 451.136 +    FT_ULong  CheckSum;   /*    table checksum */
 451.137 +    FT_ULong  Offset;     /* table file offset */
 451.138 +    FT_ULong  Length;     /*      table length */
 451.139 +
 451.140 +  } TT_TableRec, *TT_Table;
 451.141 +
 451.142 +
 451.143 +  /*************************************************************************/
 451.144 +  /*                                                                       */
 451.145 +  /* <Struct>                                                              */
 451.146 +  /*    TT_LongMetricsRec                                                  */
 451.147 +  /*                                                                       */
 451.148 +  /* <Description>                                                         */
 451.149 +  /*    A structure modeling the long metrics of the `hmtx' and `vmtx'     */
 451.150 +  /*    TrueType tables.  The values are expressed in font units.          */
 451.151 +  /*                                                                       */
 451.152 +  /* <Fields>                                                              */
 451.153 +  /*    advance :: The advance width or height for the glyph.              */
 451.154 +  /*                                                                       */
 451.155 +  /*    bearing :: The left-side or top-side bearing for the glyph.        */
 451.156 +  /*                                                                       */
 451.157 +  typedef struct  TT_LongMetricsRec_
 451.158 +  {
 451.159 +    FT_UShort  advance;
 451.160 +    FT_Short   bearing;
 451.161 +
 451.162 +  } TT_LongMetricsRec, *TT_LongMetrics;
 451.163 +
 451.164 +
 451.165 +  /*************************************************************************/
 451.166 +  /*                                                                       */
 451.167 +  /* <Type>                                                                */
 451.168 +  /*    TT_ShortMetrics                                                    */
 451.169 +  /*                                                                       */
 451.170 +  /* <Description>                                                         */
 451.171 +  /*    A simple type to model the short metrics of the `hmtx' and `vmtx'  */
 451.172 +  /*    tables.                                                            */
 451.173 +  /*                                                                       */
 451.174 +  typedef FT_Short  TT_ShortMetrics;
 451.175 +
 451.176 +
 451.177 +  /*************************************************************************/
 451.178 +  /*                                                                       */
 451.179 +  /* <Struct>                                                              */
 451.180 +  /*    TT_NameEntryRec                                                    */
 451.181 +  /*                                                                       */
 451.182 +  /* <Description>                                                         */
 451.183 +  /*    A structure modeling TrueType name records.  Name records are used */
 451.184 +  /*    to store important strings like family name, style name,           */
 451.185 +  /*    copyright, etc. in _localized_ versions (i.e., language, encoding, */
 451.186 +  /*    etc).                                                              */
 451.187 +  /*                                                                       */
 451.188 +  /* <Fields>                                                              */
 451.189 +  /*    platformID   :: The ID of the name's encoding platform.            */
 451.190 +  /*                                                                       */
 451.191 +  /*    encodingID   :: The platform-specific ID for the name's encoding.  */
 451.192 +  /*                                                                       */
 451.193 +  /*    languageID   :: The platform-specific ID for the name's language.  */
 451.194 +  /*                                                                       */
 451.195 +  /*    nameID       :: The ID specifying what kind of name this is.       */
 451.196 +  /*                                                                       */
 451.197 +  /*    stringLength :: The length of the string in bytes.                 */
 451.198 +  /*                                                                       */
 451.199 +  /*    stringOffset :: The offset to the string in the `name' table.      */
 451.200 +  /*                                                                       */
 451.201 +  /*    string       :: A pointer to the string's bytes.  Note that these  */
 451.202 +  /*                    are usually UTF-16 encoded characters.             */
 451.203 +  /*                                                                       */
 451.204 +  typedef struct  TT_NameEntryRec_
 451.205 +  {
 451.206 +    FT_UShort  platformID;
 451.207 +    FT_UShort  encodingID;
 451.208 +    FT_UShort  languageID;
 451.209 +    FT_UShort  nameID;
 451.210 +    FT_UShort  stringLength;
 451.211 +    FT_ULong   stringOffset;
 451.212 +
 451.213 +    /* this last field is not defined in the spec */
 451.214 +    /* but used by the FreeType engine            */
 451.215 +
 451.216 +    FT_Byte*   string;
 451.217 +
 451.218 +  } TT_NameEntryRec, *TT_NameEntry;
 451.219 +
 451.220 +
 451.221 +  /*************************************************************************/
 451.222 +  /*                                                                       */
 451.223 +  /* <Struct>                                                              */
 451.224 +  /*    TT_NameTableRec                                                    */
 451.225 +  /*                                                                       */
 451.226 +  /* <Description>                                                         */
 451.227 +  /*    A structure modeling the TrueType name table.                      */
 451.228 +  /*                                                                       */
 451.229 +  /* <Fields>                                                              */
 451.230 +  /*    format         :: The format of the name table.                    */
 451.231 +  /*                                                                       */
 451.232 +  /*    numNameRecords :: The number of names in table.                    */
 451.233 +  /*                                                                       */
 451.234 +  /*    storageOffset  :: The offset of the name table in the `name'       */
 451.235 +  /*                      TrueType table.                                  */
 451.236 +  /*                                                                       */
 451.237 +  /*    names          :: An array of name records.                        */
 451.238 +  /*                                                                       */
 451.239 +  /*    stream         :: the file's input stream.                         */
 451.240 +  /*                                                                       */
 451.241 +  typedef struct  TT_NameTableRec_
 451.242 +  {
 451.243 +    FT_UShort         format;
 451.244 +    FT_UInt           numNameRecords;
 451.245 +    FT_UInt           storageOffset;
 451.246 +    TT_NameEntryRec*  names;
 451.247 +    FT_Stream         stream;
 451.248 +
 451.249 +  } TT_NameTableRec, *TT_NameTable;
 451.250 +
 451.251 +
 451.252 +  /*************************************************************************/
 451.253 +  /*************************************************************************/
 451.254 +  /*************************************************************************/
 451.255 +  /***                                                                   ***/
 451.256 +  /***                                                                   ***/
 451.257 +  /***             OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS         ***/
 451.258 +  /***                                                                   ***/
 451.259 +  /***                                                                   ***/
 451.260 +  /*************************************************************************/
 451.261 +  /*************************************************************************/
 451.262 +  /*************************************************************************/
 451.263 +
 451.264 +
 451.265 +  /*************************************************************************/
 451.266 +  /*                                                                       */
 451.267 +  /* <Struct>                                                              */
 451.268 +  /*    TT_GaspRangeRec                                                    */
 451.269 +  /*                                                                       */
 451.270 +  /* <Description>                                                         */
 451.271 +  /*    A tiny structure used to model a gasp range according to the       */
 451.272 +  /*    TrueType specification.                                            */
 451.273 +  /*                                                                       */
 451.274 +  /* <Fields>                                                              */
 451.275 +  /*    maxPPEM  :: The maximum ppem value to which `gaspFlag' applies.    */
 451.276 +  /*                                                                       */
 451.277 +  /*    gaspFlag :: A flag describing the grid-fitting and anti-aliasing   */
 451.278 +  /*                modes to be used.                                      */
 451.279 +  /*                                                                       */
 451.280 +  typedef struct  TT_GaspRangeRec_
 451.281 +  {
 451.282 +    FT_UShort  maxPPEM;
 451.283 +    FT_UShort  gaspFlag;
 451.284 +
 451.285 +  } TT_GaspRangeRec, *TT_GaspRange;
 451.286 +
 451.287 +
 451.288 +#define TT_GASP_GRIDFIT  0x01
 451.289 +#define TT_GASP_DOGRAY   0x02
 451.290 +
 451.291 +
 451.292 +  /*************************************************************************/
 451.293 +  /*                                                                       */
 451.294 +  /* <Struct>                                                              */
 451.295 +  /*    TT_GaspRec                                                         */
 451.296 +  /*                                                                       */
 451.297 +  /* <Description>                                                         */
 451.298 +  /*    A structure modeling the TrueType `gasp' table used to specify     */
 451.299 +  /*    grid-fitting and anti-aliasing behaviour.                          */
 451.300 +  /*                                                                       */
 451.301 +  /* <Fields>                                                              */
 451.302 +  /*    version    :: The version number.                                  */
 451.303 +  /*                                                                       */
 451.304 +  /*    numRanges  :: The number of gasp ranges in table.                  */
 451.305 +  /*                                                                       */
 451.306 +  /*    gaspRanges :: An array of gasp ranges.                             */
 451.307 +  /*                                                                       */
 451.308 +  typedef struct  TT_Gasp_
 451.309 +  {
 451.310 +    FT_UShort     version;
 451.311 +    FT_UShort     numRanges;
 451.312 +    TT_GaspRange  gaspRanges;
 451.313 +
 451.314 +  } TT_GaspRec;
 451.315 +
 451.316 +
 451.317 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 451.318 +
 451.319 +  /*************************************************************************/
 451.320 +  /*                                                                       */
 451.321 +  /* <Struct>                                                              */
 451.322 +  /*    TT_HdmxEntryRec                                                    */
 451.323 +  /*                                                                       */
 451.324 +  /* <Description>                                                         */
 451.325 +  /*    A small structure used to model the pre-computed widths of a given */
 451.326 +  /*    size.  They are found in the `hdmx' table.                         */
 451.327 +  /*                                                                       */
 451.328 +  /* <Fields>                                                              */
 451.329 +  /*    ppem      :: The pixels per EM value at which these metrics apply. */
 451.330 +  /*                                                                       */
 451.331 +  /*    max_width :: The maximum advance width for this metric.            */
 451.332 +  /*                                                                       */
 451.333 +  /*    widths    :: An array of widths.  Note: These are 8-bit bytes.     */
 451.334 +  /*                                                                       */
 451.335 +  typedef struct  TT_HdmxEntryRec_
 451.336 +  {
 451.337 +    FT_Byte   ppem;
 451.338 +    FT_Byte   max_width;
 451.339 +    FT_Byte*  widths;
 451.340 +
 451.341 +  } TT_HdmxEntryRec, *TT_HdmxEntry;
 451.342 +
 451.343 +
 451.344 +  /*************************************************************************/
 451.345 +  /*                                                                       */
 451.346 +  /* <Struct>                                                              */
 451.347 +  /*    TT_HdmxRec                                                         */
 451.348 +  /*                                                                       */
 451.349 +  /* <Description>                                                         */
 451.350 +  /*    A structure used to model the `hdmx' table, which contains         */
 451.351 +  /*    pre-computed widths for a set of given sizes/dimensions.           */
 451.352 +  /*                                                                       */
 451.353 +  /* <Fields>                                                              */
 451.354 +  /*    version     :: The version number.                                 */
 451.355 +  /*                                                                       */
 451.356 +  /*    num_records :: The number of hdmx records.                         */
 451.357 +  /*                                                                       */
 451.358 +  /*    records     :: An array of hdmx records.                           */
 451.359 +  /*                                                                       */
 451.360 +  typedef struct  TT_HdmxRec_
 451.361 +  {
 451.362 +    FT_UShort     version;
 451.363 +    FT_Short      num_records;
 451.364 +    TT_HdmxEntry  records;
 451.365 +
 451.366 +  } TT_HdmxRec, *TT_Hdmx;
 451.367 +
 451.368 +
 451.369 +  /*************************************************************************/
 451.370 +  /*                                                                       */
 451.371 +  /* <Struct>                                                              */
 451.372 +  /*    TT_Kern0_PairRec                                                   */
 451.373 +  /*                                                                       */
 451.374 +  /* <Description>                                                         */
 451.375 +  /*    A structure used to model a kerning pair for the kerning table     */
 451.376 +  /*    format 0.  The engine now loads this table if it finds one in the  */
 451.377 +  /*    font file.                                                         */
 451.378 +  /*                                                                       */
 451.379 +  /* <Fields>                                                              */
 451.380 +  /*    left  :: The index of the left glyph in pair.                      */
 451.381 +  /*                                                                       */
 451.382 +  /*    right :: The index of the right glyph in pair.                     */
 451.383 +  /*                                                                       */
 451.384 +  /*    value :: The kerning distance.  A positive value spaces the        */
 451.385 +  /*             glyphs, a negative one makes them closer.                 */
 451.386 +  /*                                                                       */
 451.387 +  typedef struct  TT_Kern0_PairRec_
 451.388 +  {
 451.389 +    FT_UShort  left;   /* index of left  glyph in pair */
 451.390 +    FT_UShort  right;  /* index of right glyph in pair */
 451.391 +    FT_FWord   value;  /* kerning value                */
 451.392 +
 451.393 +  } TT_Kern0_PairRec, *TT_Kern0_Pair;
 451.394 +
 451.395 +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
 451.396 +
 451.397 +
 451.398 +  /*************************************************************************/
 451.399 +  /*************************************************************************/
 451.400 +  /*************************************************************************/
 451.401 +  /***                                                                   ***/
 451.402 +  /***                                                                   ***/
 451.403 +  /***                    EMBEDDED BITMAPS SUPPORT                       ***/
 451.404 +  /***                                                                   ***/
 451.405 +  /***                                                                   ***/
 451.406 +  /*************************************************************************/
 451.407 +  /*************************************************************************/
 451.408 +  /*************************************************************************/
 451.409 +
 451.410 +
 451.411 +  /*************************************************************************/
 451.412 +  /*                                                                       */
 451.413 +  /* <Struct>                                                              */
 451.414 +  /*    TT_SBit_MetricsRec                                                 */
 451.415 +  /*                                                                       */
 451.416 +  /* <Description>                                                         */
 451.417 +  /*    A structure used to hold the big metrics of a given glyph bitmap   */
 451.418 +  /*    in a TrueType or OpenType font.  These are usually found in the    */
 451.419 +  /*    `EBDT' (Microsoft) or `bloc' (Apple) table.                        */
 451.420 +  /*                                                                       */
 451.421 +  /* <Fields>                                                              */
 451.422 +  /*    height       :: The glyph height in pixels.                        */
 451.423 +  /*                                                                       */
 451.424 +  /*    width        :: The glyph width in pixels.                         */
 451.425 +  /*                                                                       */
 451.426 +  /*    horiBearingX :: The horizontal left bearing.                       */
 451.427 +  /*                                                                       */
 451.428 +  /*    horiBearingY :: The horizontal top bearing.                        */
 451.429 +  /*                                                                       */
 451.430 +  /*    horiAdvance  :: The horizontal advance.                            */
 451.431 +  /*                                                                       */
 451.432 +  /*    vertBearingX :: The vertical left bearing.                         */
 451.433 +  /*                                                                       */
 451.434 +  /*    vertBearingY :: The vertical top bearing.                          */
 451.435 +  /*                                                                       */
 451.436 +  /*    vertAdvance  :: The vertical advance.                              */
 451.437 +  /*                                                                       */
 451.438 +  typedef struct  TT_SBit_MetricsRec_
 451.439 +  {
 451.440 +    FT_Byte  height;
 451.441 +    FT_Byte  width;
 451.442 +
 451.443 +    FT_Char  horiBearingX;
 451.444 +    FT_Char  horiBearingY;
 451.445 +    FT_Byte  horiAdvance;
 451.446 +
 451.447 +    FT_Char  vertBearingX;
 451.448 +    FT_Char  vertBearingY;
 451.449 +    FT_Byte  vertAdvance;
 451.450 +
 451.451 +  } TT_SBit_MetricsRec, *TT_SBit_Metrics;
 451.452 +
 451.453 +
 451.454 +  /*************************************************************************/
 451.455 +  /*                                                                       */
 451.456 +  /* <Struct>                                                              */
 451.457 +  /*    TT_SBit_SmallMetricsRec                                            */
 451.458 +  /*                                                                       */
 451.459 +  /* <Description>                                                         */
 451.460 +  /*    A structure used to hold the small metrics of a given glyph bitmap */
 451.461 +  /*    in a TrueType or OpenType font.  These are usually found in the    */
 451.462 +  /*    `EBDT' (Microsoft) or the `bdat' (Apple) table.                    */
 451.463 +  /*                                                                       */
 451.464 +  /* <Fields>                                                              */
 451.465 +  /*    height   :: The glyph height in pixels.                            */
 451.466 +  /*                                                                       */
 451.467 +  /*    width    :: The glyph width in pixels.                             */
 451.468 +  /*                                                                       */
 451.469 +  /*    bearingX :: The left-side bearing.                                 */
 451.470 +  /*                                                                       */
 451.471 +  /*    bearingY :: The top-side bearing.                                  */
 451.472 +  /*                                                                       */
 451.473 +  /*    advance  :: The advance width or height.                           */
 451.474 +  /*                                                                       */
 451.475 +  typedef struct  TT_SBit_Small_Metrics_
 451.476 +  {
 451.477 +    FT_Byte  height;
 451.478 +    FT_Byte  width;
 451.479 +
 451.480 +    FT_Char  bearingX;
 451.481 +    FT_Char  bearingY;
 451.482 +    FT_Byte  advance;
 451.483 +
 451.484 +  } TT_SBit_SmallMetricsRec, *TT_SBit_SmallMetrics;
 451.485 +
 451.486 +
 451.487 +  /*************************************************************************/
 451.488 +  /*                                                                       */
 451.489 +  /* <Struct>                                                              */
 451.490 +  /*    TT_SBit_LineMetricsRec                                             */
 451.491 +  /*                                                                       */
 451.492 +  /* <Description>                                                         */
 451.493 +  /*    A structure used to describe the text line metrics of a given      */
 451.494 +  /*    bitmap strike, for either a horizontal or vertical layout.         */
 451.495 +  /*                                                                       */
 451.496 +  /* <Fields>                                                              */
 451.497 +  /*    ascender                :: The ascender in pixels.                 */
 451.498 +  /*                                                                       */
 451.499 +  /*    descender               :: The descender in pixels.                */
 451.500 +  /*                                                                       */
 451.501 +  /*    max_width               :: The maximum glyph width in pixels.      */
 451.502 +  /*                                                                       */
 451.503 +  /*    caret_slope_enumerator  :: Rise of the caret slope, typically set  */
 451.504 +  /*                               to 1 for non-italic fonts.              */
 451.505 +  /*                                                                       */
 451.506 +  /*    caret_slope_denominator :: Rise of the caret slope, typically set  */
 451.507 +  /*                               to 0 for non-italic fonts.              */
 451.508 +  /*                                                                       */
 451.509 +  /*    caret_offset            :: Offset in pixels to move the caret for  */
 451.510 +  /*                               proper positioning.                     */
 451.511 +  /*                                                                       */
 451.512 +  /*    min_origin_SB           :: Minimum of horiBearingX (resp.          */
 451.513 +  /*                               vertBearingY).                          */
 451.514 +  /*    min_advance_SB          :: Minimum of                              */
 451.515 +  /*                                                                       */
 451.516 +  /*                                 horizontal advance -                  */
 451.517 +  /*                                   ( horiBearingX + width )            */
 451.518 +  /*                                                                       */
 451.519 +  /*                               resp.                                   */
 451.520 +  /*                                                                       */
 451.521 +  /*                                 vertical advance -                    */
 451.522 +  /*                                   ( vertBearingY + height )           */
 451.523 +  /*                                                                       */
 451.524 +  /*    max_before_BL           :: Maximum of horiBearingY (resp.          */
 451.525 +  /*                               vertBearingY).                          */
 451.526 +  /*                                                                       */
 451.527 +  /*    min_after_BL            :: Minimum of                              */
 451.528 +  /*                                                                       */
 451.529 +  /*                                 horiBearingY - height                 */
 451.530 +  /*                                                                       */
 451.531 +  /*                               resp.                                   */
 451.532 +  /*                                                                       */
 451.533 +  /*                                 vertBearingX - width                  */
 451.534 +  /*                                                                       */
 451.535 +  /*    pads                    :: Unused (to make the size of the record  */
 451.536 +  /*                               a multiple of 32 bits.                  */
 451.537 +  /*                                                                       */
 451.538 +  typedef struct  TT_SBit_LineMetricsRec_
 451.539 +  {
 451.540 +    FT_Char  ascender;
 451.541 +    FT_Char  descender;
 451.542 +    FT_Byte  max_width;
 451.543 +    FT_Char  caret_slope_numerator;
 451.544 +    FT_Char  caret_slope_denominator;
 451.545 +    FT_Char  caret_offset;
 451.546 +    FT_Char  min_origin_SB;
 451.547 +    FT_Char  min_advance_SB;
 451.548 +    FT_Char  max_before_BL;
 451.549 +    FT_Char  min_after_BL;
 451.550 +    FT_Char  pads[2];
 451.551 +
 451.552 +  } TT_SBit_LineMetricsRec, *TT_SBit_LineMetrics;
 451.553 +
 451.554 +
 451.555 +  /*************************************************************************/
 451.556 +  /*                                                                       */
 451.557 +  /* <Struct>                                                              */
 451.558 +  /*    TT_SBit_RangeRec                                                   */
 451.559 +  /*                                                                       */
 451.560 +  /* <Description>                                                         */
 451.561 +  /*    A TrueType/OpenType subIndexTable as defined in the `EBLC'         */
 451.562 +  /*    (Microsoft) or `bloc' (Apple) tables.                              */
 451.563 +  /*                                                                       */
 451.564 +  /* <Fields>                                                              */
 451.565 +  /*    first_glyph   :: The first glyph index in the range.               */
 451.566 +  /*                                                                       */
 451.567 +  /*    last_glyph    :: The last glyph index in the range.                */
 451.568 +  /*                                                                       */
 451.569 +  /*    index_format  :: The format of index table.  Valid values are 1    */
 451.570 +  /*                     to 5.                                             */
 451.571 +  /*                                                                       */
 451.572 +  /*    image_format  :: The format of `EBDT' image data.                  */
 451.573 +  /*                                                                       */
 451.574 +  /*    image_offset  :: The offset to image data in `EBDT'.               */
 451.575 +  /*                                                                       */
 451.576 +  /*    image_size    :: For index formats 2 and 5.  This is the size in   */
 451.577 +  /*                     bytes of each glyph bitmap.                       */
 451.578 +  /*                                                                       */
 451.579 +  /*    big_metrics   :: For index formats 2 and 5.  This is the big       */
 451.580 +  /*                     metrics for each glyph bitmap.                    */
 451.581 +  /*                                                                       */
 451.582 +  /*    num_glyphs    :: For index formats 4 and 5.  This is the number of */
 451.583 +  /*                     glyphs in the code array.                         */
 451.584 +  /*                                                                       */
 451.585 +  /*    glyph_offsets :: For index formats 1 and 3.                        */
 451.586 +  /*                                                                       */
 451.587 +  /*    glyph_codes   :: For index formats 4 and 5.                        */
 451.588 +  /*                                                                       */
 451.589 +  /*    table_offset  :: The offset of the index table in the `EBLC'       */
 451.590 +  /*                     table.  Only used during strike loading.          */
 451.591 +  /*                                                                       */
 451.592 +  typedef struct  TT_SBit_RangeRec_
 451.593 +  {
 451.594 +    FT_UShort           first_glyph;
 451.595 +    FT_UShort           last_glyph;
 451.596 +
 451.597 +    FT_UShort           index_format;
 451.598 +    FT_UShort           image_format;
 451.599 +    FT_ULong            image_offset;
 451.600 +
 451.601 +    FT_ULong            image_size;
 451.602 +    TT_SBit_MetricsRec  metrics;
 451.603 +    FT_ULong            num_glyphs;
 451.604 +
 451.605 +    FT_ULong*           glyph_offsets;
 451.606 +    FT_UShort*          glyph_codes;
 451.607 +
 451.608 +    FT_ULong            table_offset;
 451.609 +
 451.610 +  } TT_SBit_RangeRec, *TT_SBit_Range;
 451.611 +
 451.612 +
 451.613 +  /*************************************************************************/
 451.614 +  /*                                                                       */
 451.615 +  /* <Struct>                                                              */
 451.616 +  /*    TT_SBit_StrikeRec                                                  */
 451.617 +  /*                                                                       */
 451.618 +  /* <Description>                                                         */
 451.619 +  /*    A structure used describe a given bitmap strike in the `EBLC'      */
 451.620 +  /*    (Microsoft) or `bloc' (Apple) tables.                              */
 451.621 +  /*                                                                       */
 451.622 +  /* <Fields>                                                              */
 451.623 +  /*   num_index_ranges :: The number of index ranges.                     */
 451.624 +  /*                                                                       */
 451.625 +  /*   index_ranges     :: An array of glyph index ranges.                 */
 451.626 +  /*                                                                       */
 451.627 +  /*   color_ref        :: Unused.  `color_ref' is put in for future       */
 451.628 +  /*                       enhancements, but these fields are already      */
 451.629 +  /*                       in use by other platforms (e.g. Newton).        */
 451.630 +  /*                       For details, please see                         */
 451.631 +  /*                                                                       */
 451.632 +  /*                         http://fonts.apple.com/                       */
 451.633 +  /*                                TTRefMan/RM06/Chap6bloc.html           */
 451.634 +  /*                                                                       */
 451.635 +  /*   hori             :: The line metrics for horizontal layouts.        */
 451.636 +  /*                                                                       */
 451.637 +  /*   vert             :: The line metrics for vertical layouts.          */
 451.638 +  /*                                                                       */
 451.639 +  /*   start_glyph      :: The lowest glyph index for this strike.         */
 451.640 +  /*                                                                       */
 451.641 +  /*   end_glyph        :: The highest glyph index for this strike.        */
 451.642 +  /*                                                                       */
 451.643 +  /*   x_ppem           :: The number of horizontal pixels per EM.         */
 451.644 +  /*                                                                       */
 451.645 +  /*   y_ppem           :: The number of vertical pixels per EM.           */
 451.646 +  /*                                                                       */
 451.647 +  /*   bit_depth        :: The bit depth.  Valid values are 1, 2, 4,       */
 451.648 +  /*                       and 8.                                          */
 451.649 +  /*                                                                       */
 451.650 +  /*   flags            :: Is this a vertical or horizontal strike?  For   */
 451.651 +  /*                       details, please see                             */
 451.652 +  /*                                                                       */
 451.653 +  /*                         http://fonts.apple.com/                       */
 451.654 +  /*                                TTRefMan/RM06/Chap6bloc.html           */
 451.655 +  /*                                                                       */
 451.656 +  typedef struct  TT_SBit_StrikeRec_
 451.657 +  {
 451.658 +    FT_Int                  num_ranges;
 451.659 +    TT_SBit_Range           sbit_ranges;
 451.660 +    FT_ULong                ranges_offset;
 451.661 +
 451.662 +    FT_ULong                color_ref;
 451.663 +
 451.664 +    TT_SBit_LineMetricsRec  hori;
 451.665 +    TT_SBit_LineMetricsRec  vert;
 451.666 +
 451.667 +    FT_UShort               start_glyph;
 451.668 +    FT_UShort               end_glyph;
 451.669 +
 451.670 +    FT_Byte                 x_ppem;
 451.671 +    FT_Byte                 y_ppem;
 451.672 +
 451.673 +    FT_Byte                 bit_depth;
 451.674 +    FT_Char                 flags;
 451.675 +
 451.676 +  } TT_SBit_StrikeRec, *TT_SBit_Strike;
 451.677 +
 451.678 +
 451.679 +  /*************************************************************************/
 451.680 +  /*                                                                       */
 451.681 +  /* <Struct>                                                              */
 451.682 +  /*    TT_SBit_ComponentRec                                               */
 451.683 +  /*                                                                       */
 451.684 +  /* <Description>                                                         */
 451.685 +  /*    A simple structure to describe a compound sbit element.            */
 451.686 +  /*                                                                       */
 451.687 +  /* <Fields>                                                              */
 451.688 +  /*    glyph_code :: The element's glyph index.                           */
 451.689 +  /*                                                                       */
 451.690 +  /*    x_offset   :: The element's left bearing.                          */
 451.691 +  /*                                                                       */
 451.692 +  /*    y_offset   :: The element's top bearing.                           */
 451.693 +  /*                                                                       */
 451.694 +  typedef struct  TT_SBit_ComponentRec_
 451.695 +  {
 451.696 +    FT_UShort  glyph_code;
 451.697 +    FT_Char    x_offset;
 451.698 +    FT_Char    y_offset;
 451.699 +
 451.700 +  } TT_SBit_ComponentRec, *TT_SBit_Component;
 451.701 +
 451.702 +
 451.703 +  /*************************************************************************/
 451.704 +  /*                                                                       */
 451.705 +  /* <Struct>                                                              */
 451.706 +  /*    TT_SBit_ScaleRec                                                   */
 451.707 +  /*                                                                       */
 451.708 +  /* <Description>                                                         */
 451.709 +  /*    A structure used describe a given bitmap scaling table, as defined */
 451.710 +  /*    in the `EBSC' table.                                               */
 451.711 +  /*                                                                       */
 451.712 +  /* <Fields>                                                              */
 451.713 +  /*    hori              :: The horizontal line metrics.                  */
 451.714 +  /*                                                                       */
 451.715 +  /*    vert              :: The vertical line metrics.                    */
 451.716 +  /*                                                                       */
 451.717 +  /*    x_ppem            :: The number of horizontal pixels per EM.       */
 451.718 +  /*                                                                       */
 451.719 +  /*    y_ppem            :: The number of vertical pixels per EM.         */
 451.720 +  /*                                                                       */
 451.721 +  /*    x_ppem_substitute :: Substitution x_ppem value.                    */
 451.722 +  /*                                                                       */
 451.723 +  /*    y_ppem_substitute :: Substitution y_ppem value.                    */
 451.724 +  /*                                                                       */
 451.725 +  typedef struct  TT_SBit_ScaleRec_
 451.726 +  {
 451.727 +    TT_SBit_LineMetricsRec  hori;
 451.728 +    TT_SBit_LineMetricsRec  vert;
 451.729 +
 451.730 +    FT_Byte                 x_ppem;
 451.731 +    FT_Byte                 y_ppem;
 451.732 +
 451.733 +    FT_Byte                 x_ppem_substitute;
 451.734 +    FT_Byte                 y_ppem_substitute;
 451.735 +
 451.736 +  } TT_SBit_ScaleRec, *TT_SBit_Scale;
 451.737 +
 451.738 +
 451.739 +  /*************************************************************************/
 451.740 +  /*************************************************************************/
 451.741 +  /*************************************************************************/
 451.742 +  /***                                                                   ***/
 451.743 +  /***                                                                   ***/
 451.744 +  /***                  POSTSCRIPT GLYPH NAMES SUPPORT                   ***/
 451.745 +  /***                                                                   ***/
 451.746 +  /***                                                                   ***/
 451.747 +  /*************************************************************************/
 451.748 +  /*************************************************************************/
 451.749 +  /*************************************************************************/
 451.750 +
 451.751 +
 451.752 +  /*************************************************************************/
 451.753 +  /*                                                                       */
 451.754 +  /* <Struct>                                                              */
 451.755 +  /*    TT_Post_20Rec                                                      */
 451.756 +  /*                                                                       */
 451.757 +  /* <Description>                                                         */
 451.758 +  /*    Postscript names sub-table, format 2.0.  Stores the PS name of     */
 451.759 +  /*    each glyph in the font face.                                       */
 451.760 +  /*                                                                       */
 451.761 +  /* <Fields>                                                              */
 451.762 +  /*    num_glyphs    :: The number of named glyphs in the table.          */
 451.763 +  /*                                                                       */
 451.764 +  /*    num_names     :: The number of PS names stored in the table.       */
 451.765 +  /*                                                                       */
 451.766 +  /*    glyph_indices :: The indices of the glyphs in the names arrays.    */
 451.767 +  /*                                                                       */
 451.768 +  /*    glyph_names   :: The PS names not in Mac Encoding.                 */
 451.769 +  /*                                                                       */
 451.770 +  typedef struct  TT_Post_20Rec_
 451.771 +  {
 451.772 +    FT_UShort   num_glyphs;
 451.773 +    FT_UShort   num_names;
 451.774 +    FT_UShort*  glyph_indices;
 451.775 +    FT_Char**   glyph_names;
 451.776 +
 451.777 +  } TT_Post_20Rec, *TT_Post_20;
 451.778 +
 451.779 +
 451.780 +  /*************************************************************************/
 451.781 +  /*                                                                       */
 451.782 +  /* <Struct>                                                              */
 451.783 +  /*    TT_Post_25Rec                                                      */
 451.784 +  /*                                                                       */
 451.785 +  /* <Description>                                                         */
 451.786 +  /*    Postscript names sub-table, format 2.5.  Stores the PS name of     */
 451.787 +  /*    each glyph in the font face.                                       */
 451.788 +  /*                                                                       */
 451.789 +  /* <Fields>                                                              */
 451.790 +  /*    num_glyphs :: The number of glyphs in the table.                   */
 451.791 +  /*                                                                       */
 451.792 +  /*    offsets    :: An array of signed offsets in a normal Mac           */
 451.793 +  /*                  Postscript name encoding.                            */
 451.794 +  /*                                                                       */
 451.795 +  typedef struct  TT_Post_25_
 451.796 +  {
 451.797 +    FT_UShort  num_glyphs;
 451.798 +    FT_Char*   offsets;
 451.799 +
 451.800 +  } TT_Post_25Rec, *TT_Post_25;
 451.801 +
 451.802 +
 451.803 +  /*************************************************************************/
 451.804 +  /*                                                                       */
 451.805 +  /* <Struct>                                                              */
 451.806 +  /*    TT_Post_NamesRec                                                   */
 451.807 +  /*                                                                       */
 451.808 +  /* <Description>                                                         */
 451.809 +  /*    Postscript names table, either format 2.0 or 2.5.                  */
 451.810 +  /*                                                                       */
 451.811 +  /* <Fields>                                                              */
 451.812 +  /*    loaded    :: A flag to indicate whether the PS names are loaded.   */
 451.813 +  /*                                                                       */
 451.814 +  /*    format_20 :: The sub-table used for format 2.0.                    */
 451.815 +  /*                                                                       */
 451.816 +  /*    format_25 :: The sub-table used for format 2.5.                    */
 451.817 +  /*                                                                       */
 451.818 +  typedef struct  TT_Post_NamesRec_
 451.819 +  {
 451.820 +    FT_Bool  loaded;
 451.821 +
 451.822 +    union
 451.823 +    {
 451.824 +      TT_Post_20Rec  format_20;
 451.825 +      TT_Post_25Rec  format_25;
 451.826 +
 451.827 +    } names;
 451.828 +
 451.829 +  } TT_Post_NamesRec, *TT_Post_Names;
 451.830 +
 451.831 +
 451.832 +  /*************************************************************************/
 451.833 +  /*************************************************************************/
 451.834 +  /*************************************************************************/
 451.835 +  /***                                                                   ***/
 451.836 +  /***                                                                   ***/
 451.837 +  /***                    GX VARIATION TABLE SUPPORT                     ***/
 451.838 +  /***                                                                   ***/
 451.839 +  /***                                                                   ***/
 451.840 +  /*************************************************************************/
 451.841 +  /*************************************************************************/
 451.842 +  /*************************************************************************/
 451.843 +
 451.844 +
 451.845 +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 451.846 +  typedef struct GX_BlendRec_  *GX_Blend;
 451.847 +#endif
 451.848 +
 451.849 +  /*************************************************************************/
 451.850 +  /*************************************************************************/
 451.851 +  /*************************************************************************/
 451.852 +  /***                                                                   ***/
 451.853 +  /***                                                                   ***/
 451.854 +  /***              EMBEDDED BDF PROPERTIES TABLE SUPPORT                ***/
 451.855 +  /***                                                                   ***/
 451.856 +  /***                                                                   ***/
 451.857 +  /*************************************************************************/
 451.858 +  /*************************************************************************/
 451.859 +  /*************************************************************************/
 451.860 +
 451.861 +  /*
 451.862 +   * These types are used to support a `BDF ' table that isn't part of the
 451.863 +   * official TrueType specification.  It is mainly used in SFNT-based
 451.864 +   * bitmap fonts that were generated from a set of BDF fonts.
 451.865 +   *
 451.866 +   * The format of the table is as follows.
 451.867 +   *
 451.868 +   *   USHORT   version      `BDF ' table version number, should be 0x0001.
 451.869 +   *   USHORT   strikeCount  Number of strikes (bitmap sizes) in this table.
 451.870 +   *   ULONG    stringTable  Offset (from start of BDF table) to string
 451.871 +   *                         table.
 451.872 +   *
 451.873 +   * This is followed by an array of `strikeCount' descriptors, having the
 451.874 +   * following format.
 451.875 +   *
 451.876 +   *   USHORT   ppem         Vertical pixels per EM for this strike.
 451.877 +   *   USHORT   numItems     Number of items for this strike (properties and
 451.878 +   *                         atoms).  Maximum is 255.
 451.879 +   *
 451.880 +   * This array in turn is followed by `strikeCount' value sets.  Each
 451.881 +   * `value set' is an array of `numItems' items with the following format.
 451.882 +   *
 451.883 +   *   ULONG    item_name    Offset in string table to item name.
 451.884 +   *   USHORT   item_type    The item type.  Possible values are
 451.885 +   *                            0 => string (e.g., COMMENT)
 451.886 +   *                            1 => atom   (e.g., FONT or even SIZE)
 451.887 +   *                            2 => int32
 451.888 +   *                            3 => uint32
 451.889 +   *                         0x10 => A flag to indicate a properties.  This
 451.890 +   *                                 is ORed with the above values.
 451.891 +   *   ULONG    item_value   For strings  => Offset into string table without
 451.892 +   *                                         the corresponding double quotes.
 451.893 +   *                         For atoms    => Offset into string table.
 451.894 +   *                         For integers => Direct value.
 451.895 +   *
 451.896 +   * All strings in the string table consist of bytes and are
 451.897 +   * zero-terminated.
 451.898 +   *
 451.899 +   */
 451.900 +
 451.901 +#ifdef TT_CONFIG_OPTION_BDF
 451.902 +
 451.903 +  typedef struct  TT_BDFRec_
 451.904 +  {
 451.905 +    FT_Byte*   table;
 451.906 +    FT_Byte*   table_end;
 451.907 +    FT_Byte*   strings;
 451.908 +    FT_ULong   strings_size;
 451.909 +    FT_UInt    num_strikes;
 451.910 +    FT_Bool    loaded;
 451.911 +
 451.912 +  } TT_BDFRec, *TT_BDF;
 451.913 +
 451.914 +#endif /* TT_CONFIG_OPTION_BDF */
 451.915 +
 451.916 +  /*************************************************************************/
 451.917 +  /*************************************************************************/
 451.918 +  /*************************************************************************/
 451.919 +  /***                                                                   ***/
 451.920 +  /***                                                                   ***/
 451.921 +  /***                  ORIGINAL TT_FACE CLASS DEFINITION                ***/
 451.922 +  /***                                                                   ***/
 451.923 +  /***                                                                   ***/
 451.924 +  /*************************************************************************/
 451.925 +  /*************************************************************************/
 451.926 +  /*************************************************************************/
 451.927 +
 451.928 +
 451.929 +  /*************************************************************************/
 451.930 +  /*                                                                       */
 451.931 +  /* This structure/class is defined here because it is common to the      */
 451.932 +  /* following formats: TTF, OpenType-TT, and OpenType-CFF.                */
 451.933 +  /*                                                                       */
 451.934 +  /* Note, however, that the classes TT_Size and TT_GlyphSlot are not      */
 451.935 +  /* shared between font drivers, and are thus defined in `ttobjs.h'.      */
 451.936 +  /*                                                                       */
 451.937 +  /*************************************************************************/
 451.938 +
 451.939 +
 451.940 +  /*************************************************************************/
 451.941 +  /*                                                                       */
 451.942 +  /* <Type>                                                                */
 451.943 +  /*    TT_Face                                                            */
 451.944 +  /*                                                                       */
 451.945 +  /* <Description>                                                         */
 451.946 +  /*    A handle to a TrueType face/font object.  A TT_Face encapsulates   */
 451.947 +  /*    the resolution and scaling independent parts of a TrueType font    */
 451.948 +  /*    resource.                                                          */
 451.949 +  /*                                                                       */
 451.950 +  /* <Note>                                                                */
 451.951 +  /*    The TT_Face structure is also used as a `parent class' for the     */
 451.952 +  /*    OpenType-CFF class (T2_Face).                                      */
 451.953 +  /*                                                                       */
 451.954 +  typedef struct TT_FaceRec_*  TT_Face;
 451.955 +
 451.956 +
 451.957 +  /* a function type used for the truetype bytecode interpreter hooks */
 451.958 +  typedef FT_Error
 451.959 +  (*TT_Interpreter)( void*  exec_context );
 451.960 +
 451.961 +  /* forward declaration */
 451.962 +  typedef struct TT_LoaderRec_*  TT_Loader;
 451.963 +
 451.964 +
 451.965 +  /*************************************************************************/
 451.966 +  /*                                                                       */
 451.967 +  /* <FuncType>                                                            */
 451.968 +  /*    TT_Loader_GotoTableFunc                                            */
 451.969 +  /*                                                                       */
 451.970 +  /* <Description>                                                         */
 451.971 +  /*    Seeks a stream to the start of a given TrueType table.             */
 451.972 +  /*                                                                       */
 451.973 +  /* <Input>                                                               */
 451.974 +  /*    face   :: A handle to the target face object.                      */
 451.975 +  /*                                                                       */
 451.976 +  /*    tag    :: A 4-byte tag used to name the table.                     */
 451.977 +  /*                                                                       */
 451.978 +  /*    stream :: The input stream.                                        */
 451.979 +  /*                                                                       */
 451.980 +  /* <Output>                                                              */
 451.981 +  /*    length :: The length of the table in bytes.  Set to 0 if not       */
 451.982 +  /*              needed.                                                  */
 451.983 +  /*                                                                       */
 451.984 +  /* <Return>                                                              */
 451.985 +  /*    FreeType error code.  0 means success.                             */
 451.986 +  /*                                                                       */
 451.987 +  /* <Note>                                                                */
 451.988 +  /*    The stream cursor must be at the font file's origin.               */
 451.989 +  /*                                                                       */
 451.990 +  typedef FT_Error
 451.991 +  (*TT_Loader_GotoTableFunc)( TT_Face    face,
 451.992 +                              FT_ULong   tag,
 451.993 +                              FT_Stream  stream,
 451.994 +                              FT_ULong*  length );
 451.995 +
 451.996 +
 451.997 +  /*************************************************************************/
 451.998 +  /*                                                                       */
 451.999 +  /* <FuncType>                                                            */
451.1000 +  /*    TT_Loader_StartGlyphFunc                                           */
451.1001 +  /*                                                                       */
451.1002 +  /* <Description>                                                         */
451.1003 +  /*    Seeks a stream to the start of a given glyph element, and opens a  */
451.1004 +  /*    frame for it.                                                      */
451.1005 +  /*                                                                       */
451.1006 +  /* <Input>                                                               */
451.1007 +  /*    loader      :: The current TrueType glyph loader object.           */
451.1008 +  /*                                                                       */
451.1009 +  /*    glyph index :: The index of the glyph to access.                   */
451.1010 +  /*                                                                       */
451.1011 +  /*    offset      :: The offset of the glyph according to the            */
451.1012 +  /*                   `locations' table.                                  */
451.1013 +  /*                                                                       */
451.1014 +  /*    byte_count  :: The size of the frame in bytes.                     */
451.1015 +  /*                                                                       */
451.1016 +  /* <Return>                                                              */
451.1017 +  /*    FreeType error code.  0 means success.                             */
451.1018 +  /*                                                                       */
451.1019 +  /* <Note>                                                                */
451.1020 +  /*    This function is normally equivalent to FT_STREAM_SEEK(offset)     */
451.1021 +  /*    followed by FT_FRAME_ENTER(byte_count) with the loader's stream,   */
451.1022 +  /*    but alternative formats (e.g. compressed ones) might use something */
451.1023 +  /*    different.                                                         */
451.1024 +  /*                                                                       */
451.1025 +  typedef FT_Error
451.1026 +  (*TT_Loader_StartGlyphFunc)( TT_Loader  loader,
451.1027 +                               FT_UInt    glyph_index,
451.1028 +                               FT_ULong   offset,
451.1029 +                               FT_UInt    byte_count );
451.1030 +
451.1031 +
451.1032 +  /*************************************************************************/
451.1033 +  /*                                                                       */
451.1034 +  /* <FuncType>                                                            */
451.1035 +  /*    TT_Loader_ReadGlyphFunc                                            */
451.1036 +  /*                                                                       */
451.1037 +  /* <Description>                                                         */
451.1038 +  /*    Reads one glyph element (its header, a simple glyph, or a          */
451.1039 +  /*    composite) from the loader's current stream frame.                 */
451.1040 +  /*                                                                       */
451.1041 +  /* <Input>                                                               */
451.1042 +  /*    loader :: The current TrueType glyph loader object.                */
451.1043 +  /*                                                                       */
451.1044 +  /* <Return>                                                              */
451.1045 +  /*    FreeType error code.  0 means success.                             */
451.1046 +  /*                                                                       */
451.1047 +  typedef FT_Error
451.1048 +  (*TT_Loader_ReadGlyphFunc)( TT_Loader  loader );
451.1049 +
451.1050 +
451.1051 +  /*************************************************************************/
451.1052 +  /*                                                                       */
451.1053 +  /* <FuncType>                                                            */
451.1054 +  /*    TT_Loader_EndGlyphFunc                                             */
451.1055 +  /*                                                                       */
451.1056 +  /* <Description>                                                         */
451.1057 +  /*    Closes the current loader stream frame for the glyph.              */
451.1058 +  /*                                                                       */
451.1059 +  /* <Input>                                                               */
451.1060 +  /*    loader :: The current TrueType glyph loader object.                */
451.1061 +  /*                                                                       */
451.1062 +  typedef void
451.1063 +  (*TT_Loader_EndGlyphFunc)( TT_Loader  loader );
451.1064 +
451.1065 +
451.1066 +  /*************************************************************************/
451.1067 +  /*                                                                       */
451.1068 +  /*                         TrueType Face Type                            */
451.1069 +  /*                                                                       */
451.1070 +  /* <Struct>                                                              */
451.1071 +  /*    TT_Face                                                            */
451.1072 +  /*                                                                       */
451.1073 +  /* <Description>                                                         */
451.1074 +  /*    The TrueType face class.  These objects model the resolution and   */
451.1075 +  /*    point-size independent data found in a TrueType font file.         */
451.1076 +  /*                                                                       */
451.1077 +  /* <Fields>                                                              */
451.1078 +  /*    root                 :: The base FT_Face structure, managed by the */
451.1079 +  /*                            base layer.                                */
451.1080 +  /*                                                                       */
451.1081 +  /*    ttc_header           :: The TrueType collection header, used when  */
451.1082 +  /*                            the file is a `ttc' rather than a `ttf'.   */
451.1083 +  /*                            For ordinary font files, the field         */
451.1084 +  /*                            `ttc_header.count' is set to 0.            */
451.1085 +  /*                                                                       */
451.1086 +  /*    format_tag           :: The font format tag.                       */
451.1087 +  /*                                                                       */
451.1088 +  /*    num_tables           :: The number of TrueType tables in this font */
451.1089 +  /*                            file.                                      */
451.1090 +  /*                                                                       */
451.1091 +  /*    dir_tables           :: The directory of TrueType tables for this  */
451.1092 +  /*                            font file.                                 */
451.1093 +  /*                                                                       */
451.1094 +  /*    header               :: The font's font header (`head' table).     */
451.1095 +  /*                            Read on font opening.                      */
451.1096 +  /*                                                                       */
451.1097 +  /*    horizontal           :: The font's horizontal header (`hhea'       */
451.1098 +  /*                            table).  This field also contains the      */
451.1099 +  /*                            associated horizontal metrics table        */
451.1100 +  /*                            (`hmtx').                                  */
451.1101 +  /*                                                                       */
451.1102 +  /*    max_profile          :: The font's maximum profile table.  Read on */
451.1103 +  /*                            font opening.  Note that some maximum      */
451.1104 +  /*                            values cannot be taken directly from this  */
451.1105 +  /*                            table.  We thus define additional fields   */
451.1106 +  /*                            below to hold the computed maxima.         */
451.1107 +  /*                                                                       */
451.1108 +  /*    vertical_info        :: A boolean which is set when the font file  */
451.1109 +  /*                            contains vertical metrics.  If not, the    */
451.1110 +  /*                            value of the `vertical' field is           */
451.1111 +  /*                            undefined.                                 */
451.1112 +  /*                                                                       */
451.1113 +  /*    vertical             :: The font's vertical header (`vhea' table). */
451.1114 +  /*                            This field also contains the associated    */
451.1115 +  /*                            vertical metrics table (`vmtx'), if found. */
451.1116 +  /*                            IMPORTANT: The contents of this field is   */
451.1117 +  /*                            undefined if the `verticalInfo' field is   */
451.1118 +  /*                            unset.                                     */
451.1119 +  /*                                                                       */
451.1120 +  /*    num_names            :: The number of name records within this     */
451.1121 +  /*                            TrueType font.                             */
451.1122 +  /*                                                                       */
451.1123 +  /*    name_table           :: The table of name records (`name').        */
451.1124 +  /*                                                                       */
451.1125 +  /*    os2                  :: The font's OS/2 table (`OS/2').            */
451.1126 +  /*                                                                       */
451.1127 +  /*    postscript           :: The font's PostScript table (`post'        */
451.1128 +  /*                            table).  The PostScript glyph names are    */
451.1129 +  /*                            not loaded by the driver on face opening.  */
451.1130 +  /*                            See the `ttpost' module for more details.  */
451.1131 +  /*                                                                       */
451.1132 +  /*    cmap_table           :: Address of the face's `cmap' SFNT table    */
451.1133 +  /*                            in memory (it's an extracted frame).       */
451.1134 +  /*                                                                       */
451.1135 +  /*    cmap_size            :: The size in bytes of the `cmap_table'      */
451.1136 +  /*                            described above.                           */
451.1137 +  /*                                                                       */
451.1138 +  /*    goto_table           :: A function called by each TrueType table   */
451.1139 +  /*                            loader to position a stream's cursor to    */
451.1140 +  /*                            the start of a given table according to    */
451.1141 +  /*                            its tag.  It defaults to TT_Goto_Face but  */
451.1142 +  /*                            can be different for strange formats (e.g. */
451.1143 +  /*                            Type 42).                                  */
451.1144 +  /*                                                                       */
451.1145 +  /*    access_glyph_frame   :: A function used to access the frame of a   */
451.1146 +  /*                            given glyph within the face's font file.   */
451.1147 +  /*                                                                       */
451.1148 +  /*    forget_glyph_frame   :: A function used to forget the frame of a   */
451.1149 +  /*                            given glyph when all data has been loaded. */
451.1150 +  /*                                                                       */
451.1151 +  /*    read_glyph_header    :: A function used to read a glyph header.    */
451.1152 +  /*                            It must be called between an `access' and  */
451.1153 +  /*                            `forget'.                                  */
451.1154 +  /*                                                                       */
451.1155 +  /*    read_simple_glyph    :: A function used to read a simple glyph.    */
451.1156 +  /*                            It must be called after the header was     */
451.1157 +  /*                            read, and before the `forget'.             */
451.1158 +  /*                                                                       */
451.1159 +  /*    read_composite_glyph :: A function used to read a composite glyph. */
451.1160 +  /*                            It must be called after the header was     */
451.1161 +  /*                            read, and before the `forget'.             */
451.1162 +  /*                                                                       */
451.1163 +  /*    sfnt                 :: A pointer to the SFNT service.             */
451.1164 +  /*                                                                       */
451.1165 +  /*    psnames              :: A pointer to the PostScript names service. */
451.1166 +  /*                                                                       */
451.1167 +  /*    hdmx                 :: The face's horizontal device metrics       */
451.1168 +  /*                            (`hdmx' table).  This table is optional in */
451.1169 +  /*                            TrueType/OpenType fonts.                   */
451.1170 +  /*                                                                       */
451.1171 +  /*    gasp                 :: The grid-fitting and scaling properties    */
451.1172 +  /*                            table (`gasp').  This table is optional in */
451.1173 +  /*                            TrueType/OpenType fonts.                   */
451.1174 +  /*                                                                       */
451.1175 +  /*    pclt                 :: The `pclt' SFNT table.                     */
451.1176 +  /*                                                                       */
451.1177 +  /*    num_sbit_strikes     :: The number of sbit strikes, i.e., bitmap   */
451.1178 +  /*                            sizes, embedded in this font.              */
451.1179 +  /*                                                                       */
451.1180 +  /*    sbit_strikes         :: An array of sbit strikes embedded in this  */
451.1181 +  /*                            font.  This table is optional in a         */
451.1182 +  /*                            TrueType/OpenType font.                    */
451.1183 +  /*                                                                       */
451.1184 +  /*    num_sbit_scales      :: The number of sbit scales for this font.   */
451.1185 +  /*                                                                       */
451.1186 +  /*    sbit_scales          :: Array of sbit scales embedded in this      */
451.1187 +  /*                            font.  This table is optional in a         */
451.1188 +  /*                            TrueType/OpenType font.                    */
451.1189 +  /*                                                                       */
451.1190 +  /*    postscript_names     :: A table used to store the Postscript names */
451.1191 +  /*                            of  the glyphs for this font.  See the     */
451.1192 +  /*                            file  `ttconfig.h' for comments on the     */
451.1193 +  /*                            TT_CONFIG_OPTION_POSTSCRIPT_NAMES option.  */
451.1194 +  /*                                                                       */
451.1195 +  /*    num_locations        :: The number of glyph locations in this      */
451.1196 +  /*                            TrueType file.  This should be             */
451.1197 +  /*                            identical to the number of glyphs.         */
451.1198 +  /*                            Ignored for Type 2 fonts.                  */
451.1199 +  /*                                                                       */
451.1200 +  /*    glyph_locations      :: An array of longs.  These are offsets to   */
451.1201 +  /*                            glyph data within the `glyf' table.        */
451.1202 +  /*                            Ignored for Type 2 font faces.             */
451.1203 +  /*                                                                       */
451.1204 +  /*    glyf_len             :: The length of the `glyf' table.  Needed    */
451.1205 +  /*                            for malformed `loca' tables.               */
451.1206 +  /*                                                                       */
451.1207 +  /*    font_program_size    :: Size in bytecodes of the face's font       */
451.1208 +  /*                            program.  0 if none defined.  Ignored for  */
451.1209 +  /*                            Type 2 fonts.                              */
451.1210 +  /*                                                                       */
451.1211 +  /*    font_program         :: The face's font program (bytecode stream)  */
451.1212 +  /*                            executed at load time, also used during    */
451.1213 +  /*                            glyph rendering.  Comes from the `fpgm'    */
451.1214 +  /*                            table.  Ignored for Type 2 font fonts.     */
451.1215 +  /*                                                                       */
451.1216 +  /*    cvt_program_size     :: The size in bytecodes of the face's cvt    */
451.1217 +  /*                            program.  Ignored for Type 2 fonts.        */
451.1218 +  /*                                                                       */
451.1219 +  /*    cvt_program          :: The face's cvt program (bytecode stream)   */
451.1220 +  /*                            executed each time an instance/size is     */
451.1221 +  /*                            changed/reset.  Comes from the `prep'      */
451.1222 +  /*                            table.  Ignored for Type 2 fonts.          */
451.1223 +  /*                                                                       */
451.1224 +  /*    cvt_size             :: Size of the control value table (in        */
451.1225 +  /*                            entries).   Ignored for Type 2 fonts.      */
451.1226 +  /*                                                                       */
451.1227 +  /*    cvt                  :: The face's original control value table.   */
451.1228 +  /*                            Coordinates are expressed in unscaled font */
451.1229 +  /*                            units.  Comes from the `cvt ' table.       */
451.1230 +  /*                            Ignored for Type 2 fonts.                  */
451.1231 +  /*                                                                       */
451.1232 +  /*    num_kern_pairs       :: The number of kerning pairs present in the */
451.1233 +  /*                            font file.  The engine only loads the      */
451.1234 +  /*                            first horizontal format 0 kern table it    */
451.1235 +  /*                            finds in the font file.  Ignored for       */
451.1236 +  /*                            Type 2 fonts.                              */
451.1237 +  /*                                                                       */
451.1238 +  /*    kern_table_index     :: The index of the kerning table in the font */
451.1239 +  /*                            kerning directory.  Ignored for Type 2     */
451.1240 +  /*                            fonts.                                     */
451.1241 +  /*                                                                       */
451.1242 +  /*    interpreter          :: A pointer to the TrueType bytecode         */
451.1243 +  /*                            interpreters field is also used to hook    */
451.1244 +  /*                            the debugger in `ttdebug'.                 */
451.1245 +  /*                                                                       */
451.1246 +  /*    unpatented_hinting   :: If true, use only unpatented methods in    */
451.1247 +  /*                            the bytecode interpreter.                  */
451.1248 +  /*                                                                       */
451.1249 +  /*    doblend              :: A boolean which is set if the font should  */
451.1250 +  /*                            be blended (this is for GX var).           */
451.1251 +  /*                                                                       */
451.1252 +  /*    blend                :: Contains the data needed to control GX     */
451.1253 +  /*                            variation tables (rather like Multiple     */
451.1254 +  /*                            Master data).                              */
451.1255 +  /*                                                                       */
451.1256 +  /*    extra                :: Reserved for third-party font drivers.     */
451.1257 +  /*                                                                       */
451.1258 +  /*    postscript_name      :: The PS name of the font.  Used by the      */
451.1259 +  /*                            postscript name service.                   */
451.1260 +  /*                                                                       */
451.1261 +  typedef struct  TT_FaceRec_
451.1262 +  {
451.1263 +    FT_FaceRec            root;
451.1264 +
451.1265 +    TTC_HeaderRec         ttc_header;
451.1266 +
451.1267 +    FT_ULong              format_tag;
451.1268 +    FT_UShort             num_tables;
451.1269 +    TT_Table              dir_tables;
451.1270 +
451.1271 +    TT_Header             header;       /* TrueType header table          */
451.1272 +    TT_HoriHeader         horizontal;   /* TrueType horizontal header     */
451.1273 +
451.1274 +    TT_MaxProfile         max_profile;
451.1275 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
451.1276 +    FT_ULong              max_components;  /* stubbed to 0 */
451.1277 +#endif
451.1278 +
451.1279 +    FT_Bool               vertical_info;
451.1280 +    TT_VertHeader         vertical;     /* TT Vertical header, if present */
451.1281 +
451.1282 +    FT_UShort             num_names;    /* number of name records  */
451.1283 +    TT_NameTableRec       name_table;   /* name table              */
451.1284 +
451.1285 +    TT_OS2                os2;          /* TrueType OS/2 table            */
451.1286 +    TT_Postscript         postscript;   /* TrueType Postscript table      */
451.1287 +
451.1288 +    FT_Byte*              cmap_table;   /* extracted `cmap' table */
451.1289 +    FT_ULong              cmap_size;
451.1290 +
451.1291 +    TT_Loader_GotoTableFunc   goto_table;
451.1292 +
451.1293 +    TT_Loader_StartGlyphFunc  access_glyph_frame;
451.1294 +    TT_Loader_EndGlyphFunc    forget_glyph_frame;
451.1295 +    TT_Loader_ReadGlyphFunc   read_glyph_header;
451.1296 +    TT_Loader_ReadGlyphFunc   read_simple_glyph;
451.1297 +    TT_Loader_ReadGlyphFunc   read_composite_glyph;
451.1298 +
451.1299 +    /* a typeless pointer to the SFNT_Interface table used to load */
451.1300 +    /* the basic TrueType tables in the face object                */
451.1301 +    void*                 sfnt;
451.1302 +
451.1303 +    /* a typeless pointer to the FT_Service_PsCMapsRec table used to */
451.1304 +    /* handle glyph names <-> unicode & Mac values                   */
451.1305 +    void*                 psnames;
451.1306 +
451.1307 +
451.1308 +    /***********************************************************************/
451.1309 +    /*                                                                     */
451.1310 +    /* Optional TrueType/OpenType tables                                   */
451.1311 +    /*                                                                     */
451.1312 +    /***********************************************************************/
451.1313 +
451.1314 +    /* horizontal device metrics */
451.1315 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
451.1316 +    TT_HdmxRec            hdmx;
451.1317 +#endif
451.1318 +
451.1319 +    /* grid-fitting and scaling table */
451.1320 +    TT_GaspRec            gasp;                 /* the `gasp' table */
451.1321 +
451.1322 +    /* PCL 5 table */
451.1323 +    TT_PCLT               pclt;
451.1324 +
451.1325 +    /* embedded bitmaps support */
451.1326 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
451.1327 +    FT_ULong              num_sbit_strikes;
451.1328 +    TT_SBit_Strike        sbit_strikes;
451.1329 +#endif
451.1330 +
451.1331 +    FT_ULong              num_sbit_scales;
451.1332 +    TT_SBit_Scale         sbit_scales;
451.1333 +
451.1334 +    /* postscript names table */
451.1335 +    TT_Post_NamesRec      postscript_names;
451.1336 +
451.1337 +
451.1338 +    /***********************************************************************/
451.1339 +    /*                                                                     */
451.1340 +    /* TrueType-specific fields (ignored by the OTF-Type2 driver)          */
451.1341 +    /*                                                                     */
451.1342 +    /***********************************************************************/
451.1343 +
451.1344 +    /* the glyph locations */
451.1345 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
451.1346 +    FT_UShort             num_locations_stub;
451.1347 +    FT_Long*              glyph_locations_stub;
451.1348 +#endif
451.1349 +
451.1350 +    /* the font program, if any */
451.1351 +    FT_ULong              font_program_size;
451.1352 +    FT_Byte*              font_program;
451.1353 +
451.1354 +    /* the cvt program, if any */
451.1355 +    FT_ULong              cvt_program_size;
451.1356 +    FT_Byte*              cvt_program;
451.1357 +
451.1358 +    /* the original, unscaled, control value table */
451.1359 +    FT_ULong              cvt_size;
451.1360 +    FT_Short*             cvt;
451.1361 +
451.1362 +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
451.1363 +    /* the format 0 kerning table, if any */
451.1364 +    FT_Int                num_kern_pairs;
451.1365 +    FT_Int                kern_table_index;
451.1366 +    TT_Kern0_Pair         kern_pairs;
451.1367 +#endif
451.1368 +
451.1369 +    /* A pointer to the bytecode interpreter to use.  This is also */
451.1370 +    /* used to hook the debugger for the `ttdebug' utility.        */
451.1371 +    TT_Interpreter        interpreter;
451.1372 +
451.1373 +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
451.1374 +    /* Use unpatented hinting only. */
451.1375 +    FT_Bool               unpatented_hinting;
451.1376 +#endif
451.1377 +
451.1378 +    /***********************************************************************/
451.1379 +    /*                                                                     */
451.1380 +    /* Other tables or fields. This is used by derivative formats like     */
451.1381 +    /* OpenType.                                                           */
451.1382 +    /*                                                                     */
451.1383 +    /***********************************************************************/
451.1384 +
451.1385 +    FT_Generic            extra;
451.1386 +
451.1387 +    const char*           postscript_name;
451.1388 +
451.1389 +    /* since version 2.1.8, but was originally placed after */
451.1390 +    /* `glyph_locations_stub'                               */
451.1391 +    FT_ULong              glyf_len;
451.1392 +
451.1393 +    /* since version 2.1.8, but was originally placed before `extra' */
451.1394 +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
451.1395 +    FT_Bool               doblend;
451.1396 +    GX_Blend              blend;
451.1397 +#endif
451.1398 +
451.1399 +    /* since version 2.2 */
451.1400 +
451.1401 +    FT_Byte*              horz_metrics;
451.1402 +    FT_ULong              horz_metrics_size;
451.1403 +
451.1404 +    FT_Byte*              vert_metrics;
451.1405 +    FT_ULong              vert_metrics_size;
451.1406 +
451.1407 +    FT_ULong              num_locations; /* in broken TTF, gid > 0xFFFF */ 
451.1408 +    FT_Byte*              glyph_locations;
451.1409 +
451.1410 +    FT_Byte*              hdmx_table;
451.1411 +    FT_ULong              hdmx_table_size;
451.1412 +    FT_UInt               hdmx_record_count;
451.1413 +    FT_ULong              hdmx_record_size;
451.1414 +    FT_Byte*              hdmx_record_sizes;
451.1415 +
451.1416 +    FT_Byte*              sbit_table;
451.1417 +    FT_ULong              sbit_table_size;
451.1418 +    FT_UInt               sbit_num_strikes;
451.1419 +
451.1420 +    FT_Byte*              kern_table;
451.1421 +    FT_ULong              kern_table_size;
451.1422 +    FT_UInt               num_kern_tables;
451.1423 +    FT_UInt32             kern_avail_bits;
451.1424 +    FT_UInt32             kern_order_bits;
451.1425 +
451.1426 +#ifdef TT_CONFIG_OPTION_BDF
451.1427 +    TT_BDFRec             bdf;
451.1428 +#endif /* TT_CONFIG_OPTION_BDF */
451.1429 +
451.1430 +    /* since 2.3.0 */
451.1431 +    FT_ULong              horz_metrics_offset;
451.1432 +    FT_ULong              vert_metrics_offset;
451.1433 +
451.1434 +  } TT_FaceRec;
451.1435 +
451.1436 +
451.1437 +  /*************************************************************************/
451.1438 +  /*                                                                       */
451.1439 +  /*  <Struct>                                                             */
451.1440 +  /*     TT_GlyphZoneRec                                                   */
451.1441 +  /*                                                                       */
451.1442 +  /*  <Description>                                                        */
451.1443 +  /*     A glyph zone is used to load, scale and hint glyph outline        */
451.1444 +  /*     coordinates.                                                      */
451.1445 +  /*                                                                       */
451.1446 +  /*  <Fields>                                                             */
451.1447 +  /*     memory       :: A handle to the memory manager.                   */
451.1448 +  /*                                                                       */
451.1449 +  /*     max_points   :: The maximal size in points of the zone.           */
451.1450 +  /*                                                                       */
451.1451 +  /*     max_contours :: Max size in links contours of the zone.           */
451.1452 +  /*                                                                       */
451.1453 +  /*     n_points     :: The current number of points in the zone.         */
451.1454 +  /*                                                                       */
451.1455 +  /*     n_contours   :: The current number of contours in the zone.       */
451.1456 +  /*                                                                       */
451.1457 +  /*     org          :: The original glyph coordinates (font              */
451.1458 +  /*                     units/scaled).                                    */
451.1459 +  /*                                                                       */
451.1460 +  /*     cur          :: The current glyph coordinates (scaled/hinted).    */
451.1461 +  /*                                                                       */
451.1462 +  /*     tags         :: The point control tags.                           */
451.1463 +  /*                                                                       */
451.1464 +  /*     contours     :: The contours end points.                          */
451.1465 +  /*                                                                       */
451.1466 +  /*     first_point  :: Offset of the current subglyph's first point.     */
451.1467 +  /*                                                                       */
451.1468 +  typedef struct  TT_GlyphZoneRec_
451.1469 +  {
451.1470 +    FT_Memory   memory;
451.1471 +    FT_UShort   max_points;
451.1472 +    FT_UShort   max_contours;
451.1473 +    FT_UShort   n_points;    /* number of points in zone    */
451.1474 +    FT_Short    n_contours;  /* number of contours          */
451.1475 +
451.1476 +    FT_Vector*  org;         /* original point coordinates  */
451.1477 +    FT_Vector*  cur;         /* current point coordinates   */
451.1478 +    FT_Vector*  orus;        /* original (unscaled) point coordinates */
451.1479 +
451.1480 +    FT_Byte*    tags;        /* current touch flags         */
451.1481 +    FT_UShort*  contours;    /* contour end points          */
451.1482 +
451.1483 +    FT_UShort   first_point; /* offset of first (#0) point  */
451.1484 +
451.1485 +  } TT_GlyphZoneRec, *TT_GlyphZone;
451.1486 +
451.1487 +
451.1488 +  /* handle to execution context */
451.1489 +  typedef struct TT_ExecContextRec_*  TT_ExecContext;
451.1490 +
451.1491 +  /* glyph loader structure */
451.1492 +  typedef struct  TT_LoaderRec_
451.1493 +  {
451.1494 +    FT_Face          face;
451.1495 +    FT_Size          size;
451.1496 +    FT_GlyphSlot     glyph;
451.1497 +    FT_GlyphLoader   gloader;
451.1498 +
451.1499 +    FT_ULong         load_flags;
451.1500 +    FT_UInt          glyph_index;
451.1501 +
451.1502 +    FT_Stream        stream;
451.1503 +    FT_Int           byte_len;
451.1504 +
451.1505 +    FT_Short         n_contours;
451.1506 +    FT_BBox          bbox;
451.1507 +    FT_Int           left_bearing;
451.1508 +    FT_Int           advance;
451.1509 +    FT_Int           linear;
451.1510 +    FT_Bool          linear_def;
451.1511 +    FT_Bool          preserve_pps;
451.1512 +    FT_Vector        pp1;
451.1513 +    FT_Vector        pp2;
451.1514 +
451.1515 +    FT_ULong         glyf_offset;
451.1516 +
451.1517 +    /* the zone where we load our glyphs */
451.1518 +    TT_GlyphZoneRec  base;
451.1519 +    TT_GlyphZoneRec  zone;
451.1520 +
451.1521 +    TT_ExecContext   exec;
451.1522 +    FT_Byte*         instructions;
451.1523 +    FT_ULong         ins_pos;
451.1524 +
451.1525 +    /* for possible extensibility in other formats */
451.1526 +    void*            other;
451.1527 +
451.1528 +    /* since version 2.1.8 */
451.1529 +    FT_Int           top_bearing;
451.1530 +    FT_Int           vadvance;
451.1531 +    FT_Vector        pp3;
451.1532 +    FT_Vector        pp4;
451.1533 +
451.1534 +    /* since version 2.2.1 */
451.1535 +    FT_Byte*         cursor;
451.1536 +    FT_Byte*         limit;
451.1537 +
451.1538 +  } TT_LoaderRec;
451.1539 +
451.1540 +
451.1541 +FT_END_HEADER
451.1542 +
451.1543 +#endif /* __TTTYPES_H__ */
451.1544 +
451.1545 +
451.1546 +/* END */
   452.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   452.2 +++ b/libs/ft2static/freetype/t1tables.h	Sat Feb 01 19:58:19 2014 +0200
   452.3 @@ -0,0 +1,504 @@
   452.4 +/***************************************************************************/
   452.5 +/*                                                                         */
   452.6 +/*  t1tables.h                                                             */
   452.7 +/*                                                                         */
   452.8 +/*    Basic Type 1/Type 2 tables definitions and interface (specification  */
   452.9 +/*    only).                                                               */
  452.10 +/*                                                                         */
  452.11 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */
  452.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  452.13 +/*                                                                         */
  452.14 +/*  This file is part of the FreeType project, and may only be used,       */
  452.15 +/*  modified, and distributed under the terms of the FreeType project      */
  452.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  452.17 +/*  this file you indicate that you have read the license and              */
  452.18 +/*  understand and accept it fully.                                        */
  452.19 +/*                                                                         */
  452.20 +/***************************************************************************/
  452.21 +
  452.22 +
  452.23 +#ifndef __T1TABLES_H__
  452.24 +#define __T1TABLES_H__
  452.25 +
  452.26 +
  452.27 +#include <ft2build.h>
  452.28 +#include FT_FREETYPE_H
  452.29 +
  452.30 +#ifdef FREETYPE_H
  452.31 +#error "freetype.h of FreeType 1 has been loaded!"
  452.32 +#error "Please fix the directory search order for header files"
  452.33 +#error "so that freetype.h of FreeType 2 is found first."
  452.34 +#endif
  452.35 +
  452.36 +
  452.37 +FT_BEGIN_HEADER
  452.38 +
  452.39 +
  452.40 +  /*************************************************************************/
  452.41 +  /*                                                                       */
  452.42 +  /* <Section>                                                             */
  452.43 +  /*    type1_tables                                                       */
  452.44 +  /*                                                                       */
  452.45 +  /* <Title>                                                               */
  452.46 +  /*    Type 1 Tables                                                      */
  452.47 +  /*                                                                       */
  452.48 +  /* <Abstract>                                                            */
  452.49 +  /*    Type~1 (PostScript) specific font tables.                          */
  452.50 +  /*                                                                       */
  452.51 +  /* <Description>                                                         */
  452.52 +  /*    This section contains the definition of Type 1-specific tables,    */
  452.53 +  /*    including structures related to other PostScript font formats.     */
  452.54 +  /*                                                                       */
  452.55 +  /*************************************************************************/
  452.56 +
  452.57 +
  452.58 +  /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */
  452.59 +  /* structures in order to support Multiple Master fonts.               */
  452.60 +
  452.61 +
  452.62 +  /*************************************************************************/
  452.63 +  /*                                                                       */
  452.64 +  /* <Struct>                                                              */
  452.65 +  /*    PS_FontInfoRec                                                     */
  452.66 +  /*                                                                       */
  452.67 +  /* <Description>                                                         */
  452.68 +  /*    A structure used to model a Type~1 or Type~2 FontInfo dictionary.  */
  452.69 +  /*    Note that for Multiple Master fonts, each instance has its own     */
  452.70 +  /*    FontInfo dictionary.                                               */
  452.71 +  /*                                                                       */
  452.72 +  typedef struct  PS_FontInfoRec_
  452.73 +  {
  452.74 +    FT_String*  version;
  452.75 +    FT_String*  notice;
  452.76 +    FT_String*  full_name;
  452.77 +    FT_String*  family_name;
  452.78 +    FT_String*  weight;
  452.79 +    FT_Long     italic_angle;
  452.80 +    FT_Bool     is_fixed_pitch;
  452.81 +    FT_Short    underline_position;
  452.82 +    FT_UShort   underline_thickness;
  452.83 +
  452.84 +  } PS_FontInfoRec;
  452.85 +
  452.86 +
  452.87 +  /*************************************************************************/
  452.88 +  /*                                                                       */
  452.89 +  /* <Struct>                                                              */
  452.90 +  /*    PS_FontInfo                                                        */
  452.91 +  /*                                                                       */
  452.92 +  /* <Description>                                                         */
  452.93 +  /*    A handle to a @PS_FontInfoRec structure.                           */
  452.94 +  /*                                                                       */
  452.95 +  typedef struct PS_FontInfoRec_*  PS_FontInfo;
  452.96 +
  452.97 +
  452.98 +  /*************************************************************************/
  452.99 +  /*                                                                       */
 452.100 +  /* <Struct>                                                              */
 452.101 +  /*    T1_FontInfo                                                        */
 452.102 +  /*                                                                       */
 452.103 +  /* <Description>                                                         */
 452.104 +  /*    This type is equivalent to @PS_FontInfoRec.  It is deprecated but  */
 452.105 +  /*    kept to maintain source compatibility between various versions of  */
 452.106 +  /*    FreeType.                                                          */
 452.107 +  /*                                                                       */
 452.108 +  typedef PS_FontInfoRec  T1_FontInfo;
 452.109 +
 452.110 +
 452.111 +  /*************************************************************************/
 452.112 +  /*                                                                       */
 452.113 +  /* <Struct>                                                              */
 452.114 +  /*    PS_PrivateRec                                                      */
 452.115 +  /*                                                                       */
 452.116 +  /* <Description>                                                         */
 452.117 +  /*    A structure used to model a Type~1 or Type~2 private dictionary.   */
 452.118 +  /*    Note that for Multiple Master fonts, each instance has its own     */
 452.119 +  /*    Private dictionary.                                                */
 452.120 +  /*                                                                       */
 452.121 +  typedef struct  PS_PrivateRec_
 452.122 +  {
 452.123 +    FT_Int     unique_id;
 452.124 +    FT_Int     lenIV;
 452.125 +
 452.126 +    FT_Byte    num_blue_values;
 452.127 +    FT_Byte    num_other_blues;
 452.128 +    FT_Byte    num_family_blues;
 452.129 +    FT_Byte    num_family_other_blues;
 452.130 +
 452.131 +    FT_Short   blue_values[14];
 452.132 +    FT_Short   other_blues[10];
 452.133 +
 452.134 +    FT_Short   family_blues      [14];
 452.135 +    FT_Short   family_other_blues[10];
 452.136 +
 452.137 +    FT_Fixed   blue_scale;
 452.138 +    FT_Int     blue_shift;
 452.139 +    FT_Int     blue_fuzz;
 452.140 +
 452.141 +    FT_UShort  standard_width[1];
 452.142 +    FT_UShort  standard_height[1];
 452.143 +
 452.144 +    FT_Byte    num_snap_widths;
 452.145 +    FT_Byte    num_snap_heights;
 452.146 +    FT_Bool    force_bold;
 452.147 +    FT_Bool    round_stem_up;
 452.148 +
 452.149 +    FT_Short   snap_widths [13];  /* including std width  */
 452.150 +    FT_Short   snap_heights[13];  /* including std height */
 452.151 +
 452.152 +    FT_Fixed   expansion_factor;
 452.153 +
 452.154 +    FT_Long    language_group;
 452.155 +    FT_Long    password;
 452.156 +
 452.157 +    FT_Short   min_feature[2];
 452.158 +
 452.159 +  } PS_PrivateRec;
 452.160 +
 452.161 +
 452.162 +  /*************************************************************************/
 452.163 +  /*                                                                       */
 452.164 +  /* <Struct>                                                              */
 452.165 +  /*    PS_Private                                                         */
 452.166 +  /*                                                                       */
 452.167 +  /* <Description>                                                         */
 452.168 +  /*    A handle to a @PS_PrivateRec structure.                            */
 452.169 +  /*                                                                       */
 452.170 +  typedef struct PS_PrivateRec_*  PS_Private;
 452.171 +
 452.172 +
 452.173 +  /*************************************************************************/
 452.174 +  /*                                                                       */
 452.175 +  /* <Struct>                                                              */
 452.176 +  /*    T1_Private                                                         */
 452.177 +  /*                                                                       */
 452.178 +  /* <Description>                                                         */
 452.179 +  /*   This type is equivalent to @PS_PrivateRec.  It is deprecated but    */
 452.180 +  /*   kept to maintain source compatibility between various versions of   */
 452.181 +  /*   FreeType.                                                           */
 452.182 +  /*                                                                       */
 452.183 +  typedef PS_PrivateRec  T1_Private;
 452.184 +
 452.185 +
 452.186 +  /*************************************************************************/
 452.187 +  /*                                                                       */
 452.188 +  /* <Enum>                                                                */
 452.189 +  /*    T1_Blend_Flags                                                     */
 452.190 +  /*                                                                       */
 452.191 +  /* <Description>                                                         */
 452.192 +  /*    A set of flags used to indicate which fields are present in a      */
 452.193 +  /*    given blend dictionary (font info or private).  Used to support    */
 452.194 +  /*    Multiple Masters fonts.                                            */
 452.195 +  /*                                                                       */
 452.196 +  typedef enum  T1_Blend_Flags_
 452.197 +  {
 452.198 +    /*# required fields in a FontInfo blend dictionary */
 452.199 +    T1_BLEND_UNDERLINE_POSITION = 0,
 452.200 +    T1_BLEND_UNDERLINE_THICKNESS,
 452.201 +    T1_BLEND_ITALIC_ANGLE,
 452.202 +
 452.203 +    /*# required fields in a Private blend dictionary */
 452.204 +    T1_BLEND_BLUE_VALUES,
 452.205 +    T1_BLEND_OTHER_BLUES,
 452.206 +    T1_BLEND_STANDARD_WIDTH,
 452.207 +    T1_BLEND_STANDARD_HEIGHT,
 452.208 +    T1_BLEND_STEM_SNAP_WIDTHS,
 452.209 +    T1_BLEND_STEM_SNAP_HEIGHTS,
 452.210 +    T1_BLEND_BLUE_SCALE,
 452.211 +    T1_BLEND_BLUE_SHIFT,
 452.212 +    T1_BLEND_FAMILY_BLUES,
 452.213 +    T1_BLEND_FAMILY_OTHER_BLUES,
 452.214 +    T1_BLEND_FORCE_BOLD,
 452.215 +
 452.216 +    /*# never remove */
 452.217 +    T1_BLEND_MAX
 452.218 +
 452.219 +  } T1_Blend_Flags;
 452.220 +
 452.221 +  /* */
 452.222 +
 452.223 +
 452.224 +  /*# backwards compatible definitions */
 452.225 +#define t1_blend_underline_position   T1_BLEND_UNDERLINE_POSITION
 452.226 +#define t1_blend_underline_thickness  T1_BLEND_UNDERLINE_THICKNESS
 452.227 +#define t1_blend_italic_angle         T1_BLEND_ITALIC_ANGLE
 452.228 +#define t1_blend_blue_values          T1_BLEND_BLUE_VALUES
 452.229 +#define t1_blend_other_blues          T1_BLEND_OTHER_BLUES
 452.230 +#define t1_blend_standard_widths      T1_BLEND_STANDARD_WIDTH
 452.231 +#define t1_blend_standard_height      T1_BLEND_STANDARD_HEIGHT
 452.232 +#define t1_blend_stem_snap_widths     T1_BLEND_STEM_SNAP_WIDTHS
 452.233 +#define t1_blend_stem_snap_heights    T1_BLEND_STEM_SNAP_HEIGHTS
 452.234 +#define t1_blend_blue_scale           T1_BLEND_BLUE_SCALE
 452.235 +#define t1_blend_blue_shift           T1_BLEND_BLUE_SHIFT
 452.236 +#define t1_blend_family_blues         T1_BLEND_FAMILY_BLUES
 452.237 +#define t1_blend_family_other_blues   T1_BLEND_FAMILY_OTHER_BLUES
 452.238 +#define t1_blend_force_bold           T1_BLEND_FORCE_BOLD
 452.239 +#define t1_blend_max                  T1_BLEND_MAX
 452.240 +
 452.241 +
 452.242 +  /* maximum number of Multiple Masters designs, as defined in the spec */
 452.243 +#define T1_MAX_MM_DESIGNS     16
 452.244 +
 452.245 +  /* maximum number of Multiple Masters axes, as defined in the spec */
 452.246 +#define T1_MAX_MM_AXIS        4
 452.247 +
 452.248 +  /* maximum number of elements in a design map */
 452.249 +#define T1_MAX_MM_MAP_POINTS  20
 452.250 +
 452.251 +
 452.252 +  /* this structure is used to store the BlendDesignMap entry for an axis */
 452.253 +  typedef struct  PS_DesignMap_
 452.254 +  {
 452.255 +    FT_Byte    num_points;
 452.256 +    FT_Long*   design_points;
 452.257 +    FT_Fixed*  blend_points;
 452.258 +
 452.259 +  } PS_DesignMapRec, *PS_DesignMap;
 452.260 +
 452.261 +  /* backwards-compatible definition */
 452.262 +  typedef PS_DesignMapRec  T1_DesignMap;
 452.263 +
 452.264 +
 452.265 +  typedef struct  PS_BlendRec_
 452.266 +  {
 452.267 +    FT_UInt          num_designs;
 452.268 +    FT_UInt          num_axis;
 452.269 +
 452.270 +    FT_String*       axis_names[T1_MAX_MM_AXIS];
 452.271 +    FT_Fixed*        design_pos[T1_MAX_MM_DESIGNS];
 452.272 +    PS_DesignMapRec  design_map[T1_MAX_MM_AXIS];
 452.273 +
 452.274 +    FT_Fixed*        weight_vector;
 452.275 +    FT_Fixed*        default_weight_vector;
 452.276 +
 452.277 +    PS_FontInfo      font_infos[T1_MAX_MM_DESIGNS + 1];
 452.278 +    PS_Private       privates  [T1_MAX_MM_DESIGNS + 1];
 452.279 +
 452.280 +    FT_ULong         blend_bitflags;
 452.281 +
 452.282 +    FT_BBox*         bboxes    [T1_MAX_MM_DESIGNS + 1];
 452.283 +
 452.284 +    /* since 2.3.0 */
 452.285 +
 452.286 +    /* undocumented, optional: the default design instance;   */
 452.287 +    /* corresponds to default_weight_vector --                */
 452.288 +    /* num_default_design_vector == 0 means it is not present */
 452.289 +    /* in the font and associated metrics files               */
 452.290 +    FT_UInt          default_design_vector[T1_MAX_MM_DESIGNS];
 452.291 +    FT_UInt          num_default_design_vector;
 452.292 +
 452.293 +  } PS_BlendRec, *PS_Blend;
 452.294 +
 452.295 +
 452.296 +  /* backwards-compatible definition */
 452.297 +  typedef PS_BlendRec  T1_Blend;
 452.298 +
 452.299 +
 452.300 +  /*************************************************************************/
 452.301 +  /*                                                                       */
 452.302 +  /* <Struct>                                                              */
 452.303 +  /*    CID_FaceDictRec                                                    */
 452.304 +  /*                                                                       */
 452.305 +  /* <Description>                                                         */
 452.306 +  /*    A structure used to represent data in a CID top-level dictionary.  */
 452.307 +  /*                                                                       */
 452.308 +  typedef struct  CID_FaceDictRec_
 452.309 +  {
 452.310 +    PS_PrivateRec  private_dict;
 452.311 +
 452.312 +    FT_UInt        len_buildchar;
 452.313 +    FT_Fixed       forcebold_threshold;
 452.314 +    FT_Pos         stroke_width;
 452.315 +    FT_Fixed       expansion_factor;
 452.316 +
 452.317 +    FT_Byte        paint_type;
 452.318 +    FT_Byte        font_type;
 452.319 +    FT_Matrix      font_matrix;
 452.320 +    FT_Vector      font_offset;
 452.321 +
 452.322 +    FT_UInt        num_subrs;
 452.323 +    FT_ULong       subrmap_offset;
 452.324 +    FT_Int         sd_bytes;
 452.325 +
 452.326 +  } CID_FaceDictRec;
 452.327 +
 452.328 +
 452.329 +  /*************************************************************************/
 452.330 +  /*                                                                       */
 452.331 +  /* <Struct>                                                              */
 452.332 +  /*    CID_FaceDict                                                       */
 452.333 +  /*                                                                       */
 452.334 +  /* <Description>                                                         */
 452.335 +  /*    A handle to a @CID_FaceDictRec structure.                          */
 452.336 +  /*                                                                       */
 452.337 +  typedef struct CID_FaceDictRec_*  CID_FaceDict;
 452.338 +
 452.339 +  /* */
 452.340 +
 452.341 +
 452.342 +  /* backwards-compatible definition */
 452.343 +  typedef CID_FaceDictRec  CID_FontDict;
 452.344 +
 452.345 +
 452.346 +  /*************************************************************************/
 452.347 +  /*                                                                       */
 452.348 +  /* <Struct>                                                              */
 452.349 +  /*    CID_FaceInfoRec                                                    */
 452.350 +  /*                                                                       */
 452.351 +  /* <Description>                                                         */
 452.352 +  /*    A structure used to represent CID Face information.                */
 452.353 +  /*                                                                       */
 452.354 +  typedef struct  CID_FaceInfoRec_
 452.355 +  {
 452.356 +    FT_String*      cid_font_name;
 452.357 +    FT_Fixed        cid_version;
 452.358 +    FT_Int          cid_font_type;
 452.359 +
 452.360 +    FT_String*      registry;
 452.361 +    FT_String*      ordering;
 452.362 +    FT_Int          supplement;
 452.363 +
 452.364 +    PS_FontInfoRec  font_info;
 452.365 +    FT_BBox         font_bbox;
 452.366 +    FT_ULong        uid_base;
 452.367 +
 452.368 +    FT_Int          num_xuid;
 452.369 +    FT_ULong        xuid[16];
 452.370 +
 452.371 +    FT_ULong        cidmap_offset;
 452.372 +    FT_Int          fd_bytes;
 452.373 +    FT_Int          gd_bytes;
 452.374 +    FT_ULong        cid_count;
 452.375 +
 452.376 +    FT_Int          num_dicts;
 452.377 +    CID_FaceDict    font_dicts;
 452.378 +
 452.379 +    FT_ULong        data_offset;
 452.380 +
 452.381 +  } CID_FaceInfoRec;
 452.382 +
 452.383 +
 452.384 +  /*************************************************************************/
 452.385 +  /*                                                                       */
 452.386 +  /* <Struct>                                                              */
 452.387 +  /*    CID_FaceInfo                                                       */
 452.388 +  /*                                                                       */
 452.389 +  /* <Description>                                                         */
 452.390 +  /*    A handle to a @CID_FaceInfoRec structure.                          */
 452.391 +  /*                                                                       */
 452.392 +  typedef struct CID_FaceInfoRec_*  CID_FaceInfo;
 452.393 +
 452.394 +
 452.395 +  /*************************************************************************/
 452.396 +  /*                                                                       */
 452.397 +  /* <Struct>                                                              */
 452.398 +  /*    CID_Info                                                           */
 452.399 +  /*                                                                       */
 452.400 +  /* <Description>                                                         */
 452.401 +  /*   This type is equivalent to @CID_FaceInfoRec.  It is deprecated but  */
 452.402 +  /*   kept to maintain source compatibility between various versions of   */
 452.403 +  /*   FreeType.                                                           */
 452.404 +  /*                                                                       */
 452.405 +  typedef CID_FaceInfoRec  CID_Info;
 452.406 +
 452.407 +
 452.408 +  /************************************************************************
 452.409 +   *
 452.410 +   * @function:
 452.411 +   *    FT_Has_PS_Glyph_Names
 452.412 +   *
 452.413 +   * @description:
 452.414 +   *    Return true if a given face provides reliable PostScript glyph
 452.415 +   *    names.  This is similar to using the @FT_HAS_GLYPH_NAMES macro,
 452.416 +   *    except that certain fonts (mostly TrueType) contain incorrect
 452.417 +   *    glyph name tables.
 452.418 +   *
 452.419 +   *    When this function returns true, the caller is sure that the glyph
 452.420 +   *    names returned by @FT_Get_Glyph_Name are reliable.
 452.421 +   *
 452.422 +   * @input:
 452.423 +   *    face ::
 452.424 +   *       face handle
 452.425 +   *
 452.426 +   * @return:
 452.427 +   *    Boolean.  True if glyph names are reliable.
 452.428 +   *
 452.429 +   */
 452.430 +  FT_EXPORT( FT_Int )
 452.431 +  FT_Has_PS_Glyph_Names( FT_Face  face );
 452.432 +
 452.433 +
 452.434 +  /************************************************************************
 452.435 +   *
 452.436 +   * @function:
 452.437 +   *    FT_Get_PS_Font_Info
 452.438 +   *
 452.439 +   * @description:
 452.440 +   *    Retrieve the @PS_FontInfoRec structure corresponding to a given
 452.441 +   *    PostScript font.
 452.442 +   *
 452.443 +   * @input:
 452.444 +   *    face ::
 452.445 +   *       PostScript face handle.
 452.446 +   *
 452.447 +   * @output:
 452.448 +   *    afont_info ::
 452.449 +   *       Output font info structure pointer.
 452.450 +   *
 452.451 +   * @return:
 452.452 +   *    FreeType error code.  0~means success.
 452.453 +   *
 452.454 +   * @note:
 452.455 +   *    The string pointers within the font info structure are owned by
 452.456 +   *    the face and don't need to be freed by the caller.
 452.457 +   *
 452.458 +   *    If the font's format is not PostScript-based, this function will
 452.459 +   *    return the `FT_Err_Invalid_Argument' error code.
 452.460 +   *
 452.461 +   */
 452.462 +  FT_EXPORT( FT_Error )
 452.463 +  FT_Get_PS_Font_Info( FT_Face      face,
 452.464 +                       PS_FontInfo  afont_info );
 452.465 +
 452.466 +
 452.467 +  /************************************************************************
 452.468 +   *
 452.469 +   * @function:
 452.470 +   *    FT_Get_PS_Font_Private
 452.471 +   *
 452.472 +   * @description:
 452.473 +   *    Retrieve the @PS_PrivateRec structure corresponding to a given
 452.474 +   *    PostScript font.
 452.475 +   *
 452.476 +   * @input:
 452.477 +   *    face ::
 452.478 +   *       PostScript face handle.
 452.479 +   *
 452.480 +   * @output:
 452.481 +   *    afont_private ::
 452.482 +   *       Output private dictionary structure pointer.
 452.483 +   *
 452.484 +   * @return:
 452.485 +   *    FreeType error code.  0~means success.
 452.486 +   *
 452.487 +   * @note:
 452.488 +   *    The string pointers within the @PS_PrivateRec structure are owned by
 452.489 +   *    the face and don't need to be freed by the caller.
 452.490 +   *
 452.491 +   *    If the font's format is not PostScript-based, this function returns
 452.492 +   *    the `FT_Err_Invalid_Argument' error code.
 452.493 +   *
 452.494 +   */
 452.495 +  FT_EXPORT( FT_Error )
 452.496 +  FT_Get_PS_Font_Private( FT_Face     face,
 452.497 +                          PS_Private  afont_private );
 452.498 +
 452.499 +  /* */
 452.500 +
 452.501 +
 452.502 +FT_END_HEADER
 452.503 +
 452.504 +#endif /* __T1TABLES_H__ */
 452.505 +
 452.506 +
 452.507 +/* END */
   453.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   453.2 +++ b/libs/ft2static/freetype/ttnameid.h	Sat Feb 01 19:58:19 2014 +0200
   453.3 @@ -0,0 +1,1247 @@
   453.4 +/***************************************************************************/
   453.5 +/*                                                                         */
   453.6 +/*  ttnameid.h                                                             */
   453.7 +/*                                                                         */
   453.8 +/*    TrueType name ID definitions (specification only).                   */
   453.9 +/*                                                                         */
  453.10 +/*  Copyright 1996-2002, 2003, 2004, 2006, 2007, 2008 by                   */
  453.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  453.12 +/*                                                                         */
  453.13 +/*  This file is part of the FreeType project, and may only be used,       */
  453.14 +/*  modified, and distributed under the terms of the FreeType project      */
  453.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  453.16 +/*  this file you indicate that you have read the license and              */
  453.17 +/*  understand and accept it fully.                                        */
  453.18 +/*                                                                         */
  453.19 +/***************************************************************************/
  453.20 +
  453.21 +
  453.22 +#ifndef __TTNAMEID_H__
  453.23 +#define __TTNAMEID_H__
  453.24 +
  453.25 +
  453.26 +#include <ft2build.h>
  453.27 +
  453.28 +
  453.29 +FT_BEGIN_HEADER
  453.30 +
  453.31 +
  453.32 +  /*************************************************************************/
  453.33 +  /*                                                                       */
  453.34 +  /* <Section>                                                             */
  453.35 +  /*    truetype_tables                                                    */
  453.36 +  /*                                                                       */
  453.37 +
  453.38 +
  453.39 +  /*************************************************************************/
  453.40 +  /*                                                                       */
  453.41 +  /* Possible values for the `platform' identifier code in the name        */
  453.42 +  /* records of the TTF `name' table.                                      */
  453.43 +  /*                                                                       */
  453.44 +  /*************************************************************************/
  453.45 +
  453.46 +
  453.47 +  /***********************************************************************
  453.48 +   *
  453.49 +   * @enum:
  453.50 +   *   TT_PLATFORM_XXX
  453.51 +   *
  453.52 +   * @description:
  453.53 +   *   A list of valid values for the `platform_id' identifier code in
  453.54 +   *   @FT_CharMapRec and @FT_SfntName structures.
  453.55 +   *
  453.56 +   * @values:
  453.57 +   *   TT_PLATFORM_APPLE_UNICODE ::
  453.58 +   *     Used by Apple to indicate a Unicode character map and/or name entry.
  453.59 +   *     See @TT_APPLE_ID_XXX for corresponding `encoding_id' values.  Note
  453.60 +   *     that name entries in this format are coded as big-endian UCS-2
  453.61 +   *     character codes _only_.
  453.62 +   *
  453.63 +   *   TT_PLATFORM_MACINTOSH ::
  453.64 +   *     Used by Apple to indicate a MacOS-specific charmap and/or name entry.
  453.65 +   *     See @TT_MAC_ID_XXX for corresponding `encoding_id' values.  Note that
  453.66 +   *     most TrueType fonts contain an Apple roman charmap to be usable on
  453.67 +   *     MacOS systems (even if they contain a Microsoft charmap as well).
  453.68 +   *
  453.69 +   *   TT_PLATFORM_ISO ::
  453.70 +   *     This value was used to specify ISO/IEC 10646 charmaps.  It is however
  453.71 +   *     now deprecated.  See @TT_ISO_ID_XXX for a list of corresponding
  453.72 +   *     `encoding_id' values.
  453.73 +   *
  453.74 +   *   TT_PLATFORM_MICROSOFT ::
  453.75 +   *     Used by Microsoft to indicate Windows-specific charmaps.  See
  453.76 +   *     @TT_MS_ID_XXX for a list of corresponding `encoding_id' values.
  453.77 +   *     Note that most fonts contain a Unicode charmap using
  453.78 +   *     (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS).
  453.79 +   *
  453.80 +   *   TT_PLATFORM_CUSTOM ::
  453.81 +   *     Used to indicate application-specific charmaps.
  453.82 +   *
  453.83 +   *   TT_PLATFORM_ADOBE ::
  453.84 +   *     This value isn't part of any font format specification, but is used
  453.85 +   *     by FreeType to report Adobe-specific charmaps in an @FT_CharMapRec
  453.86 +   *     structure.  See @TT_ADOBE_ID_XXX.
  453.87 +   */
  453.88 +
  453.89 +#define TT_PLATFORM_APPLE_UNICODE  0
  453.90 +#define TT_PLATFORM_MACINTOSH      1
  453.91 +#define TT_PLATFORM_ISO            2 /* deprecated */
  453.92 +#define TT_PLATFORM_MICROSOFT      3
  453.93 +#define TT_PLATFORM_CUSTOM         4
  453.94 +#define TT_PLATFORM_ADOBE          7 /* artificial */
  453.95 +
  453.96 +
  453.97 +  /***********************************************************************
  453.98 +   *
  453.99 +   * @enum:
 453.100 +   *   TT_APPLE_ID_XXX
 453.101 +   *
 453.102 +   * @description:
 453.103 +   *   A list of valid values for the `encoding_id' for
 453.104 +   *   @TT_PLATFORM_APPLE_UNICODE charmaps and name entries.
 453.105 +   *
 453.106 +   * @values:
 453.107 +   *   TT_APPLE_ID_DEFAULT ::
 453.108 +   *     Unicode version 1.0.
 453.109 +   *
 453.110 +   *   TT_APPLE_ID_UNICODE_1_1 ::
 453.111 +   *     Unicode 1.1; specifies Hangul characters starting at U+34xx.
 453.112 +   *
 453.113 +   *   TT_APPLE_ID_ISO_10646 ::
 453.114 +   *     Deprecated (identical to preceding).
 453.115 +   *
 453.116 +   *   TT_APPLE_ID_UNICODE_2_0 ::
 453.117 +   *     Unicode 2.0 and beyond (UTF-16 BMP only).
 453.118 +   *
 453.119 +   *   TT_APPLE_ID_UNICODE_32 ::
 453.120 +   *     Unicode 3.1 and beyond, using UTF-32.
 453.121 +   *
 453.122 +   *   TT_APPLE_ID_VARIANT_SELECTOR ::
 453.123 +   *     From Adobe, not Apple.  Not a normal cmap.  Specifies variations
 453.124 +   *     on a real cmap.
 453.125 +   */
 453.126 +
 453.127 +#define TT_APPLE_ID_DEFAULT           0 /* Unicode 1.0 */
 453.128 +#define TT_APPLE_ID_UNICODE_1_1       1 /* specify Hangul at U+34xx */
 453.129 +#define TT_APPLE_ID_ISO_10646         2 /* deprecated */
 453.130 +#define TT_APPLE_ID_UNICODE_2_0       3 /* or later */
 453.131 +#define TT_APPLE_ID_UNICODE_32        4 /* 2.0 or later, full repertoire */
 453.132 +#define TT_APPLE_ID_VARIANT_SELECTOR  5 /* variation selector data */
 453.133 +
 453.134 +
 453.135 +  /***********************************************************************
 453.136 +   *
 453.137 +   * @enum:
 453.138 +   *   TT_MAC_ID_XXX
 453.139 +   *
 453.140 +   * @description:
 453.141 +   *   A list of valid values for the `encoding_id' for
 453.142 +   *   @TT_PLATFORM_MACINTOSH charmaps and name entries.
 453.143 +   *
 453.144 +   * @values:
 453.145 +   *   TT_MAC_ID_ROMAN ::
 453.146 +   *   TT_MAC_ID_JAPANESE ::
 453.147 +   *   TT_MAC_ID_TRADITIONAL_CHINESE ::
 453.148 +   *   TT_MAC_ID_KOREAN ::
 453.149 +   *   TT_MAC_ID_ARABIC ::
 453.150 +   *   TT_MAC_ID_HEBREW ::
 453.151 +   *   TT_MAC_ID_GREEK ::
 453.152 +   *   TT_MAC_ID_RUSSIAN ::
 453.153 +   *   TT_MAC_ID_RSYMBOL ::
 453.154 +   *   TT_MAC_ID_DEVANAGARI ::
 453.155 +   *   TT_MAC_ID_GURMUKHI ::
 453.156 +   *   TT_MAC_ID_GUJARATI ::
 453.157 +   *   TT_MAC_ID_ORIYA ::
 453.158 +   *   TT_MAC_ID_BENGALI ::
 453.159 +   *   TT_MAC_ID_TAMIL ::
 453.160 +   *   TT_MAC_ID_TELUGU ::
 453.161 +   *   TT_MAC_ID_KANNADA ::
 453.162 +   *   TT_MAC_ID_MALAYALAM ::
 453.163 +   *   TT_MAC_ID_SINHALESE ::
 453.164 +   *   TT_MAC_ID_BURMESE ::
 453.165 +   *   TT_MAC_ID_KHMER ::
 453.166 +   *   TT_MAC_ID_THAI ::
 453.167 +   *   TT_MAC_ID_LAOTIAN ::
 453.168 +   *   TT_MAC_ID_GEORGIAN ::
 453.169 +   *   TT_MAC_ID_ARMENIAN ::
 453.170 +   *   TT_MAC_ID_MALDIVIAN ::
 453.171 +   *   TT_MAC_ID_SIMPLIFIED_CHINESE ::
 453.172 +   *   TT_MAC_ID_TIBETAN ::
 453.173 +   *   TT_MAC_ID_MONGOLIAN ::
 453.174 +   *   TT_MAC_ID_GEEZ ::
 453.175 +   *   TT_MAC_ID_SLAVIC ::
 453.176 +   *   TT_MAC_ID_VIETNAMESE ::
 453.177 +   *   TT_MAC_ID_SINDHI ::
 453.178 +   *   TT_MAC_ID_UNINTERP ::
 453.179 +   */
 453.180 +
 453.181 +#define TT_MAC_ID_ROMAN                 0
 453.182 +#define TT_MAC_ID_JAPANESE              1
 453.183 +#define TT_MAC_ID_TRADITIONAL_CHINESE   2
 453.184 +#define TT_MAC_ID_KOREAN                3
 453.185 +#define TT_MAC_ID_ARABIC                4
 453.186 +#define TT_MAC_ID_HEBREW                5
 453.187 +#define TT_MAC_ID_GREEK                 6
 453.188 +#define TT_MAC_ID_RUSSIAN               7
 453.189 +#define TT_MAC_ID_RSYMBOL               8
 453.190 +#define TT_MAC_ID_DEVANAGARI            9
 453.191 +#define TT_MAC_ID_GURMUKHI             10
 453.192 +#define TT_MAC_ID_GUJARATI             11
 453.193 +#define TT_MAC_ID_ORIYA                12
 453.194 +#define TT_MAC_ID_BENGALI              13
 453.195 +#define TT_MAC_ID_TAMIL                14
 453.196 +#define TT_MAC_ID_TELUGU               15
 453.197 +#define TT_MAC_ID_KANNADA              16
 453.198 +#define TT_MAC_ID_MALAYALAM            17
 453.199 +#define TT_MAC_ID_SINHALESE            18
 453.200 +#define TT_MAC_ID_BURMESE              19
 453.201 +#define TT_MAC_ID_KHMER                20
 453.202 +#define TT_MAC_ID_THAI                 21
 453.203 +#define TT_MAC_ID_LAOTIAN              22
 453.204 +#define TT_MAC_ID_GEORGIAN             23
 453.205 +#define TT_MAC_ID_ARMENIAN             24
 453.206 +#define TT_MAC_ID_MALDIVIAN            25
 453.207 +#define TT_MAC_ID_SIMPLIFIED_CHINESE   25
 453.208 +#define TT_MAC_ID_TIBETAN              26
 453.209 +#define TT_MAC_ID_MONGOLIAN            27
 453.210 +#define TT_MAC_ID_GEEZ                 28
 453.211 +#define TT_MAC_ID_SLAVIC               29
 453.212 +#define TT_MAC_ID_VIETNAMESE           30
 453.213 +#define TT_MAC_ID_SINDHI               31
 453.214 +#define TT_MAC_ID_UNINTERP             32
 453.215 +
 453.216 +
 453.217 +  /***********************************************************************
 453.218 +   *
 453.219 +   * @enum:
 453.220 +   *   TT_ISO_ID_XXX
 453.221 +   *
 453.222 +   * @description:
 453.223 +   *   A list of valid values for the `encoding_id' for
 453.224 +   *   @TT_PLATFORM_ISO charmaps and name entries.
 453.225 +   *
 453.226 +   *   Their use is now deprecated.
 453.227 +   *
 453.228 +   * @values:
 453.229 +   *   TT_ISO_ID_7BIT_ASCII ::
 453.230 +   *     ASCII.
 453.231 +   *   TT_ISO_ID_10646 ::
 453.232 +   *     ISO/10646.
 453.233 +   *   TT_ISO_ID_8859_1 ::
 453.234 +   *     Also known as Latin-1.
 453.235 +   */
 453.236 +
 453.237 +#define TT_ISO_ID_7BIT_ASCII  0
 453.238 +#define TT_ISO_ID_10646       1
 453.239 +#define TT_ISO_ID_8859_1      2
 453.240 +
 453.241 +
 453.242 +  /***********************************************************************
 453.243 +   *
 453.244 +   * @enum:
 453.245 +   *   TT_MS_ID_XXX
 453.246 +   *
 453.247 +   * @description:
 453.248 +   *   A list of valid values for the `encoding_id' for
 453.249 +   *   @TT_PLATFORM_MICROSOFT charmaps and name entries.
 453.250 +   *
 453.251 +   * @values:
 453.252 +   *   TT_MS_ID_SYMBOL_CS ::
 453.253 +   *     Corresponds to Microsoft symbol encoding. See
 453.254 +   *     @FT_ENCODING_MS_SYMBOL.
 453.255 +   *
 453.256 +   *   TT_MS_ID_UNICODE_CS ::
 453.257 +   *     Corresponds to a Microsoft WGL4 charmap, matching Unicode.  See
 453.258 +   *     @FT_ENCODING_UNICODE.
 453.259 +   *
 453.260 +   *   TT_MS_ID_SJIS ::
 453.261 +   *     Corresponds to SJIS Japanese encoding.  See @FT_ENCODING_SJIS.
 453.262 +   *
 453.263 +   *   TT_MS_ID_GB2312 ::
 453.264 +   *     Corresponds to Simplified Chinese as used in Mainland China.  See
 453.265 +   *     @FT_ENCODING_GB2312.
 453.266 +   *
 453.267 +   *   TT_MS_ID_BIG_5 ::
 453.268 +   *     Corresponds to Traditional Chinese as used in Taiwan and Hong Kong.
 453.269 +   *     See @FT_ENCODING_BIG5.
 453.270 +   *
 453.271 +   *   TT_MS_ID_WANSUNG ::
 453.272 +   *     Corresponds to Korean Wansung encoding.  See @FT_ENCODING_WANSUNG.
 453.273 +   *
 453.274 +   *   TT_MS_ID_JOHAB ::
 453.275 +   *     Corresponds to Johab encoding.  See @FT_ENCODING_JOHAB.
 453.276 +   *
 453.277 +   *   TT_MS_ID_UCS_4 ::
 453.278 +   *     Corresponds to UCS-4 or UTF-32 charmaps.  This has been added to
 453.279 +   *     the OpenType specification version 1.4 (mid-2001.)
 453.280 +   */
 453.281 +
 453.282 +#define TT_MS_ID_SYMBOL_CS    0
 453.283 +#define TT_MS_ID_UNICODE_CS   1
 453.284 +#define TT_MS_ID_SJIS         2
 453.285 +#define TT_MS_ID_GB2312       3
 453.286 +#define TT_MS_ID_BIG_5        4
 453.287 +#define TT_MS_ID_WANSUNG      5
 453.288 +#define TT_MS_ID_JOHAB        6
 453.289 +#define TT_MS_ID_UCS_4       10
 453.290 +
 453.291 +
 453.292 +  /***********************************************************************
 453.293 +   *
 453.294 +   * @enum:
 453.295 +   *   TT_ADOBE_ID_XXX
 453.296 +   *
 453.297 +   * @description:
 453.298 +   *   A list of valid values for the `encoding_id' for
 453.299 +   *   @TT_PLATFORM_ADOBE charmaps.  This is a FreeType-specific extension!
 453.300 +   *
 453.301 +   * @values:
 453.302 +   *   TT_ADOBE_ID_STANDARD ::
 453.303 +   *     Adobe standard encoding.
 453.304 +   *   TT_ADOBE_ID_EXPERT ::
 453.305 +   *     Adobe expert encoding.
 453.306 +   *   TT_ADOBE_ID_CUSTOM ::
 453.307 +   *     Adobe custom encoding.
 453.308 +   *   TT_ADOBE_ID_LATIN_1 ::
 453.309 +   *     Adobe Latin~1 encoding.
 453.310 +   */
 453.311 +
 453.312 +#define TT_ADOBE_ID_STANDARD  0
 453.313 +#define TT_ADOBE_ID_EXPERT    1
 453.314 +#define TT_ADOBE_ID_CUSTOM    2
 453.315 +#define TT_ADOBE_ID_LATIN_1   3
 453.316 +
 453.317 +
 453.318 +  /*************************************************************************/
 453.319 +  /*                                                                       */
 453.320 +  /* Possible values of the language identifier field in the name records  */
 453.321 +  /* of the TTF `name' table if the `platform' identifier code is          */
 453.322 +  /* TT_PLATFORM_MACINTOSH.                                                */
 453.323 +  /*                                                                       */
 453.324 +  /* The canonical source for the Apple assigned Language ID's is at       */
 453.325 +  /*                                                                       */
 453.326 +  /*   http://fonts.apple.com/TTRefMan/RM06/Chap6name.html                 */
 453.327 +  /*                                                                       */
 453.328 +#define TT_MAC_LANGID_ENGLISH                       0
 453.329 +#define TT_MAC_LANGID_FRENCH                        1
 453.330 +#define TT_MAC_LANGID_GERMAN                        2
 453.331 +#define TT_MAC_LANGID_ITALIAN                       3
 453.332 +#define TT_MAC_LANGID_DUTCH                         4
 453.333 +#define TT_MAC_LANGID_SWEDISH                       5
 453.334 +#define TT_MAC_LANGID_SPANISH                       6
 453.335 +#define TT_MAC_LANGID_DANISH                        7
 453.336 +#define TT_MAC_LANGID_PORTUGUESE                    8
 453.337 +#define TT_MAC_LANGID_NORWEGIAN                     9
 453.338 +#define TT_MAC_LANGID_HEBREW                       10
 453.339 +#define TT_MAC_LANGID_JAPANESE                     11
 453.340 +#define TT_MAC_LANGID_ARABIC                       12
 453.341 +#define TT_MAC_LANGID_FINNISH                      13
 453.342 +#define TT_MAC_LANGID_GREEK                        14
 453.343 +#define TT_MAC_LANGID_ICELANDIC                    15
 453.344 +#define TT_MAC_LANGID_MALTESE                      16
 453.345 +#define TT_MAC_LANGID_TURKISH                      17
 453.346 +#define TT_MAC_LANGID_CROATIAN                     18
 453.347 +#define TT_MAC_LANGID_CHINESE_TRADITIONAL          19
 453.348 +#define TT_MAC_LANGID_URDU                         20
 453.349 +#define TT_MAC_LANGID_HINDI                        21
 453.350 +#define TT_MAC_LANGID_THAI                         22
 453.351 +#define TT_MAC_LANGID_KOREAN                       23
 453.352 +#define TT_MAC_LANGID_LITHUANIAN                   24
 453.353 +#define TT_MAC_LANGID_POLISH                       25
 453.354 +#define TT_MAC_LANGID_HUNGARIAN                    26
 453.355 +#define TT_MAC_LANGID_ESTONIAN                     27
 453.356 +#define TT_MAC_LANGID_LETTISH                      28
 453.357 +#define TT_MAC_LANGID_SAAMISK                      29
 453.358 +#define TT_MAC_LANGID_FAEROESE                     30
 453.359 +#define TT_MAC_LANGID_FARSI                        31
 453.360 +#define TT_MAC_LANGID_RUSSIAN                      32
 453.361 +#define TT_MAC_LANGID_CHINESE_SIMPLIFIED           33
 453.362 +#define TT_MAC_LANGID_FLEMISH                      34
 453.363 +#define TT_MAC_LANGID_IRISH                        35
 453.364 +#define TT_MAC_LANGID_ALBANIAN                     36
 453.365 +#define TT_MAC_LANGID_ROMANIAN                     37
 453.366 +#define TT_MAC_LANGID_CZECH                        38
 453.367 +#define TT_MAC_LANGID_SLOVAK                       39
 453.368 +#define TT_MAC_LANGID_SLOVENIAN                    40
 453.369 +#define TT_MAC_LANGID_YIDDISH                      41
 453.370 +#define TT_MAC_LANGID_SERBIAN                      42
 453.371 +#define TT_MAC_LANGID_MACEDONIAN                   43
 453.372 +#define TT_MAC_LANGID_BULGARIAN                    44
 453.373 +#define TT_MAC_LANGID_UKRAINIAN                    45
 453.374 +#define TT_MAC_LANGID_BYELORUSSIAN                 46
 453.375 +#define TT_MAC_LANGID_UZBEK                        47
 453.376 +#define TT_MAC_LANGID_KAZAKH                       48
 453.377 +#define TT_MAC_LANGID_AZERBAIJANI                  49
 453.378 +#define TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT  49
 453.379 +#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT    50
 453.380 +#define TT_MAC_LANGID_ARMENIAN                     51
 453.381 +#define TT_MAC_LANGID_GEORGIAN                     52
 453.382 +#define TT_MAC_LANGID_MOLDAVIAN                    53
 453.383 +#define TT_MAC_LANGID_KIRGHIZ                      54
 453.384 +#define TT_MAC_LANGID_TAJIKI                       55
 453.385 +#define TT_MAC_LANGID_TURKMEN                      56
 453.386 +#define TT_MAC_LANGID_MONGOLIAN                    57
 453.387 +#define TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT   57
 453.388 +#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT    58
 453.389 +#define TT_MAC_LANGID_PASHTO                       59
 453.390 +#define TT_MAC_LANGID_KURDISH                      60
 453.391 +#define TT_MAC_LANGID_KASHMIRI                     61
 453.392 +#define TT_MAC_LANGID_SINDHI                       62
 453.393 +#define TT_MAC_LANGID_TIBETAN                      63
 453.394 +#define TT_MAC_LANGID_NEPALI                       64
 453.395 +#define TT_MAC_LANGID_SANSKRIT                     65
 453.396 +#define TT_MAC_LANGID_MARATHI                      66
 453.397 +#define TT_MAC_LANGID_BENGALI                      67
 453.398 +#define TT_MAC_LANGID_ASSAMESE                     68
 453.399 +#define TT_MAC_LANGID_GUJARATI                     69
 453.400 +#define TT_MAC_LANGID_PUNJABI                      70
 453.401 +#define TT_MAC_LANGID_ORIYA                        71
 453.402 +#define TT_MAC_LANGID_MALAYALAM                    72
 453.403 +#define TT_MAC_LANGID_KANNADA                      73
 453.404 +#define TT_MAC_LANGID_TAMIL                        74
 453.405 +#define TT_MAC_LANGID_TELUGU                       75
 453.406 +#define TT_MAC_LANGID_SINHALESE                    76
 453.407 +#define TT_MAC_LANGID_BURMESE                      77
 453.408 +#define TT_MAC_LANGID_KHMER                        78
 453.409 +#define TT_MAC_LANGID_LAO                          79
 453.410 +#define TT_MAC_LANGID_VIETNAMESE                   80
 453.411 +#define TT_MAC_LANGID_INDONESIAN                   81
 453.412 +#define TT_MAC_LANGID_TAGALOG                      82
 453.413 +#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT           83
 453.414 +#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT          84
 453.415 +#define TT_MAC_LANGID_AMHARIC                      85
 453.416 +#define TT_MAC_LANGID_TIGRINYA                     86
 453.417 +#define TT_MAC_LANGID_GALLA                        87
 453.418 +#define TT_MAC_LANGID_SOMALI                       88
 453.419 +#define TT_MAC_LANGID_SWAHILI                      89
 453.420 +#define TT_MAC_LANGID_RUANDA                       90
 453.421 +#define TT_MAC_LANGID_RUNDI                        91
 453.422 +#define TT_MAC_LANGID_CHEWA                        92
 453.423 +#define TT_MAC_LANGID_MALAGASY                     93
 453.424 +#define TT_MAC_LANGID_ESPERANTO                    94
 453.425 +#define TT_MAC_LANGID_WELSH                       128
 453.426 +#define TT_MAC_LANGID_BASQUE                      129
 453.427 +#define TT_MAC_LANGID_CATALAN                     130
 453.428 +#define TT_MAC_LANGID_LATIN                       131
 453.429 +#define TT_MAC_LANGID_QUECHUA                     132
 453.430 +#define TT_MAC_LANGID_GUARANI                     133
 453.431 +#define TT_MAC_LANGID_AYMARA                      134
 453.432 +#define TT_MAC_LANGID_TATAR                       135
 453.433 +#define TT_MAC_LANGID_UIGHUR                      136
 453.434 +#define TT_MAC_LANGID_DZONGKHA                    137
 453.435 +#define TT_MAC_LANGID_JAVANESE                    138
 453.436 +#define TT_MAC_LANGID_SUNDANESE                   139
 453.437 +
 453.438 +
 453.439 +#if 0  /* these seem to be errors that have been dropped */
 453.440 +
 453.441 +#define TT_MAC_LANGID_SCOTTISH_GAELIC             140
 453.442 +#define TT_MAC_LANGID_IRISH_GAELIC                141
 453.443 +
 453.444 +#endif
 453.445 +
 453.446 +
 453.447 +  /* The following codes are new as of 2000-03-10 */
 453.448 +#define TT_MAC_LANGID_GALICIAN                    140
 453.449 +#define TT_MAC_LANGID_AFRIKAANS                   141
 453.450 +#define TT_MAC_LANGID_BRETON                      142
 453.451 +#define TT_MAC_LANGID_INUKTITUT                   143
 453.452 +#define TT_MAC_LANGID_SCOTTISH_GAELIC             144
 453.453 +#define TT_MAC_LANGID_MANX_GAELIC                 145
 453.454 +#define TT_MAC_LANGID_IRISH_GAELIC                146
 453.455 +#define TT_MAC_LANGID_TONGAN                      147
 453.456 +#define TT_MAC_LANGID_GREEK_POLYTONIC             148
 453.457 +#define TT_MAC_LANGID_GREELANDIC                  149
 453.458 +#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT    150
 453.459 +
 453.460 +
 453.461 +  /*************************************************************************/
 453.462 +  /*                                                                       */
 453.463 +  /* Possible values of the language identifier field in the name records  */
 453.464 +  /* of the TTF `name' table if the `platform' identifier code is          */
 453.465 +  /* TT_PLATFORM_MICROSOFT.                                                */
 453.466 +  /*                                                                       */
 453.467 +  /* The canonical source for the MS assigned LCID's (seems to) be at      */
 453.468 +  /*                                                                       */
 453.469 +  /*   http://www.microsoft.com/globaldev/reference/lcid-all.mspx          */
 453.470 +  /*                                                                       */
 453.471 +  /* It used to be at various places, among them                           */
 453.472 +  /*                                                                       */
 453.473 +  /*   http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt              */
 453.474 +  /*   http://www.microsoft.com/globaldev/reference/loclanghome.asp        */
 453.475 +  /*   http://support.microsoft.com/support/kb/articles/Q224/8/04.ASP      */
 453.476 +  /*   http://msdn.microsoft.com/library/en-us/passport25/                 */
 453.477 +  /*           NET_Passport_VBScript_Documentation/Single_Sign_In/         */
 453.478 +  /*           Advanced_Single_Sign_In/Localization_and_LCIDs.asp          */
 453.479 +  /*                                                                       */
 453.480 +  /* Hopefully, it seems now that the Globaldev site prevails...           */
 453.481 +  /*                                   (updated by Antoine, 2004-02-17)    */
 453.482 +
 453.483 +#define TT_MS_LANGID_ARABIC_GENERAL                    0x0001
 453.484 +#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA               0x0401
 453.485 +#define TT_MS_LANGID_ARABIC_IRAQ                       0x0801
 453.486 +#define TT_MS_LANGID_ARABIC_EGYPT                      0x0c01
 453.487 +#define TT_MS_LANGID_ARABIC_LIBYA                      0x1001
 453.488 +#define TT_MS_LANGID_ARABIC_ALGERIA                    0x1401
 453.489 +#define TT_MS_LANGID_ARABIC_MOROCCO                    0x1801
 453.490 +#define TT_MS_LANGID_ARABIC_TUNISIA                    0x1c01
 453.491 +#define TT_MS_LANGID_ARABIC_OMAN                       0x2001
 453.492 +#define TT_MS_LANGID_ARABIC_YEMEN                      0x2401
 453.493 +#define TT_MS_LANGID_ARABIC_SYRIA                      0x2801
 453.494 +#define TT_MS_LANGID_ARABIC_JORDAN                     0x2c01
 453.495 +#define TT_MS_LANGID_ARABIC_LEBANON                    0x3001
 453.496 +#define TT_MS_LANGID_ARABIC_KUWAIT                     0x3401
 453.497 +#define TT_MS_LANGID_ARABIC_UAE                        0x3801
 453.498 +#define TT_MS_LANGID_ARABIC_BAHRAIN                    0x3c01
 453.499 +#define TT_MS_LANGID_ARABIC_QATAR                      0x4001
 453.500 +#define TT_MS_LANGID_BULGARIAN_BULGARIA                0x0402
 453.501 +#define TT_MS_LANGID_CATALAN_SPAIN                     0x0403
 453.502 +#define TT_MS_LANGID_CHINESE_GENERAL                   0x0004
 453.503 +#define TT_MS_LANGID_CHINESE_TAIWAN                    0x0404
 453.504 +#define TT_MS_LANGID_CHINESE_PRC                       0x0804
 453.505 +#define TT_MS_LANGID_CHINESE_HONG_KONG                 0x0c04
 453.506 +#define TT_MS_LANGID_CHINESE_SINGAPORE                 0x1004
 453.507 +
 453.508 +#if 1  /* this looks like the correct value */
 453.509 +#define TT_MS_LANGID_CHINESE_MACAU                     0x1404
 453.510 +#else  /* but beware, Microsoft may change its mind...
 453.511 +          the most recent Word reference has the following: */
 453.512 +#define TT_MS_LANGID_CHINESE_MACAU  TT_MS_LANGID_CHINESE_HONG_KONG
 453.513 +#endif
 453.514 +
 453.515 +#if 0  /* used only with .NET `cultures'; commented out */
 453.516 +#define TT_MS_LANGID_CHINESE_TRADITIONAL               0x7C04
 453.517 +#endif
 453.518 +
 453.519 +#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC              0x0405
 453.520 +#define TT_MS_LANGID_DANISH_DENMARK                    0x0406
 453.521 +#define TT_MS_LANGID_GERMAN_GERMANY                    0x0407
 453.522 +#define TT_MS_LANGID_GERMAN_SWITZERLAND                0x0807
 453.523 +#define TT_MS_LANGID_GERMAN_AUSTRIA                    0x0c07
 453.524 +#define TT_MS_LANGID_GERMAN_LUXEMBOURG                 0x1007
 453.525 +#define TT_MS_LANGID_GERMAN_LIECHTENSTEI               0x1407
 453.526 +#define TT_MS_LANGID_GREEK_GREECE                      0x0408
 453.527 +
 453.528 +  /* don't ask what this one means... It is commented out currently. */
 453.529 +#if 0
 453.530 +#define TT_MS_LANGID_GREEK_GREECE2                     0x2008
 453.531 +#endif
 453.532 +
 453.533 +#define TT_MS_LANGID_ENGLISH_GENERAL                   0x0009
 453.534 +#define TT_MS_LANGID_ENGLISH_UNITED_STATES             0x0409
 453.535 +#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM            0x0809
 453.536 +#define TT_MS_LANGID_ENGLISH_AUSTRALIA                 0x0c09
 453.537 +#define TT_MS_LANGID_ENGLISH_CANADA                    0x1009
 453.538 +#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND               0x1409
 453.539 +#define TT_MS_LANGID_ENGLISH_IRELAND                   0x1809
 453.540 +#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA              0x1c09
 453.541 +#define TT_MS_LANGID_ENGLISH_JAMAICA                   0x2009
 453.542 +#define TT_MS_LANGID_ENGLISH_CARIBBEAN                 0x2409
 453.543 +#define TT_MS_LANGID_ENGLISH_BELIZE                    0x2809
 453.544 +#define TT_MS_LANGID_ENGLISH_TRINIDAD                  0x2c09
 453.545 +#define TT_MS_LANGID_ENGLISH_ZIMBABWE                  0x3009
 453.546 +#define TT_MS_LANGID_ENGLISH_PHILIPPINES               0x3409
 453.547 +#define TT_MS_LANGID_ENGLISH_INDONESIA                 0x3809
 453.548 +#define TT_MS_LANGID_ENGLISH_HONG_KONG                 0x3c09
 453.549 +#define TT_MS_LANGID_ENGLISH_INDIA                     0x4009
 453.550 +#define TT_MS_LANGID_ENGLISH_MALAYSIA                  0x4409
 453.551 +#define TT_MS_LANGID_ENGLISH_SINGAPORE                 0x4809
 453.552 +#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT    0x040a
 453.553 +#define TT_MS_LANGID_SPANISH_MEXICO                    0x080a
 453.554 +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT  0x0c0a
 453.555 +#define TT_MS_LANGID_SPANISH_GUATEMALA                 0x100a
 453.556 +#define TT_MS_LANGID_SPANISH_COSTA_RICA                0x140a
 453.557 +#define TT_MS_LANGID_SPANISH_PANAMA                    0x180a
 453.558 +#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC        0x1c0a
 453.559 +#define TT_MS_LANGID_SPANISH_VENEZUELA                 0x200a
 453.560 +#define TT_MS_LANGID_SPANISH_COLOMBIA                  0x240a
 453.561 +#define TT_MS_LANGID_SPANISH_PERU                      0x280a
 453.562 +#define TT_MS_LANGID_SPANISH_ARGENTINA                 0x2c0a
 453.563 +#define TT_MS_LANGID_SPANISH_ECUADOR                   0x300a
 453.564 +#define TT_MS_LANGID_SPANISH_CHILE                     0x340a
 453.565 +#define TT_MS_LANGID_SPANISH_URUGUAY                   0x380a
 453.566 +#define TT_MS_LANGID_SPANISH_PARAGUAY                  0x3c0a
 453.567 +#define TT_MS_LANGID_SPANISH_BOLIVIA                   0x400a
 453.568 +#define TT_MS_LANGID_SPANISH_EL_SALVADOR               0x440a
 453.569 +#define TT_MS_LANGID_SPANISH_HONDURAS                  0x480a
 453.570 +#define TT_MS_LANGID_SPANISH_NICARAGUA                 0x4c0a
 453.571 +#define TT_MS_LANGID_SPANISH_PUERTO_RICO               0x500a
 453.572 +#define TT_MS_LANGID_SPANISH_UNITED_STATES             0x540a
 453.573 +  /* The following ID blatantly violate MS specs by using a */
 453.574 +  /* sublanguage > 0x1F.                                    */
 453.575 +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA             0xE40aU
 453.576 +#define TT_MS_LANGID_FINNISH_FINLAND                   0x040b
 453.577 +#define TT_MS_LANGID_FRENCH_FRANCE                     0x040c
 453.578 +#define TT_MS_LANGID_FRENCH_BELGIUM                    0x080c
 453.579 +#define TT_MS_LANGID_FRENCH_CANADA                     0x0c0c
 453.580 +#define TT_MS_LANGID_FRENCH_SWITZERLAND                0x100c
 453.581 +#define TT_MS_LANGID_FRENCH_LUXEMBOURG                 0x140c
 453.582 +#define TT_MS_LANGID_FRENCH_MONACO                     0x180c
 453.583 +#define TT_MS_LANGID_FRENCH_WEST_INDIES                0x1c0c
 453.584 +#define TT_MS_LANGID_FRENCH_REUNION                    0x200c
 453.585 +#define TT_MS_LANGID_FRENCH_CONGO                      0x240c
 453.586 +  /* which was formerly: */
 453.587 +#define TT_MS_LANGID_FRENCH_ZAIRE  TT_MS_LANGID_FRENCH_CONGO
 453.588 +#define TT_MS_LANGID_FRENCH_SENEGAL                    0x280c
 453.589 +#define TT_MS_LANGID_FRENCH_CAMEROON                   0x2c0c
 453.590 +#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE              0x300c
 453.591 +#define TT_MS_LANGID_FRENCH_MALI                       0x340c
 453.592 +#define TT_MS_LANGID_FRENCH_MOROCCO                    0x380c
 453.593 +#define TT_MS_LANGID_FRENCH_HAITI                      0x3c0c
 453.594 +  /* and another violation of the spec (see 0xE40aU) */
 453.595 +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA               0xE40cU
 453.596 +#define TT_MS_LANGID_HEBREW_ISRAEL                     0x040d
 453.597 +#define TT_MS_LANGID_HUNGARIAN_HUNGARY                 0x040e
 453.598 +#define TT_MS_LANGID_ICELANDIC_ICELAND                 0x040f
 453.599 +#define TT_MS_LANGID_ITALIAN_ITALY                     0x0410
 453.600 +#define TT_MS_LANGID_ITALIAN_SWITZERLAND               0x0810
 453.601 +#define TT_MS_LANGID_JAPANESE_JAPAN                    0x0411
 453.602 +#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA     0x0412
 453.603 +#define TT_MS_LANGID_KOREAN_JOHAB_KOREA                0x0812
 453.604 +#define TT_MS_LANGID_DUTCH_NETHERLANDS                 0x0413
 453.605 +#define TT_MS_LANGID_DUTCH_BELGIUM                     0x0813
 453.606 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL           0x0414
 453.607 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK          0x0814
 453.608 +#define TT_MS_LANGID_POLISH_POLAND                     0x0415
 453.609 +#define TT_MS_LANGID_PORTUGUESE_BRAZIL                 0x0416
 453.610 +#define TT_MS_LANGID_PORTUGUESE_PORTUGAL               0x0816
 453.611 +#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND        0x0417
 453.612 +#define TT_MS_LANGID_ROMANIAN_ROMANIA                  0x0418
 453.613 +#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA                0x0818
 453.614 +#define TT_MS_LANGID_RUSSIAN_RUSSIA                    0x0419
 453.615 +#define TT_MS_LANGID_RUSSIAN_MOLDAVIA                  0x0819
 453.616 +#define TT_MS_LANGID_CROATIAN_CROATIA                  0x041a
 453.617 +#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN              0x081a
 453.618 +#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC           0x0c1a
 453.619 +
 453.620 +#if 0  /* this used to be this value, but it looks like we were wrong */
 453.621 +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA        0x101a
 453.622 +#else  /* current sources say */
 453.623 +#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA       0x101a
 453.624 +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA        0x141a
 453.625 +       /* and XPsp2 Platform SDK added (2004-07-26) */
 453.626 +       /* Names are shortened to be significant within 40 chars. */
 453.627 +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN         0x181a
 453.628 +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC      0x181a
 453.629 +#endif
 453.630 +
 453.631 +#define TT_MS_LANGID_SLOVAK_SLOVAKIA                   0x041b
 453.632 +#define TT_MS_LANGID_ALBANIAN_ALBANIA                  0x041c
 453.633 +#define TT_MS_LANGID_SWEDISH_SWEDEN                    0x041d
 453.634 +#define TT_MS_LANGID_SWEDISH_FINLAND                   0x081d
 453.635 +#define TT_MS_LANGID_THAI_THAILAND                     0x041e
 453.636 +#define TT_MS_LANGID_TURKISH_TURKEY                    0x041f
 453.637 +#define TT_MS_LANGID_URDU_PAKISTAN                     0x0420
 453.638 +#define TT_MS_LANGID_URDU_INDIA                        0x0820
 453.639 +#define TT_MS_LANGID_INDONESIAN_INDONESIA              0x0421
 453.640 +#define TT_MS_LANGID_UKRAINIAN_UKRAINE                 0x0422
 453.641 +#define TT_MS_LANGID_BELARUSIAN_BELARUS                0x0423
 453.642 +#define TT_MS_LANGID_SLOVENE_SLOVENIA                  0x0424
 453.643 +#define TT_MS_LANGID_ESTONIAN_ESTONIA                  0x0425
 453.644 +#define TT_MS_LANGID_LATVIAN_LATVIA                    0x0426
 453.645 +#define TT_MS_LANGID_LITHUANIAN_LITHUANIA              0x0427
 453.646 +#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA      0x0827
 453.647 +#define TT_MS_LANGID_TAJIK_TAJIKISTAN                  0x0428
 453.648 +#define TT_MS_LANGID_FARSI_IRAN                        0x0429
 453.649 +#define TT_MS_LANGID_VIETNAMESE_VIET_NAM               0x042a
 453.650 +#define TT_MS_LANGID_ARMENIAN_ARMENIA                  0x042b
 453.651 +#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN            0x042c
 453.652 +#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC         0x082c
 453.653 +#define TT_MS_LANGID_BASQUE_SPAIN                      0x042d
 453.654 +#define TT_MS_LANGID_SORBIAN_GERMANY                   0x042e
 453.655 +#define TT_MS_LANGID_MACEDONIAN_MACEDONIA              0x042f
 453.656 +#define TT_MS_LANGID_SUTU_SOUTH_AFRICA                 0x0430
 453.657 +#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA               0x0431
 453.658 +#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA               0x0432
 453.659 +#define TT_MS_LANGID_VENDA_SOUTH_AFRICA                0x0433
 453.660 +#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA                0x0434
 453.661 +#define TT_MS_LANGID_ZULU_SOUTH_AFRICA                 0x0435
 453.662 +#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA            0x0436
 453.663 +#define TT_MS_LANGID_GEORGIAN_GEORGIA                  0x0437
 453.664 +#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS           0x0438
 453.665 +#define TT_MS_LANGID_HINDI_INDIA                       0x0439
 453.666 +#define TT_MS_LANGID_MALTESE_MALTA                     0x043a
 453.667 +  /* Added by XPsp2 Platform SDK (2004-07-26) */
 453.668 +#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY              0x043b
 453.669 +#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN              0x083b
 453.670 +#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND             0x0C3b
 453.671 +#define TT_MS_LANGID_SAMI_LULE_NORWAY                  0x103b
 453.672 +#define TT_MS_LANGID_SAMI_LULE_SWEDEN                  0x143b
 453.673 +#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY              0x183b
 453.674 +#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN              0x1C3b
 453.675 +#define TT_MS_LANGID_SAMI_SKOLT_FINLAND                0x203b
 453.676 +#define TT_MS_LANGID_SAMI_INARI_FINLAND                0x243b
 453.677 +  /* ... and we also keep our old identifier... */
 453.678 +#define TT_MS_LANGID_SAAMI_LAPONIA                     0x043b
 453.679 +
 453.680 +#if 0 /* this seems to be a previous inversion */
 453.681 +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043c
 453.682 +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083c
 453.683 +#else
 453.684 +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083c
 453.685 +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043c
 453.686 +#endif
 453.687 +
 453.688 +#define TT_MS_LANGID_YIDDISH_GERMANY                   0x043d
 453.689 +#define TT_MS_LANGID_MALAY_MALAYSIA                    0x043e
 453.690 +#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM           0x083e
 453.691 +#define TT_MS_LANGID_KAZAK_KAZAKSTAN                   0x043f
 453.692 +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440
 453.693 +  /* alias declared in Windows 2000 */
 453.694 +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \
 453.695 +          TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN
 453.696 +
 453.697 +#define TT_MS_LANGID_SWAHILI_KENYA                     0x0441
 453.698 +#define TT_MS_LANGID_TURKMEN_TURKMENISTAN              0x0442
 453.699 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN            0x0443
 453.700 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC         0x0843
 453.701 +#define TT_MS_LANGID_TATAR_TATARSTAN                   0x0444
 453.702 +#define TT_MS_LANGID_BENGALI_INDIA                     0x0445
 453.703 +#define TT_MS_LANGID_BENGALI_BANGLADESH                0x0845
 453.704 +#define TT_MS_LANGID_PUNJABI_INDIA                     0x0446
 453.705 +#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN           0x0846
 453.706 +#define TT_MS_LANGID_GUJARATI_INDIA                    0x0447
 453.707 +#define TT_MS_LANGID_ORIYA_INDIA                       0x0448
 453.708 +#define TT_MS_LANGID_TAMIL_INDIA                       0x0449
 453.709 +#define TT_MS_LANGID_TELUGU_INDIA                      0x044a
 453.710 +#define TT_MS_LANGID_KANNADA_INDIA                     0x044b
 453.711 +#define TT_MS_LANGID_MALAYALAM_INDIA                   0x044c
 453.712 +#define TT_MS_LANGID_ASSAMESE_INDIA                    0x044d
 453.713 +#define TT_MS_LANGID_MARATHI_INDIA                     0x044e
 453.714 +#define TT_MS_LANGID_SANSKRIT_INDIA                    0x044f
 453.715 +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450
 453.716 +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN      0x0850
 453.717 +#define TT_MS_LANGID_TIBETAN_CHINA                     0x0451
 453.718 +  /* Don't use the next constant!  It has            */
 453.719 +  /*   (1) the wrong spelling (Dzonghka)             */
 453.720 +  /*   (2) Microsoft doesn't officially define it -- */
 453.721 +  /*       at least it is not in the List of Local   */
 453.722 +  /*       ID Values.                                */
 453.723 +  /*   (3) Dzongkha is not the same language as      */
 453.724 +  /*       Tibetan, so merging it is wrong anyway.   */
 453.725 +  /*                                                 */
 453.726 +  /* TT_MS_LANGID_TIBETAN_BHUTAN is correct, BTW.    */
 453.727 +#define TT_MS_LANGID_DZONGHKA_BHUTAN                   0x0851
 453.728 +
 453.729 +#if 0
 453.730 +  /* the following used to be defined */
 453.731 +#define TT_MS_LANGID_TIBETAN_BHUTAN                    0x0451
 453.732 +  /* ... but it was changed; */
 453.733 +#else
 453.734 +  /* So we will continue to #define it, but with the correct value */
 453.735 +#define TT_MS_LANGID_TIBETAN_BHUTAN   TT_MS_LANGID_DZONGHKA_BHUTAN
 453.736 +#endif
 453.737 +
 453.738 +#define TT_MS_LANGID_WELSH_WALES                       0x0452
 453.739 +#define TT_MS_LANGID_KHMER_CAMBODIA                    0x0453
 453.740 +#define TT_MS_LANGID_LAO_LAOS                          0x0454
 453.741 +#define TT_MS_LANGID_BURMESE_MYANMAR                   0x0455
 453.742 +#define TT_MS_LANGID_GALICIAN_SPAIN                    0x0456
 453.743 +#define TT_MS_LANGID_KONKANI_INDIA                     0x0457
 453.744 +#define TT_MS_LANGID_MANIPURI_INDIA  /* Bengali */     0x0458
 453.745 +#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */         0x0459
 453.746 +#define TT_MS_LANGID_SINDHI_PAKISTAN                   0x0859
 453.747 +  /* Missing a LCID for Sindhi in Devanagari script */
 453.748 +#define TT_MS_LANGID_SYRIAC_SYRIA                      0x045a
 453.749 +#define TT_MS_LANGID_SINHALESE_SRI_LANKA               0x045b
 453.750 +#define TT_MS_LANGID_CHEROKEE_UNITED_STATES            0x045c
 453.751 +#define TT_MS_LANGID_INUKTITUT_CANADA                  0x045d
 453.752 +#define TT_MS_LANGID_AMHARIC_ETHIOPIA                  0x045e
 453.753 +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */    0x045f
 453.754 +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN           0x085f
 453.755 +  /* Missing a LCID for Tifinagh script */
 453.756 +#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */    0x0460
 453.757 +  /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */
 453.758 +  /* script is yet unclear... might be Arabic, Nagari or Sharada */
 453.759 +#define TT_MS_LANGID_KASHMIRI_SASIA                    0x0860
 453.760 +  /* ... and aliased (by MS) for compatibility reasons. */
 453.761 +#define TT_MS_LANGID_KASHMIRI_INDIA TT_MS_LANGID_KASHMIRI_SASIA
 453.762 +#define TT_MS_LANGID_NEPALI_NEPAL                      0x0461
 453.763 +#define TT_MS_LANGID_NEPALI_INDIA                      0x0861
 453.764 +#define TT_MS_LANGID_FRISIAN_NETHERLANDS               0x0462
 453.765 +#define TT_MS_LANGID_PASHTO_AFGHANISTAN                0x0463
 453.766 +#define TT_MS_LANGID_FILIPINO_PHILIPPINES              0x0464
 453.767 +#define TT_MS_LANGID_DHIVEHI_MALDIVES                  0x0465
 453.768 +  /* alias declared in Windows 2000 */
 453.769 +#define TT_MS_LANGID_DIVEHI_MALDIVES  TT_MS_LANGID_DHIVEHI_MALDIVES
 453.770 +#define TT_MS_LANGID_EDO_NIGERIA                       0x0466
 453.771 +#define TT_MS_LANGID_FULFULDE_NIGERIA                  0x0467
 453.772 +#define TT_MS_LANGID_HAUSA_NIGERIA                     0x0468
 453.773 +#define TT_MS_LANGID_IBIBIO_NIGERIA                    0x0469
 453.774 +#define TT_MS_LANGID_YORUBA_NIGERIA                    0x046a
 453.775 +#define TT_MS_LANGID_QUECHUA_BOLIVIA                   0x046b
 453.776 +#define TT_MS_LANGID_QUECHUA_ECUADOR                   0x086b
 453.777 +#define TT_MS_LANGID_QUECHUA_PERU                      0x0c6b
 453.778 +#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA               0x046c
 453.779 +  /* Also spelled by XPsp2 Platform SDK (2004-07-26) */
 453.780 +#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \
 453.781 +          TT_MS_LANGID_SEPEDI_SOUTH_AFRICA
 453.782 +  /* language codes 0x046d, 0x046e and 0x046f are (still) unknown. */
 453.783 +#define TT_MS_LANGID_IGBO_NIGERIA                      0x0470
 453.784 +#define TT_MS_LANGID_KANURI_NIGERIA                    0x0471
 453.785 +#define TT_MS_LANGID_OROMO_ETHIOPIA                    0x0472
 453.786 +#define TT_MS_LANGID_TIGRIGNA_ETHIOPIA                 0x0473
 453.787 +#define TT_MS_LANGID_TIGRIGNA_ERYTHREA                 0x0873
 453.788 +  /* also spelled in the `Passport SDK' list as: */
 453.789 +#define TT_MS_LANGID_TIGRIGNA_ERYTREA  TT_MS_LANGID_TIGRIGNA_ERYTHREA
 453.790 +#define TT_MS_LANGID_GUARANI_PARAGUAY                  0x0474
 453.791 +#define TT_MS_LANGID_HAWAIIAN_UNITED_STATES            0x0475
 453.792 +#define TT_MS_LANGID_LATIN                             0x0476
 453.793 +#define TT_MS_LANGID_SOMALI_SOMALIA                    0x0477
 453.794 +  /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */
 453.795 +  /*       not written (but OTOH the peculiar writing system is worth     */
 453.796 +  /*       studying).                                                     */
 453.797 +#define TT_MS_LANGID_YI_CHINA                          0x0478
 453.798 +#define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES   0x0479
 453.799 +  /* language codes from 0x047a to 0x047f are (still) unknown. */
 453.800 +#define TT_MS_LANGID_UIGHUR_CHINA                      0x0480
 453.801 +#define TT_MS_LANGID_MAORI_NEW_ZEALAND                 0x0481
 453.802 +
 453.803 +#if 0  /* not deemed useful for fonts */
 453.804 +#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE            0x04ff
 453.805 +#endif
 453.806 +
 453.807 +
 453.808 +  /*************************************************************************/
 453.809 +  /*                                                                       */
 453.810 +  /* Possible values of the `name' identifier field in the name records of */
 453.811 +  /* the TTF `name' table.  These values are platform independent.         */
 453.812 +  /*                                                                       */
 453.813 +#define TT_NAME_ID_COPYRIGHT            0
 453.814 +#define TT_NAME_ID_FONT_FAMILY          1
 453.815 +#define TT_NAME_ID_FONT_SUBFAMILY       2
 453.816 +#define TT_NAME_ID_UNIQUE_ID            3
 453.817 +#define TT_NAME_ID_FULL_NAME            4
 453.818 +#define TT_NAME_ID_VERSION_STRING       5
 453.819 +#define TT_NAME_ID_PS_NAME              6
 453.820 +#define TT_NAME_ID_TRADEMARK            7
 453.821 +
 453.822 +  /* the following values are from the OpenType spec */
 453.823 +#define TT_NAME_ID_MANUFACTURER         8
 453.824 +#define TT_NAME_ID_DESIGNER             9
 453.825 +#define TT_NAME_ID_DESCRIPTION          10
 453.826 +#define TT_NAME_ID_VENDOR_URL           11
 453.827 +#define TT_NAME_ID_DESIGNER_URL         12
 453.828 +#define TT_NAME_ID_LICENSE              13
 453.829 +#define TT_NAME_ID_LICENSE_URL          14
 453.830 +  /* number 15 is reserved */
 453.831 +#define TT_NAME_ID_PREFERRED_FAMILY     16
 453.832 +#define TT_NAME_ID_PREFERRED_SUBFAMILY  17
 453.833 +#define TT_NAME_ID_MAC_FULL_NAME        18
 453.834 +
 453.835 +  /* The following code is new as of 2000-01-21 */
 453.836 +#define TT_NAME_ID_SAMPLE_TEXT          19
 453.837 +
 453.838 +  /* This is new in OpenType 1.3 */
 453.839 +#define TT_NAME_ID_CID_FINDFONT_NAME    20
 453.840 +
 453.841 +  /* This is new in OpenType 1.5 */
 453.842 +#define TT_NAME_ID_WWS_FAMILY           21
 453.843 +#define TT_NAME_ID_WWS_SUBFAMILY        22
 453.844 +
 453.845 +
 453.846 +  /*************************************************************************/
 453.847 +  /*                                                                       */
 453.848 +  /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table.     */
 453.849 +  /*                                                                       */
 453.850 +  /* Updated 08-Nov-2008.                                                  */
 453.851 +  /*                                                                       */
 453.852 +
 453.853 +  /* Bit  0   Basic Latin */
 453.854 +#define TT_UCR_BASIC_LATIN                     (1L <<  0) /* U+0020-U+007E */
 453.855 +  /* Bit  1   C1 Controls and Latin-1 Supplement */
 453.856 +#define TT_UCR_LATIN1_SUPPLEMENT               (1L <<  1) /* U+0080-U+00FF */
 453.857 +  /* Bit  2   Latin Extended-A */
 453.858 +#define TT_UCR_LATIN_EXTENDED_A                (1L <<  2) /* U+0100-U+017F */
 453.859 +  /* Bit  3   Latin Extended-B */
 453.860 +#define TT_UCR_LATIN_EXTENDED_B                (1L <<  3) /* U+0180-U+024F */
 453.861 +  /* Bit  4   IPA Extensions                 */
 453.862 +  /*          Phonetic Extensions            */
 453.863 +  /*          Phonetic Extensions Supplement */
 453.864 +#define TT_UCR_IPA_EXTENSIONS                  (1L <<  4) /* U+0250-U+02AF */
 453.865 +                                                          /* U+1D00-U+1D7F */
 453.866 +                                                          /* U+1D80-U+1DBF */
 453.867 +  /* Bit  5   Spacing Modifier Letters */
 453.868 +  /*          Modifier Tone Letters    */
 453.869 +#define TT_UCR_SPACING_MODIFIER                (1L <<  5) /* U+02B0-U+02FF */
 453.870 +                                                          /* U+A700-U+A71F */
 453.871 +  /* Bit  6   Combining Diacritical Marks            */
 453.872 +  /*          Combining Diacritical Marks Supplement */
 453.873 +#define TT_UCR_COMBINING_DIACRITICS            (1L <<  6) /* U+0300-U+036F */
 453.874 +                                                          /* U+1DC0-U+1DFF */
 453.875 +  /* Bit  7   Greek and Coptic */
 453.876 +#define TT_UCR_GREEK                           (1L <<  7) /* U+0370-U+03FF */
 453.877 +  /* Bit  8   Coptic */
 453.878 +#define TT_UCR_COPTIC                          (1L <<  8) /* U+2C80-U+2CFF */
 453.879 +  /* Bit  9   Cyrillic            */
 453.880 +  /*          Cyrillic Supplement */
 453.881 +  /*          Cyrillic Extended-A */
 453.882 +  /*          Cyrillic Extended-B */
 453.883 +#define TT_UCR_CYRILLIC                        (1L <<  9) /* U+0400-U+04FF */
 453.884 +                                                          /* U+0500-U+052F */
 453.885 +                                                          /* U+2DE0-U+2DFF */
 453.886 +                                                          /* U+A640-U+A69F */
 453.887 +  /* Bit 10   Armenian */
 453.888 +#define TT_UCR_ARMENIAN                        (1L << 10) /* U+0530-U+058F */
 453.889 +  /* Bit 11   Hebrew */
 453.890 +#define TT_UCR_HEBREW                          (1L << 11) /* U+0590-U+05FF */
 453.891 +  /* Bit 12   Vai */
 453.892 +#define TT_UCR_VAI                             (1L << 12) /* U+A500-U+A63F */
 453.893 +  /* Bit 13   Arabic            */
 453.894 +  /*          Arabic Supplement */
 453.895 +#define TT_UCR_ARABIC                          (1L << 13) /* U+0600-U+06FF */
 453.896 +                                                          /* U+0750-U+077F */
 453.897 +  /* Bit 14   NKo */
 453.898 +#define TT_UCR_NKO                             (1L << 14) /* U+07C0-U+07FF */
 453.899 +  /* Bit 15   Devanagari */
 453.900 +#define TT_UCR_DEVANAGARI                      (1L << 15) /* U+0900-U+097F */
 453.901 +  /* Bit 16   Bengali */
 453.902 +#define TT_UCR_BENGALI                         (1L << 16) /* U+0980-U+09FF */
 453.903 +  /* Bit 17   Gurmukhi */
 453.904 +#define TT_UCR_GURMUKHI                        (1L << 17) /* U+0A00-U+0A7F */
 453.905 +  /* Bit 18   Gujarati */
 453.906 +#define TT_UCR_GUJARATI                        (1L << 18) /* U+0A80-U+0AFF */
 453.907 +  /* Bit 19   Oriya */
 453.908 +#define TT_UCR_ORIYA                           (1L << 19) /* U+0B00-U+0B7F */
 453.909 +  /* Bit 20   Tamil */
 453.910 +#define TT_UCR_TAMIL                           (1L << 20) /* U+0B80-U+0BFF */
 453.911 +  /* Bit 21   Telugu */
 453.912 +#define TT_UCR_TELUGU                          (1L << 21) /* U+0C00-U+0C7F */
 453.913 +  /* Bit 22   Kannada */
 453.914 +#define TT_UCR_KANNADA                         (1L << 22) /* U+0C80-U+0CFF */
 453.915 +  /* Bit 23   Malayalam */
 453.916 +#define TT_UCR_MALAYALAM                       (1L << 23) /* U+0D00-U+0D7F */
 453.917 +  /* Bit 24   Thai */
 453.918 +#define TT_UCR_THAI                            (1L << 24) /* U+0E00-U+0E7F */
 453.919 +  /* Bit 25   Lao */
 453.920 +#define TT_UCR_LAO                             (1L << 25) /* U+0E80-U+0EFF */
 453.921 +  /* Bit 26   Georgian            */
 453.922 +  /*          Georgian Supplement */
 453.923 +#define TT_UCR_GEORGIAN                        (1L << 26) /* U+10A0-U+10FF */
 453.924 +                                                          /* U+2D00-U+2D2F */
 453.925 +  /* Bit 27   Balinese */
 453.926 +#define TT_UCR_BALINESE                        (1L << 27) /* U+1B00-U+1B7F */
 453.927 +  /* Bit 28   Hangul Jamo */
 453.928 +#define TT_UCR_HANGUL_JAMO                     (1L << 28) /* U+1100-U+11FF */
 453.929 +  /* Bit 29   Latin Extended Additional */
 453.930 +  /*          Latin Extended-C          */
 453.931 +  /*          Latin Extended-D          */
 453.932 +#define TT_UCR_LATIN_EXTENDED_ADDITIONAL       (1L << 29) /* U+1E00-U+1EFF */
 453.933 +                                                          /* U+2C60-U+2C7F */
 453.934 +                                                          /* U+A720-U+A7FF */
 453.935 +  /* Bit 30   Greek Extended */
 453.936 +#define TT_UCR_GREEK_EXTENDED                  (1L << 30) /* U+1F00-U+1FFF */
 453.937 +  /* Bit 31   General Punctuation      */
 453.938 +  /*          Supplemental Punctuation */
 453.939 +#define TT_UCR_GENERAL_PUNCTUATION             (1L << 31) /* U+2000-U+206F */
 453.940 +                                                          /* U+2E00-U+2E7F */
 453.941 +  /* Bit 32   Superscripts And Subscripts */
 453.942 +#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS         (1L <<  0) /* U+2070-U+209F */
 453.943 +  /* Bit 33   Currency Symbols */
 453.944 +#define TT_UCR_CURRENCY_SYMBOLS                (1L <<  1) /* U+20A0-U+20CF */
 453.945 +  /* Bit 34   Combining Diacritical Marks For Symbols */
 453.946 +#define TT_UCR_COMBINING_DIACRITICS_SYMB       (1L <<  2) /* U+20D0-U+20FF */
 453.947 +  /* Bit 35   Letterlike Symbols */
 453.948 +#define TT_UCR_LETTERLIKE_SYMBOLS              (1L <<  3) /* U+2100-U+214F */
 453.949 +  /* Bit 36   Number Forms */
 453.950 +#define TT_UCR_NUMBER_FORMS                    (1L <<  4) /* U+2150-U+218F */
 453.951 +  /* Bit 37   Arrows                           */
 453.952 +  /*          Supplemental Arrows-A            */
 453.953 +  /*          Supplemental Arrows-B            */
 453.954 +  /*          Miscellaneous Symbols and Arrows */
 453.955 +#define TT_UCR_ARROWS                          (1L <<  5) /* U+2190-U+21FF */
 453.956 +                                                          /* U+27F0-U+27FF */
 453.957 +                                                          /* U+2900-U+297F */
 453.958 +                                                          /* U+2B00-U+2BFF */
 453.959 +  /* Bit 38   Mathematical Operators               */
 453.960 +  /*          Supplemental Mathematical Operators  */
 453.961 +  /*          Miscellaneous Mathematical Symbols-A */
 453.962 +  /*          Miscellaneous Mathematical Symbols-B */
 453.963 +#define TT_UCR_MATHEMATICAL_OPERATORS          (1L <<  6) /* U+2200-U+22FF */
 453.964 +                                                          /* U+2A00-U+2AFF */
 453.965 +                                                          /* U+27C0-U+27EF */
 453.966 +                                                          /* U+2980-U+29FF */
 453.967 +  /* Bit 39 Miscellaneous Technical */
 453.968 +#define TT_UCR_MISCELLANEOUS_TECHNICAL         (1L <<  7) /* U+2300-U+23FF */
 453.969 +  /* Bit 40   Control Pictures */
 453.970 +#define TT_UCR_CONTROL_PICTURES                (1L <<  8) /* U+2400-U+243F */
 453.971 +  /* Bit 41   Optical Character Recognition */
 453.972 +#define TT_UCR_OCR                             (1L <<  9) /* U+2440-U+245F */
 453.973 +  /* Bit 42   Enclosed Alphanumerics */
 453.974 +#define TT_UCR_ENCLOSED_ALPHANUMERICS          (1L << 10) /* U+2460-U+24FF */
 453.975 +  /* Bit 43   Box Drawing */
 453.976 +#define TT_UCR_BOX_DRAWING                     (1L << 11) /* U+2500-U+257F */
 453.977 +  /* Bit 44   Block Elements */
 453.978 +#define TT_UCR_BLOCK_ELEMENTS                  (1L << 12) /* U+2580-U+259F */
 453.979 +  /* Bit 45   Geometric Shapes */
 453.980 +#define TT_UCR_GEOMETRIC_SHAPES                (1L << 13) /* U+25A0-U+25FF */
 453.981 +  /* Bit 46   Miscellaneous Symbols */
 453.982 +#define TT_UCR_MISCELLANEOUS_SYMBOLS           (1L << 14) /* U+2600-U+26FF */
 453.983 +  /* Bit 47   Dingbats */
 453.984 +#define TT_UCR_DINGBATS                        (1L << 15) /* U+2700-U+27BF */
 453.985 +  /* Bit 48   CJK Symbols and Punctuation */
 453.986 +#define TT_UCR_CJK_SYMBOLS                     (1L << 16) /* U+3000-U+303F */
 453.987 +  /* Bit 49   Hiragana */
 453.988 +#define TT_UCR_HIRAGANA                        (1L << 17) /* U+3040-U+309F */
 453.989 +  /* Bit 50   Katakana                     */
 453.990 +  /*          Katakana Phonetic Extensions */
 453.991 +#define TT_UCR_KATAKANA                        (1L << 18) /* U+30A0-U+30FF */
 453.992 +                                                          /* U+31F0-U+31FF */
 453.993 +  /* Bit 51   Bopomofo          */
 453.994 +  /*          Bopomofo Extended */
 453.995 +#define TT_UCR_BOPOMOFO                        (1L << 19) /* U+3100-U+312F */
 453.996 +                                                          /* U+31A0-U+31BF */
 453.997 +  /* Bit 52   Hangul Compatibility Jamo */
 453.998 +#define TT_UCR_HANGUL_COMPATIBILITY_JAMO       (1L << 20) /* U+3130-U+318F */
 453.999 +  /* Bit 53   Phags-Pa */
453.1000 +#define TT_UCR_CJK_MISC                        (1L << 21) /* U+A840-U+A87F */
453.1001 +#define TT_UCR_KANBUN  TT_UCR_CJK_MISC /* deprecated */
453.1002 +#define TT_UCR_PHAGSPA
453.1003 +  /* Bit 54   Enclosed CJK Letters and Months */
453.1004 +#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS     (1L << 22) /* U+3200-U+32FF */
453.1005 +  /* Bit 55   CJK Compatibility */
453.1006 +#define TT_UCR_CJK_COMPATIBILITY               (1L << 23) /* U+3300-U+33FF */
453.1007 +  /* Bit 56   Hangul Syllables */
453.1008 +#define TT_UCR_HANGUL                          (1L << 24) /* U+AC00-U+D7A3 */
453.1009 +  /* Bit 57   High Surrogates              */
453.1010 +  /*          High Private Use Surrogates  */
453.1011 +  /*          Low Surrogates               */
453.1012 +  /*                                       */
453.1013 +  /* According to OpenType specs v.1.3+,   */
453.1014 +  /* setting bit 57 implies that there is  */
453.1015 +  /* at least one codepoint beyond the     */
453.1016 +  /* Basic Multilingual Plane that is      */
453.1017 +  /* supported by this font.  So it really */
453.1018 +  /* means >= U+10000                      */
453.1019 +#define TT_UCR_SURROGATES                      (1L << 25) /* U+D800-U+DB7F */
453.1020 +                                                          /* U+DB80-U+DBFF */
453.1021 +                                                          /* U+DC00-U+DFFF */
453.1022 +#define TT_UCR_NON_PLANE_0  TT_UCR_SURROGATES
453.1023 +  /* Bit 58  Phoenician */
453.1024 +#define TT_UCR_PHOENICIAN                      (1L << 26) /*U+10900-U+1091F*/
453.1025 +  /* Bit 59   CJK Unified Ideographs             */
453.1026 +  /*          CJK Radicals Supplement            */
453.1027 +  /*          Kangxi Radicals                    */
453.1028 +  /*          Ideographic Description Characters */
453.1029 +  /*          CJK Unified Ideographs Extension A */
453.1030 +  /*          CJK Unified Ideographs Extension B */
453.1031 +  /*          Kanbun                             */
453.1032 +#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS          (1L << 27) /* U+4E00-U+9FFF */
453.1033 +                                                          /* U+2E80-U+2EFF */
453.1034 +                                                          /* U+2F00-U+2FDF */
453.1035 +                                                          /* U+2FF0-U+2FFF */
453.1036 +                                                          /* U+3400-U+4DB5 */
453.1037 +                                                          /*U+20000-U+2A6DF*/
453.1038 +                                                          /* U+3190-U+319F */
453.1039 +  /* Bit 60   Private Use */
453.1040 +#define TT_UCR_PRIVATE_USE                     (1L << 28) /* U+E000-U+F8FF */
453.1041 +  /* Bit 61   CJK Strokes                             */
453.1042 +  /*          CJK Compatibility Ideographs            */
453.1043 +  /*          CJK Compatibility Ideographs Supplement */
453.1044 +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS    (1L << 29) /* U+31C0-U+31EF */
453.1045 +                                                          /* U+F900-U+FAFF */
453.1046 +                                                          /*U+2F800-U+2FA1F*/
453.1047 +  /* Bit 62   Alphabetic Presentation Forms */
453.1048 +#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS   (1L << 30) /* U+FB00-U+FB4F */
453.1049 +  /* Bit 63   Arabic Presentation Forms-A */
453.1050 +#define TT_UCR_ARABIC_PRESENTATIONS_A          (1L << 31) /* U+FB50-U+FDFF */
453.1051 +  /* Bit 64   Combining Half Marks */
453.1052 +#define TT_UCR_COMBINING_HALF_MARKS            (1L <<  0) /* U+FE20-U+FE2F */
453.1053 +  /* Bit 65   Vertical forms          */
453.1054 +  /*          CJK Compatibility Forms */
453.1055 +#define TT_UCR_CJK_COMPATIBILITY_FORMS         (1L <<  1) /* U+FE10-U+FE1F */
453.1056 +                                                          /* U+FE30-U+FE4F */
453.1057 +  /* Bit 66   Small Form Variants */
453.1058 +#define TT_UCR_SMALL_FORM_VARIANTS             (1L <<  2) /* U+FE50-U+FE6F */
453.1059 +  /* Bit 67   Arabic Presentation Forms-B */
453.1060 +#define TT_UCR_ARABIC_PRESENTATIONS_B          (1L <<  3) /* U+FE70-U+FEFE */
453.1061 +  /* Bit 68   Halfwidth and Fullwidth Forms */
453.1062 +#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS       (1L <<  4) /* U+FF00-U+FFEF */
453.1063 +  /* Bit 69   Specials */
453.1064 +#define TT_UCR_SPECIALS                        (1L <<  5) /* U+FFF0-U+FFFD */
453.1065 +  /* Bit 70   Tibetan */
453.1066 +#define TT_UCR_TIBETAN                         (1L <<  6) /* U+0F00-U+0FFF */
453.1067 +  /* Bit 71   Syriac */
453.1068 +#define TT_UCR_SYRIAC                          (1L <<  7) /* U+0700-U+074F */
453.1069 +  /* Bit 72   Thaana */
453.1070 +#define TT_UCR_THAANA                          (1L <<  8) /* U+0780-U+07BF */
453.1071 +  /* Bit 73   Sinhala */
453.1072 +#define TT_UCR_SINHALA                         (1L <<  9) /* U+0D80-U+0DFF */
453.1073 +  /* Bit 74   Myanmar */
453.1074 +#define TT_UCR_MYANMAR                         (1L << 10) /* U+1000-U+109F */
453.1075 +  /* Bit 75   Ethiopic            */
453.1076 +  /*          Ethiopic Supplement */
453.1077 +  /*          Ethiopic Extended   */
453.1078 +#define TT_UCR_ETHIOPIC                        (1L << 11) /* U+1200-U+137F */
453.1079 +                                                          /* U+1380-U+139F */
453.1080 +                                                          /* U+2D80-U+2DDF */
453.1081 +  /* Bit 76   Cherokee */
453.1082 +#define TT_UCR_CHEROKEE                        (1L << 12) /* U+13A0-U+13FF */
453.1083 +  /* Bit 77   Unified Canadian Aboriginal Syllabics */
453.1084 +#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS   (1L << 13) /* U+1400-U+167F */
453.1085 +  /* Bit 78   Ogham */
453.1086 +#define TT_UCR_OGHAM                           (1L << 14) /* U+1680-U+169F */
453.1087 +  /* Bit 79   Runic */
453.1088 +#define TT_UCR_RUNIC                           (1L << 15) /* U+16A0-U+16FF */
453.1089 +  /* Bit 80   Khmer         */
453.1090 +  /*          Khmer Symbols */
453.1091 +#define TT_UCR_KHMER                           (1L << 16) /* U+1780-U+17FF */
453.1092 +                                                          /* U+19E0-U+19FF */
453.1093 +  /* Bit 81   Mongolian */
453.1094 +#define TT_UCR_MONGOLIAN                       (1L << 17) /* U+1800-U+18AF */
453.1095 +  /* Bit 82   Braille Patterns */
453.1096 +#define TT_UCR_BRAILLE                         (1L << 18) /* U+2800-U+28FF */
453.1097 +  /* Bit 83   Yi Syllables */
453.1098 +  /*          Yi Radicals  */
453.1099 +#define TT_UCR_YI                              (1L << 19) /* U+A000-U+A48F */
453.1100 +                                                          /* U+A490-U+A4CF */
453.1101 +  /* Bit 84   Tagalog  */
453.1102 +  /*          Hanunoo  */
453.1103 +  /*          Buhid    */
453.1104 +  /*          Tagbanwa */
453.1105 +#define TT_UCR_PHILIPPINE                      (1L << 20) /* U+1700-U+171F */
453.1106 +                                                          /* U+1720-U+173F */
453.1107 +                                                          /* U+1740-U+175F */
453.1108 +                                                          /* U+1760-U+177F */
453.1109 +  /* Bit 85   Old Italic */
453.1110 +#define TT_UCR_OLD_ITALIC                      (1L << 21) /*U+10300-U+1032F*/
453.1111 +  /* Bit 86   Gothic */
453.1112 +#define TT_UCR_GOTHIC                          (1L << 22) /*U+10330-U+1034F*/
453.1113 +  /* Bit 87   Deseret */
453.1114 +#define TT_UCR_DESERET                         (1L << 23) /*U+10400-U+1044F*/
453.1115 +  /* Bit 88   Byzantine Musical Symbols      */
453.1116 +  /*          Musical Symbols                */
453.1117 +  /*          Ancient Greek Musical Notation */
453.1118 +#define TT_UCR_MUSICAL_SYMBOLS                 (1L << 24) /*U+1D000-U+1D0FF*/
453.1119 +                                                          /*U+1D100-U+1D1FF*/
453.1120 +                                                          /*U+1D200-U+1D24F*/
453.1121 +  /* Bit 89   Mathematical Alphanumeric Symbols */
453.1122 +#define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS       (1L << 25) /*U+1D400-U+1D7FF*/
453.1123 +  /* Bit 90   Private Use (plane 15) */
453.1124 +  /*          Private Use (plane 16) */
453.1125 +#define TT_UCR_PRIVATE_USE_SUPPLEMENTARY       (1L << 26) /*U+F0000-U+FFFFD*/
453.1126 +                                                        /*U+100000-U+10FFFD*/
453.1127 +  /* Bit 91   Variation Selectors            */
453.1128 +  /*          Variation Selectors Supplement */
453.1129 +#define TT_UCR_VARIATION_SELECTORS             (1L << 27) /* U+FE00-U+FE0F */
453.1130 +                                                          /*U+E0100-U+E01EF*/
453.1131 +  /* Bit 92   Tags */
453.1132 +#define TT_UCR_TAGS                            (1L << 28) /*U+E0000-U+E007F*/
453.1133 +  /* Bit 93   Limbu */
453.1134 +#define TT_UCR_LIMBU                           (1L << 29) /* U+1900-U+194F */
453.1135 +  /* Bit 94   Tai Le */
453.1136 +#define TT_UCR_TAI_LE                          (1L << 30) /* U+1950-U+197F */
453.1137 +  /* Bit 95   New Tai Lue */
453.1138 +#define TT_UCR_NEW_TAI_LUE                     (1L << 31) /* U+1980-U+19DF */
453.1139 +  /* Bit 96   Buginese */
453.1140 +#define TT_UCR_BUGINESE                        (1L <<  0) /* U+1A00-U+1A1F */
453.1141 +  /* Bit 97   Glagolitic */
453.1142 +#define TT_UCR_GLAGOLITIC                      (1L <<  1) /* U+2C00-U+2C5F */
453.1143 +  /* Bit 98   Tifinagh */
453.1144 +#define TT_UCR_TIFINAGH                        (1L <<  2) /* U+2D30-U+2D7F */
453.1145 +  /* Bit 99   Yijing Hexagram Symbols */
453.1146 +#define TT_UCR_YIJING                          (1L <<  3) /* U+4DC0-U+4DFF */
453.1147 +  /* Bit 100  Syloti Nagri */
453.1148 +#define TT_UCR_SYLOTI_NAGRI                    (1L <<  4) /* U+A800-U+A82F */
453.1149 +  /* Bit 101  Linear B Syllabary */
453.1150 +  /*          Linear B Ideograms */
453.1151 +  /*          Aegean Numbers     */
453.1152 +#define TT_UCR_LINEAR_B                        (1L <<  5) /*U+10000-U+1007F*/
453.1153 +                                                          /*U+10080-U+100FF*/
453.1154 +                                                          /*U+10100-U+1013F*/
453.1155 +  /* Bit 102  Ancient Greek Numbers */
453.1156 +#define TT_UCR_ANCIENT_GREEK_NUMBERS           (1L <<  6) /*U+10140-U+1018F*/
453.1157 +  /* Bit 103  Ugaritic */
453.1158 +#define TT_UCR_UGARITIC                        (1L <<  7) /*U+10380-U+1039F*/
453.1159 +  /* Bit 104  Old Persian */
453.1160 +#define TT_UCR_OLD_PERSIAN                     (1L <<  8) /*U+103A0-U+103DF*/
453.1161 +  /* Bit 105  Shavian */
453.1162 +#define TT_UCR_SHAVIAN                         (1L <<  9) /*U+10450-U+1047F*/
453.1163 +  /* Bit 106  Osmanya */
453.1164 +#define TT_UCR_OSMANYA                         (1L << 10) /*U+10480-U+104AF*/
453.1165 +  /* Bit 107  Cypriot Syllabary */
453.1166 +#define TT_UCR_CYPRIOT_SYLLABARY               (1L << 11) /*U+10800-U+1083F*/
453.1167 +  /* Bit 108  Kharoshthi */
453.1168 +#define TT_UCR_KHAROSHTHI                      (1L << 12) /*U+10A00-U+10A5F*/
453.1169 +  /* Bit 109  Tai Xuan Jing Symbols */
453.1170 +#define TT_UCR_TAI_XUAN_JING                   (1L << 13) /*U+1D300-U+1D35F*/
453.1171 +  /* Bit 110  Cuneiform                         */
453.1172 +  /*          Cuneiform Numbers and Punctuation */
453.1173 +#define TT_UCR_CUNEIFORM                       (1L << 14) /*U+12000-U+123FF*/
453.1174 +                                                          /*U+12400-U+1247F*/
453.1175 +  /* Bit 111  Counting Rod Numerals */
453.1176 +#define TT_UCR_COUNTING_ROD_NUMERALS           (1L << 15) /*U+1D360-U+1D37F*/
453.1177 +  /* Bit 112  Sundanese */
453.1178 +#define TT_UCR_SUNDANESE                       (1L << 16) /* U+1B80-U+1BBF */
453.1179 +  /* Bit 113  Lepcha */
453.1180 +#define TT_UCR_LEPCHA                          (1L << 17) /* U+1C00-U+1C4F */
453.1181 +  /* Bit 114  Ol Chiki */
453.1182 +#define TT_UCR_OL_CHIKI                        (1L << 18) /* U+1C50-U+1C7F */
453.1183 +  /* Bit 115  Saurashtra */
453.1184 +#define TT_UCR_SAURASHTRA                      (1L << 19) /* U+A880-U+A8DF */
453.1185 +  /* Bit 116  Kayah Li */
453.1186 +#define TT_UCR_KAYAH_LI                        (1L << 20) /* U+A900-U+A92F */
453.1187 +  /* Bit 117  Rejang */
453.1188 +#define TT_UCR_REJANG                          (1L << 21) /* U+A930-U+A95F */
453.1189 +  /* Bit 118  Cham */
453.1190 +#define TT_UCR_CHAM                            (1L << 22) /* U+AA00-U+AA5F */
453.1191 +  /* Bit 119  Ancient Symbols */
453.1192 +#define TT_UCR_ANCIENT_SYMBOLS                 (1L << 23) /*U+10190-U+101CF*/
453.1193 +  /* Bit 120  Phaistos Disc */
453.1194 +#define TT_UCR_PHAISTOS_DISC                   (1L << 24) /*U+101D0-U+101FF*/
453.1195 +  /* Bit 121  Carian */
453.1196 +  /*          Lycian */
453.1197 +  /*          Lydian */
453.1198 +#define TT_UCR_OLD_ANATOLIAN                   (1L << 25) /*U+102A0-U+102DF*/
453.1199 +                                                          /*U+10280-U+1029F*/
453.1200 +                                                          /*U+10920-U+1093F*/
453.1201 +  /* Bit 122  Domino Tiles  */
453.1202 +  /*          Mahjong Tiles */
453.1203 +#define TT_UCR_GAME_TILES                      (1L << 26) /*U+1F030-U+1F09F*/
453.1204 +                                                          /*U+1F000-U+1F02F*/
453.1205 +  /* Bit 123-127 Reserved for process-internal usage */
453.1206 +
453.1207 +
453.1208 +  /*************************************************************************/
453.1209 +  /*                                                                       */
453.1210 +  /* Some compilers have a very limited length of identifiers.             */
453.1211 +  /*                                                                       */
453.1212 +#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ )
453.1213 +#define HAVE_LIMIT_ON_IDENTS
453.1214 +#endif
453.1215 +
453.1216 +
453.1217 +#ifndef HAVE_LIMIT_ON_IDENTS
453.1218 +
453.1219 +
453.1220 +  /*************************************************************************/
453.1221 +  /*                                                                       */
453.1222 +  /* Here some alias #defines in order to be clearer.                      */
453.1223 +  /*                                                                       */
453.1224 +  /* These are not always #defined to stay within the 31~character limit   */
453.1225 +  /* which some compilers have.                                            */
453.1226 +  /*                                                                       */
453.1227 +  /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern  */
453.1228 +  /* Borland compilers (read: from BC++ 3.1 on) can increase this limit.   */
453.1229 +  /* If you get a warning with such a compiler, use the -i40 switch.       */
453.1230 +  /*                                                                       */
453.1231 +#define TT_UCR_ARABIC_PRESENTATION_FORMS_A      \
453.1232 +         TT_UCR_ARABIC_PRESENTATIONS_A
453.1233 +#define TT_UCR_ARABIC_PRESENTATION_FORMS_B      \
453.1234 +         TT_UCR_ARABIC_PRESENTATIONS_B
453.1235 +
453.1236 +#define TT_UCR_COMBINING_DIACRITICAL_MARKS      \
453.1237 +         TT_UCR_COMBINING_DIACRITICS
453.1238 +#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \
453.1239 +         TT_UCR_COMBINING_DIACRITICS_SYMB
453.1240 +
453.1241 +
453.1242 +#endif /* !HAVE_LIMIT_ON_IDENTS */
453.1243 +
453.1244 +
453.1245 +FT_END_HEADER
453.1246 +
453.1247 +#endif /* __TTNAMEID_H__ */
453.1248 +
453.1249 +
453.1250 +/* END */
   454.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   454.2 +++ b/libs/ft2static/freetype/tttables.h	Sat Feb 01 19:58:19 2014 +0200
   454.3 @@ -0,0 +1,759 @@
   454.4 +/***************************************************************************/
   454.5 +/*                                                                         */
   454.6 +/*  tttables.h                                                             */
   454.7 +/*                                                                         */
   454.8 +/*    Basic SFNT/TrueType tables definitions and interface                 */
   454.9 +/*    (specification only).                                                */
  454.10 +/*                                                                         */
  454.11 +/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010 by       */
  454.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  454.13 +/*                                                                         */
  454.14 +/*  This file is part of the FreeType project, and may only be used,       */
  454.15 +/*  modified, and distributed under the terms of the FreeType project      */
  454.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  454.17 +/*  this file you indicate that you have read the license and              */
  454.18 +/*  understand and accept it fully.                                        */
  454.19 +/*                                                                         */
  454.20 +/***************************************************************************/
  454.21 +
  454.22 +
  454.23 +#ifndef __TTTABLES_H__
  454.24 +#define __TTTABLES_H__
  454.25 +
  454.26 +
  454.27 +#include <ft2build.h>
  454.28 +#include FT_FREETYPE_H
  454.29 +
  454.30 +#ifdef FREETYPE_H
  454.31 +#error "freetype.h of FreeType 1 has been loaded!"
  454.32 +#error "Please fix the directory search order for header files"
  454.33 +#error "so that freetype.h of FreeType 2 is found first."
  454.34 +#endif
  454.35 +
  454.36 +
  454.37 +FT_BEGIN_HEADER
  454.38 +
  454.39 +  /*************************************************************************/
  454.40 +  /*                                                                       */
  454.41 +  /* <Section>                                                             */
  454.42 +  /*    truetype_tables                                                    */
  454.43 +  /*                                                                       */
  454.44 +  /* <Title>                                                               */
  454.45 +  /*    TrueType Tables                                                    */
  454.46 +  /*                                                                       */
  454.47 +  /* <Abstract>                                                            */
  454.48 +  /*    TrueType specific table types and functions.                       */
  454.49 +  /*                                                                       */
  454.50 +  /* <Description>                                                         */
  454.51 +  /*    This section contains the definition of TrueType-specific tables   */
  454.52 +  /*    as well as some routines used to access and process them.          */
  454.53 +  /*                                                                       */
  454.54 +  /*************************************************************************/
  454.55 +
  454.56 +
  454.57 +  /*************************************************************************/
  454.58 +  /*                                                                       */
  454.59 +  /* <Struct>                                                              */
  454.60 +  /*    TT_Header                                                          */
  454.61 +  /*                                                                       */
  454.62 +  /* <Description>                                                         */
  454.63 +  /*    A structure used to model a TrueType font header table.  All       */
  454.64 +  /*    fields follow the TrueType specification.                          */
  454.65 +  /*                                                                       */
  454.66 +  typedef struct  TT_Header_
  454.67 +  {
  454.68 +    FT_Fixed   Table_Version;
  454.69 +    FT_Fixed   Font_Revision;
  454.70 +
  454.71 +    FT_Long    CheckSum_Adjust;
  454.72 +    FT_Long    Magic_Number;
  454.73 +
  454.74 +    FT_UShort  Flags;
  454.75 +    FT_UShort  Units_Per_EM;
  454.76 +
  454.77 +    FT_Long    Created [2];
  454.78 +    FT_Long    Modified[2];
  454.79 +
  454.80 +    FT_Short   xMin;
  454.81 +    FT_Short   yMin;
  454.82 +    FT_Short   xMax;
  454.83 +    FT_Short   yMax;
  454.84 +
  454.85 +    FT_UShort  Mac_Style;
  454.86 +    FT_UShort  Lowest_Rec_PPEM;
  454.87 +
  454.88 +    FT_Short   Font_Direction;
  454.89 +    FT_Short   Index_To_Loc_Format;
  454.90 +    FT_Short   Glyph_Data_Format;
  454.91 +
  454.92 +  } TT_Header;
  454.93 +
  454.94 +
  454.95 +  /*************************************************************************/
  454.96 +  /*                                                                       */
  454.97 +  /* <Struct>                                                              */
  454.98 +  /*    TT_HoriHeader                                                      */
  454.99 +  /*                                                                       */
 454.100 +  /* <Description>                                                         */
 454.101 +  /*    A structure used to model a TrueType horizontal header, the `hhea' */
 454.102 +  /*    table, as well as the corresponding horizontal metrics table,      */
 454.103 +  /*    i.e., the `hmtx' table.                                            */
 454.104 +  /*                                                                       */
 454.105 +  /* <Fields>                                                              */
 454.106 +  /*    Version                :: The table version.                       */
 454.107 +  /*                                                                       */
 454.108 +  /*    Ascender               :: The font's ascender, i.e., the distance  */
 454.109 +  /*                              from the baseline to the top-most of all */
 454.110 +  /*                              glyph points found in the font.          */
 454.111 +  /*                                                                       */
 454.112 +  /*                              This value is invalid in many fonts, as  */
 454.113 +  /*                              it is usually set by the font designer,  */
 454.114 +  /*                              and often reflects only a portion of the */
 454.115 +  /*                              glyphs found in the font (maybe ASCII).  */
 454.116 +  /*                                                                       */
 454.117 +  /*                              You should use the `sTypoAscender' field */
 454.118 +  /*                              of the OS/2 table instead if you want    */
 454.119 +  /*                              the correct one.                         */
 454.120 +  /*                                                                       */
 454.121 +  /*    Descender              :: The font's descender, i.e., the distance */
 454.122 +  /*                              from the baseline to the bottom-most of  */
 454.123 +  /*                              all glyph points found in the font.  It  */
 454.124 +  /*                              is negative.                             */
 454.125 +  /*                                                                       */
 454.126 +  /*                              This value is invalid in many fonts, as  */
 454.127 +  /*                              it is usually set by the font designer,  */
 454.128 +  /*                              and often reflects only a portion of the */
 454.129 +  /*                              glyphs found in the font (maybe ASCII).  */
 454.130 +  /*                                                                       */
 454.131 +  /*                              You should use the `sTypoDescender'      */
 454.132 +  /*                              field of the OS/2 table instead if you   */
 454.133 +  /*                              want the correct one.                    */
 454.134 +  /*                                                                       */
 454.135 +  /*    Line_Gap               :: The font's line gap, i.e., the distance  */
 454.136 +  /*                              to add to the ascender and descender to  */
 454.137 +  /*                              get the BTB, i.e., the                   */
 454.138 +  /*                              baseline-to-baseline distance for the    */
 454.139 +  /*                              font.                                    */
 454.140 +  /*                                                                       */
 454.141 +  /*    advance_Width_Max      :: This field is the maximum of all advance */
 454.142 +  /*                              widths found in the font.  It can be     */
 454.143 +  /*                              used to compute the maximum width of an  */
 454.144 +  /*                              arbitrary string of text.                */
 454.145 +  /*                                                                       */
 454.146 +  /*    min_Left_Side_Bearing  :: The minimum left side bearing of all     */
 454.147 +  /*                              glyphs within the font.                  */
 454.148 +  /*                                                                       */
 454.149 +  /*    min_Right_Side_Bearing :: The minimum right side bearing of all    */
 454.150 +  /*                              glyphs within the font.                  */
 454.151 +  /*                                                                       */
 454.152 +  /*    xMax_Extent            :: The maximum horizontal extent (i.e., the */
 454.153 +  /*                              `width' of a glyph's bounding box) for   */
 454.154 +  /*                              all glyphs in the font.                  */
 454.155 +  /*                                                                       */
 454.156 +  /*    caret_Slope_Rise       :: The rise coefficient of the cursor's     */
 454.157 +  /*                              slope of the cursor (slope=rise/run).    */
 454.158 +  /*                                                                       */
 454.159 +  /*    caret_Slope_Run        :: The run coefficient of the cursor's      */
 454.160 +  /*                              slope.                                   */
 454.161 +  /*                                                                       */
 454.162 +  /*    Reserved               :: 8~reserved bytes.                        */
 454.163 +  /*                                                                       */
 454.164 +  /*    metric_Data_Format     :: Always~0.                                */
 454.165 +  /*                                                                       */
 454.166 +  /*    number_Of_HMetrics     :: Number of HMetrics entries in the `hmtx' */
 454.167 +  /*                              table -- this value can be smaller than  */
 454.168 +  /*                              the total number of glyphs in the font.  */
 454.169 +  /*                                                                       */
 454.170 +  /*    long_metrics           :: A pointer into the `hmtx' table.         */
 454.171 +  /*                                                                       */
 454.172 +  /*    short_metrics          :: A pointer into the `hmtx' table.         */
 454.173 +  /*                                                                       */
 454.174 +  /* <Note>                                                                */
 454.175 +  /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
 454.176 +  /*               be identical except for the names of their fields which */
 454.177 +  /*               are different.                                          */
 454.178 +  /*                                                                       */
 454.179 +  /*               This ensures that a single function in the `ttload'     */
 454.180 +  /*               module is able to read both the horizontal and vertical */
 454.181 +  /*               headers.                                                */
 454.182 +  /*                                                                       */
 454.183 +  typedef struct  TT_HoriHeader_
 454.184 +  {
 454.185 +    FT_Fixed   Version;
 454.186 +    FT_Short   Ascender;
 454.187 +    FT_Short   Descender;
 454.188 +    FT_Short   Line_Gap;
 454.189 +
 454.190 +    FT_UShort  advance_Width_Max;      /* advance width maximum */
 454.191 +
 454.192 +    FT_Short   min_Left_Side_Bearing;  /* minimum left-sb       */
 454.193 +    FT_Short   min_Right_Side_Bearing; /* minimum right-sb      */
 454.194 +    FT_Short   xMax_Extent;            /* xmax extents          */
 454.195 +    FT_Short   caret_Slope_Rise;
 454.196 +    FT_Short   caret_Slope_Run;
 454.197 +    FT_Short   caret_Offset;
 454.198 +
 454.199 +    FT_Short   Reserved[4];
 454.200 +
 454.201 +    FT_Short   metric_Data_Format;
 454.202 +    FT_UShort  number_Of_HMetrics;
 454.203 +
 454.204 +    /* The following fields are not defined by the TrueType specification */
 454.205 +    /* but they are used to connect the metrics header to the relevant    */
 454.206 +    /* `HMTX' table.                                                      */
 454.207 +
 454.208 +    void*      long_metrics;
 454.209 +    void*      short_metrics;
 454.210 +
 454.211 +  } TT_HoriHeader;
 454.212 +
 454.213 +
 454.214 +  /*************************************************************************/
 454.215 +  /*                                                                       */
 454.216 +  /* <Struct>                                                              */
 454.217 +  /*    TT_VertHeader                                                      */
 454.218 +  /*                                                                       */
 454.219 +  /* <Description>                                                         */
 454.220 +  /*    A structure used to model a TrueType vertical header, the `vhea'   */
 454.221 +  /*    table, as well as the corresponding vertical metrics table, i.e.,  */
 454.222 +  /*    the `vmtx' table.                                                  */
 454.223 +  /*                                                                       */
 454.224 +  /* <Fields>                                                              */
 454.225 +  /*    Version                 :: The table version.                      */
 454.226 +  /*                                                                       */
 454.227 +  /*    Ascender                :: The font's ascender, i.e., the distance */
 454.228 +  /*                               from the baseline to the top-most of    */
 454.229 +  /*                               all glyph points found in the font.     */
 454.230 +  /*                                                                       */
 454.231 +  /*                               This value is invalid in many fonts, as */
 454.232 +  /*                               it is usually set by the font designer, */
 454.233 +  /*                               and often reflects only a portion of    */
 454.234 +  /*                               the glyphs found in the font (maybe     */
 454.235 +  /*                               ASCII).                                 */
 454.236 +  /*                                                                       */
 454.237 +  /*                               You should use the `sTypoAscender'      */
 454.238 +  /*                               field of the OS/2 table instead if you  */
 454.239 +  /*                               want the correct one.                   */
 454.240 +  /*                                                                       */
 454.241 +  /*    Descender               :: The font's descender, i.e., the         */
 454.242 +  /*                               distance from the baseline to the       */
 454.243 +  /*                               bottom-most of all glyph points found   */
 454.244 +  /*                               in the font.  It is negative.           */
 454.245 +  /*                                                                       */
 454.246 +  /*                               This value is invalid in many fonts, as */
 454.247 +  /*                               it is usually set by the font designer, */
 454.248 +  /*                               and often reflects only a portion of    */
 454.249 +  /*                               the glyphs found in the font (maybe     */
 454.250 +  /*                               ASCII).                                 */
 454.251 +  /*                                                                       */
 454.252 +  /*                               You should use the `sTypoDescender'     */
 454.253 +  /*                               field of the OS/2 table instead if you  */
 454.254 +  /*                               want the correct one.                   */
 454.255 +  /*                                                                       */
 454.256 +  /*    Line_Gap                :: The font's line gap, i.e., the distance */
 454.257 +  /*                               to add to the ascender and descender to */
 454.258 +  /*                               get the BTB, i.e., the                  */
 454.259 +  /*                               baseline-to-baseline distance for the   */
 454.260 +  /*                               font.                                   */
 454.261 +  /*                                                                       */
 454.262 +  /*    advance_Height_Max      :: This field is the maximum of all        */
 454.263 +  /*                               advance heights found in the font.  It  */
 454.264 +  /*                               can be used to compute the maximum      */
 454.265 +  /*                               height of an arbitrary string of text.  */
 454.266 +  /*                                                                       */
 454.267 +  /*    min_Top_Side_Bearing    :: The minimum top side bearing of all     */
 454.268 +  /*                               glyphs within the font.                 */
 454.269 +  /*                                                                       */
 454.270 +  /*    min_Bottom_Side_Bearing :: The minimum bottom side bearing of all  */
 454.271 +  /*                               glyphs within the font.                 */
 454.272 +  /*                                                                       */
 454.273 +  /*    yMax_Extent             :: The maximum vertical extent (i.e., the  */
 454.274 +  /*                               `height' of a glyph's bounding box) for */
 454.275 +  /*                               all glyphs in the font.                 */
 454.276 +  /*                                                                       */
 454.277 +  /*    caret_Slope_Rise        :: The rise coefficient of the cursor's    */
 454.278 +  /*                               slope of the cursor (slope=rise/run).   */
 454.279 +  /*                                                                       */
 454.280 +  /*    caret_Slope_Run         :: The run coefficient of the cursor's     */
 454.281 +  /*                               slope.                                  */
 454.282 +  /*                                                                       */
 454.283 +  /*    caret_Offset            :: The cursor's offset for slanted fonts.  */
 454.284 +  /*                               This value is `reserved' in vmtx        */
 454.285 +  /*                               version 1.0.                            */
 454.286 +  /*                                                                       */
 454.287 +  /*    Reserved                :: 8~reserved bytes.                       */
 454.288 +  /*                                                                       */
 454.289 +  /*    metric_Data_Format      :: Always~0.                               */
 454.290 +  /*                                                                       */
 454.291 +  /*    number_Of_HMetrics      :: Number of VMetrics entries in the       */
 454.292 +  /*                               `vmtx' table -- this value can be       */
 454.293 +  /*                               smaller than the total number of glyphs */
 454.294 +  /*                               in the font.                            */
 454.295 +  /*                                                                       */
 454.296 +  /*    long_metrics           :: A pointer into the `vmtx' table.         */
 454.297 +  /*                                                                       */
 454.298 +  /*    short_metrics          :: A pointer into the `vmtx' table.         */
 454.299 +  /*                                                                       */
 454.300 +  /* <Note>                                                                */
 454.301 +  /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
 454.302 +  /*               be identical except for the names of their fields which */
 454.303 +  /*               are different.                                          */
 454.304 +  /*                                                                       */
 454.305 +  /*               This ensures that a single function in the `ttload'     */
 454.306 +  /*               module is able to read both the horizontal and vertical */
 454.307 +  /*               headers.                                                */
 454.308 +  /*                                                                       */
 454.309 +  typedef struct  TT_VertHeader_
 454.310 +  {
 454.311 +    FT_Fixed   Version;
 454.312 +    FT_Short   Ascender;
 454.313 +    FT_Short   Descender;
 454.314 +    FT_Short   Line_Gap;
 454.315 +
 454.316 +    FT_UShort  advance_Height_Max;      /* advance height maximum */
 454.317 +
 454.318 +    FT_Short   min_Top_Side_Bearing;    /* minimum left-sb or top-sb       */
 454.319 +    FT_Short   min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb   */
 454.320 +    FT_Short   yMax_Extent;             /* xmax or ymax extents            */
 454.321 +    FT_Short   caret_Slope_Rise;
 454.322 +    FT_Short   caret_Slope_Run;
 454.323 +    FT_Short   caret_Offset;
 454.324 +
 454.325 +    FT_Short   Reserved[4];
 454.326 +
 454.327 +    FT_Short   metric_Data_Format;
 454.328 +    FT_UShort  number_Of_VMetrics;
 454.329 +
 454.330 +    /* The following fields are not defined by the TrueType specification */
 454.331 +    /* but they're used to connect the metrics header to the relevant     */
 454.332 +    /* `HMTX' or `VMTX' table.                                            */
 454.333 +
 454.334 +    void*      long_metrics;
 454.335 +    void*      short_metrics;
 454.336 +
 454.337 +  } TT_VertHeader;
 454.338 +
 454.339 +
 454.340 +  /*************************************************************************/
 454.341 +  /*                                                                       */
 454.342 +  /* <Struct>                                                              */
 454.343 +  /*    TT_OS2                                                             */
 454.344 +  /*                                                                       */
 454.345 +  /* <Description>                                                         */
 454.346 +  /*    A structure used to model a TrueType OS/2 table. This is the long  */
 454.347 +  /*    table version.  All fields comply to the TrueType specification.   */
 454.348 +  /*                                                                       */
 454.349 +  /*    Note that we now support old Mac fonts which do not include an     */
 454.350 +  /*    OS/2 table.  In this case, the `version' field is always set to    */
 454.351 +  /*    0xFFFF.                                                            */
 454.352 +  /*                                                                       */
 454.353 +  typedef struct  TT_OS2_
 454.354 +  {
 454.355 +    FT_UShort  version;                /* 0x0001 - more or 0xFFFF */
 454.356 +    FT_Short   xAvgCharWidth;
 454.357 +    FT_UShort  usWeightClass;
 454.358 +    FT_UShort  usWidthClass;
 454.359 +    FT_Short   fsType;
 454.360 +    FT_Short   ySubscriptXSize;
 454.361 +    FT_Short   ySubscriptYSize;
 454.362 +    FT_Short   ySubscriptXOffset;
 454.363 +    FT_Short   ySubscriptYOffset;
 454.364 +    FT_Short   ySuperscriptXSize;
 454.365 +    FT_Short   ySuperscriptYSize;
 454.366 +    FT_Short   ySuperscriptXOffset;
 454.367 +    FT_Short   ySuperscriptYOffset;
 454.368 +    FT_Short   yStrikeoutSize;
 454.369 +    FT_Short   yStrikeoutPosition;
 454.370 +    FT_Short   sFamilyClass;
 454.371 +
 454.372 +    FT_Byte    panose[10];
 454.373 +
 454.374 +    FT_ULong   ulUnicodeRange1;        /* Bits 0-31   */
 454.375 +    FT_ULong   ulUnicodeRange2;        /* Bits 32-63  */
 454.376 +    FT_ULong   ulUnicodeRange3;        /* Bits 64-95  */
 454.377 +    FT_ULong   ulUnicodeRange4;        /* Bits 96-127 */
 454.378 +
 454.379 +    FT_Char    achVendID[4];
 454.380 +
 454.381 +    FT_UShort  fsSelection;
 454.382 +    FT_UShort  usFirstCharIndex;
 454.383 +    FT_UShort  usLastCharIndex;
 454.384 +    FT_Short   sTypoAscender;
 454.385 +    FT_Short   sTypoDescender;
 454.386 +    FT_Short   sTypoLineGap;
 454.387 +    FT_UShort  usWinAscent;
 454.388 +    FT_UShort  usWinDescent;
 454.389 +
 454.390 +    /* only version 1 tables: */
 454.391 +
 454.392 +    FT_ULong   ulCodePageRange1;       /* Bits 0-31   */
 454.393 +    FT_ULong   ulCodePageRange2;       /* Bits 32-63  */
 454.394 +
 454.395 +    /* only version 2 tables: */
 454.396 +
 454.397 +    FT_Short   sxHeight;
 454.398 +    FT_Short   sCapHeight;
 454.399 +    FT_UShort  usDefaultChar;
 454.400 +    FT_UShort  usBreakChar;
 454.401 +    FT_UShort  usMaxContext;
 454.402 +
 454.403 +  } TT_OS2;
 454.404 +
 454.405 +
 454.406 +  /*************************************************************************/
 454.407 +  /*                                                                       */
 454.408 +  /* <Struct>                                                              */
 454.409 +  /*    TT_Postscript                                                      */
 454.410 +  /*                                                                       */
 454.411 +  /* <Description>                                                         */
 454.412 +  /*    A structure used to model a TrueType PostScript table.  All fields */
 454.413 +  /*    comply to the TrueType specification.  This structure does not     */
 454.414 +  /*    reference the PostScript glyph names, which can be nevertheless    */
 454.415 +  /*    accessed with the `ttpost' module.                                 */
 454.416 +  /*                                                                       */
 454.417 +  typedef struct  TT_Postscript_
 454.418 +  {
 454.419 +    FT_Fixed  FormatType;
 454.420 +    FT_Fixed  italicAngle;
 454.421 +    FT_Short  underlinePosition;
 454.422 +    FT_Short  underlineThickness;
 454.423 +    FT_ULong  isFixedPitch;
 454.424 +    FT_ULong  minMemType42;
 454.425 +    FT_ULong  maxMemType42;
 454.426 +    FT_ULong  minMemType1;
 454.427 +    FT_ULong  maxMemType1;
 454.428 +
 454.429 +    /* Glyph names follow in the file, but we don't   */
 454.430 +    /* load them by default.  See the ttpost.c file.  */
 454.431 +
 454.432 +  } TT_Postscript;
 454.433 +
 454.434 +
 454.435 +  /*************************************************************************/
 454.436 +  /*                                                                       */
 454.437 +  /* <Struct>                                                              */
 454.438 +  /*    TT_PCLT                                                            */
 454.439 +  /*                                                                       */
 454.440 +  /* <Description>                                                         */
 454.441 +  /*    A structure used to model a TrueType PCLT table.  All fields       */
 454.442 +  /*    comply to the TrueType specification.                              */
 454.443 +  /*                                                                       */
 454.444 +  typedef struct  TT_PCLT_
 454.445 +  {
 454.446 +    FT_Fixed   Version;
 454.447 +    FT_ULong   FontNumber;
 454.448 +    FT_UShort  Pitch;
 454.449 +    FT_UShort  xHeight;
 454.450 +    FT_UShort  Style;
 454.451 +    FT_UShort  TypeFamily;
 454.452 +    FT_UShort  CapHeight;
 454.453 +    FT_UShort  SymbolSet;
 454.454 +    FT_Char    TypeFace[16];
 454.455 +    FT_Char    CharacterComplement[8];
 454.456 +    FT_Char    FileName[6];
 454.457 +    FT_Char    StrokeWeight;
 454.458 +    FT_Char    WidthType;
 454.459 +    FT_Byte    SerifStyle;
 454.460 +    FT_Byte    Reserved;
 454.461 +
 454.462 +  } TT_PCLT;
 454.463 +
 454.464 +
 454.465 +  /*************************************************************************/
 454.466 +  /*                                                                       */
 454.467 +  /* <Struct>                                                              */
 454.468 +  /*    TT_MaxProfile                                                      */
 454.469 +  /*                                                                       */
 454.470 +  /* <Description>                                                         */
 454.471 +  /*    The maximum profile is a table containing many max values which    */
 454.472 +  /*    can be used to pre-allocate arrays.  This ensures that no memory   */
 454.473 +  /*    allocation occurs during a glyph load.                             */
 454.474 +  /*                                                                       */
 454.475 +  /* <Fields>                                                              */
 454.476 +  /*    version               :: The version number.                       */
 454.477 +  /*                                                                       */
 454.478 +  /*    numGlyphs             :: The number of glyphs in this TrueType     */
 454.479 +  /*                             font.                                     */
 454.480 +  /*                                                                       */
 454.481 +  /*    maxPoints             :: The maximum number of points in a         */
 454.482 +  /*                             non-composite TrueType glyph.  See also   */
 454.483 +  /*                             the structure element                     */
 454.484 +  /*                             `maxCompositePoints'.                     */
 454.485 +  /*                                                                       */
 454.486 +  /*    maxContours           :: The maximum number of contours in a       */
 454.487 +  /*                             non-composite TrueType glyph.  See also   */
 454.488 +  /*                             the structure element                     */
 454.489 +  /*                             `maxCompositeContours'.                   */
 454.490 +  /*                                                                       */
 454.491 +  /*    maxCompositePoints    :: The maximum number of points in a         */
 454.492 +  /*                             composite TrueType glyph.  See also the   */
 454.493 +  /*                             structure element `maxPoints'.            */
 454.494 +  /*                                                                       */
 454.495 +  /*    maxCompositeContours  :: The maximum number of contours in a       */
 454.496 +  /*                             composite TrueType glyph.  See also the   */
 454.497 +  /*                             structure element `maxContours'.          */
 454.498 +  /*                                                                       */
 454.499 +  /*    maxZones              :: The maximum number of zones used for      */
 454.500 +  /*                             glyph hinting.                            */
 454.501 +  /*                                                                       */
 454.502 +  /*    maxTwilightPoints     :: The maximum number of points in the       */
 454.503 +  /*                             twilight zone used for glyph hinting.     */
 454.504 +  /*                                                                       */
 454.505 +  /*    maxStorage            :: The maximum number of elements in the     */
 454.506 +  /*                             storage area used for glyph hinting.      */
 454.507 +  /*                                                                       */
 454.508 +  /*    maxFunctionDefs       :: The maximum number of function            */
 454.509 +  /*                             definitions in the TrueType bytecode for  */
 454.510 +  /*                             this font.                                */
 454.511 +  /*                                                                       */
 454.512 +  /*    maxInstructionDefs    :: The maximum number of instruction         */
 454.513 +  /*                             definitions in the TrueType bytecode for  */
 454.514 +  /*                             this font.                                */
 454.515 +  /*                                                                       */
 454.516 +  /*    maxStackElements      :: The maximum number of stack elements used */
 454.517 +  /*                             during bytecode interpretation.           */
 454.518 +  /*                                                                       */
 454.519 +  /*    maxSizeOfInstructions :: The maximum number of TrueType opcodes    */
 454.520 +  /*                             used for glyph hinting.                   */
 454.521 +  /*                                                                       */
 454.522 +  /*    maxComponentElements  :: The maximum number of simple (i.e., non-  */
 454.523 +  /*                             composite) glyphs in a composite glyph.   */
 454.524 +  /*                                                                       */
 454.525 +  /*    maxComponentDepth     :: The maximum nesting depth of composite    */
 454.526 +  /*                             glyphs.                                   */
 454.527 +  /*                                                                       */
 454.528 +  /* <Note>                                                                */
 454.529 +  /*    This structure is only used during font loading.                   */
 454.530 +  /*                                                                       */
 454.531 +  typedef struct  TT_MaxProfile_
 454.532 +  {
 454.533 +    FT_Fixed   version;
 454.534 +    FT_UShort  numGlyphs;
 454.535 +    FT_UShort  maxPoints;
 454.536 +    FT_UShort  maxContours;
 454.537 +    FT_UShort  maxCompositePoints;
 454.538 +    FT_UShort  maxCompositeContours;
 454.539 +    FT_UShort  maxZones;
 454.540 +    FT_UShort  maxTwilightPoints;
 454.541 +    FT_UShort  maxStorage;
 454.542 +    FT_UShort  maxFunctionDefs;
 454.543 +    FT_UShort  maxInstructionDefs;
 454.544 +    FT_UShort  maxStackElements;
 454.545 +    FT_UShort  maxSizeOfInstructions;
 454.546 +    FT_UShort  maxComponentElements;
 454.547 +    FT_UShort  maxComponentDepth;
 454.548 +
 454.549 +  } TT_MaxProfile;
 454.550 +
 454.551 +
 454.552 +  /*************************************************************************/
 454.553 +  /*                                                                       */
 454.554 +  /* <Enum>                                                                */
 454.555 +  /*    FT_Sfnt_Tag                                                        */
 454.556 +  /*                                                                       */
 454.557 +  /* <Description>                                                         */
 454.558 +  /*    An enumeration used to specify the index of an SFNT table.         */
 454.559 +  /*    Used in the @FT_Get_Sfnt_Table API function.                       */
 454.560 +  /*                                                                       */
 454.561 +  typedef enum  FT_Sfnt_Tag_
 454.562 +  {
 454.563 +    ft_sfnt_head = 0,    /* TT_Header     */
 454.564 +    ft_sfnt_maxp = 1,    /* TT_MaxProfile */
 454.565 +    ft_sfnt_os2  = 2,    /* TT_OS2        */
 454.566 +    ft_sfnt_hhea = 3,    /* TT_HoriHeader */
 454.567 +    ft_sfnt_vhea = 4,    /* TT_VertHeader */
 454.568 +    ft_sfnt_post = 5,    /* TT_Postscript */
 454.569 +    ft_sfnt_pclt = 6,    /* TT_PCLT       */
 454.570 +
 454.571 +    sfnt_max   /* internal end mark */
 454.572 +
 454.573 +  } FT_Sfnt_Tag;
 454.574 +
 454.575 +  /* */
 454.576 +
 454.577 +
 454.578 +  /*************************************************************************/
 454.579 +  /*                                                                       */
 454.580 +  /* <Function>                                                            */
 454.581 +  /*    FT_Get_Sfnt_Table                                                  */
 454.582 +  /*                                                                       */
 454.583 +  /* <Description>                                                         */
 454.584 +  /*    Return a pointer to a given SFNT table within a face.              */
 454.585 +  /*                                                                       */
 454.586 +  /* <Input>                                                               */
 454.587 +  /*    face :: A handle to the source.                                    */
 454.588 +  /*                                                                       */
 454.589 +  /*    tag  :: The index of the SFNT table.                               */
 454.590 +  /*                                                                       */
 454.591 +  /* <Return>                                                              */
 454.592 +  /*    A type-less pointer to the table.  This will be~0 in case of       */
 454.593 +  /*    error, or if the corresponding table was not found *OR* loaded     */
 454.594 +  /*    from the file.                                                     */
 454.595 +  /*                                                                       */
 454.596 +  /*    Use a typecast according to `tag' to access the structure          */
 454.597 +  /*    elements.                                                          */
 454.598 +  /*                                                                       */
 454.599 +  /* <Note>                                                                */
 454.600 +  /*    The table is owned by the face object and disappears with it.      */
 454.601 +  /*                                                                       */
 454.602 +  /*    This function is only useful to access SFNT tables that are loaded */
 454.603 +  /*    by the sfnt, truetype, and opentype drivers.  See @FT_Sfnt_Tag for */
 454.604 +  /*    a list.                                                            */
 454.605 +  /*                                                                       */
 454.606 +  FT_EXPORT( void* )
 454.607 +  FT_Get_Sfnt_Table( FT_Face      face,
 454.608 +                     FT_Sfnt_Tag  tag );
 454.609 +
 454.610 +
 454.611 + /**************************************************************************
 454.612 +  *
 454.613 +  * @function:
 454.614 +  *   FT_Load_Sfnt_Table
 454.615 +  *
 454.616 +  * @description:
 454.617 +  *   Load any font table into client memory.
 454.618 +  *
 454.619 +  * @input:
 454.620 +  *   face ::
 454.621 +  *     A handle to the source face.
 454.622 +  *
 454.623 +  *   tag ::
 454.624 +  *     The four-byte tag of the table to load.  Use the value~0 if you want
 454.625 +  *     to access the whole font file.  Otherwise, you can use one of the
 454.626 +  *     definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new
 454.627 +  *     one with @FT_MAKE_TAG.
 454.628 +  *
 454.629 +  *   offset ::
 454.630 +  *     The starting offset in the table (or file if tag == 0).
 454.631 +  *
 454.632 +  * @output:
 454.633 +  *   buffer ::
 454.634 +  *     The target buffer address.  The client must ensure that the memory
 454.635 +  *     array is big enough to hold the data.
 454.636 +  *
 454.637 +  * @inout:
 454.638 +  *   length ::
 454.639 +  *     If the `length' parameter is NULL, then try to load the whole table.
 454.640 +  *     Return an error code if it fails.
 454.641 +  *
 454.642 +  *     Else, if `*length' is~0, exit immediately while returning the
 454.643 +  *     table's (or file) full size in it.
 454.644 +  *
 454.645 +  *     Else the number of bytes to read from the table or file, from the
 454.646 +  *     starting offset.
 454.647 +  *
 454.648 +  * @return:
 454.649 +  *   FreeType error code.  0~means success.
 454.650 +  *
 454.651 +  * @note:
 454.652 +  *   If you need to determine the table's length you should first call this
 454.653 +  *   function with `*length' set to~0, as in the following example:
 454.654 +  *
 454.655 +  *     {
 454.656 +  *       FT_ULong  length = 0;
 454.657 +  *
 454.658 +  *
 454.659 +  *       error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length );
 454.660 +  *       if ( error ) { ... table does not exist ... }
 454.661 +  *
 454.662 +  *       buffer = malloc( length );
 454.663 +  *       if ( buffer == NULL ) { ... not enough memory ... }
 454.664 +  *
 454.665 +  *       error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length );
 454.666 +  *       if ( error ) { ... could not load table ... }
 454.667 +  *     }
 454.668 +  */
 454.669 +  FT_EXPORT( FT_Error )
 454.670 +  FT_Load_Sfnt_Table( FT_Face    face,
 454.671 +                      FT_ULong   tag,
 454.672 +                      FT_Long    offset,
 454.673 +                      FT_Byte*   buffer,
 454.674 +                      FT_ULong*  length );
 454.675 +
 454.676 +
 454.677 + /**************************************************************************
 454.678 +  *
 454.679 +  * @function:
 454.680 +  *   FT_Sfnt_Table_Info
 454.681 +  *
 454.682 +  * @description:
 454.683 +  *   Return information on an SFNT table.
 454.684 +  *
 454.685 +  * @input:
 454.686 +  *   face ::
 454.687 +  *     A handle to the source face.
 454.688 +  *
 454.689 +  *   table_index ::
 454.690 +  *     The index of an SFNT table.  The function returns
 454.691 +  *     FT_Err_Table_Missing for an invalid value.
 454.692 +  *
 454.693 +  * @output:
 454.694 +  *   tag ::
 454.695 +  *     The name tag of the SFNT table.
 454.696 +  *
 454.697 +  *   length ::
 454.698 +  *     The length of the SFNT table.
 454.699 +  *
 454.700 +  * @return:
 454.701 +  *   FreeType error code.  0~means success.
 454.702 +  *
 454.703 +  * @note:
 454.704 +  *   SFNT tables with length zero are treated as missing.
 454.705 +  *
 454.706 +  */
 454.707 +  FT_EXPORT( FT_Error )
 454.708 +  FT_Sfnt_Table_Info( FT_Face    face,
 454.709 +                      FT_UInt    table_index,
 454.710 +                      FT_ULong  *tag,
 454.711 +                      FT_ULong  *length );
 454.712 +
 454.713 +
 454.714 +  /*************************************************************************/
 454.715 +  /*                                                                       */
 454.716 +  /* <Function>                                                            */
 454.717 +  /*    FT_Get_CMap_Language_ID                                            */
 454.718 +  /*                                                                       */
 454.719 +  /* <Description>                                                         */
 454.720 +  /*    Return TrueType/sfnt specific cmap language ID.  Definitions of    */
 454.721 +  /*    language ID values are in `freetype/ttnameid.h'.                   */
 454.722 +  /*                                                                       */
 454.723 +  /* <Input>                                                               */
 454.724 +  /*    charmap ::                                                         */
 454.725 +  /*      The target charmap.                                              */
 454.726 +  /*                                                                       */
 454.727 +  /* <Return>                                                              */
 454.728 +  /*    The language ID of `charmap'.  If `charmap' doesn't belong to a    */
 454.729 +  /*    TrueType/sfnt face, just return~0 as the default value.            */
 454.730 +  /*                                                                       */
 454.731 +  FT_EXPORT( FT_ULong )
 454.732 +  FT_Get_CMap_Language_ID( FT_CharMap  charmap );
 454.733 +
 454.734 +
 454.735 +  /*************************************************************************/
 454.736 +  /*                                                                       */
 454.737 +  /* <Function>                                                            */
 454.738 +  /*    FT_Get_CMap_Format                                                 */
 454.739 +  /*                                                                       */
 454.740 +  /* <Description>                                                         */
 454.741 +  /*    Return TrueType/sfnt specific cmap format.                         */
 454.742 +  /*                                                                       */
 454.743 +  /* <Input>                                                               */
 454.744 +  /*    charmap ::                                                         */
 454.745 +  /*      The target charmap.                                              */
 454.746 +  /*                                                                       */
 454.747 +  /* <Return>                                                              */
 454.748 +  /*    The format of `charmap'.  If `charmap' doesn't belong to a         */
 454.749 +  /*    TrueType/sfnt face, return -1.                                     */
 454.750 +  /*                                                                       */
 454.751 +  FT_EXPORT( FT_Long )
 454.752 +  FT_Get_CMap_Format( FT_CharMap  charmap );
 454.753 +
 454.754 +  /* */
 454.755 +
 454.756 +
 454.757 +FT_END_HEADER
 454.758 +
 454.759 +#endif /* __TTTABLES_H__ */
 454.760 +
 454.761 +
 454.762 +/* END */
   455.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   455.2 +++ b/libs/ft2static/freetype/tttags.h	Sat Feb 01 19:58:19 2014 +0200
   455.3 @@ -0,0 +1,107 @@
   455.4 +/***************************************************************************/
   455.5 +/*                                                                         */
   455.6 +/*  tttags.h                                                               */
   455.7 +/*                                                                         */
   455.8 +/*    Tags for TrueType and OpenType tables (specification only).          */
   455.9 +/*                                                                         */
  455.10 +/*  Copyright 1996-2001, 2004, 2005, 2007, 2008 by                         */
  455.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  455.12 +/*                                                                         */
  455.13 +/*  This file is part of the FreeType project, and may only be used,       */
  455.14 +/*  modified, and distributed under the terms of the FreeType project      */
  455.15 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  455.16 +/*  this file you indicate that you have read the license and              */
  455.17 +/*  understand and accept it fully.                                        */
  455.18 +/*                                                                         */
  455.19 +/***************************************************************************/
  455.20 +
  455.21 +
  455.22 +#ifndef __TTAGS_H__
  455.23 +#define __TTAGS_H__
  455.24 +
  455.25 +
  455.26 +#include <ft2build.h>
  455.27 +#include FT_FREETYPE_H
  455.28 +
  455.29 +#ifdef FREETYPE_H
  455.30 +#error "freetype.h of FreeType 1 has been loaded!"
  455.31 +#error "Please fix the directory search order for header files"
  455.32 +#error "so that freetype.h of FreeType 2 is found first."
  455.33 +#endif
  455.34 +
  455.35 +
  455.36 +FT_BEGIN_HEADER
  455.37 +
  455.38 +
  455.39 +#define TTAG_avar  FT_MAKE_TAG( 'a', 'v', 'a', 'r' )
  455.40 +#define TTAG_BASE  FT_MAKE_TAG( 'B', 'A', 'S', 'E' )
  455.41 +#define TTAG_bdat  FT_MAKE_TAG( 'b', 'd', 'a', 't' )
  455.42 +#define TTAG_BDF   FT_MAKE_TAG( 'B', 'D', 'F', ' ' )
  455.43 +#define TTAG_bhed  FT_MAKE_TAG( 'b', 'h', 'e', 'd' )
  455.44 +#define TTAG_bloc  FT_MAKE_TAG( 'b', 'l', 'o', 'c' )
  455.45 +#define TTAG_bsln  FT_MAKE_TAG( 'b', 's', 'l', 'n' )
  455.46 +#define TTAG_CFF   FT_MAKE_TAG( 'C', 'F', 'F', ' ' )
  455.47 +#define TTAG_CID   FT_MAKE_TAG( 'C', 'I', 'D', ' ' )
  455.48 +#define TTAG_cmap  FT_MAKE_TAG( 'c', 'm', 'a', 'p' )
  455.49 +#define TTAG_cvar  FT_MAKE_TAG( 'c', 'v', 'a', 'r' )
  455.50 +#define TTAG_cvt   FT_MAKE_TAG( 'c', 'v', 't', ' ' )
  455.51 +#define TTAG_DSIG  FT_MAKE_TAG( 'D', 'S', 'I', 'G' )
  455.52 +#define TTAG_EBDT  FT_MAKE_TAG( 'E', 'B', 'D', 'T' )
  455.53 +#define TTAG_EBLC  FT_MAKE_TAG( 'E', 'B', 'L', 'C' )
  455.54 +#define TTAG_EBSC  FT_MAKE_TAG( 'E', 'B', 'S', 'C' )
  455.55 +#define TTAG_feat  FT_MAKE_TAG( 'f', 'e', 'a', 't' )
  455.56 +#define TTAG_FOND  FT_MAKE_TAG( 'F', 'O', 'N', 'D' )
  455.57 +#define TTAG_fpgm  FT_MAKE_TAG( 'f', 'p', 'g', 'm' )
  455.58 +#define TTAG_fvar  FT_MAKE_TAG( 'f', 'v', 'a', 'r' )
  455.59 +#define TTAG_gasp  FT_MAKE_TAG( 'g', 'a', 's', 'p' )
  455.60 +#define TTAG_GDEF  FT_MAKE_TAG( 'G', 'D', 'E', 'F' )
  455.61 +#define TTAG_glyf  FT_MAKE_TAG( 'g', 'l', 'y', 'f' )
  455.62 +#define TTAG_GPOS  FT_MAKE_TAG( 'G', 'P', 'O', 'S' )
  455.63 +#define TTAG_GSUB  FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
  455.64 +#define TTAG_gvar  FT_MAKE_TAG( 'g', 'v', 'a', 'r' )
  455.65 +#define TTAG_hdmx  FT_MAKE_TAG( 'h', 'd', 'm', 'x' )
  455.66 +#define TTAG_head  FT_MAKE_TAG( 'h', 'e', 'a', 'd' )
  455.67 +#define TTAG_hhea  FT_MAKE_TAG( 'h', 'h', 'e', 'a' )
  455.68 +#define TTAG_hmtx  FT_MAKE_TAG( 'h', 'm', 't', 'x' )
  455.69 +#define TTAG_JSTF  FT_MAKE_TAG( 'J', 'S', 'T', 'F' )
  455.70 +#define TTAG_just  FT_MAKE_TAG( 'j', 'u', 's', 't' )
  455.71 +#define TTAG_kern  FT_MAKE_TAG( 'k', 'e', 'r', 'n' )
  455.72 +#define TTAG_lcar  FT_MAKE_TAG( 'l', 'c', 'a', 'r' )
  455.73 +#define TTAG_loca  FT_MAKE_TAG( 'l', 'o', 'c', 'a' )
  455.74 +#define TTAG_LTSH  FT_MAKE_TAG( 'L', 'T', 'S', 'H' )
  455.75 +#define TTAG_LWFN  FT_MAKE_TAG( 'L', 'W', 'F', 'N' )
  455.76 +#define TTAG_MATH  FT_MAKE_TAG( 'M', 'A', 'T', 'H' )
  455.77 +#define TTAG_maxp  FT_MAKE_TAG( 'm', 'a', 'x', 'p' )
  455.78 +#define TTAG_META  FT_MAKE_TAG( 'M', 'E', 'T', 'A' )
  455.79 +#define TTAG_MMFX  FT_MAKE_TAG( 'M', 'M', 'F', 'X' )
  455.80 +#define TTAG_MMSD  FT_MAKE_TAG( 'M', 'M', 'S', 'D' )
  455.81 +#define TTAG_mort  FT_MAKE_TAG( 'm', 'o', 'r', 't' )
  455.82 +#define TTAG_morx  FT_MAKE_TAG( 'm', 'o', 'r', 'x' )
  455.83 +#define TTAG_name  FT_MAKE_TAG( 'n', 'a', 'm', 'e' )
  455.84 +#define TTAG_opbd  FT_MAKE_TAG( 'o', 'p', 'b', 'd' )
  455.85 +#define TTAG_OS2   FT_MAKE_TAG( 'O', 'S', '/', '2' )
  455.86 +#define TTAG_OTTO  FT_MAKE_TAG( 'O', 'T', 'T', 'O' )
  455.87 +#define TTAG_PCLT  FT_MAKE_TAG( 'P', 'C', 'L', 'T' )
  455.88 +#define TTAG_POST  FT_MAKE_TAG( 'P', 'O', 'S', 'T' )
  455.89 +#define TTAG_post  FT_MAKE_TAG( 'p', 'o', 's', 't' )
  455.90 +#define TTAG_prep  FT_MAKE_TAG( 'p', 'r', 'e', 'p' )
  455.91 +#define TTAG_prop  FT_MAKE_TAG( 'p', 'r', 'o', 'p' )
  455.92 +#define TTAG_sfnt  FT_MAKE_TAG( 's', 'f', 'n', 't' )
  455.93 +#define TTAG_SING  FT_MAKE_TAG( 'S', 'I', 'N', 'G' )
  455.94 +#define TTAG_trak  FT_MAKE_TAG( 't', 'r', 'a', 'k' )
  455.95 +#define TTAG_true  FT_MAKE_TAG( 't', 'r', 'u', 'e' )
  455.96 +#define TTAG_ttc   FT_MAKE_TAG( 't', 't', 'c', ' ' )
  455.97 +#define TTAG_ttcf  FT_MAKE_TAG( 't', 't', 'c', 'f' )
  455.98 +#define TTAG_TYP1  FT_MAKE_TAG( 'T', 'Y', 'P', '1' )
  455.99 +#define TTAG_typ1  FT_MAKE_TAG( 't', 'y', 'p', '1' )
 455.100 +#define TTAG_VDMX  FT_MAKE_TAG( 'V', 'D', 'M', 'X' )
 455.101 +#define TTAG_vhea  FT_MAKE_TAG( 'v', 'h', 'e', 'a' )
 455.102 +#define TTAG_vmtx  FT_MAKE_TAG( 'v', 'm', 't', 'x' )
 455.103 +
 455.104 +
 455.105 +FT_END_HEADER
 455.106 +
 455.107 +#endif /* __TTAGS_H__ */
 455.108 +
 455.109 +
 455.110 +/* END */
   456.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   456.2 +++ b/libs/ft2static/freetype/ttunpat.h	Sat Feb 01 19:58:19 2014 +0200
   456.3 @@ -0,0 +1,59 @@
   456.4 +/***************************************************************************/
   456.5 +/*                                                                         */
   456.6 +/*  ttunpat.h                                                              */
   456.7 +/*                                                                         */
   456.8 +/*    Definitions for the unpatented TrueType hinting system               */
   456.9 +/*                                                                         */
  456.10 +/*  Copyright 2003, 2006 by                                                */
  456.11 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  456.12 +/*                                                                         */
  456.13 +/*  Written by Graham Asher <graham.asher@btinternet.com>                  */
  456.14 +/*                                                                         */
  456.15 +/*  This file is part of the FreeType project, and may only be used,       */
  456.16 +/*  modified, and distributed under the terms of the FreeType project      */
  456.17 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  456.18 +/*  this file you indicate that you have read the license and              */
  456.19 +/*  understand and accept it fully.                                        */
  456.20 +/*                                                                         */
  456.21 +/***************************************************************************/
  456.22 +
  456.23 +
  456.24 +#ifndef __TTUNPAT_H__
  456.25 +#define __TTUNPAT_H__
  456.26 +
  456.27 +
  456.28 +#include <ft2build.h>
  456.29 +#include FT_FREETYPE_H
  456.30 +
  456.31 +#ifdef FREETYPE_H
  456.32 +#error "freetype.h of FreeType 1 has been loaded!"
  456.33 +#error "Please fix the directory search order for header files"
  456.34 +#error "so that freetype.h of FreeType 2 is found first."
  456.35 +#endif
  456.36 +
  456.37 +
  456.38 +FT_BEGIN_HEADER
  456.39 +
  456.40 +
  456.41 + /***************************************************************************
  456.42 +  *
  456.43 +  * @constant:
  456.44 +  *   FT_PARAM_TAG_UNPATENTED_HINTING
  456.45 +  *
  456.46 +  * @description:
  456.47 +  *   A constant used as the tag of an @FT_Parameter structure to indicate
  456.48 +  *   that unpatented methods only should be used by the TrueType bytecode
  456.49 +  *   interpreter for a typeface opened by @FT_Open_Face.
  456.50 +  *
  456.51 +  */
  456.52 +#define FT_PARAM_TAG_UNPATENTED_HINTING  FT_MAKE_TAG( 'u', 'n', 'p', 'a' )
  456.53 +
  456.54 + /* */
  456.55 +
  456.56 +FT_END_HEADER
  456.57 +
  456.58 +
  456.59 +#endif /* __TTUNPAT_H__ */
  456.60 +
  456.61 +
  456.62 +/* END */
   457.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   457.2 +++ b/libs/ft2static/ft2build.h	Sat Feb 01 19:58:19 2014 +0200
   457.3 @@ -0,0 +1,39 @@
   457.4 +/***************************************************************************/
   457.5 +/*                                                                         */
   457.6 +/*  ft2build.h                                                             */
   457.7 +/*                                                                         */
   457.8 +/*    FreeType 2 build and setup macros.                                   */
   457.9 +/*    (Generic version)                                                    */
  457.10 +/*                                                                         */
  457.11 +/*  Copyright 1996-2001, 2006 by                                           */
  457.12 +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  457.13 +/*                                                                         */
  457.14 +/*  This file is part of the FreeType project, and may only be used,       */
  457.15 +/*  modified, and distributed under the terms of the FreeType project      */
  457.16 +/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  457.17 +/*  this file you indicate that you have read the license and              */
  457.18 +/*  understand and accept it fully.                                        */
  457.19 +/*                                                                         */
  457.20 +/***************************************************************************/
  457.21 +
  457.22 +
  457.23 +  /*************************************************************************/
  457.24 +  /*                                                                       */
  457.25 +  /* This file corresponds to the default `ft2build.h' file for            */
  457.26 +  /* FreeType 2.  It uses the `freetype' include root.                     */
  457.27 +  /*                                                                       */
  457.28 +  /* Note that specific platforms might use a different configuration.     */
  457.29 +  /* See builds/unix/ft2unix.h for an example.                             */
  457.30 +  /*                                                                       */
  457.31 +  /*************************************************************************/
  457.32 +
  457.33 +
  457.34 +#ifndef __FT2_BUILD_GENERIC_H__
  457.35 +#define __FT2_BUILD_GENERIC_H__
  457.36 +
  457.37 +#include <freetype/config/ftheader.h>
  457.38 +
  457.39 +#endif /* __FT2_BUILD_GENERIC_H__ */
  457.40 +
  457.41 +
  457.42 +/* END */
   458.1 Binary file libs/ft2static/libFreetype2.a has changed
   459.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   459.2 +++ b/libs/imago/conv.c	Sat Feb 01 19:58:19 2014 +0200
   459.3 @@ -0,0 +1,260 @@
   459.4 +/*
   459.5 +libimago - a multi-format image file input/output library.
   459.6 +Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org>
   459.7 +
   459.8 +This program is free software: you can redistribute it and/or modify
   459.9 +it under the terms of the GNU Lesser General Public License as published
  459.10 +by the Free Software Foundation, either version 3 of the License, or
  459.11 +(at your option) any later version.
  459.12 +
  459.13 +This program is distributed in the hope that it will be useful,
  459.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  459.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  459.16 +GNU Lesser General Public License for more details.
  459.17 +
  459.18 +You should have received a copy of the GNU Lesser General Public License
  459.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  459.20 +*/
  459.21 +#include <string.h>
  459.22 +#include "imago2.h"
  459.23 +
  459.24 +/* pixel-format conversions are sub-optimal at the moment to avoid
  459.25 + * writing a lot of code. optimize at some point ?
  459.26 + */
  459.27 +
  459.28 +#define CLAMP(x, a, b)	((x) < (a) ? (a) : ((x) > (b) ? (b) : (x)))
  459.29 +
  459.30 +struct pixel {
  459.31 +	float r, g, b, a;
  459.32 +};
  459.33 +
  459.34 +static void unpack_grey8(struct pixel *unp, void *pptr, int count);
  459.35 +static void unpack_rgb24(struct pixel *unp, void *pptr, int count);
  459.36 +static void unpack_rgba32(struct pixel *unp, void *pptr, int count);
  459.37 +static void unpack_greyf(struct pixel *unp, void *pptr, int count);
  459.38 +static void unpack_rgbf(struct pixel *unp, void *pptr, int count);
  459.39 +static void unpack_rgbaf(struct pixel *unp, void *pptr, int count);
  459.40 +
  459.41 +static void pack_grey8(void *pptr, struct pixel *unp, int count);
  459.42 +static void pack_rgb24(void *pptr, struct pixel *unp, int count);
  459.43 +static void pack_rgba32(void *pptr, struct pixel *unp, int count);
  459.44 +static void pack_greyf(void *pptr, struct pixel *unp, int count);
  459.45 +static void pack_rgbf(void *pptr, struct pixel *unp, int count);
  459.46 +static void pack_rgbaf(void *pptr, struct pixel *unp, int count);
  459.47 +
  459.48 +/* XXX keep in sync with enum img_fmt at imago2.h */
  459.49 +static void (*unpack[])(struct pixel*, void*, int) = {
  459.50 +	unpack_grey8,
  459.51 +	unpack_rgb24,
  459.52 +	unpack_rgba32,
  459.53 +	unpack_greyf,
  459.54 +	unpack_rgbf,
  459.55 +	unpack_rgbaf
  459.56 +};
  459.57 +
  459.58 +/* XXX keep in sync with enum img_fmt at imago2.h */
  459.59 +static void (*pack[])(void*, struct pixel*, int) = {
  459.60 +	pack_grey8,
  459.61 +	pack_rgb24,
  459.62 +	pack_rgba32,
  459.63 +	pack_greyf,
  459.64 +	pack_rgbf,
  459.65 +	pack_rgbaf
  459.66 +};
  459.67 +
  459.68 +
  459.69 +int img_convert(struct img_pixmap *img, enum img_fmt tofmt)
  459.70 +{
  459.71 +	struct pixel pbuf[8];
  459.72 +	int bufsz = (img->width & 7) == 0 ? 8 : ((img->width & 3) == 0 ? 4 : 1);
  459.73 +	int i, num_pix = img->width * img->height;
  459.74 +	int num_iter = num_pix / bufsz;
  459.75 +	char *sptr, *dptr;
  459.76 +	struct img_pixmap nimg;
  459.77 +
  459.78 +	if(img->fmt == tofmt) {
  459.79 +		return 0;	/* nothing to do */
  459.80 +	}
  459.81 +
  459.82 +	img_init(&nimg);
  459.83 +	if(img_set_pixels(&nimg, img->width, img->height, tofmt, 0) == -1) {
  459.84 +		img_destroy(&nimg);
  459.85 +		return -1;
  459.86 +	}
  459.87 +
  459.88 +	sptr = img->pixels;
  459.89 +	dptr = nimg.pixels;
  459.90 +
  459.91 +	for(i=0; i<num_iter; i++) {
  459.92 +		unpack[img->fmt](pbuf, sptr, bufsz);
  459.93 +		pack[tofmt](dptr, pbuf, bufsz);
  459.94 +
  459.95 +		sptr += bufsz * img->pixelsz;
  459.96 +		dptr += bufsz * nimg.pixelsz;
  459.97 +	}
  459.98 +
  459.99 +	img_copy(img, &nimg);
 459.100 +	img_destroy(&nimg);
 459.101 +	return 0;
 459.102 +}
 459.103 +
 459.104 +/* the following functions *could* benefit from SIMD */
 459.105 +
 459.106 +static void unpack_grey8(struct pixel *unp, void *pptr, int count)
 459.107 +{
 459.108 +	int i;
 459.109 +	unsigned char *pix = pptr;
 459.110 +
 459.111 +	for(i=0; i<count; i++) {
 459.112 +		unp->r = unp->g = unp->b = (float)*pix++ / 255.0;
 459.113 +		unp->a = 1.0;
 459.114 +		unp++;
 459.115 +	}
 459.116 +}
 459.117 +
 459.118 +static void unpack_rgb24(struct pixel *unp, void *pptr, int count)
 459.119 +{
 459.120 +	int i;
 459.121 +	unsigned char *pix = pptr;
 459.122 +
 459.123 +	for(i=0; i<count; i++) {
 459.124 +		unp->r = (float)*pix++ / 255.0;
 459.125 +		unp->g = (float)*pix++ / 255.0;
 459.126 +		unp->b = (float)*pix++ / 255.0;
 459.127 +		unp->a = 1.0;
 459.128 +		unp++;
 459.129 +	}
 459.130 +}
 459.131 +
 459.132 +static void unpack_rgba32(struct pixel *unp, void *pptr, int count)
 459.133 +{
 459.134 +	int i;
 459.135 +	unsigned char *pix = pptr;
 459.136 +
 459.137 +	for(i=0; i<count; i++) {
 459.138 +		unp->r = (float)*pix++ / 255.0;
 459.139 +		unp->g = (float)*pix++ / 255.0;
 459.140 +		unp->b = (float)*pix++ / 255.0;
 459.141 +		unp->a = (float)*pix++ / 255.0;
 459.142 +		unp++;
 459.143 +	}
 459.144 +}
 459.145 +
 459.146 +static void unpack_greyf(struct pixel *unp, void *pptr, int count)
 459.147 +{
 459.148 +	int i;
 459.149 +	float *pix = pptr;
 459.150 +
 459.151 +	for(i=0; i<count; i++) {
 459.152 +		unp->r = unp->g = unp->b = *pix++;
 459.153 +		unp->a = 1.0;
 459.154 +		unp++;
 459.155 +	}
 459.156 +}
 459.157 +
 459.158 +static void unpack_rgbf(struct pixel *unp, void *pptr, int count)
 459.159 +{
 459.160 +	int i;
 459.161 +	float *pix = pptr;
 459.162 +
 459.163 +	for(i=0; i<count; i++) {
 459.164 +		unp->r = *pix++;
 459.165 +		unp->g = *pix++;
 459.166 +		unp->b = *pix++;
 459.167 +		unp->a = 1.0;
 459.168 +		unp++;
 459.169 +	}
 459.170 +}
 459.171 +
 459.172 +static void unpack_rgbaf(struct pixel *unp, void *pptr, int count)
 459.173 +{
 459.174 +	int i;
 459.175 +	float *pix = pptr;
 459.176 +
 459.177 +	for(i=0; i<count; i++) {
 459.178 +		unp->r = *pix++;
 459.179 +		unp->g = *pix++;
 459.180 +		unp->b = *pix++;
 459.181 +		unp->a = *pix++;
 459.182 +		unp++;
 459.183 +	}
 459.184 +}
 459.185 +
 459.186 +
 459.187 +static void pack_grey8(void *pptr, struct pixel *unp, int count)
 459.188 +{
 459.189 +	int i;
 459.190 +	unsigned char *pix = pptr;
 459.191 +
 459.192 +	for(i=0; i<count; i++) {
 459.193 +		int lum = (int)(255.0 * (unp->r + unp->g + unp->b) / 3.0);
 459.194 +		*pix++ = CLAMP(lum, 0, 255);
 459.195 +		unp++;
 459.196 +	}
 459.197 +}
 459.198 +
 459.199 +static void pack_rgb24(void *pptr, struct pixel *unp, int count)
 459.200 +{
 459.201 +	int i;
 459.202 +	unsigned char *pix = pptr;
 459.203 +
 459.204 +	for(i=0; i<count; i++) {
 459.205 +		int r = (int)(unp->r * 255.0);
 459.206 +		int g = (int)(unp->g * 255.0);
 459.207 +		int b = (int)(unp->b * 255.0);
 459.208 +
 459.209 +		*pix++ = CLAMP(r, 0, 255);
 459.210 +		*pix++ = CLAMP(g, 0, 255);
 459.211 +		*pix++ = CLAMP(b, 0, 255);
 459.212 +		unp++;
 459.213 +	}
 459.214 +}
 459.215 +
 459.216 +static void pack_rgba32(void *pptr, struct pixel *unp, int count)
 459.217 +{
 459.218 +	int i;
 459.219 +	unsigned char *pix = pptr;
 459.220 +
 459.221 +	for(i=0; i<count; i++) {
 459.222 +		int r = (int)(unp->r * 255.0);
 459.223 +		int g = (int)(unp->g * 255.0);
 459.224 +		int b = (int)(unp->b * 255.0);
 459.225 +		int a = (int)(unp->a * 255.0);
 459.226 +
 459.227 +		*pix++ = CLAMP(r, 0, 255);
 459.228 +		*pix++ = CLAMP(g, 0, 255);
 459.229 +		*pix++ = CLAMP(b, 0, 255);
 459.230 +		*pix++ = CLAMP(a, 0, 255);
 459.231 +		unp++;
 459.232 +	}
 459.233 +}
 459.234 +
 459.235 +static void pack_greyf(void *pptr, struct pixel *unp, int count)
 459.236 +{
 459.237 +	int i;
 459.238 +	float *pix = pptr;
 459.239 +
 459.240 +	for(i=0; i<count; i++) {
 459.241 +		*pix++ = (unp->r + unp->g + unp->b) / 3.0;
 459.242 +		unp++;
 459.243 +	}
 459.244 +}
 459.245 +
 459.246 +static void pack_rgbf(void *pptr, struct pixel *unp, int count)
 459.247 +{
 459.248 +	int i;
 459.249 +	float *pix = pptr;
 459.250 +
 459.251 +	for(i=0; i<count; i++) {
 459.252 +		*pix++ = unp->r;
 459.253 +		*pix++ = unp->g;
 459.254 +		*pix++ = unp->b;
 459.255 +		unp++;
 459.256 +	}
 459.257 +}
 459.258 +
 459.259 +static void pack_rgbaf(void *pptr, struct pixel *unp, int count)
 459.260 +{
 459.261 +	memcpy(pptr, unp, count * sizeof *unp);
 459.262 +}
 459.263 +
   460.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   460.2 +++ b/libs/imago/file_jpeg.c	Sat Feb 01 19:58:19 2014 +0200
   460.3 @@ -0,0 +1,294 @@
   460.4 +/*
   460.5 +libimago - a multi-format image file input/output library.
   460.6 +Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org>
   460.7 +
   460.8 +This program is free software: you can redistribute it and/or modify
   460.9 +it under the terms of the GNU Lesser General Public License as published
  460.10 +by the Free Software Foundation, either version 3 of the License, or
  460.11 +(at your option) any later version.
  460.12 +
  460.13 +This program is distributed in the hope that it will be useful,
  460.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  460.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  460.16 +GNU Lesser General Public License for more details.
  460.17 +
  460.18 +You should have received a copy of the GNU Lesser General Public License
  460.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  460.20 +*/
  460.21 +
  460.22 +/* -- JPEG module -- */
  460.23 +
  460.24 +#include <stdio.h>
  460.25 +#include <stdlib.h>
  460.26 +#include <string.h>
  460.27 +
  460.28 +#ifdef WIN32
  460.29 +#include <windows.h>
  460.30 +#define HAVE_BOOLEAN
  460.31 +#endif
  460.32 +
  460.33 +#include <jpeglib.h>
  460.34 +#include "imago2.h"
  460.35 +#include "ftype_module.h"
  460.36 +
  460.37 +#define INPUT_BUF_SIZE	512
  460.38 +#define OUTPUT_BUF_SIZE	512
  460.39 +
  460.40 +/* data source manager: adapted from jdatasrc.c */
  460.41 +struct src_mgr {
  460.42 +	struct jpeg_source_mgr pub;
  460.43 +
  460.44 +	struct img_io *io;
  460.45 +	unsigned char buffer[INPUT_BUF_SIZE];
  460.46 +	int start_of_file;
  460.47 +};
  460.48 +
  460.49 +/* data destination manager: adapted from jdatadst.c */
  460.50 +struct dst_mgr {
  460.51 +	struct jpeg_destination_mgr pub;
  460.52 +
  460.53 +	struct img_io *io;
  460.54 +	unsigned char buffer[OUTPUT_BUF_SIZE];
  460.55 +};
  460.56 +
  460.57 +static int check(struct img_io *io);
  460.58 +static int read(struct img_pixmap *img, struct img_io *io);
  460.59 +static int write(struct img_pixmap *img, struct img_io *io);
  460.60 +
  460.61 +/* read source functions */
  460.62 +static void init_source(j_decompress_ptr jd);
  460.63 +static boolean fill_input_buffer(j_decompress_ptr jd);
  460.64 +static void skip_input_data(j_decompress_ptr jd, long num_bytes);
  460.65 +static void term_source(j_decompress_ptr jd);
  460.66 +
  460.67 +/* write destination functions */
  460.68 +static void init_destination(j_compress_ptr jc);
  460.69 +static boolean empty_output_buffer(j_compress_ptr jc);
  460.70 +static void term_destination(j_compress_ptr jc);
  460.71 +
  460.72 +int img_register_jpeg(void)
  460.73 +{
  460.74 +	static struct ftype_module mod = {".jpg", check, read, write};
  460.75 +	return img_register_module(&mod);
  460.76 +}
  460.77 +
  460.78 +
  460.79 +static int check(struct img_io *io)
  460.80 +{
  460.81 +	unsigned char sig[10];
  460.82 +
  460.83 +	long pos = io->seek(0, SEEK_CUR, io->uptr);
  460.84 +
  460.85 +	if(io->read(sig, 10, io->uptr) < 10) {
  460.86 +		io->seek(pos, SEEK_SET, io->uptr);
  460.87 +		return -1;
  460.88 +	}
  460.89 +
  460.90 +	if(memcmp(sig, "\xff\xd8\xff\xe0", 4) != 0 && memcmp(sig, "\xff\xd8\xff\xe1", 4) != 0
  460.91 +			&& memcmp(sig + 6, "JFIF", 4) != 0) {
  460.92 +		io->seek(pos, SEEK_SET, io->uptr);
  460.93 +		return -1;
  460.94 +	}
  460.95 +	io->seek(pos, SEEK_SET, io->uptr);
  460.96 +	return 0;
  460.97 +}
  460.98 +
  460.99 +static int read(struct img_pixmap *img, struct img_io *io)
 460.100 +{
 460.101 +	int i, nlines = 0;
 460.102 +	struct jpeg_decompress_struct cinfo;
 460.103 +	struct jpeg_error_mgr jerr;
 460.104 +	struct src_mgr src;
 460.105 +	unsigned char **scanlines;
 460.106 +
 460.107 +	io->seek(0, SEEK_CUR, io->uptr);
 460.108 +
 460.109 +	cinfo.err = jpeg_std_error(&jerr);	/* XXX change... */
 460.110 +	jpeg_create_decompress(&cinfo);
 460.111 +
 460.112 +	src.pub.init_source = init_source;
 460.113 +	src.pub.fill_input_buffer = fill_input_buffer;
 460.114 +	src.pub.skip_input_data = skip_input_data;
 460.115 +	src.pub.resync_to_restart = jpeg_resync_to_restart;
 460.116 +	src.pub.term_source = term_source;
 460.117 +	src.pub.next_input_byte = 0;
 460.118 +	src.pub.bytes_in_buffer = 0;
 460.119 +	src.io = io;
 460.120 +	cinfo.src = (struct jpeg_source_mgr*)&src;
 460.121 +
 460.122 +	jpeg_read_header(&cinfo, 1);
 460.123 +	cinfo.out_color_space = JCS_RGB;
 460.124 +
 460.125 +	if(img_set_pixels(img, cinfo.image_width, cinfo.image_height, IMG_FMT_RGB24, 0) == -1) {
 460.126 +		jpeg_destroy_decompress(&cinfo);
 460.127 +		return -1;
 460.128 +	}
 460.129 +
 460.130 +	if(!(scanlines = malloc(img->height * sizeof *scanlines))) {
 460.131 +		jpeg_destroy_decompress(&cinfo);
 460.132 +		return -1;
 460.133 +	}
 460.134 +	scanlines[0] = img->pixels;
 460.135 +	for(i=1; i<img->height; i++) {
 460.136 +		scanlines[i] = scanlines[i - 1] + img->width * img->pixelsz;
 460.137 +	}
 460.138 +
 460.139 +	jpeg_start_decompress(&cinfo);
 460.140 +	while(nlines < img->height) {
 460.141 +		int res = jpeg_read_scanlines(&cinfo, scanlines + nlines, img->height - nlines);
 460.142 +		nlines += res;
 460.143 +	}
 460.144 +	jpeg_finish_decompress(&cinfo);
 460.145 +	jpeg_destroy_decompress(&cinfo);
 460.146 +
 460.147 +	free(scanlines);
 460.148 +	return 0;
 460.149 +}
 460.150 +
 460.151 +static int write(struct img_pixmap *img, struct img_io *io)
 460.152 +{
 460.153 +	int i, nlines = 0;
 460.154 +	struct jpeg_compress_struct cinfo;
 460.155 +	struct jpeg_error_mgr jerr;
 460.156 +	struct dst_mgr dest;
 460.157 +	struct img_pixmap tmpimg;
 460.158 +	unsigned char **scanlines;
 460.159 +
 460.160 +	img_init(&tmpimg);
 460.161 +
 460.162 +	if(img->fmt != IMG_FMT_RGB24) {
 460.163 +		if(img_copy(&tmpimg, img) == -1) {
 460.164 +			return -1;
 460.165 +		}
 460.166 +		if(img_convert(&tmpimg, IMG_FMT_RGB24) == -1) {
 460.167 +			img_destroy(&tmpimg);
 460.168 +			return -1;
 460.169 +		}
 460.170 +		img = &tmpimg;
 460.171 +	}
 460.172 +
 460.173 +	if(!(scanlines = malloc(img->height * sizeof *scanlines))) {
 460.174 +		img_destroy(&tmpimg);
 460.175 +		return -1;
 460.176 +	}
 460.177 +	scanlines[0] = img->pixels;
 460.178 +	for(i=1; i<img->height; i++) {
 460.179 +		scanlines[i] = scanlines[i - 1] + img->width * img->pixelsz;
 460.180 +	}
 460.181 +
 460.182 +	cinfo.err = jpeg_std_error(&jerr);	/* XXX */
 460.183 +	jpeg_create_compress(&cinfo);
 460.184 +
 460.185 +	dest.pub.init_destination = init_destination;
 460.186 +	dest.pub.empty_output_buffer = empty_output_buffer;
 460.187 +	dest.pub.term_destination = term_destination;
 460.188 +	dest.io = io;
 460.189 +	cinfo.dest = (struct jpeg_destination_mgr*)&dest;
 460.190 +
 460.191 +	cinfo.image_width = img->width;
 460.192 +	cinfo.image_height = img->height;
 460.193 +	cinfo.input_components = 3;
 460.194 +	cinfo.in_color_space = JCS_RGB;
 460.195 +
 460.196 +	jpeg_set_defaults(&cinfo);
 460.197 +
 460.198 +	jpeg_start_compress(&cinfo, 1);
 460.199 +	while(nlines < img->height) {
 460.200 +		int res = jpeg_write_scanlines(&cinfo, scanlines + nlines, img->height - nlines);
 460.201 +		nlines += res;
 460.202 +	}
 460.203 +	jpeg_finish_compress(&cinfo);
 460.204 +	jpeg_destroy_compress(&cinfo);
 460.205 +
 460.206 +	free(scanlines);
 460.207 +	img_destroy(&tmpimg);
 460.208 +	return 0;
 460.209 +}
 460.210 +
 460.211 +/* -- read source functions --
 460.212 + * the following functions are adapted from jdatasrc.c in jpeglib
 460.213 + */
 460.214 +static void init_source(j_decompress_ptr jd)
 460.215 +{
 460.216 +	struct src_mgr *src = (struct src_mgr*)jd->src;
 460.217 +	src->start_of_file = 1;
 460.218 +}
 460.219 +
 460.220 +static boolean fill_input_buffer(j_decompress_ptr jd)
 460.221 +{
 460.222 +	struct src_mgr *src = (struct src_mgr*)jd->src;
 460.223 +	size_t nbytes;
 460.224 +
 460.225 +	nbytes = src->io->read(src->buffer, INPUT_BUF_SIZE, src->io->uptr);
 460.226 +
 460.227 +	if(nbytes <= 0) {
 460.228 +		if(src->start_of_file) {
 460.229 +			return 0;
 460.230 +		}
 460.231 +		/* insert a fake EOI marker */
 460.232 +		src->buffer[0] = 0xff;
 460.233 +		src->buffer[1] = JPEG_EOI;
 460.234 +		nbytes = 2;
 460.235 +	}
 460.236 +
 460.237 +	src->pub.next_input_byte = src->buffer;
 460.238 +	src->pub.bytes_in_buffer = nbytes;
 460.239 +	src->start_of_file = 0;
 460.240 +	return 1;
 460.241 +}
 460.242 +
 460.243 +static void skip_input_data(j_decompress_ptr jd, long num_bytes)
 460.244 +{
 460.245 +	struct src_mgr *src = (struct src_mgr*)jd->src;
 460.246 +
 460.247 +	if(num_bytes > 0) {
 460.248 +		while(num_bytes > (long)src->pub.bytes_in_buffer) {
 460.249 +			num_bytes -= (long)src->pub.bytes_in_buffer;
 460.250 +			fill_input_buffer(jd);
 460.251 +		}
 460.252 +		src->pub.next_input_byte += (size_t)num_bytes;
 460.253 +		src->pub.bytes_in_buffer -= (size_t)num_bytes;
 460.254 +	}
 460.255 +}
 460.256 +
 460.257 +static void term_source(j_decompress_ptr jd)
 460.258 +{
 460.259 +	/* nothing to see here, move along */
 460.260 +}
 460.261 +
 460.262 +
 460.263 +/* -- write destination functions --
 460.264 + * the following functions are adapted from jdatadst.c in jpeglib
 460.265 + */
 460.266 +static void init_destination(j_compress_ptr jc)
 460.267 +{
 460.268 +	struct dst_mgr *dest = (struct dst_mgr*)jc->dest;
 460.269 +
 460.270 +	dest->pub.next_output_byte = dest->buffer;
 460.271 +	dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
 460.272 +}
 460.273 +
 460.274 +static boolean empty_output_buffer(j_compress_ptr jc)
 460.275 +{
 460.276 +	struct dst_mgr *dest = (struct dst_mgr*)jc->dest;
 460.277 +
 460.278 +	if(dest->io->write(dest->buffer, OUTPUT_BUF_SIZE, dest->io->uptr) != OUTPUT_BUF_SIZE) {
 460.279 +		return 0;
 460.280 +	}
 460.281 +
 460.282 +	dest->pub.next_output_byte = dest->buffer;
 460.283 +	dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
 460.284 +	return 1;
 460.285 +}
 460.286 +
 460.287 +static void term_destination(j_compress_ptr jc)
 460.288 +{
 460.289 +	struct dst_mgr *dest = (struct dst_mgr*)jc->dest;
 460.290 +	size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
 460.291 +
 460.292 +	/* write any remaining data in the buffer */
 460.293 +	if(datacount > 0) {
 460.294 +		dest->io->write(dest->buffer, datacount, dest->io->uptr);
 460.295 +	}
 460.296 +	/* XXX flush? ... */
 460.297 +}
   461.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   461.2 +++ b/libs/imago/file_png.c	Sat Feb 01 19:58:19 2014 +0200
   461.3 @@ -0,0 +1,261 @@
   461.4 +/*
   461.5 +libimago - a multi-format image file input/output library.
   461.6 +Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org>
   461.7 +
   461.8 +This program is free software: you can redistribute it and/or modify
   461.9 +it under the terms of the GNU Lesser General Public License as published
  461.10 +by the Free Software Foundation, either version 3 of the License, or
  461.11 +(at your option) any later version.
  461.12 +
  461.13 +This program is distributed in the hope that it will be useful,
  461.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  461.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  461.16 +GNU Lesser General Public License for more details.
  461.17 +
  461.18 +You should have received a copy of the GNU Lesser General Public License
  461.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  461.20 +*/
  461.21 +
  461.22 +/* -- PNG module -- */
  461.23 +
  461.24 +#include <stdlib.h>
  461.25 +#include <png.h>
  461.26 +#include "imago2.h"
  461.27 +#include "ftype_module.h"
  461.28 +
  461.29 +static int check_file(struct img_io *io);
  461.30 +static int read_file(struct img_pixmap *img, struct img_io *io);
  461.31 +static int write_file(struct img_pixmap *img, struct img_io *io);
  461.32 +
  461.33 +static void read_func(png_struct *png, unsigned char *data, size_t len);
  461.34 +static void write_func(png_struct *png, unsigned char *data, size_t len);
  461.35 +static void flush_func(png_struct *png);
  461.36 +
  461.37 +static int png_type_to_fmt(int color_type, int channel_bits);
  461.38 +static int fmt_to_png_type(enum img_fmt fmt);
  461.39 +
  461.40 +
  461.41 +int img_register_png(void)
  461.42 +{
  461.43 +	static struct ftype_module mod = {".png", check_file, read_file, write_file};
  461.44 +	return img_register_module(&mod);
  461.45 +}
  461.46 +
  461.47 +static int check_file(struct img_io *io)
  461.48 +{
  461.49 +	unsigned char sig[8];
  461.50 +	int res;
  461.51 +	long pos = io->seek(0, SEEK_CUR, io->uptr);
  461.52 +
  461.53 +	if(io->read(sig, 8, io->uptr) < 8) {
  461.54 +		io->seek(pos, SEEK_SET, io->uptr);
  461.55 +		return -1;
  461.56 +	}
  461.57 +
  461.58 +	res = png_sig_cmp(sig, 0, 8) == 0 ? 0 : -1;
  461.59 +	io->seek(pos, SEEK_SET, io->uptr);
  461.60 +	return res;
  461.61 +}
  461.62 +
  461.63 +static int read_file(struct img_pixmap *img, struct img_io *io)
  461.64 +{
  461.65 +	png_struct *png;
  461.66 +	png_info *info;
  461.67 +	int channel_bits, color_type, ilace_type, compression, filtering, fmt;
  461.68 +	png_uint_32 xsz, ysz;
  461.69 +
  461.70 +	if(!(png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) {
  461.71 +		return -1;
  461.72 +	}
  461.73 +
  461.74 +	if(!(info = png_create_info_struct(png))) {
  461.75 +		png_destroy_read_struct(&png, 0, 0);
  461.76 +		return -1;
  461.77 +	}
  461.78 +
  461.79 +	if(setjmp(png_jmpbuf(png))) {
  461.80 +		png_destroy_read_struct(&png, &info, 0);
  461.81 +		return -1;
  461.82 +	}
  461.83 +
  461.84 +	png_set_read_fn(png, io, read_func);
  461.85 +	png_set_sig_bytes(png, 0);
  461.86 +	png_read_png(png, info, 0, 0);
  461.87 +
  461.88 +	png_get_IHDR(png, info, &xsz, &ysz, &channel_bits, &color_type, &ilace_type,
  461.89 +			&compression, &filtering);
  461.90 +	if((fmt = png_type_to_fmt(color_type, channel_bits)) == -1) {
  461.91 +		png_destroy_read_struct(&png, &info, 0);
  461.92 +		return -1;
  461.93 +	}
  461.94 +
  461.95 +	if(img_set_pixels(img, xsz, ysz, fmt, 0) == -1) {
  461.96 +		png_destroy_read_struct(&png, &info, 0);
  461.97 +		return -1;
  461.98 +	}
  461.99 +
 461.100 +
 461.101 +	if(channel_bits == 8) {
 461.102 +		unsigned int i;
 461.103 +		unsigned char **lineptr = (unsigned char**)png_get_rows(png, info);
 461.104 +		unsigned char *dest = img->pixels;
 461.105 +
 461.106 +		for(i=0; i<ysz; i++) {
 461.107 +			memcpy(dest, lineptr[i], xsz * img->pixelsz);
 461.108 +			dest += xsz * img->pixelsz;
 461.109 +		}
 461.110 +	} else {
 461.111 +		unsigned int i, j, num_elem;
 461.112 +		unsigned char **lineptr = (unsigned char**)png_get_rows(png, info);
 461.113 +		float *dest = img->pixels;
 461.114 +
 461.115 +		num_elem = img->pixelsz / sizeof(float);
 461.116 +		for(i=0; i<ysz; i++) {
 461.117 +			for(j=0; j<xsz * num_elem; j++) {
 461.118 +				unsigned short val = (lineptr[i][j * 2] << 8) | lineptr[i][j * 2 + 1];
 461.119 +				*dest++ = (float)val / 65535.0;
 461.120 +			}
 461.121 +		}
 461.122 +	}
 461.123 +
 461.124 +
 461.125 +	png_destroy_read_struct(&png, &info, 0);
 461.126 +	return 0;
 461.127 +}
 461.128 +
 461.129 +
 461.130 +static int write_file(struct img_pixmap *img, struct img_io *io)
 461.131 +{
 461.132 +	png_struct *png;
 461.133 +	png_info *info;
 461.134 +	png_text txt;
 461.135 +	struct img_pixmap tmpimg;
 461.136 +	unsigned char **rows;
 461.137 +	unsigned char *pixptr;
 461.138 +	int i, coltype;
 461.139 +
 461.140 +	img_init(&tmpimg);
 461.141 +
 461.142 +	if(!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) {
 461.143 +		return -1;
 461.144 +	}
 461.145 +	if(!(info = png_create_info_struct(png))) {
 461.146 +		png_destroy_write_struct(&png, 0);
 461.147 +		return -1;
 461.148 +	}
 461.149 +
 461.150 +	/* if the input image is floating-point, we need to convert it to integer */
 461.151 +	if(img_is_float(img)) {
 461.152 +		if(img_copy(&tmpimg, img) == -1) {
 461.153 +			return -1;
 461.154 +		}
 461.155 +		if(img_to_integer(&tmpimg) == -1) {
 461.156 +			img_destroy(&tmpimg);
 461.157 +			return -1;
 461.158 +		}
 461.159 +		img = &tmpimg;
 461.160 +	}
 461.161 +
 461.162 +	txt.compression = PNG_TEXT_COMPRESSION_NONE;
 461.163 +	txt.key = "Software";
 461.164 +	txt.text = "libimago2";
 461.165 +	txt.text_length = 0;
 461.166 +
 461.167 +	if(setjmp(png_jmpbuf(png))) {
 461.168 +		png_destroy_write_struct(&png, &info);
 461.169 +		img_destroy(&tmpimg);
 461.170 +		return -1;
 461.171 +	}
 461.172 +	png_set_write_fn(png, io, write_func, flush_func);
 461.173 +
 461.174 +	coltype = fmt_to_png_type(img->fmt);
 461.175 +	png_set_IHDR(png, info, img->width, img->height, 8, coltype, PNG_INTERLACE_NONE,
 461.176 +			PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
 461.177 +	png_set_text(png, info, &txt, 1);
 461.178 +
 461.179 +	if(!(rows = malloc(img->height * sizeof *rows))) {
 461.180 +		png_destroy_write_struct(&png, &info);
 461.181 +		img_destroy(&tmpimg);
 461.182 +		return -1;
 461.183 +	}
 461.184 +
 461.185 +	pixptr = img->pixels;
 461.186 +	for(i=0; i<img->height; i++) {
 461.187 +		rows[i] = pixptr;
 461.188 +		pixptr += img->width * img->pixelsz;
 461.189 +	}
 461.190 +	png_set_rows(png, info, rows);
 461.191 +
 461.192 +	png_write_png(png, info, 0, 0);
 461.193 +	png_write_end(png, info);
 461.194 +	png_destroy_write_struct(&png, &info);
 461.195 +
 461.196 +	free(rows);
 461.197 +
 461.198 +	img_destroy(&tmpimg);
 461.199 +	return 0;
 461.200 +}
 461.201 +
 461.202 +static void read_func(png_struct *png, unsigned char *data, size_t len)
 461.203 +{
 461.204 +	struct img_io *io = (struct img_io*)png_get_io_ptr(png);
 461.205 +
 461.206 +	if(io->read(data, len, io->uptr) == -1) {
 461.207 +		longjmp(png_jmpbuf(png), 1);
 461.208 +	}
 461.209 +}
 461.210 +
 461.211 +static void write_func(png_struct *png, unsigned char *data, size_t len)
 461.212 +{
 461.213 +	struct img_io *io = (struct img_io*)png_get_io_ptr(png);
 461.214 +
 461.215 +	if(io->write(data, len, io->uptr) == -1) {
 461.216 +		longjmp(png_jmpbuf(png), 1);
 461.217 +	}
 461.218 +}
 461.219 +
 461.220 +static void flush_func(png_struct *png)
 461.221 +{
 461.222 +	/* XXX does it matter that we can't flush? */
 461.223 +}
 461.224 +
 461.225 +static int png_type_to_fmt(int color_type, int channel_bits)
 461.226 +{
 461.227 +	/* only 8 and 16 bits per channel ar supported at the moment */
 461.228 +	if(channel_bits != 8 && channel_bits != 16) {
 461.229 +		return -1;
 461.230 +	}
 461.231 +
 461.232 +	switch(color_type) {
 461.233 +	case PNG_COLOR_TYPE_RGB:
 461.234 +		return channel_bits == 16 ? IMG_FMT_RGBF : IMG_FMT_RGB24;
 461.235 +
 461.236 +	case PNG_COLOR_TYPE_RGB_ALPHA:
 461.237 +		return channel_bits == 16 ? IMG_FMT_RGBAF : IMG_FMT_RGBA32;
 461.238 +
 461.239 +	case PNG_COLOR_TYPE_GRAY:
 461.240 +		return channel_bits == 16 ? IMG_FMT_GREYF : IMG_FMT_GREY8;
 461.241 +
 461.242 +	default:
 461.243 +		break;
 461.244 +	}
 461.245 +	return -1;
 461.246 +}
 461.247 +
 461.248 +static int fmt_to_png_type(enum img_fmt fmt)
 461.249 +{
 461.250 +	switch(fmt) {
 461.251 +	case IMG_FMT_GREY8:
 461.252 +		return PNG_COLOR_TYPE_GRAY;
 461.253 +
 461.254 +	case IMG_FMT_RGB24:
 461.255 +		return PNG_COLOR_TYPE_RGB;
 461.256 +
 461.257 +	case IMG_FMT_RGBA32:
 461.258 +		return PNG_COLOR_TYPE_RGBA;
 461.259 +
 461.260 +	default:
 461.261 +		break;
 461.262 +	}
 461.263 +	return -1;
 461.264 +}
   462.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   462.2 +++ b/libs/imago/file_ppm.c	Sat Feb 01 19:58:19 2014 +0200
   462.3 @@ -0,0 +1,153 @@
   462.4 +/*
   462.5 +libimago - a multi-format image file input/output library.
   462.6 +Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org>
   462.7 +
   462.8 +This program is free software: you can redistribute it and/or modify
   462.9 +it under the terms of the GNU Lesser General Public License as published
  462.10 +by the Free Software Foundation, either version 3 of the License, or
  462.11 +(at your option) any later version.
  462.12 +
  462.13 +This program is distributed in the hope that it will be useful,
  462.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  462.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  462.16 +GNU Lesser General Public License for more details.
  462.17 +
  462.18 +You should have received a copy of the GNU Lesser General Public License
  462.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  462.20 +*/
  462.21 +
  462.22 +/* -- Portable Pixmap (PPM) module -- */
  462.23 +
  462.24 +#include <string.h>
  462.25 +#include "imago2.h"
  462.26 +#include "ftype_module.h"
  462.27 +
  462.28 +static int check(struct img_io *io);
  462.29 +static int read(struct img_pixmap *img, struct img_io *io);
  462.30 +static int write(struct img_pixmap *img, struct img_io *io);
  462.31 +
  462.32 +int img_register_ppm(void)
  462.33 +{
  462.34 +	static struct ftype_module mod = {".ppm", check, read, write};
  462.35 +	return img_register_module(&mod);
  462.36 +}
  462.37 +
  462.38 +
  462.39 +static int check(struct img_io *io)
  462.40 +{
  462.41 +	char id[2];
  462.42 +	int res = -1;
  462.43 +	long pos = io->seek(0, SEEK_CUR, io->uptr);
  462.44 +
  462.45 +	if(io->read(id, 2, io->uptr) < 2) {
  462.46 +		io->seek(pos, SEEK_SET, io->uptr);
  462.47 +		return -1;
  462.48 +	}
  462.49 +
  462.50 +	if(id[0] == 'P' && (id[1] == '6' || id[1] == '3')) {
  462.51 +		res = 0;
  462.52 +	}
  462.53 +	io->seek(pos, SEEK_SET, io->uptr);
  462.54 +	return res;
  462.55 +}
  462.56 +
  462.57 +static int iofgetc(struct img_io *io)
  462.58 +{
  462.59 +	char c;
  462.60 +	return io->read(&c, 1, io->uptr) < 1 ? -1 : c;
  462.61 +}
  462.62 +
  462.63 +static char *iofgets(char *buf, int size, struct img_io *io)
  462.64 +{
  462.65 +	int c;
  462.66 +	char *ptr = buf;
  462.67 +
  462.68 +	while(--size > 0 && (c = iofgetc(io)) != -1) {
  462.69 +		*ptr++ = c;
  462.70 +		if(c == '\n') break;
  462.71 +	}
  462.72 +	*ptr = 0;
  462.73 +
  462.74 +	return ptr == buf ? 0 : buf;
  462.75 +}
  462.76 +
  462.77 +/* TODO: implement P3 reading */
  462.78 +static int read(struct img_pixmap *img, struct img_io *io)
  462.79 +{
  462.80 +	char buf[256];
  462.81 +	int xsz = 0, ysz = 0, maxval = 0, got_hdrlines = 1;
  462.82 +
  462.83 +	if(!iofgets(buf, sizeof buf, io)) {
  462.84 +		return -1;
  462.85 +	}
  462.86 +	if(!(buf[0] == 'P' && (buf[1] == '6' || buf[1] == '3'))) {
  462.87 +		return -1;
  462.88 +	}
  462.89 +
  462.90 +	while(got_hdrlines < 3 && iofgets(buf, sizeof buf, io)) {
  462.91 +		if(buf[0] == '#') continue;
  462.92 +
  462.93 +		switch(got_hdrlines) {
  462.94 +		case 1:
  462.95 +			if(sscanf(buf, "%d %d\n", &xsz, &ysz) < 2) {
  462.96 +				return -1;
  462.97 +			}
  462.98 +			break;
  462.99 +
 462.100 +		case 2:
 462.101 +			if(sscanf(buf, "%d\n", &maxval) < 1) {
 462.102 +				return -1;
 462.103 +			}
 462.104 +		default:
 462.105 +			break;
 462.106 +		}
 462.107 +		got_hdrlines++;
 462.108 +	}
 462.109 +
 462.110 +	if(xsz < 1 || ysz < 1 || maxval != 255) {
 462.111 +		return -1;
 462.112 +	}
 462.113 +
 462.114 +	if(img_set_pixels(img, xsz, ysz, IMG_FMT_RGB24, 0) == -1) {
 462.115 +		return -1;
 462.116 +	}
 462.117 +
 462.118 +	if((int)io->read(img->pixels, xsz * ysz * 3, io->uptr) < xsz * ysz * 3) {
 462.119 +		return -1;
 462.120 +	}
 462.121 +	return 0;
 462.122 +}
 462.123 +
 462.124 +static int write(struct img_pixmap *img, struct img_io *io)
 462.125 +{
 462.126 +	int sz;
 462.127 +	char buf[256];
 462.128 +	struct img_pixmap tmpimg;
 462.129 +
 462.130 +	img_init(&tmpimg);
 462.131 +
 462.132 +	if(img->fmt != IMG_FMT_RGB24) {
 462.133 +		if(img_copy(&tmpimg, img) == -1) {
 462.134 +			return -1;
 462.135 +		}
 462.136 +		if(img_convert(&tmpimg, IMG_FMT_RGB24) == -1) {
 462.137 +			return -1;
 462.138 +		}
 462.139 +		img = &tmpimg;
 462.140 +	}
 462.141 +
 462.142 +	sprintf(buf, "P6\n#written by libimago2\n%d %d\n255\n", img->width, img->height);
 462.143 +	if(io->write(buf, strlen(buf), io->uptr) < strlen(buf)) {
 462.144 +		img_destroy(&tmpimg);
 462.145 +		return -1;
 462.146 +	}
 462.147 +
 462.148 +	sz = img->width * img->height * 3;
 462.149 +	if((int)io->write(img->pixels, sz, io->uptr) < sz) {
 462.150 +		img_destroy(&tmpimg);
 462.151 +		return -1;
 462.152 +	}
 462.153 +
 462.154 +	img_destroy(&tmpimg);
 462.155 +	return 0;
 462.156 +}
   463.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   463.2 +++ b/libs/imago/file_rgbe.c	Sat Feb 01 19:58:19 2014 +0200
   463.3 @@ -0,0 +1,501 @@
   463.4 +/* This file contains code to read and write four byte rgbe file format
   463.5 + * developed by Greg Ward.  It handles the conversions between rgbe and
   463.6 + * pixels consisting of floats.  The data is assumed to be an array of floats.
   463.7 + * By default there are three floats per pixel in the order red, green, blue.
   463.8 + * (RGBE_DATA_??? values control this.)
   463.9 + *
  463.10 + * written by Bruce Walter  (bjw@graphics.cornell.edu)  5/26/95
  463.11 + * based on code written by Greg Ward
  463.12 + * minor modifications by John Tsiombikas (nuclear@member.fsf.org) apr.9 2007
  463.13 + */
  463.14 +
  463.15 +#include <stdio.h>
  463.16 +#include <stdlib.h>
  463.17 +#include <string.h>
  463.18 +#include <math.h>
  463.19 +#include <ctype.h>
  463.20 +#include <errno.h>
  463.21 +#include "imago2.h"
  463.22 +#include "ftype_module.h"
  463.23 +
  463.24 +
  463.25 +typedef struct {
  463.26 +	int valid;				/* indicate which fields are valid */
  463.27 +	char programtype[16];	/* listed at beginning of file to identify it
  463.28 +							 * after "#?".  defaults to "RGBE" */
  463.29 +	float gamma;			/* image has already been gamma corrected with
  463.30 +							 * given gamma.  defaults to 1.0 (no correction) */
  463.31 +	float exposure;			/* a value of 1.0 in an image corresponds to
  463.32 +							 * <exposure> watts/steradian/m^2.
  463.33 +							 * defaults to 1.0 */
  463.34 +} rgbe_header_info;
  463.35 +
  463.36 +
  463.37 +static int check(struct img_io *io);
  463.38 +static int read(struct img_pixmap *img, struct img_io *io);
  463.39 +static int write(struct img_pixmap *img, struct img_io *io);
  463.40 +
  463.41 +static int rgbe_read_header(struct img_io *io, int *width, int *height, rgbe_header_info * info);
  463.42 +static int rgbe_read_pixels_rle(struct img_io *io, float *data, int scanline_width, int num_scanlines);
  463.43 +
  463.44 +
  463.45 +int img_register_rgbe(void)
  463.46 +{
  463.47 +	static struct ftype_module mod = {".rgbe", check, read, write};
  463.48 +	return img_register_module(&mod);
  463.49 +}
  463.50 +
  463.51 +
  463.52 +static int check(struct img_io *io)
  463.53 +{
  463.54 +	int xsz, ysz, res;
  463.55 +	long pos = io->seek(0, SEEK_CUR, io->uptr);
  463.56 +
  463.57 +	rgbe_header_info hdr;
  463.58 +	res = rgbe_read_header(io, &xsz, &ysz, &hdr);
  463.59 +
  463.60 +	io->seek(pos, SEEK_SET, io->uptr);
  463.61 +	return res;
  463.62 +}
  463.63 +
  463.64 +static int read(struct img_pixmap *img, struct img_io *io)
  463.65 +{
  463.66 +	int xsz, ysz;
  463.67 +	rgbe_header_info hdr;
  463.68 +
  463.69 +	if(rgbe_read_header(io, &xsz, &ysz, &hdr) == -1) {
  463.70 +		return -1;
  463.71 +	}
  463.72 +
  463.73 +	if(img_set_pixels(img, xsz, ysz, IMG_FMT_RGBF, 0) == -1) {
  463.74 +		return -1;
  463.75 +	}
  463.76 +	if(rgbe_read_pixels_rle(io, img->pixels, xsz, ysz) == -1) {
  463.77 +		return -1;
  463.78 +	}
  463.79 +	return 0;
  463.80 +}
  463.81 +
  463.82 +static int write(struct img_pixmap *img, struct img_io *io)
  463.83 +{
  463.84 +	return -1;	/* TODO */
  463.85 +}
  463.86 +
  463.87 +
  463.88 +static int iofgetc(struct img_io *io)
  463.89 +{
  463.90 +	char c;
  463.91 +	return io->read(&c, 1, io->uptr) < 1 ? -1 : c;
  463.92 +}
  463.93 +
  463.94 +static char *iofgets(char *buf, int size, struct img_io *io)
  463.95 +{
  463.96 +	int c;
  463.97 +	char *ptr = buf;
  463.98 +
  463.99 +	while(--size > 0 && (c = iofgetc(io)) != -1) {
 463.100 +		*ptr++ = c;
 463.101 +		if(c == '\n') break;
 463.102 +	}
 463.103 +	*ptr = 0;
 463.104 +
 463.105 +	return ptr == buf ? 0 : buf;
 463.106 +}
 463.107 +
 463.108 +
 463.109 +/* flags indicating which fields in an rgbe_header_info are valid */
 463.110 +#define RGBE_VALID_PROGRAMTYPE 0x01
 463.111 +#define RGBE_VALID_GAMMA       0x02
 463.112 +#define RGBE_VALID_EXPOSURE    0x04
 463.113 +
 463.114 +/* return codes for rgbe routines */
 463.115 +#define RGBE_RETURN_SUCCESS 0
 463.116 +#define RGBE_RETURN_FAILURE -1
 463.117 +
 463.118 +
 463.119 +#if defined(__cplusplus) || defined(GNUC) || __STDC_VERSION >= 199901L
 463.120 +#define INLINE inline
 463.121 +#else
 463.122 +#define INLINE
 463.123 +#endif
 463.124 +
 463.125 +/* offsets to red, green, and blue components in a data (float) pixel */
 463.126 +#define RGBE_DATA_RED	0
 463.127 +#define RGBE_DATA_GREEN  1
 463.128 +#define RGBE_DATA_BLUE   2
 463.129 +
 463.130 +/* number of floats per pixel */
 463.131 +#define RGBE_DATA_SIZE   3
 463.132 +
 463.133 +enum rgbe_error_codes {
 463.134 +	rgbe_read_error,
 463.135 +	rgbe_write_error,
 463.136 +	rgbe_format_error,
 463.137 +	rgbe_memory_error
 463.138 +};
 463.139 +
 463.140 +
 463.141 +/* default error routine.  change this to change error handling */
 463.142 +static int rgbe_error(int rgbe_error_code, char *msg)
 463.143 +{
 463.144 +	switch (rgbe_error_code) {
 463.145 +	case rgbe_read_error:
 463.146 +		fprintf(stderr, "RGBE read error: %s\n", strerror(errno));
 463.147 +		break;
 463.148 +
 463.149 +	case rgbe_write_error:
 463.150 +		fprintf(stderr, "RGBE write error: %s\n", strerror(errno));
 463.151 +		break;
 463.152 +
 463.153 +	case rgbe_format_error:
 463.154 +		fprintf(stderr, "RGBE bad file format: %s\n", msg);
 463.155 +		break;
 463.156 +
 463.157 +	default:
 463.158 +	case rgbe_memory_error:
 463.159 +		fprintf(stderr, "RGBE error: %s\n", msg);
 463.160 +	}
 463.161 +	return RGBE_RETURN_FAILURE;
 463.162 +}
 463.163 +
 463.164 +/* standard conversion from float pixels to rgbe pixels */
 463.165 +/*static INLINE void float2rgbe(unsigned char rgbe[4], float red, float green, float blue)
 463.166 +{
 463.167 +	float v;
 463.168 +	int e;
 463.169 +
 463.170 +	v = red;
 463.171 +	if(green > v)
 463.172 +		v = green;
 463.173 +	if(blue > v)
 463.174 +		v = blue;
 463.175 +	if(v < 1e-32) {
 463.176 +		rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
 463.177 +	} else {
 463.178 +		v = frexp(v, &e) * 256.0 / v;
 463.179 +		rgbe[0] = (unsigned char)(red * v);
 463.180 +		rgbe[1] = (unsigned char)(green * v);
 463.181 +		rgbe[2] = (unsigned char)(blue * v);
 463.182 +		rgbe[3] = (unsigned char)(e + 128);
 463.183 +	}
 463.184 +}*/
 463.185 +
 463.186 +/* standard conversion from rgbe to float pixels */
 463.187 +/* note: Ward uses ldexp(col+0.5,exp-(128+8)). However we wanted pixels */
 463.188 +/*       in the range [0,1] to map back into the range [0,1]. */
 463.189 +static INLINE void rgbe2float(float *red, float *green, float *blue, unsigned char rgbe[4])
 463.190 +{
 463.191 +	float f;
 463.192 +
 463.193 +	if(rgbe[3]) {				/*nonzero pixel */
 463.194 +		f = ldexp(1.0, rgbe[3] - (int)(128 + 8));
 463.195 +		*red = rgbe[0] * f;
 463.196 +		*green = rgbe[1] * f;
 463.197 +		*blue = rgbe[2] * f;
 463.198 +	} else
 463.199 +		*red = *green = *blue = 0.0;
 463.200 +}
 463.201 +
 463.202 +#if 0
 463.203 +/* default minimal header. modify if you want more information in header */
 463.204 +static int rgbe_write_header(FILE * fp, int width, int height, rgbe_header_info * info)
 463.205 +{
 463.206 +	char *programtype = "RGBE";
 463.207 +
 463.208 +	if(info && (info->valid & RGBE_VALID_PROGRAMTYPE))
 463.209 +		programtype = info->programtype;
 463.210 +	if(fprintf(fp, "#?%s\n", programtype) < 0)
 463.211 +		return rgbe_error(rgbe_write_error, NULL);
 463.212 +	/* The #? is to identify file type, the programtype is optional. */
 463.213 +	if(info && (info->valid & RGBE_VALID_GAMMA)) {
 463.214 +		if(fprintf(fp, "GAMMA=%g\n", info->gamma) < 0)
 463.215 +			return rgbe_error(rgbe_write_error, NULL);
 463.216 +	}
 463.217 +	if(info && (info->valid & RGBE_VALID_EXPOSURE)) {
 463.218 +		if(fprintf(fp, "EXPOSURE=%g\n", info->exposure) < 0)
 463.219 +			return rgbe_error(rgbe_write_error, NULL);
 463.220 +	}
 463.221 +	if(fprintf(fp, "FORMAT=32-bit_rle_rgbe\n\n") < 0)
 463.222 +		return rgbe_error(rgbe_write_error, NULL);
 463.223 +	if(fprintf(fp, "-Y %d +X %d\n", height, width) < 0)
 463.224 +		return rgbe_error(rgbe_write_error, NULL);
 463.225 +	return RGBE_RETURN_SUCCESS;
 463.226 +}
 463.227 +#endif
 463.228 +
 463.229 +/* minimal header reading.  modify if you want to parse more information */
 463.230 +static int rgbe_read_header(struct img_io *io, int *width, int *height, rgbe_header_info * info)
 463.231 +{
 463.232 +	char buf[128];
 463.233 +	float tempf;
 463.234 +	int i;
 463.235 +
 463.236 +	if(info) {
 463.237 +		info->valid = 0;
 463.238 +		info->programtype[0] = 0;
 463.239 +		info->gamma = info->exposure = 1.0;
 463.240 +	}
 463.241 +	if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == NULL)
 463.242 +		return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/
 463.243 +	if((buf[0] != '#') || (buf[1] != '?')) {
 463.244 +		/* if you want to require the magic token then uncomment the next line */
 463.245 +		/*return rgbe_error(rgbe_format_error,"bad initial token"); */
 463.246 +	} else if(info) {
 463.247 +		info->valid |= RGBE_VALID_PROGRAMTYPE;
 463.248 +		for(i = 0; i < sizeof(info->programtype) - 1; i++) {
 463.249 +			if((buf[i + 2] == 0) || isspace(buf[i + 2]))
 463.250 +				break;
 463.251 +			info->programtype[i] = buf[i + 2];
 463.252 +		}
 463.253 +		info->programtype[i] = 0;
 463.254 +		if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0)
 463.255 +			return rgbe_error(rgbe_read_error, NULL);
 463.256 +	}
 463.257 +	for(;;) {
 463.258 +		if((buf[0] == 0) || (buf[0] == '\n'))
 463.259 +			return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_format_error, "no FORMAT specifier found");*/
 463.260 +		else if(strcmp(buf, "FORMAT=32-bit_rle_rgbe\n") == 0)
 463.261 +			break;				/* format found so break out of loop */
 463.262 +		else if(info && (sscanf(buf, "GAMMA=%g", &tempf) == 1)) {
 463.263 +			info->gamma = tempf;
 463.264 +			info->valid |= RGBE_VALID_GAMMA;
 463.265 +		} else if(info && (sscanf(buf, "EXPOSURE=%g", &tempf) == 1)) {
 463.266 +			info->exposure = tempf;
 463.267 +			info->valid |= RGBE_VALID_EXPOSURE;
 463.268 +		}
 463.269 +		if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0)
 463.270 +			return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/
 463.271 +	}
 463.272 +	if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0)
 463.273 +		return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/
 463.274 +	if(strcmp(buf, "\n") != 0)
 463.275 +		return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_format_error, "missing blank line after FORMAT specifier");*/
 463.276 +	if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0)
 463.277 +		return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/
 463.278 +	if(sscanf(buf, "-Y %d +X %d", height, width) < 2)
 463.279 +		return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_format_error, "missing image size specifier");*/
 463.280 +	return RGBE_RETURN_SUCCESS;
 463.281 +}
 463.282 +
 463.283 +#if 0
 463.284 +/* simple write routine that does not use run length encoding */
 463.285 +
 463.286 +/* These routines can be made faster by allocating a larger buffer and
 463.287 +   fread-ing and fwrite-ing the data in larger chunks */
 463.288 +static int rgbe_write_pixels(FILE * fp, float *data, int numpixels)
 463.289 +{
 463.290 +	unsigned char rgbe[4];
 463.291 +
 463.292 +	while(numpixels-- > 0) {
 463.293 +		float2rgbe(rgbe, data[RGBE_DATA_RED], data[RGBE_DATA_GREEN], data[RGBE_DATA_BLUE]);
 463.294 +		data += RGBE_DATA_SIZE;
 463.295 +		if(fwrite(rgbe, sizeof(rgbe), 1, fp) < 1)
 463.296 +			return rgbe_error(rgbe_write_error, NULL);
 463.297 +	}
 463.298 +	return RGBE_RETURN_SUCCESS;
 463.299 +}
 463.300 +#endif
 463.301 +
 463.302 +/* simple read routine.  will not correctly handle run length encoding */
 463.303 +static int rgbe_read_pixels(struct img_io *io, float *data, int numpixels)
 463.304 +{
 463.305 +	unsigned char rgbe[4];
 463.306 +
 463.307 +	while(numpixels-- > 0) {
 463.308 +		if(io->read(rgbe, sizeof(rgbe), io->uptr) < 1)
 463.309 +			return rgbe_error(rgbe_read_error, NULL);
 463.310 +		rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE], rgbe);
 463.311 +		data += RGBE_DATA_SIZE;
 463.312 +	}
 463.313 +	return RGBE_RETURN_SUCCESS;
 463.314 +}
 463.315 +
 463.316 +#if 0
 463.317 +/* The code below is only needed for the run-length encoded files. */
 463.318 +
 463.319 +/* Run length encoding adds considerable complexity but does */
 463.320 +
 463.321 +/* save some space.  For each scanline, each channel (r,g,b,e) is */
 463.322 +
 463.323 +/* encoded separately for better compression. */
 463.324 +
 463.325 +static int rgbe_write_bytes_rle(struct img_io *io, unsigned char *data, int numbytes)
 463.326 +{
 463.327 +#define MINRUNLENGTH 4
 463.328 +	int cur, beg_run, run_count, old_run_count, nonrun_count;
 463.329 +	unsigned char buf[2];
 463.330 +
 463.331 +	cur = 0;
 463.332 +	while(cur < numbytes) {
 463.333 +		beg_run = cur;
 463.334 +		/* find next run of length at least 4 if one exists */
 463.335 +		run_count = old_run_count = 0;
 463.336 +		while((run_count < MINRUNLENGTH) && (beg_run < numbytes)) {
 463.337 +			beg_run += run_count;
 463.338 +			old_run_count = run_count;
 463.339 +			run_count = 1;
 463.340 +			while((beg_run + run_count < numbytes) && (run_count < 127)
 463.341 +				  && (data[beg_run] == data[beg_run + run_count]))
 463.342 +				run_count++;
 463.343 +		}
 463.344 +		/* if data before next big run is a short run then write it as such */
 463.345 +		if((old_run_count > 1) && (old_run_count == beg_run - cur)) {
 463.346 +			buf[0] = 128 + old_run_count;	/*write short run */
 463.347 +			buf[1] = data[cur];
 463.348 +			if(fwrite(buf, sizeof(buf[0]) * 2, 1, fp) < 1)
 463.349 +				return rgbe_error(rgbe_write_error, NULL);
 463.350 +			cur = beg_run;
 463.351 +		}
 463.352 +		/* write out bytes until we reach the start of the next run */
 463.353 +		while(cur < beg_run) {
 463.354 +			nonrun_count = beg_run - cur;
 463.355 +			if(nonrun_count > 128)
 463.356 +				nonrun_count = 128;
 463.357 +			buf[0] = nonrun_count;
 463.358 +			if(fwrite(buf, sizeof(buf[0]), 1, fp) < 1)
 463.359 +				return rgbe_error(rgbe_write_error, NULL);
 463.360 +			if(fwrite(&data[cur], sizeof(data[0]) * nonrun_count, 1, fp) < 1)
 463.361 +				return rgbe_error(rgbe_write_error, NULL);
 463.362 +			cur += nonrun_count;
 463.363 +		}
 463.364 +		/* write out next run if one was found */
 463.365 +		if(run_count >= MINRUNLENGTH) {
 463.366 +			buf[0] = 128 + run_count;
 463.367 +			buf[1] = data[beg_run];
 463.368 +			if(fwrite(buf, sizeof(buf[0]) * 2, 1, fp) < 1)
 463.369 +				return rgbe_error(rgbe_write_error, NULL);
 463.370 +			cur += run_count;
 463.371 +		}
 463.372 +	}
 463.373 +	return RGBE_RETURN_SUCCESS;
 463.374 +#undef MINRUNLENGTH
 463.375 +}
 463.376 +
 463.377 +static int rgbe_write_pixels_rle(struct img_io *io, float *data, int scanline_width, int num_scanlines)
 463.378 +{
 463.379 +	unsigned char rgbe[4];
 463.380 +	unsigned char *buffer;
 463.381 +	int i, err;
 463.382 +
 463.383 +	if((scanline_width < 8) || (scanline_width > 0x7fff))
 463.384 +		/* run length encoding is not allowed so write flat */
 463.385 +		return rgbe_write_pixels(io, data, scanline_width * num_scanlines);
 463.386 +	buffer = (unsigned char *)malloc(sizeof(unsigned char) * 4 * scanline_width);
 463.387 +	if(buffer == NULL)
 463.388 +		/* no buffer space so write flat */
 463.389 +		return rgbe_write_pixels(fp, data, scanline_width * num_scanlines);
 463.390 +	while(num_scanlines-- > 0) {
 463.391 +		rgbe[0] = 2;
 463.392 +		rgbe[1] = 2;
 463.393 +		rgbe[2] = scanline_width >> 8;
 463.394 +		rgbe[3] = scanline_width & 0xFF;
 463.395 +		if(fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) {
 463.396 +			free(buffer);
 463.397 +			return rgbe_error(rgbe_write_error, NULL);
 463.398 +		}
 463.399 +		for(i = 0; i < scanline_width; i++) {
 463.400 +			float2rgbe(rgbe, data[RGBE_DATA_RED], data[RGBE_DATA_GREEN], data[RGBE_DATA_BLUE]);
 463.401 +			buffer[i] = rgbe[0];
 463.402 +			buffer[i + scanline_width] = rgbe[1];
 463.403 +			buffer[i + 2 * scanline_width] = rgbe[2];
 463.404 +			buffer[i + 3 * scanline_width] = rgbe[3];
 463.405 +			data += RGBE_DATA_SIZE;
 463.406 +		}
 463.407 +		/* write out each of the four channels separately run length encoded */
 463.408 +		/* first red, then green, then blue, then exponent */
 463.409 +		for(i = 0; i < 4; i++) {
 463.410 +			if((err = rgbe_write_bytes_rle(fp, &buffer[i * scanline_width],
 463.411 +										  scanline_width)) != RGBE_RETURN_SUCCESS) {
 463.412 +				free(buffer);
 463.413 +				return err;
 463.414 +			}
 463.415 +		}
 463.416 +	}
 463.417 +	free(buffer);
 463.418 +	return RGBE_RETURN_SUCCESS;
 463.419 +}
 463.420 +#endif
 463.421 +
 463.422 +static int rgbe_read_pixels_rle(struct img_io *io, float *data, int scanline_width, int num_scanlines)
 463.423 +{
 463.424 +	unsigned char rgbe[4], *scanline_buffer, *ptr, *ptr_end;
 463.425 +	int i, count;
 463.426 +	unsigned char buf[2];
 463.427 +
 463.428 +	if((scanline_width < 8) || (scanline_width > 0x7fff))
 463.429 +		/* run length encoding is not allowed so read flat */
 463.430 +		return rgbe_read_pixels(io, data, scanline_width * num_scanlines);
 463.431 +	scanline_buffer = NULL;
 463.432 +	/* read in each successive scanline */
 463.433 +	while(num_scanlines > 0) {
 463.434 +		if(io->read(rgbe, sizeof(rgbe), io->uptr) < 1) {
 463.435 +			free(scanline_buffer);
 463.436 +			return rgbe_error(rgbe_read_error, NULL);
 463.437 +		}
 463.438 +		if((rgbe[0] != 2) || (rgbe[1] != 2) || (rgbe[2] & 0x80)) {
 463.439 +			/* this file is not run length encoded */
 463.440 +			rgbe2float(&data[0], &data[1], &data[2], rgbe);
 463.441 +			data += RGBE_DATA_SIZE;
 463.442 +			free(scanline_buffer);
 463.443 +			return rgbe_read_pixels(io, data, scanline_width * num_scanlines - 1);
 463.444 +		}
 463.445 +		if((((int)rgbe[2]) << 8 | rgbe[3]) != scanline_width) {
 463.446 +			free(scanline_buffer);
 463.447 +			return rgbe_error(rgbe_format_error, "wrong scanline width");
 463.448 +		}
 463.449 +		if(scanline_buffer == NULL)
 463.450 +			scanline_buffer = (unsigned char *)
 463.451 +				malloc(sizeof(unsigned char) * 4 * scanline_width);
 463.452 +		if(scanline_buffer == NULL)
 463.453 +			return rgbe_error(rgbe_memory_error, "unable to allocate buffer space");
 463.454 +
 463.455 +		ptr = &scanline_buffer[0];
 463.456 +		/* read each of the four channels for the scanline into the buffer */
 463.457 +		for(i = 0; i < 4; i++) {
 463.458 +			ptr_end = &scanline_buffer[(i + 1) * scanline_width];
 463.459 +			while(ptr < ptr_end) {
 463.460 +				if(io->read(buf, sizeof(buf[0]) * 2, io->uptr) < 1) {
 463.461 +					free(scanline_buffer);
 463.462 +					return rgbe_error(rgbe_read_error, NULL);
 463.463 +				}
 463.464 +				if(buf[0] > 128) {
 463.465 +					/* a run of the same value */
 463.466 +					count = buf[0] - 128;
 463.467 +					if((count == 0) || (count > ptr_end - ptr)) {
 463.468 +						free(scanline_buffer);
 463.469 +						return rgbe_error(rgbe_format_error, "bad scanline data");
 463.470 +					}
 463.471 +					while(count-- > 0)
 463.472 +						*ptr++ = buf[1];
 463.473 +				} else {
 463.474 +					/* a non-run */
 463.475 +					count = buf[0];
 463.476 +					if((count == 0) || (count > ptr_end - ptr)) {
 463.477 +						free(scanline_buffer);
 463.478 +						return rgbe_error(rgbe_format_error, "bad scanline data");
 463.479 +					}
 463.480 +					*ptr++ = buf[1];
 463.481 +					if(--count > 0) {
 463.482 +						if(io->read(ptr, sizeof(*ptr) * count, io->uptr) < 1) {
 463.483 +							free(scanline_buffer);
 463.484 +							return rgbe_error(rgbe_read_error, NULL);
 463.485 +						}
 463.486 +						ptr += count;
 463.487 +					}
 463.488 +				}
 463.489 +			}
 463.490 +		}
 463.491 +		/* now convert data from buffer into floats */
 463.492 +		for(i = 0; i < scanline_width; i++) {
 463.493 +			rgbe[0] = scanline_buffer[i];
 463.494 +			rgbe[1] = scanline_buffer[i + scanline_width];
 463.495 +			rgbe[2] = scanline_buffer[i + 2 * scanline_width];
 463.496 +			rgbe[3] = scanline_buffer[i + 3 * scanline_width];
 463.497 +			rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE], rgbe);
 463.498 +			data += RGBE_DATA_SIZE;
 463.499 +		}
 463.500 +		num_scanlines--;
 463.501 +	}
 463.502 +	free(scanline_buffer);
 463.503 +	return RGBE_RETURN_SUCCESS;
 463.504 +}
   464.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   464.2 +++ b/libs/imago/ftype_module.c	Sat Feb 01 19:58:19 2014 +0200
   464.3 @@ -0,0 +1,118 @@
   464.4 +/*
   464.5 +libimago - a multi-format image file input/output library.
   464.6 +Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org>
   464.7 +
   464.8 +This program is free software: you can redistribute it and/or modify
   464.9 +it under the terms of the GNU Lesser General Public License as published
  464.10 +by the Free Software Foundation, either version 3 of the License, or
  464.11 +(at your option) any later version.
  464.12 +
  464.13 +This program is distributed in the hope that it will be useful,
  464.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  464.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  464.16 +GNU Lesser General Public License for more details.
  464.17 +
  464.18 +You should have received a copy of the GNU Lesser General Public License
  464.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  464.20 +*/
  464.21 +
  464.22 +#include <stdlib.h>
  464.23 +#include <string.h>
  464.24 +#include "ftype_module.h"
  464.25 +
  464.26 +static struct list_node {
  464.27 +	struct ftype_module *module;
  464.28 +	struct list_node *next;
  464.29 +} *modules;
  464.30 +
  464.31 +/* defined in modules.c which is generated by configure */
  464.32 +void img_modules_init();
  464.33 +
  464.34 +static int done_init;
  464.35 +
  464.36 +int img_register_module(struct ftype_module *mod)
  464.37 +{
  464.38 +	struct list_node *node;
  464.39 +
  464.40 +	if(!(node = malloc(sizeof *node))) {
  464.41 +		return -1;
  464.42 +	}
  464.43 +
  464.44 +	node->module = mod;
  464.45 +	node->next = modules;
  464.46 +	modules = node;
  464.47 +	return 0;
  464.48 +}
  464.49 +
  464.50 +struct ftype_module *img_find_format_module(struct img_io *io)
  464.51 +{
  464.52 +	struct list_node *node;
  464.53 +
  464.54 +	if(!done_init) {
  464.55 +		img_modules_init();
  464.56 +		done_init = 1;
  464.57 +	}
  464.58 +
  464.59 +	node = modules;
  464.60 +	while(node) {
  464.61 +		if(node->module->check(io) != -1) {
  464.62 +			return node->module;
  464.63 +		}
  464.64 +		node = node->next;
  464.65 +	}
  464.66 +	return 0;
  464.67 +}
  464.68 +
  464.69 +struct ftype_module *img_guess_format(const char *fname)
  464.70 +{
  464.71 +	struct list_node *node;
  464.72 +	char *suffix;
  464.73 +	int suffix_len;
  464.74 +
  464.75 +	if(!done_init) {
  464.76 +		img_modules_init();
  464.77 +		done_init = 1;
  464.78 +	}
  464.79 +
  464.80 +	if(!(suffix = strrchr(fname, '.'))) {
  464.81 +		return 0;	/* no suffix, can't guess ... */
  464.82 +	}
  464.83 +	suffix_len = strlen(suffix);
  464.84 +
  464.85 +	node = modules;
  464.86 +	while(node) {
  464.87 +		char *suflist = node->module->suffix;
  464.88 +		char *start, *end;
  464.89 +
  464.90 +		while(*suflist) {
  464.91 +			if(!(start = strstr(suflist, suffix))) {
  464.92 +				break;
  464.93 +			}
  464.94 +			end = start + suffix_len;
  464.95 +
  464.96 +			if(*end == ':' || *end == 0) {
  464.97 +				return node->module;	/* found it */
  464.98 +			}
  464.99 +			suflist = end;
 464.100 +		}
 464.101 +
 464.102 +		node = node->next;
 464.103 +	}
 464.104 +	return 0;
 464.105 +}
 464.106 +
 464.107 +struct ftype_module *img_get_module(int idx)
 464.108 +{
 464.109 +	struct list_node *node;
 464.110 +
 464.111 +	if(!done_init) {
 464.112 +		img_modules_init();
 464.113 +		done_init = 1;
 464.114 +	}
 464.115 +
 464.116 +	node = modules;
 464.117 +	while(node && idx--) {
 464.118 +		node = node->next;
 464.119 +	}
 464.120 +	return node ? node->module : 0;
 464.121 +}
   465.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   465.2 +++ b/libs/imago/ftype_module.h	Sat Feb 01 19:58:19 2014 +0200
   465.3 @@ -0,0 +1,39 @@
   465.4 +/*
   465.5 +libimago - a multi-format image file input/output library.
   465.6 +Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org>
   465.7 +
   465.8 +This program is free software: you can redistribute it and/or modify
   465.9 +it under the terms of the GNU Lesser General Public License as published
  465.10 +by the Free Software Foundation, either version 3 of the License, or
  465.11 +(at your option) any later version.
  465.12 +
  465.13 +This program is distributed in the hope that it will be useful,
  465.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  465.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  465.16 +GNU Lesser General Public License for more details.
  465.17 +
  465.18 +You should have received a copy of the GNU Lesser General Public License
  465.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  465.20 +*/
  465.21 +
  465.22 +#ifndef FTYPE_MODULE_H_
  465.23 +#define FTYPE_MODULE_H_
  465.24 +
  465.25 +#include "imago2.h"
  465.26 +
  465.27 +struct ftype_module {
  465.28 +	char *suffix;	/* used for format autodetection during saving only */
  465.29 +
  465.30 +	int (*check)(struct img_io *io);
  465.31 +	int (*read)(struct img_pixmap *img, struct img_io *io);
  465.32 +	int (*write)(struct img_pixmap *img, struct img_io *io);
  465.33 +};
  465.34 +
  465.35 +int img_register_module(struct ftype_module *mod);
  465.36 +
  465.37 +struct ftype_module *img_find_format_module(struct img_io *io);
  465.38 +struct ftype_module *img_guess_format(const char *fname);
  465.39 +struct ftype_module *img_get_module(int idx);
  465.40 +
  465.41 +
  465.42 +#endif	/* FTYPE_MODULE_H_ */
   466.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   466.2 +++ b/libs/imago/imago2.c	Sat Feb 01 19:58:19 2014 +0200
   466.3 @@ -0,0 +1,449 @@
   466.4 +/*
   466.5 +libimago - a multi-format image file input/output library.
   466.6 +Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org>
   466.7 +
   466.8 +This program is free software: you can redistribute it and/or modify
   466.9 +it under the terms of the GNU Lesser General Public License as published
  466.10 +by the Free Software Foundation, either version 3 of the License, or
  466.11 +(at your option) any later version.
  466.12 +
  466.13 +This program is distributed in the hope that it will be useful,
  466.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  466.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  466.16 +GNU Lesser General Public License for more details.
  466.17 +
  466.18 +You should have received a copy of the GNU Lesser General Public License
  466.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  466.20 +*/
  466.21 +
  466.22 +#include <stdio.h>
  466.23 +#include <stdlib.h>
  466.24 +#include <string.h>
  466.25 +#include "imago2.h"
  466.26 +#include "ftype_module.h"
  466.27 +
  466.28 +static int pixel_size(enum img_fmt fmt);
  466.29 +static size_t def_read(void *buf, size_t bytes, void *uptr);
  466.30 +static size_t def_write(void *buf, size_t bytes, void *uptr);
  466.31 +static long def_seek(long offset, int whence, void *uptr);
  466.32 +
  466.33 +
  466.34 +void img_init(struct img_pixmap *img)
  466.35 +{
  466.36 +	img->pixels = 0;
  466.37 +	img->width = img->height = 0;
  466.38 +	img->fmt = IMG_FMT_RGBA32;
  466.39 +	img->pixelsz = pixel_size(img->fmt);
  466.40 +	img->name = 0;
  466.41 +}
  466.42 +
  466.43 +
  466.44 +void img_destroy(struct img_pixmap *img)
  466.45 +{
  466.46 +	free(img->pixels);
  466.47 +	img->pixels = 0;	/* just in case... */
  466.48 +	img->width = img->height = 0xbadbeef;
  466.49 +	free(img->name);
  466.50 +}
  466.51 +
  466.52 +struct img_pixmap *img_create(void)
  466.53 +{
  466.54 +	struct img_pixmap *p;
  466.55 +
  466.56 +	if(!(p = malloc(sizeof *p))) {
  466.57 +		return 0;
  466.58 +	}
  466.59 +	img_init(p);
  466.60 +	return p;
  466.61 +}
  466.62 +
  466.63 +void img_free(struct img_pixmap *img)
  466.64 +{
  466.65 +	img_destroy(img);
  466.66 +	free(img);
  466.67 +}
  466.68 +
  466.69 +int img_set_name(struct img_pixmap *img, const char *name)
  466.70 +{
  466.71 +	char *tmp;
  466.72 +
  466.73 +	if(!(tmp = malloc(strlen(name) + 1))) {
  466.74 +		return -1;
  466.75 +	}
  466.76 +	strcpy(tmp, name);
  466.77 +	img->name = tmp;
  466.78 +	return 0;
  466.79 +}
  466.80 +
  466.81 +int img_set_format(struct img_pixmap *img, enum img_fmt fmt)
  466.82 +{
  466.83 +	if(img->pixels) {
  466.84 +		return img_convert(img, fmt);
  466.85 +	}
  466.86 +	img->fmt = fmt;
  466.87 +	return 0;
  466.88 +}
  466.89 +
  466.90 +int img_copy(struct img_pixmap *dest, struct img_pixmap *src)
  466.91 +{
  466.92 +	return img_set_pixels(dest, src->width, src->height, src->fmt, src->pixels);
  466.93 +}
  466.94 +
  466.95 +int img_set_pixels(struct img_pixmap *img, int w, int h, enum img_fmt fmt, void *pix)
  466.96 +{
  466.97 +	void *newpix;
  466.98 +	int pixsz = pixel_size(fmt);
  466.99 +
 466.100 +	if(!(newpix = malloc(w * h * pixsz))) {
 466.101 +		return -1;
 466.102 +	}
 466.103 +
 466.104 +	if(pix) {
 466.105 +		memcpy(newpix, pix, w * h * pixsz);
 466.106 +	} else {
 466.107 +		memset(newpix, 0, w * h * pixsz);
 466.108 +	}
 466.109 +
 466.110 +	free(img->pixels);
 466.111 +	img->pixels = newpix;
 466.112 +	img->width = w;
 466.113 +	img->height = h;
 466.114 +	img->pixelsz = pixsz;
 466.115 +	img->fmt = fmt;
 466.116 +	return 0;
 466.117 +}
 466.118 +
 466.119 +void *img_load_pixels(const char *fname, int *xsz, int *ysz, enum img_fmt fmt)
 466.120 +{
 466.121 +	struct img_pixmap img;
 466.122 +
 466.123 +	img_init(&img);
 466.124 +
 466.125 +	if(img_load(&img, fname) == -1) {
 466.126 +		return 0;
 466.127 +	}
 466.128 +	if(img.fmt != fmt) {
 466.129 +		if(img_convert(&img, fmt) == -1) {
 466.130 +			img_destroy(&img);
 466.131 +			return 0;
 466.132 +		}
 466.133 +	}
 466.134 +
 466.135 +	*xsz = img.width;
 466.136 +	*ysz = img.height;
 466.137 +	return img.pixels;
 466.138 +}
 466.139 +
 466.140 +int img_save_pixels(const char *fname, void *pix, int xsz, int ysz, enum img_fmt fmt)
 466.141 +{
 466.142 +	struct img_pixmap img;
 466.143 +
 466.144 +	img_init(&img);
 466.145 +	img.fmt = fmt;
 466.146 +	img.name = (char*)fname;
 466.147 +	img.width = xsz;
 466.148 +	img.height = ysz;
 466.149 +	img.pixels = pix;
 466.150 +
 466.151 +	return img_save(&img, fname);
 466.152 +}
 466.153 +
 466.154 +void img_free_pixels(void *pix)
 466.155 +{
 466.156 +	free(pix);
 466.157 +}
 466.158 +
 466.159 +int img_load(struct img_pixmap *img, const char *fname)
 466.160 +{
 466.161 +	int res;
 466.162 +	FILE *fp;
 466.163 +
 466.164 +	if(!(fp = fopen(fname, "rb"))) {
 466.165 +		return -1;
 466.166 +	}
 466.167 +	res = img_read_file(img, fp);
 466.168 +	fclose(fp);
 466.169 +	return res;
 466.170 +}
 466.171 +
 466.172 +/* TODO implement filetype selection */
 466.173 +int img_save(struct img_pixmap *img, const char *fname)
 466.174 +{
 466.175 +	int res;
 466.176 +	FILE *fp;
 466.177 +
 466.178 +	img_set_name(img, fname);
 466.179 +
 466.180 +	if(!(fp = fopen(fname, "wb"))) {
 466.181 +		return -1;
 466.182 +	}
 466.183 +	res = img_write_file(img, fp);
 466.184 +	fclose(fp);
 466.185 +	return res;
 466.186 +}
 466.187 +
 466.188 +int img_read_file(struct img_pixmap *img, FILE *fp)
 466.189 +{
 466.190 +	struct img_io io = {0, def_read, def_write, def_seek};
 466.191 +
 466.192 +	io.uptr = fp;
 466.193 +	return img_read(img, &io);
 466.194 +}
 466.195 +
 466.196 +int img_write_file(struct img_pixmap *img, FILE *fp)
 466.197 +{
 466.198 +	struct img_io io = {0, def_read, def_write, def_seek};
 466.199 +
 466.200 +	io.uptr = fp;
 466.201 +	return img_write(img, &io);
 466.202 +}
 466.203 +
 466.204 +int img_read(struct img_pixmap *img, struct img_io *io)
 466.205 +{
 466.206 +	struct ftype_module *mod;
 466.207 +
 466.208 +	if((mod = img_find_format_module(io))) {
 466.209 +		return mod->read(img, io);
 466.210 +	}
 466.211 +	return -1;
 466.212 +}
 466.213 +
 466.214 +int img_write(struct img_pixmap *img, struct img_io *io)
 466.215 +{
 466.216 +	struct ftype_module *mod;
 466.217 +
 466.218 +	if(!img->name || !(mod = img_guess_format(img->name))) {
 466.219 +		/* TODO throw some sort of warning? */
 466.220 +		/* TODO implement some sort of module priority or let the user specify? */
 466.221 +		if(!(mod = img_get_module(0))) {
 466.222 +			return -1;
 466.223 +		}
 466.224 +	}
 466.225 +
 466.226 +	return mod->write(img, io);
 466.227 +}
 466.228 +
 466.229 +int img_to_float(struct img_pixmap *img)
 466.230 +{
 466.231 +	enum img_fmt targ_fmt;
 466.232 +
 466.233 +	switch(img->fmt) {
 466.234 +	case IMG_FMT_GREY8:
 466.235 +		targ_fmt = IMG_FMT_GREYF;
 466.236 +		break;
 466.237 +
 466.238 +	case IMG_FMT_RGB24:
 466.239 +		targ_fmt = IMG_FMT_RGBF;
 466.240 +		break;
 466.241 +
 466.242 +	case IMG_FMT_RGBA32:
 466.243 +		targ_fmt = IMG_FMT_RGBAF;
 466.244 +		break;
 466.245 +
 466.246 +	default:
 466.247 +		return 0;	/* already float */
 466.248 +	}
 466.249 +
 466.250 +	return img_convert(img, targ_fmt);
 466.251 +}
 466.252 +
 466.253 +int img_to_integer(struct img_pixmap *img)
 466.254 +{
 466.255 +	enum img_fmt targ_fmt;
 466.256 +
 466.257 +	switch(img->fmt) {
 466.258 +	case IMG_FMT_GREYF:
 466.259 +		targ_fmt = IMG_FMT_GREY8;
 466.260 +		break;
 466.261 +
 466.262 +	case IMG_FMT_RGBF:
 466.263 +		targ_fmt = IMG_FMT_RGB24;
 466.264 +		break;
 466.265 +
 466.266 +	case IMG_FMT_RGBAF:
 466.267 +		targ_fmt = IMG_FMT_RGBA32;
 466.268 +		break;
 466.269 +
 466.270 +	default:
 466.271 +		return 0;	/* already integer */
 466.272 +	}
 466.273 +
 466.274 +	return img_convert(img, targ_fmt);
 466.275 +}
 466.276 +
 466.277 +int img_is_float(struct img_pixmap *img)
 466.278 +{
 466.279 +	return img->fmt >= IMG_FMT_GREYF && img->fmt <= IMG_FMT_RGBAF;
 466.280 +}
 466.281 +
 466.282 +int img_has_alpha(struct img_pixmap *img)
 466.283 +{
 466.284 +	if(img->fmt == IMG_FMT_RGBA32 || img->fmt == IMG_FMT_RGBAF) {
 466.285 +		return 1;
 466.286 +	}
 466.287 +	return 0;
 466.288 +}
 466.289 +
 466.290 +
 466.291 +void img_setpixel(struct img_pixmap *img, int x, int y, void *pixel)
 466.292 +{
 466.293 +	char *dest = (char*)img->pixels + (y * img->width + x) * img->pixelsz;
 466.294 +	memcpy(dest, pixel, img->pixelsz);
 466.295 +}
 466.296 +
 466.297 +void img_getpixel(struct img_pixmap *img, int x, int y, void *pixel)
 466.298 +{
 466.299 +	char *dest = (char*)img->pixels + (y * img->width + x) * img->pixelsz;
 466.300 +	memcpy(pixel, dest, img->pixelsz);
 466.301 +}
 466.302 +
 466.303 +void img_setpixel1i(struct img_pixmap *img, int x, int y, int pix)
 466.304 +{
 466.305 +	img_setpixel4i(img, x, y, pix, pix, pix, pix);
 466.306 +}
 466.307 +
 466.308 +void img_setpixel1f(struct img_pixmap *img, int x, int y, float pix)
 466.309 +{
 466.310 +	img_setpixel4f(img, x, y, pix, pix, pix, pix);
 466.311 +}
 466.312 +
 466.313 +void img_setpixel4i(struct img_pixmap *img, int x, int y, int r, int g, int b, int a)
 466.314 +{
 466.315 +	if(img_is_float(img)) {
 466.316 +		img_setpixel4f(img, x, y, r / 255.0, g / 255.0, b / 255.0, a / 255.0);
 466.317 +	} else {
 466.318 +		unsigned char pixel[4];
 466.319 +		pixel[0] = r;
 466.320 +		pixel[1] = g;
 466.321 +		pixel[2] = b;
 466.322 +		pixel[3] = a;
 466.323 +
 466.324 +		img_setpixel(img, x, y, pixel);
 466.325 +	}
 466.326 +}
 466.327 +
 466.328 +void img_setpixel4f(struct img_pixmap *img, int x, int y, float r, float g, float b, float a)
 466.329 +{
 466.330 +	if(img_is_float(img)) {
 466.331 +		float pixel[4];
 466.332 +		pixel[0] = r;
 466.333 +		pixel[1] = g;
 466.334 +		pixel[2] = b;
 466.335 +		pixel[3] = a;
 466.336 +
 466.337 +		img_setpixel(img, x, y, pixel);
 466.338 +	} else {
 466.339 +		img_setpixel4i(img, x, y, (int)(r * 255.0), (int)(g * 255.0), (int)(b * 255.0), (int)(a * 255.0));
 466.340 +	}
 466.341 +}
 466.342 +
 466.343 +void img_getpixel1i(struct img_pixmap *img, int x, int y, int *pix)
 466.344 +{
 466.345 +	int junk[3];
 466.346 +	img_getpixel4i(img, x, y, pix, junk, junk + 1, junk + 2);
 466.347 +}
 466.348 +
 466.349 +void img_getpixel1f(struct img_pixmap *img, int x, int y, float *pix)
 466.350 +{
 466.351 +	float junk[3];
 466.352 +	img_getpixel4f(img, x, y, pix, junk, junk + 1, junk + 2);
 466.353 +}
 466.354 +
 466.355 +void img_getpixel4i(struct img_pixmap *img, int x, int y, int *r, int *g, int *b, int *a)
 466.356 +{
 466.357 +	if(img_is_float(img)) {
 466.358 +		float pixel[4] = {0, 0, 0, 0};
 466.359 +		img_getpixel(img, x, y, pixel);
 466.360 +		*r = pixel[0] * 255.0;
 466.361 +		*g = pixel[1] * 255.0;
 466.362 +		*b = pixel[2] * 255.0;
 466.363 +		*a = pixel[3] * 255.0;
 466.364 +	} else {
 466.365 +		unsigned char pixel[4];
 466.366 +		img_getpixel(img, x, y, pixel);
 466.367 +		*r = pixel[0];
 466.368 +		*g = pixel[1];
 466.369 +		*b = pixel[2];
 466.370 +		*a = pixel[3];
 466.371 +	}
 466.372 +}
 466.373 +
 466.374 +void img_getpixel4f(struct img_pixmap *img, int x, int y, float *r, float *g, float *b, float *a)
 466.375 +{
 466.376 +	if(img_is_float(img)) {
 466.377 +		float pixel[4] = {0, 0, 0, 0};
 466.378 +		img_getpixel(img, x, y, pixel);
 466.379 +		*r = pixel[0];
 466.380 +		*g = pixel[1];
 466.381 +		*b = pixel[2];
 466.382 +		*a = pixel[3];
 466.383 +	} else {
 466.384 +		unsigned char pixel[4];
 466.385 +		img_getpixel(img, x, y, pixel);
 466.386 +		*r = pixel[0] / 255.0;
 466.387 +		*g = pixel[1] / 255.0;
 466.388 +		*b = pixel[2] / 255.0;
 466.389 +		*a = pixel[3] / 255.0;
 466.390 +	}
 466.391 +}
 466.392 +
 466.393 +void img_io_set_user_data(struct img_io *io, void *uptr)
 466.394 +{
 466.395 +	io->uptr = uptr;
 466.396 +}
 466.397 +
 466.398 +void img_io_set_read_func(struct img_io *io, size_t (*read)(void*, size_t, void*))
 466.399 +{
 466.400 +	io->read = read;
 466.401 +}
 466.402 +
 466.403 +void img_io_set_write_func(struct img_io *io, size_t (*write)(void*, size_t, void*))
 466.404 +{
 466.405 +	io->write = write;
 466.406 +}
 466.407 +
 466.408 +void img_io_set_seek_func(struct img_io *io, long (*seek)(long, int, void*))
 466.409 +{
 466.410 +	io->seek = seek;
 466.411 +}
 466.412 +
 466.413 +
 466.414 +static int pixel_size(enum img_fmt fmt)
 466.415 +{
 466.416 +	switch(fmt) {
 466.417 +	case IMG_FMT_GREY8:
 466.418 +		return 1;
 466.419 +	case IMG_FMT_RGB24:
 466.420 +		return 3;
 466.421 +	case IMG_FMT_RGBA32:
 466.422 +		return 4;
 466.423 +	case IMG_FMT_GREYF:
 466.424 +		return sizeof(float);
 466.425 +	case IMG_FMT_RGBF:
 466.426 +		return 3 * sizeof(float);
 466.427 +	case IMG_FMT_RGBAF:
 466.428 +		return 4 * sizeof(float);
 466.429 +	default:
 466.430 +		break;
 466.431 +	}
 466.432 +	return 0;
 466.433 +}
 466.434 +
 466.435 +static size_t def_read(void *buf, size_t bytes, void *uptr)
 466.436 +{
 466.437 +	return uptr ? fread(buf, 1, bytes, uptr) : 0;
 466.438 +}
 466.439 +
 466.440 +static size_t def_write(void *buf, size_t bytes, void *uptr)
 466.441 +{
 466.442 +	return uptr ? fwrite(buf, 1, bytes, uptr) : 0;
 466.443 +}
 466.444 +
 466.445 +static long def_seek(long offset, int whence, void *uptr)
 466.446 +{
 466.447 +	if(!uptr || fseek(uptr, offset, whence) == -1) {
 466.448 +		return -1;
 466.449 +	}
 466.450 +	return ftell(uptr);
 466.451 +}
 466.452 +
   467.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   467.2 +++ b/libs/imago/imago2.h	Sat Feb 01 19:58:19 2014 +0200
   467.3 @@ -0,0 +1,222 @@
   467.4 +/*
   467.5 +libimago - a multi-format image file input/output library.
   467.6 +Copyright (C) 2010-2012 John Tsiombikas <nuclear@member.fsf.org>
   467.7 +
   467.8 +This program is free software: you can redistribute it and/or modify
   467.9 +it under the terms of the GNU Lesser General Public License as published
  467.10 +by the Free Software Foundation, either version 3 of the License, or
  467.11 +(at your option) any later version.
  467.12 +
  467.13 +This program is distributed in the hope that it will be useful,
  467.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  467.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  467.16 +GNU Lesser General Public License for more details.
  467.17 +
  467.18 +You should have received a copy of the GNU Lesser General Public License
  467.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  467.20 +*/
  467.21 +
  467.22 +#ifndef IMAGO2_H_
  467.23 +#define IMAGO2_H_
  467.24 +
  467.25 +#include <stdio.h>
  467.26 +
  467.27 +#ifdef __cplusplus
  467.28 +#define IMG_OPTARG(arg, val)	arg = val
  467.29 +#else
  467.30 +#define IMG_OPTARG(arg, val)	arg
  467.31 +#endif
  467.32 +
  467.33 +/* XXX if you change this make sure to also change pack/unpack arrays in conv.c */
  467.34 +enum img_fmt {
  467.35 +	IMG_FMT_GREY8,
  467.36 +	IMG_FMT_RGB24,
  467.37 +	IMG_FMT_RGBA32,
  467.38 +	IMG_FMT_GREYF,
  467.39 +	IMG_FMT_RGBF,
  467.40 +	IMG_FMT_RGBAF,
  467.41 +
  467.42 +	NUM_IMG_FMT
  467.43 +};
  467.44 +
  467.45 +struct img_pixmap {
  467.46 +	void *pixels;
  467.47 +	int width, height;
  467.48 +	enum img_fmt fmt;
  467.49 +	int pixelsz;
  467.50 +	char *name;
  467.51 +};
  467.52 +
  467.53 +struct img_io {
  467.54 +	void *uptr;	/* user-data */
  467.55 +
  467.56 +	size_t (*read)(void *buf, size_t bytes, void *uptr);
  467.57 +	size_t (*write)(void *buf, size_t bytes, void *uptr);
  467.58 +	long (*seek)(long offs, int whence, void *uptr);
  467.59 +};
  467.60 +
  467.61 +#ifdef __cplusplus
  467.62 +extern "C" {
  467.63 +#endif
  467.64 +
  467.65 +/* initialize the img_pixmap structure */
  467.66 +void img_init(struct img_pixmap *img);
  467.67 +/* destroys the img_pixmap structure, freeing the pixel buffer (if available)
  467.68 + * and any other memory held by the pixmap.
  467.69 + */
  467.70 +void img_destroy(struct img_pixmap *img);
  467.71 +
  467.72 +/* convenience function that allocates an img_pixmap struct and then initializes it.
  467.73 + * returns null if the malloc fails.
  467.74 + */
  467.75 +struct img_pixmap *img_create(void);
  467.76 +/* frees a pixmap previously allocated with img_create (free followed by img_destroy) */
  467.77 +void img_free(struct img_pixmap *img);
  467.78 +
  467.79 +int img_set_name(struct img_pixmap *img, const char *name);
  467.80 +
  467.81 +/* set the image pixel format */
  467.82 +int img_set_format(struct img_pixmap *img, enum img_fmt fmt);
  467.83 +
  467.84 +/* copies one pixmap to another.
  467.85 + * equivalent to: img_set_pixels(dest, src->width, src->height, src->fmt, src->pixels)
  467.86 + */
  467.87 +int img_copy(struct img_pixmap *dest, struct img_pixmap *src);
  467.88 +
  467.89 +/* allocates a pixel buffer of the specified dimensions and format, and copies the
  467.90 + * pixels given through the pix pointer into it.
  467.91 + * the pix pointer can be null, in which case there's no copy, just allocation.
  467.92 + *
  467.93 + * C++: fmt and pix have default parameters IMG_FMT_RGBA32 and null respectively.
  467.94 + */
  467.95 +int img_set_pixels(struct img_pixmap *img, int w, int h, IMG_OPTARG(enum img_fmt fmt, IMG_FMT_RGBA32), IMG_OPTARG(void *pix, 0));
  467.96 +
  467.97 +/* Simplified image loading
  467.98 + * Loads the specified file, and returns a pointer to an array of pixels of the
  467.99 + * requested pixel format. The width and height of the image are returned through
 467.100 + * the xsz and ysz pointers.
 467.101 + * If the image cannot be loaded, the function returns null.
 467.102 + *
 467.103 + * C++: the format argument is optional and defaults to IMG_FMT_RGBA32
 467.104 + */
 467.105 +void *img_load_pixels(const char *fname, int *xsz, int *ysz, IMG_OPTARG(enum img_fmt fmt, IMG_FMT_RGBA32));
 467.106 +
 467.107 +/* Simplified image saving
 467.108 + * Reads an array of pixels supplied through the pix pointer, of dimensions xsz
 467.109 + * and ysz, and pixel-format fmt, and saves it to a file.
 467.110 + * The output filetype is guessed by the filename suffix.
 467.111 + *
 467.112 + * C++: the format argument is optional and defaults to IMG_FMT_RGBA32
 467.113 + */
 467.114 +int img_save_pixels(const char *fname, void *pix, int xsz, int ysz, IMG_OPTARG(enum img_fmt fmt, IMG_FMT_RGBA32));
 467.115 +
 467.116 +/* Frees the memory allocated by img_load_pixels */
 467.117 +void img_free_pixels(void *pix);
 467.118 +
 467.119 +/* Loads an image file into the supplied pixmap */
 467.120 +int img_load(struct img_pixmap *img, const char *fname);
 467.121 +/* Saves the supplied pixmap to a file. The output filetype is guessed by the filename suffix */
 467.122 +int img_save(struct img_pixmap *img, const char *fname);
 467.123 +
 467.124 +/* Reads an image from an open FILE* into the supplied pixmap */
 467.125 +int img_read_file(struct img_pixmap *img, FILE *fp);
 467.126 +/* Writes the supplied pixmap to an open FILE* */
 467.127 +int img_write_file(struct img_pixmap *img, FILE *fp);
 467.128 +
 467.129 +/* Reads an image using user-defined file-i/o functions (see img_io_set_*) */
 467.130 +int img_read(struct img_pixmap *img, struct img_io *io);
 467.131 +/* Writes an image using user-defined file-i/o functions (see img_io_set_*) */
 467.132 +int img_write(struct img_pixmap *img, struct img_io *io);
 467.133 +
 467.134 +/* Converts an image to the specified pixel format */
 467.135 +int img_convert(struct img_pixmap *img, enum img_fmt tofmt);
 467.136 +
 467.137 +/* Converts an image from an integer pixel format to the corresponding floating point one */
 467.138 +int img_to_float(struct img_pixmap *img);
 467.139 +/* Converts an image from a floating point pixel format to the corresponding integer one */
 467.140 +int img_to_integer(struct img_pixmap *img);
 467.141 +
 467.142 +/* Returns non-zero (true) if the supplied image is in a floating point pixel format */
 467.143 +int img_is_float(struct img_pixmap *img);
 467.144 +/* Returns non-zero (true) if the supplied image has an alpha channel */
 467.145 +int img_has_alpha(struct img_pixmap *img);
 467.146 +
 467.147 +
 467.148 +/* don't use these for anything performance-critical */
 467.149 +void img_setpixel(struct img_pixmap *img, int x, int y, void *pixel);
 467.150 +void img_getpixel(struct img_pixmap *img, int x, int y, void *pixel);
 467.151 +
 467.152 +void img_setpixel1i(struct img_pixmap *img, int x, int y, int pix);
 467.153 +void img_setpixel1f(struct img_pixmap *img, int x, int y, float pix);
 467.154 +void img_setpixel4i(struct img_pixmap *img, int x, int y, int r, int g, int b, int a);
 467.155 +void img_setpixel4f(struct img_pixmap *img, int x, int y, float r, float g, float b, float a);
 467.156 +
 467.157 +void img_getpixel1i(struct img_pixmap *img, int x, int y, int *pix);
 467.158 +void img_getpixel1f(struct img_pixmap *img, int x, int y, float *pix);
 467.159 +void img_getpixel4i(struct img_pixmap *img, int x, int y, int *r, int *g, int *b, int *a);
 467.160 +void img_getpixel4f(struct img_pixmap *img, int x, int y, float *r, float *g, float *b, float *a);
 467.161 +
 467.162 +
 467.163 +/* OpenGL helper functions */
 467.164 +
 467.165 +/* Returns the equivalent OpenGL "format" as expected by the 7th argument of glTexImage2D */
 467.166 +unsigned int img_fmt_glfmt(enum img_fmt fmt);
 467.167 +/* Returns the equivalent OpenGL "type" as expected by the 8th argument of glTexImage2D */
 467.168 +unsigned int img_fmt_gltype(enum img_fmt fmt);
 467.169 +/* Returns the equivalent OpenGL "internal format" as expected by the 3rd argument of glTexImage2D */
 467.170 +unsigned int img_fmt_glintfmt(enum img_fmt fmt);
 467.171 +
 467.172 +/* Same as above, based on the pixel format of the supplied image */
 467.173 +unsigned int img_glfmt(struct img_pixmap *img);
 467.174 +unsigned int img_gltype(struct img_pixmap *img);
 467.175 +unsigned int img_glintfmt(struct img_pixmap *img);
 467.176 +
 467.177 +/* Creates an OpenGL texture from the image, and returns the texture id, or 0 for failure */
 467.178 +unsigned int img_gltexture(struct img_pixmap *img);
 467.179 +
 467.180 +/* Load an image and create an OpenGL texture out of it */
 467.181 +unsigned int img_gltexture_load(const char *fname);
 467.182 +unsigned int img_gltexture_read_file(FILE *fp);
 467.183 +unsigned int img_gltexture_read(struct img_io *io);
 467.184 +
 467.185 +/* These functions can be used to fill an img_io struct before it's passed to
 467.186 + * one of the user-defined i/o image reading/writing functions (img_read/img_write).
 467.187 + *
 467.188 + * User-defined i/o functions:
 467.189 + *
 467.190 + * - size_t read_func(void *buffer, size_t bytes, void *user_ptr)
 467.191 + * Must try to fill the buffer with the specified number of bytes, and return
 467.192 + * the number of bytes actually read.
 467.193 + *
 467.194 + * - size_t write_func(void *buffer, size_t bytes, void *user_ptr)
 467.195 + * Must write the specified number of bytes from the supplied buffer and return
 467.196 + * the number of bytes actually written.
 467.197 + *
 467.198 + * - long seek_func(long offset, int whence, void *user_ptr)
 467.199 + * Must seek offset bytes from: the beginning of the file if whence is SEEK_SET,
 467.200 + * the current position if whence is SEEK_CUR, or the end of the file if whence is
 467.201 + * SEEK_END, and return the resulting file offset from the beginning of the file.
 467.202 + * (i.e. seek_func(0, SEEK_CUR, user_ptr); must be equivalent to an ftell).
 467.203 + *
 467.204 + * All three functions get the user-data pointer set through img_io_set_user_data
 467.205 + * as their last argument.
 467.206 + *
 467.207 + * Note: obviously you don't need to set a write function if you're only going
 467.208 + * to call img_read, or the read and seek function if you're only going to call
 467.209 + * img_write.
 467.210 + *
 467.211 + * Note: if the user-supplied write function is buffered, make sure to flush
 467.212 + * (or close the file) after img_write returns.
 467.213 + */
 467.214 +void img_io_set_user_data(struct img_io *io, void *uptr);
 467.215 +void img_io_set_read_func(struct img_io *io, size_t (*read)(void*, size_t, void*));
 467.216 +void img_io_set_write_func(struct img_io *io, size_t (*write)(void*, size_t, void*));
 467.217 +void img_io_set_seek_func(struct img_io *io, long (*seek)(long, int, void*));
 467.218 +
 467.219 +
 467.220 +#ifdef __cplusplus
 467.221 +}
 467.222 +#endif
 467.223 +
 467.224 +
 467.225 +#endif	/* IMAGO_H_ */
   468.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   468.2 +++ b/libs/imago/imago_gl.c	Sat Feb 01 19:58:19 2014 +0200
   468.3 @@ -0,0 +1,223 @@
   468.4 +#include "imago2.h"
   468.5 +
   468.6 +
   468.7 +/* to avoid dependency to OpenGL, I'll define all the relevant GL macros manually */
   468.8 +#define GL_UNSIGNED_BYTE		0x1401
   468.9 +#define GL_FLOAT				0x1406
  468.10 +
  468.11 +#define GL_LUMINANCE			0x1909
  468.12 +#define GL_RGB					0x1907
  468.13 +#define GL_RGBA					0x1908
  468.14 +
  468.15 +#define GL_RGBA32F				0x8814
  468.16 +#define GL_RGB32F				0x8815
  468.17 +#define GL_LUMINANCE32F			0x8818
  468.18 +
  468.19 +#define GL_TEXTURE_2D			0x0de1
  468.20 +#define GL_TEXTURE_WRAP_S		0x2802
  468.21 +#define GL_TEXTURE_WRAP_T		0x2803
  468.22 +#define GL_TEXTURE_MAG_FILTER	0x2800
  468.23 +#define GL_TEXTURE_MIN_FILTER	0x2801
  468.24 +#define GL_LINEAR				0x2601
  468.25 +#define GL_REPEAT				0x2901
  468.26 +
  468.27 +
  468.28 +typedef unsigned int GLenum;
  468.29 +typedef unsigned int GLuint;
  468.30 +typedef int GLint;
  468.31 +typedef int GLsizei;
  468.32 +typedef void GLvoid;
  468.33 +
  468.34 +/* for the same reason I'll load GL functions dynamically */
  468.35 +typedef void (*gl_gen_textures_func)(GLsizei, GLuint*);
  468.36 +typedef void (*gl_bind_texture_func)(GLenum, GLuint);
  468.37 +typedef void (*gl_tex_parameteri_func)(GLenum, GLenum, GLint);
  468.38 +typedef void (*gl_tex_image2d_func)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
  468.39 +
  468.40 +static gl_gen_textures_func gl_gen_textures;
  468.41 +static gl_bind_texture_func gl_bind_texture;
  468.42 +static gl_tex_parameteri_func gl_tex_parameteri;
  468.43 +static gl_tex_image2d_func gl_tex_image2d;
  468.44 +
  468.45 +static int load_glfunc(void);
  468.46 +
  468.47 +unsigned int img_fmt_glfmt(enum img_fmt fmt)
  468.48 +{
  468.49 +	switch(fmt) {
  468.50 +	case IMG_FMT_GREY8:
  468.51 +	case IMG_FMT_GREYF:
  468.52 +		return GL_LUMINANCE;
  468.53 +
  468.54 +	case IMG_FMT_RGB24:
  468.55 +	case IMG_FMT_RGBF:
  468.56 +		return GL_RGB;
  468.57 +
  468.58 +	case IMG_FMT_RGBA32:
  468.59 +	case IMG_FMT_RGBAF:
  468.60 +		return GL_RGBA;
  468.61 +
  468.62 +	default:
  468.63 +		break;
  468.64 +	}
  468.65 +	return 0;
  468.66 +}
  468.67 +
  468.68 +unsigned int img_fmt_gltype(enum img_fmt fmt)
  468.69 +{
  468.70 +	switch(fmt) {
  468.71 +	case IMG_FMT_GREY8:
  468.72 +	case IMG_FMT_RGB24:
  468.73 +	case IMG_FMT_RGBA32:
  468.74 +		return GL_UNSIGNED_BYTE;
  468.75 +
  468.76 +	case IMG_FMT_GREYF:
  468.77 +	case IMG_FMT_RGBF:
  468.78 +	case IMG_FMT_RGBAF:
  468.79 +		return GL_FLOAT;
  468.80 +
  468.81 +	default:
  468.82 +		break;
  468.83 +	}
  468.84 +	return 0;
  468.85 +}
  468.86 +
  468.87 +unsigned int img_fmt_glintfmt(enum img_fmt fmt)
  468.88 +{
  468.89 +	switch(fmt) {
  468.90 +	case IMG_FMT_GREY8:
  468.91 +		return GL_LUMINANCE;
  468.92 +	case IMG_FMT_RGB24:
  468.93 +		return GL_RGB;
  468.94 +	case IMG_FMT_RGBA32:
  468.95 +		return GL_RGBA;
  468.96 +	case IMG_FMT_GREYF:
  468.97 +		return GL_LUMINANCE32F;
  468.98 +	case IMG_FMT_RGBF:
  468.99 +		return GL_RGB32F;
 468.100 +	case IMG_FMT_RGBAF:
 468.101 +		return GL_RGBA32F;
 468.102 +	default:
 468.103 +		break;
 468.104 +	}
 468.105 +	return 0;
 468.106 +}
 468.107 +
 468.108 +unsigned int img_glfmt(struct img_pixmap *img)
 468.109 +{
 468.110 +	return img_fmt_glfmt(img->fmt);
 468.111 +}
 468.112 +
 468.113 +unsigned int img_gltype(struct img_pixmap *img)
 468.114 +{
 468.115 +	return img_fmt_gltype(img->fmt);
 468.116 +}
 468.117 +
 468.118 +unsigned int img_glintfmt(struct img_pixmap *img)
 468.119 +{
 468.120 +	return img_fmt_glintfmt(img->fmt);
 468.121 +}
 468.122 +
 468.123 +unsigned int img_gltexture(struct img_pixmap *img)
 468.124 +{
 468.125 +	unsigned int tex;
 468.126 +	unsigned int intfmt, fmt, type;
 468.127 +
 468.128 +	if(!gl_gen_textures) {
 468.129 +		if(load_glfunc() == -1) {
 468.130 +			fprintf(stderr, "imago: failed to initialize the OpenGL helpers\n");
 468.131 +			return 0;
 468.132 +		}
 468.133 +	}
 468.134 +
 468.135 +	intfmt = img_glintfmt(img);
 468.136 +	fmt = img_glfmt(img);
 468.137 +	type = img_gltype(img);
 468.138 +
 468.139 +	gl_gen_textures(1, &tex);
 468.140 +	gl_bind_texture(GL_TEXTURE_2D, tex);
 468.141 +	gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 468.142 +	gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 468.143 +	gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 468.144 +	gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 468.145 +	gl_tex_image2d(GL_TEXTURE_2D, 0, intfmt, img->width, img->height, 0, fmt, type, img->pixels);
 468.146 +	return tex;
 468.147 +}
 468.148 +
 468.149 +unsigned int img_gltexture_load(const char *fname)
 468.150 +{
 468.151 +	struct img_pixmap img;
 468.152 +	unsigned int tex;
 468.153 +
 468.154 +	img_init(&img);
 468.155 +	if(img_load(&img, fname) == -1) {
 468.156 +		img_destroy(&img);
 468.157 +		return 0;
 468.158 +	}
 468.159 +
 468.160 +	tex = img_gltexture(&img);
 468.161 +	img_destroy(&img);
 468.162 +	return tex;
 468.163 +}
 468.164 +
 468.165 +unsigned int img_gltexture_read_file(FILE *fp)
 468.166 +{
 468.167 +	struct img_pixmap img;
 468.168 +	unsigned int tex;
 468.169 +
 468.170 +	img_init(&img);
 468.171 +	if(img_read_file(&img, fp) == -1) {
 468.172 +		img_destroy(&img);
 468.173 +		return 0;
 468.174 +	}
 468.175 +
 468.176 +	tex = img_gltexture(&img);
 468.177 +	img_destroy(&img);
 468.178 +	return tex;
 468.179 +}
 468.180 +
 468.181 +unsigned int img_gltexture_read(struct img_io *io)
 468.182 +{
 468.183 +	struct img_pixmap img;
 468.184 +	unsigned int tex;
 468.185 +
 468.186 +	img_init(&img);
 468.187 +	if(img_read(&img, io) == -1) {
 468.188 +		img_destroy(&img);
 468.189 +		return 0;
 468.190 +	}
 468.191 +
 468.192 +	tex = img_gltexture(&img);
 468.193 +	img_destroy(&img);
 468.194 +	return tex;
 468.195 +}
 468.196 +
 468.197 +#if defined(__unix__) || defined(__APPLE__)
 468.198 +#ifndef __USE_GNU
 468.199 +#define __USE_GNU
 468.200 +#endif
 468.201 +
 468.202 +#include <dlfcn.h>
 468.203 +#endif
 468.204 +#ifdef WIN32
 468.205 +#include <windows.h>
 468.206 +#endif
 468.207 +
 468.208 +static int load_glfunc(void)
 468.209 +{
 468.210 +#if defined(__unix__) || defined(__APPLE__)
 468.211 +	gl_gen_textures = (gl_gen_textures_func)dlsym(RTLD_DEFAULT, "glGenTextures");
 468.212 +	gl_bind_texture = (gl_bind_texture_func)dlsym(RTLD_DEFAULT, "glBindTexture");
 468.213 +	gl_tex_parameteri = (gl_tex_parameteri_func)dlsym(RTLD_DEFAULT, "glTexParameteri");
 468.214 +	gl_tex_image2d = (gl_tex_image2d_func)dlsym(RTLD_DEFAULT, "glTexImage2D");
 468.215 +#endif
 468.216 +
 468.217 +#ifdef WIN32
 468.218 +	HMODULE handle = GetModuleHandle(0);
 468.219 +	gl_gen_textures = (gl_gen_textures_func)GetProcAddress(handle, "glGenTextures");
 468.220 +	gl_bind_texture = (gl_bind_texture_func)GetProcAddress(handle, "glBindTexture");
 468.221 +	gl_tex_parameteri = (gl_tex_parameteri_func)GetProcAddress(handle, "glTexParameteri");
 468.222 +	gl_tex_image2d = (gl_tex_image2d_func)GetProcAddress(handle, "glTexImage2D");
 468.223 +#endif
 468.224 +
 468.225 +	return (gl_gen_textures && gl_bind_texture && gl_tex_parameteri && gl_tex_image2d) ? 0 : -1;
 468.226 +}
   469.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   469.2 +++ b/libs/imago/modules.c	Sat Feb 01 19:58:19 2014 +0200
   469.3 @@ -0,0 +1,13 @@
   469.4 +/* this file is generated by ./configure, do not edit */
   469.5 +int img_register_jpeg();
   469.6 +int img_register_png();
   469.7 +int img_register_ppm();
   469.8 +int img_register_rgbe();
   469.9 +
  469.10 +void img_modules_init(void)
  469.11 +{
  469.12 +	img_register_jpeg();
  469.13 +	img_register_png();
  469.14 +	img_register_ppm();
  469.15 +	img_register_rgbe();
  469.16 +}
   470.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   470.2 +++ b/libs/kissfft/COPYING	Sat Feb 01 19:58:19 2014 +0200
   470.3 @@ -0,0 +1,11 @@
   470.4 +Copyright (c) 2003-2010 Mark Borgerding
   470.5 +
   470.6 +All rights reserved.
   470.7 +
   470.8 +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
   470.9 +
  470.10 +    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  470.11 +    * 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.
  470.12 +    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  470.13 +
  470.14 +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.
   471.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   471.2 +++ b/libs/kissfft/README	Sat Feb 01 19:58:19 2014 +0200
   471.3 @@ -0,0 +1,134 @@
   471.4 +KISS FFT - A mixed-radix Fast Fourier Transform based up on the principle, 
   471.5 +"Keep It Simple, Stupid."
   471.6 +
   471.7 +    There are many great fft libraries already around.  Kiss FFT is not trying
   471.8 +to be better than any of them.  It only attempts to be a reasonably efficient, 
   471.9 +moderately useful FFT that can use fixed or floating data types and can be 
  471.10 +incorporated into someone's C program in a few minutes with trivial licensing.
  471.11 +
  471.12 +USAGE:
  471.13 +
  471.14 +    The basic usage for 1-d complex FFT is:
  471.15 +
  471.16 +        #include "kiss_fft.h"
  471.17 +
  471.18 +        kiss_fft_cfg cfg = kiss_fft_alloc( nfft ,is_inverse_fft ,0,0 );
  471.19 +
  471.20 +        while ...
  471.21 +        
  471.22 +            ... // put kth sample in cx_in[k].r and cx_in[k].i
  471.23 +            
  471.24 +            kiss_fft( cfg , cx_in , cx_out );
  471.25 +            
  471.26 +            ... // transformed. DC is in cx_out[0].r and cx_out[0].i 
  471.27 +            
  471.28 +        free(cfg);
  471.29 +
  471.30 +    Note: frequency-domain data is stored from dc up to 2pi.
  471.31 +    so cx_out[0] is the dc bin of the FFT
  471.32 +    and cx_out[nfft/2] is the Nyquist bin (if exists)
  471.33 +
  471.34 +    Declarations are in "kiss_fft.h", along with a brief description of the 
  471.35 +functions you'll need to use. 
  471.36 +
  471.37 +Code definitions for 1d complex FFTs are in kiss_fft.c.
  471.38 +
  471.39 +You can do other cool stuff with the extras you'll find in tools/
  471.40 +
  471.41 +    * multi-dimensional FFTs 
  471.42 +    * real-optimized FFTs  (returns the positive half-spectrum: (nfft/2+1) complex frequency bins)
  471.43 +    * fast convolution FIR filtering (not available for fixed point)
  471.44 +    * spectrum image creation
  471.45 +
  471.46 +The core fft and most tools/ code can be compiled to use float, double,
  471.47 + Q15 short or Q31 samples. The default is float.
  471.48 +
  471.49 +
  471.50 +BACKGROUND:
  471.51 +
  471.52 +    I started coding this because I couldn't find a fixed point FFT that didn't 
  471.53 +use assembly code.  I started with floating point numbers so I could get the 
  471.54 +theory straight before working on fixed point issues.  In the end, I had a 
  471.55 +little bit of code that could be recompiled easily to do ffts with short, float
  471.56 +or double (other types should be easy too).  
  471.57 +
  471.58 +    Once I got my FFT working, I was curious about the speed compared to
  471.59 +a well respected and highly optimized fft library.  I don't want to criticize 
  471.60 +this great library, so let's call it FFT_BRANDX.
  471.61 +During this process, I learned:
  471.62 +
  471.63 +    1. FFT_BRANDX has more than 100K lines of code. The core of kiss_fft is about 500 lines (cpx 1-d).
  471.64 +    2. It took me an embarrassingly long time to get FFT_BRANDX working.
  471.65 +    3. A simple program using FFT_BRANDX is 522KB. A similar program using kiss_fft is 18KB (without optimizing for size).
  471.66 +    4. FFT_BRANDX is roughly twice as fast as KISS FFT in default mode.
  471.67 +
  471.68 +    It is wonderful that free, highly optimized libraries like FFT_BRANDX exist.
  471.69 +But such libraries carry a huge burden of complexity necessary to extract every 
  471.70 +last bit of performance.
  471.71 +
  471.72 +    Sometimes simpler is better, even if it's not better.
  471.73 +
  471.74 +FREQUENTLY ASKED QUESTIONS:
  471.75 +	Q: Can I use kissfft in a project with a ___ license?
  471.76 +	A: Yes.  See LICENSE below.
  471.77 +
  471.78 +	Q: Why don't I get the output I expect?
  471.79 +	A: The two most common causes of this are 
  471.80 +		1) scaling : is there a constant multiplier between what you got and what you want?
  471.81 +		2) mixed build environment -- all code must be compiled with same preprocessor 
  471.82 +		definitions for FIXED_POINT and kiss_fft_scalar
  471.83 +
  471.84 +	Q: Will you write/debug my code for me?
  471.85 +	A: Probably not unless you pay me.  I am happy to answer pointed and topical questions, but 
  471.86 +	I may refer you to a book, a forum, or some other resource.
  471.87 +
  471.88 +
  471.89 +PERFORMANCE:
  471.90 +    (on Athlon XP 2100+, with gcc 2.96, float data type)
  471.91 +
  471.92 +    Kiss performed 10000 1024-pt cpx ffts in .63 s of cpu time.
  471.93 +    For comparison, it took md5sum twice as long to process the same amount of data.
  471.94 +
  471.95 +    Transforming 5 minutes of CD quality audio takes less than a second (nfft=1024). 
  471.96 +
  471.97 +DO NOT:
  471.98 +    ... use Kiss if you need the Fastest Fourier Transform in the World
  471.99 +    ... ask me to add features that will bloat the code
 471.100 +
 471.101 +UNDER THE HOOD:
 471.102 +
 471.103 +    Kiss FFT uses a time decimation, mixed-radix, out-of-place FFT. If you give it an input buffer  
 471.104 +    and output buffer that are the same, a temporary buffer will be created to hold the data.
 471.105 +
 471.106 +    No static data is used.  The core routines of kiss_fft are thread-safe (but not all of the tools directory).
 471.107 +
 471.108 +    No scaling is done for the floating point version (for speed).  
 471.109 +    Scaling is done both ways for the fixed-point version (for overflow prevention).
 471.110 +
 471.111 +    Optimized butterflies are used for factors 2,3,4, and 5. 
 471.112 +
 471.113 +    The real (i.e. not complex) optimization code only works for even length ffts.  It does two half-length
 471.114 +    FFTs in parallel (packed into real&imag), and then combines them via twiddling.  The result is 
 471.115 +    nfft/2+1 complex frequency bins from DC to Nyquist.  If you don't know what this means, search the web.
 471.116 +
 471.117 +    The fast convolution filtering uses the overlap-scrap method, slightly 
 471.118 +    modified to put the scrap at the tail.
 471.119 +
 471.120 +LICENSE:
 471.121 +    Revised BSD License, see COPYING for verbiage. 
 471.122 +    Basically, "free to use&change, give credit where due, no guarantees"
 471.123 +    Note this license is compatible with GPL at one end of the spectrum and closed, commercial software at 
 471.124 +    the other end.  See http://www.fsf.org/licensing/licenses
 471.125 +
 471.126 +    A commercial license is available which removes the requirement for attribution.  Contact me for details.
 471.127 +
 471.128 +  
 471.129 +TODO:
 471.130 +    *) Add real optimization for odd length FFTs 
 471.131 +    *) Document/revisit the input/output fft scaling
 471.132 +    *) Make doc describing the overlap (tail) scrap fast convolution filtering in kiss_fastfir.c
 471.133 +    *) Test all the ./tools/ code with fixed point (kiss_fastfir.c doesn't work, maybe others)
 471.134 +
 471.135 +AUTHOR:
 471.136 +    Mark Borgerding
 471.137 +    Mark@Borgerding.net
   472.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   472.2 +++ b/libs/kissfft/_kiss_fft_guts.h	Sat Feb 01 19:58:19 2014 +0200
   472.3 @@ -0,0 +1,165 @@
   472.4 +/*
   472.5 +Copyright (c) 2003-2010, Mark Borgerding
   472.6 +
   472.7 +All rights reserved.
   472.8 +
   472.9 +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  472.10 +
  472.11 +    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  472.12 +    * 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.
  472.13 +    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  472.14 +
  472.15 +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.
  472.16 +*/
  472.17 +
  472.18 +/* kiss_fft.h
  472.19 +   defines kiss_fft_scalar as either short or a float type
  472.20 +   and defines
  472.21 +   typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
  472.22 +#include "kiss_fft.h"
  472.23 +#include <limits.h>
  472.24 +
  472.25 +#define MAXFACTORS 32
  472.26 +/* e.g. an fft of length 128 has 4 factors 
  472.27 + as far as kissfft is concerned
  472.28 + 4*4*4*2
  472.29 + */
  472.30 +
  472.31 +struct kiss_fft_state{
  472.32 +    int nfft;
  472.33 +    int inverse;
  472.34 +    int factors[2*MAXFACTORS];
  472.35 +    kiss_fft_cpx twiddles[1];
  472.36 +};
  472.37 +
  472.38 +/*
  472.39 +  Explanation of macros dealing with complex math:
  472.40 +
  472.41 +   C_MUL(m,a,b)         : m = a*b
  472.42 +   C_FIXDIV( c , div )  : if a fixed point impl., c /= div. noop otherwise
  472.43 +   C_SUB( res, a,b)     : res = a - b
  472.44 +   C_SUBFROM( res , a)  : res -= a
  472.45 +   C_ADDTO( res , a)    : res += a
  472.46 + * */
  472.47 +#ifdef FIXED_POINT
  472.48 +#if (FIXED_POINT==32)
  472.49 +# define FRACBITS 31
  472.50 +# define SAMPPROD int64_t
  472.51 +#define SAMP_MAX 2147483647
  472.52 +#else
  472.53 +# define FRACBITS 15
  472.54 +# define SAMPPROD int32_t 
  472.55 +#define SAMP_MAX 32767
  472.56 +#endif
  472.57 +
  472.58 +#define SAMP_MIN -SAMP_MAX
  472.59 +
  472.60 +#if defined(CHECK_OVERFLOW)
  472.61 +#  define CHECK_OVERFLOW_OP(a,op,b)  \
  472.62 +	if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
  472.63 +		fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) );  }
  472.64 +#endif
  472.65 +
  472.66 +
  472.67 +#   define smul(a,b) ( (SAMPPROD)(a)*(b) )
  472.68 +#   define sround( x )  (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
  472.69 +
  472.70 +#   define S_MUL(a,b) sround( smul(a,b) )
  472.71 +
  472.72 +#   define C_MUL(m,a,b) \
  472.73 +      do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
  472.74 +          (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
  472.75 +
  472.76 +#   define DIVSCALAR(x,k) \
  472.77 +	(x) = sround( smul(  x, SAMP_MAX/k ) )
  472.78 +
  472.79 +#   define C_FIXDIV(c,div) \
  472.80 +	do {    DIVSCALAR( (c).r , div);  \
  472.81 +		DIVSCALAR( (c).i  , div); }while (0)
  472.82 +
  472.83 +#   define C_MULBYSCALAR( c, s ) \
  472.84 +    do{ (c).r =  sround( smul( (c).r , s ) ) ;\
  472.85 +        (c).i =  sround( smul( (c).i , s ) ) ; }while(0)
  472.86 +
  472.87 +#else  /* not FIXED_POINT*/
  472.88 +
  472.89 +#   define S_MUL(a,b) ( (a)*(b) )
  472.90 +#define C_MUL(m,a,b) \
  472.91 +    do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
  472.92 +        (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
  472.93 +#   define C_FIXDIV(c,div) /* NOOP */
  472.94 +#   define C_MULBYSCALAR( c, s ) \
  472.95 +    do{ (c).r *= (s);\
  472.96 +        (c).i *= (s); }while(0)
  472.97 +#endif
  472.98 +
  472.99 +#ifndef CHECK_OVERFLOW_OP
 472.100 +#  define CHECK_OVERFLOW_OP(a,op,b) /* noop */
 472.101 +#endif
 472.102 +
 472.103 +#define  C_ADD( res, a,b)\
 472.104 +    do { \
 472.105 +	    CHECK_OVERFLOW_OP((a).r,+,(b).r)\
 472.106 +	    CHECK_OVERFLOW_OP((a).i,+,(b).i)\
 472.107 +	    (res).r=(a).r+(b).r;  (res).i=(a).i+(b).i; \
 472.108 +    }while(0)
 472.109 +#define  C_SUB( res, a,b)\
 472.110 +    do { \
 472.111 +	    CHECK_OVERFLOW_OP((a).r,-,(b).r)\
 472.112 +	    CHECK_OVERFLOW_OP((a).i,-,(b).i)\
 472.113 +	    (res).r=(a).r-(b).r;  (res).i=(a).i-(b).i; \
 472.114 +    }while(0)
 472.115 +#define C_ADDTO( res , a)\
 472.116 +    do { \
 472.117 +	    CHECK_OVERFLOW_OP((res).r,+,(a).r)\
 472.118 +	    CHECK_OVERFLOW_OP((res).i,+,(a).i)\
 472.119 +	    (res).r += (a).r;  (res).i += (a).i;\
 472.120 +    }while(0)
 472.121 +
 472.122 +#define C_SUBFROM( res , a)\
 472.123 +    do {\
 472.124 +	    CHECK_OVERFLOW_OP((res).r,-,(a).r)\
 472.125 +	    CHECK_OVERFLOW_OP((res).i,-,(a).i)\
 472.126 +	    (res).r -= (a).r;  (res).i -= (a).i; \
 472.127 +    }while(0)
 472.128 +
 472.129 +
 472.130 +#ifdef FIXED_POINT
 472.131 +#  define KISS_FFT_COS(phase)  floor(.5+SAMP_MAX * cos (phase))
 472.132 +#  define KISS_FFT_SIN(phase)  floor(.5+SAMP_MAX * sin (phase))
 472.133 +#  define HALF_OF(x) ((x)>>1)
 472.134 +#elif defined(USE_SIMD)
 472.135 +#  define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
 472.136 +#  define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
 472.137 +#  define HALF_OF(x) ((x)*_mm_set1_ps(.5))
 472.138 +#else
 472.139 +#  define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
 472.140 +#  define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
 472.141 +#  define HALF_OF(x) ((x)*.5)
 472.142 +#endif
 472.143 +
 472.144 +#define  kf_cexp(x,phase) \
 472.145 +	do{ \
 472.146 +		(x)->r = KISS_FFT_COS(phase);\
 472.147 +		(x)->i = KISS_FFT_SIN(phase);\
 472.148 +	}while(0)
 472.149 +
 472.150 +
 472.151 +/* a debugging function */
 472.152 +#define pcpx(c)\
 472.153 +    fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
 472.154 +
 472.155 +
 472.156 +#ifdef KISS_FFT_USE_ALLOCA
 472.157 +/* define this to allow use of alloca instead of malloc for temporary buffers
 472.158 + * Temporary buffers are used in two case:
 472.159 + * 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
 472.160 + * 2. "in-place" FFTs.  Notice the quotes, since kissfft does not really do an in-place transform.
 472.161 + */
 472.162 +#include <alloca.h>
 472.163 +#define  KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
 472.164 +#define  KISS_FFT_TMP_FREE(ptr)
 472.165 +#else
 472.166 +#define  KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
 472.167 +#define  KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
 472.168 +#endif
   473.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   473.2 +++ b/libs/kissfft/kiss_fft.c	Sat Feb 01 19:58:19 2014 +0200
   473.3 @@ -0,0 +1,411 @@
   473.4 +/*
   473.5 +Copyright (c) 2003-2010, Mark Borgerding
   473.6 +
   473.7 +All rights reserved.
   473.8 +
   473.9 +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  473.10 +
  473.11 +    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  473.12 +    * 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.
  473.13 +    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  473.14 +
  473.15 +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.
  473.16 +*/
  473.17 +
  473.18 +
  473.19 +#include "_kiss_fft_guts.h"
  473.20 +/* The guts header contains all the multiplication and addition macros that are defined for
  473.21 + fixed or floating point complex numbers.  It also delares the kf_ internal functions.
  473.22 + */
  473.23 +
  473.24 +static void kf_bfly2(
  473.25 +        kiss_fft_cpx * Fout,
  473.26 +        const size_t fstride,
  473.27 +        const kiss_fft_cfg st,
  473.28 +        int m
  473.29 +        )
  473.30 +{
  473.31 +    kiss_fft_cpx * Fout2;
  473.32 +    kiss_fft_cpx * tw1 = st->twiddles;
  473.33 +    kiss_fft_cpx t;
  473.34 +    Fout2 = Fout + m;
  473.35 +    do{
  473.36 +        C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2);
  473.37 +
  473.38 +        C_MUL (t,  *Fout2 , *tw1);
  473.39 +        tw1 += fstride;
  473.40 +        C_SUB( *Fout2 ,  *Fout , t );
  473.41 +        C_ADDTO( *Fout ,  t );
  473.42 +        ++Fout2;
  473.43 +        ++Fout;
  473.44 +    }while (--m);
  473.45 +}
  473.46 +
  473.47 +static void kf_bfly4(
  473.48 +        kiss_fft_cpx * Fout,
  473.49 +        const size_t fstride,
  473.50 +        const kiss_fft_cfg st,
  473.51 +        const size_t m
  473.52 +        )
  473.53 +{
  473.54 +    kiss_fft_cpx *tw1,*tw2,*tw3;
  473.55 +    kiss_fft_cpx scratch[6];
  473.56 +    size_t k=m;
  473.57 +    const size_t m2=2*m;
  473.58 +    const size_t m3=3*m;
  473.59 +
  473.60 +
  473.61 +    tw3 = tw2 = tw1 = st->twiddles;
  473.62 +
  473.63 +    do {
  473.64 +        C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4);
  473.65 +
  473.66 +        C_MUL(scratch[0],Fout[m] , *tw1 );
  473.67 +        C_MUL(scratch[1],Fout[m2] , *tw2 );
  473.68 +        C_MUL(scratch[2],Fout[m3] , *tw3 );
  473.69 +
  473.70 +        C_SUB( scratch[5] , *Fout, scratch[1] );
  473.71 +        C_ADDTO(*Fout, scratch[1]);
  473.72 +        C_ADD( scratch[3] , scratch[0] , scratch[2] );
  473.73 +        C_SUB( scratch[4] , scratch[0] , scratch[2] );
  473.74 +        C_SUB( Fout[m2], *Fout, scratch[3] );
  473.75 +        tw1 += fstride;
  473.76 +        tw2 += fstride*2;
  473.77 +        tw3 += fstride*3;
  473.78 +        C_ADDTO( *Fout , scratch[3] );
  473.79 +
  473.80 +        if(st->inverse) {
  473.81 +            Fout[m].r = scratch[5].r - scratch[4].i;
  473.82 +            Fout[m].i = scratch[5].i + scratch[4].r;
  473.83 +            Fout[m3].r = scratch[5].r + scratch[4].i;
  473.84 +            Fout[m3].i = scratch[5].i - scratch[4].r;
  473.85 +        }else{
  473.86 +            Fout[m].r = scratch[5].r + scratch[4].i;
  473.87 +            Fout[m].i = scratch[5].i - scratch[4].r;
  473.88 +            Fout[m3].r = scratch[5].r - scratch[4].i;
  473.89 +            Fout[m3].i = scratch[5].i + scratch[4].r;
  473.90 +        }
  473.91 +        ++Fout;
  473.92 +    }while(--k);
  473.93 +}
  473.94 +
  473.95 +static void kf_bfly3(
  473.96 +         kiss_fft_cpx * Fout,
  473.97 +         const size_t fstride,
  473.98 +         const kiss_fft_cfg st,
  473.99 +         size_t m
 473.100 +         )
 473.101 +{
 473.102 +     size_t k=m;
 473.103 +     const size_t m2 = 2*m;
 473.104 +     kiss_fft_cpx *tw1,*tw2;
 473.105 +     kiss_fft_cpx scratch[5];
 473.106 +     kiss_fft_cpx epi3;
 473.107 +     epi3 = st->twiddles[fstride*m];
 473.108 +
 473.109 +     tw1=tw2=st->twiddles;
 473.110 +
 473.111 +     do{
 473.112 +         C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
 473.113 +
 473.114 +         C_MUL(scratch[1],Fout[m] , *tw1);
 473.115 +         C_MUL(scratch[2],Fout[m2] , *tw2);
 473.116 +
 473.117 +         C_ADD(scratch[3],scratch[1],scratch[2]);
 473.118 +         C_SUB(scratch[0],scratch[1],scratch[2]);
 473.119 +         tw1 += fstride;
 473.120 +         tw2 += fstride*2;
 473.121 +
 473.122 +         Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
 473.123 +         Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
 473.124 +
 473.125 +         C_MULBYSCALAR( scratch[0] , epi3.i );
 473.126 +
 473.127 +         C_ADDTO(*Fout,scratch[3]);
 473.128 +
 473.129 +         Fout[m2].r = Fout[m].r + scratch[0].i;
 473.130 +         Fout[m2].i = Fout[m].i - scratch[0].r;
 473.131 +
 473.132 +         Fout[m].r -= scratch[0].i;
 473.133 +         Fout[m].i += scratch[0].r;
 473.134 +
 473.135 +         ++Fout;
 473.136 +     }while(--k);
 473.137 +}
 473.138 +
 473.139 +static void kf_bfly5(
 473.140 +        kiss_fft_cpx * Fout,
 473.141 +        const size_t fstride,
 473.142 +        const kiss_fft_cfg st,
 473.143 +        int m
 473.144 +        )
 473.145 +{
 473.146 +    kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
 473.147 +    int u;
 473.148 +    kiss_fft_cpx scratch[13];
 473.149 +    kiss_fft_cpx * twiddles = st->twiddles;
 473.150 +    kiss_fft_cpx *tw;
 473.151 +    kiss_fft_cpx ya,yb;
 473.152 +    ya = twiddles[fstride*m];
 473.153 +    yb = twiddles[fstride*2*m];
 473.154 +
 473.155 +    Fout0=Fout;
 473.156 +    Fout1=Fout0+m;
 473.157 +    Fout2=Fout0+2*m;
 473.158 +    Fout3=Fout0+3*m;
 473.159 +    Fout4=Fout0+4*m;
 473.160 +
 473.161 +    tw=st->twiddles;
 473.162 +    for ( u=0; u<m; ++u ) {
 473.163 +        C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
 473.164 +        scratch[0] = *Fout0;
 473.165 +
 473.166 +        C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
 473.167 +        C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
 473.168 +        C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
 473.169 +        C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
 473.170 +
 473.171 +        C_ADD( scratch[7],scratch[1],scratch[4]);
 473.172 +        C_SUB( scratch[10],scratch[1],scratch[4]);
 473.173 +        C_ADD( scratch[8],scratch[2],scratch[3]);
 473.174 +        C_SUB( scratch[9],scratch[2],scratch[3]);
 473.175 +
 473.176 +        Fout0->r += scratch[7].r + scratch[8].r;
 473.177 +        Fout0->i += scratch[7].i + scratch[8].i;
 473.178 +
 473.179 +        scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
 473.180 +        scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
 473.181 +
 473.182 +        scratch[6].r =  S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
 473.183 +        scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
 473.184 +
 473.185 +        C_SUB(*Fout1,scratch[5],scratch[6]);
 473.186 +        C_ADD(*Fout4,scratch[5],scratch[6]);
 473.187 +
 473.188 +        scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
 473.189 +        scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
 473.190 +        scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
 473.191 +        scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
 473.192 +
 473.193 +        C_ADD(*Fout2,scratch[11],scratch[12]);
 473.194 +        C_SUB(*Fout3,scratch[11],scratch[12]);
 473.195 +
 473.196 +        ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
 473.197 +    }
 473.198 +}
 473.199 +
 473.200 +/* perform the butterfly for one stage of a mixed radix FFT */
 473.201 +static void kf_bfly_generic(
 473.202 +        kiss_fft_cpx * Fout,
 473.203 +        const size_t fstride,
 473.204 +        const kiss_fft_cfg st,
 473.205 +        int m,
 473.206 +        int p
 473.207 +        )
 473.208 +{
 473.209 +    int u,k,q1,q;
 473.210 +    kiss_fft_cpx * twiddles = st->twiddles;
 473.211 +    kiss_fft_cpx t;
 473.212 +    int Norig = st->nfft;
 473.213 +
 473.214 +    kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p);
 473.215 +
 473.216 +    for ( u=0; u<m; ++u ) {
 473.217 +        k=u;
 473.218 +        for ( q1=0 ; q1<p ; ++q1 ) {
 473.219 +            scratch[q1] = Fout[ k  ];
 473.220 +            C_FIXDIV(scratch[q1],p);
 473.221 +            k += m;
 473.222 +        }
 473.223 +
 473.224 +        k=u;
 473.225 +        for ( q1=0 ; q1<p ; ++q1 ) {
 473.226 +            int twidx=0;
 473.227 +            Fout[ k ] = scratch[0];
 473.228 +            for (q=1;q<p;++q ) {
 473.229 +                twidx += fstride * k;
 473.230 +                if (twidx>=Norig) twidx-=Norig;
 473.231 +                C_MUL(t,scratch[q] , twiddles[twidx] );
 473.232 +                C_ADDTO( Fout[ k ] ,t);
 473.233 +            }
 473.234 +            k += m;
 473.235 +        }
 473.236 +    }
 473.237 +    KISS_FFT_TMP_FREE(scratch);
 473.238 +}
 473.239 +
 473.240 +static
 473.241 +void kf_work(
 473.242 +        kiss_fft_cpx * Fout,
 473.243 +        const kiss_fft_cpx * f,
 473.244 +        const size_t fstride,
 473.245 +        int in_stride,
 473.246 +        int * factors,
 473.247 +        const kiss_fft_cfg st
 473.248 +        )
 473.249 +{
 473.250 +    kiss_fft_cpx * Fout_beg=Fout;
 473.251 +    const int p=*factors++; /* the radix  */
 473.252 +    const int m=*factors++; /* stage's fft length/p */
 473.253 +    const kiss_fft_cpx * Fout_end = Fout + p*m;
 473.254 +
 473.255 +#ifdef _OPENMP
 473.256 +    /* use openmp extensions at the
 473.257 +     * top-level (not recursive)
 473.258 +	 */
 473.259 +    if (fstride==1 && p<=5)
 473.260 +    {
 473.261 +        int k;
 473.262 +
 473.263 +        /* execute the p different work units in different threads */
 473.264 +#       pragma omp parallel for
 473.265 +        for (k=0;k<p;++k)
 473.266 +            kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st);
 473.267 +        /* all threads have joined by this point */
 473.268 +
 473.269 +        switch (p) {
 473.270 +            case 2: kf_bfly2(Fout,fstride,st,m); break;
 473.271 +            case 3: kf_bfly3(Fout,fstride,st,m); break; 
 473.272 +            case 4: kf_bfly4(Fout,fstride,st,m); break;
 473.273 +            case 5: kf_bfly5(Fout,fstride,st,m); break; 
 473.274 +            default: kf_bfly_generic(Fout,fstride,st,m,p); break;
 473.275 +        }
 473.276 +        return;
 473.277 +    }
 473.278 +#endif
 473.279 +
 473.280 +    if (m==1) {
 473.281 +        do{
 473.282 +            *Fout = *f;
 473.283 +            f += fstride*in_stride;
 473.284 +        }while(++Fout != Fout_end );
 473.285 +    }else{
 473.286 +        do{
 473.287 +            /* recursive call:
 473.288 +             * DFT of size m*p performed by doing
 473.289 +             * p instances of smaller DFTs of size m, 
 473.290 +             * each one takes a decimated version of the input
 473.291 +			 */
 473.292 +            kf_work( Fout , f, fstride*p, in_stride, factors,st);
 473.293 +            f += fstride*in_stride;
 473.294 +        }while( (Fout += m) != Fout_end );
 473.295 +    }
 473.296 +
 473.297 +    Fout=Fout_beg;
 473.298 +
 473.299 +    /* recombine the p smaller DFTs */
 473.300 +    switch (p) {
 473.301 +        case 2: kf_bfly2(Fout,fstride,st,m); break;
 473.302 +        case 3: kf_bfly3(Fout,fstride,st,m); break;
 473.303 +        case 4: kf_bfly4(Fout,fstride,st,m); break;
 473.304 +        case 5: kf_bfly5(Fout,fstride,st,m); break;
 473.305 +        default: kf_bfly_generic(Fout,fstride,st,m,p); break;
 473.306 +    }
 473.307 +}
 473.308 +
 473.309 +/*  facbuf is populated by p1,m1,p2,m2, ...
 473.310 +    where
 473.311 +    p[i] * m[i] = m[i-1]
 473.312 +    m0 = n                  */
 473.313 +static
 473.314 +void kf_factor(int n,int * facbuf)
 473.315 +{
 473.316 +    int p=4;
 473.317 +    double floor_sqrt;
 473.318 +    floor_sqrt = floor( sqrt((double)n) );
 473.319 +
 473.320 +    /*factor out powers of 4, powers of 2, then any remaining primes */
 473.321 +    do {
 473.322 +        while (n % p) {
 473.323 +            switch (p) {
 473.324 +                case 4: p = 2; break;
 473.325 +                case 2: p = 3; break;
 473.326 +                default: p += 2; break;
 473.327 +            }
 473.328 +            if (p > floor_sqrt)
 473.329 +                p = n;          /* no more factors, skip to end */
 473.330 +        }
 473.331 +        n /= p;
 473.332 +        *facbuf++ = p;
 473.333 +        *facbuf++ = n;
 473.334 +    } while (n > 1);
 473.335 +}
 473.336 +
 473.337 +/*
 473.338 + *
 473.339 + * User-callable function to allocate all necessary storage space for the fft.
 473.340 + *
 473.341 + * The return value is a contiguous block of memory, allocated with malloc.  As such,
 473.342 + * It can be freed with free(), rather than a kiss_fft-specific function.
 473.343 + * */
 473.344 +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
 473.345 +{
 473.346 +    kiss_fft_cfg st=NULL;
 473.347 +    size_t memneeded = sizeof(struct kiss_fft_state)
 473.348 +        + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
 473.349 +
 473.350 +    if ( lenmem==NULL ) {
 473.351 +        st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
 473.352 +    }else{
 473.353 +        if (mem != NULL && *lenmem >= memneeded)
 473.354 +            st = (kiss_fft_cfg)mem;
 473.355 +        *lenmem = memneeded;
 473.356 +    }
 473.357 +    if (st) {
 473.358 +        int i;
 473.359 +        st->nfft=nfft;
 473.360 +        st->inverse = inverse_fft;
 473.361 +
 473.362 +        for (i=0;i<nfft;++i) {
 473.363 +            const double pi=3.141592653589793238462643383279502884197169399375105820974944;
 473.364 +            double phase = -2*pi*i / nfft;
 473.365 +            if (st->inverse)
 473.366 +                phase *= -1;
 473.367 +            kf_cexp(st->twiddles+i, phase );
 473.368 +        }
 473.369 +
 473.370 +        kf_factor(nfft,st->factors);
 473.371 +    }
 473.372 +    return st;
 473.373 +}
 473.374 +
 473.375 +
 473.376 +void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
 473.377 +{
 473.378 +    if (fin == fout) {
 473.379 +        /* NOTE: this is not really an in-place FFT algorithm.
 473.380 +         * It just performs an out-of-place FFT into a temp buffer
 473.381 +		 */
 473.382 +        kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft);
 473.383 +        kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
 473.384 +        memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
 473.385 +        KISS_FFT_TMP_FREE(tmpbuf);
 473.386 +    }else{
 473.387 +        kf_work( fout, fin, 1,in_stride, st->factors,st );
 473.388 +    }
 473.389 +}
 473.390 +
 473.391 +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
 473.392 +{
 473.393 +    kiss_fft_stride(cfg,fin,fout,1);
 473.394 +}
 473.395 +
 473.396 +
 473.397 +void kiss_fft_cleanup(void)
 473.398 +{
 473.399 +    /* nothing needed any more */
 473.400 +}
 473.401 +
 473.402 +int kiss_fft_next_fast_size(int n)
 473.403 +{
 473.404 +    while(1) {
 473.405 +        int m=n;
 473.406 +        while ( (m%2) == 0 ) m/=2;
 473.407 +        while ( (m%3) == 0 ) m/=3;
 473.408 +        while ( (m%5) == 0 ) m/=5;
 473.409 +        if (m<=1)
 473.410 +            break; /* n is completely factorable by twos, threes, and fives */
 473.411 +        n++;
 473.412 +    }
 473.413 +    return n;
 473.414 +}
   474.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   474.2 +++ b/libs/kissfft/kiss_fft.h	Sat Feb 01 19:58:19 2014 +0200
   474.3 @@ -0,0 +1,124 @@
   474.4 +#ifndef KISS_FFT_H
   474.5 +#define KISS_FFT_H
   474.6 +
   474.7 +#include <stdlib.h>
   474.8 +#include <stdio.h>
   474.9 +#include <math.h>
  474.10 +#include <string.h>
  474.11 +
  474.12 +#ifdef __cplusplus
  474.13 +extern "C" {
  474.14 +#endif
  474.15 +
  474.16 +/*
  474.17 + ATTENTION!
  474.18 + If you would like a :
  474.19 + -- a utility that will handle the caching of fft objects
  474.20 + -- real-only (no imaginary time component ) FFT
  474.21 + -- a multi-dimensional FFT
  474.22 + -- a command-line utility to perform ffts
  474.23 + -- a command-line utility to perform fast-convolution filtering
  474.24 +
  474.25 + Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
  474.26 +  in the tools/ directory.
  474.27 +*/
  474.28 +
  474.29 +#ifdef USE_SIMD
  474.30 +# include <xmmintrin.h>
  474.31 +# define kiss_fft_scalar __m128
  474.32 +#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16)
  474.33 +#define KISS_FFT_FREE _mm_free
  474.34 +#else	
  474.35 +#define KISS_FFT_MALLOC malloc
  474.36 +#define KISS_FFT_FREE free
  474.37 +#endif	
  474.38 +
  474.39 +
  474.40 +#ifdef FIXED_POINT
  474.41 +#include <sys/types.h>	
  474.42 +# if (FIXED_POINT == 32)
  474.43 +#  define kiss_fft_scalar int32_t
  474.44 +# else	
  474.45 +#  define kiss_fft_scalar int16_t
  474.46 +# endif
  474.47 +#else
  474.48 +# ifndef kiss_fft_scalar
  474.49 +/*  default is float */
  474.50 +#   define kiss_fft_scalar float
  474.51 +# endif
  474.52 +#endif
  474.53 +
  474.54 +typedef struct {
  474.55 +    kiss_fft_scalar r;
  474.56 +    kiss_fft_scalar i;
  474.57 +}kiss_fft_cpx;
  474.58 +
  474.59 +typedef struct kiss_fft_state* kiss_fft_cfg;
  474.60 +
  474.61 +/* 
  474.62 + *  kiss_fft_alloc
  474.63 + *  
  474.64 + *  Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
  474.65 + *
  474.66 + *  typical usage:      kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
  474.67 + *
  474.68 + *  The return value from fft_alloc is a cfg buffer used internally
  474.69 + *  by the fft routine or NULL.
  474.70 + *
  474.71 + *  If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
  474.72 + *  The returned value should be free()d when done to avoid memory leaks.
  474.73 + *  
  474.74 + *  The state can be placed in a user supplied buffer 'mem':
  474.75 + *  If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
  474.76 + *      then the function places the cfg in mem and the size used in *lenmem
  474.77 + *      and returns mem.
  474.78 + *  
  474.79 + *  If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
  474.80 + *      then the function returns NULL and places the minimum cfg 
  474.81 + *      buffer size in *lenmem.
  474.82 + * */
  474.83 +
  474.84 +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); 
  474.85 +
  474.86 +/*
  474.87 + * kiss_fft(cfg,in_out_buf)
  474.88 + *
  474.89 + * Perform an FFT on a complex input buffer.
  474.90 + * for a forward FFT,
  474.91 + * fin should be  f[0] , f[1] , ... ,f[nfft-1]
  474.92 + * fout will be   F[0] , F[1] , ... ,F[nfft-1]
  474.93 + * Note that each element is complex and can be accessed like
  474.94 +    f[k].r and f[k].i
  474.95 + * */
  474.96 +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
  474.97 +
  474.98 +/*
  474.99 + A more generic version of the above function. It reads its input from every Nth sample.
 474.100 + * */
 474.101 +void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
 474.102 +
 474.103 +/* If kiss_fft_alloc allocated a buffer, it is one contiguous 
 474.104 +   buffer and can be simply free()d when no longer needed*/
 474.105 +#define kiss_fft_free free
 474.106 +
 474.107 +/*
 474.108 + Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up 
 474.109 + your compiler output to call this before you exit.
 474.110 +*/
 474.111 +void kiss_fft_cleanup(void);
 474.112 +	
 474.113 +
 474.114 +/*
 474.115 + * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5)
 474.116 + */
 474.117 +int kiss_fft_next_fast_size(int n);
 474.118 +
 474.119 +/* for real ffts, we need an even size */
 474.120 +#define kiss_fftr_next_fast_size_real(n) \
 474.121 +        (kiss_fft_next_fast_size( ((n)+1)>>1)<<1)
 474.122 +
 474.123 +#ifdef __cplusplus
 474.124 +} 
 474.125 +#endif
 474.126 +
 474.127 +#endif
   475.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   475.2 +++ b/libs/kissfft/kiss_fftr.c	Sat Feb 01 19:58:19 2014 +0200
   475.3 @@ -0,0 +1,159 @@
   475.4 +/*
   475.5 +Copyright (c) 2003-2004, Mark Borgerding
   475.6 +
   475.7 +All rights reserved.
   475.8 +
   475.9 +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  475.10 +
  475.11 +    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  475.12 +    * 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.
  475.13 +    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  475.14 +
  475.15 +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.
  475.16 +*/
  475.17 +
  475.18 +#include "kiss_fftr.h"
  475.19 +#include "_kiss_fft_guts.h"
  475.20 +
  475.21 +struct kiss_fftr_state{
  475.22 +    kiss_fft_cfg substate;
  475.23 +    kiss_fft_cpx * tmpbuf;
  475.24 +    kiss_fft_cpx * super_twiddles;
  475.25 +#ifdef USE_SIMD
  475.26 +    void * pad;
  475.27 +#endif
  475.28 +};
  475.29 +
  475.30 +kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
  475.31 +{
  475.32 +    int i;
  475.33 +    kiss_fftr_cfg st = NULL;
  475.34 +    size_t subsize, memneeded;
  475.35 +
  475.36 +    if (nfft & 1) {
  475.37 +        fprintf(stderr,"Real FFT optimization must be even.\n");
  475.38 +        return NULL;
  475.39 +    }
  475.40 +    nfft >>= 1;
  475.41 +
  475.42 +    kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);
  475.43 +    memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2);
  475.44 +
  475.45 +    if (lenmem == NULL) {
  475.46 +        st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);
  475.47 +    } else {
  475.48 +        if (*lenmem >= memneeded)
  475.49 +            st = (kiss_fftr_cfg) mem;
  475.50 +        *lenmem = memneeded;
  475.51 +    }
  475.52 +    if (!st)
  475.53 +        return NULL;
  475.54 +
  475.55 +    st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
  475.56 +    st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
  475.57 +    st->super_twiddles = st->tmpbuf + nfft;
  475.58 +    kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
  475.59 +
  475.60 +    for (i = 0; i < nfft/2; ++i) {
  475.61 +        double phase =
  475.62 +            -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5);
  475.63 +        if (inverse_fft)
  475.64 +            phase *= -1;
  475.65 +        kf_cexp (st->super_twiddles+i,phase);
  475.66 +    }
  475.67 +    return st;
  475.68 +}
  475.69 +
  475.70 +void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
  475.71 +{
  475.72 +    /* input buffer timedata is stored row-wise */
  475.73 +    int k,ncfft;
  475.74 +    kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
  475.75 +
  475.76 +    if ( st->substate->inverse) {
  475.77 +        fprintf(stderr,"kiss fft usage error: improper alloc\n");
  475.78 +        exit(1);
  475.79 +    }
  475.80 +
  475.81 +    ncfft = st->substate->nfft;
  475.82 +
  475.83 +    /*perform the parallel fft of two real signals packed in real,imag*/
  475.84 +    kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
  475.85 +    /* The real part of the DC element of the frequency spectrum in st->tmpbuf
  475.86 +     * contains the sum of the even-numbered elements of the input time sequence
  475.87 +     * The imag part is the sum of the odd-numbered elements
  475.88 +     *
  475.89 +     * The sum of tdc.r and tdc.i is the sum of the input time sequence. 
  475.90 +     *      yielding DC of input time sequence
  475.91 +     * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... 
  475.92 +     *      yielding Nyquist bin of input time sequence
  475.93 +     */
  475.94 + 
  475.95 +    tdc.r = st->tmpbuf[0].r;
  475.96 +    tdc.i = st->tmpbuf[0].i;
  475.97 +    C_FIXDIV(tdc,2);
  475.98 +    CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
  475.99 +    CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
 475.100 +    freqdata[0].r = tdc.r + tdc.i;
 475.101 +    freqdata[ncfft].r = tdc.r - tdc.i;
 475.102 +#ifdef USE_SIMD    
 475.103 +    freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
 475.104 +#else
 475.105 +    freqdata[ncfft].i = freqdata[0].i = 0;
 475.106 +#endif
 475.107 +
 475.108 +    for ( k=1;k <= ncfft/2 ; ++k ) {
 475.109 +        fpk    = st->tmpbuf[k]; 
 475.110 +        fpnk.r =   st->tmpbuf[ncfft-k].r;
 475.111 +        fpnk.i = - st->tmpbuf[ncfft-k].i;
 475.112 +        C_FIXDIV(fpk,2);
 475.113 +        C_FIXDIV(fpnk,2);
 475.114 +
 475.115 +        C_ADD( f1k, fpk , fpnk );
 475.116 +        C_SUB( f2k, fpk , fpnk );
 475.117 +        C_MUL( tw , f2k , st->super_twiddles[k-1]);
 475.118 +
 475.119 +        freqdata[k].r = HALF_OF(f1k.r + tw.r);
 475.120 +        freqdata[k].i = HALF_OF(f1k.i + tw.i);
 475.121 +        freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r);
 475.122 +        freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i);
 475.123 +    }
 475.124 +}
 475.125 +
 475.126 +void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata)
 475.127 +{
 475.128 +    /* input buffer timedata is stored row-wise */
 475.129 +    int k, ncfft;
 475.130 +
 475.131 +    if (st->substate->inverse == 0) {
 475.132 +        fprintf (stderr, "kiss fft usage error: improper alloc\n");
 475.133 +        exit (1);
 475.134 +    }
 475.135 +
 475.136 +    ncfft = st->substate->nfft;
 475.137 +
 475.138 +    st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;
 475.139 +    st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;
 475.140 +    C_FIXDIV(st->tmpbuf[0],2);
 475.141 +
 475.142 +    for (k = 1; k <= ncfft / 2; ++k) {
 475.143 +        kiss_fft_cpx fk, fnkc, fek, fok, tmp;
 475.144 +        fk = freqdata[k];
 475.145 +        fnkc.r = freqdata[ncfft - k].r;
 475.146 +        fnkc.i = -freqdata[ncfft - k].i;
 475.147 +        C_FIXDIV( fk , 2 );
 475.148 +        C_FIXDIV( fnkc , 2 );
 475.149 +
 475.150 +        C_ADD (fek, fk, fnkc);
 475.151 +        C_SUB (tmp, fk, fnkc);
 475.152 +        C_MUL (fok, tmp, st->super_twiddles[k-1]);
 475.153 +        C_ADD (st->tmpbuf[k],     fek, fok);
 475.154 +        C_SUB (st->tmpbuf[ncfft - k], fek, fok);
 475.155 +#ifdef USE_SIMD        
 475.156 +        st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
 475.157 +#else
 475.158 +        st->tmpbuf[ncfft - k].i *= -1;
 475.159 +#endif
 475.160 +    }
 475.161 +    kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
 475.162 +}
   476.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   476.2 +++ b/libs/kissfft/kiss_fftr.h	Sat Feb 01 19:58:19 2014 +0200
   476.3 @@ -0,0 +1,46 @@
   476.4 +#ifndef KISS_FTR_H
   476.5 +#define KISS_FTR_H
   476.6 +
   476.7 +#include "kiss_fft.h"
   476.8 +#ifdef __cplusplus
   476.9 +extern "C" {
  476.10 +#endif
  476.11 +
  476.12 +    
  476.13 +/* 
  476.14 + 
  476.15 + Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
  476.16 +
  476.17 + 
  476.18 + 
  476.19 + */
  476.20 +
  476.21 +typedef struct kiss_fftr_state *kiss_fftr_cfg;
  476.22 +
  476.23 +
  476.24 +kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
  476.25 +/*
  476.26 + nfft must be even
  476.27 +
  476.28 + If you don't care to allocate space, use mem = lenmem = NULL 
  476.29 +*/
  476.30 +
  476.31 +
  476.32 +void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
  476.33 +/*
  476.34 + input timedata has nfft scalar points
  476.35 + output freqdata has nfft/2+1 complex points
  476.36 +*/
  476.37 +
  476.38 +void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
  476.39 +/*
  476.40 + input freqdata has  nfft/2+1 complex points
  476.41 + output timedata has nfft scalar points
  476.42 +*/
  476.43 +
  476.44 +#define kiss_fftr_free free
  476.45 +
  476.46 +#ifdef __cplusplus
  476.47 +}
  476.48 +#endif
  476.49 +#endif
   477.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   477.2 +++ b/libs/libjpeg/README	Sat Feb 01 19:58:19 2014 +0200
   477.3 @@ -0,0 +1,326 @@
   477.4 +The Independent JPEG Group's JPEG software
   477.5 +==========================================
   477.6 +
   477.7 +README for release 8c of 16-Jan-2011
   477.8 +====================================
   477.9 +
  477.10 +This distribution contains the eighth public release of the Independent JPEG
  477.11 +Group's free JPEG software.  You are welcome to redistribute this software and
  477.12 +to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
  477.13 +
  477.14 +This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone,
  477.15 +Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
  477.16 +Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
  477.17 +and other members of the Independent JPEG Group.
  477.18 +
  477.19 +IJG is not affiliated with the official ISO JPEG standards committee.
  477.20 +
  477.21 +
  477.22 +DOCUMENTATION ROADMAP
  477.23 +=====================
  477.24 +
  477.25 +This file contains the following sections:
  477.26 +
  477.27 +OVERVIEW            General description of JPEG and the IJG software.
  477.28 +LEGAL ISSUES        Copyright, lack of warranty, terms of distribution.
  477.29 +REFERENCES          Where to learn more about JPEG.
  477.30 +ARCHIVE LOCATIONS   Where to find newer versions of this software.
  477.31 +ACKNOWLEDGMENTS     Special thanks.
  477.32 +FILE FORMAT WARS    Software *not* to get.
  477.33 +TO DO               Plans for future IJG releases.
  477.34 +
  477.35 +Other documentation files in the distribution are:
  477.36 +
  477.37 +User documentation:
  477.38 +  install.txt       How to configure and install the IJG software.
  477.39 +  usage.txt         Usage instructions for cjpeg, djpeg, jpegtran,
  477.40 +                    rdjpgcom, and wrjpgcom.
  477.41 +  *.1               Unix-style man pages for programs (same info as usage.txt).
  477.42 +  wizard.txt        Advanced usage instructions for JPEG wizards only.
  477.43 +  change.log        Version-to-version change highlights.
  477.44 +Programmer and internal documentation:
  477.45 +  libjpeg.txt       How to use the JPEG library in your own programs.
  477.46 +  example.c         Sample code for calling the JPEG library.
  477.47 +  structure.txt     Overview of the JPEG library's internal structure.
  477.48 +  filelist.txt      Road map of IJG files.
  477.49 +  coderules.txt     Coding style rules --- please read if you contribute code.
  477.50 +
  477.51 +Please read at least the files install.txt and usage.txt.  Some information
  477.52 +can also be found in the JPEG FAQ (Frequently Asked Questions) article.  See
  477.53 +ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
  477.54 +
  477.55 +If you want to understand how the JPEG code works, we suggest reading one or
  477.56 +more of the REFERENCES, then looking at the documentation files (in roughly
  477.57 +the order listed) before diving into the code.
  477.58 +
  477.59 +
  477.60 +OVERVIEW
  477.61 +========
  477.62 +
  477.63 +This package contains C software to implement JPEG image encoding, decoding,
  477.64 +and transcoding.  JPEG (pronounced "jay-peg") is a standardized compression
  477.65 +method for full-color and gray-scale images.
  477.66 +
  477.67 +This software implements JPEG baseline, extended-sequential, and progressive
  477.68 +compression processes.  Provision is made for supporting all variants of these
  477.69 +processes, although some uncommon parameter settings aren't implemented yet.
  477.70 +We have made no provision for supporting the hierarchical or lossless
  477.71 +processes defined in the standard.
  477.72 +
  477.73 +We provide a set of library routines for reading and writing JPEG image files,
  477.74 +plus two sample applications "cjpeg" and "djpeg", which use the library to
  477.75 +perform conversion between JPEG and some other popular image file formats.
  477.76 +The library is intended to be reused in other applications.
  477.77 +
  477.78 +In order to support file conversion and viewing software, we have included
  477.79 +considerable functionality beyond the bare JPEG coding/decoding capability;
  477.80 +for example, the color quantization modules are not strictly part of JPEG
  477.81 +decoding, but they are essential for output to colormapped file formats or
  477.82 +colormapped displays.  These extra functions can be compiled out of the
  477.83 +library if not required for a particular application.
  477.84 +
  477.85 +We have also included "jpegtran", a utility for lossless transcoding between
  477.86 +different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple
  477.87 +applications for inserting and extracting textual comments in JFIF files.
  477.88 +
  477.89 +The emphasis in designing this software has been on achieving portability and
  477.90 +flexibility, while also making it fast enough to be useful.  In particular,
  477.91 +the software is not intended to be read as a tutorial on JPEG.  (See the
  477.92 +REFERENCES section for introductory material.)  Rather, it is intended to
  477.93 +be reliable, portable, industrial-strength code.  We do not claim to have
  477.94 +achieved that goal in every aspect of the software, but we strive for it.
  477.95 +
  477.96 +We welcome the use of this software as a component of commercial products.
  477.97 +No royalty is required, but we do ask for an acknowledgement in product
  477.98 +documentation, as described under LEGAL ISSUES.
  477.99 +
 477.100 +
 477.101 +LEGAL ISSUES
 477.102 +============
 477.103 +
 477.104 +In plain English:
 477.105 +
 477.106 +1. We don't promise that this software works.  (But if you find any bugs,
 477.107 +   please let us know!)
 477.108 +2. You can use this software for whatever you want.  You don't have to pay us.
 477.109 +3. You may not pretend that you wrote this software.  If you use it in a
 477.110 +   program, you must acknowledge somewhere in your documentation that
 477.111 +   you've used the IJG code.
 477.112 +
 477.113 +In legalese:
 477.114 +
 477.115 +The authors make NO WARRANTY or representation, either express or implied,
 477.116 +with respect to this software, its quality, accuracy, merchantability, or
 477.117 +fitness for a particular purpose.  This software is provided "AS IS", and you,
 477.118 +its user, assume the entire risk as to its quality and accuracy.
 477.119 +
 477.120 +This software is copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding.
 477.121 +All Rights Reserved except as specified below.
 477.122 +
 477.123 +Permission is hereby granted to use, copy, modify, and distribute this
 477.124 +software (or portions thereof) for any purpose, without fee, subject to these
 477.125 +conditions:
 477.126 +(1) If any part of the source code for this software is distributed, then this
 477.127 +README file must be included, with this copyright and no-warranty notice
 477.128 +unaltered; and any additions, deletions, or changes to the original files
 477.129 +must be clearly indicated in accompanying documentation.
 477.130 +(2) If only executable code is distributed, then the accompanying
 477.131 +documentation must state that "this software is based in part on the work of
 477.132 +the Independent JPEG Group".
 477.133 +(3) Permission for use of this software is granted only if the user accepts
 477.134 +full responsibility for any undesirable consequences; the authors accept
 477.135 +NO LIABILITY for damages of any kind.
 477.136 +
 477.137 +These conditions apply to any software derived from or based on the IJG code,
 477.138 +not just to the unmodified library.  If you use our work, you ought to
 477.139 +acknowledge us.
 477.140 +
 477.141 +Permission is NOT granted for the use of any IJG author's name or company name
 477.142 +in advertising or publicity relating to this software or products derived from
 477.143 +it.  This software may be referred to only as "the Independent JPEG Group's
 477.144 +software".
 477.145 +
 477.146 +We specifically permit and encourage the use of this software as the basis of
 477.147 +commercial products, provided that all warranty or liability claims are
 477.148 +assumed by the product vendor.
 477.149 +
 477.150 +
 477.151 +ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
 477.152 +sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
 477.153 +ansi2knr.c is NOT covered by the above copyright and conditions, but instead
 477.154 +by the usual distribution terms of the Free Software Foundation; principally,
 477.155 +that you must include source code if you redistribute it.  (See the file
 477.156 +ansi2knr.c for full details.)  However, since ansi2knr.c is not needed as part
 477.157 +of any program generated from the IJG code, this does not limit you more than
 477.158 +the foregoing paragraphs do.
 477.159 +
 477.160 +The Unix configuration script "configure" was produced with GNU Autoconf.
 477.161 +It is copyright by the Free Software Foundation but is freely distributable.
 477.162 +The same holds for its supporting scripts (config.guess, config.sub,
 477.163 +ltmain.sh).  Another support script, install-sh, is copyright by X Consortium
 477.164 +but is also freely distributable.
 477.165 +
 477.166 +The IJG distribution formerly included code to read and write GIF files.
 477.167 +To avoid entanglement with the Unisys LZW patent, GIF reading support has
 477.168 +been removed altogether, and the GIF writer has been simplified to produce
 477.169 +"uncompressed GIFs".  This technique does not use the LZW algorithm; the
 477.170 +resulting GIF files are larger than usual, but are readable by all standard
 477.171 +GIF decoders.
 477.172 +
 477.173 +We are required to state that
 477.174 +    "The Graphics Interchange Format(c) is the Copyright property of
 477.175 +    CompuServe Incorporated.  GIF(sm) is a Service Mark property of
 477.176 +    CompuServe Incorporated."
 477.177 +
 477.178 +
 477.179 +REFERENCES
 477.180 +==========
 477.181 +
 477.182 +We recommend reading one or more of these references before trying to
 477.183 +understand the innards of the JPEG software.
 477.184 +
 477.185 +The best short technical introduction to the JPEG compression algorithm is
 477.186 +	Wallace, Gregory K.  "The JPEG Still Picture Compression Standard",
 477.187 +	Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
 477.188 +(Adjacent articles in that issue discuss MPEG motion picture compression,
 477.189 +applications of JPEG, and related topics.)  If you don't have the CACM issue
 477.190 +handy, a PostScript file containing a revised version of Wallace's article is
 477.191 +available at http://www.ijg.org/files/wallace.ps.gz.  The file (actually
 477.192 +a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
 477.193 +omits the sample images that appeared in CACM, but it includes corrections
 477.194 +and some added material.  Note: the Wallace article is copyright ACM and IEEE,
 477.195 +and it may not be used for commercial purposes.
 477.196 +
 477.197 +A somewhat less technical, more leisurely introduction to JPEG can be found in
 477.198 +"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
 477.199 +M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1.  This book provides
 477.200 +good explanations and example C code for a multitude of compression methods
 477.201 +including JPEG.  It is an excellent source if you are comfortable reading C
 477.202 +code but don't know much about data compression in general.  The book's JPEG
 477.203 +sample code is far from industrial-strength, but when you are ready to look
 477.204 +at a full implementation, you've got one here...
 477.205 +
 477.206 +The best currently available description of JPEG is the textbook "JPEG Still
 477.207 +Image Data Compression Standard" by William B. Pennebaker and Joan L.
 477.208 +Mitchell, published by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1.
 477.209 +Price US$59.95, 638 pp.  The book includes the complete text of the ISO JPEG
 477.210 +standards (DIS 10918-1 and draft DIS 10918-2).
 477.211 +Although this is by far the most detailed and comprehensive exposition of
 477.212 +JPEG publicly available, we point out that it is still missing an explanation
 477.213 +of the most essential properties and algorithms of the underlying DCT
 477.214 +technology.
 477.215 +If you think that you know about DCT-based JPEG after reading this book,
 477.216 +then you are in delusion.  The real fundamentals and corresponding potential
 477.217 +of DCT-based JPEG are not publicly known so far, and that is the reason for
 477.218 +all the mistaken developments taking place in the image coding domain.
 477.219 +
 477.220 +The original JPEG standard is divided into two parts, Part 1 being the actual
 477.221 +specification, while Part 2 covers compliance testing methods.  Part 1 is
 477.222 +titled "Digital Compression and Coding of Continuous-tone Still Images,
 477.223 +Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
 477.224 +10918-1, ITU-T T.81.  Part 2 is titled "Digital Compression and Coding of
 477.225 +Continuous-tone Still Images, Part 2: Compliance testing" and has document
 477.226 +numbers ISO/IEC IS 10918-2, ITU-T T.83.
 477.227 +IJG JPEG 8 introduces an implementation of the JPEG SmartScale extension
 477.228 +which is specified in a contributed document at ITU and ISO with title "ITU-T
 477.229 +JPEG-Plus Proposal for Extending ITU-T T.81 for Advanced Image Coding", April
 477.230 +2006, Geneva, Switzerland.  The latest version of the document is Revision 3.
 477.231 +
 477.232 +The JPEG standard does not specify all details of an interchangeable file
 477.233 +format.  For the omitted details we follow the "JFIF" conventions, revision
 477.234 +1.02.  JFIF 1.02 has been adopted as an Ecma International Technical Report
 477.235 +and thus received a formal publication status.  It is available as a free
 477.236 +download in PDF format from
 477.237 +http://www.ecma-international.org/publications/techreports/E-TR-098.htm.
 477.238 +A PostScript version of the JFIF document is available at
 477.239 +http://www.ijg.org/files/jfif.ps.gz.  There is also a plain text version at
 477.240 +http://www.ijg.org/files/jfif.txt.gz, but it is missing the figures.
 477.241 +
 477.242 +The TIFF 6.0 file format specification can be obtained by FTP from
 477.243 +ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz.  The JPEG incorporation scheme
 477.244 +found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
 477.245 +IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
 477.246 +Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
 477.247 +(Compression tag 7).  Copies of this Note can be obtained from
 477.248 +http://www.ijg.org/files/.  It is expected that the next revision
 477.249 +of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
 477.250 +Although IJG's own code does not support TIFF/JPEG, the free libtiff library
 477.251 +uses our library to implement TIFF/JPEG per the Note.
 477.252 +
 477.253 +
 477.254 +ARCHIVE LOCATIONS
 477.255 +=================
 477.256 +
 477.257 +The "official" archive site for this software is www.ijg.org.
 477.258 +The most recent released version can always be found there in
 477.259 +directory "files".  This particular version will be archived as
 477.260 +http://www.ijg.org/files/jpegsrc.v8c.tar.gz, and in Windows-compatible
 477.261 +"zip" archive format as http://www.ijg.org/files/jpegsr8c.zip.
 477.262 +
 477.263 +The JPEG FAQ (Frequently Asked Questions) article is a source of some
 477.264 +general information about JPEG.
 477.265 +It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
 477.266 +and other news.answers archive sites, including the official news.answers
 477.267 +archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
 477.268 +If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
 477.269 +with body
 477.270 +	send usenet/news.answers/jpeg-faq/part1
 477.271 +	send usenet/news.answers/jpeg-faq/part2
 477.272 +
 477.273 +
 477.274 +ACKNOWLEDGMENTS
 477.275 +===============
 477.276 +
 477.277 +Thank to Juergen Bruder for providing me with a copy of the common DCT
 477.278 +algorithm article, only to find out that I had come to the same result
 477.279 +in a more direct and comprehensible way with a more generative approach.
 477.280 +
 477.281 +Thank to Istvan Sebestyen and Joan L. Mitchell for inviting me to the
 477.282 +ITU JPEG (Study Group 16) meeting in Geneva, Switzerland.
 477.283 +
 477.284 +Thank to Thomas Wiegand and Gary Sullivan for inviting me to the
 477.285 +Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland.
 477.286 +
 477.287 +Thank to John Korejwa and Massimo Ballerini for inviting me to
 477.288 +fruitful consultations in Boston, MA and Milan, Italy.
 477.289 +
 477.290 +Thank to Hendrik Elstner, Roland Fassauer, Simone Zuck, Guenther
 477.291 +Maier-Gerber, Walter Stoeber, Fred Schmitz, and Norbert Braunagel
 477.292 +for corresponding business development.
 477.293 +
 477.294 +Thank to Nico Zschach and Dirk Stelling of the technical support team
 477.295 +at the Digital Images company in Halle for providing me with extra
 477.296 +equipment for configuration tests.
 477.297 +
 477.298 +Thank to Richard F. Lyon (then of Foveon Inc.) for fruitful
 477.299 +communication about JPEG configuration in Sigma Photo Pro software.
 477.300 +
 477.301 +Thank to Andrew Finkenstadt for hosting the ijg.org site.
 477.302 +
 477.303 +Last but not least special thank to Thomas G. Lane for the original
 477.304 +design and development of this singular software package.
 477.305 +
 477.306 +
 477.307 +FILE FORMAT WARS
 477.308 +================
 477.309 +
 477.310 +The ISO JPEG standards committee actually promotes different formats like
 477.311 +"JPEG 2000" or "JPEG XR" which are incompatible with original DCT-based
 477.312 +JPEG and which are based on faulty technologies.  IJG therefore does not
 477.313 +and will not support such momentary mistakes (see REFERENCES).
 477.314 +We have little or no sympathy for the promotion of these formats.  Indeed,
 477.315 +one of the original reasons for developing this free software was to help
 477.316 +force convergence on common, interoperable format standards for JPEG files.
 477.317 +Don't use an incompatible file format!
 477.318 +(In any case, our decoder will remain capable of reading existing JPEG
 477.319 +image files indefinitely.)
 477.320 +
 477.321 +
 477.322 +TO DO
 477.323 +=====
 477.324 +
 477.325 +Version 8 is the first release of a new generation JPEG standard
 477.326 +to overcome the limitations of the original JPEG specification.
 477.327 +More features are being prepared for coming releases...
 477.328 +
 477.329 +Please send bug reports, offers of help, etc. to jpeg-info@uc.ag.
   478.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   478.2 +++ b/libs/libjpeg/cderror.h	Sat Feb 01 19:58:19 2014 +0200
   478.3 @@ -0,0 +1,132 @@
   478.4 +/*
   478.5 + * cderror.h
   478.6 + *
   478.7 + * Copyright (C) 1994-1997, Thomas G. Lane.
   478.8 + * This file is part of the Independent JPEG Group's software.
   478.9 + * For conditions of distribution and use, see the accompanying README file.
  478.10 + *
  478.11 + * This file defines the error and message codes for the cjpeg/djpeg
  478.12 + * applications.  These strings are not needed as part of the JPEG library
  478.13 + * proper.
  478.14 + * Edit this file to add new codes, or to translate the message strings to
  478.15 + * some other language.
  478.16 + */
  478.17 +
  478.18 +/*
  478.19 + * To define the enum list of message codes, include this file without
  478.20 + * defining macro JMESSAGE.  To create a message string table, include it
  478.21 + * again with a suitable JMESSAGE definition (see jerror.c for an example).
  478.22 + */
  478.23 +#ifndef JMESSAGE
  478.24 +#ifndef CDERROR_H
  478.25 +#define CDERROR_H
  478.26 +/* First time through, define the enum list */
  478.27 +#define JMAKE_ENUM_LIST
  478.28 +#else
  478.29 +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
  478.30 +#define JMESSAGE(code,string)
  478.31 +#endif /* CDERROR_H */
  478.32 +#endif /* JMESSAGE */
  478.33 +
  478.34 +#ifdef JMAKE_ENUM_LIST
  478.35 +
  478.36 +typedef enum {
  478.37 +
  478.38 +#define JMESSAGE(code,string)	code ,
  478.39 +
  478.40 +#endif /* JMAKE_ENUM_LIST */
  478.41 +
  478.42 +JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */
  478.43 +
  478.44 +#ifdef BMP_SUPPORTED
  478.45 +JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format")
  478.46 +JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported")
  478.47 +JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length")
  478.48 +JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1")
  478.49 +JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
  478.50 +JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
  478.51 +JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
  478.52 +JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
  478.53 +JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
  478.54 +JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image")
  478.55 +JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image")
  478.56 +#endif /* BMP_SUPPORTED */
  478.57 +
  478.58 +#ifdef GIF_SUPPORTED
  478.59 +JMESSAGE(JERR_GIF_BUG, "GIF output got confused")
  478.60 +JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d")
  478.61 +JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB")
  478.62 +JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file")
  478.63 +JMESSAGE(JERR_GIF_NOT, "Not a GIF file")
  478.64 +JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image")
  478.65 +JMESSAGE(JTRC_GIF_BADVERSION,
  478.66 +	 "Warning: unexpected GIF version number '%c%c%c'")
  478.67 +JMESSAGE(JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x")
  478.68 +JMESSAGE(JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input")
  478.69 +JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file")
  478.70 +JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring")
  478.71 +JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image")
  478.72 +JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
  478.73 +#endif /* GIF_SUPPORTED */
  478.74 +
  478.75 +#ifdef PPM_SUPPORTED
  478.76 +JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
  478.77 +JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
  478.78 +JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
  478.79 +JMESSAGE(JTRC_PGM, "%ux%u PGM image")
  478.80 +JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
  478.81 +JMESSAGE(JTRC_PPM, "%ux%u PPM image")
  478.82 +JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image")
  478.83 +#endif /* PPM_SUPPORTED */
  478.84 +
  478.85 +#ifdef RLE_SUPPORTED
  478.86 +JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library")
  478.87 +JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB")
  478.88 +JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE")
  478.89 +JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file")
  478.90 +JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header")
  478.91 +JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header")
  478.92 +JMESSAGE(JERR_RLE_NOT, "Not an RLE file")
  478.93 +JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE")
  478.94 +JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup")
  478.95 +JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file")
  478.96 +JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d")
  478.97 +JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file")
  478.98 +JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d")
  478.99 +JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d")
 478.100 +#endif /* RLE_SUPPORTED */
 478.101 +
 478.102 +#ifdef TARGA_SUPPORTED
 478.103 +JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format")
 478.104 +JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file")
 478.105 +JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB")
 478.106 +JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image")
 478.107 +JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image")
 478.108 +JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image")
 478.109 +#else
 478.110 +JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled")
 478.111 +#endif /* TARGA_SUPPORTED */
 478.112 +
 478.113 +JMESSAGE(JERR_BAD_CMAP_FILE,
 478.114 +	 "Color map file is invalid or of unsupported format")
 478.115 +JMESSAGE(JERR_TOO_MANY_COLORS,
 478.116 +	 "Output file format cannot handle %d colormap entries")
 478.117 +JMESSAGE(JERR_UNGETC_FAILED, "ungetc failed")
 478.118 +#ifdef TARGA_SUPPORTED
 478.119 +JMESSAGE(JERR_UNKNOWN_FORMAT,
 478.120 +	 "Unrecognized input file format --- perhaps you need -targa")
 478.121 +#else
 478.122 +JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format")
 478.123 +#endif
 478.124 +JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
 478.125 +
 478.126 +#ifdef JMAKE_ENUM_LIST
 478.127 +
 478.128 +  JMSG_LASTADDONCODE
 478.129 +} ADDON_MESSAGE_CODE;
 478.130 +
 478.131 +#undef JMAKE_ENUM_LIST
 478.132 +#endif /* JMAKE_ENUM_LIST */
 478.133 +
 478.134 +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
 478.135 +#undef JMESSAGE
   479.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   479.2 +++ b/libs/libjpeg/jcapimin.c	Sat Feb 01 19:58:19 2014 +0200
   479.3 @@ -0,0 +1,280 @@
   479.4 +/*
   479.5 + * jcapimin.c
   479.6 + *
   479.7 + * Copyright (C) 1994-1998, Thomas G. Lane.
   479.8 + * This file is part of the Independent JPEG Group's software.
   479.9 + * For conditions of distribution and use, see the accompanying README file.
  479.10 + *
  479.11 + * This file contains application interface code for the compression half
  479.12 + * of the JPEG library.  These are the "minimum" API routines that may be
  479.13 + * needed in either the normal full-compression case or the transcoding-only
  479.14 + * case.
  479.15 + *
  479.16 + * Most of the routines intended to be called directly by an application
  479.17 + * are in this file or in jcapistd.c.  But also see jcparam.c for
  479.18 + * parameter-setup helper routines, jcomapi.c for routines shared by
  479.19 + * compression and decompression, and jctrans.c for the transcoding case.
  479.20 + */
  479.21 +
  479.22 +#define JPEG_INTERNALS
  479.23 +#include "jinclude.h"
  479.24 +#include "jpeglib.h"
  479.25 +
  479.26 +
  479.27 +/*
  479.28 + * Initialization of a JPEG compression object.
  479.29 + * The error manager must already be set up (in case memory manager fails).
  479.30 + */
  479.31 +
  479.32 +GLOBAL(void)
  479.33 +jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
  479.34 +{
  479.35 +  int i;
  479.36 +
  479.37 +  /* Guard against version mismatches between library and caller. */
  479.38 +  cinfo->mem = NULL;		/* so jpeg_destroy knows mem mgr not called */
  479.39 +  if (version != JPEG_LIB_VERSION)
  479.40 +    ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
  479.41 +  if (structsize != SIZEOF(struct jpeg_compress_struct))
  479.42 +    ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, 
  479.43 +	     (int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
  479.44 +
  479.45 +  /* For debugging purposes, we zero the whole master structure.
  479.46 +   * But the application has already set the err pointer, and may have set
  479.47 +   * client_data, so we have to save and restore those fields.
  479.48 +   * Note: if application hasn't set client_data, tools like Purify may
  479.49 +   * complain here.
  479.50 +   */
  479.51 +  {
  479.52 +    struct jpeg_error_mgr * err = cinfo->err;
  479.53 +    void * client_data = cinfo->client_data; /* ignore Purify complaint here */
  479.54 +    MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
  479.55 +    cinfo->err = err;
  479.56 +    cinfo->client_data = client_data;
  479.57 +  }
  479.58 +  cinfo->is_decompressor = FALSE;
  479.59 +
  479.60 +  /* Initialize a memory manager instance for this object */
  479.61 +  jinit_memory_mgr((j_common_ptr) cinfo);
  479.62 +
  479.63 +  /* Zero out pointers to permanent structures. */
  479.64 +  cinfo->progress = NULL;
  479.65 +  cinfo->dest = NULL;
  479.66 +
  479.67 +  cinfo->comp_info = NULL;
  479.68 +
  479.69 +  for (i = 0; i < NUM_QUANT_TBLS; i++)
  479.70 +    cinfo->quant_tbl_ptrs[i] = NULL;
  479.71 +
  479.72 +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
  479.73 +    cinfo->dc_huff_tbl_ptrs[i] = NULL;
  479.74 +    cinfo->ac_huff_tbl_ptrs[i] = NULL;
  479.75 +  }
  479.76 +
  479.77 +  cinfo->script_space = NULL;
  479.78 +
  479.79 +  cinfo->input_gamma = 1.0;	/* in case application forgets */
  479.80 +
  479.81 +  /* OK, I'm ready */
  479.82 +  cinfo->global_state = CSTATE_START;
  479.83 +}
  479.84 +
  479.85 +
  479.86 +/*
  479.87 + * Destruction of a JPEG compression object
  479.88 + */
  479.89 +
  479.90 +GLOBAL(void)
  479.91 +jpeg_destroy_compress (j_compress_ptr cinfo)
  479.92 +{
  479.93 +  jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
  479.94 +}
  479.95 +
  479.96 +
  479.97 +/*
  479.98 + * Abort processing of a JPEG compression operation,
  479.99 + * but don't destroy the object itself.
 479.100 + */
 479.101 +
 479.102 +GLOBAL(void)
 479.103 +jpeg_abort_compress (j_compress_ptr cinfo)
 479.104 +{
 479.105 +  jpeg_abort((j_common_ptr) cinfo); /* use common routine */
 479.106 +}
 479.107 +
 479.108 +
 479.109 +/*
 479.110 + * Forcibly suppress or un-suppress all quantization and Huffman tables.
 479.111 + * Marks all currently defined tables as already written (if suppress)
 479.112 + * or not written (if !suppress).  This will control whether they get emitted
 479.113 + * by a subsequent jpeg_start_compress call.
 479.114 + *
 479.115 + * This routine is exported for use by applications that want to produce
 479.116 + * abbreviated JPEG datastreams.  It logically belongs in jcparam.c, but
 479.117 + * since it is called by jpeg_start_compress, we put it here --- otherwise
 479.118 + * jcparam.o would be linked whether the application used it or not.
 479.119 + */
 479.120 +
 479.121 +GLOBAL(void)
 479.122 +jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
 479.123 +{
 479.124 +  int i;
 479.125 +  JQUANT_TBL * qtbl;
 479.126 +  JHUFF_TBL * htbl;
 479.127 +
 479.128 +  for (i = 0; i < NUM_QUANT_TBLS; i++) {
 479.129 +    if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL)
 479.130 +      qtbl->sent_table = suppress;
 479.131 +  }
 479.132 +
 479.133 +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
 479.134 +    if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL)
 479.135 +      htbl->sent_table = suppress;
 479.136 +    if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL)
 479.137 +      htbl->sent_table = suppress;
 479.138 +  }
 479.139 +}
 479.140 +
 479.141 +
 479.142 +/*
 479.143 + * Finish JPEG compression.
 479.144 + *
 479.145 + * If a multipass operating mode was selected, this may do a great deal of
 479.146 + * work including most of the actual output.
 479.147 + */
 479.148 +
 479.149 +GLOBAL(void)
 479.150 +jpeg_finish_compress (j_compress_ptr cinfo)
 479.151 +{
 479.152 +  JDIMENSION iMCU_row;
 479.153 +
 479.154 +  if (cinfo->global_state == CSTATE_SCANNING ||
 479.155 +      cinfo->global_state == CSTATE_RAW_OK) {
 479.156 +    /* Terminate first pass */
 479.157 +    if (cinfo->next_scanline < cinfo->image_height)
 479.158 +      ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
 479.159 +    (*cinfo->master->finish_pass) (cinfo);
 479.160 +  } else if (cinfo->global_state != CSTATE_WRCOEFS)
 479.161 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 479.162 +  /* Perform any remaining passes */
 479.163 +  while (! cinfo->master->is_last_pass) {
 479.164 +    (*cinfo->master->prepare_for_pass) (cinfo);
 479.165 +    for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) {
 479.166 +      if (cinfo->progress != NULL) {
 479.167 +	cinfo->progress->pass_counter = (long) iMCU_row;
 479.168 +	cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows;
 479.169 +	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 479.170 +      }
 479.171 +      /* We bypass the main controller and invoke coef controller directly;
 479.172 +       * all work is being done from the coefficient buffer.
 479.173 +       */
 479.174 +      if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
 479.175 +	ERREXIT(cinfo, JERR_CANT_SUSPEND);
 479.176 +    }
 479.177 +    (*cinfo->master->finish_pass) (cinfo);
 479.178 +  }
 479.179 +  /* Write EOI, do final cleanup */
 479.180 +  (*cinfo->marker->write_file_trailer) (cinfo);
 479.181 +  (*cinfo->dest->term_destination) (cinfo);
 479.182 +  /* We can use jpeg_abort to release memory and reset global_state */
 479.183 +  jpeg_abort((j_common_ptr) cinfo);
 479.184 +}
 479.185 +
 479.186 +
 479.187 +/*
 479.188 + * Write a special marker.
 479.189 + * This is only recommended for writing COM or APPn markers.
 479.190 + * Must be called after jpeg_start_compress() and before
 479.191 + * first call to jpeg_write_scanlines() or jpeg_write_raw_data().
 479.192 + */
 479.193 +
 479.194 +GLOBAL(void)
 479.195 +jpeg_write_marker (j_compress_ptr cinfo, int marker,
 479.196 +		   const JOCTET *dataptr, unsigned int datalen)
 479.197 +{
 479.198 +  JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val));
 479.199 +
 479.200 +  if (cinfo->next_scanline != 0 ||
 479.201 +      (cinfo->global_state != CSTATE_SCANNING &&
 479.202 +       cinfo->global_state != CSTATE_RAW_OK &&
 479.203 +       cinfo->global_state != CSTATE_WRCOEFS))
 479.204 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 479.205 +
 479.206 +  (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
 479.207 +  write_marker_byte = cinfo->marker->write_marker_byte;	/* copy for speed */
 479.208 +  while (datalen--) {
 479.209 +    (*write_marker_byte) (cinfo, *dataptr);
 479.210 +    dataptr++;
 479.211 +  }
 479.212 +}
 479.213 +
 479.214 +/* Same, but piecemeal. */
 479.215 +
 479.216 +GLOBAL(void)
 479.217 +jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
 479.218 +{
 479.219 +  if (cinfo->next_scanline != 0 ||
 479.220 +      (cinfo->global_state != CSTATE_SCANNING &&
 479.221 +       cinfo->global_state != CSTATE_RAW_OK &&
 479.222 +       cinfo->global_state != CSTATE_WRCOEFS))
 479.223 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 479.224 +
 479.225 +  (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
 479.226 +}
 479.227 +
 479.228 +GLOBAL(void)
 479.229 +jpeg_write_m_byte (j_compress_ptr cinfo, int val)
 479.230 +{
 479.231 +  (*cinfo->marker->write_marker_byte) (cinfo, val);
 479.232 +}
 479.233 +
 479.234 +
 479.235 +/*
 479.236 + * Alternate compression function: just write an abbreviated table file.
 479.237 + * Before calling this, all parameters and a data destination must be set up.
 479.238 + *
 479.239 + * To produce a pair of files containing abbreviated tables and abbreviated
 479.240 + * image data, one would proceed as follows:
 479.241 + *
 479.242 + *		initialize JPEG object
 479.243 + *		set JPEG parameters
 479.244 + *		set destination to table file
 479.245 + *		jpeg_write_tables(cinfo);
 479.246 + *		set destination to image file
 479.247 + *		jpeg_start_compress(cinfo, FALSE);
 479.248 + *		write data...
 479.249 + *		jpeg_finish_compress(cinfo);
 479.250 + *
 479.251 + * jpeg_write_tables has the side effect of marking all tables written
 479.252 + * (same as jpeg_suppress_tables(..., TRUE)).  Thus a subsequent start_compress
 479.253 + * will not re-emit the tables unless it is passed write_all_tables=TRUE.
 479.254 + */
 479.255 +
 479.256 +GLOBAL(void)
 479.257 +jpeg_write_tables (j_compress_ptr cinfo)
 479.258 +{
 479.259 +  if (cinfo->global_state != CSTATE_START)
 479.260 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 479.261 +
 479.262 +  /* (Re)initialize error mgr and destination modules */
 479.263 +  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
 479.264 +  (*cinfo->dest->init_destination) (cinfo);
 479.265 +  /* Initialize the marker writer ... bit of a crock to do it here. */
 479.266 +  jinit_marker_writer(cinfo);
 479.267 +  /* Write them tables! */
 479.268 +  (*cinfo->marker->write_tables_only) (cinfo);
 479.269 +  /* And clean up. */
 479.270 +  (*cinfo->dest->term_destination) (cinfo);
 479.271 +  /*
 479.272 +   * In library releases up through v6a, we called jpeg_abort() here to free
 479.273 +   * any working memory allocated by the destination manager and marker
 479.274 +   * writer.  Some applications had a problem with that: they allocated space
 479.275 +   * of their own from the library memory manager, and didn't want it to go
 479.276 +   * away during write_tables.  So now we do nothing.  This will cause a
 479.277 +   * memory leak if an app calls write_tables repeatedly without doing a full
 479.278 +   * compression cycle or otherwise resetting the JPEG object.  However, that
 479.279 +   * seems less bad than unexpectedly freeing memory in the normal case.
 479.280 +   * An app that prefers the old behavior can call jpeg_abort for itself after
 479.281 +   * each call to jpeg_write_tables().
 479.282 +   */
 479.283 +}
   480.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   480.2 +++ b/libs/libjpeg/jcapistd.c	Sat Feb 01 19:58:19 2014 +0200
   480.3 @@ -0,0 +1,161 @@
   480.4 +/*
   480.5 + * jcapistd.c
   480.6 + *
   480.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   480.8 + * This file is part of the Independent JPEG Group's software.
   480.9 + * For conditions of distribution and use, see the accompanying README file.
  480.10 + *
  480.11 + * This file contains application interface code for the compression half
  480.12 + * of the JPEG library.  These are the "standard" API routines that are
  480.13 + * used in the normal full-compression case.  They are not used by a
  480.14 + * transcoding-only application.  Note that if an application links in
  480.15 + * jpeg_start_compress, it will end up linking in the entire compressor.
  480.16 + * We thus must separate this file from jcapimin.c to avoid linking the
  480.17 + * whole compression library into a transcoder.
  480.18 + */
  480.19 +
  480.20 +#define JPEG_INTERNALS
  480.21 +#include "jinclude.h"
  480.22 +#include "jpeglib.h"
  480.23 +
  480.24 +
  480.25 +/*
  480.26 + * Compression initialization.
  480.27 + * Before calling this, all parameters and a data destination must be set up.
  480.28 + *
  480.29 + * We require a write_all_tables parameter as a failsafe check when writing
  480.30 + * multiple datastreams from the same compression object.  Since prior runs
  480.31 + * will have left all the tables marked sent_table=TRUE, a subsequent run
  480.32 + * would emit an abbreviated stream (no tables) by default.  This may be what
  480.33 + * is wanted, but for safety's sake it should not be the default behavior:
  480.34 + * programmers should have to make a deliberate choice to emit abbreviated
  480.35 + * images.  Therefore the documentation and examples should encourage people
  480.36 + * to pass write_all_tables=TRUE; then it will take active thought to do the
  480.37 + * wrong thing.
  480.38 + */
  480.39 +
  480.40 +GLOBAL(void)
  480.41 +jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
  480.42 +{
  480.43 +  if (cinfo->global_state != CSTATE_START)
  480.44 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  480.45 +
  480.46 +  if (write_all_tables)
  480.47 +    jpeg_suppress_tables(cinfo, FALSE);	/* mark all tables to be written */
  480.48 +
  480.49 +  /* (Re)initialize error mgr and destination modules */
  480.50 +  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
  480.51 +  (*cinfo->dest->init_destination) (cinfo);
  480.52 +  /* Perform master selection of active modules */
  480.53 +  jinit_compress_master(cinfo);
  480.54 +  /* Set up for the first pass */
  480.55 +  (*cinfo->master->prepare_for_pass) (cinfo);
  480.56 +  /* Ready for application to drive first pass through jpeg_write_scanlines
  480.57 +   * or jpeg_write_raw_data.
  480.58 +   */
  480.59 +  cinfo->next_scanline = 0;
  480.60 +  cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
  480.61 +}
  480.62 +
  480.63 +
  480.64 +/*
  480.65 + * Write some scanlines of data to the JPEG compressor.
  480.66 + *
  480.67 + * The return value will be the number of lines actually written.
  480.68 + * This should be less than the supplied num_lines only in case that
  480.69 + * the data destination module has requested suspension of the compressor,
  480.70 + * or if more than image_height scanlines are passed in.
  480.71 + *
  480.72 + * Note: we warn about excess calls to jpeg_write_scanlines() since
  480.73 + * this likely signals an application programmer error.  However,
  480.74 + * excess scanlines passed in the last valid call are *silently* ignored,
  480.75 + * so that the application need not adjust num_lines for end-of-image
  480.76 + * when using a multiple-scanline buffer.
  480.77 + */
  480.78 +
  480.79 +GLOBAL(JDIMENSION)
  480.80 +jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
  480.81 +		      JDIMENSION num_lines)
  480.82 +{
  480.83 +  JDIMENSION row_ctr, rows_left;
  480.84 +
  480.85 +  if (cinfo->global_state != CSTATE_SCANNING)
  480.86 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  480.87 +  if (cinfo->next_scanline >= cinfo->image_height)
  480.88 +    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
  480.89 +
  480.90 +  /* Call progress monitor hook if present */
  480.91 +  if (cinfo->progress != NULL) {
  480.92 +    cinfo->progress->pass_counter = (long) cinfo->next_scanline;
  480.93 +    cinfo->progress->pass_limit = (long) cinfo->image_height;
  480.94 +    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
  480.95 +  }
  480.96 +
  480.97 +  /* Give master control module another chance if this is first call to
  480.98 +   * jpeg_write_scanlines.  This lets output of the frame/scan headers be
  480.99 +   * delayed so that application can write COM, etc, markers between
 480.100 +   * jpeg_start_compress and jpeg_write_scanlines.
 480.101 +   */
 480.102 +  if (cinfo->master->call_pass_startup)
 480.103 +    (*cinfo->master->pass_startup) (cinfo);
 480.104 +
 480.105 +  /* Ignore any extra scanlines at bottom of image. */
 480.106 +  rows_left = cinfo->image_height - cinfo->next_scanline;
 480.107 +  if (num_lines > rows_left)
 480.108 +    num_lines = rows_left;
 480.109 +
 480.110 +  row_ctr = 0;
 480.111 +  (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
 480.112 +  cinfo->next_scanline += row_ctr;
 480.113 +  return row_ctr;
 480.114 +}
 480.115 +
 480.116 +
 480.117 +/*
 480.118 + * Alternate entry point to write raw data.
 480.119 + * Processes exactly one iMCU row per call, unless suspended.
 480.120 + */
 480.121 +
 480.122 +GLOBAL(JDIMENSION)
 480.123 +jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
 480.124 +		     JDIMENSION num_lines)
 480.125 +{
 480.126 +  JDIMENSION lines_per_iMCU_row;
 480.127 +
 480.128 +  if (cinfo->global_state != CSTATE_RAW_OK)
 480.129 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 480.130 +  if (cinfo->next_scanline >= cinfo->image_height) {
 480.131 +    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
 480.132 +    return 0;
 480.133 +  }
 480.134 +
 480.135 +  /* Call progress monitor hook if present */
 480.136 +  if (cinfo->progress != NULL) {
 480.137 +    cinfo->progress->pass_counter = (long) cinfo->next_scanline;
 480.138 +    cinfo->progress->pass_limit = (long) cinfo->image_height;
 480.139 +    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 480.140 +  }
 480.141 +
 480.142 +  /* Give master control module another chance if this is first call to
 480.143 +   * jpeg_write_raw_data.  This lets output of the frame/scan headers be
 480.144 +   * delayed so that application can write COM, etc, markers between
 480.145 +   * jpeg_start_compress and jpeg_write_raw_data.
 480.146 +   */
 480.147 +  if (cinfo->master->call_pass_startup)
 480.148 +    (*cinfo->master->pass_startup) (cinfo);
 480.149 +
 480.150 +  /* Verify that at least one iMCU row has been passed. */
 480.151 +  lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
 480.152 +  if (num_lines < lines_per_iMCU_row)
 480.153 +    ERREXIT(cinfo, JERR_BUFFER_SIZE);
 480.154 +
 480.155 +  /* Directly compress the row. */
 480.156 +  if (! (*cinfo->coef->compress_data) (cinfo, data)) {
 480.157 +    /* If compressor did not consume the whole row, suspend processing. */
 480.158 +    return 0;
 480.159 +  }
 480.160 +
 480.161 +  /* OK, we processed one iMCU row. */
 480.162 +  cinfo->next_scanline += lines_per_iMCU_row;
 480.163 +  return lines_per_iMCU_row;
 480.164 +}
   481.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   481.2 +++ b/libs/libjpeg/jccoefct.c	Sat Feb 01 19:58:19 2014 +0200
   481.3 @@ -0,0 +1,449 @@
   481.4 +/*
   481.5 + * jccoefct.c
   481.6 + *
   481.7 + * Copyright (C) 1994-1997, Thomas G. Lane.
   481.8 + * This file is part of the Independent JPEG Group's software.
   481.9 + * For conditions of distribution and use, see the accompanying README file.
  481.10 + *
  481.11 + * This file contains the coefficient buffer controller for compression.
  481.12 + * This controller is the top level of the JPEG compressor proper.
  481.13 + * The coefficient buffer lies between forward-DCT and entropy encoding steps.
  481.14 + */
  481.15 +
  481.16 +#define JPEG_INTERNALS
  481.17 +#include "jinclude.h"
  481.18 +#include "jpeglib.h"
  481.19 +
  481.20 +
  481.21 +/* We use a full-image coefficient buffer when doing Huffman optimization,
  481.22 + * and also for writing multiple-scan JPEG files.  In all cases, the DCT
  481.23 + * step is run during the first pass, and subsequent passes need only read
  481.24 + * the buffered coefficients.
  481.25 + */
  481.26 +#ifdef ENTROPY_OPT_SUPPORTED
  481.27 +#define FULL_COEF_BUFFER_SUPPORTED
  481.28 +#else
  481.29 +#ifdef C_MULTISCAN_FILES_SUPPORTED
  481.30 +#define FULL_COEF_BUFFER_SUPPORTED
  481.31 +#endif
  481.32 +#endif
  481.33 +
  481.34 +
  481.35 +/* Private buffer controller object */
  481.36 +
  481.37 +typedef struct {
  481.38 +  struct jpeg_c_coef_controller pub; /* public fields */
  481.39 +
  481.40 +  JDIMENSION iMCU_row_num;	/* iMCU row # within image */
  481.41 +  JDIMENSION mcu_ctr;		/* counts MCUs processed in current row */
  481.42 +  int MCU_vert_offset;		/* counts MCU rows within iMCU row */
  481.43 +  int MCU_rows_per_iMCU_row;	/* number of such rows needed */
  481.44 +
  481.45 +  /* For single-pass compression, it's sufficient to buffer just one MCU
  481.46 +   * (although this may prove a bit slow in practice).  We allocate a
  481.47 +   * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
  481.48 +   * MCU constructed and sent.  (On 80x86, the workspace is FAR even though
  481.49 +   * it's not really very big; this is to keep the module interfaces unchanged
  481.50 +   * when a large coefficient buffer is necessary.)
  481.51 +   * In multi-pass modes, this array points to the current MCU's blocks
  481.52 +   * within the virtual arrays.
  481.53 +   */
  481.54 +  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
  481.55 +
  481.56 +  /* In multi-pass modes, we need a virtual block array for each component. */
  481.57 +  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
  481.58 +} my_coef_controller;
  481.59 +
  481.60 +typedef my_coef_controller * my_coef_ptr;
  481.61 +
  481.62 +
  481.63 +/* Forward declarations */
  481.64 +METHODDEF(boolean) compress_data
  481.65 +    JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
  481.66 +#ifdef FULL_COEF_BUFFER_SUPPORTED
  481.67 +METHODDEF(boolean) compress_first_pass
  481.68 +    JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
  481.69 +METHODDEF(boolean) compress_output
  481.70 +    JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
  481.71 +#endif
  481.72 +
  481.73 +
  481.74 +LOCAL(void)
  481.75 +start_iMCU_row (j_compress_ptr cinfo)
  481.76 +/* Reset within-iMCU-row counters for a new row */
  481.77 +{
  481.78 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  481.79 +
  481.80 +  /* In an interleaved scan, an MCU row is the same as an iMCU row.
  481.81 +   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
  481.82 +   * But at the bottom of the image, process only what's left.
  481.83 +   */
  481.84 +  if (cinfo->comps_in_scan > 1) {
  481.85 +    coef->MCU_rows_per_iMCU_row = 1;
  481.86 +  } else {
  481.87 +    if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
  481.88 +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
  481.89 +    else
  481.90 +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
  481.91 +  }
  481.92 +
  481.93 +  coef->mcu_ctr = 0;
  481.94 +  coef->MCU_vert_offset = 0;
  481.95 +}
  481.96 +
  481.97 +
  481.98 +/*
  481.99 + * Initialize for a processing pass.
 481.100 + */
 481.101 +
 481.102 +METHODDEF(void)
 481.103 +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
 481.104 +{
 481.105 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 481.106 +
 481.107 +  coef->iMCU_row_num = 0;
 481.108 +  start_iMCU_row(cinfo);
 481.109 +
 481.110 +  switch (pass_mode) {
 481.111 +  case JBUF_PASS_THRU:
 481.112 +    if (coef->whole_image[0] != NULL)
 481.113 +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 481.114 +    coef->pub.compress_data = compress_data;
 481.115 +    break;
 481.116 +#ifdef FULL_COEF_BUFFER_SUPPORTED
 481.117 +  case JBUF_SAVE_AND_PASS:
 481.118 +    if (coef->whole_image[0] == NULL)
 481.119 +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 481.120 +    coef->pub.compress_data = compress_first_pass;
 481.121 +    break;
 481.122 +  case JBUF_CRANK_DEST:
 481.123 +    if (coef->whole_image[0] == NULL)
 481.124 +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 481.125 +    coef->pub.compress_data = compress_output;
 481.126 +    break;
 481.127 +#endif
 481.128 +  default:
 481.129 +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 481.130 +    break;
 481.131 +  }
 481.132 +}
 481.133 +
 481.134 +
 481.135 +/*
 481.136 + * Process some data in the single-pass case.
 481.137 + * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
 481.138 + * per call, ie, v_samp_factor block rows for each component in the image.
 481.139 + * Returns TRUE if the iMCU row is completed, FALSE if suspended.
 481.140 + *
 481.141 + * NB: input_buf contains a plane for each component in image,
 481.142 + * which we index according to the component's SOF position.
 481.143 + */
 481.144 +
 481.145 +METHODDEF(boolean)
 481.146 +compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
 481.147 +{
 481.148 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 481.149 +  JDIMENSION MCU_col_num;	/* index of current MCU within row */
 481.150 +  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
 481.151 +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
 481.152 +  int blkn, bi, ci, yindex, yoffset, blockcnt;
 481.153 +  JDIMENSION ypos, xpos;
 481.154 +  jpeg_component_info *compptr;
 481.155 +
 481.156 +  /* Loop to write as much as one whole iMCU row */
 481.157 +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
 481.158 +       yoffset++) {
 481.159 +    for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
 481.160 +	 MCU_col_num++) {
 481.161 +      /* Determine where data comes from in input_buf and do the DCT thing.
 481.162 +       * Each call on forward_DCT processes a horizontal row of DCT blocks
 481.163 +       * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
 481.164 +       * sequentially.  Dummy blocks at the right or bottom edge are filled in
 481.165 +       * specially.  The data in them does not matter for image reconstruction,
 481.166 +       * so we fill them with values that will encode to the smallest amount of
 481.167 +       * data, viz: all zeroes in the AC entries, DC entries equal to previous
 481.168 +       * block's DC value.  (Thanks to Thomas Kinsman for this idea.)
 481.169 +       */
 481.170 +      blkn = 0;
 481.171 +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 481.172 +	compptr = cinfo->cur_comp_info[ci];
 481.173 +	blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
 481.174 +						: compptr->last_col_width;
 481.175 +	xpos = MCU_col_num * compptr->MCU_sample_width;
 481.176 +	ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
 481.177 +	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
 481.178 +	  if (coef->iMCU_row_num < last_iMCU_row ||
 481.179 +	      yoffset+yindex < compptr->last_row_height) {
 481.180 +	    (*cinfo->fdct->forward_DCT) (cinfo, compptr,
 481.181 +					 input_buf[compptr->component_index],
 481.182 +					 coef->MCU_buffer[blkn],
 481.183 +					 ypos, xpos, (JDIMENSION) blockcnt);
 481.184 +	    if (blockcnt < compptr->MCU_width) {
 481.185 +	      /* Create some dummy blocks at the right edge of the image. */
 481.186 +	      jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
 481.187 +			(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
 481.188 +	      for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
 481.189 +		coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
 481.190 +	      }
 481.191 +	    }
 481.192 +	  } else {
 481.193 +	    /* Create a row of dummy blocks at the bottom of the image. */
 481.194 +	    jzero_far((void FAR *) coef->MCU_buffer[blkn],
 481.195 +		      compptr->MCU_width * SIZEOF(JBLOCK));
 481.196 +	    for (bi = 0; bi < compptr->MCU_width; bi++) {
 481.197 +	      coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
 481.198 +	    }
 481.199 +	  }
 481.200 +	  blkn += compptr->MCU_width;
 481.201 +	  ypos += DCTSIZE;
 481.202 +	}
 481.203 +      }
 481.204 +      /* Try to write the MCU.  In event of a suspension failure, we will
 481.205 +       * re-DCT the MCU on restart (a bit inefficient, could be fixed...)
 481.206 +       */
 481.207 +      if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
 481.208 +	/* Suspension forced; update state counters and exit */
 481.209 +	coef->MCU_vert_offset = yoffset;
 481.210 +	coef->mcu_ctr = MCU_col_num;
 481.211 +	return FALSE;
 481.212 +      }
 481.213 +    }
 481.214 +    /* Completed an MCU row, but perhaps not an iMCU row */
 481.215 +    coef->mcu_ctr = 0;
 481.216 +  }
 481.217 +  /* Completed the iMCU row, advance counters for next one */
 481.218 +  coef->iMCU_row_num++;
 481.219 +  start_iMCU_row(cinfo);
 481.220 +  return TRUE;
 481.221 +}
 481.222 +
 481.223 +
 481.224 +#ifdef FULL_COEF_BUFFER_SUPPORTED
 481.225 +
 481.226 +/*
 481.227 + * Process some data in the first pass of a multi-pass case.
 481.228 + * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
 481.229 + * per call, ie, v_samp_factor block rows for each component in the image.
 481.230 + * This amount of data is read from the source buffer, DCT'd and quantized,
 481.231 + * and saved into the virtual arrays.  We also generate suitable dummy blocks
 481.232 + * as needed at the right and lower edges.  (The dummy blocks are constructed
 481.233 + * in the virtual arrays, which have been padded appropriately.)  This makes
 481.234 + * it possible for subsequent passes not to worry about real vs. dummy blocks.
 481.235 + *
 481.236 + * We must also emit the data to the entropy encoder.  This is conveniently
 481.237 + * done by calling compress_output() after we've loaded the current strip
 481.238 + * of the virtual arrays.
 481.239 + *
 481.240 + * NB: input_buf contains a plane for each component in image.  All
 481.241 + * components are DCT'd and loaded into the virtual arrays in this pass.
 481.242 + * However, it may be that only a subset of the components are emitted to
 481.243 + * the entropy encoder during this first pass; be careful about looking
 481.244 + * at the scan-dependent variables (MCU dimensions, etc).
 481.245 + */
 481.246 +
 481.247 +METHODDEF(boolean)
 481.248 +compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
 481.249 +{
 481.250 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 481.251 +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
 481.252 +  JDIMENSION blocks_across, MCUs_across, MCUindex;
 481.253 +  int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
 481.254 +  JCOEF lastDC;
 481.255 +  jpeg_component_info *compptr;
 481.256 +  JBLOCKARRAY buffer;
 481.257 +  JBLOCKROW thisblockrow, lastblockrow;
 481.258 +
 481.259 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 481.260 +       ci++, compptr++) {
 481.261 +    /* Align the virtual buffer for this component. */
 481.262 +    buffer = (*cinfo->mem->access_virt_barray)
 481.263 +      ((j_common_ptr) cinfo, coef->whole_image[ci],
 481.264 +       coef->iMCU_row_num * compptr->v_samp_factor,
 481.265 +       (JDIMENSION) compptr->v_samp_factor, TRUE);
 481.266 +    /* Count non-dummy DCT block rows in this iMCU row. */
 481.267 +    if (coef->iMCU_row_num < last_iMCU_row)
 481.268 +      block_rows = compptr->v_samp_factor;
 481.269 +    else {
 481.270 +      /* NB: can't use last_row_height here, since may not be set! */
 481.271 +      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
 481.272 +      if (block_rows == 0) block_rows = compptr->v_samp_factor;
 481.273 +    }
 481.274 +    blocks_across = compptr->width_in_blocks;
 481.275 +    h_samp_factor = compptr->h_samp_factor;
 481.276 +    /* Count number of dummy blocks to be added at the right margin. */
 481.277 +    ndummy = (int) (blocks_across % h_samp_factor);
 481.278 +    if (ndummy > 0)
 481.279 +      ndummy = h_samp_factor - ndummy;
 481.280 +    /* Perform DCT for all non-dummy blocks in this iMCU row.  Each call
 481.281 +     * on forward_DCT processes a complete horizontal row of DCT blocks.
 481.282 +     */
 481.283 +    for (block_row = 0; block_row < block_rows; block_row++) {
 481.284 +      thisblockrow = buffer[block_row];
 481.285 +      (*cinfo->fdct->forward_DCT) (cinfo, compptr,
 481.286 +				   input_buf[ci], thisblockrow,
 481.287 +				   (JDIMENSION) (block_row * DCTSIZE),
 481.288 +				   (JDIMENSION) 0, blocks_across);
 481.289 +      if (ndummy > 0) {
 481.290 +	/* Create dummy blocks at the right edge of the image. */
 481.291 +	thisblockrow += blocks_across; /* => first dummy block */
 481.292 +	jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
 481.293 +	lastDC = thisblockrow[-1][0];
 481.294 +	for (bi = 0; bi < ndummy; bi++) {
 481.295 +	  thisblockrow[bi][0] = lastDC;
 481.296 +	}
 481.297 +      }
 481.298 +    }
 481.299 +    /* If at end of image, create dummy block rows as needed.
 481.300 +     * The tricky part here is that within each MCU, we want the DC values
 481.301 +     * of the dummy blocks to match the last real block's DC value.
 481.302 +     * This squeezes a few more bytes out of the resulting file...
 481.303 +     */
 481.304 +    if (coef->iMCU_row_num == last_iMCU_row) {
 481.305 +      blocks_across += ndummy;	/* include lower right corner */
 481.306 +      MCUs_across = blocks_across / h_samp_factor;
 481.307 +      for (block_row = block_rows; block_row < compptr->v_samp_factor;
 481.308 +	   block_row++) {
 481.309 +	thisblockrow = buffer[block_row];
 481.310 +	lastblockrow = buffer[block_row-1];
 481.311 +	jzero_far((void FAR *) thisblockrow,
 481.312 +		  (size_t) (blocks_across * SIZEOF(JBLOCK)));
 481.313 +	for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
 481.314 +	  lastDC = lastblockrow[h_samp_factor-1][0];
 481.315 +	  for (bi = 0; bi < h_samp_factor; bi++) {
 481.316 +	    thisblockrow[bi][0] = lastDC;
 481.317 +	  }
 481.318 +	  thisblockrow += h_samp_factor; /* advance to next MCU in row */
 481.319 +	  lastblockrow += h_samp_factor;
 481.320 +	}
 481.321 +      }
 481.322 +    }
 481.323 +  }
 481.324 +  /* NB: compress_output will increment iMCU_row_num if successful.
 481.325 +   * A suspension return will result in redoing all the work above next time.
 481.326 +   */
 481.327 +
 481.328 +  /* Emit data to the entropy encoder, sharing code with subsequent passes */
 481.329 +  return compress_output(cinfo, input_buf);
 481.330 +}
 481.331 +
 481.332 +
 481.333 +/*
 481.334 + * Process some data in subsequent passes of a multi-pass case.
 481.335 + * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
 481.336 + * per call, ie, v_samp_factor block rows for each component in the scan.
 481.337 + * The data is obtained from the virtual arrays and fed to the entropy coder.
 481.338 + * Returns TRUE if the iMCU row is completed, FALSE if suspended.
 481.339 + *
 481.340 + * NB: input_buf is ignored; it is likely to be a NULL pointer.
 481.341 + */
 481.342 +
 481.343 +METHODDEF(boolean)
 481.344 +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
 481.345 +{
 481.346 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 481.347 +  JDIMENSION MCU_col_num;	/* index of current MCU within row */
 481.348 +  int blkn, ci, xindex, yindex, yoffset;
 481.349 +  JDIMENSION start_col;
 481.350 +  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
 481.351 +  JBLOCKROW buffer_ptr;
 481.352 +  jpeg_component_info *compptr;
 481.353 +
 481.354 +  /* Align the virtual buffers for the components used in this scan.
 481.355 +   * NB: during first pass, this is safe only because the buffers will
 481.356 +   * already be aligned properly, so jmemmgr.c won't need to do any I/O.
 481.357 +   */
 481.358 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 481.359 +    compptr = cinfo->cur_comp_info[ci];
 481.360 +    buffer[ci] = (*cinfo->mem->access_virt_barray)
 481.361 +      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
 481.362 +       coef->iMCU_row_num * compptr->v_samp_factor,
 481.363 +       (JDIMENSION) compptr->v_samp_factor, FALSE);
 481.364 +  }
 481.365 +
 481.366 +  /* Loop to process one whole iMCU row */
 481.367 +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
 481.368 +       yoffset++) {
 481.369 +    for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
 481.370 +	 MCU_col_num++) {
 481.371 +      /* Construct list of pointers to DCT blocks belonging to this MCU */
 481.372 +      blkn = 0;			/* index of current DCT block within MCU */
 481.373 +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 481.374 +	compptr = cinfo->cur_comp_info[ci];
 481.375 +	start_col = MCU_col_num * compptr->MCU_width;
 481.376 +	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
 481.377 +	  buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
 481.378 +	  for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
 481.379 +	    coef->MCU_buffer[blkn++] = buffer_ptr++;
 481.380 +	  }
 481.381 +	}
 481.382 +      }
 481.383 +      /* Try to write the MCU. */
 481.384 +      if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
 481.385 +	/* Suspension forced; update state counters and exit */
 481.386 +	coef->MCU_vert_offset = yoffset;
 481.387 +	coef->mcu_ctr = MCU_col_num;
 481.388 +	return FALSE;
 481.389 +      }
 481.390 +    }
 481.391 +    /* Completed an MCU row, but perhaps not an iMCU row */
 481.392 +    coef->mcu_ctr = 0;
 481.393 +  }
 481.394 +  /* Completed the iMCU row, advance counters for next one */
 481.395 +  coef->iMCU_row_num++;
 481.396 +  start_iMCU_row(cinfo);
 481.397 +  return TRUE;
 481.398 +}
 481.399 +
 481.400 +#endif /* FULL_COEF_BUFFER_SUPPORTED */
 481.401 +
 481.402 +
 481.403 +/*
 481.404 + * Initialize coefficient buffer controller.
 481.405 + */
 481.406 +
 481.407 +GLOBAL(void)
 481.408 +jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
 481.409 +{
 481.410 +  my_coef_ptr coef;
 481.411 +
 481.412 +  coef = (my_coef_ptr)
 481.413 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 481.414 +				SIZEOF(my_coef_controller));
 481.415 +  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
 481.416 +  coef->pub.start_pass = start_pass_coef;
 481.417 +
 481.418 +  /* Create the coefficient buffer. */
 481.419 +  if (need_full_buffer) {
 481.420 +#ifdef FULL_COEF_BUFFER_SUPPORTED
 481.421 +    /* Allocate a full-image virtual array for each component, */
 481.422 +    /* padded to a multiple of samp_factor DCT blocks in each direction. */
 481.423 +    int ci;
 481.424 +    jpeg_component_info *compptr;
 481.425 +
 481.426 +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 481.427 +	 ci++, compptr++) {
 481.428 +      coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
 481.429 +	((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
 481.430 +	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
 481.431 +				(long) compptr->h_samp_factor),
 481.432 +	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
 481.433 +				(long) compptr->v_samp_factor),
 481.434 +	 (JDIMENSION) compptr->v_samp_factor);
 481.435 +    }
 481.436 +#else
 481.437 +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 481.438 +#endif
 481.439 +  } else {
 481.440 +    /* We only need a single-MCU buffer. */
 481.441 +    JBLOCKROW buffer;
 481.442 +    int i;
 481.443 +
 481.444 +    buffer = (JBLOCKROW)
 481.445 +      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 481.446 +				  C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
 481.447 +    for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
 481.448 +      coef->MCU_buffer[i] = buffer + i;
 481.449 +    }
 481.450 +    coef->whole_image[0] = NULL; /* flag for no virtual arrays */
 481.451 +  }
 481.452 +}
   482.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   482.2 +++ b/libs/libjpeg/jccolor.c	Sat Feb 01 19:58:19 2014 +0200
   482.3 @@ -0,0 +1,459 @@
   482.4 +/*
   482.5 + * jccolor.c
   482.6 + *
   482.7 + * Copyright (C) 1991-1996, Thomas G. Lane.
   482.8 + * This file is part of the Independent JPEG Group's software.
   482.9 + * For conditions of distribution and use, see the accompanying README file.
  482.10 + *
  482.11 + * This file contains input colorspace conversion routines.
  482.12 + */
  482.13 +
  482.14 +#define JPEG_INTERNALS
  482.15 +#include "jinclude.h"
  482.16 +#include "jpeglib.h"
  482.17 +
  482.18 +
  482.19 +/* Private subobject */
  482.20 +
  482.21 +typedef struct {
  482.22 +  struct jpeg_color_converter pub; /* public fields */
  482.23 +
  482.24 +  /* Private state for RGB->YCC conversion */
  482.25 +  INT32 * rgb_ycc_tab;		/* => table for RGB to YCbCr conversion */
  482.26 +} my_color_converter;
  482.27 +
  482.28 +typedef my_color_converter * my_cconvert_ptr;
  482.29 +
  482.30 +
  482.31 +/**************** RGB -> YCbCr conversion: most common case **************/
  482.32 +
  482.33 +/*
  482.34 + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
  482.35 + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
  482.36 + * The conversion equations to be implemented are therefore
  482.37 + *	Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
  482.38 + *	Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + CENTERJSAMPLE
  482.39 + *	Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + CENTERJSAMPLE
  482.40 + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
  482.41 + * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
  482.42 + * rather than CENTERJSAMPLE, for Cb and Cr.  This gave equal positive and
  482.43 + * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
  482.44 + * were not represented exactly.  Now we sacrifice exact representation of
  482.45 + * maximum red and maximum blue in order to get exact grayscales.
  482.46 + *
  482.47 + * To avoid floating-point arithmetic, we represent the fractional constants
  482.48 + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
  482.49 + * the products by 2^16, with appropriate rounding, to get the correct answer.
  482.50 + *
  482.51 + * For even more speed, we avoid doing any multiplications in the inner loop
  482.52 + * by precalculating the constants times R,G,B for all possible values.
  482.53 + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
  482.54 + * for 12-bit samples it is still acceptable.  It's not very reasonable for
  482.55 + * 16-bit samples, but if you want lossless storage you shouldn't be changing
  482.56 + * colorspace anyway.
  482.57 + * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
  482.58 + * in the tables to save adding them separately in the inner loop.
  482.59 + */
  482.60 +
  482.61 +#define SCALEBITS	16	/* speediest right-shift on some machines */
  482.62 +#define CBCR_OFFSET	((INT32) CENTERJSAMPLE << SCALEBITS)
  482.63 +#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
  482.64 +#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  482.65 +
  482.66 +/* We allocate one big table and divide it up into eight parts, instead of
  482.67 + * doing eight alloc_small requests.  This lets us use a single table base
  482.68 + * address, which can be held in a register in the inner loops on many
  482.69 + * machines (more than can hold all eight addresses, anyway).
  482.70 + */
  482.71 +
  482.72 +#define R_Y_OFF		0			/* offset to R => Y section */
  482.73 +#define G_Y_OFF		(1*(MAXJSAMPLE+1))	/* offset to G => Y section */
  482.74 +#define B_Y_OFF		(2*(MAXJSAMPLE+1))	/* etc. */
  482.75 +#define R_CB_OFF	(3*(MAXJSAMPLE+1))
  482.76 +#define G_CB_OFF	(4*(MAXJSAMPLE+1))
  482.77 +#define B_CB_OFF	(5*(MAXJSAMPLE+1))
  482.78 +#define R_CR_OFF	B_CB_OFF		/* B=>Cb, R=>Cr are the same */
  482.79 +#define G_CR_OFF	(6*(MAXJSAMPLE+1))
  482.80 +#define B_CR_OFF	(7*(MAXJSAMPLE+1))
  482.81 +#define TABLE_SIZE	(8*(MAXJSAMPLE+1))
  482.82 +
  482.83 +
  482.84 +/*
  482.85 + * Initialize for RGB->YCC colorspace conversion.
  482.86 + */
  482.87 +
  482.88 +METHODDEF(void)
  482.89 +rgb_ycc_start (j_compress_ptr cinfo)
  482.90 +{
  482.91 +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
  482.92 +  INT32 * rgb_ycc_tab;
  482.93 +  INT32 i;
  482.94 +
  482.95 +  /* Allocate and fill in the conversion tables. */
  482.96 +  cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
  482.97 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  482.98 +				(TABLE_SIZE * SIZEOF(INT32)));
  482.99 +
 482.100 +  for (i = 0; i <= MAXJSAMPLE; i++) {
 482.101 +    rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
 482.102 +    rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
 482.103 +    rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i     + ONE_HALF;
 482.104 +    rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
 482.105 +    rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
 482.106 +    /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
 482.107 +     * This ensures that the maximum output will round to MAXJSAMPLE
 482.108 +     * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
 482.109 +     */
 482.110 +    rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
 482.111 +/*  B=>Cb and R=>Cr tables are the same
 482.112 +    rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
 482.113 +*/
 482.114 +    rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
 482.115 +    rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
 482.116 +  }
 482.117 +}
 482.118 +
 482.119 +
 482.120 +/*
 482.121 + * Convert some rows of samples to the JPEG colorspace.
 482.122 + *
 482.123 + * Note that we change from the application's interleaved-pixel format
 482.124 + * to our internal noninterleaved, one-plane-per-component format.
 482.125 + * The input buffer is therefore three times as wide as the output buffer.
 482.126 + *
 482.127 + * A starting row offset is provided only for the output buffer.  The caller
 482.128 + * can easily adjust the passed input_buf value to accommodate any row
 482.129 + * offset required on that side.
 482.130 + */
 482.131 +
 482.132 +METHODDEF(void)
 482.133 +rgb_ycc_convert (j_compress_ptr cinfo,
 482.134 +		 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 482.135 +		 JDIMENSION output_row, int num_rows)
 482.136 +{
 482.137 +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 482.138 +  register int r, g, b;
 482.139 +  register INT32 * ctab = cconvert->rgb_ycc_tab;
 482.140 +  register JSAMPROW inptr;
 482.141 +  register JSAMPROW outptr0, outptr1, outptr2;
 482.142 +  register JDIMENSION col;
 482.143 +  JDIMENSION num_cols = cinfo->image_width;
 482.144 +
 482.145 +  while (--num_rows >= 0) {
 482.146 +    inptr = *input_buf++;
 482.147 +    outptr0 = output_buf[0][output_row];
 482.148 +    outptr1 = output_buf[1][output_row];
 482.149 +    outptr2 = output_buf[2][output_row];
 482.150 +    output_row++;
 482.151 +    for (col = 0; col < num_cols; col++) {
 482.152 +      r = GETJSAMPLE(inptr[RGB_RED]);
 482.153 +      g = GETJSAMPLE(inptr[RGB_GREEN]);
 482.154 +      b = GETJSAMPLE(inptr[RGB_BLUE]);
 482.155 +      inptr += RGB_PIXELSIZE;
 482.156 +      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
 482.157 +       * must be too; we do not need an explicit range-limiting operation.
 482.158 +       * Hence the value being shifted is never negative, and we don't
 482.159 +       * need the general RIGHT_SHIFT macro.
 482.160 +       */
 482.161 +      /* Y */
 482.162 +      outptr0[col] = (JSAMPLE)
 482.163 +		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
 482.164 +		 >> SCALEBITS);
 482.165 +      /* Cb */
 482.166 +      outptr1[col] = (JSAMPLE)
 482.167 +		((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
 482.168 +		 >> SCALEBITS);
 482.169 +      /* Cr */
 482.170 +      outptr2[col] = (JSAMPLE)
 482.171 +		((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
 482.172 +		 >> SCALEBITS);
 482.173 +    }
 482.174 +  }
 482.175 +}
 482.176 +
 482.177 +
 482.178 +/**************** Cases other than RGB -> YCbCr **************/
 482.179 +
 482.180 +
 482.181 +/*
 482.182 + * Convert some rows of samples to the JPEG colorspace.
 482.183 + * This version handles RGB->grayscale conversion, which is the same
 482.184 + * as the RGB->Y portion of RGB->YCbCr.
 482.185 + * We assume rgb_ycc_start has been called (we only use the Y tables).
 482.186 + */
 482.187 +
 482.188 +METHODDEF(void)
 482.189 +rgb_gray_convert (j_compress_ptr cinfo,
 482.190 +		  JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 482.191 +		  JDIMENSION output_row, int num_rows)
 482.192 +{
 482.193 +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 482.194 +  register int r, g, b;
 482.195 +  register INT32 * ctab = cconvert->rgb_ycc_tab;
 482.196 +  register JSAMPROW inptr;
 482.197 +  register JSAMPROW outptr;
 482.198 +  register JDIMENSION col;
 482.199 +  JDIMENSION num_cols = cinfo->image_width;
 482.200 +
 482.201 +  while (--num_rows >= 0) {
 482.202 +    inptr = *input_buf++;
 482.203 +    outptr = output_buf[0][output_row];
 482.204 +    output_row++;
 482.205 +    for (col = 0; col < num_cols; col++) {
 482.206 +      r = GETJSAMPLE(inptr[RGB_RED]);
 482.207 +      g = GETJSAMPLE(inptr[RGB_GREEN]);
 482.208 +      b = GETJSAMPLE(inptr[RGB_BLUE]);
 482.209 +      inptr += RGB_PIXELSIZE;
 482.210 +      /* Y */
 482.211 +      outptr[col] = (JSAMPLE)
 482.212 +		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
 482.213 +		 >> SCALEBITS);
 482.214 +    }
 482.215 +  }
 482.216 +}
 482.217 +
 482.218 +
 482.219 +/*
 482.220 + * Convert some rows of samples to the JPEG colorspace.
 482.221 + * This version handles Adobe-style CMYK->YCCK conversion,
 482.222 + * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
 482.223 + * conversion as above, while passing K (black) unchanged.
 482.224 + * We assume rgb_ycc_start has been called.
 482.225 + */
 482.226 +
 482.227 +METHODDEF(void)
 482.228 +cmyk_ycck_convert (j_compress_ptr cinfo,
 482.229 +		   JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 482.230 +		   JDIMENSION output_row, int num_rows)
 482.231 +{
 482.232 +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 482.233 +  register int r, g, b;
 482.234 +  register INT32 * ctab = cconvert->rgb_ycc_tab;
 482.235 +  register JSAMPROW inptr;
 482.236 +  register JSAMPROW outptr0, outptr1, outptr2, outptr3;
 482.237 +  register JDIMENSION col;
 482.238 +  JDIMENSION num_cols = cinfo->image_width;
 482.239 +
 482.240 +  while (--num_rows >= 0) {
 482.241 +    inptr = *input_buf++;
 482.242 +    outptr0 = output_buf[0][output_row];
 482.243 +    outptr1 = output_buf[1][output_row];
 482.244 +    outptr2 = output_buf[2][output_row];
 482.245 +    outptr3 = output_buf[3][output_row];
 482.246 +    output_row++;
 482.247 +    for (col = 0; col < num_cols; col++) {
 482.248 +      r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
 482.249 +      g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
 482.250 +      b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
 482.251 +      /* K passes through as-is */
 482.252 +      outptr3[col] = inptr[3];	/* don't need GETJSAMPLE here */
 482.253 +      inptr += 4;
 482.254 +      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
 482.255 +       * must be too; we do not need an explicit range-limiting operation.
 482.256 +       * Hence the value being shifted is never negative, and we don't
 482.257 +       * need the general RIGHT_SHIFT macro.
 482.258 +       */
 482.259 +      /* Y */
 482.260 +      outptr0[col] = (JSAMPLE)
 482.261 +		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
 482.262 +		 >> SCALEBITS);
 482.263 +      /* Cb */
 482.264 +      outptr1[col] = (JSAMPLE)
 482.265 +		((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
 482.266 +		 >> SCALEBITS);
 482.267 +      /* Cr */
 482.268 +      outptr2[col] = (JSAMPLE)
 482.269 +		((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
 482.270 +		 >> SCALEBITS);
 482.271 +    }
 482.272 +  }
 482.273 +}
 482.274 +
 482.275 +
 482.276 +/*
 482.277 + * Convert some rows of samples to the JPEG colorspace.
 482.278 + * This version handles grayscale output with no conversion.
 482.279 + * The source can be either plain grayscale or YCbCr (since Y == gray).
 482.280 + */
 482.281 +
 482.282 +METHODDEF(void)
 482.283 +grayscale_convert (j_compress_ptr cinfo,
 482.284 +		   JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 482.285 +		   JDIMENSION output_row, int num_rows)
 482.286 +{
 482.287 +  register JSAMPROW inptr;
 482.288 +  register JSAMPROW outptr;
 482.289 +  register JDIMENSION col;
 482.290 +  JDIMENSION num_cols = cinfo->image_width;
 482.291 +  int instride = cinfo->input_components;
 482.292 +
 482.293 +  while (--num_rows >= 0) {
 482.294 +    inptr = *input_buf++;
 482.295 +    outptr = output_buf[0][output_row];
 482.296 +    output_row++;
 482.297 +    for (col = 0; col < num_cols; col++) {
 482.298 +      outptr[col] = inptr[0];	/* don't need GETJSAMPLE() here */
 482.299 +      inptr += instride;
 482.300 +    }
 482.301 +  }
 482.302 +}
 482.303 +
 482.304 +
 482.305 +/*
 482.306 + * Convert some rows of samples to the JPEG colorspace.
 482.307 + * This version handles multi-component colorspaces without conversion.
 482.308 + * We assume input_components == num_components.
 482.309 + */
 482.310 +
 482.311 +METHODDEF(void)
 482.312 +null_convert (j_compress_ptr cinfo,
 482.313 +	      JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 482.314 +	      JDIMENSION output_row, int num_rows)
 482.315 +{
 482.316 +  register JSAMPROW inptr;
 482.317 +  register JSAMPROW outptr;
 482.318 +  register JDIMENSION col;
 482.319 +  register int ci;
 482.320 +  int nc = cinfo->num_components;
 482.321 +  JDIMENSION num_cols = cinfo->image_width;
 482.322 +
 482.323 +  while (--num_rows >= 0) {
 482.324 +    /* It seems fastest to make a separate pass for each component. */
 482.325 +    for (ci = 0; ci < nc; ci++) {
 482.326 +      inptr = *input_buf;
 482.327 +      outptr = output_buf[ci][output_row];
 482.328 +      for (col = 0; col < num_cols; col++) {
 482.329 +	outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
 482.330 +	inptr += nc;
 482.331 +      }
 482.332 +    }
 482.333 +    input_buf++;
 482.334 +    output_row++;
 482.335 +  }
 482.336 +}
 482.337 +
 482.338 +
 482.339 +/*
 482.340 + * Empty method for start_pass.
 482.341 + */
 482.342 +
 482.343 +METHODDEF(void)
 482.344 +null_method (j_compress_ptr cinfo)
 482.345 +{
 482.346 +  /* no work needed */
 482.347 +}
 482.348 +
 482.349 +
 482.350 +/*
 482.351 + * Module initialization routine for input colorspace conversion.
 482.352 + */
 482.353 +
 482.354 +GLOBAL(void)
 482.355 +jinit_color_converter (j_compress_ptr cinfo)
 482.356 +{
 482.357 +  my_cconvert_ptr cconvert;
 482.358 +
 482.359 +  cconvert = (my_cconvert_ptr)
 482.360 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 482.361 +				SIZEOF(my_color_converter));
 482.362 +  cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
 482.363 +  /* set start_pass to null method until we find out differently */
 482.364 +  cconvert->pub.start_pass = null_method;
 482.365 +
 482.366 +  /* Make sure input_components agrees with in_color_space */
 482.367 +  switch (cinfo->in_color_space) {
 482.368 +  case JCS_GRAYSCALE:
 482.369 +    if (cinfo->input_components != 1)
 482.370 +      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 482.371 +    break;
 482.372 +
 482.373 +  case JCS_RGB:
 482.374 +#if RGB_PIXELSIZE != 3
 482.375 +    if (cinfo->input_components != RGB_PIXELSIZE)
 482.376 +      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 482.377 +    break;
 482.378 +#endif /* else share code with YCbCr */
 482.379 +
 482.380 +  case JCS_YCbCr:
 482.381 +    if (cinfo->input_components != 3)
 482.382 +      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 482.383 +    break;
 482.384 +
 482.385 +  case JCS_CMYK:
 482.386 +  case JCS_YCCK:
 482.387 +    if (cinfo->input_components != 4)
 482.388 +      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 482.389 +    break;
 482.390 +
 482.391 +  default:			/* JCS_UNKNOWN can be anything */
 482.392 +    if (cinfo->input_components < 1)
 482.393 +      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 482.394 +    break;
 482.395 +  }
 482.396 +
 482.397 +  /* Check num_components, set conversion method based on requested space */
 482.398 +  switch (cinfo->jpeg_color_space) {
 482.399 +  case JCS_GRAYSCALE:
 482.400 +    if (cinfo->num_components != 1)
 482.401 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 482.402 +    if (cinfo->in_color_space == JCS_GRAYSCALE)
 482.403 +      cconvert->pub.color_convert = grayscale_convert;
 482.404 +    else if (cinfo->in_color_space == JCS_RGB) {
 482.405 +      cconvert->pub.start_pass = rgb_ycc_start;
 482.406 +      cconvert->pub.color_convert = rgb_gray_convert;
 482.407 +    } else if (cinfo->in_color_space == JCS_YCbCr)
 482.408 +      cconvert->pub.color_convert = grayscale_convert;
 482.409 +    else
 482.410 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 482.411 +    break;
 482.412 +
 482.413 +  case JCS_RGB:
 482.414 +    if (cinfo->num_components != 3)
 482.415 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 482.416 +    if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
 482.417 +      cconvert->pub.color_convert = null_convert;
 482.418 +    else
 482.419 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 482.420 +    break;
 482.421 +
 482.422 +  case JCS_YCbCr:
 482.423 +    if (cinfo->num_components != 3)
 482.424 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 482.425 +    if (cinfo->in_color_space == JCS_RGB) {
 482.426 +      cconvert->pub.start_pass = rgb_ycc_start;
 482.427 +      cconvert->pub.color_convert = rgb_ycc_convert;
 482.428 +    } else if (cinfo->in_color_space == JCS_YCbCr)
 482.429 +      cconvert->pub.color_convert = null_convert;
 482.430 +    else
 482.431 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 482.432 +    break;
 482.433 +
 482.434 +  case JCS_CMYK:
 482.435 +    if (cinfo->num_components != 4)
 482.436 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 482.437 +    if (cinfo->in_color_space == JCS_CMYK)
 482.438 +      cconvert->pub.color_convert = null_convert;
 482.439 +    else
 482.440 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 482.441 +    break;
 482.442 +
 482.443 +  case JCS_YCCK:
 482.444 +    if (cinfo->num_components != 4)
 482.445 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 482.446 +    if (cinfo->in_color_space == JCS_CMYK) {
 482.447 +      cconvert->pub.start_pass = rgb_ycc_start;
 482.448 +      cconvert->pub.color_convert = cmyk_ycck_convert;
 482.449 +    } else if (cinfo->in_color_space == JCS_YCCK)
 482.450 +      cconvert->pub.color_convert = null_convert;
 482.451 +    else
 482.452 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 482.453 +    break;
 482.454 +
 482.455 +  default:			/* allow null conversion of JCS_UNKNOWN */
 482.456 +    if (cinfo->jpeg_color_space != cinfo->in_color_space ||
 482.457 +	cinfo->num_components != cinfo->input_components)
 482.458 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 482.459 +    cconvert->pub.color_convert = null_convert;
 482.460 +    break;
 482.461 +  }
 482.462 +}
   483.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   483.2 +++ b/libs/libjpeg/jcdctmgr.c	Sat Feb 01 19:58:19 2014 +0200
   483.3 @@ -0,0 +1,387 @@
   483.4 +/*
   483.5 + * jcdctmgr.c
   483.6 + *
   483.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   483.8 + * This file is part of the Independent JPEG Group's software.
   483.9 + * For conditions of distribution and use, see the accompanying README file.
  483.10 + *
  483.11 + * This file contains the forward-DCT management logic.
  483.12 + * This code selects a particular DCT implementation to be used,
  483.13 + * and it performs related housekeeping chores including coefficient
  483.14 + * quantization.
  483.15 + */
  483.16 +
  483.17 +#define JPEG_INTERNALS
  483.18 +#include "jinclude.h"
  483.19 +#include "jpeglib.h"
  483.20 +#include "jdct.h"		/* Private declarations for DCT subsystem */
  483.21 +
  483.22 +
  483.23 +/* Private subobject for this module */
  483.24 +
  483.25 +typedef struct {
  483.26 +  struct jpeg_forward_dct pub;	/* public fields */
  483.27 +
  483.28 +  /* Pointer to the DCT routine actually in use */
  483.29 +  forward_DCT_method_ptr do_dct;
  483.30 +
  483.31 +  /* The actual post-DCT divisors --- not identical to the quant table
  483.32 +   * entries, because of scaling (especially for an unnormalized DCT).
  483.33 +   * Each table is given in normal array order.
  483.34 +   */
  483.35 +  DCTELEM * divisors[NUM_QUANT_TBLS];
  483.36 +
  483.37 +#ifdef DCT_FLOAT_SUPPORTED
  483.38 +  /* Same as above for the floating-point case. */
  483.39 +  float_DCT_method_ptr do_float_dct;
  483.40 +  FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
  483.41 +#endif
  483.42 +} my_fdct_controller;
  483.43 +
  483.44 +typedef my_fdct_controller * my_fdct_ptr;
  483.45 +
  483.46 +
  483.47 +/*
  483.48 + * Initialize for a processing pass.
  483.49 + * Verify that all referenced Q-tables are present, and set up
  483.50 + * the divisor table for each one.
  483.51 + * In the current implementation, DCT of all components is done during
  483.52 + * the first pass, even if only some components will be output in the
  483.53 + * first scan.  Hence all components should be examined here.
  483.54 + */
  483.55 +
  483.56 +METHODDEF(void)
  483.57 +start_pass_fdctmgr (j_compress_ptr cinfo)
  483.58 +{
  483.59 +  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
  483.60 +  int ci, qtblno, i;
  483.61 +  jpeg_component_info *compptr;
  483.62 +  JQUANT_TBL * qtbl;
  483.63 +  DCTELEM * dtbl;
  483.64 +
  483.65 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  483.66 +       ci++, compptr++) {
  483.67 +    qtblno = compptr->quant_tbl_no;
  483.68 +    /* Make sure specified quantization table is present */
  483.69 +    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
  483.70 +	cinfo->quant_tbl_ptrs[qtblno] == NULL)
  483.71 +      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
  483.72 +    qtbl = cinfo->quant_tbl_ptrs[qtblno];
  483.73 +    /* Compute divisors for this quant table */
  483.74 +    /* We may do this more than once for same table, but it's not a big deal */
  483.75 +    switch (cinfo->dct_method) {
  483.76 +#ifdef DCT_ISLOW_SUPPORTED
  483.77 +    case JDCT_ISLOW:
  483.78 +      /* For LL&M IDCT method, divisors are equal to raw quantization
  483.79 +       * coefficients multiplied by 8 (to counteract scaling).
  483.80 +       */
  483.81 +      if (fdct->divisors[qtblno] == NULL) {
  483.82 +	fdct->divisors[qtblno] = (DCTELEM *)
  483.83 +	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  483.84 +				      DCTSIZE2 * SIZEOF(DCTELEM));
  483.85 +      }
  483.86 +      dtbl = fdct->divisors[qtblno];
  483.87 +      for (i = 0; i < DCTSIZE2; i++) {
  483.88 +	dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
  483.89 +      }
  483.90 +      break;
  483.91 +#endif
  483.92 +#ifdef DCT_IFAST_SUPPORTED
  483.93 +    case JDCT_IFAST:
  483.94 +      {
  483.95 +	/* For AA&N IDCT method, divisors are equal to quantization
  483.96 +	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
  483.97 +	 *   scalefactor[0] = 1
  483.98 +	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
  483.99 +	 * We apply a further scale factor of 8.
 483.100 +	 */
 483.101 +#define CONST_BITS 14
 483.102 +	static const INT16 aanscales[DCTSIZE2] = {
 483.103 +	  /* precomputed values scaled up by 14 bits */
 483.104 +	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
 483.105 +	  22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
 483.106 +	  21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
 483.107 +	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
 483.108 +	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
 483.109 +	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
 483.110 +	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
 483.111 +	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
 483.112 +	};
 483.113 +	SHIFT_TEMPS
 483.114 +
 483.115 +	if (fdct->divisors[qtblno] == NULL) {
 483.116 +	  fdct->divisors[qtblno] = (DCTELEM *)
 483.117 +	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 483.118 +					DCTSIZE2 * SIZEOF(DCTELEM));
 483.119 +	}
 483.120 +	dtbl = fdct->divisors[qtblno];
 483.121 +	for (i = 0; i < DCTSIZE2; i++) {
 483.122 +	  dtbl[i] = (DCTELEM)
 483.123 +	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
 483.124 +				  (INT32) aanscales[i]),
 483.125 +		    CONST_BITS-3);
 483.126 +	}
 483.127 +      }
 483.128 +      break;
 483.129 +#endif
 483.130 +#ifdef DCT_FLOAT_SUPPORTED
 483.131 +    case JDCT_FLOAT:
 483.132 +      {
 483.133 +	/* For float AA&N IDCT method, divisors are equal to quantization
 483.134 +	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
 483.135 +	 *   scalefactor[0] = 1
 483.136 +	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
 483.137 +	 * We apply a further scale factor of 8.
 483.138 +	 * What's actually stored is 1/divisor so that the inner loop can
 483.139 +	 * use a multiplication rather than a division.
 483.140 +	 */
 483.141 +	FAST_FLOAT * fdtbl;
 483.142 +	int row, col;
 483.143 +	static const double aanscalefactor[DCTSIZE] = {
 483.144 +	  1.0, 1.387039845, 1.306562965, 1.175875602,
 483.145 +	  1.0, 0.785694958, 0.541196100, 0.275899379
 483.146 +	};
 483.147 +
 483.148 +	if (fdct->float_divisors[qtblno] == NULL) {
 483.149 +	  fdct->float_divisors[qtblno] = (FAST_FLOAT *)
 483.150 +	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 483.151 +					DCTSIZE2 * SIZEOF(FAST_FLOAT));
 483.152 +	}
 483.153 +	fdtbl = fdct->float_divisors[qtblno];
 483.154 +	i = 0;
 483.155 +	for (row = 0; row < DCTSIZE; row++) {
 483.156 +	  for (col = 0; col < DCTSIZE; col++) {
 483.157 +	    fdtbl[i] = (FAST_FLOAT)
 483.158 +	      (1.0 / (((double) qtbl->quantval[i] *
 483.159 +		       aanscalefactor[row] * aanscalefactor[col] * 8.0)));
 483.160 +	    i++;
 483.161 +	  }
 483.162 +	}
 483.163 +      }
 483.164 +      break;
 483.165 +#endif
 483.166 +    default:
 483.167 +      ERREXIT(cinfo, JERR_NOT_COMPILED);
 483.168 +      break;
 483.169 +    }
 483.170 +  }
 483.171 +}
 483.172 +
 483.173 +
 483.174 +/*
 483.175 + * Perform forward DCT on one or more blocks of a component.
 483.176 + *
 483.177 + * The input samples are taken from the sample_data[] array starting at
 483.178 + * position start_row/start_col, and moving to the right for any additional
 483.179 + * blocks. The quantized coefficients are returned in coef_blocks[].
 483.180 + */
 483.181 +
 483.182 +METHODDEF(void)
 483.183 +forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
 483.184 +	     JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
 483.185 +	     JDIMENSION start_row, JDIMENSION start_col,
 483.186 +	     JDIMENSION num_blocks)
 483.187 +/* This version is used for integer DCT implementations. */
 483.188 +{
 483.189 +  /* This routine is heavily used, so it's worth coding it tightly. */
 483.190 +  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
 483.191 +  forward_DCT_method_ptr do_dct = fdct->do_dct;
 483.192 +  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
 483.193 +  DCTELEM workspace[DCTSIZE2];	/* work area for FDCT subroutine */
 483.194 +  JDIMENSION bi;
 483.195 +
 483.196 +  sample_data += start_row;	/* fold in the vertical offset once */
 483.197 +
 483.198 +  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
 483.199 +    /* Load data into workspace, applying unsigned->signed conversion */
 483.200 +    { register DCTELEM *workspaceptr;
 483.201 +      register JSAMPROW elemptr;
 483.202 +      register int elemr;
 483.203 +
 483.204 +      workspaceptr = workspace;
 483.205 +      for (elemr = 0; elemr < DCTSIZE; elemr++) {
 483.206 +	elemptr = sample_data[elemr] + start_col;
 483.207 +#if DCTSIZE == 8		/* unroll the inner loop */
 483.208 +	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
 483.209 +	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
 483.210 +	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
 483.211 +	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
 483.212 +	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
 483.213 +	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
 483.214 +	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
 483.215 +	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
 483.216 +#else
 483.217 +	{ register int elemc;
 483.218 +	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
 483.219 +	    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
 483.220 +	  }
 483.221 +	}
 483.222 +#endif
 483.223 +      }
 483.224 +    }
 483.225 +
 483.226 +    /* Perform the DCT */
 483.227 +    (*do_dct) (workspace);
 483.228 +
 483.229 +    /* Quantize/descale the coefficients, and store into coef_blocks[] */
 483.230 +    { register DCTELEM temp, qval;
 483.231 +      register int i;
 483.232 +      register JCOEFPTR output_ptr = coef_blocks[bi];
 483.233 +
 483.234 +      for (i = 0; i < DCTSIZE2; i++) {
 483.235 +	qval = divisors[i];
 483.236 +	temp = workspace[i];
 483.237 +	/* Divide the coefficient value by qval, ensuring proper rounding.
 483.238 +	 * Since C does not specify the direction of rounding for negative
 483.239 +	 * quotients, we have to force the dividend positive for portability.
 483.240 +	 *
 483.241 +	 * In most files, at least half of the output values will be zero
 483.242 +	 * (at default quantization settings, more like three-quarters...)
 483.243 +	 * so we should ensure that this case is fast.  On many machines,
 483.244 +	 * a comparison is enough cheaper than a divide to make a special test
 483.245 +	 * a win.  Since both inputs will be nonnegative, we need only test
 483.246 +	 * for a < b to discover whether a/b is 0.
 483.247 +	 * If your machine's division is fast enough, define FAST_DIVIDE.
 483.248 +	 */
 483.249 +#ifdef FAST_DIVIDE
 483.250 +#define DIVIDE_BY(a,b)	a /= b
 483.251 +#else
 483.252 +#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0
 483.253 +#endif
 483.254 +	if (temp < 0) {
 483.255 +	  temp = -temp;
 483.256 +	  temp += qval>>1;	/* for rounding */
 483.257 +	  DIVIDE_BY(temp, qval);
 483.258 +	  temp = -temp;
 483.259 +	} else {
 483.260 +	  temp += qval>>1;	/* for rounding */
 483.261 +	  DIVIDE_BY(temp, qval);
 483.262 +	}
 483.263 +	output_ptr[i] = (JCOEF) temp;
 483.264 +      }
 483.265 +    }
 483.266 +  }
 483.267 +}
 483.268 +
 483.269 +
 483.270 +#ifdef DCT_FLOAT_SUPPORTED
 483.271 +
 483.272 +METHODDEF(void)
 483.273 +forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
 483.274 +		   JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
 483.275 +		   JDIMENSION start_row, JDIMENSION start_col,
 483.276 +		   JDIMENSION num_blocks)
 483.277 +/* This version is used for floating-point DCT implementations. */
 483.278 +{
 483.279 +  /* This routine is heavily used, so it's worth coding it tightly. */
 483.280 +  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
 483.281 +  float_DCT_method_ptr do_dct = fdct->do_float_dct;
 483.282 +  FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
 483.283 +  FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
 483.284 +  JDIMENSION bi;
 483.285 +
 483.286 +  sample_data += start_row;	/* fold in the vertical offset once */
 483.287 +
 483.288 +  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
 483.289 +    /* Load data into workspace, applying unsigned->signed conversion */
 483.290 +    { register FAST_FLOAT *workspaceptr;
 483.291 +      register JSAMPROW elemptr;
 483.292 +      register int elemr;
 483.293 +
 483.294 +      workspaceptr = workspace;
 483.295 +      for (elemr = 0; elemr < DCTSIZE; elemr++) {
 483.296 +	elemptr = sample_data[elemr] + start_col;
 483.297 +#if DCTSIZE == 8		/* unroll the inner loop */
 483.298 +	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
 483.299 +	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
 483.300 +	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
 483.301 +	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
 483.302 +	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
 483.303 +	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
 483.304 +	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
 483.305 +	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
 483.306 +#else
 483.307 +	{ register int elemc;
 483.308 +	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
 483.309 +	    *workspaceptr++ = (FAST_FLOAT)
 483.310 +	      (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
 483.311 +	  }
 483.312 +	}
 483.313 +#endif
 483.314 +      }
 483.315 +    }
 483.316 +
 483.317 +    /* Perform the DCT */
 483.318 +    (*do_dct) (workspace);
 483.319 +
 483.320 +    /* Quantize/descale the coefficients, and store into coef_blocks[] */
 483.321 +    { register FAST_FLOAT temp;
 483.322 +      register int i;
 483.323 +      register JCOEFPTR output_ptr = coef_blocks[bi];
 483.324 +
 483.325 +      for (i = 0; i < DCTSIZE2; i++) {
 483.326 +	/* Apply the quantization and scaling factor */
 483.327 +	temp = workspace[i] * divisors[i];
 483.328 +	/* Round to nearest integer.
 483.329 +	 * Since C does not specify the direction of rounding for negative
 483.330 +	 * quotients, we have to force the dividend positive for portability.
 483.331 +	 * The maximum coefficient size is +-16K (for 12-bit data), so this
 483.332 +	 * code should work for either 16-bit or 32-bit ints.
 483.333 +	 */
 483.334 +	output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
 483.335 +      }
 483.336 +    }
 483.337 +  }
 483.338 +}
 483.339 +
 483.340 +#endif /* DCT_FLOAT_SUPPORTED */
 483.341 +
 483.342 +
 483.343 +/*
 483.344 + * Initialize FDCT manager.
 483.345 + */
 483.346 +
 483.347 +GLOBAL(void)
 483.348 +jinit_forward_dct (j_compress_ptr cinfo)
 483.349 +{
 483.350 +  my_fdct_ptr fdct;
 483.351 +  int i;
 483.352 +
 483.353 +  fdct = (my_fdct_ptr)
 483.354 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 483.355 +				SIZEOF(my_fdct_controller));
 483.356 +  cinfo->fdct = (struct jpeg_forward_dct *) fdct;
 483.357 +  fdct->pub.start_pass = start_pass_fdctmgr;
 483.358 +
 483.359 +  switch (cinfo->dct_method) {
 483.360 +#ifdef DCT_ISLOW_SUPPORTED
 483.361 +  case JDCT_ISLOW:
 483.362 +    fdct->pub.forward_DCT = forward_DCT;
 483.363 +    fdct->do_dct = jpeg_fdct_islow;
 483.364 +    break;
 483.365 +#endif
 483.366 +#ifdef DCT_IFAST_SUPPORTED
 483.367 +  case JDCT_IFAST:
 483.368 +    fdct->pub.forward_DCT = forward_DCT;
 483.369 +    fdct->do_dct = jpeg_fdct_ifast;
 483.370 +    break;
 483.371 +#endif
 483.372 +#ifdef DCT_FLOAT_SUPPORTED
 483.373 +  case JDCT_FLOAT:
 483.374 +    fdct->pub.forward_DCT = forward_DCT_float;
 483.375 +    fdct->do_float_dct = jpeg_fdct_float;
 483.376 +    break;
 483.377 +#endif
 483.378 +  default:
 483.379 +    ERREXIT(cinfo, JERR_NOT_COMPILED);
 483.380 +    break;
 483.381 +  }
 483.382 +
 483.383 +  /* Mark divisor tables unallocated */
 483.384 +  for (i = 0; i < NUM_QUANT_TBLS; i++) {
 483.385 +    fdct->divisors[i] = NULL;
 483.386 +#ifdef DCT_FLOAT_SUPPORTED
 483.387 +    fdct->float_divisors[i] = NULL;
 483.388 +#endif
 483.389 +  }
 483.390 +}
   484.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   484.2 +++ b/libs/libjpeg/jchuff.c	Sat Feb 01 19:58:19 2014 +0200
   484.3 @@ -0,0 +1,909 @@
   484.4 +/*
   484.5 + * jchuff.c
   484.6 + *
   484.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   484.8 + * This file is part of the Independent JPEG Group's software.
   484.9 + * For conditions of distribution and use, see the accompanying README file.
  484.10 + *
  484.11 + * This file contains Huffman entropy encoding routines.
  484.12 + *
  484.13 + * Much of the complexity here has to do with supporting output suspension.
  484.14 + * If the data destination module demands suspension, we want to be able to
  484.15 + * back up to the start of the current MCU.  To do this, we copy state
  484.16 + * variables into local working storage, and update them back to the
  484.17 + * permanent JPEG objects only upon successful completion of an MCU.
  484.18 + */
  484.19 +
  484.20 +#define JPEG_INTERNALS
  484.21 +#include "jinclude.h"
  484.22 +#include "jpeglib.h"
  484.23 +#include "jchuff.h"		/* Declarations shared with jcphuff.c */
  484.24 +
  484.25 +
  484.26 +/* Expanded entropy encoder object for Huffman encoding.
  484.27 + *
  484.28 + * The savable_state subrecord contains fields that change within an MCU,
  484.29 + * but must not be updated permanently until we complete the MCU.
  484.30 + */
  484.31 +
  484.32 +typedef struct {
  484.33 +  INT32 put_buffer;		/* current bit-accumulation buffer */
  484.34 +  int put_bits;			/* # of bits now in it */
  484.35 +  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
  484.36 +} savable_state;
  484.37 +
  484.38 +/* This macro is to work around compilers with missing or broken
  484.39 + * structure assignment.  You'll need to fix this code if you have
  484.40 + * such a compiler and you change MAX_COMPS_IN_SCAN.
  484.41 + */
  484.42 +
  484.43 +#ifndef NO_STRUCT_ASSIGN
  484.44 +#define ASSIGN_STATE(dest,src)  ((dest) = (src))
  484.45 +#else
  484.46 +#if MAX_COMPS_IN_SCAN == 4
  484.47 +#define ASSIGN_STATE(dest,src)  \
  484.48 +	((dest).put_buffer = (src).put_buffer, \
  484.49 +	 (dest).put_bits = (src).put_bits, \
  484.50 +	 (dest).last_dc_val[0] = (src).last_dc_val[0], \
  484.51 +	 (dest).last_dc_val[1] = (src).last_dc_val[1], \
  484.52 +	 (dest).last_dc_val[2] = (src).last_dc_val[2], \
  484.53 +	 (dest).last_dc_val[3] = (src).last_dc_val[3])
  484.54 +#endif
  484.55 +#endif
  484.56 +
  484.57 +
  484.58 +typedef struct {
  484.59 +  struct jpeg_entropy_encoder pub; /* public fields */
  484.60 +
  484.61 +  savable_state saved;		/* Bit buffer & DC state at start of MCU */
  484.62 +
  484.63 +  /* These fields are NOT loaded into local working state. */
  484.64 +  unsigned int restarts_to_go;	/* MCUs left in this restart interval */
  484.65 +  int next_restart_num;		/* next restart number to write (0-7) */
  484.66 +
  484.67 +  /* Pointers to derived tables (these workspaces have image lifespan) */
  484.68 +  c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
  484.69 +  c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
  484.70 +
  484.71 +#ifdef ENTROPY_OPT_SUPPORTED	/* Statistics tables for optimization */
  484.72 +  long * dc_count_ptrs[NUM_HUFF_TBLS];
  484.73 +  long * ac_count_ptrs[NUM_HUFF_TBLS];
  484.74 +#endif
  484.75 +} huff_entropy_encoder;
  484.76 +
  484.77 +typedef huff_entropy_encoder * huff_entropy_ptr;
  484.78 +
  484.79 +/* Working state while writing an MCU.
  484.80 + * This struct contains all the fields that are needed by subroutines.
  484.81 + */
  484.82 +
  484.83 +typedef struct {
  484.84 +  JOCTET * next_output_byte;	/* => next byte to write in buffer */
  484.85 +  size_t free_in_buffer;	/* # of byte spaces remaining in buffer */
  484.86 +  savable_state cur;		/* Current bit buffer & DC state */
  484.87 +  j_compress_ptr cinfo;		/* dump_buffer needs access to this */
  484.88 +} working_state;
  484.89 +
  484.90 +
  484.91 +/* Forward declarations */
  484.92 +METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo,
  484.93 +					JBLOCKROW *MCU_data));
  484.94 +METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo));
  484.95 +#ifdef ENTROPY_OPT_SUPPORTED
  484.96 +METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo,
  484.97 +					  JBLOCKROW *MCU_data));
  484.98 +METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo));
  484.99 +#endif
 484.100 +
 484.101 +
 484.102 +/*
 484.103 + * Initialize for a Huffman-compressed scan.
 484.104 + * If gather_statistics is TRUE, we do not output anything during the scan,
 484.105 + * just count the Huffman symbols used and generate Huffman code tables.
 484.106 + */
 484.107 +
 484.108 +METHODDEF(void)
 484.109 +start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
 484.110 +{
 484.111 +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
 484.112 +  int ci, dctbl, actbl;
 484.113 +  jpeg_component_info * compptr;
 484.114 +
 484.115 +  if (gather_statistics) {
 484.116 +#ifdef ENTROPY_OPT_SUPPORTED
 484.117 +    entropy->pub.encode_mcu = encode_mcu_gather;
 484.118 +    entropy->pub.finish_pass = finish_pass_gather;
 484.119 +#else
 484.120 +    ERREXIT(cinfo, JERR_NOT_COMPILED);
 484.121 +#endif
 484.122 +  } else {
 484.123 +    entropy->pub.encode_mcu = encode_mcu_huff;
 484.124 +    entropy->pub.finish_pass = finish_pass_huff;
 484.125 +  }
 484.126 +
 484.127 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 484.128 +    compptr = cinfo->cur_comp_info[ci];
 484.129 +    dctbl = compptr->dc_tbl_no;
 484.130 +    actbl = compptr->ac_tbl_no;
 484.131 +    if (gather_statistics) {
 484.132 +#ifdef ENTROPY_OPT_SUPPORTED
 484.133 +      /* Check for invalid table indexes */
 484.134 +      /* (make_c_derived_tbl does this in the other path) */
 484.135 +      if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
 484.136 +	ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
 484.137 +      if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
 484.138 +	ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
 484.139 +      /* Allocate and zero the statistics tables */
 484.140 +      /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
 484.141 +      if (entropy->dc_count_ptrs[dctbl] == NULL)
 484.142 +	entropy->dc_count_ptrs[dctbl] = (long *)
 484.143 +	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 484.144 +				      257 * SIZEOF(long));
 484.145 +      MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long));
 484.146 +      if (entropy->ac_count_ptrs[actbl] == NULL)
 484.147 +	entropy->ac_count_ptrs[actbl] = (long *)
 484.148 +	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 484.149 +				      257 * SIZEOF(long));
 484.150 +      MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long));
 484.151 +#endif
 484.152 +    } else {
 484.153 +      /* Compute derived values for Huffman tables */
 484.154 +      /* We may do this more than once for a table, but it's not expensive */
 484.155 +      jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
 484.156 +			      & entropy->dc_derived_tbls[dctbl]);
 484.157 +      jpeg_make_c_derived_tbl(cinfo, FALSE, actbl,
 484.158 +			      & entropy->ac_derived_tbls[actbl]);
 484.159 +    }
 484.160 +    /* Initialize DC predictions to 0 */
 484.161 +    entropy->saved.last_dc_val[ci] = 0;
 484.162 +  }
 484.163 +
 484.164 +  /* Initialize bit buffer to empty */
 484.165 +  entropy->saved.put_buffer = 0;
 484.166 +  entropy->saved.put_bits = 0;
 484.167 +
 484.168 +  /* Initialize restart stuff */
 484.169 +  entropy->restarts_to_go = cinfo->restart_interval;
 484.170 +  entropy->next_restart_num = 0;
 484.171 +}
 484.172 +
 484.173 +
 484.174 +/*
 484.175 + * Compute the derived values for a Huffman table.
 484.176 + * This routine also performs some validation checks on the table.
 484.177 + *
 484.178 + * Note this is also used by jcphuff.c.
 484.179 + */
 484.180 +
 484.181 +GLOBAL(void)
 484.182 +jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
 484.183 +			 c_derived_tbl ** pdtbl)
 484.184 +{
 484.185 +  JHUFF_TBL *htbl;
 484.186 +  c_derived_tbl *dtbl;
 484.187 +  int p, i, l, lastp, si, maxsymbol;
 484.188 +  char huffsize[257];
 484.189 +  unsigned int huffcode[257];
 484.190 +  unsigned int code;
 484.191 +
 484.192 +  /* Note that huffsize[] and huffcode[] are filled in code-length order,
 484.193 +   * paralleling the order of the symbols themselves in htbl->huffval[].
 484.194 +   */
 484.195 +
 484.196 +  /* Find the input Huffman table */
 484.197 +  if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
 484.198 +    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
 484.199 +  htbl =
 484.200 +    isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
 484.201 +  if (htbl == NULL)
 484.202 +    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
 484.203 +
 484.204 +  /* Allocate a workspace if we haven't already done so. */
 484.205 +  if (*pdtbl == NULL)
 484.206 +    *pdtbl = (c_derived_tbl *)
 484.207 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 484.208 +				  SIZEOF(c_derived_tbl));
 484.209 +  dtbl = *pdtbl;
 484.210 +  
 484.211 +  /* Figure C.1: make table of Huffman code length for each symbol */
 484.212 +
 484.213 +  p = 0;
 484.214 +  for (l = 1; l <= 16; l++) {
 484.215 +    i = (int) htbl->bits[l];
 484.216 +    if (i < 0 || p + i > 256)	/* protect against table overrun */
 484.217 +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 484.218 +    while (i--)
 484.219 +      huffsize[p++] = (char) l;
 484.220 +  }
 484.221 +  huffsize[p] = 0;
 484.222 +  lastp = p;
 484.223 +  
 484.224 +  /* Figure C.2: generate the codes themselves */
 484.225 +  /* We also validate that the counts represent a legal Huffman code tree. */
 484.226 +
 484.227 +  code = 0;
 484.228 +  si = huffsize[0];
 484.229 +  p = 0;
 484.230 +  while (huffsize[p]) {
 484.231 +    while (((int) huffsize[p]) == si) {
 484.232 +      huffcode[p++] = code;
 484.233 +      code++;
 484.234 +    }
 484.235 +    /* code is now 1 more than the last code used for codelength si; but
 484.236 +     * it must still fit in si bits, since no code is allowed to be all ones.
 484.237 +     */
 484.238 +    if (((INT32) code) >= (((INT32) 1) << si))
 484.239 +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 484.240 +    code <<= 1;
 484.241 +    si++;
 484.242 +  }
 484.243 +  
 484.244 +  /* Figure C.3: generate encoding tables */
 484.245 +  /* These are code and size indexed by symbol value */
 484.246 +
 484.247 +  /* Set all codeless symbols to have code length 0;
 484.248 +   * this lets us detect duplicate VAL entries here, and later
 484.249 +   * allows emit_bits to detect any attempt to emit such symbols.
 484.250 +   */
 484.251 +  MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi));
 484.252 +
 484.253 +  /* This is also a convenient place to check for out-of-range
 484.254 +   * and duplicated VAL entries.  We allow 0..255 for AC symbols
 484.255 +   * but only 0..15 for DC.  (We could constrain them further
 484.256 +   * based on data depth and mode, but this seems enough.)
 484.257 +   */
 484.258 +  maxsymbol = isDC ? 15 : 255;
 484.259 +
 484.260 +  for (p = 0; p < lastp; p++) {
 484.261 +    i = htbl->huffval[p];
 484.262 +    if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
 484.263 +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 484.264 +    dtbl->ehufco[i] = huffcode[p];
 484.265 +    dtbl->ehufsi[i] = huffsize[p];
 484.266 +  }
 484.267 +}
 484.268 +
 484.269 +
 484.270 +/* Outputting bytes to the file */
 484.271 +
 484.272 +/* Emit a byte, taking 'action' if must suspend. */
 484.273 +#define emit_byte(state,val,action)  \
 484.274 +	{ *(state)->next_output_byte++ = (JOCTET) (val);  \
 484.275 +	  if (--(state)->free_in_buffer == 0)  \
 484.276 +	    if (! dump_buffer(state))  \
 484.277 +	      { action; } }
 484.278 +
 484.279 +
 484.280 +LOCAL(boolean)
 484.281 +dump_buffer (working_state * state)
 484.282 +/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
 484.283 +{
 484.284 +  struct jpeg_destination_mgr * dest = state->cinfo->dest;
 484.285 +
 484.286 +  if (! (*dest->empty_output_buffer) (state->cinfo))
 484.287 +    return FALSE;
 484.288 +  /* After a successful buffer dump, must reset buffer pointers */
 484.289 +  state->next_output_byte = dest->next_output_byte;
 484.290 +  state->free_in_buffer = dest->free_in_buffer;
 484.291 +  return TRUE;
 484.292 +}
 484.293 +
 484.294 +
 484.295 +/* Outputting bits to the file */
 484.296 +
 484.297 +/* Only the right 24 bits of put_buffer are used; the valid bits are
 484.298 + * left-justified in this part.  At most 16 bits can be passed to emit_bits
 484.299 + * in one call, and we never retain more than 7 bits in put_buffer
 484.300 + * between calls, so 24 bits are sufficient.
 484.301 + */
 484.302 +
 484.303 +INLINE
 484.304 +LOCAL(boolean)
 484.305 +emit_bits (working_state * state, unsigned int code, int size)
 484.306 +/* Emit some bits; return TRUE if successful, FALSE if must suspend */
 484.307 +{
 484.308 +  /* This routine is heavily used, so it's worth coding tightly. */
 484.309 +  register INT32 put_buffer = (INT32) code;
 484.310 +  register int put_bits = state->cur.put_bits;
 484.311 +
 484.312 +  /* if size is 0, caller used an invalid Huffman table entry */
 484.313 +  if (size == 0)
 484.314 +    ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
 484.315 +
 484.316 +  put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
 484.317 +  
 484.318 +  put_bits += size;		/* new number of bits in buffer */
 484.319 +  
 484.320 +  put_buffer <<= 24 - put_bits; /* align incoming bits */
 484.321 +
 484.322 +  put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
 484.323 +  
 484.324 +  while (put_bits >= 8) {
 484.325 +    int c = (int) ((put_buffer >> 16) & 0xFF);
 484.326 +    
 484.327 +    emit_byte(state, c, return FALSE);
 484.328 +    if (c == 0xFF) {		/* need to stuff a zero byte? */
 484.329 +      emit_byte(state, 0, return FALSE);
 484.330 +    }
 484.331 +    put_buffer <<= 8;
 484.332 +    put_bits -= 8;
 484.333 +  }
 484.334 +
 484.335 +  state->cur.put_buffer = put_buffer; /* update state variables */
 484.336 +  state->cur.put_bits = put_bits;
 484.337 +
 484.338 +  return TRUE;
 484.339 +}
 484.340 +
 484.341 +
 484.342 +LOCAL(boolean)
 484.343 +flush_bits (working_state * state)
 484.344 +{
 484.345 +  if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
 484.346 +    return FALSE;
 484.347 +  state->cur.put_buffer = 0;	/* and reset bit-buffer to empty */
 484.348 +  state->cur.put_bits = 0;
 484.349 +  return TRUE;
 484.350 +}
 484.351 +
 484.352 +
 484.353 +/* Encode a single block's worth of coefficients */
 484.354 +
 484.355 +LOCAL(boolean)
 484.356 +encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
 484.357 +		  c_derived_tbl *dctbl, c_derived_tbl *actbl)
 484.358 +{
 484.359 +  register int temp, temp2;
 484.360 +  register int nbits;
 484.361 +  register int k, r, i;
 484.362 +  
 484.363 +  /* Encode the DC coefficient difference per section F.1.2.1 */
 484.364 +  
 484.365 +  temp = temp2 = block[0] - last_dc_val;
 484.366 +
 484.367 +  if (temp < 0) {
 484.368 +    temp = -temp;		/* temp is abs value of input */
 484.369 +    /* For a negative input, want temp2 = bitwise complement of abs(input) */
 484.370 +    /* This code assumes we are on a two's complement machine */
 484.371 +    temp2--;
 484.372 +  }
 484.373 +  
 484.374 +  /* Find the number of bits needed for the magnitude of the coefficient */
 484.375 +  nbits = 0;
 484.376 +  while (temp) {
 484.377 +    nbits++;
 484.378 +    temp >>= 1;
 484.379 +  }
 484.380 +  /* Check for out-of-range coefficient values.
 484.381 +   * Since we're encoding a difference, the range limit is twice as much.
 484.382 +   */
 484.383 +  if (nbits > MAX_COEF_BITS+1)
 484.384 +    ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
 484.385 +  
 484.386 +  /* Emit the Huffman-coded symbol for the number of bits */
 484.387 +  if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
 484.388 +    return FALSE;
 484.389 +
 484.390 +  /* Emit that number of bits of the value, if positive, */
 484.391 +  /* or the complement of its magnitude, if negative. */
 484.392 +  if (nbits)			/* emit_bits rejects calls with size 0 */
 484.393 +    if (! emit_bits(state, (unsigned int) temp2, nbits))
 484.394 +      return FALSE;
 484.395 +
 484.396 +  /* Encode the AC coefficients per section F.1.2.2 */
 484.397 +  
 484.398 +  r = 0;			/* r = run length of zeros */
 484.399 +  
 484.400 +  for (k = 1; k < DCTSIZE2; k++) {
 484.401 +    if ((temp = block[jpeg_natural_order[k]]) == 0) {
 484.402 +      r++;
 484.403 +    } else {
 484.404 +      /* if run length > 15, must emit special run-length-16 codes (0xF0) */
 484.405 +      while (r > 15) {
 484.406 +	if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0]))
 484.407 +	  return FALSE;
 484.408 +	r -= 16;
 484.409 +      }
 484.410 +
 484.411 +      temp2 = temp;
 484.412 +      if (temp < 0) {
 484.413 +	temp = -temp;		/* temp is abs value of input */
 484.414 +	/* This code assumes we are on a two's complement machine */
 484.415 +	temp2--;
 484.416 +      }
 484.417 +      
 484.418 +      /* Find the number of bits needed for the magnitude of the coefficient */
 484.419 +      nbits = 1;		/* there must be at least one 1 bit */
 484.420 +      while ((temp >>= 1))
 484.421 +	nbits++;
 484.422 +      /* Check for out-of-range coefficient values */
 484.423 +      if (nbits > MAX_COEF_BITS)
 484.424 +	ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
 484.425 +      
 484.426 +      /* Emit Huffman symbol for run length / number of bits */
 484.427 +      i = (r << 4) + nbits;
 484.428 +      if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i]))
 484.429 +	return FALSE;
 484.430 +
 484.431 +      /* Emit that number of bits of the value, if positive, */
 484.432 +      /* or the complement of its magnitude, if negative. */
 484.433 +      if (! emit_bits(state, (unsigned int) temp2, nbits))
 484.434 +	return FALSE;
 484.435 +      
 484.436 +      r = 0;
 484.437 +    }
 484.438 +  }
 484.439 +
 484.440 +  /* If the last coef(s) were zero, emit an end-of-block code */
 484.441 +  if (r > 0)
 484.442 +    if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0]))
 484.443 +      return FALSE;
 484.444 +
 484.445 +  return TRUE;
 484.446 +}
 484.447 +
 484.448 +
 484.449 +/*
 484.450 + * Emit a restart marker & resynchronize predictions.
 484.451 + */
 484.452 +
 484.453 +LOCAL(boolean)
 484.454 +emit_restart (working_state * state, int restart_num)
 484.455 +{
 484.456 +  int ci;
 484.457 +
 484.458 +  if (! flush_bits(state))
 484.459 +    return FALSE;
 484.460 +
 484.461 +  emit_byte(state, 0xFF, return FALSE);
 484.462 +  emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
 484.463 +
 484.464 +  /* Re-initialize DC predictions to 0 */
 484.465 +  for (ci = 0; ci < state->cinfo->comps_in_scan; ci++)
 484.466 +    state->cur.last_dc_val[ci] = 0;
 484.467 +
 484.468 +  /* The restart counter is not updated until we successfully write the MCU. */
 484.469 +
 484.470 +  return TRUE;
 484.471 +}
 484.472 +
 484.473 +
 484.474 +/*
 484.475 + * Encode and output one MCU's worth of Huffman-compressed coefficients.
 484.476 + */
 484.477 +
 484.478 +METHODDEF(boolean)
 484.479 +encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 484.480 +{
 484.481 +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
 484.482 +  working_state state;
 484.483 +  int blkn, ci;
 484.484 +  jpeg_component_info * compptr;
 484.485 +
 484.486 +  /* Load up working state */
 484.487 +  state.next_output_byte = cinfo->dest->next_output_byte;
 484.488 +  state.free_in_buffer = cinfo->dest->free_in_buffer;
 484.489 +  ASSIGN_STATE(state.cur, entropy->saved);
 484.490 +  state.cinfo = cinfo;
 484.491 +
 484.492 +  /* Emit restart marker if needed */
 484.493 +  if (cinfo->restart_interval) {
 484.494 +    if (entropy->restarts_to_go == 0)
 484.495 +      if (! emit_restart(&state, entropy->next_restart_num))
 484.496 +	return FALSE;
 484.497 +  }
 484.498 +
 484.499 +  /* Encode the MCU data blocks */
 484.500 +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
 484.501 +    ci = cinfo->MCU_membership[blkn];
 484.502 +    compptr = cinfo->cur_comp_info[ci];
 484.503 +    if (! encode_one_block(&state,
 484.504 +			   MCU_data[blkn][0], state.cur.last_dc_val[ci],
 484.505 +			   entropy->dc_derived_tbls[compptr->dc_tbl_no],
 484.506 +			   entropy->ac_derived_tbls[compptr->ac_tbl_no]))
 484.507 +      return FALSE;
 484.508 +    /* Update last_dc_val */
 484.509 +    state.cur.last_dc_val[ci] = MCU_data[blkn][0][0];
 484.510 +  }
 484.511 +
 484.512 +  /* Completed MCU, so update state */
 484.513 +  cinfo->dest->next_output_byte = state.next_output_byte;
 484.514 +  cinfo->dest->free_in_buffer = state.free_in_buffer;
 484.515 +  ASSIGN_STATE(entropy->saved, state.cur);
 484.516 +
 484.517 +  /* Update restart-interval state too */
 484.518 +  if (cinfo->restart_interval) {
 484.519 +    if (entropy->restarts_to_go == 0) {
 484.520 +      entropy->restarts_to_go = cinfo->restart_interval;
 484.521 +      entropy->next_restart_num++;
 484.522 +      entropy->next_restart_num &= 7;
 484.523 +    }
 484.524 +    entropy->restarts_to_go--;
 484.525 +  }
 484.526 +
 484.527 +  return TRUE;
 484.528 +}
 484.529 +
 484.530 +
 484.531 +/*
 484.532 + * Finish up at the end of a Huffman-compressed scan.
 484.533 + */
 484.534 +
 484.535 +METHODDEF(void)
 484.536 +finish_pass_huff (j_compress_ptr cinfo)
 484.537 +{
 484.538 +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
 484.539 +  working_state state;
 484.540 +
 484.541 +  /* Load up working state ... flush_bits needs it */
 484.542 +  state.next_output_byte = cinfo->dest->next_output_byte;
 484.543 +  state.free_in_buffer = cinfo->dest->free_in_buffer;
 484.544 +  ASSIGN_STATE(state.cur, entropy->saved);
 484.545 +  state.cinfo = cinfo;
 484.546 +
 484.547 +  /* Flush out the last data */
 484.548 +  if (! flush_bits(&state))
 484.549 +    ERREXIT(cinfo, JERR_CANT_SUSPEND);
 484.550 +
 484.551 +  /* Update state */
 484.552 +  cinfo->dest->next_output_byte = state.next_output_byte;
 484.553 +  cinfo->dest->free_in_buffer = state.free_in_buffer;
 484.554 +  ASSIGN_STATE(entropy->saved, state.cur);
 484.555 +}
 484.556 +
 484.557 +
 484.558 +/*
 484.559 + * Huffman coding optimization.
 484.560 + *
 484.561 + * We first scan the supplied data and count the number of uses of each symbol
 484.562 + * that is to be Huffman-coded. (This process MUST agree with the code above.)
 484.563 + * Then we build a Huffman coding tree for the observed counts.
 484.564 + * Symbols which are not needed at all for the particular image are not
 484.565 + * assigned any code, which saves space in the DHT marker as well as in
 484.566 + * the compressed data.
 484.567 + */
 484.568 +
 484.569 +#ifdef ENTROPY_OPT_SUPPORTED
 484.570 +
 484.571 +
 484.572 +/* Process a single block's worth of coefficients */
 484.573 +
 484.574 +LOCAL(void)
 484.575 +htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
 484.576 +		 long dc_counts[], long ac_counts[])
 484.577 +{
 484.578 +  register int temp;
 484.579 +  register int nbits;
 484.580 +  register int k, r;
 484.581 +  
 484.582 +  /* Encode the DC coefficient difference per section F.1.2.1 */
 484.583 +  
 484.584 +  temp = block[0] - last_dc_val;
 484.585 +  if (temp < 0)
 484.586 +    temp = -temp;
 484.587 +  
 484.588 +  /* Find the number of bits needed for the magnitude of the coefficient */
 484.589 +  nbits = 0;
 484.590 +  while (temp) {
 484.591 +    nbits++;
 484.592 +    temp >>= 1;
 484.593 +  }
 484.594 +  /* Check for out-of-range coefficient values.
 484.595 +   * Since we're encoding a difference, the range limit is twice as much.
 484.596 +   */
 484.597 +  if (nbits > MAX_COEF_BITS+1)
 484.598 +    ERREXIT(cinfo, JERR_BAD_DCT_COEF);
 484.599 +
 484.600 +  /* Count the Huffman symbol for the number of bits */
 484.601 +  dc_counts[nbits]++;
 484.602 +  
 484.603 +  /* Encode the AC coefficients per section F.1.2.2 */
 484.604 +  
 484.605 +  r = 0;			/* r = run length of zeros */
 484.606 +  
 484.607 +  for (k = 1; k < DCTSIZE2; k++) {
 484.608 +    if ((temp = block[jpeg_natural_order[k]]) == 0) {
 484.609 +      r++;
 484.610 +    } else {
 484.611 +      /* if run length > 15, must emit special run-length-16 codes (0xF0) */
 484.612 +      while (r > 15) {
 484.613 +	ac_counts[0xF0]++;
 484.614 +	r -= 16;
 484.615 +      }
 484.616 +      
 484.617 +      /* Find the number of bits needed for the magnitude of the coefficient */
 484.618 +      if (temp < 0)
 484.619 +	temp = -temp;
 484.620 +      
 484.621 +      /* Find the number of bits needed for the magnitude of the coefficient */
 484.622 +      nbits = 1;		/* there must be at least one 1 bit */
 484.623 +      while ((temp >>= 1))
 484.624 +	nbits++;
 484.625 +      /* Check for out-of-range coefficient values */
 484.626 +      if (nbits > MAX_COEF_BITS)
 484.627 +	ERREXIT(cinfo, JERR_BAD_DCT_COEF);
 484.628 +      
 484.629 +      /* Count Huffman symbol for run length / number of bits */
 484.630 +      ac_counts[(r << 4) + nbits]++;
 484.631 +      
 484.632 +      r = 0;
 484.633 +    }
 484.634 +  }
 484.635 +
 484.636 +  /* If the last coef(s) were zero, emit an end-of-block code */
 484.637 +  if (r > 0)
 484.638 +    ac_counts[0]++;
 484.639 +}
 484.640 +
 484.641 +
 484.642 +/*
 484.643 + * Trial-encode one MCU's worth of Huffman-compressed coefficients.
 484.644 + * No data is actually output, so no suspension return is possible.
 484.645 + */
 484.646 +
 484.647 +METHODDEF(boolean)
 484.648 +encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 484.649 +{
 484.650 +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
 484.651 +  int blkn, ci;
 484.652 +  jpeg_component_info * compptr;
 484.653 +
 484.654 +  /* Take care of restart intervals if needed */
 484.655 +  if (cinfo->restart_interval) {
 484.656 +    if (entropy->restarts_to_go == 0) {
 484.657 +      /* Re-initialize DC predictions to 0 */
 484.658 +      for (ci = 0; ci < cinfo->comps_in_scan; ci++)
 484.659 +	entropy->saved.last_dc_val[ci] = 0;
 484.660 +      /* Update restart state */
 484.661 +      entropy->restarts_to_go = cinfo->restart_interval;
 484.662 +    }
 484.663 +    entropy->restarts_to_go--;
 484.664 +  }
 484.665 +
 484.666 +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
 484.667 +    ci = cinfo->MCU_membership[blkn];
 484.668 +    compptr = cinfo->cur_comp_info[ci];
 484.669 +    htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
 484.670 +		    entropy->dc_count_ptrs[compptr->dc_tbl_no],
 484.671 +		    entropy->ac_count_ptrs[compptr->ac_tbl_no]);
 484.672 +    entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0];
 484.673 +  }
 484.674 +
 484.675 +  return TRUE;
 484.676 +}
 484.677 +
 484.678 +
 484.679 +/*
 484.680 + * Generate the best Huffman code table for the given counts, fill htbl.
 484.681 + * Note this is also used by jcphuff.c.
 484.682 + *
 484.683 + * The JPEG standard requires that no symbol be assigned a codeword of all
 484.684 + * one bits (so that padding bits added at the end of a compressed segment
 484.685 + * can't look like a valid code).  Because of the canonical ordering of
 484.686 + * codewords, this just means that there must be an unused slot in the
 484.687 + * longest codeword length category.  Section K.2 of the JPEG spec suggests
 484.688 + * reserving such a slot by pretending that symbol 256 is a valid symbol
 484.689 + * with count 1.  In theory that's not optimal; giving it count zero but
 484.690 + * including it in the symbol set anyway should give a better Huffman code.
 484.691 + * But the theoretically better code actually seems to come out worse in
 484.692 + * practice, because it produces more all-ones bytes (which incur stuffed
 484.693 + * zero bytes in the final file).  In any case the difference is tiny.
 484.694 + *
 484.695 + * The JPEG standard requires Huffman codes to be no more than 16 bits long.
 484.696 + * If some symbols have a very small but nonzero probability, the Huffman tree
 484.697 + * must be adjusted to meet the code length restriction.  We currently use
 484.698 + * the adjustment method suggested in JPEG section K.2.  This method is *not*
 484.699 + * optimal; it may not choose the best possible limited-length code.  But
 484.700 + * typically only very-low-frequency symbols will be given less-than-optimal
 484.701 + * lengths, so the code is almost optimal.  Experimental comparisons against
 484.702 + * an optimal limited-length-code algorithm indicate that the difference is
 484.703 + * microscopic --- usually less than a hundredth of a percent of total size.
 484.704 + * So the extra complexity of an optimal algorithm doesn't seem worthwhile.
 484.705 + */
 484.706 +
 484.707 +GLOBAL(void)
 484.708 +jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
 484.709 +{
 484.710 +#define MAX_CLEN 32		/* assumed maximum initial code length */
 484.711 +  UINT8 bits[MAX_CLEN+1];	/* bits[k] = # of symbols with code length k */
 484.712 +  int codesize[257];		/* codesize[k] = code length of symbol k */
 484.713 +  int others[257];		/* next symbol in current branch of tree */
 484.714 +  int c1, c2;
 484.715 +  int p, i, j;
 484.716 +  long v;
 484.717 +
 484.718 +  /* This algorithm is explained in section K.2 of the JPEG standard */
 484.719 +
 484.720 +  MEMZERO(bits, SIZEOF(bits));
 484.721 +  MEMZERO(codesize, SIZEOF(codesize));
 484.722 +  for (i = 0; i < 257; i++)
 484.723 +    others[i] = -1;		/* init links to empty */
 484.724 +  
 484.725 +  freq[256] = 1;		/* make sure 256 has a nonzero count */
 484.726 +  /* Including the pseudo-symbol 256 in the Huffman procedure guarantees
 484.727 +   * that no real symbol is given code-value of all ones, because 256
 484.728 +   * will be placed last in the largest codeword category.
 484.729 +   */
 484.730 +
 484.731 +  /* Huffman's basic algorithm to assign optimal code lengths to symbols */
 484.732 +
 484.733 +  for (;;) {
 484.734 +    /* Find the smallest nonzero frequency, set c1 = its symbol */
 484.735 +    /* In case of ties, take the larger symbol number */
 484.736 +    c1 = -1;
 484.737 +    v = 1000000000L;
 484.738 +    for (i = 0; i <= 256; i++) {
 484.739 +      if (freq[i] && freq[i] <= v) {
 484.740 +	v = freq[i];
 484.741 +	c1 = i;
 484.742 +      }
 484.743 +    }
 484.744 +
 484.745 +    /* Find the next smallest nonzero frequency, set c2 = its symbol */
 484.746 +    /* In case of ties, take the larger symbol number */
 484.747 +    c2 = -1;
 484.748 +    v = 1000000000L;
 484.749 +    for (i = 0; i <= 256; i++) {
 484.750 +      if (freq[i] && freq[i] <= v && i != c1) {
 484.751 +	v = freq[i];
 484.752 +	c2 = i;
 484.753 +      }
 484.754 +    }
 484.755 +
 484.756 +    /* Done if we've merged everything into one frequency */
 484.757 +    if (c2 < 0)
 484.758 +      break;
 484.759 +    
 484.760 +    /* Else merge the two counts/trees */
 484.761 +    freq[c1] += freq[c2];
 484.762 +    freq[c2] = 0;
 484.763 +
 484.764 +    /* Increment the codesize of everything in c1's tree branch */
 484.765 +    codesize[c1]++;
 484.766 +    while (others[c1] >= 0) {
 484.767 +      c1 = others[c1];
 484.768 +      codesize[c1]++;
 484.769 +    }
 484.770 +    
 484.771 +    others[c1] = c2;		/* chain c2 onto c1's tree branch */
 484.772 +    
 484.773 +    /* Increment the codesize of everything in c2's tree branch */
 484.774 +    codesize[c2]++;
 484.775 +    while (others[c2] >= 0) {
 484.776 +      c2 = others[c2];
 484.777 +      codesize[c2]++;
 484.778 +    }
 484.779 +  }
 484.780 +
 484.781 +  /* Now count the number of symbols of each code length */
 484.782 +  for (i = 0; i <= 256; i++) {
 484.783 +    if (codesize[i]) {
 484.784 +      /* The JPEG standard seems to think that this can't happen, */
 484.785 +      /* but I'm paranoid... */
 484.786 +      if (codesize[i] > MAX_CLEN)
 484.787 +	ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
 484.788 +
 484.789 +      bits[codesize[i]]++;
 484.790 +    }
 484.791 +  }
 484.792 +
 484.793 +  /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
 484.794 +   * Huffman procedure assigned any such lengths, we must adjust the coding.
 484.795 +   * Here is what the JPEG spec says about how this next bit works:
 484.796 +   * Since symbols are paired for the longest Huffman code, the symbols are
 484.797 +   * removed from this length category two at a time.  The prefix for the pair
 484.798 +   * (which is one bit shorter) is allocated to one of the pair; then,
 484.799 +   * skipping the BITS entry for that prefix length, a code word from the next
 484.800 +   * shortest nonzero BITS entry is converted into a prefix for two code words
 484.801 +   * one bit longer.
 484.802 +   */
 484.803 +  
 484.804 +  for (i = MAX_CLEN; i > 16; i--) {
 484.805 +    while (bits[i] > 0) {
 484.806 +      j = i - 2;		/* find length of new prefix to be used */
 484.807 +      while (bits[j] == 0)
 484.808 +	j--;
 484.809 +      
 484.810 +      bits[i] -= 2;		/* remove two symbols */
 484.811 +      bits[i-1]++;		/* one goes in this length */
 484.812 +      bits[j+1] += 2;		/* two new symbols in this length */
 484.813 +      bits[j]--;		/* symbol of this length is now a prefix */
 484.814 +    }
 484.815 +  }
 484.816 +
 484.817 +  /* Remove the count for the pseudo-symbol 256 from the largest codelength */
 484.818 +  while (bits[i] == 0)		/* find largest codelength still in use */
 484.819 +    i--;
 484.820 +  bits[i]--;
 484.821 +  
 484.822 +  /* Return final symbol counts (only for lengths 0..16) */
 484.823 +  MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
 484.824 +  
 484.825 +  /* Return a list of the symbols sorted by code length */
 484.826 +  /* It's not real clear to me why we don't need to consider the codelength
 484.827 +   * changes made above, but the JPEG spec seems to think this works.
 484.828 +   */
 484.829 +  p = 0;
 484.830 +  for (i = 1; i <= MAX_CLEN; i++) {
 484.831 +    for (j = 0; j <= 255; j++) {
 484.832 +      if (codesize[j] == i) {
 484.833 +	htbl->huffval[p] = (UINT8) j;
 484.834 +	p++;
 484.835 +      }
 484.836 +    }
 484.837 +  }
 484.838 +
 484.839 +  /* Set sent_table FALSE so updated table will be written to JPEG file. */
 484.840 +  htbl->sent_table = FALSE;
 484.841 +}
 484.842 +
 484.843 +
 484.844 +/*
 484.845 + * Finish up a statistics-gathering pass and create the new Huffman tables.
 484.846 + */
 484.847 +
 484.848 +METHODDEF(void)
 484.849 +finish_pass_gather (j_compress_ptr cinfo)
 484.850 +{
 484.851 +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
 484.852 +  int ci, dctbl, actbl;
 484.853 +  jpeg_component_info * compptr;
 484.854 +  JHUFF_TBL **htblptr;
 484.855 +  boolean did_dc[NUM_HUFF_TBLS];
 484.856 +  boolean did_ac[NUM_HUFF_TBLS];
 484.857 +
 484.858 +  /* It's important not to apply jpeg_gen_optimal_table more than once
 484.859 +   * per table, because it clobbers the input frequency counts!
 484.860 +   */
 484.861 +  MEMZERO(did_dc, SIZEOF(did_dc));
 484.862 +  MEMZERO(did_ac, SIZEOF(did_ac));
 484.863 +
 484.864 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 484.865 +    compptr = cinfo->cur_comp_info[ci];
 484.866 +    dctbl = compptr->dc_tbl_no;
 484.867 +    actbl = compptr->ac_tbl_no;
 484.868 +    if (! did_dc[dctbl]) {
 484.869 +      htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl];
 484.870 +      if (*htblptr == NULL)
 484.871 +	*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
 484.872 +      jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]);
 484.873 +      did_dc[dctbl] = TRUE;
 484.874 +    }
 484.875 +    if (! did_ac[actbl]) {
 484.876 +      htblptr = & cinfo->ac_huff_tbl_ptrs[actbl];
 484.877 +      if (*htblptr == NULL)
 484.878 +	*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
 484.879 +      jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]);
 484.880 +      did_ac[actbl] = TRUE;
 484.881 +    }
 484.882 +  }
 484.883 +}
 484.884 +
 484.885 +
 484.886 +#endif /* ENTROPY_OPT_SUPPORTED */
 484.887 +
 484.888 +
 484.889 +/*
 484.890 + * Module initialization routine for Huffman entropy encoding.
 484.891 + */
 484.892 +
 484.893 +GLOBAL(void)
 484.894 +jinit_huff_encoder (j_compress_ptr cinfo)
 484.895 +{
 484.896 +  huff_entropy_ptr entropy;
 484.897 +  int i;
 484.898 +
 484.899 +  entropy = (huff_entropy_ptr)
 484.900 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 484.901 +				SIZEOF(huff_entropy_encoder));
 484.902 +  cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
 484.903 +  entropy->pub.start_pass = start_pass_huff;
 484.904 +
 484.905 +  /* Mark tables unallocated */
 484.906 +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
 484.907 +    entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
 484.908 +#ifdef ENTROPY_OPT_SUPPORTED
 484.909 +    entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL;
 484.910 +#endif
 484.911 +  }
 484.912 +}
   485.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   485.2 +++ b/libs/libjpeg/jchuff.h	Sat Feb 01 19:58:19 2014 +0200
   485.3 @@ -0,0 +1,47 @@
   485.4 +/*
   485.5 + * jchuff.h
   485.6 + *
   485.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   485.8 + * This file is part of the Independent JPEG Group's software.
   485.9 + * For conditions of distribution and use, see the accompanying README file.
  485.10 + *
  485.11 + * This file contains declarations for Huffman entropy encoding routines
  485.12 + * that are shared between the sequential encoder (jchuff.c) and the
  485.13 + * progressive encoder (jcphuff.c).  No other modules need to see these.
  485.14 + */
  485.15 +
  485.16 +/* The legal range of a DCT coefficient is
  485.17 + *  -1024 .. +1023  for 8-bit data;
  485.18 + * -16384 .. +16383 for 12-bit data.
  485.19 + * Hence the magnitude should always fit in 10 or 14 bits respectively.
  485.20 + */
  485.21 +
  485.22 +#if BITS_IN_JSAMPLE == 8
  485.23 +#define MAX_COEF_BITS 10
  485.24 +#else
  485.25 +#define MAX_COEF_BITS 14
  485.26 +#endif
  485.27 +
  485.28 +/* Derived data constructed for each Huffman table */
  485.29 +
  485.30 +typedef struct {
  485.31 +  unsigned int ehufco[256];	/* code for each symbol */
  485.32 +  char ehufsi[256];		/* length of code for each symbol */
  485.33 +  /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
  485.34 +} c_derived_tbl;
  485.35 +
  485.36 +/* Short forms of external names for systems with brain-damaged linkers. */
  485.37 +
  485.38 +#ifdef NEED_SHORT_EXTERNAL_NAMES
  485.39 +#define jpeg_make_c_derived_tbl	jMkCDerived
  485.40 +#define jpeg_gen_optimal_table	jGenOptTbl
  485.41 +#endif /* NEED_SHORT_EXTERNAL_NAMES */
  485.42 +
  485.43 +/* Expand a Huffman table definition into the derived format */
  485.44 +EXTERN(void) jpeg_make_c_derived_tbl
  485.45 +	JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
  485.46 +	     c_derived_tbl ** pdtbl));
  485.47 +
  485.48 +/* Generate an optimal table definition given the specified counts */
  485.49 +EXTERN(void) jpeg_gen_optimal_table
  485.50 +	JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
   486.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   486.2 +++ b/libs/libjpeg/jcinit.c	Sat Feb 01 19:58:19 2014 +0200
   486.3 @@ -0,0 +1,72 @@
   486.4 +/*
   486.5 + * jcinit.c
   486.6 + *
   486.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   486.8 + * This file is part of the Independent JPEG Group's software.
   486.9 + * For conditions of distribution and use, see the accompanying README file.
  486.10 + *
  486.11 + * This file contains initialization logic for the JPEG compressor.
  486.12 + * This routine is in charge of selecting the modules to be executed and
  486.13 + * making an initialization call to each one.
  486.14 + *
  486.15 + * Logically, this code belongs in jcmaster.c.  It's split out because
  486.16 + * linking this routine implies linking the entire compression library.
  486.17 + * For a transcoding-only application, we want to be able to use jcmaster.c
  486.18 + * without linking in the whole library.
  486.19 + */
  486.20 +
  486.21 +#define JPEG_INTERNALS
  486.22 +#include "jinclude.h"
  486.23 +#include "jpeglib.h"
  486.24 +
  486.25 +
  486.26 +/*
  486.27 + * Master selection of compression modules.
  486.28 + * This is done once at the start of processing an image.  We determine
  486.29 + * which modules will be used and give them appropriate initialization calls.
  486.30 + */
  486.31 +
  486.32 +GLOBAL(void)
  486.33 +jinit_compress_master (j_compress_ptr cinfo)
  486.34 +{
  486.35 +  /* Initialize master control (includes parameter checking/processing) */
  486.36 +  jinit_c_master_control(cinfo, FALSE /* full compression */);
  486.37 +
  486.38 +  /* Preprocessing */
  486.39 +  if (! cinfo->raw_data_in) {
  486.40 +    jinit_color_converter(cinfo);
  486.41 +    jinit_downsampler(cinfo);
  486.42 +    jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
  486.43 +  }
  486.44 +  /* Forward DCT */
  486.45 +  jinit_forward_dct(cinfo);
  486.46 +  /* Entropy encoding: either Huffman or arithmetic coding. */
  486.47 +  if (cinfo->arith_code) {
  486.48 +    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
  486.49 +  } else {
  486.50 +    if (cinfo->progressive_mode) {
  486.51 +#ifdef C_PROGRESSIVE_SUPPORTED
  486.52 +      jinit_phuff_encoder(cinfo);
  486.53 +#else
  486.54 +      ERREXIT(cinfo, JERR_NOT_COMPILED);
  486.55 +#endif
  486.56 +    } else
  486.57 +      jinit_huff_encoder(cinfo);
  486.58 +  }
  486.59 +
  486.60 +  /* Need a full-image coefficient buffer in any multi-pass mode. */
  486.61 +  jinit_c_coef_controller(cinfo,
  486.62 +		(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
  486.63 +  jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
  486.64 +
  486.65 +  jinit_marker_writer(cinfo);
  486.66 +
  486.67 +  /* We can now tell the memory manager to allocate virtual arrays. */
  486.68 +  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
  486.69 +
  486.70 +  /* Write the datastream header (SOI) immediately.
  486.71 +   * Frame and scan headers are postponed till later.
  486.72 +   * This lets application insert special markers after the SOI.
  486.73 +   */
  486.74 +  (*cinfo->marker->write_file_header) (cinfo);
  486.75 +}
   487.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   487.2 +++ b/libs/libjpeg/jcmainct.c	Sat Feb 01 19:58:19 2014 +0200
   487.3 @@ -0,0 +1,293 @@
   487.4 +/*
   487.5 + * jcmainct.c
   487.6 + *
   487.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   487.8 + * This file is part of the Independent JPEG Group's software.
   487.9 + * For conditions of distribution and use, see the accompanying README file.
  487.10 + *
  487.11 + * This file contains the main buffer controller for compression.
  487.12 + * The main buffer lies between the pre-processor and the JPEG
  487.13 + * compressor proper; it holds downsampled data in the JPEG colorspace.
  487.14 + */
  487.15 +
  487.16 +#define JPEG_INTERNALS
  487.17 +#include "jinclude.h"
  487.18 +#include "jpeglib.h"
  487.19 +
  487.20 +
  487.21 +/* Note: currently, there is no operating mode in which a full-image buffer
  487.22 + * is needed at this step.  If there were, that mode could not be used with
  487.23 + * "raw data" input, since this module is bypassed in that case.  However,
  487.24 + * we've left the code here for possible use in special applications.
  487.25 + */
  487.26 +#undef FULL_MAIN_BUFFER_SUPPORTED
  487.27 +
  487.28 +
  487.29 +/* Private buffer controller object */
  487.30 +
  487.31 +typedef struct {
  487.32 +  struct jpeg_c_main_controller pub; /* public fields */
  487.33 +
  487.34 +  JDIMENSION cur_iMCU_row;	/* number of current iMCU row */
  487.35 +  JDIMENSION rowgroup_ctr;	/* counts row groups received in iMCU row */
  487.36 +  boolean suspended;		/* remember if we suspended output */
  487.37 +  J_BUF_MODE pass_mode;		/* current operating mode */
  487.38 +
  487.39 +  /* If using just a strip buffer, this points to the entire set of buffers
  487.40 +   * (we allocate one for each component).  In the full-image case, this
  487.41 +   * points to the currently accessible strips of the virtual arrays.
  487.42 +   */
  487.43 +  JSAMPARRAY buffer[MAX_COMPONENTS];
  487.44 +
  487.45 +#ifdef FULL_MAIN_BUFFER_SUPPORTED
  487.46 +  /* If using full-image storage, this array holds pointers to virtual-array
  487.47 +   * control blocks for each component.  Unused if not full-image storage.
  487.48 +   */
  487.49 +  jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
  487.50 +#endif
  487.51 +} my_main_controller;
  487.52 +
  487.53 +typedef my_main_controller * my_main_ptr;
  487.54 +
  487.55 +
  487.56 +/* Forward declarations */
  487.57 +METHODDEF(void) process_data_simple_main
  487.58 +	JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
  487.59 +	     JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
  487.60 +#ifdef FULL_MAIN_BUFFER_SUPPORTED
  487.61 +METHODDEF(void) process_data_buffer_main
  487.62 +	JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
  487.63 +	     JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
  487.64 +#endif
  487.65 +
  487.66 +
  487.67 +/*
  487.68 + * Initialize for a processing pass.
  487.69 + */
  487.70 +
  487.71 +METHODDEF(void)
  487.72 +start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
  487.73 +{
  487.74 +  my_main_ptr main = (my_main_ptr) cinfo->main;
  487.75 +
  487.76 +  /* Do nothing in raw-data mode. */
  487.77 +  if (cinfo->raw_data_in)
  487.78 +    return;
  487.79 +
  487.80 +  main->cur_iMCU_row = 0;	/* initialize counters */
  487.81 +  main->rowgroup_ctr = 0;
  487.82 +  main->suspended = FALSE;
  487.83 +  main->pass_mode = pass_mode;	/* save mode for use by process_data */
  487.84 +
  487.85 +  switch (pass_mode) {
  487.86 +  case JBUF_PASS_THRU:
  487.87 +#ifdef FULL_MAIN_BUFFER_SUPPORTED
  487.88 +    if (main->whole_image[0] != NULL)
  487.89 +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  487.90 +#endif
  487.91 +    main->pub.process_data = process_data_simple_main;
  487.92 +    break;
  487.93 +#ifdef FULL_MAIN_BUFFER_SUPPORTED
  487.94 +  case JBUF_SAVE_SOURCE:
  487.95 +  case JBUF_CRANK_DEST:
  487.96 +  case JBUF_SAVE_AND_PASS:
  487.97 +    if (main->whole_image[0] == NULL)
  487.98 +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  487.99 +    main->pub.process_data = process_data_buffer_main;
 487.100 +    break;
 487.101 +#endif
 487.102 +  default:
 487.103 +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 487.104 +    break;
 487.105 +  }
 487.106 +}
 487.107 +
 487.108 +
 487.109 +/*
 487.110 + * Process some data.
 487.111 + * This routine handles the simple pass-through mode,
 487.112 + * where we have only a strip buffer.
 487.113 + */
 487.114 +
 487.115 +METHODDEF(void)
 487.116 +process_data_simple_main (j_compress_ptr cinfo,
 487.117 +			  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
 487.118 +			  JDIMENSION in_rows_avail)
 487.119 +{
 487.120 +  my_main_ptr main = (my_main_ptr) cinfo->main;
 487.121 +
 487.122 +  while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
 487.123 +    /* Read input data if we haven't filled the main buffer yet */
 487.124 +    if (main->rowgroup_ctr < DCTSIZE)
 487.125 +      (*cinfo->prep->pre_process_data) (cinfo,
 487.126 +					input_buf, in_row_ctr, in_rows_avail,
 487.127 +					main->buffer, &main->rowgroup_ctr,
 487.128 +					(JDIMENSION) DCTSIZE);
 487.129 +
 487.130 +    /* If we don't have a full iMCU row buffered, return to application for
 487.131 +     * more data.  Note that preprocessor will always pad to fill the iMCU row
 487.132 +     * at the bottom of the image.
 487.133 +     */
 487.134 +    if (main->rowgroup_ctr != DCTSIZE)
 487.135 +      return;
 487.136 +
 487.137 +    /* Send the completed row to the compressor */
 487.138 +    if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
 487.139 +      /* If compressor did not consume the whole row, then we must need to
 487.140 +       * suspend processing and return to the application.  In this situation
 487.141 +       * we pretend we didn't yet consume the last input row; otherwise, if
 487.142 +       * it happened to be the last row of the image, the application would
 487.143 +       * think we were done.
 487.144 +       */
 487.145 +      if (! main->suspended) {
 487.146 +	(*in_row_ctr)--;
 487.147 +	main->suspended = TRUE;
 487.148 +      }
 487.149 +      return;
 487.150 +    }
 487.151 +    /* We did finish the row.  Undo our little suspension hack if a previous
 487.152 +     * call suspended; then mark the main buffer empty.
 487.153 +     */
 487.154 +    if (main->suspended) {
 487.155 +      (*in_row_ctr)++;
 487.156 +      main->suspended = FALSE;
 487.157 +    }
 487.158 +    main->rowgroup_ctr = 0;
 487.159 +    main->cur_iMCU_row++;
 487.160 +  }
 487.161 +}
 487.162 +
 487.163 +
 487.164 +#ifdef FULL_MAIN_BUFFER_SUPPORTED
 487.165 +
 487.166 +/*
 487.167 + * Process some data.
 487.168 + * This routine handles all of the modes that use a full-size buffer.
 487.169 + */
 487.170 +
 487.171 +METHODDEF(void)
 487.172 +process_data_buffer_main (j_compress_ptr cinfo,
 487.173 +			  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
 487.174 +			  JDIMENSION in_rows_avail)
 487.175 +{
 487.176 +  my_main_ptr main = (my_main_ptr) cinfo->main;
 487.177 +  int ci;
 487.178 +  jpeg_component_info *compptr;
 487.179 +  boolean writing = (main->pass_mode != JBUF_CRANK_DEST);
 487.180 +
 487.181 +  while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
 487.182 +    /* Realign the virtual buffers if at the start of an iMCU row. */
 487.183 +    if (main->rowgroup_ctr == 0) {
 487.184 +      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 487.185 +	   ci++, compptr++) {
 487.186 +	main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
 487.187 +	  ((j_common_ptr) cinfo, main->whole_image[ci],
 487.188 +	   main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
 487.189 +	   (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
 487.190 +      }
 487.191 +      /* In a read pass, pretend we just read some source data. */
 487.192 +      if (! writing) {
 487.193 +	*in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
 487.194 +	main->rowgroup_ctr = DCTSIZE;
 487.195 +      }
 487.196 +    }
 487.197 +
 487.198 +    /* If a write pass, read input data until the current iMCU row is full. */
 487.199 +    /* Note: preprocessor will pad if necessary to fill the last iMCU row. */
 487.200 +    if (writing) {
 487.201 +      (*cinfo->prep->pre_process_data) (cinfo,
 487.202 +					input_buf, in_row_ctr, in_rows_avail,
 487.203 +					main->buffer, &main->rowgroup_ctr,
 487.204 +					(JDIMENSION) DCTSIZE);
 487.205 +      /* Return to application if we need more data to fill the iMCU row. */
 487.206 +      if (main->rowgroup_ctr < DCTSIZE)
 487.207 +	return;
 487.208 +    }
 487.209 +
 487.210 +    /* Emit data, unless this is a sink-only pass. */
 487.211 +    if (main->pass_mode != JBUF_SAVE_SOURCE) {
 487.212 +      if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
 487.213 +	/* If compressor did not consume the whole row, then we must need to
 487.214 +	 * suspend processing and return to the application.  In this situation
 487.215 +	 * we pretend we didn't yet consume the last input row; otherwise, if
 487.216 +	 * it happened to be the last row of the image, the application would
 487.217 +	 * think we were done.
 487.218 +	 */
 487.219 +	if (! main->suspended) {
 487.220 +	  (*in_row_ctr)--;
 487.221 +	  main->suspended = TRUE;
 487.222 +	}
 487.223 +	return;
 487.224 +      }
 487.225 +      /* We did finish the row.  Undo our little suspension hack if a previous
 487.226 +       * call suspended; then mark the main buffer empty.
 487.227 +       */
 487.228 +      if (main->suspended) {
 487.229 +	(*in_row_ctr)++;
 487.230 +	main->suspended = FALSE;
 487.231 +      }
 487.232 +    }
 487.233 +
 487.234 +    /* If get here, we are done with this iMCU row.  Mark buffer empty. */
 487.235 +    main->rowgroup_ctr = 0;
 487.236 +    main->cur_iMCU_row++;
 487.237 +  }
 487.238 +}
 487.239 +
 487.240 +#endif /* FULL_MAIN_BUFFER_SUPPORTED */
 487.241 +
 487.242 +
 487.243 +/*
 487.244 + * Initialize main buffer controller.
 487.245 + */
 487.246 +
 487.247 +GLOBAL(void)
 487.248 +jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
 487.249 +{
 487.250 +  my_main_ptr main;
 487.251 +  int ci;
 487.252 +  jpeg_component_info *compptr;
 487.253 +
 487.254 +  main = (my_main_ptr)
 487.255 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 487.256 +				SIZEOF(my_main_controller));
 487.257 +  cinfo->main = (struct jpeg_c_main_controller *) main;
 487.258 +  main->pub.start_pass = start_pass_main;
 487.259 +
 487.260 +  /* We don't need to create a buffer in raw-data mode. */
 487.261 +  if (cinfo->raw_data_in)
 487.262 +    return;
 487.263 +
 487.264 +  /* Create the buffer.  It holds downsampled data, so each component
 487.265 +   * may be of a different size.
 487.266 +   */
 487.267 +  if (need_full_buffer) {
 487.268 +#ifdef FULL_MAIN_BUFFER_SUPPORTED
 487.269 +    /* Allocate a full-image virtual array for each component */
 487.270 +    /* Note we pad the bottom to a multiple of the iMCU height */
 487.271 +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 487.272 +	 ci++, compptr++) {
 487.273 +      main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
 487.274 +	((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
 487.275 +	 compptr->width_in_blocks * DCTSIZE,
 487.276 +	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
 487.277 +				(long) compptr->v_samp_factor) * DCTSIZE,
 487.278 +	 (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
 487.279 +    }
 487.280 +#else
 487.281 +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 487.282 +#endif
 487.283 +  } else {
 487.284 +#ifdef FULL_MAIN_BUFFER_SUPPORTED
 487.285 +    main->whole_image[0] = NULL; /* flag for no virtual arrays */
 487.286 +#endif
 487.287 +    /* Allocate a strip buffer for each component */
 487.288 +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 487.289 +	 ci++, compptr++) {
 487.290 +      main->buffer[ci] = (*cinfo->mem->alloc_sarray)
 487.291 +	((j_common_ptr) cinfo, JPOOL_IMAGE,
 487.292 +	 compptr->width_in_blocks * DCTSIZE,
 487.293 +	 (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
 487.294 +    }
 487.295 +  }
 487.296 +}
   488.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   488.2 +++ b/libs/libjpeg/jcmarker.c	Sat Feb 01 19:58:19 2014 +0200
   488.3 @@ -0,0 +1,664 @@
   488.4 +/*
   488.5 + * jcmarker.c
   488.6 + *
   488.7 + * Copyright (C) 1991-1998, Thomas G. Lane.
   488.8 + * This file is part of the Independent JPEG Group's software.
   488.9 + * For conditions of distribution and use, see the accompanying README file.
  488.10 + *
  488.11 + * This file contains routines to write JPEG datastream markers.
  488.12 + */
  488.13 +
  488.14 +#define JPEG_INTERNALS
  488.15 +#include "jinclude.h"
  488.16 +#include "jpeglib.h"
  488.17 +
  488.18 +
  488.19 +typedef enum {			/* JPEG marker codes */
  488.20 +  M_SOF0  = 0xc0,
  488.21 +  M_SOF1  = 0xc1,
  488.22 +  M_SOF2  = 0xc2,
  488.23 +  M_SOF3  = 0xc3,
  488.24 +  
  488.25 +  M_SOF5  = 0xc5,
  488.26 +  M_SOF6  = 0xc6,
  488.27 +  M_SOF7  = 0xc7,
  488.28 +  
  488.29 +  M_JPG   = 0xc8,
  488.30 +  M_SOF9  = 0xc9,
  488.31 +  M_SOF10 = 0xca,
  488.32 +  M_SOF11 = 0xcb,
  488.33 +  
  488.34 +  M_SOF13 = 0xcd,
  488.35 +  M_SOF14 = 0xce,
  488.36 +  M_SOF15 = 0xcf,
  488.37 +  
  488.38 +  M_DHT   = 0xc4,
  488.39 +  
  488.40 +  M_DAC   = 0xcc,
  488.41 +  
  488.42 +  M_RST0  = 0xd0,
  488.43 +  M_RST1  = 0xd1,
  488.44 +  M_RST2  = 0xd2,
  488.45 +  M_RST3  = 0xd3,
  488.46 +  M_RST4  = 0xd4,
  488.47 +  M_RST5  = 0xd5,
  488.48 +  M_RST6  = 0xd6,
  488.49 +  M_RST7  = 0xd7,
  488.50 +  
  488.51 +  M_SOI   = 0xd8,
  488.52 +  M_EOI   = 0xd9,
  488.53 +  M_SOS   = 0xda,
  488.54 +  M_DQT   = 0xdb,
  488.55 +  M_DNL   = 0xdc,
  488.56 +  M_DRI   = 0xdd,
  488.57 +  M_DHP   = 0xde,
  488.58 +  M_EXP   = 0xdf,
  488.59 +  
  488.60 +  M_APP0  = 0xe0,
  488.61 +  M_APP1  = 0xe1,
  488.62 +  M_APP2  = 0xe2,
  488.63 +  M_APP3  = 0xe3,
  488.64 +  M_APP4  = 0xe4,
  488.65 +  M_APP5  = 0xe5,
  488.66 +  M_APP6  = 0xe6,
  488.67 +  M_APP7  = 0xe7,
  488.68 +  M_APP8  = 0xe8,
  488.69 +  M_APP9  = 0xe9,
  488.70 +  M_APP10 = 0xea,
  488.71 +  M_APP11 = 0xeb,
  488.72 +  M_APP12 = 0xec,
  488.73 +  M_APP13 = 0xed,
  488.74 +  M_APP14 = 0xee,
  488.75 +  M_APP15 = 0xef,
  488.76 +  
  488.77 +  M_JPG0  = 0xf0,
  488.78 +  M_JPG13 = 0xfd,
  488.79 +  M_COM   = 0xfe,
  488.80 +  
  488.81 +  M_TEM   = 0x01,
  488.82 +  
  488.83 +  M_ERROR = 0x100
  488.84 +} JPEG_MARKER;
  488.85 +
  488.86 +
  488.87 +/* Private state */
  488.88 +
  488.89 +typedef struct {
  488.90 +  struct jpeg_marker_writer pub; /* public fields */
  488.91 +
  488.92 +  unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */
  488.93 +} my_marker_writer;
  488.94 +
  488.95 +typedef my_marker_writer * my_marker_ptr;
  488.96 +
  488.97 +
  488.98 +/*
  488.99 + * Basic output routines.
 488.100 + *
 488.101 + * Note that we do not support suspension while writing a marker.
 488.102 + * Therefore, an application using suspension must ensure that there is
 488.103 + * enough buffer space for the initial markers (typ. 600-700 bytes) before
 488.104 + * calling jpeg_start_compress, and enough space to write the trailing EOI
 488.105 + * (a few bytes) before calling jpeg_finish_compress.  Multipass compression
 488.106 + * modes are not supported at all with suspension, so those two are the only
 488.107 + * points where markers will be written.
 488.108 + */
 488.109 +
 488.110 +LOCAL(void)
 488.111 +emit_byte (j_compress_ptr cinfo, int val)
 488.112 +/* Emit a byte */
 488.113 +{
 488.114 +  struct jpeg_destination_mgr * dest = cinfo->dest;
 488.115 +
 488.116 +  *(dest->next_output_byte)++ = (JOCTET) val;
 488.117 +  if (--dest->free_in_buffer == 0) {
 488.118 +    if (! (*dest->empty_output_buffer) (cinfo))
 488.119 +      ERREXIT(cinfo, JERR_CANT_SUSPEND);
 488.120 +  }
 488.121 +}
 488.122 +
 488.123 +
 488.124 +LOCAL(void)
 488.125 +emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
 488.126 +/* Emit a marker code */
 488.127 +{
 488.128 +  emit_byte(cinfo, 0xFF);
 488.129 +  emit_byte(cinfo, (int) mark);
 488.130 +}
 488.131 +
 488.132 +
 488.133 +LOCAL(void)
 488.134 +emit_2bytes (j_compress_ptr cinfo, int value)
 488.135 +/* Emit a 2-byte integer; these are always MSB first in JPEG files */
 488.136 +{
 488.137 +  emit_byte(cinfo, (value >> 8) & 0xFF);
 488.138 +  emit_byte(cinfo, value & 0xFF);
 488.139 +}
 488.140 +
 488.141 +
 488.142 +/*
 488.143 + * Routines to write specific marker types.
 488.144 + */
 488.145 +
 488.146 +LOCAL(int)
 488.147 +emit_dqt (j_compress_ptr cinfo, int index)
 488.148 +/* Emit a DQT marker */
 488.149 +/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
 488.150 +{
 488.151 +  JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index];
 488.152 +  int prec;
 488.153 +  int i;
 488.154 +
 488.155 +  if (qtbl == NULL)
 488.156 +    ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
 488.157 +
 488.158 +  prec = 0;
 488.159 +  for (i = 0; i < DCTSIZE2; i++) {
 488.160 +    if (qtbl->quantval[i] > 255)
 488.161 +      prec = 1;
 488.162 +  }
 488.163 +
 488.164 +  if (! qtbl->sent_table) {
 488.165 +    emit_marker(cinfo, M_DQT);
 488.166 +
 488.167 +    emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
 488.168 +
 488.169 +    emit_byte(cinfo, index + (prec<<4));
 488.170 +
 488.171 +    for (i = 0; i < DCTSIZE2; i++) {
 488.172 +      /* The table entries must be emitted in zigzag order. */
 488.173 +      unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
 488.174 +      if (prec)
 488.175 +	emit_byte(cinfo, (int) (qval >> 8));
 488.176 +      emit_byte(cinfo, (int) (qval & 0xFF));
 488.177 +    }
 488.178 +
 488.179 +    qtbl->sent_table = TRUE;
 488.180 +  }
 488.181 +
 488.182 +  return prec;
 488.183 +}
 488.184 +
 488.185 +
 488.186 +LOCAL(void)
 488.187 +emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
 488.188 +/* Emit a DHT marker */
 488.189 +{
 488.190 +  JHUFF_TBL * htbl;
 488.191 +  int length, i;
 488.192 +  
 488.193 +  if (is_ac) {
 488.194 +    htbl = cinfo->ac_huff_tbl_ptrs[index];
 488.195 +    index += 0x10;		/* output index has AC bit set */
 488.196 +  } else {
 488.197 +    htbl = cinfo->dc_huff_tbl_ptrs[index];
 488.198 +  }
 488.199 +
 488.200 +  if (htbl == NULL)
 488.201 +    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index);
 488.202 +  
 488.203 +  if (! htbl->sent_table) {
 488.204 +    emit_marker(cinfo, M_DHT);
 488.205 +    
 488.206 +    length = 0;
 488.207 +    for (i = 1; i <= 16; i++)
 488.208 +      length += htbl->bits[i];
 488.209 +    
 488.210 +    emit_2bytes(cinfo, length + 2 + 1 + 16);
 488.211 +    emit_byte(cinfo, index);
 488.212 +    
 488.213 +    for (i = 1; i <= 16; i++)
 488.214 +      emit_byte(cinfo, htbl->bits[i]);
 488.215 +    
 488.216 +    for (i = 0; i < length; i++)
 488.217 +      emit_byte(cinfo, htbl->huffval[i]);
 488.218 +    
 488.219 +    htbl->sent_table = TRUE;
 488.220 +  }
 488.221 +}
 488.222 +
 488.223 +
 488.224 +LOCAL(void)
 488.225 +emit_dac (j_compress_ptr cinfo)
 488.226 +/* Emit a DAC marker */
 488.227 +/* Since the useful info is so small, we want to emit all the tables in */
 488.228 +/* one DAC marker.  Therefore this routine does its own scan of the table. */
 488.229 +{
 488.230 +#ifdef C_ARITH_CODING_SUPPORTED
 488.231 +  char dc_in_use[NUM_ARITH_TBLS];
 488.232 +  char ac_in_use[NUM_ARITH_TBLS];
 488.233 +  int length, i;
 488.234 +  jpeg_component_info *compptr;
 488.235 +  
 488.236 +  for (i = 0; i < NUM_ARITH_TBLS; i++)
 488.237 +    dc_in_use[i] = ac_in_use[i] = 0;
 488.238 +  
 488.239 +  for (i = 0; i < cinfo->comps_in_scan; i++) {
 488.240 +    compptr = cinfo->cur_comp_info[i];
 488.241 +    dc_in_use[compptr->dc_tbl_no] = 1;
 488.242 +    ac_in_use[compptr->ac_tbl_no] = 1;
 488.243 +  }
 488.244 +  
 488.245 +  length = 0;
 488.246 +  for (i = 0; i < NUM_ARITH_TBLS; i++)
 488.247 +    length += dc_in_use[i] + ac_in_use[i];
 488.248 +  
 488.249 +  emit_marker(cinfo, M_DAC);
 488.250 +  
 488.251 +  emit_2bytes(cinfo, length*2 + 2);
 488.252 +  
 488.253 +  for (i = 0; i < NUM_ARITH_TBLS; i++) {
 488.254 +    if (dc_in_use[i]) {
 488.255 +      emit_byte(cinfo, i);
 488.256 +      emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
 488.257 +    }
 488.258 +    if (ac_in_use[i]) {
 488.259 +      emit_byte(cinfo, i + 0x10);
 488.260 +      emit_byte(cinfo, cinfo->arith_ac_K[i]);
 488.261 +    }
 488.262 +  }
 488.263 +#endif /* C_ARITH_CODING_SUPPORTED */
 488.264 +}
 488.265 +
 488.266 +
 488.267 +LOCAL(void)
 488.268 +emit_dri (j_compress_ptr cinfo)
 488.269 +/* Emit a DRI marker */
 488.270 +{
 488.271 +  emit_marker(cinfo, M_DRI);
 488.272 +  
 488.273 +  emit_2bytes(cinfo, 4);	/* fixed length */
 488.274 +
 488.275 +  emit_2bytes(cinfo, (int) cinfo->restart_interval);
 488.276 +}
 488.277 +
 488.278 +
 488.279 +LOCAL(void)
 488.280 +emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
 488.281 +/* Emit a SOF marker */
 488.282 +{
 488.283 +  int ci;
 488.284 +  jpeg_component_info *compptr;
 488.285 +  
 488.286 +  emit_marker(cinfo, code);
 488.287 +  
 488.288 +  emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
 488.289 +
 488.290 +  /* Make sure image isn't bigger than SOF field can handle */
 488.291 +  if ((long) cinfo->image_height > 65535L ||
 488.292 +      (long) cinfo->image_width > 65535L)
 488.293 +    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
 488.294 +
 488.295 +  emit_byte(cinfo, cinfo->data_precision);
 488.296 +  emit_2bytes(cinfo, (int) cinfo->image_height);
 488.297 +  emit_2bytes(cinfo, (int) cinfo->image_width);
 488.298 +
 488.299 +  emit_byte(cinfo, cinfo->num_components);
 488.300 +
 488.301 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 488.302 +       ci++, compptr++) {
 488.303 +    emit_byte(cinfo, compptr->component_id);
 488.304 +    emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor);
 488.305 +    emit_byte(cinfo, compptr->quant_tbl_no);
 488.306 +  }
 488.307 +}
 488.308 +
 488.309 +
 488.310 +LOCAL(void)
 488.311 +emit_sos (j_compress_ptr cinfo)
 488.312 +/* Emit a SOS marker */
 488.313 +{
 488.314 +  int i, td, ta;
 488.315 +  jpeg_component_info *compptr;
 488.316 +  
 488.317 +  emit_marker(cinfo, M_SOS);
 488.318 +  
 488.319 +  emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
 488.320 +  
 488.321 +  emit_byte(cinfo, cinfo->comps_in_scan);
 488.322 +  
 488.323 +  for (i = 0; i < cinfo->comps_in_scan; i++) {
 488.324 +    compptr = cinfo->cur_comp_info[i];
 488.325 +    emit_byte(cinfo, compptr->component_id);
 488.326 +    td = compptr->dc_tbl_no;
 488.327 +    ta = compptr->ac_tbl_no;
 488.328 +    if (cinfo->progressive_mode) {
 488.329 +      /* Progressive mode: only DC or only AC tables are used in one scan;
 488.330 +       * furthermore, Huffman coding of DC refinement uses no table at all.
 488.331 +       * We emit 0 for unused field(s); this is recommended by the P&M text
 488.332 +       * but does not seem to be specified in the standard.
 488.333 +       */
 488.334 +      if (cinfo->Ss == 0) {
 488.335 +	ta = 0;			/* DC scan */
 488.336 +	if (cinfo->Ah != 0 && !cinfo->arith_code)
 488.337 +	  td = 0;		/* no DC table either */
 488.338 +      } else {
 488.339 +	td = 0;			/* AC scan */
 488.340 +      }
 488.341 +    }
 488.342 +    emit_byte(cinfo, (td << 4) + ta);
 488.343 +  }
 488.344 +
 488.345 +  emit_byte(cinfo, cinfo->Ss);
 488.346 +  emit_byte(cinfo, cinfo->Se);
 488.347 +  emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);
 488.348 +}
 488.349 +
 488.350 +
 488.351 +LOCAL(void)
 488.352 +emit_jfif_app0 (j_compress_ptr cinfo)
 488.353 +/* Emit a JFIF-compliant APP0 marker */
 488.354 +{
 488.355 +  /*
 488.356 +   * Length of APP0 block	(2 bytes)
 488.357 +   * Block ID			(4 bytes - ASCII "JFIF")
 488.358 +   * Zero byte			(1 byte to terminate the ID string)
 488.359 +   * Version Major, Minor	(2 bytes - major first)
 488.360 +   * Units			(1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
 488.361 +   * Xdpu			(2 bytes - dots per unit horizontal)
 488.362 +   * Ydpu			(2 bytes - dots per unit vertical)
 488.363 +   * Thumbnail X size		(1 byte)
 488.364 +   * Thumbnail Y size		(1 byte)
 488.365 +   */
 488.366 +  
 488.367 +  emit_marker(cinfo, M_APP0);
 488.368 +  
 488.369 +  emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
 488.370 +
 488.371 +  emit_byte(cinfo, 0x4A);	/* Identifier: ASCII "JFIF" */
 488.372 +  emit_byte(cinfo, 0x46);
 488.373 +  emit_byte(cinfo, 0x49);
 488.374 +  emit_byte(cinfo, 0x46);
 488.375 +  emit_byte(cinfo, 0);
 488.376 +  emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
 488.377 +  emit_byte(cinfo, cinfo->JFIF_minor_version);
 488.378 +  emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
 488.379 +  emit_2bytes(cinfo, (int) cinfo->X_density);
 488.380 +  emit_2bytes(cinfo, (int) cinfo->Y_density);
 488.381 +  emit_byte(cinfo, 0);		/* No thumbnail image */
 488.382 +  emit_byte(cinfo, 0);
 488.383 +}
 488.384 +
 488.385 +
 488.386 +LOCAL(void)
 488.387 +emit_adobe_app14 (j_compress_ptr cinfo)
 488.388 +/* Emit an Adobe APP14 marker */
 488.389 +{
 488.390 +  /*
 488.391 +   * Length of APP14 block	(2 bytes)
 488.392 +   * Block ID			(5 bytes - ASCII "Adobe")
 488.393 +   * Version Number		(2 bytes - currently 100)
 488.394 +   * Flags0			(2 bytes - currently 0)
 488.395 +   * Flags1			(2 bytes - currently 0)
 488.396 +   * Color transform		(1 byte)
 488.397 +   *
 488.398 +   * Although Adobe TN 5116 mentions Version = 101, all the Adobe files
 488.399 +   * now in circulation seem to use Version = 100, so that's what we write.
 488.400 +   *
 488.401 +   * We write the color transform byte as 1 if the JPEG color space is
 488.402 +   * YCbCr, 2 if it's YCCK, 0 otherwise.  Adobe's definition has to do with
 488.403 +   * whether the encoder performed a transformation, which is pretty useless.
 488.404 +   */
 488.405 +  
 488.406 +  emit_marker(cinfo, M_APP14);
 488.407 +  
 488.408 +  emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */
 488.409 +
 488.410 +  emit_byte(cinfo, 0x41);	/* Identifier: ASCII "Adobe" */
 488.411 +  emit_byte(cinfo, 0x64);
 488.412 +  emit_byte(cinfo, 0x6F);
 488.413 +  emit_byte(cinfo, 0x62);
 488.414 +  emit_byte(cinfo, 0x65);
 488.415 +  emit_2bytes(cinfo, 100);	/* Version */
 488.416 +  emit_2bytes(cinfo, 0);	/* Flags0 */
 488.417 +  emit_2bytes(cinfo, 0);	/* Flags1 */
 488.418 +  switch (cinfo->jpeg_color_space) {
 488.419 +  case JCS_YCbCr:
 488.420 +    emit_byte(cinfo, 1);	/* Color transform = 1 */
 488.421 +    break;
 488.422 +  case JCS_YCCK:
 488.423 +    emit_byte(cinfo, 2);	/* Color transform = 2 */
 488.424 +    break;
 488.425 +  default:
 488.426 +    emit_byte(cinfo, 0);	/* Color transform = 0 */
 488.427 +    break;
 488.428 +  }
 488.429 +}
 488.430 +
 488.431 +
 488.432 +/*
 488.433 + * These routines allow writing an arbitrary marker with parameters.
 488.434 + * The only intended use is to emit COM or APPn markers after calling
 488.435 + * write_file_header and before calling write_frame_header.
 488.436 + * Other uses are not guaranteed to produce desirable results.
 488.437 + * Counting the parameter bytes properly is the caller's responsibility.
 488.438 + */
 488.439 +
 488.440 +METHODDEF(void)
 488.441 +write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
 488.442 +/* Emit an arbitrary marker header */
 488.443 +{
 488.444 +  if (datalen > (unsigned int) 65533)		/* safety check */
 488.445 +    ERREXIT(cinfo, JERR_BAD_LENGTH);
 488.446 +
 488.447 +  emit_marker(cinfo, (JPEG_MARKER) marker);
 488.448 +
 488.449 +  emit_2bytes(cinfo, (int) (datalen + 2));	/* total length */
 488.450 +}
 488.451 +
 488.452 +METHODDEF(void)
 488.453 +write_marker_byte (j_compress_ptr cinfo, int val)
 488.454 +/* Emit one byte of marker parameters following write_marker_header */
 488.455 +{
 488.456 +  emit_byte(cinfo, val);
 488.457 +}
 488.458 +
 488.459 +
 488.460 +/*
 488.461 + * Write datastream header.
 488.462 + * This consists of an SOI and optional APPn markers.
 488.463 + * We recommend use of the JFIF marker, but not the Adobe marker,
 488.464 + * when using YCbCr or grayscale data.  The JFIF marker should NOT
 488.465 + * be used for any other JPEG colorspace.  The Adobe marker is helpful
 488.466 + * to distinguish RGB, CMYK, and YCCK colorspaces.
 488.467 + * Note that an application can write additional header markers after
 488.468 + * jpeg_start_compress returns.
 488.469 + */
 488.470 +
 488.471 +METHODDEF(void)
 488.472 +write_file_header (j_compress_ptr cinfo)
 488.473 +{
 488.474 +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
 488.475 +
 488.476 +  emit_marker(cinfo, M_SOI);	/* first the SOI */
 488.477 +
 488.478 +  /* SOI is defined to reset restart interval to 0 */
 488.479 +  marker->last_restart_interval = 0;
 488.480 +
 488.481 +  if (cinfo->write_JFIF_header)	/* next an optional JFIF APP0 */
 488.482 +    emit_jfif_app0(cinfo);
 488.483 +  if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
 488.484 +    emit_adobe_app14(cinfo);
 488.485 +}
 488.486 +
 488.487 +
 488.488 +/*
 488.489 + * Write frame header.
 488.490 + * This consists of DQT and SOFn markers.
 488.491 + * Note that we do not emit the SOF until we have emitted the DQT(s).
 488.492 + * This avoids compatibility problems with incorrect implementations that
 488.493 + * try to error-check the quant table numbers as soon as they see the SOF.
 488.494 + */
 488.495 +
 488.496 +METHODDEF(void)
 488.497 +write_frame_header (j_compress_ptr cinfo)
 488.498 +{
 488.499 +  int ci, prec;
 488.500 +  boolean is_baseline;
 488.501 +  jpeg_component_info *compptr;
 488.502 +  
 488.503 +  /* Emit DQT for each quantization table.
 488.504 +   * Note that emit_dqt() suppresses any duplicate tables.
 488.505 +   */
 488.506 +  prec = 0;
 488.507 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 488.508 +       ci++, compptr++) {
 488.509 +    prec += emit_dqt(cinfo, compptr->quant_tbl_no);
 488.510 +  }
 488.511 +  /* now prec is nonzero iff there are any 16-bit quant tables. */
 488.512 +
 488.513 +  /* Check for a non-baseline specification.
 488.514 +   * Note we assume that Huffman table numbers won't be changed later.
 488.515 +   */
 488.516 +  if (cinfo->arith_code || cinfo->progressive_mode ||
 488.517 +      cinfo->data_precision != 8) {
 488.518 +    is_baseline = FALSE;
 488.519 +  } else {
 488.520 +    is_baseline = TRUE;
 488.521 +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 488.522 +	 ci++, compptr++) {
 488.523 +      if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)
 488.524 +	is_baseline = FALSE;
 488.525 +    }
 488.526 +    if (prec && is_baseline) {
 488.527 +      is_baseline = FALSE;
 488.528 +      /* If it's baseline except for quantizer size, warn the user */
 488.529 +      TRACEMS(cinfo, 0, JTRC_16BIT_TABLES);
 488.530 +    }
 488.531 +  }
 488.532 +
 488.533 +  /* Emit the proper SOF marker */
 488.534 +  if (cinfo->arith_code) {
 488.535 +    emit_sof(cinfo, M_SOF9);	/* SOF code for arithmetic coding */
 488.536 +  } else {
 488.537 +    if (cinfo->progressive_mode)
 488.538 +      emit_sof(cinfo, M_SOF2);	/* SOF code for progressive Huffman */
 488.539 +    else if (is_baseline)
 488.540 +      emit_sof(cinfo, M_SOF0);	/* SOF code for baseline implementation */
 488.541 +    else
 488.542 +      emit_sof(cinfo, M_SOF1);	/* SOF code for non-baseline Huffman file */
 488.543 +  }
 488.544 +}
 488.545 +
 488.546 +
 488.547 +/*
 488.548 + * Write scan header.
 488.549 + * This consists of DHT or DAC markers, optional DRI, and SOS.
 488.550 + * Compressed data will be written following the SOS.
 488.551 + */
 488.552 +
 488.553 +METHODDEF(void)
 488.554 +write_scan_header (j_compress_ptr cinfo)
 488.555 +{
 488.556 +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
 488.557 +  int i;
 488.558 +  jpeg_component_info *compptr;
 488.559 +
 488.560 +  if (cinfo->arith_code) {
 488.561 +    /* Emit arith conditioning info.  We may have some duplication
 488.562 +     * if the file has multiple scans, but it's so small it's hardly
 488.563 +     * worth worrying about.
 488.564 +     */
 488.565 +    emit_dac(cinfo);
 488.566 +  } else {
 488.567 +    /* Emit Huffman tables.
 488.568 +     * Note that emit_dht() suppresses any duplicate tables.
 488.569 +     */
 488.570 +    for (i = 0; i < cinfo->comps_in_scan; i++) {
 488.571 +      compptr = cinfo->cur_comp_info[i];
 488.572 +      if (cinfo->progressive_mode) {
 488.573 +	/* Progressive mode: only DC or only AC tables are used in one scan */
 488.574 +	if (cinfo->Ss == 0) {
 488.575 +	  if (cinfo->Ah == 0)	/* DC needs no table for refinement scan */
 488.576 +	    emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
 488.577 +	} else {
 488.578 +	  emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
 488.579 +	}
 488.580 +      } else {
 488.581 +	/* Sequential mode: need both DC and AC tables */
 488.582 +	emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
 488.583 +	emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
 488.584 +      }
 488.585 +    }
 488.586 +  }
 488.587 +
 488.588 +  /* Emit DRI if required --- note that DRI value could change for each scan.
 488.589 +   * We avoid wasting space with unnecessary DRIs, however.
 488.590 +   */
 488.591 +  if (cinfo->restart_interval != marker->last_restart_interval) {
 488.592 +    emit_dri(cinfo);
 488.593 +    marker->last_restart_interval = cinfo->restart_interval;
 488.594 +  }
 488.595 +
 488.596 +  emit_sos(cinfo);
 488.597 +}
 488.598 +
 488.599 +
 488.600 +/*
 488.601 + * Write datastream trailer.
 488.602 + */
 488.603 +
 488.604 +METHODDEF(void)
 488.605 +write_file_trailer (j_compress_ptr cinfo)
 488.606 +{
 488.607 +  emit_marker(cinfo, M_EOI);
 488.608 +}
 488.609 +
 488.610 +
 488.611 +/*
 488.612 + * Write an abbreviated table-specification datastream.
 488.613 + * This consists of SOI, DQT and DHT tables, and EOI.
 488.614 + * Any table that is defined and not marked sent_table = TRUE will be
 488.615 + * emitted.  Note that all tables will be marked sent_table = TRUE at exit.
 488.616 + */
 488.617 +
 488.618 +METHODDEF(void)
 488.619 +write_tables_only (j_compress_ptr cinfo)
 488.620 +{
 488.621 +  int i;
 488.622 +
 488.623 +  emit_marker(cinfo, M_SOI);
 488.624 +
 488.625 +  for (i = 0; i < NUM_QUANT_TBLS; i++) {
 488.626 +    if (cinfo->quant_tbl_ptrs[i] != NULL)
 488.627 +      (void) emit_dqt(cinfo, i);
 488.628 +  }
 488.629 +
 488.630 +  if (! cinfo->arith_code) {
 488.631 +    for (i = 0; i < NUM_HUFF_TBLS; i++) {
 488.632 +      if (cinfo->dc_huff_tbl_ptrs[i] != NULL)
 488.633 +	emit_dht(cinfo, i, FALSE);
 488.634 +      if (cinfo->ac_huff_tbl_ptrs[i] != NULL)
 488.635 +	emit_dht(cinfo, i, TRUE);
 488.636 +    }
 488.637 +  }
 488.638 +
 488.639 +  emit_marker(cinfo, M_EOI);
 488.640 +}
 488.641 +
 488.642 +
 488.643 +/*
 488.644 + * Initialize the marker writer module.
 488.645 + */
 488.646 +
 488.647 +GLOBAL(void)
 488.648 +jinit_marker_writer (j_compress_ptr cinfo)
 488.649 +{
 488.650 +  my_marker_ptr marker;
 488.651 +
 488.652 +  /* Create the subobject */
 488.653 +  marker = (my_marker_ptr)
 488.654 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 488.655 +				SIZEOF(my_marker_writer));
 488.656 +  cinfo->marker = (struct jpeg_marker_writer *) marker;
 488.657 +  /* Initialize method pointers */
 488.658 +  marker->pub.write_file_header = write_file_header;
 488.659 +  marker->pub.write_frame_header = write_frame_header;
 488.660 +  marker->pub.write_scan_header = write_scan_header;
 488.661 +  marker->pub.write_file_trailer = write_file_trailer;
 488.662 +  marker->pub.write_tables_only = write_tables_only;
 488.663 +  marker->pub.write_marker_header = write_marker_header;
 488.664 +  marker->pub.write_marker_byte = write_marker_byte;
 488.665 +  /* Initialize private state */
 488.666 +  marker->last_restart_interval = 0;
 488.667 +}
   489.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   489.2 +++ b/libs/libjpeg/jcmaster.c	Sat Feb 01 19:58:19 2014 +0200
   489.3 @@ -0,0 +1,590 @@
   489.4 +/*
   489.5 + * jcmaster.c
   489.6 + *
   489.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   489.8 + * This file is part of the Independent JPEG Group's software.
   489.9 + * For conditions of distribution and use, see the accompanying README file.
  489.10 + *
  489.11 + * This file contains master control logic for the JPEG compressor.
  489.12 + * These routines are concerned with parameter validation, initial setup,
  489.13 + * and inter-pass control (determining the number of passes and the work 
  489.14 + * to be done in each pass).
  489.15 + */
  489.16 +
  489.17 +#define JPEG_INTERNALS
  489.18 +#include "jinclude.h"
  489.19 +#include "jpeglib.h"
  489.20 +
  489.21 +
  489.22 +/* Private state */
  489.23 +
  489.24 +typedef enum {
  489.25 +	main_pass,		/* input data, also do first output step */
  489.26 +	huff_opt_pass,		/* Huffman code optimization pass */
  489.27 +	output_pass		/* data output pass */
  489.28 +} c_pass_type;
  489.29 +
  489.30 +typedef struct {
  489.31 +  struct jpeg_comp_master pub;	/* public fields */
  489.32 +
  489.33 +  c_pass_type pass_type;	/* the type of the current pass */
  489.34 +
  489.35 +  int pass_number;		/* # of passes completed */
  489.36 +  int total_passes;		/* total # of passes needed */
  489.37 +
  489.38 +  int scan_number;		/* current index in scan_info[] */
  489.39 +} my_comp_master;
  489.40 +
  489.41 +typedef my_comp_master * my_master_ptr;
  489.42 +
  489.43 +
  489.44 +/*
  489.45 + * Support routines that do various essential calculations.
  489.46 + */
  489.47 +
  489.48 +LOCAL(void)
  489.49 +initial_setup (j_compress_ptr cinfo)
  489.50 +/* Do computations that are needed before master selection phase */
  489.51 +{
  489.52 +  int ci;
  489.53 +  jpeg_component_info *compptr;
  489.54 +  long samplesperrow;
  489.55 +  JDIMENSION jd_samplesperrow;
  489.56 +
  489.57 +  /* Sanity check on image dimensions */
  489.58 +  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
  489.59 +      || cinfo->num_components <= 0 || cinfo->input_components <= 0)
  489.60 +    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
  489.61 +
  489.62 +  /* Make sure image isn't bigger than I can handle */
  489.63 +  if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
  489.64 +      (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
  489.65 +    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
  489.66 +
  489.67 +  /* Width of an input scanline must be representable as JDIMENSION. */
  489.68 +  samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components;
  489.69 +  jd_samplesperrow = (JDIMENSION) samplesperrow;
  489.70 +  if ((long) jd_samplesperrow != samplesperrow)
  489.71 +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
  489.72 +
  489.73 +  /* For now, precision must match compiled-in value... */
  489.74 +  if (cinfo->data_precision != BITS_IN_JSAMPLE)
  489.75 +    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
  489.76 +
  489.77 +  /* Check that number of components won't exceed internal array sizes */
  489.78 +  if (cinfo->num_components > MAX_COMPONENTS)
  489.79 +    ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
  489.80 +	     MAX_COMPONENTS);
  489.81 +
  489.82 +  /* Compute maximum sampling factors; check factor validity */
  489.83 +  cinfo->max_h_samp_factor = 1;
  489.84 +  cinfo->max_v_samp_factor = 1;
  489.85 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  489.86 +       ci++, compptr++) {
  489.87 +    if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
  489.88 +	compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
  489.89 +      ERREXIT(cinfo, JERR_BAD_SAMPLING);
  489.90 +    cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
  489.91 +				   compptr->h_samp_factor);
  489.92 +    cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
  489.93 +				   compptr->v_samp_factor);
  489.94 +  }
  489.95 +
  489.96 +  /* Compute dimensions of components */
  489.97 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  489.98 +       ci++, compptr++) {
  489.99 +    /* Fill in the correct component_index value; don't rely on application */
 489.100 +    compptr->component_index = ci;
 489.101 +    /* For compression, we never do DCT scaling. */
 489.102 +    compptr->DCT_scaled_size = DCTSIZE;
 489.103 +    /* Size in DCT blocks */
 489.104 +    compptr->width_in_blocks = (JDIMENSION)
 489.105 +      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
 489.106 +		    (long) (cinfo->max_h_samp_factor * DCTSIZE));
 489.107 +    compptr->height_in_blocks = (JDIMENSION)
 489.108 +      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
 489.109 +		    (long) (cinfo->max_v_samp_factor * DCTSIZE));
 489.110 +    /* Size in samples */
 489.111 +    compptr->downsampled_width = (JDIMENSION)
 489.112 +      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
 489.113 +		    (long) cinfo->max_h_samp_factor);
 489.114 +    compptr->downsampled_height = (JDIMENSION)
 489.115 +      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
 489.116 +		    (long) cinfo->max_v_samp_factor);
 489.117 +    /* Mark component needed (this flag isn't actually used for compression) */
 489.118 +    compptr->component_needed = TRUE;
 489.119 +  }
 489.120 +
 489.121 +  /* Compute number of fully interleaved MCU rows (number of times that
 489.122 +   * main controller will call coefficient controller).
 489.123 +   */
 489.124 +  cinfo->total_iMCU_rows = (JDIMENSION)
 489.125 +    jdiv_round_up((long) cinfo->image_height,
 489.126 +		  (long) (cinfo->max_v_samp_factor*DCTSIZE));
 489.127 +}
 489.128 +
 489.129 +
 489.130 +#ifdef C_MULTISCAN_FILES_SUPPORTED
 489.131 +
 489.132 +LOCAL(void)
 489.133 +validate_script (j_compress_ptr cinfo)
 489.134 +/* Verify that the scan script in cinfo->scan_info[] is valid; also
 489.135 + * determine whether it uses progressive JPEG, and set cinfo->progressive_mode.
 489.136 + */
 489.137 +{
 489.138 +  const jpeg_scan_info * scanptr;
 489.139 +  int scanno, ncomps, ci, coefi, thisi;
 489.140 +  int Ss, Se, Ah, Al;
 489.141 +  boolean component_sent[MAX_COMPONENTS];
 489.142 +#ifdef C_PROGRESSIVE_SUPPORTED
 489.143 +  int * last_bitpos_ptr;
 489.144 +  int last_bitpos[MAX_COMPONENTS][DCTSIZE2];
 489.145 +  /* -1 until that coefficient has been seen; then last Al for it */
 489.146 +#endif
 489.147 +
 489.148 +  if (cinfo->num_scans <= 0)
 489.149 +    ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
 489.150 +
 489.151 +  /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1;
 489.152 +   * for progressive JPEG, no scan can have this.
 489.153 +   */
 489.154 +  scanptr = cinfo->scan_info;
 489.155 +  if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) {
 489.156 +#ifdef C_PROGRESSIVE_SUPPORTED
 489.157 +    cinfo->progressive_mode = TRUE;
 489.158 +    last_bitpos_ptr = & last_bitpos[0][0];
 489.159 +    for (ci = 0; ci < cinfo->num_components; ci++) 
 489.160 +      for (coefi = 0; coefi < DCTSIZE2; coefi++)
 489.161 +	*last_bitpos_ptr++ = -1;
 489.162 +#else
 489.163 +    ERREXIT(cinfo, JERR_NOT_COMPILED);
 489.164 +#endif
 489.165 +  } else {
 489.166 +    cinfo->progressive_mode = FALSE;
 489.167 +    for (ci = 0; ci < cinfo->num_components; ci++) 
 489.168 +      component_sent[ci] = FALSE;
 489.169 +  }
 489.170 +
 489.171 +  for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) {
 489.172 +    /* Validate component indexes */
 489.173 +    ncomps = scanptr->comps_in_scan;
 489.174 +    if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN)
 489.175 +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN);
 489.176 +    for (ci = 0; ci < ncomps; ci++) {
 489.177 +      thisi = scanptr->component_index[ci];
 489.178 +      if (thisi < 0 || thisi >= cinfo->num_components)
 489.179 +	ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
 489.180 +      /* Components must appear in SOF order within each scan */
 489.181 +      if (ci > 0 && thisi <= scanptr->component_index[ci-1])
 489.182 +	ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
 489.183 +    }
 489.184 +    /* Validate progression parameters */
 489.185 +    Ss = scanptr->Ss;
 489.186 +    Se = scanptr->Se;
 489.187 +    Ah = scanptr->Ah;
 489.188 +    Al = scanptr->Al;
 489.189 +    if (cinfo->progressive_mode) {
 489.190 +#ifdef C_PROGRESSIVE_SUPPORTED
 489.191 +      /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
 489.192 +       * seems wrong: the upper bound ought to depend on data precision.
 489.193 +       * Perhaps they really meant 0..N+1 for N-bit precision.
 489.194 +       * Here we allow 0..10 for 8-bit data; Al larger than 10 results in
 489.195 +       * out-of-range reconstructed DC values during the first DC scan,
 489.196 +       * which might cause problems for some decoders.
 489.197 +       */
 489.198 +#if BITS_IN_JSAMPLE == 8
 489.199 +#define MAX_AH_AL 10
 489.200 +#else
 489.201 +#define MAX_AH_AL 13
 489.202 +#endif
 489.203 +      if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
 489.204 +	  Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
 489.205 +	ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
 489.206 +      if (Ss == 0) {
 489.207 +	if (Se != 0)		/* DC and AC together not OK */
 489.208 +	  ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
 489.209 +      } else {
 489.210 +	if (ncomps != 1)	/* AC scans must be for only one component */
 489.211 +	  ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
 489.212 +      }
 489.213 +      for (ci = 0; ci < ncomps; ci++) {
 489.214 +	last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0];
 489.215 +	if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */
 489.216 +	  ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
 489.217 +	for (coefi = Ss; coefi <= Se; coefi++) {
 489.218 +	  if (last_bitpos_ptr[coefi] < 0) {
 489.219 +	    /* first scan of this coefficient */
 489.220 +	    if (Ah != 0)
 489.221 +	      ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
 489.222 +	  } else {
 489.223 +	    /* not first scan */
 489.224 +	    if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1)
 489.225 +	      ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
 489.226 +	  }
 489.227 +	  last_bitpos_ptr[coefi] = Al;
 489.228 +	}
 489.229 +      }
 489.230 +#endif
 489.231 +    } else {
 489.232 +      /* For sequential JPEG, all progression parameters must be these: */
 489.233 +      if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0)
 489.234 +	ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
 489.235 +      /* Make sure components are not sent twice */
 489.236 +      for (ci = 0; ci < ncomps; ci++) {
 489.237 +	thisi = scanptr->component_index[ci];
 489.238 +	if (component_sent[thisi])
 489.239 +	  ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
 489.240 +	component_sent[thisi] = TRUE;
 489.241 +      }
 489.242 +    }
 489.243 +  }
 489.244 +
 489.245 +  /* Now verify that everything got sent. */
 489.246 +  if (cinfo->progressive_mode) {
 489.247 +#ifdef C_PROGRESSIVE_SUPPORTED
 489.248 +    /* For progressive mode, we only check that at least some DC data
 489.249 +     * got sent for each component; the spec does not require that all bits
 489.250 +     * of all coefficients be transmitted.  Would it be wiser to enforce
 489.251 +     * transmission of all coefficient bits??
 489.252 +     */
 489.253 +    for (ci = 0; ci < cinfo->num_components; ci++) {
 489.254 +      if (last_bitpos[ci][0] < 0)
 489.255 +	ERREXIT(cinfo, JERR_MISSING_DATA);
 489.256 +    }
 489.257 +#endif
 489.258 +  } else {
 489.259 +    for (ci = 0; ci < cinfo->num_components; ci++) {
 489.260 +      if (! component_sent[ci])
 489.261 +	ERREXIT(cinfo, JERR_MISSING_DATA);
 489.262 +    }
 489.263 +  }
 489.264 +}
 489.265 +
 489.266 +#endif /* C_MULTISCAN_FILES_SUPPORTED */
 489.267 +
 489.268 +
 489.269 +LOCAL(void)
 489.270 +select_scan_parameters (j_compress_ptr cinfo)
 489.271 +/* Set up the scan parameters for the current scan */
 489.272 +{
 489.273 +  int ci;
 489.274 +
 489.275 +#ifdef C_MULTISCAN_FILES_SUPPORTED
 489.276 +  if (cinfo->scan_info != NULL) {
 489.277 +    /* Prepare for current scan --- the script is already validated */
 489.278 +    my_master_ptr master = (my_master_ptr) cinfo->master;
 489.279 +    const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number;
 489.280 +
 489.281 +    cinfo->comps_in_scan = scanptr->comps_in_scan;
 489.282 +    for (ci = 0; ci < scanptr->comps_in_scan; ci++) {
 489.283 +      cinfo->cur_comp_info[ci] =
 489.284 +	&cinfo->comp_info[scanptr->component_index[ci]];
 489.285 +    }
 489.286 +    cinfo->Ss = scanptr->Ss;
 489.287 +    cinfo->Se = scanptr->Se;
 489.288 +    cinfo->Ah = scanptr->Ah;
 489.289 +    cinfo->Al = scanptr->Al;
 489.290 +  }
 489.291 +  else
 489.292 +#endif
 489.293 +  {
 489.294 +    /* Prepare for single sequential-JPEG scan containing all components */
 489.295 +    if (cinfo->num_components > MAX_COMPS_IN_SCAN)
 489.296 +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
 489.297 +	       MAX_COMPS_IN_SCAN);
 489.298 +    cinfo->comps_in_scan = cinfo->num_components;
 489.299 +    for (ci = 0; ci < cinfo->num_components; ci++) {
 489.300 +      cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
 489.301 +    }
 489.302 +    cinfo->Ss = 0;
 489.303 +    cinfo->Se = DCTSIZE2-1;
 489.304 +    cinfo->Ah = 0;
 489.305 +    cinfo->Al = 0;
 489.306 +  }
 489.307 +}
 489.308 +
 489.309 +
 489.310 +LOCAL(void)
 489.311 +per_scan_setup (j_compress_ptr cinfo)
 489.312 +/* Do computations that are needed before processing a JPEG scan */
 489.313 +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */
 489.314 +{
 489.315 +  int ci, mcublks, tmp;
 489.316 +  jpeg_component_info *compptr;
 489.317 +  
 489.318 +  if (cinfo->comps_in_scan == 1) {
 489.319 +    
 489.320 +    /* Noninterleaved (single-component) scan */
 489.321 +    compptr = cinfo->cur_comp_info[0];
 489.322 +    
 489.323 +    /* Overall image size in MCUs */
 489.324 +    cinfo->MCUs_per_row = compptr->width_in_blocks;
 489.325 +    cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
 489.326 +    
 489.327 +    /* For noninterleaved scan, always one block per MCU */
 489.328 +    compptr->MCU_width = 1;
 489.329 +    compptr->MCU_height = 1;
 489.330 +    compptr->MCU_blocks = 1;
 489.331 +    compptr->MCU_sample_width = DCTSIZE;
 489.332 +    compptr->last_col_width = 1;
 489.333 +    /* For noninterleaved scans, it is convenient to define last_row_height
 489.334 +     * as the number of block rows present in the last iMCU row.
 489.335 +     */
 489.336 +    tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
 489.337 +    if (tmp == 0) tmp = compptr->v_samp_factor;
 489.338 +    compptr->last_row_height = tmp;
 489.339 +    
 489.340 +    /* Prepare array describing MCU composition */
 489.341 +    cinfo->blocks_in_MCU = 1;
 489.342 +    cinfo->MCU_membership[0] = 0;
 489.343 +    
 489.344 +  } else {
 489.345 +    
 489.346 +    /* Interleaved (multi-component) scan */
 489.347 +    if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
 489.348 +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
 489.349 +	       MAX_COMPS_IN_SCAN);
 489.350 +    
 489.351 +    /* Overall image size in MCUs */
 489.352 +    cinfo->MCUs_per_row = (JDIMENSION)
 489.353 +      jdiv_round_up((long) cinfo->image_width,
 489.354 +		    (long) (cinfo->max_h_samp_factor*DCTSIZE));
 489.355 +    cinfo->MCU_rows_in_scan = (JDIMENSION)
 489.356 +      jdiv_round_up((long) cinfo->image_height,
 489.357 +		    (long) (cinfo->max_v_samp_factor*DCTSIZE));
 489.358 +    
 489.359 +    cinfo->blocks_in_MCU = 0;
 489.360 +    
 489.361 +    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 489.362 +      compptr = cinfo->cur_comp_info[ci];
 489.363 +      /* Sampling factors give # of blocks of component in each MCU */
 489.364 +      compptr->MCU_width = compptr->h_samp_factor;
 489.365 +      compptr->MCU_height = compptr->v_samp_factor;
 489.366 +      compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
 489.367 +      compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE;
 489.368 +      /* Figure number of non-dummy blocks in last MCU column & row */
 489.369 +      tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
 489.370 +      if (tmp == 0) tmp = compptr->MCU_width;
 489.371 +      compptr->last_col_width = tmp;
 489.372 +      tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
 489.373 +      if (tmp == 0) tmp = compptr->MCU_height;
 489.374 +      compptr->last_row_height = tmp;
 489.375 +      /* Prepare array describing MCU composition */
 489.376 +      mcublks = compptr->MCU_blocks;
 489.377 +      if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU)
 489.378 +	ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
 489.379 +      while (mcublks-- > 0) {
 489.380 +	cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
 489.381 +      }
 489.382 +    }
 489.383 +    
 489.384 +  }
 489.385 +
 489.386 +  /* Convert restart specified in rows to actual MCU count. */
 489.387 +  /* Note that count must fit in 16 bits, so we provide limiting. */
 489.388 +  if (cinfo->restart_in_rows > 0) {
 489.389 +    long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row;
 489.390 +    cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L);
 489.391 +  }
 489.392 +}
 489.393 +
 489.394 +
 489.395 +/*
 489.396 + * Per-pass setup.
 489.397 + * This is called at the beginning of each pass.  We determine which modules
 489.398 + * will be active during this pass and give them appropriate start_pass calls.
 489.399 + * We also set is_last_pass to indicate whether any more passes will be
 489.400 + * required.
 489.401 + */
 489.402 +
 489.403 +METHODDEF(void)
 489.404 +prepare_for_pass (j_compress_ptr cinfo)
 489.405 +{
 489.406 +  my_master_ptr master = (my_master_ptr) cinfo->master;
 489.407 +
 489.408 +  switch (master->pass_type) {
 489.409 +  case main_pass:
 489.410 +    /* Initial pass: will collect input data, and do either Huffman
 489.411 +     * optimization or data output for the first scan.
 489.412 +     */
 489.413 +    select_scan_parameters(cinfo);
 489.414 +    per_scan_setup(cinfo);
 489.415 +    if (! cinfo->raw_data_in) {
 489.416 +      (*cinfo->cconvert->start_pass) (cinfo);
 489.417 +      (*cinfo->downsample->start_pass) (cinfo);
 489.418 +      (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
 489.419 +    }
 489.420 +    (*cinfo->fdct->start_pass) (cinfo);
 489.421 +    (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
 489.422 +    (*cinfo->coef->start_pass) (cinfo,
 489.423 +				(master->total_passes > 1 ?
 489.424 +				 JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
 489.425 +    (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
 489.426 +    if (cinfo->optimize_coding) {
 489.427 +      /* No immediate data output; postpone writing frame/scan headers */
 489.428 +      master->pub.call_pass_startup = FALSE;
 489.429 +    } else {
 489.430 +      /* Will write frame/scan headers at first jpeg_write_scanlines call */
 489.431 +      master->pub.call_pass_startup = TRUE;
 489.432 +    }
 489.433 +    break;
 489.434 +#ifdef ENTROPY_OPT_SUPPORTED
 489.435 +  case huff_opt_pass:
 489.436 +    /* Do Huffman optimization for a scan after the first one. */
 489.437 +    select_scan_parameters(cinfo);
 489.438 +    per_scan_setup(cinfo);
 489.439 +    if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
 489.440 +      (*cinfo->entropy->start_pass) (cinfo, TRUE);
 489.441 +      (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
 489.442 +      master->pub.call_pass_startup = FALSE;
 489.443 +      break;
 489.444 +    }
 489.445 +    /* Special case: Huffman DC refinement scans need no Huffman table
 489.446 +     * and therefore we can skip the optimization pass for them.
 489.447 +     */
 489.448 +    master->pass_type = output_pass;
 489.449 +    master->pass_number++;
 489.450 +    /*FALLTHROUGH*/
 489.451 +#endif
 489.452 +  case output_pass:
 489.453 +    /* Do a data-output pass. */
 489.454 +    /* We need not repeat per-scan setup if prior optimization pass did it. */
 489.455 +    if (! cinfo->optimize_coding) {
 489.456 +      select_scan_parameters(cinfo);
 489.457 +      per_scan_setup(cinfo);
 489.458 +    }
 489.459 +    (*cinfo->entropy->start_pass) (cinfo, FALSE);
 489.460 +    (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
 489.461 +    /* We emit frame/scan headers now */
 489.462 +    if (master->scan_number == 0)
 489.463 +      (*cinfo->marker->write_frame_header) (cinfo);
 489.464 +    (*cinfo->marker->write_scan_header) (cinfo);
 489.465 +    master->pub.call_pass_startup = FALSE;
 489.466 +    break;
 489.467 +  default:
 489.468 +    ERREXIT(cinfo, JERR_NOT_COMPILED);
 489.469 +  }
 489.470 +
 489.471 +  master->pub.is_last_pass = (master->pass_number == master->total_passes-1);
 489.472 +
 489.473 +  /* Set up progress monitor's pass info if present */
 489.474 +  if (cinfo->progress != NULL) {
 489.475 +    cinfo->progress->completed_passes = master->pass_number;
 489.476 +    cinfo->progress->total_passes = master->total_passes;
 489.477 +  }
 489.478 +}
 489.479 +
 489.480 +
 489.481 +/*
 489.482 + * Special start-of-pass hook.
 489.483 + * This is called by jpeg_write_scanlines if call_pass_startup is TRUE.
 489.484 + * In single-pass processing, we need this hook because we don't want to
 489.485 + * write frame/scan headers during jpeg_start_compress; we want to let the
 489.486 + * application write COM markers etc. between jpeg_start_compress and the
 489.487 + * jpeg_write_scanlines loop.
 489.488 + * In multi-pass processing, this routine is not used.
 489.489 + */
 489.490 +
 489.491 +METHODDEF(void)
 489.492 +pass_startup (j_compress_ptr cinfo)
 489.493 +{
 489.494 +  cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */
 489.495 +
 489.496 +  (*cinfo->marker->write_frame_header) (cinfo);
 489.497 +  (*cinfo->marker->write_scan_header) (cinfo);
 489.498 +}
 489.499 +
 489.500 +
 489.501 +/*
 489.502 + * Finish up at end of pass.
 489.503 + */
 489.504 +
 489.505 +METHODDEF(void)
 489.506 +finish_pass_master (j_compress_ptr cinfo)
 489.507 +{
 489.508 +  my_master_ptr master = (my_master_ptr) cinfo->master;
 489.509 +
 489.510 +  /* The entropy coder always needs an end-of-pass call,
 489.511 +   * either to analyze statistics or to flush its output buffer.
 489.512 +   */
 489.513 +  (*cinfo->entropy->finish_pass) (cinfo);
 489.514 +
 489.515 +  /* Update state for next pass */
 489.516 +  switch (master->pass_type) {
 489.517 +  case main_pass:
 489.518 +    /* next pass is either output of scan 0 (after optimization)
 489.519 +     * or output of scan 1 (if no optimization).
 489.520 +     */
 489.521 +    master->pass_type = output_pass;
 489.522 +    if (! cinfo->optimize_coding)
 489.523 +      master->scan_number++;
 489.524 +    break;
 489.525 +  case huff_opt_pass:
 489.526 +    /* next pass is always output of current scan */
 489.527 +    master->pass_type = output_pass;
 489.528 +    break;
 489.529 +  case output_pass:
 489.530 +    /* next pass is either optimization or output of next scan */
 489.531 +    if (cinfo->optimize_coding)
 489.532 +      master->pass_type = huff_opt_pass;
 489.533 +    master->scan_number++;
 489.534 +    break;
 489.535 +  }
 489.536 +
 489.537 +  master->pass_number++;
 489.538 +}
 489.539 +
 489.540 +
 489.541 +/*
 489.542 + * Initialize master compression control.
 489.543 + */
 489.544 +
 489.545 +GLOBAL(void)
 489.546 +jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
 489.547 +{
 489.548 +  my_master_ptr master;
 489.549 +
 489.550 +  master = (my_master_ptr)
 489.551 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 489.552 +				  SIZEOF(my_comp_master));
 489.553 +  cinfo->master = (struct jpeg_comp_master *) master;
 489.554 +  master->pub.prepare_for_pass = prepare_for_pass;
 489.555 +  master->pub.pass_startup = pass_startup;
 489.556 +  master->pub.finish_pass = finish_pass_master;
 489.557 +  master->pub.is_last_pass = FALSE;
 489.558 +
 489.559 +  /* Validate parameters, determine derived values */
 489.560 +  initial_setup(cinfo);
 489.561 +
 489.562 +  if (cinfo->scan_info != NULL) {
 489.563 +#ifdef C_MULTISCAN_FILES_SUPPORTED
 489.564 +    validate_script(cinfo);
 489.565 +#else
 489.566 +    ERREXIT(cinfo, JERR_NOT_COMPILED);
 489.567 +#endif
 489.568 +  } else {
 489.569 +    cinfo->progressive_mode = FALSE;
 489.570 +    cinfo->num_scans = 1;
 489.571 +  }
 489.572 +
 489.573 +  if (cinfo->progressive_mode)	/*  TEMPORARY HACK ??? */
 489.574 +    cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */
 489.575 +
 489.576 +  /* Initialize my private state */
 489.577 +  if (transcode_only) {
 489.578 +    /* no main pass in transcoding */
 489.579 +    if (cinfo->optimize_coding)
 489.580 +      master->pass_type = huff_opt_pass;
 489.581 +    else
 489.582 +      master->pass_type = output_pass;
 489.583 +  } else {
 489.584 +    /* for normal compression, first pass is always this type: */
 489.585 +    master->pass_type = main_pass;
 489.586 +  }
 489.587 +  master->scan_number = 0;
 489.588 +  master->pass_number = 0;
 489.589 +  if (cinfo->optimize_coding)
 489.590 +    master->total_passes = cinfo->num_scans * 2;
 489.591 +  else
 489.592 +    master->total_passes = cinfo->num_scans;
 489.593 +}
   490.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   490.2 +++ b/libs/libjpeg/jcomapi.c	Sat Feb 01 19:58:19 2014 +0200
   490.3 @@ -0,0 +1,106 @@
   490.4 +/*
   490.5 + * jcomapi.c
   490.6 + *
   490.7 + * Copyright (C) 1994-1997, Thomas G. Lane.
   490.8 + * This file is part of the Independent JPEG Group's software.
   490.9 + * For conditions of distribution and use, see the accompanying README file.
  490.10 + *
  490.11 + * This file contains application interface routines that are used for both
  490.12 + * compression and decompression.
  490.13 + */
  490.14 +
  490.15 +#define JPEG_INTERNALS
  490.16 +#include "jinclude.h"
  490.17 +#include "jpeglib.h"
  490.18 +
  490.19 +
  490.20 +/*
  490.21 + * Abort processing of a JPEG compression or decompression operation,
  490.22 + * but don't destroy the object itself.
  490.23 + *
  490.24 + * For this, we merely clean up all the nonpermanent memory pools.
  490.25 + * Note that temp files (virtual arrays) are not allowed to belong to
  490.26 + * the permanent pool, so we will be able to close all temp files here.
  490.27 + * Closing a data source or destination, if necessary, is the application's
  490.28 + * responsibility.
  490.29 + */
  490.30 +
  490.31 +GLOBAL(void)
  490.32 +jpeg_abort (j_common_ptr cinfo)
  490.33 +{
  490.34 +  int pool;
  490.35 +
  490.36 +  /* Do nothing if called on a not-initialized or destroyed JPEG object. */
  490.37 +  if (cinfo->mem == NULL)
  490.38 +    return;
  490.39 +
  490.40 +  /* Releasing pools in reverse order might help avoid fragmentation
  490.41 +   * with some (brain-damaged) malloc libraries.
  490.42 +   */
  490.43 +  for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
  490.44 +    (*cinfo->mem->free_pool) (cinfo, pool);
  490.45 +  }
  490.46 +
  490.47 +  /* Reset overall state for possible reuse of object */
  490.48 +  if (cinfo->is_decompressor) {
  490.49 +    cinfo->global_state = DSTATE_START;
  490.50 +    /* Try to keep application from accessing now-deleted marker list.
  490.51 +     * A bit kludgy to do it here, but this is the most central place.
  490.52 +     */
  490.53 +    ((j_decompress_ptr) cinfo)->marker_list = NULL;
  490.54 +  } else {
  490.55 +    cinfo->global_state = CSTATE_START;
  490.56 +  }
  490.57 +}
  490.58 +
  490.59 +
  490.60 +/*
  490.61 + * Destruction of a JPEG object.
  490.62 + *
  490.63 + * Everything gets deallocated except the master jpeg_compress_struct itself
  490.64 + * and the error manager struct.  Both of these are supplied by the application
  490.65 + * and must be freed, if necessary, by the application.  (Often they are on
  490.66 + * the stack and so don't need to be freed anyway.)
  490.67 + * Closing a data source or destination, if necessary, is the application's
  490.68 + * responsibility.
  490.69 + */
  490.70 +
  490.71 +GLOBAL(void)
  490.72 +jpeg_destroy (j_common_ptr cinfo)
  490.73 +{
  490.74 +  /* We need only tell the memory manager to release everything. */
  490.75 +  /* NB: mem pointer is NULL if memory mgr failed to initialize. */
  490.76 +  if (cinfo->mem != NULL)
  490.77 +    (*cinfo->mem->self_destruct) (cinfo);
  490.78 +  cinfo->mem = NULL;		/* be safe if jpeg_destroy is called twice */
  490.79 +  cinfo->global_state = 0;	/* mark it destroyed */
  490.80 +}
  490.81 +
  490.82 +
  490.83 +/*
  490.84 + * Convenience routines for allocating quantization and Huffman tables.
  490.85 + * (Would jutils.c be a more reasonable place to put these?)
  490.86 + */
  490.87 +
  490.88 +GLOBAL(JQUANT_TBL *)
  490.89 +jpeg_alloc_quant_table (j_common_ptr cinfo)
  490.90 +{
  490.91 +  JQUANT_TBL *tbl;
  490.92 +
  490.93 +  tbl = (JQUANT_TBL *)
  490.94 +    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL));
  490.95 +  tbl->sent_table = FALSE;	/* make sure this is false in any new table */
  490.96 +  return tbl;
  490.97 +}
  490.98 +
  490.99 +
 490.100 +GLOBAL(JHUFF_TBL *)
 490.101 +jpeg_alloc_huff_table (j_common_ptr cinfo)
 490.102 +{
 490.103 +  JHUFF_TBL *tbl;
 490.104 +
 490.105 +  tbl = (JHUFF_TBL *)
 490.106 +    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
 490.107 +  tbl->sent_table = FALSE;	/* make sure this is false in any new table */
 490.108 +  return tbl;
 490.109 +}
   491.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   491.2 +++ b/libs/libjpeg/jconfig.h	Sat Feb 01 19:58:19 2014 +0200
   491.3 @@ -0,0 +1,45 @@
   491.4 +/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
   491.5 +/* see jconfig.doc for explanations */
   491.6 +
   491.7 +#define HAVE_PROTOTYPES
   491.8 +#define HAVE_UNSIGNED_CHAR
   491.9 +#define HAVE_UNSIGNED_SHORT
  491.10 +/* #define void char */
  491.11 +/* #define const */
  491.12 +#undef CHAR_IS_UNSIGNED
  491.13 +#define HAVE_STDDEF_H
  491.14 +#define HAVE_STDLIB_H
  491.15 +#undef NEED_BSD_STRINGS
  491.16 +#undef NEED_SYS_TYPES_H
  491.17 +#undef NEED_FAR_POINTERS	/* we presume a 32-bit flat memory model */
  491.18 +#undef NEED_SHORT_EXTERNAL_NAMES
  491.19 +#undef INCOMPLETE_TYPES_BROKEN
  491.20 +
  491.21 +/* Define "boolean" as unsigned char, not int, per Windows custom */
  491.22 +#ifndef __RPCNDR_H__		/* don't conflict if rpcndr.h already read */
  491.23 +typedef unsigned char boolean;
  491.24 +#endif
  491.25 +#define HAVE_BOOLEAN		/* prevent jmorecfg.h from redefining it */
  491.26 +
  491.27 +
  491.28 +#ifdef JPEG_INTERNALS
  491.29 +
  491.30 +#undef RIGHT_SHIFT_IS_UNSIGNED
  491.31 +
  491.32 +#endif /* JPEG_INTERNALS */
  491.33 +
  491.34 +#ifdef JPEG_CJPEG_DJPEG
  491.35 +
  491.36 +#define BMP_SUPPORTED		/* BMP image file format */
  491.37 +#define GIF_SUPPORTED		/* GIF image file format */
  491.38 +#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
  491.39 +#undef RLE_SUPPORTED		/* Utah RLE image file format */
  491.40 +#define TARGA_SUPPORTED		/* Targa image file format */
  491.41 +
  491.42 +#define TWO_FILE_COMMANDLINE	/* optional */
  491.43 +#define USE_SETMODE		/* Microsoft has setmode() */
  491.44 +#undef NEED_SIGNAL_CATCHER
  491.45 +#undef DONT_USE_B_MODE
  491.46 +#undef PROGRESS_REPORT		/* optional */
  491.47 +
  491.48 +#endif /* JPEG_CJPEG_DJPEG */
   492.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   492.2 +++ b/libs/libjpeg/jcparam.c	Sat Feb 01 19:58:19 2014 +0200
   492.3 @@ -0,0 +1,610 @@
   492.4 +/*
   492.5 + * jcparam.c
   492.6 + *
   492.7 + * Copyright (C) 1991-1998, Thomas G. Lane.
   492.8 + * This file is part of the Independent JPEG Group's software.
   492.9 + * For conditions of distribution and use, see the accompanying README file.
  492.10 + *
  492.11 + * This file contains optional default-setting code for the JPEG compressor.
  492.12 + * Applications do not have to use this file, but those that don't use it
  492.13 + * must know a lot more about the innards of the JPEG code.
  492.14 + */
  492.15 +
  492.16 +#define JPEG_INTERNALS
  492.17 +#include "jinclude.h"
  492.18 +#include "jpeglib.h"
  492.19 +
  492.20 +
  492.21 +/*
  492.22 + * Quantization table setup routines
  492.23 + */
  492.24 +
  492.25 +GLOBAL(void)
  492.26 +jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
  492.27 +		      const unsigned int *basic_table,
  492.28 +		      int scale_factor, boolean force_baseline)
  492.29 +/* Define a quantization table equal to the basic_table times
  492.30 + * a scale factor (given as a percentage).
  492.31 + * If force_baseline is TRUE, the computed quantization table entries
  492.32 + * are limited to 1..255 for JPEG baseline compatibility.
  492.33 + */
  492.34 +{
  492.35 +  JQUANT_TBL ** qtblptr;
  492.36 +  int i;
  492.37 +  long temp;
  492.38 +
  492.39 +  /* Safety check to ensure start_compress not called yet. */
  492.40 +  if (cinfo->global_state != CSTATE_START)
  492.41 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  492.42 +
  492.43 +  if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS)
  492.44 +    ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl);
  492.45 +
  492.46 +  qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
  492.47 +
  492.48 +  if (*qtblptr == NULL)
  492.49 +    *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo);
  492.50 +
  492.51 +  for (i = 0; i < DCTSIZE2; i++) {
  492.52 +    temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
  492.53 +    /* limit the values to the valid range */
  492.54 +    if (temp <= 0L) temp = 1L;
  492.55 +    if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */
  492.56 +    if (force_baseline && temp > 255L)
  492.57 +      temp = 255L;		/* limit to baseline range if requested */
  492.58 +    (*qtblptr)->quantval[i] = (UINT16) temp;
  492.59 +  }
  492.60 +
  492.61 +  /* Initialize sent_table FALSE so table will be written to JPEG file. */
  492.62 +  (*qtblptr)->sent_table = FALSE;
  492.63 +}
  492.64 +
  492.65 +
  492.66 +GLOBAL(void)
  492.67 +jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
  492.68 +			 boolean force_baseline)
  492.69 +/* Set or change the 'quality' (quantization) setting, using default tables
  492.70 + * and a straight percentage-scaling quality scale.  In most cases it's better
  492.71 + * to use jpeg_set_quality (below); this entry point is provided for
  492.72 + * applications that insist on a linear percentage scaling.
  492.73 + */
  492.74 +{
  492.75 +  /* These are the sample quantization tables given in JPEG spec section K.1.
  492.76 +   * The spec says that the values given produce "good" quality, and
  492.77 +   * when divided by 2, "very good" quality.
  492.78 +   */
  492.79 +  static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
  492.80 +    16,  11,  10,  16,  24,  40,  51,  61,
  492.81 +    12,  12,  14,  19,  26,  58,  60,  55,
  492.82 +    14,  13,  16,  24,  40,  57,  69,  56,
  492.83 +    14,  17,  22,  29,  51,  87,  80,  62,
  492.84 +    18,  22,  37,  56,  68, 109, 103,  77,
  492.85 +    24,  35,  55,  64,  81, 104, 113,  92,
  492.86 +    49,  64,  78,  87, 103, 121, 120, 101,
  492.87 +    72,  92,  95,  98, 112, 100, 103,  99
  492.88 +  };
  492.89 +  static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
  492.90 +    17,  18,  24,  47,  99,  99,  99,  99,
  492.91 +    18,  21,  26,  66,  99,  99,  99,  99,
  492.92 +    24,  26,  56,  99,  99,  99,  99,  99,
  492.93 +    47,  66,  99,  99,  99,  99,  99,  99,
  492.94 +    99,  99,  99,  99,  99,  99,  99,  99,
  492.95 +    99,  99,  99,  99,  99,  99,  99,  99,
  492.96 +    99,  99,  99,  99,  99,  99,  99,  99,
  492.97 +    99,  99,  99,  99,  99,  99,  99,  99
  492.98 +  };
  492.99 +
 492.100 +  /* Set up two quantization tables using the specified scaling */
 492.101 +  jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
 492.102 +		       scale_factor, force_baseline);
 492.103 +  jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
 492.104 +		       scale_factor, force_baseline);
 492.105 +}
 492.106 +
 492.107 +
 492.108 +GLOBAL(int)
 492.109 +jpeg_quality_scaling (int quality)
 492.110 +/* Convert a user-specified quality rating to a percentage scaling factor
 492.111 + * for an underlying quantization table, using our recommended scaling curve.
 492.112 + * The input 'quality' factor should be 0 (terrible) to 100 (very good).
 492.113 + */
 492.114 +{
 492.115 +  /* Safety limit on quality factor.  Convert 0 to 1 to avoid zero divide. */
 492.116 +  if (quality <= 0) quality = 1;
 492.117 +  if (quality > 100) quality = 100;
 492.118 +
 492.119 +  /* The basic table is used as-is (scaling 100) for a quality of 50.
 492.120 +   * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
 492.121 +   * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table
 492.122 +   * to make all the table entries 1 (hence, minimum quantization loss).
 492.123 +   * Qualities 1..50 are converted to scaling percentage 5000/Q.
 492.124 +   */
 492.125 +  if (quality < 50)
 492.126 +    quality = 5000 / quality;
 492.127 +  else
 492.128 +    quality = 200 - quality*2;
 492.129 +
 492.130 +  return quality;
 492.131 +}
 492.132 +
 492.133 +
 492.134 +GLOBAL(void)
 492.135 +jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
 492.136 +/* Set or change the 'quality' (quantization) setting, using default tables.
 492.137 + * This is the standard quality-adjusting entry point for typical user
 492.138 + * interfaces; only those who want detailed control over quantization tables
 492.139 + * would use the preceding three routines directly.
 492.140 + */
 492.141 +{
 492.142 +  /* Convert user 0-100 rating to percentage scaling */
 492.143 +  quality = jpeg_quality_scaling(quality);
 492.144 +
 492.145 +  /* Set up standard quality tables */
 492.146 +  jpeg_set_linear_quality(cinfo, quality, force_baseline);
 492.147 +}
 492.148 +
 492.149 +
 492.150 +/*
 492.151 + * Huffman table setup routines
 492.152 + */
 492.153 +
 492.154 +LOCAL(void)
 492.155 +add_huff_table (j_compress_ptr cinfo,
 492.156 +		JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
 492.157 +/* Define a Huffman table */
 492.158 +{
 492.159 +  int nsymbols, len;
 492.160 +
 492.161 +  if (*htblptr == NULL)
 492.162 +    *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
 492.163 +
 492.164 +  /* Copy the number-of-symbols-of-each-code-length counts */
 492.165 +  MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
 492.166 +
 492.167 +  /* Validate the counts.  We do this here mainly so we can copy the right
 492.168 +   * number of symbols from the val[] array, without risking marching off
 492.169 +   * the end of memory.  jchuff.c will do a more thorough test later.
 492.170 +   */
 492.171 +  nsymbols = 0;
 492.172 +  for (len = 1; len <= 16; len++)
 492.173 +    nsymbols += bits[len];
 492.174 +  if (nsymbols < 1 || nsymbols > 256)
 492.175 +    ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 492.176 +
 492.177 +  MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
 492.178 +
 492.179 +  /* Initialize sent_table FALSE so table will be written to JPEG file. */
 492.180 +  (*htblptr)->sent_table = FALSE;
 492.181 +}
 492.182 +
 492.183 +
 492.184 +LOCAL(void)
 492.185 +std_huff_tables (j_compress_ptr cinfo)
 492.186 +/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
 492.187 +/* IMPORTANT: these are only valid for 8-bit data precision! */
 492.188 +{
 492.189 +  static const UINT8 bits_dc_luminance[17] =
 492.190 +    { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
 492.191 +  static const UINT8 val_dc_luminance[] =
 492.192 +    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
 492.193 +  
 492.194 +  static const UINT8 bits_dc_chrominance[17] =
 492.195 +    { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
 492.196 +  static const UINT8 val_dc_chrominance[] =
 492.197 +    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
 492.198 +  
 492.199 +  static const UINT8 bits_ac_luminance[17] =
 492.200 +    { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
 492.201 +  static const UINT8 val_ac_luminance[] =
 492.202 +    { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
 492.203 +      0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
 492.204 +      0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
 492.205 +      0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
 492.206 +      0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
 492.207 +      0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
 492.208 +      0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
 492.209 +      0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
 492.210 +      0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
 492.211 +      0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
 492.212 +      0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
 492.213 +      0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
 492.214 +      0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
 492.215 +      0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
 492.216 +      0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
 492.217 +      0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
 492.218 +      0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
 492.219 +      0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
 492.220 +      0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
 492.221 +      0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
 492.222 +      0xf9, 0xfa };
 492.223 +  
 492.224 +  static const UINT8 bits_ac_chrominance[17] =
 492.225 +    { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
 492.226 +  static const UINT8 val_ac_chrominance[] =
 492.227 +    { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
 492.228 +      0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
 492.229 +      0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
 492.230 +      0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
 492.231 +      0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
 492.232 +      0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
 492.233 +      0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
 492.234 +      0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
 492.235 +      0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
 492.236 +      0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
 492.237 +      0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
 492.238 +      0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
 492.239 +      0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
 492.240 +      0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
 492.241 +      0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
 492.242 +      0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
 492.243 +      0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
 492.244 +      0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
 492.245 +      0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
 492.246 +      0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
 492.247 +      0xf9, 0xfa };
 492.248 +  
 492.249 +  add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
 492.250 +		 bits_dc_luminance, val_dc_luminance);
 492.251 +  add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
 492.252 +		 bits_ac_luminance, val_ac_luminance);
 492.253 +  add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
 492.254 +		 bits_dc_chrominance, val_dc_chrominance);
 492.255 +  add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
 492.256 +		 bits_ac_chrominance, val_ac_chrominance);
 492.257 +}
 492.258 +
 492.259 +
 492.260 +/*
 492.261 + * Default parameter setup for compression.
 492.262 + *
 492.263 + * Applications that don't choose to use this routine must do their
 492.264 + * own setup of all these parameters.  Alternately, you can call this
 492.265 + * to establish defaults and then alter parameters selectively.  This
 492.266 + * is the recommended approach since, if we add any new parameters,
 492.267 + * your code will still work (they'll be set to reasonable defaults).
 492.268 + */
 492.269 +
 492.270 +GLOBAL(void)
 492.271 +jpeg_set_defaults (j_compress_ptr cinfo)
 492.272 +{
 492.273 +  int i;
 492.274 +
 492.275 +  /* Safety check to ensure start_compress not called yet. */
 492.276 +  if (cinfo->global_state != CSTATE_START)
 492.277 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 492.278 +
 492.279 +  /* Allocate comp_info array large enough for maximum component count.
 492.280 +   * Array is made permanent in case application wants to compress
 492.281 +   * multiple images at same param settings.
 492.282 +   */
 492.283 +  if (cinfo->comp_info == NULL)
 492.284 +    cinfo->comp_info = (jpeg_component_info *)
 492.285 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 492.286 +				  MAX_COMPONENTS * SIZEOF(jpeg_component_info));
 492.287 +
 492.288 +  /* Initialize everything not dependent on the color space */
 492.289 +
 492.290 +  cinfo->data_precision = BITS_IN_JSAMPLE;
 492.291 +  /* Set up two quantization tables using default quality of 75 */
 492.292 +  jpeg_set_quality(cinfo, 75, TRUE);
 492.293 +  /* Set up two Huffman tables */
 492.294 +  std_huff_tables(cinfo);
 492.295 +
 492.296 +  /* Initialize default arithmetic coding conditioning */
 492.297 +  for (i = 0; i < NUM_ARITH_TBLS; i++) {
 492.298 +    cinfo->arith_dc_L[i] = 0;
 492.299 +    cinfo->arith_dc_U[i] = 1;
 492.300 +    cinfo->arith_ac_K[i] = 5;
 492.301 +  }
 492.302 +
 492.303 +  /* Default is no multiple-scan output */
 492.304 +  cinfo->scan_info = NULL;
 492.305 +  cinfo->num_scans = 0;
 492.306 +
 492.307 +  /* Expect normal source image, not raw downsampled data */
 492.308 +  cinfo->raw_data_in = FALSE;
 492.309 +
 492.310 +  /* Use Huffman coding, not arithmetic coding, by default */
 492.311 +  cinfo->arith_code = FALSE;
 492.312 +
 492.313 +  /* By default, don't do extra passes to optimize entropy coding */
 492.314 +  cinfo->optimize_coding = FALSE;
 492.315 +  /* The standard Huffman tables are only valid for 8-bit data precision.
 492.316 +   * If the precision is higher, force optimization on so that usable
 492.317 +   * tables will be computed.  This test can be removed if default tables
 492.318 +   * are supplied that are valid for the desired precision.
 492.319 +   */
 492.320 +  if (cinfo->data_precision > 8)
 492.321 +    cinfo->optimize_coding = TRUE;
 492.322 +
 492.323 +  /* By default, use the simpler non-cosited sampling alignment */
 492.324 +  cinfo->CCIR601_sampling = FALSE;
 492.325 +
 492.326 +  /* No input smoothing */
 492.327 +  cinfo->smoothing_factor = 0;
 492.328 +
 492.329 +  /* DCT algorithm preference */
 492.330 +  cinfo->dct_method = JDCT_DEFAULT;
 492.331 +
 492.332 +  /* No restart markers */
 492.333 +  cinfo->restart_interval = 0;
 492.334 +  cinfo->restart_in_rows = 0;
 492.335 +
 492.336 +  /* Fill in default JFIF marker parameters.  Note that whether the marker
 492.337 +   * will actually be written is determined by jpeg_set_colorspace.
 492.338 +   *
 492.339 +   * By default, the library emits JFIF version code 1.01.
 492.340 +   * An application that wants to emit JFIF 1.02 extension markers should set
 492.341 +   * JFIF_minor_version to 2.  We could probably get away with just defaulting
 492.342 +   * to 1.02, but there may still be some decoders in use that will complain
 492.343 +   * about that; saying 1.01 should minimize compatibility problems.
 492.344 +   */
 492.345 +  cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */
 492.346 +  cinfo->JFIF_minor_version = 1;
 492.347 +  cinfo->density_unit = 0;	/* Pixel size is unknown by default */
 492.348 +  cinfo->X_density = 1;		/* Pixel aspect ratio is square by default */
 492.349 +  cinfo->Y_density = 1;
 492.350 +
 492.351 +  /* Choose JPEG colorspace based on input space, set defaults accordingly */
 492.352 +
 492.353 +  jpeg_default_colorspace(cinfo);
 492.354 +}
 492.355 +
 492.356 +
 492.357 +/*
 492.358 + * Select an appropriate JPEG colorspace for in_color_space.
 492.359 + */
 492.360 +
 492.361 +GLOBAL(void)
 492.362 +jpeg_default_colorspace (j_compress_ptr cinfo)
 492.363 +{
 492.364 +  switch (cinfo->in_color_space) {
 492.365 +  case JCS_GRAYSCALE:
 492.366 +    jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
 492.367 +    break;
 492.368 +  case JCS_RGB:
 492.369 +    jpeg_set_colorspace(cinfo, JCS_YCbCr);
 492.370 +    break;
 492.371 +  case JCS_YCbCr:
 492.372 +    jpeg_set_colorspace(cinfo, JCS_YCbCr);
 492.373 +    break;
 492.374 +  case JCS_CMYK:
 492.375 +    jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */
 492.376 +    break;
 492.377 +  case JCS_YCCK:
 492.378 +    jpeg_set_colorspace(cinfo, JCS_YCCK);
 492.379 +    break;
 492.380 +  case JCS_UNKNOWN:
 492.381 +    jpeg_set_colorspace(cinfo, JCS_UNKNOWN);
 492.382 +    break;
 492.383 +  default:
 492.384 +    ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 492.385 +  }
 492.386 +}
 492.387 +
 492.388 +
 492.389 +/*
 492.390 + * Set the JPEG colorspace, and choose colorspace-dependent default values.
 492.391 + */
 492.392 +
 492.393 +GLOBAL(void)
 492.394 +jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
 492.395 +{
 492.396 +  jpeg_component_info * compptr;
 492.397 +  int ci;
 492.398 +
 492.399 +#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl)  \
 492.400 +  (compptr = &cinfo->comp_info[index], \
 492.401 +   compptr->component_id = (id), \
 492.402 +   compptr->h_samp_factor = (hsamp), \
 492.403 +   compptr->v_samp_factor = (vsamp), \
 492.404 +   compptr->quant_tbl_no = (quant), \
 492.405 +   compptr->dc_tbl_no = (dctbl), \
 492.406 +   compptr->ac_tbl_no = (actbl) )
 492.407 +
 492.408 +  /* Safety check to ensure start_compress not called yet. */
 492.409 +  if (cinfo->global_state != CSTATE_START)
 492.410 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 492.411 +
 492.412 +  /* For all colorspaces, we use Q and Huff tables 0 for luminance components,
 492.413 +   * tables 1 for chrominance components.
 492.414 +   */
 492.415 +
 492.416 +  cinfo->jpeg_color_space = colorspace;
 492.417 +
 492.418 +  cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */
 492.419 +  cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */
 492.420 +
 492.421 +  switch (colorspace) {
 492.422 +  case JCS_GRAYSCALE:
 492.423 +    cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
 492.424 +    cinfo->num_components = 1;
 492.425 +    /* JFIF specifies component ID 1 */
 492.426 +    SET_COMP(0, 1, 1,1, 0, 0,0);
 492.427 +    break;
 492.428 +  case JCS_RGB:
 492.429 +    cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */
 492.430 +    cinfo->num_components = 3;
 492.431 +    SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0);
 492.432 +    SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0);
 492.433 +    SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0);
 492.434 +    break;
 492.435 +  case JCS_YCbCr:
 492.436 +    cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
 492.437 +    cinfo->num_components = 3;
 492.438 +    /* JFIF specifies component IDs 1,2,3 */
 492.439 +    /* We default to 2x2 subsamples of chrominance */
 492.440 +    SET_COMP(0, 1, 2,2, 0, 0,0);
 492.441 +    SET_COMP(1, 2, 1,1, 1, 1,1);
 492.442 +    SET_COMP(2, 3, 1,1, 1, 1,1);
 492.443 +    break;
 492.444 +  case JCS_CMYK:
 492.445 +    cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */
 492.446 +    cinfo->num_components = 4;
 492.447 +    SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0);
 492.448 +    SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0);
 492.449 +    SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0);
 492.450 +    SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0);
 492.451 +    break;
 492.452 +  case JCS_YCCK:
 492.453 +    cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */
 492.454 +    cinfo->num_components = 4;
 492.455 +    SET_COMP(0, 1, 2,2, 0, 0,0);
 492.456 +    SET_COMP(1, 2, 1,1, 1, 1,1);
 492.457 +    SET_COMP(2, 3, 1,1, 1, 1,1);
 492.458 +    SET_COMP(3, 4, 2,2, 0, 0,0);
 492.459 +    break;
 492.460 +  case JCS_UNKNOWN:
 492.461 +    cinfo->num_components = cinfo->input_components;
 492.462 +    if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS)
 492.463 +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
 492.464 +	       MAX_COMPONENTS);
 492.465 +    for (ci = 0; ci < cinfo->num_components; ci++) {
 492.466 +      SET_COMP(ci, ci, 1,1, 0, 0,0);
 492.467 +    }
 492.468 +    break;
 492.469 +  default:
 492.470 +    ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 492.471 +  }
 492.472 +}
 492.473 +
 492.474 +
 492.475 +#ifdef C_PROGRESSIVE_SUPPORTED
 492.476 +
 492.477 +LOCAL(jpeg_scan_info *)
 492.478 +fill_a_scan (jpeg_scan_info * scanptr, int ci,
 492.479 +	     int Ss, int Se, int Ah, int Al)
 492.480 +/* Support routine: generate one scan for specified component */
 492.481 +{
 492.482 +  scanptr->comps_in_scan = 1;
 492.483 +  scanptr->component_index[0] = ci;
 492.484 +  scanptr->Ss = Ss;
 492.485 +  scanptr->Se = Se;
 492.486 +  scanptr->Ah = Ah;
 492.487 +  scanptr->Al = Al;
 492.488 +  scanptr++;
 492.489 +  return scanptr;
 492.490 +}
 492.491 +
 492.492 +LOCAL(jpeg_scan_info *)
 492.493 +fill_scans (jpeg_scan_info * scanptr, int ncomps,
 492.494 +	    int Ss, int Se, int Ah, int Al)
 492.495 +/* Support routine: generate one scan for each component */
 492.496 +{
 492.497 +  int ci;
 492.498 +
 492.499 +  for (ci = 0; ci < ncomps; ci++) {
 492.500 +    scanptr->comps_in_scan = 1;
 492.501 +    scanptr->component_index[0] = ci;
 492.502 +    scanptr->Ss = Ss;
 492.503 +    scanptr->Se = Se;
 492.504 +    scanptr->Ah = Ah;
 492.505 +    scanptr->Al = Al;
 492.506 +    scanptr++;
 492.507 +  }
 492.508 +  return scanptr;
 492.509 +}
 492.510 +
 492.511 +LOCAL(jpeg_scan_info *)
 492.512 +fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
 492.513 +/* Support routine: generate interleaved DC scan if possible, else N scans */
 492.514 +{
 492.515 +  int ci;
 492.516 +
 492.517 +  if (ncomps <= MAX_COMPS_IN_SCAN) {
 492.518 +    /* Single interleaved DC scan */
 492.519 +    scanptr->comps_in_scan = ncomps;
 492.520 +    for (ci = 0; ci < ncomps; ci++)
 492.521 +      scanptr->component_index[ci] = ci;
 492.522 +    scanptr->Ss = scanptr->Se = 0;
 492.523 +    scanptr->Ah = Ah;
 492.524 +    scanptr->Al = Al;
 492.525 +    scanptr++;
 492.526 +  } else {
 492.527 +    /* Noninterleaved DC scan for each component */
 492.528 +    scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al);
 492.529 +  }
 492.530 +  return scanptr;
 492.531 +}
 492.532 +
 492.533 +
 492.534 +/*
 492.535 + * Create a recommended progressive-JPEG script.
 492.536 + * cinfo->num_components and cinfo->jpeg_color_space must be correct.
 492.537 + */
 492.538 +
 492.539 +GLOBAL(void)
 492.540 +jpeg_simple_progression (j_compress_ptr cinfo)
 492.541 +{
 492.542 +  int ncomps = cinfo->num_components;
 492.543 +  int nscans;
 492.544 +  jpeg_scan_info * scanptr;
 492.545 +
 492.546 +  /* Safety check to ensure start_compress not called yet. */
 492.547 +  if (cinfo->global_state != CSTATE_START)
 492.548 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 492.549 +
 492.550 +  /* Figure space needed for script.  Calculation must match code below! */
 492.551 +  if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
 492.552 +    /* Custom script for YCbCr color images. */
 492.553 +    nscans = 10;
 492.554 +  } else {
 492.555 +    /* All-purpose script for other color spaces. */
 492.556 +    if (ncomps > MAX_COMPS_IN_SCAN)
 492.557 +      nscans = 6 * ncomps;	/* 2 DC + 4 AC scans per component */
 492.558 +    else
 492.559 +      nscans = 2 + 4 * ncomps;	/* 2 DC scans; 4 AC scans per component */
 492.560 +  }
 492.561 +
 492.562 +  /* Allocate space for script.
 492.563 +   * We need to put it in the permanent pool in case the application performs
 492.564 +   * multiple compressions without changing the settings.  To avoid a memory
 492.565 +   * leak if jpeg_simple_progression is called repeatedly for the same JPEG
 492.566 +   * object, we try to re-use previously allocated space, and we allocate
 492.567 +   * enough space to handle YCbCr even if initially asked for grayscale.
 492.568 +   */
 492.569 +  if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
 492.570 +    cinfo->script_space_size = MAX(nscans, 10);
 492.571 +    cinfo->script_space = (jpeg_scan_info *)
 492.572 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 492.573 +			cinfo->script_space_size * SIZEOF(jpeg_scan_info));
 492.574 +  }
 492.575 +  scanptr = cinfo->script_space;
 492.576 +  cinfo->scan_info = scanptr;
 492.577 +  cinfo->num_scans = nscans;
 492.578 +
 492.579 +  if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
 492.580 +    /* Custom script for YCbCr color images. */
 492.581 +    /* Initial DC scan */
 492.582 +    scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
 492.583 +    /* Initial AC scan: get some luma data out in a hurry */
 492.584 +    scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2);
 492.585 +    /* Chroma data is too small to be worth expending many scans on */
 492.586 +    scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1);
 492.587 +    scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1);
 492.588 +    /* Complete spectral selection for luma AC */
 492.589 +    scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2);
 492.590 +    /* Refine next bit of luma AC */
 492.591 +    scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1);
 492.592 +    /* Finish DC successive approximation */
 492.593 +    scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
 492.594 +    /* Finish AC successive approximation */
 492.595 +    scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0);
 492.596 +    scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0);
 492.597 +    /* Luma bottom bit comes last since it's usually largest scan */
 492.598 +    scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
 492.599 +  } else {
 492.600 +    /* All-purpose script for other color spaces. */
 492.601 +    /* Successive approximation first pass */
 492.602 +    scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
 492.603 +    scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2);
 492.604 +    scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2);
 492.605 +    /* Successive approximation second pass */
 492.606 +    scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1);
 492.607 +    /* Successive approximation final pass */
 492.608 +    scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
 492.609 +    scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0);
 492.610 +  }
 492.611 +}
 492.612 +
 492.613 +#endif /* C_PROGRESSIVE_SUPPORTED */
   493.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   493.2 +++ b/libs/libjpeg/jcphuff.c	Sat Feb 01 19:58:19 2014 +0200
   493.3 @@ -0,0 +1,833 @@
   493.4 +/*
   493.5 + * jcphuff.c
   493.6 + *
   493.7 + * Copyright (C) 1995-1997, Thomas G. Lane.
   493.8 + * This file is part of the Independent JPEG Group's software.
   493.9 + * For conditions of distribution and use, see the accompanying README file.
  493.10 + *
  493.11 + * This file contains Huffman entropy encoding routines for progressive JPEG.
  493.12 + *
  493.13 + * We do not support output suspension in this module, since the library
  493.14 + * currently does not allow multiple-scan files to be written with output
  493.15 + * suspension.
  493.16 + */
  493.17 +
  493.18 +#define JPEG_INTERNALS
  493.19 +#include "jinclude.h"
  493.20 +#include "jpeglib.h"
  493.21 +#include "jchuff.h"		/* Declarations shared with jchuff.c */
  493.22 +
  493.23 +#ifdef C_PROGRESSIVE_SUPPORTED
  493.24 +
  493.25 +/* Expanded entropy encoder object for progressive Huffman encoding. */
  493.26 +
  493.27 +typedef struct {
  493.28 +  struct jpeg_entropy_encoder pub; /* public fields */
  493.29 +
  493.30 +  /* Mode flag: TRUE for optimization, FALSE for actual data output */
  493.31 +  boolean gather_statistics;
  493.32 +
  493.33 +  /* Bit-level coding status.
  493.34 +   * next_output_byte/free_in_buffer are local copies of cinfo->dest fields.
  493.35 +   */
  493.36 +  JOCTET * next_output_byte;	/* => next byte to write in buffer */
  493.37 +  size_t free_in_buffer;	/* # of byte spaces remaining in buffer */
  493.38 +  INT32 put_buffer;		/* current bit-accumulation buffer */
  493.39 +  int put_bits;			/* # of bits now in it */
  493.40 +  j_compress_ptr cinfo;		/* link to cinfo (needed for dump_buffer) */
  493.41 +
  493.42 +  /* Coding status for DC components */
  493.43 +  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
  493.44 +
  493.45 +  /* Coding status for AC components */
  493.46 +  int ac_tbl_no;		/* the table number of the single component */
  493.47 +  unsigned int EOBRUN;		/* run length of EOBs */
  493.48 +  unsigned int BE;		/* # of buffered correction bits before MCU */
  493.49 +  char * bit_buffer;		/* buffer for correction bits (1 per char) */
  493.50 +  /* packing correction bits tightly would save some space but cost time... */
  493.51 +
  493.52 +  unsigned int restarts_to_go;	/* MCUs left in this restart interval */
  493.53 +  int next_restart_num;		/* next restart number to write (0-7) */
  493.54 +
  493.55 +  /* Pointers to derived tables (these workspaces have image lifespan).
  493.56 +   * Since any one scan codes only DC or only AC, we only need one set
  493.57 +   * of tables, not one for DC and one for AC.
  493.58 +   */
  493.59 +  c_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
  493.60 +
  493.61 +  /* Statistics tables for optimization; again, one set is enough */
  493.62 +  long * count_ptrs[NUM_HUFF_TBLS];
  493.63 +} phuff_entropy_encoder;
  493.64 +
  493.65 +typedef phuff_entropy_encoder * phuff_entropy_ptr;
  493.66 +
  493.67 +/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit
  493.68 + * buffer can hold.  Larger sizes may slightly improve compression, but
  493.69 + * 1000 is already well into the realm of overkill.
  493.70 + * The minimum safe size is 64 bits.
  493.71 + */
  493.72 +
  493.73 +#define MAX_CORR_BITS  1000	/* Max # of correction bits I can buffer */
  493.74 +
  493.75 +/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
  493.76 + * We assume that int right shift is unsigned if INT32 right shift is,
  493.77 + * which should be safe.
  493.78 + */
  493.79 +
  493.80 +#ifdef RIGHT_SHIFT_IS_UNSIGNED
  493.81 +#define ISHIFT_TEMPS	int ishift_temp;
  493.82 +#define IRIGHT_SHIFT(x,shft)  \
  493.83 +	((ishift_temp = (x)) < 0 ? \
  493.84 +	 (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
  493.85 +	 (ishift_temp >> (shft)))
  493.86 +#else
  493.87 +#define ISHIFT_TEMPS
  493.88 +#define IRIGHT_SHIFT(x,shft)	((x) >> (shft))
  493.89 +#endif
  493.90 +
  493.91 +/* Forward declarations */
  493.92 +METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,
  493.93 +					    JBLOCKROW *MCU_data));
  493.94 +METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,
  493.95 +					    JBLOCKROW *MCU_data));
  493.96 +METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
  493.97 +					     JBLOCKROW *MCU_data));
  493.98 +METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,
  493.99 +					     JBLOCKROW *MCU_data));
 493.100 +METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));
 493.101 +METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));
 493.102 +
 493.103 +
 493.104 +/*
 493.105 + * Initialize for a Huffman-compressed scan using progressive JPEG.
 493.106 + */
 493.107 +
 493.108 +METHODDEF(void)
 493.109 +start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
 493.110 +{  
 493.111 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 493.112 +  boolean is_DC_band;
 493.113 +  int ci, tbl;
 493.114 +  jpeg_component_info * compptr;
 493.115 +
 493.116 +  entropy->cinfo = cinfo;
 493.117 +  entropy->gather_statistics = gather_statistics;
 493.118 +
 493.119 +  is_DC_band = (cinfo->Ss == 0);
 493.120 +
 493.121 +  /* We assume jcmaster.c already validated the scan parameters. */
 493.122 +
 493.123 +  /* Select execution routines */
 493.124 +  if (cinfo->Ah == 0) {
 493.125 +    if (is_DC_band)
 493.126 +      entropy->pub.encode_mcu = encode_mcu_DC_first;
 493.127 +    else
 493.128 +      entropy->pub.encode_mcu = encode_mcu_AC_first;
 493.129 +  } else {
 493.130 +    if (is_DC_band)
 493.131 +      entropy->pub.encode_mcu = encode_mcu_DC_refine;
 493.132 +    else {
 493.133 +      entropy->pub.encode_mcu = encode_mcu_AC_refine;
 493.134 +      /* AC refinement needs a correction bit buffer */
 493.135 +      if (entropy->bit_buffer == NULL)
 493.136 +	entropy->bit_buffer = (char *)
 493.137 +	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 493.138 +				      MAX_CORR_BITS * SIZEOF(char));
 493.139 +    }
 493.140 +  }
 493.141 +  if (gather_statistics)
 493.142 +    entropy->pub.finish_pass = finish_pass_gather_phuff;
 493.143 +  else
 493.144 +    entropy->pub.finish_pass = finish_pass_phuff;
 493.145 +
 493.146 +  /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1
 493.147 +   * for AC coefficients.
 493.148 +   */
 493.149 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 493.150 +    compptr = cinfo->cur_comp_info[ci];
 493.151 +    /* Initialize DC predictions to 0 */
 493.152 +    entropy->last_dc_val[ci] = 0;
 493.153 +    /* Get table index */
 493.154 +    if (is_DC_band) {
 493.155 +      if (cinfo->Ah != 0)	/* DC refinement needs no table */
 493.156 +	continue;
 493.157 +      tbl = compptr->dc_tbl_no;
 493.158 +    } else {
 493.159 +      entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
 493.160 +    }
 493.161 +    if (gather_statistics) {
 493.162 +      /* Check for invalid table index */
 493.163 +      /* (make_c_derived_tbl does this in the other path) */
 493.164 +      if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
 493.165 +        ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
 493.166 +      /* Allocate and zero the statistics tables */
 493.167 +      /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
 493.168 +      if (entropy->count_ptrs[tbl] == NULL)
 493.169 +	entropy->count_ptrs[tbl] = (long *)
 493.170 +	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 493.171 +				      257 * SIZEOF(long));
 493.172 +      MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
 493.173 +    } else {
 493.174 +      /* Compute derived values for Huffman table */
 493.175 +      /* We may do this more than once for a table, but it's not expensive */
 493.176 +      jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
 493.177 +			      & entropy->derived_tbls[tbl]);
 493.178 +    }
 493.179 +  }
 493.180 +
 493.181 +  /* Initialize AC stuff */
 493.182 +  entropy->EOBRUN = 0;
 493.183 +  entropy->BE = 0;
 493.184 +
 493.185 +  /* Initialize bit buffer to empty */
 493.186 +  entropy->put_buffer = 0;
 493.187 +  entropy->put_bits = 0;
 493.188 +
 493.189 +  /* Initialize restart stuff */
 493.190 +  entropy->restarts_to_go = cinfo->restart_interval;
 493.191 +  entropy->next_restart_num = 0;
 493.192 +}
 493.193 +
 493.194 +
 493.195 +/* Outputting bytes to the file.
 493.196 + * NB: these must be called only when actually outputting,
 493.197 + * that is, entropy->gather_statistics == FALSE.
 493.198 + */
 493.199 +
 493.200 +/* Emit a byte */
 493.201 +#define emit_byte(entropy,val)  \
 493.202 +	{ *(entropy)->next_output_byte++ = (JOCTET) (val);  \
 493.203 +	  if (--(entropy)->free_in_buffer == 0)  \
 493.204 +	    dump_buffer(entropy); }
 493.205 +
 493.206 +
 493.207 +LOCAL(void)
 493.208 +dump_buffer (phuff_entropy_ptr entropy)
 493.209 +/* Empty the output buffer; we do not support suspension in this module. */
 493.210 +{
 493.211 +  struct jpeg_destination_mgr * dest = entropy->cinfo->dest;
 493.212 +
 493.213 +  if (! (*dest->empty_output_buffer) (entropy->cinfo))
 493.214 +    ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);
 493.215 +  /* After a successful buffer dump, must reset buffer pointers */
 493.216 +  entropy->next_output_byte = dest->next_output_byte;
 493.217 +  entropy->free_in_buffer = dest->free_in_buffer;
 493.218 +}
 493.219 +
 493.220 +
 493.221 +/* Outputting bits to the file */
 493.222 +
 493.223 +/* Only the right 24 bits of put_buffer are used; the valid bits are
 493.224 + * left-justified in this part.  At most 16 bits can be passed to emit_bits
 493.225 + * in one call, and we never retain more than 7 bits in put_buffer
 493.226 + * between calls, so 24 bits are sufficient.
 493.227 + */
 493.228 +
 493.229 +INLINE
 493.230 +LOCAL(void)
 493.231 +emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
 493.232 +/* Emit some bits, unless we are in gather mode */
 493.233 +{
 493.234 +  /* This routine is heavily used, so it's worth coding tightly. */
 493.235 +  register INT32 put_buffer = (INT32) code;
 493.236 +  register int put_bits = entropy->put_bits;
 493.237 +
 493.238 +  /* if size is 0, caller used an invalid Huffman table entry */
 493.239 +  if (size == 0)
 493.240 +    ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
 493.241 +
 493.242 +  if (entropy->gather_statistics)
 493.243 +    return;			/* do nothing if we're only getting stats */
 493.244 +
 493.245 +  put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
 493.246 +  
 493.247 +  put_bits += size;		/* new number of bits in buffer */
 493.248 +  
 493.249 +  put_buffer <<= 24 - put_bits; /* align incoming bits */
 493.250 +
 493.251 +  put_buffer |= entropy->put_buffer; /* and merge with old buffer contents */
 493.252 +
 493.253 +  while (put_bits >= 8) {
 493.254 +    int c = (int) ((put_buffer >> 16) & 0xFF);
 493.255 +    
 493.256 +    emit_byte(entropy, c);
 493.257 +    if (c == 0xFF) {		/* need to stuff a zero byte? */
 493.258 +      emit_byte(entropy, 0);
 493.259 +    }
 493.260 +    put_buffer <<= 8;
 493.261 +    put_bits -= 8;
 493.262 +  }
 493.263 +
 493.264 +  entropy->put_buffer = put_buffer; /* update variables */
 493.265 +  entropy->put_bits = put_bits;
 493.266 +}
 493.267 +
 493.268 +
 493.269 +LOCAL(void)
 493.270 +flush_bits (phuff_entropy_ptr entropy)
 493.271 +{
 493.272 +  emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */
 493.273 +  entropy->put_buffer = 0;     /* and reset bit-buffer to empty */
 493.274 +  entropy->put_bits = 0;
 493.275 +}
 493.276 +
 493.277 +
 493.278 +/*
 493.279 + * Emit (or just count) a Huffman symbol.
 493.280 + */
 493.281 +
 493.282 +INLINE
 493.283 +LOCAL(void)
 493.284 +emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
 493.285 +{
 493.286 +  if (entropy->gather_statistics)
 493.287 +    entropy->count_ptrs[tbl_no][symbol]++;
 493.288 +  else {
 493.289 +    c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
 493.290 +    emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
 493.291 +  }
 493.292 +}
 493.293 +
 493.294 +
 493.295 +/*
 493.296 + * Emit bits from a correction bit buffer.
 493.297 + */
 493.298 +
 493.299 +LOCAL(void)
 493.300 +emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
 493.301 +		    unsigned int nbits)
 493.302 +{
 493.303 +  if (entropy->gather_statistics)
 493.304 +    return;			/* no real work */
 493.305 +
 493.306 +  while (nbits > 0) {
 493.307 +    emit_bits(entropy, (unsigned int) (*bufstart), 1);
 493.308 +    bufstart++;
 493.309 +    nbits--;
 493.310 +  }
 493.311 +}
 493.312 +
 493.313 +
 493.314 +/*
 493.315 + * Emit any pending EOBRUN symbol.
 493.316 + */
 493.317 +
 493.318 +LOCAL(void)
 493.319 +emit_eobrun (phuff_entropy_ptr entropy)
 493.320 +{
 493.321 +  register int temp, nbits;
 493.322 +
 493.323 +  if (entropy->EOBRUN > 0) {	/* if there is any pending EOBRUN */
 493.324 +    temp = entropy->EOBRUN;
 493.325 +    nbits = 0;
 493.326 +    while ((temp >>= 1))
 493.327 +      nbits++;
 493.328 +    /* safety check: shouldn't happen given limited correction-bit buffer */
 493.329 +    if (nbits > 14)
 493.330 +      ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
 493.331 +
 493.332 +    emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
 493.333 +    if (nbits)
 493.334 +      emit_bits(entropy, entropy->EOBRUN, nbits);
 493.335 +
 493.336 +    entropy->EOBRUN = 0;
 493.337 +
 493.338 +    /* Emit any buffered correction bits */
 493.339 +    emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);
 493.340 +    entropy->BE = 0;
 493.341 +  }
 493.342 +}
 493.343 +
 493.344 +
 493.345 +/*
 493.346 + * Emit a restart marker & resynchronize predictions.
 493.347 + */
 493.348 +
 493.349 +LOCAL(void)
 493.350 +emit_restart (phuff_entropy_ptr entropy, int restart_num)
 493.351 +{
 493.352 +  int ci;
 493.353 +
 493.354 +  emit_eobrun(entropy);
 493.355 +
 493.356 +  if (! entropy->gather_statistics) {
 493.357 +    flush_bits(entropy);
 493.358 +    emit_byte(entropy, 0xFF);
 493.359 +    emit_byte(entropy, JPEG_RST0 + restart_num);
 493.360 +  }
 493.361 +
 493.362 +  if (entropy->cinfo->Ss == 0) {
 493.363 +    /* Re-initialize DC predictions to 0 */
 493.364 +    for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)
 493.365 +      entropy->last_dc_val[ci] = 0;
 493.366 +  } else {
 493.367 +    /* Re-initialize all AC-related fields to 0 */
 493.368 +    entropy->EOBRUN = 0;
 493.369 +    entropy->BE = 0;
 493.370 +  }
 493.371 +}
 493.372 +
 493.373 +
 493.374 +/*
 493.375 + * MCU encoding for DC initial scan (either spectral selection,
 493.376 + * or first pass of successive approximation).
 493.377 + */
 493.378 +
 493.379 +METHODDEF(boolean)
 493.380 +encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 493.381 +{
 493.382 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 493.383 +  register int temp, temp2;
 493.384 +  register int nbits;
 493.385 +  int blkn, ci;
 493.386 +  int Al = cinfo->Al;
 493.387 +  JBLOCKROW block;
 493.388 +  jpeg_component_info * compptr;
 493.389 +  ISHIFT_TEMPS
 493.390 +
 493.391 +  entropy->next_output_byte = cinfo->dest->next_output_byte;
 493.392 +  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
 493.393 +
 493.394 +  /* Emit restart marker if needed */
 493.395 +  if (cinfo->restart_interval)
 493.396 +    if (entropy->restarts_to_go == 0)
 493.397 +      emit_restart(entropy, entropy->next_restart_num);
 493.398 +
 493.399 +  /* Encode the MCU data blocks */
 493.400 +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
 493.401 +    block = MCU_data[blkn];
 493.402 +    ci = cinfo->MCU_membership[blkn];
 493.403 +    compptr = cinfo->cur_comp_info[ci];
 493.404 +
 493.405 +    /* Compute the DC value after the required point transform by Al.
 493.406 +     * This is simply an arithmetic right shift.
 493.407 +     */
 493.408 +    temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
 493.409 +
 493.410 +    /* DC differences are figured on the point-transformed values. */
 493.411 +    temp = temp2 - entropy->last_dc_val[ci];
 493.412 +    entropy->last_dc_val[ci] = temp2;
 493.413 +
 493.414 +    /* Encode the DC coefficient difference per section G.1.2.1 */
 493.415 +    temp2 = temp;
 493.416 +    if (temp < 0) {
 493.417 +      temp = -temp;		/* temp is abs value of input */
 493.418 +      /* For a negative input, want temp2 = bitwise complement of abs(input) */
 493.419 +      /* This code assumes we are on a two's complement machine */
 493.420 +      temp2--;
 493.421 +    }
 493.422 +    
 493.423 +    /* Find the number of bits needed for the magnitude of the coefficient */
 493.424 +    nbits = 0;
 493.425 +    while (temp) {
 493.426 +      nbits++;
 493.427 +      temp >>= 1;
 493.428 +    }
 493.429 +    /* Check for out-of-range coefficient values.
 493.430 +     * Since we're encoding a difference, the range limit is twice as much.
 493.431 +     */
 493.432 +    if (nbits > MAX_COEF_BITS+1)
 493.433 +      ERREXIT(cinfo, JERR_BAD_DCT_COEF);
 493.434 +    
 493.435 +    /* Count/emit the Huffman-coded symbol for the number of bits */
 493.436 +    emit_symbol(entropy, compptr->dc_tbl_no, nbits);
 493.437 +    
 493.438 +    /* Emit that number of bits of the value, if positive, */
 493.439 +    /* or the complement of its magnitude, if negative. */
 493.440 +    if (nbits)			/* emit_bits rejects calls with size 0 */
 493.441 +      emit_bits(entropy, (unsigned int) temp2, nbits);
 493.442 +  }
 493.443 +
 493.444 +  cinfo->dest->next_output_byte = entropy->next_output_byte;
 493.445 +  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
 493.446 +
 493.447 +  /* Update restart-interval state too */
 493.448 +  if (cinfo->restart_interval) {
 493.449 +    if (entropy->restarts_to_go == 0) {
 493.450 +      entropy->restarts_to_go = cinfo->restart_interval;
 493.451 +      entropy->next_restart_num++;
 493.452 +      entropy->next_restart_num &= 7;
 493.453 +    }
 493.454 +    entropy->restarts_to_go--;
 493.455 +  }
 493.456 +
 493.457 +  return TRUE;
 493.458 +}
 493.459 +
 493.460 +
 493.461 +/*
 493.462 + * MCU encoding for AC initial scan (either spectral selection,
 493.463 + * or first pass of successive approximation).
 493.464 + */
 493.465 +
 493.466 +METHODDEF(boolean)
 493.467 +encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 493.468 +{
 493.469 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 493.470 +  register int temp, temp2;
 493.471 +  register int nbits;
 493.472 +  register int r, k;
 493.473 +  int Se = cinfo->Se;
 493.474 +  int Al = cinfo->Al;
 493.475 +  JBLOCKROW block;
 493.476 +
 493.477 +  entropy->next_output_byte = cinfo->dest->next_output_byte;
 493.478 +  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
 493.479 +
 493.480 +  /* Emit restart marker if needed */
 493.481 +  if (cinfo->restart_interval)
 493.482 +    if (entropy->restarts_to_go == 0)
 493.483 +      emit_restart(entropy, entropy->next_restart_num);
 493.484 +
 493.485 +  /* Encode the MCU data block */
 493.486 +  block = MCU_data[0];
 493.487 +
 493.488 +  /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */
 493.489 +  
 493.490 +  r = 0;			/* r = run length of zeros */
 493.491 +   
 493.492 +  for (k = cinfo->Ss; k <= Se; k++) {
 493.493 +    if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
 493.494 +      r++;
 493.495 +      continue;
 493.496 +    }
 493.497 +    /* We must apply the point transform by Al.  For AC coefficients this
 493.498 +     * is an integer division with rounding towards 0.  To do this portably
 493.499 +     * in C, we shift after obtaining the absolute value; so the code is
 493.500 +     * interwoven with finding the abs value (temp) and output bits (temp2).
 493.501 +     */
 493.502 +    if (temp < 0) {
 493.503 +      temp = -temp;		/* temp is abs value of input */
 493.504 +      temp >>= Al;		/* apply the point transform */
 493.505 +      /* For a negative coef, want temp2 = bitwise complement of abs(coef) */
 493.506 +      temp2 = ~temp;
 493.507 +    } else {
 493.508 +      temp >>= Al;		/* apply the point transform */
 493.509 +      temp2 = temp;
 493.510 +    }
 493.511 +    /* Watch out for case that nonzero coef is zero after point transform */
 493.512 +    if (temp == 0) {
 493.513 +      r++;
 493.514 +      continue;
 493.515 +    }
 493.516 +
 493.517 +    /* Emit any pending EOBRUN */
 493.518 +    if (entropy->EOBRUN > 0)
 493.519 +      emit_eobrun(entropy);
 493.520 +    /* if run length > 15, must emit special run-length-16 codes (0xF0) */
 493.521 +    while (r > 15) {
 493.522 +      emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
 493.523 +      r -= 16;
 493.524 +    }
 493.525 +
 493.526 +    /* Find the number of bits needed for the magnitude of the coefficient */
 493.527 +    nbits = 1;			/* there must be at least one 1 bit */
 493.528 +    while ((temp >>= 1))
 493.529 +      nbits++;
 493.530 +    /* Check for out-of-range coefficient values */
 493.531 +    if (nbits > MAX_COEF_BITS)
 493.532 +      ERREXIT(cinfo, JERR_BAD_DCT_COEF);
 493.533 +
 493.534 +    /* Count/emit Huffman symbol for run length / number of bits */
 493.535 +    emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
 493.536 +
 493.537 +    /* Emit that number of bits of the value, if positive, */
 493.538 +    /* or the complement of its magnitude, if negative. */
 493.539 +    emit_bits(entropy, (unsigned int) temp2, nbits);
 493.540 +
 493.541 +    r = 0;			/* reset zero run length */
 493.542 +  }
 493.543 +
 493.544 +  if (r > 0) {			/* If there are trailing zeroes, */
 493.545 +    entropy->EOBRUN++;		/* count an EOB */
 493.546 +    if (entropy->EOBRUN == 0x7FFF)
 493.547 +      emit_eobrun(entropy);	/* force it out to avoid overflow */
 493.548 +  }
 493.549 +
 493.550 +  cinfo->dest->next_output_byte = entropy->next_output_byte;
 493.551 +  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
 493.552 +
 493.553 +  /* Update restart-interval state too */
 493.554 +  if (cinfo->restart_interval) {
 493.555 +    if (entropy->restarts_to_go == 0) {
 493.556 +      entropy->restarts_to_go = cinfo->restart_interval;
 493.557 +      entropy->next_restart_num++;
 493.558 +      entropy->next_restart_num &= 7;
 493.559 +    }
 493.560 +    entropy->restarts_to_go--;
 493.561 +  }
 493.562 +
 493.563 +  return TRUE;
 493.564 +}
 493.565 +
 493.566 +
 493.567 +/*
 493.568 + * MCU encoding for DC successive approximation refinement scan.
 493.569 + * Note: we assume such scans can be multi-component, although the spec
 493.570 + * is not very clear on the point.
 493.571 + */
 493.572 +
 493.573 +METHODDEF(boolean)
 493.574 +encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 493.575 +{
 493.576 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 493.577 +  register int temp;
 493.578 +  int blkn;
 493.579 +  int Al = cinfo->Al;
 493.580 +  JBLOCKROW block;
 493.581 +
 493.582 +  entropy->next_output_byte = cinfo->dest->next_output_byte;
 493.583 +  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
 493.584 +
 493.585 +  /* Emit restart marker if needed */
 493.586 +  if (cinfo->restart_interval)
 493.587 +    if (entropy->restarts_to_go == 0)
 493.588 +      emit_restart(entropy, entropy->next_restart_num);
 493.589 +
 493.590 +  /* Encode the MCU data blocks */
 493.591 +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
 493.592 +    block = MCU_data[blkn];
 493.593 +
 493.594 +    /* We simply emit the Al'th bit of the DC coefficient value. */
 493.595 +    temp = (*block)[0];
 493.596 +    emit_bits(entropy, (unsigned int) (temp >> Al), 1);
 493.597 +  }
 493.598 +
 493.599 +  cinfo->dest->next_output_byte = entropy->next_output_byte;
 493.600 +  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
 493.601 +
 493.602 +  /* Update restart-interval state too */
 493.603 +  if (cinfo->restart_interval) {
 493.604 +    if (entropy->restarts_to_go == 0) {
 493.605 +      entropy->restarts_to_go = cinfo->restart_interval;
 493.606 +      entropy->next_restart_num++;
 493.607 +      entropy->next_restart_num &= 7;
 493.608 +    }
 493.609 +    entropy->restarts_to_go--;
 493.610 +  }
 493.611 +
 493.612 +  return TRUE;
 493.613 +}
 493.614 +
 493.615 +
 493.616 +/*
 493.617 + * MCU encoding for AC successive approximation refinement scan.
 493.618 + */
 493.619 +
 493.620 +METHODDEF(boolean)
 493.621 +encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 493.622 +{
 493.623 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 493.624 +  register int temp;
 493.625 +  register int r, k;
 493.626 +  int EOB;
 493.627 +  char *BR_buffer;
 493.628 +  unsigned int BR;
 493.629 +  int Se = cinfo->Se;
 493.630 +  int Al = cinfo->Al;
 493.631 +  JBLOCKROW block;
 493.632 +  int absvalues[DCTSIZE2];
 493.633 +
 493.634 +  entropy->next_output_byte = cinfo->dest->next_output_byte;
 493.635 +  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
 493.636 +
 493.637 +  /* Emit restart marker if needed */
 493.638 +  if (cinfo->restart_interval)
 493.639 +    if (entropy->restarts_to_go == 0)
 493.640 +      emit_restart(entropy, entropy->next_restart_num);
 493.641 +
 493.642 +  /* Encode the MCU data block */
 493.643 +  block = MCU_data[0];
 493.644 +
 493.645 +  /* It is convenient to make a pre-pass to determine the transformed
 493.646 +   * coefficients' absolute values and the EOB position.
 493.647 +   */
 493.648 +  EOB = 0;
 493.649 +  for (k = cinfo->Ss; k <= Se; k++) {
 493.650 +    temp = (*block)[jpeg_natural_order[k]];
 493.651 +    /* We must apply the point transform by Al.  For AC coefficients this
 493.652 +     * is an integer division with rounding towards 0.  To do this portably
 493.653 +     * in C, we shift after obtaining the absolute value.
 493.654 +     */
 493.655 +    if (temp < 0)
 493.656 +      temp = -temp;		/* temp is abs value of input */
 493.657 +    temp >>= Al;		/* apply the point transform */
 493.658 +    absvalues[k] = temp;	/* save abs value for main pass */
 493.659 +    if (temp == 1)
 493.660 +      EOB = k;			/* EOB = index of last newly-nonzero coef */
 493.661 +  }
 493.662 +
 493.663 +  /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */
 493.664 +  
 493.665 +  r = 0;			/* r = run length of zeros */
 493.666 +  BR = 0;			/* BR = count of buffered bits added now */
 493.667 +  BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */
 493.668 +
 493.669 +  for (k = cinfo->Ss; k <= Se; k++) {
 493.670 +    if ((temp = absvalues[k]) == 0) {
 493.671 +      r++;
 493.672 +      continue;
 493.673 +    }
 493.674 +
 493.675 +    /* Emit any required ZRLs, but not if they can be folded into EOB */
 493.676 +    while (r > 15 && k <= EOB) {
 493.677 +      /* emit any pending EOBRUN and the BE correction bits */
 493.678 +      emit_eobrun(entropy);
 493.679 +      /* Emit ZRL */
 493.680 +      emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
 493.681 +      r -= 16;
 493.682 +      /* Emit buffered correction bits that must be associated with ZRL */
 493.683 +      emit_buffered_bits(entropy, BR_buffer, BR);
 493.684 +      BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
 493.685 +      BR = 0;
 493.686 +    }
 493.687 +
 493.688 +    /* If the coef was previously nonzero, it only needs a correction bit.
 493.689 +     * NOTE: a straight translation of the spec's figure G.7 would suggest
 493.690 +     * that we also need to test r > 15.  But if r > 15, we can only get here
 493.691 +     * if k > EOB, which implies that this coefficient is not 1.
 493.692 +     */
 493.693 +    if (temp > 1) {
 493.694 +      /* The correction bit is the next bit of the absolute value. */
 493.695 +      BR_buffer[BR++] = (char) (temp & 1);
 493.696 +      continue;
 493.697 +    }
 493.698 +
 493.699 +    /* Emit any pending EOBRUN and the BE correction bits */
 493.700 +    emit_eobrun(entropy);
 493.701 +
 493.702 +    /* Count/emit Huffman symbol for run length / number of bits */
 493.703 +    emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1);
 493.704 +
 493.705 +    /* Emit output bit for newly-nonzero coef */
 493.706 +    temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1;
 493.707 +    emit_bits(entropy, (unsigned int) temp, 1);
 493.708 +
 493.709 +    /* Emit buffered correction bits that must be associated with this code */
 493.710 +    emit_buffered_bits(entropy, BR_buffer, BR);
 493.711 +    BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
 493.712 +    BR = 0;
 493.713 +    r = 0;			/* reset zero run length */
 493.714 +  }
 493.715 +
 493.716 +  if (r > 0 || BR > 0) {	/* If there are trailing zeroes, */
 493.717 +    entropy->EOBRUN++;		/* count an EOB */
 493.718 +    entropy->BE += BR;		/* concat my correction bits to older ones */
 493.719 +    /* We force out the EOB if we risk either:
 493.720 +     * 1. overflow of the EOB counter;
 493.721 +     * 2. overflow of the correction bit buffer during the next MCU.
 493.722 +     */
 493.723 +    if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1))
 493.724 +      emit_eobrun(entropy);
 493.725 +  }
 493.726 +
 493.727 +  cinfo->dest->next_output_byte = entropy->next_output_byte;
 493.728 +  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
 493.729 +
 493.730 +  /* Update restart-interval state too */
 493.731 +  if (cinfo->restart_interval) {
 493.732 +    if (entropy->restarts_to_go == 0) {
 493.733 +      entropy->restarts_to_go = cinfo->restart_interval;
 493.734 +      entropy->next_restart_num++;
 493.735 +      entropy->next_restart_num &= 7;
 493.736 +    }
 493.737 +    entropy->restarts_to_go--;
 493.738 +  }
 493.739 +
 493.740 +  return TRUE;
 493.741 +}
 493.742 +
 493.743 +
 493.744 +/*
 493.745 + * Finish up at the end of a Huffman-compressed progressive scan.
 493.746 + */
 493.747 +
 493.748 +METHODDEF(void)
 493.749 +finish_pass_phuff (j_compress_ptr cinfo)
 493.750 +{   
 493.751 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 493.752 +
 493.753 +  entropy->next_output_byte = cinfo->dest->next_output_byte;
 493.754 +  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
 493.755 +
 493.756 +  /* Flush out any buffered data */
 493.757 +  emit_eobrun(entropy);
 493.758 +  flush_bits(entropy);
 493.759 +
 493.760 +  cinfo->dest->next_output_byte = entropy->next_output_byte;
 493.761 +  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
 493.762 +}
 493.763 +
 493.764 +
 493.765 +/*
 493.766 + * Finish up a statistics-gathering pass and create the new Huffman tables.
 493.767 + */
 493.768 +
 493.769 +METHODDEF(void)
 493.770 +finish_pass_gather_phuff (j_compress_ptr cinfo)
 493.771 +{
 493.772 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 493.773 +  boolean is_DC_band;
 493.774 +  int ci, tbl;
 493.775 +  jpeg_component_info * compptr;
 493.776 +  JHUFF_TBL **htblptr;
 493.777 +  boolean did[NUM_HUFF_TBLS];
 493.778 +
 493.779 +  /* Flush out buffered data (all we care about is counting the EOB symbol) */
 493.780 +  emit_eobrun(entropy);
 493.781 +
 493.782 +  is_DC_band = (cinfo->Ss == 0);
 493.783 +
 493.784 +  /* It's important not to apply jpeg_gen_optimal_table more than once
 493.785 +   * per table, because it clobbers the input frequency counts!
 493.786 +   */
 493.787 +  MEMZERO(did, SIZEOF(did));
 493.788 +
 493.789 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 493.790 +    compptr = cinfo->cur_comp_info[ci];
 493.791 +    if (is_DC_band) {
 493.792 +      if (cinfo->Ah != 0)	/* DC refinement needs no table */
 493.793 +	continue;
 493.794 +      tbl = compptr->dc_tbl_no;
 493.795 +    } else {
 493.796 +      tbl = compptr->ac_tbl_no;
 493.797 +    }
 493.798 +    if (! did[tbl]) {
 493.799 +      if (is_DC_band)
 493.800 +        htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
 493.801 +      else
 493.802 +        htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
 493.803 +      if (*htblptr == NULL)
 493.804 +        *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
 493.805 +      jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]);
 493.806 +      did[tbl] = TRUE;
 493.807 +    }
 493.808 +  }
 493.809 +}
 493.810 +
 493.811 +
 493.812 +/*
 493.813 + * Module initialization routine for progressive Huffman entropy encoding.
 493.814 + */
 493.815 +
 493.816 +GLOBAL(void)
 493.817 +jinit_phuff_encoder (j_compress_ptr cinfo)
 493.818 +{
 493.819 +  phuff_entropy_ptr entropy;
 493.820 +  int i;
 493.821 +
 493.822 +  entropy = (phuff_entropy_ptr)
 493.823 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 493.824 +				SIZEOF(phuff_entropy_encoder));
 493.825 +  cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
 493.826 +  entropy->pub.start_pass = start_pass_phuff;
 493.827 +
 493.828 +  /* Mark tables unallocated */
 493.829 +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
 493.830 +    entropy->derived_tbls[i] = NULL;
 493.831 +    entropy->count_ptrs[i] = NULL;
 493.832 +  }
 493.833 +  entropy->bit_buffer = NULL;	/* needed only in AC refinement scan */
 493.834 +}
 493.835 +
 493.836 +#endif /* C_PROGRESSIVE_SUPPORTED */
   494.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   494.2 +++ b/libs/libjpeg/jcprepct.c	Sat Feb 01 19:58:19 2014 +0200
   494.3 @@ -0,0 +1,354 @@
   494.4 +/*
   494.5 + * jcprepct.c
   494.6 + *
   494.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   494.8 + * This file is part of the Independent JPEG Group's software.
   494.9 + * For conditions of distribution and use, see the accompanying README file.
  494.10 + *
  494.11 + * This file contains the compression preprocessing controller.
  494.12 + * This controller manages the color conversion, downsampling,
  494.13 + * and edge expansion steps.
  494.14 + *
  494.15 + * Most of the complexity here is associated with buffering input rows
  494.16 + * as required by the downsampler.  See the comments at the head of
  494.17 + * jcsample.c for the downsampler's needs.
  494.18 + */
  494.19 +
  494.20 +#define JPEG_INTERNALS
  494.21 +#include "jinclude.h"
  494.22 +#include "jpeglib.h"
  494.23 +
  494.24 +
  494.25 +/* At present, jcsample.c can request context rows only for smoothing.
  494.26 + * In the future, we might also need context rows for CCIR601 sampling
  494.27 + * or other more-complex downsampling procedures.  The code to support
  494.28 + * context rows should be compiled only if needed.
  494.29 + */
  494.30 +#ifdef INPUT_SMOOTHING_SUPPORTED
  494.31 +#define CONTEXT_ROWS_SUPPORTED
  494.32 +#endif
  494.33 +
  494.34 +
  494.35 +/*
  494.36 + * For the simple (no-context-row) case, we just need to buffer one
  494.37 + * row group's worth of pixels for the downsampling step.  At the bottom of
  494.38 + * the image, we pad to a full row group by replicating the last pixel row.
  494.39 + * The downsampler's last output row is then replicated if needed to pad
  494.40 + * out to a full iMCU row.
  494.41 + *
  494.42 + * When providing context rows, we must buffer three row groups' worth of
  494.43 + * pixels.  Three row groups are physically allocated, but the row pointer
  494.44 + * arrays are made five row groups high, with the extra pointers above and
  494.45 + * below "wrapping around" to point to the last and first real row groups.
  494.46 + * This allows the downsampler to access the proper context rows.
  494.47 + * At the top and bottom of the image, we create dummy context rows by
  494.48 + * copying the first or last real pixel row.  This copying could be avoided
  494.49 + * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
  494.50 + * trouble on the compression side.
  494.51 + */
  494.52 +
  494.53 +
  494.54 +/* Private buffer controller object */
  494.55 +
  494.56 +typedef struct {
  494.57 +  struct jpeg_c_prep_controller pub; /* public fields */
  494.58 +
  494.59 +  /* Downsampling input buffer.  This buffer holds color-converted data
  494.60 +   * until we have enough to do a downsample step.
  494.61 +   */
  494.62 +  JSAMPARRAY color_buf[MAX_COMPONENTS];
  494.63 +
  494.64 +  JDIMENSION rows_to_go;	/* counts rows remaining in source image */
  494.65 +  int next_buf_row;		/* index of next row to store in color_buf */
  494.66 +
  494.67 +#ifdef CONTEXT_ROWS_SUPPORTED	/* only needed for context case */
  494.68 +  int this_row_group;		/* starting row index of group to process */
  494.69 +  int next_buf_stop;		/* downsample when we reach this index */
  494.70 +#endif
  494.71 +} my_prep_controller;
  494.72 +
  494.73 +typedef my_prep_controller * my_prep_ptr;
  494.74 +
  494.75 +
  494.76 +/*
  494.77 + * Initialize for a processing pass.
  494.78 + */
  494.79 +
  494.80 +METHODDEF(void)
  494.81 +start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
  494.82 +{
  494.83 +  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
  494.84 +
  494.85 +  if (pass_mode != JBUF_PASS_THRU)
  494.86 +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  494.87 +
  494.88 +  /* Initialize total-height counter for detecting bottom of image */
  494.89 +  prep->rows_to_go = cinfo->image_height;
  494.90 +  /* Mark the conversion buffer empty */
  494.91 +  prep->next_buf_row = 0;
  494.92 +#ifdef CONTEXT_ROWS_SUPPORTED
  494.93 +  /* Preset additional state variables for context mode.
  494.94 +   * These aren't used in non-context mode, so we needn't test which mode.
  494.95 +   */
  494.96 +  prep->this_row_group = 0;
  494.97 +  /* Set next_buf_stop to stop after two row groups have been read in. */
  494.98 +  prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
  494.99 +#endif
 494.100 +}
 494.101 +
 494.102 +
 494.103 +/*
 494.104 + * Expand an image vertically from height input_rows to height output_rows,
 494.105 + * by duplicating the bottom row.
 494.106 + */
 494.107 +
 494.108 +LOCAL(void)
 494.109 +expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
 494.110 +		    int input_rows, int output_rows)
 494.111 +{
 494.112 +  register int row;
 494.113 +
 494.114 +  for (row = input_rows; row < output_rows; row++) {
 494.115 +    jcopy_sample_rows(image_data, input_rows-1, image_data, row,
 494.116 +		      1, num_cols);
 494.117 +  }
 494.118 +}
 494.119 +
 494.120 +
 494.121 +/*
 494.122 + * Process some data in the simple no-context case.
 494.123 + *
 494.124 + * Preprocessor output data is counted in "row groups".  A row group
 494.125 + * is defined to be v_samp_factor sample rows of each component.
 494.126 + * Downsampling will produce this much data from each max_v_samp_factor
 494.127 + * input rows.
 494.128 + */
 494.129 +
 494.130 +METHODDEF(void)
 494.131 +pre_process_data (j_compress_ptr cinfo,
 494.132 +		  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
 494.133 +		  JDIMENSION in_rows_avail,
 494.134 +		  JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
 494.135 +		  JDIMENSION out_row_groups_avail)
 494.136 +{
 494.137 +  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
 494.138 +  int numrows, ci;
 494.139 +  JDIMENSION inrows;
 494.140 +  jpeg_component_info * compptr;
 494.141 +
 494.142 +  while (*in_row_ctr < in_rows_avail &&
 494.143 +	 *out_row_group_ctr < out_row_groups_avail) {
 494.144 +    /* Do color conversion to fill the conversion buffer. */
 494.145 +    inrows = in_rows_avail - *in_row_ctr;
 494.146 +    numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
 494.147 +    numrows = (int) MIN((JDIMENSION) numrows, inrows);
 494.148 +    (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
 494.149 +				       prep->color_buf,
 494.150 +				       (JDIMENSION) prep->next_buf_row,
 494.151 +				       numrows);
 494.152 +    *in_row_ctr += numrows;
 494.153 +    prep->next_buf_row += numrows;
 494.154 +    prep->rows_to_go -= numrows;
 494.155 +    /* If at bottom of image, pad to fill the conversion buffer. */
 494.156 +    if (prep->rows_to_go == 0 &&
 494.157 +	prep->next_buf_row < cinfo->max_v_samp_factor) {
 494.158 +      for (ci = 0; ci < cinfo->num_components; ci++) {
 494.159 +	expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
 494.160 +			   prep->next_buf_row, cinfo->max_v_samp_factor);
 494.161 +      }
 494.162 +      prep->next_buf_row = cinfo->max_v_samp_factor;
 494.163 +    }
 494.164 +    /* If we've filled the conversion buffer, empty it. */
 494.165 +    if (prep->next_buf_row == cinfo->max_v_samp_factor) {
 494.166 +      (*cinfo->downsample->downsample) (cinfo,
 494.167 +					prep->color_buf, (JDIMENSION) 0,
 494.168 +					output_buf, *out_row_group_ctr);
 494.169 +      prep->next_buf_row = 0;
 494.170 +      (*out_row_group_ctr)++;
 494.171 +    }
 494.172 +    /* If at bottom of image, pad the output to a full iMCU height.
 494.173 +     * Note we assume the caller is providing a one-iMCU-height output buffer!
 494.174 +     */
 494.175 +    if (prep->rows_to_go == 0 &&
 494.176 +	*out_row_group_ctr < out_row_groups_avail) {
 494.177 +      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 494.178 +	   ci++, compptr++) {
 494.179 +	expand_bottom_edge(output_buf[ci],
 494.180 +			   compptr->width_in_blocks * DCTSIZE,
 494.181 +			   (int) (*out_row_group_ctr * compptr->v_samp_factor),
 494.182 +			   (int) (out_row_groups_avail * compptr->v_samp_factor));
 494.183 +      }
 494.184 +      *out_row_group_ctr = out_row_groups_avail;
 494.185 +      break;			/* can exit outer loop without test */
 494.186 +    }
 494.187 +  }
 494.188 +}
 494.189 +
 494.190 +
 494.191 +#ifdef CONTEXT_ROWS_SUPPORTED
 494.192 +
 494.193 +/*
 494.194 + * Process some data in the context case.
 494.195 + */
 494.196 +
 494.197 +METHODDEF(void)
 494.198 +pre_process_context (j_compress_ptr cinfo,
 494.199 +		     JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
 494.200 +		     JDIMENSION in_rows_avail,
 494.201 +		     JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
 494.202 +		     JDIMENSION out_row_groups_avail)
 494.203 +{
 494.204 +  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
 494.205 +  int numrows, ci;
 494.206 +  int buf_height = cinfo->max_v_samp_factor * 3;
 494.207 +  JDIMENSION inrows;
 494.208 +
 494.209 +  while (*out_row_group_ctr < out_row_groups_avail) {
 494.210 +    if (*in_row_ctr < in_rows_avail) {
 494.211 +      /* Do color conversion to fill the conversion buffer. */
 494.212 +      inrows = in_rows_avail - *in_row_ctr;
 494.213 +      numrows = prep->next_buf_stop - prep->next_buf_row;
 494.214 +      numrows = (int) MIN((JDIMENSION) numrows, inrows);
 494.215 +      (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
 494.216 +					 prep->color_buf,
 494.217 +					 (JDIMENSION) prep->next_buf_row,
 494.218 +					 numrows);
 494.219 +      /* Pad at top of image, if first time through */
 494.220 +      if (prep->rows_to_go == cinfo->image_height) {
 494.221 +	for (ci = 0; ci < cinfo->num_components; ci++) {
 494.222 +	  int row;
 494.223 +	  for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
 494.224 +	    jcopy_sample_rows(prep->color_buf[ci], 0,
 494.225 +			      prep->color_buf[ci], -row,
 494.226 +			      1, cinfo->image_width);
 494.227 +	  }
 494.228 +	}
 494.229 +      }
 494.230 +      *in_row_ctr += numrows;
 494.231 +      prep->next_buf_row += numrows;
 494.232 +      prep->rows_to_go -= numrows;
 494.233 +    } else {
 494.234 +      /* Return for more data, unless we are at the bottom of the image. */
 494.235 +      if (prep->rows_to_go != 0)
 494.236 +	break;
 494.237 +      /* When at bottom of image, pad to fill the conversion buffer. */
 494.238 +      if (prep->next_buf_row < prep->next_buf_stop) {
 494.239 +	for (ci = 0; ci < cinfo->num_components; ci++) {
 494.240 +	  expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
 494.241 +			     prep->next_buf_row, prep->next_buf_stop);
 494.242 +	}
 494.243 +	prep->next_buf_row = prep->next_buf_stop;
 494.244 +      }
 494.245 +    }
 494.246 +    /* If we've gotten enough data, downsample a row group. */
 494.247 +    if (prep->next_buf_row == prep->next_buf_stop) {
 494.248 +      (*cinfo->downsample->downsample) (cinfo,
 494.249 +					prep->color_buf,
 494.250 +					(JDIMENSION) prep->this_row_group,
 494.251 +					output_buf, *out_row_group_ctr);
 494.252 +      (*out_row_group_ctr)++;
 494.253 +      /* Advance pointers with wraparound as necessary. */
 494.254 +      prep->this_row_group += cinfo->max_v_samp_factor;
 494.255 +      if (prep->this_row_group >= buf_height)
 494.256 +	prep->this_row_group = 0;
 494.257 +      if (prep->next_buf_row >= buf_height)
 494.258 +	prep->next_buf_row = 0;
 494.259 +      prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
 494.260 +    }
 494.261 +  }
 494.262 +}
 494.263 +
 494.264 +
 494.265 +/*
 494.266 + * Create the wrapped-around downsampling input buffer needed for context mode.
 494.267 + */
 494.268 +
 494.269 +LOCAL(void)
 494.270 +create_context_buffer (j_compress_ptr cinfo)
 494.271 +{
 494.272 +  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
 494.273 +  int rgroup_height = cinfo->max_v_samp_factor;
 494.274 +  int ci, i;
 494.275 +  jpeg_component_info * compptr;
 494.276 +  JSAMPARRAY true_buffer, fake_buffer;
 494.277 +
 494.278 +  /* Grab enough space for fake row pointers for all the components;
 494.279 +   * we need five row groups' worth of pointers for each component.
 494.280 +   */
 494.281 +  fake_buffer = (JSAMPARRAY)
 494.282 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 494.283 +				(cinfo->num_components * 5 * rgroup_height) *
 494.284 +				SIZEOF(JSAMPROW));
 494.285 +
 494.286 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 494.287 +       ci++, compptr++) {
 494.288 +    /* Allocate the actual buffer space (3 row groups) for this component.
 494.289 +     * We make the buffer wide enough to allow the downsampler to edge-expand
 494.290 +     * horizontally within the buffer, if it so chooses.
 494.291 +     */
 494.292 +    true_buffer = (*cinfo->mem->alloc_sarray)
 494.293 +      ((j_common_ptr) cinfo, JPOOL_IMAGE,
 494.294 +       (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
 494.295 +		      cinfo->max_h_samp_factor) / compptr->h_samp_factor),
 494.296 +       (JDIMENSION) (3 * rgroup_height));
 494.297 +    /* Copy true buffer row pointers into the middle of the fake row array */
 494.298 +    MEMCOPY(fake_buffer + rgroup_height, true_buffer,
 494.299 +	    3 * rgroup_height * SIZEOF(JSAMPROW));
 494.300 +    /* Fill in the above and below wraparound pointers */
 494.301 +    for (i = 0; i < rgroup_height; i++) {
 494.302 +      fake_buffer[i] = true_buffer[2 * rgroup_height + i];
 494.303 +      fake_buffer[4 * rgroup_height + i] = true_buffer[i];
 494.304 +    }
 494.305 +    prep->color_buf[ci] = fake_buffer + rgroup_height;
 494.306 +    fake_buffer += 5 * rgroup_height; /* point to space for next component */
 494.307 +  }
 494.308 +}
 494.309 +
 494.310 +#endif /* CONTEXT_ROWS_SUPPORTED */
 494.311 +
 494.312 +
 494.313 +/*
 494.314 + * Initialize preprocessing controller.
 494.315 + */
 494.316 +
 494.317 +GLOBAL(void)
 494.318 +jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
 494.319 +{
 494.320 +  my_prep_ptr prep;
 494.321 +  int ci;
 494.322 +  jpeg_component_info * compptr;
 494.323 +
 494.324 +  if (need_full_buffer)		/* safety check */
 494.325 +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 494.326 +
 494.327 +  prep = (my_prep_ptr)
 494.328 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 494.329 +				SIZEOF(my_prep_controller));
 494.330 +  cinfo->prep = (struct jpeg_c_prep_controller *) prep;
 494.331 +  prep->pub.start_pass = start_pass_prep;
 494.332 +
 494.333 +  /* Allocate the color conversion buffer.
 494.334 +   * We make the buffer wide enough to allow the downsampler to edge-expand
 494.335 +   * horizontally within the buffer, if it so chooses.
 494.336 +   */
 494.337 +  if (cinfo->downsample->need_context_rows) {
 494.338 +    /* Set up to provide context rows */
 494.339 +#ifdef CONTEXT_ROWS_SUPPORTED
 494.340 +    prep->pub.pre_process_data = pre_process_context;
 494.341 +    create_context_buffer(cinfo);
 494.342 +#else
 494.343 +    ERREXIT(cinfo, JERR_NOT_COMPILED);
 494.344 +#endif
 494.345 +  } else {
 494.346 +    /* No context, just make it tall enough for one row group */
 494.347 +    prep->pub.pre_process_data = pre_process_data;
 494.348 +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 494.349 +	 ci++, compptr++) {
 494.350 +      prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
 494.351 +	((j_common_ptr) cinfo, JPOOL_IMAGE,
 494.352 +	 (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
 494.353 +			cinfo->max_h_samp_factor) / compptr->h_samp_factor),
 494.354 +	 (JDIMENSION) cinfo->max_v_samp_factor);
 494.355 +    }
 494.356 +  }
 494.357 +}
   495.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   495.2 +++ b/libs/libjpeg/jcsample.c	Sat Feb 01 19:58:19 2014 +0200
   495.3 @@ -0,0 +1,519 @@
   495.4 +/*
   495.5 + * jcsample.c
   495.6 + *
   495.7 + * Copyright (C) 1991-1996, Thomas G. Lane.
   495.8 + * This file is part of the Independent JPEG Group's software.
   495.9 + * For conditions of distribution and use, see the accompanying README file.
  495.10 + *
  495.11 + * This file contains downsampling routines.
  495.12 + *
  495.13 + * Downsampling input data is counted in "row groups".  A row group
  495.14 + * is defined to be max_v_samp_factor pixel rows of each component,
  495.15 + * from which the downsampler produces v_samp_factor sample rows.
  495.16 + * A single row group is processed in each call to the downsampler module.
  495.17 + *
  495.18 + * The downsampler is responsible for edge-expansion of its output data
  495.19 + * to fill an integral number of DCT blocks horizontally.  The source buffer
  495.20 + * may be modified if it is helpful for this purpose (the source buffer is
  495.21 + * allocated wide enough to correspond to the desired output width).
  495.22 + * The caller (the prep controller) is responsible for vertical padding.
  495.23 + *
  495.24 + * The downsampler may request "context rows" by setting need_context_rows
  495.25 + * during startup.  In this case, the input arrays will contain at least
  495.26 + * one row group's worth of pixels above and below the passed-in data;
  495.27 + * the caller will create dummy rows at image top and bottom by replicating
  495.28 + * the first or last real pixel row.
  495.29 + *
  495.30 + * An excellent reference for image resampling is
  495.31 + *   Digital Image Warping, George Wolberg, 1990.
  495.32 + *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
  495.33 + *
  495.34 + * The downsampling algorithm used here is a simple average of the source
  495.35 + * pixels covered by the output pixel.  The hi-falutin sampling literature
  495.36 + * refers to this as a "box filter".  In general the characteristics of a box
  495.37 + * filter are not very good, but for the specific cases we normally use (1:1
  495.38 + * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not
  495.39 + * nearly so bad.  If you intend to use other sampling ratios, you'd be well
  495.40 + * advised to improve this code.
  495.41 + *
  495.42 + * A simple input-smoothing capability is provided.  This is mainly intended
  495.43 + * for cleaning up color-dithered GIF input files (if you find it inadequate,
  495.44 + * we suggest using an external filtering program such as pnmconvol).  When
  495.45 + * enabled, each input pixel P is replaced by a weighted sum of itself and its
  495.46 + * eight neighbors.  P's weight is 1-8*SF and each neighbor's weight is SF,
  495.47 + * where SF = (smoothing_factor / 1024).
  495.48 + * Currently, smoothing is only supported for 2h2v sampling factors.
  495.49 + */
  495.50 +
  495.51 +#define JPEG_INTERNALS
  495.52 +#include "jinclude.h"
  495.53 +#include "jpeglib.h"
  495.54 +
  495.55 +
  495.56 +/* Pointer to routine to downsample a single component */
  495.57 +typedef JMETHOD(void, downsample1_ptr,
  495.58 +		(j_compress_ptr cinfo, jpeg_component_info * compptr,
  495.59 +		 JSAMPARRAY input_data, JSAMPARRAY output_data));
  495.60 +
  495.61 +/* Private subobject */
  495.62 +
  495.63 +typedef struct {
  495.64 +  struct jpeg_downsampler pub;	/* public fields */
  495.65 +
  495.66 +  /* Downsampling method pointers, one per component */
  495.67 +  downsample1_ptr methods[MAX_COMPONENTS];
  495.68 +} my_downsampler;
  495.69 +
  495.70 +typedef my_downsampler * my_downsample_ptr;
  495.71 +
  495.72 +
  495.73 +/*
  495.74 + * Initialize for a downsampling pass.
  495.75 + */
  495.76 +
  495.77 +METHODDEF(void)
  495.78 +start_pass_downsample (j_compress_ptr cinfo)
  495.79 +{
  495.80 +  /* no work for now */
  495.81 +}
  495.82 +
  495.83 +
  495.84 +/*
  495.85 + * Expand a component horizontally from width input_cols to width output_cols,
  495.86 + * by duplicating the rightmost samples.
  495.87 + */
  495.88 +
  495.89 +LOCAL(void)
  495.90 +expand_right_edge (JSAMPARRAY image_data, int num_rows,
  495.91 +		   JDIMENSION input_cols, JDIMENSION output_cols)
  495.92 +{
  495.93 +  register JSAMPROW ptr;
  495.94 +  register JSAMPLE pixval;
  495.95 +  register int count;
  495.96 +  int row;
  495.97 +  int numcols = (int) (output_cols - input_cols);
  495.98 +
  495.99 +  if (numcols > 0) {
 495.100 +    for (row = 0; row < num_rows; row++) {
 495.101 +      ptr = image_data[row] + input_cols;
 495.102 +      pixval = ptr[-1];		/* don't need GETJSAMPLE() here */
 495.103 +      for (count = numcols; count > 0; count--)
 495.104 +	*ptr++ = pixval;
 495.105 +    }
 495.106 +  }
 495.107 +}
 495.108 +
 495.109 +
 495.110 +/*
 495.111 + * Do downsampling for a whole row group (all components).
 495.112 + *
 495.113 + * In this version we simply downsample each component independently.
 495.114 + */
 495.115 +
 495.116 +METHODDEF(void)
 495.117 +sep_downsample (j_compress_ptr cinfo,
 495.118 +		JSAMPIMAGE input_buf, JDIMENSION in_row_index,
 495.119 +		JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)
 495.120 +{
 495.121 +  my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample;
 495.122 +  int ci;
 495.123 +  jpeg_component_info * compptr;
 495.124 +  JSAMPARRAY in_ptr, out_ptr;
 495.125 +
 495.126 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 495.127 +       ci++, compptr++) {
 495.128 +    in_ptr = input_buf[ci] + in_row_index;
 495.129 +    out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor);
 495.130 +    (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
 495.131 +  }
 495.132 +}
 495.133 +
 495.134 +
 495.135 +/*
 495.136 + * Downsample pixel values of a single component.
 495.137 + * One row group is processed per call.
 495.138 + * This version handles arbitrary integral sampling ratios, without smoothing.
 495.139 + * Note that this version is not actually used for customary sampling ratios.
 495.140 + */
 495.141 +
 495.142 +METHODDEF(void)
 495.143 +int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
 495.144 +		JSAMPARRAY input_data, JSAMPARRAY output_data)
 495.145 +{
 495.146 +  int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
 495.147 +  JDIMENSION outcol, outcol_h;	/* outcol_h == outcol*h_expand */
 495.148 +  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
 495.149 +  JSAMPROW inptr, outptr;
 495.150 +  INT32 outvalue;
 495.151 +
 495.152 +  h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
 495.153 +  v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
 495.154 +  numpix = h_expand * v_expand;
 495.155 +  numpix2 = numpix/2;
 495.156 +
 495.157 +  /* Expand input data enough to let all the output samples be generated
 495.158 +   * by the standard loop.  Special-casing padded output would be more
 495.159 +   * efficient.
 495.160 +   */
 495.161 +  expand_right_edge(input_data, cinfo->max_v_samp_factor,
 495.162 +		    cinfo->image_width, output_cols * h_expand);
 495.163 +
 495.164 +  inrow = 0;
 495.165 +  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
 495.166 +    outptr = output_data[outrow];
 495.167 +    for (outcol = 0, outcol_h = 0; outcol < output_cols;
 495.168 +	 outcol++, outcol_h += h_expand) {
 495.169 +      outvalue = 0;
 495.170 +      for (v = 0; v < v_expand; v++) {
 495.171 +	inptr = input_data[inrow+v] + outcol_h;
 495.172 +	for (h = 0; h < h_expand; h++) {
 495.173 +	  outvalue += (INT32) GETJSAMPLE(*inptr++);
 495.174 +	}
 495.175 +      }
 495.176 +      *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
 495.177 +    }
 495.178 +    inrow += v_expand;
 495.179 +  }
 495.180 +}
 495.181 +
 495.182 +
 495.183 +/*
 495.184 + * Downsample pixel values of a single component.
 495.185 + * This version handles the special case of a full-size component,
 495.186 + * without smoothing.
 495.187 + */
 495.188 +
 495.189 +METHODDEF(void)
 495.190 +fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
 495.191 +		     JSAMPARRAY input_data, JSAMPARRAY output_data)
 495.192 +{
 495.193 +  /* Copy the data */
 495.194 +  jcopy_sample_rows(input_data, 0, output_data, 0,
 495.195 +		    cinfo->max_v_samp_factor, cinfo->image_width);
 495.196 +  /* Edge-expand */
 495.197 +  expand_right_edge(output_data, cinfo->max_v_samp_factor,
 495.198 +		    cinfo->image_width, compptr->width_in_blocks * DCTSIZE);
 495.199 +}
 495.200 +
 495.201 +
 495.202 +/*
 495.203 + * Downsample pixel values of a single component.
 495.204 + * This version handles the common case of 2:1 horizontal and 1:1 vertical,
 495.205 + * without smoothing.
 495.206 + *
 495.207 + * A note about the "bias" calculations: when rounding fractional values to
 495.208 + * integer, we do not want to always round 0.5 up to the next integer.
 495.209 + * If we did that, we'd introduce a noticeable bias towards larger values.
 495.210 + * Instead, this code is arranged so that 0.5 will be rounded up or down at
 495.211 + * alternate pixel locations (a simple ordered dither pattern).
 495.212 + */
 495.213 +
 495.214 +METHODDEF(void)
 495.215 +h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
 495.216 +		 JSAMPARRAY input_data, JSAMPARRAY output_data)
 495.217 +{
 495.218 +  int outrow;
 495.219 +  JDIMENSION outcol;
 495.220 +  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
 495.221 +  register JSAMPROW inptr, outptr;
 495.222 +  register int bias;
 495.223 +
 495.224 +  /* Expand input data enough to let all the output samples be generated
 495.225 +   * by the standard loop.  Special-casing padded output would be more
 495.226 +   * efficient.
 495.227 +   */
 495.228 +  expand_right_edge(input_data, cinfo->max_v_samp_factor,
 495.229 +		    cinfo->image_width, output_cols * 2);
 495.230 +
 495.231 +  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
 495.232 +    outptr = output_data[outrow];
 495.233 +    inptr = input_data[outrow];
 495.234 +    bias = 0;			/* bias = 0,1,0,1,... for successive samples */
 495.235 +    for (outcol = 0; outcol < output_cols; outcol++) {
 495.236 +      *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
 495.237 +			      + bias) >> 1);
 495.238 +      bias ^= 1;		/* 0=>1, 1=>0 */
 495.239 +      inptr += 2;
 495.240 +    }
 495.241 +  }
 495.242 +}
 495.243 +
 495.244 +
 495.245 +/*
 495.246 + * Downsample pixel values of a single component.
 495.247 + * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
 495.248 + * without smoothing.
 495.249 + */
 495.250 +
 495.251 +METHODDEF(void)
 495.252 +h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
 495.253 +		 JSAMPARRAY input_data, JSAMPARRAY output_data)
 495.254 +{
 495.255 +  int inrow, outrow;
 495.256 +  JDIMENSION outcol;
 495.257 +  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
 495.258 +  register JSAMPROW inptr0, inptr1, outptr;
 495.259 +  register int bias;
 495.260 +
 495.261 +  /* Expand input data enough to let all the output samples be generated
 495.262 +   * by the standard loop.  Special-casing padded output would be more
 495.263 +   * efficient.
 495.264 +   */
 495.265 +  expand_right_edge(input_data, cinfo->max_v_samp_factor,
 495.266 +		    cinfo->image_width, output_cols * 2);
 495.267 +
 495.268 +  inrow = 0;
 495.269 +  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
 495.270 +    outptr = output_data[outrow];
 495.271 +    inptr0 = input_data[inrow];
 495.272 +    inptr1 = input_data[inrow+1];
 495.273 +    bias = 1;			/* bias = 1,2,1,2,... for successive samples */
 495.274 +    for (outcol = 0; outcol < output_cols; outcol++) {
 495.275 +      *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
 495.276 +			      GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1])
 495.277 +			      + bias) >> 2);
 495.278 +      bias ^= 3;		/* 1=>2, 2=>1 */
 495.279 +      inptr0 += 2; inptr1 += 2;
 495.280 +    }
 495.281 +    inrow += 2;
 495.282 +  }
 495.283 +}
 495.284 +
 495.285 +
 495.286 +#ifdef INPUT_SMOOTHING_SUPPORTED
 495.287 +
 495.288 +/*
 495.289 + * Downsample pixel values of a single component.
 495.290 + * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
 495.291 + * with smoothing.  One row of context is required.
 495.292 + */
 495.293 +
 495.294 +METHODDEF(void)
 495.295 +h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
 495.296 +			JSAMPARRAY input_data, JSAMPARRAY output_data)
 495.297 +{
 495.298 +  int inrow, outrow;
 495.299 +  JDIMENSION colctr;
 495.300 +  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
 495.301 +  register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
 495.302 +  INT32 membersum, neighsum, memberscale, neighscale;
 495.303 +
 495.304 +  /* Expand input data enough to let all the output samples be generated
 495.305 +   * by the standard loop.  Special-casing padded output would be more
 495.306 +   * efficient.
 495.307 +   */
 495.308 +  expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
 495.309 +		    cinfo->image_width, output_cols * 2);
 495.310 +
 495.311 +  /* We don't bother to form the individual "smoothed" input pixel values;
 495.312 +   * we can directly compute the output which is the average of the four
 495.313 +   * smoothed values.  Each of the four member pixels contributes a fraction
 495.314 +   * (1-8*SF) to its own smoothed image and a fraction SF to each of the three
 495.315 +   * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
 495.316 +   * output.  The four corner-adjacent neighbor pixels contribute a fraction
 495.317 +   * SF to just one smoothed pixel, or SF/4 to the final output; while the
 495.318 +   * eight edge-adjacent neighbors contribute SF to each of two smoothed
 495.319 +   * pixels, or SF/2 overall.  In order to use integer arithmetic, these
 495.320 +   * factors are scaled by 2^16 = 65536.
 495.321 +   * Also recall that SF = smoothing_factor / 1024.
 495.322 +   */
 495.323 +
 495.324 +  memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
 495.325 +  neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
 495.326 +
 495.327 +  inrow = 0;
 495.328 +  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
 495.329 +    outptr = output_data[outrow];
 495.330 +    inptr0 = input_data[inrow];
 495.331 +    inptr1 = input_data[inrow+1];
 495.332 +    above_ptr = input_data[inrow-1];
 495.333 +    below_ptr = input_data[inrow+2];
 495.334 +
 495.335 +    /* Special case for first column: pretend column -1 is same as column 0 */
 495.336 +    membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
 495.337 +		GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
 495.338 +    neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
 495.339 +	       GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
 495.340 +	       GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
 495.341 +	       GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
 495.342 +    neighsum += neighsum;
 495.343 +    neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
 495.344 +		GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
 495.345 +    membersum = membersum * memberscale + neighsum * neighscale;
 495.346 +    *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
 495.347 +    inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
 495.348 +
 495.349 +    for (colctr = output_cols - 2; colctr > 0; colctr--) {
 495.350 +      /* sum of pixels directly mapped to this output element */
 495.351 +      membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
 495.352 +		  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
 495.353 +      /* sum of edge-neighbor pixels */
 495.354 +      neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
 495.355 +		 GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
 495.356 +		 GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
 495.357 +		 GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
 495.358 +      /* The edge-neighbors count twice as much as corner-neighbors */
 495.359 +      neighsum += neighsum;
 495.360 +      /* Add in the corner-neighbors */
 495.361 +      neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
 495.362 +		  GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
 495.363 +      /* form final output scaled up by 2^16 */
 495.364 +      membersum = membersum * memberscale + neighsum * neighscale;
 495.365 +      /* round, descale and output it */
 495.366 +      *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
 495.367 +      inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
 495.368 +    }
 495.369 +
 495.370 +    /* Special case for last column */
 495.371 +    membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
 495.372 +		GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
 495.373 +    neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
 495.374 +	       GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
 495.375 +	       GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
 495.376 +	       GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
 495.377 +    neighsum += neighsum;
 495.378 +    neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
 495.379 +		GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
 495.380 +    membersum = membersum * memberscale + neighsum * neighscale;
 495.381 +    *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
 495.382 +
 495.383 +    inrow += 2;
 495.384 +  }
 495.385 +}
 495.386 +
 495.387 +
 495.388 +/*
 495.389 + * Downsample pixel values of a single component.
 495.390 + * This version handles the special case of a full-size component,
 495.391 + * with smoothing.  One row of context is required.
 495.392 + */
 495.393 +
 495.394 +METHODDEF(void)
 495.395 +fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
 495.396 +			    JSAMPARRAY input_data, JSAMPARRAY output_data)
 495.397 +{
 495.398 +  int outrow;
 495.399 +  JDIMENSION colctr;
 495.400 +  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
 495.401 +  register JSAMPROW inptr, above_ptr, below_ptr, outptr;
 495.402 +  INT32 membersum, neighsum, memberscale, neighscale;
 495.403 +  int colsum, lastcolsum, nextcolsum;
 495.404 +
 495.405 +  /* Expand input data enough to let all the output samples be generated
 495.406 +   * by the standard loop.  Special-casing padded output would be more
 495.407 +   * efficient.
 495.408 +   */
 495.409 +  expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
 495.410 +		    cinfo->image_width, output_cols);
 495.411 +
 495.412 +  /* Each of the eight neighbor pixels contributes a fraction SF to the
 495.413 +   * smoothed pixel, while the main pixel contributes (1-8*SF).  In order
 495.414 +   * to use integer arithmetic, these factors are multiplied by 2^16 = 65536.
 495.415 +   * Also recall that SF = smoothing_factor / 1024.
 495.416 +   */
 495.417 +
 495.418 +  memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
 495.419 +  neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
 495.420 +
 495.421 +  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
 495.422 +    outptr = output_data[outrow];
 495.423 +    inptr = input_data[outrow];
 495.424 +    above_ptr = input_data[outrow-1];
 495.425 +    below_ptr = input_data[outrow+1];
 495.426 +
 495.427 +    /* Special case for first column */
 495.428 +    colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
 495.429 +	     GETJSAMPLE(*inptr);
 495.430 +    membersum = GETJSAMPLE(*inptr++);
 495.431 +    nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
 495.432 +		 GETJSAMPLE(*inptr);
 495.433 +    neighsum = colsum + (colsum - membersum) + nextcolsum;
 495.434 +    membersum = membersum * memberscale + neighsum * neighscale;
 495.435 +    *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
 495.436 +    lastcolsum = colsum; colsum = nextcolsum;
 495.437 +
 495.438 +    for (colctr = output_cols - 2; colctr > 0; colctr--) {
 495.439 +      membersum = GETJSAMPLE(*inptr++);
 495.440 +      above_ptr++; below_ptr++;
 495.441 +      nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
 495.442 +		   GETJSAMPLE(*inptr);
 495.443 +      neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
 495.444 +      membersum = membersum * memberscale + neighsum * neighscale;
 495.445 +      *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
 495.446 +      lastcolsum = colsum; colsum = nextcolsum;
 495.447 +    }
 495.448 +
 495.449 +    /* Special case for last column */
 495.450 +    membersum = GETJSAMPLE(*inptr);
 495.451 +    neighsum = lastcolsum + (colsum - membersum) + colsum;
 495.452 +    membersum = membersum * memberscale + neighsum * neighscale;
 495.453 +    *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
 495.454 +
 495.455 +  }
 495.456 +}
 495.457 +
 495.458 +#endif /* INPUT_SMOOTHING_SUPPORTED */
 495.459 +
 495.460 +
 495.461 +/*
 495.462 + * Module initialization routine for downsampling.
 495.463 + * Note that we must select a routine for each component.
 495.464 + */
 495.465 +
 495.466 +GLOBAL(void)
 495.467 +jinit_downsampler (j_compress_ptr cinfo)
 495.468 +{
 495.469 +  my_downsample_ptr downsample;
 495.470 +  int ci;
 495.471 +  jpeg_component_info * compptr;
 495.472 +  boolean smoothok = TRUE;
 495.473 +
 495.474 +  downsample = (my_downsample_ptr)
 495.475 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 495.476 +				SIZEOF(my_downsampler));
 495.477 +  cinfo->downsample = (struct jpeg_downsampler *) downsample;
 495.478 +  downsample->pub.start_pass = start_pass_downsample;
 495.479 +  downsample->pub.downsample = sep_downsample;
 495.480 +  downsample->pub.need_context_rows = FALSE;
 495.481 +
 495.482 +  if (cinfo->CCIR601_sampling)
 495.483 +    ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
 495.484 +
 495.485 +  /* Verify we can handle the sampling factors, and set up method pointers */
 495.486 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 495.487 +       ci++, compptr++) {
 495.488 +    if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
 495.489 +	compptr->v_samp_factor == cinfo->max_v_samp_factor) {
 495.490 +#ifdef INPUT_SMOOTHING_SUPPORTED
 495.491 +      if (cinfo->smoothing_factor) {
 495.492 +	downsample->methods[ci] = fullsize_smooth_downsample;
 495.493 +	downsample->pub.need_context_rows = TRUE;
 495.494 +      } else
 495.495 +#endif
 495.496 +	downsample->methods[ci] = fullsize_downsample;
 495.497 +    } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
 495.498 +	       compptr->v_samp_factor == cinfo->max_v_samp_factor) {
 495.499 +      smoothok = FALSE;
 495.500 +      downsample->methods[ci] = h2v1_downsample;
 495.501 +    } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
 495.502 +	       compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
 495.503 +#ifdef INPUT_SMOOTHING_SUPPORTED
 495.504 +      if (cinfo->smoothing_factor) {
 495.505 +	downsample->methods[ci] = h2v2_smooth_downsample;
 495.506 +	downsample->pub.need_context_rows = TRUE;
 495.507 +      } else
 495.508 +#endif
 495.509 +	downsample->methods[ci] = h2v2_downsample;
 495.510 +    } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
 495.511 +	       (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
 495.512 +      smoothok = FALSE;
 495.513 +      downsample->methods[ci] = int_downsample;
 495.514 +    } else
 495.515 +      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
 495.516 +  }
 495.517 +
 495.518 +#ifdef INPUT_SMOOTHING_SUPPORTED
 495.519 +  if (cinfo->smoothing_factor && !smoothok)
 495.520 +    TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL);
 495.521 +#endif
 495.522 +}
   496.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   496.2 +++ b/libs/libjpeg/jctrans.c	Sat Feb 01 19:58:19 2014 +0200
   496.3 @@ -0,0 +1,388 @@
   496.4 +/*
   496.5 + * jctrans.c
   496.6 + *
   496.7 + * Copyright (C) 1995-1998, Thomas G. Lane.
   496.8 + * This file is part of the Independent JPEG Group's software.
   496.9 + * For conditions of distribution and use, see the accompanying README file.
  496.10 + *
  496.11 + * This file contains library routines for transcoding compression,
  496.12 + * that is, writing raw DCT coefficient arrays to an output JPEG file.
  496.13 + * The routines in jcapimin.c will also be needed by a transcoder.
  496.14 + */
  496.15 +
  496.16 +#define JPEG_INTERNALS
  496.17 +#include "jinclude.h"
  496.18 +#include "jpeglib.h"
  496.19 +
  496.20 +
  496.21 +/* Forward declarations */
  496.22 +LOCAL(void) transencode_master_selection
  496.23 +	JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
  496.24 +LOCAL(void) transencode_coef_controller
  496.25 +	JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
  496.26 +
  496.27 +
  496.28 +/*
  496.29 + * Compression initialization for writing raw-coefficient data.
  496.30 + * Before calling this, all parameters and a data destination must be set up.
  496.31 + * Call jpeg_finish_compress() to actually write the data.
  496.32 + *
  496.33 + * The number of passed virtual arrays must match cinfo->num_components.
  496.34 + * Note that the virtual arrays need not be filled or even realized at
  496.35 + * the time write_coefficients is called; indeed, if the virtual arrays
  496.36 + * were requested from this compression object's memory manager, they
  496.37 + * typically will be realized during this routine and filled afterwards.
  496.38 + */
  496.39 +
  496.40 +GLOBAL(void)
  496.41 +jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
  496.42 +{
  496.43 +  if (cinfo->global_state != CSTATE_START)
  496.44 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  496.45 +  /* Mark all tables to be written */
  496.46 +  jpeg_suppress_tables(cinfo, FALSE);
  496.47 +  /* (Re)initialize error mgr and destination modules */
  496.48 +  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
  496.49 +  (*cinfo->dest->init_destination) (cinfo);
  496.50 +  /* Perform master selection of active modules */
  496.51 +  transencode_master_selection(cinfo, coef_arrays);
  496.52 +  /* Wait for jpeg_finish_compress() call */
  496.53 +  cinfo->next_scanline = 0;	/* so jpeg_write_marker works */
  496.54 +  cinfo->global_state = CSTATE_WRCOEFS;
  496.55 +}
  496.56 +
  496.57 +
  496.58 +/*
  496.59 + * Initialize the compression object with default parameters,
  496.60 + * then copy from the source object all parameters needed for lossless
  496.61 + * transcoding.  Parameters that can be varied without loss (such as
  496.62 + * scan script and Huffman optimization) are left in their default states.
  496.63 + */
  496.64 +
  496.65 +GLOBAL(void)
  496.66 +jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
  496.67 +			       j_compress_ptr dstinfo)
  496.68 +{
  496.69 +  JQUANT_TBL ** qtblptr;
  496.70 +  jpeg_component_info *incomp, *outcomp;
  496.71 +  JQUANT_TBL *c_quant, *slot_quant;
  496.72 +  int tblno, ci, coefi;
  496.73 +
  496.74 +  /* Safety check to ensure start_compress not called yet. */
  496.75 +  if (dstinfo->global_state != CSTATE_START)
  496.76 +    ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
  496.77 +  /* Copy fundamental image dimensions */
  496.78 +  dstinfo->image_width = srcinfo->image_width;
  496.79 +  dstinfo->image_height = srcinfo->image_height;
  496.80 +  dstinfo->input_components = srcinfo->num_components;
  496.81 +  dstinfo->in_color_space = srcinfo->jpeg_color_space;
  496.82 +  /* Initialize all parameters to default values */
  496.83 +  jpeg_set_defaults(dstinfo);
  496.84 +  /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
  496.85 +   * Fix it to get the right header markers for the image colorspace.
  496.86 +   */
  496.87 +  jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
  496.88 +  dstinfo->data_precision = srcinfo->data_precision;
  496.89 +  dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
  496.90 +  /* Copy the source's quantization tables. */
  496.91 +  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
  496.92 +    if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
  496.93 +      qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
  496.94 +      if (*qtblptr == NULL)
  496.95 +	*qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
  496.96 +      MEMCOPY((*qtblptr)->quantval,
  496.97 +	      srcinfo->quant_tbl_ptrs[tblno]->quantval,
  496.98 +	      SIZEOF((*qtblptr)->quantval));
  496.99 +      (*qtblptr)->sent_table = FALSE;
 496.100 +    }
 496.101 +  }
 496.102 +  /* Copy the source's per-component info.
 496.103 +   * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
 496.104 +   */
 496.105 +  dstinfo->num_components = srcinfo->num_components;
 496.106 +  if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
 496.107 +    ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
 496.108 +	     MAX_COMPONENTS);
 496.109 +  for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
 496.110 +       ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
 496.111 +    outcomp->component_id = incomp->component_id;
 496.112 +    outcomp->h_samp_factor = incomp->h_samp_factor;
 496.113 +    outcomp->v_samp_factor = incomp->v_samp_factor;
 496.114 +    outcomp->quant_tbl_no = incomp->quant_tbl_no;
 496.115 +    /* Make sure saved quantization table for component matches the qtable
 496.116 +     * slot.  If not, the input file re-used this qtable slot.
 496.117 +     * IJG encoder currently cannot duplicate this.
 496.118 +     */
 496.119 +    tblno = outcomp->quant_tbl_no;
 496.120 +    if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
 496.121 +	srcinfo->quant_tbl_ptrs[tblno] == NULL)
 496.122 +      ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
 496.123 +    slot_quant = srcinfo->quant_tbl_ptrs[tblno];
 496.124 +    c_quant = incomp->quant_table;
 496.125 +    if (c_quant != NULL) {
 496.126 +      for (coefi = 0; coefi < DCTSIZE2; coefi++) {
 496.127 +	if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
 496.128 +	  ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
 496.129 +      }
 496.130 +    }
 496.131 +    /* Note: we do not copy the source's Huffman table assignments;
 496.132 +     * instead we rely on jpeg_set_colorspace to have made a suitable choice.
 496.133 +     */
 496.134 +  }
 496.135 +  /* Also copy JFIF version and resolution information, if available.
 496.136 +   * Strictly speaking this isn't "critical" info, but it's nearly
 496.137 +   * always appropriate to copy it if available.  In particular,
 496.138 +   * if the application chooses to copy JFIF 1.02 extension markers from
 496.139 +   * the source file, we need to copy the version to make sure we don't
 496.140 +   * emit a file that has 1.02 extensions but a claimed version of 1.01.
 496.141 +   * We will *not*, however, copy version info from mislabeled "2.01" files.
 496.142 +   */
 496.143 +  if (srcinfo->saw_JFIF_marker) {
 496.144 +    if (srcinfo->JFIF_major_version == 1) {
 496.145 +      dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
 496.146 +      dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
 496.147 +    }
 496.148 +    dstinfo->density_unit = srcinfo->density_unit;
 496.149 +    dstinfo->X_density = srcinfo->X_density;
 496.150 +    dstinfo->Y_density = srcinfo->Y_density;
 496.151 +  }
 496.152 +}
 496.153 +
 496.154 +
 496.155 +/*
 496.156 + * Master selection of compression modules for transcoding.
 496.157 + * This substitutes for jcinit.c's initialization of the full compressor.
 496.158 + */
 496.159 +
 496.160 +LOCAL(void)
 496.161 +transencode_master_selection (j_compress_ptr cinfo,
 496.162 +			      jvirt_barray_ptr * coef_arrays)
 496.163 +{
 496.164 +  /* Although we don't actually use input_components for transcoding,
 496.165 +   * jcmaster.c's initial_setup will complain if input_components is 0.
 496.166 +   */
 496.167 +  cinfo->input_components = 1;
 496.168 +  /* Initialize master control (includes parameter checking/processing) */
 496.169 +  jinit_c_master_control(cinfo, TRUE /* transcode only */);
 496.170 +
 496.171 +  /* Entropy encoding: either Huffman or arithmetic coding. */
 496.172 +  if (cinfo->arith_code) {
 496.173 +    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
 496.174 +  } else {
 496.175 +    if (cinfo->progressive_mode) {
 496.176 +#ifdef C_PROGRESSIVE_SUPPORTED
 496.177 +      jinit_phuff_encoder(cinfo);
 496.178 +#else
 496.179 +      ERREXIT(cinfo, JERR_NOT_COMPILED);
 496.180 +#endif
 496.181 +    } else
 496.182 +      jinit_huff_encoder(cinfo);
 496.183 +  }
 496.184 +
 496.185 +  /* We need a special coefficient buffer controller. */
 496.186 +  transencode_coef_controller(cinfo, coef_arrays);
 496.187 +
 496.188 +  jinit_marker_writer(cinfo);
 496.189 +
 496.190 +  /* We can now tell the memory manager to allocate virtual arrays. */
 496.191 +  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
 496.192 +
 496.193 +  /* Write the datastream header (SOI, JFIF) immediately.
 496.194 +   * Frame and scan headers are postponed till later.
 496.195 +   * This lets application insert special markers after the SOI.
 496.196 +   */
 496.197 +  (*cinfo->marker->write_file_header) (cinfo);
 496.198 +}
 496.199 +
 496.200 +
 496.201 +/*
 496.202 + * The rest of this file is a special implementation of the coefficient
 496.203 + * buffer controller.  This is similar to jccoefct.c, but it handles only
 496.204 + * output from presupplied virtual arrays.  Furthermore, we generate any
 496.205 + * dummy padding blocks on-the-fly rather than expecting them to be present
 496.206 + * in the arrays.
 496.207 + */
 496.208 +
 496.209 +/* Private buffer controller object */
 496.210 +
 496.211 +typedef struct {
 496.212 +  struct jpeg_c_coef_controller pub; /* public fields */
 496.213 +
 496.214 +  JDIMENSION iMCU_row_num;	/* iMCU row # within image */
 496.215 +  JDIMENSION mcu_ctr;		/* counts MCUs processed in current row */
 496.216 +  int MCU_vert_offset;		/* counts MCU rows within iMCU row */
 496.217 +  int MCU_rows_per_iMCU_row;	/* number of such rows needed */
 496.218 +
 496.219 +  /* Virtual block array for each component. */
 496.220 +  jvirt_barray_ptr * whole_image;
 496.221 +
 496.222 +  /* Workspace for constructing dummy blocks at right/bottom edges. */
 496.223 +  JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
 496.224 +} my_coef_controller;
 496.225 +
 496.226 +typedef my_coef_controller * my_coef_ptr;
 496.227 +
 496.228 +
 496.229 +LOCAL(void)
 496.230 +start_iMCU_row (j_compress_ptr cinfo)
 496.231 +/* Reset within-iMCU-row counters for a new row */
 496.232 +{
 496.233 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 496.234 +
 496.235 +  /* In an interleaved scan, an MCU row is the same as an iMCU row.
 496.236 +   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
 496.237 +   * But at the bottom of the image, process only what's left.
 496.238 +   */
 496.239 +  if (cinfo->comps_in_scan > 1) {
 496.240 +    coef->MCU_rows_per_iMCU_row = 1;
 496.241 +  } else {
 496.242 +    if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
 496.243 +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
 496.244 +    else
 496.245 +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
 496.246 +  }
 496.247 +
 496.248 +  coef->mcu_ctr = 0;
 496.249 +  coef->MCU_vert_offset = 0;
 496.250 +}
 496.251 +
 496.252 +
 496.253 +/*
 496.254 + * Initialize for a processing pass.
 496.255 + */
 496.256 +
 496.257 +METHODDEF(void)
 496.258 +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
 496.259 +{
 496.260 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 496.261 +
 496.262 +  if (pass_mode != JBUF_CRANK_DEST)
 496.263 +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 496.264 +
 496.265 +  coef->iMCU_row_num = 0;
 496.266 +  start_iMCU_row(cinfo);
 496.267 +}
 496.268 +
 496.269 +
 496.270 +/*
 496.271 + * Process some data.
 496.272 + * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
 496.273 + * per call, ie, v_samp_factor block rows for each component in the scan.
 496.274 + * The data is obtained from the virtual arrays and fed to the entropy coder.
 496.275 + * Returns TRUE if the iMCU row is completed, FALSE if suspended.
 496.276 + *
 496.277 + * NB: input_buf is ignored; it is likely to be a NULL pointer.
 496.278 + */
 496.279 +
 496.280 +METHODDEF(boolean)
 496.281 +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
 496.282 +{
 496.283 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 496.284 +  JDIMENSION MCU_col_num;	/* index of current MCU within row */
 496.285 +  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
 496.286 +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
 496.287 +  int blkn, ci, xindex, yindex, yoffset, blockcnt;
 496.288 +  JDIMENSION start_col;
 496.289 +  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
 496.290 +  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
 496.291 +  JBLOCKROW buffer_ptr;
 496.292 +  jpeg_component_info *compptr;
 496.293 +
 496.294 +  /* Align the virtual buffers for the components used in this scan. */
 496.295 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 496.296 +    compptr = cinfo->cur_comp_info[ci];
 496.297 +    buffer[ci] = (*cinfo->mem->access_virt_barray)
 496.298 +      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
 496.299 +       coef->iMCU_row_num * compptr->v_samp_factor,
 496.300 +       (JDIMENSION) compptr->v_samp_factor, FALSE);
 496.301 +  }
 496.302 +
 496.303 +  /* Loop to process one whole iMCU row */
 496.304 +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
 496.305 +       yoffset++) {
 496.306 +    for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
 496.307 +	 MCU_col_num++) {
 496.308 +      /* Construct list of pointers to DCT blocks belonging to this MCU */
 496.309 +      blkn = 0;			/* index of current DCT block within MCU */
 496.310 +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 496.311 +	compptr = cinfo->cur_comp_info[ci];
 496.312 +	start_col = MCU_col_num * compptr->MCU_width;
 496.313 +	blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
 496.314 +						: compptr->last_col_width;
 496.315 +	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
 496.316 +	  if (coef->iMCU_row_num < last_iMCU_row ||
 496.317 +	      yindex+yoffset < compptr->last_row_height) {
 496.318 +	    /* Fill in pointers to real blocks in this row */
 496.319 +	    buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
 496.320 +	    for (xindex = 0; xindex < blockcnt; xindex++)
 496.321 +	      MCU_buffer[blkn++] = buffer_ptr++;
 496.322 +	  } else {
 496.323 +	    /* At bottom of image, need a whole row of dummy blocks */
 496.324 +	    xindex = 0;
 496.325 +	  }
 496.326 +	  /* Fill in any dummy blocks needed in this row.
 496.327 +	   * Dummy blocks are filled in the same way as in jccoefct.c:
 496.328 +	   * all zeroes in the AC entries, DC entries equal to previous
 496.329 +	   * block's DC value.  The init routine has already zeroed the
 496.330 +	   * AC entries, so we need only set the DC entries correctly.
 496.331 +	   */
 496.332 +	  for (; xindex < compptr->MCU_width; xindex++) {
 496.333 +	    MCU_buffer[blkn] = coef->dummy_buffer[blkn];
 496.334 +	    MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
 496.335 +	    blkn++;
 496.336 +	  }
 496.337 +	}
 496.338 +      }
 496.339 +      /* Try to write the MCU. */
 496.340 +      if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
 496.341 +	/* Suspension forced; update state counters and exit */
 496.342 +	coef->MCU_vert_offset = yoffset;
 496.343 +	coef->mcu_ctr = MCU_col_num;
 496.344 +	return FALSE;
 496.345 +      }
 496.346 +    }
 496.347 +    /* Completed an MCU row, but perhaps not an iMCU row */
 496.348 +    coef->mcu_ctr = 0;
 496.349 +  }
 496.350 +  /* Completed the iMCU row, advance counters for next one */
 496.351 +  coef->iMCU_row_num++;
 496.352 +  start_iMCU_row(cinfo);
 496.353 +  return TRUE;
 496.354 +}
 496.355 +
 496.356 +
 496.357 +/*
 496.358 + * Initialize coefficient buffer controller.
 496.359 + *
 496.360 + * Each passed coefficient array must be the right size for that
 496.361 + * coefficient: width_in_blocks wide and height_in_blocks high,
 496.362 + * with unitheight at least v_samp_factor.
 496.363 + */
 496.364 +
 496.365 +LOCAL(void)
 496.366 +transencode_coef_controller (j_compress_ptr cinfo,
 496.367 +			     jvirt_barray_ptr * coef_arrays)
 496.368 +{
 496.369 +  my_coef_ptr coef;
 496.370 +  JBLOCKROW buffer;
 496.371 +  int i;
 496.372 +
 496.373 +  coef = (my_coef_ptr)
 496.374 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 496.375 +				SIZEOF(my_coef_controller));
 496.376 +  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
 496.377 +  coef->pub.start_pass = start_pass_coef;
 496.378 +  coef->pub.compress_data = compress_output;
 496.379 +
 496.380 +  /* Save pointer to virtual arrays */
 496.381 +  coef->whole_image = coef_arrays;
 496.382 +
 496.383 +  /* Allocate and pre-zero space for dummy DCT blocks. */
 496.384 +  buffer = (JBLOCKROW)
 496.385 +    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 496.386 +				C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
 496.387 +  jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
 496.388 +  for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
 496.389 +    coef->dummy_buffer[i] = buffer + i;
 496.390 +  }
 496.391 +}
   497.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   497.2 +++ b/libs/libjpeg/jdapimin.c	Sat Feb 01 19:58:19 2014 +0200
   497.3 @@ -0,0 +1,395 @@
   497.4 +/*
   497.5 + * jdapimin.c
   497.6 + *
   497.7 + * Copyright (C) 1994-1998, Thomas G. Lane.
   497.8 + * This file is part of the Independent JPEG Group's software.
   497.9 + * For conditions of distribution and use, see the accompanying README file.
  497.10 + *
  497.11 + * This file contains application interface code for the decompression half
  497.12 + * of the JPEG library.  These are the "minimum" API routines that may be
  497.13 + * needed in either the normal full-decompression case or the
  497.14 + * transcoding-only case.
  497.15 + *
  497.16 + * Most of the routines intended to be called directly by an application
  497.17 + * are in this file or in jdapistd.c.  But also see jcomapi.c for routines
  497.18 + * shared by compression and decompression, and jdtrans.c for the transcoding
  497.19 + * case.
  497.20 + */
  497.21 +
  497.22 +#define JPEG_INTERNALS
  497.23 +#include "jinclude.h"
  497.24 +#include "jpeglib.h"
  497.25 +
  497.26 +
  497.27 +/*
  497.28 + * Initialization of a JPEG decompression object.
  497.29 + * The error manager must already be set up (in case memory manager fails).
  497.30 + */
  497.31 +
  497.32 +GLOBAL(void)
  497.33 +jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
  497.34 +{
  497.35 +  int i;
  497.36 +
  497.37 +  /* Guard against version mismatches between library and caller. */
  497.38 +  cinfo->mem = NULL;		/* so jpeg_destroy knows mem mgr not called */
  497.39 +  if (version != JPEG_LIB_VERSION)
  497.40 +    ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
  497.41 +  if (structsize != SIZEOF(struct jpeg_decompress_struct))
  497.42 +    ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, 
  497.43 +	     (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
  497.44 +
  497.45 +  /* For debugging purposes, we zero the whole master structure.
  497.46 +   * But the application has already set the err pointer, and may have set
  497.47 +   * client_data, so we have to save and restore those fields.
  497.48 +   * Note: if application hasn't set client_data, tools like Purify may
  497.49 +   * complain here.
  497.50 +   */
  497.51 +  {
  497.52 +    struct jpeg_error_mgr * err = cinfo->err;
  497.53 +    void * client_data = cinfo->client_data; /* ignore Purify complaint here */
  497.54 +    MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
  497.55 +    cinfo->err = err;
  497.56 +    cinfo->client_data = client_data;
  497.57 +  }
  497.58 +  cinfo->is_decompressor = TRUE;
  497.59 +
  497.60 +  /* Initialize a memory manager instance for this object */
  497.61 +  jinit_memory_mgr((j_common_ptr) cinfo);
  497.62 +
  497.63 +  /* Zero out pointers to permanent structures. */
  497.64 +  cinfo->progress = NULL;
  497.65 +  cinfo->src = NULL;
  497.66 +
  497.67 +  for (i = 0; i < NUM_QUANT_TBLS; i++)
  497.68 +    cinfo->quant_tbl_ptrs[i] = NULL;
  497.69 +
  497.70 +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
  497.71 +    cinfo->dc_huff_tbl_ptrs[i] = NULL;
  497.72 +    cinfo->ac_huff_tbl_ptrs[i] = NULL;
  497.73 +  }
  497.74 +
  497.75 +  /* Initialize marker processor so application can override methods
  497.76 +   * for COM, APPn markers before calling jpeg_read_header.
  497.77 +   */
  497.78 +  cinfo->marker_list = NULL;
  497.79 +  jinit_marker_reader(cinfo);
  497.80 +
  497.81 +  /* And initialize the overall input controller. */
  497.82 +  jinit_input_controller(cinfo);
  497.83 +
  497.84 +  /* OK, I'm ready */
  497.85 +  cinfo->global_state = DSTATE_START;
  497.86 +}
  497.87 +
  497.88 +
  497.89 +/*
  497.90 + * Destruction of a JPEG decompression object
  497.91 + */
  497.92 +
  497.93 +GLOBAL(void)
  497.94 +jpeg_destroy_decompress (j_decompress_ptr cinfo)
  497.95 +{
  497.96 +  jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
  497.97 +}
  497.98 +
  497.99 +
 497.100 +/*
 497.101 + * Abort processing of a JPEG decompression operation,
 497.102 + * but don't destroy the object itself.
 497.103 + */
 497.104 +
 497.105 +GLOBAL(void)
 497.106 +jpeg_abort_decompress (j_decompress_ptr cinfo)
 497.107 +{
 497.108 +  jpeg_abort((j_common_ptr) cinfo); /* use common routine */
 497.109 +}
 497.110 +
 497.111 +
 497.112 +/*
 497.113 + * Set default decompression parameters.
 497.114 + */
 497.115 +
 497.116 +LOCAL(void)
 497.117 +default_decompress_parms (j_decompress_ptr cinfo)
 497.118 +{
 497.119 +  /* Guess the input colorspace, and set output colorspace accordingly. */
 497.120 +  /* (Wish JPEG committee had provided a real way to specify this...) */
 497.121 +  /* Note application may override our guesses. */
 497.122 +  switch (cinfo->num_components) {
 497.123 +  case 1:
 497.124 +    cinfo->jpeg_color_space = JCS_GRAYSCALE;
 497.125 +    cinfo->out_color_space = JCS_GRAYSCALE;
 497.126 +    break;
 497.127 +    
 497.128 +  case 3:
 497.129 +    if (cinfo->saw_JFIF_marker) {
 497.130 +      cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
 497.131 +    } else if (cinfo->saw_Adobe_marker) {
 497.132 +      switch (cinfo->Adobe_transform) {
 497.133 +      case 0:
 497.134 +	cinfo->jpeg_color_space = JCS_RGB;
 497.135 +	break;
 497.136 +      case 1:
 497.137 +	cinfo->jpeg_color_space = JCS_YCbCr;
 497.138 +	break;
 497.139 +      default:
 497.140 +	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
 497.141 +	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
 497.142 +	break;
 497.143 +      }
 497.144 +    } else {
 497.145 +      /* Saw no special markers, try to guess from the component IDs */
 497.146 +      int cid0 = cinfo->comp_info[0].component_id;
 497.147 +      int cid1 = cinfo->comp_info[1].component_id;
 497.148 +      int cid2 = cinfo->comp_info[2].component_id;
 497.149 +
 497.150 +      if (cid0 == 1 && cid1 == 2 && cid2 == 3)
 497.151 +	cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
 497.152 +      else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
 497.153 +	cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
 497.154 +      else {
 497.155 +	TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
 497.156 +	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
 497.157 +      }
 497.158 +    }
 497.159 +    /* Always guess RGB is proper output colorspace. */
 497.160 +    cinfo->out_color_space = JCS_RGB;
 497.161 +    break;
 497.162 +    
 497.163 +  case 4:
 497.164 +    if (cinfo->saw_Adobe_marker) {
 497.165 +      switch (cinfo->Adobe_transform) {
 497.166 +      case 0:
 497.167 +	cinfo->jpeg_color_space = JCS_CMYK;
 497.168 +	break;
 497.169 +      case 2:
 497.170 +	cinfo->jpeg_color_space = JCS_YCCK;
 497.171 +	break;
 497.172 +      default:
 497.173 +	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
 497.174 +	cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
 497.175 +	break;
 497.176 +      }
 497.177 +    } else {
 497.178 +      /* No special markers, assume straight CMYK. */
 497.179 +      cinfo->jpeg_color_space = JCS_CMYK;
 497.180 +    }
 497.181 +    cinfo->out_color_space = JCS_CMYK;
 497.182 +    break;
 497.183 +    
 497.184 +  default:
 497.185 +    cinfo->jpeg_color_space = JCS_UNKNOWN;
 497.186 +    cinfo->out_color_space = JCS_UNKNOWN;
 497.187 +    break;
 497.188 +  }
 497.189 +
 497.190 +  /* Set defaults for other decompression parameters. */
 497.191 +  cinfo->scale_num = 1;		/* 1:1 scaling */
 497.192 +  cinfo->scale_denom = 1;
 497.193 +  cinfo->output_gamma = 1.0;
 497.194 +  cinfo->buffered_image = FALSE;
 497.195 +  cinfo->raw_data_out = FALSE;
 497.196 +  cinfo->dct_method = JDCT_DEFAULT;
 497.197 +  cinfo->do_fancy_upsampling = TRUE;
 497.198 +  cinfo->do_block_smoothing = TRUE;
 497.199 +  cinfo->quantize_colors = FALSE;
 497.200 +  /* We set these in case application only sets quantize_colors. */
 497.201 +  cinfo->dither_mode = JDITHER_FS;
 497.202 +#ifdef QUANT_2PASS_SUPPORTED
 497.203 +  cinfo->two_pass_quantize = TRUE;
 497.204 +#else
 497.205 +  cinfo->two_pass_quantize = FALSE;
 497.206 +#endif
 497.207 +  cinfo->desired_number_of_colors = 256;
 497.208 +  cinfo->colormap = NULL;
 497.209 +  /* Initialize for no mode change in buffered-image mode. */
 497.210 +  cinfo->enable_1pass_quant = FALSE;
 497.211 +  cinfo->enable_external_quant = FALSE;
 497.212 +  cinfo->enable_2pass_quant = FALSE;
 497.213 +}
 497.214 +
 497.215 +
 497.216 +/*
 497.217 + * Decompression startup: read start of JPEG datastream to see what's there.
 497.218 + * Need only initialize JPEG object and supply a data source before calling.
 497.219 + *
 497.220 + * This routine will read as far as the first SOS marker (ie, actual start of
 497.221 + * compressed data), and will save all tables and parameters in the JPEG
 497.222 + * object.  It will also initialize the decompression parameters to default
 497.223 + * values, and finally return JPEG_HEADER_OK.  On return, the application may
 497.224 + * adjust the decompression parameters and then call jpeg_start_decompress.
 497.225 + * (Or, if the application only wanted to determine the image parameters,
 497.226 + * the data need not be decompressed.  In that case, call jpeg_abort or
 497.227 + * jpeg_destroy to release any temporary space.)
 497.228 + * If an abbreviated (tables only) datastream is presented, the routine will
 497.229 + * return JPEG_HEADER_TABLES_ONLY upon reaching EOI.  The application may then
 497.230 + * re-use the JPEG object to read the abbreviated image datastream(s).
 497.231 + * It is unnecessary (but OK) to call jpeg_abort in this case.
 497.232 + * The JPEG_SUSPENDED return code only occurs if the data source module
 497.233 + * requests suspension of the decompressor.  In this case the application
 497.234 + * should load more source data and then re-call jpeg_read_header to resume
 497.235 + * processing.
 497.236 + * If a non-suspending data source is used and require_image is TRUE, then the
 497.237 + * return code need not be inspected since only JPEG_HEADER_OK is possible.
 497.238 + *
 497.239 + * This routine is now just a front end to jpeg_consume_input, with some
 497.240 + * extra error checking.
 497.241 + */
 497.242 +
 497.243 +GLOBAL(int)
 497.244 +jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
 497.245 +{
 497.246 +  int retcode;
 497.247 +
 497.248 +  if (cinfo->global_state != DSTATE_START &&
 497.249 +      cinfo->global_state != DSTATE_INHEADER)
 497.250 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 497.251 +
 497.252 +  retcode = jpeg_consume_input(cinfo);
 497.253 +
 497.254 +  switch (retcode) {
 497.255 +  case JPEG_REACHED_SOS:
 497.256 +    retcode = JPEG_HEADER_OK;
 497.257 +    break;
 497.258 +  case JPEG_REACHED_EOI:
 497.259 +    if (require_image)		/* Complain if application wanted an image */
 497.260 +      ERREXIT(cinfo, JERR_NO_IMAGE);
 497.261 +    /* Reset to start state; it would be safer to require the application to
 497.262 +     * call jpeg_abort, but we can't change it now for compatibility reasons.
 497.263 +     * A side effect is to free any temporary memory (there shouldn't be any).
 497.264 +     */
 497.265 +    jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
 497.266 +    retcode = JPEG_HEADER_TABLES_ONLY;
 497.267 +    break;
 497.268 +  case JPEG_SUSPENDED:
 497.269 +    /* no work */
 497.270 +    break;
 497.271 +  }
 497.272 +
 497.273 +  return retcode;
 497.274 +}
 497.275 +
 497.276 +
 497.277 +/*
 497.278 + * Consume data in advance of what the decompressor requires.
 497.279 + * This can be called at any time once the decompressor object has
 497.280 + * been created and a data source has been set up.
 497.281 + *
 497.282 + * This routine is essentially a state machine that handles a couple
 497.283 + * of critical state-transition actions, namely initial setup and
 497.284 + * transition from header scanning to ready-for-start_decompress.
 497.285 + * All the actual input is done via the input controller's consume_input
 497.286 + * method.
 497.287 + */
 497.288 +
 497.289 +GLOBAL(int)
 497.290 +jpeg_consume_input (j_decompress_ptr cinfo)
 497.291 +{
 497.292 +  int retcode = JPEG_SUSPENDED;
 497.293 +
 497.294 +  /* NB: every possible DSTATE value should be listed in this switch */
 497.295 +  switch (cinfo->global_state) {
 497.296 +  case DSTATE_START:
 497.297 +    /* Start-of-datastream actions: reset appropriate modules */
 497.298 +    (*cinfo->inputctl->reset_input_controller) (cinfo);
 497.299 +    /* Initialize application's data source module */
 497.300 +    (*cinfo->src->init_source) (cinfo);
 497.301 +    cinfo->global_state = DSTATE_INHEADER;
 497.302 +    /*FALLTHROUGH*/
 497.303 +  case DSTATE_INHEADER:
 497.304 +    retcode = (*cinfo->inputctl->consume_input) (cinfo);
 497.305 +    if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
 497.306 +      /* Set up default parameters based on header data */
 497.307 +      default_decompress_parms(cinfo);
 497.308 +      /* Set global state: ready for start_decompress */
 497.309 +      cinfo->global_state = DSTATE_READY;
 497.310 +    }
 497.311 +    break;
 497.312 +  case DSTATE_READY:
 497.313 +    /* Can't advance past first SOS until start_decompress is called */
 497.314 +    retcode = JPEG_REACHED_SOS;
 497.315 +    break;
 497.316 +  case DSTATE_PRELOAD:
 497.317 +  case DSTATE_PRESCAN:
 497.318 +  case DSTATE_SCANNING:
 497.319 +  case DSTATE_RAW_OK:
 497.320 +  case DSTATE_BUFIMAGE:
 497.321 +  case DSTATE_BUFPOST:
 497.322 +  case DSTATE_STOPPING:
 497.323 +    retcode = (*cinfo->inputctl->consume_input) (cinfo);
 497.324 +    break;
 497.325 +  default:
 497.326 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 497.327 +  }
 497.328 +  return retcode;
 497.329 +}
 497.330 +
 497.331 +
 497.332 +/*
 497.333 + * Have we finished reading the input file?
 497.334 + */
 497.335 +
 497.336 +GLOBAL(boolean)
 497.337 +jpeg_input_complete (j_decompress_ptr cinfo)
 497.338 +{
 497.339 +  /* Check for valid jpeg object */
 497.340 +  if (cinfo->global_state < DSTATE_START ||
 497.341 +      cinfo->global_state > DSTATE_STOPPING)
 497.342 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 497.343 +  return cinfo->inputctl->eoi_reached;
 497.344 +}
 497.345 +
 497.346 +
 497.347 +/*
 497.348 + * Is there more than one scan?
 497.349 + */
 497.350 +
 497.351 +GLOBAL(boolean)
 497.352 +jpeg_has_multiple_scans (j_decompress_ptr cinfo)
 497.353 +{
 497.354 +  /* Only valid after jpeg_read_header completes */
 497.355 +  if (cinfo->global_state < DSTATE_READY ||
 497.356 +      cinfo->global_state > DSTATE_STOPPING)
 497.357 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 497.358 +  return cinfo->inputctl->has_multiple_scans;
 497.359 +}
 497.360 +
 497.361 +
 497.362 +/*
 497.363 + * Finish JPEG decompression.
 497.364 + *
 497.365 + * This will normally just verify the file trailer and release temp storage.
 497.366 + *
 497.367 + * Returns FALSE if suspended.  The return value need be inspected only if
 497.368 + * a suspending data source is used.
 497.369 + */
 497.370 +
 497.371 +GLOBAL(boolean)
 497.372 +jpeg_finish_decompress (j_decompress_ptr cinfo)
 497.373 +{
 497.374 +  if ((cinfo->global_state == DSTATE_SCANNING ||
 497.375 +       cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
 497.376 +    /* Terminate final pass of non-buffered mode */
 497.377 +    if (cinfo->output_scanline < cinfo->output_height)
 497.378 +      ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
 497.379 +    (*cinfo->master->finish_output_pass) (cinfo);
 497.380 +    cinfo->global_state = DSTATE_STOPPING;
 497.381 +  } else if (cinfo->global_state == DSTATE_BUFIMAGE) {
 497.382 +    /* Finishing after a buffered-image operation */
 497.383 +    cinfo->global_state = DSTATE_STOPPING;
 497.384 +  } else if (cinfo->global_state != DSTATE_STOPPING) {
 497.385 +    /* STOPPING = repeat call after a suspension, anything else is error */
 497.386 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 497.387 +  }
 497.388 +  /* Read until EOI */
 497.389 +  while (! cinfo->inputctl->eoi_reached) {
 497.390 +    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
 497.391 +      return FALSE;		/* Suspend, come back later */
 497.392 +  }
 497.393 +  /* Do final cleanup */
 497.394 +  (*cinfo->src->term_source) (cinfo);
 497.395 +  /* We can use jpeg_abort to release memory and reset global_state */
 497.396 +  jpeg_abort((j_common_ptr) cinfo);
 497.397 +  return TRUE;
 497.398 +}
   498.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   498.2 +++ b/libs/libjpeg/jdapistd.c	Sat Feb 01 19:58:19 2014 +0200
   498.3 @@ -0,0 +1,275 @@
   498.4 +/*
   498.5 + * jdapistd.c
   498.6 + *
   498.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   498.8 + * This file is part of the Independent JPEG Group's software.
   498.9 + * For conditions of distribution and use, see the accompanying README file.
  498.10 + *
  498.11 + * This file contains application interface code for the decompression half
  498.12 + * of the JPEG library.  These are the "standard" API routines that are
  498.13 + * used in the normal full-decompression case.  They are not used by a
  498.14 + * transcoding-only application.  Note that if an application links in
  498.15 + * jpeg_start_decompress, it will end up linking in the entire decompressor.
  498.16 + * We thus must separate this file from jdapimin.c to avoid linking the
  498.17 + * whole decompression library into a transcoder.
  498.18 + */
  498.19 +
  498.20 +#define JPEG_INTERNALS
  498.21 +#include "jinclude.h"
  498.22 +#include "jpeglib.h"
  498.23 +
  498.24 +
  498.25 +/* Forward declarations */
  498.26 +LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
  498.27 +
  498.28 +
  498.29 +/*
  498.30 + * Decompression initialization.
  498.31 + * jpeg_read_header must be completed before calling this.
  498.32 + *
  498.33 + * If a multipass operating mode was selected, this will do all but the
  498.34 + * last pass, and thus may take a great deal of time.
  498.35 + *
  498.36 + * Returns FALSE if suspended.  The return value need be inspected only if
  498.37 + * a suspending data source is used.
  498.38 + */
  498.39 +
  498.40 +GLOBAL(boolean)
  498.41 +jpeg_start_decompress (j_decompress_ptr cinfo)
  498.42 +{
  498.43 +  if (cinfo->global_state == DSTATE_READY) {
  498.44 +    /* First call: initialize master control, select active modules */
  498.45 +    jinit_master_decompress(cinfo);
  498.46 +    if (cinfo->buffered_image) {
  498.47 +      /* No more work here; expecting jpeg_start_output next */
  498.48 +      cinfo->global_state = DSTATE_BUFIMAGE;
  498.49 +      return TRUE;
  498.50 +    }
  498.51 +    cinfo->global_state = DSTATE_PRELOAD;
  498.52 +  }
  498.53 +  if (cinfo->global_state == DSTATE_PRELOAD) {
  498.54 +    /* If file has multiple scans, absorb them all into the coef buffer */
  498.55 +    if (cinfo->inputctl->has_multiple_scans) {
  498.56 +#ifdef D_MULTISCAN_FILES_SUPPORTED
  498.57 +      for (;;) {
  498.58 +	int retcode;
  498.59 +	/* Call progress monitor hook if present */
  498.60 +	if (cinfo->progress != NULL)
  498.61 +	  (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
  498.62 +	/* Absorb some more input */
  498.63 +	retcode = (*cinfo->inputctl->consume_input) (cinfo);
  498.64 +	if (retcode == JPEG_SUSPENDED)
  498.65 +	  return FALSE;
  498.66 +	if (retcode == JPEG_REACHED_EOI)
  498.67 +	  break;
  498.68 +	/* Advance progress counter if appropriate */
  498.69 +	if (cinfo->progress != NULL &&
  498.70 +	    (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
  498.71 +	  if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
  498.72 +	    /* jdmaster underestimated number of scans; ratchet up one scan */
  498.73 +	    cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
  498.74 +	  }
  498.75 +	}
  498.76 +      }
  498.77 +#else
  498.78 +      ERREXIT(cinfo, JERR_NOT_COMPILED);
  498.79 +#endif /* D_MULTISCAN_FILES_SUPPORTED */
  498.80 +    }
  498.81 +    cinfo->output_scan_number = cinfo->input_scan_number;
  498.82 +  } else if (cinfo->global_state != DSTATE_PRESCAN)
  498.83 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  498.84 +  /* Perform any dummy output passes, and set up for the final pass */
  498.85 +  return output_pass_setup(cinfo);
  498.86 +}
  498.87 +
  498.88 +
  498.89 +/*
  498.90 + * Set up for an output pass, and perform any dummy pass(es) needed.
  498.91 + * Common subroutine for jpeg_start_decompress and jpeg_start_output.
  498.92 + * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
  498.93 + * Exit: If done, returns TRUE and sets global_state for proper output mode.
  498.94 + *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
  498.95 + */
  498.96 +
  498.97 +LOCAL(boolean)
  498.98 +output_pass_setup (j_decompress_ptr cinfo)
  498.99 +{
 498.100 +  if (cinfo->global_state != DSTATE_PRESCAN) {
 498.101 +    /* First call: do pass setup */
 498.102 +    (*cinfo->master->prepare_for_output_pass) (cinfo);
 498.103 +    cinfo->output_scanline = 0;
 498.104 +    cinfo->global_state = DSTATE_PRESCAN;
 498.105 +  }
 498.106 +  /* Loop over any required dummy passes */
 498.107 +  while (cinfo->master->is_dummy_pass) {
 498.108 +#ifdef QUANT_2PASS_SUPPORTED
 498.109 +    /* Crank through the dummy pass */
 498.110 +    while (cinfo->output_scanline < cinfo->output_height) {
 498.111 +      JDIMENSION last_scanline;
 498.112 +      /* Call progress monitor hook if present */
 498.113 +      if (cinfo->progress != NULL) {
 498.114 +	cinfo->progress->pass_counter = (long) cinfo->output_scanline;
 498.115 +	cinfo->progress->pass_limit = (long) cinfo->output_height;
 498.116 +	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 498.117 +      }
 498.118 +      /* Process some data */
 498.119 +      last_scanline = cinfo->output_scanline;
 498.120 +      (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
 498.121 +				    &cinfo->output_scanline, (JDIMENSION) 0);
 498.122 +      if (cinfo->output_scanline == last_scanline)
 498.123 +	return FALSE;		/* No progress made, must suspend */
 498.124 +    }
 498.125 +    /* Finish up dummy pass, and set up for another one */
 498.126 +    (*cinfo->master->finish_output_pass) (cinfo);
 498.127 +    (*cinfo->master->prepare_for_output_pass) (cinfo);
 498.128 +    cinfo->output_scanline = 0;
 498.129 +#else
 498.130 +    ERREXIT(cinfo, JERR_NOT_COMPILED);
 498.131 +#endif /* QUANT_2PASS_SUPPORTED */
 498.132 +  }
 498.133 +  /* Ready for application to drive output pass through
 498.134 +   * jpeg_read_scanlines or jpeg_read_raw_data.
 498.135 +   */
 498.136 +  cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
 498.137 +  return TRUE;
 498.138 +}
 498.139 +
 498.140 +
 498.141 +/*
 498.142 + * Read some scanlines of data from the JPEG decompressor.
 498.143 + *
 498.144 + * The return value will be the number of lines actually read.
 498.145 + * This may be less than the number requested in several cases,
 498.146 + * including bottom of image, data source suspension, and operating
 498.147 + * modes that emit multiple scanlines at a time.
 498.148 + *
 498.149 + * Note: we warn about excess calls to jpeg_read_scanlines() since
 498.150 + * this likely signals an application programmer error.  However,
 498.151 + * an oversize buffer (max_lines > scanlines remaining) is not an error.
 498.152 + */
 498.153 +
 498.154 +GLOBAL(JDIMENSION)
 498.155 +jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
 498.156 +		     JDIMENSION max_lines)
 498.157 +{
 498.158 +  JDIMENSION row_ctr;
 498.159 +
 498.160 +  if (cinfo->global_state != DSTATE_SCANNING)
 498.161 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 498.162 +  if (cinfo->output_scanline >= cinfo->output_height) {
 498.163 +    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
 498.164 +    return 0;
 498.165 +  }
 498.166 +
 498.167 +  /* Call progress monitor hook if present */
 498.168 +  if (cinfo->progress != NULL) {
 498.169 +    cinfo->progress->pass_counter = (long) cinfo->output_scanline;
 498.170 +    cinfo->progress->pass_limit = (long) cinfo->output_height;
 498.171 +    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 498.172 +  }
 498.173 +
 498.174 +  /* Process some data */
 498.175 +  row_ctr = 0;
 498.176 +  (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
 498.177 +  cinfo->output_scanline += row_ctr;
 498.178 +  return row_ctr;
 498.179 +}
 498.180 +
 498.181 +
 498.182 +/*
 498.183 + * Alternate entry point to read raw data.
 498.184 + * Processes exactly one iMCU row per call, unless suspended.
 498.185 + */
 498.186 +
 498.187 +GLOBAL(JDIMENSION)
 498.188 +jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
 498.189 +		    JDIMENSION max_lines)
 498.190 +{
 498.191 +  JDIMENSION lines_per_iMCU_row;
 498.192 +
 498.193 +  if (cinfo->global_state != DSTATE_RAW_OK)
 498.194 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 498.195 +  if (cinfo->output_scanline >= cinfo->output_height) {
 498.196 +    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
 498.197 +    return 0;
 498.198 +  }
 498.199 +
 498.200 +  /* Call progress monitor hook if present */
 498.201 +  if (cinfo->progress != NULL) {
 498.202 +    cinfo->progress->pass_counter = (long) cinfo->output_scanline;
 498.203 +    cinfo->progress->pass_limit = (long) cinfo->output_height;
 498.204 +    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 498.205 +  }
 498.206 +
 498.207 +  /* Verify that at least one iMCU row can be returned. */
 498.208 +  lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
 498.209 +  if (max_lines < lines_per_iMCU_row)
 498.210 +    ERREXIT(cinfo, JERR_BUFFER_SIZE);
 498.211 +
 498.212 +  /* Decompress directly into user's buffer. */
 498.213 +  if (! (*cinfo->coef->decompress_data) (cinfo, data))
 498.214 +    return 0;			/* suspension forced, can do nothing more */
 498.215 +
 498.216 +  /* OK, we processed one iMCU row. */
 498.217 +  cinfo->output_scanline += lines_per_iMCU_row;
 498.218 +  return lines_per_iMCU_row;
 498.219 +}
 498.220 +
 498.221 +
 498.222 +/* Additional entry points for buffered-image mode. */
 498.223 +
 498.224 +#ifdef D_MULTISCAN_FILES_SUPPORTED
 498.225 +
 498.226 +/*
 498.227 + * Initialize for an output pass in buffered-image mode.
 498.228 + */
 498.229 +
 498.230 +GLOBAL(boolean)
 498.231 +jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
 498.232 +{
 498.233 +  if (cinfo->global_state != DSTATE_BUFIMAGE &&
 498.234 +      cinfo->global_state != DSTATE_PRESCAN)
 498.235 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 498.236 +  /* Limit scan number to valid range */
 498.237 +  if (scan_number <= 0)
 498.238 +    scan_number = 1;
 498.239 +  if (cinfo->inputctl->eoi_reached &&
 498.240 +      scan_number > cinfo->input_scan_number)
 498.241 +    scan_number = cinfo->input_scan_number;
 498.242 +  cinfo->output_scan_number = scan_number;
 498.243 +  /* Perform any dummy output passes, and set up for the real pass */
 498.244 +  return output_pass_setup(cinfo);
 498.245 +}
 498.246 +
 498.247 +
 498.248 +/*
 498.249 + * Finish up after an output pass in buffered-image mode.
 498.250 + *
 498.251 + * Returns FALSE if suspended.  The return value need be inspected only if
 498.252 + * a suspending data source is used.
 498.253 + */
 498.254 +
 498.255 +GLOBAL(boolean)
 498.256 +jpeg_finish_output (j_decompress_ptr cinfo)
 498.257 +{
 498.258 +  if ((cinfo->global_state == DSTATE_SCANNING ||
 498.259 +       cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
 498.260 +    /* Terminate this pass. */
 498.261 +    /* We do not require the whole pass to have been completed. */
 498.262 +    (*cinfo->master->finish_output_pass) (cinfo);
 498.263 +    cinfo->global_state = DSTATE_BUFPOST;
 498.264 +  } else if (cinfo->global_state != DSTATE_BUFPOST) {
 498.265 +    /* BUFPOST = repeat call after a suspension, anything else is error */
 498.266 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 498.267 +  }
 498.268 +  /* Read markers looking for SOS or EOI */
 498.269 +  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
 498.270 +	 ! cinfo->inputctl->eoi_reached) {
 498.271 +    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
 498.272 +      return FALSE;		/* Suspend, come back later */
 498.273 +  }
 498.274 +  cinfo->global_state = DSTATE_BUFIMAGE;
 498.275 +  return TRUE;
 498.276 +}
 498.277 +
 498.278 +#endif /* D_MULTISCAN_FILES_SUPPORTED */
   499.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   499.2 +++ b/libs/libjpeg/jdatadst.c	Sat Feb 01 19:58:19 2014 +0200
   499.3 @@ -0,0 +1,151 @@
   499.4 +/*
   499.5 + * jdatadst.c
   499.6 + *
   499.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   499.8 + * This file is part of the Independent JPEG Group's software.
   499.9 + * For conditions of distribution and use, see the accompanying README file.
  499.10 + *
  499.11 + * This file contains compression data destination routines for the case of
  499.12 + * emitting JPEG data to a file (or any stdio stream).  While these routines
  499.13 + * are sufficient for most applications, some will want to use a different
  499.14 + * destination manager.
  499.15 + * IMPORTANT: we assume that fwrite() will correctly transcribe an array of
  499.16 + * JOCTETs into 8-bit-wide elements on external storage.  If char is wider
  499.17 + * than 8 bits on your machine, you may need to do some tweaking.
  499.18 + */
  499.19 +
  499.20 +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
  499.21 +#include "jinclude.h"
  499.22 +#include "jpeglib.h"
  499.23 +#include "jerror.h"
  499.24 +
  499.25 +
  499.26 +/* Expanded data destination object for stdio output */
  499.27 +
  499.28 +typedef struct {
  499.29 +  struct jpeg_destination_mgr pub; /* public fields */
  499.30 +
  499.31 +  FILE * outfile;		/* target stream */
  499.32 +  JOCTET * buffer;		/* start of buffer */
  499.33 +} my_destination_mgr;
  499.34 +
  499.35 +typedef my_destination_mgr * my_dest_ptr;
  499.36 +
  499.37 +#define OUTPUT_BUF_SIZE  4096	/* choose an efficiently fwrite'able size */
  499.38 +
  499.39 +
  499.40 +/*
  499.41 + * Initialize destination --- called by jpeg_start_compress
  499.42 + * before any data is actually written.
  499.43 + */
  499.44 +
  499.45 +METHODDEF(void)
  499.46 +init_destination (j_compress_ptr cinfo)
  499.47 +{
  499.48 +  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
  499.49 +
  499.50 +  /* Allocate the output buffer --- it will be released when done with image */
  499.51 +  dest->buffer = (JOCTET *)
  499.52 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  499.53 +				  OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
  499.54 +
  499.55 +  dest->pub.next_output_byte = dest->buffer;
  499.56 +  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
  499.57 +}
  499.58 +
  499.59 +
  499.60 +/*
  499.61 + * Empty the output buffer --- called whenever buffer fills up.
  499.62 + *
  499.63 + * In typical applications, this should write the entire output buffer
  499.64 + * (ignoring the current state of next_output_byte & free_in_buffer),
  499.65 + * reset the pointer & count to the start of the buffer, and return TRUE
  499.66 + * indicating that the buffer has been dumped.
  499.67 + *
  499.68 + * In applications that need to be able to suspend compression due to output
  499.69 + * overrun, a FALSE return indicates that the buffer cannot be emptied now.
  499.70 + * In this situation, the compressor will return to its caller (possibly with
  499.71 + * an indication that it has not accepted all the supplied scanlines).  The
  499.72 + * application should resume compression after it has made more room in the
  499.73 + * output buffer.  Note that there are substantial restrictions on the use of
  499.74 + * suspension --- see the documentation.
  499.75 + *
  499.76 + * When suspending, the compressor will back up to a convenient restart point
  499.77 + * (typically the start of the current MCU). next_output_byte & free_in_buffer
  499.78 + * indicate where the restart point will be if the current call returns FALSE.
  499.79 + * Data beyond this point will be regenerated after resumption, so do not
  499.80 + * write it out when emptying the buffer externally.
  499.81 + */
  499.82 +
  499.83 +METHODDEF(boolean)
  499.84 +empty_output_buffer (j_compress_ptr cinfo)
  499.85 +{
  499.86 +  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
  499.87 +
  499.88 +  if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) !=
  499.89 +      (size_t) OUTPUT_BUF_SIZE)
  499.90 +    ERREXIT(cinfo, JERR_FILE_WRITE);
  499.91 +
  499.92 +  dest->pub.next_output_byte = dest->buffer;
  499.93 +  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
  499.94 +
  499.95 +  return TRUE;
  499.96 +}
  499.97 +
  499.98 +
  499.99 +/*
 499.100 + * Terminate destination --- called by jpeg_finish_compress
 499.101 + * after all data has been written.  Usually needs to flush buffer.
 499.102 + *
 499.103 + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
 499.104 + * application must deal with any cleanup that should happen even
 499.105 + * for error exit.
 499.106 + */
 499.107 +
 499.108 +METHODDEF(void)
 499.109 +term_destination (j_compress_ptr cinfo)
 499.110 +{
 499.111 +  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
 499.112 +  size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
 499.113 +
 499.114 +  /* Write any data remaining in the buffer */
 499.115 +  if (datacount > 0) {
 499.116 +    if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
 499.117 +      ERREXIT(cinfo, JERR_FILE_WRITE);
 499.118 +  }
 499.119 +  fflush(dest->outfile);
 499.120 +  /* Make sure we wrote the output file OK */
 499.121 +  if (ferror(dest->outfile))
 499.122 +    ERREXIT(cinfo, JERR_FILE_WRITE);
 499.123 +}
 499.124 +
 499.125 +
 499.126 +/*
 499.127 + * Prepare for output to a stdio stream.
 499.128 + * The caller must have already opened the stream, and is responsible
 499.129 + * for closing it after finishing compression.
 499.130 + */
 499.131 +
 499.132 +GLOBAL(void)
 499.133 +jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
 499.134 +{
 499.135 +  my_dest_ptr dest;
 499.136 +
 499.137 +  /* The destination object is made permanent so that multiple JPEG images
 499.138 +   * can be written to the same file without re-executing jpeg_stdio_dest.
 499.139 +   * This makes it dangerous to use this manager and a different destination
 499.140 +   * manager serially with the same JPEG object, because their private object
 499.141 +   * sizes may be different.  Caveat programmer.
 499.142 +   */
 499.143 +  if (cinfo->dest == NULL) {	/* first time for this JPEG object? */
 499.144 +    cinfo->dest = (struct jpeg_destination_mgr *)
 499.145 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 499.146 +				  SIZEOF(my_destination_mgr));
 499.147 +  }
 499.148 +
 499.149 +  dest = (my_dest_ptr) cinfo->dest;
 499.150 +  dest->pub.init_destination = init_destination;
 499.151 +  dest->pub.empty_output_buffer = empty_output_buffer;
 499.152 +  dest->pub.term_destination = term_destination;
 499.153 +  dest->outfile = outfile;
 499.154 +}
   500.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   500.2 +++ b/libs/libjpeg/jdatasrc.c	Sat Feb 01 19:58:19 2014 +0200
   500.3 @@ -0,0 +1,212 @@
   500.4 +/*
   500.5 + * jdatasrc.c
   500.6 + *
   500.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   500.8 + * This file is part of the Independent JPEG Group's software.
   500.9 + * For conditions of distribution and use, see the accompanying README file.
  500.10 + *
  500.11 + * This file contains decompression data source routines for the case of
  500.12 + * reading JPEG data from a file (or any stdio stream).  While these routines
  500.13 + * are sufficient for most applications, some will want to use a different
  500.14 + * source manager.
  500.15 + * IMPORTANT: we assume that fread() will correctly transcribe an array of
  500.16 + * JOCTETs from 8-bit-wide elements on external storage.  If char is wider
  500.17 + * than 8 bits on your machine, you may need to do some tweaking.
  500.18 + */
  500.19 +
  500.20 +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
  500.21 +#include "jinclude.h"
  500.22 +#include "jpeglib.h"
  500.23 +#include "jerror.h"
  500.24 +
  500.25 +
  500.26 +/* Expanded data source object for stdio input */
  500.27 +
  500.28 +typedef struct {
  500.29 +  struct jpeg_source_mgr pub;	/* public fields */
  500.30 +
  500.31 +  FILE * infile;		/* source stream */
  500.32 +  JOCTET * buffer;		/* start of buffer */
  500.33 +  boolean start_of_file;	/* have we gotten any data yet? */
  500.34 +} my_source_mgr;
  500.35 +
  500.36 +typedef my_source_mgr * my_src_ptr;
  500.37 +
  500.38 +#define INPUT_BUF_SIZE  4096	/* choose an efficiently fread'able size */
  500.39 +
  500.40 +
  500.41 +/*
  500.42 + * Initialize source --- called by jpeg_read_header
  500.43 + * before any data is actually read.
  500.44 + */
  500.45 +
  500.46 +METHODDEF(void)
  500.47 +init_source (j_decompress_ptr cinfo)
  500.48 +{
  500.49 +  my_src_ptr src = (my_src_ptr) cinfo->src;
  500.50 +
  500.51 +  /* We reset the empty-input-file flag for each image,
  500.52 +   * but we don't clear the input buffer.
  500.53 +   * This is correct behavior for reading a series of images from one source.
  500.54 +   */
  500.55 +  src->start_of_file = TRUE;
  500.56 +}
  500.57 +
  500.58 +
  500.59 +/*
  500.60 + * Fill the input buffer --- called whenever buffer is emptied.
  500.61 + *
  500.62 + * In typical applications, this should read fresh data into the buffer
  500.63 + * (ignoring the current state of next_input_byte & bytes_in_buffer),
  500.64 + * reset the pointer & count to the start of the buffer, and return TRUE
  500.65 + * indicating that the buffer has been reloaded.  It is not necessary to
  500.66 + * fill the buffer entirely, only to obtain at least one more byte.
  500.67 + *
  500.68 + * There is no such thing as an EOF return.  If the end of the file has been
  500.69 + * reached, the routine has a choice of ERREXIT() or inserting fake data into
  500.70 + * the buffer.  In most cases, generating a warning message and inserting a
  500.71 + * fake EOI marker is the best course of action --- this will allow the
  500.72 + * decompressor to output however much of the image is there.  However,
  500.73 + * the resulting error message is misleading if the real problem is an empty
  500.74 + * input file, so we handle that case specially.
  500.75 + *
  500.76 + * In applications that need to be able to suspend compression due to input
  500.77 + * not being available yet, a FALSE return indicates that no more data can be
  500.78 + * obtained right now, but more may be forthcoming later.  In this situation,
  500.79 + * the decompressor will return to its caller (with an indication of the
  500.80 + * number of scanlines it has read, if any).  The application should resume
  500.81 + * decompression after it has loaded more data into the input buffer.  Note
  500.82 + * that there are substantial restrictions on the use of suspension --- see
  500.83 + * the documentation.
  500.84 + *
  500.85 + * When suspending, the decompressor will back up to a convenient restart point
  500.86 + * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
  500.87 + * indicate where the restart point will be if the current call returns FALSE.
  500.88 + * Data beyond this point must be rescanned after resumption, so move it to
  500.89 + * the front of the buffer rather than discarding it.
  500.90 + */
  500.91 +
  500.92 +METHODDEF(boolean)
  500.93 +fill_input_buffer (j_decompress_ptr cinfo)
  500.94 +{
  500.95 +  my_src_ptr src = (my_src_ptr) cinfo->src;
  500.96 +  size_t nbytes;
  500.97 +
  500.98 +  nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
  500.99 +
 500.100 +  if (nbytes <= 0) {
 500.101 +    if (src->start_of_file)	/* Treat empty input file as fatal error */
 500.102 +      ERREXIT(cinfo, JERR_INPUT_EMPTY);
 500.103 +    WARNMS(cinfo, JWRN_JPEG_EOF);
 500.104 +    /* Insert a fake EOI marker */
 500.105 +    src->buffer[0] = (JOCTET) 0xFF;
 500.106 +    src->buffer[1] = (JOCTET) JPEG_EOI;
 500.107 +    nbytes = 2;
 500.108 +  }
 500.109 +
 500.110 +  src->pub.next_input_byte = src->buffer;
 500.111 +  src->pub.bytes_in_buffer = nbytes;
 500.112 +  src->start_of_file = FALSE;
 500.113 +
 500.114 +  return TRUE;
 500.115 +}
 500.116 +
 500.117 +
 500.118 +/*
 500.119 + * Skip data --- used to skip over a potentially large amount of
 500.120 + * uninteresting data (such as an APPn marker).
 500.121 + *
 500.122 + * Writers of suspendable-input applications must note that skip_input_data
 500.123 + * is not granted the right to give a suspension return.  If the skip extends
 500.124 + * beyond the data currently in the buffer, the buffer can be marked empty so
 500.125 + * that the next read will cause a fill_input_buffer call that can suspend.
 500.126 + * Arranging for additional bytes to be discarded before reloading the input
 500.127 + * buffer is the application writer's problem.
 500.128 + */
 500.129 +
 500.130 +METHODDEF(void)
 500.131 +skip_input_data (j_decompress_ptr cinfo, long num_bytes)
 500.132 +{
 500.133 +  my_src_ptr src = (my_src_ptr) cinfo->src;
 500.134 +
 500.135 +  /* Just a dumb implementation for now.  Could use fseek() except
 500.136 +   * it doesn't work on pipes.  Not clear that being smart is worth
 500.137 +   * any trouble anyway --- large skips are infrequent.
 500.138 +   */
 500.139 +  if (num_bytes > 0) {
 500.140 +    while (num_bytes > (long) src->pub.bytes_in_buffer) {
 500.141 +      num_bytes -= (long) src->pub.bytes_in_buffer;
 500.142 +      (void) fill_input_buffer(cinfo);
 500.143 +      /* note we assume that fill_input_buffer will never return FALSE,
 500.144 +       * so suspension need not be handled.
 500.145 +       */
 500.146 +    }
 500.147 +    src->pub.next_input_byte += (size_t) num_bytes;
 500.148 +    src->pub.bytes_in_buffer -= (size_t) num_bytes;
 500.149 +  }
 500.150 +}
 500.151 +
 500.152 +
 500.153 +/*
 500.154 + * An additional method that can be provided by data source modules is the
 500.155 + * resync_to_restart method for error recovery in the presence of RST markers.
 500.156 + * For the moment, this source module just uses the default resync method
 500.157 + * provided by the JPEG library.  That method assumes that no backtracking
 500.158 + * is possible.
 500.159 + */
 500.160 +
 500.161 +
 500.162 +/*
 500.163 + * Terminate source --- called by jpeg_finish_decompress
 500.164 + * after all data has been read.  Often a no-op.
 500.165 + *
 500.166 + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
 500.167 + * application must deal with any cleanup that should happen even
 500.168 + * for error exit.
 500.169 + */
 500.170 +
 500.171 +METHODDEF(void)
 500.172 +term_source (j_decompress_ptr cinfo)
 500.173 +{
 500.174 +  /* no work necessary here */
 500.175 +}
 500.176 +
 500.177 +
 500.178 +/*
 500.179 + * Prepare for input from a stdio stream.
 500.180 + * The caller must have already opened the stream, and is responsible
 500.181 + * for closing it after finishing decompression.
 500.182 + */
 500.183 +
 500.184 +GLOBAL(void)
 500.185 +jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
 500.186 +{
 500.187 +  my_src_ptr src;
 500.188 +
 500.189 +  /* The source object and input buffer are made permanent so that a series
 500.190 +   * of JPEG images can be read from the same file by calling jpeg_stdio_src
 500.191 +   * only before the first one.  (If we discarded the buffer at the end of
 500.192 +   * one image, we'd likely lose the start of the next one.)
 500.193 +   * This makes it unsafe to use this manager and a different source
 500.194 +   * manager serially with the same JPEG object.  Caveat programmer.
 500.195 +   */
 500.196 +  if (cinfo->src == NULL) {	/* first time for this JPEG object? */
 500.197 +    cinfo->src = (struct jpeg_source_mgr *)
 500.198 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 500.199 +				  SIZEOF(my_source_mgr));
 500.200 +    src = (my_src_ptr) cinfo->src;
 500.201 +    src->buffer = (JOCTET *)
 500.202 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 500.203 +				  INPUT_BUF_SIZE * SIZEOF(JOCTET));
 500.204 +  }
 500.205 +
 500.206 +  src = (my_src_ptr) cinfo->src;
 500.207 +  src->pub.init_source = init_source;
 500.208 +  src->pub.fill_input_buffer = fill_input_buffer;
 500.209 +  src->pub.skip_input_data = skip_input_data;
 500.210 +  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
 500.211 +  src->pub.term_source = term_source;
 500.212 +  src->infile = infile;
 500.213 +  src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
 500.214 +  src->pub.next_input_byte = NULL; /* until buffer loaded */
 500.215 +}
   501.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   501.2 +++ b/libs/libjpeg/jdcoefct.c	Sat Feb 01 19:58:19 2014 +0200
   501.3 @@ -0,0 +1,736 @@
   501.4 +/*
   501.5 + * jdcoefct.c
   501.6 + *
   501.7 + * Copyright (C) 1994-1997, Thomas G. Lane.
   501.8 + * This file is part of the Independent JPEG Group's software.
   501.9 + * For conditions of distribution and use, see the accompanying README file.
  501.10 + *
  501.11 + * This file contains the coefficient buffer controller for decompression.
  501.12 + * This controller is the top level of the JPEG decompressor proper.
  501.13 + * The coefficient buffer lies between entropy decoding and inverse-DCT steps.
  501.14 + *
  501.15 + * In buffered-image mode, this controller is the interface between
  501.16 + * input-oriented processing and output-oriented processing.
  501.17 + * Also, the input side (only) is used when reading a file for transcoding.
  501.18 + */
  501.19 +
  501.20 +#define JPEG_INTERNALS
  501.21 +#include "jinclude.h"
  501.22 +#include "jpeglib.h"
  501.23 +
  501.24 +/* Block smoothing is only applicable for progressive JPEG, so: */
  501.25 +#ifndef D_PROGRESSIVE_SUPPORTED
  501.26 +#undef BLOCK_SMOOTHING_SUPPORTED
  501.27 +#endif
  501.28 +
  501.29 +/* Private buffer controller object */
  501.30 +
  501.31 +typedef struct {
  501.32 +  struct jpeg_d_coef_controller pub; /* public fields */
  501.33 +
  501.34 +  /* These variables keep track of the current location of the input side. */
  501.35 +  /* cinfo->input_iMCU_row is also used for this. */
  501.36 +  JDIMENSION MCU_ctr;		/* counts MCUs processed in current row */
  501.37 +  int MCU_vert_offset;		/* counts MCU rows within iMCU row */
  501.38 +  int MCU_rows_per_iMCU_row;	/* number of such rows needed */
  501.39 +
  501.40 +  /* The output side's location is represented by cinfo->output_iMCU_row. */
  501.41 +
  501.42 +  /* In single-pass modes, it's sufficient to buffer just one MCU.
  501.43 +   * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
  501.44 +   * and let the entropy decoder write into that workspace each time.
  501.45 +   * (On 80x86, the workspace is FAR even though it's not really very big;
  501.46 +   * this is to keep the module interfaces unchanged when a large coefficient
  501.47 +   * buffer is necessary.)
  501.48 +   * In multi-pass modes, this array points to the current MCU's blocks
  501.49 +   * within the virtual arrays; it is used only by the input side.
  501.50 +   */
  501.51 +  JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
  501.52 +
  501.53 +#ifdef D_MULTISCAN_FILES_SUPPORTED
  501.54 +  /* In multi-pass modes, we need a virtual block array for each component. */
  501.55 +  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
  501.56 +#endif
  501.57 +
  501.58 +#ifdef BLOCK_SMOOTHING_SUPPORTED
  501.59 +  /* When doing block smoothing, we latch coefficient Al values here */
  501.60 +  int * coef_bits_latch;
  501.61 +#define SAVED_COEFS  6		/* we save coef_bits[0..5] */
  501.62 +#endif
  501.63 +} my_coef_controller;
  501.64 +
  501.65 +typedef my_coef_controller * my_coef_ptr;
  501.66 +
  501.67 +/* Forward declarations */
  501.68 +METHODDEF(int) decompress_onepass
  501.69 +	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
  501.70 +#ifdef D_MULTISCAN_FILES_SUPPORTED
  501.71 +METHODDEF(int) decompress_data
  501.72 +	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
  501.73 +#endif
  501.74 +#ifdef BLOCK_SMOOTHING_SUPPORTED
  501.75 +LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
  501.76 +METHODDEF(int) decompress_smooth_data
  501.77 +	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
  501.78 +#endif
  501.79 +
  501.80 +
  501.81 +LOCAL(void)
  501.82 +start_iMCU_row (j_decompress_ptr cinfo)
  501.83 +/* Reset within-iMCU-row counters for a new row (input side) */
  501.84 +{
  501.85 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  501.86 +
  501.87 +  /* In an interleaved scan, an MCU row is the same as an iMCU row.
  501.88 +   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
  501.89 +   * But at the bottom of the image, process only what's left.
  501.90 +   */
  501.91 +  if (cinfo->comps_in_scan > 1) {
  501.92 +    coef->MCU_rows_per_iMCU_row = 1;
  501.93 +  } else {
  501.94 +    if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
  501.95 +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
  501.96 +    else
  501.97 +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
  501.98 +  }
  501.99 +
 501.100 +  coef->MCU_ctr = 0;
 501.101 +  coef->MCU_vert_offset = 0;
 501.102 +}
 501.103 +
 501.104 +
 501.105 +/*
 501.106 + * Initialize for an input processing pass.
 501.107 + */
 501.108 +
 501.109 +METHODDEF(void)
 501.110 +start_input_pass (j_decompress_ptr cinfo)
 501.111 +{
 501.112 +  cinfo->input_iMCU_row = 0;
 501.113 +  start_iMCU_row(cinfo);
 501.114 +}
 501.115 +
 501.116 +
 501.117 +/*
 501.118 + * Initialize for an output processing pass.
 501.119 + */
 501.120 +
 501.121 +METHODDEF(void)
 501.122 +start_output_pass (j_decompress_ptr cinfo)
 501.123 +{
 501.124 +#ifdef BLOCK_SMOOTHING_SUPPORTED
 501.125 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 501.126 +
 501.127 +  /* If multipass, check to see whether to use block smoothing on this pass */
 501.128 +  if (coef->pub.coef_arrays != NULL) {
 501.129 +    if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
 501.130 +      coef->pub.decompress_data = decompress_smooth_data;
 501.131 +    else
 501.132 +      coef->pub.decompress_data = decompress_data;
 501.133 +  }
 501.134 +#endif
 501.135 +  cinfo->output_iMCU_row = 0;
 501.136 +}
 501.137 +
 501.138 +
 501.139 +/*
 501.140 + * Decompress and return some data in the single-pass case.
 501.141 + * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
 501.142 + * Input and output must run in lockstep since we have only a one-MCU buffer.
 501.143 + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
 501.144 + *
 501.145 + * NB: output_buf contains a plane for each component in image,
 501.146 + * which we index according to the component's SOF position.
 501.147 + */
 501.148 +
 501.149 +METHODDEF(int)
 501.150 +decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
 501.151 +{
 501.152 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 501.153 +  JDIMENSION MCU_col_num;	/* index of current MCU within row */
 501.154 +  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
 501.155 +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
 501.156 +  int blkn, ci, xindex, yindex, yoffset, useful_width;
 501.157 +  JSAMPARRAY output_ptr;
 501.158 +  JDIMENSION start_col, output_col;
 501.159 +  jpeg_component_info *compptr;
 501.160 +  inverse_DCT_method_ptr inverse_DCT;
 501.161 +
 501.162 +  /* Loop to process as much as one whole iMCU row */
 501.163 +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
 501.164 +       yoffset++) {
 501.165 +    for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
 501.166 +	 MCU_col_num++) {
 501.167 +      /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
 501.168 +      jzero_far((void FAR *) coef->MCU_buffer[0],
 501.169 +		(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
 501.170 +      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
 501.171 +	/* Suspension forced; update state counters and exit */
 501.172 +	coef->MCU_vert_offset = yoffset;
 501.173 +	coef->MCU_ctr = MCU_col_num;
 501.174 +	return JPEG_SUSPENDED;
 501.175 +      }
 501.176 +      /* Determine where data should go in output_buf and do the IDCT thing.
 501.177 +       * We skip dummy blocks at the right and bottom edges (but blkn gets
 501.178 +       * incremented past them!).  Note the inner loop relies on having
 501.179 +       * allocated the MCU_buffer[] blocks sequentially.
 501.180 +       */
 501.181 +      blkn = 0;			/* index of current DCT block within MCU */
 501.182 +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 501.183 +	compptr = cinfo->cur_comp_info[ci];
 501.184 +	/* Don't bother to IDCT an uninteresting component. */
 501.185 +	if (! compptr->component_needed) {
 501.186 +	  blkn += compptr->MCU_blocks;
 501.187 +	  continue;
 501.188 +	}
 501.189 +	inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
 501.190 +	useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
 501.191 +						    : compptr->last_col_width;
 501.192 +	output_ptr = output_buf[compptr->component_index] +
 501.193 +	  yoffset * compptr->DCT_scaled_size;
 501.194 +	start_col = MCU_col_num * compptr->MCU_sample_width;
 501.195 +	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
 501.196 +	  if (cinfo->input_iMCU_row < last_iMCU_row ||
 501.197 +	      yoffset+yindex < compptr->last_row_height) {
 501.198 +	    output_col = start_col;
 501.199 +	    for (xindex = 0; xindex < useful_width; xindex++) {
 501.200 +	      (*inverse_DCT) (cinfo, compptr,
 501.201 +			      (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
 501.202 +			      output_ptr, output_col);
 501.203 +	      output_col += compptr->DCT_scaled_size;
 501.204 +	    }
 501.205 +	  }
 501.206 +	  blkn += compptr->MCU_width;
 501.207 +	  output_ptr += compptr->DCT_scaled_size;
 501.208 +	}
 501.209 +      }
 501.210 +    }
 501.211 +    /* Completed an MCU row, but perhaps not an iMCU row */
 501.212 +    coef->MCU_ctr = 0;
 501.213 +  }
 501.214 +  /* Completed the iMCU row, advance counters for next one */
 501.215 +  cinfo->output_iMCU_row++;
 501.216 +  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
 501.217 +    start_iMCU_row(cinfo);
 501.218 +    return JPEG_ROW_COMPLETED;
 501.219 +  }
 501.220 +  /* Completed the scan */
 501.221 +  (*cinfo->inputctl->finish_input_pass) (cinfo);
 501.222 +  return JPEG_SCAN_COMPLETED;
 501.223 +}
 501.224 +
 501.225 +
 501.226 +/*
 501.227 + * Dummy consume-input routine for single-pass operation.
 501.228 + */
 501.229 +
 501.230 +METHODDEF(int)
 501.231 +dummy_consume_data (j_decompress_ptr cinfo)
 501.232 +{
 501.233 +  return JPEG_SUSPENDED;	/* Always indicate nothing was done */
 501.234 +}
 501.235 +
 501.236 +
 501.237 +#ifdef D_MULTISCAN_FILES_SUPPORTED
 501.238 +
 501.239 +/*
 501.240 + * Consume input data and store it in the full-image coefficient buffer.
 501.241 + * We read as much as one fully interleaved MCU row ("iMCU" row) per call,
 501.242 + * ie, v_samp_factor block rows for each component in the scan.
 501.243 + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
 501.244 + */
 501.245 +
 501.246 +METHODDEF(int)
 501.247 +consume_data (j_decompress_ptr cinfo)
 501.248 +{
 501.249 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 501.250 +  JDIMENSION MCU_col_num;	/* index of current MCU within row */
 501.251 +  int blkn, ci, xindex, yindex, yoffset;
 501.252 +  JDIMENSION start_col;
 501.253 +  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
 501.254 +  JBLOCKROW buffer_ptr;
 501.255 +  jpeg_component_info *compptr;
 501.256 +
 501.257 +  /* Align the virtual buffers for the components used in this scan. */
 501.258 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 501.259 +    compptr = cinfo->cur_comp_info[ci];
 501.260 +    buffer[ci] = (*cinfo->mem->access_virt_barray)
 501.261 +      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
 501.262 +       cinfo->input_iMCU_row * compptr->v_samp_factor,
 501.263 +       (JDIMENSION) compptr->v_samp_factor, TRUE);
 501.264 +    /* Note: entropy decoder expects buffer to be zeroed,
 501.265 +     * but this is handled automatically by the memory manager
 501.266 +     * because we requested a pre-zeroed array.
 501.267 +     */
 501.268 +  }
 501.269 +
 501.270 +  /* Loop to process one whole iMCU row */
 501.271 +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
 501.272 +       yoffset++) {
 501.273 +    for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
 501.274 +	 MCU_col_num++) {
 501.275 +      /* Construct list of pointers to DCT blocks belonging to this MCU */
 501.276 +      blkn = 0;			/* index of current DCT block within MCU */
 501.277 +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 501.278 +	compptr = cinfo->cur_comp_info[ci];
 501.279 +	start_col = MCU_col_num * compptr->MCU_width;
 501.280 +	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
 501.281 +	  buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
 501.282 +	  for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
 501.283 +	    coef->MCU_buffer[blkn++] = buffer_ptr++;
 501.284 +	  }
 501.285 +	}
 501.286 +      }
 501.287 +      /* Try to fetch the MCU. */
 501.288 +      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
 501.289 +	/* Suspension forced; update state counters and exit */
 501.290 +	coef->MCU_vert_offset = yoffset;
 501.291 +	coef->MCU_ctr = MCU_col_num;
 501.292 +	return JPEG_SUSPENDED;
 501.293 +      }
 501.294 +    }
 501.295 +    /* Completed an MCU row, but perhaps not an iMCU row */
 501.296 +    coef->MCU_ctr = 0;
 501.297 +  }
 501.298 +  /* Completed the iMCU row, advance counters for next one */
 501.299 +  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
 501.300 +    start_iMCU_row(cinfo);
 501.301 +    return JPEG_ROW_COMPLETED;
 501.302 +  }
 501.303 +  /* Completed the scan */
 501.304 +  (*cinfo->inputctl->finish_input_pass) (cinfo);
 501.305 +  return JPEG_SCAN_COMPLETED;
 501.306 +}
 501.307 +
 501.308 +
 501.309 +/*
 501.310 + * Decompress and return some data in the multi-pass case.
 501.311 + * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
 501.312 + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
 501.313 + *
 501.314 + * NB: output_buf contains a plane for each component in image.
 501.315 + */
 501.316 +
 501.317 +METHODDEF(int)
 501.318 +decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
 501.319 +{
 501.320 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 501.321 +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
 501.322 +  JDIMENSION block_num;
 501.323 +  int ci, block_row, block_rows;
 501.324 +  JBLOCKARRAY buffer;
 501.325 +  JBLOCKROW buffer_ptr;
 501.326 +  JSAMPARRAY output_ptr;
 501.327 +  JDIMENSION output_col;
 501.328 +  jpeg_component_info *compptr;
 501.329 +  inverse_DCT_method_ptr inverse_DCT;
 501.330 +
 501.331 +  /* Force some input to be done if we are getting ahead of the input. */
 501.332 +  while (cinfo->input_scan_number < cinfo->output_scan_number ||
 501.333 +	 (cinfo->input_scan_number == cinfo->output_scan_number &&
 501.334 +	  cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
 501.335 +    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
 501.336 +      return JPEG_SUSPENDED;
 501.337 +  }
 501.338 +
 501.339 +  /* OK, output from the virtual arrays. */
 501.340 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 501.341 +       ci++, compptr++) {
 501.342 +    /* Don't bother to IDCT an uninteresting component. */
 501.343 +    if (! compptr->component_needed)
 501.344 +      continue;
 501.345 +    /* Align the virtual buffer for this component. */
 501.346 +    buffer = (*cinfo->mem->access_virt_barray)
 501.347 +      ((j_common_ptr) cinfo, coef->whole_image[ci],
 501.348 +       cinfo->output_iMCU_row * compptr->v_samp_factor,
 501.349 +       (JDIMENSION) compptr->v_samp_factor, FALSE);
 501.350 +    /* Count non-dummy DCT block rows in this iMCU row. */
 501.351 +    if (cinfo->output_iMCU_row < last_iMCU_row)
 501.352 +      block_rows = compptr->v_samp_factor;
 501.353 +    else {
 501.354 +      /* NB: can't use last_row_height here; it is input-side-dependent! */
 501.355 +      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
 501.356 +      if (block_rows == 0) block_rows = compptr->v_samp_factor;
 501.357 +    }
 501.358 +    inverse_DCT = cinfo->idct->inverse_DCT[ci];
 501.359 +    output_ptr = output_buf[ci];
 501.360 +    /* Loop over all DCT blocks to be processed. */
 501.361 +    for (block_row = 0; block_row < block_rows; block_row++) {
 501.362 +      buffer_ptr = buffer[block_row];
 501.363 +      output_col = 0;
 501.364 +      for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
 501.365 +	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
 501.366 +			output_ptr, output_col);
 501.367 +	buffer_ptr++;
 501.368 +	output_col += compptr->DCT_scaled_size;
 501.369 +      }
 501.370 +      output_ptr += compptr->DCT_scaled_size;
 501.371 +    }
 501.372 +  }
 501.373 +
 501.374 +  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
 501.375 +    return JPEG_ROW_COMPLETED;
 501.376 +  return JPEG_SCAN_COMPLETED;
 501.377 +}
 501.378 +
 501.379 +#endif /* D_MULTISCAN_FILES_SUPPORTED */
 501.380 +
 501.381 +
 501.382 +#ifdef BLOCK_SMOOTHING_SUPPORTED
 501.383 +
 501.384 +/*
 501.385 + * This code applies interblock smoothing as described by section K.8
 501.386 + * of the JPEG standard: the first 5 AC coefficients are estimated from
 501.387 + * the DC values of a DCT block and its 8 neighboring blocks.
 501.388 + * We apply smoothing only for progressive JPEG decoding, and only if
 501.389 + * the coefficients it can estimate are not yet known to full precision.
 501.390 + */
 501.391 +
 501.392 +/* Natural-order array positions of the first 5 zigzag-order coefficients */
 501.393 +#define Q01_POS  1
 501.394 +#define Q10_POS  8
 501.395 +#define Q20_POS  16
 501.396 +#define Q11_POS  9
 501.397 +#define Q02_POS  2
 501.398 +
 501.399 +/*
 501.400 + * Determine whether block smoothing is applicable and safe.
 501.401 + * We also latch the current states of the coef_bits[] entries for the
 501.402 + * AC coefficients; otherwise, if the input side of the decompressor
 501.403 + * advances into a new scan, we might think the coefficients are known
 501.404 + * more accurately than they really are.
 501.405 + */
 501.406 +
 501.407 +LOCAL(boolean)
 501.408 +smoothing_ok (j_decompress_ptr cinfo)
 501.409 +{
 501.410 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 501.411 +  boolean smoothing_useful = FALSE;
 501.412 +  int ci, coefi;
 501.413 +  jpeg_component_info *compptr;
 501.414 +  JQUANT_TBL * qtable;
 501.415 +  int * coef_bits;
 501.416 +  int * coef_bits_latch;
 501.417 +
 501.418 +  if (! cinfo->progressive_mode || cinfo->coef_bits == NULL)
 501.419 +    return FALSE;
 501.420 +
 501.421 +  /* Allocate latch area if not already done */
 501.422 +  if (coef->coef_bits_latch == NULL)
 501.423 +    coef->coef_bits_latch = (int *)
 501.424 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 501.425 +				  cinfo->num_components *
 501.426 +				  (SAVED_COEFS * SIZEOF(int)));
 501.427 +  coef_bits_latch = coef->coef_bits_latch;
 501.428 +
 501.429 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 501.430 +       ci++, compptr++) {
 501.431 +    /* All components' quantization values must already be latched. */
 501.432 +    if ((qtable = compptr->quant_table) == NULL)
 501.433 +      return FALSE;
 501.434 +    /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
 501.435 +    if (qtable->quantval[0] == 0 ||
 501.436 +	qtable->quantval[Q01_POS] == 0 ||
 501.437 +	qtable->quantval[Q10_POS] == 0 ||
 501.438 +	qtable->quantval[Q20_POS] == 0 ||
 501.439 +	qtable->quantval[Q11_POS] == 0 ||
 501.440 +	qtable->quantval[Q02_POS] == 0)
 501.441 +      return FALSE;
 501.442 +    /* DC values must be at least partly known for all components. */
 501.443 +    coef_bits = cinfo->coef_bits[ci];
 501.444 +    if (coef_bits[0] < 0)
 501.445 +      return FALSE;
 501.446 +    /* Block smoothing is helpful if some AC coefficients remain inaccurate. */
 501.447 +    for (coefi = 1; coefi <= 5; coefi++) {
 501.448 +      coef_bits_latch[coefi] = coef_bits[coefi];
 501.449 +      if (coef_bits[coefi] != 0)
 501.450 +	smoothing_useful = TRUE;
 501.451 +    }
 501.452 +    coef_bits_latch += SAVED_COEFS;
 501.453 +  }
 501.454 +
 501.455 +  return smoothing_useful;
 501.456 +}
 501.457 +
 501.458 +
 501.459 +/*
 501.460 + * Variant of decompress_data for use when doing block smoothing.
 501.461 + */
 501.462 +
 501.463 +METHODDEF(int)
 501.464 +decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
 501.465 +{
 501.466 +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 501.467 +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
 501.468 +  JDIMENSION block_num, last_block_column;
 501.469 +  int ci, block_row, block_rows, access_rows;
 501.470 +  JBLOCKARRAY buffer;
 501.471 +  JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
 501.472 +  JSAMPARRAY output_ptr;
 501.473 +  JDIMENSION output_col;
 501.474 +  jpeg_component_info *compptr;
 501.475 +  inverse_DCT_method_ptr inverse_DCT;
 501.476 +  boolean first_row, last_row;
 501.477 +  JBLOCK workspace;
 501.478 +  int *coef_bits;
 501.479 +  JQUANT_TBL *quanttbl;
 501.480 +  INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
 501.481 +  int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
 501.482 +  int Al, pred;
 501.483 +
 501.484 +  /* Force some input to be done if we are getting ahead of the input. */
 501.485 +  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
 501.486 +	 ! cinfo->inputctl->eoi_reached) {
 501.487 +    if (cinfo->input_scan_number == cinfo->output_scan_number) {
 501.488 +      /* If input is working on current scan, we ordinarily want it to
 501.489 +       * have completed the current row.  But if input scan is DC,
 501.490 +       * we want it to keep one row ahead so that next block row's DC
 501.491 +       * values are up to date.
 501.492 +       */
 501.493 +      JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
 501.494 +      if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta)
 501.495 +	break;
 501.496 +    }
 501.497 +    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
 501.498 +      return JPEG_SUSPENDED;
 501.499 +  }
 501.500 +
 501.501 +  /* OK, output from the virtual arrays. */
 501.502 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 501.503 +       ci++, compptr++) {
 501.504 +    /* Don't bother to IDCT an uninteresting component. */
 501.505 +    if (! compptr->component_needed)
 501.506 +      continue;
 501.507 +    /* Count non-dummy DCT block rows in this iMCU row. */
 501.508 +    if (cinfo->output_iMCU_row < last_iMCU_row) {
 501.509 +      block_rows = compptr->v_samp_factor;
 501.510 +      access_rows = block_rows * 2; /* this and next iMCU row */
 501.511 +      last_row = FALSE;
 501.512 +    } else {
 501.513 +      /* NB: can't use last_row_height here; it is input-side-dependent! */
 501.514 +      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
 501.515 +      if (block_rows == 0) block_rows = compptr->v_samp_factor;
 501.516 +      access_rows = block_rows; /* this iMCU row only */
 501.517 +      last_row = TRUE;
 501.518 +    }
 501.519 +    /* Align the virtual buffer for this component. */
 501.520 +    if (cinfo->output_iMCU_row > 0) {
 501.521 +      access_rows += compptr->v_samp_factor; /* prior iMCU row too */
 501.522 +      buffer = (*cinfo->mem->access_virt_barray)
 501.523 +	((j_common_ptr) cinfo, coef->whole_image[ci],
 501.524 +	 (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
 501.525 +	 (JDIMENSION) access_rows, FALSE);
 501.526 +      buffer += compptr->v_samp_factor;	/* point to current iMCU row */
 501.527 +      first_row = FALSE;
 501.528 +    } else {
 501.529 +      buffer = (*cinfo->mem->access_virt_barray)
 501.530 +	((j_common_ptr) cinfo, coef->whole_image[ci],
 501.531 +	 (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
 501.532 +      first_row = TRUE;
 501.533 +    }
 501.534 +    /* Fetch component-dependent info */
 501.535 +    coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
 501.536 +    quanttbl = compptr->quant_table;
 501.537 +    Q00 = quanttbl->quantval[0];
 501.538 +    Q01 = quanttbl->quantval[Q01_POS];
 501.539 +    Q10 = quanttbl->quantval[Q10_POS];
 501.540 +    Q20 = quanttbl->quantval[Q20_POS];
 501.541 +    Q11 = quanttbl->quantval[Q11_POS];
 501.542 +    Q02 = quanttbl->quantval[Q02_POS];
 501.543 +    inverse_DCT = cinfo->idct->inverse_DCT[ci];
 501.544 +    output_ptr = output_buf[ci];
 501.545 +    /* Loop over all DCT blocks to be processed. */
 501.546 +    for (block_row = 0; block_row < block_rows; block_row++) {
 501.547 +      buffer_ptr = buffer[block_row];
 501.548 +      if (first_row && block_row == 0)
 501.549 +	prev_block_row = buffer_ptr;
 501.550 +      else
 501.551 +	prev_block_row = buffer[block_row-1];
 501.552 +      if (last_row && block_row == block_rows-1)
 501.553 +	next_block_row = buffer_ptr;
 501.554 +      else
 501.555 +	next_block_row = buffer[block_row+1];
 501.556 +      /* We fetch the surrounding DC values using a sliding-register approach.
 501.557 +       * Initialize all nine here so as to do the right thing on narrow pics.
 501.558 +       */
 501.559 +      DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
 501.560 +      DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
 501.561 +      DC7 = DC8 = DC9 = (int) next_block_row[0][0];
 501.562 +      output_col = 0;
 501.563 +      last_block_column = compptr->width_in_blocks - 1;
 501.564 +      for (block_num = 0; block_num <= last_block_column; block_num++) {
 501.565 +	/* Fetch current DCT block into workspace so we can modify it. */
 501.566 +	jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
 501.567 +	/* Update DC values */
 501.568 +	if (block_num < last_block_column) {
 501.569 +	  DC3 = (int) prev_block_row[1][0];
 501.570 +	  DC6 = (int) buffer_ptr[1][0];
 501.571 +	  DC9 = (int) next_block_row[1][0];
 501.572 +	}
 501.573 +	/* Compute coefficient estimates per K.8.
 501.574 +	 * An estimate is applied only if coefficient is still zero,
 501.575 +	 * and is not known to be fully accurate.
 501.576 +	 */
 501.577 +	/* AC01 */
 501.578 +	if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) {
 501.579 +	  num = 36 * Q00 * (DC4 - DC6);
 501.580 +	  if (num >= 0) {
 501.581 +	    pred = (int) (((Q01<<7) + num) / (Q01<<8));
 501.582 +	    if (Al > 0 && pred >= (1<<Al))
 501.583 +	      pred = (1<<Al)-1;
 501.584 +	  } else {
 501.585 +	    pred = (int) (((Q01<<7) - num) / (Q01<<8));
 501.586 +	    if (Al > 0 && pred >= (1<<Al))
 501.587 +	      pred = (1<<Al)-1;
 501.588 +	    pred = -pred;
 501.589 +	  }
 501.590 +	  workspace[1] = (JCOEF) pred;
 501.591 +	}
 501.592 +	/* AC10 */
 501.593 +	if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) {
 501.594 +	  num = 36 * Q00 * (DC2 - DC8);
 501.595 +	  if (num >= 0) {
 501.596 +	    pred = (int) (((Q10<<7) + num) / (Q10<<8));
 501.597 +	    if (Al > 0 && pred >= (1<<Al))
 501.598 +	      pred = (1<<Al)-1;
 501.599 +	  } else {
 501.600 +	    pred = (int) (((Q10<<7) - num) / (Q10<<8));
 501.601 +	    if (Al > 0 && pred >= (1<<Al))
 501.602 +	      pred = (1<<Al)-1;
 501.603 +	    pred = -pred;
 501.604 +	  }
 501.605 +	  workspace[8] = (JCOEF) pred;
 501.606 +	}
 501.607 +	/* AC20 */
 501.608 +	if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) {
 501.609 +	  num = 9 * Q00 * (DC2 + DC8 - 2*DC5);
 501.610 +	  if (num >= 0) {
 501.611 +	    pred = (int) (((Q20<<7) + num) / (Q20<<8));
 501.612 +	    if (Al > 0 && pred >= (1<<Al))
 501.613 +	      pred = (1<<Al)-1;
 501.614 +	  } else {
 501.615 +	    pred = (int) (((Q20<<7) - num) / (Q20<<8));
 501.616 +	    if (Al > 0 && pred >= (1<<Al))
 501.617 +	      pred = (1<<Al)-1;
 501.618 +	    pred = -pred;
 501.619 +	  }
 501.620 +	  workspace[16] = (JCOEF) pred;
 501.621 +	}
 501.622 +	/* AC11 */
 501.623 +	if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) {
 501.624 +	  num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
 501.625 +	  if (num >= 0) {
 501.626 +	    pred = (int) (((Q11<<7) + num) / (Q11<<8));
 501.627 +	    if (Al > 0 && pred >= (1<<Al))
 501.628 +	      pred = (1<<Al)-1;
 501.629 +	  } else {
 501.630 +	    pred = (int) (((Q11<<7) - num) / (Q11<<8));
 501.631 +	    if (Al > 0 && pred >= (1<<Al))
 501.632 +	      pred = (1<<Al)-1;
 501.633 +	    pred = -pred;
 501.634 +	  }
 501.635 +	  workspace[9] = (JCOEF) pred;
 501.636 +	}
 501.637 +	/* AC02 */
 501.638 +	if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) {
 501.639 +	  num = 9 * Q00 * (DC4 + DC6 - 2*DC5);
 501.640 +	  if (num >= 0) {
 501.641 +	    pred = (int) (((Q02<<7) + num) / (Q02<<8));
 501.642 +	    if (Al > 0 && pred >= (1<<Al))
 501.643 +	      pred = (1<<Al)-1;
 501.644 +	  } else {
 501.645 +	    pred = (int) (((Q02<<7) - num) / (Q02<<8));
 501.646 +	    if (Al > 0 && pred >= (1<<Al))
 501.647 +	      pred = (1<<Al)-1;
 501.648 +	    pred = -pred;
 501.649 +	  }
 501.650 +	  workspace[2] = (JCOEF) pred;
 501.651 +	}
 501.652 +	/* OK, do the IDCT */
 501.653 +	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace,
 501.654 +			output_ptr, output_col);
 501.655 +	/* Advance for next column */
 501.656 +	DC1 = DC2; DC2 = DC3;
 501.657 +	DC4 = DC5; DC5 = DC6;
 501.658 +	DC7 = DC8; DC8 = DC9;
 501.659 +	buffer_ptr++, prev_block_row++, next_block_row++;
 501.660 +	output_col += compptr->DCT_scaled_size;
 501.661 +      }
 501.662 +      output_ptr += compptr->DCT_scaled_size;
 501.663 +    }
 501.664 +  }
 501.665 +
 501.666 +  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
 501.667 +    return JPEG_ROW_COMPLETED;
 501.668 +  return JPEG_SCAN_COMPLETED;
 501.669 +}
 501.670 +
 501.671 +#endif /* BLOCK_SMOOTHING_SUPPORTED */
 501.672 +
 501.673 +
 501.674 +/*
 501.675 + * Initialize coefficient buffer controller.
 501.676 + */
 501.677 +
 501.678 +GLOBAL(void)
 501.679 +jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
 501.680 +{
 501.681 +  my_coef_ptr coef;
 501.682 +
 501.683 +  coef = (my_coef_ptr)
 501.684 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 501.685 +				SIZEOF(my_coef_controller));
 501.686 +  cinfo->coef = (struct jpeg_d_coef_controller *) coef;
 501.687 +  coef->pub.start_input_pass = start_input_pass;
 501.688 +  coef->pub.start_output_pass = start_output_pass;
 501.689 +#ifdef BLOCK_SMOOTHING_SUPPORTED
 501.690 +  coef->coef_bits_latch = NULL;
 501.691 +#endif
 501.692 +
 501.693 +  /* Create the coefficient buffer. */
 501.694 +  if (need_full_buffer) {
 501.695 +#ifdef D_MULTISCAN_FILES_SUPPORTED
 501.696 +    /* Allocate a full-image virtual array for each component, */
 501.697 +    /* padded to a multiple of samp_factor DCT blocks in each direction. */
 501.698 +    /* Note we ask for a pre-zeroed array. */
 501.699 +    int ci, access_rows;
 501.700 +    jpeg_component_info *compptr;
 501.701 +
 501.702 +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 501.703 +	 ci++, compptr++) {
 501.704 +      access_rows = compptr->v_samp_factor;
 501.705 +#ifdef BLOCK_SMOOTHING_SUPPORTED
 501.706 +      /* If block smoothing could be used, need a bigger window */
 501.707 +      if (cinfo->progressive_mode)
 501.708 +	access_rows *= 3;
 501.709 +#endif
 501.710 +      coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
 501.711 +	((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
 501.712 +	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
 501.713 +				(long) compptr->h_samp_factor),
 501.714 +	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
 501.715 +				(long) compptr->v_samp_factor),
 501.716 +	 (JDIMENSION) access_rows);
 501.717 +    }
 501.718 +    coef->pub.consume_data = consume_data;
 501.719 +    coef->pub.decompress_data = decompress_data;
 501.720 +    coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
 501.721 +#else
 501.722 +    ERREXIT(cinfo, JERR_NOT_COMPILED);
 501.723 +#endif
 501.724 +  } else {
 501.725 +    /* We only need a single-MCU buffer. */
 501.726 +    JBLOCKROW buffer;
 501.727 +    int i;
 501.728 +
 501.729 +    buffer = (JBLOCKROW)
 501.730 +      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 501.731 +				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
 501.732 +    for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
 501.733 +      coef->MCU_buffer[i] = buffer + i;
 501.734 +    }
 501.735 +    coef->pub.consume_data = dummy_consume_data;
 501.736 +    coef->pub.decompress_data = decompress_onepass;
 501.737 +    coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
 501.738 +  }
 501.739 +}
   502.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   502.2 +++ b/libs/libjpeg/jdcolor.c	Sat Feb 01 19:58:19 2014 +0200
   502.3 @@ -0,0 +1,396 @@
   502.4 +/*
   502.5 + * jdcolor.c
   502.6 + *
   502.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   502.8 + * This file is part of the Independent JPEG Group's software.
   502.9 + * For conditions of distribution and use, see the accompanying README file.
  502.10 + *
  502.11 + * This file contains output colorspace conversion routines.
  502.12 + */
  502.13 +
  502.14 +#define JPEG_INTERNALS
  502.15 +#include "jinclude.h"
  502.16 +#include "jpeglib.h"
  502.17 +
  502.18 +
  502.19 +/* Private subobject */
  502.20 +
  502.21 +typedef struct {
  502.22 +  struct jpeg_color_deconverter pub; /* public fields */
  502.23 +
  502.24 +  /* Private state for YCC->RGB conversion */
  502.25 +  int * Cr_r_tab;		/* => table for Cr to R conversion */
  502.26 +  int * Cb_b_tab;		/* => table for Cb to B conversion */
  502.27 +  INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
  502.28 +  INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
  502.29 +} my_color_deconverter;
  502.30 +
  502.31 +typedef my_color_deconverter * my_cconvert_ptr;
  502.32 +
  502.33 +
  502.34 +/**************** YCbCr -> RGB conversion: most common case **************/
  502.35 +
  502.36 +/*
  502.37 + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
  502.38 + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
  502.39 + * The conversion equations to be implemented are therefore
  502.40 + *	R = Y                + 1.40200 * Cr
  502.41 + *	G = Y - 0.34414 * Cb - 0.71414 * Cr
  502.42 + *	B = Y + 1.77200 * Cb
  502.43 + * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
  502.44 + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
  502.45 + *
  502.46 + * To avoid floating-point arithmetic, we represent the fractional constants
  502.47 + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
  502.48 + * the products by 2^16, with appropriate rounding, to get the correct answer.
  502.49 + * Notice that Y, being an integral input, does not contribute any fraction
  502.50 + * so it need not participate in the rounding.
  502.51 + *
  502.52 + * For even more speed, we avoid doing any multiplications in the inner loop
  502.53 + * by precalculating the constants times Cb and Cr for all possible values.
  502.54 + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
  502.55 + * for 12-bit samples it is still acceptable.  It's not very reasonable for
  502.56 + * 16-bit samples, but if you want lossless storage you shouldn't be changing
  502.57 + * colorspace anyway.
  502.58 + * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
  502.59 + * values for the G calculation are left scaled up, since we must add them
  502.60 + * together before rounding.
  502.61 + */
  502.62 +
  502.63 +#define SCALEBITS	16	/* speediest right-shift on some machines */
  502.64 +#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
  502.65 +#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  502.66 +
  502.67 +
  502.68 +/*
  502.69 + * Initialize tables for YCC->RGB colorspace conversion.
  502.70 + */
  502.71 +
  502.72 +LOCAL(void)
  502.73 +build_ycc_rgb_table (j_decompress_ptr cinfo)
  502.74 +{
  502.75 +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
  502.76 +  int i;
  502.77 +  INT32 x;
  502.78 +  SHIFT_TEMPS
  502.79 +
  502.80 +  cconvert->Cr_r_tab = (int *)
  502.81 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  502.82 +				(MAXJSAMPLE+1) * SIZEOF(int));
  502.83 +  cconvert->Cb_b_tab = (int *)
  502.84 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  502.85 +				(MAXJSAMPLE+1) * SIZEOF(int));
  502.86 +  cconvert->Cr_g_tab = (INT32 *)
  502.87 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  502.88 +				(MAXJSAMPLE+1) * SIZEOF(INT32));
  502.89 +  cconvert->Cb_g_tab = (INT32 *)
  502.90 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  502.91 +				(MAXJSAMPLE+1) * SIZEOF(INT32));
  502.92 +
  502.93 +  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
  502.94 +    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
  502.95 +    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
  502.96 +    /* Cr=>R value is nearest int to 1.40200 * x */
  502.97 +    cconvert->Cr_r_tab[i] = (int)
  502.98 +		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
  502.99 +    /* Cb=>B value is nearest int to 1.77200 * x */
 502.100 +    cconvert->Cb_b_tab[i] = (int)
 502.101 +		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
 502.102 +    /* Cr=>G value is scaled-up -0.71414 * x */
 502.103 +    cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
 502.104 +    /* Cb=>G value is scaled-up -0.34414 * x */
 502.105 +    /* We also add in ONE_HALF so that need not do it in inner loop */
 502.106 +    cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
 502.107 +  }
 502.108 +}
 502.109 +
 502.110 +
 502.111 +/*
 502.112 + * Convert some rows of samples to the output colorspace.
 502.113 + *
 502.114 + * Note that we change from noninterleaved, one-plane-per-component format
 502.115 + * to interleaved-pixel format.  The output buffer is therefore three times
 502.116 + * as wide as the input buffer.
 502.117 + * A starting row offset is provided only for the input buffer.  The caller
 502.118 + * can easily adjust the passed output_buf value to accommodate any row
 502.119 + * offset required on that side.
 502.120 + */
 502.121 +
 502.122 +METHODDEF(void)
 502.123 +ycc_rgb_convert (j_decompress_ptr cinfo,
 502.124 +		 JSAMPIMAGE input_buf, JDIMENSION input_row,
 502.125 +		 JSAMPARRAY output_buf, int num_rows)
 502.126 +{
 502.127 +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 502.128 +  register int y, cb, cr;
 502.129 +  register JSAMPROW outptr;
 502.130 +  register JSAMPROW inptr0, inptr1, inptr2;
 502.131 +  register JDIMENSION col;
 502.132 +  JDIMENSION num_cols = cinfo->output_width;
 502.133 +  /* copy these pointers into registers if possible */
 502.134 +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
 502.135 +  register int * Crrtab = cconvert->Cr_r_tab;
 502.136 +  register int * Cbbtab = cconvert->Cb_b_tab;
 502.137 +  register INT32 * Crgtab = cconvert->Cr_g_tab;
 502.138 +  register INT32 * Cbgtab = cconvert->Cb_g_tab;
 502.139 +  SHIFT_TEMPS
 502.140 +
 502.141 +  while (--num_rows >= 0) {
 502.142 +    inptr0 = input_buf[0][input_row];
 502.143 +    inptr1 = input_buf[1][input_row];
 502.144 +    inptr2 = input_buf[2][input_row];
 502.145 +    input_row++;
 502.146 +    outptr = *output_buf++;
 502.147 +    for (col = 0; col < num_cols; col++) {
 502.148 +      y  = GETJSAMPLE(inptr0[col]);
 502.149 +      cb = GETJSAMPLE(inptr1[col]);
 502.150 +      cr = GETJSAMPLE(inptr2[col]);
 502.151 +      /* Range-limiting is essential due to noise introduced by DCT losses. */
 502.152 +      outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
 502.153 +      outptr[RGB_GREEN] = range_limit[y +
 502.154 +			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
 502.155 +						 SCALEBITS))];
 502.156 +      outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
 502.157 +      outptr += RGB_PIXELSIZE;
 502.158 +    }
 502.159 +  }
 502.160 +}
 502.161 +
 502.162 +
 502.163 +/**************** Cases other than YCbCr -> RGB **************/
 502.164 +
 502.165 +
 502.166 +/*
 502.167 + * Color conversion for no colorspace change: just copy the data,
 502.168 + * converting from separate-planes to interleaved representation.
 502.169 + */
 502.170 +
 502.171 +METHODDEF(void)
 502.172 +null_convert (j_decompress_ptr cinfo,
 502.173 +	      JSAMPIMAGE input_buf, JDIMENSION input_row,
 502.174 +	      JSAMPARRAY output_buf, int num_rows)
 502.175 +{
 502.176 +  register JSAMPROW inptr, outptr;
 502.177 +  register JDIMENSION count;
 502.178 +  register int num_components = cinfo->num_components;
 502.179 +  JDIMENSION num_cols = cinfo->output_width;
 502.180 +  int ci;
 502.181 +
 502.182 +  while (--num_rows >= 0) {
 502.183 +    for (ci = 0; ci < num_components; ci++) {
 502.184 +      inptr = input_buf[ci][input_row];
 502.185 +      outptr = output_buf[0] + ci;
 502.186 +      for (count = num_cols; count > 0; count--) {
 502.187 +	*outptr = *inptr++;	/* needn't bother with GETJSAMPLE() here */
 502.188 +	outptr += num_components;
 502.189 +      }
 502.190 +    }
 502.191 +    input_row++;
 502.192 +    output_buf++;
 502.193 +  }
 502.194 +}
 502.195 +
 502.196 +
 502.197 +/*
 502.198 + * Color conversion for grayscale: just copy the data.
 502.199 + * This also works for YCbCr -> grayscale conversion, in which
 502.200 + * we just copy the Y (luminance) component and ignore chrominance.
 502.201 + */
 502.202 +
 502.203 +METHODDEF(void)
 502.204 +grayscale_convert (j_decompress_ptr cinfo,
 502.205 +		   JSAMPIMAGE input_buf, JDIMENSION input_row,
 502.206 +		   JSAMPARRAY output_buf, int num_rows)
 502.207 +{
 502.208 +  jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
 502.209 +		    num_rows, cinfo->output_width);
 502.210 +}
 502.211 +
 502.212 +
 502.213 +/*
 502.214 + * Convert grayscale to RGB: just duplicate the graylevel three times.
 502.215 + * This is provided to support applications that don't want to cope
 502.216 + * with grayscale as a separate case.
 502.217 + */
 502.218 +
 502.219 +METHODDEF(void)
 502.220 +gray_rgb_convert (j_decompress_ptr cinfo,
 502.221 +		  JSAMPIMAGE input_buf, JDIMENSION input_row,
 502.222 +		  JSAMPARRAY output_buf, int num_rows)
 502.223 +{
 502.224 +  register JSAMPROW inptr, outptr;
 502.225 +  register JDIMENSION col;
 502.226 +  JDIMENSION num_cols = cinfo->output_width;
 502.227 +
 502.228 +  while (--num_rows >= 0) {
 502.229 +    inptr = input_buf[0][input_row++];
 502.230 +    outptr = *output_buf++;
 502.231 +    for (col = 0; col < num_cols; col++) {
 502.232 +      /* We can dispense with GETJSAMPLE() here */
 502.233 +      outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
 502.234 +      outptr += RGB_PIXELSIZE;
 502.235 +    }
 502.236 +  }
 502.237 +}
 502.238 +
 502.239 +
 502.240 +/*
 502.241 + * Adobe-style YCCK->CMYK conversion.
 502.242 + * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
 502.243 + * conversion as above, while passing K (black) unchanged.
 502.244 + * We assume build_ycc_rgb_table has been called.
 502.245 + */
 502.246 +
 502.247 +METHODDEF(void)
 502.248 +ycck_cmyk_convert (j_decompress_ptr cinfo,
 502.249 +		   JSAMPIMAGE input_buf, JDIMENSION input_row,
 502.250 +		   JSAMPARRAY output_buf, int num_rows)
 502.251 +{
 502.252 +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 502.253 +  register int y, cb, cr;
 502.254 +  register JSAMPROW outptr;
 502.255 +  register JSAMPROW inptr0, inptr1, inptr2, inptr3;
 502.256 +  register JDIMENSION col;
 502.257 +  JDIMENSION num_cols = cinfo->output_width;
 502.258 +  /* copy these pointers into registers if possible */
 502.259 +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
 502.260 +  register int * Crrtab = cconvert->Cr_r_tab;
 502.261 +  register int * Cbbtab = cconvert->Cb_b_tab;
 502.262 +  register INT32 * Crgtab = cconvert->Cr_g_tab;
 502.263 +  register INT32 * Cbgtab = cconvert->Cb_g_tab;
 502.264 +  SHIFT_TEMPS
 502.265 +
 502.266 +  while (--num_rows >= 0) {
 502.267 +    inptr0 = input_buf[0][input_row];
 502.268 +    inptr1 = input_buf[1][input_row];
 502.269 +    inptr2 = input_buf[2][input_row];
 502.270 +    inptr3 = input_buf[3][input_row];
 502.271 +    input_row++;
 502.272 +    outptr = *output_buf++;
 502.273 +    for (col = 0; col < num_cols; col++) {
 502.274 +      y  = GETJSAMPLE(inptr0[col]);
 502.275 +      cb = GETJSAMPLE(inptr1[col]);
 502.276 +      cr = GETJSAMPLE(inptr2[col]);
 502.277 +      /* Range-limiting is essential due to noise introduced by DCT losses. */
 502.278 +      outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];	/* red */
 502.279 +      outptr[1] = range_limit[MAXJSAMPLE - (y +			/* green */
 502.280 +			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
 502.281 +						 SCALEBITS)))];
 502.282 +      outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];	/* blue */
 502.283 +      /* K passes through unchanged */
 502.284 +      outptr[3] = inptr3[col];	/* don't need GETJSAMPLE here */
 502.285 +      outptr += 4;
 502.286 +    }
 502.287 +  }
 502.288 +}
 502.289 +
 502.290 +
 502.291 +/*
 502.292 + * Empty method for start_pass.
 502.293 + */
 502.294 +
 502.295 +METHODDEF(void)
 502.296 +start_pass_dcolor (j_decompress_ptr cinfo)
 502.297 +{
 502.298 +  /* no work needed */
 502.299 +}
 502.300 +
 502.301 +
 502.302 +/*
 502.303 + * Module initialization routine for output colorspace conversion.
 502.304 + */
 502.305 +
 502.306 +GLOBAL(void)
 502.307 +jinit_color_deconverter (j_decompress_ptr cinfo)
 502.308 +{
 502.309 +  my_cconvert_ptr cconvert;
 502.310 +  int ci;
 502.311 +
 502.312 +  cconvert = (my_cconvert_ptr)
 502.313 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 502.314 +				SIZEOF(my_color_deconverter));
 502.315 +  cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
 502.316 +  cconvert->pub.start_pass = start_pass_dcolor;
 502.317 +
 502.318 +  /* Make sure num_components agrees with jpeg_color_space */
 502.319 +  switch (cinfo->jpeg_color_space) {
 502.320 +  case JCS_GRAYSCALE:
 502.321 +    if (cinfo->num_components != 1)
 502.322 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 502.323 +    break;
 502.324 +
 502.325 +  case JCS_RGB:
 502.326 +  case JCS_YCbCr:
 502.327 +    if (cinfo->num_components != 3)
 502.328 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 502.329 +    break;
 502.330 +
 502.331 +  case JCS_CMYK:
 502.332 +  case JCS_YCCK:
 502.333 +    if (cinfo->num_components != 4)
 502.334 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 502.335 +    break;
 502.336 +
 502.337 +  default:			/* JCS_UNKNOWN can be anything */
 502.338 +    if (cinfo->num_components < 1)
 502.339 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 502.340 +    break;
 502.341 +  }
 502.342 +
 502.343 +  /* Set out_color_components and conversion method based on requested space.
 502.344 +   * Also clear the component_needed flags for any unused components,
 502.345 +   * so that earlier pipeline stages can avoid useless computation.
 502.346 +   */
 502.347 +
 502.348 +  switch (cinfo->out_color_space) {
 502.349 +  case JCS_GRAYSCALE:
 502.350 +    cinfo->out_color_components = 1;
 502.351 +    if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
 502.352 +	cinfo->jpeg_color_space == JCS_YCbCr) {
 502.353 +      cconvert->pub.color_convert = grayscale_convert;
 502.354 +      /* For color->grayscale conversion, only the Y (0) component is needed */
 502.355 +      for (ci = 1; ci < cinfo->num_components; ci++)
 502.356 +	cinfo->comp_info[ci].component_needed = FALSE;
 502.357 +    } else
 502.358 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 502.359 +    break;
 502.360 +
 502.361 +  case JCS_RGB:
 502.362 +    cinfo->out_color_components = RGB_PIXELSIZE;
 502.363 +    if (cinfo->jpeg_color_space == JCS_YCbCr) {
 502.364 +      cconvert->pub.color_convert = ycc_rgb_convert;
 502.365 +      build_ycc_rgb_table(cinfo);
 502.366 +    } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
 502.367 +      cconvert->pub.color_convert = gray_rgb_convert;
 502.368 +    } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
 502.369 +      cconvert->pub.color_convert = null_convert;
 502.370 +    } else
 502.371 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 502.372 +    break;
 502.373 +
 502.374 +  case JCS_CMYK:
 502.375 +    cinfo->out_color_components = 4;
 502.376 +    if (cinfo->jpeg_color_space == JCS_YCCK) {
 502.377 +      cconvert->pub.color_convert = ycck_cmyk_convert;
 502.378 +      build_ycc_rgb_table(cinfo);
 502.379 +    } else if (cinfo->jpeg_color_space == JCS_CMYK) {
 502.380 +      cconvert->pub.color_convert = null_convert;
 502.381 +    } else
 502.382 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 502.383 +    break;
 502.384 +
 502.385 +  default:
 502.386 +    /* Permit null conversion to same output space */
 502.387 +    if (cinfo->out_color_space == cinfo->jpeg_color_space) {
 502.388 +      cinfo->out_color_components = cinfo->num_components;
 502.389 +      cconvert->pub.color_convert = null_convert;
 502.390 +    } else			/* unsupported non-null conversion */
 502.391 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 502.392 +    break;
 502.393 +  }
 502.394 +
 502.395 +  if (cinfo->quantize_colors)
 502.396 +    cinfo->output_components = 1; /* single colormapped output component */
 502.397 +  else
 502.398 +    cinfo->output_components = cinfo->out_color_components;
 502.399 +}
   503.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   503.2 +++ b/libs/libjpeg/jdct.h	Sat Feb 01 19:58:19 2014 +0200
   503.3 @@ -0,0 +1,176 @@
   503.4 +/*
   503.5 + * jdct.h
   503.6 + *
   503.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   503.8 + * This file is part of the Independent JPEG Group's software.
   503.9 + * For conditions of distribution and use, see the accompanying README file.
  503.10 + *
  503.11 + * This include file contains common declarations for the forward and
  503.12 + * inverse DCT modules.  These declarations are private to the DCT managers
  503.13 + * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms.
  503.14 + * The individual DCT algorithms are kept in separate files to ease 
  503.15 + * machine-dependent tuning (e.g., assembly coding).
  503.16 + */
  503.17 +
  503.18 +
  503.19 +/*
  503.20 + * A forward DCT routine is given a pointer to a work area of type DCTELEM[];
  503.21 + * the DCT is to be performed in-place in that buffer.  Type DCTELEM is int
  503.22 + * for 8-bit samples, INT32 for 12-bit samples.  (NOTE: Floating-point DCT
  503.23 + * implementations use an array of type FAST_FLOAT, instead.)
  503.24 + * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
  503.25 + * The DCT outputs are returned scaled up by a factor of 8; they therefore
  503.26 + * have a range of +-8K for 8-bit data, +-128K for 12-bit data.  This
  503.27 + * convention improves accuracy in integer implementations and saves some
  503.28 + * work in floating-point ones.
  503.29 + * Quantization of the output coefficients is done by jcdctmgr.c.
  503.30 + */
  503.31 +
  503.32 +#if BITS_IN_JSAMPLE == 8
  503.33 +typedef int DCTELEM;		/* 16 or 32 bits is fine */
  503.34 +#else
  503.35 +typedef INT32 DCTELEM;		/* must have 32 bits */
  503.36 +#endif
  503.37 +
  503.38 +typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
  503.39 +typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
  503.40 +
  503.41 +
  503.42 +/*
  503.43 + * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
  503.44 + * to an output sample array.  The routine must dequantize the input data as
  503.45 + * well as perform the IDCT; for dequantization, it uses the multiplier table
  503.46 + * pointed to by compptr->dct_table.  The output data is to be placed into the
  503.47 + * sample array starting at a specified column.  (Any row offset needed will
  503.48 + * be applied to the array pointer before it is passed to the IDCT code.)
  503.49 + * Note that the number of samples emitted by the IDCT routine is
  503.50 + * DCT_scaled_size * DCT_scaled_size.
  503.51 + */
  503.52 +
  503.53 +/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
  503.54 +
  503.55 +/*
  503.56 + * Each IDCT routine has its own ideas about the best dct_table element type.
  503.57 + */
  503.58 +
  503.59 +typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
  503.60 +#if BITS_IN_JSAMPLE == 8
  503.61 +typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
  503.62 +#define IFAST_SCALE_BITS  2	/* fractional bits in scale factors */
  503.63 +#else
  503.64 +typedef INT32 IFAST_MULT_TYPE;	/* need 32 bits for scaled quantizers */
  503.65 +#define IFAST_SCALE_BITS  13	/* fractional bits in scale factors */
  503.66 +#endif
  503.67 +typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
  503.68 +
  503.69 +
  503.70 +/*
  503.71 + * Each IDCT routine is responsible for range-limiting its results and
  503.72 + * converting them to unsigned form (0..MAXJSAMPLE).  The raw outputs could
  503.73 + * be quite far out of range if the input data is corrupt, so a bulletproof
  503.74 + * range-limiting step is required.  We use a mask-and-table-lookup method
  503.75 + * to do the combined operations quickly.  See the comments with
  503.76 + * prepare_range_limit_table (in jdmaster.c) for more info.
  503.77 + */
  503.78 +
  503.79 +#define IDCT_range_limit(cinfo)  ((cinfo)->sample_range_limit + CENTERJSAMPLE)
  503.80 +
  503.81 +#define RANGE_MASK  (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
  503.82 +
  503.83 +
  503.84 +/* Short forms of external names for systems with brain-damaged linkers. */
  503.85 +
  503.86 +#ifdef NEED_SHORT_EXTERNAL_NAMES
  503.87 +#define jpeg_fdct_islow		jFDislow
  503.88 +#define jpeg_fdct_ifast		jFDifast
  503.89 +#define jpeg_fdct_float		jFDfloat
  503.90 +#define jpeg_idct_islow		jRDislow
  503.91 +#define jpeg_idct_ifast		jRDifast
  503.92 +#define jpeg_idct_float		jRDfloat
  503.93 +#define jpeg_idct_4x4		jRD4x4
  503.94 +#define jpeg_idct_2x2		jRD2x2
  503.95 +#define jpeg_idct_1x1		jRD1x1
  503.96 +#endif /* NEED_SHORT_EXTERNAL_NAMES */
  503.97 +
  503.98 +/* Extern declarations for the forward and inverse DCT routines. */
  503.99 +
 503.100 +EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data));
 503.101 +EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data));
 503.102 +EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data));
 503.103 +
 503.104 +EXTERN(void) jpeg_idct_islow
 503.105 +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
 503.106 +	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
 503.107 +EXTERN(void) jpeg_idct_ifast
 503.108 +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
 503.109 +	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
 503.110 +EXTERN(void) jpeg_idct_float
 503.111 +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
 503.112 +	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
 503.113 +EXTERN(void) jpeg_idct_4x4
 503.114 +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
 503.115 +	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
 503.116 +EXTERN(void) jpeg_idct_2x2
 503.117 +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
 503.118 +	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
 503.119 +EXTERN(void) jpeg_idct_1x1
 503.120 +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
 503.121 +	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
 503.122 +
 503.123 +
 503.124 +/*
 503.125 + * Macros for handling fixed-point arithmetic; these are used by many
 503.126 + * but not all of the DCT/IDCT modules.
 503.127 + *
 503.128 + * All values are expected to be of type INT32.
 503.129 + * Fractional constants are scaled left by CONST_BITS bits.
 503.130 + * CONST_BITS is defined within each module using these macros,
 503.131 + * and may differ from one module to the next.
 503.132 + */
 503.133 +
 503.134 +#define ONE	((INT32) 1)
 503.135 +#define CONST_SCALE (ONE << CONST_BITS)
 503.136 +
 503.137 +/* Convert a positive real constant to an integer scaled by CONST_SCALE.
 503.138 + * Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
 503.139 + * thus causing a lot of useless floating-point operations at run time.
 503.140 + */
 503.141 +
 503.142 +#define FIX(x)	((INT32) ((x) * CONST_SCALE + 0.5))
 503.143 +
 503.144 +/* Descale and correctly round an INT32 value that's scaled by N bits.
 503.145 + * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
 503.146 + * the fudge factor is correct for either sign of X.
 503.147 + */
 503.148 +
 503.149 +#define DESCALE(x,n)  RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
 503.150 +
 503.151 +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
 503.152 + * This macro is used only when the two inputs will actually be no more than
 503.153 + * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
 503.154 + * full 32x32 multiply.  This provides a useful speedup on many machines.
 503.155 + * Unfortunately there is no way to specify a 16x16->32 multiply portably
 503.156 + * in C, but some C compilers will do the right thing if you provide the
 503.157 + * correct combination of casts.
 503.158 + */
 503.159 +
 503.160 +#ifdef SHORTxSHORT_32		/* may work if 'int' is 32 bits */
 503.161 +#define MULTIPLY16C16(var,const)  (((INT16) (var)) * ((INT16) (const)))
 503.162 +#endif
 503.163 +#ifdef SHORTxLCONST_32		/* known to work with Microsoft C 6.0 */
 503.164 +#define MULTIPLY16C16(var,const)  (((INT16) (var)) * ((INT32) (const)))
 503.165 +#endif
 503.166 +
 503.167 +#ifndef MULTIPLY16C16		/* default definition */
 503.168 +#define MULTIPLY16C16(var,const)  ((var) * (const))
 503.169 +#endif
 503.170 +
 503.171 +/* Same except both inputs are variables. */
 503.172 +
 503.173 +#ifdef SHORTxSHORT_32		/* may work if 'int' is 32 bits */
 503.174 +#define MULTIPLY16V16(var1,var2)  (((INT16) (var1)) * ((INT16) (var2)))
 503.175 +#endif
 503.176 +
 503.177 +#ifndef MULTIPLY16V16		/* default definition */
 503.178 +#define MULTIPLY16V16(var1,var2)  ((var1) * (var2))
 503.179 +#endif
   504.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   504.2 +++ b/libs/libjpeg/jddctmgr.c	Sat Feb 01 19:58:19 2014 +0200
   504.3 @@ -0,0 +1,269 @@
   504.4 +/*
   504.5 + * jddctmgr.c
   504.6 + *
   504.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   504.8 + * This file is part of the Independent JPEG Group's software.
   504.9 + * For conditions of distribution and use, see the accompanying README file.
  504.10 + *
  504.11 + * This file contains the inverse-DCT management logic.
  504.12 + * This code selects a particular IDCT implementation to be used,
  504.13 + * and it performs related housekeeping chores.  No code in this file
  504.14 + * is executed per IDCT step, only during output pass setup.
  504.15 + *
  504.16 + * Note that the IDCT routines are responsible for performing coefficient
  504.17 + * dequantization as well as the IDCT proper.  This module sets up the
  504.18 + * dequantization multiplier table needed by the IDCT routine.
  504.19 + */
  504.20 +
  504.21 +#define JPEG_INTERNALS
  504.22 +#include "jinclude.h"
  504.23 +#include "jpeglib.h"
  504.24 +#include "jdct.h"		/* Private declarations for DCT subsystem */
  504.25 +
  504.26 +
  504.27 +/*
  504.28 + * The decompressor input side (jdinput.c) saves away the appropriate
  504.29 + * quantization table for each component at the start of the first scan
  504.30 + * involving that component.  (This is necessary in order to correctly
  504.31 + * decode files that reuse Q-table slots.)
  504.32 + * When we are ready to make an output pass, the saved Q-table is converted
  504.33 + * to a multiplier table that will actually be used by the IDCT routine.
  504.34 + * The multiplier table contents are IDCT-method-dependent.  To support
  504.35 + * application changes in IDCT method between scans, we can remake the
  504.36 + * multiplier tables if necessary.
  504.37 + * In buffered-image mode, the first output pass may occur before any data
  504.38 + * has been seen for some components, and thus before their Q-tables have
  504.39 + * been saved away.  To handle this case, multiplier tables are preset
  504.40 + * to zeroes; the result of the IDCT will be a neutral gray level.
  504.41 + */
  504.42 +
  504.43 +
  504.44 +/* Private subobject for this module */
  504.45 +
  504.46 +typedef struct {
  504.47 +  struct jpeg_inverse_dct pub;	/* public fields */
  504.48 +
  504.49 +  /* This array contains the IDCT method code that each multiplier table
  504.50 +   * is currently set up for, or -1 if it's not yet set up.
  504.51 +   * The actual multiplier tables are pointed to by dct_table in the
  504.52 +   * per-component comp_info structures.
  504.53 +   */
  504.54 +  int cur_method[MAX_COMPONENTS];
  504.55 +} my_idct_controller;
  504.56 +
  504.57 +typedef my_idct_controller * my_idct_ptr;
  504.58 +
  504.59 +
  504.60 +/* Allocated multiplier tables: big enough for any supported variant */
  504.61 +
  504.62 +typedef union {
  504.63 +  ISLOW_MULT_TYPE islow_array[DCTSIZE2];
  504.64 +#ifdef DCT_IFAST_SUPPORTED
  504.65 +  IFAST_MULT_TYPE ifast_array[DCTSIZE2];
  504.66 +#endif
  504.67 +#ifdef DCT_FLOAT_SUPPORTED
  504.68 +  FLOAT_MULT_TYPE float_array[DCTSIZE2];
  504.69 +#endif
  504.70 +} multiplier_table;
  504.71 +
  504.72 +
  504.73 +/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
  504.74 + * so be sure to compile that code if either ISLOW or SCALING is requested.
  504.75 + */
  504.76 +#ifdef DCT_ISLOW_SUPPORTED
  504.77 +#define PROVIDE_ISLOW_TABLES
  504.78 +#else
  504.79 +#ifdef IDCT_SCALING_SUPPORTED
  504.80 +#define PROVIDE_ISLOW_TABLES
  504.81 +#endif
  504.82 +#endif
  504.83 +
  504.84 +
  504.85 +/*
  504.86 + * Prepare for an output pass.
  504.87 + * Here we select the proper IDCT routine for each component and build
  504.88 + * a matching multiplier table.
  504.89 + */
  504.90 +
  504.91 +METHODDEF(void)
  504.92 +start_pass (j_decompress_ptr cinfo)
  504.93 +{
  504.94 +  my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
  504.95 +  int ci, i;
  504.96 +  jpeg_component_info *compptr;
  504.97 +  int method = 0;
  504.98 +  inverse_DCT_method_ptr method_ptr = NULL;
  504.99 +  JQUANT_TBL * qtbl;
 504.100 +
 504.101 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 504.102 +       ci++, compptr++) {
 504.103 +    /* Select the proper IDCT routine for this component's scaling */
 504.104 +    switch (compptr->DCT_scaled_size) {
 504.105 +#ifdef IDCT_SCALING_SUPPORTED
 504.106 +    case 1:
 504.107 +      method_ptr = jpeg_idct_1x1;
 504.108 +      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
 504.109 +      break;
 504.110 +    case 2:
 504.111 +      method_ptr = jpeg_idct_2x2;
 504.112 +      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
 504.113 +      break;
 504.114 +    case 4:
 504.115 +      method_ptr = jpeg_idct_4x4;
 504.116 +      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
 504.117 +      break;
 504.118 +#endif
 504.119 +    case DCTSIZE:
 504.120 +      switch (cinfo->dct_method) {
 504.121 +#ifdef DCT_ISLOW_SUPPORTED
 504.122 +      case JDCT_ISLOW:
 504.123 +	method_ptr = jpeg_idct_islow;
 504.124 +	method = JDCT_ISLOW;
 504.125 +	break;
 504.126 +#endif
 504.127 +#ifdef DCT_IFAST_SUPPORTED
 504.128 +      case JDCT_IFAST:
 504.129 +	method_ptr = jpeg_idct_ifast;
 504.130 +	method = JDCT_IFAST;
 504.131 +	break;
 504.132 +#endif
 504.133 +#ifdef DCT_FLOAT_SUPPORTED
 504.134 +      case JDCT_FLOAT:
 504.135 +	method_ptr = jpeg_idct_float;
 504.136 +	method = JDCT_FLOAT;
 504.137 +	break;
 504.138 +#endif
 504.139 +      default:
 504.140 +	ERREXIT(cinfo, JERR_NOT_COMPILED);
 504.141 +	break;
 504.142 +      }
 504.143 +      break;
 504.144 +    default:
 504.145 +      ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
 504.146 +      break;
 504.147 +    }
 504.148 +    idct->pub.inverse_DCT[ci] = method_ptr;
 504.149 +    /* Create multiplier table from quant table.
 504.150 +     * However, we can skip this if the component is uninteresting
 504.151 +     * or if we already built the table.  Also, if no quant table
 504.152 +     * has yet been saved for the component, we leave the
 504.153 +     * multiplier table all-zero; we'll be reading zeroes from the
 504.154 +     * coefficient controller's buffer anyway.
 504.155 +     */
 504.156 +    if (! compptr->component_needed || idct->cur_method[ci] == method)
 504.157 +      continue;
 504.158 +    qtbl = compptr->quant_table;
 504.159 +    if (qtbl == NULL)		/* happens if no data yet for component */
 504.160 +      continue;
 504.161 +    idct->cur_method[ci] = method;
 504.162 +    switch (method) {
 504.163 +#ifdef PROVIDE_ISLOW_TABLES
 504.164 +    case JDCT_ISLOW:
 504.165 +      {
 504.166 +	/* For LL&M IDCT method, multipliers are equal to raw quantization
 504.167 +	 * coefficients, but are stored as ints to ensure access efficiency.
 504.168 +	 */
 504.169 +	ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
 504.170 +	for (i = 0; i < DCTSIZE2; i++) {
 504.171 +	  ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
 504.172 +	}
 504.173 +      }
 504.174 +      break;
 504.175 +#endif
 504.176 +#ifdef DCT_IFAST_SUPPORTED
 504.177 +    case JDCT_IFAST:
 504.178 +      {
 504.179 +	/* For AA&N IDCT method, multipliers are equal to quantization
 504.180 +	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
 504.181 +	 *   scalefactor[0] = 1
 504.182 +	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
 504.183 +	 * For integer operation, the multiplier table is to be scaled by
 504.184 +	 * IFAST_SCALE_BITS.
 504.185 +	 */
 504.186 +	IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
 504.187 +#define CONST_BITS 14
 504.188 +	static const INT16 aanscales[DCTSIZE2] = {
 504.189 +	  /* precomputed values scaled up by 14 bits */
 504.190 +	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
 504.191 +	  22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
 504.192 +	  21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
 504.193 +	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
 504.194 +	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
 504.195 +	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
 504.196 +	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
 504.197 +	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
 504.198 +	};
 504.199 +	SHIFT_TEMPS
 504.200 +
 504.201 +	for (i = 0; i < DCTSIZE2; i++) {
 504.202 +	  ifmtbl[i] = (IFAST_MULT_TYPE)
 504.203 +	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
 504.204 +				  (INT32) aanscales[i]),
 504.205 +		    CONST_BITS-IFAST_SCALE_BITS);
 504.206 +	}
 504.207 +      }
 504.208 +      break;
 504.209 +#endif
 504.210 +#ifdef DCT_FLOAT_SUPPORTED
 504.211 +    case JDCT_FLOAT:
 504.212 +      {
 504.213 +	/* For float AA&N IDCT method, multipliers are equal to quantization
 504.214 +	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
 504.215 +	 *   scalefactor[0] = 1
 504.216 +	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
 504.217 +	 */
 504.218 +	FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
 504.219 +	int row, col;
 504.220 +	static const double aanscalefactor[DCTSIZE] = {
 504.221 +	  1.0, 1.387039845, 1.306562965, 1.175875602,
 504.222 +	  1.0, 0.785694958, 0.541196100, 0.275899379
 504.223 +	};
 504.224 +
 504.225 +	i = 0;
 504.226 +	for (row = 0; row < DCTSIZE; row++) {
 504.227 +	  for (col = 0; col < DCTSIZE; col++) {
 504.228 +	    fmtbl[i] = (FLOAT_MULT_TYPE)
 504.229 +	      ((double) qtbl->quantval[i] *
 504.230 +	       aanscalefactor[row] * aanscalefactor[col]);
 504.231 +	    i++;
 504.232 +	  }
 504.233 +	}
 504.234 +      }
 504.235 +      break;
 504.236 +#endif
 504.237 +    default:
 504.238 +      ERREXIT(cinfo, JERR_NOT_COMPILED);
 504.239 +      break;
 504.240 +    }
 504.241 +  }
 504.242 +}
 504.243 +
 504.244 +
 504.245 +/*
 504.246 + * Initialize IDCT manager.
 504.247 + */
 504.248 +
 504.249 +GLOBAL(void)
 504.250 +jinit_inverse_dct (j_decompress_ptr cinfo)
 504.251 +{
 504.252 +  my_idct_ptr idct;
 504.253 +  int ci;
 504.254 +  jpeg_component_info *compptr;
 504.255 +
 504.256 +  idct = (my_idct_ptr)
 504.257 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 504.258 +				SIZEOF(my_idct_controller));
 504.259 +  cinfo->idct = (struct jpeg_inverse_dct *) idct;
 504.260 +  idct->pub.start_pass = start_pass;
 504.261 +
 504.262 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 504.263 +       ci++, compptr++) {
 504.264 +    /* Allocate and pre-zero a multiplier table for each component */
 504.265 +    compptr->dct_table =
 504.266 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 504.267 +				  SIZEOF(multiplier_table));
 504.268 +    MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
 504.269 +    /* Mark multiplier table not yet set up for any method */
 504.270 +    idct->cur_method[ci] = -1;
 504.271 +  }
 504.272 +}
   505.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   505.2 +++ b/libs/libjpeg/jdhuff.c	Sat Feb 01 19:58:19 2014 +0200
   505.3 @@ -0,0 +1,651 @@
   505.4 +/*
   505.5 + * jdhuff.c
   505.6 + *
   505.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   505.8 + * This file is part of the Independent JPEG Group's software.
   505.9 + * For conditions of distribution and use, see the accompanying README file.
  505.10 + *
  505.11 + * This file contains Huffman entropy decoding routines.
  505.12 + *
  505.13 + * Much of the complexity here has to do with supporting input suspension.
  505.14 + * If the data source module demands suspension, we want to be able to back
  505.15 + * up to the start of the current MCU.  To do this, we copy state variables
  505.16 + * into local working storage, and update them back to the permanent
  505.17 + * storage only upon successful completion of an MCU.
  505.18 + */
  505.19 +
  505.20 +#define JPEG_INTERNALS
  505.21 +#include "jinclude.h"
  505.22 +#include "jpeglib.h"
  505.23 +#include "jdhuff.h"		/* Declarations shared with jdphuff.c */
  505.24 +
  505.25 +
  505.26 +/*
  505.27 + * Expanded entropy decoder object for Huffman decoding.
  505.28 + *
  505.29 + * The savable_state subrecord contains fields that change within an MCU,
  505.30 + * but must not be updated permanently until we complete the MCU.
  505.31 + */
  505.32 +
  505.33 +typedef struct {
  505.34 +  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
  505.35 +} savable_state;
  505.36 +
  505.37 +/* This macro is to work around compilers with missing or broken
  505.38 + * structure assignment.  You'll need to fix this code if you have
  505.39 + * such a compiler and you change MAX_COMPS_IN_SCAN.
  505.40 + */
  505.41 +
  505.42 +#ifndef NO_STRUCT_ASSIGN
  505.43 +#define ASSIGN_STATE(dest,src)  ((dest) = (src))
  505.44 +#else
  505.45 +#if MAX_COMPS_IN_SCAN == 4
  505.46 +#define ASSIGN_STATE(dest,src)  \
  505.47 +	((dest).last_dc_val[0] = (src).last_dc_val[0], \
  505.48 +	 (dest).last_dc_val[1] = (src).last_dc_val[1], \
  505.49 +	 (dest).last_dc_val[2] = (src).last_dc_val[2], \
  505.50 +	 (dest).last_dc_val[3] = (src).last_dc_val[3])
  505.51 +#endif
  505.52 +#endif
  505.53 +
  505.54 +
  505.55 +typedef struct {
  505.56 +  struct jpeg_entropy_decoder pub; /* public fields */
  505.57 +
  505.58 +  /* These fields are loaded into local variables at start of each MCU.
  505.59 +   * In case of suspension, we exit WITHOUT updating them.
  505.60 +   */
  505.61 +  bitread_perm_state bitstate;	/* Bit buffer at start of MCU */
  505.62 +  savable_state saved;		/* Other state at start of MCU */
  505.63 +
  505.64 +  /* These fields are NOT loaded into local working state. */
  505.65 +  unsigned int restarts_to_go;	/* MCUs left in this restart interval */
  505.66 +
  505.67 +  /* Pointers to derived tables (these workspaces have image lifespan) */
  505.68 +  d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
  505.69 +  d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
  505.70 +
  505.71 +  /* Precalculated info set up by start_pass for use in decode_mcu: */
  505.72 +
  505.73 +  /* Pointers to derived tables to be used for each block within an MCU */
  505.74 +  d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU];
  505.75 +  d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU];
  505.76 +  /* Whether we care about the DC and AC coefficient values for each block */
  505.77 +  boolean dc_needed[D_MAX_BLOCKS_IN_MCU];
  505.78 +  boolean ac_needed[D_MAX_BLOCKS_IN_MCU];
  505.79 +} huff_entropy_decoder;
  505.80 +
  505.81 +typedef huff_entropy_decoder * huff_entropy_ptr;
  505.82 +
  505.83 +
  505.84 +/*
  505.85 + * Initialize for a Huffman-compressed scan.
  505.86 + */
  505.87 +
  505.88 +METHODDEF(void)
  505.89 +start_pass_huff_decoder (j_decompress_ptr cinfo)
  505.90 +{
  505.91 +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
  505.92 +  int ci, blkn, dctbl, actbl;
  505.93 +  jpeg_component_info * compptr;
  505.94 +
  505.95 +  /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
  505.96 +   * This ought to be an error condition, but we make it a warning because
  505.97 +   * there are some baseline files out there with all zeroes in these bytes.
  505.98 +   */
  505.99 +  if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 ||
 505.100 +      cinfo->Ah != 0 || cinfo->Al != 0)
 505.101 +    WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
 505.102 +
 505.103 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 505.104 +    compptr = cinfo->cur_comp_info[ci];
 505.105 +    dctbl = compptr->dc_tbl_no;
 505.106 +    actbl = compptr->ac_tbl_no;
 505.107 +    /* Compute derived values for Huffman tables */
 505.108 +    /* We may do this more than once for a table, but it's not expensive */
 505.109 +    jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl,
 505.110 +			    & entropy->dc_derived_tbls[dctbl]);
 505.111 +    jpeg_make_d_derived_tbl(cinfo, FALSE, actbl,
 505.112 +			    & entropy->ac_derived_tbls[actbl]);
 505.113 +    /* Initialize DC predictions to 0 */
 505.114 +    entropy->saved.last_dc_val[ci] = 0;
 505.115 +  }
 505.116 +
 505.117 +  /* Precalculate decoding info for each block in an MCU of this scan */
 505.118 +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
 505.119 +    ci = cinfo->MCU_membership[blkn];
 505.120 +    compptr = cinfo->cur_comp_info[ci];
 505.121 +    /* Precalculate which table to use for each block */
 505.122 +    entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
 505.123 +    entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
 505.124 +    /* Decide whether we really care about the coefficient values */
 505.125 +    if (compptr->component_needed) {
 505.126 +      entropy->dc_needed[blkn] = TRUE;
 505.127 +      /* we don't need the ACs if producing a 1/8th-size image */
 505.128 +      entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1);
 505.129 +    } else {
 505.130 +      entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE;
 505.131 +    }
 505.132 +  }
 505.133 +
 505.134 +  /* Initialize bitread state variables */
 505.135 +  entropy->bitstate.bits_left = 0;
 505.136 +  entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
 505.137 +  entropy->pub.insufficient_data = FALSE;
 505.138 +
 505.139 +  /* Initialize restart counter */
 505.140 +  entropy->restarts_to_go = cinfo->restart_interval;
 505.141 +}
 505.142 +
 505.143 +
 505.144 +/*
 505.145 + * Compute the derived values for a Huffman table.
 505.146 + * This routine also performs some validation checks on the table.
 505.147 + *
 505.148 + * Note this is also used by jdphuff.c.
 505.149 + */
 505.150 +
 505.151 +GLOBAL(void)
 505.152 +jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
 505.153 +			 d_derived_tbl ** pdtbl)
 505.154 +{
 505.155 +  JHUFF_TBL *htbl;
 505.156 +  d_derived_tbl *dtbl;
 505.157 +  int p, i, l, si, numsymbols;
 505.158 +  int lookbits, ctr;
 505.159 +  char huffsize[257];
 505.160 +  unsigned int huffcode[257];
 505.161 +  unsigned int code;
 505.162 +
 505.163 +  /* Note that huffsize[] and huffcode[] are filled in code-length order,
 505.164 +   * paralleling the order of the symbols themselves in htbl->huffval[].
 505.165 +   */
 505.166 +
 505.167 +  /* Find the input Huffman table */
 505.168 +  if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
 505.169 +    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
 505.170 +  htbl =
 505.171 +    isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
 505.172 +  if (htbl == NULL)
 505.173 +    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
 505.174 +
 505.175 +  /* Allocate a workspace if we haven't already done so. */
 505.176 +  if (*pdtbl == NULL)
 505.177 +    *pdtbl = (d_derived_tbl *)
 505.178 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 505.179 +				  SIZEOF(d_derived_tbl));
 505.180 +  dtbl = *pdtbl;
 505.181 +  dtbl->pub = htbl;		/* fill in back link */
 505.182 +  
 505.183 +  /* Figure C.1: make table of Huffman code length for each symbol */
 505.184 +
 505.185 +  p = 0;
 505.186 +  for (l = 1; l <= 16; l++) {
 505.187 +    i = (int) htbl->bits[l];
 505.188 +    if (i < 0 || p + i > 256)	/* protect against table overrun */
 505.189 +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 505.190 +    while (i--)
 505.191 +      huffsize[p++] = (char) l;
 505.192 +  }
 505.193 +  huffsize[p] = 0;
 505.194 +  numsymbols = p;
 505.195 +  
 505.196 +  /* Figure C.2: generate the codes themselves */
 505.197 +  /* We also validate that the counts represent a legal Huffman code tree. */
 505.198 +  
 505.199 +  code = 0;
 505.200 +  si = huffsize[0];
 505.201 +  p = 0;
 505.202 +  while (huffsize[p]) {
 505.203 +    while (((int) huffsize[p]) == si) {
 505.204 +      huffcode[p++] = code;
 505.205 +      code++;
 505.206 +    }
 505.207 +    /* code is now 1 more than the last code used for codelength si; but
 505.208 +     * it must still fit in si bits, since no code is allowed to be all ones.
 505.209 +     */
 505.210 +    if (((INT32) code) >= (((INT32) 1) << si))
 505.211 +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 505.212 +    code <<= 1;
 505.213 +    si++;
 505.214 +  }
 505.215 +
 505.216 +  /* Figure F.15: generate decoding tables for bit-sequential decoding */
 505.217 +
 505.218 +  p = 0;
 505.219 +  for (l = 1; l <= 16; l++) {
 505.220 +    if (htbl->bits[l]) {
 505.221 +      /* valoffset[l] = huffval[] index of 1st symbol of code length l,
 505.222 +       * minus the minimum code of length l
 505.223 +       */
 505.224 +      dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
 505.225 +      p += htbl->bits[l];
 505.226 +      dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
 505.227 +    } else {
 505.228 +      dtbl->maxcode[l] = -1;	/* -1 if no codes of this length */
 505.229 +    }
 505.230 +  }
 505.231 +  dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
 505.232 +
 505.233 +  /* Compute lookahead tables to speed up decoding.
 505.234 +   * First we set all the table entries to 0, indicating "too long";
 505.235 +   * then we iterate through the Huffman codes that are short enough and
 505.236 +   * fill in all the entries that correspond to bit sequences starting
 505.237 +   * with that code.
 505.238 +   */
 505.239 +
 505.240 +  MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits));
 505.241 +
 505.242 +  p = 0;
 505.243 +  for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
 505.244 +    for (i = 1; i <= (int) htbl->bits[l]; i++, p++) {
 505.245 +      /* l = current code's length, p = its index in huffcode[] & huffval[]. */
 505.246 +      /* Generate left-justified code followed by all possible bit sequences */
 505.247 +      lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
 505.248 +      for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
 505.249 +	dtbl->look_nbits[lookbits] = l;
 505.250 +	dtbl->look_sym[lookbits] = htbl->huffval[p];
 505.251 +	lookbits++;
 505.252 +      }
 505.253 +    }
 505.254 +  }
 505.255 +
 505.256 +  /* Validate symbols as being reasonable.
 505.257 +   * For AC tables, we make no check, but accept all byte values 0..255.
 505.258 +   * For DC tables, we require the symbols to be in range 0..15.
 505.259 +   * (Tighter bounds could be applied depending on the data depth and mode,
 505.260 +   * but this is sufficient to ensure safe decoding.)
 505.261 +   */
 505.262 +  if (isDC) {
 505.263 +    for (i = 0; i < numsymbols; i++) {
 505.264 +      int sym = htbl->huffval[i];
 505.265 +      if (sym < 0 || sym > 15)
 505.266 +	ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 505.267 +    }
 505.268 +  }
 505.269 +}
 505.270 +
 505.271 +
 505.272 +/*
 505.273 + * Out-of-line code for bit fetching (shared with jdphuff.c).
 505.274 + * See jdhuff.h for info about usage.
 505.275 + * Note: current values of get_buffer and bits_left are passed as parameters,
 505.276 + * but are returned in the corresponding fields of the state struct.
 505.277 + *
 505.278 + * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
 505.279 + * of get_buffer to be used.  (On machines with wider words, an even larger
 505.280 + * buffer could be used.)  However, on some machines 32-bit shifts are
 505.281 + * quite slow and take time proportional to the number of places shifted.
 505.282 + * (This is true with most PC compilers, for instance.)  In this case it may
 505.283 + * be a win to set MIN_GET_BITS to the minimum value of 15.  This reduces the
 505.284 + * average shift distance at the cost of more calls to jpeg_fill_bit_buffer.
 505.285 + */
 505.286 +
 505.287 +#ifdef SLOW_SHIFT_32
 505.288 +#define MIN_GET_BITS  15	/* minimum allowable value */
 505.289 +#else
 505.290 +#define MIN_GET_BITS  (BIT_BUF_SIZE-7)
 505.291 +#endif
 505.292 +
 505.293 +
 505.294 +GLOBAL(boolean)
 505.295 +jpeg_fill_bit_buffer (bitread_working_state * state,
 505.296 +		      register bit_buf_type get_buffer, register int bits_left,
 505.297 +		      int nbits)
 505.298 +/* Load up the bit buffer to a depth of at least nbits */
 505.299 +{
 505.300 +  /* Copy heavily used state fields into locals (hopefully registers) */
 505.301 +  register const JOCTET * next_input_byte = state->next_input_byte;
 505.302 +  register size_t bytes_in_buffer = state->bytes_in_buffer;
 505.303 +  j_decompress_ptr cinfo = state->cinfo;
 505.304 +
 505.305 +  /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */
 505.306 +  /* (It is assumed that no request will be for more than that many bits.) */
 505.307 +  /* We fail to do so only if we hit a marker or are forced to suspend. */
 505.308 +
 505.309 +  if (cinfo->unread_marker == 0) {	/* cannot advance past a marker */
 505.310 +    while (bits_left < MIN_GET_BITS) {
 505.311 +      register int c;
 505.312 +
 505.313 +      /* Attempt to read a byte */
 505.314 +      if (bytes_in_buffer == 0) {
 505.315 +	if (! (*cinfo->src->fill_input_buffer) (cinfo))
 505.316 +	  return FALSE;
 505.317 +	next_input_byte = cinfo->src->next_input_byte;
 505.318 +	bytes_in_buffer = cinfo->src->bytes_in_buffer;
 505.319 +      }
 505.320 +      bytes_in_buffer--;
 505.321 +      c = GETJOCTET(*next_input_byte++);
 505.322 +
 505.323 +      /* If it's 0xFF, check and discard stuffed zero byte */
 505.324 +      if (c == 0xFF) {
 505.325 +	/* Loop here to discard any padding FF's on terminating marker,
 505.326 +	 * so that we can save a valid unread_marker value.  NOTE: we will
 505.327 +	 * accept multiple FF's followed by a 0 as meaning a single FF data
 505.328 +	 * byte.  This data pattern is not valid according to the standard.
 505.329 +	 */
 505.330 +	do {
 505.331 +	  if (bytes_in_buffer == 0) {
 505.332 +	    if (! (*cinfo->src->fill_input_buffer) (cinfo))
 505.333 +	      return FALSE;
 505.334 +	    next_input_byte = cinfo->src->next_input_byte;
 505.335 +	    bytes_in_buffer = cinfo->src->bytes_in_buffer;
 505.336 +	  }
 505.337 +	  bytes_in_buffer--;
 505.338 +	  c = GETJOCTET(*next_input_byte++);
 505.339 +	} while (c == 0xFF);
 505.340 +
 505.341 +	if (c == 0) {
 505.342 +	  /* Found FF/00, which represents an FF data byte */
 505.343 +	  c = 0xFF;
 505.344 +	} else {
 505.345 +	  /* Oops, it's actually a marker indicating end of compressed data.
 505.346 +	   * Save the marker code for later use.
 505.347 +	   * Fine point: it might appear that we should save the marker into
 505.348 +	   * bitread working state, not straight into permanent state.  But
 505.349 +	   * once we have hit a marker, we cannot need to suspend within the
 505.350 +	   * current MCU, because we will read no more bytes from the data
 505.351 +	   * source.  So it is OK to update permanent state right away.
 505.352 +	   */
 505.353 +	  cinfo->unread_marker = c;
 505.354 +	  /* See if we need to insert some fake zero bits. */
 505.355 +	  goto no_more_bytes;
 505.356 +	}
 505.357 +      }
 505.358 +
 505.359 +      /* OK, load c into get_buffer */
 505.360 +      get_buffer = (get_buffer << 8) | c;
 505.361 +      bits_left += 8;
 505.362 +    } /* end while */
 505.363 +  } else {
 505.364 +  no_more_bytes:
 505.365 +    /* We get here if we've read the marker that terminates the compressed
 505.366 +     * data segment.  There should be enough bits in the buffer register
 505.367 +     * to satisfy the request; if so, no problem.
 505.368 +     */
 505.369 +    if (nbits > bits_left) {
 505.370 +      /* Uh-oh.  Report corrupted data to user and stuff zeroes into
 505.371 +       * the data stream, so that we can produce some kind of image.
 505.372 +       * We use a nonvolatile flag to ensure that only one warning message
 505.373 +       * appears per data segment.
 505.374 +       */
 505.375 +      if (! cinfo->entropy->insufficient_data) {
 505.376 +	WARNMS(cinfo, JWRN_HIT_MARKER);
 505.377 +	cinfo->entropy->insufficient_data = TRUE;
 505.378 +      }
 505.379 +      /* Fill the buffer with zero bits */
 505.380 +      get_buffer <<= MIN_GET_BITS - bits_left;
 505.381 +      bits_left = MIN_GET_BITS;
 505.382 +    }
 505.383 +  }
 505.384 +
 505.385 +  /* Unload the local registers */
 505.386 +  state->next_input_byte = next_input_byte;
 505.387 +  state->bytes_in_buffer = bytes_in_buffer;
 505.388 +  state->get_buffer = get_buffer;
 505.389 +  state->bits_left = bits_left;
 505.390 +
 505.391 +  return TRUE;
 505.392 +}
 505.393 +
 505.394 +
 505.395 +/*
 505.396 + * Out-of-line code for Huffman code decoding.
 505.397 + * See jdhuff.h for info about usage.
 505.398 + */
 505.399 +
 505.400 +GLOBAL(int)
 505.401 +jpeg_huff_decode (bitread_working_state * state,
 505.402 +		  register bit_buf_type get_buffer, register int bits_left,
 505.403 +		  d_derived_tbl * htbl, int min_bits)
 505.404 +{
 505.405 +  register int l = min_bits;
 505.406 +  register INT32 code;
 505.407 +
 505.408 +  /* HUFF_DECODE has determined that the code is at least min_bits */
 505.409 +  /* bits long, so fetch that many bits in one swoop. */
 505.410 +
 505.411 +  CHECK_BIT_BUFFER(*state, l, return -1);
 505.412 +  code = GET_BITS(l);
 505.413 +
 505.414 +  /* Collect the rest of the Huffman code one bit at a time. */
 505.415 +  /* This is per Figure F.16 in the JPEG spec. */
 505.416 +
 505.417 +  while (code > htbl->maxcode[l]) {
 505.418 +    code <<= 1;
 505.419 +    CHECK_BIT_BUFFER(*state, 1, return -1);
 505.420 +    code |= GET_BITS(1);
 505.421 +    l++;
 505.422 +  }
 505.423 +
 505.424 +  /* Unload the local registers */
 505.425 +  state->get_buffer = get_buffer;
 505.426 +  state->bits_left = bits_left;
 505.427 +
 505.428 +  /* With garbage input we may reach the sentinel value l = 17. */
 505.429 +
 505.430 +  if (l > 16) {
 505.431 +    WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE);
 505.432 +    return 0;			/* fake a zero as the safest result */
 505.433 +  }
 505.434 +
 505.435 +  return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ];
 505.436 +}
 505.437 +
 505.438 +
 505.439 +/*
 505.440 + * Figure F.12: extend sign bit.
 505.441 + * On some machines, a shift and add will be faster than a table lookup.
 505.442 + */
 505.443 +
 505.444 +#ifdef AVOID_TABLES
 505.445 +
 505.446 +#define HUFF_EXTEND(x,s)  ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
 505.447 +
 505.448 +#else
 505.449 +
 505.450 +#define HUFF_EXTEND(x,s)  ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
 505.451 +
 505.452 +static const int extend_test[16] =   /* entry n is 2**(n-1) */
 505.453 +  { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
 505.454 +    0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
 505.455 +
 505.456 +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
 505.457 +  { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
 505.458 +    ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
 505.459 +    ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
 505.460 +    ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
 505.461 +
 505.462 +#endif /* AVOID_TABLES */
 505.463 +
 505.464 +
 505.465 +/*
 505.466 + * Check for a restart marker & resynchronize decoder.
 505.467 + * Returns FALSE if must suspend.
 505.468 + */
 505.469 +
 505.470 +LOCAL(boolean)
 505.471 +process_restart (j_decompress_ptr cinfo)
 505.472 +{
 505.473 +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
 505.474 +  int ci;
 505.475 +
 505.476 +  /* Throw away any unused bits remaining in bit buffer; */
 505.477 +  /* include any full bytes in next_marker's count of discarded bytes */
 505.478 +  cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
 505.479 +  entropy->bitstate.bits_left = 0;
 505.480 +
 505.481 +  /* Advance past the RSTn marker */
 505.482 +  if (! (*cinfo->marker->read_restart_marker) (cinfo))
 505.483 +    return FALSE;
 505.484 +
 505.485 +  /* Re-initialize DC predictions to 0 */
 505.486 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++)
 505.487 +    entropy->saved.last_dc_val[ci] = 0;
 505.488 +
 505.489 +  /* Reset restart counter */
 505.490 +  entropy->restarts_to_go = cinfo->restart_interval;
 505.491 +
 505.492 +  /* Reset out-of-data flag, unless read_restart_marker left us smack up
 505.493 +   * against a marker.  In that case we will end up treating the next data
 505.494 +   * segment as empty, and we can avoid producing bogus output pixels by
 505.495 +   * leaving the flag set.
 505.496 +   */
 505.497 +  if (cinfo->unread_marker == 0)
 505.498 +    entropy->pub.insufficient_data = FALSE;
 505.499 +
 505.500 +  return TRUE;
 505.501 +}
 505.502 +
 505.503 +
 505.504 +/*
 505.505 + * Decode and return one MCU's worth of Huffman-compressed coefficients.
 505.506 + * The coefficients are reordered from zigzag order into natural array order,
 505.507 + * but are not dequantized.
 505.508 + *
 505.509 + * The i'th block of the MCU is stored into the block pointed to by
 505.510 + * MCU_data[i].  WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER.
 505.511 + * (Wholesale zeroing is usually a little faster than retail...)
 505.512 + *
 505.513 + * Returns FALSE if data source requested suspension.  In that case no
 505.514 + * changes have been made to permanent state.  (Exception: some output
 505.515 + * coefficients may already have been assigned.  This is harmless for
 505.516 + * this module, since we'll just re-assign them on the next call.)
 505.517 + */
 505.518 +
 505.519 +METHODDEF(boolean)
 505.520 +decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 505.521 +{
 505.522 +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
 505.523 +  int blkn;
 505.524 +  BITREAD_STATE_VARS;
 505.525 +  savable_state state;
 505.526 +
 505.527 +  /* Process restart marker if needed; may have to suspend */
 505.528 +  if (cinfo->restart_interval) {
 505.529 +    if (entropy->restarts_to_go == 0)
 505.530 +      if (! process_restart(cinfo))
 505.531 +	return FALSE;
 505.532 +  }
 505.533 +
 505.534 +  /* If we've run out of data, just leave the MCU set to zeroes.
 505.535 +   * This way, we return uniform gray for the remainder of the segment.
 505.536 +   */
 505.537 +  if (! entropy->pub.insufficient_data) {
 505.538 +
 505.539 +    /* Load up working state */
 505.540 +    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
 505.541 +    ASSIGN_STATE(state, entropy->saved);
 505.542 +
 505.543 +    /* Outer loop handles each block in the MCU */
 505.544 +
 505.545 +    for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
 505.546 +      JBLOCKROW block = MCU_data[blkn];
 505.547 +      d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
 505.548 +      d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
 505.549 +      register int s, k, r;
 505.550 +
 505.551 +      /* Decode a single block's worth of coefficients */
 505.552 +
 505.553 +      /* Section F.2.2.1: decode the DC coefficient difference */
 505.554 +      HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
 505.555 +      if (s) {
 505.556 +	CHECK_BIT_BUFFER(br_state, s, return FALSE);
 505.557 +	r = GET_BITS(s);
 505.558 +	s = HUFF_EXTEND(r, s);
 505.559 +      }
 505.560 +
 505.561 +      if (entropy->dc_needed[blkn]) {
 505.562 +	/* Convert DC difference to actual value, update last_dc_val */
 505.563 +	int ci = cinfo->MCU_membership[blkn];
 505.564 +	s += state.last_dc_val[ci];
 505.565 +	state.last_dc_val[ci] = s;
 505.566 +	/* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
 505.567 +	(*block)[0] = (JCOEF) s;
 505.568 +      }
 505.569 +
 505.570 +      if (entropy->ac_needed[blkn]) {
 505.571 +
 505.572 +	/* Section F.2.2.2: decode the AC coefficients */
 505.573 +	/* Since zeroes are skipped, output area must be cleared beforehand */
 505.574 +	for (k = 1; k < DCTSIZE2; k++) {
 505.575 +	  HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
 505.576 +      
 505.577 +	  r = s >> 4;
 505.578 +	  s &= 15;
 505.579 +      
 505.580 +	  if (s) {
 505.581 +	    k += r;
 505.582 +	    CHECK_BIT_BUFFER(br_state, s, return FALSE);
 505.583 +	    r = GET_BITS(s);
 505.584 +	    s = HUFF_EXTEND(r, s);
 505.585 +	    /* Output coefficient in natural (dezigzagged) order.
 505.586 +	     * Note: the extra entries in jpeg_natural_order[] will save us
 505.587 +	     * if k >= DCTSIZE2, which could happen if the data is corrupted.
 505.588 +	     */
 505.589 +	    (*block)[jpeg_natural_order[k]] = (JCOEF) s;
 505.590 +	  } else {
 505.591 +	    if (r != 15)
 505.592 +	      break;
 505.593 +	    k += 15;
 505.594 +	  }
 505.595 +	}
 505.596 +
 505.597 +      } else {
 505.598 +
 505.599 +	/* Section F.2.2.2: decode the AC coefficients */
 505.600 +	/* In this path we just discard the values */
 505.601 +	for (k = 1; k < DCTSIZE2; k++) {
 505.602 +	  HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
 505.603 +      
 505.604 +	  r = s >> 4;
 505.605 +	  s &= 15;
 505.606 +      
 505.607 +	  if (s) {
 505.608 +	    k += r;
 505.609 +	    CHECK_BIT_BUFFER(br_state, s, return FALSE);
 505.610 +	    DROP_BITS(s);
 505.611 +	  } else {
 505.612 +	    if (r != 15)
 505.613 +	      break;
 505.614 +	    k += 15;
 505.615 +	  }
 505.616 +	}
 505.617 +
 505.618 +      }
 505.619 +    }
 505.620 +
 505.621 +    /* Completed MCU, so update state */
 505.622 +    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
 505.623 +    ASSIGN_STATE(entropy->saved, state);
 505.624 +  }
 505.625 +
 505.626 +  /* Account for restart interval (no-op if not using restarts) */
 505.627 +  entropy->restarts_to_go--;
 505.628 +
 505.629 +  return TRUE;
 505.630 +}
 505.631 +
 505.632 +
 505.633 +/*
 505.634 + * Module initialization routine for Huffman entropy decoding.
 505.635 + */
 505.636 +
 505.637 +GLOBAL(void)
 505.638 +jinit_huff_decoder (j_decompress_ptr cinfo)
 505.639 +{
 505.640 +  huff_entropy_ptr entropy;
 505.641 +  int i;
 505.642 +
 505.643 +  entropy = (huff_entropy_ptr)
 505.644 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 505.645 +				SIZEOF(huff_entropy_decoder));
 505.646 +  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
 505.647 +  entropy->pub.start_pass = start_pass_huff_decoder;
 505.648 +  entropy->pub.decode_mcu = decode_mcu;
 505.649 +
 505.650 +  /* Mark tables unallocated */
 505.651 +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
 505.652 +    entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
 505.653 +  }
 505.654 +}
   506.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   506.2 +++ b/libs/libjpeg/jdhuff.h	Sat Feb 01 19:58:19 2014 +0200
   506.3 @@ -0,0 +1,201 @@
   506.4 +/*
   506.5 + * jdhuff.h
   506.6 + *
   506.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   506.8 + * This file is part of the Independent JPEG Group's software.
   506.9 + * For conditions of distribution and use, see the accompanying README file.
  506.10 + *
  506.11 + * This file contains declarations for Huffman entropy decoding routines
  506.12 + * that are shared between the sequential decoder (jdhuff.c) and the
  506.13 + * progressive decoder (jdphuff.c).  No other modules need to see these.
  506.14 + */
  506.15 +
  506.16 +/* Short forms of external names for systems with brain-damaged linkers. */
  506.17 +
  506.18 +#ifdef NEED_SHORT_EXTERNAL_NAMES
  506.19 +#define jpeg_make_d_derived_tbl	jMkDDerived
  506.20 +#define jpeg_fill_bit_buffer	jFilBitBuf
  506.21 +#define jpeg_huff_decode	jHufDecode
  506.22 +#endif /* NEED_SHORT_EXTERNAL_NAMES */
  506.23 +
  506.24 +
  506.25 +/* Derived data constructed for each Huffman table */
  506.26 +
  506.27 +#define HUFF_LOOKAHEAD	8	/* # of bits of lookahead */
  506.28 +
  506.29 +typedef struct {
  506.30 +  /* Basic tables: (element [0] of each array is unused) */
  506.31 +  INT32 maxcode[18];		/* largest code of length k (-1 if none) */
  506.32 +  /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
  506.33 +  INT32 valoffset[17];		/* huffval[] offset for codes of length k */
  506.34 +  /* valoffset[k] = huffval[] index of 1st symbol of code length k, less
  506.35 +   * the smallest code of length k; so given a code of length k, the
  506.36 +   * corresponding symbol is huffval[code + valoffset[k]]
  506.37 +   */
  506.38 +
  506.39 +  /* Link to public Huffman table (needed only in jpeg_huff_decode) */
  506.40 +  JHUFF_TBL *pub;
  506.41 +
  506.42 +  /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
  506.43 +   * the input data stream.  If the next Huffman code is no more
  506.44 +   * than HUFF_LOOKAHEAD bits long, we can obtain its length and
  506.45 +   * the corresponding symbol directly from these tables.
  506.46 +   */
  506.47 +  int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
  506.48 +  UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
  506.49 +} d_derived_tbl;
  506.50 +
  506.51 +/* Expand a Huffman table definition into the derived format */
  506.52 +EXTERN(void) jpeg_make_d_derived_tbl
  506.53 +	JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
  506.54 +	     d_derived_tbl ** pdtbl));
  506.55 +
  506.56 +
  506.57 +/*
  506.58 + * Fetching the next N bits from the input stream is a time-critical operation
  506.59 + * for the Huffman decoders.  We implement it with a combination of inline
  506.60 + * macros and out-of-line subroutines.  Note that N (the number of bits
  506.61 + * demanded at one time) never exceeds 15 for JPEG use.
  506.62 + *
  506.63 + * We read source bytes into get_buffer and dole out bits as needed.
  506.64 + * If get_buffer already contains enough bits, they are fetched in-line
  506.65 + * by the macros CHECK_BIT_BUFFER and GET_BITS.  When there aren't enough
  506.66 + * bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer
  506.67 + * as full as possible (not just to the number of bits needed; this
  506.68 + * prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer).
  506.69 + * Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension.
  506.70 + * On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains
  506.71 + * at least the requested number of bits --- dummy zeroes are inserted if
  506.72 + * necessary.
  506.73 + */
  506.74 +
  506.75 +typedef INT32 bit_buf_type;	/* type of bit-extraction buffer */
  506.76 +#define BIT_BUF_SIZE  32	/* size of buffer in bits */
  506.77 +
  506.78 +/* If long is > 32 bits on your machine, and shifting/masking longs is
  506.79 + * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
  506.80 + * appropriately should be a win.  Unfortunately we can't define the size
  506.81 + * with something like  #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
  506.82 + * because not all machines measure sizeof in 8-bit bytes.
  506.83 + */
  506.84 +
  506.85 +typedef struct {		/* Bitreading state saved across MCUs */
  506.86 +  bit_buf_type get_buffer;	/* current bit-extraction buffer */
  506.87 +  int bits_left;		/* # of unused bits in it */
  506.88 +} bitread_perm_state;
  506.89 +
  506.90 +typedef struct {		/* Bitreading working state within an MCU */
  506.91 +  /* Current data source location */
  506.92 +  /* We need a copy, rather than munging the original, in case of suspension */
  506.93 +  const JOCTET * next_input_byte; /* => next byte to read from source */
  506.94 +  size_t bytes_in_buffer;	/* # of bytes remaining in source buffer */
  506.95 +  /* Bit input buffer --- note these values are kept in register variables,
  506.96 +   * not in this struct, inside the inner loops.
  506.97 +   */
  506.98 +  bit_buf_type get_buffer;	/* current bit-extraction buffer */
  506.99 +  int bits_left;		/* # of unused bits in it */
 506.100 +  /* Pointer needed by jpeg_fill_bit_buffer. */
 506.101 +  j_decompress_ptr cinfo;	/* back link to decompress master record */
 506.102 +} bitread_working_state;
 506.103 +
 506.104 +/* Macros to declare and load/save bitread local variables. */
 506.105 +#define BITREAD_STATE_VARS  \
 506.106 +	register bit_buf_type get_buffer;  \
 506.107 +	register int bits_left;  \
 506.108 +	bitread_working_state br_state
 506.109 +
 506.110 +#define BITREAD_LOAD_STATE(cinfop,permstate)  \
 506.111 +	br_state.cinfo = cinfop; \
 506.112 +	br_state.next_input_byte = cinfop->src->next_input_byte; \
 506.113 +	br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
 506.114 +	get_buffer = permstate.get_buffer; \
 506.115 +	bits_left = permstate.bits_left;
 506.116 +
 506.117 +#define BITREAD_SAVE_STATE(cinfop,permstate)  \
 506.118 +	cinfop->src->next_input_byte = br_state.next_input_byte; \
 506.119 +	cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
 506.120 +	permstate.get_buffer = get_buffer; \
 506.121 +	permstate.bits_left = bits_left
 506.122 +
 506.123 +/*
 506.124 + * These macros provide the in-line portion of bit fetching.
 506.125 + * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
 506.126 + * before using GET_BITS, PEEK_BITS, or DROP_BITS.
 506.127 + * The variables get_buffer and bits_left are assumed to be locals,
 506.128 + * but the state struct might not be (jpeg_huff_decode needs this).
 506.129 + *	CHECK_BIT_BUFFER(state,n,action);
 506.130 + *		Ensure there are N bits in get_buffer; if suspend, take action.
 506.131 + *      val = GET_BITS(n);
 506.132 + *		Fetch next N bits.
 506.133 + *      val = PEEK_BITS(n);
 506.134 + *		Fetch next N bits without removing them from the buffer.
 506.135 + *	DROP_BITS(n);
 506.136 + *		Discard next N bits.
 506.137 + * The value N should be a simple variable, not an expression, because it
 506.138 + * is evaluated multiple times.
 506.139 + */
 506.140 +
 506.141 +#define CHECK_BIT_BUFFER(state,nbits,action) \
 506.142 +	{ if (bits_left < (nbits)) {  \
 506.143 +	    if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits))  \
 506.144 +	      { action; }  \
 506.145 +	    get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
 506.146 +
 506.147 +#define GET_BITS(nbits) \
 506.148 +	(((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
 506.149 +
 506.150 +#define PEEK_BITS(nbits) \
 506.151 +	(((int) (get_buffer >> (bits_left -  (nbits)))) & ((1<<(nbits))-1))
 506.152 +
 506.153 +#define DROP_BITS(nbits) \
 506.154 +	(bits_left -= (nbits))
 506.155 +
 506.156 +/* Load up the bit buffer to a depth of at least nbits */
 506.157 +EXTERN(boolean) jpeg_fill_bit_buffer
 506.158 +	JPP((bitread_working_state * state, register bit_buf_type get_buffer,
 506.159 +	     register int bits_left, int nbits));
 506.160 +
 506.161 +
 506.162 +/*
 506.163 + * Code for extracting next Huffman-coded symbol from input bit stream.
 506.164 + * Again, this is time-critical and we make the main paths be macros.
 506.165 + *
 506.166 + * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
 506.167 + * without looping.  Usually, more than 95% of the Huffman codes will be 8
 506.168 + * or fewer bits long.  The few overlength codes are handled with a loop,
 506.169 + * which need not be inline code.
 506.170 + *
 506.171 + * Notes about the HUFF_DECODE macro:
 506.172 + * 1. Near the end of the data segment, we may fail to get enough bits
 506.173 + *    for a lookahead.  In that case, we do it the hard way.
 506.174 + * 2. If the lookahead table contains no entry, the next code must be
 506.175 + *    more than HUFF_LOOKAHEAD bits long.
 506.176 + * 3. jpeg_huff_decode returns -1 if forced to suspend.
 506.177 + */
 506.178 +
 506.179 +#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
 506.180 +{ register int nb, look; \
 506.181 +  if (bits_left < HUFF_LOOKAHEAD) { \
 506.182 +    if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
 506.183 +    get_buffer = state.get_buffer; bits_left = state.bits_left; \
 506.184 +    if (bits_left < HUFF_LOOKAHEAD) { \
 506.185 +      nb = 1; goto slowlabel; \
 506.186 +    } \
 506.187 +  } \
 506.188 +  look = PEEK_BITS(HUFF_LOOKAHEAD); \
 506.189 +  if ((nb = htbl->look_nbits[look]) != 0) { \
 506.190 +    DROP_BITS(nb); \
 506.191 +    result = htbl->look_sym[look]; \
 506.192 +  } else { \
 506.193 +    nb = HUFF_LOOKAHEAD+1; \
 506.194 +slowlabel: \
 506.195 +    if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
 506.196 +	{ failaction; } \
 506.197 +    get_buffer = state.get_buffer; bits_left = state.bits_left; \
 506.198 +  } \
 506.199 +}
 506.200 +
 506.201 +/* Out-of-line case for Huffman code fetching */
 506.202 +EXTERN(int) jpeg_huff_decode
 506.203 +	JPP((bitread_working_state * state, register bit_buf_type get_buffer,
 506.204 +	     register int bits_left, d_derived_tbl * htbl, int min_bits));
   507.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   507.2 +++ b/libs/libjpeg/jdinput.c	Sat Feb 01 19:58:19 2014 +0200
   507.3 @@ -0,0 +1,381 @@
   507.4 +/*
   507.5 + * jdinput.c
   507.6 + *
   507.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   507.8 + * This file is part of the Independent JPEG Group's software.
   507.9 + * For conditions of distribution and use, see the accompanying README file.
  507.10 + *
  507.11 + * This file contains input control logic for the JPEG decompressor.
  507.12 + * These routines are concerned with controlling the decompressor's input
  507.13 + * processing (marker reading and coefficient decoding).  The actual input
  507.14 + * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c.
  507.15 + */
  507.16 +
  507.17 +#define JPEG_INTERNALS
  507.18 +#include "jinclude.h"
  507.19 +#include "jpeglib.h"
  507.20 +
  507.21 +
  507.22 +/* Private state */
  507.23 +
  507.24 +typedef struct {
  507.25 +  struct jpeg_input_controller pub; /* public fields */
  507.26 +
  507.27 +  boolean inheaders;		/* TRUE until first SOS is reached */
  507.28 +} my_input_controller;
  507.29 +
  507.30 +typedef my_input_controller * my_inputctl_ptr;
  507.31 +
  507.32 +
  507.33 +/* Forward declarations */
  507.34 +METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
  507.35 +
  507.36 +
  507.37 +/*
  507.38 + * Routines to calculate various quantities related to the size of the image.
  507.39 + */
  507.40 +
  507.41 +LOCAL(void)
  507.42 +initial_setup (j_decompress_ptr cinfo)
  507.43 +/* Called once, when first SOS marker is reached */
  507.44 +{
  507.45 +  int ci;
  507.46 +  jpeg_component_info *compptr;
  507.47 +
  507.48 +  /* Make sure image isn't bigger than I can handle */
  507.49 +  if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
  507.50 +      (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
  507.51 +    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
  507.52 +
  507.53 +  /* For now, precision must match compiled-in value... */
  507.54 +  if (cinfo->data_precision != BITS_IN_JSAMPLE)
  507.55 +    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
  507.56 +
  507.57 +  /* Check that number of components won't exceed internal array sizes */
  507.58 +  if (cinfo->num_components > MAX_COMPONENTS)
  507.59 +    ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
  507.60 +	     MAX_COMPONENTS);
  507.61 +
  507.62 +  /* Compute maximum sampling factors; check factor validity */
  507.63 +  cinfo->max_h_samp_factor = 1;
  507.64 +  cinfo->max_v_samp_factor = 1;
  507.65 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  507.66 +       ci++, compptr++) {
  507.67 +    if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
  507.68 +	compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
  507.69 +      ERREXIT(cinfo, JERR_BAD_SAMPLING);
  507.70 +    cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
  507.71 +				   compptr->h_samp_factor);
  507.72 +    cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
  507.73 +				   compptr->v_samp_factor);
  507.74 +  }
  507.75 +
  507.76 +  /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
  507.77 +   * In the full decompressor, this will be overridden by jdmaster.c;
  507.78 +   * but in the transcoder, jdmaster.c is not used, so we must do it here.
  507.79 +   */
  507.80 +  cinfo->min_DCT_scaled_size = DCTSIZE;
  507.81 +
  507.82 +  /* Compute dimensions of components */
  507.83 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  507.84 +       ci++, compptr++) {
  507.85 +    compptr->DCT_scaled_size = DCTSIZE;
  507.86 +    /* Size in DCT blocks */
  507.87 +    compptr->width_in_blocks = (JDIMENSION)
  507.88 +      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
  507.89 +		    (long) (cinfo->max_h_samp_factor * DCTSIZE));
  507.90 +    compptr->height_in_blocks = (JDIMENSION)
  507.91 +      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
  507.92 +		    (long) (cinfo->max_v_samp_factor * DCTSIZE));
  507.93 +    /* downsampled_width and downsampled_height will also be overridden by
  507.94 +     * jdmaster.c if we are doing full decompression.  The transcoder library
  507.95 +     * doesn't use these values, but the calling application might.
  507.96 +     */
  507.97 +    /* Size in samples */
  507.98 +    compptr->downsampled_width = (JDIMENSION)
  507.99 +      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
 507.100 +		    (long) cinfo->max_h_samp_factor);
 507.101 +    compptr->downsampled_height = (JDIMENSION)
 507.102 +      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
 507.103 +		    (long) cinfo->max_v_samp_factor);
 507.104 +    /* Mark component needed, until color conversion says otherwise */
 507.105 +    compptr->component_needed = TRUE;
 507.106 +    /* Mark no quantization table yet saved for component */
 507.107 +    compptr->quant_table = NULL;
 507.108 +  }
 507.109 +
 507.110 +  /* Compute number of fully interleaved MCU rows. */
 507.111 +  cinfo->total_iMCU_rows = (JDIMENSION)
 507.112 +    jdiv_round_up((long) cinfo->image_height,
 507.113 +		  (long) (cinfo->max_v_samp_factor*DCTSIZE));
 507.114 +
 507.115 +  /* Decide whether file contains multiple scans */
 507.116 +  if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
 507.117 +    cinfo->inputctl->has_multiple_scans = TRUE;
 507.118 +  else
 507.119 +    cinfo->inputctl->has_multiple_scans = FALSE;
 507.120 +}
 507.121 +
 507.122 +
 507.123 +LOCAL(void)
 507.124 +per_scan_setup (j_decompress_ptr cinfo)
 507.125 +/* Do computations that are needed before processing a JPEG scan */
 507.126 +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
 507.127 +{
 507.128 +  int ci, mcublks, tmp;
 507.129 +  jpeg_component_info *compptr;
 507.130 +  
 507.131 +  if (cinfo->comps_in_scan == 1) {
 507.132 +    
 507.133 +    /* Noninterleaved (single-component) scan */
 507.134 +    compptr = cinfo->cur_comp_info[0];
 507.135 +    
 507.136 +    /* Overall image size in MCUs */
 507.137 +    cinfo->MCUs_per_row = compptr->width_in_blocks;
 507.138 +    cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
 507.139 +    
 507.140 +    /* For noninterleaved scan, always one block per MCU */
 507.141 +    compptr->MCU_width = 1;
 507.142 +    compptr->MCU_height = 1;
 507.143 +    compptr->MCU_blocks = 1;
 507.144 +    compptr->MCU_sample_width = compptr->DCT_scaled_size;
 507.145 +    compptr->last_col_width = 1;
 507.146 +    /* For noninterleaved scans, it is convenient to define last_row_height
 507.147 +     * as the number of block rows present in the last iMCU row.
 507.148 +     */
 507.149 +    tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
 507.150 +    if (tmp == 0) tmp = compptr->v_samp_factor;
 507.151 +    compptr->last_row_height = tmp;
 507.152 +    
 507.153 +    /* Prepare array describing MCU composition */
 507.154 +    cinfo->blocks_in_MCU = 1;
 507.155 +    cinfo->MCU_membership[0] = 0;
 507.156 +    
 507.157 +  } else {
 507.158 +    
 507.159 +    /* Interleaved (multi-component) scan */
 507.160 +    if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
 507.161 +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
 507.162 +	       MAX_COMPS_IN_SCAN);
 507.163 +    
 507.164 +    /* Overall image size in MCUs */
 507.165 +    cinfo->MCUs_per_row = (JDIMENSION)
 507.166 +      jdiv_round_up((long) cinfo->image_width,
 507.167 +		    (long) (cinfo->max_h_samp_factor*DCTSIZE));
 507.168 +    cinfo->MCU_rows_in_scan = (JDIMENSION)
 507.169 +      jdiv_round_up((long) cinfo->image_height,
 507.170 +		    (long) (cinfo->max_v_samp_factor*DCTSIZE));
 507.171 +    
 507.172 +    cinfo->blocks_in_MCU = 0;
 507.173 +    
 507.174 +    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 507.175 +      compptr = cinfo->cur_comp_info[ci];
 507.176 +      /* Sampling factors give # of blocks of component in each MCU */
 507.177 +      compptr->MCU_width = compptr->h_samp_factor;
 507.178 +      compptr->MCU_height = compptr->v_samp_factor;
 507.179 +      compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
 507.180 +      compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
 507.181 +      /* Figure number of non-dummy blocks in last MCU column & row */
 507.182 +      tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
 507.183 +      if (tmp == 0) tmp = compptr->MCU_width;
 507.184 +      compptr->last_col_width = tmp;
 507.185 +      tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
 507.186 +      if (tmp == 0) tmp = compptr->MCU_height;
 507.187 +      compptr->last_row_height = tmp;
 507.188 +      /* Prepare array describing MCU composition */
 507.189 +      mcublks = compptr->MCU_blocks;
 507.190 +      if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
 507.191 +	ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
 507.192 +      while (mcublks-- > 0) {
 507.193 +	cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
 507.194 +      }
 507.195 +    }
 507.196 +    
 507.197 +  }
 507.198 +}
 507.199 +
 507.200 +
 507.201 +/*
 507.202 + * Save away a copy of the Q-table referenced by each component present
 507.203 + * in the current scan, unless already saved during a prior scan.
 507.204 + *
 507.205 + * In a multiple-scan JPEG file, the encoder could assign different components
 507.206 + * the same Q-table slot number, but change table definitions between scans
 507.207 + * so that each component uses a different Q-table.  (The IJG encoder is not
 507.208 + * currently capable of doing this, but other encoders might.)  Since we want
 507.209 + * to be able to dequantize all the components at the end of the file, this
 507.210 + * means that we have to save away the table actually used for each component.
 507.211 + * We do this by copying the table at the start of the first scan containing
 507.212 + * the component.
 507.213 + * The JPEG spec prohibits the encoder from changing the contents of a Q-table
 507.214 + * slot between scans of a component using that slot.  If the encoder does so
 507.215 + * anyway, this decoder will simply use the Q-table values that were current
 507.216 + * at the start of the first scan for the component.
 507.217 + *
 507.218 + * The decompressor output side looks only at the saved quant tables,
 507.219 + * not at the current Q-table slots.
 507.220 + */
 507.221 +
 507.222 +LOCAL(void)
 507.223 +latch_quant_tables (j_decompress_ptr cinfo)
 507.224 +{
 507.225 +  int ci, qtblno;
 507.226 +  jpeg_component_info *compptr;
 507.227 +  JQUANT_TBL * qtbl;
 507.228 +
 507.229 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 507.230 +    compptr = cinfo->cur_comp_info[ci];
 507.231 +    /* No work if we already saved Q-table for this component */
 507.232 +    if (compptr->quant_table != NULL)
 507.233 +      continue;
 507.234 +    /* Make sure specified quantization table is present */
 507.235 +    qtblno = compptr->quant_tbl_no;
 507.236 +    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
 507.237 +	cinfo->quant_tbl_ptrs[qtblno] == NULL)
 507.238 +      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
 507.239 +    /* OK, save away the quantization table */
 507.240 +    qtbl = (JQUANT_TBL *)
 507.241 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 507.242 +				  SIZEOF(JQUANT_TBL));
 507.243 +    MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
 507.244 +    compptr->quant_table = qtbl;
 507.245 +  }
 507.246 +}
 507.247 +
 507.248 +
 507.249 +/*
 507.250 + * Initialize the input modules to read a scan of compressed data.
 507.251 + * The first call to this is done by jdmaster.c after initializing
 507.252 + * the entire decompressor (during jpeg_start_decompress).
 507.253 + * Subsequent calls come from consume_markers, below.
 507.254 + */
 507.255 +
 507.256 +METHODDEF(void)
 507.257 +start_input_pass (j_decompress_ptr cinfo)
 507.258 +{
 507.259 +  per_scan_setup(cinfo);
 507.260 +  latch_quant_tables(cinfo);
 507.261 +  (*cinfo->entropy->start_pass) (cinfo);
 507.262 +  (*cinfo->coef->start_input_pass) (cinfo);
 507.263 +  cinfo->inputctl->consume_input = cinfo->coef->consume_data;
 507.264 +}
 507.265 +
 507.266 +
 507.267 +/*
 507.268 + * Finish up after inputting a compressed-data scan.
 507.269 + * This is called by the coefficient controller after it's read all
 507.270 + * the expected data of the scan.
 507.271 + */
 507.272 +
 507.273 +METHODDEF(void)
 507.274 +finish_input_pass (j_decompress_ptr cinfo)
 507.275 +{
 507.276 +  cinfo->inputctl->consume_input = consume_markers;
 507.277 +}
 507.278 +
 507.279 +
 507.280 +/*
 507.281 + * Read JPEG markers before, between, or after compressed-data scans.
 507.282 + * Change state as necessary when a new scan is reached.
 507.283 + * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
 507.284 + *
 507.285 + * The consume_input method pointer points either here or to the
 507.286 + * coefficient controller's consume_data routine, depending on whether
 507.287 + * we are reading a compressed data segment or inter-segment markers.
 507.288 + */
 507.289 +
 507.290 +METHODDEF(int)
 507.291 +consume_markers (j_decompress_ptr cinfo)
 507.292 +{
 507.293 +  my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
 507.294 +  int val;
 507.295 +
 507.296 +  if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
 507.297 +    return JPEG_REACHED_EOI;
 507.298 +
 507.299 +  val = (*cinfo->marker->read_markers) (cinfo);
 507.300 +
 507.301 +  switch (val) {
 507.302 +  case JPEG_REACHED_SOS:	/* Found SOS */
 507.303 +    if (inputctl->inheaders) {	/* 1st SOS */
 507.304 +      initial_setup(cinfo);
 507.305 +      inputctl->inheaders = FALSE;
 507.306 +      /* Note: start_input_pass must be called by jdmaster.c
 507.307 +       * before any more input can be consumed.  jdapimin.c is
 507.308 +       * responsible for enforcing this sequencing.
 507.309 +       */
 507.310 +    } else {			/* 2nd or later SOS marker */
 507.311 +      if (! inputctl->pub.has_multiple_scans)
 507.312 +	ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
 507.313 +      start_input_pass(cinfo);
 507.314 +    }
 507.315 +    break;
 507.316 +  case JPEG_REACHED_EOI:	/* Found EOI */
 507.317 +    inputctl->pub.eoi_reached = TRUE;
 507.318 +    if (inputctl->inheaders) {	/* Tables-only datastream, apparently */
 507.319 +      if (cinfo->marker->saw_SOF)
 507.320 +	ERREXIT(cinfo, JERR_SOF_NO_SOS);
 507.321 +    } else {
 507.322 +      /* Prevent infinite loop in coef ctlr's decompress_data routine
 507.323 +       * if user set output_scan_number larger than number of scans.
 507.324 +       */
 507.325 +      if (cinfo->output_scan_number > cinfo->input_scan_number)
 507.326 +	cinfo->output_scan_number = cinfo->input_scan_number;
 507.327 +    }
 507.328 +    break;
 507.329 +  case JPEG_SUSPENDED:
 507.330 +    break;
 507.331 +  }
 507.332 +
 507.333 +  return val;
 507.334 +}
 507.335 +
 507.336 +
 507.337 +/*
 507.338 + * Reset state to begin a fresh datastream.
 507.339 + */
 507.340 +
 507.341 +METHODDEF(void)
 507.342 +reset_input_controller (j_decompress_ptr cinfo)
 507.343 +{
 507.344 +  my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
 507.345 +
 507.346 +  inputctl->pub.consume_input = consume_markers;
 507.347 +  inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
 507.348 +  inputctl->pub.eoi_reached = FALSE;
 507.349 +  inputctl->inheaders = TRUE;
 507.350 +  /* Reset other modules */
 507.351 +  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
 507.352 +  (*cinfo->marker->reset_marker_reader) (cinfo);
 507.353 +  /* Reset progression state -- would be cleaner if entropy decoder did this */
 507.354 +  cinfo->coef_bits = NULL;
 507.355 +}
 507.356 +
 507.357 +
 507.358 +/*
 507.359 + * Initialize the input controller module.
 507.360 + * This is called only once, when the decompression object is created.
 507.361 + */
 507.362 +
 507.363 +GLOBAL(void)
 507.364 +jinit_input_controller (j_decompress_ptr cinfo)
 507.365 +{
 507.366 +  my_inputctl_ptr inputctl;
 507.367 +
 507.368 +  /* Create subobject in permanent pool */
 507.369 +  inputctl = (my_inputctl_ptr)
 507.370 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 507.371 +				SIZEOF(my_input_controller));
 507.372 +  cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
 507.373 +  /* Initialize method pointers */
 507.374 +  inputctl->pub.consume_input = consume_markers;
 507.375 +  inputctl->pub.reset_input_controller = reset_input_controller;
 507.376 +  inputctl->pub.start_input_pass = start_input_pass;
 507.377 +  inputctl->pub.finish_input_pass = finish_input_pass;
 507.378 +  /* Initialize state: can't use reset_input_controller since we don't
 507.379 +   * want to try to reset other modules yet.
 507.380 +   */
 507.381 +  inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
 507.382 +  inputctl->pub.eoi_reached = FALSE;
 507.383 +  inputctl->inheaders = TRUE;
 507.384 +}
   508.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   508.2 +++ b/libs/libjpeg/jdmainct.c	Sat Feb 01 19:58:19 2014 +0200
   508.3 @@ -0,0 +1,512 @@
   508.4 +/*
   508.5 + * jdmainct.c
   508.6 + *
   508.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   508.8 + * This file is part of the Independent JPEG Group's software.
   508.9 + * For conditions of distribution and use, see the accompanying README file.
  508.10 + *
  508.11 + * This file contains the main buffer controller for decompression.
  508.12 + * The main buffer lies between the JPEG decompressor proper and the
  508.13 + * post-processor; it holds downsampled data in the JPEG colorspace.
  508.14 + *
  508.15 + * Note that this code is bypassed in raw-data mode, since the application
  508.16 + * supplies the equivalent of the main buffer in that case.
  508.17 + */
  508.18 +
  508.19 +#define JPEG_INTERNALS
  508.20 +#include "jinclude.h"
  508.21 +#include "jpeglib.h"
  508.22 +
  508.23 +
  508.24 +/*
  508.25 + * In the current system design, the main buffer need never be a full-image
  508.26 + * buffer; any full-height buffers will be found inside the coefficient or
  508.27 + * postprocessing controllers.  Nonetheless, the main controller is not
  508.28 + * trivial.  Its responsibility is to provide context rows for upsampling/
  508.29 + * rescaling, and doing this in an efficient fashion is a bit tricky.
  508.30 + *
  508.31 + * Postprocessor input data is counted in "row groups".  A row group
  508.32 + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
  508.33 + * sample rows of each component.  (We require DCT_scaled_size values to be
  508.34 + * chosen such that these numbers are integers.  In practice DCT_scaled_size
  508.35 + * values will likely be powers of two, so we actually have the stronger
  508.36 + * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
  508.37 + * Upsampling will typically produce max_v_samp_factor pixel rows from each
  508.38 + * row group (times any additional scale factor that the upsampler is
  508.39 + * applying).
  508.40 + *
  508.41 + * The coefficient controller will deliver data to us one iMCU row at a time;
  508.42 + * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or
  508.43 + * exactly min_DCT_scaled_size row groups.  (This amount of data corresponds
  508.44 + * to one row of MCUs when the image is fully interleaved.)  Note that the
  508.45 + * number of sample rows varies across components, but the number of row
  508.46 + * groups does not.  Some garbage sample rows may be included in the last iMCU
  508.47 + * row at the bottom of the image.
  508.48 + *
  508.49 + * Depending on the vertical scaling algorithm used, the upsampler may need
  508.50 + * access to the sample row(s) above and below its current input row group.
  508.51 + * The upsampler is required to set need_context_rows TRUE at global selection
  508.52 + * time if so.  When need_context_rows is FALSE, this controller can simply
  508.53 + * obtain one iMCU row at a time from the coefficient controller and dole it
  508.54 + * out as row groups to the postprocessor.
  508.55 + *
  508.56 + * When need_context_rows is TRUE, this controller guarantees that the buffer
  508.57 + * passed to postprocessing contains at least one row group's worth of samples
  508.58 + * above and below the row group(s) being processed.  Note that the context
  508.59 + * rows "above" the first passed row group appear at negative row offsets in
  508.60 + * the passed buffer.  At the top and bottom of the image, the required
  508.61 + * context rows are manufactured by duplicating the first or last real sample
  508.62 + * row; this avoids having special cases in the upsampling inner loops.
  508.63 + *
  508.64 + * The amount of context is fixed at one row group just because that's a
  508.65 + * convenient number for this controller to work with.  The existing
  508.66 + * upsamplers really only need one sample row of context.  An upsampler
  508.67 + * supporting arbitrary output rescaling might wish for more than one row
  508.68 + * group of context when shrinking the image; tough, we don't handle that.
  508.69 + * (This is justified by the assumption that downsizing will be handled mostly
  508.70 + * by adjusting the DCT_scaled_size values, so that the actual scale factor at
  508.71 + * the upsample step needn't be much less than one.)
  508.72 + *
  508.73 + * To provide the desired context, we have to retain the last two row groups
  508.74 + * of one iMCU row while reading in the next iMCU row.  (The last row group
  508.75 + * can't be processed until we have another row group for its below-context,
  508.76 + * and so we have to save the next-to-last group too for its above-context.)
  508.77 + * We could do this most simply by copying data around in our buffer, but
  508.78 + * that'd be very slow.  We can avoid copying any data by creating a rather
  508.79 + * strange pointer structure.  Here's how it works.  We allocate a workspace
  508.80 + * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
  508.81 + * of row groups per iMCU row).  We create two sets of redundant pointers to
  508.82 + * the workspace.  Labeling the physical row groups 0 to M+1, the synthesized
  508.83 + * pointer lists look like this:
  508.84 + *                   M+1                          M-1
  508.85 + * master pointer --> 0         master pointer --> 0
  508.86 + *                    1                            1
  508.87 + *                   ...                          ...
  508.88 + *                   M-3                          M-3
  508.89 + *                   M-2                           M
  508.90 + *                   M-1                          M+1
  508.91 + *                    M                           M-2
  508.92 + *                   M+1                          M-1
  508.93 + *                    0                            0
  508.94 + * We read alternate iMCU rows using each master pointer; thus the last two
  508.95 + * row groups of the previous iMCU row remain un-overwritten in the workspace.
  508.96 + * The pointer lists are set up so that the required context rows appear to
  508.97 + * be adjacent to the proper places when we pass the pointer lists to the
  508.98 + * upsampler.
  508.99 + *
 508.100 + * The above pictures describe the normal state of the pointer lists.
 508.101 + * At top and bottom of the image, we diddle the pointer lists to duplicate
 508.102 + * the first or last sample row as necessary (this is cheaper than copying
 508.103 + * sample rows around).
 508.104 + *
 508.105 + * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1.  In that
 508.106 + * situation each iMCU row provides only one row group so the buffering logic
 508.107 + * must be different (eg, we must read two iMCU rows before we can emit the
 508.108 + * first row group).  For now, we simply do not support providing context
 508.109 + * rows when min_DCT_scaled_size is 1.  That combination seems unlikely to
 508.110 + * be worth providing --- if someone wants a 1/8th-size preview, they probably
 508.111 + * want it quick and dirty, so a context-free upsampler is sufficient.
 508.112 + */
 508.113 +
 508.114 +
 508.115 +/* Private buffer controller object */
 508.116 +
 508.117 +typedef struct {
 508.118 +  struct jpeg_d_main_controller pub; /* public fields */
 508.119 +
 508.120 +  /* Pointer to allocated workspace (M or M+2 row groups). */
 508.121 +  JSAMPARRAY buffer[MAX_COMPONENTS];
 508.122 +
 508.123 +  boolean buffer_full;		/* Have we gotten an iMCU row from decoder? */
 508.124 +  JDIMENSION rowgroup_ctr;	/* counts row groups output to postprocessor */
 508.125 +
 508.126 +  /* Remaining fields are only used in the context case. */
 508.127 +
 508.128 +  /* These are the master pointers to the funny-order pointer lists. */
 508.129 +  JSAMPIMAGE xbuffer[2];	/* pointers to weird pointer lists */
 508.130 +
 508.131 +  int whichptr;			/* indicates which pointer set is now in use */
 508.132 +  int context_state;		/* process_data state machine status */
 508.133 +  JDIMENSION rowgroups_avail;	/* row groups available to postprocessor */
 508.134 +  JDIMENSION iMCU_row_ctr;	/* counts iMCU rows to detect image top/bot */
 508.135 +} my_main_controller;
 508.136 +
 508.137 +typedef my_main_controller * my_main_ptr;
 508.138 +
 508.139 +/* context_state values: */
 508.140 +#define CTX_PREPARE_FOR_IMCU	0	/* need to prepare for MCU row */
 508.141 +#define CTX_PROCESS_IMCU	1	/* feeding iMCU to postprocessor */
 508.142 +#define CTX_POSTPONED_ROW	2	/* feeding postponed row group */
 508.143 +
 508.144 +
 508.145 +/* Forward declarations */
 508.146 +METHODDEF(void) process_data_simple_main
 508.147 +	JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
 508.148 +	     JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
 508.149 +METHODDEF(void) process_data_context_main
 508.150 +	JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
 508.151 +	     JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
 508.152 +#ifdef QUANT_2PASS_SUPPORTED
 508.153 +METHODDEF(void) process_data_crank_post
 508.154 +	JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
 508.155 +	     JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
 508.156 +#endif
 508.157 +
 508.158 +
 508.159 +LOCAL(void)
 508.160 +alloc_funny_pointers (j_decompress_ptr cinfo)
 508.161 +/* Allocate space for the funny pointer lists.
 508.162 + * This is done only once, not once per pass.
 508.163 + */
 508.164 +{
 508.165 +  my_main_ptr main = (my_main_ptr) cinfo->main;
 508.166 +  int ci, rgroup;
 508.167 +  int M = cinfo->min_DCT_scaled_size;
 508.168 +  jpeg_component_info *compptr;
 508.169 +  JSAMPARRAY xbuf;
 508.170 +
 508.171 +  /* Get top-level space for component array pointers.
 508.172 +   * We alloc both arrays with one call to save a few cycles.
 508.173 +   */
 508.174 +  main->xbuffer[0] = (JSAMPIMAGE)
 508.175 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 508.176 +				cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
 508.177 +  main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components;
 508.178 +
 508.179 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 508.180 +       ci++, compptr++) {
 508.181 +    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
 508.182 +      cinfo->min_DCT_scaled_size; /* height of a row group of component */
 508.183 +    /* Get space for pointer lists --- M+4 row groups in each list.
 508.184 +     * We alloc both pointer lists with one call to save a few cycles.
 508.185 +     */
 508.186 +    xbuf = (JSAMPARRAY)
 508.187 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 508.188 +				  2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
 508.189 +    xbuf += rgroup;		/* want one row group at negative offsets */
 508.190 +    main->xbuffer[0][ci] = xbuf;
 508.191 +    xbuf += rgroup * (M + 4);
 508.192 +    main->xbuffer[1][ci] = xbuf;
 508.193 +  }
 508.194 +}
 508.195 +
 508.196 +
 508.197 +LOCAL(void)
 508.198 +make_funny_pointers (j_decompress_ptr cinfo)
 508.199 +/* Create the funny pointer lists discussed in the comments above.
 508.200 + * The actual workspace is already allocated (in main->buffer),
 508.201 + * and the space for the pointer lists is allocated too.
 508.202 + * This routine just fills in the curiously ordered lists.
 508.203 + * This will be repeated at the beginning of each pass.
 508.204 + */
 508.205 +{
 508.206 +  my_main_ptr main = (my_main_ptr) cinfo->main;
 508.207 +  int ci, i, rgroup;
 508.208 +  int M = cinfo->min_DCT_scaled_size;
 508.209 +  jpeg_component_info *compptr;
 508.210 +  JSAMPARRAY buf, xbuf0, xbuf1;
 508.211 +
 508.212 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 508.213 +       ci++, compptr++) {
 508.214 +    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
 508.215 +      cinfo->min_DCT_scaled_size; /* height of a row group of component */
 508.216 +    xbuf0 = main->xbuffer[0][ci];
 508.217 +    xbuf1 = main->xbuffer[1][ci];
 508.218 +    /* First copy the workspace pointers as-is */
 508.219 +    buf = main->buffer[ci];
 508.220 +    for (i = 0; i < rgroup * (M + 2); i++) {
 508.221 +      xbuf0[i] = xbuf1[i] = buf[i];
 508.222 +    }
 508.223 +    /* In the second list, put the last four row groups in swapped order */
 508.224 +    for (i = 0; i < rgroup * 2; i++) {
 508.225 +      xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
 508.226 +      xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
 508.227 +    }
 508.228 +    /* The wraparound pointers at top and bottom will be filled later
 508.229 +     * (see set_wraparound_pointers, below).  Initially we want the "above"
 508.230 +     * pointers to duplicate the first actual data line.  This only needs
 508.231 +     * to happen in xbuffer[0].
 508.232 +     */
 508.233 +    for (i = 0; i < rgroup; i++) {
 508.234 +      xbuf0[i - rgroup] = xbuf0[0];
 508.235 +    }
 508.236 +  }
 508.237 +}
 508.238 +
 508.239 +
 508.240 +LOCAL(void)
 508.241 +set_wraparound_pointers (j_decompress_ptr cinfo)
 508.242 +/* Set up the "wraparound" pointers at top and bottom of the pointer lists.
 508.243 + * This changes the pointer list state from top-of-image to the normal state.
 508.244 + */
 508.245 +{
 508.246 +  my_main_ptr main = (my_main_ptr) cinfo->main;
 508.247 +  int ci, i, rgroup;
 508.248 +  int M = cinfo->min_DCT_scaled_size;
 508.249 +  jpeg_component_info *compptr;
 508.250 +  JSAMPARRAY xbuf0, xbuf1;
 508.251 +
 508.252 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 508.253 +       ci++, compptr++) {
 508.254 +    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
 508.255 +      cinfo->min_DCT_scaled_size; /* height of a row group of component */
 508.256 +    xbuf0 = main->xbuffer[0][ci];
 508.257 +    xbuf1 = main->xbuffer[1][ci];
 508.258 +    for (i = 0; i < rgroup; i++) {
 508.259 +      xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
 508.260 +      xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
 508.261 +      xbuf0[rgroup*(M+2) + i] = xbuf0[i];
 508.262 +      xbuf1[rgroup*(M+2) + i] = xbuf1[i];
 508.263 +    }
 508.264 +  }
 508.265 +}
 508.266 +
 508.267 +
 508.268 +LOCAL(void)
 508.269 +set_bottom_pointers (j_decompress_ptr cinfo)
 508.270 +/* Change the pointer lists to duplicate the last sample row at the bottom
 508.271 + * of the image.  whichptr indicates which xbuffer holds the final iMCU row.
 508.272 + * Also sets rowgroups_avail to indicate number of nondummy row groups in row.
 508.273 + */
 508.274 +{
 508.275 +  my_main_ptr main = (my_main_ptr) cinfo->main;
 508.276 +  int ci, i, rgroup, iMCUheight, rows_left;
 508.277 +  jpeg_component_info *compptr;
 508.278 +  JSAMPARRAY xbuf;
 508.279 +
 508.280 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 508.281 +       ci++, compptr++) {
 508.282 +    /* Count sample rows in one iMCU row and in one row group */
 508.283 +    iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;
 508.284 +    rgroup = iMCUheight / cinfo->min_DCT_scaled_size;
 508.285 +    /* Count nondummy sample rows remaining for this component */
 508.286 +    rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
 508.287 +    if (rows_left == 0) rows_left = iMCUheight;
 508.288 +    /* Count nondummy row groups.  Should get same answer for each component,
 508.289 +     * so we need only do it once.
 508.290 +     */
 508.291 +    if (ci == 0) {
 508.292 +      main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
 508.293 +    }
 508.294 +    /* Duplicate the last real sample row rgroup*2 times; this pads out the
 508.295 +     * last partial rowgroup and ensures at least one full rowgroup of context.
 508.296 +     */
 508.297 +    xbuf = main->xbuffer[main->whichptr][ci];
 508.298 +    for (i = 0; i < rgroup * 2; i++) {
 508.299 +      xbuf[rows_left + i] = xbuf[rows_left-1];
 508.300 +    }
 508.301 +  }
 508.302 +}
 508.303 +
 508.304 +
 508.305 +/*
 508.306 + * Initialize for a processing pass.
 508.307 + */
 508.308 +
 508.309 +METHODDEF(void)
 508.310 +start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
 508.311 +{
 508.312 +  my_main_ptr main = (my_main_ptr) cinfo->main;
 508.313 +
 508.314 +  switch (pass_mode) {
 508.315 +  case JBUF_PASS_THRU:
 508.316 +    if (cinfo->upsample->need_context_rows) {
 508.317 +      main->pub.process_data = process_data_context_main;
 508.318 +      make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
 508.319 +      main->whichptr = 0;	/* Read first iMCU row into xbuffer[0] */
 508.320 +      main->context_state = CTX_PREPARE_FOR_IMCU;
 508.321 +      main->iMCU_row_ctr = 0;
 508.322 +    } else {
 508.323 +      /* Simple case with no context needed */
 508.324 +      main->pub.process_data = process_data_simple_main;
 508.325 +    }
 508.326 +    main->buffer_full = FALSE;	/* Mark buffer empty */
 508.327 +    main->rowgroup_ctr = 0;
 508.328 +    break;
 508.329 +#ifdef QUANT_2PASS_SUPPORTED
 508.330 +  case JBUF_CRANK_DEST:
 508.331 +    /* For last pass of 2-pass quantization, just crank the postprocessor */
 508.332 +    main->pub.process_data = process_data_crank_post;
 508.333 +    break;
 508.334 +#endif
 508.335 +  default:
 508.336 +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 508.337 +    break;
 508.338 +  }
 508.339 +}
 508.340 +
 508.341 +
 508.342 +/*
 508.343 + * Process some data.
 508.344 + * This handles the simple case where no context is required.
 508.345 + */
 508.346 +
 508.347 +METHODDEF(void)
 508.348 +process_data_simple_main (j_decompress_ptr cinfo,
 508.349 +			  JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 508.350 +			  JDIMENSION out_rows_avail)
 508.351 +{
 508.352 +  my_main_ptr main = (my_main_ptr) cinfo->main;
 508.353 +  JDIMENSION rowgroups_avail;
 508.354 +
 508.355 +  /* Read input data if we haven't filled the main buffer yet */
 508.356 +  if (! main->buffer_full) {
 508.357 +    if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer))
 508.358 +      return;			/* suspension forced, can do nothing more */
 508.359 +    main->buffer_full = TRUE;	/* OK, we have an iMCU row to work with */
 508.360 +  }
 508.361 +
 508.362 +  /* There are always min_DCT_scaled_size row groups in an iMCU row. */
 508.363 +  rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;
 508.364 +  /* Note: at the bottom of the image, we may pass extra garbage row groups
 508.365 +   * to the postprocessor.  The postprocessor has to check for bottom
 508.366 +   * of image anyway (at row resolution), so no point in us doing it too.
 508.367 +   */
 508.368 +
 508.369 +  /* Feed the postprocessor */
 508.370 +  (*cinfo->post->post_process_data) (cinfo, main->buffer,
 508.371 +				     &main->rowgroup_ctr, rowgroups_avail,
 508.372 +				     output_buf, out_row_ctr, out_rows_avail);
 508.373 +
 508.374 +  /* Has postprocessor consumed all the data yet? If so, mark buffer empty */
 508.375 +  if (main->rowgroup_ctr >= rowgroups_avail) {
 508.376 +    main->buffer_full = FALSE;
 508.377 +    main->rowgroup_ctr = 0;
 508.378 +  }
 508.379 +}
 508.380 +
 508.381 +
 508.382 +/*
 508.383 + * Process some data.
 508.384 + * This handles the case where context rows must be provided.
 508.385 + */
 508.386 +
 508.387 +METHODDEF(void)
 508.388 +process_data_context_main (j_decompress_ptr cinfo,
 508.389 +			   JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 508.390 +			   JDIMENSION out_rows_avail)
 508.391 +{
 508.392 +  my_main_ptr main = (my_main_ptr) cinfo->main;
 508.393 +
 508.394 +  /* Read input data if we haven't filled the main buffer yet */
 508.395 +  if (! main->buffer_full) {
 508.396 +    if (! (*cinfo->coef->decompress_data) (cinfo,
 508.397 +					   main->xbuffer[main->whichptr]))
 508.398 +      return;			/* suspension forced, can do nothing more */
 508.399 +    main->buffer_full = TRUE;	/* OK, we have an iMCU row to work with */
 508.400 +    main->iMCU_row_ctr++;	/* count rows received */
 508.401 +  }
 508.402 +
 508.403 +  /* Postprocessor typically will not swallow all the input data it is handed
 508.404 +   * in one call (due to filling the output buffer first).  Must be prepared
 508.405 +   * to exit and restart.  This switch lets us keep track of how far we got.
 508.406 +   * Note that each case falls through to the next on successful completion.
 508.407 +   */
 508.408 +  switch (main->context_state) {
 508.409 +  case CTX_POSTPONED_ROW:
 508.410 +    /* Call postprocessor using previously set pointers for postponed row */
 508.411 +    (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],
 508.412 +			&main->rowgroup_ctr, main->rowgroups_avail,
 508.413 +			output_buf, out_row_ctr, out_rows_avail);
 508.414 +    if (main->rowgroup_ctr < main->rowgroups_avail)
 508.415 +      return;			/* Need to suspend */
 508.416 +    main->context_state = CTX_PREPARE_FOR_IMCU;
 508.417 +    if (*out_row_ctr >= out_rows_avail)
 508.418 +      return;			/* Postprocessor exactly filled output buf */
 508.419 +    /*FALLTHROUGH*/
 508.420 +  case CTX_PREPARE_FOR_IMCU:
 508.421 +    /* Prepare to process first M-1 row groups of this iMCU row */
 508.422 +    main->rowgroup_ctr = 0;
 508.423 +    main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
 508.424 +    /* Check for bottom of image: if so, tweak pointers to "duplicate"
 508.425 +     * the last sample row, and adjust rowgroups_avail to ignore padding rows.
 508.426 +     */
 508.427 +    if (main->iMCU_row_ctr == cinfo->total_iMCU_rows)
 508.428 +      set_bottom_pointers(cinfo);
 508.429 +    main->context_state = CTX_PROCESS_IMCU;
 508.430 +    /*FALLTHROUGH*/
 508.431 +  case CTX_PROCESS_IMCU:
 508.432 +    /* Call postprocessor using previously set pointers */
 508.433 +    (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],
 508.434 +			&main->rowgroup_ctr, main->rowgroups_avail,
 508.435 +			output_buf, out_row_ctr, out_rows_avail);
 508.436 +    if (main->rowgroup_ctr < main->rowgroups_avail)
 508.437 +      return;			/* Need to suspend */
 508.438 +    /* After the first iMCU, change wraparound pointers to normal state */
 508.439 +    if (main->iMCU_row_ctr == 1)
 508.440 +      set_wraparound_pointers(cinfo);
 508.441 +    /* Prepare to load new iMCU row using other xbuffer list */
 508.442 +    main->whichptr ^= 1;	/* 0=>1 or 1=>0 */
 508.443 +    main->buffer_full = FALSE;
 508.444 +    /* Still need to process last row group of this iMCU row, */
 508.445 +    /* which is saved at index M+1 of the other xbuffer */
 508.446 +    main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
 508.447 +    main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
 508.448 +    main->context_state = CTX_POSTPONED_ROW;
 508.449 +  }
 508.450 +}
 508.451 +
 508.452 +
 508.453 +/*
 508.454 + * Process some data.
 508.455 + * Final pass of two-pass quantization: just call the postprocessor.
 508.456 + * Source data will be the postprocessor controller's internal buffer.
 508.457 + */
 508.458 +
 508.459 +#ifdef QUANT_2PASS_SUPPORTED
 508.460 +
 508.461 +METHODDEF(void)
 508.462 +process_data_crank_post (j_decompress_ptr cinfo,
 508.463 +			 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 508.464 +			 JDIMENSION out_rows_avail)
 508.465 +{
 508.466 +  (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL,
 508.467 +				     (JDIMENSION *) NULL, (JDIMENSION) 0,
 508.468 +				     output_buf, out_row_ctr, out_rows_avail);
 508.469 +}
 508.470 +
 508.471 +#endif /* QUANT_2PASS_SUPPORTED */
 508.472 +
 508.473 +
 508.474 +/*
 508.475 + * Initialize main buffer controller.
 508.476 + */
 508.477 +
 508.478 +GLOBAL(void)
 508.479 +jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
 508.480 +{
 508.481 +  my_main_ptr main;
 508.482 +  int ci, rgroup, ngroups;
 508.483 +  jpeg_component_info *compptr;
 508.484 +
 508.485 +  main = (my_main_ptr)
 508.486 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 508.487 +				SIZEOF(my_main_controller));
 508.488 +  cinfo->main = (struct jpeg_d_main_controller *) main;
 508.489 +  main->pub.start_pass = start_pass_main;
 508.490 +
 508.491 +  if (need_full_buffer)		/* shouldn't happen */
 508.492 +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 508.493 +
 508.494 +  /* Allocate the workspace.
 508.495 +   * ngroups is the number of row groups we need.
 508.496 +   */
 508.497 +  if (cinfo->upsample->need_context_rows) {
 508.498 +    if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */
 508.499 +      ERREXIT(cinfo, JERR_NOTIMPL);
 508.500 +    alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
 508.501 +    ngroups = cinfo->min_DCT_scaled_size + 2;
 508.502 +  } else {
 508.503 +    ngroups = cinfo->min_DCT_scaled_size;
 508.504 +  }
 508.505 +
 508.506 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 508.507 +       ci++, compptr++) {
 508.508 +    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
 508.509 +      cinfo->min_DCT_scaled_size; /* height of a row group of component */
 508.510 +    main->buffer[ci] = (*cinfo->mem->alloc_sarray)
 508.511 +			((j_common_ptr) cinfo, JPOOL_IMAGE,
 508.512 +			 compptr->width_in_blocks * compptr->DCT_scaled_size,
 508.513 +			 (JDIMENSION) (rgroup * ngroups));
 508.514 +  }
 508.515 +}
   509.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   509.2 +++ b/libs/libjpeg/jdmarker.c	Sat Feb 01 19:58:19 2014 +0200
   509.3 @@ -0,0 +1,1360 @@
   509.4 +/*
   509.5 + * jdmarker.c
   509.6 + *
   509.7 + * Copyright (C) 1991-1998, Thomas G. Lane.
   509.8 + * This file is part of the Independent JPEG Group's software.
   509.9 + * For conditions of distribution and use, see the accompanying README file.
  509.10 + *
  509.11 + * This file contains routines to decode JPEG datastream markers.
  509.12 + * Most of the complexity arises from our desire to support input
  509.13 + * suspension: if not all of the data for a marker is available,
  509.14 + * we must exit back to the application.  On resumption, we reprocess
  509.15 + * the marker.
  509.16 + */
  509.17 +
  509.18 +#define JPEG_INTERNALS
  509.19 +#include "jinclude.h"
  509.20 +#include "jpeglib.h"
  509.21 +
  509.22 +
  509.23 +typedef enum {			/* JPEG marker codes */
  509.24 +  M_SOF0  = 0xc0,
  509.25 +  M_SOF1  = 0xc1,
  509.26 +  M_SOF2  = 0xc2,
  509.27 +  M_SOF3  = 0xc3,
  509.28 +  
  509.29 +  M_SOF5  = 0xc5,
  509.30 +  M_SOF6  = 0xc6,
  509.31 +  M_SOF7  = 0xc7,
  509.32 +  
  509.33 +  M_JPG   = 0xc8,
  509.34 +  M_SOF9  = 0xc9,
  509.35 +  M_SOF10 = 0xca,
  509.36 +  M_SOF11 = 0xcb,
  509.37 +  
  509.38 +  M_SOF13 = 0xcd,
  509.39 +  M_SOF14 = 0xce,
  509.40 +  M_SOF15 = 0xcf,
  509.41 +  
  509.42 +  M_DHT   = 0xc4,
  509.43 +  
  509.44 +  M_DAC   = 0xcc,
  509.45 +  
  509.46 +  M_RST0  = 0xd0,
  509.47 +  M_RST1  = 0xd1,
  509.48 +  M_RST2  = 0xd2,
  509.49 +  M_RST3  = 0xd3,
  509.50 +  M_RST4  = 0xd4,
  509.51 +  M_RST5  = 0xd5,
  509.52 +  M_RST6  = 0xd6,
  509.53 +  M_RST7  = 0xd7,
  509.54 +  
  509.55 +  M_SOI   = 0xd8,
  509.56 +  M_EOI   = 0xd9,
  509.57 +  M_SOS   = 0xda,
  509.58 +  M_DQT   = 0xdb,
  509.59 +  M_DNL   = 0xdc,
  509.60 +  M_DRI   = 0xdd,
  509.61 +  M_DHP   = 0xde,
  509.62 +  M_EXP   = 0xdf,
  509.63 +  
  509.64 +  M_APP0  = 0xe0,
  509.65 +  M_APP1  = 0xe1,
  509.66 +  M_APP2  = 0xe2,
  509.67 +  M_APP3  = 0xe3,
  509.68 +  M_APP4  = 0xe4,
  509.69 +  M_APP5  = 0xe5,
  509.70 +  M_APP6  = 0xe6,
  509.71 +  M_APP7  = 0xe7,
  509.72 +  M_APP8  = 0xe8,
  509.73 +  M_APP9  = 0xe9,
  509.74 +  M_APP10 = 0xea,
  509.75 +  M_APP11 = 0xeb,
  509.76 +  M_APP12 = 0xec,
  509.77 +  M_APP13 = 0xed,
  509.78 +  M_APP14 = 0xee,
  509.79 +  M_APP15 = 0xef,
  509.80 +  
  509.81 +  M_JPG0  = 0xf0,
  509.82 +  M_JPG13 = 0xfd,
  509.83 +  M_COM   = 0xfe,
  509.84 +  
  509.85 +  M_TEM   = 0x01,
  509.86 +  
  509.87 +  M_ERROR = 0x100
  509.88 +} JPEG_MARKER;
  509.89 +
  509.90 +
  509.91 +/* Private state */
  509.92 +
  509.93 +typedef struct {
  509.94 +  struct jpeg_marker_reader pub; /* public fields */
  509.95 +
  509.96 +  /* Application-overridable marker processing methods */
  509.97 +  jpeg_marker_parser_method process_COM;
  509.98 +  jpeg_marker_parser_method process_APPn[16];
  509.99 +
 509.100 +  /* Limit on marker data length to save for each marker type */
 509.101 +  unsigned int length_limit_COM;
 509.102 +  unsigned int length_limit_APPn[16];
 509.103 +
 509.104 +  /* Status of COM/APPn marker saving */
 509.105 +  jpeg_saved_marker_ptr cur_marker;	/* NULL if not processing a marker */
 509.106 +  unsigned int bytes_read;		/* data bytes read so far in marker */
 509.107 +  /* Note: cur_marker is not linked into marker_list until it's all read. */
 509.108 +} my_marker_reader;
 509.109 +
 509.110 +typedef my_marker_reader * my_marker_ptr;
 509.111 +
 509.112 +
 509.113 +/*
 509.114 + * Macros for fetching data from the data source module.
 509.115 + *
 509.116 + * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect
 509.117 + * the current restart point; we update them only when we have reached a
 509.118 + * suitable place to restart if a suspension occurs.
 509.119 + */
 509.120 +
 509.121 +/* Declare and initialize local copies of input pointer/count */
 509.122 +#define INPUT_VARS(cinfo)  \
 509.123 +	struct jpeg_source_mgr * datasrc = (cinfo)->src;  \
 509.124 +	const JOCTET * next_input_byte = datasrc->next_input_byte;  \
 509.125 +	size_t bytes_in_buffer = datasrc->bytes_in_buffer
 509.126 +
 509.127 +/* Unload the local copies --- do this only at a restart boundary */
 509.128 +#define INPUT_SYNC(cinfo)  \
 509.129 +	( datasrc->next_input_byte = next_input_byte,  \
 509.130 +	  datasrc->bytes_in_buffer = bytes_in_buffer )
 509.131 +
 509.132 +/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
 509.133 +#define INPUT_RELOAD(cinfo)  \
 509.134 +	( next_input_byte = datasrc->next_input_byte,  \
 509.135 +	  bytes_in_buffer = datasrc->bytes_in_buffer )
 509.136 +
 509.137 +/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
 509.138 + * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
 509.139 + * but we must reload the local copies after a successful fill.
 509.140 + */
 509.141 +#define MAKE_BYTE_AVAIL(cinfo,action)  \
 509.142 +	if (bytes_in_buffer == 0) {  \
 509.143 +	  if (! (*datasrc->fill_input_buffer) (cinfo))  \
 509.144 +	    { action; }  \
 509.145 +	  INPUT_RELOAD(cinfo);  \
 509.146 +	}
 509.147 +
 509.148 +/* Read a byte into variable V.
 509.149 + * If must suspend, take the specified action (typically "return FALSE").
 509.150 + */
 509.151 +#define INPUT_BYTE(cinfo,V,action)  \
 509.152 +	MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
 509.153 +		  bytes_in_buffer--; \
 509.154 +		  V = GETJOCTET(*next_input_byte++); )
 509.155 +
 509.156 +/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
 509.157 + * V should be declared unsigned int or perhaps INT32.
 509.158 + */
 509.159 +#define INPUT_2BYTES(cinfo,V,action)  \
 509.160 +	MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
 509.161 +		  bytes_in_buffer--; \
 509.162 +		  V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
 509.163 +		  MAKE_BYTE_AVAIL(cinfo,action); \
 509.164 +		  bytes_in_buffer--; \
 509.165 +		  V += GETJOCTET(*next_input_byte++); )
 509.166 +
 509.167 +
 509.168 +/*
 509.169 + * Routines to process JPEG markers.
 509.170 + *
 509.171 + * Entry condition: JPEG marker itself has been read and its code saved
 509.172 + *   in cinfo->unread_marker; input restart point is just after the marker.
 509.173 + *
 509.174 + * Exit: if return TRUE, have read and processed any parameters, and have
 509.175 + *   updated the restart point to point after the parameters.
 509.176 + *   If return FALSE, was forced to suspend before reaching end of
 509.177 + *   marker parameters; restart point has not been moved.  Same routine
 509.178 + *   will be called again after application supplies more input data.
 509.179 + *
 509.180 + * This approach to suspension assumes that all of a marker's parameters
 509.181 + * can fit into a single input bufferload.  This should hold for "normal"
 509.182 + * markers.  Some COM/APPn markers might have large parameter segments
 509.183 + * that might not fit.  If we are simply dropping such a marker, we use
 509.184 + * skip_input_data to get past it, and thereby put the problem on the
 509.185 + * source manager's shoulders.  If we are saving the marker's contents
 509.186 + * into memory, we use a slightly different convention: when forced to
 509.187 + * suspend, the marker processor updates the restart point to the end of
 509.188 + * what it's consumed (ie, the end of the buffer) before returning FALSE.
 509.189 + * On resumption, cinfo->unread_marker still contains the marker code,
 509.190 + * but the data source will point to the next chunk of marker data.
 509.191 + * The marker processor must retain internal state to deal with this.
 509.192 + *
 509.193 + * Note that we don't bother to avoid duplicate trace messages if a
 509.194 + * suspension occurs within marker parameters.  Other side effects
 509.195 + * require more care.
 509.196 + */
 509.197 +
 509.198 +
 509.199 +LOCAL(boolean)
 509.200 +get_soi (j_decompress_ptr cinfo)
 509.201 +/* Process an SOI marker */
 509.202 +{
 509.203 +  int i;
 509.204 +  
 509.205 +  TRACEMS(cinfo, 1, JTRC_SOI);
 509.206 +
 509.207 +  if (cinfo->marker->saw_SOI)
 509.208 +    ERREXIT(cinfo, JERR_SOI_DUPLICATE);
 509.209 +
 509.210 +  /* Reset all parameters that are defined to be reset by SOI */
 509.211 +
 509.212 +  for (i = 0; i < NUM_ARITH_TBLS; i++) {
 509.213 +    cinfo->arith_dc_L[i] = 0;
 509.214 +    cinfo->arith_dc_U[i] = 1;
 509.215 +    cinfo->arith_ac_K[i] = 5;
 509.216 +  }
 509.217 +  cinfo->restart_interval = 0;
 509.218 +
 509.219 +  /* Set initial assumptions for colorspace etc */
 509.220 +
 509.221 +  cinfo->jpeg_color_space = JCS_UNKNOWN;
 509.222 +  cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
 509.223 +
 509.224 +  cinfo->saw_JFIF_marker = FALSE;
 509.225 +  cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
 509.226 +  cinfo->JFIF_minor_version = 1;
 509.227 +  cinfo->density_unit = 0;
 509.228 +  cinfo->X_density = 1;
 509.229 +  cinfo->Y_density = 1;
 509.230 +  cinfo->saw_Adobe_marker = FALSE;
 509.231 +  cinfo->Adobe_transform = 0;
 509.232 +
 509.233 +  cinfo->marker->saw_SOI = TRUE;
 509.234 +
 509.235 +  return TRUE;
 509.236 +}
 509.237 +
 509.238 +
 509.239 +LOCAL(boolean)
 509.240 +get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
 509.241 +/* Process a SOFn marker */
 509.242 +{
 509.243 +  INT32 length;
 509.244 +  int c, ci;
 509.245 +  jpeg_component_info * compptr;
 509.246 +  INPUT_VARS(cinfo);
 509.247 +
 509.248 +  cinfo->progressive_mode = is_prog;
 509.249 +  cinfo->arith_code = is_arith;
 509.250 +
 509.251 +  INPUT_2BYTES(cinfo, length, return FALSE);
 509.252 +
 509.253 +  INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
 509.254 +  INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
 509.255 +  INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
 509.256 +  INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
 509.257 +
 509.258 +  length -= 8;
 509.259 +
 509.260 +  TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
 509.261 +	   (int) cinfo->image_width, (int) cinfo->image_height,
 509.262 +	   cinfo->num_components);
 509.263 +
 509.264 +  if (cinfo->marker->saw_SOF)
 509.265 +    ERREXIT(cinfo, JERR_SOF_DUPLICATE);
 509.266 +
 509.267 +  /* We don't support files in which the image height is initially specified */
 509.268 +  /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
 509.269 +  /* might as well have a general sanity check. */
 509.270 +  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
 509.271 +      || cinfo->num_components <= 0)
 509.272 +    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
 509.273 +
 509.274 +  if (length != (cinfo->num_components * 3))
 509.275 +    ERREXIT(cinfo, JERR_BAD_LENGTH);
 509.276 +
 509.277 +  if (cinfo->comp_info == NULL)	/* do only once, even if suspend */
 509.278 +    cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
 509.279 +			((j_common_ptr) cinfo, JPOOL_IMAGE,
 509.280 +			 cinfo->num_components * SIZEOF(jpeg_component_info));
 509.281 +  
 509.282 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 509.283 +       ci++, compptr++) {
 509.284 +    compptr->component_index = ci;
 509.285 +    INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
 509.286 +    INPUT_BYTE(cinfo, c, return FALSE);
 509.287 +    compptr->h_samp_factor = (c >> 4) & 15;
 509.288 +    compptr->v_samp_factor = (c     ) & 15;
 509.289 +    INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
 509.290 +
 509.291 +    TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
 509.292 +	     compptr->component_id, compptr->h_samp_factor,
 509.293 +	     compptr->v_samp_factor, compptr->quant_tbl_no);
 509.294 +  }
 509.295 +
 509.296 +  cinfo->marker->saw_SOF = TRUE;
 509.297 +
 509.298 +  INPUT_SYNC(cinfo);
 509.299 +  return TRUE;
 509.300 +}
 509.301 +
 509.302 +
 509.303 +LOCAL(boolean)
 509.304 +get_sos (j_decompress_ptr cinfo)
 509.305 +/* Process a SOS marker */
 509.306 +{
 509.307 +  INT32 length;
 509.308 +  int i, ci, n, c, cc;
 509.309 +  jpeg_component_info * compptr;
 509.310 +  INPUT_VARS(cinfo);
 509.311 +
 509.312 +  if (! cinfo->marker->saw_SOF)
 509.313 +    ERREXIT(cinfo, JERR_SOS_NO_SOF);
 509.314 +
 509.315 +  INPUT_2BYTES(cinfo, length, return FALSE);
 509.316 +
 509.317 +  INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
 509.318 +
 509.319 +  TRACEMS1(cinfo, 1, JTRC_SOS, n);
 509.320 +
 509.321 +  if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
 509.322 +    ERREXIT(cinfo, JERR_BAD_LENGTH);
 509.323 +
 509.324 +  cinfo->comps_in_scan = n;
 509.325 +
 509.326 +  /* Collect the component-spec parameters */
 509.327 +
 509.328 +  for (i = 0; i < n; i++) {
 509.329 +    INPUT_BYTE(cinfo, cc, return FALSE);
 509.330 +    INPUT_BYTE(cinfo, c, return FALSE);
 509.331 +    
 509.332 +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 509.333 +	 ci++, compptr++) {
 509.334 +      if (cc == compptr->component_id)
 509.335 +	goto id_found;
 509.336 +    }
 509.337 +
 509.338 +    ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
 509.339 +
 509.340 +  id_found:
 509.341 +
 509.342 +    cinfo->cur_comp_info[i] = compptr;
 509.343 +    compptr->dc_tbl_no = (c >> 4) & 15;
 509.344 +    compptr->ac_tbl_no = (c     ) & 15;
 509.345 +    
 509.346 +    TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
 509.347 +	     compptr->dc_tbl_no, compptr->ac_tbl_no);
 509.348 +  }
 509.349 +
 509.350 +  /* Collect the additional scan parameters Ss, Se, Ah/Al. */
 509.351 +  INPUT_BYTE(cinfo, c, return FALSE);
 509.352 +  cinfo->Ss = c;
 509.353 +  INPUT_BYTE(cinfo, c, return FALSE);
 509.354 +  cinfo->Se = c;
 509.355 +  INPUT_BYTE(cinfo, c, return FALSE);
 509.356 +  cinfo->Ah = (c >> 4) & 15;
 509.357 +  cinfo->Al = (c     ) & 15;
 509.358 +
 509.359 +  TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
 509.360 +	   cinfo->Ah, cinfo->Al);
 509.361 +
 509.362 +  /* Prepare to scan data & restart markers */
 509.363 +  cinfo->marker->next_restart_num = 0;
 509.364 +
 509.365 +  /* Count another SOS marker */
 509.366 +  cinfo->input_scan_number++;
 509.367 +
 509.368 +  INPUT_SYNC(cinfo);
 509.369 +  return TRUE;
 509.370 +}
 509.371 +
 509.372 +
 509.373 +#ifdef D_ARITH_CODING_SUPPORTED
 509.374 +
 509.375 +LOCAL(boolean)
 509.376 +get_dac (j_decompress_ptr cinfo)
 509.377 +/* Process a DAC marker */
 509.378 +{
 509.379 +  INT32 length;
 509.380 +  int index, val;
 509.381 +  INPUT_VARS(cinfo);
 509.382 +
 509.383 +  INPUT_2BYTES(cinfo, length, return FALSE);
 509.384 +  length -= 2;
 509.385 +  
 509.386 +  while (length > 0) {
 509.387 +    INPUT_BYTE(cinfo, index, return FALSE);
 509.388 +    INPUT_BYTE(cinfo, val, return FALSE);
 509.389 +
 509.390 +    length -= 2;
 509.391 +
 509.392 +    TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
 509.393 +
 509.394 +    if (index < 0 || index >= (2*NUM_ARITH_TBLS))
 509.395 +      ERREXIT1(cinfo, JERR_DAC_INDEX, index);
 509.396 +
 509.397 +    if (index >= NUM_ARITH_TBLS) { /* define AC table */
 509.398 +      cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
 509.399 +    } else {			/* define DC table */
 509.400 +      cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
 509.401 +      cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
 509.402 +      if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
 509.403 +	ERREXIT1(cinfo, JERR_DAC_VALUE, val);
 509.404 +    }
 509.405 +  }
 509.406 +
 509.407 +  if (length != 0)
 509.408 +    ERREXIT(cinfo, JERR_BAD_LENGTH);
 509.409 +
 509.410 +  INPUT_SYNC(cinfo);
 509.411 +  return TRUE;
 509.412 +}
 509.413 +
 509.414 +#else /* ! D_ARITH_CODING_SUPPORTED */
 509.415 +
 509.416 +#define get_dac(cinfo)  skip_variable(cinfo)
 509.417 +
 509.418 +#endif /* D_ARITH_CODING_SUPPORTED */
 509.419 +
 509.420 +
 509.421 +LOCAL(boolean)
 509.422 +get_dht (j_decompress_ptr cinfo)
 509.423 +/* Process a DHT marker */
 509.424 +{
 509.425 +  INT32 length;
 509.426 +  UINT8 bits[17];
 509.427 +  UINT8 huffval[256];
 509.428 +  int i, index, count;
 509.429 +  JHUFF_TBL **htblptr;
 509.430 +  INPUT_VARS(cinfo);
 509.431 +
 509.432 +  INPUT_2BYTES(cinfo, length, return FALSE);
 509.433 +  length -= 2;
 509.434 +  
 509.435 +  while (length > 16) {
 509.436 +    INPUT_BYTE(cinfo, index, return FALSE);
 509.437 +
 509.438 +    TRACEMS1(cinfo, 1, JTRC_DHT, index);
 509.439 +      
 509.440 +    bits[0] = 0;
 509.441 +    count = 0;
 509.442 +    for (i = 1; i <= 16; i++) {
 509.443 +      INPUT_BYTE(cinfo, bits[i], return FALSE);
 509.444 +      count += bits[i];
 509.445 +    }
 509.446 +
 509.447 +    length -= 1 + 16;
 509.448 +
 509.449 +    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
 509.450 +	     bits[1], bits[2], bits[3], bits[4],
 509.451 +	     bits[5], bits[6], bits[7], bits[8]);
 509.452 +    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
 509.453 +	     bits[9], bits[10], bits[11], bits[12],
 509.454 +	     bits[13], bits[14], bits[15], bits[16]);
 509.455 +
 509.456 +    /* Here we just do minimal validation of the counts to avoid walking
 509.457 +     * off the end of our table space.  jdhuff.c will check more carefully.
 509.458 +     */
 509.459 +    if (count > 256 || ((INT32) count) > length)
 509.460 +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 509.461 +
 509.462 +    for (i = 0; i < count; i++)
 509.463 +      INPUT_BYTE(cinfo, huffval[i], return FALSE);
 509.464 +
 509.465 +    length -= count;
 509.466 +
 509.467 +    if (index & 0x10) {		/* AC table definition */
 509.468 +      index -= 0x10;
 509.469 +      htblptr = &cinfo->ac_huff_tbl_ptrs[index];
 509.470 +    } else {			/* DC table definition */
 509.471 +      htblptr = &cinfo->dc_huff_tbl_ptrs[index];
 509.472 +    }
 509.473 +
 509.474 +    if (index < 0 || index >= NUM_HUFF_TBLS)
 509.475 +      ERREXIT1(cinfo, JERR_DHT_INDEX, index);
 509.476 +
 509.477 +    if (*htblptr == NULL)
 509.478 +      *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
 509.479 +  
 509.480 +    MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
 509.481 +    MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
 509.482 +  }
 509.483 +
 509.484 +  if (length != 0)
 509.485 +    ERREXIT(cinfo, JERR_BAD_LENGTH);
 509.486 +
 509.487 +  INPUT_SYNC(cinfo);
 509.488 +  return TRUE;
 509.489 +}
 509.490 +
 509.491 +
 509.492 +LOCAL(boolean)
 509.493 +get_dqt (j_decompress_ptr cinfo)
 509.494 +/* Process a DQT marker */
 509.495 +{
 509.496 +  INT32 length;
 509.497 +  int n, i, prec;
 509.498 +  unsigned int tmp;
 509.499 +  JQUANT_TBL *quant_ptr;
 509.500 +  INPUT_VARS(cinfo);
 509.501 +
 509.502 +  INPUT_2BYTES(cinfo, length, return FALSE);
 509.503 +  length -= 2;
 509.504 +
 509.505 +  while (length > 0) {
 509.506 +    INPUT_BYTE(cinfo, n, return FALSE);
 509.507 +    prec = n >> 4;
 509.508 +    n &= 0x0F;
 509.509 +
 509.510 +    TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
 509.511 +
 509.512 +    if (n >= NUM_QUANT_TBLS)
 509.513 +      ERREXIT1(cinfo, JERR_DQT_INDEX, n);
 509.514 +      
 509.515 +    if (cinfo->quant_tbl_ptrs[n] == NULL)
 509.516 +      cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
 509.517 +    quant_ptr = cinfo->quant_tbl_ptrs[n];
 509.518 +
 509.519 +    for (i = 0; i < DCTSIZE2; i++) {
 509.520 +      if (prec)
 509.521 +	INPUT_2BYTES(cinfo, tmp, return FALSE);
 509.522 +      else
 509.523 +	INPUT_BYTE(cinfo, tmp, return FALSE);
 509.524 +      /* We convert the zigzag-order table to natural array order. */
 509.525 +      quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
 509.526 +    }
 509.527 +
 509.528 +    if (cinfo->err->trace_level >= 2) {
 509.529 +      for (i = 0; i < DCTSIZE2; i += 8) {
 509.530 +	TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
 509.531 +		 quant_ptr->quantval[i],   quant_ptr->quantval[i+1],
 509.532 +		 quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
 509.533 +		 quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
 509.534 +		 quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
 509.535 +      }
 509.536 +    }
 509.537 +
 509.538 +    length -= DCTSIZE2+1;
 509.539 +    if (prec) length -= DCTSIZE2;
 509.540 +  }
 509.541 +
 509.542 +  if (length != 0)
 509.543 +    ERREXIT(cinfo, JERR_BAD_LENGTH);
 509.544 +
 509.545 +  INPUT_SYNC(cinfo);
 509.546 +  return TRUE;
 509.547 +}
 509.548 +
 509.549 +
 509.550 +LOCAL(boolean)
 509.551 +get_dri (j_decompress_ptr cinfo)
 509.552 +/* Process a DRI marker */
 509.553 +{
 509.554 +  INT32 length;
 509.555 +  unsigned int tmp;
 509.556 +  INPUT_VARS(cinfo);
 509.557 +
 509.558 +  INPUT_2BYTES(cinfo, length, return FALSE);
 509.559 +  
 509.560 +  if (length != 4)
 509.561 +    ERREXIT(cinfo, JERR_BAD_LENGTH);
 509.562 +
 509.563 +  INPUT_2BYTES(cinfo, tmp, return FALSE);
 509.564 +
 509.565 +  TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
 509.566 +
 509.567 +  cinfo->restart_interval = tmp;
 509.568 +
 509.569 +  INPUT_SYNC(cinfo);
 509.570 +  return TRUE;
 509.571 +}
 509.572 +
 509.573 +
 509.574 +/*
 509.575 + * Routines for processing APPn and COM markers.
 509.576 + * These are either saved in memory or discarded, per application request.
 509.577 + * APP0 and APP14 are specially checked to see if they are
 509.578 + * JFIF and Adobe markers, respectively.
 509.579 + */
 509.580 +
 509.581 +#define APP0_DATA_LEN	14	/* Length of interesting data in APP0 */
 509.582 +#define APP14_DATA_LEN	12	/* Length of interesting data in APP14 */
 509.583 +#define APPN_DATA_LEN	14	/* Must be the largest of the above!! */
 509.584 +
 509.585 +
 509.586 +LOCAL(void)
 509.587 +examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
 509.588 +	      unsigned int datalen, INT32 remaining)
 509.589 +/* Examine first few bytes from an APP0.
 509.590 + * Take appropriate action if it is a JFIF marker.
 509.591 + * datalen is # of bytes at data[], remaining is length of rest of marker data.
 509.592 + */
 509.593 +{
 509.594 +  INT32 totallen = (INT32) datalen + remaining;
 509.595 +
 509.596 +  if (datalen >= APP0_DATA_LEN &&
 509.597 +      GETJOCTET(data[0]) == 0x4A &&
 509.598 +      GETJOCTET(data[1]) == 0x46 &&
 509.599 +      GETJOCTET(data[2]) == 0x49 &&
 509.600 +      GETJOCTET(data[3]) == 0x46 &&
 509.601 +      GETJOCTET(data[4]) == 0) {
 509.602 +    /* Found JFIF APP0 marker: save info */
 509.603 +    cinfo->saw_JFIF_marker = TRUE;
 509.604 +    cinfo->JFIF_major_version = GETJOCTET(data[5]);
 509.605 +    cinfo->JFIF_minor_version = GETJOCTET(data[6]);
 509.606 +    cinfo->density_unit = GETJOCTET(data[7]);
 509.607 +    cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
 509.608 +    cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
 509.609 +    /* Check version.
 509.610 +     * Major version must be 1, anything else signals an incompatible change.
 509.611 +     * (We used to treat this as an error, but now it's a nonfatal warning,
 509.612 +     * because some bozo at Hijaak couldn't read the spec.)
 509.613 +     * Minor version should be 0..2, but process anyway if newer.
 509.614 +     */
 509.615 +    if (cinfo->JFIF_major_version != 1)
 509.616 +      WARNMS2(cinfo, JWRN_JFIF_MAJOR,
 509.617 +	      cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
 509.618 +    /* Generate trace messages */
 509.619 +    TRACEMS5(cinfo, 1, JTRC_JFIF,
 509.620 +	     cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
 509.621 +	     cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
 509.622 +    /* Validate thumbnail dimensions and issue appropriate messages */
 509.623 +    if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
 509.624 +      TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
 509.625 +	       GETJOCTET(data[12]), GETJOCTET(data[13]));
 509.626 +    totallen -= APP0_DATA_LEN;
 509.627 +    if (totallen !=
 509.628 +	((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
 509.629 +      TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
 509.630 +  } else if (datalen >= 6 &&
 509.631 +      GETJOCTET(data[0]) == 0x4A &&
 509.632 +      GETJOCTET(data[1]) == 0x46 &&
 509.633 +      GETJOCTET(data[2]) == 0x58 &&
 509.634 +      GETJOCTET(data[3]) == 0x58 &&
 509.635 +      GETJOCTET(data[4]) == 0) {
 509.636 +    /* Found JFIF "JFXX" extension APP0 marker */
 509.637 +    /* The library doesn't actually do anything with these,
 509.638 +     * but we try to produce a helpful trace message.
 509.639 +     */
 509.640 +    switch (GETJOCTET(data[5])) {
 509.641 +    case 0x10:
 509.642 +      TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
 509.643 +      break;
 509.644 +    case 0x11:
 509.645 +      TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
 509.646 +      break;
 509.647 +    case 0x13:
 509.648 +      TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
 509.649 +      break;
 509.650 +    default:
 509.651 +      TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
 509.652 +	       GETJOCTET(data[5]), (int) totallen);
 509.653 +      break;
 509.654 +    }
 509.655 +  } else {
 509.656 +    /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
 509.657 +    TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
 509.658 +  }
 509.659 +}
 509.660 +
 509.661 +
 509.662 +LOCAL(void)
 509.663 +examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
 509.664 +	       unsigned int datalen, INT32 remaining)
 509.665 +/* Examine first few bytes from an APP14.
 509.666 + * Take appropriate action if it is an Adobe marker.
 509.667 + * datalen is # of bytes at data[], remaining is length of rest of marker data.
 509.668 + */
 509.669 +{
 509.670 +  unsigned int version, flags0, flags1, transform;
 509.671 +
 509.672 +  if (datalen >= APP14_DATA_LEN &&
 509.673 +      GETJOCTET(data[0]) == 0x41 &&
 509.674 +      GETJOCTET(data[1]) == 0x64 &&
 509.675 +      GETJOCTET(data[2]) == 0x6F &&
 509.676 +      GETJOCTET(data[3]) == 0x62 &&
 509.677 +      GETJOCTET(data[4]) == 0x65) {
 509.678 +    /* Found Adobe APP14 marker */
 509.679 +    version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
 509.680 +    flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
 509.681 +    flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
 509.682 +    transform = GETJOCTET(data[11]);
 509.683 +    TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
 509.684 +    cinfo->saw_Adobe_marker = TRUE;
 509.685 +    cinfo->Adobe_transform = (UINT8) transform;
 509.686 +  } else {
 509.687 +    /* Start of APP14 does not match "Adobe", or too short */
 509.688 +    TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
 509.689 +  }
 509.690 +}
 509.691 +
 509.692 +
 509.693 +METHODDEF(boolean)
 509.694 +get_interesting_appn (j_decompress_ptr cinfo)
 509.695 +/* Process an APP0 or APP14 marker without saving it */
 509.696 +{
 509.697 +  INT32 length;
 509.698 +  JOCTET b[APPN_DATA_LEN];
 509.699 +  unsigned int i, numtoread;
 509.700 +  INPUT_VARS(cinfo);
 509.701 +
 509.702 +  INPUT_2BYTES(cinfo, length, return FALSE);
 509.703 +  length -= 2;
 509.704 +
 509.705 +  /* get the interesting part of the marker data */
 509.706 +  if (length >= APPN_DATA_LEN)
 509.707 +    numtoread = APPN_DATA_LEN;
 509.708 +  else if (length > 0)
 509.709 +    numtoread = (unsigned int) length;
 509.710 +  else
 509.711 +    numtoread = 0;
 509.712 +  for (i = 0; i < numtoread; i++)
 509.713 +    INPUT_BYTE(cinfo, b[i], return FALSE);
 509.714 +  length -= numtoread;
 509.715 +
 509.716 +  /* process it */
 509.717 +  switch (cinfo->unread_marker) {
 509.718 +  case M_APP0:
 509.719 +    examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
 509.720 +    break;
 509.721 +  case M_APP14:
 509.722 +    examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
 509.723 +    break;
 509.724 +  default:
 509.725 +    /* can't get here unless jpeg_save_markers chooses wrong processor */
 509.726 +    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
 509.727 +    break;
 509.728 +  }
 509.729 +
 509.730 +  /* skip any remaining data -- could be lots */
 509.731 +  INPUT_SYNC(cinfo);
 509.732 +  if (length > 0)
 509.733 +    (*cinfo->src->skip_input_data) (cinfo, (long) length);
 509.734 +
 509.735 +  return TRUE;
 509.736 +}
 509.737 +
 509.738 +
 509.739 +#ifdef SAVE_MARKERS_SUPPORTED
 509.740 +
 509.741 +METHODDEF(boolean)
 509.742 +save_marker (j_decompress_ptr cinfo)
 509.743 +/* Save an APPn or COM marker into the marker list */
 509.744 +{
 509.745 +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
 509.746 +  jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
 509.747 +  unsigned int bytes_read, data_length;
 509.748 +  JOCTET FAR * data;
 509.749 +  INT32 length = 0;
 509.750 +  INPUT_VARS(cinfo);
 509.751 +
 509.752 +  if (cur_marker == NULL) {
 509.753 +    /* begin reading a marker */
 509.754 +    INPUT_2BYTES(cinfo, length, return FALSE);
 509.755 +    length -= 2;
 509.756 +    if (length >= 0) {		/* watch out for bogus length word */
 509.757 +      /* figure out how much we want to save */
 509.758 +      unsigned int limit;
 509.759 +      if (cinfo->unread_marker == (int) M_COM)
 509.760 +	limit = marker->length_limit_COM;
 509.761 +      else
 509.762 +	limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
 509.763 +      if ((unsigned int) length < limit)
 509.764 +	limit = (unsigned int) length;
 509.765 +      /* allocate and initialize the marker item */
 509.766 +      cur_marker = (jpeg_saved_marker_ptr)
 509.767 +	(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 509.768 +				    SIZEOF(struct jpeg_marker_struct) + limit);
 509.769 +      cur_marker->next = NULL;
 509.770 +      cur_marker->marker = (UINT8) cinfo->unread_marker;
 509.771 +      cur_marker->original_length = (unsigned int) length;
 509.772 +      cur_marker->data_length = limit;
 509.773 +      /* data area is just beyond the jpeg_marker_struct */
 509.774 +      data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
 509.775 +      marker->cur_marker = cur_marker;
 509.776 +      marker->bytes_read = 0;
 509.777 +      bytes_read = 0;
 509.778 +      data_length = limit;
 509.779 +    } else {
 509.780 +      /* deal with bogus length word */
 509.781 +      bytes_read = data_length = 0;
 509.782 +      data = NULL;
 509.783 +    }
 509.784 +  } else {
 509.785 +    /* resume reading a marker */
 509.786 +    bytes_read = marker->bytes_read;
 509.787 +    data_length = cur_marker->data_length;
 509.788 +    data = cur_marker->data + bytes_read;
 509.789 +  }
 509.790 +
 509.791 +  while (bytes_read < data_length) {
 509.792 +    INPUT_SYNC(cinfo);		/* move the restart point to here */
 509.793 +    marker->bytes_read = bytes_read;
 509.794 +    /* If there's not at least one byte in buffer, suspend */
 509.795 +    MAKE_BYTE_AVAIL(cinfo, return FALSE);
 509.796 +    /* Copy bytes with reasonable rapidity */
 509.797 +    while (bytes_read < data_length && bytes_in_buffer > 0) {
 509.798 +      *data++ = *next_input_byte++;
 509.799 +      bytes_in_buffer--;
 509.800 +      bytes_read++;
 509.801 +    }
 509.802 +  }
 509.803 +
 509.804 +  /* Done reading what we want to read */
 509.805 +  if (cur_marker != NULL) {	/* will be NULL if bogus length word */
 509.806 +    /* Add new marker to end of list */
 509.807 +    if (cinfo->marker_list == NULL) {
 509.808 +      cinfo->marker_list = cur_marker;
 509.809 +    } else {
 509.810 +      jpeg_saved_marker_ptr prev = cinfo->marker_list;
 509.811 +      while (prev->next != NULL)
 509.812 +	prev = prev->next;
 509.813 +      prev->next = cur_marker;
 509.814 +    }
 509.815 +    /* Reset pointer & calc remaining data length */
 509.816 +    data = cur_marker->data;
 509.817 +    length = cur_marker->original_length - data_length;
 509.818 +  }
 509.819 +  /* Reset to initial state for next marker */
 509.820 +  marker->cur_marker = NULL;
 509.821 +
 509.822 +  /* Process the marker if interesting; else just make a generic trace msg */
 509.823 +  switch (cinfo->unread_marker) {
 509.824 +  case M_APP0:
 509.825 +    examine_app0(cinfo, data, data_length, length);
 509.826 +    break;
 509.827 +  case M_APP14:
 509.828 +    examine_app14(cinfo, data, data_length, length);
 509.829 +    break;
 509.830 +  default:
 509.831 +    TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
 509.832 +	     (int) (data_length + length));
 509.833 +    break;
 509.834 +  }
 509.835 +
 509.836 +  /* skip any remaining data -- could be lots */
 509.837 +  INPUT_SYNC(cinfo);		/* do before skip_input_data */
 509.838 +  if (length > 0)
 509.839 +    (*cinfo->src->skip_input_data) (cinfo, (long) length);
 509.840 +
 509.841 +  return TRUE;
 509.842 +}
 509.843 +
 509.844 +#endif /* SAVE_MARKERS_SUPPORTED */
 509.845 +
 509.846 +
 509.847 +METHODDEF(boolean)
 509.848 +skip_variable (j_decompress_ptr cinfo)
 509.849 +/* Skip over an unknown or uninteresting variable-length marker */
 509.850 +{
 509.851 +  INT32 length;
 509.852 +  INPUT_VARS(cinfo);
 509.853 +
 509.854 +  INPUT_2BYTES(cinfo, length, return FALSE);
 509.855 +  length -= 2;
 509.856 +  
 509.857 +  TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
 509.858 +
 509.859 +  INPUT_SYNC(cinfo);		/* do before skip_input_data */
 509.860 +  if (length > 0)
 509.861 +    (*cinfo->src->skip_input_data) (cinfo, (long) length);
 509.862 +
 509.863 +  return TRUE;
 509.864 +}
 509.865 +
 509.866 +
 509.867 +/*
 509.868 + * Find the next JPEG marker, save it in cinfo->unread_marker.
 509.869 + * Returns FALSE if had to suspend before reaching a marker;
 509.870 + * in that case cinfo->unread_marker is unchanged.
 509.871 + *
 509.872 + * Note that the result might not be a valid marker code,
 509.873 + * but it will never be 0 or FF.
 509.874 + */
 509.875 +
 509.876 +LOCAL(boolean)
 509.877 +next_marker (j_decompress_ptr cinfo)
 509.878 +{
 509.879 +  int c;
 509.880 +  INPUT_VARS(cinfo);
 509.881 +
 509.882 +  for (;;) {
 509.883 +    INPUT_BYTE(cinfo, c, return FALSE);
 509.884 +    /* Skip any non-FF bytes.
 509.885 +     * This may look a bit inefficient, but it will not occur in a valid file.
 509.886 +     * We sync after each discarded byte so that a suspending data source
 509.887 +     * can discard the byte from its buffer.
 509.888 +     */
 509.889 +    while (c != 0xFF) {
 509.890 +      cinfo->marker->discarded_bytes++;
 509.891 +      INPUT_SYNC(cinfo);
 509.892 +      INPUT_BYTE(cinfo, c, return FALSE);
 509.893 +    }
 509.894 +    /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as
 509.895 +     * pad bytes, so don't count them in discarded_bytes.  We assume there
 509.896 +     * will not be so many consecutive FF bytes as to overflow a suspending
 509.897 +     * data source's input buffer.
 509.898 +     */
 509.899 +    do {
 509.900 +      INPUT_BYTE(cinfo, c, return FALSE);
 509.901 +    } while (c == 0xFF);
 509.902 +    if (c != 0)
 509.903 +      break;			/* found a valid marker, exit loop */
 509.904 +    /* Reach here if we found a stuffed-zero data sequence (FF/00).
 509.905 +     * Discard it and loop back to try again.
 509.906 +     */
 509.907 +    cinfo->marker->discarded_bytes += 2;
 509.908 +    INPUT_SYNC(cinfo);
 509.909 +  }
 509.910 +
 509.911 +  if (cinfo->marker->discarded_bytes != 0) {
 509.912 +    WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
 509.913 +    cinfo->marker->discarded_bytes = 0;
 509.914 +  }
 509.915 +
 509.916 +  cinfo->unread_marker = c;
 509.917 +
 509.918 +  INPUT_SYNC(cinfo);
 509.919 +  return TRUE;
 509.920 +}
 509.921 +
 509.922 +
 509.923 +LOCAL(boolean)
 509.924 +first_marker (j_decompress_ptr cinfo)
 509.925 +/* Like next_marker, but used to obtain the initial SOI marker. */
 509.926 +/* For this marker, we do not allow preceding garbage or fill; otherwise,
 509.927 + * we might well scan an entire input file before realizing it ain't JPEG.
 509.928 + * If an application wants to process non-JFIF files, it must seek to the
 509.929 + * SOI before calling the JPEG library.
 509.930 + */
 509.931 +{
 509.932 +  int c, c2;
 509.933 +  INPUT_VARS(cinfo);
 509.934 +
 509.935 +  INPUT_BYTE(cinfo, c, return FALSE);
 509.936 +  INPUT_BYTE(cinfo, c2, return FALSE);
 509.937 +  if (c != 0xFF || c2 != (int) M_SOI)
 509.938 +    ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
 509.939 +
 509.940 +  cinfo->unread_marker = c2;
 509.941 +
 509.942 +  INPUT_SYNC(cinfo);
 509.943 +  return TRUE;
 509.944 +}
 509.945 +
 509.946 +
 509.947 +/*
 509.948 + * Read markers until SOS or EOI.
 509.949 + *
 509.950 + * Returns same codes as are defined for jpeg_consume_input:
 509.951 + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
 509.952 + */
 509.953 +
 509.954 +METHODDEF(int)
 509.955 +read_markers (j_decompress_ptr cinfo)
 509.956 +{
 509.957 +  /* Outer loop repeats once for each marker. */
 509.958 +  for (;;) {
 509.959 +    /* Collect the marker proper, unless we already did. */
 509.960 +    /* NB: first_marker() enforces the requirement that SOI appear first. */
 509.961 +    if (cinfo->unread_marker == 0) {
 509.962 +      if (! cinfo->marker->saw_SOI) {
 509.963 +	if (! first_marker(cinfo))
 509.964 +	  return JPEG_SUSPENDED;
 509.965 +      } else {
 509.966 +	if (! next_marker(cinfo))
 509.967 +	  return JPEG_SUSPENDED;
 509.968 +      }
 509.969 +    }
 509.970 +    /* At this point cinfo->unread_marker contains the marker code and the
 509.971 +     * input point is just past the marker proper, but before any parameters.
 509.972 +     * A suspension will cause us to return with this state still true.
 509.973 +     */
 509.974 +    switch (cinfo->unread_marker) {
 509.975 +    case M_SOI:
 509.976 +      if (! get_soi(cinfo))
 509.977 +	return JPEG_SUSPENDED;
 509.978 +      break;
 509.979 +
 509.980 +    case M_SOF0:		/* Baseline */
 509.981 +    case M_SOF1:		/* Extended sequential, Huffman */
 509.982 +      if (! get_sof(cinfo, FALSE, FALSE))
 509.983 +	return JPEG_SUSPENDED;
 509.984 +      break;
 509.985 +
 509.986 +    case M_SOF2:		/* Progressive, Huffman */
 509.987 +      if (! get_sof(cinfo, TRUE, FALSE))
 509.988 +	return JPEG_SUSPENDED;
 509.989 +      break;
 509.990 +
 509.991 +    case M_SOF9:		/* Extended sequential, arithmetic */
 509.992 +      if (! get_sof(cinfo, FALSE, TRUE))
 509.993 +	return JPEG_SUSPENDED;
 509.994 +      break;
 509.995 +
 509.996 +    case M_SOF10:		/* Progressive, arithmetic */
 509.997 +      if (! get_sof(cinfo, TRUE, TRUE))
 509.998 +	return JPEG_SUSPENDED;
 509.999 +      break;
509.1000 +
509.1001 +    /* Currently unsupported SOFn types */
509.1002 +    case M_SOF3:		/* Lossless, Huffman */
509.1003 +    case M_SOF5:		/* Differential sequential, Huffman */
509.1004 +    case M_SOF6:		/* Differential progressive, Huffman */
509.1005 +    case M_SOF7:		/* Differential lossless, Huffman */
509.1006 +    case M_JPG:			/* Reserved for JPEG extensions */
509.1007 +    case M_SOF11:		/* Lossless, arithmetic */
509.1008 +    case M_SOF13:		/* Differential sequential, arithmetic */
509.1009 +    case M_SOF14:		/* Differential progressive, arithmetic */
509.1010 +    case M_SOF15:		/* Differential lossless, arithmetic */
509.1011 +      ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
509.1012 +      break;
509.1013 +
509.1014 +    case M_SOS:
509.1015 +      if (! get_sos(cinfo))
509.1016 +	return JPEG_SUSPENDED;
509.1017 +      cinfo->unread_marker = 0;	/* processed the marker */
509.1018 +      return JPEG_REACHED_SOS;
509.1019 +    
509.1020 +    case M_EOI:
509.1021 +      TRACEMS(cinfo, 1, JTRC_EOI);
509.1022 +      cinfo->unread_marker = 0;	/* processed the marker */
509.1023 +      return JPEG_REACHED_EOI;
509.1024 +      
509.1025 +    case M_DAC:
509.1026 +      if (! get_dac(cinfo))
509.1027 +	return JPEG_SUSPENDED;
509.1028 +      break;
509.1029 +      
509.1030 +    case M_DHT:
509.1031 +      if (! get_dht(cinfo))
509.1032 +	return JPEG_SUSPENDED;
509.1033 +      break;
509.1034 +      
509.1035 +    case M_DQT:
509.1036 +      if (! get_dqt(cinfo))
509.1037 +	return JPEG_SUSPENDED;
509.1038 +      break;
509.1039 +      
509.1040 +    case M_DRI:
509.1041 +      if (! get_dri(cinfo))
509.1042 +	return JPEG_SUSPENDED;
509.1043 +      break;
509.1044 +      
509.1045 +    case M_APP0:
509.1046 +    case M_APP1:
509.1047 +    case M_APP2:
509.1048 +    case M_APP3:
509.1049 +    case M_APP4:
509.1050 +    case M_APP5:
509.1051 +    case M_APP6:
509.1052 +    case M_APP7:
509.1053 +    case M_APP8:
509.1054 +    case M_APP9:
509.1055 +    case M_APP10:
509.1056 +    case M_APP11:
509.1057 +    case M_APP12:
509.1058 +    case M_APP13:
509.1059 +    case M_APP14:
509.1060 +    case M_APP15:
509.1061 +      if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
509.1062 +		cinfo->unread_marker - (int) M_APP0]) (cinfo))
509.1063 +	return JPEG_SUSPENDED;
509.1064 +      break;
509.1065 +      
509.1066 +    case M_COM:
509.1067 +      if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
509.1068 +	return JPEG_SUSPENDED;
509.1069 +      break;
509.1070 +
509.1071 +    case M_RST0:		/* these are all parameterless */
509.1072 +    case M_RST1:
509.1073 +    case M_RST2:
509.1074 +    case M_RST3:
509.1075 +    case M_RST4:
509.1076 +    case M_RST5:
509.1077 +    case M_RST6:
509.1078 +    case M_RST7:
509.1079 +    case M_TEM:
509.1080 +      TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
509.1081 +      break;
509.1082 +
509.1083 +    case M_DNL:			/* Ignore DNL ... perhaps the wrong thing */
509.1084 +      if (! skip_variable(cinfo))
509.1085 +	return JPEG_SUSPENDED;
509.1086 +      break;
509.1087 +
509.1088 +    default:			/* must be DHP, EXP, JPGn, or RESn */
509.1089 +      /* For now, we treat the reserved markers as fatal errors since they are
509.1090 +       * likely to be used to signal incompatible JPEG Part 3 extensions.
509.1091 +       * Once the JPEG 3 version-number marker is well defined, this code
509.1092 +       * ought to change!
509.1093 +       */
509.1094 +      ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
509.1095 +      break;
509.1096 +    }
509.1097 +    /* Successfully processed marker, so reset state variable */
509.1098 +    cinfo->unread_marker = 0;
509.1099 +  } /* end loop */
509.1100 +}
509.1101 +
509.1102 +
509.1103 +/*
509.1104 + * Read a restart marker, which is expected to appear next in the datastream;
509.1105 + * if the marker is not there, take appropriate recovery action.
509.1106 + * Returns FALSE if suspension is required.
509.1107 + *
509.1108 + * This is called by the entropy decoder after it has read an appropriate
509.1109 + * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder
509.1110 + * has already read a marker from the data source.  Under normal conditions
509.1111 + * cinfo->unread_marker will be reset to 0 before returning; if not reset,
509.1112 + * it holds a marker which the decoder will be unable to read past.
509.1113 + */
509.1114 +
509.1115 +METHODDEF(boolean)
509.1116 +read_restart_marker (j_decompress_ptr cinfo)
509.1117 +{
509.1118 +  /* Obtain a marker unless we already did. */
509.1119 +  /* Note that next_marker will complain if it skips any data. */
509.1120 +  if (cinfo->unread_marker == 0) {
509.1121 +    if (! next_marker(cinfo))
509.1122 +      return FALSE;
509.1123 +  }
509.1124 +
509.1125 +  if (cinfo->unread_marker ==
509.1126 +      ((int) M_RST0 + cinfo->marker->next_restart_num)) {
509.1127 +    /* Normal case --- swallow the marker and let entropy decoder continue */
509.1128 +    TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
509.1129 +    cinfo->unread_marker = 0;
509.1130 +  } else {
509.1131 +    /* Uh-oh, the restart markers have been messed up. */
509.1132 +    /* Let the data source manager determine how to resync. */
509.1133 +    if (! (*cinfo->src->resync_to_restart) (cinfo,
509.1134 +					    cinfo->marker->next_restart_num))
509.1135 +      return FALSE;
509.1136 +  }
509.1137 +
509.1138 +  /* Update next-restart state */
509.1139 +  cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
509.1140 +
509.1141 +  return TRUE;
509.1142 +}
509.1143 +
509.1144 +
509.1145 +/*
509.1146 + * This is the default resync_to_restart method for data source managers
509.1147 + * to use if they don't have any better approach.  Some data source managers
509.1148 + * may be able to back up, or may have additional knowledge about the data
509.1149 + * which permits a more intelligent recovery strategy; such managers would
509.1150 + * presumably supply their own resync method.
509.1151 + *
509.1152 + * read_restart_marker calls resync_to_restart if it finds a marker other than
509.1153 + * the restart marker it was expecting.  (This code is *not* used unless
509.1154 + * a nonzero restart interval has been declared.)  cinfo->unread_marker is
509.1155 + * the marker code actually found (might be anything, except 0 or FF).
509.1156 + * The desired restart marker number (0..7) is passed as a parameter.
509.1157 + * This routine is supposed to apply whatever error recovery strategy seems
509.1158 + * appropriate in order to position the input stream to the next data segment.
509.1159 + * Note that cinfo->unread_marker is treated as a marker appearing before
509.1160 + * the current data-source input point; usually it should be reset to zero
509.1161 + * before returning.
509.1162 + * Returns FALSE if suspension is required.
509.1163 + *
509.1164 + * This implementation is substantially constrained by wanting to treat the
509.1165 + * input as a data stream; this means we can't back up.  Therefore, we have
509.1166 + * only the following actions to work with:
509.1167 + *   1. Simply discard the marker and let the entropy decoder resume at next
509.1168 + *      byte of file.
509.1169 + *   2. Read forward until we find another marker, discarding intervening
509.1170 + *      data.  (In theory we could look ahead within the current bufferload,
509.1171 + *      without having to discard data if we don't find the desired marker.
509.1172 + *      This idea is not implemented here, in part because it makes behavior
509.1173 + *      dependent on buffer size and chance buffer-boundary positions.)
509.1174 + *   3. Leave the marker unread (by failing to zero cinfo->unread_marker).
509.1175 + *      This will cause the entropy decoder to process an empty data segment,
509.1176 + *      inserting dummy zeroes, and then we will reprocess the marker.
509.1177 + *
509.1178 + * #2 is appropriate if we think the desired marker lies ahead, while #3 is
509.1179 + * appropriate if the found marker is a future restart marker (indicating
509.1180 + * that we have missed the desired restart marker, probably because it got
509.1181 + * corrupted).
509.1182 + * We apply #2 or #3 if the found marker is a restart marker no more than
509.1183 + * two counts behind or ahead of the expected one.  We also apply #2 if the
509.1184 + * found marker is not a legal JPEG marker code (it's certainly bogus data).
509.1185 + * If the found marker is a restart marker more than 2 counts away, we do #1
509.1186 + * (too much risk that the marker is erroneous; with luck we will be able to
509.1187 + * resync at some future point).
509.1188 + * For any valid non-restart JPEG marker, we apply #3.  This keeps us from
509.1189 + * overrunning the end of a scan.  An implementation limited to single-scan
509.1190 + * files might find it better to apply #2 for markers other than EOI, since
509.1191 + * any other marker would have to be bogus data in that case.
509.1192 + */
509.1193 +
509.1194 +GLOBAL(boolean)
509.1195 +jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
509.1196 +{
509.1197 +  int marker = cinfo->unread_marker;
509.1198 +  int action = 1;
509.1199 +  
509.1200 +  /* Always put up a warning. */
509.1201 +  WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
509.1202 +  
509.1203 +  /* Outer loop handles repeated decision after scanning forward. */
509.1204 +  for (;;) {
509.1205 +    if (marker < (int) M_SOF0)
509.1206 +      action = 2;		/* invalid marker */
509.1207 +    else if (marker < (int) M_RST0 || marker > (int) M_RST7)
509.1208 +      action = 3;		/* valid non-restart marker */
509.1209 +    else {
509.1210 +      if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
509.1211 +	  marker == ((int) M_RST0 + ((desired+2) & 7)))
509.1212 +	action = 3;		/* one of the next two expected restarts */
509.1213 +      else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
509.1214 +	       marker == ((int) M_RST0 + ((desired-2) & 7)))
509.1215 +	action = 2;		/* a prior restart, so advance */
509.1216 +      else
509.1217 +	action = 1;		/* desired restart or too far away */
509.1218 +    }
509.1219 +    TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
509.1220 +    switch (action) {
509.1221 +    case 1:
509.1222 +      /* Discard marker and let entropy decoder resume processing. */
509.1223 +      cinfo->unread_marker = 0;
509.1224 +      return TRUE;
509.1225 +    case 2:
509.1226 +      /* Scan to the next marker, and repeat the decision loop. */
509.1227 +      if (! next_marker(cinfo))
509.1228 +	return FALSE;
509.1229 +      marker = cinfo->unread_marker;
509.1230 +      break;
509.1231 +    case 3:
509.1232 +      /* Return without advancing past this marker. */
509.1233 +      /* Entropy decoder will be forced to process an empty segment. */
509.1234 +      return TRUE;
509.1235 +    }
509.1236 +  } /* end loop */
509.1237 +}
509.1238 +
509.1239 +
509.1240 +/*
509.1241 + * Reset marker processing state to begin a fresh datastream.
509.1242 + */
509.1243 +
509.1244 +METHODDEF(void)
509.1245 +reset_marker_reader (j_decompress_ptr cinfo)
509.1246 +{
509.1247 +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
509.1248 +
509.1249 +  cinfo->comp_info = NULL;		/* until allocated by get_sof */
509.1250 +  cinfo->input_scan_number = 0;		/* no SOS seen yet */
509.1251 +  cinfo->unread_marker = 0;		/* no pending marker */
509.1252 +  marker->pub.saw_SOI = FALSE;		/* set internal state too */
509.1253 +  marker->pub.saw_SOF = FALSE;
509.1254 +  marker->pub.discarded_bytes = 0;
509.1255 +  marker->cur_marker = NULL;
509.1256 +}
509.1257 +
509.1258 +
509.1259 +/*
509.1260 + * Initialize the marker reader module.
509.1261 + * This is called only once, when the decompression object is created.
509.1262 + */
509.1263 +
509.1264 +GLOBAL(void)
509.1265 +jinit_marker_reader (j_decompress_ptr cinfo)
509.1266 +{
509.1267 +  my_marker_ptr marker;
509.1268 +  int i;
509.1269 +
509.1270 +  /* Create subobject in permanent pool */
509.1271 +  marker = (my_marker_ptr)
509.1272 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
509.1273 +				SIZEOF(my_marker_reader));
509.1274 +  cinfo->marker = (struct jpeg_marker_reader *) marker;
509.1275 +  /* Initialize public method pointers */
509.1276 +  marker->pub.reset_marker_reader = reset_marker_reader;
509.1277 +  marker->pub.read_markers = read_markers;
509.1278 +  marker->pub.read_restart_marker = read_restart_marker;
509.1279 +  /* Initialize COM/APPn processing.
509.1280 +   * By default, we examine and then discard APP0 and APP14,
509.1281 +   * but simply discard COM and all other APPn.
509.1282 +   */
509.1283 +  marker->process_COM = skip_variable;
509.1284 +  marker->length_limit_COM = 0;
509.1285 +  for (i = 0; i < 16; i++) {
509.1286 +    marker->process_APPn[i] = skip_variable;
509.1287 +    marker->length_limit_APPn[i] = 0;
509.1288 +  }
509.1289 +  marker->process_APPn[0] = get_interesting_appn;
509.1290 +  marker->process_APPn[14] = get_interesting_appn;
509.1291 +  /* Reset marker processing state */
509.1292 +  reset_marker_reader(cinfo);
509.1293 +}
509.1294 +
509.1295 +
509.1296 +/*
509.1297 + * Control saving of COM and APPn markers into marker_list.
509.1298 + */
509.1299 +
509.1300 +#ifdef SAVE_MARKERS_SUPPORTED
509.1301 +
509.1302 +GLOBAL(void)
509.1303 +jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
509.1304 +		   unsigned int length_limit)
509.1305 +{
509.1306 +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
509.1307 +  long maxlength;
509.1308 +  jpeg_marker_parser_method processor;
509.1309 +
509.1310 +  /* Length limit mustn't be larger than what we can allocate
509.1311 +   * (should only be a concern in a 16-bit environment).
509.1312 +   */
509.1313 +  maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
509.1314 +  if (((long) length_limit) > maxlength)
509.1315 +    length_limit = (unsigned int) maxlength;
509.1316 +
509.1317 +  /* Choose processor routine to use.
509.1318 +   * APP0/APP14 have special requirements.
509.1319 +   */
509.1320 +  if (length_limit) {
509.1321 +    processor = save_marker;
509.1322 +    /* If saving APP0/APP14, save at least enough for our internal use. */
509.1323 +    if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
509.1324 +      length_limit = APP0_DATA_LEN;
509.1325 +    else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
509.1326 +      length_limit = APP14_DATA_LEN;
509.1327 +  } else {
509.1328 +    processor = skip_variable;
509.1329 +    /* If discarding APP0/APP14, use our regular on-the-fly processor. */
509.1330 +    if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
509.1331 +      processor = get_interesting_appn;
509.1332 +  }
509.1333 +
509.1334 +  if (marker_code == (int) M_COM) {
509.1335 +    marker->process_COM = processor;
509.1336 +    marker->length_limit_COM = length_limit;
509.1337 +  } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
509.1338 +    marker->process_APPn[marker_code - (int) M_APP0] = processor;
509.1339 +    marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
509.1340 +  } else
509.1341 +    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
509.1342 +}
509.1343 +
509.1344 +#endif /* SAVE_MARKERS_SUPPORTED */
509.1345 +
509.1346 +
509.1347 +/*
509.1348 + * Install a special processing method for COM or APPn markers.
509.1349 + */
509.1350 +
509.1351 +GLOBAL(void)
509.1352 +jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
509.1353 +			   jpeg_marker_parser_method routine)
509.1354 +{
509.1355 +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
509.1356 +
509.1357 +  if (marker_code == (int) M_COM)
509.1358 +    marker->process_COM = routine;
509.1359 +  else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
509.1360 +    marker->process_APPn[marker_code - (int) M_APP0] = routine;
509.1361 +  else
509.1362 +    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
509.1363 +}
   510.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   510.2 +++ b/libs/libjpeg/jdmaster.c	Sat Feb 01 19:58:19 2014 +0200
   510.3 @@ -0,0 +1,557 @@
   510.4 +/*
   510.5 + * jdmaster.c
   510.6 + *
   510.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   510.8 + * This file is part of the Independent JPEG Group's software.
   510.9 + * For conditions of distribution and use, see the accompanying README file.
  510.10 + *
  510.11 + * This file contains master control logic for the JPEG decompressor.
  510.12 + * These routines are concerned with selecting the modules to be executed
  510.13 + * and with determining the number of passes and the work to be done in each
  510.14 + * pass.
  510.15 + */
  510.16 +
  510.17 +#define JPEG_INTERNALS
  510.18 +#include "jinclude.h"
  510.19 +#include "jpeglib.h"
  510.20 +
  510.21 +
  510.22 +/* Private state */
  510.23 +
  510.24 +typedef struct {
  510.25 +  struct jpeg_decomp_master pub; /* public fields */
  510.26 +
  510.27 +  int pass_number;		/* # of passes completed */
  510.28 +
  510.29 +  boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */
  510.30 +
  510.31 +  /* Saved references to initialized quantizer modules,
  510.32 +   * in case we need to switch modes.
  510.33 +   */
  510.34 +  struct jpeg_color_quantizer * quantizer_1pass;
  510.35 +  struct jpeg_color_quantizer * quantizer_2pass;
  510.36 +} my_decomp_master;
  510.37 +
  510.38 +typedef my_decomp_master * my_master_ptr;
  510.39 +
  510.40 +
  510.41 +/*
  510.42 + * Determine whether merged upsample/color conversion should be used.
  510.43 + * CRUCIAL: this must match the actual capabilities of jdmerge.c!
  510.44 + */
  510.45 +
  510.46 +LOCAL(boolean)
  510.47 +use_merged_upsample (j_decompress_ptr cinfo)
  510.48 +{
  510.49 +#ifdef UPSAMPLE_MERGING_SUPPORTED
  510.50 +  /* Merging is the equivalent of plain box-filter upsampling */
  510.51 +  if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
  510.52 +    return FALSE;
  510.53 +  /* jdmerge.c only supports YCC=>RGB color conversion */
  510.54 +  if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
  510.55 +      cinfo->out_color_space != JCS_RGB ||
  510.56 +      cinfo->out_color_components != RGB_PIXELSIZE)
  510.57 +    return FALSE;
  510.58 +  /* and it only handles 2h1v or 2h2v sampling ratios */
  510.59 +  if (cinfo->comp_info[0].h_samp_factor != 2 ||
  510.60 +      cinfo->comp_info[1].h_samp_factor != 1 ||
  510.61 +      cinfo->comp_info[2].h_samp_factor != 1 ||
  510.62 +      cinfo->comp_info[0].v_samp_factor >  2 ||
  510.63 +      cinfo->comp_info[1].v_samp_factor != 1 ||
  510.64 +      cinfo->comp_info[2].v_samp_factor != 1)
  510.65 +    return FALSE;
  510.66 +  /* furthermore, it doesn't work if we've scaled the IDCTs differently */
  510.67 +  if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
  510.68 +      cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
  510.69 +      cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size)
  510.70 +    return FALSE;
  510.71 +  /* ??? also need to test for upsample-time rescaling, when & if supported */
  510.72 +  return TRUE;			/* by golly, it'll work... */
  510.73 +#else
  510.74 +  return FALSE;
  510.75 +#endif
  510.76 +}
  510.77 +
  510.78 +
  510.79 +/*
  510.80 + * Compute output image dimensions and related values.
  510.81 + * NOTE: this is exported for possible use by application.
  510.82 + * Hence it mustn't do anything that can't be done twice.
  510.83 + * Also note that it may be called before the master module is initialized!
  510.84 + */
  510.85 +
  510.86 +GLOBAL(void)
  510.87 +jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
  510.88 +/* Do computations that are needed before master selection phase */
  510.89 +{
  510.90 +#ifdef IDCT_SCALING_SUPPORTED
  510.91 +  int ci;
  510.92 +  jpeg_component_info *compptr;
  510.93 +#endif
  510.94 +
  510.95 +  /* Prevent application from calling me at wrong times */
  510.96 +  if (cinfo->global_state != DSTATE_READY)
  510.97 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  510.98 +
  510.99 +#ifdef IDCT_SCALING_SUPPORTED
 510.100 +
 510.101 +  /* Compute actual output image dimensions and DCT scaling choices. */
 510.102 +  if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
 510.103 +    /* Provide 1/8 scaling */
 510.104 +    cinfo->output_width = (JDIMENSION)
 510.105 +      jdiv_round_up((long) cinfo->image_width, 8L);
 510.106 +    cinfo->output_height = (JDIMENSION)
 510.107 +      jdiv_round_up((long) cinfo->image_height, 8L);
 510.108 +    cinfo->min_DCT_scaled_size = 1;
 510.109 +  } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
 510.110 +    /* Provide 1/4 scaling */
 510.111 +    cinfo->output_width = (JDIMENSION)
 510.112 +      jdiv_round_up((long) cinfo->image_width, 4L);
 510.113 +    cinfo->output_height = (JDIMENSION)
 510.114 +      jdiv_round_up((long) cinfo->image_height, 4L);
 510.115 +    cinfo->min_DCT_scaled_size = 2;
 510.116 +  } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
 510.117 +    /* Provide 1/2 scaling */
 510.118 +    cinfo->output_width = (JDIMENSION)
 510.119 +      jdiv_round_up((long) cinfo->image_width, 2L);
 510.120 +    cinfo->output_height = (JDIMENSION)
 510.121 +      jdiv_round_up((long) cinfo->image_height, 2L);
 510.122 +    cinfo->min_DCT_scaled_size = 4;
 510.123 +  } else {
 510.124 +    /* Provide 1/1 scaling */
 510.125 +    cinfo->output_width = cinfo->image_width;
 510.126 +    cinfo->output_height = cinfo->image_height;
 510.127 +    cinfo->min_DCT_scaled_size = DCTSIZE;
 510.128 +  }
 510.129 +  /* In selecting the actual DCT scaling for each component, we try to
 510.130 +   * scale up the chroma components via IDCT scaling rather than upsampling.
 510.131 +   * This saves time if the upsampler gets to use 1:1 scaling.
 510.132 +   * Note this code assumes that the supported DCT scalings are powers of 2.
 510.133 +   */
 510.134 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 510.135 +       ci++, compptr++) {
 510.136 +    int ssize = cinfo->min_DCT_scaled_size;
 510.137 +    while (ssize < DCTSIZE &&
 510.138 +	   (compptr->h_samp_factor * ssize * 2 <=
 510.139 +	    cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) &&
 510.140 +	   (compptr->v_samp_factor * ssize * 2 <=
 510.141 +	    cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) {
 510.142 +      ssize = ssize * 2;
 510.143 +    }
 510.144 +    compptr->DCT_scaled_size = ssize;
 510.145 +  }
 510.146 +
 510.147 +  /* Recompute downsampled dimensions of components;
 510.148 +   * application needs to know these if using raw downsampled data.
 510.149 +   */
 510.150 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 510.151 +       ci++, compptr++) {
 510.152 +    /* Size in samples, after IDCT scaling */
 510.153 +    compptr->downsampled_width = (JDIMENSION)
 510.154 +      jdiv_round_up((long) cinfo->image_width *
 510.155 +		    (long) (compptr->h_samp_factor * compptr->DCT_scaled_size),
 510.156 +		    (long) (cinfo->max_h_samp_factor * DCTSIZE));
 510.157 +    compptr->downsampled_height = (JDIMENSION)
 510.158 +      jdiv_round_up((long) cinfo->image_height *
 510.159 +		    (long) (compptr->v_samp_factor * compptr->DCT_scaled_size),
 510.160 +		    (long) (cinfo->max_v_samp_factor * DCTSIZE));
 510.161 +  }
 510.162 +
 510.163 +#else /* !IDCT_SCALING_SUPPORTED */
 510.164 +
 510.165 +  /* Hardwire it to "no scaling" */
 510.166 +  cinfo->output_width = cinfo->image_width;
 510.167 +  cinfo->output_height = cinfo->image_height;
 510.168 +  /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
 510.169 +   * and has computed unscaled downsampled_width and downsampled_height.
 510.170 +   */
 510.171 +
 510.172 +#endif /* IDCT_SCALING_SUPPORTED */
 510.173 +
 510.174 +  /* Report number of components in selected colorspace. */
 510.175 +  /* Probably this should be in the color conversion module... */
 510.176 +  switch (cinfo->out_color_space) {
 510.177 +  case JCS_GRAYSCALE:
 510.178 +    cinfo->out_color_components = 1;
 510.179 +    break;
 510.180 +  case JCS_RGB:
 510.181 +#if RGB_PIXELSIZE != 3
 510.182 +    cinfo->out_color_components = RGB_PIXELSIZE;
 510.183 +    break;
 510.184 +#endif /* else share code with YCbCr */
 510.185 +  case JCS_YCbCr:
 510.186 +    cinfo->out_color_components = 3;
 510.187 +    break;
 510.188 +  case JCS_CMYK:
 510.189 +  case JCS_YCCK:
 510.190 +    cinfo->out_color_components = 4;
 510.191 +    break;
 510.192 +  default:			/* else must be same colorspace as in file */
 510.193 +    cinfo->out_color_components = cinfo->num_components;
 510.194 +    break;
 510.195 +  }
 510.196 +  cinfo->output_components = (cinfo->quantize_colors ? 1 :
 510.197 +			      cinfo->out_color_components);
 510.198 +
 510.199 +  /* See if upsampler will want to emit more than one row at a time */
 510.200 +  if (use_merged_upsample(cinfo))
 510.201 +    cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
 510.202 +  else
 510.203 +    cinfo->rec_outbuf_height = 1;
 510.204 +}
 510.205 +
 510.206 +
 510.207 +/*
 510.208 + * Several decompression processes need to range-limit values to the range
 510.209 + * 0..MAXJSAMPLE; the input value may fall somewhat outside this range
 510.210 + * due to noise introduced by quantization, roundoff error, etc.  These
 510.211 + * processes are inner loops and need to be as fast as possible.  On most
 510.212 + * machines, particularly CPUs with pipelines or instruction prefetch,
 510.213 + * a (subscript-check-less) C table lookup
 510.214 + *		x = sample_range_limit[x];
 510.215 + * is faster than explicit tests
 510.216 + *		if (x < 0)  x = 0;
 510.217 + *		else if (x > MAXJSAMPLE)  x = MAXJSAMPLE;
 510.218 + * These processes all use a common table prepared by the routine below.
 510.219 + *
 510.220 + * For most steps we can mathematically guarantee that the initial value
 510.221 + * of x is within MAXJSAMPLE+1 of the legal range, so a table running from
 510.222 + * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient.  But for the initial
 510.223 + * limiting step (just after the IDCT), a wildly out-of-range value is 
 510.224 + * possible if the input data is corrupt.  To avoid any chance of indexing
 510.225 + * off the end of memory and getting a bad-pointer trap, we perform the
 510.226 + * post-IDCT limiting thus:
 510.227 + *		x = range_limit[x & MASK];
 510.228 + * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
 510.229 + * samples.  Under normal circumstances this is more than enough range and
 510.230 + * a correct output will be generated; with bogus input data the mask will
 510.231 + * cause wraparound, and we will safely generate a bogus-but-in-range output.
 510.232 + * For the post-IDCT step, we want to convert the data from signed to unsigned
 510.233 + * representation by adding CENTERJSAMPLE at the same time that we limit it.
 510.234 + * So the post-IDCT limiting table ends up looking like this:
 510.235 + *   CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE,
 510.236 + *   MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
 510.237 + *   0          (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
 510.238 + *   0,1,...,CENTERJSAMPLE-1
 510.239 + * Negative inputs select values from the upper half of the table after
 510.240 + * masking.
 510.241 + *
 510.242 + * We can save some space by overlapping the start of the post-IDCT table
 510.243 + * with the simpler range limiting table.  The post-IDCT table begins at
 510.244 + * sample_range_limit + CENTERJSAMPLE.
 510.245 + *
 510.246 + * Note that the table is allocated in near data space on PCs; it's small
 510.247 + * enough and used often enough to justify this.
 510.248 + */
 510.249 +
 510.250 +LOCAL(void)
 510.251 +prepare_range_limit_table (j_decompress_ptr cinfo)
 510.252 +/* Allocate and fill in the sample_range_limit table */
 510.253 +{
 510.254 +  JSAMPLE * table;
 510.255 +  int i;
 510.256 +
 510.257 +  table = (JSAMPLE *)
 510.258 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 510.259 +		(5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
 510.260 +  table += (MAXJSAMPLE+1);	/* allow negative subscripts of simple table */
 510.261 +  cinfo->sample_range_limit = table;
 510.262 +  /* First segment of "simple" table: limit[x] = 0 for x < 0 */
 510.263 +  MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
 510.264 +  /* Main part of "simple" table: limit[x] = x */
 510.265 +  for (i = 0; i <= MAXJSAMPLE; i++)
 510.266 +    table[i] = (JSAMPLE) i;
 510.267 +  table += CENTERJSAMPLE;	/* Point to where post-IDCT table starts */
 510.268 +  /* End of simple table, rest of first half of post-IDCT table */
 510.269 +  for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
 510.270 +    table[i] = MAXJSAMPLE;
 510.271 +  /* Second half of post-IDCT table */
 510.272 +  MEMZERO(table + (2 * (MAXJSAMPLE+1)),
 510.273 +	  (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
 510.274 +  MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
 510.275 +	  cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
 510.276 +}
 510.277 +
 510.278 +
 510.279 +/*
 510.280 + * Master selection of decompression modules.
 510.281 + * This is done once at jpeg_start_decompress time.  We determine
 510.282 + * which modules will be used and give them appropriate initialization calls.
 510.283 + * We also initialize the decompressor input side to begin consuming data.
 510.284 + *
 510.285 + * Since jpeg_read_header has finished, we know what is in the SOF
 510.286 + * and (first) SOS markers.  We also have all the application parameter
 510.287 + * settings.
 510.288 + */
 510.289 +
 510.290 +LOCAL(void)
 510.291 +master_selection (j_decompress_ptr cinfo)
 510.292 +{
 510.293 +  my_master_ptr master = (my_master_ptr) cinfo->master;
 510.294 +  boolean use_c_buffer;
 510.295 +  long samplesperrow;
 510.296 +  JDIMENSION jd_samplesperrow;
 510.297 +
 510.298 +  /* Initialize dimensions and other stuff */
 510.299 +  jpeg_calc_output_dimensions(cinfo);
 510.300 +  prepare_range_limit_table(cinfo);
 510.301 +
 510.302 +  /* Width of an output scanline must be representable as JDIMENSION. */
 510.303 +  samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
 510.304 +  jd_samplesperrow = (JDIMENSION) samplesperrow;
 510.305 +  if ((long) jd_samplesperrow != samplesperrow)
 510.306 +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
 510.307 +
 510.308 +  /* Initialize my private state */
 510.309 +  master->pass_number = 0;
 510.310 +  master->using_merged_upsample = use_merged_upsample(cinfo);
 510.311 +
 510.312 +  /* Color quantizer selection */
 510.313 +  master->quantizer_1pass = NULL;
 510.314 +  master->quantizer_2pass = NULL;
 510.315 +  /* No mode changes if not using buffered-image mode. */
 510.316 +  if (! cinfo->quantize_colors || ! cinfo->buffered_image) {
 510.317 +    cinfo->enable_1pass_quant = FALSE;
 510.318 +    cinfo->enable_external_quant = FALSE;
 510.319 +    cinfo->enable_2pass_quant = FALSE;
 510.320 +  }
 510.321 +  if (cinfo->quantize_colors) {
 510.322 +    if (cinfo->raw_data_out)
 510.323 +      ERREXIT(cinfo, JERR_NOTIMPL);
 510.324 +    /* 2-pass quantizer only works in 3-component color space. */
 510.325 +    if (cinfo->out_color_components != 3) {
 510.326 +      cinfo->enable_1pass_quant = TRUE;
 510.327 +      cinfo->enable_external_quant = FALSE;
 510.328 +      cinfo->enable_2pass_quant = FALSE;
 510.329 +      cinfo->colormap = NULL;
 510.330 +    } else if (cinfo->colormap != NULL) {
 510.331 +      cinfo->enable_external_quant = TRUE;
 510.332 +    } else if (cinfo->two_pass_quantize) {
 510.333 +      cinfo->enable_2pass_quant = TRUE;
 510.334 +    } else {
 510.335 +      cinfo->enable_1pass_quant = TRUE;
 510.336 +    }
 510.337 +
 510.338 +    if (cinfo->enable_1pass_quant) {
 510.339 +#ifdef QUANT_1PASS_SUPPORTED
 510.340 +      jinit_1pass_quantizer(cinfo);
 510.341 +      master->quantizer_1pass = cinfo->cquantize;
 510.342 +#else
 510.343 +      ERREXIT(cinfo, JERR_NOT_COMPILED);
 510.344 +#endif
 510.345 +    }
 510.346 +
 510.347 +    /* We use the 2-pass code to map to external colormaps. */
 510.348 +    if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
 510.349 +#ifdef QUANT_2PASS_SUPPORTED
 510.350 +      jinit_2pass_quantizer(cinfo);
 510.351 +      master->quantizer_2pass = cinfo->cquantize;
 510.352 +#else
 510.353 +      ERREXIT(cinfo, JERR_NOT_COMPILED);
 510.354 +#endif
 510.355 +    }
 510.356 +    /* If both quantizers are initialized, the 2-pass one is left active;
 510.357 +     * this is necessary for starting with quantization to an external map.
 510.358 +     */
 510.359 +  }
 510.360 +
 510.361 +  /* Post-processing: in particular, color conversion first */
 510.362 +  if (! cinfo->raw_data_out) {
 510.363 +    if (master->using_merged_upsample) {
 510.364 +#ifdef UPSAMPLE_MERGING_SUPPORTED
 510.365 +      jinit_merged_upsampler(cinfo); /* does color conversion too */
 510.366 +#else
 510.367 +      ERREXIT(cinfo, JERR_NOT_COMPILED);
 510.368 +#endif
 510.369 +    } else {
 510.370 +      jinit_color_deconverter(cinfo);
 510.371 +      jinit_upsampler(cinfo);
 510.372 +    }
 510.373 +    jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
 510.374 +  }
 510.375 +  /* Inverse DCT */
 510.376 +  jinit_inverse_dct(cinfo);
 510.377 +  /* Entropy decoding: either Huffman or arithmetic coding. */
 510.378 +  if (cinfo->arith_code) {
 510.379 +    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
 510.380 +  } else {
 510.381 +    if (cinfo->progressive_mode) {
 510.382 +#ifdef D_PROGRESSIVE_SUPPORTED
 510.383 +      jinit_phuff_decoder(cinfo);
 510.384 +#else
 510.385 +      ERREXIT(cinfo, JERR_NOT_COMPILED);
 510.386 +#endif
 510.387 +    } else
 510.388 +      jinit_huff_decoder(cinfo);
 510.389 +  }
 510.390 +
 510.391 +  /* Initialize principal buffer controllers. */
 510.392 +  use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
 510.393 +  jinit_d_coef_controller(cinfo, use_c_buffer);
 510.394 +
 510.395 +  if (! cinfo->raw_data_out)
 510.396 +    jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
 510.397 +
 510.398 +  /* We can now tell the memory manager to allocate virtual arrays. */
 510.399 +  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
 510.400 +
 510.401 +  /* Initialize input side of decompressor to consume first scan. */
 510.402 +  (*cinfo->inputctl->start_input_pass) (cinfo);
 510.403 +
 510.404 +#ifdef D_MULTISCAN_FILES_SUPPORTED
 510.405 +  /* If jpeg_start_decompress will read the whole file, initialize
 510.406 +   * progress monitoring appropriately.  The input step is counted
 510.407 +   * as one pass.
 510.408 +   */
 510.409 +  if (cinfo->progress != NULL && ! cinfo->buffered_image &&
 510.410 +      cinfo->inputctl->has_multiple_scans) {
 510.411 +    int nscans;
 510.412 +    /* Estimate number of scans to set pass_limit. */
 510.413 +    if (cinfo->progressive_mode) {
 510.414 +      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
 510.415 +      nscans = 2 + 3 * cinfo->num_components;
 510.416 +    } else {
 510.417 +      /* For a nonprogressive multiscan file, estimate 1 scan per component. */
 510.418 +      nscans = cinfo->num_components;
 510.419 +    }
 510.420 +    cinfo->progress->pass_counter = 0L;
 510.421 +    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
 510.422 +    cinfo->progress->completed_passes = 0;
 510.423 +    cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2);
 510.424 +    /* Count the input pass as done */
 510.425 +    master->pass_number++;
 510.426 +  }
 510.427 +#endif /* D_MULTISCAN_FILES_SUPPORTED */
 510.428 +}
 510.429 +
 510.430 +
 510.431 +/*
 510.432 + * Per-pass setup.
 510.433 + * This is called at the beginning of each output pass.  We determine which
 510.434 + * modules will be active during this pass and give them appropriate
 510.435 + * start_pass calls.  We also set is_dummy_pass to indicate whether this
 510.436 + * is a "real" output pass or a dummy pass for color quantization.
 510.437 + * (In the latter case, jdapistd.c will crank the pass to completion.)
 510.438 + */
 510.439 +
 510.440 +METHODDEF(void)
 510.441 +prepare_for_output_pass (j_decompress_ptr cinfo)
 510.442 +{
 510.443 +  my_master_ptr master = (my_master_ptr) cinfo->master;
 510.444 +
 510.445 +  if (master->pub.is_dummy_pass) {
 510.446 +#ifdef QUANT_2PASS_SUPPORTED
 510.447 +    /* Final pass of 2-pass quantization */
 510.448 +    master->pub.is_dummy_pass = FALSE;
 510.449 +    (*cinfo->cquantize->start_pass) (cinfo, FALSE);
 510.450 +    (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST);
 510.451 +    (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST);
 510.452 +#else
 510.453 +    ERREXIT(cinfo, JERR_NOT_COMPILED);
 510.454 +#endif /* QUANT_2PASS_SUPPORTED */
 510.455 +  } else {
 510.456 +    if (cinfo->quantize_colors && cinfo->colormap == NULL) {
 510.457 +      /* Select new quantization method */
 510.458 +      if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) {
 510.459 +	cinfo->cquantize = master->quantizer_2pass;
 510.460 +	master->pub.is_dummy_pass = TRUE;
 510.461 +      } else if (cinfo->enable_1pass_quant) {
 510.462 +	cinfo->cquantize = master->quantizer_1pass;
 510.463 +      } else {
 510.464 +	ERREXIT(cinfo, JERR_MODE_CHANGE);
 510.465 +      }
 510.466 +    }
 510.467 +    (*cinfo->idct->start_pass) (cinfo);
 510.468 +    (*cinfo->coef->start_output_pass) (cinfo);
 510.469 +    if (! cinfo->raw_data_out) {
 510.470 +      if (! master->using_merged_upsample)
 510.471 +	(*cinfo->cconvert->start_pass) (cinfo);
 510.472 +      (*cinfo->upsample->start_pass) (cinfo);
 510.473 +      if (cinfo->quantize_colors)
 510.474 +	(*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass);
 510.475 +      (*cinfo->post->start_pass) (cinfo,
 510.476 +	    (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
 510.477 +      (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
 510.478 +    }
 510.479 +  }
 510.480 +
 510.481 +  /* Set up progress monitor's pass info if present */
 510.482 +  if (cinfo->progress != NULL) {
 510.483 +    cinfo->progress->completed_passes = master->pass_number;
 510.484 +    cinfo->progress->total_passes = master->pass_number +
 510.485 +				    (master->pub.is_dummy_pass ? 2 : 1);
 510.486 +    /* In buffered-image mode, we assume one more output pass if EOI not
 510.487 +     * yet reached, but no more passes if EOI has been reached.
 510.488 +     */
 510.489 +    if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) {
 510.490 +      cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1);
 510.491 +    }
 510.492 +  }
 510.493 +}
 510.494 +
 510.495 +
 510.496 +/*
 510.497 + * Finish up at end of an output pass.
 510.498 + */
 510.499 +
 510.500 +METHODDEF(void)
 510.501 +finish_output_pass (j_decompress_ptr cinfo)
 510.502 +{
 510.503 +  my_master_ptr master = (my_master_ptr) cinfo->master;
 510.504 +
 510.505 +  if (cinfo->quantize_colors)
 510.506 +    (*cinfo->cquantize->finish_pass) (cinfo);
 510.507 +  master->pass_number++;
 510.508 +}
 510.509 +
 510.510 +
 510.511 +#ifdef D_MULTISCAN_FILES_SUPPORTED
 510.512 +
 510.513 +/*
 510.514 + * Switch to a new external colormap between output passes.
 510.515 + */
 510.516 +
 510.517 +GLOBAL(void)
 510.518 +jpeg_new_colormap (j_decompress_ptr cinfo)
 510.519 +{
 510.520 +  my_master_ptr master = (my_master_ptr) cinfo->master;
 510.521 +
 510.522 +  /* Prevent application from calling me at wrong times */
 510.523 +  if (cinfo->global_state != DSTATE_BUFIMAGE)
 510.524 +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 510.525 +
 510.526 +  if (cinfo->quantize_colors && cinfo->enable_external_quant &&
 510.527 +      cinfo->colormap != NULL) {
 510.528 +    /* Select 2-pass quantizer for external colormap use */
 510.529 +    cinfo->cquantize = master->quantizer_2pass;
 510.530 +    /* Notify quantizer of colormap change */
 510.531 +    (*cinfo->cquantize->new_color_map) (cinfo);
 510.532 +    master->pub.is_dummy_pass = FALSE; /* just in case */
 510.533 +  } else
 510.534 +    ERREXIT(cinfo, JERR_MODE_CHANGE);
 510.535 +}
 510.536 +
 510.537 +#endif /* D_MULTISCAN_FILES_SUPPORTED */
 510.538 +
 510.539 +
 510.540 +/*
 510.541 + * Initialize master decompression control and select active modules.
 510.542 + * This is performed at the start of jpeg_start_decompress.
 510.543 + */
 510.544 +
 510.545 +GLOBAL(void)
 510.546 +jinit_master_decompress (j_decompress_ptr cinfo)
 510.547 +{
 510.548 +  my_master_ptr master;
 510.549 +
 510.550 +  master = (my_master_ptr)
 510.551 +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 510.552 +				  SIZEOF(my_decomp_master));
 510.553 +  cinfo->master = (struct jpeg_decomp_master *) master;
 510.554 +  master->pub.prepare_for_output_pass = prepare_for_output_pass;
 510.555 +  master->pub.finish_output_pass = finish_output_pass;
 510.556 +
 510.557 +  master->pub.is_dummy_pass = FALSE;
 510.558 +
 510.559 +  master_selection(cinfo);
 510.560 +}
   511.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   511.2 +++ b/libs/libjpeg/jdmerge.c	Sat Feb 01 19:58:19 2014 +0200
   511.3 @@ -0,0 +1,400 @@
   511.4 +/*
   511.5 + * jdmerge.c
   511.6 + *
   511.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   511.8 + * This file is part of the Independent JPEG Group's software.
   511.9 + * For conditions of distribution and use, see the accompanying README file.
  511.10 + *
  511.11 + * This file contains code for merged upsampling/color conversion.
  511.12 + *
  511.13 + * This file combines functions from jdsample.c and jdcolor.c;
  511.14 + * read those files first to understand what's going on.
  511.15 + *
  511.16 + * When the chroma components are to be upsampled by simple replication
  511.17 + * (ie, box filtering), we can save some work in color conversion by
  511.18 + * calculating all the output pixels corresponding to a pair of chroma
  511.19 + * samples at one time.  In the conversion equations
  511.20 + *	R = Y           + K1 * Cr
  511.21 + *	G = Y + K2 * Cb + K3 * Cr
  511.22 + *	B = Y + K4 * Cb
  511.23 + * only the Y term varies among the group of pixels corresponding to a pair
  511.24 + * of chroma samples, so the rest of the terms can be calculated just once.
  511.25 + * At typical sampling ratios, this eliminates half or three-quarters of the
  511.26 + * multiplications needed for color conversion.
  511.27 + *
  511.28 + * This file currently provides implementations for the following cases:
  511.29 + *	YCbCr => RGB color conversion only.
  511.30 + *	Sampling ratios of 2h1v or 2h2v.
  511.31 + *	No scaling needed at upsample time.
  511.32 + *	Corner-aligned (non-CCIR601) sampling alignment.
  511.33 + * Other special cases could be added, but in most applications these are
  511.34 + * the only common cases.  (For uncommon cases we fall back on the more
  511.35 + * general code in jdsample.c and jdcolor.c.)
  511.36 + */
  511.37 +
  511.38 +#define JPEG_INTERNALS
  511.39 +#include "jinclude.h"
  511.40 +#include "jpeglib.h"
  511.41 +
  511.42 +#ifdef UPSAMPLE_MERGING_SUPPORTED
  511.43 +
  511.44 +
  511.45 +/* Private subobject */
  511.46 +
  511.47 +typedef struct {
  511.48 +  struct jpeg_upsampler pub;	/* public fields */
  511.49 +
  511.50 +  /* Pointer to routine to do actual upsampling/conversion of one row group */
  511.51 +  JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
  511.52 +			   JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  511.53 +			   JSAMPARRAY output_buf));
  511.54 +
  511.55 +  /* Private state for YCC->RGB conversion */
  511.56 +  int * Cr_r_tab;		/* => table for Cr to R conversion */
  511.57 +  int * Cb_b_tab;		/* => table for Cb to B conversion */
  511.58 +  INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
  511.59 +  INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
  511.60 +
  511.61 +  /* For 2:1 vertical sampling, we produce two output rows at a time.
  511.62 +   * We need a "spare" row buffer to hold the second output row if the
  511.63 +   * application provides just a one-row buffer; we also use the spare
  511.64 +   * to discard the dummy last row if the image height is odd.
  511.65 +   */
  511.66 +  JSAMPROW spare_row;
  511.67 +  boolean spare_full;		/* T if spare buffer is occupied */
  511.68 +
  511.69 +  JDIMENSION out_row_width;	/* samples per output row */
  511.70 +  JDIMENSION rows_to_go;	/* counts rows remaining in image */
  511.71 +} my_upsampler;
  511.72 +
  511.73 +typedef my_upsampler * my_upsample_ptr;
  511.74 +
  511.75 +#define SCALEBITS	16	/* speediest right-shift on some machines */
  511.76 +#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
  511.77 +#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  511.78 +
  511.79 +
  511.80 +/*
  511.81 + * Initialize tables for YCC->RGB colorspace conversion.
  511.82 + * This is taken directly from jdcolor.c; see that file for more info.
  511.83 + */
  511.84 +
  511.85 +LOCAL(void)
  511.86 +build_ycc_rgb_table (j_decompress_ptr cinfo)
  511.87 +{
  511.88 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  511.89 +  int i;
  511.90 +  INT32 x;
  511.91 +  SHIFT_TEMPS
  511.92 +
  511.93 +  upsample->Cr_r_tab = (int *)
  511.94 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  511.95 +				(MAXJSAMPLE+1) * SIZEOF(int));
  511.96 +  upsample->Cb_b_tab = (int *)
  511.97 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  511.98 +				(MAXJSAMPLE+1) * SIZEOF(int));
  511.99 +  upsample->Cr_g_tab = (INT32 *)
 511.100 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 511.101 +				(MAXJSAMPLE+1) * SIZEOF(INT32));
 511.102 +  upsample->Cb_g_tab = (INT32 *)
 511.103 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 511.104 +				(MAXJSAMPLE+1) * SIZEOF(INT32));
 511.105 +
 511.106 +  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
 511.107 +    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
 511.108 +    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
 511.109 +    /* Cr=>R value is nearest int to 1.40200 * x */
 511.110 +    upsample->Cr_r_tab[i] = (int)
 511.111 +		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
 511.112 +    /* Cb=>B value is nearest int to 1.77200 * x */
 511.113 +    upsample->Cb_b_tab[i] = (int)
 511.114 +		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
 511.115 +    /* Cr=>G value is scaled-up -0.71414 * x */
 511.116 +    upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
 511.117 +    /* Cb=>G value is scaled-up -0.34414 * x */
 511.118 +    /* We also add in ONE_HALF so that need not do it in inner loop */
 511.119 +    upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
 511.120 +  }
 511.121 +}
 511.122 +
 511.123 +
 511.124 +/*
 511.125 + * Initialize for an upsampling pass.
 511.126 + */
 511.127 +
 511.128 +METHODDEF(void)
 511.129 +start_pass_merged_upsample (j_decompress_ptr cinfo)
 511.130 +{
 511.131 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
 511.132 +
 511.133 +  /* Mark the spare buffer empty */
 511.134 +  upsample->spare_full = FALSE;
 511.135 +  /* Initialize total-height counter for detecting bottom of image */
 511.136 +  upsample->rows_to_go = cinfo->output_height;
 511.137 +}
 511.138 +
 511.139 +
 511.140 +/*
 511.141 + * Control routine to do upsampling (and color conversion).
 511.142 + *
 511.143 + * The control routine just handles the row buffering considerations.
 511.144 + */
 511.145 +
 511.146 +METHODDEF(void)
 511.147 +merged_2v_upsample (j_decompress_ptr cinfo,
 511.148 +		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
 511.149 +		    JDIMENSION in_row_groups_avail,
 511.150 +		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 511.151 +		    JDIMENSION out_rows_avail)
 511.152 +/* 2:1 vertical sampling case: may need a spare row. */
 511.153 +{
 511.154 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
 511.155 +  JSAMPROW work_ptrs[2];
 511.156 +  JDIMENSION num_rows;		/* number of rows returned to caller */
 511.157 +
 511.158 +  if (upsample->spare_full) {
 511.159 +    /* If we have a spare row saved from a previous cycle, just return it. */
 511.160 +    jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
 511.161 +		      1, upsample->out_row_width);
 511.162 +    num_rows = 1;
 511.163 +    upsample->spare_full = FALSE;
 511.164 +  } else {
 511.165 +    /* Figure number of rows to return to caller. */
 511.166 +    num_rows = 2;
 511.167 +    /* Not more than the distance to the end of the image. */
 511.168 +    if (num_rows > upsample->rows_to_go)
 511.169 +      num_rows = upsample->rows_to_go;
 511.170 +    /* And not more than what the client can accept: */
 511.171 +    out_rows_avail -= *out_row_ctr;
 511.172 +    if (num_rows > out_rows_avail)
 511.173 +      num_rows = out_rows_avail;
 511.174 +    /* Create output pointer array for upsampler. */
 511.175 +    work_ptrs[0] = output_buf[*out_row_ctr];
 511.176 +    if (num_rows > 1) {
 511.177 +      work_ptrs[1] = output_buf[*out_row_ctr + 1];
 511.178 +    } else {
 511.179 +      work_ptrs[1] = upsample->spare_row;
 511.180 +      upsample->spare_full = TRUE;
 511.181 +    }
 511.182 +    /* Now do the upsampling. */
 511.183 +    (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
 511.184 +  }
 511.185 +
 511.186 +  /* Adjust counts */
 511.187 +  *out_row_ctr += num_rows;
 511.188 +  upsample->rows_to_go -= num_rows;
 511.189 +  /* When the buffer is emptied, declare this input row group consumed */
 511.190 +  if (! upsample->spare_full)
 511.191 +    (*in_row_group_ctr)++;
 511.192 +}
 511.193 +
 511.194 +
 511.195 +METHODDEF(void)
 511.196 +merged_1v_upsample (j_decompress_ptr cinfo,
 511.197 +		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
 511.198 +		    JDIMENSION in_row_groups_avail,
 511.199 +		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 511.200 +		    JDIMENSION out_rows_avail)
 511.201 +/* 1:1 vertical sampling case: much easier, never need a spare row. */
 511.202 +{
 511.203 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
 511.204 +
 511.205 +  /* Just do the upsampling. */
 511.206 +  (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
 511.207 +			 output_buf + *out_row_ctr);
 511.208 +  /* Adjust counts */
 511.209 +  (*out_row_ctr)++;
 511.210 +  (*in_row_group_ctr)++;
 511.211 +}
 511.212 +
 511.213 +
 511.214 +/*
 511.215 + * These are the routines invoked by the control routines to do
 511.216 + * the actual upsampling/conversion.  One row group is processed per call.
 511.217 + *
 511.218 + * Note: since we may be writing directly into application-supplied buffers,
 511.219 + * we have to be honest about the output width; we can't assume the buffer
 511.220 + * has been rounded up to an even width.
 511.221 + */
 511.222 +
 511.223 +
 511.224 +/*
 511.225 + * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
 511.226 + */
 511.227 +
 511.228 +METHODDEF(void)
 511.229 +h2v1_merged_upsample (j_decompress_ptr cinfo,
 511.230 +		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
 511.231 +		      JSAMPARRAY output_buf)
 511.232 +{
 511.233 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
 511.234 +  register int y, cred, cgreen, cblue;
 511.235 +  int cb, cr;
 511.236 +  register JSAMPROW outptr;
 511.237 +  JSAMPROW inptr0, inptr1, inptr2;
 511.238 +  JDIMENSION col;
 511.239 +  /* copy these pointers into registers if possible */
 511.240 +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
 511.241 +  int * Crrtab = upsample->Cr_r_tab;
 511.242 +  int * Cbbtab = upsample->Cb_b_tab;
 511.243 +  INT32 * Crgtab = upsample->Cr_g_tab;
 511.244 +  INT32 * Cbgtab = upsample->Cb_g_tab;
 511.245 +  SHIFT_TEMPS
 511.246 +
 511.247 +  inptr0 = input_buf[0][in_row_group_ctr];
 511.248 +  inptr1 = input_buf[1][in_row_group_ctr];
 511.249 +  inptr2 = input_buf[2][in_row_group_ctr];
 511.250 +  outptr = output_buf[0];
 511.251 +  /* Loop for each pair of output pixels */
 511.252 +  for (col = cinfo->output_width >> 1; col > 0; col--) {
 511.253 +    /* Do the chroma part of the calculation */
 511.254 +    cb = GETJSAMPLE(*inptr1++);
 511.255 +    cr = GETJSAMPLE(*inptr2++);
 511.256 +    cred = Crrtab[cr];
 511.257 +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
 511.258 +    cblue = Cbbtab[cb];
 511.259 +    /* Fetch 2 Y values and emit 2 pixels */
 511.260 +    y  = GETJSAMPLE(*inptr0++);
 511.261 +    outptr[RGB_RED] =   range_limit[y + cred];
 511.262 +    outptr[RGB_GREEN] = range_limit[y + cgreen];
 511.263 +    outptr[RGB_BLUE] =  range_limit[y + cblue];
 511.264 +    outptr += RGB_PIXELSIZE;
 511.265 +    y  = GETJSAMPLE(*inptr0++);
 511.266 +    outptr[RGB_RED] =   range_limit[y + cred];
 511.267 +    outptr[RGB_GREEN] = range_limit[y + cgreen];
 511.268 +    outptr[RGB_BLUE] =  range_limit[y + cblue];
 511.269 +    outptr += RGB_PIXELSIZE;
 511.270 +  }
 511.271 +  /* If image width is odd, do the last output column separately */
 511.272 +  if (cinfo->output_width & 1) {
 511.273 +    cb = GETJSAMPLE(*inptr1);
 511.274 +    cr = GETJSAMPLE(*inptr2);
 511.275 +    cred = Crrtab[cr];
 511.276 +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
 511.277 +    cblue = Cbbtab[cb];
 511.278 +    y  = GETJSAMPLE(*inptr0);
 511.279 +    outptr[RGB_RED] =   range_limit[y + cred];
 511.280 +    outptr[RGB_GREEN] = range_limit[y + cgreen];
 511.281 +    outptr[RGB_BLUE] =  range_limit[y + cblue];
 511.282 +  }
 511.283 +}
 511.284 +
 511.285 +
 511.286 +/*
 511.287 + * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
 511.288 + */
 511.289 +
 511.290 +METHODDEF(void)
 511.291 +h2v2_merged_upsample (j_decompress_ptr cinfo,
 511.292 +		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
 511.293 +		      JSAMPARRAY output_buf)
 511.294 +{
 511.295 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
 511.296 +  register int y, cred, cgreen, cblue;
 511.297 +  int cb, cr;
 511.298 +  register JSAMPROW outptr0, outptr1;
 511.299 +  JSAMPROW inptr00, inptr01, inptr1, inptr2;
 511.300 +  JDIMENSION col;
 511.301 +  /* copy these pointers into registers if possible */
 511.302 +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
 511.303 +  int * Crrtab = upsample->Cr_r_tab;
 511.304 +  int * Cbbtab = upsample->Cb_b_tab;
 511.305 +  INT32 * Crgtab = upsample->Cr_g_tab;
 511.306 +  INT32 * Cbgtab = upsample->Cb_g_tab;
 511.307 +  SHIFT_TEMPS
 511.308 +
 511.309 +  inptr00 = input_buf[0][in_row_group_ctr*2];
 511.310 +  inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
 511.311 +  inptr1 = input_buf[1][in_row_group_ctr];
 511.312 +  inptr2 = input_buf[2][in_row_group_ctr];
 511.313 +  outptr0 = output_buf[0];
 511.314 +  outptr1 = output_buf[1];
 511.315 +  /* Loop for each group of output pixels */
 511.316 +  for (col = cinfo->output_width >> 1; col > 0; col--) {
 511.317 +    /* Do the chroma part of the calculation */
 511.318 +    cb = GETJSAMPLE(*inptr1++);
 511.319 +    cr = GETJSAMPLE(*inptr2++);
 511.320 +    cred = Crrtab[cr];
 511.321 +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
 511.322 +    cblue = Cbbtab[cb];
 511.323 +    /* Fetch 4 Y values and emit 4 pixels */
 511.324 +    y  = GETJSAMPLE(*inptr00++);
 511.325 +    outptr0[RGB_RED] =   range_limit[y + cred];
 511.326 +    outptr0[RGB_GREEN] = range_limit[y + cgreen];
 511.327 +    outptr0[RGB_BLUE] =  range_limit[y + cblue];
 511.328 +    outptr0 += RGB_PIXELSIZE;
 511.329 +    y  = GETJSAMPLE(*inptr00++);
 511.330 +    outptr0[RGB_RED] =   range_limit[y + cred];
 511.331 +    outptr0[RGB_GREEN] = range_limit[y + cgreen];
 511.332 +    outptr0[RGB_BLUE] =  range_limit[y + cblue];
 511.333 +    outptr0 += RGB_PIXELSIZE;
 511.334 +    y  = GETJSAMPLE(*inptr01++);
 511.335 +    outptr1[RGB_RED] =   range_limit[y + cred];
 511.336 +    outptr1[RGB_GREEN] = range_limit[y + cgreen];
 511.337 +    outptr1[RGB_BLUE] =  range_limit[y + cblue];
 511.338 +    outptr1 += RGB_PIXELSIZE;
 511.339 +    y  = GETJSAMPLE(*inptr01++);
 511.340 +    outptr1[RGB_RED] =   range_limit[y + cred];
 511.341 +    outptr1[RGB_GREEN] = range_limit[y + cgreen];
 511.342 +    outptr1[RGB_BLUE] =  range_limit[y + cblue];
 511.343 +    outptr1 += RGB_PIXELSIZE;
 511.344 +  }
 511.345 +  /* If image width is odd, do the last output column separately */
 511.346 +  if (cinfo->output_width & 1) {
 511.347 +    cb = GETJSAMPLE(*inptr1);
 511.348 +    cr = GETJSAMPLE(*inptr2);
 511.349 +    cred = Crrtab[cr];
 511.350 +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
 511.351 +    cblue = Cbbtab[cb];
 511.352 +    y  = GETJSAMPLE(*inptr00);
 511.353 +    outptr0[RGB_RED] =   range_limit[y + cred];
 511.354 +    outptr0[RGB_GREEN] = range_limit[y + cgreen];
 511.355 +    outptr0[RGB_BLUE] =  range_limit[y + cblue];
 511.356 +    y  = GETJSAMPLE(*inptr01);
 511.357 +    outptr1[RGB_RED] =   range_limit[y + cred];
 511.358 +    outptr1[RGB_GREEN] = range_limit[y + cgreen];
 511.359 +    outptr1[RGB_BLUE] =  range_limit[y + cblue];
 511.360 +  }
 511.361 +}
 511.362 +
 511.363 +
 511.364 +/*
 511.365 + * Module initialization routine for merged upsampling/color conversion.
 511.366 + *
 511.367 + * NB: this is called under the conditions determined by use_merged_upsample()
 511.368 + * in jdmaster.c.  That routine MUST correspond to the actual capabilities
 511.369 + * of this module; no safety checks are made here.
 511.370 + */
 511.371 +
 511.372 +GLOBAL(void)
 511.373 +jinit_merged_upsampler (j_decompress_ptr cinfo)
 511.374 +{
 511.375 +  my_upsample_ptr upsample;
 511.376 +
 511.377 +  upsample = (my_upsample_ptr)
 511.378 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 511.379 +				SIZEOF(my_upsampler));
 511.380 +  cinfo->upsample = (struct jpeg_upsampler *) upsample;
 511.381 +  upsample->pub.start_pass = start_pass_merged_upsample;
 511.382 +  upsample->pub.need_context_rows = FALSE;
 511.383 +
 511.384 +  upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
 511.385 +
 511.386 +  if (cinfo->max_v_samp_factor == 2) {
 511.387 +    upsample->pub.upsample = merged_2v_upsample;
 511.388 +    upsample->upmethod = h2v2_merged_upsample;
 511.389 +    /* Allocate a spare row buffer */
 511.390 +    upsample->spare_row = (JSAMPROW)
 511.391 +      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 511.392 +		(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
 511.393 +  } else {
 511.394 +    upsample->pub.upsample = merged_1v_upsample;
 511.395 +    upsample->upmethod = h2v1_merged_upsample;
 511.396 +    /* No spare row needed */
 511.397 +    upsample->spare_row = NULL;
 511.398 +  }
 511.399 +
 511.400 +  build_ycc_rgb_table(cinfo);
 511.401 +}
 511.402 +
 511.403 +#endif /* UPSAMPLE_MERGING_SUPPORTED */
   512.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   512.2 +++ b/libs/libjpeg/jdphuff.c	Sat Feb 01 19:58:19 2014 +0200
   512.3 @@ -0,0 +1,668 @@
   512.4 +/*
   512.5 + * jdphuff.c
   512.6 + *
   512.7 + * Copyright (C) 1995-1997, Thomas G. Lane.
   512.8 + * This file is part of the Independent JPEG Group's software.
   512.9 + * For conditions of distribution and use, see the accompanying README file.
  512.10 + *
  512.11 + * This file contains Huffman entropy decoding routines for progressive JPEG.
  512.12 + *
  512.13 + * Much of the complexity here has to do with supporting input suspension.
  512.14 + * If the data source module demands suspension, we want to be able to back
  512.15 + * up to the start of the current MCU.  To do this, we copy state variables
  512.16 + * into local working storage, and update them back to the permanent
  512.17 + * storage only upon successful completion of an MCU.
  512.18 + */
  512.19 +
  512.20 +#define JPEG_INTERNALS
  512.21 +#include "jinclude.h"
  512.22 +#include "jpeglib.h"
  512.23 +#include "jdhuff.h"		/* Declarations shared with jdhuff.c */
  512.24 +
  512.25 +
  512.26 +#ifdef D_PROGRESSIVE_SUPPORTED
  512.27 +
  512.28 +/*
  512.29 + * Expanded entropy decoder object for progressive Huffman decoding.
  512.30 + *
  512.31 + * The savable_state subrecord contains fields that change within an MCU,
  512.32 + * but must not be updated permanently until we complete the MCU.
  512.33 + */
  512.34 +
  512.35 +typedef struct {
  512.36 +  unsigned int EOBRUN;			/* remaining EOBs in EOBRUN */
  512.37 +  int last_dc_val[MAX_COMPS_IN_SCAN];	/* last DC coef for each component */
  512.38 +} savable_state;
  512.39 +
  512.40 +/* This macro is to work around compilers with missing or broken
  512.41 + * structure assignment.  You'll need to fix this code if you have
  512.42 + * such a compiler and you change MAX_COMPS_IN_SCAN.
  512.43 + */
  512.44 +
  512.45 +#ifndef NO_STRUCT_ASSIGN
  512.46 +#define ASSIGN_STATE(dest,src)  ((dest) = (src))
  512.47 +#else
  512.48 +#if MAX_COMPS_IN_SCAN == 4
  512.49 +#define ASSIGN_STATE(dest,src)  \
  512.50 +	((dest).EOBRUN = (src).EOBRUN, \
  512.51 +	 (dest).last_dc_val[0] = (src).last_dc_val[0], \
  512.52 +	 (dest).last_dc_val[1] = (src).last_dc_val[1], \
  512.53 +	 (dest).last_dc_val[2] = (src).last_dc_val[2], \
  512.54 +	 (dest).last_dc_val[3] = (src).last_dc_val[3])
  512.55 +#endif
  512.56 +#endif
  512.57 +
  512.58 +
  512.59 +typedef struct {
  512.60 +  struct jpeg_entropy_decoder pub; /* public fields */
  512.61 +
  512.62 +  /* These fields are loaded into local variables at start of each MCU.
  512.63 +   * In case of suspension, we exit WITHOUT updating them.
  512.64 +   */
  512.65 +  bitread_perm_state bitstate;	/* Bit buffer at start of MCU */
  512.66 +  savable_state saved;		/* Other state at start of MCU */
  512.67 +
  512.68 +  /* These fields are NOT loaded into local working state. */
  512.69 +  unsigned int restarts_to_go;	/* MCUs left in this restart interval */
  512.70 +
  512.71 +  /* Pointers to derived tables (these workspaces have image lifespan) */
  512.72 +  d_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
  512.73 +
  512.74 +  d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */
  512.75 +} phuff_entropy_decoder;
  512.76 +
  512.77 +typedef phuff_entropy_decoder * phuff_entropy_ptr;
  512.78 +
  512.79 +/* Forward declarations */
  512.80 +METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo,
  512.81 +					    JBLOCKROW *MCU_data));
  512.82 +METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo,
  512.83 +					    JBLOCKROW *MCU_data));
  512.84 +METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo,
  512.85 +					     JBLOCKROW *MCU_data));
  512.86 +METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo,
  512.87 +					     JBLOCKROW *MCU_data));
  512.88 +
  512.89 +
  512.90 +/*
  512.91 + * Initialize for a Huffman-compressed scan.
  512.92 + */
  512.93 +
  512.94 +METHODDEF(void)
  512.95 +start_pass_phuff_decoder (j_decompress_ptr cinfo)
  512.96 +{
  512.97 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
  512.98 +  boolean is_DC_band, bad;
  512.99 +  int ci, coefi, tbl;
 512.100 +  int *coef_bit_ptr;
 512.101 +  jpeg_component_info * compptr;
 512.102 +
 512.103 +  is_DC_band = (cinfo->Ss == 0);
 512.104 +
 512.105 +  /* Validate scan parameters */
 512.106 +  bad = FALSE;
 512.107 +  if (is_DC_band) {
 512.108 +    if (cinfo->Se != 0)
 512.109 +      bad = TRUE;
 512.110 +  } else {
 512.111 +    /* need not check Ss/Se < 0 since they came from unsigned bytes */
 512.112 +    if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2)
 512.113 +      bad = TRUE;
 512.114 +    /* AC scans may have only one component */
 512.115 +    if (cinfo->comps_in_scan != 1)
 512.116 +      bad = TRUE;
 512.117 +  }
 512.118 +  if (cinfo->Ah != 0) {
 512.119 +    /* Successive approximation refinement scan: must have Al = Ah-1. */
 512.120 +    if (cinfo->Al != cinfo->Ah-1)
 512.121 +      bad = TRUE;
 512.122 +  }
 512.123 +  if (cinfo->Al > 13)		/* need not check for < 0 */
 512.124 +    bad = TRUE;
 512.125 +  /* Arguably the maximum Al value should be less than 13 for 8-bit precision,
 512.126 +   * but the spec doesn't say so, and we try to be liberal about what we
 512.127 +   * accept.  Note: large Al values could result in out-of-range DC
 512.128 +   * coefficients during early scans, leading to bizarre displays due to
 512.129 +   * overflows in the IDCT math.  But we won't crash.
 512.130 +   */
 512.131 +  if (bad)
 512.132 +    ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
 512.133 +	     cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
 512.134 +  /* Update progression status, and verify that scan order is legal.
 512.135 +   * Note that inter-scan inconsistencies are treated as warnings
 512.136 +   * not fatal errors ... not clear if this is right way to behave.
 512.137 +   */
 512.138 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 512.139 +    int cindex = cinfo->cur_comp_info[ci]->component_index;
 512.140 +    coef_bit_ptr = & cinfo->coef_bits[cindex][0];
 512.141 +    if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
 512.142 +      WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
 512.143 +    for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
 512.144 +      int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
 512.145 +      if (cinfo->Ah != expected)
 512.146 +	WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
 512.147 +      coef_bit_ptr[coefi] = cinfo->Al;
 512.148 +    }
 512.149 +  }
 512.150 +
 512.151 +  /* Select MCU decoding routine */
 512.152 +  if (cinfo->Ah == 0) {
 512.153 +    if (is_DC_band)
 512.154 +      entropy->pub.decode_mcu = decode_mcu_DC_first;
 512.155 +    else
 512.156 +      entropy->pub.decode_mcu = decode_mcu_AC_first;
 512.157 +  } else {
 512.158 +    if (is_DC_band)
 512.159 +      entropy->pub.decode_mcu = decode_mcu_DC_refine;
 512.160 +    else
 512.161 +      entropy->pub.decode_mcu = decode_mcu_AC_refine;
 512.162 +  }
 512.163 +
 512.164 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 512.165 +    compptr = cinfo->cur_comp_info[ci];
 512.166 +    /* Make sure requested tables are present, and compute derived tables.
 512.167 +     * We may build same derived table more than once, but it's not expensive.
 512.168 +     */
 512.169 +    if (is_DC_band) {
 512.170 +      if (cinfo->Ah == 0) {	/* DC refinement needs no table */
 512.171 +	tbl = compptr->dc_tbl_no;
 512.172 +	jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
 512.173 +				& entropy->derived_tbls[tbl]);
 512.174 +      }
 512.175 +    } else {
 512.176 +      tbl = compptr->ac_tbl_no;
 512.177 +      jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
 512.178 +			      & entropy->derived_tbls[tbl]);
 512.179 +      /* remember the single active table */
 512.180 +      entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
 512.181 +    }
 512.182 +    /* Initialize DC predictions to 0 */
 512.183 +    entropy->saved.last_dc_val[ci] = 0;
 512.184 +  }
 512.185 +
 512.186 +  /* Initialize bitread state variables */
 512.187 +  entropy->bitstate.bits_left = 0;
 512.188 +  entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
 512.189 +  entropy->pub.insufficient_data = FALSE;
 512.190 +
 512.191 +  /* Initialize private state variables */
 512.192 +  entropy->saved.EOBRUN = 0;
 512.193 +
 512.194 +  /* Initialize restart counter */
 512.195 +  entropy->restarts_to_go = cinfo->restart_interval;
 512.196 +}
 512.197 +
 512.198 +
 512.199 +/*
 512.200 + * Figure F.12: extend sign bit.
 512.201 + * On some machines, a shift and add will be faster than a table lookup.
 512.202 + */
 512.203 +
 512.204 +#ifdef AVOID_TABLES
 512.205 +
 512.206 +#define HUFF_EXTEND(x,s)  ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
 512.207 +
 512.208 +#else
 512.209 +
 512.210 +#define HUFF_EXTEND(x,s)  ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
 512.211 +
 512.212 +static const int extend_test[16] =   /* entry n is 2**(n-1) */
 512.213 +  { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
 512.214 +    0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
 512.215 +
 512.216 +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
 512.217 +  { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
 512.218 +    ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
 512.219 +    ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
 512.220 +    ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
 512.221 +
 512.222 +#endif /* AVOID_TABLES */
 512.223 +
 512.224 +
 512.225 +/*
 512.226 + * Check for a restart marker & resynchronize decoder.
 512.227 + * Returns FALSE if must suspend.
 512.228 + */
 512.229 +
 512.230 +LOCAL(boolean)
 512.231 +process_restart (j_decompress_ptr cinfo)
 512.232 +{
 512.233 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 512.234 +  int ci;
 512.235 +
 512.236 +  /* Throw away any unused bits remaining in bit buffer; */
 512.237 +  /* include any full bytes in next_marker's count of discarded bytes */
 512.238 +  cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
 512.239 +  entropy->bitstate.bits_left = 0;
 512.240 +
 512.241 +  /* Advance past the RSTn marker */
 512.242 +  if (! (*cinfo->marker->read_restart_marker) (cinfo))
 512.243 +    return FALSE;
 512.244 +
 512.245 +  /* Re-initialize DC predictions to 0 */
 512.246 +  for (ci = 0; ci < cinfo->comps_in_scan; ci++)
 512.247 +    entropy->saved.last_dc_val[ci] = 0;
 512.248 +  /* Re-init EOB run count, too */
 512.249 +  entropy->saved.EOBRUN = 0;
 512.250 +
 512.251 +  /* Reset restart counter */
 512.252 +  entropy->restarts_to_go = cinfo->restart_interval;
 512.253 +
 512.254 +  /* Reset out-of-data flag, unless read_restart_marker left us smack up
 512.255 +   * against a marker.  In that case we will end up treating the next data
 512.256 +   * segment as empty, and we can avoid producing bogus output pixels by
 512.257 +   * leaving the flag set.
 512.258 +   */
 512.259 +  if (cinfo->unread_marker == 0)
 512.260 +    entropy->pub.insufficient_data = FALSE;
 512.261 +
 512.262 +  return TRUE;
 512.263 +}
 512.264 +
 512.265 +
 512.266 +/*
 512.267 + * Huffman MCU decoding.
 512.268 + * Each of these routines decodes and returns one MCU's worth of
 512.269 + * Huffman-compressed coefficients. 
 512.270 + * The coefficients are reordered from zigzag order into natural array order,
 512.271 + * but are not dequantized.
 512.272 + *
 512.273 + * The i'th block of the MCU is stored into the block pointed to by
 512.274 + * MCU_data[i].  WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
 512.275 + *
 512.276 + * We return FALSE if data source requested suspension.  In that case no
 512.277 + * changes have been made to permanent state.  (Exception: some output
 512.278 + * coefficients may already have been assigned.  This is harmless for
 512.279 + * spectral selection, since we'll just re-assign them on the next call.
 512.280 + * Successive approximation AC refinement has to be more careful, however.)
 512.281 + */
 512.282 +
 512.283 +/*
 512.284 + * MCU decoding for DC initial scan (either spectral selection,
 512.285 + * or first pass of successive approximation).
 512.286 + */
 512.287 +
 512.288 +METHODDEF(boolean)
 512.289 +decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 512.290 +{   
 512.291 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 512.292 +  int Al = cinfo->Al;
 512.293 +  register int s, r;
 512.294 +  int blkn, ci;
 512.295 +  JBLOCKROW block;
 512.296 +  BITREAD_STATE_VARS;
 512.297 +  savable_state state;
 512.298 +  d_derived_tbl * tbl;
 512.299 +  jpeg_component_info * compptr;
 512.300 +
 512.301 +  /* Process restart marker if needed; may have to suspend */
 512.302 +  if (cinfo->restart_interval) {
 512.303 +    if (entropy->restarts_to_go == 0)
 512.304 +      if (! process_restart(cinfo))
 512.305 +	return FALSE;
 512.306 +  }
 512.307 +
 512.308 +  /* If we've run out of data, just leave the MCU set to zeroes.
 512.309 +   * This way, we return uniform gray for the remainder of the segment.
 512.310 +   */
 512.311 +  if (! entropy->pub.insufficient_data) {
 512.312 +
 512.313 +    /* Load up working state */
 512.314 +    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
 512.315 +    ASSIGN_STATE(state, entropy->saved);
 512.316 +
 512.317 +    /* Outer loop handles each block in the MCU */
 512.318 +
 512.319 +    for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
 512.320 +      block = MCU_data[blkn];
 512.321 +      ci = cinfo->MCU_membership[blkn];
 512.322 +      compptr = cinfo->cur_comp_info[ci];
 512.323 +      tbl = entropy->derived_tbls[compptr->dc_tbl_no];
 512.324 +
 512.325 +      /* Decode a single block's worth of coefficients */
 512.326 +
 512.327 +      /* Section F.2.2.1: decode the DC coefficient difference */
 512.328 +      HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
 512.329 +      if (s) {
 512.330 +	CHECK_BIT_BUFFER(br_state, s, return FALSE);
 512.331 +	r = GET_BITS(s);
 512.332 +	s = HUFF_EXTEND(r, s);
 512.333 +      }
 512.334 +
 512.335 +      /* Convert DC difference to actual value, update last_dc_val */
 512.336 +      s += state.last_dc_val[ci];
 512.337 +      state.last_dc_val[ci] = s;
 512.338 +      /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
 512.339 +      (*block)[0] = (JCOEF) (s << Al);
 512.340 +    }
 512.341 +
 512.342 +    /* Completed MCU, so update state */
 512.343 +    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
 512.344 +    ASSIGN_STATE(entropy->saved, state);
 512.345 +  }
 512.346 +
 512.347 +  /* Account for restart interval (no-op if not using restarts) */
 512.348 +  entropy->restarts_to_go--;
 512.349 +
 512.350 +  return TRUE;
 512.351 +}
 512.352 +
 512.353 +
 512.354 +/*
 512.355 + * MCU decoding for AC initial scan (either spectral selection,
 512.356 + * or first pass of successive approximation).
 512.357 + */
 512.358 +
 512.359 +METHODDEF(boolean)
 512.360 +decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 512.361 +{   
 512.362 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 512.363 +  int Se = cinfo->Se;
 512.364 +  int Al = cinfo->Al;
 512.365 +  register int s, k, r;
 512.366 +  unsigned int EOBRUN;
 512.367 +  JBLOCKROW block;
 512.368 +  BITREAD_STATE_VARS;
 512.369 +  d_derived_tbl * tbl;
 512.370 +
 512.371 +  /* Process restart marker if needed; may have to suspend */
 512.372 +  if (cinfo->restart_interval) {
 512.373 +    if (entropy->restarts_to_go == 0)
 512.374 +      if (! process_restart(cinfo))
 512.375 +	return FALSE;
 512.376 +  }
 512.377 +
 512.378 +  /* If we've run out of data, just leave the MCU set to zeroes.
 512.379 +   * This way, we return uniform gray for the remainder of the segment.
 512.380 +   */
 512.381 +  if (! entropy->pub.insufficient_data) {
 512.382 +
 512.383 +    /* Load up working state.
 512.384 +     * We can avoid loading/saving bitread state if in an EOB run.
 512.385 +     */
 512.386 +    EOBRUN = entropy->saved.EOBRUN;	/* only part of saved state we need */
 512.387 +
 512.388 +    /* There is always only one block per MCU */
 512.389 +
 512.390 +    if (EOBRUN > 0)		/* if it's a band of zeroes... */
 512.391 +      EOBRUN--;			/* ...process it now (we do nothing) */
 512.392 +    else {
 512.393 +      BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
 512.394 +      block = MCU_data[0];
 512.395 +      tbl = entropy->ac_derived_tbl;
 512.396 +
 512.397 +      for (k = cinfo->Ss; k <= Se; k++) {
 512.398 +	HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
 512.399 +	r = s >> 4;
 512.400 +	s &= 15;
 512.401 +	if (s) {
 512.402 +	  k += r;
 512.403 +	  CHECK_BIT_BUFFER(br_state, s, return FALSE);
 512.404 +	  r = GET_BITS(s);
 512.405 +	  s = HUFF_EXTEND(r, s);
 512.406 +	  /* Scale and output coefficient in natural (dezigzagged) order */
 512.407 +	  (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
 512.408 +	} else {
 512.409 +	  if (r == 15) {	/* ZRL */
 512.410 +	    k += 15;		/* skip 15 zeroes in band */
 512.411 +	  } else {		/* EOBr, run length is 2^r + appended bits */
 512.412 +	    EOBRUN = 1 << r;
 512.413 +	    if (r) {		/* EOBr, r > 0 */
 512.414 +	      CHECK_BIT_BUFFER(br_state, r, return FALSE);
 512.415 +	      r = GET_BITS(r);
 512.416 +	      EOBRUN += r;
 512.417 +	    }
 512.418 +	    EOBRUN--;		/* this band is processed at this moment */
 512.419 +	    break;		/* force end-of-band */
 512.420 +	  }
 512.421 +	}
 512.422 +      }
 512.423 +
 512.424 +      BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
 512.425 +    }
 512.426 +
 512.427 +    /* Completed MCU, so update state */
 512.428 +    entropy->saved.EOBRUN = EOBRUN;	/* only part of saved state we need */
 512.429 +  }
 512.430 +
 512.431 +  /* Account for restart interval (no-op if not using restarts) */
 512.432 +  entropy->restarts_to_go--;
 512.433 +
 512.434 +  return TRUE;
 512.435 +}
 512.436 +
 512.437 +
 512.438 +/*
 512.439 + * MCU decoding for DC successive approximation refinement scan.
 512.440 + * Note: we assume such scans can be multi-component, although the spec
 512.441 + * is not very clear on the point.
 512.442 + */
 512.443 +
 512.444 +METHODDEF(boolean)
 512.445 +decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 512.446 +{   
 512.447 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 512.448 +  int p1 = 1 << cinfo->Al;	/* 1 in the bit position being coded */
 512.449 +  int blkn;
 512.450 +  JBLOCKROW block;
 512.451 +  BITREAD_STATE_VARS;
 512.452 +
 512.453 +  /* Process restart marker if needed; may have to suspend */
 512.454 +  if (cinfo->restart_interval) {
 512.455 +    if (entropy->restarts_to_go == 0)
 512.456 +      if (! process_restart(cinfo))
 512.457 +	return FALSE;
 512.458 +  }
 512.459 +
 512.460 +  /* Not worth the cycles to check insufficient_data here,
 512.461 +   * since we will not change the data anyway if we read zeroes.
 512.462 +   */
 512.463 +
 512.464 +  /* Load up working state */
 512.465 +  BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
 512.466 +
 512.467 +  /* Outer loop handles each block in the MCU */
 512.468 +
 512.469 +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
 512.470 +    block = MCU_data[blkn];
 512.471 +
 512.472 +    /* Encoded data is simply the next bit of the two's-complement DC value */
 512.473 +    CHECK_BIT_BUFFER(br_state, 1, return FALSE);
 512.474 +    if (GET_BITS(1))
 512.475 +      (*block)[0] |= p1;
 512.476 +    /* Note: since we use |=, repeating the assignment later is safe */
 512.477 +  }
 512.478 +
 512.479 +  /* Completed MCU, so update state */
 512.480 +  BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
 512.481 +
 512.482 +  /* Account for restart interval (no-op if not using restarts) */
 512.483 +  entropy->restarts_to_go--;
 512.484 +
 512.485 +  return TRUE;
 512.486 +}
 512.487 +
 512.488 +
 512.489 +/*
 512.490 + * MCU decoding for AC successive approximation refinement scan.
 512.491 + */
 512.492 +
 512.493 +METHODDEF(boolean)
 512.494 +decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 512.495 +{   
 512.496 +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
 512.497 +  int Se = cinfo->Se;
 512.498 +  int p1 = 1 << cinfo->Al;	/* 1 in the bit position being coded */
 512.499 +  int m1 = (-1) << cinfo->Al;	/* -1 in the bit position being coded */
 512.500 +  register int s, k, r;
 512.501 +  unsigned int EOBRUN;
 512.502 +  JBLOCKROW block;
 512.503 +  JCOEFPTR thiscoef;
 512.504 +  BITREAD_STATE_VARS;
 512.505 +  d_derived_tbl * tbl;
 512.506 +  int num_newnz;
 512.507 +  int newnz_pos[DCTSIZE2];
 512.508 +
 512.509 +  /* Process restart marker if needed; may have to suspend */
 512.510 +  if (cinfo->restart_interval) {
 512.511 +    if (entropy->restarts_to_go == 0)
 512.512 +      if (! process_restart(cinfo))
 512.513 +	return FALSE;
 512.514 +  }
 512.515 +
 512.516 +  /* If we've run out of data, don't modify the MCU.
 512.517 +   */
 512.518 +  if (! entropy->pub.insufficient_data) {
 512.519 +
 512.520 +    /* Load up working state */
 512.521 +    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
 512.522 +    EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
 512.523 +
 512.524 +    /* There is always only one block per MCU */
 512.525 +    block = MCU_data[0];
 512.526 +    tbl = entropy->ac_derived_tbl;
 512.527 +
 512.528 +    /* If we are forced to suspend, we must undo the assignments to any newly
 512.529 +     * nonzero coefficients in the block, because otherwise we'd get confused
 512.530 +     * next time about which coefficients were already nonzero.
 512.531 +     * But we need not undo addition of bits to already-nonzero coefficients;
 512.532 +     * instead, we can test the current bit to see if we already did it.
 512.533 +     */
 512.534 +    num_newnz = 0;
 512.535 +
 512.536 +    /* initialize coefficient loop counter to start of band */
 512.537 +    k = cinfo->Ss;
 512.538 +
 512.539 +    if (EOBRUN == 0) {
 512.540 +      for (; k <= Se; k++) {
 512.541 +	HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
 512.542 +	r = s >> 4;
 512.543 +	s &= 15;
 512.544 +	if (s) {
 512.545 +	  if (s != 1)		/* size of new coef should always be 1 */
 512.546 +	    WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
 512.547 +	  CHECK_BIT_BUFFER(br_state, 1, goto undoit);
 512.548 +	  if (GET_BITS(1))
 512.549 +	    s = p1;		/* newly nonzero coef is positive */
 512.550 +	  else
 512.551 +	    s = m1;		/* newly nonzero coef is negative */
 512.552 +	} else {
 512.553 +	  if (r != 15) {
 512.554 +	    EOBRUN = 1 << r;	/* EOBr, run length is 2^r + appended bits */
 512.555 +	    if (r) {
 512.556 +	      CHECK_BIT_BUFFER(br_state, r, goto undoit);
 512.557 +	      r = GET_BITS(r);
 512.558 +	      EOBRUN += r;
 512.559 +	    }
 512.560 +	    break;		/* rest of block is handled by EOB logic */
 512.561 +	  }
 512.562 +	  /* note s = 0 for processing ZRL */
 512.563 +	}
 512.564 +	/* Advance over already-nonzero coefs and r still-zero coefs,
 512.565 +	 * appending correction bits to the nonzeroes.  A correction bit is 1
 512.566 +	 * if the absolute value of the coefficient must be increased.
 512.567 +	 */
 512.568 +	do {
 512.569 +	  thiscoef = *block + jpeg_natural_order[k];
 512.570 +	  if (*thiscoef != 0) {
 512.571 +	    CHECK_BIT_BUFFER(br_state, 1, goto undoit);
 512.572 +	    if (GET_BITS(1)) {
 512.573 +	      if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
 512.574 +		if (*thiscoef >= 0)
 512.575 +		  *thiscoef += p1;
 512.576 +		else
 512.577 +		  *thiscoef += m1;
 512.578 +	      }
 512.579 +	    }
 512.580 +	  } else {
 512.581 +	    if (--r < 0)
 512.582 +	      break;		/* reached target zero coefficient */
 512.583 +	  }
 512.584 +	  k++;
 512.585 +	} while (k <= Se);
 512.586 +	if (s) {
 512.587 +	  int pos = jpeg_natural_order[k];
 512.588 +	  /* Output newly nonzero coefficient */
 512.589 +	  (*block)[pos] = (JCOEF) s;
 512.590 +	  /* Remember its position in case we have to suspend */
 512.591 +	  newnz_pos[num_newnz++] = pos;
 512.592 +	}
 512.593 +      }
 512.594 +    }
 512.595 +
 512.596 +    if (EOBRUN > 0) {
 512.597 +      /* Scan any remaining coefficient positions after the end-of-band
 512.598 +       * (the last newly nonzero coefficient, if any).  Append a correction
 512.599 +       * bit to each already-nonzero coefficient.  A correction bit is 1
 512.600 +       * if the absolute value of the coefficient must be increased.
 512.601 +       */
 512.602 +      for (; k <= Se; k++) {
 512.603 +	thiscoef = *block + jpeg_natural_order[k];
 512.604 +	if (*thiscoef != 0) {
 512.605 +	  CHECK_BIT_BUFFER(br_state, 1, goto undoit);
 512.606 +	  if (GET_BITS(1)) {
 512.607 +	    if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
 512.608 +	      if (*thiscoef >= 0)
 512.609 +		*thiscoef += p1;
 512.610 +	      else
 512.611 +		*thiscoef += m1;
 512.612 +	    }
 512.613 +	  }
 512.614 +	}
 512.615 +      }
 512.616 +      /* Count one block completed in EOB run */
 512.617 +      EOBRUN--;
 512.618 +    }
 512.619 +
 512.620 +    /* Completed MCU, so update state */
 512.621 +    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
 512.622 +    entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
 512.623 +  }
 512.624 +
 512.625 +  /* Account for restart interval (no-op if not using restarts) */
 512.626 +  entropy->restarts_to_go--;
 512.627 +
 512.628 +  return TRUE;
 512.629 +
 512.630 +undoit:
 512.631 +  /* Re-zero any output coefficients that we made newly nonzero */
 512.632 +  while (num_newnz > 0)
 512.633 +    (*block)[newnz_pos[--num_newnz]] = 0;
 512.634 +
 512.635 +  return FALSE;
 512.636 +}
 512.637 +
 512.638 +
 512.639 +/*
 512.640 + * Module initialization routine for progressive Huffman entropy decoding.
 512.641 + */
 512.642 +
 512.643 +GLOBAL(void)
 512.644 +jinit_phuff_decoder (j_decompress_ptr cinfo)
 512.645 +{
 512.646 +  phuff_entropy_ptr entropy;
 512.647 +  int *coef_bit_ptr;
 512.648 +  int ci, i;
 512.649 +
 512.650 +  entropy = (phuff_entropy_ptr)
 512.651 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 512.652 +				SIZEOF(phuff_entropy_decoder));
 512.653 +  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
 512.654 +  entropy->pub.start_pass = start_pass_phuff_decoder;
 512.655 +
 512.656 +  /* Mark derived tables unallocated */
 512.657 +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
 512.658 +    entropy->derived_tbls[i] = NULL;
 512.659 +  }
 512.660 +
 512.661 +  /* Create progression status table */
 512.662 +  cinfo->coef_bits = (int (*)[DCTSIZE2])
 512.663 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 512.664 +				cinfo->num_components*DCTSIZE2*SIZEOF(int));
 512.665 +  coef_bit_ptr = & cinfo->coef_bits[0][0];
 512.666 +  for (ci = 0; ci < cinfo->num_components; ci++) 
 512.667 +    for (i = 0; i < DCTSIZE2; i++)
 512.668 +      *coef_bit_ptr++ = -1;
 512.669 +}
 512.670 +
 512.671 +#endif /* D_PROGRESSIVE_SUPPORTED */
   513.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   513.2 +++ b/libs/libjpeg/jdpostct.c	Sat Feb 01 19:58:19 2014 +0200
   513.3 @@ -0,0 +1,290 @@
   513.4 +/*
   513.5 + * jdpostct.c
   513.6 + *
   513.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   513.8 + * This file is part of the Independent JPEG Group's software.
   513.9 + * For conditions of distribution and use, see the accompanying README file.
  513.10 + *
  513.11 + * This file contains the decompression postprocessing controller.
  513.12 + * This controller manages the upsampling, color conversion, and color
  513.13 + * quantization/reduction steps; specifically, it controls the buffering
  513.14 + * between upsample/color conversion and color quantization/reduction.
  513.15 + *
  513.16 + * If no color quantization/reduction is required, then this module has no
  513.17 + * work to do, and it just hands off to the upsample/color conversion code.
  513.18 + * An integrated upsample/convert/quantize process would replace this module
  513.19 + * entirely.
  513.20 + */
  513.21 +
  513.22 +#define JPEG_INTERNALS
  513.23 +#include "jinclude.h"
  513.24 +#include "jpeglib.h"
  513.25 +
  513.26 +
  513.27 +/* Private buffer controller object */
  513.28 +
  513.29 +typedef struct {
  513.30 +  struct jpeg_d_post_controller pub; /* public fields */
  513.31 +
  513.32 +  /* Color quantization source buffer: this holds output data from
  513.33 +   * the upsample/color conversion step to be passed to the quantizer.
  513.34 +   * For two-pass color quantization, we need a full-image buffer;
  513.35 +   * for one-pass operation, a strip buffer is sufficient.
  513.36 +   */
  513.37 +  jvirt_sarray_ptr whole_image;	/* virtual array, or NULL if one-pass */
  513.38 +  JSAMPARRAY buffer;		/* strip buffer, or current strip of virtual */
  513.39 +  JDIMENSION strip_height;	/* buffer size in rows */
  513.40 +  /* for two-pass mode only: */
  513.41 +  JDIMENSION starting_row;	/* row # of first row in current strip */
  513.42 +  JDIMENSION next_row;		/* index of next row to fill/empty in strip */
  513.43 +} my_post_controller;
  513.44 +
  513.45 +typedef my_post_controller * my_post_ptr;
  513.46 +
  513.47 +
  513.48 +/* Forward declarations */
  513.49 +METHODDEF(void) post_process_1pass
  513.50 +	JPP((j_decompress_ptr cinfo,
  513.51 +	     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  513.52 +	     JDIMENSION in_row_groups_avail,
  513.53 +	     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  513.54 +	     JDIMENSION out_rows_avail));
  513.55 +#ifdef QUANT_2PASS_SUPPORTED
  513.56 +METHODDEF(void) post_process_prepass
  513.57 +	JPP((j_decompress_ptr cinfo,
  513.58 +	     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  513.59 +	     JDIMENSION in_row_groups_avail,
  513.60 +	     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  513.61 +	     JDIMENSION out_rows_avail));
  513.62 +METHODDEF(void) post_process_2pass
  513.63 +	JPP((j_decompress_ptr cinfo,
  513.64 +	     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  513.65 +	     JDIMENSION in_row_groups_avail,
  513.66 +	     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  513.67 +	     JDIMENSION out_rows_avail));
  513.68 +#endif
  513.69 +
  513.70 +
  513.71 +/*
  513.72 + * Initialize for a processing pass.
  513.73 + */
  513.74 +
  513.75 +METHODDEF(void)
  513.76 +start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
  513.77 +{
  513.78 +  my_post_ptr post = (my_post_ptr) cinfo->post;
  513.79 +
  513.80 +  switch (pass_mode) {
  513.81 +  case JBUF_PASS_THRU:
  513.82 +    if (cinfo->quantize_colors) {
  513.83 +      /* Single-pass processing with color quantization. */
  513.84 +      post->pub.post_process_data = post_process_1pass;
  513.85 +      /* We could be doing buffered-image output before starting a 2-pass
  513.86 +       * color quantization; in that case, jinit_d_post_controller did not
  513.87 +       * allocate a strip buffer.  Use the virtual-array buffer as workspace.
  513.88 +       */
  513.89 +      if (post->buffer == NULL) {
  513.90 +	post->buffer = (*cinfo->mem->access_virt_sarray)
  513.91 +	  ((j_common_ptr) cinfo, post->whole_image,
  513.92 +	   (JDIMENSION) 0, post->strip_height, TRUE);
  513.93 +      }
  513.94 +    } else {
  513.95 +      /* For single-pass processing without color quantization,
  513.96 +       * I have no work to do; just call the upsampler directly.
  513.97 +       */
  513.98 +      post->pub.post_process_data = cinfo->upsample->upsample;
  513.99 +    }
 513.100 +    break;
 513.101 +#ifdef QUANT_2PASS_SUPPORTED
 513.102 +  case JBUF_SAVE_AND_PASS:
 513.103 +    /* First pass of 2-pass quantization */
 513.104 +    if (post->whole_image == NULL)
 513.105 +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 513.106 +    post->pub.post_process_data = post_process_prepass;
 513.107 +    break;
 513.108 +  case JBUF_CRANK_DEST:
 513.109 +    /* Second pass of 2-pass quantization */
 513.110 +    if (post->whole_image == NULL)
 513.111 +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 513.112 +    post->pub.post_process_data = post_process_2pass;
 513.113 +    break;
 513.114 +#endif /* QUANT_2PASS_SUPPORTED */
 513.115 +  default:
 513.116 +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 513.117 +    break;
 513.118 +  }
 513.119 +  post->starting_row = post->next_row = 0;
 513.120 +}
 513.121 +
 513.122 +
 513.123 +/*
 513.124 + * Process some data in the one-pass (strip buffer) case.
 513.125 + * This is used for color precision reduction as well as one-pass quantization.
 513.126 + */
 513.127 +
 513.128 +METHODDEF(void)
 513.129 +post_process_1pass (j_decompress_ptr cinfo,
 513.130 +		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
 513.131 +		    JDIMENSION in_row_groups_avail,
 513.132 +		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 513.133 +		    JDIMENSION out_rows_avail)
 513.134 +{
 513.135 +  my_post_ptr post = (my_post_ptr) cinfo->post;
 513.136 +  JDIMENSION num_rows, max_rows;
 513.137 +
 513.138 +  /* Fill the buffer, but not more than what we can dump out in one go. */
 513.139 +  /* Note we rely on the upsampler to detect bottom of image. */
 513.140 +  max_rows = out_rows_avail - *out_row_ctr;
 513.141 +  if (max_rows > post->strip_height)
 513.142 +    max_rows = post->strip_height;
 513.143 +  num_rows = 0;
 513.144 +  (*cinfo->upsample->upsample) (cinfo,
 513.145 +		input_buf, in_row_group_ctr, in_row_groups_avail,
 513.146 +		post->buffer, &num_rows, max_rows);
 513.147 +  /* Quantize and emit data. */
 513.148 +  (*cinfo->cquantize->color_quantize) (cinfo,
 513.149 +		post->buffer, output_buf + *out_row_ctr, (int) num_rows);
 513.150 +  *out_row_ctr += num_rows;
 513.151 +}
 513.152 +
 513.153 +
 513.154 +#ifdef QUANT_2PASS_SUPPORTED
 513.155 +
 513.156 +/*
 513.157 + * Process some data in the first pass of 2-pass quantization.
 513.158 + */
 513.159 +
 513.160 +METHODDEF(void)
 513.161 +post_process_prepass (j_decompress_ptr cinfo,
 513.162 +		      JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
 513.163 +		      JDIMENSION in_row_groups_avail,
 513.164 +		      JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 513.165 +		      JDIMENSION out_rows_avail)
 513.166 +{
 513.167 +  my_post_ptr post = (my_post_ptr) cinfo->post;
 513.168 +  JDIMENSION old_next_row, num_rows;
 513.169 +
 513.170 +  /* Reposition virtual buffer if at start of strip. */
 513.171 +  if (post->next_row == 0) {
 513.172 +    post->buffer = (*cinfo->mem->access_virt_sarray)
 513.173 +	((j_common_ptr) cinfo, post->whole_image,
 513.174 +	 post->starting_row, post->strip_height, TRUE);
 513.175 +  }
 513.176 +
 513.177 +  /* Upsample some data (up to a strip height's worth). */
 513.178 +  old_next_row = post->next_row;
 513.179 +  (*cinfo->upsample->upsample) (cinfo,
 513.180 +		input_buf, in_row_group_ctr, in_row_groups_avail,
 513.181 +		post->buffer, &post->next_row, post->strip_height);
 513.182 +
 513.183 +  /* Allow quantizer to scan new data.  No data is emitted, */
 513.184 +  /* but we advance out_row_ctr so outer loop can tell when we're done. */
 513.185 +  if (post->next_row > old_next_row) {
 513.186 +    num_rows = post->next_row - old_next_row;
 513.187 +    (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
 513.188 +					 (JSAMPARRAY) NULL, (int) num_rows);
 513.189 +    *out_row_ctr += num_rows;
 513.190 +  }
 513.191 +
 513.192 +  /* Advance if we filled the strip. */
 513.193 +  if (post->next_row >= post->strip_height) {
 513.194 +    post->starting_row += post->strip_height;
 513.195 +    post->next_row = 0;
 513.196 +  }
 513.197 +}
 513.198 +
 513.199 +
 513.200 +/*
 513.201 + * Process some data in the second pass of 2-pass quantization.
 513.202 + */
 513.203 +
 513.204 +METHODDEF(void)
 513.205 +post_process_2pass (j_decompress_ptr cinfo,
 513.206 +		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
 513.207 +		    JDIMENSION in_row_groups_avail,
 513.208 +		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 513.209 +		    JDIMENSION out_rows_avail)
 513.210 +{
 513.211 +  my_post_ptr post = (my_post_ptr) cinfo->post;
 513.212 +  JDIMENSION num_rows, max_rows;
 513.213 +
 513.214 +  /* Reposition virtual buffer if at start of strip. */
 513.215 +  if (post->next_row == 0) {
 513.216 +    post->buffer = (*cinfo->mem->access_virt_sarray)
 513.217 +	((j_common_ptr) cinfo, post->whole_image,
 513.218 +	 post->starting_row, post->strip_height, FALSE);
 513.219 +  }
 513.220 +
 513.221 +  /* Determine number of rows to emit. */
 513.222 +  num_rows = post->strip_height - post->next_row; /* available in strip */
 513.223 +  max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
 513.224 +  if (num_rows > max_rows)
 513.225 +    num_rows = max_rows;
 513.226 +  /* We have to check bottom of image here, can't depend on upsampler. */
 513.227 +  max_rows = cinfo->output_height - post->starting_row;
 513.228 +  if (num_rows > max_rows)
 513.229 +    num_rows = max_rows;
 513.230 +
 513.231 +  /* Quantize and emit data. */
 513.232 +  (*cinfo->cquantize->color_quantize) (cinfo,
 513.233 +		post->buffer + post->next_row, output_buf + *out_row_ctr,
 513.234 +		(int) num_rows);
 513.235 +  *out_row_ctr += num_rows;
 513.236 +
 513.237 +  /* Advance if we filled the strip. */
 513.238 +  post->next_row += num_rows;
 513.239 +  if (post->next_row >= post->strip_height) {
 513.240 +    post->starting_row += post->strip_height;
 513.241 +    post->next_row = 0;
 513.242 +  }
 513.243 +}
 513.244 +
 513.245 +#endif /* QUANT_2PASS_SUPPORTED */
 513.246 +
 513.247 +
 513.248 +/*
 513.249 + * Initialize postprocessing controller.
 513.250 + */
 513.251 +
 513.252 +GLOBAL(void)
 513.253 +jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
 513.254 +{
 513.255 +  my_post_ptr post;
 513.256 +
 513.257 +  post = (my_post_ptr)
 513.258 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 513.259 +				SIZEOF(my_post_controller));
 513.260 +  cinfo->post = (struct jpeg_d_post_controller *) post;
 513.261 +  post->pub.start_pass = start_pass_dpost;
 513.262 +  post->whole_image = NULL;	/* flag for no virtual arrays */
 513.263 +  post->buffer = NULL;		/* flag for no strip buffer */
 513.264 +
 513.265 +  /* Create the quantization buffer, if needed */
 513.266 +  if (cinfo->quantize_colors) {
 513.267 +    /* The buffer strip height is max_v_samp_factor, which is typically
 513.268 +     * an efficient number of rows for upsampling to return.
 513.269 +     * (In the presence of output rescaling, we might want to be smarter?)
 513.270 +     */
 513.271 +    post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
 513.272 +    if (need_full_buffer) {
 513.273 +      /* Two-pass color quantization: need full-image storage. */
 513.274 +      /* We round up the number of rows to a multiple of the strip height. */
 513.275 +#ifdef QUANT_2PASS_SUPPORTED
 513.276 +      post->whole_image = (*cinfo->mem->request_virt_sarray)
 513.277 +	((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
 513.278 +	 cinfo->output_width * cinfo->out_color_components,
 513.279 +	 (JDIMENSION) jround_up((long) cinfo->output_height,
 513.280 +				(long) post->strip_height),
 513.281 +	 post->strip_height);
 513.282 +#else
 513.283 +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 513.284 +#endif /* QUANT_2PASS_SUPPORTED */
 513.285 +    } else {
 513.286 +      /* One-pass color quantization: just make a strip buffer. */
 513.287 +      post->buffer = (*cinfo->mem->alloc_sarray)
 513.288 +	((j_common_ptr) cinfo, JPOOL_IMAGE,
 513.289 +	 cinfo->output_width * cinfo->out_color_components,
 513.290 +	 post->strip_height);
 513.291 +    }
 513.292 +  }
 513.293 +}
   514.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   514.2 +++ b/libs/libjpeg/jdsample.c	Sat Feb 01 19:58:19 2014 +0200
   514.3 @@ -0,0 +1,478 @@
   514.4 +/*
   514.5 + * jdsample.c
   514.6 + *
   514.7 + * Copyright (C) 1991-1996, Thomas G. Lane.
   514.8 + * This file is part of the Independent JPEG Group's software.
   514.9 + * For conditions of distribution and use, see the accompanying README file.
  514.10 + *
  514.11 + * This file contains upsampling routines.
  514.12 + *
  514.13 + * Upsampling input data is counted in "row groups".  A row group
  514.14 + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
  514.15 + * sample rows of each component.  Upsampling will normally produce
  514.16 + * max_v_samp_factor pixel rows from each row group (but this could vary
  514.17 + * if the upsampler is applying a scale factor of its own).
  514.18 + *
  514.19 + * An excellent reference for image resampling is
  514.20 + *   Digital Image Warping, George Wolberg, 1990.
  514.21 + *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
  514.22 + */
  514.23 +
  514.24 +#define JPEG_INTERNALS
  514.25 +#include "jinclude.h"
  514.26 +#include "jpeglib.h"
  514.27 +
  514.28 +
  514.29 +/* Pointer to routine to upsample a single component */
  514.30 +typedef JMETHOD(void, upsample1_ptr,
  514.31 +		(j_decompress_ptr cinfo, jpeg_component_info * compptr,
  514.32 +		 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
  514.33 +
  514.34 +/* Private subobject */
  514.35 +
  514.36 +typedef struct {
  514.37 +  struct jpeg_upsampler pub;	/* public fields */
  514.38 +
  514.39 +  /* Color conversion buffer.  When using separate upsampling and color
  514.40 +   * conversion steps, this buffer holds one upsampled row group until it
  514.41 +   * has been color converted and output.
  514.42 +   * Note: we do not allocate any storage for component(s) which are full-size,
  514.43 +   * ie do not need rescaling.  The corresponding entry of color_buf[] is
  514.44 +   * simply set to point to the input data array, thereby avoiding copying.
  514.45 +   */
  514.46 +  JSAMPARRAY color_buf[MAX_COMPONENTS];
  514.47 +
  514.48 +  /* Per-component upsampling method pointers */
  514.49 +  upsample1_ptr methods[MAX_COMPONENTS];
  514.50 +
  514.51 +  int next_row_out;		/* counts rows emitted from color_buf */
  514.52 +  JDIMENSION rows_to_go;	/* counts rows remaining in image */
  514.53 +
  514.54 +  /* Height of an input row group for each component. */
  514.55 +  int rowgroup_height[MAX_COMPONENTS];
  514.56 +
  514.57 +  /* These arrays save pixel expansion factors so that int_expand need not
  514.58 +   * recompute them each time.  They are unused for other upsampling methods.
  514.59 +   */
  514.60 +  UINT8 h_expand[MAX_COMPONENTS];
  514.61 +  UINT8 v_expand[MAX_COMPONENTS];
  514.62 +} my_upsampler;
  514.63 +
  514.64 +typedef my_upsampler * my_upsample_ptr;
  514.65 +
  514.66 +
  514.67 +/*
  514.68 + * Initialize for an upsampling pass.
  514.69 + */
  514.70 +
  514.71 +METHODDEF(void)
  514.72 +start_pass_upsample (j_decompress_ptr cinfo)
  514.73 +{
  514.74 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  514.75 +
  514.76 +  /* Mark the conversion buffer empty */
  514.77 +  upsample->next_row_out = cinfo->max_v_samp_factor;
  514.78 +  /* Initialize total-height counter for detecting bottom of image */
  514.79 +  upsample->rows_to_go = cinfo->output_height;
  514.80 +}
  514.81 +
  514.82 +
  514.83 +/*
  514.84 + * Control routine to do upsampling (and color conversion).
  514.85 + *
  514.86 + * In this version we upsample each component independently.
  514.87 + * We upsample one row group into the conversion buffer, then apply
  514.88 + * color conversion a row at a time.
  514.89 + */
  514.90 +
  514.91 +METHODDEF(void)
  514.92 +sep_upsample (j_decompress_ptr cinfo,
  514.93 +	      JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  514.94 +	      JDIMENSION in_row_groups_avail,
  514.95 +	      JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  514.96 +	      JDIMENSION out_rows_avail)
  514.97 +{
  514.98 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  514.99 +  int ci;
 514.100 +  jpeg_component_info * compptr;
 514.101 +  JDIMENSION num_rows;
 514.102 +
 514.103 +  /* Fill the conversion buffer, if it's empty */
 514.104 +  if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
 514.105 +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 514.106 +	 ci++, compptr++) {
 514.107 +      /* Invoke per-component upsample method.  Notice we pass a POINTER
 514.108 +       * to color_buf[ci], so that fullsize_upsample can change it.
 514.109 +       */
 514.110 +      (*upsample->methods[ci]) (cinfo, compptr,
 514.111 +	input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
 514.112 +	upsample->color_buf + ci);
 514.113 +    }
 514.114 +    upsample->next_row_out = 0;
 514.115 +  }
 514.116 +
 514.117 +  /* Color-convert and emit rows */
 514.118 +
 514.119 +  /* How many we have in the buffer: */
 514.120 +  num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
 514.121 +  /* Not more than the distance to the end of the image.  Need this test
 514.122 +   * in case the image height is not a multiple of max_v_samp_factor:
 514.123 +   */
 514.124 +  if (num_rows > upsample->rows_to_go) 
 514.125 +    num_rows = upsample->rows_to_go;
 514.126 +  /* And not more than what the client can accept: */
 514.127 +  out_rows_avail -= *out_row_ctr;
 514.128 +  if (num_rows > out_rows_avail)
 514.129 +    num_rows = out_rows_avail;
 514.130 +
 514.131 +  (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
 514.132 +				     (JDIMENSION) upsample->next_row_out,
 514.133 +				     output_buf + *out_row_ctr,
 514.134 +				     (int) num_rows);
 514.135 +
 514.136 +  /* Adjust counts */
 514.137 +  *out_row_ctr += num_rows;
 514.138 +  upsample->rows_to_go -= num_rows;
 514.139 +  upsample->next_row_out += num_rows;
 514.140 +  /* When the buffer is emptied, declare this input row group consumed */
 514.141 +  if (upsample->next_row_out >= cinfo->max_v_samp_factor)
 514.142 +    (*in_row_group_ctr)++;
 514.143 +}
 514.144 +
 514.145 +
 514.146 +/*
 514.147 + * These are the routines invoked by sep_upsample to upsample pixel values
 514.148 + * of a single component.  One row group is processed per call.
 514.149 + */
 514.150 +
 514.151 +
 514.152 +/*
 514.153 + * For full-size components, we just make color_buf[ci] point at the
 514.154 + * input buffer, and thus avoid copying any data.  Note that this is
 514.155 + * safe only because sep_upsample doesn't declare the input row group
 514.156 + * "consumed" until we are done color converting and emitting it.
 514.157 + */
 514.158 +
 514.159 +METHODDEF(void)
 514.160 +fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 514.161 +		   JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 514.162 +{
 514.163 +  *output_data_ptr = input_data;
 514.164 +}
 514.165 +
 514.166 +
 514.167 +/*
 514.168 + * This is a no-op version used for "uninteresting" components.
 514.169 + * These components will not be referenced by color conversion.
 514.170 + */
 514.171 +
 514.172 +METHODDEF(void)
 514.173 +noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 514.174 +	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 514.175 +{
 514.176 +  *output_data_ptr = NULL;	/* safety check */
 514.177 +}
 514.178 +
 514.179 +
 514.180 +/*
 514.181 + * This version handles any integral sampling ratios.
 514.182 + * This is not used for typical JPEG files, so it need not be fast.
 514.183 + * Nor, for that matter, is it particularly accurate: the algorithm is
 514.184 + * simple replication of the input pixel onto the corresponding output
 514.185 + * pixels.  The hi-falutin sampling literature refers to this as a
 514.186 + * "box filter".  A box filter tends to introduce visible artifacts,
 514.187 + * so if you are actually going to use 3:1 or 4:1 sampling ratios
 514.188 + * you would be well advised to improve this code.
 514.189 + */
 514.190 +
 514.191 +METHODDEF(void)
 514.192 +int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 514.193 +	      JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 514.194 +{
 514.195 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
 514.196 +  JSAMPARRAY output_data = *output_data_ptr;
 514.197 +  register JSAMPROW inptr, outptr;
 514.198 +  register JSAMPLE invalue;
 514.199 +  register int h;
 514.200 +  JSAMPROW outend;
 514.201 +  int h_expand, v_expand;
 514.202 +  int inrow, outrow;
 514.203 +
 514.204 +  h_expand = upsample->h_expand[compptr->component_index];
 514.205 +  v_expand = upsample->v_expand[compptr->component_index];
 514.206 +
 514.207 +  inrow = outrow = 0;
 514.208 +  while (outrow < cinfo->max_v_samp_factor) {
 514.209 +    /* Generate one output row with proper horizontal expansion */
 514.210 +    inptr = input_data[inrow];
 514.211 +    outptr = output_data[outrow];
 514.212 +    outend = outptr + cinfo->output_width;
 514.213 +    while (outptr < outend) {
 514.214 +      invalue = *inptr++;	/* don't need GETJSAMPLE() here */
 514.215 +      for (h = h_expand; h > 0; h--) {
 514.216 +	*outptr++ = invalue;
 514.217 +      }
 514.218 +    }
 514.219 +    /* Generate any additional output rows by duplicating the first one */
 514.220 +    if (v_expand > 1) {
 514.221 +      jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
 514.222 +			v_expand-1, cinfo->output_width);
 514.223 +    }
 514.224 +    inrow++;
 514.225 +    outrow += v_expand;
 514.226 +  }
 514.227 +}
 514.228 +
 514.229 +
 514.230 +/*
 514.231 + * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
 514.232 + * It's still a box filter.
 514.233 + */
 514.234 +
 514.235 +METHODDEF(void)
 514.236 +h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 514.237 +	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 514.238 +{
 514.239 +  JSAMPARRAY output_data = *output_data_ptr;
 514.240 +  register JSAMPROW inptr, outptr;
 514.241 +  register JSAMPLE invalue;
 514.242 +  JSAMPROW outend;
 514.243 +  int inrow;
 514.244 +
 514.245 +  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
 514.246 +    inptr = input_data[inrow];
 514.247 +    outptr = output_data[inrow];
 514.248 +    outend = outptr + cinfo->output_width;
 514.249 +    while (outptr < outend) {
 514.250 +      invalue = *inptr++;	/* don't need GETJSAMPLE() here */
 514.251 +      *outptr++ = invalue;
 514.252 +      *outptr++ = invalue;
 514.253 +    }
 514.254 +  }
 514.255 +}
 514.256 +
 514.257 +
 514.258 +/*
 514.259 + * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
 514.260 + * It's still a box filter.
 514.261 + */
 514.262 +
 514.263 +METHODDEF(void)
 514.264 +h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 514.265 +	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 514.266 +{
 514.267 +  JSAMPARRAY output_data = *output_data_ptr;
 514.268 +  register JSAMPROW inptr, outptr;
 514.269 +  register JSAMPLE invalue;
 514.270 +  JSAMPROW outend;
 514.271 +  int inrow, outrow;
 514.272 +
 514.273 +  inrow = outrow = 0;
 514.274 +  while (outrow < cinfo->max_v_samp_factor) {
 514.275 +    inptr = input_data[inrow];
 514.276 +    outptr = output_data[outrow];
 514.277 +    outend = outptr + cinfo->output_width;
 514.278 +    while (outptr < outend) {
 514.279 +      invalue = *inptr++;	/* don't need GETJSAMPLE() here */
 514.280 +      *outptr++ = invalue;
 514.281 +      *outptr++ = invalue;
 514.282 +    }
 514.283 +    jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
 514.284 +		      1, cinfo->output_width);
 514.285 +    inrow++;
 514.286 +    outrow += 2;
 514.287 +  }
 514.288 +}
 514.289 +
 514.290 +
 514.291 +/*
 514.292 + * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
 514.293 + *
 514.294 + * The upsampling algorithm is linear interpolation between pixel centers,
 514.295 + * also known as a "triangle filter".  This is a good compromise between
 514.296 + * speed and visual quality.  The centers of the output pixels are 1/4 and 3/4
 514.297 + * of the way between input pixel centers.
 514.298 + *
 514.299 + * A note about the "bias" calculations: when rounding fractional values to
 514.300 + * integer, we do not want to always round 0.5 up to the next integer.
 514.301 + * If we did that, we'd introduce a noticeable bias towards larger values.
 514.302 + * Instead, this code is arranged so that 0.5 will be rounded up or down at
 514.303 + * alternate pixel locations (a simple ordered dither pattern).
 514.304 + */
 514.305 +
 514.306 +METHODDEF(void)
 514.307 +h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 514.308 +		     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 514.309 +{
 514.310 +  JSAMPARRAY output_data = *output_data_ptr;
 514.311 +  register JSAMPROW inptr, outptr;
 514.312 +  register int invalue;
 514.313 +  register JDIMENSION colctr;
 514.314 +  int inrow;
 514.315 +
 514.316 +  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
 514.317 +    inptr = input_data[inrow];
 514.318 +    outptr = output_data[inrow];
 514.319 +    /* Special case for first column */
 514.320 +    invalue = GETJSAMPLE(*inptr++);
 514.321 +    *outptr++ = (JSAMPLE) invalue;
 514.322 +    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
 514.323 +
 514.324 +    for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
 514.325 +      /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
 514.326 +      invalue = GETJSAMPLE(*inptr++) * 3;
 514.327 +      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
 514.328 +      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
 514.329 +    }
 514.330 +
 514.331 +    /* Special case for last column */
 514.332 +    invalue = GETJSAMPLE(*inptr);
 514.333 +    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
 514.334 +    *outptr++ = (JSAMPLE) invalue;
 514.335 +  }
 514.336 +}
 514.337 +
 514.338 +
 514.339 +/*
 514.340 + * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
 514.341 + * Again a triangle filter; see comments for h2v1 case, above.
 514.342 + *
 514.343 + * It is OK for us to reference the adjacent input rows because we demanded
 514.344 + * context from the main buffer controller (see initialization code).
 514.345 + */
 514.346 +
 514.347 +METHODDEF(void)
 514.348 +h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 514.349 +		     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 514.350 +{
 514.351 +  JSAMPARRAY output_data = *output_data_ptr;
 514.352 +  register JSAMPROW inptr0, inptr1, outptr;
 514.353 +#if BITS_IN_JSAMPLE == 8
 514.354 +  register int thiscolsum, lastcolsum, nextcolsum;
 514.355 +#else
 514.356 +  register INT32 thiscolsum, lastcolsum, nextcolsum;
 514.357 +#endif
 514.358 +  register JDIMENSION colctr;
 514.359 +  int inrow, outrow, v;
 514.360 +
 514.361 +  inrow = outrow = 0;
 514.362 +  while (outrow < cinfo->max_v_samp_factor) {
 514.363 +    for (v = 0; v < 2; v++) {
 514.364 +      /* inptr0 points to nearest input row, inptr1 points to next nearest */
 514.365 +      inptr0 = input_data[inrow];
 514.366 +      if (v == 0)		/* next nearest is row above */
 514.367 +	inptr1 = input_data[inrow-1];
 514.368 +      else			/* next nearest is row below */
 514.369 +	inptr1 = input_data[inrow+1];
 514.370 +      outptr = output_data[outrow++];
 514.371 +
 514.372 +      /* Special case for first column */
 514.373 +      thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
 514.374 +      nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
 514.375 +      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
 514.376 +      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
 514.377 +      lastcolsum = thiscolsum; thiscolsum = nextcolsum;
 514.378 +
 514.379 +      for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
 514.380 +	/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
 514.381 +	/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
 514.382 +	nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
 514.383 +	*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
 514.384 +	*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
 514.385 +	lastcolsum = thiscolsum; thiscolsum = nextcolsum;
 514.386 +      }
 514.387 +
 514.388 +      /* Special case for last column */
 514.389 +      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
 514.390 +      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
 514.391 +    }
 514.392 +    inrow++;
 514.393 +  }
 514.394 +}
 514.395 +
 514.396 +
 514.397 +/*
 514.398 + * Module initialization routine for upsampling.
 514.399 + */
 514.400 +
 514.401 +GLOBAL(void)
 514.402 +jinit_upsampler (j_decompress_ptr cinfo)
 514.403 +{
 514.404 +  my_upsample_ptr upsample;
 514.405 +  int ci;
 514.406 +  jpeg_component_info * compptr;
 514.407 +  boolean need_buffer, do_fancy;
 514.408 +  int h_in_group, v_in_group, h_out_group, v_out_group;
 514.409 +
 514.410 +  upsample = (my_upsample_ptr)
 514.411 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 514.412 +				SIZEOF(my_upsampler));
 514.413 +  cinfo->upsample = (struct jpeg_upsampler *) upsample;
 514.414 +  upsample->pub.start_pass = start_pass_upsample;
 514.415 +  upsample->pub.upsample = sep_upsample;
 514.416 +  upsample->pub.need_context_rows = FALSE; /* until we find out differently */
 514.417 +
 514.418 +  if (cinfo->CCIR601_sampling)	/* this isn't supported */
 514.419 +    ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
 514.420 +
 514.421 +  /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
 514.422 +   * so don't ask for it.
 514.423 +   */
 514.424 +  do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
 514.425 +
 514.426 +  /* Verify we can handle the sampling factors, select per-component methods,
 514.427 +   * and create storage as needed.
 514.428 +   */
 514.429 +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 514.430 +       ci++, compptr++) {
 514.431 +    /* Compute size of an "input group" after IDCT scaling.  This many samples
 514.432 +     * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
 514.433 +     */
 514.434 +    h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
 514.435 +		 cinfo->min_DCT_scaled_size;
 514.436 +    v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
 514.437 +		 cinfo->min_DCT_scaled_size;
 514.438 +    h_out_group = cinfo->max_h_samp_factor;
 514.439 +    v_out_group = cinfo->max_v_samp_factor;
 514.440 +    upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
 514.441 +    need_buffer = TRUE;
 514.442 +    if (! compptr->component_needed) {
 514.443 +      /* Don't bother to upsample an uninteresting component. */
 514.444 +      upsample->methods[ci] = noop_upsample;
 514.445 +      need_buffer = FALSE;
 514.446 +    } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
 514.447 +      /* Fullsize components can be processed without any work. */
 514.448 +      upsample->methods[ci] = fullsize_upsample;
 514.449 +      need_buffer = FALSE;
 514.450 +    } else if (h_in_group * 2 == h_out_group &&
 514.451 +	       v_in_group == v_out_group) {
 514.452 +      /* Special cases for 2h1v upsampling */
 514.453 +      if (do_fancy && compptr->downsampled_width > 2)
 514.454 +	upsample->methods[ci] = h2v1_fancy_upsample;
 514.455 +      else
 514.456 +	upsample->methods[ci] = h2v1_upsample;
 514.457 +    } else if (h_in_group * 2 == h_out_group &&
 514.458 +	       v_in_group * 2 == v_out_group) {
 514.459 +      /* Special cases for 2h2v upsampling */
 514.460 +      if (do_fancy && compptr->downsampled_width > 2) {
 514.461 +	upsample->methods[ci] = h2v2_fancy_upsample;
 514.462 +	upsample->pub.need_context_rows = TRUE;
 514.463 +      } else
 514.464 +	upsample->methods[ci] = h2v2_upsample;
 514.465 +    } else if ((h_out_group % h_in_group) == 0 &&
 514.466 +	       (v_out_group % v_in_group) == 0) {
 514.467 +      /* Generic integral-factors upsampling method */
 514.468 +      upsample->methods[ci] = int_upsample;
 514.469 +      upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
 514.470 +      upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
 514.471 +    } else
 514.472 +      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
 514.473 +    if (need_buffer) {
 514.474 +      upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
 514.475 +	((j_common_ptr) cinfo, JPOOL_IMAGE,
 514.476 +	 (JDIMENSION) jround_up((long) cinfo->output_width,
 514.477 +				(long) cinfo->max_h_samp_factor),
 514.478 +	 (JDIMENSION) cinfo->max_v_samp_factor);
 514.479 +    }
 514.480 +  }
 514.481 +}
   515.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   515.2 +++ b/libs/libjpeg/jdtrans.c	Sat Feb 01 19:58:19 2014 +0200
   515.3 @@ -0,0 +1,143 @@
   515.4 +/*
   515.5 + * jdtrans.c
   515.6 + *
   515.7 + * Copyright (C) 1995-1997, Thomas G. Lane.
   515.8 + * This file is part of the Independent JPEG Group's software.
   515.9 + * For conditions of distribution and use, see the accompanying README file.
  515.10 + *
  515.11 + * This file contains library routines for transcoding decompression,
  515.12 + * that is, reading raw DCT coefficient arrays from an input JPEG file.
  515.13 + * The routines in jdapimin.c will also be needed by a transcoder.
  515.14 + */
  515.15 +
  515.16 +#define JPEG_INTERNALS
  515.17 +#include "jinclude.h"
  515.18 +#include "jpeglib.h"
  515.19 +
  515.20 +
  515.21 +/* Forward declarations */
  515.22 +LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
  515.23 +
  515.24 +
  515.25 +/*
  515.26 + * Read the coefficient arrays from a JPEG file.
  515.27 + * jpeg_read_header must be completed before calling this.
  515.28 + *
  515.29 + * The entire image is read into a set of virtual coefficient-block arrays,
  515.30 + * one per component.  The return value is a pointer to the array of
  515.31 + * virtual-array descriptors.  These can be manipulated directly via the
  515.32 + * JPEG memory manager, or handed off to jpeg_write_coefficients().
  515.33 + * To release the memory occupied by the virtual arrays, call
  515.34 + * jpeg_finish_decompress() when done with the data.
  515.35 + *
  515.36 + * An alternative usage is to simply obtain access to the coefficient arrays
  515.37 + * during a buffered-image-mode decompression operation.  This is allowed
  515.38 + * after any jpeg_finish_output() call.  The arrays can be accessed until
  515.39 + * jpeg_finish_decompress() is called.  (Note that any call to the library
  515.40 + * may reposition the arrays, so don't rely on access_virt_barray() results
  515.41 + * to stay valid across library calls.)
  515.42 + *
  515.43 + * Returns NULL if suspended.  This case need be checked only if
  515.44 + * a suspending data source is used.
  515.45 + */
  515.46 +
  515.47 +GLOBAL(jvirt_barray_ptr *)
  515.48 +jpeg_read_coefficients (j_decompress_ptr cinfo)
  515.49 +{
  515.50 +  if (cinfo->global_state == DSTATE_READY) {
  515.51 +    /* First call: initialize active modules */
  515.52 +    transdecode_master_selection(cinfo);
  515.53 +    cinfo->global_state = DSTATE_RDCOEFS;
  515.54 +  }
  515.55 +  if (cinfo->global_state == DSTATE_RDCOEFS) {
  515.56 +    /* Absorb whole file into the coef buffer */
  515.57 +    for (;;) {
  515.58 +      int retcode;
  515.59 +      /* Call progress monitor hook if present */
  515.60 +      if (cinfo->progress != NULL)
  515.61 +	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
  515.62 +      /* Absorb some more input */
  515.63 +      retcode = (*cinfo->inputctl->consume_input) (cinfo);
  515.64 +      if (retcode == JPEG_SUSPENDED)
  515.65 +	return NULL;
  515.66 +      if (retcode == JPEG_REACHED_EOI)
  515.67 +	break;
  515.68 +      /* Advance progress counter if appropriate */
  515.69 +      if (cinfo->progress != NULL &&
  515.70 +	  (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
  515.71 +	if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
  515.72 +	  /* startup underestimated number of scans; ratchet up one scan */
  515.73 +	  cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
  515.74 +	}
  515.75 +      }
  515.76 +    }
  515.77 +    /* Set state so that jpeg_finish_decompress does the right thing */
  515.78 +    cinfo->global_state = DSTATE_STOPPING;
  515.79 +  }
  515.80 +  /* At this point we should be in state DSTATE_STOPPING if being used
  515.81 +   * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
  515.82 +   * to the coefficients during a full buffered-image-mode decompression.
  515.83 +   */
  515.84 +  if ((cinfo->global_state == DSTATE_STOPPING ||
  515.85 +       cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
  515.86 +    return cinfo->coef->coef_arrays;
  515.87 +  }
  515.88 +  /* Oops, improper usage */
  515.89 +  ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  515.90 +  return NULL;			/* keep compiler happy */
  515.91 +}
  515.92 +
  515.93 +
  515.94 +/*
  515.95 + * Master selection of decompression modules for transcoding.
  515.96 + * This substitutes for jdmaster.c's initialization of the full decompressor.
  515.97 + */
  515.98 +
  515.99 +LOCAL(void)
 515.100 +transdecode_master_selection (j_decompress_ptr cinfo)
 515.101 +{
 515.102 +  /* This is effectively a buffered-image operation. */
 515.103 +  cinfo->buffered_image = TRUE;
 515.104 +
 515.105 +  /* Entropy decoding: either Huffman or arithmetic coding. */
 515.106 +  if (cinfo->arith_code) {
 515.107 +    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
 515.108 +  } else {
 515.109 +    if (cinfo->progressive_mode) {
 515.110 +#ifdef D_PROGRESSIVE_SUPPORTED
 515.111 +      jinit_phuff_decoder(cinfo);
 515.112 +#else
 515.113 +      ERREXIT(cinfo, JERR_NOT_COMPILED);
 515.114 +#endif
 515.115 +    } else
 515.116 +      jinit_huff_decoder(cinfo);
 515.117 +  }
 515.118 +
 515.119 +  /* Always get a full-image coefficient buffer. */
 515.120 +  jinit_d_coef_controller(cinfo, TRUE);
 515.121 +
 515.122 +  /* We can now tell the memory manager to allocate virtual arrays. */
 515.123 +  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
 515.124 +
 515.125 +  /* Initialize input side of decompressor to consume first scan. */
 515.126 +  (*cinfo->inputctl->start_input_pass) (cinfo);
 515.127 +
 515.128 +  /* Initialize progress monitoring. */
 515.129 +  if (cinfo->progress != NULL) {
 515.130 +    int nscans;
 515.131 +    /* Estimate number of scans to set pass_limit. */
 515.132 +    if (cinfo->progressive_mode) {
 515.133 +      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
 515.134 +      nscans = 2 + 3 * cinfo->num_components;
 515.135 +    } else if (cinfo->inputctl->has_multiple_scans) {
 515.136 +      /* For a nonprogressive multiscan file, estimate 1 scan per component. */
 515.137 +      nscans = cinfo->num_components;
 515.138 +    } else {
 515.139 +      nscans = 1;
 515.140 +    }
 515.141 +    cinfo->progress->pass_counter = 0L;
 515.142 +    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
 515.143 +    cinfo->progress->completed_passes = 0;
 515.144 +    cinfo->progress->total_passes = 1;
 515.145 +  }
 515.146 +}
   516.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   516.2 +++ b/libs/libjpeg/jerror.c	Sat Feb 01 19:58:19 2014 +0200
   516.3 @@ -0,0 +1,252 @@
   516.4 +/*
   516.5 + * jerror.c
   516.6 + *
   516.7 + * Copyright (C) 1991-1998, Thomas G. Lane.
   516.8 + * This file is part of the Independent JPEG Group's software.
   516.9 + * For conditions of distribution and use, see the accompanying README file.
  516.10 + *
  516.11 + * This file contains simple error-reporting and trace-message routines.
  516.12 + * These are suitable for Unix-like systems and others where writing to
  516.13 + * stderr is the right thing to do.  Many applications will want to replace
  516.14 + * some or all of these routines.
  516.15 + *
  516.16 + * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
  516.17 + * you get a Windows-specific hack to display error messages in a dialog box.
  516.18 + * It ain't much, but it beats dropping error messages into the bit bucket,
  516.19 + * which is what happens to output to stderr under most Windows C compilers.
  516.20 + *
  516.21 + * These routines are used by both the compression and decompression code.
  516.22 + */
  516.23 +
  516.24 +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
  516.25 +#include "jinclude.h"
  516.26 +#include "jpeglib.h"
  516.27 +#include "jversion.h"
  516.28 +#include "jerror.h"
  516.29 +
  516.30 +#ifdef USE_WINDOWS_MESSAGEBOX
  516.31 +#include <windows.h>
  516.32 +#endif
  516.33 +
  516.34 +#ifndef EXIT_FAILURE		/* define exit() codes if not provided */
  516.35 +#define EXIT_FAILURE  1
  516.36 +#endif
  516.37 +
  516.38 +
  516.39 +/*
  516.40 + * Create the message string table.
  516.41 + * We do this from the master message list in jerror.h by re-reading
  516.42 + * jerror.h with a suitable definition for macro JMESSAGE.
  516.43 + * The message table is made an external symbol just in case any applications
  516.44 + * want to refer to it directly.
  516.45 + */
  516.46 +
  516.47 +#ifdef NEED_SHORT_EXTERNAL_NAMES
  516.48 +#define jpeg_std_message_table	jMsgTable
  516.49 +#endif
  516.50 +
  516.51 +#define JMESSAGE(code,string)	string ,
  516.52 +
  516.53 +const char * const jpeg_std_message_table[] = {
  516.54 +#include "jerror.h"
  516.55 +  NULL
  516.56 +};
  516.57 +
  516.58 +
  516.59 +/*
  516.60 + * Error exit handler: must not return to caller.
  516.61 + *
  516.62 + * Applications may override this if they want to get control back after
  516.63 + * an error.  Typically one would longjmp somewhere instead of exiting.
  516.64 + * The setjmp buffer can be made a private field within an expanded error
  516.65 + * handler object.  Note that the info needed to generate an error message
  516.66 + * is stored in the error object, so you can generate the message now or
  516.67 + * later, at your convenience.
  516.68 + * You should make sure that the JPEG object is cleaned up (with jpeg_abort
  516.69 + * or jpeg_destroy) at some point.
  516.70 + */
  516.71 +
  516.72 +METHODDEF(void)
  516.73 +error_exit (j_common_ptr cinfo)
  516.74 +{
  516.75 +  /* Always display the message */
  516.76 +  (*cinfo->err->output_message) (cinfo);
  516.77 +
  516.78 +  /* Let the memory manager delete any temp files before we die */
  516.79 +  jpeg_destroy(cinfo);
  516.80 +
  516.81 +  exit(EXIT_FAILURE);
  516.82 +}
  516.83 +
  516.84 +
  516.85 +/*
  516.86 + * Actual output of an error or trace message.
  516.87 + * Applications may override this method to send JPEG messages somewhere
  516.88 + * other than stderr.
  516.89 + *
  516.90 + * On Windows, printing to stderr is generally completely useless,
  516.91 + * so we provide optional code to produce an error-dialog popup.
  516.92 + * Most Windows applications will still prefer to override this routine,
  516.93 + * but if they don't, it'll do something at least marginally useful.
  516.94 + *
  516.95 + * NOTE: to use the library in an environment that doesn't support the
  516.96 + * C stdio library, you may have to delete the call to fprintf() entirely,
  516.97 + * not just not use this routine.
  516.98 + */
  516.99 +
 516.100 +METHODDEF(void)
 516.101 +output_message (j_common_ptr cinfo)
 516.102 +{
 516.103 +  char buffer[JMSG_LENGTH_MAX];
 516.104 +
 516.105 +  /* Create the message */
 516.106 +  (*cinfo->err->format_message) (cinfo, buffer);
 516.107 +
 516.108 +#ifdef USE_WINDOWS_MESSAGEBOX
 516.109 +  /* Display it in a message dialog box */
 516.110 +  MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
 516.111 +	     MB_OK | MB_ICONERROR);
 516.112 +#else
 516.113 +  /* Send it to stderr, adding a newline */
 516.114 +  fprintf(stderr, "%s\n", buffer);
 516.115 +#endif
 516.116 +}
 516.117 +
 516.118 +
 516.119 +/*
 516.120 + * Decide whether to emit a trace or warning message.
 516.121 + * msg_level is one of:
 516.122 + *   -1: recoverable corrupt-data warning, may want to abort.
 516.123 + *    0: important advisory messages (always display to user).
 516.124 + *    1: first level of tracing detail.
 516.125 + *    2,3,...: successively more detailed tracing messages.
 516.126 + * An application might override this method if it wanted to abort on warnings
 516.127 + * or change the policy about which messages to display.
 516.128 + */
 516.129 +
 516.130 +METHODDEF(void)
 516.131 +emit_message (j_common_ptr cinfo, int msg_level)
 516.132 +{
 516.133 +  struct jpeg_error_mgr * err = cinfo->err;
 516.134 +
 516.135 +  if (msg_level < 0) {
 516.136 +    /* It's a warning message.  Since corrupt files may generate many warnings,
 516.137 +     * the policy implemented here is to show only the first warning,
 516.138 +     * unless trace_level >= 3.
 516.139 +     */
 516.140 +    if (err->num_warnings == 0 || err->trace_level >= 3)
 516.141 +      (*err->output_message) (cinfo);
 516.142 +    /* Always count warnings in num_warnings. */
 516.143 +    err->num_warnings++;
 516.144 +  } else {
 516.145 +    /* It's a trace message.  Show it if trace_level >= msg_level. */
 516.146 +    if (err->trace_level >= msg_level)
 516.147 +      (*err->output_message) (cinfo);
 516.148 +  }
 516.149 +}
 516.150 +
 516.151 +
 516.152 +/*
 516.153 + * Format a message string for the most recent JPEG error or message.
 516.154 + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
 516.155 + * characters.  Note that no '\n' character is added to the string.
 516.156 + * Few applications should need to override this method.
 516.157 + */
 516.158 +
 516.159 +METHODDEF(void)
 516.160 +format_message (j_common_ptr cinfo, char * buffer)
 516.161 +{
 516.162 +  struct jpeg_error_mgr * err = cinfo->err;
 516.163 +  int msg_code = err->msg_code;
 516.164 +  const char * msgtext = NULL;
 516.165 +  const char * msgptr;
 516.166 +  char ch;
 516.167 +  boolean isstring;
 516.168 +
 516.169 +  /* Look up message string in proper table */
 516.170 +  if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
 516.171 +    msgtext = err->jpeg_message_table[msg_code];
 516.172 +  } else if (err->addon_message_table != NULL &&
 516.173 +	     msg_code >= err->first_addon_message &&
 516.174 +	     msg_code <= err->last_addon_message) {
 516.175 +    msgtext = err->addon_message_table[msg_code - err->first_addon_message];
 516.176 +  }
 516.177 +
 516.178 +  /* Defend against bogus message number */
 516.179 +  if (msgtext == NULL) {
 516.180 +    err->msg_parm.i[0] = msg_code;
 516.181 +    msgtext = err->jpeg_message_table[0];
 516.182 +  }
 516.183 +
 516.184 +  /* Check for string parameter, as indicated by %s in the message text */
 516.185 +  isstring = FALSE;
 516.186 +  msgptr = msgtext;
 516.187 +  while ((ch = *msgptr++) != '\0') {
 516.188 +    if (ch == '%') {
 516.189 +      if (*msgptr == 's') isstring = TRUE;
 516.190 +      break;
 516.191 +    }
 516.192 +  }
 516.193 +
 516.194 +  /* Format the message into the passed buffer */
 516.195 +  if (isstring)
 516.196 +    sprintf(buffer, msgtext, err->msg_parm.s);
 516.197 +  else
 516.198 +    sprintf(buffer, msgtext,
 516.199 +	    err->msg_parm.i[0], err->msg_parm.i[1],
 516.200 +	    err->msg_parm.i[2], err->msg_parm.i[3],
 516.201 +	    err->msg_parm.i[4], err->msg_parm.i[5],
 516.202 +	    err->msg_parm.i[6], err->msg_parm.i[7]);
 516.203 +}
 516.204 +
 516.205 +
 516.206 +/*
 516.207 + * Reset error state variables at start of a new image.
 516.208 + * This is called during compression startup to reset trace/error
 516.209 + * processing to default state, without losing any application-specific
 516.210 + * method pointers.  An application might possibly want to override
 516.211 + * this method if it has additional error processing state.
 516.212 + */
 516.213 +
 516.214 +METHODDEF(void)
 516.215 +reset_error_mgr (j_common_ptr cinfo)
 516.216 +{
 516.217 +  cinfo->err->num_warnings = 0;
 516.218 +  /* trace_level is not reset since it is an application-supplied parameter */
 516.219 +  cinfo->err->msg_code = 0;	/* may be useful as a flag for "no error" */
 516.220 +}
 516.221 +
 516.222 +
 516.223 +/*
 516.224 + * Fill in the standard error-handling methods in a jpeg_error_mgr object.
 516.225 + * Typical call is:
 516.226 + *	struct jpeg_compress_struct cinfo;
 516.227 + *	struct jpeg_error_mgr err;
 516.228 + *
 516.229 + *	cinfo.err = jpeg_std_error(&err);
 516.230 + * after which the application may override some of the methods.
 516.231 + */
 516.232 +
 516.233 +GLOBAL(struct jpeg_error_mgr *)
 516.234 +jpeg_std_error (struct jpeg_error_mgr * err)
 516.235 +{
 516.236 +  err->error_exit = error_exit;
 516.237 +  err->emit_message = emit_message;
 516.238 +  err->output_message = output_message;
 516.239 +  err->format_message = format_message;
 516.240 +  err->reset_error_mgr = reset_error_mgr;
 516.241 +
 516.242 +  err->trace_level = 0;		/* default = no tracing */
 516.243 +  err->num_warnings = 0;	/* no warnings emitted yet */
 516.244 +  err->msg_code = 0;		/* may be useful as a flag for "no error" */
 516.245 +
 516.246 +  /* Initialize message table pointers */
 516.247 +  err->jpeg_message_table = jpeg_std_message_table;
 516.248 +  err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
 516.249 +
 516.250 +  err->addon_message_table = NULL;
 516.251 +  err->first_addon_message = 0;	/* for safety */
 516.252 +  err->last_addon_message = 0;
 516.253 +
 516.254 +  return err;
 516.255 +}
   517.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   517.2 +++ b/libs/libjpeg/jerror.h	Sat Feb 01 19:58:19 2014 +0200
   517.3 @@ -0,0 +1,291 @@
   517.4 +/*
   517.5 + * jerror.h
   517.6 + *
   517.7 + * Copyright (C) 1994-1997, Thomas G. Lane.
   517.8 + * This file is part of the Independent JPEG Group's software.
   517.9 + * For conditions of distribution and use, see the accompanying README file.
  517.10 + *
  517.11 + * This file defines the error and message codes for the JPEG library.
  517.12 + * Edit this file to add new codes, or to translate the message strings to
  517.13 + * some other language.
  517.14 + * A set of error-reporting macros are defined too.  Some applications using
  517.15 + * the JPEG library may wish to include this file to get the error codes
  517.16 + * and/or the macros.
  517.17 + */
  517.18 +
  517.19 +/*
  517.20 + * To define the enum list of message codes, include this file without
  517.21 + * defining macro JMESSAGE.  To create a message string table, include it
  517.22 + * again with a suitable JMESSAGE definition (see jerror.c for an example).
  517.23 + */
  517.24 +#ifndef JMESSAGE
  517.25 +#ifndef JERROR_H
  517.26 +/* First time through, define the enum list */
  517.27 +#define JMAKE_ENUM_LIST
  517.28 +#else
  517.29 +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
  517.30 +#define JMESSAGE(code,string)
  517.31 +#endif /* JERROR_H */
  517.32 +#endif /* JMESSAGE */
  517.33 +
  517.34 +#ifdef JMAKE_ENUM_LIST
  517.35 +
  517.36 +typedef enum {
  517.37 +
  517.38 +#define JMESSAGE(code,string)	code ,
  517.39 +
  517.40 +#endif /* JMAKE_ENUM_LIST */
  517.41 +
  517.42 +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
  517.43 +
  517.44 +/* For maintenance convenience, list is alphabetical by message code name */
  517.45 +JMESSAGE(JERR_ARITH_NOTIMPL,
  517.46 +	 "Sorry, there are legal restrictions on arithmetic coding")
  517.47 +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
  517.48 +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
  517.49 +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
  517.50 +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
  517.51 +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
  517.52 +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
  517.53 +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
  517.54 +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
  517.55 +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
  517.56 +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
  517.57 +JMESSAGE(JERR_BAD_LIB_VERSION,
  517.58 +	 "Wrong JPEG library version: library is %d, caller expects %d")
  517.59 +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
  517.60 +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
  517.61 +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
  517.62 +JMESSAGE(JERR_BAD_PROGRESSION,
  517.63 +	 "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
  517.64 +JMESSAGE(JERR_BAD_PROG_SCRIPT,
  517.65 +	 "Invalid progressive parameters at scan script entry %d")
  517.66 +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
  517.67 +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
  517.68 +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
  517.69 +JMESSAGE(JERR_BAD_STRUCT_SIZE,
  517.70 +	 "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
  517.71 +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
  517.72 +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
  517.73 +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
  517.74 +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
  517.75 +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
  517.76 +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
  517.77 +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
  517.78 +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
  517.79 +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
  517.80 +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
  517.81 +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
  517.82 +JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
  517.83 +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
  517.84 +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
  517.85 +JMESSAGE(JERR_FILE_READ, "Input file read error")
  517.86 +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
  517.87 +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
  517.88 +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
  517.89 +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
  517.90 +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
  517.91 +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
  517.92 +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
  517.93 +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
  517.94 +	 "Cannot transcode due to multiple use of quantization table %d")
  517.95 +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
  517.96 +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
  517.97 +JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
  517.98 +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
  517.99 +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
 517.100 +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
 517.101 +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
 517.102 +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
 517.103 +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
 517.104 +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
 517.105 +JMESSAGE(JERR_QUANT_COMPONENTS,
 517.106 +	 "Cannot quantize more than %d color components")
 517.107 +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
 517.108 +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
 517.109 +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
 517.110 +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
 517.111 +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
 517.112 +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
 517.113 +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
 517.114 +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
 517.115 +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
 517.116 +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
 517.117 +JMESSAGE(JERR_TFILE_WRITE,
 517.118 +	 "Write failed on temporary file --- out of disk space?")
 517.119 +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
 517.120 +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
 517.121 +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
 517.122 +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
 517.123 +JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
 517.124 +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
 517.125 +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
 517.126 +JMESSAGE(JMSG_VERSION, JVERSION)
 517.127 +JMESSAGE(JTRC_16BIT_TABLES,
 517.128 +	 "Caution: quantization tables are too coarse for baseline JPEG")
 517.129 +JMESSAGE(JTRC_ADOBE,
 517.130 +	 "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
 517.131 +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
 517.132 +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
 517.133 +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
 517.134 +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
 517.135 +JMESSAGE(JTRC_DQT, "Define Quantization Table %d  precision %d")
 517.136 +JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
 517.137 +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
 517.138 +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
 517.139 +JMESSAGE(JTRC_EOI, "End Of Image")
 517.140 +JMESSAGE(JTRC_HUFFBITS, "        %3d %3d %3d %3d %3d %3d %3d %3d")
 517.141 +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d  %d")
 517.142 +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
 517.143 +	 "Warning: thumbnail image size does not match data length %u")
 517.144 +JMESSAGE(JTRC_JFIF_EXTENSION,
 517.145 +	 "JFIF extension marker: type 0x%02x, length %u")
 517.146 +JMESSAGE(JTRC_JFIF_THUMBNAIL, "    with %d x %d thumbnail image")
 517.147 +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
 517.148 +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
 517.149 +JMESSAGE(JTRC_QUANTVALS, "        %4u %4u %4u %4u %4u %4u %4u %4u")
 517.150 +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
 517.151 +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
 517.152 +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
 517.153 +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
 517.154 +JMESSAGE(JTRC_RST, "RST%d")
 517.155 +JMESSAGE(JTRC_SMOOTH_NOTIMPL,
 517.156 +	 "Smoothing not supported with nonstandard sampling ratios")
 517.157 +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
 517.158 +JMESSAGE(JTRC_SOF_COMPONENT, "    Component %d: %dhx%dv q=%d")
 517.159 +JMESSAGE(JTRC_SOI, "Start of Image")
 517.160 +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
 517.161 +JMESSAGE(JTRC_SOS_COMPONENT, "    Component %d: dc=%d ac=%d")
 517.162 +JMESSAGE(JTRC_SOS_PARAMS, "  Ss=%d, Se=%d, Ah=%d, Al=%d")
 517.163 +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
 517.164 +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
 517.165 +JMESSAGE(JTRC_THUMB_JPEG,
 517.166 +	 "JFIF extension marker: JPEG-compressed thumbnail image, length %u")
 517.167 +JMESSAGE(JTRC_THUMB_PALETTE,
 517.168 +	 "JFIF extension marker: palette thumbnail image, length %u")
 517.169 +JMESSAGE(JTRC_THUMB_RGB,
 517.170 +	 "JFIF extension marker: RGB thumbnail image, length %u")
 517.171 +JMESSAGE(JTRC_UNKNOWN_IDS,
 517.172 +	 "Unrecognized component IDs %d %d %d, assuming YCbCr")
 517.173 +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
 517.174 +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
 517.175 +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
 517.176 +JMESSAGE(JWRN_BOGUS_PROGRESSION,
 517.177 +	 "Inconsistent progression sequence for component %d coefficient %d")
 517.178 +JMESSAGE(JWRN_EXTRANEOUS_DATA,
 517.179 +	 "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
 517.180 +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
 517.181 +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
 517.182 +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
 517.183 +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
 517.184 +JMESSAGE(JWRN_MUST_RESYNC,
 517.185 +	 "Corrupt JPEG data: found marker 0x%02x instead of RST%d")
 517.186 +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
 517.187 +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
 517.188 +
 517.189 +#ifdef JMAKE_ENUM_LIST
 517.190 +
 517.191 +  JMSG_LASTMSGCODE
 517.192 +} J_MESSAGE_CODE;
 517.193 +
 517.194 +#undef JMAKE_ENUM_LIST
 517.195 +#endif /* JMAKE_ENUM_LIST */
 517.196 +
 517.197 +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
 517.198 +#undef JMESSAGE
 517.199 +
 517.200 +
 517.201 +#ifndef JERROR_H
 517.202 +#define JERROR_H
 517.203 +
 517.204 +/* Macros to simplify using the error and trace message stuff */
 517.205 +/* The first parameter is either type of cinfo pointer */
 517.206 +
 517.207 +/* Fatal errors (print message and exit) */
 517.208 +#define ERREXIT(cinfo,code)  \
 517.209 +  ((cinfo)->err->msg_code = (code), \
 517.210 +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 517.211 +#define ERREXIT1(cinfo,code,p1)  \
 517.212 +  ((cinfo)->err->msg_code = (code), \
 517.213 +   (cinfo)->err->msg_parm.i[0] = (p1), \
 517.214 +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 517.215 +#define ERREXIT2(cinfo,code,p1,p2)  \
 517.216 +  ((cinfo)->err->msg_code = (code), \
 517.217 +   (cinfo)->err->msg_parm.i[0] = (p1), \
 517.218 +   (cinfo)->err->msg_parm.i[1] = (p2), \
 517.219 +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 517.220 +#define ERREXIT3(cinfo,code,p1,p2,p3)  \
 517.221 +  ((cinfo)->err->msg_code = (code), \
 517.222 +   (cinfo)->err->msg_parm.i[0] = (p1), \
 517.223 +   (cinfo)->err->msg_parm.i[1] = (p2), \
 517.224 +   (cinfo)->err->msg_parm.i[2] = (p3), \
 517.225 +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 517.226 +#define ERREXIT4(cinfo,code,p1,p2,p3,p4)  \
 517.227 +  ((cinfo)->err->msg_code = (code), \
 517.228 +   (cinfo)->err->msg_parm.i[0] = (p1), \
 517.229 +   (cinfo)->err->msg_parm.i[1] = (p2), \
 517.230 +   (cinfo)->err->msg_parm.i[2] = (p3), \
 517.231 +   (cinfo)->err->msg_parm.i[3] = (p4), \
 517.232 +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 517.233 +#define ERREXITS(cinfo,code,str)  \
 517.234 +  ((cinfo)->err->msg_code = (code), \
 517.235 +   strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
 517.236 +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 517.237 +
 517.238 +#define MAKESTMT(stuff)		do { stuff } while (0)
 517.239 +
 517.240 +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
 517.241 +#define WARNMS(cinfo,code)  \
 517.242 +  ((cinfo)->err->msg_code = (code), \
 517.243 +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
 517.244 +#define WARNMS1(cinfo,code,p1)  \
 517.245 +  ((cinfo)->err->msg_code = (code), \
 517.246 +   (cinfo)->err->msg_parm.i[0] = (p1), \
 517.247 +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
 517.248 +#define WARNMS2(cinfo,code,p1,p2)  \
 517.249 +  ((cinfo)->err->msg_code = (code), \
 517.250 +   (cinfo)->err->msg_parm.i[0] = (p1), \
 517.251 +   (cinfo)->err->msg_parm.i[1] = (p2), \
 517.252 +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
 517.253 +
 517.254 +/* Informational/debugging messages */
 517.255 +#define TRACEMS(cinfo,lvl,code)  \
 517.256 +  ((cinfo)->err->msg_code = (code), \
 517.257 +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
 517.258 +#define TRACEMS1(cinfo,lvl,code,p1)  \
 517.259 +  ((cinfo)->err->msg_code = (code), \
 517.260 +   (cinfo)->err->msg_parm.i[0] = (p1), \
 517.261 +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
 517.262 +#define TRACEMS2(cinfo,lvl,code,p1,p2)  \
 517.263 +  ((cinfo)->err->msg_code = (code), \
 517.264 +   (cinfo)->err->msg_parm.i[0] = (p1), \
 517.265 +   (cinfo)->err->msg_parm.i[1] = (p2), \
 517.266 +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
 517.267 +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3)  \
 517.268 +  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
 517.269 +	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
 517.270 +	   (cinfo)->err->msg_code = (code); \
 517.271 +	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
 517.272 +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4)  \
 517.273 +  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
 517.274 +	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
 517.275 +	   (cinfo)->err->msg_code = (code); \
 517.276 +	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
 517.277 +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5)  \
 517.278 +  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
 517.279 +	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
 517.280 +	   _mp[4] = (p5); \
 517.281 +	   (cinfo)->err->msg_code = (code); \
 517.282 +	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
 517.283 +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8)  \
 517.284 +  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
 517.285 +	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
 517.286 +	   _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
 517.287 +	   (cinfo)->err->msg_code = (code); \
 517.288 +	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
 517.289 +#define TRACEMSS(cinfo,lvl,code,str)  \
 517.290 +  ((cinfo)->err->msg_code = (code), \
 517.291 +   strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
 517.292 +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
 517.293 +
 517.294 +#endif /* JERROR_H */
   518.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   518.2 +++ b/libs/libjpeg/jfdctflt.c	Sat Feb 01 19:58:19 2014 +0200
   518.3 @@ -0,0 +1,168 @@
   518.4 +/*
   518.5 + * jfdctflt.c
   518.6 + *
   518.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   518.8 + * This file is part of the Independent JPEG Group's software.
   518.9 + * For conditions of distribution and use, see the accompanying README file.
  518.10 + *
  518.11 + * This file contains a floating-point implementation of the
  518.12 + * forward DCT (Discrete Cosine Transform).
  518.13 + *
  518.14 + * This implementation should be more accurate than either of the integer
  518.15 + * DCT implementations.  However, it may not give the same results on all
  518.16 + * machines because of differences in roundoff behavior.  Speed will depend
  518.17 + * on the hardware's floating point capacity.
  518.18 + *
  518.19 + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
  518.20 + * on each column.  Direct algorithms are also available, but they are
  518.21 + * much more complex and seem not to be any faster when reduced to code.
  518.22 + *
  518.23 + * This implementation is based on Arai, Agui, and Nakajima's algorithm for
  518.24 + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
  518.25 + * Japanese, but the algorithm is described in the Pennebaker & Mitchell
  518.26 + * JPEG textbook (see REFERENCES section in file README).  The following code
  518.27 + * is based directly on figure 4-8 in P&M.
  518.28 + * While an 8-point DCT cannot be done in less than 11 multiplies, it is
  518.29 + * possible to arrange the computation so that many of the multiplies are
  518.30 + * simple scalings of the final outputs.  These multiplies can then be
  518.31 + * folded into the multiplications or divisions by the JPEG quantization
  518.32 + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
  518.33 + * to be done in the DCT itself.
  518.34 + * The primary disadvantage of this method is that with a fixed-point
  518.35 + * implementation, accuracy is lost due to imprecise representation of the
  518.36 + * scaled quantization values.  However, that problem does not arise if
  518.37 + * we use floating point arithmetic.
  518.38 + */
  518.39 +
  518.40 +#define JPEG_INTERNALS
  518.41 +#include "jinclude.h"
  518.42 +#include "jpeglib.h"
  518.43 +#include "jdct.h"		/* Private declarations for DCT subsystem */
  518.44 +
  518.45 +#ifdef DCT_FLOAT_SUPPORTED
  518.46 +
  518.47 +
  518.48 +/*
  518.49 + * This module is specialized to the case DCTSIZE = 8.
  518.50 + */
  518.51 +
  518.52 +#if DCTSIZE != 8
  518.53 +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
  518.54 +#endif
  518.55 +
  518.56 +
  518.57 +/*
  518.58 + * Perform the forward DCT on one block of samples.
  518.59 + */
  518.60 +
  518.61 +GLOBAL(void)
  518.62 +jpeg_fdct_float (FAST_FLOAT * data)
  518.63 +{
  518.64 +  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
  518.65 +  FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
  518.66 +  FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
  518.67 +  FAST_FLOAT *dataptr;
  518.68 +  int ctr;
  518.69 +
  518.70 +  /* Pass 1: process rows. */
  518.71 +
  518.72 +  dataptr = data;
  518.73 +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
  518.74 +    tmp0 = dataptr[0] + dataptr[7];
  518.75 +    tmp7 = dataptr[0] - dataptr[7];
  518.76 +    tmp1 = dataptr[1] + dataptr[6];
  518.77 +    tmp6 = dataptr[1] - dataptr[6];
  518.78 +    tmp2 = dataptr[2] + dataptr[5];
  518.79 +    tmp5 = dataptr[2] - dataptr[5];
  518.80 +    tmp3 = dataptr[3] + dataptr[4];
  518.81 +    tmp4 = dataptr[3] - dataptr[4];
  518.82 +    
  518.83 +    /* Even part */
  518.84 +    
  518.85 +    tmp10 = tmp0 + tmp3;	/* phase 2 */
  518.86 +    tmp13 = tmp0 - tmp3;
  518.87 +    tmp11 = tmp1 + tmp2;
  518.88 +    tmp12 = tmp1 - tmp2;
  518.89 +    
  518.90 +    dataptr[0] = tmp10 + tmp11; /* phase 3 */
  518.91 +    dataptr[4] = tmp10 - tmp11;
  518.92 +    
  518.93 +    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
  518.94 +    dataptr[2] = tmp13 + z1;	/* phase 5 */
  518.95 +    dataptr[6] = tmp13 - z1;
  518.96 +    
  518.97 +    /* Odd part */
  518.98 +
  518.99 +    tmp10 = tmp4 + tmp5;	/* phase 2 */
 518.100 +    tmp11 = tmp5 + tmp6;
 518.101 +    tmp12 = tmp6 + tmp7;
 518.102 +
 518.103 +    /* The rotator is modified from fig 4-8 to avoid extra negations. */
 518.104 +    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
 518.105 +    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
 518.106 +    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
 518.107 +    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
 518.108 +
 518.109 +    z11 = tmp7 + z3;		/* phase 5 */
 518.110 +    z13 = tmp7 - z3;
 518.111 +
 518.112 +    dataptr[5] = z13 + z2;	/* phase 6 */
 518.113 +    dataptr[3] = z13 - z2;
 518.114 +    dataptr[1] = z11 + z4;
 518.115 +    dataptr[7] = z11 - z4;
 518.116 +
 518.117 +    dataptr += DCTSIZE;		/* advance pointer to next row */
 518.118 +  }
 518.119 +
 518.120 +  /* Pass 2: process columns. */
 518.121 +
 518.122 +  dataptr = data;
 518.123 +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
 518.124 +    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
 518.125 +    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
 518.126 +    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
 518.127 +    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
 518.128 +    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
 518.129 +    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
 518.130 +    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
 518.131 +    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
 518.132 +    
 518.133 +    /* Even part */
 518.134 +    
 518.135 +    tmp10 = tmp0 + tmp3;	/* phase 2 */
 518.136 +    tmp13 = tmp0 - tmp3;
 518.137 +    tmp11 = tmp1 + tmp2;
 518.138 +    tmp12 = tmp1 - tmp2;
 518.139 +    
 518.140 +    dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
 518.141 +    dataptr[DCTSIZE*4] = tmp10 - tmp11;
 518.142 +    
 518.143 +    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
 518.144 +    dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
 518.145 +    dataptr[DCTSIZE*6] = tmp13 - z1;
 518.146 +    
 518.147 +    /* Odd part */
 518.148 +
 518.149 +    tmp10 = tmp4 + tmp5;	/* phase 2 */
 518.150 +    tmp11 = tmp5 + tmp6;
 518.151 +    tmp12 = tmp6 + tmp7;
 518.152 +
 518.153 +    /* The rotator is modified from fig 4-8 to avoid extra negations. */
 518.154 +    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
 518.155 +    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
 518.156 +    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
 518.157 +    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
 518.158 +
 518.159 +    z11 = tmp7 + z3;		/* phase 5 */
 518.160 +    z13 = tmp7 - z3;
 518.161 +
 518.162 +    dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
 518.163 +    dataptr[DCTSIZE*3] = z13 - z2;
 518.164 +    dataptr[DCTSIZE*1] = z11 + z4;
 518.165 +    dataptr[DCTSIZE*7] = z11 - z4;
 518.166 +
 518.167 +    dataptr++;			/* advance pointer to next column */
 518.168 +  }
 518.169 +}
 518.170 +
 518.171 +#endif /* DCT_FLOAT_SUPPORTED */
   519.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   519.2 +++ b/libs/libjpeg/jfdctfst.c	Sat Feb 01 19:58:19 2014 +0200
   519.3 @@ -0,0 +1,224 @@
   519.4 +/*
   519.5 + * jfdctfst.c
   519.6 + *
   519.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
   519.8 + * This file is part of the Independent JPEG Group's software.
   519.9 + * For conditions of distribution and use, see the accompanying README file.
  519.10 + *
  519.11 + * This file contains a fast, not so accurate integer implementation of the
  519.12 + * forward DCT (Discrete Cosine Transform).
  519.13 + *
  519.14 + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
  519.15 + * on each column.  Direct algorithms are also available, but they are
  519.16 + * much more complex and seem not to be any faster when reduced to code.
  519.17 + *
  519.18 + * This implementation is based on Arai, Agui, and Nakajima's algorithm for
  519.19 + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
  519.20 + * Japanese, but the algorithm is described in the Pennebaker & Mitchell
  519.21 + * JPEG textbook (see REFERENCES section in file README).  The following code
  519.22 + * is based directly on figure 4-8 in P&M.
  519.23 + * While an 8-point DCT cannot be done in less than 11 multiplies, it is
  519.24 + * possible to arrange the computation so that many of the multiplies are
  519.25 + * simple scalings of the final outputs.  These multiplies can then be
  519.26 + * folded into the multiplications or divisions by the JPEG quantization
  519.27 + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
  519.28 + * to be done in the DCT itself.
  519.29 + * The primary disadvantage of this method is that with fixed-point math,
  519.30 + * accuracy is lost due to imprecise representation of the scaled
  519.31 + * quantization values.  The smaller the quantization table entry, the less
  519.32 + * precise the scaled value, so this implementation does worse with high-
  519.33 + * quality-setting files than with low-quality ones.
  519.34 + */
  519.35 +
  519.36 +#define JPEG_INTERNALS
  519.37 +#include "jinclude.h"
  519.38 +#include "jpeglib.h"
  519.39 +#include "jdct.h"		/* Private declarations for DCT subsystem */
  519.40 +
  519.41 +#ifdef DCT_IFAST_SUPPORTED
  519.42 +
  519.43 +
  519.44 +/*
  519.45 + * This module is specialized to the case DCTSIZE = 8.
  519.46 + */
  519.47 +
  519.48 +#if DCTSIZE != 8
  519.49 +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
  519.50 +#endif
  519.51 +
  519.52 +
  519.53 +/* Scaling decisions are generally the same as in the LL&M algorithm;
  519.54 + * see jfdctint.c for more details.  However, we choose to descale
  519.55 + * (right shift) multiplication products as soon as they are formed,
  519.56 + * rather than carrying additional fractional bits into subsequent additions.
  519.57 + * This compromises accuracy slightly, but it lets us save a few shifts.
  519.58 + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
  519.59 + * everywhere except in the multiplications proper; this saves a good deal
  519.60 + * of work on 16-bit-int machines.
  519.61 + *
  519.62 + * Again to save a few shifts, the intermediate results between pass 1 and
  519.63 + * pass 2 are not upscaled, but are represented only to integral precision.
  519.64 + *
  519.65 + * A final compromise is to represent the multiplicative constants to only
  519.66 + * 8 fractional bits, rather than 13.  This saves some shifting work on some
  519.67 + * machines, and may also reduce the cost of multiplication (since there
  519.68 + * are fewer one-bits in the constants).
  519.69 + */
  519.70 +
  519.71 +#define CONST_BITS  8
  519.72 +
  519.73 +
  519.74 +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
  519.75 + * causing a lot of useless floating-point operations at run time.
  519.76 + * To get around this we use the following pre-calculated constants.
  519.77 + * If you change CONST_BITS you may want to add appropriate values.
  519.78 + * (With a reasonable C compiler, you can just rely on the FIX() macro...)
  519.79 + */
  519.80 +
  519.81 +#if CONST_BITS == 8
  519.82 +#define FIX_0_382683433  ((INT32)   98)		/* FIX(0.382683433) */
  519.83 +#define FIX_0_541196100  ((INT32)  139)		/* FIX(0.541196100) */
  519.84 +#define FIX_0_707106781  ((INT32)  181)		/* FIX(0.707106781) */
  519.85 +#define FIX_1_306562965  ((INT32)  334)		/* FIX(1.306562965) */
  519.86 +#else
  519.87 +#define FIX_0_382683433  FIX(0.382683433)
  519.88 +#define FIX_0_541196100  FIX(0.541196100)
  519.89 +#define FIX_0_707106781  FIX(0.707106781)
  519.90 +#define FIX_1_306562965  FIX(1.306562965)
  519.91 +#endif
  519.92 +
  519.93 +
  519.94 +/* We can gain a little more speed, with a further compromise in accuracy,
  519.95 + * by omitting the addition in a descaling shift.  This yields an incorrectly
  519.96 + * rounded result half the time...
  519.97 + */
  519.98 +
  519.99 +#ifndef USE_ACCURATE_ROUNDING
 519.100 +#undef DESCALE
 519.101 +#define DESCALE(x,n)  RIGHT_SHIFT(x, n)
 519.102 +#endif
 519.103 +
 519.104 +
 519.105 +/* Multiply a DCTELEM variable by an INT32 constant, and immediately
 519.106 + * descale to yield a DCTELEM result.
 519.107 + */
 519.108 +
 519.109 +#define MULTIPLY(var,const)  ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
 519.110 +
 519.111 +
 519.112 +/*
 519.113 + * Perform the forward DCT on one block of samples.
 519.114 + */
 519.115 +
 519.116 +GLOBAL(void)
 519.117 +jpeg_fdct_ifast (DCTELEM * data)
 519.118 +{
 519.119 +  DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
 519.120 +  DCTELEM tmp10, tmp11, tmp12, tmp13;
 519.121 +  DCTELEM z1, z2, z3, z4, z5, z11, z13;
 519.122 +  DCTELEM *dataptr;
 519.123 +  int ctr;
 519.124 +  SHIFT_TEMPS
 519.125 +
 519.126 +  /* Pass 1: process rows. */
 519.127 +
 519.128 +  dataptr = data;
 519.129 +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
 519.130 +    tmp0 = dataptr[0] + dataptr[7];
 519.131 +    tmp7 = dataptr[0] - dataptr[7];
 519.132 +    tmp1 = dataptr[1] + dataptr[6];
 519.133 +    tmp6 = dataptr[1] - dataptr[6];
 519.134 +    tmp2 = dataptr[2] + dataptr[5];
 519.135 +    tmp5 = dataptr[2] - dataptr[5];
 519.136 +    tmp3 = dataptr[3] + dataptr[4];
 519.137 +    tmp4 = dataptr[3] - dataptr[4];
 519.138 +    
 519.139 +    /* Even part */
 519.140 +    
 519.141 +    tmp10 = tmp0 + tmp3;	/* phase 2 */
 519.142 +    tmp13 = tmp0 - tmp3;
 519.143 +    tmp11 = tmp1 + tmp2;
 519.144 +    tmp12 = tmp1 - tmp2;
 519.145 +    
 519.146 +    dataptr[0] = tmp10 + tmp11; /* phase 3 */
 519.147 +    dataptr[4] = tmp10 - tmp11;
 519.148 +    
 519.149 +    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
 519.150 +    dataptr[2] = tmp13 + z1;	/* phase 5 */
 519.151 +    dataptr[6] = tmp13 - z1;
 519.152 +    
 519.153 +    /* Odd part */
 519.154 +
 519.155 +    tmp10 = tmp4 + tmp5;	/* phase 2 */
 519.156 +    tmp11 = tmp5 + tmp6;
 519.157 +    tmp12 = tmp6 + tmp7;
 519.158 +
 519.159 +    /* The rotator is modified from fig 4-8 to avoid extra negations. */
 519.160 +    z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
 519.161 +    z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
 519.162 +    z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
 519.163 +    z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
 519.164 +
 519.165 +    z11 = tmp7 + z3;		/* phase 5 */
 519.166 +    z13 = tmp7 - z3;
 519.167 +
 519.168 +    dataptr[5] = z13 + z2;	/* phase 6 */
 519.169 +    dataptr[3] = z13 - z2;
 519.170 +    dataptr[1] = z11 + z4;
 519.171 +    dataptr[7] = z11 - z4;
 519.172 +
 519.173 +    dataptr += DCTSIZE;		/* advance pointer to next row */
 519.174 +  }
 519.175 +
 519.176 +  /* Pass 2: process columns. */
 519.177 +
 519.178 +  dataptr = data;
 519.179 +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
 519.180 +    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
 519.181 +    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
 519.182 +    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
 519.183 +    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
 519.184 +    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
 519.185 +    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
 519.186 +    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
 519.187 +    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
 519.188 +    
 519.189 +    /* Even part */
 519.190 +    
 519.191 +    tmp10 = tmp0 + tmp3;	/* phase 2 */
 519.192 +    tmp13 = tmp0 - tmp3;
 519.193 +    tmp11 = tmp1 + tmp2;
 519.194 +    tmp12 = tmp1 - tmp2;
 519.195 +    
 519.196 +    dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
 519.197 +    dataptr[DCTSIZE*4] = tmp10 - tmp11;
 519.198 +    
 519.199 +    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
 519.200 +    dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
 519.201 +    dataptr[DCTSIZE*6] = tmp13 - z1;
 519.202 +    
 519.203 +    /* Odd part */
 519.204 +
 519.205 +    tmp10 = tmp4 + tmp5;	/* phase 2 */
 519.206 +    tmp11 = tmp5 + tmp6;
 519.207 +    tmp12 = tmp6 + tmp7;
 519.208 +
 519.209 +    /* The rotator is modified from fig 4-8 to avoid extra negations. */
 519.210 +    z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
 519.211 +    z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
 519.212 +    z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
 519.213 +    z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
 519.214 +
 519.215 +    z11 = tmp7 + z3;		/* phase 5 */
 519.216 +    z13 = tmp7 - z3;
 519.217 +
 519.218 +    dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
 519.219 +    dataptr[DCTSIZE*3] = z13 - z2;
 519.220 +    dataptr[DCTSIZE*1] = z11 + z4;
 519.221 +    dataptr[DCTSIZE*7] = z11 - z4;
 519.222 +
 519.223 +    dataptr++;			/* advance pointer to next column */
 519.224 +  }
 519.225 +}
 519.226 +
 519.227 +#endif /* DCT_IFAST_SUPPORTED */
   520.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   520.2 +++ b/libs/libjpeg/jfdctint.c	Sat Feb 01 19:58:19 2014 +0200
   520.3 @@ -0,0 +1,283 @@
   520.4 +/*
   520.5 + * jfdctint.c
   520.6 + *
   520.7 + * Copyright (C) 1991-1996, Thomas G. Lane.
   520.8 + * This file is part of the Independent JPEG Group's software.
   520.9 + * For conditions of distribution and use, see the accompanying README file.
  520.10 + *
  520.11 + * This file contains a slow-but-accurate integer implementation of the
  520.12 + * forward DCT (Discrete Cosine Transform).
  520.13 + *
  520.14 + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
  520.15 + * on each column.  Direct algorithms are also available, but they are
  520.16 + * much more complex and seem not to be any faster when reduced to code.
  520.17 + *
  520.18 + * This implementation is based on an algorithm described in
  520.19 + *   C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
  520.20 + *   Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
  520.21 + *   Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
  520.22 + * The primary algorithm described there uses 11 multiplies and 29 adds.
  520.23 + * We use their alternate method with 12 multiplies and 32 adds.
  520.24 + * The advantage of this method is that no data path contains more than one
  520.25 + * multiplication; this allows a very simple and accurate implementation in
  520.26 + * scaled fixed-point arithmetic, with a minimal number of shifts.
  520.27 + */
  520.28 +
  520.29 +#define JPEG_INTERNALS
  520.30 +#include "jinclude.h"
  520.31 +#include "jpeglib.h"
  520.32 +#include "jdct.h"		/* Private declarations for DCT subsystem */
  520.33 +
  520.34 +#ifdef DCT_ISLOW_SUPPORTED
  520.35 +
  520.36 +
  520.37 +/*
  520.38 + * This module is specialized to the case DCTSIZE = 8.
  520.39 + */
  520.40 +
  520.41 +#if DCTSIZE != 8
  520.42 +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
  520.43 +#endif
  520.44 +
  520.45 +
  520.46 +/*
  520.47 + * The poop on this scaling stuff is as follows:
  520.48 + *
  520.49 + * Each 1-D DCT step produces outputs which are a factor of sqrt(N)
  520.50 + * larger than the true DCT outputs.  The final outputs are therefore
  520.51 + * a factor of N larger than desired; since N=8 this can be cured by
  520.52 + * a simple right shift at the end of the algorithm.  The advantage of
  520.53 + * this arrangement is that we save two multiplications per 1-D DCT,
  520.54 + * because the y0 and y4 outputs need not be divided by sqrt(N).
  520.55 + * In the IJG code, this factor of 8 is removed by the quantization step
  520.56 + * (in jcdctmgr.c), NOT in this module.
  520.57 + *
  520.58 + * We have to do addition and subtraction of the integer inputs, which
  520.59 + * is no problem, and multiplication by fractional constants, which is
  520.60 + * a problem to do in integer arithmetic.  We multiply all the constants
  520.61 + * by CONST_SCALE and convert them to integer constants (thus retaining
  520.62 + * CONST_BITS bits of precision in the constants).  After doing a
  520.63 + * multiplication we have to divide the product by CONST_SCALE, with proper
  520.64 + * rounding, to produce the correct output.  This division can be done
  520.65 + * cheaply as a right shift of CONST_BITS bits.  We postpone shifting
  520.66 + * as long as possible so that partial sums can be added together with
  520.67 + * full fractional precision.
  520.68 + *
  520.69 + * The outputs of the first pass are scaled up by PASS1_BITS bits so that
  520.70 + * they are represented to better-than-integral precision.  These outputs
  520.71 + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
  520.72 + * with the recommended scaling.  (For 12-bit sample data, the intermediate
  520.73 + * array is INT32 anyway.)
  520.74 + *
  520.75 + * To avoid overflow of the 32-bit intermediate results in pass 2, we must
  520.76 + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26.  Error analysis
  520.77 + * shows that the values given below are the most effective.
  520.78 + */
  520.79 +
  520.80 +#if BITS_IN_JSAMPLE == 8
  520.81 +#define CONST_BITS  13
  520.82 +#define PASS1_BITS  2
  520.83 +#else
  520.84 +#define CONST_BITS  13
  520.85 +#define PASS1_BITS  1		/* lose a little precision to avoid overflow */
  520.86 +#endif
  520.87 +
  520.88 +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
  520.89 + * causing a lot of useless floating-point operations at run time.
  520.90 + * To get around this we use the following pre-calculated constants.
  520.91 + * If you change CONST_BITS you may want to add appropriate values.
  520.92 + * (With a reasonable C compiler, you can just rely on the FIX() macro...)
  520.93 + */
  520.94 +
  520.95 +#if CONST_BITS == 13
  520.96 +#define FIX_0_298631336  ((INT32)  2446)	/* FIX(0.298631336) */
  520.97 +#define FIX_0_390180644  ((INT32)  3196)	/* FIX(0.390180644) */
  520.98 +#define FIX_0_541196100  ((INT32)  4433)	/* FIX(0.541196100) */
  520.99 +#define FIX_0_765366865  ((INT32)  6270)	/* FIX(0.765366865) */
 520.100 +#define FIX_0_899976223  ((INT32)  7373)	/* FIX(0.899976223) */
 520.101 +#define FIX_1_175875602  ((INT32)  9633)	/* FIX(1.175875602) */
 520.102 +#define FIX_1_501321110  ((INT32)  12299)	/* FIX(1.501321110) */
 520.103 +#define FIX_1_847759065  ((INT32)  15137)	/* FIX(1.847759065) */
 520.104 +#define FIX_1_961570560  ((INT32)  16069)	/* FIX(1.961570560) */
 520.105 +#define FIX_2_053119869  ((INT32)  16819)	/* FIX(2.053119869) */
 520.106 +#define FIX_2_562915447  ((INT32)  20995)	/* FIX(2.562915447) */
 520.107 +#define FIX_3_072711026  ((INT32)  25172)	/* FIX(3.072711026) */
 520.108 +#else
 520.109 +#define FIX_0_298631336  FIX(0.298631336)
 520.110 +#define FIX_0_390180644  FIX(0.390180644)
 520.111 +#define FIX_0_541196100  FIX(0.541196100)
 520.112 +#define FIX_0_765366865  FIX(0.765366865)
 520.113 +#define FIX_0_899976223  FIX(0.899976223)
 520.114 +#define FIX_1_175875602  FIX(1.175875602)
 520.115 +#define FIX_1_501321110  FIX(1.501321110)
 520.116 +#define FIX_1_847759065  FIX(1.847759065)
 520.117 +#define FIX_1_961570560  FIX(1.961570560)
 520.118 +#define FIX_2_053119869  FIX(2.053119869)
 520.119 +#define FIX_2_562915447  FIX(2.562915447)
 520.120 +#define FIX_3_072711026  FIX(3.072711026)
 520.121 +#endif
 520.122 +
 520.123 +
 520.124 +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
 520.125 + * For 8-bit samples with the recommended scaling, all the variable
 520.126 + * and constant values involved are no more than 16 bits wide, so a
 520.127 + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
 520.128 + * For 12-bit samples, a full 32-bit multiplication will be needed.
 520.129 + */
 520.130 +
 520.131 +#if BITS_IN_JSAMPLE == 8
 520.132 +#define MULTIPLY(var,const)  MULTIPLY16C16(var,const)
 520.133 +#else
 520.134 +#define MULTIPLY(var,const)  ((var) * (const))
 520.135 +#endif
 520.136 +
 520.137 +
 520.138 +/*
 520.139 + * Perform the forward DCT on one block of samples.
 520.140 + */
 520.141 +
 520.142 +GLOBAL(void)
 520.143 +jpeg_fdct_islow (DCTELEM * data)
 520.144 +{
 520.145 +  INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
 520.146 +  INT32 tmp10, tmp11, tmp12, tmp13;
 520.147 +  INT32 z1, z2, z3, z4, z5;
 520.148 +  DCTELEM *dataptr;
 520.149 +  int ctr;
 520.150 +  SHIFT_TEMPS
 520.151 +
 520.152 +  /* Pass 1: process rows. */
 520.153 +  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
 520.154 +  /* furthermore, we scale the results by 2**PASS1_BITS. */
 520.155 +
 520.156 +  dataptr = data;
 520.157 +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
 520.158 +    tmp0 = dataptr[0] + dataptr[7];
 520.159 +    tmp7 = dataptr[0] - dataptr[7];
 520.160 +    tmp1 = dataptr[1] + dataptr[6];
 520.161 +    tmp6 = dataptr[1] - dataptr[6];
 520.162 +    tmp2 = dataptr[2] + dataptr[5];
 520.163 +    tmp5 = dataptr[2] - dataptr[5];
 520.164 +    tmp3 = dataptr[3] + dataptr[4];
 520.165 +    tmp4 = dataptr[3] - dataptr[4];
 520.166 +    
 520.167 +    /* Even part per LL&M figure 1 --- note that published figure is faulty;
 520.168 +     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
 520.169 +     */
 520.170 +    
 520.171 +    tmp10 = tmp0 + tmp3;
 520.172 +    tmp13 = tmp0 - tmp3;
 520.173 +    tmp11 = tmp1 + tmp2;
 520.174 +    tmp12 = tmp1 - tmp2;
 520.175 +    
 520.176 +    dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
 520.177 +    dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
 520.178 +    
 520.179 +    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
 520.180 +    dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
 520.181 +				   CONST_BITS-PASS1_BITS);
 520.182 +    dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
 520.183 +				   CONST_BITS-PASS1_BITS);
 520.184 +    
 520.185 +    /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
 520.186 +     * cK represents cos(K*pi/16).
 520.187 +     * i0..i3 in the paper are tmp4..tmp7 here.
 520.188 +     */
 520.189 +    
 520.190 +    z1 = tmp4 + tmp7;
 520.191 +    z2 = tmp5 + tmp6;
 520.192 +    z3 = tmp4 + tmp6;
 520.193 +    z4 = tmp5 + tmp7;
 520.194 +    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
 520.195 +    
 520.196 +    tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
 520.197 +    tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
 520.198 +    tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
 520.199 +    tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
 520.200 +    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
 520.201 +    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
 520.202 +    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
 520.203 +    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
 520.204 +    
 520.205 +    z3 += z5;
 520.206 +    z4 += z5;
 520.207 +    
 520.208 +    dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
 520.209 +    dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
 520.210 +    dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
 520.211 +    dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
 520.212 +    
 520.213 +    dataptr += DCTSIZE;		/* advance pointer to next row */
 520.214 +  }
 520.215 +
 520.216 +  /* Pass 2: process columns.
 520.217 +   * We remove the PASS1_BITS scaling, but leave the results scaled up
 520.218 +   * by an overall factor of 8.
 520.219 +   */
 520.220 +
 520.221 +  dataptr = data;
 520.222 +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
 520.223 +    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
 520.224 +    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
 520.225 +    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
 520.226 +    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
 520.227 +    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
 520.228 +    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
 520.229 +    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
 520.230 +    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
 520.231 +    
 520.232 +    /* Even part per LL&M figure 1 --- note that published figure is faulty;
 520.233 +     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
 520.234 +     */
 520.235 +    
 520.236 +    tmp10 = tmp0 + tmp3;
 520.237 +    tmp13 = tmp0 - tmp3;
 520.238 +    tmp11 = tmp1 + tmp2;
 520.239 +    tmp12 = tmp1 - tmp2;
 520.240 +    
 520.241 +    dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
 520.242 +    dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
 520.243 +    
 520.244 +    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
 520.245 +    dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
 520.246 +					   CONST_BITS+PASS1_BITS);
 520.247 +    dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
 520.248 +					   CONST_BITS+PASS1_BITS);
 520.249 +    
 520.250 +    /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
 520.251 +     * cK represents cos(K*pi/16).
 520.252 +     * i0..i3 in the paper are tmp4..tmp7 here.
 520.253 +     */
 520.254 +    
 520.255 +    z1 = tmp4 + tmp7;
 520.256 +    z2 = tmp5 + tmp6;
 520.257 +    z3 = tmp4 + tmp6;
 520.258 +    z4 = tmp5 + tmp7;
 520.259 +    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
 520.260 +    
 520.261 +    tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
 520.262 +    tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
 520.263 +    tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
 520.264 +    tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
 520.265 +    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
 520.266 +    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
 520.267 +    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
 520.268 +    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
 520.269 +    
 520.270 +    z3 += z5;
 520.271 +    z4 += z5;
 520.272 +    
 520.273 +    dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3,
 520.274 +					   CONST_BITS+PASS1_BITS);
 520.275 +    dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4,
 520.276 +					   CONST_BITS+PASS1_BITS);
 520.277 +    dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3,
 520.278 +					   CONST_BITS+PASS1_BITS);
 520.279 +    dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4,
 520.280 +					   CONST_BITS+PASS1_BITS);
 520.281 +    
 520.282 +    dataptr++;			/* advance pointer to next column */
 520.283 +  }
 520.284 +}
 520.285 +
 520.286 +#endif /* DCT_ISLOW_SUPPORTED */
   521.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   521.2 +++ b/libs/libjpeg/jidctflt.c	Sat Feb 01 19:58:19 2014 +0200
   521.3 @@ -0,0 +1,242 @@
   521.4 +/*
   521.5 + * jidctflt.c
   521.6 + *
   521.7 + * Copyright (C) 1994-1998, Thomas G. Lane.
   521.8 + * This file is part of the Independent JPEG Group's software.
   521.9 + * For conditions of distribution and use, see the accompanying README file.
  521.10 + *
  521.11 + * This file contains a floating-point implementation of the
  521.12 + * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
  521.13 + * must also perform dequantization of the input coefficients.
  521.14 + *
  521.15 + * This implementation should be more accurate than either of the integer
  521.16 + * IDCT implementations.  However, it may not give the same results on all
  521.17 + * machines because of differences in roundoff behavior.  Speed will depend
  521.18 + * on the hardware's floating point capacity.
  521.19 + *
  521.20 + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
  521.21 + * on each row (or vice versa, but it's more convenient to emit a row at
  521.22 + * a time).  Direct algorithms are also available, but they are much more
  521.23 + * complex and seem not to be any faster when reduced to code.
  521.24 + *
  521.25 + * This implementation is based on Arai, Agui, and Nakajima's algorithm for
  521.26 + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
  521.27 + * Japanese, but the algorithm is described in the Pennebaker & Mitchell
  521.28 + * JPEG textbook (see REFERENCES section in file README).  The following code
  521.29 + * is based directly on figure 4-8 in P&M.
  521.30 + * While an 8-point DCT cannot be done in less than 11 multiplies, it is
  521.31 + * possible to arrange the computation so that many of the multiplies are
  521.32 + * simple scalings of the final outputs.  These multiplies can then be
  521.33 + * folded into the multiplications or divisions by the JPEG quantization
  521.34 + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
  521.35 + * to be done in the DCT itself.
  521.36 + * The primary disadvantage of this method is that with a fixed-point
  521.37 + * implementation, accuracy is lost due to imprecise representation of the
  521.38 + * scaled quantization values.  However, that problem does not arise if
  521.39 + * we use floating point arithmetic.
  521.40 + */
  521.41 +
  521.42 +#define JPEG_INTERNALS
  521.43 +#include "jinclude.h"
  521.44 +#include "jpeglib.h"
  521.45 +#include "jdct.h"		/* Private declarations for DCT subsystem */
  521.46 +
  521.47 +#ifdef DCT_FLOAT_SUPPORTED
  521.48 +
  521.49 +
  521.50 +/*
  521.51 + * This module is specialized to the case DCTSIZE = 8.
  521.52 + */
  521.53 +
  521.54 +#if DCTSIZE != 8
  521.55 +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
  521.56 +#endif
  521.57 +
  521.58 +
  521.59 +/* Dequantize a coefficient by multiplying it by the multiplier-table
  521.60 + * entry; produce a float result.
  521.61 + */
  521.62 +
  521.63 +#define DEQUANTIZE(coef,quantval)  (((FAST_FLOAT) (coef)) * (quantval))
  521.64 +
  521.65 +
  521.66 +/*
  521.67 + * Perform dequantization and inverse DCT on one block of coefficients.
  521.68 + */
  521.69 +
  521.70 +GLOBAL(void)
  521.71 +jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
  521.72 +		 JCOEFPTR coef_block,
  521.73 +		 JSAMPARRAY output_buf, JDIMENSION output_col)
  521.74 +{
  521.75 +  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
  521.76 +  FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
  521.77 +  FAST_FLOAT z5, z10, z11, z12, z13;
  521.78 +  JCOEFPTR inptr;
  521.79 +  FLOAT_MULT_TYPE * quantptr;
  521.80 +  FAST_FLOAT * wsptr;
  521.81 +  JSAMPROW outptr;
  521.82 +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
  521.83 +  int ctr;
  521.84 +  FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
  521.85 +  SHIFT_TEMPS
  521.86 +
  521.87 +  /* Pass 1: process columns from input, store into work array. */
  521.88 +
  521.89 +  inptr = coef_block;
  521.90 +  quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table;
  521.91 +  wsptr = workspace;
  521.92 +  for (ctr = DCTSIZE; ctr > 0; ctr--) {
  521.93 +    /* Due to quantization, we will usually find that many of the input
  521.94 +     * coefficients are zero, especially the AC terms.  We can exploit this
  521.95 +     * by short-circuiting the IDCT calculation for any column in which all
  521.96 +     * the AC terms are zero.  In that case each output is equal to the
  521.97 +     * DC coefficient (with scale factor as needed).
  521.98 +     * With typical images and quantization tables, half or more of the
  521.99 +     * column DCT calculations can be simplified this way.
 521.100 +     */
 521.101 +    
 521.102 +    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
 521.103 +	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
 521.104 +	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
 521.105 +	inptr[DCTSIZE*7] == 0) {
 521.106 +      /* AC terms all zero */
 521.107 +      FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
 521.108 +      
 521.109 +      wsptr[DCTSIZE*0] = dcval;
 521.110 +      wsptr[DCTSIZE*1] = dcval;
 521.111 +      wsptr[DCTSIZE*2] = dcval;
 521.112 +      wsptr[DCTSIZE*3] = dcval;
 521.113 +      wsptr[DCTSIZE*4] = dcval;
 521.114 +      wsptr[DCTSIZE*5] = dcval;
 521.115 +      wsptr[DCTSIZE*6] = dcval;
 521.116 +      wsptr[DCTSIZE*7] = dcval;
 521.117 +      
 521.118 +      inptr++;			/* advance pointers to next column */
 521.119 +      quantptr++;
 521.120 +      wsptr++;
 521.121 +      continue;
 521.122 +    }
 521.123 +    
 521.124 +    /* Even part */
 521.125 +
 521.126 +    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
 521.127 +    tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
 521.128 +    tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
 521.129 +    tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
 521.130 +
 521.131 +    tmp10 = tmp0 + tmp2;	/* phase 3 */
 521.132 +    tmp11 = tmp0 - tmp2;
 521.133 +
 521.134 +    tmp13 = tmp1 + tmp3;	/* phases 5-3 */
 521.135 +    tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
 521.136 +
 521.137 +    tmp0 = tmp10 + tmp13;	/* phase 2 */
 521.138 +    tmp3 = tmp10 - tmp13;
 521.139 +    tmp1 = tmp11 + tmp12;
 521.140 +    tmp2 = tmp11 - tmp12;
 521.141 +    
 521.142 +    /* Odd part */
 521.143 +
 521.144 +    tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
 521.145 +    tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
 521.146 +    tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
 521.147 +    tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
 521.148 +
 521.149 +    z13 = tmp6 + tmp5;		/* phase 6 */
 521.150 +    z10 = tmp6 - tmp5;
 521.151 +    z11 = tmp4 + tmp7;
 521.152 +    z12 = tmp4 - tmp7;
 521.153 +
 521.154 +    tmp7 = z11 + z13;		/* phase 5 */
 521.155 +    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
 521.156 +
 521.157 +    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
 521.158 +    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
 521.159 +    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
 521.160 +
 521.161 +    tmp6 = tmp12 - tmp7;	/* phase 2 */
 521.162 +    tmp5 = tmp11 - tmp6;
 521.163 +    tmp4 = tmp10 + tmp5;
 521.164 +
 521.165 +    wsptr[DCTSIZE*0] = tmp0 + tmp7;
 521.166 +    wsptr[DCTSIZE*7] = tmp0 - tmp7;
 521.167 +    wsptr[DCTSIZE*1] = tmp1 + tmp6;
 521.168 +    wsptr[DCTSIZE*6] = tmp1 - tmp6;
 521.169 +    wsptr[DCTSIZE*2] = tmp2 + tmp5;
 521.170 +    wsptr[DCTSIZE*5] = tmp2 - tmp5;
 521.171 +    wsptr[DCTSIZE*4] = tmp3 + tmp4;
 521.172 +    wsptr[DCTSIZE*3] = tmp3 - tmp4;
 521.173 +
 521.174 +    inptr++;			/* advance pointers to next column */
 521.175 +    quantptr++;
 521.176 +    wsptr++;
 521.177 +  }
 521.178 +  
 521.179 +  /* Pass 2: process rows from work array, store into output array. */
 521.180 +  /* Note that we must descale the results by a factor of 8 == 2**3. */
 521.181 +
 521.182 +  wsptr = workspace;
 521.183 +  for (ctr = 0; ctr < DCTSIZE; ctr++) {
 521.184 +    outptr = output_buf[ctr] + output_col;
 521.185 +    /* Rows of zeroes can be exploited in the same way as we did with columns.
 521.186 +     * However, the column calculation has created many nonzero AC terms, so
 521.187 +     * the simplification applies less often (typically 5% to 10% of the time).
 521.188 +     * And testing floats for zero is relatively expensive, so we don't bother.
 521.189 +     */
 521.190 +    
 521.191 +    /* Even part */
 521.192 +
 521.193 +    tmp10 = wsptr[0] + wsptr[4];
 521.194 +    tmp11 = wsptr[0] - wsptr[4];
 521.195 +
 521.196 +    tmp13 = wsptr[2] + wsptr[6];
 521.197 +    tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
 521.198 +
 521.199 +    tmp0 = tmp10 + tmp13;
 521.200 +    tmp3 = tmp10 - tmp13;
 521.201 +    tmp1 = tmp11 + tmp12;
 521.202 +    tmp2 = tmp11 - tmp12;
 521.203 +
 521.204 +    /* Odd part */
 521.205 +
 521.206 +    z13 = wsptr[5] + wsptr[3];
 521.207 +    z10 = wsptr[5] - wsptr[3];
 521.208 +    z11 = wsptr[1] + wsptr[7];
 521.209 +    z12 = wsptr[1] - wsptr[7];
 521.210 +
 521.211 +    tmp7 = z11 + z13;
 521.212 +    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
 521.213 +
 521.214 +    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
 521.215 +    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
 521.216 +    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
 521.217 +
 521.218 +    tmp6 = tmp12 - tmp7;
 521.219 +    tmp5 = tmp11 - tmp6;
 521.220 +    tmp4 = tmp10 + tmp5;
 521.221 +
 521.222 +    /* Final output stage: scale down by a factor of 8 and range-limit */
 521.223 +
 521.224 +    outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
 521.225 +			    & RANGE_MASK];
 521.226 +    outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
 521.227 +			    & RANGE_MASK];
 521.228 +    outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
 521.229 +			    & RANGE_MASK];
 521.230 +    outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
 521.231 +			    & RANGE_MASK];
 521.232 +    outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
 521.233 +			    & RANGE_MASK];
 521.234 +    outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
 521.235 +			    & RANGE_MASK];
 521.236 +    outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
 521.237 +			    & RANGE_MASK];
 521.238 +    outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
 521.239 +			    & RANGE_MASK];
 521.240 +    
 521.241 +    wsptr += DCTSIZE;		/* advance pointer to next row */
 521.242 +  }
 521.243 +}
 521.244 +
 521.245 +#endif /* DCT_FLOAT_SUPPORTED */
   522.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   522.2 +++ b/libs/libjpeg/jidctfst.c	Sat Feb 01 19:58:19 2014 +0200
   522.3 @@ -0,0 +1,368 @@
   522.4 +/*
   522.5 + * jidctfst.c
   522.6 + *
   522.7 + * Copyright (C) 1994-1998, Thomas G. Lane.
   522.8 + * This file is part of the Independent JPEG Group's software.
   522.9 + * For conditions of distribution and use, see the accompanying README file.
  522.10 + *
  522.11 + * This file contains a fast, not so accurate integer implementation of the
  522.12 + * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
  522.13 + * must also perform dequantization of the input coefficients.
  522.14 + *
  522.15 + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
  522.16 + * on each row (or vice versa, but it's more convenient to emit a row at
  522.17 + * a time).  Direct algorithms are also available, but they are much more
  522.18 + * complex and seem not to be any faster when reduced to code.
  522.19 + *
  522.20 + * This implementation is based on Arai, Agui, and Nakajima's algorithm for
  522.21 + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
  522.22 + * Japanese, but the algorithm is described in the Pennebaker & Mitchell
  522.23 + * JPEG textbook (see REFERENCES section in file README).  The following code
  522.24 + * is based directly on figure 4-8 in P&M.
  522.25 + * While an 8-point DCT cannot be done in less than 11 multiplies, it is
  522.26 + * possible to arrange the computation so that many of the multiplies are
  522.27 + * simple scalings of the final outputs.  These multiplies can then be
  522.28 + * folded into the multiplications or divisions by the JPEG quantization
  522.29 + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
  522.30 + * to be done in the DCT itself.
  522.31 + * The primary disadvantage of this method is that with fixed-point math,
  522.32 + * accuracy is lost due to imprecise representation of the scaled
  522.33 + * quantization values.  The smaller the quantization table entry, the less
  522.34 + * precise the scaled value, so this implementation does worse with high-
  522.35 + * quality-setting files than with low-quality ones.
  522.36 + */
  522.37 +
  522.38 +#define JPEG_INTERNALS
  522.39 +#include "jinclude.h"
  522.40 +#include "jpeglib.h"
  522.41 +#include "jdct.h"		/* Private declarations for DCT subsystem */
  522.42 +
  522.43 +#ifdef DCT_IFAST_SUPPORTED
  522.44 +
  522.45 +
  522.46 +/*
  522.47 + * This module is specialized to the case DCTSIZE = 8.
  522.48 + */
  522.49 +
  522.50 +#if DCTSIZE != 8
  522.51 +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
  522.52 +#endif
  522.53 +
  522.54 +
  522.55 +/* Scaling decisions are generally the same as in the LL&M algorithm;
  522.56 + * see jidctint.c for more details.  However, we choose to descale
  522.57 + * (right shift) multiplication products as soon as they are formed,
  522.58 + * rather than carrying additional fractional bits into subsequent additions.
  522.59 + * This compromises accuracy slightly, but it lets us save a few shifts.
  522.60 + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
  522.61 + * everywhere except in the multiplications proper; this saves a good deal
  522.62 + * of work on 16-bit-int machines.
  522.63 + *
  522.64 + * The dequantized coefficients are not integers because the AA&N scaling
  522.65 + * factors have been incorporated.  We represent them scaled up by PASS1_BITS,
  522.66 + * so that the first and second IDCT rounds have the same input scaling.
  522.67 + * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to
  522.68 + * avoid a descaling shift; this compromises accuracy rather drastically
  522.69 + * for small quantization table entries, but it saves a lot of shifts.
  522.70 + * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway,
  522.71 + * so we use a much larger scaling factor to preserve accuracy.
  522.72 + *
  522.73 + * A final compromise is to represent the multiplicative constants to only
  522.74 + * 8 fractional bits, rather than 13.  This saves some shifting work on some
  522.75 + * machines, and may also reduce the cost of multiplication (since there
  522.76 + * are fewer one-bits in the constants).
  522.77 + */
  522.78 +
  522.79 +#if BITS_IN_JSAMPLE == 8
  522.80 +#define CONST_BITS  8
  522.81 +#define PASS1_BITS  2
  522.82 +#else
  522.83 +#define CONST_BITS  8
  522.84 +#define PASS1_BITS  1		/* lose a little precision to avoid overflow */
  522.85 +#endif
  522.86 +
  522.87 +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
  522.88 + * causing a lot of useless floating-point operations at run time.
  522.89 + * To get around this we use the following pre-calculated constants.
  522.90 + * If you change CONST_BITS you may want to add appropriate values.
  522.91 + * (With a reasonable C compiler, you can just rely on the FIX() macro...)
  522.92 + */
  522.93 +
  522.94 +#if CONST_BITS == 8
  522.95 +#define FIX_1_082392200  ((INT32)  277)		/* FIX(1.082392200) */
  522.96 +#define FIX_1_414213562  ((INT32)  362)		/* FIX(1.414213562) */
  522.97 +#define FIX_1_847759065  ((INT32)  473)		/* FIX(1.847759065) */
  522.98 +#define FIX_2_613125930  ((INT32)  669)		/* FIX(2.613125930) */
  522.99 +#else
 522.100 +#define FIX_1_082392200  FIX(1.082392200)
 522.101 +#define FIX_1_414213562  FIX(1.414213562)
 522.102 +#define FIX_1_847759065  FIX(1.847759065)
 522.103 +#define FIX_2_613125930  FIX(2.613125930)
 522.104 +#endif
 522.105 +
 522.106 +
 522.107 +/* We can gain a little more speed, with a further compromise in accuracy,
 522.108 + * by omitting the addition in a descaling shift.  This yields an incorrectly
 522.109 + * rounded result half the time...
 522.110 + */
 522.111 +
 522.112 +#ifndef USE_ACCURATE_ROUNDING
 522.113 +#undef DESCALE
 522.114 +#define DESCALE(x,n)  RIGHT_SHIFT(x, n)
 522.115 +#endif
 522.116 +
 522.117 +
 522.118 +/* Multiply a DCTELEM variable by an INT32 constant, and immediately
 522.119 + * descale to yield a DCTELEM result.
 522.120 + */
 522.121 +
 522.122 +#define MULTIPLY(var,const)  ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
 522.123 +
 522.124 +
 522.125 +/* Dequantize a coefficient by multiplying it by the multiplier-table
 522.126 + * entry; produce a DCTELEM result.  For 8-bit data a 16x16->16
 522.127 + * multiplication will do.  For 12-bit data, the multiplier table is
 522.128 + * declared INT32, so a 32-bit multiply will be used.
 522.129 + */
 522.130 +
 522.131 +#if BITS_IN_JSAMPLE == 8
 522.132 +#define DEQUANTIZE(coef,quantval)  (((IFAST_MULT_TYPE) (coef)) * (quantval))
 522.133 +#else
 522.134 +#define DEQUANTIZE(coef,quantval)  \
 522.135 +	DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
 522.136 +#endif
 522.137 +
 522.138 +
 522.139 +/* Like DESCALE, but applies to a DCTELEM and produces an int.
 522.140 + * We assume that int right shift is unsigned if INT32 right shift is.
 522.141 + */
 522.142 +
 522.143 +#ifdef RIGHT_SHIFT_IS_UNSIGNED
 522.144 +#define ISHIFT_TEMPS	DCTELEM ishift_temp;
 522.145 +#if BITS_IN_JSAMPLE == 8
 522.146 +#define DCTELEMBITS  16		/* DCTELEM may be 16 or 32 bits */
 522.147 +#else
 522.148 +#define DCTELEMBITS  32		/* DCTELEM must be 32 bits */
 522.149 +#endif
 522.150 +#define IRIGHT_SHIFT(x,shft)  \
 522.151 +    ((ishift_temp = (x)) < 0 ? \
 522.152 +     (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
 522.153 +     (ishift_temp >> (shft)))
 522.154 +#else
 522.155 +#define ISHIFT_TEMPS
 522.156 +#define IRIGHT_SHIFT(x,shft)	((x) >> (shft))
 522.157 +#endif
 522.158 +
 522.159 +#ifdef USE_ACCURATE_ROUNDING
 522.160 +#define IDESCALE(x,n)  ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
 522.161 +#else
 522.162 +#define IDESCALE(x,n)  ((int) IRIGHT_SHIFT(x, n))
 522.163 +#endif
 522.164 +
 522.165 +
 522.166 +/*
 522.167 + * Perform dequantization and inverse DCT on one block of coefficients.
 522.168 + */
 522.169 +
 522.170 +GLOBAL(void)
 522.171 +jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 522.172 +		 JCOEFPTR coef_block,
 522.173 +		 JSAMPARRAY output_buf, JDIMENSION output_col)
 522.174 +{
 522.175 +  DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
 522.176 +  DCTELEM tmp10, tmp11, tmp12, tmp13;
 522.177 +  DCTELEM z5, z10, z11, z12, z13;
 522.178 +  JCOEFPTR inptr;
 522.179 +  IFAST_MULT_TYPE * quantptr;
 522.180 +  int * wsptr;
 522.181 +  JSAMPROW outptr;
 522.182 +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
 522.183 +  int ctr;
 522.184 +  int workspace[DCTSIZE2];	/* buffers data between passes */
 522.185 +  SHIFT_TEMPS			/* for DESCALE */
 522.186 +  ISHIFT_TEMPS			/* for IDESCALE */
 522.187 +
 522.188 +  /* Pass 1: process columns from input, store into work array. */
 522.189 +
 522.190 +  inptr = coef_block;
 522.191 +  quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
 522.192 +  wsptr = workspace;
 522.193 +  for (ctr = DCTSIZE; ctr > 0; ctr--) {
 522.194 +    /* Due to quantization, we will usually find that many of the input
 522.195 +     * coefficients are zero, especially the AC terms.  We can exploit this
 522.196 +     * by short-circuiting the IDCT calculation for any column in which all
 522.197 +     * the AC terms are zero.  In that case each output is equal to the
 522.198 +     * DC coefficient (with scale factor as needed).
 522.199 +     * With typical images and quantization tables, half or more of the
 522.200 +     * column DCT calculations can be simplified this way.
 522.201 +     */
 522.202 +    
 522.203 +    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
 522.204 +	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
 522.205 +	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
 522.206 +	inptr[DCTSIZE*7] == 0) {
 522.207 +      /* AC terms all zero */
 522.208 +      int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
 522.209 +
 522.210 +      wsptr[DCTSIZE*0] = dcval;
 522.211 +      wsptr[DCTSIZE*1] = dcval;
 522.212 +      wsptr[DCTSIZE*2] = dcval;
 522.213 +      wsptr[DCTSIZE*3] = dcval;
 522.214 +      wsptr[DCTSIZE*4] = dcval;
 522.215 +      wsptr[DCTSIZE*5] = dcval;
 522.216 +      wsptr[DCTSIZE*6] = dcval;
 522.217 +      wsptr[DCTSIZE*7] = dcval;
 522.218 +      
 522.219 +      inptr++;			/* advance pointers to next column */
 522.220 +      quantptr++;
 522.221 +      wsptr++;
 522.222 +      continue;
 522.223 +    }
 522.224 +    
 522.225 +    /* Even part */
 522.226 +
 522.227 +    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
 522.228 +    tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
 522.229 +    tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
 522.230 +    tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
 522.231 +
 522.232 +    tmp10 = tmp0 + tmp2;	/* phase 3 */
 522.233 +    tmp11 = tmp0 - tmp2;
 522.234 +
 522.235 +    tmp13 = tmp1 + tmp3;	/* phases 5-3 */
 522.236 +    tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
 522.237 +
 522.238 +    tmp0 = tmp10 + tmp13;	/* phase 2 */
 522.239 +    tmp3 = tmp10 - tmp13;
 522.240 +    tmp1 = tmp11 + tmp12;
 522.241 +    tmp2 = tmp11 - tmp12;
 522.242 +    
 522.243 +    /* Odd part */
 522.244 +
 522.245 +    tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
 522.246 +    tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
 522.247 +    tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
 522.248 +    tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
 522.249 +
 522.250 +    z13 = tmp6 + tmp5;		/* phase 6 */
 522.251 +    z10 = tmp6 - tmp5;
 522.252 +    z11 = tmp4 + tmp7;
 522.253 +    z12 = tmp4 - tmp7;
 522.254 +
 522.255 +    tmp7 = z11 + z13;		/* phase 5 */
 522.256 +    tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
 522.257 +
 522.258 +    z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
 522.259 +    tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
 522.260 +    tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
 522.261 +
 522.262 +    tmp6 = tmp12 - tmp7;	/* phase 2 */
 522.263 +    tmp5 = tmp11 - tmp6;
 522.264 +    tmp4 = tmp10 + tmp5;
 522.265 +
 522.266 +    wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
 522.267 +    wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
 522.268 +    wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
 522.269 +    wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
 522.270 +    wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
 522.271 +    wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
 522.272 +    wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
 522.273 +    wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
 522.274 +
 522.275 +    inptr++;			/* advance pointers to next column */
 522.276 +    quantptr++;
 522.277 +    wsptr++;
 522.278 +  }
 522.279 +  
 522.280 +  /* Pass 2: process rows from work array, store into output array. */
 522.281 +  /* Note that we must descale the results by a factor of 8 == 2**3, */
 522.282 +  /* and also undo the PASS1_BITS scaling. */
 522.283 +
 522.284 +  wsptr = workspace;
 522.285 +  for (ctr = 0; ctr < DCTSIZE; ctr++) {
 522.286 +    outptr = output_buf[ctr] + output_col;
 522.287 +    /* Rows of zeroes can be exploited in the same way as we did with columns.
 522.288 +     * However, the column calculation has created many nonzero AC terms, so
 522.289 +     * the simplification applies less often (typically 5% to 10% of the time).
 522.290 +     * On machines with very fast multiplication, it's possible that the
 522.291 +     * test takes more time than it's worth.  In that case this section
 522.292 +     * may be commented out.
 522.293 +     */
 522.294 +    
 522.295 +#ifndef NO_ZERO_ROW_TEST
 522.296 +    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
 522.297 +	wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
 522.298 +      /* AC terms all zero */
 522.299 +      JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
 522.300 +				  & RANGE_MASK];
 522.301 +      
 522.302 +      outptr[0] = dcval;
 522.303 +      outptr[1] = dcval;
 522.304 +      outptr[2] = dcval;
 522.305 +      outptr[3] = dcval;
 522.306 +      outptr[4] = dcval;
 522.307 +      outptr[5] = dcval;
 522.308 +      outptr[6] = dcval;
 522.309 +      outptr[7] = dcval;
 522.310 +
 522.311 +      wsptr += DCTSIZE;		/* advance pointer to next row */
 522.312 +      continue;
 522.313 +    }
 522.314 +#endif
 522.315 +    
 522.316 +    /* Even part */
 522.317 +
 522.318 +    tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
 522.319 +    tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
 522.320 +
 522.321 +    tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
 522.322 +    tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
 522.323 +	    - tmp13;
 522.324 +
 522.325 +    tmp0 = tmp10 + tmp13;
 522.326 +    tmp3 = tmp10 - tmp13;
 522.327 +    tmp1 = tmp11 + tmp12;
 522.328 +    tmp2 = tmp11 - tmp12;
 522.329 +
 522.330 +    /* Odd part */
 522.331 +
 522.332 +    z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
 522.333 +    z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
 522.334 +    z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
 522.335 +    z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
 522.336 +
 522.337 +    tmp7 = z11 + z13;		/* phase 5 */
 522.338 +    tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
 522.339 +
 522.340 +    z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
 522.341 +    tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
 522.342 +    tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
 522.343 +
 522.344 +    tmp6 = tmp12 - tmp7;	/* phase 2 */
 522.345 +    tmp5 = tmp11 - tmp6;
 522.346 +    tmp4 = tmp10 + tmp5;
 522.347 +
 522.348 +    /* Final output stage: scale down by a factor of 8 and range-limit */
 522.349 +
 522.350 +    outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
 522.351 +			    & RANGE_MASK];
 522.352 +    outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
 522.353 +			    & RANGE_MASK];
 522.354 +    outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
 522.355 +			    & RANGE_MASK];
 522.356 +    outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
 522.357 +			    & RANGE_MASK];
 522.358 +    outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
 522.359 +			    & RANGE_MASK];
 522.360 +    outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
 522.361 +			    & RANGE_MASK];
 522.362 +    outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
 522.363 +			    & RANGE_MASK];
 522.364 +    outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
 522.365 +			    & RANGE_MASK];
 522.366 +
 522.367 +    wsptr += DCTSIZE;		/* advance pointer to next row */
 522.368 +  }
 522.369 +}
 522.370 +
 522.371 +#endif /* DCT_IFAST_SUPPORTED */
   523.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   523.2 +++ b/libs/libjpeg/jidctint.c	Sat Feb 01 19:58:19 2014 +0200
   523.3 @@ -0,0 +1,389 @@
   523.4 +/*
   523.5 + * jidctint.c
   523.6 + *
   523.7 + * Copyright (C) 1991-1998, Thomas G. Lane.
   523.8 + * This file is part of the Independent JPEG Group's software.
   523.9 + * For conditions of distribution and use, see the accompanying README file.
  523.10 + *
  523.11 + * This file contains a slow-but-accurate integer implementation of the
  523.12 + * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
  523.13 + * must also perform dequantization of the input coefficients.
  523.14 + *
  523.15 + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
  523.16 + * on each row (or vice versa, but it's more convenient to emit a row at
  523.17 + * a time).  Direct algorithms are also available, but they are much more
  523.18 + * complex and seem not to be any faster when reduced to code.
  523.19 + *
  523.20 + * This implementation is based on an algorithm described in
  523.21 + *   C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
  523.22 + *   Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
  523.23 + *   Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
  523.24 + * The primary algorithm described there uses 11 multiplies and 29 adds.
  523.25 + * We use their alternate method with 12 multiplies and 32 adds.
  523.26 + * The advantage of this method is that no data path contains more than one
  523.27 + * multiplication; this allows a very simple and accurate implementation in
  523.28 + * scaled fixed-point arithmetic, with a minimal number of shifts.
  523.29 + */
  523.30 +
  523.31 +#define JPEG_INTERNALS
  523.32 +#include "jinclude.h"
  523.33 +#include "jpeglib.h"
  523.34 +#include "jdct.h"		/* Private declarations for DCT subsystem */
  523.35 +
  523.36 +#ifdef DCT_ISLOW_SUPPORTED
  523.37 +
  523.38 +
  523.39 +/*
  523.40 + * This module is specialized to the case DCTSIZE = 8.
  523.41 + */
  523.42 +
  523.43 +#if DCTSIZE != 8
  523.44 +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
  523.45 +#endif
  523.46 +
  523.47 +
  523.48 +/*
  523.49 + * The poop on this scaling stuff is as follows:
  523.50 + *
  523.51 + * Each 1-D IDCT step produces outputs which are a factor of sqrt(N)
  523.52 + * larger than the true IDCT outputs.  The final outputs are therefore
  523.53 + * a factor of N larger than desired; since N=8 this can be cured by
  523.54 + * a simple right shift at the end of the algorithm.  The advantage of
  523.55 + * this arrangement is that we save two multiplications per 1-D IDCT,
  523.56 + * because the y0 and y4 inputs need not be divided by sqrt(N).
  523.57 + *
  523.58 + * We have to do addition and subtraction of the integer inputs, which
  523.59 + * is no problem, and multiplication by fractional constants, which is
  523.60 + * a problem to do in integer arithmetic.  We multiply all the constants
  523.61 + * by CONST_SCALE and convert them to integer constants (thus retaining
  523.62 + * CONST_BITS bits of precision in the constants).  After doing a
  523.63 + * multiplication we have to divide the product by CONST_SCALE, with proper
  523.64 + * rounding, to produce the correct output.  This division can be done
  523.65 + * cheaply as a right shift of CONST_BITS bits.  We postpone shifting
  523.66 + * as long as possible so that partial sums can be added together with
  523.67 + * full fractional precision.
  523.68 + *
  523.69 + * The outputs of the first pass are scaled up by PASS1_BITS bits so that
  523.70 + * they are represented to better-than-integral precision.  These outputs
  523.71 + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
  523.72 + * with the recommended scaling.  (To scale up 12-bit sample data further, an
  523.73 + * intermediate INT32 array would be needed.)
  523.74 + *
  523.75 + * To avoid overflow of the 32-bit intermediate results in pass 2, we must
  523.76 + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26.  Error analysis
  523.77 + * shows that the values given below are the most effective.
  523.78 + */
  523.79 +
  523.80 +#if BITS_IN_JSAMPLE == 8
  523.81 +#define CONST_BITS  13
  523.82 +#define PASS1_BITS  2
  523.83 +#else
  523.84 +#define CONST_BITS  13
  523.85 +#define PASS1_BITS  1		/* lose a little precision to avoid overflow */
  523.86 +#endif
  523.87 +
  523.88 +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
  523.89 + * causing a lot of useless floating-point operations at run time.
  523.90 + * To get around this we use the following pre-calculated constants.
  523.91 + * If you change CONST_BITS you may want to add appropriate values.
  523.92 + * (With a reasonable C compiler, you can just rely on the FIX() macro...)
  523.93 + */
  523.94 +
  523.95 +#if CONST_BITS == 13
  523.96 +#define FIX_0_298631336  ((INT32)  2446)	/* FIX(0.298631336) */
  523.97 +#define FIX_0_390180644  ((INT32)  3196)	/* FIX(0.390180644) */
  523.98 +#define FIX_0_541196100  ((INT32)  4433)	/* FIX(0.541196100) */
  523.99 +#define FIX_0_765366865  ((INT32)  6270)	/* FIX(0.765366865) */
 523.100 +#define FIX_0_899976223  ((INT32)  7373)	/* FIX(0.899976223) */
 523.101 +#define FIX_1_175875602  ((INT32)  9633)	/* FIX(1.175875602) */
 523.102 +#define FIX_1_501321110  ((INT32)  12299)	/* FIX(1.501321110) */
 523.103 +#define FIX_1_847759065  ((INT32)  15137)	/* FIX(1.847759065) */
 523.104 +#define FIX_1_961570560  ((INT32)  16069)	/* FIX(1.961570560) */
 523.105 +#define FIX_2_053119869  ((INT32)  16819)	/* FIX(2.053119869) */
 523.106 +#define FIX_2_562915447  ((INT32)  20995)	/* FIX(2.562915447) */
 523.107 +#define FIX_3_072711026  ((INT32)  25172)	/* FIX(3.072711026) */
 523.108 +#else
 523.109 +#define FIX_0_298631336  FIX(0.298631336)
 523.110 +#define FIX_0_390180644  FIX(0.390180644)
 523.111 +#define FIX_0_541196100  FIX(0.541196100)
 523.112 +#define FIX_0_765366865  FIX(0.765366865)
 523.113 +#define FIX_0_899976223  FIX(0.899976223)
 523.114 +#define FIX_1_175875602  FIX(1.175875602)
 523.115 +#define FIX_1_501321110  FIX(1.501321110)
 523.116 +#define FIX_1_847759065  FIX(1.847759065)
 523.117 +#define FIX_1_961570560  FIX(1.961570560)
 523.118 +#define FIX_2_053119869  FIX(2.053119869)
 523.119 +#define FIX_2_562915447  FIX(2.562915447)
 523.120 +#define FIX_3_072711026  FIX(3.072711026)
 523.121 +#endif
 523.122 +
 523.123 +
 523.124 +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
 523.125 + * For 8-bit samples with the recommended scaling, all the variable
 523.126 + * and constant values involved are no more than 16 bits wide, so a
 523.127 + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
 523.128 + * For 12-bit samples, a full 32-bit multiplication will be needed.
 523.129 + */
 523.130 +
 523.131 +#if BITS_IN_JSAMPLE == 8
 523.132 +#define MULTIPLY(var,const)  MULTIPLY16C16(var,const)
 523.133 +#else
 523.134 +#define MULTIPLY(var,const)  ((var) * (const))
 523.135 +#endif
 523.136 +
 523.137 +
 523.138 +/* Dequantize a coefficient by multiplying it by the multiplier-table
 523.139 + * entry; produce an int result.  In this module, both inputs and result
 523.140 + * are 16 bits or less, so either int or short multiply will work.
 523.141 + */
 523.142 +
 523.143 +#define DEQUANTIZE(coef,quantval)  (((ISLOW_MULT_TYPE) (coef)) * (quantval))
 523.144 +
 523.145 +
 523.146 +/*
 523.147 + * Perform dequantization and inverse DCT on one block of coefficients.
 523.148 + */
 523.149 +
 523.150 +GLOBAL(void)
 523.151 +jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 523.152 +		 JCOEFPTR coef_block,
 523.153 +		 JSAMPARRAY output_buf, JDIMENSION output_col)
 523.154 +{
 523.155 +  INT32 tmp0, tmp1, tmp2, tmp3;
 523.156 +  INT32 tmp10, tmp11, tmp12, tmp13;
 523.157 +  INT32 z1, z2, z3, z4, z5;
 523.158 +  JCOEFPTR inptr;
 523.159 +  ISLOW_MULT_TYPE * quantptr;
 523.160 +  int * wsptr;
 523.161 +  JSAMPROW outptr;
 523.162 +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
 523.163 +  int ctr;
 523.164 +  int workspace[DCTSIZE2];	/* buffers data between passes */
 523.165 +  SHIFT_TEMPS
 523.166 +
 523.167 +  /* Pass 1: process columns from input, store into work array. */
 523.168 +  /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
 523.169 +  /* furthermore, we scale the results by 2**PASS1_BITS. */
 523.170 +
 523.171 +  inptr = coef_block;
 523.172 +  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
 523.173 +  wsptr = workspace;
 523.174 +  for (ctr = DCTSIZE; ctr > 0; ctr--) {
 523.175 +    /* Due to quantization, we will usually find that many of the input
 523.176 +     * coefficients are zero, especially the AC terms.  We can exploit this
 523.177 +     * by short-circuiting the IDCT calculation for any column in which all
 523.178 +     * the AC terms are zero.  In that case each output is equal to the
 523.179 +     * DC coefficient (with scale factor as needed).
 523.180 +     * With typical images and quantization tables, half or more of the
 523.181 +     * column DCT calculations can be simplified this way.
 523.182 +     */
 523.183 +    
 523.184 +    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
 523.185 +	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
 523.186 +	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
 523.187 +	inptr[DCTSIZE*7] == 0) {
 523.188 +      /* AC terms all zero */
 523.189 +      int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
 523.190 +      
 523.191 +      wsptr[DCTSIZE*0] = dcval;
 523.192 +      wsptr[DCTSIZE*1] = dcval;
 523.193 +      wsptr[DCTSIZE*2] = dcval;
 523.194 +      wsptr[DCTSIZE*3] = dcval;
 523.195 +      wsptr[DCTSIZE*4] = dcval;
 523.196 +      wsptr[DCTSIZE*5] = dcval;
 523.197 +      wsptr[DCTSIZE*6] = dcval;
 523.198 +      wsptr[DCTSIZE*7] = dcval;
 523.199 +      
 523.200 +      inptr++;			/* advance pointers to next column */
 523.201 +      quantptr++;
 523.202 +      wsptr++;
 523.203 +      continue;
 523.204 +    }
 523.205 +    
 523.206 +    /* Even part: reverse the even part of the forward DCT. */
 523.207 +    /* The rotator is sqrt(2)*c(-6). */
 523.208 +    
 523.209 +    z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
 523.210 +    z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
 523.211 +    
 523.212 +    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
 523.213 +    tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
 523.214 +    tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
 523.215 +    
 523.216 +    z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
 523.217 +    z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
 523.218 +
 523.219 +    tmp0 = (z2 + z3) << CONST_BITS;
 523.220 +    tmp1 = (z2 - z3) << CONST_BITS;
 523.221 +    
 523.222 +    tmp10 = tmp0 + tmp3;
 523.223 +    tmp13 = tmp0 - tmp3;
 523.224 +    tmp11 = tmp1 + tmp2;
 523.225 +    tmp12 = tmp1 - tmp2;
 523.226 +    
 523.227 +    /* Odd part per figure 8; the matrix is unitary and hence its
 523.228 +     * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
 523.229 +     */
 523.230 +    
 523.231 +    tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
 523.232 +    tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
 523.233 +    tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
 523.234 +    tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
 523.235 +    
 523.236 +    z1 = tmp0 + tmp3;
 523.237 +    z2 = tmp1 + tmp2;
 523.238 +    z3 = tmp0 + tmp2;
 523.239 +    z4 = tmp1 + tmp3;
 523.240 +    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
 523.241 +    
 523.242 +    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
 523.243 +    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
 523.244 +    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
 523.245 +    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
 523.246 +    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
 523.247 +    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
 523.248 +    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
 523.249 +    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
 523.250 +    
 523.251 +    z3 += z5;
 523.252 +    z4 += z5;
 523.253 +    
 523.254 +    tmp0 += z1 + z3;
 523.255 +    tmp1 += z2 + z4;
 523.256 +    tmp2 += z2 + z3;
 523.257 +    tmp3 += z1 + z4;
 523.258 +    
 523.259 +    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
 523.260 +    
 523.261 +    wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
 523.262 +    wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
 523.263 +    wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
 523.264 +    wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
 523.265 +    wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
 523.266 +    wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
 523.267 +    wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
 523.268 +    wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
 523.269 +    
 523.270 +    inptr++;			/* advance pointers to next column */
 523.271 +    quantptr++;
 523.272 +    wsptr++;
 523.273 +  }
 523.274 +  
 523.275 +  /* Pass 2: process rows from work array, store into output array. */
 523.276 +  /* Note that we must descale the results by a factor of 8 == 2**3, */
 523.277 +  /* and also undo the PASS1_BITS scaling. */
 523.278 +
 523.279 +  wsptr = workspace;
 523.280 +  for (ctr = 0; ctr < DCTSIZE; ctr++) {
 523.281 +    outptr = output_buf[ctr] + output_col;
 523.282 +    /* Rows of zeroes can be exploited in the same way as we did with columns.
 523.283 +     * However, the column calculation has created many nonzero AC terms, so
 523.284 +     * the simplification applies less often (typically 5% to 10% of the time).
 523.285 +     * On machines with very fast multiplication, it's possible that the
 523.286 +     * test takes more time than it's worth.  In that case this section
 523.287 +     * may be commented out.
 523.288 +     */
 523.289 +    
 523.290 +#ifndef NO_ZERO_ROW_TEST
 523.291 +    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
 523.292 +	wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
 523.293 +      /* AC terms all zero */
 523.294 +      JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
 523.295 +				  & RANGE_MASK];
 523.296 +      
 523.297 +      outptr[0] = dcval;
 523.298 +      outptr[1] = dcval;
 523.299 +      outptr[2] = dcval;
 523.300 +      outptr[3] = dcval;
 523.301 +      outptr[4] = dcval;
 523.302 +      outptr[5] = dcval;
 523.303 +      outptr[6] = dcval;
 523.304 +      outptr[7] = dcval;
 523.305 +
 523.306 +      wsptr += DCTSIZE;		/* advance pointer to next row */
 523.307 +      continue;
 523.308 +    }
 523.309 +#endif
 523.310 +    
 523.311 +    /* Even part: reverse the even part of the forward DCT. */
 523.312 +    /* The rotator is sqrt(2)*c(-6). */
 523.313 +    
 523.314 +    z2 = (INT32) wsptr[2];
 523.315 +    z3 = (INT32) wsptr[6];
 523.316 +    
 523.317 +    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
 523.318 +    tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
 523.319 +    tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
 523.320 +    
 523.321 +    tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS;
 523.322 +    tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS;
 523.323 +    
 523.324 +    tmp10 = tmp0 + tmp3;
 523.325 +    tmp13 = tmp0 - tmp3;
 523.326 +    tmp11 = tmp1 + tmp2;
 523.327 +    tmp12 = tmp1 - tmp2;
 523.328 +    
 523.329 +    /* Odd part per figure 8; the matrix is unitary and hence its
 523.330 +     * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
 523.331 +     */
 523.332 +    
 523.333 +    tmp0 = (INT32) wsptr[7];
 523.334 +    tmp1 = (INT32) wsptr[5];
 523.335 +    tmp2 = (INT32) wsptr[3];
 523.336 +    tmp3 = (INT32) wsptr[1];
 523.337 +    
 523.338 +    z1 = tmp0 + tmp3;
 523.339 +    z2 = tmp1 + tmp2;
 523.340 +    z3 = tmp0 + tmp2;
 523.341 +    z4 = tmp1 + tmp3;
 523.342 +    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
 523.343 +    
 523.344 +    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
 523.345 +    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
 523.346 +    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
 523.347 +    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
 523.348 +    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
 523.349 +    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
 523.350 +    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
 523.351 +    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
 523.352 +    
 523.353 +    z3 += z5;
 523.354 +    z4 += z5;
 523.355 +    
 523.356 +    tmp0 += z1 + z3;
 523.357 +    tmp1 += z2 + z4;
 523.358 +    tmp2 += z2 + z3;
 523.359 +    tmp3 += z1 + z4;
 523.360 +    
 523.361 +    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
 523.362 +    
 523.363 +    outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3,
 523.364 +					  CONST_BITS+PASS1_BITS+3)
 523.365 +			    & RANGE_MASK];
 523.366 +    outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3,
 523.367 +					  CONST_BITS+PASS1_BITS+3)
 523.368 +			    & RANGE_MASK];
 523.369 +    outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2,
 523.370 +					  CONST_BITS+PASS1_BITS+3)
 523.371 +			    & RANGE_MASK];
 523.372 +    outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2,
 523.373 +					  CONST_BITS+PASS1_BITS+3)
 523.374 +			    & RANGE_MASK];
 523.375 +    outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1,
 523.376 +					  CONST_BITS+PASS1_BITS+3)
 523.377 +			    & RANGE_MASK];
 523.378 +    outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1,
 523.379 +					  CONST_BITS+PASS1_BITS+3)
 523.380 +			    & RANGE_MASK];
 523.381 +    outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0,
 523.382 +					  CONST_BITS+PASS1_BITS+3)
 523.383 +			    & RANGE_MASK];
 523.384 +    outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
 523.385 +					  CONST_BITS+PASS1_BITS+3)
 523.386 +			    & RANGE_MASK];
 523.387 +    
 523.388 +    wsptr += DCTSIZE;		/* advance pointer to next row */
 523.389 +  }
 523.390 +}
 523.391 +
 523.392 +#endif /* DCT_ISLOW_SUPPORTED */
   524.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   524.2 +++ b/libs/libjpeg/jidctred.c	Sat Feb 01 19:58:19 2014 +0200
   524.3 @@ -0,0 +1,398 @@
   524.4 +/*
   524.5 + * jidctred.c
   524.6 + *
   524.7 + * Copyright (C) 1994-1998, Thomas G. Lane.
   524.8 + * This file is part of the Independent JPEG Group's software.
   524.9 + * For conditions of distribution and use, see the accompanying README file.
  524.10 + *
  524.11 + * This file contains inverse-DCT routines that produce reduced-size output:
  524.12 + * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.
  524.13 + *
  524.14 + * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
  524.15 + * algorithm used in jidctint.c.  We simply replace each 8-to-8 1-D IDCT step
  524.16 + * with an 8-to-4 step that produces the four averages of two adjacent outputs
  524.17 + * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
  524.18 + * These steps were derived by computing the corresponding values at the end
  524.19 + * of the normal LL&M code, then simplifying as much as possible.
  524.20 + *
  524.21 + * 1x1 is trivial: just take the DC coefficient divided by 8.
  524.22 + *
  524.23 + * See jidctint.c for additional comments.
  524.24 + */
  524.25 +
  524.26 +#define JPEG_INTERNALS
  524.27 +#include "jinclude.h"
  524.28 +#include "jpeglib.h"
  524.29 +#include "jdct.h"		/* Private declarations for DCT subsystem */
  524.30 +
  524.31 +#ifdef IDCT_SCALING_SUPPORTED
  524.32 +
  524.33 +
  524.34 +/*
  524.35 + * This module is specialized to the case DCTSIZE = 8.
  524.36 + */
  524.37 +
  524.38 +#if DCTSIZE != 8
  524.39 +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
  524.40 +#endif
  524.41 +
  524.42 +
  524.43 +/* Scaling is the same as in jidctint.c. */
  524.44 +
  524.45 +#if BITS_IN_JSAMPLE == 8
  524.46 +#define CONST_BITS  13
  524.47 +#define PASS1_BITS  2
  524.48 +#else
  524.49 +#define CONST_BITS  13
  524.50 +#define PASS1_BITS  1		/* lose a little precision to avoid overflow */
  524.51 +#endif
  524.52 +
  524.53 +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
  524.54 + * causing a lot of useless floating-point operations at run time.
  524.55 + * To get around this we use the following pre-calculated constants.
  524.56 + * If you change CONST_BITS you may want to add appropriate values.
  524.57 + * (With a reasonable C compiler, you can just rely on the FIX() macro...)
  524.58 + */
  524.59 +
  524.60 +#if CONST_BITS == 13
  524.61 +#define FIX_0_211164243  ((INT32)  1730)	/* FIX(0.211164243) */
  524.62 +#define FIX_0_509795579  ((INT32)  4176)	/* FIX(0.509795579) */
  524.63 +#define FIX_0_601344887  ((INT32)  4926)	/* FIX(0.601344887) */
  524.64 +#define FIX_0_720959822  ((INT32)  5906)	/* FIX(0.720959822) */
  524.65 +#define FIX_0_765366865  ((INT32)  6270)	/* FIX(0.765366865) */
  524.66 +#define FIX_0_850430095  ((INT32)  6967)	/* FIX(0.850430095) */
  524.67 +#define FIX_0_899976223  ((INT32)  7373)	/* FIX(0.899976223) */
  524.68 +#define FIX_1_061594337  ((INT32)  8697)	/* FIX(1.061594337) */
  524.69 +#define FIX_1_272758580  ((INT32)  10426)	/* FIX(1.272758580) */
  524.70 +#define FIX_1_451774981  ((INT32)  11893)	/* FIX(1.451774981) */
  524.71 +#define FIX_1_847759065  ((INT32)  15137)	/* FIX(1.847759065) */
  524.72 +#define FIX_2_172734803  ((INT32)  17799)	/* FIX(2.172734803) */
  524.73 +#define FIX_2_562915447  ((INT32)  20995)	/* FIX(2.562915447) */
  524.74 +#define FIX_3_624509785  ((INT32)  29692)	/* FIX(3.624509785) */
  524.75 +#else
  524.76 +#define FIX_0_211164243  FIX(0.211164243)
  524.77 +#define FIX_0_509795579  FIX(0.509795579)
  524.78 +#define FIX_0_601344887  FIX(0.601344887)
  524.79 +#define FIX_0_720959822  FIX(0.720959822)
  524.80 +#define FIX_0_765366865  FIX(0.765366865)
  524.81 +#define FIX_0_850430095  FIX(0.850430095)
  524.82 +#define FIX_0_899976223  FIX(0.899976223)
  524.83 +#define FIX_1_061594337  FIX(1.061594337)
  524.84 +#define FIX_1_272758580  FIX(1.272758580)
  524.85 +#define FIX_1_451774981  FIX(1.451774981)
  524.86 +#define FIX_1_847759065  FIX(1.847759065)
  524.87 +#define FIX_2_172734803  FIX(2.172734803)
  524.88 +#define FIX_2_562915447  FIX(2.562915447)
  524.89 +#define FIX_3_624509785  FIX(3.624509785)
  524.90 +#endif
  524.91 +
  524.92 +
  524.93 +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
  524.94 + * For 8-bit samples with the recommended scaling, all the variable
  524.95 + * and constant values involved are no more than 16 bits wide, so a
  524.96 + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
  524.97 + * For 12-bit samples, a full 32-bit multiplication will be needed.
  524.98 + */
  524.99 +
 524.100 +#if BITS_IN_JSAMPLE == 8
 524.101 +#define MULTIPLY(var,const)  MULTIPLY16C16(var,const)
 524.102 +#else
 524.103 +#define MULTIPLY(var,const)  ((var) * (const))
 524.104 +#endif
 524.105 +
 524.106 +
 524.107 +/* Dequantize a coefficient by multiplying it by the multiplier-table
 524.108 + * entry; produce an int result.  In this module, both inputs and result
 524.109 + * are 16 bits or less, so either int or short multiply will work.
 524.110 + */
 524.111 +
 524.112 +#define DEQUANTIZE(coef,quantval)  (((ISLOW_MULT_TYPE) (coef)) * (quantval))
 524.113 +
 524.114 +
 524.115 +/*
 524.116 + * Perform dequantization and inverse DCT on one block of coefficients,
 524.117 + * producing a reduced-size 4x4 output block.
 524.118 + */
 524.119 +
 524.120 +GLOBAL(void)
 524.121 +jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 524.122 +	       JCOEFPTR coef_block,
 524.123 +	       JSAMPARRAY output_buf, JDIMENSION output_col)
 524.124 +{
 524.125 +  INT32 tmp0, tmp2, tmp10, tmp12;
 524.126 +  INT32 z1, z2, z3, z4;
 524.127 +  JCOEFPTR inptr;
 524.128 +  ISLOW_MULT_TYPE * quantptr;
 524.129 +  int * wsptr;
 524.130 +  JSAMPROW outptr;
 524.131 +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
 524.132 +  int ctr;
 524.133 +  int workspace[DCTSIZE*4];	/* buffers data between passes */
 524.134 +  SHIFT_TEMPS
 524.135 +
 524.136 +  /* Pass 1: process columns from input, store into work array. */
 524.137 +
 524.138 +  inptr = coef_block;
 524.139 +  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
 524.140 +  wsptr = workspace;
 524.141 +  for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
 524.142 +    /* Don't bother to process column 4, because second pass won't use it */
 524.143 +    if (ctr == DCTSIZE-4)
 524.144 +      continue;
 524.145 +    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
 524.146 +	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
 524.147 +	inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
 524.148 +      /* AC terms all zero; we need not examine term 4 for 4x4 output */
 524.149 +      int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
 524.150 +      
 524.151 +      wsptr[DCTSIZE*0] = dcval;
 524.152 +      wsptr[DCTSIZE*1] = dcval;
 524.153 +      wsptr[DCTSIZE*2] = dcval;
 524.154 +      wsptr[DCTSIZE*3] = dcval;
 524.155 +      
 524.156 +      continue;
 524.157 +    }
 524.158 +    
 524.159 +    /* Even part */
 524.160 +    
 524.161 +    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
 524.162 +    tmp0 <<= (CONST_BITS+1);
 524.163 +    
 524.164 +    z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
 524.165 +    z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
 524.166 +
 524.167 +    tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
 524.168 +    
 524.169 +    tmp10 = tmp0 + tmp2;
 524.170 +    tmp12 = tmp0 - tmp2;
 524.171 +    
 524.172 +    /* Odd part */
 524.173 +    
 524.174 +    z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
 524.175 +    z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
 524.176 +    z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
 524.177 +    z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
 524.178 +    
 524.179 +    tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
 524.180 +	 + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
 524.181 +	 + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
 524.182 +	 + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
 524.183 +    
 524.184 +    tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
 524.185 +	 + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
 524.186 +	 + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
 524.187 +	 + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
 524.188 +
 524.189 +    /* Final output stage */
 524.190 +    
 524.191 +    wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1);
 524.192 +    wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1);
 524.193 +    wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1);
 524.194 +    wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1);
 524.195 +  }
 524.196 +  
 524.197 +  /* Pass 2: process 4 rows from work array, store into output array. */
 524.198 +
 524.199 +  wsptr = workspace;
 524.200 +  for (ctr = 0; ctr < 4; ctr++) {
 524.201 +    outptr = output_buf[ctr] + output_col;
 524.202 +    /* It's not clear whether a zero row test is worthwhile here ... */
 524.203 +
 524.204 +#ifndef NO_ZERO_ROW_TEST
 524.205 +    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
 524.206 +	wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
 524.207 +      /* AC terms all zero */
 524.208 +      JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
 524.209 +				  & RANGE_MASK];
 524.210 +      
 524.211 +      outptr[0] = dcval;
 524.212 +      outptr[1] = dcval;
 524.213 +      outptr[2] = dcval;
 524.214 +      outptr[3] = dcval;
 524.215 +      
 524.216 +      wsptr += DCTSIZE;		/* advance pointer to next row */
 524.217 +      continue;
 524.218 +    }
 524.219 +#endif
 524.220 +    
 524.221 +    /* Even part */
 524.222 +    
 524.223 +    tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1);
 524.224 +    
 524.225 +    tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065)
 524.226 +	 + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865);
 524.227 +    
 524.228 +    tmp10 = tmp0 + tmp2;
 524.229 +    tmp12 = tmp0 - tmp2;
 524.230 +    
 524.231 +    /* Odd part */
 524.232 +    
 524.233 +    z1 = (INT32) wsptr[7];
 524.234 +    z2 = (INT32) wsptr[5];
 524.235 +    z3 = (INT32) wsptr[3];
 524.236 +    z4 = (INT32) wsptr[1];
 524.237 +    
 524.238 +    tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
 524.239 +	 + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
 524.240 +	 + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
 524.241 +	 + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
 524.242 +    
 524.243 +    tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
 524.244 +	 + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
 524.245 +	 + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
 524.246 +	 + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
 524.247 +
 524.248 +    /* Final output stage */
 524.249 +    
 524.250 +    outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2,
 524.251 +					  CONST_BITS+PASS1_BITS+3+1)
 524.252 +			    & RANGE_MASK];
 524.253 +    outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2,
 524.254 +					  CONST_BITS+PASS1_BITS+3+1)
 524.255 +			    & RANGE_MASK];
 524.256 +    outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0,
 524.257 +					  CONST_BITS+PASS1_BITS+3+1)
 524.258 +			    & RANGE_MASK];
 524.259 +    outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0,
 524.260 +					  CONST_BITS+PASS1_BITS+3+1)
 524.261 +			    & RANGE_MASK];
 524.262 +    
 524.263 +    wsptr += DCTSIZE;		/* advance pointer to next row */
 524.264 +  }
 524.265 +}
 524.266 +
 524.267 +
 524.268 +/*
 524.269 + * Perform dequantization and inverse DCT on one block of coefficients,
 524.270 + * producing a reduced-size 2x2 output block.
 524.271 + */
 524.272 +
 524.273 +GLOBAL(void)
 524.274 +jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 524.275 +	       JCOEFPTR coef_block,
 524.276 +	       JSAMPARRAY output_buf, JDIMENSION output_col)
 524.277 +{
 524.278 +  INT32 tmp0, tmp10, z1;
 524.279 +  JCOEFPTR inptr;
 524.280 +  ISLOW_MULT_TYPE * quantptr;
 524.281 +  int * wsptr;
 524.282 +  JSAMPROW outptr;
 524.283 +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
 524.284 +  int ctr;
 524.285 +  int workspace[DCTSIZE*2];	/* buffers data between passes */
 524.286 +  SHIFT_TEMPS
 524.287 +
 524.288 +  /* Pass 1: process columns from input, store into work array. */
 524.289 +
 524.290 +  inptr = coef_block;
 524.291 +  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
 524.292 +  wsptr = workspace;
 524.293 +  for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
 524.294 +    /* Don't bother to process columns 2,4,6 */
 524.295 +    if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
 524.296 +      continue;
 524.297 +    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
 524.298 +	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
 524.299 +      /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
 524.300 +      int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
 524.301 +      
 524.302 +      wsptr[DCTSIZE*0] = dcval;
 524.303 +      wsptr[DCTSIZE*1] = dcval;
 524.304 +      
 524.305 +      continue;
 524.306 +    }
 524.307 +    
 524.308 +    /* Even part */
 524.309 +    
 524.310 +    z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
 524.311 +    tmp10 = z1 << (CONST_BITS+2);
 524.312 +    
 524.313 +    /* Odd part */
 524.314 +
 524.315 +    z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
 524.316 +    tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */
 524.317 +    z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
 524.318 +    tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */
 524.319 +    z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
 524.320 +    tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
 524.321 +    z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
 524.322 +    tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
 524.323 +
 524.324 +    /* Final output stage */
 524.325 +    
 524.326 +    wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2);
 524.327 +    wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2);
 524.328 +  }
 524.329 +  
 524.330 +  /* Pass 2: process 2 rows from work array, store into output array. */
 524.331 +
 524.332 +  wsptr = workspace;
 524.333 +  for (ctr = 0; ctr < 2; ctr++) {
 524.334 +    outptr = output_buf[ctr] + output_col;
 524.335 +    /* It's not clear whether a zero row test is worthwhile here ... */
 524.336 +
 524.337 +#ifndef NO_ZERO_ROW_TEST
 524.338 +    if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
 524.339 +      /* AC terms all zero */
 524.340 +      JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
 524.341 +				  & RANGE_MASK];
 524.342 +      
 524.343 +      outptr[0] = dcval;
 524.344 +      outptr[1] = dcval;
 524.345 +      
 524.346 +      wsptr += DCTSIZE;		/* advance pointer to next row */
 524.347 +      continue;
 524.348 +    }
 524.349 +#endif
 524.350 +    
 524.351 +    /* Even part */
 524.352 +    
 524.353 +    tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2);
 524.354 +    
 524.355 +    /* Odd part */
 524.356 +
 524.357 +    tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */
 524.358 +	 + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */
 524.359 +	 + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */
 524.360 +	 + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
 524.361 +
 524.362 +    /* Final output stage */
 524.363 +    
 524.364 +    outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0,
 524.365 +					  CONST_BITS+PASS1_BITS+3+2)
 524.366 +			    & RANGE_MASK];
 524.367 +    outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0,
 524.368 +					  CONST_BITS+PASS1_BITS+3+2)
 524.369 +			    & RANGE_MASK];
 524.370 +    
 524.371 +    wsptr += DCTSIZE;		/* advance pointer to next row */
 524.372 +  }
 524.373 +}
 524.374 +
 524.375 +
 524.376 +/*
 524.377 + * Perform dequantization and inverse DCT on one block of coefficients,
 524.378 + * producing a reduced-size 1x1 output block.
 524.379 + */
 524.380 +
 524.381 +GLOBAL(void)
 524.382 +jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 524.383 +	       JCOEFPTR coef_block,
 524.384 +	       JSAMPARRAY output_buf, JDIMENSION output_col)
 524.385 +{
 524.386 +  int dcval;
 524.387 +  ISLOW_MULT_TYPE * quantptr;
 524.388 +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
 524.389 +  SHIFT_TEMPS
 524.390 +
 524.391 +  /* We hardly need an inverse DCT routine for this: just take the
 524.392 +   * average pixel value, which is one-eighth of the DC coefficient.
 524.393 +   */
 524.394 +  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
 524.395 +  dcval = DEQUANTIZE(coef_block[0], quantptr[0]);
 524.396 +  dcval = (int) DESCALE((INT32) dcval, 3);
 524.397 +
 524.398 +  output_buf[0][output_col] = range_limit[dcval & RANGE_MASK];
 524.399 +}
 524.400 +
 524.401 +#endif /* IDCT_SCALING_SUPPORTED */
   525.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   525.2 +++ b/libs/libjpeg/jinclude.h	Sat Feb 01 19:58:19 2014 +0200
   525.3 @@ -0,0 +1,91 @@
   525.4 +/*
   525.5 + * jinclude.h
   525.6 + *
   525.7 + * Copyright (C) 1991-1994, Thomas G. Lane.
   525.8 + * This file is part of the Independent JPEG Group's software.
   525.9 + * For conditions of distribution and use, see the accompanying README file.
  525.10 + *
  525.11 + * This file exists to provide a single place to fix any problems with
  525.12 + * including the wrong system include files.  (Common problems are taken
  525.13 + * care of by the standard jconfig symbols, but on really weird systems
  525.14 + * you may have to edit this file.)
  525.15 + *
  525.16 + * NOTE: this file is NOT intended to be included by applications using the
  525.17 + * JPEG library.  Most applications need only include jpeglib.h.
  525.18 + */
  525.19 +
  525.20 +
  525.21 +/* Include auto-config file to find out which system include files we need. */
  525.22 +
  525.23 +#include "jconfig.h"		/* auto configuration options */
  525.24 +#define JCONFIG_INCLUDED	/* so that jpeglib.h doesn't do it again */
  525.25 +
  525.26 +/*
  525.27 + * We need the NULL macro and size_t typedef.
  525.28 + * On an ANSI-conforming system it is sufficient to include <stddef.h>.
  525.29 + * Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
  525.30 + * pull in <sys/types.h> as well.
  525.31 + * Note that the core JPEG library does not require <stdio.h>;
  525.32 + * only the default error handler and data source/destination modules do.
  525.33 + * But we must pull it in because of the references to FILE in jpeglib.h.
  525.34 + * You can remove those references if you want to compile without <stdio.h>.
  525.35 + */
  525.36 +
  525.37 +#ifdef HAVE_STDDEF_H
  525.38 +#include <stddef.h>
  525.39 +#endif
  525.40 +
  525.41 +#ifdef HAVE_STDLIB_H
  525.42 +#include <stdlib.h>
  525.43 +#endif
  525.44 +
  525.45 +#ifdef NEED_SYS_TYPES_H
  525.46 +#include <sys/types.h>
  525.47 +#endif
  525.48 +
  525.49 +#include <stdio.h>
  525.50 +
  525.51 +/*
  525.52 + * We need memory copying and zeroing functions, plus strncpy().
  525.53 + * ANSI and System V implementations declare these in <string.h>.
  525.54 + * BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
  525.55 + * Some systems may declare memset and memcpy in <memory.h>.
  525.56 + *
  525.57 + * NOTE: we assume the size parameters to these functions are of type size_t.
  525.58 + * Change the casts in these macros if not!
  525.59 + */
  525.60 +
  525.61 +#ifdef NEED_BSD_STRINGS
  525.62 +
  525.63 +#include <strings.h>
  525.64 +#define MEMZERO(target,size)	bzero((void *)(target), (size_t)(size))
  525.65 +#define MEMCOPY(dest,src,size)	bcopy((const void *)(src), (void *)(dest), (size_t)(size))
  525.66 +
  525.67 +#else /* not BSD, assume ANSI/SysV string lib */
  525.68 +
  525.69 +#include <string.h>
  525.70 +#define MEMZERO(target,size)	memset((void *)(target), 0, (size_t)(size))
  525.71 +#define MEMCOPY(dest,src,size)	memcpy((void *)(dest), (const void *)(src), (size_t)(size))
  525.72 +
  525.73 +#endif
  525.74 +
  525.75 +/*
  525.76 + * In ANSI C, and indeed any rational implementation, size_t is also the
  525.77 + * type returned by sizeof().  However, it seems there are some irrational
  525.78 + * implementations out there, in which sizeof() returns an int even though
  525.79 + * size_t is defined as long or unsigned long.  To ensure consistent results
  525.80 + * we always use this SIZEOF() macro in place of using sizeof() directly.
  525.81 + */
  525.82 +
  525.83 +#define SIZEOF(object)	((size_t) sizeof(object))
  525.84 +
  525.85 +/*
  525.86 + * The modules that use fread() and fwrite() always invoke them through
  525.87 + * these macros.  On some systems you may need to twiddle the argument casts.
  525.88 + * CAUTION: argument order is different from underlying functions!
  525.89 + */
  525.90 +
  525.91 +#define JFREAD(file,buf,sizeofbuf)  \
  525.92 +  ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
  525.93 +#define JFWRITE(file,buf,sizeofbuf)  \
  525.94 +  ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
   526.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   526.2 +++ b/libs/libjpeg/jmemmgr.c	Sat Feb 01 19:58:19 2014 +0200
   526.3 @@ -0,0 +1,1118 @@
   526.4 +/*
   526.5 + * jmemmgr.c
   526.6 + *
   526.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   526.8 + * This file is part of the Independent JPEG Group's software.
   526.9 + * For conditions of distribution and use, see the accompanying README file.
  526.10 + *
  526.11 + * This file contains the JPEG system-independent memory management
  526.12 + * routines.  This code is usable across a wide variety of machines; most
  526.13 + * of the system dependencies have been isolated in a separate file.
  526.14 + * The major functions provided here are:
  526.15 + *   * pool-based allocation and freeing of memory;
  526.16 + *   * policy decisions about how to divide available memory among the
  526.17 + *     virtual arrays;
  526.18 + *   * control logic for swapping virtual arrays between main memory and
  526.19 + *     backing storage.
  526.20 + * The separate system-dependent file provides the actual backing-storage
  526.21 + * access code, and it contains the policy decision about how much total
  526.22 + * main memory to use.
  526.23 + * This file is system-dependent in the sense that some of its functions
  526.24 + * are unnecessary in some systems.  For example, if there is enough virtual
  526.25 + * memory so that backing storage will never be used, much of the virtual
  526.26 + * array control logic could be removed.  (Of course, if you have that much
  526.27 + * memory then you shouldn't care about a little bit of unused code...)
  526.28 + */
  526.29 +
  526.30 +#define JPEG_INTERNALS
  526.31 +#define AM_MEMORY_MANAGER	/* we define jvirt_Xarray_control structs */
  526.32 +#include "jinclude.h"
  526.33 +#include "jpeglib.h"
  526.34 +#include "jmemsys.h"		/* import the system-dependent declarations */
  526.35 +
  526.36 +#ifndef NO_GETENV
  526.37 +#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare getenv() */
  526.38 +extern char * getenv JPP((const char * name));
  526.39 +#endif
  526.40 +#endif
  526.41 +
  526.42 +
  526.43 +/*
  526.44 + * Some important notes:
  526.45 + *   The allocation routines provided here must never return NULL.
  526.46 + *   They should exit to error_exit if unsuccessful.
  526.47 + *
  526.48 + *   It's not a good idea to try to merge the sarray and barray routines,
  526.49 + *   even though they are textually almost the same, because samples are
  526.50 + *   usually stored as bytes while coefficients are shorts or ints.  Thus,
  526.51 + *   in machines where byte pointers have a different representation from
  526.52 + *   word pointers, the resulting machine code could not be the same.
  526.53 + */
  526.54 +
  526.55 +
  526.56 +/*
  526.57 + * Many machines require storage alignment: longs must start on 4-byte
  526.58 + * boundaries, doubles on 8-byte boundaries, etc.  On such machines, malloc()
  526.59 + * always returns pointers that are multiples of the worst-case alignment
  526.60 + * requirement, and we had better do so too.
  526.61 + * There isn't any really portable way to determine the worst-case alignment
  526.62 + * requirement.  This module assumes that the alignment requirement is
  526.63 + * multiples of sizeof(ALIGN_TYPE).
  526.64 + * By default, we define ALIGN_TYPE as double.  This is necessary on some
  526.65 + * workstations (where doubles really do need 8-byte alignment) and will work
  526.66 + * fine on nearly everything.  If your machine has lesser alignment needs,
  526.67 + * you can save a few bytes by making ALIGN_TYPE smaller.
  526.68 + * The only place I know of where this will NOT work is certain Macintosh
  526.69 + * 680x0 compilers that define double as a 10-byte IEEE extended float.
  526.70 + * Doing 10-byte alignment is counterproductive because longwords won't be
  526.71 + * aligned well.  Put "#define ALIGN_TYPE long" in jconfig.h if you have
  526.72 + * such a compiler.
  526.73 + */
  526.74 +
  526.75 +#ifndef ALIGN_TYPE		/* so can override from jconfig.h */
  526.76 +#define ALIGN_TYPE  double
  526.77 +#endif
  526.78 +
  526.79 +
  526.80 +/*
  526.81 + * We allocate objects from "pools", where each pool is gotten with a single
  526.82 + * request to jpeg_get_small() or jpeg_get_large().  There is no per-object
  526.83 + * overhead within a pool, except for alignment padding.  Each pool has a
  526.84 + * header with a link to the next pool of the same class.
  526.85 + * Small and large pool headers are identical except that the latter's
  526.86 + * link pointer must be FAR on 80x86 machines.
  526.87 + * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
  526.88 + * field.  This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
  526.89 + * of the alignment requirement of ALIGN_TYPE.
  526.90 + */
  526.91 +
  526.92 +typedef union small_pool_struct * small_pool_ptr;
  526.93 +
  526.94 +typedef union small_pool_struct {
  526.95 +  struct {
  526.96 +    small_pool_ptr next;	/* next in list of pools */
  526.97 +    size_t bytes_used;		/* how many bytes already used within pool */
  526.98 +    size_t bytes_left;		/* bytes still available in this pool */
  526.99 +  } hdr;
 526.100 +  ALIGN_TYPE dummy;		/* included in union to ensure alignment */
 526.101 +} small_pool_hdr;
 526.102 +
 526.103 +typedef union large_pool_struct FAR * large_pool_ptr;
 526.104 +
 526.105 +typedef union large_pool_struct {
 526.106 +  struct {
 526.107 +    large_pool_ptr next;	/* next in list of pools */
 526.108 +    size_t bytes_used;		/* how many bytes already used within pool */
 526.109 +    size_t bytes_left;		/* bytes still available in this pool */
 526.110 +  } hdr;
 526.111 +  ALIGN_TYPE dummy;		/* included in union to ensure alignment */
 526.112 +} large_pool_hdr;
 526.113 +
 526.114 +
 526.115 +/*
 526.116 + * Here is the full definition of a memory manager object.
 526.117 + */
 526.118 +
 526.119 +typedef struct {
 526.120 +  struct jpeg_memory_mgr pub;	/* public fields */
 526.121 +
 526.122 +  /* Each pool identifier (lifetime class) names a linked list of pools. */
 526.123 +  small_pool_ptr small_list[JPOOL_NUMPOOLS];
 526.124 +  large_pool_ptr large_list[JPOOL_NUMPOOLS];
 526.125 +
 526.126 +  /* Since we only have one lifetime class of virtual arrays, only one
 526.127 +   * linked list is necessary (for each datatype).  Note that the virtual
 526.128 +   * array control blocks being linked together are actually stored somewhere
 526.129 +   * in the small-pool list.
 526.130 +   */
 526.131 +  jvirt_sarray_ptr virt_sarray_list;
 526.132 +  jvirt_barray_ptr virt_barray_list;
 526.133 +
 526.134 +  /* This counts total space obtained from jpeg_get_small/large */
 526.135 +  long total_space_allocated;
 526.136 +
 526.137 +  /* alloc_sarray and alloc_barray set this value for use by virtual
 526.138 +   * array routines.
 526.139 +   */
 526.140 +  JDIMENSION last_rowsperchunk;	/* from most recent alloc_sarray/barray */
 526.141 +} my_memory_mgr;
 526.142 +
 526.143 +typedef my_memory_mgr * my_mem_ptr;
 526.144 +
 526.145 +
 526.146 +/*
 526.147 + * The control blocks for virtual arrays.
 526.148 + * Note that these blocks are allocated in the "small" pool area.
 526.149 + * System-dependent info for the associated backing store (if any) is hidden
 526.150 + * inside the backing_store_info struct.
 526.151 + */
 526.152 +
 526.153 +struct jvirt_sarray_control {
 526.154 +  JSAMPARRAY mem_buffer;	/* => the in-memory buffer */
 526.155 +  JDIMENSION rows_in_array;	/* total virtual array height */
 526.156 +  JDIMENSION samplesperrow;	/* width of array (and of memory buffer) */
 526.157 +  JDIMENSION maxaccess;		/* max rows accessed by access_virt_sarray */
 526.158 +  JDIMENSION rows_in_mem;	/* height of memory buffer */
 526.159 +  JDIMENSION rowsperchunk;	/* allocation chunk size in mem_buffer */
 526.160 +  JDIMENSION cur_start_row;	/* first logical row # in the buffer */
 526.161 +  JDIMENSION first_undef_row;	/* row # of first uninitialized row */
 526.162 +  boolean pre_zero;		/* pre-zero mode requested? */
 526.163 +  boolean dirty;		/* do current buffer contents need written? */
 526.164 +  boolean b_s_open;		/* is backing-store data valid? */
 526.165 +  jvirt_sarray_ptr next;	/* link to next virtual sarray control block */
 526.166 +  backing_store_info b_s_info;	/* System-dependent control info */
 526.167 +};
 526.168 +
 526.169 +struct jvirt_barray_control {
 526.170 +  JBLOCKARRAY mem_buffer;	/* => the in-memory buffer */
 526.171 +  JDIMENSION rows_in_array;	/* total virtual array height */
 526.172 +  JDIMENSION blocksperrow;	/* width of array (and of memory buffer) */
 526.173 +  JDIMENSION maxaccess;		/* max rows accessed by access_virt_barray */
 526.174 +  JDIMENSION rows_in_mem;	/* height of memory buffer */
 526.175 +  JDIMENSION rowsperchunk;	/* allocation chunk size in mem_buffer */
 526.176 +  JDIMENSION cur_start_row;	/* first logical row # in the buffer */
 526.177 +  JDIMENSION first_undef_row;	/* row # of first uninitialized row */
 526.178 +  boolean pre_zero;		/* pre-zero mode requested? */
 526.179 +  boolean dirty;		/* do current buffer contents need written? */
 526.180 +  boolean b_s_open;		/* is backing-store data valid? */
 526.181 +  jvirt_barray_ptr next;	/* link to next virtual barray control block */
 526.182 +  backing_store_info b_s_info;	/* System-dependent control info */
 526.183 +};
 526.184 +
 526.185 +
 526.186 +#ifdef MEM_STATS		/* optional extra stuff for statistics */
 526.187 +
 526.188 +LOCAL(void)
 526.189 +print_mem_stats (j_common_ptr cinfo, int pool_id)
 526.190 +{
 526.191 +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 526.192 +  small_pool_ptr shdr_ptr;
 526.193 +  large_pool_ptr lhdr_ptr;
 526.194 +
 526.195 +  /* Since this is only a debugging stub, we can cheat a little by using
 526.196 +   * fprintf directly rather than going through the trace message code.
 526.197 +   * This is helpful because message parm array can't handle longs.
 526.198 +   */
 526.199 +  fprintf(stderr, "Freeing pool %d, total space = %ld\n",
 526.200 +	  pool_id, mem->total_space_allocated);
 526.201 +
 526.202 +  for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
 526.203 +       lhdr_ptr = lhdr_ptr->hdr.next) {
 526.204 +    fprintf(stderr, "  Large chunk used %ld\n",
 526.205 +	    (long) lhdr_ptr->hdr.bytes_used);
 526.206 +  }
 526.207 +
 526.208 +  for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
 526.209 +       shdr_ptr = shdr_ptr->hdr.next) {
 526.210 +    fprintf(stderr, "  Small chunk used %ld free %ld\n",
 526.211 +	    (long) shdr_ptr->hdr.bytes_used,
 526.212 +	    (long) shdr_ptr->hdr.bytes_left);
 526.213 +  }
 526.214 +}
 526.215 +
 526.216 +#endif /* MEM_STATS */
 526.217 +
 526.218 +
 526.219 +LOCAL(void)
 526.220 +out_of_memory (j_common_ptr cinfo, int which)
 526.221 +/* Report an out-of-memory error and stop execution */
 526.222 +/* If we compiled MEM_STATS support, report alloc requests before dying */
 526.223 +{
 526.224 +#ifdef MEM_STATS
 526.225 +  cinfo->err->trace_level = 2;	/* force self_destruct to report stats */
 526.226 +#endif
 526.227 +  ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which);
 526.228 +}
 526.229 +
 526.230 +
 526.231 +/*
 526.232 + * Allocation of "small" objects.
 526.233 + *
 526.234 + * For these, we use pooled storage.  When a new pool must be created,
 526.235 + * we try to get enough space for the current request plus a "slop" factor,
 526.236 + * where the slop will be the amount of leftover space in the new pool.
 526.237 + * The speed vs. space tradeoff is largely determined by the slop values.
 526.238 + * A different slop value is provided for each pool class (lifetime),
 526.239 + * and we also distinguish the first pool of a class from later ones.
 526.240 + * NOTE: the values given work fairly well on both 16- and 32-bit-int
 526.241 + * machines, but may be too small if longs are 64 bits or more.
 526.242 + */
 526.243 +
 526.244 +static const size_t first_pool_slop[JPOOL_NUMPOOLS] = 
 526.245 +{
 526.246 +	1600,			/* first PERMANENT pool */
 526.247 +	16000			/* first IMAGE pool */
 526.248 +};
 526.249 +
 526.250 +static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = 
 526.251 +{
 526.252 +	0,			/* additional PERMANENT pools */
 526.253 +	5000			/* additional IMAGE pools */
 526.254 +};
 526.255 +
 526.256 +#define MIN_SLOP  50		/* greater than 0 to avoid futile looping */
 526.257 +
 526.258 +
 526.259 +METHODDEF(void *)
 526.260 +alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
 526.261 +/* Allocate a "small" object */
 526.262 +{
 526.263 +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 526.264 +  small_pool_ptr hdr_ptr, prev_hdr_ptr;
 526.265 +  char * data_ptr;
 526.266 +  size_t odd_bytes, min_request, slop;
 526.267 +
 526.268 +  /* Check for unsatisfiable request (do now to ensure no overflow below) */
 526.269 +  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
 526.270 +    out_of_memory(cinfo, 1);	/* request exceeds malloc's ability */
 526.271 +
 526.272 +  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
 526.273 +  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
 526.274 +  if (odd_bytes > 0)
 526.275 +    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
 526.276 +
 526.277 +  /* See if space is available in any existing pool */
 526.278 +  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
 526.279 +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
 526.280 +  prev_hdr_ptr = NULL;
 526.281 +  hdr_ptr = mem->small_list[pool_id];
 526.282 +  while (hdr_ptr != NULL) {
 526.283 +    if (hdr_ptr->hdr.bytes_left >= sizeofobject)
 526.284 +      break;			/* found pool with enough space */
 526.285 +    prev_hdr_ptr = hdr_ptr;
 526.286 +    hdr_ptr = hdr_ptr->hdr.next;
 526.287 +  }
 526.288 +
 526.289 +  /* Time to make a new pool? */
 526.290 +  if (hdr_ptr == NULL) {
 526.291 +    /* min_request is what we need now, slop is what will be leftover */
 526.292 +    min_request = sizeofobject + SIZEOF(small_pool_hdr);
 526.293 +    if (prev_hdr_ptr == NULL)	/* first pool in class? */
 526.294 +      slop = first_pool_slop[pool_id];
 526.295 +    else
 526.296 +      slop = extra_pool_slop[pool_id];
 526.297 +    /* Don't ask for more than MAX_ALLOC_CHUNK */
 526.298 +    if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
 526.299 +      slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
 526.300 +    /* Try to get space, if fail reduce slop and try again */
 526.301 +    for (;;) {
 526.302 +      hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
 526.303 +      if (hdr_ptr != NULL)
 526.304 +	break;
 526.305 +      slop /= 2;
 526.306 +      if (slop < MIN_SLOP)	/* give up when it gets real small */
 526.307 +	out_of_memory(cinfo, 2); /* jpeg_get_small failed */
 526.308 +    }
 526.309 +    mem->total_space_allocated += min_request + slop;
 526.310 +    /* Success, initialize the new pool header and add to end of list */
 526.311 +    hdr_ptr->hdr.next = NULL;
 526.312 +    hdr_ptr->hdr.bytes_used = 0;
 526.313 +    hdr_ptr->hdr.bytes_left = sizeofobject + slop;
 526.314 +    if (prev_hdr_ptr == NULL)	/* first pool in class? */
 526.315 +      mem->small_list[pool_id] = hdr_ptr;
 526.316 +    else
 526.317 +      prev_hdr_ptr->hdr.next = hdr_ptr;
 526.318 +  }
 526.319 +
 526.320 +  /* OK, allocate the object from the current pool */
 526.321 +  data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
 526.322 +  data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
 526.323 +  hdr_ptr->hdr.bytes_used += sizeofobject;
 526.324 +  hdr_ptr->hdr.bytes_left -= sizeofobject;
 526.325 +
 526.326 +  return (void *) data_ptr;
 526.327 +}
 526.328 +
 526.329 +
 526.330 +/*
 526.331 + * Allocation of "large" objects.
 526.332 + *
 526.333 + * The external semantics of these are the same as "small" objects,
 526.334 + * except that FAR pointers are used on 80x86.  However the pool
 526.335 + * management heuristics are quite different.  We assume that each
 526.336 + * request is large enough that it may as well be passed directly to
 526.337 + * jpeg_get_large; the pool management just links everything together
 526.338 + * so that we can free it all on demand.
 526.339 + * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
 526.340 + * structures.  The routines that create these structures (see below)
 526.341 + * deliberately bunch rows together to ensure a large request size.
 526.342 + */
 526.343 +
 526.344 +METHODDEF(void FAR *)
 526.345 +alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
 526.346 +/* Allocate a "large" object */
 526.347 +{
 526.348 +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 526.349 +  large_pool_ptr hdr_ptr;
 526.350 +  size_t odd_bytes;
 526.351 +
 526.352 +  /* Check for unsatisfiable request (do now to ensure no overflow below) */
 526.353 +  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
 526.354 +    out_of_memory(cinfo, 3);	/* request exceeds malloc's ability */
 526.355 +
 526.356 +  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
 526.357 +  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
 526.358 +  if (odd_bytes > 0)
 526.359 +    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
 526.360 +
 526.361 +  /* Always make a new pool */
 526.362 +  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
 526.363 +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
 526.364 +
 526.365 +  hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
 526.366 +					    SIZEOF(large_pool_hdr));
 526.367 +  if (hdr_ptr == NULL)
 526.368 +    out_of_memory(cinfo, 4);	/* jpeg_get_large failed */
 526.369 +  mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
 526.370 +
 526.371 +  /* Success, initialize the new pool header and add to list */
 526.372 +  hdr_ptr->hdr.next = mem->large_list[pool_id];
 526.373 +  /* We maintain space counts in each pool header for statistical purposes,
 526.374 +   * even though they are not needed for allocation.
 526.375 +   */
 526.376 +  hdr_ptr->hdr.bytes_used = sizeofobject;
 526.377 +  hdr_ptr->hdr.bytes_left = 0;
 526.378 +  mem->large_list[pool_id] = hdr_ptr;
 526.379 +
 526.380 +  return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
 526.381 +}
 526.382 +
 526.383 +
 526.384 +/*
 526.385 + * Creation of 2-D sample arrays.
 526.386 + * The pointers are in near heap, the samples themselves in FAR heap.
 526.387 + *
 526.388 + * To minimize allocation overhead and to allow I/O of large contiguous
 526.389 + * blocks, we allocate the sample rows in groups of as many rows as possible
 526.390 + * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
 526.391 + * NB: the virtual array control routines, later in this file, know about
 526.392 + * this chunking of rows.  The rowsperchunk value is left in the mem manager
 526.393 + * object so that it can be saved away if this sarray is the workspace for
 526.394 + * a virtual array.
 526.395 + */
 526.396 +
 526.397 +METHODDEF(JSAMPARRAY)
 526.398 +alloc_sarray (j_common_ptr cinfo, int pool_id,
 526.399 +	      JDIMENSION samplesperrow, JDIMENSION numrows)
 526.400 +/* Allocate a 2-D sample array */
 526.401 +{
 526.402 +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 526.403 +  JSAMPARRAY result;
 526.404 +  JSAMPROW workspace;
 526.405 +  JDIMENSION rowsperchunk, currow, i;
 526.406 +  long ltemp;
 526.407 +
 526.408 +  /* Calculate max # of rows allowed in one allocation chunk */
 526.409 +  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
 526.410 +	  ((long) samplesperrow * SIZEOF(JSAMPLE));
 526.411 +  if (ltemp <= 0)
 526.412 +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
 526.413 +  if (ltemp < (long) numrows)
 526.414 +    rowsperchunk = (JDIMENSION) ltemp;
 526.415 +  else
 526.416 +    rowsperchunk = numrows;
 526.417 +  mem->last_rowsperchunk = rowsperchunk;
 526.418 +
 526.419 +  /* Get space for row pointers (small object) */
 526.420 +  result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
 526.421 +				    (size_t) (numrows * SIZEOF(JSAMPROW)));
 526.422 +
 526.423 +  /* Get the rows themselves (large objects) */
 526.424 +  currow = 0;
 526.425 +  while (currow < numrows) {
 526.426 +    rowsperchunk = MIN(rowsperchunk, numrows - currow);
 526.427 +    workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
 526.428 +	(size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
 526.429 +		  * SIZEOF(JSAMPLE)));
 526.430 +    for (i = rowsperchunk; i > 0; i--) {
 526.431 +      result[currow++] = workspace;
 526.432 +      workspace += samplesperrow;
 526.433 +    }
 526.434 +  }
 526.435 +
 526.436 +  return result;
 526.437 +}
 526.438 +
 526.439 +
 526.440 +/*
 526.441 + * Creation of 2-D coefficient-block arrays.
 526.442 + * This is essentially the same as the code for sample arrays, above.
 526.443 + */
 526.444 +
 526.445 +METHODDEF(JBLOCKARRAY)
 526.446 +alloc_barray (j_common_ptr cinfo, int pool_id,
 526.447 +	      JDIMENSION blocksperrow, JDIMENSION numrows)
 526.448 +/* Allocate a 2-D coefficient-block array */
 526.449 +{
 526.450 +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 526.451 +  JBLOCKARRAY result;
 526.452 +  JBLOCKROW workspace;
 526.453 +  JDIMENSION rowsperchunk, currow, i;
 526.454 +  long ltemp;
 526.455 +
 526.456 +  /* Calculate max # of rows allowed in one allocation chunk */
 526.457 +  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
 526.458 +	  ((long) blocksperrow * SIZEOF(JBLOCK));
 526.459 +  if (ltemp <= 0)
 526.460 +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
 526.461 +  if (ltemp < (long) numrows)
 526.462 +    rowsperchunk = (JDIMENSION) ltemp;
 526.463 +  else
 526.464 +    rowsperchunk = numrows;
 526.465 +  mem->last_rowsperchunk = rowsperchunk;
 526.466 +
 526.467 +  /* Get space for row pointers (small object) */
 526.468 +  result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
 526.469 +				     (size_t) (numrows * SIZEOF(JBLOCKROW)));
 526.470 +
 526.471 +  /* Get the rows themselves (large objects) */
 526.472 +  currow = 0;
 526.473 +  while (currow < numrows) {
 526.474 +    rowsperchunk = MIN(rowsperchunk, numrows - currow);
 526.475 +    workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
 526.476 +	(size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
 526.477 +		  * SIZEOF(JBLOCK)));
 526.478 +    for (i = rowsperchunk; i > 0; i--) {
 526.479 +      result[currow++] = workspace;
 526.480 +      workspace += blocksperrow;
 526.481 +    }
 526.482 +  }
 526.483 +
 526.484 +  return result;
 526.485 +}
 526.486 +
 526.487 +
 526.488 +/*
 526.489 + * About virtual array management:
 526.490 + *
 526.491 + * The above "normal" array routines are only used to allocate strip buffers
 526.492 + * (as wide as the image, but just a few rows high).  Full-image-sized buffers
 526.493 + * are handled as "virtual" arrays.  The array is still accessed a strip at a
 526.494 + * time, but the memory manager must save the whole array for repeated
 526.495 + * accesses.  The intended implementation is that there is a strip buffer in
 526.496 + * memory (as high as is possible given the desired memory limit), plus a
 526.497 + * backing file that holds the rest of the array.
 526.498 + *
 526.499 + * The request_virt_array routines are told the total size of the image and
 526.500 + * the maximum number of rows that will be accessed at once.  The in-memory
 526.501 + * buffer must be at least as large as the maxaccess value.
 526.502 + *
 526.503 + * The request routines create control blocks but not the in-memory buffers.
 526.504 + * That is postponed until realize_virt_arrays is called.  At that time the
 526.505 + * total amount of space needed is known (approximately, anyway), so free
 526.506 + * memory can be divided up fairly.
 526.507 + *
 526.508 + * The access_virt_array routines are responsible for making a specific strip
 526.509 + * area accessible (after reading or writing the backing file, if necessary).
 526.510 + * Note that the access routines are told whether the caller intends to modify
 526.511 + * the accessed strip; during a read-only pass this saves having to rewrite
 526.512 + * data to disk.  The access routines are also responsible for pre-zeroing
 526.513 + * any newly accessed rows, if pre-zeroing was requested.
 526.514 + *
 526.515 + * In current usage, the access requests are usually for nonoverlapping
 526.516 + * strips; that is, successive access start_row numbers differ by exactly
 526.517 + * num_rows = maxaccess.  This means we can get good performance with simple
 526.518 + * buffer dump/reload logic, by making the in-memory buffer be a multiple
 526.519 + * of the access height; then there will never be accesses across bufferload
 526.520 + * boundaries.  The code will still work with overlapping access requests,
 526.521 + * but it doesn't handle bufferload overlaps very efficiently.
 526.522 + */
 526.523 +
 526.524 +
 526.525 +METHODDEF(jvirt_sarray_ptr)
 526.526 +request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
 526.527 +		     JDIMENSION samplesperrow, JDIMENSION numrows,
 526.528 +		     JDIMENSION maxaccess)
 526.529 +/* Request a virtual 2-D sample array */
 526.530 +{
 526.531 +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 526.532 +  jvirt_sarray_ptr result;
 526.533 +
 526.534 +  /* Only IMAGE-lifetime virtual arrays are currently supported */
 526.535 +  if (pool_id != JPOOL_IMAGE)
 526.536 +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
 526.537 +
 526.538 +  /* get control block */
 526.539 +  result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
 526.540 +					  SIZEOF(struct jvirt_sarray_control));
 526.541 +
 526.542 +  result->mem_buffer = NULL;	/* marks array not yet realized */
 526.543 +  result->rows_in_array = numrows;
 526.544 +  result->samplesperrow = samplesperrow;
 526.545 +  result->maxaccess = maxaccess;
 526.546 +  result->pre_zero = pre_zero;
 526.547 +  result->b_s_open = FALSE;	/* no associated backing-store object */
 526.548 +  result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
 526.549 +  mem->virt_sarray_list = result;
 526.550 +
 526.551 +  return result;
 526.552 +}
 526.553 +
 526.554 +
 526.555 +METHODDEF(jvirt_barray_ptr)
 526.556 +request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
 526.557 +		     JDIMENSION blocksperrow, JDIMENSION numrows,
 526.558 +		     JDIMENSION maxaccess)
 526.559 +/* Request a virtual 2-D coefficient-block array */
 526.560 +{
 526.561 +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 526.562 +  jvirt_barray_ptr result;
 526.563 +
 526.564 +  /* Only IMAGE-lifetime virtual arrays are currently supported */
 526.565 +  if (pool_id != JPOOL_IMAGE)
 526.566 +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
 526.567 +
 526.568 +  /* get control block */
 526.569 +  result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
 526.570 +					  SIZEOF(struct jvirt_barray_control));
 526.571 +
 526.572 +  result->mem_buffer = NULL;	/* marks array not yet realized */
 526.573 +  result->rows_in_array = numrows;
 526.574 +  result->blocksperrow = blocksperrow;
 526.575 +  result->maxaccess = maxaccess;
 526.576 +  result->pre_zero = pre_zero;
 526.577 +  result->b_s_open = FALSE;	/* no associated backing-store object */
 526.578 +  result->next = mem->virt_barray_list; /* add to list of virtual arrays */
 526.579 +  mem->virt_barray_list = result;
 526.580 +
 526.581 +  return result;
 526.582 +}
 526.583 +
 526.584 +
 526.585 +METHODDEF(void)
 526.586 +realize_virt_arrays (j_common_ptr cinfo)
 526.587 +/* Allocate the in-memory buffers for any unrealized virtual arrays */
 526.588 +{
 526.589 +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 526.590 +  long space_per_minheight, maximum_space, avail_mem;
 526.591 +  long minheights, max_minheights;
 526.592 +  jvirt_sarray_ptr sptr;
 526.593 +  jvirt_barray_ptr bptr;
 526.594 +
 526.595 +  /* Compute the minimum space needed (maxaccess rows in each buffer)
 526.596 +   * and the maximum space needed (full image height in each buffer).
 526.597 +   * These may be of use to the system-dependent jpeg_mem_available routine.
 526.598 +   */
 526.599 +  space_per_minheight = 0;
 526.600 +  maximum_space = 0;
 526.601 +  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
 526.602 +    if (sptr->mem_buffer == NULL) { /* if not realized yet */
 526.603 +      space_per_minheight += (long) sptr->maxaccess *
 526.604 +			     (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
 526.605 +      maximum_space += (long) sptr->rows_in_array *
 526.606 +		       (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
 526.607 +    }
 526.608 +  }
 526.609 +  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
 526.610 +    if (bptr->mem_buffer == NULL) { /* if not realized yet */
 526.611 +      space_per_minheight += (long) bptr->maxaccess *
 526.612 +			     (long) bptr->blocksperrow * SIZEOF(JBLOCK);
 526.613 +      maximum_space += (long) bptr->rows_in_array *
 526.614 +		       (long) bptr->blocksperrow * SIZEOF(JBLOCK);
 526.615 +    }
 526.616 +  }
 526.617 +
 526.618 +  if (space_per_minheight <= 0)
 526.619 +    return;			/* no unrealized arrays, no work */
 526.620 +
 526.621 +  /* Determine amount of memory to actually use; this is system-dependent. */
 526.622 +  avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
 526.623 +				 mem->total_space_allocated);
 526.624 +
 526.625 +  /* If the maximum space needed is available, make all the buffers full
 526.626 +   * height; otherwise parcel it out with the same number of minheights
 526.627 +   * in each buffer.
 526.628 +   */
 526.629 +  if (avail_mem >= maximum_space)
 526.630 +    max_minheights = 1000000000L;
 526.631 +  else {
 526.632 +    max_minheights = avail_mem / space_per_minheight;
 526.633 +    /* If there doesn't seem to be enough space, try to get the minimum
 526.634 +     * anyway.  This allows a "stub" implementation of jpeg_mem_available().
 526.635 +     */
 526.636 +    if (max_minheights <= 0)
 526.637 +      max_minheights = 1;
 526.638 +  }
 526.639 +
 526.640 +  /* Allocate the in-memory buffers and initialize backing store as needed. */
 526.641 +
 526.642 +  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
 526.643 +    if (sptr->mem_buffer == NULL) { /* if not realized yet */
 526.644 +      minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L;
 526.645 +      if (minheights <= max_minheights) {
 526.646 +	/* This buffer fits in memory */
 526.647 +	sptr->rows_in_mem = sptr->rows_in_array;
 526.648 +      } else {
 526.649 +	/* It doesn't fit in memory, create backing store. */
 526.650 +	sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess);
 526.651 +	jpeg_open_backing_store(cinfo, & sptr->b_s_info,
 526.652 +				(long) sptr->rows_in_array *
 526.653 +				(long) sptr->samplesperrow *
 526.654 +				(long) SIZEOF(JSAMPLE));
 526.655 +	sptr->b_s_open = TRUE;
 526.656 +      }
 526.657 +      sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
 526.658 +				      sptr->samplesperrow, sptr->rows_in_mem);
 526.659 +      sptr->rowsperchunk = mem->last_rowsperchunk;
 526.660 +      sptr->cur_start_row = 0;
 526.661 +      sptr->first_undef_row = 0;
 526.662 +      sptr->dirty = FALSE;
 526.663 +    }
 526.664 +  }
 526.665 +
 526.666 +  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
 526.667 +    if (bptr->mem_buffer == NULL) { /* if not realized yet */
 526.668 +      minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
 526.669 +      if (minheights <= max_minheights) {
 526.670 +	/* This buffer fits in memory */
 526.671 +	bptr->rows_in_mem = bptr->rows_in_array;
 526.672 +      } else {
 526.673 +	/* It doesn't fit in memory, create backing store. */
 526.674 +	bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess);
 526.675 +	jpeg_open_backing_store(cinfo, & bptr->b_s_info,
 526.676 +				(long) bptr->rows_in_array *
 526.677 +				(long) bptr->blocksperrow *
 526.678 +				(long) SIZEOF(JBLOCK));
 526.679 +	bptr->b_s_open = TRUE;
 526.680 +      }
 526.681 +      bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
 526.682 +				      bptr->blocksperrow, bptr->rows_in_mem);
 526.683 +      bptr->rowsperchunk = mem->last_rowsperchunk;
 526.684 +      bptr->cur_start_row = 0;
 526.685 +      bptr->first_undef_row = 0;
 526.686 +      bptr->dirty = FALSE;
 526.687 +    }
 526.688 +  }
 526.689 +}
 526.690 +
 526.691 +
 526.692 +LOCAL(void)
 526.693 +do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
 526.694 +/* Do backing store read or write of a virtual sample array */
 526.695 +{
 526.696 +  long bytesperrow, file_offset, byte_count, rows, thisrow, i;
 526.697 +
 526.698 +  bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
 526.699 +  file_offset = ptr->cur_start_row * bytesperrow;
 526.700 +  /* Loop to read or write each allocation chunk in mem_buffer */
 526.701 +  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
 526.702 +    /* One chunk, but check for short chunk at end of buffer */
 526.703 +    rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
 526.704 +    /* Transfer no more than is currently defined */
 526.705 +    thisrow = (long) ptr->cur_start_row + i;
 526.706 +    rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
 526.707 +    /* Transfer no more than fits in file */
 526.708 +    rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
 526.709 +    if (rows <= 0)		/* this chunk might be past end of file! */
 526.710 +      break;
 526.711 +    byte_count = rows * bytesperrow;
 526.712 +    if (writing)
 526.713 +      (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
 526.714 +					    (void FAR *) ptr->mem_buffer[i],
 526.715 +					    file_offset, byte_count);
 526.716 +    else
 526.717 +      (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
 526.718 +					   (void FAR *) ptr->mem_buffer[i],
 526.719 +					   file_offset, byte_count);
 526.720 +    file_offset += byte_count;
 526.721 +  }
 526.722 +}
 526.723 +
 526.724 +
 526.725 +LOCAL(void)
 526.726 +do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
 526.727 +/* Do backing store read or write of a virtual coefficient-block array */
 526.728 +{
 526.729 +  long bytesperrow, file_offset, byte_count, rows, thisrow, i;
 526.730 +
 526.731 +  bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
 526.732 +  file_offset = ptr->cur_start_row * bytesperrow;
 526.733 +  /* Loop to read or write each allocation chunk in mem_buffer */
 526.734 +  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
 526.735 +    /* One chunk, but check for short chunk at end of buffer */
 526.736 +    rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
 526.737 +    /* Transfer no more than is currently defined */
 526.738 +    thisrow = (long) ptr->cur_start_row + i;
 526.739 +    rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
 526.740 +    /* Transfer no more than fits in file */
 526.741 +    rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
 526.742 +    if (rows <= 0)		/* this chunk might be past end of file! */
 526.743 +      break;
 526.744 +    byte_count = rows * bytesperrow;
 526.745 +    if (writing)
 526.746 +      (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
 526.747 +					    (void FAR *) ptr->mem_buffer[i],
 526.748 +					    file_offset, byte_count);
 526.749 +    else
 526.750 +      (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
 526.751 +					   (void FAR *) ptr->mem_buffer[i],
 526.752 +					   file_offset, byte_count);
 526.753 +    file_offset += byte_count;
 526.754 +  }
 526.755 +}
 526.756 +
 526.757 +
 526.758 +METHODDEF(JSAMPARRAY)
 526.759 +access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
 526.760 +		    JDIMENSION start_row, JDIMENSION num_rows,
 526.761 +		    boolean writable)
 526.762 +/* Access the part of a virtual sample array starting at start_row */
 526.763 +/* and extending for num_rows rows.  writable is true if  */
 526.764 +/* caller intends to modify the accessed area. */
 526.765 +{
 526.766 +  JDIMENSION end_row = start_row + num_rows;
 526.767 +  JDIMENSION undef_row;
 526.768 +
 526.769 +  /* debugging check */
 526.770 +  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
 526.771 +      ptr->mem_buffer == NULL)
 526.772 +    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 526.773 +
 526.774 +  /* Make the desired part of the virtual array accessible */
 526.775 +  if (start_row < ptr->cur_start_row ||
 526.776 +      end_row > ptr->cur_start_row+ptr->rows_in_mem) {
 526.777 +    if (! ptr->b_s_open)
 526.778 +      ERREXIT(cinfo, JERR_VIRTUAL_BUG);
 526.779 +    /* Flush old buffer contents if necessary */
 526.780 +    if (ptr->dirty) {
 526.781 +      do_sarray_io(cinfo, ptr, TRUE);
 526.782 +      ptr->dirty = FALSE;
 526.783 +    }
 526.784 +    /* Decide what part of virtual array to access.
 526.785 +     * Algorithm: if target address > current window, assume forward scan,
 526.786 +     * load starting at target address.  If target address < current window,
 526.787 +     * assume backward scan, load so that target area is top of window.
 526.788 +     * Note that when switching from forward write to forward read, will have
 526.789 +     * start_row = 0, so the limiting case applies and we load from 0 anyway.
 526.790 +     */
 526.791 +    if (start_row > ptr->cur_start_row) {
 526.792 +      ptr->cur_start_row = start_row;
 526.793 +    } else {
 526.794 +      /* use long arithmetic here to avoid overflow & unsigned problems */
 526.795 +      long ltemp;
 526.796 +
 526.797 +      ltemp = (long) end_row - (long) ptr->rows_in_mem;
 526.798 +      if (ltemp < 0)
 526.799 +	ltemp = 0;		/* don't fall off front end of file */
 526.800 +      ptr->cur_start_row = (JDIMENSION) ltemp;
 526.801 +    }
 526.802 +    /* Read in the selected part of the array.
 526.803 +     * During the initial write pass, we will do no actual read
 526.804 +     * because the selected part is all undefined.
 526.805 +     */
 526.806 +    do_sarray_io(cinfo, ptr, FALSE);
 526.807 +  }
 526.808 +  /* Ensure the accessed part of the array is defined; prezero if needed.
 526.809 +   * To improve locality of access, we only prezero the part of the array
 526.810 +   * that the caller is about to access, not the entire in-memory array.
 526.811 +   */
 526.812 +  if (ptr->first_undef_row < end_row) {
 526.813 +    if (ptr->first_undef_row < start_row) {
 526.814 +      if (writable)		/* writer skipped over a section of array */
 526.815 +	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 526.816 +      undef_row = start_row;	/* but reader is allowed to read ahead */
 526.817 +    } else {
 526.818 +      undef_row = ptr->first_undef_row;
 526.819 +    }
 526.820 +    if (writable)
 526.821 +      ptr->first_undef_row = end_row;
 526.822 +    if (ptr->pre_zero) {
 526.823 +      size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
 526.824 +      undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
 526.825 +      end_row -= ptr->cur_start_row;
 526.826 +      while (undef_row < end_row) {
 526.827 +	jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
 526.828 +	undef_row++;
 526.829 +      }
 526.830 +    } else {
 526.831 +      if (! writable)		/* reader looking at undefined data */
 526.832 +	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 526.833 +    }
 526.834 +  }
 526.835 +  /* Flag the buffer dirty if caller will write in it */
 526.836 +  if (writable)
 526.837 +    ptr->dirty = TRUE;
 526.838 +  /* Return address of proper part of the buffer */
 526.839 +  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
 526.840 +}
 526.841 +
 526.842 +
 526.843 +METHODDEF(JBLOCKARRAY)
 526.844 +access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
 526.845 +		    JDIMENSION start_row, JDIMENSION num_rows,
 526.846 +		    boolean writable)
 526.847 +/* Access the part of a virtual block array starting at start_row */
 526.848 +/* and extending for num_rows rows.  writable is true if  */
 526.849 +/* caller intends to modify the accessed area. */
 526.850 +{
 526.851 +  JDIMENSION end_row = start_row + num_rows;
 526.852 +  JDIMENSION undef_row;
 526.853 +
 526.854 +  /* debugging check */
 526.855 +  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
 526.856 +      ptr->mem_buffer == NULL)
 526.857 +    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 526.858 +
 526.859 +  /* Make the desired part of the virtual array accessible */
 526.860 +  if (start_row < ptr->cur_start_row ||
 526.861 +      end_row > ptr->cur_start_row+ptr->rows_in_mem) {
 526.862 +    if (! ptr->b_s_open)
 526.863 +      ERREXIT(cinfo, JERR_VIRTUAL_BUG);
 526.864 +    /* Flush old buffer contents if necessary */
 526.865 +    if (ptr->dirty) {
 526.866 +      do_barray_io(cinfo, ptr, TRUE);
 526.867 +      ptr->dirty = FALSE;
 526.868 +    }
 526.869 +    /* Decide what part of virtual array to access.
 526.870 +     * Algorithm: if target address > current window, assume forward scan,
 526.871 +     * load starting at target address.  If target address < current window,
 526.872 +     * assume backward scan, load so that target area is top of window.
 526.873 +     * Note that when switching from forward write to forward read, will have
 526.874 +     * start_row = 0, so the limiting case applies and we load from 0 anyway.
 526.875 +     */
 526.876 +    if (start_row > ptr->cur_start_row) {
 526.877 +      ptr->cur_start_row = start_row;
 526.878 +    } else {
 526.879 +      /* use long arithmetic here to avoid overflow & unsigned problems */
 526.880 +      long ltemp;
 526.881 +
 526.882 +      ltemp = (long) end_row - (long) ptr->rows_in_mem;
 526.883 +      if (ltemp < 0)
 526.884 +	ltemp = 0;		/* don't fall off front end of file */
 526.885 +      ptr->cur_start_row = (JDIMENSION) ltemp;
 526.886 +    }
 526.887 +    /* Read in the selected part of the array.
 526.888 +     * During the initial write pass, we will do no actual read
 526.889 +     * because the selected part is all undefined.
 526.890 +     */
 526.891 +    do_barray_io(cinfo, ptr, FALSE);
 526.892 +  }
 526.893 +  /* Ensure the accessed part of the array is defined; prezero if needed.
 526.894 +   * To improve locality of access, we only prezero the part of the array
 526.895 +   * that the caller is about to access, not the entire in-memory array.
 526.896 +   */
 526.897 +  if (ptr->first_undef_row < end_row) {
 526.898 +    if (ptr->first_undef_row < start_row) {
 526.899 +      if (writable)		/* writer skipped over a section of array */
 526.900 +	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 526.901 +      undef_row = start_row;	/* but reader is allowed to read ahead */
 526.902 +    } else {
 526.903 +      undef_row = ptr->first_undef_row;
 526.904 +    }
 526.905 +    if (writable)
 526.906 +      ptr->first_undef_row = end_row;
 526.907 +    if (ptr->pre_zero) {
 526.908 +      size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
 526.909 +      undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
 526.910 +      end_row -= ptr->cur_start_row;
 526.911 +      while (undef_row < end_row) {
 526.912 +	jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
 526.913 +	undef_row++;
 526.914 +      }
 526.915 +    } else {
 526.916 +      if (! writable)		/* reader looking at undefined data */
 526.917 +	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 526.918 +    }
 526.919 +  }
 526.920 +  /* Flag the buffer dirty if caller will write in it */
 526.921 +  if (writable)
 526.922 +    ptr->dirty = TRUE;
 526.923 +  /* Return address of proper part of the buffer */
 526.924 +  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
 526.925 +}
 526.926 +
 526.927 +
 526.928 +/*
 526.929 + * Release all objects belonging to a specified pool.
 526.930 + */
 526.931 +
 526.932 +METHODDEF(void)
 526.933 +free_pool (j_common_ptr cinfo, int pool_id)
 526.934 +{
 526.935 +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 526.936 +  small_pool_ptr shdr_ptr;
 526.937 +  large_pool_ptr lhdr_ptr;
 526.938 +  size_t space_freed;
 526.939 +
 526.940 +  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
 526.941 +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
 526.942 +
 526.943 +#ifdef MEM_STATS
 526.944 +  if (cinfo->err->trace_level > 1)
 526.945 +    print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */
 526.946 +#endif
 526.947 +
 526.948 +  /* If freeing IMAGE pool, close any virtual arrays first */
 526.949 +  if (pool_id == JPOOL_IMAGE) {
 526.950 +    jvirt_sarray_ptr sptr;
 526.951 +    jvirt_barray_ptr bptr;
 526.952 +
 526.953 +    for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
 526.954 +      if (sptr->b_s_open) {	/* there may be no backing store */
 526.955 +	sptr->b_s_open = FALSE;	/* prevent recursive close if error */
 526.956 +	(*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info);
 526.957 +      }
 526.958 +    }
 526.959 +    mem->virt_sarray_list = NULL;
 526.960 +    for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
 526.961 +      if (bptr->b_s_open) {	/* there may be no backing store */
 526.962 +	bptr->b_s_open = FALSE;	/* prevent recursive close if error */
 526.963 +	(*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info);
 526.964 +      }
 526.965 +    }
 526.966 +    mem->virt_barray_list = NULL;
 526.967 +  }
 526.968 +
 526.969 +  /* Release large objects */
 526.970 +  lhdr_ptr = mem->large_list[pool_id];
 526.971 +  mem->large_list[pool_id] = NULL;
 526.972 +
 526.973 +  while (lhdr_ptr != NULL) {
 526.974 +    large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
 526.975 +    space_freed = lhdr_ptr->hdr.bytes_used +
 526.976 +		  lhdr_ptr->hdr.bytes_left +
 526.977 +		  SIZEOF(large_pool_hdr);
 526.978 +    jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
 526.979 +    mem->total_space_allocated -= space_freed;
 526.980 +    lhdr_ptr = next_lhdr_ptr;
 526.981 +  }
 526.982 +
 526.983 +  /* Release small objects */
 526.984 +  shdr_ptr = mem->small_list[pool_id];
 526.985 +  mem->small_list[pool_id] = NULL;
 526.986 +
 526.987 +  while (shdr_ptr != NULL) {
 526.988 +    small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
 526.989 +    space_freed = shdr_ptr->hdr.bytes_used +
 526.990 +		  shdr_ptr->hdr.bytes_left +
 526.991 +		  SIZEOF(small_pool_hdr);
 526.992 +    jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
 526.993 +    mem->total_space_allocated -= space_freed;
 526.994 +    shdr_ptr = next_shdr_ptr;
 526.995 +  }
 526.996 +}
 526.997 +
 526.998 +
 526.999 +/*
526.1000 + * Close up shop entirely.
526.1001 + * Note that this cannot be called unless cinfo->mem is non-NULL.
526.1002 + */
526.1003 +
526.1004 +METHODDEF(void)
526.1005 +self_destruct (j_common_ptr cinfo)
526.1006 +{
526.1007 +  int pool;
526.1008 +
526.1009 +  /* Close all backing store, release all memory.
526.1010 +   * Releasing pools in reverse order might help avoid fragmentation
526.1011 +   * with some (brain-damaged) malloc libraries.
526.1012 +   */
526.1013 +  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
526.1014 +    free_pool(cinfo, pool);
526.1015 +  }
526.1016 +
526.1017 +  /* Release the memory manager control block too. */
526.1018 +  jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr));
526.1019 +  cinfo->mem = NULL;		/* ensures I will be called only once */
526.1020 +
526.1021 +  jpeg_mem_term(cinfo);		/* system-dependent cleanup */
526.1022 +}
526.1023 +
526.1024 +
526.1025 +/*
526.1026 + * Memory manager initialization.
526.1027 + * When this is called, only the error manager pointer is valid in cinfo!
526.1028 + */
526.1029 +
526.1030 +GLOBAL(void)
526.1031 +jinit_memory_mgr (j_common_ptr cinfo)
526.1032 +{
526.1033 +  my_mem_ptr mem;
526.1034 +  long max_to_use;
526.1035 +  int pool;
526.1036 +  size_t test_mac;
526.1037 +
526.1038 +  cinfo->mem = NULL;		/* for safety if init fails */
526.1039 +
526.1040 +  /* Check for configuration errors.
526.1041 +   * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
526.1042 +   * doesn't reflect any real hardware alignment requirement.
526.1043 +   * The test is a little tricky: for X>0, X and X-1 have no one-bits
526.1044 +   * in common if and only if X is a power of 2, ie has only one one-bit.
526.1045 +   * Some compilers may give an "unreachable code" warning here; ignore it.
526.1046 +   */
526.1047 +  if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
526.1048 +    ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
526.1049 +  /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
526.1050 +   * a multiple of SIZEOF(ALIGN_TYPE).
526.1051 +   * Again, an "unreachable code" warning may be ignored here.
526.1052 +   * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
526.1053 +   */
526.1054 +  test_mac = (size_t) MAX_ALLOC_CHUNK;
526.1055 +  if ((long) test_mac != MAX_ALLOC_CHUNK ||
526.1056 +      (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
526.1057 +    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
526.1058 +
526.1059 +  max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
526.1060 +
526.1061 +  /* Attempt to allocate memory manager's control block */
526.1062 +  mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr));
526.1063 +
526.1064 +  if (mem == NULL) {
526.1065 +    jpeg_mem_term(cinfo);	/* system-dependent cleanup */
526.1066 +    ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
526.1067 +  }
526.1068 +
526.1069 +  /* OK, fill in the method pointers */
526.1070 +  mem->pub.alloc_small = alloc_small;
526.1071 +  mem->pub.alloc_large = alloc_large;
526.1072 +  mem->pub.alloc_sarray = alloc_sarray;
526.1073 +  mem->pub.alloc_barray = alloc_barray;
526.1074 +  mem->pub.request_virt_sarray = request_virt_sarray;
526.1075 +  mem->pub.request_virt_barray = request_virt_barray;
526.1076 +  mem->pub.realize_virt_arrays = realize_virt_arrays;
526.1077 +  mem->pub.access_virt_sarray = access_virt_sarray;
526.1078 +  mem->pub.access_virt_barray = access_virt_barray;
526.1079 +  mem->pub.free_pool = free_pool;
526.1080 +  mem->pub.self_destruct = self_destruct;
526.1081 +
526.1082 +  /* Make MAX_ALLOC_CHUNK accessible to other modules */
526.1083 +  mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
526.1084 +
526.1085 +  /* Initialize working state */
526.1086 +  mem->pub.max_memory_to_use = max_to_use;
526.1087 +
526.1088 +  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
526.1089 +    mem->small_list[pool] = NULL;
526.1090 +    mem->large_list[pool] = NULL;
526.1091 +  }
526.1092 +  mem->virt_sarray_list = NULL;
526.1093 +  mem->virt_barray_list = NULL;
526.1094 +
526.1095 +  mem->total_space_allocated = SIZEOF(my_memory_mgr);
526.1096 +
526.1097 +  /* Declare ourselves open for business */
526.1098 +  cinfo->mem = & mem->pub;
526.1099 +
526.1100 +  /* Check for an environment variable JPEGMEM; if found, override the
526.1101 +   * default max_memory setting from jpeg_mem_init.  Note that the
526.1102 +   * surrounding application may again override this value.
526.1103 +   * If your system doesn't support getenv(), define NO_GETENV to disable
526.1104 +   * this feature.
526.1105 +   */
526.1106 +#ifndef NO_GETENV
526.1107 +  { char * memenv;
526.1108 +
526.1109 +    if ((memenv = getenv("JPEGMEM")) != NULL) {
526.1110 +      char ch = 'x';
526.1111 +
526.1112 +      if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
526.1113 +	if (ch == 'm' || ch == 'M')
526.1114 +	  max_to_use *= 1000L;
526.1115 +	mem->pub.max_memory_to_use = max_to_use * 1000L;
526.1116 +      }
526.1117 +    }
526.1118 +  }
526.1119 +#endif
526.1120 +
526.1121 +}
   527.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   527.2 +++ b/libs/libjpeg/jmemnobs.c	Sat Feb 01 19:58:19 2014 +0200
   527.3 @@ -0,0 +1,109 @@
   527.4 +/*
   527.5 + * jmemnobs.c
   527.6 + *
   527.7 + * Copyright (C) 1992-1996, Thomas G. Lane.
   527.8 + * This file is part of the Independent JPEG Group's software.
   527.9 + * For conditions of distribution and use, see the accompanying README file.
  527.10 + *
  527.11 + * This file provides a really simple implementation of the system-
  527.12 + * dependent portion of the JPEG memory manager.  This implementation
  527.13 + * assumes that no backing-store files are needed: all required space
  527.14 + * can be obtained from malloc().
  527.15 + * This is very portable in the sense that it'll compile on almost anything,
  527.16 + * but you'd better have lots of main memory (or virtual memory) if you want
  527.17 + * to process big images.
  527.18 + * Note that the max_memory_to_use option is ignored by this implementation.
  527.19 + */
  527.20 +
  527.21 +#define JPEG_INTERNALS
  527.22 +#include "jinclude.h"
  527.23 +#include "jpeglib.h"
  527.24 +#include "jmemsys.h"		/* import the system-dependent declarations */
  527.25 +
  527.26 +#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare malloc(),free() */
  527.27 +extern void * malloc JPP((size_t size));
  527.28 +extern void free JPP((void *ptr));
  527.29 +#endif
  527.30 +
  527.31 +
  527.32 +/*
  527.33 + * Memory allocation and freeing are controlled by the regular library
  527.34 + * routines malloc() and free().
  527.35 + */
  527.36 +
  527.37 +GLOBAL(void *)
  527.38 +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
  527.39 +{
  527.40 +  return (void *) malloc(sizeofobject);
  527.41 +}
  527.42 +
  527.43 +GLOBAL(void)
  527.44 +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
  527.45 +{
  527.46 +  free(object);
  527.47 +}
  527.48 +
  527.49 +
  527.50 +/*
  527.51 + * "Large" objects are treated the same as "small" ones.
  527.52 + * NB: although we include FAR keywords in the routine declarations,
  527.53 + * this file won't actually work in 80x86 small/medium model; at least,
  527.54 + * you probably won't be able to process useful-size images in only 64KB.
  527.55 + */
  527.56 +
  527.57 +GLOBAL(void FAR *)
  527.58 +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
  527.59 +{
  527.60 +  return (void FAR *) malloc(sizeofobject);
  527.61 +}
  527.62 +
  527.63 +GLOBAL(void)
  527.64 +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
  527.65 +{
  527.66 +  free(object);
  527.67 +}
  527.68 +
  527.69 +
  527.70 +/*
  527.71 + * This routine computes the total memory space available for allocation.
  527.72 + * Here we always say, "we got all you want bud!"
  527.73 + */
  527.74 +
  527.75 +GLOBAL(long)
  527.76 +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
  527.77 +		    long max_bytes_needed, long already_allocated)
  527.78 +{
  527.79 +  return max_bytes_needed;
  527.80 +}
  527.81 +
  527.82 +
  527.83 +/*
  527.84 + * Backing store (temporary file) management.
  527.85 + * Since jpeg_mem_available always promised the moon,
  527.86 + * this should never be called and we can just error out.
  527.87 + */
  527.88 +
  527.89 +GLOBAL(void)
  527.90 +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
  527.91 +			 long total_bytes_needed)
  527.92 +{
  527.93 +  ERREXIT(cinfo, JERR_NO_BACKING_STORE);
  527.94 +}
  527.95 +
  527.96 +
  527.97 +/*
  527.98 + * These routines take care of any system-dependent initialization and
  527.99 + * cleanup required.  Here, there isn't any.
 527.100 + */
 527.101 +
 527.102 +GLOBAL(long)
 527.103 +jpeg_mem_init (j_common_ptr cinfo)
 527.104 +{
 527.105 +  return 0;			/* just set max_memory_to_use to 0 */
 527.106 +}
 527.107 +
 527.108 +GLOBAL(void)
 527.109 +jpeg_mem_term (j_common_ptr cinfo)
 527.110 +{
 527.111 +  /* no work */
 527.112 +}
   528.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   528.2 +++ b/libs/libjpeg/jmemsys.h	Sat Feb 01 19:58:19 2014 +0200
   528.3 @@ -0,0 +1,198 @@
   528.4 +/*
   528.5 + * jmemsys.h
   528.6 + *
   528.7 + * Copyright (C) 1992-1997, Thomas G. Lane.
   528.8 + * This file is part of the Independent JPEG Group's software.
   528.9 + * For conditions of distribution and use, see the accompanying README file.
  528.10 + *
  528.11 + * This include file defines the interface between the system-independent
  528.12 + * and system-dependent portions of the JPEG memory manager.  No other
  528.13 + * modules need include it.  (The system-independent portion is jmemmgr.c;
  528.14 + * there are several different versions of the system-dependent portion.)
  528.15 + *
  528.16 + * This file works as-is for the system-dependent memory managers supplied
  528.17 + * in the IJG distribution.  You may need to modify it if you write a
  528.18 + * custom memory manager.  If system-dependent changes are needed in
  528.19 + * this file, the best method is to #ifdef them based on a configuration
  528.20 + * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
  528.21 + * and USE_MAC_MEMMGR.
  528.22 + */
  528.23 +
  528.24 +
  528.25 +/* Short forms of external names for systems with brain-damaged linkers. */
  528.26 +
  528.27 +#ifdef NEED_SHORT_EXTERNAL_NAMES
  528.28 +#define jpeg_get_small		jGetSmall
  528.29 +#define jpeg_free_small		jFreeSmall
  528.30 +#define jpeg_get_large		jGetLarge
  528.31 +#define jpeg_free_large		jFreeLarge
  528.32 +#define jpeg_mem_available	jMemAvail
  528.33 +#define jpeg_open_backing_store	jOpenBackStore
  528.34 +#define jpeg_mem_init		jMemInit
  528.35 +#define jpeg_mem_term		jMemTerm
  528.36 +#endif /* NEED_SHORT_EXTERNAL_NAMES */
  528.37 +
  528.38 +
  528.39 +/*
  528.40 + * These two functions are used to allocate and release small chunks of
  528.41 + * memory.  (Typically the total amount requested through jpeg_get_small is
  528.42 + * no more than 20K or so; this will be requested in chunks of a few K each.)
  528.43 + * Behavior should be the same as for the standard library functions malloc
  528.44 + * and free; in particular, jpeg_get_small must return NULL on failure.
  528.45 + * On most systems, these ARE malloc and free.  jpeg_free_small is passed the
  528.46 + * size of the object being freed, just in case it's needed.
  528.47 + * On an 80x86 machine using small-data memory model, these manage near heap.
  528.48 + */
  528.49 +
  528.50 +EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
  528.51 +EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
  528.52 +				  size_t sizeofobject));
  528.53 +
  528.54 +/*
  528.55 + * These two functions are used to allocate and release large chunks of
  528.56 + * memory (up to the total free space designated by jpeg_mem_available).
  528.57 + * The interface is the same as above, except that on an 80x86 machine,
  528.58 + * far pointers are used.  On most other machines these are identical to
  528.59 + * the jpeg_get/free_small routines; but we keep them separate anyway,
  528.60 + * in case a different allocation strategy is desirable for large chunks.
  528.61 + */
  528.62 +
  528.63 +EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
  528.64 +				       size_t sizeofobject));
  528.65 +EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
  528.66 +				  size_t sizeofobject));
  528.67 +
  528.68 +/*
  528.69 + * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
  528.70 + * be requested in a single call to jpeg_get_large (and jpeg_get_small for that
  528.71 + * matter, but that case should never come into play).  This macro is needed
  528.72 + * to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
  528.73 + * On those machines, we expect that jconfig.h will provide a proper value.
  528.74 + * On machines with 32-bit flat address spaces, any large constant may be used.
  528.75 + *
  528.76 + * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type
  528.77 + * size_t and will be a multiple of sizeof(align_type).
  528.78 + */
  528.79 +
  528.80 +#ifndef MAX_ALLOC_CHUNK		/* may be overridden in jconfig.h */
  528.81 +#define MAX_ALLOC_CHUNK  1000000000L
  528.82 +#endif
  528.83 +
  528.84 +/*
  528.85 + * This routine computes the total space still available for allocation by
  528.86 + * jpeg_get_large.  If more space than this is needed, backing store will be
  528.87 + * used.  NOTE: any memory already allocated must not be counted.
  528.88 + *
  528.89 + * There is a minimum space requirement, corresponding to the minimum
  528.90 + * feasible buffer sizes; jmemmgr.c will request that much space even if
  528.91 + * jpeg_mem_available returns zero.  The maximum space needed, enough to hold
  528.92 + * all working storage in memory, is also passed in case it is useful.
  528.93 + * Finally, the total space already allocated is passed.  If no better
  528.94 + * method is available, cinfo->mem->max_memory_to_use - already_allocated
  528.95 + * is often a suitable calculation.
  528.96 + *
  528.97 + * It is OK for jpeg_mem_available to underestimate the space available
  528.98 + * (that'll just lead to more backing-store access than is really necessary).
  528.99 + * However, an overestimate will lead to failure.  Hence it's wise to subtract
 528.100 + * a slop factor from the true available space.  5% should be enough.
 528.101 + *
 528.102 + * On machines with lots of virtual memory, any large constant may be returned.
 528.103 + * Conversely, zero may be returned to always use the minimum amount of memory.
 528.104 + */
 528.105 +
 528.106 +EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
 528.107 +				     long min_bytes_needed,
 528.108 +				     long max_bytes_needed,
 528.109 +				     long already_allocated));
 528.110 +
 528.111 +
 528.112 +/*
 528.113 + * This structure holds whatever state is needed to access a single
 528.114 + * backing-store object.  The read/write/close method pointers are called
 528.115 + * by jmemmgr.c to manipulate the backing-store object; all other fields
 528.116 + * are private to the system-dependent backing store routines.
 528.117 + */
 528.118 +
 528.119 +#define TEMP_NAME_LENGTH   64	/* max length of a temporary file's name */
 528.120 +
 528.121 +
 528.122 +#ifdef USE_MSDOS_MEMMGR		/* DOS-specific junk */
 528.123 +
 528.124 +typedef unsigned short XMSH;	/* type of extended-memory handles */
 528.125 +typedef unsigned short EMSH;	/* type of expanded-memory handles */
 528.126 +
 528.127 +typedef union {
 528.128 +  short file_handle;		/* DOS file handle if it's a temp file */
 528.129 +  XMSH xms_handle;		/* handle if it's a chunk of XMS */
 528.130 +  EMSH ems_handle;		/* handle if it's a chunk of EMS */
 528.131 +} handle_union;
 528.132 +
 528.133 +#endif /* USE_MSDOS_MEMMGR */
 528.134 +
 528.135 +#ifdef USE_MAC_MEMMGR		/* Mac-specific junk */
 528.136 +#include <Files.h>
 528.137 +#endif /* USE_MAC_MEMMGR */
 528.138 +
 528.139 +
 528.140 +typedef struct backing_store_struct * backing_store_ptr;
 528.141 +
 528.142 +typedef struct backing_store_struct {
 528.143 +  /* Methods for reading/writing/closing this backing-store object */
 528.144 +  JMETHOD(void, read_backing_store, (j_common_ptr cinfo,
 528.145 +				     backing_store_ptr info,
 528.146 +				     void FAR * buffer_address,
 528.147 +				     long file_offset, long byte_count));
 528.148 +  JMETHOD(void, write_backing_store, (j_common_ptr cinfo,
 528.149 +				      backing_store_ptr info,
 528.150 +				      void FAR * buffer_address,
 528.151 +				      long file_offset, long byte_count));
 528.152 +  JMETHOD(void, close_backing_store, (j_common_ptr cinfo,
 528.153 +				      backing_store_ptr info));
 528.154 +
 528.155 +  /* Private fields for system-dependent backing-store management */
 528.156 +#ifdef USE_MSDOS_MEMMGR
 528.157 +  /* For the MS-DOS manager (jmemdos.c), we need: */
 528.158 +  handle_union handle;		/* reference to backing-store storage object */
 528.159 +  char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
 528.160 +#else
 528.161 +#ifdef USE_MAC_MEMMGR
 528.162 +  /* For the Mac manager (jmemmac.c), we need: */
 528.163 +  short temp_file;		/* file reference number to temp file */
 528.164 +  FSSpec tempSpec;		/* the FSSpec for the temp file */
 528.165 +  char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
 528.166 +#else
 528.167 +  /* For a typical implementation with temp files, we need: */
 528.168 +  FILE * temp_file;		/* stdio reference to temp file */
 528.169 +  char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
 528.170 +#endif
 528.171 +#endif
 528.172 +} backing_store_info;
 528.173 +
 528.174 +
 528.175 +/*
 528.176 + * Initial opening of a backing-store object.  This must fill in the
 528.177 + * read/write/close pointers in the object.  The read/write routines
 528.178 + * may take an error exit if the specified maximum file size is exceeded.
 528.179 + * (If jpeg_mem_available always returns a large value, this routine can
 528.180 + * just take an error exit.)
 528.181 + */
 528.182 +
 528.183 +EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
 528.184 +					  backing_store_ptr info,
 528.185 +					  long total_bytes_needed));
 528.186 +
 528.187 +
 528.188 +/*
 528.189 + * These routines take care of any system-dependent initialization and
 528.190 + * cleanup required.  jpeg_mem_init will be called before anything is
 528.191 + * allocated (and, therefore, nothing in cinfo is of use except the error
 528.192 + * manager pointer).  It should return a suitable default value for
 528.193 + * max_memory_to_use; this may subsequently be overridden by the surrounding
 528.194 + * application.  (Note that max_memory_to_use is only important if
 528.195 + * jpeg_mem_available chooses to consult it ... no one else will.)
 528.196 + * jpeg_mem_term may assume that all requested memory has been freed and that
 528.197 + * all opened backing-store objects have been closed.
 528.198 + */
 528.199 +
 528.200 +EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo));
 528.201 +EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));
   529.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   529.2 +++ b/libs/libjpeg/jmorecfg.h	Sat Feb 01 19:58:19 2014 +0200
   529.3 @@ -0,0 +1,367 @@
   529.4 +/*
   529.5 + * jmorecfg.h
   529.6 + *
   529.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   529.8 + * This file is part of the Independent JPEG Group's software.
   529.9 + * For conditions of distribution and use, see the accompanying README file.
  529.10 + *
  529.11 + * This file contains additional configuration options that customize the
  529.12 + * JPEG software for special applications or support machine-dependent
  529.13 + * optimizations.  Most users will not need to touch this file.
  529.14 + */
  529.15 +
  529.16 +
  529.17 +/*
  529.18 + * Define BITS_IN_JSAMPLE as either
  529.19 + *   8   for 8-bit sample values (the usual setting)
  529.20 + *   12  for 12-bit sample values
  529.21 + * Only 8 and 12 are legal data precisions for lossy JPEG according to the
  529.22 + * JPEG standard, and the IJG code does not support anything else!
  529.23 + * We do not support run-time selection of data precision, sorry.
  529.24 + */
  529.25 +
  529.26 +#define BITS_IN_JSAMPLE  8	/* use 8 or 12 */
  529.27 +
  529.28 +
  529.29 +/*
  529.30 + * Maximum number of components (color channels) allowed in JPEG image.
  529.31 + * To meet the letter of the JPEG spec, set this to 255.  However, darn
  529.32 + * few applications need more than 4 channels (maybe 5 for CMYK + alpha
  529.33 + * mask).  We recommend 10 as a reasonable compromise; use 4 if you are
  529.34 + * really short on memory.  (Each allowed component costs a hundred or so
  529.35 + * bytes of storage, whether actually used in an image or not.)
  529.36 + */
  529.37 +
  529.38 +#define MAX_COMPONENTS  10	/* maximum number of image components */
  529.39 +
  529.40 +
  529.41 +/*
  529.42 + * Basic data types.
  529.43 + * You may need to change these if you have a machine with unusual data
  529.44 + * type sizes; for example, "char" not 8 bits, "short" not 16 bits,
  529.45 + * or "long" not 32 bits.  We don't care whether "int" is 16 or 32 bits,
  529.46 + * but it had better be at least 16.
  529.47 + */
  529.48 +
  529.49 +/* Representation of a single sample (pixel element value).
  529.50 + * We frequently allocate large arrays of these, so it's important to keep
  529.51 + * them small.  But if you have memory to burn and access to char or short
  529.52 + * arrays is very slow on your hardware, you might want to change these.
  529.53 + */
  529.54 +
  529.55 +#if BITS_IN_JSAMPLE == 8
  529.56 +/* JSAMPLE should be the smallest type that will hold the values 0..255.
  529.57 + * You can use a signed char by having GETJSAMPLE mask it with 0xFF.
  529.58 + */
  529.59 +
  529.60 +#ifdef HAVE_UNSIGNED_CHAR
  529.61 +
  529.62 +typedef unsigned char JSAMPLE;
  529.63 +#define GETJSAMPLE(value)  ((int) (value))
  529.64 +
  529.65 +#else /* not HAVE_UNSIGNED_CHAR */
  529.66 +
  529.67 +typedef char JSAMPLE;
  529.68 +#ifdef CHAR_IS_UNSIGNED
  529.69 +#define GETJSAMPLE(value)  ((int) (value))
  529.70 +#else
  529.71 +#define GETJSAMPLE(value)  ((int) (value) & 0xFF)
  529.72 +#endif /* CHAR_IS_UNSIGNED */
  529.73 +
  529.74 +#endif /* HAVE_UNSIGNED_CHAR */
  529.75 +
  529.76 +#define MAXJSAMPLE	255
  529.77 +#define CENTERJSAMPLE	128
  529.78 +
  529.79 +#endif /* BITS_IN_JSAMPLE == 8 */
  529.80 +
  529.81 +
  529.82 +#if BITS_IN_JSAMPLE == 12
  529.83 +/* JSAMPLE should be the smallest type that will hold the values 0..4095.
  529.84 + * On nearly all machines "short" will do nicely.
  529.85 + */
  529.86 +
  529.87 +typedef short JSAMPLE;
  529.88 +#define GETJSAMPLE(value)  ((int) (value))
  529.89 +
  529.90 +#define MAXJSAMPLE	4095
  529.91 +#define CENTERJSAMPLE	2048
  529.92 +
  529.93 +#endif /* BITS_IN_JSAMPLE == 12 */
  529.94 +
  529.95 +
  529.96 +/* Representation of a DCT frequency coefficient.
  529.97 + * This should be a signed value of at least 16 bits; "short" is usually OK.
  529.98 + * Again, we allocate large arrays of these, but you can change to int
  529.99 + * if you have memory to burn and "short" is really slow.
 529.100 + */
 529.101 +
 529.102 +typedef short JCOEF;
 529.103 +
 529.104 +
 529.105 +/* Compressed datastreams are represented as arrays of JOCTET.
 529.106 + * These must be EXACTLY 8 bits wide, at least once they are written to
 529.107 + * external storage.  Note that when using the stdio data source/destination
 529.108 + * managers, this is also the data type passed to fread/fwrite.
 529.109 + */
 529.110 +
 529.111 +#ifdef HAVE_UNSIGNED_CHAR
 529.112 +
 529.113 +typedef unsigned char JOCTET;
 529.114 +#define GETJOCTET(value)  (value)
 529.115 +
 529.116 +#else /* not HAVE_UNSIGNED_CHAR */
 529.117 +
 529.118 +typedef char JOCTET;
 529.119 +#ifdef CHAR_IS_UNSIGNED
 529.120 +#define GETJOCTET(value)  (value)
 529.121 +#else
 529.122 +#define GETJOCTET(value)  ((value) & 0xFF)
 529.123 +#endif /* CHAR_IS_UNSIGNED */
 529.124 +
 529.125 +#endif /* HAVE_UNSIGNED_CHAR */
 529.126 +
 529.127 +
 529.128 +/* These typedefs are used for various table entries and so forth.
 529.129 + * They must be at least as wide as specified; but making them too big
 529.130 + * won't cost a huge amount of memory, so we don't provide special
 529.131 + * extraction code like we did for JSAMPLE.  (In other words, these
 529.132 + * typedefs live at a different point on the speed/space tradeoff curve.)
 529.133 + */
 529.134 +
 529.135 +/* UINT8 must hold at least the values 0..255. */
 529.136 +
 529.137 +#ifdef HAVE_UNSIGNED_CHAR
 529.138 +typedef unsigned char UINT8;
 529.139 +#else /* not HAVE_UNSIGNED_CHAR */
 529.140 +#ifdef CHAR_IS_UNSIGNED
 529.141 +typedef char UINT8;
 529.142 +#else /* not CHAR_IS_UNSIGNED */
 529.143 +typedef short UINT8;
 529.144 +#endif /* CHAR_IS_UNSIGNED */
 529.145 +#endif /* HAVE_UNSIGNED_CHAR */
 529.146 +
 529.147 +/* UINT16 must hold at least the values 0..65535. */
 529.148 +
 529.149 +#ifdef HAVE_UNSIGNED_SHORT
 529.150 +typedef unsigned short UINT16;
 529.151 +#else /* not HAVE_UNSIGNED_SHORT */
 529.152 +typedef unsigned int UINT16;
 529.153 +#endif /* HAVE_UNSIGNED_SHORT */
 529.154 +
 529.155 +/* INT16 must hold at least the values -32768..32767. */
 529.156 +
 529.157 +#ifndef XMD_H			/* X11/xmd.h correctly defines INT16 */
 529.158 +typedef short INT16;
 529.159 +#endif
 529.160 +
 529.161 +/* INT32 must hold at least signed 32-bit values. */
 529.162 +
 529.163 +#ifndef XMD_H			/* X11/xmd.h correctly defines INT32 */
 529.164 +typedef int INT32;
 529.165 +#endif
 529.166 +
 529.167 +/* Datatype used for image dimensions.  The JPEG standard only supports
 529.168 + * images up to 64K*64K due to 16-bit fields in SOF markers.  Therefore
 529.169 + * "unsigned int" is sufficient on all machines.  However, if you need to
 529.170 + * handle larger images and you don't mind deviating from the spec, you
 529.171 + * can change this datatype.
 529.172 + */
 529.173 +
 529.174 +typedef unsigned int JDIMENSION;
 529.175 +
 529.176 +#define JPEG_MAX_DIMENSION  65500L  /* a tad under 64K to prevent overflows */
 529.177 +
 529.178 +
 529.179 +/* These macros are used in all function definitions and extern declarations.
 529.180 + * You could modify them if you need to change function linkage conventions;
 529.181 + * in particular, you'll need to do that to make the library a Windows DLL.
 529.182 + * Another application is to make all functions global for use with debuggers
 529.183 + * or code profilers that require it.
 529.184 + */
 529.185 +
 529.186 +/* a function called through method pointers: */
 529.187 +#define METHODDEF(type)		static type
 529.188 +/* a function used only in its module: */
 529.189 +#define LOCAL(type)		static type
 529.190 +/* a function referenced thru EXTERNs: */
 529.191 +#define GLOBAL(type)		type
 529.192 +/* a reference to a GLOBAL function: */
 529.193 +#define EXTERN(type)		extern type
 529.194 +
 529.195 +
 529.196 +/* This macro is used to declare a "method", that is, a function pointer.
 529.197 + * We want to supply prototype parameters if the compiler can cope.
 529.198 + * Note that the arglist parameter must be parenthesized!
 529.199 + * Again, you can customize this if you need special linkage keywords.
 529.200 + */
 529.201 +
 529.202 +#ifdef HAVE_PROTOTYPES
 529.203 +#define JMETHOD(type,methodname,arglist)  type (*methodname) arglist
 529.204 +#else
 529.205 +#define JMETHOD(type,methodname,arglist)  type (*methodname) ()
 529.206 +#endif
 529.207 +
 529.208 +
 529.209 +/* Here is the pseudo-keyword for declaring pointers that must be "far"
 529.210 + * on 80x86 machines.  Most of the specialized coding for 80x86 is handled
 529.211 + * by just saying "FAR *" where such a pointer is needed.  In a few places
 529.212 + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
 529.213 + */
 529.214 +
 529.215 +#ifdef FAR
 529.216 +#undef FAR
 529.217 +#endif
 529.218 +
 529.219 +#ifdef NEED_FAR_POINTERS
 529.220 +#define FAR  far
 529.221 +#else
 529.222 +#define FAR
 529.223 +#endif
 529.224 +
 529.225 +
 529.226 +/*
 529.227 + * On a few systems, type boolean and/or its values FALSE, TRUE may appear
 529.228 + * in standard header files.  Or you may have conflicts with application-
 529.229 + * specific header files that you want to include together with these files.
 529.230 + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
 529.231 + */
 529.232 +
 529.233 +#ifndef HAVE_BOOLEAN
 529.234 +typedef int boolean;
 529.235 +#endif
 529.236 +#ifndef FALSE			/* in case these macros already exist */
 529.237 +#define FALSE	0		/* values of boolean */
 529.238 +#endif
 529.239 +#ifndef TRUE
 529.240 +#define TRUE	1
 529.241 +#endif
 529.242 +
 529.243 +
 529.244 +/*
 529.245 + * The remaining options affect code selection within the JPEG library,
 529.246 + * but they don't need to be visible to most applications using the library.
 529.247 + * To minimize application namespace pollution, the symbols won't be
 529.248 + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
 529.249 + */
 529.250 +
 529.251 +#ifdef JPEG_INTERNALS
 529.252 +#define JPEG_INTERNAL_OPTIONS
 529.253 +#endif
 529.254 +
 529.255 +#ifdef JPEG_INTERNAL_OPTIONS
 529.256 +
 529.257 +
 529.258 +/*
 529.259 + * These defines indicate whether to include various optional functions.
 529.260 + * Undefining some of these symbols will produce a smaller but less capable
 529.261 + * library.  Note that you can leave certain source files out of the
 529.262 + * compilation/linking process if you've #undef'd the corresponding symbols.
 529.263 + * (You may HAVE to do that if your compiler doesn't like null source files.)
 529.264 + */
 529.265 +
 529.266 +/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */
 529.267 +
 529.268 +/* Capability options common to encoder and decoder: */
 529.269 +
 529.270 +#define DCT_ISLOW_SUPPORTED	/* slow but accurate integer algorithm */
 529.271 +#define DCT_IFAST_SUPPORTED	/* faster, less accurate integer method */
 529.272 +#define DCT_FLOAT_SUPPORTED	/* floating-point: accurate, fast on fast HW */
 529.273 +
 529.274 +/* Encoder capability options: */
 529.275 +
 529.276 +#undef  C_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
 529.277 +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
 529.278 +#define C_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
 529.279 +#define ENTROPY_OPT_SUPPORTED	    /* Optimization of entropy coding parms? */
 529.280 +/* Note: if you selected 12-bit data precision, it is dangerous to turn off
 529.281 + * ENTROPY_OPT_SUPPORTED.  The standard Huffman tables are only good for 8-bit
 529.282 + * precision, so jchuff.c normally uses entropy optimization to compute
 529.283 + * usable tables for higher precision.  If you don't want to do optimization,
 529.284 + * you'll have to supply different default Huffman tables.
 529.285 + * The exact same statements apply for progressive JPEG: the default tables
 529.286 + * don't work for progressive mode.  (This may get fixed, however.)
 529.287 + */
 529.288 +#define INPUT_SMOOTHING_SUPPORTED   /* Input image smoothing option? */
 529.289 +
 529.290 +/* Decoder capability options: */
 529.291 +
 529.292 +#undef  D_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
 529.293 +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
 529.294 +#define D_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
 529.295 +#define SAVE_MARKERS_SUPPORTED	    /* jpeg_save_markers() needed? */
 529.296 +#define BLOCK_SMOOTHING_SUPPORTED   /* Block smoothing? (Progressive only) */
 529.297 +#define IDCT_SCALING_SUPPORTED	    /* Output rescaling via IDCT? */
 529.298 +#undef  UPSAMPLE_SCALING_SUPPORTED  /* Output rescaling at upsample stage? */
 529.299 +#define UPSAMPLE_MERGING_SUPPORTED  /* Fast path for sloppy upsampling? */
 529.300 +#define QUANT_1PASS_SUPPORTED	    /* 1-pass color quantization? */
 529.301 +#define QUANT_2PASS_SUPPORTED	    /* 2-pass color quantization? */
 529.302 +
 529.303 +/* more capability options later, no doubt */
 529.304 +
 529.305 +
 529.306 +/*
 529.307 + * Ordering of RGB data in scanlines passed to or from the application.
 529.308 + * If your application wants to deal with data in the order B,G,R, just
 529.309 + * change these macros.  You can also deal with formats such as R,G,B,X
 529.310 + * (one extra byte per pixel) by changing RGB_PIXELSIZE.  Note that changing
 529.311 + * the offsets will also change the order in which colormap data is organized.
 529.312 + * RESTRICTIONS:
 529.313 + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
 529.314 + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
 529.315 + *    useful if you are using JPEG color spaces other than YCbCr or grayscale.
 529.316 + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
 529.317 + *    is not 3 (they don't understand about dummy color components!).  So you
 529.318 + *    can't use color quantization if you change that value.
 529.319 + */
 529.320 +
 529.321 +#define RGB_RED		0	/* Offset of Red in an RGB scanline element */
 529.322 +#define RGB_GREEN	1	/* Offset of Green */
 529.323 +#define RGB_BLUE	2	/* Offset of Blue */
 529.324 +#define RGB_PIXELSIZE	3	/* JSAMPLEs per RGB scanline element */
 529.325 +
 529.326 +
 529.327 +/* Definitions for speed-related optimizations. */
 529.328 +
 529.329 +
 529.330 +/* If your compiler supports inline functions, define INLINE
 529.331 + * as the inline keyword; otherwise define it as empty.
 529.332 + */
 529.333 +
 529.334 +#ifndef INLINE
 529.335 +#ifdef __GNUC__			/* for instance, GNU C knows about inline */
 529.336 +#define INLINE __inline__
 529.337 +#endif
 529.338 +#ifndef INLINE
 529.339 +#define INLINE			/* default is to define it as empty */
 529.340 +#endif
 529.341 +#endif
 529.342 +
 529.343 +
 529.344 +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
 529.345 + * two 16-bit shorts is faster than multiplying two ints.  Define MULTIPLIER
 529.346 + * as short on such a machine.  MULTIPLIER must be at least 16 bits wide.
 529.347 + */
 529.348 +
 529.349 +#ifndef MULTIPLIER
 529.350 +#define MULTIPLIER  int		/* type for fastest integer multiply */
 529.351 +#endif
 529.352 +
 529.353 +
 529.354 +/* FAST_FLOAT should be either float or double, whichever is done faster
 529.355 + * by your compiler.  (Note that this type is only used in the floating point
 529.356 + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
 529.357 + * Typically, float is faster in ANSI C compilers, while double is faster in
 529.358 + * pre-ANSI compilers (because they insist on converting to double anyway).
 529.359 + * The code below therefore chooses float if we have ANSI-style prototypes.
 529.360 + */
 529.361 +
 529.362 +#ifndef FAST_FLOAT
 529.363 +#ifdef HAVE_PROTOTYPES
 529.364 +#define FAST_FLOAT  float
 529.365 +#else
 529.366 +#define FAST_FLOAT  double
 529.367 +#endif
 529.368 +#endif
 529.369 +
 529.370 +#endif /* JPEG_INTERNAL_OPTIONS */
   530.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   530.2 +++ b/libs/libjpeg/jpegint.h	Sat Feb 01 19:58:19 2014 +0200
   530.3 @@ -0,0 +1,392 @@
   530.4 +/*
   530.5 + * jpegint.h
   530.6 + *
   530.7 + * Copyright (C) 1991-1997, Thomas G. Lane.
   530.8 + * This file is part of the Independent JPEG Group's software.
   530.9 + * For conditions of distribution and use, see the accompanying README file.
  530.10 + *
  530.11 + * This file provides common declarations for the various JPEG modules.
  530.12 + * These declarations are considered internal to the JPEG library; most
  530.13 + * applications using the library shouldn't need to include this file.
  530.14 + */
  530.15 +
  530.16 +
  530.17 +/* Declarations for both compression & decompression */
  530.18 +
  530.19 +typedef enum {			/* Operating modes for buffer controllers */
  530.20 +	JBUF_PASS_THRU,		/* Plain stripwise operation */
  530.21 +	/* Remaining modes require a full-image buffer to have been created */
  530.22 +	JBUF_SAVE_SOURCE,	/* Run source subobject only, save output */
  530.23 +	JBUF_CRANK_DEST,	/* Run dest subobject only, using saved data */
  530.24 +	JBUF_SAVE_AND_PASS	/* Run both subobjects, save output */
  530.25 +} J_BUF_MODE;
  530.26 +
  530.27 +/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
  530.28 +#define CSTATE_START	100	/* after create_compress */
  530.29 +#define CSTATE_SCANNING	101	/* start_compress done, write_scanlines OK */
  530.30 +#define CSTATE_RAW_OK	102	/* start_compress done, write_raw_data OK */
  530.31 +#define CSTATE_WRCOEFS	103	/* jpeg_write_coefficients done */
  530.32 +#define DSTATE_START	200	/* after create_decompress */
  530.33 +#define DSTATE_INHEADER	201	/* reading header markers, no SOS yet */
  530.34 +#define DSTATE_READY	202	/* found SOS, ready for start_decompress */
  530.35 +#define DSTATE_PRELOAD	203	/* reading multiscan file in start_decompress*/
  530.36 +#define DSTATE_PRESCAN	204	/* performing dummy pass for 2-pass quant */
  530.37 +#define DSTATE_SCANNING	205	/* start_decompress done, read_scanlines OK */
  530.38 +#define DSTATE_RAW_OK	206	/* start_decompress done, read_raw_data OK */
  530.39 +#define DSTATE_BUFIMAGE	207	/* expecting jpeg_start_output */
  530.40 +#define DSTATE_BUFPOST	208	/* looking for SOS/EOI in jpeg_finish_output */
  530.41 +#define DSTATE_RDCOEFS	209	/* reading file in jpeg_read_coefficients */
  530.42 +#define DSTATE_STOPPING	210	/* looking for EOI in jpeg_finish_decompress */
  530.43 +
  530.44 +
  530.45 +/* Declarations for compression modules */
  530.46 +
  530.47 +/* Master control module */
  530.48 +struct jpeg_comp_master {
  530.49 +  JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo));
  530.50 +  JMETHOD(void, pass_startup, (j_compress_ptr cinfo));
  530.51 +  JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
  530.52 +
  530.53 +  /* State variables made visible to other modules */
  530.54 +  boolean call_pass_startup;	/* True if pass_startup must be called */
  530.55 +  boolean is_last_pass;		/* True during last pass */
  530.56 +};
  530.57 +
  530.58 +/* Main buffer control (downsampled-data buffer) */
  530.59 +struct jpeg_c_main_controller {
  530.60 +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
  530.61 +  JMETHOD(void, process_data, (j_compress_ptr cinfo,
  530.62 +			       JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
  530.63 +			       JDIMENSION in_rows_avail));
  530.64 +};
  530.65 +
  530.66 +/* Compression preprocessing (downsampling input buffer control) */
  530.67 +struct jpeg_c_prep_controller {
  530.68 +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
  530.69 +  JMETHOD(void, pre_process_data, (j_compress_ptr cinfo,
  530.70 +				   JSAMPARRAY input_buf,
  530.71 +				   JDIMENSION *in_row_ctr,
  530.72 +				   JDIMENSION in_rows_avail,
  530.73 +				   JSAMPIMAGE output_buf,
  530.74 +				   JDIMENSION *out_row_group_ctr,
  530.75 +				   JDIMENSION out_row_groups_avail));
  530.76 +};
  530.77 +
  530.78 +/* Coefficient buffer control */
  530.79 +struct jpeg_c_coef_controller {
  530.80 +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
  530.81 +  JMETHOD(boolean, compress_data, (j_compress_ptr cinfo,
  530.82 +				   JSAMPIMAGE input_buf));
  530.83 +};
  530.84 +
  530.85 +/* Colorspace conversion */
  530.86 +struct jpeg_color_converter {
  530.87 +  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
  530.88 +  JMETHOD(void, color_convert, (j_compress_ptr cinfo,
  530.89 +				JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
  530.90 +				JDIMENSION output_row, int num_rows));
  530.91 +};
  530.92 +
  530.93 +/* Downsampling */
  530.94 +struct jpeg_downsampler {
  530.95 +  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
  530.96 +  JMETHOD(void, downsample, (j_compress_ptr cinfo,
  530.97 +			     JSAMPIMAGE input_buf, JDIMENSION in_row_index,
  530.98 +			     JSAMPIMAGE output_buf,
  530.99 +			     JDIMENSION out_row_group_index));
 530.100 +
 530.101 +  boolean need_context_rows;	/* TRUE if need rows above & below */
 530.102 +};
 530.103 +
 530.104 +/* Forward DCT (also controls coefficient quantization) */
 530.105 +struct jpeg_forward_dct {
 530.106 +  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
 530.107 +  /* perhaps this should be an array??? */
 530.108 +  JMETHOD(void, forward_DCT, (j_compress_ptr cinfo,
 530.109 +			      jpeg_component_info * compptr,
 530.110 +			      JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
 530.111 +			      JDIMENSION start_row, JDIMENSION start_col,
 530.112 +			      JDIMENSION num_blocks));
 530.113 +};
 530.114 +
 530.115 +/* Entropy encoding */
 530.116 +struct jpeg_entropy_encoder {
 530.117 +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics));
 530.118 +  JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data));
 530.119 +  JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
 530.120 +};
 530.121 +
 530.122 +/* Marker writing */
 530.123 +struct jpeg_marker_writer {
 530.124 +  JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
 530.125 +  JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
 530.126 +  JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
 530.127 +  JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
 530.128 +  JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
 530.129 +  /* These routines are exported to allow insertion of extra markers */
 530.130 +  /* Probably only COM and APPn markers should be written this way */
 530.131 +  JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
 530.132 +				      unsigned int datalen));
 530.133 +  JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
 530.134 +};
 530.135 +
 530.136 +
 530.137 +/* Declarations for decompression modules */
 530.138 +
 530.139 +/* Master control module */
 530.140 +struct jpeg_decomp_master {
 530.141 +  JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
 530.142 +  JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
 530.143 +
 530.144 +  /* State variables made visible to other modules */
 530.145 +  boolean is_dummy_pass;	/* True during 1st pass for 2-pass quant */
 530.146 +};
 530.147 +
 530.148 +/* Input control module */
 530.149 +struct jpeg_input_controller {
 530.150 +  JMETHOD(int, consume_input, (j_decompress_ptr cinfo));
 530.151 +  JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
 530.152 +  JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
 530.153 +  JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
 530.154 +
 530.155 +  /* State variables made visible to other modules */
 530.156 +  boolean has_multiple_scans;	/* True if file has multiple scans */
 530.157 +  boolean eoi_reached;		/* True when EOI has been consumed */
 530.158 +};
 530.159 +
 530.160 +/* Main buffer control (downsampled-data buffer) */
 530.161 +struct jpeg_d_main_controller {
 530.162 +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
 530.163 +  JMETHOD(void, process_data, (j_decompress_ptr cinfo,
 530.164 +			       JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 530.165 +			       JDIMENSION out_rows_avail));
 530.166 +};
 530.167 +
 530.168 +/* Coefficient buffer control */
 530.169 +struct jpeg_d_coef_controller {
 530.170 +  JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
 530.171 +  JMETHOD(int, consume_data, (j_decompress_ptr cinfo));
 530.172 +  JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
 530.173 +  JMETHOD(int, decompress_data, (j_decompress_ptr cinfo,
 530.174 +				 JSAMPIMAGE output_buf));
 530.175 +  /* Pointer to array of coefficient virtual arrays, or NULL if none */
 530.176 +  jvirt_barray_ptr *coef_arrays;
 530.177 +};
 530.178 +
 530.179 +/* Decompression postprocessing (color quantization buffer control) */
 530.180 +struct jpeg_d_post_controller {
 530.181 +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
 530.182 +  JMETHOD(void, post_process_data, (j_decompress_ptr cinfo,
 530.183 +				    JSAMPIMAGE input_buf,
 530.184 +				    JDIMENSION *in_row_group_ctr,
 530.185 +				    JDIMENSION in_row_groups_avail,
 530.186 +				    JSAMPARRAY output_buf,
 530.187 +				    JDIMENSION *out_row_ctr,
 530.188 +				    JDIMENSION out_rows_avail));
 530.189 +};
 530.190 +
 530.191 +/* Marker reading & parsing */
 530.192 +struct jpeg_marker_reader {
 530.193 +  JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
 530.194 +  /* Read markers until SOS or EOI.
 530.195 +   * Returns same codes as are defined for jpeg_consume_input:
 530.196 +   * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
 530.197 +   */
 530.198 +  JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
 530.199 +  /* Read a restart marker --- exported for use by entropy decoder only */
 530.200 +  jpeg_marker_parser_method read_restart_marker;
 530.201 +
 530.202 +  /* State of marker reader --- nominally internal, but applications
 530.203 +   * supplying COM or APPn handlers might like to know the state.
 530.204 +   */
 530.205 +  boolean saw_SOI;		/* found SOI? */
 530.206 +  boolean saw_SOF;		/* found SOF? */
 530.207 +  int next_restart_num;		/* next restart number expected (0-7) */
 530.208 +  unsigned int discarded_bytes;	/* # of bytes skipped looking for a marker */
 530.209 +};
 530.210 +
 530.211 +/* Entropy decoding */
 530.212 +struct jpeg_entropy_decoder {
 530.213 +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
 530.214 +  JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
 530.215 +				JBLOCKROW *MCU_data));
 530.216 +
 530.217 +  /* This is here to share code between baseline and progressive decoders; */
 530.218 +  /* other modules probably should not use it */
 530.219 +  boolean insufficient_data;	/* set TRUE after emitting warning */
 530.220 +};
 530.221 +
 530.222 +/* Inverse DCT (also performs dequantization) */
 530.223 +typedef JMETHOD(void, inverse_DCT_method_ptr,
 530.224 +		(j_decompress_ptr cinfo, jpeg_component_info * compptr,
 530.225 +		 JCOEFPTR coef_block,
 530.226 +		 JSAMPARRAY output_buf, JDIMENSION output_col));
 530.227 +
 530.228 +struct jpeg_inverse_dct {
 530.229 +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
 530.230 +  /* It is useful to allow each component to have a separate IDCT method. */
 530.231 +  inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
 530.232 +};
 530.233 +
 530.234 +/* Upsampling (note that upsampler must also call color converter) */
 530.235 +struct jpeg_upsampler {
 530.236 +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
 530.237 +  JMETHOD(void, upsample, (j_decompress_ptr cinfo,
 530.238 +			   JSAMPIMAGE input_buf,
 530.239 +			   JDIMENSION *in_row_group_ctr,
 530.240 +			   JDIMENSION in_row_groups_avail,
 530.241 +			   JSAMPARRAY output_buf,
 530.242 +			   JDIMENSION *out_row_ctr,
 530.243 +			   JDIMENSION out_rows_avail));
 530.244 +
 530.245 +  boolean need_context_rows;	/* TRUE if need rows above & below */
 530.246 +};
 530.247 +
 530.248 +/* Colorspace conversion */
 530.249 +struct jpeg_color_deconverter {
 530.250 +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
 530.251 +  JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
 530.252 +				JSAMPIMAGE input_buf, JDIMENSION input_row,
 530.253 +				JSAMPARRAY output_buf, int num_rows));
 530.254 +};
 530.255 +
 530.256 +/* Color quantization or color precision reduction */
 530.257 +struct jpeg_color_quantizer {
 530.258 +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
 530.259 +  JMETHOD(void, color_quantize, (j_decompress_ptr cinfo,
 530.260 +				 JSAMPARRAY input_buf, JSAMPARRAY output_buf,
 530.261 +				 int num_rows));
 530.262 +  JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
 530.263 +  JMETHOD(void, new_color_map, (j_decompress_ptr cinfo));
 530.264 +};
 530.265 +
 530.266 +
 530.267 +/* Miscellaneous useful macros */
 530.268 +
 530.269 +#undef MAX
 530.270 +#define MAX(a,b)	((a) > (b) ? (a) : (b))
 530.271 +#undef MIN
 530.272 +#define MIN(a,b)	((a) < (b) ? (a) : (b))
 530.273 +
 530.274 +
 530.275 +/* We assume that right shift corresponds to signed division by 2 with
 530.276 + * rounding towards minus infinity.  This is correct for typical "arithmetic
 530.277 + * shift" instructions that shift in copies of the sign bit.  But some
 530.278 + * C compilers implement >> with an unsigned shift.  For these machines you
 530.279 + * must define RIGHT_SHIFT_IS_UNSIGNED.
 530.280 + * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
 530.281 + * It is only applied with constant shift counts.  SHIFT_TEMPS must be
 530.282 + * included in the variables of any routine using RIGHT_SHIFT.
 530.283 + */
 530.284 +
 530.285 +#ifdef RIGHT_SHIFT_IS_UNSIGNED
 530.286 +#define SHIFT_TEMPS	INT32 shift_temp;
 530.287 +#define RIGHT_SHIFT(x,shft)  \
 530.288 +	((shift_temp = (x)) < 0 ? \
 530.289 +	 (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
 530.290 +	 (shift_temp >> (shft)))
 530.291 +#else
 530.292 +#define SHIFT_TEMPS
 530.293 +#define RIGHT_SHIFT(x,shft)	((x) >> (shft))
 530.294 +#endif
 530.295 +
 530.296 +
 530.297 +/* Short forms of external names for systems with brain-damaged linkers. */
 530.298 +
 530.299 +#ifdef NEED_SHORT_EXTERNAL_NAMES
 530.300 +#define jinit_compress_master	jICompress
 530.301 +#define jinit_c_master_control	jICMaster
 530.302 +#define jinit_c_main_controller	jICMainC
 530.303 +#define jinit_c_prep_controller	jICPrepC
 530.304 +#define jinit_c_coef_controller	jICCoefC
 530.305 +#define jinit_color_converter	jICColor
 530.306 +#define jinit_downsampler	jIDownsampler
 530.307 +#define jinit_forward_dct	jIFDCT
 530.308 +#define jinit_huff_encoder	jIHEncoder
 530.309 +#define jinit_phuff_encoder	jIPHEncoder
 530.310 +#define jinit_marker_writer	jIMWriter
 530.311 +#define jinit_master_decompress	jIDMaster
 530.312 +#define jinit_d_main_controller	jIDMainC
 530.313 +#define jinit_d_coef_controller	jIDCoefC
 530.314 +#define jinit_d_post_controller	jIDPostC
 530.315 +#define jinit_input_controller	jIInCtlr
 530.316 +#define jinit_marker_reader	jIMReader
 530.317 +#define jinit_huff_decoder	jIHDecoder
 530.318 +#define jinit_phuff_decoder	jIPHDecoder
 530.319 +#define jinit_inverse_dct	jIIDCT
 530.320 +#define jinit_upsampler		jIUpsampler
 530.321 +#define jinit_color_deconverter	jIDColor
 530.322 +#define jinit_1pass_quantizer	jI1Quant
 530.323 +#define jinit_2pass_quantizer	jI2Quant
 530.324 +#define jinit_merged_upsampler	jIMUpsampler
 530.325 +#define jinit_memory_mgr	jIMemMgr
 530.326 +#define jdiv_round_up		jDivRound
 530.327 +#define jround_up		jRound
 530.328 +#define jcopy_sample_rows	jCopySamples
 530.329 +#define jcopy_block_row		jCopyBlocks
 530.330 +#define jzero_far		jZeroFar
 530.331 +#define jpeg_zigzag_order	jZIGTable
 530.332 +#define jpeg_natural_order	jZAGTable
 530.333 +#endif /* NEED_SHORT_EXTERNAL_NAMES */
 530.334 +
 530.335 +
 530.336 +/* Compression module initialization routines */
 530.337 +EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
 530.338 +EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
 530.339 +					 boolean transcode_only));
 530.340 +EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
 530.341 +					  boolean need_full_buffer));
 530.342 +EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
 530.343 +					  boolean need_full_buffer));
 530.344 +EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
 530.345 +					  boolean need_full_buffer));
 530.346 +EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
 530.347 +EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
 530.348 +EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
 530.349 +EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
 530.350 +EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
 530.351 +EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
 530.352 +/* Decompression module initialization routines */
 530.353 +EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
 530.354 +EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
 530.355 +					  boolean need_full_buffer));
 530.356 +EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
 530.357 +					  boolean need_full_buffer));
 530.358 +EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
 530.359 +					  boolean need_full_buffer));
 530.360 +EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
 530.361 +EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
 530.362 +EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
 530.363 +EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
 530.364 +EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
 530.365 +EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
 530.366 +EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
 530.367 +EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
 530.368 +EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
 530.369 +EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
 530.370 +/* Memory manager initialization */
 530.371 +EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
 530.372 +
 530.373 +/* Utility routines in jutils.c */
 530.374 +EXTERN(long) jdiv_round_up JPP((long a, long b));
 530.375 +EXTERN(long) jround_up JPP((long a, long b));
 530.376 +EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
 530.377 +				    JSAMPARRAY output_array, int dest_row,
 530.378 +				    int num_rows, JDIMENSION num_cols));
 530.379 +EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
 530.380 +				  JDIMENSION num_blocks));
 530.381 +EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
 530.382 +/* Constant tables in jutils.c */
 530.383 +#if 0				/* This table is not actually needed in v6a */
 530.384 +extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
 530.385 +#endif
 530.386 +extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
 530.387 +
 530.388 +/* Suppress undefined-structure complaints if necessary. */
 530.389 +
 530.390 +#ifdef INCOMPLETE_TYPES_BROKEN
 530.391 +#ifndef AM_MEMORY_MANAGER	/* only jmemmgr.c defines these */
 530.392 +struct jvirt_sarray_control { long dummy; };
 530.393 +struct jvirt_barray_control { long dummy; };
 530.394 +#endif
 530.395 +#endif /* INCOMPLETE_TYPES_BROKEN */
   531.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   531.2 +++ b/libs/libjpeg/jpeglib.h	Sat Feb 01 19:58:19 2014 +0200
   531.3 @@ -0,0 +1,1096 @@
   531.4 +/*
   531.5 + * jpeglib.h
   531.6 + *
   531.7 + * Copyright (C) 1991-1998, Thomas G. Lane.
   531.8 + * This file is part of the Independent JPEG Group's software.
   531.9 + * For conditions of distribution and use, see the accompanying README file.
  531.10 + *
  531.11 + * This file defines the application interface for the JPEG library.
  531.12 + * Most applications using the library need only include this file,
  531.13 + * and perhaps jerror.h if they want to know the exact error codes.
  531.14 + */
  531.15 +
  531.16 +#ifndef JPEGLIB_H
  531.17 +#define JPEGLIB_H
  531.18 +
  531.19 +/*
  531.20 + * First we include the configuration files that record how this
  531.21 + * installation of the JPEG library is set up.  jconfig.h can be
  531.22 + * generated automatically for many systems.  jmorecfg.h contains
  531.23 + * manual configuration options that most people need not worry about.
  531.24 + */
  531.25 +
  531.26 +#ifndef JCONFIG_INCLUDED	/* in case jinclude.h already did */
  531.27 +#include "jconfig.h"		/* widely used configuration options */
  531.28 +#endif
  531.29 +#include "jmorecfg.h"		/* seldom changed options */
  531.30 +
  531.31 +
  531.32 +/* Version ID for the JPEG library.
  531.33 + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
  531.34 + */
  531.35 +
  531.36 +#define JPEG_LIB_VERSION  62	/* Version 6b */
  531.37 +
  531.38 +
  531.39 +/* Various constants determining the sizes of things.
  531.40 + * All of these are specified by the JPEG standard, so don't change them
  531.41 + * if you want to be compatible.
  531.42 + */
  531.43 +
  531.44 +#define DCTSIZE		    8	/* The basic DCT block is 8x8 samples */
  531.45 +#define DCTSIZE2	    64	/* DCTSIZE squared; # of elements in a block */
  531.46 +#define NUM_QUANT_TBLS      4	/* Quantization tables are numbered 0..3 */
  531.47 +#define NUM_HUFF_TBLS       4	/* Huffman tables are numbered 0..3 */
  531.48 +#define NUM_ARITH_TBLS      16	/* Arith-coding tables are numbered 0..15 */
  531.49 +#define MAX_COMPS_IN_SCAN   4	/* JPEG limit on # of components in one scan */
  531.50 +#define MAX_SAMP_FACTOR     4	/* JPEG limit on sampling factors */
  531.51 +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
  531.52 + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
  531.53 + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
  531.54 + * to handle it.  We even let you do this from the jconfig.h file.  However,
  531.55 + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
  531.56 + * sometimes emits noncompliant files doesn't mean you should too.
  531.57 + */
  531.58 +#define C_MAX_BLOCKS_IN_MCU   10 /* compressor's limit on blocks per MCU */
  531.59 +#ifndef D_MAX_BLOCKS_IN_MCU
  531.60 +#define D_MAX_BLOCKS_IN_MCU   10 /* decompressor's limit on blocks per MCU */
  531.61 +#endif
  531.62 +
  531.63 +
  531.64 +/* Data structures for images (arrays of samples and of DCT coefficients).
  531.65 + * On 80x86 machines, the image arrays are too big for near pointers,
  531.66 + * but the pointer arrays can fit in near memory.
  531.67 + */
  531.68 +
  531.69 +typedef JSAMPLE FAR *JSAMPROW;	/* ptr to one image row of pixel samples. */
  531.70 +typedef JSAMPROW *JSAMPARRAY;	/* ptr to some rows (a 2-D sample array) */
  531.71 +typedef JSAMPARRAY *JSAMPIMAGE;	/* a 3-D sample array: top index is color */
  531.72 +
  531.73 +typedef JCOEF JBLOCK[DCTSIZE2];	/* one block of coefficients */
  531.74 +typedef JBLOCK FAR *JBLOCKROW;	/* pointer to one row of coefficient blocks */
  531.75 +typedef JBLOCKROW *JBLOCKARRAY;		/* a 2-D array of coefficient blocks */
  531.76 +typedef JBLOCKARRAY *JBLOCKIMAGE;	/* a 3-D array of coefficient blocks */
  531.77 +
  531.78 +typedef JCOEF FAR *JCOEFPTR;	/* useful in a couple of places */
  531.79 +
  531.80 +
  531.81 +/* Types for JPEG compression parameters and working tables. */
  531.82 +
  531.83 +
  531.84 +/* DCT coefficient quantization tables. */
  531.85 +
  531.86 +typedef struct {
  531.87 +  /* This array gives the coefficient quantizers in natural array order
  531.88 +   * (not the zigzag order in which they are stored in a JPEG DQT marker).
  531.89 +   * CAUTION: IJG versions prior to v6a kept this array in zigzag order.
  531.90 +   */
  531.91 +  UINT16 quantval[DCTSIZE2];	/* quantization step for each coefficient */
  531.92 +  /* This field is used only during compression.  It's initialized FALSE when
  531.93 +   * the table is created, and set TRUE when it's been output to the file.
  531.94 +   * You could suppress output of a table by setting this to TRUE.
  531.95 +   * (See jpeg_suppress_tables for an example.)
  531.96 +   */
  531.97 +  boolean sent_table;		/* TRUE when table has been output */
  531.98 +} JQUANT_TBL;
  531.99 +
 531.100 +
 531.101 +/* Huffman coding tables. */
 531.102 +
 531.103 +typedef struct {
 531.104 +  /* These two fields directly represent the contents of a JPEG DHT marker */
 531.105 +  UINT8 bits[17];		/* bits[k] = # of symbols with codes of */
 531.106 +				/* length k bits; bits[0] is unused */
 531.107 +  UINT8 huffval[256];		/* The symbols, in order of incr code length */
 531.108 +  /* This field is used only during compression.  It's initialized FALSE when
 531.109 +   * the table is created, and set TRUE when it's been output to the file.
 531.110 +   * You could suppress output of a table by setting this to TRUE.
 531.111 +   * (See jpeg_suppress_tables for an example.)
 531.112 +   */
 531.113 +  boolean sent_table;		/* TRUE when table has been output */
 531.114 +} JHUFF_TBL;
 531.115 +
 531.116 +
 531.117 +/* Basic info about one component (color channel). */
 531.118 +
 531.119 +typedef struct {
 531.120 +  /* These values are fixed over the whole image. */
 531.121 +  /* For compression, they must be supplied by parameter setup; */
 531.122 +  /* for decompression, they are read from the SOF marker. */
 531.123 +  int component_id;		/* identifier for this component (0..255) */
 531.124 +  int component_index;		/* its index in SOF or cinfo->comp_info[] */
 531.125 +  int h_samp_factor;		/* horizontal sampling factor (1..4) */
 531.126 +  int v_samp_factor;		/* vertical sampling factor (1..4) */
 531.127 +  int quant_tbl_no;		/* quantization table selector (0..3) */
 531.128 +  /* These values may vary between scans. */
 531.129 +  /* For compression, they must be supplied by parameter setup; */
 531.130 +  /* for decompression, they are read from the SOS marker. */
 531.131 +  /* The decompressor output side may not use these variables. */
 531.132 +  int dc_tbl_no;		/* DC entropy table selector (0..3) */
 531.133 +  int ac_tbl_no;		/* AC entropy table selector (0..3) */
 531.134 +  
 531.135 +  /* Remaining fields should be treated as private by applications. */
 531.136 +  
 531.137 +  /* These values are computed during compression or decompression startup: */
 531.138 +  /* Component's size in DCT blocks.
 531.139 +   * Any dummy blocks added to complete an MCU are not counted; therefore
 531.140 +   * these values do not depend on whether a scan is interleaved or not.
 531.141 +   */
 531.142 +  JDIMENSION width_in_blocks;
 531.143 +  JDIMENSION height_in_blocks;
 531.144 +  /* Size of a DCT block in samples.  Always DCTSIZE for compression.
 531.145 +   * For decompression this is the size of the output from one DCT block,
 531.146 +   * reflecting any scaling we choose to apply during the IDCT step.
 531.147 +   * Values of 1,2,4,8 are likely to be supported.  Note that different
 531.148 +   * components may receive different IDCT scalings.
 531.149 +   */
 531.150 +  int DCT_scaled_size;
 531.151 +  /* The downsampled dimensions are the component's actual, unpadded number
 531.152 +   * of samples at the main buffer (preprocessing/compression interface), thus
 531.153 +   * downsampled_width = ceil(image_width * Hi/Hmax)
 531.154 +   * and similarly for height.  For decompression, IDCT scaling is included, so
 531.155 +   * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
 531.156 +   */
 531.157 +  JDIMENSION downsampled_width;	 /* actual width in samples */
 531.158 +  JDIMENSION downsampled_height; /* actual height in samples */
 531.159 +  /* This flag is used only for decompression.  In cases where some of the
 531.160 +   * components will be ignored (eg grayscale output from YCbCr image),
 531.161 +   * we can skip most computations for the unused components.
 531.162 +   */
 531.163 +  boolean component_needed;	/* do we need the value of this component? */
 531.164 +
 531.165 +  /* These values are computed before starting a scan of the component. */
 531.166 +  /* The decompressor output side may not use these variables. */
 531.167 +  int MCU_width;		/* number of blocks per MCU, horizontally */
 531.168 +  int MCU_height;		/* number of blocks per MCU, vertically */
 531.169 +  int MCU_blocks;		/* MCU_width * MCU_height */
 531.170 +  int MCU_sample_width;		/* MCU width in samples, MCU_width*DCT_scaled_size */
 531.171 +  int last_col_width;		/* # of non-dummy blocks across in last MCU */
 531.172 +  int last_row_height;		/* # of non-dummy blocks down in last MCU */
 531.173 +
 531.174 +  /* Saved quantization table for component; NULL if none yet saved.
 531.175 +   * See jdinput.c comments about the need for this information.
 531.176 +   * This field is currently used only for decompression.
 531.177 +   */
 531.178 +  JQUANT_TBL * quant_table;
 531.179 +
 531.180 +  /* Private per-component storage for DCT or IDCT subsystem. */
 531.181 +  void * dct_table;
 531.182 +} jpeg_component_info;
 531.183 +
 531.184 +
 531.185 +/* The script for encoding a multiple-scan file is an array of these: */
 531.186 +
 531.187 +typedef struct {
 531.188 +  int comps_in_scan;		/* number of components encoded in this scan */
 531.189 +  int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
 531.190 +  int Ss, Se;			/* progressive JPEG spectral selection parms */
 531.191 +  int Ah, Al;			/* progressive JPEG successive approx. parms */
 531.192 +} jpeg_scan_info;
 531.193 +
 531.194 +/* The decompressor can save APPn and COM markers in a list of these: */
 531.195 +
 531.196 +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr;
 531.197 +
 531.198 +struct jpeg_marker_struct {
 531.199 +  jpeg_saved_marker_ptr next;	/* next in list, or NULL */
 531.200 +  UINT8 marker;			/* marker code: JPEG_COM, or JPEG_APP0+n */
 531.201 +  unsigned int original_length;	/* # bytes of data in the file */
 531.202 +  unsigned int data_length;	/* # bytes of data saved at data[] */
 531.203 +  JOCTET FAR * data;		/* the data contained in the marker */
 531.204 +  /* the marker length word is not counted in data_length or original_length */
 531.205 +};
 531.206 +
 531.207 +/* Known color spaces. */
 531.208 +
 531.209 +typedef enum {
 531.210 +	JCS_UNKNOWN,		/* error/unspecified */
 531.211 +	JCS_GRAYSCALE,		/* monochrome */
 531.212 +	JCS_RGB,		/* red/green/blue */
 531.213 +	JCS_YCbCr,		/* Y/Cb/Cr (also known as YUV) */
 531.214 +	JCS_CMYK,		/* C/M/Y/K */
 531.215 +	JCS_YCCK		/* Y/Cb/Cr/K */
 531.216 +} J_COLOR_SPACE;
 531.217 +
 531.218 +/* DCT/IDCT algorithm options. */
 531.219 +
 531.220 +typedef enum {
 531.221 +	JDCT_ISLOW,		/* slow but accurate integer algorithm */
 531.222 +	JDCT_IFAST,		/* faster, less accurate integer method */
 531.223 +	JDCT_FLOAT		/* floating-point: accurate, fast on fast HW */
 531.224 +} J_DCT_METHOD;
 531.225 +
 531.226 +#ifndef JDCT_DEFAULT		/* may be overridden in jconfig.h */
 531.227 +#define JDCT_DEFAULT  JDCT_ISLOW
 531.228 +#endif
 531.229 +#ifndef JDCT_FASTEST		/* may be overridden in jconfig.h */
 531.230 +#define JDCT_FASTEST  JDCT_IFAST
 531.231 +#endif
 531.232 +
 531.233 +/* Dithering options for decompression. */
 531.234 +
 531.235 +typedef enum {
 531.236 +	JDITHER_NONE,		/* no dithering */
 531.237 +	JDITHER_ORDERED,	/* simple ordered dither */
 531.238 +	JDITHER_FS		/* Floyd-Steinberg error diffusion dither */
 531.239 +} J_DITHER_MODE;
 531.240 +
 531.241 +
 531.242 +/* Common fields between JPEG compression and decompression master structs. */
 531.243 +
 531.244 +#define jpeg_common_fields \
 531.245 +  struct jpeg_error_mgr * err;	/* Error handler module */\
 531.246 +  struct jpeg_memory_mgr * mem;	/* Memory manager module */\
 531.247 +  struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
 531.248 +  void * client_data;		/* Available for use by application */\
 531.249 +  boolean is_decompressor;	/* So common code can tell which is which */\
 531.250 +  int global_state		/* For checking call sequence validity */
 531.251 +
 531.252 +/* Routines that are to be used by both halves of the library are declared
 531.253 + * to receive a pointer to this structure.  There are no actual instances of
 531.254 + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
 531.255 + */
 531.256 +struct jpeg_common_struct {
 531.257 +  jpeg_common_fields;		/* Fields common to both master struct types */
 531.258 +  /* Additional fields follow in an actual jpeg_compress_struct or
 531.259 +   * jpeg_decompress_struct.  All three structs must agree on these
 531.260 +   * initial fields!  (This would be a lot cleaner in C++.)
 531.261 +   */
 531.262 +};
 531.263 +
 531.264 +typedef struct jpeg_common_struct * j_common_ptr;
 531.265 +typedef struct jpeg_compress_struct * j_compress_ptr;
 531.266 +typedef struct jpeg_decompress_struct * j_decompress_ptr;
 531.267 +
 531.268 +
 531.269 +/* Master record for a compression instance */
 531.270 +
 531.271 +struct jpeg_compress_struct {
 531.272 +  jpeg_common_fields;		/* Fields shared with jpeg_decompress_struct */
 531.273 +
 531.274 +  /* Destination for compressed data */
 531.275 +  struct jpeg_destination_mgr * dest;
 531.276 +
 531.277 +  /* Description of source image --- these fields must be filled in by
 531.278 +   * outer application before starting compression.  in_color_space must
 531.279 +   * be correct before you can even call jpeg_set_defaults().
 531.280 +   */
 531.281 +
 531.282 +  JDIMENSION image_width;	/* input image width */
 531.283 +  JDIMENSION image_height;	/* input image height */
 531.284 +  int input_components;		/* # of color components in input image */
 531.285 +  J_COLOR_SPACE in_color_space;	/* colorspace of input image */
 531.286 +
 531.287 +  double input_gamma;		/* image gamma of input image */
 531.288 +
 531.289 +  /* Compression parameters --- these fields must be set before calling
 531.290 +   * jpeg_start_compress().  We recommend calling jpeg_set_defaults() to
 531.291 +   * initialize everything to reasonable defaults, then changing anything
 531.292 +   * the application specifically wants to change.  That way you won't get
 531.293 +   * burnt when new parameters are added.  Also note that there are several
 531.294 +   * helper routines to simplify changing parameters.
 531.295 +   */
 531.296 +
 531.297 +  int data_precision;		/* bits of precision in image data */
 531.298 +
 531.299 +  int num_components;		/* # of color components in JPEG image */
 531.300 +  J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
 531.301 +
 531.302 +  jpeg_component_info * comp_info;
 531.303 +  /* comp_info[i] describes component that appears i'th in SOF */
 531.304 +  
 531.305 +  JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
 531.306 +  /* ptrs to coefficient quantization tables, or NULL if not defined */
 531.307 +  
 531.308 +  JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
 531.309 +  JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
 531.310 +  /* ptrs to Huffman coding tables, or NULL if not defined */
 531.311 +  
 531.312 +  UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
 531.313 +  UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
 531.314 +  UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
 531.315 +
 531.316 +  int num_scans;		/* # of entries in scan_info array */
 531.317 +  const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */
 531.318 +  /* The default value of scan_info is NULL, which causes a single-scan
 531.319 +   * sequential JPEG file to be emitted.  To create a multi-scan file,
 531.320 +   * set num_scans and scan_info to point to an array of scan definitions.
 531.321 +   */
 531.322 +
 531.323 +  boolean raw_data_in;		/* TRUE=caller supplies downsampled data */
 531.324 +  boolean arith_code;		/* TRUE=arithmetic coding, FALSE=Huffman */
 531.325 +  boolean optimize_coding;	/* TRUE=optimize entropy encoding parms */
 531.326 +  boolean CCIR601_sampling;	/* TRUE=first samples are cosited */
 531.327 +  int smoothing_factor;		/* 1..100, or 0 for no input smoothing */
 531.328 +  J_DCT_METHOD dct_method;	/* DCT algorithm selector */
 531.329 +
 531.330 +  /* The restart interval can be specified in absolute MCUs by setting
 531.331 +   * restart_interval, or in MCU rows by setting restart_in_rows
 531.332 +   * (in which case the correct restart_interval will be figured
 531.333 +   * for each scan).
 531.334 +   */
 531.335 +  unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
 531.336 +  int restart_in_rows;		/* if > 0, MCU rows per restart interval */
 531.337 +
 531.338 +  /* Parameters controlling emission of special markers. */
 531.339 +
 531.340 +  boolean write_JFIF_header;	/* should a JFIF marker be written? */
 531.341 +  UINT8 JFIF_major_version;	/* What to write for the JFIF version number */
 531.342 +  UINT8 JFIF_minor_version;
 531.343 +  /* These three values are not used by the JPEG code, merely copied */
 531.344 +  /* into the JFIF APP0 marker.  density_unit can be 0 for unknown, */
 531.345 +  /* 1 for dots/inch, or 2 for dots/cm.  Note that the pixel aspect */
 531.346 +  /* ratio is defined by X_density/Y_density even when density_unit=0. */
 531.347 +  UINT8 density_unit;		/* JFIF code for pixel size units */
 531.348 +  UINT16 X_density;		/* Horizontal pixel density */
 531.349 +  UINT16 Y_density;		/* Vertical pixel density */
 531.350 +  boolean write_Adobe_marker;	/* should an Adobe marker be written? */
 531.351 +  
 531.352 +  /* State variable: index of next scanline to be written to
 531.353 +   * jpeg_write_scanlines().  Application may use this to control its
 531.354 +   * processing loop, e.g., "while (next_scanline < image_height)".
 531.355 +   */
 531.356 +
 531.357 +  JDIMENSION next_scanline;	/* 0 .. image_height-1  */
 531.358 +
 531.359 +  /* Remaining fields are known throughout compressor, but generally
 531.360 +   * should not be touched by a surrounding application.
 531.361 +   */
 531.362 +
 531.363 +  /*
 531.364 +   * These fields are computed during compression startup
 531.365 +   */
 531.366 +  boolean progressive_mode;	/* TRUE if scan script uses progressive mode */
 531.367 +  int max_h_samp_factor;	/* largest h_samp_factor */
 531.368 +  int max_v_samp_factor;	/* largest v_samp_factor */
 531.369 +
 531.370 +  JDIMENSION total_iMCU_rows;	/* # of iMCU rows to be input to coef ctlr */
 531.371 +  /* The coefficient controller receives data in units of MCU rows as defined
 531.372 +   * for fully interleaved scans (whether the JPEG file is interleaved or not).
 531.373 +   * There are v_samp_factor * DCTSIZE sample rows of each component in an
 531.374 +   * "iMCU" (interleaved MCU) row.
 531.375 +   */
 531.376 +  
 531.377 +  /*
 531.378 +   * These fields are valid during any one scan.
 531.379 +   * They describe the components and MCUs actually appearing in the scan.
 531.380 +   */
 531.381 +  int comps_in_scan;		/* # of JPEG components in this scan */
 531.382 +  jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
 531.383 +  /* *cur_comp_info[i] describes component that appears i'th in SOS */
 531.384 +  
 531.385 +  JDIMENSION MCUs_per_row;	/* # of MCUs across the image */
 531.386 +  JDIMENSION MCU_rows_in_scan;	/* # of MCU rows in the image */
 531.387 +  
 531.388 +  int blocks_in_MCU;		/* # of DCT blocks per MCU */
 531.389 +  int MCU_membership[C_MAX_BLOCKS_IN_MCU];
 531.390 +  /* MCU_membership[i] is index in cur_comp_info of component owning */
 531.391 +  /* i'th block in an MCU */
 531.392 +
 531.393 +  int Ss, Se, Ah, Al;		/* progressive JPEG parameters for scan */
 531.394 +
 531.395 +  /*
 531.396 +   * Links to compression subobjects (methods and private variables of modules)
 531.397 +   */
 531.398 +  struct jpeg_comp_master * master;
 531.399 +  struct jpeg_c_main_controller * main;
 531.400 +  struct jpeg_c_prep_controller * prep;
 531.401 +  struct jpeg_c_coef_controller * coef;
 531.402 +  struct jpeg_marker_writer * marker;
 531.403 +  struct jpeg_color_converter * cconvert;
 531.404 +  struct jpeg_downsampler * downsample;
 531.405 +  struct jpeg_forward_dct * fdct;
 531.406 +  struct jpeg_entropy_encoder * entropy;
 531.407 +  jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
 531.408 +  int script_space_size;
 531.409 +};
 531.410 +
 531.411 +
 531.412 +/* Master record for a decompression instance */
 531.413 +
 531.414 +struct jpeg_decompress_struct {
 531.415 +  jpeg_common_fields;		/* Fields shared with jpeg_compress_struct */
 531.416 +
 531.417 +  /* Source of compressed data */
 531.418 +  struct jpeg_source_mgr * src;
 531.419 +
 531.420 +  /* Basic description of image --- filled in by jpeg_read_header(). */
 531.421 +  /* Application may inspect these values to decide how to process image. */
 531.422 +
 531.423 +  JDIMENSION image_width;	/* nominal image width (from SOF marker) */
 531.424 +  JDIMENSION image_height;	/* nominal image height */
 531.425 +  int num_components;		/* # of color components in JPEG image */
 531.426 +  J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
 531.427 +
 531.428 +  /* Decompression processing parameters --- these fields must be set before
 531.429 +   * calling jpeg_start_decompress().  Note that jpeg_read_header() initializes
 531.430 +   * them to default values.
 531.431 +   */
 531.432 +
 531.433 +  J_COLOR_SPACE out_color_space; /* colorspace for output */
 531.434 +
 531.435 +  unsigned int scale_num, scale_denom; /* fraction by which to scale image */
 531.436 +
 531.437 +  double output_gamma;		/* image gamma wanted in output */
 531.438 +
 531.439 +  boolean buffered_image;	/* TRUE=multiple output passes */
 531.440 +  boolean raw_data_out;		/* TRUE=downsampled data wanted */
 531.441 +
 531.442 +  J_DCT_METHOD dct_method;	/* IDCT algorithm selector */
 531.443 +  boolean do_fancy_upsampling;	/* TRUE=apply fancy upsampling */
 531.444 +  boolean do_block_smoothing;	/* TRUE=apply interblock smoothing */
 531.445 +
 531.446 +  boolean quantize_colors;	/* TRUE=colormapped output wanted */
 531.447 +  /* the following are ignored if not quantize_colors: */
 531.448 +  J_DITHER_MODE dither_mode;	/* type of color dithering to use */
 531.449 +  boolean two_pass_quantize;	/* TRUE=use two-pass color quantization */
 531.450 +  int desired_number_of_colors;	/* max # colors to use in created colormap */
 531.451 +  /* these are significant only in buffered-image mode: */
 531.452 +  boolean enable_1pass_quant;	/* enable future use of 1-pass quantizer */
 531.453 +  boolean enable_external_quant;/* enable future use of external colormap */
 531.454 +  boolean enable_2pass_quant;	/* enable future use of 2-pass quantizer */
 531.455 +
 531.456 +  /* Description of actual output image that will be returned to application.
 531.457 +   * These fields are computed by jpeg_start_decompress().
 531.458 +   * You can also use jpeg_calc_output_dimensions() to determine these values
 531.459 +   * in advance of calling jpeg_start_decompress().
 531.460 +   */
 531.461 +
 531.462 +  JDIMENSION output_width;	/* scaled image width */
 531.463 +  JDIMENSION output_height;	/* scaled image height */
 531.464 +  int out_color_components;	/* # of color components in out_color_space */
 531.465 +  int output_components;	/* # of color components returned */
 531.466 +  /* output_components is 1 (a colormap index) when quantizing colors;
 531.467 +   * otherwise it equals out_color_components.
 531.468 +   */
 531.469 +  int rec_outbuf_height;	/* min recommended height of scanline buffer */
 531.470 +  /* If the buffer passed to jpeg_read_scanlines() is less than this many rows
 531.471 +   * high, space and time will be wasted due to unnecessary data copying.
 531.472 +   * Usually rec_outbuf_height will be 1 or 2, at most 4.
 531.473 +   */
 531.474 +
 531.475 +  /* When quantizing colors, the output colormap is described by these fields.
 531.476 +   * The application can supply a colormap by setting colormap non-NULL before
 531.477 +   * calling jpeg_start_decompress; otherwise a colormap is created during
 531.478 +   * jpeg_start_decompress or jpeg_start_output.
 531.479 +   * The map has out_color_components rows and actual_number_of_colors columns.
 531.480 +   */
 531.481 +  int actual_number_of_colors;	/* number of entries in use */
 531.482 +  JSAMPARRAY colormap;		/* The color map as a 2-D pixel array */
 531.483 +
 531.484 +  /* State variables: these variables indicate the progress of decompression.
 531.485 +   * The application may examine these but must not modify them.
 531.486 +   */
 531.487 +
 531.488 +  /* Row index of next scanline to be read from jpeg_read_scanlines().
 531.489 +   * Application may use this to control its processing loop, e.g.,
 531.490 +   * "while (output_scanline < output_height)".
 531.491 +   */
 531.492 +  JDIMENSION output_scanline;	/* 0 .. output_height-1  */
 531.493 +
 531.494 +  /* Current input scan number and number of iMCU rows completed in scan.
 531.495 +   * These indicate the progress of the decompressor input side.
 531.496 +   */
 531.497 +  int input_scan_number;	/* Number of SOS markers seen so far */
 531.498 +  JDIMENSION input_iMCU_row;	/* Number of iMCU rows completed */
 531.499 +
 531.500 +  /* The "output scan number" is the notional scan being displayed by the
 531.501 +   * output side.  The decompressor will not allow output scan/row number
 531.502 +   * to get ahead of input scan/row, but it can fall arbitrarily far behind.
 531.503 +   */
 531.504 +  int output_scan_number;	/* Nominal scan number being displayed */
 531.505 +  JDIMENSION output_iMCU_row;	/* Number of iMCU rows read */
 531.506 +
 531.507 +  /* Current progression status.  coef_bits[c][i] indicates the precision
 531.508 +   * with which component c's DCT coefficient i (in zigzag order) is known.
 531.509 +   * It is -1 when no data has yet been received, otherwise it is the point
 531.510 +   * transform (shift) value for the most recent scan of the coefficient
 531.511 +   * (thus, 0 at completion of the progression).
 531.512 +   * This pointer is NULL when reading a non-progressive file.
 531.513 +   */
 531.514 +  int (*coef_bits)[DCTSIZE2];	/* -1 or current Al value for each coef */
 531.515 +
 531.516 +  /* Internal JPEG parameters --- the application usually need not look at
 531.517 +   * these fields.  Note that the decompressor output side may not use
 531.518 +   * any parameters that can change between scans.
 531.519 +   */
 531.520 +
 531.521 +  /* Quantization and Huffman tables are carried forward across input
 531.522 +   * datastreams when processing abbreviated JPEG datastreams.
 531.523 +   */
 531.524 +
 531.525 +  JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
 531.526 +  /* ptrs to coefficient quantization tables, or NULL if not defined */
 531.527 +
 531.528 +  JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
 531.529 +  JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
 531.530 +  /* ptrs to Huffman coding tables, or NULL if not defined */
 531.531 +
 531.532 +  /* These parameters are never carried across datastreams, since they
 531.533 +   * are given in SOF/SOS markers or defined to be reset by SOI.
 531.534 +   */
 531.535 +
 531.536 +  int data_precision;		/* bits of precision in image data */
 531.537 +
 531.538 +  jpeg_component_info * comp_info;
 531.539 +  /* comp_info[i] describes component that appears i'th in SOF */
 531.540 +
 531.541 +  boolean progressive_mode;	/* TRUE if SOFn specifies progressive mode */
 531.542 +  boolean arith_code;		/* TRUE=arithmetic coding, FALSE=Huffman */
 531.543 +
 531.544 +  UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
 531.545 +  UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
 531.546 +  UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
 531.547 +
 531.548 +  unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */
 531.549 +
 531.550 +  /* These fields record data obtained from optional markers recognized by
 531.551 +   * the JPEG library.
 531.552 +   */
 531.553 +  boolean saw_JFIF_marker;	/* TRUE iff a JFIF APP0 marker was found */
 531.554 +  /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
 531.555 +  UINT8 JFIF_major_version;	/* JFIF version number */
 531.556 +  UINT8 JFIF_minor_version;
 531.557 +  UINT8 density_unit;		/* JFIF code for pixel size units */
 531.558 +  UINT16 X_density;		/* Horizontal pixel density */
 531.559 +  UINT16 Y_density;		/* Vertical pixel density */
 531.560 +  boolean saw_Adobe_marker;	/* TRUE iff an Adobe APP14 marker was found */
 531.561 +  UINT8 Adobe_transform;	/* Color transform code from Adobe marker */
 531.562 +
 531.563 +  boolean CCIR601_sampling;	/* TRUE=first samples are cosited */
 531.564 +
 531.565 +  /* Aside from the specific data retained from APPn markers known to the
 531.566 +   * library, the uninterpreted contents of any or all APPn and COM markers
 531.567 +   * can be saved in a list for examination by the application.
 531.568 +   */
 531.569 +  jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
 531.570 +
 531.571 +  /* Remaining fields are known throughout decompressor, but generally
 531.572 +   * should not be touched by a surrounding application.
 531.573 +   */
 531.574 +
 531.575 +  /*
 531.576 +   * These fields are computed during decompression startup
 531.577 +   */
 531.578 +  int max_h_samp_factor;	/* largest h_samp_factor */
 531.579 +  int max_v_samp_factor;	/* largest v_samp_factor */
 531.580 +
 531.581 +  int min_DCT_scaled_size;	/* smallest DCT_scaled_size of any component */
 531.582 +
 531.583 +  JDIMENSION total_iMCU_rows;	/* # of iMCU rows in image */
 531.584 +  /* The coefficient controller's input and output progress is measured in
 531.585 +   * units of "iMCU" (interleaved MCU) rows.  These are the same as MCU rows
 531.586 +   * in fully interleaved JPEG scans, but are used whether the scan is
 531.587 +   * interleaved or not.  We define an iMCU row as v_samp_factor DCT block
 531.588 +   * rows of each component.  Therefore, the IDCT output contains
 531.589 +   * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.
 531.590 +   */
 531.591 +
 531.592 +  JSAMPLE * sample_range_limit; /* table for fast range-limiting */
 531.593 +
 531.594 +  /*
 531.595 +   * These fields are valid during any one scan.
 531.596 +   * They describe the components and MCUs actually appearing in the scan.
 531.597 +   * Note that the decompressor output side must not use these fields.
 531.598 +   */
 531.599 +  int comps_in_scan;		/* # of JPEG components in this scan */
 531.600 +  jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
 531.601 +  /* *cur_comp_info[i] describes component that appears i'th in SOS */
 531.602 +
 531.603 +  JDIMENSION MCUs_per_row;	/* # of MCUs across the image */
 531.604 +  JDIMENSION MCU_rows_in_scan;	/* # of MCU rows in the image */
 531.605 +
 531.606 +  int blocks_in_MCU;		/* # of DCT blocks per MCU */
 531.607 +  int MCU_membership[D_MAX_BLOCKS_IN_MCU];
 531.608 +  /* MCU_membership[i] is index in cur_comp_info of component owning */
 531.609 +  /* i'th block in an MCU */
 531.610 +
 531.611 +  int Ss, Se, Ah, Al;		/* progressive JPEG parameters for scan */
 531.612 +
 531.613 +  /* This field is shared between entropy decoder and marker parser.
 531.614 +   * It is either zero or the code of a JPEG marker that has been
 531.615 +   * read from the data source, but has not yet been processed.
 531.616 +   */
 531.617 +  int unread_marker;
 531.618 +
 531.619 +  /*
 531.620 +   * Links to decompression subobjects (methods, private variables of modules)
 531.621 +   */
 531.622 +  struct jpeg_decomp_master * master;
 531.623 +  struct jpeg_d_main_controller * main;
 531.624 +  struct jpeg_d_coef_controller * coef;
 531.625 +  struct jpeg_d_post_controller * post;
 531.626 +  struct jpeg_input_controller * inputctl;
 531.627 +  struct jpeg_marker_reader * marker;
 531.628 +  struct jpeg_entropy_decoder * entropy;
 531.629 +  struct jpeg_inverse_dct * idct;
 531.630 +  struct jpeg_upsampler * upsample;
 531.631 +  struct jpeg_color_deconverter * cconvert;
 531.632 +  struct jpeg_color_quantizer * cquantize;
 531.633 +};
 531.634 +
 531.635 +
 531.636 +/* "Object" declarations for JPEG modules that may be supplied or called
 531.637 + * directly by the surrounding application.
 531.638 + * As with all objects in the JPEG library, these structs only define the
 531.639 + * publicly visible methods and state variables of a module.  Additional
 531.640 + * private fields may exist after the public ones.
 531.641 + */
 531.642 +
 531.643 +
 531.644 +/* Error handler object */
 531.645 +
 531.646 +struct jpeg_error_mgr {
 531.647 +  /* Error exit handler: does not return to caller */
 531.648 +  JMETHOD(void, error_exit, (j_common_ptr cinfo));
 531.649 +  /* Conditionally emit a trace or warning message */
 531.650 +  JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
 531.651 +  /* Routine that actually outputs a trace or error message */
 531.652 +  JMETHOD(void, output_message, (j_common_ptr cinfo));
 531.653 +  /* Format a message string for the most recent JPEG error or message */
 531.654 +  JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer));
 531.655 +#define JMSG_LENGTH_MAX  200	/* recommended size of format_message buffer */
 531.656 +  /* Reset error state variables at start of a new image */
 531.657 +  JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo));
 531.658 +  
 531.659 +  /* The message ID code and any parameters are saved here.
 531.660 +   * A message can have one string parameter or up to 8 int parameters.
 531.661 +   */
 531.662 +  int msg_code;
 531.663 +#define JMSG_STR_PARM_MAX  80
 531.664 +  union {
 531.665 +    int i[8];
 531.666 +    char s[JMSG_STR_PARM_MAX];
 531.667 +  } msg_parm;
 531.668 +  
 531.669 +  /* Standard state variables for error facility */
 531.670 +  
 531.671 +  int trace_level;		/* max msg_level that will be displayed */
 531.672 +  
 531.673 +  /* For recoverable corrupt-data errors, we emit a warning message,
 531.674 +   * but keep going unless emit_message chooses to abort.  emit_message
 531.675 +   * should count warnings in num_warnings.  The surrounding application
 531.676 +   * can check for bad data by seeing if num_warnings is nonzero at the
 531.677 +   * end of processing.
 531.678 +   */
 531.679 +  long num_warnings;		/* number of corrupt-data warnings */
 531.680 +
 531.681 +  /* These fields point to the table(s) of error message strings.
 531.682 +   * An application can change the table pointer to switch to a different
 531.683 +   * message list (typically, to change the language in which errors are
 531.684 +   * reported).  Some applications may wish to add additional error codes
 531.685 +   * that will be handled by the JPEG library error mechanism; the second
 531.686 +   * table pointer is used for this purpose.
 531.687 +   *
 531.688 +   * First table includes all errors generated by JPEG library itself.
 531.689 +   * Error code 0 is reserved for a "no such error string" message.
 531.690 +   */
 531.691 +  const char * const * jpeg_message_table; /* Library errors */
 531.692 +  int last_jpeg_message;    /* Table contains strings 0..last_jpeg_message */
 531.693 +  /* Second table can be added by application (see cjpeg/djpeg for example).
 531.694 +   * It contains strings numbered first_addon_message..last_addon_message.
 531.695 +   */
 531.696 +  const char * const * addon_message_table; /* Non-library errors */
 531.697 +  int first_addon_message;	/* code for first string in addon table */
 531.698 +  int last_addon_message;	/* code for last string in addon table */
 531.699 +};
 531.700 +
 531.701 +
 531.702 +/* Progress monitor object */
 531.703 +
 531.704 +struct jpeg_progress_mgr {
 531.705 +  JMETHOD(void, progress_monitor, (j_common_ptr cinfo));
 531.706 +
 531.707 +  long pass_counter;		/* work units completed in this pass */
 531.708 +  long pass_limit;		/* total number of work units in this pass */
 531.709 +  int completed_passes;		/* passes completed so far */
 531.710 +  int total_passes;		/* total number of passes expected */
 531.711 +};
 531.712 +
 531.713 +
 531.714 +/* Data destination object for compression */
 531.715 +
 531.716 +struct jpeg_destination_mgr {
 531.717 +  JOCTET * next_output_byte;	/* => next byte to write in buffer */
 531.718 +  size_t free_in_buffer;	/* # of byte spaces remaining in buffer */
 531.719 +
 531.720 +  JMETHOD(void, init_destination, (j_compress_ptr cinfo));
 531.721 +  JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo));
 531.722 +  JMETHOD(void, term_destination, (j_compress_ptr cinfo));
 531.723 +};
 531.724 +
 531.725 +
 531.726 +/* Data source object for decompression */
 531.727 +
 531.728 +struct jpeg_source_mgr {
 531.729 +  const JOCTET * next_input_byte; /* => next byte to read from buffer */
 531.730 +  size_t bytes_in_buffer;	/* # of bytes remaining in buffer */
 531.731 +
 531.732 +  JMETHOD(void, init_source, (j_decompress_ptr cinfo));
 531.733 +  JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo));
 531.734 +  JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes));
 531.735 +  JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
 531.736 +  JMETHOD(void, term_source, (j_decompress_ptr cinfo));
 531.737 +};
 531.738 +
 531.739 +
 531.740 +/* Memory manager object.
 531.741 + * Allocates "small" objects (a few K total), "large" objects (tens of K),
 531.742 + * and "really big" objects (virtual arrays with backing store if needed).
 531.743 + * The memory manager does not allow individual objects to be freed; rather,
 531.744 + * each created object is assigned to a pool, and whole pools can be freed
 531.745 + * at once.  This is faster and more convenient than remembering exactly what
 531.746 + * to free, especially where malloc()/free() are not too speedy.
 531.747 + * NB: alloc routines never return NULL.  They exit to error_exit if not
 531.748 + * successful.
 531.749 + */
 531.750 +
 531.751 +#define JPOOL_PERMANENT	0	/* lasts until master record is destroyed */
 531.752 +#define JPOOL_IMAGE	1	/* lasts until done with image/datastream */
 531.753 +#define JPOOL_NUMPOOLS	2
 531.754 +
 531.755 +typedef struct jvirt_sarray_control * jvirt_sarray_ptr;
 531.756 +typedef struct jvirt_barray_control * jvirt_barray_ptr;
 531.757 +
 531.758 +
 531.759 +struct jpeg_memory_mgr {
 531.760 +  /* Method pointers */
 531.761 +  JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id,
 531.762 +				size_t sizeofobject));
 531.763 +  JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id,
 531.764 +				     size_t sizeofobject));
 531.765 +  JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id,
 531.766 +				     JDIMENSION samplesperrow,
 531.767 +				     JDIMENSION numrows));
 531.768 +  JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id,
 531.769 +				      JDIMENSION blocksperrow,
 531.770 +				      JDIMENSION numrows));
 531.771 +  JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo,
 531.772 +						  int pool_id,
 531.773 +						  boolean pre_zero,
 531.774 +						  JDIMENSION samplesperrow,
 531.775 +						  JDIMENSION numrows,
 531.776 +						  JDIMENSION maxaccess));
 531.777 +  JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
 531.778 +						  int pool_id,
 531.779 +						  boolean pre_zero,
 531.780 +						  JDIMENSION blocksperrow,
 531.781 +						  JDIMENSION numrows,
 531.782 +						  JDIMENSION maxaccess));
 531.783 +  JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo));
 531.784 +  JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo,
 531.785 +					   jvirt_sarray_ptr ptr,
 531.786 +					   JDIMENSION start_row,
 531.787 +					   JDIMENSION num_rows,
 531.788 +					   boolean writable));
 531.789 +  JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo,
 531.790 +					    jvirt_barray_ptr ptr,
 531.791 +					    JDIMENSION start_row,
 531.792 +					    JDIMENSION num_rows,
 531.793 +					    boolean writable));
 531.794 +  JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id));
 531.795 +  JMETHOD(void, self_destruct, (j_common_ptr cinfo));
 531.796 +
 531.797 +  /* Limit on memory allocation for this JPEG object.  (Note that this is
 531.798 +   * merely advisory, not a guaranteed maximum; it only affects the space
 531.799 +   * used for virtual-array buffers.)  May be changed by outer application
 531.800 +   * after creating the JPEG object.
 531.801 +   */
 531.802 +  long max_memory_to_use;
 531.803 +
 531.804 +  /* Maximum allocation request accepted by alloc_large. */
 531.805 +  long max_alloc_chunk;
 531.806 +};
 531.807 +
 531.808 +
 531.809 +/* Routine signature for application-supplied marker processing methods.
 531.810 + * Need not pass marker code since it is stored in cinfo->unread_marker.
 531.811 + */
 531.812 +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
 531.813 +
 531.814 +
 531.815 +/* Declarations for routines called by application.
 531.816 + * The JPP macro hides prototype parameters from compilers that can't cope.
 531.817 + * Note JPP requires double parentheses.
 531.818 + */
 531.819 +
 531.820 +#ifdef HAVE_PROTOTYPES
 531.821 +#define JPP(arglist)	arglist
 531.822 +#else
 531.823 +#define JPP(arglist)	()
 531.824 +#endif
 531.825 +
 531.826 +
 531.827 +/* Short forms of external names for systems with brain-damaged linkers.
 531.828 + * We shorten external names to be unique in the first six letters, which
 531.829 + * is good enough for all known systems.
 531.830 + * (If your compiler itself needs names to be unique in less than 15 
 531.831 + * characters, you are out of luck.  Get a better compiler.)
 531.832 + */
 531.833 +
 531.834 +#ifdef NEED_SHORT_EXTERNAL_NAMES
 531.835 +#define jpeg_std_error		jStdError
 531.836 +#define jpeg_CreateCompress	jCreaCompress
 531.837 +#define jpeg_CreateDecompress	jCreaDecompress
 531.838 +#define jpeg_destroy_compress	jDestCompress
 531.839 +#define jpeg_destroy_decompress	jDestDecompress
 531.840 +#define jpeg_stdio_dest		jStdDest
 531.841 +#define jpeg_stdio_src		jStdSrc
 531.842 +#define jpeg_set_defaults	jSetDefaults
 531.843 +#define jpeg_set_colorspace	jSetColorspace
 531.844 +#define jpeg_default_colorspace	jDefColorspace
 531.845 +#define jpeg_set_quality	jSetQuality
 531.846 +#define jpeg_set_linear_quality	jSetLQuality
 531.847 +#define jpeg_add_quant_table	jAddQuantTable
 531.848 +#define jpeg_quality_scaling	jQualityScaling
 531.849 +#define jpeg_simple_progression	jSimProgress
 531.850 +#define jpeg_suppress_tables	jSuppressTables
 531.851 +#define jpeg_alloc_quant_table	jAlcQTable
 531.852 +#define jpeg_alloc_huff_table	jAlcHTable
 531.853 +#define jpeg_start_compress	jStrtCompress
 531.854 +#define jpeg_write_scanlines	jWrtScanlines
 531.855 +#define jpeg_finish_compress	jFinCompress
 531.856 +#define jpeg_write_raw_data	jWrtRawData
 531.857 +#define jpeg_write_marker	jWrtMarker
 531.858 +#define jpeg_write_m_header	jWrtMHeader
 531.859 +#define jpeg_write_m_byte	jWrtMByte
 531.860 +#define jpeg_write_tables	jWrtTables
 531.861 +#define jpeg_read_header	jReadHeader
 531.862 +#define jpeg_start_decompress	jStrtDecompress
 531.863 +#define jpeg_read_scanlines	jReadScanlines
 531.864 +#define jpeg_finish_decompress	jFinDecompress
 531.865 +#define jpeg_read_raw_data	jReadRawData
 531.866 +#define jpeg_has_multiple_scans	jHasMultScn
 531.867 +#define jpeg_start_output	jStrtOutput
 531.868 +#define jpeg_finish_output	jFinOutput
 531.869 +#define jpeg_input_complete	jInComplete
 531.870 +#define jpeg_new_colormap	jNewCMap
 531.871 +#define jpeg_consume_input	jConsumeInput
 531.872 +#define jpeg_calc_output_dimensions	jCalcDimensions
 531.873 +#define jpeg_save_markers	jSaveMarkers
 531.874 +#define jpeg_set_marker_processor	jSetMarker
 531.875 +#define jpeg_read_coefficients	jReadCoefs
 531.876 +#define jpeg_write_coefficients	jWrtCoefs
 531.877 +#define jpeg_copy_critical_parameters	jCopyCrit
 531.878 +#define jpeg_abort_compress	jAbrtCompress
 531.879 +#define jpeg_abort_decompress	jAbrtDecompress
 531.880 +#define jpeg_abort		jAbort
 531.881 +#define jpeg_destroy		jDestroy
 531.882 +#define jpeg_resync_to_restart	jResyncRestart
 531.883 +#endif /* NEED_SHORT_EXTERNAL_NAMES */
 531.884 +
 531.885 +
 531.886 +/* Default error-management setup */
 531.887 +EXTERN(struct jpeg_error_mgr *) jpeg_std_error
 531.888 +	JPP((struct jpeg_error_mgr * err));
 531.889 +
 531.890 +/* Initialization of JPEG compression objects.
 531.891 + * jpeg_create_compress() and jpeg_create_decompress() are the exported
 531.892 + * names that applications should call.  These expand to calls on
 531.893 + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information
 531.894 + * passed for version mismatch checking.
 531.895 + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
 531.896 + */
 531.897 +#define jpeg_create_compress(cinfo) \
 531.898 +    jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
 531.899 +			(size_t) sizeof(struct jpeg_compress_struct))
 531.900 +#define jpeg_create_decompress(cinfo) \
 531.901 +    jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
 531.902 +			  (size_t) sizeof(struct jpeg_decompress_struct))
 531.903 +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo,
 531.904 +				      int version, size_t structsize));
 531.905 +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo,
 531.906 +					int version, size_t structsize));
 531.907 +/* Destruction of JPEG compression objects */
 531.908 +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo));
 531.909 +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
 531.910 +
 531.911 +/* Standard data source and destination managers: stdio streams. */
 531.912 +/* Caller is responsible for opening the file before and closing after. */
 531.913 +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
 531.914 +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
 531.915 +
 531.916 +/* Default parameter setup for compression */
 531.917 +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
 531.918 +/* Compression parameter setup aids */
 531.919 +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo,
 531.920 +				      J_COLOR_SPACE colorspace));
 531.921 +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo));
 531.922 +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
 531.923 +				   boolean force_baseline));
 531.924 +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
 531.925 +					  int scale_factor,
 531.926 +					  boolean force_baseline));
 531.927 +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
 531.928 +				       const unsigned int *basic_table,
 531.929 +				       int scale_factor,
 531.930 +				       boolean force_baseline));
 531.931 +EXTERN(int) jpeg_quality_scaling JPP((int quality));
 531.932 +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo));
 531.933 +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
 531.934 +				       boolean suppress));
 531.935 +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
 531.936 +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
 531.937 +
 531.938 +/* Main entry points for compression */
 531.939 +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
 531.940 +				      boolean write_all_tables));
 531.941 +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
 531.942 +					     JSAMPARRAY scanlines,
 531.943 +					     JDIMENSION num_lines));
 531.944 +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
 531.945 +
 531.946 +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
 531.947 +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
 531.948 +					    JSAMPIMAGE data,
 531.949 +					    JDIMENSION num_lines));
 531.950 +
 531.951 +/* Write a special marker.  See libjpeg.doc concerning safe usage. */
 531.952 +EXTERN(void) jpeg_write_marker
 531.953 +	JPP((j_compress_ptr cinfo, int marker,
 531.954 +	     const JOCTET * dataptr, unsigned int datalen));
 531.955 +/* Same, but piecemeal. */
 531.956 +EXTERN(void) jpeg_write_m_header
 531.957 +	JPP((j_compress_ptr cinfo, int marker, unsigned int datalen));
 531.958 +EXTERN(void) jpeg_write_m_byte
 531.959 +	JPP((j_compress_ptr cinfo, int val));
 531.960 +
 531.961 +/* Alternate compression function: just write an abbreviated table file */
 531.962 +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
 531.963 +
 531.964 +/* Decompression startup: read start of JPEG datastream to see what's there */
 531.965 +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
 531.966 +				  boolean require_image));
 531.967 +/* Return value is one of: */
 531.968 +#define JPEG_SUSPENDED		0 /* Suspended due to lack of input data */
 531.969 +#define JPEG_HEADER_OK		1 /* Found valid image datastream */
 531.970 +#define JPEG_HEADER_TABLES_ONLY	2 /* Found valid table-specs-only datastream */
 531.971 +/* If you pass require_image = TRUE (normal case), you need not check for
 531.972 + * a TABLES_ONLY return code; an abbreviated file will cause an error exit.
 531.973 + * JPEG_SUSPENDED is only possible if you use a data source module that can
 531.974 + * give a suspension return (the stdio source module doesn't).
 531.975 + */
 531.976 +
 531.977 +/* Main entry points for decompression */
 531.978 +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
 531.979 +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
 531.980 +					    JSAMPARRAY scanlines,
 531.981 +					    JDIMENSION max_lines));
 531.982 +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
 531.983 +
 531.984 +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
 531.985 +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
 531.986 +					   JSAMPIMAGE data,
 531.987 +					   JDIMENSION max_lines));
 531.988 +
 531.989 +/* Additional entry points for buffered-image mode. */
 531.990 +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
 531.991 +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
 531.992 +				       int scan_number));
 531.993 +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
 531.994 +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
 531.995 +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo));
 531.996 +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
 531.997 +/* Return value is one of: */
 531.998 +/* #define JPEG_SUSPENDED	0    Suspended due to lack of input data */
 531.999 +#define JPEG_REACHED_SOS	1 /* Reached start of new scan */
531.1000 +#define JPEG_REACHED_EOI	2 /* Reached end of image */
531.1001 +#define JPEG_ROW_COMPLETED	3 /* Completed one iMCU row */
531.1002 +#define JPEG_SCAN_COMPLETED	4 /* Completed last iMCU row of a scan */
531.1003 +
531.1004 +/* Precalculate output dimensions for current decompression parameters. */
531.1005 +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
531.1006 +
531.1007 +/* Control saving of COM and APPn markers into marker_list. */
531.1008 +EXTERN(void) jpeg_save_markers
531.1009 +	JPP((j_decompress_ptr cinfo, int marker_code,
531.1010 +	     unsigned int length_limit));
531.1011 +
531.1012 +/* Install a special processing method for COM or APPn markers. */
531.1013 +EXTERN(void) jpeg_set_marker_processor
531.1014 +	JPP((j_decompress_ptr cinfo, int marker_code,
531.1015 +	     jpeg_marker_parser_method routine));
531.1016 +
531.1017 +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */
531.1018 +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo));
531.1019 +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo,
531.1020 +					  jvirt_barray_ptr * coef_arrays));
531.1021 +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo,
531.1022 +						j_compress_ptr dstinfo));
531.1023 +
531.1024 +/* If you choose to abort compression or decompression before completing
531.1025 + * jpeg_finish_(de)compress, then you need to clean up to release memory,
531.1026 + * temporary files, etc.  You can just call jpeg_destroy_(de)compress
531.1027 + * if you're done with the JPEG object, but if you want to clean it up and
531.1028 + * reuse it, call this:
531.1029 + */
531.1030 +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo));
531.1031 +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo));
531.1032 +
531.1033 +/* Generic versions of jpeg_abort and jpeg_destroy that work on either
531.1034 + * flavor of JPEG object.  These may be more convenient in some places.
531.1035 + */
531.1036 +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
531.1037 +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
531.1038 +
531.1039 +/* Default restart-marker-resync procedure for use by data source modules */
531.1040 +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
531.1041 +					    int desired));
531.1042 +
531.1043 +
531.1044 +/* These marker codes are exported since applications and data source modules
531.1045 + * are likely to want to use them.
531.1046 + */
531.1047 +
531.1048 +#define JPEG_RST0	0xD0	/* RST0 marker code */
531.1049 +#define JPEG_EOI	0xD9	/* EOI marker code */
531.1050 +#define JPEG_APP0	0xE0	/* APP0 marker code */
531.1051 +#define JPEG_COM	0xFE	/* COM marker code */
531.1052 +
531.1053 +
531.1054 +/* If we have a brain-damaged compiler that emits warnings (or worse, errors)
531.1055 + * for structure definitions that are never filled in, keep it quiet by
531.1056 + * supplying dummy definitions for the various substructures.
531.1057 + */
531.1058 +
531.1059 +#ifdef INCOMPLETE_TYPES_BROKEN
531.1060 +#ifndef JPEG_INTERNALS		/* will be defined in jpegint.h */
531.1061 +struct jvirt_sarray_control { long dummy; };
531.1062 +struct jvirt_barray_control { long dummy; };
531.1063 +struct jpeg_comp_master { long dummy; };
531.1064 +struct jpeg_c_main_controller { long dummy; };
531.1065 +struct jpeg_c_prep_controller { long dummy; };
531.1066 +struct jpeg_c_coef_controller { long dummy; };
531.1067 +struct jpeg_marker_writer { long dummy; };
531.1068 +struct jpeg_color_converter { long dummy; };
531.1069 +struct jpeg_downsampler { long dummy; };
531.1070 +struct jpeg_forward_dct { long dummy; };
531.1071 +struct jpeg_entropy_encoder { long dummy; };
531.1072 +struct jpeg_decomp_master { long dummy; };
531.1073 +struct jpeg_d_main_controller { long dummy; };
531.1074 +struct jpeg_d_coef_controller { long dummy; };
531.1075 +struct jpeg_d_post_controller { long dummy; };
531.1076 +struct jpeg_input_controller { long dummy; };
531.1077 +struct jpeg_marker_reader { long dummy; };
531.1078 +struct jpeg_entropy_decoder { long dummy; };
531.1079 +struct jpeg_inverse_dct { long dummy; };
531.1080 +struct jpeg_upsampler { long dummy; };
531.1081 +struct jpeg_color_deconverter { long dummy; };
531.1082 +struct jpeg_color_quantizer { long dummy; };
531.1083 +#endif /* JPEG_INTERNALS */
531.1084 +#endif /* INCOMPLETE_TYPES_BROKEN */
531.1085 +
531.1086 +
531.1087 +/*
531.1088 + * The JPEG library modules define JPEG_INTERNALS before including this file.
531.1089 + * The internal structure declarations are read only when that is true.
531.1090 + * Applications using the library should not include jpegint.h, but may wish
531.1091 + * to include jerror.h.
531.1092 + */
531.1093 +
531.1094 +#ifdef JPEG_INTERNALS
531.1095 +#include "jpegint.h"		/* fetch private declarations */
531.1096 +#include "jerror.h"		/* fetch error codes too */
531.1097 +#endif
531.1098 +
531.1099 +#endif /* JPEGLIB_H */
   532.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   532.2 +++ b/libs/libjpeg/jquant1.c	Sat Feb 01 19:58:19 2014 +0200
   532.3 @@ -0,0 +1,856 @@
   532.4 +/*
   532.5 + * jquant1.c
   532.6 + *
   532.7 + * Copyright (C) 1991-1996, Thomas G. Lane.
   532.8 + * This file is part of the Independent JPEG Group's software.
   532.9 + * For conditions of distribution and use, see the accompanying README file.
  532.10 + *
  532.11 + * This file contains 1-pass color quantization (color mapping) routines.
  532.12 + * These routines provide mapping to a fixed color map using equally spaced
  532.13 + * color values.  Optional Floyd-Steinberg or ordered dithering is available.
  532.14 + */
  532.15 +
  532.16 +#define JPEG_INTERNALS
  532.17 +#include "jinclude.h"
  532.18 +#include "jpeglib.h"
  532.19 +
  532.20 +#ifdef QUANT_1PASS_SUPPORTED
  532.21 +
  532.22 +
  532.23 +/*
  532.24 + * The main purpose of 1-pass quantization is to provide a fast, if not very
  532.25 + * high quality, colormapped output capability.  A 2-pass quantizer usually
  532.26 + * gives better visual quality; however, for quantized grayscale output this
  532.27 + * quantizer is perfectly adequate.  Dithering is highly recommended with this
  532.28 + * quantizer, though you can turn it off if you really want to.
  532.29 + *
  532.30 + * In 1-pass quantization the colormap must be chosen in advance of seeing the
  532.31 + * image.  We use a map consisting of all combinations of Ncolors[i] color
  532.32 + * values for the i'th component.  The Ncolors[] values are chosen so that
  532.33 + * their product, the total number of colors, is no more than that requested.
  532.34 + * (In most cases, the product will be somewhat less.)
  532.35 + *
  532.36 + * Since the colormap is orthogonal, the representative value for each color
  532.37 + * component can be determined without considering the other components;
  532.38 + * then these indexes can be combined into a colormap index by a standard
  532.39 + * N-dimensional-array-subscript calculation.  Most of the arithmetic involved
  532.40 + * can be precalculated and stored in the lookup table colorindex[].
  532.41 + * colorindex[i][j] maps pixel value j in component i to the nearest
  532.42 + * representative value (grid plane) for that component; this index is
  532.43 + * multiplied by the array stride for component i, so that the
  532.44 + * index of the colormap entry closest to a given pixel value is just
  532.45 + *    sum( colorindex[component-number][pixel-component-value] )
  532.46 + * Aside from being fast, this scheme allows for variable spacing between
  532.47 + * representative values with no additional lookup cost.
  532.48 + *
  532.49 + * If gamma correction has been applied in color conversion, it might be wise
  532.50 + * to adjust the color grid spacing so that the representative colors are
  532.51 + * equidistant in linear space.  At this writing, gamma correction is not
  532.52 + * implemented by jdcolor, so nothing is done here.
  532.53 + */
  532.54 +
  532.55 +
  532.56 +/* Declarations for ordered dithering.
  532.57 + *
  532.58 + * We use a standard 16x16 ordered dither array.  The basic concept of ordered
  532.59 + * dithering is described in many references, for instance Dale Schumacher's
  532.60 + * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991).
  532.61 + * In place of Schumacher's comparisons against a "threshold" value, we add a
  532.62 + * "dither" value to the input pixel and then round the result to the nearest
  532.63 + * output value.  The dither value is equivalent to (0.5 - threshold) times
  532.64 + * the distance between output values.  For ordered dithering, we assume that
  532.65 + * the output colors are equally spaced; if not, results will probably be
  532.66 + * worse, since the dither may be too much or too little at a given point.
  532.67 + *
  532.68 + * The normal calculation would be to form pixel value + dither, range-limit
  532.69 + * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual.
  532.70 + * We can skip the separate range-limiting step by extending the colorindex
  532.71 + * table in both directions.
  532.72 + */
  532.73 +
  532.74 +#define ODITHER_SIZE  16	/* dimension of dither matrix */
  532.75 +/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */
  532.76 +#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE)	/* # cells in matrix */
  532.77 +#define ODITHER_MASK  (ODITHER_SIZE-1) /* mask for wrapping around counters */
  532.78 +
  532.79 +typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE];
  532.80 +typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE];
  532.81 +
  532.82 +static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = {
  532.83 +  /* Bayer's order-4 dither array.  Generated by the code given in
  532.84 +   * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I.
  532.85 +   * The values in this array must range from 0 to ODITHER_CELLS-1.
  532.86 +   */
  532.87 +  {   0,192, 48,240, 12,204, 60,252,  3,195, 51,243, 15,207, 63,255 },
  532.88 +  { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
  532.89 +  {  32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
  532.90 +  { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
  532.91 +  {   8,200, 56,248,  4,196, 52,244, 11,203, 59,251,  7,199, 55,247 },
  532.92 +  { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
  532.93 +  {  40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
  532.94 +  { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
  532.95 +  {   2,194, 50,242, 14,206, 62,254,  1,193, 49,241, 13,205, 61,253 },
  532.96 +  { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
  532.97 +  {  34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
  532.98 +  { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
  532.99 +  {  10,202, 58,250,  6,198, 54,246,  9,201, 57,249,  5,197, 53,245 },
 532.100 +  { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
 532.101 +  {  42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
 532.102 +  { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
 532.103 +};
 532.104 +
 532.105 +
 532.106 +/* Declarations for Floyd-Steinberg dithering.
 532.107 + *
 532.108 + * Errors are accumulated into the array fserrors[], at a resolution of
 532.109 + * 1/16th of a pixel count.  The error at a given pixel is propagated
 532.110 + * to its not-yet-processed neighbors using the standard F-S fractions,
 532.111 + *		...	(here)	7/16
 532.112 + *		3/16	5/16	1/16
 532.113 + * We work left-to-right on even rows, right-to-left on odd rows.
 532.114 + *
 532.115 + * We can get away with a single array (holding one row's worth of errors)
 532.116 + * by using it to store the current row's errors at pixel columns not yet
 532.117 + * processed, but the next row's errors at columns already processed.  We
 532.118 + * need only a few extra variables to hold the errors immediately around the
 532.119 + * current column.  (If we are lucky, those variables are in registers, but
 532.120 + * even if not, they're probably cheaper to access than array elements are.)
 532.121 + *
 532.122 + * The fserrors[] array is indexed [component#][position].
 532.123 + * We provide (#columns + 2) entries per component; the extra entry at each
 532.124 + * end saves us from special-casing the first and last pixels.
 532.125 + *
 532.126 + * Note: on a wide image, we might not have enough room in a PC's near data
 532.127 + * segment to hold the error array; so it is allocated with alloc_large.
 532.128 + */
 532.129 +
 532.130 +#if BITS_IN_JSAMPLE == 8
 532.131 +typedef INT16 FSERROR;		/* 16 bits should be enough */
 532.132 +typedef int LOCFSERROR;		/* use 'int' for calculation temps */
 532.133 +#else
 532.134 +typedef INT32 FSERROR;		/* may need more than 16 bits */
 532.135 +typedef INT32 LOCFSERROR;	/* be sure calculation temps are big enough */
 532.136 +#endif
 532.137 +
 532.138 +typedef FSERROR FAR *FSERRPTR;	/* pointer to error array (in FAR storage!) */
 532.139 +
 532.140 +
 532.141 +/* Private subobject */
 532.142 +
 532.143 +#define MAX_Q_COMPS 4		/* max components I can handle */
 532.144 +
 532.145 +typedef struct {
 532.146 +  struct jpeg_color_quantizer pub; /* public fields */
 532.147 +
 532.148 +  /* Initially allocated colormap is saved here */
 532.149 +  JSAMPARRAY sv_colormap;	/* The color map as a 2-D pixel array */
 532.150 +  int sv_actual;		/* number of entries in use */
 532.151 +
 532.152 +  JSAMPARRAY colorindex;	/* Precomputed mapping for speed */
 532.153 +  /* colorindex[i][j] = index of color closest to pixel value j in component i,
 532.154 +   * premultiplied as described above.  Since colormap indexes must fit into
 532.155 +   * JSAMPLEs, the entries of this array will too.
 532.156 +   */
 532.157 +  boolean is_padded;		/* is the colorindex padded for odither? */
 532.158 +
 532.159 +  int Ncolors[MAX_Q_COMPS];	/* # of values alloced to each component */
 532.160 +
 532.161 +  /* Variables for ordered dithering */
 532.162 +  int row_index;		/* cur row's vertical index in dither matrix */
 532.163 +  ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */
 532.164 +
 532.165 +  /* Variables for Floyd-Steinberg dithering */
 532.166 +  FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */
 532.167 +  boolean on_odd_row;		/* flag to remember which row we are on */
 532.168 +} my_cquantizer;
 532.169 +
 532.170 +typedef my_cquantizer * my_cquantize_ptr;
 532.171 +
 532.172 +
 532.173 +/*
 532.174 + * Policy-making subroutines for create_colormap and create_colorindex.
 532.175 + * These routines determine the colormap to be used.  The rest of the module
 532.176 + * only assumes that the colormap is orthogonal.
 532.177 + *
 532.178 + *  * select_ncolors decides how to divvy up the available colors
 532.179 + *    among the components.
 532.180 + *  * output_value defines the set of representative values for a component.
 532.181 + *  * largest_input_value defines the mapping from input values to
 532.182 + *    representative values for a component.
 532.183 + * Note that the latter two routines may impose different policies for
 532.184 + * different components, though this is not currently done.
 532.185 + */
 532.186 +
 532.187 +
 532.188 +LOCAL(int)
 532.189 +select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
 532.190 +/* Determine allocation of desired colors to components, */
 532.191 +/* and fill in Ncolors[] array to indicate choice. */
 532.192 +/* Return value is total number of colors (product of Ncolors[] values). */
 532.193 +{
 532.194 +  int nc = cinfo->out_color_components; /* number of color components */
 532.195 +  int max_colors = cinfo->desired_number_of_colors;
 532.196 +  int total_colors, iroot, i, j;
 532.197 +  boolean changed;
 532.198 +  long temp;
 532.199 +  static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
 532.200 +
 532.201 +  /* We can allocate at least the nc'th root of max_colors per component. */
 532.202 +  /* Compute floor(nc'th root of max_colors). */
 532.203 +  iroot = 1;
 532.204 +  do {
 532.205 +    iroot++;
 532.206 +    temp = iroot;		/* set temp = iroot ** nc */
 532.207 +    for (i = 1; i < nc; i++)
 532.208 +      temp *= iroot;
 532.209 +  } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */
 532.210 +  iroot--;			/* now iroot = floor(root) */
 532.211 +
 532.212 +  /* Must have at least 2 color values per component */
 532.213 +  if (iroot < 2)
 532.214 +    ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp);
 532.215 +
 532.216 +  /* Initialize to iroot color values for each component */
 532.217 +  total_colors = 1;
 532.218 +  for (i = 0; i < nc; i++) {
 532.219 +    Ncolors[i] = iroot;
 532.220 +    total_colors *= iroot;
 532.221 +  }
 532.222 +  /* We may be able to increment the count for one or more components without
 532.223 +   * exceeding max_colors, though we know not all can be incremented.
 532.224 +   * Sometimes, the first component can be incremented more than once!
 532.225 +   * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
 532.226 +   * In RGB colorspace, try to increment G first, then R, then B.
 532.227 +   */
 532.228 +  do {
 532.229 +    changed = FALSE;
 532.230 +    for (i = 0; i < nc; i++) {
 532.231 +      j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i);
 532.232 +      /* calculate new total_colors if Ncolors[j] is incremented */
 532.233 +      temp = total_colors / Ncolors[j];
 532.234 +      temp *= Ncolors[j]+1;	/* done in long arith to avoid oflo */
 532.235 +      if (temp > (long) max_colors)
 532.236 +	break;			/* won't fit, done with this pass */
 532.237 +      Ncolors[j]++;		/* OK, apply the increment */
 532.238 +      total_colors = (int) temp;
 532.239 +      changed = TRUE;
 532.240 +    }
 532.241 +  } while (changed);
 532.242 +
 532.243 +  return total_colors;
 532.244 +}
 532.245 +
 532.246 +
 532.247 +LOCAL(int)
 532.248 +output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
 532.249 +/* Return j'th output value, where j will range from 0 to maxj */
 532.250 +/* The output values must fall in 0..MAXJSAMPLE in increasing order */
 532.251 +{
 532.252 +  /* We always provide values 0 and MAXJSAMPLE for each component;
 532.253 +   * any additional values are equally spaced between these limits.
 532.254 +   * (Forcing the upper and lower values to the limits ensures that
 532.255 +   * dithering can't produce a color outside the selected gamut.)
 532.256 +   */
 532.257 +  return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj);
 532.258 +}
 532.259 +
 532.260 +
 532.261 +LOCAL(int)
 532.262 +largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
 532.263 +/* Return largest input value that should map to j'th output value */
 532.264 +/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
 532.265 +{
 532.266 +  /* Breakpoints are halfway between values returned by output_value */
 532.267 +  return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj));
 532.268 +}
 532.269 +
 532.270 +
 532.271 +/*
 532.272 + * Create the colormap.
 532.273 + */
 532.274 +
 532.275 +LOCAL(void)
 532.276 +create_colormap (j_decompress_ptr cinfo)
 532.277 +{
 532.278 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 532.279 +  JSAMPARRAY colormap;		/* Created colormap */
 532.280 +  int total_colors;		/* Number of distinct output colors */
 532.281 +  int i,j,k, nci, blksize, blkdist, ptr, val;
 532.282 +
 532.283 +  /* Select number of colors for each component */
 532.284 +  total_colors = select_ncolors(cinfo, cquantize->Ncolors);
 532.285 +
 532.286 +  /* Report selected color counts */
 532.287 +  if (cinfo->out_color_components == 3)
 532.288 +    TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS,
 532.289 +	     total_colors, cquantize->Ncolors[0],
 532.290 +	     cquantize->Ncolors[1], cquantize->Ncolors[2]);
 532.291 +  else
 532.292 +    TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors);
 532.293 +
 532.294 +  /* Allocate and fill in the colormap. */
 532.295 +  /* The colors are ordered in the map in standard row-major order, */
 532.296 +  /* i.e. rightmost (highest-indexed) color changes most rapidly. */
 532.297 +
 532.298 +  colormap = (*cinfo->mem->alloc_sarray)
 532.299 +    ((j_common_ptr) cinfo, JPOOL_IMAGE,
 532.300 +     (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components);
 532.301 +
 532.302 +  /* blksize is number of adjacent repeated entries for a component */
 532.303 +  /* blkdist is distance between groups of identical entries for a component */
 532.304 +  blkdist = total_colors;
 532.305 +
 532.306 +  for (i = 0; i < cinfo->out_color_components; i++) {
 532.307 +    /* fill in colormap entries for i'th color component */
 532.308 +    nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
 532.309 +    blksize = blkdist / nci;
 532.310 +    for (j = 0; j < nci; j++) {
 532.311 +      /* Compute j'th output value (out of nci) for component */
 532.312 +      val = output_value(cinfo, i, j, nci-1);
 532.313 +      /* Fill in all colormap entries that have this value of this component */
 532.314 +      for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
 532.315 +	/* fill in blksize entries beginning at ptr */
 532.316 +	for (k = 0; k < blksize; k++)
 532.317 +	  colormap[i][ptr+k] = (JSAMPLE) val;
 532.318 +      }
 532.319 +    }
 532.320 +    blkdist = blksize;		/* blksize of this color is blkdist of next */
 532.321 +  }
 532.322 +
 532.323 +  /* Save the colormap in private storage,
 532.324 +   * where it will survive color quantization mode changes.
 532.325 +   */
 532.326 +  cquantize->sv_colormap = colormap;
 532.327 +  cquantize->sv_actual = total_colors;
 532.328 +}
 532.329 +
 532.330 +
 532.331 +/*
 532.332 + * Create the color index table.
 532.333 + */
 532.334 +
 532.335 +LOCAL(void)
 532.336 +create_colorindex (j_decompress_ptr cinfo)
 532.337 +{
 532.338 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 532.339 +  JSAMPROW indexptr;
 532.340 +  int i,j,k, nci, blksize, val, pad;
 532.341 +
 532.342 +  /* For ordered dither, we pad the color index tables by MAXJSAMPLE in
 532.343 +   * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
 532.344 +   * This is not necessary in the other dithering modes.  However, we
 532.345 +   * flag whether it was done in case user changes dithering mode.
 532.346 +   */
 532.347 +  if (cinfo->dither_mode == JDITHER_ORDERED) {
 532.348 +    pad = MAXJSAMPLE*2;
 532.349 +    cquantize->is_padded = TRUE;
 532.350 +  } else {
 532.351 +    pad = 0;
 532.352 +    cquantize->is_padded = FALSE;
 532.353 +  }
 532.354 +
 532.355 +  cquantize->colorindex = (*cinfo->mem->alloc_sarray)
 532.356 +    ((j_common_ptr) cinfo, JPOOL_IMAGE,
 532.357 +     (JDIMENSION) (MAXJSAMPLE+1 + pad),
 532.358 +     (JDIMENSION) cinfo->out_color_components);
 532.359 +
 532.360 +  /* blksize is number of adjacent repeated entries for a component */
 532.361 +  blksize = cquantize->sv_actual;
 532.362 +
 532.363 +  for (i = 0; i < cinfo->out_color_components; i++) {
 532.364 +    /* fill in colorindex entries for i'th color component */
 532.365 +    nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
 532.366 +    blksize = blksize / nci;
 532.367 +
 532.368 +    /* adjust colorindex pointers to provide padding at negative indexes. */
 532.369 +    if (pad)
 532.370 +      cquantize->colorindex[i] += MAXJSAMPLE;
 532.371 +
 532.372 +    /* in loop, val = index of current output value, */
 532.373 +    /* and k = largest j that maps to current val */
 532.374 +    indexptr = cquantize->colorindex[i];
 532.375 +    val = 0;
 532.376 +    k = largest_input_value(cinfo, i, 0, nci-1);
 532.377 +    for (j = 0; j <= MAXJSAMPLE; j++) {
 532.378 +      while (j > k)		/* advance val if past boundary */
 532.379 +	k = largest_input_value(cinfo, i, ++val, nci-1);
 532.380 +      /* premultiply so that no multiplication needed in main processing */
 532.381 +      indexptr[j] = (JSAMPLE) (val * blksize);
 532.382 +    }
 532.383 +    /* Pad at both ends if necessary */
 532.384 +    if (pad)
 532.385 +      for (j = 1; j <= MAXJSAMPLE; j++) {
 532.386 +	indexptr[-j] = indexptr[0];
 532.387 +	indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE];
 532.388 +      }
 532.389 +  }
 532.390 +}
 532.391 +
 532.392 +
 532.393 +/*
 532.394 + * Create an ordered-dither array for a component having ncolors
 532.395 + * distinct output values.
 532.396 + */
 532.397 +
 532.398 +LOCAL(ODITHER_MATRIX_PTR)
 532.399 +make_odither_array (j_decompress_ptr cinfo, int ncolors)
 532.400 +{
 532.401 +  ODITHER_MATRIX_PTR odither;
 532.402 +  int j,k;
 532.403 +  INT32 num,den;
 532.404 +
 532.405 +  odither = (ODITHER_MATRIX_PTR)
 532.406 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 532.407 +				SIZEOF(ODITHER_MATRIX));
 532.408 +  /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
 532.409 +   * Hence the dither value for the matrix cell with fill order f
 532.410 +   * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
 532.411 +   * On 16-bit-int machine, be careful to avoid overflow.
 532.412 +   */
 532.413 +  den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1));
 532.414 +  for (j = 0; j < ODITHER_SIZE; j++) {
 532.415 +    for (k = 0; k < ODITHER_SIZE; k++) {
 532.416 +      num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k])))
 532.417 +	    * MAXJSAMPLE;
 532.418 +      /* Ensure round towards zero despite C's lack of consistency
 532.419 +       * about rounding negative values in integer division...
 532.420 +       */
 532.421 +      odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den);
 532.422 +    }
 532.423 +  }
 532.424 +  return odither;
 532.425 +}
 532.426 +
 532.427 +
 532.428 +/*
 532.429 + * Create the ordered-dither tables.
 532.430 + * Components having the same number of representative colors may 
 532.431 + * share a dither table.
 532.432 + */
 532.433 +
 532.434 +LOCAL(void)
 532.435 +create_odither_tables (j_decompress_ptr cinfo)
 532.436 +{
 532.437 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 532.438 +  ODITHER_MATRIX_PTR odither;
 532.439 +  int i, j, nci;
 532.440 +
 532.441 +  for (i = 0; i < cinfo->out_color_components; i++) {
 532.442 +    nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
 532.443 +    odither = NULL;		/* search for matching prior component */
 532.444 +    for (j = 0; j < i; j++) {
 532.445 +      if (nci == cquantize->Ncolors[j]) {
 532.446 +	odither = cquantize->odither[j];
 532.447 +	break;
 532.448 +      }
 532.449 +    }
 532.450 +    if (odither == NULL)	/* need a new table? */
 532.451 +      odither = make_odither_array(cinfo, nci);
 532.452 +    cquantize->odither[i] = odither;
 532.453 +  }
 532.454 +}
 532.455 +
 532.456 +
 532.457 +/*
 532.458 + * Map some rows of pixels to the output colormapped representation.
 532.459 + */
 532.460 +
 532.461 +METHODDEF(void)
 532.462 +color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
 532.463 +		JSAMPARRAY output_buf, int num_rows)
 532.464 +/* General case, no dithering */
 532.465 +{
 532.466 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 532.467 +  JSAMPARRAY colorindex = cquantize->colorindex;
 532.468 +  register int pixcode, ci;
 532.469 +  register JSAMPROW ptrin, ptrout;
 532.470 +  int row;
 532.471 +  JDIMENSION col;
 532.472 +  JDIMENSION width = cinfo->output_width;
 532.473 +  register int nc = cinfo->out_color_components;
 532.474 +
 532.475 +  for (row = 0; row < num_rows; row++) {
 532.476 +    ptrin = input_buf[row];
 532.477 +    ptrout = output_buf[row];
 532.478 +    for (col = width; col > 0; col--) {
 532.479 +      pixcode = 0;
 532.480 +      for (ci = 0; ci < nc; ci++) {
 532.481 +	pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]);
 532.482 +      }
 532.483 +      *ptrout++ = (JSAMPLE) pixcode;
 532.484 +    }
 532.485 +  }
 532.486 +}
 532.487 +
 532.488 +
 532.489 +METHODDEF(void)
 532.490 +color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
 532.491 +		 JSAMPARRAY output_buf, int num_rows)
 532.492 +/* Fast path for out_color_components==3, no dithering */
 532.493 +{
 532.494 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 532.495 +  register int pixcode;
 532.496 +  register JSAMPROW ptrin, ptrout;
 532.497 +  JSAMPROW colorindex0 = cquantize->colorindex[0];
 532.498 +  JSAMPROW colorindex1 = cquantize->colorindex[1];
 532.499 +  JSAMPROW colorindex2 = cquantize->colorindex[2];
 532.500 +  int row;
 532.501 +  JDIMENSION col;
 532.502 +  JDIMENSION width = cinfo->output_width;
 532.503 +
 532.504 +  for (row = 0; row < num_rows; row++) {
 532.505 +    ptrin = input_buf[row];
 532.506 +    ptrout = output_buf[row];
 532.507 +    for (col = width; col > 0; col--) {
 532.508 +      pixcode  = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
 532.509 +      pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
 532.510 +      pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
 532.511 +      *ptrout++ = (JSAMPLE) pixcode;
 532.512 +    }
 532.513 +  }
 532.514 +}
 532.515 +
 532.516 +
 532.517 +METHODDEF(void)
 532.518 +quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
 532.519 +		     JSAMPARRAY output_buf, int num_rows)
 532.520 +/* General case, with ordered dithering */
 532.521 +{
 532.522 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 532.523 +  register JSAMPROW input_ptr;
 532.524 +  register JSAMPROW output_ptr;
 532.525 +  JSAMPROW colorindex_ci;
 532.526 +  int * dither;			/* points to active row of dither matrix */
 532.527 +  int row_index, col_index;	/* current indexes into dither matrix */
 532.528 +  int nc = cinfo->out_color_components;
 532.529 +  int ci;
 532.530 +  int row;
 532.531 +  JDIMENSION col;
 532.532 +  JDIMENSION width = cinfo->output_width;
 532.533 +
 532.534 +  for (row = 0; row < num_rows; row++) {
 532.535 +    /* Initialize output values to 0 so can process components separately */
 532.536 +    jzero_far((void FAR *) output_buf[row],
 532.537 +	      (size_t) (width * SIZEOF(JSAMPLE)));
 532.538 +    row_index = cquantize->row_index;
 532.539 +    for (ci = 0; ci < nc; ci++) {
 532.540 +      input_ptr = input_buf[row] + ci;
 532.541 +      output_ptr = output_buf[row];
 532.542 +      colorindex_ci = cquantize->colorindex[ci];
 532.543 +      dither = cquantize->odither[ci][row_index];
 532.544 +      col_index = 0;
 532.545 +
 532.546 +      for (col = width; col > 0; col--) {
 532.547 +	/* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
 532.548 +	 * select output value, accumulate into output code for this pixel.
 532.549 +	 * Range-limiting need not be done explicitly, as we have extended
 532.550 +	 * the colorindex table to produce the right answers for out-of-range
 532.551 +	 * inputs.  The maximum dither is +- MAXJSAMPLE; this sets the
 532.552 +	 * required amount of padding.
 532.553 +	 */
 532.554 +	*output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]];
 532.555 +	input_ptr += nc;
 532.556 +	output_ptr++;
 532.557 +	col_index = (col_index + 1) & ODITHER_MASK;
 532.558 +      }
 532.559 +    }
 532.560 +    /* Advance row index for next row */
 532.561 +    row_index = (row_index + 1) & ODITHER_MASK;
 532.562 +    cquantize->row_index = row_index;
 532.563 +  }
 532.564 +}
 532.565 +
 532.566 +
 532.567 +METHODDEF(void)
 532.568 +quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
 532.569 +		      JSAMPARRAY output_buf, int num_rows)
 532.570 +/* Fast path for out_color_components==3, with ordered dithering */
 532.571 +{
 532.572 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 532.573 +  register int pixcode;
 532.574 +  register JSAMPROW input_ptr;
 532.575 +  register JSAMPROW output_ptr;
 532.576 +  JSAMPROW colorindex0 = cquantize->colorindex[0];
 532.577 +  JSAMPROW colorindex1 = cquantize->colorindex[1];
 532.578 +  JSAMPROW colorindex2 = cquantize->colorindex[2];
 532.579 +  int * dither0;		/* points to active row of dither matrix */
 532.580 +  int * dither1;
 532.581 +  int * dither2;
 532.582 +  int row_index, col_index;	/* current indexes into dither matrix */
 532.583 +  int row;
 532.584 +  JDIMENSION col;
 532.585 +  JDIMENSION width = cinfo->output_width;
 532.586 +
 532.587 +  for (row = 0; row < num_rows; row++) {
 532.588 +    row_index = cquantize->row_index;
 532.589 +    input_ptr = input_buf[row];
 532.590 +    output_ptr = output_buf[row];
 532.591 +    dither0 = cquantize->odither[0][row_index];
 532.592 +    dither1 = cquantize->odither[1][row_index];
 532.593 +    dither2 = cquantize->odither[2][row_index];
 532.594 +    col_index = 0;
 532.595 +
 532.596 +    for (col = width; col > 0; col--) {
 532.597 +      pixcode  = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) +
 532.598 +					dither0[col_index]]);
 532.599 +      pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) +
 532.600 +					dither1[col_index]]);
 532.601 +      pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) +
 532.602 +					dither2[col_index]]);
 532.603 +      *output_ptr++ = (JSAMPLE) pixcode;
 532.604 +      col_index = (col_index + 1) & ODITHER_MASK;
 532.605 +    }
 532.606 +    row_index = (row_index + 1) & ODITHER_MASK;
 532.607 +    cquantize->row_index = row_index;
 532.608 +  }
 532.609 +}
 532.610 +
 532.611 +
 532.612 +METHODDEF(void)
 532.613 +quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
 532.614 +		    JSAMPARRAY output_buf, int num_rows)
 532.615 +/* General case, with Floyd-Steinberg dithering */
 532.616 +{
 532.617 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 532.618 +  register LOCFSERROR cur;	/* current error or pixel value */
 532.619 +  LOCFSERROR belowerr;		/* error for pixel below cur */
 532.620 +  LOCFSERROR bpreverr;		/* error for below/prev col */
 532.621 +  LOCFSERROR bnexterr;		/* error for below/next col */
 532.622 +  LOCFSERROR delta;
 532.623 +  register FSERRPTR errorptr;	/* => fserrors[] at column before current */
 532.624 +  register JSAMPROW input_ptr;
 532.625 +  register JSAMPROW output_ptr;
 532.626 +  JSAMPROW colorindex_ci;
 532.627 +  JSAMPROW colormap_ci;
 532.628 +  int pixcode;
 532.629 +  int nc = cinfo->out_color_components;
 532.630 +  int dir;			/* 1 for left-to-right, -1 for right-to-left */
 532.631 +  int dirnc;			/* dir * nc */
 532.632 +  int ci;
 532.633 +  int row;
 532.634 +  JDIMENSION col;
 532.635 +  JDIMENSION width = cinfo->output_width;
 532.636 +  JSAMPLE *range_limit = cinfo->sample_range_limit;
 532.637 +  SHIFT_TEMPS
 532.638 +
 532.639 +  for (row = 0; row < num_rows; row++) {
 532.640 +    /* Initialize output values to 0 so can process components separately */
 532.641 +    jzero_far((void FAR *) output_buf[row],
 532.642 +	      (size_t) (width * SIZEOF(JSAMPLE)));
 532.643 +    for (ci = 0; ci < nc; ci++) {
 532.644 +      input_ptr = input_buf[row] + ci;
 532.645 +      output_ptr = output_buf[row];
 532.646 +      if (cquantize->on_odd_row) {
 532.647 +	/* work right to left in this row */
 532.648 +	input_ptr += (width-1) * nc; /* so point to rightmost pixel */
 532.649 +	output_ptr += width-1;
 532.650 +	dir = -1;
 532.651 +	dirnc = -nc;
 532.652 +	errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */
 532.653 +      } else {
 532.654 +	/* work left to right in this row */
 532.655 +	dir = 1;
 532.656 +	dirnc = nc;
 532.657 +	errorptr = cquantize->fserrors[ci]; /* => entry before first column */
 532.658 +      }
 532.659 +      colorindex_ci = cquantize->colorindex[ci];
 532.660 +      colormap_ci = cquantize->sv_colormap[ci];
 532.661 +      /* Preset error values: no error propagated to first pixel from left */
 532.662 +      cur = 0;
 532.663 +      /* and no error propagated to row below yet */
 532.664 +      belowerr = bpreverr = 0;
 532.665 +
 532.666 +      for (col = width; col > 0; col--) {
 532.667 +	/* cur holds the error propagated from the previous pixel on the
 532.668 +	 * current line.  Add the error propagated from the previous line
 532.669 +	 * to form the complete error correction term for this pixel, and
 532.670 +	 * round the error term (which is expressed * 16) to an integer.
 532.671 +	 * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
 532.672 +	 * for either sign of the error value.
 532.673 +	 * Note: errorptr points to *previous* column's array entry.
 532.674 +	 */
 532.675 +	cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
 532.676 +	/* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
 532.677 +	 * The maximum error is +- MAXJSAMPLE; this sets the required size
 532.678 +	 * of the range_limit array.
 532.679 +	 */
 532.680 +	cur += GETJSAMPLE(*input_ptr);
 532.681 +	cur = GETJSAMPLE(range_limit[cur]);
 532.682 +	/* Select output value, accumulate into output code for this pixel */
 532.683 +	pixcode = GETJSAMPLE(colorindex_ci[cur]);
 532.684 +	*output_ptr += (JSAMPLE) pixcode;
 532.685 +	/* Compute actual representation error at this pixel */
 532.686 +	/* Note: we can do this even though we don't have the final */
 532.687 +	/* pixel code, because the colormap is orthogonal. */
 532.688 +	cur -= GETJSAMPLE(colormap_ci[pixcode]);
 532.689 +	/* Compute error fractions to be propagated to adjacent pixels.
 532.690 +	 * Add these into the running sums, and simultaneously shift the
 532.691 +	 * next-line error sums left by 1 column.
 532.692 +	 */
 532.693 +	bnexterr = cur;
 532.694 +	delta = cur * 2;
 532.695 +	cur += delta;		/* form error * 3 */
 532.696 +	errorptr[0] = (FSERROR) (bpreverr + cur);
 532.697 +	cur += delta;		/* form error * 5 */
 532.698 +	bpreverr = belowerr + cur;
 532.699 +	belowerr = bnexterr;
 532.700 +	cur += delta;		/* form error * 7 */
 532.701 +	/* At this point cur contains the 7/16 error value to be propagated
 532.702 +	 * to the next pixel on the current line, and all the errors for the
 532.703 +	 * next line have been shifted over. We are therefore ready to move on.
 532.704 +	 */
 532.705 +	input_ptr += dirnc;	/* advance input ptr to next column */
 532.706 +	output_ptr += dir;	/* advance output ptr to next column */
 532.707 +	errorptr += dir;	/* advance errorptr to current column */
 532.708 +      }
 532.709 +      /* Post-loop cleanup: we must unload the final error value into the
 532.710 +       * final fserrors[] entry.  Note we need not unload belowerr because
 532.711 +       * it is for the dummy column before or after the actual array.
 532.712 +       */
 532.713 +      errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */
 532.714 +    }
 532.715 +    cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE);
 532.716 +  }
 532.717 +}
 532.718 +
 532.719 +
 532.720 +/*
 532.721 + * Allocate workspace for Floyd-Steinberg errors.
 532.722 + */
 532.723 +
 532.724 +LOCAL(void)
 532.725 +alloc_fs_workspace (j_decompress_ptr cinfo)
 532.726 +{
 532.727 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 532.728 +  size_t arraysize;
 532.729 +  int i;
 532.730 +
 532.731 +  arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
 532.732 +  for (i = 0; i < cinfo->out_color_components; i++) {
 532.733 +    cquantize->fserrors[i] = (FSERRPTR)
 532.734 +      (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
 532.735 +  }
 532.736 +}
 532.737 +
 532.738 +
 532.739 +/*
 532.740 + * Initialize for one-pass color quantization.
 532.741 + */
 532.742 +
 532.743 +METHODDEF(void)
 532.744 +start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
 532.745 +{
 532.746 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 532.747 +  size_t arraysize;
 532.748 +  int i;
 532.749 +
 532.750 +  /* Install my colormap. */
 532.751 +  cinfo->colormap = cquantize->sv_colormap;
 532.752 +  cinfo->actual_number_of_colors = cquantize->sv_actual;
 532.753 +
 532.754 +  /* Initialize for desired dithering mode. */
 532.755 +  switch (cinfo->dither_mode) {
 532.756 +  case JDITHER_NONE:
 532.757 +    if (cinfo->out_color_components == 3)
 532.758 +      cquantize->pub.color_quantize = color_quantize3;
 532.759 +    else
 532.760 +      cquantize->pub.color_quantize = color_quantize;
 532.761 +    break;
 532.762 +  case JDITHER_ORDERED:
 532.763 +    if (cinfo->out_color_components == 3)
 532.764 +      cquantize->pub.color_quantize = quantize3_ord_dither;
 532.765 +    else
 532.766 +      cquantize->pub.color_quantize = quantize_ord_dither;
 532.767 +    cquantize->row_index = 0;	/* initialize state for ordered dither */
 532.768 +    /* If user changed to ordered dither from another mode,
 532.769 +     * we must recreate the color index table with padding.
 532.770 +     * This will cost extra space, but probably isn't very likely.
 532.771 +     */
 532.772 +    if (! cquantize->is_padded)
 532.773 +      create_colorindex(cinfo);
 532.774 +    /* Create ordered-dither tables if we didn't already. */
 532.775 +    if (cquantize->odither[0] == NULL)
 532.776 +      create_odither_tables(cinfo);
 532.777 +    break;
 532.778 +  case JDITHER_FS:
 532.779 +    cquantize->pub.color_quantize = quantize_fs_dither;
 532.780 +    cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
 532.781 +    /* Allocate Floyd-Steinberg workspace if didn't already. */
 532.782 +    if (cquantize->fserrors[0] == NULL)
 532.783 +      alloc_fs_workspace(cinfo);
 532.784 +    /* Initialize the propagated errors to zero. */
 532.785 +    arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
 532.786 +    for (i = 0; i < cinfo->out_color_components; i++)
 532.787 +      jzero_far((void FAR *) cquantize->fserrors[i], arraysize);
 532.788 +    break;
 532.789 +  default:
 532.790 +    ERREXIT(cinfo, JERR_NOT_COMPILED);
 532.791 +    break;
 532.792 +  }
 532.793 +}
 532.794 +
 532.795 +
 532.796 +/*
 532.797 + * Finish up at the end of the pass.
 532.798 + */
 532.799 +
 532.800 +METHODDEF(void)
 532.801 +finish_pass_1_quant (j_decompress_ptr cinfo)
 532.802 +{
 532.803 +  /* no work in 1-pass case */
 532.804 +}
 532.805 +
 532.806 +
 532.807 +/*
 532.808 + * Switch to a new external colormap between output passes.
 532.809 + * Shouldn't get to this module!
 532.810 + */
 532.811 +
 532.812 +METHODDEF(void)
 532.813 +new_color_map_1_quant (j_decompress_ptr cinfo)
 532.814 +{
 532.815 +  ERREXIT(cinfo, JERR_MODE_CHANGE);
 532.816 +}
 532.817 +
 532.818 +
 532.819 +/*
 532.820 + * Module initialization routine for 1-pass color quantization.
 532.821 + */
 532.822 +
 532.823 +GLOBAL(void)
 532.824 +jinit_1pass_quantizer (j_decompress_ptr cinfo)
 532.825 +{
 532.826 +  my_cquantize_ptr cquantize;
 532.827 +
 532.828 +  cquantize = (my_cquantize_ptr)
 532.829 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 532.830 +				SIZEOF(my_cquantizer));
 532.831 +  cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
 532.832 +  cquantize->pub.start_pass = start_pass_1_quant;
 532.833 +  cquantize->pub.finish_pass = finish_pass_1_quant;
 532.834 +  cquantize->pub.new_color_map = new_color_map_1_quant;
 532.835 +  cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */
 532.836 +  cquantize->odither[0] = NULL;	/* Also flag odither arrays not allocated */
 532.837 +
 532.838 +  /* Make sure my internal arrays won't overflow */
 532.839 +  if (cinfo->out_color_components > MAX_Q_COMPS)
 532.840 +    ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
 532.841 +  /* Make sure colormap indexes can be represented by JSAMPLEs */
 532.842 +  if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
 532.843 +    ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1);
 532.844 +
 532.845 +  /* Create the colormap and color index table. */
 532.846 +  create_colormap(cinfo);
 532.847 +  create_colorindex(cinfo);
 532.848 +
 532.849 +  /* Allocate Floyd-Steinberg workspace now if requested.
 532.850 +   * We do this now since it is FAR storage and may affect the memory
 532.851 +   * manager's space calculations.  If the user changes to FS dither
 532.852 +   * mode in a later pass, we will allocate the space then, and will
 532.853 +   * possibly overrun the max_memory_to_use setting.
 532.854 +   */
 532.855 +  if (cinfo->dither_mode == JDITHER_FS)
 532.856 +    alloc_fs_workspace(cinfo);
 532.857 +}
 532.858 +
 532.859 +#endif /* QUANT_1PASS_SUPPORTED */
   533.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   533.2 +++ b/libs/libjpeg/jquant2.c	Sat Feb 01 19:58:19 2014 +0200
   533.3 @@ -0,0 +1,1310 @@
   533.4 +/*
   533.5 + * jquant2.c
   533.6 + *
   533.7 + * Copyright (C) 1991-1996, Thomas G. Lane.
   533.8 + * This file is part of the Independent JPEG Group's software.
   533.9 + * For conditions of distribution and use, see the accompanying README file.
  533.10 + *
  533.11 + * This file contains 2-pass color quantization (color mapping) routines.
  533.12 + * These routines provide selection of a custom color map for an image,
  533.13 + * followed by mapping of the image to that color map, with optional
  533.14 + * Floyd-Steinberg dithering.
  533.15 + * It is also possible to use just the second pass to map to an arbitrary
  533.16 + * externally-given color map.
  533.17 + *
  533.18 + * Note: ordered dithering is not supported, since there isn't any fast
  533.19 + * way to compute intercolor distances; it's unclear that ordered dither's
  533.20 + * fundamental assumptions even hold with an irregularly spaced color map.
  533.21 + */
  533.22 +
  533.23 +#define JPEG_INTERNALS
  533.24 +#include "jinclude.h"
  533.25 +#include "jpeglib.h"
  533.26 +
  533.27 +#ifdef QUANT_2PASS_SUPPORTED
  533.28 +
  533.29 +
  533.30 +/*
  533.31 + * This module implements the well-known Heckbert paradigm for color
  533.32 + * quantization.  Most of the ideas used here can be traced back to
  533.33 + * Heckbert's seminal paper
  533.34 + *   Heckbert, Paul.  "Color Image Quantization for Frame Buffer Display",
  533.35 + *   Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304.
  533.36 + *
  533.37 + * In the first pass over the image, we accumulate a histogram showing the
  533.38 + * usage count of each possible color.  To keep the histogram to a reasonable
  533.39 + * size, we reduce the precision of the input; typical practice is to retain
  533.40 + * 5 or 6 bits per color, so that 8 or 4 different input values are counted
  533.41 + * in the same histogram cell.
  533.42 + *
  533.43 + * Next, the color-selection step begins with a box representing the whole
  533.44 + * color space, and repeatedly splits the "largest" remaining box until we
  533.45 + * have as many boxes as desired colors.  Then the mean color in each
  533.46 + * remaining box becomes one of the possible output colors.
  533.47 + * 
  533.48 + * The second pass over the image maps each input pixel to the closest output
  533.49 + * color (optionally after applying a Floyd-Steinberg dithering correction).
  533.50 + * This mapping is logically trivial, but making it go fast enough requires
  533.51 + * considerable care.
  533.52 + *
  533.53 + * Heckbert-style quantizers vary a good deal in their policies for choosing
  533.54 + * the "largest" box and deciding where to cut it.  The particular policies
  533.55 + * used here have proved out well in experimental comparisons, but better ones
  533.56 + * may yet be found.
  533.57 + *
  533.58 + * In earlier versions of the IJG code, this module quantized in YCbCr color
  533.59 + * space, processing the raw upsampled data without a color conversion step.
  533.60 + * This allowed the color conversion math to be done only once per colormap
  533.61 + * entry, not once per pixel.  However, that optimization precluded other
  533.62 + * useful optimizations (such as merging color conversion with upsampling)
  533.63 + * and it also interfered with desired capabilities such as quantizing to an
  533.64 + * externally-supplied colormap.  We have therefore abandoned that approach.
  533.65 + * The present code works in the post-conversion color space, typically RGB.
  533.66 + *
  533.67 + * To improve the visual quality of the results, we actually work in scaled
  533.68 + * RGB space, giving G distances more weight than R, and R in turn more than
  533.69 + * B.  To do everything in integer math, we must use integer scale factors.
  533.70 + * The 2/3/1 scale factors used here correspond loosely to the relative
  533.71 + * weights of the colors in the NTSC grayscale equation.
  533.72 + * If you want to use this code to quantize a non-RGB color space, you'll
  533.73 + * probably need to change these scale factors.
  533.74 + */
  533.75 +
  533.76 +#define R_SCALE 2		/* scale R distances by this much */
  533.77 +#define G_SCALE 3		/* scale G distances by this much */
  533.78 +#define B_SCALE 1		/* and B by this much */
  533.79 +
  533.80 +/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined
  533.81 + * in jmorecfg.h.  As the code stands, it will do the right thing for R,G,B
  533.82 + * and B,G,R orders.  If you define some other weird order in jmorecfg.h,
  533.83 + * you'll get compile errors until you extend this logic.  In that case
  533.84 + * you'll probably want to tweak the histogram sizes too.
  533.85 + */
  533.86 +
  533.87 +#if RGB_RED == 0
  533.88 +#define C0_SCALE R_SCALE
  533.89 +#endif
  533.90 +#if RGB_BLUE == 0
  533.91 +#define C0_SCALE B_SCALE
  533.92 +#endif
  533.93 +#if RGB_GREEN == 1
  533.94 +#define C1_SCALE G_SCALE
  533.95 +#endif
  533.96 +#if RGB_RED == 2
  533.97 +#define C2_SCALE R_SCALE
  533.98 +#endif
  533.99 +#if RGB_BLUE == 2
 533.100 +#define C2_SCALE B_SCALE
 533.101 +#endif
 533.102 +
 533.103 +
 533.104 +/*
 533.105 + * First we have the histogram data structure and routines for creating it.
 533.106 + *
 533.107 + * The number of bits of precision can be adjusted by changing these symbols.
 533.108 + * We recommend keeping 6 bits for G and 5 each for R and B.
 533.109 + * If you have plenty of memory and cycles, 6 bits all around gives marginally
 533.110 + * better results; if you are short of memory, 5 bits all around will save
 533.111 + * some space but degrade the results.
 533.112 + * To maintain a fully accurate histogram, we'd need to allocate a "long"
 533.113 + * (preferably unsigned long) for each cell.  In practice this is overkill;
 533.114 + * we can get by with 16 bits per cell.  Few of the cell counts will overflow,
 533.115 + * and clamping those that do overflow to the maximum value will give close-
 533.116 + * enough results.  This reduces the recommended histogram size from 256Kb
 533.117 + * to 128Kb, which is a useful savings on PC-class machines.
 533.118 + * (In the second pass the histogram space is re-used for pixel mapping data;
 533.119 + * in that capacity, each cell must be able to store zero to the number of
 533.120 + * desired colors.  16 bits/cell is plenty for that too.)
 533.121 + * Since the JPEG code is intended to run in small memory model on 80x86
 533.122 + * machines, we can't just allocate the histogram in one chunk.  Instead
 533.123 + * of a true 3-D array, we use a row of pointers to 2-D arrays.  Each
 533.124 + * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and
 533.125 + * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries.  Note that
 533.126 + * on 80x86 machines, the pointer row is in near memory but the actual
 533.127 + * arrays are in far memory (same arrangement as we use for image arrays).
 533.128 + */
 533.129 +
 533.130 +#define MAXNUMCOLORS  (MAXJSAMPLE+1) /* maximum size of colormap */
 533.131 +
 533.132 +/* These will do the right thing for either R,G,B or B,G,R color order,
 533.133 + * but you may not like the results for other color orders.
 533.134 + */
 533.135 +#define HIST_C0_BITS  5		/* bits of precision in R/B histogram */
 533.136 +#define HIST_C1_BITS  6		/* bits of precision in G histogram */
 533.137 +#define HIST_C2_BITS  5		/* bits of precision in B/R histogram */
 533.138 +
 533.139 +/* Number of elements along histogram axes. */
 533.140 +#define HIST_C0_ELEMS  (1<<HIST_C0_BITS)
 533.141 +#define HIST_C1_ELEMS  (1<<HIST_C1_BITS)
 533.142 +#define HIST_C2_ELEMS  (1<<HIST_C2_BITS)
 533.143 +
 533.144 +/* These are the amounts to shift an input value to get a histogram index. */
 533.145 +#define C0_SHIFT  (BITS_IN_JSAMPLE-HIST_C0_BITS)
 533.146 +#define C1_SHIFT  (BITS_IN_JSAMPLE-HIST_C1_BITS)
 533.147 +#define C2_SHIFT  (BITS_IN_JSAMPLE-HIST_C2_BITS)
 533.148 +
 533.149 +
 533.150 +typedef UINT16 histcell;	/* histogram cell; prefer an unsigned type */
 533.151 +
 533.152 +typedef histcell FAR * histptr;	/* for pointers to histogram cells */
 533.153 +
 533.154 +typedef histcell hist1d[HIST_C2_ELEMS]; /* typedefs for the array */
 533.155 +typedef hist1d FAR * hist2d;	/* type for the 2nd-level pointers */
 533.156 +typedef hist2d * hist3d;	/* type for top-level pointer */
 533.157 +
 533.158 +
 533.159 +/* Declarations for Floyd-Steinberg dithering.
 533.160 + *
 533.161 + * Errors are accumulated into the array fserrors[], at a resolution of
 533.162 + * 1/16th of a pixel count.  The error at a given pixel is propagated
 533.163 + * to its not-yet-processed neighbors using the standard F-S fractions,
 533.164 + *		...	(here)	7/16
 533.165 + *		3/16	5/16	1/16
 533.166 + * We work left-to-right on even rows, right-to-left on odd rows.
 533.167 + *
 533.168 + * We can get away with a single array (holding one row's worth of errors)
 533.169 + * by using it to store the current row's errors at pixel columns not yet
 533.170 + * processed, but the next row's errors at columns already processed.  We
 533.171 + * need only a few extra variables to hold the errors immediately around the
 533.172 + * current column.  (If we are lucky, those variables are in registers, but
 533.173 + * even if not, they're probably cheaper to access than array elements are.)
 533.174 + *
 533.175 + * The fserrors[] array has (#columns + 2) entries; the extra entry at
 533.176 + * each end saves us from special-casing the first and last pixels.
 533.177 + * Each entry is three values long, one value for each color component.
 533.178 + *
 533.179 + * Note: on a wide image, we might not have enough room in a PC's near data
 533.180 + * segment to hold the error array; so it is allocated with alloc_large.
 533.181 + */
 533.182 +
 533.183 +#if BITS_IN_JSAMPLE == 8
 533.184 +typedef INT16 FSERROR;		/* 16 bits should be enough */
 533.185 +typedef int LOCFSERROR;		/* use 'int' for calculation temps */
 533.186 +#else
 533.187 +typedef INT32 FSERROR;		/* may need more than 16 bits */
 533.188 +typedef INT32 LOCFSERROR;	/* be sure calculation temps are big enough */
 533.189 +#endif
 533.190 +
 533.191 +typedef FSERROR FAR *FSERRPTR;	/* pointer to error array (in FAR storage!) */
 533.192 +
 533.193 +
 533.194 +/* Private subobject */
 533.195 +
 533.196 +typedef struct {
 533.197 +  struct jpeg_color_quantizer pub; /* public fields */
 533.198 +
 533.199 +  /* Space for the eventually created colormap is stashed here */
 533.200 +  JSAMPARRAY sv_colormap;	/* colormap allocated at init time */
 533.201 +  int desired;			/* desired # of colors = size of colormap */
 533.202 +
 533.203 +  /* Variables for accumulating image statistics */
 533.204 +  hist3d histogram;		/* pointer to the histogram */
 533.205 +
 533.206 +  boolean needs_zeroed;		/* TRUE if next pass must zero histogram */
 533.207 +
 533.208 +  /* Variables for Floyd-Steinberg dithering */
 533.209 +  FSERRPTR fserrors;		/* accumulated errors */
 533.210 +  boolean on_odd_row;		/* flag to remember which row we are on */
 533.211 +  int * error_limiter;		/* table for clamping the applied error */
 533.212 +} my_cquantizer;
 533.213 +
 533.214 +typedef my_cquantizer * my_cquantize_ptr;
 533.215 +
 533.216 +
 533.217 +/*
 533.218 + * Prescan some rows of pixels.
 533.219 + * In this module the prescan simply updates the histogram, which has been
 533.220 + * initialized to zeroes by start_pass.
 533.221 + * An output_buf parameter is required by the method signature, but no data
 533.222 + * is actually output (in fact the buffer controller is probably passing a
 533.223 + * NULL pointer).
 533.224 + */
 533.225 +
 533.226 +METHODDEF(void)
 533.227 +prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
 533.228 +		  JSAMPARRAY output_buf, int num_rows)
 533.229 +{
 533.230 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 533.231 +  register JSAMPROW ptr;
 533.232 +  register histptr histp;
 533.233 +  register hist3d histogram = cquantize->histogram;
 533.234 +  int row;
 533.235 +  JDIMENSION col;
 533.236 +  JDIMENSION width = cinfo->output_width;
 533.237 +
 533.238 +  for (row = 0; row < num_rows; row++) {
 533.239 +    ptr = input_buf[row];
 533.240 +    for (col = width; col > 0; col--) {
 533.241 +      /* get pixel value and index into the histogram */
 533.242 +      histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
 533.243 +			 [GETJSAMPLE(ptr[1]) >> C1_SHIFT]
 533.244 +			 [GETJSAMPLE(ptr[2]) >> C2_SHIFT];
 533.245 +      /* increment, check for overflow and undo increment if so. */
 533.246 +      if (++(*histp) <= 0)
 533.247 +	(*histp)--;
 533.248 +      ptr += 3;
 533.249 +    }
 533.250 +  }
 533.251 +}
 533.252 +
 533.253 +
 533.254 +/*
 533.255 + * Next we have the really interesting routines: selection of a colormap
 533.256 + * given the completed histogram.
 533.257 + * These routines work with a list of "boxes", each representing a rectangular
 533.258 + * subset of the input color space (to histogram precision).
 533.259 + */
 533.260 +
 533.261 +typedef struct {
 533.262 +  /* The bounds of the box (inclusive); expressed as histogram indexes */
 533.263 +  int c0min, c0max;
 533.264 +  int c1min, c1max;
 533.265 +  int c2min, c2max;
 533.266 +  /* The volume (actually 2-norm) of the box */
 533.267 +  INT32 volume;
 533.268 +  /* The number of nonzero histogram cells within this box */
 533.269 +  long colorcount;
 533.270 +} box;
 533.271 +
 533.272 +typedef box * boxptr;
 533.273 +
 533.274 +
 533.275 +LOCAL(boxptr)
 533.276 +find_biggest_color_pop (boxptr boxlist, int numboxes)
 533.277 +/* Find the splittable box with the largest color population */
 533.278 +/* Returns NULL if no splittable boxes remain */
 533.279 +{
 533.280 +  register boxptr boxp;
 533.281 +  register int i;
 533.282 +  register long maxc = 0;
 533.283 +  boxptr which = NULL;
 533.284 +  
 533.285 +  for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
 533.286 +    if (boxp->colorcount > maxc && boxp->volume > 0) {
 533.287 +      which = boxp;
 533.288 +      maxc = boxp->colorcount;
 533.289 +    }
 533.290 +  }
 533.291 +  return which;
 533.292 +}
 533.293 +
 533.294 +
 533.295 +LOCAL(boxptr)
 533.296 +find_biggest_volume (boxptr boxlist, int numboxes)
 533.297 +/* Find the splittable box with the largest (scaled) volume */
 533.298 +/* Returns NULL if no splittable boxes remain */
 533.299 +{
 533.300 +  register boxptr boxp;
 533.301 +  register int i;
 533.302 +  register INT32 maxv = 0;
 533.303 +  boxptr which = NULL;
 533.304 +  
 533.305 +  for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
 533.306 +    if (boxp->volume > maxv) {
 533.307 +      which = boxp;
 533.308 +      maxv = boxp->volume;
 533.309 +    }
 533.310 +  }
 533.311 +  return which;
 533.312 +}
 533.313 +
 533.314 +
 533.315 +LOCAL(void)
 533.316 +update_box (j_decompress_ptr cinfo, boxptr boxp)
 533.317 +/* Shrink the min/max bounds of a box to enclose only nonzero elements, */
 533.318 +/* and recompute its volume and population */
 533.319 +{
 533.320 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 533.321 +  hist3d histogram = cquantize->histogram;
 533.322 +  histptr histp;
 533.323 +  int c0,c1,c2;
 533.324 +  int c0min,c0max,c1min,c1max,c2min,c2max;
 533.325 +  INT32 dist0,dist1,dist2;
 533.326 +  long ccount;
 533.327 +  
 533.328 +  c0min = boxp->c0min;  c0max = boxp->c0max;
 533.329 +  c1min = boxp->c1min;  c1max = boxp->c1max;
 533.330 +  c2min = boxp->c2min;  c2max = boxp->c2max;
 533.331 +  
 533.332 +  if (c0max > c0min)
 533.333 +    for (c0 = c0min; c0 <= c0max; c0++)
 533.334 +      for (c1 = c1min; c1 <= c1max; c1++) {
 533.335 +	histp = & histogram[c0][c1][c2min];
 533.336 +	for (c2 = c2min; c2 <= c2max; c2++)
 533.337 +	  if (*histp++ != 0) {
 533.338 +	    boxp->c0min = c0min = c0;
 533.339 +	    goto have_c0min;
 533.340 +	  }
 533.341 +      }
 533.342 + have_c0min:
 533.343 +  if (c0max > c0min)
 533.344 +    for (c0 = c0max; c0 >= c0min; c0--)
 533.345 +      for (c1 = c1min; c1 <= c1max; c1++) {
 533.346 +	histp = & histogram[c0][c1][c2min];
 533.347 +	for (c2 = c2min; c2 <= c2max; c2++)
 533.348 +	  if (*histp++ != 0) {
 533.349 +	    boxp->c0max = c0max = c0;
 533.350 +	    goto have_c0max;
 533.351 +	  }
 533.352 +      }
 533.353 + have_c0max:
 533.354 +  if (c1max > c1min)
 533.355 +    for (c1 = c1min; c1 <= c1max; c1++)
 533.356 +      for (c0 = c0min; c0 <= c0max; c0++) {
 533.357 +	histp = & histogram[c0][c1][c2min];
 533.358 +	for (c2 = c2min; c2 <= c2max; c2++)
 533.359 +	  if (*histp++ != 0) {
 533.360 +	    boxp->c1min = c1min = c1;
 533.361 +	    goto have_c1min;
 533.362 +	  }
 533.363 +      }
 533.364 + have_c1min:
 533.365 +  if (c1max > c1min)
 533.366 +    for (c1 = c1max; c1 >= c1min; c1--)
 533.367 +      for (c0 = c0min; c0 <= c0max; c0++) {
 533.368 +	histp = & histogram[c0][c1][c2min];
 533.369 +	for (c2 = c2min; c2 <= c2max; c2++)
 533.370 +	  if (*histp++ != 0) {
 533.371 +	    boxp->c1max = c1max = c1;
 533.372 +	    goto have_c1max;
 533.373 +	  }
 533.374 +      }
 533.375 + have_c1max:
 533.376 +  if (c2max > c2min)
 533.377 +    for (c2 = c2min; c2 <= c2max; c2++)
 533.378 +      for (c0 = c0min; c0 <= c0max; c0++) {
 533.379 +	histp = & histogram[c0][c1min][c2];
 533.380 +	for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
 533.381 +	  if (*histp != 0) {
 533.382 +	    boxp->c2min = c2min = c2;
 533.383 +	    goto have_c2min;
 533.384 +	  }
 533.385 +      }
 533.386 + have_c2min:
 533.387 +  if (c2max > c2min)
 533.388 +    for (c2 = c2max; c2 >= c2min; c2--)
 533.389 +      for (c0 = c0min; c0 <= c0max; c0++) {
 533.390 +	histp = & histogram[c0][c1min][c2];
 533.391 +	for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
 533.392 +	  if (*histp != 0) {
 533.393 +	    boxp->c2max = c2max = c2;
 533.394 +	    goto have_c2max;
 533.395 +	  }
 533.396 +      }
 533.397 + have_c2max:
 533.398 +
 533.399 +  /* Update box volume.
 533.400 +   * We use 2-norm rather than real volume here; this biases the method
 533.401 +   * against making long narrow boxes, and it has the side benefit that
 533.402 +   * a box is splittable iff norm > 0.
 533.403 +   * Since the differences are expressed in histogram-cell units,
 533.404 +   * we have to shift back to JSAMPLE units to get consistent distances;
 533.405 +   * after which, we scale according to the selected distance scale factors.
 533.406 +   */
 533.407 +  dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
 533.408 +  dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
 533.409 +  dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
 533.410 +  boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
 533.411 +  
 533.412 +  /* Now scan remaining volume of box and compute population */
 533.413 +  ccount = 0;
 533.414 +  for (c0 = c0min; c0 <= c0max; c0++)
 533.415 +    for (c1 = c1min; c1 <= c1max; c1++) {
 533.416 +      histp = & histogram[c0][c1][c2min];
 533.417 +      for (c2 = c2min; c2 <= c2max; c2++, histp++)
 533.418 +	if (*histp != 0) {
 533.419 +	  ccount++;
 533.420 +	}
 533.421 +    }
 533.422 +  boxp->colorcount = ccount;
 533.423 +}
 533.424 +
 533.425 +
 533.426 +LOCAL(int)
 533.427 +median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
 533.428 +	    int desired_colors)
 533.429 +/* Repeatedly select and split the largest box until we have enough boxes */
 533.430 +{
 533.431 +  int n,lb;
 533.432 +  int c0,c1,c2,cmax;
 533.433 +  register boxptr b1,b2;
 533.434 +
 533.435 +  while (numboxes < desired_colors) {
 533.436 +    /* Select box to split.
 533.437 +     * Current algorithm: by population for first half, then by volume.
 533.438 +     */
 533.439 +    if (numboxes*2 <= desired_colors) {
 533.440 +      b1 = find_biggest_color_pop(boxlist, numboxes);
 533.441 +    } else {
 533.442 +      b1 = find_biggest_volume(boxlist, numboxes);
 533.443 +    }
 533.444 +    if (b1 == NULL)		/* no splittable boxes left! */
 533.445 +      break;
 533.446 +    b2 = &boxlist[numboxes];	/* where new box will go */
 533.447 +    /* Copy the color bounds to the new box. */
 533.448 +    b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max;
 533.449 +    b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min;
 533.450 +    /* Choose which axis to split the box on.
 533.451 +     * Current algorithm: longest scaled axis.
 533.452 +     * See notes in update_box about scaling distances.
 533.453 +     */
 533.454 +    c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
 533.455 +    c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
 533.456 +    c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
 533.457 +    /* We want to break any ties in favor of green, then red, blue last.
 533.458 +     * This code does the right thing for R,G,B or B,G,R color orders only.
 533.459 +     */
 533.460 +#if RGB_RED == 0
 533.461 +    cmax = c1; n = 1;
 533.462 +    if (c0 > cmax) { cmax = c0; n = 0; }
 533.463 +    if (c2 > cmax) { n = 2; }
 533.464 +#else
 533.465 +    cmax = c1; n = 1;
 533.466 +    if (c2 > cmax) { cmax = c2; n = 2; }
 533.467 +    if (c0 > cmax) { n = 0; }
 533.468 +#endif
 533.469 +    /* Choose split point along selected axis, and update box bounds.
 533.470 +     * Current algorithm: split at halfway point.
 533.471 +     * (Since the box has been shrunk to minimum volume,
 533.472 +     * any split will produce two nonempty subboxes.)
 533.473 +     * Note that lb value is max for lower box, so must be < old max.
 533.474 +     */
 533.475 +    switch (n) {
 533.476 +    case 0:
 533.477 +      lb = (b1->c0max + b1->c0min) / 2;
 533.478 +      b1->c0max = lb;
 533.479 +      b2->c0min = lb+1;
 533.480 +      break;
 533.481 +    case 1:
 533.482 +      lb = (b1->c1max + b1->c1min) / 2;
 533.483 +      b1->c1max = lb;
 533.484 +      b2->c1min = lb+1;
 533.485 +      break;
 533.486 +    case 2:
 533.487 +      lb = (b1->c2max + b1->c2min) / 2;
 533.488 +      b1->c2max = lb;
 533.489 +      b2->c2min = lb+1;
 533.490 +      break;
 533.491 +    }
 533.492 +    /* Update stats for boxes */
 533.493 +    update_box(cinfo, b1);
 533.494 +    update_box(cinfo, b2);
 533.495 +    numboxes++;
 533.496 +  }
 533.497 +  return numboxes;
 533.498 +}
 533.499 +
 533.500 +
 533.501 +LOCAL(void)
 533.502 +compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
 533.503 +/* Compute representative color for a box, put it in colormap[icolor] */
 533.504 +{
 533.505 +  /* Current algorithm: mean weighted by pixels (not colors) */
 533.506 +  /* Note it is important to get the rounding correct! */
 533.507 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 533.508 +  hist3d histogram = cquantize->histogram;
 533.509 +  histptr histp;
 533.510 +  int c0,c1,c2;
 533.511 +  int c0min,c0max,c1min,c1max,c2min,c2max;
 533.512 +  long count;
 533.513 +  long total = 0;
 533.514 +  long c0total = 0;
 533.515 +  long c1total = 0;
 533.516 +  long c2total = 0;
 533.517 +  
 533.518 +  c0min = boxp->c0min;  c0max = boxp->c0max;
 533.519 +  c1min = boxp->c1min;  c1max = boxp->c1max;
 533.520 +  c2min = boxp->c2min;  c2max = boxp->c2max;
 533.521 +  
 533.522 +  for (c0 = c0min; c0 <= c0max; c0++)
 533.523 +    for (c1 = c1min; c1 <= c1max; c1++) {
 533.524 +      histp = & histogram[c0][c1][c2min];
 533.525 +      for (c2 = c2min; c2 <= c2max; c2++) {
 533.526 +	if ((count = *histp++) != 0) {
 533.527 +	  total += count;
 533.528 +	  c0total += ((c0 << C0_SHIFT) + ((1<<C0_SHIFT)>>1)) * count;
 533.529 +	  c1total += ((c1 << C1_SHIFT) + ((1<<C1_SHIFT)>>1)) * count;
 533.530 +	  c2total += ((c2 << C2_SHIFT) + ((1<<C2_SHIFT)>>1)) * count;
 533.531 +	}
 533.532 +      }
 533.533 +    }
 533.534 +  
 533.535 +  cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
 533.536 +  cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
 533.537 +  cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
 533.538 +}
 533.539 +
 533.540 +
 533.541 +LOCAL(void)
 533.542 +select_colors (j_decompress_ptr cinfo, int desired_colors)
 533.543 +/* Master routine for color selection */
 533.544 +{
 533.545 +  boxptr boxlist;
 533.546 +  int numboxes;
 533.547 +  int i;
 533.548 +
 533.549 +  /* Allocate workspace for box list */
 533.550 +  boxlist = (boxptr) (*cinfo->mem->alloc_small)
 533.551 +    ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box));
 533.552 +  /* Initialize one box containing whole space */
 533.553 +  numboxes = 1;
 533.554 +  boxlist[0].c0min = 0;
 533.555 +  boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT;
 533.556 +  boxlist[0].c1min = 0;
 533.557 +  boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT;
 533.558 +  boxlist[0].c2min = 0;
 533.559 +  boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT;
 533.560 +  /* Shrink it to actually-used volume and set its statistics */
 533.561 +  update_box(cinfo, & boxlist[0]);
 533.562 +  /* Perform median-cut to produce final box list */
 533.563 +  numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors);
 533.564 +  /* Compute the representative color for each box, fill colormap */
 533.565 +  for (i = 0; i < numboxes; i++)
 533.566 +    compute_color(cinfo, & boxlist[i], i);
 533.567 +  cinfo->actual_number_of_colors = numboxes;
 533.568 +  TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes);
 533.569 +}
 533.570 +
 533.571 +
 533.572 +/*
 533.573 + * These routines are concerned with the time-critical task of mapping input
 533.574 + * colors to the nearest color in the selected colormap.
 533.575 + *
 533.576 + * We re-use the histogram space as an "inverse color map", essentially a
 533.577 + * cache for the results of nearest-color searches.  All colors within a
 533.578 + * histogram cell will be mapped to the same colormap entry, namely the one
 533.579 + * closest to the cell's center.  This may not be quite the closest entry to
 533.580 + * the actual input color, but it's almost as good.  A zero in the cache
 533.581 + * indicates we haven't found the nearest color for that cell yet; the array
 533.582 + * is cleared to zeroes before starting the mapping pass.  When we find the
 533.583 + * nearest color for a cell, its colormap index plus one is recorded in the
 533.584 + * cache for future use.  The pass2 scanning routines call fill_inverse_cmap
 533.585 + * when they need to use an unfilled entry in the cache.
 533.586 + *
 533.587 + * Our method of efficiently finding nearest colors is based on the "locally
 533.588 + * sorted search" idea described by Heckbert and on the incremental distance
 533.589 + * calculation described by Spencer W. Thomas in chapter III.1 of Graphics
 533.590 + * Gems II (James Arvo, ed.  Academic Press, 1991).  Thomas points out that
 533.591 + * the distances from a given colormap entry to each cell of the histogram can
 533.592 + * be computed quickly using an incremental method: the differences between
 533.593 + * distances to adjacent cells themselves differ by a constant.  This allows a
 533.594 + * fairly fast implementation of the "brute force" approach of computing the
 533.595 + * distance from every colormap entry to every histogram cell.  Unfortunately,
 533.596 + * it needs a work array to hold the best-distance-so-far for each histogram
 533.597 + * cell (because the inner loop has to be over cells, not colormap entries).
 533.598 + * The work array elements have to be INT32s, so the work array would need
 533.599 + * 256Kb at our recommended precision.  This is not feasible in DOS machines.
 533.600 + *
 533.601 + * To get around these problems, we apply Thomas' method to compute the
 533.602 + * nearest colors for only the cells within a small subbox of the histogram.
 533.603 + * The work array need be only as big as the subbox, so the memory usage
 533.604 + * problem is solved.  Furthermore, we need not fill subboxes that are never
 533.605 + * referenced in pass2; many images use only part of the color gamut, so a
 533.606 + * fair amount of work is saved.  An additional advantage of this
 533.607 + * approach is that we can apply Heckbert's locality criterion to quickly
 533.608 + * eliminate colormap entries that are far away from the subbox; typically
 533.609 + * three-fourths of the colormap entries are rejected by Heckbert's criterion,
 533.610 + * and we need not compute their distances to individual cells in the subbox.
 533.611 + * The speed of this approach is heavily influenced by the subbox size: too
 533.612 + * small means too much overhead, too big loses because Heckbert's criterion
 533.613 + * can't eliminate as many colormap entries.  Empirically the best subbox
 533.614 + * size seems to be about 1/512th of the histogram (1/8th in each direction).
 533.615 + *
 533.616 + * Thomas' article also describes a refined method which is asymptotically
 533.617 + * faster than the brute-force method, but it is also far more complex and
 533.618 + * cannot efficiently be applied to small subboxes.  It is therefore not
 533.619 + * useful for programs intended to be portable to DOS machines.  On machines
 533.620 + * with plenty of memory, filling the whole histogram in one shot with Thomas'
 533.621 + * refined method might be faster than the present code --- but then again,
 533.622 + * it might not be any faster, and it's certainly more complicated.
 533.623 + */
 533.624 +
 533.625 +
 533.626 +/* log2(histogram cells in update box) for each axis; this can be adjusted */
 533.627 +#define BOX_C0_LOG  (HIST_C0_BITS-3)
 533.628 +#define BOX_C1_LOG  (HIST_C1_BITS-3)
 533.629 +#define BOX_C2_LOG  (HIST_C2_BITS-3)
 533.630 +
 533.631 +#define BOX_C0_ELEMS  (1<<BOX_C0_LOG) /* # of hist cells in update box */
 533.632 +#define BOX_C1_ELEMS  (1<<BOX_C1_LOG)
 533.633 +#define BOX_C2_ELEMS  (1<<BOX_C2_LOG)
 533.634 +
 533.635 +#define BOX_C0_SHIFT  (C0_SHIFT + BOX_C0_LOG)
 533.636 +#define BOX_C1_SHIFT  (C1_SHIFT + BOX_C1_LOG)
 533.637 +#define BOX_C2_SHIFT  (C2_SHIFT + BOX_C2_LOG)
 533.638 +
 533.639 +
 533.640 +/*
 533.641 + * The next three routines implement inverse colormap filling.  They could
 533.642 + * all be folded into one big routine, but splitting them up this way saves
 533.643 + * some stack space (the mindist[] and bestdist[] arrays need not coexist)
 533.644 + * and may allow some compilers to produce better code by registerizing more
 533.645 + * inner-loop variables.
 533.646 + */
 533.647 +
 533.648 +LOCAL(int)
 533.649 +find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
 533.650 +		    JSAMPLE colorlist[])
 533.651 +/* Locate the colormap entries close enough to an update box to be candidates
 533.652 + * for the nearest entry to some cell(s) in the update box.  The update box
 533.653 + * is specified by the center coordinates of its first cell.  The number of
 533.654 + * candidate colormap entries is returned, and their colormap indexes are
 533.655 + * placed in colorlist[].
 533.656 + * This routine uses Heckbert's "locally sorted search" criterion to select
 533.657 + * the colors that need further consideration.
 533.658 + */
 533.659 +{
 533.660 +  int numcolors = cinfo->actual_number_of_colors;
 533.661 +  int maxc0, maxc1, maxc2;
 533.662 +  int centerc0, centerc1, centerc2;
 533.663 +  int i, x, ncolors;
 533.664 +  INT32 minmaxdist, min_dist, max_dist, tdist;
 533.665 +  INT32 mindist[MAXNUMCOLORS];	/* min distance to colormap entry i */
 533.666 +
 533.667 +  /* Compute true coordinates of update box's upper corner and center.
 533.668 +   * Actually we compute the coordinates of the center of the upper-corner
 533.669 +   * histogram cell, which are the upper bounds of the volume we care about.
 533.670 +   * Note that since ">>" rounds down, the "center" values may be closer to
 533.671 +   * min than to max; hence comparisons to them must be "<=", not "<".
 533.672 +   */
 533.673 +  maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
 533.674 +  centerc0 = (minc0 + maxc0) >> 1;
 533.675 +  maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
 533.676 +  centerc1 = (minc1 + maxc1) >> 1;
 533.677 +  maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
 533.678 +  centerc2 = (minc2 + maxc2) >> 1;
 533.679 +
 533.680 +  /* For each color in colormap, find:
 533.681 +   *  1. its minimum squared-distance to any point in the update box
 533.682 +   *     (zero if color is within update box);
 533.683 +   *  2. its maximum squared-distance to any point in the update box.
 533.684 +   * Both of these can be found by considering only the corners of the box.
 533.685 +   * We save the minimum distance for each color in mindist[];
 533.686 +   * only the smallest maximum distance is of interest.
 533.687 +   */
 533.688 +  minmaxdist = 0x7FFFFFFFL;
 533.689 +
 533.690 +  for (i = 0; i < numcolors; i++) {
 533.691 +    /* We compute the squared-c0-distance term, then add in the other two. */
 533.692 +    x = GETJSAMPLE(cinfo->colormap[0][i]);
 533.693 +    if (x < minc0) {
 533.694 +      tdist = (x - minc0) * C0_SCALE;
 533.695 +      min_dist = tdist*tdist;
 533.696 +      tdist = (x - maxc0) * C0_SCALE;
 533.697 +      max_dist = tdist*tdist;
 533.698 +    } else if (x > maxc0) {
 533.699 +      tdist = (x - maxc0) * C0_SCALE;
 533.700 +      min_dist = tdist*tdist;
 533.701 +      tdist = (x - minc0) * C0_SCALE;
 533.702 +      max_dist = tdist*tdist;
 533.703 +    } else {
 533.704 +      /* within cell range so no contribution to min_dist */
 533.705 +      min_dist = 0;
 533.706 +      if (x <= centerc0) {
 533.707 +	tdist = (x - maxc0) * C0_SCALE;
 533.708 +	max_dist = tdist*tdist;
 533.709 +      } else {
 533.710 +	tdist = (x - minc0) * C0_SCALE;
 533.711 +	max_dist = tdist*tdist;
 533.712 +      }
 533.713 +    }
 533.714 +
 533.715 +    x = GETJSAMPLE(cinfo->colormap[1][i]);
 533.716 +    if (x < minc1) {
 533.717 +      tdist = (x - minc1) * C1_SCALE;
 533.718 +      min_dist += tdist*tdist;
 533.719 +      tdist = (x - maxc1) * C1_SCALE;
 533.720 +      max_dist += tdist*tdist;
 533.721 +    } else if (x > maxc1) {
 533.722 +      tdist = (x - maxc1) * C1_SCALE;
 533.723 +      min_dist += tdist*tdist;
 533.724 +      tdist = (x - minc1) * C1_SCALE;
 533.725 +      max_dist += tdist*tdist;
 533.726 +    } else {
 533.727 +      /* within cell range so no contribution to min_dist */
 533.728 +      if (x <= centerc1) {
 533.729 +	tdist = (x - maxc1) * C1_SCALE;
 533.730 +	max_dist += tdist*tdist;
 533.731 +      } else {
 533.732 +	tdist = (x - minc1) * C1_SCALE;
 533.733 +	max_dist += tdist*tdist;
 533.734 +      }
 533.735 +    }
 533.736 +
 533.737 +    x = GETJSAMPLE(cinfo->colormap[2][i]);
 533.738 +    if (x < minc2) {
 533.739 +      tdist = (x - minc2) * C2_SCALE;
 533.740 +      min_dist += tdist*tdist;
 533.741 +      tdist = (x - maxc2) * C2_SCALE;
 533.742 +      max_dist += tdist*tdist;
 533.743 +    } else if (x > maxc2) {
 533.744 +      tdist = (x - maxc2) * C2_SCALE;
 533.745 +      min_dist += tdist*tdist;
 533.746 +      tdist = (x - minc2) * C2_SCALE;
 533.747 +      max_dist += tdist*tdist;
 533.748 +    } else {
 533.749 +      /* within cell range so no contribution to min_dist */
 533.750 +      if (x <= centerc2) {
 533.751 +	tdist = (x - maxc2) * C2_SCALE;
 533.752 +	max_dist += tdist*tdist;
 533.753 +      } else {
 533.754 +	tdist = (x - minc2) * C2_SCALE;
 533.755 +	max_dist += tdist*tdist;
 533.756 +      }
 533.757 +    }
 533.758 +
 533.759 +    mindist[i] = min_dist;	/* save away the results */
 533.760 +    if (max_dist < minmaxdist)
 533.761 +      minmaxdist = max_dist;
 533.762 +  }
 533.763 +
 533.764 +  /* Now we know that no cell in the update box is more than minmaxdist
 533.765 +   * away from some colormap entry.  Therefore, only colors that are
 533.766 +   * within minmaxdist of some part of the box need be considered.
 533.767 +   */
 533.768 +  ncolors = 0;
 533.769 +  for (i = 0; i < numcolors; i++) {
 533.770 +    if (mindist[i] <= minmaxdist)
 533.771 +      colorlist[ncolors++] = (JSAMPLE) i;
 533.772 +  }
 533.773 +  return ncolors;
 533.774 +}
 533.775 +
 533.776 +
 533.777 +LOCAL(void)
 533.778 +find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
 533.779 +		  int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
 533.780 +/* Find the closest colormap entry for each cell in the update box,
 533.781 + * given the list of candidate colors prepared by find_nearby_colors.
 533.782 + * Return the indexes of the closest entries in the bestcolor[] array.
 533.783 + * This routine uses Thomas' incremental distance calculation method to
 533.784 + * find the distance from a colormap entry to successive cells in the box.
 533.785 + */
 533.786 +{
 533.787 +  int ic0, ic1, ic2;
 533.788 +  int i, icolor;
 533.789 +  register INT32 * bptr;	/* pointer into bestdist[] array */
 533.790 +  JSAMPLE * cptr;		/* pointer into bestcolor[] array */
 533.791 +  INT32 dist0, dist1;		/* initial distance values */
 533.792 +  register INT32 dist2;		/* current distance in inner loop */
 533.793 +  INT32 xx0, xx1;		/* distance increments */
 533.794 +  register INT32 xx2;
 533.795 +  INT32 inc0, inc1, inc2;	/* initial values for increments */
 533.796 +  /* This array holds the distance to the nearest-so-far color for each cell */
 533.797 +  INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
 533.798 +
 533.799 +  /* Initialize best-distance for each cell of the update box */
 533.800 +  bptr = bestdist;
 533.801 +  for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--)
 533.802 +    *bptr++ = 0x7FFFFFFFL;
 533.803 +  
 533.804 +  /* For each color selected by find_nearby_colors,
 533.805 +   * compute its distance to the center of each cell in the box.
 533.806 +   * If that's less than best-so-far, update best distance and color number.
 533.807 +   */
 533.808 +  
 533.809 +  /* Nominal steps between cell centers ("x" in Thomas article) */
 533.810 +#define STEP_C0  ((1 << C0_SHIFT) * C0_SCALE)
 533.811 +#define STEP_C1  ((1 << C1_SHIFT) * C1_SCALE)
 533.812 +#define STEP_C2  ((1 << C2_SHIFT) * C2_SCALE)
 533.813 +  
 533.814 +  for (i = 0; i < numcolors; i++) {
 533.815 +    icolor = GETJSAMPLE(colorlist[i]);
 533.816 +    /* Compute (square of) distance from minc0/c1/c2 to this color */
 533.817 +    inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
 533.818 +    dist0 = inc0*inc0;
 533.819 +    inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
 533.820 +    dist0 += inc1*inc1;
 533.821 +    inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
 533.822 +    dist0 += inc2*inc2;
 533.823 +    /* Form the initial difference increments */
 533.824 +    inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
 533.825 +    inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
 533.826 +    inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
 533.827 +    /* Now loop over all cells in box, updating distance per Thomas method */
 533.828 +    bptr = bestdist;
 533.829 +    cptr = bestcolor;
 533.830 +    xx0 = inc0;
 533.831 +    for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) {
 533.832 +      dist1 = dist0;
 533.833 +      xx1 = inc1;
 533.834 +      for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) {
 533.835 +	dist2 = dist1;
 533.836 +	xx2 = inc2;
 533.837 +	for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) {
 533.838 +	  if (dist2 < *bptr) {
 533.839 +	    *bptr = dist2;
 533.840 +	    *cptr = (JSAMPLE) icolor;
 533.841 +	  }
 533.842 +	  dist2 += xx2;
 533.843 +	  xx2 += 2 * STEP_C2 * STEP_C2;
 533.844 +	  bptr++;
 533.845 +	  cptr++;
 533.846 +	}
 533.847 +	dist1 += xx1;
 533.848 +	xx1 += 2 * STEP_C1 * STEP_C1;
 533.849 +      }
 533.850 +      dist0 += xx0;
 533.851 +      xx0 += 2 * STEP_C0 * STEP_C0;
 533.852 +    }
 533.853 +  }
 533.854 +}
 533.855 +
 533.856 +
 533.857 +LOCAL(void)
 533.858 +fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
 533.859 +/* Fill the inverse-colormap entries in the update box that contains */
 533.860 +/* histogram cell c0/c1/c2.  (Only that one cell MUST be filled, but */
 533.861 +/* we can fill as many others as we wish.) */
 533.862 +{
 533.863 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 533.864 +  hist3d histogram = cquantize->histogram;
 533.865 +  int minc0, minc1, minc2;	/* lower left corner of update box */
 533.866 +  int ic0, ic1, ic2;
 533.867 +  register JSAMPLE * cptr;	/* pointer into bestcolor[] array */
 533.868 +  register histptr cachep;	/* pointer into main cache array */
 533.869 +  /* This array lists the candidate colormap indexes. */
 533.870 +  JSAMPLE colorlist[MAXNUMCOLORS];
 533.871 +  int numcolors;		/* number of candidate colors */
 533.872 +  /* This array holds the actually closest colormap index for each cell. */
 533.873 +  JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
 533.874 +
 533.875 +  /* Convert cell coordinates to update box ID */
 533.876 +  c0 >>= BOX_C0_LOG;
 533.877 +  c1 >>= BOX_C1_LOG;
 533.878 +  c2 >>= BOX_C2_LOG;
 533.879 +
 533.880 +  /* Compute true coordinates of update box's origin corner.
 533.881 +   * Actually we compute the coordinates of the center of the corner
 533.882 +   * histogram cell, which are the lower bounds of the volume we care about.
 533.883 +   */
 533.884 +  minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
 533.885 +  minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
 533.886 +  minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
 533.887 +  
 533.888 +  /* Determine which colormap entries are close enough to be candidates
 533.889 +   * for the nearest entry to some cell in the update box.
 533.890 +   */
 533.891 +  numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);
 533.892 +
 533.893 +  /* Determine the actually nearest colors. */
 533.894 +  find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist,
 533.895 +		   bestcolor);
 533.896 +
 533.897 +  /* Save the best color numbers (plus 1) in the main cache array */
 533.898 +  c0 <<= BOX_C0_LOG;		/* convert ID back to base cell indexes */
 533.899 +  c1 <<= BOX_C1_LOG;
 533.900 +  c2 <<= BOX_C2_LOG;
 533.901 +  cptr = bestcolor;
 533.902 +  for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) {
 533.903 +    for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
 533.904 +      cachep = & histogram[c0+ic0][c1+ic1][c2];
 533.905 +      for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
 533.906 +	*cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1);
 533.907 +      }
 533.908 +    }
 533.909 +  }
 533.910 +}
 533.911 +
 533.912 +
 533.913 +/*
 533.914 + * Map some rows of pixels to the output colormapped representation.
 533.915 + */
 533.916 +
 533.917 +METHODDEF(void)
 533.918 +pass2_no_dither (j_decompress_ptr cinfo,
 533.919 +		 JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
 533.920 +/* This version performs no dithering */
 533.921 +{
 533.922 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 533.923 +  hist3d histogram = cquantize->histogram;
 533.924 +  register JSAMPROW inptr, outptr;
 533.925 +  register histptr cachep;
 533.926 +  register int c0, c1, c2;
 533.927 +  int row;
 533.928 +  JDIMENSION col;
 533.929 +  JDIMENSION width = cinfo->output_width;
 533.930 +
 533.931 +  for (row = 0; row < num_rows; row++) {
 533.932 +    inptr = input_buf[row];
 533.933 +    outptr = output_buf[row];
 533.934 +    for (col = width; col > 0; col--) {
 533.935 +      /* get pixel value and index into the cache */
 533.936 +      c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
 533.937 +      c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
 533.938 +      c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
 533.939 +      cachep = & histogram[c0][c1][c2];
 533.940 +      /* If we have not seen this color before, find nearest colormap entry */
 533.941 +      /* and update the cache */
 533.942 +      if (*cachep == 0)
 533.943 +	fill_inverse_cmap(cinfo, c0,c1,c2);
 533.944 +      /* Now emit the colormap index for this cell */
 533.945 +      *outptr++ = (JSAMPLE) (*cachep - 1);
 533.946 +    }
 533.947 +  }
 533.948 +}
 533.949 +
 533.950 +
 533.951 +METHODDEF(void)
 533.952 +pass2_fs_dither (j_decompress_ptr cinfo,
 533.953 +		 JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
 533.954 +/* This version performs Floyd-Steinberg dithering */
 533.955 +{
 533.956 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 533.957 +  hist3d histogram = cquantize->histogram;
 533.958 +  register LOCFSERROR cur0, cur1, cur2;	/* current error or pixel value */
 533.959 +  LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */
 533.960 +  LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */
 533.961 +  register FSERRPTR errorptr;	/* => fserrors[] at column before current */
 533.962 +  JSAMPROW inptr;		/* => current input pixel */
 533.963 +  JSAMPROW outptr;		/* => current output pixel */
 533.964 +  histptr cachep;
 533.965 +  int dir;			/* +1 or -1 depending on direction */
 533.966 +  int dir3;			/* 3*dir, for advancing inptr & errorptr */
 533.967 +  int row;
 533.968 +  JDIMENSION col;
 533.969 +  JDIMENSION width = cinfo->output_width;
 533.970 +  JSAMPLE *range_limit = cinfo->sample_range_limit;
 533.971 +  int *error_limit = cquantize->error_limiter;
 533.972 +  JSAMPROW colormap0 = cinfo->colormap[0];
 533.973 +  JSAMPROW colormap1 = cinfo->colormap[1];
 533.974 +  JSAMPROW colormap2 = cinfo->colormap[2];
 533.975 +  SHIFT_TEMPS
 533.976 +
 533.977 +  for (row = 0; row < num_rows; row++) {
 533.978 +    inptr = input_buf[row];
 533.979 +    outptr = output_buf[row];
 533.980 +    if (cquantize->on_odd_row) {
 533.981 +      /* work right to left in this row */
 533.982 +      inptr += (width-1) * 3;	/* so point to rightmost pixel */
 533.983 +      outptr += width-1;
 533.984 +      dir = -1;
 533.985 +      dir3 = -3;
 533.986 +      errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */
 533.987 +      cquantize->on_odd_row = FALSE; /* flip for next time */
 533.988 +    } else {
 533.989 +      /* work left to right in this row */
 533.990 +      dir = 1;
 533.991 +      dir3 = 3;
 533.992 +      errorptr = cquantize->fserrors; /* => entry before first real column */
 533.993 +      cquantize->on_odd_row = TRUE; /* flip for next time */
 533.994 +    }
 533.995 +    /* Preset error values: no error propagated to first pixel from left */
 533.996 +    cur0 = cur1 = cur2 = 0;
 533.997 +    /* and no error propagated to row below yet */
 533.998 +    belowerr0 = belowerr1 = belowerr2 = 0;
 533.999 +    bpreverr0 = bpreverr1 = bpreverr2 = 0;
533.1000 +
533.1001 +    for (col = width; col > 0; col--) {
533.1002 +      /* curN holds the error propagated from the previous pixel on the
533.1003 +       * current line.  Add the error propagated from the previous line
533.1004 +       * to form the complete error correction term for this pixel, and
533.1005 +       * round the error term (which is expressed * 16) to an integer.
533.1006 +       * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
533.1007 +       * for either sign of the error value.
533.1008 +       * Note: errorptr points to *previous* column's array entry.
533.1009 +       */
533.1010 +      cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4);
533.1011 +      cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4);
533.1012 +      cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4);
533.1013 +      /* Limit the error using transfer function set by init_error_limit.
533.1014 +       * See comments with init_error_limit for rationale.
533.1015 +       */
533.1016 +      cur0 = error_limit[cur0];
533.1017 +      cur1 = error_limit[cur1];
533.1018 +      cur2 = error_limit[cur2];
533.1019 +      /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
533.1020 +       * The maximum error is +- MAXJSAMPLE (or less with error limiting);
533.1021 +       * this sets the required size of the range_limit array.
533.1022 +       */
533.1023 +      cur0 += GETJSAMPLE(inptr[0]);
533.1024 +      cur1 += GETJSAMPLE(inptr[1]);
533.1025 +      cur2 += GETJSAMPLE(inptr[2]);
533.1026 +      cur0 = GETJSAMPLE(range_limit[cur0]);
533.1027 +      cur1 = GETJSAMPLE(range_limit[cur1]);
533.1028 +      cur2 = GETJSAMPLE(range_limit[cur2]);
533.1029 +      /* Index into the cache with adjusted pixel value */
533.1030 +      cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT];
533.1031 +      /* If we have not seen this color before, find nearest colormap */
533.1032 +      /* entry and update the cache */
533.1033 +      if (*cachep == 0)
533.1034 +	fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT);
533.1035 +      /* Now emit the colormap index for this cell */
533.1036 +      { register int pixcode = *cachep - 1;
533.1037 +	*outptr = (JSAMPLE) pixcode;
533.1038 +	/* Compute representation error for this pixel */
533.1039 +	cur0 -= GETJSAMPLE(colormap0[pixcode]);
533.1040 +	cur1 -= GETJSAMPLE(colormap1[pixcode]);
533.1041 +	cur2 -= GETJSAMPLE(colormap2[pixcode]);
533.1042 +      }
533.1043 +      /* Compute error fractions to be propagated to adjacent pixels.
533.1044 +       * Add these into the running sums, and simultaneously shift the
533.1045 +       * next-line error sums left by 1 column.
533.1046 +       */
533.1047 +      { register LOCFSERROR bnexterr, delta;
533.1048 +
533.1049 +	bnexterr = cur0;	/* Process component 0 */
533.1050 +	delta = cur0 * 2;
533.1051 +	cur0 += delta;		/* form error * 3 */
533.1052 +	errorptr[0] = (FSERROR) (bpreverr0 + cur0);
533.1053 +	cur0 += delta;		/* form error * 5 */
533.1054 +	bpreverr0 = belowerr0 + cur0;
533.1055 +	belowerr0 = bnexterr;
533.1056 +	cur0 += delta;		/* form error * 7 */
533.1057 +	bnexterr = cur1;	/* Process component 1 */
533.1058 +	delta = cur1 * 2;
533.1059 +	cur1 += delta;		/* form error * 3 */
533.1060 +	errorptr[1] = (FSERROR) (bpreverr1 + cur1);
533.1061 +	cur1 += delta;		/* form error * 5 */
533.1062 +	bpreverr1 = belowerr1 + cur1;
533.1063 +	belowerr1 = bnexterr;
533.1064 +	cur1 += delta;		/* form error * 7 */
533.1065 +	bnexterr = cur2;	/* Process component 2 */
533.1066 +	delta = cur2 * 2;
533.1067 +	cur2 += delta;		/* form error * 3 */
533.1068 +	errorptr[2] = (FSERROR) (bpreverr2 + cur2);
533.1069 +	cur2 += delta;		/* form error * 5 */
533.1070 +	bpreverr2 = belowerr2 + cur2;
533.1071 +	belowerr2 = bnexterr;
533.1072 +	cur2 += delta;		/* form error * 7 */
533.1073 +      }
533.1074 +      /* At this point curN contains the 7/16 error value to be propagated
533.1075 +       * to the next pixel on the current line, and all the errors for the
533.1076 +       * next line have been shifted over.  We are therefore ready to move on.
533.1077 +       */
533.1078 +      inptr += dir3;		/* Advance pixel pointers to next column */
533.1079 +      outptr += dir;
533.1080 +      errorptr += dir3;		/* advance errorptr to current column */
533.1081 +    }
533.1082 +    /* Post-loop cleanup: we must unload the final error values into the
533.1083 +     * final fserrors[] entry.  Note we need not unload belowerrN because
533.1084 +     * it is for the dummy column before or after the actual array.
533.1085 +     */
533.1086 +    errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */
533.1087 +    errorptr[1] = (FSERROR) bpreverr1;
533.1088 +    errorptr[2] = (FSERROR) bpreverr2;
533.1089 +  }
533.1090 +}
533.1091 +
533.1092 +
533.1093 +/*
533.1094 + * Initialize the error-limiting transfer function (lookup table).
533.1095 + * The raw F-S error computation can potentially compute error values of up to
533.1096 + * +- MAXJSAMPLE.  But we want the maximum correction applied to a pixel to be
533.1097 + * much less, otherwise obviously wrong pixels will be created.  (Typical
533.1098 + * effects include weird fringes at color-area boundaries, isolated bright
533.1099 + * pixels in a dark area, etc.)  The standard advice for avoiding this problem
533.1100 + * is to ensure that the "corners" of the color cube are allocated as output
533.1101 + * colors; then repeated errors in the same direction cannot cause cascading
533.1102 + * error buildup.  However, that only prevents the error from getting
533.1103 + * completely out of hand; Aaron Giles reports that error limiting improves
533.1104 + * the results even with corner colors allocated.
533.1105 + * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
533.1106 + * well, but the smoother transfer function used below is even better.  Thanks
533.1107 + * to Aaron Giles for this idea.
533.1108 + */
533.1109 +
533.1110 +LOCAL(void)
533.1111 +init_error_limit (j_decompress_ptr cinfo)
533.1112 +/* Allocate and fill in the error_limiter table */
533.1113 +{
533.1114 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
533.1115 +  int * table;
533.1116 +  int in, out;
533.1117 +
533.1118 +  table = (int *) (*cinfo->mem->alloc_small)
533.1119 +    ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int));
533.1120 +  table += MAXJSAMPLE;		/* so can index -MAXJSAMPLE .. +MAXJSAMPLE */
533.1121 +  cquantize->error_limiter = table;
533.1122 +
533.1123 +#define STEPSIZE ((MAXJSAMPLE+1)/16)
533.1124 +  /* Map errors 1:1 up to +- MAXJSAMPLE/16 */
533.1125 +  out = 0;
533.1126 +  for (in = 0; in < STEPSIZE; in++, out++) {
533.1127 +    table[in] = out; table[-in] = -out;
533.1128 +  }
533.1129 +  /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
533.1130 +  for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) {
533.1131 +    table[in] = out; table[-in] = -out;
533.1132 +  }
533.1133 +  /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
533.1134 +  for (; in <= MAXJSAMPLE; in++) {
533.1135 +    table[in] = out; table[-in] = -out;
533.1136 +  }
533.1137 +#undef STEPSIZE
533.1138 +}
533.1139 +
533.1140 +
533.1141 +/*
533.1142 + * Finish up at the end of each pass.
533.1143 + */
533.1144 +
533.1145 +METHODDEF(void)
533.1146 +finish_pass1 (j_decompress_ptr cinfo)
533.1147 +{
533.1148 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
533.1149 +
533.1150 +  /* Select the representative colors and fill in cinfo->colormap */
533.1151 +  cinfo->colormap = cquantize->sv_colormap;
533.1152 +  select_colors(cinfo, cquantize->desired);
533.1153 +  /* Force next pass to zero the color index table */
533.1154 +  cquantize->needs_zeroed = TRUE;
533.1155 +}
533.1156 +
533.1157 +
533.1158 +METHODDEF(void)
533.1159 +finish_pass2 (j_decompress_ptr cinfo)
533.1160 +{
533.1161 +  /* no work */
533.1162 +}
533.1163 +
533.1164 +
533.1165 +/*
533.1166 + * Initialize for each processing pass.
533.1167 + */
533.1168 +
533.1169 +METHODDEF(void)
533.1170 +start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
533.1171 +{
533.1172 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
533.1173 +  hist3d histogram = cquantize->histogram;
533.1174 +  int i;
533.1175 +
533.1176 +  /* Only F-S dithering or no dithering is supported. */
533.1177 +  /* If user asks for ordered dither, give him F-S. */
533.1178 +  if (cinfo->dither_mode != JDITHER_NONE)
533.1179 +    cinfo->dither_mode = JDITHER_FS;
533.1180 +
533.1181 +  if (is_pre_scan) {
533.1182 +    /* Set up method pointers */
533.1183 +    cquantize->pub.color_quantize = prescan_quantize;
533.1184 +    cquantize->pub.finish_pass = finish_pass1;
533.1185 +    cquantize->needs_zeroed = TRUE; /* Always zero histogram */
533.1186 +  } else {
533.1187 +    /* Set up method pointers */
533.1188 +    if (cinfo->dither_mode == JDITHER_FS)
533.1189 +      cquantize->pub.color_quantize = pass2_fs_dither;
533.1190 +    else
533.1191 +      cquantize->pub.color_quantize = pass2_no_dither;
533.1192 +    cquantize->pub.finish_pass = finish_pass2;
533.1193 +
533.1194 +    /* Make sure color count is acceptable */
533.1195 +    i = cinfo->actual_number_of_colors;
533.1196 +    if (i < 1)
533.1197 +      ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1);
533.1198 +    if (i > MAXNUMCOLORS)
533.1199 +      ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
533.1200 +
533.1201 +    if (cinfo->dither_mode == JDITHER_FS) {
533.1202 +      size_t arraysize = (size_t) ((cinfo->output_width + 2) *
533.1203 +				   (3 * SIZEOF(FSERROR)));
533.1204 +      /* Allocate Floyd-Steinberg workspace if we didn't already. */
533.1205 +      if (cquantize->fserrors == NULL)
533.1206 +	cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
533.1207 +	  ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
533.1208 +      /* Initialize the propagated errors to zero. */
533.1209 +      jzero_far((void FAR *) cquantize->fserrors, arraysize);
533.1210 +      /* Make the error-limit table if we didn't already. */
533.1211 +      if (cquantize->error_limiter == NULL)
533.1212 +	init_error_limit(cinfo);
533.1213 +      cquantize->on_odd_row = FALSE;
533.1214 +    }
533.1215 +
533.1216 +  }
533.1217 +  /* Zero the histogram or inverse color map, if necessary */
533.1218 +  if (cquantize->needs_zeroed) {
533.1219 +    for (i = 0; i < HIST_C0_ELEMS; i++) {
533.1220 +      jzero_far((void FAR *) histogram[i],
533.1221 +		HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
533.1222 +    }
533.1223 +    cquantize->needs_zeroed = FALSE;
533.1224 +  }
533.1225 +}
533.1226 +
533.1227 +
533.1228 +/*
533.1229 + * Switch to a new external colormap between output passes.
533.1230 + */
533.1231 +
533.1232 +METHODDEF(void)
533.1233 +new_color_map_2_quant (j_decompress_ptr cinfo)
533.1234 +{
533.1235 +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
533.1236 +
533.1237 +  /* Reset the inverse color map */
533.1238 +  cquantize->needs_zeroed = TRUE;
533.1239 +}
533.1240 +
533.1241 +
533.1242 +/*
533.1243 + * Module initialization routine for 2-pass color quantization.
533.1244 + */
533.1245 +
533.1246 +GLOBAL(void)
533.1247 +jinit_2pass_quantizer (j_decompress_ptr cinfo)
533.1248 +{
533.1249 +  my_cquantize_ptr cquantize;
533.1250 +  int i;
533.1251 +
533.1252 +  cquantize = (my_cquantize_ptr)
533.1253 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
533.1254 +				SIZEOF(my_cquantizer));
533.1255 +  cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
533.1256 +  cquantize->pub.start_pass = start_pass_2_quant;
533.1257 +  cquantize->pub.new_color_map = new_color_map_2_quant;
533.1258 +  cquantize->fserrors = NULL;	/* flag optional arrays not allocated */
533.1259 +  cquantize->error_limiter = NULL;
533.1260 +
533.1261 +  /* Make sure jdmaster didn't give me a case I can't handle */
533.1262 +  if (cinfo->out_color_components != 3)
533.1263 +    ERREXIT(cinfo, JERR_NOTIMPL);
533.1264 +
533.1265 +  /* Allocate the histogram/inverse colormap storage */
533.1266 +  cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small)
533.1267 +    ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d));
533.1268 +  for (i = 0; i < HIST_C0_ELEMS; i++) {
533.1269 +    cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large)
533.1270 +      ((j_common_ptr) cinfo, JPOOL_IMAGE,
533.1271 +       HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
533.1272 +  }
533.1273 +  cquantize->needs_zeroed = TRUE; /* histogram is garbage now */
533.1274 +
533.1275 +  /* Allocate storage for the completed colormap, if required.
533.1276 +   * We do this now since it is FAR storage and may affect
533.1277 +   * the memory manager's space calculations.
533.1278 +   */
533.1279 +  if (cinfo->enable_2pass_quant) {
533.1280 +    /* Make sure color count is acceptable */
533.1281 +    int desired = cinfo->desired_number_of_colors;
533.1282 +    /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
533.1283 +    if (desired < 8)
533.1284 +      ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
533.1285 +    /* Make sure colormap indexes can be represented by JSAMPLEs */
533.1286 +    if (desired > MAXNUMCOLORS)
533.1287 +      ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
533.1288 +    cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
533.1289 +      ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3);
533.1290 +    cquantize->desired = desired;
533.1291 +  } else
533.1292 +    cquantize->sv_colormap = NULL;
533.1293 +
533.1294 +  /* Only F-S dithering or no dithering is supported. */
533.1295 +  /* If user asks for ordered dither, give him F-S. */
533.1296 +  if (cinfo->dither_mode != JDITHER_NONE)
533.1297 +    cinfo->dither_mode = JDITHER_FS;
533.1298 +
533.1299 +  /* Allocate Floyd-Steinberg workspace if necessary.
533.1300 +   * This isn't really needed until pass 2, but again it is FAR storage.
533.1301 +   * Although we will cope with a later change in dither_mode,
533.1302 +   * we do not promise to honor max_memory_to_use if dither_mode changes.
533.1303 +   */
533.1304 +  if (cinfo->dither_mode == JDITHER_FS) {
533.1305 +    cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
533.1306 +      ((j_common_ptr) cinfo, JPOOL_IMAGE,
533.1307 +       (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR))));
533.1308 +    /* Might as well create the error-limiting table too. */
533.1309 +    init_error_limit(cinfo);
533.1310 +  }
533.1311 +}
533.1312 +
533.1313 +#endif /* QUANT_2PASS_SUPPORTED */
   534.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   534.2 +++ b/libs/libjpeg/jutils.c	Sat Feb 01 19:58:19 2014 +0200
   534.3 @@ -0,0 +1,179 @@
   534.4 +/*
   534.5 + * jutils.c
   534.6 + *
   534.7 + * Copyright (C) 1991-1996, Thomas G. Lane.
   534.8 + * This file is part of the Independent JPEG Group's software.
   534.9 + * For conditions of distribution and use, see the accompanying README file.
  534.10 + *
  534.11 + * This file contains tables and miscellaneous utility routines needed
  534.12 + * for both compression and decompression.
  534.13 + * Note we prefix all global names with "j" to minimize conflicts with
  534.14 + * a surrounding application.
  534.15 + */
  534.16 +
  534.17 +#define JPEG_INTERNALS
  534.18 +#include "jinclude.h"
  534.19 +#include "jpeglib.h"
  534.20 +
  534.21 +
  534.22 +/*
  534.23 + * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
  534.24 + * of a DCT block read in natural order (left to right, top to bottom).
  534.25 + */
  534.26 +
  534.27 +#if 0				/* This table is not actually needed in v6a */
  534.28 +
  534.29 +const int jpeg_zigzag_order[DCTSIZE2] = {
  534.30 +   0,  1,  5,  6, 14, 15, 27, 28,
  534.31 +   2,  4,  7, 13, 16, 26, 29, 42,
  534.32 +   3,  8, 12, 17, 25, 30, 41, 43,
  534.33 +   9, 11, 18, 24, 31, 40, 44, 53,
  534.34 +  10, 19, 23, 32, 39, 45, 52, 54,
  534.35 +  20, 22, 33, 38, 46, 51, 55, 60,
  534.36 +  21, 34, 37, 47, 50, 56, 59, 61,
  534.37 +  35, 36, 48, 49, 57, 58, 62, 63
  534.38 +};
  534.39 +
  534.40 +#endif
  534.41 +
  534.42 +/*
  534.43 + * jpeg_natural_order[i] is the natural-order position of the i'th element
  534.44 + * of zigzag order.
  534.45 + *
  534.46 + * When reading corrupted data, the Huffman decoders could attempt
  534.47 + * to reference an entry beyond the end of this array (if the decoded
  534.48 + * zero run length reaches past the end of the block).  To prevent
  534.49 + * wild stores without adding an inner-loop test, we put some extra
  534.50 + * "63"s after the real entries.  This will cause the extra coefficient
  534.51 + * to be stored in location 63 of the block, not somewhere random.
  534.52 + * The worst case would be a run-length of 15, which means we need 16
  534.53 + * fake entries.
  534.54 + */
  534.55 +
  534.56 +const int jpeg_natural_order[DCTSIZE2+16] = {
  534.57 +  0,  1,  8, 16,  9,  2,  3, 10,
  534.58 + 17, 24, 32, 25, 18, 11,  4,  5,
  534.59 + 12, 19, 26, 33, 40, 48, 41, 34,
  534.60 + 27, 20, 13,  6,  7, 14, 21, 28,
  534.61 + 35, 42, 49, 56, 57, 50, 43, 36,
  534.62 + 29, 22, 15, 23, 30, 37, 44, 51,
  534.63 + 58, 59, 52, 45, 38, 31, 39, 46,
  534.64 + 53, 60, 61, 54, 47, 55, 62, 63,
  534.65 + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
  534.66 + 63, 63, 63, 63, 63, 63, 63, 63
  534.67 +};
  534.68 +
  534.69 +
  534.70 +/*
  534.71 + * Arithmetic utilities
  534.72 + */
  534.73 +
  534.74 +GLOBAL(long)
  534.75 +jdiv_round_up (long a, long b)
  534.76 +/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
  534.77 +/* Assumes a >= 0, b > 0 */
  534.78 +{
  534.79 +  return (a + b - 1L) / b;
  534.80 +}
  534.81 +
  534.82 +
  534.83 +GLOBAL(long)
  534.84 +jround_up (long a, long b)
  534.85 +/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
  534.86 +/* Assumes a >= 0, b > 0 */
  534.87 +{
  534.88 +  a += b - 1L;
  534.89 +  return a - (a % b);
  534.90 +}
  534.91 +
  534.92 +
  534.93 +/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
  534.94 + * and coefficient-block arrays.  This won't work on 80x86 because the arrays
  534.95 + * are FAR and we're assuming a small-pointer memory model.  However, some
  534.96 + * DOS compilers provide far-pointer versions of memcpy() and memset() even
  534.97 + * in the small-model libraries.  These will be used if USE_FMEM is defined.
  534.98 + * Otherwise, the routines below do it the hard way.  (The performance cost
  534.99 + * is not all that great, because these routines aren't very heavily used.)
 534.100 + */
 534.101 +
 534.102 +#ifndef NEED_FAR_POINTERS	/* normal case, same as regular macros */
 534.103 +#define FMEMCOPY(dest,src,size)	MEMCOPY(dest,src,size)
 534.104 +#define FMEMZERO(target,size)	MEMZERO(target,size)
 534.105 +#else				/* 80x86 case, define if we can */
 534.106 +#ifdef USE_FMEM
 534.107 +#define FMEMCOPY(dest,src,size)	_fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
 534.108 +#define FMEMZERO(target,size)	_fmemset((void FAR *)(target), 0, (size_t)(size))
 534.109 +#endif
 534.110 +#endif
 534.111 +
 534.112 +
 534.113 +GLOBAL(void)
 534.114 +jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
 534.115 +		   JSAMPARRAY output_array, int dest_row,
 534.116 +		   int num_rows, JDIMENSION num_cols)
 534.117 +/* Copy some rows of samples from one place to another.
 534.118 + * num_rows rows are copied from input_array[source_row++]
 534.119 + * to output_array[dest_row++]; these areas may overlap for duplication.
 534.120 + * The source and destination arrays must be at least as wide as num_cols.
 534.121 + */
 534.122 +{
 534.123 +  register JSAMPROW inptr, outptr;
 534.124 +#ifdef FMEMCOPY
 534.125 +  register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
 534.126 +#else
 534.127 +  register JDIMENSION count;
 534.128 +#endif
 534.129 +  register int row;
 534.130 +
 534.131 +  input_array += source_row;
 534.132 +  output_array += dest_row;
 534.133 +
 534.134 +  for (row = num_rows; row > 0; row--) {
 534.135 +    inptr = *input_array++;
 534.136 +    outptr = *output_array++;
 534.137 +#ifdef FMEMCOPY
 534.138 +    FMEMCOPY(outptr, inptr, count);
 534.139 +#else
 534.140 +    for (count = num_cols; count > 0; count--)
 534.141 +      *outptr++ = *inptr++;	/* needn't bother with GETJSAMPLE() here */
 534.142 +#endif
 534.143 +  }
 534.144 +}
 534.145 +
 534.146 +
 534.147 +GLOBAL(void)
 534.148 +jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
 534.149 +		 JDIMENSION num_blocks)
 534.150 +/* Copy a row of coefficient blocks from one place to another. */
 534.151 +{
 534.152 +#ifdef FMEMCOPY
 534.153 +  FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
 534.154 +#else
 534.155 +  register JCOEFPTR inptr, outptr;
 534.156 +  register long count;
 534.157 +
 534.158 +  inptr = (JCOEFPTR) input_row;
 534.159 +  outptr = (JCOEFPTR) output_row;
 534.160 +  for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
 534.161 +    *outptr++ = *inptr++;
 534.162 +  }
 534.163 +#endif
 534.164 +}
 534.165 +
 534.166 +
 534.167 +GLOBAL(void)
 534.168 +jzero_far (void FAR * target, size_t bytestozero)
 534.169 +/* Zero out a chunk of FAR memory. */
 534.170 +/* This might be sample-array data, block-array data, or alloc_large data. */
 534.171 +{
 534.172 +#ifdef FMEMZERO
 534.173 +  FMEMZERO(target, bytestozero);
 534.174 +#else
 534.175 +  register char FAR * ptr = (char FAR *) target;
 534.176 +  register size_t count;
 534.177 +
 534.178 +  for (count = bytestozero; count > 0; count--) {
 534.179 +    *ptr++ = 0;
 534.180 +  }
 534.181 +#endif
 534.182 +}
   535.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   535.2 +++ b/libs/libjpeg/jversion.h	Sat Feb 01 19:58:19 2014 +0200
   535.3 @@ -0,0 +1,14 @@
   535.4 +/*
   535.5 + * jversion.h
   535.6 + *
   535.7 + * Copyright (C) 1991-1998, Thomas G. Lane.
   535.8 + * This file is part of the Independent JPEG Group's software.
   535.9 + * For conditions of distribution and use, see the accompanying README file.
  535.10 + *
  535.11 + * This file contains software version identification.
  535.12 + */
  535.13 +
  535.14 +
  535.15 +#define JVERSION	"6b  27-Mar-1998"
  535.16 +
  535.17 +#define JCOPYRIGHT	"Copyright (C) 1998, Thomas G. Lane"
   536.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   536.2 +++ b/libs/libpng/LICENSE	Sat Feb 01 19:58:19 2014 +0200
   536.3 @@ -0,0 +1,111 @@
   536.4 +
   536.5 +This copy of the libpng notices is provided for your convenience.  In case of
   536.6 +any discrepancy between this copy and the notices in the file png.h that is
   536.7 +included in the libpng distribution, the latter shall prevail.
   536.8 +
   536.9 +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
  536.10 +
  536.11 +If you modify libpng you may insert additional notices immediately following
  536.12 +this sentence.
  536.13 +
  536.14 +This code is released under the libpng license.
  536.15 +
  536.16 +libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are
  536.17 +Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are
  536.18 +distributed according to the same disclaimer and license as libpng-1.2.5
  536.19 +with the following individual added to the list of Contributing Authors
  536.20 +
  536.21 +   Cosmin Truta
  536.22 +
  536.23 +libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
  536.24 +Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
  536.25 +distributed according to the same disclaimer and license as libpng-1.0.6
  536.26 +with the following individuals added to the list of Contributing Authors
  536.27 +
  536.28 +   Simon-Pierre Cadieux
  536.29 +   Eric S. Raymond
  536.30 +   Gilles Vollant
  536.31 +
  536.32 +and with the following additions to the disclaimer:
  536.33 +
  536.34 +   There is no warranty against interference with your enjoyment of the
  536.35 +   library or against infringement.  There is no warranty that our
  536.36 +   efforts or the library will fulfill any of your particular purposes
  536.37 +   or needs.  This library is provided with all faults, and the entire
  536.38 +   risk of satisfactory quality, performance, accuracy, and effort is with
  536.39 +   the user.
  536.40 +
  536.41 +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
  536.42 +Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
  536.43 +distributed according to the same disclaimer and license as libpng-0.96,
  536.44 +with the following individuals added to the list of Contributing Authors:
  536.45 +
  536.46 +   Tom Lane
  536.47 +   Glenn Randers-Pehrson
  536.48 +   Willem van Schaik
  536.49 +
  536.50 +libpng versions 0.89, June 1996, through 0.96, May 1997, are
  536.51 +Copyright (c) 1996, 1997 Andreas Dilger
  536.52 +Distributed according to the same disclaimer and license as libpng-0.88,
  536.53 +with the following individuals added to the list of Contributing Authors:
  536.54 +
  536.55 +   John Bowler
  536.56 +   Kevin Bracey
  536.57 +   Sam Bushell
  536.58 +   Magnus Holmgren
  536.59 +   Greg Roelofs
  536.60 +   Tom Tanner
  536.61 +
  536.62 +libpng versions 0.5, May 1995, through 0.88, January 1996, are
  536.63 +Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  536.64 +
  536.65 +For the purposes of this copyright and license, "Contributing Authors"
  536.66 +is defined as the following set of individuals:
  536.67 +
  536.68 +   Andreas Dilger
  536.69 +   Dave Martindale
  536.70 +   Guy Eric Schalnat
  536.71 +   Paul Schmidt
  536.72 +   Tim Wegner
  536.73 +
  536.74 +The PNG Reference Library is supplied "AS IS".  The Contributing Authors
  536.75 +and Group 42, Inc. disclaim all warranties, expressed or implied,
  536.76 +including, without limitation, the warranties of merchantability and of
  536.77 +fitness for any purpose.  The Contributing Authors and Group 42, Inc.
  536.78 +assume no liability for direct, indirect, incidental, special, exemplary,
  536.79 +or consequential damages, which may result from the use of the PNG
  536.80 +Reference Library, even if advised of the possibility of such damage.
  536.81 +
  536.82 +Permission is hereby granted to use, copy, modify, and distribute this
  536.83 +source code, or portions hereof, for any purpose, without fee, subject
  536.84 +to the following restrictions:
  536.85 +
  536.86 +1. The origin of this source code must not be misrepresented.
  536.87 +
  536.88 +2. Altered versions must be plainly marked as such and must not
  536.89 +   be misrepresented as being the original source.
  536.90 +
  536.91 +3. This Copyright notice may not be removed or altered from any
  536.92 +   source or altered source distribution.
  536.93 +
  536.94 +The Contributing Authors and Group 42, Inc. specifically permit, without
  536.95 +fee, and encourage the use of this source code as a component to
  536.96 +supporting the PNG file format in commercial products.  If you use this
  536.97 +source code in a product, acknowledgment is not required but would be
  536.98 +appreciated.
  536.99 +
 536.100 +
 536.101 +A "png_get_copyright" function is available, for convenient use in "about"
 536.102 +boxes and the like:
 536.103 +
 536.104 +   printf("%s",png_get_copyright(NULL));
 536.105 +
 536.106 +Also, the PNG logo (in PNG format, of course) is supplied in the
 536.107 +files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
 536.108 +
 536.109 +Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
 536.110 +certification mark of the Open Source Initiative.
 536.111 +
 536.112 +Glenn Randers-Pehrson
 536.113 +glennrp at users.sourceforge.net
 536.114 +July 7, 2011
   537.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   537.2 +++ b/libs/libpng/png.c	Sat Feb 01 19:58:19 2014 +0200
   537.3 @@ -0,0 +1,799 @@
   537.4 +
   537.5 +/* png.c - location for general purpose libpng functions
   537.6 + *
   537.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   537.8 + * For conditions of distribution and use, see copyright notice in png.h
   537.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  537.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  537.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  537.12 + */
  537.13 +
  537.14 +#define PNG_INTERNAL
  537.15 +#define PNG_NO_EXTERN
  537.16 +#include "png.h"
  537.17 +
  537.18 +/* Generate a compiler error if there is an old png.h in the search path. */
  537.19 +typedef version_1_2_33 Your_png_h_is_not_version_1_2_33;
  537.20 +
  537.21 +/* Version information for C files.  This had better match the version
  537.22 + * string defined in png.h.  */
  537.23 +
  537.24 +#ifdef PNG_USE_GLOBAL_ARRAYS
  537.25 +/* png_libpng_ver was changed to a function in version 1.0.5c */
  537.26 +PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
  537.27 +
  537.28 +#ifdef PNG_READ_SUPPORTED
  537.29 +
  537.30 +/* png_sig was changed to a function in version 1.0.5c */
  537.31 +/* Place to hold the signature string for a PNG file. */
  537.32 +PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
  537.33 +#endif /* PNG_READ_SUPPORTED */
  537.34 +
  537.35 +/* Invoke global declarations for constant strings for known chunk types */
  537.36 +PNG_IHDR;
  537.37 +PNG_IDAT;
  537.38 +PNG_IEND;
  537.39 +PNG_PLTE;
  537.40 +PNG_bKGD;
  537.41 +PNG_cHRM;
  537.42 +PNG_gAMA;
  537.43 +PNG_hIST;
  537.44 +PNG_iCCP;
  537.45 +PNG_iTXt;
  537.46 +PNG_oFFs;
  537.47 +PNG_pCAL;
  537.48 +PNG_sCAL;
  537.49 +PNG_pHYs;
  537.50 +PNG_sBIT;
  537.51 +PNG_sPLT;
  537.52 +PNG_sRGB;
  537.53 +PNG_tEXt;
  537.54 +PNG_tIME;
  537.55 +PNG_tRNS;
  537.56 +PNG_zTXt;
  537.57 +
  537.58 +#ifdef PNG_READ_SUPPORTED
  537.59 +/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  537.60 +
  537.61 +/* start of interlace block */
  537.62 +PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
  537.63 +
  537.64 +/* offset to next interlace block */
  537.65 +PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
  537.66 +
  537.67 +/* start of interlace block in the y direction */
  537.68 +PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
  537.69 +
  537.70 +/* offset to next interlace block in the y direction */
  537.71 +PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
  537.72 +
  537.73 +/* Height of interlace block.  This is not currently used - if you need
  537.74 + * it, uncomment it here and in png.h
  537.75 +PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
  537.76 +*/
  537.77 +
  537.78 +/* Mask to determine which pixels are valid in a pass */
  537.79 +PNG_CONST int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
  537.80 +
  537.81 +/* Mask to determine which pixels to overwrite while displaying */
  537.82 +PNG_CONST int FARDATA png_pass_dsp_mask[]
  537.83 +   = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
  537.84 +
  537.85 +#endif /* PNG_READ_SUPPORTED */
  537.86 +#endif /* PNG_USE_GLOBAL_ARRAYS */
  537.87 +
  537.88 +/* Tells libpng that we have already handled the first "num_bytes" bytes
  537.89 + * of the PNG file signature.  If the PNG data is embedded into another
  537.90 + * stream we can set num_bytes = 8 so that libpng will not attempt to read
  537.91 + * or write any of the magic bytes before it starts on the IHDR.
  537.92 + */
  537.93 +
  537.94 +#ifdef PNG_READ_SUPPORTED
  537.95 +void PNGAPI
  537.96 +png_set_sig_bytes(png_structp png_ptr, int num_bytes)
  537.97 +{
  537.98 +   if (png_ptr == NULL) return;
  537.99 +   png_debug(1, "in png_set_sig_bytes\n");
 537.100 +   if (num_bytes > 8)
 537.101 +      png_error(png_ptr, "Too many bytes for PNG signature.");
 537.102 +
 537.103 +   png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
 537.104 +}
 537.105 +
 537.106 +/* Checks whether the supplied bytes match the PNG signature.  We allow
 537.107 + * checking less than the full 8-byte signature so that those apps that
 537.108 + * already read the first few bytes of a file to determine the file type
 537.109 + * can simply check the remaining bytes for extra assurance.  Returns
 537.110 + * an integer less than, equal to, or greater than zero if sig is found,
 537.111 + * respectively, to be less than, to match, or be greater than the correct
 537.112 + * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
 537.113 + */
 537.114 +int PNGAPI
 537.115 +png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
 537.116 +{
 537.117 +   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
 537.118 +   if (num_to_check > 8)
 537.119 +      num_to_check = 8;
 537.120 +   else if (num_to_check < 1)
 537.121 +      return (-1);
 537.122 +
 537.123 +   if (start > 7)
 537.124 +      return (-1);
 537.125 +
 537.126 +   if (start + num_to_check > 8)
 537.127 +      num_to_check = 8 - start;
 537.128 +
 537.129 +   return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
 537.130 +}
 537.131 +
 537.132 +#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
 537.133 +/* (Obsolete) function to check signature bytes.  It does not allow one
 537.134 + * to check a partial signature.  This function might be removed in the
 537.135 + * future - use png_sig_cmp().  Returns true (nonzero) if the file is PNG.
 537.136 + */
 537.137 +int PNGAPI
 537.138 +png_check_sig(png_bytep sig, int num)
 537.139 +{
 537.140 +  return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
 537.141 +}
 537.142 +#endif
 537.143 +#endif /* PNG_READ_SUPPORTED */
 537.144 +
 537.145 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
 537.146 +/* Function to allocate memory for zlib and clear it to 0. */
 537.147 +#ifdef PNG_1_0_X
 537.148 +voidpf PNGAPI
 537.149 +#else
 537.150 +voidpf /* private */
 537.151 +#endif
 537.152 +png_zalloc(voidpf png_ptr, uInt items, uInt size)
 537.153 +{
 537.154 +   png_voidp ptr;
 537.155 +   png_structp p=(png_structp)png_ptr;
 537.156 +   png_uint_32 save_flags=p->flags;
 537.157 +   png_uint_32 num_bytes;
 537.158 +
 537.159 +   if (png_ptr == NULL) return (NULL);
 537.160 +   if (items > PNG_UINT_32_MAX/size)
 537.161 +   {
 537.162 +     png_warning (p, "Potential overflow in png_zalloc()");
 537.163 +     return (NULL);
 537.164 +   }
 537.165 +   num_bytes = (png_uint_32)items * size;
 537.166 +
 537.167 +   p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
 537.168 +   ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
 537.169 +   p->flags=save_flags;
 537.170 +
 537.171 +#if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
 537.172 +   if (ptr == NULL)
 537.173 +       return ((voidpf)ptr);
 537.174 +
 537.175 +   if (num_bytes > (png_uint_32)0x8000L)
 537.176 +   {
 537.177 +      png_memset(ptr, 0, (png_size_t)0x8000L);
 537.178 +      png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
 537.179 +         (png_size_t)(num_bytes - (png_uint_32)0x8000L));
 537.180 +   }
 537.181 +   else
 537.182 +   {
 537.183 +      png_memset(ptr, 0, (png_size_t)num_bytes);
 537.184 +   }
 537.185 +#endif
 537.186 +   return ((voidpf)ptr);
 537.187 +}
 537.188 +
 537.189 +/* function to free memory for zlib */
 537.190 +#ifdef PNG_1_0_X
 537.191 +void PNGAPI
 537.192 +#else
 537.193 +void /* private */
 537.194 +#endif
 537.195 +png_zfree(voidpf png_ptr, voidpf ptr)
 537.196 +{
 537.197 +   png_free((png_structp)png_ptr, (png_voidp)ptr);
 537.198 +}
 537.199 +
 537.200 +/* Reset the CRC variable to 32 bits of 1's.  Care must be taken
 537.201 + * in case CRC is > 32 bits to leave the top bits 0.
 537.202 + */
 537.203 +void /* PRIVATE */
 537.204 +png_reset_crc(png_structp png_ptr)
 537.205 +{
 537.206 +   png_ptr->crc = crc32(0, Z_NULL, 0);
 537.207 +}
 537.208 +
 537.209 +/* Calculate the CRC over a section of data.  We can only pass as
 537.210 + * much data to this routine as the largest single buffer size.  We
 537.211 + * also check that this data will actually be used before going to the
 537.212 + * trouble of calculating it.
 537.213 + */
 537.214 +void /* PRIVATE */
 537.215 +png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
 537.216 +{
 537.217 +   int need_crc = 1;
 537.218 +
 537.219 +   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
 537.220 +   {
 537.221 +      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
 537.222 +          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
 537.223 +         need_crc = 0;
 537.224 +   }
 537.225 +   else                                                    /* critical */
 537.226 +   {
 537.227 +      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
 537.228 +         need_crc = 0;
 537.229 +   }
 537.230 +
 537.231 +   if (need_crc)
 537.232 +      png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
 537.233 +}
 537.234 +
 537.235 +/* Allocate the memory for an info_struct for the application.  We don't
 537.236 + * really need the png_ptr, but it could potentially be useful in the
 537.237 + * future.  This should be used in favour of malloc(png_sizeof(png_info))
 537.238 + * and png_info_init() so that applications that want to use a shared
 537.239 + * libpng don't have to be recompiled if png_info changes size.
 537.240 + */
 537.241 +png_infop PNGAPI
 537.242 +png_create_info_struct(png_structp png_ptr)
 537.243 +{
 537.244 +   png_infop info_ptr;
 537.245 +
 537.246 +   png_debug(1, "in png_create_info_struct\n");
 537.247 +   if (png_ptr == NULL) return (NULL);
 537.248 +#ifdef PNG_USER_MEM_SUPPORTED
 537.249 +   info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
 537.250 +      png_ptr->malloc_fn, png_ptr->mem_ptr);
 537.251 +#else
 537.252 +   info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
 537.253 +#endif
 537.254 +   if (info_ptr != NULL)
 537.255 +      png_info_init_3(&info_ptr, png_sizeof(png_info));
 537.256 +
 537.257 +   return (info_ptr);
 537.258 +}
 537.259 +
 537.260 +/* This function frees the memory associated with a single info struct.
 537.261 + * Normally, one would use either png_destroy_read_struct() or
 537.262 + * png_destroy_write_struct() to free an info struct, but this may be
 537.263 + * useful for some applications.
 537.264 + */
 537.265 +void PNGAPI
 537.266 +png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
 537.267 +{
 537.268 +   png_infop info_ptr = NULL;
 537.269 +   if (png_ptr == NULL) return;
 537.270 +
 537.271 +   png_debug(1, "in png_destroy_info_struct\n");
 537.272 +   if (info_ptr_ptr != NULL)
 537.273 +      info_ptr = *info_ptr_ptr;
 537.274 +
 537.275 +   if (info_ptr != NULL)
 537.276 +   {
 537.277 +      png_info_destroy(png_ptr, info_ptr);
 537.278 +
 537.279 +#ifdef PNG_USER_MEM_SUPPORTED
 537.280 +      png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
 537.281 +          png_ptr->mem_ptr);
 537.282 +#else
 537.283 +      png_destroy_struct((png_voidp)info_ptr);
 537.284 +#endif
 537.285 +      *info_ptr_ptr = NULL;
 537.286 +   }
 537.287 +}
 537.288 +
 537.289 +/* Initialize the info structure.  This is now an internal function (0.89)
 537.290 + * and applications using it are urged to use png_create_info_struct()
 537.291 + * instead.
 537.292 + */
 537.293 +#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
 537.294 +#undef png_info_init
 537.295 +void PNGAPI
 537.296 +png_info_init(png_infop info_ptr)
 537.297 +{
 537.298 +   /* We only come here via pre-1.0.12-compiled applications */
 537.299 +   png_info_init_3(&info_ptr, 0);
 537.300 +}
 537.301 +#endif
 537.302 +
 537.303 +void PNGAPI
 537.304 +png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
 537.305 +{
 537.306 +   png_infop info_ptr = *ptr_ptr;
 537.307 +
 537.308 +   if (info_ptr == NULL) return;
 537.309 +
 537.310 +   png_debug(1, "in png_info_init_3\n");
 537.311 +
 537.312 +   if (png_sizeof(png_info) > png_info_struct_size)
 537.313 +     {
 537.314 +       png_destroy_struct(info_ptr);
 537.315 +       info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
 537.316 +       *ptr_ptr = info_ptr;
 537.317 +     }
 537.318 +
 537.319 +   /* set everything to 0 */
 537.320 +   png_memset(info_ptr, 0, png_sizeof(png_info));
 537.321 +}
 537.322 +
 537.323 +#ifdef PNG_FREE_ME_SUPPORTED
 537.324 +void PNGAPI
 537.325 +png_data_freer(png_structp png_ptr, png_infop info_ptr,
 537.326 +   int freer, png_uint_32 mask)
 537.327 +{
 537.328 +   png_debug(1, "in png_data_freer\n");
 537.329 +   if (png_ptr == NULL || info_ptr == NULL)
 537.330 +      return;
 537.331 +   if (freer == PNG_DESTROY_WILL_FREE_DATA)
 537.332 +      info_ptr->free_me |= mask;
 537.333 +   else if (freer == PNG_USER_WILL_FREE_DATA)
 537.334 +      info_ptr->free_me &= ~mask;
 537.335 +   else
 537.336 +      png_warning(png_ptr,
 537.337 +         "Unknown freer parameter in png_data_freer.");
 537.338 +}
 537.339 +#endif
 537.340 +
 537.341 +void PNGAPI
 537.342 +png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
 537.343 +   int num)
 537.344 +{
 537.345 +   png_debug(1, "in png_free_data\n");
 537.346 +   if (png_ptr == NULL || info_ptr == NULL)
 537.347 +      return;
 537.348 +
 537.349 +#if defined(PNG_TEXT_SUPPORTED)
 537.350 +/* free text item num or (if num == -1) all text items */
 537.351 +#ifdef PNG_FREE_ME_SUPPORTED
 537.352 +if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
 537.353 +#else
 537.354 +if (mask & PNG_FREE_TEXT)
 537.355 +#endif
 537.356 +{
 537.357 +   if (num != -1)
 537.358 +   {
 537.359 +     if (info_ptr->text && info_ptr->text[num].key)
 537.360 +     {
 537.361 +         png_free(png_ptr, info_ptr->text[num].key);
 537.362 +         info_ptr->text[num].key = NULL;
 537.363 +     }
 537.364 +   }
 537.365 +   else
 537.366 +   {
 537.367 +       int i;
 537.368 +       for (i = 0; i < info_ptr->num_text; i++)
 537.369 +           png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
 537.370 +       png_free(png_ptr, info_ptr->text);
 537.371 +       info_ptr->text = NULL;
 537.372 +       info_ptr->num_text=0;
 537.373 +   }
 537.374 +}
 537.375 +#endif
 537.376 +
 537.377 +#if defined(PNG_tRNS_SUPPORTED)
 537.378 +/* free any tRNS entry */
 537.379 +#ifdef PNG_FREE_ME_SUPPORTED
 537.380 +if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
 537.381 +#else
 537.382 +if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
 537.383 +#endif
 537.384 +{
 537.385 +    png_free(png_ptr, info_ptr->trans);
 537.386 +    info_ptr->trans = NULL;
 537.387 +    info_ptr->valid &= ~PNG_INFO_tRNS;
 537.388 +#ifndef PNG_FREE_ME_SUPPORTED
 537.389 +    png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
 537.390 +#endif
 537.391 +}
 537.392 +#endif
 537.393 +
 537.394 +#if defined(PNG_sCAL_SUPPORTED)
 537.395 +/* free any sCAL entry */
 537.396 +#ifdef PNG_FREE_ME_SUPPORTED
 537.397 +if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
 537.398 +#else
 537.399 +if (mask & PNG_FREE_SCAL)
 537.400 +#endif
 537.401 +{
 537.402 +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
 537.403 +    png_free(png_ptr, info_ptr->scal_s_width);
 537.404 +    png_free(png_ptr, info_ptr->scal_s_height);
 537.405 +    info_ptr->scal_s_width = NULL;
 537.406 +    info_ptr->scal_s_height = NULL;
 537.407 +#endif
 537.408 +    info_ptr->valid &= ~PNG_INFO_sCAL;
 537.409 +}
 537.410 +#endif
 537.411 +
 537.412 +#if defined(PNG_pCAL_SUPPORTED)
 537.413 +/* free any pCAL entry */
 537.414 +#ifdef PNG_FREE_ME_SUPPORTED
 537.415 +if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
 537.416 +#else
 537.417 +if (mask & PNG_FREE_PCAL)
 537.418 +#endif
 537.419 +{
 537.420 +    png_free(png_ptr, info_ptr->pcal_purpose);
 537.421 +    png_free(png_ptr, info_ptr->pcal_units);
 537.422 +    info_ptr->pcal_purpose = NULL;
 537.423 +    info_ptr->pcal_units = NULL;
 537.424 +    if (info_ptr->pcal_params != NULL)
 537.425 +    {
 537.426 +        int i;
 537.427 +        for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
 537.428 +        {
 537.429 +          png_free(png_ptr, info_ptr->pcal_params[i]);
 537.430 +          info_ptr->pcal_params[i]=NULL;
 537.431 +        }
 537.432 +        png_free(png_ptr, info_ptr->pcal_params);
 537.433 +        info_ptr->pcal_params = NULL;
 537.434 +    }
 537.435 +    info_ptr->valid &= ~PNG_INFO_pCAL;
 537.436 +}
 537.437 +#endif
 537.438 +
 537.439 +#if defined(PNG_iCCP_SUPPORTED)
 537.440 +/* free any iCCP entry */
 537.441 +#ifdef PNG_FREE_ME_SUPPORTED
 537.442 +if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
 537.443 +#else
 537.444 +if (mask & PNG_FREE_ICCP)
 537.445 +#endif
 537.446 +{
 537.447 +    png_free(png_ptr, info_ptr->iccp_name);
 537.448 +    png_free(png_ptr, info_ptr->iccp_profile);
 537.449 +    info_ptr->iccp_name = NULL;
 537.450 +    info_ptr->iccp_profile = NULL;
 537.451 +    info_ptr->valid &= ~PNG_INFO_iCCP;
 537.452 +}
 537.453 +#endif
 537.454 +
 537.455 +#if defined(PNG_sPLT_SUPPORTED)
 537.456 +/* free a given sPLT entry, or (if num == -1) all sPLT entries */
 537.457 +#ifdef PNG_FREE_ME_SUPPORTED
 537.458 +if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
 537.459 +#else
 537.460 +if (mask & PNG_FREE_SPLT)
 537.461 +#endif
 537.462 +{
 537.463 +   if (num != -1)
 537.464 +   {
 537.465 +      if (info_ptr->splt_palettes)
 537.466 +      {
 537.467 +          png_free(png_ptr, info_ptr->splt_palettes[num].name);
 537.468 +          png_free(png_ptr, info_ptr->splt_palettes[num].entries);
 537.469 +          info_ptr->splt_palettes[num].name = NULL;
 537.470 +          info_ptr->splt_palettes[num].entries = NULL;
 537.471 +      }
 537.472 +   }
 537.473 +   else
 537.474 +   {
 537.475 +       if (info_ptr->splt_palettes_num)
 537.476 +       {
 537.477 +         int i;
 537.478 +         for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
 537.479 +            png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
 537.480 +
 537.481 +         png_free(png_ptr, info_ptr->splt_palettes);
 537.482 +         info_ptr->splt_palettes = NULL;
 537.483 +         info_ptr->splt_palettes_num = 0;
 537.484 +       }
 537.485 +       info_ptr->valid &= ~PNG_INFO_sPLT;
 537.486 +   }
 537.487 +}
 537.488 +#endif
 537.489 +
 537.490 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
 537.491 +  if (png_ptr->unknown_chunk.data)
 537.492 +  {
 537.493 +    png_free(png_ptr, png_ptr->unknown_chunk.data);
 537.494 +    png_ptr->unknown_chunk.data = NULL;
 537.495 +  }
 537.496 +
 537.497 +#ifdef PNG_FREE_ME_SUPPORTED
 537.498 +if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
 537.499 +#else
 537.500 +if (mask & PNG_FREE_UNKN)
 537.501 +#endif
 537.502 +{
 537.503 +   if (num != -1)
 537.504 +   {
 537.505 +       if (info_ptr->unknown_chunks)
 537.506 +       {
 537.507 +          png_free(png_ptr, info_ptr->unknown_chunks[num].data);
 537.508 +          info_ptr->unknown_chunks[num].data = NULL;
 537.509 +       }
 537.510 +   }
 537.511 +   else
 537.512 +   {
 537.513 +       int i;
 537.514 +
 537.515 +       if (info_ptr->unknown_chunks_num)
 537.516 +       {
 537.517 +         for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
 537.518 +            png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
 537.519 +
 537.520 +         png_free(png_ptr, info_ptr->unknown_chunks);
 537.521 +         info_ptr->unknown_chunks = NULL;
 537.522 +         info_ptr->unknown_chunks_num = 0;
 537.523 +       }
 537.524 +   }
 537.525 +}
 537.526 +#endif
 537.527 +
 537.528 +#if defined(PNG_hIST_SUPPORTED)
 537.529 +/* free any hIST entry */
 537.530 +#ifdef PNG_FREE_ME_SUPPORTED
 537.531 +if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
 537.532 +#else
 537.533 +if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
 537.534 +#endif
 537.535 +{
 537.536 +    png_free(png_ptr, info_ptr->hist);
 537.537 +    info_ptr->hist = NULL;
 537.538 +    info_ptr->valid &= ~PNG_INFO_hIST;
 537.539 +#ifndef PNG_FREE_ME_SUPPORTED
 537.540 +    png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
 537.541 +#endif
 537.542 +}
 537.543 +#endif
 537.544 +
 537.545 +/* free any PLTE entry that was internally allocated */
 537.546 +#ifdef PNG_FREE_ME_SUPPORTED
 537.547 +if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
 537.548 +#else
 537.549 +if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
 537.550 +#endif
 537.551 +{
 537.552 +    png_zfree(png_ptr, info_ptr->palette);
 537.553 +    info_ptr->palette = NULL;
 537.554 +    info_ptr->valid &= ~PNG_INFO_PLTE;
 537.555 +#ifndef PNG_FREE_ME_SUPPORTED
 537.556 +    png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
 537.557 +#endif
 537.558 +    info_ptr->num_palette = 0;
 537.559 +}
 537.560 +
 537.561 +#if defined(PNG_INFO_IMAGE_SUPPORTED)
 537.562 +/* free any image bits attached to the info structure */
 537.563 +#ifdef PNG_FREE_ME_SUPPORTED
 537.564 +if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
 537.565 +#else
 537.566 +if (mask & PNG_FREE_ROWS)
 537.567 +#endif
 537.568 +{
 537.569 +    if (info_ptr->row_pointers)
 537.570 +    {
 537.571 +       int row;
 537.572 +       for (row = 0; row < (int)info_ptr->height; row++)
 537.573 +       {
 537.574 +          png_free(png_ptr, info_ptr->row_pointers[row]);
 537.575 +          info_ptr->row_pointers[row]=NULL;
 537.576 +       }
 537.577 +       png_free(png_ptr, info_ptr->row_pointers);
 537.578 +       info_ptr->row_pointers=NULL;
 537.579 +    }
 537.580 +    info_ptr->valid &= ~PNG_INFO_IDAT;
 537.581 +}
 537.582 +#endif
 537.583 +
 537.584 +#ifdef PNG_FREE_ME_SUPPORTED
 537.585 +   if (num == -1)
 537.586 +     info_ptr->free_me &= ~mask;
 537.587 +   else
 537.588 +     info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
 537.589 +#endif
 537.590 +}
 537.591 +
 537.592 +/* This is an internal routine to free any memory that the info struct is
 537.593 + * pointing to before re-using it or freeing the struct itself.  Recall
 537.594 + * that png_free() checks for NULL pointers for us.
 537.595 + */
 537.596 +void /* PRIVATE */
 537.597 +png_info_destroy(png_structp png_ptr, png_infop info_ptr)
 537.598 +{
 537.599 +   png_debug(1, "in png_info_destroy\n");
 537.600 +
 537.601 +   png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
 537.602 +
 537.603 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
 537.604 +   if (png_ptr->num_chunk_list)
 537.605 +   {
 537.606 +       png_free(png_ptr, png_ptr->chunk_list);
 537.607 +       png_ptr->chunk_list=NULL;
 537.608 +       png_ptr->num_chunk_list = 0;
 537.609 +   }
 537.610 +#endif
 537.611 +
 537.612 +   png_info_init_3(&info_ptr, png_sizeof(png_info));
 537.613 +}
 537.614 +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
 537.615 +
 537.616 +/* This function returns a pointer to the io_ptr associated with the user
 537.617 + * functions.  The application should free any memory associated with this
 537.618 + * pointer before png_write_destroy() or png_read_destroy() are called.
 537.619 + */
 537.620 +png_voidp PNGAPI
 537.621 +png_get_io_ptr(png_structp png_ptr)
 537.622 +{
 537.623 +   if (png_ptr == NULL) return (NULL);
 537.624 +   return (png_ptr->io_ptr);
 537.625 +}
 537.626 +
 537.627 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
 537.628 +#if !defined(PNG_NO_STDIO)
 537.629 +/* Initialize the default input/output functions for the PNG file.  If you
 537.630 + * use your own read or write routines, you can call either png_set_read_fn()
 537.631 + * or png_set_write_fn() instead of png_init_io().  If you have defined
 537.632 + * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
 537.633 + * necessarily available.
 537.634 + */
 537.635 +void PNGAPI
 537.636 +png_init_io(png_structp png_ptr, png_FILE_p fp)
 537.637 +{
 537.638 +   png_debug(1, "in png_init_io\n");
 537.639 +   if (png_ptr == NULL) return;
 537.640 +   png_ptr->io_ptr = (png_voidp)fp;
 537.641 +}
 537.642 +#endif
 537.643 +
 537.644 +#if defined(PNG_TIME_RFC1123_SUPPORTED)
 537.645 +/* Convert the supplied time into an RFC 1123 string suitable for use in
 537.646 + * a "Creation Time" or other text-based time string.
 537.647 + */
 537.648 +png_charp PNGAPI
 537.649 +png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
 537.650 +{
 537.651 +   static PNG_CONST char short_months[12][4] =
 537.652 +        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
 537.653 +         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
 537.654 +
 537.655 +   if (png_ptr == NULL) return (NULL);
 537.656 +   if (png_ptr->time_buffer == NULL)
 537.657 +   {
 537.658 +      png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
 537.659 +         png_sizeof(char)));
 537.660 +   }
 537.661 +
 537.662 +#if defined(_WIN32_WCE)
 537.663 +   {
 537.664 +      wchar_t time_buf[29];
 537.665 +      wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
 537.666 +          ptime->day % 32, short_months[(ptime->month - 1) % 12],
 537.667 +        ptime->year, ptime->hour % 24, ptime->minute % 60,
 537.668 +          ptime->second % 61);
 537.669 +      WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
 537.670 +          NULL, NULL);
 537.671 +   }
 537.672 +#else
 537.673 +#ifdef USE_FAR_KEYWORD
 537.674 +   {
 537.675 +      char near_time_buf[29];
 537.676 +      png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000",
 537.677 +          ptime->day % 32, short_months[(ptime->month - 1) % 12],
 537.678 +          ptime->year, ptime->hour % 24, ptime->minute % 60,
 537.679 +          ptime->second % 61);
 537.680 +      png_memcpy(png_ptr->time_buffer, near_time_buf,
 537.681 +          29*png_sizeof(char));
 537.682 +   }
 537.683 +#else
 537.684 +   png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000",
 537.685 +       ptime->day % 32, short_months[(ptime->month - 1) % 12],
 537.686 +       ptime->year, ptime->hour % 24, ptime->minute % 60,
 537.687 +       ptime->second % 61);
 537.688 +#endif
 537.689 +#endif /* _WIN32_WCE */
 537.690 +   return ((png_charp)png_ptr->time_buffer);
 537.691 +}
 537.692 +#endif /* PNG_TIME_RFC1123_SUPPORTED */
 537.693 +
 537.694 +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
 537.695 +
 537.696 +png_charp PNGAPI
 537.697 +png_get_copyright(png_structp png_ptr)
 537.698 +{
 537.699 +   png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
 537.700 +   return ((png_charp) "\n libpng version 1.2.33 - October 31, 2008\n\
 537.701 +   Copyright (c) 1998-2008 Glenn Randers-Pehrson\n\
 537.702 +   Copyright (c) 1996-1997 Andreas Dilger\n\
 537.703 +   Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");
 537.704 +}
 537.705 +
 537.706 +/* The following return the library version as a short string in the
 537.707 + * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
 537.708 + * used with your application, print out PNG_LIBPNG_VER_STRING, which
 537.709 + * is defined in png.h.
 537.710 + * Note: now there is no difference between png_get_libpng_ver() and
 537.711 + * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
 537.712 + * it is guaranteed that png.c uses the correct version of png.h.
 537.713 + */
 537.714 +png_charp PNGAPI
 537.715 +png_get_libpng_ver(png_structp png_ptr)
 537.716 +{
 537.717 +   /* Version of *.c files used when building libpng */
 537.718 +   png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
 537.719 +   return ((png_charp) PNG_LIBPNG_VER_STRING);
 537.720 +}
 537.721 +
 537.722 +png_charp PNGAPI
 537.723 +png_get_header_ver(png_structp png_ptr)
 537.724 +{
 537.725 +   /* Version of *.h files used when building libpng */
 537.726 +   png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
 537.727 +   return ((png_charp) PNG_LIBPNG_VER_STRING);
 537.728 +}
 537.729 +
 537.730 +png_charp PNGAPI
 537.731 +png_get_header_version(png_structp png_ptr)
 537.732 +{
 537.733 +   /* Returns longer string containing both version and date */
 537.734 +   png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
 537.735 +   return ((png_charp) PNG_HEADER_VERSION_STRING
 537.736 +#ifndef PNG_READ_SUPPORTED
 537.737 +   "     (NO READ SUPPORT)"
 537.738 +#endif
 537.739 +   "\n");
 537.740 +}
 537.741 +
 537.742 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
 537.743 +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 537.744 +int PNGAPI
 537.745 +png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
 537.746 +{
 537.747 +   /* check chunk_name and return "keep" value if it's on the list, else 0 */
 537.748 +   int i;
 537.749 +   png_bytep p;
 537.750 +   if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
 537.751 +      return 0;
 537.752 +   p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5;
 537.753 +   for (i = png_ptr->num_chunk_list; i; i--, p -= 5)
 537.754 +      if (!png_memcmp(chunk_name, p, 4))
 537.755 +        return ((int)*(p + 4));
 537.756 +   return 0;
 537.757 +}
 537.758 +#endif
 537.759 +
 537.760 +/* This function, added to libpng-1.0.6g, is untested. */
 537.761 +int PNGAPI
 537.762 +png_reset_zstream(png_structp png_ptr)
 537.763 +{
 537.764 +   if (png_ptr == NULL) return Z_STREAM_ERROR;
 537.765 +   return (inflateReset(&png_ptr->zstream));
 537.766 +}
 537.767 +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
 537.768 +
 537.769 +/* This function was added to libpng-1.0.7 */
 537.770 +png_uint_32 PNGAPI
 537.771 +png_access_version_number(void)
 537.772 +{
 537.773 +   /* Version of *.c files used when building libpng */
 537.774 +   return((png_uint_32) PNG_LIBPNG_VER);
 537.775 +}
 537.776 +
 537.777 +
 537.778 +#if defined(PNG_READ_SUPPORTED) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)
 537.779 +#if !defined(PNG_1_0_X)
 537.780 +/* this function was added to libpng 1.2.0 */
 537.781 +int PNGAPI
 537.782 +png_mmx_support(void)
 537.783 +{
 537.784 +   /* obsolete, to be removed from libpng-1.4.0 */
 537.785 +    return -1;
 537.786 +}
 537.787 +#endif /* PNG_1_0_X */
 537.788 +#endif /* PNG_READ_SUPPORTED && PNG_ASSEMBLER_CODE_SUPPORTED */
 537.789 +
 537.790 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
 537.791 +#ifdef PNG_SIZE_T
 537.792 +/* Added at libpng version 1.2.6 */
 537.793 +   PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
 537.794 +png_size_t PNGAPI
 537.795 +png_convert_size(size_t size)
 537.796 +{
 537.797 +  if (size > (png_size_t)-1)
 537.798 +     PNG_ABORT();  /* We haven't got access to png_ptr, so no png_error() */
 537.799 +  return ((png_size_t)size);
 537.800 +}
 537.801 +#endif /* PNG_SIZE_T */
 537.802 +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
   538.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   538.2 +++ b/libs/libpng/png.h	Sat Feb 01 19:58:19 2014 +0200
   538.3 @@ -0,0 +1,3597 @@
   538.4 +/* png.h - header file for PNG reference library
   538.5 + *
   538.6 + * libpng version 1.2.33 - October 31, 2008
   538.7 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
   538.8 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
   538.9 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  538.10 + *
  538.11 + * Authors and maintainers:
  538.12 + *  libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  538.13 + *  libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
  538.14 + *  libpng versions 0.97, January 1998, through 1.2.33 - October 31, 2008: Glenn
  538.15 + *  See also "Contributing Authors", below.
  538.16 + *
  538.17 + * Note about libpng version numbers:
  538.18 + *
  538.19 + *    Due to various miscommunications, unforeseen code incompatibilities
  538.20 + *    and occasional factors outside the authors' control, version numbering
  538.21 + *    on the library has not always been consistent and straightforward.
  538.22 + *    The following table summarizes matters since version 0.89c, which was
  538.23 + *    the first widely used release:
  538.24 + *
  538.25 + *    source                 png.h  png.h  shared-lib
  538.26 + *    version                string   int  version
  538.27 + *    -------                ------ -----  ----------
  538.28 + *    0.89c "1.0 beta 3"     0.89      89  1.0.89
  538.29 + *    0.90  "1.0 beta 4"     0.90      90  0.90  [should have been 2.0.90]
  538.30 + *    0.95  "1.0 beta 5"     0.95      95  0.95  [should have been 2.0.95]
  538.31 + *    0.96  "1.0 beta 6"     0.96      96  0.96  [should have been 2.0.96]
  538.32 + *    0.97b "1.00.97 beta 7" 1.00.97   97  1.0.1 [should have been 2.0.97]
  538.33 + *    0.97c                  0.97      97  2.0.97
  538.34 + *    0.98                   0.98      98  2.0.98
  538.35 + *    0.99                   0.99      98  2.0.99
  538.36 + *    0.99a-m                0.99      99  2.0.99
  538.37 + *    1.00                   1.00     100  2.1.0 [100 should be 10000]
  538.38 + *    1.0.0      (from here on, the   100  2.1.0 [100 should be 10000]
  538.39 + *    1.0.1       png.h string is   10001  2.1.0
  538.40 + *    1.0.1a-e    identical to the  10002  from here on, the shared library
  538.41 + *    1.0.2       source version)   10002  is 2.V where V is the source code
  538.42 + *    1.0.2a-b                      10003  version, except as noted.
  538.43 + *    1.0.3                         10003
  538.44 + *    1.0.3a-d                      10004
  538.45 + *    1.0.4                         10004
  538.46 + *    1.0.4a-f                      10005
  538.47 + *    1.0.5 (+ 2 patches)           10005
  538.48 + *    1.0.5a-d                      10006
  538.49 + *    1.0.5e-r                      10100 (not source compatible)
  538.50 + *    1.0.5s-v                      10006 (not binary compatible)
  538.51 + *    1.0.6 (+ 3 patches)           10006 (still binary incompatible)
  538.52 + *    1.0.6d-f                      10007 (still binary incompatible)
  538.53 + *    1.0.6g                        10007
  538.54 + *    1.0.6h                        10007  10.6h (testing xy.z so-numbering)
  538.55 + *    1.0.6i                        10007  10.6i
  538.56 + *    1.0.6j                        10007  2.1.0.6j (incompatible with 1.0.0)
  538.57 + *    1.0.7beta11-14        DLLNUM  10007  2.1.0.7beta11-14 (binary compatible)
  538.58 + *    1.0.7beta15-18           1    10007  2.1.0.7beta15-18 (binary compatible)
  538.59 + *    1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)
  538.60 + *    1.0.7                    1    10007  (still compatible)
  538.61 + *    1.0.8beta1-4             1    10008  2.1.0.8beta1-4
  538.62 + *    1.0.8rc1                 1    10008  2.1.0.8rc1
  538.63 + *    1.0.8                    1    10008  2.1.0.8
  538.64 + *    1.0.9beta1-6             1    10009  2.1.0.9beta1-6
  538.65 + *    1.0.9rc1                 1    10009  2.1.0.9rc1
  538.66 + *    1.0.9beta7-10            1    10009  2.1.0.9beta7-10
  538.67 + *    1.0.9rc2                 1    10009  2.1.0.9rc2
  538.68 + *    1.0.9                    1    10009  2.1.0.9
  538.69 + *    1.0.10beta1              1    10010  2.1.0.10beta1
  538.70 + *    1.0.10rc1                1    10010  2.1.0.10rc1
  538.71 + *    1.0.10                   1    10010  2.1.0.10
  538.72 + *    1.0.11beta1-3            1    10011  2.1.0.11beta1-3
  538.73 + *    1.0.11rc1                1    10011  2.1.0.11rc1
  538.74 + *    1.0.11                   1    10011  2.1.0.11
  538.75 + *    1.0.12beta1-2            2    10012  2.1.0.12beta1-2
  538.76 + *    1.0.12rc1                2    10012  2.1.0.12rc1
  538.77 + *    1.0.12                   2    10012  2.1.0.12
  538.78 + *    1.1.0a-f                 -    10100  2.1.1.0a-f (branch abandoned)
  538.79 + *    1.2.0beta1-2             2    10200  2.1.2.0beta1-2
  538.80 + *    1.2.0beta3-5             3    10200  3.1.2.0beta3-5
  538.81 + *    1.2.0rc1                 3    10200  3.1.2.0rc1
  538.82 + *    1.2.0                    3    10200  3.1.2.0
  538.83 + *    1.2.1beta1-4             3    10201  3.1.2.1beta1-4
  538.84 + *    1.2.1rc1-2               3    10201  3.1.2.1rc1-2
  538.85 + *    1.2.1                    3    10201  3.1.2.1
  538.86 + *    1.2.2beta1-6            12    10202  12.so.0.1.2.2beta1-6
  538.87 + *    1.0.13beta1             10    10013  10.so.0.1.0.13beta1
  538.88 + *    1.0.13rc1               10    10013  10.so.0.1.0.13rc1
  538.89 + *    1.2.2rc1                12    10202  12.so.0.1.2.2rc1
  538.90 + *    1.0.13                  10    10013  10.so.0.1.0.13
  538.91 + *    1.2.2                   12    10202  12.so.0.1.2.2
  538.92 + *    1.2.3rc1-6              12    10203  12.so.0.1.2.3rc1-6
  538.93 + *    1.2.3                   12    10203  12.so.0.1.2.3
  538.94 + *    1.2.4beta1-3            13    10204  12.so.0.1.2.4beta1-3
  538.95 + *    1.0.14rc1               13    10014  10.so.0.1.0.14rc1
  538.96 + *    1.2.4rc1                13    10204  12.so.0.1.2.4rc1
  538.97 + *    1.0.14                  10    10014  10.so.0.1.0.14
  538.98 + *    1.2.4                   13    10204  12.so.0.1.2.4
  538.99 + *    1.2.5beta1-2            13    10205  12.so.0.1.2.5beta1-2
 538.100 + *    1.0.15rc1-3             10    10015  10.so.0.1.0.15rc1-3
 538.101 + *    1.2.5rc1-3              13    10205  12.so.0.1.2.5rc1-3
 538.102 + *    1.0.15                  10    10015  10.so.0.1.0.15
 538.103 + *    1.2.5                   13    10205  12.so.0.1.2.5
 538.104 + *    1.2.6beta1-4            13    10206  12.so.0.1.2.6beta1-4
 538.105 + *    1.0.16                  10    10016  10.so.0.1.0.16
 538.106 + *    1.2.6                   13    10206  12.so.0.1.2.6
 538.107 + *    1.2.7beta1-2            13    10207  12.so.0.1.2.7beta1-2
 538.108 + *    1.0.17rc1               10    10017  10.so.0.1.0.17rc1
 538.109 + *    1.2.7rc1                13    10207  12.so.0.1.2.7rc1
 538.110 + *    1.0.17                  10    10017  10.so.0.1.0.17
 538.111 + *    1.2.7                   13    10207  12.so.0.1.2.7
 538.112 + *    1.2.8beta1-5            13    10208  12.so.0.1.2.8beta1-5
 538.113 + *    1.0.18rc1-5             10    10018  10.so.0.1.0.18rc1-5
 538.114 + *    1.2.8rc1-5              13    10208  12.so.0.1.2.8rc1-5
 538.115 + *    1.0.18                  10    10018  10.so.0.1.0.18
 538.116 + *    1.2.8                   13    10208  12.so.0.1.2.8
 538.117 + *    1.2.9beta1-3            13    10209  12.so.0.1.2.9beta1-3
 538.118 + *    1.2.9beta4-11           13    10209  12.so.0.9[.0]
 538.119 + *    1.2.9rc1                13    10209  12.so.0.9[.0]
 538.120 + *    1.2.9                   13    10209  12.so.0.9[.0]
 538.121 + *    1.2.10beta1-8           13    10210  12.so.0.10[.0]
 538.122 + *    1.2.10rc1-3             13    10210  12.so.0.10[.0]
 538.123 + *    1.2.10                  13    10210  12.so.0.10[.0]
 538.124 + *    1.2.11beta1-4           13    10211  12.so.0.11[.0]
 538.125 + *    1.0.19rc1-5             10    10019  10.so.0.19[.0]
 538.126 + *    1.2.11rc1-5             13    10211  12.so.0.11[.0]
 538.127 + *    1.0.19                  10    10019  10.so.0.19[.0]
 538.128 + *    1.2.11                  13    10211  12.so.0.11[.0]
 538.129 + *    1.0.20                  10    10020  10.so.0.20[.0]
 538.130 + *    1.2.12                  13    10212  12.so.0.12[.0]
 538.131 + *    1.2.13beta1             13    10213  12.so.0.13[.0]
 538.132 + *    1.0.21                  10    10021  10.so.0.21[.0]
 538.133 + *    1.2.13                  13    10213  12.so.0.13[.0]
 538.134 + *    1.2.14beta1-2           13    10214  12.so.0.14[.0]
 538.135 + *    1.0.22rc1               10    10022  10.so.0.22[.0]
 538.136 + *    1.2.14rc1               13    10214  12.so.0.14[.0]
 538.137 + *    1.0.22                  10    10022  10.so.0.22[.0]
 538.138 + *    1.2.14                  13    10214  12.so.0.14[.0]
 538.139 + *    1.2.15beta1-6           13    10215  12.so.0.15[.0]
 538.140 + *    1.0.23rc1-5             10    10023  10.so.0.23[.0]
 538.141 + *    1.2.15rc1-5             13    10215  12.so.0.15[.0]
 538.142 + *    1.0.23                  10    10023  10.so.0.23[.0]
 538.143 + *    1.2.15                  13    10215  12.so.0.15[.0]
 538.144 + *    1.2.16beta1-2           13    10216  12.so.0.16[.0]
 538.145 + *    1.2.16rc1               13    10216  12.so.0.16[.0]
 538.146 + *    1.0.24                  10    10024  10.so.0.24[.0]
 538.147 + *    1.2.16                  13    10216  12.so.0.16[.0]
 538.148 + *    1.2.17beta1-2           13    10217  12.so.0.17[.0]
 538.149 + *    1.0.25rc1               10    10025  10.so.0.25[.0]
 538.150 + *    1.2.17rc1-3             13    10217  12.so.0.17[.0]
 538.151 + *    1.0.25                  10    10025  10.so.0.25[.0]
 538.152 + *    1.2.17                  13    10217  12.so.0.17[.0]
 538.153 + *    1.0.26                  10    10026  10.so.0.26[.0]
 538.154 + *    1.2.18                  13    10218  12.so.0.18[.0]
 538.155 + *    1.2.19beta1-31          13    10219  12.so.0.19[.0]
 538.156 + *    1.0.27rc1-6             10    10027  10.so.0.27[.0]
 538.157 + *    1.2.19rc1-6             13    10219  12.so.0.19[.0]
 538.158 + *    1.0.27                  10    10027  10.so.0.27[.0]
 538.159 + *    1.2.19                  13    10219  12.so.0.19[.0]
 538.160 + *    1.2.20beta01-04         13    10220  12.so.0.20[.0]
 538.161 + *    1.0.28rc1-6             10    10028  10.so.0.28[.0]
 538.162 + *    1.2.20rc1-6             13    10220  12.so.0.20[.0]
 538.163 + *    1.0.28                  10    10028  10.so.0.28[.0]
 538.164 + *    1.2.20                  13    10220  12.so.0.20[.0]
 538.165 + *    1.2.21beta1-2           13    10221  12.so.0.21[.0]
 538.166 + *    1.2.21rc1-3             13    10221  12.so.0.21[.0]
 538.167 + *    1.0.29                  10    10029  10.so.0.29[.0]
 538.168 + *    1.2.21                  13    10221  12.so.0.21[.0]
 538.169 + *    1.2.22beta1-4           13    10222  12.so.0.22[.0]
 538.170 + *    1.0.30rc1               10    10030  10.so.0.30[.0]
 538.171 + *    1.2.22rc1               13    10222  12.so.0.22[.0]
 538.172 + *    1.0.30                  10    10030  10.so.0.30[.0]
 538.173 + *    1.2.22                  13    10222  12.so.0.22[.0]
 538.174 + *    1.2.23beta01-05         13    10223  12.so.0.23[.0]
 538.175 + *    1.2.23rc01              13    10223  12.so.0.23[.0]
 538.176 + *    1.2.23                  13    10223  12.so.0.23[.0]
 538.177 + *    1.2.24beta01-02         13    10224  12.so.0.24[.0]
 538.178 + *    1.2.24rc01              13    10224  12.so.0.24[.0]
 538.179 + *    1.2.24                  13    10224  12.so.0.24[.0]
 538.180 + *    1.2.25beta01-06         13    10225  12.so.0.25[.0]
 538.181 + *    1.2.25rc01-02           13    10225  12.so.0.25[.0]
 538.182 + *    1.0.31                  10    10031  10.so.0.31[.0]
 538.183 + *    1.2.25                  13    10225  12.so.0.25[.0]
 538.184 + *    1.2.26beta01-06         13    10226  12.so.0.26[.0]
 538.185 + *    1.2.26rc01              13    10226  12.so.0.26[.0]
 538.186 + *    1.2.26                  13    10226  12.so.0.26[.0]
 538.187 + *    1.0.32                  10    10032  10.so.0.32[.0]
 538.188 + *    1.2.27beta01-06         13    10227  12.so.0.27[.0]
 538.189 + *    1.2.27rc01              13    10227  12.so.0.27[.0]
 538.190 + *    1.0.33                  10    10033  10.so.0.33[.0]
 538.191 + *    1.2.27                  13    10227  12.so.0.27[.0]
 538.192 + *    1.0.34                  10    10034  10.so.0.34[.0]
 538.193 + *    1.2.28                  13    10228  12.so.0.28[.0]
 538.194 + *    1.2.29beta01-03         13    10229  12.so.0.29[.0]
 538.195 + *    1.2.29rc01              13    10229  12.so.0.29[.0]
 538.196 + *    1.0.35                  10    10035  10.so.0.35[.0]
 538.197 + *    1.2.29                  13    10229  12.so.0.29[.0]
 538.198 + *    1.0.37                  10    10037  10.so.0.37[.0]
 538.199 + *    1.2.30beta01-04         13    10230  12.so.0.30[.0]
 538.200 + *    1.0.38rc01-08           10    10038  10.so.0.38[.0]
 538.201 + *    1.2.30rc01-08           13    10230  12.so.0.30[.0]
 538.202 + *    1.0.38                  10    10038  10.so.0.38[.0]
 538.203 + *    1.2.30                  13    10230  12.so.0.30[.0]
 538.204 + *    1.0.39rc01-03           10    10039  10.so.0.39[.0]
 538.205 + *    1.2.31rc01-03           13    10231  12.so.0.31[.0]
 538.206 + *    1.0.39                  10    10039  10.so.0.39[.0]
 538.207 + *    1.2.31                  13    10231  12.so.0.31[.0]
 538.208 + *    1.2.32beta01-02         13    10232  12.so.0.32[.0]
 538.209 + *    1.0.40rc01              10    10040  10.so.0.40[.0]
 538.210 + *    1.2.32rc01              13    10232  12.so.0.32[.0]
 538.211 + *    1.0.40                  10    10040  10.so.0.40[.0]
 538.212 + *    1.2.32                  13    10232  12.so.0.32[.0]
 538.213 + *    1.2.33beta01-02         13    10233  12.so.0.33[.0]
 538.214 + *    1.2.33rc01-02           13    10233  12.so.0.33[.0]
 538.215 + *    1.0.41rc01              10    10041  10.so.0.41[.0]
 538.216 + *    1.2.33                  13    10233  12.so.0.33[.0]
 538.217 + *    1.0.41                  10    10041  10.so.0.41[.0]
 538.218 + *
 538.219 + *    Henceforth the source version will match the shared-library major
 538.220 + *    and minor numbers; the shared-library major version number will be
 538.221 + *    used for changes in backward compatibility, as it is intended.  The
 538.222 + *    PNG_LIBPNG_VER macro, which is not used within libpng but is available
 538.223 + *    for applications, is an unsigned integer of the form xyyzz corresponding
 538.224 + *    to the source version x.y.z (leading zeros in y and z).  Beta versions
 538.225 + *    were given the previous public release number plus a letter, until
 538.226 + *    version 1.0.6j; from then on they were given the upcoming public
 538.227 + *    release number plus "betaNN" or "rcNN".
 538.228 + *
 538.229 + *    Binary incompatibility exists only when applications make direct access
 538.230 + *    to the info_ptr or png_ptr members through png.h, and the compiled
 538.231 + *    application is loaded with a different version of the library.
 538.232 + *
 538.233 + *    DLLNUM will change each time there are forward or backward changes
 538.234 + *    in binary compatibility (e.g., when a new feature is added).
 538.235 + *
 538.236 + * See libpng.txt or libpng.3 for more information.  The PNG specification
 538.237 + * is available as a W3C Recommendation and as an ISO Specification,
 538.238 + * <http://www.w3.org/TR/2003/REC-PNG-20031110/
 538.239 + */
 538.240 +
 538.241 +/*
 538.242 + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
 538.243 + *
 538.244 + * If you modify libpng you may insert additional notices immediately following
 538.245 + * this sentence.
 538.246 + *
 538.247 + * libpng versions 1.2.6, August 15, 2004, through 1.2.33, October 31, 2008, are
 538.248 + * Copyright (c) 2004, 2006-2008 Glenn Randers-Pehrson, and are
 538.249 + * distributed according to the same disclaimer and license as libpng-1.2.5
 538.250 + * with the following individual added to the list of Contributing Authors:
 538.251 + *
 538.252 + *    Cosmin Truta
 538.253 + *
 538.254 + * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
 538.255 + * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
 538.256 + * distributed according to the same disclaimer and license as libpng-1.0.6
 538.257 + * with the following individuals added to the list of Contributing Authors:
 538.258 + *
 538.259 + *    Simon-Pierre Cadieux
 538.260 + *    Eric S. Raymond
 538.261 + *    Gilles Vollant
 538.262 + *
 538.263 + * and with the following additions to the disclaimer:
 538.264 + *
 538.265 + *    There is no warranty against interference with your enjoyment of the
 538.266 + *    library or against infringement.  There is no warranty that our
 538.267 + *    efforts or the library will fulfill any of your particular purposes
 538.268 + *    or needs.  This library is provided with all faults, and the entire
 538.269 + *    risk of satisfactory quality, performance, accuracy, and effort is with
 538.270 + *    the user.
 538.271 + *
 538.272 + * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
 538.273 + * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
 538.274 + * distributed according to the same disclaimer and license as libpng-0.96,
 538.275 + * with the following individuals added to the list of Contributing Authors:
 538.276 + *
 538.277 + *    Tom Lane
 538.278 + *    Glenn Randers-Pehrson
 538.279 + *    Willem van Schaik
 538.280 + *
 538.281 + * libpng versions 0.89, June 1996, through 0.96, May 1997, are
 538.282 + * Copyright (c) 1996, 1997 Andreas Dilger
 538.283 + * Distributed according to the same disclaimer and license as libpng-0.88,
 538.284 + * with the following individuals added to the list of Contributing Authors:
 538.285 + *
 538.286 + *    John Bowler
 538.287 + *    Kevin Bracey
 538.288 + *    Sam Bushell
 538.289 + *    Magnus Holmgren
 538.290 + *    Greg Roelofs
 538.291 + *    Tom Tanner
 538.292 + *
 538.293 + * libpng versions 0.5, May 1995, through 0.88, January 1996, are
 538.294 + * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
 538.295 + *
 538.296 + * For the purposes of this copyright and license, "Contributing Authors"
 538.297 + * is defined as the following set of individuals:
 538.298 + *
 538.299 + *    Andreas Dilger
 538.300 + *    Dave Martindale
 538.301 + *    Guy Eric Schalnat
 538.302 + *    Paul Schmidt
 538.303 + *    Tim Wegner
 538.304 + *
 538.305 + * The PNG Reference Library is supplied "AS IS".  The Contributing Authors
 538.306 + * and Group 42, Inc. disclaim all warranties, expressed or implied,
 538.307 + * including, without limitation, the warranties of merchantability and of
 538.308 + * fitness for any purpose.  The Contributing Authors and Group 42, Inc.
 538.309 + * assume no liability for direct, indirect, incidental, special, exemplary,
 538.310 + * or consequential damages, which may result from the use of the PNG
 538.311 + * Reference Library, even if advised of the possibility of such damage.
 538.312 + *
 538.313 + * Permission is hereby granted to use, copy, modify, and distribute this
 538.314 + * source code, or portions hereof, for any purpose, without fee, subject
 538.315 + * to the following restrictions:
 538.316 + *
 538.317 + * 1. The origin of this source code must not be misrepresented.
 538.318 + *
 538.319 + * 2. Altered versions must be plainly marked as such and
 538.320 + * must not be misrepresented as being the original source.
 538.321 + *
 538.322 + * 3. This Copyright notice may not be removed or altered from
 538.323 + *    any source or altered source distribution.
 538.324 + *
 538.325 + * The Contributing Authors and Group 42, Inc. specifically permit, without
 538.326 + * fee, and encourage the use of this source code as a component to
 538.327 + * supporting the PNG file format in commercial products.  If you use this
 538.328 + * source code in a product, acknowledgment is not required but would be
 538.329 + * appreciated.
 538.330 + */
 538.331 +
 538.332 +/*
 538.333 + * A "png_get_copyright" function is available, for convenient use in "about"
 538.334 + * boxes and the like:
 538.335 + *
 538.336 + * printf("%s",png_get_copyright(NULL));
 538.337 + *
 538.338 + * Also, the PNG logo (in PNG format, of course) is supplied in the
 538.339 + * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
 538.340 + */
 538.341 +
 538.342 +/*
 538.343 + * Libpng is OSI Certified Open Source Software.  OSI Certified is a
 538.344 + * certification mark of the Open Source Initiative.
 538.345 + */
 538.346 +
 538.347 +/*
 538.348 + * The contributing authors would like to thank all those who helped
 538.349 + * with testing, bug fixes, and patience.  This wouldn't have been
 538.350 + * possible without all of you.
 538.351 + *
 538.352 + * Thanks to Frank J. T. Wojcik for helping with the documentation.
 538.353 + */
 538.354 +
 538.355 +/*
 538.356 + * Y2K compliance in libpng:
 538.357 + * =========================
 538.358 + *
 538.359 + *    October 31, 2008
 538.360 + *
 538.361 + *    Since the PNG Development group is an ad-hoc body, we can't make
 538.362 + *    an official declaration.
 538.363 + *
 538.364 + *    This is your unofficial assurance that libpng from version 0.71 and
 538.365 + *    upward through 1.2.33 are Y2K compliant.  It is my belief that earlier
 538.366 + *    versions were also Y2K compliant.
 538.367 + *
 538.368 + *    Libpng only has three year fields.  One is a 2-byte unsigned integer
 538.369 + *    that will hold years up to 65535.  The other two hold the date in text
 538.370 + *    format, and will hold years up to 9999.
 538.371 + *
 538.372 + *    The integer is
 538.373 + *        "png_uint_16 year" in png_time_struct.
 538.374 + *
 538.375 + *    The strings are
 538.376 + *        "png_charp time_buffer" in png_struct and
 538.377 + *        "near_time_buffer", which is a local character string in png.c.
 538.378 + *
 538.379 + *    There are seven time-related functions:
 538.380 + *        png.c: png_convert_to_rfc_1123() in png.c
 538.381 + *          (formerly png_convert_to_rfc_1152() in error)
 538.382 + *        png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
 538.383 + *        png_convert_from_time_t() in pngwrite.c
 538.384 + *        png_get_tIME() in pngget.c
 538.385 + *        png_handle_tIME() in pngrutil.c, called in pngread.c
 538.386 + *        png_set_tIME() in pngset.c
 538.387 + *        png_write_tIME() in pngwutil.c, called in pngwrite.c
 538.388 + *
 538.389 + *    All handle dates properly in a Y2K environment.  The
 538.390 + *    png_convert_from_time_t() function calls gmtime() to convert from system
 538.391 + *    clock time, which returns (year - 1900), which we properly convert to
 538.392 + *    the full 4-digit year.  There is a possibility that applications using
 538.393 + *    libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
 538.394 + *    function, or that they are incorrectly passing only a 2-digit year
 538.395 + *    instead of "year - 1900" into the png_convert_from_struct_tm() function,
 538.396 + *    but this is not under our control.  The libpng documentation has always
 538.397 + *    stated that it works with 4-digit years, and the APIs have been
 538.398 + *    documented as such.
 538.399 + *
 538.400 + *    The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
 538.401 + *    integer to hold the year, and can hold years as large as 65535.
 538.402 + *
 538.403 + *    zlib, upon which libpng depends, is also Y2K compliant.  It contains
 538.404 + *    no date-related code.
 538.405 + *
 538.406 + *       Glenn Randers-Pehrson
 538.407 + *       libpng maintainer
 538.408 + *       PNG Development Group
 538.409 + */
 538.410 +
 538.411 +#ifndef PNG_H
 538.412 +#define PNG_H
 538.413 +
 538.414 +/* This is not the place to learn how to use libpng.  The file libpng.txt
 538.415 + * describes how to use libpng, and the file example.c summarizes it
 538.416 + * with some code on which to build.  This file is useful for looking
 538.417 + * at the actual function definitions and structure components.
 538.418 + */
 538.419 +
 538.420 +/* Version information for png.h - this should match the version in png.c */
 538.421 +#define PNG_LIBPNG_VER_STRING "1.2.33"
 538.422 +#define PNG_HEADER_VERSION_STRING \
 538.423 +   " libpng version 1.2.33 - October 31, 2008\n"
 538.424 +
 538.425 +#define PNG_LIBPNG_VER_SONUM   0
 538.426 +#define PNG_LIBPNG_VER_DLLNUM  13
 538.427 +
 538.428 +/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 538.429 +#define PNG_LIBPNG_VER_MAJOR   1
 538.430 +#define PNG_LIBPNG_VER_MINOR   2
 538.431 +#define PNG_LIBPNG_VER_RELEASE 33
 538.432 +/* This should match the numeric part of the final component of
 538.433 + * PNG_LIBPNG_VER_STRING, omitting any leading zero: */
 538.434 +
 538.435 +#define PNG_LIBPNG_VER_BUILD  0
 538.436 +
 538.437 +/* Release Status */
 538.438 +#define PNG_LIBPNG_BUILD_ALPHA    1
 538.439 +#define PNG_LIBPNG_BUILD_BETA     2
 538.440 +#define PNG_LIBPNG_BUILD_RC       3
 538.441 +#define PNG_LIBPNG_BUILD_STABLE   4
 538.442 +#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
 538.443 +  
 538.444 +/* Release-Specific Flags */
 538.445 +#define PNG_LIBPNG_BUILD_PATCH    8 /* Can be OR'ed with
 538.446 +                                       PNG_LIBPNG_BUILD_STABLE only */
 538.447 +#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
 538.448 +                                       PNG_LIBPNG_BUILD_SPECIAL */
 538.449 +#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
 538.450 +                                       PNG_LIBPNG_BUILD_PRIVATE */
 538.451 +
 538.452 +#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
 538.453 +
 538.454 +/* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
 538.455 + * We must not include leading zeros.
 538.456 + * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
 538.457 + * version 1.0.0 was mis-numbered 100 instead of 10000).  From
 538.458 + * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release */
 538.459 +#define PNG_LIBPNG_VER 10233 /* 1.2.33 */
 538.460 +
 538.461 +#ifndef PNG_VERSION_INFO_ONLY
 538.462 +/* include the compression library's header */
 538.463 +#include "zlib.h"
 538.464 +#endif
 538.465 +
 538.466 +/* include all user configurable info, including optional assembler routines */
 538.467 +#include "pngconf.h"
 538.468 +
 538.469 +/*
 538.470 + * Added at libpng-1.2.8 */
 538.471 +/* Ref MSDN: Private as priority over Special
 538.472 + * VS_FF_PRIVATEBUILD File *was not* built using standard release
 538.473 + * procedures. If this value is given, the StringFileInfo block must
 538.474 + * contain a PrivateBuild string. 
 538.475 + *
 538.476 + * VS_FF_SPECIALBUILD File *was* built by the original company using
 538.477 + * standard release procedures but is a variation of the standard
 538.478 + * file of the same version number. If this value is given, the
 538.479 + * StringFileInfo block must contain a SpecialBuild string. 
 538.480 + */
 538.481 +
 538.482 +#if defined(PNG_USER_PRIVATEBUILD)
 538.483 +#  define PNG_LIBPNG_BUILD_TYPE \
 538.484 +          (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
 538.485 +#else
 538.486 +#  if defined(PNG_LIBPNG_SPECIALBUILD)
 538.487 +#    define PNG_LIBPNG_BUILD_TYPE \
 538.488 +            (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
 538.489 +#  else
 538.490 +#    define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
 538.491 +#  endif
 538.492 +#endif
 538.493 +
 538.494 +#ifndef PNG_VERSION_INFO_ONLY
 538.495 +
 538.496 +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
 538.497 +#ifdef __cplusplus
 538.498 +extern "C" {
 538.499 +#endif /* __cplusplus */
 538.500 +
 538.501 +/* This file is arranged in several sections.  The first section contains
 538.502 + * structure and type definitions.  The second section contains the external
 538.503 + * library functions, while the third has the internal library functions,
 538.504 + * which applications aren't expected to use directly.
 538.505 + */
 538.506 +
 538.507 +#ifndef PNG_NO_TYPECAST_NULL
 538.508 +#define int_p_NULL                (int *)NULL
 538.509 +#define png_bytep_NULL            (png_bytep)NULL
 538.510 +#define png_bytepp_NULL           (png_bytepp)NULL
 538.511 +#define png_doublep_NULL          (png_doublep)NULL
 538.512 +#define png_error_ptr_NULL        (png_error_ptr)NULL
 538.513 +#define png_flush_ptr_NULL        (png_flush_ptr)NULL
 538.514 +#define png_free_ptr_NULL         (png_free_ptr)NULL
 538.515 +#define png_infopp_NULL           (png_infopp)NULL
 538.516 +#define png_malloc_ptr_NULL       (png_malloc_ptr)NULL
 538.517 +#define png_read_status_ptr_NULL  (png_read_status_ptr)NULL
 538.518 +#define png_rw_ptr_NULL           (png_rw_ptr)NULL
 538.519 +#define png_structp_NULL          (png_structp)NULL
 538.520 +#define png_uint_16p_NULL         (png_uint_16p)NULL
 538.521 +#define png_voidp_NULL            (png_voidp)NULL
 538.522 +#define png_write_status_ptr_NULL (png_write_status_ptr)NULL
 538.523 +#else
 538.524 +#define int_p_NULL                NULL
 538.525 +#define png_bytep_NULL            NULL
 538.526 +#define png_bytepp_NULL           NULL
 538.527 +#define png_doublep_NULL          NULL
 538.528 +#define png_error_ptr_NULL        NULL
 538.529 +#define png_flush_ptr_NULL        NULL
 538.530 +#define png_free_ptr_NULL         NULL
 538.531 +#define png_infopp_NULL           NULL
 538.532 +#define png_malloc_ptr_NULL       NULL
 538.533 +#define png_read_status_ptr_NULL  NULL
 538.534 +#define png_rw_ptr_NULL           NULL
 538.535 +#define png_structp_NULL          NULL
 538.536 +#define png_uint_16p_NULL         NULL
 538.537 +#define png_voidp_NULL            NULL
 538.538 +#define png_write_status_ptr_NULL NULL
 538.539 +#endif
 538.540 +
 538.541 +/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
 538.542 +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
 538.543 +/* Version information for C files, stored in png.c.  This had better match
 538.544 + * the version above.
 538.545 + */
 538.546 +#ifdef PNG_USE_GLOBAL_ARRAYS
 538.547 +PNG_EXPORT_VAR (PNG_CONST char) png_libpng_ver[18];
 538.548 +  /* need room for 99.99.99beta99z */
 538.549 +#else
 538.550 +#define png_libpng_ver png_get_header_ver(NULL)
 538.551 +#endif
 538.552 +
 538.553 +#ifdef PNG_USE_GLOBAL_ARRAYS
 538.554 +/* This was removed in version 1.0.5c */
 538.555 +/* Structures to facilitate easy interlacing.  See png.c for more details */
 538.556 +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_start[7];
 538.557 +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_inc[7];
 538.558 +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_ystart[7];
 538.559 +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_yinc[7];
 538.560 +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_mask[7];
 538.561 +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_dsp_mask[7];
 538.562 +/* This isn't currently used.  If you need it, see png.c for more details.
 538.563 +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_height[7];
 538.564 +*/
 538.565 +#endif
 538.566 +
 538.567 +#endif /* PNG_NO_EXTERN */
 538.568 +
 538.569 +/* Three color definitions.  The order of the red, green, and blue, (and the
 538.570 + * exact size) is not important, although the size of the fields need to
 538.571 + * be png_byte or png_uint_16 (as defined below).
 538.572 + */
 538.573 +typedef struct png_color_struct
 538.574 +{
 538.575 +   png_byte red;
 538.576 +   png_byte green;
 538.577 +   png_byte blue;
 538.578 +} png_color;
 538.579 +typedef png_color FAR * png_colorp;
 538.580 +typedef png_color FAR * FAR * png_colorpp;
 538.581 +
 538.582 +typedef struct png_color_16_struct
 538.583 +{
 538.584 +   png_byte index;    /* used for palette files */
 538.585 +   png_uint_16 red;   /* for use in red green blue files */
 538.586 +   png_uint_16 green;
 538.587 +   png_uint_16 blue;
 538.588 +   png_uint_16 gray;  /* for use in grayscale files */
 538.589 +} png_color_16;
 538.590 +typedef png_color_16 FAR * png_color_16p;
 538.591 +typedef png_color_16 FAR * FAR * png_color_16pp;
 538.592 +
 538.593 +typedef struct png_color_8_struct
 538.594 +{
 538.595 +   png_byte red;   /* for use in red green blue files */
 538.596 +   png_byte green;
 538.597 +   png_byte blue;
 538.598 +   png_byte gray;  /* for use in grayscale files */
 538.599 +   png_byte alpha; /* for alpha channel files */
 538.600 +} png_color_8;
 538.601 +typedef png_color_8 FAR * png_color_8p;
 538.602 +typedef png_color_8 FAR * FAR * png_color_8pp;
 538.603 +
 538.604 +/*
 538.605 + * The following two structures are used for the in-core representation
 538.606 + * of sPLT chunks.
 538.607 + */
 538.608 +typedef struct png_sPLT_entry_struct
 538.609 +{
 538.610 +   png_uint_16 red;
 538.611 +   png_uint_16 green;
 538.612 +   png_uint_16 blue;
 538.613 +   png_uint_16 alpha;
 538.614 +   png_uint_16 frequency;
 538.615 +} png_sPLT_entry;
 538.616 +typedef png_sPLT_entry FAR * png_sPLT_entryp;
 538.617 +typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp;
 538.618 +
 538.619 +/*  When the depth of the sPLT palette is 8 bits, the color and alpha samples
 538.620 + *  occupy the LSB of their respective members, and the MSB of each member
 538.621 + *  is zero-filled.  The frequency member always occupies the full 16 bits.
 538.622 + */
 538.623 +
 538.624 +typedef struct png_sPLT_struct
 538.625 +{
 538.626 +   png_charp name;           /* palette name */
 538.627 +   png_byte depth;           /* depth of palette samples */
 538.628 +   png_sPLT_entryp entries;  /* palette entries */
 538.629 +   png_int_32 nentries;      /* number of palette entries */
 538.630 +} png_sPLT_t;
 538.631 +typedef png_sPLT_t FAR * png_sPLT_tp;
 538.632 +typedef png_sPLT_t FAR * FAR * png_sPLT_tpp;
 538.633 +
 538.634 +#ifdef PNG_TEXT_SUPPORTED
 538.635 +/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
 538.636 + * and whether that contents is compressed or not.  The "key" field
 538.637 + * points to a regular zero-terminated C string.  The "text", "lang", and
 538.638 + * "lang_key" fields can be regular C strings, empty strings, or NULL pointers.
 538.639 + * However, the * structure returned by png_get_text() will always contain
 538.640 + * regular zero-terminated C strings (possibly empty), never NULL pointers,
 538.641 + * so they can be safely used in printf() and other string-handling functions.
 538.642 + */
 538.643 +typedef struct png_text_struct
 538.644 +{
 538.645 +   int  compression;       /* compression value:
 538.646 +                             -1: tEXt, none
 538.647 +                              0: zTXt, deflate
 538.648 +                              1: iTXt, none
 538.649 +                              2: iTXt, deflate  */
 538.650 +   png_charp key;          /* keyword, 1-79 character description of "text" */
 538.651 +   png_charp text;         /* comment, may be an empty string (ie "")
 538.652 +                              or a NULL pointer */
 538.653 +   png_size_t text_length; /* length of the text string */
 538.654 +#ifdef PNG_iTXt_SUPPORTED
 538.655 +   png_size_t itxt_length; /* length of the itxt string */
 538.656 +   png_charp lang;         /* language code, 0-79 characters
 538.657 +                              or a NULL pointer */
 538.658 +   png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
 538.659 +                              chars or a NULL pointer */
 538.660 +#endif
 538.661 +} png_text;
 538.662 +typedef png_text FAR * png_textp;
 538.663 +typedef png_text FAR * FAR * png_textpp;
 538.664 +#endif
 538.665 +
 538.666 +/* Supported compression types for text in PNG files (tEXt, and zTXt).
 538.667 + * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
 538.668 +#define PNG_TEXT_COMPRESSION_NONE_WR -3
 538.669 +#define PNG_TEXT_COMPRESSION_zTXt_WR -2
 538.670 +#define PNG_TEXT_COMPRESSION_NONE    -1
 538.671 +#define PNG_TEXT_COMPRESSION_zTXt     0
 538.672 +#define PNG_ITXT_COMPRESSION_NONE     1
 538.673 +#define PNG_ITXT_COMPRESSION_zTXt     2
 538.674 +#define PNG_TEXT_COMPRESSION_LAST     3  /* Not a valid value */
 538.675 +
 538.676 +/* png_time is a way to hold the time in an machine independent way.
 538.677 + * Two conversions are provided, both from time_t and struct tm.  There
 538.678 + * is no portable way to convert to either of these structures, as far
 538.679 + * as I know.  If you know of a portable way, send it to me.  As a side
 538.680 + * note - PNG has always been Year 2000 compliant!
 538.681 + */
 538.682 +typedef struct png_time_struct
 538.683 +{
 538.684 +   png_uint_16 year; /* full year, as in, 1995 */
 538.685 +   png_byte month;   /* month of year, 1 - 12 */
 538.686 +   png_byte day;     /* day of month, 1 - 31 */
 538.687 +   png_byte hour;    /* hour of day, 0 - 23 */
 538.688 +   png_byte minute;  /* minute of hour, 0 - 59 */
 538.689 +   png_byte second;  /* second of minute, 0 - 60 (for leap seconds) */
 538.690 +} png_time;
 538.691 +typedef png_time FAR * png_timep;
 538.692 +typedef png_time FAR * FAR * png_timepp;
 538.693 +
 538.694 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
 538.695 +/* png_unknown_chunk is a structure to hold queued chunks for which there is
 538.696 + * no specific support.  The idea is that we can use this to queue
 538.697 + * up private chunks for output even though the library doesn't actually
 538.698 + * know about their semantics.
 538.699 + */
 538.700 +#define PNG_CHUNK_NAME_LENGTH 5
 538.701 +typedef struct png_unknown_chunk_t
 538.702 +{
 538.703 +    png_byte name[PNG_CHUNK_NAME_LENGTH];
 538.704 +    png_byte *data;
 538.705 +    png_size_t size;
 538.706 +
 538.707 +    /* libpng-using applications should NOT directly modify this byte. */
 538.708 +    png_byte location; /* mode of operation at read time */
 538.709 +}
 538.710 +png_unknown_chunk;
 538.711 +typedef png_unknown_chunk FAR * png_unknown_chunkp;
 538.712 +typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp;
 538.713 +#endif
 538.714 +
 538.715 +/* png_info is a structure that holds the information in a PNG file so
 538.716 + * that the application can find out the characteristics of the image.
 538.717 + * If you are reading the file, this structure will tell you what is
 538.718 + * in the PNG file.  If you are writing the file, fill in the information
 538.719 + * you want to put into the PNG file, then call png_write_info().
 538.720 + * The names chosen should be very close to the PNG specification, so
 538.721 + * consult that document for information about the meaning of each field.
 538.722 + *
 538.723 + * With libpng < 0.95, it was only possible to directly set and read the
 538.724 + * the values in the png_info_struct, which meant that the contents and
 538.725 + * order of the values had to remain fixed.  With libpng 0.95 and later,
 538.726 + * however, there are now functions that abstract the contents of
 538.727 + * png_info_struct from the application, so this makes it easier to use
 538.728 + * libpng with dynamic libraries, and even makes it possible to use
 538.729 + * libraries that don't have all of the libpng ancillary chunk-handing
 538.730 + * functionality.
 538.731 + *
 538.732 + * In any case, the order of the parameters in png_info_struct should NOT
 538.733 + * be changed for as long as possible to keep compatibility with applications
 538.734 + * that use the old direct-access method with png_info_struct.
 538.735 + *
 538.736 + * The following members may have allocated storage attached that should be
 538.737 + * cleaned up before the structure is discarded: palette, trans, text,
 538.738 + * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
 538.739 + * splt_palettes, scal_unit, row_pointers, and unknowns.   By default, these
 538.740 + * are automatically freed when the info structure is deallocated, if they were
 538.741 + * allocated internally by libpng.  This behavior can be changed by means
 538.742 + * of the png_data_freer() function.
 538.743 + *
 538.744 + * More allocation details: all the chunk-reading functions that
 538.745 + * change these members go through the corresponding png_set_*
 538.746 + * functions.  A function to clear these members is available: see
 538.747 + * png_free_data().  The png_set_* functions do not depend on being
 538.748 + * able to point info structure members to any of the storage they are
 538.749 + * passed (they make their own copies), EXCEPT that the png_set_text
 538.750 + * functions use the same storage passed to them in the text_ptr or
 538.751 + * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
 538.752 + * functions do not make their own copies.
 538.753 + */
 538.754 +typedef struct png_info_struct
 538.755 +{
 538.756 +   /* the following are necessary for every PNG file */
 538.757 +   png_uint_32 width;       /* width of image in pixels (from IHDR) */
 538.758 +   png_uint_32 height;      /* height of image in pixels (from IHDR) */
 538.759 +   png_uint_32 valid;       /* valid chunk data (see PNG_INFO_ below) */
 538.760 +   png_uint_32 rowbytes;    /* bytes needed to hold an untransformed row */
 538.761 +   png_colorp palette;      /* array of color values (valid & PNG_INFO_PLTE) */
 538.762 +   png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
 538.763 +   png_uint_16 num_trans;   /* number of transparent palette color (tRNS) */
 538.764 +   png_byte bit_depth;      /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
 538.765 +   png_byte color_type;     /* see PNG_COLOR_TYPE_ below (from IHDR) */
 538.766 +   /* The following three should have been named *_method not *_type */
 538.767 +   png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
 538.768 +   png_byte filter_type;    /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
 538.769 +   png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
 538.770 +
 538.771 +   /* The following is informational only on read, and not used on writes. */
 538.772 +   png_byte channels;       /* number of data channels per pixel (1, 2, 3, 4) */
 538.773 +   png_byte pixel_depth;    /* number of bits per pixel */
 538.774 +   png_byte spare_byte;     /* to align the data, and for future use */
 538.775 +   png_byte signature[8];   /* magic bytes read by libpng from start of file */
 538.776 +
 538.777 +   /* The rest of the data is optional.  If you are reading, check the
 538.778 +    * valid field to see if the information in these are valid.  If you
 538.779 +    * are writing, set the valid field to those chunks you want written,
 538.780 +    * and initialize the appropriate fields below.
 538.781 +    */
 538.782 +
 538.783 +#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
 538.784 +   /* The gAMA chunk describes the gamma characteristics of the system
 538.785 +    * on which the image was created, normally in the range [1.0, 2.5].
 538.786 +    * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
 538.787 +    */
 538.788 +   float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
 538.789 +#endif
 538.790 +
 538.791 +#if defined(PNG_sRGB_SUPPORTED)
 538.792 +    /* GR-P, 0.96a */
 538.793 +    /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
 538.794 +   png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
 538.795 +#endif
 538.796 +
 538.797 +#if defined(PNG_TEXT_SUPPORTED)
 538.798 +   /* The tEXt, and zTXt chunks contain human-readable textual data in
 538.799 +    * uncompressed, compressed, and optionally compressed forms, respectively.
 538.800 +    * The data in "text" is an array of pointers to uncompressed,
 538.801 +    * null-terminated C strings. Each chunk has a keyword that describes the
 538.802 +    * textual data contained in that chunk.  Keywords are not required to be
 538.803 +    * unique, and the text string may be empty.  Any number of text chunks may
 538.804 +    * be in an image.
 538.805 +    */
 538.806 +   int num_text; /* number of comments read/to write */
 538.807 +   int max_text; /* current size of text array */
 538.808 +   png_textp text; /* array of comments read/to write */
 538.809 +#endif /* PNG_TEXT_SUPPORTED */
 538.810 +
 538.811 +#if defined(PNG_tIME_SUPPORTED)
 538.812 +   /* The tIME chunk holds the last time the displayed image data was
 538.813 +    * modified.  See the png_time struct for the contents of this struct.
 538.814 +    */
 538.815 +   png_time mod_time;
 538.816 +#endif
 538.817 +
 538.818 +#if defined(PNG_sBIT_SUPPORTED)
 538.819 +   /* The sBIT chunk specifies the number of significant high-order bits
 538.820 +    * in the pixel data.  Values are in the range [1, bit_depth], and are
 538.821 +    * only specified for the channels in the pixel data.  The contents of
 538.822 +    * the low-order bits is not specified.  Data is valid if
 538.823 +    * (valid & PNG_INFO_sBIT) is non-zero.
 538.824 +    */
 538.825 +   png_color_8 sig_bit; /* significant bits in color channels */
 538.826 +#endif
 538.827 +
 538.828 +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
 538.829 +defined(PNG_READ_BACKGROUND_SUPPORTED)
 538.830 +   /* The tRNS chunk supplies transparency data for paletted images and
 538.831 +    * other image types that don't need a full alpha channel.  There are
 538.832 +    * "num_trans" transparency values for a paletted image, stored in the
 538.833 +    * same order as the palette colors, starting from index 0.  Values
 538.834 +    * for the data are in the range [0, 255], ranging from fully transparent
 538.835 +    * to fully opaque, respectively.  For non-paletted images, there is a
 538.836 +    * single color specified that should be treated as fully transparent.
 538.837 +    * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
 538.838 +    */
 538.839 +   png_bytep trans; /* transparent values for paletted image */
 538.840 +   png_color_16 trans_values; /* transparent color for non-palette image */
 538.841 +#endif
 538.842 +
 538.843 +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
 538.844 +   /* The bKGD chunk gives the suggested image background color if the
 538.845 +    * display program does not have its own background color and the image
 538.846 +    * is needs to composited onto a background before display.  The colors
 538.847 +    * in "background" are normally in the same color space/depth as the
 538.848 +    * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
 538.849 +    */
 538.850 +   png_color_16 background;
 538.851 +#endif
 538.852 +
 538.853 +#if defined(PNG_oFFs_SUPPORTED)
 538.854 +   /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
 538.855 +    * and downwards from the top-left corner of the display, page, or other
 538.856 +    * application-specific co-ordinate space.  See the PNG_OFFSET_ defines
 538.857 +    * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.
 538.858 +    */
 538.859 +   png_int_32 x_offset; /* x offset on page */
 538.860 +   png_int_32 y_offset; /* y offset on page */
 538.861 +   png_byte offset_unit_type; /* offset units type */
 538.862 +#endif
 538.863 +
 538.864 +#if defined(PNG_pHYs_SUPPORTED)
 538.865 +   /* The pHYs chunk gives the physical pixel density of the image for
 538.866 +    * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
 538.867 +    * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
 538.868 +    */
 538.869 +   png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
 538.870 +   png_uint_32 y_pixels_per_unit; /* vertical pixel density */
 538.871 +   png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
 538.872 +#endif
 538.873 +
 538.874 +#if defined(PNG_hIST_SUPPORTED)
 538.875 +   /* The hIST chunk contains the relative frequency or importance of the
 538.876 +    * various palette entries, so that a viewer can intelligently select a
 538.877 +    * reduced-color palette, if required.  Data is an array of "num_palette"
 538.878 +    * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
 538.879 +    * is non-zero.
 538.880 +    */
 538.881 +   png_uint_16p hist;
 538.882 +#endif
 538.883 +
 538.884 +#ifdef PNG_cHRM_SUPPORTED
 538.885 +   /* The cHRM chunk describes the CIE color characteristics of the monitor
 538.886 +    * on which the PNG was created.  This data allows the viewer to do gamut
 538.887 +    * mapping of the input image to ensure that the viewer sees the same
 538.888 +    * colors in the image as the creator.  Values are in the range
 538.889 +    * [0.0, 0.8].  Data valid if (valid & PNG_INFO_cHRM) non-zero.
 538.890 +    */
 538.891 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 538.892 +   float x_white;
 538.893 +   float y_white;
 538.894 +   float x_red;
 538.895 +   float y_red;
 538.896 +   float x_green;
 538.897 +   float y_green;
 538.898 +   float x_blue;
 538.899 +   float y_blue;
 538.900 +#endif
 538.901 +#endif
 538.902 +
 538.903 +#if defined(PNG_pCAL_SUPPORTED)
 538.904 +   /* The pCAL chunk describes a transformation between the stored pixel
 538.905 +    * values and original physical data values used to create the image.
 538.906 +    * The integer range [0, 2^bit_depth - 1] maps to the floating-point
 538.907 +    * range given by [pcal_X0, pcal_X1], and are further transformed by a
 538.908 +    * (possibly non-linear) transformation function given by "pcal_type"
 538.909 +    * and "pcal_params" into "pcal_units".  Please see the PNG_EQUATION_
 538.910 +    * defines below, and the PNG-Group's PNG extensions document for a
 538.911 +    * complete description of the transformations and how they should be
 538.912 +    * implemented, and for a description of the ASCII parameter strings.
 538.913 +    * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
 538.914 +    */
 538.915 +   png_charp pcal_purpose;  /* pCAL chunk description string */
 538.916 +   png_int_32 pcal_X0;      /* minimum value */
 538.917 +   png_int_32 pcal_X1;      /* maximum value */
 538.918 +   png_charp pcal_units;    /* Latin-1 string giving physical units */
 538.919 +   png_charpp pcal_params;  /* ASCII strings containing parameter values */
 538.920 +   png_byte pcal_type;      /* equation type (see PNG_EQUATION_ below) */
 538.921 +   png_byte pcal_nparams;   /* number of parameters given in pcal_params */
 538.922 +#endif
 538.923 +
 538.924 +/* New members added in libpng-1.0.6 */
 538.925 +#ifdef PNG_FREE_ME_SUPPORTED
 538.926 +   png_uint_32 free_me;     /* flags items libpng is responsible for freeing */
 538.927 +#endif
 538.928 +
 538.929 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
 538.930 +   /* storage for unknown chunks that the library doesn't recognize. */
 538.931 +   png_unknown_chunkp unknown_chunks;
 538.932 +   png_size_t unknown_chunks_num;
 538.933 +#endif
 538.934 +
 538.935 +#if defined(PNG_iCCP_SUPPORTED)
 538.936 +   /* iCCP chunk data. */
 538.937 +   png_charp iccp_name;     /* profile name */
 538.938 +   png_charp iccp_profile;  /* International Color Consortium profile data */
 538.939 +                            /* Note to maintainer: should be png_bytep */
 538.940 +   png_uint_32 iccp_proflen;  /* ICC profile data length */
 538.941 +   png_byte iccp_compression; /* Always zero */
 538.942 +#endif
 538.943 +
 538.944 +#if defined(PNG_sPLT_SUPPORTED)
 538.945 +   /* data on sPLT chunks (there may be more than one). */
 538.946 +   png_sPLT_tp splt_palettes;
 538.947 +   png_uint_32 splt_palettes_num;
 538.948 +#endif
 538.949 +
 538.950 +#if defined(PNG_sCAL_SUPPORTED)
 538.951 +   /* The sCAL chunk describes the actual physical dimensions of the
 538.952 +    * subject matter of the graphic.  The chunk contains a unit specification
 538.953 +    * a byte value, and two ASCII strings representing floating-point
 538.954 +    * values.  The values are width and height corresponsing to one pixel
 538.955 +    * in the image.  This external representation is converted to double
 538.956 +    * here.  Data values are valid if (valid & PNG_INFO_sCAL) is non-zero.
 538.957 +    */
 538.958 +   png_byte scal_unit;         /* unit of physical scale */
 538.959 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 538.960 +   double scal_pixel_width;    /* width of one pixel */
 538.961 +   double scal_pixel_height;   /* height of one pixel */
 538.962 +#endif
 538.963 +#ifdef PNG_FIXED_POINT_SUPPORTED
 538.964 +   png_charp scal_s_width;     /* string containing height */
 538.965 +   png_charp scal_s_height;    /* string containing width */
 538.966 +#endif
 538.967 +#endif
 538.968 +
 538.969 +#if defined(PNG_INFO_IMAGE_SUPPORTED)
 538.970 +   /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */
 538.971 +   /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
 538.972 +   png_bytepp row_pointers;        /* the image bits */
 538.973 +#endif
 538.974 +
 538.975 +#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED)
 538.976 +   png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */
 538.977 +#endif
 538.978 +
 538.979 +#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED)
 538.980 +   png_fixed_point int_x_white;
 538.981 +   png_fixed_point int_y_white;
 538.982 +   png_fixed_point int_x_red;
 538.983 +   png_fixed_point int_y_red;
 538.984 +   png_fixed_point int_x_green;
 538.985 +   png_fixed_point int_y_green;
 538.986 +   png_fixed_point int_x_blue;
 538.987 +   png_fixed_point int_y_blue;
 538.988 +#endif
 538.989 +
 538.990 +} png_info;
 538.991 +
 538.992 +typedef png_info FAR * png_infop;
 538.993 +typedef png_info FAR * FAR * png_infopp;
 538.994 +
 538.995 +/* Maximum positive integer used in PNG is (2^31)-1 */
 538.996 +#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
 538.997 +#define PNG_UINT_32_MAX ((png_uint_32)(-1))
 538.998 +#define PNG_SIZE_MAX ((png_size_t)(-1))
 538.999 +#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
538.1000 +/* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */
538.1001 +#define PNG_MAX_UINT PNG_UINT_31_MAX
538.1002 +#endif
538.1003 +
538.1004 +/* These describe the color_type field in png_info. */
538.1005 +/* color type masks */
538.1006 +#define PNG_COLOR_MASK_PALETTE    1
538.1007 +#define PNG_COLOR_MASK_COLOR      2
538.1008 +#define PNG_COLOR_MASK_ALPHA      4
538.1009 +
538.1010 +/* color types.  Note that not all combinations are legal */
538.1011 +#define PNG_COLOR_TYPE_GRAY 0
538.1012 +#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
538.1013 +#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
538.1014 +#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
538.1015 +#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
538.1016 +/* aliases */
538.1017 +#define PNG_COLOR_TYPE_RGBA  PNG_COLOR_TYPE_RGB_ALPHA
538.1018 +#define PNG_COLOR_TYPE_GA  PNG_COLOR_TYPE_GRAY_ALPHA
538.1019 +
538.1020 +/* This is for compression type. PNG 1.0-1.2 only define the single type. */
538.1021 +#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
538.1022 +#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
538.1023 +
538.1024 +/* This is for filter type. PNG 1.0-1.2 only define the single type. */
538.1025 +#define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */
538.1026 +#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
538.1027 +#define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE
538.1028 +
538.1029 +/* These are for the interlacing type.  These values should NOT be changed. */
538.1030 +#define PNG_INTERLACE_NONE        0 /* Non-interlaced image */
538.1031 +#define PNG_INTERLACE_ADAM7       1 /* Adam7 interlacing */
538.1032 +#define PNG_INTERLACE_LAST        2 /* Not a valid value */
538.1033 +
538.1034 +/* These are for the oFFs chunk.  These values should NOT be changed. */
538.1035 +#define PNG_OFFSET_PIXEL          0 /* Offset in pixels */
538.1036 +#define PNG_OFFSET_MICROMETER     1 /* Offset in micrometers (1/10^6 meter) */
538.1037 +#define PNG_OFFSET_LAST           2 /* Not a valid value */
538.1038 +
538.1039 +/* These are for the pCAL chunk.  These values should NOT be changed. */
538.1040 +#define PNG_EQUATION_LINEAR       0 /* Linear transformation */
538.1041 +#define PNG_EQUATION_BASE_E       1 /* Exponential base e transform */
538.1042 +#define PNG_EQUATION_ARBITRARY    2 /* Arbitrary base exponential transform */
538.1043 +#define PNG_EQUATION_HYPERBOLIC   3 /* Hyperbolic sine transformation */
538.1044 +#define PNG_EQUATION_LAST         4 /* Not a valid value */
538.1045 +
538.1046 +/* These are for the sCAL chunk.  These values should NOT be changed. */
538.1047 +#define PNG_SCALE_UNKNOWN         0 /* unknown unit (image scale) */
538.1048 +#define PNG_SCALE_METER           1 /* meters per pixel */
538.1049 +#define PNG_SCALE_RADIAN          2 /* radians per pixel */
538.1050 +#define PNG_SCALE_LAST            3 /* Not a valid value */
538.1051 +
538.1052 +/* These are for the pHYs chunk.  These values should NOT be changed. */
538.1053 +#define PNG_RESOLUTION_UNKNOWN    0 /* pixels/unknown unit (aspect ratio) */
538.1054 +#define PNG_RESOLUTION_METER      1 /* pixels/meter */
538.1055 +#define PNG_RESOLUTION_LAST       2 /* Not a valid value */
538.1056 +
538.1057 +/* These are for the sRGB chunk.  These values should NOT be changed. */
538.1058 +#define PNG_sRGB_INTENT_PERCEPTUAL 0
538.1059 +#define PNG_sRGB_INTENT_RELATIVE   1
538.1060 +#define PNG_sRGB_INTENT_SATURATION 2
538.1061 +#define PNG_sRGB_INTENT_ABSOLUTE   3
538.1062 +#define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */
538.1063 +
538.1064 +/* This is for text chunks */
538.1065 +#define PNG_KEYWORD_MAX_LENGTH     79
538.1066 +
538.1067 +/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
538.1068 +#define PNG_MAX_PALETTE_LENGTH    256
538.1069 +
538.1070 +/* These determine if an ancillary chunk's data has been successfully read
538.1071 + * from the PNG header, or if the application has filled in the corresponding
538.1072 + * data in the info_struct to be written into the output file.  The values
538.1073 + * of the PNG_INFO_<chunk> defines should NOT be changed.
538.1074 + */
538.1075 +#define PNG_INFO_gAMA 0x0001
538.1076 +#define PNG_INFO_sBIT 0x0002
538.1077 +#define PNG_INFO_cHRM 0x0004
538.1078 +#define PNG_INFO_PLTE 0x0008
538.1079 +#define PNG_INFO_tRNS 0x0010
538.1080 +#define PNG_INFO_bKGD 0x0020
538.1081 +#define PNG_INFO_hIST 0x0040
538.1082 +#define PNG_INFO_pHYs 0x0080
538.1083 +#define PNG_INFO_oFFs 0x0100
538.1084 +#define PNG_INFO_tIME 0x0200
538.1085 +#define PNG_INFO_pCAL 0x0400
538.1086 +#define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
538.1087 +#define PNG_INFO_iCCP 0x1000   /* ESR, 1.0.6 */
538.1088 +#define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
538.1089 +#define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
538.1090 +#define PNG_INFO_IDAT 0x8000L  /* ESR, 1.0.6 */
538.1091 +
538.1092 +/* This is used for the transformation routines, as some of them
538.1093 + * change these values for the row.  It also should enable using
538.1094 + * the routines for other purposes.
538.1095 + */
538.1096 +typedef struct png_row_info_struct
538.1097 +{
538.1098 +   png_uint_32 width; /* width of row */
538.1099 +   png_uint_32 rowbytes; /* number of bytes in row */
538.1100 +   png_byte color_type; /* color type of row */
538.1101 +   png_byte bit_depth; /* bit depth of row */
538.1102 +   png_byte channels; /* number of channels (1, 2, 3, or 4) */
538.1103 +   png_byte pixel_depth; /* bits per pixel (depth * channels) */
538.1104 +} png_row_info;
538.1105 +
538.1106 +typedef png_row_info FAR * png_row_infop;
538.1107 +typedef png_row_info FAR * FAR * png_row_infopp;
538.1108 +
538.1109 +/* These are the function types for the I/O functions and for the functions
538.1110 + * that allow the user to override the default I/O functions with his or her
538.1111 + * own.  The png_error_ptr type should match that of user-supplied warning
538.1112 + * and error functions, while the png_rw_ptr type should match that of the
538.1113 + * user read/write data functions.
538.1114 + */
538.1115 +typedef struct png_struct_def png_struct;
538.1116 +typedef png_struct FAR * png_structp;
538.1117 +
538.1118 +typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
538.1119 +typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
538.1120 +typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp));
538.1121 +typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32,
538.1122 +   int));
538.1123 +typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32,
538.1124 +   int));
538.1125 +
538.1126 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
538.1127 +typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop));
538.1128 +typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
538.1129 +typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
538.1130 +   png_uint_32, int));
538.1131 +#endif
538.1132 +
538.1133 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
538.1134 +    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
538.1135 +    defined(PNG_LEGACY_SUPPORTED)
538.1136 +typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp,
538.1137 +    png_row_infop, png_bytep));
538.1138 +#endif
538.1139 +
538.1140 +#if defined(PNG_USER_CHUNKS_SUPPORTED)
538.1141 +typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp));
538.1142 +#endif
538.1143 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
538.1144 +typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp));
538.1145 +#endif
538.1146 +
538.1147 +/* Transform masks for the high-level interface */
538.1148 +#define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */
538.1149 +#define PNG_TRANSFORM_STRIP_16       0x0001    /* read only */
538.1150 +#define PNG_TRANSFORM_STRIP_ALPHA    0x0002    /* read only */
538.1151 +#define PNG_TRANSFORM_PACKING        0x0004    /* read and write */
538.1152 +#define PNG_TRANSFORM_PACKSWAP       0x0008    /* read and write */
538.1153 +#define PNG_TRANSFORM_EXPAND         0x0010    /* read only */
538.1154 +#define PNG_TRANSFORM_INVERT_MONO    0x0020    /* read and write */
538.1155 +#define PNG_TRANSFORM_SHIFT          0x0040    /* read and write */
538.1156 +#define PNG_TRANSFORM_BGR            0x0080    /* read and write */
538.1157 +#define PNG_TRANSFORM_SWAP_ALPHA     0x0100    /* read and write */
538.1158 +#define PNG_TRANSFORM_SWAP_ENDIAN    0x0200    /* read and write */
538.1159 +#define PNG_TRANSFORM_INVERT_ALPHA   0x0400    /* read and write */
538.1160 +#define PNG_TRANSFORM_STRIP_FILLER   0x0800    /* WRITE only */
538.1161 +
538.1162 +/* Flags for MNG supported features */
538.1163 +#define PNG_FLAG_MNG_EMPTY_PLTE     0x01
538.1164 +#define PNG_FLAG_MNG_FILTER_64      0x04
538.1165 +#define PNG_ALL_MNG_FEATURES        0x05
538.1166 +
538.1167 +typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
538.1168 +typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
538.1169 +
538.1170 +/* The structure that holds the information to read and write PNG files.
538.1171 + * The only people who need to care about what is inside of this are the
538.1172 + * people who will be modifying the library for their own special needs.
538.1173 + * It should NOT be accessed directly by an application, except to store
538.1174 + * the jmp_buf.
538.1175 + */
538.1176 +
538.1177 +struct png_struct_def
538.1178 +{
538.1179 +#ifdef PNG_SETJMP_SUPPORTED
538.1180 +   jmp_buf jmpbuf;            /* used in png_error */
538.1181 +#endif
538.1182 +   png_error_ptr error_fn;    /* function for printing errors and aborting */
538.1183 +   png_error_ptr warning_fn;  /* function for printing warnings */
538.1184 +   png_voidp error_ptr;       /* user supplied struct for error functions */
538.1185 +   png_rw_ptr write_data_fn;  /* function for writing output data */
538.1186 +   png_rw_ptr read_data_fn;   /* function for reading input data */
538.1187 +   png_voidp io_ptr;          /* ptr to application struct for I/O functions */
538.1188 +
538.1189 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
538.1190 +   png_user_transform_ptr read_user_transform_fn; /* user read transform */
538.1191 +#endif
538.1192 +
538.1193 +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
538.1194 +   png_user_transform_ptr write_user_transform_fn; /* user write transform */
538.1195 +#endif
538.1196 +
538.1197 +/* These were added in libpng-1.0.2 */
538.1198 +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
538.1199 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
538.1200 +    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
538.1201 +   png_voidp user_transform_ptr; /* user supplied struct for user transform */
538.1202 +   png_byte user_transform_depth;    /* bit depth of user transformed pixels */
538.1203 +   png_byte user_transform_channels; /* channels in user transformed pixels */
538.1204 +#endif
538.1205 +#endif
538.1206 +
538.1207 +   png_uint_32 mode;          /* tells us where we are in the PNG file */
538.1208 +   png_uint_32 flags;         /* flags indicating various things to libpng */
538.1209 +   png_uint_32 transformations; /* which transformations to perform */
538.1210 +
538.1211 +   z_stream zstream;          /* pointer to decompression structure (below) */
538.1212 +   png_bytep zbuf;            /* buffer for zlib */
538.1213 +   png_size_t zbuf_size;      /* size of zbuf */
538.1214 +   int zlib_level;            /* holds zlib compression level */
538.1215 +   int zlib_method;           /* holds zlib compression method */
538.1216 +   int zlib_window_bits;      /* holds zlib compression window bits */
538.1217 +   int zlib_mem_level;        /* holds zlib compression memory level */
538.1218 +   int zlib_strategy;         /* holds zlib compression strategy */
538.1219 +
538.1220 +   png_uint_32 width;         /* width of image in pixels */
538.1221 +   png_uint_32 height;        /* height of image in pixels */
538.1222 +   png_uint_32 num_rows;      /* number of rows in current pass */
538.1223 +   png_uint_32 usr_width;     /* width of row at start of write */
538.1224 +   png_uint_32 rowbytes;      /* size of row in bytes */
538.1225 +   png_uint_32 irowbytes;     /* size of current interlaced row in bytes */
538.1226 +   png_uint_32 iwidth;        /* width of current interlaced row in pixels */
538.1227 +   png_uint_32 row_number;    /* current row in interlace pass */
538.1228 +   png_bytep prev_row;        /* buffer to save previous (unfiltered) row */
538.1229 +   png_bytep row_buf;         /* buffer to save current (unfiltered) row */
538.1230 +#ifndef PNG_NO_WRITE_FILTER
538.1231 +   png_bytep sub_row;         /* buffer to save "sub" row when filtering */
538.1232 +   png_bytep up_row;          /* buffer to save "up" row when filtering */
538.1233 +   png_bytep avg_row;         /* buffer to save "avg" row when filtering */
538.1234 +   png_bytep paeth_row;       /* buffer to save "Paeth" row when filtering */
538.1235 +#endif
538.1236 +   png_row_info row_info;     /* used for transformation routines */
538.1237 +
538.1238 +   png_uint_32 idat_size;     /* current IDAT size for read */
538.1239 +   png_uint_32 crc;           /* current chunk CRC value */
538.1240 +   png_colorp palette;        /* palette from the input file */
538.1241 +   png_uint_16 num_palette;   /* number of color entries in palette */
538.1242 +   png_uint_16 num_trans;     /* number of transparency values */
538.1243 +   png_byte chunk_name[5];    /* null-terminated name of current chunk */
538.1244 +   png_byte compression;      /* file compression type (always 0) */
538.1245 +   png_byte filter;           /* file filter type (always 0) */
538.1246 +   png_byte interlaced;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
538.1247 +   png_byte pass;             /* current interlace pass (0 - 6) */
538.1248 +   png_byte do_filter;        /* row filter flags (see PNG_FILTER_ below ) */
538.1249 +   png_byte color_type;       /* color type of file */
538.1250 +   png_byte bit_depth;        /* bit depth of file */
538.1251 +   png_byte usr_bit_depth;    /* bit depth of users row */
538.1252 +   png_byte pixel_depth;      /* number of bits per pixel */
538.1253 +   png_byte channels;         /* number of channels in file */
538.1254 +   png_byte usr_channels;     /* channels at start of write */
538.1255 +   png_byte sig_bytes;        /* magic bytes read/written from start of file */
538.1256 +
538.1257 +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
538.1258 +#ifdef PNG_LEGACY_SUPPORTED
538.1259 +   png_byte filler;           /* filler byte for pixel expansion */
538.1260 +#else
538.1261 +   png_uint_16 filler;           /* filler bytes for pixel expansion */
538.1262 +#endif
538.1263 +#endif
538.1264 +
538.1265 +#if defined(PNG_bKGD_SUPPORTED)
538.1266 +   png_byte background_gamma_type;
538.1267 +#  ifdef PNG_FLOATING_POINT_SUPPORTED
538.1268 +   float background_gamma;
538.1269 +#  endif
538.1270 +   png_color_16 background;   /* background color in screen gamma space */
538.1271 +#if defined(PNG_READ_GAMMA_SUPPORTED)
538.1272 +   png_color_16 background_1; /* background normalized to gamma 1.0 */
538.1273 +#endif
538.1274 +#endif /* PNG_bKGD_SUPPORTED */
538.1275 +
538.1276 +#if defined(PNG_WRITE_FLUSH_SUPPORTED)
538.1277 +   png_flush_ptr output_flush_fn;/* Function for flushing output */
538.1278 +   png_uint_32 flush_dist;    /* how many rows apart to flush, 0 - no flush */
538.1279 +   png_uint_32 flush_rows;    /* number of rows written since last flush */
538.1280 +#endif
538.1281 +
538.1282 +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
538.1283 +   int gamma_shift;      /* number of "insignificant" bits 16-bit gamma */
538.1284 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.1285 +   float gamma;          /* file gamma value */
538.1286 +   float screen_gamma;   /* screen gamma value (display_exponent) */
538.1287 +#endif
538.1288 +#endif
538.1289 +
538.1290 +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
538.1291 +   png_bytep gamma_table;     /* gamma table for 8-bit depth files */
538.1292 +   png_bytep gamma_from_1;    /* converts from 1.0 to screen */
538.1293 +   png_bytep gamma_to_1;      /* converts from file to 1.0 */
538.1294 +   png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
538.1295 +   png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
538.1296 +   png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
538.1297 +#endif
538.1298 +
538.1299 +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
538.1300 +   png_color_8 sig_bit;       /* significant bits in each available channel */
538.1301 +#endif
538.1302 +
538.1303 +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
538.1304 +   png_color_8 shift;         /* shift for significant bit tranformation */
538.1305 +#endif
538.1306 +
538.1307 +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
538.1308 + || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
538.1309 +   png_bytep trans;           /* transparency values for paletted files */
538.1310 +   png_color_16 trans_values; /* transparency values for non-paletted files */
538.1311 +#endif
538.1312 +
538.1313 +   png_read_status_ptr read_row_fn;   /* called after each row is decoded */
538.1314 +   png_write_status_ptr write_row_fn; /* called after each row is encoded */
538.1315 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
538.1316 +   png_progressive_info_ptr info_fn; /* called after header data fully read */
538.1317 +   png_progressive_row_ptr row_fn;   /* called after each prog. row is decoded */
538.1318 +   png_progressive_end_ptr end_fn;   /* called after image is complete */
538.1319 +   png_bytep save_buffer_ptr;        /* current location in save_buffer */
538.1320 +   png_bytep save_buffer;            /* buffer for previously read data */
538.1321 +   png_bytep current_buffer_ptr;     /* current location in current_buffer */
538.1322 +   png_bytep current_buffer;         /* buffer for recently used data */
538.1323 +   png_uint_32 push_length;          /* size of current input chunk */
538.1324 +   png_uint_32 skip_length;          /* bytes to skip in input data */
538.1325 +   png_size_t save_buffer_size;      /* amount of data now in save_buffer */
538.1326 +   png_size_t save_buffer_max;       /* total size of save_buffer */
538.1327 +   png_size_t buffer_size;           /* total amount of available input data */
538.1328 +   png_size_t current_buffer_size;   /* amount of data now in current_buffer */
538.1329 +   int process_mode;                 /* what push library is currently doing */
538.1330 +   int cur_palette;                  /* current push library palette index */
538.1331 +
538.1332 +#  if defined(PNG_TEXT_SUPPORTED)
538.1333 +     png_size_t current_text_size;   /* current size of text input data */
538.1334 +     png_size_t current_text_left;   /* how much text left to read in input */
538.1335 +     png_charp current_text;         /* current text chunk buffer */
538.1336 +     png_charp current_text_ptr;     /* current location in current_text */
538.1337 +#  endif /* PNG_TEXT_SUPPORTED */
538.1338 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
538.1339 +
538.1340 +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
538.1341 +/* for the Borland special 64K segment handler */
538.1342 +   png_bytepp offset_table_ptr;
538.1343 +   png_bytep offset_table;
538.1344 +   png_uint_16 offset_table_number;
538.1345 +   png_uint_16 offset_table_count;
538.1346 +   png_uint_16 offset_table_count_free;
538.1347 +#endif
538.1348 +
538.1349 +#if defined(PNG_READ_DITHER_SUPPORTED)
538.1350 +   png_bytep palette_lookup;         /* lookup table for dithering */
538.1351 +   png_bytep dither_index;           /* index translation for palette files */
538.1352 +#endif
538.1353 +
538.1354 +#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
538.1355 +   png_uint_16p hist;                /* histogram */
538.1356 +#endif
538.1357 +
538.1358 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
538.1359 +   png_byte heuristic_method;        /* heuristic for row filter selection */
538.1360 +   png_byte num_prev_filters;        /* number of weights for previous rows */
538.1361 +   png_bytep prev_filters;           /* filter type(s) of previous row(s) */
538.1362 +   png_uint_16p filter_weights;      /* weight(s) for previous line(s) */
538.1363 +   png_uint_16p inv_filter_weights;  /* 1/weight(s) for previous line(s) */
538.1364 +   png_uint_16p filter_costs;        /* relative filter calculation cost */
538.1365 +   png_uint_16p inv_filter_costs;    /* 1/relative filter calculation cost */
538.1366 +#endif
538.1367 +
538.1368 +#if defined(PNG_TIME_RFC1123_SUPPORTED)
538.1369 +   png_charp time_buffer;            /* String to hold RFC 1123 time text */
538.1370 +#endif
538.1371 +
538.1372 +/* New members added in libpng-1.0.6 */
538.1373 +
538.1374 +#ifdef PNG_FREE_ME_SUPPORTED
538.1375 +   png_uint_32 free_me;       /* flags items libpng is responsible for freeing */
538.1376 +#endif
538.1377 +
538.1378 +#if defined(PNG_USER_CHUNKS_SUPPORTED)
538.1379 +   png_voidp user_chunk_ptr;
538.1380 +   png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
538.1381 +#endif
538.1382 +
538.1383 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
538.1384 +   int num_chunk_list;
538.1385 +   png_bytep chunk_list;
538.1386 +#endif
538.1387 +
538.1388 +/* New members added in libpng-1.0.3 */
538.1389 +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
538.1390 +   png_byte rgb_to_gray_status;
538.1391 +   /* These were changed from png_byte in libpng-1.0.6 */
538.1392 +   png_uint_16 rgb_to_gray_red_coeff;
538.1393 +   png_uint_16 rgb_to_gray_green_coeff;
538.1394 +   png_uint_16 rgb_to_gray_blue_coeff;
538.1395 +#endif
538.1396 +
538.1397 +/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
538.1398 +#if defined(PNG_MNG_FEATURES_SUPPORTED) || \
538.1399 +    defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
538.1400 +    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
538.1401 +/* changed from png_byte to png_uint_32 at version 1.2.0 */
538.1402 +#ifdef PNG_1_0_X
538.1403 +   png_byte mng_features_permitted;
538.1404 +#else
538.1405 +   png_uint_32 mng_features_permitted;
538.1406 +#endif /* PNG_1_0_X */
538.1407 +#endif
538.1408 +
538.1409 +/* New member added in libpng-1.0.7 */
538.1410 +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
538.1411 +   png_fixed_point int_gamma;
538.1412 +#endif
538.1413 +
538.1414 +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
538.1415 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
538.1416 +   png_byte filter_type;
538.1417 +#endif
538.1418 +
538.1419 +#if defined(PNG_1_0_X)
538.1420 +/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */
538.1421 +   png_uint_32 row_buf_size;
538.1422 +#endif
538.1423 +
538.1424 +/* New members added in libpng-1.2.0 */
538.1425 +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
538.1426 +#  if !defined(PNG_1_0_X)
538.1427 +#    if defined(PNG_MMX_CODE_SUPPORTED)
538.1428 +   png_byte     mmx_bitdepth_threshold;
538.1429 +   png_uint_32  mmx_rowbytes_threshold;
538.1430 +#    endif
538.1431 +   png_uint_32  asm_flags;
538.1432 +#  endif
538.1433 +#endif
538.1434 +
538.1435 +/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
538.1436 +#ifdef PNG_USER_MEM_SUPPORTED
538.1437 +   png_voidp mem_ptr;                /* user supplied struct for mem functions */
538.1438 +   png_malloc_ptr malloc_fn;         /* function for allocating memory */
538.1439 +   png_free_ptr free_fn;             /* function for freeing memory */
538.1440 +#endif
538.1441 +
538.1442 +/* New member added in libpng-1.0.13 and 1.2.0 */
538.1443 +   png_bytep big_row_buf;         /* buffer to save current (unfiltered) row */
538.1444 +
538.1445 +#if defined(PNG_READ_DITHER_SUPPORTED)
538.1446 +/* The following three members were added at version 1.0.14 and 1.2.4 */
538.1447 +   png_bytep dither_sort;            /* working sort array */
538.1448 +   png_bytep index_to_palette;       /* where the original index currently is */
538.1449 +                                     /* in the palette */
538.1450 +   png_bytep palette_to_index;       /* which original index points to this */
538.1451 +                                     /* palette color */
538.1452 +#endif
538.1453 +
538.1454 +/* New members added in libpng-1.0.16 and 1.2.6 */
538.1455 +   png_byte compression_type;
538.1456 +
538.1457 +#ifdef PNG_SET_USER_LIMITS_SUPPORTED
538.1458 +   png_uint_32 user_width_max;
538.1459 +   png_uint_32 user_height_max;
538.1460 +#endif
538.1461 +
538.1462 +/* New member added in libpng-1.0.25 and 1.2.17 */
538.1463 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
538.1464 +   /* storage for unknown chunk that the library doesn't recognize. */
538.1465 +   png_unknown_chunk unknown_chunk;
538.1466 +#endif
538.1467 +
538.1468 +/* New members added in libpng-1.2.26 */
538.1469 +  png_uint_32 old_big_row_buf_size, old_prev_row_size;
538.1470 +
538.1471 +/* New member added in libpng-1.2.30 */
538.1472 +  png_charp chunkdata;  /* buffer for reading chunk data */
538.1473 +
538.1474 +};
538.1475 +
538.1476 +
538.1477 +/* This triggers a compiler error in png.c, if png.c and png.h
538.1478 + * do not agree upon the version number.
538.1479 + */
538.1480 +typedef png_structp version_1_2_33;
538.1481 +
538.1482 +typedef png_struct FAR * FAR * png_structpp;
538.1483 +
538.1484 +/* Here are the function definitions most commonly used.  This is not
538.1485 + * the place to find out how to use libpng.  See libpng.txt for the
538.1486 + * full explanation, see example.c for the summary.  This just provides
538.1487 + * a simple one line description of the use of each function.
538.1488 + */
538.1489 +
538.1490 +/* Returns the version number of the library */
538.1491 +extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
538.1492 +
538.1493 +/* Tell lib we have already handled the first <num_bytes> magic bytes.
538.1494 + * Handling more than 8 bytes from the beginning of the file is an error.
538.1495 + */
538.1496 +extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
538.1497 +   int num_bytes));
538.1498 +
538.1499 +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
538.1500 + * PNG file.  Returns zero if the supplied bytes match the 8-byte PNG
538.1501 + * signature, and non-zero otherwise.  Having num_to_check == 0 or
538.1502 + * start > 7 will always fail (ie return non-zero).
538.1503 + */
538.1504 +extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
538.1505 +   png_size_t num_to_check));
538.1506 +
538.1507 +/* Simple signature checking function.  This is the same as calling
538.1508 + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
538.1509 + */
538.1510 +extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num));
538.1511 +
538.1512 +/* Allocate and initialize png_ptr struct for reading, and any other memory. */
538.1513 +extern PNG_EXPORT(png_structp,png_create_read_struct)
538.1514 +   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
538.1515 +   png_error_ptr error_fn, png_error_ptr warn_fn));
538.1516 +
538.1517 +/* Allocate and initialize png_ptr struct for writing, and any other memory */
538.1518 +extern PNG_EXPORT(png_structp,png_create_write_struct)
538.1519 +   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
538.1520 +   png_error_ptr error_fn, png_error_ptr warn_fn));
538.1521 +
538.1522 +#ifdef PNG_WRITE_SUPPORTED
538.1523 +extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size)
538.1524 +   PNGARG((png_structp png_ptr));
538.1525 +#endif
538.1526 +
538.1527 +#ifdef PNG_WRITE_SUPPORTED
538.1528 +extern PNG_EXPORT(void,png_set_compression_buffer_size)
538.1529 +   PNGARG((png_structp png_ptr, png_uint_32 size));
538.1530 +#endif
538.1531 +
538.1532 +/* Reset the compression stream */
538.1533 +extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
538.1534 +
538.1535 +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
538.1536 +#ifdef PNG_USER_MEM_SUPPORTED
538.1537 +extern PNG_EXPORT(png_structp,png_create_read_struct_2)
538.1538 +   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
538.1539 +   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
538.1540 +   png_malloc_ptr malloc_fn, png_free_ptr free_fn));
538.1541 +extern PNG_EXPORT(png_structp,png_create_write_struct_2)
538.1542 +   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
538.1543 +   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
538.1544 +   png_malloc_ptr malloc_fn, png_free_ptr free_fn));
538.1545 +#endif
538.1546 +
538.1547 +/* Write a PNG chunk - size, type, (optional) data, CRC. */
538.1548 +extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
538.1549 +   png_bytep chunk_name, png_bytep data, png_size_t length));
538.1550 +
538.1551 +/* Write the start of a PNG chunk - length and chunk name. */
538.1552 +extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr,
538.1553 +   png_bytep chunk_name, png_uint_32 length));
538.1554 +
538.1555 +/* Write the data of a PNG chunk started with png_write_chunk_start(). */
538.1556 +extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr,
538.1557 +   png_bytep data, png_size_t length));
538.1558 +
538.1559 +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
538.1560 +extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr));
538.1561 +
538.1562 +/* Allocate and initialize the info structure */
538.1563 +extern PNG_EXPORT(png_infop,png_create_info_struct)
538.1564 +   PNGARG((png_structp png_ptr));
538.1565 +
538.1566 +#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
538.1567 +/* Initialize the info structure (old interface - DEPRECATED) */
538.1568 +extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr));
538.1569 +#undef png_info_init
538.1570 +#define png_info_init(info_ptr) png_info_init_3(&info_ptr,\
538.1571 +    png_sizeof(png_info));
538.1572 +#endif
538.1573 +
538.1574 +extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr,
538.1575 +    png_size_t png_info_struct_size));
538.1576 +
538.1577 +/* Writes all the PNG information before the image. */
538.1578 +extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
538.1579 +   png_infop info_ptr));
538.1580 +extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
538.1581 +   png_infop info_ptr));
538.1582 +
538.1583 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
538.1584 +/* read the information before the actual image data. */
538.1585 +extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
538.1586 +   png_infop info_ptr));
538.1587 +#endif
538.1588 +
538.1589 +#if defined(PNG_TIME_RFC1123_SUPPORTED)
538.1590 +extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
538.1591 +   PNGARG((png_structp png_ptr, png_timep ptime));
538.1592 +#endif
538.1593 +
538.1594 +#if !defined(_WIN32_WCE)
538.1595 +/* "time.h" functions are not supported on WindowsCE */
538.1596 +#if defined(PNG_WRITE_tIME_SUPPORTED)
538.1597 +/* convert from a struct tm to png_time */
538.1598 +extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
538.1599 +   struct tm FAR * ttime));
538.1600 +
538.1601 +/* convert from time_t to png_time.  Uses gmtime() */
538.1602 +extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
538.1603 +   time_t ttime));
538.1604 +#endif /* PNG_WRITE_tIME_SUPPORTED */
538.1605 +#endif /* _WIN32_WCE */
538.1606 +
538.1607 +#if defined(PNG_READ_EXPAND_SUPPORTED)
538.1608 +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
538.1609 +extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
538.1610 +#if !defined(PNG_1_0_X)
538.1611 +extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp
538.1612 +  png_ptr));
538.1613 +#endif
538.1614 +extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
538.1615 +extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr));
538.1616 +#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
538.1617 +/* Deprecated */
538.1618 +extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr));
538.1619 +#endif
538.1620 +#endif
538.1621 +
538.1622 +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
538.1623 +/* Use blue, green, red order for pixels. */
538.1624 +extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
538.1625 +#endif
538.1626 +
538.1627 +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
538.1628 +/* Expand the grayscale to 24-bit RGB if necessary. */
538.1629 +extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
538.1630 +#endif
538.1631 +
538.1632 +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
538.1633 +/* Reduce RGB to grayscale. */
538.1634 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.1635 +extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
538.1636 +   int error_action, double red, double green ));
538.1637 +#endif
538.1638 +extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr,
538.1639 +   int error_action, png_fixed_point red, png_fixed_point green ));
538.1640 +extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
538.1641 +   png_ptr));
538.1642 +#endif
538.1643 +
538.1644 +extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
538.1645 +   png_colorp palette));
538.1646 +
538.1647 +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
538.1648 +extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
538.1649 +#endif
538.1650 +
538.1651 +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
538.1652 +    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
538.1653 +extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
538.1654 +#endif
538.1655 +
538.1656 +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
538.1657 +    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
538.1658 +extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
538.1659 +#endif
538.1660 +
538.1661 +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
538.1662 +/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
538.1663 +extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
538.1664 +   png_uint_32 filler, int flags));
538.1665 +/* The values of the PNG_FILLER_ defines should NOT be changed */
538.1666 +#define PNG_FILLER_BEFORE 0
538.1667 +#define PNG_FILLER_AFTER 1
538.1668 +/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
538.1669 +#if !defined(PNG_1_0_X)
538.1670 +extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr,
538.1671 +   png_uint_32 filler, int flags));
538.1672 +#endif
538.1673 +#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
538.1674 +
538.1675 +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
538.1676 +/* Swap bytes in 16-bit depth files. */
538.1677 +extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
538.1678 +#endif
538.1679 +
538.1680 +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
538.1681 +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
538.1682 +extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
538.1683 +#endif
538.1684 +
538.1685 +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
538.1686 +/* Swap packing order of pixels in bytes. */
538.1687 +extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
538.1688 +#endif
538.1689 +
538.1690 +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
538.1691 +/* Converts files to legal bit depths. */
538.1692 +extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
538.1693 +   png_color_8p true_bits));
538.1694 +#endif
538.1695 +
538.1696 +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
538.1697 +    defined(PNG_WRITE_INTERLACING_SUPPORTED)
538.1698 +/* Have the code handle the interlacing.  Returns the number of passes. */
538.1699 +extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
538.1700 +#endif
538.1701 +
538.1702 +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
538.1703 +/* Invert monochrome files */
538.1704 +extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
538.1705 +#endif
538.1706 +
538.1707 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
538.1708 +/* Handle alpha and tRNS by replacing with a background color. */
538.1709 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.1710 +extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
538.1711 +   png_color_16p background_color, int background_gamma_code,
538.1712 +   int need_expand, double background_gamma));
538.1713 +#endif
538.1714 +#define PNG_BACKGROUND_GAMMA_UNKNOWN 0
538.1715 +#define PNG_BACKGROUND_GAMMA_SCREEN  1
538.1716 +#define PNG_BACKGROUND_GAMMA_FILE    2
538.1717 +#define PNG_BACKGROUND_GAMMA_UNIQUE  3
538.1718 +#endif
538.1719 +
538.1720 +#if defined(PNG_READ_16_TO_8_SUPPORTED)
538.1721 +/* strip the second byte of information from a 16-bit depth file. */
538.1722 +extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
538.1723 +#endif
538.1724 +
538.1725 +#if defined(PNG_READ_DITHER_SUPPORTED)
538.1726 +/* Turn on dithering, and reduce the palette to the number of colors available. */
538.1727 +extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
538.1728 +   png_colorp palette, int num_palette, int maximum_colors,
538.1729 +   png_uint_16p histogram, int full_dither));
538.1730 +#endif
538.1731 +
538.1732 +#if defined(PNG_READ_GAMMA_SUPPORTED)
538.1733 +/* Handle gamma correction. Screen_gamma=(display_exponent) */
538.1734 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.1735 +extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
538.1736 +   double screen_gamma, double default_file_gamma));
538.1737 +#endif
538.1738 +#endif
538.1739 +
538.1740 +#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
538.1741 +#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
538.1742 +    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
538.1743 +/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */
538.1744 +/* Deprecated and will be removed.  Use png_permit_mng_features() instead. */
538.1745 +extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr,
538.1746 +   int empty_plte_permitted));
538.1747 +#endif
538.1748 +#endif
538.1749 +
538.1750 +#if defined(PNG_WRITE_FLUSH_SUPPORTED)
538.1751 +/* Set how many lines between output flushes - 0 for no flushing */
538.1752 +extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
538.1753 +/* Flush the current PNG output buffer */
538.1754 +extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
538.1755 +#endif
538.1756 +
538.1757 +/* optional update palette with requested transformations */
538.1758 +extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
538.1759 +
538.1760 +/* optional call to update the users info structure */
538.1761 +extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
538.1762 +   png_infop info_ptr));
538.1763 +
538.1764 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
538.1765 +/* read one or more rows of image data. */
538.1766 +extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
538.1767 +   png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
538.1768 +#endif
538.1769 +
538.1770 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
538.1771 +/* read a row of data. */
538.1772 +extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
538.1773 +   png_bytep row,
538.1774 +   png_bytep display_row));
538.1775 +#endif
538.1776 +
538.1777 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
538.1778 +/* read the whole image into memory at once. */
538.1779 +extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
538.1780 +   png_bytepp image));
538.1781 +#endif
538.1782 +
538.1783 +/* write a row of image data */
538.1784 +extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
538.1785 +   png_bytep row));
538.1786 +
538.1787 +/* write a few rows of image data */
538.1788 +extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr,
538.1789 +   png_bytepp row, png_uint_32 num_rows));
538.1790 +
538.1791 +/* write the image data */
538.1792 +extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
538.1793 +   png_bytepp image));
538.1794 +
538.1795 +/* writes the end of the PNG file. */
538.1796 +extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
538.1797 +   png_infop info_ptr));
538.1798 +
538.1799 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
538.1800 +/* read the end of the PNG file. */
538.1801 +extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
538.1802 +   png_infop info_ptr));
538.1803 +#endif
538.1804 +
538.1805 +/* free any memory associated with the png_info_struct */
538.1806 +extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
538.1807 +   png_infopp info_ptr_ptr));
538.1808 +
538.1809 +/* free any memory associated with the png_struct and the png_info_structs */
538.1810 +extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
538.1811 +   png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
538.1812 +
538.1813 +/* free all memory used by the read (old method - NOT DLL EXPORTED) */
538.1814 +extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
538.1815 +   png_infop end_info_ptr));
538.1816 +
538.1817 +/* free any memory associated with the png_struct and the png_info_structs */
538.1818 +extern PNG_EXPORT(void,png_destroy_write_struct)
538.1819 +   PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
538.1820 +
538.1821 +/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
538.1822 +extern void png_write_destroy PNGARG((png_structp png_ptr));
538.1823 +
538.1824 +/* set the libpng method of handling chunk CRC errors */
538.1825 +extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
538.1826 +   int crit_action, int ancil_action));
538.1827 +
538.1828 +/* Values for png_set_crc_action() to say how to handle CRC errors in
538.1829 + * ancillary and critical chunks, and whether to use the data contained
538.1830 + * therein.  Note that it is impossible to "discard" data in a critical
538.1831 + * chunk.  For versions prior to 0.90, the action was always error/quit,
538.1832 + * whereas in version 0.90 and later, the action for CRC errors in ancillary
538.1833 + * chunks is warn/discard.  These values should NOT be changed.
538.1834 + *
538.1835 + *      value                       action:critical     action:ancillary
538.1836 + */
538.1837 +#define PNG_CRC_DEFAULT       0  /* error/quit          warn/discard data */
538.1838 +#define PNG_CRC_ERROR_QUIT    1  /* error/quit          error/quit        */
538.1839 +#define PNG_CRC_WARN_DISCARD  2  /* (INVALID)           warn/discard data */
538.1840 +#define PNG_CRC_WARN_USE      3  /* warn/use data       warn/use data     */
538.1841 +#define PNG_CRC_QUIET_USE     4  /* quiet/use data      quiet/use data    */
538.1842 +#define PNG_CRC_NO_CHANGE     5  /* use current value   use current value */
538.1843 +
538.1844 +/* These functions give the user control over the scan-line filtering in
538.1845 + * libpng and the compression methods used by zlib.  These functions are
538.1846 + * mainly useful for testing, as the defaults should work with most users.
538.1847 + * Those users who are tight on memory or want faster performance at the
538.1848 + * expense of compression can modify them.  See the compression library
538.1849 + * header file (zlib.h) for an explination of the compression functions.
538.1850 + */
538.1851 +
538.1852 +/* set the filtering method(s) used by libpng.  Currently, the only valid
538.1853 + * value for "method" is 0.
538.1854 + */
538.1855 +extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method,
538.1856 +   int filters));
538.1857 +
538.1858 +/* Flags for png_set_filter() to say which filters to use.  The flags
538.1859 + * are chosen so that they don't conflict with real filter types
538.1860 + * below, in case they are supplied instead of the #defined constants.
538.1861 + * These values should NOT be changed.
538.1862 + */
538.1863 +#define PNG_NO_FILTERS     0x00
538.1864 +#define PNG_FILTER_NONE    0x08
538.1865 +#define PNG_FILTER_SUB     0x10
538.1866 +#define PNG_FILTER_UP      0x20
538.1867 +#define PNG_FILTER_AVG     0x40
538.1868 +#define PNG_FILTER_PAETH   0x80
538.1869 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
538.1870 +                         PNG_FILTER_AVG | PNG_FILTER_PAETH)
538.1871 +
538.1872 +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
538.1873 + * These defines should NOT be changed.
538.1874 + */
538.1875 +#define PNG_FILTER_VALUE_NONE  0
538.1876 +#define PNG_FILTER_VALUE_SUB   1
538.1877 +#define PNG_FILTER_VALUE_UP    2
538.1878 +#define PNG_FILTER_VALUE_AVG   3
538.1879 +#define PNG_FILTER_VALUE_PAETH 4
538.1880 +#define PNG_FILTER_VALUE_LAST  5
538.1881 +
538.1882 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */
538.1883 +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
538.1884 + * defines, either the default (minimum-sum-of-absolute-differences), or
538.1885 + * the experimental method (weighted-minimum-sum-of-absolute-differences).
538.1886 + *
538.1887 + * Weights are factors >= 1.0, indicating how important it is to keep the
538.1888 + * filter type consistent between rows.  Larger numbers mean the current
538.1889 + * filter is that many times as likely to be the same as the "num_weights"
538.1890 + * previous filters.  This is cumulative for each previous row with a weight.
538.1891 + * There needs to be "num_weights" values in "filter_weights", or it can be
538.1892 + * NULL if the weights aren't being specified.  Weights have no influence on
538.1893 + * the selection of the first row filter.  Well chosen weights can (in theory)
538.1894 + * improve the compression for a given image.
538.1895 + *
538.1896 + * Costs are factors >= 1.0 indicating the relative decoding costs of a
538.1897 + * filter type.  Higher costs indicate more decoding expense, and are
538.1898 + * therefore less likely to be selected over a filter with lower computational
538.1899 + * costs.  There needs to be a value in "filter_costs" for each valid filter
538.1900 + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
538.1901 + * setting the costs.  Costs try to improve the speed of decompression without
538.1902 + * unduly increasing the compressed image size.
538.1903 + *
538.1904 + * A negative weight or cost indicates the default value is to be used, and
538.1905 + * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
538.1906 + * The default values for both weights and costs are currently 1.0, but may
538.1907 + * change if good general weighting/cost heuristics can be found.  If both
538.1908 + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
538.1909 + * to the UNWEIGHTED method, but with added encoding time/computation.
538.1910 + */
538.1911 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.1912 +extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
538.1913 +   int heuristic_method, int num_weights, png_doublep filter_weights,
538.1914 +   png_doublep filter_costs));
538.1915 +#endif
538.1916 +#endif /*  PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
538.1917 +
538.1918 +/* Heuristic used for row filter selection.  These defines should NOT be
538.1919 + * changed.
538.1920 + */
538.1921 +#define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently "UNWEIGHTED" */
538.1922 +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */
538.1923 +#define PNG_FILTER_HEURISTIC_WEIGHTED   2  /* Experimental feature */
538.1924 +#define PNG_FILTER_HEURISTIC_LAST       3  /* Not a valid value */
538.1925 +
538.1926 +/* Set the library compression level.  Currently, valid values range from
538.1927 + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
538.1928 + * (0 - no compression, 9 - "maximal" compression).  Note that tests have
538.1929 + * shown that zlib compression levels 3-6 usually perform as well as level 9
538.1930 + * for PNG images, and do considerably fewer caclulations.  In the future,
538.1931 + * these values may not correspond directly to the zlib compression levels.
538.1932 + */
538.1933 +extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
538.1934 +   int level));
538.1935 +
538.1936 +extern PNG_EXPORT(void,png_set_compression_mem_level)
538.1937 +   PNGARG((png_structp png_ptr, int mem_level));
538.1938 +
538.1939 +extern PNG_EXPORT(void,png_set_compression_strategy)
538.1940 +   PNGARG((png_structp png_ptr, int strategy));
538.1941 +
538.1942 +extern PNG_EXPORT(void,png_set_compression_window_bits)
538.1943 +   PNGARG((png_structp png_ptr, int window_bits));
538.1944 +
538.1945 +extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
538.1946 +   int method));
538.1947 +
538.1948 +/* These next functions are called for input/output, memory, and error
538.1949 + * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,
538.1950 + * and call standard C I/O routines such as fread(), fwrite(), and
538.1951 + * fprintf().  These functions can be made to use other I/O routines
538.1952 + * at run time for those applications that need to handle I/O in a
538.1953 + * different manner by calling png_set_???_fn().  See libpng.txt for
538.1954 + * more information.
538.1955 + */
538.1956 +
538.1957 +#if !defined(PNG_NO_STDIO)
538.1958 +/* Initialize the input/output for the PNG file to the default functions. */
538.1959 +extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp));
538.1960 +#endif
538.1961 +
538.1962 +/* Replace the (error and abort), and warning functions with user
538.1963 + * supplied functions.  If no messages are to be printed you must still
538.1964 + * write and use replacement functions. The replacement error_fn should
538.1965 + * still do a longjmp to the last setjmp location if you are using this
538.1966 + * method of error handling.  If error_fn or warning_fn is NULL, the
538.1967 + * default function will be used.
538.1968 + */
538.1969 +
538.1970 +extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
538.1971 +   png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
538.1972 +
538.1973 +/* Return the user pointer associated with the error functions */
538.1974 +extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
538.1975 +
538.1976 +/* Replace the default data output functions with a user supplied one(s).
538.1977 + * If buffered output is not used, then output_flush_fn can be set to NULL.
538.1978 + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
538.1979 + * output_flush_fn will be ignored (and thus can be NULL).
538.1980 + */
538.1981 +extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
538.1982 +   png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
538.1983 +
538.1984 +/* Replace the default data input function with a user supplied one. */
538.1985 +extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr,
538.1986 +   png_voidp io_ptr, png_rw_ptr read_data_fn));
538.1987 +
538.1988 +/* Return the user pointer associated with the I/O functions */
538.1989 +extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr));
538.1990 +
538.1991 +extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr,
538.1992 +   png_read_status_ptr read_row_fn));
538.1993 +
538.1994 +extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr,
538.1995 +   png_write_status_ptr write_row_fn));
538.1996 +
538.1997 +#ifdef PNG_USER_MEM_SUPPORTED
538.1998 +/* Replace the default memory allocation functions with user supplied one(s). */
538.1999 +extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
538.2000 +   png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
538.2001 +/* Return the user pointer associated with the memory functions */
538.2002 +extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
538.2003 +#endif
538.2004 +
538.2005 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
538.2006 +    defined(PNG_LEGACY_SUPPORTED)
538.2007 +extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
538.2008 +   png_ptr, png_user_transform_ptr read_user_transform_fn));
538.2009 +#endif
538.2010 +
538.2011 +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
538.2012 +    defined(PNG_LEGACY_SUPPORTED)
538.2013 +extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
538.2014 +   png_ptr, png_user_transform_ptr write_user_transform_fn));
538.2015 +#endif
538.2016 +
538.2017 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
538.2018 +    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
538.2019 +    defined(PNG_LEGACY_SUPPORTED)
538.2020 +extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
538.2021 +   png_ptr, png_voidp user_transform_ptr, int user_transform_depth,
538.2022 +   int user_transform_channels));
538.2023 +/* Return the user pointer associated with the user transform functions */
538.2024 +extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
538.2025 +   PNGARG((png_structp png_ptr));
538.2026 +#endif
538.2027 +
538.2028 +#ifdef PNG_USER_CHUNKS_SUPPORTED
538.2029 +extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr,
538.2030 +   png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
538.2031 +extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp
538.2032 +   png_ptr));
538.2033 +#endif
538.2034 +
538.2035 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
538.2036 +/* Sets the function callbacks for the push reader, and a pointer to a
538.2037 + * user-defined structure available to the callback functions.
538.2038 + */
538.2039 +extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr,
538.2040 +   png_voidp progressive_ptr,
538.2041 +   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
538.2042 +   png_progressive_end_ptr end_fn));
538.2043 +
538.2044 +/* returns the user pointer associated with the push read functions */
538.2045 +extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
538.2046 +   PNGARG((png_structp png_ptr));
538.2047 +
538.2048 +/* function to be called when data becomes available */
538.2049 +extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
538.2050 +   png_infop info_ptr, png_bytep buffer, png_size_t buffer_size));
538.2051 +
538.2052 +/* function that combines rows.  Not very much different than the
538.2053 + * png_combine_row() call.  Is this even used?????
538.2054 + */
538.2055 +extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr,
538.2056 +   png_bytep old_row, png_bytep new_row));
538.2057 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
538.2058 +
538.2059 +extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
538.2060 +   png_uint_32 size));
538.2061 +
538.2062 +#if defined(PNG_1_0_X)
538.2063 +#  define png_malloc_warn png_malloc
538.2064 +#else
538.2065 +/* Added at libpng version 1.2.4 */
538.2066 +extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr,
538.2067 +   png_uint_32 size));
538.2068 +#endif
538.2069 +
538.2070 +/* frees a pointer allocated by png_malloc() */
538.2071 +extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
538.2072 +
538.2073 +#if defined(PNG_1_0_X)
538.2074 +/* Function to allocate memory for zlib. */
538.2075 +extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items,
538.2076 +   uInt size));
538.2077 +
538.2078 +/* Function to free memory for zlib */
538.2079 +extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr));
538.2080 +#endif
538.2081 +
538.2082 +/* Free data that was allocated internally */
538.2083 +extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
538.2084 +   png_infop info_ptr, png_uint_32 free_me, int num));
538.2085 +#ifdef PNG_FREE_ME_SUPPORTED
538.2086 +/* Reassign responsibility for freeing existing data, whether allocated
538.2087 + * by libpng or by the application */
538.2088 +extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
538.2089 +   png_infop info_ptr, int freer, png_uint_32 mask));
538.2090 +#endif
538.2091 +/* assignments for png_data_freer */
538.2092 +#define PNG_DESTROY_WILL_FREE_DATA 1
538.2093 +#define PNG_SET_WILL_FREE_DATA 1
538.2094 +#define PNG_USER_WILL_FREE_DATA 2
538.2095 +/* Flags for png_ptr->free_me and info_ptr->free_me */
538.2096 +#define PNG_FREE_HIST 0x0008
538.2097 +#define PNG_FREE_ICCP 0x0010
538.2098 +#define PNG_FREE_SPLT 0x0020
538.2099 +#define PNG_FREE_ROWS 0x0040
538.2100 +#define PNG_FREE_PCAL 0x0080
538.2101 +#define PNG_FREE_SCAL 0x0100
538.2102 +#define PNG_FREE_UNKN 0x0200
538.2103 +#define PNG_FREE_LIST 0x0400
538.2104 +#define PNG_FREE_PLTE 0x1000
538.2105 +#define PNG_FREE_TRNS 0x2000
538.2106 +#define PNG_FREE_TEXT 0x4000
538.2107 +#define PNG_FREE_ALL  0x7fff
538.2108 +#define PNG_FREE_MUL  0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
538.2109 +
538.2110 +#ifdef PNG_USER_MEM_SUPPORTED
538.2111 +extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
538.2112 +   png_uint_32 size));
538.2113 +extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
538.2114 +   png_voidp ptr));
538.2115 +#endif
538.2116 +
538.2117 +extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
538.2118 +   png_voidp s1, png_voidp s2, png_uint_32 size));
538.2119 +
538.2120 +extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr,
538.2121 +   png_voidp s1, int value, png_uint_32 size));
538.2122 +
538.2123 +#if defined(USE_FAR_KEYWORD)  /* memory model conversion function */
538.2124 +extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
538.2125 +   int check));
538.2126 +#endif /* USE_FAR_KEYWORD */
538.2127 +
538.2128 +#ifndef PNG_NO_ERROR_TEXT
538.2129 +/* Fatal error in PNG image of libpng - can't continue */
538.2130 +extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
538.2131 +   png_const_charp error_message));
538.2132 +
538.2133 +/* The same, but the chunk name is prepended to the error string. */
538.2134 +extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
538.2135 +   png_const_charp error_message));
538.2136 +#else
538.2137 +/* Fatal error in PNG image of libpng - can't continue */
538.2138 +extern PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr));
538.2139 +#endif
538.2140 +
538.2141 +#ifndef PNG_NO_WARNINGS
538.2142 +/* Non-fatal error in libpng.  Can continue, but may have a problem. */
538.2143 +extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
538.2144 +   png_const_charp warning_message));
538.2145 +
538.2146 +#ifdef PNG_READ_SUPPORTED
538.2147 +/* Non-fatal error in libpng, chunk name is prepended to message. */
538.2148 +extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
538.2149 +   png_const_charp warning_message));
538.2150 +#endif /* PNG_READ_SUPPORTED */
538.2151 +#endif /* PNG_NO_WARNINGS */
538.2152 +
538.2153 +/* The png_set_<chunk> functions are for storing values in the png_info_struct.
538.2154 + * Similarly, the png_get_<chunk> calls are used to read values from the
538.2155 + * png_info_struct, either storing the parameters in the passed variables, or
538.2156 + * setting pointers into the png_info_struct where the data is stored.  The
538.2157 + * png_get_<chunk> functions return a non-zero value if the data was available
538.2158 + * in info_ptr, or return zero and do not change any of the parameters if the
538.2159 + * data was not available.
538.2160 + *
538.2161 + * These functions should be used instead of directly accessing png_info
538.2162 + * to avoid problems with future changes in the size and internal layout of
538.2163 + * png_info_struct.
538.2164 + */
538.2165 +/* Returns "flag" if chunk data is valid in info_ptr. */
538.2166 +extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr,
538.2167 +png_infop info_ptr, png_uint_32 flag));
538.2168 +
538.2169 +/* Returns number of bytes needed to hold a transformed row. */
538.2170 +extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
538.2171 +png_infop info_ptr));
538.2172 +
538.2173 +#if defined(PNG_INFO_IMAGE_SUPPORTED)
538.2174 +/* Returns row_pointers, which is an array of pointers to scanlines that was
538.2175 +returned from png_read_png(). */
538.2176 +extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr,
538.2177 +png_infop info_ptr));
538.2178 +/* Set row_pointers, which is an array of pointers to scanlines for use
538.2179 +by png_write_png(). */
538.2180 +extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr,
538.2181 +   png_infop info_ptr, png_bytepp row_pointers));
538.2182 +#endif
538.2183 +
538.2184 +/* Returns number of color channels in image. */
538.2185 +extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
538.2186 +png_infop info_ptr));
538.2187 +
538.2188 +#ifdef PNG_EASY_ACCESS_SUPPORTED
538.2189 +/* Returns image width in pixels. */
538.2190 +extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp
538.2191 +png_ptr, png_infop info_ptr));
538.2192 +
538.2193 +/* Returns image height in pixels. */
538.2194 +extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp
538.2195 +png_ptr, png_infop info_ptr));
538.2196 +
538.2197 +/* Returns image bit_depth. */
538.2198 +extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp
538.2199 +png_ptr, png_infop info_ptr));
538.2200 +
538.2201 +/* Returns image color_type. */
538.2202 +extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp
538.2203 +png_ptr, png_infop info_ptr));
538.2204 +
538.2205 +/* Returns image filter_type. */
538.2206 +extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp
538.2207 +png_ptr, png_infop info_ptr));
538.2208 +
538.2209 +/* Returns image interlace_type. */
538.2210 +extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp
538.2211 +png_ptr, png_infop info_ptr));
538.2212 +
538.2213 +/* Returns image compression_type. */
538.2214 +extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp
538.2215 +png_ptr, png_infop info_ptr));
538.2216 +
538.2217 +/* Returns image resolution in pixels per meter, from pHYs chunk data. */
538.2218 +extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp
538.2219 +png_ptr, png_infop info_ptr));
538.2220 +extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp
538.2221 +png_ptr, png_infop info_ptr));
538.2222 +extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp
538.2223 +png_ptr, png_infop info_ptr));
538.2224 +
538.2225 +/* Returns pixel aspect ratio, computed from pHYs chunk data.  */
538.2226 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.2227 +extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
538.2228 +png_ptr, png_infop info_ptr));
538.2229 +#endif
538.2230 +
538.2231 +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
538.2232 +extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp
538.2233 +png_ptr, png_infop info_ptr));
538.2234 +extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp
538.2235 +png_ptr, png_infop info_ptr));
538.2236 +extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp
538.2237 +png_ptr, png_infop info_ptr));
538.2238 +extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp
538.2239 +png_ptr, png_infop info_ptr));
538.2240 +
538.2241 +#endif /* PNG_EASY_ACCESS_SUPPORTED */
538.2242 +
538.2243 +/* Returns pointer to signature string read from PNG header */
538.2244 +extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr,
538.2245 +png_infop info_ptr));
538.2246 +
538.2247 +#if defined(PNG_bKGD_SUPPORTED)
538.2248 +extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
538.2249 +   png_infop info_ptr, png_color_16p *background));
538.2250 +#endif
538.2251 +
538.2252 +#if defined(PNG_bKGD_SUPPORTED)
538.2253 +extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
538.2254 +   png_infop info_ptr, png_color_16p background));
538.2255 +#endif
538.2256 +
538.2257 +#if defined(PNG_cHRM_SUPPORTED)
538.2258 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.2259 +extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
538.2260 +   png_infop info_ptr, double *white_x, double *white_y, double *red_x,
538.2261 +   double *red_y, double *green_x, double *green_y, double *blue_x,
538.2262 +   double *blue_y));
538.2263 +#endif
538.2264 +#ifdef PNG_FIXED_POINT_SUPPORTED
538.2265 +extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr,
538.2266 +   png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point
538.2267 +   *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y,
538.2268 +   png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point
538.2269 +   *int_blue_x, png_fixed_point *int_blue_y));
538.2270 +#endif
538.2271 +#endif
538.2272 +
538.2273 +#if defined(PNG_cHRM_SUPPORTED)
538.2274 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.2275 +extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
538.2276 +   png_infop info_ptr, double white_x, double white_y, double red_x,
538.2277 +   double red_y, double green_x, double green_y, double blue_x, double blue_y));
538.2278 +#endif
538.2279 +#ifdef PNG_FIXED_POINT_SUPPORTED
538.2280 +extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr,
538.2281 +   png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y,
538.2282 +   png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
538.2283 +   int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
538.2284 +   png_fixed_point int_blue_y));
538.2285 +#endif
538.2286 +#endif
538.2287 +
538.2288 +#if defined(PNG_gAMA_SUPPORTED)
538.2289 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.2290 +extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
538.2291 +   png_infop info_ptr, double *file_gamma));
538.2292 +#endif
538.2293 +extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr,
538.2294 +   png_infop info_ptr, png_fixed_point *int_file_gamma));
538.2295 +#endif
538.2296 +
538.2297 +#if defined(PNG_gAMA_SUPPORTED)
538.2298 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.2299 +extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
538.2300 +   png_infop info_ptr, double file_gamma));
538.2301 +#endif
538.2302 +extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr,
538.2303 +   png_infop info_ptr, png_fixed_point int_file_gamma));
538.2304 +#endif
538.2305 +
538.2306 +#if defined(PNG_hIST_SUPPORTED)
538.2307 +extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
538.2308 +   png_infop info_ptr, png_uint_16p *hist));
538.2309 +#endif
538.2310 +
538.2311 +#if defined(PNG_hIST_SUPPORTED)
538.2312 +extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
538.2313 +   png_infop info_ptr, png_uint_16p hist));
538.2314 +#endif
538.2315 +
538.2316 +extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
538.2317 +   png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
538.2318 +   int *bit_depth, int *color_type, int *interlace_method,
538.2319 +   int *compression_method, int *filter_method));
538.2320 +
538.2321 +extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
538.2322 +   png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
538.2323 +   int color_type, int interlace_method, int compression_method,
538.2324 +   int filter_method));
538.2325 +
538.2326 +#if defined(PNG_oFFs_SUPPORTED)
538.2327 +extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
538.2328 +   png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
538.2329 +   int *unit_type));
538.2330 +#endif
538.2331 +
538.2332 +#if defined(PNG_oFFs_SUPPORTED)
538.2333 +extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
538.2334 +   png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y,
538.2335 +   int unit_type));
538.2336 +#endif
538.2337 +
538.2338 +#if defined(PNG_pCAL_SUPPORTED)
538.2339 +extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
538.2340 +   png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
538.2341 +   int *type, int *nparams, png_charp *units, png_charpp *params));
538.2342 +#endif
538.2343 +
538.2344 +#if defined(PNG_pCAL_SUPPORTED)
538.2345 +extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
538.2346 +   png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
538.2347 +   int type, int nparams, png_charp units, png_charpp params));
538.2348 +#endif
538.2349 +
538.2350 +#if defined(PNG_pHYs_SUPPORTED)
538.2351 +extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
538.2352 +   png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
538.2353 +#endif
538.2354 +
538.2355 +#if defined(PNG_pHYs_SUPPORTED)
538.2356 +extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
538.2357 +   png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
538.2358 +#endif
538.2359 +
538.2360 +extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
538.2361 +   png_infop info_ptr, png_colorp *palette, int *num_palette));
538.2362 +
538.2363 +extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
538.2364 +   png_infop info_ptr, png_colorp palette, int num_palette));
538.2365 +
538.2366 +#if defined(PNG_sBIT_SUPPORTED)
538.2367 +extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
538.2368 +   png_infop info_ptr, png_color_8p *sig_bit));
538.2369 +#endif
538.2370 +
538.2371 +#if defined(PNG_sBIT_SUPPORTED)
538.2372 +extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
538.2373 +   png_infop info_ptr, png_color_8p sig_bit));
538.2374 +#endif
538.2375 +
538.2376 +#if defined(PNG_sRGB_SUPPORTED)
538.2377 +extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
538.2378 +   png_infop info_ptr, int *intent));
538.2379 +#endif
538.2380 +
538.2381 +#if defined(PNG_sRGB_SUPPORTED)
538.2382 +extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
538.2383 +   png_infop info_ptr, int intent));
538.2384 +extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
538.2385 +   png_infop info_ptr, int intent));
538.2386 +#endif
538.2387 +
538.2388 +#if defined(PNG_iCCP_SUPPORTED)
538.2389 +extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr,
538.2390 +   png_infop info_ptr, png_charpp name, int *compression_type,
538.2391 +   png_charpp profile, png_uint_32 *proflen));
538.2392 +   /* Note to maintainer: profile should be png_bytepp */
538.2393 +#endif
538.2394 +
538.2395 +#if defined(PNG_iCCP_SUPPORTED)
538.2396 +extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
538.2397 +   png_infop info_ptr, png_charp name, int compression_type,
538.2398 +   png_charp profile, png_uint_32 proflen));
538.2399 +   /* Note to maintainer: profile should be png_bytep */
538.2400 +#endif
538.2401 +
538.2402 +#if defined(PNG_sPLT_SUPPORTED)
538.2403 +extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr,
538.2404 +   png_infop info_ptr, png_sPLT_tpp entries));
538.2405 +#endif
538.2406 +
538.2407 +#if defined(PNG_sPLT_SUPPORTED)
538.2408 +extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
538.2409 +   png_infop info_ptr, png_sPLT_tp entries, int nentries));
538.2410 +#endif
538.2411 +
538.2412 +#if defined(PNG_TEXT_SUPPORTED)
538.2413 +/* png_get_text also returns the number of text chunks in *num_text */
538.2414 +extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
538.2415 +   png_infop info_ptr, png_textp *text_ptr, int *num_text));
538.2416 +#endif
538.2417 +
538.2418 +/*
538.2419 + *  Note while png_set_text() will accept a structure whose text,
538.2420 + *  language, and  translated keywords are NULL pointers, the structure
538.2421 + *  returned by png_get_text will always contain regular
538.2422 + *  zero-terminated C strings.  They might be empty strings but
538.2423 + *  they will never be NULL pointers.
538.2424 + */
538.2425 +
538.2426 +#if defined(PNG_TEXT_SUPPORTED)
538.2427 +extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
538.2428 +   png_infop info_ptr, png_textp text_ptr, int num_text));
538.2429 +#endif
538.2430 +
538.2431 +#if defined(PNG_tIME_SUPPORTED)
538.2432 +extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
538.2433 +   png_infop info_ptr, png_timep *mod_time));
538.2434 +#endif
538.2435 +
538.2436 +#if defined(PNG_tIME_SUPPORTED)
538.2437 +extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
538.2438 +   png_infop info_ptr, png_timep mod_time));
538.2439 +#endif
538.2440 +
538.2441 +#if defined(PNG_tRNS_SUPPORTED)
538.2442 +extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
538.2443 +   png_infop info_ptr, png_bytep *trans, int *num_trans,
538.2444 +   png_color_16p *trans_values));
538.2445 +#endif
538.2446 +
538.2447 +#if defined(PNG_tRNS_SUPPORTED)
538.2448 +extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
538.2449 +   png_infop info_ptr, png_bytep trans, int num_trans,
538.2450 +   png_color_16p trans_values));
538.2451 +#endif
538.2452 +
538.2453 +#if defined(PNG_tRNS_SUPPORTED)
538.2454 +#endif
538.2455 +
538.2456 +#if defined(PNG_sCAL_SUPPORTED)
538.2457 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.2458 +extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr,
538.2459 +   png_infop info_ptr, int *unit, double *width, double *height));
538.2460 +#else
538.2461 +#ifdef PNG_FIXED_POINT_SUPPORTED
538.2462 +extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr,
538.2463 +   png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight));
538.2464 +#endif
538.2465 +#endif
538.2466 +#endif /* PNG_sCAL_SUPPORTED */
538.2467 +
538.2468 +#if defined(PNG_sCAL_SUPPORTED)
538.2469 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.2470 +extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
538.2471 +   png_infop info_ptr, int unit, double width, double height));
538.2472 +#else
538.2473 +#ifdef PNG_FIXED_POINT_SUPPORTED
538.2474 +extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
538.2475 +   png_infop info_ptr, int unit, png_charp swidth, png_charp sheight));
538.2476 +#endif
538.2477 +#endif
538.2478 +#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
538.2479 +
538.2480 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
538.2481 +/* provide a list of chunks and how they are to be handled, if the built-in
538.2482 +   handling or default unknown chunk handling is not desired.  Any chunks not
538.2483 +   listed will be handled in the default manner.  The IHDR and IEND chunks
538.2484 +   must not be listed.
538.2485 +      keep = 0: follow default behaviour
538.2486 +           = 1: do not keep
538.2487 +           = 2: keep only if safe-to-copy
538.2488 +           = 3: keep even if unsafe-to-copy
538.2489 +*/
538.2490 +extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp
538.2491 +   png_ptr, int keep, png_bytep chunk_list, int num_chunks));
538.2492 +extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr,
538.2493 +   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns));
538.2494 +extern PNG_EXPORT(void, png_set_unknown_chunk_location)
538.2495 +   PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location));
538.2496 +extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp
538.2497 +   png_ptr, png_infop info_ptr, png_unknown_chunkpp entries));
538.2498 +#endif
538.2499 +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
538.2500 +PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep
538.2501 +   chunk_name));
538.2502 +#endif
538.2503 +
538.2504 +/* Png_free_data() will turn off the "valid" flag for anything it frees.
538.2505 +   If you need to turn it off for a chunk that your application has freed,
538.2506 +   you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */
538.2507 +extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr,
538.2508 +   png_infop info_ptr, int mask));
538.2509 +
538.2510 +#if defined(PNG_INFO_IMAGE_SUPPORTED)
538.2511 +/* The "params" pointer is currently not used and is for future expansion. */
538.2512 +extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr,
538.2513 +                        png_infop info_ptr,
538.2514 +                        int transforms,
538.2515 +                        png_voidp params));
538.2516 +extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr,
538.2517 +                        png_infop info_ptr,
538.2518 +                        int transforms,
538.2519 +                        png_voidp params));
538.2520 +#endif
538.2521 +
538.2522 +/* Define PNG_DEBUG at compile time for debugging information.  Higher
538.2523 + * numbers for PNG_DEBUG mean more debugging information.  This has
538.2524 + * only been added since version 0.95 so it is not implemented throughout
538.2525 + * libpng yet, but more support will be added as needed.
538.2526 + */
538.2527 +#ifdef PNG_DEBUG
538.2528 +#if (PNG_DEBUG > 0)
538.2529 +#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
538.2530 +#include <crtdbg.h>
538.2531 +#if (PNG_DEBUG > 1)
538.2532 +#define png_debug(l,m)  _RPT0(_CRT_WARN,m)
538.2533 +#define png_debug1(l,m,p1)  _RPT1(_CRT_WARN,m,p1)
538.2534 +#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2)
538.2535 +#endif
538.2536 +#else /* PNG_DEBUG_FILE || !_MSC_VER */
538.2537 +#ifndef PNG_DEBUG_FILE
538.2538 +#define PNG_DEBUG_FILE stderr
538.2539 +#endif /* PNG_DEBUG_FILE */
538.2540 +#if (PNG_DEBUG > 1)
538.2541 +#define png_debug(l,m) \
538.2542 +{ \
538.2543 +     int num_tabs=l; \
538.2544 +     fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
538.2545 +       (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
538.2546 +}
538.2547 +#define png_debug1(l,m,p1) \
538.2548 +{ \
538.2549 +     int num_tabs=l; \
538.2550 +     fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
538.2551 +       (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
538.2552 +}
538.2553 +#define png_debug2(l,m,p1,p2) \
538.2554 +{ \
538.2555 +     int num_tabs=l; \
538.2556 +     fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
538.2557 +       (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
538.2558 +}
538.2559 +#endif /* (PNG_DEBUG > 1) */
538.2560 +#endif /* _MSC_VER */
538.2561 +#endif /* (PNG_DEBUG > 0) */
538.2562 +#endif /* PNG_DEBUG */
538.2563 +#ifndef png_debug
538.2564 +#define png_debug(l, m)
538.2565 +#endif
538.2566 +#ifndef png_debug1
538.2567 +#define png_debug1(l, m, p1)
538.2568 +#endif
538.2569 +#ifndef png_debug2
538.2570 +#define png_debug2(l, m, p1, p2)
538.2571 +#endif
538.2572 +
538.2573 +extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
538.2574 +extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr));
538.2575 +extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
538.2576 +extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
538.2577 +
538.2578 +#ifdef PNG_MNG_FEATURES_SUPPORTED
538.2579 +extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
538.2580 +   png_ptr, png_uint_32 mng_features_permitted));
538.2581 +#endif
538.2582 +
538.2583 +/* For use in png_set_keep_unknown, added to version 1.2.6 */
538.2584 +#define PNG_HANDLE_CHUNK_AS_DEFAULT   0
538.2585 +#define PNG_HANDLE_CHUNK_NEVER        1
538.2586 +#define PNG_HANDLE_CHUNK_IF_SAFE      2
538.2587 +#define PNG_HANDLE_CHUNK_ALWAYS       3
538.2588 +
538.2589 +/* Added to version 1.2.0 */
538.2590 +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
538.2591 +#if defined(PNG_MMX_CODE_SUPPORTED)
538.2592 +#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED  0x01  /* not user-settable */
538.2593 +#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU    0x02  /* not user-settable */
538.2594 +#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  0x04
538.2595 +#define PNG_ASM_FLAG_MMX_READ_INTERLACE    0x08
538.2596 +#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB   0x10
538.2597 +#define PNG_ASM_FLAG_MMX_READ_FILTER_UP    0x20
538.2598 +#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG   0x40
538.2599 +#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80
538.2600 +#define PNG_ASM_FLAGS_INITIALIZED          0x80000000  /* not user-settable */
538.2601 +
538.2602 +#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
538.2603 +                           | PNG_ASM_FLAG_MMX_READ_INTERLACE    \
538.2604 +                           | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
538.2605 +                           | PNG_ASM_FLAG_MMX_READ_FILTER_UP    \
538.2606 +                           | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
538.2607 +                           | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH )
538.2608 +#define PNG_MMX_WRITE_FLAGS ( 0 )
538.2609 +
538.2610 +#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \
538.2611 +                      | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU   \
538.2612 +                      | PNG_MMX_READ_FLAGS                \
538.2613 +                      | PNG_MMX_WRITE_FLAGS )
538.2614 +
538.2615 +#define PNG_SELECT_READ   1
538.2616 +#define PNG_SELECT_WRITE  2
538.2617 +#endif /* PNG_MMX_CODE_SUPPORTED */
538.2618 +
538.2619 +#if !defined(PNG_1_0_X)
538.2620 +/* pngget.c */
538.2621 +extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask)
538.2622 +   PNGARG((int flag_select, int *compilerID));
538.2623 +
538.2624 +/* pngget.c */
538.2625 +extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask)
538.2626 +   PNGARG((int flag_select));
538.2627 +
538.2628 +/* pngget.c */
538.2629 +extern PNG_EXPORT(png_uint_32,png_get_asm_flags)
538.2630 +   PNGARG((png_structp png_ptr));
538.2631 +
538.2632 +/* pngget.c */
538.2633 +extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold)
538.2634 +   PNGARG((png_structp png_ptr));
538.2635 +
538.2636 +/* pngget.c */
538.2637 +extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold)
538.2638 +   PNGARG((png_structp png_ptr));
538.2639 +
538.2640 +/* pngset.c */
538.2641 +extern PNG_EXPORT(void,png_set_asm_flags)
538.2642 +   PNGARG((png_structp png_ptr, png_uint_32 asm_flags));
538.2643 +
538.2644 +/* pngset.c */
538.2645 +extern PNG_EXPORT(void,png_set_mmx_thresholds)
538.2646 +   PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold,
538.2647 +   png_uint_32 mmx_rowbytes_threshold));
538.2648 +
538.2649 +#endif /* PNG_1_0_X */
538.2650 +
538.2651 +#if !defined(PNG_1_0_X)
538.2652 +/* png.c, pnggccrd.c, or pngvcrd.c */
538.2653 +extern PNG_EXPORT(int,png_mmx_support) PNGARG((void));
538.2654 +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
538.2655 +
538.2656 +/* Strip the prepended error numbers ("#nnn ") from error and warning
538.2657 + * messages before passing them to the error or warning handler. */
538.2658 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
538.2659 +extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
538.2660 +   png_ptr, png_uint_32 strip_mode));
538.2661 +#endif
538.2662 +
538.2663 +#endif /* PNG_1_0_X */
538.2664 +
538.2665 +/* Added at libpng-1.2.6 */
538.2666 +#ifdef PNG_SET_USER_LIMITS_SUPPORTED
538.2667 +extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp
538.2668 +   png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max));
538.2669 +extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp
538.2670 +   png_ptr));
538.2671 +extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp
538.2672 +   png_ptr));
538.2673 +#endif
538.2674 +
538.2675 +
538.2676 +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */
538.2677 +
538.2678 +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
538.2679 +/* With these routines we avoid an integer divide, which will be slower on
538.2680 + * most machines.  However, it does take more operations than the corresponding
538.2681 + * divide method, so it may be slower on a few RISC systems.  There are two
538.2682 + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
538.2683 + *
538.2684 + * Note that the rounding factors are NOT supposed to be the same!  128 and
538.2685 + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
538.2686 + * standard method.
538.2687 + *
538.2688 + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
538.2689 + */
538.2690 +
538.2691 + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity          */
538.2692 +
538.2693 +#  define png_composite(composite, fg, alpha, bg)                            \
538.2694 +     { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
538.2695 +                        +        (png_uint_16)(bg)*(png_uint_16)(255 -       \
538.2696 +                        (png_uint_16)(alpha)) + (png_uint_16)128);           \
538.2697 +       (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
538.2698 +
538.2699 +#  define png_composite_16(composite, fg, alpha, bg)                         \
538.2700 +     { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
538.2701 +                        + (png_uint_32)(bg)*(png_uint_32)(65535L -           \
538.2702 +                        (png_uint_32)(alpha)) + (png_uint_32)32768L);        \
538.2703 +       (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
538.2704 +
538.2705 +#else  /* standard method using integer division */
538.2706 +
538.2707 +#  define png_composite(composite, fg, alpha, bg)                            \
538.2708 +     (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) +    \
538.2709 +       (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) +       \
538.2710 +       (png_uint_16)127) / 255)
538.2711 +
538.2712 +#  define png_composite_16(composite, fg, alpha, bg)                         \
538.2713 +     (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
538.2714 +       (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) +      \
538.2715 +       (png_uint_32)32767) / (png_uint_32)65535L)
538.2716 +
538.2717 +#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
538.2718 +
538.2719 +/* Inline macros to do direct reads of bytes from the input buffer.  These
538.2720 + * require that you are using an architecture that uses PNG byte ordering
538.2721 + * (MSB first) and supports unaligned data storage.  I think that PowerPC
538.2722 + * in big-endian mode and 680x0 are the only ones that will support this.
538.2723 + * The x86 line of processors definitely do not.  The png_get_int_32()
538.2724 + * routine also assumes we are using two's complement format for negative
538.2725 + * values, which is almost certainly true.
538.2726 + */
538.2727 +#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED)
538.2728 +#  define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
538.2729 +#  define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
538.2730 +#  define png_get_int_32(buf)  ( *((png_int_32p)  (buf)))
538.2731 +#else
538.2732 +extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf));
538.2733 +extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf));
538.2734 +extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf));
538.2735 +#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */
538.2736 +extern PNG_EXPORT(png_uint_32,png_get_uint_31)
538.2737 +  PNGARG((png_structp png_ptr, png_bytep buf));
538.2738 +/* No png_get_int_16 -- may be added if there's a real need for it. */
538.2739 +
538.2740 +/* Place a 32-bit number into a buffer in PNG byte order (big-endian).
538.2741 + */
538.2742 +extern PNG_EXPORT(void,png_save_uint_32)
538.2743 +   PNGARG((png_bytep buf, png_uint_32 i));
538.2744 +extern PNG_EXPORT(void,png_save_int_32)
538.2745 +   PNGARG((png_bytep buf, png_int_32 i));
538.2746 +
538.2747 +/* Place a 16-bit number into a buffer in PNG byte order.
538.2748 + * The parameter is declared unsigned int, not png_uint_16,
538.2749 + * just to avoid potential problems on pre-ANSI C compilers.
538.2750 + */
538.2751 +extern PNG_EXPORT(void,png_save_uint_16)
538.2752 +   PNGARG((png_bytep buf, unsigned int i));
538.2753 +/* No png_save_int_16 -- may be added if there's a real need for it. */
538.2754 +
538.2755 +/* ************************************************************************* */
538.2756 +
538.2757 +/* These next functions are used internally in the code.  They generally
538.2758 + * shouldn't be used unless you are writing code to add or replace some
538.2759 + * functionality in libpng.  More information about most functions can
538.2760 + * be found in the files where the functions are located.
538.2761 + */
538.2762 +
538.2763 +
538.2764 +/* Various modes of operation, that are visible to applications because
538.2765 + * they are used for unknown chunk location.
538.2766 + */
538.2767 +#define PNG_HAVE_IHDR               0x01
538.2768 +#define PNG_HAVE_PLTE               0x02
538.2769 +#define PNG_HAVE_IDAT               0x04
538.2770 +#define PNG_AFTER_IDAT              0x08 /* Have complete zlib datastream */
538.2771 +#define PNG_HAVE_IEND               0x10
538.2772 +
538.2773 +#if defined(PNG_INTERNAL)
538.2774 +
538.2775 +/* More modes of operation.  Note that after an init, mode is set to
538.2776 + * zero automatically when the structure is created.
538.2777 + */
538.2778 +#define PNG_HAVE_gAMA               0x20
538.2779 +#define PNG_HAVE_cHRM               0x40
538.2780 +#define PNG_HAVE_sRGB               0x80
538.2781 +#define PNG_HAVE_CHUNK_HEADER      0x100
538.2782 +#define PNG_WROTE_tIME             0x200
538.2783 +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
538.2784 +#define PNG_BACKGROUND_IS_GRAY     0x800
538.2785 +#define PNG_HAVE_PNG_SIGNATURE    0x1000
538.2786 +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
538.2787 +
538.2788 +/* flags for the transformations the PNG library does on the image data */
538.2789 +#define PNG_BGR                0x0001
538.2790 +#define PNG_INTERLACE          0x0002
538.2791 +#define PNG_PACK               0x0004
538.2792 +#define PNG_SHIFT              0x0008
538.2793 +#define PNG_SWAP_BYTES         0x0010
538.2794 +#define PNG_INVERT_MONO        0x0020
538.2795 +#define PNG_DITHER             0x0040
538.2796 +#define PNG_BACKGROUND         0x0080
538.2797 +#define PNG_BACKGROUND_EXPAND  0x0100
538.2798 +                          /*   0x0200 unused */
538.2799 +#define PNG_16_TO_8            0x0400
538.2800 +#define PNG_RGBA               0x0800
538.2801 +#define PNG_EXPAND             0x1000
538.2802 +#define PNG_GAMMA              0x2000
538.2803 +#define PNG_GRAY_TO_RGB        0x4000
538.2804 +#define PNG_FILLER             0x8000L
538.2805 +#define PNG_PACKSWAP          0x10000L
538.2806 +#define PNG_SWAP_ALPHA        0x20000L
538.2807 +#define PNG_STRIP_ALPHA       0x40000L
538.2808 +#define PNG_INVERT_ALPHA      0x80000L
538.2809 +#define PNG_USER_TRANSFORM   0x100000L
538.2810 +#define PNG_RGB_TO_GRAY_ERR  0x200000L
538.2811 +#define PNG_RGB_TO_GRAY_WARN 0x400000L
538.2812 +#define PNG_RGB_TO_GRAY      0x600000L  /* two bits, RGB_TO_GRAY_ERR|WARN */
538.2813 +                       /*    0x800000L     Unused */
538.2814 +#define PNG_ADD_ALPHA       0x1000000L  /* Added to libpng-1.2.7 */
538.2815 +#define PNG_EXPAND_tRNS     0x2000000L  /* Added to libpng-1.2.9 */
538.2816 +                       /*   0x4000000L  unused */
538.2817 +                       /*   0x8000000L  unused */
538.2818 +                       /*  0x10000000L  unused */
538.2819 +                       /*  0x20000000L  unused */
538.2820 +                       /*  0x40000000L  unused */
538.2821 +
538.2822 +/* flags for png_create_struct */
538.2823 +#define PNG_STRUCT_PNG   0x0001
538.2824 +#define PNG_STRUCT_INFO  0x0002
538.2825 +
538.2826 +/* Scaling factor for filter heuristic weighting calculations */
538.2827 +#define PNG_WEIGHT_SHIFT 8
538.2828 +#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
538.2829 +#define PNG_COST_SHIFT 3
538.2830 +#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
538.2831 +
538.2832 +/* flags for the png_ptr->flags rather than declaring a byte for each one */
538.2833 +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001
538.2834 +#define PNG_FLAG_ZLIB_CUSTOM_LEVEL        0x0002
538.2835 +#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL    0x0004
538.2836 +#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS  0x0008
538.2837 +#define PNG_FLAG_ZLIB_CUSTOM_METHOD       0x0010
538.2838 +#define PNG_FLAG_ZLIB_FINISHED            0x0020
538.2839 +#define PNG_FLAG_ROW_INIT                 0x0040
538.2840 +#define PNG_FLAG_FILLER_AFTER             0x0080
538.2841 +#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100
538.2842 +#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
538.2843 +#define PNG_FLAG_CRC_CRITICAL_USE         0x0400
538.2844 +#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
538.2845 +#define PNG_FLAG_FREE_PLTE                0x1000
538.2846 +#define PNG_FLAG_FREE_TRNS                0x2000
538.2847 +#define PNG_FLAG_FREE_HIST                0x4000
538.2848 +#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000L
538.2849 +#define PNG_FLAG_KEEP_UNSAFE_CHUNKS       0x10000L
538.2850 +#define PNG_FLAG_LIBRARY_MISMATCH         0x20000L
538.2851 +#define PNG_FLAG_STRIP_ERROR_NUMBERS      0x40000L
538.2852 +#define PNG_FLAG_STRIP_ERROR_TEXT         0x80000L
538.2853 +#define PNG_FLAG_MALLOC_NULL_MEM_OK       0x100000L
538.2854 +#define PNG_FLAG_ADD_ALPHA                0x200000L  /* Added to libpng-1.2.8 */
538.2855 +#define PNG_FLAG_STRIP_ALPHA              0x400000L  /* Added to libpng-1.2.8 */
538.2856 +                                  /*      0x800000L  unused */
538.2857 +                                  /*     0x1000000L  unused */
538.2858 +                                  /*     0x2000000L  unused */
538.2859 +                                  /*     0x4000000L  unused */
538.2860 +                                  /*     0x8000000L  unused */
538.2861 +                                  /*    0x10000000L  unused */
538.2862 +                                  /*    0x20000000L  unused */
538.2863 +                                  /*    0x40000000L  unused */
538.2864 +
538.2865 +#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
538.2866 +                                     PNG_FLAG_CRC_ANCILLARY_NOWARN)
538.2867 +
538.2868 +#define PNG_FLAG_CRC_CRITICAL_MASK  (PNG_FLAG_CRC_CRITICAL_USE | \
538.2869 +                                     PNG_FLAG_CRC_CRITICAL_IGNORE)
538.2870 +
538.2871 +#define PNG_FLAG_CRC_MASK           (PNG_FLAG_CRC_ANCILLARY_MASK | \
538.2872 +                                     PNG_FLAG_CRC_CRITICAL_MASK)
538.2873 +
538.2874 +/* save typing and make code easier to understand */
538.2875 +
538.2876 +#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
538.2877 +   abs((int)((c1).green) - (int)((c2).green)) + \
538.2878 +   abs((int)((c1).blue) - (int)((c2).blue)))
538.2879 +
538.2880 +/* Added to libpng-1.2.6 JB */
538.2881 +#define PNG_ROWBYTES(pixel_bits, width) \
538.2882 +    ((pixel_bits) >= 8 ? \
538.2883 +    ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \
538.2884 +    (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) )
538.2885 +
538.2886 +/* PNG_OUT_OF_RANGE returns true if value is outside the range
538.2887 +   ideal-delta..ideal+delta.  Each argument is evaluated twice.
538.2888 +   "ideal" and "delta" should be constants, normally simple
538.2889 +   integers, "value" a variable. Added to libpng-1.2.6 JB */
538.2890 +#define PNG_OUT_OF_RANGE(value, ideal, delta) \
538.2891 +        ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
538.2892 +
538.2893 +/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
538.2894 +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
538.2895 +/* place to hold the signature string for a PNG file. */
538.2896 +#ifdef PNG_USE_GLOBAL_ARRAYS
538.2897 +   PNG_EXPORT_VAR (PNG_CONST png_byte FARDATA) png_sig[8];
538.2898 +#else
538.2899 +#endif
538.2900 +#endif /* PNG_NO_EXTERN */
538.2901 +
538.2902 +/* Constant strings for known chunk types.  If you need to add a chunk,
538.2903 + * define the name here, and add an invocation of the macro in png.c and
538.2904 + * wherever it's needed.
538.2905 + */
538.2906 +#define PNG_IHDR png_byte png_IHDR[5] = { 73,  72,  68,  82, '\0'}
538.2907 +#define PNG_IDAT png_byte png_IDAT[5] = { 73,  68,  65,  84, '\0'}
538.2908 +#define PNG_IEND png_byte png_IEND[5] = { 73,  69,  78,  68, '\0'}
538.2909 +#define PNG_PLTE png_byte png_PLTE[5] = { 80,  76,  84,  69, '\0'}
538.2910 +#define PNG_bKGD png_byte png_bKGD[5] = { 98,  75,  71,  68, '\0'}
538.2911 +#define PNG_cHRM png_byte png_cHRM[5] = { 99,  72,  82,  77, '\0'}
538.2912 +#define PNG_gAMA png_byte png_gAMA[5] = {103,  65,  77,  65, '\0'}
538.2913 +#define PNG_hIST png_byte png_hIST[5] = {104,  73,  83,  84, '\0'}
538.2914 +#define PNG_iCCP png_byte png_iCCP[5] = {105,  67,  67,  80, '\0'}
538.2915 +#define PNG_iTXt png_byte png_iTXt[5] = {105,  84,  88, 116, '\0'}
538.2916 +#define PNG_oFFs png_byte png_oFFs[5] = {111,  70,  70, 115, '\0'}
538.2917 +#define PNG_pCAL png_byte png_pCAL[5] = {112,  67,  65,  76, '\0'}
538.2918 +#define PNG_sCAL png_byte png_sCAL[5] = {115,  67,  65,  76, '\0'}
538.2919 +#define PNG_pHYs png_byte png_pHYs[5] = {112,  72,  89, 115, '\0'}
538.2920 +#define PNG_sBIT png_byte png_sBIT[5] = {115,  66,  73,  84, '\0'}
538.2921 +#define PNG_sPLT png_byte png_sPLT[5] = {115,  80,  76,  84, '\0'}
538.2922 +#define PNG_sRGB png_byte png_sRGB[5] = {115,  82,  71,  66, '\0'}
538.2923 +#define PNG_tEXt png_byte png_tEXt[5] = {116,  69,  88, 116, '\0'}
538.2924 +#define PNG_tIME png_byte png_tIME[5] = {116,  73,  77,  69, '\0'}
538.2925 +#define PNG_tRNS png_byte png_tRNS[5] = {116,  82,  78,  83, '\0'}
538.2926 +#define PNG_zTXt png_byte png_zTXt[5] = {122,  84,  88, 116, '\0'}
538.2927 +
538.2928 +#ifdef PNG_USE_GLOBAL_ARRAYS
538.2929 +PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5];
538.2930 +PNG_EXPORT_VAR (png_byte FARDATA) png_IDAT[5];
538.2931 +PNG_EXPORT_VAR (png_byte FARDATA) png_IEND[5];
538.2932 +PNG_EXPORT_VAR (png_byte FARDATA) png_PLTE[5];
538.2933 +PNG_EXPORT_VAR (png_byte FARDATA) png_bKGD[5];
538.2934 +PNG_EXPORT_VAR (png_byte FARDATA) png_cHRM[5];
538.2935 +PNG_EXPORT_VAR (png_byte FARDATA) png_gAMA[5];
538.2936 +PNG_EXPORT_VAR (png_byte FARDATA) png_hIST[5];
538.2937 +PNG_EXPORT_VAR (png_byte FARDATA) png_iCCP[5];
538.2938 +PNG_EXPORT_VAR (png_byte FARDATA) png_iTXt[5];
538.2939 +PNG_EXPORT_VAR (png_byte FARDATA) png_oFFs[5];
538.2940 +PNG_EXPORT_VAR (png_byte FARDATA) png_pCAL[5];
538.2941 +PNG_EXPORT_VAR (png_byte FARDATA) png_sCAL[5];
538.2942 +PNG_EXPORT_VAR (png_byte FARDATA) png_pHYs[5];
538.2943 +PNG_EXPORT_VAR (png_byte FARDATA) png_sBIT[5];
538.2944 +PNG_EXPORT_VAR (png_byte FARDATA) png_sPLT[5];
538.2945 +PNG_EXPORT_VAR (png_byte FARDATA) png_sRGB[5];
538.2946 +PNG_EXPORT_VAR (png_byte FARDATA) png_tEXt[5];
538.2947 +PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5];
538.2948 +PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5];
538.2949 +PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5];
538.2950 +#endif /* PNG_USE_GLOBAL_ARRAYS */
538.2951 +
538.2952 +#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
538.2953 +/* Initialize png_ptr struct for reading, and allocate any other memory.
538.2954 + * (old interface - DEPRECATED - use png_create_read_struct instead).
538.2955 + */
538.2956 +extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr));
538.2957 +#undef png_read_init
538.2958 +#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \
538.2959 +    PNG_LIBPNG_VER_STRING,  png_sizeof(png_struct));
538.2960 +#endif
538.2961 +
538.2962 +extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr,
538.2963 +    png_const_charp user_png_ver, png_size_t png_struct_size));
538.2964 +#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
538.2965 +extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
538.2966 +    png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
538.2967 +    png_info_size));
538.2968 +#endif
538.2969 +
538.2970 +#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
538.2971 +/* Initialize png_ptr struct for writing, and allocate any other memory.
538.2972 + * (old interface - DEPRECATED - use png_create_write_struct instead).
538.2973 + */
538.2974 +extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr));
538.2975 +#undef png_write_init
538.2976 +#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \
538.2977 +    PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
538.2978 +#endif
538.2979 +
538.2980 +extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr,
538.2981 +    png_const_charp user_png_ver, png_size_t png_struct_size));
538.2982 +extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr,
538.2983 +    png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
538.2984 +    png_info_size));
538.2985 +
538.2986 +/* Allocate memory for an internal libpng struct */
538.2987 +PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
538.2988 +
538.2989 +/* Free memory from internal libpng struct */
538.2990 +PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
538.2991 +
538.2992 +PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
538.2993 +  malloc_fn, png_voidp mem_ptr));
538.2994 +PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
538.2995 +   png_free_ptr free_fn, png_voidp mem_ptr));
538.2996 +
538.2997 +/* Free any memory that info_ptr points to and reset struct. */
538.2998 +PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
538.2999 +   png_infop info_ptr));
538.3000 +
538.3001 +#ifndef PNG_1_0_X
538.3002 +/* Function to allocate memory for zlib. */
538.3003 +PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
538.3004 +
538.3005 +/* Function to free memory for zlib */
538.3006 +PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
538.3007 +
538.3008 +#ifdef PNG_SIZE_T
538.3009 +/* Function to convert a sizeof an item to png_sizeof item */
538.3010 +   PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
538.3011 +#endif
538.3012 +
538.3013 +/* Next four functions are used internally as callbacks.  PNGAPI is required
538.3014 + * but not PNG_EXPORT.  PNGAPI added at libpng version 1.2.3. */
538.3015 +
538.3016 +PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr,
538.3017 +   png_bytep data, png_size_t length));
538.3018 +
538.3019 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
538.3020 +PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
538.3021 +   png_bytep buffer, png_size_t length));
538.3022 +#endif
538.3023 +
538.3024 +PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr,
538.3025 +   png_bytep data, png_size_t length));
538.3026 +
538.3027 +#if defined(PNG_WRITE_FLUSH_SUPPORTED)
538.3028 +#if !defined(PNG_NO_STDIO)
538.3029 +PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr));
538.3030 +#endif
538.3031 +#endif
538.3032 +#else /* PNG_1_0_X */
538.3033 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
538.3034 +PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr,
538.3035 +   png_bytep buffer, png_size_t length));
538.3036 +#endif
538.3037 +#endif /* PNG_1_0_X */
538.3038 +
538.3039 +/* Reset the CRC variable */
538.3040 +PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
538.3041 +
538.3042 +/* Write the "data" buffer to whatever output you are using. */
538.3043 +PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
538.3044 +   png_size_t length));
538.3045 +
538.3046 +/* Read data from whatever input you are using into the "data" buffer */
538.3047 +PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
538.3048 +   png_size_t length));
538.3049 +
538.3050 +/* Read bytes into buf, and update png_ptr->crc */
538.3051 +PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
538.3052 +   png_size_t length));
538.3053 +
538.3054 +/* Decompress data in a chunk that uses compression */
538.3055 +#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
538.3056 +    defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
538.3057 +PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr,
538.3058 +   int comp_type, png_size_t chunklength,
538.3059 +   png_size_t prefix_length, png_size_t *data_length));
538.3060 +#endif
538.3061 +
538.3062 +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
538.3063 +PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
538.3064 +
538.3065 +/* Read the CRC from the file and compare it to the libpng calculated CRC */
538.3066 +PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
538.3067 +
538.3068 +/* Calculate the CRC over a section of data.  Note that we are only
538.3069 + * passing a maximum of 64K on systems that have this as a memory limit,
538.3070 + * since this is the maximum buffer size we can specify.
538.3071 + */
538.3072 +PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
538.3073 +   png_size_t length));
538.3074 +
538.3075 +#if defined(PNG_WRITE_FLUSH_SUPPORTED)
538.3076 +PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
538.3077 +#endif
538.3078 +
538.3079 +/* simple function to write the signature */
538.3080 +PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr));
538.3081 +
538.3082 +/* write various chunks */
538.3083 +
538.3084 +/* Write the IHDR chunk, and update the png_struct with the necessary
538.3085 + * information.
538.3086 + */
538.3087 +PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
538.3088 +   png_uint_32 height,
538.3089 +   int bit_depth, int color_type, int compression_method, int filter_method,
538.3090 +   int interlace_method));
538.3091 +
538.3092 +PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
538.3093 +   png_uint_32 num_pal));
538.3094 +
538.3095 +PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
538.3096 +   png_size_t length));
538.3097 +
538.3098 +PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
538.3099 +
538.3100 +#if defined(PNG_WRITE_gAMA_SUPPORTED)
538.3101 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.3102 +PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
538.3103 +#endif
538.3104 +#ifdef PNG_FIXED_POINT_SUPPORTED
538.3105 +PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point
538.3106 +    file_gamma));
538.3107 +#endif
538.3108 +#endif
538.3109 +
538.3110 +#if defined(PNG_WRITE_sBIT_SUPPORTED)
538.3111 +PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
538.3112 +   int color_type));
538.3113 +#endif
538.3114 +
538.3115 +#if defined(PNG_WRITE_cHRM_SUPPORTED)
538.3116 +#ifdef PNG_FLOATING_POINT_SUPPORTED
538.3117 +PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
538.3118 +   double white_x, double white_y,
538.3119 +   double red_x, double red_y, double green_x, double green_y,
538.3120 +   double blue_x, double blue_y));
538.3121 +#endif
538.3122 +#ifdef PNG_FIXED_POINT_SUPPORTED
538.3123 +PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
538.3124 +   png_fixed_point int_white_x, png_fixed_point int_white_y,
538.3125 +   png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
538.3126 +   int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
538.3127 +   png_fixed_point int_blue_y));
538.3128 +#endif
538.3129 +#endif
538.3130 +
538.3131 +#if defined(PNG_WRITE_sRGB_SUPPORTED)
538.3132 +PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
538.3133 +   int intent));
538.3134 +#endif
538.3135 +
538.3136 +#if defined(PNG_WRITE_iCCP_SUPPORTED)
538.3137 +PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
538.3138 +   png_charp name, int compression_type,
538.3139 +   png_charp profile, int proflen));
538.3140 +   /* Note to maintainer: profile should be png_bytep */
538.3141 +#endif
538.3142 +
538.3143 +#if defined(PNG_WRITE_sPLT_SUPPORTED)
538.3144 +PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
538.3145 +   png_sPLT_tp palette));
538.3146 +#endif
538.3147 +
538.3148 +#if defined(PNG_WRITE_tRNS_SUPPORTED)
538.3149 +PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
538.3150 +   png_color_16p values, int number, int color_type));
538.3151 +#endif
538.3152 +
538.3153 +#if defined(PNG_WRITE_bKGD_SUPPORTED)
538.3154 +PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
538.3155 +   png_color_16p values, int color_type));
538.3156 +#endif
538.3157 +
538.3158 +#if defined(PNG_WRITE_hIST_SUPPORTED)
538.3159 +PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
538.3160 +   int num_hist));
538.3161 +#endif
538.3162 +
538.3163 +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
538.3164 +    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
538.3165 +PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
538.3166 +   png_charp key, png_charpp new_key));
538.3167 +#endif
538.3168 +
538.3169 +#if defined(PNG_WRITE_tEXt_SUPPORTED)
538.3170 +PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
538.3171 +   png_charp text, png_size_t text_len));
538.3172 +#endif
538.3173 +
538.3174 +#if defined(PNG_WRITE_zTXt_SUPPORTED)
538.3175 +PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
538.3176 +   png_charp text, png_size_t text_len, int compression));
538.3177 +#endif
538.3178 +
538.3179 +#if defined(PNG_WRITE_iTXt_SUPPORTED)
538.3180 +PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
538.3181 +   int compression, png_charp key, png_charp lang, png_charp lang_key,
538.3182 +   png_charp text));
538.3183 +#endif
538.3184 +
538.3185 +#if defined(PNG_TEXT_SUPPORTED)  /* Added at version 1.0.14 and 1.2.4 */
538.3186 +PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
538.3187 +   png_infop info_ptr, png_textp text_ptr, int num_text));
538.3188 +#endif
538.3189 +
538.3190 +#if defined(PNG_WRITE_oFFs_SUPPORTED)
538.3191 +PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
538.3192 +   png_int_32 x_offset, png_int_32 y_offset, int unit_type));
538.3193 +#endif
538.3194 +
538.3195 +#if defined(PNG_WRITE_pCAL_SUPPORTED)
538.3196 +PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
538.3197 +   png_int_32 X0, png_int_32 X1, int type, int nparams,
538.3198 +   png_charp units, png_charpp params));
538.3199 +#endif
538.3200 +
538.3201 +#if defined(PNG_WRITE_pHYs_SUPPORTED)
538.3202 +PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
538.3203 +   png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
538.3204 +   int unit_type));
538.3205 +#endif
538.3206 +
538.3207 +#if defined(PNG_WRITE_tIME_SUPPORTED)
538.3208 +PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
538.3209 +   png_timep mod_time));
538.3210 +#endif
538.3211 +
538.3212 +#if defined(PNG_WRITE_sCAL_SUPPORTED)
538.3213 +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
538.3214 +PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
538.3215 +   int unit, double width, double height));
538.3216 +#else
538.3217 +#ifdef PNG_FIXED_POINT_SUPPORTED
538.3218 +PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
538.3219 +   int unit, png_charp width, png_charp height));
538.3220 +#endif
538.3221 +#endif
538.3222 +#endif
538.3223 +
538.3224 +/* Called when finished processing a row of data */
538.3225 +PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
538.3226 +
538.3227 +/* Internal use only.   Called before first row of data */
538.3228 +PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
538.3229 +
538.3230 +#if defined(PNG_READ_GAMMA_SUPPORTED)
538.3231 +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr));
538.3232 +#endif
538.3233 +
538.3234 +/* combine a row of data, dealing with alpha, etc. if requested */
538.3235 +PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
538.3236 +   int mask));
538.3237 +
538.3238 +#if defined(PNG_READ_INTERLACING_SUPPORTED)
538.3239 +/* expand an interlaced row */
538.3240 +/* OLD pre-1.0.9 interface:
538.3241 +PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
538.3242 +   png_bytep row, int pass, png_uint_32 transformations));
538.3243 + */
538.3244 +PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
538.3245 +#endif
538.3246 +
538.3247 +/* GRR TO DO (2.0 or whenever):  simplify other internal calling interfaces */
538.3248 +
538.3249 +#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
538.3250 +/* grab pixels out of a row for an interlaced pass */
538.3251 +PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
538.3252 +   png_bytep row, int pass));
538.3253 +#endif
538.3254 +
538.3255 +/* unfilter a row */
538.3256 +PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
538.3257 +   png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter));
538.3258 +
538.3259 +/* Choose the best filter to use and filter the row data */
538.3260 +PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
538.3261 +   png_row_infop row_info));
538.3262 +
538.3263 +/* Write out the filtered row. */
538.3264 +PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
538.3265 +   png_bytep filtered_row));
538.3266 +/* finish a row while reading, dealing with interlacing passes, etc. */
538.3267 +PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
538.3268 +
538.3269 +/* initialize the row buffers, etc. */
538.3270 +PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
538.3271 +/* optional call to update the users info structure */
538.3272 +PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
538.3273 +   png_infop info_ptr));
538.3274 +
538.3275 +/* these are the functions that do the transformations */
538.3276 +#if defined(PNG_READ_FILLER_SUPPORTED)
538.3277 +PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
538.3278 +   png_bytep row, png_uint_32 filler, png_uint_32 flags));
538.3279 +#endif
538.3280 +
538.3281 +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
538.3282 +PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
538.3283 +   png_bytep row));
538.3284 +#endif
538.3285 +
538.3286 +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
538.3287 +PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
538.3288 +   png_bytep row));
538.3289 +#endif
538.3290 +
538.3291 +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
538.3292 +PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
538.3293 +   png_bytep row));
538.3294 +#endif
538.3295 +
538.3296 +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
538.3297 +PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
538.3298 +   png_bytep row));
538.3299 +#endif
538.3300 +
538.3301 +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
538.3302 +    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
538.3303 +PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
538.3304 +   png_bytep row, png_uint_32 flags));
538.3305 +#endif
538.3306 +
538.3307 +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
538.3308 +PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row));
538.3309 +#endif
538.3310 +
538.3311 +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
538.3312 +PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row));
538.3313 +#endif
538.3314 +
538.3315 +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
538.3316 +PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
538.3317 +   row_info, png_bytep row));
538.3318 +#endif
538.3319 +
538.3320 +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
538.3321 +PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
538.3322 +   png_bytep row));
538.3323 +#endif
538.3324 +
538.3325 +#if defined(PNG_READ_PACK_SUPPORTED)
538.3326 +PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row));
538.3327 +#endif
538.3328 +
538.3329 +#if defined(PNG_READ_SHIFT_SUPPORTED)
538.3330 +PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
538.3331 +   png_color_8p sig_bits));
538.3332 +#endif
538.3333 +
538.3334 +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
538.3335 +PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row));
538.3336 +#endif
538.3337 +
538.3338 +#if defined(PNG_READ_16_TO_8_SUPPORTED)
538.3339 +PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row));
538.3340 +#endif
538.3341 +
538.3342 +#if defined(PNG_READ_DITHER_SUPPORTED)
538.3343 +PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info,
538.3344 +   png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup));
538.3345 +
538.3346 +#  if defined(PNG_CORRECT_PALETTE_SUPPORTED)
538.3347 +PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
538.3348 +   png_colorp palette, int num_palette));
538.3349 +#  endif
538.3350 +#endif
538.3351 +
538.3352 +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
538.3353 +PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row));
538.3354 +#endif
538.3355 +
538.3356 +#if defined(PNG_WRITE_PACK_SUPPORTED)
538.3357 +PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
538.3358 +   png_bytep row, png_uint_32 bit_depth));
538.3359 +#endif
538.3360 +
538.3361 +#if defined(PNG_WRITE_SHIFT_SUPPORTED)
538.3362 +PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
538.3363 +   png_color_8p bit_depth));
538.3364 +#endif
538.3365 +
538.3366 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
538.3367 +#if defined(PNG_READ_GAMMA_SUPPORTED)
538.3368 +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
538.3369 +   png_color_16p trans_values, png_color_16p background,
538.3370 +   png_color_16p background_1,
538.3371 +   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
538.3372 +   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
538.3373 +   png_uint_16pp gamma_16_to_1, int gamma_shift));
538.3374 +#else
538.3375 +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
538.3376 +   png_color_16p trans_values, png_color_16p background));
538.3377 +#endif
538.3378 +#endif
538.3379 +
538.3380 +#if defined(PNG_READ_GAMMA_SUPPORTED)
538.3381 +PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
538.3382 +   png_bytep gamma_table, png_uint_16pp gamma_16_table,
538.3383 +   int gamma_shift));
538.3384 +#endif
538.3385 +
538.3386 +#if defined(PNG_READ_EXPAND_SUPPORTED)
538.3387 +PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
538.3388 +   png_bytep row, png_colorp palette, png_bytep trans, int num_trans));
538.3389 +PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
538.3390 +   png_bytep row, png_color_16p trans_value));
538.3391 +#endif
538.3392 +
538.3393 +/* The following decodes the appropriate chunks, and does error correction,
538.3394 + * then calls the appropriate callback for the chunk if it is valid.
538.3395 + */
538.3396 +
538.3397 +/* decode the IHDR chunk */
538.3398 +PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3399 +   png_uint_32 length));
538.3400 +PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3401 +   png_uint_32 length));
538.3402 +PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3403 +   png_uint_32 length));
538.3404 +
538.3405 +#if defined(PNG_READ_bKGD_SUPPORTED)
538.3406 +PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3407 +   png_uint_32 length));
538.3408 +#endif
538.3409 +
538.3410 +#if defined(PNG_READ_cHRM_SUPPORTED)
538.3411 +PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3412 +   png_uint_32 length));
538.3413 +#endif
538.3414 +
538.3415 +#if defined(PNG_READ_gAMA_SUPPORTED)
538.3416 +PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3417 +   png_uint_32 length));
538.3418 +#endif
538.3419 +
538.3420 +#if defined(PNG_READ_hIST_SUPPORTED)
538.3421 +PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3422 +   png_uint_32 length));
538.3423 +#endif
538.3424 +
538.3425 +#if defined(PNG_READ_iCCP_SUPPORTED)
538.3426 +extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3427 +   png_uint_32 length));
538.3428 +#endif /* PNG_READ_iCCP_SUPPORTED */
538.3429 +
538.3430 +#if defined(PNG_READ_iTXt_SUPPORTED)
538.3431 +PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3432 +   png_uint_32 length));
538.3433 +#endif
538.3434 +
538.3435 +#if defined(PNG_READ_oFFs_SUPPORTED)
538.3436 +PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3437 +   png_uint_32 length));
538.3438 +#endif
538.3439 +
538.3440 +#if defined(PNG_READ_pCAL_SUPPORTED)
538.3441 +PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3442 +   png_uint_32 length));
538.3443 +#endif
538.3444 +
538.3445 +#if defined(PNG_READ_pHYs_SUPPORTED)
538.3446 +PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3447 +   png_uint_32 length));
538.3448 +#endif
538.3449 +
538.3450 +#if defined(PNG_READ_sBIT_SUPPORTED)
538.3451 +PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3452 +   png_uint_32 length));
538.3453 +#endif
538.3454 +
538.3455 +#if defined(PNG_READ_sCAL_SUPPORTED)
538.3456 +PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3457 +   png_uint_32 length));
538.3458 +#endif
538.3459 +
538.3460 +#if defined(PNG_READ_sPLT_SUPPORTED)
538.3461 +extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3462 +   png_uint_32 length));
538.3463 +#endif /* PNG_READ_sPLT_SUPPORTED */
538.3464 +
538.3465 +#if defined(PNG_READ_sRGB_SUPPORTED)
538.3466 +PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3467 +   png_uint_32 length));
538.3468 +#endif
538.3469 +
538.3470 +#if defined(PNG_READ_tEXt_SUPPORTED)
538.3471 +PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3472 +   png_uint_32 length));
538.3473 +#endif
538.3474 +
538.3475 +#if defined(PNG_READ_tIME_SUPPORTED)
538.3476 +PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3477 +   png_uint_32 length));
538.3478 +#endif
538.3479 +
538.3480 +#if defined(PNG_READ_tRNS_SUPPORTED)
538.3481 +PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3482 +   png_uint_32 length));
538.3483 +#endif
538.3484 +
538.3485 +#if defined(PNG_READ_zTXt_SUPPORTED)
538.3486 +PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
538.3487 +   png_uint_32 length));
538.3488 +#endif
538.3489 +
538.3490 +PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
538.3491 +   png_infop info_ptr, png_uint_32 length));
538.3492 +
538.3493 +PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
538.3494 +   png_bytep chunk_name));
538.3495 +
538.3496 +/* handle the transformations for reading and writing */
538.3497 +PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr));
538.3498 +PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr));
538.3499 +
538.3500 +PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
538.3501 +
538.3502 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
538.3503 +PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
538.3504 +   png_infop info_ptr));
538.3505 +PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
538.3506 +   png_infop info_ptr));
538.3507 +PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
538.3508 +PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
538.3509 +   png_uint_32 length));
538.3510 +PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
538.3511 +PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
538.3512 +PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
538.3513 +   png_bytep buffer, png_size_t buffer_length));
538.3514 +PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
538.3515 +PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
538.3516 +   png_bytep buffer, png_size_t buffer_length));
538.3517 +PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
538.3518 +PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
538.3519 +   png_infop info_ptr, png_uint_32 length));
538.3520 +PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
538.3521 +   png_infop info_ptr));
538.3522 +PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
538.3523 +   png_infop info_ptr));
538.3524 +PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
538.3525 +PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
538.3526 +   png_infop info_ptr));
538.3527 +PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
538.3528 +   png_infop info_ptr));
538.3529 +PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
538.3530 +#if defined(PNG_READ_tEXt_SUPPORTED)
538.3531 +PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
538.3532 +   png_infop info_ptr, png_uint_32 length));
538.3533 +PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
538.3534 +   png_infop info_ptr));
538.3535 +#endif
538.3536 +#if defined(PNG_READ_zTXt_SUPPORTED)
538.3537 +PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
538.3538 +   png_infop info_ptr, png_uint_32 length));
538.3539 +PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
538.3540 +   png_infop info_ptr));
538.3541 +#endif
538.3542 +#if defined(PNG_READ_iTXt_SUPPORTED)
538.3543 +PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
538.3544 +   png_infop info_ptr, png_uint_32 length));
538.3545 +PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
538.3546 +   png_infop info_ptr));
538.3547 +#endif
538.3548 +
538.3549 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
538.3550 +
538.3551 +#ifdef PNG_MNG_FEATURES_SUPPORTED
538.3552 +PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
538.3553 +   png_bytep row));
538.3554 +PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
538.3555 +   png_bytep row));
538.3556 +#endif
538.3557 +
538.3558 +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
538.3559 +#if defined(PNG_MMX_CODE_SUPPORTED)
538.3560 +/* png.c */ /* PRIVATE */
538.3561 +PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr));
538.3562 +#endif
538.3563 +#endif
538.3564 +
538.3565 +#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
538.3566 +PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr,
538.3567 +png_infop info_ptr));
538.3568 +
538.3569 +PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr,
538.3570 +png_infop info_ptr));
538.3571 +
538.3572 +PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr,
538.3573 +png_infop info_ptr));
538.3574 +
538.3575 +PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr,
538.3576 +png_infop info_ptr));
538.3577 +
538.3578 +PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr,
538.3579 +png_infop info_ptr));
538.3580 +
538.3581 +#if defined(PNG_pHYs_SUPPORTED)
538.3582 +PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr,
538.3583 +png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
538.3584 +#endif /* PNG_pHYs_SUPPORTED */
538.3585 +#endif  /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
538.3586 +
538.3587 +/* Read the chunk header (length + type name) */
538.3588 +PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr));
538.3589 +
538.3590 +/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
538.3591 +
538.3592 +#endif /* PNG_INTERNAL */
538.3593 +
538.3594 +#ifdef __cplusplus
538.3595 +}
538.3596 +#endif
538.3597 +
538.3598 +#endif /* PNG_VERSION_INFO_ONLY */
538.3599 +/* do not put anything past this line */
538.3600 +#endif /* PNG_H */
   539.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   539.2 +++ b/libs/libpng/pngconf.h	Sat Feb 01 19:58:19 2014 +0200
   539.3 @@ -0,0 +1,1481 @@
   539.4 +
   539.5 +/* pngconf.h - machine configurable file for libpng
   539.6 + *
   539.7 + * libpng version 1.2.33 - October 31, 2008
   539.8 + * For conditions of distribution and use, see copyright notice in png.h
   539.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  539.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  539.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  539.12 + */
  539.13 +
  539.14 +/* Any machine specific code is near the front of this file, so if you
  539.15 + * are configuring libpng for a machine, you may want to read the section
  539.16 + * starting here down to where it starts to typedef png_color, png_text,
  539.17 + * and png_info.
  539.18 + */
  539.19 +
  539.20 +#ifndef PNGCONF_H
  539.21 +#define PNGCONF_H
  539.22 +
  539.23 +#define PNG_1_2_X
  539.24 +
  539.25 +/* 
  539.26 + * PNG_USER_CONFIG has to be defined on the compiler command line. This
  539.27 + * includes the resource compiler for Windows DLL configurations.
  539.28 + */
  539.29 +#ifdef PNG_USER_CONFIG
  539.30 +#  ifndef PNG_USER_PRIVATEBUILD
  539.31 +#    define PNG_USER_PRIVATEBUILD
  539.32 +#  endif
  539.33 +#include "pngusr.h"
  539.34 +#endif
  539.35 +
  539.36 +/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */
  539.37 +#ifdef PNG_CONFIGURE_LIBPNG
  539.38 +#ifdef HAVE_CONFIG_H
  539.39 +#include "config.h"
  539.40 +#endif
  539.41 +#endif
  539.42 +
  539.43 +/*
  539.44 + * Added at libpng-1.2.8
  539.45 + *  
  539.46 + * If you create a private DLL you need to define in "pngusr.h" the followings:
  539.47 + * #define PNG_USER_PRIVATEBUILD <Describes by whom and why this version of
  539.48 + *        the DLL was built>
  539.49 + *  e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons."
  539.50 + * #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to
  539.51 + *        distinguish your DLL from those of the official release. These
  539.52 + *        correspond to the trailing letters that come after the version
  539.53 + *        number and must match your private DLL name>
  539.54 + *  e.g. // private DLL "libpng13gx.dll"
  539.55 + *       #define PNG_USER_DLLFNAME_POSTFIX "gx"
  539.56 + * 
  539.57 + * The following macros are also at your disposal if you want to complete the 
  539.58 + * DLL VERSIONINFO structure.
  539.59 + * - PNG_USER_VERSIONINFO_COMMENTS
  539.60 + * - PNG_USER_VERSIONINFO_COMPANYNAME
  539.61 + * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS
  539.62 + */
  539.63 +
  539.64 +#ifdef __STDC__
  539.65 +#ifdef SPECIALBUILD
  539.66 +#  pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\
  539.67 + are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.")
  539.68 +#endif
  539.69 +
  539.70 +#ifdef PRIVATEBUILD
  539.71 +# pragma message("PRIVATEBUILD is deprecated.\
  539.72 + Use PNG_USER_PRIVATEBUILD instead.")
  539.73 +# define PNG_USER_PRIVATEBUILD PRIVATEBUILD
  539.74 +#endif
  539.75 +#endif /* __STDC__ */
  539.76 +
  539.77 +#ifndef PNG_VERSION_INFO_ONLY
  539.78 +
  539.79 +/* End of material added to libpng-1.2.8 */
  539.80 +
  539.81 +/* Added at libpng-1.2.19, removed at libpng-1.2.20 because it caused trouble
  539.82 +   Restored at libpng-1.2.21 */
  539.83 +#if !defined(PNG_NO_WARN_UNINITIALIZED_ROW) && \
  539.84 +    !defined(PNG_WARN_UNINITIALIZED_ROW)
  539.85 +#  define PNG_WARN_UNINITIALIZED_ROW 1
  539.86 +#endif
  539.87 +/* End of material added at libpng-1.2.19/1.2.21 */
  539.88 +
  539.89 +/* This is the size of the compression buffer, and thus the size of
  539.90 + * an IDAT chunk.  Make this whatever size you feel is best for your
  539.91 + * machine.  One of these will be allocated per png_struct.  When this
  539.92 + * is full, it writes the data to the disk, and does some other
  539.93 + * calculations.  Making this an extremely small size will slow
  539.94 + * the library down, but you may want to experiment to determine
  539.95 + * where it becomes significant, if you are concerned with memory
  539.96 + * usage.  Note that zlib allocates at least 32Kb also.  For readers,
  539.97 + * this describes the size of the buffer available to read the data in.
  539.98 + * Unless this gets smaller than the size of a row (compressed),
  539.99 + * it should not make much difference how big this is.
 539.100 + */
 539.101 +
 539.102 +#ifndef PNG_ZBUF_SIZE
 539.103 +#  define PNG_ZBUF_SIZE 8192
 539.104 +#endif
 539.105 +
 539.106 +/* Enable if you want a write-only libpng */
 539.107 +
 539.108 +#ifndef PNG_NO_READ_SUPPORTED
 539.109 +#  define PNG_READ_SUPPORTED
 539.110 +#endif
 539.111 +
 539.112 +/* Enable if you want a read-only libpng */
 539.113 +
 539.114 +#ifndef PNG_NO_WRITE_SUPPORTED
 539.115 +#  define PNG_WRITE_SUPPORTED
 539.116 +#endif
 539.117 +
 539.118 +/* Enabled by default in 1.2.0.  You can disable this if you don't need to
 539.119 +   support PNGs that are embedded in MNG datastreams */
 539.120 +#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES)
 539.121 +#  ifndef PNG_MNG_FEATURES_SUPPORTED
 539.122 +#    define PNG_MNG_FEATURES_SUPPORTED
 539.123 +#  endif
 539.124 +#endif
 539.125 +
 539.126 +#ifndef PNG_NO_FLOATING_POINT_SUPPORTED
 539.127 +#  ifndef PNG_FLOATING_POINT_SUPPORTED
 539.128 +#    define PNG_FLOATING_POINT_SUPPORTED
 539.129 +#  endif
 539.130 +#endif
 539.131 +
 539.132 +/* If you are running on a machine where you cannot allocate more
 539.133 + * than 64K of memory at once, uncomment this.  While libpng will not
 539.134 + * normally need that much memory in a chunk (unless you load up a very
 539.135 + * large file), zlib needs to know how big of a chunk it can use, and
 539.136 + * libpng thus makes sure to check any memory allocation to verify it
 539.137 + * will fit into memory.
 539.138 +#define PNG_MAX_MALLOC_64K
 539.139 + */
 539.140 +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
 539.141 +#  define PNG_MAX_MALLOC_64K
 539.142 +#endif
 539.143 +
 539.144 +/* Special munging to support doing things the 'cygwin' way:
 539.145 + * 'Normal' png-on-win32 defines/defaults:
 539.146 + *   PNG_BUILD_DLL -- building dll
 539.147 + *   PNG_USE_DLL   -- building an application, linking to dll
 539.148 + *   (no define)   -- building static library, or building an
 539.149 + *                    application and linking to the static lib
 539.150 + * 'Cygwin' defines/defaults:
 539.151 + *   PNG_BUILD_DLL -- (ignored) building the dll
 539.152 + *   (no define)   -- (ignored) building an application, linking to the dll
 539.153 + *   PNG_STATIC    -- (ignored) building the static lib, or building an 
 539.154 + *                    application that links to the static lib.
 539.155 + *   ALL_STATIC    -- (ignored) building various static libs, or building an 
 539.156 + *                    application that links to the static libs.
 539.157 + * Thus,
 539.158 + * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and
 539.159 + * this bit of #ifdefs will define the 'correct' config variables based on
 539.160 + * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but
 539.161 + * unnecessary.
 539.162 + *
 539.163 + * Also, the precedence order is:
 539.164 + *   ALL_STATIC (since we can't #undef something outside our namespace)
 539.165 + *   PNG_BUILD_DLL
 539.166 + *   PNG_STATIC
 539.167 + *   (nothing) == PNG_USE_DLL
 539.168 + * 
 539.169 + * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent
 539.170 + *   of auto-import in binutils, we no longer need to worry about 
 539.171 + *   __declspec(dllexport) / __declspec(dllimport) and friends.  Therefore,
 539.172 + *   we don't need to worry about PNG_STATIC or ALL_STATIC when it comes
 539.173 + *   to __declspec() stuff.  However, we DO need to worry about 
 539.174 + *   PNG_BUILD_DLL and PNG_STATIC because those change some defaults
 539.175 + *   such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed.
 539.176 + */
 539.177 +#if defined(__CYGWIN__)
 539.178 +#  if defined(ALL_STATIC)
 539.179 +#    if defined(PNG_BUILD_DLL)
 539.180 +#      undef PNG_BUILD_DLL
 539.181 +#    endif
 539.182 +#    if defined(PNG_USE_DLL)
 539.183 +#      undef PNG_USE_DLL
 539.184 +#    endif
 539.185 +#    if defined(PNG_DLL)
 539.186 +#      undef PNG_DLL
 539.187 +#    endif
 539.188 +#    if !defined(PNG_STATIC)
 539.189 +#      define PNG_STATIC
 539.190 +#    endif
 539.191 +#  else
 539.192 +#    if defined (PNG_BUILD_DLL)
 539.193 +#      if defined(PNG_STATIC)
 539.194 +#        undef PNG_STATIC
 539.195 +#      endif
 539.196 +#      if defined(PNG_USE_DLL)
 539.197 +#        undef PNG_USE_DLL
 539.198 +#      endif
 539.199 +#      if !defined(PNG_DLL)
 539.200 +#        define PNG_DLL
 539.201 +#      endif
 539.202 +#    else
 539.203 +#      if defined(PNG_STATIC)
 539.204 +#        if defined(PNG_USE_DLL)
 539.205 +#          undef PNG_USE_DLL
 539.206 +#        endif
 539.207 +#        if defined(PNG_DLL)
 539.208 +#          undef PNG_DLL
 539.209 +#        endif
 539.210 +#      else
 539.211 +#        if !defined(PNG_USE_DLL)
 539.212 +#          define PNG_USE_DLL
 539.213 +#        endif
 539.214 +#        if !defined(PNG_DLL)
 539.215 +#          define PNG_DLL
 539.216 +#        endif
 539.217 +#      endif  
 539.218 +#    endif  
 539.219 +#  endif
 539.220 +#endif
 539.221 +
 539.222 +/* This protects us against compilers that run on a windowing system
 539.223 + * and thus don't have or would rather us not use the stdio types:
 539.224 + * stdin, stdout, and stderr.  The only one currently used is stderr
 539.225 + * in png_error() and png_warning().  #defining PNG_NO_CONSOLE_IO will
 539.226 + * prevent these from being compiled and used. #defining PNG_NO_STDIO
 539.227 + * will also prevent these, plus will prevent the entire set of stdio
 539.228 + * macros and functions (FILE *, printf, etc.) from being compiled and used,
 539.229 + * unless (PNG_DEBUG > 0) has been #defined.
 539.230 + *
 539.231 + * #define PNG_NO_CONSOLE_IO
 539.232 + * #define PNG_NO_STDIO
 539.233 + */
 539.234 +
 539.235 +#if defined(_WIN32_WCE)
 539.236 +#  include <windows.h>
 539.237 +   /* Console I/O functions are not supported on WindowsCE */
 539.238 +#  define PNG_NO_CONSOLE_IO
 539.239 +#  ifdef PNG_DEBUG
 539.240 +#    undef PNG_DEBUG
 539.241 +#  endif
 539.242 +#endif
 539.243 +
 539.244 +#ifdef PNG_BUILD_DLL
 539.245 +#  ifndef PNG_CONSOLE_IO_SUPPORTED
 539.246 +#    ifndef PNG_NO_CONSOLE_IO
 539.247 +#      define PNG_NO_CONSOLE_IO
 539.248 +#    endif
 539.249 +#  endif
 539.250 +#endif
 539.251 +
 539.252 +#  ifdef PNG_NO_STDIO
 539.253 +#    ifndef PNG_NO_CONSOLE_IO
 539.254 +#      define PNG_NO_CONSOLE_IO
 539.255 +#    endif
 539.256 +#    ifdef PNG_DEBUG
 539.257 +#      if (PNG_DEBUG > 0)
 539.258 +#        include <stdio.h>
 539.259 +#      endif
 539.260 +#    endif
 539.261 +#  else
 539.262 +#    if !defined(_WIN32_WCE)
 539.263 +/* "stdio.h" functions are not supported on WindowsCE */
 539.264 +#      include <stdio.h>
 539.265 +#    endif
 539.266 +#  endif
 539.267 +
 539.268 +/* This macro protects us against machines that don't have function
 539.269 + * prototypes (ie K&R style headers).  If your compiler does not handle
 539.270 + * function prototypes, define this macro and use the included ansi2knr.
 539.271 + * I've always been able to use _NO_PROTO as the indicator, but you may
 539.272 + * need to drag the empty declaration out in front of here, or change the
 539.273 + * ifdef to suit your own needs.
 539.274 + */
 539.275 +#ifndef PNGARG
 539.276 +
 539.277 +#ifdef OF /* zlib prototype munger */
 539.278 +#  define PNGARG(arglist) OF(arglist)
 539.279 +#else
 539.280 +
 539.281 +#ifdef _NO_PROTO
 539.282 +#  define PNGARG(arglist) ()
 539.283 +#  ifndef PNG_TYPECAST_NULL
 539.284 +#     define PNG_TYPECAST_NULL
 539.285 +#  endif
 539.286 +#else
 539.287 +#  define PNGARG(arglist) arglist
 539.288 +#endif /* _NO_PROTO */
 539.289 +
 539.290 +
 539.291 +#endif /* OF */
 539.292 +
 539.293 +#endif /* PNGARG */
 539.294 +
 539.295 +/* Try to determine if we are compiling on a Mac.  Note that testing for
 539.296 + * just __MWERKS__ is not good enough, because the Codewarrior is now used
 539.297 + * on non-Mac platforms.
 539.298 + */
 539.299 +#ifndef MACOS
 539.300 +#  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
 539.301 +      defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
 539.302 +#    define MACOS
 539.303 +#  endif
 539.304 +#endif
 539.305 +
 539.306 +/* enough people need this for various reasons to include it here */
 539.307 +#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE)
 539.308 +#  include <sys/types.h>
 539.309 +#endif
 539.310 +
 539.311 +#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED)
 539.312 +#  define PNG_SETJMP_SUPPORTED
 539.313 +#endif
 539.314 +
 539.315 +#ifdef PNG_SETJMP_SUPPORTED
 539.316 +/* This is an attempt to force a single setjmp behaviour on Linux.  If
 539.317 + * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
 539.318 + */
 539.319 +
 539.320 +#  ifdef __linux__
 539.321 +#    ifdef _BSD_SOURCE
 539.322 +#      define PNG_SAVE_BSD_SOURCE
 539.323 +#      undef _BSD_SOURCE
 539.324 +#    endif
 539.325 +#    ifdef _SETJMP_H
 539.326 +     /* If you encounter a compiler error here, see the explanation
 539.327 +      * near the end of INSTALL.
 539.328 +      */
 539.329 +         __pngconf.h__ already includes setjmp.h;
 539.330 +         __dont__ include it again.;
 539.331 +#    endif
 539.332 +#  endif /* __linux__ */
 539.333 +
 539.334 +   /* include setjmp.h for error handling */
 539.335 +#  include <setjmp.h>
 539.336 +
 539.337 +#  ifdef __linux__
 539.338 +#    ifdef PNG_SAVE_BSD_SOURCE
 539.339 +#      ifndef _BSD_SOURCE
 539.340 +#        define _BSD_SOURCE
 539.341 +#      endif
 539.342 +#      undef PNG_SAVE_BSD_SOURCE
 539.343 +#    endif
 539.344 +#  endif /* __linux__ */
 539.345 +#endif /* PNG_SETJMP_SUPPORTED */
 539.346 +
 539.347 +#ifdef BSD
 539.348 +#  include <strings.h>
 539.349 +#else
 539.350 +#  include <string.h>
 539.351 +#endif
 539.352 +
 539.353 +/* Other defines for things like memory and the like can go here.  */
 539.354 +#ifdef PNG_INTERNAL
 539.355 +
 539.356 +#include <stdlib.h>
 539.357 +
 539.358 +/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
 539.359 + * aren't usually used outside the library (as far as I know), so it is
 539.360 + * debatable if they should be exported at all.  In the future, when it is
 539.361 + * possible to have run-time registry of chunk-handling functions, some of
 539.362 + * these will be made available again.
 539.363 +#define PNG_EXTERN extern
 539.364 + */
 539.365 +#define PNG_EXTERN
 539.366 +
 539.367 +/* Other defines specific to compilers can go here.  Try to keep
 539.368 + * them inside an appropriate ifdef/endif pair for portability.
 539.369 + */
 539.370 +
 539.371 +#if defined(PNG_FLOATING_POINT_SUPPORTED)
 539.372 +#  if defined(MACOS)
 539.373 +     /* We need to check that <math.h> hasn't already been included earlier
 539.374 +      * as it seems it doesn't agree with <fp.h>, yet we should really use
 539.375 +      * <fp.h> if possible.
 539.376 +      */
 539.377 +#    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
 539.378 +#      include <fp.h>
 539.379 +#    endif
 539.380 +#  else
 539.381 +#    include <math.h>
 539.382 +#  endif
 539.383 +#  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
 539.384 +     /* Amiga SAS/C: We must include builtin FPU functions when compiling using
 539.385 +      * MATH=68881
 539.386 +      */
 539.387 +#    include <m68881.h>
 539.388 +#  endif
 539.389 +#endif
 539.390 +
 539.391 +/* Codewarrior on NT has linking problems without this. */
 539.392 +#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
 539.393 +#  define PNG_ALWAYS_EXTERN
 539.394 +#endif
 539.395 +
 539.396 +/* This provides the non-ANSI (far) memory allocation routines. */
 539.397 +#if defined(__TURBOC__) && defined(__MSDOS__)
 539.398 +#  include <mem.h>
 539.399 +#  include <alloc.h>
 539.400 +#endif
 539.401 +
 539.402 +/* I have no idea why is this necessary... */
 539.403 +#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \
 539.404 +    defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__))
 539.405 +#  include <malloc.h>
 539.406 +#endif
 539.407 +
 539.408 +/* This controls how fine the dithering gets.  As this allocates
 539.409 + * a largish chunk of memory (32K), those who are not as concerned
 539.410 + * with dithering quality can decrease some or all of these.
 539.411 + */
 539.412 +#ifndef PNG_DITHER_RED_BITS
 539.413 +#  define PNG_DITHER_RED_BITS 5
 539.414 +#endif
 539.415 +#ifndef PNG_DITHER_GREEN_BITS
 539.416 +#  define PNG_DITHER_GREEN_BITS 5
 539.417 +#endif
 539.418 +#ifndef PNG_DITHER_BLUE_BITS
 539.419 +#  define PNG_DITHER_BLUE_BITS 5
 539.420 +#endif
 539.421 +
 539.422 +/* This controls how fine the gamma correction becomes when you
 539.423 + * are only interested in 8 bits anyway.  Increasing this value
 539.424 + * results in more memory being used, and more pow() functions
 539.425 + * being called to fill in the gamma tables.  Don't set this value
 539.426 + * less then 8, and even that may not work (I haven't tested it).
 539.427 + */
 539.428 +
 539.429 +#ifndef PNG_MAX_GAMMA_8
 539.430 +#  define PNG_MAX_GAMMA_8 11
 539.431 +#endif
 539.432 +
 539.433 +/* This controls how much a difference in gamma we can tolerate before
 539.434 + * we actually start doing gamma conversion.
 539.435 + */
 539.436 +#ifndef PNG_GAMMA_THRESHOLD
 539.437 +#  define PNG_GAMMA_THRESHOLD 0.05
 539.438 +#endif
 539.439 +
 539.440 +#endif /* PNG_INTERNAL */
 539.441 +
 539.442 +/* The following uses const char * instead of char * for error
 539.443 + * and warning message functions, so some compilers won't complain.
 539.444 + * If you do not want to use const, define PNG_NO_CONST here.
 539.445 + */
 539.446 +
 539.447 +#ifndef PNG_NO_CONST
 539.448 +#  define PNG_CONST const
 539.449 +#else
 539.450 +#  define PNG_CONST
 539.451 +#endif
 539.452 +
 539.453 +/* The following defines give you the ability to remove code from the
 539.454 + * library that you will not be using.  I wish I could figure out how to
 539.455 + * automate this, but I can't do that without making it seriously hard
 539.456 + * on the users.  So if you are not using an ability, change the #define
 539.457 + * to and #undef, and that part of the library will not be compiled.  If
 539.458 + * your linker can't find a function, you may want to make sure the
 539.459 + * ability is defined here.  Some of these depend upon some others being
 539.460 + * defined.  I haven't figured out all the interactions here, so you may
 539.461 + * have to experiment awhile to get everything to compile.  If you are
 539.462 + * creating or using a shared library, you probably shouldn't touch this,
 539.463 + * as it will affect the size of the structures, and this will cause bad
 539.464 + * things to happen if the library and/or application ever change.
 539.465 + */
 539.466 +
 539.467 +/* Any features you will not be using can be undef'ed here */
 539.468 +
 539.469 +/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
 539.470 + * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
 539.471 + * on the compile line, then pick and choose which ones to define without
 539.472 + * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
 539.473 + * if you only want to have a png-compliant reader/writer but don't need
 539.474 + * any of the extra transformations.  This saves about 80 kbytes in a
 539.475 + * typical installation of the library. (PNG_NO_* form added in version
 539.476 + * 1.0.1c, for consistency)
 539.477 + */
 539.478 +
 539.479 +/* The size of the png_text structure changed in libpng-1.0.6 when
 539.480 + * iTXt support was added.  iTXt support was turned off by default through
 539.481 + * libpng-1.2.x, to support old apps that malloc the png_text structure
 539.482 + * instead of calling png_set_text() and letting libpng malloc it.  It
 539.483 + * was turned on by default in libpng-1.3.0.
 539.484 + */
 539.485 +
 539.486 +#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
 539.487 +#  ifndef PNG_NO_iTXt_SUPPORTED
 539.488 +#    define PNG_NO_iTXt_SUPPORTED
 539.489 +#  endif
 539.490 +#  ifndef PNG_NO_READ_iTXt
 539.491 +#    define PNG_NO_READ_iTXt
 539.492 +#  endif
 539.493 +#  ifndef PNG_NO_WRITE_iTXt
 539.494 +#    define PNG_NO_WRITE_iTXt
 539.495 +#  endif
 539.496 +#endif
 539.497 +
 539.498 +#if !defined(PNG_NO_iTXt_SUPPORTED)
 539.499 +#  if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt)
 539.500 +#    define PNG_READ_iTXt
 539.501 +#  endif
 539.502 +#  if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt)
 539.503 +#    define PNG_WRITE_iTXt
 539.504 +#  endif
 539.505 +#endif
 539.506 +
 539.507 +/* The following support, added after version 1.0.0, can be turned off here en
 539.508 + * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility
 539.509 + * with old applications that require the length of png_struct and png_info
 539.510 + * to remain unchanged.
 539.511 + */
 539.512 +
 539.513 +#ifdef PNG_LEGACY_SUPPORTED
 539.514 +#  define PNG_NO_FREE_ME
 539.515 +#  define PNG_NO_READ_UNKNOWN_CHUNKS
 539.516 +#  define PNG_NO_WRITE_UNKNOWN_CHUNKS
 539.517 +#  define PNG_NO_READ_USER_CHUNKS
 539.518 +#  define PNG_NO_READ_iCCP
 539.519 +#  define PNG_NO_WRITE_iCCP
 539.520 +#  define PNG_NO_READ_iTXt
 539.521 +#  define PNG_NO_WRITE_iTXt
 539.522 +#  define PNG_NO_READ_sCAL
 539.523 +#  define PNG_NO_WRITE_sCAL
 539.524 +#  define PNG_NO_READ_sPLT
 539.525 +#  define PNG_NO_WRITE_sPLT
 539.526 +#  define PNG_NO_INFO_IMAGE
 539.527 +#  define PNG_NO_READ_RGB_TO_GRAY
 539.528 +#  define PNG_NO_READ_USER_TRANSFORM
 539.529 +#  define PNG_NO_WRITE_USER_TRANSFORM
 539.530 +#  define PNG_NO_USER_MEM
 539.531 +#  define PNG_NO_READ_EMPTY_PLTE
 539.532 +#  define PNG_NO_MNG_FEATURES
 539.533 +#  define PNG_NO_FIXED_POINT_SUPPORTED
 539.534 +#endif
 539.535 +
 539.536 +/* Ignore attempt to turn off both floating and fixed point support */
 539.537 +#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \
 539.538 +    !defined(PNG_NO_FIXED_POINT_SUPPORTED)
 539.539 +#  define PNG_FIXED_POINT_SUPPORTED
 539.540 +#endif
 539.541 +
 539.542 +#ifndef PNG_NO_FREE_ME
 539.543 +#  define PNG_FREE_ME_SUPPORTED
 539.544 +#endif
 539.545 +
 539.546 +#if defined(PNG_READ_SUPPORTED)
 539.547 +
 539.548 +#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \
 539.549 +      !defined(PNG_NO_READ_TRANSFORMS)
 539.550 +#  define PNG_READ_TRANSFORMS_SUPPORTED
 539.551 +#endif
 539.552 +
 539.553 +#ifdef PNG_READ_TRANSFORMS_SUPPORTED
 539.554 +#  ifndef PNG_NO_READ_EXPAND
 539.555 +#    define PNG_READ_EXPAND_SUPPORTED
 539.556 +#  endif
 539.557 +#  ifndef PNG_NO_READ_SHIFT
 539.558 +#    define PNG_READ_SHIFT_SUPPORTED
 539.559 +#  endif
 539.560 +#  ifndef PNG_NO_READ_PACK
 539.561 +#    define PNG_READ_PACK_SUPPORTED
 539.562 +#  endif
 539.563 +#  ifndef PNG_NO_READ_BGR
 539.564 +#    define PNG_READ_BGR_SUPPORTED
 539.565 +#  endif
 539.566 +#  ifndef PNG_NO_READ_SWAP
 539.567 +#    define PNG_READ_SWAP_SUPPORTED
 539.568 +#  endif
 539.569 +#  ifndef PNG_NO_READ_PACKSWAP
 539.570 +#    define PNG_READ_PACKSWAP_SUPPORTED
 539.571 +#  endif
 539.572 +#  ifndef PNG_NO_READ_INVERT
 539.573 +#    define PNG_READ_INVERT_SUPPORTED
 539.574 +#  endif
 539.575 +#  ifndef PNG_NO_READ_DITHER
 539.576 +#    define PNG_READ_DITHER_SUPPORTED
 539.577 +#  endif
 539.578 +#  ifndef PNG_NO_READ_BACKGROUND
 539.579 +#    define PNG_READ_BACKGROUND_SUPPORTED
 539.580 +#  endif
 539.581 +#  ifndef PNG_NO_READ_16_TO_8
 539.582 +#    define PNG_READ_16_TO_8_SUPPORTED
 539.583 +#  endif
 539.584 +#  ifndef PNG_NO_READ_FILLER
 539.585 +#    define PNG_READ_FILLER_SUPPORTED
 539.586 +#  endif
 539.587 +#  ifndef PNG_NO_READ_GAMMA
 539.588 +#    define PNG_READ_GAMMA_SUPPORTED
 539.589 +#  endif
 539.590 +#  ifndef PNG_NO_READ_GRAY_TO_RGB
 539.591 +#    define PNG_READ_GRAY_TO_RGB_SUPPORTED
 539.592 +#  endif
 539.593 +#  ifndef PNG_NO_READ_SWAP_ALPHA
 539.594 +#    define PNG_READ_SWAP_ALPHA_SUPPORTED
 539.595 +#  endif
 539.596 +#  ifndef PNG_NO_READ_INVERT_ALPHA
 539.597 +#    define PNG_READ_INVERT_ALPHA_SUPPORTED
 539.598 +#  endif
 539.599 +#  ifndef PNG_NO_READ_STRIP_ALPHA
 539.600 +#    define PNG_READ_STRIP_ALPHA_SUPPORTED
 539.601 +#  endif
 539.602 +#  ifndef PNG_NO_READ_USER_TRANSFORM
 539.603 +#    define PNG_READ_USER_TRANSFORM_SUPPORTED
 539.604 +#  endif
 539.605 +#  ifndef PNG_NO_READ_RGB_TO_GRAY
 539.606 +#    define PNG_READ_RGB_TO_GRAY_SUPPORTED
 539.607 +#  endif
 539.608 +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
 539.609 +
 539.610 +#if !defined(PNG_NO_PROGRESSIVE_READ) && \
 539.611 + !defined(PNG_PROGRESSIVE_READ_SUPPORTED) /* if you don't do progressive   */
 539.612 +#  define PNG_PROGRESSIVE_READ_SUPPORTED  /* reading.  This is not talking */
 539.613 +#endif                            /* about interlacing capability!  You'll */
 539.614 +           /* still have interlacing unless you change the following line: */
 539.615 +
 539.616 +#define PNG_READ_INTERLACING_SUPPORTED /* required in PNG-compliant decoders */
 539.617 +
 539.618 +#ifndef PNG_NO_READ_COMPOSITE_NODIV
 539.619 +#  ifndef PNG_NO_READ_COMPOSITED_NODIV  /* libpng-1.0.x misspelling */
 539.620 +#    define PNG_READ_COMPOSITE_NODIV_SUPPORTED  /* well tested on Intel, SGI */
 539.621 +#  endif
 539.622 +#endif
 539.623 +
 539.624 +#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
 539.625 +/* Deprecated, will be removed from version 2.0.0.
 539.626 +   Use PNG_MNG_FEATURES_SUPPORTED instead. */
 539.627 +#ifndef PNG_NO_READ_EMPTY_PLTE
 539.628 +#  define PNG_READ_EMPTY_PLTE_SUPPORTED
 539.629 +#endif
 539.630 +#endif
 539.631 +
 539.632 +#endif /* PNG_READ_SUPPORTED */
 539.633 +
 539.634 +#if defined(PNG_WRITE_SUPPORTED)
 539.635 +
 539.636 +# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \
 539.637 +    !defined(PNG_NO_WRITE_TRANSFORMS)
 539.638 +#  define PNG_WRITE_TRANSFORMS_SUPPORTED
 539.639 +#endif
 539.640 +
 539.641 +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
 539.642 +#  ifndef PNG_NO_WRITE_SHIFT
 539.643 +#    define PNG_WRITE_SHIFT_SUPPORTED
 539.644 +#  endif
 539.645 +#  ifndef PNG_NO_WRITE_PACK
 539.646 +#    define PNG_WRITE_PACK_SUPPORTED
 539.647 +#  endif
 539.648 +#  ifndef PNG_NO_WRITE_BGR
 539.649 +#    define PNG_WRITE_BGR_SUPPORTED
 539.650 +#  endif
 539.651 +#  ifndef PNG_NO_WRITE_SWAP
 539.652 +#    define PNG_WRITE_SWAP_SUPPORTED
 539.653 +#  endif
 539.654 +#  ifndef PNG_NO_WRITE_PACKSWAP
 539.655 +#    define PNG_WRITE_PACKSWAP_SUPPORTED
 539.656 +#  endif
 539.657 +#  ifndef PNG_NO_WRITE_INVERT
 539.658 +#    define PNG_WRITE_INVERT_SUPPORTED
 539.659 +#  endif
 539.660 +#  ifndef PNG_NO_WRITE_FILLER
 539.661 +#    define PNG_WRITE_FILLER_SUPPORTED   /* same as WRITE_STRIP_ALPHA */
 539.662 +#  endif
 539.663 +#  ifndef PNG_NO_WRITE_SWAP_ALPHA
 539.664 +#    define PNG_WRITE_SWAP_ALPHA_SUPPORTED
 539.665 +#  endif
 539.666 +#  ifndef PNG_NO_WRITE_INVERT_ALPHA
 539.667 +#    define PNG_WRITE_INVERT_ALPHA_SUPPORTED
 539.668 +#  endif
 539.669 +#  ifndef PNG_NO_WRITE_USER_TRANSFORM
 539.670 +#    define PNG_WRITE_USER_TRANSFORM_SUPPORTED
 539.671 +#  endif
 539.672 +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
 539.673 +
 539.674 +#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \
 539.675 +    !defined(PNG_WRITE_INTERLACING_SUPPORTED)
 539.676 +#define PNG_WRITE_INTERLACING_SUPPORTED  /* not required for PNG-compliant
 539.677 +                                            encoders, but can cause trouble
 539.678 +                                            if left undefined */
 539.679 +#endif
 539.680 +
 539.681 +#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \
 539.682 +    !defined(PNG_WRITE_WEIGHTED_FILTER) && \
 539.683 +     defined(PNG_FLOATING_POINT_SUPPORTED)
 539.684 +#  define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
 539.685 +#endif
 539.686 +
 539.687 +#ifndef PNG_NO_WRITE_FLUSH
 539.688 +#  define PNG_WRITE_FLUSH_SUPPORTED
 539.689 +#endif
 539.690 +
 539.691 +#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
 539.692 +/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */
 539.693 +#ifndef PNG_NO_WRITE_EMPTY_PLTE
 539.694 +#  define PNG_WRITE_EMPTY_PLTE_SUPPORTED
 539.695 +#endif
 539.696 +#endif
 539.697 +
 539.698 +#endif /* PNG_WRITE_SUPPORTED */
 539.699 +
 539.700 +#ifndef PNG_1_0_X
 539.701 +#  ifndef PNG_NO_ERROR_NUMBERS
 539.702 +#    define PNG_ERROR_NUMBERS_SUPPORTED
 539.703 +#  endif
 539.704 +#endif /* PNG_1_0_X */
 539.705 +
 539.706 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
 539.707 +    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
 539.708 +#  ifndef PNG_NO_USER_TRANSFORM_PTR
 539.709 +#    define PNG_USER_TRANSFORM_PTR_SUPPORTED
 539.710 +#  endif
 539.711 +#endif
 539.712 +
 539.713 +#ifndef PNG_NO_STDIO
 539.714 +#  define PNG_TIME_RFC1123_SUPPORTED
 539.715 +#endif
 539.716 +
 539.717 +/* This adds extra functions in pngget.c for accessing data from the
 539.718 + * info pointer (added in version 0.99)
 539.719 + * png_get_image_width()
 539.720 + * png_get_image_height()
 539.721 + * png_get_bit_depth()
 539.722 + * png_get_color_type()
 539.723 + * png_get_compression_type()
 539.724 + * png_get_filter_type()
 539.725 + * png_get_interlace_type()
 539.726 + * png_get_pixel_aspect_ratio()
 539.727 + * png_get_pixels_per_meter()
 539.728 + * png_get_x_offset_pixels()
 539.729 + * png_get_y_offset_pixels()
 539.730 + * png_get_x_offset_microns()
 539.731 + * png_get_y_offset_microns()
 539.732 + */
 539.733 +#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED)
 539.734 +#  define PNG_EASY_ACCESS_SUPPORTED
 539.735 +#endif
 539.736 +
 539.737 +/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 
 539.738 + * and removed from version 1.2.20.  The following will be removed
 539.739 + * from libpng-1.4.0
 539.740 +*/
 539.741 +
 539.742 +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_OPTIMIZED_CODE)
 539.743 +#  ifndef PNG_OPTIMIZED_CODE_SUPPORTED
 539.744 +#    define PNG_OPTIMIZED_CODE_SUPPORTED
 539.745 +#  endif
 539.746 +#endif
 539.747 +
 539.748 +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE)
 539.749 +#  ifndef PNG_ASSEMBLER_CODE_SUPPORTED
 539.750 +#    define PNG_ASSEMBLER_CODE_SUPPORTED
 539.751 +#  endif
 539.752 +
 539.753 +#  if defined(__GNUC__) && defined(__x86_64__) && (__GNUC__ < 4)
 539.754 +     /* work around 64-bit gcc compiler bugs in gcc-3.x */
 539.755 +#    if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
 539.756 +#      define PNG_NO_MMX_CODE
 539.757 +#    endif
 539.758 +#  endif
 539.759 +
 539.760 +#  if defined(__APPLE__)
 539.761 +#    if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
 539.762 +#      define PNG_NO_MMX_CODE
 539.763 +#    endif
 539.764 +#  endif
 539.765 +
 539.766 +#  if (defined(__MWERKS__) && ((__MWERKS__ < 0x0900) || macintosh))
 539.767 +#    if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
 539.768 +#      define PNG_NO_MMX_CODE
 539.769 +#    endif
 539.770 +#  endif
 539.771 +
 539.772 +#  if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
 539.773 +#    define PNG_MMX_CODE_SUPPORTED
 539.774 +#  endif
 539.775 +
 539.776 +#endif
 539.777 +/* end of obsolete code to be removed from libpng-1.4.0 */
 539.778 +
 539.779 +#if !defined(PNG_1_0_X)
 539.780 +#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED)
 539.781 +#  define PNG_USER_MEM_SUPPORTED
 539.782 +#endif
 539.783 +#endif /* PNG_1_0_X */
 539.784 +
 539.785 +/* Added at libpng-1.2.6 */
 539.786 +#if !defined(PNG_1_0_X)
 539.787 +#ifndef PNG_SET_USER_LIMITS_SUPPORTED
 539.788 +#if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED)
 539.789 +#  define PNG_SET_USER_LIMITS_SUPPORTED
 539.790 +#endif
 539.791 +#endif
 539.792 +#endif /* PNG_1_0_X */
 539.793 +
 539.794 +/* Added at libpng-1.0.16 and 1.2.6.  To accept all valid PNGS no matter
 539.795 + * how large, set these limits to 0x7fffffffL
 539.796 + */
 539.797 +#ifndef PNG_USER_WIDTH_MAX
 539.798 +#  define PNG_USER_WIDTH_MAX 1000000L
 539.799 +#endif
 539.800 +#ifndef PNG_USER_HEIGHT_MAX
 539.801 +#  define PNG_USER_HEIGHT_MAX 1000000L
 539.802 +#endif
 539.803 +
 539.804 +/* These are currently experimental features, define them if you want */
 539.805 +
 539.806 +/* very little testing */
 539.807 +/*
 539.808 +#ifdef PNG_READ_SUPPORTED
 539.809 +#  ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
 539.810 +#    define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
 539.811 +#  endif
 539.812 +#endif
 539.813 +*/
 539.814 +
 539.815 +/* This is only for PowerPC big-endian and 680x0 systems */
 539.816 +/* some testing */
 539.817 +/*
 539.818 +#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
 539.819 +#  define PNG_READ_BIG_ENDIAN_SUPPORTED
 539.820 +#endif
 539.821 +*/
 539.822 +
 539.823 +/* Buggy compilers (e.g., gcc 2.7.2.2) need this */
 539.824 +/*
 539.825 +#define PNG_NO_POINTER_INDEXING
 539.826 +*/
 539.827 +
 539.828 +/* These functions are turned off by default, as they will be phased out. */
 539.829 +/*
 539.830 +#define  PNG_USELESS_TESTS_SUPPORTED
 539.831 +#define  PNG_CORRECT_PALETTE_SUPPORTED
 539.832 +*/
 539.833 +
 539.834 +/* Any chunks you are not interested in, you can undef here.  The
 539.835 + * ones that allocate memory may be expecially important (hIST,
 539.836 + * tEXt, zTXt, tRNS, pCAL).  Others will just save time and make png_info
 539.837 + * a bit smaller.
 539.838 + */
 539.839 +
 539.840 +#if defined(PNG_READ_SUPPORTED) && \
 539.841 +    !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
 539.842 +    !defined(PNG_NO_READ_ANCILLARY_CHUNKS)
 539.843 +#  define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
 539.844 +#endif
 539.845 +
 539.846 +#if defined(PNG_WRITE_SUPPORTED) && \
 539.847 +    !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
 539.848 +    !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS)
 539.849 +#  define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
 539.850 +#endif
 539.851 +
 539.852 +#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
 539.853 +
 539.854 +#ifdef PNG_NO_READ_TEXT
 539.855 +#  define PNG_NO_READ_iTXt
 539.856 +#  define PNG_NO_READ_tEXt
 539.857 +#  define PNG_NO_READ_zTXt
 539.858 +#endif
 539.859 +#ifndef PNG_NO_READ_bKGD
 539.860 +#  define PNG_READ_bKGD_SUPPORTED
 539.861 +#  define PNG_bKGD_SUPPORTED
 539.862 +#endif
 539.863 +#ifndef PNG_NO_READ_cHRM
 539.864 +#  define PNG_READ_cHRM_SUPPORTED
 539.865 +#  define PNG_cHRM_SUPPORTED
 539.866 +#endif
 539.867 +#ifndef PNG_NO_READ_gAMA
 539.868 +#  define PNG_READ_gAMA_SUPPORTED
 539.869 +#  define PNG_gAMA_SUPPORTED
 539.870 +#endif
 539.871 +#ifndef PNG_NO_READ_hIST
 539.872 +#  define PNG_READ_hIST_SUPPORTED
 539.873 +#  define PNG_hIST_SUPPORTED
 539.874 +#endif
 539.875 +#ifndef PNG_NO_READ_iCCP
 539.876 +#  define PNG_READ_iCCP_SUPPORTED
 539.877 +#  define PNG_iCCP_SUPPORTED
 539.878 +#endif
 539.879 +#ifndef PNG_NO_READ_iTXt
 539.880 +#  ifndef PNG_READ_iTXt_SUPPORTED
 539.881 +#    define PNG_READ_iTXt_SUPPORTED
 539.882 +#  endif
 539.883 +#  ifndef PNG_iTXt_SUPPORTED
 539.884 +#    define PNG_iTXt_SUPPORTED
 539.885 +#  endif
 539.886 +#endif
 539.887 +#ifndef PNG_NO_READ_oFFs
 539.888 +#  define PNG_READ_oFFs_SUPPORTED
 539.889 +#  define PNG_oFFs_SUPPORTED
 539.890 +#endif
 539.891 +#ifndef PNG_NO_READ_pCAL
 539.892 +#  define PNG_READ_pCAL_SUPPORTED
 539.893 +#  define PNG_pCAL_SUPPORTED
 539.894 +#endif
 539.895 +#ifndef PNG_NO_READ_sCAL
 539.896 +#  define PNG_READ_sCAL_SUPPORTED
 539.897 +#  define PNG_sCAL_SUPPORTED
 539.898 +#endif
 539.899 +#ifndef PNG_NO_READ_pHYs
 539.900 +#  define PNG_READ_pHYs_SUPPORTED
 539.901 +#  define PNG_pHYs_SUPPORTED
 539.902 +#endif
 539.903 +#ifndef PNG_NO_READ_sBIT
 539.904 +#  define PNG_READ_sBIT_SUPPORTED
 539.905 +#  define PNG_sBIT_SUPPORTED
 539.906 +#endif
 539.907 +#ifndef PNG_NO_READ_sPLT
 539.908 +#  define PNG_READ_sPLT_SUPPORTED
 539.909 +#  define PNG_sPLT_SUPPORTED
 539.910 +#endif
 539.911 +#ifndef PNG_NO_READ_sRGB
 539.912 +#  define PNG_READ_sRGB_SUPPORTED
 539.913 +#  define PNG_sRGB_SUPPORTED
 539.914 +#endif
 539.915 +#ifndef PNG_NO_READ_tEXt
 539.916 +#  define PNG_READ_tEXt_SUPPORTED
 539.917 +#  define PNG_tEXt_SUPPORTED
 539.918 +#endif
 539.919 +#ifndef PNG_NO_READ_tIME
 539.920 +#  define PNG_READ_tIME_SUPPORTED
 539.921 +#  define PNG_tIME_SUPPORTED
 539.922 +#endif
 539.923 +#ifndef PNG_NO_READ_tRNS
 539.924 +#  define PNG_READ_tRNS_SUPPORTED
 539.925 +#  define PNG_tRNS_SUPPORTED
 539.926 +#endif
 539.927 +#ifndef PNG_NO_READ_zTXt
 539.928 +#  define PNG_READ_zTXt_SUPPORTED
 539.929 +#  define PNG_zTXt_SUPPORTED
 539.930 +#endif
 539.931 +#ifndef PNG_NO_READ_UNKNOWN_CHUNKS
 539.932 +#  define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
 539.933 +#  ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
 539.934 +#    define PNG_UNKNOWN_CHUNKS_SUPPORTED
 539.935 +#  endif
 539.936 +#  ifndef PNG_NO_HANDLE_AS_UNKNOWN
 539.937 +#    define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 539.938 +#  endif
 539.939 +#endif
 539.940 +#if !defined(PNG_NO_READ_USER_CHUNKS) && \
 539.941 +     defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
 539.942 +#  define PNG_READ_USER_CHUNKS_SUPPORTED
 539.943 +#  define PNG_USER_CHUNKS_SUPPORTED
 539.944 +#  ifdef PNG_NO_READ_UNKNOWN_CHUNKS
 539.945 +#    undef PNG_NO_READ_UNKNOWN_CHUNKS
 539.946 +#  endif
 539.947 +#  ifdef PNG_NO_HANDLE_AS_UNKNOWN
 539.948 +#    undef PNG_NO_HANDLE_AS_UNKNOWN
 539.949 +#  endif
 539.950 +#endif
 539.951 +#ifndef PNG_NO_READ_OPT_PLTE
 539.952 +#  define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */
 539.953 +#endif                      /* optional PLTE chunk in RGB and RGBA images */
 539.954 +#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \
 539.955 +    defined(PNG_READ_zTXt_SUPPORTED)
 539.956 +#  define PNG_READ_TEXT_SUPPORTED
 539.957 +#  define PNG_TEXT_SUPPORTED
 539.958 +#endif
 539.959 +
 539.960 +#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
 539.961 +
 539.962 +#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
 539.963 +
 539.964 +#ifdef PNG_NO_WRITE_TEXT
 539.965 +#  define PNG_NO_WRITE_iTXt
 539.966 +#  define PNG_NO_WRITE_tEXt
 539.967 +#  define PNG_NO_WRITE_zTXt
 539.968 +#endif
 539.969 +#ifndef PNG_NO_WRITE_bKGD
 539.970 +#  define PNG_WRITE_bKGD_SUPPORTED
 539.971 +#  ifndef PNG_bKGD_SUPPORTED
 539.972 +#    define PNG_bKGD_SUPPORTED
 539.973 +#  endif
 539.974 +#endif
 539.975 +#ifndef PNG_NO_WRITE_cHRM
 539.976 +#  define PNG_WRITE_cHRM_SUPPORTED
 539.977 +#  ifndef PNG_cHRM_SUPPORTED
 539.978 +#    define PNG_cHRM_SUPPORTED
 539.979 +#  endif
 539.980 +#endif
 539.981 +#ifndef PNG_NO_WRITE_gAMA
 539.982 +#  define PNG_WRITE_gAMA_SUPPORTED
 539.983 +#  ifndef PNG_gAMA_SUPPORTED
 539.984 +#    define PNG_gAMA_SUPPORTED
 539.985 +#  endif
 539.986 +#endif
 539.987 +#ifndef PNG_NO_WRITE_hIST
 539.988 +#  define PNG_WRITE_hIST_SUPPORTED
 539.989 +#  ifndef PNG_hIST_SUPPORTED
 539.990 +#    define PNG_hIST_SUPPORTED
 539.991 +#  endif
 539.992 +#endif
 539.993 +#ifndef PNG_NO_WRITE_iCCP
 539.994 +#  define PNG_WRITE_iCCP_SUPPORTED
 539.995 +#  ifndef PNG_iCCP_SUPPORTED
 539.996 +#    define PNG_iCCP_SUPPORTED
 539.997 +#  endif
 539.998 +#endif
 539.999 +#ifndef PNG_NO_WRITE_iTXt
539.1000 +#  ifndef PNG_WRITE_iTXt_SUPPORTED
539.1001 +#    define PNG_WRITE_iTXt_SUPPORTED
539.1002 +#  endif
539.1003 +#  ifndef PNG_iTXt_SUPPORTED
539.1004 +#    define PNG_iTXt_SUPPORTED
539.1005 +#  endif
539.1006 +#endif
539.1007 +#ifndef PNG_NO_WRITE_oFFs
539.1008 +#  define PNG_WRITE_oFFs_SUPPORTED
539.1009 +#  ifndef PNG_oFFs_SUPPORTED
539.1010 +#    define PNG_oFFs_SUPPORTED
539.1011 +#  endif
539.1012 +#endif
539.1013 +#ifndef PNG_NO_WRITE_pCAL
539.1014 +#  define PNG_WRITE_pCAL_SUPPORTED
539.1015 +#  ifndef PNG_pCAL_SUPPORTED
539.1016 +#    define PNG_pCAL_SUPPORTED
539.1017 +#  endif
539.1018 +#endif
539.1019 +#ifndef PNG_NO_WRITE_sCAL
539.1020 +#  define PNG_WRITE_sCAL_SUPPORTED
539.1021 +#  ifndef PNG_sCAL_SUPPORTED
539.1022 +#    define PNG_sCAL_SUPPORTED
539.1023 +#  endif
539.1024 +#endif
539.1025 +#ifndef PNG_NO_WRITE_pHYs
539.1026 +#  define PNG_WRITE_pHYs_SUPPORTED
539.1027 +#  ifndef PNG_pHYs_SUPPORTED
539.1028 +#    define PNG_pHYs_SUPPORTED
539.1029 +#  endif
539.1030 +#endif
539.1031 +#ifndef PNG_NO_WRITE_sBIT
539.1032 +#  define PNG_WRITE_sBIT_SUPPORTED
539.1033 +#  ifndef PNG_sBIT_SUPPORTED
539.1034 +#    define PNG_sBIT_SUPPORTED
539.1035 +#  endif
539.1036 +#endif
539.1037 +#ifndef PNG_NO_WRITE_sPLT
539.1038 +#  define PNG_WRITE_sPLT_SUPPORTED
539.1039 +#  ifndef PNG_sPLT_SUPPORTED
539.1040 +#    define PNG_sPLT_SUPPORTED
539.1041 +#  endif
539.1042 +#endif
539.1043 +#ifndef PNG_NO_WRITE_sRGB
539.1044 +#  define PNG_WRITE_sRGB_SUPPORTED
539.1045 +#  ifndef PNG_sRGB_SUPPORTED
539.1046 +#    define PNG_sRGB_SUPPORTED
539.1047 +#  endif
539.1048 +#endif
539.1049 +#ifndef PNG_NO_WRITE_tEXt
539.1050 +#  define PNG_WRITE_tEXt_SUPPORTED
539.1051 +#  ifndef PNG_tEXt_SUPPORTED
539.1052 +#    define PNG_tEXt_SUPPORTED
539.1053 +#  endif
539.1054 +#endif
539.1055 +#ifndef PNG_NO_WRITE_tIME
539.1056 +#  define PNG_WRITE_tIME_SUPPORTED
539.1057 +#  ifndef PNG_tIME_SUPPORTED
539.1058 +#    define PNG_tIME_SUPPORTED
539.1059 +#  endif
539.1060 +#endif
539.1061 +#ifndef PNG_NO_WRITE_tRNS
539.1062 +#  define PNG_WRITE_tRNS_SUPPORTED
539.1063 +#  ifndef PNG_tRNS_SUPPORTED
539.1064 +#    define PNG_tRNS_SUPPORTED
539.1065 +#  endif
539.1066 +#endif
539.1067 +#ifndef PNG_NO_WRITE_zTXt
539.1068 +#  define PNG_WRITE_zTXt_SUPPORTED
539.1069 +#  ifndef PNG_zTXt_SUPPORTED
539.1070 +#    define PNG_zTXt_SUPPORTED
539.1071 +#  endif
539.1072 +#endif
539.1073 +#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS
539.1074 +#  define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
539.1075 +#  ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
539.1076 +#    define PNG_UNKNOWN_CHUNKS_SUPPORTED
539.1077 +#  endif
539.1078 +#  ifndef PNG_NO_HANDLE_AS_UNKNOWN
539.1079 +#     ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
539.1080 +#       define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
539.1081 +#     endif
539.1082 +#  endif
539.1083 +#endif
539.1084 +#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
539.1085 +    defined(PNG_WRITE_zTXt_SUPPORTED)
539.1086 +#  define PNG_WRITE_TEXT_SUPPORTED
539.1087 +#  ifndef PNG_TEXT_SUPPORTED
539.1088 +#    define PNG_TEXT_SUPPORTED
539.1089 +#  endif
539.1090 +#endif
539.1091 +
539.1092 +#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
539.1093 +
539.1094 +/* Turn this off to disable png_read_png() and
539.1095 + * png_write_png() and leave the row_pointers member
539.1096 + * out of the info structure.
539.1097 + */
539.1098 +#ifndef PNG_NO_INFO_IMAGE
539.1099 +#  define PNG_INFO_IMAGE_SUPPORTED
539.1100 +#endif
539.1101 +
539.1102 +/* need the time information for reading tIME chunks */
539.1103 +#if defined(PNG_tIME_SUPPORTED)
539.1104 +#  if !defined(_WIN32_WCE)
539.1105 +     /* "time.h" functions are not supported on WindowsCE */
539.1106 +#    include <time.h>
539.1107 +#  endif
539.1108 +#endif
539.1109 +
539.1110 +/* Some typedefs to get us started.  These should be safe on most of the
539.1111 + * common platforms.  The typedefs should be at least as large as the
539.1112 + * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
539.1113 + * don't have to be exactly that size.  Some compilers dislike passing
539.1114 + * unsigned shorts as function parameters, so you may be better off using
539.1115 + * unsigned int for png_uint_16.  Likewise, for 64-bit systems, you may
539.1116 + * want to have unsigned int for png_uint_32 instead of unsigned long.
539.1117 + */
539.1118 +
539.1119 +typedef unsigned long png_uint_32;
539.1120 +typedef long png_int_32;
539.1121 +typedef unsigned short png_uint_16;
539.1122 +typedef short png_int_16;
539.1123 +typedef unsigned char png_byte;
539.1124 +
539.1125 +/* This is usually size_t.  It is typedef'ed just in case you need it to
539.1126 +   change (I'm not sure if you will or not, so I thought I'd be safe) */
539.1127 +#ifdef PNG_SIZE_T
539.1128 +   typedef PNG_SIZE_T png_size_t;
539.1129 +#  define png_sizeof(x) png_convert_size(sizeof(x))
539.1130 +#else
539.1131 +   typedef size_t png_size_t;
539.1132 +#  define png_sizeof(x) sizeof(x)
539.1133 +#endif
539.1134 +
539.1135 +/* The following is needed for medium model support.  It cannot be in the
539.1136 + * PNG_INTERNAL section.  Needs modification for other compilers besides
539.1137 + * MSC.  Model independent support declares all arrays and pointers to be
539.1138 + * large using the far keyword.  The zlib version used must also support
539.1139 + * model independent data.  As of version zlib 1.0.4, the necessary changes
539.1140 + * have been made in zlib.  The USE_FAR_KEYWORD define triggers other
539.1141 + * changes that are needed. (Tim Wegner)
539.1142 + */
539.1143 +
539.1144 +/* Separate compiler dependencies (problem here is that zlib.h always
539.1145 +   defines FAR. (SJT) */
539.1146 +#ifdef __BORLANDC__
539.1147 +#  if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
539.1148 +#    define LDATA 1
539.1149 +#  else
539.1150 +#    define LDATA 0
539.1151 +#  endif
539.1152 +   /* GRR:  why is Cygwin in here?  Cygwin is not Borland C... */
539.1153 +#  if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
539.1154 +#    define PNG_MAX_MALLOC_64K
539.1155 +#    if (LDATA != 1)
539.1156 +#      ifndef FAR
539.1157 +#        define FAR __far
539.1158 +#      endif
539.1159 +#      define USE_FAR_KEYWORD
539.1160 +#    endif   /* LDATA != 1 */
539.1161 +     /* Possibly useful for moving data out of default segment.
539.1162 +      * Uncomment it if you want. Could also define FARDATA as
539.1163 +      * const if your compiler supports it. (SJT)
539.1164 +#    define FARDATA FAR
539.1165 +      */
539.1166 +#  endif  /* __WIN32__, __FLAT__, __CYGWIN__ */
539.1167 +#endif   /* __BORLANDC__ */
539.1168 +
539.1169 +
539.1170 +/* Suggest testing for specific compiler first before testing for
539.1171 + * FAR.  The Watcom compiler defines both __MEDIUM__ and M_I86MM,
539.1172 + * making reliance oncertain keywords suspect. (SJT)
539.1173 + */
539.1174 +
539.1175 +/* MSC Medium model */
539.1176 +#if defined(FAR)
539.1177 +#  if defined(M_I86MM)
539.1178 +#    define USE_FAR_KEYWORD
539.1179 +#    define FARDATA FAR
539.1180 +#    include <dos.h>
539.1181 +#  endif
539.1182 +#endif
539.1183 +
539.1184 +/* SJT: default case */
539.1185 +#ifndef FAR
539.1186 +#  define FAR
539.1187 +#endif
539.1188 +
539.1189 +/* At this point FAR is always defined */
539.1190 +#ifndef FARDATA
539.1191 +#  define FARDATA
539.1192 +#endif
539.1193 +
539.1194 +/* Typedef for floating-point numbers that are converted
539.1195 +   to fixed-point with a multiple of 100,000, e.g., int_gamma */
539.1196 +typedef png_int_32 png_fixed_point;
539.1197 +
539.1198 +/* Add typedefs for pointers */
539.1199 +typedef void            FAR * png_voidp;
539.1200 +typedef png_byte        FAR * png_bytep;
539.1201 +typedef png_uint_32     FAR * png_uint_32p;
539.1202 +typedef png_int_32      FAR * png_int_32p;
539.1203 +typedef png_uint_16     FAR * png_uint_16p;
539.1204 +typedef png_int_16      FAR * png_int_16p;
539.1205 +typedef PNG_CONST char  FAR * png_const_charp;
539.1206 +typedef char            FAR * png_charp;
539.1207 +typedef png_fixed_point FAR * png_fixed_point_p;
539.1208 +
539.1209 +#ifndef PNG_NO_STDIO
539.1210 +#if defined(_WIN32_WCE)
539.1211 +typedef HANDLE                png_FILE_p;
539.1212 +#else
539.1213 +typedef FILE                * png_FILE_p;
539.1214 +#endif
539.1215 +#endif
539.1216 +
539.1217 +#ifdef PNG_FLOATING_POINT_SUPPORTED
539.1218 +typedef double          FAR * png_doublep;
539.1219 +#endif
539.1220 +
539.1221 +/* Pointers to pointers; i.e. arrays */
539.1222 +typedef png_byte        FAR * FAR * png_bytepp;
539.1223 +typedef png_uint_32     FAR * FAR * png_uint_32pp;
539.1224 +typedef png_int_32      FAR * FAR * png_int_32pp;
539.1225 +typedef png_uint_16     FAR * FAR * png_uint_16pp;
539.1226 +typedef png_int_16      FAR * FAR * png_int_16pp;
539.1227 +typedef PNG_CONST char  FAR * FAR * png_const_charpp;
539.1228 +typedef char            FAR * FAR * png_charpp;
539.1229 +typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
539.1230 +#ifdef PNG_FLOATING_POINT_SUPPORTED
539.1231 +typedef double          FAR * FAR * png_doublepp;
539.1232 +#endif
539.1233 +
539.1234 +/* Pointers to pointers to pointers; i.e., pointer to array */
539.1235 +typedef char            FAR * FAR * FAR * png_charppp;
539.1236 +
539.1237 +#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
539.1238 +/* SPC -  Is this stuff deprecated? */
539.1239 +/* It'll be removed as of libpng-1.3.0 - GR-P */
539.1240 +/* libpng typedefs for types in zlib. If zlib changes
539.1241 + * or another compression library is used, then change these.
539.1242 + * Eliminates need to change all the source files.
539.1243 + */
539.1244 +typedef charf *         png_zcharp;
539.1245 +typedef charf * FAR *   png_zcharpp;
539.1246 +typedef z_stream FAR *  png_zstreamp;
539.1247 +#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */
539.1248 +
539.1249 +/*
539.1250 + * Define PNG_BUILD_DLL if the module being built is a Windows
539.1251 + * LIBPNG DLL.
539.1252 + *
539.1253 + * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL.
539.1254 + * It is equivalent to Microsoft predefined macro _DLL that is
539.1255 + * automatically defined when you compile using the share
539.1256 + * version of the CRT (C Run-Time library)
539.1257 + *
539.1258 + * The cygwin mods make this behavior a little different:
539.1259 + * Define PNG_BUILD_DLL if you are building a dll for use with cygwin
539.1260 + * Define PNG_STATIC if you are building a static library for use with cygwin,
539.1261 + *   -or- if you are building an application that you want to link to the
539.1262 + *   static library.
539.1263 + * PNG_USE_DLL is defined by default (no user action needed) unless one of
539.1264 + *   the other flags is defined.
539.1265 + */
539.1266 +
539.1267 +#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL))
539.1268 +#  define PNG_DLL
539.1269 +#endif
539.1270 +/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib.
539.1271 + * When building a static lib, default to no GLOBAL ARRAYS, but allow
539.1272 + * command-line override
539.1273 + */
539.1274 +#if defined(__CYGWIN__)
539.1275 +#  if !defined(PNG_STATIC)
539.1276 +#    if defined(PNG_USE_GLOBAL_ARRAYS)
539.1277 +#      undef PNG_USE_GLOBAL_ARRAYS
539.1278 +#    endif
539.1279 +#    if !defined(PNG_USE_LOCAL_ARRAYS)
539.1280 +#      define PNG_USE_LOCAL_ARRAYS
539.1281 +#    endif
539.1282 +#  else
539.1283 +#    if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS)
539.1284 +#      if defined(PNG_USE_GLOBAL_ARRAYS)
539.1285 +#        undef PNG_USE_GLOBAL_ARRAYS
539.1286 +#      endif
539.1287 +#    endif
539.1288 +#  endif
539.1289 +#  if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
539.1290 +#    define PNG_USE_LOCAL_ARRAYS
539.1291 +#  endif
539.1292 +#endif
539.1293 +
539.1294 +/* Do not use global arrays (helps with building DLL's)
539.1295 + * They are no longer used in libpng itself, since version 1.0.5c,
539.1296 + * but might be required for some pre-1.0.5c applications.
539.1297 + */
539.1298 +#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
539.1299 +#  if defined(PNG_NO_GLOBAL_ARRAYS) || \
539.1300 +      (defined(__GNUC__) && defined(PNG_DLL)) || defined(_MSC_VER)
539.1301 +#    define PNG_USE_LOCAL_ARRAYS
539.1302 +#  else
539.1303 +#    define PNG_USE_GLOBAL_ARRAYS
539.1304 +#  endif
539.1305 +#endif
539.1306 +
539.1307 +#if defined(__CYGWIN__)
539.1308 +#  undef PNGAPI
539.1309 +#  define PNGAPI __cdecl
539.1310 +#  undef PNG_IMPEXP
539.1311 +#  define PNG_IMPEXP
539.1312 +#endif  
539.1313 +
539.1314 +/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall",
539.1315 + * you may get warnings regarding the linkage of png_zalloc and png_zfree.
539.1316 + * Don't ignore those warnings; you must also reset the default calling
539.1317 + * convention in your compiler to match your PNGAPI, and you must build
539.1318 + * zlib and your applications the same way you build libpng.
539.1319 + */
539.1320 +
539.1321 +#if defined(__MINGW32__) && !defined(PNG_MODULEDEF)
539.1322 +#  ifndef PNG_NO_MODULEDEF
539.1323 +#    define PNG_NO_MODULEDEF
539.1324 +#  endif
539.1325 +#endif
539.1326 +
539.1327 +#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF)
539.1328 +#  define PNG_IMPEXP
539.1329 +#endif
539.1330 +
539.1331 +#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \
539.1332 +    (( defined(_Windows) || defined(_WINDOWS) || \
539.1333 +       defined(WIN32) || defined(_WIN32) || defined(__WIN32__) ))
539.1334 +
539.1335 +#  ifndef PNGAPI
539.1336 +#     if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
539.1337 +#        define PNGAPI __cdecl
539.1338 +#     else
539.1339 +#        define PNGAPI _cdecl
539.1340 +#     endif
539.1341 +#  endif
539.1342 +
539.1343 +#  if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \
539.1344 +       0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)
539.1345 +#     define PNG_IMPEXP
539.1346 +#  endif
539.1347 +
539.1348 +#  if !defined(PNG_IMPEXP)
539.1349 +
539.1350 +#     define PNG_EXPORT_TYPE1(type,symbol)  PNG_IMPEXP type PNGAPI symbol
539.1351 +#     define PNG_EXPORT_TYPE2(type,symbol)  type PNG_IMPEXP PNGAPI symbol
539.1352 +
539.1353 +      /* Borland/Microsoft */
539.1354 +#     if defined(_MSC_VER) || defined(__BORLANDC__)
539.1355 +#        if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500)
539.1356 +#           define PNG_EXPORT PNG_EXPORT_TYPE1
539.1357 +#        else
539.1358 +#           define PNG_EXPORT PNG_EXPORT_TYPE2
539.1359 +#           if defined(PNG_BUILD_DLL)
539.1360 +#              define PNG_IMPEXP __export
539.1361 +#           else
539.1362 +#              define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in
539.1363 +                                                 VC++ */
539.1364 +#           endif                             /* Exists in Borland C++ for
539.1365 +                                                 C++ classes (== huge) */
539.1366 +#        endif
539.1367 +#     endif
539.1368 +
539.1369 +#     if !defined(PNG_IMPEXP)
539.1370 +#        if defined(PNG_BUILD_DLL)
539.1371 +#           define PNG_IMPEXP __declspec(dllexport)
539.1372 +#        else
539.1373 +#           define PNG_IMPEXP __declspec(dllimport)
539.1374 +#        endif
539.1375 +#     endif
539.1376 +#  endif  /* PNG_IMPEXP */
539.1377 +#else /* !(DLL || non-cygwin WINDOWS) */
539.1378 +#   if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
539.1379 +#      ifndef PNGAPI
539.1380 +#         define PNGAPI _System
539.1381 +#      endif
539.1382 +#   else
539.1383 +#      if 0 /* ... other platforms, with other meanings */
539.1384 +#      endif
539.1385 +#   endif
539.1386 +#endif
539.1387 +
539.1388 +#ifndef PNGAPI
539.1389 +#  define PNGAPI
539.1390 +#endif
539.1391 +#ifndef PNG_IMPEXP
539.1392 +#  define PNG_IMPEXP
539.1393 +#endif
539.1394 +
539.1395 +#ifdef PNG_BUILDSYMS
539.1396 +#  ifndef PNG_EXPORT
539.1397 +#    define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END
539.1398 +#  endif
539.1399 +#  ifdef PNG_USE_GLOBAL_ARRAYS
539.1400 +#    ifndef PNG_EXPORT_VAR
539.1401 +#      define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT
539.1402 +#    endif
539.1403 +#  endif
539.1404 +#endif
539.1405 +
539.1406 +#ifndef PNG_EXPORT
539.1407 +#  define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
539.1408 +#endif
539.1409 +
539.1410 +#ifdef PNG_USE_GLOBAL_ARRAYS
539.1411 +#  ifndef PNG_EXPORT_VAR
539.1412 +#    define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type
539.1413 +#  endif
539.1414 +#endif
539.1415 +
539.1416 +/* User may want to use these so they are not in PNG_INTERNAL. Any library
539.1417 + * functions that are passed far data must be model independent.
539.1418 + */
539.1419 +
539.1420 +#ifndef PNG_ABORT
539.1421 +#  define PNG_ABORT() abort()
539.1422 +#endif
539.1423 +
539.1424 +#ifdef PNG_SETJMP_SUPPORTED
539.1425 +#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
539.1426 +#else
539.1427 +#  define png_jmpbuf(png_ptr) \
539.1428 +   (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED)
539.1429 +#endif
539.1430 +
539.1431 +#if defined(USE_FAR_KEYWORD)  /* memory model independent fns */
539.1432 +/* use this to make far-to-near assignments */
539.1433 +#  define CHECK   1
539.1434 +#  define NOCHECK 0
539.1435 +#  define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
539.1436 +#  define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
539.1437 +#  define png_snprintf _fsnprintf   /* Added to v 1.2.19 */
539.1438 +#  define png_strlen  _fstrlen
539.1439 +#  define png_memcmp  _fmemcmp    /* SJT: added */
539.1440 +#  define png_memcpy  _fmemcpy
539.1441 +#  define png_memset  _fmemset
539.1442 +#else /* use the usual functions */
539.1443 +#  define CVT_PTR(ptr)         (ptr)
539.1444 +#  define CVT_PTR_NOCHECK(ptr) (ptr)
539.1445 +#  ifndef PNG_NO_SNPRINTF
539.1446 +#    ifdef _MSC_VER
539.1447 +#      define png_snprintf _snprintf   /* Added to v 1.2.19 */
539.1448 +#      define png_snprintf2 _snprintf
539.1449 +#      define png_snprintf6 _snprintf
539.1450 +#    else
539.1451 +#      define png_snprintf snprintf   /* Added to v 1.2.19 */
539.1452 +#      define png_snprintf2 snprintf
539.1453 +#      define png_snprintf6 snprintf
539.1454 +#    endif
539.1455 +#  else
539.1456 +     /* You don't have or don't want to use snprintf().  Caution: Using
539.1457 +      * sprintf instead of snprintf exposes your application to accidental
539.1458 +      * or malevolent buffer overflows.  If you don't have snprintf()
539.1459 +      * as a general rule you should provide one (you can get one from
539.1460 +      * Portable OpenSSH). */
539.1461 +#    define png_snprintf(s1,n,fmt,x1) sprintf(s1,fmt,x1)
539.1462 +#    define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2)
539.1463 +#    define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \
539.1464 +        sprintf(s1,fmt,x1,x2,x3,x4,x5,x6)
539.1465 +#  endif
539.1466 +#  define png_strlen  strlen
539.1467 +#  define png_memcmp  memcmp      /* SJT: added */
539.1468 +#  define png_memcpy  memcpy
539.1469 +#  define png_memset  memset
539.1470 +#endif
539.1471 +/* End of memory model independent support */
539.1472 +
539.1473 +/* Just a little check that someone hasn't tried to define something
539.1474 + * contradictory.
539.1475 + */
539.1476 +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
539.1477 +#  undef PNG_ZBUF_SIZE
539.1478 +#  define PNG_ZBUF_SIZE 65536L
539.1479 +#endif
539.1480 +
539.1481 +/* Added at libpng-1.2.8 */
539.1482 +#endif /* PNG_VERSION_INFO_ONLY */
539.1483 +
539.1484 +#endif /* PNGCONF_H */
   540.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   540.2 +++ b/libs/libpng/pngerror.c	Sat Feb 01 19:58:19 2014 +0200
   540.3 @@ -0,0 +1,345 @@
   540.4 +
   540.5 +/* pngerror.c - stub functions for i/o and memory allocation
   540.6 + *
   540.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   540.8 + * For conditions of distribution and use, see copyright notice in png.h
   540.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  540.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  540.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  540.12 + *
  540.13 + * This file provides a location for all error handling.  Users who
  540.14 + * need special error handling are expected to write replacement functions
  540.15 + * and use png_set_error_fn() to use those functions.  See the instructions
  540.16 + * at each function.
  540.17 + */
  540.18 +
  540.19 +#define PNG_INTERNAL
  540.20 +#include "png.h"
  540.21 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  540.22 +
  540.23 +static void /* PRIVATE */
  540.24 +png_default_error PNGARG((png_structp png_ptr,
  540.25 +  png_const_charp error_message));
  540.26 +#ifndef PNG_NO_WARNINGS
  540.27 +static void /* PRIVATE */
  540.28 +png_default_warning PNGARG((png_structp png_ptr,
  540.29 +  png_const_charp warning_message));
  540.30 +#endif /* PNG_NO_WARNINGS */
  540.31 +
  540.32 +/* This function is called whenever there is a fatal error.  This function
  540.33 + * should not be changed.  If there is a need to handle errors differently,
  540.34 + * you should supply a replacement error function and use png_set_error_fn()
  540.35 + * to replace the error function at run-time.
  540.36 + */
  540.37 +#ifndef PNG_NO_ERROR_TEXT
  540.38 +void PNGAPI
  540.39 +png_error(png_structp png_ptr, png_const_charp error_message)
  540.40 +{
  540.41 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
  540.42 +   char msg[16];
  540.43 +   if (png_ptr != NULL)
  540.44 +   {
  540.45 +     if (png_ptr->flags&
  540.46 +       (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
  540.47 +     {
  540.48 +       if (*error_message == '#')
  540.49 +       {
  540.50 +         /* Strip "#nnnn " from beginning of error message. */
  540.51 +           int offset;
  540.52 +           for (offset = 1; offset<15; offset++)
  540.53 +              if (error_message[offset] == ' ')
  540.54 +                  break;
  540.55 +           if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
  540.56 +           {
  540.57 +              int i;
  540.58 +              for (i = 0; i < offset - 1; i++)
  540.59 +                 msg[i] = error_message[i + 1];
  540.60 +              msg[i - 1] = '\0';
  540.61 +              error_message = msg;
  540.62 +           }
  540.63 +           else
  540.64 +              error_message += offset;
  540.65 +       }
  540.66 +       else
  540.67 +       {
  540.68 +           if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
  540.69 +           {
  540.70 +              msg[0] = '0';
  540.71 +              msg[1] = '\0';
  540.72 +              error_message = msg;
  540.73 +           }
  540.74 +       }
  540.75 +     }
  540.76 +   }
  540.77 +#endif
  540.78 +   if (png_ptr != NULL && png_ptr->error_fn != NULL)
  540.79 +      (*(png_ptr->error_fn))(png_ptr, error_message);
  540.80 +
  540.81 +   /* If the custom handler doesn't exist, or if it returns,
  540.82 +      use the default handler, which will not return. */
  540.83 +   png_default_error(png_ptr, error_message);
  540.84 +}
  540.85 +#else
  540.86 +void PNGAPI
  540.87 +png_err(png_structp png_ptr)
  540.88 +{
  540.89 +   if (png_ptr != NULL && png_ptr->error_fn != NULL)
  540.90 +      (*(png_ptr->error_fn))(png_ptr, '\0');
  540.91 +
  540.92 +   /* If the custom handler doesn't exist, or if it returns,
  540.93 +      use the default handler, which will not return. */
  540.94 +   png_default_error(png_ptr, '\0');
  540.95 +}
  540.96 +#endif /* PNG_NO_ERROR_TEXT */
  540.97 +
  540.98 +#ifndef PNG_NO_WARNINGS
  540.99 +/* This function is called whenever there is a non-fatal error.  This function
 540.100 + * should not be changed.  If there is a need to handle warnings differently,
 540.101 + * you should supply a replacement warning function and use
 540.102 + * png_set_error_fn() to replace the warning function at run-time.
 540.103 + */
 540.104 +void PNGAPI
 540.105 +png_warning(png_structp png_ptr, png_const_charp warning_message)
 540.106 +{
 540.107 +   int offset = 0;
 540.108 +   if (png_ptr != NULL)
 540.109 +   {
 540.110 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
 540.111 +   if (png_ptr->flags&
 540.112 +     (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
 540.113 +#endif
 540.114 +     {
 540.115 +       if (*warning_message == '#')
 540.116 +       {
 540.117 +           for (offset = 1; offset < 15; offset++)
 540.118 +              if (warning_message[offset] == ' ')
 540.119 +                  break;
 540.120 +       }
 540.121 +     }
 540.122 +     if (png_ptr != NULL && png_ptr->warning_fn != NULL)
 540.123 +        (*(png_ptr->warning_fn))(png_ptr, warning_message + offset);
 540.124 +   }
 540.125 +   else
 540.126 +      png_default_warning(png_ptr, warning_message + offset);
 540.127 +}
 540.128 +#endif /* PNG_NO_WARNINGS */
 540.129 +
 540.130 +
 540.131 +/* These utilities are used internally to build an error message that relates
 540.132 + * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
 540.133 + * this is used to prefix the message.  The message is limited in length
 540.134 + * to 63 bytes, the name characters are output as hex digits wrapped in []
 540.135 + * if the character is invalid.
 540.136 + */
 540.137 +#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
 540.138 +static PNG_CONST char png_digit[16] = {
 540.139 +   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 540.140 +   'A', 'B', 'C', 'D', 'E', 'F'
 540.141 +};
 540.142 +
 540.143 +#define PNG_MAX_ERROR_TEXT 64
 540.144 +
 540.145 +#if !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT)
 540.146 +static void /* PRIVATE */
 540.147 +png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
 540.148 +   error_message)
 540.149 +{
 540.150 +   int iout = 0, iin = 0;
 540.151 +
 540.152 +   while (iin < 4)
 540.153 +   {
 540.154 +      int c = png_ptr->chunk_name[iin++];
 540.155 +      if (isnonalpha(c))
 540.156 +      {
 540.157 +         buffer[iout++] = '[';
 540.158 +         buffer[iout++] = png_digit[(c & 0xf0) >> 4];
 540.159 +         buffer[iout++] = png_digit[c & 0x0f];
 540.160 +         buffer[iout++] = ']';
 540.161 +      }
 540.162 +      else
 540.163 +      {
 540.164 +         buffer[iout++] = (png_byte)c;
 540.165 +      }
 540.166 +   }
 540.167 +
 540.168 +   if (error_message == NULL)
 540.169 +      buffer[iout] = '\0';
 540.170 +   else
 540.171 +   {
 540.172 +      buffer[iout++] = ':';
 540.173 +      buffer[iout++] = ' ';
 540.174 +      png_memcpy(buffer + iout, error_message, PNG_MAX_ERROR_TEXT);
 540.175 +      buffer[iout + PNG_MAX_ERROR_TEXT - 1] = '\0';
 540.176 +   }
 540.177 +}
 540.178 +
 540.179 +#ifdef PNG_READ_SUPPORTED
 540.180 +void PNGAPI
 540.181 +png_chunk_error(png_structp png_ptr, png_const_charp error_message)
 540.182 +{
 540.183 +   char msg[18+PNG_MAX_ERROR_TEXT];
 540.184 +   if (png_ptr == NULL)
 540.185 +     png_error(png_ptr, error_message);
 540.186 +   else
 540.187 +   {
 540.188 +     png_format_buffer(png_ptr, msg, error_message);
 540.189 +     png_error(png_ptr, msg);
 540.190 +   }
 540.191 +}
 540.192 +#endif /* PNG_READ_SUPPORTED */
 540.193 +#endif /* !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT) */
 540.194 +
 540.195 +#ifndef PNG_NO_WARNINGS
 540.196 +void PNGAPI
 540.197 +png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
 540.198 +{
 540.199 +   char msg[18+PNG_MAX_ERROR_TEXT];
 540.200 +   if (png_ptr == NULL)
 540.201 +     png_warning(png_ptr, warning_message);
 540.202 +   else
 540.203 +   {
 540.204 +     png_format_buffer(png_ptr, msg, warning_message);
 540.205 +     png_warning(png_ptr, msg);
 540.206 +   }
 540.207 +}
 540.208 +#endif /* PNG_NO_WARNINGS */
 540.209 +
 540.210 +
 540.211 +/* This is the default error handling function.  Note that replacements for
 540.212 + * this function MUST NOT RETURN, or the program will likely crash.  This
 540.213 + * function is used by default, or if the program supplies NULL for the
 540.214 + * error function pointer in png_set_error_fn().
 540.215 + */
 540.216 +static void /* PRIVATE */
 540.217 +png_default_error(png_structp png_ptr, png_const_charp error_message)
 540.218 +{
 540.219 +#ifndef PNG_NO_CONSOLE_IO
 540.220 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
 540.221 +   if (*error_message == '#')
 540.222 +   {
 540.223 +     /* Strip "#nnnn " from beginning of warning message. */
 540.224 +     int offset;
 540.225 +     char error_number[16];
 540.226 +     for (offset = 0; offset<15; offset++)
 540.227 +     {
 540.228 +         error_number[offset] = error_message[offset + 1];
 540.229 +         if (error_message[offset] == ' ')
 540.230 +             break;
 540.231 +     }
 540.232 +     if ((offset > 1) && (offset < 15))
 540.233 +     {
 540.234 +       error_number[offset - 1] = '\0';
 540.235 +       fprintf(stderr, "libpng error no. %s: %s\n", error_number,
 540.236 +          error_message + offset + 1);
 540.237 +     }
 540.238 +     else
 540.239 +       fprintf(stderr, "libpng error: %s, offset=%d\n", error_message, offset);
 540.240 +   }
 540.241 +   else
 540.242 +#endif
 540.243 +   fprintf(stderr, "libpng error: %s\n", error_message);
 540.244 +#endif
 540.245 +
 540.246 +#ifdef PNG_SETJMP_SUPPORTED
 540.247 +   if (png_ptr)
 540.248 +   {
 540.249 +#  ifdef USE_FAR_KEYWORD
 540.250 +   {
 540.251 +      jmp_buf jmpbuf;
 540.252 +      png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
 540.253 +      longjmp(jmpbuf, 1);
 540.254 +   }
 540.255 +#  else
 540.256 +   longjmp(png_ptr->jmpbuf, 1);
 540.257 +#  endif
 540.258 +   }
 540.259 +#else
 540.260 +   PNG_ABORT();
 540.261 +#endif
 540.262 +#ifdef PNG_NO_CONSOLE_IO
 540.263 +   error_message = error_message; /* make compiler happy */
 540.264 +#endif
 540.265 +}
 540.266 +
 540.267 +#ifndef PNG_NO_WARNINGS
 540.268 +/* This function is called when there is a warning, but the library thinks
 540.269 + * it can continue anyway.  Replacement functions don't have to do anything
 540.270 + * here if you don't want them to.  In the default configuration, png_ptr is
 540.271 + * not used, but it is passed in case it may be useful.
 540.272 + */
 540.273 +static void /* PRIVATE */
 540.274 +png_default_warning(png_structp png_ptr, png_const_charp warning_message)
 540.275 +{
 540.276 +#ifndef PNG_NO_CONSOLE_IO
 540.277 +#  ifdef PNG_ERROR_NUMBERS_SUPPORTED
 540.278 +   if (*warning_message == '#')
 540.279 +   {
 540.280 +     int offset;
 540.281 +     char warning_number[16];
 540.282 +     for (offset = 0; offset < 15; offset++)
 540.283 +     {
 540.284 +        warning_number[offset] = warning_message[offset + 1];
 540.285 +        if (warning_message[offset] == ' ')
 540.286 +            break;
 540.287 +     }
 540.288 +     if ((offset > 1) && (offset < 15))
 540.289 +     {
 540.290 +       warning_number[offset + 1] = '\0';
 540.291 +       fprintf(stderr, "libpng warning no. %s: %s\n", warning_number,
 540.292 +          warning_message + offset);
 540.293 +     }
 540.294 +     else
 540.295 +       fprintf(stderr, "libpng warning: %s\n", warning_message);
 540.296 +   }
 540.297 +   else
 540.298 +#  endif
 540.299 +     fprintf(stderr, "libpng warning: %s\n", warning_message);
 540.300 +#else
 540.301 +   warning_message = warning_message; /* make compiler happy */
 540.302 +#endif
 540.303 +   png_ptr = png_ptr; /* make compiler happy */
 540.304 +}
 540.305 +#endif /* PNG_NO_WARNINGS */
 540.306 +
 540.307 +/* This function is called when the application wants to use another method
 540.308 + * of handling errors and warnings.  Note that the error function MUST NOT
 540.309 + * return to the calling routine or serious problems will occur.  The return
 540.310 + * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
 540.311 + */
 540.312 +void PNGAPI
 540.313 +png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
 540.314 +   png_error_ptr error_fn, png_error_ptr warning_fn)
 540.315 +{
 540.316 +   if (png_ptr == NULL)
 540.317 +      return;
 540.318 +   png_ptr->error_ptr = error_ptr;
 540.319 +   png_ptr->error_fn = error_fn;
 540.320 +   png_ptr->warning_fn = warning_fn;
 540.321 +}
 540.322 +
 540.323 +
 540.324 +/* This function returns a pointer to the error_ptr associated with the user
 540.325 + * functions.  The application should free any memory associated with this
 540.326 + * pointer before png_write_destroy and png_read_destroy are called.
 540.327 + */
 540.328 +png_voidp PNGAPI
 540.329 +png_get_error_ptr(png_structp png_ptr)
 540.330 +{
 540.331 +   if (png_ptr == NULL)
 540.332 +      return NULL;
 540.333 +   return ((png_voidp)png_ptr->error_ptr);
 540.334 +}
 540.335 +
 540.336 +
 540.337 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
 540.338 +void PNGAPI
 540.339 +png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
 540.340 +{
 540.341 +   if (png_ptr != NULL)
 540.342 +   {
 540.343 +     png_ptr->flags &=
 540.344 +       ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
 540.345 +   }
 540.346 +}
 540.347 +#endif
 540.348 +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
   541.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   541.2 +++ b/libs/libpng/pnggccrd.c	Sat Feb 01 19:58:19 2014 +0200
   541.3 @@ -0,0 +1,103 @@
   541.4 +/* pnggccrd.c was removed from libpng-1.2.20. */
   541.5 +
   541.6 +/* This code snippet is for use by configure's compilation test. */
   541.7 +
   541.8 +#if (!defined _MSC_VER) && \
   541.9 +    defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
  541.10 +    defined(PNG_MMX_CODE_SUPPORTED)
  541.11 +
  541.12 +int PNGAPI png_dummy_mmx_support(void);
  541.13 +
  541.14 +static int _mmx_supported = 2; // 0: no MMX; 1: MMX supported; 2: not tested
  541.15 +
  541.16 +int PNGAPI
  541.17 +png_dummy_mmx_support(void) __attribute__((noinline));
  541.18 +
  541.19 +int PNGAPI
  541.20 +png_dummy_mmx_support(void)
  541.21 +{
  541.22 +   int result;
  541.23 +#if defined(PNG_MMX_CODE_SUPPORTED)  // superfluous, but what the heck
  541.24 +    __asm__ __volatile__ (
  541.25 +#if defined(__x86_64__)
  541.26 +        "pushq %%rbx          \n\t"  // rbx gets clobbered by CPUID instruction
  541.27 +        "pushq %%rcx          \n\t"  // so does rcx...
  541.28 +        "pushq %%rdx          \n\t"  // ...and rdx (but rcx & rdx safe on Linux)
  541.29 +        "pushfq               \n\t"  // save Eflag to stack
  541.30 +        "popq %%rax           \n\t"  // get Eflag from stack into rax
  541.31 +        "movq %%rax, %%rcx    \n\t"  // make another copy of Eflag in rcx
  541.32 +        "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
  541.33 +        "pushq %%rax          \n\t"  // save modified Eflag back to stack
  541.34 +        "popfq                \n\t"  // restore modified value to Eflag reg
  541.35 +        "pushfq               \n\t"  // save Eflag to stack
  541.36 +        "popq %%rax           \n\t"  // get Eflag from stack
  541.37 +        "pushq %%rcx          \n\t"  // save original Eflag to stack
  541.38 +        "popfq                \n\t"  // restore original Eflag
  541.39 +#else
  541.40 +        "pushl %%ebx          \n\t"  // ebx gets clobbered by CPUID instruction
  541.41 +        "pushl %%ecx          \n\t"  // so does ecx...
  541.42 +        "pushl %%edx          \n\t"  // ...and edx (but ecx & edx safe on Linux)
  541.43 +        "pushfl               \n\t"  // save Eflag to stack
  541.44 +        "popl %%eax           \n\t"  // get Eflag from stack into eax
  541.45 +        "movl %%eax, %%ecx    \n\t"  // make another copy of Eflag in ecx
  541.46 +        "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
  541.47 +        "pushl %%eax          \n\t"  // save modified Eflag back to stack
  541.48 +        "popfl                \n\t"  // restore modified value to Eflag reg
  541.49 +        "pushfl               \n\t"  // save Eflag to stack
  541.50 +        "popl %%eax           \n\t"  // get Eflag from stack
  541.51 +        "pushl %%ecx          \n\t"  // save original Eflag to stack
  541.52 +        "popfl                \n\t"  // restore original Eflag
  541.53 +#endif
  541.54 +        "xorl %%ecx, %%eax    \n\t"  // compare new Eflag with original Eflag
  541.55 +        "jz 0f                \n\t"  // if same, CPUID instr. is not supported
  541.56 +
  541.57 +        "xorl %%eax, %%eax    \n\t"  // set eax to zero
  541.58 +//      ".byte  0x0f, 0xa2    \n\t"  // CPUID instruction (two-byte opcode)
  541.59 +        "cpuid                \n\t"  // get the CPU identification info
  541.60 +        "cmpl $1, %%eax       \n\t"  // make sure eax return non-zero value
  541.61 +        "jl 0f                \n\t"  // if eax is zero, MMX is not supported
  541.62 +
  541.63 +        "xorl %%eax, %%eax    \n\t"  // set eax to zero and...
  541.64 +        "incl %%eax           \n\t"  // ...increment eax to 1.  This pair is
  541.65 +                                     // faster than the instruction "mov eax, 1"
  541.66 +        "cpuid                \n\t"  // get the CPU identification info again
  541.67 +        "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23)
  541.68 +        "cmpl $0, %%edx       \n\t"  // 0 = MMX not supported
  541.69 +        "jz 0f                \n\t"  // non-zero = yes, MMX IS supported
  541.70 +
  541.71 +        "movl $1, %%eax       \n\t"  // set return value to 1
  541.72 +        "jmp  1f              \n\t"  // DONE:  have MMX support
  541.73 +
  541.74 +    "0:                       \n\t"  // .NOT_SUPPORTED: target label for jump instructions
  541.75 +        "movl $0, %%eax       \n\t"  // set return value to 0
  541.76 +    "1:                       \n\t"  // .RETURN: target label for jump instructions
  541.77 +#if defined(__x86_64__)
  541.78 +        "popq %%rdx           \n\t"  // restore rdx
  541.79 +        "popq %%rcx           \n\t"  // restore rcx
  541.80 +        "popq %%rbx           \n\t"  // restore rbx
  541.81 +#else
  541.82 +        "popl %%edx           \n\t"  // restore edx
  541.83 +        "popl %%ecx           \n\t"  // restore ecx
  541.84 +        "popl %%ebx           \n\t"  // restore ebx
  541.85 +#endif
  541.86 +
  541.87 +//      "ret                  \n\t"  // DONE:  no MMX support
  541.88 +                                     // (fall through to standard C "ret")
  541.89 +
  541.90 +        : "=a" (result)              // output list
  541.91 +
  541.92 +        :                            // any variables used on input (none)
  541.93 +
  541.94 +                                     // no clobber list
  541.95 +//      , "%ebx", "%ecx", "%edx"     // GRR:  we handle these manually
  541.96 +//      , "memory"   // if write to a variable gcc thought was in a reg
  541.97 +//      , "cc"       // "condition codes" (flag bits)
  541.98 +    );
  541.99 +    _mmx_supported = result;
 541.100 +#else
 541.101 +    _mmx_supported = 0;
 541.102 +#endif /* PNG_MMX_CODE_SUPPORTED */
 541.103 +
 541.104 +    return _mmx_supported;
 541.105 +}
 541.106 +#endif
   542.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   542.2 +++ b/libs/libpng/pngget.c	Sat Feb 01 19:58:19 2014 +0200
   542.3 @@ -0,0 +1,900 @@
   542.4 +
   542.5 +/* pngget.c - retrieval of values from info struct
   542.6 + *
   542.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   542.8 + * For conditions of distribution and use, see copyright notice in png.h
   542.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  542.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  542.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  542.12 + */
  542.13 +
  542.14 +#define PNG_INTERNAL
  542.15 +#include "png.h"
  542.16 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  542.17 +
  542.18 +png_uint_32 PNGAPI
  542.19 +png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
  542.20 +{
  542.21 +   if (png_ptr != NULL && info_ptr != NULL)
  542.22 +      return(info_ptr->valid & flag);
  542.23 +   else
  542.24 +      return(0);
  542.25 +}
  542.26 +
  542.27 +png_uint_32 PNGAPI
  542.28 +png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
  542.29 +{
  542.30 +   if (png_ptr != NULL && info_ptr != NULL)
  542.31 +      return(info_ptr->rowbytes);
  542.32 +   else
  542.33 +      return(0);
  542.34 +}
  542.35 +
  542.36 +#if defined(PNG_INFO_IMAGE_SUPPORTED)
  542.37 +png_bytepp PNGAPI
  542.38 +png_get_rows(png_structp png_ptr, png_infop info_ptr)
  542.39 +{
  542.40 +   if (png_ptr != NULL && info_ptr != NULL)
  542.41 +      return(info_ptr->row_pointers);
  542.42 +   else
  542.43 +      return(0);
  542.44 +}
  542.45 +#endif
  542.46 +
  542.47 +#ifdef PNG_EASY_ACCESS_SUPPORTED
  542.48 +/* easy access to info, added in libpng-0.99 */
  542.49 +png_uint_32 PNGAPI
  542.50 +png_get_image_width(png_structp png_ptr, png_infop info_ptr)
  542.51 +{
  542.52 +   if (png_ptr != NULL && info_ptr != NULL)
  542.53 +   {
  542.54 +      return info_ptr->width;
  542.55 +   }
  542.56 +   return (0);
  542.57 +}
  542.58 +
  542.59 +png_uint_32 PNGAPI
  542.60 +png_get_image_height(png_structp png_ptr, png_infop info_ptr)
  542.61 +{
  542.62 +   if (png_ptr != NULL && info_ptr != NULL)
  542.63 +   {
  542.64 +      return info_ptr->height;
  542.65 +   }
  542.66 +   return (0);
  542.67 +}
  542.68 +
  542.69 +png_byte PNGAPI
  542.70 +png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
  542.71 +{
  542.72 +   if (png_ptr != NULL && info_ptr != NULL)
  542.73 +   {
  542.74 +      return info_ptr->bit_depth;
  542.75 +   }
  542.76 +   return (0);
  542.77 +}
  542.78 +
  542.79 +png_byte PNGAPI
  542.80 +png_get_color_type(png_structp png_ptr, png_infop info_ptr)
  542.81 +{
  542.82 +   if (png_ptr != NULL && info_ptr != NULL)
  542.83 +   {
  542.84 +      return info_ptr->color_type;
  542.85 +   }
  542.86 +   return (0);
  542.87 +}
  542.88 +
  542.89 +png_byte PNGAPI
  542.90 +png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
  542.91 +{
  542.92 +   if (png_ptr != NULL && info_ptr != NULL)
  542.93 +   {
  542.94 +      return info_ptr->filter_type;
  542.95 +   }
  542.96 +   return (0);
  542.97 +}
  542.98 +
  542.99 +png_byte PNGAPI
 542.100 +png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
 542.101 +{
 542.102 +   if (png_ptr != NULL && info_ptr != NULL)
 542.103 +   {
 542.104 +      return info_ptr->interlace_type;
 542.105 +   }
 542.106 +   return (0);
 542.107 +}
 542.108 +
 542.109 +png_byte PNGAPI
 542.110 +png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
 542.111 +{
 542.112 +   if (png_ptr != NULL && info_ptr != NULL)
 542.113 +   {
 542.114 +      return info_ptr->compression_type;
 542.115 +   }
 542.116 +   return (0);
 542.117 +}
 542.118 +
 542.119 +png_uint_32 PNGAPI
 542.120 +png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 542.121 +{
 542.122 +   if (png_ptr != NULL && info_ptr != NULL)
 542.123 +#if defined(PNG_pHYs_SUPPORTED)
 542.124 +   if (info_ptr->valid & PNG_INFO_pHYs)
 542.125 +   {
 542.126 +      png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
 542.127 +      if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
 542.128 +          return (0);
 542.129 +      else return (info_ptr->x_pixels_per_unit);
 542.130 +   }
 542.131 +#else
 542.132 +   return (0);
 542.133 +#endif
 542.134 +   return (0);
 542.135 +}
 542.136 +
 542.137 +png_uint_32 PNGAPI
 542.138 +png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 542.139 +{
 542.140 +   if (png_ptr != NULL && info_ptr != NULL)
 542.141 +#if defined(PNG_pHYs_SUPPORTED)
 542.142 +   if (info_ptr->valid & PNG_INFO_pHYs)
 542.143 +   {
 542.144 +      png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
 542.145 +      if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
 542.146 +          return (0);
 542.147 +      else return (info_ptr->y_pixels_per_unit);
 542.148 +   }
 542.149 +#else
 542.150 +   return (0);
 542.151 +#endif
 542.152 +   return (0);
 542.153 +}
 542.154 +
 542.155 +png_uint_32 PNGAPI
 542.156 +png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 542.157 +{
 542.158 +   if (png_ptr != NULL && info_ptr != NULL)
 542.159 +#if defined(PNG_pHYs_SUPPORTED)
 542.160 +   if (info_ptr->valid & PNG_INFO_pHYs)
 542.161 +   {
 542.162 +      png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
 542.163 +      if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
 542.164 +         info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
 542.165 +          return (0);
 542.166 +      else return (info_ptr->x_pixels_per_unit);
 542.167 +   }
 542.168 +#else
 542.169 +   return (0);
 542.170 +#endif
 542.171 +   return (0);
 542.172 +}
 542.173 +
 542.174 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 542.175 +float PNGAPI
 542.176 +png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
 542.177 +   {
 542.178 +   if (png_ptr != NULL && info_ptr != NULL)
 542.179 +#if defined(PNG_pHYs_SUPPORTED)
 542.180 +   if (info_ptr->valid & PNG_INFO_pHYs)
 542.181 +   {
 542.182 +      png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
 542.183 +      if (info_ptr->x_pixels_per_unit == 0)
 542.184 +         return ((float)0.0);
 542.185 +      else
 542.186 +         return ((float)((float)info_ptr->y_pixels_per_unit
 542.187 +            /(float)info_ptr->x_pixels_per_unit));
 542.188 +   }
 542.189 +#else
 542.190 +   return (0.0);
 542.191 +#endif
 542.192 +   return ((float)0.0);
 542.193 +}
 542.194 +#endif
 542.195 +
 542.196 +png_int_32 PNGAPI
 542.197 +png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
 542.198 +{
 542.199 +   if (png_ptr != NULL && info_ptr != NULL)
 542.200 +#if defined(PNG_oFFs_SUPPORTED)
 542.201 +   if (info_ptr->valid & PNG_INFO_oFFs)
 542.202 +   {
 542.203 +      png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
 542.204 +      if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
 542.205 +          return (0);
 542.206 +      else return (info_ptr->x_offset);
 542.207 +   }
 542.208 +#else
 542.209 +   return (0);
 542.210 +#endif
 542.211 +   return (0);
 542.212 +}
 542.213 +
 542.214 +png_int_32 PNGAPI
 542.215 +png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
 542.216 +{
 542.217 +   if (png_ptr != NULL && info_ptr != NULL)
 542.218 +#if defined(PNG_oFFs_SUPPORTED)
 542.219 +   if (info_ptr->valid & PNG_INFO_oFFs)
 542.220 +   {
 542.221 +      png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
 542.222 +      if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
 542.223 +          return (0);
 542.224 +      else return (info_ptr->y_offset);
 542.225 +   }
 542.226 +#else
 542.227 +   return (0);
 542.228 +#endif
 542.229 +   return (0);
 542.230 +}
 542.231 +
 542.232 +png_int_32 PNGAPI
 542.233 +png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
 542.234 +{
 542.235 +   if (png_ptr != NULL && info_ptr != NULL)
 542.236 +#if defined(PNG_oFFs_SUPPORTED)
 542.237 +   if (info_ptr->valid & PNG_INFO_oFFs)
 542.238 +   {
 542.239 +      png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
 542.240 +      if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
 542.241 +          return (0);
 542.242 +      else return (info_ptr->x_offset);
 542.243 +   }
 542.244 +#else
 542.245 +   return (0);
 542.246 +#endif
 542.247 +   return (0);
 542.248 +}
 542.249 +
 542.250 +png_int_32 PNGAPI
 542.251 +png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
 542.252 +{
 542.253 +   if (png_ptr != NULL && info_ptr != NULL)
 542.254 +#if defined(PNG_oFFs_SUPPORTED)
 542.255 +   if (info_ptr->valid & PNG_INFO_oFFs)
 542.256 +   {
 542.257 +      png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
 542.258 +      if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
 542.259 +          return (0);
 542.260 +      else return (info_ptr->y_offset);
 542.261 +   }
 542.262 +#else
 542.263 +   return (0);
 542.264 +#endif
 542.265 +   return (0);
 542.266 +}
 542.267 +
 542.268 +#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
 542.269 +png_uint_32 PNGAPI
 542.270 +png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
 542.271 +{
 542.272 +   return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
 542.273 +     *.0254 +.5));
 542.274 +}
 542.275 +
 542.276 +png_uint_32 PNGAPI
 542.277 +png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
 542.278 +{
 542.279 +   return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
 542.280 +     *.0254 +.5));
 542.281 +}
 542.282 +
 542.283 +png_uint_32 PNGAPI
 542.284 +png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
 542.285 +{
 542.286 +   return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
 542.287 +     *.0254 +.5));
 542.288 +}
 542.289 +
 542.290 +float PNGAPI
 542.291 +png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
 542.292 +{
 542.293 +   return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
 542.294 +     *.00003937);
 542.295 +}
 542.296 +
 542.297 +float PNGAPI
 542.298 +png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
 542.299 +{
 542.300 +   return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
 542.301 +     *.00003937);
 542.302 +}
 542.303 +
 542.304 +#if defined(PNG_pHYs_SUPPORTED)
 542.305 +png_uint_32 PNGAPI
 542.306 +png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
 542.307 +   png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
 542.308 +{
 542.309 +   png_uint_32 retval = 0;
 542.310 +
 542.311 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
 542.312 +   {
 542.313 +      png_debug1(1, "in %s retrieval function\n", "pHYs");
 542.314 +      if (res_x != NULL)
 542.315 +      {
 542.316 +         *res_x = info_ptr->x_pixels_per_unit;
 542.317 +         retval |= PNG_INFO_pHYs;
 542.318 +      }
 542.319 +      if (res_y != NULL)
 542.320 +      {
 542.321 +         *res_y = info_ptr->y_pixels_per_unit;
 542.322 +         retval |= PNG_INFO_pHYs;
 542.323 +      }
 542.324 +      if (unit_type != NULL)
 542.325 +      {
 542.326 +         *unit_type = (int)info_ptr->phys_unit_type;
 542.327 +         retval |= PNG_INFO_pHYs;
 542.328 +         if (*unit_type == 1)
 542.329 +         {
 542.330 +            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
 542.331 +            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
 542.332 +         }
 542.333 +      }
 542.334 +   }
 542.335 +   return (retval);
 542.336 +}
 542.337 +#endif /* PNG_pHYs_SUPPORTED */
 542.338 +#endif  /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
 542.339 +
 542.340 +/* png_get_channels really belongs in here, too, but it's been around longer */
 542.341 +
 542.342 +#endif  /* PNG_EASY_ACCESS_SUPPORTED */
 542.343 +
 542.344 +png_byte PNGAPI
 542.345 +png_get_channels(png_structp png_ptr, png_infop info_ptr)
 542.346 +{
 542.347 +   if (png_ptr != NULL && info_ptr != NULL)
 542.348 +      return(info_ptr->channels);
 542.349 +   else
 542.350 +      return (0);
 542.351 +}
 542.352 +
 542.353 +png_bytep PNGAPI
 542.354 +png_get_signature(png_structp png_ptr, png_infop info_ptr)
 542.355 +{
 542.356 +   if (png_ptr != NULL && info_ptr != NULL)
 542.357 +      return(info_ptr->signature);
 542.358 +   else
 542.359 +      return (NULL);
 542.360 +}
 542.361 +
 542.362 +#if defined(PNG_bKGD_SUPPORTED)
 542.363 +png_uint_32 PNGAPI
 542.364 +png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
 542.365 +   png_color_16p *background)
 542.366 +{
 542.367 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
 542.368 +      && background != NULL)
 542.369 +   {
 542.370 +      png_debug1(1, "in %s retrieval function\n", "bKGD");
 542.371 +      *background = &(info_ptr->background);
 542.372 +      return (PNG_INFO_bKGD);
 542.373 +   }
 542.374 +   return (0);
 542.375 +}
 542.376 +#endif
 542.377 +
 542.378 +#if defined(PNG_cHRM_SUPPORTED)
 542.379 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 542.380 +png_uint_32 PNGAPI
 542.381 +png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
 542.382 +   double *white_x, double *white_y, double *red_x, double *red_y,
 542.383 +   double *green_x, double *green_y, double *blue_x, double *blue_y)
 542.384 +{
 542.385 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
 542.386 +   {
 542.387 +      png_debug1(1, "in %s retrieval function\n", "cHRM");
 542.388 +      if (white_x != NULL)
 542.389 +         *white_x = (double)info_ptr->x_white;
 542.390 +      if (white_y != NULL)
 542.391 +         *white_y = (double)info_ptr->y_white;
 542.392 +      if (red_x != NULL)
 542.393 +         *red_x = (double)info_ptr->x_red;
 542.394 +      if (red_y != NULL)
 542.395 +         *red_y = (double)info_ptr->y_red;
 542.396 +      if (green_x != NULL)
 542.397 +         *green_x = (double)info_ptr->x_green;
 542.398 +      if (green_y != NULL)
 542.399 +         *green_y = (double)info_ptr->y_green;
 542.400 +      if (blue_x != NULL)
 542.401 +         *blue_x = (double)info_ptr->x_blue;
 542.402 +      if (blue_y != NULL)
 542.403 +         *blue_y = (double)info_ptr->y_blue;
 542.404 +      return (PNG_INFO_cHRM);
 542.405 +   }
 542.406 +   return (0);
 542.407 +}
 542.408 +#endif
 542.409 +#ifdef PNG_FIXED_POINT_SUPPORTED
 542.410 +png_uint_32 PNGAPI
 542.411 +png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
 542.412 +   png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
 542.413 +   png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
 542.414 +   png_fixed_point *blue_x, png_fixed_point *blue_y)
 542.415 +{
 542.416 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
 542.417 +   {
 542.418 +      png_debug1(1, "in %s retrieval function\n", "cHRM");
 542.419 +      if (white_x != NULL)
 542.420 +         *white_x = info_ptr->int_x_white;
 542.421 +      if (white_y != NULL)
 542.422 +         *white_y = info_ptr->int_y_white;
 542.423 +      if (red_x != NULL)
 542.424 +         *red_x = info_ptr->int_x_red;
 542.425 +      if (red_y != NULL)
 542.426 +         *red_y = info_ptr->int_y_red;
 542.427 +      if (green_x != NULL)
 542.428 +         *green_x = info_ptr->int_x_green;
 542.429 +      if (green_y != NULL)
 542.430 +         *green_y = info_ptr->int_y_green;
 542.431 +      if (blue_x != NULL)
 542.432 +         *blue_x = info_ptr->int_x_blue;
 542.433 +      if (blue_y != NULL)
 542.434 +         *blue_y = info_ptr->int_y_blue;
 542.435 +      return (PNG_INFO_cHRM);
 542.436 +   }
 542.437 +   return (0);
 542.438 +}
 542.439 +#endif
 542.440 +#endif
 542.441 +
 542.442 +#if defined(PNG_gAMA_SUPPORTED)
 542.443 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 542.444 +png_uint_32 PNGAPI
 542.445 +png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
 542.446 +{
 542.447 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
 542.448 +      && file_gamma != NULL)
 542.449 +   {
 542.450 +      png_debug1(1, "in %s retrieval function\n", "gAMA");
 542.451 +      *file_gamma = (double)info_ptr->gamma;
 542.452 +      return (PNG_INFO_gAMA);
 542.453 +   }
 542.454 +   return (0);
 542.455 +}
 542.456 +#endif
 542.457 +#ifdef PNG_FIXED_POINT_SUPPORTED
 542.458 +png_uint_32 PNGAPI
 542.459 +png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
 542.460 +    png_fixed_point *int_file_gamma)
 542.461 +{
 542.462 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
 542.463 +      && int_file_gamma != NULL)
 542.464 +   {
 542.465 +      png_debug1(1, "in %s retrieval function\n", "gAMA");
 542.466 +      *int_file_gamma = info_ptr->int_gamma;
 542.467 +      return (PNG_INFO_gAMA);
 542.468 +   }
 542.469 +   return (0);
 542.470 +}
 542.471 +#endif
 542.472 +#endif
 542.473 +
 542.474 +#if defined(PNG_sRGB_SUPPORTED)
 542.475 +png_uint_32 PNGAPI
 542.476 +png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
 542.477 +{
 542.478 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
 542.479 +      && file_srgb_intent != NULL)
 542.480 +   {
 542.481 +      png_debug1(1, "in %s retrieval function\n", "sRGB");
 542.482 +      *file_srgb_intent = (int)info_ptr->srgb_intent;
 542.483 +      return (PNG_INFO_sRGB);
 542.484 +   }
 542.485 +   return (0);
 542.486 +}
 542.487 +#endif
 542.488 +
 542.489 +#if defined(PNG_iCCP_SUPPORTED)
 542.490 +png_uint_32 PNGAPI
 542.491 +png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
 542.492 +             png_charpp name, int *compression_type,
 542.493 +             png_charpp profile, png_uint_32 *proflen)
 542.494 +{
 542.495 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
 542.496 +      && name != NULL && profile != NULL && proflen != NULL)
 542.497 +   {
 542.498 +      png_debug1(1, "in %s retrieval function\n", "iCCP");
 542.499 +      *name = info_ptr->iccp_name;
 542.500 +      *profile = info_ptr->iccp_profile;
 542.501 +      /* compression_type is a dummy so the API won't have to change
 542.502 +         if we introduce multiple compression types later. */
 542.503 +      *proflen = (int)info_ptr->iccp_proflen;
 542.504 +      *compression_type = (int)info_ptr->iccp_compression;
 542.505 +      return (PNG_INFO_iCCP);
 542.506 +   }
 542.507 +   return (0);
 542.508 +}
 542.509 +#endif
 542.510 +
 542.511 +#if defined(PNG_sPLT_SUPPORTED)
 542.512 +png_uint_32 PNGAPI
 542.513 +png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
 542.514 +             png_sPLT_tpp spalettes)
 542.515 +{
 542.516 +   if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
 542.517 +   {
 542.518 +     *spalettes = info_ptr->splt_palettes;
 542.519 +     return ((png_uint_32)info_ptr->splt_palettes_num);
 542.520 +   }
 542.521 +   return (0);
 542.522 +}
 542.523 +#endif
 542.524 +
 542.525 +#if defined(PNG_hIST_SUPPORTED)
 542.526 +png_uint_32 PNGAPI
 542.527 +png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
 542.528 +{
 542.529 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
 542.530 +      && hist != NULL)
 542.531 +   {
 542.532 +      png_debug1(1, "in %s retrieval function\n", "hIST");
 542.533 +      *hist = info_ptr->hist;
 542.534 +      return (PNG_INFO_hIST);
 542.535 +   }
 542.536 +   return (0);
 542.537 +}
 542.538 +#endif
 542.539 +
 542.540 +png_uint_32 PNGAPI
 542.541 +png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
 542.542 +   png_uint_32 *width, png_uint_32 *height, int *bit_depth,
 542.543 +   int *color_type, int *interlace_type, int *compression_type,
 542.544 +   int *filter_type)
 542.545 +
 542.546 +{
 542.547 +   if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
 542.548 +      bit_depth != NULL && color_type != NULL)
 542.549 +   {
 542.550 +      png_debug1(1, "in %s retrieval function\n", "IHDR");
 542.551 +      *width = info_ptr->width;
 542.552 +      *height = info_ptr->height;
 542.553 +      *bit_depth = info_ptr->bit_depth;
 542.554 +      if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16)
 542.555 +        png_error(png_ptr, "Invalid bit depth");
 542.556 +      *color_type = info_ptr->color_type;
 542.557 +      if (info_ptr->color_type > 6)
 542.558 +        png_error(png_ptr, "Invalid color type");
 542.559 +      if (compression_type != NULL)
 542.560 +         *compression_type = info_ptr->compression_type;
 542.561 +      if (filter_type != NULL)
 542.562 +         *filter_type = info_ptr->filter_type;
 542.563 +      if (interlace_type != NULL)
 542.564 +         *interlace_type = info_ptr->interlace_type;
 542.565 +
 542.566 +      /* check for potential overflow of rowbytes */
 542.567 +      if (*width == 0 || *width > PNG_UINT_31_MAX)
 542.568 +        png_error(png_ptr, "Invalid image width");
 542.569 +      if (*height == 0 || *height > PNG_UINT_31_MAX)
 542.570 +        png_error(png_ptr, "Invalid image height");
 542.571 +      if (info_ptr->width > (PNG_UINT_32_MAX
 542.572 +                 >> 3)      /* 8-byte RGBA pixels */
 542.573 +                 - 64       /* bigrowbuf hack */
 542.574 +                 - 1        /* filter byte */
 542.575 +                 - 7*8      /* rounding of width to multiple of 8 pixels */
 542.576 +                 - 8)       /* extra max_pixel_depth pad */
 542.577 +      {
 542.578 +         png_warning(png_ptr,
 542.579 +            "Width too large for libpng to process image data.");
 542.580 +      }
 542.581 +      return (1);
 542.582 +   }
 542.583 +   return (0);
 542.584 +}
 542.585 +
 542.586 +#if defined(PNG_oFFs_SUPPORTED)
 542.587 +png_uint_32 PNGAPI
 542.588 +png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
 542.589 +   png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
 542.590 +{
 542.591 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
 542.592 +      && offset_x != NULL && offset_y != NULL && unit_type != NULL)
 542.593 +   {
 542.594 +      png_debug1(1, "in %s retrieval function\n", "oFFs");
 542.595 +      *offset_x = info_ptr->x_offset;
 542.596 +      *offset_y = info_ptr->y_offset;
 542.597 +      *unit_type = (int)info_ptr->offset_unit_type;
 542.598 +      return (PNG_INFO_oFFs);
 542.599 +   }
 542.600 +   return (0);
 542.601 +}
 542.602 +#endif
 542.603 +
 542.604 +#if defined(PNG_pCAL_SUPPORTED)
 542.605 +png_uint_32 PNGAPI
 542.606 +png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
 542.607 +   png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
 542.608 +   png_charp *units, png_charpp *params)
 542.609 +{
 542.610 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
 542.611 +      && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
 542.612 +      nparams != NULL && units != NULL && params != NULL)
 542.613 +   {
 542.614 +      png_debug1(1, "in %s retrieval function\n", "pCAL");
 542.615 +      *purpose = info_ptr->pcal_purpose;
 542.616 +      *X0 = info_ptr->pcal_X0;
 542.617 +      *X1 = info_ptr->pcal_X1;
 542.618 +      *type = (int)info_ptr->pcal_type;
 542.619 +      *nparams = (int)info_ptr->pcal_nparams;
 542.620 +      *units = info_ptr->pcal_units;
 542.621 +      *params = info_ptr->pcal_params;
 542.622 +      return (PNG_INFO_pCAL);
 542.623 +   }
 542.624 +   return (0);
 542.625 +}
 542.626 +#endif
 542.627 +
 542.628 +#if defined(PNG_sCAL_SUPPORTED)
 542.629 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 542.630 +png_uint_32 PNGAPI
 542.631 +png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
 542.632 +             int *unit, double *width, double *height)
 542.633 +{
 542.634 +    if (png_ptr != NULL && info_ptr != NULL &&
 542.635 +       (info_ptr->valid & PNG_INFO_sCAL))
 542.636 +    {
 542.637 +        *unit = info_ptr->scal_unit;
 542.638 +        *width = info_ptr->scal_pixel_width;
 542.639 +        *height = info_ptr->scal_pixel_height;
 542.640 +        return (PNG_INFO_sCAL);
 542.641 +    }
 542.642 +    return(0);
 542.643 +}
 542.644 +#else
 542.645 +#ifdef PNG_FIXED_POINT_SUPPORTED
 542.646 +png_uint_32 PNGAPI
 542.647 +png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
 542.648 +             int *unit, png_charpp width, png_charpp height)
 542.649 +{
 542.650 +    if (png_ptr != NULL && info_ptr != NULL &&
 542.651 +       (info_ptr->valid & PNG_INFO_sCAL))
 542.652 +    {
 542.653 +        *unit = info_ptr->scal_unit;
 542.654 +        *width = info_ptr->scal_s_width;
 542.655 +        *height = info_ptr->scal_s_height;
 542.656 +        return (PNG_INFO_sCAL);
 542.657 +    }
 542.658 +    return(0);
 542.659 +}
 542.660 +#endif
 542.661 +#endif
 542.662 +#endif
 542.663 +
 542.664 +#if defined(PNG_pHYs_SUPPORTED)
 542.665 +png_uint_32 PNGAPI
 542.666 +png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
 542.667 +   png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
 542.668 +{
 542.669 +   png_uint_32 retval = 0;
 542.670 +
 542.671 +   if (png_ptr != NULL && info_ptr != NULL &&
 542.672 +      (info_ptr->valid & PNG_INFO_pHYs))
 542.673 +   {
 542.674 +      png_debug1(1, "in %s retrieval function\n", "pHYs");
 542.675 +      if (res_x != NULL)
 542.676 +      {
 542.677 +         *res_x = info_ptr->x_pixels_per_unit;
 542.678 +         retval |= PNG_INFO_pHYs;
 542.679 +      }
 542.680 +      if (res_y != NULL)
 542.681 +      {
 542.682 +         *res_y = info_ptr->y_pixels_per_unit;
 542.683 +         retval |= PNG_INFO_pHYs;
 542.684 +      }
 542.685 +      if (unit_type != NULL)
 542.686 +      {
 542.687 +         *unit_type = (int)info_ptr->phys_unit_type;
 542.688 +         retval |= PNG_INFO_pHYs;
 542.689 +      }
 542.690 +   }
 542.691 +   return (retval);
 542.692 +}
 542.693 +#endif
 542.694 +
 542.695 +png_uint_32 PNGAPI
 542.696 +png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
 542.697 +   int *num_palette)
 542.698 +{
 542.699 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
 542.700 +       && palette != NULL)
 542.701 +   {
 542.702 +      png_debug1(1, "in %s retrieval function\n", "PLTE");
 542.703 +      *palette = info_ptr->palette;
 542.704 +      *num_palette = info_ptr->num_palette;
 542.705 +      png_debug1(3, "num_palette = %d\n", *num_palette);
 542.706 +      return (PNG_INFO_PLTE);
 542.707 +   }
 542.708 +   return (0);
 542.709 +}
 542.710 +
 542.711 +#if defined(PNG_sBIT_SUPPORTED)
 542.712 +png_uint_32 PNGAPI
 542.713 +png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
 542.714 +{
 542.715 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
 542.716 +      && sig_bit != NULL)
 542.717 +   {
 542.718 +      png_debug1(1, "in %s retrieval function\n", "sBIT");
 542.719 +      *sig_bit = &(info_ptr->sig_bit);
 542.720 +      return (PNG_INFO_sBIT);
 542.721 +   }
 542.722 +   return (0);
 542.723 +}
 542.724 +#endif
 542.725 +
 542.726 +#if defined(PNG_TEXT_SUPPORTED)
 542.727 +png_uint_32 PNGAPI
 542.728 +png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
 542.729 +   int *num_text)
 542.730 +{
 542.731 +   if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
 542.732 +   {
 542.733 +      png_debug1(1, "in %s retrieval function\n",
 542.734 +         (png_ptr->chunk_name[0] == '\0' ? "text"
 542.735 +             : (png_const_charp)png_ptr->chunk_name));
 542.736 +      if (text_ptr != NULL)
 542.737 +         *text_ptr = info_ptr->text;
 542.738 +      if (num_text != NULL)
 542.739 +         *num_text = info_ptr->num_text;
 542.740 +      return ((png_uint_32)info_ptr->num_text);
 542.741 +   }
 542.742 +   if (num_text != NULL)
 542.743 +     *num_text = 0;
 542.744 +   return(0);
 542.745 +}
 542.746 +#endif
 542.747 +
 542.748 +#if defined(PNG_tIME_SUPPORTED)
 542.749 +png_uint_32 PNGAPI
 542.750 +png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
 542.751 +{
 542.752 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
 542.753 +       && mod_time != NULL)
 542.754 +   {
 542.755 +      png_debug1(1, "in %s retrieval function\n", "tIME");
 542.756 +      *mod_time = &(info_ptr->mod_time);
 542.757 +      return (PNG_INFO_tIME);
 542.758 +   }
 542.759 +   return (0);
 542.760 +}
 542.761 +#endif
 542.762 +
 542.763 +#if defined(PNG_tRNS_SUPPORTED)
 542.764 +png_uint_32 PNGAPI
 542.765 +png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
 542.766 +   png_bytep *trans, int *num_trans, png_color_16p *trans_values)
 542.767 +{
 542.768 +   png_uint_32 retval = 0;
 542.769 +   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
 542.770 +   {
 542.771 +      png_debug1(1, "in %s retrieval function\n", "tRNS");
 542.772 +      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 542.773 +      {
 542.774 +          if (trans != NULL)
 542.775 +          {
 542.776 +             *trans = info_ptr->trans;
 542.777 +             retval |= PNG_INFO_tRNS;
 542.778 +          }
 542.779 +          if (trans_values != NULL)
 542.780 +             *trans_values = &(info_ptr->trans_values);
 542.781 +      }
 542.782 +      else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
 542.783 +      {
 542.784 +          if (trans_values != NULL)
 542.785 +          {
 542.786 +             *trans_values = &(info_ptr->trans_values);
 542.787 +             retval |= PNG_INFO_tRNS;
 542.788 +          }
 542.789 +          if (trans != NULL)
 542.790 +             *trans = NULL;
 542.791 +      }
 542.792 +      if (num_trans != NULL)
 542.793 +      {
 542.794 +         *num_trans = info_ptr->num_trans;
 542.795 +         retval |= PNG_INFO_tRNS;
 542.796 +      }
 542.797 +   }
 542.798 +   return (retval);
 542.799 +}
 542.800 +#endif
 542.801 +
 542.802 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
 542.803 +png_uint_32 PNGAPI
 542.804 +png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
 542.805 +             png_unknown_chunkpp unknowns)
 542.806 +{
 542.807 +   if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
 542.808 +   {
 542.809 +     *unknowns = info_ptr->unknown_chunks;
 542.810 +     return ((png_uint_32)info_ptr->unknown_chunks_num);
 542.811 +   }
 542.812 +   return (0);
 542.813 +}
 542.814 +#endif
 542.815 +
 542.816 +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
 542.817 +png_byte PNGAPI
 542.818 +png_get_rgb_to_gray_status (png_structp png_ptr)
 542.819 +{
 542.820 +   return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
 542.821 +}
 542.822 +#endif
 542.823 +
 542.824 +#if defined(PNG_USER_CHUNKS_SUPPORTED)
 542.825 +png_voidp PNGAPI
 542.826 +png_get_user_chunk_ptr(png_structp png_ptr)
 542.827 +{
 542.828 +   return (png_ptr? png_ptr->user_chunk_ptr : NULL);
 542.829 +}
 542.830 +#endif
 542.831 +
 542.832 +#ifdef PNG_WRITE_SUPPORTED
 542.833 +png_uint_32 PNGAPI
 542.834 +png_get_compression_buffer_size(png_structp png_ptr)
 542.835 +{
 542.836 +   return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
 542.837 +}
 542.838 +#endif
 542.839 +
 542.840 +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
 542.841 +#ifndef PNG_1_0_X
 542.842 +/* this function was added to libpng 1.2.0 and should exist by default */
 542.843 +png_uint_32 PNGAPI
 542.844 +png_get_asm_flags (png_structp png_ptr)
 542.845 +{
 542.846 +    /* obsolete, to be removed from libpng-1.4.0 */
 542.847 +    return (png_ptr? 0L: 0L);
 542.848 +}
 542.849 +
 542.850 +/* this function was added to libpng 1.2.0 and should exist by default */
 542.851 +png_uint_32 PNGAPI
 542.852 +png_get_asm_flagmask (int flag_select)
 542.853 +{
 542.854 +    /* obsolete, to be removed from libpng-1.4.0 */
 542.855 +    flag_select=flag_select;
 542.856 +    return 0L;
 542.857 +}
 542.858 +
 542.859 +    /* GRR:  could add this:   && defined(PNG_MMX_CODE_SUPPORTED) */
 542.860 +/* this function was added to libpng 1.2.0 */
 542.861 +png_uint_32 PNGAPI
 542.862 +png_get_mmx_flagmask (int flag_select, int *compilerID)
 542.863 +{
 542.864 +    /* obsolete, to be removed from libpng-1.4.0 */
 542.865 +    flag_select=flag_select;
 542.866 +    *compilerID = -1;   /* unknown (i.e., no asm/MMX code compiled) */
 542.867 +    return 0L;
 542.868 +}
 542.869 +
 542.870 +/* this function was added to libpng 1.2.0 */
 542.871 +png_byte PNGAPI
 542.872 +png_get_mmx_bitdepth_threshold (png_structp png_ptr)
 542.873 +{
 542.874 +    /* obsolete, to be removed from libpng-1.4.0 */
 542.875 +    return (png_ptr? 0: 0);
 542.876 +}
 542.877 +
 542.878 +/* this function was added to libpng 1.2.0 */
 542.879 +png_uint_32 PNGAPI
 542.880 +png_get_mmx_rowbytes_threshold (png_structp png_ptr)
 542.881 +{
 542.882 +    /* obsolete, to be removed from libpng-1.4.0 */
 542.883 +    return (png_ptr? 0L: 0L);
 542.884 +}
 542.885 +#endif /* ?PNG_1_0_X */
 542.886 +#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
 542.887 +
 542.888 +#ifdef PNG_SET_USER_LIMITS_SUPPORTED
 542.889 +/* these functions were added to libpng 1.2.6 */
 542.890 +png_uint_32 PNGAPI
 542.891 +png_get_user_width_max (png_structp png_ptr)
 542.892 +{
 542.893 +    return (png_ptr? png_ptr->user_width_max : 0);
 542.894 +}
 542.895 +png_uint_32 PNGAPI
 542.896 +png_get_user_height_max (png_structp png_ptr)
 542.897 +{
 542.898 +    return (png_ptr? png_ptr->user_height_max : 0);
 542.899 +}
 542.900 +#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
 542.901 + 
 542.902 +
 542.903 +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
   543.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   543.2 +++ b/libs/libpng/pngmem.c	Sat Feb 01 19:58:19 2014 +0200
   543.3 @@ -0,0 +1,609 @@
   543.4 +
   543.5 +/* pngmem.c - stub functions for memory allocation
   543.6 + *
   543.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   543.8 + * For conditions of distribution and use, see copyright notice in png.h
   543.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  543.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  543.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  543.12 + *
  543.13 + * This file provides a location for all memory allocation.  Users who
  543.14 + * need special memory handling are expected to supply replacement
  543.15 + * functions for png_malloc() and png_free(), and to use
  543.16 + * png_create_read_struct_2() and png_create_write_struct_2() to
  543.17 + * identify the replacement functions.
  543.18 + */
  543.19 +
  543.20 +#define PNG_INTERNAL
  543.21 +#include "png.h"
  543.22 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  543.23 +
  543.24 +/* Borland DOS special memory handler */
  543.25 +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
  543.26 +/* if you change this, be sure to change the one in png.h also */
  543.27 +
  543.28 +/* Allocate memory for a png_struct.  The malloc and memset can be replaced
  543.29 +   by a single call to calloc() if this is thought to improve performance. */
  543.30 +png_voidp /* PRIVATE */
  543.31 +png_create_struct(int type)
  543.32 +{
  543.33 +#ifdef PNG_USER_MEM_SUPPORTED
  543.34 +   return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
  543.35 +}
  543.36 +
  543.37 +/* Alternate version of png_create_struct, for use with user-defined malloc. */
  543.38 +png_voidp /* PRIVATE */
  543.39 +png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
  543.40 +{
  543.41 +#endif /* PNG_USER_MEM_SUPPORTED */
  543.42 +   png_size_t size;
  543.43 +   png_voidp struct_ptr;
  543.44 +
  543.45 +   if (type == PNG_STRUCT_INFO)
  543.46 +     size = png_sizeof(png_info);
  543.47 +   else if (type == PNG_STRUCT_PNG)
  543.48 +     size = png_sizeof(png_struct);
  543.49 +   else
  543.50 +     return (png_get_copyright(NULL));
  543.51 +
  543.52 +#ifdef PNG_USER_MEM_SUPPORTED
  543.53 +   if (malloc_fn != NULL)
  543.54 +   {
  543.55 +      png_struct dummy_struct;
  543.56 +      png_structp png_ptr = &dummy_struct;
  543.57 +      png_ptr->mem_ptr=mem_ptr;
  543.58 +      struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
  543.59 +   }
  543.60 +   else
  543.61 +#endif /* PNG_USER_MEM_SUPPORTED */
  543.62 +      struct_ptr = (png_voidp)farmalloc(size);
  543.63 +   if (struct_ptr != NULL)
  543.64 +      png_memset(struct_ptr, 0, size);
  543.65 +   return (struct_ptr);
  543.66 +}
  543.67 +
  543.68 +/* Free memory allocated by a png_create_struct() call */
  543.69 +void /* PRIVATE */
  543.70 +png_destroy_struct(png_voidp struct_ptr)
  543.71 +{
  543.72 +#ifdef PNG_USER_MEM_SUPPORTED
  543.73 +   png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
  543.74 +}
  543.75 +
  543.76 +/* Free memory allocated by a png_create_struct() call */
  543.77 +void /* PRIVATE */
  543.78 +png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
  543.79 +    png_voidp mem_ptr)
  543.80 +{
  543.81 +#endif
  543.82 +   if (struct_ptr != NULL)
  543.83 +   {
  543.84 +#ifdef PNG_USER_MEM_SUPPORTED
  543.85 +      if (free_fn != NULL)
  543.86 +      {
  543.87 +         png_struct dummy_struct;
  543.88 +         png_structp png_ptr = &dummy_struct;
  543.89 +         png_ptr->mem_ptr=mem_ptr;
  543.90 +         (*(free_fn))(png_ptr, struct_ptr);
  543.91 +         return;
  543.92 +      }
  543.93 +#endif /* PNG_USER_MEM_SUPPORTED */
  543.94 +      farfree (struct_ptr);
  543.95 +   }
  543.96 +}
  543.97 +
  543.98 +/* Allocate memory.  For reasonable files, size should never exceed
  543.99 + * 64K.  However, zlib may allocate more then 64K if you don't tell
 543.100 + * it not to.  See zconf.h and png.h for more information. zlib does
 543.101 + * need to allocate exactly 64K, so whatever you call here must
 543.102 + * have the ability to do that.
 543.103 + *
 543.104 + * Borland seems to have a problem in DOS mode for exactly 64K.
 543.105 + * It gives you a segment with an offset of 8 (perhaps to store its
 543.106 + * memory stuff).  zlib doesn't like this at all, so we have to
 543.107 + * detect and deal with it.  This code should not be needed in
 543.108 + * Windows or OS/2 modes, and only in 16 bit mode.  This code has
 543.109 + * been updated by Alexander Lehmann for version 0.89 to waste less
 543.110 + * memory.
 543.111 + *
 543.112 + * Note that we can't use png_size_t for the "size" declaration,
 543.113 + * since on some systems a png_size_t is a 16-bit quantity, and as a
 543.114 + * result, we would be truncating potentially larger memory requests
 543.115 + * (which should cause a fatal error) and introducing major problems.
 543.116 + */
 543.117 +
 543.118 +png_voidp PNGAPI
 543.119 +png_malloc(png_structp png_ptr, png_uint_32 size)
 543.120 +{
 543.121 +   png_voidp ret;
 543.122 +
 543.123 +   if (png_ptr == NULL || size == 0)
 543.124 +      return (NULL);
 543.125 +
 543.126 +#ifdef PNG_USER_MEM_SUPPORTED
 543.127 +   if (png_ptr->malloc_fn != NULL)
 543.128 +       ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
 543.129 +   else
 543.130 +       ret = (png_malloc_default(png_ptr, size));
 543.131 +   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
 543.132 +       png_error(png_ptr, "Out of memory!");
 543.133 +   return (ret);
 543.134 +}
 543.135 +
 543.136 +png_voidp PNGAPI
 543.137 +png_malloc_default(png_structp png_ptr, png_uint_32 size)
 543.138 +{
 543.139 +   png_voidp ret;
 543.140 +#endif /* PNG_USER_MEM_SUPPORTED */
 543.141 +
 543.142 +   if (png_ptr == NULL || size == 0)
 543.143 +      return (NULL);
 543.144 +
 543.145 +#ifdef PNG_MAX_MALLOC_64K
 543.146 +   if (size > (png_uint_32)65536L)
 543.147 +   {
 543.148 +      png_warning(png_ptr, "Cannot Allocate > 64K");
 543.149 +      ret = NULL;
 543.150 +   }
 543.151 +   else
 543.152 +#endif
 543.153 +
 543.154 +   if (size != (size_t)size)
 543.155 +     ret = NULL;
 543.156 +   else if (size == (png_uint_32)65536L)
 543.157 +   {
 543.158 +      if (png_ptr->offset_table == NULL)
 543.159 +      {
 543.160 +         /* try to see if we need to do any of this fancy stuff */
 543.161 +         ret = farmalloc(size);
 543.162 +         if (ret == NULL || ((png_size_t)ret & 0xffff))
 543.163 +         {
 543.164 +            int num_blocks;
 543.165 +            png_uint_32 total_size;
 543.166 +            png_bytep table;
 543.167 +            int i;
 543.168 +            png_byte huge * hptr;
 543.169 +
 543.170 +            if (ret != NULL)
 543.171 +            {
 543.172 +               farfree(ret);
 543.173 +               ret = NULL;
 543.174 +            }
 543.175 +
 543.176 +            if (png_ptr->zlib_window_bits > 14)
 543.177 +               num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
 543.178 +            else
 543.179 +               num_blocks = 1;
 543.180 +            if (png_ptr->zlib_mem_level >= 7)
 543.181 +               num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
 543.182 +            else
 543.183 +               num_blocks++;
 543.184 +
 543.185 +            total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
 543.186 +
 543.187 +            table = farmalloc(total_size);
 543.188 +
 543.189 +            if (table == NULL)
 543.190 +            {
 543.191 +#ifndef PNG_USER_MEM_SUPPORTED
 543.192 +               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
 543.193 +                  png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
 543.194 +               else
 543.195 +                  png_warning(png_ptr, "Out Of Memory.");
 543.196 +#endif
 543.197 +               return (NULL);
 543.198 +            }
 543.199 +
 543.200 +            if ((png_size_t)table & 0xfff0)
 543.201 +            {
 543.202 +#ifndef PNG_USER_MEM_SUPPORTED
 543.203 +               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
 543.204 +                  png_error(png_ptr,
 543.205 +                    "Farmalloc didn't return normalized pointer");
 543.206 +               else
 543.207 +                  png_warning(png_ptr,
 543.208 +                    "Farmalloc didn't return normalized pointer");
 543.209 +#endif
 543.210 +               return (NULL);
 543.211 +            }
 543.212 +
 543.213 +            png_ptr->offset_table = table;
 543.214 +            png_ptr->offset_table_ptr = farmalloc(num_blocks *
 543.215 +               png_sizeof(png_bytep));
 543.216 +
 543.217 +            if (png_ptr->offset_table_ptr == NULL)
 543.218 +            {
 543.219 +#ifndef PNG_USER_MEM_SUPPORTED
 543.220 +               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
 543.221 +                  png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
 543.222 +               else
 543.223 +                  png_warning(png_ptr, "Out Of memory.");
 543.224 +#endif
 543.225 +               return (NULL);
 543.226 +            }
 543.227 +
 543.228 +            hptr = (png_byte huge *)table;
 543.229 +            if ((png_size_t)hptr & 0xf)
 543.230 +            {
 543.231 +               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
 543.232 +               hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
 543.233 +            }
 543.234 +            for (i = 0; i < num_blocks; i++)
 543.235 +            {
 543.236 +               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
 543.237 +               hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
 543.238 +            }
 543.239 +
 543.240 +            png_ptr->offset_table_number = num_blocks;
 543.241 +            png_ptr->offset_table_count = 0;
 543.242 +            png_ptr->offset_table_count_free = 0;
 543.243 +         }
 543.244 +      }
 543.245 +
 543.246 +      if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
 543.247 +      {
 543.248 +#ifndef PNG_USER_MEM_SUPPORTED
 543.249 +         if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
 543.250 +            png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
 543.251 +         else
 543.252 +            png_warning(png_ptr, "Out of Memory.");
 543.253 +#endif
 543.254 +         return (NULL);
 543.255 +      }
 543.256 +
 543.257 +      ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
 543.258 +   }
 543.259 +   else
 543.260 +      ret = farmalloc(size);
 543.261 +
 543.262 +#ifndef PNG_USER_MEM_SUPPORTED
 543.263 +   if (ret == NULL)
 543.264 +   {
 543.265 +      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
 543.266 +         png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
 543.267 +      else
 543.268 +         png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
 543.269 +   }
 543.270 +#endif
 543.271 +
 543.272 +   return (ret);
 543.273 +}
 543.274 +
 543.275 +/* free a pointer allocated by png_malloc().  In the default
 543.276 +   configuration, png_ptr is not used, but is passed in case it
 543.277 +   is needed.  If ptr is NULL, return without taking any action. */
 543.278 +
 543.279 +void PNGAPI
 543.280 +png_free(png_structp png_ptr, png_voidp ptr)
 543.281 +{
 543.282 +   if (png_ptr == NULL || ptr == NULL)
 543.283 +      return;
 543.284 +
 543.285 +#ifdef PNG_USER_MEM_SUPPORTED
 543.286 +   if (png_ptr->free_fn != NULL)
 543.287 +   {
 543.288 +      (*(png_ptr->free_fn))(png_ptr, ptr);
 543.289 +      return;
 543.290 +   }
 543.291 +   else png_free_default(png_ptr, ptr);
 543.292 +}
 543.293 +
 543.294 +void PNGAPI
 543.295 +png_free_default(png_structp png_ptr, png_voidp ptr)
 543.296 +{
 543.297 +#endif /* PNG_USER_MEM_SUPPORTED */
 543.298 +
 543.299 +   if (png_ptr == NULL || ptr == NULL) return;
 543.300 +
 543.301 +   if (png_ptr->offset_table != NULL)
 543.302 +   {
 543.303 +      int i;
 543.304 +
 543.305 +      for (i = 0; i < png_ptr->offset_table_count; i++)
 543.306 +      {
 543.307 +         if (ptr == png_ptr->offset_table_ptr[i])
 543.308 +         {
 543.309 +            ptr = NULL;
 543.310 +            png_ptr->offset_table_count_free++;
 543.311 +            break;
 543.312 +         }
 543.313 +      }
 543.314 +      if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
 543.315 +      {
 543.316 +         farfree(png_ptr->offset_table);
 543.317 +         farfree(png_ptr->offset_table_ptr);
 543.318 +         png_ptr->offset_table = NULL;
 543.319 +         png_ptr->offset_table_ptr = NULL;
 543.320 +      }
 543.321 +   }
 543.322 +
 543.323 +   if (ptr != NULL)
 543.324 +   {
 543.325 +      farfree(ptr);
 543.326 +   }
 543.327 +}
 543.328 +
 543.329 +#else /* Not the Borland DOS special memory handler */
 543.330 +
 543.331 +/* Allocate memory for a png_struct or a png_info.  The malloc and
 543.332 +   memset can be replaced by a single call to calloc() if this is thought
 543.333 +   to improve performance noticably. */
 543.334 +png_voidp /* PRIVATE */
 543.335 +png_create_struct(int type)
 543.336 +{
 543.337 +#ifdef PNG_USER_MEM_SUPPORTED
 543.338 +   return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
 543.339 +}
 543.340 +
 543.341 +/* Allocate memory for a png_struct or a png_info.  The malloc and
 543.342 +   memset can be replaced by a single call to calloc() if this is thought
 543.343 +   to improve performance noticably. */
 543.344 +png_voidp /* PRIVATE */
 543.345 +png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
 543.346 +{
 543.347 +#endif /* PNG_USER_MEM_SUPPORTED */
 543.348 +   png_size_t size;
 543.349 +   png_voidp struct_ptr;
 543.350 +
 543.351 +   if (type == PNG_STRUCT_INFO)
 543.352 +      size = png_sizeof(png_info);
 543.353 +   else if (type == PNG_STRUCT_PNG)
 543.354 +      size = png_sizeof(png_struct);
 543.355 +   else
 543.356 +      return (NULL);
 543.357 +
 543.358 +#ifdef PNG_USER_MEM_SUPPORTED
 543.359 +   if (malloc_fn != NULL)
 543.360 +   {
 543.361 +      png_struct dummy_struct;
 543.362 +      png_structp png_ptr = &dummy_struct;
 543.363 +      png_ptr->mem_ptr=mem_ptr;
 543.364 +      struct_ptr = (*(malloc_fn))(png_ptr, size);
 543.365 +      if (struct_ptr != NULL)
 543.366 +         png_memset(struct_ptr, 0, size);
 543.367 +      return (struct_ptr);
 543.368 +   }
 543.369 +#endif /* PNG_USER_MEM_SUPPORTED */
 543.370 +
 543.371 +#if defined(__TURBOC__) && !defined(__FLAT__)
 543.372 +   struct_ptr = (png_voidp)farmalloc(size);
 543.373 +#else
 543.374 +# if defined(_MSC_VER) && defined(MAXSEG_64K)
 543.375 +   struct_ptr = (png_voidp)halloc(size, 1);
 543.376 +# else
 543.377 +   struct_ptr = (png_voidp)malloc(size);
 543.378 +# endif
 543.379 +#endif
 543.380 +   if (struct_ptr != NULL)
 543.381 +      png_memset(struct_ptr, 0, size);
 543.382 +
 543.383 +   return (struct_ptr);
 543.384 +}
 543.385 +
 543.386 +
 543.387 +/* Free memory allocated by a png_create_struct() call */
 543.388 +void /* PRIVATE */
 543.389 +png_destroy_struct(png_voidp struct_ptr)
 543.390 +{
 543.391 +#ifdef PNG_USER_MEM_SUPPORTED
 543.392 +   png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
 543.393 +}
 543.394 +
 543.395 +/* Free memory allocated by a png_create_struct() call */
 543.396 +void /* PRIVATE */
 543.397 +png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
 543.398 +    png_voidp mem_ptr)
 543.399 +{
 543.400 +#endif /* PNG_USER_MEM_SUPPORTED */
 543.401 +   if (struct_ptr != NULL)
 543.402 +   {
 543.403 +#ifdef PNG_USER_MEM_SUPPORTED
 543.404 +      if (free_fn != NULL)
 543.405 +      {
 543.406 +         png_struct dummy_struct;
 543.407 +         png_structp png_ptr = &dummy_struct;
 543.408 +         png_ptr->mem_ptr=mem_ptr;
 543.409 +         (*(free_fn))(png_ptr, struct_ptr);
 543.410 +         return;
 543.411 +      }
 543.412 +#endif /* PNG_USER_MEM_SUPPORTED */
 543.413 +#if defined(__TURBOC__) && !defined(__FLAT__)
 543.414 +      farfree(struct_ptr);
 543.415 +#else
 543.416 +# if defined(_MSC_VER) && defined(MAXSEG_64K)
 543.417 +      hfree(struct_ptr);
 543.418 +# else
 543.419 +      free(struct_ptr);
 543.420 +# endif
 543.421 +#endif
 543.422 +   }
 543.423 +}
 543.424 +
 543.425 +/* Allocate memory.  For reasonable files, size should never exceed
 543.426 +   64K.  However, zlib may allocate more then 64K if you don't tell
 543.427 +   it not to.  See zconf.h and png.h for more information.  zlib does
 543.428 +   need to allocate exactly 64K, so whatever you call here must
 543.429 +   have the ability to do that. */
 543.430 +
 543.431 +png_voidp PNGAPI
 543.432 +png_malloc(png_structp png_ptr, png_uint_32 size)
 543.433 +{
 543.434 +   png_voidp ret;
 543.435 +
 543.436 +#ifdef PNG_USER_MEM_SUPPORTED
 543.437 +   if (png_ptr == NULL || size == 0)
 543.438 +      return (NULL);
 543.439 +
 543.440 +   if (png_ptr->malloc_fn != NULL)
 543.441 +       ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
 543.442 +   else
 543.443 +       ret = (png_malloc_default(png_ptr, size));
 543.444 +   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
 543.445 +       png_error(png_ptr, "Out of Memory!");
 543.446 +   return (ret);
 543.447 +}
 543.448 +
 543.449 +png_voidp PNGAPI
 543.450 +png_malloc_default(png_structp png_ptr, png_uint_32 size)
 543.451 +{
 543.452 +   png_voidp ret;
 543.453 +#endif /* PNG_USER_MEM_SUPPORTED */
 543.454 +
 543.455 +   if (png_ptr == NULL || size == 0)
 543.456 +      return (NULL);
 543.457 +
 543.458 +#ifdef PNG_MAX_MALLOC_64K
 543.459 +   if (size > (png_uint_32)65536L)
 543.460 +   {
 543.461 +#ifndef PNG_USER_MEM_SUPPORTED
 543.462 +      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
 543.463 +         png_error(png_ptr, "Cannot Allocate > 64K");
 543.464 +      else
 543.465 +#endif
 543.466 +         return NULL;
 543.467 +   }
 543.468 +#endif
 543.469 +
 543.470 + /* Check for overflow */
 543.471 +#if defined(__TURBOC__) && !defined(__FLAT__)
 543.472 + if (size != (unsigned long)size)
 543.473 +   ret = NULL;
 543.474 + else
 543.475 +   ret = farmalloc(size);
 543.476 +#else
 543.477 +# if defined(_MSC_VER) && defined(MAXSEG_64K)
 543.478 + if (size != (unsigned long)size)
 543.479 +   ret = NULL;
 543.480 + else
 543.481 +   ret = halloc(size, 1);
 543.482 +# else
 543.483 + if (size != (size_t)size)
 543.484 +   ret = NULL;
 543.485 + else
 543.486 +   ret = malloc((size_t)size);
 543.487 +# endif
 543.488 +#endif
 543.489 +
 543.490 +#ifndef PNG_USER_MEM_SUPPORTED
 543.491 +   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
 543.492 +      png_error(png_ptr, "Out of Memory");
 543.493 +#endif
 543.494 +
 543.495 +   return (ret);
 543.496 +}
 543.497 +
 543.498 +/* Free a pointer allocated by png_malloc().  If ptr is NULL, return
 543.499 +   without taking any action. */
 543.500 +void PNGAPI
 543.501 +png_free(png_structp png_ptr, png_voidp ptr)
 543.502 +{
 543.503 +   if (png_ptr == NULL || ptr == NULL)
 543.504 +      return;
 543.505 +
 543.506 +#ifdef PNG_USER_MEM_SUPPORTED
 543.507 +   if (png_ptr->free_fn != NULL)
 543.508 +   {
 543.509 +      (*(png_ptr->free_fn))(png_ptr, ptr);
 543.510 +      return;
 543.511 +   }
 543.512 +   else png_free_default(png_ptr, ptr);
 543.513 +}
 543.514 +void PNGAPI
 543.515 +png_free_default(png_structp png_ptr, png_voidp ptr)
 543.516 +{
 543.517 +   if (png_ptr == NULL || ptr == NULL)
 543.518 +      return;
 543.519 +
 543.520 +#endif /* PNG_USER_MEM_SUPPORTED */
 543.521 +
 543.522 +#if defined(__TURBOC__) && !defined(__FLAT__)
 543.523 +   farfree(ptr);
 543.524 +#else
 543.525 +# if defined(_MSC_VER) && defined(MAXSEG_64K)
 543.526 +   hfree(ptr);
 543.527 +# else
 543.528 +   free(ptr);
 543.529 +# endif
 543.530 +#endif
 543.531 +}
 543.532 +
 543.533 +#endif /* Not Borland DOS special memory handler */
 543.534 +
 543.535 +#if defined(PNG_1_0_X)
 543.536 +#  define png_malloc_warn png_malloc
 543.537 +#else
 543.538 +/* This function was added at libpng version 1.2.3.  The png_malloc_warn()
 543.539 + * function will set up png_malloc() to issue a png_warning and return NULL
 543.540 + * instead of issuing a png_error, if it fails to allocate the requested
 543.541 + * memory.
 543.542 + */
 543.543 +png_voidp PNGAPI
 543.544 +png_malloc_warn(png_structp png_ptr, png_uint_32 size)
 543.545 +{
 543.546 +   png_voidp ptr;
 543.547 +   png_uint_32 save_flags;
 543.548 +   if (png_ptr == NULL) return (NULL);
 543.549 +
 543.550 +   save_flags = png_ptr->flags;
 543.551 +   png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
 543.552 +   ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
 543.553 +   png_ptr->flags=save_flags;
 543.554 +   return(ptr);
 543.555 +}
 543.556 +#endif
 543.557 +
 543.558 +png_voidp PNGAPI
 543.559 +png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
 543.560 +   png_uint_32 length)
 543.561 +{
 543.562 +   png_size_t size;
 543.563 +
 543.564 +   size = (png_size_t)length;
 543.565 +   if ((png_uint_32)size != length)
 543.566 +      png_error(png_ptr, "Overflow in png_memcpy_check.");
 543.567 +
 543.568 +   return(png_memcpy (s1, s2, size));
 543.569 +}
 543.570 +
 543.571 +png_voidp PNGAPI
 543.572 +png_memset_check (png_structp png_ptr, png_voidp s1, int value,
 543.573 +   png_uint_32 length)
 543.574 +{
 543.575 +   png_size_t size;
 543.576 +
 543.577 +   size = (png_size_t)length;
 543.578 +   if ((png_uint_32)size != length)
 543.579 +      png_error(png_ptr, "Overflow in png_memset_check.");
 543.580 +
 543.581 +   return (png_memset (s1, value, size));
 543.582 +
 543.583 +}
 543.584 +
 543.585 +#ifdef PNG_USER_MEM_SUPPORTED
 543.586 +/* This function is called when the application wants to use another method
 543.587 + * of allocating and freeing memory.
 543.588 + */
 543.589 +void PNGAPI
 543.590 +png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
 543.591 +  malloc_fn, png_free_ptr free_fn)
 543.592 +{
 543.593 +   if (png_ptr != NULL)
 543.594 +   {
 543.595 +      png_ptr->mem_ptr = mem_ptr;
 543.596 +      png_ptr->malloc_fn = malloc_fn;
 543.597 +      png_ptr->free_fn = free_fn;
 543.598 +   }
 543.599 +}
 543.600 +
 543.601 +/* This function returns a pointer to the mem_ptr associated with the user
 543.602 + * functions.  The application should free any memory associated with this
 543.603 + * pointer before png_write_destroy and png_read_destroy are called.
 543.604 + */
 543.605 +png_voidp PNGAPI
 543.606 +png_get_mem_ptr(png_structp png_ptr)
 543.607 +{
 543.608 +   if (png_ptr == NULL) return (NULL);
 543.609 +   return ((png_voidp)png_ptr->mem_ptr);
 543.610 +}
 543.611 +#endif /* PNG_USER_MEM_SUPPORTED */
 543.612 +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
   544.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   544.2 +++ b/libs/libpng/pngpread.c	Sat Feb 01 19:58:19 2014 +0200
   544.3 @@ -0,0 +1,1594 @@
   544.4 +
   544.5 +/* pngpread.c - read a png file in push mode
   544.6 + *
   544.7 + * Last changed in libpng 1.2.32 [September 18, 2008]
   544.8 + * For conditions of distribution and use, see copyright notice in png.h
   544.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  544.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  544.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  544.12 + */
  544.13 +
  544.14 +#define PNG_INTERNAL
  544.15 +#include "png.h"
  544.16 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  544.17 +
  544.18 +/* push model modes */
  544.19 +#define PNG_READ_SIG_MODE   0
  544.20 +#define PNG_READ_CHUNK_MODE 1
  544.21 +#define PNG_READ_IDAT_MODE  2
  544.22 +#define PNG_SKIP_MODE       3
  544.23 +#define PNG_READ_tEXt_MODE  4
  544.24 +#define PNG_READ_zTXt_MODE  5
  544.25 +#define PNG_READ_DONE_MODE  6
  544.26 +#define PNG_READ_iTXt_MODE  7
  544.27 +#define PNG_ERROR_MODE      8
  544.28 +
  544.29 +void PNGAPI
  544.30 +png_process_data(png_structp png_ptr, png_infop info_ptr,
  544.31 +   png_bytep buffer, png_size_t buffer_size)
  544.32 +{
  544.33 +   if (png_ptr == NULL || info_ptr == NULL) return;
  544.34 +   png_push_restore_buffer(png_ptr, buffer, buffer_size);
  544.35 +
  544.36 +   while (png_ptr->buffer_size)
  544.37 +   {
  544.38 +      png_process_some_data(png_ptr, info_ptr);
  544.39 +   }
  544.40 +}
  544.41 +
  544.42 +/* What we do with the incoming data depends on what we were previously
  544.43 + * doing before we ran out of data...
  544.44 + */
  544.45 +void /* PRIVATE */
  544.46 +png_process_some_data(png_structp png_ptr, png_infop info_ptr)
  544.47 +{
  544.48 +   if (png_ptr == NULL) return;
  544.49 +   switch (png_ptr->process_mode)
  544.50 +   {
  544.51 +      case PNG_READ_SIG_MODE:
  544.52 +      {
  544.53 +         png_push_read_sig(png_ptr, info_ptr);
  544.54 +         break;
  544.55 +      }
  544.56 +      case PNG_READ_CHUNK_MODE:
  544.57 +      {
  544.58 +         png_push_read_chunk(png_ptr, info_ptr);
  544.59 +         break;
  544.60 +      }
  544.61 +      case PNG_READ_IDAT_MODE:
  544.62 +      {
  544.63 +         png_push_read_IDAT(png_ptr);
  544.64 +         break;
  544.65 +      }
  544.66 +#if defined(PNG_READ_tEXt_SUPPORTED)
  544.67 +      case PNG_READ_tEXt_MODE:
  544.68 +      {
  544.69 +         png_push_read_tEXt(png_ptr, info_ptr);
  544.70 +         break;
  544.71 +      }
  544.72 +#endif
  544.73 +#if defined(PNG_READ_zTXt_SUPPORTED)
  544.74 +      case PNG_READ_zTXt_MODE:
  544.75 +      {
  544.76 +         png_push_read_zTXt(png_ptr, info_ptr);
  544.77 +         break;
  544.78 +      }
  544.79 +#endif
  544.80 +#if defined(PNG_READ_iTXt_SUPPORTED)
  544.81 +      case PNG_READ_iTXt_MODE:
  544.82 +      {
  544.83 +         png_push_read_iTXt(png_ptr, info_ptr);
  544.84 +         break;
  544.85 +      }
  544.86 +#endif
  544.87 +      case PNG_SKIP_MODE:
  544.88 +      {
  544.89 +         png_push_crc_finish(png_ptr);
  544.90 +         break;
  544.91 +      }
  544.92 +      default:
  544.93 +      {
  544.94 +         png_ptr->buffer_size = 0;
  544.95 +         break;
  544.96 +      }
  544.97 +   }
  544.98 +}
  544.99 +
 544.100 +/* Read any remaining signature bytes from the stream and compare them with
 544.101 + * the correct PNG signature.  It is possible that this routine is called
 544.102 + * with bytes already read from the signature, either because they have been
 544.103 + * checked by the calling application, or because of multiple calls to this
 544.104 + * routine.
 544.105 + */
 544.106 +void /* PRIVATE */
 544.107 +png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
 544.108 +{
 544.109 +   png_size_t num_checked = png_ptr->sig_bytes,
 544.110 +             num_to_check = 8 - num_checked;
 544.111 +
 544.112 +   if (png_ptr->buffer_size < num_to_check)
 544.113 +   {
 544.114 +      num_to_check = png_ptr->buffer_size;
 544.115 +   }
 544.116 +
 544.117 +   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
 544.118 +      num_to_check);
 544.119 +   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
 544.120 +
 544.121 +   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
 544.122 +   {
 544.123 +      if (num_checked < 4 &&
 544.124 +          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
 544.125 +         png_error(png_ptr, "Not a PNG file");
 544.126 +      else
 544.127 +         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
 544.128 +   }
 544.129 +   else
 544.130 +   {
 544.131 +      if (png_ptr->sig_bytes >= 8)
 544.132 +      {
 544.133 +         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
 544.134 +      }
 544.135 +   }
 544.136 +}
 544.137 +
 544.138 +void /* PRIVATE */
 544.139 +png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 544.140 +{
 544.141 +#ifdef PNG_USE_LOCAL_ARRAYS
 544.142 +      PNG_CONST PNG_IHDR;
 544.143 +      PNG_CONST PNG_IDAT;
 544.144 +      PNG_CONST PNG_IEND;
 544.145 +      PNG_CONST PNG_PLTE;
 544.146 +#if defined(PNG_READ_bKGD_SUPPORTED)
 544.147 +      PNG_CONST PNG_bKGD;
 544.148 +#endif
 544.149 +#if defined(PNG_READ_cHRM_SUPPORTED)
 544.150 +      PNG_CONST PNG_cHRM;
 544.151 +#endif
 544.152 +#if defined(PNG_READ_gAMA_SUPPORTED)
 544.153 +      PNG_CONST PNG_gAMA;
 544.154 +#endif
 544.155 +#if defined(PNG_READ_hIST_SUPPORTED)
 544.156 +      PNG_CONST PNG_hIST;
 544.157 +#endif
 544.158 +#if defined(PNG_READ_iCCP_SUPPORTED)
 544.159 +      PNG_CONST PNG_iCCP;
 544.160 +#endif
 544.161 +#if defined(PNG_READ_iTXt_SUPPORTED)
 544.162 +      PNG_CONST PNG_iTXt;
 544.163 +#endif
 544.164 +#if defined(PNG_READ_oFFs_SUPPORTED)
 544.165 +      PNG_CONST PNG_oFFs;
 544.166 +#endif
 544.167 +#if defined(PNG_READ_pCAL_SUPPORTED)
 544.168 +      PNG_CONST PNG_pCAL;
 544.169 +#endif
 544.170 +#if defined(PNG_READ_pHYs_SUPPORTED)
 544.171 +      PNG_CONST PNG_pHYs;
 544.172 +#endif
 544.173 +#if defined(PNG_READ_sBIT_SUPPORTED)
 544.174 +      PNG_CONST PNG_sBIT;
 544.175 +#endif
 544.176 +#if defined(PNG_READ_sCAL_SUPPORTED)
 544.177 +      PNG_CONST PNG_sCAL;
 544.178 +#endif
 544.179 +#if defined(PNG_READ_sRGB_SUPPORTED)
 544.180 +      PNG_CONST PNG_sRGB;
 544.181 +#endif
 544.182 +#if defined(PNG_READ_sPLT_SUPPORTED)
 544.183 +      PNG_CONST PNG_sPLT;
 544.184 +#endif
 544.185 +#if defined(PNG_READ_tEXt_SUPPORTED)
 544.186 +      PNG_CONST PNG_tEXt;
 544.187 +#endif
 544.188 +#if defined(PNG_READ_tIME_SUPPORTED)
 544.189 +      PNG_CONST PNG_tIME;
 544.190 +#endif
 544.191 +#if defined(PNG_READ_tRNS_SUPPORTED)
 544.192 +      PNG_CONST PNG_tRNS;
 544.193 +#endif
 544.194 +#if defined(PNG_READ_zTXt_SUPPORTED)
 544.195 +      PNG_CONST PNG_zTXt;
 544.196 +#endif
 544.197 +#endif /* PNG_USE_LOCAL_ARRAYS */
 544.198 +   /* First we make sure we have enough data for the 4 byte chunk name
 544.199 +    * and the 4 byte chunk length before proceeding with decoding the
 544.200 +    * chunk data.  To fully decode each of these chunks, we also make
 544.201 +    * sure we have enough data in the buffer for the 4 byte CRC at the
 544.202 +    * end of every chunk (except IDAT, which is handled separately).
 544.203 +    */
 544.204 +   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
 544.205 +   {
 544.206 +      png_byte chunk_length[4];
 544.207 +
 544.208 +      if (png_ptr->buffer_size < 8)
 544.209 +      {
 544.210 +         png_push_save_buffer(png_ptr);
 544.211 +         return;
 544.212 +      }
 544.213 +
 544.214 +      png_push_fill_buffer(png_ptr, chunk_length, 4);
 544.215 +      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
 544.216 +      png_reset_crc(png_ptr);
 544.217 +      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
 544.218 +      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
 544.219 +      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
 544.220 +   }
 544.221 +
 544.222 +   if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
 544.223 +     if (png_ptr->mode & PNG_AFTER_IDAT)
 544.224 +        png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
 544.225 +
 544.226 +   if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
 544.227 +   {
 544.228 +      if (png_ptr->push_length != 13)
 544.229 +         png_error(png_ptr, "Invalid IHDR length");
 544.230 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.231 +      {
 544.232 +         png_push_save_buffer(png_ptr);
 544.233 +         return;
 544.234 +      }
 544.235 +      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
 544.236 +   }
 544.237 +   else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
 544.238 +   {
 544.239 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.240 +      {
 544.241 +         png_push_save_buffer(png_ptr);
 544.242 +         return;
 544.243 +      }
 544.244 +      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
 544.245 +
 544.246 +      png_ptr->process_mode = PNG_READ_DONE_MODE;
 544.247 +      png_push_have_end(png_ptr, info_ptr);
 544.248 +   }
 544.249 +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 544.250 +   else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
 544.251 +   {
 544.252 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.253 +      {
 544.254 +         png_push_save_buffer(png_ptr);
 544.255 +         return;
 544.256 +      }
 544.257 +      if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
 544.258 +         png_ptr->mode |= PNG_HAVE_IDAT;
 544.259 +      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
 544.260 +      if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
 544.261 +         png_ptr->mode |= PNG_HAVE_PLTE;
 544.262 +      else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
 544.263 +      {
 544.264 +         if (!(png_ptr->mode & PNG_HAVE_IHDR))
 544.265 +            png_error(png_ptr, "Missing IHDR before IDAT");
 544.266 +         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
 544.267 +                  !(png_ptr->mode & PNG_HAVE_PLTE))
 544.268 +            png_error(png_ptr, "Missing PLTE before IDAT");
 544.269 +      }
 544.270 +   }
 544.271 +#endif
 544.272 +   else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
 544.273 +   {
 544.274 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.275 +      {
 544.276 +         png_push_save_buffer(png_ptr);
 544.277 +         return;
 544.278 +      }
 544.279 +      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
 544.280 +   }
 544.281 +   else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
 544.282 +   {
 544.283 +      /* If we reach an IDAT chunk, this means we have read all of the
 544.284 +       * header chunks, and we can start reading the image (or if this
 544.285 +       * is called after the image has been read - we have an error).
 544.286 +       */
 544.287 +     if (!(png_ptr->mode & PNG_HAVE_IHDR))
 544.288 +       png_error(png_ptr, "Missing IHDR before IDAT");
 544.289 +     else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
 544.290 +         !(png_ptr->mode & PNG_HAVE_PLTE))
 544.291 +       png_error(png_ptr, "Missing PLTE before IDAT");
 544.292 +
 544.293 +      if (png_ptr->mode & PNG_HAVE_IDAT)
 544.294 +      {
 544.295 +         if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
 544.296 +           if (png_ptr->push_length == 0)
 544.297 +              return;
 544.298 +
 544.299 +         if (png_ptr->mode & PNG_AFTER_IDAT)
 544.300 +            png_error(png_ptr, "Too many IDAT's found");
 544.301 +      }
 544.302 +
 544.303 +      png_ptr->idat_size = png_ptr->push_length;
 544.304 +      png_ptr->mode |= PNG_HAVE_IDAT;
 544.305 +      png_ptr->process_mode = PNG_READ_IDAT_MODE;
 544.306 +      png_push_have_info(png_ptr, info_ptr);
 544.307 +      png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
 544.308 +      png_ptr->zstream.next_out = png_ptr->row_buf;
 544.309 +      return;
 544.310 +   }
 544.311 +#if defined(PNG_READ_gAMA_SUPPORTED)
 544.312 +   else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
 544.313 +   {
 544.314 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.315 +      {
 544.316 +         png_push_save_buffer(png_ptr);
 544.317 +         return;
 544.318 +      }
 544.319 +      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
 544.320 +   }
 544.321 +#endif
 544.322 +#if defined(PNG_READ_sBIT_SUPPORTED)
 544.323 +   else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
 544.324 +   {
 544.325 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.326 +      {
 544.327 +         png_push_save_buffer(png_ptr);
 544.328 +         return;
 544.329 +      }
 544.330 +      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
 544.331 +   }
 544.332 +#endif
 544.333 +#if defined(PNG_READ_cHRM_SUPPORTED)
 544.334 +   else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
 544.335 +   {
 544.336 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.337 +      {
 544.338 +         png_push_save_buffer(png_ptr);
 544.339 +         return;
 544.340 +      }
 544.341 +      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
 544.342 +   }
 544.343 +#endif
 544.344 +#if defined(PNG_READ_sRGB_SUPPORTED)
 544.345 +   else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
 544.346 +   {
 544.347 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.348 +      {
 544.349 +         png_push_save_buffer(png_ptr);
 544.350 +         return;
 544.351 +      }
 544.352 +      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
 544.353 +   }
 544.354 +#endif
 544.355 +#if defined(PNG_READ_iCCP_SUPPORTED)
 544.356 +   else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
 544.357 +   {
 544.358 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.359 +      {
 544.360 +         png_push_save_buffer(png_ptr);
 544.361 +         return;
 544.362 +      }
 544.363 +      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
 544.364 +   }
 544.365 +#endif
 544.366 +#if defined(PNG_READ_sPLT_SUPPORTED)
 544.367 +   else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
 544.368 +   {
 544.369 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.370 +      {
 544.371 +         png_push_save_buffer(png_ptr);
 544.372 +         return;
 544.373 +      }
 544.374 +      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
 544.375 +   }
 544.376 +#endif
 544.377 +#if defined(PNG_READ_tRNS_SUPPORTED)
 544.378 +   else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
 544.379 +   {
 544.380 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.381 +      {
 544.382 +         png_push_save_buffer(png_ptr);
 544.383 +         return;
 544.384 +      }
 544.385 +      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
 544.386 +   }
 544.387 +#endif
 544.388 +#if defined(PNG_READ_bKGD_SUPPORTED)
 544.389 +   else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
 544.390 +   {
 544.391 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.392 +      {
 544.393 +         png_push_save_buffer(png_ptr);
 544.394 +         return;
 544.395 +      }
 544.396 +      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
 544.397 +   }
 544.398 +#endif
 544.399 +#if defined(PNG_READ_hIST_SUPPORTED)
 544.400 +   else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
 544.401 +   {
 544.402 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.403 +      {
 544.404 +         png_push_save_buffer(png_ptr);
 544.405 +         return;
 544.406 +      }
 544.407 +      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
 544.408 +   }
 544.409 +#endif
 544.410 +#if defined(PNG_READ_pHYs_SUPPORTED)
 544.411 +   else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
 544.412 +   {
 544.413 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.414 +      {
 544.415 +         png_push_save_buffer(png_ptr);
 544.416 +         return;
 544.417 +      }
 544.418 +      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
 544.419 +   }
 544.420 +#endif
 544.421 +#if defined(PNG_READ_oFFs_SUPPORTED)
 544.422 +   else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
 544.423 +   {
 544.424 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.425 +      {
 544.426 +         png_push_save_buffer(png_ptr);
 544.427 +         return;
 544.428 +      }
 544.429 +      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
 544.430 +   }
 544.431 +#endif
 544.432 +#if defined(PNG_READ_pCAL_SUPPORTED)
 544.433 +   else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
 544.434 +   {
 544.435 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.436 +      {
 544.437 +         png_push_save_buffer(png_ptr);
 544.438 +         return;
 544.439 +      }
 544.440 +      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
 544.441 +   }
 544.442 +#endif
 544.443 +#if defined(PNG_READ_sCAL_SUPPORTED)
 544.444 +   else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
 544.445 +   {
 544.446 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.447 +      {
 544.448 +         png_push_save_buffer(png_ptr);
 544.449 +         return;
 544.450 +      }
 544.451 +      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
 544.452 +   }
 544.453 +#endif
 544.454 +#if defined(PNG_READ_tIME_SUPPORTED)
 544.455 +   else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
 544.456 +   {
 544.457 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.458 +      {
 544.459 +         png_push_save_buffer(png_ptr);
 544.460 +         return;
 544.461 +      }
 544.462 +      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
 544.463 +   }
 544.464 +#endif
 544.465 +#if defined(PNG_READ_tEXt_SUPPORTED)
 544.466 +   else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
 544.467 +   {
 544.468 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.469 +      {
 544.470 +         png_push_save_buffer(png_ptr);
 544.471 +         return;
 544.472 +      }
 544.473 +      png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
 544.474 +   }
 544.475 +#endif
 544.476 +#if defined(PNG_READ_zTXt_SUPPORTED)
 544.477 +   else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
 544.478 +   {
 544.479 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.480 +      {
 544.481 +         png_push_save_buffer(png_ptr);
 544.482 +         return;
 544.483 +      }
 544.484 +      png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
 544.485 +   }
 544.486 +#endif
 544.487 +#if defined(PNG_READ_iTXt_SUPPORTED)
 544.488 +   else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
 544.489 +   {
 544.490 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.491 +      {
 544.492 +         png_push_save_buffer(png_ptr);
 544.493 +         return;
 544.494 +      }
 544.495 +      png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
 544.496 +   }
 544.497 +#endif
 544.498 +   else
 544.499 +   {
 544.500 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 544.501 +      {
 544.502 +         png_push_save_buffer(png_ptr);
 544.503 +         return;
 544.504 +      }
 544.505 +      png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
 544.506 +   }
 544.507 +
 544.508 +   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
 544.509 +}
 544.510 +
 544.511 +void /* PRIVATE */
 544.512 +png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
 544.513 +{
 544.514 +   png_ptr->process_mode = PNG_SKIP_MODE;
 544.515 +   png_ptr->skip_length = skip;
 544.516 +}
 544.517 +
 544.518 +void /* PRIVATE */
 544.519 +png_push_crc_finish(png_structp png_ptr)
 544.520 +{
 544.521 +   if (png_ptr->skip_length && png_ptr->save_buffer_size)
 544.522 +   {
 544.523 +      png_size_t save_size;
 544.524 +
 544.525 +      if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
 544.526 +         save_size = (png_size_t)png_ptr->skip_length;
 544.527 +      else
 544.528 +         save_size = png_ptr->save_buffer_size;
 544.529 +
 544.530 +      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
 544.531 +
 544.532 +      png_ptr->skip_length -= save_size;
 544.533 +      png_ptr->buffer_size -= save_size;
 544.534 +      png_ptr->save_buffer_size -= save_size;
 544.535 +      png_ptr->save_buffer_ptr += save_size;
 544.536 +   }
 544.537 +   if (png_ptr->skip_length && png_ptr->current_buffer_size)
 544.538 +   {
 544.539 +      png_size_t save_size;
 544.540 +
 544.541 +      if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
 544.542 +         save_size = (png_size_t)png_ptr->skip_length;
 544.543 +      else
 544.544 +         save_size = png_ptr->current_buffer_size;
 544.545 +
 544.546 +      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
 544.547 +
 544.548 +      png_ptr->skip_length -= save_size;
 544.549 +      png_ptr->buffer_size -= save_size;
 544.550 +      png_ptr->current_buffer_size -= save_size;
 544.551 +      png_ptr->current_buffer_ptr += save_size;
 544.552 +   }
 544.553 +   if (!png_ptr->skip_length)
 544.554 +   {
 544.555 +      if (png_ptr->buffer_size < 4)
 544.556 +      {
 544.557 +         png_push_save_buffer(png_ptr);
 544.558 +         return;
 544.559 +      }
 544.560 +
 544.561 +      png_crc_finish(png_ptr, 0);
 544.562 +      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
 544.563 +   }
 544.564 +}
 544.565 +
 544.566 +void PNGAPI
 544.567 +png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
 544.568 +{
 544.569 +   png_bytep ptr;
 544.570 +
 544.571 +   if (png_ptr == NULL) return;
 544.572 +   ptr = buffer;
 544.573 +   if (png_ptr->save_buffer_size)
 544.574 +   {
 544.575 +      png_size_t save_size;
 544.576 +
 544.577 +      if (length < png_ptr->save_buffer_size)
 544.578 +         save_size = length;
 544.579 +      else
 544.580 +         save_size = png_ptr->save_buffer_size;
 544.581 +
 544.582 +      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
 544.583 +      length -= save_size;
 544.584 +      ptr += save_size;
 544.585 +      png_ptr->buffer_size -= save_size;
 544.586 +      png_ptr->save_buffer_size -= save_size;
 544.587 +      png_ptr->save_buffer_ptr += save_size;
 544.588 +   }
 544.589 +   if (length && png_ptr->current_buffer_size)
 544.590 +   {
 544.591 +      png_size_t save_size;
 544.592 +
 544.593 +      if (length < png_ptr->current_buffer_size)
 544.594 +         save_size = length;
 544.595 +      else
 544.596 +         save_size = png_ptr->current_buffer_size;
 544.597 +
 544.598 +      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
 544.599 +      png_ptr->buffer_size -= save_size;
 544.600 +      png_ptr->current_buffer_size -= save_size;
 544.601 +      png_ptr->current_buffer_ptr += save_size;
 544.602 +   }
 544.603 +}
 544.604 +
 544.605 +void /* PRIVATE */
 544.606 +png_push_save_buffer(png_structp png_ptr)
 544.607 +{
 544.608 +   if (png_ptr->save_buffer_size)
 544.609 +   {
 544.610 +      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
 544.611 +      {
 544.612 +         png_size_t i, istop;
 544.613 +         png_bytep sp;
 544.614 +         png_bytep dp;
 544.615 +
 544.616 +         istop = png_ptr->save_buffer_size;
 544.617 +         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
 544.618 +            i < istop; i++, sp++, dp++)
 544.619 +         {
 544.620 +            *dp = *sp;
 544.621 +         }
 544.622 +      }
 544.623 +   }
 544.624 +   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
 544.625 +      png_ptr->save_buffer_max)
 544.626 +   {
 544.627 +      png_size_t new_max;
 544.628 +      png_bytep old_buffer;
 544.629 +
 544.630 +      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
 544.631 +         (png_ptr->current_buffer_size + 256))
 544.632 +      {
 544.633 +        png_error(png_ptr, "Potential overflow of save_buffer");
 544.634 +      }
 544.635 +      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
 544.636 +      old_buffer = png_ptr->save_buffer;
 544.637 +      png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
 544.638 +         (png_uint_32)new_max);
 544.639 +      png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
 544.640 +      png_free(png_ptr, old_buffer);
 544.641 +      png_ptr->save_buffer_max = new_max;
 544.642 +   }
 544.643 +   if (png_ptr->current_buffer_size)
 544.644 +   {
 544.645 +      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
 544.646 +         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
 544.647 +      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
 544.648 +      png_ptr->current_buffer_size = 0;
 544.649 +   }
 544.650 +   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
 544.651 +   png_ptr->buffer_size = 0;
 544.652 +}
 544.653 +
 544.654 +void /* PRIVATE */
 544.655 +png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
 544.656 +   png_size_t buffer_length)
 544.657 +{
 544.658 +   png_ptr->current_buffer = buffer;
 544.659 +   png_ptr->current_buffer_size = buffer_length;
 544.660 +   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
 544.661 +   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
 544.662 +}
 544.663 +
 544.664 +void /* PRIVATE */
 544.665 +png_push_read_IDAT(png_structp png_ptr)
 544.666 +{
 544.667 +#ifdef PNG_USE_LOCAL_ARRAYS
 544.668 +   PNG_CONST PNG_IDAT;
 544.669 +#endif
 544.670 +   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
 544.671 +   {
 544.672 +      png_byte chunk_length[4];
 544.673 +
 544.674 +      if (png_ptr->buffer_size < 8)
 544.675 +      {
 544.676 +         png_push_save_buffer(png_ptr);
 544.677 +         return;
 544.678 +      }
 544.679 +
 544.680 +      png_push_fill_buffer(png_ptr, chunk_length, 4);
 544.681 +      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
 544.682 +      png_reset_crc(png_ptr);
 544.683 +      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
 544.684 +      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
 544.685 +
 544.686 +      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
 544.687 +      {
 544.688 +         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
 544.689 +         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
 544.690 +            png_error(png_ptr, "Not enough compressed data");
 544.691 +         return;
 544.692 +      }
 544.693 +
 544.694 +      png_ptr->idat_size = png_ptr->push_length;
 544.695 +   }
 544.696 +   if (png_ptr->idat_size && png_ptr->save_buffer_size)
 544.697 +   {
 544.698 +      png_size_t save_size;
 544.699 +
 544.700 +      if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
 544.701 +      {
 544.702 +         save_size = (png_size_t)png_ptr->idat_size;
 544.703 +         /* check for overflow */
 544.704 +         if ((png_uint_32)save_size != png_ptr->idat_size)
 544.705 +            png_error(png_ptr, "save_size overflowed in pngpread");
 544.706 +      }
 544.707 +      else
 544.708 +         save_size = png_ptr->save_buffer_size;
 544.709 +
 544.710 +      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
 544.711 +      if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
 544.712 +         png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
 544.713 +      png_ptr->idat_size -= save_size;
 544.714 +      png_ptr->buffer_size -= save_size;
 544.715 +      png_ptr->save_buffer_size -= save_size;
 544.716 +      png_ptr->save_buffer_ptr += save_size;
 544.717 +   }
 544.718 +   if (png_ptr->idat_size && png_ptr->current_buffer_size)
 544.719 +   {
 544.720 +      png_size_t save_size;
 544.721 +
 544.722 +      if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
 544.723 +      {
 544.724 +         save_size = (png_size_t)png_ptr->idat_size;
 544.725 +         /* check for overflow */
 544.726 +         if ((png_uint_32)save_size != png_ptr->idat_size)
 544.727 +            png_error(png_ptr, "save_size overflowed in pngpread");
 544.728 +      }
 544.729 +      else
 544.730 +         save_size = png_ptr->current_buffer_size;
 544.731 +
 544.732 +      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
 544.733 +      if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
 544.734 +        png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
 544.735 +
 544.736 +      png_ptr->idat_size -= save_size;
 544.737 +      png_ptr->buffer_size -= save_size;
 544.738 +      png_ptr->current_buffer_size -= save_size;
 544.739 +      png_ptr->current_buffer_ptr += save_size;
 544.740 +   }
 544.741 +   if (!png_ptr->idat_size)
 544.742 +   {
 544.743 +      if (png_ptr->buffer_size < 4)
 544.744 +      {
 544.745 +         png_push_save_buffer(png_ptr);
 544.746 +         return;
 544.747 +      }
 544.748 +
 544.749 +      png_crc_finish(png_ptr, 0);
 544.750 +      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
 544.751 +      png_ptr->mode |= PNG_AFTER_IDAT;
 544.752 +   }
 544.753 +}
 544.754 +
 544.755 +void /* PRIVATE */
 544.756 +png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
 544.757 +   png_size_t buffer_length)
 544.758 +{
 544.759 +   int ret;
 544.760 +
 544.761 +   if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
 544.762 +      png_error(png_ptr, "Extra compression data");
 544.763 +
 544.764 +   png_ptr->zstream.next_in = buffer;
 544.765 +   png_ptr->zstream.avail_in = (uInt)buffer_length;
 544.766 +   for (;;)
 544.767 +   {
 544.768 +      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
 544.769 +      if (ret != Z_OK)
 544.770 +      {
 544.771 +         if (ret == Z_STREAM_END)
 544.772 +         {
 544.773 +            if (png_ptr->zstream.avail_in)
 544.774 +               png_error(png_ptr, "Extra compressed data");
 544.775 +            if (!(png_ptr->zstream.avail_out))
 544.776 +            {
 544.777 +               png_push_process_row(png_ptr);
 544.778 +            }
 544.779 +
 544.780 +            png_ptr->mode |= PNG_AFTER_IDAT;
 544.781 +            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
 544.782 +            break;
 544.783 +         }
 544.784 +         else if (ret == Z_BUF_ERROR)
 544.785 +            break;
 544.786 +         else
 544.787 +            png_error(png_ptr, "Decompression Error");
 544.788 +      }
 544.789 +      if (!(png_ptr->zstream.avail_out))
 544.790 +      {
 544.791 +         if ((
 544.792 +#if defined(PNG_READ_INTERLACING_SUPPORTED)
 544.793 +             png_ptr->interlaced && png_ptr->pass > 6) ||
 544.794 +             (!png_ptr->interlaced &&
 544.795 +#endif
 544.796 +             png_ptr->row_number == png_ptr->num_rows))
 544.797 +         {
 544.798 +           if (png_ptr->zstream.avail_in)
 544.799 +             png_warning(png_ptr, "Too much data in IDAT chunks");
 544.800 +           png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
 544.801 +           break;
 544.802 +         }
 544.803 +         png_push_process_row(png_ptr);
 544.804 +         png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
 544.805 +         png_ptr->zstream.next_out = png_ptr->row_buf;
 544.806 +      }
 544.807 +      else
 544.808 +         break;
 544.809 +   }
 544.810 +}
 544.811 +
 544.812 +void /* PRIVATE */
 544.813 +png_push_process_row(png_structp png_ptr)
 544.814 +{
 544.815 +   png_ptr->row_info.color_type = png_ptr->color_type;
 544.816 +   png_ptr->row_info.width = png_ptr->iwidth;
 544.817 +   png_ptr->row_info.channels = png_ptr->channels;
 544.818 +   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
 544.819 +   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
 544.820 +
 544.821 +   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
 544.822 +       png_ptr->row_info.width);
 544.823 +
 544.824 +   png_read_filter_row(png_ptr, &(png_ptr->row_info),
 544.825 +      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
 544.826 +      (int)(png_ptr->row_buf[0]));
 544.827 +
 544.828 +   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
 544.829 +      png_ptr->rowbytes + 1);
 544.830 +
 544.831 +   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
 544.832 +      png_do_read_transformations(png_ptr);
 544.833 +
 544.834 +#if defined(PNG_READ_INTERLACING_SUPPORTED)
 544.835 +   /* blow up interlaced rows to full size */
 544.836 +   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
 544.837 +   {
 544.838 +      if (png_ptr->pass < 6)
 544.839 +/*       old interface (pre-1.0.9):
 544.840 +         png_do_read_interlace(&(png_ptr->row_info),
 544.841 +            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
 544.842 + */
 544.843 +         png_do_read_interlace(png_ptr);
 544.844 +
 544.845 +    switch (png_ptr->pass)
 544.846 +    {
 544.847 +         case 0:
 544.848 +         {
 544.849 +            int i;
 544.850 +            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
 544.851 +            {
 544.852 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
 544.853 +               png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
 544.854 +            }
 544.855 +            if (png_ptr->pass == 2) /* pass 1 might be empty */
 544.856 +            {
 544.857 +               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
 544.858 +               {
 544.859 +                  png_push_have_row(png_ptr, png_bytep_NULL);
 544.860 +                  png_read_push_finish_row(png_ptr);
 544.861 +               }
 544.862 +            }
 544.863 +            if (png_ptr->pass == 4 && png_ptr->height <= 4)
 544.864 +            {
 544.865 +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
 544.866 +               {
 544.867 +                  png_push_have_row(png_ptr, png_bytep_NULL);
 544.868 +                  png_read_push_finish_row(png_ptr);
 544.869 +               }
 544.870 +            }
 544.871 +            if (png_ptr->pass == 6 && png_ptr->height <= 4)
 544.872 +            {
 544.873 +                png_push_have_row(png_ptr, png_bytep_NULL);
 544.874 +                png_read_push_finish_row(png_ptr);
 544.875 +            }
 544.876 +            break;
 544.877 +         }
 544.878 +         case 1:
 544.879 +         {
 544.880 +            int i;
 544.881 +            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
 544.882 +            {
 544.883 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
 544.884 +               png_read_push_finish_row(png_ptr);
 544.885 +            }
 544.886 +            if (png_ptr->pass == 2) /* skip top 4 generated rows */
 544.887 +            {
 544.888 +               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
 544.889 +               {
 544.890 +                  png_push_have_row(png_ptr, png_bytep_NULL);
 544.891 +                  png_read_push_finish_row(png_ptr);
 544.892 +               }
 544.893 +            }
 544.894 +            break;
 544.895 +         }
 544.896 +         case 2:
 544.897 +         {
 544.898 +            int i;
 544.899 +            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
 544.900 +            {
 544.901 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
 544.902 +               png_read_push_finish_row(png_ptr);
 544.903 +            }
 544.904 +            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
 544.905 +            {
 544.906 +               png_push_have_row(png_ptr, png_bytep_NULL);
 544.907 +               png_read_push_finish_row(png_ptr);
 544.908 +            }
 544.909 +            if (png_ptr->pass == 4) /* pass 3 might be empty */
 544.910 +            {
 544.911 +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
 544.912 +               {
 544.913 +                  png_push_have_row(png_ptr, png_bytep_NULL);
 544.914 +                  png_read_push_finish_row(png_ptr);
 544.915 +               }
 544.916 +            }
 544.917 +            break;
 544.918 +         }
 544.919 +         case 3:
 544.920 +         {
 544.921 +            int i;
 544.922 +            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
 544.923 +            {
 544.924 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
 544.925 +               png_read_push_finish_row(png_ptr);
 544.926 +            }
 544.927 +            if (png_ptr->pass == 4) /* skip top two generated rows */
 544.928 +            {
 544.929 +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
 544.930 +               {
 544.931 +                  png_push_have_row(png_ptr, png_bytep_NULL);
 544.932 +                  png_read_push_finish_row(png_ptr);
 544.933 +               }
 544.934 +            }
 544.935 +            break;
 544.936 +         }
 544.937 +         case 4:
 544.938 +         {
 544.939 +            int i;
 544.940 +            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
 544.941 +            {
 544.942 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
 544.943 +               png_read_push_finish_row(png_ptr);
 544.944 +            }
 544.945 +            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
 544.946 +            {
 544.947 +               png_push_have_row(png_ptr, png_bytep_NULL);
 544.948 +               png_read_push_finish_row(png_ptr);
 544.949 +            }
 544.950 +            if (png_ptr->pass == 6) /* pass 5 might be empty */
 544.951 +            {
 544.952 +               png_push_have_row(png_ptr, png_bytep_NULL);
 544.953 +               png_read_push_finish_row(png_ptr);
 544.954 +            }
 544.955 +            break;
 544.956 +         }
 544.957 +         case 5:
 544.958 +         {
 544.959 +            int i;
 544.960 +            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
 544.961 +            {
 544.962 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
 544.963 +               png_read_push_finish_row(png_ptr);
 544.964 +            }
 544.965 +            if (png_ptr->pass == 6) /* skip top generated row */
 544.966 +            {
 544.967 +               png_push_have_row(png_ptr, png_bytep_NULL);
 544.968 +               png_read_push_finish_row(png_ptr);
 544.969 +            }
 544.970 +            break;
 544.971 +         }
 544.972 +         case 6:
 544.973 +         {
 544.974 +            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
 544.975 +            png_read_push_finish_row(png_ptr);
 544.976 +            if (png_ptr->pass != 6)
 544.977 +               break;
 544.978 +            png_push_have_row(png_ptr, png_bytep_NULL);
 544.979 +            png_read_push_finish_row(png_ptr);
 544.980 +         }
 544.981 +      }
 544.982 +   }
 544.983 +   else
 544.984 +#endif
 544.985 +   {
 544.986 +      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
 544.987 +      png_read_push_finish_row(png_ptr);
 544.988 +   }
 544.989 +}
 544.990 +
 544.991 +void /* PRIVATE */
 544.992 +png_read_push_finish_row(png_structp png_ptr)
 544.993 +{
 544.994 +#ifdef PNG_USE_LOCAL_ARRAYS
 544.995 +   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 544.996 +
 544.997 +   /* start of interlace block */
 544.998 +   PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
 544.999 +
544.1000 +   /* offset to next interlace block */
544.1001 +   PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
544.1002 +
544.1003 +   /* start of interlace block in the y direction */
544.1004 +   PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
544.1005 +
544.1006 +   /* offset to next interlace block in the y direction */
544.1007 +   PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
544.1008 +
544.1009 +   /* Height of interlace block.  This is not currently used - if you need
544.1010 +    * it, uncomment it here and in png.h
544.1011 +   PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
544.1012 +   */
544.1013 +#endif
544.1014 +
544.1015 +   png_ptr->row_number++;
544.1016 +   if (png_ptr->row_number < png_ptr->num_rows)
544.1017 +      return;
544.1018 +
544.1019 +   if (png_ptr->interlaced)
544.1020 +   {
544.1021 +      png_ptr->row_number = 0;
544.1022 +      png_memset_check(png_ptr, png_ptr->prev_row, 0,
544.1023 +         png_ptr->rowbytes + 1);
544.1024 +      do
544.1025 +      {
544.1026 +         png_ptr->pass++;
544.1027 +         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
544.1028 +             (png_ptr->pass == 3 && png_ptr->width < 3) ||
544.1029 +             (png_ptr->pass == 5 && png_ptr->width < 2))
544.1030 +           png_ptr->pass++;
544.1031 +
544.1032 +         if (png_ptr->pass > 7)
544.1033 +            png_ptr->pass--;
544.1034 +         if (png_ptr->pass >= 7)
544.1035 +            break;
544.1036 +
544.1037 +         png_ptr->iwidth = (png_ptr->width +
544.1038 +            png_pass_inc[png_ptr->pass] - 1 -
544.1039 +            png_pass_start[png_ptr->pass]) /
544.1040 +            png_pass_inc[png_ptr->pass];
544.1041 +
544.1042 +         png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
544.1043 +            png_ptr->iwidth) + 1;
544.1044 +
544.1045 +         if (png_ptr->transformations & PNG_INTERLACE)
544.1046 +            break;
544.1047 +
544.1048 +         png_ptr->num_rows = (png_ptr->height +
544.1049 +            png_pass_yinc[png_ptr->pass] - 1 -
544.1050 +            png_pass_ystart[png_ptr->pass]) /
544.1051 +            png_pass_yinc[png_ptr->pass];
544.1052 +
544.1053 +      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
544.1054 +   }
544.1055 +}
544.1056 +
544.1057 +#if defined(PNG_READ_tEXt_SUPPORTED)
544.1058 +void /* PRIVATE */
544.1059 +png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
544.1060 +   length)
544.1061 +{
544.1062 +   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
544.1063 +      {
544.1064 +         png_error(png_ptr, "Out of place tEXt");
544.1065 +         info_ptr = info_ptr; /* to quiet some compiler warnings */
544.1066 +      }
544.1067 +
544.1068 +#ifdef PNG_MAX_MALLOC_64K
544.1069 +   png_ptr->skip_length = 0;  /* This may not be necessary */
544.1070 +
544.1071 +   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
544.1072 +   {
544.1073 +      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
544.1074 +      png_ptr->skip_length = length - (png_uint_32)65535L;
544.1075 +      length = (png_uint_32)65535L;
544.1076 +   }
544.1077 +#endif
544.1078 +
544.1079 +   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
544.1080 +      (png_uint_32)(length + 1));
544.1081 +   png_ptr->current_text[length] = '\0';
544.1082 +   png_ptr->current_text_ptr = png_ptr->current_text;
544.1083 +   png_ptr->current_text_size = (png_size_t)length;
544.1084 +   png_ptr->current_text_left = (png_size_t)length;
544.1085 +   png_ptr->process_mode = PNG_READ_tEXt_MODE;
544.1086 +}
544.1087 +
544.1088 +void /* PRIVATE */
544.1089 +png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
544.1090 +{
544.1091 +   if (png_ptr->buffer_size && png_ptr->current_text_left)
544.1092 +   {
544.1093 +      png_size_t text_size;
544.1094 +
544.1095 +      if (png_ptr->buffer_size < png_ptr->current_text_left)
544.1096 +         text_size = png_ptr->buffer_size;
544.1097 +      else
544.1098 +         text_size = png_ptr->current_text_left;
544.1099 +      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
544.1100 +      png_ptr->current_text_left -= text_size;
544.1101 +      png_ptr->current_text_ptr += text_size;
544.1102 +   }
544.1103 +   if (!(png_ptr->current_text_left))
544.1104 +   {
544.1105 +      png_textp text_ptr;
544.1106 +      png_charp text;
544.1107 +      png_charp key;
544.1108 +      int ret;
544.1109 +
544.1110 +      if (png_ptr->buffer_size < 4)
544.1111 +      {
544.1112 +         png_push_save_buffer(png_ptr);
544.1113 +         return;
544.1114 +      }
544.1115 +
544.1116 +      png_push_crc_finish(png_ptr);
544.1117 +
544.1118 +#if defined(PNG_MAX_MALLOC_64K)
544.1119 +      if (png_ptr->skip_length)
544.1120 +         return;
544.1121 +#endif
544.1122 +
544.1123 +      key = png_ptr->current_text;
544.1124 +
544.1125 +      for (text = key; *text; text++)
544.1126 +         /* empty loop */ ;
544.1127 +
544.1128 +      if (text < key + png_ptr->current_text_size)
544.1129 +         text++;
544.1130 +
544.1131 +      text_ptr = (png_textp)png_malloc(png_ptr,
544.1132 +         (png_uint_32)png_sizeof(png_text));
544.1133 +      text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
544.1134 +      text_ptr->key = key;
544.1135 +#ifdef PNG_iTXt_SUPPORTED
544.1136 +      text_ptr->lang = NULL;
544.1137 +      text_ptr->lang_key = NULL;
544.1138 +#endif
544.1139 +      text_ptr->text = text;
544.1140 +
544.1141 +      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
544.1142 +
544.1143 +      png_free(png_ptr, key);
544.1144 +      png_free(png_ptr, text_ptr);
544.1145 +      png_ptr->current_text = NULL;
544.1146 +
544.1147 +      if (ret)
544.1148 +        png_warning(png_ptr, "Insufficient memory to store text chunk.");
544.1149 +   }
544.1150 +}
544.1151 +#endif
544.1152 +
544.1153 +#if defined(PNG_READ_zTXt_SUPPORTED)
544.1154 +void /* PRIVATE */
544.1155 +png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
544.1156 +   length)
544.1157 +{
544.1158 +   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
544.1159 +      {
544.1160 +         png_error(png_ptr, "Out of place zTXt");
544.1161 +         info_ptr = info_ptr; /* to quiet some compiler warnings */
544.1162 +      }
544.1163 +
544.1164 +#ifdef PNG_MAX_MALLOC_64K
544.1165 +   /* We can't handle zTXt chunks > 64K, since we don't have enough space
544.1166 +    * to be able to store the uncompressed data.  Actually, the threshold
544.1167 +    * is probably around 32K, but it isn't as definite as 64K is.
544.1168 +    */
544.1169 +   if (length > (png_uint_32)65535L)
544.1170 +   {
544.1171 +      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
544.1172 +      png_push_crc_skip(png_ptr, length);
544.1173 +      return;
544.1174 +   }
544.1175 +#endif
544.1176 +
544.1177 +   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
544.1178 +      (png_uint_32)(length + 1));
544.1179 +   png_ptr->current_text[length] = '\0';
544.1180 +   png_ptr->current_text_ptr = png_ptr->current_text;
544.1181 +   png_ptr->current_text_size = (png_size_t)length;
544.1182 +   png_ptr->current_text_left = (png_size_t)length;
544.1183 +   png_ptr->process_mode = PNG_READ_zTXt_MODE;
544.1184 +}
544.1185 +
544.1186 +void /* PRIVATE */
544.1187 +png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
544.1188 +{
544.1189 +   if (png_ptr->buffer_size && png_ptr->current_text_left)
544.1190 +   {
544.1191 +      png_size_t text_size;
544.1192 +
544.1193 +      if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
544.1194 +         text_size = png_ptr->buffer_size;
544.1195 +      else
544.1196 +         text_size = png_ptr->current_text_left;
544.1197 +      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
544.1198 +      png_ptr->current_text_left -= text_size;
544.1199 +      png_ptr->current_text_ptr += text_size;
544.1200 +   }
544.1201 +   if (!(png_ptr->current_text_left))
544.1202 +   {
544.1203 +      png_textp text_ptr;
544.1204 +      png_charp text;
544.1205 +      png_charp key;
544.1206 +      int ret;
544.1207 +      png_size_t text_size, key_size;
544.1208 +
544.1209 +      if (png_ptr->buffer_size < 4)
544.1210 +      {
544.1211 +         png_push_save_buffer(png_ptr);
544.1212 +         return;
544.1213 +      }
544.1214 +
544.1215 +      png_push_crc_finish(png_ptr);
544.1216 +
544.1217 +      key = png_ptr->current_text;
544.1218 +
544.1219 +      for (text = key; *text; text++)
544.1220 +         /* empty loop */ ;
544.1221 +
544.1222 +      /* zTXt can't have zero text */
544.1223 +      if (text >= key + png_ptr->current_text_size)
544.1224 +      {
544.1225 +         png_ptr->current_text = NULL;
544.1226 +         png_free(png_ptr, key);
544.1227 +         return;
544.1228 +      }
544.1229 +
544.1230 +      text++;
544.1231 +
544.1232 +      if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
544.1233 +      {
544.1234 +         png_ptr->current_text = NULL;
544.1235 +         png_free(png_ptr, key);
544.1236 +         return;
544.1237 +      }
544.1238 +
544.1239 +      text++;
544.1240 +
544.1241 +      png_ptr->zstream.next_in = (png_bytep )text;
544.1242 +      png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
544.1243 +         (text - key));
544.1244 +      png_ptr->zstream.next_out = png_ptr->zbuf;
544.1245 +      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
544.1246 +
544.1247 +      key_size = text - key;
544.1248 +      text_size = 0;
544.1249 +      text = NULL;
544.1250 +      ret = Z_STREAM_END;
544.1251 +
544.1252 +      while (png_ptr->zstream.avail_in)
544.1253 +      {
544.1254 +         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
544.1255 +         if (ret != Z_OK && ret != Z_STREAM_END)
544.1256 +         {
544.1257 +            inflateReset(&png_ptr->zstream);
544.1258 +            png_ptr->zstream.avail_in = 0;
544.1259 +            png_ptr->current_text = NULL;
544.1260 +            png_free(png_ptr, key);
544.1261 +            png_free(png_ptr, text);
544.1262 +            return;
544.1263 +         }
544.1264 +         if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
544.1265 +         {
544.1266 +            if (text == NULL)
544.1267 +            {
544.1268 +               text = (png_charp)png_malloc(png_ptr,
544.1269 +                     (png_uint_32)(png_ptr->zbuf_size
544.1270 +                     - png_ptr->zstream.avail_out + key_size + 1));
544.1271 +               png_memcpy(text + key_size, png_ptr->zbuf,
544.1272 +                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
544.1273 +               png_memcpy(text, key, key_size);
544.1274 +               text_size = key_size + png_ptr->zbuf_size -
544.1275 +                  png_ptr->zstream.avail_out;
544.1276 +               *(text + text_size) = '\0';
544.1277 +            }
544.1278 +            else
544.1279 +            {
544.1280 +               png_charp tmp;
544.1281 +
544.1282 +               tmp = text;
544.1283 +               text = (png_charp)png_malloc(png_ptr, text_size +
544.1284 +                  (png_uint_32)(png_ptr->zbuf_size 
544.1285 +                  - png_ptr->zstream.avail_out + 1));
544.1286 +               png_memcpy(text, tmp, text_size);
544.1287 +               png_free(png_ptr, tmp);
544.1288 +               png_memcpy(text + text_size, png_ptr->zbuf,
544.1289 +                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
544.1290 +               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
544.1291 +               *(text + text_size) = '\0';
544.1292 +            }
544.1293 +            if (ret != Z_STREAM_END)
544.1294 +            {
544.1295 +               png_ptr->zstream.next_out = png_ptr->zbuf;
544.1296 +               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
544.1297 +            }
544.1298 +         }
544.1299 +         else
544.1300 +         {
544.1301 +            break;
544.1302 +         }
544.1303 +
544.1304 +         if (ret == Z_STREAM_END)
544.1305 +            break;
544.1306 +      }
544.1307 +
544.1308 +      inflateReset(&png_ptr->zstream);
544.1309 +      png_ptr->zstream.avail_in = 0;
544.1310 +
544.1311 +      if (ret != Z_STREAM_END)
544.1312 +      {
544.1313 +         png_ptr->current_text = NULL;
544.1314 +         png_free(png_ptr, key);
544.1315 +         png_free(png_ptr, text);
544.1316 +         return;
544.1317 +      }
544.1318 +
544.1319 +      png_ptr->current_text = NULL;
544.1320 +      png_free(png_ptr, key);
544.1321 +      key = text;
544.1322 +      text += key_size;
544.1323 +
544.1324 +      text_ptr = (png_textp)png_malloc(png_ptr,
544.1325 +          (png_uint_32)png_sizeof(png_text));
544.1326 +      text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
544.1327 +      text_ptr->key = key;
544.1328 +#ifdef PNG_iTXt_SUPPORTED
544.1329 +      text_ptr->lang = NULL;
544.1330 +      text_ptr->lang_key = NULL;
544.1331 +#endif
544.1332 +      text_ptr->text = text;
544.1333 +
544.1334 +      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
544.1335 +
544.1336 +      png_free(png_ptr, key);
544.1337 +      png_free(png_ptr, text_ptr);
544.1338 +
544.1339 +      if (ret)
544.1340 +        png_warning(png_ptr, "Insufficient memory to store text chunk.");
544.1341 +   }
544.1342 +}
544.1343 +#endif
544.1344 +
544.1345 +#if defined(PNG_READ_iTXt_SUPPORTED)
544.1346 +void /* PRIVATE */
544.1347 +png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
544.1348 +   length)
544.1349 +{
544.1350 +   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
544.1351 +      {
544.1352 +         png_error(png_ptr, "Out of place iTXt");
544.1353 +         info_ptr = info_ptr; /* to quiet some compiler warnings */
544.1354 +      }
544.1355 +
544.1356 +#ifdef PNG_MAX_MALLOC_64K
544.1357 +   png_ptr->skip_length = 0;  /* This may not be necessary */
544.1358 +
544.1359 +   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
544.1360 +   {
544.1361 +      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
544.1362 +      png_ptr->skip_length = length - (png_uint_32)65535L;
544.1363 +      length = (png_uint_32)65535L;
544.1364 +   }
544.1365 +#endif
544.1366 +
544.1367 +   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
544.1368 +      (png_uint_32)(length + 1));
544.1369 +   png_ptr->current_text[length] = '\0';
544.1370 +   png_ptr->current_text_ptr = png_ptr->current_text;
544.1371 +   png_ptr->current_text_size = (png_size_t)length;
544.1372 +   png_ptr->current_text_left = (png_size_t)length;
544.1373 +   png_ptr->process_mode = PNG_READ_iTXt_MODE;
544.1374 +}
544.1375 +
544.1376 +void /* PRIVATE */
544.1377 +png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
544.1378 +{
544.1379 +
544.1380 +   if (png_ptr->buffer_size && png_ptr->current_text_left)
544.1381 +   {
544.1382 +      png_size_t text_size;
544.1383 +
544.1384 +      if (png_ptr->buffer_size < png_ptr->current_text_left)
544.1385 +         text_size = png_ptr->buffer_size;
544.1386 +      else
544.1387 +         text_size = png_ptr->current_text_left;
544.1388 +      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
544.1389 +      png_ptr->current_text_left -= text_size;
544.1390 +      png_ptr->current_text_ptr += text_size;
544.1391 +   }
544.1392 +   if (!(png_ptr->current_text_left))
544.1393 +   {
544.1394 +      png_textp text_ptr;
544.1395 +      png_charp key;
544.1396 +      int comp_flag;
544.1397 +      png_charp lang;
544.1398 +      png_charp lang_key;
544.1399 +      png_charp text;
544.1400 +      int ret;
544.1401 +
544.1402 +      if (png_ptr->buffer_size < 4)
544.1403 +      {
544.1404 +         png_push_save_buffer(png_ptr);
544.1405 +         return;
544.1406 +      }
544.1407 +
544.1408 +      png_push_crc_finish(png_ptr);
544.1409 +
544.1410 +#if defined(PNG_MAX_MALLOC_64K)
544.1411 +      if (png_ptr->skip_length)
544.1412 +         return;
544.1413 +#endif
544.1414 +
544.1415 +      key = png_ptr->current_text;
544.1416 +
544.1417 +      for (lang = key; *lang; lang++)
544.1418 +         /* empty loop */ ;
544.1419 +
544.1420 +      if (lang < key + png_ptr->current_text_size - 3)
544.1421 +         lang++;
544.1422 +
544.1423 +      comp_flag = *lang++;
544.1424 +      lang++;     /* skip comp_type, always zero */
544.1425 +
544.1426 +      for (lang_key = lang; *lang_key; lang_key++)
544.1427 +         /* empty loop */ ;
544.1428 +      lang_key++;        /* skip NUL separator */
544.1429 +
544.1430 +      text=lang_key;
544.1431 +      if (lang_key < key + png_ptr->current_text_size - 1)
544.1432 +      {
544.1433 +        for (; *text; text++)
544.1434 +           /* empty loop */ ;
544.1435 +      }
544.1436 +
544.1437 +      if (text < key + png_ptr->current_text_size)
544.1438 +         text++;
544.1439 +
544.1440 +      text_ptr = (png_textp)png_malloc(png_ptr,
544.1441 +         (png_uint_32)png_sizeof(png_text));
544.1442 +      text_ptr->compression = comp_flag + 2;
544.1443 +      text_ptr->key = key;
544.1444 +      text_ptr->lang = lang;
544.1445 +      text_ptr->lang_key = lang_key;
544.1446 +      text_ptr->text = text;
544.1447 +      text_ptr->text_length = 0;
544.1448 +      text_ptr->itxt_length = png_strlen(text);
544.1449 +
544.1450 +      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
544.1451 +
544.1452 +      png_ptr->current_text = NULL;
544.1453 +
544.1454 +      png_free(png_ptr, text_ptr);
544.1455 +      if (ret)
544.1456 +        png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
544.1457 +   }
544.1458 +}
544.1459 +#endif
544.1460 +
544.1461 +/* This function is called when we haven't found a handler for this
544.1462 + * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
544.1463 + * name or a critical chunk), the chunk is (currently) silently ignored.
544.1464 + */
544.1465 +void /* PRIVATE */
544.1466 +png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
544.1467 +   length)
544.1468 +{
544.1469 +   png_uint_32 skip = 0;
544.1470 +
544.1471 +   if (!(png_ptr->chunk_name[0] & 0x20))
544.1472 +   {
544.1473 +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
544.1474 +      if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
544.1475 +         PNG_HANDLE_CHUNK_ALWAYS
544.1476 +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
544.1477 +         && png_ptr->read_user_chunk_fn == NULL
544.1478 +#endif
544.1479 +         )
544.1480 +#endif
544.1481 +         png_chunk_error(png_ptr, "unknown critical chunk");
544.1482 +
544.1483 +      info_ptr = info_ptr; /* to quiet some compiler warnings */
544.1484 +   }
544.1485 +
544.1486 +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
544.1487 +   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
544.1488 +   {
544.1489 +#ifdef PNG_MAX_MALLOC_64K
544.1490 +      if (length > (png_uint_32)65535L)
544.1491 +      {
544.1492 +          png_warning(png_ptr, "unknown chunk too large to fit in memory");
544.1493 +          skip = length - (png_uint_32)65535L;
544.1494 +          length = (png_uint_32)65535L;
544.1495 +      }
544.1496 +#endif
544.1497 +      png_memcpy((png_charp)png_ptr->unknown_chunk.name,
544.1498 +                 (png_charp)png_ptr->chunk_name, 
544.1499 +                 png_sizeof(png_ptr->unknown_chunk.name));
544.1500 +      png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
544.1501 +        = '\0';
544.1502 +
544.1503 +      png_ptr->unknown_chunk.size = (png_size_t)length;
544.1504 +      if (length == 0)
544.1505 +         png_ptr->unknown_chunk.data = NULL;
544.1506 +      else
544.1507 +      {
544.1508 +         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
544.1509 +       (png_uint_32)length);
544.1510 +         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
544.1511 +      }
544.1512 +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
544.1513 +      if (png_ptr->read_user_chunk_fn != NULL)
544.1514 +      {
544.1515 +         /* callback to user unknown chunk handler */
544.1516 +         int ret;
544.1517 +         ret = (*(png_ptr->read_user_chunk_fn))
544.1518 +           (png_ptr, &png_ptr->unknown_chunk);
544.1519 +         if (ret < 0)
544.1520 +            png_chunk_error(png_ptr, "error in user chunk");
544.1521 +         if (ret == 0)
544.1522 +         {
544.1523 +            if (!(png_ptr->chunk_name[0] & 0x20))
544.1524 +               if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
544.1525 +                    PNG_HANDLE_CHUNK_ALWAYS)
544.1526 +                  png_chunk_error(png_ptr, "unknown critical chunk");
544.1527 +            png_set_unknown_chunks(png_ptr, info_ptr,
544.1528 +               &png_ptr->unknown_chunk, 1);
544.1529 +         }
544.1530 +      }
544.1531 +      else
544.1532 +#endif
544.1533 +        png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
544.1534 +      png_free(png_ptr, png_ptr->unknown_chunk.data);
544.1535 +      png_ptr->unknown_chunk.data = NULL;
544.1536 +   }
544.1537 +   else
544.1538 +#endif
544.1539 +      skip=length;
544.1540 +   png_push_crc_skip(png_ptr, skip);
544.1541 +}
544.1542 +
544.1543 +void /* PRIVATE */
544.1544 +png_push_have_info(png_structp png_ptr, png_infop info_ptr)
544.1545 +{
544.1546 +   if (png_ptr->info_fn != NULL)
544.1547 +      (*(png_ptr->info_fn))(png_ptr, info_ptr);
544.1548 +}
544.1549 +
544.1550 +void /* PRIVATE */
544.1551 +png_push_have_end(png_structp png_ptr, png_infop info_ptr)
544.1552 +{
544.1553 +   if (png_ptr->end_fn != NULL)
544.1554 +      (*(png_ptr->end_fn))(png_ptr, info_ptr);
544.1555 +}
544.1556 +
544.1557 +void /* PRIVATE */
544.1558 +png_push_have_row(png_structp png_ptr, png_bytep row)
544.1559 +{
544.1560 +   if (png_ptr->row_fn != NULL)
544.1561 +      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
544.1562 +         (int)png_ptr->pass);
544.1563 +}
544.1564 +
544.1565 +void PNGAPI
544.1566 +png_progressive_combine_row (png_structp png_ptr,
544.1567 +   png_bytep old_row, png_bytep new_row)
544.1568 +{
544.1569 +#ifdef PNG_USE_LOCAL_ARRAYS
544.1570 +   PNG_CONST int FARDATA png_pass_dsp_mask[7] =
544.1571 +      {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
544.1572 +#endif
544.1573 +   if (png_ptr == NULL) return;
544.1574 +   if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
544.1575 +      png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
544.1576 +}
544.1577 +
544.1578 +void PNGAPI
544.1579 +png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
544.1580 +   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
544.1581 +   png_progressive_end_ptr end_fn)
544.1582 +{
544.1583 +   if (png_ptr == NULL) return;
544.1584 +   png_ptr->info_fn = info_fn;
544.1585 +   png_ptr->row_fn = row_fn;
544.1586 +   png_ptr->end_fn = end_fn;
544.1587 +
544.1588 +   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
544.1589 +}
544.1590 +
544.1591 +png_voidp PNGAPI
544.1592 +png_get_progressive_ptr(png_structp png_ptr)
544.1593 +{
544.1594 +   if (png_ptr == NULL) return (NULL);
544.1595 +   return png_ptr->io_ptr;
544.1596 +}
544.1597 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
   545.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   545.2 +++ b/libs/libpng/pngread.c	Sat Feb 01 19:58:19 2014 +0200
   545.3 @@ -0,0 +1,1459 @@
   545.4 +
   545.5 +/* pngread.c - read a PNG file
   545.6 + *
   545.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   545.8 + * For conditions of distribution and use, see copyright notice in png.h
   545.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  545.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  545.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  545.12 + *
  545.13 + * This file contains routines that an application calls directly to
  545.14 + * read a PNG file or stream.
  545.15 + */
  545.16 +
  545.17 +#define PNG_INTERNAL
  545.18 +#include "png.h"
  545.19 +#if defined(PNG_READ_SUPPORTED)
  545.20 +
  545.21 +/* Create a PNG structure for reading, and allocate any memory needed. */
  545.22 +png_structp PNGAPI
  545.23 +png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
  545.24 +   png_error_ptr error_fn, png_error_ptr warn_fn)
  545.25 +{
  545.26 +
  545.27 +#ifdef PNG_USER_MEM_SUPPORTED
  545.28 +   return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
  545.29 +      warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
  545.30 +}
  545.31 +
  545.32 +/* Alternate create PNG structure for reading, and allocate any memory needed. */
  545.33 +png_structp PNGAPI
  545.34 +png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
  545.35 +   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
  545.36 +   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
  545.37 +{
  545.38 +#endif /* PNG_USER_MEM_SUPPORTED */
  545.39 +
  545.40 +#ifdef PNG_SETJMP_SUPPORTED
  545.41 +   volatile
  545.42 +#endif
  545.43 +   png_structp png_ptr;
  545.44 +
  545.45 +#ifdef PNG_SETJMP_SUPPORTED
  545.46 +#ifdef USE_FAR_KEYWORD
  545.47 +   jmp_buf jmpbuf;
  545.48 +#endif
  545.49 +#endif
  545.50 +
  545.51 +   int i;
  545.52 +
  545.53 +   png_debug(1, "in png_create_read_struct\n");
  545.54 +#ifdef PNG_USER_MEM_SUPPORTED
  545.55 +   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
  545.56 +      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
  545.57 +#else
  545.58 +   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
  545.59 +#endif
  545.60 +   if (png_ptr == NULL)
  545.61 +      return (NULL);
  545.62 +
  545.63 +   /* added at libpng-1.2.6 */
  545.64 +#ifdef PNG_SET_USER_LIMITS_SUPPORTED
  545.65 +   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
  545.66 +   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
  545.67 +#endif
  545.68 +
  545.69 +#ifdef PNG_SETJMP_SUPPORTED
  545.70 +#ifdef USE_FAR_KEYWORD
  545.71 +   if (setjmp(jmpbuf))
  545.72 +#else
  545.73 +   if (setjmp(png_ptr->jmpbuf))
  545.74 +#endif
  545.75 +   {
  545.76 +      png_free(png_ptr, png_ptr->zbuf);
  545.77 +      png_ptr->zbuf = NULL;
  545.78 +#ifdef PNG_USER_MEM_SUPPORTED
  545.79 +      png_destroy_struct_2((png_voidp)png_ptr,
  545.80 +         (png_free_ptr)free_fn, (png_voidp)mem_ptr);
  545.81 +#else
  545.82 +      png_destroy_struct((png_voidp)png_ptr);
  545.83 +#endif
  545.84 +      return (NULL);
  545.85 +   }
  545.86 +#ifdef USE_FAR_KEYWORD
  545.87 +   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
  545.88 +#endif
  545.89 +#endif
  545.90 +
  545.91 +#ifdef PNG_USER_MEM_SUPPORTED
  545.92 +   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
  545.93 +#endif
  545.94 +
  545.95 +   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
  545.96 +
  545.97 +   if (user_png_ver)
  545.98 +   {
  545.99 +     i = 0;
 545.100 +     do
 545.101 +     {
 545.102 +       if (user_png_ver[i] != png_libpng_ver[i])
 545.103 +          png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
 545.104 +     } while (png_libpng_ver[i++]);
 545.105 +   }
 545.106 +   else
 545.107 +        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
 545.108 +   
 545.109 +
 545.110 +   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
 545.111 +   {
 545.112 +     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
 545.113 +      * we must recompile any applications that use any older library version.
 545.114 +      * For versions after libpng 1.0, we will be compatible, so we need
 545.115 +      * only check the first digit.
 545.116 +      */
 545.117 +     if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
 545.118 +         (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
 545.119 +         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
 545.120 +     {
 545.121 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
 545.122 +        char msg[80];
 545.123 +        if (user_png_ver)
 545.124 +        {
 545.125 +          png_snprintf(msg, 80,
 545.126 +             "Application was compiled with png.h from libpng-%.20s",
 545.127 +             user_png_ver);
 545.128 +          png_warning(png_ptr, msg);
 545.129 +        }
 545.130 +        png_snprintf(msg, 80,
 545.131 +             "Application  is  running with png.c from libpng-%.20s",
 545.132 +           png_libpng_ver);
 545.133 +        png_warning(png_ptr, msg);
 545.134 +#endif
 545.135 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
 545.136 +        png_ptr->flags = 0;
 545.137 +#endif
 545.138 +        png_error(png_ptr,
 545.139 +           "Incompatible libpng version in application and library");
 545.140 +     }
 545.141 +   }
 545.142 +
 545.143 +   /* initialize zbuf - compression buffer */
 545.144 +   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
 545.145 +   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
 545.146 +     (png_uint_32)png_ptr->zbuf_size);
 545.147 +   png_ptr->zstream.zalloc = png_zalloc;
 545.148 +   png_ptr->zstream.zfree = png_zfree;
 545.149 +   png_ptr->zstream.opaque = (voidpf)png_ptr;
 545.150 +
 545.151 +   switch (inflateInit(&png_ptr->zstream))
 545.152 +   {
 545.153 +     case Z_OK: /* Do nothing */ break;
 545.154 +     case Z_MEM_ERROR:
 545.155 +     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
 545.156 +     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
 545.157 +     default: png_error(png_ptr, "Unknown zlib error");
 545.158 +   }
 545.159 +
 545.160 +   png_ptr->zstream.next_out = png_ptr->zbuf;
 545.161 +   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
 545.162 +
 545.163 +   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
 545.164 +
 545.165 +#ifdef PNG_SETJMP_SUPPORTED
 545.166 +/* Applications that neglect to set up their own setjmp() and then encounter
 545.167 +   a png_error() will longjmp here.  Since the jmpbuf is then meaningless we
 545.168 +   abort instead of returning. */
 545.169 +#ifdef USE_FAR_KEYWORD
 545.170 +   if (setjmp(jmpbuf))
 545.171 +      PNG_ABORT();
 545.172 +   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
 545.173 +#else
 545.174 +   if (setjmp(png_ptr->jmpbuf))
 545.175 +      PNG_ABORT();
 545.176 +#endif
 545.177 +#endif
 545.178 +   return (png_ptr);
 545.179 +}
 545.180 +
 545.181 +#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
 545.182 +/* Initialize PNG structure for reading, and allocate any memory needed.
 545.183 +   This interface is deprecated in favour of the png_create_read_struct(),
 545.184 +   and it will disappear as of libpng-1.3.0. */
 545.185 +#undef png_read_init
 545.186 +void PNGAPI
 545.187 +png_read_init(png_structp png_ptr)
 545.188 +{
 545.189 +   /* We only come here via pre-1.0.7-compiled applications */
 545.190 +   png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
 545.191 +}
 545.192 +
 545.193 +void PNGAPI
 545.194 +png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
 545.195 +   png_size_t png_struct_size, png_size_t png_info_size)
 545.196 +{
 545.197 +   /* We only come here via pre-1.0.12-compiled applications */
 545.198 +   if (png_ptr == NULL) return;
 545.199 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
 545.200 +   if (png_sizeof(png_struct) > png_struct_size ||
 545.201 +      png_sizeof(png_info) > png_info_size)
 545.202 +   {
 545.203 +      char msg[80];
 545.204 +      png_ptr->warning_fn = NULL;
 545.205 +      if (user_png_ver)
 545.206 +      {
 545.207 +        png_snprintf(msg, 80,
 545.208 +           "Application was compiled with png.h from libpng-%.20s",
 545.209 +           user_png_ver);
 545.210 +        png_warning(png_ptr, msg);
 545.211 +      }
 545.212 +      png_snprintf(msg, 80,
 545.213 +         "Application  is  running with png.c from libpng-%.20s",
 545.214 +         png_libpng_ver);
 545.215 +      png_warning(png_ptr, msg);
 545.216 +   }
 545.217 +#endif
 545.218 +   if (png_sizeof(png_struct) > png_struct_size)
 545.219 +     {
 545.220 +       png_ptr->error_fn = NULL;
 545.221 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
 545.222 +       png_ptr->flags = 0;
 545.223 +#endif
 545.224 +       png_error(png_ptr,
 545.225 +       "The png struct allocated by the application for reading is too small.");
 545.226 +     }
 545.227 +   if (png_sizeof(png_info) > png_info_size)
 545.228 +     {
 545.229 +       png_ptr->error_fn = NULL;
 545.230 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
 545.231 +       png_ptr->flags = 0;
 545.232 +#endif
 545.233 +       png_error(png_ptr,
 545.234 +         "The info struct allocated by application for reading is too small.");
 545.235 +     }
 545.236 +   png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
 545.237 +}
 545.238 +#endif /* PNG_1_0_X || PNG_1_2_X */
 545.239 +
 545.240 +void PNGAPI
 545.241 +png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
 545.242 +   png_size_t png_struct_size)
 545.243 +{
 545.244 +#ifdef PNG_SETJMP_SUPPORTED
 545.245 +   jmp_buf tmp_jmp;  /* to save current jump buffer */
 545.246 +#endif
 545.247 +
 545.248 +   int i = 0;
 545.249 +
 545.250 +   png_structp png_ptr=*ptr_ptr;
 545.251 +
 545.252 +   if (png_ptr == NULL) return;
 545.253 +
 545.254 +   do
 545.255 +   {
 545.256 +     if (user_png_ver[i] != png_libpng_ver[i])
 545.257 +     {
 545.258 +#ifdef PNG_LEGACY_SUPPORTED
 545.259 +       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
 545.260 +#else
 545.261 +       png_ptr->warning_fn = NULL;
 545.262 +       png_warning(png_ptr,
 545.263 +        "Application uses deprecated png_read_init() and should be recompiled.");
 545.264 +       break;
 545.265 +#endif
 545.266 +     }
 545.267 +   } while (png_libpng_ver[i++]);
 545.268 +
 545.269 +   png_debug(1, "in png_read_init_3\n");
 545.270 +
 545.271 +#ifdef PNG_SETJMP_SUPPORTED
 545.272 +   /* save jump buffer and error functions */
 545.273 +   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
 545.274 +#endif
 545.275 +
 545.276 +   if (png_sizeof(png_struct) > png_struct_size)
 545.277 +   {
 545.278 +      png_destroy_struct(png_ptr);
 545.279 +      *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
 545.280 +      png_ptr = *ptr_ptr;
 545.281 +   }
 545.282 +
 545.283 +   /* reset all variables to 0 */
 545.284 +   png_memset(png_ptr, 0, png_sizeof(png_struct));
 545.285 +
 545.286 +#ifdef PNG_SETJMP_SUPPORTED
 545.287 +   /* restore jump buffer */
 545.288 +   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
 545.289 +#endif
 545.290 +
 545.291 +   /* added at libpng-1.2.6 */
 545.292 +#ifdef PNG_SET_USER_LIMITS_SUPPORTED
 545.293 +   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
 545.294 +   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
 545.295 +#endif
 545.296 +
 545.297 +   /* initialize zbuf - compression buffer */
 545.298 +   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
 545.299 +   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
 545.300 +     (png_uint_32)png_ptr->zbuf_size);
 545.301 +   png_ptr->zstream.zalloc = png_zalloc;
 545.302 +   png_ptr->zstream.zfree = png_zfree;
 545.303 +   png_ptr->zstream.opaque = (voidpf)png_ptr;
 545.304 +
 545.305 +   switch (inflateInit(&png_ptr->zstream))
 545.306 +   {
 545.307 +     case Z_OK: /* Do nothing */ break;
 545.308 +     case Z_MEM_ERROR:
 545.309 +     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
 545.310 +     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
 545.311 +     default: png_error(png_ptr, "Unknown zlib error");
 545.312 +   }
 545.313 +
 545.314 +   png_ptr->zstream.next_out = png_ptr->zbuf;
 545.315 +   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
 545.316 +
 545.317 +   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
 545.318 +}
 545.319 +
 545.320 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 545.321 +/* Read the information before the actual image data.  This has been
 545.322 + * changed in v0.90 to allow reading a file that already has the magic
 545.323 + * bytes read from the stream.  You can tell libpng how many bytes have
 545.324 + * been read from the beginning of the stream (up to the maximum of 8)
 545.325 + * via png_set_sig_bytes(), and we will only check the remaining bytes
 545.326 + * here.  The application can then have access to the signature bytes we
 545.327 + * read if it is determined that this isn't a valid PNG file.
 545.328 + */
 545.329 +void PNGAPI
 545.330 +png_read_info(png_structp png_ptr, png_infop info_ptr)
 545.331 +{
 545.332 +   if (png_ptr == NULL || info_ptr == NULL) return;
 545.333 +   png_debug(1, "in png_read_info\n");
 545.334 +   /* If we haven't checked all of the PNG signature bytes, do so now. */
 545.335 +   if (png_ptr->sig_bytes < 8)
 545.336 +   {
 545.337 +      png_size_t num_checked = png_ptr->sig_bytes,
 545.338 +                 num_to_check = 8 - num_checked;
 545.339 +
 545.340 +      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
 545.341 +      png_ptr->sig_bytes = 8;
 545.342 +
 545.343 +      if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
 545.344 +      {
 545.345 +         if (num_checked < 4 &&
 545.346 +             png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
 545.347 +            png_error(png_ptr, "Not a PNG file");
 545.348 +         else
 545.349 +            png_error(png_ptr, "PNG file corrupted by ASCII conversion");
 545.350 +      }
 545.351 +      if (num_checked < 3)
 545.352 +         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
 545.353 +   }
 545.354 +
 545.355 +   for (;;)
 545.356 +   {
 545.357 +#ifdef PNG_USE_LOCAL_ARRAYS
 545.358 +      PNG_CONST PNG_IHDR;
 545.359 +      PNG_CONST PNG_IDAT;
 545.360 +      PNG_CONST PNG_IEND;
 545.361 +      PNG_CONST PNG_PLTE;
 545.362 +#if defined(PNG_READ_bKGD_SUPPORTED)
 545.363 +      PNG_CONST PNG_bKGD;
 545.364 +#endif
 545.365 +#if defined(PNG_READ_cHRM_SUPPORTED)
 545.366 +      PNG_CONST PNG_cHRM;
 545.367 +#endif
 545.368 +#if defined(PNG_READ_gAMA_SUPPORTED)
 545.369 +      PNG_CONST PNG_gAMA;
 545.370 +#endif
 545.371 +#if defined(PNG_READ_hIST_SUPPORTED)
 545.372 +      PNG_CONST PNG_hIST;
 545.373 +#endif
 545.374 +#if defined(PNG_READ_iCCP_SUPPORTED)
 545.375 +      PNG_CONST PNG_iCCP;
 545.376 +#endif
 545.377 +#if defined(PNG_READ_iTXt_SUPPORTED)
 545.378 +      PNG_CONST PNG_iTXt;
 545.379 +#endif
 545.380 +#if defined(PNG_READ_oFFs_SUPPORTED)
 545.381 +      PNG_CONST PNG_oFFs;
 545.382 +#endif
 545.383 +#if defined(PNG_READ_pCAL_SUPPORTED)
 545.384 +      PNG_CONST PNG_pCAL;
 545.385 +#endif
 545.386 +#if defined(PNG_READ_pHYs_SUPPORTED)
 545.387 +      PNG_CONST PNG_pHYs;
 545.388 +#endif
 545.389 +#if defined(PNG_READ_sBIT_SUPPORTED)
 545.390 +      PNG_CONST PNG_sBIT;
 545.391 +#endif
 545.392 +#if defined(PNG_READ_sCAL_SUPPORTED)
 545.393 +      PNG_CONST PNG_sCAL;
 545.394 +#endif
 545.395 +#if defined(PNG_READ_sPLT_SUPPORTED)
 545.396 +      PNG_CONST PNG_sPLT;
 545.397 +#endif
 545.398 +#if defined(PNG_READ_sRGB_SUPPORTED)
 545.399 +      PNG_CONST PNG_sRGB;
 545.400 +#endif
 545.401 +#if defined(PNG_READ_tEXt_SUPPORTED)
 545.402 +      PNG_CONST PNG_tEXt;
 545.403 +#endif
 545.404 +#if defined(PNG_READ_tIME_SUPPORTED)
 545.405 +      PNG_CONST PNG_tIME;
 545.406 +#endif
 545.407 +#if defined(PNG_READ_tRNS_SUPPORTED)
 545.408 +      PNG_CONST PNG_tRNS;
 545.409 +#endif
 545.410 +#if defined(PNG_READ_zTXt_SUPPORTED)
 545.411 +      PNG_CONST PNG_zTXt;
 545.412 +#endif
 545.413 +#endif /* PNG_USE_LOCAL_ARRAYS */
 545.414 +      png_uint_32 length = png_read_chunk_header(png_ptr);
 545.415 +      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
 545.416 +
 545.417 +      /* This should be a binary subdivision search or a hash for
 545.418 +       * matching the chunk name rather than a linear search.
 545.419 +       */
 545.420 +      if (!png_memcmp(chunk_name, png_IDAT, 4))
 545.421 +        if (png_ptr->mode & PNG_AFTER_IDAT)
 545.422 +          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
 545.423 +
 545.424 +      if (!png_memcmp(chunk_name, png_IHDR, 4))
 545.425 +         png_handle_IHDR(png_ptr, info_ptr, length);
 545.426 +      else if (!png_memcmp(chunk_name, png_IEND, 4))
 545.427 +         png_handle_IEND(png_ptr, info_ptr, length);
 545.428 +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 545.429 +      else if (png_handle_as_unknown(png_ptr, chunk_name))
 545.430 +      {
 545.431 +         if (!png_memcmp(chunk_name, png_IDAT, 4))
 545.432 +            png_ptr->mode |= PNG_HAVE_IDAT;
 545.433 +         png_handle_unknown(png_ptr, info_ptr, length);
 545.434 +         if (!png_memcmp(chunk_name, png_PLTE, 4))
 545.435 +            png_ptr->mode |= PNG_HAVE_PLTE;
 545.436 +         else if (!png_memcmp(chunk_name, png_IDAT, 4))
 545.437 +         {
 545.438 +            if (!(png_ptr->mode & PNG_HAVE_IHDR))
 545.439 +               png_error(png_ptr, "Missing IHDR before IDAT");
 545.440 +            else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
 545.441 +                     !(png_ptr->mode & PNG_HAVE_PLTE))
 545.442 +               png_error(png_ptr, "Missing PLTE before IDAT");
 545.443 +            break;
 545.444 +         }
 545.445 +      }
 545.446 +#endif
 545.447 +      else if (!png_memcmp(chunk_name, png_PLTE, 4))
 545.448 +         png_handle_PLTE(png_ptr, info_ptr, length);
 545.449 +      else if (!png_memcmp(chunk_name, png_IDAT, 4))
 545.450 +      {
 545.451 +         if (!(png_ptr->mode & PNG_HAVE_IHDR))
 545.452 +            png_error(png_ptr, "Missing IHDR before IDAT");
 545.453 +         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
 545.454 +                  !(png_ptr->mode & PNG_HAVE_PLTE))
 545.455 +            png_error(png_ptr, "Missing PLTE before IDAT");
 545.456 +
 545.457 +         png_ptr->idat_size = length;
 545.458 +         png_ptr->mode |= PNG_HAVE_IDAT;
 545.459 +         break;
 545.460 +      }
 545.461 +#if defined(PNG_READ_bKGD_SUPPORTED)
 545.462 +      else if (!png_memcmp(chunk_name, png_bKGD, 4))
 545.463 +         png_handle_bKGD(png_ptr, info_ptr, length);
 545.464 +#endif
 545.465 +#if defined(PNG_READ_cHRM_SUPPORTED)
 545.466 +      else if (!png_memcmp(chunk_name, png_cHRM, 4))
 545.467 +         png_handle_cHRM(png_ptr, info_ptr, length);
 545.468 +#endif
 545.469 +#if defined(PNG_READ_gAMA_SUPPORTED)
 545.470 +      else if (!png_memcmp(chunk_name, png_gAMA, 4))
 545.471 +         png_handle_gAMA(png_ptr, info_ptr, length);
 545.472 +#endif
 545.473 +#if defined(PNG_READ_hIST_SUPPORTED)
 545.474 +      else if (!png_memcmp(chunk_name, png_hIST, 4))
 545.475 +         png_handle_hIST(png_ptr, info_ptr, length);
 545.476 +#endif
 545.477 +#if defined(PNG_READ_oFFs_SUPPORTED)
 545.478 +      else if (!png_memcmp(chunk_name, png_oFFs, 4))
 545.479 +         png_handle_oFFs(png_ptr, info_ptr, length);
 545.480 +#endif
 545.481 +#if defined(PNG_READ_pCAL_SUPPORTED)
 545.482 +      else if (!png_memcmp(chunk_name, png_pCAL, 4))
 545.483 +         png_handle_pCAL(png_ptr, info_ptr, length);
 545.484 +#endif
 545.485 +#if defined(PNG_READ_sCAL_SUPPORTED)
 545.486 +      else if (!png_memcmp(chunk_name, png_sCAL, 4))
 545.487 +         png_handle_sCAL(png_ptr, info_ptr, length);
 545.488 +#endif
 545.489 +#if defined(PNG_READ_pHYs_SUPPORTED)
 545.490 +      else if (!png_memcmp(chunk_name, png_pHYs, 4))
 545.491 +         png_handle_pHYs(png_ptr, info_ptr, length);
 545.492 +#endif
 545.493 +#if defined(PNG_READ_sBIT_SUPPORTED)
 545.494 +      else if (!png_memcmp(chunk_name, png_sBIT, 4))
 545.495 +         png_handle_sBIT(png_ptr, info_ptr, length);
 545.496 +#endif
 545.497 +#if defined(PNG_READ_sRGB_SUPPORTED)
 545.498 +      else if (!png_memcmp(chunk_name, png_sRGB, 4))
 545.499 +         png_handle_sRGB(png_ptr, info_ptr, length);
 545.500 +#endif
 545.501 +#if defined(PNG_READ_iCCP_SUPPORTED)
 545.502 +      else if (!png_memcmp(chunk_name, png_iCCP, 4))
 545.503 +         png_handle_iCCP(png_ptr, info_ptr, length);
 545.504 +#endif
 545.505 +#if defined(PNG_READ_sPLT_SUPPORTED)
 545.506 +      else if (!png_memcmp(chunk_name, png_sPLT, 4))
 545.507 +         png_handle_sPLT(png_ptr, info_ptr, length);
 545.508 +#endif
 545.509 +#if defined(PNG_READ_tEXt_SUPPORTED)
 545.510 +      else if (!png_memcmp(chunk_name, png_tEXt, 4))
 545.511 +         png_handle_tEXt(png_ptr, info_ptr, length);
 545.512 +#endif
 545.513 +#if defined(PNG_READ_tIME_SUPPORTED)
 545.514 +      else if (!png_memcmp(chunk_name, png_tIME, 4))
 545.515 +         png_handle_tIME(png_ptr, info_ptr, length);
 545.516 +#endif
 545.517 +#if defined(PNG_READ_tRNS_SUPPORTED)
 545.518 +      else if (!png_memcmp(chunk_name, png_tRNS, 4))
 545.519 +         png_handle_tRNS(png_ptr, info_ptr, length);
 545.520 +#endif
 545.521 +#if defined(PNG_READ_zTXt_SUPPORTED)
 545.522 +      else if (!png_memcmp(chunk_name, png_zTXt, 4))
 545.523 +         png_handle_zTXt(png_ptr, info_ptr, length);
 545.524 +#endif
 545.525 +#if defined(PNG_READ_iTXt_SUPPORTED)
 545.526 +      else if (!png_memcmp(chunk_name, png_iTXt, 4))
 545.527 +         png_handle_iTXt(png_ptr, info_ptr, length);
 545.528 +#endif
 545.529 +      else
 545.530 +         png_handle_unknown(png_ptr, info_ptr, length);
 545.531 +   }
 545.532 +}
 545.533 +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 545.534 +
 545.535 +/* optional call to update the users info_ptr structure */
 545.536 +void PNGAPI
 545.537 +png_read_update_info(png_structp png_ptr, png_infop info_ptr)
 545.538 +{
 545.539 +   png_debug(1, "in png_read_update_info\n");
 545.540 +   if (png_ptr == NULL) return;
 545.541 +   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
 545.542 +      png_read_start_row(png_ptr);
 545.543 +   else
 545.544 +      png_warning(png_ptr,
 545.545 +      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
 545.546 +   png_read_transform_info(png_ptr, info_ptr);
 545.547 +}
 545.548 +
 545.549 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 545.550 +/* Initialize palette, background, etc, after transformations
 545.551 + * are set, but before any reading takes place.  This allows
 545.552 + * the user to obtain a gamma-corrected palette, for example.
 545.553 + * If the user doesn't call this, we will do it ourselves.
 545.554 + */
 545.555 +void PNGAPI
 545.556 +png_start_read_image(png_structp png_ptr)
 545.557 +{
 545.558 +   png_debug(1, "in png_start_read_image\n");
 545.559 +   if (png_ptr == NULL) return;
 545.560 +   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
 545.561 +      png_read_start_row(png_ptr);
 545.562 +}
 545.563 +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 545.564 +
 545.565 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 545.566 +void PNGAPI
 545.567 +png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
 545.568 +{
 545.569 +#ifdef PNG_USE_LOCAL_ARRAYS
 545.570 +   PNG_CONST PNG_IDAT;
 545.571 +   PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
 545.572 +      0xff};
 545.573 +   PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
 545.574 +#endif
 545.575 +   int ret;
 545.576 +   if (png_ptr == NULL) return;
 545.577 +   png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
 545.578 +      png_ptr->row_number, png_ptr->pass);
 545.579 +   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
 545.580 +      png_read_start_row(png_ptr);
 545.581 +   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
 545.582 +   {
 545.583 +   /* check for transforms that have been set but were defined out */
 545.584 +#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
 545.585 +   if (png_ptr->transformations & PNG_INVERT_MONO)
 545.586 +      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
 545.587 +#endif
 545.588 +#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
 545.589 +   if (png_ptr->transformations & PNG_FILLER)
 545.590 +      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
 545.591 +#endif
 545.592 +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
 545.593 +   if (png_ptr->transformations & PNG_PACKSWAP)
 545.594 +      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
 545.595 +#endif
 545.596 +#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
 545.597 +   if (png_ptr->transformations & PNG_PACK)
 545.598 +      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
 545.599 +#endif
 545.600 +#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
 545.601 +   if (png_ptr->transformations & PNG_SHIFT)
 545.602 +      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
 545.603 +#endif
 545.604 +#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
 545.605 +   if (png_ptr->transformations & PNG_BGR)
 545.606 +      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
 545.607 +#endif
 545.608 +#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
 545.609 +   if (png_ptr->transformations & PNG_SWAP_BYTES)
 545.610 +      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
 545.611 +#endif
 545.612 +   }
 545.613 +
 545.614 +#if defined(PNG_READ_INTERLACING_SUPPORTED)
 545.615 +   /* if interlaced and we do not need a new row, combine row and return */
 545.616 +   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
 545.617 +   {
 545.618 +      switch (png_ptr->pass)
 545.619 +      {
 545.620 +         case 0:
 545.621 +            if (png_ptr->row_number & 0x07)
 545.622 +            {
 545.623 +               if (dsp_row != NULL)
 545.624 +                  png_combine_row(png_ptr, dsp_row,
 545.625 +                     png_pass_dsp_mask[png_ptr->pass]);
 545.626 +               png_read_finish_row(png_ptr);
 545.627 +               return;
 545.628 +            }
 545.629 +            break;
 545.630 +         case 1:
 545.631 +            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
 545.632 +            {
 545.633 +               if (dsp_row != NULL)
 545.634 +                  png_combine_row(png_ptr, dsp_row,
 545.635 +                     png_pass_dsp_mask[png_ptr->pass]);
 545.636 +               png_read_finish_row(png_ptr);
 545.637 +               return;
 545.638 +            }
 545.639 +            break;
 545.640 +         case 2:
 545.641 +            if ((png_ptr->row_number & 0x07) != 4)
 545.642 +            {
 545.643 +               if (dsp_row != NULL && (png_ptr->row_number & 4))
 545.644 +                  png_combine_row(png_ptr, dsp_row,
 545.645 +                     png_pass_dsp_mask[png_ptr->pass]);
 545.646 +               png_read_finish_row(png_ptr);
 545.647 +               return;
 545.648 +            }
 545.649 +            break;
 545.650 +         case 3:
 545.651 +            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
 545.652 +            {
 545.653 +               if (dsp_row != NULL)
 545.654 +                  png_combine_row(png_ptr, dsp_row,
 545.655 +                     png_pass_dsp_mask[png_ptr->pass]);
 545.656 +               png_read_finish_row(png_ptr);
 545.657 +               return;
 545.658 +            }
 545.659 +            break;
 545.660 +         case 4:
 545.661 +            if ((png_ptr->row_number & 3) != 2)
 545.662 +            {
 545.663 +               if (dsp_row != NULL && (png_ptr->row_number & 2))
 545.664 +                  png_combine_row(png_ptr, dsp_row,
 545.665 +                     png_pass_dsp_mask[png_ptr->pass]);
 545.666 +               png_read_finish_row(png_ptr);
 545.667 +               return;
 545.668 +            }
 545.669 +            break;
 545.670 +         case 5:
 545.671 +            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
 545.672 +            {
 545.673 +               if (dsp_row != NULL)
 545.674 +                  png_combine_row(png_ptr, dsp_row,
 545.675 +                     png_pass_dsp_mask[png_ptr->pass]);
 545.676 +               png_read_finish_row(png_ptr);
 545.677 +               return;
 545.678 +            }
 545.679 +            break;
 545.680 +         case 6:
 545.681 +            if (!(png_ptr->row_number & 1))
 545.682 +            {
 545.683 +               png_read_finish_row(png_ptr);
 545.684 +               return;
 545.685 +            }
 545.686 +            break;
 545.687 +      }
 545.688 +   }
 545.689 +#endif
 545.690 +
 545.691 +   if (!(png_ptr->mode & PNG_HAVE_IDAT))
 545.692 +      png_error(png_ptr, "Invalid attempt to read row data");
 545.693 +
 545.694 +   png_ptr->zstream.next_out = png_ptr->row_buf;
 545.695 +   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
 545.696 +   do
 545.697 +   {
 545.698 +      if (!(png_ptr->zstream.avail_in))
 545.699 +      {
 545.700 +         while (!png_ptr->idat_size)
 545.701 +         {
 545.702 +            png_crc_finish(png_ptr, 0);
 545.703 +
 545.704 +            png_ptr->idat_size = png_read_chunk_header(png_ptr);
 545.705 +            if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
 545.706 +               png_error(png_ptr, "Not enough image data");
 545.707 +         }
 545.708 +         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
 545.709 +         png_ptr->zstream.next_in = png_ptr->zbuf;
 545.710 +         if (png_ptr->zbuf_size > png_ptr->idat_size)
 545.711 +            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
 545.712 +         png_crc_read(png_ptr, png_ptr->zbuf,
 545.713 +            (png_size_t)png_ptr->zstream.avail_in);
 545.714 +         png_ptr->idat_size -= png_ptr->zstream.avail_in;
 545.715 +      }
 545.716 +      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
 545.717 +      if (ret == Z_STREAM_END)
 545.718 +      {
 545.719 +         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
 545.720 +            png_ptr->idat_size)
 545.721 +            png_error(png_ptr, "Extra compressed data");
 545.722 +         png_ptr->mode |= PNG_AFTER_IDAT;
 545.723 +         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
 545.724 +         break;
 545.725 +      }
 545.726 +      if (ret != Z_OK)
 545.727 +         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
 545.728 +                   "Decompression error");
 545.729 +
 545.730 +   } while (png_ptr->zstream.avail_out);
 545.731 +
 545.732 +   png_ptr->row_info.color_type = png_ptr->color_type;
 545.733 +   png_ptr->row_info.width = png_ptr->iwidth;
 545.734 +   png_ptr->row_info.channels = png_ptr->channels;
 545.735 +   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
 545.736 +   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
 545.737 +   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
 545.738 +       png_ptr->row_info.width);
 545.739 +
 545.740 +   if (png_ptr->row_buf[0])
 545.741 +   png_read_filter_row(png_ptr, &(png_ptr->row_info),
 545.742 +      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
 545.743 +      (int)(png_ptr->row_buf[0]));
 545.744 +
 545.745 +   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
 545.746 +      png_ptr->rowbytes + 1);
 545.747 +
 545.748 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
 545.749 +   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
 545.750 +      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
 545.751 +   {
 545.752 +      /* Intrapixel differencing */
 545.753 +      png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
 545.754 +   }
 545.755 +#endif
 545.756 +
 545.757 +
 545.758 +   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
 545.759 +      png_do_read_transformations(png_ptr);
 545.760 +
 545.761 +#if defined(PNG_READ_INTERLACING_SUPPORTED)
 545.762 +   /* blow up interlaced rows to full size */
 545.763 +   if (png_ptr->interlaced &&
 545.764 +      (png_ptr->transformations & PNG_INTERLACE))
 545.765 +   {
 545.766 +      if (png_ptr->pass < 6)
 545.767 +/*       old interface (pre-1.0.9):
 545.768 +         png_do_read_interlace(&(png_ptr->row_info),
 545.769 +            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
 545.770 + */
 545.771 +         png_do_read_interlace(png_ptr);
 545.772 +
 545.773 +      if (dsp_row != NULL)
 545.774 +         png_combine_row(png_ptr, dsp_row,
 545.775 +            png_pass_dsp_mask[png_ptr->pass]);
 545.776 +      if (row != NULL)
 545.777 +         png_combine_row(png_ptr, row,
 545.778 +            png_pass_mask[png_ptr->pass]);
 545.779 +   }
 545.780 +   else
 545.781 +#endif
 545.782 +   {
 545.783 +      if (row != NULL)
 545.784 +         png_combine_row(png_ptr, row, 0xff);
 545.785 +      if (dsp_row != NULL)
 545.786 +         png_combine_row(png_ptr, dsp_row, 0xff);
 545.787 +   }
 545.788 +   png_read_finish_row(png_ptr);
 545.789 +
 545.790 +   if (png_ptr->read_row_fn != NULL)
 545.791 +      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
 545.792 +}
 545.793 +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 545.794 +
 545.795 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 545.796 +/* Read one or more rows of image data.  If the image is interlaced,
 545.797 + * and png_set_interlace_handling() has been called, the rows need to
 545.798 + * contain the contents of the rows from the previous pass.  If the
 545.799 + * image has alpha or transparency, and png_handle_alpha()[*] has been
 545.800 + * called, the rows contents must be initialized to the contents of the
 545.801 + * screen.
 545.802 + *
 545.803 + * "row" holds the actual image, and pixels are placed in it
 545.804 + * as they arrive.  If the image is displayed after each pass, it will
 545.805 + * appear to "sparkle" in.  "display_row" can be used to display a
 545.806 + * "chunky" progressive image, with finer detail added as it becomes
 545.807 + * available.  If you do not want this "chunky" display, you may pass
 545.808 + * NULL for display_row.  If you do not want the sparkle display, and
 545.809 + * you have not called png_handle_alpha(), you may pass NULL for rows.
 545.810 + * If you have called png_handle_alpha(), and the image has either an
 545.811 + * alpha channel or a transparency chunk, you must provide a buffer for
 545.812 + * rows.  In this case, you do not have to provide a display_row buffer
 545.813 + * also, but you may.  If the image is not interlaced, or if you have
 545.814 + * not called png_set_interlace_handling(), the display_row buffer will
 545.815 + * be ignored, so pass NULL to it.
 545.816 + *
 545.817 + * [*] png_handle_alpha() does not exist yet, as of this version of libpng
 545.818 + */
 545.819 +
 545.820 +void PNGAPI
 545.821 +png_read_rows(png_structp png_ptr, png_bytepp row,
 545.822 +   png_bytepp display_row, png_uint_32 num_rows)
 545.823 +{
 545.824 +   png_uint_32 i;
 545.825 +   png_bytepp rp;
 545.826 +   png_bytepp dp;
 545.827 +
 545.828 +   png_debug(1, "in png_read_rows\n");
 545.829 +   if (png_ptr == NULL) return;
 545.830 +   rp = row;
 545.831 +   dp = display_row;
 545.832 +   if (rp != NULL && dp != NULL)
 545.833 +      for (i = 0; i < num_rows; i++)
 545.834 +      {
 545.835 +         png_bytep rptr = *rp++;
 545.836 +         png_bytep dptr = *dp++;
 545.837 +
 545.838 +         png_read_row(png_ptr, rptr, dptr);
 545.839 +      }
 545.840 +   else if (rp != NULL)
 545.841 +      for (i = 0; i < num_rows; i++)
 545.842 +      {
 545.843 +         png_bytep rptr = *rp;
 545.844 +         png_read_row(png_ptr, rptr, png_bytep_NULL);
 545.845 +         rp++;
 545.846 +      }
 545.847 +   else if (dp != NULL)
 545.848 +      for (i = 0; i < num_rows; i++)
 545.849 +      {
 545.850 +         png_bytep dptr = *dp;
 545.851 +         png_read_row(png_ptr, png_bytep_NULL, dptr);
 545.852 +         dp++;
 545.853 +      }
 545.854 +}
 545.855 +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 545.856 +
 545.857 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 545.858 +/* Read the entire image.  If the image has an alpha channel or a tRNS
 545.859 + * chunk, and you have called png_handle_alpha()[*], you will need to
 545.860 + * initialize the image to the current image that PNG will be overlaying.
 545.861 + * We set the num_rows again here, in case it was incorrectly set in
 545.862 + * png_read_start_row() by a call to png_read_update_info() or
 545.863 + * png_start_read_image() if png_set_interlace_handling() wasn't called
 545.864 + * prior to either of these functions like it should have been.  You can
 545.865 + * only call this function once.  If you desire to have an image for
 545.866 + * each pass of a interlaced image, use png_read_rows() instead.
 545.867 + *
 545.868 + * [*] png_handle_alpha() does not exist yet, as of this version of libpng
 545.869 + */
 545.870 +void PNGAPI
 545.871 +png_read_image(png_structp png_ptr, png_bytepp image)
 545.872 +{
 545.873 +   png_uint_32 i, image_height;
 545.874 +   int pass, j;
 545.875 +   png_bytepp rp;
 545.876 +
 545.877 +   png_debug(1, "in png_read_image\n");
 545.878 +   if (png_ptr == NULL) return;
 545.879 +
 545.880 +#ifdef PNG_READ_INTERLACING_SUPPORTED
 545.881 +   pass = png_set_interlace_handling(png_ptr);
 545.882 +#else
 545.883 +   if (png_ptr->interlaced)
 545.884 +      png_error(png_ptr,
 545.885 +        "Cannot read interlaced image -- interlace handler disabled.");
 545.886 +   pass = 1;
 545.887 +#endif
 545.888 +
 545.889 +
 545.890 +   image_height=png_ptr->height;
 545.891 +   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
 545.892 +
 545.893 +   for (j = 0; j < pass; j++)
 545.894 +   {
 545.895 +      rp = image;
 545.896 +      for (i = 0; i < image_height; i++)
 545.897 +      {
 545.898 +         png_read_row(png_ptr, *rp, png_bytep_NULL);
 545.899 +         rp++;
 545.900 +      }
 545.901 +   }
 545.902 +}
 545.903 +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 545.904 +
 545.905 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 545.906 +/* Read the end of the PNG file.  Will not read past the end of the
 545.907 + * file, will verify the end is accurate, and will read any comments
 545.908 + * or time information at the end of the file, if info is not NULL.
 545.909 + */
 545.910 +void PNGAPI
 545.911 +png_read_end(png_structp png_ptr, png_infop info_ptr)
 545.912 +{
 545.913 +   png_debug(1, "in png_read_end\n");
 545.914 +   if (png_ptr == NULL) return;
 545.915 +   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
 545.916 +
 545.917 +   do
 545.918 +   {
 545.919 +#ifdef PNG_USE_LOCAL_ARRAYS
 545.920 +      PNG_CONST PNG_IHDR;
 545.921 +      PNG_CONST PNG_IDAT;
 545.922 +      PNG_CONST PNG_IEND;
 545.923 +      PNG_CONST PNG_PLTE;
 545.924 +#if defined(PNG_READ_bKGD_SUPPORTED)
 545.925 +      PNG_CONST PNG_bKGD;
 545.926 +#endif
 545.927 +#if defined(PNG_READ_cHRM_SUPPORTED)
 545.928 +      PNG_CONST PNG_cHRM;
 545.929 +#endif
 545.930 +#if defined(PNG_READ_gAMA_SUPPORTED)
 545.931 +      PNG_CONST PNG_gAMA;
 545.932 +#endif
 545.933 +#if defined(PNG_READ_hIST_SUPPORTED)
 545.934 +      PNG_CONST PNG_hIST;
 545.935 +#endif
 545.936 +#if defined(PNG_READ_iCCP_SUPPORTED)
 545.937 +      PNG_CONST PNG_iCCP;
 545.938 +#endif
 545.939 +#if defined(PNG_READ_iTXt_SUPPORTED)
 545.940 +      PNG_CONST PNG_iTXt;
 545.941 +#endif
 545.942 +#if defined(PNG_READ_oFFs_SUPPORTED)
 545.943 +      PNG_CONST PNG_oFFs;
 545.944 +#endif
 545.945 +#if defined(PNG_READ_pCAL_SUPPORTED)
 545.946 +      PNG_CONST PNG_pCAL;
 545.947 +#endif
 545.948 +#if defined(PNG_READ_pHYs_SUPPORTED)
 545.949 +      PNG_CONST PNG_pHYs;
 545.950 +#endif
 545.951 +#if defined(PNG_READ_sBIT_SUPPORTED)
 545.952 +      PNG_CONST PNG_sBIT;
 545.953 +#endif
 545.954 +#if defined(PNG_READ_sCAL_SUPPORTED)
 545.955 +      PNG_CONST PNG_sCAL;
 545.956 +#endif
 545.957 +#if defined(PNG_READ_sPLT_SUPPORTED)
 545.958 +      PNG_CONST PNG_sPLT;
 545.959 +#endif
 545.960 +#if defined(PNG_READ_sRGB_SUPPORTED)
 545.961 +      PNG_CONST PNG_sRGB;
 545.962 +#endif
 545.963 +#if defined(PNG_READ_tEXt_SUPPORTED)
 545.964 +      PNG_CONST PNG_tEXt;
 545.965 +#endif
 545.966 +#if defined(PNG_READ_tIME_SUPPORTED)
 545.967 +      PNG_CONST PNG_tIME;
 545.968 +#endif
 545.969 +#if defined(PNG_READ_tRNS_SUPPORTED)
 545.970 +      PNG_CONST PNG_tRNS;
 545.971 +#endif
 545.972 +#if defined(PNG_READ_zTXt_SUPPORTED)
 545.973 +      PNG_CONST PNG_zTXt;
 545.974 +#endif
 545.975 +#endif /* PNG_USE_LOCAL_ARRAYS */
 545.976 +      png_uint_32 length = png_read_chunk_header(png_ptr);
 545.977 +      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
 545.978 +
 545.979 +      if (!png_memcmp(chunk_name, png_IHDR, 4))
 545.980 +         png_handle_IHDR(png_ptr, info_ptr, length);
 545.981 +      else if (!png_memcmp(chunk_name, png_IEND, 4))
 545.982 +         png_handle_IEND(png_ptr, info_ptr, length);
 545.983 +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 545.984 +      else if (png_handle_as_unknown(png_ptr, chunk_name))
 545.985 +      {
 545.986 +         if (!png_memcmp(chunk_name, png_IDAT, 4))
 545.987 +         {
 545.988 +            if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
 545.989 +               png_error(png_ptr, "Too many IDAT's found");
 545.990 +         }
 545.991 +         png_handle_unknown(png_ptr, info_ptr, length);
 545.992 +         if (!png_memcmp(chunk_name, png_PLTE, 4))
 545.993 +            png_ptr->mode |= PNG_HAVE_PLTE;
 545.994 +      }
 545.995 +#endif
 545.996 +      else if (!png_memcmp(chunk_name, png_IDAT, 4))
 545.997 +      {
 545.998 +         /* Zero length IDATs are legal after the last IDAT has been
 545.999 +          * read, but not after other chunks have been read.
545.1000 +          */
545.1001 +         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
545.1002 +            png_error(png_ptr, "Too many IDAT's found");
545.1003 +         png_crc_finish(png_ptr, length);
545.1004 +      }
545.1005 +      else if (!png_memcmp(chunk_name, png_PLTE, 4))
545.1006 +         png_handle_PLTE(png_ptr, info_ptr, length);
545.1007 +#if defined(PNG_READ_bKGD_SUPPORTED)
545.1008 +      else if (!png_memcmp(chunk_name, png_bKGD, 4))
545.1009 +         png_handle_bKGD(png_ptr, info_ptr, length);
545.1010 +#endif
545.1011 +#if defined(PNG_READ_cHRM_SUPPORTED)
545.1012 +      else if (!png_memcmp(chunk_name, png_cHRM, 4))
545.1013 +         png_handle_cHRM(png_ptr, info_ptr, length);
545.1014 +#endif
545.1015 +#if defined(PNG_READ_gAMA_SUPPORTED)
545.1016 +      else if (!png_memcmp(chunk_name, png_gAMA, 4))
545.1017 +         png_handle_gAMA(png_ptr, info_ptr, length);
545.1018 +#endif
545.1019 +#if defined(PNG_READ_hIST_SUPPORTED)
545.1020 +      else if (!png_memcmp(chunk_name, png_hIST, 4))
545.1021 +         png_handle_hIST(png_ptr, info_ptr, length);
545.1022 +#endif
545.1023 +#if defined(PNG_READ_oFFs_SUPPORTED)
545.1024 +      else if (!png_memcmp(chunk_name, png_oFFs, 4))
545.1025 +         png_handle_oFFs(png_ptr, info_ptr, length);
545.1026 +#endif
545.1027 +#if defined(PNG_READ_pCAL_SUPPORTED)
545.1028 +      else if (!png_memcmp(chunk_name, png_pCAL, 4))
545.1029 +         png_handle_pCAL(png_ptr, info_ptr, length);
545.1030 +#endif
545.1031 +#if defined(PNG_READ_sCAL_SUPPORTED)
545.1032 +      else if (!png_memcmp(chunk_name, png_sCAL, 4))
545.1033 +         png_handle_sCAL(png_ptr, info_ptr, length);
545.1034 +#endif
545.1035 +#if defined(PNG_READ_pHYs_SUPPORTED)
545.1036 +      else if (!png_memcmp(chunk_name, png_pHYs, 4))
545.1037 +         png_handle_pHYs(png_ptr, info_ptr, length);
545.1038 +#endif
545.1039 +#if defined(PNG_READ_sBIT_SUPPORTED)
545.1040 +      else if (!png_memcmp(chunk_name, png_sBIT, 4))
545.1041 +         png_handle_sBIT(png_ptr, info_ptr, length);
545.1042 +#endif
545.1043 +#if defined(PNG_READ_sRGB_SUPPORTED)
545.1044 +      else if (!png_memcmp(chunk_name, png_sRGB, 4))
545.1045 +         png_handle_sRGB(png_ptr, info_ptr, length);
545.1046 +#endif
545.1047 +#if defined(PNG_READ_iCCP_SUPPORTED)
545.1048 +      else if (!png_memcmp(chunk_name, png_iCCP, 4))
545.1049 +         png_handle_iCCP(png_ptr, info_ptr, length);
545.1050 +#endif
545.1051 +#if defined(PNG_READ_sPLT_SUPPORTED)
545.1052 +      else if (!png_memcmp(chunk_name, png_sPLT, 4))
545.1053 +         png_handle_sPLT(png_ptr, info_ptr, length);
545.1054 +#endif
545.1055 +#if defined(PNG_READ_tEXt_SUPPORTED)
545.1056 +      else if (!png_memcmp(chunk_name, png_tEXt, 4))
545.1057 +         png_handle_tEXt(png_ptr, info_ptr, length);
545.1058 +#endif
545.1059 +#if defined(PNG_READ_tIME_SUPPORTED)
545.1060 +      else if (!png_memcmp(chunk_name, png_tIME, 4))
545.1061 +         png_handle_tIME(png_ptr, info_ptr, length);
545.1062 +#endif
545.1063 +#if defined(PNG_READ_tRNS_SUPPORTED)
545.1064 +      else if (!png_memcmp(chunk_name, png_tRNS, 4))
545.1065 +         png_handle_tRNS(png_ptr, info_ptr, length);
545.1066 +#endif
545.1067 +#if defined(PNG_READ_zTXt_SUPPORTED)
545.1068 +      else if (!png_memcmp(chunk_name, png_zTXt, 4))
545.1069 +         png_handle_zTXt(png_ptr, info_ptr, length);
545.1070 +#endif
545.1071 +#if defined(PNG_READ_iTXt_SUPPORTED)
545.1072 +      else if (!png_memcmp(chunk_name, png_iTXt, 4))
545.1073 +         png_handle_iTXt(png_ptr, info_ptr, length);
545.1074 +#endif
545.1075 +      else
545.1076 +         png_handle_unknown(png_ptr, info_ptr, length);
545.1077 +   } while (!(png_ptr->mode & PNG_HAVE_IEND));
545.1078 +}
545.1079 +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
545.1080 +
545.1081 +/* free all memory used by the read */
545.1082 +void PNGAPI
545.1083 +png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
545.1084 +   png_infopp end_info_ptr_ptr)
545.1085 +{
545.1086 +   png_structp png_ptr = NULL;
545.1087 +   png_infop info_ptr = NULL, end_info_ptr = NULL;
545.1088 +#ifdef PNG_USER_MEM_SUPPORTED
545.1089 +   png_free_ptr free_fn = NULL;
545.1090 +   png_voidp mem_ptr = NULL;
545.1091 +#endif
545.1092 +
545.1093 +   png_debug(1, "in png_destroy_read_struct\n");
545.1094 +   if (png_ptr_ptr != NULL)
545.1095 +      png_ptr = *png_ptr_ptr;
545.1096 +   if (png_ptr == NULL)
545.1097 +      return;
545.1098 +
545.1099 +#ifdef PNG_USER_MEM_SUPPORTED
545.1100 +   free_fn = png_ptr->free_fn;
545.1101 +   mem_ptr = png_ptr->mem_ptr;
545.1102 +#endif
545.1103 +
545.1104 +   if (info_ptr_ptr != NULL)
545.1105 +      info_ptr = *info_ptr_ptr;
545.1106 +
545.1107 +   if (end_info_ptr_ptr != NULL)
545.1108 +      end_info_ptr = *end_info_ptr_ptr;
545.1109 +
545.1110 +   png_read_destroy(png_ptr, info_ptr, end_info_ptr);
545.1111 +
545.1112 +   if (info_ptr != NULL)
545.1113 +   {
545.1114 +#if defined(PNG_TEXT_SUPPORTED)
545.1115 +      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
545.1116 +#endif
545.1117 +
545.1118 +#ifdef PNG_USER_MEM_SUPPORTED
545.1119 +      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
545.1120 +          (png_voidp)mem_ptr);
545.1121 +#else
545.1122 +      png_destroy_struct((png_voidp)info_ptr);
545.1123 +#endif
545.1124 +      *info_ptr_ptr = NULL;
545.1125 +   }
545.1126 +
545.1127 +   if (end_info_ptr != NULL)
545.1128 +   {
545.1129 +#if defined(PNG_READ_TEXT_SUPPORTED)
545.1130 +      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
545.1131 +#endif
545.1132 +#ifdef PNG_USER_MEM_SUPPORTED
545.1133 +      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
545.1134 +         (png_voidp)mem_ptr);
545.1135 +#else
545.1136 +      png_destroy_struct((png_voidp)end_info_ptr);
545.1137 +#endif
545.1138 +      *end_info_ptr_ptr = NULL;
545.1139 +   }
545.1140 +
545.1141 +   if (png_ptr != NULL)
545.1142 +   {
545.1143 +#ifdef PNG_USER_MEM_SUPPORTED
545.1144 +      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
545.1145 +          (png_voidp)mem_ptr);
545.1146 +#else
545.1147 +      png_destroy_struct((png_voidp)png_ptr);
545.1148 +#endif
545.1149 +      *png_ptr_ptr = NULL;
545.1150 +   }
545.1151 +}
545.1152 +
545.1153 +/* free all memory used by the read (old method) */
545.1154 +void /* PRIVATE */
545.1155 +png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
545.1156 +{
545.1157 +#ifdef PNG_SETJMP_SUPPORTED
545.1158 +   jmp_buf tmp_jmp;
545.1159 +#endif
545.1160 +   png_error_ptr error_fn;
545.1161 +   png_error_ptr warning_fn;
545.1162 +   png_voidp error_ptr;
545.1163 +#ifdef PNG_USER_MEM_SUPPORTED
545.1164 +   png_free_ptr free_fn;
545.1165 +#endif
545.1166 +
545.1167 +   png_debug(1, "in png_read_destroy\n");
545.1168 +   if (info_ptr != NULL)
545.1169 +      png_info_destroy(png_ptr, info_ptr);
545.1170 +
545.1171 +   if (end_info_ptr != NULL)
545.1172 +      png_info_destroy(png_ptr, end_info_ptr);
545.1173 +
545.1174 +   png_free(png_ptr, png_ptr->zbuf);
545.1175 +   png_free(png_ptr, png_ptr->big_row_buf);
545.1176 +   png_free(png_ptr, png_ptr->prev_row);
545.1177 +   png_free(png_ptr, png_ptr->chunkdata);
545.1178 +#if defined(PNG_READ_DITHER_SUPPORTED)
545.1179 +   png_free(png_ptr, png_ptr->palette_lookup);
545.1180 +   png_free(png_ptr, png_ptr->dither_index);
545.1181 +#endif
545.1182 +#if defined(PNG_READ_GAMMA_SUPPORTED)
545.1183 +   png_free(png_ptr, png_ptr->gamma_table);
545.1184 +#endif
545.1185 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
545.1186 +   png_free(png_ptr, png_ptr->gamma_from_1);
545.1187 +   png_free(png_ptr, png_ptr->gamma_to_1);
545.1188 +#endif
545.1189 +#ifdef PNG_FREE_ME_SUPPORTED
545.1190 +   if (png_ptr->free_me & PNG_FREE_PLTE)
545.1191 +      png_zfree(png_ptr, png_ptr->palette);
545.1192 +   png_ptr->free_me &= ~PNG_FREE_PLTE;
545.1193 +#else
545.1194 +   if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
545.1195 +      png_zfree(png_ptr, png_ptr->palette);
545.1196 +   png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
545.1197 +#endif
545.1198 +#if defined(PNG_tRNS_SUPPORTED) || \
545.1199 +    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
545.1200 +#ifdef PNG_FREE_ME_SUPPORTED
545.1201 +   if (png_ptr->free_me & PNG_FREE_TRNS)
545.1202 +      png_free(png_ptr, png_ptr->trans);
545.1203 +   png_ptr->free_me &= ~PNG_FREE_TRNS;
545.1204 +#else
545.1205 +   if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
545.1206 +      png_free(png_ptr, png_ptr->trans);
545.1207 +   png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
545.1208 +#endif
545.1209 +#endif
545.1210 +#if defined(PNG_READ_hIST_SUPPORTED)
545.1211 +#ifdef PNG_FREE_ME_SUPPORTED
545.1212 +   if (png_ptr->free_me & PNG_FREE_HIST)
545.1213 +      png_free(png_ptr, png_ptr->hist);
545.1214 +   png_ptr->free_me &= ~PNG_FREE_HIST;
545.1215 +#else
545.1216 +   if (png_ptr->flags & PNG_FLAG_FREE_HIST)
545.1217 +      png_free(png_ptr, png_ptr->hist);
545.1218 +   png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
545.1219 +#endif
545.1220 +#endif
545.1221 +#if defined(PNG_READ_GAMMA_SUPPORTED)
545.1222 +   if (png_ptr->gamma_16_table != NULL)
545.1223 +   {
545.1224 +      int i;
545.1225 +      int istop = (1 << (8 - png_ptr->gamma_shift));
545.1226 +      for (i = 0; i < istop; i++)
545.1227 +      {
545.1228 +         png_free(png_ptr, png_ptr->gamma_16_table[i]);
545.1229 +      }
545.1230 +   png_free(png_ptr, png_ptr->gamma_16_table);
545.1231 +   }
545.1232 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
545.1233 +   if (png_ptr->gamma_16_from_1 != NULL)
545.1234 +   {
545.1235 +      int i;
545.1236 +      int istop = (1 << (8 - png_ptr->gamma_shift));
545.1237 +      for (i = 0; i < istop; i++)
545.1238 +      {
545.1239 +         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
545.1240 +      }
545.1241 +   png_free(png_ptr, png_ptr->gamma_16_from_1);
545.1242 +   }
545.1243 +   if (png_ptr->gamma_16_to_1 != NULL)
545.1244 +   {
545.1245 +      int i;
545.1246 +      int istop = (1 << (8 - png_ptr->gamma_shift));
545.1247 +      for (i = 0; i < istop; i++)
545.1248 +      {
545.1249 +         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
545.1250 +      }
545.1251 +   png_free(png_ptr, png_ptr->gamma_16_to_1);
545.1252 +   }
545.1253 +#endif
545.1254 +#endif
545.1255 +#if defined(PNG_TIME_RFC1123_SUPPORTED)
545.1256 +   png_free(png_ptr, png_ptr->time_buffer);
545.1257 +#endif
545.1258 +
545.1259 +   inflateEnd(&png_ptr->zstream);
545.1260 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
545.1261 +   png_free(png_ptr, png_ptr->save_buffer);
545.1262 +#endif
545.1263 +
545.1264 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
545.1265 +#ifdef PNG_TEXT_SUPPORTED
545.1266 +   png_free(png_ptr, png_ptr->current_text);
545.1267 +#endif /* PNG_TEXT_SUPPORTED */
545.1268 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
545.1269 +
545.1270 +   /* Save the important info out of the png_struct, in case it is
545.1271 +    * being used again.
545.1272 +    */
545.1273 +#ifdef PNG_SETJMP_SUPPORTED
545.1274 +   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
545.1275 +#endif
545.1276 +
545.1277 +   error_fn = png_ptr->error_fn;
545.1278 +   warning_fn = png_ptr->warning_fn;
545.1279 +   error_ptr = png_ptr->error_ptr;
545.1280 +#ifdef PNG_USER_MEM_SUPPORTED
545.1281 +   free_fn = png_ptr->free_fn;
545.1282 +#endif
545.1283 +
545.1284 +   png_memset(png_ptr, 0, png_sizeof(png_struct));
545.1285 +
545.1286 +   png_ptr->error_fn = error_fn;
545.1287 +   png_ptr->warning_fn = warning_fn;
545.1288 +   png_ptr->error_ptr = error_ptr;
545.1289 +#ifdef PNG_USER_MEM_SUPPORTED
545.1290 +   png_ptr->free_fn = free_fn;
545.1291 +#endif
545.1292 +
545.1293 +#ifdef PNG_SETJMP_SUPPORTED
545.1294 +   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
545.1295 +#endif
545.1296 +
545.1297 +}
545.1298 +
545.1299 +void PNGAPI
545.1300 +png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
545.1301 +{
545.1302 +   if (png_ptr == NULL) return;
545.1303 +   png_ptr->read_row_fn = read_row_fn;
545.1304 +}
545.1305 +
545.1306 +
545.1307 +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
545.1308 +#if defined(PNG_INFO_IMAGE_SUPPORTED)
545.1309 +void PNGAPI
545.1310 +png_read_png(png_structp png_ptr, png_infop info_ptr,
545.1311 +                           int transforms,
545.1312 +                           voidp params)
545.1313 +{
545.1314 +   int row;
545.1315 +
545.1316 +   if (png_ptr == NULL) return;
545.1317 +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
545.1318 +   /* invert the alpha channel from opacity to transparency
545.1319 +    */
545.1320 +   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
545.1321 +       png_set_invert_alpha(png_ptr);
545.1322 +#endif
545.1323 +
545.1324 +   /* png_read_info() gives us all of the information from the
545.1325 +    * PNG file before the first IDAT (image data chunk).
545.1326 +    */
545.1327 +   png_read_info(png_ptr, info_ptr);
545.1328 +   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
545.1329 +      png_error(png_ptr, "Image is too high to process with png_read_png()");
545.1330 +
545.1331 +   /* -------------- image transformations start here ------------------- */
545.1332 +
545.1333 +#if defined(PNG_READ_16_TO_8_SUPPORTED)
545.1334 +   /* tell libpng to strip 16 bit/color files down to 8 bits per color
545.1335 +    */
545.1336 +   if (transforms & PNG_TRANSFORM_STRIP_16)
545.1337 +       png_set_strip_16(png_ptr);
545.1338 +#endif
545.1339 +
545.1340 +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
545.1341 +   /* Strip alpha bytes from the input data without combining with
545.1342 +    * the background (not recommended).
545.1343 +    */
545.1344 +   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
545.1345 +       png_set_strip_alpha(png_ptr);
545.1346 +#endif
545.1347 +
545.1348 +#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
545.1349 +   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
545.1350 +    * byte into separate bytes (useful for paletted and grayscale images).
545.1351 +    */
545.1352 +   if (transforms & PNG_TRANSFORM_PACKING)
545.1353 +       png_set_packing(png_ptr);
545.1354 +#endif
545.1355 +
545.1356 +#if defined(PNG_READ_PACKSWAP_SUPPORTED)
545.1357 +   /* Change the order of packed pixels to least significant bit first
545.1358 +    * (not useful if you are using png_set_packing).
545.1359 +    */
545.1360 +   if (transforms & PNG_TRANSFORM_PACKSWAP)
545.1361 +       png_set_packswap(png_ptr);
545.1362 +#endif
545.1363 +
545.1364 +#if defined(PNG_READ_EXPAND_SUPPORTED)
545.1365 +   /* Expand paletted colors into true RGB triplets
545.1366 +    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
545.1367 +    * Expand paletted or RGB images with transparency to full alpha
545.1368 +    * channels so the data will be available as RGBA quartets.
545.1369 +    */
545.1370 +   if (transforms & PNG_TRANSFORM_EXPAND)
545.1371 +       if ((png_ptr->bit_depth < 8) ||
545.1372 +           (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
545.1373 +           (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
545.1374 +         png_set_expand(png_ptr);
545.1375 +#endif
545.1376 +
545.1377 +   /* We don't handle background color or gamma transformation or dithering.
545.1378 +    */
545.1379 +
545.1380 +#if defined(PNG_READ_INVERT_SUPPORTED)
545.1381 +   /* invert monochrome files to have 0 as white and 1 as black
545.1382 +    */
545.1383 +   if (transforms & PNG_TRANSFORM_INVERT_MONO)
545.1384 +       png_set_invert_mono(png_ptr);
545.1385 +#endif
545.1386 +
545.1387 +#if defined(PNG_READ_SHIFT_SUPPORTED)
545.1388 +   /* If you want to shift the pixel values from the range [0,255] or
545.1389 +    * [0,65535] to the original [0,7] or [0,31], or whatever range the
545.1390 +    * colors were originally in:
545.1391 +    */
545.1392 +   if ((transforms & PNG_TRANSFORM_SHIFT)
545.1393 +       && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
545.1394 +   {
545.1395 +      png_color_8p sig_bit;
545.1396 +
545.1397 +      png_get_sBIT(png_ptr, info_ptr, &sig_bit);
545.1398 +      png_set_shift(png_ptr, sig_bit);
545.1399 +   }
545.1400 +#endif
545.1401 +
545.1402 +#if defined(PNG_READ_BGR_SUPPORTED)
545.1403 +   /* flip the RGB pixels to BGR (or RGBA to BGRA)
545.1404 +    */
545.1405 +   if (transforms & PNG_TRANSFORM_BGR)
545.1406 +       png_set_bgr(png_ptr);
545.1407 +#endif
545.1408 +
545.1409 +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
545.1410 +   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
545.1411 +    */
545.1412 +   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
545.1413 +       png_set_swap_alpha(png_ptr);
545.1414 +#endif
545.1415 +
545.1416 +#if defined(PNG_READ_SWAP_SUPPORTED)
545.1417 +   /* swap bytes of 16 bit files to least significant byte first
545.1418 +    */
545.1419 +   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
545.1420 +       png_set_swap(png_ptr);
545.1421 +#endif
545.1422 +
545.1423 +   /* We don't handle adding filler bytes */
545.1424 +
545.1425 +   /* Optional call to gamma correct and add the background to the palette
545.1426 +    * and update info structure.  REQUIRED if you are expecting libpng to
545.1427 +    * update the palette for you (i.e., you selected such a transform above).
545.1428 +    */
545.1429 +   png_read_update_info(png_ptr, info_ptr);
545.1430 +
545.1431 +   /* -------------- image transformations end here ------------------- */
545.1432 +
545.1433 +#ifdef PNG_FREE_ME_SUPPORTED
545.1434 +   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
545.1435 +#endif
545.1436 +   if (info_ptr->row_pointers == NULL)
545.1437 +   {
545.1438 +      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
545.1439 +         info_ptr->height * png_sizeof(png_bytep));
545.1440 +#ifdef PNG_FREE_ME_SUPPORTED
545.1441 +      info_ptr->free_me |= PNG_FREE_ROWS;
545.1442 +#endif
545.1443 +      for (row = 0; row < (int)info_ptr->height; row++)
545.1444 +      {
545.1445 +         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
545.1446 +            png_get_rowbytes(png_ptr, info_ptr));
545.1447 +      }
545.1448 +   }
545.1449 +
545.1450 +   png_read_image(png_ptr, info_ptr->row_pointers);
545.1451 +   info_ptr->valid |= PNG_INFO_IDAT;
545.1452 +
545.1453 +   /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
545.1454 +   png_read_end(png_ptr, info_ptr);
545.1455 +
545.1456 +   transforms = transforms; /* quiet compiler warnings */
545.1457 +   params = params;
545.1458 +
545.1459 +}
545.1460 +#endif /* PNG_INFO_IMAGE_SUPPORTED */
545.1461 +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
545.1462 +#endif /* PNG_READ_SUPPORTED */
   546.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   546.2 +++ b/libs/libpng/pngrio.c	Sat Feb 01 19:58:19 2014 +0200
   546.3 @@ -0,0 +1,166 @@
   546.4 +
   546.5 +/* pngrio.c - functions for data input
   546.6 + *
   546.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   546.8 + * For conditions of distribution and use, see copyright notice in png.h
   546.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  546.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  546.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  546.12 + *
  546.13 + * This file provides a location for all input.  Users who need
  546.14 + * special handling are expected to write a function that has the same
  546.15 + * arguments as this and performs a similar function, but that possibly
  546.16 + * has a different input method.  Note that you shouldn't change this
  546.17 + * function, but rather write a replacement function and then make
  546.18 + * libpng use it at run time with png_set_read_fn(...).
  546.19 + */
  546.20 +
  546.21 +#define PNG_INTERNAL
  546.22 +#include "png.h"
  546.23 +#if defined(PNG_READ_SUPPORTED)
  546.24 +
  546.25 +/* Read the data from whatever input you are using.  The default routine
  546.26 +   reads from a file pointer.  Note that this routine sometimes gets called
  546.27 +   with very small lengths, so you should implement some kind of simple
  546.28 +   buffering if you are using unbuffered reads.  This should never be asked
  546.29 +   to read more then 64K on a 16 bit machine. */
  546.30 +void /* PRIVATE */
  546.31 +png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
  546.32 +{
  546.33 +   png_debug1(4, "reading %d bytes\n", (int)length);
  546.34 +   if (png_ptr->read_data_fn != NULL)
  546.35 +      (*(png_ptr->read_data_fn))(png_ptr, data, length);
  546.36 +   else
  546.37 +      png_error(png_ptr, "Call to NULL read function");
  546.38 +}
  546.39 +
  546.40 +#if !defined(PNG_NO_STDIO)
  546.41 +/* This is the function that does the actual reading of data.  If you are
  546.42 +   not reading from a standard C stream, you should create a replacement
  546.43 +   read_data function and use it at run time with png_set_read_fn(), rather
  546.44 +   than changing the library. */
  546.45 +#ifndef USE_FAR_KEYWORD
  546.46 +void PNGAPI
  546.47 +png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
  546.48 +{
  546.49 +   png_size_t check;
  546.50 +
  546.51 +   if (png_ptr == NULL) return;
  546.52 +   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
  546.53 +    * instead of an int, which is what fread() actually returns.
  546.54 +    */
  546.55 +#if defined(_WIN32_WCE)
  546.56 +   if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
  546.57 +      check = 0;
  546.58 +#else
  546.59 +   check = (png_size_t)fread(data, (png_size_t)1, length,
  546.60 +      (png_FILE_p)png_ptr->io_ptr);
  546.61 +#endif
  546.62 +
  546.63 +   if (check != length)
  546.64 +      png_error(png_ptr, "Read Error");
  546.65 +}
  546.66 +#else
  546.67 +/* this is the model-independent version. Since the standard I/O library
  546.68 +   can't handle far buffers in the medium and small models, we have to copy
  546.69 +   the data.
  546.70 +*/
  546.71 +
  546.72 +#define NEAR_BUF_SIZE 1024
  546.73 +#define MIN(a,b) (a <= b ? a : b)
  546.74 +
  546.75 +static void PNGAPI
  546.76 +png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
  546.77 +{
  546.78 +   int check;
  546.79 +   png_byte *n_data;
  546.80 +   png_FILE_p io_ptr;
  546.81 +
  546.82 +   if (png_ptr == NULL) return;
  546.83 +   /* Check if data really is near. If so, use usual code. */
  546.84 +   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
  546.85 +   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
  546.86 +   if ((png_bytep)n_data == data)
  546.87 +   {
  546.88 +#if defined(_WIN32_WCE)
  546.89 +      if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
  546.90 +         check = 0;
  546.91 +#else
  546.92 +      check = fread(n_data, 1, length, io_ptr);
  546.93 +#endif
  546.94 +   }
  546.95 +   else
  546.96 +   {
  546.97 +      png_byte buf[NEAR_BUF_SIZE];
  546.98 +      png_size_t read, remaining, err;
  546.99 +      check = 0;
 546.100 +      remaining = length;
 546.101 +      do
 546.102 +      {
 546.103 +         read = MIN(NEAR_BUF_SIZE, remaining);
 546.104 +#if defined(_WIN32_WCE)
 546.105 +         if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
 546.106 +            err = 0;
 546.107 +#else
 546.108 +         err = fread(buf, (png_size_t)1, read, io_ptr);
 546.109 +#endif
 546.110 +         png_memcpy(data, buf, read); /* copy far buffer to near buffer */
 546.111 +         if (err != read)
 546.112 +            break;
 546.113 +         else
 546.114 +            check += err;
 546.115 +         data += read;
 546.116 +         remaining -= read;
 546.117 +      }
 546.118 +      while (remaining != 0);
 546.119 +   }
 546.120 +   if ((png_uint_32)check != (png_uint_32)length)
 546.121 +      png_error(png_ptr, "read Error");
 546.122 +}
 546.123 +#endif
 546.124 +#endif
 546.125 +
 546.126 +/* This function allows the application to supply a new input function
 546.127 +   for libpng if standard C streams aren't being used.
 546.128 +
 546.129 +   This function takes as its arguments:
 546.130 +   png_ptr      - pointer to a png input data structure
 546.131 +   io_ptr       - pointer to user supplied structure containing info about
 546.132 +                  the input functions.  May be NULL.
 546.133 +   read_data_fn - pointer to a new input function that takes as its
 546.134 +                  arguments a pointer to a png_struct, a pointer to
 546.135 +                  a location where input data can be stored, and a 32-bit
 546.136 +                  unsigned int that is the number of bytes to be read.
 546.137 +                  To exit and output any fatal error messages the new write
 546.138 +                  function should call png_error(png_ptr, "Error msg"). */
 546.139 +void PNGAPI
 546.140 +png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
 546.141 +   png_rw_ptr read_data_fn)
 546.142 +{
 546.143 +   if (png_ptr == NULL) return;
 546.144 +   png_ptr->io_ptr = io_ptr;
 546.145 +
 546.146 +#if !defined(PNG_NO_STDIO)
 546.147 +   if (read_data_fn != NULL)
 546.148 +      png_ptr->read_data_fn = read_data_fn;
 546.149 +   else
 546.150 +      png_ptr->read_data_fn = png_default_read_data;
 546.151 +#else
 546.152 +   png_ptr->read_data_fn = read_data_fn;
 546.153 +#endif
 546.154 +
 546.155 +   /* It is an error to write to a read device */
 546.156 +   if (png_ptr->write_data_fn != NULL)
 546.157 +   {
 546.158 +      png_ptr->write_data_fn = NULL;
 546.159 +      png_warning(png_ptr,
 546.160 +         "It's an error to set both read_data_fn and write_data_fn in the ");
 546.161 +      png_warning(png_ptr,
 546.162 +         "same structure.  Resetting write_data_fn to NULL.");
 546.163 +   }
 546.164 +
 546.165 +#if defined(PNG_WRITE_FLUSH_SUPPORTED)
 546.166 +   png_ptr->output_flush_fn = NULL;
 546.167 +#endif
 546.168 +}
 546.169 +#endif /* PNG_READ_SUPPORTED */
   547.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   547.2 +++ b/libs/libpng/pngrtran.c	Sat Feb 01 19:58:19 2014 +0200
   547.3 @@ -0,0 +1,4296 @@
   547.4 +
   547.5 +/* pngrtran.c - transforms the data in a row for PNG readers
   547.6 + *
   547.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   547.8 + * For conditions of distribution and use, see copyright notice in png.h
   547.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  547.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  547.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  547.12 + *
  547.13 + * This file contains functions optionally called by an application
  547.14 + * in order to tell libpng how to handle data when reading a PNG.
  547.15 + * Transformations that are used in both reading and writing are
  547.16 + * in pngtrans.c.
  547.17 + */
  547.18 +
  547.19 +#define PNG_INTERNAL
  547.20 +#include "png.h"
  547.21 +#if defined(PNG_READ_SUPPORTED)
  547.22 +
  547.23 +/* Set the action on getting a CRC error for an ancillary or critical chunk. */
  547.24 +void PNGAPI
  547.25 +png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
  547.26 +{
  547.27 +   png_debug(1, "in png_set_crc_action\n");
  547.28 +   /* Tell libpng how we react to CRC errors in critical chunks */
  547.29 +   if (png_ptr == NULL) return;
  547.30 +   switch (crit_action)
  547.31 +   {
  547.32 +      case PNG_CRC_NO_CHANGE:                        /* leave setting as is */
  547.33 +         break;
  547.34 +      case PNG_CRC_WARN_USE:                               /* warn/use data */
  547.35 +         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  547.36 +         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
  547.37 +         break;
  547.38 +      case PNG_CRC_QUIET_USE:                             /* quiet/use data */
  547.39 +         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  547.40 +         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
  547.41 +                           PNG_FLAG_CRC_CRITICAL_IGNORE;
  547.42 +         break;
  547.43 +      case PNG_CRC_WARN_DISCARD:    /* not a valid action for critical data */
  547.44 +         png_warning(png_ptr,
  547.45 +            "Can't discard critical data on CRC error.");
  547.46 +      case PNG_CRC_ERROR_QUIT:                                /* error/quit */
  547.47 +      case PNG_CRC_DEFAULT:
  547.48 +      default:
  547.49 +         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  547.50 +         break;
  547.51 +   }
  547.52 +
  547.53 +   switch (ancil_action)
  547.54 +   {
  547.55 +      case PNG_CRC_NO_CHANGE:                       /* leave setting as is */
  547.56 +         break;
  547.57 +      case PNG_CRC_WARN_USE:                              /* warn/use data */
  547.58 +         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  547.59 +         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
  547.60 +         break;
  547.61 +      case PNG_CRC_QUIET_USE:                            /* quiet/use data */
  547.62 +         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  547.63 +         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
  547.64 +                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
  547.65 +         break;
  547.66 +      case PNG_CRC_ERROR_QUIT:                               /* error/quit */
  547.67 +         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  547.68 +         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
  547.69 +         break;
  547.70 +      case PNG_CRC_WARN_DISCARD:                      /* warn/discard data */
  547.71 +      case PNG_CRC_DEFAULT:
  547.72 +      default:
  547.73 +         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  547.74 +         break;
  547.75 +   }
  547.76 +}
  547.77 +
  547.78 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
  547.79 +    defined(PNG_FLOATING_POINT_SUPPORTED)
  547.80 +/* handle alpha and tRNS via a background color */
  547.81 +void PNGAPI
  547.82 +png_set_background(png_structp png_ptr,
  547.83 +   png_color_16p background_color, int background_gamma_code,
  547.84 +   int need_expand, double background_gamma)
  547.85 +{
  547.86 +   png_debug(1, "in png_set_background\n");
  547.87 +   if (png_ptr == NULL) return;
  547.88 +   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
  547.89 +   {
  547.90 +      png_warning(png_ptr, "Application must supply a known background gamma");
  547.91 +      return;
  547.92 +   }
  547.93 +
  547.94 +   png_ptr->transformations |= PNG_BACKGROUND;
  547.95 +   png_memcpy(&(png_ptr->background), background_color,
  547.96 +      png_sizeof(png_color_16));
  547.97 +   png_ptr->background_gamma = (float)background_gamma;
  547.98 +   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
  547.99 +   png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
 547.100 +}
 547.101 +#endif
 547.102 +
 547.103 +#if defined(PNG_READ_16_TO_8_SUPPORTED)
 547.104 +/* strip 16 bit depth files to 8 bit depth */
 547.105 +void PNGAPI
 547.106 +png_set_strip_16(png_structp png_ptr)
 547.107 +{
 547.108 +   png_debug(1, "in png_set_strip_16\n");
 547.109 +   if (png_ptr == NULL) return;
 547.110 +   png_ptr->transformations |= PNG_16_TO_8;
 547.111 +}
 547.112 +#endif
 547.113 +
 547.114 +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
 547.115 +void PNGAPI
 547.116 +png_set_strip_alpha(png_structp png_ptr)
 547.117 +{
 547.118 +   png_debug(1, "in png_set_strip_alpha\n");
 547.119 +   if (png_ptr == NULL) return;
 547.120 +   png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
 547.121 +}
 547.122 +#endif
 547.123 +
 547.124 +#if defined(PNG_READ_DITHER_SUPPORTED)
 547.125 +/* Dither file to 8 bit.  Supply a palette, the current number
 547.126 + * of elements in the palette, the maximum number of elements
 547.127 + * allowed, and a histogram if possible.  If the current number
 547.128 + * of colors is greater then the maximum number, the palette will be
 547.129 + * modified to fit in the maximum number.  "full_dither" indicates
 547.130 + * whether we need a dithering cube set up for RGB images, or if we
 547.131 + * simply are reducing the number of colors in a paletted image.
 547.132 + */
 547.133 +
 547.134 +typedef struct png_dsort_struct
 547.135 +{
 547.136 +   struct png_dsort_struct FAR * next;
 547.137 +   png_byte left;
 547.138 +   png_byte right;
 547.139 +} png_dsort;
 547.140 +typedef png_dsort FAR *       png_dsortp;
 547.141 +typedef png_dsort FAR * FAR * png_dsortpp;
 547.142 +
 547.143 +void PNGAPI
 547.144 +png_set_dither(png_structp png_ptr, png_colorp palette,
 547.145 +   int num_palette, int maximum_colors, png_uint_16p histogram,
 547.146 +   int full_dither)
 547.147 +{
 547.148 +   png_debug(1, "in png_set_dither\n");
 547.149 +   if (png_ptr == NULL) return;
 547.150 +   png_ptr->transformations |= PNG_DITHER;
 547.151 +
 547.152 +   if (!full_dither)
 547.153 +   {
 547.154 +      int i;
 547.155 +
 547.156 +      png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
 547.157 +         (png_uint_32)(num_palette * png_sizeof(png_byte)));
 547.158 +      for (i = 0; i < num_palette; i++)
 547.159 +         png_ptr->dither_index[i] = (png_byte)i;
 547.160 +   }
 547.161 +
 547.162 +   if (num_palette > maximum_colors)
 547.163 +   {
 547.164 +      if (histogram != NULL)
 547.165 +      {
 547.166 +         /* This is easy enough, just throw out the least used colors.
 547.167 +            Perhaps not the best solution, but good enough. */
 547.168 +
 547.169 +         int i;
 547.170 +
 547.171 +         /* initialize an array to sort colors */
 547.172 +         png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
 547.173 +            (png_uint_32)(num_palette * png_sizeof(png_byte)));
 547.174 +
 547.175 +         /* initialize the dither_sort array */
 547.176 +         for (i = 0; i < num_palette; i++)
 547.177 +            png_ptr->dither_sort[i] = (png_byte)i;
 547.178 +
 547.179 +         /* Find the least used palette entries by starting a
 547.180 +            bubble sort, and running it until we have sorted
 547.181 +            out enough colors.  Note that we don't care about
 547.182 +            sorting all the colors, just finding which are
 547.183 +            least used. */
 547.184 +
 547.185 +         for (i = num_palette - 1; i >= maximum_colors; i--)
 547.186 +         {
 547.187 +            int done; /* to stop early if the list is pre-sorted */
 547.188 +            int j;
 547.189 +
 547.190 +            done = 1;
 547.191 +            for (j = 0; j < i; j++)
 547.192 +            {
 547.193 +               if (histogram[png_ptr->dither_sort[j]]
 547.194 +                   < histogram[png_ptr->dither_sort[j + 1]])
 547.195 +               {
 547.196 +                  png_byte t;
 547.197 +
 547.198 +                  t = png_ptr->dither_sort[j];
 547.199 +                  png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
 547.200 +                  png_ptr->dither_sort[j + 1] = t;
 547.201 +                  done = 0;
 547.202 +               }
 547.203 +            }
 547.204 +            if (done)
 547.205 +               break;
 547.206 +         }
 547.207 +
 547.208 +         /* swap the palette around, and set up a table, if necessary */
 547.209 +         if (full_dither)
 547.210 +         {
 547.211 +            int j = num_palette;
 547.212 +
 547.213 +            /* put all the useful colors within the max, but don't
 547.214 +               move the others */
 547.215 +            for (i = 0; i < maximum_colors; i++)
 547.216 +            {
 547.217 +               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
 547.218 +               {
 547.219 +                  do
 547.220 +                     j--;
 547.221 +                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
 547.222 +                  palette[i] = palette[j];
 547.223 +               }
 547.224 +            }
 547.225 +         }
 547.226 +         else
 547.227 +         {
 547.228 +            int j = num_palette;
 547.229 +
 547.230 +            /* move all the used colors inside the max limit, and
 547.231 +               develop a translation table */
 547.232 +            for (i = 0; i < maximum_colors; i++)
 547.233 +            {
 547.234 +               /* only move the colors we need to */
 547.235 +               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
 547.236 +               {
 547.237 +                  png_color tmp_color;
 547.238 +
 547.239 +                  do
 547.240 +                     j--;
 547.241 +                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
 547.242 +
 547.243 +                  tmp_color = palette[j];
 547.244 +                  palette[j] = palette[i];
 547.245 +                  palette[i] = tmp_color;
 547.246 +                  /* indicate where the color went */
 547.247 +                  png_ptr->dither_index[j] = (png_byte)i;
 547.248 +                  png_ptr->dither_index[i] = (png_byte)j;
 547.249 +               }
 547.250 +            }
 547.251 +
 547.252 +            /* find closest color for those colors we are not using */
 547.253 +            for (i = 0; i < num_palette; i++)
 547.254 +            {
 547.255 +               if ((int)png_ptr->dither_index[i] >= maximum_colors)
 547.256 +               {
 547.257 +                  int min_d, k, min_k, d_index;
 547.258 +
 547.259 +                  /* find the closest color to one we threw out */
 547.260 +                  d_index = png_ptr->dither_index[i];
 547.261 +                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
 547.262 +                  for (k = 1, min_k = 0; k < maximum_colors; k++)
 547.263 +                  {
 547.264 +                     int d;
 547.265 +
 547.266 +                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
 547.267 +
 547.268 +                     if (d < min_d)
 547.269 +                     {
 547.270 +                        min_d = d;
 547.271 +                        min_k = k;
 547.272 +                     }
 547.273 +                  }
 547.274 +                  /* point to closest color */
 547.275 +                  png_ptr->dither_index[i] = (png_byte)min_k;
 547.276 +               }
 547.277 +            }
 547.278 +         }
 547.279 +         png_free(png_ptr, png_ptr->dither_sort);
 547.280 +         png_ptr->dither_sort = NULL;
 547.281 +      }
 547.282 +      else
 547.283 +      {
 547.284 +         /* This is much harder to do simply (and quickly).  Perhaps
 547.285 +            we need to go through a median cut routine, but those
 547.286 +            don't always behave themselves with only a few colors
 547.287 +            as input.  So we will just find the closest two colors,
 547.288 +            and throw out one of them (chosen somewhat randomly).
 547.289 +            [We don't understand this at all, so if someone wants to
 547.290 +             work on improving it, be our guest - AED, GRP]
 547.291 +            */
 547.292 +         int i;
 547.293 +         int max_d;
 547.294 +         int num_new_palette;
 547.295 +         png_dsortp t;
 547.296 +         png_dsortpp hash;
 547.297 +
 547.298 +         t = NULL;
 547.299 +
 547.300 +         /* initialize palette index arrays */
 547.301 +         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
 547.302 +            (png_uint_32)(num_palette * png_sizeof(png_byte)));
 547.303 +         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
 547.304 +            (png_uint_32)(num_palette * png_sizeof(png_byte)));
 547.305 +
 547.306 +         /* initialize the sort array */
 547.307 +         for (i = 0; i < num_palette; i++)
 547.308 +         {
 547.309 +            png_ptr->index_to_palette[i] = (png_byte)i;
 547.310 +            png_ptr->palette_to_index[i] = (png_byte)i;
 547.311 +         }
 547.312 +
 547.313 +         hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
 547.314 +            png_sizeof(png_dsortp)));
 547.315 +         for (i = 0; i < 769; i++)
 547.316 +            hash[i] = NULL;
 547.317 +/*         png_memset(hash, 0, 769 * png_sizeof(png_dsortp)); */
 547.318 +
 547.319 +         num_new_palette = num_palette;
 547.320 +
 547.321 +         /* initial wild guess at how far apart the farthest pixel
 547.322 +            pair we will be eliminating will be.  Larger
 547.323 +            numbers mean more areas will be allocated, Smaller
 547.324 +            numbers run the risk of not saving enough data, and
 547.325 +            having to do this all over again.
 547.326 +
 547.327 +            I have not done extensive checking on this number.
 547.328 +            */
 547.329 +         max_d = 96;
 547.330 +
 547.331 +         while (num_new_palette > maximum_colors)
 547.332 +         {
 547.333 +            for (i = 0; i < num_new_palette - 1; i++)
 547.334 +            {
 547.335 +               int j;
 547.336 +
 547.337 +               for (j = i + 1; j < num_new_palette; j++)
 547.338 +               {
 547.339 +                  int d;
 547.340 +
 547.341 +                  d = PNG_COLOR_DIST(palette[i], palette[j]);
 547.342 +
 547.343 +                  if (d <= max_d)
 547.344 +                  {
 547.345 +
 547.346 +                     t = (png_dsortp)png_malloc_warn(png_ptr,
 547.347 +                         (png_uint_32)(png_sizeof(png_dsort)));
 547.348 +                     if (t == NULL)
 547.349 +                         break;
 547.350 +                     t->next = hash[d];
 547.351 +                     t->left = (png_byte)i;
 547.352 +                     t->right = (png_byte)j;
 547.353 +                     hash[d] = t;
 547.354 +                  }
 547.355 +               }
 547.356 +               if (t == NULL)
 547.357 +                  break;
 547.358 +            }
 547.359 +
 547.360 +            if (t != NULL)
 547.361 +            for (i = 0; i <= max_d; i++)
 547.362 +            {
 547.363 +               if (hash[i] != NULL)
 547.364 +               {
 547.365 +                  png_dsortp p;
 547.366 +
 547.367 +                  for (p = hash[i]; p; p = p->next)
 547.368 +                  {
 547.369 +                     if ((int)png_ptr->index_to_palette[p->left]
 547.370 +                        < num_new_palette &&
 547.371 +                        (int)png_ptr->index_to_palette[p->right]
 547.372 +                        < num_new_palette)
 547.373 +                     {
 547.374 +                        int j, next_j;
 547.375 +
 547.376 +                        if (num_new_palette & 0x01)
 547.377 +                        {
 547.378 +                           j = p->left;
 547.379 +                           next_j = p->right;
 547.380 +                        }
 547.381 +                        else
 547.382 +                        {
 547.383 +                           j = p->right;
 547.384 +                           next_j = p->left;
 547.385 +                        }
 547.386 +
 547.387 +                        num_new_palette--;
 547.388 +                        palette[png_ptr->index_to_palette[j]]
 547.389 +                          = palette[num_new_palette];
 547.390 +                        if (!full_dither)
 547.391 +                        {
 547.392 +                           int k;
 547.393 +
 547.394 +                           for (k = 0; k < num_palette; k++)
 547.395 +                           {
 547.396 +                              if (png_ptr->dither_index[k] ==
 547.397 +                                 png_ptr->index_to_palette[j])
 547.398 +                                 png_ptr->dither_index[k] =
 547.399 +                                    png_ptr->index_to_palette[next_j];
 547.400 +                              if ((int)png_ptr->dither_index[k] ==
 547.401 +                                 num_new_palette)
 547.402 +                                 png_ptr->dither_index[k] =
 547.403 +                                    png_ptr->index_to_palette[j];
 547.404 +                           }
 547.405 +                        }
 547.406 +
 547.407 +                        png_ptr->index_to_palette[png_ptr->palette_to_index
 547.408 +                           [num_new_palette]] = png_ptr->index_to_palette[j];
 547.409 +                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
 547.410 +                           = png_ptr->palette_to_index[num_new_palette];
 547.411 +
 547.412 +                        png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
 547.413 +                        png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
 547.414 +                     }
 547.415 +                     if (num_new_palette <= maximum_colors)
 547.416 +                        break;
 547.417 +                  }
 547.418 +                  if (num_new_palette <= maximum_colors)
 547.419 +                     break;
 547.420 +               }
 547.421 +            }
 547.422 +
 547.423 +            for (i = 0; i < 769; i++)
 547.424 +            {
 547.425 +               if (hash[i] != NULL)
 547.426 +               {
 547.427 +                  png_dsortp p = hash[i];
 547.428 +                  while (p)
 547.429 +                  {
 547.430 +                     t = p->next;
 547.431 +                     png_free(png_ptr, p);
 547.432 +                     p = t;
 547.433 +                  }
 547.434 +               }
 547.435 +               hash[i] = 0;
 547.436 +            }
 547.437 +            max_d += 96;
 547.438 +         }
 547.439 +         png_free(png_ptr, hash);
 547.440 +         png_free(png_ptr, png_ptr->palette_to_index);
 547.441 +         png_free(png_ptr, png_ptr->index_to_palette);
 547.442 +         png_ptr->palette_to_index = NULL;
 547.443 +         png_ptr->index_to_palette = NULL;
 547.444 +      }
 547.445 +      num_palette = maximum_colors;
 547.446 +   }
 547.447 +   if (png_ptr->palette == NULL)
 547.448 +   {
 547.449 +      png_ptr->palette = palette;
 547.450 +   }
 547.451 +   png_ptr->num_palette = (png_uint_16)num_palette;
 547.452 +
 547.453 +   if (full_dither)
 547.454 +   {
 547.455 +      int i;
 547.456 +      png_bytep distance;
 547.457 +      int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
 547.458 +         PNG_DITHER_BLUE_BITS;
 547.459 +      int num_red = (1 << PNG_DITHER_RED_BITS);
 547.460 +      int num_green = (1 << PNG_DITHER_GREEN_BITS);
 547.461 +      int num_blue = (1 << PNG_DITHER_BLUE_BITS);
 547.462 +      png_size_t num_entries = ((png_size_t)1 << total_bits);
 547.463 +
 547.464 +      png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
 547.465 +         (png_uint_32)(num_entries * png_sizeof(png_byte)));
 547.466 +
 547.467 +      png_memset(png_ptr->palette_lookup, 0, num_entries *
 547.468 +         png_sizeof(png_byte));
 547.469 +
 547.470 +      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
 547.471 +         png_sizeof(png_byte)));
 547.472 +
 547.473 +      png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
 547.474 +
 547.475 +      for (i = 0; i < num_palette; i++)
 547.476 +      {
 547.477 +         int ir, ig, ib;
 547.478 +         int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
 547.479 +         int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
 547.480 +         int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
 547.481 +
 547.482 +         for (ir = 0; ir < num_red; ir++)
 547.483 +         {
 547.484 +            /* int dr = abs(ir - r); */
 547.485 +            int dr = ((ir > r) ? ir - r : r - ir);
 547.486 +            int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
 547.487 +
 547.488 +            for (ig = 0; ig < num_green; ig++)
 547.489 +            {
 547.490 +               /* int dg = abs(ig - g); */
 547.491 +               int dg = ((ig > g) ? ig - g : g - ig);
 547.492 +               int dt = dr + dg;
 547.493 +               int dm = ((dr > dg) ? dr : dg);
 547.494 +               int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
 547.495 +
 547.496 +               for (ib = 0; ib < num_blue; ib++)
 547.497 +               {
 547.498 +                  int d_index = index_g | ib;
 547.499 +                  /* int db = abs(ib - b); */
 547.500 +                  int db = ((ib > b) ? ib - b : b - ib);
 547.501 +                  int dmax = ((dm > db) ? dm : db);
 547.502 +                  int d = dmax + dt + db;
 547.503 +
 547.504 +                  if (d < (int)distance[d_index])
 547.505 +                  {
 547.506 +                     distance[d_index] = (png_byte)d;
 547.507 +                     png_ptr->palette_lookup[d_index] = (png_byte)i;
 547.508 +                  }
 547.509 +               }
 547.510 +            }
 547.511 +         }
 547.512 +      }
 547.513 +
 547.514 +      png_free(png_ptr, distance);
 547.515 +   }
 547.516 +}
 547.517 +#endif
 547.518 +
 547.519 +#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
 547.520 +/* Transform the image from the file_gamma to the screen_gamma.  We
 547.521 + * only do transformations on images where the file_gamma and screen_gamma
 547.522 + * are not close reciprocals, otherwise it slows things down slightly, and
 547.523 + * also needlessly introduces small errors.
 547.524 + *
 547.525 + * We will turn off gamma transformation later if no semitransparent entries
 547.526 + * are present in the tRNS array for palette images.  We can't do it here
 547.527 + * because we don't necessarily have the tRNS chunk yet.
 547.528 + */
 547.529 +void PNGAPI
 547.530 +png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
 547.531 +{
 547.532 +   png_debug(1, "in png_set_gamma\n");
 547.533 +   if (png_ptr == NULL) return;
 547.534 +   if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
 547.535 +       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
 547.536 +       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
 547.537 +     png_ptr->transformations |= PNG_GAMMA;
 547.538 +   png_ptr->gamma = (float)file_gamma;
 547.539 +   png_ptr->screen_gamma = (float)scrn_gamma;
 547.540 +}
 547.541 +#endif
 547.542 +
 547.543 +#if defined(PNG_READ_EXPAND_SUPPORTED)
 547.544 +/* Expand paletted images to RGB, expand grayscale images of
 547.545 + * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
 547.546 + * to alpha channels.
 547.547 + */
 547.548 +void PNGAPI
 547.549 +png_set_expand(png_structp png_ptr)
 547.550 +{
 547.551 +   png_debug(1, "in png_set_expand\n");
 547.552 +   if (png_ptr == NULL) return;
 547.553 +   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 547.554 +   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 547.555 +}
 547.556 +
 547.557 +/* GRR 19990627:  the following three functions currently are identical
 547.558 + *  to png_set_expand().  However, it is entirely reasonable that someone
 547.559 + *  might wish to expand an indexed image to RGB but *not* expand a single,
 547.560 + *  fully transparent palette entry to a full alpha channel--perhaps instead
 547.561 + *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
 547.562 + *  the transparent color with a particular RGB value, or drop tRNS entirely.
 547.563 + *  IOW, a future version of the library may make the transformations flag
 547.564 + *  a bit more fine-grained, with separate bits for each of these three
 547.565 + *  functions.
 547.566 + *
 547.567 + *  More to the point, these functions make it obvious what libpng will be
 547.568 + *  doing, whereas "expand" can (and does) mean any number of things.
 547.569 + *
 547.570 + *  GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
 547.571 + *  to expand only the sample depth but not to expand the tRNS to alpha.
 547.572 + */
 547.573 +
 547.574 +/* Expand paletted images to RGB. */
 547.575 +void PNGAPI
 547.576 +png_set_palette_to_rgb(png_structp png_ptr)
 547.577 +{
 547.578 +   png_debug(1, "in png_set_palette_to_rgb\n");
 547.579 +   if (png_ptr == NULL) return;
 547.580 +   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 547.581 +   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 547.582 +}
 547.583 +
 547.584 +#if !defined(PNG_1_0_X)
 547.585 +/* Expand grayscale images of less than 8-bit depth to 8 bits. */
 547.586 +void PNGAPI
 547.587 +png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
 547.588 +{
 547.589 +   png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n");
 547.590 +   if (png_ptr == NULL) return;
 547.591 +   png_ptr->transformations |= PNG_EXPAND;
 547.592 +   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 547.593 +}
 547.594 +#endif
 547.595 +
 547.596 +#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
 547.597 +/* Expand grayscale images of less than 8-bit depth to 8 bits. */
 547.598 +/* Deprecated as of libpng-1.2.9 */
 547.599 +void PNGAPI
 547.600 +png_set_gray_1_2_4_to_8(png_structp png_ptr)
 547.601 +{
 547.602 +   png_debug(1, "in png_set_gray_1_2_4_to_8\n");
 547.603 +   if (png_ptr == NULL) return;
 547.604 +   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 547.605 +}
 547.606 +#endif
 547.607 +
 547.608 +
 547.609 +/* Expand tRNS chunks to alpha channels. */
 547.610 +void PNGAPI
 547.611 +png_set_tRNS_to_alpha(png_structp png_ptr)
 547.612 +{
 547.613 +   png_debug(1, "in png_set_tRNS_to_alpha\n");
 547.614 +   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 547.615 +   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 547.616 +}
 547.617 +#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
 547.618 +
 547.619 +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
 547.620 +void PNGAPI
 547.621 +png_set_gray_to_rgb(png_structp png_ptr)
 547.622 +{
 547.623 +   png_debug(1, "in png_set_gray_to_rgb\n");
 547.624 +   png_ptr->transformations |= PNG_GRAY_TO_RGB;
 547.625 +   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 547.626 +}
 547.627 +#endif
 547.628 +
 547.629 +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
 547.630 +#if defined(PNG_FLOATING_POINT_SUPPORTED)
 547.631 +/* Convert a RGB image to a grayscale of the same width.  This allows us,
 547.632 + * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
 547.633 + */
 547.634 +
 547.635 +void PNGAPI
 547.636 +png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
 547.637 +   double green)
 547.638 +{
 547.639 +      int red_fixed = (int)((float)red*100000.0 + 0.5);
 547.640 +      int green_fixed = (int)((float)green*100000.0 + 0.5);
 547.641 +      if (png_ptr == NULL) return;
 547.642 +      png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
 547.643 +}
 547.644 +#endif
 547.645 +
 547.646 +void PNGAPI
 547.647 +png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
 547.648 +   png_fixed_point red, png_fixed_point green)
 547.649 +{
 547.650 +   png_debug(1, "in png_set_rgb_to_gray\n");
 547.651 +   if (png_ptr == NULL) return;
 547.652 +   switch(error_action)
 547.653 +   {
 547.654 +      case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
 547.655 +              break;
 547.656 +      case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
 547.657 +              break;
 547.658 +      case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
 547.659 +   }
 547.660 +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 547.661 +#if defined(PNG_READ_EXPAND_SUPPORTED)
 547.662 +      png_ptr->transformations |= PNG_EXPAND;
 547.663 +#else
 547.664 +   {
 547.665 +      png_warning(png_ptr,
 547.666 +        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
 547.667 +      png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
 547.668 +   }
 547.669 +#endif
 547.670 +   {
 547.671 +      png_uint_16 red_int, green_int;
 547.672 +      if (red < 0 || green < 0)
 547.673 +      {
 547.674 +         red_int   =  6968; /* .212671 * 32768 + .5 */
 547.675 +         green_int = 23434; /* .715160 * 32768 + .5 */
 547.676 +      }
 547.677 +      else if (red + green < 100000L)
 547.678 +      {
 547.679 +        red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
 547.680 +        green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
 547.681 +      }
 547.682 +      else
 547.683 +      {
 547.684 +         png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
 547.685 +         red_int   =  6968;
 547.686 +         green_int = 23434;
 547.687 +      }
 547.688 +      png_ptr->rgb_to_gray_red_coeff   = red_int;
 547.689 +      png_ptr->rgb_to_gray_green_coeff = green_int;
 547.690 +      png_ptr->rgb_to_gray_blue_coeff  = 
 547.691 +         (png_uint_16)(32768 - red_int - green_int);
 547.692 +   }
 547.693 +}
 547.694 +#endif
 547.695 +
 547.696 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
 547.697 +    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
 547.698 +    defined(PNG_LEGACY_SUPPORTED)
 547.699 +void PNGAPI
 547.700 +png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
 547.701 +   read_user_transform_fn)
 547.702 +{
 547.703 +   png_debug(1, "in png_set_read_user_transform_fn\n");
 547.704 +   if (png_ptr == NULL) return;
 547.705 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
 547.706 +   png_ptr->transformations |= PNG_USER_TRANSFORM;
 547.707 +   png_ptr->read_user_transform_fn = read_user_transform_fn;
 547.708 +#endif
 547.709 +#ifdef PNG_LEGACY_SUPPORTED
 547.710 +   if (read_user_transform_fn)
 547.711 +      png_warning(png_ptr,
 547.712 +        "This version of libpng does not support user transforms");
 547.713 +#endif
 547.714 +}
 547.715 +#endif
 547.716 +
 547.717 +/* Initialize everything needed for the read.  This includes modifying
 547.718 + * the palette.
 547.719 + */
 547.720 +void /* PRIVATE */
 547.721 +png_init_read_transformations(png_structp png_ptr)
 547.722 +{
 547.723 +   png_debug(1, "in png_init_read_transformations\n");
 547.724 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
 547.725 +   if (png_ptr != NULL)
 547.726 +#endif
 547.727 +  {
 547.728 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
 547.729 + || defined(PNG_READ_GAMMA_SUPPORTED)
 547.730 +   int color_type = png_ptr->color_type;
 547.731 +#endif
 547.732 +
 547.733 +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
 547.734 +
 547.735 +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
 547.736 +   /* Detect gray background and attempt to enable optimization
 547.737 +    * for gray --> RGB case */
 547.738 +   /* Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
 547.739 +    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
 547.740 +    * background color might actually be gray yet not be flagged as such.
 547.741 +    * This is not a problem for the current code, which uses
 547.742 +    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
 547.743 +    * png_do_gray_to_rgb() transformation.
 547.744 +    */
 547.745 +   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
 547.746 +       !(color_type & PNG_COLOR_MASK_COLOR))
 547.747 +   {
 547.748 +          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
 547.749 +   } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
 547.750 +              !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
 547.751 +              (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
 547.752 +              png_ptr->background.red == png_ptr->background.green &&
 547.753 +              png_ptr->background.red == png_ptr->background.blue)
 547.754 +   {
 547.755 +          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
 547.756 +          png_ptr->background.gray = png_ptr->background.red;
 547.757 +   }
 547.758 +#endif
 547.759 +
 547.760 +   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
 547.761 +       (png_ptr->transformations & PNG_EXPAND))
 547.762 +   {
 547.763 +      if (!(color_type & PNG_COLOR_MASK_COLOR))  /* i.e., GRAY or GRAY_ALPHA */
 547.764 +      {
 547.765 +         /* expand background and tRNS chunks */
 547.766 +         switch (png_ptr->bit_depth)
 547.767 +         {
 547.768 +            case 1:
 547.769 +               png_ptr->background.gray *= (png_uint_16)0xff;
 547.770 +               png_ptr->background.red = png_ptr->background.green
 547.771 +                 =  png_ptr->background.blue = png_ptr->background.gray;
 547.772 +               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
 547.773 +               {
 547.774 +                 png_ptr->trans_values.gray *= (png_uint_16)0xff;
 547.775 +                 png_ptr->trans_values.red = png_ptr->trans_values.green
 547.776 +                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
 547.777 +               }
 547.778 +               break;
 547.779 +            case 2:
 547.780 +               png_ptr->background.gray *= (png_uint_16)0x55;
 547.781 +               png_ptr->background.red = png_ptr->background.green
 547.782 +                 = png_ptr->background.blue = png_ptr->background.gray;
 547.783 +               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
 547.784 +               {
 547.785 +                 png_ptr->trans_values.gray *= (png_uint_16)0x55;
 547.786 +                 png_ptr->trans_values.red = png_ptr->trans_values.green
 547.787 +                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
 547.788 +               }
 547.789 +               break;
 547.790 +            case 4:
 547.791 +               png_ptr->background.gray *= (png_uint_16)0x11;
 547.792 +               png_ptr->background.red = png_ptr->background.green
 547.793 +                 = png_ptr->background.blue = png_ptr->background.gray;
 547.794 +               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
 547.795 +               {
 547.796 +                 png_ptr->trans_values.gray *= (png_uint_16)0x11;
 547.797 +                 png_ptr->trans_values.red = png_ptr->trans_values.green
 547.798 +                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
 547.799 +               }
 547.800 +               break;
 547.801 +            case 8:
 547.802 +            case 16:
 547.803 +               png_ptr->background.red = png_ptr->background.green
 547.804 +                 = png_ptr->background.blue = png_ptr->background.gray;
 547.805 +               break;
 547.806 +         }
 547.807 +      }
 547.808 +      else if (color_type == PNG_COLOR_TYPE_PALETTE)
 547.809 +      {
 547.810 +         png_ptr->background.red   =
 547.811 +            png_ptr->palette[png_ptr->background.index].red;
 547.812 +         png_ptr->background.green =
 547.813 +            png_ptr->palette[png_ptr->background.index].green;
 547.814 +         png_ptr->background.blue  =
 547.815 +            png_ptr->palette[png_ptr->background.index].blue;
 547.816 +
 547.817 +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
 547.818 +        if (png_ptr->transformations & PNG_INVERT_ALPHA)
 547.819 +        {
 547.820 +#if defined(PNG_READ_EXPAND_SUPPORTED)
 547.821 +           if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
 547.822 +#endif
 547.823 +           {
 547.824 +           /* invert the alpha channel (in tRNS) unless the pixels are
 547.825 +              going to be expanded, in which case leave it for later */
 547.826 +              int i, istop;
 547.827 +              istop=(int)png_ptr->num_trans;
 547.828 +              for (i=0; i<istop; i++)
 547.829 +                 png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
 547.830 +           }
 547.831 +        }
 547.832 +#endif
 547.833 +
 547.834 +      }
 547.835 +   }
 547.836 +#endif
 547.837 +
 547.838 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
 547.839 +   png_ptr->background_1 = png_ptr->background;
 547.840 +#endif
 547.841 +#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
 547.842 +
 547.843 +   if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
 547.844 +       && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
 547.845 +         < PNG_GAMMA_THRESHOLD))
 547.846 +   {
 547.847 +    int i, k;
 547.848 +    k=0;
 547.849 +    for (i=0; i<png_ptr->num_trans; i++)
 547.850 +    {
 547.851 +      if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
 547.852 +        k=1; /* partial transparency is present */
 547.853 +    }
 547.854 +    if (k == 0)
 547.855 +      png_ptr->transformations &= ~PNG_GAMMA;
 547.856 +   }
 547.857 +
 547.858 +   if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
 547.859 +        png_ptr->gamma != 0.0)
 547.860 +   {
 547.861 +      png_build_gamma_table(png_ptr);
 547.862 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
 547.863 +      if (png_ptr->transformations & PNG_BACKGROUND)
 547.864 +      {
 547.865 +         if (color_type == PNG_COLOR_TYPE_PALETTE)
 547.866 +         {
 547.867 +           /* could skip if no transparency and
 547.868 +           */
 547.869 +            png_color back, back_1;
 547.870 +            png_colorp palette = png_ptr->palette;
 547.871 +            int num_palette = png_ptr->num_palette;
 547.872 +            int i;
 547.873 +            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
 547.874 +            {
 547.875 +               back.red = png_ptr->gamma_table[png_ptr->background.red];
 547.876 +               back.green = png_ptr->gamma_table[png_ptr->background.green];
 547.877 +               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
 547.878 +
 547.879 +               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
 547.880 +               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
 547.881 +               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
 547.882 +            }
 547.883 +            else
 547.884 +            {
 547.885 +               double g, gs;
 547.886 +
 547.887 +               switch (png_ptr->background_gamma_type)
 547.888 +               {
 547.889 +                  case PNG_BACKGROUND_GAMMA_SCREEN:
 547.890 +                     g = (png_ptr->screen_gamma);
 547.891 +                     gs = 1.0;
 547.892 +                     break;
 547.893 +                  case PNG_BACKGROUND_GAMMA_FILE:
 547.894 +                     g = 1.0 / (png_ptr->gamma);
 547.895 +                     gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
 547.896 +                     break;
 547.897 +                  case PNG_BACKGROUND_GAMMA_UNIQUE:
 547.898 +                     g = 1.0 / (png_ptr->background_gamma);
 547.899 +                     gs = 1.0 / (png_ptr->background_gamma *
 547.900 +                                 png_ptr->screen_gamma);
 547.901 +                     break;
 547.902 +                  default:
 547.903 +                     g = 1.0;    /* back_1 */
 547.904 +                     gs = 1.0;   /* back */
 547.905 +               }
 547.906 +
 547.907 +               if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
 547.908 +               {
 547.909 +                  back.red   = (png_byte)png_ptr->background.red;
 547.910 +                  back.green = (png_byte)png_ptr->background.green;
 547.911 +                  back.blue  = (png_byte)png_ptr->background.blue;
 547.912 +               }
 547.913 +               else
 547.914 +               {
 547.915 +                  back.red = (png_byte)(pow(
 547.916 +                     (double)png_ptr->background.red/255, gs) * 255.0 + .5);
 547.917 +                  back.green = (png_byte)(pow(
 547.918 +                     (double)png_ptr->background.green/255, gs) * 255.0 + .5);
 547.919 +                  back.blue = (png_byte)(pow(
 547.920 +                     (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
 547.921 +               }
 547.922 +
 547.923 +               back_1.red = (png_byte)(pow(
 547.924 +                  (double)png_ptr->background.red/255, g) * 255.0 + .5);
 547.925 +               back_1.green = (png_byte)(pow(
 547.926 +                  (double)png_ptr->background.green/255, g) * 255.0 + .5);
 547.927 +               back_1.blue = (png_byte)(pow(
 547.928 +                  (double)png_ptr->background.blue/255, g) * 255.0 + .5);
 547.929 +            }
 547.930 +            for (i = 0; i < num_palette; i++)
 547.931 +            {
 547.932 +               if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
 547.933 +               {
 547.934 +                  if (png_ptr->trans[i] == 0)
 547.935 +                  {
 547.936 +                     palette[i] = back;
 547.937 +                  }
 547.938 +                  else /* if (png_ptr->trans[i] != 0xff) */
 547.939 +                  {
 547.940 +                     png_byte v, w;
 547.941 +
 547.942 +                     v = png_ptr->gamma_to_1[palette[i].red];
 547.943 +                     png_composite(w, v, png_ptr->trans[i], back_1.red);
 547.944 +                     palette[i].red = png_ptr->gamma_from_1[w];
 547.945 +
 547.946 +                     v = png_ptr->gamma_to_1[palette[i].green];
 547.947 +                     png_composite(w, v, png_ptr->trans[i], back_1.green);
 547.948 +                     palette[i].green = png_ptr->gamma_from_1[w];
 547.949 +
 547.950 +                     v = png_ptr->gamma_to_1[palette[i].blue];
 547.951 +                     png_composite(w, v, png_ptr->trans[i], back_1.blue);
 547.952 +                     palette[i].blue = png_ptr->gamma_from_1[w];
 547.953 +                  }
 547.954 +               }
 547.955 +               else
 547.956 +               {
 547.957 +                  palette[i].red = png_ptr->gamma_table[palette[i].red];
 547.958 +                  palette[i].green = png_ptr->gamma_table[palette[i].green];
 547.959 +                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
 547.960 +               }
 547.961 +            }
 547.962 +	    /* Prevent the transformations being done again, and make sure
 547.963 +	     * that the now spurious alpha channel is stripped - the code
 547.964 +	     * has just reduced background composition and gamma correction
 547.965 +	     * to a simple alpha channel strip.
 547.966 +	     */
 547.967 +	    png_ptr->transformations &= ~PNG_BACKGROUND;
 547.968 +	    png_ptr->transformations &= ~PNG_GAMMA;
 547.969 +	    png_ptr->transformations |= PNG_STRIP_ALPHA;
 547.970 +         }
 547.971 +         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
 547.972 +         else
 547.973 +         /* color_type != PNG_COLOR_TYPE_PALETTE */
 547.974 +         {
 547.975 +            double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
 547.976 +            double g = 1.0;
 547.977 +            double gs = 1.0;
 547.978 +
 547.979 +            switch (png_ptr->background_gamma_type)
 547.980 +            {
 547.981 +               case PNG_BACKGROUND_GAMMA_SCREEN:
 547.982 +                  g = (png_ptr->screen_gamma);
 547.983 +                  gs = 1.0;
 547.984 +                  break;
 547.985 +               case PNG_BACKGROUND_GAMMA_FILE:
 547.986 +                  g = 1.0 / (png_ptr->gamma);
 547.987 +                  gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
 547.988 +                  break;
 547.989 +               case PNG_BACKGROUND_GAMMA_UNIQUE:
 547.990 +                  g = 1.0 / (png_ptr->background_gamma);
 547.991 +                  gs = 1.0 / (png_ptr->background_gamma *
 547.992 +                     png_ptr->screen_gamma);
 547.993 +                  break;
 547.994 +            }
 547.995 +
 547.996 +            png_ptr->background_1.gray = (png_uint_16)(pow(
 547.997 +               (double)png_ptr->background.gray / m, g) * m + .5);
 547.998 +            png_ptr->background.gray = (png_uint_16)(pow(
 547.999 +               (double)png_ptr->background.gray / m, gs) * m + .5);
547.1000 +
547.1001 +            if ((png_ptr->background.red != png_ptr->background.green) ||
547.1002 +                (png_ptr->background.red != png_ptr->background.blue) ||
547.1003 +                (png_ptr->background.red != png_ptr->background.gray))
547.1004 +            {
547.1005 +               /* RGB or RGBA with color background */
547.1006 +               png_ptr->background_1.red = (png_uint_16)(pow(
547.1007 +                  (double)png_ptr->background.red / m, g) * m + .5);
547.1008 +               png_ptr->background_1.green = (png_uint_16)(pow(
547.1009 +                  (double)png_ptr->background.green / m, g) * m + .5);
547.1010 +               png_ptr->background_1.blue = (png_uint_16)(pow(
547.1011 +                  (double)png_ptr->background.blue / m, g) * m + .5);
547.1012 +               png_ptr->background.red = (png_uint_16)(pow(
547.1013 +                  (double)png_ptr->background.red / m, gs) * m + .5);
547.1014 +               png_ptr->background.green = (png_uint_16)(pow(
547.1015 +                  (double)png_ptr->background.green / m, gs) * m + .5);
547.1016 +               png_ptr->background.blue = (png_uint_16)(pow(
547.1017 +                  (double)png_ptr->background.blue / m, gs) * m + .5);
547.1018 +            }
547.1019 +            else
547.1020 +            {
547.1021 +               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
547.1022 +               png_ptr->background_1.red = png_ptr->background_1.green
547.1023 +                 = png_ptr->background_1.blue = png_ptr->background_1.gray;
547.1024 +               png_ptr->background.red = png_ptr->background.green
547.1025 +                 = png_ptr->background.blue = png_ptr->background.gray;
547.1026 +            }
547.1027 +         }
547.1028 +      }
547.1029 +      else
547.1030 +      /* transformation does not include PNG_BACKGROUND */
547.1031 +#endif /* PNG_READ_BACKGROUND_SUPPORTED */
547.1032 +      if (color_type == PNG_COLOR_TYPE_PALETTE)
547.1033 +      {
547.1034 +         png_colorp palette = png_ptr->palette;
547.1035 +         int num_palette = png_ptr->num_palette;
547.1036 +         int i;
547.1037 +
547.1038 +         for (i = 0; i < num_palette; i++)
547.1039 +         {
547.1040 +            palette[i].red = png_ptr->gamma_table[palette[i].red];
547.1041 +            palette[i].green = png_ptr->gamma_table[palette[i].green];
547.1042 +            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
547.1043 +         }
547.1044 +
547.1045 +	 /* Done the gamma correction. */
547.1046 +	 png_ptr->transformations &= ~PNG_GAMMA;
547.1047 +      }
547.1048 +   }
547.1049 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
547.1050 +   else
547.1051 +#endif
547.1052 +#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
547.1053 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
547.1054 +   /* No GAMMA transformation */
547.1055 +   if ((png_ptr->transformations & PNG_BACKGROUND) &&
547.1056 +       (color_type == PNG_COLOR_TYPE_PALETTE))
547.1057 +   {
547.1058 +      int i;
547.1059 +      int istop = (int)png_ptr->num_trans;
547.1060 +      png_color back;
547.1061 +      png_colorp palette = png_ptr->palette;
547.1062 +
547.1063 +      back.red   = (png_byte)png_ptr->background.red;
547.1064 +      back.green = (png_byte)png_ptr->background.green;
547.1065 +      back.blue  = (png_byte)png_ptr->background.blue;
547.1066 +
547.1067 +      for (i = 0; i < istop; i++)
547.1068 +      {
547.1069 +         if (png_ptr->trans[i] == 0)
547.1070 +         {
547.1071 +            palette[i] = back;
547.1072 +         }
547.1073 +         else if (png_ptr->trans[i] != 0xff)
547.1074 +         {
547.1075 +            /* The png_composite() macro is defined in png.h */
547.1076 +            png_composite(palette[i].red, palette[i].red,
547.1077 +               png_ptr->trans[i], back.red);
547.1078 +            png_composite(palette[i].green, palette[i].green,
547.1079 +               png_ptr->trans[i], back.green);
547.1080 +            png_composite(palette[i].blue, palette[i].blue,
547.1081 +               png_ptr->trans[i], back.blue);
547.1082 +         }
547.1083 +      }
547.1084 +
547.1085 +      /* Handled alpha, still need to strip the channel. */
547.1086 +      png_ptr->transformations &= ~PNG_BACKGROUND;
547.1087 +      png_ptr->transformations |= PNG_STRIP_ALPHA;
547.1088 +   }
547.1089 +#endif /* PNG_READ_BACKGROUND_SUPPORTED */
547.1090 +
547.1091 +#if defined(PNG_READ_SHIFT_SUPPORTED)
547.1092 +   if ((png_ptr->transformations & PNG_SHIFT) &&
547.1093 +      (color_type == PNG_COLOR_TYPE_PALETTE))
547.1094 +   {
547.1095 +      png_uint_16 i;
547.1096 +      png_uint_16 istop = png_ptr->num_palette;
547.1097 +      int sr = 8 - png_ptr->sig_bit.red;
547.1098 +      int sg = 8 - png_ptr->sig_bit.green;
547.1099 +      int sb = 8 - png_ptr->sig_bit.blue;
547.1100 +
547.1101 +      if (sr < 0 || sr > 8)
547.1102 +         sr = 0;
547.1103 +      if (sg < 0 || sg > 8)
547.1104 +         sg = 0;
547.1105 +      if (sb < 0 || sb > 8)
547.1106 +         sb = 0;
547.1107 +      for (i = 0; i < istop; i++)
547.1108 +      {
547.1109 +         png_ptr->palette[i].red >>= sr;
547.1110 +         png_ptr->palette[i].green >>= sg;
547.1111 +         png_ptr->palette[i].blue >>= sb;
547.1112 +      }
547.1113 +   }
547.1114 +#endif  /* PNG_READ_SHIFT_SUPPORTED */
547.1115 + }
547.1116 +#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
547.1117 + && !defined(PNG_READ_BACKGROUND_SUPPORTED)
547.1118 +   if (png_ptr)
547.1119 +      return;
547.1120 +#endif
547.1121 +}
547.1122 +
547.1123 +/* Modify the info structure to reflect the transformations.  The
547.1124 + * info should be updated so a PNG file could be written with it,
547.1125 + * assuming the transformations result in valid PNG data.
547.1126 + */
547.1127 +void /* PRIVATE */
547.1128 +png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
547.1129 +{
547.1130 +   png_debug(1, "in png_read_transform_info\n");
547.1131 +#if defined(PNG_READ_EXPAND_SUPPORTED)
547.1132 +   if (png_ptr->transformations & PNG_EXPAND)
547.1133 +   {
547.1134 +      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
547.1135 +      {
547.1136 +         if (png_ptr->num_trans &&
547.1137 +              (png_ptr->transformations & PNG_EXPAND_tRNS))
547.1138 +            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
547.1139 +         else
547.1140 +            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
547.1141 +         info_ptr->bit_depth = 8;
547.1142 +         info_ptr->num_trans = 0;
547.1143 +      }
547.1144 +      else
547.1145 +      {
547.1146 +         if (png_ptr->num_trans)
547.1147 +         {
547.1148 +            if (png_ptr->transformations & PNG_EXPAND_tRNS)
547.1149 +              info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
547.1150 +#if 0 /* Removed from libpng-1.2.27 */
547.1151 +            else
547.1152 +              info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
547.1153 +#endif
547.1154 +         }
547.1155 +         if (info_ptr->bit_depth < 8)
547.1156 +            info_ptr->bit_depth = 8;
547.1157 +         info_ptr->num_trans = 0;
547.1158 +      }
547.1159 +   }
547.1160 +#endif
547.1161 +
547.1162 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
547.1163 +   if (png_ptr->transformations & PNG_BACKGROUND)
547.1164 +   {
547.1165 +      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
547.1166 +      info_ptr->num_trans = 0;
547.1167 +      info_ptr->background = png_ptr->background;
547.1168 +   }
547.1169 +#endif
547.1170 +
547.1171 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.1172 +   if (png_ptr->transformations & PNG_GAMMA)
547.1173 +   {
547.1174 +#ifdef PNG_FLOATING_POINT_SUPPORTED
547.1175 +      info_ptr->gamma = png_ptr->gamma;
547.1176 +#endif
547.1177 +#ifdef PNG_FIXED_POINT_SUPPORTED
547.1178 +      info_ptr->int_gamma = png_ptr->int_gamma;
547.1179 +#endif
547.1180 +   }
547.1181 +#endif
547.1182 +
547.1183 +#if defined(PNG_READ_16_TO_8_SUPPORTED)
547.1184 +   if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
547.1185 +      info_ptr->bit_depth = 8;
547.1186 +#endif
547.1187 +
547.1188 +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
547.1189 +   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
547.1190 +      info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
547.1191 +#endif
547.1192 +
547.1193 +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
547.1194 +   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
547.1195 +      info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
547.1196 +#endif
547.1197 +
547.1198 +#if defined(PNG_READ_DITHER_SUPPORTED)
547.1199 +   if (png_ptr->transformations & PNG_DITHER)
547.1200 +   {
547.1201 +      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
547.1202 +         (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
547.1203 +         png_ptr->palette_lookup && info_ptr->bit_depth == 8)
547.1204 +      {
547.1205 +         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
547.1206 +      }
547.1207 +   }
547.1208 +#endif
547.1209 +
547.1210 +#if defined(PNG_READ_PACK_SUPPORTED)
547.1211 +   if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
547.1212 +      info_ptr->bit_depth = 8;
547.1213 +#endif
547.1214 +
547.1215 +   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
547.1216 +      info_ptr->channels = 1;
547.1217 +   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
547.1218 +      info_ptr->channels = 3;
547.1219 +   else
547.1220 +      info_ptr->channels = 1;
547.1221 +
547.1222 +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
547.1223 +   if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
547.1224 +      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
547.1225 +#endif
547.1226 +
547.1227 +   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
547.1228 +      info_ptr->channels++;
547.1229 +
547.1230 +#if defined(PNG_READ_FILLER_SUPPORTED)
547.1231 +   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
547.1232 +   if ((png_ptr->transformations & PNG_FILLER) &&
547.1233 +       ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
547.1234 +       (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
547.1235 +   {
547.1236 +      info_ptr->channels++;
547.1237 +      /* if adding a true alpha channel not just filler */
547.1238 +#if !defined(PNG_1_0_X)
547.1239 +      if (png_ptr->transformations & PNG_ADD_ALPHA)
547.1240 +        info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
547.1241 +#endif
547.1242 +   }
547.1243 +#endif
547.1244 +
547.1245 +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
547.1246 +defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
547.1247 +   if (png_ptr->transformations & PNG_USER_TRANSFORM)
547.1248 +     {
547.1249 +       if (info_ptr->bit_depth < png_ptr->user_transform_depth)
547.1250 +         info_ptr->bit_depth = png_ptr->user_transform_depth;
547.1251 +       if (info_ptr->channels < png_ptr->user_transform_channels)
547.1252 +         info_ptr->channels = png_ptr->user_transform_channels;
547.1253 +     }
547.1254 +#endif
547.1255 +
547.1256 +   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
547.1257 +      info_ptr->bit_depth);
547.1258 +
547.1259 +   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
547.1260 +
547.1261 +#if !defined(PNG_READ_EXPAND_SUPPORTED)
547.1262 +   if (png_ptr)
547.1263 +      return;
547.1264 +#endif
547.1265 +}
547.1266 +
547.1267 +/* Transform the row.  The order of transformations is significant,
547.1268 + * and is very touchy.  If you add a transformation, take care to
547.1269 + * decide how it fits in with the other transformations here.
547.1270 + */
547.1271 +void /* PRIVATE */
547.1272 +png_do_read_transformations(png_structp png_ptr)
547.1273 +{
547.1274 +   png_debug(1, "in png_do_read_transformations\n");
547.1275 +   if (png_ptr->row_buf == NULL)
547.1276 +   {
547.1277 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
547.1278 +      char msg[50];
547.1279 +
547.1280 +      png_snprintf2(msg, 50,
547.1281 +         "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number,
547.1282 +         png_ptr->pass);
547.1283 +      png_error(png_ptr, msg);
547.1284 +#else
547.1285 +      png_error(png_ptr, "NULL row buffer");
547.1286 +#endif
547.1287 +   }
547.1288 +#ifdef PNG_WARN_UNINITIALIZED_ROW
547.1289 +   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
547.1290 +      /* Application has failed to call either png_read_start_image()
547.1291 +       * or png_read_update_info() after setting transforms that expand
547.1292 +       * pixels.  This check added to libpng-1.2.19 */
547.1293 +#if (PNG_WARN_UNINITIALIZED_ROW==1)
547.1294 +      png_error(png_ptr, "Uninitialized row");
547.1295 +#else
547.1296 +      png_warning(png_ptr, "Uninitialized row");
547.1297 +#endif
547.1298 +#endif
547.1299 +
547.1300 +#if defined(PNG_READ_EXPAND_SUPPORTED)
547.1301 +   if (png_ptr->transformations & PNG_EXPAND)
547.1302 +   {
547.1303 +      if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
547.1304 +      {
547.1305 +         png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
547.1306 +            png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
547.1307 +      }
547.1308 +      else
547.1309 +      {
547.1310 +         if (png_ptr->num_trans &&
547.1311 +             (png_ptr->transformations & PNG_EXPAND_tRNS))
547.1312 +            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
547.1313 +               &(png_ptr->trans_values));
547.1314 +         else
547.1315 +            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
547.1316 +               NULL);
547.1317 +      }
547.1318 +   }
547.1319 +#endif
547.1320 +
547.1321 +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
547.1322 +   if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
547.1323 +      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
547.1324 +         PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
547.1325 +#endif
547.1326 +
547.1327 +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
547.1328 +   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
547.1329 +   {
547.1330 +      int rgb_error =
547.1331 +         png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
547.1332 +      if (rgb_error)
547.1333 +      {
547.1334 +         png_ptr->rgb_to_gray_status=1;
547.1335 +         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 
547.1336 +             PNG_RGB_TO_GRAY_WARN)
547.1337 +            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
547.1338 +         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
547.1339 +             PNG_RGB_TO_GRAY_ERR)
547.1340 +            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
547.1341 +      }
547.1342 +   }
547.1343 +#endif
547.1344 +
547.1345 +/*
547.1346 +From Andreas Dilger e-mail to png-implement, 26 March 1998:
547.1347 +
547.1348 +  In most cases, the "simple transparency" should be done prior to doing
547.1349 +  gray-to-RGB, or you will have to test 3x as many bytes to check if a
547.1350 +  pixel is transparent.  You would also need to make sure that the
547.1351 +  transparency information is upgraded to RGB.
547.1352 +
547.1353 +  To summarize, the current flow is:
547.1354 +  - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
547.1355 +                                  with background "in place" if transparent,
547.1356 +                                  convert to RGB if necessary
547.1357 +  - Gray + alpha -> composite with gray background and remove alpha bytes,
547.1358 +                                  convert to RGB if necessary
547.1359 +
547.1360 +  To support RGB backgrounds for gray images we need:
547.1361 +  - Gray + simple transparency -> convert to RGB + simple transparency, compare
547.1362 +                                  3 or 6 bytes and composite with background
547.1363 +                                  "in place" if transparent (3x compare/pixel
547.1364 +                                  compared to doing composite with gray bkgrnd)
547.1365 +  - Gray + alpha -> convert to RGB + alpha, composite with background and
547.1366 +                                  remove alpha bytes (3x float operations/pixel
547.1367 +                                  compared with composite on gray background)
547.1368 +
547.1369 +  Greg's change will do this.  The reason it wasn't done before is for
547.1370 +  performance, as this increases the per-pixel operations.  If we would check
547.1371 +  in advance if the background was gray or RGB, and position the gray-to-RGB
547.1372 +  transform appropriately, then it would save a lot of work/time.
547.1373 + */
547.1374 +
547.1375 +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
547.1376 +   /* if gray -> RGB, do so now only if background is non-gray; else do later
547.1377 +    * for performance reasons */
547.1378 +   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
547.1379 +       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
547.1380 +      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
547.1381 +#endif
547.1382 +
547.1383 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
547.1384 +   if ((png_ptr->transformations & PNG_BACKGROUND) &&
547.1385 +      ((png_ptr->num_trans != 0 ) ||
547.1386 +      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
547.1387 +      png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
547.1388 +         &(png_ptr->trans_values), &(png_ptr->background)
547.1389 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.1390 +         , &(png_ptr->background_1),
547.1391 +         png_ptr->gamma_table, png_ptr->gamma_from_1,
547.1392 +         png_ptr->gamma_to_1, png_ptr->gamma_16_table,
547.1393 +         png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
547.1394 +         png_ptr->gamma_shift
547.1395 +#endif
547.1396 +);
547.1397 +#endif
547.1398 +
547.1399 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.1400 +   if ((png_ptr->transformations & PNG_GAMMA) &&
547.1401 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
547.1402 +      !((png_ptr->transformations & PNG_BACKGROUND) &&
547.1403 +      ((png_ptr->num_trans != 0) ||
547.1404 +      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
547.1405 +#endif
547.1406 +      (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
547.1407 +      png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
547.1408 +         png_ptr->gamma_table, png_ptr->gamma_16_table,
547.1409 +         png_ptr->gamma_shift);
547.1410 +#endif
547.1411 +
547.1412 +#if defined(PNG_READ_16_TO_8_SUPPORTED)
547.1413 +   if (png_ptr->transformations & PNG_16_TO_8)
547.1414 +      png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
547.1415 +#endif
547.1416 +
547.1417 +#if defined(PNG_READ_DITHER_SUPPORTED)
547.1418 +   if (png_ptr->transformations & PNG_DITHER)
547.1419 +   {
547.1420 +      png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
547.1421 +         png_ptr->palette_lookup, png_ptr->dither_index);
547.1422 +      if (png_ptr->row_info.rowbytes == (png_uint_32)0)
547.1423 +         png_error(png_ptr, "png_do_dither returned rowbytes=0");
547.1424 +   }
547.1425 +#endif
547.1426 +
547.1427 +#if defined(PNG_READ_INVERT_SUPPORTED)
547.1428 +   if (png_ptr->transformations & PNG_INVERT_MONO)
547.1429 +      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
547.1430 +#endif
547.1431 +
547.1432 +#if defined(PNG_READ_SHIFT_SUPPORTED)
547.1433 +   if (png_ptr->transformations & PNG_SHIFT)
547.1434 +      png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
547.1435 +         &(png_ptr->shift));
547.1436 +#endif
547.1437 +
547.1438 +#if defined(PNG_READ_PACK_SUPPORTED)
547.1439 +   if (png_ptr->transformations & PNG_PACK)
547.1440 +      png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
547.1441 +#endif
547.1442 +
547.1443 +#if defined(PNG_READ_BGR_SUPPORTED)
547.1444 +   if (png_ptr->transformations & PNG_BGR)
547.1445 +      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
547.1446 +#endif
547.1447 +
547.1448 +#if defined(PNG_READ_PACKSWAP_SUPPORTED)
547.1449 +   if (png_ptr->transformations & PNG_PACKSWAP)
547.1450 +      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
547.1451 +#endif
547.1452 +
547.1453 +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
547.1454 +   /* if gray -> RGB, do so now only if we did not do so above */
547.1455 +   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
547.1456 +       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
547.1457 +      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
547.1458 +#endif
547.1459 +
547.1460 +#if defined(PNG_READ_FILLER_SUPPORTED)
547.1461 +   if (png_ptr->transformations & PNG_FILLER)
547.1462 +      png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
547.1463 +         (png_uint_32)png_ptr->filler, png_ptr->flags);
547.1464 +#endif
547.1465 +
547.1466 +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
547.1467 +   if (png_ptr->transformations & PNG_INVERT_ALPHA)
547.1468 +      png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
547.1469 +#endif
547.1470 +
547.1471 +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
547.1472 +   if (png_ptr->transformations & PNG_SWAP_ALPHA)
547.1473 +      png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
547.1474 +#endif
547.1475 +
547.1476 +#if defined(PNG_READ_SWAP_SUPPORTED)
547.1477 +   if (png_ptr->transformations & PNG_SWAP_BYTES)
547.1478 +      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
547.1479 +#endif
547.1480 +
547.1481 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
547.1482 +   if (png_ptr->transformations & PNG_USER_TRANSFORM)
547.1483 +    {
547.1484 +      if (png_ptr->read_user_transform_fn != NULL)
547.1485 +        (*(png_ptr->read_user_transform_fn)) /* user read transform function */
547.1486 +          (png_ptr,                    /* png_ptr */
547.1487 +           &(png_ptr->row_info),       /* row_info:     */
547.1488 +             /*  png_uint_32 width;          width of row */
547.1489 +             /*  png_uint_32 rowbytes;       number of bytes in row */
547.1490 +             /*  png_byte color_type;        color type of pixels */
547.1491 +             /*  png_byte bit_depth;         bit depth of samples */
547.1492 +             /*  png_byte channels;          number of channels (1-4) */
547.1493 +             /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
547.1494 +           png_ptr->row_buf + 1);      /* start of pixel data for row */
547.1495 +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
547.1496 +      if (png_ptr->user_transform_depth)
547.1497 +         png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
547.1498 +      if (png_ptr->user_transform_channels)
547.1499 +         png_ptr->row_info.channels = png_ptr->user_transform_channels;
547.1500 +#endif
547.1501 +      png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
547.1502 +         png_ptr->row_info.channels);
547.1503 +      png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
547.1504 +         png_ptr->row_info.width);
547.1505 +   }
547.1506 +#endif
547.1507 +
547.1508 +}
547.1509 +
547.1510 +#if defined(PNG_READ_PACK_SUPPORTED)
547.1511 +/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
547.1512 + * without changing the actual values.  Thus, if you had a row with
547.1513 + * a bit depth of 1, you would end up with bytes that only contained
547.1514 + * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
547.1515 + * png_do_shift() after this.
547.1516 + */
547.1517 +void /* PRIVATE */
547.1518 +png_do_unpack(png_row_infop row_info, png_bytep row)
547.1519 +{
547.1520 +   png_debug(1, "in png_do_unpack\n");
547.1521 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.1522 +   if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
547.1523 +#else
547.1524 +   if (row_info->bit_depth < 8)
547.1525 +#endif
547.1526 +   {
547.1527 +      png_uint_32 i;
547.1528 +      png_uint_32 row_width=row_info->width;
547.1529 +
547.1530 +      switch (row_info->bit_depth)
547.1531 +      {
547.1532 +         case 1:
547.1533 +         {
547.1534 +            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
547.1535 +            png_bytep dp = row + (png_size_t)row_width - 1;
547.1536 +            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
547.1537 +            for (i = 0; i < row_width; i++)
547.1538 +            {
547.1539 +               *dp = (png_byte)((*sp >> shift) & 0x01);
547.1540 +               if (shift == 7)
547.1541 +               {
547.1542 +                  shift = 0;
547.1543 +                  sp--;
547.1544 +               }
547.1545 +               else
547.1546 +                  shift++;
547.1547 +
547.1548 +               dp--;
547.1549 +            }
547.1550 +            break;
547.1551 +         }
547.1552 +         case 2:
547.1553 +         {
547.1554 +
547.1555 +            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
547.1556 +            png_bytep dp = row + (png_size_t)row_width - 1;
547.1557 +            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
547.1558 +            for (i = 0; i < row_width; i++)
547.1559 +            {
547.1560 +               *dp = (png_byte)((*sp >> shift) & 0x03);
547.1561 +               if (shift == 6)
547.1562 +               {
547.1563 +                  shift = 0;
547.1564 +                  sp--;
547.1565 +               }
547.1566 +               else
547.1567 +                  shift += 2;
547.1568 +
547.1569 +               dp--;
547.1570 +            }
547.1571 +            break;
547.1572 +         }
547.1573 +         case 4:
547.1574 +         {
547.1575 +            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
547.1576 +            png_bytep dp = row + (png_size_t)row_width - 1;
547.1577 +            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
547.1578 +            for (i = 0; i < row_width; i++)
547.1579 +            {
547.1580 +               *dp = (png_byte)((*sp >> shift) & 0x0f);
547.1581 +               if (shift == 4)
547.1582 +               {
547.1583 +                  shift = 0;
547.1584 +                  sp--;
547.1585 +               }
547.1586 +               else
547.1587 +                  shift = 4;
547.1588 +
547.1589 +               dp--;
547.1590 +            }
547.1591 +            break;
547.1592 +         }
547.1593 +      }
547.1594 +      row_info->bit_depth = 8;
547.1595 +      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
547.1596 +      row_info->rowbytes = row_width * row_info->channels;
547.1597 +   }
547.1598 +}
547.1599 +#endif
547.1600 +
547.1601 +#if defined(PNG_READ_SHIFT_SUPPORTED)
547.1602 +/* Reverse the effects of png_do_shift.  This routine merely shifts the
547.1603 + * pixels back to their significant bits values.  Thus, if you have
547.1604 + * a row of bit depth 8, but only 5 are significant, this will shift
547.1605 + * the values back to 0 through 31.
547.1606 + */
547.1607 +void /* PRIVATE */
547.1608 +png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
547.1609 +{
547.1610 +   png_debug(1, "in png_do_unshift\n");
547.1611 +   if (
547.1612 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.1613 +       row != NULL && row_info != NULL && sig_bits != NULL &&
547.1614 +#endif
547.1615 +       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
547.1616 +   {
547.1617 +      int shift[4];
547.1618 +      int channels = 0;
547.1619 +      int c;
547.1620 +      png_uint_16 value = 0;
547.1621 +      png_uint_32 row_width = row_info->width;
547.1622 +
547.1623 +      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
547.1624 +      {
547.1625 +         shift[channels++] = row_info->bit_depth - sig_bits->red;
547.1626 +         shift[channels++] = row_info->bit_depth - sig_bits->green;
547.1627 +         shift[channels++] = row_info->bit_depth - sig_bits->blue;
547.1628 +      }
547.1629 +      else
547.1630 +      {
547.1631 +         shift[channels++] = row_info->bit_depth - sig_bits->gray;
547.1632 +      }
547.1633 +      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
547.1634 +      {
547.1635 +         shift[channels++] = row_info->bit_depth - sig_bits->alpha;
547.1636 +      }
547.1637 +
547.1638 +      for (c = 0; c < channels; c++)
547.1639 +      {
547.1640 +         if (shift[c] <= 0)
547.1641 +            shift[c] = 0;
547.1642 +         else
547.1643 +            value = 1;
547.1644 +      }
547.1645 +
547.1646 +      if (!value)
547.1647 +         return;
547.1648 +
547.1649 +      switch (row_info->bit_depth)
547.1650 +      {
547.1651 +         case 2:
547.1652 +         {
547.1653 +            png_bytep bp;
547.1654 +            png_uint_32 i;
547.1655 +            png_uint_32 istop = row_info->rowbytes;
547.1656 +
547.1657 +            for (bp = row, i = 0; i < istop; i++)
547.1658 +            {
547.1659 +               *bp >>= 1;
547.1660 +               *bp++ &= 0x55;
547.1661 +            }
547.1662 +            break;
547.1663 +         }
547.1664 +         case 4:
547.1665 +         {
547.1666 +            png_bytep bp = row;
547.1667 +            png_uint_32 i;
547.1668 +            png_uint_32 istop = row_info->rowbytes;
547.1669 +            png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
547.1670 +               (png_byte)((int)0xf >> shift[0]));
547.1671 +
547.1672 +            for (i = 0; i < istop; i++)
547.1673 +            {
547.1674 +               *bp >>= shift[0];
547.1675 +               *bp++ &= mask;
547.1676 +            }
547.1677 +            break;
547.1678 +         }
547.1679 +         case 8:
547.1680 +         {
547.1681 +            png_bytep bp = row;
547.1682 +            png_uint_32 i;
547.1683 +            png_uint_32 istop = row_width * channels;
547.1684 +
547.1685 +            for (i = 0; i < istop; i++)
547.1686 +            {
547.1687 +               *bp++ >>= shift[i%channels];
547.1688 +            }
547.1689 +            break;
547.1690 +         }
547.1691 +         case 16:
547.1692 +         {
547.1693 +            png_bytep bp = row;
547.1694 +            png_uint_32 i;
547.1695 +            png_uint_32 istop = channels * row_width;
547.1696 +
547.1697 +            for (i = 0; i < istop; i++)
547.1698 +            {
547.1699 +               value = (png_uint_16)((*bp << 8) + *(bp + 1));
547.1700 +               value >>= shift[i%channels];
547.1701 +               *bp++ = (png_byte)(value >> 8);
547.1702 +               *bp++ = (png_byte)(value & 0xff);
547.1703 +            }
547.1704 +            break;
547.1705 +         }
547.1706 +      }
547.1707 +   }
547.1708 +}
547.1709 +#endif
547.1710 +
547.1711 +#if defined(PNG_READ_16_TO_8_SUPPORTED)
547.1712 +/* chop rows of bit depth 16 down to 8 */
547.1713 +void /* PRIVATE */
547.1714 +png_do_chop(png_row_infop row_info, png_bytep row)
547.1715 +{
547.1716 +   png_debug(1, "in png_do_chop\n");
547.1717 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.1718 +   if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
547.1719 +#else
547.1720 +   if (row_info->bit_depth == 16)
547.1721 +#endif
547.1722 +   {
547.1723 +      png_bytep sp = row;
547.1724 +      png_bytep dp = row;
547.1725 +      png_uint_32 i;
547.1726 +      png_uint_32 istop = row_info->width * row_info->channels;
547.1727 +
547.1728 +      for (i = 0; i<istop; i++, sp += 2, dp++)
547.1729 +      {
547.1730 +#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
547.1731 +      /* This does a more accurate scaling of the 16-bit color
547.1732 +       * value, rather than a simple low-byte truncation.
547.1733 +       *
547.1734 +       * What the ideal calculation should be:
547.1735 +       *   *dp = (((((png_uint_32)(*sp) << 8) |
547.1736 +       *          (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
547.1737 +       *
547.1738 +       * GRR: no, I think this is what it really should be:
547.1739 +       *   *dp = (((((png_uint_32)(*sp) << 8) |
547.1740 +       *           (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
547.1741 +       *
547.1742 +       * GRR: here's the exact calculation with shifts:
547.1743 +       *   temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
547.1744 +       *   *dp = (temp - (temp >> 8)) >> 8;
547.1745 +       *
547.1746 +       * Approximate calculation with shift/add instead of multiply/divide:
547.1747 +       *   *dp = ((((png_uint_32)(*sp) << 8) |
547.1748 +       *          (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
547.1749 +       *
547.1750 +       * What we actually do to avoid extra shifting and conversion:
547.1751 +       */
547.1752 +
547.1753 +         *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
547.1754 +#else
547.1755 +       /* Simply discard the low order byte */
547.1756 +         *dp = *sp;
547.1757 +#endif
547.1758 +      }
547.1759 +      row_info->bit_depth = 8;
547.1760 +      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
547.1761 +      row_info->rowbytes = row_info->width * row_info->channels;
547.1762 +   }
547.1763 +}
547.1764 +#endif
547.1765 +
547.1766 +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
547.1767 +void /* PRIVATE */
547.1768 +png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
547.1769 +{
547.1770 +   png_debug(1, "in png_do_read_swap_alpha\n");
547.1771 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.1772 +   if (row != NULL && row_info != NULL)
547.1773 +#endif
547.1774 +   {
547.1775 +      png_uint_32 row_width = row_info->width;
547.1776 +      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
547.1777 +      {
547.1778 +         /* This converts from RGBA to ARGB */
547.1779 +         if (row_info->bit_depth == 8)
547.1780 +         {
547.1781 +            png_bytep sp = row + row_info->rowbytes;
547.1782 +            png_bytep dp = sp;
547.1783 +            png_byte save;
547.1784 +            png_uint_32 i;
547.1785 +
547.1786 +            for (i = 0; i < row_width; i++)
547.1787 +            {
547.1788 +               save = *(--sp);
547.1789 +               *(--dp) = *(--sp);
547.1790 +               *(--dp) = *(--sp);
547.1791 +               *(--dp) = *(--sp);
547.1792 +               *(--dp) = save;
547.1793 +            }
547.1794 +         }
547.1795 +         /* This converts from RRGGBBAA to AARRGGBB */
547.1796 +         else
547.1797 +         {
547.1798 +            png_bytep sp = row + row_info->rowbytes;
547.1799 +            png_bytep dp = sp;
547.1800 +            png_byte save[2];
547.1801 +            png_uint_32 i;
547.1802 +
547.1803 +            for (i = 0; i < row_width; i++)
547.1804 +            {
547.1805 +               save[0] = *(--sp);
547.1806 +               save[1] = *(--sp);
547.1807 +               *(--dp) = *(--sp);
547.1808 +               *(--dp) = *(--sp);
547.1809 +               *(--dp) = *(--sp);
547.1810 +               *(--dp) = *(--sp);
547.1811 +               *(--dp) = *(--sp);
547.1812 +               *(--dp) = *(--sp);
547.1813 +               *(--dp) = save[0];
547.1814 +               *(--dp) = save[1];
547.1815 +            }
547.1816 +         }
547.1817 +      }
547.1818 +      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
547.1819 +      {
547.1820 +         /* This converts from GA to AG */
547.1821 +         if (row_info->bit_depth == 8)
547.1822 +         {
547.1823 +            png_bytep sp = row + row_info->rowbytes;
547.1824 +            png_bytep dp = sp;
547.1825 +            png_byte save;
547.1826 +            png_uint_32 i;
547.1827 +
547.1828 +            for (i = 0; i < row_width; i++)
547.1829 +            {
547.1830 +               save = *(--sp);
547.1831 +               *(--dp) = *(--sp);
547.1832 +               *(--dp) = save;
547.1833 +            }
547.1834 +         }
547.1835 +         /* This converts from GGAA to AAGG */
547.1836 +         else
547.1837 +         {
547.1838 +            png_bytep sp = row + row_info->rowbytes;
547.1839 +            png_bytep dp = sp;
547.1840 +            png_byte save[2];
547.1841 +            png_uint_32 i;
547.1842 +
547.1843 +            for (i = 0; i < row_width; i++)
547.1844 +            {
547.1845 +               save[0] = *(--sp);
547.1846 +               save[1] = *(--sp);
547.1847 +               *(--dp) = *(--sp);
547.1848 +               *(--dp) = *(--sp);
547.1849 +               *(--dp) = save[0];
547.1850 +               *(--dp) = save[1];
547.1851 +            }
547.1852 +         }
547.1853 +      }
547.1854 +   }
547.1855 +}
547.1856 +#endif
547.1857 +
547.1858 +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
547.1859 +void /* PRIVATE */
547.1860 +png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
547.1861 +{
547.1862 +   png_debug(1, "in png_do_read_invert_alpha\n");
547.1863 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.1864 +   if (row != NULL && row_info != NULL)
547.1865 +#endif
547.1866 +   {
547.1867 +      png_uint_32 row_width = row_info->width;
547.1868 +      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
547.1869 +      {
547.1870 +         /* This inverts the alpha channel in RGBA */
547.1871 +         if (row_info->bit_depth == 8)
547.1872 +         {
547.1873 +            png_bytep sp = row + row_info->rowbytes;
547.1874 +            png_bytep dp = sp;
547.1875 +            png_uint_32 i;
547.1876 +
547.1877 +            for (i = 0; i < row_width; i++)
547.1878 +            {
547.1879 +               *(--dp) = (png_byte)(255 - *(--sp));
547.1880 +
547.1881 +/*             This does nothing:
547.1882 +               *(--dp) = *(--sp);
547.1883 +               *(--dp) = *(--sp);
547.1884 +               *(--dp) = *(--sp);
547.1885 +               We can replace it with:
547.1886 +*/
547.1887 +               sp-=3;
547.1888 +               dp=sp;
547.1889 +            }
547.1890 +         }
547.1891 +         /* This inverts the alpha channel in RRGGBBAA */
547.1892 +         else
547.1893 +         {
547.1894 +            png_bytep sp = row + row_info->rowbytes;
547.1895 +            png_bytep dp = sp;
547.1896 +            png_uint_32 i;
547.1897 +
547.1898 +            for (i = 0; i < row_width; i++)
547.1899 +            {
547.1900 +               *(--dp) = (png_byte)(255 - *(--sp));
547.1901 +               *(--dp) = (png_byte)(255 - *(--sp));
547.1902 +
547.1903 +/*             This does nothing:
547.1904 +               *(--dp) = *(--sp);
547.1905 +               *(--dp) = *(--sp);
547.1906 +               *(--dp) = *(--sp);
547.1907 +               *(--dp) = *(--sp);
547.1908 +               *(--dp) = *(--sp);
547.1909 +               *(--dp) = *(--sp);
547.1910 +               We can replace it with:
547.1911 +*/
547.1912 +               sp-=6;
547.1913 +               dp=sp;
547.1914 +            }
547.1915 +         }
547.1916 +      }
547.1917 +      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
547.1918 +      {
547.1919 +         /* This inverts the alpha channel in GA */
547.1920 +         if (row_info->bit_depth == 8)
547.1921 +         {
547.1922 +            png_bytep sp = row + row_info->rowbytes;
547.1923 +            png_bytep dp = sp;
547.1924 +            png_uint_32 i;
547.1925 +
547.1926 +            for (i = 0; i < row_width; i++)
547.1927 +            {
547.1928 +               *(--dp) = (png_byte)(255 - *(--sp));
547.1929 +               *(--dp) = *(--sp);
547.1930 +            }
547.1931 +         }
547.1932 +         /* This inverts the alpha channel in GGAA */
547.1933 +         else
547.1934 +         {
547.1935 +            png_bytep sp  = row + row_info->rowbytes;
547.1936 +            png_bytep dp = sp;
547.1937 +            png_uint_32 i;
547.1938 +
547.1939 +            for (i = 0; i < row_width; i++)
547.1940 +            {
547.1941 +               *(--dp) = (png_byte)(255 - *(--sp));
547.1942 +               *(--dp) = (png_byte)(255 - *(--sp));
547.1943 +/*
547.1944 +               *(--dp) = *(--sp);
547.1945 +               *(--dp) = *(--sp);
547.1946 +*/
547.1947 +               sp-=2;
547.1948 +               dp=sp;
547.1949 +            }
547.1950 +         }
547.1951 +      }
547.1952 +   }
547.1953 +}
547.1954 +#endif
547.1955 +
547.1956 +#if defined(PNG_READ_FILLER_SUPPORTED)
547.1957 +/* Add filler channel if we have RGB color */
547.1958 +void /* PRIVATE */
547.1959 +png_do_read_filler(png_row_infop row_info, png_bytep row,
547.1960 +   png_uint_32 filler, png_uint_32 flags)
547.1961 +{
547.1962 +   png_uint_32 i;
547.1963 +   png_uint_32 row_width = row_info->width;
547.1964 +
547.1965 +   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
547.1966 +   png_byte lo_filler = (png_byte)(filler & 0xff);
547.1967 +
547.1968 +   png_debug(1, "in png_do_read_filler\n");
547.1969 +   if (
547.1970 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.1971 +       row != NULL  && row_info != NULL &&
547.1972 +#endif
547.1973 +       row_info->color_type == PNG_COLOR_TYPE_GRAY)
547.1974 +   {
547.1975 +      if (row_info->bit_depth == 8)
547.1976 +      {
547.1977 +         /* This changes the data from G to GX */
547.1978 +         if (flags & PNG_FLAG_FILLER_AFTER)
547.1979 +         {
547.1980 +            png_bytep sp = row + (png_size_t)row_width;
547.1981 +            png_bytep dp =  sp + (png_size_t)row_width;
547.1982 +            for (i = 1; i < row_width; i++)
547.1983 +            {
547.1984 +               *(--dp) = lo_filler;
547.1985 +               *(--dp) = *(--sp);
547.1986 +            }
547.1987 +            *(--dp) = lo_filler;
547.1988 +            row_info->channels = 2;
547.1989 +            row_info->pixel_depth = 16;
547.1990 +            row_info->rowbytes = row_width * 2;
547.1991 +         }
547.1992 +      /* This changes the data from G to XG */
547.1993 +         else
547.1994 +         {
547.1995 +            png_bytep sp = row + (png_size_t)row_width;
547.1996 +            png_bytep dp = sp  + (png_size_t)row_width;
547.1997 +            for (i = 0; i < row_width; i++)
547.1998 +            {
547.1999 +               *(--dp) = *(--sp);
547.2000 +               *(--dp) = lo_filler;
547.2001 +            }
547.2002 +            row_info->channels = 2;
547.2003 +            row_info->pixel_depth = 16;
547.2004 +            row_info->rowbytes = row_width * 2;
547.2005 +         }
547.2006 +      }
547.2007 +      else if (row_info->bit_depth == 16)
547.2008 +      {
547.2009 +         /* This changes the data from GG to GGXX */
547.2010 +         if (flags & PNG_FLAG_FILLER_AFTER)
547.2011 +         {
547.2012 +            png_bytep sp = row + (png_size_t)row_width * 2;
547.2013 +            png_bytep dp = sp  + (png_size_t)row_width * 2;
547.2014 +            for (i = 1; i < row_width; i++)
547.2015 +            {
547.2016 +               *(--dp) = hi_filler;
547.2017 +               *(--dp) = lo_filler;
547.2018 +               *(--dp) = *(--sp);
547.2019 +               *(--dp) = *(--sp);
547.2020 +            }
547.2021 +            *(--dp) = hi_filler;
547.2022 +            *(--dp) = lo_filler;
547.2023 +            row_info->channels = 2;
547.2024 +            row_info->pixel_depth = 32;
547.2025 +            row_info->rowbytes = row_width * 4;
547.2026 +         }
547.2027 +         /* This changes the data from GG to XXGG */
547.2028 +         else
547.2029 +         {
547.2030 +            png_bytep sp = row + (png_size_t)row_width * 2;
547.2031 +            png_bytep dp = sp  + (png_size_t)row_width * 2;
547.2032 +            for (i = 0; i < row_width; i++)
547.2033 +            {
547.2034 +               *(--dp) = *(--sp);
547.2035 +               *(--dp) = *(--sp);
547.2036 +               *(--dp) = hi_filler;
547.2037 +               *(--dp) = lo_filler;
547.2038 +            }
547.2039 +            row_info->channels = 2;
547.2040 +            row_info->pixel_depth = 32;
547.2041 +            row_info->rowbytes = row_width * 4;
547.2042 +         }
547.2043 +      }
547.2044 +   } /* COLOR_TYPE == GRAY */
547.2045 +   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
547.2046 +   {
547.2047 +      if (row_info->bit_depth == 8)
547.2048 +      {
547.2049 +         /* This changes the data from RGB to RGBX */
547.2050 +         if (flags & PNG_FLAG_FILLER_AFTER)
547.2051 +         {
547.2052 +            png_bytep sp = row + (png_size_t)row_width * 3;
547.2053 +            png_bytep dp = sp  + (png_size_t)row_width;
547.2054 +            for (i = 1; i < row_width; i++)
547.2055 +            {
547.2056 +               *(--dp) = lo_filler;
547.2057 +               *(--dp) = *(--sp);
547.2058 +               *(--dp) = *(--sp);
547.2059 +               *(--dp) = *(--sp);
547.2060 +            }
547.2061 +            *(--dp) = lo_filler;
547.2062 +            row_info->channels = 4;
547.2063 +            row_info->pixel_depth = 32;
547.2064 +            row_info->rowbytes = row_width * 4;
547.2065 +         }
547.2066 +      /* This changes the data from RGB to XRGB */
547.2067 +         else
547.2068 +         {
547.2069 +            png_bytep sp = row + (png_size_t)row_width * 3;
547.2070 +            png_bytep dp = sp + (png_size_t)row_width;
547.2071 +            for (i = 0; i < row_width; i++)
547.2072 +            {
547.2073 +               *(--dp) = *(--sp);
547.2074 +               *(--dp) = *(--sp);
547.2075 +               *(--dp) = *(--sp);
547.2076 +               *(--dp) = lo_filler;
547.2077 +            }
547.2078 +            row_info->channels = 4;
547.2079 +            row_info->pixel_depth = 32;
547.2080 +            row_info->rowbytes = row_width * 4;
547.2081 +         }
547.2082 +      }
547.2083 +      else if (row_info->bit_depth == 16)
547.2084 +      {
547.2085 +         /* This changes the data from RRGGBB to RRGGBBXX */
547.2086 +         if (flags & PNG_FLAG_FILLER_AFTER)
547.2087 +         {
547.2088 +            png_bytep sp = row + (png_size_t)row_width * 6;
547.2089 +            png_bytep dp = sp  + (png_size_t)row_width * 2;
547.2090 +            for (i = 1; i < row_width; i++)
547.2091 +            {
547.2092 +               *(--dp) = hi_filler;
547.2093 +               *(--dp) = lo_filler;
547.2094 +               *(--dp) = *(--sp);
547.2095 +               *(--dp) = *(--sp);
547.2096 +               *(--dp) = *(--sp);
547.2097 +               *(--dp) = *(--sp);
547.2098 +               *(--dp) = *(--sp);
547.2099 +               *(--dp) = *(--sp);
547.2100 +            }
547.2101 +            *(--dp) = hi_filler;
547.2102 +            *(--dp) = lo_filler;
547.2103 +            row_info->channels = 4;
547.2104 +            row_info->pixel_depth = 64;
547.2105 +            row_info->rowbytes = row_width * 8;
547.2106 +         }
547.2107 +         /* This changes the data from RRGGBB to XXRRGGBB */
547.2108 +         else
547.2109 +         {
547.2110 +            png_bytep sp = row + (png_size_t)row_width * 6;
547.2111 +            png_bytep dp = sp  + (png_size_t)row_width * 2;
547.2112 +            for (i = 0; i < row_width; i++)
547.2113 +            {
547.2114 +               *(--dp) = *(--sp);
547.2115 +               *(--dp) = *(--sp);
547.2116 +               *(--dp) = *(--sp);
547.2117 +               *(--dp) = *(--sp);
547.2118 +               *(--dp) = *(--sp);
547.2119 +               *(--dp) = *(--sp);
547.2120 +               *(--dp) = hi_filler;
547.2121 +               *(--dp) = lo_filler;
547.2122 +            }
547.2123 +            row_info->channels = 4;
547.2124 +            row_info->pixel_depth = 64;
547.2125 +            row_info->rowbytes = row_width * 8;
547.2126 +         }
547.2127 +      }
547.2128 +   } /* COLOR_TYPE == RGB */
547.2129 +}
547.2130 +#endif
547.2131 +
547.2132 +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
547.2133 +/* expand grayscale files to RGB, with or without alpha */
547.2134 +void /* PRIVATE */
547.2135 +png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
547.2136 +{
547.2137 +   png_uint_32 i;
547.2138 +   png_uint_32 row_width = row_info->width;
547.2139 +
547.2140 +   png_debug(1, "in png_do_gray_to_rgb\n");
547.2141 +   if (row_info->bit_depth >= 8 &&
547.2142 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.2143 +       row != NULL && row_info != NULL &&
547.2144 +#endif
547.2145 +      !(row_info->color_type & PNG_COLOR_MASK_COLOR))
547.2146 +   {
547.2147 +      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
547.2148 +      {
547.2149 +         if (row_info->bit_depth == 8)
547.2150 +         {
547.2151 +            png_bytep sp = row + (png_size_t)row_width - 1;
547.2152 +            png_bytep dp = sp  + (png_size_t)row_width * 2;
547.2153 +            for (i = 0; i < row_width; i++)
547.2154 +            {
547.2155 +               *(dp--) = *sp;
547.2156 +               *(dp--) = *sp;
547.2157 +               *(dp--) = *(sp--);
547.2158 +            }
547.2159 +         }
547.2160 +         else
547.2161 +         {
547.2162 +            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
547.2163 +            png_bytep dp = sp  + (png_size_t)row_width * 4;
547.2164 +            for (i = 0; i < row_width; i++)
547.2165 +            {
547.2166 +               *(dp--) = *sp;
547.2167 +               *(dp--) = *(sp - 1);
547.2168 +               *(dp--) = *sp;
547.2169 +               *(dp--) = *(sp - 1);
547.2170 +               *(dp--) = *(sp--);
547.2171 +               *(dp--) = *(sp--);
547.2172 +            }
547.2173 +         }
547.2174 +      }
547.2175 +      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
547.2176 +      {
547.2177 +         if (row_info->bit_depth == 8)
547.2178 +         {
547.2179 +            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
547.2180 +            png_bytep dp = sp  + (png_size_t)row_width * 2;
547.2181 +            for (i = 0; i < row_width; i++)
547.2182 +            {
547.2183 +               *(dp--) = *(sp--);
547.2184 +               *(dp--) = *sp;
547.2185 +               *(dp--) = *sp;
547.2186 +               *(dp--) = *(sp--);
547.2187 +            }
547.2188 +         }
547.2189 +         else
547.2190 +         {
547.2191 +            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
547.2192 +            png_bytep dp = sp  + (png_size_t)row_width * 4;
547.2193 +            for (i = 0; i < row_width; i++)
547.2194 +            {
547.2195 +               *(dp--) = *(sp--);
547.2196 +               *(dp--) = *(sp--);
547.2197 +               *(dp--) = *sp;
547.2198 +               *(dp--) = *(sp - 1);
547.2199 +               *(dp--) = *sp;
547.2200 +               *(dp--) = *(sp - 1);
547.2201 +               *(dp--) = *(sp--);
547.2202 +               *(dp--) = *(sp--);
547.2203 +            }
547.2204 +         }
547.2205 +      }
547.2206 +      row_info->channels += (png_byte)2;
547.2207 +      row_info->color_type |= PNG_COLOR_MASK_COLOR;
547.2208 +      row_info->pixel_depth = (png_byte)(row_info->channels *
547.2209 +         row_info->bit_depth);
547.2210 +      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
547.2211 +   }
547.2212 +}
547.2213 +#endif
547.2214 +
547.2215 +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
547.2216 +/* reduce RGB files to grayscale, with or without alpha
547.2217 + * using the equation given in Poynton's ColorFAQ at
547.2218 + * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008)
547.2219 + * New link:
547.2220 + * <http://www.poynton.com/notes/colour_and_gamma/>
547.2221 + * Charles Poynton poynton at poynton.com
547.2222 + *
547.2223 + *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
547.2224 + *
547.2225 + *  We approximate this with
547.2226 + *
547.2227 + *     Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
547.2228 + *
547.2229 + *  which can be expressed with integers as
547.2230 + *
547.2231 + *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
547.2232 + *
547.2233 + *  The calculation is to be done in a linear colorspace.
547.2234 + *
547.2235 + *  Other integer coefficents can be used via png_set_rgb_to_gray().
547.2236 + */
547.2237 +int /* PRIVATE */
547.2238 +png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
547.2239 +
547.2240 +{
547.2241 +   png_uint_32 i;
547.2242 +
547.2243 +   png_uint_32 row_width = row_info->width;
547.2244 +   int rgb_error = 0;
547.2245 +
547.2246 +   png_debug(1, "in png_do_rgb_to_gray\n");
547.2247 +   if (
547.2248 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.2249 +       row != NULL && row_info != NULL &&
547.2250 +#endif
547.2251 +      (row_info->color_type & PNG_COLOR_MASK_COLOR))
547.2252 +   {
547.2253 +      png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
547.2254 +      png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
547.2255 +      png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
547.2256 +
547.2257 +      if (row_info->color_type == PNG_COLOR_TYPE_RGB)
547.2258 +      {
547.2259 +         if (row_info->bit_depth == 8)
547.2260 +         {
547.2261 +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
547.2262 +            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
547.2263 +            {
547.2264 +               png_bytep sp = row;
547.2265 +               png_bytep dp = row;
547.2266 +
547.2267 +               for (i = 0; i < row_width; i++)
547.2268 +               {
547.2269 +                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
547.2270 +                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
547.2271 +                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
547.2272 +                  if (red != green || red != blue)
547.2273 +                  {
547.2274 +                     rgb_error |= 1;
547.2275 +                     *(dp++) = png_ptr->gamma_from_1[
547.2276 +                       (rc*red + gc*green + bc*blue)>>15];
547.2277 +                  }
547.2278 +                  else
547.2279 +                     *(dp++) = *(sp - 1);
547.2280 +               }
547.2281 +            }
547.2282 +            else
547.2283 +#endif
547.2284 +            {
547.2285 +               png_bytep sp = row;
547.2286 +               png_bytep dp = row;
547.2287 +               for (i = 0; i < row_width; i++)
547.2288 +               {
547.2289 +                  png_byte red   = *(sp++);
547.2290 +                  png_byte green = *(sp++);
547.2291 +                  png_byte blue  = *(sp++);
547.2292 +                  if (red != green || red != blue)
547.2293 +                  {
547.2294 +                     rgb_error |= 1;
547.2295 +                     *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
547.2296 +                  }
547.2297 +                  else
547.2298 +                     *(dp++) = *(sp - 1);
547.2299 +               }
547.2300 +            }
547.2301 +         }
547.2302 +
547.2303 +         else /* RGB bit_depth == 16 */
547.2304 +         {
547.2305 +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
547.2306 +            if (png_ptr->gamma_16_to_1 != NULL &&
547.2307 +                png_ptr->gamma_16_from_1 != NULL)
547.2308 +            {
547.2309 +               png_bytep sp = row;
547.2310 +               png_bytep dp = row;
547.2311 +               for (i = 0; i < row_width; i++)
547.2312 +               {
547.2313 +                  png_uint_16 red, green, blue, w;
547.2314 +
547.2315 +                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
547.2316 +                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
547.2317 +                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
547.2318 +
547.2319 +                  if (red == green && red == blue)
547.2320 +                     w = red;
547.2321 +                  else
547.2322 +                  {
547.2323 +                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
547.2324 +                                  png_ptr->gamma_shift][red>>8];
547.2325 +                     png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
547.2326 +                                  png_ptr->gamma_shift][green>>8];
547.2327 +                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
547.2328 +                                  png_ptr->gamma_shift][blue>>8];
547.2329 +                     png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
547.2330 +                                  + bc*blue_1)>>15);
547.2331 +                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
547.2332 +                         png_ptr->gamma_shift][gray16 >> 8];
547.2333 +                     rgb_error |= 1;
547.2334 +                  }
547.2335 +
547.2336 +                  *(dp++) = (png_byte)((w>>8) & 0xff);
547.2337 +                  *(dp++) = (png_byte)(w & 0xff);
547.2338 +               }
547.2339 +            }
547.2340 +            else
547.2341 +#endif
547.2342 +            {
547.2343 +               png_bytep sp = row;
547.2344 +               png_bytep dp = row;
547.2345 +               for (i = 0; i < row_width; i++)
547.2346 +               {
547.2347 +                  png_uint_16 red, green, blue, gray16;
547.2348 +
547.2349 +                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
547.2350 +                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
547.2351 +                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
547.2352 +
547.2353 +                  if (red != green || red != blue)
547.2354 +                     rgb_error |= 1;
547.2355 +                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
547.2356 +                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
547.2357 +                  *(dp++) = (png_byte)(gray16 & 0xff);
547.2358 +               }
547.2359 +            }
547.2360 +         }
547.2361 +      }
547.2362 +      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
547.2363 +      {
547.2364 +         if (row_info->bit_depth == 8)
547.2365 +         {
547.2366 +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
547.2367 +            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
547.2368 +            {
547.2369 +               png_bytep sp = row;
547.2370 +               png_bytep dp = row;
547.2371 +               for (i = 0; i < row_width; i++)
547.2372 +               {
547.2373 +                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
547.2374 +                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
547.2375 +                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
547.2376 +                  if (red != green || red != blue)
547.2377 +                     rgb_error |= 1;
547.2378 +                  *(dp++) =  png_ptr->gamma_from_1
547.2379 +                             [(rc*red + gc*green + bc*blue)>>15];
547.2380 +                  *(dp++) = *(sp++);  /* alpha */
547.2381 +               }
547.2382 +            }
547.2383 +            else
547.2384 +#endif
547.2385 +            {
547.2386 +               png_bytep sp = row;
547.2387 +               png_bytep dp = row;
547.2388 +               for (i = 0; i < row_width; i++)
547.2389 +               {
547.2390 +                  png_byte red   = *(sp++);
547.2391 +                  png_byte green = *(sp++);
547.2392 +                  png_byte blue  = *(sp++);
547.2393 +                  if (red != green || red != blue)
547.2394 +                     rgb_error |= 1;
547.2395 +                  *(dp++) =  (png_byte)((rc*red + gc*green + bc*blue)>>15);
547.2396 +                  *(dp++) = *(sp++);  /* alpha */
547.2397 +               }
547.2398 +            }
547.2399 +         }
547.2400 +         else /* RGBA bit_depth == 16 */
547.2401 +         {
547.2402 +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
547.2403 +            if (png_ptr->gamma_16_to_1 != NULL &&
547.2404 +                png_ptr->gamma_16_from_1 != NULL)
547.2405 +            {
547.2406 +               png_bytep sp = row;
547.2407 +               png_bytep dp = row;
547.2408 +               for (i = 0; i < row_width; i++)
547.2409 +               {
547.2410 +                  png_uint_16 red, green, blue, w;
547.2411 +
547.2412 +                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
547.2413 +                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
547.2414 +                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
547.2415 +
547.2416 +                  if (red == green && red == blue)
547.2417 +                     w = red;
547.2418 +                  else
547.2419 +                  {
547.2420 +                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
547.2421 +                                  png_ptr->gamma_shift][red>>8];
547.2422 +                     png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
547.2423 +                                  png_ptr->gamma_shift][green>>8];
547.2424 +                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
547.2425 +                                  png_ptr->gamma_shift][blue>>8];
547.2426 +                     png_uint_16 gray16  = (png_uint_16)((rc * red_1
547.2427 +                                  + gc * green_1 + bc * blue_1)>>15);
547.2428 +                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
547.2429 +                         png_ptr->gamma_shift][gray16 >> 8];
547.2430 +                     rgb_error |= 1;
547.2431 +                  }
547.2432 +
547.2433 +                  *(dp++) = (png_byte)((w>>8) & 0xff);
547.2434 +                  *(dp++) = (png_byte)(w & 0xff);
547.2435 +                  *(dp++) = *(sp++);  /* alpha */
547.2436 +                  *(dp++) = *(sp++);
547.2437 +               }
547.2438 +            }
547.2439 +            else
547.2440 +#endif
547.2441 +            {
547.2442 +               png_bytep sp = row;
547.2443 +               png_bytep dp = row;
547.2444 +               for (i = 0; i < row_width; i++)
547.2445 +               {
547.2446 +                  png_uint_16 red, green, blue, gray16;
547.2447 +                  red   = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
547.2448 +                  green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
547.2449 +                  blue  = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
547.2450 +                  if (red != green || red != blue)
547.2451 +                     rgb_error |= 1;
547.2452 +                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
547.2453 +                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
547.2454 +                  *(dp++) = (png_byte)(gray16 & 0xff);
547.2455 +                  *(dp++) = *(sp++);  /* alpha */
547.2456 +                  *(dp++) = *(sp++);
547.2457 +               }
547.2458 +            }
547.2459 +         }
547.2460 +      }
547.2461 +   row_info->channels -= (png_byte)2;
547.2462 +      row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
547.2463 +      row_info->pixel_depth = (png_byte)(row_info->channels *
547.2464 +         row_info->bit_depth);
547.2465 +      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
547.2466 +   }
547.2467 +   return rgb_error;
547.2468 +}
547.2469 +#endif
547.2470 +
547.2471 +/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
547.2472 + * large of png_color.  This lets grayscale images be treated as
547.2473 + * paletted.  Most useful for gamma correction and simplification
547.2474 + * of code.
547.2475 + */
547.2476 +void PNGAPI
547.2477 +png_build_grayscale_palette(int bit_depth, png_colorp palette)
547.2478 +{
547.2479 +   int num_palette;
547.2480 +   int color_inc;
547.2481 +   int i;
547.2482 +   int v;
547.2483 +
547.2484 +   png_debug(1, "in png_do_build_grayscale_palette\n");
547.2485 +   if (palette == NULL)
547.2486 +      return;
547.2487 +
547.2488 +   switch (bit_depth)
547.2489 +   {
547.2490 +      case 1:
547.2491 +         num_palette = 2;
547.2492 +         color_inc = 0xff;
547.2493 +         break;
547.2494 +      case 2:
547.2495 +         num_palette = 4;
547.2496 +         color_inc = 0x55;
547.2497 +         break;
547.2498 +      case 4:
547.2499 +         num_palette = 16;
547.2500 +         color_inc = 0x11;
547.2501 +         break;
547.2502 +      case 8:
547.2503 +         num_palette = 256;
547.2504 +         color_inc = 1;
547.2505 +         break;
547.2506 +      default:
547.2507 +         num_palette = 0;
547.2508 +         color_inc = 0;
547.2509 +         break;
547.2510 +   }
547.2511 +
547.2512 +   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
547.2513 +   {
547.2514 +      palette[i].red = (png_byte)v;
547.2515 +      palette[i].green = (png_byte)v;
547.2516 +      palette[i].blue = (png_byte)v;
547.2517 +   }
547.2518 +}
547.2519 +
547.2520 +/* This function is currently unused.  Do we really need it? */
547.2521 +#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
547.2522 +void /* PRIVATE */
547.2523 +png_correct_palette(png_structp png_ptr, png_colorp palette,
547.2524 +   int num_palette)
547.2525 +{
547.2526 +   png_debug(1, "in png_correct_palette\n");
547.2527 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
547.2528 +    defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
547.2529 +   if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
547.2530 +   {
547.2531 +      png_color back, back_1;
547.2532 +
547.2533 +      if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
547.2534 +      {
547.2535 +         back.red = png_ptr->gamma_table[png_ptr->background.red];
547.2536 +         back.green = png_ptr->gamma_table[png_ptr->background.green];
547.2537 +         back.blue = png_ptr->gamma_table[png_ptr->background.blue];
547.2538 +
547.2539 +         back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
547.2540 +         back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
547.2541 +         back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
547.2542 +      }
547.2543 +      else
547.2544 +      {
547.2545 +         double g;
547.2546 +
547.2547 +         g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
547.2548 +
547.2549 +         if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
547.2550 +             fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
547.2551 +         {
547.2552 +            back.red = png_ptr->background.red;
547.2553 +            back.green = png_ptr->background.green;
547.2554 +            back.blue = png_ptr->background.blue;
547.2555 +         }
547.2556 +         else
547.2557 +         {
547.2558 +            back.red =
547.2559 +               (png_byte)(pow((double)png_ptr->background.red/255, g) *
547.2560 +                255.0 + 0.5);
547.2561 +            back.green =
547.2562 +               (png_byte)(pow((double)png_ptr->background.green/255, g) *
547.2563 +                255.0 + 0.5);
547.2564 +            back.blue =
547.2565 +               (png_byte)(pow((double)png_ptr->background.blue/255, g) *
547.2566 +                255.0 + 0.5);
547.2567 +         }
547.2568 +
547.2569 +         g = 1.0 / png_ptr->background_gamma;
547.2570 +
547.2571 +         back_1.red =
547.2572 +            (png_byte)(pow((double)png_ptr->background.red/255, g) *
547.2573 +             255.0 + 0.5);
547.2574 +         back_1.green =
547.2575 +            (png_byte)(pow((double)png_ptr->background.green/255, g) *
547.2576 +             255.0 + 0.5);
547.2577 +         back_1.blue =
547.2578 +            (png_byte)(pow((double)png_ptr->background.blue/255, g) *
547.2579 +             255.0 + 0.5);
547.2580 +      }
547.2581 +
547.2582 +      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
547.2583 +      {
547.2584 +         png_uint_32 i;
547.2585 +
547.2586 +         for (i = 0; i < (png_uint_32)num_palette; i++)
547.2587 +         {
547.2588 +            if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
547.2589 +            {
547.2590 +               palette[i] = back;
547.2591 +            }
547.2592 +            else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
547.2593 +            {
547.2594 +               png_byte v, w;
547.2595 +
547.2596 +               v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
547.2597 +               png_composite(w, v, png_ptr->trans[i], back_1.red);
547.2598 +               palette[i].red = png_ptr->gamma_from_1[w];
547.2599 +
547.2600 +               v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
547.2601 +               png_composite(w, v, png_ptr->trans[i], back_1.green);
547.2602 +               palette[i].green = png_ptr->gamma_from_1[w];
547.2603 +
547.2604 +               v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
547.2605 +               png_composite(w, v, png_ptr->trans[i], back_1.blue);
547.2606 +               palette[i].blue = png_ptr->gamma_from_1[w];
547.2607 +            }
547.2608 +            else
547.2609 +            {
547.2610 +               palette[i].red = png_ptr->gamma_table[palette[i].red];
547.2611 +               palette[i].green = png_ptr->gamma_table[palette[i].green];
547.2612 +               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
547.2613 +            }
547.2614 +         }
547.2615 +      }
547.2616 +      else
547.2617 +      {
547.2618 +         int i;
547.2619 +
547.2620 +         for (i = 0; i < num_palette; i++)
547.2621 +         {
547.2622 +            if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
547.2623 +            {
547.2624 +               palette[i] = back;
547.2625 +            }
547.2626 +            else
547.2627 +            {
547.2628 +               palette[i].red = png_ptr->gamma_table[palette[i].red];
547.2629 +               palette[i].green = png_ptr->gamma_table[palette[i].green];
547.2630 +               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
547.2631 +            }
547.2632 +         }
547.2633 +      }
547.2634 +   }
547.2635 +   else
547.2636 +#endif
547.2637 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.2638 +   if (png_ptr->transformations & PNG_GAMMA)
547.2639 +   {
547.2640 +      int i;
547.2641 +
547.2642 +      for (i = 0; i < num_palette; i++)
547.2643 +      {
547.2644 +         palette[i].red = png_ptr->gamma_table[palette[i].red];
547.2645 +         palette[i].green = png_ptr->gamma_table[palette[i].green];
547.2646 +         palette[i].blue = png_ptr->gamma_table[palette[i].blue];
547.2647 +      }
547.2648 +   }
547.2649 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
547.2650 +   else
547.2651 +#endif
547.2652 +#endif
547.2653 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
547.2654 +   if (png_ptr->transformations & PNG_BACKGROUND)
547.2655 +   {
547.2656 +      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
547.2657 +      {
547.2658 +         png_color back;
547.2659 +
547.2660 +         back.red   = (png_byte)png_ptr->background.red;
547.2661 +         back.green = (png_byte)png_ptr->background.green;
547.2662 +         back.blue  = (png_byte)png_ptr->background.blue;
547.2663 +
547.2664 +         for (i = 0; i < (int)png_ptr->num_trans; i++)
547.2665 +         {
547.2666 +            if (png_ptr->trans[i] == 0)
547.2667 +            {
547.2668 +               palette[i].red = back.red;
547.2669 +               palette[i].green = back.green;
547.2670 +               palette[i].blue = back.blue;
547.2671 +            }
547.2672 +            else if (png_ptr->trans[i] != 0xff)
547.2673 +            {
547.2674 +               png_composite(palette[i].red, png_ptr->palette[i].red,
547.2675 +                  png_ptr->trans[i], back.red);
547.2676 +               png_composite(palette[i].green, png_ptr->palette[i].green,
547.2677 +                  png_ptr->trans[i], back.green);
547.2678 +               png_composite(palette[i].blue, png_ptr->palette[i].blue,
547.2679 +                  png_ptr->trans[i], back.blue);
547.2680 +            }
547.2681 +         }
547.2682 +      }
547.2683 +      else /* assume grayscale palette (what else could it be?) */
547.2684 +      {
547.2685 +         int i;
547.2686 +
547.2687 +         for (i = 0; i < num_palette; i++)
547.2688 +         {
547.2689 +            if (i == (png_byte)png_ptr->trans_values.gray)
547.2690 +            {
547.2691 +               palette[i].red = (png_byte)png_ptr->background.red;
547.2692 +               palette[i].green = (png_byte)png_ptr->background.green;
547.2693 +               palette[i].blue = (png_byte)png_ptr->background.blue;
547.2694 +            }
547.2695 +         }
547.2696 +      }
547.2697 +   }
547.2698 +#endif
547.2699 +}
547.2700 +#endif
547.2701 +
547.2702 +#if defined(PNG_READ_BACKGROUND_SUPPORTED)
547.2703 +/* Replace any alpha or transparency with the supplied background color.
547.2704 + * "background" is already in the screen gamma, while "background_1" is
547.2705 + * at a gamma of 1.0.  Paletted files have already been taken care of.
547.2706 + */
547.2707 +void /* PRIVATE */
547.2708 +png_do_background(png_row_infop row_info, png_bytep row,
547.2709 +   png_color_16p trans_values, png_color_16p background
547.2710 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.2711 +   , png_color_16p background_1,
547.2712 +   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
547.2713 +   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
547.2714 +   png_uint_16pp gamma_16_to_1, int gamma_shift
547.2715 +#endif
547.2716 +   )
547.2717 +{
547.2718 +   png_bytep sp, dp;
547.2719 +   png_uint_32 i;
547.2720 +   png_uint_32 row_width=row_info->width;
547.2721 +   int shift;
547.2722 +
547.2723 +   png_debug(1, "in png_do_background\n");
547.2724 +   if (background != NULL &&
547.2725 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.2726 +       row != NULL && row_info != NULL &&
547.2727 +#endif
547.2728 +      (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
547.2729 +      (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
547.2730 +   {
547.2731 +      switch (row_info->color_type)
547.2732 +      {
547.2733 +         case PNG_COLOR_TYPE_GRAY:
547.2734 +         {
547.2735 +            switch (row_info->bit_depth)
547.2736 +            {
547.2737 +               case 1:
547.2738 +               {
547.2739 +                  sp = row;
547.2740 +                  shift = 7;
547.2741 +                  for (i = 0; i < row_width; i++)
547.2742 +                  {
547.2743 +                     if ((png_uint_16)((*sp >> shift) & 0x01)
547.2744 +                        == trans_values->gray)
547.2745 +                     {
547.2746 +                        *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
547.2747 +                        *sp |= (png_byte)(background->gray << shift);
547.2748 +                     }
547.2749 +                     if (!shift)
547.2750 +                     {
547.2751 +                        shift = 7;
547.2752 +                        sp++;
547.2753 +                     }
547.2754 +                     else
547.2755 +                        shift--;
547.2756 +                  }
547.2757 +                  break;
547.2758 +               }
547.2759 +               case 2:
547.2760 +               {
547.2761 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.2762 +                  if (gamma_table != NULL)
547.2763 +                  {
547.2764 +                     sp = row;
547.2765 +                     shift = 6;
547.2766 +                     for (i = 0; i < row_width; i++)
547.2767 +                     {
547.2768 +                        if ((png_uint_16)((*sp >> shift) & 0x03)
547.2769 +                            == trans_values->gray)
547.2770 +                        {
547.2771 +                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
547.2772 +                           *sp |= (png_byte)(background->gray << shift);
547.2773 +                        }
547.2774 +                        else
547.2775 +                        {
547.2776 +                           png_byte p = (png_byte)((*sp >> shift) & 0x03);
547.2777 +                           png_byte g = (png_byte)((gamma_table [p | (p << 2) |
547.2778 +                               (p << 4) | (p << 6)] >> 6) & 0x03);
547.2779 +                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
547.2780 +                           *sp |= (png_byte)(g << shift);
547.2781 +                        }
547.2782 +                        if (!shift)
547.2783 +                        {
547.2784 +                           shift = 6;
547.2785 +                           sp++;
547.2786 +                        }
547.2787 +                        else
547.2788 +                           shift -= 2;
547.2789 +                     }
547.2790 +                  }
547.2791 +                  else
547.2792 +#endif
547.2793 +                  {
547.2794 +                     sp = row;
547.2795 +                     shift = 6;
547.2796 +                     for (i = 0; i < row_width; i++)
547.2797 +                     {
547.2798 +                        if ((png_uint_16)((*sp >> shift) & 0x03)
547.2799 +                            == trans_values->gray)
547.2800 +                        {
547.2801 +                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
547.2802 +                           *sp |= (png_byte)(background->gray << shift);
547.2803 +                        }
547.2804 +                        if (!shift)
547.2805 +                        {
547.2806 +                           shift = 6;
547.2807 +                           sp++;
547.2808 +                        }
547.2809 +                        else
547.2810 +                           shift -= 2;
547.2811 +                     }
547.2812 +                  }
547.2813 +                  break;
547.2814 +               }
547.2815 +               case 4:
547.2816 +               {
547.2817 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.2818 +                  if (gamma_table != NULL)
547.2819 +                  {
547.2820 +                     sp = row;
547.2821 +                     shift = 4;
547.2822 +                     for (i = 0; i < row_width; i++)
547.2823 +                     {
547.2824 +                        if ((png_uint_16)((*sp >> shift) & 0x0f)
547.2825 +                            == trans_values->gray)
547.2826 +                        {
547.2827 +                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
547.2828 +                           *sp |= (png_byte)(background->gray << shift);
547.2829 +                        }
547.2830 +                        else
547.2831 +                        {
547.2832 +                           png_byte p = (png_byte)((*sp >> shift) & 0x0f);
547.2833 +                           png_byte g = (png_byte)((gamma_table[p |
547.2834 +                             (p << 4)] >> 4) & 0x0f);
547.2835 +                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
547.2836 +                           *sp |= (png_byte)(g << shift);
547.2837 +                        }
547.2838 +                        if (!shift)
547.2839 +                        {
547.2840 +                           shift = 4;
547.2841 +                           sp++;
547.2842 +                        }
547.2843 +                        else
547.2844 +                           shift -= 4;
547.2845 +                     }
547.2846 +                  }
547.2847 +                  else
547.2848 +#endif
547.2849 +                  {
547.2850 +                     sp = row;
547.2851 +                     shift = 4;
547.2852 +                     for (i = 0; i < row_width; i++)
547.2853 +                     {
547.2854 +                        if ((png_uint_16)((*sp >> shift) & 0x0f)
547.2855 +                            == trans_values->gray)
547.2856 +                        {
547.2857 +                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
547.2858 +                           *sp |= (png_byte)(background->gray << shift);
547.2859 +                        }
547.2860 +                        if (!shift)
547.2861 +                        {
547.2862 +                           shift = 4;
547.2863 +                           sp++;
547.2864 +                        }
547.2865 +                        else
547.2866 +                           shift -= 4;
547.2867 +                     }
547.2868 +                  }
547.2869 +                  break;
547.2870 +               }
547.2871 +               case 8:
547.2872 +               {
547.2873 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.2874 +                  if (gamma_table != NULL)
547.2875 +                  {
547.2876 +                     sp = row;
547.2877 +                     for (i = 0; i < row_width; i++, sp++)
547.2878 +                     {
547.2879 +                        if (*sp == trans_values->gray)
547.2880 +                        {
547.2881 +                           *sp = (png_byte)background->gray;
547.2882 +                        }
547.2883 +                        else
547.2884 +                        {
547.2885 +                           *sp = gamma_table[*sp];
547.2886 +                        }
547.2887 +                     }
547.2888 +                  }
547.2889 +                  else
547.2890 +#endif
547.2891 +                  {
547.2892 +                     sp = row;
547.2893 +                     for (i = 0; i < row_width; i++, sp++)
547.2894 +                     {
547.2895 +                        if (*sp == trans_values->gray)
547.2896 +                        {
547.2897 +                           *sp = (png_byte)background->gray;
547.2898 +                        }
547.2899 +                     }
547.2900 +                  }
547.2901 +                  break;
547.2902 +               }
547.2903 +               case 16:
547.2904 +               {
547.2905 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.2906 +                  if (gamma_16 != NULL)
547.2907 +                  {
547.2908 +                     sp = row;
547.2909 +                     for (i = 0; i < row_width; i++, sp += 2)
547.2910 +                     {
547.2911 +                        png_uint_16 v;
547.2912 +
547.2913 +                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
547.2914 +                        if (v == trans_values->gray)
547.2915 +                        {
547.2916 +                           /* background is already in screen gamma */
547.2917 +                           *sp = (png_byte)((background->gray >> 8) & 0xff);
547.2918 +                           *(sp + 1) = (png_byte)(background->gray & 0xff);
547.2919 +                        }
547.2920 +                        else
547.2921 +                        {
547.2922 +                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
547.2923 +                           *sp = (png_byte)((v >> 8) & 0xff);
547.2924 +                           *(sp + 1) = (png_byte)(v & 0xff);
547.2925 +                        }
547.2926 +                     }
547.2927 +                  }
547.2928 +                  else
547.2929 +#endif
547.2930 +                  {
547.2931 +                     sp = row;
547.2932 +                     for (i = 0; i < row_width; i++, sp += 2)
547.2933 +                     {
547.2934 +                        png_uint_16 v;
547.2935 +
547.2936 +                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
547.2937 +                        if (v == trans_values->gray)
547.2938 +                        {
547.2939 +                           *sp = (png_byte)((background->gray >> 8) & 0xff);
547.2940 +                           *(sp + 1) = (png_byte)(background->gray & 0xff);
547.2941 +                        }
547.2942 +                     }
547.2943 +                  }
547.2944 +                  break;
547.2945 +               }
547.2946 +            }
547.2947 +            break;
547.2948 +         }
547.2949 +         case PNG_COLOR_TYPE_RGB:
547.2950 +         {
547.2951 +            if (row_info->bit_depth == 8)
547.2952 +            {
547.2953 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.2954 +               if (gamma_table != NULL)
547.2955 +               {
547.2956 +                  sp = row;
547.2957 +                  for (i = 0; i < row_width; i++, sp += 3)
547.2958 +                  {
547.2959 +                     if (*sp == trans_values->red &&
547.2960 +                        *(sp + 1) == trans_values->green &&
547.2961 +                        *(sp + 2) == trans_values->blue)
547.2962 +                     {
547.2963 +                        *sp = (png_byte)background->red;
547.2964 +                        *(sp + 1) = (png_byte)background->green;
547.2965 +                        *(sp + 2) = (png_byte)background->blue;
547.2966 +                     }
547.2967 +                     else
547.2968 +                     {
547.2969 +                        *sp = gamma_table[*sp];
547.2970 +                        *(sp + 1) = gamma_table[*(sp + 1)];
547.2971 +                        *(sp + 2) = gamma_table[*(sp + 2)];
547.2972 +                     }
547.2973 +                  }
547.2974 +               }
547.2975 +               else
547.2976 +#endif
547.2977 +               {
547.2978 +                  sp = row;
547.2979 +                  for (i = 0; i < row_width; i++, sp += 3)
547.2980 +                  {
547.2981 +                     if (*sp == trans_values->red &&
547.2982 +                        *(sp + 1) == trans_values->green &&
547.2983 +                        *(sp + 2) == trans_values->blue)
547.2984 +                     {
547.2985 +                        *sp = (png_byte)background->red;
547.2986 +                        *(sp + 1) = (png_byte)background->green;
547.2987 +                        *(sp + 2) = (png_byte)background->blue;
547.2988 +                     }
547.2989 +                  }
547.2990 +               }
547.2991 +            }
547.2992 +            else /* if (row_info->bit_depth == 16) */
547.2993 +            {
547.2994 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.2995 +               if (gamma_16 != NULL)
547.2996 +               {
547.2997 +                  sp = row;
547.2998 +                  for (i = 0; i < row_width; i++, sp += 6)
547.2999 +                  {
547.3000 +                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
547.3001 +                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
547.3002 +                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
547.3003 +                     if (r == trans_values->red && g == trans_values->green &&
547.3004 +                        b == trans_values->blue)
547.3005 +                     {
547.3006 +                        /* background is already in screen gamma */
547.3007 +                        *sp = (png_byte)((background->red >> 8) & 0xff);
547.3008 +                        *(sp + 1) = (png_byte)(background->red & 0xff);
547.3009 +                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
547.3010 +                        *(sp + 3) = (png_byte)(background->green & 0xff);
547.3011 +                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
547.3012 +                        *(sp + 5) = (png_byte)(background->blue & 0xff);
547.3013 +                     }
547.3014 +                     else
547.3015 +                     {
547.3016 +                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
547.3017 +                        *sp = (png_byte)((v >> 8) & 0xff);
547.3018 +                        *(sp + 1) = (png_byte)(v & 0xff);
547.3019 +                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
547.3020 +                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
547.3021 +                        *(sp + 3) = (png_byte)(v & 0xff);
547.3022 +                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
547.3023 +                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
547.3024 +                        *(sp + 5) = (png_byte)(v & 0xff);
547.3025 +                     }
547.3026 +                  }
547.3027 +               }
547.3028 +               else
547.3029 +#endif
547.3030 +               {
547.3031 +                  sp = row;
547.3032 +                  for (i = 0; i < row_width; i++, sp += 6)
547.3033 +                  {
547.3034 +                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
547.3035 +                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
547.3036 +                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
547.3037 +
547.3038 +                     if (r == trans_values->red && g == trans_values->green &&
547.3039 +                        b == trans_values->blue)
547.3040 +                     {
547.3041 +                        *sp = (png_byte)((background->red >> 8) & 0xff);
547.3042 +                        *(sp + 1) = (png_byte)(background->red & 0xff);
547.3043 +                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
547.3044 +                        *(sp + 3) = (png_byte)(background->green & 0xff);
547.3045 +                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
547.3046 +                        *(sp + 5) = (png_byte)(background->blue & 0xff);
547.3047 +                     }
547.3048 +                  }
547.3049 +               }
547.3050 +            }
547.3051 +            break;
547.3052 +         }
547.3053 +         case PNG_COLOR_TYPE_GRAY_ALPHA:
547.3054 +         {
547.3055 +            if (row_info->bit_depth == 8)
547.3056 +            {
547.3057 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.3058 +               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
547.3059 +                   gamma_table != NULL)
547.3060 +               {
547.3061 +                  sp = row;
547.3062 +                  dp = row;
547.3063 +                  for (i = 0; i < row_width; i++, sp += 2, dp++)
547.3064 +                  {
547.3065 +                     png_uint_16 a = *(sp + 1);
547.3066 +
547.3067 +                     if (a == 0xff)
547.3068 +                     {
547.3069 +                        *dp = gamma_table[*sp];
547.3070 +                     }
547.3071 +                     else if (a == 0)
547.3072 +                     {
547.3073 +                        /* background is already in screen gamma */
547.3074 +                        *dp = (png_byte)background->gray;
547.3075 +                     }
547.3076 +                     else
547.3077 +                     {
547.3078 +                        png_byte v, w;
547.3079 +
547.3080 +                        v = gamma_to_1[*sp];
547.3081 +                        png_composite(w, v, a, background_1->gray);
547.3082 +                        *dp = gamma_from_1[w];
547.3083 +                     }
547.3084 +                  }
547.3085 +               }
547.3086 +               else
547.3087 +#endif
547.3088 +               {
547.3089 +                  sp = row;
547.3090 +                  dp = row;
547.3091 +                  for (i = 0; i < row_width; i++, sp += 2, dp++)
547.3092 +                  {
547.3093 +                     png_byte a = *(sp + 1);
547.3094 +
547.3095 +                     if (a == 0xff)
547.3096 +                     {
547.3097 +                        *dp = *sp;
547.3098 +                     }
547.3099 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.3100 +                     else if (a == 0)
547.3101 +                     {
547.3102 +                        *dp = (png_byte)background->gray;
547.3103 +                     }
547.3104 +                     else
547.3105 +                     {
547.3106 +                        png_composite(*dp, *sp, a, background_1->gray);
547.3107 +                     }
547.3108 +#else
547.3109 +                     *dp = (png_byte)background->gray;
547.3110 +#endif
547.3111 +                  }
547.3112 +               }
547.3113 +            }
547.3114 +            else /* if (png_ptr->bit_depth == 16) */
547.3115 +            {
547.3116 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.3117 +               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
547.3118 +                   gamma_16_to_1 != NULL)
547.3119 +               {
547.3120 +                  sp = row;
547.3121 +                  dp = row;
547.3122 +                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
547.3123 +                  {
547.3124 +                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
547.3125 +
547.3126 +                     if (a == (png_uint_16)0xffff)
547.3127 +                     {
547.3128 +                        png_uint_16 v;
547.3129 +
547.3130 +                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
547.3131 +                        *dp = (png_byte)((v >> 8) & 0xff);
547.3132 +                        *(dp + 1) = (png_byte)(v & 0xff);
547.3133 +                     }
547.3134 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.3135 +                     else if (a == 0)
547.3136 +#else
547.3137 +                     else
547.3138 +#endif
547.3139 +                     {
547.3140 +                        /* background is already in screen gamma */
547.3141 +                        *dp = (png_byte)((background->gray >> 8) & 0xff);
547.3142 +                        *(dp + 1) = (png_byte)(background->gray & 0xff);
547.3143 +                     }
547.3144 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.3145 +                     else
547.3146 +                     {
547.3147 +                        png_uint_16 g, v, w;
547.3148 +
547.3149 +                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
547.3150 +                        png_composite_16(v, g, a, background_1->gray);
547.3151 +                        w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
547.3152 +                        *dp = (png_byte)((w >> 8) & 0xff);
547.3153 +                        *(dp + 1) = (png_byte)(w & 0xff);
547.3154 +                     }
547.3155 +#endif
547.3156 +                  }
547.3157 +               }
547.3158 +               else
547.3159 +#endif
547.3160 +               {
547.3161 +                  sp = row;
547.3162 +                  dp = row;
547.3163 +                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
547.3164 +                  {
547.3165 +                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
547.3166 +                     if (a == (png_uint_16)0xffff)
547.3167 +                     {
547.3168 +                        png_memcpy(dp, sp, 2);
547.3169 +                     }
547.3170 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.3171 +                     else if (a == 0)
547.3172 +#else
547.3173 +                     else
547.3174 +#endif
547.3175 +                     {
547.3176 +                        *dp = (png_byte)((background->gray >> 8) & 0xff);
547.3177 +                        *(dp + 1) = (png_byte)(background->gray & 0xff);
547.3178 +                     }
547.3179 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.3180 +                     else
547.3181 +                     {
547.3182 +                        png_uint_16 g, v;
547.3183 +
547.3184 +                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
547.3185 +                        png_composite_16(v, g, a, background_1->gray);
547.3186 +                        *dp = (png_byte)((v >> 8) & 0xff);
547.3187 +                        *(dp + 1) = (png_byte)(v & 0xff);
547.3188 +                     }
547.3189 +#endif
547.3190 +                  }
547.3191 +               }
547.3192 +            }
547.3193 +            break;
547.3194 +         }
547.3195 +         case PNG_COLOR_TYPE_RGB_ALPHA:
547.3196 +         {
547.3197 +            if (row_info->bit_depth == 8)
547.3198 +            {
547.3199 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.3200 +               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
547.3201 +                   gamma_table != NULL)
547.3202 +               {
547.3203 +                  sp = row;
547.3204 +                  dp = row;
547.3205 +                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
547.3206 +                  {
547.3207 +                     png_byte a = *(sp + 3);
547.3208 +
547.3209 +                     if (a == 0xff)
547.3210 +                     {
547.3211 +                        *dp = gamma_table[*sp];
547.3212 +                        *(dp + 1) = gamma_table[*(sp + 1)];
547.3213 +                        *(dp + 2) = gamma_table[*(sp + 2)];
547.3214 +                     }
547.3215 +                     else if (a == 0)
547.3216 +                     {
547.3217 +                        /* background is already in screen gamma */
547.3218 +                        *dp = (png_byte)background->red;
547.3219 +                        *(dp + 1) = (png_byte)background->green;
547.3220 +                        *(dp + 2) = (png_byte)background->blue;
547.3221 +                     }
547.3222 +                     else
547.3223 +                     {
547.3224 +                        png_byte v, w;
547.3225 +
547.3226 +                        v = gamma_to_1[*sp];
547.3227 +                        png_composite(w, v, a, background_1->red);
547.3228 +                        *dp = gamma_from_1[w];
547.3229 +                        v = gamma_to_1[*(sp + 1)];
547.3230 +                        png_composite(w, v, a, background_1->green);
547.3231 +                        *(dp + 1) = gamma_from_1[w];
547.3232 +                        v = gamma_to_1[*(sp + 2)];
547.3233 +                        png_composite(w, v, a, background_1->blue);
547.3234 +                        *(dp + 2) = gamma_from_1[w];
547.3235 +                     }
547.3236 +                  }
547.3237 +               }
547.3238 +               else
547.3239 +#endif
547.3240 +               {
547.3241 +                  sp = row;
547.3242 +                  dp = row;
547.3243 +                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
547.3244 +                  {
547.3245 +                     png_byte a = *(sp + 3);
547.3246 +
547.3247 +                     if (a == 0xff)
547.3248 +                     {
547.3249 +                        *dp = *sp;
547.3250 +                        *(dp + 1) = *(sp + 1);
547.3251 +                        *(dp + 2) = *(sp + 2);
547.3252 +                     }
547.3253 +                     else if (a == 0)
547.3254 +                     {
547.3255 +                        *dp = (png_byte)background->red;
547.3256 +                        *(dp + 1) = (png_byte)background->green;
547.3257 +                        *(dp + 2) = (png_byte)background->blue;
547.3258 +                     }
547.3259 +                     else
547.3260 +                     {
547.3261 +                        png_composite(*dp, *sp, a, background->red);
547.3262 +                        png_composite(*(dp + 1), *(sp + 1), a,
547.3263 +                           background->green);
547.3264 +                        png_composite(*(dp + 2), *(sp + 2), a,
547.3265 +                           background->blue);
547.3266 +                     }
547.3267 +                  }
547.3268 +               }
547.3269 +            }
547.3270 +            else /* if (row_info->bit_depth == 16) */
547.3271 +            {
547.3272 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.3273 +               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
547.3274 +                   gamma_16_to_1 != NULL)
547.3275 +               {
547.3276 +                  sp = row;
547.3277 +                  dp = row;
547.3278 +                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
547.3279 +                  {
547.3280 +                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
547.3281 +                         << 8) + (png_uint_16)(*(sp + 7)));
547.3282 +                     if (a == (png_uint_16)0xffff)
547.3283 +                     {
547.3284 +                        png_uint_16 v;
547.3285 +
547.3286 +                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
547.3287 +                        *dp = (png_byte)((v >> 8) & 0xff);
547.3288 +                        *(dp + 1) = (png_byte)(v & 0xff);
547.3289 +                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
547.3290 +                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
547.3291 +                        *(dp + 3) = (png_byte)(v & 0xff);
547.3292 +                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
547.3293 +                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
547.3294 +                        *(dp + 5) = (png_byte)(v & 0xff);
547.3295 +                     }
547.3296 +                     else if (a == 0)
547.3297 +                     {
547.3298 +                        /* background is already in screen gamma */
547.3299 +                        *dp = (png_byte)((background->red >> 8) & 0xff);
547.3300 +                        *(dp + 1) = (png_byte)(background->red & 0xff);
547.3301 +                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
547.3302 +                        *(dp + 3) = (png_byte)(background->green & 0xff);
547.3303 +                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
547.3304 +                        *(dp + 5) = (png_byte)(background->blue & 0xff);
547.3305 +                     }
547.3306 +                     else
547.3307 +                     {
547.3308 +                        png_uint_16 v, w, x;
547.3309 +
547.3310 +                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
547.3311 +                        png_composite_16(w, v, a, background_1->red);
547.3312 +                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
547.3313 +                        *dp = (png_byte)((x >> 8) & 0xff);
547.3314 +                        *(dp + 1) = (png_byte)(x & 0xff);
547.3315 +                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
547.3316 +                        png_composite_16(w, v, a, background_1->green);
547.3317 +                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
547.3318 +                        *(dp + 2) = (png_byte)((x >> 8) & 0xff);
547.3319 +                        *(dp + 3) = (png_byte)(x & 0xff);
547.3320 +                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
547.3321 +                        png_composite_16(w, v, a, background_1->blue);
547.3322 +                        x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
547.3323 +                        *(dp + 4) = (png_byte)((x >> 8) & 0xff);
547.3324 +                        *(dp + 5) = (png_byte)(x & 0xff);
547.3325 +                     }
547.3326 +                  }
547.3327 +               }
547.3328 +               else
547.3329 +#endif
547.3330 +               {
547.3331 +                  sp = row;
547.3332 +                  dp = row;
547.3333 +                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
547.3334 +                  {
547.3335 +                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
547.3336 +                        << 8) + (png_uint_16)(*(sp + 7)));
547.3337 +                     if (a == (png_uint_16)0xffff)
547.3338 +                     {
547.3339 +                        png_memcpy(dp, sp, 6);
547.3340 +                     }
547.3341 +                     else if (a == 0)
547.3342 +                     {
547.3343 +                        *dp = (png_byte)((background->red >> 8) & 0xff);
547.3344 +                        *(dp + 1) = (png_byte)(background->red & 0xff);
547.3345 +                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
547.3346 +                        *(dp + 3) = (png_byte)(background->green & 0xff);
547.3347 +                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
547.3348 +                        *(dp + 5) = (png_byte)(background->blue & 0xff);
547.3349 +                     }
547.3350 +                     else
547.3351 +                     {
547.3352 +                        png_uint_16 v;
547.3353 +
547.3354 +                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
547.3355 +                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
547.3356 +                            + *(sp + 3));
547.3357 +                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
547.3358 +                            + *(sp + 5));
547.3359 +
547.3360 +                        png_composite_16(v, r, a, background->red);
547.3361 +                        *dp = (png_byte)((v >> 8) & 0xff);
547.3362 +                        *(dp + 1) = (png_byte)(v & 0xff);
547.3363 +                        png_composite_16(v, g, a, background->green);
547.3364 +                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
547.3365 +                        *(dp + 3) = (png_byte)(v & 0xff);
547.3366 +                        png_composite_16(v, b, a, background->blue);
547.3367 +                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
547.3368 +                        *(dp + 5) = (png_byte)(v & 0xff);
547.3369 +                     }
547.3370 +                  }
547.3371 +               }
547.3372 +            }
547.3373 +            break;
547.3374 +         }
547.3375 +      }
547.3376 +
547.3377 +      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
547.3378 +      {
547.3379 +         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
547.3380 +         row_info->channels--;
547.3381 +         row_info->pixel_depth = (png_byte)(row_info->channels *
547.3382 +            row_info->bit_depth);
547.3383 +         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
547.3384 +      }
547.3385 +   }
547.3386 +}
547.3387 +#endif
547.3388 +
547.3389 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.3390 +/* Gamma correct the image, avoiding the alpha channel.  Make sure
547.3391 + * you do this after you deal with the transparency issue on grayscale
547.3392 + * or RGB images. If your bit depth is 8, use gamma_table, if it
547.3393 + * is 16, use gamma_16_table and gamma_shift.  Build these with
547.3394 + * build_gamma_table().
547.3395 + */
547.3396 +void /* PRIVATE */
547.3397 +png_do_gamma(png_row_infop row_info, png_bytep row,
547.3398 +   png_bytep gamma_table, png_uint_16pp gamma_16_table,
547.3399 +   int gamma_shift)
547.3400 +{
547.3401 +   png_bytep sp;
547.3402 +   png_uint_32 i;
547.3403 +   png_uint_32 row_width=row_info->width;
547.3404 +
547.3405 +   png_debug(1, "in png_do_gamma\n");
547.3406 +   if (
547.3407 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.3408 +       row != NULL && row_info != NULL &&
547.3409 +#endif
547.3410 +       ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
547.3411 +        (row_info->bit_depth == 16 && gamma_16_table != NULL)))
547.3412 +   {
547.3413 +      switch (row_info->color_type)
547.3414 +      {
547.3415 +         case PNG_COLOR_TYPE_RGB:
547.3416 +         {
547.3417 +            if (row_info->bit_depth == 8)
547.3418 +            {
547.3419 +               sp = row;
547.3420 +               for (i = 0; i < row_width; i++)
547.3421 +               {
547.3422 +                  *sp = gamma_table[*sp];
547.3423 +                  sp++;
547.3424 +                  *sp = gamma_table[*sp];
547.3425 +                  sp++;
547.3426 +                  *sp = gamma_table[*sp];
547.3427 +                  sp++;
547.3428 +               }
547.3429 +            }
547.3430 +            else /* if (row_info->bit_depth == 16) */
547.3431 +            {
547.3432 +               sp = row;
547.3433 +               for (i = 0; i < row_width; i++)
547.3434 +               {
547.3435 +                  png_uint_16 v;
547.3436 +
547.3437 +                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
547.3438 +                  *sp = (png_byte)((v >> 8) & 0xff);
547.3439 +                  *(sp + 1) = (png_byte)(v & 0xff);
547.3440 +                  sp += 2;
547.3441 +                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
547.3442 +                  *sp = (png_byte)((v >> 8) & 0xff);
547.3443 +                  *(sp + 1) = (png_byte)(v & 0xff);
547.3444 +                  sp += 2;
547.3445 +                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
547.3446 +                  *sp = (png_byte)((v >> 8) & 0xff);
547.3447 +                  *(sp + 1) = (png_byte)(v & 0xff);
547.3448 +                  sp += 2;
547.3449 +               }
547.3450 +            }
547.3451 +            break;
547.3452 +         }
547.3453 +         case PNG_COLOR_TYPE_RGB_ALPHA:
547.3454 +         {
547.3455 +            if (row_info->bit_depth == 8)
547.3456 +            {
547.3457 +               sp = row;
547.3458 +               for (i = 0; i < row_width; i++)
547.3459 +               {
547.3460 +                  *sp = gamma_table[*sp];
547.3461 +                  sp++;
547.3462 +                  *sp = gamma_table[*sp];
547.3463 +                  sp++;
547.3464 +                  *sp = gamma_table[*sp];
547.3465 +                  sp++;
547.3466 +                  sp++;
547.3467 +               }
547.3468 +            }
547.3469 +            else /* if (row_info->bit_depth == 16) */
547.3470 +            {
547.3471 +               sp = row;
547.3472 +               for (i = 0; i < row_width; i++)
547.3473 +               {
547.3474 +                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
547.3475 +                  *sp = (png_byte)((v >> 8) & 0xff);
547.3476 +                  *(sp + 1) = (png_byte)(v & 0xff);
547.3477 +                  sp += 2;
547.3478 +                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
547.3479 +                  *sp = (png_byte)((v >> 8) & 0xff);
547.3480 +                  *(sp + 1) = (png_byte)(v & 0xff);
547.3481 +                  sp += 2;
547.3482 +                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
547.3483 +                  *sp = (png_byte)((v >> 8) & 0xff);
547.3484 +                  *(sp + 1) = (png_byte)(v & 0xff);
547.3485 +                  sp += 4;
547.3486 +               }
547.3487 +            }
547.3488 +            break;
547.3489 +         }
547.3490 +         case PNG_COLOR_TYPE_GRAY_ALPHA:
547.3491 +         {
547.3492 +            if (row_info->bit_depth == 8)
547.3493 +            {
547.3494 +               sp = row;
547.3495 +               for (i = 0; i < row_width; i++)
547.3496 +               {
547.3497 +                  *sp = gamma_table[*sp];
547.3498 +                  sp += 2;
547.3499 +               }
547.3500 +            }
547.3501 +            else /* if (row_info->bit_depth == 16) */
547.3502 +            {
547.3503 +               sp = row;
547.3504 +               for (i = 0; i < row_width; i++)
547.3505 +               {
547.3506 +                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
547.3507 +                  *sp = (png_byte)((v >> 8) & 0xff);
547.3508 +                  *(sp + 1) = (png_byte)(v & 0xff);
547.3509 +                  sp += 4;
547.3510 +               }
547.3511 +            }
547.3512 +            break;
547.3513 +         }
547.3514 +         case PNG_COLOR_TYPE_GRAY:
547.3515 +         {
547.3516 +            if (row_info->bit_depth == 2)
547.3517 +            {
547.3518 +               sp = row;
547.3519 +               for (i = 0; i < row_width; i += 4)
547.3520 +               {
547.3521 +                  int a = *sp & 0xc0;
547.3522 +                  int b = *sp & 0x30;
547.3523 +                  int c = *sp & 0x0c;
547.3524 +                  int d = *sp & 0x03;
547.3525 +
547.3526 +                  *sp = (png_byte)(
547.3527 +                        ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
547.3528 +                        ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
547.3529 +                        ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
547.3530 +                        ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
547.3531 +                  sp++;
547.3532 +               }
547.3533 +            }
547.3534 +            if (row_info->bit_depth == 4)
547.3535 +            {
547.3536 +               sp = row;
547.3537 +               for (i = 0; i < row_width; i += 2)
547.3538 +               {
547.3539 +                  int msb = *sp & 0xf0;
547.3540 +                  int lsb = *sp & 0x0f;
547.3541 +
547.3542 +                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
547.3543 +                          | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
547.3544 +                  sp++;
547.3545 +               }
547.3546 +            }
547.3547 +            else if (row_info->bit_depth == 8)
547.3548 +            {
547.3549 +               sp = row;
547.3550 +               for (i = 0; i < row_width; i++)
547.3551 +               {
547.3552 +                  *sp = gamma_table[*sp];
547.3553 +                  sp++;
547.3554 +               }
547.3555 +            }
547.3556 +            else if (row_info->bit_depth == 16)
547.3557 +            {
547.3558 +               sp = row;
547.3559 +               for (i = 0; i < row_width; i++)
547.3560 +               {
547.3561 +                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
547.3562 +                  *sp = (png_byte)((v >> 8) & 0xff);
547.3563 +                  *(sp + 1) = (png_byte)(v & 0xff);
547.3564 +                  sp += 2;
547.3565 +               }
547.3566 +            }
547.3567 +            break;
547.3568 +         }
547.3569 +      }
547.3570 +   }
547.3571 +}
547.3572 +#endif
547.3573 +
547.3574 +#if defined(PNG_READ_EXPAND_SUPPORTED)
547.3575 +/* Expands a palette row to an RGB or RGBA row depending
547.3576 + * upon whether you supply trans and num_trans.
547.3577 + */
547.3578 +void /* PRIVATE */
547.3579 +png_do_expand_palette(png_row_infop row_info, png_bytep row,
547.3580 +   png_colorp palette, png_bytep trans, int num_trans)
547.3581 +{
547.3582 +   int shift, value;
547.3583 +   png_bytep sp, dp;
547.3584 +   png_uint_32 i;
547.3585 +   png_uint_32 row_width=row_info->width;
547.3586 +
547.3587 +   png_debug(1, "in png_do_expand_palette\n");
547.3588 +   if (
547.3589 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.3590 +       row != NULL && row_info != NULL &&
547.3591 +#endif
547.3592 +       row_info->color_type == PNG_COLOR_TYPE_PALETTE)
547.3593 +   {
547.3594 +      if (row_info->bit_depth < 8)
547.3595 +      {
547.3596 +         switch (row_info->bit_depth)
547.3597 +         {
547.3598 +            case 1:
547.3599 +            {
547.3600 +               sp = row + (png_size_t)((row_width - 1) >> 3);
547.3601 +               dp = row + (png_size_t)row_width - 1;
547.3602 +               shift = 7 - (int)((row_width + 7) & 0x07);
547.3603 +               for (i = 0; i < row_width; i++)
547.3604 +               {
547.3605 +                  if ((*sp >> shift) & 0x01)
547.3606 +                     *dp = 1;
547.3607 +                  else
547.3608 +                     *dp = 0;
547.3609 +                  if (shift == 7)
547.3610 +                  {
547.3611 +                     shift = 0;
547.3612 +                     sp--;
547.3613 +                  }
547.3614 +                  else
547.3615 +                     shift++;
547.3616 +
547.3617 +                  dp--;
547.3618 +               }
547.3619 +               break;
547.3620 +            }
547.3621 +            case 2:
547.3622 +            {
547.3623 +               sp = row + (png_size_t)((row_width - 1) >> 2);
547.3624 +               dp = row + (png_size_t)row_width - 1;
547.3625 +               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
547.3626 +               for (i = 0; i < row_width; i++)
547.3627 +               {
547.3628 +                  value = (*sp >> shift) & 0x03;
547.3629 +                  *dp = (png_byte)value;
547.3630 +                  if (shift == 6)
547.3631 +                  {
547.3632 +                     shift = 0;
547.3633 +                     sp--;
547.3634 +                  }
547.3635 +                  else
547.3636 +                     shift += 2;
547.3637 +
547.3638 +                  dp--;
547.3639 +               }
547.3640 +               break;
547.3641 +            }
547.3642 +            case 4:
547.3643 +            {
547.3644 +               sp = row + (png_size_t)((row_width - 1) >> 1);
547.3645 +               dp = row + (png_size_t)row_width - 1;
547.3646 +               shift = (int)((row_width & 0x01) << 2);
547.3647 +               for (i = 0; i < row_width; i++)
547.3648 +               {
547.3649 +                  value = (*sp >> shift) & 0x0f;
547.3650 +                  *dp = (png_byte)value;
547.3651 +                  if (shift == 4)
547.3652 +                  {
547.3653 +                     shift = 0;
547.3654 +                     sp--;
547.3655 +                  }
547.3656 +                  else
547.3657 +                     shift += 4;
547.3658 +
547.3659 +                  dp--;
547.3660 +               }
547.3661 +               break;
547.3662 +            }
547.3663 +         }
547.3664 +         row_info->bit_depth = 8;
547.3665 +         row_info->pixel_depth = 8;
547.3666 +         row_info->rowbytes = row_width;
547.3667 +      }
547.3668 +      switch (row_info->bit_depth)
547.3669 +      {
547.3670 +         case 8:
547.3671 +         {
547.3672 +            if (trans != NULL)
547.3673 +            {
547.3674 +               sp = row + (png_size_t)row_width - 1;
547.3675 +               dp = row + (png_size_t)(row_width << 2) - 1;
547.3676 +
547.3677 +               for (i = 0; i < row_width; i++)
547.3678 +               {
547.3679 +                  if ((int)(*sp) >= num_trans)
547.3680 +                     *dp-- = 0xff;
547.3681 +                  else
547.3682 +                     *dp-- = trans[*sp];
547.3683 +                  *dp-- = palette[*sp].blue;
547.3684 +                  *dp-- = palette[*sp].green;
547.3685 +                  *dp-- = palette[*sp].red;
547.3686 +                  sp--;
547.3687 +               }
547.3688 +               row_info->bit_depth = 8;
547.3689 +               row_info->pixel_depth = 32;
547.3690 +               row_info->rowbytes = row_width * 4;
547.3691 +               row_info->color_type = 6;
547.3692 +               row_info->channels = 4;
547.3693 +            }
547.3694 +            else
547.3695 +            {
547.3696 +               sp = row + (png_size_t)row_width - 1;
547.3697 +               dp = row + (png_size_t)(row_width * 3) - 1;
547.3698 +
547.3699 +               for (i = 0; i < row_width; i++)
547.3700 +               {
547.3701 +                  *dp-- = palette[*sp].blue;
547.3702 +                  *dp-- = palette[*sp].green;
547.3703 +                  *dp-- = palette[*sp].red;
547.3704 +                  sp--;
547.3705 +               }
547.3706 +               row_info->bit_depth = 8;
547.3707 +               row_info->pixel_depth = 24;
547.3708 +               row_info->rowbytes = row_width * 3;
547.3709 +               row_info->color_type = 2;
547.3710 +               row_info->channels = 3;
547.3711 +            }
547.3712 +            break;
547.3713 +         }
547.3714 +      }
547.3715 +   }
547.3716 +}
547.3717 +
547.3718 +/* If the bit depth < 8, it is expanded to 8.  Also, if the already
547.3719 + * expanded transparency value is supplied, an alpha channel is built.
547.3720 + */
547.3721 +void /* PRIVATE */
547.3722 +png_do_expand(png_row_infop row_info, png_bytep row,
547.3723 +   png_color_16p trans_value)
547.3724 +{
547.3725 +   int shift, value;
547.3726 +   png_bytep sp, dp;
547.3727 +   png_uint_32 i;
547.3728 +   png_uint_32 row_width=row_info->width;
547.3729 +
547.3730 +   png_debug(1, "in png_do_expand\n");
547.3731 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.3732 +   if (row != NULL && row_info != NULL)
547.3733 +#endif
547.3734 +   {
547.3735 +      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
547.3736 +      {
547.3737 +         png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
547.3738 +
547.3739 +         if (row_info->bit_depth < 8)
547.3740 +         {
547.3741 +            switch (row_info->bit_depth)
547.3742 +            {
547.3743 +               case 1:
547.3744 +               {
547.3745 +                  gray = (png_uint_16)((gray&0x01)*0xff);
547.3746 +                  sp = row + (png_size_t)((row_width - 1) >> 3);
547.3747 +                  dp = row + (png_size_t)row_width - 1;
547.3748 +                  shift = 7 - (int)((row_width + 7) & 0x07);
547.3749 +                  for (i = 0; i < row_width; i++)
547.3750 +                  {
547.3751 +                     if ((*sp >> shift) & 0x01)
547.3752 +                        *dp = 0xff;
547.3753 +                     else
547.3754 +                        *dp = 0;
547.3755 +                     if (shift == 7)
547.3756 +                     {
547.3757 +                        shift = 0;
547.3758 +                        sp--;
547.3759 +                     }
547.3760 +                     else
547.3761 +                        shift++;
547.3762 +
547.3763 +                     dp--;
547.3764 +                  }
547.3765 +                  break;
547.3766 +               }
547.3767 +               case 2:
547.3768 +               {
547.3769 +                  gray = (png_uint_16)((gray&0x03)*0x55);
547.3770 +                  sp = row + (png_size_t)((row_width - 1) >> 2);
547.3771 +                  dp = row + (png_size_t)row_width - 1;
547.3772 +                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
547.3773 +                  for (i = 0; i < row_width; i++)
547.3774 +                  {
547.3775 +                     value = (*sp >> shift) & 0x03;
547.3776 +                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
547.3777 +                        (value << 6));
547.3778 +                     if (shift == 6)
547.3779 +                     {
547.3780 +                        shift = 0;
547.3781 +                        sp--;
547.3782 +                     }
547.3783 +                     else
547.3784 +                        shift += 2;
547.3785 +
547.3786 +                     dp--;
547.3787 +                  }
547.3788 +                  break;
547.3789 +               }
547.3790 +               case 4:
547.3791 +               {
547.3792 +                  gray = (png_uint_16)((gray&0x0f)*0x11);
547.3793 +                  sp = row + (png_size_t)((row_width - 1) >> 1);
547.3794 +                  dp = row + (png_size_t)row_width - 1;
547.3795 +                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
547.3796 +                  for (i = 0; i < row_width; i++)
547.3797 +                  {
547.3798 +                     value = (*sp >> shift) & 0x0f;
547.3799 +                     *dp = (png_byte)(value | (value << 4));
547.3800 +                     if (shift == 4)
547.3801 +                     {
547.3802 +                        shift = 0;
547.3803 +                        sp--;
547.3804 +                     }
547.3805 +                     else
547.3806 +                        shift = 4;
547.3807 +
547.3808 +                     dp--;
547.3809 +                  }
547.3810 +                  break;
547.3811 +               }
547.3812 +            }
547.3813 +            row_info->bit_depth = 8;
547.3814 +            row_info->pixel_depth = 8;
547.3815 +            row_info->rowbytes = row_width;
547.3816 +         }
547.3817 +
547.3818 +         if (trans_value != NULL)
547.3819 +         {
547.3820 +            if (row_info->bit_depth == 8)
547.3821 +            {
547.3822 +               gray = gray & 0xff;
547.3823 +               sp = row + (png_size_t)row_width - 1;
547.3824 +               dp = row + (png_size_t)(row_width << 1) - 1;
547.3825 +               for (i = 0; i < row_width; i++)
547.3826 +               {
547.3827 +                  if (*sp == gray)
547.3828 +                     *dp-- = 0;
547.3829 +                  else
547.3830 +                     *dp-- = 0xff;
547.3831 +                  *dp-- = *sp--;
547.3832 +               }
547.3833 +            }
547.3834 +            else if (row_info->bit_depth == 16)
547.3835 +            {
547.3836 +               png_byte gray_high = (gray >> 8) & 0xff;
547.3837 +               png_byte gray_low = gray & 0xff;
547.3838 +               sp = row + row_info->rowbytes - 1;
547.3839 +               dp = row + (row_info->rowbytes << 1) - 1;
547.3840 +               for (i = 0; i < row_width; i++)
547.3841 +               {
547.3842 +                  if (*(sp - 1) == gray_high && *(sp) == gray_low) 
547.3843 +                  {
547.3844 +                     *dp-- = 0;
547.3845 +                     *dp-- = 0;
547.3846 +                  }
547.3847 +                  else
547.3848 +                  {
547.3849 +                     *dp-- = 0xff;
547.3850 +                     *dp-- = 0xff;
547.3851 +                  }
547.3852 +                  *dp-- = *sp--;
547.3853 +                  *dp-- = *sp--;
547.3854 +               }
547.3855 +            }
547.3856 +            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
547.3857 +            row_info->channels = 2;
547.3858 +            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
547.3859 +            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
547.3860 +               row_width);
547.3861 +         }
547.3862 +      }
547.3863 +      else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
547.3864 +      {
547.3865 +         if (row_info->bit_depth == 8)
547.3866 +         {
547.3867 +            png_byte red = trans_value->red & 0xff;
547.3868 +            png_byte green = trans_value->green & 0xff;
547.3869 +            png_byte blue = trans_value->blue & 0xff;
547.3870 +            sp = row + (png_size_t)row_info->rowbytes - 1;
547.3871 +            dp = row + (png_size_t)(row_width << 2) - 1;
547.3872 +            for (i = 0; i < row_width; i++)
547.3873 +            {
547.3874 +               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
547.3875 +                  *dp-- = 0;
547.3876 +               else
547.3877 +                  *dp-- = 0xff;
547.3878 +               *dp-- = *sp--;
547.3879 +               *dp-- = *sp--;
547.3880 +               *dp-- = *sp--;
547.3881 +            }
547.3882 +         }
547.3883 +         else if (row_info->bit_depth == 16)
547.3884 +         {
547.3885 +            png_byte red_high = (trans_value->red >> 8) & 0xff;
547.3886 +            png_byte green_high = (trans_value->green >> 8) & 0xff;
547.3887 +            png_byte blue_high = (trans_value->blue >> 8) & 0xff;
547.3888 +            png_byte red_low = trans_value->red & 0xff;
547.3889 +            png_byte green_low = trans_value->green & 0xff;
547.3890 +            png_byte blue_low = trans_value->blue & 0xff;
547.3891 +            sp = row + row_info->rowbytes - 1;
547.3892 +            dp = row + (png_size_t)(row_width << 3) - 1;
547.3893 +            for (i = 0; i < row_width; i++)
547.3894 +            {
547.3895 +               if (*(sp - 5) == red_high &&
547.3896 +                  *(sp - 4) == red_low &&
547.3897 +                  *(sp - 3) == green_high &&
547.3898 +                  *(sp - 2) == green_low &&
547.3899 +                  *(sp - 1) == blue_high &&
547.3900 +                  *(sp    ) == blue_low)
547.3901 +               {
547.3902 +                  *dp-- = 0;
547.3903 +                  *dp-- = 0;
547.3904 +               }
547.3905 +               else
547.3906 +               {
547.3907 +                  *dp-- = 0xff;
547.3908 +                  *dp-- = 0xff;
547.3909 +               }
547.3910 +               *dp-- = *sp--;
547.3911 +               *dp-- = *sp--;
547.3912 +               *dp-- = *sp--;
547.3913 +               *dp-- = *sp--;
547.3914 +               *dp-- = *sp--;
547.3915 +               *dp-- = *sp--;
547.3916 +            }
547.3917 +         }
547.3918 +         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
547.3919 +         row_info->channels = 4;
547.3920 +         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
547.3921 +         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
547.3922 +      }
547.3923 +   }
547.3924 +}
547.3925 +#endif
547.3926 +
547.3927 +#if defined(PNG_READ_DITHER_SUPPORTED)
547.3928 +void /* PRIVATE */
547.3929 +png_do_dither(png_row_infop row_info, png_bytep row,
547.3930 +    png_bytep palette_lookup, png_bytep dither_lookup)
547.3931 +{
547.3932 +   png_bytep sp, dp;
547.3933 +   png_uint_32 i;
547.3934 +   png_uint_32 row_width=row_info->width;
547.3935 +
547.3936 +   png_debug(1, "in png_do_dither\n");
547.3937 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.3938 +   if (row != NULL && row_info != NULL)
547.3939 +#endif
547.3940 +   {
547.3941 +      if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
547.3942 +         palette_lookup && row_info->bit_depth == 8)
547.3943 +      {
547.3944 +         int r, g, b, p;
547.3945 +         sp = row;
547.3946 +         dp = row;
547.3947 +         for (i = 0; i < row_width; i++)
547.3948 +         {
547.3949 +            r = *sp++;
547.3950 +            g = *sp++;
547.3951 +            b = *sp++;
547.3952 +
547.3953 +            /* this looks real messy, but the compiler will reduce
547.3954 +               it down to a reasonable formula.  For example, with
547.3955 +               5 bits per color, we get:
547.3956 +               p = (((r >> 3) & 0x1f) << 10) |
547.3957 +                  (((g >> 3) & 0x1f) << 5) |
547.3958 +                  ((b >> 3) & 0x1f);
547.3959 +               */
547.3960 +            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
547.3961 +               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
547.3962 +               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
547.3963 +               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
547.3964 +               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
547.3965 +               (PNG_DITHER_BLUE_BITS)) |
547.3966 +               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
547.3967 +               ((1 << PNG_DITHER_BLUE_BITS) - 1));
547.3968 +
547.3969 +            *dp++ = palette_lookup[p];
547.3970 +         }
547.3971 +         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
547.3972 +         row_info->channels = 1;
547.3973 +         row_info->pixel_depth = row_info->bit_depth;
547.3974 +         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
547.3975 +      }
547.3976 +      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
547.3977 +         palette_lookup != NULL && row_info->bit_depth == 8)
547.3978 +      {
547.3979 +         int r, g, b, p;
547.3980 +         sp = row;
547.3981 +         dp = row;
547.3982 +         for (i = 0; i < row_width; i++)
547.3983 +         {
547.3984 +            r = *sp++;
547.3985 +            g = *sp++;
547.3986 +            b = *sp++;
547.3987 +            sp++;
547.3988 +
547.3989 +            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
547.3990 +               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
547.3991 +               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
547.3992 +               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
547.3993 +               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
547.3994 +               (PNG_DITHER_BLUE_BITS)) |
547.3995 +               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
547.3996 +               ((1 << PNG_DITHER_BLUE_BITS) - 1));
547.3997 +
547.3998 +            *dp++ = palette_lookup[p];
547.3999 +         }
547.4000 +         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
547.4001 +         row_info->channels = 1;
547.4002 +         row_info->pixel_depth = row_info->bit_depth;
547.4003 +         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
547.4004 +      }
547.4005 +      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
547.4006 +         dither_lookup && row_info->bit_depth == 8)
547.4007 +      {
547.4008 +         sp = row;
547.4009 +         for (i = 0; i < row_width; i++, sp++)
547.4010 +         {
547.4011 +            *sp = dither_lookup[*sp];
547.4012 +         }
547.4013 +      }
547.4014 +   }
547.4015 +}
547.4016 +#endif
547.4017 +
547.4018 +#ifdef PNG_FLOATING_POINT_SUPPORTED
547.4019 +#if defined(PNG_READ_GAMMA_SUPPORTED)
547.4020 +static PNG_CONST int png_gamma_shift[] =
547.4021 +   {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
547.4022 +
547.4023 +/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
547.4024 + * tables, we don't make a full table if we are reducing to 8-bit in
547.4025 + * the future.  Note also how the gamma_16 tables are segmented so that
547.4026 + * we don't need to allocate > 64K chunks for a full 16-bit table.
547.4027 + */
547.4028 +void /* PRIVATE */
547.4029 +png_build_gamma_table(png_structp png_ptr)
547.4030 +{
547.4031 +  png_debug(1, "in png_build_gamma_table\n");
547.4032 +
547.4033 +  if (png_ptr->bit_depth <= 8)
547.4034 +  {
547.4035 +     int i;
547.4036 +     double g;
547.4037 +
547.4038 +     if (png_ptr->screen_gamma > .000001)
547.4039 +        g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
547.4040 +     else
547.4041 +        g = 1.0;
547.4042 +
547.4043 +     png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
547.4044 +        (png_uint_32)256);
547.4045 +
547.4046 +     for (i = 0; i < 256; i++)
547.4047 +     {
547.4048 +        png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
547.4049 +           g) * 255.0 + .5);
547.4050 +     }
547.4051 +
547.4052 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
547.4053 +   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
547.4054 +     if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
547.4055 +     {
547.4056 +
547.4057 +        g = 1.0 / (png_ptr->gamma);
547.4058 +
547.4059 +        png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
547.4060 +           (png_uint_32)256);
547.4061 +
547.4062 +        for (i = 0; i < 256; i++)
547.4063 +        {
547.4064 +           png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
547.4065 +              g) * 255.0 + .5);
547.4066 +        }
547.4067 +
547.4068 +
547.4069 +        png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
547.4070 +           (png_uint_32)256);
547.4071 +
547.4072 +        if (png_ptr->screen_gamma > 0.000001)
547.4073 +           g = 1.0 / png_ptr->screen_gamma;
547.4074 +        else
547.4075 +           g = png_ptr->gamma;   /* probably doing rgb_to_gray */
547.4076 +
547.4077 +        for (i = 0; i < 256; i++)
547.4078 +        {
547.4079 +           png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
547.4080 +              g) * 255.0 + .5);
547.4081 +
547.4082 +        }
547.4083 +     }
547.4084 +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
547.4085 +  }
547.4086 +  else
547.4087 +  {
547.4088 +     double g;
547.4089 +     int i, j, shift, num;
547.4090 +     int sig_bit;
547.4091 +     png_uint_32 ig;
547.4092 +
547.4093 +     if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
547.4094 +     {
547.4095 +        sig_bit = (int)png_ptr->sig_bit.red;
547.4096 +        if ((int)png_ptr->sig_bit.green > sig_bit)
547.4097 +           sig_bit = png_ptr->sig_bit.green;
547.4098 +        if ((int)png_ptr->sig_bit.blue > sig_bit)
547.4099 +           sig_bit = png_ptr->sig_bit.blue;
547.4100 +     }
547.4101 +     else
547.4102 +     {
547.4103 +        sig_bit = (int)png_ptr->sig_bit.gray;
547.4104 +     }
547.4105 +
547.4106 +     if (sig_bit > 0)
547.4107 +        shift = 16 - sig_bit;
547.4108 +     else
547.4109 +        shift = 0;
547.4110 +
547.4111 +     if (png_ptr->transformations & PNG_16_TO_8)
547.4112 +     {
547.4113 +        if (shift < (16 - PNG_MAX_GAMMA_8))
547.4114 +           shift = (16 - PNG_MAX_GAMMA_8);
547.4115 +     }
547.4116 +
547.4117 +     if (shift > 8)
547.4118 +        shift = 8;
547.4119 +     if (shift < 0)
547.4120 +        shift = 0;
547.4121 +
547.4122 +     png_ptr->gamma_shift = (png_byte)shift;
547.4123 +
547.4124 +     num = (1 << (8 - shift));
547.4125 +
547.4126 +     if (png_ptr->screen_gamma > .000001)
547.4127 +        g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
547.4128 +     else
547.4129 +        g = 1.0;
547.4130 +
547.4131 +     png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
547.4132 +        (png_uint_32)(num * png_sizeof(png_uint_16p)));
547.4133 +
547.4134 +     if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
547.4135 +     {
547.4136 +        double fin, fout;
547.4137 +        png_uint_32 last, max;
547.4138 +
547.4139 +        for (i = 0; i < num; i++)
547.4140 +        {
547.4141 +           png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
547.4142 +              (png_uint_32)(256 * png_sizeof(png_uint_16)));
547.4143 +        }
547.4144 +
547.4145 +        g = 1.0 / g;
547.4146 +        last = 0;
547.4147 +        for (i = 0; i < 256; i++)
547.4148 +        {
547.4149 +           fout = ((double)i + 0.5) / 256.0;
547.4150 +           fin = pow(fout, g);
547.4151 +           max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
547.4152 +           while (last <= max)
547.4153 +           {
547.4154 +              png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
547.4155 +                 [(int)(last >> (8 - shift))] = (png_uint_16)(
547.4156 +                 (png_uint_16)i | ((png_uint_16)i << 8));
547.4157 +              last++;
547.4158 +           }
547.4159 +        }
547.4160 +        while (last < ((png_uint_32)num << 8))
547.4161 +        {
547.4162 +           png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
547.4163 +              [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
547.4164 +           last++;
547.4165 +        }
547.4166 +     }
547.4167 +     else
547.4168 +     {
547.4169 +        for (i = 0; i < num; i++)
547.4170 +        {
547.4171 +           png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
547.4172 +              (png_uint_32)(256 * png_sizeof(png_uint_16)));
547.4173 +
547.4174 +           ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
547.4175 +           for (j = 0; j < 256; j++)
547.4176 +           {
547.4177 +              png_ptr->gamma_16_table[i][j] =
547.4178 +                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
547.4179 +                    65535.0, g) * 65535.0 + .5);
547.4180 +           }
547.4181 +        }
547.4182 +     }
547.4183 +
547.4184 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
547.4185 +   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
547.4186 +     if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
547.4187 +     {
547.4188 +
547.4189 +        g = 1.0 / (png_ptr->gamma);
547.4190 +
547.4191 +        png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
547.4192 +           (png_uint_32)(num * png_sizeof(png_uint_16p )));
547.4193 +
547.4194 +        for (i = 0; i < num; i++)
547.4195 +        {
547.4196 +           png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
547.4197 +              (png_uint_32)(256 * png_sizeof(png_uint_16)));
547.4198 +
547.4199 +           ig = (((png_uint_32)i *
547.4200 +              (png_uint_32)png_gamma_shift[shift]) >> 4);
547.4201 +           for (j = 0; j < 256; j++)
547.4202 +           {
547.4203 +              png_ptr->gamma_16_to_1[i][j] =
547.4204 +                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
547.4205 +                    65535.0, g) * 65535.0 + .5);
547.4206 +           }
547.4207 +        }
547.4208 +
547.4209 +        if (png_ptr->screen_gamma > 0.000001)
547.4210 +           g = 1.0 / png_ptr->screen_gamma;
547.4211 +        else
547.4212 +           g = png_ptr->gamma;   /* probably doing rgb_to_gray */
547.4213 +
547.4214 +        png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
547.4215 +           (png_uint_32)(num * png_sizeof(png_uint_16p)));
547.4216 +
547.4217 +        for (i = 0; i < num; i++)
547.4218 +        {
547.4219 +           png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
547.4220 +              (png_uint_32)(256 * png_sizeof(png_uint_16)));
547.4221 +
547.4222 +           ig = (((png_uint_32)i *
547.4223 +              (png_uint_32)png_gamma_shift[shift]) >> 4);
547.4224 +           for (j = 0; j < 256; j++)
547.4225 +           {
547.4226 +              png_ptr->gamma_16_from_1[i][j] =
547.4227 +                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
547.4228 +                    65535.0, g) * 65535.0 + .5);
547.4229 +           }
547.4230 +        }
547.4231 +     }
547.4232 +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
547.4233 +  }
547.4234 +}
547.4235 +#endif
547.4236 +/* To do: install integer version of png_build_gamma_table here */
547.4237 +#endif
547.4238 +
547.4239 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
547.4240 +/* undoes intrapixel differencing  */
547.4241 +void /* PRIVATE */
547.4242 +png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
547.4243 +{
547.4244 +   png_debug(1, "in png_do_read_intrapixel\n");
547.4245 +   if (
547.4246 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
547.4247 +       row != NULL && row_info != NULL &&
547.4248 +#endif
547.4249 +       (row_info->color_type & PNG_COLOR_MASK_COLOR))
547.4250 +   {
547.4251 +      int bytes_per_pixel;
547.4252 +      png_uint_32 row_width = row_info->width;
547.4253 +      if (row_info->bit_depth == 8)
547.4254 +      {
547.4255 +         png_bytep rp;
547.4256 +         png_uint_32 i;
547.4257 +
547.4258 +         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
547.4259 +            bytes_per_pixel = 3;
547.4260 +         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
547.4261 +            bytes_per_pixel = 4;
547.4262 +         else
547.4263 +            return;
547.4264 +
547.4265 +         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
547.4266 +         {
547.4267 +            *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
547.4268 +            *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
547.4269 +         }
547.4270 +      }
547.4271 +      else if (row_info->bit_depth == 16)
547.4272 +      {
547.4273 +         png_bytep rp;
547.4274 +         png_uint_32 i;
547.4275 +
547.4276 +         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
547.4277 +            bytes_per_pixel = 6;
547.4278 +         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
547.4279 +            bytes_per_pixel = 8;
547.4280 +         else
547.4281 +            return;
547.4282 +
547.4283 +         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
547.4284 +         {
547.4285 +            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
547.4286 +            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
547.4287 +            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
547.4288 +            png_uint_32 red  = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL);
547.4289 +            png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL);
547.4290 +            *(rp  ) = (png_byte)((red >> 8) & 0xff);
547.4291 +            *(rp+1) = (png_byte)(red & 0xff);
547.4292 +            *(rp+4) = (png_byte)((blue >> 8) & 0xff);
547.4293 +            *(rp+5) = (png_byte)(blue & 0xff);
547.4294 +         }
547.4295 +      }
547.4296 +   }
547.4297 +}
547.4298 +#endif /* PNG_MNG_FEATURES_SUPPORTED */
547.4299 +#endif /* PNG_READ_SUPPORTED */
   548.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   548.2 +++ b/libs/libpng/pngrutil.c	Sat Feb 01 19:58:19 2014 +0200
   548.3 @@ -0,0 +1,3234 @@
   548.4 +
   548.5 +/* pngrutil.c - utilities to read a PNG file
   548.6 + *
   548.7 + * Last changed in libpng 1.2.33 [October 31, 2008]
   548.8 + * For conditions of distribution and use, see copyright notice in png.h
   548.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  548.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  548.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  548.12 + *
  548.13 + * This file contains routines that are only called from within
  548.14 + * libpng itself during the course of reading an image.
  548.15 + */
  548.16 +
  548.17 +#define PNG_INTERNAL
  548.18 +#include "png.h"
  548.19 +#if defined(PNG_READ_SUPPORTED)
  548.20 +
  548.21 +#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
  548.22 +#  define WIN32_WCE_OLD
  548.23 +#endif
  548.24 +
  548.25 +#ifdef PNG_FLOATING_POINT_SUPPORTED
  548.26 +#  if defined(WIN32_WCE_OLD)
  548.27 +/* strtod() function is not supported on WindowsCE */
  548.28 +__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr)
  548.29 +{
  548.30 +   double result = 0;
  548.31 +   int len;
  548.32 +   wchar_t *str, *end;
  548.33 +
  548.34 +   len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
  548.35 +   str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
  548.36 +   if ( NULL != str )
  548.37 +   {
  548.38 +      MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
  548.39 +      result = wcstod(str, &end);
  548.40 +      len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
  548.41 +      *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
  548.42 +      png_free(png_ptr, str);
  548.43 +   }
  548.44 +   return result;
  548.45 +}
  548.46 +#  else
  548.47 +#    define png_strtod(p,a,b) strtod(a,b)
  548.48 +#  endif
  548.49 +#endif
  548.50 +
  548.51 +png_uint_32 PNGAPI
  548.52 +png_get_uint_31(png_structp png_ptr, png_bytep buf)
  548.53 +{
  548.54 +#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
  548.55 +   png_uint_32 i = png_get_uint_32(buf);
  548.56 +#else
  548.57 +   /* Avoid an extra function call by inlining the result. */
  548.58 +   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
  548.59 +      ((png_uint_32)(*(buf + 1)) << 16) +
  548.60 +      ((png_uint_32)(*(buf + 2)) << 8) +
  548.61 +      (png_uint_32)(*(buf + 3));
  548.62 +#endif
  548.63 +   if (i > PNG_UINT_31_MAX)
  548.64 +     png_error(png_ptr, "PNG unsigned integer out of range.");
  548.65 +   return (i);
  548.66 +}
  548.67 +#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
  548.68 +/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
  548.69 +png_uint_32 PNGAPI
  548.70 +png_get_uint_32(png_bytep buf)
  548.71 +{
  548.72 +   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
  548.73 +      ((png_uint_32)(*(buf + 1)) << 16) +
  548.74 +      ((png_uint_32)(*(buf + 2)) << 8) +
  548.75 +      (png_uint_32)(*(buf + 3));
  548.76 +
  548.77 +   return (i);
  548.78 +}
  548.79 +
  548.80 +/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
  548.81 + * data is stored in the PNG file in two's complement format, and it is
  548.82 + * assumed that the machine format for signed integers is the same. */
  548.83 +png_int_32 PNGAPI
  548.84 +png_get_int_32(png_bytep buf)
  548.85 +{
  548.86 +   png_int_32 i = ((png_int_32)(*buf) << 24) +
  548.87 +      ((png_int_32)(*(buf + 1)) << 16) +
  548.88 +      ((png_int_32)(*(buf + 2)) << 8) +
  548.89 +      (png_int_32)(*(buf + 3));
  548.90 +
  548.91 +   return (i);
  548.92 +}
  548.93 +
  548.94 +/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
  548.95 +png_uint_16 PNGAPI
  548.96 +png_get_uint_16(png_bytep buf)
  548.97 +{
  548.98 +   png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
  548.99 +      (png_uint_16)(*(buf + 1)));
 548.100 +
 548.101 +   return (i);
 548.102 +}
 548.103 +#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
 548.104 +
 548.105 +/* Read the chunk header (length + type name).
 548.106 + * Put the type name into png_ptr->chunk_name, and return the length.
 548.107 + */
 548.108 +png_uint_32 /* PRIVATE */
 548.109 +png_read_chunk_header(png_structp png_ptr)
 548.110 +{
 548.111 +   png_byte buf[8];
 548.112 +   png_uint_32 length;
 548.113 +
 548.114 +   /* read the length and the chunk name */
 548.115 +   png_read_data(png_ptr, buf, 8);
 548.116 +   length = png_get_uint_31(png_ptr, buf);
 548.117 +
 548.118 +   /* put the chunk name into png_ptr->chunk_name */
 548.119 +   png_memcpy(png_ptr->chunk_name, buf + 4, 4);
 548.120 +
 548.121 +   png_debug2(0, "Reading %s chunk, length = %lu\n",
 548.122 +      png_ptr->chunk_name, length);
 548.123 +
 548.124 +   /* reset the crc and run it over the chunk name */
 548.125 +   png_reset_crc(png_ptr);
 548.126 +   png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
 548.127 +
 548.128 +   /* check to see if chunk name is valid */
 548.129 +   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
 548.130 +
 548.131 +   return length;
 548.132 +}
 548.133 +
 548.134 +/* Read data, and (optionally) run it through the CRC. */
 548.135 +void /* PRIVATE */
 548.136 +png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
 548.137 +{
 548.138 +   if (png_ptr == NULL) return;
 548.139 +   png_read_data(png_ptr, buf, length);
 548.140 +   png_calculate_crc(png_ptr, buf, length);
 548.141 +}
 548.142 +
 548.143 +/* Optionally skip data and then check the CRC.  Depending on whether we
 548.144 +   are reading a ancillary or critical chunk, and how the program has set
 548.145 +   things up, we may calculate the CRC on the data and print a message.
 548.146 +   Returns '1' if there was a CRC error, '0' otherwise. */
 548.147 +int /* PRIVATE */
 548.148 +png_crc_finish(png_structp png_ptr, png_uint_32 skip)
 548.149 +{
 548.150 +   png_size_t i;
 548.151 +   png_size_t istop = png_ptr->zbuf_size;
 548.152 +
 548.153 +   for (i = (png_size_t)skip; i > istop; i -= istop)
 548.154 +   {
 548.155 +      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
 548.156 +   }
 548.157 +   if (i)
 548.158 +   {
 548.159 +      png_crc_read(png_ptr, png_ptr->zbuf, i);
 548.160 +   }
 548.161 +
 548.162 +   if (png_crc_error(png_ptr))
 548.163 +   {
 548.164 +      if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
 548.165 +           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
 548.166 +          (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
 548.167 +          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
 548.168 +      {
 548.169 +         png_chunk_warning(png_ptr, "CRC error");
 548.170 +      }
 548.171 +      else
 548.172 +      {
 548.173 +         png_chunk_error(png_ptr, "CRC error");
 548.174 +      }
 548.175 +      return (1);
 548.176 +   }
 548.177 +
 548.178 +   return (0);
 548.179 +}
 548.180 +
 548.181 +/* Compare the CRC stored in the PNG file with that calculated by libpng from
 548.182 +   the data it has read thus far. */
 548.183 +int /* PRIVATE */
 548.184 +png_crc_error(png_structp png_ptr)
 548.185 +{
 548.186 +   png_byte crc_bytes[4];
 548.187 +   png_uint_32 crc;
 548.188 +   int need_crc = 1;
 548.189 +
 548.190 +   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
 548.191 +   {
 548.192 +      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
 548.193 +          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
 548.194 +         need_crc = 0;
 548.195 +   }
 548.196 +   else                                                    /* critical */
 548.197 +   {
 548.198 +      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
 548.199 +         need_crc = 0;
 548.200 +   }
 548.201 +
 548.202 +   png_read_data(png_ptr, crc_bytes, 4);
 548.203 +
 548.204 +   if (need_crc)
 548.205 +   {
 548.206 +      crc = png_get_uint_32(crc_bytes);
 548.207 +      return ((int)(crc != png_ptr->crc));
 548.208 +   }
 548.209 +   else
 548.210 +      return (0);
 548.211 +}
 548.212 +
 548.213 +#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
 548.214 +    defined(PNG_READ_iCCP_SUPPORTED)
 548.215 +/*
 548.216 + * Decompress trailing data in a chunk.  The assumption is that chunkdata
 548.217 + * points at an allocated area holding the contents of a chunk with a
 548.218 + * trailing compressed part.  What we get back is an allocated area
 548.219 + * holding the original prefix part and an uncompressed version of the
 548.220 + * trailing part (the malloc area passed in is freed).
 548.221 + */
 548.222 +void /* PRIVATE */
 548.223 +png_decompress_chunk(png_structp png_ptr, int comp_type,
 548.224 +                              png_size_t chunklength,
 548.225 +                              png_size_t prefix_size, png_size_t *newlength)
 548.226 +{
 548.227 +   static PNG_CONST char msg[] = "Error decoding compressed text";
 548.228 +   png_charp text;
 548.229 +   png_size_t text_size;
 548.230 +
 548.231 +   if (comp_type == PNG_COMPRESSION_TYPE_BASE)
 548.232 +   {
 548.233 +      int ret = Z_OK;
 548.234 +      png_ptr->zstream.next_in = (png_bytep)(png_ptr->chunkdata + prefix_size);
 548.235 +      png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
 548.236 +      png_ptr->zstream.next_out = png_ptr->zbuf;
 548.237 +      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
 548.238 +
 548.239 +      text_size = 0;
 548.240 +      text = NULL;
 548.241 +
 548.242 +      while (png_ptr->zstream.avail_in)
 548.243 +      {
 548.244 +         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
 548.245 +         if (ret != Z_OK && ret != Z_STREAM_END)
 548.246 +         {
 548.247 +            if (png_ptr->zstream.msg != NULL)
 548.248 +               png_warning(png_ptr, png_ptr->zstream.msg);
 548.249 +            else
 548.250 +               png_warning(png_ptr, msg);
 548.251 +            inflateReset(&png_ptr->zstream);
 548.252 +            png_ptr->zstream.avail_in = 0;
 548.253 +
 548.254 +            if (text ==  NULL)
 548.255 +            {
 548.256 +               text_size = prefix_size + png_sizeof(msg) + 1;
 548.257 +               text = (png_charp)png_malloc_warn(png_ptr, text_size);
 548.258 +               if (text ==  NULL)
 548.259 +                 {
 548.260 +                    png_free(png_ptr, png_ptr->chunkdata);
 548.261 +                    png_ptr->chunkdata = NULL;
 548.262 +                    png_error(png_ptr, "Not enough memory to decompress chunk");
 548.263 +                 }
 548.264 +               png_memcpy(text, png_ptr->chunkdata, prefix_size);
 548.265 +            }
 548.266 +
 548.267 +            text[text_size - 1] = 0x00;
 548.268 +
 548.269 +            /* Copy what we can of the error message into the text chunk */
 548.270 +            text_size = (png_size_t)(chunklength -
 548.271 +              (text - png_ptr->chunkdata) - 1);
 548.272 +            if (text_size > png_sizeof(msg))
 548.273 +               text_size = png_sizeof(msg);
 548.274 +            png_memcpy(text + prefix_size, msg, text_size);
 548.275 +            break;
 548.276 +         }
 548.277 +         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
 548.278 +         {
 548.279 +            if (text == NULL)
 548.280 +            {
 548.281 +               text_size = prefix_size +
 548.282 +                   png_ptr->zbuf_size - png_ptr->zstream.avail_out;
 548.283 +               text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
 548.284 +               if (text ==  NULL)
 548.285 +               {
 548.286 +                  png_free(png_ptr, png_ptr->chunkdata);
 548.287 +                  png_ptr->chunkdata = NULL;
 548.288 +                  png_error(png_ptr,
 548.289 +                    "Not enough memory to decompress chunk.");
 548.290 +               }
 548.291 +               png_memcpy(text + prefix_size, png_ptr->zbuf,
 548.292 +                    text_size - prefix_size);
 548.293 +               png_memcpy(text, png_ptr->chunkdata, prefix_size);
 548.294 +               *(text + text_size) = 0x00;
 548.295 +            }
 548.296 +            else
 548.297 +            {
 548.298 +               png_charp tmp;
 548.299 +
 548.300 +               tmp = text;
 548.301 +               text = (png_charp)png_malloc_warn(png_ptr,
 548.302 +                  (png_uint_32)(text_size +
 548.303 +                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
 548.304 +               if (text == NULL)
 548.305 +               {
 548.306 +                  png_free(png_ptr, tmp);
 548.307 +                  png_free(png_ptr, png_ptr->chunkdata);
 548.308 +                  png_ptr->chunkdata = NULL;
 548.309 +                  png_error(png_ptr,
 548.310 +                    "Not enough memory to decompress chunk..");
 548.311 +               }
 548.312 +               png_memcpy(text, tmp, text_size);
 548.313 +               png_free(png_ptr, tmp);
 548.314 +               png_memcpy(text + text_size, png_ptr->zbuf,
 548.315 +                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
 548.316 +               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
 548.317 +               *(text + text_size) = 0x00;
 548.318 +            }
 548.319 +            if (ret == Z_STREAM_END)
 548.320 +               break;
 548.321 +            else
 548.322 +            {
 548.323 +               png_ptr->zstream.next_out = png_ptr->zbuf;
 548.324 +               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
 548.325 +            }
 548.326 +         }
 548.327 +      }
 548.328 +      if (ret != Z_STREAM_END)
 548.329 +      {
 548.330 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
 548.331 +         char umsg[52];
 548.332 +
 548.333 +         if (ret == Z_BUF_ERROR)
 548.334 +            png_snprintf(umsg, 52,
 548.335 +                "Buffer error in compressed datastream in %s chunk",
 548.336 +                png_ptr->chunk_name);
 548.337 +         else if (ret == Z_DATA_ERROR)
 548.338 +            png_snprintf(umsg, 52,
 548.339 +                "Data error in compressed datastream in %s chunk",
 548.340 +                png_ptr->chunk_name);
 548.341 +         else
 548.342 +            png_snprintf(umsg, 52,
 548.343 +                "Incomplete compressed datastream in %s chunk",
 548.344 +                png_ptr->chunk_name);
 548.345 +         png_warning(png_ptr, umsg);
 548.346 +#else
 548.347 +         png_warning(png_ptr,
 548.348 +            "Incomplete compressed datastream in chunk other than IDAT");
 548.349 +#endif
 548.350 +         text_size = prefix_size;
 548.351 +         if (text ==  NULL)
 548.352 +         {
 548.353 +            text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
 548.354 +            if (text == NULL)
 548.355 +              {
 548.356 +                png_free(png_ptr, png_ptr->chunkdata);
 548.357 +                png_ptr->chunkdata = NULL;
 548.358 +                png_error(png_ptr, "Not enough memory for text.");
 548.359 +              }
 548.360 +            png_memcpy(text, png_ptr->chunkdata, prefix_size);
 548.361 +         }
 548.362 +         *(text + text_size) = 0x00;
 548.363 +      }
 548.364 +
 548.365 +      inflateReset(&png_ptr->zstream);
 548.366 +      png_ptr->zstream.avail_in = 0;
 548.367 +
 548.368 +      png_free(png_ptr, png_ptr->chunkdata);
 548.369 +      png_ptr->chunkdata = text;
 548.370 +      *newlength=text_size;
 548.371 +   }
 548.372 +   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
 548.373 +   {
 548.374 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
 548.375 +      char umsg[50];
 548.376 +
 548.377 +      png_snprintf(umsg, 50, "Unknown zTXt compression type %d", comp_type);
 548.378 +      png_warning(png_ptr, umsg);
 548.379 +#else
 548.380 +      png_warning(png_ptr, "Unknown zTXt compression type");
 548.381 +#endif
 548.382 +
 548.383 +      *(png_ptr->chunkdata + prefix_size) = 0x00;
 548.384 +      *newlength = prefix_size;
 548.385 +   }
 548.386 +}
 548.387 +#endif
 548.388 +
 548.389 +/* read and check the IDHR chunk */
 548.390 +void /* PRIVATE */
 548.391 +png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 548.392 +{
 548.393 +   png_byte buf[13];
 548.394 +   png_uint_32 width, height;
 548.395 +   int bit_depth, color_type, compression_type, filter_type;
 548.396 +   int interlace_type;
 548.397 +
 548.398 +   png_debug(1, "in png_handle_IHDR\n");
 548.399 +
 548.400 +   if (png_ptr->mode & PNG_HAVE_IHDR)
 548.401 +      png_error(png_ptr, "Out of place IHDR");
 548.402 +
 548.403 +   /* check the length */
 548.404 +   if (length != 13)
 548.405 +      png_error(png_ptr, "Invalid IHDR chunk");
 548.406 +
 548.407 +   png_ptr->mode |= PNG_HAVE_IHDR;
 548.408 +
 548.409 +   png_crc_read(png_ptr, buf, 13);
 548.410 +   png_crc_finish(png_ptr, 0);
 548.411 +
 548.412 +   width = png_get_uint_31(png_ptr, buf);
 548.413 +   height = png_get_uint_31(png_ptr, buf + 4);
 548.414 +   bit_depth = buf[8];
 548.415 +   color_type = buf[9];
 548.416 +   compression_type = buf[10];
 548.417 +   filter_type = buf[11];
 548.418 +   interlace_type = buf[12];
 548.419 +
 548.420 +   /* set internal variables */
 548.421 +   png_ptr->width = width;
 548.422 +   png_ptr->height = height;
 548.423 +   png_ptr->bit_depth = (png_byte)bit_depth;
 548.424 +   png_ptr->interlaced = (png_byte)interlace_type;
 548.425 +   png_ptr->color_type = (png_byte)color_type;
 548.426 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
 548.427 +   png_ptr->filter_type = (png_byte)filter_type;
 548.428 +#endif
 548.429 +   png_ptr->compression_type = (png_byte)compression_type;
 548.430 +
 548.431 +   /* find number of channels */
 548.432 +   switch (png_ptr->color_type)
 548.433 +   {
 548.434 +      case PNG_COLOR_TYPE_GRAY:
 548.435 +      case PNG_COLOR_TYPE_PALETTE:
 548.436 +         png_ptr->channels = 1;
 548.437 +         break;
 548.438 +      case PNG_COLOR_TYPE_RGB:
 548.439 +         png_ptr->channels = 3;
 548.440 +         break;
 548.441 +      case PNG_COLOR_TYPE_GRAY_ALPHA:
 548.442 +         png_ptr->channels = 2;
 548.443 +         break;
 548.444 +      case PNG_COLOR_TYPE_RGB_ALPHA:
 548.445 +         png_ptr->channels = 4;
 548.446 +         break;
 548.447 +   }
 548.448 +
 548.449 +   /* set up other useful info */
 548.450 +   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
 548.451 +   png_ptr->channels);
 548.452 +   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
 548.453 +   png_debug1(3, "bit_depth = %d\n", png_ptr->bit_depth);
 548.454 +   png_debug1(3, "channels = %d\n", png_ptr->channels);
 548.455 +   png_debug1(3, "rowbytes = %lu\n", png_ptr->rowbytes);
 548.456 +   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
 548.457 +      color_type, interlace_type, compression_type, filter_type);
 548.458 +}
 548.459 +
 548.460 +/* read and check the palette */
 548.461 +void /* PRIVATE */
 548.462 +png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 548.463 +{
 548.464 +   png_color palette[PNG_MAX_PALETTE_LENGTH];
 548.465 +   int num, i;
 548.466 +#ifndef PNG_NO_POINTER_INDEXING
 548.467 +   png_colorp pal_ptr;
 548.468 +#endif
 548.469 +
 548.470 +   png_debug(1, "in png_handle_PLTE\n");
 548.471 +
 548.472 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
 548.473 +      png_error(png_ptr, "Missing IHDR before PLTE");
 548.474 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
 548.475 +   {
 548.476 +      png_warning(png_ptr, "Invalid PLTE after IDAT");
 548.477 +      png_crc_finish(png_ptr, length);
 548.478 +      return;
 548.479 +   }
 548.480 +   else if (png_ptr->mode & PNG_HAVE_PLTE)
 548.481 +      png_error(png_ptr, "Duplicate PLTE chunk");
 548.482 +
 548.483 +   png_ptr->mode |= PNG_HAVE_PLTE;
 548.484 +
 548.485 +   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
 548.486 +   {
 548.487 +      png_warning(png_ptr,
 548.488 +        "Ignoring PLTE chunk in grayscale PNG");
 548.489 +      png_crc_finish(png_ptr, length);
 548.490 +      return;
 548.491 +   }
 548.492 +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
 548.493 +   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
 548.494 +   {
 548.495 +      png_crc_finish(png_ptr, length);
 548.496 +      return;
 548.497 +   }
 548.498 +#endif
 548.499 +
 548.500 +   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
 548.501 +   {
 548.502 +      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
 548.503 +      {
 548.504 +         png_warning(png_ptr, "Invalid palette chunk");
 548.505 +         png_crc_finish(png_ptr, length);
 548.506 +         return;
 548.507 +      }
 548.508 +      else
 548.509 +      {
 548.510 +         png_error(png_ptr, "Invalid palette chunk");
 548.511 +      }
 548.512 +   }
 548.513 +
 548.514 +   num = (int)length / 3;
 548.515 +
 548.516 +#ifndef PNG_NO_POINTER_INDEXING
 548.517 +   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
 548.518 +   {
 548.519 +      png_byte buf[3];
 548.520 +
 548.521 +      png_crc_read(png_ptr, buf, 3);
 548.522 +      pal_ptr->red = buf[0];
 548.523 +      pal_ptr->green = buf[1];
 548.524 +      pal_ptr->blue = buf[2];
 548.525 +   }
 548.526 +#else
 548.527 +   for (i = 0; i < num; i++)
 548.528 +   {
 548.529 +      png_byte buf[3];
 548.530 +
 548.531 +      png_crc_read(png_ptr, buf, 3);
 548.532 +      /* don't depend upon png_color being any order */
 548.533 +      palette[i].red = buf[0];
 548.534 +      palette[i].green = buf[1];
 548.535 +      palette[i].blue = buf[2];
 548.536 +   }
 548.537 +#endif
 548.538 +
 548.539 +   /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
 548.540 +      whatever the normal CRC configuration tells us.  However, if we
 548.541 +      have an RGB image, the PLTE can be considered ancillary, so
 548.542 +      we will act as though it is. */
 548.543 +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
 548.544 +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 548.545 +#endif
 548.546 +   {
 548.547 +      png_crc_finish(png_ptr, 0);
 548.548 +   }
 548.549 +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
 548.550 +   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
 548.551 +   {
 548.552 +      /* If we don't want to use the data from an ancillary chunk,
 548.553 +         we have two options: an error abort, or a warning and we
 548.554 +         ignore the data in this chunk (which should be OK, since
 548.555 +         it's considered ancillary for a RGB or RGBA image). */
 548.556 +      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
 548.557 +      {
 548.558 +         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
 548.559 +         {
 548.560 +            png_chunk_error(png_ptr, "CRC error");
 548.561 +         }
 548.562 +         else
 548.563 +         {
 548.564 +            png_chunk_warning(png_ptr, "CRC error");
 548.565 +            return;
 548.566 +         }
 548.567 +      }
 548.568 +      /* Otherwise, we (optionally) emit a warning and use the chunk. */
 548.569 +      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
 548.570 +      {
 548.571 +         png_chunk_warning(png_ptr, "CRC error");
 548.572 +      }
 548.573 +   }
 548.574 +#endif
 548.575 +
 548.576 +   png_set_PLTE(png_ptr, info_ptr, palette, num);
 548.577 +
 548.578 +#if defined(PNG_READ_tRNS_SUPPORTED)
 548.579 +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 548.580 +   {
 548.581 +      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
 548.582 +      {
 548.583 +         if (png_ptr->num_trans > (png_uint_16)num)
 548.584 +         {
 548.585 +            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
 548.586 +            png_ptr->num_trans = (png_uint_16)num;
 548.587 +         }
 548.588 +         if (info_ptr->num_trans > (png_uint_16)num)
 548.589 +         {
 548.590 +            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
 548.591 +            info_ptr->num_trans = (png_uint_16)num;
 548.592 +         }
 548.593 +      }
 548.594 +   }
 548.595 +#endif
 548.596 +
 548.597 +}
 548.598 +
 548.599 +void /* PRIVATE */
 548.600 +png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 548.601 +{
 548.602 +   png_debug(1, "in png_handle_IEND\n");
 548.603 +
 548.604 +   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
 548.605 +   {
 548.606 +      png_error(png_ptr, "No image in file");
 548.607 +   }
 548.608 +
 548.609 +   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
 548.610 +
 548.611 +   if (length != 0)
 548.612 +   {
 548.613 +      png_warning(png_ptr, "Incorrect IEND chunk length");
 548.614 +   }
 548.615 +   png_crc_finish(png_ptr, length);
 548.616 +
 548.617 +   info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
 548.618 +}
 548.619 +
 548.620 +#if defined(PNG_READ_gAMA_SUPPORTED)
 548.621 +void /* PRIVATE */
 548.622 +png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 548.623 +{
 548.624 +   png_fixed_point igamma;
 548.625 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 548.626 +   float file_gamma;
 548.627 +#endif
 548.628 +   png_byte buf[4];
 548.629 +
 548.630 +   png_debug(1, "in png_handle_gAMA\n");
 548.631 +
 548.632 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
 548.633 +      png_error(png_ptr, "Missing IHDR before gAMA");
 548.634 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
 548.635 +   {
 548.636 +      png_warning(png_ptr, "Invalid gAMA after IDAT");
 548.637 +      png_crc_finish(png_ptr, length);
 548.638 +      return;
 548.639 +   }
 548.640 +   else if (png_ptr->mode & PNG_HAVE_PLTE)
 548.641 +      /* Should be an error, but we can cope with it */
 548.642 +      png_warning(png_ptr, "Out of place gAMA chunk");
 548.643 +
 548.644 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
 548.645 +#if defined(PNG_READ_sRGB_SUPPORTED)
 548.646 +      && !(info_ptr->valid & PNG_INFO_sRGB)
 548.647 +#endif
 548.648 +      )
 548.649 +   {
 548.650 +      png_warning(png_ptr, "Duplicate gAMA chunk");
 548.651 +      png_crc_finish(png_ptr, length);
 548.652 +      return;
 548.653 +   }
 548.654 +
 548.655 +   if (length != 4)
 548.656 +   {
 548.657 +      png_warning(png_ptr, "Incorrect gAMA chunk length");
 548.658 +      png_crc_finish(png_ptr, length);
 548.659 +      return;
 548.660 +   }
 548.661 +
 548.662 +   png_crc_read(png_ptr, buf, 4);
 548.663 +   if (png_crc_finish(png_ptr, 0))
 548.664 +      return;
 548.665 +
 548.666 +   igamma = (png_fixed_point)png_get_uint_32(buf);
 548.667 +   /* check for zero gamma */
 548.668 +   if (igamma == 0)
 548.669 +      {
 548.670 +         png_warning(png_ptr,
 548.671 +           "Ignoring gAMA chunk with gamma=0");
 548.672 +         return;
 548.673 +      }
 548.674 +
 548.675 +#if defined(PNG_READ_sRGB_SUPPORTED)
 548.676 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
 548.677 +      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
 548.678 +      {
 548.679 +         png_warning(png_ptr,
 548.680 +           "Ignoring incorrect gAMA value when sRGB is also present");
 548.681 +#ifndef PNG_NO_CONSOLE_IO
 548.682 +         fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
 548.683 +#endif
 548.684 +         return;
 548.685 +      }
 548.686 +#endif /* PNG_READ_sRGB_SUPPORTED */
 548.687 +
 548.688 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 548.689 +   file_gamma = (float)igamma / (float)100000.0;
 548.690 +#  ifdef PNG_READ_GAMMA_SUPPORTED
 548.691 +     png_ptr->gamma = file_gamma;
 548.692 +#  endif
 548.693 +     png_set_gAMA(png_ptr, info_ptr, file_gamma);
 548.694 +#endif
 548.695 +#ifdef PNG_FIXED_POINT_SUPPORTED
 548.696 +   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
 548.697 +#endif
 548.698 +}
 548.699 +#endif
 548.700 +
 548.701 +#if defined(PNG_READ_sBIT_SUPPORTED)
 548.702 +void /* PRIVATE */
 548.703 +png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 548.704 +{
 548.705 +   png_size_t truelen;
 548.706 +   png_byte buf[4];
 548.707 +
 548.708 +   png_debug(1, "in png_handle_sBIT\n");
 548.709 +
 548.710 +   buf[0] = buf[1] = buf[2] = buf[3] = 0;
 548.711 +
 548.712 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
 548.713 +      png_error(png_ptr, "Missing IHDR before sBIT");
 548.714 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
 548.715 +   {
 548.716 +      png_warning(png_ptr, "Invalid sBIT after IDAT");
 548.717 +      png_crc_finish(png_ptr, length);
 548.718 +      return;
 548.719 +   }
 548.720 +   else if (png_ptr->mode & PNG_HAVE_PLTE)
 548.721 +   {
 548.722 +      /* Should be an error, but we can cope with it */
 548.723 +      png_warning(png_ptr, "Out of place sBIT chunk");
 548.724 +   }
 548.725 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
 548.726 +   {
 548.727 +      png_warning(png_ptr, "Duplicate sBIT chunk");
 548.728 +      png_crc_finish(png_ptr, length);
 548.729 +      return;
 548.730 +   }
 548.731 +
 548.732 +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 548.733 +      truelen = 3;
 548.734 +   else
 548.735 +      truelen = (png_size_t)png_ptr->channels;
 548.736 +
 548.737 +   if (length != truelen || length > 4)
 548.738 +   {
 548.739 +      png_warning(png_ptr, "Incorrect sBIT chunk length");
 548.740 +      png_crc_finish(png_ptr, length);
 548.741 +      return;
 548.742 +   }
 548.743 +
 548.744 +   png_crc_read(png_ptr, buf, truelen);
 548.745 +   if (png_crc_finish(png_ptr, 0))
 548.746 +      return;
 548.747 +
 548.748 +   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
 548.749 +   {
 548.750 +      png_ptr->sig_bit.red = buf[0];
 548.751 +      png_ptr->sig_bit.green = buf[1];
 548.752 +      png_ptr->sig_bit.blue = buf[2];
 548.753 +      png_ptr->sig_bit.alpha = buf[3];
 548.754 +   }
 548.755 +   else
 548.756 +   {
 548.757 +      png_ptr->sig_bit.gray = buf[0];
 548.758 +      png_ptr->sig_bit.red = buf[0];
 548.759 +      png_ptr->sig_bit.green = buf[0];
 548.760 +      png_ptr->sig_bit.blue = buf[0];
 548.761 +      png_ptr->sig_bit.alpha = buf[1];
 548.762 +   }
 548.763 +   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
 548.764 +}
 548.765 +#endif
 548.766 +
 548.767 +#if defined(PNG_READ_cHRM_SUPPORTED)
 548.768 +void /* PRIVATE */
 548.769 +png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 548.770 +{
 548.771 +   png_byte buf[32];
 548.772 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 548.773 +   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
 548.774 +#endif
 548.775 +   png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
 548.776 +      int_y_green, int_x_blue, int_y_blue;
 548.777 +
 548.778 +   png_uint_32 uint_x, uint_y;
 548.779 +
 548.780 +   png_debug(1, "in png_handle_cHRM\n");
 548.781 +
 548.782 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
 548.783 +      png_error(png_ptr, "Missing IHDR before cHRM");
 548.784 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
 548.785 +   {
 548.786 +      png_warning(png_ptr, "Invalid cHRM after IDAT");
 548.787 +      png_crc_finish(png_ptr, length);
 548.788 +      return;
 548.789 +   }
 548.790 +   else if (png_ptr->mode & PNG_HAVE_PLTE)
 548.791 +      /* Should be an error, but we can cope with it */
 548.792 +      png_warning(png_ptr, "Missing PLTE before cHRM");
 548.793 +
 548.794 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
 548.795 +#if defined(PNG_READ_sRGB_SUPPORTED)
 548.796 +      && !(info_ptr->valid & PNG_INFO_sRGB)
 548.797 +#endif
 548.798 +      )
 548.799 +   {
 548.800 +      png_warning(png_ptr, "Duplicate cHRM chunk");
 548.801 +      png_crc_finish(png_ptr, length);
 548.802 +      return;
 548.803 +   }
 548.804 +
 548.805 +   if (length != 32)
 548.806 +   {
 548.807 +      png_warning(png_ptr, "Incorrect cHRM chunk length");
 548.808 +      png_crc_finish(png_ptr, length);
 548.809 +      return;
 548.810 +   }
 548.811 +
 548.812 +   png_crc_read(png_ptr, buf, 32);
 548.813 +   if (png_crc_finish(png_ptr, 0))
 548.814 +      return;
 548.815 +
 548.816 +   uint_x = png_get_uint_32(buf);
 548.817 +   uint_y = png_get_uint_32(buf + 4);
 548.818 +   if (uint_x > 80000L || uint_y > 80000L ||
 548.819 +      uint_x + uint_y > 100000L)
 548.820 +   {
 548.821 +      png_warning(png_ptr, "Invalid cHRM white point");
 548.822 +      return;
 548.823 +   }
 548.824 +   int_x_white = (png_fixed_point)uint_x;
 548.825 +   int_y_white = (png_fixed_point)uint_y;
 548.826 +
 548.827 +   uint_x = png_get_uint_32(buf + 8);
 548.828 +   uint_y = png_get_uint_32(buf + 12);
 548.829 +   if (uint_x + uint_y > 100000L)
 548.830 +   {
 548.831 +      png_warning(png_ptr, "Invalid cHRM red point");
 548.832 +      return;
 548.833 +   }
 548.834 +   int_x_red = (png_fixed_point)uint_x;
 548.835 +   int_y_red = (png_fixed_point)uint_y;
 548.836 +
 548.837 +   uint_x = png_get_uint_32(buf + 16);
 548.838 +   uint_y = png_get_uint_32(buf + 20);
 548.839 +   if (uint_x + uint_y > 100000L)
 548.840 +   {
 548.841 +      png_warning(png_ptr, "Invalid cHRM green point");
 548.842 +      return;
 548.843 +   }
 548.844 +   int_x_green = (png_fixed_point)uint_x;
 548.845 +   int_y_green = (png_fixed_point)uint_y;
 548.846 +
 548.847 +   uint_x = png_get_uint_32(buf + 24);
 548.848 +   uint_y = png_get_uint_32(buf + 28);
 548.849 +   if (uint_x + uint_y > 100000L)
 548.850 +   {
 548.851 +      png_warning(png_ptr, "Invalid cHRM blue point");
 548.852 +      return;
 548.853 +   }
 548.854 +   int_x_blue = (png_fixed_point)uint_x;
 548.855 +   int_y_blue = (png_fixed_point)uint_y;
 548.856 +
 548.857 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 548.858 +   white_x = (float)int_x_white / (float)100000.0;
 548.859 +   white_y = (float)int_y_white / (float)100000.0;
 548.860 +   red_x   = (float)int_x_red   / (float)100000.0;
 548.861 +   red_y   = (float)int_y_red   / (float)100000.0;
 548.862 +   green_x = (float)int_x_green / (float)100000.0;
 548.863 +   green_y = (float)int_y_green / (float)100000.0;
 548.864 +   blue_x  = (float)int_x_blue  / (float)100000.0;
 548.865 +   blue_y  = (float)int_y_blue  / (float)100000.0;
 548.866 +#endif
 548.867 +
 548.868 +#if defined(PNG_READ_sRGB_SUPPORTED)
 548.869 +   if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
 548.870 +      {
 548.871 +      if (PNG_OUT_OF_RANGE(int_x_white, 31270,  1000) ||
 548.872 +          PNG_OUT_OF_RANGE(int_y_white, 32900,  1000) ||
 548.873 +          PNG_OUT_OF_RANGE(int_x_red,   64000L, 1000) ||
 548.874 +          PNG_OUT_OF_RANGE(int_y_red,   33000,  1000) ||
 548.875 +          PNG_OUT_OF_RANGE(int_x_green, 30000,  1000) ||
 548.876 +          PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
 548.877 +          PNG_OUT_OF_RANGE(int_x_blue,  15000,  1000) ||
 548.878 +          PNG_OUT_OF_RANGE(int_y_blue,   6000,  1000))
 548.879 +         {
 548.880 +            png_warning(png_ptr,
 548.881 +              "Ignoring incorrect cHRM value when sRGB is also present");
 548.882 +#ifndef PNG_NO_CONSOLE_IO
 548.883 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 548.884 +            fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
 548.885 +               white_x, white_y, red_x, red_y);
 548.886 +            fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
 548.887 +               green_x, green_y, blue_x, blue_y);
 548.888 +#else
 548.889 +            fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
 548.890 +               int_x_white, int_y_white, int_x_red, int_y_red);
 548.891 +            fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
 548.892 +               int_x_green, int_y_green, int_x_blue, int_y_blue);
 548.893 +#endif
 548.894 +#endif /* PNG_NO_CONSOLE_IO */
 548.895 +         }
 548.896 +         return;
 548.897 +      }
 548.898 +#endif /* PNG_READ_sRGB_SUPPORTED */
 548.899 +
 548.900 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 548.901 +   png_set_cHRM(png_ptr, info_ptr,
 548.902 +      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
 548.903 +#endif
 548.904 +#ifdef PNG_FIXED_POINT_SUPPORTED
 548.905 +   png_set_cHRM_fixed(png_ptr, info_ptr,
 548.906 +      int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
 548.907 +      int_y_green, int_x_blue, int_y_blue);
 548.908 +#endif
 548.909 +}
 548.910 +#endif
 548.911 +
 548.912 +#if defined(PNG_READ_sRGB_SUPPORTED)
 548.913 +void /* PRIVATE */
 548.914 +png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 548.915 +{
 548.916 +   int intent;
 548.917 +   png_byte buf[1];
 548.918 +
 548.919 +   png_debug(1, "in png_handle_sRGB\n");
 548.920 +
 548.921 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
 548.922 +      png_error(png_ptr, "Missing IHDR before sRGB");
 548.923 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
 548.924 +   {
 548.925 +      png_warning(png_ptr, "Invalid sRGB after IDAT");
 548.926 +      png_crc_finish(png_ptr, length);
 548.927 +      return;
 548.928 +   }
 548.929 +   else if (png_ptr->mode & PNG_HAVE_PLTE)
 548.930 +      /* Should be an error, but we can cope with it */
 548.931 +      png_warning(png_ptr, "Out of place sRGB chunk");
 548.932 +
 548.933 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
 548.934 +   {
 548.935 +      png_warning(png_ptr, "Duplicate sRGB chunk");
 548.936 +      png_crc_finish(png_ptr, length);
 548.937 +      return;
 548.938 +   }
 548.939 +
 548.940 +   if (length != 1)
 548.941 +   {
 548.942 +      png_warning(png_ptr, "Incorrect sRGB chunk length");
 548.943 +      png_crc_finish(png_ptr, length);
 548.944 +      return;
 548.945 +   }
 548.946 +
 548.947 +   png_crc_read(png_ptr, buf, 1);
 548.948 +   if (png_crc_finish(png_ptr, 0))
 548.949 +      return;
 548.950 +
 548.951 +   intent = buf[0];
 548.952 +   /* check for bad intent */
 548.953 +   if (intent >= PNG_sRGB_INTENT_LAST)
 548.954 +   {
 548.955 +      png_warning(png_ptr, "Unknown sRGB intent");
 548.956 +      return;
 548.957 +   }
 548.958 +
 548.959 +#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
 548.960 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
 548.961 +   {
 548.962 +   png_fixed_point igamma;
 548.963 +#ifdef PNG_FIXED_POINT_SUPPORTED
 548.964 +      igamma=info_ptr->int_gamma;
 548.965 +#else
 548.966 +#  ifdef PNG_FLOATING_POINT_SUPPORTED
 548.967 +      igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
 548.968 +#  endif
 548.969 +#endif
 548.970 +      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
 548.971 +      {
 548.972 +         png_warning(png_ptr,
 548.973 +           "Ignoring incorrect gAMA value when sRGB is also present");
 548.974 +#ifndef PNG_NO_CONSOLE_IO
 548.975 +#  ifdef PNG_FIXED_POINT_SUPPORTED
 548.976 +         fprintf(stderr, "incorrect gamma=(%d/100000)\n",
 548.977 +            (int)png_ptr->int_gamma);
 548.978 +#  else
 548.979 +#    ifdef PNG_FLOATING_POINT_SUPPORTED
 548.980 +         fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
 548.981 +#    endif
 548.982 +#  endif
 548.983 +#endif
 548.984 +      }
 548.985 +   }
 548.986 +#endif /* PNG_READ_gAMA_SUPPORTED */
 548.987 +
 548.988 +#ifdef PNG_READ_cHRM_SUPPORTED
 548.989 +#ifdef PNG_FIXED_POINT_SUPPORTED
 548.990 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
 548.991 +      if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270,  1000) ||
 548.992 +          PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900,  1000) ||
 548.993 +          PNG_OUT_OF_RANGE(info_ptr->int_x_red,   64000L, 1000) ||
 548.994 +          PNG_OUT_OF_RANGE(info_ptr->int_y_red,   33000,  1000) ||
 548.995 +          PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000,  1000) ||
 548.996 +          PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
 548.997 +          PNG_OUT_OF_RANGE(info_ptr->int_x_blue,  15000,  1000) ||
 548.998 +          PNG_OUT_OF_RANGE(info_ptr->int_y_blue,   6000,  1000))
 548.999 +         {
548.1000 +            png_warning(png_ptr,
548.1001 +              "Ignoring incorrect cHRM value when sRGB is also present");
548.1002 +         }
548.1003 +#endif /* PNG_FIXED_POINT_SUPPORTED */
548.1004 +#endif /* PNG_READ_cHRM_SUPPORTED */
548.1005 +
548.1006 +   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
548.1007 +}
548.1008 +#endif /* PNG_READ_sRGB_SUPPORTED */
548.1009 +
548.1010 +#if defined(PNG_READ_iCCP_SUPPORTED)
548.1011 +void /* PRIVATE */
548.1012 +png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1013 +/* Note: this does not properly handle chunks that are > 64K under DOS */
548.1014 +{
548.1015 +   png_byte compression_type;
548.1016 +   png_bytep pC;
548.1017 +   png_charp profile;
548.1018 +   png_uint_32 skip = 0;
548.1019 +   png_uint_32 profile_size, profile_length;
548.1020 +   png_size_t slength, prefix_length, data_length;
548.1021 +
548.1022 +   png_debug(1, "in png_handle_iCCP\n");
548.1023 +
548.1024 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1025 +      png_error(png_ptr, "Missing IHDR before iCCP");
548.1026 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
548.1027 +   {
548.1028 +      png_warning(png_ptr, "Invalid iCCP after IDAT");
548.1029 +      png_crc_finish(png_ptr, length);
548.1030 +      return;
548.1031 +   }
548.1032 +   else if (png_ptr->mode & PNG_HAVE_PLTE)
548.1033 +      /* Should be an error, but we can cope with it */
548.1034 +      png_warning(png_ptr, "Out of place iCCP chunk");
548.1035 +
548.1036 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
548.1037 +   {
548.1038 +      png_warning(png_ptr, "Duplicate iCCP chunk");
548.1039 +      png_crc_finish(png_ptr, length);
548.1040 +      return;
548.1041 +   }
548.1042 +
548.1043 +#ifdef PNG_MAX_MALLOC_64K
548.1044 +   if (length > (png_uint_32)65535L)
548.1045 +   {
548.1046 +      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
548.1047 +      skip = length - (png_uint_32)65535L;
548.1048 +      length = (png_uint_32)65535L;
548.1049 +   }
548.1050 +#endif
548.1051 +
548.1052 +   png_free(png_ptr, png_ptr->chunkdata);
548.1053 +   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
548.1054 +   slength = (png_size_t)length;
548.1055 +   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
548.1056 +
548.1057 +   if (png_crc_finish(png_ptr, skip))
548.1058 +   {
548.1059 +      png_free(png_ptr, png_ptr->chunkdata);
548.1060 +      png_ptr->chunkdata = NULL;
548.1061 +      return;
548.1062 +   }
548.1063 +
548.1064 +   png_ptr->chunkdata[slength] = 0x00;
548.1065 +
548.1066 +   for (profile = png_ptr->chunkdata; *profile; profile++)
548.1067 +      /* empty loop to find end of name */ ;
548.1068 +
548.1069 +   ++profile;
548.1070 +
548.1071 +   /* there should be at least one zero (the compression type byte)
548.1072 +      following the separator, and we should be on it  */
548.1073 +   if ( profile >= png_ptr->chunkdata + slength - 1)
548.1074 +   {
548.1075 +      png_free(png_ptr, png_ptr->chunkdata);
548.1076 +      png_ptr->chunkdata = NULL;
548.1077 +      png_warning(png_ptr, "Malformed iCCP chunk");
548.1078 +      return;
548.1079 +   }
548.1080 +
548.1081 +   /* compression_type should always be zero */
548.1082 +   compression_type = *profile++;
548.1083 +   if (compression_type)
548.1084 +   {
548.1085 +      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
548.1086 +      compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
548.1087 +                                 wrote nonzero) */
548.1088 +   }
548.1089 +
548.1090 +   prefix_length = profile - png_ptr->chunkdata;
548.1091 +   png_decompress_chunk(png_ptr, compression_type,
548.1092 +     slength, prefix_length, &data_length);
548.1093 +
548.1094 +   profile_length = data_length - prefix_length;
548.1095 +
548.1096 +   if ( prefix_length > data_length || profile_length < 4)
548.1097 +   {
548.1098 +      png_free(png_ptr, png_ptr->chunkdata);
548.1099 +      png_ptr->chunkdata = NULL;
548.1100 +      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
548.1101 +      return;
548.1102 +   }
548.1103 +
548.1104 +   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
548.1105 +   pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
548.1106 +   profile_size = ((*(pC    ))<<24) |
548.1107 +                  ((*(pC + 1))<<16) |
548.1108 +                  ((*(pC + 2))<< 8) |
548.1109 +                  ((*(pC + 3))    );
548.1110 +
548.1111 +   if (profile_size < profile_length)
548.1112 +      profile_length = profile_size;
548.1113 +
548.1114 +   if (profile_size > profile_length)
548.1115 +   {
548.1116 +      png_free(png_ptr, png_ptr->chunkdata);
548.1117 +      png_ptr->chunkdata = NULL;
548.1118 +      png_warning(png_ptr, "Ignoring truncated iCCP profile.");
548.1119 +      return;
548.1120 +   }
548.1121 +
548.1122 +   png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
548.1123 +     compression_type, png_ptr->chunkdata + prefix_length, profile_length);
548.1124 +   png_free(png_ptr, png_ptr->chunkdata);
548.1125 +   png_ptr->chunkdata = NULL;
548.1126 +}
548.1127 +#endif /* PNG_READ_iCCP_SUPPORTED */
548.1128 +
548.1129 +#if defined(PNG_READ_sPLT_SUPPORTED)
548.1130 +void /* PRIVATE */
548.1131 +png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1132 +/* Note: this does not properly handle chunks that are > 64K under DOS */
548.1133 +{
548.1134 +   png_bytep entry_start;
548.1135 +   png_sPLT_t new_palette;
548.1136 +#ifdef PNG_NO_POINTER_INDEXING
548.1137 +   png_sPLT_entryp pp;
548.1138 +#endif
548.1139 +   int data_length, entry_size, i;
548.1140 +   png_uint_32 skip = 0;
548.1141 +   png_size_t slength;
548.1142 +
548.1143 +   png_debug(1, "in png_handle_sPLT\n");
548.1144 +
548.1145 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1146 +      png_error(png_ptr, "Missing IHDR before sPLT");
548.1147 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
548.1148 +   {
548.1149 +      png_warning(png_ptr, "Invalid sPLT after IDAT");
548.1150 +      png_crc_finish(png_ptr, length);
548.1151 +      return;
548.1152 +   }
548.1153 +
548.1154 +#ifdef PNG_MAX_MALLOC_64K
548.1155 +   if (length > (png_uint_32)65535L)
548.1156 +   {
548.1157 +      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
548.1158 +      skip = length - (png_uint_32)65535L;
548.1159 +      length = (png_uint_32)65535L;
548.1160 +   }
548.1161 +#endif
548.1162 +
548.1163 +   png_free(png_ptr, png_ptr->chunkdata);
548.1164 +   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
548.1165 +   slength = (png_size_t)length;
548.1166 +   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
548.1167 +
548.1168 +   if (png_crc_finish(png_ptr, skip))
548.1169 +   {
548.1170 +      png_free(png_ptr, png_ptr->chunkdata);
548.1171 +      png_ptr->chunkdata = NULL;
548.1172 +      return;
548.1173 +   }
548.1174 +
548.1175 +   png_ptr->chunkdata[slength] = 0x00;
548.1176 +
548.1177 +   for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; entry_start++)
548.1178 +      /* empty loop to find end of name */ ;
548.1179 +   ++entry_start;
548.1180 +
548.1181 +   /* a sample depth should follow the separator, and we should be on it  */
548.1182 +   if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
548.1183 +   {
548.1184 +      png_free(png_ptr, png_ptr->chunkdata);
548.1185 +      png_ptr->chunkdata = NULL;
548.1186 +      png_warning(png_ptr, "malformed sPLT chunk");
548.1187 +      return;
548.1188 +   }
548.1189 +
548.1190 +   new_palette.depth = *entry_start++;
548.1191 +   entry_size = (new_palette.depth == 8 ? 6 : 10);
548.1192 +   data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
548.1193 +
548.1194 +   /* integrity-check the data length */
548.1195 +   if (data_length % entry_size)
548.1196 +   {
548.1197 +      png_free(png_ptr, png_ptr->chunkdata);
548.1198 +      png_ptr->chunkdata = NULL;
548.1199 +      png_warning(png_ptr, "sPLT chunk has bad length");
548.1200 +      return;
548.1201 +   }
548.1202 +
548.1203 +   new_palette.nentries = (png_int_32) ( data_length / entry_size);
548.1204 +   if ((png_uint_32) new_palette.nentries >
548.1205 +       (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
548.1206 +   {
548.1207 +       png_warning(png_ptr, "sPLT chunk too long");
548.1208 +       return;
548.1209 +   }
548.1210 +   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
548.1211 +       png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
548.1212 +   if (new_palette.entries == NULL)
548.1213 +   {
548.1214 +       png_warning(png_ptr, "sPLT chunk requires too much memory");
548.1215 +       return;
548.1216 +   }
548.1217 +
548.1218 +#ifndef PNG_NO_POINTER_INDEXING
548.1219 +   for (i = 0; i < new_palette.nentries; i++)
548.1220 +   {
548.1221 +      png_sPLT_entryp pp = new_palette.entries + i;
548.1222 +
548.1223 +      if (new_palette.depth == 8)
548.1224 +      {
548.1225 +          pp->red = *entry_start++;
548.1226 +          pp->green = *entry_start++;
548.1227 +          pp->blue = *entry_start++;
548.1228 +          pp->alpha = *entry_start++;
548.1229 +      }
548.1230 +      else
548.1231 +      {
548.1232 +          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
548.1233 +          pp->green = png_get_uint_16(entry_start); entry_start += 2;
548.1234 +          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
548.1235 +          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
548.1236 +      }
548.1237 +      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
548.1238 +   }
548.1239 +#else
548.1240 +   pp = new_palette.entries;
548.1241 +   for (i = 0; i < new_palette.nentries; i++)
548.1242 +   {
548.1243 +
548.1244 +      if (new_palette.depth == 8)
548.1245 +      {
548.1246 +          pp[i].red   = *entry_start++;
548.1247 +          pp[i].green = *entry_start++;
548.1248 +          pp[i].blue  = *entry_start++;
548.1249 +          pp[i].alpha = *entry_start++;
548.1250 +      }
548.1251 +      else
548.1252 +      {
548.1253 +          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
548.1254 +          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
548.1255 +          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
548.1256 +          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
548.1257 +      }
548.1258 +      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
548.1259 +   }
548.1260 +#endif
548.1261 +
548.1262 +   /* discard all chunk data except the name and stash that */
548.1263 +   new_palette.name = png_ptr->chunkdata;
548.1264 +
548.1265 +   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
548.1266 +
548.1267 +   png_free(png_ptr, png_ptr->chunkdata);
548.1268 +   png_ptr->chunkdata = NULL;
548.1269 +   png_free(png_ptr, new_palette.entries);
548.1270 +}
548.1271 +#endif /* PNG_READ_sPLT_SUPPORTED */
548.1272 +
548.1273 +#if defined(PNG_READ_tRNS_SUPPORTED)
548.1274 +void /* PRIVATE */
548.1275 +png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1276 +{
548.1277 +   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
548.1278 +
548.1279 +   png_debug(1, "in png_handle_tRNS\n");
548.1280 +
548.1281 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1282 +      png_error(png_ptr, "Missing IHDR before tRNS");
548.1283 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
548.1284 +   {
548.1285 +      png_warning(png_ptr, "Invalid tRNS after IDAT");
548.1286 +      png_crc_finish(png_ptr, length);
548.1287 +      return;
548.1288 +   }
548.1289 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
548.1290 +   {
548.1291 +      png_warning(png_ptr, "Duplicate tRNS chunk");
548.1292 +      png_crc_finish(png_ptr, length);
548.1293 +      return;
548.1294 +   }
548.1295 +
548.1296 +   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
548.1297 +   {
548.1298 +      png_byte buf[2];
548.1299 +
548.1300 +      if (length != 2)
548.1301 +      {
548.1302 +         png_warning(png_ptr, "Incorrect tRNS chunk length");
548.1303 +         png_crc_finish(png_ptr, length);
548.1304 +         return;
548.1305 +      }
548.1306 +
548.1307 +      png_crc_read(png_ptr, buf, 2);
548.1308 +      png_ptr->num_trans = 1;
548.1309 +      png_ptr->trans_values.gray = png_get_uint_16(buf);
548.1310 +   }
548.1311 +   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
548.1312 +   {
548.1313 +      png_byte buf[6];
548.1314 +
548.1315 +      if (length != 6)
548.1316 +      {
548.1317 +         png_warning(png_ptr, "Incorrect tRNS chunk length");
548.1318 +         png_crc_finish(png_ptr, length);
548.1319 +         return;
548.1320 +      }
548.1321 +      png_crc_read(png_ptr, buf, (png_size_t)length);
548.1322 +      png_ptr->num_trans = 1;
548.1323 +      png_ptr->trans_values.red = png_get_uint_16(buf);
548.1324 +      png_ptr->trans_values.green = png_get_uint_16(buf + 2);
548.1325 +      png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
548.1326 +   }
548.1327 +   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
548.1328 +   {
548.1329 +      if (!(png_ptr->mode & PNG_HAVE_PLTE))
548.1330 +      {
548.1331 +         /* Should be an error, but we can cope with it. */
548.1332 +         png_warning(png_ptr, "Missing PLTE before tRNS");
548.1333 +      }
548.1334 +      if (length > (png_uint_32)png_ptr->num_palette ||
548.1335 +          length > PNG_MAX_PALETTE_LENGTH)
548.1336 +      {
548.1337 +         png_warning(png_ptr, "Incorrect tRNS chunk length");
548.1338 +         png_crc_finish(png_ptr, length);
548.1339 +         return;
548.1340 +      }
548.1341 +      if (length == 0)
548.1342 +      {
548.1343 +         png_warning(png_ptr, "Zero length tRNS chunk");
548.1344 +         png_crc_finish(png_ptr, length);
548.1345 +         return;
548.1346 +      }
548.1347 +      png_crc_read(png_ptr, readbuf, (png_size_t)length);
548.1348 +      png_ptr->num_trans = (png_uint_16)length;
548.1349 +   }
548.1350 +   else
548.1351 +   {
548.1352 +      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
548.1353 +      png_crc_finish(png_ptr, length);
548.1354 +      return;
548.1355 +   }
548.1356 +
548.1357 +   if (png_crc_finish(png_ptr, 0))
548.1358 +   {
548.1359 +      png_ptr->num_trans = 0;
548.1360 +      return;
548.1361 +   }
548.1362 +
548.1363 +   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
548.1364 +      &(png_ptr->trans_values));
548.1365 +}
548.1366 +#endif
548.1367 +
548.1368 +#if defined(PNG_READ_bKGD_SUPPORTED)
548.1369 +void /* PRIVATE */
548.1370 +png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1371 +{
548.1372 +   png_size_t truelen;
548.1373 +   png_byte buf[6];
548.1374 +
548.1375 +   png_debug(1, "in png_handle_bKGD\n");
548.1376 +
548.1377 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1378 +      png_error(png_ptr, "Missing IHDR before bKGD");
548.1379 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
548.1380 +   {
548.1381 +      png_warning(png_ptr, "Invalid bKGD after IDAT");
548.1382 +      png_crc_finish(png_ptr, length);
548.1383 +      return;
548.1384 +   }
548.1385 +   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
548.1386 +            !(png_ptr->mode & PNG_HAVE_PLTE))
548.1387 +   {
548.1388 +      png_warning(png_ptr, "Missing PLTE before bKGD");
548.1389 +      png_crc_finish(png_ptr, length);
548.1390 +      return;
548.1391 +   }
548.1392 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
548.1393 +   {
548.1394 +      png_warning(png_ptr, "Duplicate bKGD chunk");
548.1395 +      png_crc_finish(png_ptr, length);
548.1396 +      return;
548.1397 +   }
548.1398 +
548.1399 +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
548.1400 +      truelen = 1;
548.1401 +   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
548.1402 +      truelen = 6;
548.1403 +   else
548.1404 +      truelen = 2;
548.1405 +
548.1406 +   if (length != truelen)
548.1407 +   {
548.1408 +      png_warning(png_ptr, "Incorrect bKGD chunk length");
548.1409 +      png_crc_finish(png_ptr, length);
548.1410 +      return;
548.1411 +   }
548.1412 +
548.1413 +   png_crc_read(png_ptr, buf, truelen);
548.1414 +   if (png_crc_finish(png_ptr, 0))
548.1415 +      return;
548.1416 +
548.1417 +   /* We convert the index value into RGB components so that we can allow
548.1418 +    * arbitrary RGB values for background when we have transparency, and
548.1419 +    * so it is easy to determine the RGB values of the background color
548.1420 +    * from the info_ptr struct. */
548.1421 +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
548.1422 +   {
548.1423 +      png_ptr->background.index = buf[0];
548.1424 +      if (info_ptr && info_ptr->num_palette)
548.1425 +      {
548.1426 +          if (buf[0] > info_ptr->num_palette)
548.1427 +          {
548.1428 +             png_warning(png_ptr, "Incorrect bKGD chunk index value");
548.1429 +             return;
548.1430 +          }
548.1431 +          png_ptr->background.red =
548.1432 +             (png_uint_16)png_ptr->palette[buf[0]].red;
548.1433 +          png_ptr->background.green =
548.1434 +             (png_uint_16)png_ptr->palette[buf[0]].green;
548.1435 +          png_ptr->background.blue =
548.1436 +             (png_uint_16)png_ptr->palette[buf[0]].blue;
548.1437 +      }
548.1438 +   }
548.1439 +   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
548.1440 +   {
548.1441 +      png_ptr->background.red =
548.1442 +      png_ptr->background.green =
548.1443 +      png_ptr->background.blue =
548.1444 +      png_ptr->background.gray = png_get_uint_16(buf);
548.1445 +   }
548.1446 +   else
548.1447 +   {
548.1448 +      png_ptr->background.red = png_get_uint_16(buf);
548.1449 +      png_ptr->background.green = png_get_uint_16(buf + 2);
548.1450 +      png_ptr->background.blue = png_get_uint_16(buf + 4);
548.1451 +   }
548.1452 +
548.1453 +   png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
548.1454 +}
548.1455 +#endif
548.1456 +
548.1457 +#if defined(PNG_READ_hIST_SUPPORTED)
548.1458 +void /* PRIVATE */
548.1459 +png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1460 +{
548.1461 +   unsigned int num, i;
548.1462 +   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
548.1463 +
548.1464 +   png_debug(1, "in png_handle_hIST\n");
548.1465 +
548.1466 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1467 +      png_error(png_ptr, "Missing IHDR before hIST");
548.1468 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
548.1469 +   {
548.1470 +      png_warning(png_ptr, "Invalid hIST after IDAT");
548.1471 +      png_crc_finish(png_ptr, length);
548.1472 +      return;
548.1473 +   }
548.1474 +   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
548.1475 +   {
548.1476 +      png_warning(png_ptr, "Missing PLTE before hIST");
548.1477 +      png_crc_finish(png_ptr, length);
548.1478 +      return;
548.1479 +   }
548.1480 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
548.1481 +   {
548.1482 +      png_warning(png_ptr, "Duplicate hIST chunk");
548.1483 +      png_crc_finish(png_ptr, length);
548.1484 +      return;
548.1485 +   }
548.1486 +
548.1487 +   num = length / 2 ;
548.1488 +   if (num != (unsigned int) png_ptr->num_palette || num >
548.1489 +      (unsigned int) PNG_MAX_PALETTE_LENGTH)
548.1490 +   {
548.1491 +      png_warning(png_ptr, "Incorrect hIST chunk length");
548.1492 +      png_crc_finish(png_ptr, length);
548.1493 +      return;
548.1494 +   }
548.1495 +
548.1496 +   for (i = 0; i < num; i++)
548.1497 +   {
548.1498 +      png_byte buf[2];
548.1499 +
548.1500 +      png_crc_read(png_ptr, buf, 2);
548.1501 +      readbuf[i] = png_get_uint_16(buf);
548.1502 +   }
548.1503 +
548.1504 +   if (png_crc_finish(png_ptr, 0))
548.1505 +      return;
548.1506 +
548.1507 +   png_set_hIST(png_ptr, info_ptr, readbuf);
548.1508 +}
548.1509 +#endif
548.1510 +
548.1511 +#if defined(PNG_READ_pHYs_SUPPORTED)
548.1512 +void /* PRIVATE */
548.1513 +png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1514 +{
548.1515 +   png_byte buf[9];
548.1516 +   png_uint_32 res_x, res_y;
548.1517 +   int unit_type;
548.1518 +
548.1519 +   png_debug(1, "in png_handle_pHYs\n");
548.1520 +
548.1521 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1522 +      png_error(png_ptr, "Missing IHDR before pHYs");
548.1523 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
548.1524 +   {
548.1525 +      png_warning(png_ptr, "Invalid pHYs after IDAT");
548.1526 +      png_crc_finish(png_ptr, length);
548.1527 +      return;
548.1528 +   }
548.1529 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
548.1530 +   {
548.1531 +      png_warning(png_ptr, "Duplicate pHYs chunk");
548.1532 +      png_crc_finish(png_ptr, length);
548.1533 +      return;
548.1534 +   }
548.1535 +
548.1536 +   if (length != 9)
548.1537 +   {
548.1538 +      png_warning(png_ptr, "Incorrect pHYs chunk length");
548.1539 +      png_crc_finish(png_ptr, length);
548.1540 +      return;
548.1541 +   }
548.1542 +
548.1543 +   png_crc_read(png_ptr, buf, 9);
548.1544 +   if (png_crc_finish(png_ptr, 0))
548.1545 +      return;
548.1546 +
548.1547 +   res_x = png_get_uint_32(buf);
548.1548 +   res_y = png_get_uint_32(buf + 4);
548.1549 +   unit_type = buf[8];
548.1550 +   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
548.1551 +}
548.1552 +#endif
548.1553 +
548.1554 +#if defined(PNG_READ_oFFs_SUPPORTED)
548.1555 +void /* PRIVATE */
548.1556 +png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1557 +{
548.1558 +   png_byte buf[9];
548.1559 +   png_int_32 offset_x, offset_y;
548.1560 +   int unit_type;
548.1561 +
548.1562 +   png_debug(1, "in png_handle_oFFs\n");
548.1563 +
548.1564 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1565 +      png_error(png_ptr, "Missing IHDR before oFFs");
548.1566 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
548.1567 +   {
548.1568 +      png_warning(png_ptr, "Invalid oFFs after IDAT");
548.1569 +      png_crc_finish(png_ptr, length);
548.1570 +      return;
548.1571 +   }
548.1572 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
548.1573 +   {
548.1574 +      png_warning(png_ptr, "Duplicate oFFs chunk");
548.1575 +      png_crc_finish(png_ptr, length);
548.1576 +      return;
548.1577 +   }
548.1578 +
548.1579 +   if (length != 9)
548.1580 +   {
548.1581 +      png_warning(png_ptr, "Incorrect oFFs chunk length");
548.1582 +      png_crc_finish(png_ptr, length);
548.1583 +      return;
548.1584 +   }
548.1585 +
548.1586 +   png_crc_read(png_ptr, buf, 9);
548.1587 +   if (png_crc_finish(png_ptr, 0))
548.1588 +      return;
548.1589 +
548.1590 +   offset_x = png_get_int_32(buf);
548.1591 +   offset_y = png_get_int_32(buf + 4);
548.1592 +   unit_type = buf[8];
548.1593 +   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
548.1594 +}
548.1595 +#endif
548.1596 +
548.1597 +#if defined(PNG_READ_pCAL_SUPPORTED)
548.1598 +/* read the pCAL chunk (described in the PNG Extensions document) */
548.1599 +void /* PRIVATE */
548.1600 +png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1601 +{
548.1602 +   png_int_32 X0, X1;
548.1603 +   png_byte type, nparams;
548.1604 +   png_charp buf, units, endptr;
548.1605 +   png_charpp params;
548.1606 +   png_size_t slength;
548.1607 +   int i;
548.1608 +
548.1609 +   png_debug(1, "in png_handle_pCAL\n");
548.1610 +
548.1611 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1612 +      png_error(png_ptr, "Missing IHDR before pCAL");
548.1613 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
548.1614 +   {
548.1615 +      png_warning(png_ptr, "Invalid pCAL after IDAT");
548.1616 +      png_crc_finish(png_ptr, length);
548.1617 +      return;
548.1618 +   }
548.1619 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
548.1620 +   {
548.1621 +      png_warning(png_ptr, "Duplicate pCAL chunk");
548.1622 +      png_crc_finish(png_ptr, length);
548.1623 +      return;
548.1624 +   }
548.1625 +
548.1626 +   png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
548.1627 +      length + 1);
548.1628 +   png_free(png_ptr, png_ptr->chunkdata);
548.1629 +   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
548.1630 +   if (png_ptr->chunkdata == NULL)
548.1631 +     {
548.1632 +       png_warning(png_ptr, "No memory for pCAL purpose.");
548.1633 +       return;
548.1634 +     }
548.1635 +   slength = (png_size_t)length;
548.1636 +   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
548.1637 +
548.1638 +   if (png_crc_finish(png_ptr, 0))
548.1639 +   {
548.1640 +      png_free(png_ptr, png_ptr->chunkdata);
548.1641 +      png_ptr->chunkdata = NULL;
548.1642 +      return;
548.1643 +   }
548.1644 +
548.1645 +   png_ptr->chunkdata[slength] = 0x00; /* null terminate the last string */
548.1646 +
548.1647 +   png_debug(3, "Finding end of pCAL purpose string\n");
548.1648 +   for (buf = png_ptr->chunkdata; *buf; buf++)
548.1649 +      /* empty loop */ ;
548.1650 +
548.1651 +   endptr = png_ptr->chunkdata + slength;
548.1652 +
548.1653 +   /* We need to have at least 12 bytes after the purpose string
548.1654 +      in order to get the parameter information. */
548.1655 +   if (endptr <= buf + 12)
548.1656 +   {
548.1657 +      png_warning(png_ptr, "Invalid pCAL data");
548.1658 +      png_free(png_ptr, png_ptr->chunkdata);
548.1659 +      png_ptr->chunkdata = NULL;
548.1660 +      return;
548.1661 +   }
548.1662 +
548.1663 +   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
548.1664 +   X0 = png_get_int_32((png_bytep)buf+1);
548.1665 +   X1 = png_get_int_32((png_bytep)buf+5);
548.1666 +   type = buf[9];
548.1667 +   nparams = buf[10];
548.1668 +   units = buf + 11;
548.1669 +
548.1670 +   png_debug(3, "Checking pCAL equation type and number of parameters\n");
548.1671 +   /* Check that we have the right number of parameters for known
548.1672 +      equation types. */
548.1673 +   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
548.1674 +       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
548.1675 +       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
548.1676 +       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
548.1677 +   {
548.1678 +      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
548.1679 +      png_free(png_ptr, png_ptr->chunkdata);
548.1680 +      png_ptr->chunkdata = NULL;
548.1681 +      return;
548.1682 +   }
548.1683 +   else if (type >= PNG_EQUATION_LAST)
548.1684 +   {
548.1685 +      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
548.1686 +   }
548.1687 +
548.1688 +   for (buf = units; *buf; buf++)
548.1689 +      /* Empty loop to move past the units string. */ ;
548.1690 +
548.1691 +   png_debug(3, "Allocating pCAL parameters array\n");
548.1692 +   params = (png_charpp)png_malloc_warn(png_ptr,
548.1693 +      (png_uint_32)(nparams * png_sizeof(png_charp))) ;
548.1694 +   if (params == NULL)
548.1695 +     {
548.1696 +       png_free(png_ptr, png_ptr->chunkdata);
548.1697 +       png_ptr->chunkdata = NULL;
548.1698 +       png_warning(png_ptr, "No memory for pCAL params.");
548.1699 +       return;
548.1700 +     }
548.1701 +
548.1702 +   /* Get pointers to the start of each parameter string. */
548.1703 +   for (i = 0; i < (int)nparams; i++)
548.1704 +   {
548.1705 +      buf++; /* Skip the null string terminator from previous parameter. */
548.1706 +
548.1707 +      png_debug1(3, "Reading pCAL parameter %d\n", i);
548.1708 +      for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
548.1709 +         /* Empty loop to move past each parameter string */ ;
548.1710 +
548.1711 +      /* Make sure we haven't run out of data yet */
548.1712 +      if (buf > endptr)
548.1713 +      {
548.1714 +         png_warning(png_ptr, "Invalid pCAL data");
548.1715 +         png_free(png_ptr, png_ptr->chunkdata);
548.1716 +         png_ptr->chunkdata = NULL;
548.1717 +         png_free(png_ptr, params);
548.1718 +         return;
548.1719 +      }
548.1720 +   }
548.1721 +
548.1722 +   png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
548.1723 +      units, params);
548.1724 +
548.1725 +   png_free(png_ptr, png_ptr->chunkdata);
548.1726 +   png_ptr->chunkdata = NULL;
548.1727 +   png_free(png_ptr, params);
548.1728 +}
548.1729 +#endif
548.1730 +
548.1731 +#if defined(PNG_READ_sCAL_SUPPORTED)
548.1732 +/* read the sCAL chunk */
548.1733 +void /* PRIVATE */
548.1734 +png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1735 +{
548.1736 +   png_charp ep;
548.1737 +#ifdef PNG_FLOATING_POINT_SUPPORTED
548.1738 +   double width, height;
548.1739 +   png_charp vp;
548.1740 +#else
548.1741 +#ifdef PNG_FIXED_POINT_SUPPORTED
548.1742 +   png_charp swidth, sheight;
548.1743 +#endif
548.1744 +#endif
548.1745 +   png_size_t slength;
548.1746 +
548.1747 +   png_debug(1, "in png_handle_sCAL\n");
548.1748 +
548.1749 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1750 +      png_error(png_ptr, "Missing IHDR before sCAL");
548.1751 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
548.1752 +   {
548.1753 +      png_warning(png_ptr, "Invalid sCAL after IDAT");
548.1754 +      png_crc_finish(png_ptr, length);
548.1755 +      return;
548.1756 +   }
548.1757 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
548.1758 +   {
548.1759 +      png_warning(png_ptr, "Duplicate sCAL chunk");
548.1760 +      png_crc_finish(png_ptr, length);
548.1761 +      return;
548.1762 +   }
548.1763 +
548.1764 +   png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
548.1765 +      length + 1);
548.1766 +   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
548.1767 +   if (png_ptr->chunkdata == NULL)
548.1768 +   {
548.1769 +      png_warning(png_ptr, "Out of memory while processing sCAL chunk");
548.1770 +      return;
548.1771 +   }
548.1772 +   slength = (png_size_t)length;
548.1773 +   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
548.1774 +
548.1775 +   if (png_crc_finish(png_ptr, 0))
548.1776 +   {
548.1777 +      png_free(png_ptr, png_ptr->chunkdata);
548.1778 +      png_ptr->chunkdata = NULL;
548.1779 +      return;
548.1780 +   }
548.1781 +
548.1782 +   png_ptr->chunkdata[slength] = 0x00; /* null terminate the last string */
548.1783 +
548.1784 +   ep = png_ptr->chunkdata + 1;        /* skip unit byte */
548.1785 +
548.1786 +#ifdef PNG_FLOATING_POINT_SUPPORTED
548.1787 +   width = png_strtod(png_ptr, ep, &vp);
548.1788 +   if (*vp)
548.1789 +   {
548.1790 +      png_warning(png_ptr, "malformed width string in sCAL chunk");
548.1791 +      return;
548.1792 +   }
548.1793 +#else
548.1794 +#ifdef PNG_FIXED_POINT_SUPPORTED
548.1795 +   swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
548.1796 +   if (swidth == NULL)
548.1797 +   {
548.1798 +      png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
548.1799 +      return;
548.1800 +   }
548.1801 +   png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
548.1802 +#endif
548.1803 +#endif
548.1804 +
548.1805 +   for (ep = png_ptr->chunkdata; *ep; ep++)
548.1806 +      /* empty loop */ ;
548.1807 +   ep++;
548.1808 +
548.1809 +   if (png_ptr->chunkdata + slength < ep)
548.1810 +   {
548.1811 +      png_warning(png_ptr, "Truncated sCAL chunk");
548.1812 +#if defined(PNG_FIXED_POINT_SUPPORTED) && \
548.1813 +    !defined(PNG_FLOATING_POINT_SUPPORTED)
548.1814 +      png_free(png_ptr, swidth);
548.1815 +#endif
548.1816 +      png_free(png_ptr, png_ptr->chunkdata);
548.1817 +      png_ptr->chunkdata = NULL;
548.1818 +      return;
548.1819 +   }
548.1820 +
548.1821 +#ifdef PNG_FLOATING_POINT_SUPPORTED
548.1822 +   height = png_strtod(png_ptr, ep, &vp);
548.1823 +   if (*vp)
548.1824 +   {
548.1825 +      png_warning(png_ptr, "malformed height string in sCAL chunk");
548.1826 +      return;
548.1827 +   }
548.1828 +#else
548.1829 +#ifdef PNG_FIXED_POINT_SUPPORTED
548.1830 +   sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
548.1831 +   if (sheight == NULL)
548.1832 +   {
548.1833 +      png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
548.1834 +      return;
548.1835 +   }
548.1836 +   png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
548.1837 +#endif
548.1838 +#endif
548.1839 +
548.1840 +   if (png_ptr->chunkdata + slength < ep
548.1841 +#ifdef PNG_FLOATING_POINT_SUPPORTED
548.1842 +      || width <= 0. || height <= 0.
548.1843 +#endif
548.1844 +      )
548.1845 +   {
548.1846 +      png_warning(png_ptr, "Invalid sCAL data");
548.1847 +      png_free(png_ptr, png_ptr->chunkdata);
548.1848 +      png_ptr->chunkdata = NULL;
548.1849 +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
548.1850 +      png_free(png_ptr, swidth);
548.1851 +      png_free(png_ptr, sheight);
548.1852 +#endif
548.1853 +      return;
548.1854 +   }
548.1855 +
548.1856 +
548.1857 +#ifdef PNG_FLOATING_POINT_SUPPORTED
548.1858 +   png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
548.1859 +#else
548.1860 +#ifdef PNG_FIXED_POINT_SUPPORTED
548.1861 +   png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
548.1862 +#endif
548.1863 +#endif
548.1864 +
548.1865 +   png_free(png_ptr, png_ptr->chunkdata);
548.1866 +   png_ptr->chunkdata = NULL;
548.1867 +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
548.1868 +   png_free(png_ptr, swidth);
548.1869 +   png_free(png_ptr, sheight);
548.1870 +#endif
548.1871 +}
548.1872 +#endif
548.1873 +
548.1874 +#if defined(PNG_READ_tIME_SUPPORTED)
548.1875 +void /* PRIVATE */
548.1876 +png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1877 +{
548.1878 +   png_byte buf[7];
548.1879 +   png_time mod_time;
548.1880 +
548.1881 +   png_debug(1, "in png_handle_tIME\n");
548.1882 +
548.1883 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1884 +      png_error(png_ptr, "Out of place tIME chunk");
548.1885 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
548.1886 +   {
548.1887 +      png_warning(png_ptr, "Duplicate tIME chunk");
548.1888 +      png_crc_finish(png_ptr, length);
548.1889 +      return;
548.1890 +   }
548.1891 +
548.1892 +   if (png_ptr->mode & PNG_HAVE_IDAT)
548.1893 +      png_ptr->mode |= PNG_AFTER_IDAT;
548.1894 +
548.1895 +   if (length != 7)
548.1896 +   {
548.1897 +      png_warning(png_ptr, "Incorrect tIME chunk length");
548.1898 +      png_crc_finish(png_ptr, length);
548.1899 +      return;
548.1900 +   }
548.1901 +
548.1902 +   png_crc_read(png_ptr, buf, 7);
548.1903 +   if (png_crc_finish(png_ptr, 0))
548.1904 +      return;
548.1905 +
548.1906 +   mod_time.second = buf[6];
548.1907 +   mod_time.minute = buf[5];
548.1908 +   mod_time.hour = buf[4];
548.1909 +   mod_time.day = buf[3];
548.1910 +   mod_time.month = buf[2];
548.1911 +   mod_time.year = png_get_uint_16(buf);
548.1912 +
548.1913 +   png_set_tIME(png_ptr, info_ptr, &mod_time);
548.1914 +}
548.1915 +#endif
548.1916 +
548.1917 +#if defined(PNG_READ_tEXt_SUPPORTED)
548.1918 +/* Note: this does not properly handle chunks that are > 64K under DOS */
548.1919 +void /* PRIVATE */
548.1920 +png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.1921 +{
548.1922 +   png_textp text_ptr;
548.1923 +   png_charp key;
548.1924 +   png_charp text;
548.1925 +   png_uint_32 skip = 0;
548.1926 +   png_size_t slength;
548.1927 +   int ret;
548.1928 +
548.1929 +   png_debug(1, "in png_handle_tEXt\n");
548.1930 +
548.1931 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.1932 +      png_error(png_ptr, "Missing IHDR before tEXt");
548.1933 +
548.1934 +   if (png_ptr->mode & PNG_HAVE_IDAT)
548.1935 +      png_ptr->mode |= PNG_AFTER_IDAT;
548.1936 +
548.1937 +#ifdef PNG_MAX_MALLOC_64K
548.1938 +   if (length > (png_uint_32)65535L)
548.1939 +   {
548.1940 +      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
548.1941 +      skip = length - (png_uint_32)65535L;
548.1942 +      length = (png_uint_32)65535L;
548.1943 +   }
548.1944 +#endif
548.1945 +
548.1946 +   png_free(png_ptr, png_ptr->chunkdata);
548.1947 +   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
548.1948 +   if (png_ptr->chunkdata == NULL)
548.1949 +   {
548.1950 +     png_warning(png_ptr, "No memory to process text chunk.");
548.1951 +     return;
548.1952 +   }
548.1953 +   slength = (png_size_t)length;
548.1954 +   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
548.1955 +
548.1956 +   if (png_crc_finish(png_ptr, skip))
548.1957 +   {
548.1958 +      png_free(png_ptr, png_ptr->chunkdata);
548.1959 +      png_ptr->chunkdata = NULL;
548.1960 +      return;
548.1961 +   }
548.1962 +
548.1963 +   key = png_ptr->chunkdata;
548.1964 +   key[slength] = 0x00;
548.1965 +
548.1966 +   for (text = key; *text; text++)
548.1967 +      /* empty loop to find end of key */ ;
548.1968 +
548.1969 +   if (text != key + slength)
548.1970 +      text++;
548.1971 +
548.1972 +   text_ptr = (png_textp)png_malloc_warn(png_ptr,
548.1973 +      (png_uint_32)png_sizeof(png_text));
548.1974 +   if (text_ptr == NULL)
548.1975 +   {
548.1976 +     png_warning(png_ptr, "Not enough memory to process text chunk.");
548.1977 +     png_free(png_ptr, png_ptr->chunkdata);
548.1978 +     png_ptr->chunkdata = NULL;
548.1979 +     return;
548.1980 +   }
548.1981 +   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
548.1982 +   text_ptr->key = key;
548.1983 +#ifdef PNG_iTXt_SUPPORTED
548.1984 +   text_ptr->lang = NULL;
548.1985 +   text_ptr->lang_key = NULL;
548.1986 +   text_ptr->itxt_length = 0;
548.1987 +#endif
548.1988 +   text_ptr->text = text;
548.1989 +   text_ptr->text_length = png_strlen(text);
548.1990 +
548.1991 +   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
548.1992 +
548.1993 +   png_free(png_ptr, png_ptr->chunkdata);
548.1994 +   png_ptr->chunkdata = NULL;
548.1995 +   png_free(png_ptr, text_ptr);
548.1996 +   if (ret)
548.1997 +     png_warning(png_ptr, "Insufficient memory to process text chunk.");
548.1998 +}
548.1999 +#endif
548.2000 +
548.2001 +#if defined(PNG_READ_zTXt_SUPPORTED)
548.2002 +/* note: this does not correctly handle chunks that are > 64K under DOS */
548.2003 +void /* PRIVATE */
548.2004 +png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.2005 +{
548.2006 +   png_textp text_ptr;
548.2007 +   png_charp text;
548.2008 +   int comp_type;
548.2009 +   int ret;
548.2010 +   png_size_t slength, prefix_len, data_len;
548.2011 +
548.2012 +   png_debug(1, "in png_handle_zTXt\n");
548.2013 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.2014 +      png_error(png_ptr, "Missing IHDR before zTXt");
548.2015 +
548.2016 +   if (png_ptr->mode & PNG_HAVE_IDAT)
548.2017 +      png_ptr->mode |= PNG_AFTER_IDAT;
548.2018 +
548.2019 +#ifdef PNG_MAX_MALLOC_64K
548.2020 +   /* We will no doubt have problems with chunks even half this size, but
548.2021 +      there is no hard and fast rule to tell us where to stop. */
548.2022 +   if (length > (png_uint_32)65535L)
548.2023 +   {
548.2024 +     png_warning(png_ptr, "zTXt chunk too large to fit in memory");
548.2025 +     png_crc_finish(png_ptr, length);
548.2026 +     return;
548.2027 +   }
548.2028 +#endif
548.2029 +
548.2030 +   png_free(png_ptr, png_ptr->chunkdata);
548.2031 +   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
548.2032 +   if (png_ptr->chunkdata == NULL)
548.2033 +   {
548.2034 +     png_warning(png_ptr, "Out of memory processing zTXt chunk.");
548.2035 +     return;
548.2036 +   }
548.2037 +   slength = (png_size_t)length;
548.2038 +   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
548.2039 +   if (png_crc_finish(png_ptr, 0))
548.2040 +   {
548.2041 +      png_free(png_ptr, png_ptr->chunkdata);
548.2042 +      png_ptr->chunkdata = NULL;
548.2043 +      return;
548.2044 +   }
548.2045 +
548.2046 +   png_ptr->chunkdata[slength] = 0x00;
548.2047 +
548.2048 +   for (text = png_ptr->chunkdata; *text; text++)
548.2049 +      /* empty loop */ ;
548.2050 +
548.2051 +   /* zTXt must have some text after the chunkdataword */
548.2052 +   if (text >= png_ptr->chunkdata + slength - 2)
548.2053 +   {
548.2054 +      png_warning(png_ptr, "Truncated zTXt chunk");
548.2055 +      png_free(png_ptr, png_ptr->chunkdata);
548.2056 +      png_ptr->chunkdata = NULL;
548.2057 +      return;
548.2058 +   }
548.2059 +   else
548.2060 +   {
548.2061 +       comp_type = *(++text);
548.2062 +       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
548.2063 +       {
548.2064 +          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
548.2065 +          comp_type = PNG_TEXT_COMPRESSION_zTXt;
548.2066 +       }
548.2067 +       text++;        /* skip the compression_method byte */
548.2068 +   }
548.2069 +   prefix_len = text - png_ptr->chunkdata;
548.2070 +
548.2071 +   png_decompress_chunk(png_ptr, comp_type,
548.2072 +     (png_size_t)length, prefix_len, &data_len);
548.2073 +
548.2074 +   text_ptr = (png_textp)png_malloc_warn(png_ptr,
548.2075 +      (png_uint_32)png_sizeof(png_text));
548.2076 +   if (text_ptr == NULL)
548.2077 +   {
548.2078 +     png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
548.2079 +     png_free(png_ptr, png_ptr->chunkdata);
548.2080 +     png_ptr->chunkdata = NULL;
548.2081 +     return;
548.2082 +   }
548.2083 +   text_ptr->compression = comp_type;
548.2084 +   text_ptr->key = png_ptr->chunkdata;
548.2085 +#ifdef PNG_iTXt_SUPPORTED
548.2086 +   text_ptr->lang = NULL;
548.2087 +   text_ptr->lang_key = NULL;
548.2088 +   text_ptr->itxt_length = 0;
548.2089 +#endif
548.2090 +   text_ptr->text = png_ptr->chunkdata + prefix_len;
548.2091 +   text_ptr->text_length = data_len;
548.2092 +
548.2093 +   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
548.2094 +
548.2095 +   png_free(png_ptr, text_ptr);
548.2096 +   png_free(png_ptr, png_ptr->chunkdata);
548.2097 +   png_ptr->chunkdata = NULL;
548.2098 +   if (ret)
548.2099 +     png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
548.2100 +}
548.2101 +#endif
548.2102 +
548.2103 +#if defined(PNG_READ_iTXt_SUPPORTED)
548.2104 +/* note: this does not correctly handle chunks that are > 64K under DOS */
548.2105 +void /* PRIVATE */
548.2106 +png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.2107 +{
548.2108 +   png_textp text_ptr;
548.2109 +   png_charp key, lang, text, lang_key;
548.2110 +   int comp_flag;
548.2111 +   int comp_type = 0;
548.2112 +   int ret;
548.2113 +   png_size_t slength, prefix_len, data_len;
548.2114 +
548.2115 +   png_debug(1, "in png_handle_iTXt\n");
548.2116 +
548.2117 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
548.2118 +      png_error(png_ptr, "Missing IHDR before iTXt");
548.2119 +
548.2120 +   if (png_ptr->mode & PNG_HAVE_IDAT)
548.2121 +      png_ptr->mode |= PNG_AFTER_IDAT;
548.2122 +
548.2123 +#ifdef PNG_MAX_MALLOC_64K
548.2124 +   /* We will no doubt have problems with chunks even half this size, but
548.2125 +      there is no hard and fast rule to tell us where to stop. */
548.2126 +   if (length > (png_uint_32)65535L)
548.2127 +   {
548.2128 +     png_warning(png_ptr, "iTXt chunk too large to fit in memory");
548.2129 +     png_crc_finish(png_ptr, length);
548.2130 +     return;
548.2131 +   }
548.2132 +#endif
548.2133 +
548.2134 +   png_free(png_ptr, png_ptr->chunkdata);
548.2135 +   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
548.2136 +   if (png_ptr->chunkdata == NULL)
548.2137 +   {
548.2138 +     png_warning(png_ptr, "No memory to process iTXt chunk.");
548.2139 +     return;
548.2140 +   }
548.2141 +   slength = (png_size_t)length;
548.2142 +   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
548.2143 +   if (png_crc_finish(png_ptr, 0))
548.2144 +   {
548.2145 +      png_free(png_ptr, png_ptr->chunkdata);
548.2146 +      png_ptr->chunkdata = NULL;
548.2147 +      return;
548.2148 +   }
548.2149 +
548.2150 +   png_ptr->chunkdata[slength] = 0x00;
548.2151 +
548.2152 +   for (lang = png_ptr->chunkdata; *lang; lang++)
548.2153 +      /* empty loop */ ;
548.2154 +   lang++;        /* skip NUL separator */
548.2155 +
548.2156 +   /* iTXt must have a language tag (possibly empty), two compression bytes,
548.2157 +      translated keyword (possibly empty), and possibly some text after the
548.2158 +      keyword */
548.2159 +
548.2160 +   if (lang >= png_ptr->chunkdata + slength - 3)
548.2161 +   {
548.2162 +      png_warning(png_ptr, "Truncated iTXt chunk");
548.2163 +      png_free(png_ptr, png_ptr->chunkdata);
548.2164 +      png_ptr->chunkdata = NULL;
548.2165 +      return;
548.2166 +   }
548.2167 +   else
548.2168 +   {
548.2169 +       comp_flag = *lang++;
548.2170 +       comp_type = *lang++;
548.2171 +   }
548.2172 +
548.2173 +   for (lang_key = lang; *lang_key; lang_key++)
548.2174 +      /* empty loop */ ;
548.2175 +   lang_key++;        /* skip NUL separator */
548.2176 +
548.2177 +   if (lang_key >= png_ptr->chunkdata + slength)
548.2178 +   {
548.2179 +      png_warning(png_ptr, "Truncated iTXt chunk");
548.2180 +      png_free(png_ptr, png_ptr->chunkdata);
548.2181 +      png_ptr->chunkdata = NULL;
548.2182 +      return;
548.2183 +   }
548.2184 +
548.2185 +   for (text = lang_key; *text; text++)
548.2186 +      /* empty loop */ ;
548.2187 +   text++;        /* skip NUL separator */
548.2188 +   if (text >= png_ptr->chunkdata + slength)
548.2189 +   {
548.2190 +      png_warning(png_ptr, "Malformed iTXt chunk");
548.2191 +      png_free(png_ptr, png_ptr->chunkdata);
548.2192 +      png_ptr->chunkdata = NULL;
548.2193 +      return;
548.2194 +   }
548.2195 +
548.2196 +   prefix_len = text - png_ptr->chunkdata;
548.2197 +
548.2198 +   key=png_ptr->chunkdata;
548.2199 +   if (comp_flag)
548.2200 +       png_decompress_chunk(png_ptr, comp_type,
548.2201 +         (size_t)length, prefix_len, &data_len);
548.2202 +   else
548.2203 +       data_len = png_strlen(png_ptr->chunkdata + prefix_len);
548.2204 +   text_ptr = (png_textp)png_malloc_warn(png_ptr,
548.2205 +      (png_uint_32)png_sizeof(png_text));
548.2206 +   if (text_ptr == NULL)
548.2207 +   {
548.2208 +     png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
548.2209 +     png_free(png_ptr, png_ptr->chunkdata);
548.2210 +     png_ptr->chunkdata = NULL;
548.2211 +     return;
548.2212 +   }
548.2213 +   text_ptr->compression = (int)comp_flag + 1;
548.2214 +   text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
548.2215 +   text_ptr->lang = png_ptr->chunkdata + (lang - key);
548.2216 +   text_ptr->itxt_length = data_len;
548.2217 +   text_ptr->text_length = 0;
548.2218 +   text_ptr->key = png_ptr->chunkdata;
548.2219 +   text_ptr->text = png_ptr->chunkdata + prefix_len;
548.2220 +
548.2221 +   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
548.2222 +
548.2223 +   png_free(png_ptr, text_ptr);
548.2224 +   png_free(png_ptr, png_ptr->chunkdata);
548.2225 +   png_ptr->chunkdata = NULL;
548.2226 +   if (ret)
548.2227 +     png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
548.2228 +}
548.2229 +#endif
548.2230 +
548.2231 +/* This function is called when we haven't found a handler for a
548.2232 +   chunk.  If there isn't a problem with the chunk itself (ie bad
548.2233 +   chunk name, CRC, or a critical chunk), the chunk is silently ignored
548.2234 +   -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
548.2235 +   case it will be saved away to be written out later. */
548.2236 +void /* PRIVATE */
548.2237 +png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
548.2238 +{
548.2239 +   png_uint_32 skip = 0;
548.2240 +
548.2241 +   png_debug(1, "in png_handle_unknown\n");
548.2242 +
548.2243 +   if (png_ptr->mode & PNG_HAVE_IDAT)
548.2244 +   {
548.2245 +#ifdef PNG_USE_LOCAL_ARRAYS
548.2246 +      PNG_CONST PNG_IDAT;
548.2247 +#endif
548.2248 +      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* not an IDAT */
548.2249 +         png_ptr->mode |= PNG_AFTER_IDAT;
548.2250 +   }
548.2251 +
548.2252 +   if (!(png_ptr->chunk_name[0] & 0x20))
548.2253 +   {
548.2254 +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
548.2255 +      if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
548.2256 +           PNG_HANDLE_CHUNK_ALWAYS
548.2257 +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
548.2258 +           && png_ptr->read_user_chunk_fn == NULL
548.2259 +#endif
548.2260 +        )
548.2261 +#endif
548.2262 +          png_chunk_error(png_ptr, "unknown critical chunk");
548.2263 +   }
548.2264 +
548.2265 +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
548.2266 +   if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) ||
548.2267 +       (png_ptr->read_user_chunk_fn != NULL))
548.2268 +   {
548.2269 +#ifdef PNG_MAX_MALLOC_64K
548.2270 +       if (length > (png_uint_32)65535L)
548.2271 +       {
548.2272 +           png_warning(png_ptr, "unknown chunk too large to fit in memory");
548.2273 +           skip = length - (png_uint_32)65535L;
548.2274 +           length = (png_uint_32)65535L;
548.2275 +       }
548.2276 +#endif
548.2277 +       png_memcpy((png_charp)png_ptr->unknown_chunk.name,
548.2278 +                  (png_charp)png_ptr->chunk_name, 
548.2279 +                  png_sizeof(png_ptr->unknown_chunk.name));
548.2280 +       png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] = '\0';
548.2281 +       png_ptr->unknown_chunk.size = (png_size_t)length;
548.2282 +       if (length == 0)
548.2283 +         png_ptr->unknown_chunk.data = NULL;
548.2284 +       else
548.2285 +       {
548.2286 +         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
548.2287 +         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
548.2288 +       }
548.2289 +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
548.2290 +       if (png_ptr->read_user_chunk_fn != NULL)
548.2291 +       {
548.2292 +          /* callback to user unknown chunk handler */
548.2293 +          int ret;
548.2294 +          ret = (*(png_ptr->read_user_chunk_fn))
548.2295 +            (png_ptr, &png_ptr->unknown_chunk);
548.2296 +          if (ret < 0)
548.2297 +             png_chunk_error(png_ptr, "error in user chunk");
548.2298 +          if (ret == 0)
548.2299 +          {
548.2300 +             if (!(png_ptr->chunk_name[0] & 0x20))
548.2301 +                if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
548.2302 +                     PNG_HANDLE_CHUNK_ALWAYS)
548.2303 +                   png_chunk_error(png_ptr, "unknown critical chunk");
548.2304 +             png_set_unknown_chunks(png_ptr, info_ptr,
548.2305 +               &png_ptr->unknown_chunk, 1);
548.2306 +          }
548.2307 +       }
548.2308 +       else
548.2309 +#endif
548.2310 +       png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
548.2311 +       png_free(png_ptr, png_ptr->unknown_chunk.data);
548.2312 +       png_ptr->unknown_chunk.data = NULL;
548.2313 +   }
548.2314 +   else
548.2315 +#endif
548.2316 +      skip = length;
548.2317 +
548.2318 +   png_crc_finish(png_ptr, skip);
548.2319 +
548.2320 +#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
548.2321 +   info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
548.2322 +#endif
548.2323 +}
548.2324 +
548.2325 +/* This function is called to verify that a chunk name is valid.
548.2326 +   This function can't have the "critical chunk check" incorporated
548.2327 +   into it, since in the future we will need to be able to call user
548.2328 +   functions to handle unknown critical chunks after we check that
548.2329 +   the chunk name itself is valid. */
548.2330 +
548.2331 +#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
548.2332 +
548.2333 +void /* PRIVATE */
548.2334 +png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
548.2335 +{
548.2336 +   png_debug(1, "in png_check_chunk_name\n");
548.2337 +   if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
548.2338 +       isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
548.2339 +   {
548.2340 +      png_chunk_error(png_ptr, "invalid chunk type");
548.2341 +   }
548.2342 +}
548.2343 +
548.2344 +/* Combines the row recently read in with the existing pixels in the
548.2345 +   row.  This routine takes care of alpha and transparency if requested.
548.2346 +   This routine also handles the two methods of progressive display
548.2347 +   of interlaced images, depending on the mask value.
548.2348 +   The mask value describes which pixels are to be combined with
548.2349 +   the row.  The pattern always repeats every 8 pixels, so just 8
548.2350 +   bits are needed.  A one indicates the pixel is to be combined,
548.2351 +   a zero indicates the pixel is to be skipped.  This is in addition
548.2352 +   to any alpha or transparency value associated with the pixel.  If
548.2353 +   you want all pixels to be combined, pass 0xff (255) in mask.  */
548.2354 +
548.2355 +void /* PRIVATE */
548.2356 +png_combine_row(png_structp png_ptr, png_bytep row, int mask)
548.2357 +{
548.2358 +   png_debug(1, "in png_combine_row\n");
548.2359 +   if (mask == 0xff)
548.2360 +   {
548.2361 +      png_memcpy(row, png_ptr->row_buf + 1,
548.2362 +         PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
548.2363 +   }
548.2364 +   else
548.2365 +   {
548.2366 +      switch (png_ptr->row_info.pixel_depth)
548.2367 +      {
548.2368 +         case 1:
548.2369 +         {
548.2370 +            png_bytep sp = png_ptr->row_buf + 1;
548.2371 +            png_bytep dp = row;
548.2372 +            int s_inc, s_start, s_end;
548.2373 +            int m = 0x80;
548.2374 +            int shift;
548.2375 +            png_uint_32 i;
548.2376 +            png_uint_32 row_width = png_ptr->width;
548.2377 +
548.2378 +#if defined(PNG_READ_PACKSWAP_SUPPORTED)
548.2379 +            if (png_ptr->transformations & PNG_PACKSWAP)
548.2380 +            {
548.2381 +                s_start = 0;
548.2382 +                s_end = 7;
548.2383 +                s_inc = 1;
548.2384 +            }
548.2385 +            else
548.2386 +#endif
548.2387 +            {
548.2388 +                s_start = 7;
548.2389 +                s_end = 0;
548.2390 +                s_inc = -1;
548.2391 +            }
548.2392 +
548.2393 +            shift = s_start;
548.2394 +
548.2395 +            for (i = 0; i < row_width; i++)
548.2396 +            {
548.2397 +               if (m & mask)
548.2398 +               {
548.2399 +                  int value;
548.2400 +
548.2401 +                  value = (*sp >> shift) & 0x01;
548.2402 +                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
548.2403 +                  *dp |= (png_byte)(value << shift);
548.2404 +               }
548.2405 +
548.2406 +               if (shift == s_end)
548.2407 +               {
548.2408 +                  shift = s_start;
548.2409 +                  sp++;
548.2410 +                  dp++;
548.2411 +               }
548.2412 +               else
548.2413 +                  shift += s_inc;
548.2414 +
548.2415 +               if (m == 1)
548.2416 +                  m = 0x80;
548.2417 +               else
548.2418 +                  m >>= 1;
548.2419 +            }
548.2420 +            break;
548.2421 +         }
548.2422 +         case 2:
548.2423 +         {
548.2424 +            png_bytep sp = png_ptr->row_buf + 1;
548.2425 +            png_bytep dp = row;
548.2426 +            int s_start, s_end, s_inc;
548.2427 +            int m = 0x80;
548.2428 +            int shift;
548.2429 +            png_uint_32 i;
548.2430 +            png_uint_32 row_width = png_ptr->width;
548.2431 +            int value;
548.2432 +
548.2433 +#if defined(PNG_READ_PACKSWAP_SUPPORTED)
548.2434 +            if (png_ptr->transformations & PNG_PACKSWAP)
548.2435 +            {
548.2436 +               s_start = 0;
548.2437 +               s_end = 6;
548.2438 +               s_inc = 2;
548.2439 +            }
548.2440 +            else
548.2441 +#endif
548.2442 +            {
548.2443 +               s_start = 6;
548.2444 +               s_end = 0;
548.2445 +               s_inc = -2;
548.2446 +            }
548.2447 +
548.2448 +            shift = s_start;
548.2449 +
548.2450 +            for (i = 0; i < row_width; i++)
548.2451 +            {
548.2452 +               if (m & mask)
548.2453 +               {
548.2454 +                  value = (*sp >> shift) & 0x03;
548.2455 +                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
548.2456 +                  *dp |= (png_byte)(value << shift);
548.2457 +               }
548.2458 +
548.2459 +               if (shift == s_end)
548.2460 +               {
548.2461 +                  shift = s_start;
548.2462 +                  sp++;
548.2463 +                  dp++;
548.2464 +               }
548.2465 +               else
548.2466 +                  shift += s_inc;
548.2467 +               if (m == 1)
548.2468 +                  m = 0x80;
548.2469 +               else
548.2470 +                  m >>= 1;
548.2471 +            }
548.2472 +            break;
548.2473 +         }
548.2474 +         case 4:
548.2475 +         {
548.2476 +            png_bytep sp = png_ptr->row_buf + 1;
548.2477 +            png_bytep dp = row;
548.2478 +            int s_start, s_end, s_inc;
548.2479 +            int m = 0x80;
548.2480 +            int shift;
548.2481 +            png_uint_32 i;
548.2482 +            png_uint_32 row_width = png_ptr->width;
548.2483 +            int value;
548.2484 +
548.2485 +#if defined(PNG_READ_PACKSWAP_SUPPORTED)
548.2486 +            if (png_ptr->transformations & PNG_PACKSWAP)
548.2487 +            {
548.2488 +               s_start = 0;
548.2489 +               s_end = 4;
548.2490 +               s_inc = 4;
548.2491 +            }
548.2492 +            else
548.2493 +#endif
548.2494 +            {
548.2495 +               s_start = 4;
548.2496 +               s_end = 0;
548.2497 +               s_inc = -4;
548.2498 +            }
548.2499 +            shift = s_start;
548.2500 +
548.2501 +            for (i = 0; i < row_width; i++)
548.2502 +            {
548.2503 +               if (m & mask)
548.2504 +               {
548.2505 +                  value = (*sp >> shift) & 0xf;
548.2506 +                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
548.2507 +                  *dp |= (png_byte)(value << shift);
548.2508 +               }
548.2509 +
548.2510 +               if (shift == s_end)
548.2511 +               {
548.2512 +                  shift = s_start;
548.2513 +                  sp++;
548.2514 +                  dp++;
548.2515 +               }
548.2516 +               else
548.2517 +                  shift += s_inc;
548.2518 +               if (m == 1)
548.2519 +                  m = 0x80;
548.2520 +               else
548.2521 +                  m >>= 1;
548.2522 +            }
548.2523 +            break;
548.2524 +         }
548.2525 +         default:
548.2526 +         {
548.2527 +            png_bytep sp = png_ptr->row_buf + 1;
548.2528 +            png_bytep dp = row;
548.2529 +            png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
548.2530 +            png_uint_32 i;
548.2531 +            png_uint_32 row_width = png_ptr->width;
548.2532 +            png_byte m = 0x80;
548.2533 +
548.2534 +
548.2535 +            for (i = 0; i < row_width; i++)
548.2536 +            {
548.2537 +               if (m & mask)
548.2538 +               {
548.2539 +                  png_memcpy(dp, sp, pixel_bytes);
548.2540 +               }
548.2541 +
548.2542 +               sp += pixel_bytes;
548.2543 +               dp += pixel_bytes;
548.2544 +
548.2545 +               if (m == 1)
548.2546 +                  m = 0x80;
548.2547 +               else
548.2548 +                  m >>= 1;
548.2549 +            }
548.2550 +            break;
548.2551 +         }
548.2552 +      }
548.2553 +   }
548.2554 +}
548.2555 +
548.2556 +#ifdef PNG_READ_INTERLACING_SUPPORTED
548.2557 +/* OLD pre-1.0.9 interface:
548.2558 +void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
548.2559 +   png_uint_32 transformations)
548.2560 + */
548.2561 +void /* PRIVATE */
548.2562 +png_do_read_interlace(png_structp png_ptr)
548.2563 +{
548.2564 +   png_row_infop row_info = &(png_ptr->row_info);
548.2565 +   png_bytep row = png_ptr->row_buf + 1;
548.2566 +   int pass = png_ptr->pass;
548.2567 +   png_uint_32 transformations = png_ptr->transformations;
548.2568 +#ifdef PNG_USE_LOCAL_ARRAYS
548.2569 +   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
548.2570 +   /* offset to next interlace block */
548.2571 +   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
548.2572 +#endif
548.2573 +
548.2574 +   png_debug(1, "in png_do_read_interlace\n");
548.2575 +   if (row != NULL && row_info != NULL)
548.2576 +   {
548.2577 +      png_uint_32 final_width;
548.2578 +
548.2579 +      final_width = row_info->width * png_pass_inc[pass];
548.2580 +
548.2581 +      switch (row_info->pixel_depth)
548.2582 +      {
548.2583 +         case 1:
548.2584 +         {
548.2585 +            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
548.2586 +            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
548.2587 +            int sshift, dshift;
548.2588 +            int s_start, s_end, s_inc;
548.2589 +            int jstop = png_pass_inc[pass];
548.2590 +            png_byte v;
548.2591 +            png_uint_32 i;
548.2592 +            int j;
548.2593 +
548.2594 +#if defined(PNG_READ_PACKSWAP_SUPPORTED)
548.2595 +            if (transformations & PNG_PACKSWAP)
548.2596 +            {
548.2597 +                sshift = (int)((row_info->width + 7) & 0x07);
548.2598 +                dshift = (int)((final_width + 7) & 0x07);
548.2599 +                s_start = 7;
548.2600 +                s_end = 0;
548.2601 +                s_inc = -1;
548.2602 +            }
548.2603 +            else
548.2604 +#endif
548.2605 +            {
548.2606 +                sshift = 7 - (int)((row_info->width + 7) & 0x07);
548.2607 +                dshift = 7 - (int)((final_width + 7) & 0x07);
548.2608 +                s_start = 0;
548.2609 +                s_end = 7;
548.2610 +                s_inc = 1;
548.2611 +            }
548.2612 +
548.2613 +            for (i = 0; i < row_info->width; i++)
548.2614 +            {
548.2615 +               v = (png_byte)((*sp >> sshift) & 0x01);
548.2616 +               for (j = 0; j < jstop; j++)
548.2617 +               {
548.2618 +                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
548.2619 +                  *dp |= (png_byte)(v << dshift);
548.2620 +                  if (dshift == s_end)
548.2621 +                  {
548.2622 +                     dshift = s_start;
548.2623 +                     dp--;
548.2624 +                  }
548.2625 +                  else
548.2626 +                     dshift += s_inc;
548.2627 +               }
548.2628 +               if (sshift == s_end)
548.2629 +               {
548.2630 +                  sshift = s_start;
548.2631 +                  sp--;
548.2632 +               }
548.2633 +               else
548.2634 +                  sshift += s_inc;
548.2635 +            }
548.2636 +            break;
548.2637 +         }
548.2638 +         case 2:
548.2639 +         {
548.2640 +            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
548.2641 +            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
548.2642 +            int sshift, dshift;
548.2643 +            int s_start, s_end, s_inc;
548.2644 +            int jstop = png_pass_inc[pass];
548.2645 +            png_uint_32 i;
548.2646 +
548.2647 +#if defined(PNG_READ_PACKSWAP_SUPPORTED)
548.2648 +            if (transformations & PNG_PACKSWAP)
548.2649 +            {
548.2650 +               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
548.2651 +               dshift = (int)(((final_width + 3) & 0x03) << 1);
548.2652 +               s_start = 6;
548.2653 +               s_end = 0;
548.2654 +               s_inc = -2;
548.2655 +            }
548.2656 +            else
548.2657 +#endif
548.2658 +            {
548.2659 +               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
548.2660 +               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
548.2661 +               s_start = 0;
548.2662 +               s_end = 6;
548.2663 +               s_inc = 2;
548.2664 +            }
548.2665 +
548.2666 +            for (i = 0; i < row_info->width; i++)
548.2667 +            {
548.2668 +               png_byte v;
548.2669 +               int j;
548.2670 +
548.2671 +               v = (png_byte)((*sp >> sshift) & 0x03);
548.2672 +               for (j = 0; j < jstop; j++)
548.2673 +               {
548.2674 +                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
548.2675 +                  *dp |= (png_byte)(v << dshift);
548.2676 +                  if (dshift == s_end)
548.2677 +                  {
548.2678 +                     dshift = s_start;
548.2679 +                     dp--;
548.2680 +                  }
548.2681 +                  else
548.2682 +                     dshift += s_inc;
548.2683 +               }
548.2684 +               if (sshift == s_end)
548.2685 +               {
548.2686 +                  sshift = s_start;
548.2687 +                  sp--;
548.2688 +               }
548.2689 +               else
548.2690 +                  sshift += s_inc;
548.2691 +            }
548.2692 +            break;
548.2693 +         }
548.2694 +         case 4:
548.2695 +         {
548.2696 +            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
548.2697 +            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
548.2698 +            int sshift, dshift;
548.2699 +            int s_start, s_end, s_inc;
548.2700 +            png_uint_32 i;
548.2701 +            int jstop = png_pass_inc[pass];
548.2702 +
548.2703 +#if defined(PNG_READ_PACKSWAP_SUPPORTED)
548.2704 +            if (transformations & PNG_PACKSWAP)
548.2705 +            {
548.2706 +               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
548.2707 +               dshift = (int)(((final_width + 1) & 0x01) << 2);
548.2708 +               s_start = 4;
548.2709 +               s_end = 0;
548.2710 +               s_inc = -4;
548.2711 +            }
548.2712 +            else
548.2713 +#endif
548.2714 +            {
548.2715 +               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
548.2716 +               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
548.2717 +               s_start = 0;
548.2718 +               s_end = 4;
548.2719 +               s_inc = 4;
548.2720 +            }
548.2721 +
548.2722 +            for (i = 0; i < row_info->width; i++)
548.2723 +            {
548.2724 +               png_byte v = (png_byte)((*sp >> sshift) & 0xf);
548.2725 +               int j;
548.2726 +
548.2727 +               for (j = 0; j < jstop; j++)
548.2728 +               {
548.2729 +                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
548.2730 +                  *dp |= (png_byte)(v << dshift);
548.2731 +                  if (dshift == s_end)
548.2732 +                  {
548.2733 +                     dshift = s_start;
548.2734 +                     dp--;
548.2735 +                  }
548.2736 +                  else
548.2737 +                     dshift += s_inc;
548.2738 +               }
548.2739 +               if (sshift == s_end)
548.2740 +               {
548.2741 +                  sshift = s_start;
548.2742 +                  sp--;
548.2743 +               }
548.2744 +               else
548.2745 +                  sshift += s_inc;
548.2746 +            }
548.2747 +            break;
548.2748 +         }
548.2749 +         default:
548.2750 +         {
548.2751 +            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
548.2752 +            png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
548.2753 +            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
548.2754 +
548.2755 +            int jstop = png_pass_inc[pass];
548.2756 +            png_uint_32 i;
548.2757 +
548.2758 +            for (i = 0; i < row_info->width; i++)
548.2759 +            {
548.2760 +               png_byte v[8];
548.2761 +               int j;
548.2762 +
548.2763 +               png_memcpy(v, sp, pixel_bytes);
548.2764 +               for (j = 0; j < jstop; j++)
548.2765 +               {
548.2766 +                  png_memcpy(dp, v, pixel_bytes);
548.2767 +                  dp -= pixel_bytes;
548.2768 +               }
548.2769 +               sp -= pixel_bytes;
548.2770 +            }
548.2771 +            break;
548.2772 +         }
548.2773 +      }
548.2774 +      row_info->width = final_width;
548.2775 +      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
548.2776 +   }
548.2777 +#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
548.2778 +   transformations = transformations; /* silence compiler warning */
548.2779 +#endif
548.2780 +}
548.2781 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
548.2782 +
548.2783 +void /* PRIVATE */
548.2784 +png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
548.2785 +   png_bytep prev_row, int filter)
548.2786 +{
548.2787 +   png_debug(1, "in png_read_filter_row\n");
548.2788 +   png_debug2(2, "row = %lu, filter = %d\n", png_ptr->row_number, filter);
548.2789 +   switch (filter)
548.2790 +   {
548.2791 +      case PNG_FILTER_VALUE_NONE:
548.2792 +         break;
548.2793 +      case PNG_FILTER_VALUE_SUB:
548.2794 +      {
548.2795 +         png_uint_32 i;
548.2796 +         png_uint_32 istop = row_info->rowbytes;
548.2797 +         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
548.2798 +         png_bytep rp = row + bpp;
548.2799 +         png_bytep lp = row;
548.2800 +
548.2801 +         for (i = bpp; i < istop; i++)
548.2802 +         {
548.2803 +            *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
548.2804 +            rp++;
548.2805 +         }
548.2806 +         break;
548.2807 +      }
548.2808 +      case PNG_FILTER_VALUE_UP:
548.2809 +      {
548.2810 +         png_uint_32 i;
548.2811 +         png_uint_32 istop = row_info->rowbytes;
548.2812 +         png_bytep rp = row;
548.2813 +         png_bytep pp = prev_row;
548.2814 +
548.2815 +         for (i = 0; i < istop; i++)
548.2816 +         {
548.2817 +            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
548.2818 +            rp++;
548.2819 +         }
548.2820 +         break;
548.2821 +      }
548.2822 +      case PNG_FILTER_VALUE_AVG:
548.2823 +      {
548.2824 +         png_uint_32 i;
548.2825 +         png_bytep rp = row;
548.2826 +         png_bytep pp = prev_row;
548.2827 +         png_bytep lp = row;
548.2828 +         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
548.2829 +         png_uint_32 istop = row_info->rowbytes - bpp;
548.2830 +
548.2831 +         for (i = 0; i < bpp; i++)
548.2832 +         {
548.2833 +            *rp = (png_byte)(((int)(*rp) +
548.2834 +               ((int)(*pp++) / 2 )) & 0xff);
548.2835 +            rp++;
548.2836 +         }
548.2837 +
548.2838 +         for (i = 0; i < istop; i++)
548.2839 +         {
548.2840 +            *rp = (png_byte)(((int)(*rp) +
548.2841 +               (int)(*pp++ + *lp++) / 2 ) & 0xff);
548.2842 +            rp++;
548.2843 +         }
548.2844 +         break;
548.2845 +      }
548.2846 +      case PNG_FILTER_VALUE_PAETH:
548.2847 +      {
548.2848 +         png_uint_32 i;
548.2849 +         png_bytep rp = row;
548.2850 +         png_bytep pp = prev_row;
548.2851 +         png_bytep lp = row;
548.2852 +         png_bytep cp = prev_row;
548.2853 +         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
548.2854 +         png_uint_32 istop=row_info->rowbytes - bpp;
548.2855 +
548.2856 +         for (i = 0; i < bpp; i++)
548.2857 +         {
548.2858 +            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
548.2859 +            rp++;
548.2860 +         }
548.2861 +
548.2862 +         for (i = 0; i < istop; i++)   /* use leftover rp,pp */
548.2863 +         {
548.2864 +            int a, b, c, pa, pb, pc, p;
548.2865 +
548.2866 +            a = *lp++;
548.2867 +            b = *pp++;
548.2868 +            c = *cp++;
548.2869 +
548.2870 +            p = b - c;
548.2871 +            pc = a - c;
548.2872 +
548.2873 +#ifdef PNG_USE_ABS
548.2874 +            pa = abs(p);
548.2875 +            pb = abs(pc);
548.2876 +            pc = abs(p + pc);
548.2877 +#else
548.2878 +            pa = p < 0 ? -p : p;
548.2879 +            pb = pc < 0 ? -pc : pc;
548.2880 +            pc = (p + pc) < 0 ? -(p + pc) : p + pc;
548.2881 +#endif
548.2882 +
548.2883 +            /*
548.2884 +               if (pa <= pb && pa <= pc)
548.2885 +                  p = a;
548.2886 +               else if (pb <= pc)
548.2887 +                  p = b;
548.2888 +               else
548.2889 +                  p = c;
548.2890 +             */
548.2891 +
548.2892 +            p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
548.2893 +
548.2894 +            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
548.2895 +            rp++;
548.2896 +         }
548.2897 +         break;
548.2898 +      }
548.2899 +      default:
548.2900 +         png_warning(png_ptr, "Ignoring bad adaptive filter type");
548.2901 +         *row = 0;
548.2902 +         break;
548.2903 +   }
548.2904 +}
548.2905 +
548.2906 +void /* PRIVATE */
548.2907 +png_read_finish_row(png_structp png_ptr)
548.2908 +{
548.2909 +#ifdef PNG_USE_LOCAL_ARRAYS
548.2910 +#ifdef PNG_READ_INTERLACING_SUPPORTED
548.2911 +   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
548.2912 +
548.2913 +   /* start of interlace block */
548.2914 +   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
548.2915 +
548.2916 +   /* offset to next interlace block */
548.2917 +   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
548.2918 +
548.2919 +   /* start of interlace block in the y direction */
548.2920 +   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
548.2921 +
548.2922 +   /* offset to next interlace block in the y direction */
548.2923 +   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
548.2924 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
548.2925 +#endif
548.2926 +
548.2927 +   png_debug(1, "in png_read_finish_row\n");
548.2928 +   png_ptr->row_number++;
548.2929 +   if (png_ptr->row_number < png_ptr->num_rows)
548.2930 +      return;
548.2931 +
548.2932 +#ifdef PNG_READ_INTERLACING_SUPPORTED
548.2933 +   if (png_ptr->interlaced)
548.2934 +   {
548.2935 +      png_ptr->row_number = 0;
548.2936 +      png_memset_check(png_ptr, png_ptr->prev_row, 0,
548.2937 +         png_ptr->rowbytes + 1);
548.2938 +      do
548.2939 +      {
548.2940 +         png_ptr->pass++;
548.2941 +         if (png_ptr->pass >= 7)
548.2942 +            break;
548.2943 +         png_ptr->iwidth = (png_ptr->width +
548.2944 +            png_pass_inc[png_ptr->pass] - 1 -
548.2945 +            png_pass_start[png_ptr->pass]) /
548.2946 +            png_pass_inc[png_ptr->pass];
548.2947 +
548.2948 +         png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
548.2949 +            png_ptr->iwidth) + 1;
548.2950 +
548.2951 +         if (!(png_ptr->transformations & PNG_INTERLACE))
548.2952 +         {
548.2953 +            png_ptr->num_rows = (png_ptr->height +
548.2954 +               png_pass_yinc[png_ptr->pass] - 1 -
548.2955 +               png_pass_ystart[png_ptr->pass]) /
548.2956 +               png_pass_yinc[png_ptr->pass];
548.2957 +            if (!(png_ptr->num_rows))
548.2958 +               continue;
548.2959 +         }
548.2960 +         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
548.2961 +            break;
548.2962 +      } while (png_ptr->iwidth == 0);
548.2963 +
548.2964 +      if (png_ptr->pass < 7)
548.2965 +         return;
548.2966 +   }
548.2967 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
548.2968 +
548.2969 +   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
548.2970 +   {
548.2971 +#ifdef PNG_USE_LOCAL_ARRAYS
548.2972 +      PNG_CONST PNG_IDAT;
548.2973 +#endif
548.2974 +      char extra;
548.2975 +      int ret;
548.2976 +
548.2977 +      png_ptr->zstream.next_out = (Byte *)&extra;
548.2978 +      png_ptr->zstream.avail_out = (uInt)1;
548.2979 +      for (;;)
548.2980 +      {
548.2981 +         if (!(png_ptr->zstream.avail_in))
548.2982 +         {
548.2983 +            while (!png_ptr->idat_size)
548.2984 +            {
548.2985 +               png_byte chunk_length[4];
548.2986 +
548.2987 +               png_crc_finish(png_ptr, 0);
548.2988 +
548.2989 +               png_read_data(png_ptr, chunk_length, 4);
548.2990 +               png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
548.2991 +               png_reset_crc(png_ptr);
548.2992 +               png_crc_read(png_ptr, png_ptr->chunk_name, 4);
548.2993 +               if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
548.2994 +                  png_error(png_ptr, "Not enough image data");
548.2995 +
548.2996 +            }
548.2997 +            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
548.2998 +            png_ptr->zstream.next_in = png_ptr->zbuf;
548.2999 +            if (png_ptr->zbuf_size > png_ptr->idat_size)
548.3000 +               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
548.3001 +            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
548.3002 +            png_ptr->idat_size -= png_ptr->zstream.avail_in;
548.3003 +         }
548.3004 +         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
548.3005 +         if (ret == Z_STREAM_END)
548.3006 +         {
548.3007 +            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
548.3008 +               png_ptr->idat_size)
548.3009 +               png_warning(png_ptr, "Extra compressed data");
548.3010 +            png_ptr->mode |= PNG_AFTER_IDAT;
548.3011 +            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
548.3012 +            break;
548.3013 +         }
548.3014 +         if (ret != Z_OK)
548.3015 +            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
548.3016 +                      "Decompression Error");
548.3017 +
548.3018 +         if (!(png_ptr->zstream.avail_out))
548.3019 +         {
548.3020 +            png_warning(png_ptr, "Extra compressed data.");
548.3021 +            png_ptr->mode |= PNG_AFTER_IDAT;
548.3022 +            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
548.3023 +            break;
548.3024 +         }
548.3025 +
548.3026 +      }
548.3027 +      png_ptr->zstream.avail_out = 0;
548.3028 +   }
548.3029 +
548.3030 +   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
548.3031 +      png_warning(png_ptr, "Extra compression data");
548.3032 +
548.3033 +   inflateReset(&png_ptr->zstream);
548.3034 +
548.3035 +   png_ptr->mode |= PNG_AFTER_IDAT;
548.3036 +}
548.3037 +
548.3038 +void /* PRIVATE */
548.3039 +png_read_start_row(png_structp png_ptr)
548.3040 +{
548.3041 +#ifdef PNG_USE_LOCAL_ARRAYS
548.3042 +#ifdef PNG_READ_INTERLACING_SUPPORTED
548.3043 +   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
548.3044 +
548.3045 +   /* start of interlace block */
548.3046 +   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
548.3047 +
548.3048 +   /* offset to next interlace block */
548.3049 +   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
548.3050 +
548.3051 +   /* start of interlace block in the y direction */
548.3052 +   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
548.3053 +
548.3054 +   /* offset to next interlace block in the y direction */
548.3055 +   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
548.3056 +#endif
548.3057 +#endif
548.3058 +
548.3059 +   int max_pixel_depth;
548.3060 +   png_size_t row_bytes;
548.3061 +
548.3062 +   png_debug(1, "in png_read_start_row\n");
548.3063 +   png_ptr->zstream.avail_in = 0;
548.3064 +   png_init_read_transformations(png_ptr);
548.3065 +#ifdef PNG_READ_INTERLACING_SUPPORTED
548.3066 +   if (png_ptr->interlaced)
548.3067 +   {
548.3068 +      if (!(png_ptr->transformations & PNG_INTERLACE))
548.3069 +         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
548.3070 +            png_pass_ystart[0]) / png_pass_yinc[0];
548.3071 +      else
548.3072 +         png_ptr->num_rows = png_ptr->height;
548.3073 +
548.3074 +      png_ptr->iwidth = (png_ptr->width +
548.3075 +         png_pass_inc[png_ptr->pass] - 1 -
548.3076 +         png_pass_start[png_ptr->pass]) /
548.3077 +         png_pass_inc[png_ptr->pass];
548.3078 +
548.3079 +         png_ptr->irowbytes =
548.3080 +            PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1;
548.3081 +   }
548.3082 +   else
548.3083 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
548.3084 +   {
548.3085 +      png_ptr->num_rows = png_ptr->height;
548.3086 +      png_ptr->iwidth = png_ptr->width;
548.3087 +      png_ptr->irowbytes = png_ptr->rowbytes + 1;
548.3088 +   }
548.3089 +   max_pixel_depth = png_ptr->pixel_depth;
548.3090 +
548.3091 +#if defined(PNG_READ_PACK_SUPPORTED)
548.3092 +   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
548.3093 +      max_pixel_depth = 8;
548.3094 +#endif
548.3095 +
548.3096 +#if defined(PNG_READ_EXPAND_SUPPORTED)
548.3097 +   if (png_ptr->transformations & PNG_EXPAND)
548.3098 +   {
548.3099 +      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
548.3100 +      {
548.3101 +         if (png_ptr->num_trans)
548.3102 +            max_pixel_depth = 32;
548.3103 +         else
548.3104 +            max_pixel_depth = 24;
548.3105 +      }
548.3106 +      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
548.3107 +      {
548.3108 +         if (max_pixel_depth < 8)
548.3109 +            max_pixel_depth = 8;
548.3110 +         if (png_ptr->num_trans)
548.3111 +            max_pixel_depth *= 2;
548.3112 +      }
548.3113 +      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
548.3114 +      {
548.3115 +         if (png_ptr->num_trans)
548.3116 +         {
548.3117 +            max_pixel_depth *= 4;
548.3118 +            max_pixel_depth /= 3;
548.3119 +         }
548.3120 +      }
548.3121 +   }
548.3122 +#endif
548.3123 +
548.3124 +#if defined(PNG_READ_FILLER_SUPPORTED)
548.3125 +   if (png_ptr->transformations & (PNG_FILLER))
548.3126 +   {
548.3127 +      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
548.3128 +         max_pixel_depth = 32;
548.3129 +      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
548.3130 +      {
548.3131 +         if (max_pixel_depth <= 8)
548.3132 +            max_pixel_depth = 16;
548.3133 +         else
548.3134 +            max_pixel_depth = 32;
548.3135 +      }
548.3136 +      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
548.3137 +      {
548.3138 +         if (max_pixel_depth <= 32)
548.3139 +            max_pixel_depth = 32;
548.3140 +         else
548.3141 +            max_pixel_depth = 64;
548.3142 +      }
548.3143 +   }
548.3144 +#endif
548.3145 +
548.3146 +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
548.3147 +   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
548.3148 +   {
548.3149 +      if (
548.3150 +#if defined(PNG_READ_EXPAND_SUPPORTED)
548.3151 +        (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
548.3152 +#endif
548.3153 +#if defined(PNG_READ_FILLER_SUPPORTED)
548.3154 +        (png_ptr->transformations & (PNG_FILLER)) ||
548.3155 +#endif
548.3156 +        png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
548.3157 +      {
548.3158 +         if (max_pixel_depth <= 16)
548.3159 +            max_pixel_depth = 32;
548.3160 +         else
548.3161 +            max_pixel_depth = 64;
548.3162 +      }
548.3163 +      else
548.3164 +      {
548.3165 +         if (max_pixel_depth <= 8)
548.3166 +           {
548.3167 +             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
548.3168 +               max_pixel_depth = 32;
548.3169 +             else
548.3170 +               max_pixel_depth = 24;
548.3171 +           }
548.3172 +         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
548.3173 +            max_pixel_depth = 64;
548.3174 +         else
548.3175 +            max_pixel_depth = 48;
548.3176 +      }
548.3177 +   }
548.3178 +#endif
548.3179 +
548.3180 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
548.3181 +defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
548.3182 +   if (png_ptr->transformations & PNG_USER_TRANSFORM)
548.3183 +     {
548.3184 +       int user_pixel_depth = png_ptr->user_transform_depth*
548.3185 +         png_ptr->user_transform_channels;
548.3186 +       if (user_pixel_depth > max_pixel_depth)
548.3187 +         max_pixel_depth=user_pixel_depth;
548.3188 +     }
548.3189 +#endif
548.3190 +
548.3191 +   /* align the width on the next larger 8 pixels.  Mainly used
548.3192 +      for interlacing */
548.3193 +   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
548.3194 +   /* calculate the maximum bytes needed, adding a byte and a pixel
548.3195 +      for safety's sake */
548.3196 +   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
548.3197 +      1 + ((max_pixel_depth + 7) >> 3);
548.3198 +#ifdef PNG_MAX_MALLOC_64K
548.3199 +   if (row_bytes > (png_uint_32)65536L)
548.3200 +      png_error(png_ptr, "This image requires a row greater than 64KB");
548.3201 +#endif
548.3202 +
548.3203 +   if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
548.3204 +   {
548.3205 +     png_free(png_ptr, png_ptr->big_row_buf);
548.3206 +     png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
548.3207 +     png_ptr->row_buf = png_ptr->big_row_buf+32;
548.3208 +     png_ptr->old_big_row_buf_size = row_bytes+64;
548.3209 +   }
548.3210 +
548.3211 +#ifdef PNG_MAX_MALLOC_64K
548.3212 +   if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
548.3213 +      png_error(png_ptr, "This image requires a row greater than 64KB");
548.3214 +#endif
548.3215 +   if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
548.3216 +      png_error(png_ptr, "Row has too many bytes to allocate in memory.");
548.3217 +
548.3218 +   if (png_ptr->rowbytes+1 > png_ptr->old_prev_row_size)
548.3219 +   {
548.3220 +     png_free(png_ptr, png_ptr->prev_row);
548.3221 +     png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
548.3222 +        png_ptr->rowbytes + 1));
548.3223 +     png_ptr->old_prev_row_size = png_ptr->rowbytes+1;
548.3224 +   }
548.3225 +
548.3226 +   png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
548.3227 +
548.3228 +   png_debug1(3, "width = %lu,\n", png_ptr->width);
548.3229 +   png_debug1(3, "height = %lu,\n", png_ptr->height);
548.3230 +   png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
548.3231 +   png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
548.3232 +   png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
548.3233 +   png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
548.3234 +
548.3235 +   png_ptr->flags |= PNG_FLAG_ROW_INIT;
548.3236 +}
548.3237 +#endif /* PNG_READ_SUPPORTED */
   549.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   549.2 +++ b/libs/libpng/pngset.c	Sat Feb 01 19:58:19 2014 +0200
   549.3 @@ -0,0 +1,1293 @@
   549.4 +
   549.5 +/* pngset.c - storage of image information into info struct
   549.6 + *
   549.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   549.8 + * For conditions of distribution and use, see copyright notice in png.h
   549.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  549.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  549.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  549.12 + *
  549.13 + * The functions here are used during reads to store data from the file
  549.14 + * into the info struct, and during writes to store application data
  549.15 + * into the info struct for writing into the file.  This abstracts the
  549.16 + * info struct and allows us to change the structure in the future.
  549.17 + */
  549.18 +
  549.19 +#define PNG_INTERNAL
  549.20 +#include "png.h"
  549.21 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  549.22 +
  549.23 +#if defined(PNG_bKGD_SUPPORTED)
  549.24 +void PNGAPI
  549.25 +png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
  549.26 +{
  549.27 +   png_debug1(1, "in %s storage function\n", "bKGD");
  549.28 +   if (png_ptr == NULL || info_ptr == NULL)
  549.29 +      return;
  549.30 +
  549.31 +   png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
  549.32 +   info_ptr->valid |= PNG_INFO_bKGD;
  549.33 +}
  549.34 +#endif
  549.35 +
  549.36 +#if defined(PNG_cHRM_SUPPORTED)
  549.37 +#ifdef PNG_FLOATING_POINT_SUPPORTED
  549.38 +void PNGAPI
  549.39 +png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
  549.40 +   double white_x, double white_y, double red_x, double red_y,
  549.41 +   double green_x, double green_y, double blue_x, double blue_y)
  549.42 +{
  549.43 +   png_debug1(1, "in %s storage function\n", "cHRM");
  549.44 +   if (png_ptr == NULL || info_ptr == NULL)
  549.45 +      return;
  549.46 +   if (!(white_x || white_y || red_x || red_y || green_x || green_y ||
  549.47 +       blue_x || blue_y))
  549.48 +   {
  549.49 +      png_warning(png_ptr,
  549.50 +        "Ignoring attempt to set all-zero chromaticity values");
  549.51 +      return;
  549.52 +   }
  549.53 +   if (white_x < 0.0 || white_y < 0.0 ||
  549.54 +         red_x < 0.0 ||   red_y < 0.0 ||
  549.55 +       green_x < 0.0 || green_y < 0.0 ||
  549.56 +        blue_x < 0.0 ||  blue_y < 0.0)
  549.57 +   {
  549.58 +      png_warning(png_ptr,
  549.59 +        "Ignoring attempt to set negative chromaticity value");
  549.60 +      return;
  549.61 +   }
  549.62 +   if (white_x > 21474.83 || white_y > 21474.83 ||
  549.63 +         red_x > 21474.83 ||   red_y > 21474.83 ||
  549.64 +       green_x > 21474.83 || green_y > 21474.83 ||
  549.65 +        blue_x > 21474.83 ||  blue_y > 21474.83)
  549.66 +   {
  549.67 +      png_warning(png_ptr,
  549.68 +        "Ignoring attempt to set chromaticity value exceeding 21474.83");
  549.69 +      return;
  549.70 +   }
  549.71 +
  549.72 +   info_ptr->x_white = (float)white_x;
  549.73 +   info_ptr->y_white = (float)white_y;
  549.74 +   info_ptr->x_red   = (float)red_x;
  549.75 +   info_ptr->y_red   = (float)red_y;
  549.76 +   info_ptr->x_green = (float)green_x;
  549.77 +   info_ptr->y_green = (float)green_y;
  549.78 +   info_ptr->x_blue  = (float)blue_x;
  549.79 +   info_ptr->y_blue  = (float)blue_y;
  549.80 +#ifdef PNG_FIXED_POINT_SUPPORTED
  549.81 +   info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
  549.82 +   info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
  549.83 +   info_ptr->int_x_red   = (png_fixed_point)(  red_x*100000.+0.5);
  549.84 +   info_ptr->int_y_red   = (png_fixed_point)(  red_y*100000.+0.5);
  549.85 +   info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
  549.86 +   info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
  549.87 +   info_ptr->int_x_blue  = (png_fixed_point)( blue_x*100000.+0.5);
  549.88 +   info_ptr->int_y_blue  = (png_fixed_point)( blue_y*100000.+0.5);
  549.89 +#endif
  549.90 +   info_ptr->valid |= PNG_INFO_cHRM;
  549.91 +}
  549.92 +#endif
  549.93 +#ifdef PNG_FIXED_POINT_SUPPORTED
  549.94 +void PNGAPI
  549.95 +png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
  549.96 +   png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
  549.97 +   png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
  549.98 +   png_fixed_point blue_x, png_fixed_point blue_y)
  549.99 +{
 549.100 +   png_debug1(1, "in %s storage function\n", "cHRM");
 549.101 +   if (png_ptr == NULL || info_ptr == NULL)
 549.102 +      return;
 549.103 +
 549.104 +   if (!(white_x || white_y || red_x || red_y || green_x || green_y ||
 549.105 +       blue_x || blue_y))
 549.106 +   {
 549.107 +      png_warning(png_ptr,
 549.108 +        "Ignoring attempt to set all-zero chromaticity values");
 549.109 +      return;
 549.110 +   }
 549.111 +   if (white_x < 0 || white_y < 0 ||
 549.112 +         red_x < 0 ||   red_y < 0 ||
 549.113 +       green_x < 0 || green_y < 0 ||
 549.114 +        blue_x < 0 ||  blue_y < 0)
 549.115 +   {
 549.116 +      png_warning(png_ptr,
 549.117 +        "Ignoring attempt to set negative chromaticity value");
 549.118 +      return;
 549.119 +   }
 549.120 +   if (white_x > (png_fixed_point) PNG_UINT_31_MAX ||
 549.121 +       white_y > (png_fixed_point) PNG_UINT_31_MAX ||
 549.122 +         red_x > (png_fixed_point) PNG_UINT_31_MAX ||
 549.123 +         red_y > (png_fixed_point) PNG_UINT_31_MAX ||
 549.124 +       green_x > (png_fixed_point) PNG_UINT_31_MAX ||
 549.125 +       green_y > (png_fixed_point) PNG_UINT_31_MAX ||
 549.126 +        blue_x > (png_fixed_point) PNG_UINT_31_MAX ||
 549.127 +        blue_y > (png_fixed_point) PNG_UINT_31_MAX )
 549.128 +   {
 549.129 +      png_warning(png_ptr,
 549.130 +        "Ignoring attempt to set chromaticity value exceeding 21474.83");
 549.131 +      return;
 549.132 +   }
 549.133 +   info_ptr->int_x_white = white_x;
 549.134 +   info_ptr->int_y_white = white_y;
 549.135 +   info_ptr->int_x_red   = red_x;
 549.136 +   info_ptr->int_y_red   = red_y;
 549.137 +   info_ptr->int_x_green = green_x;
 549.138 +   info_ptr->int_y_green = green_y;
 549.139 +   info_ptr->int_x_blue  = blue_x;
 549.140 +   info_ptr->int_y_blue  = blue_y;
 549.141 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 549.142 +   info_ptr->x_white = (float)(white_x/100000.);
 549.143 +   info_ptr->y_white = (float)(white_y/100000.);
 549.144 +   info_ptr->x_red   = (float)(  red_x/100000.);
 549.145 +   info_ptr->y_red   = (float)(  red_y/100000.);
 549.146 +   info_ptr->x_green = (float)(green_x/100000.);
 549.147 +   info_ptr->y_green = (float)(green_y/100000.);
 549.148 +   info_ptr->x_blue  = (float)( blue_x/100000.);
 549.149 +   info_ptr->y_blue  = (float)( blue_y/100000.);
 549.150 +#endif
 549.151 +   info_ptr->valid |= PNG_INFO_cHRM;
 549.152 +}
 549.153 +#endif
 549.154 +#endif
 549.155 +
 549.156 +#if defined(PNG_gAMA_SUPPORTED)
 549.157 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 549.158 +void PNGAPI
 549.159 +png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
 549.160 +{
 549.161 +   double gamma;
 549.162 +   png_debug1(1, "in %s storage function\n", "gAMA");
 549.163 +   if (png_ptr == NULL || info_ptr == NULL)
 549.164 +      return;
 549.165 +
 549.166 +   /* Check for overflow */
 549.167 +   if (file_gamma > 21474.83)
 549.168 +   {
 549.169 +      png_warning(png_ptr, "Limiting gamma to 21474.83");
 549.170 +      gamma=21474.83;
 549.171 +   }
 549.172 +   else
 549.173 +      gamma = file_gamma;
 549.174 +   info_ptr->gamma = (float)gamma;
 549.175 +#ifdef PNG_FIXED_POINT_SUPPORTED
 549.176 +   info_ptr->int_gamma = (int)(gamma*100000.+.5);
 549.177 +#endif
 549.178 +   info_ptr->valid |= PNG_INFO_gAMA;
 549.179 +   if (gamma == 0.0)
 549.180 +      png_warning(png_ptr, "Setting gamma=0");
 549.181 +}
 549.182 +#endif
 549.183 +void PNGAPI
 549.184 +png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
 549.185 +   int_gamma)
 549.186 +{
 549.187 +   png_fixed_point gamma;
 549.188 +
 549.189 +   png_debug1(1, "in %s storage function\n", "gAMA");
 549.190 +   if (png_ptr == NULL || info_ptr == NULL)
 549.191 +      return;
 549.192 +
 549.193 +   if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX)
 549.194 +   {
 549.195 +     png_warning(png_ptr, "Limiting gamma to 21474.83");
 549.196 +     gamma=PNG_UINT_31_MAX;
 549.197 +   }
 549.198 +   else
 549.199 +   {
 549.200 +     if (int_gamma < 0)
 549.201 +     {
 549.202 +       png_warning(png_ptr, "Setting negative gamma to zero");
 549.203 +       gamma = 0;
 549.204 +     }
 549.205 +     else
 549.206 +       gamma = int_gamma;
 549.207 +   }
 549.208 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 549.209 +   info_ptr->gamma = (float)(gamma/100000.);
 549.210 +#endif
 549.211 +#ifdef PNG_FIXED_POINT_SUPPORTED
 549.212 +   info_ptr->int_gamma = gamma;
 549.213 +#endif
 549.214 +   info_ptr->valid |= PNG_INFO_gAMA;
 549.215 +   if (gamma == 0)
 549.216 +      png_warning(png_ptr, "Setting gamma=0");
 549.217 +}
 549.218 +#endif
 549.219 +
 549.220 +#if defined(PNG_hIST_SUPPORTED)
 549.221 +void PNGAPI
 549.222 +png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
 549.223 +{
 549.224 +   int i;
 549.225 +
 549.226 +   png_debug1(1, "in %s storage function\n", "hIST");
 549.227 +   if (png_ptr == NULL || info_ptr == NULL)
 549.228 +      return;
 549.229 +   if (info_ptr->num_palette == 0 || info_ptr->num_palette
 549.230 +       > PNG_MAX_PALETTE_LENGTH)
 549.231 +   {
 549.232 +       png_warning(png_ptr,
 549.233 +          "Invalid palette size, hIST allocation skipped.");
 549.234 +       return;
 549.235 +   }
 549.236 +
 549.237 +#ifdef PNG_FREE_ME_SUPPORTED
 549.238 +   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
 549.239 +#endif
 549.240 +   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in version
 549.241 +      1.2.1 */
 549.242 +   png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
 549.243 +      (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)));
 549.244 +   if (png_ptr->hist == NULL)
 549.245 +     {
 549.246 +       png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
 549.247 +       return;
 549.248 +     }
 549.249 +
 549.250 +   for (i = 0; i < info_ptr->num_palette; i++)
 549.251 +       png_ptr->hist[i] = hist[i];
 549.252 +   info_ptr->hist = png_ptr->hist;
 549.253 +   info_ptr->valid |= PNG_INFO_hIST;
 549.254 +
 549.255 +#ifdef PNG_FREE_ME_SUPPORTED
 549.256 +   info_ptr->free_me |= PNG_FREE_HIST;
 549.257 +#else
 549.258 +   png_ptr->flags |= PNG_FLAG_FREE_HIST;
 549.259 +#endif
 549.260 +}
 549.261 +#endif
 549.262 +
 549.263 +void PNGAPI
 549.264 +png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
 549.265 +   png_uint_32 width, png_uint_32 height, int bit_depth,
 549.266 +   int color_type, int interlace_type, int compression_type,
 549.267 +   int filter_type)
 549.268 +{
 549.269 +   png_debug1(1, "in %s storage function\n", "IHDR");
 549.270 +   if (png_ptr == NULL || info_ptr == NULL)
 549.271 +      return;
 549.272 +
 549.273 +   /* check for width and height valid values */
 549.274 +   if (width == 0 || height == 0)
 549.275 +      png_error(png_ptr, "Image width or height is zero in IHDR");
 549.276 +#ifdef PNG_SET_USER_LIMITS_SUPPORTED
 549.277 +   if (width > png_ptr->user_width_max || height > png_ptr->user_height_max)
 549.278 +      png_error(png_ptr, "image size exceeds user limits in IHDR");
 549.279 +#else
 549.280 +   if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX)
 549.281 +      png_error(png_ptr, "image size exceeds user limits in IHDR");
 549.282 +#endif
 549.283 +   if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX)
 549.284 +      png_error(png_ptr, "Invalid image size in IHDR");
 549.285 +   if ( width > (PNG_UINT_32_MAX
 549.286 +                 >> 3)      /* 8-byte RGBA pixels */
 549.287 +                 - 64       /* bigrowbuf hack */
 549.288 +                 - 1        /* filter byte */
 549.289 +                 - 7*8      /* rounding of width to multiple of 8 pixels */
 549.290 +                 - 8)       /* extra max_pixel_depth pad */
 549.291 +      png_warning(png_ptr, "Width is too large for libpng to process pixels");
 549.292 +
 549.293 +   /* check other values */
 549.294 +   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
 549.295 +      bit_depth != 8 && bit_depth != 16)
 549.296 +      png_error(png_ptr, "Invalid bit depth in IHDR");
 549.297 +
 549.298 +   if (color_type < 0 || color_type == 1 ||
 549.299 +      color_type == 5 || color_type > 6)
 549.300 +      png_error(png_ptr, "Invalid color type in IHDR");
 549.301 +
 549.302 +   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
 549.303 +       ((color_type == PNG_COLOR_TYPE_RGB ||
 549.304 +         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
 549.305 +         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
 549.306 +      png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
 549.307 +
 549.308 +   if (interlace_type >= PNG_INTERLACE_LAST)
 549.309 +      png_error(png_ptr, "Unknown interlace method in IHDR");
 549.310 +
 549.311 +   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
 549.312 +      png_error(png_ptr, "Unknown compression method in IHDR");
 549.313 +
 549.314 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
 549.315 +   /* Accept filter_method 64 (intrapixel differencing) only if
 549.316 +    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
 549.317 +    * 2. Libpng did not read a PNG signature (this filter_method is only
 549.318 +    *    used in PNG datastreams that are embedded in MNG datastreams) and
 549.319 +    * 3. The application called png_permit_mng_features with a mask that
 549.320 +    *    included PNG_FLAG_MNG_FILTER_64 and
 549.321 +    * 4. The filter_method is 64 and
 549.322 +    * 5. The color_type is RGB or RGBA
 549.323 +    */
 549.324 +   if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted)
 549.325 +      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
 549.326 +   if (filter_type != PNG_FILTER_TYPE_BASE)
 549.327 +   {
 549.328 +     if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
 549.329 +        (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
 549.330 +        ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
 549.331 +        (color_type == PNG_COLOR_TYPE_RGB ||
 549.332 +         color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
 549.333 +        png_error(png_ptr, "Unknown filter method in IHDR");
 549.334 +     if (png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)
 549.335 +        png_warning(png_ptr, "Invalid filter method in IHDR");
 549.336 +   }
 549.337 +#else
 549.338 +   if (filter_type != PNG_FILTER_TYPE_BASE)
 549.339 +      png_error(png_ptr, "Unknown filter method in IHDR");
 549.340 +#endif
 549.341 +
 549.342 +   info_ptr->width = width;
 549.343 +   info_ptr->height = height;
 549.344 +   info_ptr->bit_depth = (png_byte)bit_depth;
 549.345 +   info_ptr->color_type =(png_byte) color_type;
 549.346 +   info_ptr->compression_type = (png_byte)compression_type;
 549.347 +   info_ptr->filter_type = (png_byte)filter_type;
 549.348 +   info_ptr->interlace_type = (png_byte)interlace_type;
 549.349 +   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 549.350 +      info_ptr->channels = 1;
 549.351 +   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
 549.352 +      info_ptr->channels = 3;
 549.353 +   else
 549.354 +      info_ptr->channels = 1;
 549.355 +   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
 549.356 +      info_ptr->channels++;
 549.357 +   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
 549.358 +
 549.359 +   /* check for potential overflow */
 549.360 +   if (width > (PNG_UINT_32_MAX
 549.361 +                 >> 3)      /* 8-byte RGBA pixels */
 549.362 +                 - 64       /* bigrowbuf hack */
 549.363 +                 - 1        /* filter byte */
 549.364 +                 - 7*8      /* rounding of width to multiple of 8 pixels */
 549.365 +                 - 8)       /* extra max_pixel_depth pad */
 549.366 +      info_ptr->rowbytes = (png_size_t)0;
 549.367 +   else
 549.368 +      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
 549.369 +}
 549.370 +
 549.371 +#if defined(PNG_oFFs_SUPPORTED)
 549.372 +void PNGAPI
 549.373 +png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
 549.374 +   png_int_32 offset_x, png_int_32 offset_y, int unit_type)
 549.375 +{
 549.376 +   png_debug1(1, "in %s storage function\n", "oFFs");
 549.377 +   if (png_ptr == NULL || info_ptr == NULL)
 549.378 +      return;
 549.379 +
 549.380 +   info_ptr->x_offset = offset_x;
 549.381 +   info_ptr->y_offset = offset_y;
 549.382 +   info_ptr->offset_unit_type = (png_byte)unit_type;
 549.383 +   info_ptr->valid |= PNG_INFO_oFFs;
 549.384 +}
 549.385 +#endif
 549.386 +
 549.387 +#if defined(PNG_pCAL_SUPPORTED)
 549.388 +void PNGAPI
 549.389 +png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
 549.390 +   png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
 549.391 +   png_charp units, png_charpp params)
 549.392 +{
 549.393 +   png_uint_32 length;
 549.394 +   int i;
 549.395 +
 549.396 +   png_debug1(1, "in %s storage function\n", "pCAL");
 549.397 +   if (png_ptr == NULL || info_ptr == NULL)
 549.398 +      return;
 549.399 +
 549.400 +   length = png_strlen(purpose) + 1;
 549.401 +   png_debug1(3, "allocating purpose for info (%lu bytes)\n",
 549.402 +     (unsigned long)length);
 549.403 +   info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
 549.404 +   if (info_ptr->pcal_purpose == NULL)
 549.405 +   {
 549.406 +       png_warning(png_ptr, "Insufficient memory for pCAL purpose.");
 549.407 +      return;
 549.408 +   }
 549.409 +   png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
 549.410 +
 549.411 +   png_debug(3, "storing X0, X1, type, and nparams in info\n");
 549.412 +   info_ptr->pcal_X0 = X0;
 549.413 +   info_ptr->pcal_X1 = X1;
 549.414 +   info_ptr->pcal_type = (png_byte)type;
 549.415 +   info_ptr->pcal_nparams = (png_byte)nparams;
 549.416 +
 549.417 +   length = png_strlen(units) + 1;
 549.418 +   png_debug1(3, "allocating units for info (%lu bytes)\n",
 549.419 +     (unsigned long)length);
 549.420 +   info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
 549.421 +   if (info_ptr->pcal_units == NULL)
 549.422 +   {
 549.423 +       png_warning(png_ptr, "Insufficient memory for pCAL units.");
 549.424 +      return;
 549.425 +   }
 549.426 +   png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
 549.427 +
 549.428 +   info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
 549.429 +      (png_uint_32)((nparams + 1) * png_sizeof(png_charp)));
 549.430 +   if (info_ptr->pcal_params == NULL)
 549.431 +   {
 549.432 +       png_warning(png_ptr, "Insufficient memory for pCAL params.");
 549.433 +      return;
 549.434 +   }
 549.435 +
 549.436 +   info_ptr->pcal_params[nparams] = NULL;
 549.437 +
 549.438 +   for (i = 0; i < nparams; i++)
 549.439 +   {
 549.440 +      length = png_strlen(params[i]) + 1;
 549.441 +      png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i,
 549.442 +        (unsigned long)length);
 549.443 +      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
 549.444 +      if (info_ptr->pcal_params[i] == NULL)
 549.445 +      {
 549.446 +          png_warning(png_ptr, "Insufficient memory for pCAL parameter.");
 549.447 +          return;
 549.448 +      }
 549.449 +      png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
 549.450 +   }
 549.451 +
 549.452 +   info_ptr->valid |= PNG_INFO_pCAL;
 549.453 +#ifdef PNG_FREE_ME_SUPPORTED
 549.454 +   info_ptr->free_me |= PNG_FREE_PCAL;
 549.455 +#endif
 549.456 +}
 549.457 +#endif
 549.458 +
 549.459 +#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
 549.460 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 549.461 +void PNGAPI
 549.462 +png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
 549.463 +             int unit, double width, double height)
 549.464 +{
 549.465 +   png_debug1(1, "in %s storage function\n", "sCAL");
 549.466 +   if (png_ptr == NULL || info_ptr == NULL)
 549.467 +      return;
 549.468 +
 549.469 +   info_ptr->scal_unit = (png_byte)unit;
 549.470 +   info_ptr->scal_pixel_width = width;
 549.471 +   info_ptr->scal_pixel_height = height;
 549.472 +
 549.473 +   info_ptr->valid |= PNG_INFO_sCAL;
 549.474 +}
 549.475 +#else
 549.476 +#ifdef PNG_FIXED_POINT_SUPPORTED
 549.477 +void PNGAPI
 549.478 +png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
 549.479 +             int unit, png_charp swidth, png_charp sheight)
 549.480 +{
 549.481 +   png_uint_32 length;
 549.482 +
 549.483 +   png_debug1(1, "in %s storage function\n", "sCAL");
 549.484 +   if (png_ptr == NULL || info_ptr == NULL)
 549.485 +      return;
 549.486 +
 549.487 +   info_ptr->scal_unit = (png_byte)unit;
 549.488 +
 549.489 +   length = png_strlen(swidth) + 1;
 549.490 +   png_debug1(3, "allocating unit for info (%u bytes)\n",
 549.491 +      (unsigned int)length);
 549.492 +   info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
 549.493 +   if (info_ptr->scal_s_width == NULL)
 549.494 +   {
 549.495 +      png_warning(png_ptr,
 549.496 +       "Memory allocation failed while processing sCAL.");
 549.497 +      return;
 549.498 +   }
 549.499 +   png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
 549.500 +
 549.501 +   length = png_strlen(sheight) + 1;
 549.502 +   png_debug1(3, "allocating unit for info (%u bytes)\n",
 549.503 +      (unsigned int)length);
 549.504 +   info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
 549.505 +   if (info_ptr->scal_s_height == NULL)
 549.506 +   {
 549.507 +      png_free (png_ptr, info_ptr->scal_s_width);
 549.508 +      info_ptr->scal_s_width = NULL;
 549.509 +      png_warning(png_ptr,
 549.510 +       "Memory allocation failed while processing sCAL.");
 549.511 +      return;
 549.512 +   }
 549.513 +   png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
 549.514 +   info_ptr->valid |= PNG_INFO_sCAL;
 549.515 +#ifdef PNG_FREE_ME_SUPPORTED
 549.516 +   info_ptr->free_me |= PNG_FREE_SCAL;
 549.517 +#endif
 549.518 +}
 549.519 +#endif
 549.520 +#endif
 549.521 +#endif
 549.522 +
 549.523 +#if defined(PNG_pHYs_SUPPORTED)
 549.524 +void PNGAPI
 549.525 +png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
 549.526 +   png_uint_32 res_x, png_uint_32 res_y, int unit_type)
 549.527 +{
 549.528 +   png_debug1(1, "in %s storage function\n", "pHYs");
 549.529 +   if (png_ptr == NULL || info_ptr == NULL)
 549.530 +      return;
 549.531 +
 549.532 +   info_ptr->x_pixels_per_unit = res_x;
 549.533 +   info_ptr->y_pixels_per_unit = res_y;
 549.534 +   info_ptr->phys_unit_type = (png_byte)unit_type;
 549.535 +   info_ptr->valid |= PNG_INFO_pHYs;
 549.536 +}
 549.537 +#endif
 549.538 +
 549.539 +void PNGAPI
 549.540 +png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
 549.541 +   png_colorp palette, int num_palette)
 549.542 +{
 549.543 +
 549.544 +   png_debug1(1, "in %s storage function\n", "PLTE");
 549.545 +   if (png_ptr == NULL || info_ptr == NULL)
 549.546 +      return;
 549.547 +
 549.548 +   if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
 549.549 +     {
 549.550 +       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 549.551 +         png_error(png_ptr, "Invalid palette length");
 549.552 +       else
 549.553 +       {
 549.554 +         png_warning(png_ptr, "Invalid palette length");
 549.555 +         return;
 549.556 +       }
 549.557 +     }
 549.558 +
 549.559 +   /*
 549.560 +    * It may not actually be necessary to set png_ptr->palette here;
 549.561 +    * we do it for backward compatibility with the way the png_handle_tRNS
 549.562 +    * function used to do the allocation.
 549.563 +    */
 549.564 +#ifdef PNG_FREE_ME_SUPPORTED
 549.565 +   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
 549.566 +#endif
 549.567 +
 549.568 +   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
 549.569 +      of num_palette entries,
 549.570 +      in case of an invalid PNG file that has too-large sample values. */
 549.571 +   png_ptr->palette = (png_colorp)png_malloc(png_ptr,
 549.572 +      PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
 549.573 +   png_memset(png_ptr->palette, 0, PNG_MAX_PALETTE_LENGTH *
 549.574 +      png_sizeof(png_color));
 549.575 +   png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
 549.576 +   info_ptr->palette = png_ptr->palette;
 549.577 +   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
 549.578 +
 549.579 +#ifdef PNG_FREE_ME_SUPPORTED
 549.580 +   info_ptr->free_me |= PNG_FREE_PLTE;
 549.581 +#else
 549.582 +   png_ptr->flags |= PNG_FLAG_FREE_PLTE;
 549.583 +#endif
 549.584 +
 549.585 +   info_ptr->valid |= PNG_INFO_PLTE;
 549.586 +}
 549.587 +
 549.588 +#if defined(PNG_sBIT_SUPPORTED)
 549.589 +void PNGAPI
 549.590 +png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
 549.591 +   png_color_8p sig_bit)
 549.592 +{
 549.593 +   png_debug1(1, "in %s storage function\n", "sBIT");
 549.594 +   if (png_ptr == NULL || info_ptr == NULL)
 549.595 +      return;
 549.596 +
 549.597 +   png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
 549.598 +   info_ptr->valid |= PNG_INFO_sBIT;
 549.599 +}
 549.600 +#endif
 549.601 +
 549.602 +#if defined(PNG_sRGB_SUPPORTED)
 549.603 +void PNGAPI
 549.604 +png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
 549.605 +{
 549.606 +   png_debug1(1, "in %s storage function\n", "sRGB");
 549.607 +   if (png_ptr == NULL || info_ptr == NULL)
 549.608 +      return;
 549.609 +
 549.610 +   info_ptr->srgb_intent = (png_byte)intent;
 549.611 +   info_ptr->valid |= PNG_INFO_sRGB;
 549.612 +}
 549.613 +
 549.614 +void PNGAPI
 549.615 +png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
 549.616 +   int intent)
 549.617 +{
 549.618 +#if defined(PNG_gAMA_SUPPORTED)
 549.619 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 549.620 +   float file_gamma;
 549.621 +#endif
 549.622 +#ifdef PNG_FIXED_POINT_SUPPORTED
 549.623 +   png_fixed_point int_file_gamma;
 549.624 +#endif
 549.625 +#endif
 549.626 +#if defined(PNG_cHRM_SUPPORTED)
 549.627 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 549.628 +   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
 549.629 +#endif
 549.630 +#ifdef PNG_FIXED_POINT_SUPPORTED
 549.631 +   png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
 549.632 +      int_green_y, int_blue_x, int_blue_y;
 549.633 +#endif
 549.634 +#endif
 549.635 +   png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
 549.636 +   if (png_ptr == NULL || info_ptr == NULL)
 549.637 +      return;
 549.638 +
 549.639 +   png_set_sRGB(png_ptr, info_ptr, intent);
 549.640 +
 549.641 +#if defined(PNG_gAMA_SUPPORTED)
 549.642 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 549.643 +   file_gamma = (float).45455;
 549.644 +   png_set_gAMA(png_ptr, info_ptr, file_gamma);
 549.645 +#endif
 549.646 +#ifdef PNG_FIXED_POINT_SUPPORTED
 549.647 +   int_file_gamma = 45455L;
 549.648 +   png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
 549.649 +#endif
 549.650 +#endif
 549.651 +
 549.652 +#if defined(PNG_cHRM_SUPPORTED)
 549.653 +#ifdef PNG_FIXED_POINT_SUPPORTED
 549.654 +   int_white_x = 31270L;
 549.655 +   int_white_y = 32900L;
 549.656 +   int_red_x   = 64000L;
 549.657 +   int_red_y   = 33000L;
 549.658 +   int_green_x = 30000L;
 549.659 +   int_green_y = 60000L;
 549.660 +   int_blue_x  = 15000L;
 549.661 +   int_blue_y  =  6000L;
 549.662 +
 549.663 +   png_set_cHRM_fixed(png_ptr, info_ptr,
 549.664 +      int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y,
 549.665 +      int_blue_x, int_blue_y);
 549.666 +#endif
 549.667 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 549.668 +   white_x = (float).3127;
 549.669 +   white_y = (float).3290;
 549.670 +   red_x   = (float).64;
 549.671 +   red_y   = (float).33;
 549.672 +   green_x = (float).30;
 549.673 +   green_y = (float).60;
 549.674 +   blue_x  = (float).15;
 549.675 +   blue_y  = (float).06;
 549.676 +
 549.677 +   png_set_cHRM(png_ptr, info_ptr,
 549.678 +      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
 549.679 +#endif
 549.680 +#endif
 549.681 +}
 549.682 +#endif
 549.683 +
 549.684 +
 549.685 +#if defined(PNG_iCCP_SUPPORTED)
 549.686 +void PNGAPI
 549.687 +png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
 549.688 +             png_charp name, int compression_type,
 549.689 +             png_charp profile, png_uint_32 proflen)
 549.690 +{
 549.691 +   png_charp new_iccp_name;
 549.692 +   png_charp new_iccp_profile;
 549.693 +   png_uint_32 length;
 549.694 +
 549.695 +   png_debug1(1, "in %s storage function\n", "iCCP");
 549.696 +   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
 549.697 +      return;
 549.698 +
 549.699 +   length = png_strlen(name)+1;
 549.700 +   new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
 549.701 +   if (new_iccp_name == NULL)
 549.702 +   {
 549.703 +      png_warning(png_ptr, "Insufficient memory to process iCCP chunk.");
 549.704 +      return;
 549.705 +   }
 549.706 +   png_memcpy(new_iccp_name, name, length);
 549.707 +   new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
 549.708 +   if (new_iccp_profile == NULL)
 549.709 +   {
 549.710 +      png_free (png_ptr, new_iccp_name);
 549.711 +      png_warning(png_ptr,
 549.712 +      "Insufficient memory to process iCCP profile.");
 549.713 +      return;
 549.714 +   }
 549.715 +   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
 549.716 +
 549.717 +   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
 549.718 +
 549.719 +   info_ptr->iccp_proflen = proflen;
 549.720 +   info_ptr->iccp_name = new_iccp_name;
 549.721 +   info_ptr->iccp_profile = new_iccp_profile;
 549.722 +   /* Compression is always zero but is here so the API and info structure
 549.723 +    * does not have to change if we introduce multiple compression types */
 549.724 +   info_ptr->iccp_compression = (png_byte)compression_type;
 549.725 +#ifdef PNG_FREE_ME_SUPPORTED
 549.726 +   info_ptr->free_me |= PNG_FREE_ICCP;
 549.727 +#endif
 549.728 +   info_ptr->valid |= PNG_INFO_iCCP;
 549.729 +}
 549.730 +#endif
 549.731 +
 549.732 +#if defined(PNG_TEXT_SUPPORTED)
 549.733 +void PNGAPI
 549.734 +png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
 549.735 +   int num_text)
 549.736 +{
 549.737 +   int ret;
 549.738 +   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
 549.739 +   if (ret)
 549.740 +     png_error(png_ptr, "Insufficient memory to store text");
 549.741 +}
 549.742 +
 549.743 +int /* PRIVATE */
 549.744 +png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
 549.745 +   int num_text)
 549.746 +{
 549.747 +   int i;
 549.748 +
 549.749 +   png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
 549.750 +      "text" : (png_const_charp)png_ptr->chunk_name));
 549.751 +
 549.752 +   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
 549.753 +      return(0);
 549.754 +
 549.755 +   /* Make sure we have enough space in the "text" array in info_struct
 549.756 +    * to hold all of the incoming text_ptr objects.
 549.757 +    */
 549.758 +   if (info_ptr->num_text + num_text > info_ptr->max_text)
 549.759 +   {
 549.760 +      if (info_ptr->text != NULL)
 549.761 +      {
 549.762 +         png_textp old_text;
 549.763 +         int old_max;
 549.764 +
 549.765 +         old_max = info_ptr->max_text;
 549.766 +         info_ptr->max_text = info_ptr->num_text + num_text + 8;
 549.767 +         old_text = info_ptr->text;
 549.768 +         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
 549.769 +            (png_uint_32)(info_ptr->max_text * png_sizeof(png_text)));
 549.770 +         if (info_ptr->text == NULL)
 549.771 +           {
 549.772 +             png_free(png_ptr, old_text);
 549.773 +             return(1);
 549.774 +           }
 549.775 +         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
 549.776 +            png_sizeof(png_text)));
 549.777 +         png_free(png_ptr, old_text);
 549.778 +      }
 549.779 +      else
 549.780 +      {
 549.781 +         info_ptr->max_text = num_text + 8;
 549.782 +         info_ptr->num_text = 0;
 549.783 +         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
 549.784 +            (png_uint_32)(info_ptr->max_text * png_sizeof(png_text)));
 549.785 +         if (info_ptr->text == NULL)
 549.786 +           return(1);
 549.787 +#ifdef PNG_FREE_ME_SUPPORTED
 549.788 +         info_ptr->free_me |= PNG_FREE_TEXT;
 549.789 +#endif
 549.790 +      }
 549.791 +      png_debug1(3, "allocated %d entries for info_ptr->text\n",
 549.792 +         info_ptr->max_text);
 549.793 +   }
 549.794 +   for (i = 0; i < num_text; i++)
 549.795 +   {
 549.796 +      png_size_t text_length, key_len;
 549.797 +      png_size_t lang_len, lang_key_len;
 549.798 +      png_textp textp = &(info_ptr->text[info_ptr->num_text]);
 549.799 +
 549.800 +      if (text_ptr[i].key == NULL)
 549.801 +          continue;
 549.802 +
 549.803 +      key_len = png_strlen(text_ptr[i].key);
 549.804 +
 549.805 +      if (text_ptr[i].compression <= 0)
 549.806 +      {
 549.807 +        lang_len = 0;
 549.808 +        lang_key_len = 0;
 549.809 +      }
 549.810 +      else
 549.811 +#ifdef PNG_iTXt_SUPPORTED
 549.812 +      {
 549.813 +        /* set iTXt data */
 549.814 +        if (text_ptr[i].lang != NULL)
 549.815 +          lang_len = png_strlen(text_ptr[i].lang);
 549.816 +        else
 549.817 +          lang_len = 0;
 549.818 +        if (text_ptr[i].lang_key != NULL)
 549.819 +          lang_key_len = png_strlen(text_ptr[i].lang_key);
 549.820 +        else
 549.821 +          lang_key_len = 0;
 549.822 +      }
 549.823 +#else
 549.824 +      {
 549.825 +        png_warning(png_ptr, "iTXt chunk not supported.");
 549.826 +        continue;
 549.827 +      }
 549.828 +#endif
 549.829 +
 549.830 +      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
 549.831 +      {
 549.832 +         text_length = 0;
 549.833 +#ifdef PNG_iTXt_SUPPORTED
 549.834 +         if (text_ptr[i].compression > 0)
 549.835 +            textp->compression = PNG_ITXT_COMPRESSION_NONE;
 549.836 +         else
 549.837 +#endif
 549.838 +            textp->compression = PNG_TEXT_COMPRESSION_NONE;
 549.839 +      }
 549.840 +      else
 549.841 +      {
 549.842 +         text_length = png_strlen(text_ptr[i].text);
 549.843 +         textp->compression = text_ptr[i].compression;
 549.844 +      }
 549.845 +
 549.846 +      textp->key = (png_charp)png_malloc_warn(png_ptr,
 549.847 +         (png_uint_32)
 549.848 +         (key_len + text_length + lang_len + lang_key_len + 4));
 549.849 +      if (textp->key == NULL)
 549.850 +        return(1);
 549.851 +      png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n",
 549.852 +         (png_uint_32)
 549.853 +         (key_len + lang_len + lang_key_len + text_length + 4),
 549.854 +         (int)textp->key);
 549.855 +
 549.856 +      png_memcpy(textp->key, text_ptr[i].key,
 549.857 +         (png_size_t)(key_len));
 549.858 +      *(textp->key + key_len) = '\0';
 549.859 +#ifdef PNG_iTXt_SUPPORTED
 549.860 +      if (text_ptr[i].compression > 0)
 549.861 +      {
 549.862 +         textp->lang = textp->key + key_len + 1;
 549.863 +         png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
 549.864 +         *(textp->lang + lang_len) = '\0';
 549.865 +         textp->lang_key = textp->lang + lang_len + 1;
 549.866 +         png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
 549.867 +         *(textp->lang_key + lang_key_len) = '\0';
 549.868 +         textp->text = textp->lang_key + lang_key_len + 1;
 549.869 +      }
 549.870 +      else
 549.871 +#endif
 549.872 +      {
 549.873 +#ifdef PNG_iTXt_SUPPORTED
 549.874 +         textp->lang=NULL;
 549.875 +         textp->lang_key=NULL;
 549.876 +#endif
 549.877 +         textp->text = textp->key + key_len + 1;
 549.878 +      }
 549.879 +      if (text_length)
 549.880 +         png_memcpy(textp->text, text_ptr[i].text,
 549.881 +            (png_size_t)(text_length));
 549.882 +      *(textp->text + text_length) = '\0';
 549.883 +
 549.884 +#ifdef PNG_iTXt_SUPPORTED
 549.885 +      if (textp->compression > 0)
 549.886 +      {
 549.887 +         textp->text_length = 0;
 549.888 +         textp->itxt_length = text_length;
 549.889 +      }
 549.890 +      else
 549.891 +#endif
 549.892 +      {
 549.893 +         textp->text_length = text_length;
 549.894 +#ifdef PNG_iTXt_SUPPORTED
 549.895 +         textp->itxt_length = 0;
 549.896 +#endif
 549.897 +      }
 549.898 +      info_ptr->num_text++;
 549.899 +      png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
 549.900 +   }
 549.901 +   return(0);
 549.902 +}
 549.903 +#endif
 549.904 +
 549.905 +#if defined(PNG_tIME_SUPPORTED)
 549.906 +void PNGAPI
 549.907 +png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
 549.908 +{
 549.909 +   png_debug1(1, "in %s storage function\n", "tIME");
 549.910 +   if (png_ptr == NULL || info_ptr == NULL ||
 549.911 +       (png_ptr->mode & PNG_WROTE_tIME))
 549.912 +      return;
 549.913 +
 549.914 +   png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
 549.915 +   info_ptr->valid |= PNG_INFO_tIME;
 549.916 +}
 549.917 +#endif
 549.918 +
 549.919 +#if defined(PNG_tRNS_SUPPORTED)
 549.920 +void PNGAPI
 549.921 +png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
 549.922 +   png_bytep trans, int num_trans, png_color_16p trans_values)
 549.923 +{
 549.924 +   png_debug1(1, "in %s storage function\n", "tRNS");
 549.925 +   if (png_ptr == NULL || info_ptr == NULL)
 549.926 +      return;
 549.927 +
 549.928 +   if (trans != NULL)
 549.929 +   {
 549.930 +       /*
 549.931 +        * It may not actually be necessary to set png_ptr->trans here;
 549.932 +        * we do it for backward compatibility with the way the png_handle_tRNS
 549.933 +        * function used to do the allocation.
 549.934 +        */
 549.935 +
 549.936 +#ifdef PNG_FREE_ME_SUPPORTED
 549.937 +       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
 549.938 +#endif
 549.939 +
 549.940 +       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
 549.941 +       png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
 549.942 +           (png_uint_32)PNG_MAX_PALETTE_LENGTH);
 549.943 +       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
 549.944 +         png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
 549.945 +   }
 549.946 +
 549.947 +   if (trans_values != NULL)
 549.948 +   {
 549.949 +      int sample_max = (1 << info_ptr->bit_depth);
 549.950 +      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
 549.951 +          (int)trans_values->gray > sample_max) ||
 549.952 +          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
 549.953 +          ((int)trans_values->red > sample_max ||
 549.954 +          (int)trans_values->green > sample_max ||
 549.955 +          (int)trans_values->blue > sample_max)))
 549.956 +        png_warning(png_ptr,
 549.957 +           "tRNS chunk has out-of-range samples for bit_depth");
 549.958 +      png_memcpy(&(info_ptr->trans_values), trans_values,
 549.959 +         png_sizeof(png_color_16));
 549.960 +      if (num_trans == 0)
 549.961 +        num_trans = 1;
 549.962 +   }
 549.963 +
 549.964 +   info_ptr->num_trans = (png_uint_16)num_trans;
 549.965 +   if (num_trans != 0)
 549.966 +   {
 549.967 +      info_ptr->valid |= PNG_INFO_tRNS;
 549.968 +#ifdef PNG_FREE_ME_SUPPORTED
 549.969 +      info_ptr->free_me |= PNG_FREE_TRNS;
 549.970 +#else
 549.971 +      png_ptr->flags |= PNG_FLAG_FREE_TRNS;
 549.972 +#endif
 549.973 +   }
 549.974 +}
 549.975 +#endif
 549.976 +
 549.977 +#if defined(PNG_sPLT_SUPPORTED)
 549.978 +void PNGAPI
 549.979 +png_set_sPLT(png_structp png_ptr,
 549.980 +             png_infop info_ptr, png_sPLT_tp entries, int nentries)
 549.981 +/*
 549.982 + *  entries        - array of png_sPLT_t structures
 549.983 + *                   to be added to the list of palettes
 549.984 + *                   in the info structure.
 549.985 + *  nentries       - number of palette structures to be
 549.986 + *                   added.
 549.987 + */
 549.988 +{
 549.989 +    png_sPLT_tp np;
 549.990 +    int i;
 549.991 +
 549.992 +    if (png_ptr == NULL || info_ptr == NULL)
 549.993 +       return;
 549.994 +
 549.995 +    np = (png_sPLT_tp)png_malloc_warn(png_ptr,
 549.996 +        (info_ptr->splt_palettes_num + nentries) *
 549.997 +        (png_uint_32)png_sizeof(png_sPLT_t));
 549.998 +    if (np == NULL)
 549.999 +    {
549.1000 +      png_warning(png_ptr, "No memory for sPLT palettes.");
549.1001 +      return;
549.1002 +    }
549.1003 +
549.1004 +    png_memcpy(np, info_ptr->splt_palettes,
549.1005 +           info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
549.1006 +    png_free(png_ptr, info_ptr->splt_palettes);
549.1007 +    info_ptr->splt_palettes=NULL;
549.1008 +
549.1009 +    for (i = 0; i < nentries; i++)
549.1010 +    {
549.1011 +        png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
549.1012 +        png_sPLT_tp from = entries + i;
549.1013 +        png_uint_32 length;
549.1014 +
549.1015 +        length = png_strlen(from->name) + 1;
549.1016 +        to->name = (png_charp)png_malloc_warn(png_ptr, length);
549.1017 +        if (to->name == NULL)
549.1018 +        {
549.1019 +           png_warning(png_ptr,
549.1020 +             "Out of memory while processing sPLT chunk");
549.1021 +           continue;
549.1022 +        }
549.1023 +        png_memcpy(to->name, from->name, length);
549.1024 +        to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
549.1025 +            (png_uint_32)(from->nentries * png_sizeof(png_sPLT_entry)));
549.1026 +        if (to->entries == NULL)
549.1027 +        {
549.1028 +           png_warning(png_ptr,
549.1029 +             "Out of memory while processing sPLT chunk");
549.1030 +           png_free(png_ptr, to->name);
549.1031 +           to->name = NULL;
549.1032 +           continue;
549.1033 +        }
549.1034 +        png_memcpy(to->entries, from->entries,
549.1035 +            from->nentries * png_sizeof(png_sPLT_entry));
549.1036 +        to->nentries = from->nentries;
549.1037 +        to->depth = from->depth;
549.1038 +    }
549.1039 +
549.1040 +    info_ptr->splt_palettes = np;
549.1041 +    info_ptr->splt_palettes_num += nentries;
549.1042 +    info_ptr->valid |= PNG_INFO_sPLT;
549.1043 +#ifdef PNG_FREE_ME_SUPPORTED
549.1044 +    info_ptr->free_me |= PNG_FREE_SPLT;
549.1045 +#endif
549.1046 +}
549.1047 +#endif /* PNG_sPLT_SUPPORTED */
549.1048 +
549.1049 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
549.1050 +void PNGAPI
549.1051 +png_set_unknown_chunks(png_structp png_ptr,
549.1052 +   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
549.1053 +{
549.1054 +    png_unknown_chunkp np;
549.1055 +    int i;
549.1056 +
549.1057 +    if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
549.1058 +        return;
549.1059 +
549.1060 +    np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
549.1061 +        (png_uint_32)((info_ptr->unknown_chunks_num + num_unknowns) *
549.1062 +        png_sizeof(png_unknown_chunk)));
549.1063 +    if (np == NULL)
549.1064 +    {
549.1065 +       png_warning(png_ptr,
549.1066 +          "Out of memory while processing unknown chunk.");
549.1067 +       return;
549.1068 +    }
549.1069 +
549.1070 +    png_memcpy(np, info_ptr->unknown_chunks,
549.1071 +           info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
549.1072 +    png_free(png_ptr, info_ptr->unknown_chunks);
549.1073 +    info_ptr->unknown_chunks=NULL;
549.1074 +
549.1075 +    for (i = 0; i < num_unknowns; i++)
549.1076 +    {
549.1077 +       png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
549.1078 +       png_unknown_chunkp from = unknowns + i;
549.1079 +
549.1080 +       png_memcpy((png_charp)to->name, 
549.1081 +                  (png_charp)from->name, 
549.1082 +                  png_sizeof(from->name));
549.1083 +       to->name[png_sizeof(to->name)-1] = '\0';
549.1084 +       to->size = from->size;
549.1085 +       /* note our location in the read or write sequence */
549.1086 +       to->location = (png_byte)(png_ptr->mode & 0xff);
549.1087 +
549.1088 +       if (from->size == 0)
549.1089 +          to->data=NULL;
549.1090 +       else
549.1091 +       {
549.1092 +          to->data = (png_bytep)png_malloc_warn(png_ptr,
549.1093 +            (png_uint_32)from->size);
549.1094 +          if (to->data == NULL)
549.1095 +          {
549.1096 +             png_warning(png_ptr,
549.1097 +              "Out of memory while processing unknown chunk.");
549.1098 +             to->size = 0;
549.1099 +          }
549.1100 +          else
549.1101 +             png_memcpy(to->data, from->data, from->size);
549.1102 +       }
549.1103 +    }
549.1104 +
549.1105 +    info_ptr->unknown_chunks = np;
549.1106 +    info_ptr->unknown_chunks_num += num_unknowns;
549.1107 +#ifdef PNG_FREE_ME_SUPPORTED
549.1108 +    info_ptr->free_me |= PNG_FREE_UNKN;
549.1109 +#endif
549.1110 +}
549.1111 +void PNGAPI
549.1112 +png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
549.1113 +   int chunk, int location)
549.1114 +{
549.1115 +   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
549.1116 +         (int)info_ptr->unknown_chunks_num)
549.1117 +      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
549.1118 +}
549.1119 +#endif
549.1120 +
549.1121 +#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
549.1122 +#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
549.1123 +    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
549.1124 +void PNGAPI
549.1125 +png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
549.1126 +{
549.1127 +   /* This function is deprecated in favor of png_permit_mng_features()
549.1128 +      and will be removed from libpng-1.3.0 */
549.1129 +   png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n");
549.1130 +   if (png_ptr == NULL)
549.1131 +      return;
549.1132 +   png_ptr->mng_features_permitted = (png_byte)
549.1133 +     ((png_ptr->mng_features_permitted & (~PNG_FLAG_MNG_EMPTY_PLTE)) |
549.1134 +     ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
549.1135 +}
549.1136 +#endif
549.1137 +#endif
549.1138 +
549.1139 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
549.1140 +png_uint_32 PNGAPI
549.1141 +png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
549.1142 +{
549.1143 +   png_debug(1, "in png_permit_mng_features\n");
549.1144 +   if (png_ptr == NULL)
549.1145 +      return (png_uint_32)0;
549.1146 +   png_ptr->mng_features_permitted =
549.1147 +     (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
549.1148 +   return (png_uint_32)png_ptr->mng_features_permitted;
549.1149 +}
549.1150 +#endif
549.1151 +
549.1152 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
549.1153 +void PNGAPI
549.1154 +png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
549.1155 +   chunk_list, int num_chunks)
549.1156 +{
549.1157 +    png_bytep new_list, p;
549.1158 +    int i, old_num_chunks;
549.1159 +    if (png_ptr == NULL)
549.1160 +       return;
549.1161 +    if (num_chunks == 0)
549.1162 +    {
549.1163 +      if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
549.1164 +        png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
549.1165 +      else
549.1166 +        png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
549.1167 +
549.1168 +      if (keep == PNG_HANDLE_CHUNK_ALWAYS)
549.1169 +        png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
549.1170 +      else
549.1171 +        png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
549.1172 +      return;
549.1173 +    }
549.1174 +    if (chunk_list == NULL)
549.1175 +      return;
549.1176 +    old_num_chunks = png_ptr->num_chunk_list;
549.1177 +    new_list=(png_bytep)png_malloc(png_ptr,
549.1178 +       (png_uint_32)
549.1179 +       (5*(num_chunks + old_num_chunks)));
549.1180 +    if (png_ptr->chunk_list != NULL)
549.1181 +    {
549.1182 +       png_memcpy(new_list, png_ptr->chunk_list,
549.1183 +          (png_size_t)(5*old_num_chunks));
549.1184 +       png_free(png_ptr, png_ptr->chunk_list);
549.1185 +       png_ptr->chunk_list=NULL;
549.1186 +    }
549.1187 +    png_memcpy(new_list + 5*old_num_chunks, chunk_list,
549.1188 +       (png_size_t)(5*num_chunks));
549.1189 +    for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5)
549.1190 +       *p=(png_byte)keep;
549.1191 +    png_ptr->num_chunk_list = old_num_chunks + num_chunks;
549.1192 +    png_ptr->chunk_list = new_list;
549.1193 +#ifdef PNG_FREE_ME_SUPPORTED
549.1194 +    png_ptr->free_me |= PNG_FREE_LIST;
549.1195 +#endif
549.1196 +}
549.1197 +#endif
549.1198 +
549.1199 +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
549.1200 +void PNGAPI
549.1201 +png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
549.1202 +   png_user_chunk_ptr read_user_chunk_fn)
549.1203 +{
549.1204 +   png_debug(1, "in png_set_read_user_chunk_fn\n");
549.1205 +   if (png_ptr == NULL)
549.1206 +      return;
549.1207 +   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
549.1208 +   png_ptr->user_chunk_ptr = user_chunk_ptr;
549.1209 +}
549.1210 +#endif
549.1211 +
549.1212 +#if defined(PNG_INFO_IMAGE_SUPPORTED)
549.1213 +void PNGAPI
549.1214 +png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
549.1215 +{
549.1216 +   png_debug1(1, "in %s storage function\n", "rows");
549.1217 +
549.1218 +   if (png_ptr == NULL || info_ptr == NULL)
549.1219 +      return;
549.1220 +
549.1221 +   if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
549.1222 +      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
549.1223 +   info_ptr->row_pointers = row_pointers;
549.1224 +   if (row_pointers)
549.1225 +      info_ptr->valid |= PNG_INFO_IDAT;
549.1226 +}
549.1227 +#endif
549.1228 +
549.1229 +#ifdef PNG_WRITE_SUPPORTED
549.1230 +void PNGAPI
549.1231 +png_set_compression_buffer_size(png_structp png_ptr,
549.1232 +    png_uint_32 size)
549.1233 +{
549.1234 +    if (png_ptr == NULL)
549.1235 +       return;
549.1236 +    png_free(png_ptr, png_ptr->zbuf);
549.1237 +    png_ptr->zbuf_size = (png_size_t)size;
549.1238 +    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
549.1239 +    png_ptr->zstream.next_out = png_ptr->zbuf;
549.1240 +    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
549.1241 +}
549.1242 +#endif
549.1243 +
549.1244 +void PNGAPI
549.1245 +png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
549.1246 +{
549.1247 +   if (png_ptr && info_ptr)
549.1248 +      info_ptr->valid &= ~mask;
549.1249 +}
549.1250 +
549.1251 +
549.1252 +#ifndef PNG_1_0_X
549.1253 +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
549.1254 +/* function was added to libpng 1.2.0 and should always exist by default */
549.1255 +void PNGAPI
549.1256 +png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags)
549.1257 +{
549.1258 +/* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */
549.1259 +    if (png_ptr != NULL)
549.1260 +    png_ptr->asm_flags = 0;
549.1261 +    asm_flags = asm_flags; /* Quiet the compiler */
549.1262 +}
549.1263 +
549.1264 +/* this function was added to libpng 1.2.0 */
549.1265 +void PNGAPI
549.1266 +png_set_mmx_thresholds (png_structp png_ptr,
549.1267 +                        png_byte mmx_bitdepth_threshold,
549.1268 +                        png_uint_32 mmx_rowbytes_threshold)
549.1269 +{
549.1270 +/* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */
549.1271 +    if (png_ptr == NULL)
549.1272 +       return;
549.1273 +    /* Quiet the compiler */
549.1274 +    mmx_bitdepth_threshold = mmx_bitdepth_threshold;
549.1275 +    mmx_rowbytes_threshold = mmx_rowbytes_threshold;
549.1276 +}
549.1277 +#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
549.1278 +
549.1279 +#ifdef PNG_SET_USER_LIMITS_SUPPORTED
549.1280 +/* this function was added to libpng 1.2.6 */
549.1281 +void PNGAPI
549.1282 +png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
549.1283 +    png_uint_32 user_height_max)
549.1284 +{
549.1285 +    /* Images with dimensions larger than these limits will be
549.1286 +     * rejected by png_set_IHDR().  To accept any PNG datastream
549.1287 +     * regardless of dimensions, set both limits to 0x7ffffffL.
549.1288 +     */
549.1289 +    if (png_ptr == NULL) return;
549.1290 +    png_ptr->user_width_max = user_width_max;
549.1291 +    png_ptr->user_height_max = user_height_max;
549.1292 +}
549.1293 +#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
549.1294 +
549.1295 +#endif /* ?PNG_1_0_X */
549.1296 +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
   550.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   550.2 +++ b/libs/libpng/pngtrans.c	Sat Feb 01 19:58:19 2014 +0200
   550.3 @@ -0,0 +1,662 @@
   550.4 +
   550.5 +/* pngtrans.c - transforms the data in a row (used by both readers and writers)
   550.6 + *
   550.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   550.8 + * For conditions of distribution and use, see copyright notice in png.h
   550.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  550.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  550.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  550.12 + */
  550.13 +
  550.14 +#define PNG_INTERNAL
  550.15 +#include "png.h"
  550.16 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  550.17 +
  550.18 +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
  550.19 +/* turn on BGR-to-RGB mapping */
  550.20 +void PNGAPI
  550.21 +png_set_bgr(png_structp png_ptr)
  550.22 +{
  550.23 +   png_debug(1, "in png_set_bgr\n");
  550.24 +   if (png_ptr == NULL) return;
  550.25 +   png_ptr->transformations |= PNG_BGR;
  550.26 +}
  550.27 +#endif
  550.28 +
  550.29 +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
  550.30 +/* turn on 16 bit byte swapping */
  550.31 +void PNGAPI
  550.32 +png_set_swap(png_structp png_ptr)
  550.33 +{
  550.34 +   png_debug(1, "in png_set_swap\n");
  550.35 +   if (png_ptr == NULL) return;
  550.36 +   if (png_ptr->bit_depth == 16)
  550.37 +      png_ptr->transformations |= PNG_SWAP_BYTES;
  550.38 +}
  550.39 +#endif
  550.40 +
  550.41 +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
  550.42 +/* turn on pixel packing */
  550.43 +void PNGAPI
  550.44 +png_set_packing(png_structp png_ptr)
  550.45 +{
  550.46 +   png_debug(1, "in png_set_packing\n");
  550.47 +   if (png_ptr == NULL) return;
  550.48 +   if (png_ptr->bit_depth < 8)
  550.49 +   {
  550.50 +      png_ptr->transformations |= PNG_PACK;
  550.51 +      png_ptr->usr_bit_depth = 8;
  550.52 +   }
  550.53 +}
  550.54 +#endif
  550.55 +
  550.56 +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
  550.57 +/* turn on packed pixel swapping */
  550.58 +void PNGAPI
  550.59 +png_set_packswap(png_structp png_ptr)
  550.60 +{
  550.61 +   png_debug(1, "in png_set_packswap\n");
  550.62 +   if (png_ptr == NULL) return;
  550.63 +   if (png_ptr->bit_depth < 8)
  550.64 +      png_ptr->transformations |= PNG_PACKSWAP;
  550.65 +}
  550.66 +#endif
  550.67 +
  550.68 +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
  550.69 +void PNGAPI
  550.70 +png_set_shift(png_structp png_ptr, png_color_8p true_bits)
  550.71 +{
  550.72 +   png_debug(1, "in png_set_shift\n");
  550.73 +   if (png_ptr == NULL) return;
  550.74 +   png_ptr->transformations |= PNG_SHIFT;
  550.75 +   png_ptr->shift = *true_bits;
  550.76 +}
  550.77 +#endif
  550.78 +
  550.79 +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
  550.80 +    defined(PNG_WRITE_INTERLACING_SUPPORTED)
  550.81 +int PNGAPI
  550.82 +png_set_interlace_handling(png_structp png_ptr)
  550.83 +{
  550.84 +   png_debug(1, "in png_set_interlace handling\n");
  550.85 +   if (png_ptr && png_ptr->interlaced)
  550.86 +   {
  550.87 +      png_ptr->transformations |= PNG_INTERLACE;
  550.88 +      return (7);
  550.89 +   }
  550.90 +
  550.91 +   return (1);
  550.92 +}
  550.93 +#endif
  550.94 +
  550.95 +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
  550.96 +/* Add a filler byte on read, or remove a filler or alpha byte on write.
  550.97 + * The filler type has changed in v0.95 to allow future 2-byte fillers
  550.98 + * for 48-bit input data, as well as to avoid problems with some compilers
  550.99 + * that don't like bytes as parameters.
 550.100 + */
 550.101 +void PNGAPI
 550.102 +png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
 550.103 +{
 550.104 +   png_debug(1, "in png_set_filler\n");
 550.105 +   if (png_ptr == NULL) return;
 550.106 +   png_ptr->transformations |= PNG_FILLER;
 550.107 +   png_ptr->filler = (png_byte)filler;
 550.108 +   if (filler_loc == PNG_FILLER_AFTER)
 550.109 +      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
 550.110 +   else
 550.111 +      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
 550.112 +
 550.113 +   /* This should probably go in the "do_read_filler" routine.
 550.114 +    * I attempted to do that in libpng-1.0.1a but that caused problems
 550.115 +    * so I restored it in libpng-1.0.2a
 550.116 +   */
 550.117 +
 550.118 +   if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
 550.119 +   {
 550.120 +      png_ptr->usr_channels = 4;
 550.121 +   }
 550.122 +
 550.123 +   /* Also I added this in libpng-1.0.2a (what happens when we expand
 550.124 +    * a less-than-8-bit grayscale to GA? */
 550.125 +
 550.126 +   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
 550.127 +   {
 550.128 +      png_ptr->usr_channels = 2;
 550.129 +   }
 550.130 +}
 550.131 +
 550.132 +#if !defined(PNG_1_0_X)
 550.133 +/* Added to libpng-1.2.7 */
 550.134 +void PNGAPI
 550.135 +png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
 550.136 +{
 550.137 +   png_debug(1, "in png_set_add_alpha\n");
 550.138 +   if (png_ptr == NULL) return;
 550.139 +   png_set_filler(png_ptr, filler, filler_loc);
 550.140 +   png_ptr->transformations |= PNG_ADD_ALPHA;
 550.141 +}
 550.142 +#endif
 550.143 +
 550.144 +#endif
 550.145 +
 550.146 +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
 550.147 +    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
 550.148 +void PNGAPI
 550.149 +png_set_swap_alpha(png_structp png_ptr)
 550.150 +{
 550.151 +   png_debug(1, "in png_set_swap_alpha\n");
 550.152 +   if (png_ptr == NULL) return;
 550.153 +   png_ptr->transformations |= PNG_SWAP_ALPHA;
 550.154 +}
 550.155 +#endif
 550.156 +
 550.157 +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
 550.158 +    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
 550.159 +void PNGAPI
 550.160 +png_set_invert_alpha(png_structp png_ptr)
 550.161 +{
 550.162 +   png_debug(1, "in png_set_invert_alpha\n");
 550.163 +   if (png_ptr == NULL) return;
 550.164 +   png_ptr->transformations |= PNG_INVERT_ALPHA;
 550.165 +}
 550.166 +#endif
 550.167 +
 550.168 +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
 550.169 +void PNGAPI
 550.170 +png_set_invert_mono(png_structp png_ptr)
 550.171 +{
 550.172 +   png_debug(1, "in png_set_invert_mono\n");
 550.173 +   if (png_ptr == NULL) return;
 550.174 +   png_ptr->transformations |= PNG_INVERT_MONO;
 550.175 +}
 550.176 +
 550.177 +/* invert monochrome grayscale data */
 550.178 +void /* PRIVATE */
 550.179 +png_do_invert(png_row_infop row_info, png_bytep row)
 550.180 +{
 550.181 +   png_debug(1, "in png_do_invert\n");
 550.182 +  /* This test removed from libpng version 1.0.13 and 1.2.0:
 550.183 +   *   if (row_info->bit_depth == 1 &&
 550.184 +   */
 550.185 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
 550.186 +   if (row == NULL || row_info == NULL)
 550.187 +     return;
 550.188 +#endif
 550.189 +   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
 550.190 +   {
 550.191 +      png_bytep rp = row;
 550.192 +      png_uint_32 i;
 550.193 +      png_uint_32 istop = row_info->rowbytes;
 550.194 +
 550.195 +      for (i = 0; i < istop; i++)
 550.196 +      {
 550.197 +         *rp = (png_byte)(~(*rp));
 550.198 +         rp++;
 550.199 +      }
 550.200 +   }
 550.201 +   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
 550.202 +      row_info->bit_depth == 8)
 550.203 +   {
 550.204 +      png_bytep rp = row;
 550.205 +      png_uint_32 i;
 550.206 +      png_uint_32 istop = row_info->rowbytes;
 550.207 +
 550.208 +      for (i = 0; i < istop; i+=2)
 550.209 +      {
 550.210 +         *rp = (png_byte)(~(*rp));
 550.211 +         rp+=2;
 550.212 +      }
 550.213 +   }
 550.214 +   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
 550.215 +      row_info->bit_depth == 16)
 550.216 +   {
 550.217 +      png_bytep rp = row;
 550.218 +      png_uint_32 i;
 550.219 +      png_uint_32 istop = row_info->rowbytes;
 550.220 +
 550.221 +      for (i = 0; i < istop; i+=4)
 550.222 +      {
 550.223 +         *rp = (png_byte)(~(*rp));
 550.224 +         *(rp+1) = (png_byte)(~(*(rp+1)));
 550.225 +         rp+=4;
 550.226 +      }
 550.227 +   }
 550.228 +}
 550.229 +#endif
 550.230 +
 550.231 +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
 550.232 +/* swaps byte order on 16 bit depth images */
 550.233 +void /* PRIVATE */
 550.234 +png_do_swap(png_row_infop row_info, png_bytep row)
 550.235 +{
 550.236 +   png_debug(1, "in png_do_swap\n");
 550.237 +   if (
 550.238 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
 550.239 +       row != NULL && row_info != NULL &&
 550.240 +#endif
 550.241 +       row_info->bit_depth == 16)
 550.242 +   {
 550.243 +      png_bytep rp = row;
 550.244 +      png_uint_32 i;
 550.245 +      png_uint_32 istop= row_info->width * row_info->channels;
 550.246 +
 550.247 +      for (i = 0; i < istop; i++, rp += 2)
 550.248 +      {
 550.249 +         png_byte t = *rp;
 550.250 +         *rp = *(rp + 1);
 550.251 +         *(rp + 1) = t;
 550.252 +      }
 550.253 +   }
 550.254 +}
 550.255 +#endif
 550.256 +
 550.257 +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
 550.258 +static PNG_CONST png_byte onebppswaptable[256] = {
 550.259 +   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
 550.260 +   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
 550.261 +   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
 550.262 +   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
 550.263 +   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
 550.264 +   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
 550.265 +   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
 550.266 +   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
 550.267 +   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
 550.268 +   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
 550.269 +   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
 550.270 +   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
 550.271 +   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
 550.272 +   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
 550.273 +   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
 550.274 +   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
 550.275 +   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
 550.276 +   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
 550.277 +   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
 550.278 +   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
 550.279 +   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
 550.280 +   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
 550.281 +   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
 550.282 +   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
 550.283 +   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
 550.284 +   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
 550.285 +   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
 550.286 +   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
 550.287 +   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
 550.288 +   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
 550.289 +   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
 550.290 +   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
 550.291 +};
 550.292 +
 550.293 +static PNG_CONST png_byte twobppswaptable[256] = {
 550.294 +   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
 550.295 +   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
 550.296 +   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
 550.297 +   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
 550.298 +   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
 550.299 +   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
 550.300 +   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
 550.301 +   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
 550.302 +   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
 550.303 +   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
 550.304 +   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
 550.305 +   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
 550.306 +   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
 550.307 +   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
 550.308 +   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
 550.309 +   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
 550.310 +   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
 550.311 +   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
 550.312 +   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
 550.313 +   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
 550.314 +   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
 550.315 +   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
 550.316 +   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
 550.317 +   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
 550.318 +   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
 550.319 +   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
 550.320 +   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
 550.321 +   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
 550.322 +   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
 550.323 +   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
 550.324 +   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
 550.325 +   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
 550.326 +};
 550.327 +
 550.328 +static PNG_CONST png_byte fourbppswaptable[256] = {
 550.329 +   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
 550.330 +   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
 550.331 +   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
 550.332 +   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
 550.333 +   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
 550.334 +   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
 550.335 +   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
 550.336 +   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
 550.337 +   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
 550.338 +   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
 550.339 +   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
 550.340 +   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
 550.341 +   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
 550.342 +   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
 550.343 +   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
 550.344 +   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
 550.345 +   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
 550.346 +   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
 550.347 +   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
 550.348 +   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
 550.349 +   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
 550.350 +   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
 550.351 +   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
 550.352 +   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
 550.353 +   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
 550.354 +   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
 550.355 +   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
 550.356 +   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
 550.357 +   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
 550.358 +   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
 550.359 +   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
 550.360 +   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
 550.361 +};
 550.362 +
 550.363 +/* swaps pixel packing order within bytes */
 550.364 +void /* PRIVATE */
 550.365 +png_do_packswap(png_row_infop row_info, png_bytep row)
 550.366 +{
 550.367 +   png_debug(1, "in png_do_packswap\n");
 550.368 +   if (
 550.369 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
 550.370 +       row != NULL && row_info != NULL &&
 550.371 +#endif
 550.372 +       row_info->bit_depth < 8)
 550.373 +   {
 550.374 +      png_bytep rp, end, table;
 550.375 +
 550.376 +      end = row + row_info->rowbytes;
 550.377 +
 550.378 +      if (row_info->bit_depth == 1)
 550.379 +         table = (png_bytep)onebppswaptable;
 550.380 +      else if (row_info->bit_depth == 2)
 550.381 +         table = (png_bytep)twobppswaptable;
 550.382 +      else if (row_info->bit_depth == 4)
 550.383 +         table = (png_bytep)fourbppswaptable;
 550.384 +      else
 550.385 +         return;
 550.386 +
 550.387 +      for (rp = row; rp < end; rp++)
 550.388 +         *rp = table[*rp];
 550.389 +   }
 550.390 +}
 550.391 +#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
 550.392 +
 550.393 +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
 550.394 +    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
 550.395 +/* remove filler or alpha byte(s) */
 550.396 +void /* PRIVATE */
 550.397 +png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
 550.398 +{
 550.399 +   png_debug(1, "in png_do_strip_filler\n");
 550.400 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
 550.401 +   if (row != NULL && row_info != NULL)
 550.402 +#endif
 550.403 +   {
 550.404 +      png_bytep sp=row;
 550.405 +      png_bytep dp=row;
 550.406 +      png_uint_32 row_width=row_info->width;
 550.407 +      png_uint_32 i;
 550.408 +
 550.409 +      if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
 550.410 +         (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
 550.411 +         (flags & PNG_FLAG_STRIP_ALPHA))) &&
 550.412 +         row_info->channels == 4)
 550.413 +      {
 550.414 +         if (row_info->bit_depth == 8)
 550.415 +         {
 550.416 +            /* This converts from RGBX or RGBA to RGB */
 550.417 +            if (flags & PNG_FLAG_FILLER_AFTER)
 550.418 +            {
 550.419 +               dp+=3; sp+=4;
 550.420 +               for (i = 1; i < row_width; i++)
 550.421 +               {
 550.422 +                  *dp++ = *sp++;
 550.423 +                  *dp++ = *sp++;
 550.424 +                  *dp++ = *sp++;
 550.425 +                  sp++;
 550.426 +               }
 550.427 +            }
 550.428 +            /* This converts from XRGB or ARGB to RGB */
 550.429 +            else
 550.430 +            {
 550.431 +               for (i = 0; i < row_width; i++)
 550.432 +               {
 550.433 +                  sp++;
 550.434 +                  *dp++ = *sp++;
 550.435 +                  *dp++ = *sp++;
 550.436 +                  *dp++ = *sp++;
 550.437 +               }
 550.438 +            }
 550.439 +            row_info->pixel_depth = 24;
 550.440 +            row_info->rowbytes = row_width * 3;
 550.441 +         }
 550.442 +         else /* if (row_info->bit_depth == 16) */
 550.443 +         {
 550.444 +            if (flags & PNG_FLAG_FILLER_AFTER)
 550.445 +            {
 550.446 +               /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
 550.447 +               sp += 8; dp += 6;
 550.448 +               for (i = 1; i < row_width; i++)
 550.449 +               {
 550.450 +                  /* This could be (although png_memcpy is probably slower):
 550.451 +                  png_memcpy(dp, sp, 6);
 550.452 +                  sp += 8;
 550.453 +                  dp += 6;
 550.454 +                  */
 550.455 +
 550.456 +                  *dp++ = *sp++;
 550.457 +                  *dp++ = *sp++;
 550.458 +                  *dp++ = *sp++;
 550.459 +                  *dp++ = *sp++;
 550.460 +                  *dp++ = *sp++;
 550.461 +                  *dp++ = *sp++;
 550.462 +                  sp += 2;
 550.463 +               }
 550.464 +            }
 550.465 +            else
 550.466 +            {
 550.467 +               /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
 550.468 +               for (i = 0; i < row_width; i++)
 550.469 +               {
 550.470 +                  /* This could be (although png_memcpy is probably slower):
 550.471 +                  png_memcpy(dp, sp, 6);
 550.472 +                  sp += 8;
 550.473 +                  dp += 6;
 550.474 +                  */
 550.475 +
 550.476 +                  sp+=2;
 550.477 +                  *dp++ = *sp++;
 550.478 +                  *dp++ = *sp++;
 550.479 +                  *dp++ = *sp++;
 550.480 +                  *dp++ = *sp++;
 550.481 +                  *dp++ = *sp++;
 550.482 +                  *dp++ = *sp++;
 550.483 +               }
 550.484 +            }
 550.485 +            row_info->pixel_depth = 48;
 550.486 +            row_info->rowbytes = row_width * 6;
 550.487 +         }
 550.488 +         row_info->channels = 3;
 550.489 +      }
 550.490 +      else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
 550.491 +         (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
 550.492 +         (flags & PNG_FLAG_STRIP_ALPHA))) &&
 550.493 +          row_info->channels == 2)
 550.494 +      {
 550.495 +         if (row_info->bit_depth == 8)
 550.496 +         {
 550.497 +            /* This converts from GX or GA to G */
 550.498 +            if (flags & PNG_FLAG_FILLER_AFTER)
 550.499 +            {
 550.500 +               for (i = 0; i < row_width; i++)
 550.501 +               {
 550.502 +                  *dp++ = *sp++;
 550.503 +                  sp++;
 550.504 +               }
 550.505 +            }
 550.506 +            /* This converts from XG or AG to G */
 550.507 +            else
 550.508 +            {
 550.509 +               for (i = 0; i < row_width; i++)
 550.510 +               {
 550.511 +                  sp++;
 550.512 +                  *dp++ = *sp++;
 550.513 +               }
 550.514 +            }
 550.515 +            row_info->pixel_depth = 8;
 550.516 +            row_info->rowbytes = row_width;
 550.517 +         }
 550.518 +         else /* if (row_info->bit_depth == 16) */
 550.519 +         {
 550.520 +            if (flags & PNG_FLAG_FILLER_AFTER)
 550.521 +            {
 550.522 +               /* This converts from GGXX or GGAA to GG */
 550.523 +               sp += 4; dp += 2;
 550.524 +               for (i = 1; i < row_width; i++)
 550.525 +               {
 550.526 +                  *dp++ = *sp++;
 550.527 +                  *dp++ = *sp++;
 550.528 +                  sp += 2;
 550.529 +               }
 550.530 +            }
 550.531 +            else
 550.532 +            {
 550.533 +               /* This converts from XXGG or AAGG to GG */
 550.534 +               for (i = 0; i < row_width; i++)
 550.535 +               {
 550.536 +                  sp += 2;
 550.537 +                  *dp++ = *sp++;
 550.538 +                  *dp++ = *sp++;
 550.539 +               }
 550.540 +            }
 550.541 +            row_info->pixel_depth = 16;
 550.542 +            row_info->rowbytes = row_width * 2;
 550.543 +         }
 550.544 +         row_info->channels = 1;
 550.545 +      }
 550.546 +      if (flags & PNG_FLAG_STRIP_ALPHA)
 550.547 +        row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
 550.548 +   }
 550.549 +}
 550.550 +#endif
 550.551 +
 550.552 +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
 550.553 +/* swaps red and blue bytes within a pixel */
 550.554 +void /* PRIVATE */
 550.555 +png_do_bgr(png_row_infop row_info, png_bytep row)
 550.556 +{
 550.557 +   png_debug(1, "in png_do_bgr\n");
 550.558 +   if (
 550.559 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
 550.560 +       row != NULL && row_info != NULL &&
 550.561 +#endif
 550.562 +       (row_info->color_type & PNG_COLOR_MASK_COLOR))
 550.563 +   {
 550.564 +      png_uint_32 row_width = row_info->width;
 550.565 +      if (row_info->bit_depth == 8)
 550.566 +      {
 550.567 +         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 550.568 +         {
 550.569 +            png_bytep rp;
 550.570 +            png_uint_32 i;
 550.571 +
 550.572 +            for (i = 0, rp = row; i < row_width; i++, rp += 3)
 550.573 +            {
 550.574 +               png_byte save = *rp;
 550.575 +               *rp = *(rp + 2);
 550.576 +               *(rp + 2) = save;
 550.577 +            }
 550.578 +         }
 550.579 +         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 550.580 +         {
 550.581 +            png_bytep rp;
 550.582 +            png_uint_32 i;
 550.583 +
 550.584 +            for (i = 0, rp = row; i < row_width; i++, rp += 4)
 550.585 +            {
 550.586 +               png_byte save = *rp;
 550.587 +               *rp = *(rp + 2);
 550.588 +               *(rp + 2) = save;
 550.589 +            }
 550.590 +         }
 550.591 +      }
 550.592 +      else if (row_info->bit_depth == 16)
 550.593 +      {
 550.594 +         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 550.595 +         {
 550.596 +            png_bytep rp;
 550.597 +            png_uint_32 i;
 550.598 +
 550.599 +            for (i = 0, rp = row; i < row_width; i++, rp += 6)
 550.600 +            {
 550.601 +               png_byte save = *rp;
 550.602 +               *rp = *(rp + 4);
 550.603 +               *(rp + 4) = save;
 550.604 +               save = *(rp + 1);
 550.605 +               *(rp + 1) = *(rp + 5);
 550.606 +               *(rp + 5) = save;
 550.607 +            }
 550.608 +         }
 550.609 +         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 550.610 +         {
 550.611 +            png_bytep rp;
 550.612 +            png_uint_32 i;
 550.613 +
 550.614 +            for (i = 0, rp = row; i < row_width; i++, rp += 8)
 550.615 +            {
 550.616 +               png_byte save = *rp;
 550.617 +               *rp = *(rp + 4);
 550.618 +               *(rp + 4) = save;
 550.619 +               save = *(rp + 1);
 550.620 +               *(rp + 1) = *(rp + 5);
 550.621 +               *(rp + 5) = save;
 550.622 +            }
 550.623 +         }
 550.624 +      }
 550.625 +   }
 550.626 +}
 550.627 +#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
 550.628 +
 550.629 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
 550.630 +    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
 550.631 +    defined(PNG_LEGACY_SUPPORTED)
 550.632 +void PNGAPI
 550.633 +png_set_user_transform_info(png_structp png_ptr, png_voidp
 550.634 +   user_transform_ptr, int user_transform_depth, int user_transform_channels)
 550.635 +{
 550.636 +   png_debug(1, "in png_set_user_transform_info\n");
 550.637 +   if (png_ptr == NULL) return;
 550.638 +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
 550.639 +   png_ptr->user_transform_ptr = user_transform_ptr;
 550.640 +   png_ptr->user_transform_depth = (png_byte)user_transform_depth;
 550.641 +   png_ptr->user_transform_channels = (png_byte)user_transform_channels;
 550.642 +#else
 550.643 +   if (user_transform_ptr || user_transform_depth || user_transform_channels)
 550.644 +      png_warning(png_ptr,
 550.645 +        "This version of libpng does not support user transform info");
 550.646 +#endif
 550.647 +}
 550.648 +#endif
 550.649 +
 550.650 +/* This function returns a pointer to the user_transform_ptr associated with
 550.651 + * the user transform functions.  The application should free any memory
 550.652 + * associated with this pointer before png_write_destroy and png_read_destroy
 550.653 + * are called.
 550.654 + */
 550.655 +png_voidp PNGAPI
 550.656 +png_get_user_transform_ptr(png_structp png_ptr)
 550.657 +{
 550.658 +   if (png_ptr == NULL) return (NULL);
 550.659 +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
 550.660 +   return ((png_voidp)png_ptr->user_transform_ptr);
 550.661 +#else
 550.662 +   return (NULL);
 550.663 +#endif
 550.664 +}
 550.665 +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
   551.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   551.2 +++ b/libs/libpng/pngvcrd.c	Sat Feb 01 19:58:19 2014 +0200
   551.3 @@ -0,0 +1,1 @@
   551.4 +/* pnggvrd.c was removed from libpng-1.2.20. */
   552.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   552.2 +++ b/libs/libpng/pngwio.c	Sat Feb 01 19:58:19 2014 +0200
   552.3 @@ -0,0 +1,234 @@
   552.4 +
   552.5 +/* pngwio.c - functions for data output
   552.6 + *
   552.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   552.8 + * For conditions of distribution and use, see copyright notice in png.h
   552.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  552.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  552.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  552.12 + *
  552.13 + * This file provides a location for all output.  Users who need
  552.14 + * special handling are expected to write functions that have the same
  552.15 + * arguments as these and perform similar functions, but that possibly
  552.16 + * use different output methods.  Note that you shouldn't change these
  552.17 + * functions, but rather write replacement functions and then change
  552.18 + * them at run time with png_set_write_fn(...).
  552.19 + */
  552.20 +
  552.21 +#define PNG_INTERNAL
  552.22 +#include "png.h"
  552.23 +#ifdef PNG_WRITE_SUPPORTED
  552.24 +
  552.25 +/* Write the data to whatever output you are using.  The default routine
  552.26 +   writes to a file pointer.  Note that this routine sometimes gets called
  552.27 +   with very small lengths, so you should implement some kind of simple
  552.28 +   buffering if you are using unbuffered writes.  This should never be asked
  552.29 +   to write more than 64K on a 16 bit machine.  */
  552.30 +
  552.31 +void /* PRIVATE */
  552.32 +png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
  552.33 +{
  552.34 +   if (png_ptr->write_data_fn != NULL )
  552.35 +      (*(png_ptr->write_data_fn))(png_ptr, data, length);
  552.36 +   else
  552.37 +      png_error(png_ptr, "Call to NULL write function");
  552.38 +}
  552.39 +
  552.40 +#if !defined(PNG_NO_STDIO)
  552.41 +/* This is the function that does the actual writing of data.  If you are
  552.42 +   not writing to a standard C stream, you should create a replacement
  552.43 +   write_data function and use it at run time with png_set_write_fn(), rather
  552.44 +   than changing the library. */
  552.45 +#ifndef USE_FAR_KEYWORD
  552.46 +void PNGAPI
  552.47 +png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
  552.48 +{
  552.49 +   png_uint_32 check;
  552.50 +
  552.51 +   if (png_ptr == NULL) return;
  552.52 +#if defined(_WIN32_WCE)
  552.53 +   if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
  552.54 +      check = 0;
  552.55 +#else
  552.56 +   check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
  552.57 +#endif
  552.58 +   if (check != length)
  552.59 +      png_error(png_ptr, "Write Error");
  552.60 +}
  552.61 +#else
  552.62 +/* this is the model-independent version. Since the standard I/O library
  552.63 +   can't handle far buffers in the medium and small models, we have to copy
  552.64 +   the data.
  552.65 +*/
  552.66 +
  552.67 +#define NEAR_BUF_SIZE 1024
  552.68 +#define MIN(a,b) (a <= b ? a : b)
  552.69 +
  552.70 +void PNGAPI
  552.71 +png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
  552.72 +{
  552.73 +   png_uint_32 check;
  552.74 +   png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
  552.75 +   png_FILE_p io_ptr;
  552.76 +
  552.77 +   if (png_ptr == NULL) return;
  552.78 +   /* Check if data really is near. If so, use usual code. */
  552.79 +   near_data = (png_byte *)CVT_PTR_NOCHECK(data);
  552.80 +   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
  552.81 +   if ((png_bytep)near_data == data)
  552.82 +   {
  552.83 +#if defined(_WIN32_WCE)
  552.84 +      if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
  552.85 +         check = 0;
  552.86 +#else
  552.87 +      check = fwrite(near_data, 1, length, io_ptr);
  552.88 +#endif
  552.89 +   }
  552.90 +   else
  552.91 +   {
  552.92 +      png_byte buf[NEAR_BUF_SIZE];
  552.93 +      png_size_t written, remaining, err;
  552.94 +      check = 0;
  552.95 +      remaining = length;
  552.96 +      do
  552.97 +      {
  552.98 +         written = MIN(NEAR_BUF_SIZE, remaining);
  552.99 +         png_memcpy(buf, data, written); /* copy far buffer to near buffer */
 552.100 +#if defined(_WIN32_WCE)
 552.101 +         if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
 552.102 +            err = 0;
 552.103 +#else
 552.104 +         err = fwrite(buf, 1, written, io_ptr);
 552.105 +#endif
 552.106 +         if (err != written)
 552.107 +            break;
 552.108 +         else
 552.109 +            check += err;
 552.110 +         data += written;
 552.111 +         remaining -= written;
 552.112 +      }
 552.113 +      while (remaining != 0);
 552.114 +   }
 552.115 +   if (check != length)
 552.116 +      png_error(png_ptr, "Write Error");
 552.117 +}
 552.118 +
 552.119 +#endif
 552.120 +#endif
 552.121 +
 552.122 +/* This function is called to output any data pending writing (normally
 552.123 +   to disk).  After png_flush is called, there should be no data pending
 552.124 +   writing in any buffers. */
 552.125 +#if defined(PNG_WRITE_FLUSH_SUPPORTED)
 552.126 +void /* PRIVATE */
 552.127 +png_flush(png_structp png_ptr)
 552.128 +{
 552.129 +   if (png_ptr->output_flush_fn != NULL)
 552.130 +      (*(png_ptr->output_flush_fn))(png_ptr);
 552.131 +}
 552.132 +
 552.133 +#if !defined(PNG_NO_STDIO)
 552.134 +void PNGAPI
 552.135 +png_default_flush(png_structp png_ptr)
 552.136 +{
 552.137 +#if !defined(_WIN32_WCE)
 552.138 +   png_FILE_p io_ptr;
 552.139 +#endif
 552.140 +   if (png_ptr == NULL) return;
 552.141 +#if !defined(_WIN32_WCE)
 552.142 +   io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
 552.143 +   if (io_ptr != NULL)
 552.144 +      fflush(io_ptr);
 552.145 +#endif
 552.146 +}
 552.147 +#endif
 552.148 +#endif
 552.149 +
 552.150 +/* This function allows the application to supply new output functions for
 552.151 +   libpng if standard C streams aren't being used.
 552.152 +
 552.153 +   This function takes as its arguments:
 552.154 +   png_ptr       - pointer to a png output data structure
 552.155 +   io_ptr        - pointer to user supplied structure containing info about
 552.156 +                   the output functions.  May be NULL.
 552.157 +   write_data_fn - pointer to a new output function that takes as its
 552.158 +                   arguments a pointer to a png_struct, a pointer to
 552.159 +                   data to be written, and a 32-bit unsigned int that is
 552.160 +                   the number of bytes to be written.  The new write
 552.161 +                   function should call png_error(png_ptr, "Error msg")
 552.162 +                   to exit and output any fatal error messages.
 552.163 +   flush_data_fn - pointer to a new flush function that takes as its
 552.164 +                   arguments a pointer to a png_struct.  After a call to
 552.165 +                   the flush function, there should be no data in any buffers
 552.166 +                   or pending transmission.  If the output method doesn't do
 552.167 +                   any buffering of ouput, a function prototype must still be
 552.168 +                   supplied although it doesn't have to do anything.  If
 552.169 +                   PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
 552.170 +                   time, output_flush_fn will be ignored, although it must be
 552.171 +                   supplied for compatibility. */
 552.172 +void PNGAPI
 552.173 +png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
 552.174 +   png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
 552.175 +{
 552.176 +   if (png_ptr == NULL) return;
 552.177 +   png_ptr->io_ptr = io_ptr;
 552.178 +
 552.179 +#if !defined(PNG_NO_STDIO)
 552.180 +   if (write_data_fn != NULL)
 552.181 +      png_ptr->write_data_fn = write_data_fn;
 552.182 +   else
 552.183 +      png_ptr->write_data_fn = png_default_write_data;
 552.184 +#else
 552.185 +   png_ptr->write_data_fn = write_data_fn;
 552.186 +#endif
 552.187 +
 552.188 +#if defined(PNG_WRITE_FLUSH_SUPPORTED)
 552.189 +#if !defined(PNG_NO_STDIO)
 552.190 +   if (output_flush_fn != NULL)
 552.191 +      png_ptr->output_flush_fn = output_flush_fn;
 552.192 +   else
 552.193 +      png_ptr->output_flush_fn = png_default_flush;
 552.194 +#else
 552.195 +   png_ptr->output_flush_fn = output_flush_fn;
 552.196 +#endif
 552.197 +#endif /* PNG_WRITE_FLUSH_SUPPORTED */
 552.198 +
 552.199 +   /* It is an error to read while writing a png file */
 552.200 +   if (png_ptr->read_data_fn != NULL)
 552.201 +   {
 552.202 +      png_ptr->read_data_fn = NULL;
 552.203 +      png_warning(png_ptr,
 552.204 +         "Attempted to set both read_data_fn and write_data_fn in");
 552.205 +      png_warning(png_ptr,
 552.206 +         "the same structure.  Resetting read_data_fn to NULL.");
 552.207 +   }
 552.208 +}
 552.209 +
 552.210 +#if defined(USE_FAR_KEYWORD)
 552.211 +#if defined(_MSC_VER)
 552.212 +void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
 552.213 +{
 552.214 +   void *near_ptr;
 552.215 +   void FAR *far_ptr;
 552.216 +   FP_OFF(near_ptr) = FP_OFF(ptr);
 552.217 +   far_ptr = (void FAR *)near_ptr;
 552.218 +   if (check != 0)
 552.219 +      if (FP_SEG(ptr) != FP_SEG(far_ptr))
 552.220 +         png_error(png_ptr, "segment lost in conversion");
 552.221 +   return(near_ptr);
 552.222 +}
 552.223 +#  else
 552.224 +void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
 552.225 +{
 552.226 +   void *near_ptr;
 552.227 +   void FAR *far_ptr;
 552.228 +   near_ptr = (void FAR *)ptr;
 552.229 +   far_ptr = (void FAR *)near_ptr;
 552.230 +   if (check != 0)
 552.231 +      if (far_ptr != ptr)
 552.232 +         png_error(png_ptr, "segment lost in conversion");
 552.233 +   return(near_ptr);
 552.234 +}
 552.235 +#   endif
 552.236 +#   endif
 552.237 +#endif /* PNG_WRITE_SUPPORTED */
   553.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   553.2 +++ b/libs/libpng/pngwrite.c	Sat Feb 01 19:58:19 2014 +0200
   553.3 @@ -0,0 +1,1547 @@
   553.4 +
   553.5 +/* pngwrite.c - general routines to write a PNG file
   553.6 + *
   553.7 + * Last changed in libpng 1.2.31 [August 19, 2008]
   553.8 + * For conditions of distribution and use, see copyright notice in png.h
   553.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  553.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  553.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  553.12 + */
  553.13 +
  553.14 +/* get internal access to png.h */
  553.15 +#define PNG_INTERNAL
  553.16 +#include "png.h"
  553.17 +#ifdef PNG_WRITE_SUPPORTED
  553.18 +
  553.19 +/* Writes all the PNG information.  This is the suggested way to use the
  553.20 + * library.  If you have a new chunk to add, make a function to write it,
  553.21 + * and put it in the correct location here.  If you want the chunk written
  553.22 + * after the image data, put it in png_write_end().  I strongly encourage
  553.23 + * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
  553.24 + * the chunk, as that will keep the code from breaking if you want to just
  553.25 + * write a plain PNG file.  If you have long comments, I suggest writing
  553.26 + * them in png_write_end(), and compressing them.
  553.27 + */
  553.28 +void PNGAPI
  553.29 +png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
  553.30 +{
  553.31 +   png_debug(1, "in png_write_info_before_PLTE\n");
  553.32 +   if (png_ptr == NULL || info_ptr == NULL)
  553.33 +      return;
  553.34 +   if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
  553.35 +   {
  553.36 +   png_write_sig(png_ptr); /* write PNG signature */
  553.37 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
  553.38 +   if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted))
  553.39 +   {
  553.40 +      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
  553.41 +      png_ptr->mng_features_permitted=0;
  553.42 +   }
  553.43 +#endif
  553.44 +   /* write IHDR information. */
  553.45 +   png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
  553.46 +      info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
  553.47 +      info_ptr->filter_type,
  553.48 +#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
  553.49 +      info_ptr->interlace_type);
  553.50 +#else
  553.51 +      0);
  553.52 +#endif
  553.53 +   /* the rest of these check to see if the valid field has the appropriate
  553.54 +      flag set, and if it does, writes the chunk. */
  553.55 +#if defined(PNG_WRITE_gAMA_SUPPORTED)
  553.56 +   if (info_ptr->valid & PNG_INFO_gAMA)
  553.57 +   {
  553.58 +#  ifdef PNG_FLOATING_POINT_SUPPORTED
  553.59 +      png_write_gAMA(png_ptr, info_ptr->gamma);
  553.60 +#else
  553.61 +#ifdef PNG_FIXED_POINT_SUPPORTED
  553.62 +      png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
  553.63 +#  endif
  553.64 +#endif
  553.65 +   }
  553.66 +#endif
  553.67 +#if defined(PNG_WRITE_sRGB_SUPPORTED)
  553.68 +   if (info_ptr->valid & PNG_INFO_sRGB)
  553.69 +      png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
  553.70 +#endif
  553.71 +#if defined(PNG_WRITE_iCCP_SUPPORTED)
  553.72 +   if (info_ptr->valid & PNG_INFO_iCCP)
  553.73 +      png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
  553.74 +                     info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
  553.75 +#endif
  553.76 +#if defined(PNG_WRITE_sBIT_SUPPORTED)
  553.77 +   if (info_ptr->valid & PNG_INFO_sBIT)
  553.78 +      png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
  553.79 +#endif
  553.80 +#if defined(PNG_WRITE_cHRM_SUPPORTED)
  553.81 +   if (info_ptr->valid & PNG_INFO_cHRM)
  553.82 +   {
  553.83 +#ifdef PNG_FLOATING_POINT_SUPPORTED
  553.84 +      png_write_cHRM(png_ptr,
  553.85 +         info_ptr->x_white, info_ptr->y_white,
  553.86 +         info_ptr->x_red, info_ptr->y_red,
  553.87 +         info_ptr->x_green, info_ptr->y_green,
  553.88 +         info_ptr->x_blue, info_ptr->y_blue);
  553.89 +#else
  553.90 +#  ifdef PNG_FIXED_POINT_SUPPORTED
  553.91 +      png_write_cHRM_fixed(png_ptr,
  553.92 +         info_ptr->int_x_white, info_ptr->int_y_white,
  553.93 +         info_ptr->int_x_red, info_ptr->int_y_red,
  553.94 +         info_ptr->int_x_green, info_ptr->int_y_green,
  553.95 +         info_ptr->int_x_blue, info_ptr->int_y_blue);
  553.96 +#  endif
  553.97 +#endif
  553.98 +   }
  553.99 +#endif
 553.100 +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
 553.101 +   if (info_ptr->unknown_chunks_num)
 553.102 +   {
 553.103 +       png_unknown_chunk *up;
 553.104 +
 553.105 +       png_debug(5, "writing extra chunks\n");
 553.106 +
 553.107 +       for (up = info_ptr->unknown_chunks;
 553.108 +            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
 553.109 +            up++)
 553.110 +       {
 553.111 +         int keep=png_handle_as_unknown(png_ptr, up->name);
 553.112 +         if (keep != PNG_HANDLE_CHUNK_NEVER &&
 553.113 +            up->location && !(up->location & PNG_HAVE_PLTE) &&
 553.114 +            !(up->location & PNG_HAVE_IDAT) &&
 553.115 +            ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
 553.116 +            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
 553.117 +         {
 553.118 +            if (up->size == 0)
 553.119 +               png_warning(png_ptr, "Writing zero-length unknown chunk");
 553.120 +            png_write_chunk(png_ptr, up->name, up->data, up->size);
 553.121 +         }
 553.122 +       }
 553.123 +   }
 553.124 +#endif
 553.125 +      png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
 553.126 +   }
 553.127 +}
 553.128 +
 553.129 +void PNGAPI
 553.130 +png_write_info(png_structp png_ptr, png_infop info_ptr)
 553.131 +{
 553.132 +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
 553.133 +   int i;
 553.134 +#endif
 553.135 +
 553.136 +   png_debug(1, "in png_write_info\n");
 553.137 +
 553.138 +   if (png_ptr == NULL || info_ptr == NULL)
 553.139 +      return;
 553.140 +
 553.141 +   png_write_info_before_PLTE(png_ptr, info_ptr);
 553.142 +
 553.143 +   if (info_ptr->valid & PNG_INFO_PLTE)
 553.144 +      png_write_PLTE(png_ptr, info_ptr->palette,
 553.145 +         (png_uint_32)info_ptr->num_palette);
 553.146 +   else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 553.147 +      png_error(png_ptr, "Valid palette required for paletted images");
 553.148 +
 553.149 +#if defined(PNG_WRITE_tRNS_SUPPORTED)
 553.150 +   if (info_ptr->valid & PNG_INFO_tRNS)
 553.151 +      {
 553.152 +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
 553.153 +         /* invert the alpha channel (in tRNS) */
 553.154 +         if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
 553.155 +            info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 553.156 +         {
 553.157 +            int j;
 553.158 +            for (j=0; j<(int)info_ptr->num_trans; j++)
 553.159 +               info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
 553.160 +         }
 553.161 +#endif
 553.162 +      png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
 553.163 +         info_ptr->num_trans, info_ptr->color_type);
 553.164 +      }
 553.165 +#endif
 553.166 +#if defined(PNG_WRITE_bKGD_SUPPORTED)
 553.167 +   if (info_ptr->valid & PNG_INFO_bKGD)
 553.168 +      png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
 553.169 +#endif
 553.170 +#if defined(PNG_WRITE_hIST_SUPPORTED)
 553.171 +   if (info_ptr->valid & PNG_INFO_hIST)
 553.172 +      png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
 553.173 +#endif
 553.174 +#if defined(PNG_WRITE_oFFs_SUPPORTED)
 553.175 +   if (info_ptr->valid & PNG_INFO_oFFs)
 553.176 +      png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
 553.177 +         info_ptr->offset_unit_type);
 553.178 +#endif
 553.179 +#if defined(PNG_WRITE_pCAL_SUPPORTED)
 553.180 +   if (info_ptr->valid & PNG_INFO_pCAL)
 553.181 +      png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
 553.182 +         info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
 553.183 +         info_ptr->pcal_units, info_ptr->pcal_params);
 553.184 +#endif
 553.185 +#if defined(PNG_WRITE_sCAL_SUPPORTED)
 553.186 +   if (info_ptr->valid & PNG_INFO_sCAL)
 553.187 +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
 553.188 +      png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
 553.189 +          info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
 553.190 +#else
 553.191 +#ifdef PNG_FIXED_POINT_SUPPORTED
 553.192 +      png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
 553.193 +          info_ptr->scal_s_width, info_ptr->scal_s_height);
 553.194 +#else
 553.195 +      png_warning(png_ptr,
 553.196 +          "png_write_sCAL not supported; sCAL chunk not written.");
 553.197 +#endif
 553.198 +#endif
 553.199 +#endif
 553.200 +#if defined(PNG_WRITE_pHYs_SUPPORTED)
 553.201 +   if (info_ptr->valid & PNG_INFO_pHYs)
 553.202 +      png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
 553.203 +         info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
 553.204 +#endif
 553.205 +#if defined(PNG_WRITE_tIME_SUPPORTED)
 553.206 +   if (info_ptr->valid & PNG_INFO_tIME)
 553.207 +   {
 553.208 +      png_write_tIME(png_ptr, &(info_ptr->mod_time));
 553.209 +      png_ptr->mode |= PNG_WROTE_tIME;
 553.210 +   }
 553.211 +#endif
 553.212 +#if defined(PNG_WRITE_sPLT_SUPPORTED)
 553.213 +   if (info_ptr->valid & PNG_INFO_sPLT)
 553.214 +     for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
 553.215 +       png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
 553.216 +#endif
 553.217 +#if defined(PNG_WRITE_TEXT_SUPPORTED)
 553.218 +   /* Check to see if we need to write text chunks */
 553.219 +   for (i = 0; i < info_ptr->num_text; i++)
 553.220 +   {
 553.221 +      png_debug2(2, "Writing header text chunk %d, type %d\n", i,
 553.222 +         info_ptr->text[i].compression);
 553.223 +      /* an internationalized chunk? */
 553.224 +      if (info_ptr->text[i].compression > 0)
 553.225 +      {
 553.226 +#if defined(PNG_WRITE_iTXt_SUPPORTED)
 553.227 +          /* write international chunk */
 553.228 +          png_write_iTXt(png_ptr,
 553.229 +                         info_ptr->text[i].compression,
 553.230 +                         info_ptr->text[i].key,
 553.231 +                         info_ptr->text[i].lang,
 553.232 +                         info_ptr->text[i].lang_key,
 553.233 +                         info_ptr->text[i].text);
 553.234 +#else
 553.235 +          png_warning(png_ptr, "Unable to write international text");
 553.236 +#endif
 553.237 +          /* Mark this chunk as written */
 553.238 +          info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
 553.239 +      }
 553.240 +      /* If we want a compressed text chunk */
 553.241 +      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
 553.242 +      {
 553.243 +#if defined(PNG_WRITE_zTXt_SUPPORTED)
 553.244 +         /* write compressed chunk */
 553.245 +         png_write_zTXt(png_ptr, info_ptr->text[i].key,
 553.246 +            info_ptr->text[i].text, 0,
 553.247 +            info_ptr->text[i].compression);
 553.248 +#else
 553.249 +         png_warning(png_ptr, "Unable to write compressed text");
 553.250 +#endif
 553.251 +         /* Mark this chunk as written */
 553.252 +         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
 553.253 +      }
 553.254 +      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
 553.255 +      {
 553.256 +#if defined(PNG_WRITE_tEXt_SUPPORTED)
 553.257 +         /* write uncompressed chunk */
 553.258 +         png_write_tEXt(png_ptr, info_ptr->text[i].key,
 553.259 +                         info_ptr->text[i].text,
 553.260 +                         0);
 553.261 +#else
 553.262 +         png_warning(png_ptr, "Unable to write uncompressed text");
 553.263 +#endif
 553.264 +         /* Mark this chunk as written */
 553.265 +         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
 553.266 +      }
 553.267 +   }
 553.268 +#endif
 553.269 +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
 553.270 +   if (info_ptr->unknown_chunks_num)
 553.271 +   {
 553.272 +       png_unknown_chunk *up;
 553.273 +
 553.274 +       png_debug(5, "writing extra chunks\n");
 553.275 +
 553.276 +       for (up = info_ptr->unknown_chunks;
 553.277 +            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
 553.278 +            up++)
 553.279 +       {
 553.280 +         int keep=png_handle_as_unknown(png_ptr, up->name);
 553.281 +         if (keep != PNG_HANDLE_CHUNK_NEVER &&
 553.282 +            up->location && (up->location & PNG_HAVE_PLTE) &&
 553.283 +            !(up->location & PNG_HAVE_IDAT) &&
 553.284 +            ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
 553.285 +            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
 553.286 +         {
 553.287 +            png_write_chunk(png_ptr, up->name, up->data, up->size);
 553.288 +         }
 553.289 +       }
 553.290 +   }
 553.291 +#endif
 553.292 +}
 553.293 +
 553.294 +/* Writes the end of the PNG file.  If you don't want to write comments or
 553.295 + * time information, you can pass NULL for info.  If you already wrote these
 553.296 + * in png_write_info(), do not write them again here.  If you have long
 553.297 + * comments, I suggest writing them here, and compressing them.
 553.298 + */
 553.299 +void PNGAPI
 553.300 +png_write_end(png_structp png_ptr, png_infop info_ptr)
 553.301 +{
 553.302 +   png_debug(1, "in png_write_end\n");
 553.303 +   if (png_ptr == NULL)
 553.304 +      return;
 553.305 +   if (!(png_ptr->mode & PNG_HAVE_IDAT))
 553.306 +      png_error(png_ptr, "No IDATs written into file");
 553.307 +
 553.308 +   /* see if user wants us to write information chunks */
 553.309 +   if (info_ptr != NULL)
 553.310 +   {
 553.311 +#if defined(PNG_WRITE_TEXT_SUPPORTED)
 553.312 +      int i; /* local index variable */
 553.313 +#endif
 553.314 +#if defined(PNG_WRITE_tIME_SUPPORTED)
 553.315 +      /* check to see if user has supplied a time chunk */
 553.316 +      if ((info_ptr->valid & PNG_INFO_tIME) &&
 553.317 +         !(png_ptr->mode & PNG_WROTE_tIME))
 553.318 +         png_write_tIME(png_ptr, &(info_ptr->mod_time));
 553.319 +#endif
 553.320 +#if defined(PNG_WRITE_TEXT_SUPPORTED)
 553.321 +      /* loop through comment chunks */
 553.322 +      for (i = 0; i < info_ptr->num_text; i++)
 553.323 +      {
 553.324 +         png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
 553.325 +            info_ptr->text[i].compression);
 553.326 +         /* an internationalized chunk? */
 553.327 +         if (info_ptr->text[i].compression > 0)
 553.328 +         {
 553.329 +#if defined(PNG_WRITE_iTXt_SUPPORTED)
 553.330 +             /* write international chunk */
 553.331 +             png_write_iTXt(png_ptr,
 553.332 +                         info_ptr->text[i].compression,
 553.333 +                         info_ptr->text[i].key,
 553.334 +                         info_ptr->text[i].lang,
 553.335 +                         info_ptr->text[i].lang_key,
 553.336 +                         info_ptr->text[i].text);
 553.337 +#else
 553.338 +             png_warning(png_ptr, "Unable to write international text");
 553.339 +#endif
 553.340 +             /* Mark this chunk as written */
 553.341 +             info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
 553.342 +         }
 553.343 +         else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
 553.344 +         {
 553.345 +#if defined(PNG_WRITE_zTXt_SUPPORTED)
 553.346 +            /* write compressed chunk */
 553.347 +            png_write_zTXt(png_ptr, info_ptr->text[i].key,
 553.348 +               info_ptr->text[i].text, 0,
 553.349 +               info_ptr->text[i].compression);
 553.350 +#else
 553.351 +            png_warning(png_ptr, "Unable to write compressed text");
 553.352 +#endif
 553.353 +            /* Mark this chunk as written */
 553.354 +            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
 553.355 +         }
 553.356 +         else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
 553.357 +         {
 553.358 +#if defined(PNG_WRITE_tEXt_SUPPORTED)
 553.359 +            /* write uncompressed chunk */
 553.360 +            png_write_tEXt(png_ptr, info_ptr->text[i].key,
 553.361 +               info_ptr->text[i].text, 0);
 553.362 +#else
 553.363 +            png_warning(png_ptr, "Unable to write uncompressed text");
 553.364 +#endif
 553.365 +
 553.366 +            /* Mark this chunk as written */
 553.367 +            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
 553.368 +         }
 553.369 +      }
 553.370 +#endif
 553.371 +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
 553.372 +   if (info_ptr->unknown_chunks_num)
 553.373 +   {
 553.374 +       png_unknown_chunk *up;
 553.375 +
 553.376 +       png_debug(5, "writing extra chunks\n");
 553.377 +
 553.378 +       for (up = info_ptr->unknown_chunks;
 553.379 +            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
 553.380 +            up++)
 553.381 +       {
 553.382 +         int keep=png_handle_as_unknown(png_ptr, up->name);
 553.383 +         if (keep != PNG_HANDLE_CHUNK_NEVER &&
 553.384 +            up->location && (up->location & PNG_AFTER_IDAT) &&
 553.385 +            ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
 553.386 +            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
 553.387 +         {
 553.388 +            png_write_chunk(png_ptr, up->name, up->data, up->size);
 553.389 +         }
 553.390 +       }
 553.391 +   }
 553.392 +#endif
 553.393 +   }
 553.394 +
 553.395 +   png_ptr->mode |= PNG_AFTER_IDAT;
 553.396 +
 553.397 +   /* write end of PNG file */
 553.398 +   png_write_IEND(png_ptr);
 553.399 +   /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,
 553.400 +    * and restored again in libpng-1.2.30, may cause some applications that
 553.401 +    * do not set png_ptr->output_flush_fn to crash.  If your application
 553.402 +    * experiences a problem, please try building libpng with
 553.403 +    * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to
 553.404 +    * png-mng-implement at lists.sf.net .  This kludge will be removed
 553.405 +    * from libpng-1.4.0.
 553.406 +    */
 553.407 +#if defined(PNG_WRITE_FLUSH_SUPPORTED) && \
 553.408 +    defined(PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED)
 553.409 +   png_flush(png_ptr);
 553.410 +#endif
 553.411 +}
 553.412 +
 553.413 +#if defined(PNG_WRITE_tIME_SUPPORTED)
 553.414 +#if !defined(_WIN32_WCE)
 553.415 +/* "time.h" functions are not supported on WindowsCE */
 553.416 +void PNGAPI
 553.417 +png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
 553.418 +{
 553.419 +   png_debug(1, "in png_convert_from_struct_tm\n");
 553.420 +   ptime->year = (png_uint_16)(1900 + ttime->tm_year);
 553.421 +   ptime->month = (png_byte)(ttime->tm_mon + 1);
 553.422 +   ptime->day = (png_byte)ttime->tm_mday;
 553.423 +   ptime->hour = (png_byte)ttime->tm_hour;
 553.424 +   ptime->minute = (png_byte)ttime->tm_min;
 553.425 +   ptime->second = (png_byte)ttime->tm_sec;
 553.426 +}
 553.427 +
 553.428 +void PNGAPI
 553.429 +png_convert_from_time_t(png_timep ptime, time_t ttime)
 553.430 +{
 553.431 +   struct tm *tbuf;
 553.432 +
 553.433 +   png_debug(1, "in png_convert_from_time_t\n");
 553.434 +   tbuf = gmtime(&ttime);
 553.435 +   png_convert_from_struct_tm(ptime, tbuf);
 553.436 +}
 553.437 +#endif
 553.438 +#endif
 553.439 +
 553.440 +/* Initialize png_ptr structure, and allocate any memory needed */
 553.441 +png_structp PNGAPI
 553.442 +png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
 553.443 +   png_error_ptr error_fn, png_error_ptr warn_fn)
 553.444 +{
 553.445 +#ifdef PNG_USER_MEM_SUPPORTED
 553.446 +   return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
 553.447 +      warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
 553.448 +}
 553.449 +
 553.450 +/* Alternate initialize png_ptr structure, and allocate any memory needed */
 553.451 +png_structp PNGAPI
 553.452 +png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
 553.453 +   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
 553.454 +   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
 553.455 +{
 553.456 +#endif /* PNG_USER_MEM_SUPPORTED */
 553.457 +#ifdef PNG_SETJMP_SUPPORTED
 553.458 +    volatile
 553.459 +#endif
 553.460 +    png_structp png_ptr;
 553.461 +#ifdef PNG_SETJMP_SUPPORTED
 553.462 +#ifdef USE_FAR_KEYWORD
 553.463 +   jmp_buf jmpbuf;
 553.464 +#endif
 553.465 +#endif
 553.466 +   int i;
 553.467 +   png_debug(1, "in png_create_write_struct\n");
 553.468 +#ifdef PNG_USER_MEM_SUPPORTED
 553.469 +   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
 553.470 +      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
 553.471 +#else
 553.472 +   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
 553.473 +#endif /* PNG_USER_MEM_SUPPORTED */
 553.474 +   if (png_ptr == NULL)
 553.475 +      return (NULL);
 553.476 +
 553.477 +   /* added at libpng-1.2.6 */
 553.478 +#ifdef PNG_SET_USER_LIMITS_SUPPORTED
 553.479 +   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
 553.480 +   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
 553.481 +#endif
 553.482 +
 553.483 +#ifdef PNG_SETJMP_SUPPORTED
 553.484 +#ifdef USE_FAR_KEYWORD
 553.485 +   if (setjmp(jmpbuf))
 553.486 +#else
 553.487 +   if (setjmp(png_ptr->jmpbuf))
 553.488 +#endif
 553.489 +   {
 553.490 +      png_free(png_ptr, png_ptr->zbuf);
 553.491 +       png_ptr->zbuf=NULL;
 553.492 +      png_destroy_struct(png_ptr);
 553.493 +      return (NULL);
 553.494 +   }
 553.495 +#ifdef USE_FAR_KEYWORD
 553.496 +   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
 553.497 +#endif
 553.498 +#endif
 553.499 +
 553.500 +#ifdef PNG_USER_MEM_SUPPORTED
 553.501 +   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
 553.502 +#endif /* PNG_USER_MEM_SUPPORTED */
 553.503 +   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
 553.504 +
 553.505 +   if (user_png_ver)
 553.506 +   {
 553.507 +     i=0;
 553.508 +     do
 553.509 +     {
 553.510 +       if (user_png_ver[i] != png_libpng_ver[i])
 553.511 +          png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
 553.512 +     } while (png_libpng_ver[i++]);
 553.513 +   }
 553.514 +
 553.515 +   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
 553.516 +   {
 553.517 +     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
 553.518 +      * we must recompile any applications that use any older library version.
 553.519 +      * For versions after libpng 1.0, we will be compatible, so we need
 553.520 +      * only check the first digit.
 553.521 +      */
 553.522 +     if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
 553.523 +         (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
 553.524 +         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
 553.525 +     {
 553.526 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
 553.527 +        char msg[80];
 553.528 +        if (user_png_ver)
 553.529 +        {
 553.530 +          png_snprintf(msg, 80,
 553.531 +             "Application was compiled with png.h from libpng-%.20s",
 553.532 +             user_png_ver);
 553.533 +          png_warning(png_ptr, msg);
 553.534 +        }
 553.535 +        png_snprintf(msg, 80,
 553.536 +           "Application  is  running with png.c from libpng-%.20s",
 553.537 +           png_libpng_ver);
 553.538 +        png_warning(png_ptr, msg);
 553.539 +#endif
 553.540 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
 553.541 +        png_ptr->flags=0;
 553.542 +#endif
 553.543 +        png_error(png_ptr,
 553.544 +           "Incompatible libpng version in application and library");
 553.545 +     }
 553.546 +   }
 553.547 +
 553.548 +   /* initialize zbuf - compression buffer */
 553.549 +   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
 553.550 +   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
 553.551 +      (png_uint_32)png_ptr->zbuf_size);
 553.552 +
 553.553 +   png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
 553.554 +      png_flush_ptr_NULL);
 553.555 +
 553.556 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
 553.557 +   png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
 553.558 +      1, png_doublep_NULL, png_doublep_NULL);
 553.559 +#endif
 553.560 +
 553.561 +#ifdef PNG_SETJMP_SUPPORTED
 553.562 +/* Applications that neglect to set up their own setjmp() and then encounter
 553.563 +   a png_error() will longjmp here.  Since the jmpbuf is then meaningless we
 553.564 +   abort instead of returning. */
 553.565 +#ifdef USE_FAR_KEYWORD
 553.566 +   if (setjmp(jmpbuf))
 553.567 +      PNG_ABORT();
 553.568 +   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
 553.569 +#else
 553.570 +   if (setjmp(png_ptr->jmpbuf))
 553.571 +      PNG_ABORT();
 553.572 +#endif
 553.573 +#endif
 553.574 +   return (png_ptr);
 553.575 +}
 553.576 +
 553.577 +/* Initialize png_ptr structure, and allocate any memory needed */
 553.578 +#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
 553.579 +/* Deprecated. */
 553.580 +#undef png_write_init
 553.581 +void PNGAPI
 553.582 +png_write_init(png_structp png_ptr)
 553.583 +{
 553.584 +   /* We only come here via pre-1.0.7-compiled applications */
 553.585 +   png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
 553.586 +}
 553.587 +
 553.588 +void PNGAPI
 553.589 +png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
 553.590 +   png_size_t png_struct_size, png_size_t png_info_size)
 553.591 +{
 553.592 +   /* We only come here via pre-1.0.12-compiled applications */
 553.593 +   if (png_ptr == NULL) return;
 553.594 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
 553.595 +   if (png_sizeof(png_struct) > png_struct_size ||
 553.596 +      png_sizeof(png_info) > png_info_size)
 553.597 +   {
 553.598 +      char msg[80];
 553.599 +      png_ptr->warning_fn=NULL;
 553.600 +      if (user_png_ver)
 553.601 +      {
 553.602 +        png_snprintf(msg, 80,
 553.603 +           "Application was compiled with png.h from libpng-%.20s",
 553.604 +           user_png_ver);
 553.605 +        png_warning(png_ptr, msg);
 553.606 +      }
 553.607 +      png_snprintf(msg, 80,
 553.608 +         "Application  is  running with png.c from libpng-%.20s",
 553.609 +         png_libpng_ver);
 553.610 +      png_warning(png_ptr, msg);
 553.611 +   }
 553.612 +#endif
 553.613 +   if (png_sizeof(png_struct) > png_struct_size)
 553.614 +     {
 553.615 +       png_ptr->error_fn=NULL;
 553.616 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
 553.617 +       png_ptr->flags=0;
 553.618 +#endif
 553.619 +       png_error(png_ptr,
 553.620 +       "The png struct allocated by the application for writing is too small.");
 553.621 +     }
 553.622 +   if (png_sizeof(png_info) > png_info_size)
 553.623 +     {
 553.624 +       png_ptr->error_fn=NULL;
 553.625 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
 553.626 +       png_ptr->flags=0;
 553.627 +#endif
 553.628 +       png_error(png_ptr,
 553.629 +       "The info struct allocated by the application for writing is too small.");
 553.630 +     }
 553.631 +   png_write_init_3(&png_ptr, user_png_ver, png_struct_size);
 553.632 +}
 553.633 +#endif /* PNG_1_0_X || PNG_1_2_X */
 553.634 +
 553.635 +
 553.636 +void PNGAPI
 553.637 +png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
 553.638 +   png_size_t png_struct_size)
 553.639 +{
 553.640 +   png_structp png_ptr=*ptr_ptr;
 553.641 +#ifdef PNG_SETJMP_SUPPORTED
 553.642 +   jmp_buf tmp_jmp; /* to save current jump buffer */
 553.643 +#endif
 553.644 +
 553.645 +   int i = 0;
 553.646 +
 553.647 +   if (png_ptr == NULL)
 553.648 +      return;
 553.649 +
 553.650 +   do
 553.651 +   {
 553.652 +     if (user_png_ver[i] != png_libpng_ver[i])
 553.653 +     {
 553.654 +#ifdef PNG_LEGACY_SUPPORTED
 553.655 +       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
 553.656 +#else
 553.657 +       png_ptr->warning_fn=NULL;
 553.658 +       png_warning(png_ptr,
 553.659 + "Application uses deprecated png_write_init() and should be recompiled.");
 553.660 +       break;
 553.661 +#endif
 553.662 +     }
 553.663 +   } while (png_libpng_ver[i++]);
 553.664 +
 553.665 +   png_debug(1, "in png_write_init_3\n");
 553.666 +
 553.667 +#ifdef PNG_SETJMP_SUPPORTED
 553.668 +   /* save jump buffer and error functions */
 553.669 +   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
 553.670 +#endif
 553.671 +
 553.672 +   if (png_sizeof(png_struct) > png_struct_size)
 553.673 +     {
 553.674 +       png_destroy_struct(png_ptr);
 553.675 +       png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
 553.676 +       *ptr_ptr = png_ptr;
 553.677 +     }
 553.678 +
 553.679 +   /* reset all variables to 0 */
 553.680 +   png_memset(png_ptr, 0, png_sizeof(png_struct));
 553.681 +
 553.682 +   /* added at libpng-1.2.6 */
 553.683 +#ifdef PNG_SET_USER_LIMITS_SUPPORTED
 553.684 +   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
 553.685 +   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
 553.686 +#endif
 553.687 +
 553.688 +#ifdef PNG_SETJMP_SUPPORTED
 553.689 +   /* restore jump buffer */
 553.690 +   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
 553.691 +#endif
 553.692 +
 553.693 +   png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
 553.694 +      png_flush_ptr_NULL);
 553.695 +
 553.696 +   /* initialize zbuf - compression buffer */
 553.697 +   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
 553.698 +   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
 553.699 +      (png_uint_32)png_ptr->zbuf_size);
 553.700 +
 553.701 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
 553.702 +   png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
 553.703 +      1, png_doublep_NULL, png_doublep_NULL);
 553.704 +#endif
 553.705 +}
 553.706 +
 553.707 +/* Write a few rows of image data.  If the image is interlaced,
 553.708 + * either you will have to write the 7 sub images, or, if you
 553.709 + * have called png_set_interlace_handling(), you will have to
 553.710 + * "write" the image seven times.
 553.711 + */
 553.712 +void PNGAPI
 553.713 +png_write_rows(png_structp png_ptr, png_bytepp row,
 553.714 +   png_uint_32 num_rows)
 553.715 +{
 553.716 +   png_uint_32 i; /* row counter */
 553.717 +   png_bytepp rp; /* row pointer */
 553.718 +
 553.719 +   png_debug(1, "in png_write_rows\n");
 553.720 +
 553.721 +   if (png_ptr == NULL)
 553.722 +      return;
 553.723 +
 553.724 +   /* loop through the rows */
 553.725 +   for (i = 0, rp = row; i < num_rows; i++, rp++)
 553.726 +   {
 553.727 +      png_write_row(png_ptr, *rp);
 553.728 +   }
 553.729 +}
 553.730 +
 553.731 +/* Write the image.  You only need to call this function once, even
 553.732 + * if you are writing an interlaced image.
 553.733 + */
 553.734 +void PNGAPI
 553.735 +png_write_image(png_structp png_ptr, png_bytepp image)
 553.736 +{
 553.737 +   png_uint_32 i; /* row index */
 553.738 +   int pass, num_pass; /* pass variables */
 553.739 +   png_bytepp rp; /* points to current row */
 553.740 +
 553.741 +   if (png_ptr == NULL)
 553.742 +      return;
 553.743 +
 553.744 +   png_debug(1, "in png_write_image\n");
 553.745 +#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
 553.746 +   /* intialize interlace handling.  If image is not interlaced,
 553.747 +      this will set pass to 1 */
 553.748 +   num_pass = png_set_interlace_handling(png_ptr);
 553.749 +#else
 553.750 +   num_pass = 1;
 553.751 +#endif
 553.752 +   /* loop through passes */
 553.753 +   for (pass = 0; pass < num_pass; pass++)
 553.754 +   {
 553.755 +      /* loop through image */
 553.756 +      for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
 553.757 +      {
 553.758 +         png_write_row(png_ptr, *rp);
 553.759 +      }
 553.760 +   }
 553.761 +}
 553.762 +
 553.763 +/* called by user to write a row of image data */
 553.764 +void PNGAPI
 553.765 +png_write_row(png_structp png_ptr, png_bytep row)
 553.766 +{
 553.767 +   if (png_ptr == NULL)
 553.768 +      return;
 553.769 +   png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
 553.770 +      png_ptr->row_number, png_ptr->pass);
 553.771 +
 553.772 +   /* initialize transformations and other stuff if first time */
 553.773 +   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
 553.774 +   {
 553.775 +   /* make sure we wrote the header info */
 553.776 +   if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
 553.777 +      png_error(png_ptr,
 553.778 +         "png_write_info was never called before png_write_row.");
 553.779 +
 553.780 +   /* check for transforms that have been set but were defined out */
 553.781 +#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
 553.782 +   if (png_ptr->transformations & PNG_INVERT_MONO)
 553.783 +      png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined.");
 553.784 +#endif
 553.785 +#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
 553.786 +   if (png_ptr->transformations & PNG_FILLER)
 553.787 +      png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined.");
 553.788 +#endif
 553.789 +#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED)
 553.790 +   if (png_ptr->transformations & PNG_PACKSWAP)
 553.791 +      png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
 553.792 +#endif
 553.793 +#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
 553.794 +   if (png_ptr->transformations & PNG_PACK)
 553.795 +      png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
 553.796 +#endif
 553.797 +#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
 553.798 +   if (png_ptr->transformations & PNG_SHIFT)
 553.799 +      png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
 553.800 +#endif
 553.801 +#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
 553.802 +   if (png_ptr->transformations & PNG_BGR)
 553.803 +      png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
 553.804 +#endif
 553.805 +#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
 553.806 +   if (png_ptr->transformations & PNG_SWAP_BYTES)
 553.807 +      png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
 553.808 +#endif
 553.809 +
 553.810 +      png_write_start_row(png_ptr);
 553.811 +   }
 553.812 +
 553.813 +#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
 553.814 +   /* if interlaced and not interested in row, return */
 553.815 +   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
 553.816 +   {
 553.817 +      switch (png_ptr->pass)
 553.818 +      {
 553.819 +         case 0:
 553.820 +            if (png_ptr->row_number & 0x07)
 553.821 +            {
 553.822 +               png_write_finish_row(png_ptr);
 553.823 +               return;
 553.824 +            }
 553.825 +            break;
 553.826 +         case 1:
 553.827 +            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
 553.828 +            {
 553.829 +               png_write_finish_row(png_ptr);
 553.830 +               return;
 553.831 +            }
 553.832 +            break;
 553.833 +         case 2:
 553.834 +            if ((png_ptr->row_number & 0x07) != 4)
 553.835 +            {
 553.836 +               png_write_finish_row(png_ptr);
 553.837 +               return;
 553.838 +            }
 553.839 +            break;
 553.840 +         case 3:
 553.841 +            if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
 553.842 +            {
 553.843 +               png_write_finish_row(png_ptr);
 553.844 +               return;
 553.845 +            }
 553.846 +            break;
 553.847 +         case 4:
 553.848 +            if ((png_ptr->row_number & 0x03) != 2)
 553.849 +            {
 553.850 +               png_write_finish_row(png_ptr);
 553.851 +               return;
 553.852 +            }
 553.853 +            break;
 553.854 +         case 5:
 553.855 +            if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
 553.856 +            {
 553.857 +               png_write_finish_row(png_ptr);
 553.858 +               return;
 553.859 +            }
 553.860 +            break;
 553.861 +         case 6:
 553.862 +            if (!(png_ptr->row_number & 0x01))
 553.863 +            {
 553.864 +               png_write_finish_row(png_ptr);
 553.865 +               return;
 553.866 +            }
 553.867 +            break;
 553.868 +      }
 553.869 +   }
 553.870 +#endif
 553.871 +
 553.872 +   /* set up row info for transformations */
 553.873 +   png_ptr->row_info.color_type = png_ptr->color_type;
 553.874 +   png_ptr->row_info.width = png_ptr->usr_width;
 553.875 +   png_ptr->row_info.channels = png_ptr->usr_channels;
 553.876 +   png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
 553.877 +   png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
 553.878 +      png_ptr->row_info.channels);
 553.879 +
 553.880 +   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
 553.881 +      png_ptr->row_info.width);
 553.882 +
 553.883 +   png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
 553.884 +   png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width);
 553.885 +   png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
 553.886 +   png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
 553.887 +   png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
 553.888 +   png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes);
 553.889 +
 553.890 +   /* Copy user's row into buffer, leaving room for filter byte. */
 553.891 +   png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
 553.892 +      png_ptr->row_info.rowbytes);
 553.893 +
 553.894 +#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
 553.895 +   /* handle interlacing */
 553.896 +   if (png_ptr->interlaced && png_ptr->pass < 6 &&
 553.897 +      (png_ptr->transformations & PNG_INTERLACE))
 553.898 +   {
 553.899 +      png_do_write_interlace(&(png_ptr->row_info),
 553.900 +         png_ptr->row_buf + 1, png_ptr->pass);
 553.901 +      /* this should always get caught above, but still ... */
 553.902 +      if (!(png_ptr->row_info.width))
 553.903 +      {
 553.904 +         png_write_finish_row(png_ptr);
 553.905 +         return;
 553.906 +      }
 553.907 +   }
 553.908 +#endif
 553.909 +
 553.910 +   /* handle other transformations */
 553.911 +   if (png_ptr->transformations)
 553.912 +      png_do_write_transformations(png_ptr);
 553.913 +
 553.914 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
 553.915 +   /* Write filter_method 64 (intrapixel differencing) only if
 553.916 +    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
 553.917 +    * 2. Libpng did not write a PNG signature (this filter_method is only
 553.918 +    *    used in PNG datastreams that are embedded in MNG datastreams) and
 553.919 +    * 3. The application called png_permit_mng_features with a mask that
 553.920 +    *    included PNG_FLAG_MNG_FILTER_64 and
 553.921 +    * 4. The filter_method is 64 and
 553.922 +    * 5. The color_type is RGB or RGBA
 553.923 +    */
 553.924 +   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
 553.925 +      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
 553.926 +   {
 553.927 +      /* Intrapixel differencing */
 553.928 +      png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
 553.929 +   }
 553.930 +#endif
 553.931 +
 553.932 +   /* Find a filter if necessary, filter the row and write it out. */
 553.933 +   png_write_find_filter(png_ptr, &(png_ptr->row_info));
 553.934 +
 553.935 +   if (png_ptr->write_row_fn != NULL)
 553.936 +      (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
 553.937 +}
 553.938 +
 553.939 +#if defined(PNG_WRITE_FLUSH_SUPPORTED)
 553.940 +/* Set the automatic flush interval or 0 to turn flushing off */
 553.941 +void PNGAPI
 553.942 +png_set_flush(png_structp png_ptr, int nrows)
 553.943 +{
 553.944 +   png_debug(1, "in png_set_flush\n");
 553.945 +   if (png_ptr == NULL)
 553.946 +      return;
 553.947 +   png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
 553.948 +}
 553.949 +
 553.950 +/* flush the current output buffers now */
 553.951 +void PNGAPI
 553.952 +png_write_flush(png_structp png_ptr)
 553.953 +{
 553.954 +   int wrote_IDAT;
 553.955 +
 553.956 +   png_debug(1, "in png_write_flush\n");
 553.957 +   if (png_ptr == NULL)
 553.958 +      return;
 553.959 +   /* We have already written out all of the data */
 553.960 +   if (png_ptr->row_number >= png_ptr->num_rows)
 553.961 +     return;
 553.962 +
 553.963 +   do
 553.964 +   {
 553.965 +      int ret;
 553.966 +
 553.967 +      /* compress the data */
 553.968 +      ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
 553.969 +      wrote_IDAT = 0;
 553.970 +
 553.971 +      /* check for compression errors */
 553.972 +      if (ret != Z_OK)
 553.973 +      {
 553.974 +         if (png_ptr->zstream.msg != NULL)
 553.975 +            png_error(png_ptr, png_ptr->zstream.msg);
 553.976 +         else
 553.977 +            png_error(png_ptr, "zlib error");
 553.978 +      }
 553.979 +
 553.980 +      if (!(png_ptr->zstream.avail_out))
 553.981 +      {
 553.982 +         /* write the IDAT and reset the zlib output buffer */
 553.983 +         png_write_IDAT(png_ptr, png_ptr->zbuf,
 553.984 +                        png_ptr->zbuf_size);
 553.985 +         png_ptr->zstream.next_out = png_ptr->zbuf;
 553.986 +         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
 553.987 +         wrote_IDAT = 1;
 553.988 +      }
 553.989 +   } while(wrote_IDAT == 1);
 553.990 +
 553.991 +   /* If there is any data left to be output, write it into a new IDAT */
 553.992 +   if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
 553.993 +   {
 553.994 +      /* write the IDAT and reset the zlib output buffer */
 553.995 +      png_write_IDAT(png_ptr, png_ptr->zbuf,
 553.996 +                     png_ptr->zbuf_size - png_ptr->zstream.avail_out);
 553.997 +      png_ptr->zstream.next_out = png_ptr->zbuf;
 553.998 +      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
 553.999 +   }
553.1000 +   png_ptr->flush_rows = 0;
553.1001 +   png_flush(png_ptr);
553.1002 +}
553.1003 +#endif /* PNG_WRITE_FLUSH_SUPPORTED */
553.1004 +
553.1005 +/* free all memory used by the write */
553.1006 +void PNGAPI
553.1007 +png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
553.1008 +{
553.1009 +   png_structp png_ptr = NULL;
553.1010 +   png_infop info_ptr = NULL;
553.1011 +#ifdef PNG_USER_MEM_SUPPORTED
553.1012 +   png_free_ptr free_fn = NULL;
553.1013 +   png_voidp mem_ptr = NULL;
553.1014 +#endif
553.1015 +
553.1016 +   png_debug(1, "in png_destroy_write_struct\n");
553.1017 +   if (png_ptr_ptr != NULL)
553.1018 +   {
553.1019 +      png_ptr = *png_ptr_ptr;
553.1020 +#ifdef PNG_USER_MEM_SUPPORTED
553.1021 +      free_fn = png_ptr->free_fn;
553.1022 +      mem_ptr = png_ptr->mem_ptr;
553.1023 +#endif
553.1024 +   }
553.1025 +
553.1026 +#ifdef PNG_USER_MEM_SUPPORTED
553.1027 +   if (png_ptr != NULL)
553.1028 +   {
553.1029 +      free_fn = png_ptr->free_fn;
553.1030 +      mem_ptr = png_ptr->mem_ptr;
553.1031 +   }
553.1032 +#endif
553.1033 +
553.1034 +   if (info_ptr_ptr != NULL)
553.1035 +      info_ptr = *info_ptr_ptr;
553.1036 +
553.1037 +   if (info_ptr != NULL)
553.1038 +   {
553.1039 +      if (png_ptr != NULL)
553.1040 +      {
553.1041 +        png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
553.1042 +
553.1043 +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
553.1044 +        if (png_ptr->num_chunk_list)
553.1045 +        {
553.1046 +           png_free(png_ptr, png_ptr->chunk_list);
553.1047 +           png_ptr->chunk_list=NULL;
553.1048 +           png_ptr->num_chunk_list = 0;
553.1049 +        }
553.1050 +#endif
553.1051 +      }
553.1052 +
553.1053 +#ifdef PNG_USER_MEM_SUPPORTED
553.1054 +      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
553.1055 +         (png_voidp)mem_ptr);
553.1056 +#else
553.1057 +      png_destroy_struct((png_voidp)info_ptr);
553.1058 +#endif
553.1059 +      *info_ptr_ptr = NULL;
553.1060 +   }
553.1061 +
553.1062 +   if (png_ptr != NULL)
553.1063 +   {
553.1064 +      png_write_destroy(png_ptr);
553.1065 +#ifdef PNG_USER_MEM_SUPPORTED
553.1066 +      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
553.1067 +         (png_voidp)mem_ptr);
553.1068 +#else
553.1069 +      png_destroy_struct((png_voidp)png_ptr);
553.1070 +#endif
553.1071 +      *png_ptr_ptr = NULL;
553.1072 +   }
553.1073 +}
553.1074 +
553.1075 +
553.1076 +/* Free any memory used in png_ptr struct (old method) */
553.1077 +void /* PRIVATE */
553.1078 +png_write_destroy(png_structp png_ptr)
553.1079 +{
553.1080 +#ifdef PNG_SETJMP_SUPPORTED
553.1081 +   jmp_buf tmp_jmp; /* save jump buffer */
553.1082 +#endif
553.1083 +   png_error_ptr error_fn;
553.1084 +   png_error_ptr warning_fn;
553.1085 +   png_voidp error_ptr;
553.1086 +#ifdef PNG_USER_MEM_SUPPORTED
553.1087 +   png_free_ptr free_fn;
553.1088 +#endif
553.1089 +
553.1090 +   png_debug(1, "in png_write_destroy\n");
553.1091 +   /* free any memory zlib uses */
553.1092 +   deflateEnd(&png_ptr->zstream);
553.1093 +
553.1094 +   /* free our memory.  png_free checks NULL for us. */
553.1095 +   png_free(png_ptr, png_ptr->zbuf);
553.1096 +   png_free(png_ptr, png_ptr->row_buf);
553.1097 +#ifndef PNG_NO_WRITE_FILTER
553.1098 +   png_free(png_ptr, png_ptr->prev_row);
553.1099 +   png_free(png_ptr, png_ptr->sub_row);
553.1100 +   png_free(png_ptr, png_ptr->up_row);
553.1101 +   png_free(png_ptr, png_ptr->avg_row);
553.1102 +   png_free(png_ptr, png_ptr->paeth_row);
553.1103 +#endif
553.1104 +
553.1105 +#if defined(PNG_TIME_RFC1123_SUPPORTED)
553.1106 +   png_free(png_ptr, png_ptr->time_buffer);
553.1107 +#endif
553.1108 +
553.1109 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
553.1110 +   png_free(png_ptr, png_ptr->prev_filters);
553.1111 +   png_free(png_ptr, png_ptr->filter_weights);
553.1112 +   png_free(png_ptr, png_ptr->inv_filter_weights);
553.1113 +   png_free(png_ptr, png_ptr->filter_costs);
553.1114 +   png_free(png_ptr, png_ptr->inv_filter_costs);
553.1115 +#endif
553.1116 +
553.1117 +#ifdef PNG_SETJMP_SUPPORTED
553.1118 +   /* reset structure */
553.1119 +   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
553.1120 +#endif
553.1121 +
553.1122 +   error_fn = png_ptr->error_fn;
553.1123 +   warning_fn = png_ptr->warning_fn;
553.1124 +   error_ptr = png_ptr->error_ptr;
553.1125 +#ifdef PNG_USER_MEM_SUPPORTED
553.1126 +   free_fn = png_ptr->free_fn;
553.1127 +#endif
553.1128 +
553.1129 +   png_memset(png_ptr, 0, png_sizeof(png_struct));
553.1130 +
553.1131 +   png_ptr->error_fn = error_fn;
553.1132 +   png_ptr->warning_fn = warning_fn;
553.1133 +   png_ptr->error_ptr = error_ptr;
553.1134 +#ifdef PNG_USER_MEM_SUPPORTED
553.1135 +   png_ptr->free_fn = free_fn;
553.1136 +#endif
553.1137 +
553.1138 +#ifdef PNG_SETJMP_SUPPORTED
553.1139 +   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
553.1140 +#endif
553.1141 +}
553.1142 +
553.1143 +/* Allow the application to select one or more row filters to use. */
553.1144 +void PNGAPI
553.1145 +png_set_filter(png_structp png_ptr, int method, int filters)
553.1146 +{
553.1147 +   png_debug(1, "in png_set_filter\n");
553.1148 +   if (png_ptr == NULL)
553.1149 +      return;
553.1150 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
553.1151 +   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
553.1152 +      (method == PNG_INTRAPIXEL_DIFFERENCING))
553.1153 +         method = PNG_FILTER_TYPE_BASE;
553.1154 +#endif
553.1155 +   if (method == PNG_FILTER_TYPE_BASE)
553.1156 +   {
553.1157 +      switch (filters & (PNG_ALL_FILTERS | 0x07))
553.1158 +      {
553.1159 +#ifndef PNG_NO_WRITE_FILTER
553.1160 +         case 5:
553.1161 +         case 6:
553.1162 +         case 7: png_warning(png_ptr, "Unknown row filter for method 0");
553.1163 +#endif /* PNG_NO_WRITE_FILTER */
553.1164 +         case PNG_FILTER_VALUE_NONE:
553.1165 +              png_ptr->do_filter=PNG_FILTER_NONE; break;
553.1166 +#ifndef PNG_NO_WRITE_FILTER
553.1167 +         case PNG_FILTER_VALUE_SUB:
553.1168 +              png_ptr->do_filter=PNG_FILTER_SUB; break;
553.1169 +         case PNG_FILTER_VALUE_UP:
553.1170 +              png_ptr->do_filter=PNG_FILTER_UP; break;
553.1171 +         case PNG_FILTER_VALUE_AVG:
553.1172 +              png_ptr->do_filter=PNG_FILTER_AVG; break;
553.1173 +         case PNG_FILTER_VALUE_PAETH:
553.1174 +              png_ptr->do_filter=PNG_FILTER_PAETH; break;
553.1175 +         default: png_ptr->do_filter = (png_byte)filters; break;
553.1176 +#else
553.1177 +         default: png_warning(png_ptr, "Unknown row filter for method 0");
553.1178 +#endif /* PNG_NO_WRITE_FILTER */
553.1179 +      }
553.1180 +
553.1181 +      /* If we have allocated the row_buf, this means we have already started
553.1182 +       * with the image and we should have allocated all of the filter buffers
553.1183 +       * that have been selected.  If prev_row isn't already allocated, then
553.1184 +       * it is too late to start using the filters that need it, since we
553.1185 +       * will be missing the data in the previous row.  If an application
553.1186 +       * wants to start and stop using particular filters during compression,
553.1187 +       * it should start out with all of the filters, and then add and
553.1188 +       * remove them after the start of compression.
553.1189 +       */
553.1190 +      if (png_ptr->row_buf != NULL)
553.1191 +      {
553.1192 +#ifndef PNG_NO_WRITE_FILTER
553.1193 +         if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
553.1194 +         {
553.1195 +            png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
553.1196 +              (png_ptr->rowbytes + 1));
553.1197 +            png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
553.1198 +         }
553.1199 +
553.1200 +         if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
553.1201 +         {
553.1202 +            if (png_ptr->prev_row == NULL)
553.1203 +            {
553.1204 +               png_warning(png_ptr, "Can't add Up filter after starting");
553.1205 +               png_ptr->do_filter &= ~PNG_FILTER_UP;
553.1206 +            }
553.1207 +            else
553.1208 +            {
553.1209 +               png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
553.1210 +                  (png_ptr->rowbytes + 1));
553.1211 +               png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
553.1212 +            }
553.1213 +         }
553.1214 +
553.1215 +         if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
553.1216 +         {
553.1217 +            if (png_ptr->prev_row == NULL)
553.1218 +            {
553.1219 +               png_warning(png_ptr, "Can't add Average filter after starting");
553.1220 +               png_ptr->do_filter &= ~PNG_FILTER_AVG;
553.1221 +            }
553.1222 +            else
553.1223 +            {
553.1224 +               png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
553.1225 +                  (png_ptr->rowbytes + 1));
553.1226 +               png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
553.1227 +            }
553.1228 +         }
553.1229 +
553.1230 +         if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
553.1231 +             png_ptr->paeth_row == NULL)
553.1232 +         {
553.1233 +            if (png_ptr->prev_row == NULL)
553.1234 +            {
553.1235 +               png_warning(png_ptr, "Can't add Paeth filter after starting");
553.1236 +               png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
553.1237 +            }
553.1238 +            else
553.1239 +            {
553.1240 +               png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
553.1241 +                  (png_ptr->rowbytes + 1));
553.1242 +               png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
553.1243 +            }
553.1244 +         }
553.1245 +
553.1246 +         if (png_ptr->do_filter == PNG_NO_FILTERS)
553.1247 +#endif /* PNG_NO_WRITE_FILTER */
553.1248 +            png_ptr->do_filter = PNG_FILTER_NONE;
553.1249 +      }
553.1250 +   }
553.1251 +   else
553.1252 +      png_error(png_ptr, "Unknown custom filter method");
553.1253 +}
553.1254 +
553.1255 +/* This allows us to influence the way in which libpng chooses the "best"
553.1256 + * filter for the current scanline.  While the "minimum-sum-of-absolute-
553.1257 + * differences metric is relatively fast and effective, there is some
553.1258 + * question as to whether it can be improved upon by trying to keep the
553.1259 + * filtered data going to zlib more consistent, hopefully resulting in
553.1260 + * better compression.
553.1261 + */
553.1262 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)      /* GRR 970116 */
553.1263 +void PNGAPI
553.1264 +png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
553.1265 +   int num_weights, png_doublep filter_weights,
553.1266 +   png_doublep filter_costs)
553.1267 +{
553.1268 +   int i;
553.1269 +
553.1270 +   png_debug(1, "in png_set_filter_heuristics\n");
553.1271 +   if (png_ptr == NULL)
553.1272 +      return;
553.1273 +   if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
553.1274 +   {
553.1275 +      png_warning(png_ptr, "Unknown filter heuristic method");
553.1276 +      return;
553.1277 +   }
553.1278 +
553.1279 +   if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
553.1280 +   {
553.1281 +      heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
553.1282 +   }
553.1283 +
553.1284 +   if (num_weights < 0 || filter_weights == NULL ||
553.1285 +      heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
553.1286 +   {
553.1287 +      num_weights = 0;
553.1288 +   }
553.1289 +
553.1290 +   png_ptr->num_prev_filters = (png_byte)num_weights;
553.1291 +   png_ptr->heuristic_method = (png_byte)heuristic_method;
553.1292 +
553.1293 +   if (num_weights > 0)
553.1294 +   {
553.1295 +      if (png_ptr->prev_filters == NULL)
553.1296 +      {
553.1297 +         png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
553.1298 +            (png_uint_32)(png_sizeof(png_byte) * num_weights));
553.1299 +
553.1300 +         /* To make sure that the weighting starts out fairly */
553.1301 +         for (i = 0; i < num_weights; i++)
553.1302 +         {
553.1303 +            png_ptr->prev_filters[i] = 255;
553.1304 +         }
553.1305 +      }
553.1306 +
553.1307 +      if (png_ptr->filter_weights == NULL)
553.1308 +      {
553.1309 +         png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
553.1310 +            (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
553.1311 +
553.1312 +         png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
553.1313 +            (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
553.1314 +         for (i = 0; i < num_weights; i++)
553.1315 +         {
553.1316 +            png_ptr->inv_filter_weights[i] =
553.1317 +            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
553.1318 +         }
553.1319 +      }
553.1320 +
553.1321 +      for (i = 0; i < num_weights; i++)
553.1322 +      {
553.1323 +         if (filter_weights[i] < 0.0)
553.1324 +         {
553.1325 +            png_ptr->inv_filter_weights[i] =
553.1326 +            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
553.1327 +         }
553.1328 +         else
553.1329 +         {
553.1330 +            png_ptr->inv_filter_weights[i] =
553.1331 +               (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
553.1332 +            png_ptr->filter_weights[i] =
553.1333 +               (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
553.1334 +         }
553.1335 +      }
553.1336 +   }
553.1337 +
553.1338 +   /* If, in the future, there are other filter methods, this would
553.1339 +    * need to be based on png_ptr->filter.
553.1340 +    */
553.1341 +   if (png_ptr->filter_costs == NULL)
553.1342 +   {
553.1343 +      png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
553.1344 +         (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
553.1345 +
553.1346 +      png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
553.1347 +         (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
553.1348 +
553.1349 +      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
553.1350 +      {
553.1351 +         png_ptr->inv_filter_costs[i] =
553.1352 +         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
553.1353 +      }
553.1354 +   }
553.1355 +
553.1356 +   /* Here is where we set the relative costs of the different filters.  We
553.1357 +    * should take the desired compression level into account when setting
553.1358 +    * the costs, so that Paeth, for instance, has a high relative cost at low
553.1359 +    * compression levels, while it has a lower relative cost at higher
553.1360 +    * compression settings.  The filter types are in order of increasing
553.1361 +    * relative cost, so it would be possible to do this with an algorithm.
553.1362 +    */
553.1363 +   for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
553.1364 +   {
553.1365 +      if (filter_costs == NULL || filter_costs[i] < 0.0)
553.1366 +      {
553.1367 +         png_ptr->inv_filter_costs[i] =
553.1368 +         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
553.1369 +      }
553.1370 +      else if (filter_costs[i] >= 1.0)
553.1371 +      {
553.1372 +         png_ptr->inv_filter_costs[i] =
553.1373 +            (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
553.1374 +         png_ptr->filter_costs[i] =
553.1375 +            (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
553.1376 +      }
553.1377 +   }
553.1378 +}
553.1379 +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
553.1380 +
553.1381 +void PNGAPI
553.1382 +png_set_compression_level(png_structp png_ptr, int level)
553.1383 +{
553.1384 +   png_debug(1, "in png_set_compression_level\n");
553.1385 +   if (png_ptr == NULL)
553.1386 +      return;
553.1387 +   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
553.1388 +   png_ptr->zlib_level = level;
553.1389 +}
553.1390 +
553.1391 +void PNGAPI
553.1392 +png_set_compression_mem_level(png_structp png_ptr, int mem_level)
553.1393 +{
553.1394 +   png_debug(1, "in png_set_compression_mem_level\n");
553.1395 +   if (png_ptr == NULL)
553.1396 +      return;
553.1397 +   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
553.1398 +   png_ptr->zlib_mem_level = mem_level;
553.1399 +}
553.1400 +
553.1401 +void PNGAPI
553.1402 +png_set_compression_strategy(png_structp png_ptr, int strategy)
553.1403 +{
553.1404 +   png_debug(1, "in png_set_compression_strategy\n");
553.1405 +   if (png_ptr == NULL)
553.1406 +      return;
553.1407 +   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
553.1408 +   png_ptr->zlib_strategy = strategy;
553.1409 +}
553.1410 +
553.1411 +void PNGAPI
553.1412 +png_set_compression_window_bits(png_structp png_ptr, int window_bits)
553.1413 +{
553.1414 +   if (png_ptr == NULL)
553.1415 +      return;
553.1416 +   if (window_bits > 15)
553.1417 +      png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
553.1418 +   else if (window_bits < 8)
553.1419 +      png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
553.1420 +#ifndef WBITS_8_OK
553.1421 +   /* avoid libpng bug with 256-byte windows */
553.1422 +   if (window_bits == 8)
553.1423 +     {
553.1424 +       png_warning(png_ptr, "Compression window is being reset to 512");
553.1425 +       window_bits=9;
553.1426 +     }
553.1427 +#endif
553.1428 +   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
553.1429 +   png_ptr->zlib_window_bits = window_bits;
553.1430 +}
553.1431 +
553.1432 +void PNGAPI
553.1433 +png_set_compression_method(png_structp png_ptr, int method)
553.1434 +{
553.1435 +   png_debug(1, "in png_set_compression_method\n");
553.1436 +   if (png_ptr == NULL)
553.1437 +      return;
553.1438 +   if (method != 8)
553.1439 +      png_warning(png_ptr, "Only compression method 8 is supported by PNG");
553.1440 +   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
553.1441 +   png_ptr->zlib_method = method;
553.1442 +}
553.1443 +
553.1444 +void PNGAPI
553.1445 +png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
553.1446 +{
553.1447 +   if (png_ptr == NULL)
553.1448 +      return;
553.1449 +   png_ptr->write_row_fn = write_row_fn;
553.1450 +}
553.1451 +
553.1452 +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
553.1453 +void PNGAPI
553.1454 +png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
553.1455 +   write_user_transform_fn)
553.1456 +{
553.1457 +   png_debug(1, "in png_set_write_user_transform_fn\n");
553.1458 +   if (png_ptr == NULL)
553.1459 +      return;
553.1460 +   png_ptr->transformations |= PNG_USER_TRANSFORM;
553.1461 +   png_ptr->write_user_transform_fn = write_user_transform_fn;
553.1462 +}
553.1463 +#endif
553.1464 +
553.1465 +
553.1466 +#if defined(PNG_INFO_IMAGE_SUPPORTED)
553.1467 +void PNGAPI
553.1468 +png_write_png(png_structp png_ptr, png_infop info_ptr,
553.1469 +              int transforms, voidp params)
553.1470 +{
553.1471 +   if (png_ptr == NULL || info_ptr == NULL)
553.1472 +      return;
553.1473 +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
553.1474 +   /* invert the alpha channel from opacity to transparency */
553.1475 +   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
553.1476 +       png_set_invert_alpha(png_ptr);
553.1477 +#endif
553.1478 +
553.1479 +   /* Write the file header information. */
553.1480 +   png_write_info(png_ptr, info_ptr);
553.1481 +
553.1482 +   /* ------ these transformations don't touch the info structure ------- */
553.1483 +
553.1484 +#if defined(PNG_WRITE_INVERT_SUPPORTED)
553.1485 +   /* invert monochrome pixels */
553.1486 +   if (transforms & PNG_TRANSFORM_INVERT_MONO)
553.1487 +       png_set_invert_mono(png_ptr);
553.1488 +#endif
553.1489 +
553.1490 +#if defined(PNG_WRITE_SHIFT_SUPPORTED)
553.1491 +   /* Shift the pixels up to a legal bit depth and fill in
553.1492 +    * as appropriate to correctly scale the image.
553.1493 +    */
553.1494 +   if ((transforms & PNG_TRANSFORM_SHIFT)
553.1495 +               && (info_ptr->valid & PNG_INFO_sBIT))
553.1496 +       png_set_shift(png_ptr, &info_ptr->sig_bit);
553.1497 +#endif
553.1498 +
553.1499 +#if defined(PNG_WRITE_PACK_SUPPORTED)
553.1500 +   /* pack pixels into bytes */
553.1501 +   if (transforms & PNG_TRANSFORM_PACKING)
553.1502 +       png_set_packing(png_ptr);
553.1503 +#endif
553.1504 +
553.1505 +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
553.1506 +   /* swap location of alpha bytes from ARGB to RGBA */
553.1507 +   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
553.1508 +       png_set_swap_alpha(png_ptr);
553.1509 +#endif
553.1510 +
553.1511 +#if defined(PNG_WRITE_FILLER_SUPPORTED)
553.1512 +   /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
553.1513 +    * RGB (4 channels -> 3 channels). The second parameter is not used.
553.1514 +    */
553.1515 +   if (transforms & PNG_TRANSFORM_STRIP_FILLER)
553.1516 +       png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
553.1517 +#endif
553.1518 +
553.1519 +#if defined(PNG_WRITE_BGR_SUPPORTED)
553.1520 +   /* flip BGR pixels to RGB */
553.1521 +   if (transforms & PNG_TRANSFORM_BGR)
553.1522 +       png_set_bgr(png_ptr);
553.1523 +#endif
553.1524 +
553.1525 +#if defined(PNG_WRITE_SWAP_SUPPORTED)
553.1526 +   /* swap bytes of 16-bit files to most significant byte first */
553.1527 +   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
553.1528 +       png_set_swap(png_ptr);
553.1529 +#endif
553.1530 +
553.1531 +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
553.1532 +   /* swap bits of 1, 2, 4 bit packed pixel formats */
553.1533 +   if (transforms & PNG_TRANSFORM_PACKSWAP)
553.1534 +       png_set_packswap(png_ptr);
553.1535 +#endif
553.1536 +
553.1537 +   /* ----------------------- end of transformations ------------------- */
553.1538 +
553.1539 +   /* write the bits */
553.1540 +   if (info_ptr->valid & PNG_INFO_IDAT)
553.1541 +       png_write_image(png_ptr, info_ptr->row_pointers);
553.1542 +
553.1543 +   /* It is REQUIRED to call this to finish writing the rest of the file */
553.1544 +   png_write_end(png_ptr, info_ptr);
553.1545 +
553.1546 +   transforms = transforms; /* quiet compiler warnings */
553.1547 +   params = params;
553.1548 +}
553.1549 +#endif
553.1550 +#endif /* PNG_WRITE_SUPPORTED */
   554.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   554.2 +++ b/libs/libpng/pngwtran.c	Sat Feb 01 19:58:19 2014 +0200
   554.3 @@ -0,0 +1,572 @@
   554.4 +
   554.5 +/* pngwtran.c - transforms the data in a row for PNG writers
   554.6 + *
   554.7 + * Last changed in libpng 1.2.9 April 14, 2006
   554.8 + * For conditions of distribution and use, see copyright notice in png.h
   554.9 + * Copyright (c) 1998-2006 Glenn Randers-Pehrson
  554.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  554.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  554.12 + */
  554.13 +
  554.14 +#define PNG_INTERNAL
  554.15 +#include "png.h"
  554.16 +#ifdef PNG_WRITE_SUPPORTED
  554.17 +
  554.18 +/* Transform the data according to the user's wishes.  The order of
  554.19 + * transformations is significant.
  554.20 + */
  554.21 +void /* PRIVATE */
  554.22 +png_do_write_transformations(png_structp png_ptr)
  554.23 +{
  554.24 +   png_debug(1, "in png_do_write_transformations\n");
  554.25 +
  554.26 +   if (png_ptr == NULL)
  554.27 +      return;
  554.28 +
  554.29 +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
  554.30 +   if (png_ptr->transformations & PNG_USER_TRANSFORM)
  554.31 +      if (png_ptr->write_user_transform_fn != NULL)
  554.32 +        (*(png_ptr->write_user_transform_fn)) /* user write transform function */
  554.33 +          (png_ptr,                    /* png_ptr */
  554.34 +           &(png_ptr->row_info),       /* row_info:     */
  554.35 +             /*  png_uint_32 width;          width of row */
  554.36 +             /*  png_uint_32 rowbytes;       number of bytes in row */
  554.37 +             /*  png_byte color_type;        color type of pixels */
  554.38 +             /*  png_byte bit_depth;         bit depth of samples */
  554.39 +             /*  png_byte channels;          number of channels (1-4) */
  554.40 +             /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
  554.41 +           png_ptr->row_buf + 1);      /* start of pixel data for row */
  554.42 +#endif
  554.43 +#if defined(PNG_WRITE_FILLER_SUPPORTED)
  554.44 +   if (png_ptr->transformations & PNG_FILLER)
  554.45 +      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  554.46 +         png_ptr->flags);
  554.47 +#endif
  554.48 +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
  554.49 +   if (png_ptr->transformations & PNG_PACKSWAP)
  554.50 +      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  554.51 +#endif
  554.52 +#if defined(PNG_WRITE_PACK_SUPPORTED)
  554.53 +   if (png_ptr->transformations & PNG_PACK)
  554.54 +      png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
  554.55 +         (png_uint_32)png_ptr->bit_depth);
  554.56 +#endif
  554.57 +#if defined(PNG_WRITE_SWAP_SUPPORTED)
  554.58 +   if (png_ptr->transformations & PNG_SWAP_BYTES)
  554.59 +      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  554.60 +#endif
  554.61 +#if defined(PNG_WRITE_SHIFT_SUPPORTED)
  554.62 +   if (png_ptr->transformations & PNG_SHIFT)
  554.63 +      png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
  554.64 +         &(png_ptr->shift));
  554.65 +#endif
  554.66 +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
  554.67 +   if (png_ptr->transformations & PNG_SWAP_ALPHA)
  554.68 +      png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
  554.69 +#endif
  554.70 +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
  554.71 +   if (png_ptr->transformations & PNG_INVERT_ALPHA)
  554.72 +      png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
  554.73 +#endif
  554.74 +#if defined(PNG_WRITE_BGR_SUPPORTED)
  554.75 +   if (png_ptr->transformations & PNG_BGR)
  554.76 +      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
  554.77 +#endif
  554.78 +#if defined(PNG_WRITE_INVERT_SUPPORTED)
  554.79 +   if (png_ptr->transformations & PNG_INVERT_MONO)
  554.80 +      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
  554.81 +#endif
  554.82 +}
  554.83 +
  554.84 +#if defined(PNG_WRITE_PACK_SUPPORTED)
  554.85 +/* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
  554.86 + * row_info bit depth should be 8 (one pixel per byte).  The channels
  554.87 + * should be 1 (this only happens on grayscale and paletted images).
  554.88 + */
  554.89 +void /* PRIVATE */
  554.90 +png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
  554.91 +{
  554.92 +   png_debug(1, "in png_do_pack\n");
  554.93 +   if (row_info->bit_depth == 8 &&
  554.94 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
  554.95 +       row != NULL && row_info != NULL &&
  554.96 +#endif
  554.97 +      row_info->channels == 1)
  554.98 +   {
  554.99 +      switch ((int)bit_depth)
 554.100 +      {
 554.101 +         case 1:
 554.102 +         {
 554.103 +            png_bytep sp, dp;
 554.104 +            int mask, v;
 554.105 +            png_uint_32 i;
 554.106 +            png_uint_32 row_width = row_info->width;
 554.107 +
 554.108 +            sp = row;
 554.109 +            dp = row;
 554.110 +            mask = 0x80;
 554.111 +            v = 0;
 554.112 +
 554.113 +            for (i = 0; i < row_width; i++)
 554.114 +            {
 554.115 +               if (*sp != 0)
 554.116 +                  v |= mask;
 554.117 +               sp++;
 554.118 +               if (mask > 1)
 554.119 +                  mask >>= 1;
 554.120 +               else
 554.121 +               {
 554.122 +                  mask = 0x80;
 554.123 +                  *dp = (png_byte)v;
 554.124 +                  dp++;
 554.125 +                  v = 0;
 554.126 +               }
 554.127 +            }
 554.128 +            if (mask != 0x80)
 554.129 +               *dp = (png_byte)v;
 554.130 +            break;
 554.131 +         }
 554.132 +         case 2:
 554.133 +         {
 554.134 +            png_bytep sp, dp;
 554.135 +            int shift, v;
 554.136 +            png_uint_32 i;
 554.137 +            png_uint_32 row_width = row_info->width;
 554.138 +
 554.139 +            sp = row;
 554.140 +            dp = row;
 554.141 +            shift = 6;
 554.142 +            v = 0;
 554.143 +            for (i = 0; i < row_width; i++)
 554.144 +            {
 554.145 +               png_byte value;
 554.146 +
 554.147 +               value = (png_byte)(*sp & 0x03);
 554.148 +               v |= (value << shift);
 554.149 +               if (shift == 0)
 554.150 +               {
 554.151 +                  shift = 6;
 554.152 +                  *dp = (png_byte)v;
 554.153 +                  dp++;
 554.154 +                  v = 0;
 554.155 +               }
 554.156 +               else
 554.157 +                  shift -= 2;
 554.158 +               sp++;
 554.159 +            }
 554.160 +            if (shift != 6)
 554.161 +               *dp = (png_byte)v;
 554.162 +            break;
 554.163 +         }
 554.164 +         case 4:
 554.165 +         {
 554.166 +            png_bytep sp, dp;
 554.167 +            int shift, v;
 554.168 +            png_uint_32 i;
 554.169 +            png_uint_32 row_width = row_info->width;
 554.170 +
 554.171 +            sp = row;
 554.172 +            dp = row;
 554.173 +            shift = 4;
 554.174 +            v = 0;
 554.175 +            for (i = 0; i < row_width; i++)
 554.176 +            {
 554.177 +               png_byte value;
 554.178 +
 554.179 +               value = (png_byte)(*sp & 0x0f);
 554.180 +               v |= (value << shift);
 554.181 +
 554.182 +               if (shift == 0)
 554.183 +               {
 554.184 +                  shift = 4;
 554.185 +                  *dp = (png_byte)v;
 554.186 +                  dp++;
 554.187 +                  v = 0;
 554.188 +               }
 554.189 +               else
 554.190 +                  shift -= 4;
 554.191 +
 554.192 +               sp++;
 554.193 +            }
 554.194 +            if (shift != 4)
 554.195 +               *dp = (png_byte)v;
 554.196 +            break;
 554.197 +         }
 554.198 +      }
 554.199 +      row_info->bit_depth = (png_byte)bit_depth;
 554.200 +      row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
 554.201 +      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
 554.202 +         row_info->width);
 554.203 +   }
 554.204 +}
 554.205 +#endif
 554.206 +
 554.207 +#if defined(PNG_WRITE_SHIFT_SUPPORTED)
 554.208 +/* Shift pixel values to take advantage of whole range.  Pass the
 554.209 + * true number of bits in bit_depth.  The row should be packed
 554.210 + * according to row_info->bit_depth.  Thus, if you had a row of
 554.211 + * bit depth 4, but the pixels only had values from 0 to 7, you
 554.212 + * would pass 3 as bit_depth, and this routine would translate the
 554.213 + * data to 0 to 15.
 554.214 + */
 554.215 +void /* PRIVATE */
 554.216 +png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
 554.217 +{
 554.218 +   png_debug(1, "in png_do_shift\n");
 554.219 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
 554.220 +   if (row != NULL && row_info != NULL &&
 554.221 +#else
 554.222 +   if (
 554.223 +#endif
 554.224 +      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
 554.225 +   {
 554.226 +      int shift_start[4], shift_dec[4];
 554.227 +      int channels = 0;
 554.228 +
 554.229 +      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
 554.230 +      {
 554.231 +         shift_start[channels] = row_info->bit_depth - bit_depth->red;
 554.232 +         shift_dec[channels] = bit_depth->red;
 554.233 +         channels++;
 554.234 +         shift_start[channels] = row_info->bit_depth - bit_depth->green;
 554.235 +         shift_dec[channels] = bit_depth->green;
 554.236 +         channels++;
 554.237 +         shift_start[channels] = row_info->bit_depth - bit_depth->blue;
 554.238 +         shift_dec[channels] = bit_depth->blue;
 554.239 +         channels++;
 554.240 +      }
 554.241 +      else
 554.242 +      {
 554.243 +         shift_start[channels] = row_info->bit_depth - bit_depth->gray;
 554.244 +         shift_dec[channels] = bit_depth->gray;
 554.245 +         channels++;
 554.246 +      }
 554.247 +      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
 554.248 +      {
 554.249 +         shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
 554.250 +         shift_dec[channels] = bit_depth->alpha;
 554.251 +         channels++;
 554.252 +      }
 554.253 +
 554.254 +      /* with low row depths, could only be grayscale, so one channel */
 554.255 +      if (row_info->bit_depth < 8)
 554.256 +      {
 554.257 +         png_bytep bp = row;
 554.258 +         png_uint_32 i;
 554.259 +         png_byte mask;
 554.260 +         png_uint_32 row_bytes = row_info->rowbytes;
 554.261 +
 554.262 +         if (bit_depth->gray == 1 && row_info->bit_depth == 2)
 554.263 +            mask = 0x55;
 554.264 +         else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
 554.265 +            mask = 0x11;
 554.266 +         else
 554.267 +            mask = 0xff;
 554.268 +
 554.269 +         for (i = 0; i < row_bytes; i++, bp++)
 554.270 +         {
 554.271 +            png_uint_16 v;
 554.272 +            int j;
 554.273 +
 554.274 +            v = *bp;
 554.275 +            *bp = 0;
 554.276 +            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
 554.277 +            {
 554.278 +               if (j > 0)
 554.279 +                  *bp |= (png_byte)((v << j) & 0xff);
 554.280 +               else
 554.281 +                  *bp |= (png_byte)((v >> (-j)) & mask);
 554.282 +            }
 554.283 +         }
 554.284 +      }
 554.285 +      else if (row_info->bit_depth == 8)
 554.286 +      {
 554.287 +         png_bytep bp = row;
 554.288 +         png_uint_32 i;
 554.289 +         png_uint_32 istop = channels * row_info->width;
 554.290 +
 554.291 +         for (i = 0; i < istop; i++, bp++)
 554.292 +         {
 554.293 +
 554.294 +            png_uint_16 v;
 554.295 +            int j;
 554.296 +            int c = (int)(i%channels);
 554.297 +
 554.298 +            v = *bp;
 554.299 +            *bp = 0;
 554.300 +            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
 554.301 +            {
 554.302 +               if (j > 0)
 554.303 +                  *bp |= (png_byte)((v << j) & 0xff);
 554.304 +               else
 554.305 +                  *bp |= (png_byte)((v >> (-j)) & 0xff);
 554.306 +            }
 554.307 +         }
 554.308 +      }
 554.309 +      else
 554.310 +      {
 554.311 +         png_bytep bp;
 554.312 +         png_uint_32 i;
 554.313 +         png_uint_32 istop = channels * row_info->width;
 554.314 +
 554.315 +         for (bp = row, i = 0; i < istop; i++)
 554.316 +         {
 554.317 +            int c = (int)(i%channels);
 554.318 +            png_uint_16 value, v;
 554.319 +            int j;
 554.320 +
 554.321 +            v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
 554.322 +            value = 0;
 554.323 +            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
 554.324 +            {
 554.325 +               if (j > 0)
 554.326 +                  value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
 554.327 +               else
 554.328 +                  value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
 554.329 +            }
 554.330 +            *bp++ = (png_byte)(value >> 8);
 554.331 +            *bp++ = (png_byte)(value & 0xff);
 554.332 +         }
 554.333 +      }
 554.334 +   }
 554.335 +}
 554.336 +#endif
 554.337 +
 554.338 +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
 554.339 +void /* PRIVATE */
 554.340 +png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
 554.341 +{
 554.342 +   png_debug(1, "in png_do_write_swap_alpha\n");
 554.343 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
 554.344 +   if (row != NULL && row_info != NULL)
 554.345 +#endif
 554.346 +   {
 554.347 +      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 554.348 +      {
 554.349 +         /* This converts from ARGB to RGBA */
 554.350 +         if (row_info->bit_depth == 8)
 554.351 +         {
 554.352 +            png_bytep sp, dp;
 554.353 +            png_uint_32 i;
 554.354 +            png_uint_32 row_width = row_info->width;
 554.355 +            for (i = 0, sp = dp = row; i < row_width; i++)
 554.356 +            {
 554.357 +               png_byte save = *(sp++);
 554.358 +               *(dp++) = *(sp++);
 554.359 +               *(dp++) = *(sp++);
 554.360 +               *(dp++) = *(sp++);
 554.361 +               *(dp++) = save;
 554.362 +            }
 554.363 +         }
 554.364 +         /* This converts from AARRGGBB to RRGGBBAA */
 554.365 +         else
 554.366 +         {
 554.367 +            png_bytep sp, dp;
 554.368 +            png_uint_32 i;
 554.369 +            png_uint_32 row_width = row_info->width;
 554.370 +
 554.371 +            for (i = 0, sp = dp = row; i < row_width; i++)
 554.372 +            {
 554.373 +               png_byte save[2];
 554.374 +               save[0] = *(sp++);
 554.375 +               save[1] = *(sp++);
 554.376 +               *(dp++) = *(sp++);
 554.377 +               *(dp++) = *(sp++);
 554.378 +               *(dp++) = *(sp++);
 554.379 +               *(dp++) = *(sp++);
 554.380 +               *(dp++) = *(sp++);
 554.381 +               *(dp++) = *(sp++);
 554.382 +               *(dp++) = save[0];
 554.383 +               *(dp++) = save[1];
 554.384 +            }
 554.385 +         }
 554.386 +      }
 554.387 +      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 554.388 +      {
 554.389 +         /* This converts from AG to GA */
 554.390 +         if (row_info->bit_depth == 8)
 554.391 +         {
 554.392 +            png_bytep sp, dp;
 554.393 +            png_uint_32 i;
 554.394 +            png_uint_32 row_width = row_info->width;
 554.395 +
 554.396 +            for (i = 0, sp = dp = row; i < row_width; i++)
 554.397 +            {
 554.398 +               png_byte save = *(sp++);
 554.399 +               *(dp++) = *(sp++);
 554.400 +               *(dp++) = save;
 554.401 +            }
 554.402 +         }
 554.403 +         /* This converts from AAGG to GGAA */
 554.404 +         else
 554.405 +         {
 554.406 +            png_bytep sp, dp;
 554.407 +            png_uint_32 i;
 554.408 +            png_uint_32 row_width = row_info->width;
 554.409 +
 554.410 +            for (i = 0, sp = dp = row; i < row_width; i++)
 554.411 +            {
 554.412 +               png_byte save[2];
 554.413 +               save[0] = *(sp++);
 554.414 +               save[1] = *(sp++);
 554.415 +               *(dp++) = *(sp++);
 554.416 +               *(dp++) = *(sp++);
 554.417 +               *(dp++) = save[0];
 554.418 +               *(dp++) = save[1];
 554.419 +            }
 554.420 +         }
 554.421 +      }
 554.422 +   }
 554.423 +}
 554.424 +#endif
 554.425 +
 554.426 +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
 554.427 +void /* PRIVATE */
 554.428 +png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
 554.429 +{
 554.430 +   png_debug(1, "in png_do_write_invert_alpha\n");
 554.431 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
 554.432 +   if (row != NULL && row_info != NULL)
 554.433 +#endif
 554.434 +   {
 554.435 +      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 554.436 +      {
 554.437 +         /* This inverts the alpha channel in RGBA */
 554.438 +         if (row_info->bit_depth == 8)
 554.439 +         {
 554.440 +            png_bytep sp, dp;
 554.441 +            png_uint_32 i;
 554.442 +            png_uint_32 row_width = row_info->width;
 554.443 +            for (i = 0, sp = dp = row; i < row_width; i++)
 554.444 +            {
 554.445 +               /* does nothing
 554.446 +               *(dp++) = *(sp++);
 554.447 +               *(dp++) = *(sp++);
 554.448 +               *(dp++) = *(sp++);
 554.449 +               */
 554.450 +               sp+=3; dp = sp;
 554.451 +               *(dp++) = (png_byte)(255 - *(sp++));
 554.452 +            }
 554.453 +         }
 554.454 +         /* This inverts the alpha channel in RRGGBBAA */
 554.455 +         else
 554.456 +         {
 554.457 +            png_bytep sp, dp;
 554.458 +            png_uint_32 i;
 554.459 +            png_uint_32 row_width = row_info->width;
 554.460 +
 554.461 +            for (i = 0, sp = dp = row; i < row_width; i++)
 554.462 +            {
 554.463 +               /* does nothing
 554.464 +               *(dp++) = *(sp++);
 554.465 +               *(dp++) = *(sp++);
 554.466 +               *(dp++) = *(sp++);
 554.467 +               *(dp++) = *(sp++);
 554.468 +               *(dp++) = *(sp++);
 554.469 +               *(dp++) = *(sp++);
 554.470 +               */
 554.471 +               sp+=6; dp = sp;
 554.472 +               *(dp++) = (png_byte)(255 - *(sp++));
 554.473 +               *(dp++) = (png_byte)(255 - *(sp++));
 554.474 +            }
 554.475 +         }
 554.476 +      }
 554.477 +      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 554.478 +      {
 554.479 +         /* This inverts the alpha channel in GA */
 554.480 +         if (row_info->bit_depth == 8)
 554.481 +         {
 554.482 +            png_bytep sp, dp;
 554.483 +            png_uint_32 i;
 554.484 +            png_uint_32 row_width = row_info->width;
 554.485 +
 554.486 +            for (i = 0, sp = dp = row; i < row_width; i++)
 554.487 +            {
 554.488 +               *(dp++) = *(sp++);
 554.489 +               *(dp++) = (png_byte)(255 - *(sp++));
 554.490 +            }
 554.491 +         }
 554.492 +         /* This inverts the alpha channel in GGAA */
 554.493 +         else
 554.494 +         {
 554.495 +            png_bytep sp, dp;
 554.496 +            png_uint_32 i;
 554.497 +            png_uint_32 row_width = row_info->width;
 554.498 +
 554.499 +            for (i = 0, sp = dp = row; i < row_width; i++)
 554.500 +            {
 554.501 +               /* does nothing
 554.502 +               *(dp++) = *(sp++);
 554.503 +               *(dp++) = *(sp++);
 554.504 +               */
 554.505 +               sp+=2; dp = sp;
 554.506 +               *(dp++) = (png_byte)(255 - *(sp++));
 554.507 +               *(dp++) = (png_byte)(255 - *(sp++));
 554.508 +            }
 554.509 +         }
 554.510 +      }
 554.511 +   }
 554.512 +}
 554.513 +#endif
 554.514 +
 554.515 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
 554.516 +/* undoes intrapixel differencing  */
 554.517 +void /* PRIVATE */
 554.518 +png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
 554.519 +{
 554.520 +   png_debug(1, "in png_do_write_intrapixel\n");
 554.521 +   if (
 554.522 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
 554.523 +       row != NULL && row_info != NULL &&
 554.524 +#endif
 554.525 +       (row_info->color_type & PNG_COLOR_MASK_COLOR))
 554.526 +   {
 554.527 +      int bytes_per_pixel;
 554.528 +      png_uint_32 row_width = row_info->width;
 554.529 +      if (row_info->bit_depth == 8)
 554.530 +      {
 554.531 +         png_bytep rp;
 554.532 +         png_uint_32 i;
 554.533 +
 554.534 +         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 554.535 +            bytes_per_pixel = 3;
 554.536 +         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 554.537 +            bytes_per_pixel = 4;
 554.538 +         else
 554.539 +            return;
 554.540 +
 554.541 +         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
 554.542 +         {
 554.543 +            *(rp)   = (png_byte)((*rp     - *(rp+1))&0xff);
 554.544 +            *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
 554.545 +         }
 554.546 +      }
 554.547 +      else if (row_info->bit_depth == 16)
 554.548 +      {
 554.549 +         png_bytep rp;
 554.550 +         png_uint_32 i;
 554.551 +
 554.552 +         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 554.553 +            bytes_per_pixel = 6;
 554.554 +         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 554.555 +            bytes_per_pixel = 8;
 554.556 +         else
 554.557 +            return;
 554.558 +
 554.559 +         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
 554.560 +         {
 554.561 +            png_uint_32 s0   = (*(rp  ) << 8) | *(rp+1);
 554.562 +            png_uint_32 s1   = (*(rp+2) << 8) | *(rp+3);
 554.563 +            png_uint_32 s2   = (*(rp+4) << 8) | *(rp+5);
 554.564 +            png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
 554.565 +            png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
 554.566 +            *(rp  ) = (png_byte)((red >> 8) & 0xff);
 554.567 +            *(rp+1) = (png_byte)(red & 0xff);
 554.568 +            *(rp+4) = (png_byte)((blue >> 8) & 0xff);
 554.569 +            *(rp+5) = (png_byte)(blue & 0xff);
 554.570 +         }
 554.571 +      }
 554.572 +   }
 554.573 +}
 554.574 +#endif /* PNG_MNG_FEATURES_SUPPORTED */
 554.575 +#endif /* PNG_WRITE_SUPPORTED */
   555.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   555.2 +++ b/libs/libpng/pngwutil.c	Sat Feb 01 19:58:19 2014 +0200
   555.3 @@ -0,0 +1,2827 @@
   555.4 +
   555.5 +/* pngwutil.c - utilities to write a PNG file
   555.6 + *
   555.7 + * Last changed in libpng 1.2.30 [August 15, 2008]
   555.8 + * For conditions of distribution and use, see copyright notice in png.h
   555.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  555.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  555.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  555.12 + */
  555.13 +
  555.14 +#define PNG_INTERNAL
  555.15 +#include "png.h"
  555.16 +#ifdef PNG_WRITE_SUPPORTED
  555.17 +
  555.18 +/* Place a 32-bit number into a buffer in PNG byte order.  We work
  555.19 + * with unsigned numbers for convenience, although one supported
  555.20 + * ancillary chunk uses signed (two's complement) numbers.
  555.21 + */
  555.22 +void PNGAPI
  555.23 +png_save_uint_32(png_bytep buf, png_uint_32 i)
  555.24 +{
  555.25 +   buf[0] = (png_byte)((i >> 24) & 0xff);
  555.26 +   buf[1] = (png_byte)((i >> 16) & 0xff);
  555.27 +   buf[2] = (png_byte)((i >> 8) & 0xff);
  555.28 +   buf[3] = (png_byte)(i & 0xff);
  555.29 +}
  555.30 +
  555.31 +/* The png_save_int_32 function assumes integers are stored in two's
  555.32 + * complement format.  If this isn't the case, then this routine needs to
  555.33 + * be modified to write data in two's complement format.
  555.34 + */
  555.35 +void PNGAPI
  555.36 +png_save_int_32(png_bytep buf, png_int_32 i)
  555.37 +{
  555.38 +   buf[0] = (png_byte)((i >> 24) & 0xff);
  555.39 +   buf[1] = (png_byte)((i >> 16) & 0xff);
  555.40 +   buf[2] = (png_byte)((i >> 8) & 0xff);
  555.41 +   buf[3] = (png_byte)(i & 0xff);
  555.42 +}
  555.43 +
  555.44 +/* Place a 16-bit number into a buffer in PNG byte order.
  555.45 + * The parameter is declared unsigned int, not png_uint_16,
  555.46 + * just to avoid potential problems on pre-ANSI C compilers.
  555.47 + */
  555.48 +void PNGAPI
  555.49 +png_save_uint_16(png_bytep buf, unsigned int i)
  555.50 +{
  555.51 +   buf[0] = (png_byte)((i >> 8) & 0xff);
  555.52 +   buf[1] = (png_byte)(i & 0xff);
  555.53 +}
  555.54 +
  555.55 +/* Simple function to write the signature.  If we have already written
  555.56 + * the magic bytes of the signature, or more likely, the PNG stream is
  555.57 + * being embedded into another stream and doesn't need its own signature,
  555.58 + * we should call png_set_sig_bytes() to tell libpng how many of the
  555.59 + * bytes have already been written.
  555.60 + */
  555.61 +void /* PRIVATE */
  555.62 +png_write_sig(png_structp png_ptr)
  555.63 +{
  555.64 +   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
  555.65 +
  555.66 +   /* write the rest of the 8 byte signature */
  555.67 +   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
  555.68 +      (png_size_t)(8 - png_ptr->sig_bytes));
  555.69 +   if (png_ptr->sig_bytes < 3)
  555.70 +      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
  555.71 +}
  555.72 +
  555.73 +/* Write a PNG chunk all at once.  The type is an array of ASCII characters
  555.74 + * representing the chunk name.  The array must be at least 4 bytes in
  555.75 + * length, and does not need to be null terminated.  To be safe, pass the
  555.76 + * pre-defined chunk names here, and if you need a new one, define it
  555.77 + * where the others are defined.  The length is the length of the data.
  555.78 + * All the data must be present.  If that is not possible, use the
  555.79 + * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
  555.80 + * functions instead.
  555.81 + */
  555.82 +void PNGAPI
  555.83 +png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
  555.84 +   png_bytep data, png_size_t length)
  555.85 +{
  555.86 +   if (png_ptr == NULL) return;
  555.87 +   png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
  555.88 +   png_write_chunk_data(png_ptr, data, (png_size_t)length);
  555.89 +   png_write_chunk_end(png_ptr);
  555.90 +}
  555.91 +
  555.92 +/* Write the start of a PNG chunk.  The type is the chunk type.
  555.93 + * The total_length is the sum of the lengths of all the data you will be
  555.94 + * passing in png_write_chunk_data().
  555.95 + */
  555.96 +void PNGAPI
  555.97 +png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
  555.98 +   png_uint_32 length)
  555.99 +{
 555.100 +   png_byte buf[8];
 555.101 +
 555.102 +   png_debug2(0, "Writing %s chunk, length = %lu\n", chunk_name,
 555.103 +      (unsigned long)length);
 555.104 +   if (png_ptr == NULL) return;
 555.105 +
 555.106 +   /* write the length and the chunk name */
 555.107 +   png_save_uint_32(buf, length);
 555.108 +   png_memcpy(buf + 4, chunk_name, 4);
 555.109 +   png_write_data(png_ptr, buf, (png_size_t)8);
 555.110 +   /* put the chunk name into png_ptr->chunk_name */
 555.111 +   png_memcpy(png_ptr->chunk_name, chunk_name, 4);
 555.112 +   /* reset the crc and run it over the chunk name */
 555.113 +   png_reset_crc(png_ptr);
 555.114 +   png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
 555.115 +}
 555.116 +
 555.117 +/* Write the data of a PNG chunk started with png_write_chunk_start().
 555.118 + * Note that multiple calls to this function are allowed, and that the
 555.119 + * sum of the lengths from these calls *must* add up to the total_length
 555.120 + * given to png_write_chunk_start().
 555.121 + */
 555.122 +void PNGAPI
 555.123 +png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
 555.124 +{
 555.125 +   /* write the data, and run the CRC over it */
 555.126 +   if (png_ptr == NULL) return;
 555.127 +   if (data != NULL && length > 0)
 555.128 +   {
 555.129 +      png_write_data(png_ptr, data, length);
 555.130 +      /* update the CRC after writing the data,
 555.131 +       * in case that the user I/O routine alters it.
 555.132 +       */
 555.133 +      png_calculate_crc(png_ptr, data, length);
 555.134 +   }
 555.135 +}
 555.136 +
 555.137 +/* Finish a chunk started with png_write_chunk_start(). */
 555.138 +void PNGAPI
 555.139 +png_write_chunk_end(png_structp png_ptr)
 555.140 +{
 555.141 +   png_byte buf[4];
 555.142 +
 555.143 +   if (png_ptr == NULL) return;
 555.144 +
 555.145 +   /* write the crc in a single operation */
 555.146 +   png_save_uint_32(buf, png_ptr->crc);
 555.147 +
 555.148 +   png_write_data(png_ptr, buf, (png_size_t)4);
 555.149 +}
 555.150 +
 555.151 +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
 555.152 +/*
 555.153 + * This pair of functions encapsulates the operation of (a) compressing a
 555.154 + * text string, and (b) issuing it later as a series of chunk data writes.
 555.155 + * The compression_state structure is shared context for these functions
 555.156 + * set up by the caller in order to make the whole mess thread-safe.
 555.157 + */
 555.158 +
 555.159 +typedef struct
 555.160 +{
 555.161 +    char *input;   /* the uncompressed input data */
 555.162 +    int input_len;   /* its length */
 555.163 +    int num_output_ptr; /* number of output pointers used */
 555.164 +    int max_output_ptr; /* size of output_ptr */
 555.165 +    png_charpp output_ptr; /* array of pointers to output */
 555.166 +} compression_state;
 555.167 +
 555.168 +/* compress given text into storage in the png_ptr structure */
 555.169 +static int /* PRIVATE */
 555.170 +png_text_compress(png_structp png_ptr,
 555.171 +        png_charp text, png_size_t text_len, int compression,
 555.172 +        compression_state *comp)
 555.173 +{
 555.174 +   int ret;
 555.175 +
 555.176 +   comp->num_output_ptr = 0;
 555.177 +   comp->max_output_ptr = 0;
 555.178 +   comp->output_ptr = NULL;
 555.179 +   comp->input = NULL;
 555.180 +   comp->input_len = 0;
 555.181 +
 555.182 +   /* we may just want to pass the text right through */
 555.183 +   if (compression == PNG_TEXT_COMPRESSION_NONE)
 555.184 +   {
 555.185 +       comp->input = text;
 555.186 +       comp->input_len = text_len;
 555.187 +       return((int)text_len);
 555.188 +   }
 555.189 +
 555.190 +   if (compression >= PNG_TEXT_COMPRESSION_LAST)
 555.191 +   {
 555.192 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
 555.193 +      char msg[50];
 555.194 +      png_snprintf(msg, 50, "Unknown compression type %d", compression);
 555.195 +      png_warning(png_ptr, msg);
 555.196 +#else
 555.197 +      png_warning(png_ptr, "Unknown compression type");
 555.198 +#endif
 555.199 +   }
 555.200 +
 555.201 +   /* We can't write the chunk until we find out how much data we have,
 555.202 +    * which means we need to run the compressor first and save the
 555.203 +    * output.  This shouldn't be a problem, as the vast majority of
 555.204 +    * comments should be reasonable, but we will set up an array of
 555.205 +    * malloc'd pointers to be sure.
 555.206 +    *
 555.207 +    * If we knew the application was well behaved, we could simplify this
 555.208 +    * greatly by assuming we can always malloc an output buffer large
 555.209 +    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
 555.210 +    * and malloc this directly.  The only time this would be a bad idea is
 555.211 +    * if we can't malloc more than 64K and we have 64K of random input
 555.212 +    * data, or if the input string is incredibly large (although this
 555.213 +    * wouldn't cause a failure, just a slowdown due to swapping).
 555.214 +    */
 555.215 +
 555.216 +   /* set up the compression buffers */
 555.217 +   png_ptr->zstream.avail_in = (uInt)text_len;
 555.218 +   png_ptr->zstream.next_in = (Bytef *)text;
 555.219 +   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
 555.220 +   png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
 555.221 +
 555.222 +   /* this is the same compression loop as in png_write_row() */
 555.223 +   do
 555.224 +   {
 555.225 +      /* compress the data */
 555.226 +      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
 555.227 +      if (ret != Z_OK)
 555.228 +      {
 555.229 +         /* error */
 555.230 +         if (png_ptr->zstream.msg != NULL)
 555.231 +            png_error(png_ptr, png_ptr->zstream.msg);
 555.232 +         else
 555.233 +            png_error(png_ptr, "zlib error");
 555.234 +      }
 555.235 +      /* check to see if we need more room */
 555.236 +      if (!(png_ptr->zstream.avail_out))
 555.237 +      {
 555.238 +         /* make sure the output array has room */
 555.239 +         if (comp->num_output_ptr >= comp->max_output_ptr)
 555.240 +         {
 555.241 +            int old_max;
 555.242 +
 555.243 +            old_max = comp->max_output_ptr;
 555.244 +            comp->max_output_ptr = comp->num_output_ptr + 4;
 555.245 +            if (comp->output_ptr != NULL)
 555.246 +            {
 555.247 +               png_charpp old_ptr;
 555.248 +
 555.249 +               old_ptr = comp->output_ptr;
 555.250 +               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
 555.251 +                  (png_uint_32)
 555.252 +                  (comp->max_output_ptr * png_sizeof(png_charpp)));
 555.253 +               png_memcpy(comp->output_ptr, old_ptr, old_max
 555.254 +                  * png_sizeof(png_charp));
 555.255 +               png_free(png_ptr, old_ptr);
 555.256 +            }
 555.257 +            else
 555.258 +               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
 555.259 +                  (png_uint_32)
 555.260 +                  (comp->max_output_ptr * png_sizeof(png_charp)));
 555.261 +         }
 555.262 +
 555.263 +         /* save the data */
 555.264 +         comp->output_ptr[comp->num_output_ptr] =
 555.265 +            (png_charp)png_malloc(png_ptr,
 555.266 +            (png_uint_32)png_ptr->zbuf_size);
 555.267 +         png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
 555.268 +            png_ptr->zbuf_size);
 555.269 +         comp->num_output_ptr++;
 555.270 +
 555.271 +         /* and reset the buffer */
 555.272 +         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
 555.273 +         png_ptr->zstream.next_out = png_ptr->zbuf;
 555.274 +      }
 555.275 +   /* continue until we don't have any more to compress */
 555.276 +   } while (png_ptr->zstream.avail_in);
 555.277 +
 555.278 +   /* finish the compression */
 555.279 +   do
 555.280 +   {
 555.281 +      /* tell zlib we are finished */
 555.282 +      ret = deflate(&png_ptr->zstream, Z_FINISH);
 555.283 +
 555.284 +      if (ret == Z_OK)
 555.285 +      {
 555.286 +         /* check to see if we need more room */
 555.287 +         if (!(png_ptr->zstream.avail_out))
 555.288 +         {
 555.289 +            /* check to make sure our output array has room */
 555.290 +            if (comp->num_output_ptr >= comp->max_output_ptr)
 555.291 +            {
 555.292 +               int old_max;
 555.293 +
 555.294 +               old_max = comp->max_output_ptr;
 555.295 +               comp->max_output_ptr = comp->num_output_ptr + 4;
 555.296 +               if (comp->output_ptr != NULL)
 555.297 +               {
 555.298 +                  png_charpp old_ptr;
 555.299 +
 555.300 +                  old_ptr = comp->output_ptr;
 555.301 +                  /* This could be optimized to realloc() */
 555.302 +                  comp->output_ptr = (png_charpp)png_malloc(png_ptr,
 555.303 +                     (png_uint_32)(comp->max_output_ptr *
 555.304 +                     png_sizeof(png_charp)));
 555.305 +                  png_memcpy(comp->output_ptr, old_ptr,
 555.306 +                     old_max * png_sizeof(png_charp));
 555.307 +                  png_free(png_ptr, old_ptr);
 555.308 +               }
 555.309 +               else
 555.310 +                  comp->output_ptr = (png_charpp)png_malloc(png_ptr,
 555.311 +                     (png_uint_32)(comp->max_output_ptr *
 555.312 +                     png_sizeof(png_charp)));
 555.313 +            }
 555.314 +
 555.315 +            /* save off the data */
 555.316 +            comp->output_ptr[comp->num_output_ptr] =
 555.317 +               (png_charp)png_malloc(png_ptr,
 555.318 +               (png_uint_32)png_ptr->zbuf_size);
 555.319 +            png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
 555.320 +               png_ptr->zbuf_size);
 555.321 +            comp->num_output_ptr++;
 555.322 +
 555.323 +            /* and reset the buffer pointers */
 555.324 +            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
 555.325 +            png_ptr->zstream.next_out = png_ptr->zbuf;
 555.326 +         }
 555.327 +      }
 555.328 +      else if (ret != Z_STREAM_END)
 555.329 +      {
 555.330 +         /* we got an error */
 555.331 +         if (png_ptr->zstream.msg != NULL)
 555.332 +            png_error(png_ptr, png_ptr->zstream.msg);
 555.333 +         else
 555.334 +            png_error(png_ptr, "zlib error");
 555.335 +      }
 555.336 +   } while (ret != Z_STREAM_END);
 555.337 +
 555.338 +   /* text length is number of buffers plus last buffer */
 555.339 +   text_len = png_ptr->zbuf_size * comp->num_output_ptr;
 555.340 +   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
 555.341 +      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
 555.342 +
 555.343 +   return((int)text_len);
 555.344 +}
 555.345 +
 555.346 +/* ship the compressed text out via chunk writes */
 555.347 +static void /* PRIVATE */
 555.348 +png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
 555.349 +{
 555.350 +   int i;
 555.351 +
 555.352 +   /* handle the no-compression case */
 555.353 +   if (comp->input)
 555.354 +   {
 555.355 +       png_write_chunk_data(png_ptr, (png_bytep)comp->input,
 555.356 +                            (png_size_t)comp->input_len);
 555.357 +       return;
 555.358 +   }
 555.359 +
 555.360 +   /* write saved output buffers, if any */
 555.361 +   for (i = 0; i < comp->num_output_ptr; i++)
 555.362 +   {
 555.363 +      png_write_chunk_data(png_ptr, (png_bytep)comp->output_ptr[i],
 555.364 +         (png_size_t)png_ptr->zbuf_size);
 555.365 +      png_free(png_ptr, comp->output_ptr[i]);
 555.366 +       comp->output_ptr[i]=NULL;
 555.367 +   }
 555.368 +   if (comp->max_output_ptr != 0)
 555.369 +      png_free(png_ptr, comp->output_ptr);
 555.370 +       comp->output_ptr=NULL;
 555.371 +   /* write anything left in zbuf */
 555.372 +   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
 555.373 +      png_write_chunk_data(png_ptr, png_ptr->zbuf,
 555.374 +         (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
 555.375 +
 555.376 +   /* reset zlib for another zTXt/iTXt or image data */
 555.377 +   deflateReset(&png_ptr->zstream);
 555.378 +   png_ptr->zstream.data_type = Z_BINARY;
 555.379 +}
 555.380 +#endif
 555.381 +
 555.382 +/* Write the IHDR chunk, and update the png_struct with the necessary
 555.383 + * information.  Note that the rest of this code depends upon this
 555.384 + * information being correct.
 555.385 + */
 555.386 +void /* PRIVATE */
 555.387 +png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
 555.388 +   int bit_depth, int color_type, int compression_type, int filter_type,
 555.389 +   int interlace_type)
 555.390 +{
 555.391 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.392 +   PNG_IHDR;
 555.393 +#endif
 555.394 +   int ret;
 555.395 +
 555.396 +   png_byte buf[13]; /* buffer to store the IHDR info */
 555.397 +
 555.398 +   png_debug(1, "in png_write_IHDR\n");
 555.399 +   /* Check that we have valid input data from the application info */
 555.400 +   switch (color_type)
 555.401 +   {
 555.402 +      case PNG_COLOR_TYPE_GRAY:
 555.403 +         switch (bit_depth)
 555.404 +         {
 555.405 +            case 1:
 555.406 +            case 2:
 555.407 +            case 4:
 555.408 +            case 8:
 555.409 +            case 16: png_ptr->channels = 1; break;
 555.410 +            default: png_error(png_ptr, "Invalid bit depth for grayscale image");
 555.411 +         }
 555.412 +         break;
 555.413 +      case PNG_COLOR_TYPE_RGB:
 555.414 +         if (bit_depth != 8 && bit_depth != 16)
 555.415 +            png_error(png_ptr, "Invalid bit depth for RGB image");
 555.416 +         png_ptr->channels = 3;
 555.417 +         break;
 555.418 +      case PNG_COLOR_TYPE_PALETTE:
 555.419 +         switch (bit_depth)
 555.420 +         {
 555.421 +            case 1:
 555.422 +            case 2:
 555.423 +            case 4:
 555.424 +            case 8: png_ptr->channels = 1; break;
 555.425 +            default: png_error(png_ptr, "Invalid bit depth for paletted image");
 555.426 +         }
 555.427 +         break;
 555.428 +      case PNG_COLOR_TYPE_GRAY_ALPHA:
 555.429 +         if (bit_depth != 8 && bit_depth != 16)
 555.430 +            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
 555.431 +         png_ptr->channels = 2;
 555.432 +         break;
 555.433 +      case PNG_COLOR_TYPE_RGB_ALPHA:
 555.434 +         if (bit_depth != 8 && bit_depth != 16)
 555.435 +            png_error(png_ptr, "Invalid bit depth for RGBA image");
 555.436 +         png_ptr->channels = 4;
 555.437 +         break;
 555.438 +      default:
 555.439 +         png_error(png_ptr, "Invalid image color type specified");
 555.440 +   }
 555.441 +
 555.442 +   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
 555.443 +   {
 555.444 +      png_warning(png_ptr, "Invalid compression type specified");
 555.445 +      compression_type = PNG_COMPRESSION_TYPE_BASE;
 555.446 +   }
 555.447 +
 555.448 +   /* Write filter_method 64 (intrapixel differencing) only if
 555.449 +    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
 555.450 +    * 2. Libpng did not write a PNG signature (this filter_method is only
 555.451 +    *    used in PNG datastreams that are embedded in MNG datastreams) and
 555.452 +    * 3. The application called png_permit_mng_features with a mask that
 555.453 +    *    included PNG_FLAG_MNG_FILTER_64 and
 555.454 +    * 4. The filter_method is 64 and
 555.455 +    * 5. The color_type is RGB or RGBA
 555.456 +    */
 555.457 +   if (
 555.458 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
 555.459 +      !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
 555.460 +      ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
 555.461 +      (color_type == PNG_COLOR_TYPE_RGB ||
 555.462 +       color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
 555.463 +      (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
 555.464 +#endif
 555.465 +      filter_type != PNG_FILTER_TYPE_BASE)
 555.466 +   {
 555.467 +      png_warning(png_ptr, "Invalid filter type specified");
 555.468 +      filter_type = PNG_FILTER_TYPE_BASE;
 555.469 +   }
 555.470 +
 555.471 +#ifdef PNG_WRITE_INTERLACING_SUPPORTED
 555.472 +   if (interlace_type != PNG_INTERLACE_NONE &&
 555.473 +      interlace_type != PNG_INTERLACE_ADAM7)
 555.474 +   {
 555.475 +      png_warning(png_ptr, "Invalid interlace type specified");
 555.476 +      interlace_type = PNG_INTERLACE_ADAM7;
 555.477 +   }
 555.478 +#else
 555.479 +   interlace_type=PNG_INTERLACE_NONE;
 555.480 +#endif
 555.481 +
 555.482 +   /* save off the relevent information */
 555.483 +   png_ptr->bit_depth = (png_byte)bit_depth;
 555.484 +   png_ptr->color_type = (png_byte)color_type;
 555.485 +   png_ptr->interlaced = (png_byte)interlace_type;
 555.486 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
 555.487 +   png_ptr->filter_type = (png_byte)filter_type;
 555.488 +#endif
 555.489 +   png_ptr->compression_type = (png_byte)compression_type;
 555.490 +   png_ptr->width = width;
 555.491 +   png_ptr->height = height;
 555.492 +
 555.493 +   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
 555.494 +   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
 555.495 +   /* set the usr info, so any transformations can modify it */
 555.496 +   png_ptr->usr_width = png_ptr->width;
 555.497 +   png_ptr->usr_bit_depth = png_ptr->bit_depth;
 555.498 +   png_ptr->usr_channels = png_ptr->channels;
 555.499 +
 555.500 +   /* pack the header information into the buffer */
 555.501 +   png_save_uint_32(buf, width);
 555.502 +   png_save_uint_32(buf + 4, height);
 555.503 +   buf[8] = (png_byte)bit_depth;
 555.504 +   buf[9] = (png_byte)color_type;
 555.505 +   buf[10] = (png_byte)compression_type;
 555.506 +   buf[11] = (png_byte)filter_type;
 555.507 +   buf[12] = (png_byte)interlace_type;
 555.508 +
 555.509 +   /* write the chunk */
 555.510 +   png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
 555.511 +
 555.512 +   /* initialize zlib with PNG info */
 555.513 +   png_ptr->zstream.zalloc = png_zalloc;
 555.514 +   png_ptr->zstream.zfree = png_zfree;
 555.515 +   png_ptr->zstream.opaque = (voidpf)png_ptr;
 555.516 +   if (!(png_ptr->do_filter))
 555.517 +   {
 555.518 +      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
 555.519 +         png_ptr->bit_depth < 8)
 555.520 +         png_ptr->do_filter = PNG_FILTER_NONE;
 555.521 +      else
 555.522 +         png_ptr->do_filter = PNG_ALL_FILTERS;
 555.523 +   }
 555.524 +   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
 555.525 +   {
 555.526 +      if (png_ptr->do_filter != PNG_FILTER_NONE)
 555.527 +         png_ptr->zlib_strategy = Z_FILTERED;
 555.528 +      else
 555.529 +         png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
 555.530 +   }
 555.531 +   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
 555.532 +      png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
 555.533 +   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
 555.534 +      png_ptr->zlib_mem_level = 8;
 555.535 +   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
 555.536 +      png_ptr->zlib_window_bits = 15;
 555.537 +   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
 555.538 +      png_ptr->zlib_method = 8;
 555.539 +   ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
 555.540 +         png_ptr->zlib_method, png_ptr->zlib_window_bits,
 555.541 +         png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
 555.542 +   if (ret != Z_OK)
 555.543 +   {
 555.544 +      if (ret == Z_VERSION_ERROR) png_error(png_ptr,
 555.545 +          "zlib failed to initialize compressor -- version error");
 555.546 +      if (ret == Z_STREAM_ERROR) png_error(png_ptr,
 555.547 +           "zlib failed to initialize compressor -- stream error");
 555.548 +      if (ret == Z_MEM_ERROR) png_error(png_ptr,
 555.549 +           "zlib failed to initialize compressor -- mem error");
 555.550 +      png_error(png_ptr, "zlib failed to initialize compressor");
 555.551 +   }
 555.552 +   png_ptr->zstream.next_out = png_ptr->zbuf;
 555.553 +   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
 555.554 +   /* libpng is not interested in zstream.data_type */
 555.555 +   /* set it to a predefined value, to avoid its evaluation inside zlib */
 555.556 +   png_ptr->zstream.data_type = Z_BINARY;
 555.557 +
 555.558 +   png_ptr->mode = PNG_HAVE_IHDR;
 555.559 +}
 555.560 +
 555.561 +/* write the palette.  We are careful not to trust png_color to be in the
 555.562 + * correct order for PNG, so people can redefine it to any convenient
 555.563 + * structure.
 555.564 + */
 555.565 +void /* PRIVATE */
 555.566 +png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
 555.567 +{
 555.568 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.569 +   PNG_PLTE;
 555.570 +#endif
 555.571 +   png_uint_32 i;
 555.572 +   png_colorp pal_ptr;
 555.573 +   png_byte buf[3];
 555.574 +
 555.575 +   png_debug(1, "in png_write_PLTE\n");
 555.576 +   if ((
 555.577 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
 555.578 +        !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
 555.579 +#endif
 555.580 +        num_pal == 0) || num_pal > 256)
 555.581 +   {
 555.582 +     if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 555.583 +     {
 555.584 +        png_error(png_ptr, "Invalid number of colors in palette");
 555.585 +     }
 555.586 +     else
 555.587 +     {
 555.588 +        png_warning(png_ptr, "Invalid number of colors in palette");
 555.589 +        return;
 555.590 +     }
 555.591 +   }
 555.592 +
 555.593 +   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
 555.594 +   {
 555.595 +      png_warning(png_ptr,
 555.596 +        "Ignoring request to write a PLTE chunk in grayscale PNG");
 555.597 +      return;
 555.598 +   }
 555.599 +
 555.600 +   png_ptr->num_palette = (png_uint_16)num_pal;
 555.601 +   png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
 555.602 +
 555.603 +   png_write_chunk_start(png_ptr, (png_bytep)png_PLTE,
 555.604 +     (png_uint_32)(num_pal * 3));
 555.605 +#ifndef PNG_NO_POINTER_INDEXING
 555.606 +   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
 555.607 +   {
 555.608 +      buf[0] = pal_ptr->red;
 555.609 +      buf[1] = pal_ptr->green;
 555.610 +      buf[2] = pal_ptr->blue;
 555.611 +      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
 555.612 +   }
 555.613 +#else
 555.614 +   /* This is a little slower but some buggy compilers need to do this instead */
 555.615 +   pal_ptr=palette;
 555.616 +   for (i = 0; i < num_pal; i++)
 555.617 +   {
 555.618 +      buf[0] = pal_ptr[i].red;
 555.619 +      buf[1] = pal_ptr[i].green;
 555.620 +      buf[2] = pal_ptr[i].blue;
 555.621 +      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
 555.622 +   }
 555.623 +#endif
 555.624 +   png_write_chunk_end(png_ptr);
 555.625 +   png_ptr->mode |= PNG_HAVE_PLTE;
 555.626 +}
 555.627 +
 555.628 +/* write an IDAT chunk */
 555.629 +void /* PRIVATE */
 555.630 +png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
 555.631 +{
 555.632 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.633 +   PNG_IDAT;
 555.634 +#endif
 555.635 +   png_debug(1, "in png_write_IDAT\n");
 555.636 +
 555.637 +   /* Optimize the CMF field in the zlib stream. */
 555.638 +   /* This hack of the zlib stream is compliant to the stream specification. */
 555.639 +   if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
 555.640 +       png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
 555.641 +   {
 555.642 +      unsigned int z_cmf = data[0];  /* zlib compression method and flags */
 555.643 +      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
 555.644 +      {
 555.645 +         /* Avoid memory underflows and multiplication overflows. */
 555.646 +         /* The conditions below are practically always satisfied;
 555.647 +            however, they still must be checked. */
 555.648 +         if (length >= 2 &&
 555.649 +             png_ptr->height < 16384 && png_ptr->width < 16384)
 555.650 +         {
 555.651 +            png_uint_32 uncompressed_idat_size = png_ptr->height *
 555.652 +               ((png_ptr->width *
 555.653 +               png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
 555.654 +            unsigned int z_cinfo = z_cmf >> 4;
 555.655 +            unsigned int half_z_window_size = 1 << (z_cinfo + 7);
 555.656 +            while (uncompressed_idat_size <= half_z_window_size &&
 555.657 +                   half_z_window_size >= 256)
 555.658 +            {
 555.659 +               z_cinfo--;
 555.660 +               half_z_window_size >>= 1;
 555.661 +            }
 555.662 +            z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
 555.663 +            if (data[0] != (png_byte)z_cmf)
 555.664 +            {
 555.665 +               data[0] = (png_byte)z_cmf;
 555.666 +               data[1] &= 0xe0;
 555.667 +               data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
 555.668 +            }
 555.669 +         }
 555.670 +      }
 555.671 +      else
 555.672 +         png_error(png_ptr,
 555.673 +            "Invalid zlib compression method or flags in IDAT");
 555.674 +   }
 555.675 +
 555.676 +   png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
 555.677 +   png_ptr->mode |= PNG_HAVE_IDAT;
 555.678 +}
 555.679 +
 555.680 +/* write an IEND chunk */
 555.681 +void /* PRIVATE */
 555.682 +png_write_IEND(png_structp png_ptr)
 555.683 +{
 555.684 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.685 +   PNG_IEND;
 555.686 +#endif
 555.687 +   png_debug(1, "in png_write_IEND\n");
 555.688 +   png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL,
 555.689 +     (png_size_t)0);
 555.690 +   png_ptr->mode |= PNG_HAVE_IEND;
 555.691 +}
 555.692 +
 555.693 +#if defined(PNG_WRITE_gAMA_SUPPORTED)
 555.694 +/* write a gAMA chunk */
 555.695 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 555.696 +void /* PRIVATE */
 555.697 +png_write_gAMA(png_structp png_ptr, double file_gamma)
 555.698 +{
 555.699 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.700 +   PNG_gAMA;
 555.701 +#endif
 555.702 +   png_uint_32 igamma;
 555.703 +   png_byte buf[4];
 555.704 +
 555.705 +   png_debug(1, "in png_write_gAMA\n");
 555.706 +   /* file_gamma is saved in 1/100,000ths */
 555.707 +   igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
 555.708 +   png_save_uint_32(buf, igamma);
 555.709 +   png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
 555.710 +}
 555.711 +#endif
 555.712 +#ifdef PNG_FIXED_POINT_SUPPORTED
 555.713 +void /* PRIVATE */
 555.714 +png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
 555.715 +{
 555.716 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.717 +   PNG_gAMA;
 555.718 +#endif
 555.719 +   png_byte buf[4];
 555.720 +
 555.721 +   png_debug(1, "in png_write_gAMA\n");
 555.722 +   /* file_gamma is saved in 1/100,000ths */
 555.723 +   png_save_uint_32(buf, (png_uint_32)file_gamma);
 555.724 +   png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
 555.725 +}
 555.726 +#endif
 555.727 +#endif
 555.728 +
 555.729 +#if defined(PNG_WRITE_sRGB_SUPPORTED)
 555.730 +/* write a sRGB chunk */
 555.731 +void /* PRIVATE */
 555.732 +png_write_sRGB(png_structp png_ptr, int srgb_intent)
 555.733 +{
 555.734 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.735 +   PNG_sRGB;
 555.736 +#endif
 555.737 +   png_byte buf[1];
 555.738 +
 555.739 +   png_debug(1, "in png_write_sRGB\n");
 555.740 +   if (srgb_intent >= PNG_sRGB_INTENT_LAST)
 555.741 +         png_warning(png_ptr,
 555.742 +            "Invalid sRGB rendering intent specified");
 555.743 +   buf[0]=(png_byte)srgb_intent;
 555.744 +   png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
 555.745 +}
 555.746 +#endif
 555.747 +
 555.748 +#if defined(PNG_WRITE_iCCP_SUPPORTED)
 555.749 +/* write an iCCP chunk */
 555.750 +void /* PRIVATE */
 555.751 +png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
 555.752 +   png_charp profile, int profile_len)
 555.753 +{
 555.754 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.755 +   PNG_iCCP;
 555.756 +#endif
 555.757 +   png_size_t name_len;
 555.758 +   png_charp new_name;
 555.759 +   compression_state comp;
 555.760 +   int embedded_profile_len = 0;
 555.761 +
 555.762 +   png_debug(1, "in png_write_iCCP\n");
 555.763 +
 555.764 +   comp.num_output_ptr = 0;
 555.765 +   comp.max_output_ptr = 0;
 555.766 +   comp.output_ptr = NULL;
 555.767 +   comp.input = NULL;
 555.768 +   comp.input_len = 0;
 555.769 +
 555.770 +   if (name == NULL || (name_len = png_check_keyword(png_ptr, name,
 555.771 +      &new_name)) == 0)
 555.772 +   {
 555.773 +      png_warning(png_ptr, "Empty keyword in iCCP chunk");
 555.774 +      return;
 555.775 +   }
 555.776 +
 555.777 +   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
 555.778 +      png_warning(png_ptr, "Unknown compression type in iCCP chunk");
 555.779 +
 555.780 +   if (profile == NULL)
 555.781 +      profile_len = 0;
 555.782 +
 555.783 +   if (profile_len > 3)
 555.784 +      embedded_profile_len =
 555.785 +          ((*( (png_bytep)profile    ))<<24) |
 555.786 +          ((*( (png_bytep)profile + 1))<<16) |
 555.787 +          ((*( (png_bytep)profile + 2))<< 8) |
 555.788 +          ((*( (png_bytep)profile + 3))    );
 555.789 +
 555.790 +   if (profile_len < embedded_profile_len)
 555.791 +   {
 555.792 +      png_warning(png_ptr,
 555.793 +        "Embedded profile length too large in iCCP chunk");
 555.794 +      return;
 555.795 +   }
 555.796 +
 555.797 +   if (profile_len > embedded_profile_len)
 555.798 +   {
 555.799 +      png_warning(png_ptr,
 555.800 +        "Truncating profile to actual length in iCCP chunk");
 555.801 +      profile_len = embedded_profile_len;
 555.802 +   }
 555.803 +
 555.804 +   if (profile_len)
 555.805 +      profile_len = png_text_compress(png_ptr, profile,
 555.806 +        (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp);
 555.807 +
 555.808 +   /* make sure we include the NULL after the name and the compression type */
 555.809 +   png_write_chunk_start(png_ptr, (png_bytep)png_iCCP,
 555.810 +          (png_uint_32)(name_len + profile_len + 2));
 555.811 +   new_name[name_len + 1] = 0x00;
 555.812 +   png_write_chunk_data(png_ptr, (png_bytep)new_name,
 555.813 +     (png_size_t)(name_len + 2));
 555.814 +
 555.815 +   if (profile_len)
 555.816 +      png_write_compressed_data_out(png_ptr, &comp);
 555.817 +
 555.818 +   png_write_chunk_end(png_ptr);
 555.819 +   png_free(png_ptr, new_name);
 555.820 +}
 555.821 +#endif
 555.822 +
 555.823 +#if defined(PNG_WRITE_sPLT_SUPPORTED)
 555.824 +/* write a sPLT chunk */
 555.825 +void /* PRIVATE */
 555.826 +png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
 555.827 +{
 555.828 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.829 +   PNG_sPLT;
 555.830 +#endif
 555.831 +   png_size_t name_len;
 555.832 +   png_charp new_name;
 555.833 +   png_byte entrybuf[10];
 555.834 +   int entry_size = (spalette->depth == 8 ? 6 : 10);
 555.835 +   int palette_size = entry_size * spalette->nentries;
 555.836 +   png_sPLT_entryp ep;
 555.837 +#ifdef PNG_NO_POINTER_INDEXING
 555.838 +   int i;
 555.839 +#endif
 555.840 +
 555.841 +   png_debug(1, "in png_write_sPLT\n");
 555.842 +   if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr,
 555.843 +      spalette->name, &new_name))==0)
 555.844 +   {
 555.845 +      png_warning(png_ptr, "Empty keyword in sPLT chunk");
 555.846 +      return;
 555.847 +   }
 555.848 +
 555.849 +   /* make sure we include the NULL after the name */
 555.850 +   png_write_chunk_start(png_ptr, (png_bytep)png_sPLT,
 555.851 +     (png_uint_32)(name_len + 2 + palette_size));
 555.852 +   png_write_chunk_data(png_ptr, (png_bytep)new_name,
 555.853 +     (png_size_t)(name_len + 1));
 555.854 +   png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, (png_size_t)1);
 555.855 +
 555.856 +   /* loop through each palette entry, writing appropriately */
 555.857 +#ifndef PNG_NO_POINTER_INDEXING
 555.858 +   for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
 555.859 +   {
 555.860 +      if (spalette->depth == 8)
 555.861 +      {
 555.862 +          entrybuf[0] = (png_byte)ep->red;
 555.863 +          entrybuf[1] = (png_byte)ep->green;
 555.864 +          entrybuf[2] = (png_byte)ep->blue;
 555.865 +          entrybuf[3] = (png_byte)ep->alpha;
 555.866 +          png_save_uint_16(entrybuf + 4, ep->frequency);
 555.867 +      }
 555.868 +      else
 555.869 +      {
 555.870 +          png_save_uint_16(entrybuf + 0, ep->red);
 555.871 +          png_save_uint_16(entrybuf + 2, ep->green);
 555.872 +          png_save_uint_16(entrybuf + 4, ep->blue);
 555.873 +          png_save_uint_16(entrybuf + 6, ep->alpha);
 555.874 +          png_save_uint_16(entrybuf + 8, ep->frequency);
 555.875 +      }
 555.876 +      png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
 555.877 +   }
 555.878 +#else
 555.879 +   ep=spalette->entries;
 555.880 +   for (i=0; i>spalette->nentries; i++)
 555.881 +   {
 555.882 +      if (spalette->depth == 8)
 555.883 +      {
 555.884 +          entrybuf[0] = (png_byte)ep[i].red;
 555.885 +          entrybuf[1] = (png_byte)ep[i].green;
 555.886 +          entrybuf[2] = (png_byte)ep[i].blue;
 555.887 +          entrybuf[3] = (png_byte)ep[i].alpha;
 555.888 +          png_save_uint_16(entrybuf + 4, ep[i].frequency);
 555.889 +      }
 555.890 +      else
 555.891 +      {
 555.892 +          png_save_uint_16(entrybuf + 0, ep[i].red);
 555.893 +          png_save_uint_16(entrybuf + 2, ep[i].green);
 555.894 +          png_save_uint_16(entrybuf + 4, ep[i].blue);
 555.895 +          png_save_uint_16(entrybuf + 6, ep[i].alpha);
 555.896 +          png_save_uint_16(entrybuf + 8, ep[i].frequency);
 555.897 +      }
 555.898 +      png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
 555.899 +   }
 555.900 +#endif
 555.901 +
 555.902 +   png_write_chunk_end(png_ptr);
 555.903 +   png_free(png_ptr, new_name);
 555.904 +}
 555.905 +#endif
 555.906 +
 555.907 +#if defined(PNG_WRITE_sBIT_SUPPORTED)
 555.908 +/* write the sBIT chunk */
 555.909 +void /* PRIVATE */
 555.910 +png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
 555.911 +{
 555.912 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.913 +   PNG_sBIT;
 555.914 +#endif
 555.915 +   png_byte buf[4];
 555.916 +   png_size_t size;
 555.917 +
 555.918 +   png_debug(1, "in png_write_sBIT\n");
 555.919 +   /* make sure we don't depend upon the order of PNG_COLOR_8 */
 555.920 +   if (color_type & PNG_COLOR_MASK_COLOR)
 555.921 +   {
 555.922 +      png_byte maxbits;
 555.923 +
 555.924 +      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
 555.925 +                png_ptr->usr_bit_depth);
 555.926 +      if (sbit->red == 0 || sbit->red > maxbits ||
 555.927 +          sbit->green == 0 || sbit->green > maxbits ||
 555.928 +          sbit->blue == 0 || sbit->blue > maxbits)
 555.929 +      {
 555.930 +         png_warning(png_ptr, "Invalid sBIT depth specified");
 555.931 +         return;
 555.932 +      }
 555.933 +      buf[0] = sbit->red;
 555.934 +      buf[1] = sbit->green;
 555.935 +      buf[2] = sbit->blue;
 555.936 +      size = 3;
 555.937 +   }
 555.938 +   else
 555.939 +   {
 555.940 +      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
 555.941 +      {
 555.942 +         png_warning(png_ptr, "Invalid sBIT depth specified");
 555.943 +         return;
 555.944 +      }
 555.945 +      buf[0] = sbit->gray;
 555.946 +      size = 1;
 555.947 +   }
 555.948 +
 555.949 +   if (color_type & PNG_COLOR_MASK_ALPHA)
 555.950 +   {
 555.951 +      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
 555.952 +      {
 555.953 +         png_warning(png_ptr, "Invalid sBIT depth specified");
 555.954 +         return;
 555.955 +      }
 555.956 +      buf[size++] = sbit->alpha;
 555.957 +   }
 555.958 +
 555.959 +   png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size);
 555.960 +}
 555.961 +#endif
 555.962 +
 555.963 +#if defined(PNG_WRITE_cHRM_SUPPORTED)
 555.964 +/* write the cHRM chunk */
 555.965 +#ifdef PNG_FLOATING_POINT_SUPPORTED
 555.966 +void /* PRIVATE */
 555.967 +png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
 555.968 +   double red_x, double red_y, double green_x, double green_y,
 555.969 +   double blue_x, double blue_y)
 555.970 +{
 555.971 +#ifdef PNG_USE_LOCAL_ARRAYS
 555.972 +   PNG_cHRM;
 555.973 +#endif
 555.974 +   png_byte buf[32];
 555.975 +   png_uint_32 itemp;
 555.976 +
 555.977 +   png_debug(1, "in png_write_cHRM\n");
 555.978 +   /* each value is saved in 1/100,000ths */
 555.979 +   if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
 555.980 +       white_x + white_y > 1.0)
 555.981 +   {
 555.982 +      png_warning(png_ptr, "Invalid cHRM white point specified");
 555.983 +#if !defined(PNG_NO_CONSOLE_IO)
 555.984 +      fprintf(stderr, "white_x=%f, white_y=%f\n", white_x, white_y);
 555.985 +#endif
 555.986 +      return;
 555.987 +   }
 555.988 +   itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
 555.989 +   png_save_uint_32(buf, itemp);
 555.990 +   itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
 555.991 +   png_save_uint_32(buf + 4, itemp);
 555.992 +
 555.993 +   if (red_x < 0 ||  red_y < 0 || red_x + red_y > 1.0)
 555.994 +   {
 555.995 +      png_warning(png_ptr, "Invalid cHRM red point specified");
 555.996 +      return;
 555.997 +   }
 555.998 +   itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
 555.999 +   png_save_uint_32(buf + 8, itemp);
555.1000 +   itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
555.1001 +   png_save_uint_32(buf + 12, itemp);
555.1002 +
555.1003 +   if (green_x < 0 || green_y < 0 || green_x + green_y > 1.0)
555.1004 +   {
555.1005 +      png_warning(png_ptr, "Invalid cHRM green point specified");
555.1006 +      return;
555.1007 +   }
555.1008 +   itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
555.1009 +   png_save_uint_32(buf + 16, itemp);
555.1010 +   itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
555.1011 +   png_save_uint_32(buf + 20, itemp);
555.1012 +
555.1013 +   if (blue_x < 0 || blue_y < 0 || blue_x + blue_y > 1.0)
555.1014 +   {
555.1015 +      png_warning(png_ptr, "Invalid cHRM blue point specified");
555.1016 +      return;
555.1017 +   }
555.1018 +   itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
555.1019 +   png_save_uint_32(buf + 24, itemp);
555.1020 +   itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
555.1021 +   png_save_uint_32(buf + 28, itemp);
555.1022 +
555.1023 +   png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
555.1024 +}
555.1025 +#endif
555.1026 +#ifdef PNG_FIXED_POINT_SUPPORTED
555.1027 +void /* PRIVATE */
555.1028 +png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
555.1029 +   png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
555.1030 +   png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
555.1031 +   png_fixed_point blue_y)
555.1032 +{
555.1033 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1034 +   PNG_cHRM;
555.1035 +#endif
555.1036 +   png_byte buf[32];
555.1037 +
555.1038 +   png_debug(1, "in png_write_cHRM\n");
555.1039 +   /* each value is saved in 1/100,000ths */
555.1040 +   if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L)
555.1041 +   {
555.1042 +      png_warning(png_ptr, "Invalid fixed cHRM white point specified");
555.1043 +#if !defined(PNG_NO_CONSOLE_IO)
555.1044 +      fprintf(stderr, "white_x=%ld, white_y=%ld\n", (unsigned long)white_x,
555.1045 +        (unsigned long)white_y);
555.1046 +#endif
555.1047 +      return;
555.1048 +   }
555.1049 +   png_save_uint_32(buf, (png_uint_32)white_x);
555.1050 +   png_save_uint_32(buf + 4, (png_uint_32)white_y);
555.1051 +
555.1052 +   if (red_x + red_y > 100000L)
555.1053 +   {
555.1054 +      png_warning(png_ptr, "Invalid cHRM fixed red point specified");
555.1055 +      return;
555.1056 +   }
555.1057 +   png_save_uint_32(buf + 8, (png_uint_32)red_x);
555.1058 +   png_save_uint_32(buf + 12, (png_uint_32)red_y);
555.1059 +
555.1060 +   if (green_x + green_y > 100000L)
555.1061 +   {
555.1062 +      png_warning(png_ptr, "Invalid fixed cHRM green point specified");
555.1063 +      return;
555.1064 +   }
555.1065 +   png_save_uint_32(buf + 16, (png_uint_32)green_x);
555.1066 +   png_save_uint_32(buf + 20, (png_uint_32)green_y);
555.1067 +
555.1068 +   if (blue_x + blue_y > 100000L)
555.1069 +   {
555.1070 +      png_warning(png_ptr, "Invalid fixed cHRM blue point specified");
555.1071 +      return;
555.1072 +   }
555.1073 +   png_save_uint_32(buf + 24, (png_uint_32)blue_x);
555.1074 +   png_save_uint_32(buf + 28, (png_uint_32)blue_y);
555.1075 +
555.1076 +   png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
555.1077 +}
555.1078 +#endif
555.1079 +#endif
555.1080 +
555.1081 +#if defined(PNG_WRITE_tRNS_SUPPORTED)
555.1082 +/* write the tRNS chunk */
555.1083 +void /* PRIVATE */
555.1084 +png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
555.1085 +   int num_trans, int color_type)
555.1086 +{
555.1087 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1088 +   PNG_tRNS;
555.1089 +#endif
555.1090 +   png_byte buf[6];
555.1091 +
555.1092 +   png_debug(1, "in png_write_tRNS\n");
555.1093 +   if (color_type == PNG_COLOR_TYPE_PALETTE)
555.1094 +   {
555.1095 +      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
555.1096 +      {
555.1097 +         png_warning(png_ptr, "Invalid number of transparent colors specified");
555.1098 +         return;
555.1099 +      }
555.1100 +      /* write the chunk out as it is */
555.1101 +      png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans,
555.1102 +        (png_size_t)num_trans);
555.1103 +   }
555.1104 +   else if (color_type == PNG_COLOR_TYPE_GRAY)
555.1105 +   {
555.1106 +      /* one 16 bit value */
555.1107 +      if (tran->gray >= (1 << png_ptr->bit_depth))
555.1108 +      {
555.1109 +         png_warning(png_ptr,
555.1110 +           "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
555.1111 +         return;
555.1112 +      }
555.1113 +      png_save_uint_16(buf, tran->gray);
555.1114 +      png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2);
555.1115 +   }
555.1116 +   else if (color_type == PNG_COLOR_TYPE_RGB)
555.1117 +   {
555.1118 +      /* three 16 bit values */
555.1119 +      png_save_uint_16(buf, tran->red);
555.1120 +      png_save_uint_16(buf + 2, tran->green);
555.1121 +      png_save_uint_16(buf + 4, tran->blue);
555.1122 +      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
555.1123 +      {
555.1124 +         png_warning(png_ptr,
555.1125 +           "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
555.1126 +         return;
555.1127 +      }
555.1128 +      png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6);
555.1129 +   }
555.1130 +   else
555.1131 +   {
555.1132 +      png_warning(png_ptr, "Can't write tRNS with an alpha channel");
555.1133 +   }
555.1134 +}
555.1135 +#endif
555.1136 +
555.1137 +#if defined(PNG_WRITE_bKGD_SUPPORTED)
555.1138 +/* write the background chunk */
555.1139 +void /* PRIVATE */
555.1140 +png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
555.1141 +{
555.1142 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1143 +   PNG_bKGD;
555.1144 +#endif
555.1145 +   png_byte buf[6];
555.1146 +
555.1147 +   png_debug(1, "in png_write_bKGD\n");
555.1148 +   if (color_type == PNG_COLOR_TYPE_PALETTE)
555.1149 +   {
555.1150 +      if (
555.1151 +#if defined(PNG_MNG_FEATURES_SUPPORTED)
555.1152 +          (png_ptr->num_palette ||
555.1153 +          (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
555.1154 +#endif
555.1155 +         back->index > png_ptr->num_palette)
555.1156 +      {
555.1157 +         png_warning(png_ptr, "Invalid background palette index");
555.1158 +         return;
555.1159 +      }
555.1160 +      buf[0] = back->index;
555.1161 +      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1);
555.1162 +   }
555.1163 +   else if (color_type & PNG_COLOR_MASK_COLOR)
555.1164 +   {
555.1165 +      png_save_uint_16(buf, back->red);
555.1166 +      png_save_uint_16(buf + 2, back->green);
555.1167 +      png_save_uint_16(buf + 4, back->blue);
555.1168 +      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
555.1169 +      {
555.1170 +         png_warning(png_ptr,
555.1171 +           "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
555.1172 +         return;
555.1173 +      }
555.1174 +      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6);
555.1175 +   }
555.1176 +   else
555.1177 +   {
555.1178 +      if (back->gray >= (1 << png_ptr->bit_depth))
555.1179 +      {
555.1180 +         png_warning(png_ptr,
555.1181 +           "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
555.1182 +         return;
555.1183 +      }
555.1184 +      png_save_uint_16(buf, back->gray);
555.1185 +      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2);
555.1186 +   }
555.1187 +}
555.1188 +#endif
555.1189 +
555.1190 +#if defined(PNG_WRITE_hIST_SUPPORTED)
555.1191 +/* write the histogram */
555.1192 +void /* PRIVATE */
555.1193 +png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
555.1194 +{
555.1195 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1196 +   PNG_hIST;
555.1197 +#endif
555.1198 +   int i;
555.1199 +   png_byte buf[3];
555.1200 +
555.1201 +   png_debug(1, "in png_write_hIST\n");
555.1202 +   if (num_hist > (int)png_ptr->num_palette)
555.1203 +   {
555.1204 +      png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist,
555.1205 +         png_ptr->num_palette);
555.1206 +      png_warning(png_ptr, "Invalid number of histogram entries specified");
555.1207 +      return;
555.1208 +   }
555.1209 +
555.1210 +   png_write_chunk_start(png_ptr, (png_bytep)png_hIST,
555.1211 +     (png_uint_32)(num_hist * 2));
555.1212 +   for (i = 0; i < num_hist; i++)
555.1213 +   {
555.1214 +      png_save_uint_16(buf, hist[i]);
555.1215 +      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
555.1216 +   }
555.1217 +   png_write_chunk_end(png_ptr);
555.1218 +}
555.1219 +#endif
555.1220 +
555.1221 +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
555.1222 +    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
555.1223 +/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
555.1224 + * and if invalid, correct the keyword rather than discarding the entire
555.1225 + * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
555.1226 + * length, forbids leading or trailing whitespace, multiple internal spaces,
555.1227 + * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
555.1228 + *
555.1229 + * The new_key is allocated to hold the corrected keyword and must be freed
555.1230 + * by the calling routine.  This avoids problems with trying to write to
555.1231 + * static keywords without having to have duplicate copies of the strings.
555.1232 + */
555.1233 +png_size_t /* PRIVATE */
555.1234 +png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
555.1235 +{
555.1236 +   png_size_t key_len;
555.1237 +   png_charp kp, dp;
555.1238 +   int kflag;
555.1239 +   int kwarn=0;
555.1240 +
555.1241 +   png_debug(1, "in png_check_keyword\n");
555.1242 +   *new_key = NULL;
555.1243 +
555.1244 +   if (key == NULL || (key_len = png_strlen(key)) == 0)
555.1245 +   {
555.1246 +      png_warning(png_ptr, "zero length keyword");
555.1247 +      return ((png_size_t)0);
555.1248 +   }
555.1249 +
555.1250 +   png_debug1(2, "Keyword to be checked is '%s'\n", key);
555.1251 +
555.1252 +   *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
555.1253 +   if (*new_key == NULL)
555.1254 +   {
555.1255 +      png_warning(png_ptr, "Out of memory while procesing keyword");
555.1256 +      return ((png_size_t)0);
555.1257 +   }
555.1258 +
555.1259 +   /* Replace non-printing characters with a blank and print a warning */
555.1260 +   for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
555.1261 +   {
555.1262 +      if ((png_byte)*kp < 0x20 ||
555.1263 +         ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1))
555.1264 +      {
555.1265 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
555.1266 +         char msg[40];
555.1267 +
555.1268 +         png_snprintf(msg, 40,
555.1269 +           "invalid keyword character 0x%02X", (png_byte)*kp);
555.1270 +         png_warning(png_ptr, msg);
555.1271 +#else
555.1272 +         png_warning(png_ptr, "invalid character in keyword");
555.1273 +#endif
555.1274 +         *dp = ' ';
555.1275 +      }
555.1276 +      else
555.1277 +      {
555.1278 +         *dp = *kp;
555.1279 +      }
555.1280 +   }
555.1281 +   *dp = '\0';
555.1282 +
555.1283 +   /* Remove any trailing white space. */
555.1284 +   kp = *new_key + key_len - 1;
555.1285 +   if (*kp == ' ')
555.1286 +   {
555.1287 +      png_warning(png_ptr, "trailing spaces removed from keyword");
555.1288 +
555.1289 +      while (*kp == ' ')
555.1290 +      {
555.1291 +        *(kp--) = '\0';
555.1292 +        key_len--;
555.1293 +      }
555.1294 +   }
555.1295 +
555.1296 +   /* Remove any leading white space. */
555.1297 +   kp = *new_key;
555.1298 +   if (*kp == ' ')
555.1299 +   {
555.1300 +      png_warning(png_ptr, "leading spaces removed from keyword");
555.1301 +
555.1302 +      while (*kp == ' ')
555.1303 +      {
555.1304 +        kp++;
555.1305 +        key_len--;
555.1306 +      }
555.1307 +   }
555.1308 +
555.1309 +   png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp);
555.1310 +
555.1311 +   /* Remove multiple internal spaces. */
555.1312 +   for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
555.1313 +   {
555.1314 +      if (*kp == ' ' && kflag == 0)
555.1315 +      {
555.1316 +         *(dp++) = *kp;
555.1317 +         kflag = 1;
555.1318 +      }
555.1319 +      else if (*kp == ' ')
555.1320 +      {
555.1321 +         key_len--;
555.1322 +         kwarn=1;
555.1323 +      }
555.1324 +      else
555.1325 +      {
555.1326 +         *(dp++) = *kp;
555.1327 +         kflag = 0;
555.1328 +      }
555.1329 +   }
555.1330 +   *dp = '\0';
555.1331 +   if (kwarn)
555.1332 +      png_warning(png_ptr, "extra interior spaces removed from keyword");
555.1333 +
555.1334 +   if (key_len == 0)
555.1335 +   {
555.1336 +      png_free(png_ptr, *new_key);
555.1337 +       *new_key=NULL;
555.1338 +      png_warning(png_ptr, "Zero length keyword");
555.1339 +   }
555.1340 +
555.1341 +   if (key_len > 79)
555.1342 +   {
555.1343 +      png_warning(png_ptr, "keyword length must be 1 - 79 characters");
555.1344 +      new_key[79] = '\0';
555.1345 +      key_len = 79;
555.1346 +   }
555.1347 +
555.1348 +   return (key_len);
555.1349 +}
555.1350 +#endif
555.1351 +
555.1352 +#if defined(PNG_WRITE_tEXt_SUPPORTED)
555.1353 +/* write a tEXt chunk */
555.1354 +void /* PRIVATE */
555.1355 +png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
555.1356 +   png_size_t text_len)
555.1357 +{
555.1358 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1359 +   PNG_tEXt;
555.1360 +#endif
555.1361 +   png_size_t key_len;
555.1362 +   png_charp new_key;
555.1363 +
555.1364 +   png_debug(1, "in png_write_tEXt\n");
555.1365 +   if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
555.1366 +   {
555.1367 +      png_warning(png_ptr, "Empty keyword in tEXt chunk");
555.1368 +      return;
555.1369 +   }
555.1370 +
555.1371 +   if (text == NULL || *text == '\0')
555.1372 +      text_len = 0;
555.1373 +   else
555.1374 +      text_len = png_strlen(text);
555.1375 +
555.1376 +   /* make sure we include the 0 after the key */
555.1377 +   png_write_chunk_start(png_ptr, (png_bytep)png_tEXt,
555.1378 +      (png_uint_32)(key_len + text_len + 1));
555.1379 +   /*
555.1380 +    * We leave it to the application to meet PNG-1.0 requirements on the
555.1381 +    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
555.1382 +    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
555.1383 +    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
555.1384 +    */
555.1385 +   png_write_chunk_data(png_ptr, (png_bytep)new_key,
555.1386 +     (png_size_t)(key_len + 1));
555.1387 +   if (text_len)
555.1388 +      png_write_chunk_data(png_ptr, (png_bytep)text, (png_size_t)text_len);
555.1389 +
555.1390 +   png_write_chunk_end(png_ptr);
555.1391 +   png_free(png_ptr, new_key);
555.1392 +}
555.1393 +#endif
555.1394 +
555.1395 +#if defined(PNG_WRITE_zTXt_SUPPORTED)
555.1396 +/* write a compressed text chunk */
555.1397 +void /* PRIVATE */
555.1398 +png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
555.1399 +   png_size_t text_len, int compression)
555.1400 +{
555.1401 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1402 +   PNG_zTXt;
555.1403 +#endif
555.1404 +   png_size_t key_len;
555.1405 +   char buf[1];
555.1406 +   png_charp new_key;
555.1407 +   compression_state comp;
555.1408 +
555.1409 +   png_debug(1, "in png_write_zTXt\n");
555.1410 +
555.1411 +   comp.num_output_ptr = 0;
555.1412 +   comp.max_output_ptr = 0;
555.1413 +   comp.output_ptr = NULL;
555.1414 +   comp.input = NULL;
555.1415 +   comp.input_len = 0;
555.1416 +
555.1417 +   if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
555.1418 +   {
555.1419 +      png_warning(png_ptr, "Empty keyword in zTXt chunk");
555.1420 +      png_free(png_ptr, new_key);
555.1421 +      return;
555.1422 +   }
555.1423 +
555.1424 +   if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
555.1425 +   {
555.1426 +      png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
555.1427 +      png_free(png_ptr, new_key);
555.1428 +      return;
555.1429 +   }
555.1430 +
555.1431 +   text_len = png_strlen(text);
555.1432 +
555.1433 +   /* compute the compressed data; do it now for the length */
555.1434 +   text_len = png_text_compress(png_ptr, text, text_len, compression,
555.1435 +       &comp);
555.1436 +
555.1437 +   /* write start of chunk */
555.1438 +   png_write_chunk_start(png_ptr, (png_bytep)png_zTXt,
555.1439 +     (png_uint_32)(key_len+text_len + 2));
555.1440 +   /* write key */
555.1441 +   png_write_chunk_data(png_ptr, (png_bytep)new_key,
555.1442 +     (png_size_t)(key_len + 1));
555.1443 +   png_free(png_ptr, new_key);
555.1444 +
555.1445 +   buf[0] = (png_byte)compression;
555.1446 +   /* write compression */
555.1447 +   png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
555.1448 +   /* write the compressed data */
555.1449 +   png_write_compressed_data_out(png_ptr, &comp);
555.1450 +
555.1451 +   /* close the chunk */
555.1452 +   png_write_chunk_end(png_ptr);
555.1453 +}
555.1454 +#endif
555.1455 +
555.1456 +#if defined(PNG_WRITE_iTXt_SUPPORTED)
555.1457 +/* write an iTXt chunk */
555.1458 +void /* PRIVATE */
555.1459 +png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
555.1460 +    png_charp lang, png_charp lang_key, png_charp text)
555.1461 +{
555.1462 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1463 +   PNG_iTXt;
555.1464 +#endif
555.1465 +   png_size_t lang_len, key_len, lang_key_len, text_len;
555.1466 +   png_charp new_lang, new_key;
555.1467 +   png_byte cbuf[2];
555.1468 +   compression_state comp;
555.1469 +
555.1470 +   png_debug(1, "in png_write_iTXt\n");
555.1471 +
555.1472 +   comp.num_output_ptr = 0;
555.1473 +   comp.max_output_ptr = 0;
555.1474 +   comp.output_ptr = NULL;
555.1475 +   comp.input = NULL;
555.1476 +
555.1477 +   if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
555.1478 +   {
555.1479 +      png_warning(png_ptr, "Empty keyword in iTXt chunk");
555.1480 +      return;
555.1481 +   }
555.1482 +   if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0)
555.1483 +   {
555.1484 +      png_warning(png_ptr, "Empty language field in iTXt chunk");
555.1485 +      new_lang = NULL;
555.1486 +      lang_len = 0;
555.1487 +   }
555.1488 +
555.1489 +   if (lang_key == NULL)
555.1490 +     lang_key_len = 0;
555.1491 +   else
555.1492 +     lang_key_len = png_strlen(lang_key);
555.1493 +
555.1494 +   if (text == NULL)
555.1495 +      text_len = 0;
555.1496 +   else
555.1497 +     text_len = png_strlen(text);
555.1498 +
555.1499 +   /* compute the compressed data; do it now for the length */
555.1500 +   text_len = png_text_compress(png_ptr, text, text_len, compression-2,
555.1501 +      &comp);
555.1502 +
555.1503 +
555.1504 +   /* make sure we include the compression flag, the compression byte,
555.1505 +    * and the NULs after the key, lang, and lang_key parts */
555.1506 +
555.1507 +   png_write_chunk_start(png_ptr, (png_bytep)png_iTXt,
555.1508 +          (png_uint_32)(
555.1509 +        5 /* comp byte, comp flag, terminators for key, lang and lang_key */
555.1510 +        + key_len
555.1511 +        + lang_len
555.1512 +        + lang_key_len
555.1513 +        + text_len));
555.1514 +
555.1515 +   /*
555.1516 +    * We leave it to the application to meet PNG-1.0 requirements on the
555.1517 +    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
555.1518 +    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
555.1519 +    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
555.1520 +    */
555.1521 +   png_write_chunk_data(png_ptr, (png_bytep)new_key,
555.1522 +     (png_size_t)(key_len + 1));
555.1523 +
555.1524 +   /* set the compression flag */
555.1525 +   if (compression == PNG_ITXT_COMPRESSION_NONE || \
555.1526 +       compression == PNG_TEXT_COMPRESSION_NONE)
555.1527 +       cbuf[0] = 0;
555.1528 +   else /* compression == PNG_ITXT_COMPRESSION_zTXt */
555.1529 +       cbuf[0] = 1;
555.1530 +   /* set the compression method */
555.1531 +   cbuf[1] = 0;
555.1532 +   png_write_chunk_data(png_ptr, cbuf, (png_size_t)2);
555.1533 +
555.1534 +   cbuf[0] = 0;
555.1535 +   png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf),
555.1536 +     (png_size_t)(lang_len + 1));
555.1537 +   png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf),
555.1538 +     (png_size_t)(lang_key_len + 1));
555.1539 +   png_write_compressed_data_out(png_ptr, &comp);
555.1540 +
555.1541 +   png_write_chunk_end(png_ptr);
555.1542 +   png_free(png_ptr, new_key);
555.1543 +   png_free(png_ptr, new_lang);
555.1544 +}
555.1545 +#endif
555.1546 +
555.1547 +#if defined(PNG_WRITE_oFFs_SUPPORTED)
555.1548 +/* write the oFFs chunk */
555.1549 +void /* PRIVATE */
555.1550 +png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
555.1551 +   int unit_type)
555.1552 +{
555.1553 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1554 +   PNG_oFFs;
555.1555 +#endif
555.1556 +   png_byte buf[9];
555.1557 +
555.1558 +   png_debug(1, "in png_write_oFFs\n");
555.1559 +   if (unit_type >= PNG_OFFSET_LAST)
555.1560 +      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
555.1561 +
555.1562 +   png_save_int_32(buf, x_offset);
555.1563 +   png_save_int_32(buf + 4, y_offset);
555.1564 +   buf[8] = (png_byte)unit_type;
555.1565 +
555.1566 +   png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9);
555.1567 +}
555.1568 +#endif
555.1569 +#if defined(PNG_WRITE_pCAL_SUPPORTED)
555.1570 +/* write the pCAL chunk (described in the PNG extensions document) */
555.1571 +void /* PRIVATE */
555.1572 +png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
555.1573 +   png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
555.1574 +{
555.1575 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1576 +   PNG_pCAL;
555.1577 +#endif
555.1578 +   png_size_t purpose_len, units_len, total_len;
555.1579 +   png_uint_32p params_len;
555.1580 +   png_byte buf[10];
555.1581 +   png_charp new_purpose;
555.1582 +   int i;
555.1583 +
555.1584 +   png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams);
555.1585 +   if (type >= PNG_EQUATION_LAST)
555.1586 +      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
555.1587 +
555.1588 +   purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
555.1589 +   png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len);
555.1590 +   units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
555.1591 +   png_debug1(3, "pCAL units length = %d\n", (int)units_len);
555.1592 +   total_len = purpose_len + units_len + 10;
555.1593 +
555.1594 +   params_len = (png_uint_32p)png_malloc(png_ptr,
555.1595 +      (png_uint_32)(nparams * png_sizeof(png_uint_32)));
555.1596 +
555.1597 +   /* Find the length of each parameter, making sure we don't count the
555.1598 +      null terminator for the last parameter. */
555.1599 +   for (i = 0; i < nparams; i++)
555.1600 +   {
555.1601 +      params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
555.1602 +      png_debug2(3, "pCAL parameter %d length = %lu\n", i,
555.1603 +        (unsigned long) params_len[i]);
555.1604 +      total_len += (png_size_t)params_len[i];
555.1605 +   }
555.1606 +
555.1607 +   png_debug1(3, "pCAL total length = %d\n", (int)total_len);
555.1608 +   png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len);
555.1609 +   png_write_chunk_data(png_ptr, (png_bytep)new_purpose,
555.1610 +     (png_size_t)purpose_len);
555.1611 +   png_save_int_32(buf, X0);
555.1612 +   png_save_int_32(buf + 4, X1);
555.1613 +   buf[8] = (png_byte)type;
555.1614 +   buf[9] = (png_byte)nparams;
555.1615 +   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
555.1616 +   png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
555.1617 +
555.1618 +   png_free(png_ptr, new_purpose);
555.1619 +
555.1620 +   for (i = 0; i < nparams; i++)
555.1621 +   {
555.1622 +      png_write_chunk_data(png_ptr, (png_bytep)params[i],
555.1623 +         (png_size_t)params_len[i]);
555.1624 +   }
555.1625 +
555.1626 +   png_free(png_ptr, params_len);
555.1627 +   png_write_chunk_end(png_ptr);
555.1628 +}
555.1629 +#endif
555.1630 +
555.1631 +#if defined(PNG_WRITE_sCAL_SUPPORTED)
555.1632 +/* write the sCAL chunk */
555.1633 +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
555.1634 +void /* PRIVATE */
555.1635 +png_write_sCAL(png_structp png_ptr, int unit, double width, double height)
555.1636 +{
555.1637 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1638 +   PNG_sCAL;
555.1639 +#endif
555.1640 +   char buf[64];
555.1641 +   png_size_t total_len;
555.1642 +
555.1643 +   png_debug(1, "in png_write_sCAL\n");
555.1644 +
555.1645 +   buf[0] = (char)unit;
555.1646 +#if defined(_WIN32_WCE)
555.1647 +/* sprintf() function is not supported on WindowsCE */
555.1648 +   {
555.1649 +      wchar_t wc_buf[32];
555.1650 +      size_t wc_len;
555.1651 +      swprintf(wc_buf, TEXT("%12.12e"), width);
555.1652 +      wc_len = wcslen(wc_buf);
555.1653 +      WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL);
555.1654 +      total_len = wc_len + 2;
555.1655 +      swprintf(wc_buf, TEXT("%12.12e"), height);
555.1656 +      wc_len = wcslen(wc_buf);
555.1657 +      WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len,
555.1658 +         NULL, NULL);
555.1659 +      total_len += wc_len;
555.1660 +   }
555.1661 +#else
555.1662 +   png_snprintf(buf + 1, 63, "%12.12e", width);
555.1663 +   total_len = 1 + png_strlen(buf + 1) + 1;
555.1664 +   png_snprintf(buf + total_len, 64-total_len, "%12.12e", height);
555.1665 +   total_len += png_strlen(buf + total_len);
555.1666 +#endif
555.1667 +
555.1668 +   png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len);
555.1669 +   png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len);
555.1670 +}
555.1671 +#else
555.1672 +#ifdef PNG_FIXED_POINT_SUPPORTED
555.1673 +void /* PRIVATE */
555.1674 +png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
555.1675 +   png_charp height)
555.1676 +{
555.1677 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1678 +   PNG_sCAL;
555.1679 +#endif
555.1680 +   png_byte buf[64];
555.1681 +   png_size_t wlen, hlen, total_len;
555.1682 +
555.1683 +   png_debug(1, "in png_write_sCAL_s\n");
555.1684 +
555.1685 +   wlen = png_strlen(width);
555.1686 +   hlen = png_strlen(height);
555.1687 +   total_len = wlen + hlen + 2;
555.1688 +   if (total_len > 64)
555.1689 +   {
555.1690 +      png_warning(png_ptr, "Can't write sCAL (buffer too small)");
555.1691 +      return;
555.1692 +   }
555.1693 +
555.1694 +   buf[0] = (png_byte)unit;
555.1695 +   png_memcpy(buf + 1, width, wlen + 1);      /* append the '\0' here */
555.1696 +   png_memcpy(buf + wlen + 2, height, hlen);  /* do NOT append the '\0' here */
555.1697 +
555.1698 +   png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len);
555.1699 +   png_write_chunk(png_ptr, (png_bytep)png_sCAL, buf, total_len);
555.1700 +}
555.1701 +#endif
555.1702 +#endif
555.1703 +#endif
555.1704 +
555.1705 +#if defined(PNG_WRITE_pHYs_SUPPORTED)
555.1706 +/* write the pHYs chunk */
555.1707 +void /* PRIVATE */
555.1708 +png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
555.1709 +   png_uint_32 y_pixels_per_unit,
555.1710 +   int unit_type)
555.1711 +{
555.1712 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1713 +   PNG_pHYs;
555.1714 +#endif
555.1715 +   png_byte buf[9];
555.1716 +
555.1717 +   png_debug(1, "in png_write_pHYs\n");
555.1718 +   if (unit_type >= PNG_RESOLUTION_LAST)
555.1719 +      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
555.1720 +
555.1721 +   png_save_uint_32(buf, x_pixels_per_unit);
555.1722 +   png_save_uint_32(buf + 4, y_pixels_per_unit);
555.1723 +   buf[8] = (png_byte)unit_type;
555.1724 +
555.1725 +   png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9);
555.1726 +}
555.1727 +#endif
555.1728 +
555.1729 +#if defined(PNG_WRITE_tIME_SUPPORTED)
555.1730 +/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
555.1731 + * or png_convert_from_time_t(), or fill in the structure yourself.
555.1732 + */
555.1733 +void /* PRIVATE */
555.1734 +png_write_tIME(png_structp png_ptr, png_timep mod_time)
555.1735 +{
555.1736 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1737 +   PNG_tIME;
555.1738 +#endif
555.1739 +   png_byte buf[7];
555.1740 +
555.1741 +   png_debug(1, "in png_write_tIME\n");
555.1742 +   if (mod_time->month  > 12 || mod_time->month  < 1 ||
555.1743 +       mod_time->day    > 31 || mod_time->day    < 1 ||
555.1744 +       mod_time->hour   > 23 || mod_time->second > 60)
555.1745 +   {
555.1746 +      png_warning(png_ptr, "Invalid time specified for tIME chunk");
555.1747 +      return;
555.1748 +   }
555.1749 +
555.1750 +   png_save_uint_16(buf, mod_time->year);
555.1751 +   buf[2] = mod_time->month;
555.1752 +   buf[3] = mod_time->day;
555.1753 +   buf[4] = mod_time->hour;
555.1754 +   buf[5] = mod_time->minute;
555.1755 +   buf[6] = mod_time->second;
555.1756 +
555.1757 +   png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7);
555.1758 +}
555.1759 +#endif
555.1760 +
555.1761 +/* initializes the row writing capability of libpng */
555.1762 +void /* PRIVATE */
555.1763 +png_write_start_row(png_structp png_ptr)
555.1764 +{
555.1765 +#ifdef PNG_WRITE_INTERLACING_SUPPORTED
555.1766 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1767 +   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
555.1768 +
555.1769 +   /* start of interlace block */
555.1770 +   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
555.1771 +
555.1772 +   /* offset to next interlace block */
555.1773 +   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
555.1774 +
555.1775 +   /* start of interlace block in the y direction */
555.1776 +   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
555.1777 +
555.1778 +   /* offset to next interlace block in the y direction */
555.1779 +   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
555.1780 +#endif
555.1781 +#endif
555.1782 +
555.1783 +   png_size_t buf_size;
555.1784 +
555.1785 +   png_debug(1, "in png_write_start_row\n");
555.1786 +   buf_size = (png_size_t)(PNG_ROWBYTES(
555.1787 +      png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1);
555.1788 +
555.1789 +   /* set up row buffer */
555.1790 +   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr,
555.1791 +     (png_uint_32)buf_size);
555.1792 +   png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
555.1793 +
555.1794 +#ifndef PNG_NO_WRITE_FILTER
555.1795 +   /* set up filtering buffer, if using this filter */
555.1796 +   if (png_ptr->do_filter & PNG_FILTER_SUB)
555.1797 +   {
555.1798 +      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
555.1799 +         (png_uint_32)(png_ptr->rowbytes + 1));
555.1800 +      png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
555.1801 +   }
555.1802 +
555.1803 +   /* We only need to keep the previous row if we are using one of these. */
555.1804 +   if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
555.1805 +   {
555.1806 +     /* set up previous row buffer */
555.1807 +      png_ptr->prev_row = (png_bytep)png_malloc(png_ptr,
555.1808 +        (png_uint_32)buf_size);
555.1809 +      png_memset(png_ptr->prev_row, 0, buf_size);
555.1810 +
555.1811 +      if (png_ptr->do_filter & PNG_FILTER_UP)
555.1812 +      {
555.1813 +         png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
555.1814 +           (png_uint_32)(png_ptr->rowbytes + 1));
555.1815 +         png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
555.1816 +      }
555.1817 +
555.1818 +      if (png_ptr->do_filter & PNG_FILTER_AVG)
555.1819 +      {
555.1820 +         png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
555.1821 +           (png_uint_32)(png_ptr->rowbytes + 1));
555.1822 +         png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
555.1823 +      }
555.1824 +
555.1825 +      if (png_ptr->do_filter & PNG_FILTER_PAETH)
555.1826 +      {
555.1827 +         png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
555.1828 +           (png_uint_32)(png_ptr->rowbytes + 1));
555.1829 +         png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
555.1830 +      }
555.1831 +   }
555.1832 +#endif /* PNG_NO_WRITE_FILTER */
555.1833 +
555.1834 +#ifdef PNG_WRITE_INTERLACING_SUPPORTED
555.1835 +   /* if interlaced, we need to set up width and height of pass */
555.1836 +   if (png_ptr->interlaced)
555.1837 +   {
555.1838 +      if (!(png_ptr->transformations & PNG_INTERLACE))
555.1839 +      {
555.1840 +         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
555.1841 +            png_pass_ystart[0]) / png_pass_yinc[0];
555.1842 +         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
555.1843 +            png_pass_start[0]) / png_pass_inc[0];
555.1844 +      }
555.1845 +      else
555.1846 +      {
555.1847 +         png_ptr->num_rows = png_ptr->height;
555.1848 +         png_ptr->usr_width = png_ptr->width;
555.1849 +      }
555.1850 +   }
555.1851 +   else
555.1852 +#endif
555.1853 +   {
555.1854 +      png_ptr->num_rows = png_ptr->height;
555.1855 +      png_ptr->usr_width = png_ptr->width;
555.1856 +   }
555.1857 +   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
555.1858 +   png_ptr->zstream.next_out = png_ptr->zbuf;
555.1859 +}
555.1860 +
555.1861 +/* Internal use only.  Called when finished processing a row of data. */
555.1862 +void /* PRIVATE */
555.1863 +png_write_finish_row(png_structp png_ptr)
555.1864 +{
555.1865 +#ifdef PNG_WRITE_INTERLACING_SUPPORTED
555.1866 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1867 +   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
555.1868 +
555.1869 +   /* start of interlace block */
555.1870 +   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
555.1871 +
555.1872 +   /* offset to next interlace block */
555.1873 +   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
555.1874 +
555.1875 +   /* start of interlace block in the y direction */
555.1876 +   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
555.1877 +
555.1878 +   /* offset to next interlace block in the y direction */
555.1879 +   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
555.1880 +#endif
555.1881 +#endif
555.1882 +
555.1883 +   int ret;
555.1884 +
555.1885 +   png_debug(1, "in png_write_finish_row\n");
555.1886 +   /* next row */
555.1887 +   png_ptr->row_number++;
555.1888 +
555.1889 +   /* see if we are done */
555.1890 +   if (png_ptr->row_number < png_ptr->num_rows)
555.1891 +      return;
555.1892 +
555.1893 +#ifdef PNG_WRITE_INTERLACING_SUPPORTED
555.1894 +   /* if interlaced, go to next pass */
555.1895 +   if (png_ptr->interlaced)
555.1896 +   {
555.1897 +      png_ptr->row_number = 0;
555.1898 +      if (png_ptr->transformations & PNG_INTERLACE)
555.1899 +      {
555.1900 +         png_ptr->pass++;
555.1901 +      }
555.1902 +      else
555.1903 +      {
555.1904 +         /* loop until we find a non-zero width or height pass */
555.1905 +         do
555.1906 +         {
555.1907 +            png_ptr->pass++;
555.1908 +            if (png_ptr->pass >= 7)
555.1909 +               break;
555.1910 +            png_ptr->usr_width = (png_ptr->width +
555.1911 +               png_pass_inc[png_ptr->pass] - 1 -
555.1912 +               png_pass_start[png_ptr->pass]) /
555.1913 +               png_pass_inc[png_ptr->pass];
555.1914 +            png_ptr->num_rows = (png_ptr->height +
555.1915 +               png_pass_yinc[png_ptr->pass] - 1 -
555.1916 +               png_pass_ystart[png_ptr->pass]) /
555.1917 +               png_pass_yinc[png_ptr->pass];
555.1918 +            if (png_ptr->transformations & PNG_INTERLACE)
555.1919 +               break;
555.1920 +         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
555.1921 +
555.1922 +      }
555.1923 +
555.1924 +      /* reset the row above the image for the next pass */
555.1925 +      if (png_ptr->pass < 7)
555.1926 +      {
555.1927 +         if (png_ptr->prev_row != NULL)
555.1928 +            png_memset(png_ptr->prev_row, 0,
555.1929 +               (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
555.1930 +               png_ptr->usr_bit_depth, png_ptr->width)) + 1);
555.1931 +         return;
555.1932 +      }
555.1933 +   }
555.1934 +#endif
555.1935 +
555.1936 +   /* if we get here, we've just written the last row, so we need
555.1937 +      to flush the compressor */
555.1938 +   do
555.1939 +   {
555.1940 +      /* tell the compressor we are done */
555.1941 +      ret = deflate(&png_ptr->zstream, Z_FINISH);
555.1942 +      /* check for an error */
555.1943 +      if (ret == Z_OK)
555.1944 +      {
555.1945 +         /* check to see if we need more room */
555.1946 +         if (!(png_ptr->zstream.avail_out))
555.1947 +         {
555.1948 +            png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
555.1949 +            png_ptr->zstream.next_out = png_ptr->zbuf;
555.1950 +            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
555.1951 +         }
555.1952 +      }
555.1953 +      else if (ret != Z_STREAM_END)
555.1954 +      {
555.1955 +         if (png_ptr->zstream.msg != NULL)
555.1956 +            png_error(png_ptr, png_ptr->zstream.msg);
555.1957 +         else
555.1958 +            png_error(png_ptr, "zlib error");
555.1959 +      }
555.1960 +   } while (ret != Z_STREAM_END);
555.1961 +
555.1962 +   /* write any extra space */
555.1963 +   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
555.1964 +   {
555.1965 +      png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
555.1966 +         png_ptr->zstream.avail_out);
555.1967 +   }
555.1968 +
555.1969 +   deflateReset(&png_ptr->zstream);
555.1970 +   png_ptr->zstream.data_type = Z_BINARY;
555.1971 +}
555.1972 +
555.1973 +#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
555.1974 +/* Pick out the correct pixels for the interlace pass.
555.1975 + * The basic idea here is to go through the row with a source
555.1976 + * pointer and a destination pointer (sp and dp), and copy the
555.1977 + * correct pixels for the pass.  As the row gets compacted,
555.1978 + * sp will always be >= dp, so we should never overwrite anything.
555.1979 + * See the default: case for the easiest code to understand.
555.1980 + */
555.1981 +void /* PRIVATE */
555.1982 +png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
555.1983 +{
555.1984 +#ifdef PNG_USE_LOCAL_ARRAYS
555.1985 +   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
555.1986 +
555.1987 +   /* start of interlace block */
555.1988 +   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
555.1989 +
555.1990 +   /* offset to next interlace block */
555.1991 +   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
555.1992 +#endif
555.1993 +
555.1994 +   png_debug(1, "in png_do_write_interlace\n");
555.1995 +   /* we don't have to do anything on the last pass (6) */
555.1996 +#if defined(PNG_USELESS_TESTS_SUPPORTED)
555.1997 +   if (row != NULL && row_info != NULL && pass < 6)
555.1998 +#else
555.1999 +   if (pass < 6)
555.2000 +#endif
555.2001 +   {
555.2002 +      /* each pixel depth is handled separately */
555.2003 +      switch (row_info->pixel_depth)
555.2004 +      {
555.2005 +         case 1:
555.2006 +         {
555.2007 +            png_bytep sp;
555.2008 +            png_bytep dp;
555.2009 +            int shift;
555.2010 +            int d;
555.2011 +            int value;
555.2012 +            png_uint_32 i;
555.2013 +            png_uint_32 row_width = row_info->width;
555.2014 +
555.2015 +            dp = row;
555.2016 +            d = 0;
555.2017 +            shift = 7;
555.2018 +            for (i = png_pass_start[pass]; i < row_width;
555.2019 +               i += png_pass_inc[pass])
555.2020 +            {
555.2021 +               sp = row + (png_size_t)(i >> 3);
555.2022 +               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
555.2023 +               d |= (value << shift);
555.2024 +
555.2025 +               if (shift == 0)
555.2026 +               {
555.2027 +                  shift = 7;
555.2028 +                  *dp++ = (png_byte)d;
555.2029 +                  d = 0;
555.2030 +               }
555.2031 +               else
555.2032 +                  shift--;
555.2033 +
555.2034 +            }
555.2035 +            if (shift != 7)
555.2036 +               *dp = (png_byte)d;
555.2037 +            break;
555.2038 +         }
555.2039 +         case 2:
555.2040 +         {
555.2041 +            png_bytep sp;
555.2042 +            png_bytep dp;
555.2043 +            int shift;
555.2044 +            int d;
555.2045 +            int value;
555.2046 +            png_uint_32 i;
555.2047 +            png_uint_32 row_width = row_info->width;
555.2048 +
555.2049 +            dp = row;
555.2050 +            shift = 6;
555.2051 +            d = 0;
555.2052 +            for (i = png_pass_start[pass]; i < row_width;
555.2053 +               i += png_pass_inc[pass])
555.2054 +            {
555.2055 +               sp = row + (png_size_t)(i >> 2);
555.2056 +               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
555.2057 +               d |= (value << shift);
555.2058 +
555.2059 +               if (shift == 0)
555.2060 +               {
555.2061 +                  shift = 6;
555.2062 +                  *dp++ = (png_byte)d;
555.2063 +                  d = 0;
555.2064 +               }
555.2065 +               else
555.2066 +                  shift -= 2;
555.2067 +            }
555.2068 +            if (shift != 6)
555.2069 +                   *dp = (png_byte)d;
555.2070 +            break;
555.2071 +         }
555.2072 +         case 4:
555.2073 +         {
555.2074 +            png_bytep sp;
555.2075 +            png_bytep dp;
555.2076 +            int shift;
555.2077 +            int d;
555.2078 +            int value;
555.2079 +            png_uint_32 i;
555.2080 +            png_uint_32 row_width = row_info->width;
555.2081 +
555.2082 +            dp = row;
555.2083 +            shift = 4;
555.2084 +            d = 0;
555.2085 +            for (i = png_pass_start[pass]; i < row_width;
555.2086 +               i += png_pass_inc[pass])
555.2087 +            {
555.2088 +               sp = row + (png_size_t)(i >> 1);
555.2089 +               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
555.2090 +               d |= (value << shift);
555.2091 +
555.2092 +               if (shift == 0)
555.2093 +               {
555.2094 +                  shift = 4;
555.2095 +                  *dp++ = (png_byte)d;
555.2096 +                  d = 0;
555.2097 +               }
555.2098 +               else
555.2099 +                  shift -= 4;
555.2100 +            }
555.2101 +            if (shift != 4)
555.2102 +               *dp = (png_byte)d;
555.2103 +            break;
555.2104 +         }
555.2105 +         default:
555.2106 +         {
555.2107 +            png_bytep sp;
555.2108 +            png_bytep dp;
555.2109 +            png_uint_32 i;
555.2110 +            png_uint_32 row_width = row_info->width;
555.2111 +            png_size_t pixel_bytes;
555.2112 +
555.2113 +            /* start at the beginning */
555.2114 +            dp = row;
555.2115 +            /* find out how many bytes each pixel takes up */
555.2116 +            pixel_bytes = (row_info->pixel_depth >> 3);
555.2117 +            /* loop through the row, only looking at the pixels that
555.2118 +               matter */
555.2119 +            for (i = png_pass_start[pass]; i < row_width;
555.2120 +               i += png_pass_inc[pass])
555.2121 +            {
555.2122 +               /* find out where the original pixel is */
555.2123 +               sp = row + (png_size_t)i * pixel_bytes;
555.2124 +               /* move the pixel */
555.2125 +               if (dp != sp)
555.2126 +                  png_memcpy(dp, sp, pixel_bytes);
555.2127 +               /* next pixel */
555.2128 +               dp += pixel_bytes;
555.2129 +            }
555.2130 +            break;
555.2131 +         }
555.2132 +      }
555.2133 +      /* set new row width */
555.2134 +      row_info->width = (row_info->width +
555.2135 +         png_pass_inc[pass] - 1 -
555.2136 +         png_pass_start[pass]) /
555.2137 +         png_pass_inc[pass];
555.2138 +         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
555.2139 +            row_info->width);
555.2140 +   }
555.2141 +}
555.2142 +#endif
555.2143 +
555.2144 +/* This filters the row, chooses which filter to use, if it has not already
555.2145 + * been specified by the application, and then writes the row out with the
555.2146 + * chosen filter.
555.2147 + */
555.2148 +#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
555.2149 +#define PNG_HISHIFT 10
555.2150 +#define PNG_LOMASK ((png_uint_32)0xffffL)
555.2151 +#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
555.2152 +void /* PRIVATE */
555.2153 +png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
555.2154 +{
555.2155 +   png_bytep best_row;
555.2156 +#ifndef PNG_NO_WRITE_FILTER
555.2157 +   png_bytep prev_row, row_buf;
555.2158 +   png_uint_32 mins, bpp;
555.2159 +   png_byte filter_to_do = png_ptr->do_filter;
555.2160 +   png_uint_32 row_bytes = row_info->rowbytes;
555.2161 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2162 +   int num_p_filters = (int)png_ptr->num_prev_filters;
555.2163 +#endif
555.2164 +
555.2165 +   png_debug(1, "in png_write_find_filter\n");
555.2166 +   /* find out how many bytes offset each pixel is */
555.2167 +   bpp = (row_info->pixel_depth + 7) >> 3;
555.2168 +
555.2169 +   prev_row = png_ptr->prev_row;
555.2170 +#endif
555.2171 +   best_row = png_ptr->row_buf;
555.2172 +#ifndef PNG_NO_WRITE_FILTER
555.2173 +   row_buf = best_row;
555.2174 +   mins = PNG_MAXSUM;
555.2175 +
555.2176 +   /* The prediction method we use is to find which method provides the
555.2177 +    * smallest value when summing the absolute values of the distances
555.2178 +    * from zero, using anything >= 128 as negative numbers.  This is known
555.2179 +    * as the "minimum sum of absolute differences" heuristic.  Other
555.2180 +    * heuristics are the "weighted minimum sum of absolute differences"
555.2181 +    * (experimental and can in theory improve compression), and the "zlib
555.2182 +    * predictive" method (not implemented yet), which does test compressions
555.2183 +    * of lines using different filter methods, and then chooses the
555.2184 +    * (series of) filter(s) that give minimum compressed data size (VERY
555.2185 +    * computationally expensive).
555.2186 +    *
555.2187 +    * GRR 980525:  consider also
555.2188 +    *   (1) minimum sum of absolute differences from running average (i.e.,
555.2189 +    *       keep running sum of non-absolute differences & count of bytes)
555.2190 +    *       [track dispersion, too?  restart average if dispersion too large?]
555.2191 +    *  (1b) minimum sum of absolute differences from sliding average, probably
555.2192 +    *       with window size <= deflate window (usually 32K)
555.2193 +    *   (2) minimum sum of squared differences from zero or running average
555.2194 +    *       (i.e., ~ root-mean-square approach)
555.2195 +    */
555.2196 +
555.2197 +
555.2198 +   /* We don't need to test the 'no filter' case if this is the only filter
555.2199 +    * that has been chosen, as it doesn't actually do anything to the data.
555.2200 +    */
555.2201 +   if ((filter_to_do & PNG_FILTER_NONE) &&
555.2202 +       filter_to_do != PNG_FILTER_NONE)
555.2203 +   {
555.2204 +      png_bytep rp;
555.2205 +      png_uint_32 sum = 0;
555.2206 +      png_uint_32 i;
555.2207 +      int v;
555.2208 +
555.2209 +      for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
555.2210 +      {
555.2211 +         v = *rp;
555.2212 +         sum += (v < 128) ? v : 256 - v;
555.2213 +      }
555.2214 +
555.2215 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2216 +      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
555.2217 +      {
555.2218 +         png_uint_32 sumhi, sumlo;
555.2219 +         int j;
555.2220 +         sumlo = sum & PNG_LOMASK;
555.2221 +         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
555.2222 +
555.2223 +         /* Reduce the sum if we match any of the previous rows */
555.2224 +         for (j = 0; j < num_p_filters; j++)
555.2225 +         {
555.2226 +            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
555.2227 +            {
555.2228 +               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
555.2229 +                  PNG_WEIGHT_SHIFT;
555.2230 +               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
555.2231 +                  PNG_WEIGHT_SHIFT;
555.2232 +            }
555.2233 +         }
555.2234 +
555.2235 +         /* Factor in the cost of this filter (this is here for completeness,
555.2236 +          * but it makes no sense to have a "cost" for the NONE filter, as
555.2237 +          * it has the minimum possible computational cost - none).
555.2238 +          */
555.2239 +         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
555.2240 +            PNG_COST_SHIFT;
555.2241 +         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
555.2242 +            PNG_COST_SHIFT;
555.2243 +
555.2244 +         if (sumhi > PNG_HIMASK)
555.2245 +            sum = PNG_MAXSUM;
555.2246 +         else
555.2247 +            sum = (sumhi << PNG_HISHIFT) + sumlo;
555.2248 +      }
555.2249 +#endif
555.2250 +      mins = sum;
555.2251 +   }
555.2252 +
555.2253 +   /* sub filter */
555.2254 +   if (filter_to_do == PNG_FILTER_SUB)
555.2255 +   /* it's the only filter so no testing is needed */
555.2256 +   {
555.2257 +      png_bytep rp, lp, dp;
555.2258 +      png_uint_32 i;
555.2259 +      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
555.2260 +           i++, rp++, dp++)
555.2261 +      {
555.2262 +         *dp = *rp;
555.2263 +      }
555.2264 +      for (lp = row_buf + 1; i < row_bytes;
555.2265 +         i++, rp++, lp++, dp++)
555.2266 +      {
555.2267 +         *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
555.2268 +      }
555.2269 +      best_row = png_ptr->sub_row;
555.2270 +   }
555.2271 +
555.2272 +   else if (filter_to_do & PNG_FILTER_SUB)
555.2273 +   {
555.2274 +      png_bytep rp, dp, lp;
555.2275 +      png_uint_32 sum = 0, lmins = mins;
555.2276 +      png_uint_32 i;
555.2277 +      int v;
555.2278 +
555.2279 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2280 +      /* We temporarily increase the "minimum sum" by the factor we
555.2281 +       * would reduce the sum of this filter, so that we can do the
555.2282 +       * early exit comparison without scaling the sum each time.
555.2283 +       */
555.2284 +      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
555.2285 +      {
555.2286 +         int j;
555.2287 +         png_uint_32 lmhi, lmlo;
555.2288 +         lmlo = lmins & PNG_LOMASK;
555.2289 +         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
555.2290 +
555.2291 +         for (j = 0; j < num_p_filters; j++)
555.2292 +         {
555.2293 +            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
555.2294 +            {
555.2295 +               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
555.2296 +                  PNG_WEIGHT_SHIFT;
555.2297 +               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
555.2298 +                  PNG_WEIGHT_SHIFT;
555.2299 +            }
555.2300 +         }
555.2301 +
555.2302 +         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
555.2303 +            PNG_COST_SHIFT;
555.2304 +         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
555.2305 +            PNG_COST_SHIFT;
555.2306 +
555.2307 +         if (lmhi > PNG_HIMASK)
555.2308 +            lmins = PNG_MAXSUM;
555.2309 +         else
555.2310 +            lmins = (lmhi << PNG_HISHIFT) + lmlo;
555.2311 +      }
555.2312 +#endif
555.2313 +
555.2314 +      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
555.2315 +           i++, rp++, dp++)
555.2316 +      {
555.2317 +         v = *dp = *rp;
555.2318 +
555.2319 +         sum += (v < 128) ? v : 256 - v;
555.2320 +      }
555.2321 +      for (lp = row_buf + 1; i < row_bytes;
555.2322 +         i++, rp++, lp++, dp++)
555.2323 +      {
555.2324 +         v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
555.2325 +
555.2326 +         sum += (v < 128) ? v : 256 - v;
555.2327 +
555.2328 +         if (sum > lmins)  /* We are already worse, don't continue. */
555.2329 +            break;
555.2330 +      }
555.2331 +
555.2332 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2333 +      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
555.2334 +      {
555.2335 +         int j;
555.2336 +         png_uint_32 sumhi, sumlo;
555.2337 +         sumlo = sum & PNG_LOMASK;
555.2338 +         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
555.2339 +
555.2340 +         for (j = 0; j < num_p_filters; j++)
555.2341 +         {
555.2342 +            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
555.2343 +            {
555.2344 +               sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
555.2345 +                  PNG_WEIGHT_SHIFT;
555.2346 +               sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
555.2347 +                  PNG_WEIGHT_SHIFT;
555.2348 +            }
555.2349 +         }
555.2350 +
555.2351 +         sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
555.2352 +            PNG_COST_SHIFT;
555.2353 +         sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
555.2354 +            PNG_COST_SHIFT;
555.2355 +
555.2356 +         if (sumhi > PNG_HIMASK)
555.2357 +            sum = PNG_MAXSUM;
555.2358 +         else
555.2359 +            sum = (sumhi << PNG_HISHIFT) + sumlo;
555.2360 +      }
555.2361 +#endif
555.2362 +
555.2363 +      if (sum < mins)
555.2364 +      {
555.2365 +         mins = sum;
555.2366 +         best_row = png_ptr->sub_row;
555.2367 +      }
555.2368 +   }
555.2369 +
555.2370 +   /* up filter */
555.2371 +   if (filter_to_do == PNG_FILTER_UP)
555.2372 +   {
555.2373 +      png_bytep rp, dp, pp;
555.2374 +      png_uint_32 i;
555.2375 +
555.2376 +      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
555.2377 +           pp = prev_row + 1; i < row_bytes;
555.2378 +           i++, rp++, pp++, dp++)
555.2379 +      {
555.2380 +         *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
555.2381 +      }
555.2382 +      best_row = png_ptr->up_row;
555.2383 +   }
555.2384 +
555.2385 +   else if (filter_to_do & PNG_FILTER_UP)
555.2386 +   {
555.2387 +      png_bytep rp, dp, pp;
555.2388 +      png_uint_32 sum = 0, lmins = mins;
555.2389 +      png_uint_32 i;
555.2390 +      int v;
555.2391 +
555.2392 +
555.2393 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2394 +      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
555.2395 +      {
555.2396 +         int j;
555.2397 +         png_uint_32 lmhi, lmlo;
555.2398 +         lmlo = lmins & PNG_LOMASK;
555.2399 +         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
555.2400 +
555.2401 +         for (j = 0; j < num_p_filters; j++)
555.2402 +         {
555.2403 +            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
555.2404 +            {
555.2405 +               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
555.2406 +                  PNG_WEIGHT_SHIFT;
555.2407 +               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
555.2408 +                  PNG_WEIGHT_SHIFT;
555.2409 +            }
555.2410 +         }
555.2411 +
555.2412 +         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
555.2413 +            PNG_COST_SHIFT;
555.2414 +         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
555.2415 +            PNG_COST_SHIFT;
555.2416 +
555.2417 +         if (lmhi > PNG_HIMASK)
555.2418 +            lmins = PNG_MAXSUM;
555.2419 +         else
555.2420 +            lmins = (lmhi << PNG_HISHIFT) + lmlo;
555.2421 +      }
555.2422 +#endif
555.2423 +
555.2424 +      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
555.2425 +           pp = prev_row + 1; i < row_bytes; i++)
555.2426 +      {
555.2427 +         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
555.2428 +
555.2429 +         sum += (v < 128) ? v : 256 - v;
555.2430 +
555.2431 +         if (sum > lmins)  /* We are already worse, don't continue. */
555.2432 +            break;
555.2433 +      }
555.2434 +
555.2435 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2436 +      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
555.2437 +      {
555.2438 +         int j;
555.2439 +         png_uint_32 sumhi, sumlo;
555.2440 +         sumlo = sum & PNG_LOMASK;
555.2441 +         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
555.2442 +
555.2443 +         for (j = 0; j < num_p_filters; j++)
555.2444 +         {
555.2445 +            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
555.2446 +            {
555.2447 +               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
555.2448 +                  PNG_WEIGHT_SHIFT;
555.2449 +               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
555.2450 +                  PNG_WEIGHT_SHIFT;
555.2451 +            }
555.2452 +         }
555.2453 +
555.2454 +         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
555.2455 +            PNG_COST_SHIFT;
555.2456 +         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
555.2457 +            PNG_COST_SHIFT;
555.2458 +
555.2459 +         if (sumhi > PNG_HIMASK)
555.2460 +            sum = PNG_MAXSUM;
555.2461 +         else
555.2462 +            sum = (sumhi << PNG_HISHIFT) + sumlo;
555.2463 +      }
555.2464 +#endif
555.2465 +
555.2466 +      if (sum < mins)
555.2467 +      {
555.2468 +         mins = sum;
555.2469 +         best_row = png_ptr->up_row;
555.2470 +      }
555.2471 +   }
555.2472 +
555.2473 +   /* avg filter */
555.2474 +   if (filter_to_do == PNG_FILTER_AVG)
555.2475 +   {
555.2476 +      png_bytep rp, dp, pp, lp;
555.2477 +      png_uint_32 i;
555.2478 +      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
555.2479 +           pp = prev_row + 1; i < bpp; i++)
555.2480 +      {
555.2481 +         *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
555.2482 +      }
555.2483 +      for (lp = row_buf + 1; i < row_bytes; i++)
555.2484 +      {
555.2485 +         *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
555.2486 +                 & 0xff);
555.2487 +      }
555.2488 +      best_row = png_ptr->avg_row;
555.2489 +   }
555.2490 +
555.2491 +   else if (filter_to_do & PNG_FILTER_AVG)
555.2492 +   {
555.2493 +      png_bytep rp, dp, pp, lp;
555.2494 +      png_uint_32 sum = 0, lmins = mins;
555.2495 +      png_uint_32 i;
555.2496 +      int v;
555.2497 +
555.2498 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2499 +      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
555.2500 +      {
555.2501 +         int j;
555.2502 +         png_uint_32 lmhi, lmlo;
555.2503 +         lmlo = lmins & PNG_LOMASK;
555.2504 +         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
555.2505 +
555.2506 +         for (j = 0; j < num_p_filters; j++)
555.2507 +         {
555.2508 +            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
555.2509 +            {
555.2510 +               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
555.2511 +                  PNG_WEIGHT_SHIFT;
555.2512 +               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
555.2513 +                  PNG_WEIGHT_SHIFT;
555.2514 +            }
555.2515 +         }
555.2516 +
555.2517 +         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
555.2518 +            PNG_COST_SHIFT;
555.2519 +         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
555.2520 +            PNG_COST_SHIFT;
555.2521 +
555.2522 +         if (lmhi > PNG_HIMASK)
555.2523 +            lmins = PNG_MAXSUM;
555.2524 +         else
555.2525 +            lmins = (lmhi << PNG_HISHIFT) + lmlo;
555.2526 +      }
555.2527 +#endif
555.2528 +
555.2529 +      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
555.2530 +           pp = prev_row + 1; i < bpp; i++)
555.2531 +      {
555.2532 +         v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
555.2533 +
555.2534 +         sum += (v < 128) ? v : 256 - v;
555.2535 +      }
555.2536 +      for (lp = row_buf + 1; i < row_bytes; i++)
555.2537 +      {
555.2538 +         v = *dp++ =
555.2539 +          (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
555.2540 +
555.2541 +         sum += (v < 128) ? v : 256 - v;
555.2542 +
555.2543 +         if (sum > lmins)  /* We are already worse, don't continue. */
555.2544 +            break;
555.2545 +      }
555.2546 +
555.2547 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2548 +      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
555.2549 +      {
555.2550 +         int j;
555.2551 +         png_uint_32 sumhi, sumlo;
555.2552 +         sumlo = sum & PNG_LOMASK;
555.2553 +         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
555.2554 +
555.2555 +         for (j = 0; j < num_p_filters; j++)
555.2556 +         {
555.2557 +            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
555.2558 +            {
555.2559 +               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
555.2560 +                  PNG_WEIGHT_SHIFT;
555.2561 +               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
555.2562 +                  PNG_WEIGHT_SHIFT;
555.2563 +            }
555.2564 +         }
555.2565 +
555.2566 +         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
555.2567 +            PNG_COST_SHIFT;
555.2568 +         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
555.2569 +            PNG_COST_SHIFT;
555.2570 +
555.2571 +         if (sumhi > PNG_HIMASK)
555.2572 +            sum = PNG_MAXSUM;
555.2573 +         else
555.2574 +            sum = (sumhi << PNG_HISHIFT) + sumlo;
555.2575 +      }
555.2576 +#endif
555.2577 +
555.2578 +      if (sum < mins)
555.2579 +      {
555.2580 +         mins = sum;
555.2581 +         best_row = png_ptr->avg_row;
555.2582 +      }
555.2583 +   }
555.2584 +
555.2585 +   /* Paeth filter */
555.2586 +   if (filter_to_do == PNG_FILTER_PAETH)
555.2587 +   {
555.2588 +      png_bytep rp, dp, pp, cp, lp;
555.2589 +      png_uint_32 i;
555.2590 +      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
555.2591 +           pp = prev_row + 1; i < bpp; i++)
555.2592 +      {
555.2593 +         *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
555.2594 +      }
555.2595 +
555.2596 +      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
555.2597 +      {
555.2598 +         int a, b, c, pa, pb, pc, p;
555.2599 +
555.2600 +         b = *pp++;
555.2601 +         c = *cp++;
555.2602 +         a = *lp++;
555.2603 +
555.2604 +         p = b - c;
555.2605 +         pc = a - c;
555.2606 +
555.2607 +#ifdef PNG_USE_ABS
555.2608 +         pa = abs(p);
555.2609 +         pb = abs(pc);
555.2610 +         pc = abs(p + pc);
555.2611 +#else
555.2612 +         pa = p < 0 ? -p : p;
555.2613 +         pb = pc < 0 ? -pc : pc;
555.2614 +         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
555.2615 +#endif
555.2616 +
555.2617 +         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
555.2618 +
555.2619 +         *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
555.2620 +      }
555.2621 +      best_row = png_ptr->paeth_row;
555.2622 +   }
555.2623 +
555.2624 +   else if (filter_to_do & PNG_FILTER_PAETH)
555.2625 +   {
555.2626 +      png_bytep rp, dp, pp, cp, lp;
555.2627 +      png_uint_32 sum = 0, lmins = mins;
555.2628 +      png_uint_32 i;
555.2629 +      int v;
555.2630 +
555.2631 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2632 +      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
555.2633 +      {
555.2634 +         int j;
555.2635 +         png_uint_32 lmhi, lmlo;
555.2636 +         lmlo = lmins & PNG_LOMASK;
555.2637 +         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
555.2638 +
555.2639 +         for (j = 0; j < num_p_filters; j++)
555.2640 +         {
555.2641 +            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
555.2642 +            {
555.2643 +               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
555.2644 +                  PNG_WEIGHT_SHIFT;
555.2645 +               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
555.2646 +                  PNG_WEIGHT_SHIFT;
555.2647 +            }
555.2648 +         }
555.2649 +
555.2650 +         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
555.2651 +            PNG_COST_SHIFT;
555.2652 +         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
555.2653 +            PNG_COST_SHIFT;
555.2654 +
555.2655 +         if (lmhi > PNG_HIMASK)
555.2656 +            lmins = PNG_MAXSUM;
555.2657 +         else
555.2658 +            lmins = (lmhi << PNG_HISHIFT) + lmlo;
555.2659 +      }
555.2660 +#endif
555.2661 +
555.2662 +      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
555.2663 +           pp = prev_row + 1; i < bpp; i++)
555.2664 +      {
555.2665 +         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
555.2666 +
555.2667 +         sum += (v < 128) ? v : 256 - v;
555.2668 +      }
555.2669 +
555.2670 +      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
555.2671 +      {
555.2672 +         int a, b, c, pa, pb, pc, p;
555.2673 +
555.2674 +         b = *pp++;
555.2675 +         c = *cp++;
555.2676 +         a = *lp++;
555.2677 +
555.2678 +#ifndef PNG_SLOW_PAETH
555.2679 +         p = b - c;
555.2680 +         pc = a - c;
555.2681 +#ifdef PNG_USE_ABS
555.2682 +         pa = abs(p);
555.2683 +         pb = abs(pc);
555.2684 +         pc = abs(p + pc);
555.2685 +#else
555.2686 +         pa = p < 0 ? -p : p;
555.2687 +         pb = pc < 0 ? -pc : pc;
555.2688 +         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
555.2689 +#endif
555.2690 +         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
555.2691 +#else /* PNG_SLOW_PAETH */
555.2692 +         p = a + b - c;
555.2693 +         pa = abs(p - a);
555.2694 +         pb = abs(p - b);
555.2695 +         pc = abs(p - c);
555.2696 +         if (pa <= pb && pa <= pc)
555.2697 +            p = a;
555.2698 +         else if (pb <= pc)
555.2699 +            p = b;
555.2700 +         else
555.2701 +            p = c;
555.2702 +#endif /* PNG_SLOW_PAETH */
555.2703 +
555.2704 +         v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
555.2705 +
555.2706 +         sum += (v < 128) ? v : 256 - v;
555.2707 +
555.2708 +         if (sum > lmins)  /* We are already worse, don't continue. */
555.2709 +            break;
555.2710 +      }
555.2711 +
555.2712 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2713 +      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
555.2714 +      {
555.2715 +         int j;
555.2716 +         png_uint_32 sumhi, sumlo;
555.2717 +         sumlo = sum & PNG_LOMASK;
555.2718 +         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
555.2719 +
555.2720 +         for (j = 0; j < num_p_filters; j++)
555.2721 +         {
555.2722 +            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
555.2723 +            {
555.2724 +               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
555.2725 +                  PNG_WEIGHT_SHIFT;
555.2726 +               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
555.2727 +                  PNG_WEIGHT_SHIFT;
555.2728 +            }
555.2729 +         }
555.2730 +
555.2731 +         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
555.2732 +            PNG_COST_SHIFT;
555.2733 +         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
555.2734 +            PNG_COST_SHIFT;
555.2735 +
555.2736 +         if (sumhi > PNG_HIMASK)
555.2737 +            sum = PNG_MAXSUM;
555.2738 +         else
555.2739 +            sum = (sumhi << PNG_HISHIFT) + sumlo;
555.2740 +      }
555.2741 +#endif
555.2742 +
555.2743 +      if (sum < mins)
555.2744 +      {
555.2745 +         best_row = png_ptr->paeth_row;
555.2746 +      }
555.2747 +   }
555.2748 +#endif /* PNG_NO_WRITE_FILTER */
555.2749 +   /* Do the actual writing of the filtered row data from the chosen filter. */
555.2750 +
555.2751 +   png_write_filtered_row(png_ptr, best_row);
555.2752 +
555.2753 +#ifndef PNG_NO_WRITE_FILTER
555.2754 +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
555.2755 +   /* Save the type of filter we picked this time for future calculations */
555.2756 +   if (png_ptr->num_prev_filters > 0)
555.2757 +   {
555.2758 +      int j;
555.2759 +      for (j = 1; j < num_p_filters; j++)
555.2760 +      {
555.2761 +         png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
555.2762 +      }
555.2763 +      png_ptr->prev_filters[j] = best_row[0];
555.2764 +   }
555.2765 +#endif
555.2766 +#endif /* PNG_NO_WRITE_FILTER */
555.2767 +}
555.2768 +
555.2769 +
555.2770 +/* Do the actual writing of a previously filtered row. */
555.2771 +void /* PRIVATE */
555.2772 +png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
555.2773 +{
555.2774 +   png_debug(1, "in png_write_filtered_row\n");
555.2775 +   png_debug1(2, "filter = %d\n", filtered_row[0]);
555.2776 +   /* set up the zlib input buffer */
555.2777 +
555.2778 +   png_ptr->zstream.next_in = filtered_row;
555.2779 +   png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
555.2780 +   /* repeat until we have compressed all the data */
555.2781 +   do
555.2782 +   {
555.2783 +      int ret; /* return of zlib */
555.2784 +
555.2785 +      /* compress the data */
555.2786 +      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
555.2787 +      /* check for compression errors */
555.2788 +      if (ret != Z_OK)
555.2789 +      {
555.2790 +         if (png_ptr->zstream.msg != NULL)
555.2791 +            png_error(png_ptr, png_ptr->zstream.msg);
555.2792 +         else
555.2793 +            png_error(png_ptr, "zlib error");
555.2794 +      }
555.2795 +
555.2796 +      /* see if it is time to write another IDAT */
555.2797 +      if (!(png_ptr->zstream.avail_out))
555.2798 +      {
555.2799 +         /* write the IDAT and reset the zlib output buffer */
555.2800 +         png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
555.2801 +         png_ptr->zstream.next_out = png_ptr->zbuf;
555.2802 +         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
555.2803 +      }
555.2804 +   /* repeat until all data has been compressed */
555.2805 +   } while (png_ptr->zstream.avail_in);
555.2806 +
555.2807 +   /* swap the current and previous rows */
555.2808 +   if (png_ptr->prev_row != NULL)
555.2809 +   {
555.2810 +      png_bytep tptr;
555.2811 +
555.2812 +      tptr = png_ptr->prev_row;
555.2813 +      png_ptr->prev_row = png_ptr->row_buf;
555.2814 +      png_ptr->row_buf = tptr;
555.2815 +   }
555.2816 +
555.2817 +   /* finish row - updates counters and flushes zlib if last row */
555.2818 +   png_write_finish_row(png_ptr);
555.2819 +
555.2820 +#if defined(PNG_WRITE_FLUSH_SUPPORTED)
555.2821 +   png_ptr->flush_rows++;
555.2822 +
555.2823 +   if (png_ptr->flush_dist > 0 &&
555.2824 +       png_ptr->flush_rows >= png_ptr->flush_dist)
555.2825 +   {
555.2826 +      png_write_flush(png_ptr);
555.2827 +   }
555.2828 +#endif
555.2829 +}
555.2830 +#endif /* PNG_WRITE_SUPPORTED */
   556.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   556.2 +++ b/libs/ogg/AUTHORS	Sat Feb 01 19:58:19 2014 +0200
   556.3 @@ -0,0 +1,7 @@
   556.4 +Monty <monty@xiph.org>
   556.5 +Greg Maxwell <greg@xiph.org>
   556.6 +Ralph Giles <giles@xiph.org>
   556.7 +Cristian Adam <cristian.adam@gmail.com>
   556.8 +Tim Terriberry <tterribe@xiph.org>
   556.9 +
  556.10 +and the rest of the Xiph.Org Foundation.
   557.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   557.2 +++ b/libs/ogg/COPYING	Sat Feb 01 19:58:19 2014 +0200
   557.3 @@ -0,0 +1,28 @@
   557.4 +Copyright (c) 2002, Xiph.org Foundation
   557.5 +
   557.6 +Redistribution and use in source and binary forms, with or without
   557.7 +modification, are permitted provided that the following conditions
   557.8 +are met:
   557.9 +
  557.10 +- Redistributions of source code must retain the above copyright
  557.11 +notice, this list of conditions and the following disclaimer.
  557.12 +
  557.13 +- Redistributions in binary form must reproduce the above copyright
  557.14 +notice, this list of conditions and the following disclaimer in the
  557.15 +documentation and/or other materials provided with the distribution.
  557.16 +
  557.17 +- Neither the name of the Xiph.org Foundation nor the names of its
  557.18 +contributors may be used to endorse or promote products derived from
  557.19 +this software without specific prior written permission.
  557.20 +
  557.21 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  557.22 +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  557.23 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  557.24 +A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
  557.25 +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  557.26 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  557.27 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  557.28 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  557.29 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  557.30 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  557.31 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   558.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   558.2 +++ b/libs/ogg/bitwise.c	Sat Feb 01 19:58:19 2014 +0200
   558.3 @@ -0,0 +1,857 @@
   558.4 +/********************************************************************
   558.5 + *                                                                  *
   558.6 + * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE.              *
   558.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   558.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   558.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  558.10 + *                                                                  *
  558.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
  558.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  558.13 + *                                                                  *
  558.14 + ********************************************************************
  558.15 +
  558.16 +  function: packing variable sized words into an octet stream
  558.17 +  last mod: $Id: bitwise.c 18051 2011-08-04 17:56:39Z giles $
  558.18 +
  558.19 + ********************************************************************/
  558.20 +
  558.21 +/* We're 'LSb' endian; if we write a word but read individual bits,
  558.22 +   then we'll read the lsb first */
  558.23 +
  558.24 +#include <string.h>
  558.25 +#include <stdlib.h>
  558.26 +#include <limits.h>
  558.27 +#include <ogg/ogg.h>
  558.28 +
  558.29 +#define BUFFER_INCREMENT 256
  558.30 +
  558.31 +static const unsigned long mask[]=
  558.32 +{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
  558.33 + 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
  558.34 + 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
  558.35 + 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
  558.36 + 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
  558.37 + 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
  558.38 + 0x3fffffff,0x7fffffff,0xffffffff };
  558.39 +
  558.40 +static const unsigned int mask8B[]=
  558.41 +{0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
  558.42 +
  558.43 +void oggpack_writeinit(oggpack_buffer *b){
  558.44 +  memset(b,0,sizeof(*b));
  558.45 +  b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT);
  558.46 +  b->buffer[0]='\0';
  558.47 +  b->storage=BUFFER_INCREMENT;
  558.48 +}
  558.49 +
  558.50 +void oggpackB_writeinit(oggpack_buffer *b){
  558.51 +  oggpack_writeinit(b);
  558.52 +}
  558.53 +
  558.54 +int oggpack_writecheck(oggpack_buffer *b){
  558.55 +  if(!b->ptr || !b->storage)return -1;
  558.56 +  return 0;
  558.57 +}
  558.58 +
  558.59 +int oggpackB_writecheck(oggpack_buffer *b){
  558.60 +  return oggpack_writecheck(b);
  558.61 +}
  558.62 +
  558.63 +void oggpack_writetrunc(oggpack_buffer *b,long bits){
  558.64 +  long bytes=bits>>3;
  558.65 +  if(b->ptr){
  558.66 +    bits-=bytes*8;
  558.67 +    b->ptr=b->buffer+bytes;
  558.68 +    b->endbit=bits;
  558.69 +    b->endbyte=bytes;
  558.70 +    *b->ptr&=mask[bits];
  558.71 +  }
  558.72 +}
  558.73 +
  558.74 +void oggpackB_writetrunc(oggpack_buffer *b,long bits){
  558.75 +  long bytes=bits>>3;
  558.76 +  if(b->ptr){
  558.77 +    bits-=bytes*8;
  558.78 +    b->ptr=b->buffer+bytes;
  558.79 +    b->endbit=bits;
  558.80 +    b->endbyte=bytes;
  558.81 +    *b->ptr&=mask8B[bits];
  558.82 +  }
  558.83 +}
  558.84 +
  558.85 +/* Takes only up to 32 bits. */
  558.86 +void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
  558.87 +  if(bits<0 || bits>32) goto err;
  558.88 +  if(b->endbyte>=b->storage-4){
  558.89 +    void *ret;
  558.90 +    if(!b->ptr)return;
  558.91 +    if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
  558.92 +    ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
  558.93 +    if(!ret) goto err;
  558.94 +    b->buffer=ret;
  558.95 +    b->storage+=BUFFER_INCREMENT;
  558.96 +    b->ptr=b->buffer+b->endbyte;
  558.97 +  }
  558.98 +
  558.99 +  value&=mask[bits];
 558.100 +  bits+=b->endbit;
 558.101 +
 558.102 +  b->ptr[0]|=value<<b->endbit;
 558.103 +
 558.104 +  if(bits>=8){
 558.105 +    b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
 558.106 +    if(bits>=16){
 558.107 +      b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
 558.108 +      if(bits>=24){
 558.109 +        b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
 558.110 +        if(bits>=32){
 558.111 +          if(b->endbit)
 558.112 +            b->ptr[4]=(unsigned char)(value>>(32-b->endbit));
 558.113 +          else
 558.114 +            b->ptr[4]=0;
 558.115 +        }
 558.116 +      }
 558.117 +    }
 558.118 +  }
 558.119 +
 558.120 +  b->endbyte+=bits/8;
 558.121 +  b->ptr+=bits/8;
 558.122 +  b->endbit=bits&7;
 558.123 +  return;
 558.124 + err:
 558.125 +  oggpack_writeclear(b);
 558.126 +}
 558.127 +
 558.128 +/* Takes only up to 32 bits. */
 558.129 +void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
 558.130 +  if(bits<0 || bits>32) goto err;
 558.131 +  if(b->endbyte>=b->storage-4){
 558.132 +    void *ret;
 558.133 +    if(!b->ptr)return;
 558.134 +    if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
 558.135 +    ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
 558.136 +    if(!ret) goto err;
 558.137 +    b->buffer=ret;
 558.138 +    b->storage+=BUFFER_INCREMENT;
 558.139 +    b->ptr=b->buffer+b->endbyte;
 558.140 +  }
 558.141 +
 558.142 +  value=(value&mask[bits])<<(32-bits);
 558.143 +  bits+=b->endbit;
 558.144 +
 558.145 +  b->ptr[0]|=value>>(24+b->endbit);
 558.146 +
 558.147 +  if(bits>=8){
 558.148 +    b->ptr[1]=(unsigned char)(value>>(16+b->endbit));
 558.149 +    if(bits>=16){
 558.150 +      b->ptr[2]=(unsigned char)(value>>(8+b->endbit));
 558.151 +      if(bits>=24){
 558.152 +        b->ptr[3]=(unsigned char)(value>>(b->endbit));
 558.153 +        if(bits>=32){
 558.154 +          if(b->endbit)
 558.155 +            b->ptr[4]=(unsigned char)(value<<(8-b->endbit));
 558.156 +          else
 558.157 +            b->ptr[4]=0;
 558.158 +        }
 558.159 +      }
 558.160 +    }
 558.161 +  }
 558.162 +
 558.163 +  b->endbyte+=bits/8;
 558.164 +  b->ptr+=bits/8;
 558.165 +  b->endbit=bits&7;
 558.166 +  return;
 558.167 + err:
 558.168 +  oggpack_writeclear(b);
 558.169 +}
 558.170 +
 558.171 +void oggpack_writealign(oggpack_buffer *b){
 558.172 +  int bits=8-b->endbit;
 558.173 +  if(bits<8)
 558.174 +    oggpack_write(b,0,bits);
 558.175 +}
 558.176 +
 558.177 +void oggpackB_writealign(oggpack_buffer *b){
 558.178 +  int bits=8-b->endbit;
 558.179 +  if(bits<8)
 558.180 +    oggpackB_write(b,0,bits);
 558.181 +}
 558.182 +
 558.183 +static void oggpack_writecopy_helper(oggpack_buffer *b,
 558.184 +                                     void *source,
 558.185 +                                     long bits,
 558.186 +                                     void (*w)(oggpack_buffer *,
 558.187 +                                               unsigned long,
 558.188 +                                               int),
 558.189 +                                     int msb){
 558.190 +  unsigned char *ptr=(unsigned char *)source;
 558.191 +
 558.192 +  long bytes=bits/8;
 558.193 +  bits-=bytes*8;
 558.194 +
 558.195 +  if(b->endbit){
 558.196 +    int i;
 558.197 +    /* unaligned copy.  Do it the hard way. */
 558.198 +    for(i=0;i<bytes;i++)
 558.199 +      w(b,(unsigned long)(ptr[i]),8);
 558.200 +  }else{
 558.201 +    /* aligned block copy */
 558.202 +    if(b->endbyte+bytes+1>=b->storage){
 558.203 +      void *ret;
 558.204 +      if(!b->ptr) goto err;
 558.205 +      if(b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err;
 558.206 +      b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
 558.207 +      ret=_ogg_realloc(b->buffer,b->storage);
 558.208 +      if(!ret) goto err;
 558.209 +      b->buffer=ret;
 558.210 +      b->ptr=b->buffer+b->endbyte;
 558.211 +    }
 558.212 +
 558.213 +    memmove(b->ptr,source,bytes);
 558.214 +    b->ptr+=bytes;
 558.215 +    b->endbyte+=bytes;
 558.216 +    *b->ptr=0;
 558.217 +
 558.218 +  }
 558.219 +  if(bits){
 558.220 +    if(msb)
 558.221 +      w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
 558.222 +    else
 558.223 +      w(b,(unsigned long)(ptr[bytes]),bits);
 558.224 +  }
 558.225 +  return;
 558.226 + err:
 558.227 +  oggpack_writeclear(b);
 558.228 +}
 558.229 +
 558.230 +void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
 558.231 +  oggpack_writecopy_helper(b,source,bits,oggpack_write,0);
 558.232 +}
 558.233 +
 558.234 +void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){
 558.235 +  oggpack_writecopy_helper(b,source,bits,oggpackB_write,1);
 558.236 +}
 558.237 +
 558.238 +void oggpack_reset(oggpack_buffer *b){
 558.239 +  if(!b->ptr)return;
 558.240 +  b->ptr=b->buffer;
 558.241 +  b->buffer[0]=0;
 558.242 +  b->endbit=b->endbyte=0;
 558.243 +}
 558.244 +
 558.245 +void oggpackB_reset(oggpack_buffer *b){
 558.246 +  oggpack_reset(b);
 558.247 +}
 558.248 +
 558.249 +void oggpack_writeclear(oggpack_buffer *b){
 558.250 +  if(b->buffer)_ogg_free(b->buffer);
 558.251 +  memset(b,0,sizeof(*b));
 558.252 +}
 558.253 +
 558.254 +void oggpackB_writeclear(oggpack_buffer *b){
 558.255 +  oggpack_writeclear(b);
 558.256 +}
 558.257 +
 558.258 +void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
 558.259 +  memset(b,0,sizeof(*b));
 558.260 +  b->buffer=b->ptr=buf;
 558.261 +  b->storage=bytes;
 558.262 +}
 558.263 +
 558.264 +void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
 558.265 +  oggpack_readinit(b,buf,bytes);
 558.266 +}
 558.267 +
 558.268 +/* Read in bits without advancing the bitptr; bits <= 32 */
 558.269 +long oggpack_look(oggpack_buffer *b,int bits){
 558.270 +  unsigned long ret;
 558.271 +  unsigned long m;
 558.272 +
 558.273 +  if(bits<0 || bits>32) return -1;
 558.274 +  m=mask[bits];
 558.275 +  bits+=b->endbit;
 558.276 +
 558.277 +  if(b->endbyte >= b->storage-4){
 558.278 +    /* not the main path */
 558.279 +    if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
 558.280 +    /* special case to avoid reading b->ptr[0], which might be past the end of
 558.281 +        the buffer; also skips some useless accounting */
 558.282 +    else if(!bits)return(0L);
 558.283 +  }
 558.284 +
 558.285 +  ret=b->ptr[0]>>b->endbit;
 558.286 +  if(bits>8){
 558.287 +    ret|=b->ptr[1]<<(8-b->endbit);
 558.288 +    if(bits>16){
 558.289 +      ret|=b->ptr[2]<<(16-b->endbit);
 558.290 +      if(bits>24){
 558.291 +        ret|=b->ptr[3]<<(24-b->endbit);
 558.292 +        if(bits>32 && b->endbit)
 558.293 +          ret|=b->ptr[4]<<(32-b->endbit);
 558.294 +      }
 558.295 +    }
 558.296 +  }
 558.297 +  return(m&ret);
 558.298 +}
 558.299 +
 558.300 +/* Read in bits without advancing the bitptr; bits <= 32 */
 558.301 +long oggpackB_look(oggpack_buffer *b,int bits){
 558.302 +  unsigned long ret;
 558.303 +  int m=32-bits;
 558.304 +
 558.305 +  if(m<0 || m>32) return -1;
 558.306 +  bits+=b->endbit;
 558.307 +
 558.308 +  if(b->endbyte >= b->storage-4){
 558.309 +    /* not the main path */
 558.310 +    if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
 558.311 +    /* special case to avoid reading b->ptr[0], which might be past the end of
 558.312 +        the buffer; also skips some useless accounting */
 558.313 +    else if(!bits)return(0L);
 558.314 +  }
 558.315 +
 558.316 +  ret=b->ptr[0]<<(24+b->endbit);
 558.317 +  if(bits>8){
 558.318 +    ret|=b->ptr[1]<<(16+b->endbit);
 558.319 +    if(bits>16){
 558.320 +      ret|=b->ptr[2]<<(8+b->endbit);
 558.321 +      if(bits>24){
 558.322 +        ret|=b->ptr[3]<<(b->endbit);
 558.323 +        if(bits>32 && b->endbit)
 558.324 +          ret|=b->ptr[4]>>(8-b->endbit);
 558.325 +      }
 558.326 +    }
 558.327 +  }
 558.328 +  return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1);
 558.329 +}
 558.330 +
 558.331 +long oggpack_look1(oggpack_buffer *b){
 558.332 +  if(b->endbyte>=b->storage)return(-1);
 558.333 +  return((b->ptr[0]>>b->endbit)&1);
 558.334 +}
 558.335 +
 558.336 +long oggpackB_look1(oggpack_buffer *b){
 558.337 +  if(b->endbyte>=b->storage)return(-1);
 558.338 +  return((b->ptr[0]>>(7-b->endbit))&1);
 558.339 +}
 558.340 +
 558.341 +void oggpack_adv(oggpack_buffer *b,int bits){
 558.342 +  bits+=b->endbit;
 558.343 +
 558.344 +  if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
 558.345 +
 558.346 +  b->ptr+=bits/8;
 558.347 +  b->endbyte+=bits/8;
 558.348 +  b->endbit=bits&7;
 558.349 +  return;
 558.350 +
 558.351 + overflow:
 558.352 +  b->ptr=NULL;
 558.353 +  b->endbyte=b->storage;
 558.354 +  b->endbit=1;
 558.355 +}
 558.356 +
 558.357 +void oggpackB_adv(oggpack_buffer *b,int bits){
 558.358 +  oggpack_adv(b,bits);
 558.359 +}
 558.360 +
 558.361 +void oggpack_adv1(oggpack_buffer *b){
 558.362 +  if(++(b->endbit)>7){
 558.363 +    b->endbit=0;
 558.364 +    b->ptr++;
 558.365 +    b->endbyte++;
 558.366 +  }
 558.367 +}
 558.368 +
 558.369 +void oggpackB_adv1(oggpack_buffer *b){
 558.370 +  oggpack_adv1(b);
 558.371 +}
 558.372 +
 558.373 +/* bits <= 32 */
 558.374 +long oggpack_read(oggpack_buffer *b,int bits){
 558.375 +  long ret;
 558.376 +  unsigned long m;
 558.377 +
 558.378 +  if(bits<0 || bits>32) goto err;
 558.379 +  m=mask[bits];
 558.380 +  bits+=b->endbit;
 558.381 +
 558.382 +  if(b->endbyte >= b->storage-4){
 558.383 +    /* not the main path */
 558.384 +    if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
 558.385 +    /* special case to avoid reading b->ptr[0], which might be past the end of
 558.386 +        the buffer; also skips some useless accounting */
 558.387 +    else if(!bits)return(0L);
 558.388 +  }
 558.389 +
 558.390 +  ret=b->ptr[0]>>b->endbit;
 558.391 +  if(bits>8){
 558.392 +    ret|=b->ptr[1]<<(8-b->endbit);
 558.393 +    if(bits>16){
 558.394 +      ret|=b->ptr[2]<<(16-b->endbit);
 558.395 +      if(bits>24){
 558.396 +        ret|=b->ptr[3]<<(24-b->endbit);
 558.397 +        if(bits>32 && b->endbit){
 558.398 +          ret|=b->ptr[4]<<(32-b->endbit);
 558.399 +        }
 558.400 +      }
 558.401 +    }
 558.402 +  }
 558.403 +  ret&=m;
 558.404 +  b->ptr+=bits/8;
 558.405 +  b->endbyte+=bits/8;
 558.406 +  b->endbit=bits&7;
 558.407 +  return ret;
 558.408 +
 558.409 + overflow:
 558.410 + err:
 558.411 +  b->ptr=NULL;
 558.412 +  b->endbyte=b->storage;
 558.413 +  b->endbit=1;
 558.414 +  return -1L;
 558.415 +}
 558.416 +
 558.417 +/* bits <= 32 */
 558.418 +long oggpackB_read(oggpack_buffer *b,int bits){
 558.419 +  long ret;
 558.420 +  long m=32-bits;
 558.421 +
 558.422 +  if(m<0 || m>32) goto err;
 558.423 +  bits+=b->endbit;
 558.424 +
 558.425 +  if(b->endbyte+4>=b->storage){
 558.426 +    /* not the main path */
 558.427 +    if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
 558.428 +    /* special case to avoid reading b->ptr[0], which might be past the end of
 558.429 +        the buffer; also skips some useless accounting */
 558.430 +    else if(!bits)return(0L);
 558.431 +  }
 558.432 +
 558.433 +  ret=b->ptr[0]<<(24+b->endbit);
 558.434 +  if(bits>8){
 558.435 +    ret|=b->ptr[1]<<(16+b->endbit);
 558.436 +    if(bits>16){
 558.437 +      ret|=b->ptr[2]<<(8+b->endbit);
 558.438 +      if(bits>24){
 558.439 +        ret|=b->ptr[3]<<(b->endbit);
 558.440 +        if(bits>32 && b->endbit)
 558.441 +          ret|=b->ptr[4]>>(8-b->endbit);
 558.442 +      }
 558.443 +    }
 558.444 +  }
 558.445 +  ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1);
 558.446 +
 558.447 +  b->ptr+=bits/8;
 558.448 +  b->endbyte+=bits/8;
 558.449 +  b->endbit=bits&7;
 558.450 +  return ret;
 558.451 +
 558.452 + overflow:
 558.453 + err:
 558.454 +  b->ptr=NULL;
 558.455 +  b->endbyte=b->storage;
 558.456 +  b->endbit=1;
 558.457 +  return -1L;
 558.458 +}
 558.459 +
 558.460 +long oggpack_read1(oggpack_buffer *b){
 558.461 +  long ret;
 558.462 +
 558.463 +  if(b->endbyte >= b->storage) goto overflow;
 558.464 +  ret=(b->ptr[0]>>b->endbit)&1;
 558.465 +
 558.466 +  b->endbit++;
 558.467 +  if(b->endbit>7){
 558.468 +    b->endbit=0;
 558.469 +    b->ptr++;
 558.470 +    b->endbyte++;
 558.471 +  }
 558.472 +  return ret;
 558.473 +
 558.474 + overflow:
 558.475 +  b->ptr=NULL;
 558.476 +  b->endbyte=b->storage;
 558.477 +  b->endbit=1;
 558.478 +  return -1L;
 558.479 +}
 558.480 +
 558.481 +long oggpackB_read1(oggpack_buffer *b){
 558.482 +  long ret;
 558.483 +
 558.484 +  if(b->endbyte >= b->storage) goto overflow;
 558.485 +  ret=(b->ptr[0]>>(7-b->endbit))&1;
 558.486 +
 558.487 +  b->endbit++;
 558.488 +  if(b->endbit>7){
 558.489 +    b->endbit=0;
 558.490 +    b->ptr++;
 558.491 +    b->endbyte++;
 558.492 +  }
 558.493 +  return ret;
 558.494 +
 558.495 + overflow:
 558.496 +  b->ptr=NULL;
 558.497 +  b->endbyte=b->storage;
 558.498 +  b->endbit=1;
 558.499 +  return -1L;
 558.500 +}
 558.501 +
 558.502 +long oggpack_bytes(oggpack_buffer *b){
 558.503 +  return(b->endbyte+(b->endbit+7)/8);
 558.504 +}
 558.505 +
 558.506 +long oggpack_bits(oggpack_buffer *b){
 558.507 +  return(b->endbyte*8+b->endbit);
 558.508 +}
 558.509 +
 558.510 +long oggpackB_bytes(oggpack_buffer *b){
 558.511 +  return oggpack_bytes(b);
 558.512 +}
 558.513 +
 558.514 +long oggpackB_bits(oggpack_buffer *b){
 558.515 +  return oggpack_bits(b);
 558.516 +}
 558.517 +
 558.518 +unsigned char *oggpack_get_buffer(oggpack_buffer *b){
 558.519 +  return(b->buffer);
 558.520 +}
 558.521 +
 558.522 +unsigned char *oggpackB_get_buffer(oggpack_buffer *b){
 558.523 +  return oggpack_get_buffer(b);
 558.524 +}
 558.525 +
 558.526 +/* Self test of the bitwise routines; everything else is based on
 558.527 +   them, so they damned well better be solid. */
 558.528 +
 558.529 +#ifdef _V_SELFTEST
 558.530 +#include <stdio.h>
 558.531 +
 558.532 +static int ilog(unsigned int v){
 558.533 +  int ret=0;
 558.534 +  while(v){
 558.535 +    ret++;
 558.536 +    v>>=1;
 558.537 +  }
 558.538 +  return(ret);
 558.539 +}
 558.540 +
 558.541 +oggpack_buffer o;
 558.542 +oggpack_buffer r;
 558.543 +
 558.544 +void report(char *in){
 558.545 +  fprintf(stderr,"%s",in);
 558.546 +  exit(1);
 558.547 +}
 558.548 +
 558.549 +void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
 558.550 +  long bytes,i;
 558.551 +  unsigned char *buffer;
 558.552 +
 558.553 +  oggpack_reset(&o);
 558.554 +  for(i=0;i<vals;i++)
 558.555 +    oggpack_write(&o,b[i],bits?bits:ilog(b[i]));
 558.556 +  buffer=oggpack_get_buffer(&o);
 558.557 +  bytes=oggpack_bytes(&o);
 558.558 +  if(bytes!=compsize)report("wrong number of bytes!\n");
 558.559 +  for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
 558.560 +    for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
 558.561 +    report("wrote incorrect value!\n");
 558.562 +  }
 558.563 +  oggpack_readinit(&r,buffer,bytes);
 558.564 +  for(i=0;i<vals;i++){
 558.565 +    int tbit=bits?bits:ilog(b[i]);
 558.566 +    if(oggpack_look(&r,tbit)==-1)
 558.567 +      report("out of data!\n");
 558.568 +    if(oggpack_look(&r,tbit)!=(b[i]&mask[tbit]))
 558.569 +      report("looked at incorrect value!\n");
 558.570 +    if(tbit==1)
 558.571 +      if(oggpack_look1(&r)!=(b[i]&mask[tbit]))
 558.572 +        report("looked at single bit incorrect value!\n");
 558.573 +    if(tbit==1){
 558.574 +      if(oggpack_read1(&r)!=(b[i]&mask[tbit]))
 558.575 +        report("read incorrect single bit value!\n");
 558.576 +    }else{
 558.577 +    if(oggpack_read(&r,tbit)!=(b[i]&mask[tbit]))
 558.578 +      report("read incorrect value!\n");
 558.579 +    }
 558.580 +  }
 558.581 +  if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
 558.582 +}
 558.583 +
 558.584 +void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){
 558.585 +  long bytes,i;
 558.586 +  unsigned char *buffer;
 558.587 +
 558.588 +  oggpackB_reset(&o);
 558.589 +  for(i=0;i<vals;i++)
 558.590 +    oggpackB_write(&o,b[i],bits?bits:ilog(b[i]));
 558.591 +  buffer=oggpackB_get_buffer(&o);
 558.592 +  bytes=oggpackB_bytes(&o);
 558.593 +  if(bytes!=compsize)report("wrong number of bytes!\n");
 558.594 +  for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
 558.595 +    for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
 558.596 +    report("wrote incorrect value!\n");
 558.597 +  }
 558.598 +  oggpackB_readinit(&r,buffer,bytes);
 558.599 +  for(i=0;i<vals;i++){
 558.600 +    int tbit=bits?bits:ilog(b[i]);
 558.601 +    if(oggpackB_look(&r,tbit)==-1)
 558.602 +      report("out of data!\n");
 558.603 +    if(oggpackB_look(&r,tbit)!=(b[i]&mask[tbit]))
 558.604 +      report("looked at incorrect value!\n");
 558.605 +    if(tbit==1)
 558.606 +      if(oggpackB_look1(&r)!=(b[i]&mask[tbit]))
 558.607 +        report("looked at single bit incorrect value!\n");
 558.608 +    if(tbit==1){
 558.609 +      if(oggpackB_read1(&r)!=(b[i]&mask[tbit]))
 558.610 +        report("read incorrect single bit value!\n");
 558.611 +    }else{
 558.612 +    if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit]))
 558.613 +      report("read incorrect value!\n");
 558.614 +    }
 558.615 +  }
 558.616 +  if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
 558.617 +}
 558.618 +
 558.619 +int main(void){
 558.620 +  unsigned char *buffer;
 558.621 +  long bytes,i;
 558.622 +  static unsigned long testbuffer1[]=
 558.623 +    {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
 558.624 +       567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
 558.625 +  int test1size=43;
 558.626 +
 558.627 +  static unsigned long testbuffer2[]=
 558.628 +    {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
 558.629 +       1233432,534,5,346435231,14436467,7869299,76326614,167548585,
 558.630 +       85525151,0,12321,1,349528352};
 558.631 +  int test2size=21;
 558.632 +
 558.633 +  static unsigned long testbuffer3[]=
 558.634 +    {1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1,
 558.635 +       0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
 558.636 +  int test3size=56;
 558.637 +
 558.638 +  static unsigned long large[]=
 558.639 +    {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
 558.640 +       1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
 558.641 +       85525151,0,12321,1,2146528352};
 558.642 +
 558.643 +  int onesize=33;
 558.644 +  static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
 558.645 +                    34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
 558.646 +                    223,4};
 558.647 +  static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
 558.648 +                       8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
 558.649 +                       245,251,128};
 558.650 +
 558.651 +  int twosize=6;
 558.652 +  static int two[6]={61,255,255,251,231,29};
 558.653 +  static int twoB[6]={247,63,255,253,249,120};
 558.654 +
 558.655 +  int threesize=54;
 558.656 +  static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
 558.657 +                      142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
 558.658 +                      58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
 558.659 +                      100,52,4,14,18,86,77,1};
 558.660 +  static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
 558.661 +                         130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
 558.662 +                         233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
 558.663 +                         200,20,254,4,58,106,176,144,0};
 558.664 +
 558.665 +  int foursize=38;
 558.666 +  static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
 558.667 +                     132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
 558.668 +                     28,2,133,0,1};
 558.669 +  static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
 558.670 +                        1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
 558.671 +                        129,10,4,32};
 558.672 +
 558.673 +  int fivesize=45;
 558.674 +  static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
 558.675 +                     241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
 558.676 +                     84,75,159,2,1,0,132,192,8,0,0,18,22};
 558.677 +  static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
 558.678 +                        124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
 558.679 +                        172,150,169,129,79,128,0,6,4,32,0,27,9,0};
 558.680 +
 558.681 +  int sixsize=7;
 558.682 +  static int six[7]={17,177,170,242,169,19,148};
 558.683 +  static int sixB[7]={136,141,85,79,149,200,41};
 558.684 +
 558.685 +  /* Test read/write together */
 558.686 +  /* Later we test against pregenerated bitstreams */
 558.687 +  oggpack_writeinit(&o);
 558.688 +
 558.689 +  fprintf(stderr,"\nSmall preclipped packing (LSb): ");
 558.690 +  cliptest(testbuffer1,test1size,0,one,onesize);
 558.691 +  fprintf(stderr,"ok.");
 558.692 +
 558.693 +  fprintf(stderr,"\nNull bit call (LSb): ");
 558.694 +  cliptest(testbuffer3,test3size,0,two,twosize);
 558.695 +  fprintf(stderr,"ok.");
 558.696 +
 558.697 +  fprintf(stderr,"\nLarge preclipped packing (LSb): ");
 558.698 +  cliptest(testbuffer2,test2size,0,three,threesize);
 558.699 +  fprintf(stderr,"ok.");
 558.700 +
 558.701 +  fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
 558.702 +  oggpack_reset(&o);
 558.703 +  for(i=0;i<test2size;i++)
 558.704 +    oggpack_write(&o,large[i],32);
 558.705 +  buffer=oggpack_get_buffer(&o);
 558.706 +  bytes=oggpack_bytes(&o);
 558.707 +  oggpack_readinit(&r,buffer,bytes);
 558.708 +  for(i=0;i<test2size;i++){
 558.709 +    if(oggpack_look(&r,32)==-1)report("out of data. failed!");
 558.710 +    if(oggpack_look(&r,32)!=large[i]){
 558.711 +      fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpack_look(&r,32),large[i],
 558.712 +              oggpack_look(&r,32),large[i]);
 558.713 +      report("read incorrect value!\n");
 558.714 +    }
 558.715 +    oggpack_adv(&r,32);
 558.716 +  }
 558.717 +  if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
 558.718 +  fprintf(stderr,"ok.");
 558.719 +
 558.720 +  fprintf(stderr,"\nSmall unclipped packing (LSb): ");
 558.721 +  cliptest(testbuffer1,test1size,7,four,foursize);
 558.722 +  fprintf(stderr,"ok.");
 558.723 +
 558.724 +  fprintf(stderr,"\nLarge unclipped packing (LSb): ");
 558.725 +  cliptest(testbuffer2,test2size,17,five,fivesize);
 558.726 +  fprintf(stderr,"ok.");
 558.727 +
 558.728 +  fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
 558.729 +  cliptest(testbuffer3,test3size,1,six,sixsize);
 558.730 +  fprintf(stderr,"ok.");
 558.731 +
 558.732 +  fprintf(stderr,"\nTesting read past end (LSb): ");
 558.733 +  oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
 558.734 +  for(i=0;i<64;i++){
 558.735 +    if(oggpack_read(&r,1)!=0){
 558.736 +      fprintf(stderr,"failed; got -1 prematurely.\n");
 558.737 +      exit(1);
 558.738 +    }
 558.739 +  }
 558.740 +  if(oggpack_look(&r,1)!=-1 ||
 558.741 +     oggpack_read(&r,1)!=-1){
 558.742 +      fprintf(stderr,"failed; read past end without -1.\n");
 558.743 +      exit(1);
 558.744 +  }
 558.745 +  oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
 558.746 +  if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){
 558.747 +      fprintf(stderr,"failed 2; got -1 prematurely.\n");
 558.748 +      exit(1);
 558.749 +  }
 558.750 +
 558.751 +  if(oggpack_look(&r,18)!=0 ||
 558.752 +     oggpack_look(&r,18)!=0){
 558.753 +    fprintf(stderr,"failed 3; got -1 prematurely.\n");
 558.754 +      exit(1);
 558.755 +  }
 558.756 +  if(oggpack_look(&r,19)!=-1 ||
 558.757 +     oggpack_look(&r,19)!=-1){
 558.758 +    fprintf(stderr,"failed; read past end without -1.\n");
 558.759 +      exit(1);
 558.760 +  }
 558.761 +  if(oggpack_look(&r,32)!=-1 ||
 558.762 +     oggpack_look(&r,32)!=-1){
 558.763 +    fprintf(stderr,"failed; read past end without -1.\n");
 558.764 +      exit(1);
 558.765 +  }
 558.766 +  oggpack_writeclear(&o);
 558.767 +  fprintf(stderr,"ok.\n");
 558.768 +
 558.769 +  /********** lazy, cut-n-paste retest with MSb packing ***********/
 558.770 +
 558.771 +  /* Test read/write together */
 558.772 +  /* Later we test against pregenerated bitstreams */
 558.773 +  oggpackB_writeinit(&o);
 558.774 +
 558.775 +  fprintf(stderr,"\nSmall preclipped packing (MSb): ");
 558.776 +  cliptestB(testbuffer1,test1size,0,oneB,onesize);
 558.777 +  fprintf(stderr,"ok.");
 558.778 +
 558.779 +  fprintf(stderr,"\nNull bit call (MSb): ");
 558.780 +  cliptestB(testbuffer3,test3size,0,twoB,twosize);
 558.781 +  fprintf(stderr,"ok.");
 558.782 +
 558.783 +  fprintf(stderr,"\nLarge preclipped packing (MSb): ");
 558.784 +  cliptestB(testbuffer2,test2size,0,threeB,threesize);
 558.785 +  fprintf(stderr,"ok.");
 558.786 +
 558.787 +  fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
 558.788 +  oggpackB_reset(&o);
 558.789 +  for(i=0;i<test2size;i++)
 558.790 +    oggpackB_write(&o,large[i],32);
 558.791 +  buffer=oggpackB_get_buffer(&o);
 558.792 +  bytes=oggpackB_bytes(&o);
 558.793 +  oggpackB_readinit(&r,buffer,bytes);
 558.794 +  for(i=0;i<test2size;i++){
 558.795 +    if(oggpackB_look(&r,32)==-1)report("out of data. failed!");
 558.796 +    if(oggpackB_look(&r,32)!=large[i]){
 558.797 +      fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i],
 558.798 +              oggpackB_look(&r,32),large[i]);
 558.799 +      report("read incorrect value!\n");
 558.800 +    }
 558.801 +    oggpackB_adv(&r,32);
 558.802 +  }
 558.803 +  if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
 558.804 +  fprintf(stderr,"ok.");
 558.805 +
 558.806 +  fprintf(stderr,"\nSmall unclipped packing (MSb): ");
 558.807 +  cliptestB(testbuffer1,test1size,7,fourB,foursize);
 558.808 +  fprintf(stderr,"ok.");
 558.809 +
 558.810 +  fprintf(stderr,"\nLarge unclipped packing (MSb): ");
 558.811 +  cliptestB(testbuffer2,test2size,17,fiveB,fivesize);
 558.812 +  fprintf(stderr,"ok.");
 558.813 +
 558.814 +  fprintf(stderr,"\nSingle bit unclipped packing (MSb): ");
 558.815 +  cliptestB(testbuffer3,test3size,1,sixB,sixsize);
 558.816 +  fprintf(stderr,"ok.");
 558.817 +
 558.818 +  fprintf(stderr,"\nTesting read past end (MSb): ");
 558.819 +  oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
 558.820 +  for(i=0;i<64;i++){
 558.821 +    if(oggpackB_read(&r,1)!=0){
 558.822 +      fprintf(stderr,"failed; got -1 prematurely.\n");
 558.823 +      exit(1);
 558.824 +    }
 558.825 +  }
 558.826 +  if(oggpackB_look(&r,1)!=-1 ||
 558.827 +     oggpackB_read(&r,1)!=-1){
 558.828 +      fprintf(stderr,"failed; read past end without -1.\n");
 558.829 +      exit(1);
 558.830 +  }
 558.831 +  oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
 558.832 +  if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){
 558.833 +      fprintf(stderr,"failed 2; got -1 prematurely.\n");
 558.834 +      exit(1);
 558.835 +  }
 558.836 +
 558.837 +  if(oggpackB_look(&r,18)!=0 ||
 558.838 +     oggpackB_look(&r,18)!=0){
 558.839 +    fprintf(stderr,"failed 3; got -1 prematurely.\n");
 558.840 +      exit(1);
 558.841 +  }
 558.842 +  if(oggpackB_look(&r,19)!=-1 ||
 558.843 +     oggpackB_look(&r,19)!=-1){
 558.844 +    fprintf(stderr,"failed; read past end without -1.\n");
 558.845 +      exit(1);
 558.846 +  }
 558.847 +  if(oggpackB_look(&r,32)!=-1 ||
 558.848 +     oggpackB_look(&r,32)!=-1){
 558.849 +    fprintf(stderr,"failed; read past end without -1.\n");
 558.850 +      exit(1);
 558.851 +  }
 558.852 +  oggpackB_writeclear(&o);
 558.853 +  fprintf(stderr,"ok.\n\n");
 558.854 +
 558.855 +
 558.856 +  return(0);
 558.857 +}
 558.858 +#endif  /* _V_SELFTEST */
 558.859 +
 558.860 +#undef BUFFER_INCREMENT
   559.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   559.2 +++ b/libs/ogg/framing.c	Sat Feb 01 19:58:19 2014 +0200
   559.3 @@ -0,0 +1,2111 @@
   559.4 +/********************************************************************
   559.5 + *                                                                  *
   559.6 + * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE.              *
   559.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   559.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   559.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  559.10 + *                                                                  *
  559.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
  559.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  559.13 + *                                                                  *
  559.14 + ********************************************************************
  559.15 +
  559.16 + function: code raw packets into framed OggSquish stream and
  559.17 +           decode Ogg streams back into raw packets
  559.18 + last mod: $Id: framing.c 18758 2013-01-08 16:29:56Z tterribe $
  559.19 +
  559.20 + note: The CRC code is directly derived from public domain code by
  559.21 + Ross Williams (ross@guest.adelaide.edu.au).  See docs/framing.html
  559.22 + for details.
  559.23 +
  559.24 + ********************************************************************/
  559.25 +
  559.26 +#include <stdlib.h>
  559.27 +#include <limits.h>
  559.28 +#include <string.h>
  559.29 +#include <ogg/ogg.h>
  559.30 +
  559.31 +/* A complete description of Ogg framing exists in docs/framing.html */
  559.32 +
  559.33 +int ogg_page_version(const ogg_page *og){
  559.34 +  return((int)(og->header[4]));
  559.35 +}
  559.36 +
  559.37 +int ogg_page_continued(const ogg_page *og){
  559.38 +  return((int)(og->header[5]&0x01));
  559.39 +}
  559.40 +
  559.41 +int ogg_page_bos(const ogg_page *og){
  559.42 +  return((int)(og->header[5]&0x02));
  559.43 +}
  559.44 +
  559.45 +int ogg_page_eos(const ogg_page *og){
  559.46 +  return((int)(og->header[5]&0x04));
  559.47 +}
  559.48 +
  559.49 +ogg_int64_t ogg_page_granulepos(const ogg_page *og){
  559.50 +  unsigned char *page=og->header;
  559.51 +  ogg_int64_t granulepos=page[13]&(0xff);
  559.52 +  granulepos= (granulepos<<8)|(page[12]&0xff);
  559.53 +  granulepos= (granulepos<<8)|(page[11]&0xff);
  559.54 +  granulepos= (granulepos<<8)|(page[10]&0xff);
  559.55 +  granulepos= (granulepos<<8)|(page[9]&0xff);
  559.56 +  granulepos= (granulepos<<8)|(page[8]&0xff);
  559.57 +  granulepos= (granulepos<<8)|(page[7]&0xff);
  559.58 +  granulepos= (granulepos<<8)|(page[6]&0xff);
  559.59 +  return(granulepos);
  559.60 +}
  559.61 +
  559.62 +int ogg_page_serialno(const ogg_page *og){
  559.63 +  return(og->header[14] |
  559.64 +         (og->header[15]<<8) |
  559.65 +         (og->header[16]<<16) |
  559.66 +         (og->header[17]<<24));
  559.67 +}
  559.68 +
  559.69 +long ogg_page_pageno(const ogg_page *og){
  559.70 +  return(og->header[18] |
  559.71 +         (og->header[19]<<8) |
  559.72 +         (og->header[20]<<16) |
  559.73 +         (og->header[21]<<24));
  559.74 +}
  559.75 +
  559.76 +
  559.77 +
  559.78 +/* returns the number of packets that are completed on this page (if
  559.79 +   the leading packet is begun on a previous page, but ends on this
  559.80 +   page, it's counted */
  559.81 +
  559.82 +/* NOTE:
  559.83 +   If a page consists of a packet begun on a previous page, and a new
  559.84 +   packet begun (but not completed) on this page, the return will be:
  559.85 +     ogg_page_packets(page)   ==1,
  559.86 +     ogg_page_continued(page) !=0
  559.87 +
  559.88 +   If a page happens to be a single packet that was begun on a
  559.89 +   previous page, and spans to the next page (in the case of a three or
  559.90 +   more page packet), the return will be:
  559.91 +     ogg_page_packets(page)   ==0,
  559.92 +     ogg_page_continued(page) !=0
  559.93 +*/
  559.94 +
  559.95 +int ogg_page_packets(const ogg_page *og){
  559.96 +  int i,n=og->header[26],count=0;
  559.97 +  for(i=0;i<n;i++)
  559.98 +    if(og->header[27+i]<255)count++;
  559.99 +  return(count);
 559.100 +}
 559.101 +
 559.102 +
 559.103 +#if 0
 559.104 +/* helper to initialize lookup for direct-table CRC (illustrative; we
 559.105 +   use the static init below) */
 559.106 +
 559.107 +static ogg_uint32_t _ogg_crc_entry(unsigned long index){
 559.108 +  int           i;
 559.109 +  unsigned long r;
 559.110 +
 559.111 +  r = index << 24;
 559.112 +  for (i=0; i<8; i++)
 559.113 +    if (r & 0x80000000UL)
 559.114 +      r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator
 559.115 +                                    polynomial, although we use an
 559.116 +                                    unreflected alg and an init/final
 559.117 +                                    of 0, not 0xffffffff */
 559.118 +    else
 559.119 +       r<<=1;
 559.120 + return (r & 0xffffffffUL);
 559.121 +}
 559.122 +#endif
 559.123 +
 559.124 +static const ogg_uint32_t crc_lookup[256]={
 559.125 +  0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
 559.126 +  0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
 559.127 +  0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
 559.128 +  0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
 559.129 +  0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
 559.130 +  0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
 559.131 +  0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
 559.132 +  0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
 559.133 +  0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
 559.134 +  0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
 559.135 +  0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
 559.136 +  0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
 559.137 +  0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
 559.138 +  0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
 559.139 +  0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
 559.140 +  0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
 559.141 +  0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
 559.142 +  0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
 559.143 +  0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
 559.144 +  0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
 559.145 +  0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
 559.146 +  0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
 559.147 +  0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
 559.148 +  0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
 559.149 +  0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
 559.150 +  0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
 559.151 +  0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
 559.152 +  0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
 559.153 +  0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
 559.154 +  0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
 559.155 +  0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
 559.156 +  0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
 559.157 +  0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
 559.158 +  0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
 559.159 +  0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
 559.160 +  0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
 559.161 +  0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
 559.162 +  0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
 559.163 +  0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
 559.164 +  0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
 559.165 +  0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
 559.166 +  0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
 559.167 +  0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
 559.168 +  0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
 559.169 +  0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
 559.170 +  0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
 559.171 +  0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
 559.172 +  0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
 559.173 +  0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
 559.174 +  0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
 559.175 +  0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
 559.176 +  0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
 559.177 +  0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
 559.178 +  0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
 559.179 +  0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
 559.180 +  0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
 559.181 +  0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
 559.182 +  0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
 559.183 +  0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
 559.184 +  0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
 559.185 +  0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
 559.186 +  0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
 559.187 +  0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
 559.188 +  0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
 559.189 +
 559.190 +/* init the encode/decode logical stream state */
 559.191 +
 559.192 +int ogg_stream_init(ogg_stream_state *os,int serialno){
 559.193 +  if(os){
 559.194 +    memset(os,0,sizeof(*os));
 559.195 +    os->body_storage=16*1024;
 559.196 +    os->lacing_storage=1024;
 559.197 +
 559.198 +    os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data));
 559.199 +    os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
 559.200 +    os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals));
 559.201 +
 559.202 +    if(!os->body_data || !os->lacing_vals || !os->granule_vals){
 559.203 +      ogg_stream_clear(os);
 559.204 +      return -1;
 559.205 +    }
 559.206 +
 559.207 +    os->serialno=serialno;
 559.208 +
 559.209 +    return(0);
 559.210 +  }
 559.211 +  return(-1);
 559.212 +}
 559.213 +
 559.214 +/* async/delayed error detection for the ogg_stream_state */
 559.215 +int ogg_stream_check(ogg_stream_state *os){
 559.216 +  if(!os || !os->body_data) return -1;
 559.217 +  return 0;
 559.218 +}
 559.219 +
 559.220 +/* _clear does not free os, only the non-flat storage within */
 559.221 +int ogg_stream_clear(ogg_stream_state *os){
 559.222 +  if(os){
 559.223 +    if(os->body_data)_ogg_free(os->body_data);
 559.224 +    if(os->lacing_vals)_ogg_free(os->lacing_vals);
 559.225 +    if(os->granule_vals)_ogg_free(os->granule_vals);
 559.226 +
 559.227 +    memset(os,0,sizeof(*os));
 559.228 +  }
 559.229 +  return(0);
 559.230 +}
 559.231 +
 559.232 +int ogg_stream_destroy(ogg_stream_state *os){
 559.233 +  if(os){
 559.234 +    ogg_stream_clear(os);
 559.235 +    _ogg_free(os);
 559.236 +  }
 559.237 +  return(0);
 559.238 +}
 559.239 +
 559.240 +/* Helpers for ogg_stream_encode; this keeps the structure and
 559.241 +   what's happening fairly clear */
 559.242 +
 559.243 +static int _os_body_expand(ogg_stream_state *os,long needed){
 559.244 +  if(os->body_storage-needed<=os->body_fill){
 559.245 +    long body_storage;
 559.246 +    void *ret;
 559.247 +    if(os->body_storage>LONG_MAX-needed){
 559.248 +      ogg_stream_clear(os);
 559.249 +      return -1;
 559.250 +    }
 559.251 +    body_storage=os->body_storage+needed;
 559.252 +    if(body_storage<LONG_MAX-1024)body_storage+=1024;
 559.253 +    ret=_ogg_realloc(os->body_data,body_storage*sizeof(*os->body_data));
 559.254 +    if(!ret){
 559.255 +      ogg_stream_clear(os);
 559.256 +      return -1;
 559.257 +    }
 559.258 +    os->body_storage=body_storage;
 559.259 +    os->body_data=ret;
 559.260 +  }
 559.261 +  return 0;
 559.262 +}
 559.263 +
 559.264 +static int _os_lacing_expand(ogg_stream_state *os,long needed){
 559.265 +  if(os->lacing_storage-needed<=os->lacing_fill){
 559.266 +    long lacing_storage;
 559.267 +    void *ret;
 559.268 +    if(os->lacing_storage>LONG_MAX-needed){
 559.269 +      ogg_stream_clear(os);
 559.270 +      return -1;
 559.271 +    }
 559.272 +    lacing_storage=os->lacing_storage+needed;
 559.273 +    if(lacing_storage<LONG_MAX-32)lacing_storage+=32;
 559.274 +    ret=_ogg_realloc(os->lacing_vals,lacing_storage*sizeof(*os->lacing_vals));
 559.275 +    if(!ret){
 559.276 +      ogg_stream_clear(os);
 559.277 +      return -1;
 559.278 +    }
 559.279 +    os->lacing_vals=ret;
 559.280 +    ret=_ogg_realloc(os->granule_vals,lacing_storage*
 559.281 +                     sizeof(*os->granule_vals));
 559.282 +    if(!ret){
 559.283 +      ogg_stream_clear(os);
 559.284 +      return -1;
 559.285 +    }
 559.286 +    os->granule_vals=ret;
 559.287 +    os->lacing_storage=lacing_storage;
 559.288 +  }
 559.289 +  return 0;
 559.290 +}
 559.291 +
 559.292 +/* checksum the page */
 559.293 +/* Direct table CRC; note that this will be faster in the future if we
 559.294 +   perform the checksum simultaneously with other copies */
 559.295 +
 559.296 +void ogg_page_checksum_set(ogg_page *og){
 559.297 +  if(og){
 559.298 +    ogg_uint32_t crc_reg=0;
 559.299 +    int i;
 559.300 +
 559.301 +    /* safety; needed for API behavior, but not framing code */
 559.302 +    og->header[22]=0;
 559.303 +    og->header[23]=0;
 559.304 +    og->header[24]=0;
 559.305 +    og->header[25]=0;
 559.306 +
 559.307 +    for(i=0;i<og->header_len;i++)
 559.308 +      crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
 559.309 +    for(i=0;i<og->body_len;i++)
 559.310 +      crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
 559.311 +
 559.312 +    og->header[22]=(unsigned char)(crc_reg&0xff);
 559.313 +    og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
 559.314 +    og->header[24]=(unsigned char)((crc_reg>>16)&0xff);
 559.315 +    og->header[25]=(unsigned char)((crc_reg>>24)&0xff);
 559.316 +  }
 559.317 +}
 559.318 +
 559.319 +/* submit data to the internal buffer of the framing engine */
 559.320 +int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
 559.321 +                       long e_o_s, ogg_int64_t granulepos){
 559.322 +
 559.323 +  long bytes = 0, lacing_vals;
 559.324 +  int i;
 559.325 +
 559.326 +  if(ogg_stream_check(os)) return -1;
 559.327 +  if(!iov) return 0;
 559.328 +
 559.329 +  for (i = 0; i < count; ++i){
 559.330 +    if(iov[i].iov_len>LONG_MAX) return -1;
 559.331 +    if(bytes>LONG_MAX-(long)iov[i].iov_len) return -1;
 559.332 +    bytes += (long)iov[i].iov_len;
 559.333 +  }
 559.334 +  lacing_vals=bytes/255+1;
 559.335 +
 559.336 +  if(os->body_returned){
 559.337 +    /* advance packet data according to the body_returned pointer. We
 559.338 +       had to keep it around to return a pointer into the buffer last
 559.339 +       call */
 559.340 +
 559.341 +    os->body_fill-=os->body_returned;
 559.342 +    if(os->body_fill)
 559.343 +      memmove(os->body_data,os->body_data+os->body_returned,
 559.344 +              os->body_fill);
 559.345 +    os->body_returned=0;
 559.346 +  }
 559.347 +
 559.348 +  /* make sure we have the buffer storage */
 559.349 +  if(_os_body_expand(os,bytes) || _os_lacing_expand(os,lacing_vals))
 559.350 +    return -1;
 559.351 +
 559.352 +  /* Copy in the submitted packet.  Yes, the copy is a waste; this is
 559.353 +     the liability of overly clean abstraction for the time being.  It
 559.354 +     will actually be fairly easy to eliminate the extra copy in the
 559.355 +     future */
 559.356 +
 559.357 +  for (i = 0; i < count; ++i) {
 559.358 +    memcpy(os->body_data+os->body_fill, iov[i].iov_base, iov[i].iov_len);
 559.359 +    os->body_fill += (int)iov[i].iov_len;
 559.360 +  }
 559.361 +
 559.362 +  /* Store lacing vals for this packet */
 559.363 +  for(i=0;i<lacing_vals-1;i++){
 559.364 +    os->lacing_vals[os->lacing_fill+i]=255;
 559.365 +    os->granule_vals[os->lacing_fill+i]=os->granulepos;
 559.366 +  }
 559.367 +  os->lacing_vals[os->lacing_fill+i]=bytes%255;
 559.368 +  os->granulepos=os->granule_vals[os->lacing_fill+i]=granulepos;
 559.369 +
 559.370 +  /* flag the first segment as the beginning of the packet */
 559.371 +  os->lacing_vals[os->lacing_fill]|= 0x100;
 559.372 +
 559.373 +  os->lacing_fill+=lacing_vals;
 559.374 +
 559.375 +  /* for the sake of completeness */
 559.376 +  os->packetno++;
 559.377 +
 559.378 +  if(e_o_s)os->e_o_s=1;
 559.379 +
 559.380 +  return(0);
 559.381 +}
 559.382 +
 559.383 +int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
 559.384 +  ogg_iovec_t iov;
 559.385 +  iov.iov_base = op->packet;
 559.386 +  iov.iov_len = op->bytes;
 559.387 +  return ogg_stream_iovecin(os, &iov, 1, op->e_o_s, op->granulepos);
 559.388 +}
 559.389 +
 559.390 +/* Conditionally flush a page; force==0 will only flush nominal-size
 559.391 +   pages, force==1 forces us to flush a page regardless of page size
 559.392 +   so long as there's any data available at all. */
 559.393 +static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int nfill){
 559.394 +  int i;
 559.395 +  int vals=0;
 559.396 +  int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
 559.397 +  int bytes=0;
 559.398 +  long acc=0;
 559.399 +  ogg_int64_t granule_pos=-1;
 559.400 +
 559.401 +  if(ogg_stream_check(os)) return(0);
 559.402 +  if(maxvals==0) return(0);
 559.403 +
 559.404 +  /* construct a page */
 559.405 +  /* decide how many segments to include */
 559.406 +
 559.407 +  /* If this is the initial header case, the first page must only include
 559.408 +     the initial header packet */
 559.409 +  if(os->b_o_s==0){  /* 'initial header page' case */
 559.410 +    granule_pos=0;
 559.411 +    for(vals=0;vals<maxvals;vals++){
 559.412 +      if((os->lacing_vals[vals]&0x0ff)<255){
 559.413 +        vals++;
 559.414 +        break;
 559.415 +      }
 559.416 +    }
 559.417 +  }else{
 559.418 +
 559.419 +    /* The extra packets_done, packet_just_done logic here attempts to do two things:
 559.420 +       1) Don't unneccessarily span pages.
 559.421 +       2) Unless necessary, don't flush pages if there are less than four packets on
 559.422 +          them; this expands page size to reduce unneccessary overhead if incoming packets
 559.423 +          are large.
 559.424 +       These are not necessary behaviors, just 'always better than naive flushing'
 559.425 +       without requiring an application to explicitly request a specific optimized
 559.426 +       behavior. We'll want an explicit behavior setup pathway eventually as well. */
 559.427 +
 559.428 +    int packets_done=0;
 559.429 +    int packet_just_done=0;
 559.430 +    for(vals=0;vals<maxvals;vals++){
 559.431 +      if(acc>nfill && packet_just_done>=4){
 559.432 +        force=1;
 559.433 +        break;
 559.434 +      }
 559.435 +      acc+=os->lacing_vals[vals]&0x0ff;
 559.436 +      if((os->lacing_vals[vals]&0xff)<255){
 559.437 +        granule_pos=os->granule_vals[vals];
 559.438 +        packet_just_done=++packets_done;
 559.439 +      }else
 559.440 +        packet_just_done=0;
 559.441 +    }
 559.442 +    if(vals==255)force=1;
 559.443 +  }
 559.444 +
 559.445 +  if(!force) return(0);
 559.446 +
 559.447 +  /* construct the header in temp storage */
 559.448 +  memcpy(os->header,"OggS",4);
 559.449 +
 559.450 +  /* stream structure version */
 559.451 +  os->header[4]=0x00;
 559.452 +
 559.453 +  /* continued packet flag? */
 559.454 +  os->header[5]=0x00;
 559.455 +  if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
 559.456 +  /* first page flag? */
 559.457 +  if(os->b_o_s==0)os->header[5]|=0x02;
 559.458 +  /* last page flag? */
 559.459 +  if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04;
 559.460 +  os->b_o_s=1;
 559.461 +
 559.462 +  /* 64 bits of PCM position */
 559.463 +  for(i=6;i<14;i++){
 559.464 +    os->header[i]=(unsigned char)(granule_pos&0xff);
 559.465 +    granule_pos>>=8;
 559.466 +  }
 559.467 +
 559.468 +  /* 32 bits of stream serial number */
 559.469 +  {
 559.470 +    long serialno=os->serialno;
 559.471 +    for(i=14;i<18;i++){
 559.472 +      os->header[i]=(unsigned char)(serialno&0xff);
 559.473 +      serialno>>=8;
 559.474 +    }
 559.475 +  }
 559.476 +
 559.477 +  /* 32 bits of page counter (we have both counter and page header
 559.478 +     because this val can roll over) */
 559.479 +  if(os->pageno==-1)os->pageno=0; /* because someone called
 559.480 +                                     stream_reset; this would be a
 559.481 +                                     strange thing to do in an
 559.482 +                                     encode stream, but it has
 559.483 +                                     plausible uses */
 559.484 +  {
 559.485 +    long pageno=os->pageno++;
 559.486 +    for(i=18;i<22;i++){
 559.487 +      os->header[i]=(unsigned char)(pageno&0xff);
 559.488 +      pageno>>=8;
 559.489 +    }
 559.490 +  }
 559.491 +
 559.492 +  /* zero for computation; filled in later */
 559.493 +  os->header[22]=0;
 559.494 +  os->header[23]=0;
 559.495 +  os->header[24]=0;
 559.496 +  os->header[25]=0;
 559.497 +
 559.498 +  /* segment table */
 559.499 +  os->header[26]=(unsigned char)(vals&0xff);
 559.500 +  for(i=0;i<vals;i++)
 559.501 +    bytes+=os->header[i+27]=(unsigned char)(os->lacing_vals[i]&0xff);
 559.502 +
 559.503 +  /* set pointers in the ogg_page struct */
 559.504 +  og->header=os->header;
 559.505 +  og->header_len=os->header_fill=vals+27;
 559.506 +  og->body=os->body_data+os->body_returned;
 559.507 +  og->body_len=bytes;
 559.508 +
 559.509 +  /* advance the lacing data and set the body_returned pointer */
 559.510 +
 559.511 +  os->lacing_fill-=vals;
 559.512 +  memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
 559.513 +  memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
 559.514 +  os->body_returned+=bytes;
 559.515 +
 559.516 +  /* calculate the checksum */
 559.517 +
 559.518 +  ogg_page_checksum_set(og);
 559.519 +
 559.520 +  /* done */
 559.521 +  return(1);
 559.522 +}
 559.523 +
 559.524 +/* This will flush remaining packets into a page (returning nonzero),
 559.525 +   even if there is not enough data to trigger a flush normally
 559.526 +   (undersized page). If there are no packets or partial packets to
 559.527 +   flush, ogg_stream_flush returns 0.  Note that ogg_stream_flush will
 559.528 +   try to flush a normal sized page like ogg_stream_pageout; a call to
 559.529 +   ogg_stream_flush does not guarantee that all packets have flushed.
 559.530 +   Only a return value of 0 from ogg_stream_flush indicates all packet
 559.531 +   data is flushed into pages.
 559.532 +
 559.533 +   since ogg_stream_flush will flush the last page in a stream even if
 559.534 +   it's undersized, you almost certainly want to use ogg_stream_pageout
 559.535 +   (and *not* ogg_stream_flush) unless you specifically need to flush
 559.536 +   a page regardless of size in the middle of a stream. */
 559.537 +
 559.538 +int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){
 559.539 +  return ogg_stream_flush_i(os,og,1,4096);
 559.540 +}
 559.541 +
 559.542 +/* Like the above, but an argument is provided to adjust the nominal
 559.543 +   page size for applications which are smart enough to provide their
 559.544 +   own delay based flushing */
 559.545 +
 559.546 +int ogg_stream_flush_fill(ogg_stream_state *os,ogg_page *og, int nfill){
 559.547 +  return ogg_stream_flush_i(os,og,1,nfill);
 559.548 +}
 559.549 +
 559.550 +/* This constructs pages from buffered packet segments.  The pointers
 559.551 +returned are to static buffers; do not free. The returned buffers are
 559.552 +good only until the next call (using the same ogg_stream_state) */
 559.553 +
 559.554 +int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
 559.555 +  int force=0;
 559.556 +  if(ogg_stream_check(os)) return 0;
 559.557 +
 559.558 +  if((os->e_o_s&&os->lacing_fill) ||          /* 'were done, now flush' case */
 559.559 +     (os->lacing_fill&&!os->b_o_s))           /* 'initial header page' case */
 559.560 +    force=1;
 559.561 +
 559.562 +  return(ogg_stream_flush_i(os,og,force,4096));
 559.563 +}
 559.564 +
 559.565 +/* Like the above, but an argument is provided to adjust the nominal
 559.566 +page size for applications which are smart enough to provide their
 559.567 +own delay based flushing */
 559.568 +
 559.569 +int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill){
 559.570 +  int force=0;
 559.571 +  if(ogg_stream_check(os)) return 0;
 559.572 +
 559.573 +  if((os->e_o_s&&os->lacing_fill) ||          /* 'were done, now flush' case */
 559.574 +     (os->lacing_fill&&!os->b_o_s))           /* 'initial header page' case */
 559.575 +    force=1;
 559.576 +
 559.577 +  return(ogg_stream_flush_i(os,og,force,nfill));
 559.578 +}
 559.579 +
 559.580 +int ogg_stream_eos(ogg_stream_state *os){
 559.581 +  if(ogg_stream_check(os)) return 1;
 559.582 +  return os->e_o_s;
 559.583 +}
 559.584 +
 559.585 +/* DECODING PRIMITIVES: packet streaming layer **********************/
 559.586 +
 559.587 +/* This has two layers to place more of the multi-serialno and paging
 559.588 +   control in the application's hands.  First, we expose a data buffer
 559.589 +   using ogg_sync_buffer().  The app either copies into the
 559.590 +   buffer, or passes it directly to read(), etc.  We then call
 559.591 +   ogg_sync_wrote() to tell how many bytes we just added.
 559.592 +
 559.593 +   Pages are returned (pointers into the buffer in ogg_sync_state)
 559.594 +   by ogg_sync_pageout().  The page is then submitted to
 559.595 +   ogg_stream_pagein() along with the appropriate
 559.596 +   ogg_stream_state* (ie, matching serialno).  We then get raw
 559.597 +   packets out calling ogg_stream_packetout() with a
 559.598 +   ogg_stream_state. */
 559.599 +
 559.600 +/* initialize the struct to a known state */
 559.601 +int ogg_sync_init(ogg_sync_state *oy){
 559.602 +  if(oy){
 559.603 +    oy->storage = -1; /* used as a readiness flag */
 559.604 +    memset(oy,0,sizeof(*oy));
 559.605 +  }
 559.606 +  return(0);
 559.607 +}
 559.608 +
 559.609 +/* clear non-flat storage within */
 559.610 +int ogg_sync_clear(ogg_sync_state *oy){
 559.611 +  if(oy){
 559.612 +    if(oy->data)_ogg_free(oy->data);
 559.613 +    memset(oy,0,sizeof(*oy));
 559.614 +  }
 559.615 +  return(0);
 559.616 +}
 559.617 +
 559.618 +int ogg_sync_destroy(ogg_sync_state *oy){
 559.619 +  if(oy){
 559.620 +    ogg_sync_clear(oy);
 559.621 +    _ogg_free(oy);
 559.622 +  }
 559.623 +  return(0);
 559.624 +}
 559.625 +
 559.626 +int ogg_sync_check(ogg_sync_state *oy){
 559.627 +  if(oy->storage<0) return -1;
 559.628 +  return 0;
 559.629 +}
 559.630 +
 559.631 +char *ogg_sync_buffer(ogg_sync_state *oy, long size){
 559.632 +  if(ogg_sync_check(oy)) return NULL;
 559.633 +
 559.634 +  /* first, clear out any space that has been previously returned */
 559.635 +  if(oy->returned){
 559.636 +    oy->fill-=oy->returned;
 559.637 +    if(oy->fill>0)
 559.638 +      memmove(oy->data,oy->data+oy->returned,oy->fill);
 559.639 +    oy->returned=0;
 559.640 +  }
 559.641 +
 559.642 +  if(size>oy->storage-oy->fill){
 559.643 +    /* We need to extend the internal buffer */
 559.644 +    long newsize=size+oy->fill+4096; /* an extra page to be nice */
 559.645 +    void *ret;
 559.646 +
 559.647 +    if(oy->data)
 559.648 +      ret=_ogg_realloc(oy->data,newsize);
 559.649 +    else
 559.650 +      ret=_ogg_malloc(newsize);
 559.651 +    if(!ret){
 559.652 +      ogg_sync_clear(oy);
 559.653 +      return NULL;
 559.654 +    }
 559.655 +    oy->data=ret;
 559.656 +    oy->storage=newsize;
 559.657 +  }
 559.658 +
 559.659 +  /* expose a segment at least as large as requested at the fill mark */
 559.660 +  return((char *)oy->data+oy->fill);
 559.661 +}
 559.662 +
 559.663 +int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
 559.664 +  if(ogg_sync_check(oy))return -1;
 559.665 +  if(oy->fill+bytes>oy->storage)return -1;
 559.666 +  oy->fill+=bytes;
 559.667 +  return(0);
 559.668 +}
 559.669 +
 559.670 +/* sync the stream.  This is meant to be useful for finding page
 559.671 +   boundaries.
 559.672 +
 559.673 +   return values for this:
 559.674 +  -n) skipped n bytes
 559.675 +   0) page not ready; more data (no bytes skipped)
 559.676 +   n) page synced at current location; page length n bytes
 559.677 +
 559.678 +*/
 559.679 +
 559.680 +long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
 559.681 +  unsigned char *page=oy->data+oy->returned;
 559.682 +  unsigned char *next;
 559.683 +  long bytes=oy->fill-oy->returned;
 559.684 +
 559.685 +  if(ogg_sync_check(oy))return 0;
 559.686 +
 559.687 +  if(oy->headerbytes==0){
 559.688 +    int headerbytes,i;
 559.689 +    if(bytes<27)return(0); /* not enough for a header */
 559.690 +
 559.691 +    /* verify capture pattern */
 559.692 +    if(memcmp(page,"OggS",4))goto sync_fail;
 559.693 +
 559.694 +    headerbytes=page[26]+27;
 559.695 +    if(bytes<headerbytes)return(0); /* not enough for header + seg table */
 559.696 +
 559.697 +    /* count up body length in the segment table */
 559.698 +
 559.699 +    for(i=0;i<page[26];i++)
 559.700 +      oy->bodybytes+=page[27+i];
 559.701 +    oy->headerbytes=headerbytes;
 559.702 +  }
 559.703 +
 559.704 +  if(oy->bodybytes+oy->headerbytes>bytes)return(0);
 559.705 +
 559.706 +  /* The whole test page is buffered.  Verify the checksum */
 559.707 +  {
 559.708 +    /* Grab the checksum bytes, set the header field to zero */
 559.709 +    char chksum[4];
 559.710 +    ogg_page log;
 559.711 +
 559.712 +    memcpy(chksum,page+22,4);
 559.713 +    memset(page+22,0,4);
 559.714 +
 559.715 +    /* set up a temp page struct and recompute the checksum */
 559.716 +    log.header=page;
 559.717 +    log.header_len=oy->headerbytes;
 559.718 +    log.body=page+oy->headerbytes;
 559.719 +    log.body_len=oy->bodybytes;
 559.720 +    ogg_page_checksum_set(&log);
 559.721 +
 559.722 +    /* Compare */
 559.723 +    if(memcmp(chksum,page+22,4)){
 559.724 +      /* D'oh.  Mismatch! Corrupt page (or miscapture and not a page
 559.725 +         at all) */
 559.726 +      /* replace the computed checksum with the one actually read in */
 559.727 +      memcpy(page+22,chksum,4);
 559.728 +
 559.729 +      /* Bad checksum. Lose sync */
 559.730 +      goto sync_fail;
 559.731 +    }
 559.732 +  }
 559.733 +
 559.734 +  /* yes, have a whole page all ready to go */
 559.735 +  {
 559.736 +    unsigned char *page=oy->data+oy->returned;
 559.737 +    long bytes;
 559.738 +
 559.739 +    if(og){
 559.740 +      og->header=page;
 559.741 +      og->header_len=oy->headerbytes;
 559.742 +      og->body=page+oy->headerbytes;
 559.743 +      og->body_len=oy->bodybytes;
 559.744 +    }
 559.745 +
 559.746 +    oy->unsynced=0;
 559.747 +    oy->returned+=(bytes=oy->headerbytes+oy->bodybytes);
 559.748 +    oy->headerbytes=0;
 559.749 +    oy->bodybytes=0;
 559.750 +    return(bytes);
 559.751 +  }
 559.752 +
 559.753 + sync_fail:
 559.754 +
 559.755 +  oy->headerbytes=0;
 559.756 +  oy->bodybytes=0;
 559.757 +
 559.758 +  /* search for possible capture */
 559.759 +  next=memchr(page+1,'O',bytes-1);
 559.760 +  if(!next)
 559.761 +    next=oy->data+oy->fill;
 559.762 +
 559.763 +  oy->returned=(int)(next-oy->data);
 559.764 +  return((long)-(next-page));
 559.765 +}
 559.766 +
 559.767 +/* sync the stream and get a page.  Keep trying until we find a page.
 559.768 +   Suppress 'sync errors' after reporting the first.
 559.769 +
 559.770 +   return values:
 559.771 +   -1) recapture (hole in data)
 559.772 +    0) need more data
 559.773 +    1) page returned
 559.774 +
 559.775 +   Returns pointers into buffered data; invalidated by next call to
 559.776 +   _stream, _clear, _init, or _buffer */
 559.777 +
 559.778 +int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
 559.779 +
 559.780 +  if(ogg_sync_check(oy))return 0;
 559.781 +
 559.782 +  /* all we need to do is verify a page at the head of the stream
 559.783 +     buffer.  If it doesn't verify, we look for the next potential
 559.784 +     frame */
 559.785 +
 559.786 +  for(;;){
 559.787 +    long ret=ogg_sync_pageseek(oy,og);
 559.788 +    if(ret>0){
 559.789 +      /* have a page */
 559.790 +      return(1);
 559.791 +    }
 559.792 +    if(ret==0){
 559.793 +      /* need more data */
 559.794 +      return(0);
 559.795 +    }
 559.796 +
 559.797 +    /* head did not start a synced page... skipped some bytes */
 559.798 +    if(!oy->unsynced){
 559.799 +      oy->unsynced=1;
 559.800 +      return(-1);
 559.801 +    }
 559.802 +
 559.803 +    /* loop. keep looking */
 559.804 +
 559.805 +  }
 559.806 +}
 559.807 +
 559.808 +/* add the incoming page to the stream state; we decompose the page
 559.809 +   into packet segments here as well. */
 559.810 +
 559.811 +int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
 559.812 +  unsigned char *header=og->header;
 559.813 +  unsigned char *body=og->body;
 559.814 +  long           bodysize=og->body_len;
 559.815 +  int            segptr=0;
 559.816 +
 559.817 +  int version=ogg_page_version(og);
 559.818 +  int continued=ogg_page_continued(og);
 559.819 +  int bos=ogg_page_bos(og);
 559.820 +  int eos=ogg_page_eos(og);
 559.821 +  ogg_int64_t granulepos=ogg_page_granulepos(og);
 559.822 +  int serialno=ogg_page_serialno(og);
 559.823 +  long pageno=ogg_page_pageno(og);
 559.824 +  int segments=header[26];
 559.825 +
 559.826 +  if(ogg_stream_check(os)) return -1;
 559.827 +
 559.828 +  /* clean up 'returned data' */
 559.829 +  {
 559.830 +    long lr=os->lacing_returned;
 559.831 +    long br=os->body_returned;
 559.832 +
 559.833 +    /* body data */
 559.834 +    if(br){
 559.835 +      os->body_fill-=br;
 559.836 +      if(os->body_fill)
 559.837 +        memmove(os->body_data,os->body_data+br,os->body_fill);
 559.838 +      os->body_returned=0;
 559.839 +    }
 559.840 +
 559.841 +    if(lr){
 559.842 +      /* segment table */
 559.843 +      if(os->lacing_fill-lr){
 559.844 +        memmove(os->lacing_vals,os->lacing_vals+lr,
 559.845 +                (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
 559.846 +        memmove(os->granule_vals,os->granule_vals+lr,
 559.847 +                (os->lacing_fill-lr)*sizeof(*os->granule_vals));
 559.848 +      }
 559.849 +      os->lacing_fill-=lr;
 559.850 +      os->lacing_packet-=lr;
 559.851 +      os->lacing_returned=0;
 559.852 +    }
 559.853 +  }
 559.854 +
 559.855 +  /* check the serial number */
 559.856 +  if(serialno!=os->serialno)return(-1);
 559.857 +  if(version>0)return(-1);
 559.858 +
 559.859 +  if(_os_lacing_expand(os,segments+1)) return -1;
 559.860 +
 559.861 +  /* are we in sequence? */
 559.862 +  if(pageno!=os->pageno){
 559.863 +    int i;
 559.864 +
 559.865 +    /* unroll previous partial packet (if any) */
 559.866 +    for(i=os->lacing_packet;i<os->lacing_fill;i++)
 559.867 +      os->body_fill-=os->lacing_vals[i]&0xff;
 559.868 +    os->lacing_fill=os->lacing_packet;
 559.869 +
 559.870 +    /* make a note of dropped data in segment table */
 559.871 +    if(os->pageno!=-1){
 559.872 +      os->lacing_vals[os->lacing_fill++]=0x400;
 559.873 +      os->lacing_packet++;
 559.874 +    }
 559.875 +  }
 559.876 +
 559.877 +  /* are we a 'continued packet' page?  If so, we may need to skip
 559.878 +     some segments */
 559.879 +  if(continued){
 559.880 +    if(os->lacing_fill<1 ||
 559.881 +       os->lacing_vals[os->lacing_fill-1]==0x400){
 559.882 +      bos=0;
 559.883 +      for(;segptr<segments;segptr++){
 559.884 +        int val=header[27+segptr];
 559.885 +        body+=val;
 559.886 +        bodysize-=val;
 559.887 +        if(val<255){
 559.888 +          segptr++;
 559.889 +          break;
 559.890 +        }
 559.891 +      }
 559.892 +    }
 559.893 +  }
 559.894 +
 559.895 +  if(bodysize){
 559.896 +    if(_os_body_expand(os,bodysize)) return -1;
 559.897 +    memcpy(os->body_data+os->body_fill,body,bodysize);
 559.898 +    os->body_fill+=bodysize;
 559.899 +  }
 559.900 +
 559.901 +  {
 559.902 +    int saved=-1;
 559.903 +    while(segptr<segments){
 559.904 +      int val=header[27+segptr];
 559.905 +      os->lacing_vals[os->lacing_fill]=val;
 559.906 +      os->granule_vals[os->lacing_fill]=-1;
 559.907 +
 559.908 +      if(bos){
 559.909 +        os->lacing_vals[os->lacing_fill]|=0x100;
 559.910 +        bos=0;
 559.911 +      }
 559.912 +
 559.913 +      if(val<255)saved=os->lacing_fill;
 559.914 +
 559.915 +      os->lacing_fill++;
 559.916 +      segptr++;
 559.917 +
 559.918 +      if(val<255)os->lacing_packet=os->lacing_fill;
 559.919 +    }
 559.920 +
 559.921 +    /* set the granulepos on the last granuleval of the last full packet */
 559.922 +    if(saved!=-1){
 559.923 +      os->granule_vals[saved]=granulepos;
 559.924 +    }
 559.925 +
 559.926 +  }
 559.927 +
 559.928 +  if(eos){
 559.929 +    os->e_o_s=1;
 559.930 +    if(os->lacing_fill>0)
 559.931 +      os->lacing_vals[os->lacing_fill-1]|=0x200;
 559.932 +  }
 559.933 +
 559.934 +  os->pageno=pageno+1;
 559.935 +
 559.936 +  return(0);
 559.937 +}
 559.938 +
 559.939 +/* clear things to an initial state.  Good to call, eg, before seeking */
 559.940 +int ogg_sync_reset(ogg_sync_state *oy){
 559.941 +  if(ogg_sync_check(oy))return -1;
 559.942 +
 559.943 +  oy->fill=0;
 559.944 +  oy->returned=0;
 559.945 +  oy->unsynced=0;
 559.946 +  oy->headerbytes=0;
 559.947 +  oy->bodybytes=0;
 559.948 +  return(0);
 559.949 +}
 559.950 +
 559.951 +int ogg_stream_reset(ogg_stream_state *os){
 559.952 +  if(ogg_stream_check(os)) return -1;
 559.953 +
 559.954 +  os->body_fill=0;
 559.955 +  os->body_returned=0;
 559.956 +
 559.957 +  os->lacing_fill=0;
 559.958 +  os->lacing_packet=0;
 559.959 +  os->lacing_returned=0;
 559.960 +
 559.961 +  os->header_fill=0;
 559.962 +
 559.963 +  os->e_o_s=0;
 559.964 +  os->b_o_s=0;
 559.965 +  os->pageno=-1;
 559.966 +  os->packetno=0;
 559.967 +  os->granulepos=0;
 559.968 +
 559.969 +  return(0);
 559.970 +}
 559.971 +
 559.972 +int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){
 559.973 +  if(ogg_stream_check(os)) return -1;
 559.974 +  ogg_stream_reset(os);
 559.975 +  os->serialno=serialno;
 559.976 +  return(0);
 559.977 +}
 559.978 +
 559.979 +static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){
 559.980 +
 559.981 +  /* The last part of decode. We have the stream broken into packet
 559.982 +     segments.  Now we need to group them into packets (or return the
 559.983 +     out of sync markers) */
 559.984 +
 559.985 +  int ptr=os->lacing_returned;
 559.986 +
 559.987 +  if(os->lacing_packet<=ptr)return(0);
 559.988 +
 559.989 +  if(os->lacing_vals[ptr]&0x400){
 559.990 +    /* we need to tell the codec there's a gap; it might need to
 559.991 +       handle previous packet dependencies. */
 559.992 +    os->lacing_returned++;
 559.993 +    os->packetno++;
 559.994 +    return(-1);
 559.995 +  }
 559.996 +
 559.997 +  if(!op && !adv)return(1); /* just using peek as an inexpensive way
 559.998 +                               to ask if there's a whole packet
 559.999 +                               waiting */
559.1000 +
559.1001 +  /* Gather the whole packet. We'll have no holes or a partial packet */
559.1002 +  {
559.1003 +    int size=os->lacing_vals[ptr]&0xff;
559.1004 +    long bytes=size;
559.1005 +    int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */
559.1006 +    int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */
559.1007 +
559.1008 +    while(size==255){
559.1009 +      int val=os->lacing_vals[++ptr];
559.1010 +      size=val&0xff;
559.1011 +      if(val&0x200)eos=0x200;
559.1012 +      bytes+=size;
559.1013 +    }
559.1014 +
559.1015 +    if(op){
559.1016 +      op->e_o_s=eos;
559.1017 +      op->b_o_s=bos;
559.1018 +      op->packet=os->body_data+os->body_returned;
559.1019 +      op->packetno=os->packetno;
559.1020 +      op->granulepos=os->granule_vals[ptr];
559.1021 +      op->bytes=bytes;
559.1022 +    }
559.1023 +
559.1024 +    if(adv){
559.1025 +      os->body_returned+=bytes;
559.1026 +      os->lacing_returned=ptr+1;
559.1027 +      os->packetno++;
559.1028 +    }
559.1029 +  }
559.1030 +  return(1);
559.1031 +}
559.1032 +
559.1033 +int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){
559.1034 +  if(ogg_stream_check(os)) return 0;
559.1035 +  return _packetout(os,op,1);
559.1036 +}
559.1037 +
559.1038 +int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){
559.1039 +  if(ogg_stream_check(os)) return 0;
559.1040 +  return _packetout(os,op,0);
559.1041 +}
559.1042 +
559.1043 +void ogg_packet_clear(ogg_packet *op) {
559.1044 +  _ogg_free(op->packet);
559.1045 +  memset(op, 0, sizeof(*op));
559.1046 +}
559.1047 +
559.1048 +#ifdef _V_SELFTEST
559.1049 +#include <stdio.h>
559.1050 +
559.1051 +ogg_stream_state os_en, os_de;
559.1052 +ogg_sync_state oy;
559.1053 +
559.1054 +void checkpacket(ogg_packet *op,long len, int no, long pos){
559.1055 +  long j;
559.1056 +  static int sequence=0;
559.1057 +  static int lastno=0;
559.1058 +
559.1059 +  if(op->bytes!=len){
559.1060 +    fprintf(stderr,"incorrect packet length (%ld != %ld)!\n",op->bytes,len);
559.1061 +    exit(1);
559.1062 +  }
559.1063 +  if(op->granulepos!=pos){
559.1064 +    fprintf(stderr,"incorrect packet granpos (%ld != %ld)!\n",(long)op->granulepos,pos);
559.1065 +    exit(1);
559.1066 +  }
559.1067 +
559.1068 +  /* packet number just follows sequence/gap; adjust the input number
559.1069 +     for that */
559.1070 +  if(no==0){
559.1071 +    sequence=0;
559.1072 +  }else{
559.1073 +    sequence++;
559.1074 +    if(no>lastno+1)
559.1075 +      sequence++;
559.1076 +  }
559.1077 +  lastno=no;
559.1078 +  if(op->packetno!=sequence){
559.1079 +    fprintf(stderr,"incorrect packet sequence %ld != %d\n",
559.1080 +            (long)(op->packetno),sequence);
559.1081 +    exit(1);
559.1082 +  }
559.1083 +
559.1084 +  /* Test data */
559.1085 +  for(j=0;j<op->bytes;j++)
559.1086 +    if(op->packet[j]!=((j+no)&0xff)){
559.1087 +      fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n",
559.1088 +              j,op->packet[j],(j+no)&0xff);
559.1089 +      exit(1);
559.1090 +    }
559.1091 +}
559.1092 +
559.1093 +void check_page(unsigned char *data,const int *header,ogg_page *og){
559.1094 +  long j;
559.1095 +  /* Test data */
559.1096 +  for(j=0;j<og->body_len;j++)
559.1097 +    if(og->body[j]!=data[j]){
559.1098 +      fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n",
559.1099 +              j,data[j],og->body[j]);
559.1100 +      exit(1);
559.1101 +    }
559.1102 +
559.1103 +  /* Test header */
559.1104 +  for(j=0;j<og->header_len;j++){
559.1105 +    if(og->header[j]!=header[j]){
559.1106 +      fprintf(stderr,"header content mismatch at pos %ld:\n",j);
559.1107 +      for(j=0;j<header[26]+27;j++)
559.1108 +        fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]);
559.1109 +      fprintf(stderr,"\n");
559.1110 +      exit(1);
559.1111 +    }
559.1112 +  }
559.1113 +  if(og->header_len!=header[26]+27){
559.1114 +    fprintf(stderr,"header length incorrect! (%ld!=%d)\n",
559.1115 +            og->header_len,header[26]+27);
559.1116 +    exit(1);
559.1117 +  }
559.1118 +}
559.1119 +
559.1120 +void print_header(ogg_page *og){
559.1121 +  int j;
559.1122 +  fprintf(stderr,"\nHEADER:\n");
559.1123 +  fprintf(stderr,"  capture: %c %c %c %c  version: %d  flags: %x\n",
559.1124 +          og->header[0],og->header[1],og->header[2],og->header[3],
559.1125 +          (int)og->header[4],(int)og->header[5]);
559.1126 +
559.1127 +  fprintf(stderr,"  granulepos: %d  serialno: %d  pageno: %ld\n",
559.1128 +          (og->header[9]<<24)|(og->header[8]<<16)|
559.1129 +          (og->header[7]<<8)|og->header[6],
559.1130 +          (og->header[17]<<24)|(og->header[16]<<16)|
559.1131 +          (og->header[15]<<8)|og->header[14],
559.1132 +          ((long)(og->header[21])<<24)|(og->header[20]<<16)|
559.1133 +          (og->header[19]<<8)|og->header[18]);
559.1134 +
559.1135 +  fprintf(stderr,"  checksum: %02x:%02x:%02x:%02x\n  segments: %d (",
559.1136 +          (int)og->header[22],(int)og->header[23],
559.1137 +          (int)og->header[24],(int)og->header[25],
559.1138 +          (int)og->header[26]);
559.1139 +
559.1140 +  for(j=27;j<og->header_len;j++)
559.1141 +    fprintf(stderr,"%d ",(int)og->header[j]);
559.1142 +  fprintf(stderr,")\n\n");
559.1143 +}
559.1144 +
559.1145 +void copy_page(ogg_page *og){
559.1146 +  unsigned char *temp=_ogg_malloc(og->header_len);
559.1147 +  memcpy(temp,og->header,og->header_len);
559.1148 +  og->header=temp;
559.1149 +
559.1150 +  temp=_ogg_malloc(og->body_len);
559.1151 +  memcpy(temp,og->body,og->body_len);
559.1152 +  og->body=temp;
559.1153 +}
559.1154 +
559.1155 +void free_page(ogg_page *og){
559.1156 +  _ogg_free (og->header);
559.1157 +  _ogg_free (og->body);
559.1158 +}
559.1159 +
559.1160 +void error(void){
559.1161 +  fprintf(stderr,"error!\n");
559.1162 +  exit(1);
559.1163 +}
559.1164 +
559.1165 +/* 17 only */
559.1166 +const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06,
559.1167 +                       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559.1168 +                       0x01,0x02,0x03,0x04,0,0,0,0,
559.1169 +                       0x15,0xed,0xec,0x91,
559.1170 +                       1,
559.1171 +                       17};
559.1172 +
559.1173 +/* 17, 254, 255, 256, 500, 510, 600 byte, pad */
559.1174 +const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02,
559.1175 +                       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559.1176 +                       0x01,0x02,0x03,0x04,0,0,0,0,
559.1177 +                       0x59,0x10,0x6c,0x2c,
559.1178 +                       1,
559.1179 +                       17};
559.1180 +const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04,
559.1181 +                       0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
559.1182 +                       0x01,0x02,0x03,0x04,1,0,0,0,
559.1183 +                       0x89,0x33,0x85,0xce,
559.1184 +                       13,
559.1185 +                       254,255,0,255,1,255,245,255,255,0,
559.1186 +                       255,255,90};
559.1187 +
559.1188 +/* nil packets; beginning,middle,end */
559.1189 +const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02,
559.1190 +                       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559.1191 +                       0x01,0x02,0x03,0x04,0,0,0,0,
559.1192 +                       0xff,0x7b,0x23,0x17,
559.1193 +                       1,
559.1194 +                       0};
559.1195 +const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04,
559.1196 +                       0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
559.1197 +                       0x01,0x02,0x03,0x04,1,0,0,0,
559.1198 +                       0x5c,0x3f,0x66,0xcb,
559.1199 +                       17,
559.1200 +                       17,254,255,0,0,255,1,0,255,245,255,255,0,
559.1201 +                       255,255,90,0};
559.1202 +
559.1203 +/* large initial packet */
559.1204 +const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02,
559.1205 +                       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559.1206 +                       0x01,0x02,0x03,0x04,0,0,0,0,
559.1207 +                       0x01,0x27,0x31,0xaa,
559.1208 +                       18,
559.1209 +                       255,255,255,255,255,255,255,255,
559.1210 +                       255,255,255,255,255,255,255,255,255,10};
559.1211 +
559.1212 +const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04,
559.1213 +                       0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
559.1214 +                       0x01,0x02,0x03,0x04,1,0,0,0,
559.1215 +                       0x7f,0x4e,0x8a,0xd2,
559.1216 +                       4,
559.1217 +                       255,4,255,0};
559.1218 +
559.1219 +
559.1220 +/* continuing packet test */
559.1221 +const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02,
559.1222 +                       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559.1223 +                       0x01,0x02,0x03,0x04,0,0,0,0,
559.1224 +                       0xff,0x7b,0x23,0x17,
559.1225 +                       1,
559.1226 +                       0};
559.1227 +
559.1228 +const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00,
559.1229 +                       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
559.1230 +                       0x01,0x02,0x03,0x04,1,0,0,0,
559.1231 +                       0xf8,0x3c,0x19,0x79,
559.1232 +                       255,
559.1233 +                       255,255,255,255,255,255,255,255,
559.1234 +                       255,255,255,255,255,255,255,255,
559.1235 +                       255,255,255,255,255,255,255,255,
559.1236 +                       255,255,255,255,255,255,255,255,
559.1237 +                       255,255,255,255,255,255,255,255,
559.1238 +                       255,255,255,255,255,255,255,255,
559.1239 +                       255,255,255,255,255,255,255,255,
559.1240 +                       255,255,255,255,255,255,255,255,
559.1241 +                       255,255,255,255,255,255,255,255,
559.1242 +                       255,255,255,255,255,255,255,255,
559.1243 +                       255,255,255,255,255,255,255,255,
559.1244 +                       255,255,255,255,255,255,255,255,
559.1245 +                       255,255,255,255,255,255,255,255,
559.1246 +                       255,255,255,255,255,255,255,255,
559.1247 +                       255,255,255,255,255,255,255,255,
559.1248 +                       255,255,255,255,255,255,255,255,
559.1249 +                       255,255,255,255,255,255,255,255,
559.1250 +                       255,255,255,255,255,255,255,255,
559.1251 +                       255,255,255,255,255,255,255,255,
559.1252 +                       255,255,255,255,255,255,255,255,
559.1253 +                       255,255,255,255,255,255,255,255,
559.1254 +                       255,255,255,255,255,255,255,255,
559.1255 +                       255,255,255,255,255,255,255,255,
559.1256 +                       255,255,255,255,255,255,255,255,
559.1257 +                       255,255,255,255,255,255,255,255,
559.1258 +                       255,255,255,255,255,255,255,255,
559.1259 +                       255,255,255,255,255,255,255,255,
559.1260 +                       255,255,255,255,255,255,255,255,
559.1261 +                       255,255,255,255,255,255,255,255,
559.1262 +                       255,255,255,255,255,255,255,255,
559.1263 +                       255,255,255,255,255,255,255,255,
559.1264 +                       255,255,255,255,255,255,255};
559.1265 +
559.1266 +const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05,
559.1267 +                       0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
559.1268 +                       0x01,0x02,0x03,0x04,2,0,0,0,
559.1269 +                       0x38,0xe6,0xb6,0x28,
559.1270 +                       6,
559.1271 +                       255,220,255,4,255,0};
559.1272 +
559.1273 +
559.1274 +/* spill expansion test */
559.1275 +const int head1_4b[] = {0x4f,0x67,0x67,0x53,0,0x02,
559.1276 +                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559.1277 +                        0x01,0x02,0x03,0x04,0,0,0,0,
559.1278 +                        0xff,0x7b,0x23,0x17,
559.1279 +                        1,
559.1280 +                        0};
559.1281 +
559.1282 +const int head2_4b[] = {0x4f,0x67,0x67,0x53,0,0x00,
559.1283 +                        0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
559.1284 +                        0x01,0x02,0x03,0x04,1,0,0,0,
559.1285 +                        0xce,0x8f,0x17,0x1a,
559.1286 +                        23,
559.1287 +                        255,255,255,255,255,255,255,255,
559.1288 +                        255,255,255,255,255,255,255,255,255,10,255,4,255,0,0};
559.1289 +
559.1290 +
559.1291 +const int head3_4b[] = {0x4f,0x67,0x67,0x53,0,0x04,
559.1292 +                        0x07,0x14,0x00,0x00,0x00,0x00,0x00,0x00,
559.1293 +                        0x01,0x02,0x03,0x04,2,0,0,0,
559.1294 +                        0x9b,0xb2,0x50,0xa1,
559.1295 +                        1,
559.1296 +                        0};
559.1297 +
559.1298 +/* page with the 255 segment limit */
559.1299 +const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02,
559.1300 +                       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559.1301 +                       0x01,0x02,0x03,0x04,0,0,0,0,
559.1302 +                       0xff,0x7b,0x23,0x17,
559.1303 +                       1,
559.1304 +                       0};
559.1305 +
559.1306 +const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00,
559.1307 +                       0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
559.1308 +                       0x01,0x02,0x03,0x04,1,0,0,0,
559.1309 +                       0xed,0x2a,0x2e,0xa7,
559.1310 +                       255,
559.1311 +                       10,10,10,10,10,10,10,10,
559.1312 +                       10,10,10,10,10,10,10,10,
559.1313 +                       10,10,10,10,10,10,10,10,
559.1314 +                       10,10,10,10,10,10,10,10,
559.1315 +                       10,10,10,10,10,10,10,10,
559.1316 +                       10,10,10,10,10,10,10,10,
559.1317 +                       10,10,10,10,10,10,10,10,
559.1318 +                       10,10,10,10,10,10,10,10,
559.1319 +                       10,10,10,10,10,10,10,10,
559.1320 +                       10,10,10,10,10,10,10,10,
559.1321 +                       10,10,10,10,10,10,10,10,
559.1322 +                       10,10,10,10,10,10,10,10,
559.1323 +                       10,10,10,10,10,10,10,10,
559.1324 +                       10,10,10,10,10,10,10,10,
559.1325 +                       10,10,10,10,10,10,10,10,
559.1326 +                       10,10,10,10,10,10,10,10,
559.1327 +                       10,10,10,10,10,10,10,10,
559.1328 +                       10,10,10,10,10,10,10,10,
559.1329 +                       10,10,10,10,10,10,10,10,
559.1330 +                       10,10,10,10,10,10,10,10,
559.1331 +                       10,10,10,10,10,10,10,10,
559.1332 +                       10,10,10,10,10,10,10,10,
559.1333 +                       10,10,10,10,10,10,10,10,
559.1334 +                       10,10,10,10,10,10,10,10,
559.1335 +                       10,10,10,10,10,10,10,10,
559.1336 +                       10,10,10,10,10,10,10,10,
559.1337 +                       10,10,10,10,10,10,10,10,
559.1338 +                       10,10,10,10,10,10,10,10,
559.1339 +                       10,10,10,10,10,10,10,10,
559.1340 +                       10,10,10,10,10,10,10,10,
559.1341 +                       10,10,10,10,10,10,10,10,
559.1342 +                       10,10,10,10,10,10,10};
559.1343 +
559.1344 +const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04,
559.1345 +                       0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
559.1346 +                       0x01,0x02,0x03,0x04,2,0,0,0,
559.1347 +                       0x6c,0x3b,0x82,0x3d,
559.1348 +                       1,
559.1349 +                       50};
559.1350 +
559.1351 +
559.1352 +/* packet that overspans over an entire page */
559.1353 +const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02,
559.1354 +                       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559.1355 +                       0x01,0x02,0x03,0x04,0,0,0,0,
559.1356 +                       0xff,0x7b,0x23,0x17,
559.1357 +                       1,
559.1358 +                       0};
559.1359 +
559.1360 +const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00,
559.1361 +                       0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
559.1362 +                       0x01,0x02,0x03,0x04,1,0,0,0,
559.1363 +                       0x68,0x22,0x7c,0x3d,
559.1364 +                       255,
559.1365 +                       100,
559.1366 +                       255,255,255,255,255,255,255,255,
559.1367 +                       255,255,255,255,255,255,255,255,
559.1368 +                       255,255,255,255,255,255,255,255,
559.1369 +                       255,255,255,255,255,255,255,255,
559.1370 +                       255,255,255,255,255,255,255,255,
559.1371 +                       255,255,255,255,255,255,255,255,
559.1372 +                       255,255,255,255,255,255,255,255,
559.1373 +                       255,255,255,255,255,255,255,255,
559.1374 +                       255,255,255,255,255,255,255,255,
559.1375 +                       255,255,255,255,255,255,255,255,
559.1376 +                       255,255,255,255,255,255,255,255,
559.1377 +                       255,255,255,255,255,255,255,255,
559.1378 +                       255,255,255,255,255,255,255,255,
559.1379 +                       255,255,255,255,255,255,255,255,
559.1380 +                       255,255,255,255,255,255,255,255,
559.1381 +                       255,255,255,255,255,255,255,255,
559.1382 +                       255,255,255,255,255,255,255,255,
559.1383 +                       255,255,255,255,255,255,255,255,
559.1384 +                       255,255,255,255,255,255,255,255,
559.1385 +                       255,255,255,255,255,255,255,255,
559.1386 +                       255,255,255,255,255,255,255,255,
559.1387 +                       255,255,255,255,255,255,255,255,
559.1388 +                       255,255,255,255,255,255,255,255,
559.1389 +                       255,255,255,255,255,255,255,255,
559.1390 +                       255,255,255,255,255,255,255,255,
559.1391 +                       255,255,255,255,255,255,255,255,
559.1392 +                       255,255,255,255,255,255,255,255,
559.1393 +                       255,255,255,255,255,255,255,255,
559.1394 +                       255,255,255,255,255,255,255,255,
559.1395 +                       255,255,255,255,255,255,255,255,
559.1396 +                       255,255,255,255,255,255,255,255,
559.1397 +                       255,255,255,255,255,255};
559.1398 +
559.1399 +const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01,
559.1400 +                       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
559.1401 +                       0x01,0x02,0x03,0x04,2,0,0,0,
559.1402 +                       0xf4,0x87,0xba,0xf3,
559.1403 +                       255,
559.1404 +                       255,255,255,255,255,255,255,255,
559.1405 +                       255,255,255,255,255,255,255,255,
559.1406 +                       255,255,255,255,255,255,255,255,
559.1407 +                       255,255,255,255,255,255,255,255,
559.1408 +                       255,255,255,255,255,255,255,255,
559.1409 +                       255,255,255,255,255,255,255,255,
559.1410 +                       255,255,255,255,255,255,255,255,
559.1411 +                       255,255,255,255,255,255,255,255,
559.1412 +                       255,255,255,255,255,255,255,255,
559.1413 +                       255,255,255,255,255,255,255,255,
559.1414 +                       255,255,255,255,255,255,255,255,
559.1415 +                       255,255,255,255,255,255,255,255,
559.1416 +                       255,255,255,255,255,255,255,255,
559.1417 +                       255,255,255,255,255,255,255,255,
559.1418 +                       255,255,255,255,255,255,255,255,
559.1419 +                       255,255,255,255,255,255,255,255,
559.1420 +                       255,255,255,255,255,255,255,255,
559.1421 +                       255,255,255,255,255,255,255,255,
559.1422 +                       255,255,255,255,255,255,255,255,
559.1423 +                       255,255,255,255,255,255,255,255,
559.1424 +                       255,255,255,255,255,255,255,255,
559.1425 +                       255,255,255,255,255,255,255,255,
559.1426 +                       255,255,255,255,255,255,255,255,
559.1427 +                       255,255,255,255,255,255,255,255,
559.1428 +                       255,255,255,255,255,255,255,255,
559.1429 +                       255,255,255,255,255,255,255,255,
559.1430 +                       255,255,255,255,255,255,255,255,
559.1431 +                       255,255,255,255,255,255,255,255,
559.1432 +                       255,255,255,255,255,255,255,255,
559.1433 +                       255,255,255,255,255,255,255,255,
559.1434 +                       255,255,255,255,255,255,255,255,
559.1435 +                       255,255,255,255,255,255,255};
559.1436 +
559.1437 +const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05,
559.1438 +                       0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
559.1439 +                       0x01,0x02,0x03,0x04,3,0,0,0,
559.1440 +                       0xf7,0x2f,0x6c,0x60,
559.1441 +                       5,
559.1442 +                       254,255,4,255,0};
559.1443 +
559.1444 +/* packet that overspans over an entire page */
559.1445 +const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02,
559.1446 +                       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559.1447 +                       0x01,0x02,0x03,0x04,0,0,0,0,
559.1448 +                       0xff,0x7b,0x23,0x17,
559.1449 +                       1,
559.1450 +                       0};
559.1451 +
559.1452 +const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00,
559.1453 +                       0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
559.1454 +                       0x01,0x02,0x03,0x04,1,0,0,0,
559.1455 +                       0x68,0x22,0x7c,0x3d,
559.1456 +                       255,
559.1457 +                       100,
559.1458 +                       255,255,255,255,255,255,255,255,
559.1459 +                       255,255,255,255,255,255,255,255,
559.1460 +                       255,255,255,255,255,255,255,255,
559.1461 +                       255,255,255,255,255,255,255,255,
559.1462 +                       255,255,255,255,255,255,255,255,
559.1463 +                       255,255,255,255,255,255,255,255,
559.1464 +                       255,255,255,255,255,255,255,255,
559.1465 +                       255,255,255,255,255,255,255,255,
559.1466 +                       255,255,255,255,255,255,255,255,
559.1467 +                       255,255,255,255,255,255,255,255,
559.1468 +                       255,255,255,255,255,255,255,255,
559.1469 +                       255,255,255,255,255,255,255,255,
559.1470 +                       255,255,255,255,255,255,255,255,
559.1471 +                       255,255,255,255,255,255,255,255,
559.1472 +                       255,255,255,255,255,255,255,255,
559.1473 +                       255,255,255,255,255,255,255,255,
559.1474 +                       255,255,255,255,255,255,255,255,
559.1475 +                       255,255,255,255,255,255,255,255,
559.1476 +                       255,255,255,255,255,255,255,255,
559.1477 +                       255,255,255,255,255,255,255,255,
559.1478 +                       255,255,255,255,255,255,255,255,
559.1479 +                       255,255,255,255,255,255,255,255,
559.1480 +                       255,255,255,255,255,255,255,255,
559.1481 +                       255,255,255,255,255,255,255,255,
559.1482 +                       255,255,255,255,255,255,255,255,
559.1483 +                       255,255,255,255,255,255,255,255,
559.1484 +                       255,255,255,255,255,255,255,255,
559.1485 +                       255,255,255,255,255,255,255,255,
559.1486 +                       255,255,255,255,255,255,255,255,
559.1487 +                       255,255,255,255,255,255,255,255,
559.1488 +                       255,255,255,255,255,255,255,255,
559.1489 +                       255,255,255,255,255,255};
559.1490 +
559.1491 +const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05,
559.1492 +                       0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
559.1493 +                       0x01,0x02,0x03,0x04,2,0,0,0,
559.1494 +                       0xd4,0xe0,0x60,0xe5,
559.1495 +                       1,
559.1496 +                       0};
559.1497 +
559.1498 +void test_pack(const int *pl, const int **headers, int byteskip,
559.1499 +               int pageskip, int packetskip){
559.1500 +  unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */
559.1501 +  long inptr=0;
559.1502 +  long outptr=0;
559.1503 +  long deptr=0;
559.1504 +  long depacket=0;
559.1505 +  long granule_pos=7,pageno=0;
559.1506 +  int i,j,packets,pageout=pageskip;
559.1507 +  int eosflag=0;
559.1508 +  int bosflag=0;
559.1509 +
559.1510 +  int byteskipcount=0;
559.1511 +
559.1512 +  ogg_stream_reset(&os_en);
559.1513 +  ogg_stream_reset(&os_de);
559.1514 +  ogg_sync_reset(&oy);
559.1515 +
559.1516 +  for(packets=0;packets<packetskip;packets++)
559.1517 +    depacket+=pl[packets];
559.1518 +
559.1519 +  for(packets=0;;packets++)if(pl[packets]==-1)break;
559.1520 +
559.1521 +  for(i=0;i<packets;i++){
559.1522 +    /* construct a test packet */
559.1523 +    ogg_packet op;
559.1524 +    int len=pl[i];
559.1525 +
559.1526 +    op.packet=data+inptr;
559.1527 +    op.bytes=len;
559.1528 +    op.e_o_s=(pl[i+1]<0?1:0);
559.1529 +    op.granulepos=granule_pos;
559.1530 +
559.1531 +    granule_pos+=1024;
559.1532 +
559.1533 +    for(j=0;j<len;j++)data[inptr++]=i+j;
559.1534 +
559.1535 +    /* submit the test packet */
559.1536 +    ogg_stream_packetin(&os_en,&op);
559.1537 +
559.1538 +    /* retrieve any finished pages */
559.1539 +    {
559.1540 +      ogg_page og;
559.1541 +
559.1542 +      while(ogg_stream_pageout(&os_en,&og)){
559.1543 +        /* We have a page.  Check it carefully */
559.1544 +
559.1545 +        fprintf(stderr,"%ld, ",pageno);
559.1546 +
559.1547 +        if(headers[pageno]==NULL){
559.1548 +          fprintf(stderr,"coded too many pages!\n");
559.1549 +          exit(1);
559.1550 +        }
559.1551 +
559.1552 +        check_page(data+outptr,headers[pageno],&og);
559.1553 +
559.1554 +        outptr+=og.body_len;
559.1555 +        pageno++;
559.1556 +        if(pageskip){
559.1557 +          bosflag=1;
559.1558 +          pageskip--;
559.1559 +          deptr+=og.body_len;
559.1560 +        }
559.1561 +
559.1562 +        /* have a complete page; submit it to sync/decode */
559.1563 +
559.1564 +        {
559.1565 +          ogg_page og_de;
559.1566 +          ogg_packet op_de,op_de2;
559.1567 +          char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
559.1568 +          char *next=buf;
559.1569 +          byteskipcount+=og.header_len;
559.1570 +          if(byteskipcount>byteskip){
559.1571 +            memcpy(next,og.header,byteskipcount-byteskip);
559.1572 +            next+=byteskipcount-byteskip;
559.1573 +            byteskipcount=byteskip;
559.1574 +          }
559.1575 +
559.1576 +          byteskipcount+=og.body_len;
559.1577 +          if(byteskipcount>byteskip){
559.1578 +            memcpy(next,og.body,byteskipcount-byteskip);
559.1579 +            next+=byteskipcount-byteskip;
559.1580 +            byteskipcount=byteskip;
559.1581 +          }
559.1582 +
559.1583 +          ogg_sync_wrote(&oy,next-buf);
559.1584 +
559.1585 +          while(1){
559.1586 +            int ret=ogg_sync_pageout(&oy,&og_de);
559.1587 +            if(ret==0)break;
559.1588 +            if(ret<0)continue;
559.1589 +            /* got a page.  Happy happy.  Verify that it's good. */
559.1590 +
559.1591 +            fprintf(stderr,"(%d), ",pageout);
559.1592 +
559.1593 +            check_page(data+deptr,headers[pageout],&og_de);
559.1594 +            deptr+=og_de.body_len;
559.1595 +            pageout++;
559.1596 +
559.1597 +            /* submit it to deconstitution */
559.1598 +            ogg_stream_pagein(&os_de,&og_de);
559.1599 +
559.1600 +            /* packets out? */
559.1601 +            while(ogg_stream_packetpeek(&os_de,&op_de2)>0){
559.1602 +              ogg_stream_packetpeek(&os_de,NULL);
559.1603 +              ogg_stream_packetout(&os_de,&op_de); /* just catching them all */
559.1604 +
559.1605 +              /* verify peek and out match */
559.1606 +              if(memcmp(&op_de,&op_de2,sizeof(op_de))){
559.1607 +                fprintf(stderr,"packetout != packetpeek! pos=%ld\n",
559.1608 +                        depacket);
559.1609 +                exit(1);
559.1610 +              }
559.1611 +
559.1612 +              /* verify the packet! */
559.1613 +              /* check data */
559.1614 +              if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
559.1615 +                fprintf(stderr,"packet data mismatch in decode! pos=%ld\n",
559.1616 +                        depacket);
559.1617 +                exit(1);
559.1618 +              }
559.1619 +              /* check bos flag */
559.1620 +              if(bosflag==0 && op_de.b_o_s==0){
559.1621 +                fprintf(stderr,"b_o_s flag not set on packet!\n");
559.1622 +                exit(1);
559.1623 +              }
559.1624 +              if(bosflag && op_de.b_o_s){
559.1625 +                fprintf(stderr,"b_o_s flag incorrectly set on packet!\n");
559.1626 +                exit(1);
559.1627 +              }
559.1628 +              bosflag=1;
559.1629 +              depacket+=op_de.bytes;
559.1630 +
559.1631 +              /* check eos flag */
559.1632 +              if(eosflag){
559.1633 +                fprintf(stderr,"Multiple decoded packets with eos flag!\n");
559.1634 +                exit(1);
559.1635 +              }
559.1636 +
559.1637 +              if(op_de.e_o_s)eosflag=1;
559.1638 +
559.1639 +              /* check granulepos flag */
559.1640 +              if(op_de.granulepos!=-1){
559.1641 +                fprintf(stderr," granule:%ld ",(long)op_de.granulepos);
559.1642 +              }
559.1643 +            }
559.1644 +          }
559.1645 +        }
559.1646 +      }
559.1647 +    }
559.1648 +  }
559.1649 +  _ogg_free(data);
559.1650 +  if(headers[pageno]!=NULL){
559.1651 +    fprintf(stderr,"did not write last page!\n");
559.1652 +    exit(1);
559.1653 +  }
559.1654 +  if(headers[pageout]!=NULL){
559.1655 +    fprintf(stderr,"did not decode last page!\n");
559.1656 +    exit(1);
559.1657 +  }
559.1658 +  if(inptr!=outptr){
559.1659 +    fprintf(stderr,"encoded page data incomplete!\n");
559.1660 +    exit(1);
559.1661 +  }
559.1662 +  if(inptr!=deptr){
559.1663 +    fprintf(stderr,"decoded page data incomplete!\n");
559.1664 +    exit(1);
559.1665 +  }
559.1666 +  if(inptr!=depacket){
559.1667 +    fprintf(stderr,"decoded packet data incomplete!\n");
559.1668 +    exit(1);
559.1669 +  }
559.1670 +  if(!eosflag){
559.1671 +    fprintf(stderr,"Never got a packet with EOS set!\n");
559.1672 +    exit(1);
559.1673 +  }
559.1674 +  fprintf(stderr,"ok.\n");
559.1675 +}
559.1676 +
559.1677 +int main(void){
559.1678 +
559.1679 +  ogg_stream_init(&os_en,0x04030201);
559.1680 +  ogg_stream_init(&os_de,0x04030201);
559.1681 +  ogg_sync_init(&oy);
559.1682 +
559.1683 +  /* Exercise each code path in the framing code.  Also verify that
559.1684 +     the checksums are working.  */
559.1685 +
559.1686 +  {
559.1687 +    /* 17 only */
559.1688 +    const int packets[]={17, -1};
559.1689 +    const int *headret[]={head1_0,NULL};
559.1690 +
559.1691 +    fprintf(stderr,"testing single page encoding... ");
559.1692 +    test_pack(packets,headret,0,0,0);
559.1693 +  }
559.1694 +
559.1695 +  {
559.1696 +    /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
559.1697 +    const int packets[]={17, 254, 255, 256, 500, 510, 600, -1};
559.1698 +    const int *headret[]={head1_1,head2_1,NULL};
559.1699 +
559.1700 +    fprintf(stderr,"testing basic page encoding... ");
559.1701 +    test_pack(packets,headret,0,0,0);
559.1702 +  }
559.1703 +
559.1704 +  {
559.1705 +    /* nil packets; beginning,middle,end */
559.1706 +    const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
559.1707 +    const int *headret[]={head1_2,head2_2,NULL};
559.1708 +
559.1709 +    fprintf(stderr,"testing basic nil packets... ");
559.1710 +    test_pack(packets,headret,0,0,0);
559.1711 +  }
559.1712 +
559.1713 +  {
559.1714 +    /* large initial packet */
559.1715 +    const int packets[]={4345,259,255,-1};
559.1716 +    const int *headret[]={head1_3,head2_3,NULL};
559.1717 +
559.1718 +    fprintf(stderr,"testing initial-packet lacing > 4k... ");
559.1719 +    test_pack(packets,headret,0,0,0);
559.1720 +  }
559.1721 +
559.1722 +  {
559.1723 +    /* continuing packet test; with page spill expansion, we have to
559.1724 +       overflow the lacing table. */
559.1725 +    const int packets[]={0,65500,259,255,-1};
559.1726 +    const int *headret[]={head1_4,head2_4,head3_4,NULL};
559.1727 +
559.1728 +    fprintf(stderr,"testing single packet page span... ");
559.1729 +    test_pack(packets,headret,0,0,0);
559.1730 +  }
559.1731 +
559.1732 +  {
559.1733 +    /* spill expand packet test */
559.1734 +    const int packets[]={0,4345,259,255,0,0,-1};
559.1735 +    const int *headret[]={head1_4b,head2_4b,head3_4b,NULL};
559.1736 +
559.1737 +    fprintf(stderr,"testing page spill expansion... ");
559.1738 +    test_pack(packets,headret,0,0,0);
559.1739 +  }
559.1740 +
559.1741 +  /* page with the 255 segment limit */
559.1742 +  {
559.1743 +
559.1744 +    const int packets[]={0,10,10,10,10,10,10,10,10,
559.1745 +                   10,10,10,10,10,10,10,10,
559.1746 +                   10,10,10,10,10,10,10,10,
559.1747 +                   10,10,10,10,10,10,10,10,
559.1748 +                   10,10,10,10,10,10,10,10,
559.1749 +                   10,10,10,10,10,10,10,10,
559.1750 +                   10,10,10,10,10,10,10,10,
559.1751 +                   10,10,10,10,10,10,10,10,
559.1752 +                   10,10,10,10,10,10,10,10,
559.1753 +                   10,10,10,10,10,10,10,10,
559.1754 +                   10,10,10,10,10,10,10,10,
559.1755 +                   10,10,10,10,10,10,10,10,
559.1756 +                   10,10,10,10,10,10,10,10,
559.1757 +                   10,10,10,10,10,10,10,10,
559.1758 +                   10,10,10,10,10,10,10,10,
559.1759 +                   10,10,10,10,10,10,10,10,
559.1760 +                   10,10,10,10,10,10,10,10,
559.1761 +                   10,10,10,10,10,10,10,10,
559.1762 +                   10,10,10,10,10,10,10,10,
559.1763 +                   10,10,10,10,10,10,10,10,
559.1764 +                   10,10,10,10,10,10,10,10,
559.1765 +                   10,10,10,10,10,10,10,10,
559.1766 +                   10,10,10,10,10,10,10,10,
559.1767 +                   10,10,10,10,10,10,10,10,
559.1768 +                   10,10,10,10,10,10,10,10,
559.1769 +                   10,10,10,10,10,10,10,10,
559.1770 +                   10,10,10,10,10,10,10,10,
559.1771 +                   10,10,10,10,10,10,10,10,
559.1772 +                   10,10,10,10,10,10,10,10,
559.1773 +                   10,10,10,10,10,10,10,10,
559.1774 +                   10,10,10,10,10,10,10,10,
559.1775 +                   10,10,10,10,10,10,10,50,-1};
559.1776 +    const int *headret[]={head1_5,head2_5,head3_5,NULL};
559.1777 +
559.1778 +    fprintf(stderr,"testing max packet segments... ");
559.1779 +    test_pack(packets,headret,0,0,0);
559.1780 +  }
559.1781 +
559.1782 +  {
559.1783 +    /* packet that overspans over an entire page */
559.1784 +    const int packets[]={0,100,130049,259,255,-1};
559.1785 +    const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
559.1786 +
559.1787 +    fprintf(stderr,"testing very large packets... ");
559.1788 +    test_pack(packets,headret,0,0,0);
559.1789 +  }
559.1790 +
559.1791 +  {
559.1792 +    /* test for the libogg 1.1.1 resync in large continuation bug
559.1793 +       found by Josh Coalson)  */
559.1794 +    const int packets[]={0,100,130049,259,255,-1};
559.1795 +    const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
559.1796 +
559.1797 +    fprintf(stderr,"testing continuation resync in very large packets... ");
559.1798 +    test_pack(packets,headret,100,2,3);
559.1799 +  }
559.1800 +
559.1801 +  {
559.1802 +    /* term only page.  why not? */
559.1803 +    const int packets[]={0,100,64770,-1};
559.1804 +    const int *headret[]={head1_7,head2_7,head3_7,NULL};
559.1805 +
559.1806 +    fprintf(stderr,"testing zero data page (1 nil packet)... ");
559.1807 +    test_pack(packets,headret,0,0,0);
559.1808 +  }
559.1809 +
559.1810 +
559.1811 +
559.1812 +  {
559.1813 +    /* build a bunch of pages for testing */
559.1814 +    unsigned char *data=_ogg_malloc(1024*1024);
559.1815 +    int pl[]={0, 1,1,98,4079, 1,1,2954,2057, 76,34,912,0,234,1000,1000, 1000,300,-1};
559.1816 +    int inptr=0,i,j;
559.1817 +    ogg_page og[5];
559.1818 +
559.1819 +    ogg_stream_reset(&os_en);
559.1820 +
559.1821 +    for(i=0;pl[i]!=-1;i++){
559.1822 +      ogg_packet op;
559.1823 +      int len=pl[i];
559.1824 +
559.1825 +      op.packet=data+inptr;
559.1826 +      op.bytes=len;
559.1827 +      op.e_o_s=(pl[i+1]<0?1:0);
559.1828 +      op.granulepos=(i+1)*1000;
559.1829 +
559.1830 +      for(j=0;j<len;j++)data[inptr++]=i+j;
559.1831 +      ogg_stream_packetin(&os_en,&op);
559.1832 +    }
559.1833 +
559.1834 +    _ogg_free(data);
559.1835 +
559.1836 +    /* retrieve finished pages */
559.1837 +    for(i=0;i<5;i++){
559.1838 +      if(ogg_stream_pageout(&os_en,&og[i])==0){
559.1839 +        fprintf(stderr,"Too few pages output building sync tests!\n");
559.1840 +        exit(1);
559.1841 +      }
559.1842 +      copy_page(&og[i]);
559.1843 +    }
559.1844 +
559.1845 +    /* Test lost pages on pagein/packetout: no rollback */
559.1846 +    {
559.1847 +      ogg_page temp;
559.1848 +      ogg_packet test;
559.1849 +
559.1850 +      fprintf(stderr,"Testing loss of pages... ");
559.1851 +
559.1852 +      ogg_sync_reset(&oy);
559.1853 +      ogg_stream_reset(&os_de);
559.1854 +      for(i=0;i<5;i++){
559.1855 +        memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
559.1856 +               og[i].header_len);
559.1857 +        ogg_sync_wrote(&oy,og[i].header_len);
559.1858 +        memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
559.1859 +        ogg_sync_wrote(&oy,og[i].body_len);
559.1860 +      }
559.1861 +
559.1862 +      ogg_sync_pageout(&oy,&temp);
559.1863 +      ogg_stream_pagein(&os_de,&temp);
559.1864 +      ogg_sync_pageout(&oy,&temp);
559.1865 +      ogg_stream_pagein(&os_de,&temp);
559.1866 +      ogg_sync_pageout(&oy,&temp);
559.1867 +      /* skip */
559.1868 +      ogg_sync_pageout(&oy,&temp);
559.1869 +      ogg_stream_pagein(&os_de,&temp);
559.1870 +
559.1871 +      /* do we get the expected results/packets? */
559.1872 +
559.1873 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1874 +      checkpacket(&test,0,0,0);
559.1875 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1876 +      checkpacket(&test,1,1,-1);
559.1877 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1878 +      checkpacket(&test,1,2,-1);
559.1879 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1880 +      checkpacket(&test,98,3,-1);
559.1881 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1882 +      checkpacket(&test,4079,4,5000);
559.1883 +      if(ogg_stream_packetout(&os_de,&test)!=-1){
559.1884 +        fprintf(stderr,"Error: loss of page did not return error\n");
559.1885 +        exit(1);
559.1886 +      }
559.1887 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1888 +      checkpacket(&test,76,9,-1);
559.1889 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1890 +      checkpacket(&test,34,10,-1);
559.1891 +      fprintf(stderr,"ok.\n");
559.1892 +    }
559.1893 +
559.1894 +    /* Test lost pages on pagein/packetout: rollback with continuation */
559.1895 +    {
559.1896 +      ogg_page temp;
559.1897 +      ogg_packet test;
559.1898 +
559.1899 +      fprintf(stderr,"Testing loss of pages (rollback required)... ");
559.1900 +
559.1901 +      ogg_sync_reset(&oy);
559.1902 +      ogg_stream_reset(&os_de);
559.1903 +      for(i=0;i<5;i++){
559.1904 +        memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
559.1905 +               og[i].header_len);
559.1906 +        ogg_sync_wrote(&oy,og[i].header_len);
559.1907 +        memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
559.1908 +        ogg_sync_wrote(&oy,og[i].body_len);
559.1909 +      }
559.1910 +
559.1911 +      ogg_sync_pageout(&oy,&temp);
559.1912 +      ogg_stream_pagein(&os_de,&temp);
559.1913 +      ogg_sync_pageout(&oy,&temp);
559.1914 +      ogg_stream_pagein(&os_de,&temp);
559.1915 +      ogg_sync_pageout(&oy,&temp);
559.1916 +      ogg_stream_pagein(&os_de,&temp);
559.1917 +      ogg_sync_pageout(&oy,&temp);
559.1918 +      /* skip */
559.1919 +      ogg_sync_pageout(&oy,&temp);
559.1920 +      ogg_stream_pagein(&os_de,&temp);
559.1921 +
559.1922 +      /* do we get the expected results/packets? */
559.1923 +
559.1924 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1925 +      checkpacket(&test,0,0,0);
559.1926 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1927 +      checkpacket(&test,1,1,-1);
559.1928 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1929 +      checkpacket(&test,1,2,-1);
559.1930 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1931 +      checkpacket(&test,98,3,-1);
559.1932 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1933 +      checkpacket(&test,4079,4,5000);
559.1934 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1935 +      checkpacket(&test,1,5,-1);
559.1936 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1937 +      checkpacket(&test,1,6,-1);
559.1938 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1939 +      checkpacket(&test,2954,7,-1);
559.1940 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1941 +      checkpacket(&test,2057,8,9000);
559.1942 +      if(ogg_stream_packetout(&os_de,&test)!=-1){
559.1943 +        fprintf(stderr,"Error: loss of page did not return error\n");
559.1944 +        exit(1);
559.1945 +      }
559.1946 +      if(ogg_stream_packetout(&os_de,&test)!=1)error();
559.1947 +      checkpacket(&test,300,17,18000);
559.1948 +      fprintf(stderr,"ok.\n");
559.1949 +    }
559.1950 +
559.1951 +    /* the rest only test sync */
559.1952 +    {
559.1953 +      ogg_page og_de;
559.1954 +      /* Test fractional page inputs: incomplete capture */
559.1955 +      fprintf(stderr,"Testing sync on partial inputs... ");
559.1956 +      ogg_sync_reset(&oy);
559.1957 +      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
559.1958 +             3);
559.1959 +      ogg_sync_wrote(&oy,3);
559.1960 +      if(ogg_sync_pageout(&oy,&og_de)>0)error();
559.1961 +
559.1962 +      /* Test fractional page inputs: incomplete fixed header */
559.1963 +      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3,
559.1964 +             20);
559.1965 +      ogg_sync_wrote(&oy,20);
559.1966 +      if(ogg_sync_pageout(&oy,&og_de)>0)error();
559.1967 +
559.1968 +      /* Test fractional page inputs: incomplete header */
559.1969 +      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23,
559.1970 +             5);
559.1971 +      ogg_sync_wrote(&oy,5);
559.1972 +      if(ogg_sync_pageout(&oy,&og_de)>0)error();
559.1973 +
559.1974 +      /* Test fractional page inputs: incomplete body */
559.1975 +
559.1976 +      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28,
559.1977 +             og[1].header_len-28);
559.1978 +      ogg_sync_wrote(&oy,og[1].header_len-28);
559.1979 +      if(ogg_sync_pageout(&oy,&og_de)>0)error();
559.1980 +
559.1981 +      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000);
559.1982 +      ogg_sync_wrote(&oy,1000);
559.1983 +      if(ogg_sync_pageout(&oy,&og_de)>0)error();
559.1984 +
559.1985 +      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000,
559.1986 +             og[1].body_len-1000);
559.1987 +      ogg_sync_wrote(&oy,og[1].body_len-1000);
559.1988 +      if(ogg_sync_pageout(&oy,&og_de)<=0)error();
559.1989 +
559.1990 +      fprintf(stderr,"ok.\n");
559.1991 +    }
559.1992 +
559.1993 +    /* Test fractional page inputs: page + incomplete capture */
559.1994 +    {
559.1995 +      ogg_page og_de;
559.1996 +      fprintf(stderr,"Testing sync on 1+partial inputs... ");
559.1997 +      ogg_sync_reset(&oy);
559.1998 +
559.1999 +      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
559.2000 +             og[1].header_len);
559.2001 +      ogg_sync_wrote(&oy,og[1].header_len);
559.2002 +
559.2003 +      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
559.2004 +             og[1].body_len);
559.2005 +      ogg_sync_wrote(&oy,og[1].body_len);
559.2006 +
559.2007 +      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
559.2008 +             20);
559.2009 +      ogg_sync_wrote(&oy,20);
559.2010 +      if(ogg_sync_pageout(&oy,&og_de)<=0)error();
559.2011 +      if(ogg_sync_pageout(&oy,&og_de)>0)error();
559.2012 +
559.2013 +      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20,
559.2014 +             og[1].header_len-20);
559.2015 +      ogg_sync_wrote(&oy,og[1].header_len-20);
559.2016 +      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
559.2017 +             og[1].body_len);
559.2018 +      ogg_sync_wrote(&oy,og[1].body_len);
559.2019 +      if(ogg_sync_pageout(&oy,&og_de)<=0)error();
559.2020 +
559.2021 +      fprintf(stderr,"ok.\n");
559.2022 +    }
559.2023 +
559.2024 +    /* Test recapture: garbage + page */
559.2025 +    {
559.2026 +      ogg_page og_de;
559.2027 +      fprintf(stderr,"Testing search for capture... ");
559.2028 +      ogg_sync_reset(&oy);
559.2029 +
559.2030 +      /* 'garbage' */
559.2031 +      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
559.2032 +             og[1].body_len);
559.2033 +      ogg_sync_wrote(&oy,og[1].body_len);
559.2034 +
559.2035 +      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
559.2036 +             og[1].header_len);
559.2037 +      ogg_sync_wrote(&oy,og[1].header_len);
559.2038 +
559.2039 +      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
559.2040 +             og[1].body_len);
559.2041 +      ogg_sync_wrote(&oy,og[1].body_len);
559.2042 +
559.2043 +      memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
559.2044 +             20);
559.2045 +      ogg_sync_wrote(&oy,20);
559.2046 +      if(ogg_sync_pageout(&oy,&og_de)>0)error();
559.2047 +      if(ogg_sync_pageout(&oy,&og_de)<=0)error();
559.2048 +      if(ogg_sync_pageout(&oy,&og_de)>0)error();
559.2049 +
559.2050 +      memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20,
559.2051 +             og[2].header_len-20);
559.2052 +      ogg_sync_wrote(&oy,og[2].header_len-20);
559.2053 +      memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
559.2054 +             og[2].body_len);
559.2055 +      ogg_sync_wrote(&oy,og[2].body_len);
559.2056 +      if(ogg_sync_pageout(&oy,&og_de)<=0)error();
559.2057 +
559.2058 +      fprintf(stderr,"ok.\n");
559.2059 +    }
559.2060 +
559.2061 +    /* Test recapture: page + garbage + page */
559.2062 +    {
559.2063 +      ogg_page og_de;
559.2064 +      fprintf(stderr,"Testing recapture... ");
559.2065 +      ogg_sync_reset(&oy);
559.2066 +
559.2067 +      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
559.2068 +             og[1].header_len);
559.2069 +      ogg_sync_wrote(&oy,og[1].header_len);
559.2070 +
559.2071 +      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
559.2072 +             og[1].body_len);
559.2073 +      ogg_sync_wrote(&oy,og[1].body_len);
559.2074 +
559.2075 +      memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
559.2076 +             og[2].header_len);
559.2077 +      ogg_sync_wrote(&oy,og[2].header_len);
559.2078 +
559.2079 +      memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
559.2080 +             og[2].header_len);
559.2081 +      ogg_sync_wrote(&oy,og[2].header_len);
559.2082 +
559.2083 +      if(ogg_sync_pageout(&oy,&og_de)<=0)error();
559.2084 +
559.2085 +      memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
559.2086 +             og[2].body_len-5);
559.2087 +      ogg_sync_wrote(&oy,og[2].body_len-5);
559.2088 +
559.2089 +      memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header,
559.2090 +             og[3].header_len);
559.2091 +      ogg_sync_wrote(&oy,og[3].header_len);
559.2092 +
559.2093 +      memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body,
559.2094 +             og[3].body_len);
559.2095 +      ogg_sync_wrote(&oy,og[3].body_len);
559.2096 +
559.2097 +      if(ogg_sync_pageout(&oy,&og_de)>0)error();
559.2098 +      if(ogg_sync_pageout(&oy,&og_de)<=0)error();
559.2099 +
559.2100 +      fprintf(stderr,"ok.\n");
559.2101 +    }
559.2102 +
559.2103 +    /* Free page data that was previously copied */
559.2104 +    {
559.2105 +      for(i=0;i<5;i++){
559.2106 +        free_page(&og[i]);
559.2107 +      }
559.2108 +    }
559.2109 +  }
559.2110 +
559.2111 +  return(0);
559.2112 +}
559.2113 +
559.2114 +#endif
   560.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   560.2 +++ b/libs/ogg/ogg.h	Sat Feb 01 19:58:19 2014 +0200
   560.3 @@ -0,0 +1,210 @@
   560.4 +/********************************************************************
   560.5 + *                                                                  *
   560.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   560.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   560.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   560.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  560.10 + *                                                                  *
  560.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  560.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  560.13 + *                                                                  *
  560.14 + ********************************************************************
  560.15 +
  560.16 + function: toplevel libogg include
  560.17 + last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $
  560.18 +
  560.19 + ********************************************************************/
  560.20 +#ifndef _OGG_H
  560.21 +#define _OGG_H
  560.22 +
  560.23 +#ifdef __cplusplus
  560.24 +extern "C" {
  560.25 +#endif
  560.26 +
  560.27 +#include <stddef.h>
  560.28 +#include <ogg/os_types.h>
  560.29 +
  560.30 +typedef struct {
  560.31 +  void *iov_base;
  560.32 +  size_t iov_len;
  560.33 +} ogg_iovec_t;
  560.34 +
  560.35 +typedef struct {
  560.36 +  long endbyte;
  560.37 +  int  endbit;
  560.38 +
  560.39 +  unsigned char *buffer;
  560.40 +  unsigned char *ptr;
  560.41 +  long storage;
  560.42 +} oggpack_buffer;
  560.43 +
  560.44 +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
  560.45 +
  560.46 +typedef struct {
  560.47 +  unsigned char *header;
  560.48 +  long header_len;
  560.49 +  unsigned char *body;
  560.50 +  long body_len;
  560.51 +} ogg_page;
  560.52 +
  560.53 +/* ogg_stream_state contains the current encode/decode state of a logical
  560.54 +   Ogg bitstream **********************************************************/
  560.55 +
  560.56 +typedef struct {
  560.57 +  unsigned char   *body_data;    /* bytes from packet bodies */
  560.58 +  long    body_storage;          /* storage elements allocated */
  560.59 +  long    body_fill;             /* elements stored; fill mark */
  560.60 +  long    body_returned;         /* elements of fill returned */
  560.61 +
  560.62 +
  560.63 +  int     *lacing_vals;      /* The values that will go to the segment table */
  560.64 +  ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
  560.65 +                                this way, but it is simple coupled to the
  560.66 +                                lacing fifo */
  560.67 +  long    lacing_storage;
  560.68 +  long    lacing_fill;
  560.69 +  long    lacing_packet;
  560.70 +  long    lacing_returned;
  560.71 +
  560.72 +  unsigned char    header[282];      /* working space for header encode */
  560.73 +  int              header_fill;
  560.74 +
  560.75 +  int     e_o_s;          /* set when we have buffered the last packet in the
  560.76 +                             logical bitstream */
  560.77 +  int     b_o_s;          /* set after we've written the initial page
  560.78 +                             of a logical bitstream */
  560.79 +  long    serialno;
  560.80 +  long    pageno;
  560.81 +  ogg_int64_t  packetno;  /* sequence number for decode; the framing
  560.82 +                             knows where there's a hole in the data,
  560.83 +                             but we need coupling so that the codec
  560.84 +                             (which is in a separate abstraction
  560.85 +                             layer) also knows about the gap */
  560.86 +  ogg_int64_t   granulepos;
  560.87 +
  560.88 +} ogg_stream_state;
  560.89 +
  560.90 +/* ogg_packet is used to encapsulate the data and metadata belonging
  560.91 +   to a single raw Ogg/Vorbis packet *************************************/
  560.92 +
  560.93 +typedef struct {
  560.94 +  unsigned char *packet;
  560.95 +  long  bytes;
  560.96 +  long  b_o_s;
  560.97 +  long  e_o_s;
  560.98 +
  560.99 +  ogg_int64_t  granulepos;
 560.100 +
 560.101 +  ogg_int64_t  packetno;     /* sequence number for decode; the framing
 560.102 +                                knows where there's a hole in the data,
 560.103 +                                but we need coupling so that the codec
 560.104 +                                (which is in a separate abstraction
 560.105 +                                layer) also knows about the gap */
 560.106 +} ogg_packet;
 560.107 +
 560.108 +typedef struct {
 560.109 +  unsigned char *data;
 560.110 +  int storage;
 560.111 +  int fill;
 560.112 +  int returned;
 560.113 +
 560.114 +  int unsynced;
 560.115 +  int headerbytes;
 560.116 +  int bodybytes;
 560.117 +} ogg_sync_state;
 560.118 +
 560.119 +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
 560.120 +
 560.121 +extern void  oggpack_writeinit(oggpack_buffer *b);
 560.122 +extern int   oggpack_writecheck(oggpack_buffer *b);
 560.123 +extern void  oggpack_writetrunc(oggpack_buffer *b,long bits);
 560.124 +extern void  oggpack_writealign(oggpack_buffer *b);
 560.125 +extern void  oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
 560.126 +extern void  oggpack_reset(oggpack_buffer *b);
 560.127 +extern void  oggpack_writeclear(oggpack_buffer *b);
 560.128 +extern void  oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
 560.129 +extern void  oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
 560.130 +extern long  oggpack_look(oggpack_buffer *b,int bits);
 560.131 +extern long  oggpack_look1(oggpack_buffer *b);
 560.132 +extern void  oggpack_adv(oggpack_buffer *b,int bits);
 560.133 +extern void  oggpack_adv1(oggpack_buffer *b);
 560.134 +extern long  oggpack_read(oggpack_buffer *b,int bits);
 560.135 +extern long  oggpack_read1(oggpack_buffer *b);
 560.136 +extern long  oggpack_bytes(oggpack_buffer *b);
 560.137 +extern long  oggpack_bits(oggpack_buffer *b);
 560.138 +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
 560.139 +
 560.140 +extern void  oggpackB_writeinit(oggpack_buffer *b);
 560.141 +extern int   oggpackB_writecheck(oggpack_buffer *b);
 560.142 +extern void  oggpackB_writetrunc(oggpack_buffer *b,long bits);
 560.143 +extern void  oggpackB_writealign(oggpack_buffer *b);
 560.144 +extern void  oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
 560.145 +extern void  oggpackB_reset(oggpack_buffer *b);
 560.146 +extern void  oggpackB_writeclear(oggpack_buffer *b);
 560.147 +extern void  oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
 560.148 +extern void  oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
 560.149 +extern long  oggpackB_look(oggpack_buffer *b,int bits);
 560.150 +extern long  oggpackB_look1(oggpack_buffer *b);
 560.151 +extern void  oggpackB_adv(oggpack_buffer *b,int bits);
 560.152 +extern void  oggpackB_adv1(oggpack_buffer *b);
 560.153 +extern long  oggpackB_read(oggpack_buffer *b,int bits);
 560.154 +extern long  oggpackB_read1(oggpack_buffer *b);
 560.155 +extern long  oggpackB_bytes(oggpack_buffer *b);
 560.156 +extern long  oggpackB_bits(oggpack_buffer *b);
 560.157 +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
 560.158 +
 560.159 +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
 560.160 +
 560.161 +extern int      ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
 560.162 +extern int      ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
 560.163 +                                   int count, long e_o_s, ogg_int64_t granulepos);
 560.164 +extern int      ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
 560.165 +extern int      ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill);
 560.166 +extern int      ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
 560.167 +extern int      ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill);
 560.168 +
 560.169 +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
 560.170 +
 560.171 +extern int      ogg_sync_init(ogg_sync_state *oy);
 560.172 +extern int      ogg_sync_clear(ogg_sync_state *oy);
 560.173 +extern int      ogg_sync_reset(ogg_sync_state *oy);
 560.174 +extern int      ogg_sync_destroy(ogg_sync_state *oy);
 560.175 +extern int      ogg_sync_check(ogg_sync_state *oy);
 560.176 +
 560.177 +extern char    *ogg_sync_buffer(ogg_sync_state *oy, long size);
 560.178 +extern int      ogg_sync_wrote(ogg_sync_state *oy, long bytes);
 560.179 +extern long     ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
 560.180 +extern int      ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
 560.181 +extern int      ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
 560.182 +extern int      ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
 560.183 +extern int      ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);
 560.184 +
 560.185 +/* Ogg BITSTREAM PRIMITIVES: general ***************************/
 560.186 +
 560.187 +extern int      ogg_stream_init(ogg_stream_state *os,int serialno);
 560.188 +extern int      ogg_stream_clear(ogg_stream_state *os);
 560.189 +extern int      ogg_stream_reset(ogg_stream_state *os);
 560.190 +extern int      ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
 560.191 +extern int      ogg_stream_destroy(ogg_stream_state *os);
 560.192 +extern int      ogg_stream_check(ogg_stream_state *os);
 560.193 +extern int      ogg_stream_eos(ogg_stream_state *os);
 560.194 +
 560.195 +extern void     ogg_page_checksum_set(ogg_page *og);
 560.196 +
 560.197 +extern int      ogg_page_version(const ogg_page *og);
 560.198 +extern int      ogg_page_continued(const ogg_page *og);
 560.199 +extern int      ogg_page_bos(const ogg_page *og);
 560.200 +extern int      ogg_page_eos(const ogg_page *og);
 560.201 +extern ogg_int64_t  ogg_page_granulepos(const ogg_page *og);
 560.202 +extern int      ogg_page_serialno(const ogg_page *og);
 560.203 +extern long     ogg_page_pageno(const ogg_page *og);
 560.204 +extern int      ogg_page_packets(const ogg_page *og);
 560.205 +
 560.206 +extern void     ogg_packet_clear(ogg_packet *op);
 560.207 +
 560.208 +
 560.209 +#ifdef __cplusplus
 560.210 +}
 560.211 +#endif
 560.212 +
 560.213 +#endif  /* _OGG_H */
   561.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   561.2 +++ b/libs/ogg/os_types.h	Sat Feb 01 19:58:19 2014 +0200
   561.3 @@ -0,0 +1,147 @@
   561.4 +/********************************************************************
   561.5 + *                                                                  *
   561.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   561.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   561.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   561.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  561.10 + *                                                                  *
  561.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
  561.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  561.13 + *                                                                  *
  561.14 + ********************************************************************
  561.15 +
  561.16 + function: #ifdef jail to whip a few platforms into the UNIX ideal.
  561.17 + last mod: $Id: os_types.h 17712 2010-12-03 17:10:02Z xiphmont $
  561.18 +
  561.19 + ********************************************************************/
  561.20 +#ifndef _OS_TYPES_H
  561.21 +#define _OS_TYPES_H
  561.22 +
  561.23 +/* make it easy on the folks that want to compile the libs with a
  561.24 +   different malloc than stdlib */
  561.25 +#define _ogg_malloc  malloc
  561.26 +#define _ogg_calloc  calloc
  561.27 +#define _ogg_realloc realloc
  561.28 +#define _ogg_free    free
  561.29 +
  561.30 +#if defined(_WIN32) 
  561.31 +
  561.32 +#  if defined(__CYGWIN__)
  561.33 +#    include <stdint.h>
  561.34 +     typedef int16_t ogg_int16_t;
  561.35 +     typedef uint16_t ogg_uint16_t;
  561.36 +     typedef int32_t ogg_int32_t;
  561.37 +     typedef uint32_t ogg_uint32_t;
  561.38 +     typedef int64_t ogg_int64_t;
  561.39 +     typedef uint64_t ogg_uint64_t;
  561.40 +#  elif defined(__MINGW32__)
  561.41 +#    include <sys/types.h>
  561.42 +     typedef short ogg_int16_t;
  561.43 +     typedef unsigned short ogg_uint16_t;
  561.44 +     typedef int ogg_int32_t;
  561.45 +     typedef unsigned int ogg_uint32_t;
  561.46 +     typedef long long ogg_int64_t;
  561.47 +     typedef unsigned long long ogg_uint64_t;
  561.48 +#  elif defined(__MWERKS__)
  561.49 +     typedef long long ogg_int64_t;
  561.50 +     typedef int ogg_int32_t;
  561.51 +     typedef unsigned int ogg_uint32_t;
  561.52 +     typedef short ogg_int16_t;
  561.53 +     typedef unsigned short ogg_uint16_t;
  561.54 +#  else
  561.55 +     /* MSVC/Borland */
  561.56 +     typedef __int64 ogg_int64_t;
  561.57 +     typedef __int32 ogg_int32_t;
  561.58 +     typedef unsigned __int32 ogg_uint32_t;
  561.59 +     typedef __int16 ogg_int16_t;
  561.60 +     typedef unsigned __int16 ogg_uint16_t;
  561.61 +#  endif
  561.62 +
  561.63 +#elif defined(__MACOS__)
  561.64 +
  561.65 +#  include <sys/types.h>
  561.66 +   typedef SInt16 ogg_int16_t;
  561.67 +   typedef UInt16 ogg_uint16_t;
  561.68 +   typedef SInt32 ogg_int32_t;
  561.69 +   typedef UInt32 ogg_uint32_t;
  561.70 +   typedef SInt64 ogg_int64_t;
  561.71 +
  561.72 +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
  561.73 +
  561.74 +#  include <inttypes.h>
  561.75 +   typedef int16_t ogg_int16_t;
  561.76 +   typedef uint16_t ogg_uint16_t;
  561.77 +   typedef int32_t ogg_int32_t;
  561.78 +   typedef uint32_t ogg_uint32_t;
  561.79 +   typedef int64_t ogg_int64_t;
  561.80 +
  561.81 +#elif defined(__HAIKU__)
  561.82 +
  561.83 +  /* Haiku */
  561.84 +#  include <sys/types.h>
  561.85 +   typedef short ogg_int16_t;
  561.86 +   typedef unsigned short ogg_uint16_t;
  561.87 +   typedef int ogg_int32_t;
  561.88 +   typedef unsigned int ogg_uint32_t;
  561.89 +   typedef long long ogg_int64_t;
  561.90 +
  561.91 +#elif defined(__BEOS__)
  561.92 +
  561.93 +   /* Be */
  561.94 +#  include <inttypes.h>
  561.95 +   typedef int16_t ogg_int16_t;
  561.96 +   typedef uint16_t ogg_uint16_t;
  561.97 +   typedef int32_t ogg_int32_t;
  561.98 +   typedef uint32_t ogg_uint32_t;
  561.99 +   typedef int64_t ogg_int64_t;
 561.100 +
 561.101 +#elif defined (__EMX__)
 561.102 +
 561.103 +   /* OS/2 GCC */
 561.104 +   typedef short ogg_int16_t;
 561.105 +   typedef unsigned short ogg_uint16_t;
 561.106 +   typedef int ogg_int32_t;
 561.107 +   typedef unsigned int ogg_uint32_t;
 561.108 +   typedef long long ogg_int64_t;
 561.109 +
 561.110 +#elif defined (DJGPP)
 561.111 +
 561.112 +   /* DJGPP */
 561.113 +   typedef short ogg_int16_t;
 561.114 +   typedef int ogg_int32_t;
 561.115 +   typedef unsigned int ogg_uint32_t;
 561.116 +   typedef long long ogg_int64_t;
 561.117 +
 561.118 +#elif defined(R5900)
 561.119 +
 561.120 +   /* PS2 EE */
 561.121 +   typedef long ogg_int64_t;
 561.122 +   typedef int ogg_int32_t;
 561.123 +   typedef unsigned ogg_uint32_t;
 561.124 +   typedef short ogg_int16_t;
 561.125 +
 561.126 +#elif defined(__SYMBIAN32__)
 561.127 +
 561.128 +   /* Symbian GCC */
 561.129 +   typedef signed short ogg_int16_t;
 561.130 +   typedef unsigned short ogg_uint16_t;
 561.131 +   typedef signed int ogg_int32_t;
 561.132 +   typedef unsigned int ogg_uint32_t;
 561.133 +   typedef long long int ogg_int64_t;
 561.134 +
 561.135 +#elif defined(__TMS320C6X__)
 561.136 +
 561.137 +   /* TI C64x compiler */
 561.138 +   typedef signed short ogg_int16_t;
 561.139 +   typedef unsigned short ogg_uint16_t;
 561.140 +   typedef signed int ogg_int32_t;
 561.141 +   typedef unsigned int ogg_uint32_t;
 561.142 +   typedef long long int ogg_int64_t;
 561.143 +
 561.144 +#else
 561.145 +
 561.146 +#  include <ogg/config_types.h>
 561.147 +
 561.148 +#endif
 561.149 +
 561.150 +#endif  /* _OS_TYPES_H */
   562.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   562.2 +++ b/libs/psys/pattr.c	Sat Feb 01 19:58:19 2014 +0200
   562.3 @@ -0,0 +1,401 @@
   562.4 +#define _GNU_SOURCE
   562.5 +#include <stdio.h>
   562.6 +#include <stdlib.h>
   562.7 +#include <string.h>
   562.8 +#include <errno.h>
   562.9 +#include <ctype.h>
  562.10 +
  562.11 +#ifdef _MSC_VER
  562.12 +#include <malloc.h>
  562.13 +#else
  562.14 +#include <alloca.h>
  562.15 +#endif
  562.16 +
  562.17 +#include "pattr.h"
  562.18 +
  562.19 +enum {
  562.20 +	OPT_STR,
  562.21 +	OPT_NUM,
  562.22 +	OPT_NUM_RANGE,
  562.23 +	OPT_VEC,
  562.24 +	OPT_VEC_RANGE
  562.25 +};
  562.26 +
  562.27 +struct cfgopt {
  562.28 +	char *name;
  562.29 +	int type;
  562.30 +	long tm;
  562.31 +	char *valstr;
  562.32 +	vec3_t val, valrng;
  562.33 +};
  562.34 +
  562.35 +static int init_particle_attr(struct psys_particle_attributes *pattr);
  562.36 +static void destroy_particle_attr(struct psys_particle_attributes *pattr);
  562.37 +static struct cfgopt *get_cfg_opt(const char *line);
  562.38 +static void release_cfg_opt(struct cfgopt *opt);
  562.39 +static char *stripspace(char *str);
  562.40 +
  562.41 +static void *tex_cls;
  562.42 +static unsigned int (*load_texture)(const char*, void*);
  562.43 +static void (*unload_texture)(unsigned int, void*);
  562.44 +
  562.45 +
  562.46 +void psys_texture_loader(unsigned int (*load)(const char*, void*), void (*unload)(unsigned int, void*), void *cls)
  562.47 +{
  562.48 +	load_texture = load;
  562.49 +	unload_texture = unload;
  562.50 +	tex_cls = cls;
  562.51 +}
  562.52 +
  562.53 +struct psys_attributes *psys_create_attr(void)
  562.54 +{
  562.55 +	struct psys_attributes *attr = malloc(sizeof *attr);
  562.56 +	if(attr) {
  562.57 +		if(psys_init_attr(attr) == -1) {
  562.58 +			free(attr);
  562.59 +			attr = 0;
  562.60 +		}
  562.61 +	}
  562.62 +	return attr;
  562.63 +}
  562.64 +
  562.65 +void psys_free_attr(struct psys_attributes *attr)
  562.66 +{
  562.67 +	psys_destroy_attr(attr);
  562.68 +	free(attr);
  562.69 +}
  562.70 +
  562.71 +int psys_init_attr(struct psys_attributes *attr)
  562.72 +{
  562.73 +	memset(attr, 0, sizeof *attr);
  562.74 +
  562.75 +	if(psys_init_track3(&attr->spawn_range) == -1)
  562.76 +		goto err;
  562.77 +	if(psys_init_track(&attr->rate) == -1)
  562.78 +		goto err;
  562.79 +	if(psys_init_anm_rnd(&attr->life) == -1)
  562.80 +		goto err;
  562.81 +	if(psys_init_anm_rnd(&attr->size) == -1)
  562.82 +		goto err;
  562.83 +	if(psys_init_anm_rnd3(&attr->dir) == -1)
  562.84 +		goto err;
  562.85 +	if(psys_init_track3(&attr->grav) == -1)
  562.86 +		goto err;
  562.87 +
  562.88 +	if(init_particle_attr(&attr->part_attr) == -1)
  562.89 +		goto err;
  562.90 +
  562.91 +	attr->max_particles = -1;
  562.92 +
  562.93 +	anm_set_track_default(&attr->size.value.trk, 1.0);
  562.94 +	anm_set_track_default(&attr->life.value.trk, 1.0);
  562.95 +
  562.96 +	return 0;
  562.97 +
  562.98 +err:
  562.99 +	psys_destroy_attr(attr);
 562.100 +	return -1;
 562.101 +}
 562.102 +
 562.103 +
 562.104 +static int init_particle_attr(struct psys_particle_attributes *pattr)
 562.105 +{
 562.106 +	if(psys_init_track3(&pattr->color) == -1) {
 562.107 +		return -1;
 562.108 +	}
 562.109 +	if(psys_init_track(&pattr->alpha) == -1) {
 562.110 +		psys_destroy_track3(&pattr->color);
 562.111 +		return -1;
 562.112 +	}
 562.113 +	if(psys_init_track(&pattr->size) == -1) {
 562.114 +		psys_destroy_track3(&pattr->color);
 562.115 +		psys_destroy_track(&pattr->alpha);
 562.116 +		return -1;
 562.117 +	}
 562.118 +
 562.119 +	anm_set_track_default(&pattr->color.x, 1.0);
 562.120 +	anm_set_track_default(&pattr->color.y, 1.0);
 562.121 +	anm_set_track_default(&pattr->color.z, 1.0);
 562.122 +	anm_set_track_default(&pattr->alpha.trk, 1.0);
 562.123 +	anm_set_track_default(&pattr->size.trk, 1.0);
 562.124 +	return 0;
 562.125 +}
 562.126 +
 562.127 +
 562.128 +void psys_destroy_attr(struct psys_attributes *attr)
 562.129 +{
 562.130 +	psys_destroy_track3(&attr->spawn_range);
 562.131 +	psys_destroy_track(&attr->rate);
 562.132 +	psys_destroy_anm_rnd(&attr->life);
 562.133 +	psys_destroy_anm_rnd(&attr->size);
 562.134 +	psys_destroy_anm_rnd3(&attr->dir);
 562.135 +	psys_destroy_track3(&attr->grav);
 562.136 +
 562.137 +	destroy_particle_attr(&attr->part_attr);
 562.138 +
 562.139 +	if(attr->tex && unload_texture) {
 562.140 +		unload_texture(attr->tex, tex_cls);
 562.141 +	}
 562.142 +}
 562.143 +
 562.144 +static void destroy_particle_attr(struct psys_particle_attributes *pattr)
 562.145 +{
 562.146 +	psys_destroy_track3(&pattr->color);
 562.147 +	psys_destroy_track(&pattr->alpha);
 562.148 +	psys_destroy_track(&pattr->size);
 562.149 +}
 562.150 +
 562.151 +void psys_copy_attr(struct psys_attributes *dest, const struct psys_attributes *src)
 562.152 +{
 562.153 +	dest->tex = src->tex;
 562.154 +
 562.155 +	psys_copy_track3(&dest->spawn_range, &src->spawn_range);
 562.156 +	psys_copy_track(&dest->rate, &src->rate);
 562.157 +
 562.158 +	psys_copy_anm_rnd(&dest->life, &src->life);
 562.159 +	psys_copy_anm_rnd(&dest->size, &src->size);
 562.160 +	psys_copy_anm_rnd3(&dest->dir, &src->dir);
 562.161 +
 562.162 +	psys_copy_track3(&dest->grav, &src->grav);
 562.163 +
 562.164 +	dest->drag = src->drag;
 562.165 +	dest->max_particles = src->max_particles;
 562.166 +
 562.167 +	/* also copy the particle attributes */
 562.168 +	psys_copy_track3(&dest->part_attr.color, &src->part_attr.color);
 562.169 +	psys_copy_track(&dest->part_attr.alpha, &src->part_attr.alpha);
 562.170 +	psys_copy_track(&dest->part_attr.size, &src->part_attr.size);
 562.171 +}
 562.172 +
 562.173 +void psys_eval_attr(struct psys_attributes *attr, anm_time_t tm)
 562.174 +{
 562.175 +	psys_eval_track3(&attr->spawn_range, tm);
 562.176 +	psys_eval_track(&attr->rate, tm);
 562.177 +	psys_eval_anm_rnd(&attr->life, tm);
 562.178 +	psys_eval_anm_rnd(&attr->size, tm);
 562.179 +	psys_eval_anm_rnd3(&attr->dir, tm);
 562.180 +	psys_eval_track3(&attr->grav, tm);
 562.181 +}
 562.182 +
 562.183 +int psys_load_attr(struct psys_attributes *attr, const char *fname)
 562.184 +{
 562.185 +	FILE *fp;
 562.186 +	int res;
 562.187 +
 562.188 +	if(!fname) {
 562.189 +		return -1;
 562.190 +	}
 562.191 +
 562.192 +	if(!(fp = fopen(fname, "r"))) {
 562.193 +		fprintf(stderr, "%s: failed to read file: %s: %s\n", __FUNCTION__, fname, strerror(errno));
 562.194 +		return -1;
 562.195 +	}
 562.196 +	res = psys_load_attr_stream(attr, fp);
 562.197 +	fclose(fp);
 562.198 +	return res;
 562.199 +}
 562.200 +
 562.201 +int psys_load_attr_stream(struct psys_attributes *attr, FILE *fp)
 562.202 +{
 562.203 +	int lineno = 0;
 562.204 +	char buf[512];
 562.205 +	struct cfgopt *opt = 0;
 562.206 +
 562.207 +	psys_init_attr(attr);
 562.208 +
 562.209 +	while(fgets(buf, sizeof buf, fp)) {
 562.210 +
 562.211 +		lineno++;
 562.212 +
 562.213 +		if(!(opt = get_cfg_opt(buf))) {
 562.214 +			continue;
 562.215 +		}
 562.216 +
 562.217 +		if(strcmp(opt->name, "texture") == 0) {
 562.218 +			if(opt->type != OPT_STR) {
 562.219 +				goto err;
 562.220 +			}
 562.221 +			if(!load_texture) {
 562.222 +				fprintf(stderr, "particle system requests a texture, but no texture loader available!\n");
 562.223 +				goto err;
 562.224 +			}
 562.225 +			if(!(attr->tex = load_texture(opt->valstr, tex_cls))) {
 562.226 +				fprintf(stderr, "failed to load texture: %s\n", opt->valstr);
 562.227 +				goto err;
 562.228 +			}
 562.229 +
 562.230 +			release_cfg_opt(opt);
 562.231 +			continue;
 562.232 +		} else if(opt->type == OPT_STR) {
 562.233 +			fprintf(stderr, "invalid particle config: '%s'\n", opt->name);
 562.234 +			goto err;
 562.235 +		}
 562.236 +
 562.237 +		if(strcmp(opt->name, "spawn_range") == 0) {
 562.238 +			psys_set_value3(&attr->spawn_range, opt->tm, opt->val);
 562.239 +		} else if(strcmp(opt->name, "rate") == 0) {
 562.240 +			psys_set_value(&attr->rate, opt->tm, opt->val.x);
 562.241 +		} else if(strcmp(opt->name, "life") == 0) {
 562.242 +			psys_set_anm_rnd(&attr->life, opt->tm, opt->val.x, opt->valrng.x);
 562.243 +		} else if(strcmp(opt->name, "size") == 0) {
 562.244 +			psys_set_anm_rnd(&attr->size, opt->tm, opt->val.x, opt->valrng.x);
 562.245 +		} else if(strcmp(opt->name, "dir") == 0) {
 562.246 +			psys_set_anm_rnd3(&attr->dir, opt->tm, opt->val, opt->valrng);
 562.247 +		} else if(strcmp(opt->name, "grav") == 0) {
 562.248 +			psys_set_value3(&attr->grav, opt->tm, opt->val);
 562.249 +		} else if(strcmp(opt->name, "drag") == 0) {
 562.250 +			attr->drag = opt->val.x;
 562.251 +		} else if(strcmp(opt->name, "pcolor") == 0) {
 562.252 +			psys_set_value3(&attr->part_attr.color, opt->tm, opt->val);
 562.253 +		} else if(strcmp(opt->name, "palpha") == 0) {
 562.254 +			psys_set_value(&attr->part_attr.alpha, opt->tm, opt->val.x);
 562.255 +		} else if(strcmp(opt->name, "psize") == 0) {
 562.256 +			psys_set_value(&attr->part_attr.size, opt->tm, opt->val.x);
 562.257 +		} else {
 562.258 +			fprintf(stderr, "unrecognized particle config option: %s\n", opt->name);
 562.259 +			goto err;
 562.260 +		}
 562.261 +
 562.262 +		release_cfg_opt(opt);
 562.263 +	}
 562.264 +
 562.265 +	return 0;
 562.266 +
 562.267 +err:
 562.268 +	fprintf(stderr, "Line %d: error parsing particle definition\n", lineno);
 562.269 +	release_cfg_opt(opt);
 562.270 +	return -1;
 562.271 +}
 562.272 +
 562.273 +static struct cfgopt *get_cfg_opt(const char *line)
 562.274 +{
 562.275 +	char *buf, *tmp;
 562.276 +	struct cfgopt *opt;
 562.277 +
 562.278 +	/* allocate a working buffer on the stack that could fit the current line */
 562.279 +	buf = alloca(strlen(line) + 1);
 562.280 +
 562.281 +	line = stripspace((char*)line);
 562.282 +	if(line[0] == '#' || !line[0]) {
 562.283 +		return 0;	/* skip empty lines and comments */
 562.284 +	}
 562.285 +
 562.286 +	if(!(opt = malloc(sizeof *opt))) {
 562.287 +		return 0;
 562.288 +	}
 562.289 +
 562.290 +	if(!(opt->valstr = strchr(line, '='))) {
 562.291 +		release_cfg_opt(opt);
 562.292 +		return 0;
 562.293 +	}
 562.294 +	*opt->valstr++ = 0;
 562.295 +	opt->valstr = stripspace(opt->valstr);
 562.296 +
 562.297 +	strcpy(buf, line);
 562.298 +	buf = stripspace(buf);
 562.299 +
 562.300 +	/* parse the keyframe time specifier if it exists */
 562.301 +	if((tmp = strchr(buf, '('))) {
 562.302 +		char *endp;
 562.303 +		float tval;
 562.304 +
 562.305 +		*tmp++ = 0;
 562.306 +		opt->name = malloc(strlen(buf) + 1);
 562.307 +		strcpy(opt->name, buf);
 562.308 +
 562.309 +		tval = strtod(tmp, &endp);
 562.310 +		if(endp == tmp) { /* nada ... */
 562.311 +			opt->tm = 0;
 562.312 +		} else if(*endp == 's') {	/* seconds suffix */
 562.313 +			opt->tm = (long)(tval * 1000.0f);
 562.314 +		} else {
 562.315 +			opt->tm = (long)tval;
 562.316 +		}
 562.317 +	} else {
 562.318 +		opt->name = malloc(strlen(buf) + 1);
 562.319 +		strcpy(opt->name, buf);
 562.320 +		opt->tm = 0;
 562.321 +	}
 562.322 +
 562.323 +	if(sscanf(opt->valstr, "[%f %f %f] ~ [%f %f %f]", &opt->val.x, &opt->val.y, &opt->val.z,
 562.324 +				&opt->valrng.x, &opt->valrng.y, &opt->valrng.z) == 6) {
 562.325 +		/* value is a vector range */
 562.326 +		opt->type = OPT_VEC_RANGE;
 562.327 +
 562.328 +	} else if(sscanf(opt->valstr, "%f ~ %f", &opt->val.x, &opt->valrng.x) == 2) {
 562.329 +		/* value is a number range */
 562.330 +		opt->type = OPT_NUM_RANGE;
 562.331 +		opt->val.y = opt->val.z = opt->val.x;
 562.332 +		opt->valrng.y = opt->valrng.z = opt->valrng.x;
 562.333 +
 562.334 +	} else if(sscanf(opt->valstr, "[%f %f %f]", &opt->val.x, &opt->val.y, &opt->val.z) == 3) {
 562.335 +		/* value is a vector */
 562.336 +		opt->type = OPT_VEC;
 562.337 +		opt->valrng.x = opt->valrng.y = opt->valrng.z = 0.0f;
 562.338 +
 562.339 +	} else if(sscanf(opt->valstr, "%f", &opt->val.x) == 1) {
 562.340 +		/* value is a number */
 562.341 +		opt->type = OPT_NUM;
 562.342 +		opt->val.y = opt->val.z = opt->val.x;
 562.343 +		opt->valrng.x = opt->valrng.y = opt->valrng.z = 0.0f;
 562.344 +
 562.345 +	} else if(sscanf(opt->valstr, "\"%s\"", buf) == 1) {
 562.346 +		/* just a string... strip the quotes */
 562.347 +		if(buf[strlen(buf) - 1] == '\"') {
 562.348 +			buf[strlen(buf) - 1] = 0;
 562.349 +		}
 562.350 +		opt->type = OPT_STR;
 562.351 +		opt->valstr = strdup(buf);
 562.352 +	} else {
 562.353 +		/* fuck it ... */
 562.354 +		release_cfg_opt(opt);
 562.355 +		return 0;
 562.356 +	}
 562.357 +
 562.358 +	return opt;
 562.359 +}
 562.360 +
 562.361 +static void release_cfg_opt(struct cfgopt *opt)
 562.362 +{
 562.363 +	if(opt) {
 562.364 +		free(opt->name);
 562.365 +		opt->name = 0;
 562.366 +	}
 562.367 +	opt = 0;
 562.368 +}
 562.369 +
 562.370 +
 562.371 +int psys_save_attr(const struct psys_attributes *attr, const char *fname)
 562.372 +{
 562.373 +	FILE *fp;
 562.374 +	int res;
 562.375 +
 562.376 +	if(!(fp = fopen(fname, "w"))) {
 562.377 +		fprintf(stderr, "%s: failed to write file: %s: %s\n", __FUNCTION__, fname, strerror(errno));
 562.378 +		return -1;
 562.379 +	}
 562.380 +	res = psys_save_attr_stream(attr, fp);
 562.381 +	fclose(fp);
 562.382 +	return res;
 562.383 +}
 562.384 +
 562.385 +int psys_save_attr_stream(const struct psys_attributes *attr, FILE *fp)
 562.386 +{
 562.387 +	return -1;	/* TODO */
 562.388 +}
 562.389 +
 562.390 +
 562.391 +static char *stripspace(char *str)
 562.392 +{
 562.393 +	char *end;
 562.394 +
 562.395 +	while(*str && isspace(*str)) {
 562.396 +		str++;
 562.397 +	}
 562.398 +
 562.399 +	end = str + strlen(str) - 1;
 562.400 +	while(end >= str && isspace(*end)) {
 562.401 +		*end-- = 0;
 562.402 +	}
 562.403 +	return str;
 562.404 +}
   563.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   563.2 +++ b/libs/psys/pattr.h	Sat Feb 01 19:58:19 2014 +0200
   563.3 @@ -0,0 +1,62 @@
   563.4 +#ifndef PATTR_H_
   563.5 +#define PATTR_H_
   563.6 +
   563.7 +#include "pstrack.h"
   563.8 +#include "rndval.h"
   563.9 +
  563.10 +/* the particle attributes vary from 0 to 1 during its lifetime */
  563.11 +struct psys_particle_attributes {
  563.12 +	struct psys_track3 color;
  563.13 +	struct psys_track alpha;
  563.14 +	struct psys_track size;
  563.15 +};
  563.16 +
  563.17 +struct psys_attributes {
  563.18 +	unsigned int tex;	/* OpenGL texture to use for the billboard */
  563.19 +
  563.20 +	struct psys_track3 spawn_range;	/* radius of emmiter */
  563.21 +	struct psys_track rate;			/* spawn rate particles per sec */
  563.22 +	struct psys_anm_rnd life;		/* particle life in seconds */
  563.23 +	struct psys_anm_rnd size;		/* base particle size */
  563.24 +	struct psys_anm_rnd3 dir;		/* particle shoot direction */
  563.25 +
  563.26 +	struct psys_track3 grav;		/* external force (usually gravity) */
  563.27 +	float drag;	/* I don't think this needs to animate */
  563.28 +
  563.29 +	/* particle attributes */
  563.30 +	struct psys_particle_attributes part_attr;
  563.31 +
  563.32 +	/* limits */
  563.33 +	int max_particles;
  563.34 +};
  563.35 +
  563.36 +#ifdef __cplusplus
  563.37 +extern "C" {
  563.38 +#endif
  563.39 +
  563.40 +void psys_texture_loader(unsigned int (*load)(const char*, void*), void (*unload)(unsigned int, void*), void *cls);
  563.41 +
  563.42 +struct psys_attributes *psys_create_attr(void);
  563.43 +void psys_free_attr(struct psys_attributes *attr);
  563.44 +
  563.45 +int psys_init_attr(struct psys_attributes *attr);
  563.46 +void psys_destroy_attr(struct psys_attributes *attr);
  563.47 +
  563.48 +/* copies particle system attributes src to dest
  563.49 + * XXX: dest must have been initialized first
  563.50 + */
  563.51 +void psys_copy_attr(struct psys_attributes *dest, const struct psys_attributes *src);
  563.52 +
  563.53 +void psys_eval_attr(struct psys_attributes *attr, anm_time_t tm);
  563.54 +
  563.55 +int psys_load_attr(struct psys_attributes *attr, const char *fname);
  563.56 +int psys_load_attr_stream(struct psys_attributes *attr, FILE *fp);
  563.57 +
  563.58 +int psys_save_attr(const struct psys_attributes *attr, const char *fname);
  563.59 +int psys_save_attr_stream(const struct psys_attributes *attr, FILE *fp);
  563.60 +
  563.61 +#ifdef __cplusplus
  563.62 +}
  563.63 +#endif
  563.64 +
  563.65 +#endif	/* PATTR_H_ */
   564.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   564.2 +++ b/libs/psys/pstrack.c	Sat Feb 01 19:58:19 2014 +0200
   564.3 @@ -0,0 +1,112 @@
   564.4 +#include "pstrack.h"
   564.5 +
   564.6 +int psys_init_track(struct psys_track *track)
   564.7 +{
   564.8 +	track->cache_tm = ANM_TIME_INVAL;
   564.9 +
  564.10 +	if(anm_init_track(&track->trk) == -1) {
  564.11 +		return -1;
  564.12 +	}
  564.13 +	return 0;
  564.14 +}
  564.15 +
  564.16 +void psys_destroy_track(struct psys_track *track)
  564.17 +{
  564.18 +	anm_destroy_track(&track->trk);
  564.19 +}
  564.20 +
  564.21 +int psys_init_track3(struct psys_track3 *track)
  564.22 +{
  564.23 +	track->cache_tm = ANM_TIME_INVAL;
  564.24 +
  564.25 +	if(anm_init_track(&track->x) == -1) {
  564.26 +		return -1;
  564.27 +	}
  564.28 +	if(anm_init_track(&track->y) == -1) {
  564.29 +		anm_destroy_track(&track->x);
  564.30 +		return -1;
  564.31 +	}
  564.32 +	if(anm_init_track(&track->z) == -1) {
  564.33 +		anm_destroy_track(&track->x);
  564.34 +		anm_destroy_track(&track->z);
  564.35 +		return -1;
  564.36 +	}
  564.37 +	return 0;
  564.38 +}
  564.39 +
  564.40 +void psys_destroy_track3(struct psys_track3 *track)
  564.41 +{
  564.42 +	anm_destroy_track(&track->x);
  564.43 +	anm_destroy_track(&track->y);
  564.44 +	anm_destroy_track(&track->z);
  564.45 +}
  564.46 +
  564.47 +void psys_copy_track(struct psys_track *dest, const struct psys_track *src)
  564.48 +{
  564.49 +	anm_copy_track(&dest->trk, &src->trk);
  564.50 +	dest->cache_tm = ANM_TIME_INVAL;
  564.51 +}
  564.52 +
  564.53 +void psys_copy_track3(struct psys_track3 *dest, const struct psys_track3 *src)
  564.54 +{
  564.55 +	anm_copy_track(&dest->x, &src->x);
  564.56 +	anm_copy_track(&dest->y, &src->y);
  564.57 +	anm_copy_track(&dest->z, &src->z);
  564.58 +
  564.59 +	dest->cache_tm = ANM_TIME_INVAL;
  564.60 +}
  564.61 +
  564.62 +void psys_eval_track(struct psys_track *track, anm_time_t tm)
  564.63 +{
  564.64 +	if(track->cache_tm != tm) {
  564.65 +		track->cache_tm = tm;
  564.66 +		track->cache_val = anm_get_value(&track->trk, tm);
  564.67 +	}
  564.68 +}
  564.69 +
  564.70 +void psys_set_value(struct psys_track *track, anm_time_t tm, float v)
  564.71 +{
  564.72 +	anm_set_value(&track->trk, tm, v);
  564.73 +	track->cache_tm = ANM_TIME_INVAL;
  564.74 +}
  564.75 +
  564.76 +float psys_get_value(struct psys_track *track, anm_time_t tm)
  564.77 +{
  564.78 +	psys_eval_track(track, tm);
  564.79 +	return track->cache_val;
  564.80 +}
  564.81 +
  564.82 +float psys_get_cur_value(struct psys_track *track)
  564.83 +{
  564.84 +	return track->cache_val;
  564.85 +}
  564.86 +
  564.87 +
  564.88 +void psys_eval_track3(struct psys_track3 *track, anm_time_t tm)
  564.89 +{
  564.90 +	if(track->cache_tm != tm) {
  564.91 +		track->cache_tm = tm;
  564.92 +		track->cache_vec.x = anm_get_value(&track->x, tm);
  564.93 +		track->cache_vec.y = anm_get_value(&track->y, tm);
  564.94 +		track->cache_vec.z = anm_get_value(&track->z, tm);
  564.95 +	}
  564.96 +}
  564.97 +
  564.98 +void psys_set_value3(struct psys_track3 *track, anm_time_t tm, vec3_t v)
  564.99 +{
 564.100 +	anm_set_value(&track->x, tm, v.x);
 564.101 +	anm_set_value(&track->y, tm, v.y);
 564.102 +	anm_set_value(&track->z, tm, v.z);
 564.103 +	track->cache_tm = ANM_TIME_INVAL;
 564.104 +}
 564.105 +
 564.106 +vec3_t psys_get_value3(struct psys_track3 *track, anm_time_t tm)
 564.107 +{
 564.108 +	psys_eval_track3(track, tm);
 564.109 +	return track->cache_vec;
 564.110 +}
 564.111 +
 564.112 +vec3_t psys_get_cur_value3(struct psys_track3 *track)
 564.113 +{
 564.114 +	return track->cache_vec;
 564.115 +}
   565.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   565.2 +++ b/libs/psys/pstrack.h	Sat Feb 01 19:58:19 2014 +0200
   565.3 @@ -0,0 +1,49 @@
   565.4 +#ifndef PSTRACK_H_
   565.5 +#define PSTRACK_H_
   565.6 +
   565.7 +#include <vmath/vmath.h>
   565.8 +#include <anim/anim.h>
   565.9 +
  565.10 +struct psys_track {
  565.11 +	struct anm_track trk;
  565.12 +
  565.13 +	anm_time_t cache_tm;
  565.14 +	float cache_val;
  565.15 +};
  565.16 +
  565.17 +struct psys_track3 {
  565.18 +	struct anm_track x, y, z;
  565.19 +
  565.20 +	anm_time_t cache_tm;
  565.21 +	vec3_t cache_vec;
  565.22 +};
  565.23 +
  565.24 +#ifdef __cplusplus
  565.25 +extern "C" {
  565.26 +#endif
  565.27 +
  565.28 +int psys_init_track(struct psys_track *track);
  565.29 +void psys_destroy_track(struct psys_track *track);
  565.30 +
  565.31 +int psys_init_track3(struct psys_track3 *track);
  565.32 +void psys_destroy_track3(struct psys_track3 *track);
  565.33 +
  565.34 +/* XXX dest must have been initialized first */
  565.35 +void psys_copy_track(struct psys_track *dest, const struct psys_track *src);
  565.36 +void psys_copy_track3(struct psys_track3 *dest, const struct psys_track3 *src);
  565.37 +
  565.38 +void psys_eval_track(struct psys_track *track, anm_time_t tm);
  565.39 +void psys_set_value(struct psys_track *track, anm_time_t tm, float v);
  565.40 +float psys_get_value(struct psys_track *track, anm_time_t tm);
  565.41 +float psys_get_cur_value(struct psys_track *track);
  565.42 +
  565.43 +void psys_eval_track3(struct psys_track3 *track, anm_time_t tm);
  565.44 +void psys_set_value3(struct psys_track3 *track, anm_time_t tm, vec3_t v);
  565.45 +vec3_t psys_get_value3(struct psys_track3 *track, anm_time_t tm);
  565.46 +vec3_t psys_get_cur_value3(struct psys_track3 *track);
  565.47 +
  565.48 +#ifdef __cplusplus
  565.49 +}
  565.50 +#endif
  565.51 +
  565.52 +#endif	/* PSTRACK_H_ */
   566.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   566.2 +++ b/libs/psys/psys.c	Sat Feb 01 19:58:19 2014 +0200
   566.3 @@ -0,0 +1,325 @@
   566.4 +#include <stdlib.h>
   566.5 +#include <math.h>
   566.6 +#include <float.h>
   566.7 +#include <assert.h>
   566.8 +#include <pthread.h>
   566.9 +#include "psys.h"
  566.10 +
  566.11 +static int spawn(struct psys_emitter *em, struct psys_particle *p, void *cls);
  566.12 +static void update_particle(struct psys_emitter *em, struct psys_particle *p, float tm, float dt, void *cls);
  566.13 +
  566.14 +/* particle pool */
  566.15 +static struct psys_particle *ppool;
  566.16 +static int ppool_size;
  566.17 +static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER;
  566.18 +
  566.19 +static struct psys_particle *palloc(void);
  566.20 +static void pfree(struct psys_particle *p);
  566.21 +
  566.22 +/* --- constructors and shit --- */
  566.23 +
  566.24 +struct psys_emitter *psys_create(void)
  566.25 +{
  566.26 +	struct psys_emitter *em;
  566.27 +
  566.28 +	if(!(em = malloc(sizeof *em))) {
  566.29 +		return 0;
  566.30 +	}
  566.31 +	if(psys_init(em) == -1) {
  566.32 +		free(em);
  566.33 +		return 0;
  566.34 +	}
  566.35 +	return em;
  566.36 +}
  566.37 +
  566.38 +void psys_free(struct psys_emitter *em)
  566.39 +{
  566.40 +	psys_destroy(em);
  566.41 +	free(em);
  566.42 +}
  566.43 +
  566.44 +int psys_init(struct psys_emitter *em)
  566.45 +{
  566.46 +	memset(em, 0, sizeof *em);
  566.47 +
  566.48 +	if(anm_init_node(&em->prs) == -1) {
  566.49 +		return -1;
  566.50 +	}
  566.51 +	if(psys_init_attr(&em->attr) == -1) {
  566.52 +		anm_destroy_node(&em->prs);
  566.53 +		return -1;
  566.54 +	}
  566.55 +
  566.56 +	em->spawn = spawn;
  566.57 +	em->update = update_particle;
  566.58 +
  566.59 +	em->draw = 0;
  566.60 +	em->draw_start = 0;
  566.61 +	em->draw_end = 0;
  566.62 +	return 0;
  566.63 +}
  566.64 +
  566.65 +void psys_destroy(struct psys_emitter *em)
  566.66 +{
  566.67 +	struct psys_particle *part;
  566.68 +
  566.69 +	part = em->plist;
  566.70 +	while(part) {
  566.71 +		struct psys_particle *tmp = part;
  566.72 +		part = part->next;
  566.73 +		pfree(tmp);
  566.74 +	}
  566.75 +
  566.76 +	psys_destroy_attr(&em->attr);
  566.77 +}
  566.78 +
  566.79 +void psys_set_pos(struct psys_emitter *em, vec3_t pos, float tm)
  566.80 +{
  566.81 +	anm_set_position(&em->prs, pos, ANM_SEC2TM(tm));
  566.82 +}
  566.83 +
  566.84 +void psys_set_rot(struct psys_emitter *em, quat_t rot, float tm)
  566.85 +{
  566.86 +	anm_set_rotation(&em->prs, rot, ANM_SEC2TM(tm));
  566.87 +}
  566.88 +
  566.89 +void psys_set_pivot(struct psys_emitter *em, vec3_t pivot)
  566.90 +{
  566.91 +	anm_set_pivot(&em->prs, pivot);
  566.92 +}
  566.93 +
  566.94 +vec3_t psys_get_pos(struct psys_emitter *em, float tm)
  566.95 +{
  566.96 +	return anm_get_node_position(&em->prs, ANM_SEC2TM(tm));
  566.97 +}
  566.98 +
  566.99 +quat_t psys_get_rot(struct psys_emitter *em, float tm)
 566.100 +{
 566.101 +	return anm_get_node_rotation(&em->prs, ANM_SEC2TM(tm));
 566.102 +}
 566.103 +
 566.104 +vec3_t psys_get_pivot(struct psys_emitter *em)
 566.105 +{
 566.106 +	return anm_get_pivot(&em->prs);
 566.107 +}
 566.108 +
 566.109 +void psys_clear_collision_planes(struct psys_emitter *em)
 566.110 +{
 566.111 +	struct psys_plane *plane;
 566.112 +
 566.113 +	plane = em->planes;
 566.114 +	while(plane) {
 566.115 +		struct psys_plane *tmp = plane;
 566.116 +		plane = plane->next;
 566.117 +		free(tmp);
 566.118 +	}
 566.119 +}
 566.120 +
 566.121 +int psys_add_collision_plane(struct psys_emitter *em, plane_t plane, float elast)
 566.122 +{
 566.123 +	struct psys_plane *node;
 566.124 +
 566.125 +	if(!(node = malloc(sizeof *node))) {
 566.126 +		return -1;
 566.127 +	}
 566.128 +	node->p = plane;
 566.129 +	node->elasticity = elast;
 566.130 +	node->next = em->planes;
 566.131 +	em->planes = node;
 566.132 +	return 0;
 566.133 +}
 566.134 +
 566.135 +void psys_add_particle(struct psys_emitter *em, struct psys_particle *p)
 566.136 +{
 566.137 +	p->next = em->plist;
 566.138 +	em->plist = p;
 566.139 +
 566.140 +	em->pcount++;
 566.141 +}
 566.142 +
 566.143 +void psys_spawn_func(struct psys_emitter *em, psys_spawn_func_t func, void *cls)
 566.144 +{
 566.145 +	em->spawn = func;
 566.146 +	em->spawn_cls = cls;
 566.147 +}
 566.148 +
 566.149 +void psys_update_func(struct psys_emitter *em, psys_update_func_t func, void *cls)
 566.150 +{
 566.151 +	em->update = func;
 566.152 +	em->upd_cls = cls;
 566.153 +}
 566.154 +
 566.155 +void psys_draw_func(struct psys_emitter *em, psys_draw_func_t draw,
 566.156 +		psys_draw_start_func_t start, psys_draw_end_func_t end, void *cls)
 566.157 +{
 566.158 +	em->draw = draw;
 566.159 +	em->draw_start = start;
 566.160 +	em->draw_end = end;
 566.161 +	em->draw_cls = cls;
 566.162 +}
 566.163 +
 566.164 +/* --- update and render --- */
 566.165 +
 566.166 +void psys_update(struct psys_emitter *em, float tm)
 566.167 +{
 566.168 +	float dt, spawn_dt, spawn_tm;
 566.169 +	int i, spawn_count;
 566.170 +	struct psys_particle *p, pdummy;
 566.171 +	anm_time_t atm = ANM_SEC2TM(tm);
 566.172 +
 566.173 +	assert(em->spawn && em->update);
 566.174 +
 566.175 +	dt = tm - em->last_update;
 566.176 +	if(dt <= 0.0) {
 566.177 +		return;
 566.178 +	}
 566.179 +
 566.180 +	psys_eval_attr(&em->attr, atm);
 566.181 +
 566.182 +	/* how many particles to spawn for this interval ? */
 566.183 +	em->spawn_acc += psys_get_cur_value(&em->attr.rate) * dt;
 566.184 +	if(em->spawn_acc >= 1.0) {
 566.185 +		spawn_count = em->spawn_acc;
 566.186 +		em->spawn_acc = fmod(em->spawn_acc, 1.0);
 566.187 +	} else {
 566.188 +		spawn_count = 0;
 566.189 +	}
 566.190 +
 566.191 +	spawn_dt = dt / (float)spawn_count;
 566.192 +	spawn_tm = em->last_update;
 566.193 +	for(i=0; i<spawn_count; i++) {
 566.194 +		if(em->attr.max_particles >= 0 && em->pcount >= em->attr.max_particles) {
 566.195 +			break;
 566.196 +		}
 566.197 +
 566.198 +		/* update emitter position for this spawning */
 566.199 +		em->cur_pos = anm_get_position(&em->prs, ANM_SEC2TM(spawn_tm));
 566.200 +
 566.201 +		if(!(p = palloc())) {
 566.202 +			return;
 566.203 +		}
 566.204 +		if(em->spawn(em, p, em->spawn_cls) == -1) {
 566.205 +			pfree(p);
 566.206 +		}
 566.207 +		spawn_tm += spawn_dt;
 566.208 +	}
 566.209 +
 566.210 +	/* update all particles */
 566.211 +	p = em->plist;
 566.212 +	while(p) {
 566.213 +		em->update(em, p, tm, dt, em->upd_cls);
 566.214 +		p = p->next;
 566.215 +	}
 566.216 +
 566.217 +	/* cleanup dead particles */
 566.218 +	pdummy.next = em->plist;
 566.219 +	p = &pdummy;
 566.220 +	while(p->next) {
 566.221 +		if(p->next->life <= 0) {
 566.222 +			struct psys_particle *tmp = p->next;
 566.223 +			p->next = p->next->next;
 566.224 +			pfree(tmp);
 566.225 +			em->pcount--;
 566.226 +		} else {
 566.227 +			p = p->next;
 566.228 +		}
 566.229 +	}
 566.230 +	em->plist = pdummy.next;
 566.231 +
 566.232 +	em->last_update = tm;
 566.233 +}
 566.234 +
 566.235 +void psys_draw(const struct psys_emitter *em)
 566.236 +{
 566.237 +	struct psys_particle *p;
 566.238 +
 566.239 +	assert(em->draw);
 566.240 +
 566.241 +	if(em->draw_start) {
 566.242 +		em->draw_start(em, em->draw_cls);
 566.243 +	}
 566.244 +
 566.245 +	p = em->plist;
 566.246 +	while(p) {
 566.247 +		em->draw(em, p, em->draw_cls);
 566.248 +		p = p->next;
 566.249 +	}
 566.250 +
 566.251 +	if(em->draw_end) {
 566.252 +		em->draw_end(em, em->draw_cls);
 566.253 +	}
 566.254 +}
 566.255 +
 566.256 +static int spawn(struct psys_emitter *em, struct psys_particle *p, void *cls)
 566.257 +{
 566.258 +	struct psys_rnd3 rpos;
 566.259 +	rpos.value = em->cur_pos;
 566.260 +	rpos.range = psys_get_cur_value3(&em->attr.spawn_range);
 566.261 +
 566.262 +	p->pos = psys_eval_rnd3(&rpos);
 566.263 +	p->vel = psys_eval_anm_rnd3(&em->attr.dir, PSYS_EVAL_CUR);
 566.264 +	p->base_size = psys_eval_anm_rnd(&em->attr.size, PSYS_EVAL_CUR);
 566.265 +	p->max_life = p->life = psys_eval_anm_rnd(&em->attr.life, PSYS_EVAL_CUR);
 566.266 +
 566.267 +	p->pattr = &em->attr.part_attr;
 566.268 +
 566.269 +	psys_add_particle(em, p);
 566.270 +	return 0;
 566.271 +}
 566.272 +
 566.273 +static void update_particle(struct psys_emitter *em, struct psys_particle *p, float tm, float dt, void *cls)
 566.274 +{
 566.275 +	vec3_t accel, grav;
 566.276 +	anm_time_t t;
 566.277 +
 566.278 +	grav = psys_get_cur_value3(&em->attr.grav);
 566.279 +
 566.280 +	accel.x = grav.x - p->vel.x * em->attr.drag;
 566.281 +	accel.y = grav.y - p->vel.y * em->attr.drag;
 566.282 +	accel.z = grav.z - p->vel.z * em->attr.drag;
 566.283 +
 566.284 +	p->vel.x += accel.x * dt;
 566.285 +	p->vel.y += accel.y * dt;
 566.286 +	p->vel.z += accel.z * dt;
 566.287 +
 566.288 +	p->pos.x += p->vel.x * dt;
 566.289 +	p->pos.y += p->vel.y * dt;
 566.290 +	p->pos.z += p->vel.z * dt;
 566.291 +
 566.292 +	/* update particle attributes */
 566.293 +	t = (anm_time_t)(1000.0 * (p->max_life - p->life) / p->max_life);
 566.294 +
 566.295 +	p->color = psys_get_value3(&p->pattr->color, t);
 566.296 +	p->alpha = psys_get_value(&p->pattr->alpha, t);
 566.297 +	p->size = p->base_size * psys_get_value(&p->pattr->size, t);
 566.298 +
 566.299 +	p->life -= dt;
 566.300 +}
 566.301 +
 566.302 +/* --- particle allocation pool --- */
 566.303 +
 566.304 +static struct psys_particle *palloc(void)
 566.305 +{
 566.306 +	struct psys_particle *p;
 566.307 +
 566.308 +	pthread_mutex_lock(&pool_lock);
 566.309 +	if(ppool) {
 566.310 +		p = ppool;
 566.311 +		ppool = ppool->next;
 566.312 +		ppool_size--;
 566.313 +	} else {
 566.314 +		p = malloc(sizeof *p);
 566.315 +	}
 566.316 +	pthread_mutex_unlock(&pool_lock);
 566.317 +
 566.318 +	return p;
 566.319 +}
 566.320 +
 566.321 +static void pfree(struct psys_particle *p)
 566.322 +{
 566.323 +	pthread_mutex_lock(&pool_lock);
 566.324 +	p->next = ppool;
 566.325 +	ppool = p;
 566.326 +	ppool_size++;
 566.327 +	pthread_mutex_unlock(&pool_lock);
 566.328 +}
   567.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   567.2 +++ b/libs/psys/psys.h	Sat Feb 01 19:58:19 2014 +0200
   567.3 @@ -0,0 +1,111 @@
   567.4 +#ifndef LIBPSYS_H_
   567.5 +#define LIBPSYS_H_
   567.6 +
   567.7 +#include <vmath/vmath.h>
   567.8 +#include <anim/anim.h>
   567.9 +#include "rndval.h"
  567.10 +#include "pattr.h"
  567.11 +
  567.12 +struct psys_particle;
  567.13 +struct psys_emitter;
  567.14 +
  567.15 +typedef int (*psys_spawn_func_t)(struct psys_emitter*, struct psys_particle*, void*);
  567.16 +typedef void (*psys_update_func_t)(struct psys_emitter*, struct psys_particle*, float, float, void*);
  567.17 +
  567.18 +typedef void (*psys_draw_func_t)(const struct psys_emitter*, const struct psys_particle*, void*);
  567.19 +typedef void (*psys_draw_start_func_t)(const struct psys_emitter*, void*);
  567.20 +typedef void (*psys_draw_end_func_t)(const struct psys_emitter*, void*);
  567.21 +
  567.22 +
  567.23 +struct psys_plane {
  567.24 +	plane_t p;
  567.25 +	float elasticity;
  567.26 +	struct psys_plane *next;
  567.27 +};
  567.28 +
  567.29 +
  567.30 +struct psys_emitter {
  567.31 +	struct anm_node prs;
  567.32 +	vec3_t cur_pos;
  567.33 +
  567.34 +	struct psys_attributes attr;
  567.35 +
  567.36 +	/* list of active particles */
  567.37 +	struct psys_particle *plist;
  567.38 +	int pcount;	/* number of active particles */
  567.39 +
  567.40 +	/* list of collision planes */
  567.41 +	struct psys_plane *planes;
  567.42 +
  567.43 +	/* custom spawn closure */
  567.44 +	void *spawn_cls;
  567.45 +	psys_spawn_func_t spawn;
  567.46 +
  567.47 +	/* custom particle update closure */
  567.48 +	void *upd_cls;
  567.49 +	psys_update_func_t update;
  567.50 +
  567.51 +	/* custom draw closure */
  567.52 +	void *draw_cls;
  567.53 +	psys_draw_func_t draw;
  567.54 +	psys_draw_start_func_t draw_start;
  567.55 +	psys_draw_end_func_t draw_end;
  567.56 +
  567.57 +	float spawn_acc;	/* partial spawn accumulator */
  567.58 +	float last_update;	/* last update time (to calc dt) */
  567.59 +};
  567.60 +
  567.61 +
  567.62 +struct psys_particle {
  567.63 +	vec3_t pos, vel;
  567.64 +	float life, max_life;
  567.65 +	float base_size;
  567.66 +
  567.67 +	struct psys_particle_attributes *pattr;
  567.68 +
  567.69 +	/* current particle attr values calculated during update */
  567.70 +	vec3_t color;
  567.71 +	float alpha, size;
  567.72 +
  567.73 +	struct psys_particle *next;
  567.74 +};
  567.75 +
  567.76 +#ifdef __cplusplus
  567.77 +extern "C" {
  567.78 +#endif
  567.79 +
  567.80 +struct psys_emitter *psys_create(void);
  567.81 +void psys_free(struct psys_emitter *em);
  567.82 +
  567.83 +int psys_init(struct psys_emitter *em);
  567.84 +void psys_destroy(struct psys_emitter *em);
  567.85 +
  567.86 +/* set properties */
  567.87 +void psys_set_pos(struct psys_emitter *em, vec3_t pos, float tm);
  567.88 +void psys_set_rot(struct psys_emitter *em, quat_t rot, float tm);
  567.89 +void psys_set_pivot(struct psys_emitter *em, vec3_t pivot);
  567.90 +
  567.91 +vec3_t psys_get_pos(struct psys_emitter *em, float tm);
  567.92 +quat_t psys_get_rot(struct psys_emitter *em, float tm);
  567.93 +vec3_t psys_get_pivot(struct psys_emitter *em);
  567.94 +
  567.95 +void psys_clear_collision_planes(struct psys_emitter *em);
  567.96 +int psys_add_collision_plane(struct psys_emitter *em, plane_t plane, float elast);
  567.97 +
  567.98 +void psys_add_particle(struct psys_emitter *em, struct psys_particle *p);
  567.99 +
 567.100 +void psys_spawn_func(struct psys_emitter *em, psys_spawn_func_t func, void *cls);
 567.101 +void psys_update_func(struct psys_emitter *em, psys_update_func_t func, void *cls);
 567.102 +void psys_draw_func(struct psys_emitter *em, psys_draw_func_t draw,
 567.103 +		psys_draw_start_func_t start, psys_draw_end_func_t end, void *cls);
 567.104 +
 567.105 +/* update and render */
 567.106 +
 567.107 +void psys_update(struct psys_emitter *em, float tm);
 567.108 +void psys_draw(const struct psys_emitter *em);
 567.109 +
 567.110 +#ifdef __cplusplus
 567.111 +}
 567.112 +#endif
 567.113 +
 567.114 +#endif	/* LIBPSYS_H_ */
   568.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   568.2 +++ b/libs/psys/rndval.c	Sat Feb 01 19:58:19 2014 +0200
   568.3 @@ -0,0 +1,116 @@
   568.4 +#include <stdlib.h>
   568.5 +#include "rndval.h"
   568.6 +
   568.7 +int psys_init_anm_rnd(struct psys_anm_rnd *r)
   568.8 +{
   568.9 +	if(psys_init_track(&r->value) == -1) {
  568.10 +		return -1;
  568.11 +	}
  568.12 +	if(psys_init_track(&r->range) == -1) {
  568.13 +		psys_destroy_track(&r->value);
  568.14 +		return -1;
  568.15 +	}
  568.16 +	return 0;
  568.17 +}
  568.18 +
  568.19 +void psys_destroy_anm_rnd(struct psys_anm_rnd *r)
  568.20 +{
  568.21 +	psys_destroy_track(&r->value);
  568.22 +	psys_destroy_track(&r->range);
  568.23 +}
  568.24 +
  568.25 +int psys_init_anm_rnd3(struct psys_anm_rnd3 *r)
  568.26 +{
  568.27 +	if(psys_init_track3(&r->value) == -1) {
  568.28 +		return -1;
  568.29 +	}
  568.30 +	if(psys_init_track3(&r->range) == -1) {
  568.31 +		psys_destroy_track3(&r->value);
  568.32 +		return -1;
  568.33 +	}
  568.34 +	return 0;
  568.35 +}
  568.36 +
  568.37 +void psys_destroy_anm_rnd3(struct psys_anm_rnd3 *r)
  568.38 +{
  568.39 +	psys_destroy_track3(&r->value);
  568.40 +	psys_destroy_track3(&r->range);
  568.41 +}
  568.42 +
  568.43 +void psys_copy_anm_rnd(struct psys_anm_rnd *dest, const struct psys_anm_rnd *src)
  568.44 +{
  568.45 +	psys_copy_track(&dest->value, &src->value);
  568.46 +	psys_copy_track(&dest->range, &src->range);
  568.47 +}
  568.48 +
  568.49 +void psys_copy_anm_rnd3(struct psys_anm_rnd3 *dest, const struct psys_anm_rnd3 *src)
  568.50 +{
  568.51 +	psys_copy_track3(&dest->value, &src->value);
  568.52 +	psys_copy_track3(&dest->range, &src->range);
  568.53 +}
  568.54 +
  568.55 +void psys_set_rnd(struct psys_rnd *r, float val, float range)
  568.56 +{
  568.57 +	r->value = val;
  568.58 +	r->range = range;
  568.59 +}
  568.60 +
  568.61 +void psys_set_rnd3(struct psys_rnd3 *r, vec3_t val, vec3_t range)
  568.62 +{
  568.63 +	r->value = val;
  568.64 +	r->range = range;
  568.65 +}
  568.66 +
  568.67 +void psys_set_anm_rnd(struct psys_anm_rnd *r, anm_time_t tm, float val, float range)
  568.68 +{
  568.69 +	psys_set_value(&r->value, tm, val);
  568.70 +	psys_set_value(&r->range, tm, range);
  568.71 +}
  568.72 +
  568.73 +void psys_set_anm_rnd3(struct psys_anm_rnd3 *r, anm_time_t tm, vec3_t val, vec3_t range)
  568.74 +{
  568.75 +	psys_set_value3(&r->value, tm, val);
  568.76 +	psys_set_value3(&r->range, tm, range);
  568.77 +}
  568.78 +
  568.79 +
  568.80 +float psys_eval_rnd(struct psys_rnd *r)
  568.81 +{
  568.82 +	return r->value + r->range * (float)rand() / (float)RAND_MAX - 0.5 * r->range;
  568.83 +}
  568.84 +
  568.85 +vec3_t psys_eval_rnd3(struct psys_rnd3 *r)
  568.86 +{
  568.87 +	vec3_t res;
  568.88 +	res.x = r->value.x + r->range.x * (float)rand() / (float)RAND_MAX - 0.5 * r->range.x;
  568.89 +	res.y = r->value.y + r->range.y * (float)rand() / (float)RAND_MAX - 0.5 * r->range.y;
  568.90 +	res.z = r->value.z + r->range.z * (float)rand() / (float)RAND_MAX - 0.5 * r->range.z;
  568.91 +	return res;
  568.92 +}
  568.93 +
  568.94 +
  568.95 +float psys_eval_anm_rnd(struct psys_anm_rnd *r, anm_time_t tm)
  568.96 +{
  568.97 +	struct psys_rnd tmp;
  568.98 +	if(tm == ANM_TIME_INVAL) {
  568.99 +		tmp.value = psys_get_cur_value(&r->value);
 568.100 +		tmp.range = psys_get_cur_value(&r->range);
 568.101 +	} else {
 568.102 +		tmp.value = psys_get_value(&r->value, tm);
 568.103 +		tmp.range = psys_get_value(&r->range, tm);
 568.104 +	}
 568.105 +	return psys_eval_rnd(&tmp);
 568.106 +}
 568.107 +
 568.108 +vec3_t psys_eval_anm_rnd3(struct psys_anm_rnd3 *r, anm_time_t tm)
 568.109 +{
 568.110 +	struct psys_rnd3 tmp;
 568.111 +	if(tm == ANM_TIME_INVAL) {
 568.112 +		tmp.value = psys_get_cur_value3(&r->value);
 568.113 +		tmp.range = psys_get_cur_value3(&r->range);
 568.114 +	} else {
 568.115 +		tmp.value = psys_get_value3(&r->value, tm);
 568.116 +		tmp.range = psys_get_value3(&r->range, tm);
 568.117 +	}
 568.118 +	return psys_eval_rnd3(&tmp);
 568.119 +}
   569.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   569.2 +++ b/libs/psys/rndval.h	Sat Feb 01 19:58:19 2014 +0200
   569.3 @@ -0,0 +1,53 @@
   569.4 +#ifndef RNDVAL_H_
   569.5 +#define RNDVAL_H_
   569.6 +
   569.7 +#include <vmath/vmath.h>
   569.8 +#include "pstrack.h"
   569.9 +
  569.10 +struct psys_rnd {
  569.11 +	float value, range;
  569.12 +};
  569.13 +
  569.14 +struct psys_rnd3 {
  569.15 +	vec3_t value, range;
  569.16 +};
  569.17 +
  569.18 +struct psys_anm_rnd {
  569.19 +	struct psys_track value, range;
  569.20 +};
  569.21 +
  569.22 +struct psys_anm_rnd3 {
  569.23 +	struct psys_track3 value, range;
  569.24 +};
  569.25 +
  569.26 +#define PSYS_EVAL_CUR	ANM_TIME_INVAL
  569.27 +
  569.28 +#ifdef __cplusplus
  569.29 +extern "C" {
  569.30 +#endif
  569.31 +
  569.32 +int psys_init_anm_rnd(struct psys_anm_rnd *v);
  569.33 +void psys_destroy_anm_rnd(struct psys_anm_rnd *v);
  569.34 +int psys_init_anm_rnd3(struct psys_anm_rnd3 *v);
  569.35 +void psys_destroy_anm_rnd3(struct psys_anm_rnd3 *v);
  569.36 +
  569.37 +void psys_copy_anm_rnd(struct psys_anm_rnd *dest, const struct psys_anm_rnd *src);
  569.38 +void psys_copy_anm_rnd3(struct psys_anm_rnd3 *dest, const struct psys_anm_rnd3 *src);
  569.39 +
  569.40 +void psys_set_rnd(struct psys_rnd *r, float val, float range);
  569.41 +void psys_set_rnd3(struct psys_rnd3 *r, vec3_t val, vec3_t range);
  569.42 +
  569.43 +void psys_set_anm_rnd(struct psys_anm_rnd *r, anm_time_t tm, float val, float range);
  569.44 +void psys_set_anm_rnd3(struct psys_anm_rnd3 *r, anm_time_t tm, vec3_t val, vec3_t range);
  569.45 +
  569.46 +float psys_eval_rnd(struct psys_rnd *r);
  569.47 +vec3_t psys_eval_rnd3(struct psys_rnd3 *r);
  569.48 +
  569.49 +float psys_eval_anm_rnd(struct psys_anm_rnd *r, anm_time_t tm);
  569.50 +vec3_t psys_eval_anm_rnd3(struct psys_anm_rnd3 *r, anm_time_t tm);
  569.51 +
  569.52 +#ifdef __cplusplus
  569.53 +}
  569.54 +#endif
  569.55 +
  569.56 +#endif	/* RNDVAL_H_ */
   570.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   570.2 +++ b/libs/vmath/basis.cc	Sat Feb 01 19:58:19 2014 +0200
   570.3 @@ -0,0 +1,63 @@
   570.4 +#include "basis.h"
   570.5 +#include "vmath.h"
   570.6 +
   570.7 +Basis::Basis()
   570.8 +{
   570.9 +	i = Vector3(1, 0, 0);
  570.10 +	j = Vector3(0, 1, 0);
  570.11 +	k = Vector3(0, 0, 1);
  570.12 +}
  570.13 +
  570.14 +Basis::Basis(const Vector3 &i, const Vector3 &j, const Vector3 &k)
  570.15 +{
  570.16 +	this->i = i;
  570.17 +	this->j = j;
  570.18 +	this->k = k;
  570.19 +}
  570.20 +
  570.21 +Basis::Basis(const Vector3 &dir, bool left_handed)
  570.22 +{
  570.23 +	k = dir;
  570.24 +	j = Vector3(0, 1, 0);
  570.25 +	i = cross_product(j, k);
  570.26 +	j = cross_product(k, i);
  570.27 +}
  570.28 +
  570.29 +/** Rotate with euler angles */
  570.30 +void Basis::rotate(scalar_t x, scalar_t y, scalar_t z) {
  570.31 +	Matrix4x4 RotMat;
  570.32 +	RotMat.set_rotation(Vector3(x, y, z));
  570.33 +	i.transform(RotMat);
  570.34 +	j.transform(RotMat);
  570.35 +	k.transform(RotMat);
  570.36 +}
  570.37 +
  570.38 +/** Rotate by axis-angle specification */
  570.39 +void Basis::rotate(const Vector3 &axis, scalar_t angle) {
  570.40 +	Quaternion q;
  570.41 +	q.set_rotation(axis, angle);
  570.42 +	i.transform(q);
  570.43 +	j.transform(q);
  570.44 +	k.transform(q);
  570.45 +}
  570.46 +
  570.47 +/** Rotate with a 4x4 matrix */
  570.48 +void Basis::rotate(const Matrix4x4 &mat) {
  570.49 +	i.transform(mat);
  570.50 +	j.transform(mat);
  570.51 +	k.transform(mat);
  570.52 +}
  570.53 +
  570.54 +/** Rotate with a quaternion */
  570.55 +void Basis::rotate(const Quaternion &quat) {
  570.56 +	i.transform(quat);
  570.57 +	j.transform(quat);
  570.58 +	k.transform(quat);
  570.59 +}
  570.60 +
  570.61 +/** Extract a rotation matrix from the orthogonal basis */
  570.62 +Matrix3x3 Basis::create_rotation_matrix() const {
  570.63 +	return Matrix3x3(	i.x, j.x, k.x,
  570.64 +						i.y, j.y, k.y,
  570.65 +						i.z, j.z, k.z);
  570.66 +}
   571.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   571.2 +++ b/libs/vmath/basis.h	Sat Feb 01 19:58:19 2014 +0200
   571.3 @@ -0,0 +1,57 @@
   571.4 +/*
   571.5 +libvmath - a vector math library
   571.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   571.7 +
   571.8 +This program is free software: you can redistribute it and/or modify
   571.9 +it under the terms of the GNU Lesser General Public License as published
  571.10 +by the Free Software Foundation, either version 3 of the License, or
  571.11 +(at your option) any later version.
  571.12 +
  571.13 +This program is distributed in the hope that it will be useful,
  571.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  571.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  571.16 +GNU Lesser General Public License for more details.
  571.17 +
  571.18 +You should have received a copy of the GNU Lesser General Public License
  571.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  571.20 +*/
  571.21 +
  571.22 +#ifndef VMATH_BASIS_H_
  571.23 +#define VMATH_BASIS_H_
  571.24 +
  571.25 +#include "vector.h"
  571.26 +#include "matrix.h"
  571.27 +
  571.28 +enum {
  571.29 +	LEFT_HANDED,
  571.30 +	RIGHT_HANDED
  571.31 +};
  571.32 +
  571.33 +#ifdef __cplusplus
  571.34 +extern "C" {
  571.35 +#endif	/* __cplusplus */
  571.36 +
  571.37 +void basis_matrix(mat4_t res, vec3_t i, vec3_t j, vec3_t k);
  571.38 +void basis_matrix_dir(mat4_t res, vec3_t dir);
  571.39 +
  571.40 +#ifdef __cplusplus
  571.41 +}	/* extern "C" */
  571.42 +
  571.43 +class Basis {
  571.44 +public:
  571.45 +	Vector3 i, j, k;
  571.46 +
  571.47 +	Basis();
  571.48 +	Basis(const Vector3 &i, const Vector3 &j, const Vector3 &k);
  571.49 +	Basis(const Vector3 &dir, bool left_handed = true);
  571.50 +
  571.51 +	void rotate(scalar_t x, scalar_t y, scalar_t z);
  571.52 +	void rotate(const Vector3 &axis, scalar_t angle);
  571.53 +	void rotate(const Matrix4x4 &mat);
  571.54 +	void rotate(const Quaternion &quat);
  571.55 +
  571.56 +	Matrix3x3 create_rotation_matrix() const;
  571.57 +};
  571.58 +#endif	/* __cplusplus */
  571.59 +
  571.60 +#endif	/* VMATH_BASIS_H_ */
   572.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   572.2 +++ b/libs/vmath/basis_c.c	Sat Feb 01 19:58:19 2014 +0200
   572.3 @@ -0,0 +1,37 @@
   572.4 +/*
   572.5 +libvmath - a vector math library
   572.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   572.7 +
   572.8 +This program is free software: you can redistribute it and/or modify
   572.9 +it under the terms of the GNU Lesser General Public License as published
  572.10 +by the Free Software Foundation, either version 3 of the License, or
  572.11 +(at your option) any later version.
  572.12 +
  572.13 +This program is distributed in the hope that it will be useful,
  572.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  572.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  572.16 +GNU Lesser General Public License for more details.
  572.17 +
  572.18 +You should have received a copy of the GNU Lesser General Public License
  572.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  572.20 +*/
  572.21 +
  572.22 +#include "basis.h"
  572.23 +#include "matrix.h"
  572.24 +
  572.25 +void basis_matrix(mat4_t res, vec3_t i, vec3_t j, vec3_t k)
  572.26 +{
  572.27 +	m4_identity(res);
  572.28 +	m4_set_column(res, v4_cons(i.x, i.y, i.z, 1.0), 0);
  572.29 +	m4_set_column(res, v4_cons(j.x, j.y, j.z, 1.0), 1);
  572.30 +	m4_set_column(res, v4_cons(k.x, k.y, k.z, 1.0), 2);
  572.31 +}
  572.32 +
  572.33 +void basis_matrix_dir(mat4_t res, vec3_t dir)
  572.34 +{
  572.35 +	vec3_t k = v3_normalize(dir);
  572.36 +	vec3_t j = {0, 1, 0};
  572.37 +	vec3_t i = v3_cross(j, k);
  572.38 +	j = v3_cross(k, i);
  572.39 +	basis_matrix(res, i, j, k);
  572.40 +}
   573.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   573.2 +++ b/libs/vmath/geom.c	Sat Feb 01 19:58:19 2014 +0200
   573.3 @@ -0,0 +1,150 @@
   573.4 +/*
   573.5 +libvmath - a vector math library
   573.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   573.7 +
   573.8 +This program is free software: you can redistribute it and/or modify
   573.9 +it under the terms of the GNU Lesser General Public License as published
  573.10 +by the Free Software Foundation, either version 3 of the License, or
  573.11 +(at your option) any later version.
  573.12 +
  573.13 +This program is distributed in the hope that it will be useful,
  573.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  573.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  573.16 +GNU Lesser General Public License for more details.
  573.17 +
  573.18 +You should have received a copy of the GNU Lesser General Public License
  573.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  573.20 +*/
  573.21 +
  573.22 +
  573.23 +#include <math.h>
  573.24 +#include "geom.h"
  573.25 +#include "vector.h"
  573.26 +
  573.27 +plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d)
  573.28 +{
  573.29 +	plane_t p;
  573.30 +	p.norm.x = nx;
  573.31 +	p.norm.y = ny;
  573.32 +	p.norm.z = nz;
  573.33 +	p.d = d;
  573.34 +	return p;
  573.35 +}
  573.36 +
  573.37 +plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2)
  573.38 +{
  573.39 +	vec3_t a, b, norm;
  573.40 +
  573.41 +	a = v3_sub(v1, v0);
  573.42 +	b = v3_sub(v2, v0);
  573.43 +	norm = v3_cross(a, b);
  573.44 +	norm = v3_normalize(norm);
  573.45 +
  573.46 +	return plane_ptnorm(v0, norm);
  573.47 +}
  573.48 +
  573.49 +plane_t plane_ptnorm(vec3_t pt, vec3_t normal)
  573.50 +{
  573.51 +	plane_t plane;
  573.52 +
  573.53 +	plane.norm = normal;
  573.54 +	plane.d = v3_dot(pt, normal);
  573.55 +
  573.56 +	return plane;
  573.57 +}
  573.58 +
  573.59 +plane_t plane_invert(plane_t p)
  573.60 +{
  573.61 +	p.norm = v3_neg(p.norm);
  573.62 +	p.d = -p.d;
  573.63 +	return p;
  573.64 +}
  573.65 +
  573.66 +scalar_t plane_signed_dist(plane_t plane, vec3_t pt)
  573.67 +{
  573.68 +	vec3_t pp = plane_point(plane);
  573.69 +	vec3_t pptopt = v3_sub(pt, pp);
  573.70 +	return v3_dot(pptopt, plane.norm);
  573.71 +}
  573.72 +
  573.73 +scalar_t plane_dist(plane_t plane, vec3_t pt)
  573.74 +{
  573.75 +	return fabs(plane_signed_dist(plane, pt));
  573.76 +}
  573.77 +
  573.78 +vec3_t plane_point(plane_t plane)
  573.79 +{
  573.80 +	return v3_scale(plane.norm, plane.d);
  573.81 +}
  573.82 +
  573.83 +int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos)
  573.84 +{
  573.85 +	vec3_t pt, orig_to_pt;
  573.86 +	scalar_t ndotdir;
  573.87 +
  573.88 +	pt = plane_point(plane);
  573.89 +	ndotdir = v3_dot(plane.norm, ray.dir);
  573.90 +
  573.91 +	if(fabs(ndotdir) < 1e-7) {
  573.92 +		return 0;
  573.93 +	}
  573.94 +
  573.95 +	if(pos) {
  573.96 +		orig_to_pt = v3_sub(pt, ray.origin);
  573.97 +		*pos = v3_dot(plane.norm, orig_to_pt) / ndotdir;
  573.98 +	}
  573.99 +	return 1;
 573.100 +}
 573.101 +
 573.102 +sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad)
 573.103 +{
 573.104 +	sphere_t sph;
 573.105 +	sph.pos.x = x;
 573.106 +	sph.pos.y = y;
 573.107 +	sph.pos.z = z;
 573.108 +	sph.rad = rad;
 573.109 +	return sph;
 573.110 +}
 573.111 +
 573.112 +int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos)
 573.113 +{
 573.114 +	scalar_t a, b, c, d, sqrt_d, t1, t2, t;
 573.115 +
 573.116 +	a = v3_dot(ray.dir, ray.dir);
 573.117 +	b = 2.0 * ray.dir.x * (ray.origin.x - sph.pos.x) +
 573.118 +		2.0 * ray.dir.y * (ray.origin.y - sph.pos.y) +
 573.119 +		2.0 * ray.dir.z * (ray.origin.z - sph.pos.z);
 573.120 +	c = v3_dot(sph.pos, sph.pos) + v3_dot(ray.origin, ray.origin) +
 573.121 +		2.0 * v3_dot(v3_neg(sph.pos), ray.origin) - sph.rad * sph.rad;
 573.122 +
 573.123 +	d = b * b - 4.0 * a * c;
 573.124 +	if(d < 0.0) {
 573.125 +		return 0;
 573.126 +	}
 573.127 +
 573.128 +	sqrt_d = sqrt(d);
 573.129 +	t1 = (-b + sqrt_d) / (2.0 * a);
 573.130 +	t2 = (-b - sqrt_d) / (2.0 * a);
 573.131 +
 573.132 +	if(t1 < 1e-7 || t1 > 1.0) {
 573.133 +		t1 = t2;
 573.134 +	}
 573.135 +	if(t2 < 1e-7 || t2 > 1.0) {
 573.136 +		t2 = t1;
 573.137 +	}
 573.138 +	t = t1 < t2 ? t1 : t2;
 573.139 +
 573.140 +	if(t < 1e-7 || t > 1.0) {
 573.141 +		return 0;
 573.142 +	}
 573.143 +
 573.144 +	if(pos) {
 573.145 +		*pos = t;
 573.146 +	}
 573.147 +	return 1;
 573.148 +}
 573.149 +
 573.150 +int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad)
 573.151 +{
 573.152 +	return -1;
 573.153 +}
   574.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   574.2 +++ b/libs/vmath/geom.h	Sat Feb 01 19:58:19 2014 +0200
   574.3 @@ -0,0 +1,72 @@
   574.4 +/*
   574.5 +libvmath - a vector math library
   574.6 +Copyright (C) 2004-2012 John Tsiombikas <nuclear@member.fsf.org>
   574.7 +
   574.8 +This program is free software: you can redistribute it and/or modify
   574.9 +it under the terms of the GNU Lesser General Public License as published
  574.10 +by the Free Software Foundation, either version 3 of the License, or
  574.11 +(at your option) any later version.
  574.12 +
  574.13 +This program is distributed in the hope that it will be useful,
  574.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  574.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  574.16 +GNU Lesser General Public License for more details.
  574.17 +
  574.18 +You should have received a copy of the GNU Lesser General Public License
  574.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  574.20 +*/
  574.21 +#ifndef LIBVMATH_GEOM_H_
  574.22 +#define LIBVMATH_GEOM_H_
  574.23 +
  574.24 +#include "vector.h"
  574.25 +#include "ray.h"
  574.26 +
  574.27 +typedef struct {
  574.28 +	vec3_t norm;
  574.29 +	scalar_t d;
  574.30 +} plane_t;
  574.31 +
  574.32 +typedef struct {
  574.33 +	vec3_t pos;
  574.34 +	scalar_t rad;
  574.35 +} sphere_t;
  574.36 +
  574.37 +typedef struct {
  574.38 +	vec3_t min, max;
  574.39 +} aabox_t;
  574.40 +
  574.41 +#ifdef __cplusplus
  574.42 +extern "C" {
  574.43 +#endif
  574.44 +
  574.45 +/* planes are good... you need planes, yes you do */
  574.46 +plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d);
  574.47 +plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2);
  574.48 +plane_t plane_ptnorm(vec3_t pt, vec3_t normal);
  574.49 +
  574.50 +plane_t plane_invert(plane_t p);
  574.51 +
  574.52 +scalar_t plane_signed_dist(plane_t plane, vec3_t pt);
  574.53 +scalar_t plane_dist(plane_t plane, vec3_t pt);
  574.54 +vec3_t plane_point(plane_t plane);
  574.55 +
  574.56 +int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos);
  574.57 +
  574.58 +/* spheres always come in handy */
  574.59 +sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad);
  574.60 +
  574.61 +int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos);
  574.62 +int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad);
  574.63 +
  574.64 +#ifdef __cplusplus
  574.65 +}
  574.66 +
  574.67 +/* TODO
  574.68 +class Plane : public plane_t {
  574.69 +public:
  574.70 +};
  574.71 +*/
  574.72 +
  574.73 +#endif
  574.74 +
  574.75 +#endif	/* LIBVMATH_GEOM_H_ */
   575.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   575.2 +++ b/libs/vmath/matrix.cc	Sat Feb 01 19:58:19 2014 +0200
   575.3 @@ -0,0 +1,853 @@
   575.4 +#include <cstdio>
   575.5 +#include <cmath>
   575.6 +#include "matrix.h"
   575.7 +#include "vector.h"
   575.8 +#include "quat.h"
   575.9 +
  575.10 +using namespace std;
  575.11 +
  575.12 +// ----------- Matrix3x3 --------------
  575.13 +
  575.14 +Matrix3x3 Matrix3x3::identity = Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1);
  575.15 +
  575.16 +Matrix3x3::Matrix3x3()
  575.17 +{
  575.18 +	*this = Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1);
  575.19 +}
  575.20 +
  575.21 +Matrix3x3::Matrix3x3(	scalar_t m11, scalar_t m12, scalar_t m13,
  575.22 +						scalar_t m21, scalar_t m22, scalar_t m23,
  575.23 +						scalar_t m31, scalar_t m32, scalar_t m33)
  575.24 +{
  575.25 +	m[0][0] = m11; m[0][1] = m12; m[0][2] = m13;
  575.26 +	m[1][0] = m21; m[1][1] = m22; m[1][2] = m23;
  575.27 +	m[2][0] = m31; m[2][1] = m32; m[2][2] = m33;
  575.28 +}
  575.29 +
  575.30 +Matrix3x3::Matrix3x3(const Vector3 &ivec, const Vector3 &jvec, const Vector3 &kvec)
  575.31 +{
  575.32 +	set_row_vector(ivec, 0);
  575.33 +	set_row_vector(jvec, 1);
  575.34 +	set_row_vector(kvec, 2);
  575.35 +}
  575.36 +
  575.37 +Matrix3x3::Matrix3x3(const mat3_t cmat)
  575.38 +{
  575.39 +	memcpy(m, cmat, sizeof(mat3_t));
  575.40 +}
  575.41 +
  575.42 +Matrix3x3::Matrix3x3(const Matrix4x4 &mat4x4)
  575.43 +{
  575.44 +	for(int i=0; i<3; i++) {
  575.45 +		for(int j=0; j<3; j++) {
  575.46 +			m[i][j] = mat4x4[i][j];
  575.47 +		}
  575.48 +	}
  575.49 +}
  575.50 +
  575.51 +Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2)
  575.52 +{
  575.53 +	Matrix3x3 res;
  575.54 +	const scalar_t *op1 = m1.m[0], *op2 = m2.m[0];
  575.55 +	scalar_t *dest = res.m[0];
  575.56 +
  575.57 +	for(int i=0; i<9; i++) {
  575.58 +		*dest++ = *op1++ + *op2++;
  575.59 +	}
  575.60 +	return res;
  575.61 +}
  575.62 +
  575.63 +Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2)
  575.64 +{
  575.65 +	Matrix3x3 res;
  575.66 +	const scalar_t *op1 = m1.m[0], *op2 = m2.m[0];
  575.67 +	scalar_t *dest = res.m[0];
  575.68 +
  575.69 +	for(int i=0; i<9; i++) {
  575.70 +		*dest++ = *op1++ - *op2++;
  575.71 +	}
  575.72 +	return res;
  575.73 +}
  575.74 +
  575.75 +Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2)
  575.76 +{
  575.77 +	Matrix3x3 res;
  575.78 +	for(int i=0; i<3; i++) {
  575.79 +		for(int j=0; j<3; j++) {
  575.80 +			res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j];
  575.81 +		}
  575.82 +	}
  575.83 +	return res;
  575.84 +}
  575.85 +
  575.86 +void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2)
  575.87 +{
  575.88 +	scalar_t *op1 = m1.m[0];
  575.89 +	const scalar_t *op2 = m2.m[0];
  575.90 +
  575.91 +	for(int i=0; i<9; i++) {
  575.92 +		*op1++ += *op2++;
  575.93 +	}
  575.94 +}
  575.95 +
  575.96 +void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2)
  575.97 +{
  575.98 +	scalar_t *op1 = m1.m[0];
  575.99 +	const scalar_t *op2 = m2.m[0];
 575.100 +
 575.101 +	for(int i=0; i<9; i++) {
 575.102 +		*op1++ -= *op2++;
 575.103 +	}
 575.104 +}
 575.105 +
 575.106 +void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2)
 575.107 +{
 575.108 +	Matrix3x3 res;
 575.109 +	for(int i=0; i<3; i++) {
 575.110 +		for(int j=0; j<3; j++) {
 575.111 +			res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j];
 575.112 +		}
 575.113 +	}
 575.114 +	memcpy(m1.m, res.m, 9 * sizeof(scalar_t));
 575.115 +}
 575.116 +
 575.117 +Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar)
 575.118 +{
 575.119 +	Matrix3x3 res;
 575.120 +	const scalar_t *mptr = mat.m[0];
 575.121 +	scalar_t *dptr = res.m[0];
 575.122 +
 575.123 +	for(int i=0; i<9; i++) {
 575.124 +		*dptr++ = *mptr++ * scalar;
 575.125 +	}
 575.126 +	return res;
 575.127 +}
 575.128 +
 575.129 +Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat)
 575.130 +{
 575.131 +	Matrix3x3 res;
 575.132 +	const scalar_t *mptr = mat.m[0];
 575.133 +	scalar_t *dptr = res.m[0];
 575.134 +
 575.135 +	for(int i=0; i<9; i++) {
 575.136 +		*dptr++ = *mptr++ * scalar;
 575.137 +	}
 575.138 +	return res;
 575.139 +}
 575.140 +
 575.141 +void operator *=(Matrix3x3 &mat, scalar_t scalar)
 575.142 +{
 575.143 +	scalar_t *mptr = mat.m[0];
 575.144 +
 575.145 +	for(int i=0; i<9; i++) {
 575.146 +		*mptr++ *= scalar;
 575.147 +	}
 575.148 +}
 575.149 +
 575.150 +void Matrix3x3::translate(const Vector2 &trans)
 575.151 +{
 575.152 +	Matrix3x3 tmat(1, 0, trans.x, 0, 1, trans.y, 0, 0, 1);
 575.153 +	*this *= tmat;
 575.154 +}
 575.155 +
 575.156 +void Matrix3x3::set_translation(const Vector2 &trans)
 575.157 +{
 575.158 +	*this = Matrix3x3(1, 0, trans.x, 0, 1, trans.y, 0, 0, 1);
 575.159 +}
 575.160 +
 575.161 +void Matrix3x3::rotate(scalar_t angle)
 575.162 +{
 575.163 +	scalar_t cos_a = cos(angle);
 575.164 +	scalar_t sin_a = sin(angle);
 575.165 +	Matrix3x3 rmat(	cos_a,	-sin_a,		0,
 575.166 +					sin_a,	cos_a,		0,
 575.167 +					0,		0,			1);
 575.168 +	*this *= rmat;
 575.169 +}
 575.170 +
 575.171 +void Matrix3x3::set_rotation(scalar_t angle)
 575.172 +{
 575.173 +	scalar_t cos_a = cos(angle);
 575.174 +	scalar_t sin_a = sin(angle);
 575.175 +	*this = Matrix3x3(cos_a, -sin_a, 0, sin_a, cos_a, 0, 0, 0, 1);
 575.176 +}
 575.177 +
 575.178 +void Matrix3x3::rotate(const Vector3 &euler_angles)
 575.179 +{
 575.180 +	Matrix3x3 xrot, yrot, zrot;
 575.181 +
 575.182 +	xrot = Matrix3x3(	1,			0,					0,
 575.183 +						0,	cos(euler_angles.x),	-sin(euler_angles.x),
 575.184 +						0,	sin(euler_angles.x),	cos(euler_angles.x));
 575.185 +
 575.186 +	yrot = Matrix3x3(	cos(euler_angles.y),	0,	sin(euler_angles.y),
 575.187 +								0,				1,				0,
 575.188 +						-sin(euler_angles.y),	0,	cos(euler_angles.y));
 575.189 +
 575.190 +	zrot = Matrix3x3(	cos(euler_angles.z),	-sin(euler_angles.z),	0,
 575.191 +						sin(euler_angles.z),	cos(euler_angles.z),	0,
 575.192 +								0,						0,				1);
 575.193 +
 575.194 +	*this *= xrot * yrot * zrot;
 575.195 +}
 575.196 +
 575.197 +void Matrix3x3::set_rotation(const Vector3 &euler_angles)
 575.198 +{
 575.199 +	Matrix3x3 xrot, yrot, zrot;
 575.200 +
 575.201 +	xrot = Matrix3x3(	1,			0,					0,
 575.202 +						0,	cos(euler_angles.x),	-sin(euler_angles.x),
 575.203 +						0,	sin(euler_angles.x),	cos(euler_angles.x));
 575.204 +
 575.205 +	yrot = Matrix3x3(	cos(euler_angles.y),	0,	sin(euler_angles.y),
 575.206 +								0,				1,				0,
 575.207 +						-sin(euler_angles.y),	0,	cos(euler_angles.y));
 575.208 +
 575.209 +	zrot = Matrix3x3(	cos(euler_angles.z),	-sin(euler_angles.z),	0,
 575.210 +						sin(euler_angles.z),	cos(euler_angles.z),	0,
 575.211 +								0,						0,				1);
 575.212 +
 575.213 +	*this = xrot * yrot * zrot;
 575.214 +}
 575.215 +
 575.216 +void Matrix3x3::rotate(const Vector3 &axis, scalar_t angle)
 575.217 +{
 575.218 +	scalar_t sina = (scalar_t)sin(angle);
 575.219 +	scalar_t cosa = (scalar_t)cos(angle);
 575.220 +	scalar_t invcosa = 1-cosa;
 575.221 +	scalar_t nxsq = axis.x * axis.x;
 575.222 +	scalar_t nysq = axis.y * axis.y;
 575.223 +	scalar_t nzsq = axis.z * axis.z;
 575.224 +
 575.225 +	Matrix3x3 xform;
 575.226 +	xform.m[0][0] = nxsq + (1-nxsq) * cosa;
 575.227 +	xform.m[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
 575.228 +	xform.m[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
 575.229 +
 575.230 +	xform.m[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
 575.231 +	xform.m[1][1] = nysq + (1-nysq) * cosa;
 575.232 +	xform.m[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
 575.233 +
 575.234 +	xform.m[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
 575.235 +	xform.m[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
 575.236 +	xform.m[2][2] = nzsq + (1-nzsq) * cosa;
 575.237 +
 575.238 +	*this *= xform;
 575.239 +}
 575.240 +
 575.241 +void Matrix3x3::set_rotation(const Vector3 &axis, scalar_t angle)
 575.242 +{
 575.243 +	scalar_t sina = (scalar_t)sin(angle);
 575.244 +	scalar_t cosa = (scalar_t)cos(angle);
 575.245 +	scalar_t invcosa = 1-cosa;
 575.246 +	scalar_t nxsq = axis.x * axis.x;
 575.247 +	scalar_t nysq = axis.y * axis.y;
 575.248 +	scalar_t nzsq = axis.z * axis.z;
 575.249 +
 575.250 +	reset_identity();
 575.251 +	m[0][0] = nxsq + (1-nxsq) * cosa;
 575.252 +	m[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
 575.253 +	m[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
 575.254 +	m[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
 575.255 +	m[1][1] = nysq + (1-nysq) * cosa;
 575.256 +	m[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
 575.257 +	m[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
 575.258 +	m[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
 575.259 +	m[2][2] = nzsq + (1-nzsq) * cosa;
 575.260 +}
 575.261 +
 575.262 +// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
 575.263 +// article "Quaternion Calculus and Fast Animation".
 575.264 +// adapted from: http://www.geometrictools.com/LibMathematics/Algebra/Wm5Quaternion.inl
 575.265 +Quaternion Matrix3x3::get_rotation_quat() const
 575.266 +{
 575.267 +	static const int next[3] = {1, 2, 0};
 575.268 +
 575.269 +	float quat[4];
 575.270 +
 575.271 +	scalar_t trace = m[0][0] + m[1][1] + m[2][2];
 575.272 +	scalar_t root;
 575.273 +
 575.274 +	if(trace > 0.0f) {
 575.275 +		// |w| > 1/2
 575.276 +		root = sqrt(trace + 1.0f);	// 2w
 575.277 +		quat[0] = 0.5f * root;
 575.278 +		root = 0.5f / root;	// 1 / 4w
 575.279 +		quat[1] = (m[2][1] - m[1][2]) * root;
 575.280 +		quat[2] = (m[0][2] - m[2][0]) * root;
 575.281 +		quat[3] = (m[1][0] - m[0][1]) * root;
 575.282 +	} else {
 575.283 +		// |w| <= 1/2
 575.284 +		int i = 0;
 575.285 +		if(m[1][1] > m[0][0]) {
 575.286 +			i = 1;
 575.287 +		}
 575.288 +		if(m[2][2] > m[i][i]) {
 575.289 +			i = 2;
 575.290 +		}
 575.291 +		int j = next[i];
 575.292 +		int k = next[j];
 575.293 +
 575.294 +		root = sqrt(m[i][i] - m[j][j] - m[k][k] + 1.0f);
 575.295 +		quat[i + 1] = 0.5f * root;
 575.296 +		root = 0.5f / root;
 575.297 +		quat[0] = (m[k][j] - m[j][k]) * root;
 575.298 +		quat[j + 1] = (m[j][i] - m[i][j]) * root;
 575.299 +		quat[k + 1] = (m[k][i] - m[i][k]) * root;
 575.300 +	}
 575.301 +	return Quaternion(quat[0], quat[1], quat[2], quat[3]);
 575.302 +}
 575.303 +
 575.304 +void Matrix3x3::scale(const Vector3 &scale_vec)
 575.305 +{
 575.306 +	Matrix3x3 smat(	scale_vec.x, 0, 0,
 575.307 +					0, scale_vec.y, 0,
 575.308 +					0, 0, scale_vec.z);
 575.309 +	*this *= smat;
 575.310 +}
 575.311 +
 575.312 +void Matrix3x3::set_scaling(const Vector3 &scale_vec)
 575.313 +{
 575.314 +	*this = Matrix3x3(	scale_vec.x, 0, 0,
 575.315 +						0, scale_vec.y, 0,
 575.316 +						0, 0, scale_vec.z);
 575.317 +}
 575.318 +
 575.319 +void Matrix3x3::set_column_vector(const Vector3 &vec, unsigned int col_index)
 575.320 +{
 575.321 +	m[0][col_index] = vec.x;
 575.322 +	m[1][col_index] = vec.y;
 575.323 +	m[2][col_index] = vec.z;
 575.324 +}
 575.325 +
 575.326 +void Matrix3x3::set_row_vector(const Vector3 &vec, unsigned int row_index)
 575.327 +{
 575.328 +	m[row_index][0] = vec.x;
 575.329 +	m[row_index][1] = vec.y;
 575.330 +	m[row_index][2] = vec.z;
 575.331 +}
 575.332 +
 575.333 +Vector3 Matrix3x3::get_column_vector(unsigned int col_index) const
 575.334 +{
 575.335 +	return Vector3(m[0][col_index], m[1][col_index], m[2][col_index]);
 575.336 +}
 575.337 +
 575.338 +Vector3 Matrix3x3::get_row_vector(unsigned int row_index) const
 575.339 +{
 575.340 +	return Vector3(m[row_index][0], m[row_index][1], m[row_index][2]);
 575.341 +}
 575.342 +
 575.343 +void Matrix3x3::transpose()
 575.344 +{
 575.345 +	Matrix3x3 tmp = *this;
 575.346 +	for(int i=0; i<3; i++) {
 575.347 +		for(int j=0; j<3; j++) {
 575.348 +			m[i][j] = tmp[j][i];
 575.349 +		}
 575.350 +	}
 575.351 +}
 575.352 +
 575.353 +Matrix3x3 Matrix3x3::transposed() const
 575.354 +{
 575.355 +	Matrix3x3 res;
 575.356 +	for(int i=0; i<3; i++) {
 575.357 +		for(int j=0; j<3; j++) {
 575.358 +			res[i][j] = m[j][i];
 575.359 +		}
 575.360 +	}
 575.361 +	return res;
 575.362 +}
 575.363 +
 575.364 +scalar_t Matrix3x3::determinant() const
 575.365 +{
 575.366 +	return	m[0][0] * (m[1][1]*m[2][2] - m[1][2]*m[2][1]) -
 575.367 +			m[0][1] * (m[1][0]*m[2][2] - m[1][2]*m[2][0]) +
 575.368 +			m[0][2] * (m[1][0]*m[2][1] - m[1][1]*m[2][0]);
 575.369 +}
 575.370 +
 575.371 +Matrix3x3 Matrix3x3::inverse() const
 575.372 +{
 575.373 +	// TODO: implement 3x3 inverse
 575.374 +	return *this;
 575.375 +}
 575.376 +
 575.377 +ostream &operator <<(ostream &out, const Matrix3x3 &mat)
 575.378 +{
 575.379 +	for(int i=0; i<3; i++) {
 575.380 +		char str[100];
 575.381 +		sprintf(str, "[ %12.5f %12.5f %12.5f ]\n", (float)mat.m[i][0], (float)mat.m[i][1], (float)mat.m[i][2]);
 575.382 +		out << str;
 575.383 +	}
 575.384 +	return out;
 575.385 +}
 575.386 +
 575.387 +
 575.388 +
 575.389 +/* ----------------- Matrix4x4 implementation --------------- */
 575.390 +
 575.391 +Matrix4x4 Matrix4x4::identity = Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
 575.392 +
 575.393 +Matrix4x4::Matrix4x4()
 575.394 +{
 575.395 +	*this = Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
 575.396 +}
 575.397 +
 575.398 +Matrix4x4::Matrix4x4(	scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14,
 575.399 +						scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24,
 575.400 +						scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34,
 575.401 +						scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44)
 575.402 +{
 575.403 +	m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14;
 575.404 +	m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24;
 575.405 +	m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34;
 575.406 +	m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44;
 575.407 +}
 575.408 +
 575.409 +Matrix4x4::Matrix4x4(const mat4_t cmat)
 575.410 +{
 575.411 +	memcpy(m, cmat, sizeof(mat4_t));
 575.412 +}
 575.413 +
 575.414 +Matrix4x4::Matrix4x4(const Matrix3x3 &mat3x3)
 575.415 +{
 575.416 +	reset_identity();
 575.417 +	for(int i=0; i<3; i++) {
 575.418 +		for(int j=0; j<3; j++) {
 575.419 +			m[i][j] = mat3x3[i][j];
 575.420 +		}
 575.421 +	}
 575.422 +}
 575.423 +
 575.424 +Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2)
 575.425 +{
 575.426 +	Matrix4x4 res;
 575.427 +	const scalar_t *op1 = m1.m[0], *op2 = m2.m[0];
 575.428 +	scalar_t *dest = res.m[0];
 575.429 +
 575.430 +	for(int i=0; i<16; i++) {
 575.431 +		*dest++ = *op1++ + *op2++;
 575.432 +	}
 575.433 +	return res;
 575.434 +}
 575.435 +
 575.436 +Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2)
 575.437 +{
 575.438 +	Matrix4x4 res;
 575.439 +	const scalar_t *op1 = m1.m[0], *op2 = m2.m[0];
 575.440 +	scalar_t *dest = res.m[0];
 575.441 +
 575.442 +	for(int i=0; i<16; i++) {
 575.443 +		*dest++ = *op1++ - *op2++;
 575.444 +	}
 575.445 +	return res;
 575.446 +}
 575.447 +
 575.448 +void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2)
 575.449 +{
 575.450 +	scalar_t *op1 = m1.m[0];
 575.451 +	const scalar_t *op2 = m2.m[0];
 575.452 +
 575.453 +	for(int i=0; i<16; i++) {
 575.454 +		*op1++ += *op2++;
 575.455 +	}
 575.456 +}
 575.457 +
 575.458 +void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2)
 575.459 +{
 575.460 +	scalar_t *op1 = m1.m[0];
 575.461 +	const scalar_t *op2 = m2.m[0];
 575.462 +
 575.463 +	for(int i=0; i<16; i++) {
 575.464 +		*op1++ -= *op2++;
 575.465 +	}
 575.466 +}
 575.467 +
 575.468 +Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar)
 575.469 +{
 575.470 +	Matrix4x4 res;
 575.471 +	const scalar_t *mptr = mat.m[0];
 575.472 +	scalar_t *dptr = res.m[0];
 575.473 +
 575.474 +	for(int i=0; i<16; i++) {
 575.475 +		*dptr++ = *mptr++ * scalar;
 575.476 +	}
 575.477 +	return res;
 575.478 +}
 575.479 +
 575.480 +Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat)
 575.481 +{
 575.482 +	Matrix4x4 res;
 575.483 +	const scalar_t *mptr = mat.m[0];
 575.484 +	scalar_t *dptr = res.m[0];
 575.485 +
 575.486 +	for(int i=0; i<16; i++) {
 575.487 +		*dptr++ = *mptr++ * scalar;
 575.488 +	}
 575.489 +	return res;
 575.490 +}
 575.491 +
 575.492 +void operator *=(Matrix4x4 &mat, scalar_t scalar)
 575.493 +{
 575.494 +	scalar_t *mptr = mat.m[0];
 575.495 +
 575.496 +	for(int i=0; i<16; i++) {
 575.497 +		*mptr++ *= scalar;
 575.498 +	}
 575.499 +}
 575.500 +
 575.501 +void Matrix4x4::translate(const Vector3 &trans)
 575.502 +{
 575.503 +	Matrix4x4 tmat(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1);
 575.504 +	*this *= tmat;
 575.505 +}
 575.506 +
 575.507 +void Matrix4x4::set_translation(const Vector3 &trans)
 575.508 +{
 575.509 +	*this = Matrix4x4(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1);
 575.510 +}
 575.511 +
 575.512 +Vector3 Matrix4x4::get_translation() const
 575.513 +{
 575.514 +	return Vector3(m[0][3], m[1][3], m[2][3]);
 575.515 +}
 575.516 +
 575.517 +void Matrix4x4::rotate(const Vector3 &euler_angles)
 575.518 +{
 575.519 +	Matrix3x3 xrot, yrot, zrot;
 575.520 +
 575.521 +	xrot = Matrix3x3(	1,			0,					0,
 575.522 +						0,	cos(euler_angles.x),	-sin(euler_angles.x),
 575.523 +						0,	sin(euler_angles.x),	cos(euler_angles.x));
 575.524 +
 575.525 +	yrot = Matrix3x3(	cos(euler_angles.y),	0,	sin(euler_angles.y),
 575.526 +								0,				1,				0,
 575.527 +						-sin(euler_angles.y),	0,	cos(euler_angles.y));
 575.528 +
 575.529 +	zrot = Matrix3x3(	cos(euler_angles.z),	-sin(euler_angles.z),	0,
 575.530 +						sin(euler_angles.z),	cos(euler_angles.z),	0,
 575.531 +								0,						0,				1);
 575.532 +
 575.533 +	*this *= Matrix4x4(xrot * yrot * zrot);
 575.534 +}
 575.535 +
 575.536 +void Matrix4x4::set_rotation(const Vector3 &euler_angles)
 575.537 +{
 575.538 +	Matrix3x3 xrot, yrot, zrot;
 575.539 +
 575.540 +	xrot = Matrix3x3(	1,			0,					0,
 575.541 +						0,	cos(euler_angles.x),	-sin(euler_angles.x),
 575.542 +						0,	sin(euler_angles.x),	cos(euler_angles.x));
 575.543 +
 575.544 +	yrot = Matrix3x3(	cos(euler_angles.y),	0,	sin(euler_angles.y),
 575.545 +								0,				1,				0,
 575.546 +						-sin(euler_angles.y),	0,	cos(euler_angles.y));
 575.547 +
 575.548 +	zrot = Matrix3x3(	cos(euler_angles.z),	-sin(euler_angles.z),	0,
 575.549 +						sin(euler_angles.z),	cos(euler_angles.z),	0,
 575.550 +								0,						0,				1);
 575.551 +
 575.552 +	*this = Matrix4x4(xrot * yrot * zrot);
 575.553 +}
 575.554 +
 575.555 +void Matrix4x4::rotate(const Vector3 &axis, scalar_t angle)
 575.556 +{
 575.557 +	scalar_t sina = (scalar_t)sin(angle);
 575.558 +	scalar_t cosa = (scalar_t)cos(angle);
 575.559 +	scalar_t invcosa = 1-cosa;
 575.560 +	scalar_t nxsq = axis.x * axis.x;
 575.561 +	scalar_t nysq = axis.y * axis.y;
 575.562 +	scalar_t nzsq = axis.z * axis.z;
 575.563 +
 575.564 +	Matrix4x4 xform;
 575.565 +	xform[0][0] = nxsq + (1-nxsq) * cosa;
 575.566 +	xform[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
 575.567 +	xform[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
 575.568 +	xform[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
 575.569 +	xform[1][1] = nysq + (1-nysq) * cosa;
 575.570 +	xform[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
 575.571 +	xform[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
 575.572 +	xform[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
 575.573 +	xform[2][2] = nzsq + (1-nzsq) * cosa;
 575.574 +
 575.575 +	*this *= xform;
 575.576 +}
 575.577 +
 575.578 +void Matrix4x4::set_rotation(const Vector3 &axis, scalar_t angle)
 575.579 +{
 575.580 +	scalar_t sina = (scalar_t)sin(angle);
 575.581 +	scalar_t cosa = (scalar_t)cos(angle);
 575.582 +	scalar_t invcosa = 1-cosa;
 575.583 +	scalar_t nxsq = axis.x * axis.x;
 575.584 +	scalar_t nysq = axis.y * axis.y;
 575.585 +	scalar_t nzsq = axis.z * axis.z;
 575.586 +
 575.587 +	reset_identity();
 575.588 +	m[0][0] = nxsq + (1-nxsq) * cosa;
 575.589 +	m[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
 575.590 +	m[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
 575.591 +	m[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
 575.592 +	m[1][1] = nysq + (1-nysq) * cosa;
 575.593 +	m[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
 575.594 +	m[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
 575.595 +	m[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
 575.596 +	m[2][2] = nzsq + (1-nzsq) * cosa;
 575.597 +}
 575.598 +
 575.599 +void Matrix4x4::rotate(const Quaternion &quat)
 575.600 +{
 575.601 +	*this *= quat.get_rotation_matrix();
 575.602 +}
 575.603 +
 575.604 +void Matrix4x4::set_rotation(const Quaternion &quat)
 575.605 +{
 575.606 +	*this = quat.get_rotation_matrix();
 575.607 +}
 575.608 +
 575.609 +Quaternion Matrix4x4::get_rotation_quat() const
 575.610 +{
 575.611 +	Matrix3x3 mat3 = *this;
 575.612 +	return mat3.get_rotation_quat();
 575.613 +}
 575.614 +
 575.615 +void Matrix4x4::scale(const Vector4 &scale_vec)
 575.616 +{
 575.617 +	Matrix4x4 smat(	scale_vec.x, 0, 0, 0,
 575.618 +					0, scale_vec.y, 0, 0,
 575.619 +					0, 0, scale_vec.z, 0,
 575.620 +					0, 0, 0, scale_vec.w);
 575.621 +	*this *= smat;
 575.622 +}
 575.623 +
 575.624 +void Matrix4x4::set_scaling(const Vector4 &scale_vec)
 575.625 +{
 575.626 +	*this = Matrix4x4(	scale_vec.x, 0, 0, 0,
 575.627 +						0, scale_vec.y, 0, 0,
 575.628 +						0, 0, scale_vec.z, 0,
 575.629 +						0, 0, 0, scale_vec.w);
 575.630 +}
 575.631 +
 575.632 +Vector3 Matrix4x4::get_scaling() const
 575.633 +{
 575.634 +	Vector3 vi = get_row_vector(0);
 575.635 +	Vector3 vj = get_row_vector(1);
 575.636 +	Vector3 vk = get_row_vector(2);
 575.637 +
 575.638 +	return Vector3(vi.length(), vj.length(), vk.length());
 575.639 +}
 575.640 +
 575.641 +void Matrix4x4::set_frustum(float left, float right, float bottom, float top, float znear, float zfar)
 575.642 +{
 575.643 +	float dx = right - left;
 575.644 +	float dy = top - bottom;
 575.645 +	float dz = zfar - znear;
 575.646 +
 575.647 +	float a = (right + left) / dx;
 575.648 +	float b = (top + bottom) / dy;
 575.649 +	float c = -(zfar + znear) / dz;
 575.650 +	float d = -2.0 * zfar * znear / dz;
 575.651 +
 575.652 +	*this = Matrix4x4(2.0 * znear / dx, 0, a, 0,
 575.653 +			0, 2.0 * znear / dy, b, 0,
 575.654 +			0, 0, c, d,
 575.655 +			0, 0, -1, 0);
 575.656 +}
 575.657 +
 575.658 +void Matrix4x4::set_perspective(float vfov, float aspect, float znear, float zfar)
 575.659 +{
 575.660 +	float f = 1.0f / tan(vfov * 0.5f);
 575.661 +    float dz = znear - zfar;
 575.662 +
 575.663 +	reset_identity();
 575.664 +
 575.665 +	m[0][0] = f / aspect;
 575.666 +    m[1][1] = f;
 575.667 +    m[2][2] = (zfar + znear) / dz;
 575.668 +    m[3][2] = -1.0f;
 575.669 +    m[2][3] = 2.0f * zfar * znear / dz;
 575.670 +    m[3][3] = 0.0f;
 575.671 +}
 575.672 +
 575.673 +void Matrix4x4::set_orthographic(float left, float right, float bottom, float top, float znear, float zfar)
 575.674 +{
 575.675 +	float dx = right - left;
 575.676 +	float dy = top - bottom;
 575.677 +	float dz = zfar - znear;
 575.678 +
 575.679 +	reset_identity();
 575.680 +
 575.681 +	m[0][0] = 2.0 / dx;
 575.682 +	m[1][1] = 2.0 / dy;
 575.683 +	m[2][2] = -2.0 / dz;
 575.684 +	m[0][3] = -(right + left) / dx;
 575.685 +	m[1][3] = -(top + bottom) / dy;
 575.686 +	m[2][3] = -(zfar + znear) / dz;
 575.687 +}
 575.688 +
 575.689 +void Matrix4x4::set_lookat(const Vector3 &pos, const Vector3 &targ, const Vector3 &up)
 575.690 +{
 575.691 +	Vector3 vk = (targ - pos).normalized();
 575.692 +	Vector3 vj = up.normalized();
 575.693 +	Vector3 vi = cross_product(vk, vj).normalized();
 575.694 +	vj = cross_product(vi, vk);
 575.695 +
 575.696 +	*this = Matrix4x4(
 575.697 +			vi.x, vi.y, vi.z, 0,
 575.698 +			vj.x, vj.y, vj.z, 0,
 575.699 +			-vk.x, -vk.y, -vk.z, 0,
 575.700 +			0, 0, 0, 1);
 575.701 +	translate(-pos);
 575.702 +}
 575.703 +
 575.704 +void Matrix4x4::set_column_vector(const Vector4 &vec, unsigned int col_index)
 575.705 +{
 575.706 +	m[0][col_index] = vec.x;
 575.707 +	m[1][col_index] = vec.y;
 575.708 +	m[2][col_index] = vec.z;
 575.709 +	m[3][col_index] = vec.w;
 575.710 +}
 575.711 +
 575.712 +void Matrix4x4::set_row_vector(const Vector4 &vec, unsigned int row_index)
 575.713 +{
 575.714 +	m[row_index][0] = vec.x;
 575.715 +	m[row_index][1] = vec.y;
 575.716 +	m[row_index][2] = vec.z;
 575.717 +	m[row_index][3] = vec.w;
 575.718 +}
 575.719 +
 575.720 +Vector4 Matrix4x4::get_column_vector(unsigned int col_index) const
 575.721 +{
 575.722 +	return Vector4(m[0][col_index], m[1][col_index], m[2][col_index], m[3][col_index]);
 575.723 +}
 575.724 +
 575.725 +Vector4 Matrix4x4::get_row_vector(unsigned int row_index) const
 575.726 +{
 575.727 +	return Vector4(m[row_index][0], m[row_index][1], m[row_index][2], m[row_index][3]);
 575.728 +}
 575.729 +
 575.730 +void Matrix4x4::transpose()
 575.731 +{
 575.732 +	Matrix4x4 tmp = *this;
 575.733 +	for(int i=0; i<4; i++) {
 575.734 +		for(int j=0; j<4; j++) {
 575.735 +			m[i][j] = tmp[j][i];
 575.736 +		}
 575.737 +	}
 575.738 +}
 575.739 +
 575.740 +Matrix4x4 Matrix4x4::transposed() const
 575.741 +{
 575.742 +	Matrix4x4 res;
 575.743 +	for(int i=0; i<4; i++) {
 575.744 +		for(int j=0; j<4; j++) {
 575.745 +			res[i][j] = m[j][i];
 575.746 +		}
 575.747 +	}
 575.748 +	return res;
 575.749 +}
 575.750 +
 575.751 +scalar_t Matrix4x4::determinant() const
 575.752 +{
 575.753 +	scalar_t det11 =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 575.754 +						(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
 575.755 +						(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
 575.756 +
 575.757 +	scalar_t det12 =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 575.758 +						(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 575.759 +						(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
 575.760 +
 575.761 +	scalar_t det13 =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
 575.762 +						(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 575.763 +						(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 575.764 +
 575.765 +	scalar_t det14 =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
 575.766 +						(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
 575.767 +						(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 575.768 +
 575.769 +	return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14;
 575.770 +}
 575.771 +
 575.772 +
 575.773 +Matrix4x4 Matrix4x4::adjoint() const
 575.774 +{
 575.775 +	Matrix4x4 coef;
 575.776 +
 575.777 +	coef.m[0][0] =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 575.778 +					(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
 575.779 +					(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
 575.780 +	coef.m[0][1] =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 575.781 +					(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 575.782 +					(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
 575.783 +	coef.m[0][2] =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
 575.784 +					(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 575.785 +					(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 575.786 +	coef.m[0][3] =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
 575.787 +					(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
 575.788 +					(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 575.789 +
 575.790 +	coef.m[1][0] =	(m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 575.791 +					(m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
 575.792 +					(m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
 575.793 +	coef.m[1][1] =	(m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 575.794 +					(m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 575.795 +					(m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
 575.796 +	coef.m[1][2] =	(m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
 575.797 +					(m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 575.798 +					(m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 575.799 +	coef.m[1][3] =	(m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
 575.800 +					(m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
 575.801 +					(m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 575.802 +
 575.803 +	coef.m[2][0] =	(m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
 575.804 +					(m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) +
 575.805 +					(m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2]));
 575.806 +	coef.m[2][1] =	(m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
 575.807 +					(m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
 575.808 +					(m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2]));
 575.809 +	coef.m[2][2] =	(m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) -
 575.810 +					(m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
 575.811 +					(m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
 575.812 +	coef.m[2][3] =	(m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) -
 575.813 +					(m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) +
 575.814 +					(m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
 575.815 +
 575.816 +	coef.m[3][0] =	(m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
 575.817 +					(m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) +
 575.818 +					(m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]));
 575.819 +	coef.m[3][1] =	(m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
 575.820 +					(m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
 575.821 +					(m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2]));
 575.822 +	coef.m[3][2] =	(m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) -
 575.823 +					(m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
 575.824 +					(m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
 575.825 +	coef.m[3][3] =	(m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) -
 575.826 +					(m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) +
 575.827 +					(m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
 575.828 +
 575.829 +	coef.transpose();
 575.830 +
 575.831 +	for(int i=0; i<4; i++) {
 575.832 +		for(int j=0; j<4; j++) {
 575.833 +			coef.m[i][j] = j%2 ? -coef.m[i][j] : coef.m[i][j];
 575.834 +			if(i%2) coef.m[i][j] = -coef.m[i][j];
 575.835 +		}
 575.836 +	}
 575.837 +
 575.838 +	return coef;
 575.839 +}
 575.840 +
 575.841 +Matrix4x4 Matrix4x4::inverse() const
 575.842 +{
 575.843 +	Matrix4x4 adj = adjoint();
 575.844 +
 575.845 +	return adj * (1.0f / determinant());
 575.846 +}
 575.847 +
 575.848 +ostream &operator <<(ostream &out, const Matrix4x4 &mat)
 575.849 +{
 575.850 +	for(int i=0; i<4; i++) {
 575.851 +		char str[100];
 575.852 +		sprintf(str, "[ %12.5f %12.5f %12.5f %12.5f ]\n", (float)mat.m[i][0], (float)mat.m[i][1], (float)mat.m[i][2], (float)mat.m[i][3]);
 575.853 +		out << str;
 575.854 +	}
 575.855 +	return out;
 575.856 +}
   576.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   576.2 +++ b/libs/vmath/matrix.h	Sat Feb 01 19:58:19 2014 +0200
   576.3 @@ -0,0 +1,264 @@
   576.4 +/*
   576.5 +libvmath - a vector math library
   576.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   576.7 +
   576.8 +This program is free software: you can redistribute it and/or modify
   576.9 +it under the terms of the GNU Lesser General Public License as published
  576.10 +by the Free Software Foundation, either version 3 of the License, or
  576.11 +(at your option) any later version.
  576.12 +
  576.13 +This program is distributed in the hope that it will be useful,
  576.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  576.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  576.16 +GNU Lesser General Public License for more details.
  576.17 +
  576.18 +You should have received a copy of the GNU Lesser General Public License
  576.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  576.20 +*/
  576.21 +
  576.22 +#ifndef VMATH_MATRIX_H_
  576.23 +#define VMATH_MATRIX_H_
  576.24 +
  576.25 +#include <stdio.h>
  576.26 +#include "vmath_types.h"
  576.27 +#include "vector.h"
  576.28 +
  576.29 +#ifdef __cplusplus
  576.30 +extern "C" {
  576.31 +#endif	/* __cplusplus */
  576.32 +
  576.33 +/* C matrix 3x3 functions */
  576.34 +static inline void m3_identity(mat3_t m);
  576.35 +static inline void m3_cons(mat3_t m,
  576.36 +		scalar_t m11, scalar_t m12, scalar_t m13,
  576.37 +		scalar_t m21, scalar_t m22, scalar_t m23,
  576.38 +		scalar_t m31, scalar_t m32, scalar_t m33);
  576.39 +static inline void m3_copy(mat3_t dest, mat3_t src);
  576.40 +void m3_to_m4(mat4_t dest, mat3_t src);
  576.41 +
  576.42 +void m3_print(FILE *fp, mat3_t m);
  576.43 +
  576.44 +/* C matrix 4x4 functions */
  576.45 +static inline void m4_identity(mat4_t m);
  576.46 +static inline void m4_cons(mat4_t m,
  576.47 +		scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14,
  576.48 +		scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24,
  576.49 +		scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34,
  576.50 +		scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44);
  576.51 +static inline void m4_copy(mat4_t dest, mat4_t src);
  576.52 +void m4_to_m3(mat3_t dest, mat4_t src);
  576.53 +
  576.54 +static inline void m4_mult(mat4_t res, mat4_t m1, mat4_t m2);
  576.55 +
  576.56 +void m4_set_translation(mat4_t m, scalar_t x, scalar_t y, scalar_t z);
  576.57 +void m4_translate(mat4_t m, scalar_t x, scalar_t y, scalar_t z);
  576.58 +
  576.59 +void m4_rotate(mat4_t m, scalar_t x, scalar_t y, scalar_t z);
  576.60 +
  576.61 +void m4_set_rotation_x(mat4_t m, scalar_t angle);
  576.62 +void m4_rotate_x(mat4_t m, scalar_t angle);
  576.63 +void m4_set_rotation_y(mat4_t m, scalar_t angle);
  576.64 +void m4_rotate_y(mat4_t m, scalar_t angle);
  576.65 +void m4_set_rotation_z(mat4_t m, scalar_t angle);
  576.66 +void m4_rotate_z(mat4_t m, scalar_t angle);
  576.67 +/* axis-angle rotation */
  576.68 +void m4_set_rotation_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z);
  576.69 +void m4_rotate_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z);
  576.70 +/* concatentate a rotation quaternion */
  576.71 +void m4_rotate_quat(mat4_t m, quat_t q);
  576.72 +
  576.73 +void m4_set_scaling(mat4_t m, scalar_t x, scalar_t y, scalar_t z);
  576.74 +void m4_scale(mat4_t m, scalar_t x, scalar_t y, scalar_t z);
  576.75 +
  576.76 +static inline void m4_set_column(mat4_t m, vec4_t v, int idx);
  576.77 +static inline void m4_set_row(mat4_t m, vec4_t v, int idx);
  576.78 +
  576.79 +void m4_transpose(mat4_t res, mat4_t m);
  576.80 +scalar_t m4_determinant(mat4_t m);
  576.81 +void m4_adjoint(mat4_t res, mat4_t m);
  576.82 +void m4_inverse(mat4_t res, mat4_t m);
  576.83 +
  576.84 +void m4_print(FILE *fp, mat4_t m);
  576.85 +
  576.86 +#ifdef __cplusplus
  576.87 +}
  576.88 +
  576.89 +/* when included from C++ source files, also define the matrix classes */
  576.90 +#include <iostream>
  576.91 +
  576.92 +/** 3x3 matrix */
  576.93 +class Matrix3x3 {
  576.94 +public:
  576.95 +	scalar_t m[3][3];
  576.96 +
  576.97 +	static Matrix3x3 identity;
  576.98 +
  576.99 +	Matrix3x3();
 576.100 +	Matrix3x3(	scalar_t m11, scalar_t m12, scalar_t m13,
 576.101 +				scalar_t m21, scalar_t m22, scalar_t m23,
 576.102 +				scalar_t m31, scalar_t m32, scalar_t m33);
 576.103 +	Matrix3x3(const Vector3 &ivec, const Vector3 &jvec, const Vector3 &kvec);
 576.104 +	Matrix3x3(const mat3_t cmat);
 576.105 +
 576.106 +	Matrix3x3(const Matrix4x4 &mat4x4);
 576.107 +
 576.108 +	/* binary operations matrix (op) matrix */
 576.109 +	friend Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2);
 576.110 +	friend Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2);
 576.111 +	friend Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2);
 576.112 +
 576.113 +	friend void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2);
 576.114 +	friend void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2);
 576.115 +	friend void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2);
 576.116 +
 576.117 +	/* binary operations matrix (op) scalar and scalar (op) matrix */
 576.118 +	friend Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar);
 576.119 +	friend Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat);
 576.120 +
 576.121 +	friend void operator *=(Matrix3x3 &mat, scalar_t scalar);
 576.122 +
 576.123 +	inline scalar_t *operator [](int index);
 576.124 +	inline const scalar_t *operator [](int index) const;
 576.125 +
 576.126 +	inline void reset_identity();
 576.127 +
 576.128 +	void translate(const Vector2 &trans);
 576.129 +	void set_translation(const Vector2 &trans);
 576.130 +
 576.131 +	void rotate(scalar_t angle);						/* 2d rotation */
 576.132 +	void rotate(const Vector3 &euler_angles);			/* 3d rotation with euler angles */
 576.133 +	void rotate(const Vector3 &axis, scalar_t angle);	/* 3d axis/angle rotation */
 576.134 +	void set_rotation(scalar_t angle);
 576.135 +	void set_rotation(const Vector3 &euler_angles);
 576.136 +	void set_rotation(const Vector3 &axis, scalar_t angle);
 576.137 +	Quaternion get_rotation_quat() const;
 576.138 +
 576.139 +	void scale(const Vector3 &scale_vec);
 576.140 +	void set_scaling(const Vector3 &scale_vec);
 576.141 +
 576.142 +	void set_column_vector(const Vector3 &vec, unsigned int col_index);
 576.143 +	void set_row_vector(const Vector3 &vec, unsigned int row_index);
 576.144 +	Vector3 get_column_vector(unsigned int col_index) const;
 576.145 +	Vector3 get_row_vector(unsigned int row_index) const;
 576.146 +
 576.147 +	void transpose();
 576.148 +	Matrix3x3 transposed() const;
 576.149 +	scalar_t determinant() const;
 576.150 +	Matrix3x3 inverse() const;
 576.151 +
 576.152 +	friend std::ostream &operator <<(std::ostream &out, const Matrix3x3 &mat);
 576.153 +};
 576.154 +
 576.155 +/* binary operations matrix (op) matrix */
 576.156 +Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2);
 576.157 +Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2);
 576.158 +Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2);
 576.159 +
 576.160 +void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2);
 576.161 +void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2);
 576.162 +void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2);
 576.163 +
 576.164 +/* binary operations matrix (op) scalar and scalar (op) matrix */
 576.165 +Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar);
 576.166 +Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat);
 576.167 +
 576.168 +void operator *=(Matrix3x3 &mat, scalar_t scalar);
 576.169 +
 576.170 +std::ostream &operator <<(std::ostream &out, const Matrix3x3 &mat);
 576.171 +
 576.172 +
 576.173 +
 576.174 +/** 4x4 matrix */
 576.175 +class Matrix4x4 {
 576.176 +public:
 576.177 +	scalar_t m[4][4];
 576.178 +
 576.179 +	static Matrix4x4 identity;
 576.180 +
 576.181 +	Matrix4x4();
 576.182 +	Matrix4x4(	scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14,
 576.183 +				scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24,
 576.184 +				scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34,
 576.185 +				scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44);
 576.186 +	Matrix4x4(const mat4_t cmat);
 576.187 +
 576.188 +	Matrix4x4(const Matrix3x3 &mat3x3);
 576.189 +
 576.190 +	/* binary operations matrix (op) matrix */
 576.191 +	friend Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2);
 576.192 +	friend Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2);
 576.193 +	friend Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2);
 576.194 +
 576.195 +	friend void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2);
 576.196 +	friend void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2);
 576.197 +	friend inline void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2);
 576.198 +
 576.199 +	/* binary operations matrix (op) scalar and scalar (op) matrix */
 576.200 +	friend Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar);
 576.201 +	friend Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat);
 576.202 +
 576.203 +	friend void operator *=(Matrix4x4 &mat, scalar_t scalar);
 576.204 +
 576.205 +	inline scalar_t *operator [](int index);
 576.206 +	inline const scalar_t *operator [](int index) const;
 576.207 +
 576.208 +	inline void reset_identity();
 576.209 +
 576.210 +	void translate(const Vector3 &trans);
 576.211 +	void set_translation(const Vector3 &trans);
 576.212 +	Vector3 get_translation() const;	/* extract translation */
 576.213 +
 576.214 +	void rotate(const Vector3 &euler_angles);			/* 3d rotation with euler angles */
 576.215 +	void rotate(const Vector3 &axis, scalar_t angle);	/* 3d axis/angle rotation */
 576.216 +	void rotate(const Quaternion &quat);
 576.217 +	void set_rotation(const Vector3 &euler_angles);
 576.218 +	void set_rotation(const Vector3 &axis, scalar_t angle);
 576.219 +	void set_rotation(const Quaternion &quat);
 576.220 +	Quaternion get_rotation_quat() const;		/* extract rotation */
 576.221 +
 576.222 +	void scale(const Vector4 &scale_vec);
 576.223 +	void set_scaling(const Vector4 &scale_vec);
 576.224 +	Vector3 get_scaling() const;		/* extract scaling */
 576.225 +
 576.226 +	void set_frustum(float left, float right, float top, float bottom, float znear, float zfar);
 576.227 +	void set_perspective(float vfov, float aspect, float znear, float zfar);
 576.228 +	void set_orthographic(float left, float right, float bottom, float top, float znear = -1.0, float zfar = 1.0);
 576.229 +
 576.230 +	void set_lookat(const Vector3 &pos, const Vector3 &targ = Vector3(0, 0, 0), const Vector3 &up = Vector3(0, 1, 0));
 576.231 +
 576.232 +	void set_column_vector(const Vector4 &vec, unsigned int col_index);
 576.233 +	void set_row_vector(const Vector4 &vec, unsigned int row_index);
 576.234 +	Vector4 get_column_vector(unsigned int col_index) const;
 576.235 +	Vector4 get_row_vector(unsigned int row_index) const;
 576.236 +
 576.237 +	void transpose();
 576.238 +	Matrix4x4 transposed() const;
 576.239 +	scalar_t determinant() const;
 576.240 +	Matrix4x4 adjoint() const;
 576.241 +	Matrix4x4 inverse() const;
 576.242 +
 576.243 +	friend std::ostream &operator <<(std::ostream &out, const Matrix4x4 &mat);
 576.244 +};
 576.245 +
 576.246 +/* binary operations matrix (op) matrix */
 576.247 +Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2);
 576.248 +Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2);
 576.249 +inline Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2);
 576.250 +
 576.251 +void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2);
 576.252 +void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2);
 576.253 +inline void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2);
 576.254 +
 576.255 +/* binary operations matrix (op) scalar and scalar (op) matrix */
 576.256 +Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar);
 576.257 +Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat);
 576.258 +
 576.259 +void operator *=(Matrix4x4 &mat, scalar_t scalar);
 576.260 +
 576.261 +std::ostream &operator <<(std::ostream &out, const Matrix4x4 &mat);
 576.262 +
 576.263 +#endif	/* __cplusplus */
 576.264 +
 576.265 +#include "matrix.inl"
 576.266 +
 576.267 +#endif	/* VMATH_MATRIX_H_ */
   577.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   577.2 +++ b/libs/vmath/matrix.inl	Sat Feb 01 19:58:19 2014 +0200
   577.3 @@ -0,0 +1,200 @@
   577.4 +/*
   577.5 +libvmath - a vector math library
   577.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   577.7 +
   577.8 +This program is free software: you can redistribute it and/or modify
   577.9 +it under the terms of the GNU Lesser General Public License as published
  577.10 +by the Free Software Foundation, either version 3 of the License, or
  577.11 +(at your option) any later version.
  577.12 +
  577.13 +This program is distributed in the hope that it will be useful,
  577.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  577.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  577.16 +GNU Lesser General Public License for more details.
  577.17 +
  577.18 +You should have received a copy of the GNU Lesser General Public License
  577.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  577.20 +*/
  577.21 +
  577.22 +#include <string.h>
  577.23 +
  577.24 +#ifdef __cplusplus
  577.25 +extern "C" {
  577.26 +#endif	/* __cplusplus */
  577.27 +
  577.28 +/* C matrix 3x3 functions */
  577.29 +static inline void m3_identity(mat3_t m)
  577.30 +{
  577.31 +	static const mat3_t id = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
  577.32 +	memcpy(m, id, sizeof id);
  577.33 +}
  577.34 +
  577.35 +static inline void m3_cons(mat3_t m,
  577.36 +		scalar_t m11, scalar_t m12, scalar_t m13,
  577.37 +		scalar_t m21, scalar_t m22, scalar_t m23,
  577.38 +		scalar_t m31, scalar_t m32, scalar_t m33)
  577.39 +{
  577.40 +	m[0][0] = m11; m[0][1] = m12; m[0][2] = m13;
  577.41 +	m[1][0] = m21; m[1][1] = m22; m[1][2] = m23;
  577.42 +	m[2][0] = m31; m[2][1] = m32; m[2][2] = m33;
  577.43 +}
  577.44 +
  577.45 +static inline void m3_copy(mat3_t dest, mat3_t src)
  577.46 +{
  577.47 +	memcpy(dest, src, sizeof(mat3_t));
  577.48 +}
  577.49 +
  577.50 +
  577.51 +/* C matrix 4x4 functions */
  577.52 +static inline void m4_identity(mat4_t m)
  577.53 +{
  577.54 +	static const mat4_t id = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
  577.55 +	memcpy(m, id, sizeof id);
  577.56 +}
  577.57 +
  577.58 +static inline void m4_cons(mat4_t m,
  577.59 +		scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14,
  577.60 +		scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24,
  577.61 +		scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34,
  577.62 +		scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44)
  577.63 +{
  577.64 +	m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14;
  577.65 +	m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24;
  577.66 +	m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34;
  577.67 +	m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44;
  577.68 +}
  577.69 +
  577.70 +static inline void m4_copy(mat4_t dest, mat4_t src)
  577.71 +{
  577.72 +	memcpy(dest, src, sizeof(mat4_t));
  577.73 +}
  577.74 +
  577.75 +static inline void m4_mult(mat4_t res, mat4_t m1, mat4_t m2)
  577.76 +{
  577.77 +	mat4_t tmp;
  577.78 +
  577.79 +	/*
  577.80 +	int i, j;
  577.81 +	for(i=0; i<4; i++) {
  577.82 +		for(j=0; j<4; j++) {
  577.83 +			tmp[i][j] = m1[i][0] * m2[0][j] + m1[i][1] * m2[1][j] + m1[i][2] * m2[2][j] + m1[i][3] * m2[3][j];
  577.84 +		}
  577.85 +	}
  577.86 +	*/
  577.87 +
  577.88 +	tmp[0][0] = m1[0][0] * m2[0][0] + m1[0][1] * m2[1][0] + m1[0][2] * m2[2][0] + m1[0][3] * m2[3][0];
  577.89 +	tmp[0][1] = m1[0][0] * m2[0][1] + m1[0][1] * m2[1][1] + m1[0][2] * m2[2][1] + m1[0][3] * m2[3][1];
  577.90 +	tmp[0][2] = m1[0][0] * m2[0][2] + m1[0][1] * m2[1][2] + m1[0][2] * m2[2][2] + m1[0][3] * m2[3][2];
  577.91 +	tmp[0][3] = m1[0][0] * m2[0][3] + m1[0][1] * m2[1][3] + m1[0][2] * m2[2][3] + m1[0][3] * m2[3][3];
  577.92 +
  577.93 +	tmp[1][0] = m1[1][0] * m2[0][0] + m1[1][1] * m2[1][0] + m1[1][2] * m2[2][0] + m1[1][3] * m2[3][0];
  577.94 +	tmp[1][1] = m1[1][0] * m2[0][1] + m1[1][1] * m2[1][1] + m1[1][2] * m2[2][1] + m1[1][3] * m2[3][1];
  577.95 +	tmp[1][2] = m1[1][0] * m2[0][2] + m1[1][1] * m2[1][2] + m1[1][2] * m2[2][2] + m1[1][3] * m2[3][2];
  577.96 +	tmp[1][3] = m1[1][0] * m2[0][3] + m1[1][1] * m2[1][3] + m1[1][2] * m2[2][3] + m1[1][3] * m2[3][3];
  577.97 +
  577.98 +	tmp[2][0] = m1[2][0] * m2[0][0] + m1[2][1] * m2[1][0] + m1[2][2] * m2[2][0] + m1[2][3] * m2[3][0];
  577.99 +	tmp[2][1] = m1[2][0] * m2[0][1] + m1[2][1] * m2[1][1] + m1[2][2] * m2[2][1] + m1[2][3] * m2[3][1];
 577.100 +	tmp[2][2] = m1[2][0] * m2[0][2] + m1[2][1] * m2[1][2] + m1[2][2] * m2[2][2] + m1[2][3] * m2[3][2];
 577.101 +	tmp[2][3] = m1[2][0] * m2[0][3] + m1[2][1] * m2[1][3] + m1[2][2] * m2[2][3] + m1[2][3] * m2[3][3];
 577.102 +
 577.103 +	tmp[3][0] = m1[3][0] * m2[0][0] + m1[3][1] * m2[1][0] + m1[3][2] * m2[2][0] + m1[3][3] * m2[3][0];
 577.104 +	tmp[3][1] = m1[3][0] * m2[0][1] + m1[3][1] * m2[1][1] + m1[3][2] * m2[2][1] + m1[3][3] * m2[3][1];
 577.105 +	tmp[3][2] = m1[3][0] * m2[0][2] + m1[3][1] * m2[1][2] + m1[3][2] * m2[2][2] + m1[3][3] * m2[3][2];
 577.106 +	tmp[3][3] = m1[3][0] * m2[0][3] + m1[3][1] * m2[1][3] + m1[3][2] * m2[2][3] + m1[3][3] * m2[3][3];
 577.107 +
 577.108 +	m4_copy(res, tmp);
 577.109 +}
 577.110 +
 577.111 +static inline void m4_set_column(mat4_t m, vec4_t v, int idx)
 577.112 +{
 577.113 +	m[0][idx] = v.x;
 577.114 +	m[1][idx] = v.y;
 577.115 +	m[2][idx] = v.z;
 577.116 +	m[3][idx] = v.w;
 577.117 +}
 577.118 +
 577.119 +static inline void m4_set_row(mat4_t m, vec4_t v, int idx)
 577.120 +{
 577.121 +	m[idx][0] = v.x;
 577.122 +	m[idx][1] = v.y;
 577.123 +	m[idx][2] = v.z;
 577.124 +	m[idx][3] = v.w;
 577.125 +}
 577.126 +
 577.127 +#ifdef __cplusplus
 577.128 +}	/* extern "C" */
 577.129 +
 577.130 +
 577.131 +/* unrolled to hell and inline */
 577.132 +inline Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2)
 577.133 +{
 577.134 +	Matrix4x4 res;
 577.135 +
 577.136 +	/*
 577.137 +	for(i=0; i<4; i++) {
 577.138 +		for(j=0; j<4; j++) {
 577.139 +			res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j] + m1.m[i][3] * m2.m[3][j];
 577.140 +		}
 577.141 +	}
 577.142 +	*/
 577.143 +
 577.144 +	res.m[0][0] = m1.m[0][0] * m2.m[0][0] + m1.m[0][1] * m2.m[1][0] + m1.m[0][2] * m2.m[2][0] + m1.m[0][3] * m2.m[3][0];
 577.145 +	res.m[0][1] = m1.m[0][0] * m2.m[0][1] + m1.m[0][1] * m2.m[1][1] + m1.m[0][2] * m2.m[2][1] + m1.m[0][3] * m2.m[3][1];
 577.146 +	res.m[0][2] = m1.m[0][0] * m2.m[0][2] + m1.m[0][1] * m2.m[1][2] + m1.m[0][2] * m2.m[2][2] + m1.m[0][3] * m2.m[3][2];
 577.147 +	res.m[0][3] = m1.m[0][0] * m2.m[0][3] + m1.m[0][1] * m2.m[1][3] + m1.m[0][2] * m2.m[2][3] + m1.m[0][3] * m2.m[3][3];
 577.148 +
 577.149 +	res.m[1][0] = m1.m[1][0] * m2.m[0][0] + m1.m[1][1] * m2.m[1][0] + m1.m[1][2] * m2.m[2][0] + m1.m[1][3] * m2.m[3][0];
 577.150 +	res.m[1][1] = m1.m[1][0] * m2.m[0][1] + m1.m[1][1] * m2.m[1][1] + m1.m[1][2] * m2.m[2][1] + m1.m[1][3] * m2.m[3][1];
 577.151 +	res.m[1][2] = m1.m[1][0] * m2.m[0][2] + m1.m[1][1] * m2.m[1][2] + m1.m[1][2] * m2.m[2][2] + m1.m[1][3] * m2.m[3][2];
 577.152 +	res.m[1][3] = m1.m[1][0] * m2.m[0][3] + m1.m[1][1] * m2.m[1][3] + m1.m[1][2] * m2.m[2][3] + m1.m[1][3] * m2.m[3][3];
 577.153 +
 577.154 +	res.m[2][0] = m1.m[2][0] * m2.m[0][0] + m1.m[2][1] * m2.m[1][0] + m1.m[2][2] * m2.m[2][0] + m1.m[2][3] * m2.m[3][0];
 577.155 +	res.m[2][1] = m1.m[2][0] * m2.m[0][1] + m1.m[2][1] * m2.m[1][1] + m1.m[2][2] * m2.m[2][1] + m1.m[2][3] * m2.m[3][1];
 577.156 +	res.m[2][2] = m1.m[2][0] * m2.m[0][2] + m1.m[2][1] * m2.m[1][2] + m1.m[2][2] * m2.m[2][2] + m1.m[2][3] * m2.m[3][2];
 577.157 +	res.m[2][3] = m1.m[2][0] * m2.m[0][3] + m1.m[2][1] * m2.m[1][3] + m1.m[2][2] * m2.m[2][3] + m1.m[2][3] * m2.m[3][3];
 577.158 +
 577.159 +	res.m[3][0] = m1.m[3][0] * m2.m[0][0] + m1.m[3][1] * m2.m[1][0] + m1.m[3][2] * m2.m[2][0] + m1.m[3][3] * m2.m[3][0];
 577.160 +	res.m[3][1] = m1.m[3][0] * m2.m[0][1] + m1.m[3][1] * m2.m[1][1] + m1.m[3][2] * m2.m[2][1] + m1.m[3][3] * m2.m[3][1];
 577.161 +	res.m[3][2] = m1.m[3][0] * m2.m[0][2] + m1.m[3][1] * m2.m[1][2] + m1.m[3][2] * m2.m[2][2] + m1.m[3][3] * m2.m[3][2];
 577.162 +	res.m[3][3] = m1.m[3][0] * m2.m[0][3] + m1.m[3][1] * m2.m[1][3] + m1.m[3][2] * m2.m[2][3] + m1.m[3][3] * m2.m[3][3];
 577.163 +
 577.164 +	return res;
 577.165 +}
 577.166 +
 577.167 +inline void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2)
 577.168 +{
 577.169 +	Matrix4x4 res = m1 * m2;
 577.170 +	m1 = res;
 577.171 +}
 577.172 +
 577.173 +
 577.174 +inline scalar_t *Matrix3x3::operator [](int index)
 577.175 +{
 577.176 +	return m[index];
 577.177 +}
 577.178 +
 577.179 +inline const scalar_t *Matrix3x3::operator [](int index) const
 577.180 +{
 577.181 +	return m[index];
 577.182 +}
 577.183 +
 577.184 +inline void Matrix3x3::reset_identity()
 577.185 +{
 577.186 +	*this = identity;
 577.187 +}
 577.188 +
 577.189 +inline scalar_t *Matrix4x4::operator [](int index)
 577.190 +{
 577.191 +	return m[index];
 577.192 +}
 577.193 +
 577.194 +inline const scalar_t *Matrix4x4::operator [](int index) const
 577.195 +{
 577.196 +	return m[index];
 577.197 +}
 577.198 +
 577.199 +inline void Matrix4x4::reset_identity()
 577.200 +{
 577.201 +	*this = identity;
 577.202 +}
 577.203 +#endif	/* __cplusplus */
   578.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   578.2 +++ b/libs/vmath/matrix_c.c	Sat Feb 01 19:58:19 2014 +0200
   578.3 @@ -0,0 +1,292 @@
   578.4 +/*
   578.5 +libvmath - a vector math library
   578.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   578.7 +
   578.8 +This program is free software: you can redistribute it and/or modify
   578.9 +it under the terms of the GNU Lesser General Public License as published
  578.10 +by the Free Software Foundation, either version 3 of the License, or
  578.11 +(at your option) any later version.
  578.12 +
  578.13 +This program is distributed in the hope that it will be useful,
  578.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  578.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  578.16 +GNU Lesser General Public License for more details.
  578.17 +
  578.18 +You should have received a copy of the GNU Lesser General Public License
  578.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  578.20 +*/
  578.21 +
  578.22 +
  578.23 +#include <stdio.h>
  578.24 +#include "matrix.h"
  578.25 +#include "vector.h"
  578.26 +#include "quat.h"
  578.27 +
  578.28 +void m3_to_m4(mat4_t dest, mat3_t src)
  578.29 +{
  578.30 +	int i, j;
  578.31 +
  578.32 +	memset(dest, 0, sizeof(mat4_t));
  578.33 +	for(i=0; i<3; i++) {
  578.34 +		for(j=0; j<3; j++) {
  578.35 +			dest[i][j] = src[i][j];
  578.36 +		}
  578.37 +	}
  578.38 +	dest[3][3] = 1.0;
  578.39 +}
  578.40 +
  578.41 +void m3_print(FILE *fp, mat3_t m)
  578.42 +{
  578.43 +	int i;
  578.44 +	for(i=0; i<3; i++) {
  578.45 +		fprintf(fp, "[ %12.5f %12.5f %12.5f ]\n", (float)m[i][0], (float)m[i][1], (float)m[i][2]);
  578.46 +	}
  578.47 +}
  578.48 +
  578.49 +/* C matrix 4x4 functions */
  578.50 +void m4_to_m3(mat3_t dest, mat4_t src)
  578.51 +{
  578.52 +	int i, j;
  578.53 +	for(i=0; i<3; i++) {
  578.54 +		for(j=0; j<3; j++) {
  578.55 +			dest[i][j] = src[i][j];
  578.56 +		}
  578.57 +	}
  578.58 +}
  578.59 +
  578.60 +void m4_set_translation(mat4_t m, scalar_t x, scalar_t y, scalar_t z)
  578.61 +{
  578.62 +	m4_identity(m);
  578.63 +	m[0][3] = x;
  578.64 +	m[1][3] = y;
  578.65 +	m[2][3] = z;
  578.66 +}
  578.67 +
  578.68 +void m4_translate(mat4_t m, scalar_t x, scalar_t y, scalar_t z)
  578.69 +{
  578.70 +	mat4_t tm;
  578.71 +	m4_set_translation(tm, x, y, z);
  578.72 +	m4_mult(m, m, tm);
  578.73 +}
  578.74 +
  578.75 +void m4_rotate(mat4_t m, scalar_t x, scalar_t y, scalar_t z)
  578.76 +{
  578.77 +	m4_rotate_x(m, x);
  578.78 +	m4_rotate_y(m, y);
  578.79 +	m4_rotate_z(m, z);
  578.80 +}
  578.81 +
  578.82 +void m4_set_rotation_x(mat4_t m, scalar_t angle)
  578.83 +{
  578.84 +	m4_identity(m);
  578.85 +	m[1][1] = cos(angle); m[1][2] = -sin(angle);
  578.86 +	m[2][1] = sin(angle); m[2][2] = cos(angle);
  578.87 +}
  578.88 +
  578.89 +void m4_rotate_x(mat4_t m, scalar_t angle)
  578.90 +{
  578.91 +	mat4_t rm;
  578.92 +	m4_set_rotation_x(rm, angle);
  578.93 +	m4_mult(m, m, rm);
  578.94 +}
  578.95 +
  578.96 +void m4_set_rotation_y(mat4_t m, scalar_t angle)
  578.97 +{
  578.98 +	m4_identity(m);
  578.99 +	m[0][0] = cos(angle); m[0][2] = sin(angle);
 578.100 +	m[2][0] = -sin(angle); m[2][2] = cos(angle);
 578.101 +}
 578.102 +
 578.103 +void m4_rotate_y(mat4_t m, scalar_t angle)
 578.104 +{
 578.105 +	mat4_t rm;
 578.106 +	m4_set_rotation_y(rm, angle);
 578.107 +	m4_mult(m, m, rm);
 578.108 +}
 578.109 +
 578.110 +void m4_set_rotation_z(mat4_t m, scalar_t angle)
 578.111 +{
 578.112 +	m4_identity(m);
 578.113 +	m[0][0] = cos(angle); m[0][1] = -sin(angle);
 578.114 +	m[1][0] = sin(angle); m[1][1] = cos(angle);
 578.115 +}
 578.116 +
 578.117 +void m4_rotate_z(mat4_t m, scalar_t angle)
 578.118 +{
 578.119 +	mat4_t rm;
 578.120 +	m4_set_rotation_z(rm, angle);
 578.121 +	m4_mult(m, m, rm);
 578.122 +}
 578.123 +
 578.124 +void m4_set_rotation_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z)
 578.125 +{
 578.126 +	scalar_t sina = sin(angle);
 578.127 +	scalar_t cosa = cos(angle);
 578.128 +	scalar_t one_minus_cosa = 1.0 - cosa;
 578.129 +	scalar_t nxsq = x * x;
 578.130 +	scalar_t nysq = y * y;
 578.131 +	scalar_t nzsq = z * z;
 578.132 +
 578.133 +	m[0][0] = nxsq + (1.0 - nxsq) * cosa;
 578.134 +	m[0][1] = x * y * one_minus_cosa - z * sina;
 578.135 +	m[0][2] = x * z * one_minus_cosa + y * sina;
 578.136 +	m[1][0] = x * y * one_minus_cosa + z * sina;
 578.137 +	m[1][1] = nysq + (1.0 - nysq) * cosa;
 578.138 +	m[1][2] = y * z * one_minus_cosa - x * sina;
 578.139 +	m[2][0] = x * z * one_minus_cosa - y * sina;
 578.140 +	m[2][1] = y * z * one_minus_cosa + x * sina;
 578.141 +	m[2][2] = nzsq + (1.0 - nzsq) * cosa;
 578.142 +
 578.143 +	/* the rest are identity */
 578.144 +	m[3][0] = m[3][1] = m[3][2] = m[0][3] = m[1][3] = m[2][3] = 0.0;
 578.145 +	m[3][3] = 1.0;
 578.146 +}
 578.147 +
 578.148 +void m4_rotate_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z)
 578.149 +{
 578.150 +	mat4_t xform;
 578.151 +	m4_set_rotation_axis(xform, angle, x, y, z);
 578.152 +	m4_mult(m, m, xform);
 578.153 +}
 578.154 +
 578.155 +void m4_rotate_quat(mat4_t m, quat_t q)
 578.156 +{
 578.157 +	mat4_t rm;
 578.158 +	quat_to_mat4(rm, q);
 578.159 +	m4_mult(m, m, rm);
 578.160 +}
 578.161 +
 578.162 +void m4_scale(mat4_t m, scalar_t x, scalar_t y, scalar_t z)
 578.163 +{
 578.164 +	mat4_t sm;
 578.165 +	m4_identity(sm);
 578.166 +	sm[0][0] = x;
 578.167 +	sm[1][1] = y;
 578.168 +	sm[2][2] = z;
 578.169 +	m4_mult(m, m, sm);
 578.170 +}
 578.171 +
 578.172 +void m4_transpose(mat4_t res, mat4_t m)
 578.173 +{
 578.174 +	int i, j;
 578.175 +	mat4_t tmp;
 578.176 +	m4_copy(tmp, m);
 578.177 +
 578.178 +	for(i=0; i<4; i++) {
 578.179 +		for(j=0; j<4; j++) {
 578.180 +			res[i][j] = tmp[j][i];
 578.181 +		}
 578.182 +	}
 578.183 +}
 578.184 +
 578.185 +scalar_t m4_determinant(mat4_t m)
 578.186 +{
 578.187 +	scalar_t det11 =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 578.188 +						(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
 578.189 +						(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
 578.190 +
 578.191 +	scalar_t det12 =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 578.192 +						(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 578.193 +						(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
 578.194 +
 578.195 +	scalar_t det13 =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
 578.196 +						(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 578.197 +						(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 578.198 +
 578.199 +	scalar_t det14 =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
 578.200 +						(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
 578.201 +						(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 578.202 +
 578.203 +	return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14;
 578.204 +}
 578.205 +
 578.206 +void m4_adjoint(mat4_t res, mat4_t m)
 578.207 +{
 578.208 +	int i, j;
 578.209 +	mat4_t coef;
 578.210 +
 578.211 +	coef[0][0] =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 578.212 +					(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
 578.213 +					(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
 578.214 +	coef[0][1] =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 578.215 +					(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 578.216 +					(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
 578.217 +	coef[0][2] =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
 578.218 +					(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 578.219 +					(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 578.220 +	coef[0][3] =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
 578.221 +					(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
 578.222 +					(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 578.223 +
 578.224 +	coef[1][0] =	(m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 578.225 +					(m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
 578.226 +					(m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
 578.227 +	coef[1][1] =	(m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
 578.228 +					(m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 578.229 +					(m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
 578.230 +	coef[1][2] =	(m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
 578.231 +					(m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
 578.232 +					(m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 578.233 +	coef[1][3] =	(m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
 578.234 +					(m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
 578.235 +					(m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
 578.236 +
 578.237 +	coef[2][0] =	(m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
 578.238 +					(m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) +
 578.239 +					(m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2]));
 578.240 +	coef[2][1] =	(m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
 578.241 +					(m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
 578.242 +					(m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2]));
 578.243 +	coef[2][2] =	(m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) -
 578.244 +					(m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
 578.245 +					(m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
 578.246 +	coef[2][3] =	(m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) -
 578.247 +					(m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) +
 578.248 +					(m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
 578.249 +
 578.250 +	coef[3][0] =	(m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
 578.251 +					(m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) +
 578.252 +					(m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]));
 578.253 +	coef[3][1] =	(m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
 578.254 +					(m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
 578.255 +					(m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2]));
 578.256 +	coef[3][2] =	(m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) -
 578.257 +					(m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
 578.258 +					(m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
 578.259 +	coef[3][3] =	(m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) -
 578.260 +					(m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) +
 578.261 +					(m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
 578.262 +
 578.263 +	m4_transpose(res, coef);
 578.264 +
 578.265 +	for(i=0; i<4; i++) {
 578.266 +		for(j=0; j<4; j++) {
 578.267 +			res[i][j] = j % 2 ? -res[i][j] : res[i][j];
 578.268 +			if(i % 2) res[i][j] = -res[i][j];
 578.269 +		}
 578.270 +	}
 578.271 +}
 578.272 +
 578.273 +void m4_inverse(mat4_t res, mat4_t m)
 578.274 +{
 578.275 +	int i, j;
 578.276 +	mat4_t adj;
 578.277 +	scalar_t det;
 578.278 +
 578.279 +	m4_adjoint(adj, m);
 578.280 +	det = m4_determinant(m);
 578.281 +	
 578.282 +	for(i=0; i<4; i++) {
 578.283 +		for(j=0; j<4; j++) {
 578.284 +			res[i][j] = adj[i][j] / det;
 578.285 +		}
 578.286 +	}
 578.287 +}
 578.288 +
 578.289 +void m4_print(FILE *fp, mat4_t m)
 578.290 +{
 578.291 +	int i;
 578.292 +	for(i=0; i<4; i++) {
 578.293 +		fprintf(fp, "[ %12.5f %12.5f %12.5f %12.5f ]\n", (float)m[i][0], (float)m[i][1], (float)m[i][2], (float)m[i][3]);
 578.294 +	}
 578.295 +}
   579.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   579.2 +++ b/libs/vmath/quat.cc	Sat Feb 01 19:58:19 2014 +0200
   579.3 @@ -0,0 +1,212 @@
   579.4 +#include "quat.h"
   579.5 +#include "vmath.h"
   579.6 +
   579.7 +Quaternion::Quaternion()
   579.8 +{
   579.9 +	s = 1.0;
  579.10 +	v.x = v.y = v.z = 0.0;
  579.11 +}
  579.12 +
  579.13 +Quaternion::Quaternion(scalar_t s, const Vector3 &v)
  579.14 +{
  579.15 +	this->s = s;
  579.16 +	this->v = v;
  579.17 +}
  579.18 +
  579.19 +Quaternion::Quaternion(scalar_t s, scalar_t x, scalar_t y, scalar_t z)
  579.20 +{
  579.21 +	v.x = x;
  579.22 +	v.y = y;
  579.23 +	v.z = z;
  579.24 +	this->s = s;
  579.25 +}
  579.26 +
  579.27 +Quaternion::Quaternion(const Vector3 &axis, scalar_t angle)
  579.28 +{
  579.29 +	set_rotation(axis, angle);
  579.30 +}
  579.31 +
  579.32 +Quaternion::Quaternion(const quat_t &quat)
  579.33 +{
  579.34 +	v.x = quat.x;
  579.35 +	v.y = quat.y;
  579.36 +	v.z = quat.z;
  579.37 +	s = quat.w;
  579.38 +}
  579.39 +
  579.40 +Quaternion Quaternion::operator +(const Quaternion &quat) const
  579.41 +{
  579.42 +	return Quaternion(s + quat.s, v + quat.v);
  579.43 +}
  579.44 +
  579.45 +Quaternion Quaternion::operator -(const Quaternion &quat) const
  579.46 +{
  579.47 +	return Quaternion(s - quat.s, v - quat.v);
  579.48 +}
  579.49 +
  579.50 +Quaternion Quaternion::operator -() const
  579.51 +{
  579.52 +	return Quaternion(-s, -v);
  579.53 +}
  579.54 +
  579.55 +/** Quaternion Multiplication:
  579.56 + * Q1*Q2 = [s1*s2 - v1.v2,  s1*v2 + s2*v1 + v1(x)v2]
  579.57 + */
  579.58 +Quaternion Quaternion::operator *(const Quaternion &quat) const
  579.59 +{
  579.60 +	Quaternion newq;
  579.61 +	newq.s = s * quat.s - dot_product(v, quat.v);
  579.62 +	newq.v = quat.v * s + v * quat.s + cross_product(v, quat.v);
  579.63 +	return newq;
  579.64 +}
  579.65 +
  579.66 +void Quaternion::operator +=(const Quaternion &quat)
  579.67 +{
  579.68 +	*this = Quaternion(s + quat.s, v + quat.v);
  579.69 +}
  579.70 +
  579.71 +void Quaternion::operator -=(const Quaternion &quat)
  579.72 +{
  579.73 +	*this = Quaternion(s - quat.s, v - quat.v);
  579.74 +}
  579.75 +
  579.76 +void Quaternion::operator *=(const Quaternion &quat)
  579.77 +{
  579.78 +	*this = *this * quat;
  579.79 +}
  579.80 +
  579.81 +void Quaternion::reset_identity()
  579.82 +{
  579.83 +	s = 1.0;
  579.84 +	v.x = v.y = v.z = 0.0;
  579.85 +}
  579.86 +
  579.87 +Quaternion Quaternion::conjugate() const
  579.88 +{
  579.89 +	return Quaternion(s, -v);
  579.90 +}
  579.91 +
  579.92 +scalar_t Quaternion::length() const
  579.93 +{
  579.94 +	return (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s);
  579.95 +}
  579.96 +
  579.97 +/** Q * ~Q = ||Q||^2 */
  579.98 +scalar_t Quaternion::length_sq() const
  579.99 +{
 579.100 +	return v.x*v.x + v.y*v.y + v.z*v.z + s*s;
 579.101 +}
 579.102 +
 579.103 +void Quaternion::normalize()
 579.104 +{
 579.105 +	scalar_t len = (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s);
 579.106 +	v.x /= len;
 579.107 +	v.y /= len;
 579.108 +	v.z /= len;
 579.109 +	s /= len;
 579.110 +}
 579.111 +
 579.112 +Quaternion Quaternion::normalized() const
 579.113 +{
 579.114 +	Quaternion nq = *this;
 579.115 +	scalar_t len = (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s);
 579.116 +	nq.v.x /= len;
 579.117 +	nq.v.y /= len;
 579.118 +	nq.v.z /= len;
 579.119 +	nq.s /= len;
 579.120 +	return nq;
 579.121 +}
 579.122 +
 579.123 +/** Quaternion Inversion: Q^-1 = ~Q / ||Q||^2 */
 579.124 +Quaternion Quaternion::inverse() const
 579.125 +{
 579.126 +	Quaternion inv = conjugate();
 579.127 +	scalar_t lensq = length_sq();
 579.128 +	inv.v /= lensq;
 579.129 +	inv.s /= lensq;
 579.130 +
 579.131 +	return inv;
 579.132 +}
 579.133 +
 579.134 +
 579.135 +void Quaternion::set_rotation(const Vector3 &axis, scalar_t angle)
 579.136 +{
 579.137 +	scalar_t half_angle = angle / 2.0;
 579.138 +	s = cos(half_angle);
 579.139 +	v = axis * sin(half_angle);
 579.140 +}
 579.141 +
 579.142 +void Quaternion::rotate(const Vector3 &axis, scalar_t angle)
 579.143 +{
 579.144 +	Quaternion q;
 579.145 +	scalar_t half_angle = angle / 2.0;
 579.146 +	q.s = cos(half_angle);
 579.147 +	q.v = axis * sin(half_angle);
 579.148 +
 579.149 +	*this *= q;
 579.150 +}
 579.151 +
 579.152 +void Quaternion::rotate(const Quaternion &q)
 579.153 +{
 579.154 +	*this = q * *this * q.conjugate();
 579.155 +}
 579.156 +
 579.157 +Matrix3x3 Quaternion::get_rotation_matrix() const
 579.158 +{
 579.159 +	return Matrix3x3(
 579.160 +			1.0 - 2.0 * v.y*v.y - 2.0 * v.z*v.z,	2.0 * v.x * v.y - 2.0 * s * v.z,		2.0 * v.z * v.x + 2.0 * s * v.y,
 579.161 +			2.0 * v.x * v.y + 2.0 * s * v.z,		1.0 - 2.0 * v.x*v.x - 2.0 * v.z*v.z,	2.0 * v.y * v.z - 2.0 * s * v.x,
 579.162 +			2.0 * v.z * v.x - 2.0 * s * v.y,		2.0 * v.y * v.z + 2.0 * s * v.x,		1.0 - 2.0 * v.x*v.x - 2.0 * v.y*v.y);
 579.163 +}
 579.164 +
 579.165 +
 579.166 +/** Spherical linear interpolation (slerp) */
 579.167 +Quaternion slerp(const Quaternion &quat1, const Quaternion &q2, scalar_t t)
 579.168 +{
 579.169 +	Quaternion q1;
 579.170 +	scalar_t dot = q1.s * q2.s + q1.v.x * q2.v.x + q1.v.y * q2.v.y + q1.v.z * q2.v.z;
 579.171 +
 579.172 +	if(dot < 0.0) {
 579.173 +		/* make sure we interpolate across the shortest arc */
 579.174 +		q1 = -quat1;
 579.175 +		dot = -dot;
 579.176 +	} else {
 579.177 +		q1 = quat1;
 579.178 +	}
 579.179 +
 579.180 +	/* clamp dot to [-1, 1] in order to avoid domain errors in acos due to
 579.181 +	 * floating point imprecisions
 579.182 +	 */
 579.183 +	if(dot < -1.0) dot = -1.0;
 579.184 +	if(dot > 1.0) dot = 1.0;
 579.185 +
 579.186 +	scalar_t angle = acos(dot);
 579.187 +	scalar_t a, b;
 579.188 +
 579.189 +	scalar_t sin_angle = sin(angle);
 579.190 +	if(fabs(sin_angle) < SMALL_NUMBER) {
 579.191 +		/* for very small angles or completely opposite orientations
 579.192 +		 * use linear interpolation to avoid div/zero (in the first case it makes sense,
 579.193 +		 * the second case is pretty much undefined anyway I guess ...
 579.194 +		 */
 579.195 +		a = 1.0f - t;
 579.196 +		b = t;
 579.197 +	} else {
 579.198 +		a = sin((1.0f - t) * angle) / sin_angle;
 579.199 +		b = sin(t * angle) / sin_angle;
 579.200 +	}
 579.201 +
 579.202 +	scalar_t x = q1.v.x * a + q2.v.x * b;
 579.203 +	scalar_t y = q1.v.y * a + q2.v.y * b;
 579.204 +	scalar_t z = q1.v.z * a + q2.v.z * b;
 579.205 +	scalar_t s = q1.s * a + q2.s * b;
 579.206 +
 579.207 +	return Quaternion(s, Vector3(x, y, z));
 579.208 +}
 579.209 +
 579.210 +
 579.211 +std::ostream &operator <<(std::ostream &out, const Quaternion &q)
 579.212 +{
 579.213 +	out << "(" << q.s << ", " << q.v << ")";
 579.214 +	return out;
 579.215 +}
   580.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   580.2 +++ b/libs/vmath/quat.h	Sat Feb 01 19:58:19 2014 +0200
   580.3 @@ -0,0 +1,118 @@
   580.4 +/*
   580.5 +libvmath - a vector math library
   580.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   580.7 +
   580.8 +This program is free software: you can redistribute it and/or modify
   580.9 +it under the terms of the GNU Lesser General Public License as published
  580.10 +by the Free Software Foundation, either version 3 of the License, or
  580.11 +(at your option) any later version.
  580.12 +
  580.13 +This program is distributed in the hope that it will be useful,
  580.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  580.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  580.16 +GNU Lesser General Public License for more details.
  580.17 +
  580.18 +You should have received a copy of the GNU Lesser General Public License
  580.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  580.20 +*/
  580.21 +
  580.22 +#ifndef VMATH_QUATERNION_H_
  580.23 +#define VMATH_QUATERNION_H_
  580.24 +
  580.25 +#include <stdio.h>
  580.26 +#include "vmath_types.h"
  580.27 +#include "vector.h"
  580.28 +
  580.29 +#ifdef __cplusplus
  580.30 +extern "C" {
  580.31 +#endif	/* __cplusplus */
  580.32 +
  580.33 +#define quat_cons(s, x, y, z)	v4_cons(x, y, z, s)
  580.34 +#define quat_vec(q)				v3_cons((q).x, (q).y, (q).z)
  580.35 +#define quat_s(q)				((q).w)
  580.36 +#define quat_identity()			quat_cons(1.0, 0.0, 0.0, 0.0)
  580.37 +void quat_print(FILE *fp, quat_t q);
  580.38 +
  580.39 +#define quat_add		v4_add
  580.40 +#define quat_sub		v4_sub
  580.41 +#define quat_neg		v4_neg
  580.42 +
  580.43 +static inline quat_t quat_mul(quat_t q1, quat_t q2);
  580.44 +
  580.45 +static inline quat_t quat_conjugate(quat_t q);
  580.46 +
  580.47 +#define quat_length		v4_length
  580.48 +#define quat_length_sq	v4_length_sq
  580.49 +
  580.50 +#define quat_normalize	v4_normalize
  580.51 +static inline quat_t quat_inverse(quat_t q);
  580.52 +
  580.53 +quat_t quat_rotate(quat_t q, scalar_t angle, scalar_t x, scalar_t y, scalar_t z);
  580.54 +quat_t quat_rotate_quat(quat_t q, quat_t rotq);
  580.55 +
  580.56 +static inline void quat_to_mat3(mat3_t res, quat_t q);
  580.57 +static inline void quat_to_mat4(mat4_t res, quat_t q);
  580.58 +
  580.59 +#define quat_lerp quat_slerp
  580.60 +quat_t quat_slerp(quat_t q1, quat_t q2, scalar_t t);
  580.61 +
  580.62 +
  580.63 +#ifdef __cplusplus
  580.64 +}	/* extern "C" */
  580.65 +
  580.66 +#include <iostream>
  580.67 +
  580.68 +/* Quaternion */
  580.69 +class Quaternion {
  580.70 +public:
  580.71 +	scalar_t s;
  580.72 +	Vector3 v;
  580.73 +
  580.74 +	Quaternion();
  580.75 +	Quaternion(scalar_t s, const Vector3 &v);
  580.76 +	Quaternion(scalar_t s, scalar_t x, scalar_t y, scalar_t z);
  580.77 +	Quaternion(const Vector3 &axis, scalar_t angle);
  580.78 +	Quaternion(const quat_t &quat);
  580.79 +
  580.80 +	Quaternion operator +(const Quaternion &quat) const;
  580.81 +	Quaternion operator -(const Quaternion &quat) const;
  580.82 +	Quaternion operator -() const;
  580.83 +	Quaternion operator *(const Quaternion &quat) const;
  580.84 +
  580.85 +	void operator +=(const Quaternion &quat);
  580.86 +	void operator -=(const Quaternion &quat);
  580.87 +	void operator *=(const Quaternion &quat);
  580.88 +
  580.89 +	void reset_identity();
  580.90 +
  580.91 +	Quaternion conjugate() const;
  580.92 +
  580.93 +	scalar_t length() const;
  580.94 +	scalar_t length_sq() const;
  580.95 +
  580.96 +	void normalize();
  580.97 +	Quaternion normalized() const;
  580.98 +
  580.99 +	Quaternion inverse() const;
 580.100 +
 580.101 +	void set_rotation(const Vector3 &axis, scalar_t angle);
 580.102 +	void rotate(const Vector3 &axis, scalar_t angle);
 580.103 +	/* note: this is a totally different operation from the above
 580.104 +	 * this treats the quaternion as signifying direction and rotates
 580.105 +	 * it by a rotation quaternion by rot * q * rot'
 580.106 +	 */
 580.107 +	void rotate(const Quaternion &q);
 580.108 +
 580.109 +	Matrix3x3 get_rotation_matrix() const;
 580.110 +};
 580.111 +
 580.112 +Quaternion slerp(const Quaternion &q1, const Quaternion &q2, scalar_t t);
 580.113 +inline Quaternion lerp(const Quaternion &q1, const Quaternion &q2, scalar_t t);
 580.114 +
 580.115 +std::ostream &operator <<(std::ostream &out, const Quaternion &q);
 580.116 +
 580.117 +#endif	/* __cplusplus */
 580.118 +
 580.119 +#include "quat.inl"
 580.120 +
 580.121 +#endif	/* VMATH_QUATERNION_H_ */
   581.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   581.2 +++ b/libs/vmath/quat.inl	Sat Feb 01 19:58:19 2014 +0200
   581.3 @@ -0,0 +1,81 @@
   581.4 +/*
   581.5 +libvmath - a vector math library
   581.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   581.7 +
   581.8 +This program is free software: you can redistribute it and/or modify
   581.9 +it under the terms of the GNU Lesser General Public License as published
  581.10 +by the Free Software Foundation, either version 3 of the License, or
  581.11 +(at your option) any later version.
  581.12 +
  581.13 +This program is distributed in the hope that it will be useful,
  581.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  581.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  581.16 +GNU Lesser General Public License for more details.
  581.17 +
  581.18 +You should have received a copy of the GNU Lesser General Public License
  581.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  581.20 +*/
  581.21 +
  581.22 +#include "vector.h"
  581.23 +#include "matrix.h"
  581.24 +
  581.25 +#ifdef __cplusplus
  581.26 +extern "C" {
  581.27 +#endif	/* __cplusplus */
  581.28 +
  581.29 +static inline quat_t quat_mul(quat_t q1, quat_t q2)
  581.30 +{
  581.31 +	quat_t res;
  581.32 +	vec3_t v1 = quat_vec(q1);
  581.33 +	vec3_t v2 = quat_vec(q2);
  581.34 +
  581.35 +	res.w = q1.w * q2.w - v3_dot(v1, v2);
  581.36 +	/* resvec = v2 * q1 + v1 * q2 + cross(v1, v2) */
  581.37 +	res.x = v2.x * q1.w + v1.x * q2.w + (v1.y * v2.z - v1.z * v2.y);
  581.38 +	res.y = v2.y * q1.w + v1.y * q2.w + (v1.z * v2.x - v1.x * v2.z);
  581.39 +	res.z = v2.z * q1.w + v1.z * q2.w + (v1.x * v2.y - v1.y * v2.x);
  581.40 +	return res;
  581.41 +}
  581.42 +
  581.43 +static inline quat_t quat_conjugate(quat_t q)
  581.44 +{
  581.45 +	q.x = -q.x;
  581.46 +	q.y = -q.y;
  581.47 +	q.z = -q.z;
  581.48 +	return q;
  581.49 +}
  581.50 +
  581.51 +static inline quat_t quat_inverse(quat_t q)
  581.52 +{
  581.53 +	scalar_t lensq = quat_length_sq(q);
  581.54 +	q = quat_conjugate(q);
  581.55 +	q.x /= lensq;
  581.56 +	q.y /= lensq;
  581.57 +	q.z /= lensq;
  581.58 +	q.w /= lensq;
  581.59 +	return q;
  581.60 +}
  581.61 +
  581.62 +static inline void quat_to_mat3(mat3_t res, quat_t q)
  581.63 +{
  581.64 +	m3_cons(res, 1.0 - 2.0 * q.y*q.y - 2.0 * q.z*q.z, 2.0 * q.x * q.y - 2.0 * q.w * q.z,   2.0 * q.z * q.x + 2.0 * q.w * q.y,
  581.65 +				 2.0 * q.x * q.y + 2.0 * q.w * q.z,   1.0 - 2.0 * q.x*q.x - 2.0 * q.z*q.z, 2.0 * q.y * q.z - 2.0 * q.w * q.x,
  581.66 +				 2.0 * q.z * q.x - 2.0 * q.w * q.y,   2.0 * q.y * q.z + 2.0 * q.w * q.x,   1.0 - 2.0 * q.x*q.x - 2.0 * q.y*q.y);
  581.67 +}
  581.68 +
  581.69 +static inline void quat_to_mat4(mat4_t res, quat_t q)
  581.70 +{
  581.71 +	m4_cons(res, 1.0 - 2.0 * q.y*q.y - 2.0 * q.z*q.z, 2.0 * q.x * q.y - 2.0 * q.w * q.z,   2.0 * q.z * q.x + 2.0 * q.w * q.y,   0,
  581.72 +				 2.0 * q.x * q.y + 2.0 * q.w * q.z,   1.0 - 2.0 * q.x*q.x - 2.0 * q.z*q.z, 2.0 * q.y * q.z - 2.0 * q.w * q.x,   0,
  581.73 +				 2.0 * q.z * q.x - 2.0 * q.w * q.y,   2.0 * q.y * q.z + 2.0 * q.w * q.x,   1.0 - 2.0 * q.x*q.x - 2.0 * q.y*q.y, 0,
  581.74 +				 0, 0, 0, 1);
  581.75 +}
  581.76 +
  581.77 +#ifdef __cplusplus
  581.78 +}	/* extern "C" */
  581.79 +
  581.80 +inline Quaternion lerp(const Quaternion &a, const Quaternion &b, scalar_t t)
  581.81 +{
  581.82 +	return slerp(a, b, t);
  581.83 +}
  581.84 +#endif	/* __cplusplus */
   582.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   582.2 +++ b/libs/vmath/quat_c.c	Sat Feb 01 19:58:19 2014 +0200
   582.3 @@ -0,0 +1,89 @@
   582.4 +/*
   582.5 +libvmath - a vector math library
   582.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   582.7 +
   582.8 +This program is free software: you can redistribute it and/or modify
   582.9 +it under the terms of the GNU Lesser General Public License as published
  582.10 +by the Free Software Foundation, either version 3 of the License, or
  582.11 +(at your option) any later version.
  582.12 +
  582.13 +This program is distributed in the hope that it will be useful,
  582.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  582.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  582.16 +GNU Lesser General Public License for more details.
  582.17 +
  582.18 +You should have received a copy of the GNU Lesser General Public License
  582.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  582.20 +*/
  582.21 +
  582.22 +
  582.23 +#include <stdio.h>
  582.24 +#include <math.h>
  582.25 +#include "quat.h"
  582.26 +
  582.27 +void quat_print(FILE *fp, quat_t q)
  582.28 +{
  582.29 +	fprintf(fp, "([ %.4f %.4f %.4f ] %.4f)", q.x, q.y, q.z, q.w);
  582.30 +}
  582.31 +
  582.32 +quat_t quat_rotate(quat_t q, scalar_t angle, scalar_t x, scalar_t y, scalar_t z)
  582.33 +{
  582.34 +	quat_t rq;
  582.35 +	scalar_t half_angle = angle * 0.5;
  582.36 +	scalar_t sin_half = sin(half_angle);
  582.37 +
  582.38 +	rq.w = cos(half_angle);
  582.39 +	rq.x = x * sin_half;
  582.40 +	rq.y = y * sin_half;
  582.41 +	rq.z = z * sin_half;
  582.42 +
  582.43 +	return quat_mul(q, rq);
  582.44 +}
  582.45 +
  582.46 +quat_t quat_rotate_quat(quat_t q, quat_t rotq)
  582.47 +{
  582.48 +	return quat_mul(quat_mul(rotq, q), quat_conjugate(rotq));
  582.49 +}
  582.50 +
  582.51 +quat_t quat_slerp(quat_t q1, quat_t q2, scalar_t t)
  582.52 +{
  582.53 +	quat_t res;
  582.54 +	scalar_t a, b, angle, sin_angle, dot;
  582.55 +
  582.56 +	dot = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z;
  582.57 +	if(dot < 0.0) {
  582.58 +		/* make sure we interpolate across the shortest arc */
  582.59 +		q1.x = -q1.x;
  582.60 +		q1.y = -q1.y;
  582.61 +		q1.z = -q1.z;
  582.62 +		q1.w = -q1.w;
  582.63 +		dot = -dot;
  582.64 +	}
  582.65 +
  582.66 +	/* clamp dot to [-1, 1] in order to avoid domain errors in acos due to
  582.67 +	 * floating point imprecisions
  582.68 +	 */
  582.69 +	if(dot < -1.0) dot = -1.0;
  582.70 +	if(dot > 1.0) dot = 1.0;
  582.71 +
  582.72 +	angle = acos(dot);
  582.73 +	sin_angle = sin(angle);
  582.74 +
  582.75 +	if(fabs(sin_angle) < SMALL_NUMBER) {
  582.76 +		/* for very small angles or completely opposite orientations
  582.77 +		 * use linear interpolation to avoid div/zero (in the first case it makes sense,
  582.78 +		 * the second case is pretty much undefined anyway I guess ...
  582.79 +		 */
  582.80 +		a = 1.0f - t;
  582.81 +		b = t;
  582.82 +	} else {
  582.83 +		a = sin((1.0f - t) * angle) / sin_angle;
  582.84 +		b = sin(t * angle) / sin_angle;
  582.85 +	}
  582.86 +
  582.87 +	res.x = q1.x * a + q2.x * b;
  582.88 +	res.y = q1.y * a + q2.y * b;
  582.89 +	res.z = q1.z * a + q2.z * b;
  582.90 +	res.w = q1.w * a + q2.w * b;
  582.91 +	return res;
  582.92 +}
   583.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   583.2 +++ b/libs/vmath/ray.cc	Sat Feb 01 19:58:19 2014 +0200
   583.3 @@ -0,0 +1,61 @@
   583.4 +#include "ray.h"
   583.5 +#include "vector.h"
   583.6 +
   583.7 +scalar_t Ray::env_ior = 1.0;
   583.8 +
   583.9 +Ray::Ray()
  583.10 +{
  583.11 +	ior = env_ior;
  583.12 +	energy = 1.0;
  583.13 +	time = 0;
  583.14 +	iter = 0;
  583.15 +}
  583.16 +
  583.17 +Ray::Ray(const Vector3 &origin, const Vector3 &dir)
  583.18 +{
  583.19 +	this->origin = origin;
  583.20 +	this->dir = dir;
  583.21 +	ior = env_ior;
  583.22 +	energy = 1.0;
  583.23 +	time = 0;
  583.24 +	iter = 0;
  583.25 +}
  583.26 +
  583.27 +void Ray::transform(const Matrix4x4 &xform)
  583.28 +{
  583.29 +	Matrix4x4 upper = xform;
  583.30 +	upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0;
  583.31 +	upper[3][3] = 1.0;
  583.32 +
  583.33 +	dir.transform(upper);
  583.34 +	origin.transform(xform);
  583.35 +}
  583.36 +
  583.37 +Ray Ray::transformed(const Matrix4x4 &xform) const
  583.38 +{
  583.39 +	Ray foo = *this;
  583.40 +	foo.transform(xform);
  583.41 +	return foo;
  583.42 +}
  583.43 +
  583.44 +void Ray::enter(scalar_t new_ior)
  583.45 +{
  583.46 +	ior = new_ior;
  583.47 +}
  583.48 +
  583.49 +void Ray::leave()
  583.50 +{
  583.51 +}
  583.52 +
  583.53 +scalar_t Ray::calc_ior(bool entering, scalar_t mat_ior) const
  583.54 +{
  583.55 +	scalar_t from_ior = this->ior;
  583.56 +
  583.57 +	if(entering) {
  583.58 +		return from_ior / mat_ior;
  583.59 +	}
  583.60 +
  583.61 +	Ray tmp = *this;
  583.62 +	tmp.leave();
  583.63 +	return from_ior / tmp.ior;
  583.64 +}
   584.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   584.2 +++ b/libs/vmath/ray.h	Sat Feb 01 19:58:19 2014 +0200
   584.3 @@ -0,0 +1,68 @@
   584.4 +/*
   584.5 +libvmath - a vector math library
   584.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   584.7 +
   584.8 +This program is free software: you can redistribute it and/or modify
   584.9 +it under the terms of the GNU Lesser General Public License as published
  584.10 +by the Free Software Foundation, either version 3 of the License, or
  584.11 +(at your option) any later version.
  584.12 +
  584.13 +This program is distributed in the hope that it will be useful,
  584.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  584.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  584.16 +GNU Lesser General Public License for more details.
  584.17 +
  584.18 +You should have received a copy of the GNU Lesser General Public License
  584.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  584.20 +*/
  584.21 +
  584.22 +#ifndef VMATH_RAY_H_
  584.23 +#define VMATH_RAY_H_
  584.24 +
  584.25 +#include "matrix.h"
  584.26 +#include "vector.h"
  584.27 +
  584.28 +typedef struct {
  584.29 +	vec3_t origin, dir;
  584.30 +} ray_t;
  584.31 +
  584.32 +#ifdef __cplusplus
  584.33 +extern "C" {
  584.34 +#endif	/* __cplusplus */
  584.35 +
  584.36 +static inline ray_t ray_cons(vec3_t origin, vec3_t dir);
  584.37 +ray_t ray_transform(ray_t r, mat4_t m);
  584.38 +
  584.39 +#ifdef __cplusplus
  584.40 +}	/* __cplusplus */
  584.41 +
  584.42 +class Ray {
  584.43 +public:
  584.44 +	/* enviornmental index of refraction, normally 1.0 */
  584.45 +	static scalar_t env_ior;
  584.46 +
  584.47 +	Vector3 origin, dir;
  584.48 +	scalar_t energy;
  584.49 +	int iter;
  584.50 +	scalar_t ior;
  584.51 +	long time;
  584.52 +
  584.53 +	Ray();
  584.54 +	Ray(const Vector3 &origin, const Vector3 &dir);
  584.55 +
  584.56 +	void transform(const Matrix4x4 &xform);
  584.57 +	Ray transformed(const Matrix4x4 &xform) const;
  584.58 +
  584.59 +	void enter(scalar_t new_ior);
  584.60 +	void leave();
  584.61 +
  584.62 +	scalar_t calc_ior(bool entering, scalar_t mat_ior = 1.0) const;
  584.63 +};
  584.64 +
  584.65 +inline Ray reflect_ray(const Ray &inray, const Vector3 &norm);
  584.66 +inline Ray refract_ray(const Ray &inray, const Vector3 &norm, scalar_t ior, bool entering, scalar_t ray_mag = -1.0);
  584.67 +#endif	/* __cplusplus */
  584.68 +
  584.69 +#include "ray.inl"
  584.70 +
  584.71 +#endif	/* VMATH_RAY_H_ */
   585.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   585.2 +++ b/libs/vmath/ray.inl	Sat Feb 01 19:58:19 2014 +0200
   585.3 @@ -0,0 +1,70 @@
   585.4 +/*
   585.5 +libvmath - a vector math library
   585.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   585.7 +
   585.8 +This program is free software: you can redistribute it and/or modify
   585.9 +it under the terms of the GNU Lesser General Public License as published
  585.10 +by the Free Software Foundation, either version 3 of the License, or
  585.11 +(at your option) any later version.
  585.12 +
  585.13 +This program is distributed in the hope that it will be useful,
  585.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  585.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  585.16 +GNU Lesser General Public License for more details.
  585.17 +
  585.18 +You should have received a copy of the GNU Lesser General Public License
  585.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  585.20 +*/
  585.21 +
  585.22 +#ifdef __cplusplus
  585.23 +extern "C" {
  585.24 +#endif	/* __cplusplus */
  585.25 +
  585.26 +static inline ray_t ray_cons(vec3_t origin, vec3_t dir)
  585.27 +{
  585.28 +	ray_t r;
  585.29 +	r.origin = origin;
  585.30 +	r.dir = dir;
  585.31 +	return r;
  585.32 +}
  585.33 +
  585.34 +#ifdef __cplusplus
  585.35 +}
  585.36 +
  585.37 +inline Ray reflect_ray(const Ray &inray, const Vector3 &norm)
  585.38 +{
  585.39 +	Ray ray = inray;
  585.40 +	ray.iter--;
  585.41 +	ray.dir = ray.dir.reflection(norm);
  585.42 +	return ray;
  585.43 +}
  585.44 +
  585.45 +inline Ray refract_ray(const Ray &inray, const Vector3 &norm, scalar_t mat_ior, bool entering, scalar_t ray_mag)
  585.46 +{
  585.47 +	Ray ray = inray;
  585.48 +	ray.iter--;
  585.49 +
  585.50 +	scalar_t ior = ray.calc_ior(entering, mat_ior);
  585.51 +
  585.52 +	if(entering) {
  585.53 +		ray.enter(mat_ior);
  585.54 +	} else {
  585.55 +		ray.leave();
  585.56 +	}
  585.57 +
  585.58 +	if(ray_mag < 0.0) {
  585.59 +		ray_mag = ray.dir.length();
  585.60 +	}
  585.61 +	ray.dir = (ray.dir / ray_mag).refraction(norm, ior) * ray_mag;
  585.62 +
  585.63 +	/* check TIR */
  585.64 +	if(dot_product(ray.dir, norm) > 0.0) {
  585.65 +		if(entering) {
  585.66 +			ray.leave();
  585.67 +		} else {
  585.68 +			ray.enter(mat_ior);
  585.69 +		}
  585.70 +	}
  585.71 +	return ray;
  585.72 +}
  585.73 +#endif	/* __cplusplus */
   586.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   586.2 +++ b/libs/vmath/ray_c.c	Sat Feb 01 19:58:19 2014 +0200
   586.3 @@ -0,0 +1,36 @@
   586.4 +/*
   586.5 +libvmath - a vector math library
   586.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   586.7 +
   586.8 +This program is free software: you can redistribute it and/or modify
   586.9 +it under the terms of the GNU Lesser General Public License as published
  586.10 +by the Free Software Foundation, either version 3 of the License, or
  586.11 +(at your option) any later version.
  586.12 +
  586.13 +This program is distributed in the hope that it will be useful,
  586.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  586.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  586.16 +GNU Lesser General Public License for more details.
  586.17 +
  586.18 +You should have received a copy of the GNU Lesser General Public License
  586.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  586.20 +*/
  586.21 +
  586.22 +#include "ray.h"
  586.23 +#include "vector.h"
  586.24 +
  586.25 +ray_t ray_transform(ray_t r, mat4_t xform)
  586.26 +{
  586.27 +	mat4_t upper;
  586.28 +	vec3_t dir;
  586.29 +
  586.30 +	m4_copy(upper, xform);
  586.31 +	upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0;
  586.32 +	upper[3][3] = 1.0;
  586.33 +
  586.34 +	dir = v3_sub(r.dir, r.origin);
  586.35 +	dir = v3_transform(dir, upper);
  586.36 +	r.origin = v3_transform(r.origin, xform);
  586.37 +	r.dir = v3_add(dir, r.origin);
  586.38 +	return r;
  586.39 +}
   587.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   587.2 +++ b/libs/vmath/sphvec.cc	Sat Feb 01 19:58:19 2014 +0200
   587.3 @@ -0,0 +1,27 @@
   587.4 +#include "sphvec.h"
   587.5 +#include "vector.h"
   587.6 +
   587.7 +/* theta: 0 <= theta <= 2pi, the angle around Y axis.
   587.8 + * phi: 0 <= phi <= pi, the angle from Y axis.
   587.9 + * r: radius.
  587.10 + */
  587.11 +SphVector::SphVector(scalar_t theta, scalar_t phi, scalar_t r) {
  587.12 +	this->theta = theta;
  587.13 +	this->phi = phi;
  587.14 +	this->r = r;
  587.15 +}
  587.16 +
  587.17 +/* Constructs a spherical coordinate vector from a cartesian vector */
  587.18 +SphVector::SphVector(const Vector3 &cvec) {
  587.19 +	*this = cvec;
  587.20 +}
  587.21 +
  587.22 +/* Assignment operator that converts cartesian to spherical coords */
  587.23 +SphVector &SphVector::operator =(const Vector3 &cvec) {
  587.24 +	r = cvec.length();
  587.25 +	//theta = atan2(cvec.y, cvec.x);
  587.26 +	theta = atan2(cvec.z, cvec.x);
  587.27 +	//phi = acos(cvec.z / r);
  587.28 +	phi = acos(cvec.y / r);
  587.29 +	return *this;
  587.30 +}
   588.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   588.2 +++ b/libs/vmath/sphvec.h	Sat Feb 01 19:58:19 2014 +0200
   588.3 @@ -0,0 +1,36 @@
   588.4 +/*
   588.5 +libvmath - a vector math library
   588.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   588.7 +
   588.8 +This program is free software: you can redistribute it and/or modify
   588.9 +it under the terms of the GNU Lesser General Public License as published
  588.10 +by the Free Software Foundation, either version 3 of the License, or
  588.11 +(at your option) any later version.
  588.12 +
  588.13 +This program is distributed in the hope that it will be useful,
  588.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  588.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  588.16 +GNU Lesser General Public License for more details.
  588.17 +
  588.18 +You should have received a copy of the GNU Lesser General Public License
  588.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  588.20 +*/
  588.21 +
  588.22 +#ifndef VMATH_SPHVEC_H_
  588.23 +#define VMATH_SPHVEC_H_
  588.24 +
  588.25 +#include "vmath_types.h"
  588.26 +
  588.27 +#ifdef __cplusplus
  588.28 +/* Vector in spherical coordinates */
  588.29 +class SphVector {
  588.30 +public:
  588.31 +	scalar_t theta, phi, r;
  588.32 +
  588.33 +	SphVector(scalar_t theta = 0.0, scalar_t phi = 0.0, scalar_t r = 1.0);
  588.34 +	SphVector(const Vector3 &cvec);
  588.35 +	SphVector &operator =(const Vector3 &cvec);
  588.36 +};
  588.37 +#endif	/* __cplusplus */
  588.38 +
  588.39 +#endif	/* VMATH_SPHVEC_H_ */
   589.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   589.2 +++ b/libs/vmath/vector.cc	Sat Feb 01 19:58:19 2014 +0200
   589.3 @@ -0,0 +1,326 @@
   589.4 +#include "vector.h"
   589.5 +#include "vmath.h"
   589.6 +
   589.7 +// ---------- Vector2 -----------
   589.8 +
   589.9 +Vector2::Vector2(scalar_t x, scalar_t y)
  589.10 +{
  589.11 +	this->x = x;
  589.12 +	this->y = y;
  589.13 +}
  589.14 +
  589.15 +Vector2::Vector2(const vec2_t &vec)
  589.16 +{
  589.17 +	x = vec.x;
  589.18 +	y = vec.y;
  589.19 +}
  589.20 +
  589.21 +Vector2::Vector2(const Vector3 &vec)
  589.22 +{
  589.23 +	x = vec.x;
  589.24 +	y = vec.y;
  589.25 +}
  589.26 +
  589.27 +Vector2::Vector2(const Vector4 &vec)
  589.28 +{
  589.29 +	x = vec.x;
  589.30 +	y = vec.y;
  589.31 +}
  589.32 +
  589.33 +void Vector2::normalize()
  589.34 +{
  589.35 +	scalar_t len = length();
  589.36 +	x /= len;
  589.37 +	y /= len;
  589.38 +}
  589.39 +
  589.40 +Vector2 Vector2::normalized() const
  589.41 +{
  589.42 +	scalar_t len = length();
  589.43 +	return Vector2(x / len, y / len);
  589.44 +}
  589.45 +
  589.46 +void Vector2::transform(const Matrix3x3 &mat)
  589.47 +{
  589.48 +	scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2];
  589.49 +	y = mat[1][0] * x + mat[1][1] * y + mat[1][2];
  589.50 +	x = nx;
  589.51 +}
  589.52 +
  589.53 +Vector2 Vector2::transformed(const Matrix3x3 &mat) const
  589.54 +{
  589.55 +	Vector2 vec;
  589.56 +	vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2];
  589.57 +	vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2];
  589.58 +	return vec;
  589.59 +}
  589.60 +
  589.61 +void Vector2::rotate(scalar_t angle)
  589.62 +{
  589.63 +	*this = Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y);
  589.64 +}
  589.65 +
  589.66 +Vector2 Vector2::rotated(scalar_t angle) const
  589.67 +{
  589.68 +	return Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y);
  589.69 +}
  589.70 +
  589.71 +Vector2 Vector2::reflection(const Vector2 &normal) const
  589.72 +{
  589.73 +	return 2.0 * dot_product(*this, normal) * normal - *this;
  589.74 +}
  589.75 +
  589.76 +Vector2 Vector2::refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const
  589.77 +{
  589.78 +	// quick and dirty implementation :)
  589.79 +	Vector3 v3refr = Vector3(this->x, this->y, 1.0).refraction(Vector3(this->x, this->y, 1), src_ior, dst_ior);
  589.80 +	return Vector2(v3refr.x, v3refr.y);
  589.81 +}
  589.82 +
  589.83 +std::ostream &operator <<(std::ostream &out, const Vector2 &vec)
  589.84 +{
  589.85 +	out << "[" << vec.x << " " << vec.y << "]";
  589.86 +	return out;
  589.87 +}
  589.88 +
  589.89 +
  589.90 +
  589.91 +// --------- Vector3 ----------
  589.92 +
  589.93 +Vector3::Vector3(scalar_t x, scalar_t y, scalar_t z)
  589.94 +{
  589.95 +	this->x = x;
  589.96 +	this->y = y;
  589.97 +	this->z = z;
  589.98 +}
  589.99 +
 589.100 +Vector3::Vector3(const vec3_t &vec)
 589.101 +{
 589.102 +	x = vec.x;
 589.103 +	y = vec.y;
 589.104 +	z = vec.z;
 589.105 +}
 589.106 +
 589.107 +Vector3::Vector3(const Vector2 &vec)
 589.108 +{
 589.109 +	x = vec.x;
 589.110 +	y = vec.y;
 589.111 +	z = 1;
 589.112 +}
 589.113 +
 589.114 +Vector3::Vector3(const Vector4 &vec)
 589.115 +{
 589.116 +	x = vec.x;
 589.117 +	y = vec.y;
 589.118 +	z = vec.z;
 589.119 +}
 589.120 +
 589.121 +Vector3::Vector3(const SphVector &sph)
 589.122 +{
 589.123 +	*this = sph;
 589.124 +}
 589.125 +
 589.126 +Vector3 &Vector3::operator =(const SphVector &sph)
 589.127 +{
 589.128 +	x = sph.r * cos(sph.theta) * sin(sph.phi);
 589.129 +	z = sph.r * sin(sph.theta) * sin(sph.phi);
 589.130 +	y = sph.r * cos(sph.phi);
 589.131 +	return *this;
 589.132 +}
 589.133 +
 589.134 +void Vector3::normalize()
 589.135 +{
 589.136 +	scalar_t len = length();
 589.137 +	x /= len;
 589.138 +	y /= len;
 589.139 +	z /= len;
 589.140 +}
 589.141 +
 589.142 +Vector3 Vector3::normalized() const
 589.143 +{
 589.144 +	scalar_t len = length();
 589.145 +	return Vector3(x / len, y / len, z / len);
 589.146 +}
 589.147 +
 589.148 +Vector3 Vector3::reflection(const Vector3 &normal) const
 589.149 +{
 589.150 +	return 2.0 * dot_product(*this, normal) * normal - *this;
 589.151 +}
 589.152 +
 589.153 +Vector3 Vector3::refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const
 589.154 +{
 589.155 +	return refraction(normal, src_ior / dst_ior);
 589.156 +}
 589.157 +
 589.158 +Vector3 Vector3::refraction(const Vector3 &normal, scalar_t ior) const
 589.159 +{
 589.160 +	scalar_t cos_inc = dot_product(*this, -normal);
 589.161 +
 589.162 +	scalar_t radical = 1.0 + SQ(ior) * (SQ(cos_inc) - 1.0);
 589.163 +
 589.164 +	if(radical < 0.0) {		// total internal reflection
 589.165 +		return -reflection(normal);
 589.166 +	}
 589.167 +
 589.168 +	scalar_t beta = ior * cos_inc - sqrt(radical);
 589.169 +
 589.170 +	return *this * ior + normal * beta;
 589.171 +}
 589.172 +
 589.173 +void Vector3::transform(const Matrix3x3 &mat)
 589.174 +{
 589.175 +	scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z;
 589.176 +	scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z;
 589.177 +	z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z;
 589.178 +	x = nx;
 589.179 +	y = ny;
 589.180 +}
 589.181 +
 589.182 +Vector3 Vector3::transformed(const Matrix3x3 &mat) const
 589.183 +{
 589.184 +	Vector3 vec;
 589.185 +	vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z;
 589.186 +	vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z;
 589.187 +	vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z;
 589.188 +	return vec;
 589.189 +}
 589.190 +
 589.191 +void Vector3::transform(const Matrix4x4 &mat)
 589.192 +{
 589.193 +	scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3];
 589.194 +	scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3];
 589.195 +	z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3];
 589.196 +	x = nx;
 589.197 +	y = ny;
 589.198 +}
 589.199 +
 589.200 +Vector3 Vector3::transformed(const Matrix4x4 &mat) const
 589.201 +{
 589.202 +	Vector3 vec;
 589.203 +	vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3];
 589.204 +	vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3];
 589.205 +	vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3];
 589.206 +	return vec;
 589.207 +}
 589.208 +
 589.209 +void Vector3::transform(const Quaternion &quat)
 589.210 +{
 589.211 +	Quaternion vq(0.0f, *this);
 589.212 +	vq = quat * vq * quat.inverse();
 589.213 +	*this = vq.v;
 589.214 +}
 589.215 +
 589.216 +Vector3 Vector3::transformed(const Quaternion &quat) const
 589.217 +{
 589.218 +	Quaternion vq(0.0f, *this);
 589.219 +	vq = quat * vq * quat.inverse();
 589.220 +	return vq.v;
 589.221 +}
 589.222 +
 589.223 +void Vector3::rotate(const Vector3 &euler)
 589.224 +{
 589.225 +	Matrix4x4 rot;
 589.226 +	rot.set_rotation(euler);
 589.227 +	transform(rot);
 589.228 +}
 589.229 +
 589.230 +Vector3 Vector3::rotated(const Vector3 &euler) const
 589.231 +{
 589.232 +	Matrix4x4 rot;
 589.233 +	rot.set_rotation(euler);
 589.234 +	return transformed(rot);
 589.235 +}
 589.236 +
 589.237 +std::ostream &operator <<(std::ostream &out, const Vector3 &vec)
 589.238 +{
 589.239 +	out << "[" << vec.x << " " << vec.y << " " << vec.z << "]";
 589.240 +	return out;
 589.241 +}
 589.242 +
 589.243 +
 589.244 +// -------------- Vector4 --------------
 589.245 +Vector4::Vector4(scalar_t x, scalar_t y, scalar_t z, scalar_t w)
 589.246 +{
 589.247 +	this->x = x;
 589.248 +	this->y = y;
 589.249 +	this->z = z;
 589.250 +	this->w = w;
 589.251 +}
 589.252 +
 589.253 +Vector4::Vector4(const vec4_t &vec)
 589.254 +{
 589.255 +	x = vec.x;
 589.256 +	y = vec.y;
 589.257 +	z = vec.z;
 589.258 +	w = vec.w;
 589.259 +}
 589.260 +
 589.261 +Vector4::Vector4(const Vector2 &vec)
 589.262 +{
 589.263 +	x = vec.x;
 589.264 +	y = vec.y;
 589.265 +	z = 1;
 589.266 +	w = 1;
 589.267 +}
 589.268 +
 589.269 +Vector4::Vector4(const Vector3 &vec)
 589.270 +{
 589.271 +	x = vec.x;
 589.272 +	y = vec.y;
 589.273 +	z = vec.z;
 589.274 +	w = 1;
 589.275 +}
 589.276 +
 589.277 +void Vector4::normalize()
 589.278 +{
 589.279 +	scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w);
 589.280 +	x /= len;
 589.281 +	y /= len;
 589.282 +	z /= len;
 589.283 +	w /= len;
 589.284 +}
 589.285 +
 589.286 +Vector4 Vector4::normalized() const
 589.287 +{
 589.288 +	scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w);
 589.289 +	return Vector4(x / len, y / len, z / len, w / len);
 589.290 +}
 589.291 +
 589.292 +void Vector4::transform(const Matrix4x4 &mat)
 589.293 +{
 589.294 +	scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w;
 589.295 +	scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w;
 589.296 +	scalar_t nz = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w;
 589.297 +	w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w;
 589.298 +	x = nx;
 589.299 +	y = ny;
 589.300 +	z = nz;
 589.301 +}
 589.302 +
 589.303 +Vector4 Vector4::transformed(const Matrix4x4 &mat) const
 589.304 +{
 589.305 +	Vector4 vec;
 589.306 +	vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w;
 589.307 +	vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w;
 589.308 +	vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w;
 589.309 +	vec.w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w;
 589.310 +	return vec;
 589.311 +}
 589.312 +
 589.313 +// TODO: implement 4D vector reflection
 589.314 +Vector4 Vector4::reflection(const Vector4 &normal) const
 589.315 +{
 589.316 +	return *this;
 589.317 +}
 589.318 +
 589.319 +// TODO: implement 4D vector refraction
 589.320 +Vector4 Vector4::refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const
 589.321 +{
 589.322 +	return *this;
 589.323 +}
 589.324 +
 589.325 +std::ostream &operator <<(std::ostream &out, const Vector4 &vec)
 589.326 +{
 589.327 +	out << "[" << vec.x << " " << vec.y << " " << vec.z << " " << vec.w << "]";
 589.328 +	return out;
 589.329 +}
   590.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   590.2 +++ b/libs/vmath/vector.h	Sat Feb 01 19:58:19 2014 +0200
   590.3 @@ -0,0 +1,298 @@
   590.4 +/*
   590.5 +libvmath - a vector math library
   590.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   590.7 +
   590.8 +This program is free software: you can redistribute it and/or modify
   590.9 +it under the terms of the GNU Lesser General Public License as published
  590.10 +by the Free Software Foundation, either version 3 of the License, or
  590.11 +(at your option) any later version.
  590.12 +
  590.13 +This program is distributed in the hope that it will be useful,
  590.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  590.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  590.16 +GNU Lesser General Public License for more details.
  590.17 +
  590.18 +You should have received a copy of the GNU Lesser General Public License
  590.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  590.20 +*/
  590.21 +
  590.22 +#ifndef VMATH_VECTOR_H_
  590.23 +#define VMATH_VECTOR_H_
  590.24 +
  590.25 +#include <stdio.h>
  590.26 +#include "vmath_types.h"
  590.27 +
  590.28 +#ifdef __cplusplus
  590.29 +extern "C" {
  590.30 +#endif	/* __cplusplus */
  590.31 +
  590.32 +/* C 2D vector functions */
  590.33 +static inline vec2_t v2_cons(scalar_t x, scalar_t y);
  590.34 +static inline void v2_print(FILE *fp, vec2_t v);
  590.35 +
  590.36 +static inline vec2_t v2_add(vec2_t v1, vec2_t v2);
  590.37 +static inline vec2_t v2_sub(vec2_t v1, vec2_t v2);
  590.38 +static inline vec2_t v2_scale(vec2_t v, scalar_t s);
  590.39 +static inline scalar_t v2_dot(vec2_t v1, vec2_t v2);
  590.40 +static inline scalar_t v2_length(vec2_t v);
  590.41 +static inline scalar_t v2_length_sq(vec2_t v);
  590.42 +static inline vec2_t v2_normalize(vec2_t v);
  590.43 +
  590.44 +static inline vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t);
  590.45 +
  590.46 +/* C 3D vector functions */
  590.47 +static inline vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z);
  590.48 +static inline void v3_print(FILE *fp, vec3_t v);
  590.49 +
  590.50 +static inline vec3_t v3_add(vec3_t v1, vec3_t v2);
  590.51 +static inline vec3_t v3_sub(vec3_t v1, vec3_t v2);
  590.52 +static inline vec3_t v3_neg(vec3_t v);
  590.53 +static inline vec3_t v3_mul(vec3_t v1, vec3_t v2);
  590.54 +static inline vec3_t v3_scale(vec3_t v1, scalar_t s);
  590.55 +static inline scalar_t v3_dot(vec3_t v1, vec3_t v2);
  590.56 +static inline vec3_t v3_cross(vec3_t v1, vec3_t v2);
  590.57 +static inline scalar_t v3_length(vec3_t v);
  590.58 +static inline scalar_t v3_length_sq(vec3_t v);
  590.59 +static inline vec3_t v3_normalize(vec3_t v);
  590.60 +static inline vec3_t v3_transform(vec3_t v, mat4_t m);
  590.61 +
  590.62 +static inline vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z);
  590.63 +static inline vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z);
  590.64 +static inline vec3_t v3_rotate_quat(vec3_t v, quat_t q);
  590.65 +
  590.66 +static inline vec3_t v3_reflect(vec3_t v, vec3_t n);
  590.67 +
  590.68 +static inline vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t);
  590.69 +
  590.70 +/* C 4D vector functions */
  590.71 +static inline vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w);
  590.72 +static inline void v4_print(FILE *fp, vec4_t v);
  590.73 +
  590.74 +static inline vec4_t v4_add(vec4_t v1, vec4_t v2);
  590.75 +static inline vec4_t v4_sub(vec4_t v1, vec4_t v2);
  590.76 +static inline vec4_t v4_neg(vec4_t v);
  590.77 +static inline vec4_t v4_mul(vec4_t v1, vec4_t v2);
  590.78 +static inline vec4_t v4_scale(vec4_t v, scalar_t s);
  590.79 +static inline scalar_t v4_dot(vec4_t v1, vec4_t v2);
  590.80 +static inline scalar_t v4_length(vec4_t v);
  590.81 +static inline scalar_t v4_length_sq(vec4_t v);
  590.82 +static inline vec4_t v4_normalize(vec4_t v);
  590.83 +static inline vec4_t v4_transform(vec4_t v, mat4_t m);
  590.84 +
  590.85 +#ifdef __cplusplus
  590.86 +}	/* extern "C" */
  590.87 +
  590.88 +/* when included from C++ source files, also define the vector classes */
  590.89 +#include <iostream>
  590.90 +
  590.91 +/** 2D Vector */
  590.92 +class Vector2 {
  590.93 +public:
  590.94 +	scalar_t x, y;
  590.95 +
  590.96 +	Vector2(scalar_t x = 0.0, scalar_t y = 0.0);
  590.97 +	Vector2(const vec2_t &vec);
  590.98 +	Vector2(const Vector3 &vec);
  590.99 +	Vector2(const Vector4 &vec);
 590.100 +
 590.101 +	inline scalar_t &operator [](int elem);
 590.102 +	inline const scalar_t &operator [](int elem) const;
 590.103 +
 590.104 +	inline scalar_t length() const;
 590.105 +	inline scalar_t length_sq() const;
 590.106 +	void normalize();
 590.107 +	Vector2 normalized() const;
 590.108 +
 590.109 +	void transform(const Matrix3x3 &mat);
 590.110 +	Vector2 transformed(const Matrix3x3 &mat) const;
 590.111 +
 590.112 +	void rotate(scalar_t angle);
 590.113 +	Vector2 rotated(scalar_t angle) const;
 590.114 +
 590.115 +	Vector2 reflection(const Vector2 &normal) const;
 590.116 +	Vector2 refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const;
 590.117 +};
 590.118 +
 590.119 +/* unary operations */
 590.120 +inline Vector2 operator -(const Vector2 &vec);
 590.121 +
 590.122 +/* binary vector (op) vector operations */
 590.123 +inline scalar_t dot_product(const Vector2 &v1, const Vector2 &v2);
 590.124 +
 590.125 +inline Vector2 operator +(const Vector2 &v1, const Vector2 &v2);
 590.126 +inline Vector2 operator -(const Vector2 &v1, const Vector2 &v2);
 590.127 +inline Vector2 operator *(const Vector2 &v1, const Vector2 &v2);
 590.128 +inline Vector2 operator /(const Vector2 &v1, const Vector2 &v2);
 590.129 +inline bool operator ==(const Vector2 &v1, const Vector2 &v2);
 590.130 +
 590.131 +inline void operator +=(Vector2 &v1, const Vector2 &v2);
 590.132 +inline void operator -=(Vector2 &v1, const Vector2 &v2);
 590.133 +inline void operator *=(Vector2 &v1, const Vector2 &v2);
 590.134 +inline void operator /=(Vector2 &v1, const Vector2 &v2);
 590.135 +
 590.136 +/* binary vector (op) scalar and scalar (op) vector operations */
 590.137 +inline Vector2 operator +(const Vector2 &vec, scalar_t scalar);
 590.138 +inline Vector2 operator +(scalar_t scalar, const Vector2 &vec);
 590.139 +inline Vector2 operator -(const Vector2 &vec, scalar_t scalar);
 590.140 +inline Vector2 operator *(const Vector2 &vec, scalar_t scalar);
 590.141 +inline Vector2 operator *(scalar_t scalar, const Vector2 &vec);
 590.142 +inline Vector2 operator /(const Vector2 &vec, scalar_t scalar);
 590.143 +
 590.144 +inline void operator +=(Vector2 &vec, scalar_t scalar);
 590.145 +inline void operator -=(Vector2 &vec, scalar_t scalar);
 590.146 +inline void operator *=(Vector2 &vec, scalar_t scalar);
 590.147 +inline void operator /=(Vector2 &vec, scalar_t scalar);
 590.148 +
 590.149 +std::ostream &operator <<(std::ostream &out, const Vector2 &vec);
 590.150 +
 590.151 +inline Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t);
 590.152 +inline Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1,
 590.153 +		const Vector2 &v2, const Vector2 &v3, scalar_t t);
 590.154 +inline Vector2 bspline(const Vector2 &v0, const Vector2 &v1,
 590.155 +		const Vector2 &v2, const Vector2 &v3, scalar_t t);
 590.156 +
 590.157 +/* 3D Vector */
 590.158 +class Vector3 {
 590.159 +public:
 590.160 +	scalar_t x, y, z;
 590.161 +
 590.162 +	Vector3(scalar_t x = 0.0, scalar_t y = 0.0, scalar_t z = 0.0);
 590.163 +	Vector3(const vec3_t &vec);
 590.164 +	Vector3(const Vector2 &vec);
 590.165 +	Vector3(const Vector4 &vec);
 590.166 +	Vector3(const SphVector &sph);
 590.167 +
 590.168 +	Vector3 &operator =(const SphVector &sph);
 590.169 +
 590.170 +	inline scalar_t &operator [](int elem);
 590.171 +	inline const scalar_t &operator [](int elem) const;
 590.172 +
 590.173 +	inline scalar_t length() const;
 590.174 +	inline scalar_t length_sq() const;
 590.175 +	void normalize();
 590.176 +	Vector3 normalized() const;
 590.177 +
 590.178 +	void transform(const Matrix3x3 &mat);
 590.179 +	Vector3 transformed(const Matrix3x3 &mat) const;
 590.180 +	void transform(const Matrix4x4 &mat);
 590.181 +	Vector3 transformed(const Matrix4x4 &mat) const;
 590.182 +	void transform(const Quaternion &quat);
 590.183 +	Vector3 transformed(const Quaternion &quat) const;
 590.184 +
 590.185 +	void rotate(const Vector3 &euler);
 590.186 +	Vector3 rotated(const Vector3 &euler) const;
 590.187 +
 590.188 +	Vector3 reflection(const Vector3 &normal) const;
 590.189 +	Vector3 refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const;
 590.190 +	Vector3 refraction(const Vector3 &normal, scalar_t ior) const;
 590.191 +};
 590.192 +
 590.193 +/* unary operations */
 590.194 +inline Vector3 operator -(const Vector3 &vec);
 590.195 +
 590.196 +/* binary vector (op) vector operations */
 590.197 +inline scalar_t dot_product(const Vector3 &v1, const Vector3 &v2);
 590.198 +inline Vector3 cross_product(const Vector3 &v1, const Vector3 &v2);
 590.199 +
 590.200 +inline Vector3 operator +(const Vector3 &v1, const Vector3 &v2);
 590.201 +inline Vector3 operator -(const Vector3 &v1, const Vector3 &v2);
 590.202 +inline Vector3 operator *(const Vector3 &v1, const Vector3 &v2);
 590.203 +inline Vector3 operator /(const Vector3 &v1, const Vector3 &v2);
 590.204 +inline bool operator ==(const Vector3 &v1, const Vector3 &v2);
 590.205 +
 590.206 +inline void operator +=(Vector3 &v1, const Vector3 &v2);
 590.207 +inline void operator -=(Vector3 &v1, const Vector3 &v2);
 590.208 +inline void operator *=(Vector3 &v1, const Vector3 &v2);
 590.209 +inline void operator /=(Vector3 &v1, const Vector3 &v2);
 590.210 +
 590.211 +/* binary vector (op) scalar and scalar (op) vector operations */
 590.212 +inline Vector3 operator +(const Vector3 &vec, scalar_t scalar);
 590.213 +inline Vector3 operator +(scalar_t scalar, const Vector3 &vec);
 590.214 +inline Vector3 operator -(const Vector3 &vec, scalar_t scalar);
 590.215 +inline Vector3 operator *(const Vector3 &vec, scalar_t scalar);
 590.216 +inline Vector3 operator *(scalar_t scalar, const Vector3 &vec);
 590.217 +inline Vector3 operator /(const Vector3 &vec, scalar_t scalar);
 590.218 +
 590.219 +inline void operator +=(Vector3 &vec, scalar_t scalar);
 590.220 +inline void operator -=(Vector3 &vec, scalar_t scalar);
 590.221 +inline void operator *=(Vector3 &vec, scalar_t scalar);
 590.222 +inline void operator /=(Vector3 &vec, scalar_t scalar);
 590.223 +
 590.224 +std::ostream &operator <<(std::ostream &out, const Vector3 &vec);
 590.225 +
 590.226 +inline Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t);
 590.227 +inline Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1,
 590.228 +		const Vector3 &v2, const Vector3 &v3, scalar_t t);
 590.229 +inline Vector3 bspline(const Vector3 &v0, const Vector3 &v1,
 590.230 +		const Vector3 &v2, const Vector3 &v3, scalar_t t);
 590.231 +
 590.232 +/* 4D Vector */
 590.233 +class Vector4 {
 590.234 +public:
 590.235 +	scalar_t x, y, z, w;
 590.236 +
 590.237 +	Vector4(scalar_t x = 0.0, scalar_t y = 0.0, scalar_t z = 0.0, scalar_t w = 0.0);
 590.238 +	Vector4(const vec4_t &vec);
 590.239 +	Vector4(const Vector2 &vec);
 590.240 +	Vector4(const Vector3 &vec);
 590.241 +
 590.242 +	inline scalar_t &operator [](int elem);
 590.243 +	inline const scalar_t &operator [](int elem) const;
 590.244 +
 590.245 +	inline scalar_t length() const;
 590.246 +	inline scalar_t length_sq() const;
 590.247 +	void normalize();
 590.248 +	Vector4 normalized() const;
 590.249 +
 590.250 +	void transform(const Matrix4x4 &mat);
 590.251 +	Vector4 transformed(const Matrix4x4 &mat) const;
 590.252 +
 590.253 +	Vector4 reflection(const Vector4 &normal) const;
 590.254 +	Vector4 refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const;
 590.255 +};
 590.256 +
 590.257 +
 590.258 +/* unary operations */
 590.259 +inline Vector4 operator -(const Vector4 &vec);
 590.260 +
 590.261 +/* binary vector (op) vector operations */
 590.262 +inline scalar_t dot_product(const Vector4 &v1, const Vector4 &v2);
 590.263 +inline Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3);
 590.264 +
 590.265 +inline Vector4 operator +(const Vector4 &v1, const Vector4 &v2);
 590.266 +inline Vector4 operator -(const Vector4 &v1, const Vector4 &v2);
 590.267 +inline Vector4 operator *(const Vector4 &v1, const Vector4 &v2);
 590.268 +inline Vector4 operator /(const Vector4 &v1, const Vector4 &v2);
 590.269 +inline bool operator ==(const Vector4 &v1, const Vector4 &v2);
 590.270 +
 590.271 +inline void operator +=(Vector4 &v1, const Vector4 &v2);
 590.272 +inline void operator -=(Vector4 &v1, const Vector4 &v2);
 590.273 +inline void operator *=(Vector4 &v1, const Vector4 &v2);
 590.274 +inline void operator /=(Vector4 &v1, const Vector4 &v2);
 590.275 +
 590.276 +/* binary vector (op) scalar and scalar (op) vector operations */
 590.277 +inline Vector4 operator +(const Vector4 &vec, scalar_t scalar);
 590.278 +inline Vector4 operator +(scalar_t scalar, const Vector4 &vec);
 590.279 +inline Vector4 operator -(const Vector4 &vec, scalar_t scalar);
 590.280 +inline Vector4 operator *(const Vector4 &vec, scalar_t scalar);
 590.281 +inline Vector4 operator *(scalar_t scalar, const Vector4 &vec);
 590.282 +inline Vector4 operator /(const Vector4 &vec, scalar_t scalar);
 590.283 +
 590.284 +inline void operator +=(Vector4 &vec, scalar_t scalar);
 590.285 +inline void operator -=(Vector4 &vec, scalar_t scalar);
 590.286 +inline void operator *=(Vector4 &vec, scalar_t scalar);
 590.287 +inline void operator /=(Vector4 &vec, scalar_t scalar);
 590.288 +
 590.289 +std::ostream &operator <<(std::ostream &out, const Vector4 &vec);
 590.290 +
 590.291 +inline Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t);
 590.292 +inline Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1,
 590.293 +		const Vector4 &v2, const Vector4 &v3, scalar_t t);
 590.294 +inline Vector4 bspline(const Vector4 &v0, const Vector4 &v1,
 590.295 +		const Vector4 &v2, const Vector4 &v3, scalar_t t);
 590.296 +
 590.297 +#endif	/* __cplusplus */
 590.298 +
 590.299 +#include "vector.inl"
 590.300 +
 590.301 +#endif	/* VMATH_VECTOR_H_ */
   591.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   591.2 +++ b/libs/vmath/vector.inl	Sat Feb 01 19:58:19 2014 +0200
   591.3 @@ -0,0 +1,812 @@
   591.4 +/*
   591.5 +libvmath - a vector math library
   591.6 +Copyright (C) 2004-2013 John Tsiombikas <nuclear@member.fsf.org>
   591.7 +
   591.8 +This program is free software: you can redistribute it and/or modify
   591.9 +it under the terms of the GNU Lesser General Public License as published
  591.10 +by the Free Software Foundation, either version 3 of the License, or
  591.11 +(at your option) any later version.
  591.12 +
  591.13 +This program is distributed in the hope that it will be useful,
  591.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  591.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  591.16 +GNU Lesser General Public License for more details.
  591.17 +
  591.18 +You should have received a copy of the GNU Lesser General Public License
  591.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  591.20 +*/
  591.21 +
  591.22 +#include <math.h>
  591.23 +
  591.24 +#ifdef __cplusplus
  591.25 +extern "C" {
  591.26 +#endif	/* __cplusplus */
  591.27 +
  591.28 +scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t);
  591.29 +scalar_t bspline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t);
  591.30 +
  591.31 +/* C 2D vector functions */
  591.32 +static inline vec2_t v2_cons(scalar_t x, scalar_t y)
  591.33 +{
  591.34 +	vec2_t v;
  591.35 +	v.x = x;
  591.36 +	v.y = y;
  591.37 +	return v;
  591.38 +}
  591.39 +
  591.40 +static inline void v2_print(FILE *fp, vec2_t v)
  591.41 +{
  591.42 +	fprintf(fp, "[ %.4f %.4f ]", v.x, v.y);
  591.43 +}
  591.44 +
  591.45 +static inline vec2_t v2_add(vec2_t v1, vec2_t v2)
  591.46 +{
  591.47 +	vec2_t res;
  591.48 +	res.x = v1.x + v2.x;
  591.49 +	res.y = v1.y + v2.y;
  591.50 +	return res;
  591.51 +}
  591.52 +
  591.53 +static inline vec2_t v2_sub(vec2_t v1, vec2_t v2)
  591.54 +{
  591.55 +	vec2_t res;
  591.56 +	res.x = v1.x - v2.x;
  591.57 +	res.y = v1.y - v2.y;
  591.58 +	return res;
  591.59 +}
  591.60 +
  591.61 +static inline vec2_t v2_scale(vec2_t v, scalar_t s)
  591.62 +{
  591.63 +	vec2_t res;
  591.64 +	res.x = v.x * s;
  591.65 +	res.y = v.y * s;
  591.66 +	return res;
  591.67 +}
  591.68 +
  591.69 +static inline scalar_t v2_dot(vec2_t v1, vec2_t v2)
  591.70 +{
  591.71 +	return v1.x * v2.x + v1.y * v2.y;
  591.72 +}
  591.73 +
  591.74 +static inline scalar_t v2_length(vec2_t v)
  591.75 +{
  591.76 +	return sqrt(v.x * v.x + v.y * v.y);
  591.77 +}
  591.78 +
  591.79 +static inline scalar_t v2_length_sq(vec2_t v)
  591.80 +{
  591.81 +	return v.x * v.x + v.y * v.y;
  591.82 +}
  591.83 +
  591.84 +static inline vec2_t v2_normalize(vec2_t v)
  591.85 +{
  591.86 +	scalar_t len = (scalar_t)sqrt(v.x * v.x + v.y * v.y);
  591.87 +	v.x /= len;
  591.88 +	v.y /= len;
  591.89 +	return v;
  591.90 +}
  591.91 +
  591.92 +static inline vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t)
  591.93 +{
  591.94 +	vec2_t res;
  591.95 +	res.x = v1.x + (v2.x - v1.x) * t;
  591.96 +	res.y = v1.y + (v2.y - v1.y) * t;
  591.97 +	return res;
  591.98 +}
  591.99 +
 591.100 +
 591.101 +/* C 3D vector functions */
 591.102 +static inline vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z)
 591.103 +{
 591.104 +	vec3_t v;
 591.105 +	v.x = x;
 591.106 +	v.y = y;
 591.107 +	v.z = z;
 591.108 +	return v;
 591.109 +}
 591.110 +
 591.111 +static inline void v3_print(FILE *fp, vec3_t v)
 591.112 +{
 591.113 +	fprintf(fp, "[ %.4f %.4f %.4f ]", v.x, v.y, v.z);
 591.114 +}
 591.115 +
 591.116 +static inline vec3_t v3_add(vec3_t v1, vec3_t v2)
 591.117 +{
 591.118 +	v1.x += v2.x;
 591.119 +	v1.y += v2.y;
 591.120 +	v1.z += v2.z;
 591.121 +	return v1;
 591.122 +}
 591.123 +
 591.124 +static inline vec3_t v3_sub(vec3_t v1, vec3_t v2)
 591.125 +{
 591.126 +	v1.x -= v2.x;
 591.127 +	v1.y -= v2.y;
 591.128 +	v1.z -= v2.z;
 591.129 +	return v1;
 591.130 +}
 591.131 +
 591.132 +static inline vec3_t v3_neg(vec3_t v)
 591.133 +{
 591.134 +	v.x = -v.x;
 591.135 +	v.y = -v.y;
 591.136 +	v.z = -v.z;
 591.137 +	return v;
 591.138 +}
 591.139 +
 591.140 +static inline vec3_t v3_mul(vec3_t v1, vec3_t v2)
 591.141 +{
 591.142 +	v1.x *= v2.x;
 591.143 +	v1.y *= v2.y;
 591.144 +	v1.z *= v2.z;
 591.145 +	return v1;
 591.146 +}
 591.147 +
 591.148 +static inline vec3_t v3_scale(vec3_t v1, scalar_t s)
 591.149 +{
 591.150 +	v1.x *= s;
 591.151 +	v1.y *= s;
 591.152 +	v1.z *= s;
 591.153 +	return v1;
 591.154 +}
 591.155 +
 591.156 +static inline scalar_t v3_dot(vec3_t v1, vec3_t v2)
 591.157 +{
 591.158 +	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
 591.159 +}
 591.160 +
 591.161 +static inline vec3_t v3_cross(vec3_t v1, vec3_t v2)
 591.162 +{
 591.163 +	vec3_t v;
 591.164 +	v.x = v1.y * v2.z - v1.z * v2.y;
 591.165 +	v.y = v1.z * v2.x - v1.x * v2.z;
 591.166 +	v.z = v1.x * v2.y - v1.y * v2.x;
 591.167 +	return v;
 591.168 +}
 591.169 +
 591.170 +static inline scalar_t v3_length(vec3_t v)
 591.171 +{
 591.172 +	return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
 591.173 +}
 591.174 +
 591.175 +static inline scalar_t v3_length_sq(vec3_t v)
 591.176 +{
 591.177 +	return v.x * v.x + v.y * v.y + v.z * v.z;
 591.178 +}
 591.179 +
 591.180 +static inline vec3_t v3_normalize(vec3_t v)
 591.181 +{
 591.182 +	scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
 591.183 +	v.x /= len;
 591.184 +	v.y /= len;
 591.185 +	v.z /= len;
 591.186 +	return v;
 591.187 +}
 591.188 +
 591.189 +static inline vec3_t v3_transform(vec3_t v, mat4_t m)
 591.190 +{
 591.191 +	vec3_t res;
 591.192 +	res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3];
 591.193 +	res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3];
 591.194 +	res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3];
 591.195 +	return res;
 591.196 +}
 591.197 +
 591.198 +static inline vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z)
 591.199 +{
 591.200 +	void m4_rotate(mat4_t, scalar_t, scalar_t, scalar_t);
 591.201 +
 591.202 +	mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
 591.203 +	m4_rotate(m, x, y, z);
 591.204 +	return v3_transform(v, m);
 591.205 +}
 591.206 +
 591.207 +static inline vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z)
 591.208 +{
 591.209 +	void m4_rotate_axis(mat4_t, scalar_t, scalar_t, scalar_t, scalar_t);
 591.210 +
 591.211 +	mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
 591.212 +	m4_rotate_axis(m, angle, x, y, z);
 591.213 +	return v3_transform(v, m);
 591.214 +}
 591.215 +
 591.216 +static inline vec3_t v3_rotate_quat(vec3_t v, quat_t q)
 591.217 +{
 591.218 +	quat_t quat_rotate_quat(quat_t, quat_t);
 591.219 +
 591.220 +	quat_t vq = v4_cons(v.x, v.y, v.z, 0.0);
 591.221 +	quat_t res = quat_rotate_quat(vq, q);
 591.222 +	return v3_cons(res.x, res.y, res.z);
 591.223 +}
 591.224 +
 591.225 +static inline vec3_t v3_reflect(vec3_t v, vec3_t n)
 591.226 +{
 591.227 +	scalar_t dot = v3_dot(v, n);
 591.228 +	return v3_sub(v3_scale(n, dot * 2.0), v);
 591.229 +}
 591.230 +
 591.231 +static inline vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t)
 591.232 +{
 591.233 +	v1.x += (v2.x - v1.x) * t;
 591.234 +	v1.y += (v2.y - v1.y) * t;
 591.235 +	v1.z += (v2.z - v1.z) * t;
 591.236 +	return v1;
 591.237 +}
 591.238 +
 591.239 +/* C 4D vector functions */
 591.240 +static inline vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w)
 591.241 +{
 591.242 +	vec4_t v;
 591.243 +	v.x = x;
 591.244 +	v.y = y;
 591.245 +	v.z = z;
 591.246 +	v.w = w;
 591.247 +	return v;
 591.248 +}
 591.249 +
 591.250 +static inline void v4_print(FILE *fp, vec4_t v)
 591.251 +{
 591.252 +	fprintf(fp, "[ %.4f %.4f %.4f %.4f ]", v.x, v.y, v.z, v.w);
 591.253 +}
 591.254 +
 591.255 +static inline vec4_t v4_add(vec4_t v1, vec4_t v2)
 591.256 +{
 591.257 +	v1.x += v2.x;
 591.258 +	v1.y += v2.y;
 591.259 +	v1.z += v2.z;
 591.260 +	v1.w += v2.w;
 591.261 +	return v1;
 591.262 +}
 591.263 +
 591.264 +static inline vec4_t v4_sub(vec4_t v1, vec4_t v2)
 591.265 +{
 591.266 +	v1.x -= v2.x;
 591.267 +	v1.y -= v2.y;
 591.268 +	v1.z -= v2.z;
 591.269 +	v1.w -= v2.w;
 591.270 +	return v1;
 591.271 +}
 591.272 +
 591.273 +static inline vec4_t v4_neg(vec4_t v)
 591.274 +{
 591.275 +	v.x = -v.x;
 591.276 +	v.y = -v.y;
 591.277 +	v.z = -v.z;
 591.278 +	v.w = -v.w;
 591.279 +	return v;
 591.280 +}
 591.281 +
 591.282 +static inline vec4_t v4_mul(vec4_t v1, vec4_t v2)
 591.283 +{
 591.284 +	v1.x *= v2.x;
 591.285 +	v1.y *= v2.y;
 591.286 +	v1.z *= v2.z;
 591.287 +	v1.w *= v2.w;
 591.288 +	return v1;
 591.289 +}
 591.290 +
 591.291 +static inline vec4_t v4_scale(vec4_t v, scalar_t s)
 591.292 +{
 591.293 +	v.x *= s;
 591.294 +	v.y *= s;
 591.295 +	v.z *= s;
 591.296 +	v.w *= s;
 591.297 +	return v;
 591.298 +}
 591.299 +
 591.300 +static inline scalar_t v4_dot(vec4_t v1, vec4_t v2)
 591.301 +{
 591.302 +	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
 591.303 +}
 591.304 +
 591.305 +static inline scalar_t v4_length(vec4_t v)
 591.306 +{
 591.307 +	return sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
 591.308 +}
 591.309 +
 591.310 +static inline scalar_t v4_length_sq(vec4_t v)
 591.311 +{
 591.312 +	return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
 591.313 +}
 591.314 +
 591.315 +static inline vec4_t v4_normalize(vec4_t v)
 591.316 +{
 591.317 +	scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
 591.318 +	v.x /= len;
 591.319 +	v.y /= len;
 591.320 +	v.z /= len;
 591.321 +	v.w /= len;
 591.322 +	return v;
 591.323 +}
 591.324 +
 591.325 +static inline vec4_t v4_transform(vec4_t v, mat4_t m)
 591.326 +{
 591.327 +	vec4_t res;
 591.328 +	res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w;
 591.329 +	res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w;
 591.330 +	res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w;
 591.331 +	res.w = m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w;
 591.332 +	return res;
 591.333 +}
 591.334 +
 591.335 +#ifdef __cplusplus
 591.336 +}	/* extern "C" */
 591.337 +
 591.338 +
 591.339 +/* --------------- C++ part -------------- */
 591.340 +
 591.341 +inline scalar_t &Vector2::operator [](int elem)
 591.342 +{
 591.343 +	return elem ? y : x;
 591.344 +}
 591.345 +
 591.346 +inline const scalar_t &Vector2::operator [](int elem) const
 591.347 +{
 591.348 +	return elem ? y : x;
 591.349 +}
 591.350 +
 591.351 +inline Vector2 operator -(const Vector2 &vec)
 591.352 +{
 591.353 +	return Vector2(-vec.x, -vec.y);
 591.354 +}
 591.355 +
 591.356 +inline scalar_t dot_product(const Vector2 &v1, const Vector2 &v2)
 591.357 +{
 591.358 +	return v1.x * v2.x + v1.y * v2.y;
 591.359 +}
 591.360 +
 591.361 +inline Vector2 operator +(const Vector2 &v1, const Vector2 &v2)
 591.362 +{
 591.363 +	return Vector2(v1.x + v2.x, v1.y + v2.y);
 591.364 +}
 591.365 +
 591.366 +inline Vector2 operator -(const Vector2 &v1, const Vector2 &v2)
 591.367 +{
 591.368 +	return Vector2(v1.x - v2.x, v1.y - v2.y);
 591.369 +}
 591.370 +
 591.371 +inline Vector2 operator *(const Vector2 &v1, const Vector2 &v2)
 591.372 +{
 591.373 +	return Vector2(v1.x * v2.x, v1.y * v2.y);
 591.374 +}
 591.375 +
 591.376 +inline Vector2 operator /(const Vector2 &v1, const Vector2 &v2)
 591.377 +{
 591.378 +	return Vector2(v1.x / v2.x, v1.y / v2.y);
 591.379 +}
 591.380 +
 591.381 +inline bool operator ==(const Vector2 &v1, const Vector2 &v2)
 591.382 +{
 591.383 +	return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.x) < XSMALL_NUMBER);
 591.384 +}
 591.385 +
 591.386 +inline void operator +=(Vector2 &v1, const Vector2 &v2)
 591.387 +{
 591.388 +	v1.x += v2.x;
 591.389 +	v1.y += v2.y;
 591.390 +}
 591.391 +
 591.392 +inline void operator -=(Vector2 &v1, const Vector2 &v2)
 591.393 +{
 591.394 +	v1.x -= v2.x;
 591.395 +	v1.y -= v2.y;
 591.396 +}
 591.397 +
 591.398 +inline void operator *=(Vector2 &v1, const Vector2 &v2)
 591.399 +{
 591.400 +	v1.x *= v2.x;
 591.401 +	v1.y *= v2.y;
 591.402 +}
 591.403 +
 591.404 +inline void operator /=(Vector2 &v1, const Vector2 &v2)
 591.405 +{
 591.406 +	v1.x /= v2.x;
 591.407 +	v1.y /= v2.y;
 591.408 +}
 591.409 +
 591.410 +inline Vector2 operator +(const Vector2 &vec, scalar_t scalar)
 591.411 +{
 591.412 +	return Vector2(vec.x + scalar, vec.y + scalar);
 591.413 +}
 591.414 +
 591.415 +inline Vector2 operator +(scalar_t scalar, const Vector2 &vec)
 591.416 +{
 591.417 +	return Vector2(vec.x + scalar, vec.y + scalar);
 591.418 +}
 591.419 +
 591.420 +inline Vector2 operator -(const Vector2 &vec, scalar_t scalar)
 591.421 +{
 591.422 +	return Vector2(vec.x - scalar, vec.y - scalar);
 591.423 +}
 591.424 +
 591.425 +inline Vector2 operator *(const Vector2 &vec, scalar_t scalar)
 591.426 +{
 591.427 +	return Vector2(vec.x * scalar, vec.y * scalar);
 591.428 +}
 591.429 +
 591.430 +inline Vector2 operator *(scalar_t scalar, const Vector2 &vec)
 591.431 +{
 591.432 +	return Vector2(vec.x * scalar, vec.y * scalar);
 591.433 +}
 591.434 +
 591.435 +inline Vector2 operator /(const Vector2 &vec, scalar_t scalar)
 591.436 +{
 591.437 +	return Vector2(vec.x / scalar, vec.y / scalar);
 591.438 +}
 591.439 +
 591.440 +inline void operator +=(Vector2 &vec, scalar_t scalar)
 591.441 +{
 591.442 +	vec.x += scalar;
 591.443 +	vec.y += scalar;
 591.444 +}
 591.445 +
 591.446 +inline void operator -=(Vector2 &vec, scalar_t scalar)
 591.447 +{
 591.448 +	vec.x -= scalar;
 591.449 +	vec.y -= scalar;
 591.450 +}
 591.451 +
 591.452 +inline void operator *=(Vector2 &vec, scalar_t scalar)
 591.453 +{
 591.454 +	vec.x *= scalar;
 591.455 +	vec.y *= scalar;
 591.456 +}
 591.457 +
 591.458 +inline void operator /=(Vector2 &vec, scalar_t scalar)
 591.459 +{
 591.460 +	vec.x /= scalar;
 591.461 +	vec.y /= scalar;
 591.462 +}
 591.463 +
 591.464 +inline scalar_t Vector2::length() const
 591.465 +{
 591.466 +	return sqrt(x*x + y*y);
 591.467 +}
 591.468 +
 591.469 +inline scalar_t Vector2::length_sq() const
 591.470 +{
 591.471 +	return x*x + y*y;
 591.472 +}
 591.473 +
 591.474 +inline Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t)
 591.475 +{
 591.476 +	return a + (b - a) * t;
 591.477 +}
 591.478 +
 591.479 +inline Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1,
 591.480 +		const Vector2 &v2, const Vector2 &v3, scalar_t t)
 591.481 +{
 591.482 +	scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
 591.483 +	scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
 591.484 +	return Vector2(x, y);
 591.485 +}
 591.486 +
 591.487 +inline Vector2 bspline(const Vector2 &v0, const Vector2 &v1,
 591.488 +		const Vector2 &v2, const Vector2 &v3, scalar_t t)
 591.489 +{
 591.490 +	scalar_t x = bspline(v0.x, v1.x, v2.x, v3.x, t);
 591.491 +	scalar_t y = bspline(v0.y, v1.y, v2.y, v3.y, t);
 591.492 +	return Vector2(x, y);
 591.493 +}
 591.494 +
 591.495 +
 591.496 +/* ------------- Vector3 -------------- */
 591.497 +
 591.498 +inline scalar_t &Vector3::operator [](int elem) {
 591.499 +	return elem ? (elem == 1 ? y : z) : x;
 591.500 +}
 591.501 +
 591.502 +inline const scalar_t &Vector3::operator [](int elem) const {
 591.503 +	return elem ? (elem == 1 ? y : z) : x;
 591.504 +}
 591.505 +
 591.506 +/* unary operations */
 591.507 +inline Vector3 operator -(const Vector3 &vec) {
 591.508 +	return Vector3(-vec.x, -vec.y, -vec.z);
 591.509 +}
 591.510 +
 591.511 +/* binary vector (op) vector operations */
 591.512 +inline scalar_t dot_product(const Vector3 &v1, const Vector3 &v2) {
 591.513 +	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
 591.514 +}
 591.515 +
 591.516 +inline Vector3 cross_product(const Vector3 &v1, const Vector3 &v2) {
 591.517 +	return Vector3(v1.y * v2.z - v1.z * v2.y,  v1.z * v2.x - v1.x * v2.z,  v1.x * v2.y - v1.y * v2.x);
 591.518 +}
 591.519 +
 591.520 +
 591.521 +inline Vector3 operator +(const Vector3 &v1, const Vector3 &v2) {
 591.522 +	return Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
 591.523 +}
 591.524 +
 591.525 +inline Vector3 operator -(const Vector3 &v1, const Vector3 &v2) {
 591.526 +	return Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
 591.527 +}
 591.528 +
 591.529 +inline Vector3 operator *(const Vector3 &v1, const Vector3 &v2) {
 591.530 +	return Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
 591.531 +}
 591.532 +
 591.533 +inline Vector3 operator /(const Vector3 &v1, const Vector3 &v2) {
 591.534 +	return Vector3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z);
 591.535 +}
 591.536 +
 591.537 +inline bool operator ==(const Vector3 &v1, const Vector3 &v2) {
 591.538 +	return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.y) < XSMALL_NUMBER) && (fabs(v1.z - v2.z) < XSMALL_NUMBER);
 591.539 +}
 591.540 +
 591.541 +inline void operator +=(Vector3 &v1, const Vector3 &v2) {
 591.542 +	v1.x += v2.x;
 591.543 +	v1.y += v2.y;
 591.544 +	v1.z += v2.z;
 591.545 +}
 591.546 +
 591.547 +inline void operator -=(Vector3 &v1, const Vector3 &v2) {
 591.548 +	v1.x -= v2.x;
 591.549 +	v1.y -= v2.y;
 591.550 +	v1.z -= v2.z;
 591.551 +}
 591.552 +
 591.553 +inline void operator *=(Vector3 &v1, const Vector3 &v2) {
 591.554 +	v1.x *= v2.x;
 591.555 +	v1.y *= v2.y;
 591.556 +	v1.z *= v2.z;
 591.557 +}
 591.558 +
 591.559 +inline void operator /=(Vector3 &v1, const Vector3 &v2) {
 591.560 +	v1.x /= v2.x;
 591.561 +	v1.y /= v2.y;
 591.562 +	v1.z /= v2.z;
 591.563 +}
 591.564 +/* binary vector (op) scalar and scalar (op) vector operations */
 591.565 +inline Vector3 operator +(const Vector3 &vec, scalar_t scalar) {
 591.566 +	return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar);
 591.567 +}
 591.568 +
 591.569 +inline Vector3 operator +(scalar_t scalar, const Vector3 &vec) {
 591.570 +	return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar);
 591.571 +}
 591.572 +
 591.573 +inline Vector3 operator -(const Vector3 &vec, scalar_t scalar) {
 591.574 +	return Vector3(vec.x - scalar, vec.y - scalar, vec.z - scalar);
 591.575 +}
 591.576 +
 591.577 +inline Vector3 operator *(const Vector3 &vec, scalar_t scalar) {
 591.578 +	return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
 591.579 +}
 591.580 +
 591.581 +inline Vector3 operator *(scalar_t scalar, const Vector3 &vec) {
 591.582 +	return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
 591.583 +}
 591.584 +
 591.585 +inline Vector3 operator /(const Vector3 &vec, scalar_t scalar) {
 591.586 +	return Vector3(vec.x / scalar, vec.y / scalar, vec.z / scalar);
 591.587 +}
 591.588 +
 591.589 +inline void operator +=(Vector3 &vec, scalar_t scalar) {
 591.590 +	vec.x += scalar;
 591.591 +	vec.y += scalar;
 591.592 +	vec.z += scalar;
 591.593 +}
 591.594 +
 591.595 +inline void operator -=(Vector3 &vec, scalar_t scalar) {
 591.596 +	vec.x -= scalar;
 591.597 +	vec.y -= scalar;
 591.598 +	vec.z -= scalar;
 591.599 +}
 591.600 +
 591.601 +inline void operator *=(Vector3 &vec, scalar_t scalar) {
 591.602 +	vec.x *= scalar;
 591.603 +	vec.y *= scalar;
 591.604 +	vec.z *= scalar;
 591.605 +}
 591.606 +
 591.607 +inline void operator /=(Vector3 &vec, scalar_t scalar) {
 591.608 +	vec.x /= scalar;
 591.609 +	vec.y /= scalar;
 591.610 +	vec.z /= scalar;
 591.611 +}
 591.612 +
 591.613 +inline scalar_t Vector3::length() const {
 591.614 +	return sqrt(x*x + y*y + z*z);
 591.615 +}
 591.616 +inline scalar_t Vector3::length_sq() const {
 591.617 +	return x*x + y*y + z*z;
 591.618 +}
 591.619 +
 591.620 +inline Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t) {
 591.621 +	return a + (b - a) * t;
 591.622 +}
 591.623 +
 591.624 +inline Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1,
 591.625 +		const Vector3 &v2, const Vector3 &v3, scalar_t t)
 591.626 +{
 591.627 +	scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
 591.628 +	scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
 591.629 +	scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t);
 591.630 +	return Vector3(x, y, z);
 591.631 +}
 591.632 +
 591.633 +inline Vector3 bspline(const Vector3 &v0, const Vector3 &v1,
 591.634 +		const Vector3 &v2, const Vector3 &v3, scalar_t t)
 591.635 +{
 591.636 +	scalar_t x = bspline(v0.x, v1.x, v2.x, v3.x, t);
 591.637 +	scalar_t y = bspline(v0.y, v1.y, v2.y, v3.y, t);
 591.638 +	scalar_t z = bspline(v0.z, v1.z, v2.z, v3.z, t);
 591.639 +	return Vector3(x, y, z);
 591.640 +}
 591.641 +
 591.642 +/* ----------- Vector4 ----------------- */
 591.643 +
 591.644 +inline scalar_t &Vector4::operator [](int elem) {
 591.645 +	return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x;
 591.646 +}
 591.647 +
 591.648 +inline const scalar_t &Vector4::operator [](int elem) const {
 591.649 +	return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x;
 591.650 +}
 591.651 +
 591.652 +inline Vector4 operator -(const Vector4 &vec) {
 591.653 +	return Vector4(-vec.x, -vec.y, -vec.z, -vec.w);
 591.654 +}
 591.655 +
 591.656 +inline scalar_t dot_product(const Vector4 &v1, const Vector4 &v2) {
 591.657 +	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
 591.658 +}
 591.659 +
 591.660 +inline Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3) {
 591.661 +	scalar_t a, b, c, d, e, f;       /* Intermediate Values */
 591.662 +    Vector4 result;
 591.663 +
 591.664 +    /* Calculate intermediate values. */
 591.665 +    a = (v2.x * v3.y) - (v2.y * v3.x);
 591.666 +    b = (v2.x * v3.z) - (v2.z * v3.x);
 591.667 +    c = (v2.x * v3.w) - (v2.w * v3.x);
 591.668 +    d = (v2.y * v3.z) - (v2.z * v3.y);
 591.669 +    e = (v2.y * v3.w) - (v2.w * v3.y);
 591.670 +    f = (v2.z * v3.w) - (v2.w * v3.z);
 591.671 +
 591.672 +    /* Calculate the result-vector components. */
 591.673 +    result.x =   (v1.y * f) - (v1.z * e) + (v1.w * d);
 591.674 +    result.y = - (v1.x * f) + (v1.z * c) - (v1.w * b);
 591.675 +    result.z =   (v1.x * e) - (v1.y * c) + (v1.w * a);
 591.676 +    result.w = - (v1.x * d) + (v1.y * b) - (v1.z * a);
 591.677 +    return result;
 591.678 +}
 591.679 +
 591.680 +inline Vector4 operator +(const Vector4 &v1, const Vector4 &v2) {
 591.681 +	return Vector4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
 591.682 +}
 591.683 +
 591.684 +inline Vector4 operator -(const Vector4 &v1, const Vector4 &v2) {
 591.685 +	return Vector4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
 591.686 +}
 591.687 +
 591.688 +inline Vector4 operator *(const Vector4 &v1, const Vector4 &v2) {
 591.689 +	return Vector4(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w);
 591.690 +}
 591.691 +
 591.692 +inline Vector4 operator /(const Vector4 &v1, const Vector4 &v2) {
 591.693 +	return Vector4(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w);
 591.694 +}
 591.695 +
 591.696 +inline bool operator ==(const Vector4 &v1, const Vector4 &v2) {
 591.697 +	return	(fabs(v1.x - v2.x) < XSMALL_NUMBER) &&
 591.698 +			(fabs(v1.y - v2.y) < XSMALL_NUMBER) &&
 591.699 +			(fabs(v1.z - v2.z) < XSMALL_NUMBER) &&
 591.700 +			(fabs(v1.w - v2.w) < XSMALL_NUMBER);
 591.701 +}
 591.702 +
 591.703 +inline void operator +=(Vector4 &v1, const Vector4 &v2) {
 591.704 +	v1.x += v2.x;
 591.705 +	v1.y += v2.y;
 591.706 +	v1.z += v2.z;
 591.707 +	v1.w += v2.w;
 591.708 +}
 591.709 +
 591.710 +inline void operator -=(Vector4 &v1, const Vector4 &v2) {
 591.711 +	v1.x -= v2.x;
 591.712 +	v1.y -= v2.y;
 591.713 +	v1.z -= v2.z;
 591.714 +	v1.w -= v2.w;
 591.715 +}
 591.716 +
 591.717 +inline void operator *=(Vector4 &v1, const Vector4 &v2) {
 591.718 +	v1.x *= v2.x;
 591.719 +	v1.y *= v2.y;
 591.720 +	v1.z *= v2.z;
 591.721 +	v1.w *= v2.w;
 591.722 +}
 591.723 +
 591.724 +inline void operator /=(Vector4 &v1, const Vector4 &v2) {
 591.725 +	v1.x /= v2.x;
 591.726 +	v1.y /= v2.y;
 591.727 +	v1.z /= v2.z;
 591.728 +	v1.w /= v2.w;
 591.729 +}
 591.730 +
 591.731 +/* binary vector (op) scalar and scalar (op) vector operations */
 591.732 +inline Vector4 operator +(const Vector4 &vec, scalar_t scalar) {
 591.733 +	return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar);
 591.734 +}
 591.735 +
 591.736 +inline Vector4 operator +(scalar_t scalar, const Vector4 &vec) {
 591.737 +	return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar);
 591.738 +}
 591.739 +
 591.740 +inline Vector4 operator -(const Vector4 &vec, scalar_t scalar) {
 591.741 +	return Vector4(vec.x - scalar, vec.y - scalar, vec.z - scalar, vec.w - scalar);
 591.742 +}
 591.743 +
 591.744 +inline Vector4 operator *(const Vector4 &vec, scalar_t scalar) {
 591.745 +	return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar);
 591.746 +}
 591.747 +
 591.748 +inline Vector4 operator *(scalar_t scalar, const Vector4 &vec) {
 591.749 +	return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar);
 591.750 +}
 591.751 +
 591.752 +inline Vector4 operator /(const Vector4 &vec, scalar_t scalar) {
 591.753 +	return Vector4(vec.x / scalar, vec.y / scalar, vec.z / scalar, vec.w / scalar);
 591.754 +}
 591.755 +
 591.756 +inline void operator +=(Vector4 &vec, scalar_t scalar) {
 591.757 +	vec.x += scalar;
 591.758 +	vec.y += scalar;
 591.759 +	vec.z += scalar;
 591.760 +	vec.w += scalar;
 591.761 +}
 591.762 +
 591.763 +inline void operator -=(Vector4 &vec, scalar_t scalar) {
 591.764 +	vec.x -= scalar;
 591.765 +	vec.y -= scalar;
 591.766 +	vec.z -= scalar;
 591.767 +	vec.w -= scalar;
 591.768 +}
 591.769 +
 591.770 +inline void operator *=(Vector4 &vec, scalar_t scalar) {
 591.771 +	vec.x *= scalar;
 591.772 +	vec.y *= scalar;
 591.773 +	vec.z *= scalar;
 591.774 +	vec.w *= scalar;
 591.775 +}
 591.776 +
 591.777 +inline void operator /=(Vector4 &vec, scalar_t scalar) {
 591.778 +	vec.x /= scalar;
 591.779 +	vec.y /= scalar;
 591.780 +	vec.z /= scalar;
 591.781 +	vec.w /= scalar;
 591.782 +}
 591.783 +
 591.784 +inline scalar_t Vector4::length() const {
 591.785 +	return sqrt(x*x + y*y + z*z + w*w);
 591.786 +}
 591.787 +inline scalar_t Vector4::length_sq() const {
 591.788 +	return x*x + y*y + z*z + w*w;
 591.789 +}
 591.790 +
 591.791 +inline Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t)
 591.792 +{
 591.793 +	return v0 + (v1 - v0) * t;
 591.794 +}
 591.795 +
 591.796 +inline Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1,
 591.797 +		const Vector4 &v2, const Vector4 &v3, scalar_t t)
 591.798 +{
 591.799 +	scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
 591.800 +	scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
 591.801 +	scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t);
 591.802 +	scalar_t w = spline(v0.w, v1.w, v2.w, v3.w, t);
 591.803 +	return Vector4(x, y, z, w);
 591.804 +}
 591.805 +
 591.806 +inline Vector4 bspline(const Vector4 &v0, const Vector4 &v1,
 591.807 +		const Vector4 &v2, const Vector4 &v3, scalar_t t)
 591.808 +{
 591.809 +	scalar_t x = bspline(v0.x, v1.x, v2.x, v3.x, t);
 591.810 +	scalar_t y = bspline(v0.y, v1.y, v2.y, v3.y, t);
 591.811 +	scalar_t z = bspline(v0.z, v1.z, v2.z, v3.z, t);
 591.812 +	scalar_t w = bspline(v0.w, v1.w, v2.w, v3.w, t);
 591.813 +	return Vector4(x, y, z, w);
 591.814 +}
 591.815 +#endif	/* __cplusplus */
   592.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   592.2 +++ b/libs/vmath/vmath.c	Sat Feb 01 19:58:19 2014 +0200
   592.3 @@ -0,0 +1,386 @@
   592.4 +/*
   592.5 +libvmath - a vector math library
   592.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   592.7 +
   592.8 +This program is free software: you can redistribute it and/or modify
   592.9 +it under the terms of the GNU Lesser General Public License as published
  592.10 +by the Free Software Foundation, either version 3 of the License, or
  592.11 +(at your option) any later version.
  592.12 +
  592.13 +This program is distributed in the hope that it will be useful,
  592.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  592.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  592.16 +GNU Lesser General Public License for more details.
  592.17 +
  592.18 +You should have received a copy of the GNU Lesser General Public License
  592.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  592.20 +*/
  592.21 +#include <stdlib.h>
  592.22 +#include <math.h>
  592.23 +#include "vmath.h"
  592.24 +
  592.25 +#if defined(__APPLE__) && !defined(TARGET_IPHONE)
  592.26 +#include <xmmintrin.h>
  592.27 +
  592.28 +void enable_fpexcept(void)
  592.29 +{
  592.30 +	unsigned int bits;
  592.31 +	bits = _MM_MASK_INVALID | _MM_MASK_DIV_ZERO | _MM_MASK_OVERFLOW | _MM_MASK_UNDERFLOW;
  592.32 +	_MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~bits);
  592.33 +}
  592.34 +
  592.35 +void disable_fpexcept(void)
  592.36 +{
  592.37 +	unsigned int bits;
  592.38 +	bits = _MM_MASK_INVALID | _MM_MASK_DIV_ZERO | _MM_MASK_OVERFLOW | _MM_MASK_UNDERFLOW;
  592.39 +	_MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() | bits);
  592.40 +}
  592.41 +
  592.42 +#elif defined(__GNUC__) && !defined(TARGET_IPHONE)
  592.43 +#define __USE_GNU
  592.44 +#include <fenv.h>
  592.45 +
  592.46 +void enable_fpexcept(void)
  592.47 +{
  592.48 +	feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW);
  592.49 +}
  592.50 +
  592.51 +void disable_fpexcept(void)
  592.52 +{
  592.53 +	fedisableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW);
  592.54 +}
  592.55 +
  592.56 +#elif defined(_MSC_VER)
  592.57 +#include <float.h>
  592.58 +
  592.59 +void enable_fpexcept(void)
  592.60 +{
  592.61 +	_clearfp();
  592.62 +	_controlfp(_controlfp(0, 0) & ~(_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW), _MCW_EM);
  592.63 +}
  592.64 +
  592.65 +void disable_fpexcept(void)
  592.66 +{
  592.67 +	_clearfp();
  592.68 +	_controlfp(_controlfp(0, 0) | (_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW), _MCW_EM);
  592.69 +}
  592.70 +#else
  592.71 +void enable_fpexcept(void) {}
  592.72 +void disable_fpexcept(void) {}
  592.73 +#endif
  592.74 +
  592.75 +
  592.76 +/** Numerical calculation of integrals using simpson's rule */
  592.77 +scalar_t integral(scalar_t (*f)(scalar_t), scalar_t low, scalar_t high, int samples)
  592.78 +{
  592.79 +	int i;
  592.80 +	scalar_t h = (high - low) / (scalar_t)samples;
  592.81 +	scalar_t sum = 0.0;
  592.82 +
  592.83 +	for(i=0; i<samples+1; i++) {
  592.84 +		scalar_t y = f((scalar_t)i * h + low);
  592.85 +		sum += ((!i || i == samples) ? y : ((i % 2) ? 4.0 * y : 2.0 * y)) * (h / 3.0);
  592.86 +	}
  592.87 +	return sum;
  592.88 +}
  592.89 +
  592.90 +/** Gaussuan function */
  592.91 +scalar_t gaussian(scalar_t x, scalar_t mean, scalar_t sdev)
  592.92 +{
  592.93 +	scalar_t exponent = -SQ(x - mean) / (2.0 * SQ(sdev));
  592.94 +	return 1.0 - -pow(M_E, exponent) / (sdev * sqrt(TWO_PI));
  592.95 +}
  592.96 +
  592.97 +
  592.98 +/** b-spline approximation */
  592.99 +scalar_t bspline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t)
 592.100 +{
 592.101 +	vec4_t tmp;
 592.102 +	scalar_t tsq = t * t;
 592.103 +
 592.104 +	static mat4_t bspline_mat = {
 592.105 +		{-1,  3, -3,  1},
 592.106 +		{3, -6,  3,  0},
 592.107 +		{-3,  0,  3,  0},
 592.108 +		{1,  4,  1,  0}
 592.109 +	};
 592.110 +
 592.111 +	tmp = v4_scale(v4_transform(v4_cons(a, b, c, d), bspline_mat), 1.0 / 6.0);
 592.112 +	return v4_dot(v4_cons(tsq * t, tsq, t, 1.0), tmp);
 592.113 +}
 592.114 +
 592.115 +/** Catmull-rom spline interpolation */
 592.116 +scalar_t spline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t)
 592.117 +{
 592.118 +	vec4_t tmp;
 592.119 +	scalar_t tsq = t * t;
 592.120 +
 592.121 +	static mat4_t crspline_mat = {
 592.122 +		{-1,  3, -3,  1},
 592.123 +		{2, -5,  4, -1},
 592.124 +		{-1,  0,  1,  0},
 592.125 +		{0,  2,  0,  0}
 592.126 +	};
 592.127 +
 592.128 +	tmp = v4_scale(v4_transform(v4_cons(a, b, c, d), crspline_mat), 0.5);
 592.129 +	return v4_dot(v4_cons(tsq * t, tsq, t, 1.0), tmp);
 592.130 +}
 592.131 +
 592.132 +/** Bezier interpolation */
 592.133 +scalar_t bezier(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t)
 592.134 +{
 592.135 +	scalar_t omt, omt3, t3, f;
 592.136 +	t3 = t * t * t;
 592.137 +	omt = 1.0f - t;
 592.138 +	omt3 = omt * omt * omt;
 592.139 +	f = 3 * t * omt;
 592.140 +
 592.141 +	return (a * omt3) + (b * f * omt) + (c * f * t) + (d * t3);
 592.142 +}
 592.143 +
 592.144 +/* ---- Ken Perlin's implementation of noise ---- */
 592.145 +
 592.146 +#define B	0x100
 592.147 +#define BM	0xff
 592.148 +#define N	0x1000
 592.149 +#define NP	12   /* 2^N */
 592.150 +#define NM	0xfff
 592.151 +
 592.152 +#define s_curve(t) (t * t * (3.0f - 2.0f * t))
 592.153 +
 592.154 +#define setup(elem, b0, b1, r0, r1) \
 592.155 +	do {							\
 592.156 +		scalar_t t = elem + N;		\
 592.157 +		b0 = ((int)t) & BM;			\
 592.158 +		b1 = (b0 + 1) & BM;			\
 592.159 +		r0 = t - (int)t;			\
 592.160 +		r1 = r0 - 1.0f;				\
 592.161 +	} while(0)
 592.162 +
 592.163 +
 592.164 +static int perm[B + B + 2];			/* permuted index from g_n onto themselves */
 592.165 +static vec3_t grad3[B + B + 2];		/* 3D random gradients */
 592.166 +static vec2_t grad2[B + B + 2];		/* 2D random gradients */
 592.167 +static scalar_t grad1[B + B + 2];	/* 1D random ... slopes */
 592.168 +static int tables_valid;
 592.169 +
 592.170 +static void init_noise()
 592.171 +{
 592.172 +	int i;
 592.173 +
 592.174 +	/* calculate random gradients */
 592.175 +	for(i=0; i<B; i++) {
 592.176 +		perm[i] = i;	/* .. and initialize permutation mapping to identity */
 592.177 +
 592.178 +		grad1[i] = (scalar_t)((rand() % (B + B)) - B) / B;
 592.179 +
 592.180 +		grad2[i].x = (scalar_t)((rand() % (B + B)) - B) / B;
 592.181 +		grad2[i].y = (scalar_t)((rand() % (B + B)) - B) / B;
 592.182 +		grad2[i] = v2_normalize(grad2[i]);
 592.183 +
 592.184 +		grad3[i].x = (scalar_t)((rand() % (B + B)) - B) / B;
 592.185 +		grad3[i].y = (scalar_t)((rand() % (B + B)) - B) / B;
 592.186 +		grad3[i].z = (scalar_t)((rand() % (B + B)) - B) / B;
 592.187 +		grad3[i] = v3_normalize(grad3[i]);
 592.188 +	}
 592.189 +
 592.190 +	/* permute indices by swapping them randomly */
 592.191 +	for(i=0; i<B; i++) {
 592.192 +		int rand_idx = rand() % B;
 592.193 +
 592.194 +		int tmp = perm[i];
 592.195 +		perm[i] = perm[rand_idx];
 592.196 +		perm[rand_idx] = tmp;
 592.197 +	}
 592.198 +
 592.199 +	/* fill up the rest of the arrays by duplicating the existing gradients */
 592.200 +	/* and permutations */
 592.201 +	for(i=0; i<B+2; i++) {
 592.202 +		perm[B + i] = perm[i];
 592.203 +		grad1[B + i] = grad1[i];
 592.204 +		grad2[B + i] = grad2[i];
 592.205 +		grad3[B + i] = grad3[i];
 592.206 +	}
 592.207 +}
 592.208 +
 592.209 +scalar_t noise1(scalar_t x)
 592.210 +{
 592.211 +	int bx0, bx1;
 592.212 +	scalar_t rx0, rx1, sx, u, v;
 592.213 +
 592.214 +	if(!tables_valid) {
 592.215 +		init_noise();
 592.216 +		tables_valid = 1;
 592.217 +	}
 592.218 +
 592.219 +	setup(x, bx0, bx1, rx0, rx1);
 592.220 +	sx = s_curve(rx0);
 592.221 +	u = rx0 * grad1[perm[bx0]];
 592.222 +	v = rx1 * grad1[perm[bx1]];
 592.223 +
 592.224 +	return lerp(u, v, sx);
 592.225 +}
 592.226 +
 592.227 +scalar_t noise2(scalar_t x, scalar_t y)
 592.228 +{
 592.229 +	int i, j, b00, b10, b01, b11;
 592.230 +	int bx0, bx1, by0, by1;
 592.231 +	scalar_t rx0, rx1, ry0, ry1;
 592.232 +	scalar_t sx, sy, u, v, a, b;
 592.233 +
 592.234 +	if(!tables_valid) {
 592.235 +		init_noise();
 592.236 +		tables_valid = 1;
 592.237 +	}
 592.238 +
 592.239 +	setup(x, bx0, bx1, rx0, rx1);
 592.240 +	setup(y, by0, by1, ry0, ry1);
 592.241 +
 592.242 +	i = perm[bx0];
 592.243 +	j = perm[bx1];
 592.244 +
 592.245 +	b00 = perm[i + by0];
 592.246 +	b10 = perm[j + by0];
 592.247 +	b01 = perm[i + by1];
 592.248 +	b11 = perm[j + by1];
 592.249 +
 592.250 +	/* calculate hermite inteprolating factors */
 592.251 +	sx = s_curve(rx0);
 592.252 +	sy = s_curve(ry0);
 592.253 +
 592.254 +	/* interpolate along the left edge */
 592.255 +	u = v2_dot(grad2[b00], v2_cons(rx0, ry0));
 592.256 +	v = v2_dot(grad2[b10], v2_cons(rx1, ry0));
 592.257 +	a = lerp(u, v, sx);
 592.258 +
 592.259 +	/* interpolate along the right edge */
 592.260 +	u = v2_dot(grad2[b01], v2_cons(rx0, ry1));
 592.261 +	v = v2_dot(grad2[b11], v2_cons(rx1, ry1));
 592.262 +	b = lerp(u, v, sx);
 592.263 +
 592.264 +	/* interpolate between them */
 592.265 +	return lerp(a, b, sy);
 592.266 +}
 592.267 +
 592.268 +scalar_t noise3(scalar_t x, scalar_t y, scalar_t z)
 592.269 +{
 592.270 +	int i, j;
 592.271 +	int bx0, bx1, by0, by1, bz0, bz1;
 592.272 +	int b00, b10, b01, b11;
 592.273 +	scalar_t rx0, rx1, ry0, ry1, rz0, rz1;
 592.274 +	scalar_t sx, sy, sz;
 592.275 +	scalar_t u, v, a, b, c, d;
 592.276 +
 592.277 +	if(!tables_valid) {
 592.278 +		init_noise();
 592.279 +		tables_valid = 1;
 592.280 +	}
 592.281 +
 592.282 +	setup(x, bx0, bx1, rx0, rx1);
 592.283 +	setup(y, by0, by1, ry0, ry1);
 592.284 +	setup(z, bz0, bz1, rz0, rz1);
 592.285 +
 592.286 +	i = perm[bx0];
 592.287 +	j = perm[bx1];
 592.288 +
 592.289 +	b00 = perm[i + by0];
 592.290 +	b10 = perm[j + by0];
 592.291 +	b01 = perm[i + by1];
 592.292 +	b11 = perm[j + by1];
 592.293 +
 592.294 +	/* calculate hermite interpolating factors */
 592.295 +	sx = s_curve(rx0);
 592.296 +	sy = s_curve(ry0);
 592.297 +	sz = s_curve(rz0);
 592.298 +
 592.299 +	/* interpolate along the top slice of the cell */
 592.300 +	u = v3_dot(grad3[b00 + bz0], v3_cons(rx0, ry0, rz0));
 592.301 +	v = v3_dot(grad3[b10 + bz0], v3_cons(rx1, ry0, rz0));
 592.302 +	a = lerp(u, v, sx);
 592.303 +
 592.304 +	u = v3_dot(grad3[b01 + bz0], v3_cons(rx0, ry1, rz0));
 592.305 +	v = v3_dot(grad3[b11 + bz0], v3_cons(rx1, ry1, rz0));
 592.306 +	b = lerp(u, v, sx);
 592.307 +
 592.308 +	c = lerp(a, b, sy);
 592.309 +
 592.310 +	/* interpolate along the bottom slice of the cell */
 592.311 +	u = v3_dot(grad3[b00 + bz0], v3_cons(rx0, ry0, rz1));
 592.312 +	v = v3_dot(grad3[b10 + bz0], v3_cons(rx1, ry0, rz1));
 592.313 +	a = lerp(u, v, sx);
 592.314 +
 592.315 +	u = v3_dot(grad3[b01 + bz0], v3_cons(rx0, ry1, rz1));
 592.316 +	v = v3_dot(grad3[b11 + bz0], v3_cons(rx1, ry1, rz1));
 592.317 +	b = lerp(u, v, sx);
 592.318 +
 592.319 +	d = lerp(a, b, sy);
 592.320 +
 592.321 +	/* interpolate between slices */
 592.322 +	return lerp(c, d, sz);
 592.323 +}
 592.324 +
 592.325 +scalar_t fbm1(scalar_t x, int octaves)
 592.326 +{
 592.327 +	int i;
 592.328 +	scalar_t res = 0.0f, freq = 1.0f;
 592.329 +	for(i=0; i<octaves; i++) {
 592.330 +		res += noise1(x * freq) / freq;
 592.331 +		freq *= 2.0f;
 592.332 +	}
 592.333 +	return res;
 592.334 +}
 592.335 +
 592.336 +scalar_t fbm2(scalar_t x, scalar_t y, int octaves)
 592.337 +{
 592.338 +	int i;
 592.339 +	scalar_t res = 0.0f, freq = 1.0f;
 592.340 +	for(i=0; i<octaves; i++) {
 592.341 +		res += noise2(x * freq, y * freq) / freq;
 592.342 +		freq *= 2.0f;
 592.343 +	}
 592.344 +	return res;
 592.345 +}
 592.346 +
 592.347 +scalar_t fbm3(scalar_t x, scalar_t y, scalar_t z, int octaves)
 592.348 +{
 592.349 +	int i;
 592.350 +	scalar_t res = 0.0f, freq = 1.0f;
 592.351 +	for(i=0; i<octaves; i++) {
 592.352 +		res += noise3(x * freq, y * freq, z * freq) / freq;
 592.353 +		freq *= 2.0f;
 592.354 +	}
 592.355 +	return res;
 592.356 +}
 592.357 +
 592.358 +scalar_t turbulence1(scalar_t x, int octaves)
 592.359 +{
 592.360 +	int i;
 592.361 +	scalar_t res = 0.0f, freq = 1.0f;
 592.362 +	for(i=0; i<octaves; i++) {
 592.363 +		res += fabs(noise1(x * freq) / freq);
 592.364 +		freq *= 2.0f;
 592.365 +	}
 592.366 +	return res;
 592.367 +}
 592.368 +
 592.369 +scalar_t turbulence2(scalar_t x, scalar_t y, int octaves)
 592.370 +{
 592.371 +	int i;
 592.372 +	scalar_t res = 0.0f, freq = 1.0f;
 592.373 +	for(i=0; i<octaves; i++) {
 592.374 +		res += fabs(noise2(x * freq, y * freq) / freq);
 592.375 +		freq *= 2.0f;
 592.376 +	}
 592.377 +	return res;
 592.378 +}
 592.379 +
 592.380 +scalar_t turbulence3(scalar_t x, scalar_t y, scalar_t z, int octaves)
 592.381 +{
 592.382 +	int i;
 592.383 +	scalar_t res = 0.0f, freq = 1.0f;
 592.384 +	for(i=0; i<octaves; i++) {
 592.385 +		res += fabs(noise3(x * freq, y * freq, z * freq) / freq);
 592.386 +		freq *= 2.0f;
 592.387 +	}
 592.388 +	return res;
 592.389 +}
   593.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   593.2 +++ b/libs/vmath/vmath.h	Sat Feb 01 19:58:19 2014 +0200
   593.3 @@ -0,0 +1,97 @@
   593.4 +/*
   593.5 +libvmath - a vector math library
   593.6 +Copyright (C) 2004-2013 John Tsiombikas <nuclear@member.fsf.org>
   593.7 +
   593.8 +This program is free software: you can redistribute it and/or modify
   593.9 +it under the terms of the GNU Lesser General Public License as published
  593.10 +by the Free Software Foundation, either version 3 of the License, or
  593.11 +(at your option) any later version.
  593.12 +
  593.13 +This program is distributed in the hope that it will be useful,
  593.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  593.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  593.16 +GNU Lesser General Public License for more details.
  593.17 +
  593.18 +You should have received a copy of the GNU Lesser General Public License
  593.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  593.20 +*/
  593.21 +
  593.22 +#ifndef VMATH_H_
  593.23 +#define VMATH_H_
  593.24 +
  593.25 +#include <math.h>
  593.26 +#include "vmath_types.h"
  593.27 +
  593.28 +#ifndef M_PI
  593.29 +#define M_PI	PI
  593.30 +#endif
  593.31 +
  593.32 +#ifndef M_E
  593.33 +#define M_E				2.718281828459045
  593.34 +#endif
  593.35 +
  593.36 +#define PI				3.141592653589793
  593.37 +#define HALF_PI			1.570796326794897
  593.38 +#define QUARTER_PI		0.785398163397448
  593.39 +#define TWO_PI			6.283185307179586
  593.40 +
  593.41 +
  593.42 +#define RAD_TO_DEG(a) ((((scalar_t)a) * 360.0) / TWO_PI)
  593.43 +#define DEG_TO_RAD(a) (((scalar_t)a) * (PI / 180.0))
  593.44 +
  593.45 +#define SQ(x) ((x) * (x))
  593.46 +
  593.47 +#define MIN(a, b)	((a) < (b) ? (a) : (b))
  593.48 +#define MAX(a, b)	((a) > (b) ? (a) : (b))
  593.49 +
  593.50 +#ifndef __GNUC__
  593.51 +#define round(x)	((x) >= 0 ? (x) + 0.5 : (x) - 0.5)
  593.52 +#endif
  593.53 +
  593.54 +#ifdef __cplusplus
  593.55 +extern "C" {
  593.56 +#endif	/* __cplusplus */
  593.57 +
  593.58 +void enable_fpexcept(void);
  593.59 +void disable_fpexcept(void);
  593.60 +
  593.61 +static inline scalar_t smoothstep(float a, float b, float x);
  593.62 +
  593.63 +static inline scalar_t frand(scalar_t range);
  593.64 +static inline vec3_t sphrand(scalar_t rad);
  593.65 +
  593.66 +scalar_t integral(scalar_t (*f)(scalar_t), scalar_t low, scalar_t high, int samples);
  593.67 +scalar_t gaussian(scalar_t x, scalar_t mean, scalar_t sdev);
  593.68 +
  593.69 +static inline scalar_t lerp(scalar_t a, scalar_t b, scalar_t t);
  593.70 +
  593.71 +scalar_t bspline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t);
  593.72 +scalar_t spline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t);
  593.73 +scalar_t bezier(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t);
  593.74 +
  593.75 +scalar_t noise1(scalar_t x);
  593.76 +scalar_t noise2(scalar_t x, scalar_t y);
  593.77 +scalar_t noise3(scalar_t x, scalar_t y, scalar_t z);
  593.78 +
  593.79 +scalar_t fbm1(scalar_t x, int octaves);
  593.80 +scalar_t fbm2(scalar_t x, scalar_t y, int octaves);
  593.81 +scalar_t fbm3(scalar_t x, scalar_t y, scalar_t z, int octaves);
  593.82 +
  593.83 +scalar_t turbulence1(scalar_t x, int octaves);
  593.84 +scalar_t turbulence2(scalar_t x, scalar_t y, int octaves);
  593.85 +scalar_t turbulence3(scalar_t x, scalar_t y, scalar_t z, int octaves);
  593.86 +
  593.87 +#ifdef __cplusplus
  593.88 +}
  593.89 +#endif	/* __cplusplus */
  593.90 +
  593.91 +#include "vmath.inl"
  593.92 +
  593.93 +#include "vector.h"
  593.94 +#include "matrix.h"
  593.95 +#include "quat.h"
  593.96 +#include "sphvec.h"
  593.97 +#include "ray.h"
  593.98 +#include "geom.h"
  593.99 +
 593.100 +#endif	/* VMATH_H_ */
   594.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   594.2 +++ b/libs/vmath/vmath.inl	Sat Feb 01 19:58:19 2014 +0200
   594.3 @@ -0,0 +1,56 @@
   594.4 +/*
   594.5 +libvmath - a vector math library
   594.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   594.7 +
   594.8 +This program is free software: you can redistribute it and/or modify
   594.9 +it under the terms of the GNU Lesser General Public License as published
  594.10 +by the Free Software Foundation, either version 3 of the License, or
  594.11 +(at your option) any later version.
  594.12 +
  594.13 +This program is distributed in the hope that it will be useful,
  594.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  594.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  594.16 +GNU Lesser General Public License for more details.
  594.17 +
  594.18 +You should have received a copy of the GNU Lesser General Public License
  594.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  594.20 +*/
  594.21 +
  594.22 +#include <stdlib.h>
  594.23 +
  594.24 +static inline scalar_t smoothstep(float a, float b, float x)
  594.25 +{
  594.26 +	if(x < a) return 0.0;
  594.27 +	if(x >= b) return 1.0;
  594.28 +
  594.29 +	x = (x - a) / (b - a);
  594.30 +	return x * x * (3.0 - 2.0 * x);
  594.31 +}
  594.32 +
  594.33 +/** Generates a random number in [0, range) */
  594.34 +static inline scalar_t frand(scalar_t range)
  594.35 +{
  594.36 +	return range * (scalar_t)rand() / (scalar_t)RAND_MAX;
  594.37 +}
  594.38 +
  594.39 +/** Generates a random vector on the surface of a sphere */
  594.40 +static inline vec3_t sphrand(scalar_t rad)
  594.41 +{
  594.42 +	scalar_t u = (scalar_t)rand() / RAND_MAX;
  594.43 +	scalar_t v = (scalar_t)rand() / RAND_MAX;
  594.44 +
  594.45 +	scalar_t theta = 2.0 * M_PI * u;
  594.46 +	scalar_t phi = acos(2.0 * v - 1.0);
  594.47 +
  594.48 +	vec3_t res;
  594.49 +	res.x = rad * cos(theta) * sin(phi);
  594.50 +	res.y = rad * sin(theta) * sin(phi);
  594.51 +	res.z = rad * cos(phi);
  594.52 +	return res;
  594.53 +}
  594.54 +
  594.55 +/** linear interpolation */
  594.56 +static inline scalar_t lerp(scalar_t a, scalar_t b, scalar_t t)
  594.57 +{
  594.58 +	return a + (b - a) * t;
  594.59 +}
   595.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   595.2 +++ b/libs/vmath/vmath_config.h	Sat Feb 01 19:58:19 2014 +0200
   595.3 @@ -0,0 +1,19 @@
   595.4 +#ifndef VMATH_CONFIG_H_
   595.5 +#define VMATH_CONFIG_H_
   595.6 +
   595.7 +#if (__STDC_VERSION__ < 199999) && !defined(__cplusplus)
   595.8 +#if defined(__GNUC__) || defined(_MSC_VER)
   595.9 +#define inline __inline
  595.10 +#else
  595.11 +#define inline
  595.12 +
  595.13 +#ifdef VECTOR_H_
  595.14 +#warning "compiling vector operations without inline, performance might suffer"
  595.15 +#endif	/* VECTOR_H_ */
  595.16 +
  595.17 +#endif	/* gcc/msvc */
  595.18 +#endif	/* not C99 */
  595.19 +
  595.20 +#define SINGLE_PRECISION_MATH
  595.21 +
  595.22 +#endif	/* VMATH_CONFIG_H_ */
   596.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   596.2 +++ b/libs/vmath/vmath_types.h	Sat Feb 01 19:58:19 2014 +0200
   596.3 @@ -0,0 +1,58 @@
   596.4 +/*
   596.5 +libvmath - a vector math library
   596.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
   596.7 +
   596.8 +This program is free software: you can redistribute it and/or modify
   596.9 +it under the terms of the GNU Lesser General Public License as published
  596.10 +by the Free Software Foundation, either version 3 of the License, or
  596.11 +(at your option) any later version.
  596.12 +
  596.13 +This program is distributed in the hope that it will be useful,
  596.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  596.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  596.16 +GNU Lesser General Public License for more details.
  596.17 +
  596.18 +You should have received a copy of the GNU Lesser General Public License
  596.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
  596.20 +*/
  596.21 +
  596.22 +#ifndef VMATH_TYPES_H_
  596.23 +#define VMATH_TYPES_H_
  596.24 +
  596.25 +#include "vmath_config.h"
  596.26 +
  596.27 +#define SMALL_NUMBER	1.e-4
  596.28 +#define XSMALL_NUMBER	1.e-8
  596.29 +#define ERROR_MARGIN	1.e-6
  596.30 +
  596.31 +
  596.32 +#ifdef SINGLE_PRECISION_MATH
  596.33 +typedef float scalar_t;
  596.34 +#else
  596.35 +typedef double scalar_t;
  596.36 +#endif	/* floating point precision */
  596.37 +
  596.38 +/* vectors */
  596.39 +typedef struct { scalar_t x, y; } vec2_t;
  596.40 +typedef struct { scalar_t x, y, z; } vec3_t;
  596.41 +typedef struct { scalar_t x, y, z, w; } vec4_t;
  596.42 +
  596.43 +/* quaternions */
  596.44 +typedef vec4_t quat_t;
  596.45 +
  596.46 +/* matrices */
  596.47 +typedef scalar_t mat3_t[3][3];
  596.48 +typedef scalar_t mat4_t[4][4];
  596.49 +
  596.50 +
  596.51 +#ifdef __cplusplus
  596.52 +class Vector2;
  596.53 +class Vector3;
  596.54 +class Vector4;
  596.55 +class Quaternion;
  596.56 +class Matrix3x3;
  596.57 +class Matrix4x4;
  596.58 +class SphVector;
  596.59 +#endif	/* __cplusplus */
  596.60 +
  596.61 +#endif	/* VMATH_TYPES_H_ */
   597.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   597.2 +++ b/libs/vorbis/AUTHORS	Sat Feb 01 19:58:19 2014 +0200
   597.3 @@ -0,0 +1,3 @@
   597.4 +Monty <monty@xiph.org>
   597.5 +
   597.6 +and the rest of the Xiph.org Foundation.
   598.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   598.2 +++ b/libs/vorbis/COPYING	Sat Feb 01 19:58:19 2014 +0200
   598.3 @@ -0,0 +1,28 @@
   598.4 +Copyright (c) 2002-2008 Xiph.org Foundation
   598.5 +
   598.6 +Redistribution and use in source and binary forms, with or without
   598.7 +modification, are permitted provided that the following conditions
   598.8 +are met:
   598.9 +
  598.10 +- Redistributions of source code must retain the above copyright
  598.11 +notice, this list of conditions and the following disclaimer.
  598.12 +
  598.13 +- Redistributions in binary form must reproduce the above copyright
  598.14 +notice, this list of conditions and the following disclaimer in the
  598.15 +documentation and/or other materials provided with the distribution.
  598.16 +
  598.17 +- Neither the name of the Xiph.org Foundation nor the names of its
  598.18 +contributors may be used to endorse or promote products derived from
  598.19 +this software without specific prior written permission.
  598.20 +
  598.21 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  598.22 +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  598.23 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  598.24 +A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
  598.25 +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  598.26 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  598.27 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  598.28 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  598.29 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  598.30 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  598.31 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   599.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   599.2 +++ b/libs/vorbis/analysis.c	Sat Feb 01 19:58:19 2014 +0200
   599.3 @@ -0,0 +1,120 @@
   599.4 +/********************************************************************
   599.5 + *                                                                  *
   599.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   599.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   599.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   599.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  599.10 + *                                                                  *
  599.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  599.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  599.13 + *                                                                  *
  599.14 + ********************************************************************
  599.15 +
  599.16 + function: single-block PCM analysis mode dispatch
  599.17 + last mod: $Id: analysis.c 16226 2009-07-08 06:43:49Z xiphmont $
  599.18 +
  599.19 + ********************************************************************/
  599.20 +
  599.21 +#include <stdio.h>
  599.22 +#include <string.h>
  599.23 +#include <math.h>
  599.24 +#include <ogg/ogg.h>
  599.25 +#include "vorbis/codec.h"
  599.26 +#include "codec_internal.h"
  599.27 +#include "registry.h"
  599.28 +#include "scales.h"
  599.29 +#include "os.h"
  599.30 +#include "misc.h"
  599.31 +
  599.32 +/* decides between modes, dispatches to the appropriate mapping. */
  599.33 +int vorbis_analysis(vorbis_block *vb, ogg_packet *op){
  599.34 +  int ret,i;
  599.35 +  vorbis_block_internal *vbi=vb->internal;
  599.36 +
  599.37 +  vb->glue_bits=0;
  599.38 +  vb->time_bits=0;
  599.39 +  vb->floor_bits=0;
  599.40 +  vb->res_bits=0;
  599.41 +
  599.42 +  /* first things first.  Make sure encode is ready */
  599.43 +  for(i=0;i<PACKETBLOBS;i++)
  599.44 +    oggpack_reset(vbi->packetblob[i]);
  599.45 +
  599.46 +  /* we only have one mapping type (0), and we let the mapping code
  599.47 +     itself figure out what soft mode to use.  This allows easier
  599.48 +     bitrate management */
  599.49 +
  599.50 +  if((ret=_mapping_P[0]->forward(vb)))
  599.51 +    return(ret);
  599.52 +
  599.53 +  if(op){
  599.54 +    if(vorbis_bitrate_managed(vb))
  599.55 +      /* The app is using a bitmanaged mode... but not using the
  599.56 +         bitrate management interface. */
  599.57 +      return(OV_EINVAL);
  599.58 +
  599.59 +    op->packet=oggpack_get_buffer(&vb->opb);
  599.60 +    op->bytes=oggpack_bytes(&vb->opb);
  599.61 +    op->b_o_s=0;
  599.62 +    op->e_o_s=vb->eofflag;
  599.63 +    op->granulepos=vb->granulepos;
  599.64 +    op->packetno=vb->sequence; /* for sake of completeness */
  599.65 +  }
  599.66 +  return(0);
  599.67 +}
  599.68 +
  599.69 +#ifdef ANALYSIS
  599.70 +int analysis_noisy=1;
  599.71 +
  599.72 +/* there was no great place to put this.... */
  599.73 +void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,ogg_int64_t off){
  599.74 +  int j;
  599.75 +  FILE *of;
  599.76 +  char buffer[80];
  599.77 +
  599.78 +  sprintf(buffer,"%s_%d.m",base,i);
  599.79 +  of=fopen(buffer,"w");
  599.80 +
  599.81 +  if(!of)perror("failed to open data dump file");
  599.82 +
  599.83 +  for(j=0;j<n;j++){
  599.84 +    if(bark){
  599.85 +      float b=toBARK((4000.f*j/n)+.25);
  599.86 +      fprintf(of,"%f ",b);
  599.87 +    }else
  599.88 +      if(off!=0)
  599.89 +        fprintf(of,"%f ",(double)(j+off)/8000.);
  599.90 +      else
  599.91 +        fprintf(of,"%f ",(double)j);
  599.92 +
  599.93 +    if(dB){
  599.94 +      float val;
  599.95 +      if(v[j]==0.)
  599.96 +        val=-140.;
  599.97 +      else
  599.98 +        val=todB(v+j);
  599.99 +      fprintf(of,"%f\n",val);
 599.100 +    }else{
 599.101 +      fprintf(of,"%f\n",v[j]);
 599.102 +    }
 599.103 +  }
 599.104 +  fclose(of);
 599.105 +}
 599.106 +
 599.107 +void _analysis_output(char *base,int i,float *v,int n,int bark,int dB,
 599.108 +                      ogg_int64_t off){
 599.109 +  if(analysis_noisy)_analysis_output_always(base,i,v,n,bark,dB,off);
 599.110 +}
 599.111 +
 599.112 +#endif
 599.113 +
 599.114 +
 599.115 +
 599.116 +
 599.117 +
 599.118 +
 599.119 +
 599.120 +
 599.121 +
 599.122 +
 599.123 +
   600.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   600.2 +++ b/libs/vorbis/backends.h	Sat Feb 01 19:58:19 2014 +0200
   600.3 @@ -0,0 +1,144 @@
   600.4 +/********************************************************************
   600.5 + *                                                                  *
   600.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   600.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   600.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   600.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  600.10 + *                                                                  *
  600.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  600.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  600.13 + *                                                                  *
  600.14 + ********************************************************************
  600.15 +
  600.16 + function: libvorbis backend and mapping structures; needed for
  600.17 +           static mode headers
  600.18 + last mod: $Id: backends.h 16962 2010-03-11 07:30:34Z xiphmont $
  600.19 +
  600.20 + ********************************************************************/
  600.21 +
  600.22 +/* this is exposed up here because we need it for static modes.
  600.23 +   Lookups for each backend aren't exposed because there's no reason
  600.24 +   to do so */
  600.25 +
  600.26 +#ifndef _vorbis_backend_h_
  600.27 +#define _vorbis_backend_h_
  600.28 +
  600.29 +#include "codec_internal.h"
  600.30 +
  600.31 +/* this would all be simpler/shorter with templates, but.... */
  600.32 +/* Floor backend generic *****************************************/
  600.33 +typedef struct{
  600.34 +  void                   (*pack)  (vorbis_info_floor *,oggpack_buffer *);
  600.35 +  vorbis_info_floor     *(*unpack)(vorbis_info *,oggpack_buffer *);
  600.36 +  vorbis_look_floor     *(*look)  (vorbis_dsp_state *,vorbis_info_floor *);
  600.37 +  void (*free_info) (vorbis_info_floor *);
  600.38 +  void (*free_look) (vorbis_look_floor *);
  600.39 +  void *(*inverse1)  (struct vorbis_block *,vorbis_look_floor *);
  600.40 +  int   (*inverse2)  (struct vorbis_block *,vorbis_look_floor *,
  600.41 +                     void *buffer,float *);
  600.42 +} vorbis_func_floor;
  600.43 +
  600.44 +typedef struct{
  600.45 +  int   order;
  600.46 +  long  rate;
  600.47 +  long  barkmap;
  600.48 +
  600.49 +  int   ampbits;
  600.50 +  int   ampdB;
  600.51 +
  600.52 +  int   numbooks; /* <= 16 */
  600.53 +  int   books[16];
  600.54 +
  600.55 +  float lessthan;     /* encode-only config setting hacks for libvorbis */
  600.56 +  float greaterthan;  /* encode-only config setting hacks for libvorbis */
  600.57 +
  600.58 +} vorbis_info_floor0;
  600.59 +
  600.60 +
  600.61 +#define VIF_POSIT 63
  600.62 +#define VIF_CLASS 16
  600.63 +#define VIF_PARTS 31
  600.64 +typedef struct{
  600.65 +  int   partitions;                /* 0 to 31 */
  600.66 +  int   partitionclass[VIF_PARTS]; /* 0 to 15 */
  600.67 +
  600.68 +  int   class_dim[VIF_CLASS];        /* 1 to 8 */
  600.69 +  int   class_subs[VIF_CLASS];       /* 0,1,2,3 (bits: 1<<n poss) */
  600.70 +  int   class_book[VIF_CLASS];       /* subs ^ dim entries */
  600.71 +  int   class_subbook[VIF_CLASS][8]; /* [VIF_CLASS][subs] */
  600.72 +
  600.73 +
  600.74 +  int   mult;                      /* 1 2 3 or 4 */
  600.75 +  int   postlist[VIF_POSIT+2];    /* first two implicit */
  600.76 +
  600.77 +
  600.78 +  /* encode side analysis parameters */
  600.79 +  float maxover;
  600.80 +  float maxunder;
  600.81 +  float maxerr;
  600.82 +
  600.83 +  float twofitweight;
  600.84 +  float twofitatten;
  600.85 +
  600.86 +  int   n;
  600.87 +
  600.88 +} vorbis_info_floor1;
  600.89 +
  600.90 +/* Residue backend generic *****************************************/
  600.91 +typedef struct{
  600.92 +  void                 (*pack)  (vorbis_info_residue *,oggpack_buffer *);
  600.93 +  vorbis_info_residue *(*unpack)(vorbis_info *,oggpack_buffer *);
  600.94 +  vorbis_look_residue *(*look)  (vorbis_dsp_state *,
  600.95 +                                 vorbis_info_residue *);
  600.96 +  void (*free_info)    (vorbis_info_residue *);
  600.97 +  void (*free_look)    (vorbis_look_residue *);
  600.98 +  long **(*class)      (struct vorbis_block *,vorbis_look_residue *,
  600.99 +                        int **,int *,int);
 600.100 +  int  (*forward)      (oggpack_buffer *,struct vorbis_block *,
 600.101 +                        vorbis_look_residue *,
 600.102 +                        int **,int *,int,long **,int);
 600.103 +  int  (*inverse)      (struct vorbis_block *,vorbis_look_residue *,
 600.104 +                        float **,int *,int);
 600.105 +} vorbis_func_residue;
 600.106 +
 600.107 +typedef struct vorbis_info_residue0{
 600.108 +/* block-partitioned VQ coded straight residue */
 600.109 +  long  begin;
 600.110 +  long  end;
 600.111 +
 600.112 +  /* first stage (lossless partitioning) */
 600.113 +  int    grouping;         /* group n vectors per partition */
 600.114 +  int    partitions;       /* possible codebooks for a partition */
 600.115 +  int    partvals;         /* partitions ^ groupbook dim */
 600.116 +  int    groupbook;        /* huffbook for partitioning */
 600.117 +  int    secondstages[64]; /* expanded out to pointers in lookup */
 600.118 +  int    booklist[512];    /* list of second stage books */
 600.119 +
 600.120 +  const int classmetric1[64];
 600.121 +  const int classmetric2[64];
 600.122 +} vorbis_info_residue0;
 600.123 +
 600.124 +/* Mapping backend generic *****************************************/
 600.125 +typedef struct{
 600.126 +  void                 (*pack)  (vorbis_info *,vorbis_info_mapping *,
 600.127 +                                 oggpack_buffer *);
 600.128 +  vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *);
 600.129 +  void (*free_info)    (vorbis_info_mapping *);
 600.130 +  int  (*forward)      (struct vorbis_block *vb);
 600.131 +  int  (*inverse)      (struct vorbis_block *vb,vorbis_info_mapping *);
 600.132 +} vorbis_func_mapping;
 600.133 +
 600.134 +typedef struct vorbis_info_mapping0{
 600.135 +  int   submaps;  /* <= 16 */
 600.136 +  int   chmuxlist[256];   /* up to 256 channels in a Vorbis stream */
 600.137 +
 600.138 +  int   floorsubmap[16];   /* [mux] submap to floors */
 600.139 +  int   residuesubmap[16]; /* [mux] submap to residue */
 600.140 +
 600.141 +  int   coupling_steps;
 600.142 +  int   coupling_mag[256];
 600.143 +  int   coupling_ang[256];
 600.144 +
 600.145 +} vorbis_info_mapping0;
 600.146 +
 600.147 +#endif
   601.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   601.2 +++ b/libs/vorbis/bitrate.c	Sat Feb 01 19:58:19 2014 +0200
   601.3 @@ -0,0 +1,253 @@
   601.4 +/********************************************************************
   601.5 + *                                                                  *
   601.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   601.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   601.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   601.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  601.10 + *                                                                  *
  601.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  601.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  601.13 + *                                                                  *
  601.14 + ********************************************************************
  601.15 +
  601.16 + function: bitrate tracking and management
  601.17 + last mod: $Id: bitrate.c 16227 2009-07-08 06:58:46Z xiphmont $
  601.18 +
  601.19 + ********************************************************************/
  601.20 +
  601.21 +#include <stdlib.h>
  601.22 +#include <string.h>
  601.23 +#include <math.h>
  601.24 +#include <ogg/ogg.h>
  601.25 +#include "vorbis/codec.h"
  601.26 +#include "codec_internal.h"
  601.27 +#include "os.h"
  601.28 +#include "misc.h"
  601.29 +#include "bitrate.h"
  601.30 +
  601.31 +/* compute bitrate tracking setup  */
  601.32 +void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){
  601.33 +  codec_setup_info *ci=vi->codec_setup;
  601.34 +  bitrate_manager_info *bi=&ci->bi;
  601.35 +
  601.36 +  memset(bm,0,sizeof(*bm));
  601.37 +
  601.38 +  if(bi && (bi->reservoir_bits>0)){
  601.39 +    long ratesamples=vi->rate;
  601.40 +    int  halfsamples=ci->blocksizes[0]>>1;
  601.41 +
  601.42 +    bm->short_per_long=ci->blocksizes[1]/ci->blocksizes[0];
  601.43 +    bm->managed=1;
  601.44 +
  601.45 +    bm->avg_bitsper= rint(1.*bi->avg_rate*halfsamples/ratesamples);
  601.46 +    bm->min_bitsper= rint(1.*bi->min_rate*halfsamples/ratesamples);
  601.47 +    bm->max_bitsper= rint(1.*bi->max_rate*halfsamples/ratesamples);
  601.48 +
  601.49 +    bm->avgfloat=PACKETBLOBS/2;
  601.50 +
  601.51 +    /* not a necessary fix, but one that leads to a more balanced
  601.52 +       typical initialization */
  601.53 +    {
  601.54 +      long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
  601.55 +      bm->minmax_reservoir=desired_fill;
  601.56 +      bm->avg_reservoir=desired_fill;
  601.57 +    }
  601.58 +
  601.59 +  }
  601.60 +}
  601.61 +
  601.62 +void vorbis_bitrate_clear(bitrate_manager_state *bm){
  601.63 +  memset(bm,0,sizeof(*bm));
  601.64 +  return;
  601.65 +}
  601.66 +
  601.67 +int vorbis_bitrate_managed(vorbis_block *vb){
  601.68 +  vorbis_dsp_state      *vd=vb->vd;
  601.69 +  private_state         *b=vd->backend_state;
  601.70 +  bitrate_manager_state *bm=&b->bms;
  601.71 +
  601.72 +  if(bm && bm->managed)return(1);
  601.73 +  return(0);
  601.74 +}
  601.75 +
  601.76 +/* finish taking in the block we just processed */
  601.77 +int vorbis_bitrate_addblock(vorbis_block *vb){
  601.78 +  vorbis_block_internal *vbi=vb->internal;
  601.79 +  vorbis_dsp_state      *vd=vb->vd;
  601.80 +  private_state         *b=vd->backend_state;
  601.81 +  bitrate_manager_state *bm=&b->bms;
  601.82 +  vorbis_info           *vi=vd->vi;
  601.83 +  codec_setup_info      *ci=vi->codec_setup;
  601.84 +  bitrate_manager_info  *bi=&ci->bi;
  601.85 +
  601.86 +  int  choice=rint(bm->avgfloat);
  601.87 +  long this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
  601.88 +  long min_target_bits=(vb->W?bm->min_bitsper*bm->short_per_long:bm->min_bitsper);
  601.89 +  long max_target_bits=(vb->W?bm->max_bitsper*bm->short_per_long:bm->max_bitsper);
  601.90 +  int  samples=ci->blocksizes[vb->W]>>1;
  601.91 +  long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
  601.92 +  if(!bm->managed){
  601.93 +    /* not a bitrate managed stream, but for API simplicity, we'll
  601.94 +       buffer the packet to keep the code path clean */
  601.95 +
  601.96 +    if(bm->vb)return(-1); /* one has been submitted without
  601.97 +                             being claimed */
  601.98 +    bm->vb=vb;
  601.99 +    return(0);
 601.100 +  }
 601.101 +
 601.102 +  bm->vb=vb;
 601.103 +
 601.104 +  /* look ahead for avg floater */
 601.105 +  if(bm->avg_bitsper>0){
 601.106 +    double slew=0.;
 601.107 +    long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
 601.108 +    double slewlimit= 15./bi->slew_damp;
 601.109 +
 601.110 +    /* choosing a new floater:
 601.111 +       if we're over target, we slew down
 601.112 +       if we're under target, we slew up
 601.113 +
 601.114 +       choose slew as follows: look through packetblobs of this frame
 601.115 +       and set slew as the first in the appropriate direction that
 601.116 +       gives us the slew we want.  This may mean no slew if delta is
 601.117 +       already favorable.
 601.118 +
 601.119 +       Then limit slew to slew max */
 601.120 +
 601.121 +    if(bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
 601.122 +      while(choice>0 && this_bits>avg_target_bits &&
 601.123 +            bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
 601.124 +        choice--;
 601.125 +        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
 601.126 +      }
 601.127 +    }else if(bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
 601.128 +      while(choice+1<PACKETBLOBS && this_bits<avg_target_bits &&
 601.129 +            bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
 601.130 +        choice++;
 601.131 +        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
 601.132 +      }
 601.133 +    }
 601.134 +
 601.135 +    slew=rint(choice-bm->avgfloat)/samples*vi->rate;
 601.136 +    if(slew<-slewlimit)slew=-slewlimit;
 601.137 +    if(slew>slewlimit)slew=slewlimit;
 601.138 +    choice=rint(bm->avgfloat+= slew/vi->rate*samples);
 601.139 +    this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
 601.140 +  }
 601.141 +
 601.142 +
 601.143 +
 601.144 +  /* enforce min(if used) on the current floater (if used) */
 601.145 +  if(bm->min_bitsper>0){
 601.146 +    /* do we need to force the bitrate up? */
 601.147 +    if(this_bits<min_target_bits){
 601.148 +      while(bm->minmax_reservoir-(min_target_bits-this_bits)<0){
 601.149 +        choice++;
 601.150 +        if(choice>=PACKETBLOBS)break;
 601.151 +        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
 601.152 +      }
 601.153 +    }
 601.154 +  }
 601.155 +
 601.156 +  /* enforce max (if used) on the current floater (if used) */
 601.157 +  if(bm->max_bitsper>0){
 601.158 +    /* do we need to force the bitrate down? */
 601.159 +    if(this_bits>max_target_bits){
 601.160 +      while(bm->minmax_reservoir+(this_bits-max_target_bits)>bi->reservoir_bits){
 601.161 +        choice--;
 601.162 +        if(choice<0)break;
 601.163 +        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
 601.164 +      }
 601.165 +    }
 601.166 +  }
 601.167 +
 601.168 +  /* Choice of packetblobs now made based on floater, and min/max
 601.169 +     requirements. Now boundary check extreme choices */
 601.170 +
 601.171 +  if(choice<0){
 601.172 +    /* choosing a smaller packetblob is insufficient to trim bitrate.
 601.173 +       frame will need to be truncated */
 601.174 +    long maxsize=(max_target_bits+(bi->reservoir_bits-bm->minmax_reservoir))/8;
 601.175 +    bm->choice=choice=0;
 601.176 +
 601.177 +    if(oggpack_bytes(vbi->packetblob[choice])>maxsize){
 601.178 +
 601.179 +      oggpack_writetrunc(vbi->packetblob[choice],maxsize*8);
 601.180 +      this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
 601.181 +    }
 601.182 +  }else{
 601.183 +    long minsize=(min_target_bits-bm->minmax_reservoir+7)/8;
 601.184 +    if(choice>=PACKETBLOBS)
 601.185 +      choice=PACKETBLOBS-1;
 601.186 +
 601.187 +    bm->choice=choice;
 601.188 +
 601.189 +    /* prop up bitrate according to demand. pad this frame out with zeroes */
 601.190 +    minsize-=oggpack_bytes(vbi->packetblob[choice]);
 601.191 +    while(minsize-->0)oggpack_write(vbi->packetblob[choice],0,8);
 601.192 +    this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
 601.193 +
 601.194 +  }
 601.195 +
 601.196 +  /* now we have the final packet and the final packet size.  Update statistics */
 601.197 +  /* min and max reservoir */
 601.198 +  if(bm->min_bitsper>0 || bm->max_bitsper>0){
 601.199 +
 601.200 +    if(max_target_bits>0 && this_bits>max_target_bits){
 601.201 +      bm->minmax_reservoir+=(this_bits-max_target_bits);
 601.202 +    }else if(min_target_bits>0 && this_bits<min_target_bits){
 601.203 +      bm->minmax_reservoir+=(this_bits-min_target_bits);
 601.204 +    }else{
 601.205 +      /* inbetween; we want to take reservoir toward but not past desired_fill */
 601.206 +      if(bm->minmax_reservoir>desired_fill){
 601.207 +        if(max_target_bits>0){ /* logical bulletproofing against initialization state */
 601.208 +          bm->minmax_reservoir+=(this_bits-max_target_bits);
 601.209 +          if(bm->minmax_reservoir<desired_fill)bm->minmax_reservoir=desired_fill;
 601.210 +        }else{
 601.211 +          bm->minmax_reservoir=desired_fill;
 601.212 +        }
 601.213 +      }else{
 601.214 +        if(min_target_bits>0){ /* logical bulletproofing against initialization state */
 601.215 +          bm->minmax_reservoir+=(this_bits-min_target_bits);
 601.216 +          if(bm->minmax_reservoir>desired_fill)bm->minmax_reservoir=desired_fill;
 601.217 +        }else{
 601.218 +          bm->minmax_reservoir=desired_fill;
 601.219 +        }
 601.220 +      }
 601.221 +    }
 601.222 +  }
 601.223 +
 601.224 +  /* avg reservoir */
 601.225 +  if(bm->avg_bitsper>0){
 601.226 +    long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
 601.227 +    bm->avg_reservoir+=this_bits-avg_target_bits;
 601.228 +  }
 601.229 +
 601.230 +  return(0);
 601.231 +}
 601.232 +
 601.233 +int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){
 601.234 +  private_state         *b=vd->backend_state;
 601.235 +  bitrate_manager_state *bm=&b->bms;
 601.236 +  vorbis_block          *vb=bm->vb;
 601.237 +  int                    choice=PACKETBLOBS/2;
 601.238 +  if(!vb)return 0;
 601.239 +
 601.240 +  if(op){
 601.241 +    vorbis_block_internal *vbi=vb->internal;
 601.242 +
 601.243 +    if(vorbis_bitrate_managed(vb))
 601.244 +      choice=bm->choice;
 601.245 +
 601.246 +    op->packet=oggpack_get_buffer(vbi->packetblob[choice]);
 601.247 +    op->bytes=oggpack_bytes(vbi->packetblob[choice]);
 601.248 +    op->b_o_s=0;
 601.249 +    op->e_o_s=vb->eofflag;
 601.250 +    op->granulepos=vb->granulepos;
 601.251 +    op->packetno=vb->sequence; /* for sake of completeness */
 601.252 +  }
 601.253 +
 601.254 +  bm->vb=0;
 601.255 +  return(1);
 601.256 +}
   602.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   602.2 +++ b/libs/vorbis/bitrate.h	Sat Feb 01 19:58:19 2014 +0200
   602.3 @@ -0,0 +1,59 @@
   602.4 +/********************************************************************
   602.5 + *                                                                  *
   602.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   602.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   602.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   602.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  602.10 + *                                                                  *
  602.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  602.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  602.13 + *                                                                  *
  602.14 + ********************************************************************
  602.15 +
  602.16 + function: bitrate tracking and management
  602.17 + last mod: $Id: bitrate.h 13293 2007-07-24 00:09:47Z xiphmont $
  602.18 +
  602.19 + ********************************************************************/
  602.20 +
  602.21 +#ifndef _V_BITRATE_H_
  602.22 +#define _V_BITRATE_H_
  602.23 +
  602.24 +#include "vorbis/codec.h"
  602.25 +#include "codec_internal.h"
  602.26 +#include "os.h"
  602.27 +
  602.28 +/* encode side bitrate tracking */
  602.29 +typedef struct bitrate_manager_state {
  602.30 +  int            managed;
  602.31 +
  602.32 +  long           avg_reservoir;
  602.33 +  long           minmax_reservoir;
  602.34 +  long           avg_bitsper;
  602.35 +  long           min_bitsper;
  602.36 +  long           max_bitsper;
  602.37 +
  602.38 +  long           short_per_long;
  602.39 +  double         avgfloat;
  602.40 +
  602.41 +  vorbis_block  *vb;
  602.42 +  int            choice;
  602.43 +} bitrate_manager_state;
  602.44 +
  602.45 +typedef struct bitrate_manager_info{
  602.46 +  long           avg_rate;
  602.47 +  long           min_rate;
  602.48 +  long           max_rate;
  602.49 +  long           reservoir_bits;
  602.50 +  double         reservoir_bias;
  602.51 +
  602.52 +  double         slew_damp;
  602.53 +
  602.54 +} bitrate_manager_info;
  602.55 +
  602.56 +extern void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bs);
  602.57 +extern void vorbis_bitrate_clear(bitrate_manager_state *bs);
  602.58 +extern int vorbis_bitrate_managed(vorbis_block *vb);
  602.59 +extern int vorbis_bitrate_addblock(vorbis_block *vb);
  602.60 +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, ogg_packet *op);
  602.61 +
  602.62 +#endif
   603.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   603.2 +++ b/libs/vorbis/block.c	Sat Feb 01 19:58:19 2014 +0200
   603.3 @@ -0,0 +1,1046 @@
   603.4 +/********************************************************************
   603.5 + *                                                                  *
   603.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   603.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   603.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   603.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  603.10 + *                                                                  *
  603.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  603.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  603.13 + *                                                                  *
  603.14 + ********************************************************************
  603.15 +
  603.16 + function: PCM data vector blocking, windowing and dis/reassembly
  603.17 + last mod: $Id: block.c 17561 2010-10-23 10:34:24Z xiphmont $
  603.18 +
  603.19 + Handle windowing, overlap-add, etc of the PCM vectors.  This is made
  603.20 + more amusing by Vorbis' current two allowed block sizes.
  603.21 +
  603.22 + ********************************************************************/
  603.23 +
  603.24 +#include <stdio.h>
  603.25 +#include <stdlib.h>
  603.26 +#include <string.h>
  603.27 +#include <ogg/ogg.h>
  603.28 +#include "vorbis/codec.h"
  603.29 +#include "codec_internal.h"
  603.30 +
  603.31 +#include "window.h"
  603.32 +#include "mdct.h"
  603.33 +#include "lpc.h"
  603.34 +#include "registry.h"
  603.35 +#include "misc.h"
  603.36 +
  603.37 +static int ilog2(unsigned int v){
  603.38 +  int ret=0;
  603.39 +  if(v)--v;
  603.40 +  while(v){
  603.41 +    ret++;
  603.42 +    v>>=1;
  603.43 +  }
  603.44 +  return(ret);
  603.45 +}
  603.46 +
  603.47 +/* pcm accumulator examples (not exhaustive):
  603.48 +
  603.49 + <-------------- lW ---------------->
  603.50 +                   <--------------- W ---------------->
  603.51 +:            .....|.....       _______________         |
  603.52 +:        .'''     |     '''_---      |       |\        |
  603.53 +:.....'''         |_____--- '''......|       | \_______|
  603.54 +:.................|__________________|_______|__|______|
  603.55 +                  |<------ Sl ------>|      > Sr <     |endW
  603.56 +                  |beginSl           |endSl  |  |endSr
  603.57 +                  |beginW            |endlW  |beginSr
  603.58 +
  603.59 +
  603.60 +                      |< lW >|
  603.61 +                   <--------------- W ---------------->
  603.62 +                  |   |  ..  ______________            |
  603.63 +                  |   | '  `/        |     ---_        |
  603.64 +                  |___.'___/`.       |         ---_____|
  603.65 +                  |_______|__|_______|_________________|
  603.66 +                  |      >|Sl|<      |<------ Sr ----->|endW
  603.67 +                  |       |  |endSl  |beginSr          |endSr
  603.68 +                  |beginW |  |endlW
  603.69 +                  mult[0] |beginSl                     mult[n]
  603.70 +
  603.71 + <-------------- lW ----------------->
  603.72 +                          |<--W-->|
  603.73 +:            ..............  ___  |   |
  603.74 +:        .'''             |`/   \ |   |
  603.75 +:.....'''                 |/`....\|...|
  603.76 +:.........................|___|___|___|
  603.77 +                          |Sl |Sr |endW
  603.78 +                          |   |   |endSr
  603.79 +                          |   |beginSr
  603.80 +                          |   |endSl
  603.81 +                          |beginSl
  603.82 +                          |beginW
  603.83 +*/
  603.84 +
  603.85 +/* block abstraction setup *********************************************/
  603.86 +
  603.87 +#ifndef WORD_ALIGN
  603.88 +#define WORD_ALIGN 8
  603.89 +#endif
  603.90 +
  603.91 +int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
  603.92 +  int i;
  603.93 +  memset(vb,0,sizeof(*vb));
  603.94 +  vb->vd=v;
  603.95 +  vb->localalloc=0;
  603.96 +  vb->localstore=NULL;
  603.97 +  if(v->analysisp){
  603.98 +    vorbis_block_internal *vbi=
  603.99 +      vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
 603.100 +    vbi->ampmax=-9999;
 603.101 +
 603.102 +    for(i=0;i<PACKETBLOBS;i++){
 603.103 +      if(i==PACKETBLOBS/2){
 603.104 +        vbi->packetblob[i]=&vb->opb;
 603.105 +      }else{
 603.106 +        vbi->packetblob[i]=
 603.107 +          _ogg_calloc(1,sizeof(oggpack_buffer));
 603.108 +      }
 603.109 +      oggpack_writeinit(vbi->packetblob[i]);
 603.110 +    }
 603.111 +  }
 603.112 +
 603.113 +  return(0);
 603.114 +}
 603.115 +
 603.116 +void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
 603.117 +  bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
 603.118 +  if(bytes+vb->localtop>vb->localalloc){
 603.119 +    /* can't just _ogg_realloc... there are outstanding pointers */
 603.120 +    if(vb->localstore){
 603.121 +      struct alloc_chain *link=_ogg_malloc(sizeof(*link));
 603.122 +      vb->totaluse+=vb->localtop;
 603.123 +      link->next=vb->reap;
 603.124 +      link->ptr=vb->localstore;
 603.125 +      vb->reap=link;
 603.126 +    }
 603.127 +    /* highly conservative */
 603.128 +    vb->localalloc=bytes;
 603.129 +    vb->localstore=_ogg_malloc(vb->localalloc);
 603.130 +    vb->localtop=0;
 603.131 +  }
 603.132 +  {
 603.133 +    void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
 603.134 +    vb->localtop+=bytes;
 603.135 +    return ret;
 603.136 +  }
 603.137 +}
 603.138 +
 603.139 +/* reap the chain, pull the ripcord */
 603.140 +void _vorbis_block_ripcord(vorbis_block *vb){
 603.141 +  /* reap the chain */
 603.142 +  struct alloc_chain *reap=vb->reap;
 603.143 +  while(reap){
 603.144 +    struct alloc_chain *next=reap->next;
 603.145 +    _ogg_free(reap->ptr);
 603.146 +    memset(reap,0,sizeof(*reap));
 603.147 +    _ogg_free(reap);
 603.148 +    reap=next;
 603.149 +  }
 603.150 +  /* consolidate storage */
 603.151 +  if(vb->totaluse){
 603.152 +    vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
 603.153 +    vb->localalloc+=vb->totaluse;
 603.154 +    vb->totaluse=0;
 603.155 +  }
 603.156 +
 603.157 +  /* pull the ripcord */
 603.158 +  vb->localtop=0;
 603.159 +  vb->reap=NULL;
 603.160 +}
 603.161 +
 603.162 +int vorbis_block_clear(vorbis_block *vb){
 603.163 +  int i;
 603.164 +  vorbis_block_internal *vbi=vb->internal;
 603.165 +
 603.166 +  _vorbis_block_ripcord(vb);
 603.167 +  if(vb->localstore)_ogg_free(vb->localstore);
 603.168 +
 603.169 +  if(vbi){
 603.170 +    for(i=0;i<PACKETBLOBS;i++){
 603.171 +      oggpack_writeclear(vbi->packetblob[i]);
 603.172 +      if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
 603.173 +    }
 603.174 +    _ogg_free(vbi);
 603.175 +  }
 603.176 +  memset(vb,0,sizeof(*vb));
 603.177 +  return(0);
 603.178 +}
 603.179 +
 603.180 +/* Analysis side code, but directly related to blocking.  Thus it's
 603.181 +   here and not in analysis.c (which is for analysis transforms only).
 603.182 +   The init is here because some of it is shared */
 603.183 +
 603.184 +static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
 603.185 +  int i;
 603.186 +  codec_setup_info *ci=vi->codec_setup;
 603.187 +  private_state *b=NULL;
 603.188 +  int hs;
 603.189 +
 603.190 +  if(ci==NULL) return 1;
 603.191 +  hs=ci->halfrate_flag;
 603.192 +
 603.193 +  memset(v,0,sizeof(*v));
 603.194 +  b=v->backend_state=_ogg_calloc(1,sizeof(*b));
 603.195 +
 603.196 +  v->vi=vi;
 603.197 +  b->modebits=ilog2(ci->modes);
 603.198 +
 603.199 +  b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
 603.200 +  b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
 603.201 +
 603.202 +  /* MDCT is tranform 0 */
 603.203 +
 603.204 +  b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
 603.205 +  b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
 603.206 +  mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
 603.207 +  mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
 603.208 +
 603.209 +  /* Vorbis I uses only window type 0 */
 603.210 +  b->window[0]=ilog2(ci->blocksizes[0])-6;
 603.211 +  b->window[1]=ilog2(ci->blocksizes[1])-6;
 603.212 +
 603.213 +  if(encp){ /* encode/decode differ here */
 603.214 +
 603.215 +    /* analysis always needs an fft */
 603.216 +    drft_init(&b->fft_look[0],ci->blocksizes[0]);
 603.217 +    drft_init(&b->fft_look[1],ci->blocksizes[1]);
 603.218 +
 603.219 +    /* finish the codebooks */
 603.220 +    if(!ci->fullbooks){
 603.221 +      ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
 603.222 +      for(i=0;i<ci->books;i++)
 603.223 +        vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
 603.224 +    }
 603.225 +
 603.226 +    b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
 603.227 +    for(i=0;i<ci->psys;i++){
 603.228 +      _vp_psy_init(b->psy+i,
 603.229 +                   ci->psy_param[i],
 603.230 +                   &ci->psy_g_param,
 603.231 +                   ci->blocksizes[ci->psy_param[i]->blockflag]/2,
 603.232 +                   vi->rate);
 603.233 +    }
 603.234 +
 603.235 +    v->analysisp=1;
 603.236 +  }else{
 603.237 +    /* finish the codebooks */
 603.238 +    if(!ci->fullbooks){
 603.239 +      ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
 603.240 +      for(i=0;i<ci->books;i++){
 603.241 +        if(ci->book_param[i]==NULL)
 603.242 +          goto abort_books;
 603.243 +        if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
 603.244 +          goto abort_books;
 603.245 +        /* decode codebooks are now standalone after init */
 603.246 +        vorbis_staticbook_destroy(ci->book_param[i]);
 603.247 +        ci->book_param[i]=NULL;
 603.248 +      }
 603.249 +    }
 603.250 +  }
 603.251 +
 603.252 +  /* initialize the storage vectors. blocksize[1] is small for encode,
 603.253 +     but the correct size for decode */
 603.254 +  v->pcm_storage=ci->blocksizes[1];
 603.255 +  v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
 603.256 +  v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
 603.257 +  {
 603.258 +    int i;
 603.259 +    for(i=0;i<vi->channels;i++)
 603.260 +      v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
 603.261 +  }
 603.262 +
 603.263 +  /* all 1 (large block) or 0 (small block) */
 603.264 +  /* explicitly set for the sake of clarity */
 603.265 +  v->lW=0; /* previous window size */
 603.266 +  v->W=0;  /* current window size */
 603.267 +
 603.268 +  /* all vector indexes */
 603.269 +  v->centerW=ci->blocksizes[1]/2;
 603.270 +
 603.271 +  v->pcm_current=v->centerW;
 603.272 +
 603.273 +  /* initialize all the backend lookups */
 603.274 +  b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
 603.275 +  b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
 603.276 +
 603.277 +  for(i=0;i<ci->floors;i++)
 603.278 +    b->flr[i]=_floor_P[ci->floor_type[i]]->
 603.279 +      look(v,ci->floor_param[i]);
 603.280 +
 603.281 +  for(i=0;i<ci->residues;i++)
 603.282 +    b->residue[i]=_residue_P[ci->residue_type[i]]->
 603.283 +      look(v,ci->residue_param[i]);
 603.284 +
 603.285 +  return 0;
 603.286 + abort_books:
 603.287 +  for(i=0;i<ci->books;i++){
 603.288 +    if(ci->book_param[i]!=NULL){
 603.289 +      vorbis_staticbook_destroy(ci->book_param[i]);
 603.290 +      ci->book_param[i]=NULL;
 603.291 +    }
 603.292 +  }
 603.293 +  vorbis_dsp_clear(v);
 603.294 +  return -1;
 603.295 +}
 603.296 +
 603.297 +/* arbitrary settings and spec-mandated numbers get filled in here */
 603.298 +int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
 603.299 +  private_state *b=NULL;
 603.300 +
 603.301 +  if(_vds_shared_init(v,vi,1))return 1;
 603.302 +  b=v->backend_state;
 603.303 +  b->psy_g_look=_vp_global_look(vi);
 603.304 +
 603.305 +  /* Initialize the envelope state storage */
 603.306 +  b->ve=_ogg_calloc(1,sizeof(*b->ve));
 603.307 +  _ve_envelope_init(b->ve,vi);
 603.308 +
 603.309 +  vorbis_bitrate_init(vi,&b->bms);
 603.310 +
 603.311 +  /* compressed audio packets start after the headers
 603.312 +     with sequence number 3 */
 603.313 +  v->sequence=3;
 603.314 +
 603.315 +  return(0);
 603.316 +}
 603.317 +
 603.318 +void vorbis_dsp_clear(vorbis_dsp_state *v){
 603.319 +  int i;
 603.320 +  if(v){
 603.321 +    vorbis_info *vi=v->vi;
 603.322 +    codec_setup_info *ci=(vi?vi->codec_setup:NULL);
 603.323 +    private_state *b=v->backend_state;
 603.324 +
 603.325 +    if(b){
 603.326 +
 603.327 +      if(b->ve){
 603.328 +        _ve_envelope_clear(b->ve);
 603.329 +        _ogg_free(b->ve);
 603.330 +      }
 603.331 +
 603.332 +      if(b->transform[0]){
 603.333 +        mdct_clear(b->transform[0][0]);
 603.334 +        _ogg_free(b->transform[0][0]);
 603.335 +        _ogg_free(b->transform[0]);
 603.336 +      }
 603.337 +      if(b->transform[1]){
 603.338 +        mdct_clear(b->transform[1][0]);
 603.339 +        _ogg_free(b->transform[1][0]);
 603.340 +        _ogg_free(b->transform[1]);
 603.341 +      }
 603.342 +
 603.343 +      if(b->flr){
 603.344 +        if(ci)
 603.345 +          for(i=0;i<ci->floors;i++)
 603.346 +            _floor_P[ci->floor_type[i]]->
 603.347 +              free_look(b->flr[i]);
 603.348 +        _ogg_free(b->flr);
 603.349 +      }
 603.350 +      if(b->residue){
 603.351 +        if(ci)
 603.352 +          for(i=0;i<ci->residues;i++)
 603.353 +            _residue_P[ci->residue_type[i]]->
 603.354 +              free_look(b->residue[i]);
 603.355 +        _ogg_free(b->residue);
 603.356 +      }
 603.357 +      if(b->psy){
 603.358 +        if(ci)
 603.359 +          for(i=0;i<ci->psys;i++)
 603.360 +            _vp_psy_clear(b->psy+i);
 603.361 +        _ogg_free(b->psy);
 603.362 +      }
 603.363 +
 603.364 +      if(b->psy_g_look)_vp_global_free(b->psy_g_look);
 603.365 +      vorbis_bitrate_clear(&b->bms);
 603.366 +
 603.367 +      drft_clear(&b->fft_look[0]);
 603.368 +      drft_clear(&b->fft_look[1]);
 603.369 +
 603.370 +    }
 603.371 +
 603.372 +    if(v->pcm){
 603.373 +      if(vi)
 603.374 +        for(i=0;i<vi->channels;i++)
 603.375 +          if(v->pcm[i])_ogg_free(v->pcm[i]);
 603.376 +      _ogg_free(v->pcm);
 603.377 +      if(v->pcmret)_ogg_free(v->pcmret);
 603.378 +    }
 603.379 +
 603.380 +    if(b){
 603.381 +      /* free header, header1, header2 */
 603.382 +      if(b->header)_ogg_free(b->header);
 603.383 +      if(b->header1)_ogg_free(b->header1);
 603.384 +      if(b->header2)_ogg_free(b->header2);
 603.385 +      _ogg_free(b);
 603.386 +    }
 603.387 +
 603.388 +    memset(v,0,sizeof(*v));
 603.389 +  }
 603.390 +}
 603.391 +
 603.392 +float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
 603.393 +  int i;
 603.394 +  vorbis_info *vi=v->vi;
 603.395 +  private_state *b=v->backend_state;
 603.396 +
 603.397 +  /* free header, header1, header2 */
 603.398 +  if(b->header)_ogg_free(b->header);b->header=NULL;
 603.399 +  if(b->header1)_ogg_free(b->header1);b->header1=NULL;
 603.400 +  if(b->header2)_ogg_free(b->header2);b->header2=NULL;
 603.401 +
 603.402 +  /* Do we have enough storage space for the requested buffer? If not,
 603.403 +     expand the PCM (and envelope) storage */
 603.404 +
 603.405 +  if(v->pcm_current+vals>=v->pcm_storage){
 603.406 +    v->pcm_storage=v->pcm_current+vals*2;
 603.407 +
 603.408 +    for(i=0;i<vi->channels;i++){
 603.409 +      v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
 603.410 +    }
 603.411 +  }
 603.412 +
 603.413 +  for(i=0;i<vi->channels;i++)
 603.414 +    v->pcmret[i]=v->pcm[i]+v->pcm_current;
 603.415 +
 603.416 +  return(v->pcmret);
 603.417 +}
 603.418 +
 603.419 +static void _preextrapolate_helper(vorbis_dsp_state *v){
 603.420 +  int i;
 603.421 +  int order=16;
 603.422 +  float *lpc=alloca(order*sizeof(*lpc));
 603.423 +  float *work=alloca(v->pcm_current*sizeof(*work));
 603.424 +  long j;
 603.425 +  v->preextrapolate=1;
 603.426 +
 603.427 +  if(v->pcm_current-v->centerW>order*2){ /* safety */
 603.428 +    for(i=0;i<v->vi->channels;i++){
 603.429 +      /* need to run the extrapolation in reverse! */
 603.430 +      for(j=0;j<v->pcm_current;j++)
 603.431 +        work[j]=v->pcm[i][v->pcm_current-j-1];
 603.432 +
 603.433 +      /* prime as above */
 603.434 +      vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
 603.435 +
 603.436 +#if 0
 603.437 +      if(v->vi->channels==2){
 603.438 +        if(i==0)
 603.439 +          _analysis_output("predataL",0,work,v->pcm_current-v->centerW,0,0,0);
 603.440 +        else
 603.441 +          _analysis_output("predataR",0,work,v->pcm_current-v->centerW,0,0,0);
 603.442 +      }else{
 603.443 +        _analysis_output("predata",0,work,v->pcm_current-v->centerW,0,0,0);
 603.444 +      }
 603.445 +#endif
 603.446 +
 603.447 +      /* run the predictor filter */
 603.448 +      vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
 603.449 +                         order,
 603.450 +                         work+v->pcm_current-v->centerW,
 603.451 +                         v->centerW);
 603.452 +
 603.453 +      for(j=0;j<v->pcm_current;j++)
 603.454 +        v->pcm[i][v->pcm_current-j-1]=work[j];
 603.455 +
 603.456 +    }
 603.457 +  }
 603.458 +}
 603.459 +
 603.460 +
 603.461 +/* call with val<=0 to set eof */
 603.462 +
 603.463 +int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
 603.464 +  vorbis_info *vi=v->vi;
 603.465 +  codec_setup_info *ci=vi->codec_setup;
 603.466 +
 603.467 +  if(vals<=0){
 603.468 +    int order=32;
 603.469 +    int i;
 603.470 +    float *lpc=alloca(order*sizeof(*lpc));
 603.471 +
 603.472 +    /* if it wasn't done earlier (very short sample) */
 603.473 +    if(!v->preextrapolate)
 603.474 +      _preextrapolate_helper(v);
 603.475 +
 603.476 +    /* We're encoding the end of the stream.  Just make sure we have
 603.477 +       [at least] a few full blocks of zeroes at the end. */
 603.478 +    /* actually, we don't want zeroes; that could drop a large
 603.479 +       amplitude off a cliff, creating spread spectrum noise that will
 603.480 +       suck to encode.  Extrapolate for the sake of cleanliness. */
 603.481 +
 603.482 +    vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
 603.483 +    v->eofflag=v->pcm_current;
 603.484 +    v->pcm_current+=ci->blocksizes[1]*3;
 603.485 +
 603.486 +    for(i=0;i<vi->channels;i++){
 603.487 +      if(v->eofflag>order*2){
 603.488 +        /* extrapolate with LPC to fill in */
 603.489 +        long n;
 603.490 +
 603.491 +        /* make a predictor filter */
 603.492 +        n=v->eofflag;
 603.493 +        if(n>ci->blocksizes[1])n=ci->blocksizes[1];
 603.494 +        vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
 603.495 +
 603.496 +        /* run the predictor filter */
 603.497 +        vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
 603.498 +                           v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
 603.499 +      }else{
 603.500 +        /* not enough data to extrapolate (unlikely to happen due to
 603.501 +           guarding the overlap, but bulletproof in case that
 603.502 +           assumtion goes away). zeroes will do. */
 603.503 +        memset(v->pcm[i]+v->eofflag,0,
 603.504 +               (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
 603.505 +
 603.506 +      }
 603.507 +    }
 603.508 +  }else{
 603.509 +
 603.510 +    if(v->pcm_current+vals>v->pcm_storage)
 603.511 +      return(OV_EINVAL);
 603.512 +
 603.513 +    v->pcm_current+=vals;
 603.514 +
 603.515 +    /* we may want to reverse extrapolate the beginning of a stream
 603.516 +       too... in case we're beginning on a cliff! */
 603.517 +    /* clumsy, but simple.  It only runs once, so simple is good. */
 603.518 +    if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
 603.519 +      _preextrapolate_helper(v);
 603.520 +
 603.521 +  }
 603.522 +  return(0);
 603.523 +}
 603.524 +
 603.525 +/* do the deltas, envelope shaping, pre-echo and determine the size of
 603.526 +   the next block on which to continue analysis */
 603.527 +int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
 603.528 +  int i;
 603.529 +  vorbis_info *vi=v->vi;
 603.530 +  codec_setup_info *ci=vi->codec_setup;
 603.531 +  private_state *b=v->backend_state;
 603.532 +  vorbis_look_psy_global *g=b->psy_g_look;
 603.533 +  long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
 603.534 +  vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
 603.535 +
 603.536 +  /* check to see if we're started... */
 603.537 +  if(!v->preextrapolate)return(0);
 603.538 +
 603.539 +  /* check to see if we're done... */
 603.540 +  if(v->eofflag==-1)return(0);
 603.541 +
 603.542 +  /* By our invariant, we have lW, W and centerW set.  Search for
 603.543 +     the next boundary so we can determine nW (the next window size)
 603.544 +     which lets us compute the shape of the current block's window */
 603.545 +
 603.546 +  /* we do an envelope search even on a single blocksize; we may still
 603.547 +     be throwing more bits at impulses, and envelope search handles
 603.548 +     marking impulses too. */
 603.549 +  {
 603.550 +    long bp=_ve_envelope_search(v);
 603.551 +    if(bp==-1){
 603.552 +
 603.553 +      if(v->eofflag==0)return(0); /* not enough data currently to search for a
 603.554 +                                     full long block */
 603.555 +      v->nW=0;
 603.556 +    }else{
 603.557 +
 603.558 +      if(ci->blocksizes[0]==ci->blocksizes[1])
 603.559 +        v->nW=0;
 603.560 +      else
 603.561 +        v->nW=bp;
 603.562 +    }
 603.563 +  }
 603.564 +
 603.565 +  centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
 603.566 +
 603.567 +  {
 603.568 +    /* center of next block + next block maximum right side. */
 603.569 +
 603.570 +    long blockbound=centerNext+ci->blocksizes[v->nW]/2;
 603.571 +    if(v->pcm_current<blockbound)return(0); /* not enough data yet;
 603.572 +                                               although this check is
 603.573 +                                               less strict that the
 603.574 +                                               _ve_envelope_search,
 603.575 +                                               the search is not run
 603.576 +                                               if we only use one
 603.577 +                                               block size */
 603.578 +
 603.579 +
 603.580 +  }
 603.581 +
 603.582 +  /* fill in the block.  Note that for a short window, lW and nW are *short*
 603.583 +     regardless of actual settings in the stream */
 603.584 +
 603.585 +  _vorbis_block_ripcord(vb);
 603.586 +  vb->lW=v->lW;
 603.587 +  vb->W=v->W;
 603.588 +  vb->nW=v->nW;
 603.589 +
 603.590 +  if(v->W){
 603.591 +    if(!v->lW || !v->nW){
 603.592 +      vbi->blocktype=BLOCKTYPE_TRANSITION;
 603.593 +      /*fprintf(stderr,"-");*/
 603.594 +    }else{
 603.595 +      vbi->blocktype=BLOCKTYPE_LONG;
 603.596 +      /*fprintf(stderr,"_");*/
 603.597 +    }
 603.598 +  }else{
 603.599 +    if(_ve_envelope_mark(v)){
 603.600 +      vbi->blocktype=BLOCKTYPE_IMPULSE;
 603.601 +      /*fprintf(stderr,"|");*/
 603.602 +
 603.603 +    }else{
 603.604 +      vbi->blocktype=BLOCKTYPE_PADDING;
 603.605 +      /*fprintf(stderr,".");*/
 603.606 +
 603.607 +    }
 603.608 +  }
 603.609 +
 603.610 +  vb->vd=v;
 603.611 +  vb->sequence=v->sequence++;
 603.612 +  vb->granulepos=v->granulepos;
 603.613 +  vb->pcmend=ci->blocksizes[v->W];
 603.614 +
 603.615 +  /* copy the vectors; this uses the local storage in vb */
 603.616 +
 603.617 +  /* this tracks 'strongest peak' for later psychoacoustics */
 603.618 +  /* moved to the global psy state; clean this mess up */
 603.619 +  if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
 603.620 +  g->ampmax=_vp_ampmax_decay(g->ampmax,v);
 603.621 +  vbi->ampmax=g->ampmax;
 603.622 +
 603.623 +  vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
 603.624 +  vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
 603.625 +  for(i=0;i<vi->channels;i++){
 603.626 +    vbi->pcmdelay[i]=
 603.627 +      _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
 603.628 +    memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
 603.629 +    vb->pcm[i]=vbi->pcmdelay[i]+beginW;
 603.630 +
 603.631 +    /* before we added the delay
 603.632 +       vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
 603.633 +       memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
 603.634 +    */
 603.635 +
 603.636 +  }
 603.637 +
 603.638 +  /* handle eof detection: eof==0 means that we've not yet received EOF
 603.639 +                           eof>0  marks the last 'real' sample in pcm[]
 603.640 +                           eof<0  'no more to do'; doesn't get here */
 603.641 +
 603.642 +  if(v->eofflag){
 603.643 +    if(v->centerW>=v->eofflag){
 603.644 +      v->eofflag=-1;
 603.645 +      vb->eofflag=1;
 603.646 +      return(1);
 603.647 +    }
 603.648 +  }
 603.649 +
 603.650 +  /* advance storage vectors and clean up */
 603.651 +  {
 603.652 +    int new_centerNext=ci->blocksizes[1]/2;
 603.653 +    int movementW=centerNext-new_centerNext;
 603.654 +
 603.655 +    if(movementW>0){
 603.656 +
 603.657 +      _ve_envelope_shift(b->ve,movementW);
 603.658 +      v->pcm_current-=movementW;
 603.659 +
 603.660 +      for(i=0;i<vi->channels;i++)
 603.661 +        memmove(v->pcm[i],v->pcm[i]+movementW,
 603.662 +                v->pcm_current*sizeof(*v->pcm[i]));
 603.663 +
 603.664 +
 603.665 +      v->lW=v->W;
 603.666 +      v->W=v->nW;
 603.667 +      v->centerW=new_centerNext;
 603.668 +
 603.669 +      if(v->eofflag){
 603.670 +        v->eofflag-=movementW;
 603.671 +        if(v->eofflag<=0)v->eofflag=-1;
 603.672 +        /* do not add padding to end of stream! */
 603.673 +        if(v->centerW>=v->eofflag){
 603.674 +          v->granulepos+=movementW-(v->centerW-v->eofflag);
 603.675 +        }else{
 603.676 +          v->granulepos+=movementW;
 603.677 +        }
 603.678 +      }else{
 603.679 +        v->granulepos+=movementW;
 603.680 +      }
 603.681 +    }
 603.682 +  }
 603.683 +
 603.684 +  /* done */
 603.685 +  return(1);
 603.686 +}
 603.687 +
 603.688 +int vorbis_synthesis_restart(vorbis_dsp_state *v){
 603.689 +  vorbis_info *vi=v->vi;
 603.690 +  codec_setup_info *ci;
 603.691 +  int hs;
 603.692 +
 603.693 +  if(!v->backend_state)return -1;
 603.694 +  if(!vi)return -1;
 603.695 +  ci=vi->codec_setup;
 603.696 +  if(!ci)return -1;
 603.697 +  hs=ci->halfrate_flag;
 603.698 +
 603.699 +  v->centerW=ci->blocksizes[1]>>(hs+1);
 603.700 +  v->pcm_current=v->centerW>>hs;
 603.701 +
 603.702 +  v->pcm_returned=-1;
 603.703 +  v->granulepos=-1;
 603.704 +  v->sequence=-1;
 603.705 +  v->eofflag=0;
 603.706 +  ((private_state *)(v->backend_state))->sample_count=-1;
 603.707 +
 603.708 +  return(0);
 603.709 +}
 603.710 +
 603.711 +int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
 603.712 +  if(_vds_shared_init(v,vi,0)){
 603.713 +    vorbis_dsp_clear(v);
 603.714 +    return 1;
 603.715 +  }
 603.716 +  vorbis_synthesis_restart(v);
 603.717 +  return 0;
 603.718 +}
 603.719 +
 603.720 +/* Unlike in analysis, the window is only partially applied for each
 603.721 +   block.  The time domain envelope is not yet handled at the point of
 603.722 +   calling (as it relies on the previous block). */
 603.723 +
 603.724 +int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
 603.725 +  vorbis_info *vi=v->vi;
 603.726 +  codec_setup_info *ci=vi->codec_setup;
 603.727 +  private_state *b=v->backend_state;
 603.728 +  int hs=ci->halfrate_flag;
 603.729 +  int i,j;
 603.730 +
 603.731 +  if(!vb)return(OV_EINVAL);
 603.732 +  if(v->pcm_current>v->pcm_returned  && v->pcm_returned!=-1)return(OV_EINVAL);
 603.733 +
 603.734 +  v->lW=v->W;
 603.735 +  v->W=vb->W;
 603.736 +  v->nW=-1;
 603.737 +
 603.738 +  if((v->sequence==-1)||
 603.739 +     (v->sequence+1 != vb->sequence)){
 603.740 +    v->granulepos=-1; /* out of sequence; lose count */
 603.741 +    b->sample_count=-1;
 603.742 +  }
 603.743 +
 603.744 +  v->sequence=vb->sequence;
 603.745 +
 603.746 +  if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly
 603.747 +                   was called on block */
 603.748 +    int n=ci->blocksizes[v->W]>>(hs+1);
 603.749 +    int n0=ci->blocksizes[0]>>(hs+1);
 603.750 +    int n1=ci->blocksizes[1]>>(hs+1);
 603.751 +
 603.752 +    int thisCenter;
 603.753 +    int prevCenter;
 603.754 +
 603.755 +    v->glue_bits+=vb->glue_bits;
 603.756 +    v->time_bits+=vb->time_bits;
 603.757 +    v->floor_bits+=vb->floor_bits;
 603.758 +    v->res_bits+=vb->res_bits;
 603.759 +
 603.760 +    if(v->centerW){
 603.761 +      thisCenter=n1;
 603.762 +      prevCenter=0;
 603.763 +    }else{
 603.764 +      thisCenter=0;
 603.765 +      prevCenter=n1;
 603.766 +    }
 603.767 +
 603.768 +    /* v->pcm is now used like a two-stage double buffer.  We don't want
 603.769 +       to have to constantly shift *or* adjust memory usage.  Don't
 603.770 +       accept a new block until the old is shifted out */
 603.771 +
 603.772 +    for(j=0;j<vi->channels;j++){
 603.773 +      /* the overlap/add section */
 603.774 +      if(v->lW){
 603.775 +        if(v->W){
 603.776 +          /* large/large */
 603.777 +          float *w=_vorbis_window_get(b->window[1]-hs);
 603.778 +          float *pcm=v->pcm[j]+prevCenter;
 603.779 +          float *p=vb->pcm[j];
 603.780 +          for(i=0;i<n1;i++)
 603.781 +            pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
 603.782 +        }else{
 603.783 +          /* large/small */
 603.784 +          float *w=_vorbis_window_get(b->window[0]-hs);
 603.785 +          float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
 603.786 +          float *p=vb->pcm[j];
 603.787 +          for(i=0;i<n0;i++)
 603.788 +            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
 603.789 +        }
 603.790 +      }else{
 603.791 +        if(v->W){
 603.792 +          /* small/large */
 603.793 +          float *w=_vorbis_window_get(b->window[0]-hs);
 603.794 +          float *pcm=v->pcm[j]+prevCenter;
 603.795 +          float *p=vb->pcm[j]+n1/2-n0/2;
 603.796 +          for(i=0;i<n0;i++)
 603.797 +            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
 603.798 +          for(;i<n1/2+n0/2;i++)
 603.799 +            pcm[i]=p[i];
 603.800 +        }else{
 603.801 +          /* small/small */
 603.802 +          float *w=_vorbis_window_get(b->window[0]-hs);
 603.803 +          float *pcm=v->pcm[j]+prevCenter;
 603.804 +          float *p=vb->pcm[j];
 603.805 +          for(i=0;i<n0;i++)
 603.806 +            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
 603.807 +        }
 603.808 +      }
 603.809 +
 603.810 +      /* the copy section */
 603.811 +      {
 603.812 +        float *pcm=v->pcm[j]+thisCenter;
 603.813 +        float *p=vb->pcm[j]+n;
 603.814 +        for(i=0;i<n;i++)
 603.815 +          pcm[i]=p[i];
 603.816 +      }
 603.817 +    }
 603.818 +
 603.819 +    if(v->centerW)
 603.820 +      v->centerW=0;
 603.821 +    else
 603.822 +      v->centerW=n1;
 603.823 +
 603.824 +    /* deal with initial packet state; we do this using the explicit
 603.825 +       pcm_returned==-1 flag otherwise we're sensitive to first block
 603.826 +       being short or long */
 603.827 +
 603.828 +    if(v->pcm_returned==-1){
 603.829 +      v->pcm_returned=thisCenter;
 603.830 +      v->pcm_current=thisCenter;
 603.831 +    }else{
 603.832 +      v->pcm_returned=prevCenter;
 603.833 +      v->pcm_current=prevCenter+
 603.834 +        ((ci->blocksizes[v->lW]/4+
 603.835 +        ci->blocksizes[v->W]/4)>>hs);
 603.836 +    }
 603.837 +
 603.838 +  }
 603.839 +
 603.840 +  /* track the frame number... This is for convenience, but also
 603.841 +     making sure our last packet doesn't end with added padding.  If
 603.842 +     the last packet is partial, the number of samples we'll have to
 603.843 +     return will be past the vb->granulepos.
 603.844 +
 603.845 +     This is not foolproof!  It will be confused if we begin
 603.846 +     decoding at the last page after a seek or hole.  In that case,
 603.847 +     we don't have a starting point to judge where the last frame
 603.848 +     is.  For this reason, vorbisfile will always try to make sure
 603.849 +     it reads the last two marked pages in proper sequence */
 603.850 +
 603.851 +  if(b->sample_count==-1){
 603.852 +    b->sample_count=0;
 603.853 +  }else{
 603.854 +    b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
 603.855 +  }
 603.856 +
 603.857 +  if(v->granulepos==-1){
 603.858 +    if(vb->granulepos!=-1){ /* only set if we have a position to set to */
 603.859 +
 603.860 +      v->granulepos=vb->granulepos;
 603.861 +
 603.862 +      /* is this a short page? */
 603.863 +      if(b->sample_count>v->granulepos){
 603.864 +        /* corner case; if this is both the first and last audio page,
 603.865 +           then spec says the end is cut, not beginning */
 603.866 +       long extra=b->sample_count-vb->granulepos;
 603.867 +
 603.868 +        /* we use ogg_int64_t for granule positions because a
 603.869 +           uint64 isn't universally available.  Unfortunately,
 603.870 +           that means granposes can be 'negative' and result in
 603.871 +           extra being negative */
 603.872 +        if(extra<0)
 603.873 +          extra=0;
 603.874 +
 603.875 +        if(vb->eofflag){
 603.876 +          /* trim the end */
 603.877 +          /* no preceding granulepos; assume we started at zero (we'd
 603.878 +             have to in a short single-page stream) */
 603.879 +          /* granulepos could be -1 due to a seek, but that would result
 603.880 +             in a long count, not short count */
 603.881 +
 603.882 +          /* Guard against corrupt/malicious frames that set EOP and
 603.883 +             a backdated granpos; don't rewind more samples than we
 603.884 +             actually have */
 603.885 +          if(extra > (v->pcm_current - v->pcm_returned)<<hs)
 603.886 +            extra = (v->pcm_current - v->pcm_returned)<<hs;
 603.887 +
 603.888 +          v->pcm_current-=extra>>hs;
 603.889 +        }else{
 603.890 +          /* trim the beginning */
 603.891 +          v->pcm_returned+=extra>>hs;
 603.892 +          if(v->pcm_returned>v->pcm_current)
 603.893 +            v->pcm_returned=v->pcm_current;
 603.894 +        }
 603.895 +
 603.896 +      }
 603.897 +
 603.898 +    }
 603.899 +  }else{
 603.900 +    v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
 603.901 +    if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
 603.902 +
 603.903 +      if(v->granulepos>vb->granulepos){
 603.904 +        long extra=v->granulepos-vb->granulepos;
 603.905 +
 603.906 +        if(extra)
 603.907 +          if(vb->eofflag){
 603.908 +            /* partial last frame.  Strip the extra samples off */
 603.909 +
 603.910 +            /* Guard against corrupt/malicious frames that set EOP and
 603.911 +               a backdated granpos; don't rewind more samples than we
 603.912 +               actually have */
 603.913 +            if(extra > (v->pcm_current - v->pcm_returned)<<hs)
 603.914 +              extra = (v->pcm_current - v->pcm_returned)<<hs;
 603.915 +
 603.916 +            /* we use ogg_int64_t for granule positions because a
 603.917 +               uint64 isn't universally available.  Unfortunately,
 603.918 +               that means granposes can be 'negative' and result in
 603.919 +               extra being negative */
 603.920 +            if(extra<0)
 603.921 +              extra=0;
 603.922 +
 603.923 +            v->pcm_current-=extra>>hs;
 603.924 +          } /* else {Shouldn't happen *unless* the bitstream is out of
 603.925 +               spec.  Either way, believe the bitstream } */
 603.926 +      } /* else {Shouldn't happen *unless* the bitstream is out of
 603.927 +           spec.  Either way, believe the bitstream } */
 603.928 +      v->granulepos=vb->granulepos;
 603.929 +    }
 603.930 +  }
 603.931 +
 603.932 +  /* Update, cleanup */
 603.933 +
 603.934 +  if(vb->eofflag)v->eofflag=1;
 603.935 +  return(0);
 603.936 +
 603.937 +}
 603.938 +
 603.939 +/* pcm==NULL indicates we just want the pending samples, no more */
 603.940 +int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
 603.941 +  vorbis_info *vi=v->vi;
 603.942 +
 603.943 +  if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
 603.944 +    if(pcm){
 603.945 +      int i;
 603.946 +      for(i=0;i<vi->channels;i++)
 603.947 +        v->pcmret[i]=v->pcm[i]+v->pcm_returned;
 603.948 +      *pcm=v->pcmret;
 603.949 +    }
 603.950 +    return(v->pcm_current-v->pcm_returned);
 603.951 +  }
 603.952 +  return(0);
 603.953 +}
 603.954 +
 603.955 +int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
 603.956 +  if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
 603.957 +  v->pcm_returned+=n;
 603.958 +  return(0);
 603.959 +}
 603.960 +
 603.961 +/* intended for use with a specific vorbisfile feature; we want access
 603.962 +   to the [usually synthetic/postextrapolated] buffer and lapping at
 603.963 +   the end of a decode cycle, specifically, a half-short-block worth.
 603.964 +   This funtion works like pcmout above, except it will also expose
 603.965 +   this implicit buffer data not normally decoded. */
 603.966 +int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
 603.967 +  vorbis_info *vi=v->vi;
 603.968 +  codec_setup_info *ci=vi->codec_setup;
 603.969 +  int hs=ci->halfrate_flag;
 603.970 +
 603.971 +  int n=ci->blocksizes[v->W]>>(hs+1);
 603.972 +  int n0=ci->blocksizes[0]>>(hs+1);
 603.973 +  int n1=ci->blocksizes[1]>>(hs+1);
 603.974 +  int i,j;
 603.975 +
 603.976 +  if(v->pcm_returned<0)return 0;
 603.977 +
 603.978 +  /* our returned data ends at pcm_returned; because the synthesis pcm
 603.979 +     buffer is a two-fragment ring, that means our data block may be
 603.980 +     fragmented by buffering, wrapping or a short block not filling
 603.981 +     out a buffer.  To simplify things, we unfragment if it's at all
 603.982 +     possibly needed. Otherwise, we'd need to call lapout more than
 603.983 +     once as well as hold additional dsp state.  Opt for
 603.984 +     simplicity. */
 603.985 +
 603.986 +  /* centerW was advanced by blockin; it would be the center of the
 603.987 +     *next* block */
 603.988 +  if(v->centerW==n1){
 603.989 +    /* the data buffer wraps; swap the halves */
 603.990 +    /* slow, sure, small */
 603.991 +    for(j=0;j<vi->channels;j++){
 603.992 +      float *p=v->pcm[j];
 603.993 +      for(i=0;i<n1;i++){
 603.994 +        float temp=p[i];
 603.995 +        p[i]=p[i+n1];
 603.996 +        p[i+n1]=temp;
 603.997 +      }
 603.998 +    }
 603.999 +
603.1000 +    v->pcm_current-=n1;
603.1001 +    v->pcm_returned-=n1;
603.1002 +    v->centerW=0;
603.1003 +  }
603.1004 +
603.1005 +  /* solidify buffer into contiguous space */
603.1006 +  if((v->lW^v->W)==1){
603.1007 +    /* long/short or short/long */
603.1008 +    for(j=0;j<vi->channels;j++){
603.1009 +      float *s=v->pcm[j];
603.1010 +      float *d=v->pcm[j]+(n1-n0)/2;
603.1011 +      for(i=(n1+n0)/2-1;i>=0;--i)
603.1012 +        d[i]=s[i];
603.1013 +    }
603.1014 +    v->pcm_returned+=(n1-n0)/2;
603.1015 +    v->pcm_current+=(n1-n0)/2;
603.1016 +  }else{
603.1017 +    if(v->lW==0){
603.1018 +      /* short/short */
603.1019 +      for(j=0;j<vi->channels;j++){
603.1020 +        float *s=v->pcm[j];
603.1021 +        float *d=v->pcm[j]+n1-n0;
603.1022 +        for(i=n0-1;i>=0;--i)
603.1023 +          d[i]=s[i];
603.1024 +      }
603.1025 +      v->pcm_returned+=n1-n0;
603.1026 +      v->pcm_current+=n1-n0;
603.1027 +    }
603.1028 +  }
603.1029 +
603.1030 +  if(pcm){
603.1031 +    int i;
603.1032 +    for(i=0;i<vi->channels;i++)
603.1033 +      v->pcmret[i]=v->pcm[i]+v->pcm_returned;
603.1034 +    *pcm=v->pcmret;
603.1035 +  }
603.1036 +
603.1037 +  return(n1+n-v->pcm_returned);
603.1038 +
603.1039 +}
603.1040 +
603.1041 +float *vorbis_window(vorbis_dsp_state *v,int W){
603.1042 +  vorbis_info *vi=v->vi;
603.1043 +  codec_setup_info *ci=vi->codec_setup;
603.1044 +  int hs=ci->halfrate_flag;
603.1045 +  private_state *b=v->backend_state;
603.1046 +
603.1047 +  if(b->window[W]-1<0)return NULL;
603.1048 +  return _vorbis_window_get(b->window[W]-hs);
603.1049 +}
   604.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   604.2 +++ b/libs/vorbis/books/coupled/res_books_51.h	Sat Feb 01 19:58:19 2014 +0200
   604.3 @@ -0,0 +1,12257 @@
   604.4 +static const long _vq_quantlist__44p0_l0_0[] = {
   604.5 +	6,
   604.6 +	5,
   604.7 +	7,
   604.8 +	4,
   604.9 +	8,
  604.10 +	3,
  604.11 +	9,
  604.12 +	2,
  604.13 +	10,
  604.14 +	1,
  604.15 +	11,
  604.16 +	0,
  604.17 +	12,
  604.18 +};
  604.19 +
  604.20 +static const long _vq_lengthlist__44p0_l0_0[] = {
  604.21 +	 1, 3, 4, 7, 7, 8, 8, 9, 9, 9,10,10,10, 5, 6, 5,
  604.22 +	 8, 7, 9, 8, 9, 9,10, 9,11,10, 5, 5, 7, 7, 8, 8,
  604.23 +	 9, 9, 9, 9,10,10,11, 8, 9, 8,10, 9,10, 9,10, 9,
  604.24 +	11,10,11,10, 8, 8, 9, 9,10, 9,10, 9,11,10,11,10,
  604.25 +	11,10,11,11,11,11,11,11,11,11,11,11,11,11,10,11,
  604.26 +	11,11,12,11,11,11,11,11,11,10,12,12,12,12,12,12,
  604.27 +	12,11,12,12,12,11,11,11,12,12,12,12,12,12,12,11,
  604.28 +	12,11,12,11,11,13,12,12,12,13,12,12,12,12,11,12,
  604.29 +	11,11,13,13,13,12,12,12,12,12,12,11,11,11,10,13,
  604.30 +	13,13,12,13,12,13,11,13,10,12,11,11,13,13,12,13,
  604.31 +	12,12,12,12,11,12,11,11,11,
  604.32 +};
  604.33 +
  604.34 +static const static_codebook _44p0_l0_0 = {
  604.35 +	2, 169,
  604.36 +	(long *)_vq_lengthlist__44p0_l0_0,
  604.37 +	1, -526516224, 1616117760, 4, 0,
  604.38 +	(long *)_vq_quantlist__44p0_l0_0,
  604.39 +	0
  604.40 +};
  604.41 +
  604.42 +static const long _vq_quantlist__44p0_l0_1[] = {
  604.43 +	2,
  604.44 +	1,
  604.45 +	3,
  604.46 +	0,
  604.47 +	4,
  604.48 +};
  604.49 +
  604.50 +static const long _vq_lengthlist__44p0_l0_1[] = {
  604.51 +	 1, 4, 4, 6, 6, 5, 5, 5, 7, 5, 5, 5, 5, 6, 7, 7,
  604.52 +	 6, 7, 7, 7, 6, 7, 7, 7, 7,
  604.53 +};
  604.54 +
  604.55 +static const static_codebook _44p0_l0_1 = {
  604.56 +	2, 25,
  604.57 +	(long *)_vq_lengthlist__44p0_l0_1,
  604.58 +	1, -533725184, 1611661312, 3, 0,
  604.59 +	(long *)_vq_quantlist__44p0_l0_1,
  604.60 +	0
  604.61 +};
  604.62 +
  604.63 +static const long _vq_quantlist__44p0_l1_0[] = {
  604.64 +	1,
  604.65 +	0,
  604.66 +	2,
  604.67 +};
  604.68 +
  604.69 +static const long _vq_lengthlist__44p0_l1_0[] = {
  604.70 +	 1, 4, 4, 4, 4, 4, 4, 4, 4,
  604.71 +};
  604.72 +
  604.73 +static const static_codebook _44p0_l1_0 = {
  604.74 +	2, 9,
  604.75 +	(long *)_vq_lengthlist__44p0_l1_0,
  604.76 +	1, -516716544, 1630767104, 2, 0,
  604.77 +	(long *)_vq_quantlist__44p0_l1_0,
  604.78 +	0
  604.79 +};
  604.80 +
  604.81 +static const long _huff_lengthlist__44p0_lfe[] = {
  604.82 +	 1, 3, 2, 3,
  604.83 +};
  604.84 +
  604.85 +static const static_codebook _huff_book__44p0_lfe = {
  604.86 +	2, 4,
  604.87 +	(long *)_huff_lengthlist__44p0_lfe,
  604.88 +	0, 0, 0, 0, 0,
  604.89 +	NULL,
  604.90 +	0
  604.91 +};
  604.92 +
  604.93 +static const long _huff_lengthlist__44p0_long[] = {
  604.94 +	 2, 3, 6, 7,10,14,16, 3, 2, 5, 7,11,14,17, 6, 5,
  604.95 +	 5, 7,10,12,14, 7, 7, 6, 6, 7, 9,13,10,11, 9, 6,
  604.96 +	 6, 9,11,15,15,13,10, 9,10,12,18,18,16,14,12,13,
  604.97 +	16,
  604.98 +};
  604.99 +
 604.100 +static const static_codebook _huff_book__44p0_long = {
 604.101 +	2, 49,
 604.102 +	(long *)_huff_lengthlist__44p0_long,
 604.103 +	0, 0, 0, 0, 0,
 604.104 +	NULL,
 604.105 +	0
 604.106 +};
 604.107 +
 604.108 +static const long _vq_quantlist__44p0_p1_0[] = {
 604.109 +	1,
 604.110 +	0,
 604.111 +	2,
 604.112 +};
 604.113 +
 604.114 +static const long _vq_lengthlist__44p0_p1_0[] = {
 604.115 +	 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.116 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.117 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.118 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.119 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.120 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.121 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.122 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.123 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.124 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.125 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.126 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.127 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.128 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.129 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.130 +	 0, 0, 0,
 604.131 +};
 604.132 +
 604.133 +static const static_codebook _44p0_p1_0 = {
 604.134 +	5, 243,
 604.135 +	(long *)_vq_lengthlist__44p0_p1_0,
 604.136 +	1, -535822336, 1611661312, 2, 0,
 604.137 +	(long *)_vq_quantlist__44p0_p1_0,
 604.138 +	0
 604.139 +};
 604.140 +
 604.141 +static const long _vq_quantlist__44p0_p2_0[] = {
 604.142 +	1,
 604.143 +	0,
 604.144 +	2,
 604.145 +};
 604.146 +
 604.147 +static const long _vq_lengthlist__44p0_p2_0[] = {
 604.148 +	 1, 5, 5, 0, 7, 7, 0, 8, 8, 0, 9, 9, 0,12,12, 0,
 604.149 +	 8, 8, 0, 9, 9, 0,12,12, 0, 8, 8, 0, 6, 6, 0,11,
 604.150 +	11, 0,12,12, 0,12,12, 0,15,15, 0,11,11, 0,12,12,
 604.151 +	 0,15,15, 0,12,12, 0, 5, 5, 0, 5, 5, 0, 6, 6, 0,
 604.152 +	 7, 7, 0,11,11, 0, 6, 6, 0, 7, 7, 0,10,11, 0, 6,
 604.153 +	 6, 0, 7, 7, 0,11,11, 0,12,12, 0,11,11, 0,15,15,
 604.154 +	 0,10,10, 0,12,12, 0,15,15, 0,12,12, 0, 6, 6, 0,
 604.155 +	12,12, 0,12,12, 0,12,12, 0,15,15, 0,11,11, 0,12,
 604.156 +	12, 0,15,15, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.157 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.158 +	 0, 0, 0, 8, 8, 0,12,12, 0,12,12, 0,12,12, 0,15,
 604.159 +	15, 0,12,12, 0,11,12, 0,15,16, 0,11,11, 0, 6, 6,
 604.160 +	 0,11,12, 0,12,12, 0,12,12, 0,16,15, 0,12,12, 0,
 604.161 +	13,12, 0,15,14, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,
 604.162 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.163 +	 0, 0, 0,
 604.164 +};
 604.165 +
 604.166 +static const static_codebook _44p0_p2_0 = {
 604.167 +	5, 243,
 604.168 +	(long *)_vq_lengthlist__44p0_p2_0,
 604.169 +	1, -533200896, 1614282752, 2, 0,
 604.170 +	(long *)_vq_quantlist__44p0_p2_0,
 604.171 +	0
 604.172 +};
 604.173 +
 604.174 +static const long _vq_quantlist__44p0_p2_1[] = {
 604.175 +	1,
 604.176 +	0,
 604.177 +	2,
 604.178 +};
 604.179 +
 604.180 +static const long _vq_lengthlist__44p0_p2_1[] = {
 604.181 +	 1, 3, 3, 0, 9, 9, 0, 9, 9, 0,10,10, 0, 9, 9, 0,
 604.182 +	10,10, 0,10,10, 0, 9, 9, 0,10,10, 0, 7, 7, 0, 7,
 604.183 +	 7, 0, 6, 6, 0, 8, 8, 0, 7, 7, 0, 8, 8, 0, 8, 9,
 604.184 +	 0, 8, 8, 0, 8, 8, 0, 7, 7, 0, 9, 9, 0, 8, 8, 0,
 604.185 +	10,10, 0, 9, 9, 0,10,10, 0,10,10, 0, 9, 9, 0,10,
 604.186 +	10, 0, 9, 9, 0,11,11, 0,11,11, 0,12,12, 0,11,11,
 604.187 +	 0,12,12, 0,13,13, 0,12,12, 0,13,12, 0, 8, 8, 0,
 604.188 +	12,12, 0,12,12, 0,13,13, 0,12,12, 0,13,13, 0,13,
 604.189 +	13, 0,13,13, 0,13,13, 0, 7, 7, 0, 0, 0, 0, 0, 0,
 604.190 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.191 +	 0, 0, 0, 9, 9, 0,11,11, 0,12,12, 0,13,13, 0,12,
 604.192 +	12, 0,13,13, 0,13,13, 0,12,12, 0,12,12, 0, 8, 8,
 604.193 +	 0,12,12, 0,12,12, 0,13,13, 0,13,13, 0,13,14, 0,
 604.194 +	14,13, 0,13,13, 0,13,13, 0, 7, 7, 0, 0, 0, 0, 0,
 604.195 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 604.196 +	 0, 0, 0,
 604.197 +};
 604.198 +
 604.199 +static const static_codebook _44p0_p2_1 = {
 604.200 +	5, 243,
 604.201 +	(long *)_vq_lengthlist__44p0_p2_1,
 604.202 +	1, -535822336, 1611661312, 2, 0,
 604.203 +	(long *)_vq_quantlist__44p0_p2_1,
 604.204 +	0
 604.205 +};
 604.206 +
 604.207 +static const long _vq_quantlist__44p0_p3_0[] = {
 604.208 +	1,
 604.209 +	0,
 604.210 +	2,
 604.211 +};
 604.212 +
 604.213 +static const long _vq_lengthlist__44p0_p3_0[] = {
 604.214 +	 1, 6, 6, 7, 8, 8, 7, 8, 8, 7, 9, 9,10,12,11, 9,
 604.215 +	 8, 8, 7, 9, 9,11,12,12, 9, 9, 9, 6, 7, 7,10,11,
 604.216 +	11,10,11,11,10,11,11,13,13,14,12,12,12,11,11,11,
 604.217 +	14,14,14,12,12,12, 6, 5, 5, 9, 6, 5, 9, 6, 6, 9,
 604.218 +	 7, 7,12,10,10,11, 6, 6,10, 7, 7,13,10,10,12, 7,
 604.219 +	 7, 7, 8, 8,12,10,10,12,10,10,11,10,10,15,13,13,
 604.220 +	13, 9, 9,12,11,11,16,13,13,15,11,11, 8, 7, 7,12,
 604.221 +	12,12,12,11,11,12,11,11,14,14,14,14,12,12,12,12,
 604.222 +	12,16,15,15,14,12,12, 0,10,10, 0,12,12, 0,12,12,
 604.223 +	 0,11,11, 0,14,14, 0,11,11, 0,12,12, 0,15,15, 0,
 604.224 +	11,11, 8, 8, 8,13,11,11,13,10,10,13,11,11,15,13,
 604.225 +	13,14,11,11,12,10,10,16,14,14,14,10,10, 9, 7, 7,
 604.226 +	13,11,11,13,11,11,12,11,11,16,14,14,14,12,12,13,
 604.227 +	12,12,15,14,14,15,13,12, 0,11,11, 0,12,12, 0,12,
 604.228 +	12, 0,12,12, 0,15,15, 0,12,12, 0,13,12, 0,14,15,
 604.229 +	 0,12,12,
 604.230 +};
 604.231 +
 604.232 +static const static_codebook _44p0_p3_0 = {
 604.233 +	5, 243,
 604.234 +	(long *)_vq_lengthlist__44p0_p3_0,
 604.235 +	1, -531365888, 1616117760, 2, 0,
 604.236 +	(long *)_vq_quantlist__44p0_p3_0,
 604.237 +	0
 604.238 +};
 604.239 +
 604.240 +static const long _vq_quantlist__44p0_p3_1[] = {
 604.241 +	2,
 604.242 +	1,
 604.243 +	3,
 604.244 +	0,
 604.245 +	4,
 604.246 +};
 604.247 +
 604.248 +static const long _vq_lengthlist__44p0_p3_1[] = {
 604.249 +	 2, 4, 4, 8, 8,10,12,12,11,11, 9,11,11,12,13,11,
 604.250 +	12,12,11,11,11,12,12,12,12,10,13,12,13,13,11,12,
 604.251 +	12,13,13,11,12,12,13,13,11,12,13,13,13,11,13,13,
 604.252 +	13,13,10,13,13,12,13,11,12,12,14,14,11,13,12,12,
 604.253 +	12,11,12,12,13,13,11,13,13,12,12,11,13,13,13,13,
 604.254 +	11,12,12,13,13,11,13,13,12,12,11,12,12,13,13,11,
 604.255 +	13,13,12,12,11,13,13,13,13,11,12,12,14,14,11,13,
 604.256 +	13,12,12,11,12,12,13,13,11,13,13,12,12,11,10,10,
 604.257 +	10,10,12,10,10,11,11,11, 8, 8,11,11,13,10,10,10,
 604.258 +	10,12,10,10,10,10,13,11,11,11,11,13,10,10,11,11,
 604.259 +	13,11,11,12,12,13,11,11,11,11,13,11,11,12,12,13,
 604.260 +	11,11,12,12,13,10,10,11,11,13,11,11,11,11,13,11,
 604.261 +	10,11,11,13,11,11,11,11,13,11,11,11,11,13,10,10,
 604.262 +	11,11,13,11,11,11,11,12,10,11,11,11,13,11,11,11,
 604.263 +	11,13,11,11,11,11,13,10,10,11,11,13,11,11,11,11,
 604.264 +	13,11,11,11,11,13,11,11,11,11,11,10,10,10,10,12,
 604.265 +	10,10, 9, 9,12,12,12,11,11,13,12,12, 9, 9,13,12,
 604.266 +	12,10,10,12,12,12,12,12,13,13,13,14,14,13,12,12,
 604.267 +	11,11,13,13,13,12,12,13,12,12,11,11,13,12,13,11,
 604.268 +	11,13,13,13,14,14,13,12,12,10,10,13,13,13,11,11,
 604.269 +	13,12,12,10,10,13,13,13,11,11,13,13,13,14,14,13,
 604.270 +	12,12,10,10,13,13,13,11,11,13,12,13,10,10,13,13,
 604.271 +	13,11,11,13,13,13,14,14,13,12,12,10,10,13,13,13,
 604.272 +	11,11,13,13,12,10,10,14,12,12, 8, 8,14,12,12, 9,
 604.273 +	 9,14,11,11, 9, 9,14,12,12, 8, 8,14,11,11, 7, 7,
 604.274 +	14,13,13,10,10,15,12,12,10,10,15,13,13,10,10,15,
 604.275 +	12,12, 9, 9,15,13,13,10,10,15,13,13,10,10,15,12,
 604.276 +	12,10,10,15,13,13,10,10,14,12,12, 9, 9,14,13,13,
 604.277 +	 9, 9,14,13,13, 9, 9,15,12,12, 9, 9,15,13,13, 9,
 604.278 +	 9,14,12,12, 9, 9,14,13,13, 9, 9,14,13,13, 9, 9,
 604.279 +	15,12,12, 9, 9,14,13,13, 9, 9,14,12,12, 9, 9,14,
 604.280 +	13,13, 9, 9,13,12,12, 8, 8,13,13,13, 8, 8,14,13,
 604.281 +	13, 9, 9,13,13,13, 7, 7,14,13,13, 8, 8,14,14,14,
 604.282 +	10,10,14,14,14,11,11,14,14,14, 9, 9,14,14,14,10,
 604.283 +	10,14,14,14, 9, 9,14,14,14,10, 9,15,14,14,11,11,
 604.284 +	14,14,14, 9, 9,14,14,14,10,10,14,14,14, 9, 9,14,
 604.285 +	14,14, 9, 9,15,14,14,11,11,14,14,14, 8, 8,14,14,
 604.286 +	14, 9, 9,14,14,14, 8, 8,14,14,14, 9, 9,15,14,14,
 604.287 +	11,11,14,14,14, 8, 8,14,14,14, 9, 9,14,14,14, 8,
 604.288 +	 8,12,12,12,13,13,16,15,15,11,11,16,15,16,12,12,
 604.289 +	17,16,16,11,11,17,15,15,12,11,16,16,16,12,13,16,
 604.290 +	15,15,13,13,16,16,16,12,12,16,16,15,13,13,16,16,
 604.291 +	16,12,12,16,16,16,13,13,17,16,16,14,14,17,17,16,
 604.292 +	12,12,17,16,16,13,13,17,17,16,12,13,16,16,17,13,
 604.293 +	12,17,16,16,14,13,17,16,16,12,12,17,16,16,12,12,
 604.294 +	17,16,17,12,12,17,17,17,13,13,16,16,16,13,14,17,
 604.295 +	17,16,12,12,16,16,16,13,13,17,17,17,12,12,13,14,
 604.296 +	14,10,10,16,14,14,12,12,16,15,15,14,14,16,14,14,
 604.297 +	12,12,15,14,14,13,13,17,15,15,14,13,16,16,15,15,
 604.298 +	15,16,15,15,14,14,16,15,15,14,14,17,15,15,14,14,
 604.299 +	16,15,15,14,14,16,16,15,15,15,17,15,15,13,13,16,
 604.300 +	15,15,14,14,17,15,15,13,13,17,15,15,14,14,16,15,
 604.301 +	15,15,15,16,14,14,13,13,16,15,15,14,14,16,14,14,
 604.302 +	13,13,17,15,15,14,14,16,16,15,15,15,17,14,14,13,
 604.303 +	13,16,15,15,14,14,17,14,14,13,13,13,11,11,10,10,
 604.304 +	16,14,14,13,13,15,14,14,13,13,16,14,14,12,12,16,
 604.305 +	14,14,12,12,15,15,15,14,14,16,14,14,14,14,16,15,
 604.306 +	14,14,14,16,14,14,14,14,16,15,15,14,13,16,15,15,
 604.307 +	14,14,16,14,14,14,14,17,15,15,14,14,16,14,14,14,
 604.308 +	14,16,15,15,13,14,16,15,15,14,14,16,14,14,14,14,
 604.309 +	16,15,15,13,13,16,14,14,13,13,16,15,15,13,13,16,
 604.310 +	15,15,14,14,16,14,14,14,14,17,15,15,13,13,16,15,
 604.311 +	14,13,13,17,15,15,13,13,14,14,14, 9, 9,14,14,14,
 604.312 +	17,17,14,15,15,18,18,14,14,14,18,19,14,14,14,18,
 604.313 +	18,15,15,15,19,18,15,16,15,18,20,15,15,15,18,19,
 604.314 +	15,15,15,19,19,15,15,15,18,20,15,15,15,18,19,15,
 604.315 +	15,16,20,18,15,15,15,18,18,15,15,15,19,19,15,15,
 604.316 +	15,18,19,15,15,15,18,19,15,15,15,19,19,14,15,14,
 604.317 +	19,19,15,15,15,20,19,15,14,14,19,18,14,15,15,18,
 604.318 +	19,15,15,16,20,20,14,14,14,18,19,15,15,15,19,18,
 604.319 +	14,14,14,18,18,14,12,12, 9, 9,13,14,14,18,18,14,
 604.320 +	13,13,18,19,14,14,14,18,18,14,14,14,18,18,15,15,
 604.321 +	15,19,19,15,14,14,19,18,14,15,15,19,18,15,14,14,
 604.322 +	18,18,15,15,15,19,18,14,15,15,19,19,15,14,14,19,
 604.323 +	18,14,15,15,19,18,15,14,14,19,18,14,15,15,19,18,
 604.324 +	15,15,15,21,18,15,14,14,19,18,14,15,15,18,19,14,
 604.325 +	15,14,20,19,14,15,15,18,19,14,15,15,19,19,15,14,
 604.326 +	14,19,20,14,15,15,18,18,14,14,14,19,19,14,15,15,
 604.327 +	19,18,12,12,12,13,13,16,15,15,11,11,16,15,15,12,
 604.328 +	12,16,16,16,11,11,16,15,15,11,11,16,16,16,13,13,
 604.329 +	17,16,16,13,13,17,17,17,12,12,16,16,16,13,13,17,
 604.330 +	16,17,13,12,15,16,16,12,12,16,15,15,13,13,17,16,
 604.331 +	16,12,12,16,16,15,12,12,16,16,16,12,12,17,17,16,
 604.332 +	13,12,16,16,16,13,13,17,16,16,12,12,17,16,16,12,
 604.333 +	12,17,17,16,12,12,16,17,16,12,12,17,15,15,13,13,
 604.334 +	17,16,16,12,12,16,16,16,12,12,16,16,16,12,12,13,
 604.335 +	13,13, 9, 9,15,14,14,13,13,16,15,14,14,14,16,14,
 604.336 +	14,13,13,15,14,14,13,13,17,15,15,14,14,16,15,15,
 604.337 +	15,15,16,15,15,14,14,16,15,15,15,15,17,15,15,14,
 604.338 +	14,16,15,15,14,14,16,15,15,15,15,17,14,15,14,14,
 604.339 +	16,15,15,14,14,17,15,15,13,14,17,15,15,14,14,16,
 604.340 +	15,15,15,15,17,14,14,13,13,16,15,15,14,14,17,14,
 604.341 +	14,13,13,17,15,15,14,14,16,15,16,15,15,17,14,14,
 604.342 +	13,13,16,15,15,14,14,18,14,14,13,13,13,11,11,11,
 604.343 +	11,15,14,14,12,12,15,14,14,13,13,16,14,14,12,12,
 604.344 +	16,13,14,12,12,16,15,15,13,13,16,14,14,14,14,16,
 604.345 +	15,15,13,13,16,14,14,13,13,16,14,15,13,13,15,15,
 604.346 +	15,13,13,16,14,14,14,13,16,14,14,13,13,16,14,14,
 604.347 +	13,13,16,15,15,13,13,16,15,15,13,13,16,14,14,14,
 604.348 +	14,16,15,15,12,12,16,14,14,13,13,16,15,15,12,12,
 604.349 +	16,15,15,13,13,16,14,14,14,14,17,15,14,12,12,16,
 604.350 +	14,14,13,13,16,15,15,12,12,14,14,14, 8, 8,14,14,
 604.351 +	14,17,18,14,15,15,17,18,14,14,14,17,18,14,14,14,
 604.352 +	18,18,14,15,15,18,18,14,16,15,19,19,15,15,15,18,
 604.353 +	19,15,16,15,20,19,15,15,15,18,18,14,15,15,18,19,
 604.354 +	15,16,16,20,19,15,15,15,19,17,14,15,15,20,18,14,
 604.355 +	15,15,18,18,14,15,15,18,19,14,15,15,19,20,14,14,
 604.356 +	14,18,18,14,15,15,18,19,14,14,14,18,19,14,15,15,
 604.357 +	19,18,15,16,16,20,21,14,14,15,19,19,14,15,15,19,
 604.358 +	19,14,14,14,19,18,13,12,12, 9, 9,13,14,14,18,19,
 604.359 +	14,14,14,18,19,14,14,14,18,18,14,14,14,18,18,14,
 604.360 +	15,15,19,19,15,14,14,19,18,15,15,15,19,19,15,14,
 604.361 +	14,19,20,14,15,15,18,19,14,15,15,20,18,15,14,14,
 604.362 +	18,18,14,15,15,18,18,14,14,14,19,19,14,15,15,18,
 604.363 +	18,14,15,15,19,18,15,14,14,19,19,14,15,15,19,18,
 604.364 +	15,14,14,19,18,14,14,15,18,19,14,15,15,19,18,15,
 604.365 +	14,14,18,19,14,15,14,19,20,14,14,14,19,19,14,15,
 604.366 +	15,19,19,12,12,12,13,13,16,16,16,11,11,16,16,16,
 604.367 +	12,12,17,16,16,11,11,17,15,15,11,11,16,16,16,13,
 604.368 +	13,17,15,16,13,13,16,16,16,12,12,17,16,16,13,13,
 604.369 +	17,17,16,12,12,17,17,16,13,13,17,16,16,13,13,17,
 604.370 +	17,17,12,12,17,16,16,13,13,17,17,17,12,12,16,16,
 604.371 +	16,12,12,17,15,15,13,13,17,16,16,11,11,17,16,16,
 604.372 +	12,12,16,16,16,11,11,16,17,16,12,12,17,16,16,13,
 604.373 +	13,17,17,16,12,12,17,17,16,12,12,17,16,16,11,11,
 604.374 +	13,14,14, 9, 9,16,14,14,13,13,16,14,15,14,14,16,
 604.375 +	14,14,12,12,16,14,14,13,13,17,15,15,14,14,16,15,
 604.376 +	15,15,15,17,15,15,14,14,16,15,15,14,14,17,15,15,
 604.377 +	14,14,16,15,15,14,14,16,15,15,15,16,17,14,15,14,
 604.378 +	14,16,15,15,14,14,17,15,15,14,14,16,15,15,14,14,
 604.379 +	16,15,15,15,15,17,14,14,13,13,16,15,15,14,14,16,
 604.380 +	14,14,13,13,17,15,15,14,14,16,16,15,15,15,17,14,
 604.381 +	14,13,13,16,15,15,14,14,17,14,14,13,13,13,11,11,
 604.382 +	10,10,16,14,14,12,12,15,13,13,13,12,16,14,14,11,
 604.383 +	11,16,14,14,11,11,16,14,15,13,14,16,14,14,13,13,
 604.384 +	16,15,15,13,13,16,14,14,13,13,16,15,15,13,13,16,
 604.385 +	15,15,13,13,17,14,14,14,14,17,15,15,13,13,16,14,
 604.386 +	15,13,13,16,15,15,13,13,16,15,15,13,13,16,14,14,
 604.387 +	13,13,17,15,15,12,12,16,14,14,12,12,16,15,15,12,
 604.388 +	12,16,15,15,13,13,16,14,14,13,13,17,15,15,12,12,
 604.389 +	17,14,14,12,12,16,15,15,12,12,13,14,14, 8, 8,13,
 604.390 +	14,14,18,18,13,15,15,17,18,14,14,14,18,19,14,14,
 604.391 +	14,19,18,14,15,15,19,18,15,15,16,21,18,15,15,15,
 604.392 +	19,19,14,16,16,19,19,14,15,15,18,19,14,15,15,19,
 604.393 +	20,14,16,16,19,18,15,15,15,18,19,14,15,15,19,18,
 604.394 +	15,15,15,18,18,15,15,15,20,18,15,16,16,20,19,14,
 604.395 +	15,14,18,19,14,15,16,19,20,14,15,15,19,18,15,15,
 604.396 +	15,19,18,15,16,16,20,19,15,14,14,18,18,14,15,15,
 604.397 +	19,19,14,15,15,18,18,13,12,12, 8, 8,13,14,14,19,
 604.398 +	18,14,13,13,20,18,14,14,14,19,18,14,13,13,18,19,
 604.399 +	14,15,15,20,19,15,14,14,19,19,14,15,15,19,18,15,
 604.400 +	14,14,20,20,15,15,15,19,18,14,15,15,19,18,15,14,
 604.401 +	14,19,18,14,15,15,20,19,14,14,14,20,19,14,15,15,
 604.402 +	19,18,15,15,15,18,18,15,14,14,18,18,14,15,15,19,
 604.403 +	19,14,14,14,19,19,14,15,15,19,19,15,15,15,19,18,
 604.404 +	15,14,14,20,19,15,15,15,19,19,14,14,14,20,19,14,
 604.405 +	15,15,20,20,12,12,12,13,13,17,16,16,11,11,16,16,
 604.406 +	15,12,12,17,16,16,11,11,17,15,15,11,11,17,17,17,
 604.407 +	13,13,17,16,16,13,13,17,17,17,12,12,17,16,16,13,
 604.408 +	13,17,17,16,12,13,16,17,16,13,13,17,16,15,13,13,
 604.409 +	17,16,16,12,12,17,16,16,12,13,17,16,17,12,12,17,
 604.410 +	17,17,12,12,17,16,15,13,13,17,16,16,12,12,17,16,
 604.411 +	16,12,12,17,16,16,11,11,16,16,16,12,12,17,15,15,
 604.412 +	13,13,17,16,15,11,11,16,16,16,12,12,17,16,16,11,
 604.413 +	11,13,14,14, 9, 9,16,14,14,13,13,16,14,15,14,14,
 604.414 +	16,14,14,12,12,16,14,14,13,13,17,15,15,14,15,16,
 604.415 +	15,15,15,15,17,15,15,14,14,16,15,15,15,14,16,15,
 604.416 +	15,14,14,16,15,15,14,14,16,15,16,15,15,17,15,14,
 604.417 +	14,14,16,15,15,14,14,17,15,15,13,13,16,15,15,14,
 604.418 +	14,16,16,16,15,15,17,14,14,13,13,16,15,15,14,14,
 604.419 +	18,14,15,13,13,16,15,15,14,14,16,16,15,15,15,16,
 604.420 +	14,14,13,13,16,15,15,14,14,17,14,15,13,13,13,11,
 604.421 +	11,10,10,15,14,14,12,12,15,14,14,13,13,16,14,14,
 604.422 +	12,12,16,13,14,12,12,16,14,15,14,13,16,14,14,14,
 604.423 +	14,16,15,15,13,13,16,14,14,13,13,16,15,15,13,13,
 604.424 +	15,15,15,13,13,16,14,14,14,14,17,15,15,13,13,16,
 604.425 +	14,14,13,13,16,15,15,13,13,16,15,15,13,13,16,14,
 604.426 +	14,13,13,17,15,15,12,12,16,14,14,12,12,16,14,15,
 604.427 +	12,12,16,15,15,13,13,16,14,14,13,13,17,15,15,12,
 604.428 +	12,16,14,14,12,12,16,15,15,12,12,14,14,14, 8, 8,
 604.429 +	14,14,14,17,17,14,15,15,18,18,14,14,14,18,17,14,
 604.430 +	14,14,18,18,14,15,15,18,20,15,16,15,19,18,15,15,
 604.431 +	15,19,18,15,15,16,19,18,15,15,15,18,18,14,15,15,
 604.432 +	18,18,15,16,16,18,19,15,15,15,18,18,15,15,15,19,
 604.433 +	20,15,15,15,18,18,15,15,15,18,18,15,16,16,19,19,
 604.434 +	15,14,15,19,19,15,15,15,19,20,14,14,15,18,18,15,
 604.435 +	15,15,19,19,15,16,16,19,19,15,15,14,18,19,15,15,
 604.436 +	15,20,20,15,15,14,18,18,13,12,12, 8, 8,13,14,14,
 604.437 +	18,18,14,14,14,18,18,14,14,14,18,20,14,14,14,18,
 604.438 +	18,14,15,15,19,18,15,14,14,18,19,15,15,15,18,19,
 604.439 +	15,14,14,18,19,15,15,15,18,18,14,15,14,18,19,15,
 604.440 +	14,14,21,19,15,15,15,19,18,14,14,14,19,18,14,15,
 604.441 +	15,19,18,15,15,15,20,19,15,14,14,20,18,14,15,15,
 604.442 +	18,19,14,14,14,19,18,14,15,15,18,19,15,15,15,18,
 604.443 +	19,15,14,14,19,19,15,15,15,19,19,14,14,14,19,20,
 604.444 +	14,15,15,18,19,
 604.445 +};
 604.446 +
 604.447 +static const static_codebook _44p0_p3_1 = {
 604.448 +	5, 3125,
 604.449 +	(long *)_vq_lengthlist__44p0_p3_1,
 604.450 +	1, -533725184, 1611661312, 3, 0,
 604.451 +	(long *)_vq_quantlist__44p0_p3_1,
 604.452 +	0
 604.453 +};
 604.454 +
 604.455 +static const long _vq_quantlist__44p0_p4_0[] = {
 604.456 +	2,
 604.457 +	1,
 604.458 +	3,
 604.459 +	0,
 604.460 +	4,
 604.461 +};
 604.462 +
 604.463 +static const long _vq_lengthlist__44p0_p4_0[] = {
 604.464 +	 2, 6, 6,14,14, 6, 8, 8,14,14, 7, 7, 7,14,14, 0,
 604.465 +	13,13,15,16, 0,13,13,15,15, 7, 8, 8,15,15, 9,10,
 604.466 +	10,16,16, 9, 8, 8,14,15, 0,13,13,17,17, 0,13,13,
 604.467 +	16,16, 8, 8, 8,15,15,12,11,11,16,16, 9, 8, 8,14,
 604.468 +	14, 0,13,13,17,17, 0,13,13,15,15, 0,14,14,16,16,
 604.469 +	 0, 0, 0,18,19, 0,12,12,16,15, 0,16,16, 0,20, 0,
 604.470 +	14,14,16,16, 0,14,14,17,17, 0, 0, 0,19,19, 0,12,
 604.471 +	12,15,15, 0,18,17,21,21, 0,14,14,16,16, 5, 7, 7,
 604.472 +	12,13, 9,10, 9,14,14,11,10,10,14,14, 0, 0, 0,18,
 604.473 +	17, 0,20,21,18,18, 9,10,10,14,14,12,12,12,17,16,
 604.474 +	12,10,10,14,14, 0,20,20,18,17, 0,21,21,17,17,11,
 604.475 +	10,10,14,14,15,13,13,18,18,13,11,11,14,14, 0,20,
 604.476 +	 0,18,18, 0,20,21,18,17, 0,21, 0,18,19, 0, 0, 0,
 604.477 +	 0,21, 0,21,20,16,17, 0, 0, 0,21,21, 0, 0, 0,20,
 604.478 +	18, 0,20, 0,17,18, 0, 0, 0, 0, 0, 0, 0,20,16,17,
 604.479 +	 0, 0, 0,20, 0, 0, 0, 0,18,18, 6, 6, 6,13,13, 8,
 604.480 +	 5, 5,11,11, 9, 6, 6,13,13, 0, 9, 9,12,12, 0,10,
 604.481 +	10,14,14, 9, 7, 7,13,13,12, 9, 9,13,13,10, 6, 6,
 604.482 +	13,13, 0,10,10,14,14, 0,10,10,13,13, 9, 7, 7,13,
 604.483 +	13,13,10,10,13,13,11, 6, 6,13,13, 0,10,10,15,15,
 604.484 +	 0,10,10,13,13, 0,12,11,15,15, 0,20,19,17,16, 0,
 604.485 +	 9, 9,13,13, 0,13,13,20,19, 0,11,11,13,13, 0,11,
 604.486 +	11,15,15, 0,20,19,17,17, 0,10,10,13,13, 0,14,15,
 604.487 +	 0,21, 0,12,12,13,13, 0,10,10,12,12, 0,11,11,15,
 604.488 +	15, 0,11,11,15,15, 0,15,15,20,20, 0,16,16, 0, 0,
 604.489 +	 0,11,11,15,15, 0,14,14,17,17, 0,11,11,15,15, 0,
 604.490 +	15,15,20,21, 0,16,16,21,21, 0,12,12,15,15, 0,15,
 604.491 +	15,18,20, 0,11,11,16,15, 0,15,15,21,21, 0,16,16,
 604.492 +	 0,21, 0,16,16, 0, 0, 0, 0, 0, 0, 0, 0,14,14,21,
 604.493 +	21, 0,17,18, 0, 0, 0,16,17,20, 0, 0,16,16, 0, 0,
 604.494 +	 0, 0, 0, 0, 0, 0,15,15,20,20, 0,19,18, 0,21, 0,
 604.495 +	18,17, 0, 0, 0,10,10,11,11, 0,10,10,10,10, 0,11,
 604.496 +	11,12,12, 0,11,11, 9, 9, 0,13,13,12,12, 0,11,11,
 604.497 +	12,12, 0,13,13,12,12, 0,10,10,12,12, 0,12,12,13,
 604.498 +	13, 0,12,12,12,12, 0,11,11,12,12, 0,13,13,12,12,
 604.499 +	 0,10,10,12,12, 0,13,13,13,13, 0,12,12,12,12, 0,
 604.500 +	14,13,13,13, 0,19,21,15,15, 0,12,11,12,12, 0,16,
 604.501 +	15,19,19, 0,13,13,11,11, 0,13,13,13,13, 0, 0,21,
 604.502 +	15,16, 0,12,12,12,12, 0,16,16,19,21, 0,13,13,12,
 604.503 +	12, 7, 7, 7,16,16,11, 9, 9,16,16,12, 9, 9,16,16,
 604.504 +	 0,13,13,16,16, 0,14,14,17,16,11, 9, 9,16,16,14,
 604.505 +	12,11,17,17,13, 8, 9,15,15, 0,13,13,19,19, 0,13,
 604.506 +	13,16,15,12,10,10,17,17,15,12,12,19,18,14, 9, 9,
 604.507 +	17,16, 0,14,14,18, 0, 0,14,13,16,16, 0,14,15,18,
 604.508 +	17, 0,21, 0,19,21, 0,12,12,16,16, 0,16,16, 0, 0,
 604.509 +	 0,14,14,16,16, 0,14,14,18,18, 0, 0,21,20, 0, 0,
 604.510 +	13,13,16,17, 0,18,18, 0, 0, 0,15,14,17,16, 8, 7,
 604.511 +	 7,14,14,11,10,10,15,15,13,10,10,15,15, 0,21,20,
 604.512 +	19,19, 0,21, 0,17,18,11,10,10,15,16,14,12,12,18,
 604.513 +	18,14,11,11,15,14, 0,21,20,18,19, 0, 0,21,18,18,
 604.514 +	12,11,11,16,16,16,14,14,18,20,14,11,11,16,15, 0,
 604.515 +	20,20,19,19, 0, 0,20,18,18, 0,21, 0,18,19, 0, 0,
 604.516 +	 0, 0, 0, 0,20,20,17,18, 0, 0, 0,20,20, 0, 0, 0,
 604.517 +	19,19, 0, 0, 0,20,18, 0, 0, 0, 0, 0, 0, 0,21,18,
 604.518 +	18, 0,21,21, 0,21, 0, 0, 0,19,20,11, 9, 9,14,14,
 604.519 +	13,10,10,14,14,13,11,11,15,15, 0,13,13,13,13, 0,
 604.520 +	14,14,16,16,13,11,11,15,15,16,12,12,15,15,14,10,
 604.521 +	10,14,14, 0,14,14,16,16, 0,14,14,15,15,13,10,10,
 604.522 +	15,15,17,13,14,15,16,15,10,10,15,15, 0,14,14,17,
 604.523 +	16, 0,14,14,15,15, 0,15,15,17,17, 0, 0,21,18,18,
 604.524 +	 0,13,13,15,15, 0,16,16,21,20, 0,14,14,15,14, 0,
 604.525 +	15,14,16,17, 0, 0,20,20,19, 0,13,13,15,15, 0,19,
 604.526 +	18, 0, 0, 0,15,15,15,15, 0,11,11,14,14, 0,12,12,
 604.527 +	16,16, 0,12,12,16,16, 0,15,16,21,21, 0,16,17,21,
 604.528 +	 0, 0,12,12,17,16, 0,14,14,18,19, 0,11,11,16,16,
 604.529 +	 0,15,15,20,21, 0,16,16,21, 0, 0,12,12,17,16, 0,
 604.530 +	15,15,19,19, 0,12,12,16,17, 0,16,15, 0, 0, 0,16,
 604.531 +	16, 0, 0, 0,17,17, 0,21, 0, 0, 0, 0, 0, 0,14,15,
 604.532 +	20, 0, 0,17,17, 0, 0, 0,17,17, 0, 0, 0,17,16, 0,
 604.533 +	 0, 0, 0, 0, 0, 0, 0,15,15, 0, 0, 0,18,18, 0, 0,
 604.534 +	 0,18,17, 0, 0, 0,11,11,14,14, 0,12,12,15,15, 0,
 604.535 +	12,12,15,15, 0,13,13,14,14, 0,14,14,17,17, 0,12,
 604.536 +	12,16,16, 0,14,14,16,16, 0,11,11,15,15, 0,13,13,
 604.537 +	16,17, 0,13,13,16,16, 0,12,12,15,15, 0,14,14,17,
 604.538 +	16, 0,11,11,15,15, 0,14,14,17,17, 0,13,13,16,16,
 604.539 +	 0,15,15,17,18, 0,21,20,20,21, 0,12,12,15,15, 0,
 604.540 +	16,16,20,21, 0,14,14,15,15, 0,14,14,17,17, 0, 0,
 604.541 +	 0,18,19, 0,12,13,15,15, 0,18,17,21, 0, 0,14,15,
 604.542 +	15,15, 8, 8, 8,16,16,12,10,10,16,16,13, 9, 9,16,
 604.543 +	16, 0,14,14,18,17, 0,14,14,16,17,12,10,10,18,17,
 604.544 +	14,12,11,18,18,14, 9, 9,16,16, 0,13,13,18,18, 0,
 604.545 +	13,13,17,16,12, 9, 9,16,17,17,13,13,17,17,14, 9,
 604.546 +	 9,15,15, 0,14,14,20,19, 0,13,13,16,16, 0,15,15,
 604.547 +	19,18, 0, 0, 0,20,19, 0,12,13,17,17, 0,16,16,20,
 604.548 +	 0, 0,14,14,16,17, 0,14,14,19,18, 0, 0, 0,20,20,
 604.549 +	 0,13,13,16,16, 0,18,17, 0, 0, 0,15,15,16,16, 9,
 604.550 +	 7, 7,14,14,12,10,10,15,15,13,10,10,15,15, 0,21,
 604.551 +	 0,18,19, 0,20,21,19,18,12,10,10,16,15,15,13,13,
 604.552 +	18,18,14,11,11,15,15, 0, 0, 0,19,18, 0, 0,21,18,
 604.553 +	18,13,11,11,15,15,16,14,14,17,19,15,11,11,15,15,
 604.554 +	 0,21,21,20,18, 0, 0,21,18,18, 0, 0,21,21,19, 0,
 604.555 +	 0, 0, 0, 0, 0,19,20,18,17, 0, 0, 0,21,21, 0,21,
 604.556 +	 0,20,18, 0, 0,21,19,19, 0, 0, 0, 0, 0, 0,20,21,
 604.557 +	17,17, 0, 0, 0, 0, 0, 0,21, 0,18,20, 0,10,10,14,
 604.558 +	14, 0,11,11,15,15, 0,11,11,15,15, 0,14,14,15,15,
 604.559 +	 0,15,15,16,16, 0,11,12,16,16, 0,13,13,16,16, 0,
 604.560 +	11,11,15,15, 0,14,14,17,17, 0,14,14,15,15, 0,11,
 604.561 +	11,16,15, 0,14,14,15,15, 0,11,11,15,15, 0,15,15,
 604.562 +	17,17, 0,14,14,15,15, 0,16,16,18,18, 0, 0, 0,20,
 604.563 +	19, 0,14,13,16,15, 0,17,17,21, 0, 0,15,15,15,15,
 604.564 +	 0,16,15,17,16, 0,20, 0,20,18, 0,13,14,15,15, 0,
 604.565 +	19,18, 0,21, 0,15,15,15,15, 0,11,11,14,14, 0,12,
 604.566 +	12,16,16, 0,12,12,16,16, 0,16,15,20,21, 0,17,16,
 604.567 +	 0, 0, 0,12,12,16,16, 0,14,14,18,18, 0,11,11,16,
 604.568 +	16, 0,15,15,21,20, 0,16,16, 0, 0, 0,12,12,16,17,
 604.569 +	 0,15,14,19,19, 0,11,12,16,16, 0,15,15,21, 0, 0,
 604.570 +	16,16, 0, 0, 0,16,17, 0, 0, 0, 0, 0, 0, 0, 0,15,
 604.571 +	15,21, 0, 0,17,17, 0, 0, 0,17,17, 0, 0, 0,17,16,
 604.572 +	 0, 0, 0, 0, 0, 0, 0, 0,15,15, 0,20, 0,19,20, 0,
 604.573 +	 0, 0,17,17, 0, 0, 0,12,12,15,15, 0,12,12,15,15,
 604.574 +	 0,12,12,16,16, 0,13,13,15,15, 0,15,15,17,17, 0,
 604.575 +	13,13,17,16, 0,14,14,17,17, 0,11,11,16,16, 0,14,
 604.576 +	14,17,17, 0,13,13,16,16, 0,12,12,16,16, 0,15,15,
 604.577 +	16,17, 0,11,11,15,16, 0,14,14,17,17, 0,13,14,16,
 604.578 +	16, 0,15,15,18,18, 0,21,20,20,19, 0,13,13,16,17,
 604.579 +	 0,16,16, 0, 0, 0,14,14,16,16, 0,15,15,18,18, 0,
 604.580 +	 0, 0,20,19, 0,13,13,16,16, 0,17,17, 0, 0, 0,14,
 604.581 +	14,16,16, 0,11,11,16,16, 0,13,13,18,17, 0,13,13,
 604.582 +	17,17, 0,16,16,17,17, 0,16,16,17,18, 0,12,12,17,
 604.583 +	17, 0,15,15,18,18, 0,12,12,16,16, 0,16,16,19,19,
 604.584 +	 0,15,15,16,17, 0,12,12,17,17, 0,17,17,18,18, 0,
 604.585 +	12,12,17,17, 0,16,16,19,19, 0,15,16,17,17, 0,16,
 604.586 +	16,18,17, 0, 0, 0,21,21, 0,13,13,16,16, 0,17,17,
 604.587 +	 0,20, 0,15,15,16,17, 0,16,16,19,18, 0, 0,21,20,
 604.588 +	21, 0,14,14,17,16, 0,20, 0, 0, 0, 0,15,16,16,17,
 604.589 +	 0, 9, 9,14,14, 0,13,13,16,16, 0,14,14,15,15, 0,
 604.590 +	 0,20,19,19, 0, 0, 0,19,19, 0,12,12,15,15, 0,15,
 604.591 +	16,19,18, 0,14,14,15,15, 0,21, 0,18,18, 0,20, 0,
 604.592 +	17,18, 0,13,13,16,16, 0,17,17,17,19, 0,14,14,16,
 604.593 +	15, 0,21,20,20,19, 0, 0, 0,19,19, 0, 0, 0,19,18,
 604.594 +	 0, 0, 0, 0, 0, 0,20,20,17,18, 0, 0, 0,21,21, 0,
 604.595 +	 0, 0,18,18, 0,21, 0,18,19, 0, 0, 0, 0, 0, 0,20,
 604.596 +	21,18,18, 0, 0, 0,20,21, 0, 0, 0,19,19, 0,18,18,
 604.597 +	15,15, 0,20,21,17,17, 0,19,21,17,17, 0, 0, 0,17,
 604.598 +	18, 0, 0, 0,20,19, 0,19,19,17,17, 0, 0, 0,18,18,
 604.599 +	 0,19,20,16,17, 0, 0,21,20,20, 0,19,20,19,18, 0,
 604.600 +	19,20,16,16, 0, 0, 0,18,19, 0,19,20,17,17, 0, 0,
 604.601 +	21, 0,20, 0,21,21,17,19, 0,20, 0,19,20, 0, 0, 0,
 604.602 +	20, 0, 0,19,18,17,16, 0, 0, 0, 0, 0, 0, 0,20,17,
 604.603 +	17, 0,20,21,18,20, 0, 0, 0, 0,21, 0,19,20,17,17,
 604.604 +	 0, 0, 0, 0, 0, 0,20,21,17,17, 0,11,11,14,14, 0,
 604.605 +	13,13,16,17, 0,13,13,16,16, 0,17,17, 0,21, 0,18,
 604.606 +	17,21, 0, 0,13,13,16,16, 0,15,15,18,18, 0,12,12,
 604.607 +	16,16, 0,17,16,21, 0, 0,17,17, 0, 0, 0,12,12,17,
 604.608 +	17, 0,17,17,19,21, 0,13,12,16,16, 0,17,17, 0, 0,
 604.609 +	 0,17,17, 0, 0, 0,18,17, 0,21, 0, 0, 0, 0, 0, 0,
 604.610 +	15,15,20, 0, 0,20,18, 0, 0, 0,17,18, 0, 0, 0,16,
 604.611 +	17, 0, 0, 0, 0, 0, 0, 0, 0,15,15, 0, 0, 0,19,19,
 604.612 +	 0, 0, 0,18,18, 0, 0, 0,14,14,18,18, 0,16,16, 0,
 604.613 +	21, 0,16,16,21,21, 0,17,17, 0,20, 0,17,17,20, 0,
 604.614 +	 0,16,15, 0, 0, 0,20,20, 0, 0, 0,15,15,20,20, 0,
 604.615 +	17,17,21, 0, 0,17,18,20,20, 0,15,15,20,20, 0,18,
 604.616 +	18, 0, 0, 0,15,15,19,20, 0,17,18, 0, 0, 0,17,17,
 604.617 +	20,20, 0,18,17,21, 0, 0, 0, 0, 0,21, 0,15,15,20,
 604.618 +	20, 0,19,19, 0, 0, 0,17,17,21, 0, 0,17,17, 0, 0,
 604.619 +	 0, 0, 0,21, 0, 0,15,15,19,19, 0,20,21, 0, 0, 0,
 604.620 +	18,17,21,21, 0,12,12,16,16, 0,14,14,17,17, 0,13,
 604.621 +	13,17,18, 0,16,16,18,17, 0,16,16,18,18, 0,13,13,
 604.622 +	18,18, 0,15,16,19,18, 0,13,13,16,16, 0,16,16,20,
 604.623 +	18, 0,16,16,17,17, 0,12,13,17,17, 0,17,16,18,18,
 604.624 +	 0,12,12,16,16, 0,17,16,20,19, 0,16,16,16,16, 0,
 604.625 +	16,17,18,20, 0, 0, 0,21,20, 0,14,14,17,16, 0,19,
 604.626 +	18, 0,20, 0,16,16,17,16, 0,16,16,17,18, 0, 0,21,
 604.627 +	21,21, 0,14,14,16,16, 0,20,20,21, 0, 0,16,16,16,
 604.628 +	16, 0,10,10,14,14, 0,14,14,15,16, 0,14,14,15,15,
 604.629 +	 0, 0,21,18,18, 0, 0,21,18,19, 0,13,13,16,16, 0,
 604.630 +	16,16,18,18, 0,14,14,15,15, 0,21, 0,18,18, 0,21,
 604.631 +	 0,18,18, 0,13,13,16,16, 0,17,17,19,20, 0,14,14,
 604.632 +	15,15, 0, 0, 0,18,20, 0, 0,21,18,18, 0, 0,21,19,
 604.633 +	18, 0, 0, 0, 0, 0, 0,20,21,18,17, 0, 0, 0,21,21,
 604.634 +	 0, 0, 0,19,19, 0,21, 0,18,19, 0, 0, 0, 0, 0, 0,
 604.635 +	21,20,17,17, 0, 0,21,20, 0, 0, 0, 0,19,19, 0,19,
 604.636 +	20,15,16, 0, 0,20,18,17, 0,20,21,17,18, 0,21, 0,
 604.637 +	18,18, 0, 0, 0,19,19, 0,20,20,17,18, 0, 0, 0,18,
 604.638 +	19, 0,20,20,18,17, 0, 0, 0, 0,20, 0, 0,21,17,18,
 604.639 +	 0,20,21,17,17, 0, 0, 0,18,18, 0,19,19,17,17, 0,
 604.640 +	 0, 0,21,21, 0,20,20,17,17, 0, 0, 0,21,19, 0, 0,
 604.641 +	 0,20,19, 0,21,20,17,18, 0, 0, 0, 0, 0, 0, 0,20,
 604.642 +	18,17, 0,21,20,18,18, 0, 0, 0,20,21, 0,20,20,17,
 604.643 +	17, 0, 0, 0, 0, 0, 0,20, 0,17,17, 0,11,11,13,14,
 604.644 +	 0,13,13,16,16, 0,13,13,16,16, 0,17,17, 0, 0, 0,
 604.645 +	17,18, 0, 0, 0,13,13,16,16, 0,15,16,18,18, 0,13,
 604.646 +	13,16,17, 0,16,17,20, 0, 0,17,18,20, 0, 0,13,13,
 604.647 +	17,17, 0,16,16,20,21, 0,13,13,16,16, 0,17,17,21,
 604.648 +	 0, 0,17,18, 0, 0, 0,17,18, 0,21, 0, 0, 0, 0, 0,
 604.649 +	 0,15,15,20, 0, 0,19,19, 0, 0, 0,17,17, 0, 0, 0,
 604.650 +	18,17,21,20, 0, 0, 0, 0, 0, 0,16,16,20,21, 0,21,
 604.651 +	20, 0,21, 0,19,21, 0, 0, 0,15,15, 0, 0, 0,16,17,
 604.652 +	 0,19, 0,16,16, 0, 0, 0,17,17, 0, 0, 0,19,18, 0,
 604.653 +	 0, 0,16,16,20,20, 0,20,18,21, 0, 0,15,15,21,21,
 604.654 +	 0,18,18, 0, 0, 0,18,19, 0, 0, 0,16,15, 0,21, 0,
 604.655 +	20,19, 0, 0, 0,16,16, 0, 0, 0,20,18, 0,21, 0,17,
 604.656 +	18,21, 0, 0,18,19, 0, 0, 0, 0, 0, 0, 0, 0,16,16,
 604.657 +	20,20, 0,19,20, 0, 0, 0,17,17, 0, 0, 0,18,17,20,
 604.658 +	21, 0, 0, 0, 0, 0, 0,16,16, 0,20, 0,20,22, 0, 0,
 604.659 +	 0,18,18, 0,22,
 604.660 +};
 604.661 +
 604.662 +static const static_codebook _44p0_p4_0 = {
 604.663 +	5, 3125,
 604.664 +	(long *)_vq_lengthlist__44p0_p4_0,
 604.665 +	1, -528744448, 1616642048, 3, 0,
 604.666 +	(long *)_vq_quantlist__44p0_p4_0,
 604.667 +	0
 604.668 +};
 604.669 +
 604.670 +static const long _vq_quantlist__44p0_p4_1[] = {
 604.671 +	3,
 604.672 +	2,
 604.673 +	4,
 604.674 +	1,
 604.675 +	5,
 604.676 +	0,
 604.677 +	6,
 604.678 +};
 604.679 +
 604.680 +static const long _vq_lengthlist__44p0_p4_1[] = {
 604.681 +	 2, 3, 3, 3, 3, 3, 3,
 604.682 +};
 604.683 +
 604.684 +static const static_codebook _44p0_p4_1 = {
 604.685 +	1, 7,
 604.686 +	(long *)_vq_lengthlist__44p0_p4_1,
 604.687 +	1, -533200896, 1611661312, 3, 0,
 604.688 +	(long *)_vq_quantlist__44p0_p4_1,
 604.689 +	0
 604.690 +};
 604.691 +
 604.692 +static const long _vq_quantlist__44p0_p5_0[] = {
 604.693 +	1,
 604.694 +	0,
 604.695 +	2,
 604.696 +};
 604.697 +
 604.698 +static const long _vq_lengthlist__44p0_p5_0[] = {
 604.699 +	 1, 6, 6, 6, 8, 8, 7, 8, 8, 7, 9, 8,10,11,11, 9,
 604.700 +	 8, 8, 7, 8, 8,11,11,11, 9, 8, 8, 6, 7, 7,10,10,
 604.701 +	10,10,10,10,10,10,10,14,13,13,12,11,11,10,10,10,
 604.702 +	14,14,13,13,11,11, 6, 6, 6, 8, 5, 5, 8, 7, 7, 8,
 604.703 +	 7, 7,11, 9, 9, 9, 7, 7, 8, 7, 7,12,10,10,10, 7,
 604.704 +	 7, 7, 8, 8,12,11,11,12,10,10,11,10,10,14,13,13,
 604.705 +	13,10,10,11,10,11,16,14,14,13,10,10, 7, 8, 7,12,
 604.706 +	12,12,12,11,11,12,11,11,16,14,15,13,12,12,11,11,
 604.707 +	11,17,15,14,14,13,13,10, 9, 9,13,11,11,13,11,11,
 604.708 +	12,11,11,16,14,13,14,11,11,12,11,11,16,15,14,14,
 604.709 +	11,11, 7, 8, 8,12,11,11,12,10,10,12,10,10,16,14,
 604.710 +	13,13,11,11,12,10,10,16,14,14,13,10,10, 8, 8, 8,
 604.711 +	12,12,12,12,11,11,12,11,11,16,14,15,14,12,12,12,
 604.712 +	11,11,16,15,15,14,12,12,10,10,10,13,11,11,13,11,
 604.713 +	11,12,12,12,16,14,14,14,11,11,12,11,11,17,14,15,
 604.714 +	14,11,11,
 604.715 +};
 604.716 +
 604.717 +static const static_codebook _44p0_p5_0 = {
 604.718 +	5, 243,
 604.719 +	(long *)_vq_lengthlist__44p0_p5_0,
 604.720 +	1, -527106048, 1620377600, 2, 0,
 604.721 +	(long *)_vq_quantlist__44p0_p5_0,
 604.722 +	0
 604.723 +};
 604.724 +
 604.725 +static const long _vq_quantlist__44p0_p5_1[] = {
 604.726 +	1,
 604.727 +	0,
 604.728 +	2,
 604.729 +};
 604.730 +
 604.731 +static const long _vq_lengthlist__44p0_p5_1[] = {
 604.732 +	 2, 7, 7, 7, 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 9, 8,
 604.733 +	 7, 7, 8, 8, 8, 9, 9, 9, 9, 7, 7, 6, 6, 6, 9, 7,
 604.734 +	 7, 9, 7, 7, 9, 8, 8,10, 8, 8,10, 8, 8,10, 8, 8,
 604.735 +	10, 8, 8,10, 8, 8, 7, 6, 6, 9, 6, 6, 9, 6, 6, 9,
 604.736 +	 7, 7,10, 8, 8, 9, 6, 6, 9, 7, 7,10, 8, 8, 9, 7,
 604.737 +	 7, 7, 8, 8,11, 9, 9,11, 9, 9,11, 9, 9,12, 9, 9,
 604.738 +	12, 8, 8,12, 9, 9,12,10, 9,12, 8, 8, 8, 7, 7,10,
 604.739 +	 9, 9,11, 9, 9,11, 9, 9,11,11,10,11, 9, 9,11,10,
 604.740 +	 9,11,10,11,11, 9, 9,10, 8, 8,11, 9, 9,11, 9, 9,
 604.741 +	11, 9, 9,11,10,10,11, 9, 9,11, 9, 9,11,10,10,11,
 604.742 +	 9, 9, 9, 8, 8,12, 9, 9,12, 9, 9,11, 9, 9,12, 9,
 604.743 +	 9,12, 8, 8,12, 9, 9,12, 9, 9,12, 8, 8, 9, 7, 7,
 604.744 +	11, 9,10,11,10, 9,11, 9, 9,11,11,11,11, 9, 9,11,
 604.745 +	10,10,11,11,11,11, 9, 9,10, 9, 9,11, 9, 9,11,10,
 604.746 +	10,11,10, 9,11,10,10,11, 9, 9,11,10,10,11,10,11,
 604.747 +	11, 9, 9,
 604.748 +};
 604.749 +
 604.750 +static const static_codebook _44p0_p5_1 = {
 604.751 +	5, 243,
 604.752 +	(long *)_vq_lengthlist__44p0_p5_1,
 604.753 +	1, -530841600, 1616642048, 2, 0,
 604.754 +	(long *)_vq_quantlist__44p0_p5_1,
 604.755 +	0
 604.756 +};
 604.757 +
 604.758 +static const long _vq_quantlist__44p0_p6_0[] = {
 604.759 +	1,
 604.760 +	0,
 604.761 +	2,
 604.762 +};
 604.763 +
 604.764 +static const long _vq_lengthlist__44p0_p6_0[] = {
 604.765 +	 1, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
 604.766 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9,
 604.767 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.768 +	 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.769 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.770 +	 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.771 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.772 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.773 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.774 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.775 +	 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.776 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.777 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.778 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.779 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 604.780 +	 9, 9, 9,
 604.781 +};
 604.782 +
 604.783 +static const static_codebook _44p0_p6_0 = {
 604.784 +	5, 243,
 604.785 +	(long *)_vq_lengthlist__44p0_p6_0,
 604.786 +	1, -516716544, 1630767104, 2, 0,
 604.787 +	(long *)_vq_quantlist__44p0_p6_0,
 604.788 +	0
 604.789 +};
 604.790 +
 604.791 +static const long _vq_quantlist__44p0_p6_1[] = {
 604.792 +	12,
 604.793 +	11,
 604.794 +	13,
 604.795 +	10,
 604.796 +	14,
 604.797 +	9,
 604.798 +	15,
 604.799 +	8,
 604.800 +	16,
 604.801 +	7,
 604.802 +	17,
 604.803 +	6,
 604.804 +	18,
 604.805 +	5,
 604.806 +	19,
 604.807 +	4,
 604.808 +	20,
 604.809 +	3,
 604.810 +	21,
 604.811 +	2,
 604.812 +	22,
 604.813 +	1,
 604.814 +	23,
 604.815 +	0,
 604.816 +	24,
 604.817 +};
 604.818 +
 604.819 +static const long _vq_lengthlist__44p0_p6_1[] = {
 604.820 +	 1, 3, 2, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,
 604.821 +	11,12,12,12,14,14,14,15,15,
 604.822 +};
 604.823 +
 604.824 +static const static_codebook _44p0_p6_1 = {
 604.825 +	1, 25,
 604.826 +	(long *)_vq_lengthlist__44p0_p6_1,
 604.827 +	1, -518864896, 1620639744, 5, 0,
 604.828 +	(long *)_vq_quantlist__44p0_p6_1,
 604.829 +	0
 604.830 +};
 604.831 +
 604.832 +static const long _vq_quantlist__44p0_p6_2[] = {
 604.833 +	12,
 604.834 +	11,
 604.835 +	13,
 604.836 +	10,
 604.837 +	14,
 604.838 +	9,
 604.839 +	15,
 604.840 +	8,
 604.841 +	16,
 604.842 +	7,
 604.843 +	17,
 604.844 +	6,
 604.845 +	18,
 604.846 +	5,
 604.847 +	19,
 604.848 +	4,
 604.849 +	20,
 604.850 +	3,
 604.851 +	21,
 604.852 +	2,
 604.853 +	22,
 604.854 +	1,
 604.855 +	23,
 604.856 +	0,
 604.857 +	24,
 604.858 +};
 604.859 +
 604.860 +static const long _vq_lengthlist__44p0_p6_2[] = {
 604.861 +	 3, 4, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 604.862 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
 604.863 +};
 604.864 +
 604.865 +static const static_codebook _44p0_p6_2 = {
 604.866 +	1, 25,
 604.867 +	(long *)_vq_lengthlist__44p0_p6_2,
 604.868 +	1, -529006592, 1611661312, 5, 0,
 604.869 +	(long *)_vq_quantlist__44p0_p6_2,
 604.870 +	0
 604.871 +};
 604.872 +
 604.873 +static const long _huff_lengthlist__44p0_short[] = {
 604.874 +	 3, 3, 7, 8,10,13,16, 3, 2, 5, 7, 9,13,16, 6, 4,
 604.875 +	 4, 6,10,14,15, 7, 5, 5, 7,10,13,14, 9, 8, 9, 9,
 604.876 +	 9,11,13,12,11,12, 9, 7, 8,11,14,12,10, 6, 5, 7,
 604.877 +	10,
 604.878 +};
 604.879 +
 604.880 +static const static_codebook _huff_book__44p0_short = {
 604.881 +	2, 49,
 604.882 +	(long *)_huff_lengthlist__44p0_short,
 604.883 +	0, 0, 0, 0, 0,
 604.884 +	NULL,
 604.885 +	0
 604.886 +};
 604.887 +
 604.888 +static const long _vq_quantlist__44p1_l0_0[] = {
 604.889 +	6,
 604.890 +	5,
 604.891 +	7,
 604.892 +	4,
 604.893 +	8,
 604.894 +	3,
 604.895 +	9,
 604.896 +	2,
 604.897 +	10,
 604.898 +	1,
 604.899 +	11,
 604.900 +	0,
 604.901 +	12,
 604.902 +};
 604.903 +
 604.904 +static const long _vq_lengthlist__44p1_l0_0[] = {
 604.905 +	 1, 4, 4, 7, 7, 8, 8, 9, 9,10,10,11,11, 4, 6, 5,
 604.906 +	 8, 6, 9, 8,10, 9,10,10,11,10, 5, 5, 6, 6, 8, 8,
 604.907 +	 9, 9,10,10,10,10,11, 7, 8, 8, 9, 8,10, 9,10, 9,
 604.908 +	11,10,11,10, 7, 8, 8, 8,10, 9,10,10,10,10,11,10,
 604.909 +	11, 9,10,10,11,11,11,11,12,11,12,11,12,11, 9,10,
 604.910 +	10,11,11,11,11,11,11,11,12,11,12,11,11,11,12,12,
 604.911 +	12,12,12,12,12,12,12,11,11,12,11,12,12,12,12,12,
 604.912 +	12,12,12,11,12,12,12,12,12,13,12,13,12,12,12,12,
 604.913 +	12,12,12,12,12,13,13,13,13,12,13,12,12,12,12,12,
 604.914 +	13,13,12,13,12,13,12,13,12,12,12,12,13,13,13,13,
 604.915 +	13,13,12,12,12,12,12,11,12,
 604.916 +};
 604.917 +
 604.918 +static const static_codebook _44p1_l0_0 = {
 604.919 +	2, 169,
 604.920 +	(long *)_vq_lengthlist__44p1_l0_0,
 604.921 +	1, -526516224, 1616117760, 4, 0,
 604.922 +	(long *)_vq_quantlist__44p1_l0_0,
 604.923 +	0
 604.924 +};
 604.925 +
 604.926 +static const long _vq_quantlist__44p1_l0_1[] = {
 604.927 +	2,
 604.928 +	1,
 604.929 +	3,
 604.930 +	0,
 604.931 +	4,
 604.932 +};
 604.933 +
 604.934 +static const long _vq_lengthlist__44p1_l0_1[] = {
 604.935 +	 1, 4, 4, 6, 6, 5, 5, 5, 6, 6, 5, 6, 5, 6, 6, 6,
 604.936 +	 6, 7, 7, 7, 6, 7, 6, 7, 7,
 604.937 +};
 604.938 +
 604.939 +static const static_codebook _44p1_l0_1 = {
 604.940 +	2, 25,
 604.941 +	(long *)_vq_lengthlist__44p1_l0_1,
 604.942 +	1, -533725184, 1611661312, 3, 0,
 604.943 +	(long *)_vq_quantlist__44p1_l0_1,
 604.944 +	0
 604.945 +};
 604.946 +
 604.947 +static const long _vq_quantlist__44p1_l1_0[] = {
 604.948 +	1,
 604.949 +	0,
 604.950 +	2,
 604.951 +};
 604.952 +
 604.953 +static const long _vq_lengthlist__44p1_l1_0[] = {
 604.954 +	 1, 4, 4, 4, 4, 4, 4, 4, 4,
 604.955 +};
 604.956 +
 604.957 +static const static_codebook _44p1_l1_0 = {
 604.958 +	2, 9,
 604.959 +	(long *)_vq_lengthlist__44p1_l1_0,
 604.960 +	1, -516716544, 1630767104, 2, 0,
 604.961 +	(long *)_vq_quantlist__44p1_l1_0,
 604.962 +	0
 604.963 +};
 604.964 +
 604.965 +static const long _huff_lengthlist__44p1_lfe[] = {
 604.966 +	 1, 3, 2, 3,
 604.967 +};
 604.968 +
 604.969 +static const static_codebook _huff_book__44p1_lfe = {
 604.970 +	2, 4,
 604.971 +	(long *)_huff_lengthlist__44p1_lfe,
 604.972 +	0, 0, 0, 0, 0,
 604.973 +	NULL,
 604.974 +	0
 604.975 +};
 604.976 +
 604.977 +static const long _huff_lengthlist__44p1_long[] = {
 604.978 +	 3, 3, 7, 7, 9,13,16, 3, 2, 4, 6,10,13,17, 7, 4,
 604.979 +	 4, 6, 9,12,14, 7, 6, 6, 5, 7, 9,12,10,10, 9, 6,
 604.980 +	 6, 9,12,14,14,13, 9, 8,10,11,18,18,15,13,11,10,
 604.981 +	11,
 604.982 +};
 604.983 +
 604.984 +static const static_codebook _huff_book__44p1_long = {
 604.985 +	2, 49,
 604.986 +	(long *)_huff_lengthlist__44p1_long,
 604.987 +	0, 0, 0, 0, 0,
 604.988 +	NULL,
 604.989 +	0
 604.990 +};
 604.991 +
 604.992 +static const long _vq_quantlist__44p1_p1_0[] = {
 604.993 +	1,
 604.994 +	0,
 604.995 +	2,
 604.996 +};
 604.997 +
 604.998 +static const long _vq_lengthlist__44p1_p1_0[] = {
 604.999 +	 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1000 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1001 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1002 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1003 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1004 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1005 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1006 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1007 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1008 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1009 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1010 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1011 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1012 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1013 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1014 +	 0, 0, 0,
604.1015 +};
604.1016 +
604.1017 +static const static_codebook _44p1_p1_0 = {
604.1018 +	5, 243,
604.1019 +	(long *)_vq_lengthlist__44p1_p1_0,
604.1020 +	1, -535822336, 1611661312, 2, 0,
604.1021 +	(long *)_vq_quantlist__44p1_p1_0,
604.1022 +	0
604.1023 +};
604.1024 +
604.1025 +static const long _vq_quantlist__44p1_p2_0[] = {
604.1026 +	1,
604.1027 +	0,
604.1028 +	2,
604.1029 +};
604.1030 +
604.1031 +static const long _vq_lengthlist__44p1_p2_0[] = {
604.1032 +	 1, 4, 4, 0, 7, 7, 0, 8, 8, 0, 9, 9, 0,12,12, 0,
604.1033 +	 8, 8, 0, 9, 9, 0,12,12, 0, 8, 8, 0, 6, 6, 0,11,
604.1034 +	11, 0,11,11, 0,12,12, 0,14,14, 0,11,11, 0,12,12,
604.1035 +	 0,14,14, 0,11,11, 0, 6, 6, 0, 6, 5, 0, 7, 6, 0,
604.1036 +	 7, 7, 0,10,10, 0, 6, 6, 0, 7, 7, 0,10,10, 0, 7,
604.1037 +	 7, 0, 7, 7, 0,10,10, 0,11,11, 0,11,11, 0,14,14,
604.1038 +	 0,10,10, 0,12,12, 0,14,14, 0,12,12, 0, 6, 6, 0,
604.1039 +	11,11, 0,11,11, 0,12,12, 0,14,14, 0,11,11, 0,12,
604.1040 +	12, 0,15,15, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1041 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1042 +	 0, 0, 0, 8, 8, 0,11,11, 0,11,11, 0,12,12, 0,15,
604.1043 +	15, 0,12,12, 0,11,11, 0,15,15, 0,11,11, 0, 6, 6,
604.1044 +	 0,11,11, 0,12,12, 0,12,12, 0,15,15, 0,11,11, 0,
604.1045 +	12,12, 0,14,14, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,
604.1046 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1047 +	 0, 0, 0,
604.1048 +};
604.1049 +
604.1050 +static const static_codebook _44p1_p2_0 = {
604.1051 +	5, 243,
604.1052 +	(long *)_vq_lengthlist__44p1_p2_0,
604.1053 +	1, -533200896, 1614282752, 2, 0,
604.1054 +	(long *)_vq_quantlist__44p1_p2_0,
604.1055 +	0
604.1056 +};
604.1057 +
604.1058 +static const long _vq_quantlist__44p1_p2_1[] = {
604.1059 +	1,
604.1060 +	0,
604.1061 +	2,
604.1062 +};
604.1063 +
604.1064 +static const long _vq_lengthlist__44p1_p2_1[] = {
604.1065 +	 1, 3, 3, 0, 8, 8, 0, 8, 8, 0,10,10, 0, 9, 9, 0,
604.1066 +	10,10, 0,10,10, 0, 9, 9, 0,10,10, 0, 7, 7, 0, 7,
604.1067 +	 7, 0, 7, 7, 0, 8, 8, 0, 8, 8, 0, 8, 8, 0, 9, 9,
604.1068 +	 0, 8, 8, 0, 8, 8, 0, 7, 7, 0, 8, 8, 0, 8, 8, 0,
604.1069 +	10,10, 0, 9, 9, 0, 9, 9, 0,10,10, 0, 9, 9, 0,10,
604.1070 +	10, 0, 8, 8, 0,11,11, 0,11,11, 0,12,12, 0,11,11,
604.1071 +	 0,12,12, 0,12,12, 0,12,12, 0,12,12, 0, 8, 8, 0,
604.1072 +	11,11, 0,11,11, 0,13,12, 0,12,12, 0,13,12, 0,13,
604.1073 +	13, 0,12,12, 0,13,13, 0, 7, 7, 0, 0, 0, 0, 0, 0,
604.1074 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1075 +	 0, 0, 0, 8, 8, 0,11,11, 0,11,11, 0,13,12, 0,12,
604.1076 +	12, 0,12,12, 0,12,12, 0,11,11, 0,12,12, 0, 8, 8,
604.1077 +	 0,12,12, 0,12,12, 0,13,13, 0,12,12, 0,13,13, 0,
604.1078 +	13,13, 0,12,13, 0,13,13, 0, 7, 7, 0, 0, 0, 0, 0,
604.1079 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1080 +	 0, 0, 0,
604.1081 +};
604.1082 +
604.1083 +static const static_codebook _44p1_p2_1 = {
604.1084 +	5, 243,
604.1085 +	(long *)_vq_lengthlist__44p1_p2_1,
604.1086 +	1, -535822336, 1611661312, 2, 0,
604.1087 +	(long *)_vq_quantlist__44p1_p2_1,
604.1088 +	0
604.1089 +};
604.1090 +
604.1091 +static const long _vq_quantlist__44p1_p3_0[] = {
604.1092 +	1,
604.1093 +	0,
604.1094 +	2,
604.1095 +};
604.1096 +
604.1097 +static const long _vq_lengthlist__44p1_p3_0[] = {
604.1098 +	 1, 6, 6, 6, 7, 7, 7, 8, 8, 7, 8, 8,10,11,11, 9,
604.1099 +	 8, 8, 7, 9, 9,11,12,12, 9, 8, 8, 6, 7, 7, 9,11,
604.1100 +	11,10,11,11,10,11,11,13,13,13,11,12,12,10,11,11,
604.1101 +	13,14,14,12,12,12, 6, 6, 6, 8, 6, 6, 8, 6, 6, 9,
604.1102 +	 7, 7,12,10,10,10, 6, 6, 9, 7, 7,12,10,10,11, 7,
604.1103 +	 6, 7, 8, 8,12,10,10,12,10,10,11,10,10,15,13,13,
604.1104 +	13,10,10,12,11,11,15,13,13,14,11,11, 8, 7, 7,12,
604.1105 +	11,11,12,11,11,11,11,11,14,14,14,13,12,12,12,11,
604.1106 +	11,16,15,15,14,12,12, 0,10,10, 0,11,11, 0,12,12,
604.1107 +	 0,11,11, 0,14,14, 0,11,11, 0,11,11, 0,15,15, 0,
604.1108 +	11,11, 7, 8, 8,13,10,10,12,10,10,12,11,11,15,13,
604.1109 +	13,14,11,11,12,10,10,16,14,14,14,10,10, 8, 7, 7,
604.1110 +	12,11,11,13,11,11,12,11,11,15,14,14,14,12,12,13,
604.1111 +	12,12,15,14,14,15,12,12, 0,11,11, 0,12,12, 0,12,
604.1112 +	12, 0,12,12, 0,15,15, 0,12,12, 0,12,12, 0,15,14,
604.1113 +	 0,12,12,
604.1114 +};
604.1115 +
604.1116 +static const static_codebook _44p1_p3_0 = {
604.1117 +	5, 243,
604.1118 +	(long *)_vq_lengthlist__44p1_p3_0,
604.1119 +	1, -531365888, 1616117760, 2, 0,
604.1120 +	(long *)_vq_quantlist__44p1_p3_0,
604.1121 +	0
604.1122 +};
604.1123 +
604.1124 +static const long _vq_quantlist__44p1_p3_1[] = {
604.1125 +	2,
604.1126 +	1,
604.1127 +	3,
604.1128 +	0,
604.1129 +	4,
604.1130 +};
604.1131 +
604.1132 +static const long _vq_lengthlist__44p1_p3_1[] = {
604.1133 +	 2, 3, 4, 7, 7,10,12,12,12,12,10,11,11,13,13,11,
604.1134 +	12,12,11,11,12,12,12,12,12,11,13,13,13,13,12,12,
604.1135 +	12,13,14,12,13,13,13,13,12,13,13,13,13,12,13,13,
604.1136 +	13,13,11,13,13,13,13,12,12,12,14,14,12,13,13,12,
604.1137 +	12,12,12,13,13,13,12,13,13,13,13,12,13,13,13,13,
604.1138 +	12,12,12,14,14,12,13,13,12,12,12,13,13,13,13,12,
604.1139 +	13,13,12,12,12,13,13,13,13,12,12,12,14,14,12,13,
604.1140 +	13,12,12,12,13,13,13,13,12,13,13,12,12,10,10,11,
604.1141 +	10,10,11,11,11,11,11,11, 9, 9,10,10,12,11,11,10,
604.1142 +	10,12,10,10,10,10,13,12,12,12,12,13,11,11,11,11,
604.1143 +	13,12,12,12,12,13,11,11,11,11,13,12,12,12,12,13,
604.1144 +	12,12,12,12,13,11,11,11,11,13,12,12,12,12,13,11,
604.1145 +	11,11,11,13,12,12,11,11,13,12,12,11,11,13,11,11,
604.1146 +	11,11,13,12,12,11,11,13,11,11,11,11,13,12,12,11,
604.1147 +	11,13,12,12,11,11,13,11,11,11,11,13,12,12,11,11,
604.1148 +	13,11,11,11,11,13,12,12,11,11,11,11,11,10,10,11,
604.1149 +	11,11, 9, 9,11,12,12,11,11,12,12,12, 9, 9,13,13,
604.1150 +	13,10,10,13,13,13,11,11,13,13,13,14,14,13,13,13,
604.1151 +	11,10,13,13,14,12,12,13,13,13,11,11,13,13,13,11,
604.1152 +	11,13,13,13,14,14,13,13,13,10,10,13,13,13,11,11,
604.1153 +	13,13,13,10,10,13,14,13,11,11,13,14,14,14,14,13,
604.1154 +	13,13,10,10,13,14,14,11,11,13,13,13,10,10,13,14,
604.1155 +	14,11,11,13,13,13,14,14,14,13,13,10,10,13,14,14,
604.1156 +	11,11,13,13,13,10,10,14,12,12, 9, 9,14,12,12, 9,
604.1157 +	 9,14,11,11, 9, 9,14,12,12, 8, 8,14,11,11, 7, 7,
604.1158 +	15,13,13,10,10,15,12,12,10,10,15,13,13,10,10,15,
604.1159 +	12,12,10,10,15,13,13,10,10,15,13,13,10,10,15,12,
604.1160 +	12,10,10,15,13,13,10,10,15,12,12,10,10,15,13,13,
604.1161 +	10,10,15,13,13,10,10,15,12,12,10,10,15,13,13, 9,
604.1162 +	 9,15,12,12, 9, 9,14,13,13, 9, 9,15,13,13,10,10,
604.1163 +	15,12,12,10,10,15,13,13, 9, 9,15,12,12, 9, 9,15,
604.1164 +	13,13, 9, 9,13,12,12, 9, 9,13,13,13, 8, 8,13,13,
604.1165 +	13, 9, 9,13,13,13, 7, 7,14,13,13, 8, 8,14,14,14,
604.1166 +	10,10,15,14,14,11,11,14,14,14, 9, 9,15,14,14,10,
604.1167 +	10,15,14,14, 9, 9,14,14,14,10,10,15,14,14,11,11,
604.1168 +	15,14,14, 9, 9,14,14,14,10,10,14,14,14, 9, 9,15,
604.1169 +	14,15,10,10,15,14,14,11,11,14,14,14, 9, 9,14,14,
604.1170 +	14, 9, 9,14,14,14, 8, 8,15,14,14,10,10,15,14,14,
604.1171 +	11,11,14,14,14, 9, 9,15,14,14, 9, 9,14,14,14, 8,
604.1172 +	 8,12,12,12,13,13,16,16,16,11,11,17,16,16,12,12,
604.1173 +	17,16,16,11,11,17,16,16,11,11,17,17,16,13,13,17,
604.1174 +	16,16,13,13,18,17,16,12,12,17,16,16,13,13,17,16,
604.1175 +	17,12,12,18,17,17,13,13,17,16,16,14,14,18,17,17,
604.1176 +	12,12,18,16,16,13,13,17,17,17,13,12,17,17,17,13,
604.1177 +	13,17,16,16,13,13,18,17,17,12,12,17,16,16,13,12,
604.1178 +	17,17,17,12,12,18,17,17,13,13,18,16,16,14,14,18,
604.1179 +	17,17,12,12,17,17,17,13,13,18,17,18,12,12,13,14,
604.1180 +	14,10,10,16,14,14,13,13,17,15,15,14,14,17,14,14,
604.1181 +	12,13,16,14,14,13,13,17,15,15,14,14,16,16,16,15,
604.1182 +	15,17,15,15,14,14,17,16,16,14,15,17,15,15,14,14,
604.1183 +	17,15,16,14,14,17,16,16,15,15,17,15,15,13,13,17,
604.1184 +	15,15,14,14,18,15,15,13,14,17,15,15,14,14,16,16,
604.1185 +	16,15,15,17,15,15,13,13,17,15,15,14,14,17,15,15,
604.1186 +	13,13,17,15,15,14,14,16,16,16,15,15,17,15,15,13,
604.1187 +	13,17,15,15,14,14,18,15,15,13,13,13,11,11,10,10,
604.1188 +	16,14,14,13,12,16,14,14,13,13,16,15,14,12,12,16,
604.1189 +	14,14,12,12,16,15,15,14,14,16,14,14,14,14,17,15,
604.1190 +	15,13,13,16,15,15,14,14,17,15,15,13,14,17,15,15,
604.1191 +	14,14,17,15,14,14,14,17,15,15,13,13,17,15,15,14,
604.1192 +	14,17,15,15,13,13,17,15,15,14,14,17,14,14,14,14,
604.1193 +	17,15,15,13,13,17,15,15,13,13,17,15,15,13,13,17,
604.1194 +	15,15,14,14,17,15,15,14,14,17,15,15,13,13,17,15,
604.1195 +	15,13,13,17,15,15,13,13,14,14,15, 8, 8,14,14,14,
604.1196 +	19,19,14,15,15,18,19,14,14,14,19,18,14,14,14,19,
604.1197 +	19,15,15,15,19,18,15,16,16,19,19,15,15,15,19,19,
604.1198 +	15,16,16,20,19,15,15,15,19,19,15,15,15,19,19,16,
604.1199 +	16,16,20,19,15,15,15,19,18,15,16,16,20,19,15,15,
604.1200 +	15,18,18,15,15,15,19,20,15,16,16,19,19,15,15,15,
604.1201 +	20,19,15,15,15,20,19,15,15,15,19,18,15,15,15,19,
604.1202 +	19,15,16,16,19,20,15,15,15,19,19,15,15,15,19,20,
604.1203 +	15,15,15,19,19,14,12,12, 9, 9,14,14,14,19,19,14,
604.1204 +	14,14,19,19,14,14,15,20,19,15,14,14,18,19,15,15,
604.1205 +	15,19,19,15,15,14,20,19,15,15,15,20,19,15,15,14,
604.1206 +	20,19,15,15,15,20,19,15,15,15,19,20,15,14,14,19,
604.1207 +	20,15,15,15,20,20,15,14,14,20,19,15,15,15,19,19,
604.1208 +	15,15,15,19,19,15,14,14,19,19,15,15,15,19,20,15,
604.1209 +	15,15,20,20,15,15,15,19,19,15,15,15,20,19,16,14,
604.1210 +	14,19,19,15,15,15,20,19,15,14,15,20,19,14,15,15,
604.1211 +	20,19,12,12,12,13,13,16,16,16,11,11,16,16,16,12,
604.1212 +	12,17,16,16,11,11,17,15,16,11,11,17,17,17,13,13,
604.1213 +	18,16,17,13,13,18,17,17,13,12,17,16,17,13,13,17,
604.1214 +	17,17,13,13,16,16,16,12,12,17,16,16,13,13,17,16,
604.1215 +	16,12,12,17,16,16,12,13,17,17,17,12,12,17,17,17,
604.1216 +	13,13,18,16,16,13,13,18,17,17,12,12,18,17,17,12,
604.1217 +	12,17,17,17,12,12,17,17,17,12,12,17,16,16,13,13,
604.1218 +	17,17,17,12,12,17,16,16,12,12,17,17,17,12,12,13,
604.1219 +	14,14, 9, 9,16,14,14,13,13,16,15,15,14,14,17,14,
604.1220 +	14,13,13,16,14,14,13,13,17,15,15,15,15,16,16,16,
604.1221 +	15,15,17,15,15,14,14,17,15,15,15,15,17,15,15,14,
604.1222 +	14,17,15,15,14,14,16,16,16,15,15,17,15,15,14,14,
604.1223 +	17,15,15,14,14,17,15,15,14,14,17,15,15,14,14,16,
604.1224 +	16,16,15,15,18,15,15,14,13,17,15,15,14,14,17,15,
604.1225 +	15,13,13,17,15,15,14,14,16,16,16,15,15,17,15,15,
604.1226 +	14,13,17,15,15,14,14,17,15,15,13,13,13,11,11,11,
604.1227 +	11,16,14,14,12,12,16,14,14,13,13,16,15,14,12,12,
604.1228 +	17,14,14,12,12,17,15,15,13,13,17,14,14,14,14,17,
604.1229 +	15,15,13,13,17,14,15,14,13,17,15,15,13,13,16,15,
604.1230 +	15,13,13,16,14,14,14,14,17,15,15,13,13,16,14,14,
604.1231 +	13,13,16,15,15,13,13,17,15,15,13,13,17,14,14,14,
604.1232 +	14,17,15,15,12,12,17,15,15,13,13,17,15,15,12,12,
604.1233 +	16,15,15,13,13,17,14,14,13,14,17,15,15,12,12,17,
604.1234 +	14,14,13,13,17,15,15,12,12,14,14,14, 8, 8,14,14,
604.1235 +	14,18,18,14,15,15,19,19,14,14,14,19,19,14,15,14,
604.1236 +	18,19,15,15,15,18,19,15,16,16,20,20,15,15,15,19,
604.1237 +	20,15,16,16,19,20,15,15,15,19,20,15,15,16,19,19,
604.1238 +	15,16,16,20,20,15,15,15,20,19,15,16,16,20,19,15,
604.1239 +	15,15,19,20,15,15,15,19,19,15,16,16,20,19,15,15,
604.1240 +	15,19,19,15,16,15,20,19,15,15,15,19,19,15,15,15,
604.1241 +	19,20,15,16,16,20,20,15,15,15,19,19,15,15,15,20,
604.1242 +	20,15,15,15,19,19,14,12,12, 9, 9,14,14,14,18,18,
604.1243 +	14,14,14,19,20,14,14,14,18,18,14,14,14,18,19,15,
604.1244 +	15,15,19,20,15,14,14,19,19,15,15,15,19,19,15,14,
604.1245 +	15,19,19,15,15,15,18,20,15,15,15,19,19,15,14,14,
604.1246 +	19,19,15,15,15,20,19,15,15,14,20,20,15,15,15,19,
604.1247 +	19,15,15,15,19,19,15,14,14,19,19,15,15,15,19,19,
604.1248 +	15,14,14,19,20,14,15,15,19,19,15,15,15,19,19,15,
604.1249 +	14,14,20,19,15,15,15,19,19,15,14,14,20,19,15,15,
604.1250 +	15,19,19,13,12,12,13,13,17,17,16,11,11,16,16,16,
604.1251 +	12,12,17,17,16,11,11,17,16,16,11,11,17,17,17,13,
604.1252 +	13,17,16,16,13,13,18,17,17,12,12,17,16,16,13,13,
604.1253 +	18,17,17,12,12,18,17,17,13,13,18,16,17,13,13,17,
604.1254 +	17,17,12,12,18,17,17,13,13,18,17,17,12,12,17,16,
604.1255 +	17,12,12,17,16,16,13,13,17,16,16,11,11,17,16,16,
604.1256 +	12,12,17,17,17,11,11,17,17,17,12,12,18,16,16,13,
604.1257 +	13,18,17,17,12,11,17,16,16,12,12,18,17,17,11,11,
604.1258 +	13,14,14, 9, 9,16,14,14,13,13,16,15,15,14,14,17,
604.1259 +	14,14,12,12,16,14,14,13,13,17,15,15,14,14,17,16,
604.1260 +	16,15,16,18,15,15,14,14,17,15,15,14,14,17,15,15,
604.1261 +	14,14,18,15,15,14,14,16,16,16,15,16,18,15,15,14,
604.1262 +	14,17,16,15,14,14,18,15,15,14,14,17,15,15,14,14,
604.1263 +	17,16,16,15,15,18,14,15,13,13,17,15,15,14,14,18,
604.1264 +	15,15,13,13,17,15,15,14,14,17,16,15,15,15,17,15,
604.1265 +	15,13,13,17,15,15,14,14,18,15,15,13,13,13,11,11,
604.1266 +	10,10,16,14,14,12,12,16,14,14,12,12,17,14,15,11,
604.1267 +	11,17,14,14,11,11,17,15,15,13,13,17,14,14,14,13,
604.1268 +	17,15,15,13,13,16,15,15,13,13,17,15,15,13,13,17,
604.1269 +	15,15,13,13,17,14,14,14,14,17,15,15,13,13,17,14,
604.1270 +	15,13,13,16,15,15,13,13,17,15,15,13,13,17,14,14,
604.1271 +	13,13,17,15,15,12,12,16,14,14,12,12,17,15,15,12,
604.1272 +	12,17,15,15,13,13,17,14,14,13,13,17,15,15,12,12,
604.1273 +	17,14,14,12,12,17,15,15,12,12,13,15,14, 8, 8,14,
604.1274 +	14,14,19,19,14,15,15,18,19,14,14,14,18,19,14,15,
604.1275 +	14,19,19,15,16,15,19,19,15,16,16,19,20,15,15,15,
604.1276 +	19,19,15,16,16,19,19,15,16,16,19,19,15,15,15,19,
604.1277 +	19,15,16,16,20,20,15,15,15,19,19,15,15,15,19,19,
604.1278 +	15,15,15,19,19,15,15,15,19,19,15,16,16,20,19,15,
604.1279 +	15,15,19,19,15,15,15,19,19,15,15,15,19,19,15,16,
604.1280 +	15,19,19,15,16,16,21,19,15,15,15,20,20,15,15,15,
604.1281 +	20,21,15,15,15,19,20,14,12,12, 8, 8,14,14,14,19,
604.1282 +	19,14,13,13,19,19,14,14,14,19,19,14,13,14,19,19,
604.1283 +	15,15,15,20,20,15,14,14,20,19,15,15,15,19,20,15,
604.1284 +	14,14,19,20,15,15,15,20,19,15,15,15,19,20,15,14,
604.1285 +	14,20,20,15,15,15,20,19,15,14,14,19,19,15,15,15,
604.1286 +	19,19,15,15,15,20,19,15,14,14,21,19,15,15,15,20,
604.1287 +	21,15,14,14,21,19,15,15,15,19,19,15,15,15,20,20,
604.1288 +	15,14,14,19,21,15,15,15,19,19,15,14,14,19,20,15,
604.1289 +	15,15,19,19,13,12,12,13,13,17,16,16,11,11,17,16,
604.1290 +	15,12,12,18,16,16,11,11,17,16,16,11,11,18,17,17,
604.1291 +	13,13,18,16,16,13,13,17,17,17,12,13,18,17,16,13,
604.1292 +	13,18,17,17,13,13,17,17,17,13,13,17,16,16,13,13,
604.1293 +	18,16,17,12,12,17,16,16,13,12,17,17,17,12,12,18,
604.1294 +	17,17,13,12,18,16,16,13,13,18,17,17,12,12,17,16,
604.1295 +	16,12,12,17,17,17,11,11,17,16,16,12,12,17,16,16,
604.1296 +	13,13,17,16,16,11,11,17,16,16,12,12,17,17,17,11,
604.1297 +	11,13,14,14, 9, 9,16,14,14,13,13,16,15,15,14,14,
604.1298 +	17,14,14,12,12,16,14,14,13,13,17,15,15,14,14,17,
604.1299 +	15,16,15,15,17,15,15,14,14,17,15,16,14,15,18,15,
604.1300 +	15,14,14,17,15,15,14,14,16,16,16,15,15,18,15,15,
604.1301 +	13,14,17,15,15,14,14,18,15,15,14,14,17,15,15,14,
604.1302 +	14,17,16,16,15,15,17,15,15,13,13,17,15,15,14,14,
604.1303 +	18,15,15,13,13,17,15,15,14,14,17,16,16,15,15,17,
604.1304 +	15,15,13,13,17,15,15,14,14,18,15,15,13,13,13,11,
604.1305 +	11,10,10,16,14,14,12,12,16,14,14,13,13,17,14,14,
604.1306 +	11,11,17,14,14,12,12,17,15,15,14,14,17,14,14,14,
604.1307 +	14,17,15,15,13,13,17,15,14,13,13,16,15,15,13,13,
604.1308 +	16,15,15,13,13,17,14,14,14,14,17,15,15,13,13,17,
604.1309 +	14,14,13,13,16,15,15,13,13,16,15,15,13,13,17,14,
604.1310 +	14,13,13,17,15,15,12,12,17,14,14,12,12,16,15,15,
604.1311 +	12,12,17,15,15,13,13,17,14,14,13,13,17,15,15,12,
604.1312 +	12,17,14,14,12,12,16,15,15,12,12,14,14,14, 8, 8,
604.1313 +	14,14,14,18,18,14,15,15,19,18,14,14,14,18,18,14,
604.1314 +	14,14,18,19,15,16,15,19,19,15,17,16,20,20,15,15,
604.1315 +	15,19,19,15,16,16,19,19,15,15,15,19,19,15,16,15,
604.1316 +	18,19,15,16,16,20,20,15,15,15,19,19,15,16,16,19,
604.1317 +	20,15,15,15,19,19,15,15,16,19,19,15,16,16,20,20,
604.1318 +	15,15,15,19,19,15,15,15,19,20,15,15,15,19,19,15,
604.1319 +	15,15,19,19,15,16,16,20,20,15,15,15,19,20,15,16,
604.1320 +	16,20,20,15,15,15,19,19,13,12,12, 8, 8,14,14,14,
604.1321 +	19,20,14,14,14,19,19,14,14,14,18,19,14,14,14,19,
604.1322 +	20,15,15,15,19,20,15,14,14,21,20,15,15,15,20,20,
604.1323 +	15,15,14,19,19,15,15,15,19,19,15,15,15,19,19,15,
604.1324 +	14,14,19,20,15,15,15,19,20,15,14,14,19,19,15,15,
604.1325 +	15,19,19,15,15,15,19,19,16,14,14,19,19,15,15,15,
604.1326 +	20,20,15,14,14,21,19,15,15,15,19,19,15,15,15,19,
604.1327 +	20,16,14,14,19,20,15,15,15,19,19,15,14,14,19,19,
604.1328 +	15,15,15,20,19,
604.1329 +};
604.1330 +
604.1331 +static const static_codebook _44p1_p3_1 = {
604.1332 +	5, 3125,
604.1333 +	(long *)_vq_lengthlist__44p1_p3_1,
604.1334 +	1, -533725184, 1611661312, 3, 0,
604.1335 +	(long *)_vq_quantlist__44p1_p3_1,
604.1336 +	0
604.1337 +};
604.1338 +
604.1339 +static const long _vq_quantlist__44p1_p4_0[] = {
604.1340 +	2,
604.1341 +	1,
604.1342 +	3,
604.1343 +	0,
604.1344 +	4,
604.1345 +};
604.1346 +
604.1347 +static const long _vq_lengthlist__44p1_p4_0[] = {
604.1348 +	 2, 6, 6,14,14, 6, 7, 7,14,14, 7, 7, 7,14,14, 0,
604.1349 +	13,13,16,16, 0,13,13,15,14, 7, 8, 8,15,15, 9,10,
604.1350 +	10,16,16, 9, 8, 8,15,15, 0,13,13,17,16, 0,13,13,
604.1351 +	15,16, 8, 8, 8,15,15,12,11,11,16,16, 9, 8, 8,14,
604.1352 +	14, 0,13,13,17,18, 0,13,13,15,15, 0,14,14,16,16,
604.1353 +	 0, 0, 0,19,18, 0,12,12,16,15, 0,15,16, 0,20, 0,
604.1354 +	14,14,16,16, 0,14,14,17,17, 0, 0, 0,19,18, 0,12,
604.1355 +	12,15,15, 0,17,17, 0,20, 0,14,14,16,16, 5, 6, 7,
604.1356 +	12,12, 9, 9, 9,14,14,10,10,10,14,14, 0,21,21,18,
604.1357 +	17, 0,20,20,18,17, 9,10,10,14,14,12,12,12,16,16,
604.1358 +	12,10,10,14,14, 0,20,19,18,17, 0, 0,20,17,18,11,
604.1359 +	10,10,14,14,14,13,13,18,18,13,11,11,14,14, 0,20,
604.1360 +	20,17,18, 0,21,21,17,17, 0,21, 0,18,18, 0, 0, 0,
604.1361 +	 0, 0, 0,20,19,16,17, 0, 0, 0,19,19, 0, 0, 0,18,
604.1362 +	18, 0,21,21,18,18, 0, 0, 0, 0, 0, 0,20,20,16,17,
604.1363 +	 0, 0, 0,21,21, 0, 0, 0,18,19, 6, 6, 6,13,12, 8,
604.1364 +	 6, 6,11,11, 8, 6, 6,13,13, 0, 9, 9,11,11, 0,11,
604.1365 +	10,14,14, 9, 7, 7,13,13,11, 9, 9,13,13,10, 6, 6,
604.1366 +	13,13, 0,10,10,14,15, 0,10,10,13,13, 9, 7, 7,13,
604.1367 +	13,13,10, 9,13,13,10, 6, 6,13,13, 0,10,10,15,14,
604.1368 +	 0,10,10,13,13, 0,11,11,15,15, 0,19,20,17,17, 0,
604.1369 +	 9, 9,13,13, 0,13,13,20,20, 0,11,11,13,13, 0,11,
604.1370 +	11,15,15, 0,19,19,17,17, 0,10,10,13,13, 0,15,15,
604.1371 +	20,20, 0,12,12,13,13, 0,10,10,12,12, 0,11,11,15,
604.1372 +	15, 0,11,11,15,15, 0,15,15,20, 0, 0,16,16, 0,21,
604.1373 +	 0,11,11,15,15, 0,14,14,18,17, 0,11,11,15,15, 0,
604.1374 +	15,16,19,20, 0,16,16,21,21, 0,12,12,15,15, 0,15,
604.1375 +	14,18,18, 0,11,11,16,16, 0,15,15,21,21, 0,16,15,
604.1376 +	 0, 0, 0,16,16,21, 0, 0, 0, 0, 0, 0, 0,14,14,20,
604.1377 +	20, 0,18,18, 0, 0, 0,16,17,21, 0, 0,16,16,21,21,
604.1378 +	 0, 0, 0, 0, 0, 0,15,15,21,21, 0,20,19, 0,21, 0,
604.1379 +	17,17, 0, 0, 0,10,10,12,11, 0,10,10,10,11, 0,11,
604.1380 +	11,12,12, 0,11,11, 9, 9, 0,13,13,11,12, 0,11,11,
604.1381 +	12,12, 0,13,13,12,12, 0,10,10,12,12, 0,12,12,13,
604.1382 +	13, 0,12,12,12,12, 0,11,11,12,12, 0,13,13,12,12,
604.1383 +	 0,10,10,12,12, 0,13,13,14,14, 0,12,12,12,12, 0,
604.1384 +	14,14,14,13, 0,19,20,15,15, 0,12,11,12,12, 0,15,
604.1385 +	15,21,20, 0,13,13,11,11, 0,13,13,13,13, 0,19, 0,
604.1386 +	15,15, 0,12,12,12,12, 0,17,16,19, 0, 0,13,13,12,
604.1387 +	12, 7, 7, 7,16,16,11, 9, 9,15,15,12, 9, 9,16,16,
604.1388 +	 0,13,13,15,14, 0,14,14,17,16,10, 9, 9,16,16,14,
604.1389 +	11,11,17,16,12, 9, 8,15,15, 0,13,13,18,18, 0,13,
604.1390 +	13,15,15,12,10,10,18,17,15,12,12,17,17,14, 9, 9,
604.1391 +	16,16, 0,13,13,18,19, 0,14,13,17,16, 0,14,14,18,
604.1392 +	18, 0, 0, 0,20,21, 0,12,12,16,16, 0,16,16,20,21,
604.1393 +	 0,14,14,17,16, 0,14,14,18,19, 0, 0, 0,19,21, 0,
604.1394 +	13,13,17,17, 0,17,17, 0,21, 0,15,15,16,16, 8, 7,
604.1395 +	 7,14,14,11,10,10,15,15,12,10,10,15,15, 0,20,20,
604.1396 +	18,18, 0, 0, 0,17,17,11,10,10,16,16,14,12,12,18,
604.1397 +	17,14,11,11,15,15, 0,20,21,18,18, 0, 0,19,18,17,
604.1398 +	12,10,10,16,16,17,14,14,19,19,14,11,11,15,15, 0,
604.1399 +	21,21,19,19, 0,21,20,19,18, 0,21, 0,18,19, 0, 0,
604.1400 +	 0, 0, 0, 0,20,20,18,17, 0,21, 0, 0, 0, 0, 0, 0,
604.1401 +	19,18, 0, 0, 0,18,19, 0, 0, 0, 0, 0, 0, 0,21,17,
604.1402 +	18, 0, 0, 0, 0,21, 0, 0,21,18,19,11, 9, 9,14,14,
604.1403 +	13,10,10,13,13,13,11,11,15,15, 0,13,13,12,12, 0,
604.1404 +	15,15,16,16,13,10,10,15,15,16,12,12,15,15,15,10,
604.1405 +	10,15,15, 0,14,13,16,15, 0,14,13,15,15,13,10,10,
604.1406 +	15,15,18,14,14,15,15,15,10,10,14,15, 0,14,14,16,
604.1407 +	16, 0,14,14,16,15, 0,15,15,17,16, 0,21, 0,18,18,
604.1408 +	 0,12,13,15,15, 0,16,16, 0, 0, 0,14,14,15,15, 0,
604.1409 +	15,15,16,16, 0,21,20,18,18, 0,13,13,15,15, 0,19,
604.1410 +	18, 0, 0, 0,15,15,15,15, 0,11,11,13,13, 0,12,12,
604.1411 +	16,16, 0,12,12,16,16, 0,15,16,20, 0, 0,16,17, 0,
604.1412 +	 0, 0,12,12,16,16, 0,14,14,18,18, 0,11,11,16,17,
604.1413 +	 0,15,15,20, 0, 0,16,16, 0, 0, 0,12,12,16,16, 0,
604.1414 +	15,15,19,19, 0,11,11,17,17, 0,16,16,21, 0, 0,16,
604.1415 +	16, 0, 0, 0,17,17,20,20, 0, 0, 0, 0, 0, 0,15,15,
604.1416 +	20, 0, 0,17,18, 0, 0, 0,17,17, 0, 0, 0,16,16, 0,
604.1417 +	21, 0, 0, 0, 0, 0, 0,15,15,21, 0, 0,19,18, 0, 0,
604.1418 +	 0,18,17, 0, 0, 0,11,11,14,14, 0,11,11,15,15, 0,
604.1419 +	12,12,16,16, 0,13,13,14,14, 0,14,14,17,17, 0,12,
604.1420 +	12,16,16, 0,14,14,16,16, 0,11,11,16,15, 0,13,13,
604.1421 +	16,17, 0,13,13,16,16, 0,12,12,15,16, 0,15,14,16,
604.1422 +	16, 0,11,11,15,15, 0,14,14,17,17, 0,13,13,16,16,
604.1423 +	 0,15,14,18,18, 0,21, 0,19,19, 0,13,13,15,15, 0,
604.1424 +	16,16,20,20, 0,14,14,16,15, 0,14,14,17,17, 0,21,
604.1425 +	 0,20,18, 0,13,13,15,15, 0,17,17, 0, 0, 0,14,14,
604.1426 +	16,15, 8, 8, 8,16,16,12, 9, 9,16,16,13, 9, 9,16,
604.1427 +	16, 0,14,14,18,17, 0,14,14,16,17,12,10,10,18,17,
604.1428 +	14,11,11,18,18,14, 9, 9,16,16, 0,13,13,18,18, 0,
604.1429 +	13,13,17,16,12, 9, 9,16,17,17,13,13,16,16,14, 9,
604.1430 +	 9,15,15, 0,14,14,20,20, 0,13,13,15,15, 0,15,14,
604.1431 +	18,18, 0, 0, 0,20,21, 0,12,13,16,17, 0,16,16,20,
604.1432 +	21, 0,14,14,16,17, 0,14,14,18,17, 0, 0, 0,20,21,
604.1433 +	 0,13,13,16,16, 0,19,17, 0,21, 0,14,15,16,16, 8,
604.1434 +	 7, 7,14,13,12,10,10,15,15,13,10,10,15,15, 0,21,
604.1435 +	21,18,19, 0,20,21,18,18,12,10,10,16,15,15,12,12,
604.1436 +	17,17,14,11,11,15,15, 0,21,21,19,18, 0, 0,21,17,
604.1437 +	18,13,11,11,15,15,16,13,13,18,19,15,11,11,15,14,
604.1438 +	 0,21, 0,19,19, 0, 0,21,18,18, 0, 0,21,19,19, 0,
604.1439 +	 0, 0, 0, 0, 0,20,19,17,17, 0, 0, 0,21, 0, 0,21,
604.1440 +	 0,18,19, 0, 0,20,20,19, 0, 0, 0, 0, 0, 0,21,20,
604.1441 +	18,17, 0, 0, 0, 0,20, 0, 0, 0,18,19, 0,10,10,15,
604.1442 +	14, 0,11,11,14,14, 0,11,11,15,16, 0,14,14,15,15,
604.1443 +	 0,15,15,16,16, 0,11,11,16,16, 0,14,13,16,16, 0,
604.1444 +	11,11,15,15, 0,14,14,16,16, 0,14,14,15,15, 0,11,
604.1445 +	11,15,15, 0,13,13,15,15, 0,11,11,15,15, 0,15,15,
604.1446 +	18,17, 0,14,14,15,15, 0,15,16,18,18, 0, 0, 0,20,
604.1447 +	20, 0,14,13,16,15, 0,17,17,21, 0, 0,15,15,15,15,
604.1448 +	 0,16,15,17,17, 0, 0, 0,19,19, 0,13,13,15,15, 0,
604.1449 +	20,19, 0, 0, 0,15,15,15,15, 0,11,11,13,13, 0,12,
604.1450 +	12,16,16, 0,12,12,16,16, 0,15,15,21,21, 0,17,16,
604.1451 +	 0, 0, 0,12,12,16,16, 0,14,14,17,17, 0,11,11,16,
604.1452 +	16, 0,15,15, 0, 0, 0,16,16,21, 0, 0,12,12,17,16,
604.1453 +	 0,14,15,20,20, 0,11,11,16,16, 0,15,15, 0,20, 0,
604.1454 +	16,16, 0,21, 0,16,17,21, 0, 0, 0, 0, 0, 0, 0,15,
604.1455 +	15, 0,21, 0,18,18, 0, 0, 0,17,16, 0, 0, 0,17,17,
604.1456 +	21, 0, 0, 0, 0, 0, 0, 0,15,15, 0,20, 0,19,20,21,
604.1457 +	 0, 0,17,18, 0, 0, 0,12,12,15,15, 0,12,12,15,15,
604.1458 +	 0,12,12,16,16, 0,13,13,15,15, 0,15,15,17,17, 0,
604.1459 +	13,12,17,16, 0,14,14,17,16, 0,11,11,16,16, 0,14,
604.1460 +	14,17,17, 0,14,14,17,17, 0,12,12,16,16, 0,15,15,
604.1461 +	17,17, 0,11,11,16,16, 0,14,14,17,17, 0,14,14,16,
604.1462 +	16, 0,15,15,18,17, 0, 0, 0,19, 0, 0,13,13,16,16,
604.1463 +	 0,16,16, 0,21, 0,14,14,16,16, 0,15,15,18,17, 0,
604.1464 +	 0, 0,19,19, 0,13,13,16,16, 0,18,17, 0,21, 0,14,
604.1465 +	15,16,16, 0,11,11,16,16, 0,13,13,17,17, 0,13,13,
604.1466 +	17,17, 0,16,16,16,17, 0,16,16,18,18, 0,12,12,17,
604.1467 +	17, 0,16,15,18,17, 0,12,12,16,16, 0,16,15,19,19,
604.1468 +	 0,16,15,17,17, 0,12,12,17,18, 0,16,16,18,18, 0,
604.1469 +	12,12,16,16, 0,16,16,19,19, 0,15,16,17,17, 0,15,
604.1470 +	16,18,18, 0, 0, 0,20,20, 0,13,13,16,16, 0,18,18,
604.1471 +	21,20, 0,15,15,16,16, 0,16,16,19,18, 0, 0, 0,19,
604.1472 +	20, 0,14,14,17,17, 0,19,19, 0,21, 0,15,16,16,16,
604.1473 +	 0, 9, 9,14,14, 0,13,13,15,15, 0,14,14,15,15, 0,
604.1474 +	 0,21,19,19, 0, 0,21,18,18, 0,12,12,15,15, 0,15,
604.1475 +	15,18,18, 0,14,13,15,15, 0,21,21,18,19, 0,21,20,
604.1476 +	18,18, 0,13,13,16,16, 0,17,17,18,19, 0,14,14,15,
604.1477 +	15, 0, 0,21,19,19, 0,21,20,18,19, 0,20,20,19,19,
604.1478 +	 0, 0, 0, 0, 0, 0,19,20,17,17, 0, 0, 0,21,21, 0,
604.1479 +	21, 0,18,20, 0,21, 0,18,21, 0, 0, 0, 0, 0, 0,21,
604.1480 +	21,19,18, 0, 0, 0, 0, 0, 0, 0, 0,19,19, 0,18,18,
604.1481 +	15,15, 0,18,20,17,16, 0,20, 0,17,17, 0,21, 0,17,
604.1482 +	17, 0,21,20,19,20, 0,19,19,16,16, 0,21,21,17,18,
604.1483 +	 0,19,19,17,17, 0,20,21,21,21, 0,20,20,18,18, 0,
604.1484 +	19,19,16,16, 0, 0,21,18,19, 0,18,19,16,17, 0,21,
604.1485 +	21,19,20, 0,21,19,18,18, 0,21,20,19,21, 0, 0, 0,
604.1486 +	20,21, 0,19,19,17,16, 0, 0, 0, 0, 0, 0,21,20,17,
604.1487 +	17, 0,20,21,19,18, 0, 0, 0, 0,21, 0,19,18,16,17,
604.1488 +	 0, 0, 0, 0, 0, 0,20,20,17,17, 0,11,11,14,14, 0,
604.1489 +	13,13,16,16, 0,13,13,16,16, 0,17,17,21, 0, 0,17,
604.1490 +	18, 0, 0, 0,12,12,16,16, 0,15,15,17,18, 0,12,12,
604.1491 +	16,16, 0,16,16, 0,20, 0,17,17, 0,21, 0,12,12,17,
604.1492 +	17, 0,16,16,19,20, 0,12,12,17,17, 0,17,17, 0,20,
604.1493 +	 0,17,17, 0, 0, 0,17,17,21, 0, 0, 0, 0, 0, 0, 0,
604.1494 +	15,15, 0,20, 0,19,19, 0, 0, 0,18,18, 0, 0, 0,17,
604.1495 +	17, 0, 0, 0, 0, 0, 0, 0, 0,15,15, 0, 0, 0,20,19,
604.1496 +	 0, 0, 0,19,18, 0, 0, 0,14,14,21,19, 0,16,16,20,
604.1497 +	21, 0,16,16,20,20, 0,17,17,20, 0, 0,17,17,20,20,
604.1498 +	 0,15,15,20,20, 0,19,18,20, 0, 0,15,15,20,20, 0,
604.1499 +	17,18,21,20, 0,17,17,20,21, 0,15,15,19,19, 0,19,
604.1500 +	18,21,21, 0,15,15,19,20, 0,17,18, 0, 0, 0,17,17,
604.1501 +	20,20, 0,17,18,20,21, 0, 0, 0, 0, 0, 0,15,15,20,
604.1502 +	20, 0,19,19, 0, 0, 0,17,17,19,21, 0,17,17, 0,21,
604.1503 +	 0, 0, 0, 0,21, 0,15,15,20,19, 0, 0,20, 0, 0, 0,
604.1504 +	17,17,21,20, 0,12,12,16,16, 0,14,14,17,17, 0,13,
604.1505 +	13,17,17, 0,16,16,17,18, 0,17,16,18,18, 0,13,13,
604.1506 +	18,17, 0,15,16,19,18, 0,13,13,16,16, 0,16,16,19,
604.1507 +	19, 0,16,16,17,17, 0,13,12,17,17, 0,16,16,18,17,
604.1508 +	 0,12,12,16,16, 0,17,17,19,18, 0,16,15,16,16, 0,
604.1509 +	16,17,18,19, 0, 0, 0,20,20, 0,14,14,17,16, 0,18,
604.1510 +	18,21, 0, 0,16,16,16,16, 0,16,16,18,17, 0, 0,21,
604.1511 +	21,21, 0,14,14,16,16, 0,21,20,21, 0, 0,16,16,16,
604.1512 +	16, 0,10,10,14,14, 0,14,14,15,16, 0,14,14,15,15,
604.1513 +	 0, 0,21,18,18, 0, 0,21,18,19, 0,13,13,16,16, 0,
604.1514 +	16,16,18,17, 0,14,14,15,15, 0,20, 0,18,18, 0,21,
604.1515 +	 0,18,17, 0,13,13,16,15, 0,17,17,19,19, 0,14,14,
604.1516 +	15,15, 0,20,20,18,19, 0, 0, 0,18,17, 0, 0,21,18,
604.1517 +	18, 0, 0, 0, 0, 0, 0,20,21,18,17, 0, 0, 0, 0, 0,
604.1518 +	 0, 0, 0,19,19, 0, 0,21,18,18, 0, 0, 0, 0, 0, 0,
604.1519 +	21, 0,18,17, 0, 0, 0, 0,21, 0, 0, 0,19,20, 0,19,
604.1520 +	19,16,16, 0, 0,21,18,17, 0,21, 0,18,18, 0,20, 0,
604.1521 +	19,18, 0,21,20,19,19, 0,21,19,17,18, 0, 0,21,19,
604.1522 +	19, 0,21,19,18,18, 0,21, 0,20,18, 0, 0,21,18,18,
604.1523 +	 0,20,21,17,17, 0,21, 0,18,18, 0,21,19,17,17, 0,
604.1524 +	21, 0, 0,20, 0, 0,20,17,18, 0, 0, 0,19,20, 0, 0,
604.1525 +	 0,20,19, 0,19,21,17,18, 0,21, 0, 0, 0, 0,21,21,
604.1526 +	18,17, 0, 0,21,18,18, 0, 0, 0, 0,21, 0,20,19,16,
604.1527 +	17, 0, 0, 0, 0, 0, 0,21,20,17,17, 0,11,11,13,13,
604.1528 +	 0,13,13,16,16, 0,13,13,16,16, 0,17,17, 0,21, 0,
604.1529 +	18,19,21, 0, 0,12,12,16,16, 0,15,15,19,18, 0,13,
604.1530 +	13,16,16, 0,16,17,21,19, 0,17,17,21,21, 0,13,13,
604.1531 +	16,16, 0,16,16,20,18, 0,13,13,16,16, 0,17,17, 0,
604.1532 +	 0, 0,18,18, 0, 0, 0,18,17, 0,20, 0, 0, 0, 0, 0,
604.1533 +	 0,15,15,21,21, 0,19,18, 0, 0, 0,17,17,21,21, 0,
604.1534 +	17,17, 0, 0, 0, 0, 0, 0, 0, 0,15,15,20,21, 0,20,
604.1535 +	20, 0, 0, 0,19,19, 0, 0, 0,14,15,21,19, 0,16,16,
604.1536 +	 0,21, 0,17,16,21,21, 0,17,18,21,20, 0,18,18, 0,
604.1537 +	21, 0,16,16, 0,20, 0,19,19, 0, 0, 0,16,15, 0,20,
604.1538 +	 0,18,18, 0, 0, 0,17,17, 0,21, 0,16,16,20,20, 0,
604.1539 +	20,19, 0, 0, 0,15,16,21,22, 0,18,18, 0, 0, 0,18,
604.1540 +	17, 0, 0, 0,18,18, 0, 0, 0, 0, 0, 0, 0, 0,16,16,
604.1541 +	21,20, 0,19,20, 0, 0, 0,18,17,21, 0, 0,17,18, 0,
604.1542 +	 0, 0, 0, 0, 0, 0, 0,16,16, 0,20, 0, 0,20, 0, 0,
604.1543 +	 0,18,18,22, 0,
604.1544 +};
604.1545 +
604.1546 +static const static_codebook _44p1_p4_0 = {
604.1547 +	5, 3125,
604.1548 +	(long *)_vq_lengthlist__44p1_p4_0,
604.1549 +	1, -528744448, 1616642048, 3, 0,
604.1550 +	(long *)_vq_quantlist__44p1_p4_0,
604.1551 +	0
604.1552 +};
604.1553 +
604.1554 +static const long _vq_quantlist__44p1_p4_1[] = {
604.1555 +	3,
604.1556 +	2,
604.1557 +	4,
604.1558 +	1,
604.1559 +	5,
604.1560 +	0,
604.1561 +	6,
604.1562 +};
604.1563 +
604.1564 +static const long _vq_lengthlist__44p1_p4_1[] = {
604.1565 +	 2, 3, 3, 3, 3, 3, 3,
604.1566 +};
604.1567 +
604.1568 +static const static_codebook _44p1_p4_1 = {
604.1569 +	1, 7,
604.1570 +	(long *)_vq_lengthlist__44p1_p4_1,
604.1571 +	1, -533200896, 1611661312, 3, 0,
604.1572 +	(long *)_vq_quantlist__44p1_p4_1,
604.1573 +	0
604.1574 +};
604.1575 +
604.1576 +static const long _vq_quantlist__44p1_p5_0[] = {
604.1577 +	1,
604.1578 +	0,
604.1579 +	2,
604.1580 +};
604.1581 +
604.1582 +static const long _vq_lengthlist__44p1_p5_0[] = {
604.1583 +	 1, 6, 6, 7, 8, 8, 7, 8, 8, 7, 9, 8,10,11,11, 9,
604.1584 +	 8, 8, 7, 8, 8,11,11,11, 9, 8, 8, 6, 7, 7,10,10,
604.1585 +	10,10,10,10,10,10,10,14,13,13,12,11,11,10,10,10,
604.1586 +	14,14,13,12,11,11, 6, 6, 6, 8, 5, 5, 8, 7, 7, 9,
604.1587 +	 7, 7,11,10,10, 9, 7, 7, 9, 7, 7,12,10,10,10, 7,
604.1588 +	 7, 7, 8, 8,12,11,10,12,10,10,11,10,10,15,13,13,
604.1589 +	13,10,10,11,10,10,17,14,13,13,10,10, 7, 7, 7,12,
604.1590 +	11,12,12,11,11,12,11,11,16,14,14,13,12,12,12,11,
604.1591 +	11,17,15,14,14,12,12,10, 9, 9,13,11,11,13,11,11,
604.1592 +	13,11,11,17,14,13,14,11,11,12,11,11,16,15,14,14,
604.1593 +	11,11, 7, 8, 8,12,11,11,12,10,10,12,10,10,15,13,
604.1594 +	13,14,11,10,12,10,10,16,14,14,14,10,10, 8, 7, 7,
604.1595 +	12,11,11,12,11,11,12,11,11,17,14,14,14,12,12,12,
604.1596 +	11,11,16,15,15,14,12,12,10,10,10,13,11,11,13,11,
604.1597 +	11,13,11,12,16,14,14,14,11,11,13,12,11,16,15,15,
604.1598 +	14,11,11,
604.1599 +};
604.1600 +
604.1601 +static const static_codebook _44p1_p5_0 = {
604.1602 +	5, 243,
604.1603 +	(long *)_vq_lengthlist__44p1_p5_0,
604.1604 +	1, -527106048, 1620377600, 2, 0,
604.1605 +	(long *)_vq_quantlist__44p1_p5_0,
604.1606 +	0
604.1607 +};
604.1608 +
604.1609 +static const long _vq_quantlist__44p1_p5_1[] = {
604.1610 +	1,
604.1611 +	0,
604.1612 +	2,
604.1613 +};
604.1614 +
604.1615 +static const long _vq_lengthlist__44p1_p5_1[] = {
604.1616 +	 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 8, 8, 8,
604.1617 +	 7, 7, 8, 8, 8, 9, 8, 8, 9, 7, 7, 6, 6, 6, 9, 8,
604.1618 +	 7, 9, 7, 7, 9, 8, 8,10, 8, 8,10, 8, 8,10, 8, 8,
604.1619 +	10, 8, 8,10, 8, 8, 7, 6, 6, 9, 6, 6, 9, 7, 7, 9,
604.1620 +	 7, 7,10, 8, 8, 9, 6, 6, 9, 7, 7,10, 8, 8, 9, 7,
604.1621 +	 7, 7, 8, 8,11, 9, 9,11, 9, 9,11, 8, 9,12, 9, 9,
604.1622 +	12, 8, 8,11, 9, 9,12, 9, 9,12, 8, 8, 8, 7, 7,10,
604.1623 +	 9, 9,10,10, 9,10, 9, 9,11,10,10,11, 9, 9,11, 9,
604.1624 +	 9,11,10,11,11, 9, 9,10, 8, 8,11, 9, 9,10, 9, 9,
604.1625 +	11, 9, 9,11,10,10,11, 9, 9,11, 9, 9,11,10,10,11,
604.1626 +	 9, 9, 9, 8, 8,11, 9, 9,12, 9, 9,11, 9, 9,12, 9,
604.1627 +	 9,12, 8, 8,12, 9, 9,12, 9, 9,12, 8, 8, 9, 7, 7,
604.1628 +	11, 9, 9,11,10,10,11, 9, 9,11,11,11,11, 9, 9,11,
604.1629 +	10,10,11,11,11,11, 9, 9,10, 9, 9,11, 9, 9,11,10,
604.1630 +	10,11, 9, 9,11,10,10,11, 9, 9,11, 9,10,11,10,10,
604.1631 +	11, 9, 9,
604.1632 +};
604.1633 +
604.1634 +static const static_codebook _44p1_p5_1 = {
604.1635 +	5, 243,
604.1636 +	(long *)_vq_lengthlist__44p1_p5_1,
604.1637 +	1, -530841600, 1616642048, 2, 0,
604.1638 +	(long *)_vq_quantlist__44p1_p5_1,
604.1639 +	0
604.1640 +};
604.1641 +
604.1642 +static const long _vq_quantlist__44p1_p6_0[] = {
604.1643 +	1,
604.1644 +	0,
604.1645 +	2,
604.1646 +};
604.1647 +
604.1648 +static const long _vq_lengthlist__44p1_p6_0[] = {
604.1649 +	 1, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
604.1650 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9,
604.1651 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1652 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1653 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1654 +	 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1655 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1656 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1657 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1658 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1659 +	 9, 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1660 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1661 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1662 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1663 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.1664 +	 9, 9, 9,
604.1665 +};
604.1666 +
604.1667 +static const static_codebook _44p1_p6_0 = {
604.1668 +	5, 243,
604.1669 +	(long *)_vq_lengthlist__44p1_p6_0,
604.1670 +	1, -516716544, 1630767104, 2, 0,
604.1671 +	(long *)_vq_quantlist__44p1_p6_0,
604.1672 +	0
604.1673 +};
604.1674 +
604.1675 +static const long _vq_quantlist__44p1_p6_1[] = {
604.1676 +	12,
604.1677 +	11,
604.1678 +	13,
604.1679 +	10,
604.1680 +	14,
604.1681 +	9,
604.1682 +	15,
604.1683 +	8,
604.1684 +	16,
604.1685 +	7,
604.1686 +	17,
604.1687 +	6,
604.1688 +	18,
604.1689 +	5,
604.1690 +	19,
604.1691 +	4,
604.1692 +	20,
604.1693 +	3,
604.1694 +	21,
604.1695 +	2,
604.1696 +	22,
604.1697 +	1,
604.1698 +	23,
604.1699 +	0,
604.1700 +	24,
604.1701 +};
604.1702 +
604.1703 +static const long _vq_lengthlist__44p1_p6_1[] = {
604.1704 +	 1, 3, 2, 5, 4, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
604.1705 +	12,13,13,13,14,16,16,16,16,
604.1706 +};
604.1707 +
604.1708 +static const static_codebook _44p1_p6_1 = {
604.1709 +	1, 25,
604.1710 +	(long *)_vq_lengthlist__44p1_p6_1,
604.1711 +	1, -518864896, 1620639744, 5, 0,
604.1712 +	(long *)_vq_quantlist__44p1_p6_1,
604.1713 +	0
604.1714 +};
604.1715 +
604.1716 +static const long _vq_quantlist__44p1_p6_2[] = {
604.1717 +	12,
604.1718 +	11,
604.1719 +	13,
604.1720 +	10,
604.1721 +	14,
604.1722 +	9,
604.1723 +	15,
604.1724 +	8,
604.1725 +	16,
604.1726 +	7,
604.1727 +	17,
604.1728 +	6,
604.1729 +	18,
604.1730 +	5,
604.1731 +	19,
604.1732 +	4,
604.1733 +	20,
604.1734 +	3,
604.1735 +	21,
604.1736 +	2,
604.1737 +	22,
604.1738 +	1,
604.1739 +	23,
604.1740 +	0,
604.1741 +	24,
604.1742 +};
604.1743 +
604.1744 +static const long _vq_lengthlist__44p1_p6_2[] = {
604.1745 +	 3, 4, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.1746 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.1747 +};
604.1748 +
604.1749 +static const static_codebook _44p1_p6_2 = {
604.1750 +	1, 25,
604.1751 +	(long *)_vq_lengthlist__44p1_p6_2,
604.1752 +	1, -529006592, 1611661312, 5, 0,
604.1753 +	(long *)_vq_quantlist__44p1_p6_2,
604.1754 +	0
604.1755 +};
604.1756 +
604.1757 +static const long _huff_lengthlist__44p1_short[] = {
604.1758 +	 4, 5, 7, 8,10,13,14, 4, 2, 4, 6, 8,11,12, 7, 4,
604.1759 +	 3, 5, 8,12,14, 8, 5, 4, 4, 8,12,12, 9, 7, 7, 7,
604.1760 +	 9,10,11,13,11,11, 9, 7, 8,10,13,11,10, 6, 5, 7,
604.1761 +	 9,
604.1762 +};
604.1763 +
604.1764 +static const static_codebook _huff_book__44p1_short = {
604.1765 +	2, 49,
604.1766 +	(long *)_huff_lengthlist__44p1_short,
604.1767 +	0, 0, 0, 0, 0,
604.1768 +	NULL,
604.1769 +	0
604.1770 +};
604.1771 +
604.1772 +static const long _vq_quantlist__44p2_l0_0[] = {
604.1773 +	6,
604.1774 +	5,
604.1775 +	7,
604.1776 +	4,
604.1777 +	8,
604.1778 +	3,
604.1779 +	9,
604.1780 +	2,
604.1781 +	10,
604.1782 +	1,
604.1783 +	11,
604.1784 +	0,
604.1785 +	12,
604.1786 +};
604.1787 +
604.1788 +static const long _vq_lengthlist__44p2_l0_0[] = {
604.1789 +	 1, 4, 4, 7, 7, 8, 8, 9, 9,10,10,11,11, 4, 6, 5,
604.1790 +	 8, 7, 9, 8,10, 9,11,10,11,11, 4, 5, 6, 7, 8, 8,
604.1791 +	 9, 9,10,10,10,10,11, 8, 9, 8,10, 8,10, 9,11,10,
604.1792 +	11,11,11,11, 8, 8, 9, 8,10, 9,10,10,11,11,11,11,
604.1793 +	11, 9,10,10,11,11,11,11,11,11,12,11,12,11, 9,10,
604.1794 +	10,10,11,11,11,11,11,11,12,11,12,10,11,11,12,11,
604.1795 +	12,12,12,12,12,12,12,12,10,11,11,11,11,12,12,12,
604.1796 +	13,12,12,12,12,11,12,12,12,12,13,13,12,12,12,12,
604.1797 +	12,12,11,12,12,12,12,13,13,12,13,12,12,12,12,12,
604.1798 +	13,13,13,13,13,13,12,13,12,13,12,12,12,13,13,13,
604.1799 +	13,13,13,13,12,13,12,12,12,
604.1800 +};
604.1801 +
604.1802 +static const static_codebook _44p2_l0_0 = {
604.1803 +	2, 169,
604.1804 +	(long *)_vq_lengthlist__44p2_l0_0,
604.1805 +	1, -526516224, 1616117760, 4, 0,
604.1806 +	(long *)_vq_quantlist__44p2_l0_0,
604.1807 +	0
604.1808 +};
604.1809 +
604.1810 +static const long _vq_quantlist__44p2_l0_1[] = {
604.1811 +	2,
604.1812 +	1,
604.1813 +	3,
604.1814 +	0,
604.1815 +	4,
604.1816 +};
604.1817 +
604.1818 +static const long _vq_lengthlist__44p2_l0_1[] = {
604.1819 +	 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5,
604.1820 +	 5, 6, 6, 6, 5, 6, 5, 6, 6,
604.1821 +};
604.1822 +
604.1823 +static const static_codebook _44p2_l0_1 = {
604.1824 +	2, 25,
604.1825 +	(long *)_vq_lengthlist__44p2_l0_1,
604.1826 +	1, -533725184, 1611661312, 3, 0,
604.1827 +	(long *)_vq_quantlist__44p2_l0_1,
604.1828 +	0
604.1829 +};
604.1830 +
604.1831 +static const long _vq_quantlist__44p2_l1_0[] = {
604.1832 +	1,
604.1833 +	0,
604.1834 +	2,
604.1835 +};
604.1836 +
604.1837 +static const long _vq_lengthlist__44p2_l1_0[] = {
604.1838 +	 1, 4, 4, 4, 4, 4, 4, 4, 4,
604.1839 +};
604.1840 +
604.1841 +static const static_codebook _44p2_l1_0 = {
604.1842 +	2, 9,
604.1843 +	(long *)_vq_lengthlist__44p2_l1_0,
604.1844 +	1, -516716544, 1630767104, 2, 0,
604.1845 +	(long *)_vq_quantlist__44p2_l1_0,
604.1846 +	0
604.1847 +};
604.1848 +
604.1849 +static const long _huff_lengthlist__44p2_lfe[] = {
604.1850 +	 1, 3, 2, 3,
604.1851 +};
604.1852 +
604.1853 +static const static_codebook _huff_book__44p2_lfe = {
604.1854 +	2, 4,
604.1855 +	(long *)_huff_lengthlist__44p2_lfe,
604.1856 +	0, 0, 0, 0, 0,
604.1857 +	NULL,
604.1858 +	0
604.1859 +};
604.1860 +
604.1861 +static const long _huff_lengthlist__44p2_long[] = {
604.1862 +	 3, 4, 9, 8, 8,10,13,16, 4, 2, 9, 5, 7,10,14,18,
604.1863 +	 9, 7, 6, 5, 7, 9,12,16, 7, 5, 5, 3, 5, 8,11,13,
604.1864 +	 8, 7, 7, 5, 5, 7, 9,11,10,10, 9, 8, 6, 6, 8,10,
604.1865 +	13,14,13,11, 9, 8, 9,10,17,18,16,14,11,10,10,10,
604.1866 +};
604.1867 +
604.1868 +static const static_codebook _huff_book__44p2_long = {
604.1869 +	2, 64,
604.1870 +	(long *)_huff_lengthlist__44p2_long,
604.1871 +	0, 0, 0, 0, 0,
604.1872 +	NULL,
604.1873 +	0
604.1874 +};
604.1875 +
604.1876 +static const long _vq_quantlist__44p2_p1_0[] = {
604.1877 +	1,
604.1878 +	0,
604.1879 +	2,
604.1880 +};
604.1881 +
604.1882 +static const long _vq_lengthlist__44p2_p1_0[] = {
604.1883 +	 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1884 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1885 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1886 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1887 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1888 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1889 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1890 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1891 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1892 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1893 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1894 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1895 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1896 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1897 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1898 +	 0, 0, 0,
604.1899 +};
604.1900 +
604.1901 +static const static_codebook _44p2_p1_0 = {
604.1902 +	5, 243,
604.1903 +	(long *)_vq_lengthlist__44p2_p1_0,
604.1904 +	1, -535822336, 1611661312, 2, 0,
604.1905 +	(long *)_vq_quantlist__44p2_p1_0,
604.1906 +	0
604.1907 +};
604.1908 +
604.1909 +static const long _vq_quantlist__44p2_p2_0[] = {
604.1910 +	2,
604.1911 +	1,
604.1912 +	3,
604.1913 +	0,
604.1914 +	4,
604.1915 +};
604.1916 +
604.1917 +static const long _vq_lengthlist__44p2_p2_0[] = {
604.1918 +	 1, 4, 4, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0,
604.1919 +	10,10, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0, 0,
604.1920 +	 0, 0, 0, 0, 9, 9, 0, 0, 0,11,11, 0, 0, 0, 0, 0,
604.1921 +	 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0,
604.1922 +	 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0,11,11, 0, 0,
604.1923 +	 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0,11,11, 0, 0, 0,
604.1924 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1925 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
604.1926 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1927 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1928 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1929 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1930 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1931 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1932 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1933 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0,
604.1934 +	 6, 6, 0, 0, 0, 7, 7, 0, 0, 0, 8, 8, 0, 0, 0, 0,
604.1935 +	 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
604.1936 +	 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0,
604.1937 +	 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0,
604.1938 +	 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0,
604.1939 +	 8, 8, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1940 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1941 +	 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0,
604.1942 +	 0, 0,10,10, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0,
604.1943 +	 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,
604.1944 +	11,11, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0, 0,
604.1945 +	 0, 0, 0, 0, 9, 9, 0, 0, 0,11,10, 0, 0, 0, 0, 0,
604.1946 +	 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0,
604.1947 +	 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1948 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1949 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1950 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1951 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1952 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1953 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1954 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1955 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1956 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1957 +	 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0, 0,11,11, 0, 0,
604.1958 +	 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,11,11, 0, 0, 0,
604.1959 +	 0, 0, 0, 0, 0,10,10, 0, 0, 0,13,13, 0, 0, 0, 0,
604.1960 +	 0, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0,12,12,
604.1961 +	 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0,13,13, 0,
604.1962 +	 0, 0, 0, 0, 0, 0, 0,12,12, 0, 0, 0,13,13, 0, 0,
604.1963 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1964 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
604.1965 +	 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1966 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1967 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1968 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1969 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1970 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1971 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1972 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1973 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1974 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1975 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1976 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1977 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1978 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1979 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1980 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,11,11,
604.1981 +	 0, 0, 0,12,12, 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0,
604.1982 +	 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0,12,11, 0, 0,
604.1983 +	 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,13,13, 0, 0, 0,
604.1984 +	 0, 0, 0, 0, 0,12,12, 0, 0, 0,13,13, 0, 0, 0, 0,
604.1985 +	 0, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0,12,12,
604.1986 +	 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1987 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1988 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1989 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1990 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1991 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1992 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1993 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1994 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1995 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.1996 +	 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0, 0,11,11, 0,
604.1997 +	 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,13,13, 0, 0,
604.1998 +	 0, 0, 0, 0, 0, 0,12,12, 0, 0, 0,13,13, 0, 0, 0,
604.1999 +	 0, 0, 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0,10,
604.2000 +	10, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0,14,13,
604.2001 +	 0, 0, 0, 0, 0, 0, 0, 0,13,12, 0, 0, 0,13,13, 0,
604.2002 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2003 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2004 +	 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2005 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2006 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2007 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2008 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2009 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2010 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2011 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2012 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2013 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2014 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2015 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2016 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2017 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2018 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2019 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,11,
604.2020 +	11, 0, 0, 0,12,12, 0, 0, 0,12,12, 0, 0, 0, 0, 0,
604.2021 +	 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,12,12, 0,
604.2022 +	 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0,13,13, 0, 0,
604.2023 +	 0, 0, 0, 0, 0, 0,12,12, 0, 0, 0,12,12, 0, 0, 0,
604.2024 +	 0, 0, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0,12,
604.2025 +	12, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2026 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2027 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2028 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2029 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2030 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2031 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2032 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2033 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2034 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2035 +	 0, 0, 0, 0, 9, 9, 0, 0, 0,11,11, 0, 0, 0,12,12,
604.2036 +	 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,12,12, 0,
604.2037 +	 0, 0, 0, 0, 0, 0, 0,11,11, 0, 0, 0,14,14, 0, 0,
604.2038 +	 0, 0, 0, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0,
604.2039 +	12,12, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0,12,
604.2040 +	12, 0, 0, 0, 0, 0, 0, 0, 0,11,11, 0, 0, 0,14,13,
604.2041 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2042 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2043 +	 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2044 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2045 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2046 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2047 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2048 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2049 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2050 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2051 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2052 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2053 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2054 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2055 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2056 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2057 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2058 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,
604.2059 +	11,11, 0, 0, 0,12,12, 0, 0, 0,13,13, 0, 0, 0, 0,
604.2060 +	 0, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0,12,12,
604.2061 +	 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0,12,12, 0,
604.2062 +	 0, 0, 0, 0, 0, 0, 0,12,12, 0, 0, 0,14,14, 0, 0,
604.2063 +	 0, 0, 0, 0, 0, 0,14,14, 0, 0, 0, 0, 0, 0, 0, 0,
604.2064 +	12,12, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2065 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2066 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2067 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2068 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2069 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2070 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2071 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2072 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2073 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2074 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2075 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2076 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2077 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2078 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2079 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2080 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2081 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2082 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2083 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2084 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2085 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2086 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2087 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2088 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2089 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2090 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2091 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2092 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2093 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2094 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2095 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2096 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2097 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2098 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2099 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2100 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2101 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2102 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2103 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2104 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2105 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2106 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2107 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2108 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2109 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2110 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2111 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2112 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2113 +	 0, 0, 0, 0, 0,
604.2114 +};
604.2115 +
604.2116 +static const static_codebook _44p2_p2_0 = {
604.2117 +	5, 3125,
604.2118 +	(long *)_vq_lengthlist__44p2_p2_0,
604.2119 +	1, -533725184, 1611661312, 3, 0,
604.2120 +	(long *)_vq_quantlist__44p2_p2_0,
604.2121 +	0
604.2122 +};
604.2123 +
604.2124 +static const long _vq_quantlist__44p2_p3_0[] = {
604.2125 +	1,
604.2126 +	0,
604.2127 +	2,
604.2128 +};
604.2129 +
604.2130 +static const long _vq_lengthlist__44p2_p3_0[] = {
604.2131 +	 1, 5, 5, 6, 7, 7, 0, 8, 8, 6, 9, 9, 8,11,11, 0,
604.2132 +	 8, 8, 0, 9, 9, 0,12,12, 0, 8, 8, 5, 7, 7, 7,10,
604.2133 +	10, 0,12,12, 8,11,11, 9,12,12, 0,11,12, 0,12,12,
604.2134 +	 0,15,15, 0,12,12, 0, 6, 6, 0, 6, 6, 0, 7, 7, 0,
604.2135 +	 7, 7, 0,10,10, 0, 7, 7, 0, 8, 8, 0,11,11, 0, 7,
604.2136 +	 7, 6, 7, 7,10, 9, 9, 0,11,10,10, 9, 9,12,12,12,
604.2137 +	 0,10,10, 0,11,11, 0,13,13, 0,11,11, 7, 6, 6,10,
604.2138 +	10,10, 0,11,11,11,11,11,12,12,12, 0,11,11, 0,12,
604.2139 +	12, 0,15,15, 0,11,11, 0,11,11, 0,11,11, 0,12,12,
604.2140 +	 0,12,12, 0,14,14, 0,12,12, 0,12,12, 0,15,15, 0,
604.2141 +	11,11, 0, 8, 8, 0,10,10, 0,11,11, 0,11,11, 0,12,
604.2142 +	12, 0,12,12, 0,11,11, 0,15,15, 0,11,11, 0, 6, 6,
604.2143 +	 0,10,10, 0,12,12, 0,10,10, 0,13,13, 0,12,12, 0,
604.2144 +	13,13, 0,14,14, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,
604.2145 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.2146 +	 0, 0, 0,
604.2147 +};
604.2148 +
604.2149 +static const static_codebook _44p2_p3_0 = {
604.2150 +	5, 243,
604.2151 +	(long *)_vq_lengthlist__44p2_p3_0,
604.2152 +	1, -533200896, 1614282752, 2, 0,
604.2153 +	(long *)_vq_quantlist__44p2_p3_0,
604.2154 +	0
604.2155 +};
604.2156 +
604.2157 +static const long _vq_quantlist__44p2_p3_1[] = {
604.2158 +	1,
604.2159 +	0,
604.2160 +	2,
604.2161 +};
604.2162 +
604.2163 +static const long _vq_lengthlist__44p2_p3_1[] = {
604.2164 +	 2, 3, 3, 0, 8, 8, 0, 8, 8, 0, 9, 9, 0, 9, 9, 0,
604.2165 +	 9, 9, 0, 9, 9, 0, 9, 9, 0, 8, 8, 0, 6, 6, 0, 7,
604.2166 +	 7, 0, 7, 7, 0, 8, 8, 0, 8, 8, 0, 8, 8, 0, 8, 8,
604.2167 +	 0, 8, 8, 0, 8, 8, 0, 6, 6, 0, 6, 6, 0, 6, 6, 0,
604.2168 +	 8, 8, 0, 9, 9, 0, 7, 7, 0, 8, 8, 0, 9, 9, 0, 6,
604.2169 +	 6, 0, 8, 8, 0, 9, 9, 0, 9, 9, 0,10,10, 0,10,10,
604.2170 +	 0,10,10, 0,10,10, 0,11,11, 0, 9, 9, 0, 7, 7, 0,
604.2171 +	10,10, 0,10,10, 0,12,11, 0,12,12, 0,11,11, 0,11,
604.2172 +	11, 0,12,12, 0,10,10, 0, 7, 7, 0,10,10, 0,10,10,
604.2173 +	 0,12,12, 0,11,12, 0,11,11, 0,11,11, 0,11,11, 0,
604.2174 +	10,10, 0, 8, 8, 0, 9, 9, 0, 9, 9, 0,10,10, 0,10,
604.2175 +	10, 0,10, 9, 0,10,10, 0,10,10, 0, 9, 9, 0, 6, 6,
604.2176 +	 0,10,10, 0,10,10, 0,11,11, 0,12,12, 0,11,11, 0,
604.2177 +	11,11, 0,12,12, 0,11,11, 0, 7, 7, 0, 9, 9, 0, 9,
604.2178 +	 9, 0,11,11, 0,11,11, 0,10,10, 0,10,10, 0,11,11,
604.2179 +	 0, 9, 9,
604.2180 +};
604.2181 +
604.2182 +static const static_codebook _44p2_p3_1 = {
604.2183 +	5, 243,
604.2184 +	(long *)_vq_lengthlist__44p2_p3_1,
604.2185 +	1, -535822336, 1611661312, 2, 0,
604.2186 +	(long *)_vq_quantlist__44p2_p3_1,
604.2187 +	0
604.2188 +};
604.2189 +
604.2190 +static const long _vq_quantlist__44p2_p4_0[] = {
604.2191 +	1,
604.2192 +	0,
604.2193 +	2,
604.2194 +};
604.2195 +
604.2196 +static const long _vq_lengthlist__44p2_p4_0[] = {
604.2197 +	 1, 6, 6, 6, 7, 7, 7, 8, 8, 7, 8, 8,10,11,11, 9,
604.2198 +	 8, 8, 7, 8, 8,11,11,11, 9, 8, 8, 6, 7, 7, 9,11,
604.2199 +	11, 9,11,11,10,11,11,12,13,13,11,12,12,10,11,11,
604.2200 +	13,14,14,12,12,12, 6, 6, 6, 8, 6, 6, 8, 7, 7, 9,
604.2201 +	 7, 7,11,10,10,10, 6, 6, 9, 7, 7,12,10,10,11, 6,
604.2202 +	 7, 7, 7, 7,11,10,10,12,10,10,11,10,10,14,13,13,
604.2203 +	13,10,10,12,11,11,15,13,13,14,10,10, 8, 7, 7,12,
604.2204 +	11,11,12,11,11,11,11,11,14,14,14,13,12,12,12,11,
604.2205 +	11,15,15,15,13,12,12, 0,10,10, 0,11,11, 0,11,11,
604.2206 +	 0,11,11, 0,14,14, 0,11,11, 0,11,11, 0,15,15, 0,
604.2207 +	11,11, 7, 8, 8,12,10,10,12,10,10,12,11,11,15,13,
604.2208 +	13,14,11,11,12,10,10,16,14,14,14,10,10, 8, 7, 7,
604.2209 +	12,11,11,12,11,11,12,11,11,16,14,14,14,12,12,13,
604.2210 +	12,12,15,14,14,15,12,12, 0,11,11, 0,12,12, 0,12,
604.2211 +	12, 0,12,12, 0,15,15, 0,12,12, 0,12,12, 0,14,14,
604.2212 +	 0,12,12,
604.2213 +};
604.2214 +
604.2215 +static const static_codebook _44p2_p4_0 = {
604.2216 +	5, 243,
604.2217 +	(long *)_vq_lengthlist__44p2_p4_0,
604.2218 +	1, -531365888, 1616117760, 2, 0,
604.2219 +	(long *)_vq_quantlist__44p2_p4_0,
604.2220 +	0
604.2221 +};
604.2222 +
604.2223 +static const long _vq_quantlist__44p2_p4_1[] = {
604.2224 +	2,
604.2225 +	1,
604.2226 +	3,
604.2227 +	0,
604.2228 +	4,
604.2229 +};
604.2230 +
604.2231 +static const long _vq_lengthlist__44p2_p4_1[] = {
604.2232 +	 3, 4, 4, 8, 8,11, 9, 9,12,12,11,10,10,12,12,12,
604.2233 +	10,10,11,11,12,12,12,12,12,12,11,11,13,13,12,12,
604.2234 +	12,13,13,12,10,10,12,12,12,11,11,13,13,12,13,13,
604.2235 +	13,13,12,11,11,13,13,12,12,12,13,13,12,10,10,12,
604.2236 +	12,12,11,11,13,13,12,13,13,12,12,12,11,11,13,13,
604.2237 +	12,13,13,13,13,12,11,11,12,12,12,11,11,12,12,12,
604.2238 +	13,13,12,12,12,13,13,13,13,12,13,13,13,13,13,13,
604.2239 +	13,12,12,12,13,13,13,13,12,13,13,12,12,11, 8, 8,
604.2240 +	10,10,12,11,11,11,11,12,10,10,10,10,13,11,11,10,
604.2241 +	10,13,11,11,10,10,13,12,12,12,12,13,11,11,11,11,
604.2242 +	13,12,12,11,11,13,12,12,11,11,13,12,12,12,11,13,
604.2243 +	12,12,12,12,13,11,11,11,11,13,12,12,11,11,13,11,
604.2244 +	12,11,11,13,12,12,11,11,14,12,12,11,11,13,11,11,
604.2245 +	11,11,14,12,12,11,11,13,11,12,10,10,14,12,12,11,
604.2246 +	11,14,12,12,11,11,14,11,11,11,11,14,12,12,11,11,
604.2247 +	13,12,12,11,11,14,12,12,11,11,11, 8, 8,10,10,12,
604.2248 +	 7, 7,10,10,12, 9, 9,11,11,13, 9, 9, 9, 9,13,13,
604.2249 +	13,10,10,13, 9, 9,12,12,13,13,13,12,12,13, 9, 8,
604.2250 +	11,11,13,10,10,12,12,14,13,13,11,11,13, 9, 9,11,
604.2251 +	11,13,13,13,12,12,13, 9, 9,10,10,13,10,10,11,11,
604.2252 +	13,13,13,10,10,14,10,10,11,11,14,14,14,12,12,13,
604.2253 +	 9, 9,10,10,13,10,10,11,11,14,13,14,10,10,14,14,
604.2254 +	14,11,12,14,14,14,14,14,14,13,13,10,10,13,14,14,
604.2255 +	11,11,14,14,14,10,10,14, 9, 9, 9, 9,14, 9, 9, 9,
604.2256 +	 9,14,10,10, 9, 9,14,10,10, 8, 8,14,11,11, 8, 8,
604.2257 +	15,11,11,10,10,15,12,12,10,10,15,10,10,10,10,15,
604.2258 +	11,11,10,10,15,13,13,10,10,15,11,11,10,10,15,12,
604.2259 +	12,10,10,15,10,10,10,10,15,11,11,10,10,15,13,13,
604.2260 +	10,10,15,11,11,10,10,15,12,12,10,10,15,11,11, 9,
604.2261 +	 9,15,11,11, 9, 9,15,13,13, 9, 9,15,13,13,10,10,
604.2262 +	15,12,12,10,10,15,13,13,10,10,15,13,12, 9, 9,15,
604.2263 +	13,13, 9, 9,14,12,12, 9, 9,14,13,13, 9, 9,14,13,
604.2264 +	13, 9, 9,14,13,13, 7, 7,14,13,13, 8, 8,15,14,14,
604.2265 +	10,10,15,14,14,10,10,15,14,14,10,10,15,14,14,10,
604.2266 +	10,15,14,14, 9, 9,15,14,14,10,10,15,14,14,10,10,
604.2267 +	14,14,14, 9, 9,15,14,14,10,10,14,14,14, 9, 9,15,
604.2268 +	14,14,10,10,15,14,14,10,10,14,14,14, 9, 9,14,14,
604.2269 +	14, 9, 9,14,14,14, 8, 8,15,14,14,10,10,15,14,14,
604.2270 +	11,11,15,14,14, 9, 9,15,14,14, 9, 9,14,14,14, 8,
604.2271 +	 8,13, 9, 9,12,12,17,11,11,12,12,17,12,12,12,12,
604.2272 +	17,12,12,11,11,18,15,15,12,12,17,12,12,12,12,17,
604.2273 +	14,15,13,13,17,12,12,12,12,17,13,13,12,13,17,15,
604.2274 +	15,12,12,18,13,13,13,13,18,15,15,13,13,18,12,12,
604.2275 +	12,12,18,13,13,13,13,18,15,15,12,12,18,13,13,12,
604.2276 +	12,18,15,15,13,13,18,13,13,12,12,17,13,13,12,12,
604.2277 +	17,15,15,12,12,18,15,15,13,13,18,15,15,13,14,18,
604.2278 +	15,16,12,12,18,15,15,12,12,18,16,16,12,12,13, 8,
604.2279 +	 8,10,10,14,15,14,11,11,14,15,15,12,12,15,14,14,
604.2280 +	12,11,15,15,15,12,12,15,15,15,12,12,15,15,15,13,
604.2281 +	13,15,15,15,12,12,15,15,15,13,13,15,15,15,13,13,
604.2282 +	15,15,15,13,13,15,15,16,13,13,15,15,15,12,12,15,
604.2283 +	15,15,13,13,15,15,15,13,13,15,15,15,13,13,15,15,
604.2284 +	15,13,13,15,15,14,12,12,15,15,15,12,12,16,15,14,
604.2285 +	12,12,16,15,15,13,13,16,16,16,13,13,16,15,15,12,
604.2286 +	12,15,15,15,13,13,15,15,15,12,12,13,12,12,10,10,
604.2287 +	14,14,14,11,11,15,14,14,12,12,15,14,14,11,11,15,
604.2288 +	14,14,11,11,15,15,15,13,13,15,14,14,13,13,15,15,
604.2289 +	15,12,12,15,14,15,13,13,16,15,15,12,12,15,15,15,
604.2290 +	13,13,16,14,14,13,13,15,15,15,12,12,15,15,15,13,
604.2291 +	13,16,15,15,12,12,16,15,15,12,12,16,14,14,13,13,
604.2292 +	15,15,15,11,11,15,15,15,12,12,16,15,15,11,11,16,
604.2293 +	15,15,13,13,16,14,15,14,14,16,15,15,12,12,16,15,
604.2294 +	14,12,12,16,15,15,12,12,14,10,10, 9, 9,14,11,11,
604.2295 +	12,12,14,12,12,13,13,14,12,12,12,12,15,14,14,13,
604.2296 +	13,15,13,13,14,14,15,14,14,15,15,15,12,12,13,13,
604.2297 +	15,13,13,14,14,15,14,14,13,13,15,13,13,13,14,15,
604.2298 +	14,14,15,15,15,12,12,13,13,15,13,13,14,14,15,14,
604.2299 +	14,13,13,15,13,13,14,14,15,14,14,15,15,15,13,13,
604.2300 +	12,12,15,13,13,13,13,15,14,14,13,12,15,15,15,14,
604.2301 +	15,15,15,14,20,20,15,14,14,13,13,15,14,14,13,13,
604.2302 +	15,14,14,13,13,14,12,12, 9, 9,14,14,14,12,12,14,
604.2303 +	13,13,12,13,14,14,14,12,12,15,14,14,12,12,15,14,
604.2304 +	14,14,13,15,14,14,14,14,15,14,14,13,13,15,14,14,
604.2305 +	13,13,15,15,15,14,14,15,14,14,13,13,15,14,14,14,
604.2306 +	14,15,14,14,13,13,15,14,14,13,13,15,15,15,15,14,
604.2307 +	15,15,15,13,13,15,14,14,14,14,15,14,14,13,13,15,
604.2308 +	14,14,13,13,14,15,15,14,14,15,15,15,14,14,15,14,
604.2309 +	14,14,14,15,15,15,14,14,15,14,14,13,14,15,15,15,
604.2310 +	14,14,13,10,10,12,12,17,11,11,12,12,17,12,12,12,
604.2311 +	12,17,12,12,11,11,17,15,15,12,11,18,13,13,13,13,
604.2312 +	18,15,15,13,13,17,12,12,12,12,18,13,13,13,13,17,
604.2313 +	15,15,12,12,17,12,12,12,12,17,15,15,13,13,17,12,
604.2314 +	12,12,12,17,13,13,12,12,17,15,15,12,12,18,14,13,
604.2315 +	12,12,18,15,15,13,13,18,13,13,12,12,18,13,13,12,
604.2316 +	12,18,16,16,12,12,18,16,16,12,12,18,15,15,13,13,
604.2317 +	18,16,16,12,12,17,15,15,12,12,17,16,16,12,12,13,
604.2318 +	 8, 8,10,10,14,14,15,12,12,14,15,15,12,12,15,14,
604.2319 +	14,12,12,15,15,14,12,12,15,15,15,13,13,15,15,15,
604.2320 +	13,13,15,15,15,12,12,16,15,15,13,13,16,15,15,13,
604.2321 +	13,15,15,15,12,12,15,15,15,14,14,15,15,15,12,12,
604.2322 +	15,15,15,13,13,16,15,15,13,13,15,15,15,13,13,16,
604.2323 +	15,15,13,13,15,15,14,12,12,15,15,15,12,12,16,14,
604.2324 +	15,13,13,16,15,15,13,13,15,16,15,13,13,16,15,14,
604.2325 +	13,13,16,15,15,13,13,16,15,15,13,13,13,12,12,11,
604.2326 +	11,14,14,14,11,11,14,14,14,12,12,15,14,14,11,11,
604.2327 +	16,14,14,11,11,15,15,15,12,13,16,14,14,13,13,15,
604.2328 +	15,15,12,12,15,14,14,13,13,16,15,15,12,12,15,15,
604.2329 +	15,12,12,15,14,14,13,13,15,15,15,12,12,15,14,14,
604.2330 +	12,12,16,15,15,12,12,16,15,15,12,12,16,14,14,13,
604.2331 +	13,15,15,15,11,11,15,15,14,12,12,16,15,15,11,11,
604.2332 +	16,15,15,12,12,16,14,14,13,13,16,15,15,11,11,16,
604.2333 +	14,14,12,12,16,15,15,11,11,14,10,10, 9, 9,14,11,
604.2334 +	11,12,12,14,12,12,13,14,14,12,12,12,12,14,14,14,
604.2335 +	13,13,15,13,13,14,14,15,14,14,15,15,15,12,12,13,
604.2336 +	13,15,13,13,14,14,15,15,15,14,14,15,13,13,14,14,
604.2337 +	15,15,15,15,15,15,12,12,13,13,15,13,13,14,14,15,
604.2338 +	14,14,13,13,15,13,13,14,14,15,14,14,15,15,15,12,
604.2339 +	12,13,13,15,13,13,13,13,14,14,14,13,13,15,15,15,
604.2340 +	14,15,15,15,15,21,19,15,14,14,13,13,15,14,14,14,
604.2341 +	14,14,14,14,13,13,14,12,12, 9, 9,14,14,14,12,12,
604.2342 +	14,14,13,13,13,14,14,14,12,12,14,14,14,12,12,15,
604.2343 +	14,14,13,13,15,14,14,14,14,15,14,14,13,13,15,14,
604.2344 +	14,13,13,15,15,15,15,15,15,14,14,13,13,15,14,14,
604.2345 +	14,14,15,14,14,13,13,15,14,14,13,13,14,15,15,15,
604.2346 +	15,15,14,15,13,13,15,14,14,14,14,15,14,14,13,13,
604.2347 +	15,14,14,13,13,14,15,15,14,14,15,15,15,14,14,15,
604.2348 +	14,14,14,14,15,15,15,15,15,15,14,14,14,13,14,15,
604.2349 +	15,14,14,13,10,10,12,12,18,12,12,12,12,17,12,12,
604.2350 +	12,12,18,13,13,11,11,18,15,14,11,11,17,13,13,13,
604.2351 +	13,18,15,15,12,12,18,12,12,12,12,17,13,13,12,12,
604.2352 +	18,15,15,12,12,18,13,13,13,12,18,15,15,13,13,18,
604.2353 +	13,13,12,12,18,13,13,12,12,18,15,15,12,12,17,13,
604.2354 +	13,12,12,17,15,15,12,12,17,12,12,11,11,17,13,13,
604.2355 +	11,11,17,15,15,11,11,18,16,16,12,12,18,15,15,13,
604.2356 +	13,18,15,15,11,11,17,15,15,12,12,18,15,15,11,11,
604.2357 +	13, 8, 8,10,10,14,14,14,11,11,15,15,15,12,12,15,
604.2358 +	14,14,11,11,16,14,14,12,12,15,15,15,12,12,15,15,
604.2359 +	15,13,13,15,15,15,12,12,15,15,15,12,12,16,15,15,
604.2360 +	13,13,15,15,15,12,12,15,15,15,13,13,16,15,15,12,
604.2361 +	12,15,15,15,12,12,16,15,15,13,13,16,15,15,12,12,
604.2362 +	15,15,15,13,13,15,14,14,12,12,15,15,15,12,12,16,
604.2363 +	15,14,12,12,16,15,15,13,13,16,16,16,13,13,16,14,
604.2364 +	15,13,13,15,15,15,13,13,16,15,15,12,12,13,12,12,
604.2365 +	10,10,14,14,14,11,11,15,14,14,12,12,15,14,14,11,
604.2366 +	11,16,14,14,11,11,15,14,15,12,12,15,14,14,13,13,
604.2367 +	15,15,15,12,12,15,14,14,12,12,15,14,15,12,12,15,
604.2368 +	15,15,12,12,16,14,14,13,13,15,15,15,11,12,16,14,
604.2369 +	14,12,12,16,15,15,12,12,15,15,15,12,12,16,14,14,
604.2370 +	12,12,15,15,15,11,11,15,14,14,11,12,15,15,14,11,
604.2371 +	11,16,15,15,12,12,16,14,14,13,13,16,15,15,11,11,
604.2372 +	16,14,14,12,12,16,15,15,11,11,13,10,10, 8, 8,14,
604.2373 +	12,12,12,12,14,12,12,13,13,14,12,12,12,12,14,14,
604.2374 +	14,13,13,15,13,13,14,14,15,15,14,15,15,15,13,13,
604.2375 +	13,13,15,13,13,14,14,15,14,15,14,14,15,13,13,13,
604.2376 +	13,15,15,15,15,15,15,12,12,13,12,15,13,13,14,14,
604.2377 +	15,14,14,13,13,15,13,13,14,13,15,15,15,16,16,15,
604.2378 +	13,13,12,12,15,13,13,13,13,14,14,14,12,12,15,15,
604.2379 +	15,14,14,15,15,15,20,20,15,14,14,13,13,15,15,14,
604.2380 +	14,14,15,14,14,13,13,13,12,12, 9, 9,14,13,13,12,
604.2381 +	12,14,13,13,12,12,14,14,14,12,12,14,14,14,13,13,
604.2382 +	15,14,14,13,13,15,14,14,14,14,15,15,14,12,12,15,
604.2383 +	14,14,13,13,15,14,15,14,15,15,14,14,13,13,15,14,
604.2384 +	14,14,14,15,14,14,12,12,15,14,14,13,13,14,15,14,
604.2385 +	15,14,15,14,14,13,13,15,14,14,14,14,15,14,14,12,
604.2386 +	12,15,14,14,13,13,15,15,15,14,14,15,15,15,14,14,
604.2387 +	16,14,14,14,14,15,15,15,14,14,15,14,14,14,14,14,
604.2388 +	15,15,14,14,13,13,13,12,13,17,15,15,12,12,17,15,
604.2389 +	15,12,12,18,15,15,11,11,17,16,16,11,11,18,16,16,
604.2390 +	13,13,18,17,16,13,13,18,16,16,12,12,18,16,16,12,
604.2391 +	12,18,17,17,12,12,17,16,16,12,13,17,16,16,12,13,
604.2392 +	17,16,16,12,12,17,16,16,12,12,18,17,16,12,12,18,
604.2393 +	16,16,12,12,17,16,17,12,12,18,15,15,11,11,18,15,
604.2394 +	15,12,12,17,17,17,11,11,17,17,17,12,12,17,16,16,
604.2395 +	13,13,18,16,16,11,11,18,16,16,12,12,18,17,16,11,
604.2396 +	11,14,14,14,10,10,16,15,14,11,11,16,15,15,12,12,
604.2397 +	16,14,14,12,12,17,14,14,13,13,17,15,15,13,13,17,
604.2398 +	15,15,14,14,16,15,15,12,12,16,15,15,13,13,18,15,
604.2399 +	15,14,14,16,15,15,12,12,16,15,15,14,14,16,15,15,
604.2400 +	12,12,16,15,15,13,13,17,15,15,13,13,17,15,15,13,
604.2401 +	13,17,15,15,14,14,16,14,14,12,12,17,15,15,12,12,
604.2402 +	18,15,15,13,13,17,15,15,14,14,17,16,16,15,15,17,
604.2403 +	15,14,13,13,17,15,15,14,14,17,15,15,13,13,14,12,
604.2404 +	12,11,11,15,14,14,12,12,16,14,14,12,12,16,14,14,
604.2405 +	11,11,17,14,14,12,12,16,15,14,13,13,16,14,14,13,
604.2406 +	13,16,15,15,12,12,16,14,14,13,13,17,15,15,13,13,
604.2407 +	16,15,15,13,13,17,14,14,13,13,16,15,15,12,12,16,
604.2408 +	14,14,12,12,16,15,15,12,12,17,15,15,12,12,17,14,
604.2409 +	14,13,13,16,15,15,12,12,16,14,14,12,12,16,15,15,
604.2410 +	12,12,17,15,15,13,13,17,14,14,13,13,17,15,15,12,
604.2411 +	12,17,14,14,12,12,17,15,15,12,12,14,14,14, 8, 8,
604.2412 +	14,14,14,13,13,14,15,15,14,14,14,14,14,14,14,15,
604.2413 +	15,15,19,19,15,15,15,14,14,15,15,16,20,19,15,15,
604.2414 +	15,14,14,15,16,16,15,15,15,15,15,19,19,15,15,15,
604.2415 +	14,14,15,16,16,19,20,15,15,15,14,14,15,15,15,15,
604.2416 +	15,15,15,15,19,19,15,15,15,15,15,15,15,16,19,20,
604.2417 +	15,14,15,14,14,15,15,15,15,15,15,15,15,20,19,15,
604.2418 +	15,15,21,19,15,16,16,20,20,15,15,14,19,19,15,15,
604.2419 +	16,20,21,15,15,15,20,19,13,12,12, 9, 9,14,14,14,
604.2420 +	12,12,14,13,13,13,13,14,14,14,13,13,15,14,14,20,
604.2421 +	19,15,14,14,14,13,15,14,14,19,19,15,15,14,13,13,
604.2422 +	15,14,14,14,14,15,15,15,19,20,15,14,14,13,13,15,
604.2423 +	14,14,20,19,14,15,14,13,13,15,14,14,14,13,15,15,
604.2424 +	15,19,20,15,15,14,14,14,15,14,14,21,19,15,15,15,
604.2425 +	13,13,15,14,14,14,14,14,15,15,20,20,15,15,15,21,
604.2426 +	20,15,14,14,19,20,15,15,15,20,20,15,14,14,19,20,
604.2427 +	15,15,15,21,19,
604.2428 +};
604.2429 +
604.2430 +static const static_codebook _44p2_p4_1 = {
604.2431 +	5, 3125,
604.2432 +	(long *)_vq_lengthlist__44p2_p4_1,
604.2433 +	1, -533725184, 1611661312, 3, 0,
604.2434 +	(long *)_vq_quantlist__44p2_p4_1,
604.2435 +	0
604.2436 +};
604.2437 +
604.2438 +static const long _vq_quantlist__44p2_p5_0[] = {
604.2439 +	2,
604.2440 +	1,
604.2441 +	3,
604.2442 +	0,
604.2443 +	4,
604.2444 +};
604.2445 +
604.2446 +static const long _vq_lengthlist__44p2_p5_0[] = {
604.2447 +	 2, 6, 6,14,14, 6, 7, 7,14,14, 7, 7, 7,15,15, 0,
604.2448 +	13,13,16,16, 0,13,13,15,15, 7, 8, 8,15,15, 9,10,
604.2449 +	10,17,16, 9, 8, 8,15,15, 0,13,13,18,17, 0,13,13,
604.2450 +	16,16, 8, 8, 8,15,15,12,11,11,16,17, 9, 8, 8,14,
604.2451 +	14, 0,13,13,18,17, 0,13,13,16,15, 0,14,14,18,17,
604.2452 +	 0,20,22,18,20, 0,12,12,16,16, 0,16,16,22,20, 0,
604.2453 +	14,14,16,16, 0,14,14,17,17, 0,22,22,22,19, 0,12,
604.2454 +	13,16,16, 0,17,17, 0, 0, 0,15,15,16,16, 5, 7, 7,
604.2455 +	13,13, 9, 9, 9,15,14,10,10,10,14,14, 0,21,21,18,
604.2456 +	17, 0,21,22,18,17, 9,10,10,14,14,12,12,12,17,17,
604.2457 +	12,10,10,14,14, 0,19,21,18,17, 0,20,22,18,18,11,
604.2458 +	10,10,14,14,14,13,13,18,17,12,11,11,14,14, 0,22,
604.2459 +	19,17,18, 0,20, 0,18,17, 0,22,21,17,17, 0, 0, 0,
604.2460 +	 0, 0, 0,20,22,17,17, 0,22, 0,21,19, 0,22, 0,18,
604.2461 +	18, 0, 0,22,18,19, 0, 0, 0, 0, 0, 0,19,21,17,17,
604.2462 +	 0, 0, 0,20,20, 0, 0, 0,18,18, 6, 6, 6,13,12, 8,
604.2463 +	 6, 6,11,11, 8, 6, 6,13,13, 0, 9, 9,11,11, 0,11,
604.2464 +	11,14,14, 9, 7, 7,13,13,11, 9, 9,13,13,10, 6, 6,
604.2465 +	13,13, 0,10,10,14,14, 0,10,10,13,13, 9, 7, 7,13,
604.2466 +	14,13, 9, 9,13,13,10, 6, 6,13,12, 0,11,11,15,15,
604.2467 +	 0,10,10,13,13, 0,12,12,15,15, 0,19, 0,17,17, 0,
604.2468 +	 9, 9,13,13, 0,13,14,19,20, 0,11,11,13,13, 0,11,
604.2469 +	11,14,14, 0,19,20,17,18, 0,10,10,13,13, 0,15,15,
604.2470 +	21,19, 0,12,12,13,13, 0,10,10,12,13, 0,11,11,15,
604.2471 +	15, 0,11,11,15,15, 0,15,15,22, 0, 0,16,17,22, 0,
604.2472 +	 0,11,11,15,15, 0,14,14,18,17, 0,11,11,15,16, 0,
604.2473 +	15,15,22,21, 0,16,16, 0,20, 0,12,12,16,15, 0,15,
604.2474 +	14,19,19, 0,11,11,16,16, 0,15,15,21, 0, 0,16,15,
604.2475 +	 0, 0, 0,16,16,22,21, 0, 0, 0, 0, 0, 0,15,15,20,
604.2476 +	20, 0,18,18, 0, 0, 0,16,17, 0, 0, 0,17,17, 0,22,
604.2477 +	 0, 0, 0, 0, 0, 0,15,15,21,22, 0,20,18, 0, 0, 0,
604.2478 +	18,17,22, 0, 0,10,10,12,11, 0,10,10,10,10, 0,11,
604.2479 +	11,12,12, 0,11,11, 9, 9, 0,13,13,12,12, 0,11,11,
604.2480 +	12,12, 0,13,13,12,12, 0,10,10,12,12, 0,13,12,13,
604.2481 +	13, 0,12,12,12,12, 0,11,11,12,12, 0,13,13,12,12,
604.2482 +	 0,10,10,12,12, 0,13,13,13,14, 0,12,12,12,12, 0,
604.2483 +	13,14,14,14, 0,20,21,15,15, 0,12,11,12,12, 0,15,
604.2484 +	16,20,22, 0,13,12,11,11, 0,13,13,14,13, 0,20, 0,
604.2485 +	16,15, 0,12,12,12,12, 0,16,16,22,21, 0,13,13,12,
604.2486 +	12, 6, 7, 7,16,16,11, 9, 9,15,15,12, 9, 9,16,16,
604.2487 +	 0,13,13,14,14, 0,14,14,16,17,10, 9, 9,16,16,14,
604.2488 +	12,12,16,16,12, 9, 9,15,15, 0,13,13,18,18, 0,13,
604.2489 +	13,15,16,12,10,10,17,18,15,12,12,17,17,13, 9, 9,
604.2490 +	16,16, 0,13,13,17,18, 0,14,14,16,16, 0,15,15,18,
604.2491 +	18, 0,22, 0,20,20, 0,12,12,16,16, 0,16,16,20,22,
604.2492 +	 0,14,14,16,16, 0,15,14,18,18, 0, 0,22,19,21, 0,
604.2493 +	13,13,16,17, 0,17,17,22,22, 0,15,15,16,16, 7, 7,
604.2494 +	 7,14,14,11,10,10,15,15,12,10,10,15,14, 0,22, 0,
604.2495 +	18,18, 0, 0,21,17,18,11,10,10,15,15,14,12,12,17,
604.2496 +	17,14,11,11,15,15, 0,22,20,18,18, 0, 0,20,18,17,
604.2497 +	12,10,10,16,16,17,14,14,19,18,14,11,11,15,15, 0,
604.2498 +	21,22,19,19, 0,21,22,18,18, 0,22, 0,19,21, 0, 0,
604.2499 +	 0, 0, 0, 0,22,22,18,17, 0, 0, 0,21,20, 0,22,22,
604.2500 +	20,19, 0, 0,22,20,20, 0, 0, 0, 0, 0, 0,20,21,17,
604.2501 +	17, 0, 0,22,21,21, 0, 0, 0,18,18,10, 9, 9,14,14,
604.2502 +	13,10,10,13,13,13,10,11,14,14, 0,13,13,12,12, 0,
604.2503 +	15,15,16,16,13,10,10,15,15,15,12,12,14,14,15,10,
604.2504 +	10,14,15, 0,14,14,16,15, 0,14,14,15,15,13,10,10,
604.2505 +	15,15,18,13,13,15,15,15,10,10,14,15, 0,14,14,16,
604.2506 +	16, 0,14,14,15,15, 0,15,15,16,16, 0,22, 0,18,18,
604.2507 +	 0,12,13,14,14, 0,17,17,22, 0, 0,14,14,14,14, 0,
604.2508 +	15,15,16,16, 0,22, 0,18,17, 0,13,13,14,14, 0,19,
604.2509 +	18,21,22, 0,15,15,14,14, 0,11,11,13,13, 0,12,12,
604.2510 +	16,16, 0,12,12,16,16, 0,15,16,21, 0, 0,16,17, 0,
604.2511 +	22, 0,12,12,16,16, 0,14,14,17,18, 0,11,11,16,16,
604.2512 +	 0,15,15,21,22, 0,16,16, 0, 0, 0,12,12,16,16, 0,
604.2513 +	15,15, 0,19, 0,12,12,16,17, 0,16,16,22, 0, 0,16,
604.2514 +	16, 0,22, 0,17,17, 0,22, 0, 0, 0, 0, 0, 0,15,15,
604.2515 +	20,19, 0,18,18, 0, 0, 0,17,18, 0, 0, 0,17,17, 0,
604.2516 +	 0, 0, 0, 0, 0, 0, 0,15,15, 0,22, 0,20,18, 0, 0,
604.2517 +	 0,18,18,22,22, 0,11,11,14,14, 0,12,12,14,14, 0,
604.2518 +	12,12,15,15, 0,13,13,14,14, 0,14,14,17,16, 0,12,
604.2519 +	12,16,16, 0,14,14,16,16, 0,11,11,15,15, 0,13,13,
604.2520 +	16,16, 0,13,13,15,15, 0,12,12,15,15, 0,15,14,16,
604.2521 +	16, 0,11,11,15,15, 0,14,14,17,17, 0,13,13,15,15,
604.2522 +	 0,15,15,17,17, 0, 0, 0,19,18, 0,13,12,15,15, 0,
604.2523 +	16,16, 0, 0, 0,14,14,15,15, 0,14,14,16,17, 0,22,
604.2524 +	 0,18,18, 0,13,13,15,15, 0,17,17, 0, 0, 0,14,14,
604.2525 +	15,15, 8, 8, 8,16,16,12,10,10,16,16,13, 9, 9,16,
604.2526 +	16, 0,14,14,17,17, 0,14,14,17,16,12,10,10,18,17,
604.2527 +	14,11,11,18,18,14, 9,10,16,16, 0,13,13,18,19, 0,
604.2528 +	14,13,16,16,12, 9, 9,16,16,17,13,13,17,17,14, 9,
604.2529 +	 9,15,15, 0,14,14,19,20, 0,13,13,15,15, 0,15,15,
604.2530 +	18,19, 0, 0,22,22,22, 0,13,13,17,17, 0,16,16,19,
604.2531 +	21, 0,14,14,16,16, 0,14,14,18,18, 0, 0, 0, 0, 0,
604.2532 +	 0,13,13,16,16, 0,18,18, 0, 0, 0,15,15,16,16, 8,
604.2533 +	 7, 7,14,14,12,10,10,15,15,13,10,10,15,14, 0,22,
604.2534 +	 0,18,18, 0,22, 0,18,18,12,10,10,16,15,15,12,12,
604.2535 +	17,17,14,11,11,15,15, 0,20,21,19,18, 0, 0, 0,17,
604.2536 +	18,13,11,11,15,15,16,13,13,18,18,15,11,11,14,14,
604.2537 +	 0,22,21,19,19, 0,21,22,18,18, 0,22,22,20,18, 0,
604.2538 +	 0, 0, 0, 0, 0,22,19,17,17, 0, 0, 0,22,21, 0, 0,
604.2539 +	22,19,17, 0, 0,22,19,19, 0, 0, 0, 0, 0, 0,22,21,
604.2540 +	18,17, 0, 0, 0,22, 0, 0, 0, 0,19,19, 0,10,10,14,
604.2541 +	14, 0,11,11,15,14, 0,11,11,15,15, 0,14,14,15,14,
604.2542 +	 0,15,15,16,16, 0,11,11,16,16, 0,13,13,16,16, 0,
604.2543 +	11,11,15,15, 0,14,14,17,16, 0,14,14,15,15, 0,11,
604.2544 +	11,16,16, 0,14,13,15,15, 0,11,11,15,15, 0,15,15,
604.2545 +	17,17, 0,14,14,15,14, 0,16,16,17,17, 0, 0,22,18,
604.2546 +	18, 0,13,13,15,15, 0,17,17,22, 0, 0,15,15,15,14,
604.2547 +	 0,15,16,16,17, 0, 0,22,18,19, 0,13,13,15,15, 0,
604.2548 +	20,18,21, 0, 0,15,15,14,14, 0,11,11,13,13, 0,12,
604.2549 +	12,16,16, 0,12,12,16,15, 0,15,16,22,22, 0,17,17,
604.2550 +	 0, 0, 0,12,12,16,16, 0,14,14,18,18, 0,11,11,16,
604.2551 +	16, 0,15,16,22,20, 0,16,16, 0,22, 0,12,12,16,16,
604.2552 +	 0,15,15,18,20, 0,11,11,16,16, 0,15,15, 0, 0, 0,
604.2553 +	16,16, 0, 0, 0,17,17,22, 0, 0, 0, 0, 0, 0, 0,15,
604.2554 +	15, 0,21, 0,18,18, 0, 0, 0,17,16, 0, 0, 0,17,17,
604.2555 +	22,22, 0, 0, 0, 0, 0, 0,15,15,21, 0, 0,20,22, 0,
604.2556 +	 0, 0,18,18, 0, 0, 0,12,12,15,15, 0,12,12,15,15,
604.2557 +	 0,12,12,16,16, 0,13,13,15,15, 0,15,15,17,17, 0,
604.2558 +	13,12,16,16, 0,14,14,16,16, 0,12,11,16,16, 0,14,
604.2559 +	14,17,17, 0,14,14,16,16, 0,12,12,16,16, 0,15,15,
604.2560 +	17,16, 0,11,11,15,16, 0,14,14,17,17, 0,14,14,16,
604.2561 +	16, 0,15,15,18,18, 0, 0, 0,22,19, 0,13,13,15,16,
604.2562 +	 0,16,17, 0, 0, 0,14,14,16,16, 0,15,15,18,17, 0,
604.2563 +	 0, 0,20,20, 0,13,13,16,15, 0,17,17,22,22, 0,14,
604.2564 +	14,15,15, 0,11,11,16,16, 0,13,13,16,17, 0,13,13,
604.2565 +	17,18, 0,16,16,17,17, 0,17,17,18,18, 0,12,12,17,
604.2566 +	17, 0,16,15,18,18, 0,12,12,16,16, 0,16,16,18,18,
604.2567 +	 0,15,15,17,17, 0,12,12,17,17, 0,16,16,19,18, 0,
604.2568 +	12,12,16,17, 0,16,16,19,19, 0,15,16,16,17, 0,16,
604.2569 +	16,19,17, 0, 0, 0,20,22, 0,13,13,16,16, 0,19,18,
604.2570 +	21, 0, 0,15,15,16,16, 0,16,16,18,18, 0, 0, 0,22,
604.2571 +	21, 0,14,14,16,16, 0,21,19,21,22, 0,16,16,16,16,
604.2572 +	 0, 9, 9,14,14, 0,13,13,15,15, 0,14,14,15,15, 0,
604.2573 +	 0,20,18,19, 0, 0,22,18,18, 0,12,12,15,15, 0,15,
604.2574 +	15,17,18, 0,14,13,14,14, 0,20, 0,18,18, 0,21, 0,
604.2575 +	18,17, 0,13,13,15,16, 0,17,17,18,18, 0,14,14,15,
604.2576 +	15, 0,22,22,20,19, 0,20,21,18,18, 0,20,22,19,19,
604.2577 +	 0, 0, 0, 0, 0, 0,20,20,17,17, 0, 0,22,22,21, 0,
604.2578 +	22, 0,18,18, 0,20,22,19,19, 0, 0, 0, 0, 0, 0,21,
604.2579 +	21,17,18, 0, 0, 0,21,20, 0, 0,22,19,18, 0,18,18,
604.2580 +	15,15, 0,22,21,17,16, 0, 0,22,17,17, 0,20,22,18,
604.2581 +	18, 0, 0,22,20,20, 0,21,19,16,16, 0,21,21,18,18,
604.2582 +	 0,19,19,17,17, 0, 0,22,19,19, 0,22,20,17,17, 0,
604.2583 +	21,19,16,16, 0,22,22,19,18, 0,19,20,16,16, 0,22,
604.2584 +	21,19,21, 0,21,22,17,18, 0,21,20,18,18, 0, 0, 0,
604.2585 +	19,20, 0,20,19,16,16, 0,22,22, 0, 0, 0,21,21,17,
604.2586 +	16, 0,22,20,19,18, 0, 0, 0,20,20, 0,20,19,16,16,
604.2587 +	 0, 0, 0, 0, 0, 0,21,22,17,17, 0,11,11,13,13, 0,
604.2588 +	13,13,15,16, 0,13,13,16,16, 0,17,18,21, 0, 0,17,
604.2589 +	18, 0, 0, 0,12,12,15,16, 0,15,15,19,18, 0,12,12,
604.2590 +	16,16, 0,17,17,22, 0, 0,17,17, 0,22, 0,12,12,17,
604.2591 +	16, 0,16,16,19,20, 0,12,12,16,16, 0,17,17, 0, 0,
604.2592 +	 0,17,17, 0,21, 0,17,16,22, 0, 0, 0, 0, 0, 0, 0,
604.2593 +	15,15,20,22, 0,20,18, 0, 0, 0,18,18, 0, 0, 0,17,
604.2594 +	17,21, 0, 0, 0, 0, 0, 0, 0,15,15,21,22, 0,19,20,
604.2595 +	22, 0, 0,19,18, 0, 0, 0,14,14,18,18, 0,16,16,22,
604.2596 +	20, 0,16,16,22,19, 0,17,17,20,22, 0,19,19, 0, 0,
604.2597 +	 0,15,15,20, 0, 0,18,21, 0,20, 0,15,15,21,20, 0,
604.2598 +	18,17, 0, 0, 0,17,17, 0,22, 0,15,15,19,19, 0,19,
604.2599 +	18, 0, 0, 0,15,15,20, 0, 0,18,18,22,22, 0,17,17,
604.2600 +	 0,20, 0,18,18, 0, 0, 0, 0,22, 0, 0, 0,15,15,19,
604.2601 +	20, 0,20,19, 0, 0, 0,17,17,20,21, 0,17,18,20,22,
604.2602 +	 0, 0, 0, 0,22, 0,15,15,20,20, 0,22,20, 0, 0, 0,
604.2603 +	17,18,20, 0, 0,12,12,17,16, 0,14,14,17,17, 0,13,
604.2604 +	13,17,17, 0,16,16,18,18, 0,17,16,17,17, 0,13,13,
604.2605 +	17,17, 0,15,16,18,18, 0,13,13,16,16, 0,16,16,18,
604.2606 +	18, 0,16,16,17,16, 0,13,13,16,16, 0,17,17,18,17,
604.2607 +	 0,12,12,15,16, 0,17,17,19,19, 0,16,16,16,16, 0,
604.2608 +	16,17,19,18, 0, 0, 0,21,22, 0,14,14,16,16, 0,18,
604.2609 +	18, 0,22, 0,16,16,16,16, 0,16,16,18,17, 0, 0, 0,
604.2610 +	21,20, 0,14,14,16,16, 0,21,22,22, 0, 0,16,16,16,
604.2611 +	16, 0, 9, 9,14,13, 0,13,14,15,16, 0,14,13,15,14,
604.2612 +	 0,22, 0,18,18, 0,21, 0,17,18, 0,13,13,15,15, 0,
604.2613 +	15,16,18,17, 0,14,14,15,14, 0,20,22,18,18, 0,22,
604.2614 +	21,17,17, 0,13,13,15,15, 0,17,17,19,19, 0,14,14,
604.2615 +	14,14, 0, 0,22,18,18, 0, 0,22,17,17, 0, 0,22,19,
604.2616 +	20, 0, 0, 0, 0, 0, 0,21,20,17,16, 0, 0, 0,21,22,
604.2617 +	 0, 0, 0,18,19, 0, 0, 0,18,18, 0, 0, 0, 0, 0, 0,
604.2618 +	22, 0,17,17, 0, 0, 0,20,22, 0, 0, 0,18,19, 0,18,
604.2619 +	19,16,16, 0,22,20,17,17, 0,22,22,17,18, 0,22,22,
604.2620 +	18,17, 0, 0,22,18,19, 0,20,20,17,18, 0, 0,22,19,
604.2621 +	18, 0,22,22,17,17, 0,22, 0,19,19, 0, 0,22,18,18,
604.2622 +	 0,20,22,17,17, 0, 0,22,18,18, 0,19,20,17,17, 0,
604.2623 +	22, 0,20,19, 0,22,21,17,17, 0, 0, 0,18,18, 0, 0,
604.2624 +	 0,22,19, 0,20, 0,17,17, 0,22, 0, 0,22, 0, 0,20,
604.2625 +	17,18, 0,22, 0,19,19, 0, 0, 0, 0,19, 0,19,21,17,
604.2626 +	17, 0, 0, 0, 0, 0, 0,20,21,17,16, 0,11,11,13,13,
604.2627 +	 0,13,13,16,16, 0,13,13,15,16, 0,17,17,21,22, 0,
604.2628 +	17,18, 0, 0, 0,12,12,16,16, 0,15,15,18,18, 0,13,
604.2629 +	13,16,16, 0,17,16,21,21, 0,17,17, 0, 0, 0,13,13,
604.2630 +	16,16, 0,16,16,19,18, 0,13,13,16,16, 0,17,17, 0,
604.2631 +	22, 0,17,18,20,22, 0,17,18, 0, 0, 0, 0, 0, 0, 0,
604.2632 +	 0,15,15,20, 0, 0,18,19, 0, 0, 0,17,17, 0, 0, 0,
604.2633 +	18,17,22, 0, 0, 0, 0, 0, 0, 0,15,16,21,20, 0,20,
604.2634 +	20, 0, 0, 0,18,19, 0, 0, 0,15,15,22,22, 0,17,16,
604.2635 +	20,22, 0,17,17,20,22, 0,18,18, 0,21, 0,19,18, 0,
604.2636 +	 0, 0,16,16,20,20, 0,19,19,22, 0, 0,15,16,21,22,
604.2637 +	 0,18,19,22, 0, 0,17,18, 0, 0, 0,16,16,22, 0, 0,
604.2638 +	19,19, 0,21, 0,15,16,20, 0, 0,18,18, 0,22, 0,18,
604.2639 +	17, 0, 0, 0,18,18, 0, 0, 0, 0, 0, 0, 0, 0,16,16,
604.2640 +	22,21, 0,20,21, 0, 0, 0,17,18,22, 0, 0,18,18, 0,
604.2641 +	 0, 0, 0, 0, 0, 0, 0,16,16,20,19, 0,22,21, 0, 0,
604.2642 +	 0,18,18,22,22,
604.2643 +};
604.2644 +
604.2645 +static const static_codebook _44p2_p5_0 = {
604.2646 +	5, 3125,
604.2647 +	(long *)_vq_lengthlist__44p2_p5_0,
604.2648 +	1, -528744448, 1616642048, 3, 0,
604.2649 +	(long *)_vq_quantlist__44p2_p5_0,
604.2650 +	0
604.2651 +};
604.2652 +
604.2653 +static const long _vq_quantlist__44p2_p5_1[] = {
604.2654 +	3,
604.2655 +	2,
604.2656 +	4,
604.2657 +	1,
604.2658 +	5,
604.2659 +	0,
604.2660 +	6,
604.2661 +};
604.2662 +
604.2663 +static const long _vq_lengthlist__44p2_p5_1[] = {
604.2664 +	 2, 3, 3, 3, 3, 3, 3,
604.2665 +};
604.2666 +
604.2667 +static const static_codebook _44p2_p5_1 = {
604.2668 +	1, 7,
604.2669 +	(long *)_vq_lengthlist__44p2_p5_1,
604.2670 +	1, -533200896, 1611661312, 3, 0,
604.2671 +	(long *)_vq_quantlist__44p2_p5_1,
604.2672 +	0
604.2673 +};
604.2674 +
604.2675 +static const long _vq_quantlist__44p2_p6_0[] = {
604.2676 +	1,
604.2677 +	0,
604.2678 +	2,
604.2679 +};
604.2680 +
604.2681 +static const long _vq_lengthlist__44p2_p6_0[] = {
604.2682 +	 1, 7, 7, 7, 8, 8, 7, 8, 8, 7, 9, 9,10,11,11, 9,
604.2683 +	 8, 8, 7, 8, 9,11,11,11, 9, 8, 8, 6, 7, 7,10,10,
604.2684 +	10,10,10,10,10,10,10,14,14,14,12,11,11,10,11,11,
604.2685 +	15,14,14,13,11,11, 6, 6, 6, 8, 5, 5, 8, 7, 7, 8,
604.2686 +	 7, 7,11,10,10, 9, 7, 7, 9, 7, 7,12,10,10,10, 7,
604.2687 +	 7, 6, 8, 7,12,10,10,12,10,10,11,10,10,15,14,13,
604.2688 +	13,10,10,11,10,10,16,14,14,14,10,10, 7, 7, 7,12,
604.2689 +	11,11,12,11,11,11,11,11,16,14,14,13,12,12,11,11,
604.2690 +	11,17,15,15,14,12,12,10, 9, 9,13,11,11,13,11,11,
604.2691 +	12,11,11,16,14,13,14,11,11,12,11,11,17,15,14,14,
604.2692 +	11,11, 7, 8, 8,12,11,11,12,10,10,12,10,10,16,13,
604.2693 +	14,13,10,10,11,10,10,17,14,14,14,10,10, 7, 7, 7,
604.2694 +	12,11,11,12,11,11,12,11,11,15,14,15,14,12,12,12,
604.2695 +	11,11,17,15,15,14,12,12,10,10, 9,13,11,11,13,11,
604.2696 +	11,13,11,11,16,14,14,14,11,11,13,11,11,16,15,15,
604.2697 +	15,11,11,
604.2698 +};
604.2699 +
604.2700 +static const static_codebook _44p2_p6_0 = {
604.2701 +	5, 243,
604.2702 +	(long *)_vq_lengthlist__44p2_p6_0,
604.2703 +	1, -527106048, 1620377600, 2, 0,
604.2704 +	(long *)_vq_quantlist__44p2_p6_0,
604.2705 +	0
604.2706 +};
604.2707 +
604.2708 +static const long _vq_quantlist__44p2_p6_1[] = {
604.2709 +	1,
604.2710 +	0,
604.2711 +	2,
604.2712 +};
604.2713 +
604.2714 +static const long _vq_lengthlist__44p2_p6_1[] = {
604.2715 +	 2, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, 8,
604.2716 +	 7, 7, 8, 8, 8, 9, 9, 9, 9, 8, 8, 6, 7, 7, 9, 8,
604.2717 +	 8, 9, 7, 7, 9, 8, 8,10, 8, 8,10, 8, 8,10, 8, 8,
604.2718 +	10, 8, 9,10, 8, 8, 7, 6, 6, 8, 6, 6, 9, 6, 6, 9,
604.2719 +	 7, 7,10, 8, 8, 9, 6, 6, 9, 7, 7,10, 9, 8, 9, 7,
604.2720 +	 7, 7, 7, 7,11, 8, 8,11, 9, 9,10, 9, 9,12, 9, 9,
604.2721 +	12, 8, 8,11, 9, 9,12, 9, 9,12, 8, 8, 8, 7, 7,10,
604.2722 +	 9, 9,10, 9, 9,10, 9, 9,11,10,11,11, 9, 9,11, 9,
604.2723 +	 9,11,11,11,11, 9, 9,10, 8, 8,11, 9, 9,10, 9, 9,
604.2724 +	11, 9, 9,11,10,10,11, 9, 9,11, 9, 9,12,10,10,11,
604.2725 +	 9, 9, 8, 8, 8,11, 9, 9,12, 9, 9,11, 9, 9,12, 9,
604.2726 +	 9,12, 8, 8,12, 9, 9,12, 9,10,12, 8, 8, 9, 7, 7,
604.2727 +	11, 9, 9,11,10,10,11, 9, 9,11,11,11,11, 9, 9,11,
604.2728 +	10,10,12,11,11,11, 9,10,10, 9, 9,11, 9, 9,11,10,
604.2729 +	10,11,10,10,11,11,11,11, 9, 9,11, 9,10,11,11,11,
604.2730 +	11, 9, 9,
604.2731 +};
604.2732 +
604.2733 +static const static_codebook _44p2_p6_1 = {
604.2734 +	5, 243,
604.2735 +	(long *)_vq_lengthlist__44p2_p6_1,
604.2736 +	1, -530841600, 1616642048, 2, 0,
604.2737 +	(long *)_vq_quantlist__44p2_p6_1,
604.2738 +	0
604.2739 +};
604.2740 +
604.2741 +static const long _vq_quantlist__44p2_p7_0[] = {
604.2742 +	1,
604.2743 +	0,
604.2744 +	2,
604.2745 +};
604.2746 +
604.2747 +static const long _vq_lengthlist__44p2_p7_0[] = {
604.2748 +	 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.2749 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2750 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2751 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2752 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2753 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2754 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2755 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2756 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2757 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2758 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2759 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2760 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2761 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2762 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2763 +	 9, 9, 9,
604.2764 +};
604.2765 +
604.2766 +static const static_codebook _44p2_p7_0 = {
604.2767 +	5, 243,
604.2768 +	(long *)_vq_lengthlist__44p2_p7_0,
604.2769 +	1, -513979392, 1633504256, 2, 0,
604.2770 +	(long *)_vq_quantlist__44p2_p7_0,
604.2771 +	0
604.2772 +};
604.2773 +
604.2774 +static const long _vq_quantlist__44p2_p7_1[] = {
604.2775 +	1,
604.2776 +	0,
604.2777 +	2,
604.2778 +};
604.2779 +
604.2780 +static const long _vq_lengthlist__44p2_p7_1[] = {
604.2781 +	 1, 9, 9, 6, 9, 9, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2782 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2783 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2784 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2785 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2786 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2787 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2788 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2789 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2790 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2791 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2792 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2793 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2794 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.2795 +	 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.2796 +	10,10,10,
604.2797 +};
604.2798 +
604.2799 +static const static_codebook _44p2_p7_1 = {
604.2800 +	5, 243,
604.2801 +	(long *)_vq_lengthlist__44p2_p7_1,
604.2802 +	1, -516716544, 1630767104, 2, 0,
604.2803 +	(long *)_vq_quantlist__44p2_p7_1,
604.2804 +	0
604.2805 +};
604.2806 +
604.2807 +static const long _vq_quantlist__44p2_p7_2[] = {
604.2808 +	12,
604.2809 +	11,
604.2810 +	13,
604.2811 +	10,
604.2812 +	14,
604.2813 +	9,
604.2814 +	15,
604.2815 +	8,
604.2816 +	16,
604.2817 +	7,
604.2818 +	17,
604.2819 +	6,
604.2820 +	18,
604.2821 +	5,
604.2822 +	19,
604.2823 +	4,
604.2824 +	20,
604.2825 +	3,
604.2826 +	21,
604.2827 +	2,
604.2828 +	22,
604.2829 +	1,
604.2830 +	23,
604.2831 +	0,
604.2832 +	24,
604.2833 +};
604.2834 +
604.2835 +static const long _vq_lengthlist__44p2_p7_2[] = {
604.2836 +	 1, 3, 2, 5, 4, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
604.2837 +	12,13,13,14,14,15,15,15,15,
604.2838 +};
604.2839 +
604.2840 +static const static_codebook _44p2_p7_2 = {
604.2841 +	1, 25,
604.2842 +	(long *)_vq_lengthlist__44p2_p7_2,
604.2843 +	1, -518864896, 1620639744, 5, 0,
604.2844 +	(long *)_vq_quantlist__44p2_p7_2,
604.2845 +	0
604.2846 +};
604.2847 +
604.2848 +static const long _vq_quantlist__44p2_p7_3[] = {
604.2849 +	12,
604.2850 +	11,
604.2851 +	13,
604.2852 +	10,
604.2853 +	14,
604.2854 +	9,
604.2855 +	15,
604.2856 +	8,
604.2857 +	16,
604.2858 +	7,
604.2859 +	17,
604.2860 +	6,
604.2861 +	18,
604.2862 +	5,
604.2863 +	19,
604.2864 +	4,
604.2865 +	20,
604.2866 +	3,
604.2867 +	21,
604.2868 +	2,
604.2869 +	22,
604.2870 +	1,
604.2871 +	23,
604.2872 +	0,
604.2873 +	24,
604.2874 +};
604.2875 +
604.2876 +static const long _vq_lengthlist__44p2_p7_3[] = {
604.2877 +	 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.2878 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.2879 +};
604.2880 +
604.2881 +static const static_codebook _44p2_p7_3 = {
604.2882 +	1, 25,
604.2883 +	(long *)_vq_lengthlist__44p2_p7_3,
604.2884 +	1, -529006592, 1611661312, 5, 0,
604.2885 +	(long *)_vq_quantlist__44p2_p7_3,
604.2886 +	0
604.2887 +};
604.2888 +
604.2889 +static const long _huff_lengthlist__44p2_short[] = {
604.2890 +	 4, 4,12, 9, 8,12,15,17, 4, 2,11, 6, 5, 9,13,15,
604.2891 +	11, 7, 8, 7, 7,10,14,13, 8, 5, 7, 5, 5, 8,12,12,
604.2892 +	 8, 4, 7, 4, 3, 6,11,12,11, 8, 9, 7, 6, 8,11,12,
604.2893 +	15,13,14,12, 9, 7,10,13,16,12,17,12, 7, 5, 8,11,
604.2894 +};
604.2895 +
604.2896 +static const static_codebook _huff_book__44p2_short = {
604.2897 +	2, 64,
604.2898 +	(long *)_huff_lengthlist__44p2_short,
604.2899 +	0, 0, 0, 0, 0,
604.2900 +	NULL,
604.2901 +	0
604.2902 +};
604.2903 +
604.2904 +static const long _vq_quantlist__44p3_l0_0[] = {
604.2905 +	6,
604.2906 +	5,
604.2907 +	7,
604.2908 +	4,
604.2909 +	8,
604.2910 +	3,
604.2911 +	9,
604.2912 +	2,
604.2913 +	10,
604.2914 +	1,
604.2915 +	11,
604.2916 +	0,
604.2917 +	12,
604.2918 +};
604.2919 +
604.2920 +static const long _vq_lengthlist__44p3_l0_0[] = {
604.2921 +	 1, 4, 4, 8, 8, 8, 8, 9, 9,10,10,10,10, 4, 6, 5,
604.2922 +	 8, 7, 9, 9, 9, 9,10, 9,11, 9, 4, 5, 6, 7, 8, 9,
604.2923 +	 9, 9, 9, 9,10, 9,10, 8, 9, 8, 9, 8,10, 9,11, 9,
604.2924 +	12,10,12,10, 8, 8, 9, 8, 9, 9,10, 9,11,10,12,10,
604.2925 +	12, 9,10,10,11,10,12,11,12,11,12,12,12,12, 9,10,
604.2926 +	10,11,11,11,11,11,12,12,12,12,12,10,11,11,12,12,
604.2927 +	12,12,12,12,12,12,12,12,10,11,11,12,12,12,12,12,
604.2928 +	12,12,12,12,12,11,12,12,12,12,12,13,12,13,12,13,
604.2929 +	12,12,11,12,12,12,12,12,12,13,12,12,12,12,12,12,
604.2930 +	12,12,13,13,12,13,12,13,12,13,12,12,12,13,12,13,
604.2931 +	12,13,12,13,12,13,12,12,12,
604.2932 +};
604.2933 +
604.2934 +static const static_codebook _44p3_l0_0 = {
604.2935 +	2, 169,
604.2936 +	(long *)_vq_lengthlist__44p3_l0_0,
604.2937 +	1, -526516224, 1616117760, 4, 0,
604.2938 +	(long *)_vq_quantlist__44p3_l0_0,
604.2939 +	0
604.2940 +};
604.2941 +
604.2942 +static const long _vq_quantlist__44p3_l0_1[] = {
604.2943 +	2,
604.2944 +	1,
604.2945 +	3,
604.2946 +	0,
604.2947 +	4,
604.2948 +};
604.2949 +
604.2950 +static const long _vq_lengthlist__44p3_l0_1[] = {
604.2951 +	 3, 4, 4, 5, 5, 4, 4, 5, 5, 5, 4, 5, 4, 5, 5, 5,
604.2952 +	 5, 6, 5, 6, 5, 6, 5, 6, 5,
604.2953 +};
604.2954 +
604.2955 +static const static_codebook _44p3_l0_1 = {
604.2956 +	2, 25,
604.2957 +	(long *)_vq_lengthlist__44p3_l0_1,
604.2958 +	1, -533725184, 1611661312, 3, 0,
604.2959 +	(long *)_vq_quantlist__44p3_l0_1,
604.2960 +	0
604.2961 +};
604.2962 +
604.2963 +static const long _vq_quantlist__44p3_l1_0[] = {
604.2964 +	1,
604.2965 +	0,
604.2966 +	2,
604.2967 +};
604.2968 +
604.2969 +static const long _vq_lengthlist__44p3_l1_0[] = {
604.2970 +	 1, 4, 4, 4, 4, 4, 4, 4, 4,
604.2971 +};
604.2972 +
604.2973 +static const static_codebook _44p3_l1_0 = {
604.2974 +	2, 9,
604.2975 +	(long *)_vq_lengthlist__44p3_l1_0,
604.2976 +	1, -516716544, 1630767104, 2, 0,
604.2977 +	(long *)_vq_quantlist__44p3_l1_0,
604.2978 +	0
604.2979 +};
604.2980 +
604.2981 +static const long _huff_lengthlist__44p3_lfe[] = {
604.2982 +	 1, 3, 2, 3,
604.2983 +};
604.2984 +
604.2985 +static const static_codebook _huff_book__44p3_lfe = {
604.2986 +	2, 4,
604.2987 +	(long *)_huff_lengthlist__44p3_lfe,
604.2988 +	0, 0, 0, 0, 0,
604.2989 +	NULL,
604.2990 +	0
604.2991 +};
604.2992 +
604.2993 +static const long _huff_lengthlist__44p3_long[] = {
604.2994 +	 3, 4,13, 9, 9,12,15,17, 4, 2,18, 5, 7,10,14,18,
604.2995 +	11, 8, 6, 5, 6, 8,11,14, 8, 5, 5, 3, 5, 8,11,13,
604.2996 +	 9, 6, 7, 5, 5, 7, 9,10,11,10, 9, 8, 6, 6, 8,10,
604.2997 +	14,14,11,11, 9, 8, 9,10,17,17,14,13,10, 9,10,10,
604.2998 +};
604.2999 +
604.3000 +static const static_codebook _huff_book__44p3_long = {
604.3001 +	2, 64,
604.3002 +	(long *)_huff_lengthlist__44p3_long,
604.3003 +	0, 0, 0, 0, 0,
604.3004 +	NULL,
604.3005 +	0
604.3006 +};
604.3007 +
604.3008 +static const long _vq_quantlist__44p3_p1_0[] = {
604.3009 +	1,
604.3010 +	0,
604.3011 +	2,
604.3012 +};
604.3013 +
604.3014 +static const long _vq_lengthlist__44p3_p1_0[] = {
604.3015 +	 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3016 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3017 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3018 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3019 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3020 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3021 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3022 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3023 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3024 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3025 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3026 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3027 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3028 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3029 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3030 +	 0, 0, 0,
604.3031 +};
604.3032 +
604.3033 +static const static_codebook _44p3_p1_0 = {
604.3034 +	5, 243,
604.3035 +	(long *)_vq_lengthlist__44p3_p1_0,
604.3036 +	1, -535822336, 1611661312, 2, 0,
604.3037 +	(long *)_vq_quantlist__44p3_p1_0,
604.3038 +	0
604.3039 +};
604.3040 +
604.3041 +static const long _vq_quantlist__44p3_p2_0[] = {
604.3042 +	2,
604.3043 +	1,
604.3044 +	3,
604.3045 +	0,
604.3046 +	4,
604.3047 +};
604.3048 +
604.3049 +static const long _vq_lengthlist__44p3_p2_0[] = {
604.3050 +	 3, 7, 7, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,
604.3051 +	11,11, 0, 0, 0, 0, 0, 0, 0, 0,10, 9, 0, 0, 0, 0,
604.3052 +	 0, 0, 0, 0, 9, 9, 0, 0, 0,10,11, 0, 0, 0, 0, 0,
604.3053 +	 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0,
604.3054 +	 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0,12,12, 0, 0,
604.3055 +	 0, 0, 0, 0, 0, 0,11,11, 0, 0, 0,12,12, 0, 0, 0,
604.3056 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3057 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
604.3058 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3059 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3060 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3061 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3062 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3063 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3064 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3065 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0,
604.3066 +	 5, 5, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0,
604.3067 +	 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
604.3068 +	 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0,
604.3069 +	 0, 0, 0, 0, 0, 0, 0, 5, 6, 0, 0, 0, 7, 7, 0, 0,
604.3070 +	 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0,
604.3071 +	 8, 8, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3072 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3073 +	 0, 0, 0, 0, 0, 0, 0, 0,11,11, 0, 0, 0, 9, 9, 0,
604.3074 +	 0, 0,10,10, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0,
604.3075 +	 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,
604.3076 +	10,10, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0, 0,
604.3077 +	 0, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
604.3078 +	 0, 0, 0,11,12, 0, 0, 0, 0, 0, 0, 0, 0,11,11, 0,
604.3079 +	 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3080 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3081 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3082 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3083 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3084 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3085 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3086 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3087 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3088 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3089 +	 0, 0, 9, 9, 0, 0, 0, 7, 7, 0, 0, 0, 8, 8, 0, 0,
604.3090 +	 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0,
604.3091 +	 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0,
604.3092 +	 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8,
604.3093 +	 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0,
604.3094 +	 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,11,11, 0, 0,
604.3095 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3096 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
604.3097 +	 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3098 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3099 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3100 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3101 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3102 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3103 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3104 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3105 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3106 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3107 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3108 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3109 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3110 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3111 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3112 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 7, 7,
604.3113 +	 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0,
604.3114 +	 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0,
604.3115 +	 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,
604.3116 +	 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0,
604.3117 +	 0, 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,
604.3118 +	 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3119 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3120 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3121 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3122 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3123 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3124 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3125 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3126 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3127 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3128 +	 0, 0, 0, 9, 9, 0, 0, 0, 7, 7, 0, 0, 0, 8, 8, 0,
604.3129 +	 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0,
604.3130 +	 0, 0, 0, 0, 0, 0, 8, 7, 0, 0, 0, 9, 9, 0, 0, 0,
604.3131 +	 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7,
604.3132 +	 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0,11,11,
604.3133 +	 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0,
604.3134 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3135 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3136 +	 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3137 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3138 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3139 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3140 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3141 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3142 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3143 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3144 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3145 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3146 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3147 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3148 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3149 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3150 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3151 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 7,
604.3152 +	 7, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
604.3153 +	 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0,
604.3154 +	 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0,
604.3155 +	 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0,
604.3156 +	 0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 9,
604.3157 +	 9, 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3158 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3159 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3160 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3161 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3162 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3163 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3164 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3165 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3166 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3167 +	 0, 0, 0, 0,10,10, 0, 0, 0, 9, 9, 0, 0, 0,10,10,
604.3168 +	 0, 0, 0,11,12, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0,
604.3169 +	 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0,11,11, 0, 0,
604.3170 +	 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0,
604.3171 +	 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0,11,
604.3172 +	11, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,12,12,
604.3173 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3174 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3175 +	 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3176 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3177 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3178 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3179 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3180 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3181 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3182 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3183 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3184 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3185 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3186 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3187 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3188 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3189 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3190 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0,
604.3191 +	 9, 9, 0, 0, 0,10,10, 0, 0, 0,12,12, 0, 0, 0, 0,
604.3192 +	 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,
604.3193 +	 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0,
604.3194 +	 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,11,11, 0, 0,
604.3195 +	 0, 0, 0, 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,
604.3196 +	10,10, 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3197 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3198 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3199 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3200 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3201 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3202 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3203 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3204 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3205 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3206 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3207 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3208 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3209 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3210 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3211 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3212 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3213 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3214 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3215 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3216 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3217 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3218 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3219 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3220 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3221 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3222 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3223 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3224 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3225 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3226 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3227 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3228 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3229 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3230 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3231 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3232 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3233 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3234 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3235 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3236 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3237 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3238 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3239 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3240 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3241 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3242 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3243 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3244 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3245 +	 0, 0, 0, 0, 0,
604.3246 +};
604.3247 +
604.3248 +static const static_codebook _44p3_p2_0 = {
604.3249 +	5, 3125,
604.3250 +	(long *)_vq_lengthlist__44p3_p2_0,
604.3251 +	1, -533725184, 1611661312, 3, 0,
604.3252 +	(long *)_vq_quantlist__44p3_p2_0,
604.3253 +	0
604.3254 +};
604.3255 +
604.3256 +static const long _vq_quantlist__44p3_p3_0[] = {
604.3257 +	1,
604.3258 +	0,
604.3259 +	2,
604.3260 +};
604.3261 +
604.3262 +static const long _vq_lengthlist__44p3_p3_0[] = {
604.3263 +	 1, 5, 5, 5, 8, 8, 0, 8, 8, 6, 9, 9, 8,10,10, 0,
604.3264 +	 8, 8, 0, 9, 9, 0,12,12, 0, 8, 8, 4, 7, 7, 6,10,
604.3265 +	10, 0,12,12, 7,11,11, 9,12,12, 0,12,12, 0,13,13,
604.3266 +	 0,15,15, 0,12,12, 0, 7, 7, 0, 7, 7, 0, 8, 8, 0,
604.3267 +	 8, 8, 0,10,10, 0, 7, 7, 0, 8, 8, 0,11,11, 0, 7,
604.3268 +	 7, 5, 7, 7, 9, 9, 9, 0,11,10, 9, 9, 9,11,12,12,
604.3269 +	 0,10,10, 0,11,11, 0,13,13, 0,11,11, 6, 7, 7, 9,
604.3270 +	10,10, 0,12,12,10,11,11,11,12,12, 0,12,12, 0,13,
604.3271 +	13, 0,15,15, 0,12,12, 0,10,10, 0,11,11, 0,11,11,
604.3272 +	 0,12,12, 0,13,13, 0,11,11, 0,12,12, 0,15,15, 0,
604.3273 +	11,11, 0, 8, 8, 0,10,10, 0,12,12, 0,11,11, 0,12,
604.3274 +	12, 0,12,12, 0,12,12, 0,15,15, 0,11,11, 0, 7, 7,
604.3275 +	 0,10,10, 0,12,12, 0,10,10, 0,12,13, 0,12,12, 0,
604.3276 +	13,13, 0,14,14, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,
604.3277 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.3278 +	 0, 0, 0,
604.3279 +};
604.3280 +
604.3281 +static const static_codebook _44p3_p3_0 = {
604.3282 +	5, 243,
604.3283 +	(long *)_vq_lengthlist__44p3_p3_0,
604.3284 +	1, -533200896, 1614282752, 2, 0,
604.3285 +	(long *)_vq_quantlist__44p3_p3_0,
604.3286 +	0
604.3287 +};
604.3288 +
604.3289 +static const long _vq_quantlist__44p3_p3_1[] = {
604.3290 +	1,
604.3291 +	0,
604.3292 +	2,
604.3293 +};
604.3294 +
604.3295 +static const long _vq_lengthlist__44p3_p3_1[] = {
604.3296 +	 3, 4, 4, 0, 8, 8, 0, 8, 8, 0, 9, 9, 0,10,10, 0,
604.3297 +	 8, 8, 0, 9, 9, 0,10,10, 0, 8, 8, 0, 7, 7, 0, 8,
604.3298 +	 8, 0, 8, 8, 0, 8, 8, 0, 8, 8, 0, 8, 8, 0, 8, 8,
604.3299 +	 0, 8, 8, 0, 8, 8, 0, 7, 7, 0, 6, 6, 0, 7, 7, 0,
604.3300 +	 7, 7, 0,10,10, 0, 6, 6, 0, 7, 7, 0,10,10, 0, 6,
604.3301 +	 5, 0, 8, 8, 0, 7, 7, 0, 8, 8, 0, 8, 8, 0, 9, 9,
604.3302 +	 0, 7, 7, 0, 8, 8, 0, 9, 9, 0, 7, 7, 0, 6, 6, 0,
604.3303 +	 9,10, 0,10,10, 0,10,10, 0,11,11, 0, 9, 9, 0,10,
604.3304 +	10, 0,11,11, 0, 9, 9, 0, 8, 8, 0, 8, 8, 0, 8, 8,
604.3305 +	 0, 9, 9, 0, 9, 9, 0, 8, 8, 0, 8, 8, 0, 9, 9, 0,
604.3306 +	 7, 7, 0, 8, 8, 0, 7, 7, 0, 7, 7, 0, 8, 8, 0, 9,
604.3307 +	 9, 0, 7, 7, 0, 7, 7, 0, 9, 9, 0, 6, 6, 0, 6, 6,
604.3308 +	 0,10,10, 0,10,10, 0,10,10, 0,12,12, 0, 9, 9, 0,
604.3309 +	10,10, 0,12,12, 0, 9, 9, 0, 8, 8, 0, 7, 7, 0, 8,
604.3310 +	 8, 0, 8, 8, 0, 9, 9, 0, 7, 7, 0, 8, 8, 0, 9, 9,
604.3311 +	 0, 7, 7,
604.3312 +};
604.3313 +
604.3314 +static const static_codebook _44p3_p3_1 = {
604.3315 +	5, 243,
604.3316 +	(long *)_vq_lengthlist__44p3_p3_1,
604.3317 +	1, -535822336, 1611661312, 2, 0,
604.3318 +	(long *)_vq_quantlist__44p3_p3_1,
604.3319 +	0
604.3320 +};
604.3321 +
604.3322 +static const long _vq_quantlist__44p3_p4_0[] = {
604.3323 +	1,
604.3324 +	0,
604.3325 +	2,
604.3326 +};
604.3327 +
604.3328 +static const long _vq_lengthlist__44p3_p4_0[] = {
604.3329 +	 1, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8,10,11,11, 9,
604.3330 +	 8, 8, 8, 8, 8,11,11,11,10, 8, 8, 5, 7, 7, 9,11,
604.3331 +	11,10,11,11,10,11,11,12,13,14,11,12,12,10,11,11,
604.3332 +	13,14,14,12,12,12, 5, 6, 6, 8, 6, 6, 8, 7, 7, 8,
604.3333 +	 7, 7,11,10,10,10, 7, 7, 9, 7, 7,12,11,11,11, 7,
604.3334 +	 7, 7, 7, 7,11,10,10,12,10,10,11,10,10,15,13,13,
604.3335 +	13,10,10,12,11,11,15,13,13,14,11,11, 7, 7, 7,11,
604.3336 +	11,11,12,11,11,12,11,11,14,14,14,14,12,12,12,12,
604.3337 +	12,16,15,15,14,12,12, 0,10,10, 0,11,11, 0,11,12,
604.3338 +	 0,11,11, 0,14,14, 0,11,11, 0,12,12, 0,15,15, 0,
604.3339 +	11,11, 8, 8, 8,12,10,10,12,10,10,13,11,11,15,13,
604.3340 +	13,14,11,11,12,10,10,16,14,14,14,10,10, 8, 7, 7,
604.3341 +	12,11,11,13,11,11,12,11,11,15,14,14,14,12,12,13,
604.3342 +	12,12,15,14,14,15,12,12, 0,11,11, 0,12,12, 0,12,
604.3343 +	12, 0,12,12, 0,15,15, 0,12,12, 0,13,13, 0,14,15,
604.3344 +	 0,12,12,
604.3345 +};
604.3346 +
604.3347 +static const static_codebook _44p3_p4_0 = {
604.3348 +	5, 243,
604.3349 +	(long *)_vq_lengthlist__44p3_p4_0,
604.3350 +	1, -531365888, 1616117760, 2, 0,
604.3351 +	(long *)_vq_quantlist__44p3_p4_0,
604.3352 +	0
604.3353 +};
604.3354 +
604.3355 +static const long _vq_quantlist__44p3_p4_1[] = {
604.3356 +	2,
604.3357 +	1,
604.3358 +	3,
604.3359 +	0,
604.3360 +	4,
604.3361 +};
604.3362 +
604.3363 +static const long _vq_lengthlist__44p3_p4_1[] = {
604.3364 +	 3, 4, 5, 8, 8,12,10,10,12,12,12,10,10,12,12,13,
604.3365 +	11,11,12,12,13,12,12,12,12,13,10,10,13,13,13,13,
604.3366 +	13,13,13,13,10,10,13,13,13,11,11,13,13,14,13,13,
604.3367 +	12,12,13,10,10,13,13,13,13,13,13,13,13,10,10,12,
604.3368 +	12,13,11,11,13,13,13,13,13,12,12,13,12,12,13,13,
604.3369 +	13,13,13,13,13,14,11,11,12,12,14,12,12,13,12,14,
604.3370 +	14,14,12,12,13,14,14,13,13,14,13,13,13,13,14,14,
604.3371 +	14,12,12,14,13,13,13,13,14,14,14,12,12,12, 8, 8,
604.3372 +	11,11,12,12,12,11,11,12,11,11,10,10,13,12,12,10,
604.3373 +	10,13,12,12,10,10,13,12,12,12,12,14,12,12,12,12,
604.3374 +	13,13,13,11,11,14,12,12,11,11,14,12,12,12,12,14,
604.3375 +	12,12,12,12,13,12,12,12,12,13,13,13,11,11,14,12,
604.3376 +	12,11,11,14,12,12,12,12,14,13,13,12,12,14,12,12,
604.3377 +	12,11,14,13,13,11,11,14,13,12,11,11,14,13,13,11,
604.3378 +	11,14,13,13,12,12,14,12,12,12,12,15,13,13,12,12,
604.3379 +	14,12,12,11,11,14,13,13,11,11,12, 9, 9,10,10,12,
604.3380 +	 7, 7,11,11,12, 9, 9,12,12,13,10,10,10,10,14,14,
604.3381 +	14,11,11,13, 9, 9,12,12,14,14,14,12,12,13, 8, 8,
604.3382 +	11,11,14, 9, 9,12,12,14,14,14,11,11,13, 9, 9,12,
604.3383 +	12,14,14,14,12,12,14, 8, 8,11,11,14, 9, 9,12,12,
604.3384 +	14,14,14,11,11,14,10,10,12,12,14,14,14,13,13,14,
604.3385 +	 9, 9,11,11,14,10,10,12,12,14,14,14,11,11,14,14,
604.3386 +	15,12,12,15,14,14,14,14,15,14,14,11,11,14,14,14,
604.3387 +	12,12,14,14,14,11,11,14,11,11,10,10,14,10,10,10,
604.3388 +	10,14,10,10,10,10,15,11,11, 9, 9,14,12,12, 9, 9,
604.3389 +	15,11,11,11,11,15,13,13,11,11,15,10,10,10,10,15,
604.3390 +	11,11,10,10,15,13,13,11,11,15,11,11,11,11,15,13,
604.3391 +	13,11,11,15,10,10,10,10,15,11,11,10,10,15,13,13,
604.3392 +	11,11,15,12,12,11,11,15,13,13,11,11,15,11,11,10,
604.3393 +	10,15,12,12,10,10,15,13,13,10,10,15,14,14,11,11,
604.3394 +	15,13,13,11,11,15,14,14,10,11,15,13,13,10,10,15,
604.3395 +	13,14,10,10,14,13,13,10,10,14,13,13,10,10,14,13,
604.3396 +	13,10,10,14,13,13, 9, 9,14,14,14, 9, 9,15,14,14,
604.3397 +	11,11,15,14,14,10,10,15,14,14,10,10,15,14,14,11,
604.3398 +	11,15,14,14,10,10,15,14,14,11,11,15,14,14,10,10,
604.3399 +	14,14,14,10,10,15,14,14,10,10,14,14,14,10,10,15,
604.3400 +	14,14,11,11,15,14,14,11,11,14,14,14,10,10,15,14,
604.3401 +	14,10,10,14,14,14, 9, 9,15,15,15,11,11,15,14,14,
604.3402 +	12,12,15,15,14,10,10,15,14,14,10,10,14,15,15, 9,
604.3403 +	 9,14,10,10,12,12,17, 9, 9,12,12,17,10,10,13,13,
604.3404 +	17,11,11,12,12,18,14,14,12,12,17,10,10,13,13,17,
604.3405 +	14,14,12,12,17, 9, 9,12,12,17,11,11,12,12,17,14,
604.3406 +	14,12,12,18,10,10,13,13,18,14,14,13,13,18, 9, 9,
604.3407 +	12,12,18,10,10,13,13,18,14,14,12,12,18,11,11,13,
604.3408 +	13,18,14,14,13,13,18,10,10,12,12,17,11,11,12,12,
604.3409 +	17,14,14,12,12,18,15,15,13,13,18,14,14,14,14,18,
604.3410 +	15,15,12,12,18,14,14,12,12,18,15,15,12,12,13, 7,
604.3411 +	 7,11,11,14,15,15,11,11,14,15,15,12,12,14,15,15,
604.3412 +	11,11,15,15,15,11,11,14,15,15,12,12,14,15,15,12,
604.3413 +	12,14,15,15,11,11,14,15,15,11,11,15,15,15,12,12,
604.3414 +	14,15,15,12,12,14,15,15,12,12,14,15,15,11,11,14,
604.3415 +	15,15,11,11,15,15,15,12,12,15,15,15,12,12,14,15,
604.3416 +	15,12,12,14,15,14,12,12,14,15,15,11,11,15,14,14,
604.3417 +	12,12,15,15,15,12,12,15,16,16,12,12,15,15,15,12,
604.3418 +	12,15,15,15,12,12,15,15,15,12,12,13,13,13,11,10,
604.3419 +	14,14,15,11,11,14,14,14,12,12,15,14,14,10,10,15,
604.3420 +	15,15,11,11,14,15,15,12,12,14,14,14,11,11,14,15,
604.3421 +	15,11,11,14,15,15,12,12,15,15,15,11,11,14,15,15,
604.3422 +	12,12,14,14,14,12,12,14,15,15,11,11,14,15,15,12,
604.3423 +	12,15,15,15,11,11,15,15,15,12,12,15,14,14,12,12,
604.3424 +	14,15,15,11,11,14,15,15,11,11,15,15,15,10,10,15,
604.3425 +	15,16,12,12,15,15,15,14,14,15,15,15,11,11,15,15,
604.3426 +	15,12,12,15,15,15,11,11,14,11,11,10,10,15, 9, 9,
604.3427 +	12,12,15,10,10,12,12,15,11,11,11,11,15,14,14,12,
604.3428 +	12,15,10,10,13,13,15,14,14,12,12,15, 9, 9,12,12,
604.3429 +	15,10,10,13,13,15,13,13,12,11,15,10,10,12,12,15,
604.3430 +	14,14,12,12,15, 9, 9,11,11,15,11,11,12,12,15,13,
604.3431 +	13,11,11,15,11,11,13,13,15,13,14,13,14,15,11,11,
604.3432 +	11,11,15,11,11,12,12,15,14,14,11,11,15,14,14,13,
604.3433 +	13,15,14,14,20,20,15,14,14,12,12,15,14,14,12,12,
604.3434 +	15,14,14,11,11,14,13,13,10,10,14,13,13,12,12,14,
604.3435 +	14,13,12,12,15,14,14,12,12,15,14,14,11,11,15,14,
604.3436 +	14,12,12,15,14,14,13,13,15,14,14,12,11,15,14,14,
604.3437 +	11,11,15,14,14,13,13,15,14,14,12,12,15,14,14,13,
604.3438 +	13,15,14,14,12,11,15,14,14,12,12,15,14,14,13,13,
604.3439 +	15,14,14,13,13,15,14,14,12,12,15,14,14,12,12,15,
604.3440 +	14,14,12,12,15,15,15,13,13,15,15,15,13,13,15,14,
604.3441 +	14,13,13,15,15,15,13,13,15,14,15,12,12,15,15,15,
604.3442 +	13,13,14,10,10,12,13,17, 9, 9,12,12,17,10,10,13,
604.3443 +	13,17,11,11,12,12,18,14,14,12,12,18,10,10,13,13,
604.3444 +	18,14,14,12,12,17, 9, 9,12,12,18,10,11,13,13,18,
604.3445 +	14,14,12,12,17,10,10,12,12,17,14,14,12,12,17, 9,
604.3446 +	 9,12,12,17,11,11,12,12,17,14,14,12,12,18,11,11,
604.3447 +	12,12,18,14,14,13,13,18,11,11,12,12,18,11,11,12,
604.3448 +	12,18,14,14,12,12,18,15,15,12,12,18,14,14,13,13,
604.3449 +	18,15,15,12,12,17,14,14,12,12,17,15,15,12,12,13,
604.3450 +	 7, 7,11,11,14,15,15,11,11,14,15,15,11,11,14,15,
604.3451 +	14,12,12,15,15,15,12,11,14,15,15,12,12,14,15,15,
604.3452 +	12,12,14,15,15,11,11,14,15,15,11,11,15,15,15,13,
604.3453 +	13,14,15,15,11,11,14,15,15,13,12,14,15,15,11,11,
604.3454 +	14,15,15,11,11,15,15,15,13,13,14,15,15,12,12,15,
604.3455 +	15,15,12,12,15,15,15,11,11,15,15,15,11,11,15,15,
604.3456 +	15,12,12,15,15,15,13,13,15,16,16,12,12,15,15,15,
604.3457 +	12,13,15,15,15,12,12,15,15,15,12,12,13,13,13,11,
604.3458 +	11,14,14,14,11,11,14,14,14,12,12,14,14,14,10,10,
604.3459 +	15,14,14,11,11,14,15,15,12,12,14,14,14,12,12,14,
604.3460 +	15,15,11,11,14,15,14,12,12,15,14,14,11,11,14,15,
604.3461 +	15,12,12,14,14,14,11,11,14,15,15,11,11,14,14,14,
604.3462 +	12,12,15,15,14,11,11,15,15,15,12,12,15,14,14,12,
604.3463 +	12,14,15,15,11,11,14,15,14,11,11,15,15,15,10,10,
604.3464 +	15,15,15,12,12,15,14,14,14,13,15,15,15,11,11,15,
604.3465 +	15,15,11,11,15,15,15,10,10,14,11,11,10,10,15, 9,
604.3466 +	 9,12,12,15,10,10,12,12,15,11,11,11,11,15,14,14,
604.3467 +	12,12,15,10,10,13,13,15,13,13,12,12,15, 9, 9,12,
604.3468 +	12,15,11,11,13,13,15,14,14,12,12,15,10,10,13,13,
604.3469 +	15,13,14,12,12,15, 9, 9,12,12,15,10,10,13,13,15,
604.3470 +	13,13,11,11,15,11,11,13,13,15,14,14,13,13,15,10,
604.3471 +	10,11,11,15,11,11,12,12,15,14,14,11,11,15,14,14,
604.3472 +	13,13,15,14,14,21,20,15,14,14,11,11,15,14,14,12,
604.3473 +	12,15,14,14,11,11,14,13,13,10,10,14,13,13,11,11,
604.3474 +	15,14,14,12,12,15,14,14,12,12,14,14,14,12,12,15,
604.3475 +	14,14,12,12,15,14,14,13,13,14,14,14,11,11,15,14,
604.3476 +	14,11,11,15,14,14,13,13,15,14,14,12,12,15,14,14,
604.3477 +	13,13,14,14,14,11,11,15,14,14,11,11,14,14,14,13,
604.3478 +	13,15,14,14,12,12,15,14,14,12,12,15,14,14,12,12,
604.3479 +	15,14,14,12,12,14,14,14,13,13,15,15,15,13,13,16,
604.3480 +	14,14,12,13,15,15,15,13,13,15,14,14,12,12,15,15,
604.3481 +	15,13,13,15,11,11,13,12,18,10,10,12,12,17,11,11,
604.3482 +	12,12,18,12,12,11,11,18,14,14,12,12,18,11,11,13,
604.3483 +	13,17,14,14,12,12,18,10,10,12,12,18,12,12,12,12,
604.3484 +	18,14,15,12,12,18,11,11,13,13,18,14,14,12,12,17,
604.3485 +	10,10,12,12,18,11,11,12,12,18,15,14,12,12,17,12,
604.3486 +	12,12,12,17,14,14,12,12,17,11,11,11,11,17,12,12,
604.3487 +	12,11,17,15,15,11,11,18,15,15,12,12,18,14,15,13,
604.3488 +	13,18,15,15,11,11,17,15,15,12,12,18,15,15,11,11,
604.3489 +	14, 9, 9,11,11,14,15,15,11,11,15,15,15,11,11,15,
604.3490 +	15,15,12,11,15,15,15,12,12,15,15,15,11,11,15,15,
604.3491 +	15,13,13,14,15,15,11,11,15,15,15,11,11,15,15,15,
604.3492 +	13,13,15,15,15,11,11,15,15,15,13,13,15,15,15,11,
604.3493 +	11,15,15,15,11,11,15,15,15,13,13,15,15,15,12,12,
604.3494 +	15,15,15,13,13,15,15,14,11,11,15,15,15,12,12,15,
604.3495 +	15,15,12,12,16,15,15,13,13,15,16,16,13,13,16,15,
604.3496 +	15,12,12,15,15,15,13,12,15,15,15,12,12,13,12,12,
604.3497 +	11,11,14,14,14,11,11,14,14,14,12,12,15,14,14,11,
604.3498 +	11,15,14,14,12,12,15,14,14,12,12,15,14,14,12,12,
604.3499 +	14,15,15,11,11,15,14,14,12,12,15,14,14,11,11,15,
604.3500 +	14,14,12,12,15,14,14,12,12,14,15,15,11,11,15,14,
604.3501 +	14,12,12,15,14,14,11,11,15,15,15,12,12,15,14,14,
604.3502 +	12,12,15,15,15,11,11,15,14,14,11,11,15,14,15,11,
604.3503 +	11,15,15,15,12,12,15,14,14,13,13,16,15,15,11,11,
604.3504 +	15,14,14,12,12,15,15,15,11,11,14,11,11, 9, 9,15,
604.3505 +	10,10,12,12,14,11,11,12,12,15,12,12,12,12,15,14,
604.3506 +	14,13,13,15,11,11,13,13,15,14,14,13,13,15,10,10,
604.3507 +	12,12,15,12,12,13,13,15,14,14,13,13,15,11,11,12,
604.3508 +	12,15,14,14,13,13,14,10,10,12,12,15,12,12,13,13,
604.3509 +	15,14,14,12,12,15,12,12,13,13,15,14,14,15,15,15,
604.3510 +	11,11,12,12,15,12,12,12,13,15,14,14,12,12,15,15,
604.3511 +	15,14,14,15,14,14,20,20,15,14,14,12,12,15,14,14,
604.3512 +	13,13,15,14,14,12,12,14,13,13,10,10,14,13,13,11,
604.3513 +	11,14,13,13,12,12,14,14,14,12,12,15,14,14,13,13,
604.3514 +	15,14,14,12,12,14,14,14,14,14,14,14,14,11,11,15,
604.3515 +	14,14,12,12,15,14,14,14,14,15,14,14,12,12,14,14,
604.3516 +	14,14,14,14,14,14,11,11,15,14,14,12,12,14,14,14,
604.3517 +	14,14,15,14,14,12,12,15,14,14,13,13,15,14,14,12,
604.3518 +	12,15,14,14,12,12,14,14,14,14,13,15,15,15,14,14,
604.3519 +	15,14,14,13,13,15,15,15,14,14,15,14,14,13,13,15,
604.3520 +	15,15,13,13,14,13,13,13,13,18,15,15,12,12,18,15,
604.3521 +	15,13,12,18,15,16,11,11,18,16,17,12,12,18,15,15,
604.3522 +	13,13,18,17,17,12,12,18,15,15,12,12,17,15,15,12,
604.3523 +	12,18,17,17,12,12,18,15,15,13,13,18,16,17,12,12,
604.3524 +	17,15,15,12,12,18,15,15,12,12,18,16,17,11,12,18,
604.3525 +	16,16,12,12,17,16,17,12,12,18,15,15,11,11,18,15,
604.3526 +	15,12,12,18,17,17,11,11,17,17,17,12,12,18,16,16,
604.3527 +	13,13,18,17,17,11,11,18,16,16,12,12,18,17,17,11,
604.3528 +	11,15,14,14,11,11,16,15,15,11,11,16,15,15,12,12,
604.3529 +	16,15,15,12,12,17,15,15,14,13,16,15,15,12,12,17,
604.3530 +	15,15,14,14,16,15,15,11,11,16,15,15,12,12,18,15,
604.3531 +	15,13,13,16,15,15,11,11,17,15,15,14,14,16,15,15,
604.3532 +	11,11,16,15,15,12,12,17,15,15,13,13,16,15,15,12,
604.3533 +	12,17,16,15,14,14,16,14,15,12,12,16,15,15,12,12,
604.3534 +	18,15,15,13,13,17,15,15,14,14,17,16,16,15,15,17,
604.3535 +	15,15,13,13,17,15,15,14,14,18,15,15,13,13,15,12,
604.3536 +	13,11,11,15,14,14,12,12,16,14,14,12,12,16,14,14,
604.3537 +	12,12,16,14,14,12,12,16,14,14,13,12,17,14,14,13,
604.3538 +	13,16,15,15,12,12,16,14,14,12,12,17,14,14,12,12,
604.3539 +	16,14,14,12,12,17,14,14,13,13,15,15,15,12,12,16,
604.3540 +	14,14,12,12,17,14,14,12,12,17,15,15,12,12,17,14,
604.3541 +	14,13,13,16,15,15,12,12,16,14,14,12,12,17,15,15,
604.3542 +	12,12,18,15,15,13,13,17,14,14,13,13,17,15,15,12,
604.3543 +	12,17,14,14,12,12,17,15,15,12,12,14,15,15, 9, 9,
604.3544 +	15,15,15,12,12,15,15,15,13,13,15,15,15,14,14,15,
604.3545 +	15,15,19,19,15,15,16,13,13,15,15,16,19,20,15,15,
604.3546 +	15,13,12,15,16,16,14,14,15,15,15,19,19,15,15,15,
604.3547 +	13,13,15,16,15,20,19,14,15,15,13,13,15,15,15,14,
604.3548 +	14,15,15,15,19,19,15,15,15,14,14,15,16,16,19,20,
604.3549 +	15,15,15,14,14,15,15,15,14,14,15,15,15,19,19,15,
604.3550 +	15,15,20,19,15,16,16,20,19,15,15,15,19,19,15,16,
604.3551 +	16,20,20,15,15,15,19,20,14,13,13,10,10,14,14,14,
604.3552 +	11,11,14,14,14,12,12,15,14,14,13,13,15,14,14,19,
604.3553 +	20,15,14,14,12,12,14,14,14,20,19,14,14,14,11,11,
604.3554 +	15,14,14,12,12,15,14,14,20,20,15,14,14,12,12,14,
604.3555 +	14,14,20,19,14,14,14,11,11,15,14,14,12,12,15,14,
604.3556 +	14,19,20,15,14,14,13,13,15,14,14,22,19,15,15,14,
604.3557 +	12,12,15,14,14,13,13,14,15,15,22,20,15,15,15,20,
604.3558 +	20,15,14,14,21,20,15,15,15,20,21,15,14,14,20,20,
604.3559 +	14,15,15,20,20,
604.3560 +};
604.3561 +
604.3562 +static const static_codebook _44p3_p4_1 = {
604.3563 +	5, 3125,
604.3564 +	(long *)_vq_lengthlist__44p3_p4_1,
604.3565 +	1, -533725184, 1611661312, 3, 0,
604.3566 +	(long *)_vq_quantlist__44p3_p4_1,
604.3567 +	0
604.3568 +};
604.3569 +
604.3570 +static const long _vq_quantlist__44p3_p5_0[] = {
604.3571 +	2,
604.3572 +	1,
604.3573 +	3,
604.3574 +	0,
604.3575 +	4,
604.3576 +};
604.3577 +
604.3578 +static const long _vq_lengthlist__44p3_p5_0[] = {
604.3579 +	 2, 6, 6,14,14, 6, 7, 7,14,14, 7, 7, 7,15,15, 0,
604.3580 +	12,12,15,15, 0,13,13,15,15, 7, 8, 8,15,15,10,10,
604.3581 +	10,16,16, 9, 8, 8,15,15, 0,13,13,18,17, 0,13,13,
604.3582 +	16,16, 8, 8, 8,15,15,12,11,11,16,16, 9, 8, 8,15,
604.3583 +	15, 0,13,13,18,18, 0,13,13,16,16, 0,14,14,17,17,
604.3584 +	 0,20, 0,19,20, 0,12,12,16,16, 0,16,16,20,22, 0,
604.3585 +	14,14,16,16, 0,14,14,17,17, 0,20,22,20,19, 0,13,
604.3586 +	13,15,16, 0,17,18, 0,21, 0,15,15,16,16, 5, 7, 7,
604.3587 +	13,13, 8, 9, 9,14,14,10,10,10,14,14, 0,20,22,18,
604.3588 +	18, 0,22,21,18,17, 9,10,10,14,14,12,12,12,17,17,
604.3589 +	12,10,10,14,14, 0, 0,20,17,17, 0,22,21,17,18,11,
604.3590 +	10,10,14,14,14,13,13,18,18,12,11,11,14,14, 0,22,
604.3591 +	21,18,19, 0,20, 0,17,17, 0,22, 0,18,18, 0, 0, 0,
604.3592 +	 0, 0, 0,20,20,17,17, 0,22, 0,22,21, 0,21, 0,19,
604.3593 +	18, 0,22,22,18,18, 0, 0, 0, 0, 0, 0,21, 0,17,17,
604.3594 +	 0,22, 0,20,20, 0, 0, 0,19,18, 6, 6, 6,12,12, 8,
604.3595 +	 6, 6,10,10, 8, 6, 6,13,12, 0,10,10,11,11, 0,11,
604.3596 +	11,13,13, 8, 7, 7,13,13,11, 9, 9,13,13,10, 6, 6,
604.3597 +	12,12, 0,10,10,14,14, 0,10,10,13,13, 9, 7, 7,13,
604.3598 +	13,12,10,10,13,13,10, 6, 6,12,12, 0,11,11,15,15,
604.3599 +	 0,10,10,13,13, 0,12,12,15,14, 0,19,20,16,17, 0,
604.3600 +	 9, 9,13,13, 0,14,14,20,21, 0,12,11,13,12, 0,12,
604.3601 +	12,15,14, 0,20,19,17,17, 0,10,10,12,13, 0,15,15,
604.3602 +	22,21, 0,12,12,12,13, 0,10,10,12,12, 0,11,11,15,
604.3603 +	15, 0,11,11,15,15, 0,15,15,22,22, 0,16,17, 0, 0,
604.3604 +	 0,11,11,15,15, 0,14,14,18,18, 0,11,11,16,16, 0,
604.3605 +	16,15, 0,21, 0,16,16, 0, 0, 0,12,12,15,15, 0,14,
604.3606 +	14,19,19, 0,11,11,15,15, 0,15,15,22, 0, 0,16,16,
604.3607 +	22, 0, 0,16,16, 0,21, 0, 0, 0, 0, 0, 0,15,15,19,
604.3608 +	20, 0,18,18, 0, 0, 0,17,17, 0, 0, 0,17,17, 0, 0,
604.3609 +	 0, 0, 0, 0, 0, 0,16,15,22,21, 0,20,20, 0, 0, 0,
604.3610 +	18,18, 0, 0, 0,10,10,12,12, 0,10,10,11,11, 0,11,
604.3611 +	11,12,12, 0,11,11, 9, 9, 0,13,12,12,12, 0,11,11,
604.3612 +	13,13, 0,13,13,12,12, 0,10,10,12,12, 0,13,12,13,
604.3613 +	13, 0,12,12,12,12, 0,11,11,13,13, 0,13,13,12,12,
604.3614 +	 0,10,10,12,12, 0,13,13,14,13, 0,12,12,12,12, 0,
604.3615 +	14,13,13,14, 0,20,21,15,15, 0,11,11,12,12, 0,15,
604.3616 +	16,20,20, 0,12,13,10,10, 0,13,13,14,13, 0,20,20,
604.3617 +	15,15, 0,11,11,12,12, 0,16,17,21,21, 0,13,13,11,
604.3618 +	11, 6, 7, 7,16,15,11, 9, 9,14,15,12, 9, 9,16,16,
604.3619 +	 0,13,13,15,15, 0,14,14,17,17,10, 9, 9,16,16,14,
604.3620 +	12,12,16,16,12, 9, 9,15,15, 0,13,13,17,18, 0,13,
604.3621 +	13,15,15,12,10,10,17,17,15,12,12,17,17,13, 9, 9,
604.3622 +	16,16, 0,13,13,18,19, 0,14,14,16,16, 0,15,15,18,
604.3623 +	18, 0, 0, 0,20,19, 0,12,12,17,16, 0,16,17, 0,21,
604.3624 +	 0,14,15,16,16, 0,15,15,18,18, 0, 0,22,19,21, 0,
604.3625 +	13,13,16,16, 0,18,17,22,22, 0,15,15,16,16, 7, 7,
604.3626 +	 7,13,13,11,10,10,15,15,12,10,10,14,14, 0,21, 0,
604.3627 +	18,17, 0,21,22,18,18,11,10,10,15,15,14,12,12,17,
604.3628 +	17,14,11,11,14,14, 0,21,20,18,18, 0,22,21,18,17,
604.3629 +	12,11,10,16,16,16,14,14,17,19,14,11,11,15,15, 0,
604.3630 +	 0,22,19,19, 0,21,22,18,18, 0,21, 0,18,19, 0, 0,
604.3631 +	 0,22, 0, 0,22,21,17,17, 0, 0, 0,20,22, 0, 0,21,
604.3632 +	18,18, 0, 0, 0,19,20, 0, 0, 0, 0, 0, 0, 0,21,17,
604.3633 +	17, 0, 0, 0,22,21, 0, 0, 0,19,19,10, 9, 9,14,13,
604.3634 +	13,10,10,12,12,13,10,10,14,14, 0,13,13,12,12, 0,
604.3635 +	15,14,16,15,13,10,10,14,14,15,12,12,14,14,15,10,
604.3636 +	10,14,14, 0,14,14,15,15, 0,14,13,14,14,13,10,10,
604.3637 +	15,15,17,13,13,15,15,14,10,10,14,14, 0,14,14,15,
604.3638 +	16, 0,14,14,15,15, 0,15,15,16,16, 0,21,22,17,18,
604.3639 +	 0,12,12,14,14, 0,17,17,20,21, 0,14,14,14,14, 0,
604.3640 +	15,15,16,16, 0,21,22,18,18, 0,13,13,14,14, 0,18,
604.3641 +	18,22, 0, 0,15,15,14,14, 0,11,11,13,13, 0,12,12,
604.3642 +	16,15, 0,12,12,16,16, 0,16,16, 0, 0, 0,16,17, 0,
604.3643 +	22, 0,12,12,16,16, 0,14,14,17,18, 0,11,11,16,16,
604.3644 +	 0,15,15, 0,21, 0,16,16,21,22, 0,12,12,16,16, 0,
604.3645 +	15,15,19,19, 0,12,12,17,16, 0,16,16,21,22, 0,16,
604.3646 +	16, 0, 0, 0,17,17, 0,22, 0, 0, 0, 0, 0, 0,15,15,
604.3647 +	19,20, 0,17,19, 0, 0, 0,17,17,22, 0, 0,17,17, 0,
604.3648 +	22, 0, 0, 0, 0, 0, 0,15,15,21, 0, 0,19,20, 0, 0,
604.3649 +	 0,19,18,22, 0, 0,11,12,14,14, 0,11,11,14,14, 0,
604.3650 +	12,12,15,15, 0,13,13,13,13, 0,14,14,16,16, 0,12,
604.3651 +	12,15,15, 0,14,14,16,15, 0,11,11,15,15, 0,13,13,
604.3652 +	16,16, 0,13,13,15,15, 0,12,12,15,15, 0,15,14,16,
604.3653 +	16, 0,11,11,15,15, 0,14,14,17,17, 0,13,13,15,15,
604.3654 +	 0,15,15,16,16, 0, 0, 0,18,18, 0,12,12,14,14, 0,
604.3655 +	16,16,22, 0, 0,14,14,15,15, 0,15,15,16,17, 0,21,
604.3656 +	22,18,18, 0,13,13,15,14, 0,18,17,22, 0, 0,14,14,
604.3657 +	15,15, 8, 8, 8,16,15,12,10,10,16,15,12,10,10,16,
604.3658 +	16, 0,14,14,16,17, 0,14,14,17,16,12,10,10,17,18,
604.3659 +	14,12,12,18,18,14,10,10,16,16, 0,14,14,18,18, 0,
604.3660 +	14,14,16,16,12, 9, 9,16,16,17,13,13,16,17,14, 9,
604.3661 +	 9,15,15, 0,14,14,18,19, 0,13,13,15,15, 0,15,15,
604.3662 +	18,19, 0, 0, 0,22,21, 0,13,13,16,16, 0,16,16,22,
604.3663 +	 0, 0,15,15,16,16, 0,14,14,18,17, 0, 0, 0,20, 0,
604.3664 +	 0,13,13,16,16, 0,18,18, 0, 0, 0,15,15,16,16, 8,
604.3665 +	 7, 7,13,13,12,10,10,15,15,12,10,10,14,14, 0,22,
604.3666 +	22,19,18, 0, 0, 0,18,18,12,10,10,15,15,14,13,13,
604.3667 +	17,17,14,11,11,15,15, 0,19,20,18,18, 0,22,21,17,
604.3668 +	18,13,11,11,15,15,16,13,13,18,18,14,11,11,14,15,
604.3669 +	 0,22,21,20,19, 0,22,21,17,17, 0, 0,22,19,18, 0,
604.3670 +	 0, 0, 0, 0, 0,22,20,17,17, 0, 0, 0,21,20, 0, 0,
604.3671 +	 0,19,17, 0, 0,22,19,19, 0, 0, 0, 0, 0, 0,22,20,
604.3672 +	18,17, 0, 0, 0, 0, 0, 0, 0, 0,18,18, 0,10,10,14,
604.3673 +	14, 0,11,11,14,14, 0,11,11,15,15, 0,14,14,14,14,
604.3674 +	 0,15,15,16,16, 0,11,11,16,16, 0,13,13,16,16, 0,
604.3675 +	11,11,15,15, 0,14,14,16,16, 0,14,14,15,15, 0,11,
604.3676 +	11,15,15, 0,13,13,15,15, 0,10,10,15,15, 0,15,15,
604.3677 +	17,17, 0,14,14,14,14, 0,16,16,16,16, 0, 0,22,19,
604.3678 +	19, 0,13,13,14,14, 0,17,17, 0, 0, 0,15,15,14,14,
604.3679 +	 0,16,16,17,17, 0, 0,22,18,18, 0,13,13,14,14, 0,
604.3680 +	21,18, 0, 0, 0,15,15,14,14, 0,11,11,13,13, 0,12,
604.3681 +	12,15,15, 0,12,12,16,15, 0,16,16, 0, 0, 0,17,17,
604.3682 +	22,22, 0,12,12,16,16, 0,14,14,18,18, 0,11,12,16,
604.3683 +	16, 0,15,16, 0,21, 0,16,16,22,21, 0,12,12,16,16,
604.3684 +	 0,15,15,19,20, 0,11,12,16,16, 0,15,15,20,22, 0,
604.3685 +	16,16, 0,22, 0,17,17,22, 0, 0, 0, 0, 0, 0, 0,15,
604.3686 +	15,21,22, 0,19,18, 0, 0, 0,17,17, 0, 0, 0,17,17,
604.3687 +	 0,22, 0, 0, 0, 0, 0, 0,16,15,22, 0, 0,19,19, 0,
604.3688 +	 0, 0,17,18, 0, 0, 0,12,12,15,15, 0,12,12,15,15,
604.3689 +	 0,12,12,15,15, 0,13,13,14,14, 0,15,15,16,17, 0,
604.3690 +	12,12,16,16, 0,14,14,16,16, 0,12,11,15,16, 0,14,
604.3691 +	14,16,17, 0,14,14,16,16, 0,13,12,16,16, 0,15,15,
604.3692 +	16,16, 0,11,11,15,15, 0,14,14,16,16, 0,14,14,15,
604.3693 +	15, 0,15,15,18,17, 0, 0,22, 0,20, 0,13,13,15,15,
604.3694 +	 0,16,17,22,22, 0,14,14,15,15, 0,15,15,17,18, 0,
604.3695 +	20, 0,19,19, 0,13,13,15,15, 0,18,18,22, 0, 0,14,
604.3696 +	14,15,15, 0,11,11,16,16, 0,14,14,17,16, 0,13,13,
604.3697 +	17,17, 0,16,16,17,17, 0,17,17,18,19, 0,12,12,16,
604.3698 +	17, 0,15,15,18,18, 0,12,12,16,16, 0,16,16,19,18,
604.3699 +	 0,16,16,17,16, 0,12,13,17,17, 0,17,16,18,17, 0,
604.3700 +	13,12,16,16, 0,16,16,18,19, 0,16,16,16,17, 0,16,
604.3701 +	16,18,18, 0,22, 0,22,22, 0,13,13,16,16, 0,19,18,
604.3702 +	22,20, 0,16,15,16,16, 0,16,17,18,18, 0, 0, 0,22,
604.3703 +	20, 0,14,14,16,16, 0,19,19, 0, 0, 0,16,16,16,16,
604.3704 +	 0, 9, 9,13,13, 0,13,13,15,15, 0,14,14,15,15, 0,
604.3705 +	 0,22,17,18, 0,22, 0,18,19, 0,12,12,15,15, 0,15,
604.3706 +	16,17,17, 0,14,14,14,14, 0,22, 0,18,18, 0,21,22,
604.3707 +	17,17, 0,13,13,15,15, 0,17,17,17,18, 0,14,14,15,
604.3708 +	15, 0,22,21,21,19, 0,20,21,17,17, 0,21,21,19,18,
604.3709 +	 0, 0, 0, 0, 0, 0,21,21,17,17, 0, 0, 0,22,22, 0,
604.3710 +	 0,22,19,18, 0, 0,21,19,18, 0, 0, 0, 0,22, 0,19,
604.3711 +	20,17,17, 0, 0, 0, 0,22, 0, 0, 0,19,18, 0,19,19,
604.3712 +	15,16, 0,21,19,16,17, 0, 0,21,17,17, 0, 0,22,17,
604.3713 +	17, 0,22,22,18,19, 0,20,20,16,16, 0, 0,22,18,18,
604.3714 +	 0,20,19,16,17, 0,22,21,20,19, 0, 0,21,17,17, 0,
604.3715 +	21,20,17,17, 0, 0, 0,18,18, 0,19,19,17,16, 0,22,
604.3716 +	 0,19,19, 0,21,22,17,18, 0, 0,22,19,18, 0, 0, 0,
604.3717 +	19,20, 0,19,19,16,16, 0,22,22,22, 0, 0,20,22,16,
604.3718 +	16, 0,22,20,18,19, 0, 0, 0,20,19, 0,20,20,16,16,
604.3719 +	 0, 0, 0, 0, 0, 0,22,20,17,16, 0,11,11,13,13, 0,
604.3720 +	14,13,15,15, 0,13,13,16,15, 0,18,17,21, 0, 0,18,
604.3721 +	18,21, 0, 0,12,12,15,15, 0,15,16,17,18, 0,12,12,
604.3722 +	15,15, 0,17,17,22,20, 0,17,18,22, 0, 0,12,12,17,
604.3723 +	16, 0,16,17,19,19, 0,13,13,16,16, 0,17,17, 0,22,
604.3724 +	 0,17,17, 0,21, 0,18,18,20,22, 0, 0, 0, 0, 0, 0,
604.3725 +	15,15,21,20, 0,20,19, 0, 0, 0,18,18,22, 0, 0,17,
604.3726 +	17,22, 0, 0, 0, 0, 0, 0, 0,15,16,20,22, 0,20,21,
604.3727 +	 0, 0, 0,19,18, 0, 0, 0,15,15,19,19, 0,17,16,20,
604.3728 +	20, 0,16,17,20,21, 0,18,17, 0, 0, 0,19,19, 0, 0,
604.3729 +	 0,15,15,21,19, 0,19,19, 0, 0, 0,15,15,22,22, 0,
604.3730 +	18,18, 0,22, 0,17,18,22,21, 0,15,15,20,19, 0,19,
604.3731 +	19, 0, 0, 0,15,15,20,22, 0,18,19,20, 0, 0,18,17,
604.3732 +	21,21, 0,18,18,19,22, 0, 0, 0, 0, 0, 0,15,15,20,
604.3733 +	19, 0,19,19, 0, 0, 0,18,18,21,22, 0,18,18,22, 0,
604.3734 +	 0, 0, 0, 0, 0, 0,15,15,19,20, 0,21,21, 0, 0, 0,
604.3735 +	17,17,20,20, 0,12,12,17,17, 0,14,14,16,17, 0,13,
604.3736 +	14,17,17, 0,16,16,17,17, 0,17,17,17,19, 0,13,13,
604.3737 +	17,17, 0,16,16,18,18, 0,13,13,16,16, 0,16,16,18,
604.3738 +	18, 0,16,16,17,17, 0,13,13,17,17, 0,17,17,18,17,
604.3739 +	 0,12,12,15,16, 0,17,18,19,20, 0,16,16,16,16, 0,
604.3740 +	17,16,18,19, 0, 0,22,21,22, 0,14,14,16,16, 0,19,
604.3741 +	19, 0, 0, 0,16,16,16,16, 0,16,16,18,17, 0, 0,22,
604.3742 +	21,21, 0,14,14,16,16, 0,22,20,22, 0, 0,16,16,15,
604.3743 +	15, 0, 9, 9,13,13, 0,14,14,15,15, 0,14,14,14,14,
604.3744 +	 0,22,22,18,18, 0, 0,22,18,18, 0,12,12,15,15, 0,
604.3745 +	16,16,18,17, 0,14,14,14,14, 0,20,21,18,18, 0,22,
604.3746 +	21,17,17, 0,13,13,15,15, 0,17,17,18,18, 0,14,14,
604.3747 +	14,14, 0, 0,21,18,19, 0, 0,22,17,17, 0,22,22,19,
604.3748 +	18, 0, 0, 0, 0, 0, 0,19,21,17,17, 0, 0, 0,22,20,
604.3749 +	 0, 0,21,18,19, 0, 0,22,18,18, 0, 0, 0, 0,22, 0,
604.3750 +	20,22,17,17, 0, 0, 0,20,22, 0, 0, 0,18,18, 0,19,
604.3751 +	21,16,16, 0,20,22,16,17, 0,20, 0,17,17, 0,22, 0,
604.3752 +	18,17, 0,21, 0,18,19, 0,20,20,17,17, 0,22, 0,18,
604.3753 +	18, 0,21,20,17,17, 0, 0,20,20,19, 0, 0,21,18,17,
604.3754 +	 0,21,21,17,17, 0,22, 0,18,17, 0,19,19,17,17, 0,
604.3755 +	 0,22,20,21, 0, 0,21,17,17, 0,22, 0,18,18, 0, 0,
604.3756 +	 0,20,22, 0,20,19,16,16, 0, 0, 0, 0, 0, 0,22,22,
604.3757 +	17,17, 0,22, 0,18,19, 0, 0, 0,21,20, 0,19,21,16,
604.3758 +	17, 0, 0, 0, 0, 0, 0,22,22,17,16, 0,11,11,13,13,
604.3759 +	 0,13,13,15,15, 0,13,13,15,15, 0,17,17,22,21, 0,
604.3760 +	18,18,22, 0, 0,12,13,16,15, 0,15,16,18,18, 0,13,
604.3761 +	13,16,16, 0,17,17, 0,22, 0,17,17,22,22, 0,13,13,
604.3762 +	16,16, 0,16,16,19,18, 0,13,13,16,16, 0,18,17, 0,
604.3763 +	20, 0,18,17,20, 0, 0,17,17,21, 0, 0, 0, 0, 0, 0,
604.3764 +	 0,15,15,21,22, 0,19,20, 0, 0, 0,18,18, 0, 0, 0,
604.3765 +	18,17, 0, 0, 0, 0, 0, 0, 0, 0,16,16,22,22, 0,20,
604.3766 +	20, 0, 0, 0,21,19, 0, 0, 0,15,15,20,19, 0,16,16,
604.3767 +	22,20, 0,17,17, 0,22, 0,18,18, 0,22, 0,19,17, 0,
604.3768 +	 0, 0,15,16,22,20, 0,18,19, 0, 0, 0,16,16,22,20,
604.3769 +	 0,18,18, 0,22, 0,18,18,22, 0, 0,16,16,21,20, 0,
604.3770 +	19,20, 0,22, 0,16,16, 0,22, 0,18,18, 0,22, 0,18,
604.3771 +	18, 0,21, 0,19,18, 0,22, 0, 0, 0, 0, 0, 0,16,16,
604.3772 +	21,20, 0,20, 0, 0, 0, 0,18,18,21, 0, 0,18,18, 0,
604.3773 +	 0, 0, 0, 0, 0, 0, 0,16,16,21,19, 0, 0, 0, 0, 0,
604.3774 +	 0,18,18, 0,21,
604.3775 +};
604.3776 +
604.3777 +static const static_codebook _44p3_p5_0 = {
604.3778 +	5, 3125,
604.3779 +	(long *)_vq_lengthlist__44p3_p5_0,
604.3780 +	1, -528744448, 1616642048, 3, 0,
604.3781 +	(long *)_vq_quantlist__44p3_p5_0,
604.3782 +	0
604.3783 +};
604.3784 +
604.3785 +static const long _vq_quantlist__44p3_p5_1[] = {
604.3786 +	3,
604.3787 +	2,
604.3788 +	4,
604.3789 +	1,
604.3790 +	5,
604.3791 +	0,
604.3792 +	6,
604.3793 +};
604.3794 +
604.3795 +static const long _vq_lengthlist__44p3_p5_1[] = {
604.3796 +	 2, 3, 3, 3, 3, 3, 3,
604.3797 +};
604.3798 +
604.3799 +static const static_codebook _44p3_p5_1 = {
604.3800 +	1, 7,
604.3801 +	(long *)_vq_lengthlist__44p3_p5_1,
604.3802 +	1, -533200896, 1611661312, 3, 0,
604.3803 +	(long *)_vq_quantlist__44p3_p5_1,
604.3804 +	0
604.3805 +};
604.3806 +
604.3807 +static const long _vq_quantlist__44p3_p6_0[] = {
604.3808 +	1,
604.3809 +	0,
604.3810 +	2,
604.3811 +};
604.3812 +
604.3813 +static const long _vq_lengthlist__44p3_p6_0[] = {
604.3814 +	 1, 6, 6, 7, 7, 7, 7, 8, 8, 7, 9, 9,11,11,11, 9,
604.3815 +	 8, 8, 8, 9, 9,12,11,11, 9, 8, 8, 6, 7, 7,10,11,
604.3816 +	10,10,10,10,11,11,10,14,13,14,12,11,11,11,11,11,
604.3817 +	15,14,14,13,12,12, 5, 6, 6, 8, 5, 5, 8, 7, 7, 8,
604.3818 +	 8, 8,12,10,10, 9, 7, 7, 9, 7, 8,12,10,10,10, 7,
604.3819 +	 7, 7, 8, 8,12,10,10,12,10,10,11,10,10,15,13,13,
604.3820 +	13,10,10,11,10,10,16,13,14,14,10,10, 7, 7, 7,12,
604.3821 +	11,11,12,11,11,11,11,11,16,15,15,14,12,12,12,11,
604.3822 +	11,16,15,16,14,12,12,10, 9, 9,14,11,11,13,11,11,
604.3823 +	12,11,11,16,14,14,14,11,11,12,11,11,17,15,15,14,
604.3824 +	11,11, 7, 8, 8,12,11,11,12,10,10,12,10,10,16,14,
604.3825 +	13,14,10,10,12,10,10,17,14,14,14,10,10, 8, 7, 7,
604.3826 +	13,11,11,12,11,11,12,11,11,16,15,14,14,12,12,12,
604.3827 +	11,11,16,15,14,15,12,12,11,10,10,13,11,11,13,12,
604.3828 +	11,13,11,11,17,14,14,14,11,11,13,11,11,17,14,15,
604.3829 +	14,11,11,
604.3830 +};
604.3831 +
604.3832 +static const static_codebook _44p3_p6_0 = {
604.3833 +	5, 243,
604.3834 +	(long *)_vq_lengthlist__44p3_p6_0,
604.3835 +	1, -527106048, 1620377600, 2, 0,
604.3836 +	(long *)_vq_quantlist__44p3_p6_0,
604.3837 +	0
604.3838 +};
604.3839 +
604.3840 +static const long _vq_quantlist__44p3_p6_1[] = {
604.3841 +	1,
604.3842 +	0,
604.3843 +	2,
604.3844 +};
604.3845 +
604.3846 +static const long _vq_lengthlist__44p3_p6_1[] = {
604.3847 +	 2, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,
604.3848 +	 7, 7, 8, 8, 8, 9, 9, 9, 9, 7, 8, 6, 7, 7, 8, 8,
604.3849 +	 8, 8, 8, 8, 9, 8, 8,10, 9, 9,10, 8, 8,10, 8, 8,
604.3850 +	10, 9, 9,10, 8, 8, 6, 6, 6, 8, 6, 6, 8, 7, 7, 8,
604.3851 +	 7, 7,10, 8, 8, 9, 7, 7, 9, 7, 7,10, 8, 9, 9, 7,
604.3852 +	 7, 7, 7, 7,10, 8, 8,11, 8, 8,10, 8, 8,12, 9, 9,
604.3853 +	12, 8, 8,11, 9, 9,12, 9, 9,11, 8, 8, 7, 7, 7,10,
604.3854 +	 9, 9,10, 9, 9,10, 9, 9,11,10,10,10, 9, 9,11, 9,
604.3855 +	 9,11,10,10,11, 9, 9, 9, 8, 8,10, 9, 9,10, 9, 9,
604.3856 +	11, 9, 9,11,10,10,11, 9, 9,11, 9, 9,11,10,10,11,
604.3857 +	 9, 9, 8, 8, 8,11, 9, 9,11, 9, 9,11, 9, 9,12, 9,
604.3858 +	 9,12, 8, 8,12, 9, 9,12, 9, 9,12, 8, 8, 8, 7, 7,
604.3859 +	10, 9, 9,10, 9, 9,11, 9, 9,11,11,11,11, 9, 9,11,
604.3860 +	10,10,11,11,11,11, 9, 9,10, 9, 9,11, 9, 9,11, 9,
604.3861 +	10,11,10, 9,11,10,10,11, 9, 9,11, 9,10,11,10,10,
604.3862 +	11, 9, 9,
604.3863 +};
604.3864 +
604.3865 +static const static_codebook _44p3_p6_1 = {
604.3866 +	5, 243,
604.3867 +	(long *)_vq_lengthlist__44p3_p6_1,
604.3868 +	1, -530841600, 1616642048, 2, 0,
604.3869 +	(long *)_vq_quantlist__44p3_p6_1,
604.3870 +	0
604.3871 +};
604.3872 +
604.3873 +static const long _vq_quantlist__44p3_p7_0[] = {
604.3874 +	1,
604.3875 +	0,
604.3876 +	2,
604.3877 +};
604.3878 +
604.3879 +static const long _vq_lengthlist__44p3_p7_0[] = {
604.3880 +	 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.3881 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3882 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3883 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3884 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3885 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3886 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3887 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3888 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3889 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3890 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3891 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3892 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3893 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3894 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3895 +	 9, 9, 9,
604.3896 +};
604.3897 +
604.3898 +static const static_codebook _44p3_p7_0 = {
604.3899 +	5, 243,
604.3900 +	(long *)_vq_lengthlist__44p3_p7_0,
604.3901 +	1, -513979392, 1633504256, 2, 0,
604.3902 +	(long *)_vq_quantlist__44p3_p7_0,
604.3903 +	0
604.3904 +};
604.3905 +
604.3906 +static const long _vq_quantlist__44p3_p7_1[] = {
604.3907 +	1,
604.3908 +	0,
604.3909 +	2,
604.3910 +};
604.3911 +
604.3912 +static const long _vq_lengthlist__44p3_p7_1[] = {
604.3913 +	 1, 9, 9, 6, 9, 9, 5, 9, 9, 8, 9, 9, 9, 9, 9, 9,
604.3914 +	 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9,
604.3915 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3916 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9,
604.3917 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3918 +	 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3919 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3920 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3921 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3922 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3923 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3924 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9,
604.3925 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.3926 +	 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
604.3927 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.3928 +	10,10,10,
604.3929 +};
604.3930 +
604.3931 +static const static_codebook _44p3_p7_1 = {
604.3932 +	5, 243,
604.3933 +	(long *)_vq_lengthlist__44p3_p7_1,
604.3934 +	1, -516716544, 1630767104, 2, 0,
604.3935 +	(long *)_vq_quantlist__44p3_p7_1,
604.3936 +	0
604.3937 +};
604.3938 +
604.3939 +static const long _vq_quantlist__44p3_p7_2[] = {
604.3940 +	12,
604.3941 +	11,
604.3942 +	13,
604.3943 +	10,
604.3944 +	14,
604.3945 +	9,
604.3946 +	15,
604.3947 +	8,
604.3948 +	16,
604.3949 +	7,
604.3950 +	17,
604.3951 +	6,
604.3952 +	18,
604.3953 +	5,
604.3954 +	19,
604.3955 +	4,
604.3956 +	20,
604.3957 +	3,
604.3958 +	21,
604.3959 +	2,
604.3960 +	22,
604.3961 +	1,
604.3962 +	23,
604.3963 +	0,
604.3964 +	24,
604.3965 +};
604.3966 +
604.3967 +static const long _vq_lengthlist__44p3_p7_2[] = {
604.3968 +	 1, 3, 2, 5, 4, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
604.3969 +	12,13,13,14,14,15,15,15,15,
604.3970 +};
604.3971 +
604.3972 +static const static_codebook _44p3_p7_2 = {
604.3973 +	1, 25,
604.3974 +	(long *)_vq_lengthlist__44p3_p7_2,
604.3975 +	1, -518864896, 1620639744, 5, 0,
604.3976 +	(long *)_vq_quantlist__44p3_p7_2,
604.3977 +	0
604.3978 +};
604.3979 +
604.3980 +static const long _vq_quantlist__44p3_p7_3[] = {
604.3981 +	12,
604.3982 +	11,
604.3983 +	13,
604.3984 +	10,
604.3985 +	14,
604.3986 +	9,
604.3987 +	15,
604.3988 +	8,
604.3989 +	16,
604.3990 +	7,
604.3991 +	17,
604.3992 +	6,
604.3993 +	18,
604.3994 +	5,
604.3995 +	19,
604.3996 +	4,
604.3997 +	20,
604.3998 +	3,
604.3999 +	21,
604.4000 +	2,
604.4001 +	22,
604.4002 +	1,
604.4003 +	23,
604.4004 +	0,
604.4005 +	24,
604.4006 +};
604.4007 +
604.4008 +static const long _vq_lengthlist__44p3_p7_3[] = {
604.4009 +	 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.4010 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.4011 +};
604.4012 +
604.4013 +static const static_codebook _44p3_p7_3 = {
604.4014 +	1, 25,
604.4015 +	(long *)_vq_lengthlist__44p3_p7_3,
604.4016 +	1, -529006592, 1611661312, 5, 0,
604.4017 +	(long *)_vq_quantlist__44p3_p7_3,
604.4018 +	0
604.4019 +};
604.4020 +
604.4021 +static const long _huff_lengthlist__44p3_short[] = {
604.4022 +	 4, 5,16, 9, 9,12,17,18, 4, 2,18, 6, 5, 9,13,15,
604.4023 +	10, 7, 7, 6, 7, 9,13,13, 8, 5, 6, 5, 5, 7,11,12,
604.4024 +	 8, 4, 7, 4, 3, 6,10,12,11, 8, 9, 7, 6, 8,11,12,
604.4025 +	15,13,13,11, 9, 7,10,12,16,12,16,12, 6, 5, 8,11,
604.4026 +};
604.4027 +
604.4028 +static const static_codebook _huff_book__44p3_short = {
604.4029 +	2, 64,
604.4030 +	(long *)_huff_lengthlist__44p3_short,
604.4031 +	0, 0, 0, 0, 0,
604.4032 +	NULL,
604.4033 +	0
604.4034 +};
604.4035 +
604.4036 +static const long _vq_quantlist__44p4_l0_0[] = {
604.4037 +	6,
604.4038 +	5,
604.4039 +	7,
604.4040 +	4,
604.4041 +	8,
604.4042 +	3,
604.4043 +	9,
604.4044 +	2,
604.4045 +	10,
604.4046 +	1,
604.4047 +	11,
604.4048 +	0,
604.4049 +	12,
604.4050 +};
604.4051 +
604.4052 +static const long _vq_lengthlist__44p4_l0_0[] = {
604.4053 +	 1, 4, 4, 8, 8, 9, 8, 9, 9,10,10,10,10, 4, 6, 5,
604.4054 +	 8, 7, 9, 9, 9, 9,10, 9,10,10, 4, 5, 6, 7, 8, 9,
604.4055 +	 9, 9, 9, 9,10, 9,10, 8, 9, 8, 9, 8,10, 9,11, 9,
604.4056 +	12,10,11,10, 8, 8, 9, 8, 9, 9,10, 9,11,10,11,10,
604.4057 +	12, 9,10,10,11,10,11,11,12,11,12,12,12,12, 9,10,
604.4058 +	10,11,11,11,11,11,12,12,12,12,12,10,11,11,12,12,
604.4059 +	12,12,12,12,12,12,12,12,10,11,11,12,12,12,12,12,
604.4060 +	12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,13,
604.4061 +	12,12,11,12,11,12,12,12,12,12,12,12,12,12,12,12,
604.4062 +	12,12,12,12,12,13,12,12,12,12,12,12,11,13,12,12,
604.4063 +	12,13,12,12,12,12,12,12,12,
604.4064 +};
604.4065 +
604.4066 +static const static_codebook _44p4_l0_0 = {
604.4067 +	2, 169,
604.4068 +	(long *)_vq_lengthlist__44p4_l0_0,
604.4069 +	1, -526516224, 1616117760, 4, 0,
604.4070 +	(long *)_vq_quantlist__44p4_l0_0,
604.4071 +	0
604.4072 +};
604.4073 +
604.4074 +static const long _vq_quantlist__44p4_l0_1[] = {
604.4075 +	2,
604.4076 +	1,
604.4077 +	3,
604.4078 +	0,
604.4079 +	4,
604.4080 +};
604.4081 +
604.4082 +static const long _vq_lengthlist__44p4_l0_1[] = {
604.4083 +	 3, 4, 4, 5, 5, 4, 4, 5, 5, 5, 4, 5, 4, 5, 5, 5,
604.4084 +	 5, 6, 5, 6, 5, 6, 5, 6, 5,
604.4085 +};
604.4086 +
604.4087 +static const static_codebook _44p4_l0_1 = {
604.4088 +	2, 25,
604.4089 +	(long *)_vq_lengthlist__44p4_l0_1,
604.4090 +	1, -533725184, 1611661312, 3, 0,
604.4091 +	(long *)_vq_quantlist__44p4_l0_1,
604.4092 +	0
604.4093 +};
604.4094 +
604.4095 +static const long _vq_quantlist__44p4_l1_0[] = {
604.4096 +	1,
604.4097 +	0,
604.4098 +	2,
604.4099 +};
604.4100 +
604.4101 +static const long _vq_lengthlist__44p4_l1_0[] = {
604.4102 +	 1, 4, 4, 4, 4, 4, 4, 4, 4,
604.4103 +};
604.4104 +
604.4105 +static const static_codebook _44p4_l1_0 = {
604.4106 +	2, 9,
604.4107 +	(long *)_vq_lengthlist__44p4_l1_0,
604.4108 +	1, -516716544, 1630767104, 2, 0,
604.4109 +	(long *)_vq_quantlist__44p4_l1_0,
604.4110 +	0
604.4111 +};
604.4112 +
604.4113 +static const long _huff_lengthlist__44p4_lfe[] = {
604.4114 +	 1, 3, 2, 3,
604.4115 +};
604.4116 +
604.4117 +static const static_codebook _huff_book__44p4_lfe = {
604.4118 +	2, 4,
604.4119 +	(long *)_huff_lengthlist__44p4_lfe,
604.4120 +	0, 0, 0, 0, 0,
604.4121 +	NULL,
604.4122 +	0
604.4123 +};
604.4124 +
604.4125 +static const long _huff_lengthlist__44p4_long[] = {
604.4126 +	 3, 5,13, 9, 9,12,16,18, 4, 2,20, 6, 7,10,15,20,
604.4127 +	10, 7, 5, 5, 6, 8,10,13, 8, 5, 5, 3, 5, 7,10,11,
604.4128 +	 9, 7, 6, 5, 5, 7, 9, 9,11,10, 8, 7, 6, 6, 8, 8,
604.4129 +	15,15,10,10, 9, 7, 8, 9,17,19,13,12,10, 8, 9, 9,
604.4130 +};
604.4131 +
604.4132 +static const static_codebook _huff_book__44p4_long = {
604.4133 +	2, 64,
604.4134 +	(long *)_huff_lengthlist__44p4_long,
604.4135 +	0, 0, 0, 0, 0,
604.4136 +	NULL,
604.4137 +	0
604.4138 +};
604.4139 +
604.4140 +static const long _vq_quantlist__44p4_p1_0[] = {
604.4141 +	1,
604.4142 +	0,
604.4143 +	2,
604.4144 +};
604.4145 +
604.4146 +static const long _vq_lengthlist__44p4_p1_0[] = {
604.4147 +	 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4148 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4149 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4150 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4151 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4152 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4153 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4154 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4155 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4156 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4157 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4158 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4159 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4160 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4161 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4162 +	 0, 0, 0,
604.4163 +};
604.4164 +
604.4165 +static const static_codebook _44p4_p1_0 = {
604.4166 +	5, 243,
604.4167 +	(long *)_vq_lengthlist__44p4_p1_0,
604.4168 +	1, -535822336, 1611661312, 2, 0,
604.4169 +	(long *)_vq_quantlist__44p4_p1_0,
604.4170 +	0
604.4171 +};
604.4172 +
604.4173 +static const long _vq_quantlist__44p4_p2_0[] = {
604.4174 +	2,
604.4175 +	1,
604.4176 +	3,
604.4177 +	0,
604.4178 +	4,
604.4179 +};
604.4180 +
604.4181 +static const long _vq_lengthlist__44p4_p2_0[] = {
604.4182 +	 3, 9, 9, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0,
604.4183 +	12,12, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0, 0,
604.4184 +	 0, 0, 0, 0, 9, 9, 0, 0, 0,11,11, 0, 0, 0, 0, 0,
604.4185 +	 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0,
604.4186 +	 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0,12,12, 0, 0,
604.4187 +	 0, 0, 0, 0, 0, 0,11,11, 0, 0, 0,12,12, 0, 0, 0,
604.4188 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4189 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
604.4190 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4191 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4192 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4193 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4194 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4195 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4196 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4197 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0,
604.4198 +	 5, 5, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0,
604.4199 +	 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
604.4200 +	 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0,
604.4201 +	 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 7, 7, 0, 0,
604.4202 +	 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0,
604.4203 +	 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4204 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4205 +	 0, 0, 0, 0, 0, 0, 0, 0,11,11, 0, 0, 0, 9, 9, 0,
604.4206 +	 0, 0,10,10, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0,
604.4207 +	 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,
604.4208 +	10,10, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0, 0,
604.4209 +	 0, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
604.4210 +	 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,11,11, 0,
604.4211 +	 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4212 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4213 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4214 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4215 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4216 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4217 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4218 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4219 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4220 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4221 +	 0, 0, 9, 9, 0, 0, 0, 7, 7, 0, 0, 0, 8, 8, 0, 0,
604.4222 +	 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0,
604.4223 +	 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0,
604.4224 +	 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8,
604.4225 +	 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0,
604.4226 +	 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,11,11, 0, 0,
604.4227 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4228 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
604.4229 +	 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4230 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4231 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4232 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4233 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4234 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4235 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4236 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4237 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4238 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4239 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4240 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4241 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4242 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4243 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4244 +	 0, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0, 7, 7,
604.4245 +	 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0,
604.4246 +	 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0,
604.4247 +	 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,
604.4248 +	 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0, 0,
604.4249 +	 0, 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,
604.4250 +	 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4251 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4252 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4253 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4254 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4255 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4256 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4257 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4258 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4259 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4260 +	 0, 0, 0, 9, 9, 0, 0, 0, 7, 7, 0, 0, 0, 8, 8, 0,
604.4261 +	 0, 0,10,11, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0,
604.4262 +	 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0,
604.4263 +	 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7,
604.4264 +	 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0,11,11,
604.4265 +	 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0,
604.4266 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4267 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4268 +	 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4269 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4270 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4271 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4272 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4273 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4274 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4275 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4276 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4277 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4278 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4279 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4280 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4281 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4282 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4283 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0, 7,
604.4284 +	 7, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
604.4285 +	 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0,
604.4286 +	 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0,
604.4287 +	 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0,
604.4288 +	 0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 9,
604.4289 +	 9, 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4290 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4291 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4292 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4293 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4294 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4295 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4296 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4297 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4298 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4299 +	 0, 0, 0, 0,10,10, 0, 0, 0, 9, 9, 0, 0, 0,10,10,
604.4300 +	 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0,
604.4301 +	 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0,
604.4302 +	 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0,
604.4303 +	 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0,11,
604.4304 +	11, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,12,12,
604.4305 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4306 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4307 +	 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4308 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4309 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4310 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4311 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4312 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4313 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4314 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4315 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4316 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4317 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4318 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4319 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4320 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4321 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4322 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0,
604.4323 +	 9, 9, 0, 0, 0,10,10, 0, 0, 0,12,12, 0, 0, 0, 0,
604.4324 +	 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,
604.4325 +	 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0,
604.4326 +	 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0,
604.4327 +	 0, 0, 0, 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0,
604.4328 +	10,10, 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4329 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4330 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4331 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4332 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4333 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4334 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4335 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4336 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4337 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4338 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4339 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4340 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4341 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4342 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4343 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4344 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4345 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4346 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4347 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4348 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4349 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4350 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4351 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4352 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4353 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4354 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4355 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4356 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4357 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4358 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4359 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4360 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4361 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4362 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4363 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4364 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4365 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4366 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4367 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4368 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4369 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4370 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4371 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4372 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4373 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4374 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4375 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4376 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4377 +	 0, 0, 0, 0, 0,
604.4378 +};
604.4379 +
604.4380 +static const static_codebook _44p4_p2_0 = {
604.4381 +	5, 3125,
604.4382 +	(long *)_vq_lengthlist__44p4_p2_0,
604.4383 +	1, -533725184, 1611661312, 3, 0,
604.4384 +	(long *)_vq_quantlist__44p4_p2_0,
604.4385 +	0
604.4386 +};
604.4387 +
604.4388 +static const long _vq_quantlist__44p4_p3_0[] = {
604.4389 +	1,
604.4390 +	0,
604.4391 +	2,
604.4392 +};
604.4393 +
604.4394 +static const long _vq_lengthlist__44p4_p3_0[] = {
604.4395 +	 1, 6, 6, 5, 7, 8, 0, 8, 8, 6, 9, 9, 7,10,10, 0,
604.4396 +	 8, 8, 0, 9, 9, 0,12,12, 0, 8, 8, 4, 7, 7, 6,10,
604.4397 +	10, 0,12,12, 7,11,11, 8,12,12, 0,12,12, 0,13,12,
604.4398 +	 0,15,15, 0,12,12, 0, 7, 7, 0, 7, 7, 0, 7, 7, 0,
604.4399 +	 8, 8, 0,10,10, 0, 7, 7, 0, 8, 8, 0,11,11, 0, 7,
604.4400 +	 7, 5, 7, 7, 8, 9, 9, 0,10,10, 8, 9, 9,11,11,11,
604.4401 +	 0,10, 9, 0,11,11, 0,13,13, 0,10,10, 6, 7, 7, 8,
604.4402 +	10,10, 0,12,12, 9,10,10,10,12,12, 0,12,12, 0,12,
604.4403 +	12, 0,15,15, 0,12,12, 0,10,10, 0,11,11, 0,11,11,
604.4404 +	 0,11,11, 0,13,13, 0,11,11, 0,11,11, 0,15,15, 0,
604.4405 +	10,10, 0, 8, 8, 0,10,10, 0,12,12, 0,11,11, 0,12,
604.4406 +	12, 0,12,12, 0,12,12, 0,15,15, 0,11,11, 0, 7, 7,
604.4407 +	 0,10,10, 0,12,12, 0,10,10, 0,12,12, 0,12,12, 0,
604.4408 +	13,13, 0,14,14, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,
604.4409 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.4410 +	 0, 0, 0,
604.4411 +};
604.4412 +
604.4413 +static const static_codebook _44p4_p3_0 = {
604.4414 +	5, 243,
604.4415 +	(long *)_vq_lengthlist__44p4_p3_0,
604.4416 +	1, -533200896, 1614282752, 2, 0,
604.4417 +	(long *)_vq_quantlist__44p4_p3_0,
604.4418 +	0
604.4419 +};
604.4420 +
604.4421 +static const long _vq_quantlist__44p4_p3_1[] = {
604.4422 +	1,
604.4423 +	0,
604.4424 +	2,
604.4425 +};
604.4426 +
604.4427 +static const long _vq_lengthlist__44p4_p3_1[] = {
604.4428 +	 3, 5, 5, 0, 8, 8, 0, 8, 8, 0, 9, 9, 0,10,10, 0,
604.4429 +	 8, 8, 0, 8, 8, 0,10,10, 0, 8, 8, 0, 7, 7, 0, 8,
604.4430 +	 8, 0, 7, 7, 0, 8, 8, 0, 8, 8, 0, 8, 8, 0, 8, 8,
604.4431 +	 0, 8, 8, 0, 8, 8, 0, 7, 7, 0, 6, 6, 0, 7, 7, 0,
604.4432 +	 7, 7, 0,10,10, 0, 6, 6, 0, 7, 7, 0,10,10, 0, 5,
604.4433 +	 5, 0, 8, 8, 0, 7, 7, 0, 8, 8, 0, 8, 8, 0, 9, 9,
604.4434 +	 0, 7, 7, 0, 8, 8, 0, 9, 9, 0, 7, 7, 0, 6, 6, 0,
604.4435 +	 9,10, 0,10,10, 0,10,10, 0,11,11, 0, 9, 9, 0,10,
604.4436 +	10, 0,11,11, 0, 9, 9, 0, 8, 8, 0, 8, 8, 0, 8, 8,
604.4437 +	 0, 9, 9, 0, 9, 9, 0, 7, 7, 0, 8, 8, 0, 9, 9, 0,
604.4438 +	 7, 7, 0, 8, 8, 0, 7, 7, 0, 7, 7, 0, 8, 8, 0, 9,
604.4439 +	 9, 0, 7, 7, 0, 7, 7, 0, 8, 8, 0, 6, 6, 0, 6, 6,
604.4440 +	 0,10,10, 0,10,10, 0,10,10, 0,12,12, 0, 9, 9, 0,
604.4441 +	10,10, 0,12,12, 0, 9, 9, 0, 8, 8, 0, 7, 7, 0, 7,
604.4442 +	 7, 0, 8, 8, 0, 9, 9, 0, 7, 7, 0, 8, 8, 0, 9, 9,
604.4443 +	 0, 6, 6,
604.4444 +};
604.4445 +
604.4446 +static const static_codebook _44p4_p3_1 = {
604.4447 +	5, 243,
604.4448 +	(long *)_vq_lengthlist__44p4_p3_1,
604.4449 +	1, -535822336, 1611661312, 2, 0,
604.4450 +	(long *)_vq_quantlist__44p4_p3_1,
604.4451 +	0
604.4452 +};
604.4453 +
604.4454 +static const long _vq_quantlist__44p4_p4_0[] = {
604.4455 +	1,
604.4456 +	0,
604.4457 +	2,
604.4458 +};
604.4459 +
604.4460 +static const long _vq_lengthlist__44p4_p4_0[] = {
604.4461 +	 1, 6, 6, 6, 7, 7, 7, 8, 8, 7, 8, 8,10,11,11, 9,
604.4462 +	 8, 8, 8, 8, 8,11,11,12, 9, 8, 8, 5, 7, 7, 9,11,
604.4463 +	11,10,11,11,10,11,11,12,14,14,11,12,12,10,12,12,
604.4464 +	13,14,14,12,12,12, 5, 6, 6, 7, 6, 6, 8, 7, 7, 8,
604.4465 +	 7, 7,11,10,10,10, 7, 7, 9, 8, 8,12,11,11,10, 7,
604.4466 +	 7, 7, 7, 7,11,10,10,12,10,10,11,10,10,15,13,13,
604.4467 +	13,10,10,12,11,11,15,13,13,14,11,11, 7, 7, 7,11,
604.4468 +	11,11,12,11,11,12,11,11,14,14,14,13,12,12,12,12,
604.4469 +	12,16,15,15,14,12,12, 0,10,10, 0,11,11, 0,12,12,
604.4470 +	 0,11,11, 0,14,14, 0,11,11, 0,12,12, 0,15,15, 0,
604.4471 +	11,11, 7, 8, 8,12,11,10,12,10,10,12,11,11,15,13,
604.4472 +	13,14,11,11,12,10,10,16,14,14,14,10,10, 8, 7, 7,
604.4473 +	12,11,11,12,11,11,12,11,11,15,14,14,14,12,12,13,
604.4474 +	12,12,15,14,14,15,13,13, 0,11,11, 0,12,12, 0,12,
604.4475 +	12, 0,12,12, 0,15,15, 0,12,12, 0,13,13, 0,15,14,
604.4476 +	 0,12,12,
604.4477 +};
604.4478 +
604.4479 +static const static_codebook _44p4_p4_0 = {
604.4480 +	5, 243,
604.4481 +	(long *)_vq_lengthlist__44p4_p4_0,
604.4482 +	1, -531365888, 1616117760, 2, 0,
604.4483 +	(long *)_vq_quantlist__44p4_p4_0,
604.4484 +	0
604.4485 +};
604.4486 +
604.4487 +static const long _vq_quantlist__44p4_p4_1[] = {
604.4488 +	2,
604.4489 +	1,
604.4490 +	3,
604.4491 +	0,
604.4492 +	4,
604.4493 +};
604.4494 +
604.4495 +static const long _vq_lengthlist__44p4_p4_1[] = {
604.4496 +	 4, 5, 5, 9, 9,12, 9, 9,12,12,12,10,10,13,13,13,
604.4497 +	11,11,12,12,13,13,13,12,12,13,10,10,13,13,13,13,
604.4498 +	13,13,13,13,10,10,13,12,13,11,11,13,13,13,14,14,
604.4499 +	13,12,13,10,10,13,13,12,13,13,13,13,13,10,10,12,
604.4500 +	12,13,11,11,13,13,13,14,14,12,12,13,12,12,13,13,
604.4501 +	13,13,13,13,13,13,11,11,12,12,13,11,11,13,13,13,
604.4502 +	14,14,12,12,13,14,14,13,13,14,13,13,14,14,14,14,
604.4503 +	14,12,12,13,14,14,13,13,14,14,14,12,12,12, 8, 8,
604.4504 +	12,12,13,12,12,11,11,13,11,11,11,11,14,12,12,11,
604.4505 +	11,14,12,12,10,11,14,12,12,12,12,14,12,12,12,12,
604.4506 +	13,13,13,11,11,14,12,12,11,11,14,12,12,12,12,14,
604.4507 +	12,12,12,12,14,12,12,12,12,14,13,13,11,11,14,12,
604.4508 +	12,11,11,14,12,12,12,12,14,13,13,12,12,14,12,12,
604.4509 +	12,12,14,13,13,11,11,14,12,12,11,11,14,13,13,11,
604.4510 +	11,15,13,13,12,12,14,12,12,12,12,15,13,13,12,12,
604.4511 +	14,12,12,11,11,15,13,13,11,11,12, 9, 9,11,11,13,
604.4512 +	 7, 7,11,11,13, 8, 8,12,12,14,10,10,10,10,14,14,
604.4513 +	14,11,11,14, 8, 8,12,12,14,14,14,12,12,14, 7, 7,
604.4514 +	11,11,14, 9, 9,12,12,14,14,14,11,11,14, 8, 8,12,
604.4515 +	12,14,14,14,12,12,14, 7, 7,11,11,14, 9, 9,12,12,
604.4516 +	14,14,14,11,11,14,10,10,12,12,14,14,14,13,13,14,
604.4517 +	 9, 9,11,11,14,10,10,12,11,15,14,14,11,11,14,15,
604.4518 +	15,12,12,15,14,14,14,14,15,14,14,11,11,15,14,14,
604.4519 +	12,12,15,14,14,11,11,14,11,11,10,10,15,10,10,10,
604.4520 +	10,15,10,10,10,10,15,11,11, 9, 9,15,12,13, 9, 9,
604.4521 +	15,11,11,11,11,15,13,13,11,11,15,10,10,10,10,15,
604.4522 +	11,11,10,10,15,13,13,11,11,15,11,11,11,11,15,13,
604.4523 +	13,11,11,15,10,10,10,10,15,11,11,10,10,15,13,13,
604.4524 +	10,11,15,12,12,11,11,15,13,13,11,10,15,11,11,10,
604.4525 +	10,15,11,12,10, 9,15,13,13,10,10,15,14,14,11,11,
604.4526 +	15,13,13,11,11,15,14,14,10,10,15,13,13,10,10,15,
604.4527 +	14,14,10,10,14,13,13,10,10,15,13,13,10,10,15,13,
604.4528 +	13,10,10,14,14,14, 8, 9,15,14,14, 9, 9,15,14,14,
604.4529 +	11,11,15,14,14,10,10,15,14,14,10,10,15,14,14,11,
604.4530 +	11,15,14,14,10,10,15,14,14,11,11,15,14,14,10,10,
604.4531 +	15,14,14,10,10,15,14,14,10,10,15,14,14, 9, 9,15,
604.4532 +	14,14,11,11,15,14,14,11,11,15,14,14,10,10,15,14,
604.4533 +	14,10,10,14,14,14, 9, 9,15,15,15,11,11,15,14,14,
604.4534 +	12,12,15,15,15,10,10,15,14,15,10,10,15,15,15, 9,
604.4535 +	 9,15,10,10,13,13,17, 8, 8,12,12,17,10, 9,13,13,
604.4536 +	18,11,11,12,12,18,14,14,12,12,17, 9, 9,13,13,17,
604.4537 +	13,13,12,12,18, 8, 8,12,12,18,10,10,12,12,18,14,
604.4538 +	14,12,12,18,10,10,13,13,18,13,13,13,13,18, 9, 9,
604.4539 +	12,12,18,10,10,13,13,18,14,14,12,12,18,11,11,13,
604.4540 +	13,18,14,14,13,13,18,10,10,12,12,17,11,11,12,12,
604.4541 +	18,14,14,12,12,18,14,14,13,13,18,14,14,13,13,19,
604.4542 +	14,15,12,12,18,14,14,12,12,18,15,15,12,12,13, 7,
604.4543 +	 7,11,11,14,15,15,11,11,14,16,15,11,11,14,15,15,
604.4544 +	11,11,14,15,15,11,11,14,15,15,11,12,14,15,15,12,
604.4545 +	12,13,15,15,11,11,14,15,15,11,11,15,15,15,12,12,
604.4546 +	14,15,15,12,12,14,16,16,12,12,14,15,15,11,11,14,
604.4547 +	15,15,11,11,15,15,15,12,12,15,15,15,12,12,14,15,
604.4548 +	15,12,12,14,15,15,11,11,14,15,15,11,11,15,14,15,
604.4549 +	12,12,15,15,15,12,12,15,16,16,12,12,15,15,15,12,
604.4550 +	12,14,15,15,12,12,15,15,15,12,12,13,13,13,11,11,
604.4551 +	14,14,15,11,11,14,14,14,12,12,14,15,15,10,10,15,
604.4552 +	15,15,11,11,14,15,15,12,12,14,14,14,11,11,14,15,
604.4553 +	15,11,11,14,15,15,12,12,15,15,15,11,11,14,15,15,
604.4554 +	12,12,14,14,15,11,11,14,15,15,11,11,14,15,15,12,
604.4555 +	12,15,15,15,11,11,15,15,15,12,12,14,15,15,12,12,
604.4556 +	14,15,15,10,10,14,15,15,11,11,15,15,15,10,10,15,
604.4557 +	15,15,12,12,15,15,15,14,14,15,15,15,11,11,15,15,
604.4558 +	15,11,11,15,15,15,11,11,14,10,10,10,10,15, 9, 9,
604.4559 +	12,11,15,10,10,12,12,15,11,11,11,11,15,13,13,12,
604.4560 +	12,16,10,10,12,12,15,13,13,12,12,15, 9, 9,11,11,
604.4561 +	15,10,10,13,12,15,13,13,11,11,15,10,10,12,12,15,
604.4562 +	13,13,12,12,15, 9, 9,11,11,15,10,10,12,12,15,13,
604.4563 +	13,11,11,15,11,11,12,12,15,13,13,13,13,15,10,10,
604.4564 +	11,11,15,11,11,12,12,15,13,14,11,11,15,14,14,13,
604.4565 +	13,16,14,14,20,19,15,14,14,11,11,15,13,14,12,12,
604.4566 +	15,14,14,11,11,14,13,13,10,10,14,14,13,11,11,15,
604.4567 +	13,14,12,12,15,14,14,12,12,15,14,14,11,11,15,14,
604.4568 +	14,12,12,15,15,14,13,13,15,14,14,11,11,15,14,14,
604.4569 +	11,11,15,14,14,13,13,15,14,14,12,12,15,14,14,13,
604.4570 +	13,15,14,14,11,11,15,14,14,11,11,15,14,14,13,13,
604.4571 +	15,14,14,12,12,15,14,14,12,12,15,14,14,12,12,15,
604.4572 +	14,14,11,11,15,15,15,12,12,15,15,15,13,13,16,14,
604.4573 +	14,12,12,15,15,15,13,13,15,15,15,12,12,15,15,15,
604.4574 +	12,12,14,10,10,13,13,17, 9, 9,12,12,17, 9, 9,13,
604.4575 +	13,17,11,11,12,12,18,14,14,12,12,18,10,10,13,13,
604.4576 +	18,14,13,12,12,18, 9, 9,12,12,18,10,10,12,13,18,
604.4577 +	14,14,12,12,17, 9, 9,12,12,17,13,14,12,12,17, 9,
604.4578 +	 9,12,12,17,10,10,12,12,17,14,14,11,11,18,11,11,
604.4579 +	12,12,18,14,14,12,13,18,10,10,12,12,18,11,11,12,
604.4580 +	12,18,14,14,11,11,18,15,15,12,12,18,14,14,13,13,
604.4581 +	18,14,15,12,12,17,14,14,12,12,17,15,15,12,12,13,
604.4582 +	 7, 7,11,11,14,15,15,11,11,14,15,15,11,11,14,15,
604.4583 +	15,11,11,14,15,15,11,11,14,15,15,11,11,14,15,15,
604.4584 +	12,12,14,15,15,11,11,14,15,15,11,11,15,15,15,12,
604.4585 +	12,14,15,15,11,11,14,15,15,12,12,14,15,15,11,11,
604.4586 +	15,15,15,11,11,15,15,15,12,12,14,15,15,12,12,14,
604.4587 +	15,16,12,12,14,15,15,11,11,14,15,15,11,11,15,15,
604.4588 +	15,12,12,15,15,15,12,12,15,16,16,12,12,15,15,15,
604.4589 +	12,12,15,15,15,12,12,15,15,15,12,12,13,13,13,12,
604.4590 +	12,14,14,14,11,11,14,14,14,12,12,14,14,14,10,10,
604.4591 +	15,15,15,11,11,14,15,15,12,12,14,14,14,11,11,14,
604.4592 +	15,15,11,11,14,14,14,12,12,15,15,14,11,11,14,15,
604.4593 +	15,12,12,14,14,14,11,11,14,15,15,11,11,14,14,14,
604.4594 +	11,11,15,14,14,10,10,14,15,15,12,12,14,14,14,12,
604.4595 +	12,14,15,15,10,10,14,15,15,11,11,15,15,15,10,10,
604.4596 +	15,15,15,12,12,15,14,14,13,13,15,15,15,10,10,15,
604.4597 +	14,14,11,11,15,15,15,10,10,14,10,10,10,10,14, 9,
604.4598 +	 9,12,12,15,10,10,12,12,14,11,11,11,11,15,13,14,
604.4599 +	12,12,15,10,10,13,13,15,13,13,12,12,15, 9, 9,12,
604.4600 +	12,15,10,10,13,13,15,13,14,11,11,15,10,10,12,12,
604.4601 +	15,13,13,12,12,15, 9, 9,11,11,15,10,10,12,12,15,
604.4602 +	13,13,11,11,15,11,11,12,12,15,13,13,13,13,15,10,
604.4603 +	10,11,11,15,11,11,12,12,15,14,14,11,11,15,14,14,
604.4604 +	13,13,15,14,14,20,19,15,14,14,11,11,15,14,14,12,
604.4605 +	12,15,14,14,11,11,14,13,13,11,11,15,13,13,11,11,
604.4606 +	15,14,13,12,12,15,14,14,11,12,15,14,14,11,11,15,
604.4607 +	14,14,12,12,14,14,14,13,13,15,14,14,11,11,15,14,
604.4608 +	14,11,11,15,14,14,13,13,15,14,14,12,12,15,14,14,
604.4609 +	13,13,14,14,14,11,11,15,14,14,11,11,15,14,14,13,
604.4610 +	13,15,14,14,12,12,15,14,14,12,12,15,14,14,12,12,
604.4611 +	15,14,14,11,11,14,14,14,12,12,15,15,15,13,13,16,
604.4612 +	14,14,12,12,15,15,15,13,13,15,14,14,12,12,15,15,
604.4613 +	15,12,12,15,11,11,13,13,18,10,10,12,12,17,11,11,
604.4614 +	12,12,18,12,12,11,11,18,14,14,12,12,18,10,10,13,
604.4615 +	13,18,14,14,12,12,18,10,10,12,12,18,11,11,12,12,
604.4616 +	18,14,14,12,12,18,11,11,12,13,18,14,14,12,12,18,
604.4617 +	10,10,12,12,18,11,11,12,12,18,14,14,11,11,18,11,
604.4618 +	11,12,12,18,14,14,12,12,17,10,10,11,11,17,12,12,
604.4619 +	11,11,17,14,14,11,11,18,15,15,12,12,18,14,14,13,
604.4620 +	13,18,15,15,11,11,18,15,14,12,12,18,15,15,11,11,
604.4621 +	14, 8, 8,11,11,14,15,15,10,10,14,15,15,11,11,14,
604.4622 +	15,15,11,11,15,15,15,12,12,15,15,15,11,11,15,15,
604.4623 +	15,12,12,14,15,15,10,10,15,15,15,11,11,15,15,15,
604.4624 +	12,12,15,15,15,11,11,15,15,15,13,13,14,15,15,10,
604.4625 +	10,15,15,15,11,11,15,15,15,12,12,15,15,15,12,12,
604.4626 +	15,16,16,12,12,15,14,14,11,11,15,15,15,11,11,15,
604.4627 +	15,15,12,12,16,15,15,13,13,15,16,16,13,13,16,15,
604.4628 +	15,12,12,15,15,15,12,12,15,15,15,12,12,14,13,13,
604.4629 +	11,11,14,14,14,11,11,14,14,14,12,12,15,14,14,11,
604.4630 +	11,15,15,14,11,11,15,14,14,12,12,15,14,14,12,12,
604.4631 +	14,15,15,11,11,15,14,14,12,12,15,14,14,11,11,15,
604.4632 +	14,15,12,12,15,14,14,12,12,14,15,15,11,11,15,14,
604.4633 +	14,11,11,15,14,14,11,11,15,15,14,12,12,15,14,14,
604.4634 +	12,12,15,15,15,10,11,15,14,14,11,11,15,15,15,10,
604.4635 +	10,15,15,15,12,12,16,14,14,13,13,15,15,15,11,11,
604.4636 +	15,14,14,11,11,15,15,15,11,11,14,11,11, 9, 9,14,
604.4637 +	10,10,12,12,15,11,11,12,12,15,12,12,12,12,15,14,
604.4638 +	14,13,13,15,11,11,12,12,15,14,14,13,13,14,10,10,
604.4639 +	12,12,15,11,11,13,13,15,14,14,12,12,15,10,10,12,
604.4640 +	12,14,14,14,13,13,14,10,10,11,11,15,11,11,12,12,
604.4641 +	15,14,14,12,12,15,12,12,13,13,15,14,14,14,14,15,
604.4642 +	11,11,11,11,15,12,11,12,12,15,14,14,11,11,15,15,
604.4643 +	15,13,14,15,14,14,20,19,15,14,14,12,12,15,14,14,
604.4644 +	13,13,15,14,14,12,12,14,13,13,10,10,14,13,13,11,
604.4645 +	11,14,13,13,11,11,15,14,14,12,12,15,14,14,12,12,
604.4646 +	15,14,14,12,11,14,14,14,13,13,15,14,14,11,11,15,
604.4647 +	14,14,11,11,15,14,14,14,14,15,14,14,11,12,15,14,
604.4648 +	14,13,13,14,14,14,11,11,15,14,14,11,11,15,14,14,
604.4649 +	14,14,15,14,14,12,12,15,14,14,13,13,15,14,14,11,
604.4650 +	11,14,14,14,12,12,15,14,14,13,13,15,15,15,13,13,
604.4651 +	15,14,14,13,13,15,15,15,13,13,15,14,14,13,13,15,
604.4652 +	15,15,13,13,15,14,14,13,13,18,15,15,12,12,18,15,
604.4653 +	15,12,12,18,16,16,11,11,18,17,17,12,12,18,15,15,
604.4654 +	13,13,18,17,17,12,12,18,15,15,12,12,18,15,16,12,
604.4655 +	12,18,17,17,12,12,18,15,15,13,12,17,16,17,12,12,
604.4656 +	17,15,15,11,12,18,15,15,12,12,18,17,17,11,11,18,
604.4657 +	16,16,12,12,18,17,16,12,12,18,15,15,11,11,18,15,
604.4658 +	15,12,12,18,17,17,11,11,18,17,17,12,12,18,16,16,
604.4659 +	13,13,18,17,17,11,11,17,16,16,11,11,18,17,17,11,
604.4660 +	11,15,15,15,11,11,16,15,15,11,11,16,15,15,11,11,
604.4661 +	16,15,15,12,12,17,15,15,14,14,16,15,15,11,11,17,
604.4662 +	15,15,14,14,16,15,15,11,11,16,15,15,12,12,18,15,
604.4663 +	15,13,13,16,15,15,11,11,17,15,15,14,14,16,15,15,
604.4664 +	11,11,16,15,15,12,12,17,15,15,13,13,16,15,15,12,
604.4665 +	12,17,16,15,14,14,16,15,15,11,11,16,15,15,12,12,
604.4666 +	18,15,15,13,13,17,15,15,14,14,17,16,16,15,15,18,
604.4667 +	14,15,13,13,18,15,15,14,14,18,15,15,13,13,15,13,
604.4668 +	13,12,12,15,14,14,12,12,16,14,14,12,12,16,14,14,
604.4669 +	12,12,17,14,15,12,12,16,14,14,12,12,17,14,14,13,
604.4670 +	13,16,15,15,12,12,16,14,14,12,12,17,14,14,12,12,
604.4671 +	16,14,14,12,12,17,14,14,13,13,15,15,15,11,11,16,
604.4672 +	14,14,12,12,17,14,14,12,12,16,15,15,12,12,17,14,
604.4673 +	14,13,12,16,15,15,11,11,16,14,14,12,12,17,15,15,
604.4674 +	11,11,17,15,15,13,13,17,14,14,13,13,18,15,15,12,
604.4675 +	12,17,14,14,12,12,17,15,15,12,12,14,15,15, 9, 9,
604.4676 +	14,15,15,12,12,15,16,15,13,13,15,15,15,14,14,15,
604.4677 +	15,15,21,19,15,15,15,13,13,15,15,15,19,19,15,15,
604.4678 +	15,12,12,15,16,16,14,14,15,15,15,19,19,15,16,15,
604.4679 +	13,13,15,16,16,19,20,15,15,15,12,13,15,16,16,14,
604.4680 +	14,15,15,15,20,19,15,15,15,14,14,15,16,16,19,19,
604.4681 +	15,15,15,14,13,15,15,15,14,14,15,15,15,19,19,15,
604.4682 +	16,16,20,19,15,17,16,21,20,15,15,15,20,19,15,16,
604.4683 +	16,20,20,15,15,15,19,20,14,13,13,10,10,14,14,14,
604.4684 +	11,11,14,14,14,12,12,15,14,14,13,13,15,15,14,20,
604.4685 +	20,15,14,14,12,12,14,14,14,19,19,15,14,14,11,11,
604.4686 +	15,14,14,12,12,15,14,14,20,19,15,14,14,12,12,14,
604.4687 +	14,14,20,20,14,14,14,11,11,15,14,14,12,12,15,14,
604.4688 +	14,20,21,15,14,14,13,13,15,14,14,20,20,15,14,14,
604.4689 +	12,12,15,14,14,13,13,14,15,15,20,20,15,15,15,20,
604.4690 +	19,15,14,14,20,19,15,15,15,20,20,15,14,14,21,20,
604.4691 +	15,15,15,20,20,
604.4692 +};
604.4693 +
604.4694 +static const static_codebook _44p4_p4_1 = {
604.4695 +	5, 3125,
604.4696 +	(long *)_vq_lengthlist__44p4_p4_1,
604.4697 +	1, -533725184, 1611661312, 3, 0,
604.4698 +	(long *)_vq_quantlist__44p4_p4_1,
604.4699 +	0
604.4700 +};
604.4701 +
604.4702 +static const long _vq_quantlist__44p4_p5_0[] = {
604.4703 +	2,
604.4704 +	1,
604.4705 +	3,
604.4706 +	0,
604.4707 +	4,
604.4708 +};
604.4709 +
604.4710 +static const long _vq_lengthlist__44p4_p5_0[] = {
604.4711 +	 1, 7, 6,15,15, 7, 8, 8,15,15, 8, 8, 8,15,15, 0,
604.4712 +	13,13,16,16, 0,14,14,16,16, 7, 9, 9,16,16,10,11,
604.4713 +	11,17,17,10, 8, 8,15,16, 0,14,14,18,18, 0,14,14,
604.4714 +	16,16, 9, 9, 9,16,16,12,11,11,17,17,10, 9, 9,15,
604.4715 +	15, 0,14,14,19,19, 0,14,14,16,16, 0,15,15,18,17,
604.4716 +	 0, 0, 0,20,20, 0,13,13,16,16, 0,17,17,22,20, 0,
604.4717 +	15,15,17,17, 0,15,15,18,18, 0,22,21,20,21, 0,13,
604.4718 +	13,16,16, 0,18,18, 0,22, 0,15,15,17,17, 6, 7, 7,
604.4719 +	13,13, 9,10,10,15,15,11,10,10,15,15, 0,21,22,18,
604.4720 +	18, 0, 0, 0,18,18,10,10,10,15,15,12,13,13,17,17,
604.4721 +	12,11,11,15,15, 0,22,22,18,18, 0, 0,21,18,18,12,
604.4722 +	11,11,15,15,15,14,14,18,18,13,11,11,15,15, 0, 0,
604.4723 +	21,18,19, 0,21,22,18,19, 0,22, 0,18,19, 0, 0, 0,
604.4724 +	 0, 0, 0,21,21,18,18, 0,22, 0, 0,21, 0, 0, 0,19,
604.4725 +	18, 0, 0, 0,18,19, 0, 0, 0, 0, 0, 0,20,20,18,17,
604.4726 +	 0, 0,22, 0,21, 0, 0, 0,19,19, 6, 6, 6,13,13, 8,
604.4727 +	 6, 6,11,11, 9, 7, 7,13,13, 0,10,10,11,11, 0,12,
604.4728 +	12,14,14, 9, 8, 8,14,14,12,10,10,13,13,10, 7, 7,
604.4729 +	13,13, 0,11,11,15,15, 0,11,11,13,13, 9, 8, 8,14,
604.4730 +	14,13,10,10,13,14,11, 7, 7,13,13, 0,11,11,15,15,
604.4731 +	 0,11,11,13,13, 0,12,12,15,15, 0,21,21,17,17, 0,
604.4732 +	10,10,13,13, 0,14,14,20,20, 0,12,12,13,13, 0,12,
604.4733 +	12,15,15, 0,21,22,17,18, 0,10,10,13,13, 0,16,16,
604.4734 +	20,21, 0,12,12,13,13, 0,11,11,13,13, 0,12,12,16,
604.4735 +	16, 0,12,12,16,16, 0,16,16, 0,21, 0,17,18, 0, 0,
604.4736 +	 0,12,12,15,15, 0,15,15,18,18, 0,12,12,16,16, 0,
604.4737 +	16,16,21,22, 0,17,17,22,21, 0,12,12,16,16, 0,15,
604.4738 +	15,19,19, 0,12,12,16,16, 0,16,16,22,22, 0,17,16,
604.4739 +	22, 0, 0,17,18, 0, 0, 0, 0, 0, 0, 0, 0,15,15,21,
604.4740 +	20, 0,19,20, 0,22, 0,18,18, 0, 0, 0,18,17, 0, 0,
604.4741 +	 0, 0, 0, 0, 0, 0,16,16,22,21, 0,20,20, 0,22, 0,
604.4742 +	20,19, 0, 0, 0,11,11,12,12, 0,10,10,11,11, 0,11,
604.4743 +	11,12,12, 0,12,12,10,10, 0,13,13,12,12, 0,11,11,
604.4744 +	13,13, 0,13,13,12,12, 0,10,10,12,12, 0,13,13,14,
604.4745 +	13, 0,12,12,12,12, 0,12,12,13,13, 0,14,14,13,13,
604.4746 +	 0,10,10,12,12, 0,13,13,14,14, 0,13,12,12,12, 0,
604.4747 +	14,14,14,14, 0,21,21,16,16, 0,12,12,12,12, 0,16,
604.4748 +	16,20,21, 0,13,13,11,11, 0,14,14,14,14, 0,20,20,
604.4749 +	16,15, 0,12,12,12,12, 0,17,17,20,20, 0,13,13,11,
604.4750 +	11, 7, 8, 8,16,16,11,10,10,15,15,12,10,10,17,17,
604.4751 +	 0,14,14,16,15, 0,15,15,17,17,11, 9, 9,16,16,14,
604.4752 +	12,12,17,17,13, 9, 9,16,15, 0,14,14,19,18, 0,14,
604.4753 +	14,16,16,12,10,10,17,18,16,13,13,17,18,14,10,10,
604.4754 +	16,16, 0,14,14,19,19, 0,14,15,17,17, 0,15,15,18,
604.4755 +	19, 0, 0, 0,20,20, 0,13,13,17,17, 0,17,18, 0,22,
604.4756 +	 0,15,15,16,17, 0,15,15,18,18, 0, 0, 0,20,21, 0,
604.4757 +	14,14,17,17, 0,19,18, 0, 0, 0,16,16,17,17, 8, 7,
604.4758 +	 7,14,14,12,11,11,15,15,13,11,11,15,15, 0, 0, 0,
604.4759 +	18,19, 0,21,20,18,18,12,10,11,15,16,14,13,13,18,
604.4760 +	18,14,11,11,15,15, 0,20,20,19,18, 0,20, 0,18,18,
604.4761 +	13,11,11,16,16,17,15,15,19,19,14,12,12,15,15, 0,
604.4762 +	21, 0,18,20, 0,22,22,18,19, 0,22,22,19,19, 0, 0,
604.4763 +	 0, 0, 0, 0,21,22,19,18, 0, 0, 0, 0,21, 0, 0, 0,
604.4764 +	19,19, 0, 0,22,20,20, 0, 0, 0, 0, 0, 0,22, 0,18,
604.4765 +	18, 0, 0, 0, 0,22, 0, 0, 0,19,20,11,10,10,14,14,
604.4766 +	14,11,11,13,13,14,11,11,15,15, 0,14,13,12,12, 0,
604.4767 +	15,15,16,16,13,11,11,15,15,16,13,13,15,15,15,10,
604.4768 +	10,14,15, 0,14,14,16,16, 0,14,14,15,15,13,11,11,
604.4769 +	15,15,18,14,14,15,15,15,10,10,15,14, 0,14,14,16,
604.4770 +	16, 0,14,14,15,15, 0,15,15,17,16, 0,21,22,18,18,
604.4771 +	 0,13,13,14,14, 0,18,17,20,21, 0,15,15,14,14, 0,
604.4772 +	15,16,16,17, 0, 0, 0,19,18, 0,13,13,15,14, 0,19,
604.4773 +	19, 0, 0, 0,15,15,14,14, 0,12,12,14,13, 0,13,13,
604.4774 +	16,16, 0,12,12,16,16, 0,16,16,22, 0, 0,17,18, 0,
604.4775 +	22, 0,13,13,16,16, 0,15,15,18,18, 0,12,12,16,16,
604.4776 +	 0,16,16,22,22, 0,17,17, 0, 0, 0,13,13,17,17, 0,
604.4777 +	16,16,19,20, 0,12,12,17,17, 0,17,17,22, 0, 0,17,
604.4778 +	17,22,21, 0,18,18, 0, 0, 0, 0, 0, 0, 0, 0,16,16,
604.4779 +	21,21, 0,19,19, 0, 0, 0,18,18, 0,22, 0,18,18, 0,
604.4780 +	22, 0, 0, 0, 0, 0, 0,16,16,22, 0, 0,20,20, 0, 0,
604.4781 +	 0,19,18, 0, 0, 0,12,12,15,15, 0,12,12,15,14, 0,
604.4782 +	13,13,15,15, 0,14,14,14,14, 0,15,15,16,16, 0,13,
604.4783 +	13,15,16, 0,15,15,16,16, 0,12,12,15,15, 0,14,14,
604.4784 +	16,16, 0,14,14,15,15, 0,13,13,15,16, 0,15,15,16,
604.4785 +	16, 0,12,12,15,15, 0,15,15,17,17, 0,14,14,15,15,
604.4786 +	 0,15,15,17,17, 0,21,21,19,19, 0,13,13,14,14, 0,
604.4787 +	17,17,22, 0, 0,14,14,15,15, 0,15,15,17,17, 0,22,
604.4788 +	 0,18,20, 0,13,13,15,15, 0,18,18, 0,22, 0,15,15,
604.4789 +	14,15, 8, 8, 8,17,16,12,10,10,16,16,13,10,10,17,
604.4790 +	16, 0,15,15,17,17, 0,15,15,17,17,12,11,11,18,18,
604.4791 +	15,12,12,18,18,15,10,10,16,17, 0,14,14,18,18, 0,
604.4792 +	14,14,17,17,13,10,10,16,16,17,14,14,17,17,15,10,
604.4793 +	10,16,15, 0,15,15,19,20, 0,14,14,15,16, 0,16,16,
604.4794 +	19,19, 0, 0, 0,21,22, 0,13,13,17,17, 0,18,17, 0,
604.4795 +	21, 0,15,15,17,17, 0,15,15,18,19, 0, 0,22, 0,21,
604.4796 +	 0,13,13,16,17, 0,19,19, 0,22, 0,16,15,16,16, 9,
604.4797 +	 8, 8,14,14,12,11,11,15,15,13,11,11,15,15, 0,21,
604.4798 +	20,19,18, 0, 0, 0,19,18,12,11,11,16,15,15,13,13,
604.4799 +	17,18,14,11,11,15,15, 0,22,22,19,18, 0,22,21,18,
604.4800 +	18,14,11,11,15,15,17,14,14,18,18,15,12,12,15,15,
604.4801 +	 0,22,22,20,19, 0, 0,21,18,18, 0, 0,22,20,20, 0,
604.4802 +	 0, 0, 0, 0, 0,20,21,18,18, 0, 0, 0,21,21, 0, 0,
604.4803 +	 0,20,19, 0,22,21,19,19, 0, 0, 0, 0, 0, 0, 0,22,
604.4804 +	17,18, 0, 0,22, 0,22, 0,22, 0,19,19, 0,11,11,15,
604.4805 +	15, 0,11,11,14,14, 0,12,12,15,15, 0,15,15,14,14,
604.4806 +	 0,16,16,16,16, 0,12,12,16,16, 0,14,14,16,16, 0,
604.4807 +	11,11,15,15, 0,15,15,17,17, 0,15,15,15,15, 0,12,
604.4808 +	12,16,16, 0,14,14,15,15, 0,11,11,15,15, 0,15,15,
604.4809 +	17,17, 0,15,15,14,15, 0,16,16,17,17, 0, 0, 0,19,
604.4810 +	19, 0,14,14,15,15, 0,18,18,21, 0, 0,15,15,14,15,
604.4811 +	 0,16,16,17,17, 0,21, 0,19,19, 0,14,14,15,15, 0,
604.4812 +	20,20,22, 0, 0,16,15,14,14, 0,12,12,13,13, 0,12,
604.4813 +	12,16,16, 0,12,12,16,16, 0,16,16,22,21, 0,18,17,
604.4814 +	21, 0, 0,13,13,16,16, 0,15,15,18,19, 0,12,12,16,
604.4815 +	16, 0,16,17,22, 0, 0,17,17, 0,22, 0,13,13,17,16,
604.4816 +	 0,15,15,19,19, 0,12,12,16,16, 0,16,16,21,20, 0,
604.4817 +	17,16,22, 0, 0,18,18,22,21, 0, 0, 0, 0, 0, 0,15,
604.4818 +	16,21,21, 0,19,19, 0, 0, 0,18,17, 0, 0, 0,18,18,
604.4819 +	21, 0, 0, 0, 0, 0, 0, 0,16,16,22,22, 0,20,21, 0,
604.4820 +	 0, 0,18,19, 0,22, 0,13,13,16,16, 0,12,12,15,15,
604.4821 +	 0,13,13,16,16, 0,14,14,15,15, 0,15,15,17,17, 0,
604.4822 +	13,13,17,16, 0,15,15,17,17, 0,12,12,16,16, 0,15,
604.4823 +	15,17,17, 0,14,14,16,16, 0,13,13,16,17, 0,15,15,
604.4824 +	17,17, 0,12,12,16,16, 0,14,14,17,17, 0,14,14,16,
604.4825 +	16, 0,16,16,17,17, 0,21, 0,21,19, 0,13,13,16,16,
604.4826 +	 0,17,17, 0, 0, 0,15,15,16,16, 0,16,15,18,18, 0,
604.4827 +	22, 0,20,20, 0,13,13,15,15, 0,18,18, 0, 0, 0,15,
604.4828 +	15,15,15, 0,12,12,17,17, 0,14,14,17,17, 0,14,14,
604.4829 +	17,17, 0,17,17,18,17, 0,17,17,19,18, 0,13,13,17,
604.4830 +	17, 0,16,16,18,18, 0,13,13,16,16, 0,17,17,19,19,
604.4831 +	 0,16,16,17,17, 0,13,13,18,18, 0,17,17,18,18, 0,
604.4832 +	13,13,17,17, 0,17,17,19,19, 0,16,17,17,17, 0,17,
604.4833 +	17,19,19, 0,21, 0,21,19, 0,14,14,16,16, 0,20,19,
604.4834 +	 0,21, 0,16,16,16,16, 0,17,18,19,19, 0, 0, 0, 0,
604.4835 +	21, 0,15,15,16,17, 0,21,20, 0, 0, 0,17,18,16,17,
604.4836 +	 0, 9, 9,14,14, 0,14,14,15,16, 0,14,14,15,15, 0,
604.4837 +	 0, 0,18,18, 0,21, 0,18,19, 0,12,12,15,15, 0,16,
604.4838 +	16,17,17, 0,14,14,14,14, 0,22, 0,19,18, 0,22, 0,
604.4839 +	17,18, 0,14,14,16,15, 0,18,18,19,18, 0,14,15,15,
604.4840 +	15, 0, 0,21,20,20, 0, 0, 0,18,18, 0,21,21,19,19,
604.4841 +	 0, 0, 0, 0, 0, 0,21,21,18,18, 0,22, 0,20,20, 0,
604.4842 +	22, 0,19,19, 0,22, 0,19,20, 0, 0, 0, 0, 0, 0, 0,
604.4843 +	21,17,18, 0, 0, 0,22,22, 0, 0, 0,19,18, 0,18,20,
604.4844 +	16,16, 0,21,20,17,17, 0, 0,21,18,18, 0,22,21,18,
604.4845 +	18, 0, 0,22,19,19, 0,20,20,17,17, 0, 0, 0,18,18,
604.4846 +	 0,19,20,17,17, 0,22, 0,19,21, 0,22,21,18,18, 0,
604.4847 +	20,19,17,18, 0, 0, 0,19,19, 0,20,20,17,17, 0,22,
604.4848 +	22,21,21, 0,20, 0,18,18, 0,22,22,18,18, 0, 0, 0,
604.4849 +	20,22, 0,20,20,16,16, 0, 0, 0,21, 0, 0,21,20,16,
604.4850 +	17, 0,22, 0,19,20, 0, 0, 0,21,20, 0,19,21,17,17,
604.4851 +	 0, 0, 0, 0, 0, 0,21,21,17,17, 0,12,12,13,13, 0,
604.4852 +	14,14,16,16, 0,14,14,16,16, 0,18,18, 0, 0, 0,19,
604.4853 +	18,22, 0, 0,13,13,16,16, 0,16,16,18,18, 0,13,13,
604.4854 +	16,16, 0,17,18,21, 0, 0,18,18,21, 0, 0,13,13,16,
604.4855 +	16, 0,17,17,19,20, 0,13,13,16,17, 0,18,18,21, 0,
604.4856 +	 0,18,18,21, 0, 0,18,19, 0,21, 0, 0, 0, 0, 0, 0,
604.4857 +	16,16,21,20, 0,20,20, 0, 0, 0,18,19, 0, 0, 0,18,
604.4858 +	18, 0, 0, 0, 0, 0, 0, 0, 0,16,16, 0,21, 0,22,22,
604.4859 +	 0, 0, 0,19,19, 0, 0, 0,16,16,19,20, 0,17,16,22,
604.4860 +	21, 0,17,17,21,20, 0,19,18, 0,22, 0,19,19,22,22,
604.4861 +	 0,16,15,22,22, 0,19,19, 0,21, 0,15,15,20,20, 0,
604.4862 +	18,19, 0,21, 0,18,18,22,22, 0,16,16,21,20, 0,20,
604.4863 +	19,21,22, 0,16,15,20,20, 0,19,19, 0,22, 0,18,18,
604.4864 +	21, 0, 0,19,18,21,22, 0, 0, 0, 0, 0, 0,16,16,19,
604.4865 +	21, 0,20,22, 0,22, 0,18,18,20,21, 0,19,18, 0,22,
604.4866 +	 0, 0, 0,22, 0, 0,16,16,20,20, 0,21,21, 0, 0, 0,
604.4867 +	18,18,21, 0, 0,12,12,17,17, 0,15,14,17,17, 0,14,
604.4868 +	14,18,18, 0,17,17,17,18, 0,18,18,18,18, 0,13,13,
604.4869 +	18,18, 0,16,17,19,18, 0,13,13,16,17, 0,17,17,18,
604.4870 +	19, 0,17,17,17,17, 0,13,13,17,17, 0,17,18,18,18,
604.4871 +	 0,13,13,16,16, 0,18,18,19,20, 0,16,17,17,16, 0,
604.4872 +	17,18,19,18, 0, 0, 0,22,21, 0,15,15,16,16, 0,20,
604.4873 +	20,21,22, 0,17,17,16,16, 0,16,17,18,18, 0, 0, 0,
604.4874 +	21,21, 0,15,15,16,16, 0,21,20, 0, 0, 0,17,17,16,
604.4875 +	16, 0,10,10,14,14, 0,14,14,15,15, 0,14,14,15,15,
604.4876 +	 0,22, 0,18,18, 0, 0, 0,19,19, 0,13,13,15,16, 0,
604.4877 +	17,16,18,18, 0,14,14,15,15, 0,21,21,19,18, 0,22,
604.4878 +	21,18,17, 0,14,14,15,15, 0,18,18,19,18, 0,15,15,
604.4879 +	14,14, 0,22,21,19,19, 0,22,21,17,18, 0, 0, 0,19,
604.4880 +	19, 0, 0, 0, 0, 0, 0,20,22,17,17, 0, 0,22,22,20,
604.4881 +	 0, 0, 0,19,18, 0,21,22,19,18, 0, 0, 0, 0, 0, 0,
604.4882 +	22,22,17,18, 0, 0, 0,21,22, 0, 0, 0,19,18, 0,20,
604.4883 +	20,17,17, 0,21,21,17,18, 0,21,22,18,18, 0,21, 0,
604.4884 +	18,18, 0,22, 0,19,19, 0,19,21,18,18, 0, 0,22,18,
604.4885 +	18, 0,22,21,17,17, 0,22, 0,20,20, 0, 0, 0,18,18,
604.4886 +	 0,22,21,18,18, 0,21, 0,19,19, 0,20,21,17,17, 0,
604.4887 +	 0,22,22,20, 0,21,22,17,17, 0, 0,21,19,18, 0, 0,
604.4888 +	 0,21,21, 0,21,20,16,17, 0, 0, 0, 0, 0, 0,21, 0,
604.4889 +	17,17, 0,21, 0,19,20, 0, 0, 0,20,22, 0,20,20,17,
604.4890 +	17, 0, 0, 0, 0, 0, 0,21,21,17,17, 0,12,12,13,13,
604.4891 +	 0,14,14,16,16, 0,14,14,16,16, 0,18,18,21, 0, 0,
604.4892 +	19,19,22, 0, 0,13,13,16,16, 0,16,16,18,18, 0,13,
604.4893 +	13,16,16, 0,18,18,21,22, 0,18,18, 0,22, 0,13,13,
604.4894 +	16,16, 0,17,17,20,18, 0,13,13,16,16, 0,19,18, 0,
604.4895 +	22, 0,18,18,22,21, 0,18,19, 0, 0, 0, 0, 0, 0, 0,
604.4896 +	 0,16,16,21,21, 0,21,21, 0, 0, 0,18,19, 0, 0, 0,
604.4897 +	19,19,21, 0, 0, 0, 0, 0, 0, 0,16,16, 0,21, 0,20,
604.4898 +	20, 0, 0, 0,20,20, 0, 0, 0,16,16,21,20, 0,18,17,
604.4899 +	21,22, 0,17,18, 0,21, 0,18,19,22,22, 0,19,19, 0,
604.4900 +	22, 0,16,17,21,22, 0,20,19, 0, 0, 0,16,16,20,21,
604.4901 +	 0,19,19, 0, 0, 0,19,19, 0,22, 0,17,17,21,21, 0,
604.4902 +	19,20, 0, 0, 0,16,16, 0,20, 0,19,20, 0,21, 0,18,
604.4903 +	18, 0,22, 0,19,20,22,22, 0, 0, 0, 0,22, 0,17,17,
604.4904 +	 0,21, 0,21,21, 0, 0, 0,18,19,23,21, 0,20,19, 0,
604.4905 +	 0, 0, 0, 0, 0, 0, 0,17,17, 0,20, 0, 0, 0, 0, 0,
604.4906 +	 0,19,19,23,22,
604.4907 +};
604.4908 +
604.4909 +static const static_codebook _44p4_p5_0 = {
604.4910 +	5, 3125,
604.4911 +	(long *)_vq_lengthlist__44p4_p5_0,
604.4912 +	1, -528744448, 1616642048, 3, 0,
604.4913 +	(long *)_vq_quantlist__44p4_p5_0,
604.4914 +	0
604.4915 +};
604.4916 +
604.4917 +static const long _vq_quantlist__44p4_p5_1[] = {
604.4918 +	3,
604.4919 +	2,
604.4920 +	4,
604.4921 +	1,
604.4922 +	5,
604.4923 +	0,
604.4924 +	6,
604.4925 +};
604.4926 +
604.4927 +static const long _vq_lengthlist__44p4_p5_1[] = {
604.4928 +	 2, 3, 3, 3, 3, 3, 3,
604.4929 +};
604.4930 +
604.4931 +static const static_codebook _44p4_p5_1 = {
604.4932 +	1, 7,
604.4933 +	(long *)_vq_lengthlist__44p4_p5_1,
604.4934 +	1, -533200896, 1611661312, 3, 0,
604.4935 +	(long *)_vq_quantlist__44p4_p5_1,
604.4936 +	0
604.4937 +};
604.4938 +
604.4939 +static const long _vq_quantlist__44p4_p6_0[] = {
604.4940 +	1,
604.4941 +	0,
604.4942 +	2,
604.4943 +};
604.4944 +
604.4945 +static const long _vq_lengthlist__44p4_p6_0[] = {
604.4946 +	 1, 7, 7, 7, 8, 8, 7, 8, 8, 7, 9, 9,11,11,11, 9,
604.4947 +	 8, 8, 8, 9, 9,12,11,12, 9, 8, 8, 6, 7, 7,10,11,
604.4948 +	11,10,10,10,11,11,11,14,14,14,12,11,12,11,11,11,
604.4949 +	15,15,14,13,12,12, 5, 6, 6, 8, 5, 5, 8, 7, 7, 8,
604.4950 +	 7, 7,12,10,10,10, 7, 6, 9, 8, 8,12,10,10,10, 6,
604.4951 +	 6, 7, 8, 8,12,10,10,12,10,10,11,10,10,16,14,14,
604.4952 +	13,10,10,12,10,10,15,14,14,14,10,10, 7, 7, 7,13,
604.4953 +	11,11,13,11,11,12,11,11,16,14,14,14,12,12,12,11,
604.4954 +	11,18,15,15,14,12,12,10, 9,10,14,11,11,13,11,11,
604.4955 +	12,11,11,17,14,14,14,11,11,13,11,11,16,15,15,14,
604.4956 +	11,11, 7, 8, 8,13,11,11,12,10,10,12,10,10,16,14,
604.4957 +	13,13,10,10,12,10,10,17,14,14,14,10,10, 8, 7, 7,
604.4958 +	12,11,11,13,11,11,12,11,11,16,15,14,14,12,12,12,
604.4959 +	11,11,16,15,15,14,12,12,11,10,10,14,11,11,13,11,
604.4960 +	11,13,11,11,17,14,14,14,11,11,13,11,11,18,14,15,
604.4961 +	15,11,10,
604.4962 +};
604.4963 +
604.4964 +static const static_codebook _44p4_p6_0 = {
604.4965 +	5, 243,
604.4966 +	(long *)_vq_lengthlist__44p4_p6_0,
604.4967 +	1, -527106048, 1620377600, 2, 0,
604.4968 +	(long *)_vq_quantlist__44p4_p6_0,
604.4969 +	0
604.4970 +};
604.4971 +
604.4972 +static const long _vq_quantlist__44p4_p6_1[] = {
604.4973 +	1,
604.4974 +	0,
604.4975 +	2,
604.4976 +};
604.4977 +
604.4978 +static const long _vq_lengthlist__44p4_p6_1[] = {
604.4979 +	 2, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,
604.4980 +	 7, 7, 8, 8, 8, 9, 9, 9, 9, 8, 8, 6, 7, 7, 8, 8,
604.4981 +	 8, 8, 8, 8, 9, 8, 8, 9, 8, 9, 9, 8, 8,10, 8, 8,
604.4982 +	10, 9, 9,10, 8, 8, 6, 6, 6, 8, 6, 6, 8, 7, 7, 8,
604.4983 +	 7, 7,10, 8, 8, 9, 7, 7, 9, 7, 7,10, 8, 8, 9, 7,
604.4984 +	 7, 7, 7, 7,10, 8, 8,11, 9, 9,10, 9, 9,11, 9, 9,
604.4985 +	11, 8, 8,11, 9, 9,12, 9, 9,12, 8, 8, 7, 7, 7,10,
604.4986 +	 9, 9,10, 9, 9,10, 9, 9,11,10,10,10, 9, 9,11, 9,
604.4987 +	10,11,10,11,10, 9, 9, 9, 8, 8,10, 9, 9,10, 9, 9,
604.4988 +	11, 9, 9,11,10,10,11, 9, 9,11, 9, 9,11,10,10,11,
604.4989 +	 9, 9, 8, 8, 8,11, 9, 9,11, 9, 9,11, 9, 9,12, 9,
604.4990 +	 9,12, 8, 8,11, 9, 9,12, 9, 9,12, 8, 8, 8, 7, 7,
604.4991 +	10, 9, 9,10, 9, 9,10, 9, 9,11,11,11,11, 9, 9,11,
604.4992 +	10,10,11,11,11,11, 9, 9,10, 9, 9,11, 9, 9,11, 9,
604.4993 +	10,11,10,10,11,10,10,11, 9, 9,11,10,10,11,10,10,
604.4994 +	11, 9, 9,
604.4995 +};
604.4996 +
604.4997 +static const static_codebook _44p4_p6_1 = {
604.4998 +	5, 243,
604.4999 +	(long *)_vq_lengthlist__44p4_p6_1,
604.5000 +	1, -530841600, 1616642048, 2, 0,
604.5001 +	(long *)_vq_quantlist__44p4_p6_1,
604.5002 +	0
604.5003 +};
604.5004 +
604.5005 +static const long _vq_quantlist__44p4_p7_0[] = {
604.5006 +	1,
604.5007 +	0,
604.5008 +	2,
604.5009 +};
604.5010 +
604.5011 +static const long _vq_lengthlist__44p4_p7_0[] = {
604.5012 +	 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.5013 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5014 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5015 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5016 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5017 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5018 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5019 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5020 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5021 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5022 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5023 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5024 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5025 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5026 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5027 +	 9, 9, 9,
604.5028 +};
604.5029 +
604.5030 +static const static_codebook _44p4_p7_0 = {
604.5031 +	5, 243,
604.5032 +	(long *)_vq_lengthlist__44p4_p7_0,
604.5033 +	1, -513979392, 1633504256, 2, 0,
604.5034 +	(long *)_vq_quantlist__44p4_p7_0,
604.5035 +	0
604.5036 +};
604.5037 +
604.5038 +static const long _vq_quantlist__44p4_p7_1[] = {
604.5039 +	1,
604.5040 +	0,
604.5041 +	2,
604.5042 +};
604.5043 +
604.5044 +static const long _vq_lengthlist__44p4_p7_1[] = {
604.5045 +	 1, 9, 9, 7, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 8,
604.5046 +	 9, 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 7, 9, 9, 9, 9,
604.5047 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5048 +	 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5049 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5050 +	 9, 5, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5051 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9,
604.5052 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5053 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5054 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.5055 +	 9, 9, 5,10, 9,10,10,10,10,10,10,10,10,10,10,10,
604.5056 +	10,10,10,10,10,10,10,10,10,10,10,10,10, 8,10,10,
604.5057 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.5058 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.5059 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.5060 +	10,10,10,
604.5061 +};
604.5062 +
604.5063 +static const static_codebook _44p4_p7_1 = {
604.5064 +	5, 243,
604.5065 +	(long *)_vq_lengthlist__44p4_p7_1,
604.5066 +	1, -516716544, 1630767104, 2, 0,
604.5067 +	(long *)_vq_quantlist__44p4_p7_1,
604.5068 +	0
604.5069 +};
604.5070 +
604.5071 +static const long _vq_quantlist__44p4_p7_2[] = {
604.5072 +	12,
604.5073 +	11,
604.5074 +	13,
604.5075 +	10,
604.5076 +	14,
604.5077 +	9,
604.5078 +	15,
604.5079 +	8,
604.5080 +	16,
604.5081 +	7,
604.5082 +	17,
604.5083 +	6,
604.5084 +	18,
604.5085 +	5,
604.5086 +	19,
604.5087 +	4,
604.5088 +	20,
604.5089 +	3,
604.5090 +	21,
604.5091 +	2,
604.5092 +	22,
604.5093 +	1,
604.5094 +	23,
604.5095 +	0,
604.5096 +	24,
604.5097 +};
604.5098 +
604.5099 +static const long _vq_lengthlist__44p4_p7_2[] = {
604.5100 +	 1, 3, 2, 5, 4, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
604.5101 +	12,13,13,14,14,15,15,15,15,
604.5102 +};
604.5103 +
604.5104 +static const static_codebook _44p4_p7_2 = {
604.5105 +	1, 25,
604.5106 +	(long *)_vq_lengthlist__44p4_p7_2,
604.5107 +	1, -518864896, 1620639744, 5, 0,
604.5108 +	(long *)_vq_quantlist__44p4_p7_2,
604.5109 +	0
604.5110 +};
604.5111 +
604.5112 +static const long _vq_quantlist__44p4_p7_3[] = {
604.5113 +	12,
604.5114 +	11,
604.5115 +	13,
604.5116 +	10,
604.5117 +	14,
604.5118 +	9,
604.5119 +	15,
604.5120 +	8,
604.5121 +	16,
604.5122 +	7,
604.5123 +	17,
604.5124 +	6,
604.5125 +	18,
604.5126 +	5,
604.5127 +	19,
604.5128 +	4,
604.5129 +	20,
604.5130 +	3,
604.5131 +	21,
604.5132 +	2,
604.5133 +	22,
604.5134 +	1,
604.5135 +	23,
604.5136 +	0,
604.5137 +	24,
604.5138 +};
604.5139 +
604.5140 +static const long _vq_lengthlist__44p4_p7_3[] = {
604.5141 +	 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.5142 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.5143 +};
604.5144 +
604.5145 +static const static_codebook _44p4_p7_3 = {
604.5146 +	1, 25,
604.5147 +	(long *)_vq_lengthlist__44p4_p7_3,
604.5148 +	1, -529006592, 1611661312, 5, 0,
604.5149 +	(long *)_vq_quantlist__44p4_p7_3,
604.5150 +	0
604.5151 +};
604.5152 +
604.5153 +static const long _huff_lengthlist__44p4_short[] = {
604.5154 +	 3, 5,16, 9, 9,13,18,21, 4, 2,21, 6, 6,10,15,21,
604.5155 +	16,19, 6, 5, 7,10,13,16, 8, 6, 5, 4, 4, 8,13,16,
604.5156 +	 8, 5, 6, 4, 4, 7,12,15,13,10, 9, 7, 7, 9,13,16,
604.5157 +	18,15,13,12, 9, 7,10,14,21,18,13,13, 7, 5, 8,12,
604.5158 +};
604.5159 +
604.5160 +static const static_codebook _huff_book__44p4_short = {
604.5161 +	2, 64,
604.5162 +	(long *)_huff_lengthlist__44p4_short,
604.5163 +	0, 0, 0, 0, 0,
604.5164 +	NULL,
604.5165 +	0
604.5166 +};
604.5167 +
604.5168 +static const long _vq_quantlist__44p5_l0_0[] = {
604.5169 +	6,
604.5170 +	5,
604.5171 +	7,
604.5172 +	4,
604.5173 +	8,
604.5174 +	3,
604.5175 +	9,
604.5176 +	2,
604.5177 +	10,
604.5178 +	1,
604.5179 +	11,
604.5180 +	0,
604.5181 +	12,
604.5182 +};
604.5183 +
604.5184 +static const long _vq_lengthlist__44p5_l0_0[] = {
604.5185 +	 1, 4, 4, 8, 8,10,10,10,10, 9, 8,11,11, 4, 6, 5,
604.5186 +	 8, 6,10,10,10,10,10, 9,10, 9, 4, 5, 6, 6, 9,10,
604.5187 +	10,10,10, 9,10, 9,10, 8, 9, 8, 9, 8, 9, 9,10, 9,
604.5188 +	11,10,12,10, 8, 8, 9, 8, 9, 9, 9, 9,10,10,11,10,
604.5189 +	12, 9,10,10,11,10,11,10,12,11,12,11,13,11, 9,10,
604.5190 +	10,10,11,10,11,11,12,11,12,11,12,11,12,12,12,12,
604.5191 +	13,12,13,12,13,12,13,13,11,12,12,12,12,12,12,12,
604.5192 +	13,13,13,13,13,12,12,12,13,13,13,13,13,13,13,13,
604.5193 +	13,13,12,13,12,13,13,13,13,13,13,13,13,13,13,12,
604.5194 +	13,13,13,14,14,13,13,13,13,13,13,13,12,13,12,13,
604.5195 +	13,13,13,13,13,13,13,13,13,
604.5196 +};
604.5197 +
604.5198 +static const static_codebook _44p5_l0_0 = {
604.5199 +	2, 169,
604.5200 +	(long *)_vq_lengthlist__44p5_l0_0,
604.5201 +	1, -526516224, 1616117760, 4, 0,
604.5202 +	(long *)_vq_quantlist__44p5_l0_0,
604.5203 +	0
604.5204 +};
604.5205 +
604.5206 +static const long _vq_quantlist__44p5_l0_1[] = {
604.5207 +	2,
604.5208 +	1,
604.5209 +	3,
604.5210 +	0,
604.5211 +	4,
604.5212 +};
604.5213 +
604.5214 +static const long _vq_lengthlist__44p5_l0_1[] = {
604.5215 +	 4, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 4, 4, 5, 5,
604.5216 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.5217 +};
604.5218 +
604.5219 +static const static_codebook _44p5_l0_1 = {
604.5220 +	2, 25,
604.5221 +	(long *)_vq_lengthlist__44p5_l0_1,
604.5222 +	1, -533725184, 1611661312, 3, 0,
604.5223 +	(long *)_vq_quantlist__44p5_l0_1,
604.5224 +	0
604.5225 +};
604.5226 +
604.5227 +static const long _vq_quantlist__44p5_l1_0[] = {
604.5228 +	1,
604.5229 +	0,
604.5230 +	2,
604.5231 +};
604.5232 +
604.5233 +static const long _vq_lengthlist__44p5_l1_0[] = {
604.5234 +	 1, 4, 4, 4, 4, 4, 4, 4, 4,
604.5235 +};
604.5236 +
604.5237 +static const static_codebook _44p5_l1_0 = {
604.5238 +	2, 9,
604.5239 +	(long *)_vq_lengthlist__44p5_l1_0,
604.5240 +	1, -516716544, 1630767104, 2, 0,
604.5241 +	(long *)_vq_quantlist__44p5_l1_0,
604.5242 +	0
604.5243 +};
604.5244 +
604.5245 +static const long _huff_lengthlist__44p5_lfe[] = {
604.5246 +	 1, 3, 2, 3,
604.5247 +};
604.5248 +
604.5249 +static const static_codebook _huff_book__44p5_lfe = {
604.5250 +	2, 4,
604.5251 +	(long *)_huff_lengthlist__44p5_lfe,
604.5252 +	0, 0, 0, 0, 0,
604.5253 +	NULL,
604.5254 +	0
604.5255 +};
604.5256 +
604.5257 +static const long _huff_lengthlist__44p5_long[] = {
604.5258 +	 3, 7,12,14,14,16,18,19, 6, 2, 4, 6, 8, 9,12,14,
604.5259 +	12, 3, 3, 5, 7, 8,11,13,13, 6, 4, 5, 7, 8,10,11,
604.5260 +	14, 8, 7, 7, 7, 7, 9,10,15, 9, 8, 7, 7, 6, 8, 9,
604.5261 +	17,11,11,10, 9, 8, 9, 9,19,14,13,11,10, 9, 9, 9,
604.5262 +};
604.5263 +
604.5264 +static const static_codebook _huff_book__44p5_long = {
604.5265 +	2, 64,
604.5266 +	(long *)_huff_lengthlist__44p5_long,
604.5267 +	0, 0, 0, 0, 0,
604.5268 +	NULL,
604.5269 +	0
604.5270 +};
604.5271 +
604.5272 +static const long _vq_quantlist__44p5_p1_0[] = {
604.5273 +	1,
604.5274 +	0,
604.5275 +	2,
604.5276 +};
604.5277 +
604.5278 +static const long _vq_lengthlist__44p5_p1_0[] = {
604.5279 +	 2, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 8, 9, 7,
604.5280 +	 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 8, 5, 7, 8, 8, 9,
604.5281 +	10, 8, 9,10, 8, 9,10, 9,10,12,10,11,11, 8,10,10,
604.5282 +	10,11,11, 9,11,11, 5, 8, 7, 8, 9, 9, 8,10, 9, 8,
604.5283 +	10,10, 9,11,11,10,11,11, 8,10, 9,10,11,11, 9,12,
604.5284 +	10, 5, 8, 8, 7, 9,10, 8,10, 9, 7, 9, 9, 9,10,11,
604.5285 +	 9,11,11, 8,10, 9,10,11,11,10,11,11, 7, 9, 9, 9,
604.5286 +	10,11, 9,11,11, 9, 9,11,10,10,13,11,11,12, 9,11,
604.5287 +	11,11,12,13,11,13,12, 7, 9, 9, 9,11,11, 9,11,10,
604.5288 +	 9,11,10,10,11,12,11,13,12, 9,11,11,11,12,13,11,
604.5289 +	13,11, 5, 8, 8, 8, 9,10, 7,10, 9, 8, 9,10,10,11,
604.5290 +	11,10,11,11, 7, 9, 9, 9,11,11, 9,11,10, 7, 9, 9,
604.5291 +	 9,10,11, 9,11,11, 9,11,11,11,11,13,11,13,12, 9,
604.5292 +	10,11,11,12,13,10,12,11, 7, 9, 9, 9,11,11, 9,11,
604.5293 +	10, 9,11,11,11,12,13,11,13,12, 9,11, 9,11,12,11,
604.5294 +	10,13,10,
604.5295 +};
604.5296 +
604.5297 +static const static_codebook _44p5_p1_0 = {
604.5298 +	5, 243,
604.5299 +	(long *)_vq_lengthlist__44p5_p1_0,
604.5300 +	1, -535822336, 1611661312, 2, 0,
604.5301 +	(long *)_vq_quantlist__44p5_p1_0,
604.5302 +	0
604.5303 +};
604.5304 +
604.5305 +static const long _vq_quantlist__44p5_p2_0[] = {
604.5306 +	2,
604.5307 +	1,
604.5308 +	3,
604.5309 +	0,
604.5310 +	4,
604.5311 +};
604.5312 +
604.5313 +static const long _vq_lengthlist__44p5_p2_0[] = {
604.5314 +	 4, 6, 6, 9, 9, 6, 7, 8,10,10, 6, 8, 7,10,10, 8,
604.5315 +	10,10,12,13, 8,10,10,13,12, 6, 7, 8,10,10, 7, 8,
604.5316 +	 9,10,11, 8, 9, 9,11,11,10,10,11,12,14,10,11,11,
604.5317 +	14,13, 6, 8, 7,10,10, 8, 9, 9,11,11, 7, 9, 8,11,
604.5318 +	10,10,11,11,13,14,10,11,10,14,12, 9,10,10,12,12,
604.5319 +	10,10,11,12,13,10,11,11,13,13,12,12,13,12,15,13,
604.5320 +	14,13,15,14, 9,10,10,12,12,10,11,11,13,13,10,11,
604.5321 +	10,13,12,13,13,14,14,15,12,13,12,15,12, 6, 7, 8,
604.5322 +	10,11, 8, 9,10,11,12, 8, 9, 9,11,12,10,11,12,13,
604.5323 +	14,10,11,11,14,13, 8, 9,10,11,12, 9,10,11,12,13,
604.5324 +	 9,10,11,12,13,11,12,13,13,15,12,12,13,15,14, 8,
604.5325 +	 9, 9,12,12, 9,10,11,12,13, 9,10,10,13,12,12,12,
604.5326 +	13,14,15,11,12,12,14,14,11,11,12,13,14,11,12,13,
604.5327 +	13,15,12,13,13,14,15,14,13,15,14,16,14,15,15,16,
604.5328 +	16,11,12,11,14,13,12,13,13,15,14,11,13,12,14,13,
604.5329 +	14,15,15,15,16,13,14,14,16,14, 6, 8, 7,11,10, 8,
604.5330 +	 9, 9,11,12, 8,10, 9,12,11,10,11,11,13,14,10,12,
604.5331 +	11,14,13, 8, 9, 9,12,12, 9,10,10,12,13, 9,11,10,
604.5332 +	13,12,11,12,12,13,14,12,13,12,15,14, 8,10, 9,12,
604.5333 +	11, 9,11,10,13,12, 9,11,10,13,12,12,13,12,14,15,
604.5334 +	11,13,12,15,13,11,11,12,13,14,11,12,13,13,15,12,
604.5335 +	13,13,14,15,13,14,14,14,16,14,15,15,16,16,11,12,
604.5336 +	11,14,13,12,13,13,15,14,11,13,12,15,13,14,15,15,
604.5337 +	16,16,13,15,13,16,14, 9,10,11,12,14,11,11,12,13,
604.5338 +	15,11,12,12,13,14,13,14,15,15,17,13,14,14,15,16,
604.5339 +	11,11,12,13,15,12,12,13,14,16,12,13,13,14,15,14,
604.5340 +	14,16,15,17,15,15,15,16,17,11,12,12,14,14,12,13,
604.5341 +	13,15,16,12,13,13,15,15,15,15,15,16,17,14,15,15,
604.5342 +	16,16,14,14,15,15,17,14,15,15,15,17,15,15,16,16,
604.5343 +	17,16,16,17,16,18,17,17,17,18,18,14,15,14,16,16,
604.5344 +	15,15,16,17,17,14,15,15,17,16,17,17,17,18,18,16,
604.5345 +	16,16,17,17, 9,11,10,14,12,11,12,12,14,13,11,12,
604.5346 +	11,15,13,13,14,14,16,15,13,15,14,17,15,11,12,12,
604.5347 +	15,14,12,13,13,15,15,12,13,13,15,15,14,15,15,16,
604.5348 +	16,15,15,15,17,16,11,12,11,15,13,12,13,13,15,14,
604.5349 +	12,13,12,16,14,15,15,15,17,16,14,15,14,17,15,14,
604.5350 +	14,15,16,16,14,15,15,16,16,15,16,15,17,17,16,16,
604.5351 +	16,17,17,17,17,17,18,17,14,15,14,16,15,15,15,15,
604.5352 +	17,16,15,15,15,17,15,17,17,17,18,18,16,17,16,18,
604.5353 +	16, 6, 8, 8,11,11, 8, 9, 9,11,12, 8, 9, 9,12,11,
604.5354 +	10,11,11,13,14,10,12,11,14,13, 7, 9, 9,11,12, 9,
604.5355 +	10,10,12,13, 9,10,10,13,13,11,11,12,13,15,11,12,
604.5356 +	12,15,14, 8, 9, 9,12,11, 9,11,10,13,13, 9,11,10,
604.5357 +	13,12,12,13,12,14,15,11,13,12,15,13,10,11,12,13,
604.5358 +	14,11,12,12,13,15,12,12,13,14,15,13,13,14,14,16,
604.5359 +	14,15,15,16,16,11,12,11,14,13,12,13,13,15,14,11,
604.5360 +	13,12,15,13,14,15,15,15,16,13,14,14,16,14, 7, 9,
604.5361 +	 9,11,12, 9,10,11,12,13, 9,10,10,13,12,11,12,12,
604.5362 +	14,15,11,12,12,15,14, 9, 9,11,11,13,10,10,12,12,
604.5363 +	14,10,11,12,13,14,12,12,13,14,16,12,13,13,15,15,
604.5364 +	 9,11,10,13,13,10,12,12,13,14,10,12,11,14,13,12,
604.5365 +	13,13,15,16,12,13,13,15,14,11,11,13,13,15,12,12,
604.5366 +	14,13,16,13,13,13,14,15,14,14,15,14,17,15,15,15,
604.5367 +	16,16,12,13,12,15,14,13,14,14,15,15,12,14,13,16,
604.5368 +	14,15,15,16,16,17,14,15,14,17,15, 7, 9, 9,12,11,
604.5369 +	 9,10,10,12,13, 9,11,10,13,12,11,12,12,14,14,11,
604.5370 +	13,12,15,14, 9,10,10,13,12,10,10,11,12,13,10,12,
604.5371 +	11,14,13,12,12,13,13,15,12,14,13,16,15, 9,10,10,
604.5372 +	13,12,11,11,12,13,13,10,12,10,14,12,13,13,13,15,
604.5373 +	15,12,13,12,15,13,11,12,12,14,14,12,12,13,14,15,
604.5374 +	13,14,13,15,15,14,13,15,13,16,15,16,15,17,16,12,
604.5375 +	13,12,14,14,13,14,14,15,15,12,13,12,15,14,15,15,
604.5376 +	16,16,17,14,15,13,16,13,10,11,12,13,14,11,12,13,
604.5377 +	14,15,12,13,13,15,15,14,14,15,15,17,14,15,15,16,
604.5378 +	16,12,12,13,12,15,12,12,14,13,16,13,13,14,14,16,
604.5379 +	14,14,16,15,17,15,15,16,16,17,12,13,13,15,15,13,
604.5380 +	14,14,16,16,13,14,13,16,15,15,16,16,17,17,14,15,
604.5381 +	15,17,16,14,14,15,14,17,15,15,16,15,17,15,15,16,
604.5382 +	15,17,16,16,17,16,18,17,17,17,17,18,14,15,15,17,
604.5383 +	16,15,16,16,17,17,15,16,15,17,16,17,17,17,18,18,
604.5384 +	16,17,16,18,17,10,12,11,14,14,12,13,13,15,15,12,
604.5385 +	13,12,15,14,14,15,15,16,16,14,15,15,17,16,11,13,
604.5386 +	12,15,14,12,13,13,15,15,13,14,13,16,14,15,15,15,
604.5387 +	16,16,15,16,15,17,16,12,13,13,15,15,13,14,14,16,
604.5388 +	16,12,14,13,16,15,15,16,16,17,17,15,16,15,17,16,
604.5389 +	14,15,15,16,16,14,15,15,16,16,15,16,16,17,16,16,
604.5390 +	16,16,16,17,17,18,17,18,17,14,15,15,17,16,15,16,
604.5391 +	16,17,17,15,16,15,17,16,17,17,18,18,18,16,17,16,
604.5392 +	18,16, 6, 8, 8,11,11, 8, 9, 9,11,12, 8, 9, 9,12,
604.5393 +	11,10,11,12,13,14,10,11,11,14,13, 8, 9, 9,11,12,
604.5394 +	 9,10,11,12,13, 9,10,11,13,13,11,12,13,13,15,12,
604.5395 +	12,12,15,14, 7, 9, 9,12,11, 9,10,10,13,13, 9,10,
604.5396 +	10,13,12,11,12,12,14,15,11,12,11,15,13,11,11,12,
604.5397 +	13,14,11,12,13,13,15,12,13,13,14,15,13,14,14,14,
604.5398 +	16,14,15,15,16,16,10,12,11,14,13,12,13,12,14,14,
604.5399 +	11,12,12,15,13,14,15,15,16,16,13,14,13,16,14, 7,
604.5400 +	 9, 9,11,12, 9,10,11,12,13, 9,10,10,13,12,11,12,
604.5401 +	13,14,15,11,12,12,14,14, 9,10,10,12,13,10,10,12,
604.5402 +	12,14,11,12,11,13,13,12,12,14,13,15,13,13,13,15,
604.5403 +	15, 9,10,10,12,13,10,11,12,13,14,10,11,10,13,12,
604.5404 +	13,13,14,15,16,12,13,12,15,13,12,13,13,14,14,12,
604.5405 +	12,13,14,15,13,14,14,15,15,14,13,15,13,16,15,16,
604.5406 +	15,17,16,11,12,12,14,14,13,13,14,15,15,12,13,12,
604.5407 +	15,14,15,15,16,16,17,14,14,13,16,13, 7, 9, 9,12,
604.5408 +	11, 9,10,10,12,13, 9,11,10,13,12,11,12,12,14,15,
604.5409 +	11,12,12,15,14, 9,10,11,13,13,10,11,12,13,14,10,
604.5410 +	12,12,14,13,12,13,13,14,16,12,13,13,16,15, 9,11,
604.5411 +	 9,13,11,10,12,11,13,13,10,12,10,14,12,12,13,13,
604.5412 +	15,15,12,13,12,16,14,12,12,13,14,15,12,13,14,14,
604.5413 +	15,13,14,14,15,15,14,14,15,15,17,15,16,15,17,16,
604.5414 +	11,13,11,15,13,13,14,13,15,14,12,14,12,16,13,15,
604.5415 +	15,15,16,16,14,15,14,17,14,10,11,12,14,14,12,12,
604.5416 +	13,14,15,12,13,13,15,15,14,15,15,16,17,14,15,15,
604.5417 +	16,16,12,12,13,15,15,13,13,14,15,16,13,14,14,16,
604.5418 +	16,15,15,16,16,17,15,16,16,17,17,11,12,13,14,15,
604.5419 +	13,13,14,15,16,12,13,13,15,15,15,15,16,16,17,15,
604.5420 +	15,15,16,16,14,15,15,16,17,15,15,16,16,17,15,16,
604.5421 +	16,17,17,16,16,17,16,18,17,17,17,18,18,14,15,15,
604.5422 +	16,16,15,16,16,16,17,15,15,15,16,16,17,17,17,18,
604.5423 +	18,16,16,16,17,16,10,12,11,14,13,12,13,13,15,15,
604.5424 +	11,13,12,15,14,14,15,15,16,16,14,15,14,17,15,12,
604.5425 +	13,13,15,15,13,13,14,16,16,13,14,14,16,16,15,15,
604.5426 +	15,16,17,15,16,16,17,17,12,13,12,15,12,13,14,13,
604.5427 +	16,14,12,14,12,16,13,15,16,15,17,16,14,16,14,17,
604.5428 +	15,14,15,15,16,17,15,15,16,17,17,15,16,16,17,17,
604.5429 +	16,16,17,17,18,17,18,17,18,18,14,15,14,17,14,15,
604.5430 +	16,15,17,15,15,16,15,17,15,17,17,17,18,17,16,17,
604.5431 +	16,18,16, 9,11,11,14,14,11,12,12,14,14,11,12,12,
604.5432 +	15,14,13,14,14,16,16,13,15,14,16,16,10,11,12,14,
604.5433 +	14,11,12,13,15,15,12,13,13,15,15,13,14,15,16,17,
604.5434 +	14,15,15,17,16,11,12,12,15,14,12,13,13,15,15,12,
604.5435 +	13,13,15,15,14,15,15,16,16,14,15,15,17,16,12,13,
604.5436 +	14,15,16,13,14,14,15,16,13,14,15,16,16,15,15,16,
604.5437 +	16,18,16,16,16,18,17,14,14,14,16,15,15,15,15,17,
604.5438 +	16,14,15,15,17,16,16,17,17,18,17,16,16,16,18,16,
604.5439 +	10,12,12,14,14,11,12,13,15,15,12,13,13,15,15,13,
604.5440 +	14,15,16,17,14,15,15,17,16,11,12,13,14,15,12,12,
604.5441 +	14,15,16,13,13,14,15,16,14,14,15,16,17,15,15,16,
604.5442 +	17,17,12,13,13,15,15,13,14,14,16,16,13,14,13,16,
604.5443 +	15,15,16,15,17,17,15,16,15,17,16,13,13,15,14,17,
604.5444 +	14,13,16,15,17,15,14,16,15,17,15,15,17,16,18,16,
604.5445 +	16,17,17,18,14,15,15,17,16,15,16,16,17,17,15,16,
604.5446 +	15,17,16,17,17,17,18,18,16,17,16,18,17,10,12,11,
604.5447 +	14,14,11,12,13,15,15,12,13,12,15,15,14,15,15,16,
604.5448 +	16,14,15,15,17,16,11,12,12,15,15,12,13,13,15,15,
604.5449 +	13,14,13,16,15,14,15,15,16,16,15,16,15,17,16,11,
604.5450 +	13,13,15,15,13,14,14,15,15,12,14,13,16,15,15,16,
604.5451 +	15,17,17,15,16,15,17,16,13,15,14,16,16,14,15,14,
604.5452 +	16,16,15,16,15,17,16,15,16,16,16,17,16,17,16,18,
604.5453 +	17,14,15,15,16,16,15,16,16,17,17,15,15,15,17,16,
604.5454 +	17,17,17,18,18,16,16,16,18,16,12,13,13,15,16,13,
604.5455 +	14,14,15,16,13,14,14,16,16,15,15,16,16,18,15,16,
604.5456 +	16,17,17,13,13,14,15,16,14,14,15,15,17,14,15,15,
604.5457 +	16,17,15,15,17,16,18,16,16,17,17,17,13,14,14,16,
604.5458 +	16,14,15,15,17,17,14,15,14,17,16,16,17,16,17,18,
604.5459 +	16,17,16,18,17,15,15,16,14,17,16,15,17,14,18,16,
604.5460 +	16,16,15,18,16,16,18,15,19,18,18,18,17,19,15,16,
604.5461 +	16,18,17,16,17,17,18,17,16,17,16,18,17,18,18,18,
604.5462 +	19,19,17,18,16,18,17,11,12,12,15,15,13,13,14,15,
604.5463 +	16,13,14,13,16,15,15,16,16,16,17,15,16,16,17,16,
604.5464 +	12,14,13,16,15,13,13,14,15,16,14,15,14,17,15,15,
604.5465 +	15,16,16,17,16,17,16,18,17,12,13,14,15,16,14,15,
604.5466 +	15,16,16,13,14,13,16,15,16,16,16,17,17,15,16,15,
604.5467 +	17,15,15,16,15,17,16,15,15,15,16,16,16,17,16,18,
604.5468 +	16,16,15,16,15,17,17,18,17,18,17,15,15,16,17,17,
604.5469 +	16,16,17,17,17,15,16,15,17,16,18,18,18,18,18,16,
604.5470 +	17,16,18,15, 9,11,11,14,14,11,12,12,14,15,10,12,
604.5471 +	12,15,14,13,14,15,16,16,13,14,14,16,16,11,12,12,
604.5472 +	14,15,12,12,13,15,15,12,13,13,15,15,14,15,15,16,
604.5473 +	17,14,15,15,16,16,10,12,12,14,14,12,13,13,15,15,
604.5474 +	11,13,12,15,15,14,15,15,16,17,13,15,14,16,16,14,
604.5475 +	14,14,15,16,14,15,15,16,17,14,15,15,16,17,16,16,
604.5476 +	17,16,18,16,17,17,17,17,12,14,13,16,15,13,15,14,
604.5477 +	16,16,13,14,14,16,15,16,16,16,17,17,15,16,15,17,
604.5478 +	16,10,11,11,14,14,12,12,13,14,15,11,13,12,15,14,
604.5479 +	14,15,15,16,17,14,15,15,16,16,12,13,13,15,15,12,
604.5480 +	13,14,15,16,13,14,14,15,15,15,15,16,16,17,15,15,
604.5481 +	16,17,17,11,12,12,15,15,13,13,14,15,16,12,13,13,
604.5482 +	15,15,15,15,16,16,17,14,15,15,16,16,14,15,15,16,
604.5483 +	16,15,15,15,16,17,15,16,16,17,17,16,16,17,16,18,
604.5484 +	17,17,17,17,18,13,14,15,16,16,15,15,16,16,17,14,
604.5485 +	14,14,16,16,16,16,17,17,18,16,16,16,17,16,10,12,
604.5486 +	12,14,14,12,13,13,15,15,11,13,12,15,15,14,15,15,
604.5487 +	16,17,13,15,14,17,16,12,13,13,15,15,13,13,14,15,
604.5488 +	16,13,14,14,16,16,15,15,16,16,17,15,15,16,17,17,
604.5489 +	11,13,12,15,14,13,14,13,16,15,12,14,12,16,15,15,
604.5490 +	16,15,17,17,14,15,14,17,16,14,15,15,16,17,15,15,
604.5491 +	16,16,17,15,16,16,17,17,16,16,17,17,18,17,17,17,
604.5492 +	18,18,13,15,13,17,14,14,16,14,17,16,14,15,13,17,
604.5493 +	15,16,17,16,18,17,15,17,15,18,16,11,12,12,15,15,
604.5494 +	13,13,14,15,16,13,14,13,16,15,15,16,16,16,17,15,
604.5495 +	16,16,17,16,12,14,13,16,15,13,13,14,15,16,14,15,
604.5496 +	15,16,16,16,15,16,16,17,16,16,16,17,17,12,13,14,
604.5497 +	15,16,14,14,15,15,17,13,14,13,16,15,16,16,17,17,
604.5498 +	18,15,16,15,17,15,15,16,15,17,17,15,15,16,16,17,
604.5499 +	16,17,16,17,17,16,15,17,15,18,17,18,17,18,18,15,
604.5500 +	15,16,16,17,16,16,17,16,18,15,15,15,16,16,17,17,
604.5501 +	18,17,18,16,16,15,17,15,12,13,13,15,15,13,14,14,
604.5502 +	16,16,13,14,14,16,16,15,16,16,17,18,15,16,15,18,
604.5503 +	16,13,14,14,16,16,14,14,15,16,17,14,15,15,17,17,
604.5504 +	16,16,17,17,18,16,16,17,18,17,13,14,13,16,14,14,
604.5505 +	15,15,17,16,14,15,14,17,15,16,17,17,18,17,15,17,
604.5506 +	15,18,16,15,16,16,17,17,16,16,17,17,18,16,17,17,
604.5507 +	18,18,17,16,18,17,19,18,18,18,18,18,15,16,15,17,
604.5508 +	14,16,16,16,18,15,16,17,15,18,14,18,18,18,18,17,
604.5509 +	17,18,16,19,15,
604.5510 +};
604.5511 +
604.5512 +static const static_codebook _44p5_p2_0 = {
604.5513 +	5, 3125,
604.5514 +	(long *)_vq_lengthlist__44p5_p2_0,
604.5515 +	1, -533725184, 1611661312, 3, 0,
604.5516 +	(long *)_vq_quantlist__44p5_p2_0,
604.5517 +	0
604.5518 +};
604.5519 +
604.5520 +static const long _vq_quantlist__44p5_p3_0[] = {
604.5521 +	1,
604.5522 +	0,
604.5523 +	2,
604.5524 +};
604.5525 +
604.5526 +static const long _vq_lengthlist__44p5_p3_0[] = {
604.5527 +	 1, 5, 6, 5, 7, 8, 5, 8, 7, 5, 7, 8, 7, 8,10, 8,
604.5528 +	10,10, 5, 8, 7, 8,10,10, 7,10, 8, 6, 8, 9, 8,10,
604.5529 +	11, 9,10,10, 9,10,11,10,11,12,11,12,12, 9,11,10,
604.5530 +	11,12,12,10,12,11, 6, 9, 8, 9,10,10, 8,11,10, 9,
604.5531 +	10,11,10,11,12,11,12,12, 9,11,10,11,12,12,10,12,
604.5532 +	11, 6, 9, 9, 8,10,11, 9,11,10, 8,10,10,10,10,12,
604.5533 +	11,12,12, 9,11,10,11,12,12,10,12,11, 8,10,10,10,
604.5534 +	11,12,10,12,11,10,10,12,11,11,13,12,13,13,10,12,
604.5535 +	11,12,13,13,11,13,11, 7,10,10,10,11,12,10,12,11,
604.5536 +	10,12,11,11,11,12,12,14,13,10,12,12,12,14,14,11,
604.5537 +	13,11, 6, 9, 9, 9,10,11, 8,11,10, 9,10,11,10,11,
604.5538 +	12,11,12,12, 8,11,10,11,12,12,10,12,10, 7,10,10,
604.5539 +	10,11,12,10,12,11,10,12,12,11,11,13,12,13,13,10,
604.5540 +	11,12,12,13,14,11,12,11, 8,10,10,10,11,12,10,12,
604.5541 +	11,10,11,12,11,11,13,12,13,13,10,12,10,12,13,13,
604.5542 +	11,13,11,
604.5543 +};
604.5544 +
604.5545 +static const static_codebook _44p5_p3_0 = {
604.5546 +	5, 243,
604.5547 +	(long *)_vq_lengthlist__44p5_p3_0,
604.5548 +	1, -533200896, 1614282752, 2, 0,
604.5549 +	(long *)_vq_quantlist__44p5_p3_0,
604.5550 +	0
604.5551 +};
604.5552 +
604.5553 +static const long _vq_quantlist__44p5_p3_1[] = {
604.5554 +	1,
604.5555 +	0,
604.5556 +	2,
604.5557 +};
604.5558 +
604.5559 +static const long _vq_lengthlist__44p5_p3_1[] = {
604.5560 +	 5, 6, 6, 6, 7, 7, 6, 7, 7, 6, 7, 7, 7, 7, 8, 7,
604.5561 +	 8, 8, 6, 7, 7, 7, 8, 8, 7, 8, 7, 7, 8, 8, 8, 8,
604.5562 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8,
604.5563 +	 8, 9, 9, 8, 9, 9, 7, 8, 7, 8, 8, 8, 8, 8, 8, 8,
604.5564 +	 8, 8, 8, 9, 9, 8, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9,
604.5565 +	 8, 6, 8, 8, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8, 9,
604.5566 +	 8, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9, 8, 7, 8, 8, 8,
604.5567 +	 9, 9, 8, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 8, 9,
604.5568 +	 9, 9, 9, 9, 9, 9, 9, 7, 8, 8, 8, 8, 9, 8, 9, 8,
604.5569 +	 8, 8, 8, 8, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8,
604.5570 +	 9, 9, 6, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8,
604.5571 +	 9, 8, 9, 9, 7, 8, 8, 8, 9, 9, 8, 9, 8, 7, 8, 8,
604.5572 +	 8, 8, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 8,
604.5573 +	 8, 8, 9, 9, 9, 8, 9, 9, 7, 8, 8, 8, 9, 9, 8, 9,
604.5574 +	 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9,
604.5575 +	 9, 9, 9,
604.5576 +};
604.5577 +
604.5578 +static const static_codebook _44p5_p3_1 = {
604.5579 +	5, 243,
604.5580 +	(long *)_vq_lengthlist__44p5_p3_1,
604.5581 +	1, -535822336, 1611661312, 2, 0,
604.5582 +	(long *)_vq_quantlist__44p5_p3_1,
604.5583 +	0
604.5584 +};
604.5585 +
604.5586 +static const long _vq_quantlist__44p5_p4_0[] = {
604.5587 +	1,
604.5588 +	0,
604.5589 +	2,
604.5590 +};
604.5591 +
604.5592 +static const long _vq_lengthlist__44p5_p4_0[] = {
604.5593 +	 1, 5, 5, 5, 7, 9, 5, 9, 7, 5, 7, 8, 7, 7,10, 9,
604.5594 +	10,10, 5, 8, 7, 9,10,10, 7,10, 7, 6, 8, 9, 9,10,
604.5595 +	12, 9,11,11, 9,10,11,11,11,13,12,13,13, 9,11,11,
604.5596 +	11,12,13,11,13,11, 6, 9, 8, 9,11,11, 9,12,10, 9,
604.5597 +	11,11,11,11,13,11,13,12, 9,11,10,12,13,13,11,13,
604.5598 +	11, 6, 9, 9, 8,10,11, 9,12,11, 9,10,11,10,10,12,
604.5599 +	11,13,13, 9,11,11,11,13,12,11,13,11, 8,10,10, 9,
604.5600 +	10,12,10,12,11,10,10,12,10,10,13,12,13,13,10,12,
604.5601 +	11,12,13,13,10,13,10, 7,10,10,11,11,13,11,14,11,
604.5602 +	10,12,11,11,11,13,13,14,13,10,12,12,14,14,14,11,
604.5603 +	14,11, 6, 9, 9, 9,11,12, 8,11,10, 9,11,11,11,11,
604.5604 +	13,11,12,13, 8,11,10,11,13,13,10,12,10, 7,10,10,
604.5605 +	11,11,14,11,13,11,10,12,12,11,11,14,14,14,14,10,
604.5606 +	11,12,13,13,14,11,13,11, 8,10,10,10,11,12, 9,12,
604.5607 +	10,10,11,12,11,10,13,12,13,13,10,12,10,12,13,13,
604.5608 +	11,13,10,
604.5609 +};
604.5610 +
604.5611 +static const static_codebook _44p5_p4_0 = {
604.5612 +	5, 243,
604.5613 +	(long *)_vq_lengthlist__44p5_p4_0,
604.5614 +	1, -531365888, 1616117760, 2, 0,
604.5615 +	(long *)_vq_quantlist__44p5_p4_0,
604.5616 +	0
604.5617 +};
604.5618 +
604.5619 +static const long _vq_quantlist__44p5_p4_1[] = {
604.5620 +	2,
604.5621 +	1,
604.5622 +	3,
604.5623 +	0,
604.5624 +	4,
604.5625 +};
604.5626 +
604.5627 +static const long _vq_lengthlist__44p5_p4_1[] = {
604.5628 +	 5, 7, 7,10,10, 7, 8, 9,10,11, 7, 9, 8,11,10, 9,
604.5629 +	10,10,11,11, 9,10,10,11,11, 7, 9, 9,10,10, 8, 9,
604.5630 +	10,10,11, 9,10,10,11,11,10,10,11,11,11,10,11,11,
604.5631 +	12,12, 7, 9, 9,10,10, 9,10,10,11,11, 8,10, 9,11,
604.5632 +	10,10,11,11,11,11,10,11,10,11,11,10,10,10,11,11,
604.5633 +	10,10,11,11,11,11,11,11,11,11,11,11,12,11,12,11,
604.5634 +	12,11,12,12,10,10,10,11,11,10,11,11,11,11,10,11,
604.5635 +	10,11,11,11,12,11,12,12,11,12,11,12,11, 8, 9, 9,
604.5636 +	11,11, 9,10,10,11,12, 9,10,10,11,11,10,11,11,12,
604.5637 +	12,10,11,11,12,12, 9,10,10,11,11,10,10,11,11,12,
604.5638 +	10,11,11,12,12,11,11,12,12,12,11,12,12,12,12, 9,
604.5639 +	10,10,11,11,10,11,11,12,12,10,11,10,12,12,11,12,
604.5640 +	12,12,12,11,12,12,12,12,11,11,11,12,12,11,11,12,
604.5641 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.5642 +	12,11,11,11,12,12,11,12,12,12,12,11,12,12,12,12,
604.5643 +	12,12,12,12,12,12,12,12,12,12, 8, 9, 9,11,11, 9,
604.5644 +	10,10,11,11, 9,10,10,11,11,10,11,11,12,12,10,11,
604.5645 +	11,12,12, 9,10,10,11,11,10,10,11,12,12,10,11,11,
604.5646 +	12,12,11,12,12,12,12,11,12,12,12,12, 9,10,10,11,
604.5647 +	11,10,11,11,12,12,10,11,10,12,11,11,12,12,12,12,
604.5648 +	11,12,11,12,12,11,11,11,12,12,11,12,12,12,12,11,
604.5649 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,11,
604.5650 +	11,12,12,11,12,12,12,12,11,12,11,12,12,12,12,12,
604.5651 +	12,12,12,12,12,12,12,10,11,11,12,12,11,12,12,12,
604.5652 +	12,11,12,12,12,12,12,12,13,13,13,12,12,12,13,13,
604.5653 +	11,12,12,12,12,12,12,12,12,13,12,12,12,13,13,12,
604.5654 +	12,13,13,13,12,13,13,13,13,11,12,12,12,12,12,12,
604.5655 +	12,13,13,12,12,12,13,13,12,13,13,13,13,12,13,13,
604.5656 +	13,13,12,12,12,12,13,12,13,13,13,13,13,13,13,13,
604.5657 +	13,13,13,13,13,13,13,13,13,13,13,12,12,12,13,12,
604.5658 +	13,13,13,13,13,12,13,13,13,13,13,13,13,13,13,13,
604.5659 +	13,13,13,13,10,11,11,12,12,11,12,12,12,12,11,12,
604.5660 +	11,12,12,12,12,12,13,12,12,12,12,13,13,11,12,12,
604.5661 +	12,12,12,12,12,13,13,12,12,12,13,13,12,13,13,13,
604.5662 +	13,12,13,13,13,13,11,12,12,12,12,12,12,12,13,13,
604.5663 +	12,12,12,13,12,12,13,13,13,13,12,13,12,13,13,12,
604.5664 +	12,12,12,13,12,13,13,13,13,12,13,13,13,13,13,13,
604.5665 +	13,13,13,13,13,13,13,13,12,12,12,13,12,13,13,13,
604.5666 +	13,13,12,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.5667 +	13, 8, 9, 9,11,11, 9,10,10,11,11, 9,10,10,12,11,
604.5668 +	10,11,11,12,12,10,11,11,12,12, 9,10,10,11,11,10,
604.5669 +	10,11,11,12,10,11,11,12,12,11,11,12,12,12,11,12,
604.5670 +	12,12,12, 9,10,10,11,11,10,11,11,12,12,10,11,10,
604.5671 +	12,12,11,12,12,12,12,11,12,12,12,12,11,11,11,12,
604.5672 +	12,11,11,12,12,12,11,12,12,12,12,12,12,12,12,12,
604.5673 +	12,12,12,12,12,11,11,11,12,12,11,12,12,12,12,11,
604.5674 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12, 9,10,
604.5675 +	10,11,11,10,10,11,12,12,10,11,11,12,12,11,11,12,
604.5676 +	12,12,11,12,12,12,12,10,10,11,11,12,11,11,12,12,
604.5677 +	12,11,11,12,12,12,11,11,12,12,13,12,12,12,12,12,
604.5678 +	10,11,11,12,12,11,12,11,12,12,11,12,11,12,12,12,
604.5679 +	12,12,12,12,12,12,12,12,12,11,11,12,12,12,12,12,
604.5680 +	12,12,12,12,12,12,12,13,12,12,13,12,13,12,12,13,
604.5681 +	13,13,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.5682 +	12,12,12,12,13,12,12,12,12,13,12, 8,10,10,11,11,
604.5683 +	10,11,11,12,12,10,11,10,12,12,11,12,12,12,12,11,
604.5684 +	12,12,12,12,10,11,10,12,12,10,10,11,12,12,11,12,
604.5685 +	12,12,12,12,12,12,12,13,12,12,12,13,13,10,11,11,
604.5686 +	12,12,11,12,12,12,12,10,12,11,12,12,12,12,12,13,
604.5687 +	13,12,13,12,13,12,11,12,12,12,12,11,12,12,12,13,
604.5688 +	12,12,12,13,13,12,12,13,12,13,12,13,13,13,13,11,
604.5689 +	12,12,12,12,12,12,12,13,13,12,12,12,13,12,12,13,
604.5690 +	13,13,13,12,13,12,13,12,11,11,11,12,12,11,12,12,
604.5691 +	12,13,11,12,12,12,12,12,12,12,13,13,12,12,13,13,
604.5692 +	13,11,12,12,12,12,12,12,12,12,13,12,12,13,13,13,
604.5693 +	12,12,13,13,13,13,13,13,13,13,11,12,12,12,12,12,
604.5694 +	13,12,13,13,12,12,12,13,13,12,13,13,13,13,12,13,
604.5695 +	13,13,13,12,12,12,12,13,12,13,13,13,13,13,13,13,
604.5696 +	13,13,13,13,13,13,13,13,13,13,13,13,12,12,12,13,
604.5697 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.5698 +	13,13,13,13,13,10,11,11,12,12,11,12,12,12,13,11,
604.5699 +	12,12,13,12,12,13,13,13,13,12,13,13,13,13,11,12,
604.5700 +	12,12,12,12,12,12,13,13,12,13,12,13,13,13,13,13,
604.5701 +	13,13,13,13,13,13,13,11,12,12,13,12,12,13,12,13,
604.5702 +	13,12,13,12,13,13,13,13,13,13,13,13,13,13,13,13,
604.5703 +	12,13,13,13,13,12,13,13,13,13,13,13,13,13,13,13,
604.5704 +	13,13,13,13,13,13,13,13,13,12,13,13,13,13,13,13,
604.5705 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.5706 +	13,13, 8, 9, 9,11,11, 9,10,10,11,12, 9,10,10,11,
604.5707 +	11,10,11,11,12,12,10,11,11,12,12, 9,10,10,11,11,
604.5708 +	10,10,11,12,12,10,11,11,12,12,11,11,12,12,12,11,
604.5709 +	12,12,12,12, 9,10,10,11,11,10,11,11,12,12,10,11,
604.5710 +	10,12,12,11,12,12,12,12,11,12,11,12,12,11,11,11,
604.5711 +	12,12,11,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.5712 +	12,12,12,12,12,12,11,11,11,12,12,11,12,12,12,12,
604.5713 +	11,12,11,12,12,12,12,12,12,12,12,12,12,12,12, 8,
604.5714 +	10,10,11,11,10,10,11,12,12,10,11,11,12,12,11,12,
604.5715 +	12,12,12,11,12,12,12,12,10,11,11,12,12,10,11,12,
604.5716 +	12,12,11,12,12,12,12,12,12,12,12,13,12,12,12,13,
604.5717 +	13,10,10,11,12,12,11,12,12,12,12,10,11,10,12,12,
604.5718 +	12,12,12,13,13,12,12,12,13,12,11,12,12,12,12,11,
604.5719 +	12,12,12,13,12,12,12,13,13,12,12,13,12,13,12,13,
604.5720 +	13,13,13,11,12,12,12,12,12,12,12,13,13,11,12,12,
604.5721 +	13,12,12,13,13,13,13,12,13,12,13,12, 9,10,10,11,
604.5722 +	11,10,11,11,12,12,10,11,11,12,12,11,12,12,12,12,
604.5723 +	11,12,11,12,12,10,11,11,12,12,11,11,12,12,12,11,
604.5724 +	11,12,12,12,12,12,12,12,13,12,12,12,13,12,10,11,
604.5725 +	10,12,11,11,12,11,12,12,11,12,11,12,12,12,12,12,
604.5726 +	12,12,12,12,11,12,12,11,12,12,12,12,12,12,12,12,
604.5727 +	12,12,12,12,12,12,12,12,13,12,13,12,13,13,13,13,
604.5728 +	11,12,11,12,12,12,12,12,13,12,12,12,12,12,12,12,
604.5729 +	13,12,13,13,12,12,12,13,12,10,11,11,12,12,11,12,
604.5730 +	12,12,13,11,12,12,13,12,12,12,13,13,13,12,13,13,
604.5731 +	13,13,11,12,12,12,13,12,12,13,13,13,12,12,13,13,
604.5732 +	13,13,13,13,13,13,13,13,13,13,13,11,12,12,12,12,
604.5733 +	12,12,13,13,13,12,13,12,13,13,13,13,13,13,13,13,
604.5734 +	13,13,13,13,12,13,13,13,13,12,13,13,13,13,13,13,
604.5735 +	13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,13,
604.5736 +	13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,13,
604.5737 +	13,13,13,13,13,13,11,11,11,12,12,11,12,12,12,12,
604.5738 +	11,12,12,12,12,12,12,13,13,13,12,13,12,13,13,11,
604.5739 +	12,12,12,12,12,12,13,13,13,12,12,13,13,13,12,13,
604.5740 +	13,13,13,12,13,13,13,13,11,12,12,12,12,12,13,12,
604.5741 +	13,13,12,12,12,13,12,13,13,13,13,13,12,13,12,13,
604.5742 +	13,12,12,12,13,13,12,13,13,13,13,13,13,13,13,13,
604.5743 +	13,13,13,13,13,13,13,13,13,13,12,12,12,13,12,13,
604.5744 +	13,13,13,13,12,13,13,13,13,13,13,13,13,13,13,13,
604.5745 +	13,13,13,10,11,11,12,12,11,12,12,12,12,11,12,12,
604.5746 +	12,12,12,12,12,13,13,12,12,12,13,13,11,12,12,12,
604.5747 +	12,11,12,12,13,13,12,12,12,13,13,12,12,13,13,13,
604.5748 +	12,13,13,13,13,11,12,12,12,12,12,12,12,13,13,12,
604.5749 +	12,12,13,12,12,13,13,13,13,12,13,12,13,13,12,12,
604.5750 +	12,12,12,12,12,13,13,13,12,13,13,13,13,12,13,13,
604.5751 +	13,13,13,13,13,13,13,12,12,12,13,12,12,13,13,13,
604.5752 +	13,12,13,12,13,13,13,13,13,13,13,13,13,13,13,13,
604.5753 +	10,11,11,12,12,11,12,12,12,13,11,12,12,13,12,12,
604.5754 +	12,12,13,13,12,12,12,13,13,11,12,12,12,12,12,12,
604.5755 +	13,13,13,12,12,12,13,13,12,12,13,13,13,12,13,13,
604.5756 +	13,13,11,12,12,12,12,12,12,12,13,13,12,12,12,13,
604.5757 +	13,12,13,13,13,13,12,13,13,13,13,12,12,12,12,13,
604.5758 +	12,12,13,13,13,12,13,13,13,13,12,13,13,13,13,13,
604.5759 +	13,13,13,13,12,12,12,13,13,13,13,13,13,13,12,13,
604.5760 +	13,13,13,13,13,13,13,13,13,13,13,13,13,10,11,11,
604.5761 +	12,12,11,12,12,12,13,11,12,12,13,12,12,13,13,13,
604.5762 +	13,12,13,12,13,13,11,12,12,13,13,12,12,12,13,13,
604.5763 +	12,12,13,13,13,12,13,13,13,13,13,13,13,13,13,11,
604.5764 +	12,12,13,12,12,13,12,13,13,12,13,12,13,13,13,13,
604.5765 +	13,13,13,12,13,13,13,13,12,12,12,13,13,12,13,13,
604.5766 +	13,13,12,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.5767 +	13,12,12,12,13,13,12,13,13,13,13,12,13,13,13,13,
604.5768 +	13,13,13,13,13,13,13,13,13,13,11,11,11,12,12,11,
604.5769 +	12,12,12,12,11,12,12,12,12,12,12,12,13,13,12,12,
604.5770 +	12,13,13,11,12,12,12,12,12,12,12,12,13,12,12,12,
604.5771 +	13,13,12,12,13,13,13,12,13,13,13,13,11,12,12,12,
604.5772 +	12,12,12,12,13,13,12,12,12,13,12,12,13,13,13,13,
604.5773 +	12,13,12,13,13,12,12,12,12,12,12,12,13,12,13,12,
604.5774 +	13,13,13,13,12,13,13,12,13,13,13,13,13,13,12,12,
604.5775 +	12,12,12,12,13,13,13,13,12,13,12,13,13,13,13,13,
604.5776 +	13,13,12,13,13,13,12,10,11,11,12,12,11,12,12,12,
604.5777 +	12,11,12,12,12,12,12,12,12,13,13,12,13,12,13,13,
604.5778 +	11,12,12,12,12,12,12,12,13,13,12,12,12,13,13,12,
604.5779 +	12,13,13,13,13,13,13,13,13,11,12,12,12,12,12,13,
604.5780 +	12,13,13,12,13,12,13,13,12,13,13,13,13,12,13,12,
604.5781 +	13,13,12,12,12,12,12,12,13,13,13,13,12,13,13,13,
604.5782 +	13,13,13,13,13,13,13,13,13,13,13,12,12,12,13,12,
604.5783 +	12,13,13,13,13,12,13,12,13,13,13,13,13,13,13,13,
604.5784 +	13,13,13,13,10,11,11,12,12,11,12,12,12,12,11,12,
604.5785 +	12,12,12,12,12,12,13,13,12,12,12,13,13,11,12,12,
604.5786 +	12,12,12,12,12,13,13,12,12,12,13,13,12,12,13,13,
604.5787 +	13,12,12,13,13,13,11,12,11,12,12,12,12,12,13,13,
604.5788 +	11,12,12,13,13,12,13,13,13,13,12,13,12,13,13,12,
604.5789 +	12,12,12,12,12,13,13,13,13,12,13,13,13,13,13,13,
604.5790 +	13,13,13,13,13,13,13,13,12,12,12,13,12,12,13,13,
604.5791 +	13,13,12,13,12,13,13,13,13,13,13,13,12,13,13,13,
604.5792 +	13,10,11,11,12,12,11,12,12,12,13,11,12,12,13,12,
604.5793 +	12,12,13,13,13,12,13,13,13,13,11,12,12,13,13,12,
604.5794 +	12,13,13,13,12,12,13,13,13,12,13,13,13,13,13,13,
604.5795 +	13,13,13,11,12,12,13,12,12,13,12,13,13,12,12,12,
604.5796 +	13,13,12,13,13,13,13,13,13,13,13,13,12,12,13,13,
604.5797 +	13,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.5798 +	13,13,13,13,13,12,12,12,13,13,13,13,13,13,13,12,
604.5799 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,10,12,
604.5800 +	11,12,12,11,12,12,12,13,11,12,12,12,12,12,12,12,
604.5801 +	13,13,12,12,12,13,13,11,12,12,12,13,12,12,12,13,
604.5802 +	13,12,12,12,13,13,12,13,13,13,13,12,13,13,13,13,
604.5803 +	11,12,12,13,12,12,12,12,13,13,12,12,12,13,13,12,
604.5804 +	13,13,13,13,12,13,12,13,13,12,13,12,13,13,12,13,
604.5805 +	13,13,13,12,13,13,13,13,13,13,13,13,13,13,13,13,
604.5806 +	13,13,12,12,12,13,12,13,13,13,13,13,12,13,12,13,
604.5807 +	13,13,13,13,13,13,12,13,13,13,13,10,11,11,12,12,
604.5808 +	11,12,12,12,13,11,12,12,12,12,12,12,12,13,13,12,
604.5809 +	12,12,13,13,11,12,12,12,12,12,12,13,13,13,12,13,
604.5810 +	13,13,13,12,12,13,13,13,13,13,13,13,13,11,12,12,
604.5811 +	12,12,12,13,12,13,13,12,12,12,13,13,12,13,13,13,
604.5812 +	13,12,13,12,13,13,12,12,12,12,13,12,13,13,13,13,
604.5813 +	12,13,13,13,13,12,13,13,13,13,13,13,13,13,13,12,
604.5814 +	12,12,12,12,12,13,13,13,13,12,13,13,13,13,13,13,
604.5815 +	13,13,13,12,13,13,13,13,11,12,11,12,12,11,12,12,
604.5816 +	12,12,11,12,12,12,12,12,12,12,12,13,12,12,12,13,
604.5817 +	12,11,12,12,12,12,12,12,12,12,13,12,12,12,13,13,
604.5818 +	12,12,13,13,13,12,13,13,13,13,11,12,12,12,12,12,
604.5819 +	12,12,13,13,12,12,12,13,12,12,13,13,13,13,12,13,
604.5820 +	12,13,13,12,12,12,12,12,12,12,13,13,13,12,13,13,
604.5821 +	13,13,13,13,13,12,13,13,13,13,13,13,12,12,12,12,
604.5822 +	12,12,13,13,13,13,12,13,12,13,12,13,13,13,13,13,
604.5823 +	13,13,13,13,12,
604.5824 +};
604.5825 +
604.5826 +static const static_codebook _44p5_p4_1 = {
604.5827 +	5, 3125,
604.5828 +	(long *)_vq_lengthlist__44p5_p4_1,
604.5829 +	1, -533725184, 1611661312, 3, 0,
604.5830 +	(long *)_vq_quantlist__44p5_p4_1,
604.5831 +	0
604.5832 +};
604.5833 +
604.5834 +static const long _vq_quantlist__44p5_p5_0[] = {
604.5835 +	2,
604.5836 +	1,
604.5837 +	3,
604.5838 +	0,
604.5839 +	4,
604.5840 +};
604.5841 +
604.5842 +static const long _vq_lengthlist__44p5_p5_0[] = {
604.5843 +	 1, 6, 6,10,10, 6, 7, 9,11,13, 5, 9, 7,13,11, 8,
604.5844 +	11,12,13,15, 8,12,11,15,13, 6, 7, 8,11,11, 7, 8,
604.5845 +	10,11,13, 9,10,10,13,13,11,11,13,12,16,12,13,13,
604.5846 +	16,15, 6, 8, 7,11,11, 9,10,10,13,13, 7,10, 7,13,
604.5847 +	11,12,13,13,15,16,11,13,11,16,12,10,11,11,11,13,
604.5848 +	11,11,13,12,15,13,13,13,14,15,13,12,15,12,17,15,
604.5849 +	16,16,16,16,10,11,11,14,11,13,13,13,15,14,11,13,
604.5850 +	11,15,12,15,15,16,16,16,13,15,12,17,12, 6, 8, 9,
604.5851 +	12,12, 9,10,12,13,15, 9,11,11,15,14,12,13,15,16,
604.5852 +	18,13,14,14,17,16, 9,10,11,13,14,11,10,13,14,16,
604.5853 +	11,12,12,15,15,14,13,16,15,18,14,15,15,17,17, 9,
604.5854 +	11,11,14,14,11,12,13,15,16,11,13,11,15,14,15,15,
604.5855 +	15,17,18,14,15,14,17,15,13,14,14,15,16,14,14,15,
604.5856 +	15,17,15,16,15,17,17,16,16,17,15,19,17,18,18,19,
604.5857 +	18,13,14,14,16,15,15,15,16,17,17,14,15,14,18,15,
604.5858 +	17,17,17,19,19,16,17,15,19,16, 6, 9, 8,13,12, 9,
604.5859 +	11,11,14,15, 9,12,10,15,13,13,14,14,16,17,12,15,
604.5860 +	13,18,16, 9,11,11,14,14,11,11,13,14,15,11,13,12,
604.5861 +	16,15,14,14,15,15,18,14,15,15,18,17, 9,11,10,14,
604.5862 +	13,11,12,12,15,15,11,13,10,16,14,14,15,15,16,18,
604.5863 +	14,16,13,18,15,13,14,14,16,16,14,14,15,15,17,15,
604.5864 +	16,15,17,17,16,16,17,16,19,17,18,17,18,19,13,14,
604.5865 +	14,16,15,15,15,15,17,17,14,15,14,17,15,17,17,17,
604.5866 +	18,19,16,17,15,19,15,11,13,13,15,16,13,14,15,16,
604.5867 +	18,14,15,15,17,17,16,16,18,18,20,17,18,17,19,20,
604.5868 +	13,14,14,16,17,15,15,16,17,18,15,16,16,17,17,18,
604.5869 +	17,19,18,19,18,18,18,19,21,14,14,15,16,17,15,15,
604.5870 +	16,18,18,15,16,16,17,18,18,18,19,19,21,18,19,19,
604.5871 +	22,20,16,16,17,17,19,17,17,17,18,20,17,18,18,20,
604.5872 +	19,19,19,20,19, 0,19,19,20,20,21,17,17,17,19,18,
604.5873 +	18,18,20,19,19,18,18,18,20,20,19,19,20,20,20,20,
604.5874 +	21,20,21,19,11,13,13,16,15,14,15,15,17,17,14,15,
604.5875 +	14,18,16,16,18,18,20,19,16,19,17,21,18,13,14,15,
604.5876 +	16,17,15,15,16,18,18,15,16,15,19,18,18,18,18,19,
604.5877 +	19,18,18,18,22,20,13,14,14,16,16,15,16,16,18,17,
604.5878 +	15,16,15,18,17,18,18,18,19,19,17,18,17,21,18,16,
604.5879 +	17,17,18,18,17,18,19,19,19,18,20,18,19,19,19,20,
604.5880 +	21,19,21,20,20,20, 0,21,16,17,17,19,19,18,18,18,
604.5881 +	19,21,17,18,18,19,18,20,19,21,20,21,19,20,20,22,
604.5882 +	19, 7, 9, 9,13,13, 8,10,11,14,15, 9,12,11,15,14,
604.5883 +	11,13,14,16,17,13,15,14,17,16, 8,10,11,14,14,10,
604.5884 +	10,12,14,16,11,12,12,16,15,13,12,15,15,18,14,15,
604.5885 +	15,19,17, 9,11,11,14,14,11,12,12,15,15,11,13,11,
604.5886 +	16,14,14,15,14,17,17,14,16,14,18,15,12,13,14,15,
604.5887 +	16,13,13,15,14,17,15,15,15,17,17,15,14,17,14,19,
604.5888 +	17,18,18,19,18,13,14,14,16,16,15,15,15,17,17,14,
604.5889 +	15,14,18,15,17,18,17,18,17,16,18,16,19,15, 7,10,
604.5890 +	10,13,13, 9,10,12,14,15,10,12,11,15,14,12,13,14,
604.5891 +	16,17,13,15,14,18,16,10,10,12,13,14,10,10,13,13,
604.5892 +	16,12,12,13,15,15,13,12,15,15,18,15,15,16,18,17,
604.5893 +	10,11,11,14,14,12,13,13,15,16,10,13,10,16,14,14,
604.5894 +	15,15,17,17,14,15,13,17,15,13,13,14,15,16,14,13,
604.5895 +	15,14,18,15,15,16,16,17,16,15,18,15,18,17,18,18,
604.5896 +	18,18,13,15,14,17,16,15,16,16,17,17,14,15,13,17,
604.5897 +	15,17,17,18,18,18,16,17,14,20,14, 8,10,10,14,14,
604.5898 +	11,11,13,14,16,11,13,11,16,14,14,15,16,16,18,14,
604.5899 +	16,15,18,16,10,12,11,15,14,11,11,13,14,16,13,14,
604.5900 +	13,16,15,15,14,16,15,19,16,17,16,20,18,10,11,12,
604.5901 +	14,15,13,13,14,16,16,11,14,11,16,14,16,16,17,18,
604.5902 +	19,15,17,14,20,15,14,15,14,17,16,13,14,15,15,18,
604.5903 +	16,17,16,19,18,16,15,18,15,19,18,19,18,21,21,14,
604.5904 +	14,15,16,17,16,16,17,18,18,13,15,14,17,15,18,18,
604.5905 +	19,18,22,16,18,15,21,15,12,13,14,16,16,14,14,16,
604.5906 +	16,18,14,15,15,17,18,16,16,18,18,20,18,18,17,20,
604.5907 +	20,13,14,15,15,17,15,14,16,16,18,16,16,16,17,19,
604.5908 +	17,15,18,17,21,18,18,18,19,19,14,15,15,18,17,15,
604.5909 +	16,16,18,19,15,16,15,18,18,17,18,18,20,21,17,19,
604.5910 +	17,20,19,16,16,17,16,19,17,17,18,17,20,18,18,18,
604.5911 +	18,19,19,18,20,17,22,20,20,19,20,20,17,17,18,18,
604.5912 +	19,18,18,20,21,20,17,18,17,20,20,21,21,21,21,21,
604.5913 +	19,21,18,22,20,11,13,13,17,16,14,14,16,16,18,14,
604.5914 +	16,14,18,16,17,18,19,19,20,18,19,18,21,19,14,15,
604.5915 +	14,17,16,14,14,16,18,18,16,17,16,18,17,18,17,19,
604.5916 +	18,20,19,19,18,20,20,13,14,15,16,17,16,16,17,18,
604.5917 +	19,14,16,14,19,17,18,19,18,20,20,18,20,17,21,18,
604.5918 +	17,17,17,19,18,16,17,18,18,19,18,19,18,21,21,18,
604.5919 +	18,20,17,21,19,20,20,22,21,16,17,18,18,19,18,18,
604.5920 +	19,21,20,16,17,17,20,18,21,21,22,21,22,18,21,18,
604.5921 +	 0,18, 7, 9, 9,13,13, 9,11,12,14,15, 8,11,10,15,
604.5922 +	14,13,14,15,16,18,11,14,13,17,15, 9,11,11,14,14,
604.5923 +	11,11,13,14,16,11,12,12,15,15,14,14,16,15,18,14,
604.5924 +	14,15,17,17, 8,11,10,14,14,11,12,12,15,15,10,12,
604.5925 +	10,16,14,14,15,15,17,18,13,15,12,18,15,13,14,14,
604.5926 +	16,16,14,14,15,15,17,15,15,15,16,17,16,15,17,15,
604.5927 +	19,17,17,17,18,18,12,14,13,16,15,15,15,15,17,17,
604.5928 +	13,15,13,17,14,17,18,18,18,19,15,17,14,19,14, 8,
604.5929 +	10,10,14,14,11,11,13,14,16,11,13,11,16,14,14,15,
604.5930 +	16,17,19,14,16,15,18,17,10,12,11,15,14,11,11,14,
604.5931 +	14,17,13,14,13,17,15,15,14,17,15,19,16,17,16,19,
604.5932 +	17,10,11,12,14,15,13,13,14,15,17,11,13,11,17,14,
604.5933 +	16,16,17,18,19,15,16,14,18,15,14,15,14,16,16,13,
604.5934 +	14,15,15,18,16,16,16,18,18,16,15,18,15,20,18,19,
604.5935 +	18,21,18,14,14,15,16,17,16,16,17,17,18,13,15,14,
604.5936 +	17,16,19,19,19,19,19,15,18,15,20,15, 7,10,10,13,
604.5937 +	13,10,11,12,14,15, 9,12,10,15,14,13,14,15,16,17,
604.5938 +	12,15,13,17,16,10,11,11,14,14,10,10,13,14,16,12,
604.5939 +	13,13,16,15,14,13,16,15,18,15,15,16,17,17,10,12,
604.5940 +	10,14,13,12,13,12,15,15,10,13,10,16,13,15,16,15,
604.5941 +	17,18,13,16,12,18,15,13,14,14,16,17,14,13,15,15,
604.5942 +	18,15,16,15,17,17,16,14,17,15,19,17,18,18,19,19,
604.5943 +	13,15,13,17,14,15,15,15,18,17,14,15,13,17,14,18,
604.5944 +	17,18,18,19,15,17,15,19,15,11,13,13,16,17,14,14,
604.5945 +	16,16,18,14,16,15,18,17,17,18,19,18,21,18,18,17,
604.5946 +	20,18,13,15,14,17,16,14,14,16,17,18,16,17,16,19,
604.5947 +	17,18,17,19,18,22,18,19,19,21,21,13,14,15,16,18,
604.5948 +	16,16,17,17,20,14,16,14,18,17,18,18,19,19,21,17,
604.5949 +	18,17,21,18,17,18,17,19,18,16,17,17,18,19,18,18,
604.5950 +	18,22,22,18,17,19,17, 0,20,21,19,21,20,17,17,18,
604.5951 +	18,21,18,18,18,19,21,17,17,17,19,19,20,20,22,21,
604.5952 +	21,19,20,18,20,17,12,14,13,17,16,14,15,15,17,18,
604.5953 +	14,16,14,18,16,17,18,18,21,20,16,18,16,21,18,14,
604.5954 +	15,15,17,17,15,15,16,18,18,15,17,16,18,18,17,17,
604.5955 +	19,19,20,18,19,18,20,19,14,15,14,17,15,15,16,16,
604.5956 +	18,17,15,16,14,19,15,18,18,18,19,20,17,20,15,21,
604.5957 +	17,16,17,18,18,19,17,17,18,18,20,18,19,18,19,21,
604.5958 +	19,18,19,19,21,20, 0,19,21,20,16,17,16,19,16,18,
604.5959 +	18,18,19,19,17,18,17,20,17,19,20,20,22, 0,19,20,
604.5960 +	17,21,17,11,13,14,16,17,14,15,15,17,18,14,15,15,
604.5961 +	18,18,16,17,17,19,20,16,18,17,19,21,13,14,15,17,
604.5962 +	17,14,15,16,17,19,15,16,16,18,19,16,17,18,19,21,
604.5963 +	17,18,20,21,21,13,15,15,17,17,15,16,16,18,19,15,
604.5964 +	16,16,18,19,17,17,18,19,22,17,19,18,22,19,15,16,
604.5965 +	17,19,19,16,17,18,18,20,17,18,18,19,20,19,18,20,
604.5966 +	18,22,20,19,19,22,21,16,17,17,18,19,18,18,18,19,
604.5967 +	20,17,18,18,20,19,20,19,20,22,20,19,20,21,21,20,
604.5968 +	12,14,14,16,16,13,14,16,17,18,14,16,15,18,18,15,
604.5969 +	17,17,19,19,17,18,18,19,19,13,14,15,16,17,14,14,
604.5970 +	16,16,20,15,16,16,17,19,16,15,18,17,20,18,17,19,
604.5971 +	19,19,14,15,15,17,17,16,16,16,18,18,15,16,15,19,
604.5972 +	18,17,18,18,20,21,17,18,17,21,18,16,15,17,17,19,
604.5973 +	17,15,18,17,20,19,17,18,19,20,18,16,19,17,22,20,
604.5974 +	19,20,19,20,17,17,18,19,19,18,18,19,20,20,17,18,
604.5975 +	17,18,18,21,21,20,20,21,18,20,17,21,19,11,14,14,
604.5976 +	16,17,15,14,16,17,19,14,16,14,18,17,18,18,19,19,
604.5977 +	21,17,19,18,20,20,13,15,14,17,17,14,14,16,17,18,
604.5978 +	16,17,16,19,18,18,17,19,18,20,18,21,18,20,20,13,
604.5979 +	15,15,16,17,16,16,17,18,19,14,16,15,19,18,19,19,
604.5980 +	19,21,20,18,19,17,20,18,16,17,16,19,18,16,17,17,
604.5981 +	19,20,17,19,18,20,19,18,17,21,18, 0,21,20,20, 0,
604.5982 +	20,17,17,18,18,19,18,19,19,20,22,16,17,17,20,18,
604.5983 +	21,22,20,20,22,18,22,18,22,18,12,14,14,17,17,14,
604.5984 +	15,16,17,19,14,16,15,17,17,17,17,18,18,21,17,19,
604.5985 +	17,20,19,14,15,15,16,18,15,14,16,16,19,16,17,16,
604.5986 +	19,18,17,16,20,17,20,18,20,19,19,20,14,15,15,18,
604.5987 +	17,16,16,17,18,19,14,16,15,19,17,18,21,18,19,21,
604.5988 +	17,18,17,19,18,17,17,18,17,20,17,16,18,17,21,18,
604.5989 +	19,19,19,19,18,17,19,17,20,20,21,20,21,20,17,17,
604.5990 +	17,19,19,19,18,18,20,21,16,18,16,19,18,20,20,21,
604.5991 +	21,20,18,19,16, 0,17,12,14,14,17,17,15,15,18,17,
604.5992 +	19,15,18,15,20,16,20,19,21,18,22,20,20,20,22,19,
604.5993 +	14,16,14,20,17,14,15,17,17,20,18,18,17,20,18,18,
604.5994 +	17,19,17,21,20,21,20, 0,21,14,15,16,17,19,18,17,
604.5995 +	19,18,21,14,18,15,21,17,21,20,21,20, 0,18,21,17,
604.5996 +	21,17,18,19,17,20,18,16,17,17,19,19,19,21,20, 0,
604.5997 +	20,18,17,21,17, 0,22, 0,21, 0,22,17,17,19,18,20,
604.5998 +	20,20,21,19,22,16,17,18,20,18,22,22, 0,22, 0,17,
604.5999 +	21,17,22,17,11,14,13,16,16,14,15,15,17,18,14,15,
604.6000 +	14,18,17,17,18,18,19,20,16,17,17,21,19,13,14,15,
604.6001 +	17,17,15,16,16,18,18,15,16,16,19,18,18,18,18,19,
604.6002 +	20,17,18,18,20,19,13,15,14,17,17,15,16,16,17,18,
604.6003 +	14,16,15,19,17,17,18,19,21,21,17,18,17,20,18,16,
604.6004 +	17,17,19,19,17,18,19,19,20,18,19,18,21,21,21,20,
604.6005 +	19,21,22,20,20,19,21,20,15,17,16,19,19,17,18,18,
604.6006 +	20,21,16,18,17,20,18,19,19,21,21,21,19,19,19,20,
604.6007 +	18,11,14,13,17,16,14,14,16,16,19,14,16,15,19,16,
604.6008 +	18,18,18,19,22,17,18,17,20,19,13,15,14,17,17,15,
604.6009 +	15,16,17,19,16,17,16,20,18,18,17,19,18,21,19,19,
604.6010 +	18,22, 0,13,14,15,17,18,16,16,17,17,19,14,16,15,
604.6011 +	19,18,18,19,19,20,21,18,18,17,20,18,17,18,17,20,
604.6012 +	18,16,17,17,18,20,18,19,18,20,20,18,18,21,17,21,
604.6013 +	20,21,21, 0,19,16,16,18,18,19,19,18,20,19,20,16,
604.6014 +	17,17,20,18,21,20,21,22,22,18,20,17,21,17,12,14,
604.6015 +	14,17,16,14,15,16,18,18,13,15,14,18,17,17,18,18,
604.6016 +	19,19,15,17,16,19,19,14,15,15,17,17,15,15,16,18,
604.6017 +	19,15,16,16,19,18,17,17,18,18,20,18,18,18,21,20,
604.6018 +	13,15,14,17,16,15,16,15,18,18,14,16,14,18,17,18,
604.6019 +	18,18,19,21,16,18,16,20,17,17,18,17,18,19,17,17,
604.6020 +	18,18,19,18,19,19,21,19,19,18,20,18,21,21,20,20,
604.6021 +	21,20,16,17,15,20,17,17,19,17,19,19,17,18,15,20,
604.6022 +	17,19,20,19,21,22,17,20,16, 0,17,12,14,14,17,18,
604.6023 +	16,15,18,16,20,16,18,15,21,17,20,18,21,19,22,19,
604.6024 +	21,19, 0,19,14,16,15,19,17,14,15,17,16,21,18,19,
604.6025 +	18,21,17,19,17,21,17,22,20,21,21, 0,21,14,15,16,
604.6026 +	17,19,18,17,19,18,21,14,17,15,20,17,21,22,21,20,
604.6027 +	22,18,21,17,21,17,17,19,17,21,18,16,17,17,19,20,
604.6028 +	19,21,20,21,20,17,18,20,17,21, 0,22,20,21,22,17,
604.6029 +	17,20,18,21,21,20,22,20,21,16,17,17,21,19, 0,22,
604.6030 +	 0,21,21,18,22,17,21,17,12,14,14,17,16,14,15,16,
604.6031 +	17,18,14,16,15,18,17,17,17,20,19,20,16,18,17,21,
604.6032 +	18,14,15,15,17,17,14,15,16,17,19,16,17,16,18,18,
604.6033 +	17,16,19,18,19,18,19,18,21,20,14,15,15,18,17,16,
604.6034 +	16,16,19,18,15,16,14,20,16,18,18,19,19,20,16,19,
604.6035 +	16,21,17,17,17,18,19,19,16,16,18,18,19,19,19,18,
604.6036 +	20,20,18,16,19,18,20,22,21,20,19,20,16,18,17,20,
604.6037 +	16,18,19,18,19,18,16,18,16,20,17,21,20,21,20,20,
604.6038 +	18,19,17,21,16,
604.6039 +};
604.6040 +
604.6041 +static const static_codebook _44p5_p5_0 = {
604.6042 +	5, 3125,
604.6043 +	(long *)_vq_lengthlist__44p5_p5_0,
604.6044 +	1, -528744448, 1616642048, 3, 0,
604.6045 +	(long *)_vq_quantlist__44p5_p5_0,
604.6046 +	0
604.6047 +};
604.6048 +
604.6049 +static const long _vq_quantlist__44p5_p5_1[] = {
604.6050 +	3,
604.6051 +	2,
604.6052 +	4,
604.6053 +	1,
604.6054 +	5,
604.6055 +	0,
604.6056 +	6,
604.6057 +};
604.6058 +
604.6059 +static const long _vq_lengthlist__44p5_p5_1[] = {
604.6060 +	 2, 3, 3, 3, 3, 3, 3,
604.6061 +};
604.6062 +
604.6063 +static const static_codebook _44p5_p5_1 = {
604.6064 +	1, 7,
604.6065 +	(long *)_vq_lengthlist__44p5_p5_1,
604.6066 +	1, -533200896, 1611661312, 3, 0,
604.6067 +	(long *)_vq_quantlist__44p5_p5_1,
604.6068 +	0
604.6069 +};
604.6070 +
604.6071 +static const long _vq_quantlist__44p5_p6_0[] = {
604.6072 +	1,
604.6073 +	0,
604.6074 +	2,
604.6075 +};
604.6076 +
604.6077 +static const long _vq_lengthlist__44p5_p6_0[] = {
604.6078 +	 1, 5, 5, 5, 7, 9, 5, 9, 7, 5, 7, 8, 7, 7,10, 9,
604.6079 +	 9,10, 5, 8, 7, 9,10, 9, 7,10, 7, 6, 9, 9, 9,10,
604.6080 +	12,10,12,11, 9,10,11,11,10,13,12,12,13,10,11,11,
604.6081 +	12,13,13,11,13,11, 6, 9, 9,10,11,12, 9,12,11,10,
604.6082 +	11,11,11,11,13,12,13,13, 9,11,10,12,13,13,11,13,
604.6083 +	10, 6, 9,10, 9,11,12,10,12,11, 9,10,11,10,10,13,
604.6084 +	11,13,13,10,11,11,12,13,12,11,13,11, 7, 9,10, 9,
604.6085 +	10,12,10,11,11,10,10,11,10,10,12,12,11,12,10,11,
604.6086 +	10,12,12,12,10,12,10, 7,10,10,11,11,13,11,13,11,
604.6087 +	10,12,11,11,10,13,13,14,13,10,11,12,13,13,14,11,
604.6088 +	13,10, 6,10, 9,10,11,12, 9,12,11, 9,11,11,11,11,
604.6089 +	13,12,12,13, 9,11,10,12,13,13,10,13,10, 7,10,10,
604.6090 +	11,11,14,11,13,11,10,12,11,11,10,14,13,14,13,10,
604.6091 +	11,12,13,13,14,11,13,10, 7,10, 9,10,10,12, 9,12,
604.6092 +	10,10,11,11,10,10,12,12,12,12, 9,11,10,11,12,12,
604.6093 +	10,12, 9,
604.6094 +};
604.6095 +
604.6096 +static const static_codebook _44p5_p6_0 = {
604.6097 +	5, 243,
604.6098 +	(long *)_vq_lengthlist__44p5_p6_0,
604.6099 +	1, -527106048, 1620377600, 2, 0,
604.6100 +	(long *)_vq_quantlist__44p5_p6_0,
604.6101 +	0
604.6102 +};
604.6103 +
604.6104 +static const long _vq_quantlist__44p5_p6_1[] = {
604.6105 +	1,
604.6106 +	0,
604.6107 +	2,
604.6108 +};
604.6109 +
604.6110 +static const long _vq_lengthlist__44p5_p6_1[] = {
604.6111 +	 2, 6, 6, 5, 7, 8, 5, 8, 7, 6, 7, 7, 7, 7, 8, 8,
604.6112 +	 8, 8, 6, 7, 7, 7, 8, 8, 7, 8, 7, 6, 8, 8, 8, 9,
604.6113 +	10, 8, 9, 9, 8, 9, 9, 9, 9,10,10,10,10, 8, 9, 9,
604.6114 +	10,10,10, 9,10,10, 6, 8, 8, 8, 9, 9, 8,10, 9, 9,
604.6115 +	 9, 9, 9, 9,10,10,10,10, 8, 9, 9,10,10,10, 9,10,
604.6116 +	 9, 6, 8, 9, 8, 9, 9, 8, 9, 9, 8, 9, 9, 9, 9,10,
604.6117 +	 9,10,10, 8, 9, 9, 9,10,10, 9,10, 9, 7, 8, 9, 8,
604.6118 +	 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9,
604.6119 +	 9, 9, 9, 9, 9, 9, 9, 7, 9, 9, 9,10,10, 9,10,10,
604.6120 +	 9,10, 9, 9, 9,10,10,10,10, 9,10, 9,10,10,10, 9,
604.6121 +	10, 9, 6, 8, 8, 8, 9, 9, 8, 9, 9, 8, 9, 9, 9, 9,
604.6122 +	10, 9,10,10, 8, 9, 9, 9,10,10, 9,10, 9, 7, 9, 9,
604.6123 +	 9,10,10, 9,10, 9, 9, 9,10,10, 9,10,10,10,10, 9,
604.6124 +	 9, 9,10,10,10, 9,10, 9, 7, 9, 8, 8, 9, 9, 8, 9,
604.6125 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9,
604.6126 +	 9, 9, 9,
604.6127 +};
604.6128 +
604.6129 +static const static_codebook _44p5_p6_1 = {
604.6130 +	5, 243,
604.6131 +	(long *)_vq_lengthlist__44p5_p6_1,
604.6132 +	1, -530841600, 1616642048, 2, 0,
604.6133 +	(long *)_vq_quantlist__44p5_p6_1,
604.6134 +	0
604.6135 +};
604.6136 +
604.6137 +static const long _vq_quantlist__44p5_p7_0[] = {
604.6138 +	1,
604.6139 +	0,
604.6140 +	2,
604.6141 +};
604.6142 +
604.6143 +static const long _vq_lengthlist__44p5_p7_0[] = {
604.6144 +	 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.6145 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6146 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6147 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6148 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6149 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6150 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6151 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6152 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6153 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6154 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6155 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6156 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6157 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6158 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6159 +	 9, 9, 9,
604.6160 +};
604.6161 +
604.6162 +static const static_codebook _44p5_p7_0 = {
604.6163 +	5, 243,
604.6164 +	(long *)_vq_lengthlist__44p5_p7_0,
604.6165 +	1, -513979392, 1633504256, 2, 0,
604.6166 +	(long *)_vq_quantlist__44p5_p7_0,
604.6167 +	0
604.6168 +};
604.6169 +
604.6170 +static const long _vq_quantlist__44p5_p7_1[] = {
604.6171 +	1,
604.6172 +	0,
604.6173 +	2,
604.6174 +};
604.6175 +
604.6176 +static const long _vq_lengthlist__44p5_p7_1[] = {
604.6177 +	 1, 7, 7, 6, 9, 9, 7, 9, 9, 6, 9, 9, 9, 9, 9, 9,
604.6178 +	 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6179 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6180 +	 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6181 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6182 +	 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6183 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6184 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6185 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6186 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6187 +	 9, 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6188 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6189 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.6190 +	 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.6191 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.6192 +	10,10,10,
604.6193 +};
604.6194 +
604.6195 +static const static_codebook _44p5_p7_1 = {
604.6196 +	5, 243,
604.6197 +	(long *)_vq_lengthlist__44p5_p7_1,
604.6198 +	1, -516716544, 1630767104, 2, 0,
604.6199 +	(long *)_vq_quantlist__44p5_p7_1,
604.6200 +	0
604.6201 +};
604.6202 +
604.6203 +static const long _vq_quantlist__44p5_p7_2[] = {
604.6204 +	12,
604.6205 +	11,
604.6206 +	13,
604.6207 +	10,
604.6208 +	14,
604.6209 +	9,
604.6210 +	15,
604.6211 +	8,
604.6212 +	16,
604.6213 +	7,
604.6214 +	17,
604.6215 +	6,
604.6216 +	18,
604.6217 +	5,
604.6218 +	19,
604.6219 +	4,
604.6220 +	20,
604.6221 +	3,
604.6222 +	21,
604.6223 +	2,
604.6224 +	22,
604.6225 +	1,
604.6226 +	23,
604.6227 +	0,
604.6228 +	24,
604.6229 +};
604.6230 +
604.6231 +static const long _vq_lengthlist__44p5_p7_2[] = {
604.6232 +	 1, 2, 3, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,
604.6233 +	11,12,12,13,13,14,14,14,14,
604.6234 +};
604.6235 +
604.6236 +static const static_codebook _44p5_p7_2 = {
604.6237 +	1, 25,
604.6238 +	(long *)_vq_lengthlist__44p5_p7_2,
604.6239 +	1, -518864896, 1620639744, 5, 0,
604.6240 +	(long *)_vq_quantlist__44p5_p7_2,
604.6241 +	0
604.6242 +};
604.6243 +
604.6244 +static const long _vq_quantlist__44p5_p7_3[] = {
604.6245 +	12,
604.6246 +	11,
604.6247 +	13,
604.6248 +	10,
604.6249 +	14,
604.6250 +	9,
604.6251 +	15,
604.6252 +	8,
604.6253 +	16,
604.6254 +	7,
604.6255 +	17,
604.6256 +	6,
604.6257 +	18,
604.6258 +	5,
604.6259 +	19,
604.6260 +	4,
604.6261 +	20,
604.6262 +	3,
604.6263 +	21,
604.6264 +	2,
604.6265 +	22,
604.6266 +	1,
604.6267 +	23,
604.6268 +	0,
604.6269 +	24,
604.6270 +};
604.6271 +
604.6272 +static const long _vq_lengthlist__44p5_p7_3[] = {
604.6273 +	 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.6274 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.6275 +};
604.6276 +
604.6277 +static const static_codebook _44p5_p7_3 = {
604.6278 +	1, 25,
604.6279 +	(long *)_vq_lengthlist__44p5_p7_3,
604.6280 +	1, -529006592, 1611661312, 5, 0,
604.6281 +	(long *)_vq_quantlist__44p5_p7_3,
604.6282 +	0
604.6283 +};
604.6284 +
604.6285 +static const long _huff_lengthlist__44p5_short[] = {
604.6286 +	 4, 7,12,14,15,18,20,20, 5, 3, 4, 6, 9,11,15,19,
604.6287 +	 9, 4, 3, 4, 7, 9,13,18,11, 6, 3, 3, 5, 8,13,19,
604.6288 +	14, 9, 6, 5, 7,10,16,20,16,11, 9, 8,10,10,14,16,
604.6289 +	21,14,13,11, 8, 7,11,14,21,14,13, 9, 6, 5,10,12,
604.6290 +};
604.6291 +
604.6292 +static const static_codebook _huff_book__44p5_short = {
604.6293 +	2, 64,
604.6294 +	(long *)_huff_lengthlist__44p5_short,
604.6295 +	0, 0, 0, 0, 0,
604.6296 +	NULL,
604.6297 +	0
604.6298 +};
604.6299 +
604.6300 +static const long _vq_quantlist__44p6_l0_0[] = {
604.6301 +	6,
604.6302 +	5,
604.6303 +	7,
604.6304 +	4,
604.6305 +	8,
604.6306 +	3,
604.6307 +	9,
604.6308 +	2,
604.6309 +	10,
604.6310 +	1,
604.6311 +	11,
604.6312 +	0,
604.6313 +	12,
604.6314 +};
604.6315 +
604.6316 +static const long _vq_lengthlist__44p6_l0_0[] = {
604.6317 +	 1, 4, 4, 7, 7,10,10,12,12,12,12,13,12, 5, 5, 5,
604.6318 +	 8, 6,11, 9,12,12,13,12,12,12, 4, 5, 5, 6, 8, 9,
604.6319 +	11,12,12,13,12,12,12, 7, 7, 8, 9, 9,11, 8,12, 9,
604.6320 +	12,12,12,12, 7, 8, 8, 9, 9, 8,11, 9,12,12,12,11,
604.6321 +	12,10,10,10,11,11,11,11,11,10,11,11,12,11,10,10,
604.6322 +	10,11,11,11,11,10,11,11,11,11,12,11,11,11,12,11,
604.6323 +	12,11,12,11,13,11,13,11,11,11,11,11,12,11,12,10,
604.6324 +	13,11,12,11,13,12,12,12,13,12,13,13,13,12,14,12,
604.6325 +	14,13,12,12,12,12,13,13,13,12,14,12,14,13,14,13,
604.6326 +	14,14,14,14,14,14,14,14,15,14,15,14,13,14,13,14,
604.6327 +	14,14,14,14,15,14,14,14,15,
604.6328 +};
604.6329 +
604.6330 +static const static_codebook _44p6_l0_0 = {
604.6331 +	2, 169,
604.6332 +	(long *)_vq_lengthlist__44p6_l0_0,
604.6333 +	1, -526516224, 1616117760, 4, 0,
604.6334 +	(long *)_vq_quantlist__44p6_l0_0,
604.6335 +	0
604.6336 +};
604.6337 +
604.6338 +static const long _vq_quantlist__44p6_l0_1[] = {
604.6339 +	2,
604.6340 +	1,
604.6341 +	3,
604.6342 +	0,
604.6343 +	4,
604.6344 +};
604.6345 +
604.6346 +static const long _vq_lengthlist__44p6_l0_1[] = {
604.6347 +	 4, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5,
604.6348 +	 5, 5, 4, 5, 5, 5, 5, 5, 4,
604.6349 +};
604.6350 +
604.6351 +static const static_codebook _44p6_l0_1 = {
604.6352 +	2, 25,
604.6353 +	(long *)_vq_lengthlist__44p6_l0_1,
604.6354 +	1, -533725184, 1611661312, 3, 0,
604.6355 +	(long *)_vq_quantlist__44p6_l0_1,
604.6356 +	0
604.6357 +};
604.6358 +
604.6359 +static const long _vq_quantlist__44p6_l1_0[] = {
604.6360 +	1,
604.6361 +	0,
604.6362 +	2,
604.6363 +};
604.6364 +
604.6365 +static const long _vq_lengthlist__44p6_l1_0[] = {
604.6366 +	 1, 3, 2, 5, 5, 6, 6, 6, 6,
604.6367 +};
604.6368 +
604.6369 +static const static_codebook _44p6_l1_0 = {
604.6370 +	2, 9,
604.6371 +	(long *)_vq_lengthlist__44p6_l1_0,
604.6372 +	1, -516716544, 1630767104, 2, 0,
604.6373 +	(long *)_vq_quantlist__44p6_l1_0,
604.6374 +	0
604.6375 +};
604.6376 +
604.6377 +static const long _huff_lengthlist__44p6_lfe[] = {
604.6378 +	 2, 3, 1, 3,
604.6379 +};
604.6380 +
604.6381 +static const static_codebook _huff_book__44p6_lfe = {
604.6382 +	2, 4,
604.6383 +	(long *)_huff_lengthlist__44p6_lfe,
604.6384 +	0, 0, 0, 0, 0,
604.6385 +	NULL,
604.6386 +	0
604.6387 +};
604.6388 +
604.6389 +static const long _huff_lengthlist__44p6_long[] = {
604.6390 +	 2, 7,13,15,16,17,19,20, 6, 3, 4, 7, 9,10,12,15,
604.6391 +	13, 4, 3, 4, 7, 8,11,13,14, 7, 4, 4, 6, 7,10,11,
604.6392 +	16, 9, 7, 6, 7, 8, 9,10,16, 9, 8, 7, 7, 6, 8, 8,
604.6393 +	18,12,10,10, 9, 8, 8, 9,20,14,13,12,11, 8, 9, 9,
604.6394 +};
604.6395 +
604.6396 +static const static_codebook _huff_book__44p6_long = {
604.6397 +	2, 64,
604.6398 +	(long *)_huff_lengthlist__44p6_long,
604.6399 +	0, 0, 0, 0, 0,
604.6400 +	NULL,
604.6401 +	0
604.6402 +};
604.6403 +
604.6404 +static const long _vq_quantlist__44p6_p1_0[] = {
604.6405 +	1,
604.6406 +	0,
604.6407 +	2,
604.6408 +};
604.6409 +
604.6410 +static const long _vq_lengthlist__44p6_p1_0[] = {
604.6411 +	 2, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 8, 9, 7,
604.6412 +	 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 8, 5, 7, 8, 8, 9,
604.6413 +	10, 8, 9, 9, 8, 9,10, 9,10,12,10,11,11, 8, 9,10,
604.6414 +	10,11,11, 9,11,11, 5, 8, 7, 8, 9, 9, 8,10, 9, 8,
604.6415 +	10, 9, 9,11,11,10,11,11, 8,10, 9,10,11,11, 9,12,
604.6416 +	10, 5, 8, 8, 7, 9,10, 8,10, 9, 7, 9, 9, 9,10,11,
604.6417 +	 9,11,11, 8,10,10,10,11,11,10,12,11, 7, 9, 9, 9,
604.6418 +	10,11, 9,11,11, 9, 9,11,10,10,13,11,11,12, 9,11,
604.6419 +	11,11,12,13,11,13,12, 7, 9, 9, 9,11,11, 9,12,10,
604.6420 +	 9,11,10,10,11,12,11,13,12, 9,11,11,11,13,13,11,
604.6421 +	13,11, 5, 8, 8, 8, 9,10, 7,10, 9, 8,10,10,10,11,
604.6422 +	11,10,11,11, 7, 9, 9, 9,11,11, 9,11,10, 7, 9, 9,
604.6423 +	 9,10,12, 9,11,11, 9,11,11,11,11,13,11,13,13, 9,
604.6424 +	10,11,11,12,13,10,12,11, 7, 9, 9, 9,11,11, 9,11,
604.6425 +	10, 9,11,11,11,12,13,11,13,12, 9,11, 9,11,12,11,
604.6426 +	10,13,10,
604.6427 +};
604.6428 +
604.6429 +static const static_codebook _44p6_p1_0 = {
604.6430 +	5, 243,
604.6431 +	(long *)_vq_lengthlist__44p6_p1_0,
604.6432 +	1, -535822336, 1611661312, 2, 0,
604.6433 +	(long *)_vq_quantlist__44p6_p1_0,
604.6434 +	0
604.6435 +};
604.6436 +
604.6437 +static const long _vq_quantlist__44p6_p2_0[] = {
604.6438 +	2,
604.6439 +	1,
604.6440 +	3,
604.6441 +	0,
604.6442 +	4,
604.6443 +};
604.6444 +
604.6445 +static const long _vq_lengthlist__44p6_p2_0[] = {
604.6446 +	 4, 6, 6, 9, 9, 6, 7, 8,10,10, 6, 8, 7,10,10, 8,
604.6447 +	10,10,12,13, 8,10,10,13,12, 6, 8, 8,10,10, 7, 8,
604.6448 +	 9,10,11, 8, 9, 9,11,11,10,10,11,12,13,10,11,11,
604.6449 +	14,13, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 9, 8,11,
604.6450 +	10,10,11,11,13,14,10,11,10,13,12, 9,10,10,12,12,
604.6451 +	10,10,11,12,13,10,11,11,13,13,12,12,13,12,15,13,
604.6452 +	14,13,15,14, 9,10,10,13,12,10,11,11,13,13,10,11,
604.6453 +	10,13,12,13,13,14,14,15,12,13,12,15,12, 6, 8, 8,
604.6454 +	10,11, 8, 9,10,11,12, 8, 9, 9,11,11,10,11,12,13,
604.6455 +	14,10,11,11,14,13, 8, 9, 9,11,12, 9,10,11,12,13,
604.6456 +	 9,10,11,12,13,11,11,13,13,15,11,12,12,14,14, 8,
604.6457 +	 9, 9,12,12, 9,10,11,12,13, 9,10,10,13,12,11,12,
604.6458 +	13,14,15,11,12,12,14,14,11,11,12,13,14,11,12,13,
604.6459 +	13,15,12,13,13,14,15,13,13,14,14,16,14,15,15,16,
604.6460 +	16,11,12,11,14,13,12,13,13,14,14,11,13,12,14,13,
604.6461 +	14,15,15,16,16,13,14,14,16,14, 6, 8, 8,11,10, 8,
604.6462 +	 9, 9,12,11, 8,10, 9,12,11,10,11,11,13,13,10,12,
604.6463 +	11,14,13, 8, 9, 9,12,12, 9,10,10,12,13, 9,11,10,
604.6464 +	13,12,11,12,12,14,14,11,13,12,15,14, 8, 9, 9,12,
604.6465 +	11, 9,10,10,13,12, 9,11,10,13,12,12,12,12,14,14,
604.6466 +	11,13,12,15,13,11,11,12,13,14,11,12,13,13,14,12,
604.6467 +	13,13,14,15,13,13,14,14,16,14,15,15,16,16,11,12,
604.6468 +	11,14,13,12,13,13,15,14,11,13,12,15,13,14,15,15,
604.6469 +	16,16,13,15,13,16,14, 9,10,11,12,13,11,11,12,13,
604.6470 +	14,11,12,12,13,14,13,13,14,14,16,13,14,14,15,16,
604.6471 +	11,11,12,13,14,12,12,13,14,15,12,13,13,14,15,14,
604.6472 +	14,15,15,17,14,15,15,16,17,11,12,12,14,14,12,13,
604.6473 +	13,14,15,12,13,12,15,15,14,15,15,16,17,14,15,15,
604.6474 +	16,16,13,14,14,15,16,14,14,15,15,17,15,15,15,16,
604.6475 +	17,16,16,17,16,18,16,17,17,18,18,13,14,14,16,15,
604.6476 +	14,15,15,17,16,14,15,15,16,16,16,17,17,18,18,16,
604.6477 +	16,16,17,16, 9,11,10,13,12,11,12,12,14,13,11,12,
604.6478 +	11,15,13,13,14,14,16,15,13,14,13,17,14,11,12,12,
604.6479 +	14,14,12,12,13,15,15,12,13,13,15,14,14,14,15,16,
604.6480 +	16,14,15,15,17,16,11,12,11,14,13,12,13,13,15,14,
604.6481 +	12,13,12,15,13,14,15,15,16,16,14,15,14,17,15,13,
604.6482 +	14,14,15,16,14,15,15,16,17,14,15,15,16,17,16,16,
604.6483 +	16,17,17,16,17,17,18,18,13,15,14,16,15,15,15,15,
604.6484 +	17,16,14,15,14,17,15,16,17,17,18,18,16,17,16,18,
604.6485 +	16, 6, 8, 8,11,11, 8, 9, 9,11,12, 8, 9, 9,12,11,
604.6486 +	10,11,11,13,14,10,12,11,14,13, 7, 9, 9,11,12, 9,
604.6487 +	10,10,12,13, 9,10,10,13,12,11,11,12,13,15,11,12,
604.6488 +	12,15,14, 8, 9, 9,12,11, 9,10,10,13,13, 9,11,10,
604.6489 +	13,12,12,12,12,14,15,11,13,12,15,13,10,11,11,13,
604.6490 +	14,11,12,12,13,15,11,12,12,14,14,13,13,14,14,16,
604.6491 +	14,15,14,16,16,11,12,11,14,13,12,13,13,15,14,11,
604.6492 +	13,12,15,13,14,15,15,16,16,13,14,14,16,14, 8, 9,
604.6493 +	 9,11,12, 9,10,11,12,13, 9,10,10,13,12,11,12,13,
604.6494 +	14,15,11,12,12,15,14, 9, 9,11,11,13,10,10,12,12,
604.6495 +	14,10,10,11,13,14,12,12,13,14,16,12,13,13,15,15,
604.6496 +	 9,11,10,13,12,10,11,11,13,14,10,12,11,14,13,12,
604.6497 +	13,13,15,16,12,13,13,15,15,11,11,13,13,15,12,12,
604.6498 +	14,13,15,13,13,14,14,15,14,14,15,14,17,15,15,15,
604.6499 +	16,16,12,13,12,15,14,13,14,14,15,15,12,14,13,15,
604.6500 +	14,15,15,15,17,17,14,15,14,17,15, 7, 9, 9,12,11,
604.6501 +	 9,10,10,12,12, 9,11,10,13,12,11,12,12,14,14,11,
604.6502 +	13,12,15,14, 9,10,10,12,12,10,10,11,12,13,10,11,
604.6503 +	11,14,13,12,12,13,14,15,12,13,13,16,15, 9,10,10,
604.6504 +	13,12,10,11,11,13,13,10,11,10,14,12,13,13,13,15,
604.6505 +	15,12,13,12,15,14,11,12,12,14,14,12,12,13,14,15,
604.6506 +	13,14,13,15,15,14,13,15,14,16,15,16,15,17,16,12,
604.6507 +	12,12,14,14,13,13,14,15,15,12,13,12,15,14,15,15,
604.6508 +	16,16,17,14,15,14,17,14,10,11,12,13,14,11,12,13,
604.6509 +	14,15,11,12,13,14,15,13,14,15,15,17,14,15,15,16,
604.6510 +	16,11,12,13,12,15,12,12,14,13,16,13,13,14,13,16,
604.6511 +	14,14,16,14,18,15,15,16,16,17,12,13,12,15,15,13,
604.6512 +	14,14,15,16,13,14,13,16,15,15,15,16,17,18,15,15,
604.6513 +	15,17,16,14,14,15,14,17,15,14,16,14,17,15,15,16,
604.6514 +	15,18,16,16,17,16,19,17,17,17,17,18,14,15,15,17,
604.6515 +	16,15,16,16,17,17,15,16,15,18,16,17,17,18,18,18,
604.6516 +	16,17,16,18,17,10,11,11,14,13,11,12,12,15,14,11,
604.6517 +	13,12,15,14,14,15,15,16,16,14,15,15,17,16,11,12,
604.6518 +	12,15,14,12,13,13,15,14,13,14,13,16,14,14,15,15,
604.6519 +	16,16,15,16,15,18,16,11,13,12,15,15,13,14,14,15,
604.6520 +	15,12,14,13,16,15,15,16,16,17,17,15,16,15,17,16,
604.6521 +	14,15,14,16,16,14,15,15,16,16,15,16,15,17,16,16,
604.6522 +	16,17,16,17,17,18,17,19,18,14,15,15,17,16,15,16,
604.6523 +	16,17,17,15,15,15,18,16,17,18,18,18,18,16,17,16,
604.6524 +	19,16, 6, 8, 8,11,11, 8, 9, 9,11,12, 8, 9, 9,12,
604.6525 +	11,10,11,12,13,14,10,11,11,14,13, 8, 9, 9,11,12,
604.6526 +	 9,10,11,12,13, 9,10,10,13,13,11,12,13,13,15,11,
604.6527 +	12,12,15,14, 7, 9, 9,12,11, 9,10,10,12,13, 9,10,
604.6528 +	10,13,12,11,12,12,14,15,11,12,11,14,13,11,11,12,
604.6529 +	13,14,11,12,13,13,15,12,13,13,14,15,13,14,14,14,
604.6530 +	16,14,15,15,16,16,10,11,11,14,13,11,12,12,14,14,
604.6531 +	11,12,12,15,13,14,14,14,16,16,13,14,13,16,14, 7,
604.6532 +	 9, 9,11,12, 9,10,10,12,13, 9,10,10,12,12,11,12,
604.6533 +	13,14,15,11,12,12,14,14, 9,10,10,12,13,10,10,11,
604.6534 +	12,14,10,11,11,13,13,12,12,13,14,15,13,13,13,15,
604.6535 +	15, 9,10,10,12,12,10,11,11,13,14,10,11,10,13,12,
604.6536 +	12,13,13,15,16,12,13,12,15,14,11,12,13,14,14,12,
604.6537 +	12,13,14,15,13,14,13,15,15,14,14,15,14,17,15,16,
604.6538 +	15,17,16,11,12,12,14,14,13,13,13,15,15,12,13,12,
604.6539 +	15,14,15,15,15,16,17,14,15,14,16,14, 8, 9, 9,12,
604.6540 +	11, 9,10,10,12,13, 9,11,10,13,12,11,12,12,14,15,
604.6541 +	11,12,12,15,14, 9,10,11,13,13,10,11,12,13,14,10,
604.6542 +	11,11,14,13,12,13,13,15,15,12,13,13,16,15, 9,11,
604.6543 +	 9,13,11,10,11,10,14,13,10,12,10,14,12,12,13,13,
604.6544 +	15,15,12,13,12,16,14,12,12,13,14,15,12,13,14,14,
604.6545 +	16,13,14,14,15,15,14,14,15,15,17,15,16,15,17,16,
604.6546 +	11,13,11,15,13,13,14,13,15,14,12,14,12,16,13,15,
604.6547 +	15,15,16,16,14,15,14,17,14,10,11,11,13,14,11,12,
604.6548 +	13,14,15,11,12,12,14,15,14,14,15,16,17,14,15,15,
604.6549 +	16,16,11,12,13,14,15,12,13,14,15,16,13,14,14,15,
604.6550 +	16,15,15,16,16,18,15,16,16,17,17,11,12,12,14,15,
604.6551 +	13,13,14,14,16,12,13,13,15,15,15,15,16,16,18,14,
604.6552 +	15,15,16,16,14,15,15,16,17,15,15,16,16,17,15,16,
604.6553 +	16,17,17,16,16,17,16,19,17,18,17,18,18,14,14,15,
604.6554 +	16,16,15,15,16,16,17,14,15,15,16,16,17,17,18,18,
604.6555 +	19,16,17,16,17,16,10,12,11,14,13,11,13,12,15,14,
604.6556 +	11,13,12,15,14,14,15,15,16,16,13,15,14,17,15,12,
604.6557 +	13,13,15,15,13,13,14,15,16,13,14,14,16,16,14,15,
604.6558 +	15,17,17,15,16,16,17,17,11,13,12,15,12,13,14,13,
604.6559 +	16,13,12,14,12,16,13,15,16,15,17,16,14,16,14,18,
604.6560 +	14,14,15,15,16,17,15,15,16,16,17,15,16,16,17,17,
604.6561 +	16,16,17,17,18,17,18,17,18,18,14,15,14,17,14,15,
604.6562 +	16,15,18,15,15,16,15,18,14,17,17,17,18,17,16,17,
604.6563 +	16,19,16, 9,11,11,13,13,10,12,12,14,14,11,12,12,
604.6564 +	15,14,13,14,14,16,16,13,14,14,16,16,10,11,12,14,
604.6565 +	14,11,12,13,14,15,12,13,13,15,15,13,14,15,16,16,
604.6566 +	14,15,15,17,16,11,12,12,15,14,12,13,13,15,15,12,
604.6567 +	13,12,15,15,14,15,15,16,17,14,15,14,17,16,12,13,
604.6568 +	14,15,16,13,13,14,15,16,13,14,15,16,16,14,15,16,
604.6569 +	16,18,15,16,16,18,18,13,14,14,16,15,14,15,15,17,
604.6570 +	16,14,15,15,17,16,16,17,17,18,18,16,17,16,18,17,
604.6571 +	10,12,12,14,14,11,12,13,15,15,12,13,13,15,15,13,
604.6572 +	14,15,16,17,14,15,15,17,16,11,11,13,14,15,12,12,
604.6573 +	14,15,16,13,13,14,15,16,14,14,15,16,17,15,15,16,
604.6574 +	17,17,12,13,12,15,15,13,14,14,16,16,13,14,13,16,
604.6575 +	15,15,16,15,17,17,15,16,15,18,16,13,12,15,14,17,
604.6576 +	14,13,16,14,17,14,14,16,15,18,15,14,17,16,18,16,
604.6577 +	16,17,17,18,14,15,15,17,16,15,16,16,17,17,15,16,
604.6578 +	15,18,16,17,17,17,18,18,16,17,16,19,17,10,11,11,
604.6579 +	14,14,11,12,12,15,15,11,13,12,15,15,14,15,14,16,
604.6580 +	16,14,15,15,17,16,11,12,12,15,14,12,12,13,15,15,
604.6581 +	13,14,13,16,15,14,15,15,16,16,15,16,15,18,17,11,
604.6582 +	13,12,15,15,13,14,13,15,15,12,14,13,16,15,15,16,
604.6583 +	15,17,17,15,16,15,18,16,13,14,13,16,16,14,15,14,
604.6584 +	16,16,14,15,15,17,16,16,16,16,16,18,16,18,17,19,
604.6585 +	18,14,15,15,17,16,15,16,16,17,17,15,15,15,17,16,
604.6586 +	17,17,18,18,19,16,17,16,18,16,12,13,13,15,16,13,
604.6587 +	14,14,16,17,13,14,14,16,16,15,15,16,17,18,15,16,
604.6588 +	16,18,17,13,13,14,14,17,14,14,15,15,17,14,14,15,
604.6589 +	16,17,15,15,17,16,18,16,17,17,18,18,13,14,14,17,
604.6590 +	16,14,15,15,17,17,14,15,14,17,16,16,17,17,18,18,
604.6591 +	16,17,16,18,17,15,14,16,13,18,16,15,17,14,19,16,
604.6592 +	16,17,15,18,17,16,18,15,19,18,18,18,17,19,15,16,
604.6593 +	16,18,17,16,17,17,18,18,16,17,16,19,17,18,19,18,
604.6594 +	19,19,17,18,17,20,18,11,12,12,15,15,13,13,14,15,
604.6595 +	16,13,14,13,16,15,15,16,16,17,17,15,16,16,18,17,
604.6596 +	12,14,13,16,15,13,13,14,15,16,14,15,14,17,16,16,
604.6597 +	16,16,16,17,16,17,17,19,17,12,13,14,16,16,14,15,
604.6598 +	15,16,17,13,15,13,17,15,16,17,17,18,18,16,17,16,
604.6599 +	18,16,15,16,15,17,16,15,15,15,17,17,16,17,16,18,
604.6600 +	17,17,16,17,16,18,18,19,18,20,18,15,16,16,17,17,
604.6601 +	16,17,17,18,18,15,16,15,18,17,18,18,19,19,19,17,
604.6602 +	18,16,19,16, 9,11,11,13,13,11,12,12,14,15,10,12,
604.6603 +	12,14,14,13,14,14,16,16,13,14,14,16,16,11,12,12,
604.6604 +	14,14,12,12,13,15,15,12,13,13,15,15,14,15,15,16,
604.6605 +	17,14,15,15,16,16,10,12,11,14,14,12,13,13,15,15,
604.6606 +	11,13,12,15,14,14,15,15,16,17,13,15,14,17,16,13,
604.6607 +	14,14,15,16,14,15,15,16,17,14,15,15,16,17,16,16,
604.6608 +	17,17,18,16,17,17,18,18,12,14,13,16,15,13,15,14,
604.6609 +	17,16,13,14,13,17,15,15,16,16,18,18,15,16,15,18,
604.6610 +	16,10,11,11,14,14,11,12,13,14,15,11,12,12,15,15,
604.6611 +	14,15,15,16,17,14,15,15,16,16,11,12,13,15,15,12,
604.6612 +	13,14,15,16,13,14,14,15,16,15,15,16,16,18,15,15,
604.6613 +	16,17,17,11,12,12,14,15,13,13,14,15,16,12,13,13,
604.6614 +	15,15,15,15,16,17,18,14,15,15,17,16,14,15,15,16,
604.6615 +	17,15,15,16,16,17,15,16,16,17,17,16,16,17,16,19,
604.6616 +	17,17,18,19,18,13,13,14,16,16,14,15,16,17,17,14,
604.6617 +	14,15,16,16,16,16,17,18,18,16,16,16,18,16,10,12,
604.6618 +	12,14,14,12,13,13,15,15,11,13,12,15,15,14,15,15,
604.6619 +	16,17,13,15,14,17,16,12,13,13,15,15,13,13,14,15,
604.6620 +	16,13,14,14,16,16,15,15,16,17,18,15,15,16,17,17,
604.6621 +	11,13,12,15,14,13,14,13,16,15,12,14,12,16,14,15,
604.6622 +	16,15,17,17,14,16,14,17,16,14,15,15,16,17,15,15,
604.6623 +	16,16,18,15,16,16,17,17,16,17,17,17,19,17,17,17,
604.6624 +	18,18,13,15,12,17,14,14,16,14,17,15,14,15,13,17,
604.6625 +	14,16,17,16,18,17,15,17,14,19,15,11,12,12,15,15,
604.6626 +	13,13,14,15,16,13,14,13,16,15,15,16,16,17,18,15,
604.6627 +	16,16,17,17,12,14,13,16,16,13,13,15,15,17,14,15,
604.6628 +	15,17,16,16,16,17,16,19,16,17,17,18,18,12,13,14,
604.6629 +	15,16,14,14,15,16,17,13,14,13,16,15,16,17,17,18,
604.6630 +	19,15,16,16,17,16,15,16,16,18,17,15,15,16,17,18,
604.6631 +	16,17,17,18,18,16,16,18,16,19,18,19,19,20,19,15,
604.6632 +	15,16,16,17,16,16,17,17,18,15,15,15,17,16,18,18,
604.6633 +	19,18,20,17,17,16,18,16,12,13,13,16,15,13,14,14,
604.6634 +	16,16,13,14,14,16,16,15,16,16,17,18,15,16,15,18,
604.6635 +	17,13,14,14,16,16,14,15,15,16,17,14,15,15,17,17,
604.6636 +	16,17,17,18,18,16,17,17,18,18,13,14,13,17,14,14,
604.6637 +	15,14,17,16,14,15,14,17,15,16,17,17,18,18,15,17,
604.6638 +	15,19,15,16,16,16,17,18,16,16,17,17,19,16,17,17,
604.6639 +	18,19,17,17,18,18,20,18,18,18,19,19,15,16,14,18,
604.6640 +	13,16,17,16,19,15,16,17,15,19,14,18,18,18,19,17,
604.6641 +	17,18,16,20,15,
604.6642 +};
604.6643 +
604.6644 +static const static_codebook _44p6_p2_0 = {
604.6645 +	5, 3125,
604.6646 +	(long *)_vq_lengthlist__44p6_p2_0,
604.6647 +	1, -533725184, 1611661312, 3, 0,
604.6648 +	(long *)_vq_quantlist__44p6_p2_0,
604.6649 +	0
604.6650 +};
604.6651 +
604.6652 +static const long _vq_quantlist__44p6_p3_0[] = {
604.6653 +	1,
604.6654 +	0,
604.6655 +	2,
604.6656 +};
604.6657 +
604.6658 +static const long _vq_lengthlist__44p6_p3_0[] = {
604.6659 +	 1, 5, 5, 5, 7, 8, 5, 8, 7, 5, 7, 8, 8, 8,10, 8,
604.6660 +	10,10, 5, 8, 7, 8,10,10, 8,10, 8, 6, 8, 9, 8,10,
604.6661 +	12, 9,11,11, 9,10,11,11,11,13,12,13,13, 9,11,11,
604.6662 +	11,13,13,11,13,12, 6, 9, 8, 9,11,11, 8,12,10, 9,
604.6663 +	11,11,11,12,13,11,13,13, 9,11,10,11,13,13,11,13,
604.6664 +	11, 5, 9, 9, 8,11,11, 9,12,11, 8,10,11,10,11,13,
604.6665 +	11,13,13, 9,11,11,11,13,13,11,13,12, 8,10,11,10,
604.6666 +	12,13,10,13,12,10,10,13,11,11,14,12,13,14,11,13,
604.6667 +	12,13,14,14,12,14,12, 8,11,10,11,12,13,11,14,12,
604.6668 +	10,13,12,12,12,13,13,15,14,11,12,13,13,14,15,12,
604.6669 +	14,12, 5, 9, 9, 9,11,12, 8,11,11, 9,11,11,11,12,
604.6670 +	13,11,13,13, 8,11,10,11,13,13,10,13,11, 8,10,11,
604.6671 +	11,12,14,11,13,12,11,13,12,12,12,14,13,15,14,10,
604.6672 +	12,13,13,14,15,12,13,12, 8,11,10,10,12,13,10,13,
604.6673 +	12,11,12,13,12,12,14,13,14,14,10,13,10,12,14,13,
604.6674 +	11,14,11,
604.6675 +};
604.6676 +
604.6677 +static const static_codebook _44p6_p3_0 = {
604.6678 +	5, 243,
604.6679 +	(long *)_vq_lengthlist__44p6_p3_0,
604.6680 +	1, -533200896, 1614282752, 2, 0,
604.6681 +	(long *)_vq_quantlist__44p6_p3_0,
604.6682 +	0
604.6683 +};
604.6684 +
604.6685 +static const long _vq_quantlist__44p6_p3_1[] = {
604.6686 +	1,
604.6687 +	0,
604.6688 +	2,
604.6689 +};
604.6690 +
604.6691 +static const long _vq_lengthlist__44p6_p3_1[] = {
604.6692 +	 5, 7, 7, 6, 7, 7, 6, 7, 7, 6, 7, 7, 7, 8, 8, 7,
604.6693 +	 8, 8, 6, 7, 7, 7, 8, 8, 7, 8, 8, 7, 7, 8, 7, 8,
604.6694 +	 8, 7, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8,
604.6695 +	 8, 9, 9, 8, 9, 8, 7, 8, 7, 7, 8, 8, 7, 8, 8, 8,
604.6696 +	 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9,
604.6697 +	 8, 6, 8, 8, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8, 9,
604.6698 +	 8, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9, 8, 7, 8, 8, 8,
604.6699 +	 8, 9, 8, 9, 9, 8, 8, 9, 8, 9, 9, 9, 9, 9, 8, 9,
604.6700 +	 9, 9, 9, 9, 9, 9, 9, 7, 8, 8, 8, 9, 9, 8, 9, 8,
604.6701 +	 8, 8, 8, 8, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9,
604.6702 +	 9, 9, 6, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8,
604.6703 +	 9, 8, 9, 9, 7, 8, 8, 8, 9, 9, 8, 9, 8, 7, 8, 8,
604.6704 +	 8, 8, 9, 8, 9, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 8,
604.6705 +	 8, 8, 9, 9, 9, 8, 9, 9, 7, 8, 8, 8, 9, 9, 8, 9,
604.6706 +	 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9,
604.6707 +	 9, 9, 9,
604.6708 +};
604.6709 +
604.6710 +static const static_codebook _44p6_p3_1 = {
604.6711 +	5, 243,
604.6712 +	(long *)_vq_lengthlist__44p6_p3_1,
604.6713 +	1, -535822336, 1611661312, 2, 0,
604.6714 +	(long *)_vq_quantlist__44p6_p3_1,
604.6715 +	0
604.6716 +};
604.6717 +
604.6718 +static const long _vq_quantlist__44p6_p4_0[] = {
604.6719 +	1,
604.6720 +	0,
604.6721 +	2,
604.6722 +};
604.6723 +
604.6724 +static const long _vq_lengthlist__44p6_p4_0[] = {
604.6725 +	 2, 5, 5, 5, 7, 8, 5, 8, 7, 5, 7, 7, 7, 7, 9, 7,
604.6726 +	 9, 9, 5, 7, 7, 8, 9, 9, 7, 9, 7, 6, 8, 8, 8, 9,
604.6727 +	10, 8, 9, 9, 8, 9,10, 9, 9,11,10,11,11, 8, 9, 9,
604.6728 +	10,11,11, 9,11,10, 6, 8, 8, 8, 9, 9, 8,10, 9, 8,
604.6729 +	 9, 9, 9,10,11,10,11,10, 8,10, 9,10,11,11, 9,11,
604.6730 +	 9, 6, 8, 8, 7, 9, 9, 8,10, 9, 7, 9, 9, 9, 9,10,
604.6731 +	 9,10,10, 8, 9, 9, 9,10,10, 9,11,10, 7, 9, 9, 8,
604.6732 +	10,10, 9,10,10, 9, 9,10,10,10,11,10,11,11, 9,10,
604.6733 +	10,10,11,11,10,11,10, 7, 9, 9, 9, 9,10, 9,10, 9,
604.6734 +	 8,10, 9, 9, 9,11,10,11,11, 9,10,10,10,11,11, 9,
604.6735 +	11, 9, 6, 8, 8, 8, 9,10, 7, 9, 9, 8, 9, 9, 9,10,
604.6736 +	10, 9,10,10, 7, 9, 9, 9,10,10, 9,10, 9, 7, 9, 9,
604.6737 +	 9, 9,10, 9,10, 9, 9,10,10, 9, 9,11,10,11,11, 8,
604.6738 +	 9,10,10,11,11, 9,11, 9, 7, 9, 9, 9,10,10, 8,10,
604.6739 +	10, 9,10,10,10,10,11,10,11,11, 9,10, 9,10,11,11,
604.6740 +	10,11,10,
604.6741 +};
604.6742 +
604.6743 +static const static_codebook _44p6_p4_0 = {
604.6744 +	5, 243,
604.6745 +	(long *)_vq_lengthlist__44p6_p4_0,
604.6746 +	1, -531365888, 1616117760, 2, 0,
604.6747 +	(long *)_vq_quantlist__44p6_p4_0,
604.6748 +	0
604.6749 +};
604.6750 +
604.6751 +static const long _vq_quantlist__44p6_p4_1[] = {
604.6752 +	2,
604.6753 +	1,
604.6754 +	3,
604.6755 +	0,
604.6756 +	4,
604.6757 +};
604.6758 +
604.6759 +static const long _vq_lengthlist__44p6_p4_1[] = {
604.6760 +	 6, 8, 8,10,10, 8, 9, 9,10,11, 8,10, 9,11,10, 9,
604.6761 +	10,10,11,11, 9,10,10,11,11, 8, 9, 9,10,10, 9, 9,
604.6762 +	10,11,11,10,10,10,11,11,10,11,11,11,11,10,11,11,
604.6763 +	11,11, 8, 9, 9,11,10,10,10,10,11,11, 9,10, 9,11,
604.6764 +	11,10,11,11,11,11,10,11,10,11,11,10,10,11,11,11,
604.6765 +	10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
604.6766 +	11,11,11,11,10,11,10,11,11,11,11,11,11,11,10,11,
604.6767 +	11,11,11,11,11,11,11,11,11,11,11,11,11, 8, 9,10,
604.6768 +	11,11,10,10,11,11,11,10,10,10,11,11,10,11,11,12,
604.6769 +	12,10,11,11,12,12,10,10,11,11,11,10,10,11,11,12,
604.6770 +	11,11,11,12,12,11,11,12,12,12,11,11,12,12,12,10,
604.6771 +	10,10,11,11,11,11,11,12,12,10,11,11,12,12,11,12,
604.6772 +	12,12,12,11,12,11,12,12,11,11,11,11,12,11,11,12,
604.6773 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6774 +	12,11,11,11,12,11,11,12,12,12,12,11,12,12,12,12,
604.6775 +	12,12,12,12,12,12,12,12,12,12, 8,10, 9,11,11,10,
604.6776 +	10,10,11,11,10,11,10,11,11,10,11,11,12,12,10,11,
604.6777 +	11,12,12,10,10,10,11,11,10,11,11,12,12,11,11,11,
604.6778 +	12,12,11,11,12,12,12,11,12,12,12,12,10,11,10,11,
604.6779 +	11,11,11,11,12,12,10,11,10,12,11,11,12,11,12,12,
604.6780 +	11,12,11,12,12,11,11,11,12,12,11,11,12,12,12,11,
604.6781 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,11,
604.6782 +	11,12,11,11,12,12,12,12,11,12,11,12,12,12,12,12,
604.6783 +	12,12,12,12,12,12,12,10,11,11,11,12,11,11,12,12,
604.6784 +	12,11,11,11,12,12,11,12,12,12,12,11,12,12,12,12,
604.6785 +	11,11,12,12,12,11,12,12,12,12,12,12,12,12,12,12,
604.6786 +	12,12,12,12,12,12,12,12,13,11,12,11,12,12,12,12,
604.6787 +	12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.6788 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6789 +	12,12,12,13,12,13,12,12,12,12,13,12,12,12,12,12,
604.6790 +	12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,12,
604.6791 +	12,12,13,12,10,11,11,12,11,11,11,12,12,12,11,12,
604.6792 +	11,12,12,11,12,12,12,12,11,12,12,12,12,11,11,12,
604.6793 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6794 +	12,12,12,12,12,12,11,12,11,12,12,12,12,12,12,12,
604.6795 +	11,12,12,12,12,12,12,12,12,12,12,12,12,13,12,12,
604.6796 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6797 +	12,12,13,12,12,12,12,13,12,12,12,12,12,12,12,12,
604.6798 +	12,12,12,12,12,12,12,12,12,12,13,13,12,13,12,13,
604.6799 +	12, 8,10,10,11,11,10,10,11,11,11,10,11,10,11,11,
604.6800 +	10,11,11,12,12,10,11,11,12,12, 9,10,11,11,11,10,
604.6801 +	10,11,12,12,10,11,11,12,12,11,11,12,12,12,11,12,
604.6802 +	12,12,12,10,11,10,11,11,11,11,11,12,12,10,11,11,
604.6803 +	12,12,11,12,12,12,12,11,12,11,12,12,11,11,11,12,
604.6804 +	12,11,11,12,12,12,11,12,12,12,12,12,12,12,12,12,
604.6805 +	12,12,12,12,12,11,11,11,12,12,11,12,12,12,12,11,
604.6806 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12, 9,10,
604.6807 +	10,11,11,10,11,11,12,12,10,11,11,12,12,11,11,12,
604.6808 +	12,12,11,12,12,12,12,10,11,11,12,12,11,11,12,12,
604.6809 +	12,11,11,12,12,12,11,11,12,12,12,12,12,12,12,12,
604.6810 +	10,11,11,12,12,11,12,12,12,12,11,12,11,12,12,12,
604.6811 +	12,12,12,12,12,12,12,12,12,11,11,12,12,12,12,12,
604.6812 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6813 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6814 +	12,12,12,12,12,12,12,12,12,12,12, 9,10,10,11,11,
604.6815 +	10,11,11,12,12,10,11,11,12,11,11,12,12,12,12,11,
604.6816 +	12,12,12,12,10,11,11,12,12,11,11,11,12,12,11,12,
604.6817 +	12,12,12,12,12,12,12,12,12,12,12,12,12,10,11,11,
604.6818 +	12,12,11,12,12,12,12,11,12,11,12,12,12,12,12,12,
604.6819 +	12,12,12,12,12,12,11,12,12,12,12,11,12,12,12,12,
604.6820 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,
604.6821 +	12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,
604.6822 +	12,12,12,12,12,12,12,12,11,11,11,12,12,11,12,12,
604.6823 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6824 +	13,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6825 +	12,12,13,12,13,12,12,13,13,13,11,12,12,12,12,12,
604.6826 +	12,12,13,13,12,12,12,13,12,12,12,12,13,13,12,13,
604.6827 +	12,13,13,12,12,12,12,12,12,12,12,12,13,12,13,13,
604.6828 +	13,13,12,13,13,13,13,13,13,13,13,13,12,12,12,12,
604.6829 +	12,12,12,13,13,13,12,13,12,13,13,12,13,13,13,13,
604.6830 +	12,13,13,13,13,11,11,11,12,12,11,12,12,12,12,11,
604.6831 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,12,
604.6832 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,
604.6833 +	12,13,12,12,12,13,13,11,12,12,12,12,12,12,12,12,
604.6834 +	13,12,12,12,13,12,12,13,12,13,13,12,13,12,13,13,
604.6835 +	12,12,12,12,12,12,12,13,13,13,12,12,13,13,13,12,
604.6836 +	13,13,12,13,13,13,13,13,13,12,12,12,12,12,12,13,
604.6837 +	12,13,13,12,13,12,13,12,12,13,13,13,13,12,13,13,
604.6838 +	13,13, 8,10,10,11,11,10,10,11,11,11, 9,11,10,11,
604.6839 +	11,10,11,11,12,12,10,11,11,12,12,10,10,11,11,11,
604.6840 +	10,11,11,12,12,11,11,11,12,12,11,11,12,12,12,11,
604.6841 +	12,12,12,12, 9,11,10,11,11,10,11,11,12,12,10,11,
604.6842 +	10,12,12,11,12,12,12,12,11,12,11,12,12,11,11,11,
604.6843 +	12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,12,
604.6844 +	12,12,12,12,12,12,11,11,11,12,12,11,12,12,12,12,
604.6845 +	11,12,11,12,12,12,12,12,12,12,12,12,12,12,12, 9,
604.6846 +	10,10,11,11,10,11,11,12,12,10,11,11,12,12,11,12,
604.6847 +	12,12,12,11,12,12,12,12,10,11,11,12,12,11,11,12,
604.6848 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6849 +	12,10,11,11,12,12,11,11,12,12,12,11,11,11,12,12,
604.6850 +	12,12,12,12,12,11,12,12,12,12,11,12,12,12,12,11,
604.6851 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6852 +	12,12,12,11,12,12,12,12,12,12,12,12,12,11,12,12,
604.6853 +	12,12,12,12,12,12,12,12,12,12,12,12, 9,10,10,11,
604.6854 +	11,10,11,11,12,12,10,11,11,12,12,11,12,12,12,12,
604.6855 +	11,12,11,12,12,10,11,11,12,12,11,11,12,12,12,11,
604.6856 +	11,12,12,12,12,12,12,12,12,12,12,12,12,12,10,11,
604.6857 +	11,12,12,11,12,11,12,12,11,12,11,12,12,12,12,12,
604.6858 +	12,12,11,12,11,12,12,11,12,12,12,12,12,12,12,12,
604.6859 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6860 +	11,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6861 +	12,12,12,12,12,12,12,12,12,11,11,11,12,12,11,12,
604.6862 +	12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.6863 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,13,
604.6864 +	13,12,12,12,13,13,12,12,13,13,13,11,12,12,12,12,
604.6865 +	12,12,12,12,12,12,12,12,12,12,12,13,12,13,13,12,
604.6866 +	12,12,13,12,12,12,12,12,12,12,12,13,13,13,12,12,
604.6867 +	13,13,13,12,13,13,12,13,12,13,13,13,13,12,12,12,
604.6868 +	12,12,12,12,13,13,13,12,12,12,13,12,12,13,13,13,
604.6869 +	13,12,13,13,13,13,11,11,11,12,12,11,12,12,12,12,
604.6870 +	11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,
604.6871 +	12,12,12,12,12,12,12,12,12,12,12,12,13,12,12,12,
604.6872 +	13,13,13,12,12,12,13,13,11,12,12,12,12,12,12,12,
604.6873 +	13,12,12,12,12,13,12,12,13,12,13,13,12,13,12,13,
604.6874 +	12,12,12,12,12,12,12,12,13,13,13,12,13,13,13,13,
604.6875 +	12,13,13,13,13,13,13,13,13,13,12,12,12,12,12,12,
604.6876 +	13,12,13,12,12,13,12,13,12,13,13,13,13,13,12,13,
604.6877 +	13,13,13,10,11,11,12,12,11,12,12,12,12,11,12,12,
604.6878 +	12,12,12,12,12,12,12,12,12,12,12,12,11,11,12,12,
604.6879 +	12,11,12,12,12,12,12,12,12,12,12,12,12,12,13,13,
604.6880 +	12,12,12,13,13,11,12,12,12,12,12,12,12,12,12,12,
604.6881 +	12,12,12,12,12,12,12,13,13,12,12,12,13,12,12,12,
604.6882 +	12,12,12,12,12,12,12,13,12,12,12,12,13,12,12,13,
604.6883 +	12,13,12,13,13,13,13,12,12,12,12,12,12,12,12,13,
604.6884 +	12,12,12,12,13,12,12,13,13,13,13,12,13,12,13,13,
604.6885 +	11,11,11,12,12,11,12,12,12,12,11,12,12,12,12,12,
604.6886 +	12,12,12,13,12,12,12,13,12,11,12,12,12,12,12,12,
604.6887 +	12,12,13,12,12,12,12,13,12,12,13,13,13,12,12,13,
604.6888 +	13,13,11,12,12,12,12,12,12,12,12,13,12,12,12,13,
604.6889 +	12,12,13,12,13,13,12,13,12,13,13,12,12,12,12,12,
604.6890 +	12,12,13,12,13,12,12,13,13,13,12,12,13,13,13,13,
604.6891 +	13,13,13,13,12,12,12,12,12,12,13,13,13,13,12,13,
604.6892 +	12,13,12,12,13,13,13,13,12,13,13,13,13,11,11,11,
604.6893 +	12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,12,
604.6894 +	12,12,12,12,12,13,11,12,12,12,12,12,12,12,12,13,
604.6895 +	12,12,12,13,13,12,12,13,13,13,12,12,13,13,13,11,
604.6896 +	12,12,12,12,12,12,12,13,13,12,12,12,13,12,12,13,
604.6897 +	12,13,13,12,13,12,13,13,12,12,12,12,12,12,12,12,
604.6898 +	12,13,12,13,12,13,13,12,13,13,13,13,12,13,13,13,
604.6899 +	13,12,12,12,12,12,12,13,12,13,13,12,12,12,13,13,
604.6900 +	12,13,13,13,13,12,13,12,13,13,11,12,12,12,12,11,
604.6901 +	12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,
604.6902 +	12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.6903 +	12,12,12,12,13,12,13,12,12,12,13,13,11,12,12,12,
604.6904 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,
604.6905 +	12,13,12,13,13,12,12,12,12,12,12,12,13,12,13,12,
604.6906 +	12,13,12,13,12,12,13,12,13,12,13,13,13,13,12,12,
604.6907 +	12,12,12,12,12,12,12,12,12,12,12,13,12,12,13,13,
604.6908 +	13,13,12,13,12,13,12,11,11,11,12,12,11,12,12,12,
604.6909 +	12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6910 +	11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6911 +	12,12,12,12,12,12,12,13,13,11,12,12,12,12,12,12,
604.6912 +	12,12,12,12,12,12,12,12,12,12,12,13,13,12,12,12,
604.6913 +	13,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6914 +	12,12,12,13,12,12,12,13,12,12,12,12,12,12,12,12,
604.6915 +	12,12,12,13,12,12,12,12,13,12,12,13,12,13,12,12,
604.6916 +	13,12,13,12,10,11,11,12,12,11,12,12,12,12,11,12,
604.6917 +	11,12,12,11,12,12,12,12,11,12,12,12,12,11,12,12,
604.6918 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6919 +	13,12,12,12,13,13,11,12,11,12,12,12,12,12,12,12,
604.6920 +	11,12,12,12,12,12,12,12,13,13,12,12,12,13,12,12,
604.6921 +	12,12,12,12,12,12,12,12,13,12,12,12,12,13,12,13,
604.6922 +	13,12,13,12,13,13,13,13,12,12,12,12,12,12,12,12,
604.6923 +	13,13,12,12,12,13,12,12,13,13,13,13,12,13,12,13,
604.6924 +	12,11,11,11,12,12,11,12,12,12,12,11,12,12,12,12,
604.6925 +	12,12,12,13,13,12,12,12,13,12,11,12,12,12,12,12,
604.6926 +	12,12,12,13,12,12,12,13,13,12,12,13,13,13,12,12,
604.6927 +	13,13,13,11,12,12,12,12,12,12,12,13,13,12,12,12,
604.6928 +	13,12,12,13,12,13,13,12,12,12,13,13,12,12,12,12,
604.6929 +	12,12,12,13,13,13,12,12,13,13,13,12,12,13,13,13,
604.6930 +	12,13,13,13,13,12,12,12,12,12,12,12,13,13,13,12,
604.6931 +	12,12,13,12,12,13,13,13,13,12,13,13,13,13,11,11,
604.6932 +	11,12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,
604.6933 +	12,13,12,12,12,13,13,11,12,12,12,12,12,12,12,12,
604.6934 +	13,12,12,12,13,13,12,12,13,13,13,12,12,13,13,13,
604.6935 +	11,12,12,12,12,12,12,12,13,12,12,12,12,13,12,12,
604.6936 +	13,12,13,13,12,13,12,13,13,12,12,12,12,12,12,12,
604.6937 +	12,13,13,12,13,12,13,13,12,13,13,13,13,13,13,13,
604.6938 +	13,13,12,12,12,12,12,12,13,12,13,13,12,13,12,13,
604.6939 +	12,12,13,13,13,13,12,13,12,13,13,11,11,11,12,12,
604.6940 +	11,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,
604.6941 +	12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,
604.6942 +	12,12,12,12,12,12,12,13,12,12,12,13,13,11,12,12,
604.6943 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,
604.6944 +	13,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,
604.6945 +	12,12,12,12,13,12,12,12,12,13,12,12,13,12,13,12,
604.6946 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6947 +	13,12,12,12,13,12,12,12,11,12,11,12,12,11,12,12,
604.6948 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.6949 +	12,11,12,12,12,12,12,12,12,12,13,12,12,12,12,12,
604.6950 +	12,12,12,13,13,12,12,12,13,13,11,12,12,12,12,12,
604.6951 +	12,12,12,12,12,12,12,12,12,12,13,12,13,13,12,12,
604.6952 +	12,13,12,12,12,12,12,12,12,12,12,12,13,12,12,12,
604.6953 +	13,13,12,12,13,12,13,12,13,13,13,13,12,12,12,12,
604.6954 +	12,12,12,12,13,12,12,12,12,13,12,12,13,12,13,13,
604.6955 +	12,13,12,13,12,
604.6956 +};
604.6957 +
604.6958 +static const static_codebook _44p6_p4_1 = {
604.6959 +	5, 3125,
604.6960 +	(long *)_vq_lengthlist__44p6_p4_1,
604.6961 +	1, -533725184, 1611661312, 3, 0,
604.6962 +	(long *)_vq_quantlist__44p6_p4_1,
604.6963 +	0
604.6964 +};
604.6965 +
604.6966 +static const long _vq_quantlist__44p6_p5_0[] = {
604.6967 +	2,
604.6968 +	1,
604.6969 +	3,
604.6970 +	0,
604.6971 +	4,
604.6972 +};
604.6973 +
604.6974 +static const long _vq_lengthlist__44p6_p5_0[] = {
604.6975 +	 2, 6, 6,10,10, 5, 7, 8,11,12, 5, 8, 7,12,11, 9,
604.6976 +	11,11,13,15, 9,11,11,15,13, 6, 7, 8,11,11, 7, 7,
604.6977 +	 9,11,13, 8, 9, 9,13,12,11,11,12,12,15,11,12,12,
604.6978 +	15,14, 6, 8, 7,11,11, 8, 9, 9,12,13, 7, 9, 7,13,
604.6979 +	11,11,12,12,14,15,11,12,11,15,12,10,11,11,12,14,
604.6980 +	10,11,12,12,15,12,13,13,14,15,13,12,14,12,16,15,
604.6981 +	15,15,16,16,10,11,11,14,12,12,13,13,15,14,10,12,
604.6982 +	11,15,12,15,15,15,16,17,13,14,12,17,12, 6, 8, 8,
604.6983 +	12,12, 8, 9,10,13,13, 8, 9, 9,13,13,12,12,13,15,
604.6984 +	16,12,13,13,16,15, 8, 9,10,12,13, 9, 9,11,13,14,
604.6985 +	10,11,11,14,14,13,13,14,15,16,13,14,14,16,16, 8,
604.6986 +	10, 9,13,13,10,11,11,14,14, 9,10,10,14,13,13,14,
604.6987 +	14,16,17,13,13,13,16,15,12,13,13,14,16,13,13,14,
604.6988 +	14,16,14,14,14,16,16,15,15,16,15,18,16,17,17,18,
604.6989 +	18,12,13,13,15,15,14,14,14,16,16,13,14,13,16,15,
604.6990 +	16,16,17,18,18,15,16,15,18,15, 6, 8, 8,12,12, 8,
604.6991 +	 9, 9,13,13, 8,10, 9,13,13,12,13,13,15,16,12,13,
604.6992 +	12,16,15, 8, 9,10,13,13, 9,10,10,13,14,10,11,11,
604.6993 +	14,14,13,13,13,15,16,13,14,14,17,16, 8,10, 9,13,
604.6994 +	13,10,11,11,14,14, 9,11, 9,14,13,13,14,14,16,16,
604.6995 +	13,14,13,16,14,12,13,13,15,16,13,13,14,15,16,14,
604.6996 +	14,14,16,16,15,15,16,15,18,17,17,17,18,18,12,13,
604.6997 +	13,16,14,14,14,14,16,16,13,14,13,16,14,16,17,17,
604.6998 +	18,18,15,16,15,18,15,11,12,13,14,16,13,13,14,15,
604.6999 +	17,13,14,14,16,17,16,16,17,17,19,16,17,17,18,19,
604.7000 +	13,13,14,16,16,14,14,15,16,17,14,15,15,17,17,17,
604.7001 +	16,17,17,19,17,17,18,19,19,13,14,14,16,16,14,14,
604.7002 +	15,17,18,14,15,14,17,17,17,17,18,18,19,17,17,17,
604.7003 +	18,19,16,16,16,17,18,17,17,17,18,19,17,17,17,18,
604.7004 +	19,18,18,19,18,20,19,20,19,21,20,16,17,17,18,18,
604.7005 +	17,17,18,19,19,17,17,17,19,18,19,19,19,19,20,19,
604.7006 +	19,19,20,19,11,13,12,16,14,13,14,14,17,16,13,14,
604.7007 +	13,17,15,16,17,17,18,18,16,17,16,19,17,13,14,14,
604.7008 +	16,16,14,14,14,17,17,14,15,15,17,16,17,17,17,19,
604.7009 +	19,17,18,17,19,18,13,14,13,17,16,14,15,15,17,17,
604.7010 +	14,15,14,18,16,17,17,17,19,19,17,17,16,19,17,16,
604.7011 +	17,17,18,19,17,17,17,18,18,17,18,17,19,18,18,19,
604.7012 +	18,19,19,19,20,19,20,20,16,17,16,18,17,17,17,17,
604.7013 +	18,18,17,18,17,19,17,19,19,19,19,20,18,19,19,20,
604.7014 +	18, 6, 8, 8,12,12, 8, 9, 9,13,13, 8,10, 9,13,13,
604.7015 +	11,13,13,15,16,12,13,13,16,15, 8, 9, 9,13,13, 9,
604.7016 +	 9,10,13,14,10,11,11,14,14,12,12,13,14,16,13,14,
604.7017 +	14,17,16, 8,10, 9,13,13,10,11,11,14,14, 9,11,10,
604.7018 +	14,13,13,14,14,16,16,13,14,13,16,15,12,13,13,14,
604.7019 +	16,12,13,14,14,16,13,14,14,16,16,15,14,16,15,18,
604.7020 +	16,17,17,18,17,12,13,13,16,15,14,14,14,16,16,13,
604.7021 +	14,13,16,15,16,16,17,17,17,15,16,15,18,15, 7, 9,
604.7022 +	 9,13,13, 9, 9,11,13,14, 9,10,10,14,13,12,13,14,
604.7023 +	15,16,12,14,13,17,15, 9, 9,10,13,14,10, 9,11,13,
604.7024 +	15,11,11,11,14,14,13,12,14,14,17,14,14,14,17,16,
604.7025 +	 9,10,10,14,13,11,11,11,14,14,10,11,10,15,13,14,
604.7026 +	14,14,16,17,13,14,13,17,14,13,13,14,14,16,13,13,
604.7027 +	14,14,17,14,14,14,16,16,15,14,16,15,18,17,17,17,
604.7028 +	18,18,13,14,13,16,15,14,14,15,17,16,13,14,13,17,
604.7029 +	15,17,16,17,17,17,15,16,14,18,14, 7, 9, 9,13,13,
604.7030 +	 9,10,10,13,14, 9,11,10,14,13,13,14,14,16,16,13,
604.7031 +	14,14,17,15, 9,10,10,14,13, 9,10,11,13,14,11,12,
604.7032 +	11,15,14,13,13,14,14,16,14,15,15,17,17, 9,10,10,
604.7033 +	14,14,11,12,12,14,15,10,11,10,15,13,14,15,15,17,
604.7034 +	17,14,15,13,17,14,13,14,13,16,16,13,13,14,15,16,
604.7035 +	14,15,15,17,17,15,14,16,15,18,17,18,17,20,18,13,
604.7036 +	14,14,16,16,15,15,15,17,17,13,14,13,17,15,17,17,
604.7037 +	18,18,18,15,16,14,19,14,12,13,13,15,16,13,13,15,
604.7038 +	16,17,13,14,14,16,16,15,15,17,17,19,16,17,17,19,
604.7039 +	18,13,13,14,15,17,14,13,15,15,17,14,15,15,16,17,
604.7040 +	16,15,18,16,19,17,17,17,18,19,13,14,14,17,16,14,
604.7041 +	15,15,17,17,14,15,14,17,16,17,17,17,18,19,16,17,
604.7042 +	16,19,17,16,16,17,16,18,16,16,17,16,19,17,17,18,
604.7043 +	18,19,18,17,18,17,21,19,19,19,20,19,16,17,17,18,
604.7044 +	18,17,17,18,18,19,16,17,16,18,18,19,19,19,19,20,
604.7045 +	18,18,17,20,18,11,13,13,16,15,13,14,14,16,17,13,
604.7046 +	15,14,17,16,16,17,17,18,18,17,17,17,19,18,13,14,
604.7047 +	13,17,16,14,13,14,16,17,15,16,15,18,16,17,16,17,
604.7048 +	17,19,18,18,18,20,18,13,14,14,16,17,15,15,15,17,
604.7049 +	18,14,15,14,18,16,18,18,18,19,20,17,18,16,20,17,
604.7050 +	16,17,16,18,18,16,16,17,18,18,17,18,18,19,18,18,
604.7051 +	17,19,17,20,19,20,19,22,20,16,16,17,18,18,18,17,
604.7052 +	17,19,19,16,17,16,18,17,19,20,19,22,21,18,19,18,
604.7053 +	21,17, 6, 8, 8,12,12, 8, 9,10,13,13, 8, 9, 9,13,
604.7054 +	13,12,13,13,15,16,11,13,13,16,15, 8, 9,10,13,13,
604.7055 +	 9,10,11,13,14,10,11,11,14,14,13,13,14,15,16,13,
604.7056 +	14,14,16,16, 8, 9, 9,13,13,10,11,11,14,14, 9,10,
604.7057 +	 9,14,13,13,14,14,16,17,12,14,12,16,14,12,13,13,
604.7058 +	15,16,13,13,14,15,16,13,14,14,15,17,15,15,16,15,
604.7059 +	18,16,16,17,17,17,12,13,13,16,14,13,14,14,16,16,
604.7060 +	12,14,13,16,14,16,17,17,18,18,15,15,14,18,14, 7,
604.7061 +	 9, 9,13,13, 9,10,11,13,14, 9,10,10,14,13,13,14,
604.7062 +	14,15,17,13,14,14,16,15, 9,10,10,14,14,10,10,11,
604.7063 +	13,15,11,12,12,15,14,14,13,15,14,17,14,15,15,17,
604.7064 +	17, 9,10,10,13,14,11,11,12,14,15, 9,11,10,14,13,
604.7065 +	14,15,15,16,18,13,14,13,16,14,13,14,14,16,16,13,
604.7066 +	13,14,15,17,15,15,15,16,17,15,14,16,15,18,17,17,
604.7067 +	18,19,18,13,14,14,16,16,14,15,15,17,17,13,14,13,
604.7068 +	16,15,17,17,18,18,18,15,16,14,18,15, 7, 9, 9,13,
604.7069 +	13, 9,10,10,13,14, 9,11,10,14,13,12,13,14,15,16,
604.7070 +	12,14,13,16,15, 9,10,10,13,14,10,10,11,13,14,11,
604.7071 +	11,11,15,14,13,13,14,14,16,14,14,14,17,16, 9,10,
604.7072 +	 9,14,13,11,11,11,14,14,10,11, 9,15,13,14,14,14,
604.7073 +	16,16,13,14,12,17,14,13,13,14,15,16,13,13,14,15,
604.7074 +	16,14,15,14,16,17,15,14,16,14,18,16,17,17,18,18,
604.7075 +	13,14,13,16,14,14,14,14,16,16,13,14,13,17,14,17,
604.7076 +	17,17,18,18,15,16,14,18,15,11,13,13,16,16,13,14,
604.7077 +	15,16,17,13,14,14,17,16,16,17,17,18,19,17,17,17,
604.7078 +	19,18,13,14,14,17,17,13,13,15,16,18,15,15,15,17,
604.7079 +	17,17,16,18,17,20,18,17,18,19,19,13,14,14,16,17,
604.7080 +	15,15,16,16,18,14,15,14,16,16,17,17,18,18,20,17,
604.7081 +	18,16,18,17,16,17,16,19,18,16,16,17,18,19,18,18,
604.7082 +	18,19,19,18,17,18,17,21,20,19,19,21,21,16,16,17,
604.7083 +	18,18,17,17,18,19,19,16,17,16,19,18,20,20,20,19,
604.7084 +	21,18,18,17,20,18,12,13,13,16,15,13,14,14,16,16,
604.7085 +	13,14,13,17,16,16,17,17,18,18,15,17,15,19,17,13,
604.7086 +	14,14,16,17,14,14,15,16,17,14,15,15,17,17,16,16,
604.7087 +	17,17,18,17,17,17,19,19,13,14,13,17,15,14,15,15,
604.7088 +	17,16,14,15,13,17,15,17,18,17,19,18,16,17,15,20,
604.7089 +	16,16,17,17,18,18,16,16,17,18,18,17,18,17,19,18,
604.7090 +	17,17,18,18,20,19,20,19,20,19,16,16,16,19,16,17,
604.7091 +	17,17,19,18,16,17,16,19,16,19,19,19,19,19,18,19,
604.7092 +	17,19,17,11,13,13,16,16,13,14,14,17,17,13,14,14,
604.7093 +	17,17,15,17,17,19,19,16,18,17,20,19,12,14,14,17,
604.7094 +	17,13,14,15,17,18,14,15,15,17,18,16,16,17,18,20,
604.7095 +	17,18,18,20,18,13,14,14,17,17,14,15,15,17,18,14,
604.7096 +	15,15,17,17,17,18,17,19,19,17,18,17,19,19,15,16,
604.7097 +	16,18,18,15,16,17,18,19,16,17,17,19,19,17,17,18,
604.7098 +	18,21,18,19,19,21,19,16,17,17,18,18,17,17,18,19,
604.7099 +	19,17,18,17,19,19,19,19,19,20,20,18,19,18,21,19,
604.7100 +	12,13,13,16,16,13,14,14,16,17,13,15,14,17,16,15,
604.7101 +	16,17,17,19,16,17,17,19,18,13,13,14,16,17,14,13,
604.7102 +	15,16,17,14,15,15,17,17,15,15,17,17,20,17,17,18,
604.7103 +	19,18,13,14,14,17,16,15,15,15,17,18,14,15,14,17,
604.7104 +	16,17,17,17,18,18,16,17,16,19,17,16,15,17,17,19,
604.7105 +	16,15,17,16,19,17,16,17,18,19,17,16,19,16,20,19,
604.7106 +	18,19,19,19,16,17,17,18,18,17,17,17,18,19,16,17,
604.7107 +	16,19,18,20,19,19,20,19,18,18,17,20,17,11,13,13,
604.7108 +	16,16,13,14,15,16,17,14,15,14,18,16,17,17,17,18,
604.7109 +	21,17,18,17,20,19,13,14,14,17,16,13,14,15,16,18,
604.7110 +	15,16,15,18,17,17,16,17,17,19,17,18,18,20,19,13,
604.7111 +	14,14,16,17,15,15,16,17,18,14,15,14,18,17,17,18,
604.7112 +	18,19,20,17,18,16,19,17,16,17,15,19,18,16,16,16,
604.7113 +	18,18,17,18,17,20,19,18,17,18,17,20,20,20,19,22,
604.7114 +	20,16,17,17,18,19,18,18,18,19,20,16,17,16,19,18,
604.7115 +	20,19,19,20,20,18,19,17,20,17,13,14,14,16,17,14,
604.7116 +	14,16,16,18,14,16,15,17,16,16,16,17,17,18,17,17,
604.7117 +	16,19,18,14,14,15,16,17,14,14,16,16,18,16,16,16,
604.7118 +	17,17,16,15,17,16,19,18,18,18,19,19,14,15,15,17,
604.7119 +	17,15,16,16,17,18,14,16,14,18,16,17,17,18,18,19,
604.7120 +	16,17,16,19,17,16,16,17,16,18,16,16,17,16,19,18,
604.7121 +	18,18,17,18,17,16,18,16,20,19,19,19,19,19,16,17,
604.7122 +	17,18,18,17,17,18,19,19,16,17,16,19,17,18,19,19,
604.7123 +	19,20,17,18,16,20,16,11,14,13,17,17,14,14,16,16,
604.7124 +	18,14,16,14,19,16,18,18,19,18,19,18,19,18,21,18,
604.7125 +	13,15,14,18,16,14,14,16,16,18,16,17,16,19,17,18,
604.7126 +	16,19,17,20,19,19,19,21,19,13,14,15,17,18,17,16,
604.7127 +	17,17,19,14,16,14,18,16,20,19,19,20,21,18,19,16,
604.7128 +	21,17,17,18,16,19,17,16,16,17,18,18,19,19,18,21,
604.7129 +	18,17,17,18,17,20,20,20,20,22,20,17,17,18,18,20,
604.7130 +	19,19,19,18,20,16,17,17,19,19,21,21,21,20,21,17,
604.7131 +	19,17,23,17,11,13,13,16,16,13,14,14,17,17,13,14,
604.7132 +	14,17,17,16,17,17,19,20,15,16,16,19,19,13,14,14,
604.7133 +	16,17,14,15,15,17,18,14,15,15,17,17,17,17,18,19,
604.7134 +	19,17,17,18,19,19,13,14,14,17,16,14,15,15,17,17,
604.7135 +	13,15,14,18,17,17,18,18,19,20,16,17,16,19,18,16,
604.7136 +	16,17,18,18,17,17,17,18,19,17,18,17,19,19,19,19,
604.7137 +	19,19,20,19,20,19,20,20,15,16,16,18,17,16,17,17,
604.7138 +	20,18,15,16,16,19,17,19,19,19,20,20,17,18,17,21,
604.7139 +	17,11,13,13,16,16,13,14,15,16,17,13,15,14,17,16,
604.7140 +	17,17,18,18,20,17,17,17,19,19,13,14,14,17,17,14,
604.7141 +	14,15,17,18,15,15,15,18,17,17,17,18,17,20,18,18,
604.7142 +	17,20,18,13,14,14,16,17,15,15,16,17,18,14,15,13,
604.7143 +	17,17,17,18,18,19,20,17,17,16,19,17,16,17,17,18,
604.7144 +	18,16,16,17,18,18,18,18,18,19,19,18,17,19,18,21,
604.7145 +	19,20,20,20,20,16,15,17,18,18,17,17,18,18,20,16,
604.7146 +	16,16,18,17,20,19,20,21,22,17,18,17,20,17,12,13,
604.7147 +	13,16,16,13,14,15,16,17,13,14,14,17,16,16,17,18,
604.7148 +	18,19,15,16,16,19,18,13,14,14,16,17,14,14,15,16,
604.7149 +	17,14,15,15,17,17,16,16,17,17,19,17,17,17,19,18,
604.7150 +	13,14,13,17,16,14,15,15,17,17,13,15,13,17,16,17,
604.7151 +	17,17,19,19,15,17,15,19,17,16,17,17,18,18,16,16,
604.7152 +	17,17,19,17,18,17,19,19,18,17,19,17,19,19,19,19,
604.7153 +	20,19,15,17,15,19,16,17,17,16,19,18,16,17,15,18,
604.7154 +	16,19,19,19,20,19,17,19,16,19,16,11,14,14,17,17,
604.7155 +	15,14,16,16,18,15,16,14,18,16,18,18,19,18,21,18,
604.7156 +	19,18,20,18,13,15,14,18,17,14,14,16,16,18,16,17,
604.7157 +	16,19,17,17,17,19,17,22,19,19,19,21,19,13,14,15,
604.7158 +	17,18,17,16,17,17,19,14,16,14,18,16,19,19,19,20,
604.7159 +	21,18,18,16,20,17,17,18,16,19,18,15,17,17,19,19,
604.7160 +	19,19,18,21,19,18,17,20,17,21,22,21,20,21,21,17,
604.7161 +	16,19,18,20,19,18,19,18,20,16,17,16,19,18,21,20,
604.7162 +	21,19,23,18,19,16,20,17,13,14,14,17,16,14,14,15,
604.7163 +	16,18,14,16,14,17,16,16,16,17,17,19,16,17,16,19,
604.7164 +	17,14,15,15,17,17,14,14,16,16,17,15,16,16,18,17,
604.7165 +	16,16,17,17,19,17,18,17,19,18,14,15,14,17,16,16,
604.7166 +	16,16,17,17,14,16,14,17,16,18,18,18,18,19,16,17,
604.7167 +	15,19,16,17,17,17,18,18,16,15,17,17,18,18,18,18,
604.7168 +	19,19,17,16,18,16,19,19,19,19,19,19,16,17,16,19,
604.7169 +	16,18,18,17,19,18,16,17,16,19,16,19,19,20,19,19,
604.7170 +	17,18,16,20,16,
604.7171 +};
604.7172 +
604.7173 +static const static_codebook _44p6_p5_0 = {
604.7174 +	5, 3125,
604.7175 +	(long *)_vq_lengthlist__44p6_p5_0,
604.7176 +	1, -528744448, 1616642048, 3, 0,
604.7177 +	(long *)_vq_quantlist__44p6_p5_0,
604.7178 +	0
604.7179 +};
604.7180 +
604.7181 +static const long _vq_quantlist__44p6_p5_1[] = {
604.7182 +	3,
604.7183 +	2,
604.7184 +	4,
604.7185 +	1,
604.7186 +	5,
604.7187 +	0,
604.7188 +	6,
604.7189 +};
604.7190 +
604.7191 +static const long _vq_lengthlist__44p6_p5_1[] = {
604.7192 +	 2, 3, 3, 3, 3, 3, 3,
604.7193 +};
604.7194 +
604.7195 +static const static_codebook _44p6_p5_1 = {
604.7196 +	1, 7,
604.7197 +	(long *)_vq_lengthlist__44p6_p5_1,
604.7198 +	1, -533200896, 1611661312, 3, 0,
604.7199 +	(long *)_vq_quantlist__44p6_p5_1,
604.7200 +	0
604.7201 +};
604.7202 +
604.7203 +static const long _vq_quantlist__44p6_p6_0[] = {
604.7204 +	1,
604.7205 +	0,
604.7206 +	2,
604.7207 +};
604.7208 +
604.7209 +static const long _vq_lengthlist__44p6_p6_0[] = {
604.7210 +	 1, 5, 5, 5, 7, 9, 5, 9, 7, 5, 7, 8, 7, 7,10, 9,
604.7211 +	10,10, 5, 8, 7, 9,10,10, 7,10, 7, 6, 9, 9, 9,10,
604.7212 +	12, 9,11,11, 9,10,11,11,11,13,12,13,13, 9,11,11,
604.7213 +	12,13,13,11,13,11, 6, 9, 9, 9,11,11, 9,12,10, 9,
604.7214 +	11,11,11,11,13,12,13,13, 9,11,10,12,13,13,11,13,
604.7215 +	11, 6, 9, 9, 9,11,12, 9,12,11, 9,10,11,10,10,13,
604.7216 +	12,13,13, 9,11,11,12,13,12,11,13,11, 7, 9,10, 9,
604.7217 +	10,12,10,12,11,10,10,12,10,10,12,12,12,13,10,11,
604.7218 +	11,12,12,13,10,12,10, 7,10,10,11,11,14,11,14,11,
604.7219 +	10,12,11,11,11,14,14,14,14,10,11,12,14,14,14,11,
604.7220 +	14,11, 6, 9, 9, 9,11,12, 9,12,11, 9,11,11,11,11,
604.7221 +	13,12,12,13, 9,11,10,12,13,13,10,13,10, 7,10,10,
604.7222 +	11,11,14,11,14,11,10,12,11,11,11,14,14,15,14,10,
604.7223 +	11,12,13,14,15,11,14,11, 7,10, 9,10,11,12, 9,12,
604.7224 +	10,10,11,11,10,10,12,12,13,12, 9,12,10,12,13,12,
604.7225 +	10,12,10,
604.7226 +};
604.7227 +
604.7228 +static const static_codebook _44p6_p6_0 = {
604.7229 +	5, 243,
604.7230 +	(long *)_vq_lengthlist__44p6_p6_0,
604.7231 +	1, -527106048, 1620377600, 2, 0,
604.7232 +	(long *)_vq_quantlist__44p6_p6_0,
604.7233 +	0
604.7234 +};
604.7235 +
604.7236 +static const long _vq_quantlist__44p6_p6_1[] = {
604.7237 +	1,
604.7238 +	0,
604.7239 +	2,
604.7240 +};
604.7241 +
604.7242 +static const long _vq_lengthlist__44p6_p6_1[] = {
604.7243 +	 2, 6, 6, 6, 7, 8, 6, 8, 7, 6, 7, 7, 7, 7, 8, 7,
604.7244 +	 8, 8, 6, 7, 7, 7, 8, 8, 7, 8, 7, 6, 8, 8, 8, 9,
604.7245 +	 9, 8, 9, 9, 8, 9, 9, 9, 9,10, 9,10,10, 8, 9, 9,
604.7246 +	 9,10,10, 9,10, 9, 6, 8, 8, 8, 9, 9, 8, 9, 9, 8,
604.7247 +	 9, 9, 9, 9,10, 9,10,10, 8, 9, 9, 9,10, 9, 9,10,
604.7248 +	 9, 6, 8, 8, 8, 9, 9, 8, 9, 9, 8, 9, 9, 9, 9,10,
604.7249 +	 9, 9,10, 8, 9, 9, 9,10, 9, 9,10, 9, 7, 8, 8, 8,
604.7250 +	 9, 9, 8, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 8, 9,
604.7251 +	 9, 9,10, 9, 9, 9, 9, 7, 9, 9, 9, 9,10, 9,10, 9,
604.7252 +	 9, 9, 9, 9, 9,10,10,10,10, 9, 9, 9,10,10,10, 9,
604.7253 +	10, 9, 6, 8, 8, 8, 9, 9, 8, 9, 9, 8, 9, 9, 9, 9,
604.7254 +	10, 9,10,10, 8, 9, 9, 9,10, 9, 9,10, 9, 7, 9, 9,
604.7255 +	 9, 9,10, 9,10, 9, 9, 9, 9, 9, 9,10,10,10,10, 9,
604.7256 +	 9, 9,10,10,10, 9,10, 9, 7, 8, 8, 8, 9, 9, 8, 9,
604.7257 +	 9, 8, 9, 9, 9, 9,10, 9, 9,10, 8, 9, 8, 9, 9, 9,
604.7258 +	 9,10, 9,
604.7259 +};
604.7260 +
604.7261 +static const static_codebook _44p6_p6_1 = {
604.7262 +	5, 243,
604.7263 +	(long *)_vq_lengthlist__44p6_p6_1,
604.7264 +	1, -530841600, 1616642048, 2, 0,
604.7265 +	(long *)_vq_quantlist__44p6_p6_1,
604.7266 +	0
604.7267 +};
604.7268 +
604.7269 +static const long _vq_quantlist__44p6_p7_0[] = {
604.7270 +	1,
604.7271 +	0,
604.7272 +	2,
604.7273 +};
604.7274 +
604.7275 +static const long _vq_lengthlist__44p6_p7_0[] = {
604.7276 +	 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.7277 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7278 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7279 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7280 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7281 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7282 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7283 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7284 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7285 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7286 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7287 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7288 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7289 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7290 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.7291 +	 9, 9, 9,
604.7292 +};
604.7293 +
604.7294 +static const static_codebook _44p6_p7_0 = {
604.7295 +	5, 243,
604.7296 +	(long *)_vq_lengthlist__44p6_p7_0,
604.7297 +	1, -513979392, 1633504256, 2, 0,
604.7298 +	(long *)_vq_quantlist__44p6_p7_0,
604.7299 +	0
604.7300 +};
604.7301 +
604.7302 +static const long _vq_quantlist__44p6_p7_1[] = {
604.7303 +	1,
604.7304 +	0,
604.7305 +	2,
604.7306 +};
604.7307 +
604.7308 +static const long _vq_lengthlist__44p6_p7_1[] = {
604.7309 +	 1, 4, 5, 5,10,10, 5,10,10, 5,10,10,10,10,10,10,
604.7310 +	10,10, 5,10,10,10,10,10,10,10,10, 7,10,10,10,10,
604.7311 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.7312 +	10,10,10,10,10,10, 6,10,10,10,10,10,10,10,10,10,
604.7313 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.7314 +	10, 6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.7315 +	10,10,10,10,10,10,10,10,10,10,10,10, 9,10,10,10,
604.7316 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.7317 +	10,10,10,10,10,10,10, 9,10,10,10,10,10,10,10,10,
604.7318 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.7319 +	10,10, 6,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.7320 +	10,10,10,10,10,10,10,10,10,10,10,10,10, 9,10,10,
604.7321 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.7322 +	10,10,10,10,10,10,10,10, 9,10,10,10,10,10,10,10,
604.7323 +	10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,
604.7324 +	11,11,11,
604.7325 +};
604.7326 +
604.7327 +static const static_codebook _44p6_p7_1 = {
604.7328 +	5, 243,
604.7329 +	(long *)_vq_lengthlist__44p6_p7_1,
604.7330 +	1, -516716544, 1630767104, 2, 0,
604.7331 +	(long *)_vq_quantlist__44p6_p7_1,
604.7332 +	0
604.7333 +};
604.7334 +
604.7335 +static const long _vq_quantlist__44p6_p7_2[] = {
604.7336 +	12,
604.7337 +	11,
604.7338 +	13,
604.7339 +	10,
604.7340 +	14,
604.7341 +	9,
604.7342 +	15,
604.7343 +	8,
604.7344 +	16,
604.7345 +	7,
604.7346 +	17,
604.7347 +	6,
604.7348 +	18,
604.7349 +	5,
604.7350 +	19,
604.7351 +	4,
604.7352 +	20,
604.7353 +	3,
604.7354 +	21,
604.7355 +	2,
604.7356 +	22,
604.7357 +	1,
604.7358 +	23,
604.7359 +	0,
604.7360 +	24,
604.7361 +};
604.7362 +
604.7363 +static const long _vq_lengthlist__44p6_p7_2[] = {
604.7364 +	 1, 2, 3, 4, 5, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
604.7365 +	12,13,13,14,14,15,15,15,15,
604.7366 +};
604.7367 +
604.7368 +static const static_codebook _44p6_p7_2 = {
604.7369 +	1, 25,
604.7370 +	(long *)_vq_lengthlist__44p6_p7_2,
604.7371 +	1, -518864896, 1620639744, 5, 0,
604.7372 +	(long *)_vq_quantlist__44p6_p7_2,
604.7373 +	0
604.7374 +};
604.7375 +
604.7376 +static const long _vq_quantlist__44p6_p7_3[] = {
604.7377 +	12,
604.7378 +	11,
604.7379 +	13,
604.7380 +	10,
604.7381 +	14,
604.7382 +	9,
604.7383 +	15,
604.7384 +	8,
604.7385 +	16,
604.7386 +	7,
604.7387 +	17,
604.7388 +	6,
604.7389 +	18,
604.7390 +	5,
604.7391 +	19,
604.7392 +	4,
604.7393 +	20,
604.7394 +	3,
604.7395 +	21,
604.7396 +	2,
604.7397 +	22,
604.7398 +	1,
604.7399 +	23,
604.7400 +	0,
604.7401 +	24,
604.7402 +};
604.7403 +
604.7404 +static const long _vq_lengthlist__44p6_p7_3[] = {
604.7405 +	 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.7406 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.7407 +};
604.7408 +
604.7409 +static const static_codebook _44p6_p7_3 = {
604.7410 +	1, 25,
604.7411 +	(long *)_vq_lengthlist__44p6_p7_3,
604.7412 +	1, -529006592, 1611661312, 5, 0,
604.7413 +	(long *)_vq_quantlist__44p6_p7_3,
604.7414 +	0
604.7415 +};
604.7416 +
604.7417 +static const long _huff_lengthlist__44p6_short[] = {
604.7418 +	 2, 8,13,15,16,18,21,22, 5, 4, 6, 8,10,12,17,21,
604.7419 +	 9, 5, 5, 6, 8,11,15,19,11, 6, 5, 5, 6, 7,12,14,
604.7420 +	14, 8, 7, 5, 4, 4, 9,11,16,11, 9, 7, 4, 3, 7,10,
604.7421 +	22,15,14,12, 8, 7, 9,11,21,16,15,12, 9, 5, 6, 8,
604.7422 +};
604.7423 +
604.7424 +static const static_codebook _huff_book__44p6_short = {
604.7425 +	2, 64,
604.7426 +	(long *)_huff_lengthlist__44p6_short,
604.7427 +	0, 0, 0, 0, 0,
604.7428 +	NULL,
604.7429 +	0
604.7430 +};
604.7431 +
604.7432 +static const long _vq_quantlist__44p7_l0_0[] = {
604.7433 +	6,
604.7434 +	5,
604.7435 +	7,
604.7436 +	4,
604.7437 +	8,
604.7438 +	3,
604.7439 +	9,
604.7440 +	2,
604.7441 +	10,
604.7442 +	1,
604.7443 +	11,
604.7444 +	0,
604.7445 +	12,
604.7446 +};
604.7447 +
604.7448 +static const long _vq_lengthlist__44p7_l0_0[] = {
604.7449 +	 2, 4, 4, 7, 7, 8, 8,10,10,11,11,12,12, 4, 5, 5,
604.7450 +	 7, 7, 9, 9,11, 9,12,11,12,12, 4, 5, 5, 7, 7, 9,
604.7451 +	 9, 9,10,10,11,12,12, 7, 7, 7, 7, 8, 9, 8,11, 5,
604.7452 +	12, 6,12,10, 7, 7, 7, 8, 7, 8, 9, 5,11, 6,12,10,
604.7453 +	12, 8, 9, 9, 9, 9,10,10,11, 7,11, 7,12, 9, 8, 9,
604.7454 +	 8, 9, 9,10,10, 7,11, 7,11, 9,11,10,10,10,10,10,
604.7455 +	10,10,11,10,11, 8,11, 9,10,10,10,10,10,10,10,10,
604.7456 +	11, 8,10, 9,11,10,11,11,11,11,11,10,11,10,12,10,
604.7457 +	12,11,10,11,11,11,11,10,11,10,11,10,12,11,12,11,
604.7458 +	12,12,12,12,12,12,12,12,12,12,13,12,11,12,11,12,
604.7459 +	12,12,12,12,11,12,11,12,13,
604.7460 +};
604.7461 +
604.7462 +static const static_codebook _44p7_l0_0 = {
604.7463 +	2, 169,
604.7464 +	(long *)_vq_lengthlist__44p7_l0_0,
604.7465 +	1, -526516224, 1616117760, 4, 0,
604.7466 +	(long *)_vq_quantlist__44p7_l0_0,
604.7467 +	0
604.7468 +};
604.7469 +
604.7470 +static const long _vq_quantlist__44p7_l0_1[] = {
604.7471 +	2,
604.7472 +	1,
604.7473 +	3,
604.7474 +	0,
604.7475 +	4,
604.7476 +};
604.7477 +
604.7478 +static const long _vq_lengthlist__44p7_l0_1[] = {
604.7479 +	 4, 4, 4, 5, 5, 4, 4, 5, 5, 5, 4, 5, 4, 5, 5, 5,
604.7480 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.7481 +};
604.7482 +
604.7483 +static const static_codebook _44p7_l0_1 = {
604.7484 +	2, 25,
604.7485 +	(long *)_vq_lengthlist__44p7_l0_1,
604.7486 +	1, -533725184, 1611661312, 3, 0,
604.7487 +	(long *)_vq_quantlist__44p7_l0_1,
604.7488 +	0
604.7489 +};
604.7490 +
604.7491 +static const long _vq_quantlist__44p7_l1_0[] = {
604.7492 +	54,
604.7493 +	29,
604.7494 +	79,
604.7495 +	0,
604.7496 +	108,
604.7497 +};
604.7498 +
604.7499 +static const long _vq_lengthlist__44p7_l1_0[] = {
604.7500 +	 1, 2, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
604.7501 +	 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.7502 +};
604.7503 +
604.7504 +static const static_codebook _44p7_l1_0 = {
604.7505 +	2, 25,
604.7506 +	(long *)_vq_lengthlist__44p7_l1_0,
604.7507 +	1, -514516992, 1620639744, 7, 0,
604.7508 +	(long *)_vq_quantlist__44p7_l1_0,
604.7509 +	0
604.7510 +};
604.7511 +
604.7512 +static const long _huff_lengthlist__44p7_lfe[] = {
604.7513 +	 2, 3, 1, 3,
604.7514 +};
604.7515 +
604.7516 +static const static_codebook _huff_book__44p7_lfe = {
604.7517 +	2, 4,
604.7518 +	(long *)_huff_lengthlist__44p7_lfe,
604.7519 +	0, 0, 0, 0, 0,
604.7520 +	NULL,
604.7521 +	0
604.7522 +};
604.7523 +
604.7524 +static const long _huff_lengthlist__44p7_long[] = {
604.7525 +	 2, 7,14,16,17,17,18,20, 6, 3, 5, 8,10,11,13,15,
604.7526 +	13, 5, 3, 5, 8, 9,11,12,15, 7, 4, 3, 5, 7, 9,11,
604.7527 +	16,10, 7, 5, 6, 7, 9,10,17,11, 8, 7, 7, 6, 8, 8,
604.7528 +	19,13,11, 9, 9, 8, 8, 9,20,14,13,11,10, 8, 9, 9,
604.7529 +};
604.7530 +
604.7531 +static const static_codebook _huff_book__44p7_long = {
604.7532 +	2, 64,
604.7533 +	(long *)_huff_lengthlist__44p7_long,
604.7534 +	0, 0, 0, 0, 0,
604.7535 +	NULL,
604.7536 +	0
604.7537 +};
604.7538 +
604.7539 +static const long _vq_quantlist__44p7_p1_0[] = {
604.7540 +	1,
604.7541 +	0,
604.7542 +	2,
604.7543 +};
604.7544 +
604.7545 +static const long _vq_lengthlist__44p7_p1_0[] = {
604.7546 +	 2, 5, 5, 4, 7, 7, 4, 7, 7, 5, 7, 7, 7, 8, 9, 7,
604.7547 +	 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 8, 6, 7, 8, 8, 9,
604.7548 +	10, 8, 9,10, 8, 9,10,10,10,12,10,11,11, 8,10,10,
604.7549 +	10,11,12,10,11,11, 6, 8, 7, 8,10, 9, 8,10, 9, 8,
604.7550 +	10,10,10,11,11,10,12,11, 8,10, 9,10,11,11,10,12,
604.7551 +	10, 5, 8, 8, 8,10,10, 8,10,10, 7, 9,10, 9,10,11,
604.7552 +	 9,11,11, 8,10,10,10,11,12,10,12,11, 7, 9, 9, 9,
604.7553 +	10,11, 9,11,11, 9, 9,11,10,11,12,11,11,12, 9,11,
604.7554 +	11,11,12,12,11,12,12, 7, 9, 9,10,11,11,10,12,11,
604.7555 +	 9,11,10,11,11,12,11,13,12,10,11,11,12,13,13,11,
604.7556 +	13,11, 5, 8, 8, 8,10,10, 8,10,10, 8,10,10,10,11,
604.7557 +	12,10,12,11, 7,10, 9, 9,11,11, 9,11,10, 7, 9, 9,
604.7558 +	10,11,12,10,11,11,10,11,11,11,11,13,12,13,13, 9,
604.7559 +	10,11,11,12,13,11,12,11, 7, 9, 9, 9,11,11, 9,11,
604.7560 +	10, 9,11,11,11,12,12,11,12,12, 9,11, 9,11,12,11,
604.7561 +	10,12,11,
604.7562 +};
604.7563 +
604.7564 +static const static_codebook _44p7_p1_0 = {
604.7565 +	5, 243,
604.7566 +	(long *)_vq_lengthlist__44p7_p1_0,
604.7567 +	1, -535822336, 1611661312, 2, 0,
604.7568 +	(long *)_vq_quantlist__44p7_p1_0,
604.7569 +	0
604.7570 +};
604.7571 +
604.7572 +static const long _vq_quantlist__44p7_p2_0[] = {
604.7573 +	2,
604.7574 +	1,
604.7575 +	3,
604.7576 +	0,
604.7577 +	4,
604.7578 +};
604.7579 +
604.7580 +static const long _vq_lengthlist__44p7_p2_0[] = {
604.7581 +	 4, 6, 6, 9, 9, 6, 8, 8,10,10, 6, 8, 8,10,10, 8,
604.7582 +	10,10,12,13, 8,10,10,13,12, 6, 8, 8,10,10, 8, 8,
604.7583 +	 9,10,11, 8, 9, 9,11,11,10,10,11,12,13,10,11,11,
604.7584 +	13,13, 6, 8, 8,10,10, 8, 9, 9,11,11, 8, 9, 8,11,
604.7585 +	10,10,11,11,13,13,10,11,10,13,12, 9,10,10,12,12,
604.7586 +	10,10,11,12,13,10,11,11,13,13,12,12,13,12,15,13,
604.7587 +	13,13,15,14, 9,10,10,12,12,10,11,11,13,13,10,11,
604.7588 +	10,13,12,12,13,13,14,15,12,13,12,15,12, 6, 8, 8,
604.7589 +	10,11, 8, 9,10,11,12, 8, 9, 9,11,11,10,11,12,13,
604.7590 +	14,10,11,11,13,13, 8, 9, 9,11,12, 9,10,11,12,13,
604.7591 +	 9,10,10,12,13,11,12,13,13,15,11,12,12,14,14, 8,
604.7592 +	 9, 9,11,12, 9,10,11,12,13, 9,10,10,13,12,11,12,
604.7593 +	13,14,15,11,12,12,14,13,10,11,12,13,14,11,12,13,
604.7594 +	13,15,12,13,13,14,14,13,13,14,14,16,14,15,14,16,
604.7595 +	15,10,12,11,14,13,12,12,13,14,14,11,12,12,14,14,
604.7596 +	14,14,15,15,16,13,14,14,16,14, 6, 8, 8,11,10, 8,
604.7597 +	 9, 9,11,11, 8,10, 9,12,11,10,11,11,13,13,10,12,
604.7598 +	11,14,13, 8, 9, 9,12,11, 9,10,10,12,13, 9,11,10,
604.7599 +	13,12,11,12,12,14,14,11,13,12,15,14, 8, 9, 9,12,
604.7600 +	11, 9,10,10,13,12, 9,11,10,13,12,11,12,12,14,14,
604.7601 +	11,13,12,15,13,10,11,12,13,14,11,12,13,13,14,12,
604.7602 +	13,12,14,14,13,13,14,14,16,14,15,14,16,16,10,12,
604.7603 +	11,14,13,12,13,13,14,14,11,13,12,15,13,14,14,15,
604.7604 +	16,16,13,14,13,16,14, 9,10,11,12,13,11,11,12,13,
604.7605 +	14,11,11,12,13,14,13,13,14,14,16,13,14,14,15,15,
604.7606 +	11,11,12,13,14,12,12,13,13,15,12,13,13,14,15,14,
604.7607 +	14,15,15,17,14,14,15,16,16,11,12,12,13,14,12,12,
604.7608 +	13,14,15,12,13,12,14,15,14,14,15,15,17,14,15,14,
604.7609 +	16,16,13,14,14,15,16,14,14,15,15,17,14,15,15,16,
604.7610 +	16,15,16,17,16,18,16,17,16,17,17,13,14,14,16,15,
604.7611 +	14,15,15,16,16,14,15,14,16,15,16,16,17,17,18,16,
604.7612 +	16,16,17,16, 9,11,10,13,12,11,12,11,14,13,11,12,
604.7613 +	11,14,13,13,14,14,16,15,13,14,13,16,14,11,12,12,
604.7614 +	14,13,12,12,13,14,14,12,13,13,15,14,14,14,15,16,
604.7615 +	16,14,15,14,17,15,11,12,11,14,13,12,13,13,15,14,
604.7616 +	12,13,12,15,13,14,15,14,16,16,14,15,14,17,15,13,
604.7617 +	14,14,15,16,14,14,15,16,16,14,15,15,16,16,15,16,
604.7618 +	16,16,17,16,16,16,17,17,13,14,14,16,15,14,15,15,
604.7619 +	17,16,14,15,14,17,15,16,17,17,17,17,16,16,16,18,
604.7620 +	16, 6, 8, 8,11,11, 8, 9, 9,11,12, 8, 9, 9,12,11,
604.7621 +	10,11,11,13,14,10,11,11,14,13, 8, 9, 9,11,12, 9,
604.7622 +	10,10,12,13, 9,10,10,13,12,11,11,12,13,15,11,12,
604.7623 +	12,15,14, 8, 9, 9,12,11, 9,10,11,12,13, 9,11,10,
604.7624 +	13,12,11,12,12,14,15,11,13,12,15,14,10,11,11,13,
604.7625 +	14,11,12,12,13,14,11,12,12,14,14,13,13,14,14,16,
604.7626 +	13,14,14,16,15,11,12,11,14,13,12,13,13,14,14,11,
604.7627 +	13,12,14,13,14,14,15,16,16,13,14,14,16,14, 8, 9,
604.7628 +	 9,11,12, 9,10,10,12,13, 9,10,10,13,12,11,12,12,
604.7629 +	14,15,11,12,12,14,14, 9, 9,10,11,13,10,10,12,12,
604.7630 +	14,10,10,11,13,13,12,12,13,14,16,12,12,13,15,15,
604.7631 +	 9,10,10,13,12,10,11,11,13,14,10,12,11,14,13,12,
604.7632 +	13,13,15,15,12,13,13,15,15,11,11,12,13,15,12,12,
604.7633 +	13,13,15,12,13,13,14,15,14,14,15,15,17,14,15,15,
604.7634 +	16,16,11,13,12,15,14,13,13,13,15,15,12,14,13,15,
604.7635 +	14,15,15,15,16,16,14,15,15,17,15, 7, 9, 9,12,11,
604.7636 +	 9,10,10,12,12, 9,11,10,13,12,11,12,12,14,14,11,
604.7637 +	13,12,15,14, 9,10,10,12,12,10,10,11,12,13,10,11,
604.7638 +	11,14,13,12,12,13,14,15,12,13,13,15,14, 9,10,10,
604.7639 +	12,12,10,11,11,13,13,10,11,10,14,12,12,13,13,15,
604.7640 +	15,12,13,12,15,13,11,12,12,14,14,12,12,13,14,15,
604.7641 +	12,13,13,15,15,14,13,14,13,16,14,15,15,16,16,11,
604.7642 +	12,12,14,14,13,13,14,15,15,12,13,12,15,14,15,15,
604.7643 +	15,16,16,14,15,14,17,14,10,11,12,13,14,11,12,13,
604.7644 +	14,15,11,12,12,14,15,13,14,15,15,17,14,14,14,16,
604.7645 +	16,11,12,13,12,15,12,12,14,13,16,13,13,14,13,16,
604.7646 +	14,14,15,14,17,15,15,15,15,17,11,13,12,15,15,13,
604.7647 +	13,14,15,16,12,14,13,16,15,15,15,15,17,17,15,15,
604.7648 +	15,17,16,14,14,15,14,16,14,14,16,14,17,15,15,15,
604.7649 +	14,17,16,16,17,15,18,17,17,17,16,18,14,15,15,17,
604.7650 +	16,15,16,16,17,17,15,16,15,17,16,17,17,17,18,18,
604.7651 +	16,17,16,18,17,10,11,11,14,13,11,12,12,14,14,11,
604.7652 +	13,12,15,14,14,14,14,16,16,14,15,14,16,15,11,12,
604.7653 +	12,15,13,12,13,13,15,14,13,14,13,16,14,14,15,15,
604.7654 +	16,16,15,16,15,17,16,11,13,12,15,14,13,13,14,15,
604.7655 +	15,12,14,13,16,14,15,15,15,17,17,14,16,15,17,16,
604.7656 +	14,14,14,16,15,14,15,15,16,16,15,16,15,17,16,16,
604.7657 +	16,16,16,17,16,17,17,18,17,14,15,15,16,16,15,15,
604.7658 +	16,17,16,14,15,15,17,16,17,17,17,18,18,16,17,16,
604.7659 +	18,16, 6, 8, 8,11,11, 8, 9, 9,11,12, 8, 9, 9,12,
604.7660 +	11,10,11,12,13,14,10,11,11,14,13, 8, 9, 9,11,12,
604.7661 +	 9,10,11,12,13, 9,11,10,13,12,11,12,13,14,15,11,
604.7662 +	12,12,15,14, 8, 9, 9,12,11, 9,10,10,12,13, 9,10,
604.7663 +	10,13,12,11,12,12,14,15,11,12,12,14,13,11,11,12,
604.7664 +	13,14,11,12,13,13,15,12,13,13,14,14,13,14,14,14,
604.7665 +	16,14,15,14,16,16,10,11,11,14,13,11,12,12,14,14,
604.7666 +	11,12,12,14,13,13,14,14,15,16,13,14,13,16,14, 7,
604.7667 +	 9, 9,11,11, 9,10,11,12,13, 9,10,10,12,12,11,12,
604.7668 +	13,14,15,11,12,12,14,14, 9,10,10,12,12,10,10,11,
604.7669 +	12,13,10,11,11,13,13,12,12,13,13,15,12,13,13,15,
604.7670 +	15, 9,10,10,12,12,10,11,11,13,13,10,11,10,13,12,
604.7671 +	12,13,13,14,15,12,13,12,15,13,11,12,12,14,14,12,
604.7672 +	12,13,14,15,13,14,13,15,15,14,13,15,13,16,15,15,
604.7673 +	15,16,16,11,12,12,14,14,12,13,13,14,15,12,13,12,
604.7674 +	15,14,14,15,15,16,17,13,14,13,16,13, 8, 9, 9,12,
604.7675 +	11, 9,10,10,12,13, 9,10,10,13,12,11,12,12,14,15,
604.7676 +	11,12,12,15,14, 9,10,10,12,13,10,11,12,13,14,10,
604.7677 +	11,11,14,13,12,13,13,15,15,12,13,13,15,15, 9,10,
604.7678 +	 9,13,11,10,11,10,13,13,10,12,10,14,12,12,13,12,
604.7679 +	15,15,12,13,12,15,14,11,12,13,14,15,12,13,14,14,
604.7680 +	15,13,13,13,15,15,14,15,15,15,17,15,15,15,16,16,
604.7681 +	11,12,11,15,13,12,13,13,15,14,12,13,12,16,13,14,
604.7682 +	15,15,16,16,14,15,14,17,14,10,11,11,13,14,11,12,
604.7683 +	13,14,15,11,12,12,14,14,14,14,15,15,17,14,14,14,
604.7684 +	15,16,11,12,13,14,15,12,13,14,14,16,13,14,13,15,
604.7685 +	15,14,15,16,15,17,15,15,15,17,17,11,12,12,13,15,
604.7686 +	13,13,14,14,16,12,13,13,14,15,15,15,15,16,17,14,
604.7687 +	15,15,16,16,14,15,15,16,16,14,15,15,16,17,15,15,
604.7688 +	16,16,17,16,16,17,16,18,17,17,17,18,18,14,14,15,
604.7689 +	15,16,15,15,15,16,17,14,15,15,16,16,16,17,17,17,
604.7690 +	18,16,16,16,17,16,10,11,11,14,13,11,13,12,15,14,
604.7691 +	11,13,12,15,14,14,15,14,16,16,13,15,14,17,15,11,
604.7692 +	12,13,15,15,12,13,14,15,16,13,14,13,16,15,15,15,
604.7693 +	15,16,17,15,15,15,17,16,11,13,11,15,12,13,14,13,
604.7694 +	16,13,12,14,12,16,13,15,15,15,17,15,14,16,14,17,
604.7695 +	14,14,15,15,16,17,15,15,16,16,17,15,16,15,17,17,
604.7696 +	16,16,17,17,18,16,17,17,18,18,14,15,14,17,13,15,
604.7697 +	16,15,17,15,15,16,15,17,14,16,17,16,18,16,16,17,
604.7698 +	16,18,15, 9,11,11,13,13,10,12,12,14,14,11,12,12,
604.7699 +	14,14,13,14,14,15,16,13,14,14,16,16,10,11,12,14,
604.7700 +	14,11,12,13,14,15,11,13,13,15,15,13,14,14,15,16,
604.7701 +	14,15,15,16,16,11,12,12,14,14,12,13,13,15,15,12,
604.7702 +	13,12,15,14,14,15,15,16,16,14,15,14,17,16,12,13,
604.7703 +	13,15,16,13,13,14,15,16,13,14,14,16,16,14,15,16,
604.7704 +	16,17,15,16,16,17,17,13,14,14,16,15,14,15,15,17,
604.7705 +	16,14,15,14,17,15,16,16,17,17,17,16,16,16,18,16,
604.7706 +	10,11,12,14,14,11,12,13,14,15,11,13,12,15,15,13,
604.7707 +	14,15,16,16,14,15,15,17,16,11,11,13,14,15,12,12,
604.7708 +	14,14,16,12,13,14,15,15,14,14,15,16,17,15,15,15,
604.7709 +	17,17,12,13,12,15,15,13,14,14,16,15,13,14,13,16,
604.7710 +	15,15,16,15,17,17,15,16,15,17,16,13,12,15,14,16,
604.7711 +	14,13,15,14,17,14,13,15,15,17,15,14,17,15,18,16,
604.7712 +	15,17,17,18,14,15,15,17,16,15,16,16,17,17,15,16,
604.7713 +	15,17,16,16,17,17,18,18,16,17,16,18,17,10,11,11,
604.7714 +	14,14,11,12,12,14,15,11,13,12,15,14,13,14,14,16,
604.7715 +	16,14,15,14,16,16,11,12,12,14,14,12,12,13,15,15,
604.7716 +	12,13,13,15,15,14,14,15,16,16,14,15,15,17,16,11,
604.7717 +	12,12,15,15,13,13,13,15,15,12,13,13,15,15,15,15,
604.7718 +	15,17,17,14,15,15,17,16,13,14,13,16,15,14,14,14,
604.7719 +	16,16,14,15,14,17,16,15,15,16,16,17,16,17,16,18,
604.7720 +	17,14,15,15,16,16,15,15,15,17,17,14,15,15,17,16,
604.7721 +	16,17,17,18,18,16,17,16,18,16,12,13,13,15,15,13,
604.7722 +	14,14,16,16,13,14,14,16,16,14,15,16,16,18,15,16,
604.7723 +	16,17,17,13,13,14,14,16,14,14,15,15,17,14,14,15,
604.7724 +	15,17,15,15,17,15,18,16,16,17,17,18,13,14,14,16,
604.7725 +	16,14,15,15,16,17,14,15,15,17,16,16,17,16,17,18,
604.7726 +	16,17,16,18,17,15,14,16,13,18,16,15,17,14,18,16,
604.7727 +	15,17,14,18,17,16,18,15,19,17,17,18,16,19,15,16,
604.7728 +	16,17,17,16,17,17,18,18,16,17,16,18,17,18,18,18,
604.7729 +	19,18,17,18,17,19,17,11,12,12,15,15,13,13,14,15,
604.7730 +	16,13,14,13,16,15,15,15,15,16,17,15,16,15,17,16,
604.7731 +	12,13,13,15,15,13,13,14,15,16,14,15,14,16,15,15,
604.7732 +	15,16,16,17,16,16,16,18,17,12,13,13,15,15,14,14,
604.7733 +	15,16,16,13,14,13,16,15,16,16,16,17,17,15,16,15,
604.7734 +	18,16,15,15,15,17,15,14,15,15,16,16,16,17,16,17,
604.7735 +	16,16,16,17,16,17,17,18,17,19,18,15,15,16,17,17,
604.7736 +	16,16,16,17,17,15,16,15,17,16,17,18,18,18,18,16,
604.7737 +	17,16,18,16, 9,11,11,13,13,11,12,12,14,14,10,12,
604.7738 +	12,14,14,13,14,14,15,16,13,14,14,16,15,11,12,12,
604.7739 +	14,14,12,12,13,14,15,12,13,13,15,15,14,14,15,16,
604.7740 +	17,14,15,15,16,16,10,12,11,14,14,11,13,13,15,15,
604.7741 +	11,13,12,15,14,14,14,15,16,16,13,14,14,16,15,13,
604.7742 +	14,14,15,16,14,14,15,15,17,14,15,15,16,17,16,16,
604.7743 +	16,16,18,16,16,17,17,17,12,13,13,16,15,13,14,14,
604.7744 +	16,16,12,14,13,16,15,15,16,16,17,17,14,16,15,17,
604.7745 +	16,10,11,11,14,14,11,12,13,14,15,11,12,12,15,14,
604.7746 +	14,14,15,16,16,13,14,14,16,16,11,12,12,14,15,12,
604.7747 +	13,14,15,15,13,13,13,15,15,14,15,15,16,17,15,15,
604.7748 +	15,16,17,11,12,12,14,14,12,13,13,15,15,12,13,12,
604.7749 +	15,15,14,15,15,16,17,14,15,14,16,16,14,14,15,16,
604.7750 +	16,14,15,15,16,17,15,16,15,17,17,16,16,17,16,18,
604.7751 +	16,17,17,18,18,13,13,14,15,16,14,14,15,16,17,14,
604.7752 +	14,14,16,15,16,16,17,17,18,15,16,15,17,16,10,12,
604.7753 +	11,14,14,11,13,13,15,15,11,13,12,15,15,14,15,15,
604.7754 +	16,16,13,15,14,16,16,12,12,13,15,15,13,13,14,15,
604.7755 +	16,13,14,14,16,15,15,15,16,16,17,15,15,15,17,17,
604.7756 +	11,13,11,15,14,12,14,13,16,15,12,14,12,16,14,15,
604.7757 +	15,15,17,17,14,15,14,17,15,14,15,15,16,17,15,15,
604.7758 +	16,16,17,15,16,16,17,17,16,16,17,17,18,16,17,17,
604.7759 +	18,18,13,14,12,16,14,14,15,13,17,15,14,15,13,17,
604.7760 +	14,16,17,15,18,17,15,17,14,18,15,11,12,12,14,15,
604.7761 +	13,13,14,15,16,13,14,13,16,15,15,15,16,16,17,15,
604.7762 +	15,15,16,16,12,13,13,15,15,13,13,14,15,16,14,15,
604.7763 +	14,16,16,15,15,16,16,18,16,16,16,18,17,12,13,13,
604.7764 +	15,15,14,14,15,15,16,13,14,13,15,15,16,16,16,17,
604.7765 +	18,15,16,15,17,16,15,16,15,17,16,15,15,16,16,17,
604.7766 +	16,17,16,17,17,16,16,17,16,18,17,18,18,18,18,14,
604.7767 +	15,15,15,17,16,15,17,16,17,14,15,15,16,16,17,17,
604.7768 +	18,18,19,16,16,16,17,16,12,13,13,15,15,13,14,14,
604.7769 +	16,16,13,14,14,16,16,15,16,16,17,17,15,16,15,18,
604.7770 +	16,13,14,14,16,16,14,15,15,16,17,14,15,15,17,16,
604.7771 +	16,16,17,17,18,16,17,16,18,18,13,14,13,16,14,14,
604.7772 +	15,14,17,15,14,15,14,17,14,16,17,16,18,17,15,17,
604.7773 +	15,18,15,15,16,16,17,18,16,16,17,17,18,16,17,17,
604.7774 +	17,18,17,17,18,18,19,17,18,18,19,18,15,16,14,17,
604.7775 +	13,16,17,15,18,14,16,17,15,18,14,18,18,17,19,16,
604.7776 +	17,18,16,19,15,
604.7777 +};
604.7778 +
604.7779 +static const static_codebook _44p7_p2_0 = {
604.7780 +	5, 3125,
604.7781 +	(long *)_vq_lengthlist__44p7_p2_0,
604.7782 +	1, -533725184, 1611661312, 3, 0,
604.7783 +	(long *)_vq_quantlist__44p7_p2_0,
604.7784 +	0
604.7785 +};
604.7786 +
604.7787 +static const long _vq_quantlist__44p7_p3_0[] = {
604.7788 +	1,
604.7789 +	0,
604.7790 +	2,
604.7791 +};
604.7792 +
604.7793 +static const long _vq_lengthlist__44p7_p3_0[] = {
604.7794 +	 2, 5, 5, 4, 7, 7, 4, 7, 7, 5, 7, 8, 7, 8,10, 8,
604.7795 +	 9, 9, 5, 7, 7, 8, 9, 9, 7,10, 8, 5, 7, 8, 8, 9,
604.7796 +	10, 8,10,10, 8, 9,10,10,10,12,10,12,12, 8,10,10,
604.7797 +	10,12,12,10,12,11, 5, 8, 7, 8,10,10, 8,10, 9, 8,
604.7798 +	10,10,10,11,12,10,12,12, 8,10, 9,10,12,12,10,12,
604.7799 +	10, 5, 8, 8, 7,10,10, 8,10,10, 7, 9,10, 9,10,12,
604.7800 +	10,12,12, 8,10,10,10,12,12,10,12,11, 7, 9,10, 9,
604.7801 +	11,12,10,12,11, 9, 9,12,11,10,14,12,12,13,10,12,
604.7802 +	11,12,13,13,11,14,12, 7,10, 9,10,11,11,10,12,11,
604.7803 +	 9,11,11,11,11,13,12,14,13,10,12,12,12,14,14,11,
604.7804 +	14,12, 5, 8, 8, 8,10,10, 7,10,10, 8,10,10,10,11,
604.7805 +	12,10,12,12, 7,10, 9,10,12,12, 9,12,10, 7, 9,10,
604.7806 +	10,11,12,10,11,11,10,12,12,11,12,14,12,14,14, 9,
604.7807 +	11,11,12,13,14,11,13,11, 7,10, 9,10,11,12, 9,12,
604.7808 +	11,10,11,12,11,12,14,12,13,13, 9,12, 9,12,13,12,
604.7809 +	11,14,10,
604.7810 +};
604.7811 +
604.7812 +static const static_codebook _44p7_p3_0 = {
604.7813 +	5, 243,
604.7814 +	(long *)_vq_lengthlist__44p7_p3_0,
604.7815 +	1, -533200896, 1614282752, 2, 0,
604.7816 +	(long *)_vq_quantlist__44p7_p3_0,
604.7817 +	0
604.7818 +};
604.7819 +
604.7820 +static const long _vq_quantlist__44p7_p3_1[] = {
604.7821 +	1,
604.7822 +	0,
604.7823 +	2,
604.7824 +};
604.7825 +
604.7826 +static const long _vq_lengthlist__44p7_p3_1[] = {
604.7827 +	 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 8, 7,
604.7828 +	 8, 8, 7, 8, 7, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8,
604.7829 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 8,
604.7830 +	 8, 8, 8, 8, 9, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.7831 +	 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9,
604.7832 +	 8, 7, 8, 8, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8, 8,
604.7833 +	 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 7, 8, 8, 8,
604.7834 +	 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8,
604.7835 +	 8, 9, 9, 9, 8, 9, 9, 7, 8, 8, 8, 8, 8, 8, 8, 8,
604.7836 +	 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8, 8, 9, 9, 8,
604.7837 +	 9, 8, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8,
604.7838 +	 9, 8, 8, 9, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8,
604.7839 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8,
604.7840 +	 8, 8, 8, 9, 9, 8, 9, 8, 7, 8, 8, 8, 8, 8, 8, 9,
604.7841 +	 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 8, 9, 9,
604.7842 +	 8, 9, 8,
604.7843 +};
604.7844 +
604.7845 +static const static_codebook _44p7_p3_1 = {
604.7846 +	5, 243,
604.7847 +	(long *)_vq_lengthlist__44p7_p3_1,
604.7848 +	1, -535822336, 1611661312, 2, 0,
604.7849 +	(long *)_vq_quantlist__44p7_p3_1,
604.7850 +	0
604.7851 +};
604.7852 +
604.7853 +static const long _vq_quantlist__44p7_p4_0[] = {
604.7854 +	1,
604.7855 +	0,
604.7856 +	2,
604.7857 +};
604.7858 +
604.7859 +static const long _vq_lengthlist__44p7_p4_0[] = {
604.7860 +	 1, 5, 5, 5, 7, 8, 5, 8, 7, 5, 7, 8, 7, 8,10, 8,
604.7861 +	10,10, 5, 8, 7, 8,10,10, 7,10, 8, 6, 8, 9, 9,10,
604.7862 +	12, 9,11,11, 9,10,11,11,11,13,11,13,13, 9,11,11,
604.7863 +	11,12,13,11,13,11, 6, 9, 8, 9,11,11, 9,12,10, 9,
604.7864 +	11,11,11,11,13,11,13,13, 9,11,10,11,13,13,11,13,
604.7865 +	11, 6, 9, 9, 8,10,11, 9,12,11, 8,10,11,10,11,13,
604.7866 +	11,13,13, 9,11,11,11,13,12,11,13,11, 8,10,10, 9,
604.7867 +	11,12,10,12,12,10,10,12,11,11,14,12,13,14,10,12,
604.7868 +	12,12,13,13,11,14,11, 8,11,10,11,12,13,11,14,12,
604.7869 +	10,12,11,11,12,14,13,15,14,10,12,12,13,14,15,12,
604.7870 +	14,12, 5, 9, 9, 9,11,12, 8,11,10, 9,11,11,11,11,
604.7871 +	13,11,12,13, 8,11,10,11,13,13,10,13,11, 8,10,11,
604.7872 +	11,12,14,11,13,12,10,12,12,12,12,14,14,15,14,10,
604.7873 +	11,12,13,14,15,11,14,12, 8,10,10,10,12,12, 9,12,
604.7874 +	11,10,12,12,11,11,14,12,13,13,10,12,10,12,14,13,
604.7875 +	11,13,11,
604.7876 +};
604.7877 +
604.7878 +static const static_codebook _44p7_p4_0 = {
604.7879 +	5, 243,
604.7880 +	(long *)_vq_lengthlist__44p7_p4_0,
604.7881 +	1, -531365888, 1616117760, 2, 0,
604.7882 +	(long *)_vq_quantlist__44p7_p4_0,
604.7883 +	0
604.7884 +};
604.7885 +
604.7886 +static const long _vq_quantlist__44p7_p4_1[] = {
604.7887 +	2,
604.7888 +	1,
604.7889 +	3,
604.7890 +	0,
604.7891 +	4,
604.7892 +};
604.7893 +
604.7894 +static const long _vq_lengthlist__44p7_p4_1[] = {
604.7895 +	 7, 8, 8,10,10, 8, 9, 9,10,11, 8, 9, 9,10,10, 9,
604.7896 +	10,10,11,11, 9,10,10,11,11, 8, 9, 9,10,10, 9, 9,
604.7897 +	10,11,11, 9,10,10,11,11,10,10,11,11,11,10,11,11,
604.7898 +	11,11, 8, 9, 9,10,10, 9,10,10,11,11, 9,10, 9,11,
604.7899 +	11,10,11,11,11,11,10,11,10,11,11,10,10,10,11,11,
604.7900 +	10,11,11,11,11,10,11,11,11,11,11,11,11,11,12,11,
604.7901 +	11,11,11,12,10,10,10,11,11,10,11,11,11,11,10,11,
604.7902 +	11,11,11,11,11,11,12,11,11,11,11,12,11, 8, 9,10,
604.7903 +	11,11, 9,10,11,11,11, 9,10,10,11,11,10,11,11,12,
604.7904 +	12,10,11,11,12,12,10,10,10,11,11,10,10,11,11,12,
604.7905 +	10,11,11,12,12,11,11,12,12,12,11,11,12,12,12,10,
604.7906 +	10,10,11,11,10,11,11,12,12,10,11,11,12,11,11,12,
604.7907 +	12,12,12,11,12,11,12,12,11,11,11,11,12,11,11,12,
604.7908 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.7909 +	12,11,11,11,12,12,11,12,12,12,12,11,12,11,12,12,
604.7910 +	12,12,12,12,12,12,12,12,12,12, 8,10, 9,11,11, 9,
604.7911 +	10,10,11,11, 9,10,10,11,11,10,11,11,12,12,10,11,
604.7912 +	11,12,12,10,10,10,11,11,10,11,11,12,12,10,11,11,
604.7913 +	12,12,11,11,12,12,12,11,12,12,12,12,10,10,10,11,
604.7914 +	11,10,11,11,12,12,10,11,10,12,11,11,12,11,12,12,
604.7915 +	11,12,11,12,12,11,11,11,12,12,11,12,12,12,12,11,
604.7916 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,11,
604.7917 +	11,12,11,11,12,12,12,12,11,12,11,12,12,12,12,12,
604.7918 +	12,12,12,12,12,12,12,10,11,11,11,12,11,11,12,12,
604.7919 +	12,11,11,11,12,12,11,12,12,12,12,11,12,12,12,12,
604.7920 +	11,11,12,12,12,11,12,12,12,12,12,12,12,12,12,12,
604.7921 +	12,13,12,13,12,12,12,13,13,11,12,11,12,12,11,12,
604.7922 +	12,12,12,11,12,12,12,12,12,12,12,13,13,12,12,12,
604.7923 +	13,13,12,12,12,12,12,12,12,12,12,13,12,12,13,13,
604.7924 +	13,12,13,13,13,13,12,13,13,13,13,12,12,12,12,12,
604.7925 +	12,12,13,13,13,12,12,12,13,12,12,13,13,13,13,12,
604.7926 +	13,13,13,13,10,11,11,12,11,11,11,11,12,12,11,12,
604.7927 +	11,12,12,11,12,12,12,12,11,12,12,12,12,11,11,11,
604.7928 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,13,
604.7929 +	13,12,12,12,13,13,11,12,11,12,12,12,12,12,12,12,
604.7930 +	11,12,11,12,12,12,12,12,13,13,12,12,12,13,12,12,
604.7931 +	12,12,12,12,12,12,12,13,13,12,12,12,13,13,12,13,
604.7932 +	13,13,13,12,13,13,13,13,12,12,12,12,12,12,12,12,
604.7933 +	13,13,12,13,12,13,12,12,13,13,13,13,13,13,13,13,
604.7934 +	13, 8,10,10,11,11, 9,10,10,11,11, 9,10,10,11,11,
604.7935 +	10,11,11,12,12,10,11,11,12,12, 9,10,10,11,11,10,
604.7936 +	10,11,11,12,10,11,11,12,12,11,11,12,12,12,11,11,
604.7937 +	12,12,12,10,10,10,11,11,10,11,11,12,12,10,11,10,
604.7938 +	12,11,11,12,11,12,12,11,12,11,12,12,11,11,11,12,
604.7939 +	12,11,11,12,12,12,11,12,12,12,12,11,12,12,12,12,
604.7940 +	12,12,12,12,12,11,11,11,12,11,11,12,12,12,12,11,
604.7941 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12, 9,10,
604.7942 +	10,11,11,10,11,11,11,12,10,11,11,12,12,11,11,11,
604.7943 +	12,12,11,11,11,12,12,10,10,11,11,12,11,11,12,12,
604.7944 +	12,11,11,11,12,12,11,11,12,12,12,11,12,12,12,12,
604.7945 +	10,11,11,12,12,11,11,11,12,12,11,12,11,12,12,11,
604.7946 +	12,12,12,12,11,12,12,12,12,11,11,12,12,12,11,12,
604.7947 +	12,12,12,12,12,12,12,12,12,12,12,12,13,12,12,12,
604.7948 +	12,13,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.7949 +	12,12,12,12,12,12,12,12,12,13,12, 9,10,10,11,11,
604.7950 +	10,11,11,12,12,10,11,11,12,11,11,12,11,12,12,11,
604.7951 +	12,11,12,12,10,11,11,12,12,11,11,11,12,12,11,12,
604.7952 +	11,12,12,11,12,12,12,12,12,12,12,12,12,10,11,11,
604.7953 +	12,12,11,12,11,12,12,11,12,11,12,12,12,12,12,13,
604.7954 +	12,12,12,12,12,12,11,12,11,12,12,11,12,12,12,12,
604.7955 +	12,12,12,12,12,12,12,12,12,13,12,12,12,12,13,11,
604.7956 +	12,12,12,12,12,12,12,13,12,11,12,12,12,12,12,12,
604.7957 +	12,13,12,12,12,12,13,12,10,11,11,12,12,11,12,12,
604.7958 +	12,12,11,12,12,12,12,12,12,12,12,13,12,12,12,13,
604.7959 +	13,11,11,12,12,12,12,12,12,12,13,12,12,12,12,12,
604.7960 +	12,12,13,12,13,12,12,13,13,13,11,12,12,12,12,12,
604.7961 +	12,12,13,13,12,12,12,13,12,12,13,12,13,13,12,13,
604.7962 +	12,13,13,12,12,12,12,12,12,12,13,12,13,12,13,13,
604.7963 +	13,13,13,13,13,13,13,13,13,13,13,13,12,12,12,13,
604.7964 +	13,12,13,13,13,13,12,13,13,13,13,13,13,13,13,13,
604.7965 +	13,13,13,13,13,10,11,11,12,12,11,12,12,12,12,11,
604.7966 +	12,12,12,12,12,12,12,13,13,12,12,12,13,13,11,12,
604.7967 +	12,12,12,12,12,12,12,13,12,12,12,13,12,12,12,13,
604.7968 +	13,13,12,13,13,13,13,11,12,12,12,12,12,12,12,13,
604.7969 +	13,12,12,12,13,12,12,13,13,13,13,12,13,12,13,13,
604.7970 +	12,12,12,12,12,12,13,13,13,13,12,13,13,13,13,13,
604.7971 +	13,13,13,13,13,13,13,13,13,12,12,12,13,12,12,13,
604.7972 +	13,13,13,12,13,13,13,13,13,13,13,13,13,13,13,13,
604.7973 +	13,13, 8,10,10,11,11, 9,10,10,11,11, 9,10,10,11,
604.7974 +	11,10,11,11,12,12,10,11,11,12,12,10,10,10,11,11,
604.7975 +	10,11,11,11,12,10,11,11,12,12,11,11,12,12,12,11,
604.7976 +	11,12,12,12, 9,10,10,11,11,10,11,11,12,12,10,11,
604.7977 +	10,12,11,11,12,11,12,12,11,12,11,12,12,11,11,11,
604.7978 +	12,12,11,11,12,12,12,11,12,12,12,12,12,12,12,12,
604.7979 +	12,12,12,12,12,12,11,11,11,12,11,11,12,12,12,12,
604.7980 +	11,12,11,12,12,12,12,12,12,12,12,12,12,12,12, 9,
604.7981 +	10,10,11,11,10,11,11,12,12,10,11,11,12,12,11,11,
604.7982 +	12,12,12,11,12,12,12,12,10,11,11,12,12,11,11,12,
604.7983 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.7984 +	12,10,11,11,12,12,11,11,12,12,12,11,11,11,12,12,
604.7985 +	12,12,12,12,12,11,12,12,12,12,11,12,12,12,12,12,
604.7986 +	12,12,12,12,12,12,12,12,12,12,12,13,12,13,12,12,
604.7987 +	12,13,12,11,12,12,12,12,12,12,12,12,12,11,12,12,
604.7988 +	12,12,12,12,12,13,12,12,12,12,13,12, 9,10,10,11,
604.7989 +	11,10,11,11,12,12,10,11,11,12,12,11,11,11,12,12,
604.7990 +	11,12,11,12,12,10,11,11,12,12,11,11,12,12,12,11,
604.7991 +	11,11,12,12,11,12,12,12,12,11,12,12,12,12,10,11,
604.7992 +	10,12,11,11,11,11,12,12,11,12,11,12,12,11,12,12,
604.7993 +	12,12,11,12,11,12,12,11,12,12,12,12,12,12,12,12,
604.7994 +	12,12,12,12,12,12,12,12,12,12,13,12,12,12,12,13,
604.7995 +	11,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,
604.7996 +	12,12,13,12,12,12,12,13,12,10,11,11,12,12,11,12,
604.7997 +	12,12,12,11,12,12,12,12,12,12,12,13,13,12,12,12,
604.7998 +	13,13,11,12,12,12,12,12,12,12,12,13,12,12,12,13,
604.7999 +	13,12,12,13,13,13,12,13,13,13,13,11,12,12,12,12,
604.8000 +	12,12,12,12,13,12,12,12,12,12,12,13,13,13,13,12,
604.8001 +	13,12,13,13,12,12,12,12,13,12,13,13,13,13,12,13,
604.8002 +	13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,12,
604.8003 +	12,12,12,13,13,13,13,12,13,12,13,13,13,13,13,13,
604.8004 +	13,13,13,13,13,13,11,11,11,12,12,11,12,12,12,12,
604.8005 +	11,12,12,12,12,12,12,12,13,13,12,12,12,13,12,11,
604.8006 +	12,12,12,12,12,12,12,13,13,12,12,12,13,13,12,12,
604.8007 +	13,13,13,12,13,13,13,13,11,12,11,12,12,12,12,12,
604.8008 +	13,12,12,12,12,13,12,12,13,12,13,13,12,13,12,13,
604.8009 +	12,12,12,12,12,13,12,12,13,13,13,12,13,13,13,13,
604.8010 +	13,13,13,13,13,13,13,13,13,13,12,12,12,12,12,12,
604.8011 +	13,13,13,13,12,13,12,13,12,13,13,13,13,13,13,13,
604.8012 +	13,13,13,10,11,11,12,12,10,11,11,12,12,10,11,11,
604.8013 +	12,12,11,12,12,12,12,11,12,12,12,12,11,11,11,12,
604.8014 +	12,11,11,12,12,12,11,12,12,12,12,12,12,12,13,13,
604.8015 +	12,12,12,13,13,11,11,11,12,12,11,12,12,12,12,11,
604.8016 +	12,11,13,12,12,12,12,13,13,12,12,12,13,13,11,12,
604.8017 +	12,12,12,12,12,12,12,13,12,12,12,13,13,12,12,13,
604.8018 +	13,13,12,13,12,13,13,11,12,12,12,12,12,12,12,13,
604.8019 +	12,12,12,12,13,12,12,13,13,13,13,12,13,13,13,13,
604.8020 +	10,11,11,12,12,11,12,12,12,12,11,12,12,12,12,12,
604.8021 +	12,12,13,13,12,12,12,13,13,11,11,12,12,12,11,12,
604.8022 +	12,12,13,12,12,12,13,13,12,12,13,13,13,12,12,13,
604.8023 +	13,13,11,12,12,12,12,12,12,12,13,13,12,12,12,13,
604.8024 +	13,12,13,13,13,13,12,13,12,13,13,12,12,12,12,13,
604.8025 +	12,12,13,12,13,12,12,13,13,13,12,12,13,13,13,12,
604.8026 +	13,13,13,13,12,12,12,12,13,12,12,13,13,13,12,12,
604.8027 +	12,13,13,13,13,13,13,13,12,13,13,13,13,10,11,11,
604.8028 +	12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,13,
604.8029 +	13,12,12,12,13,13,11,12,12,12,12,11,12,12,12,13,
604.8030 +	12,12,12,13,13,12,12,13,13,13,12,13,13,13,13,11,
604.8031 +	12,12,12,12,12,12,12,13,13,12,12,12,13,12,12,13,
604.8032 +	12,13,13,12,13,12,13,13,12,12,12,12,12,12,12,12,
604.8033 +	13,13,12,13,12,13,13,12,13,13,13,13,13,13,13,13,
604.8034 +	13,12,12,12,13,12,12,13,13,13,13,12,13,12,13,13,
604.8035 +	13,13,13,13,13,13,13,13,13,13,11,11,11,12,12,11,
604.8036 +	12,12,12,12,11,12,12,12,12,12,12,12,13,13,12,12,
604.8037 +	12,13,13,11,12,12,12,12,12,12,12,12,13,12,12,12,
604.8038 +	13,13,12,12,13,13,13,12,12,13,13,13,11,12,12,12,
604.8039 +	12,12,12,12,13,13,12,12,12,13,13,12,13,13,13,13,
604.8040 +	12,13,12,13,13,12,12,12,12,12,12,12,13,12,13,12,
604.8041 +	13,13,13,13,12,13,13,12,13,13,13,13,13,13,12,12,
604.8042 +	12,12,12,12,13,13,13,13,12,13,12,13,13,13,13,13,
604.8043 +	13,13,13,13,13,13,13,10,11,11,12,12,11,12,12,12,
604.8044 +	13,11,12,12,13,12,12,12,12,13,13,12,12,12,13,13,
604.8045 +	11,12,12,12,12,12,12,12,13,13,12,13,12,13,13,12,
604.8046 +	12,13,13,13,12,13,13,13,13,11,12,12,12,13,12,12,
604.8047 +	12,13,13,12,12,12,13,12,12,13,13,13,13,12,13,12,
604.8048 +	13,13,12,12,12,12,12,12,12,13,13,13,12,13,13,13,
604.8049 +	13,13,13,13,13,13,13,13,13,13,13,12,12,12,13,12,
604.8050 +	12,13,13,13,13,12,13,12,13,13,13,13,13,13,13,13,
604.8051 +	13,13,13,13,10,11,11,12,12,10,11,11,12,12,10,11,
604.8052 +	11,12,12,11,12,12,12,12,11,12,12,12,12,11,11,11,
604.8053 +	12,12,11,11,12,12,13,11,12,12,12,12,12,12,12,13,
604.8054 +	13,12,12,12,13,13,10,11,11,12,12,11,12,12,12,12,
604.8055 +	11,12,11,12,12,12,12,12,13,13,12,12,12,13,12,11,
604.8056 +	12,12,12,12,12,12,12,12,13,12,12,12,13,13,12,12,
604.8057 +	13,13,13,12,13,13,13,13,11,12,12,12,12,12,12,12,
604.8058 +	13,13,12,12,12,13,12,12,13,13,13,13,12,13,12,13,
604.8059 +	13,10,11,11,12,12,11,12,12,12,12,11,12,12,12,12,
604.8060 +	12,12,12,13,13,12,12,12,13,13,11,12,12,12,12,12,
604.8061 +	12,12,12,13,12,12,12,13,13,12,12,13,13,13,12,12,
604.8062 +	13,13,13,11,12,12,12,12,12,12,12,13,13,11,12,12,
604.8063 +	13,12,12,13,13,13,13,12,13,12,13,13,12,12,12,12,
604.8064 +	13,12,12,13,13,13,12,13,13,13,13,13,13,13,13,13,
604.8065 +	13,13,13,13,13,12,12,12,13,12,12,12,13,13,13,12,
604.8066 +	12,12,13,13,13,13,13,13,13,12,13,13,13,13,10,11,
604.8067 +	11,12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,
604.8068 +	13,13,12,12,12,13,13,11,12,12,12,12,12,12,12,12,
604.8069 +	13,12,12,12,13,13,12,12,13,13,13,12,12,13,13,13,
604.8070 +	11,12,11,12,12,12,12,12,13,13,11,12,12,13,12,12,
604.8071 +	13,12,13,13,12,13,12,13,13,12,12,12,12,12,12,12,
604.8072 +	13,13,13,12,13,12,13,13,12,13,13,13,13,13,13,13,
604.8073 +	13,13,12,12,12,13,12,12,13,12,13,13,12,13,12,13,
604.8074 +	13,13,13,13,13,13,12,13,12,13,13,10,11,11,12,12,
604.8075 +	11,12,12,12,12,11,12,12,13,12,12,12,12,13,13,12,
604.8076 +	12,12,13,13,11,12,12,12,12,12,12,12,12,13,12,12,
604.8077 +	12,13,13,12,12,13,13,13,12,13,13,13,13,11,12,12,
604.8078 +	12,12,12,12,12,13,13,12,12,12,13,12,12,13,13,13,
604.8079 +	13,12,13,12,13,13,12,12,12,12,13,12,12,13,13,13,
604.8080 +	12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,
604.8081 +	12,12,12,12,12,13,13,13,13,12,13,12,13,13,13,13,
604.8082 +	13,13,13,13,13,13,13,13,11,11,11,12,12,11,12,12,
604.8083 +	12,12,11,12,12,12,12,12,12,12,13,13,12,12,12,13,
604.8084 +	13,11,12,12,12,12,12,12,12,13,13,12,12,12,13,13,
604.8085 +	12,12,13,13,13,12,13,13,13,13,11,12,12,12,12,12,
604.8086 +	12,12,13,13,12,12,12,13,12,12,13,12,13,13,12,13,
604.8087 +	12,13,13,12,12,12,12,12,12,13,13,13,13,12,13,13,
604.8088 +	13,13,13,13,13,13,13,13,13,13,13,13,12,12,12,12,
604.8089 +	12,12,13,13,13,13,12,13,12,13,12,13,13,13,13,13,
604.8090 +	13,13,13,13,12,
604.8091 +};
604.8092 +
604.8093 +static const static_codebook _44p7_p4_1 = {
604.8094 +	5, 3125,
604.8095 +	(long *)_vq_lengthlist__44p7_p4_1,
604.8096 +	1, -533725184, 1611661312, 3, 0,
604.8097 +	(long *)_vq_quantlist__44p7_p4_1,
604.8098 +	0
604.8099 +};
604.8100 +
604.8101 +static const long _vq_quantlist__44p7_p5_0[] = {
604.8102 +	2,
604.8103 +	1,
604.8104 +	3,
604.8105 +	0,
604.8106 +	4,
604.8107 +};
604.8108 +
604.8109 +static const long _vq_lengthlist__44p7_p5_0[] = {
604.8110 +	 2, 6, 6, 9, 9, 5, 7, 8,10,11, 5, 8, 7,11,10, 8,
604.8111 +	10,11,12,13, 8,11,10,13,12, 6, 7, 8,10,11, 7, 8,
604.8112 +	10,10,12, 8, 9, 9,12,11,10,10,12,11,14,10,11,12,
604.8113 +	14,13, 6, 8, 7,11,10, 8, 9, 9,11,12, 7,10, 8,12,
604.8114 +	10,10,12,12,13,14,10,12,10,14,11, 9,10,11,11,12,
604.8115 +	10,10,11,11,13,11,12,12,13,13,12,11,13,11,15,13,
604.8116 +	14,13,14,14, 9,11,10,12,11,11,12,12,13,13,10,11,
604.8117 +	10,13,11,13,13,14,14,14,12,13,11,14,11, 7, 8, 9,
604.8118 +	11,12, 9, 9,11,12,13, 9,10,10,13,12,11,12,13,13,
604.8119 +	15,11,12,12,14,14, 9,10,10,12,13,10,10,12,12,14,
604.8120 +	11,11,11,13,13,12,12,13,13,15,12,13,13,15,14, 9,
604.8121 +	10,10,12,13,10,11,11,13,14,10,12,11,14,13,12,13,
604.8122 +	13,14,15,12,13,13,15,14,12,12,13,13,14,12,13,13,
604.8123 +	13,15,13,14,14,14,15,14,14,15,14,16,14,15,15,16,
604.8124 +	16,12,13,13,14,14,13,13,14,15,14,12,13,13,15,14,
604.8125 +	14,15,15,15,16,14,15,14,16,14, 7, 9, 8,12,11, 9,
604.8126 +	10,10,12,13, 9,11, 9,13,12,11,12,12,14,14,11,13,
604.8127 +	12,15,13, 9,10,10,13,12,10,11,12,13,14,10,12,11,
604.8128 +	14,13,12,13,13,14,15,13,13,13,15,14, 9,10,10,13,
604.8129 +	12,11,11,11,13,13,10,12,10,14,12,13,13,13,14,15,
604.8130 +	12,13,12,15,13,12,13,13,14,14,12,13,13,14,15,13,
604.8131 +	14,13,15,15,14,14,15,14,16,14,15,15,16,15,12,13,
604.8132 +	12,14,13,13,13,13,15,14,12,13,13,15,13,14,15,15,
604.8133 +	16,15,14,15,14,16,14,11,12,12,13,14,12,13,14,14,
604.8134 +	15,12,13,13,14,15,14,14,15,15,16,14,15,15,16,16,
604.8135 +	12,13,13,14,15,13,13,14,14,16,13,14,14,15,15,15,
604.8136 +	15,16,15,17,15,15,15,16,16,12,13,13,14,15,13,14,
604.8137 +	14,15,16,13,14,14,15,15,15,15,16,16,17,15,15,15,
604.8138 +	17,16,14,15,15,16,16,15,15,16,15,16,15,16,16,16,
604.8139 +	17,16,16,17,16,18,16,16,17,18,17,14,15,15,16,16,
604.8140 +	15,16,16,16,17,15,16,15,17,16,16,17,17,17,18,16,
604.8141 +	16,16,17,16,11,12,12,14,13,12,13,13,15,14,12,14,
604.8142 +	13,15,14,14,15,15,16,16,14,15,14,16,15,12,13,13,
604.8143 +	15,14,13,14,14,15,15,13,14,14,16,15,15,15,15,16,
604.8144 +	16,15,16,15,17,16,12,13,13,15,14,13,14,14,15,15,
604.8145 +	13,14,13,16,14,15,15,15,16,16,15,15,15,17,15,14,
604.8146 +	15,15,16,16,15,15,15,16,16,15,16,16,17,17,16,16,
604.8147 +	17,17,17,16,17,17,18,17,14,15,15,16,15,15,15,16,
604.8148 +	16,16,15,15,15,17,15,17,17,17,18,17,16,17,16,18,
604.8149 +	16, 6, 9, 9,12,12, 8,10,10,12,13, 9,11,10,13,12,
604.8150 +	10,12,12,14,14,11,13,12,14,14, 8,10,10,12,12, 9,
604.8151 +	10,11,12,14,10,11,11,13,13,12,12,13,13,15,12,13,
604.8152 +	13,15,14, 9,10,10,13,13,10,11,11,13,13,10,12,10,
604.8153 +	14,13,12,13,13,14,15,12,13,13,15,14,11,12,12,13,
604.8154 +	14,12,12,13,13,15,12,13,13,14,14,13,13,14,13,16,
604.8155 +	14,15,15,16,15,11,12,12,14,14,13,13,13,15,14,12,
604.8156 +	13,13,15,14,14,15,15,16,15,14,14,14,16,14, 7, 9,
604.8157 +	10,12,12, 9,10,11,13,13, 9,11,10,13,13,11,12,13,
604.8158 +	14,15,12,13,13,15,14, 9,10,11,12,13,10,10,12,13,
604.8159 +	14,11,11,12,14,14,12,12,14,14,15,13,13,13,15,15,
604.8160 +	 9,11,11,13,13,11,12,12,14,14,10,12,10,14,13,13,
604.8161 +	14,13,15,15,12,14,13,15,14,12,12,13,13,15,12,12,
604.8162 +	14,13,15,13,14,14,15,15,14,14,15,14,17,14,15,15,
604.8163 +	16,16,12,13,13,15,14,13,14,14,15,15,12,14,13,15,
604.8164 +	14,14,15,15,16,16,14,15,14,16,14, 7,10,10,12,12,
604.8165 +	10,11,11,12,13,10,12,10,14,12,12,13,13,14,15,12,
604.8166 +	13,13,15,14, 9,11,10,13,12,10,10,12,12,14,11,13,
604.8167 +	12,14,13,13,13,14,13,15,13,14,14,15,14,10,11,11,
604.8168 +	13,13,12,12,12,13,14,10,12,10,14,12,13,14,14,15,
604.8169 +	15,13,14,13,15,13,12,13,13,14,14,12,12,13,14,15,
604.8170 +	13,14,14,15,15,13,13,14,13,15,14,15,15,16,16,12,
604.8171 +	13,13,14,14,13,14,14,15,15,12,13,13,15,13,15,15,
604.8172 +	15,16,16,13,14,13,16,13,11,12,13,14,14,12,13,14,
604.8173 +	14,15,12,13,13,15,15,14,14,15,15,17,14,15,15,16,
604.8174 +	16,12,13,14,14,15,13,13,14,14,16,13,14,14,15,16,
604.8175 +	14,14,16,15,17,15,15,16,16,16,12,13,13,15,15,13,
604.8176 +	14,14,15,16,13,14,14,15,16,15,15,16,17,17,15,16,
604.8177 +	15,17,16,14,15,15,15,16,15,15,16,15,17,15,15,16,
604.8178 +	16,17,16,16,16,16,18,16,16,17,17,17,14,15,15,16,
604.8179 +	16,15,16,16,16,17,15,16,15,17,16,16,17,17,17,17,
604.8180 +	16,17,16,18,17,11,12,12,14,14,13,13,14,14,15,13,
604.8181 +	14,13,15,14,14,15,15,15,16,14,15,15,17,15,12,13,
604.8182 +	13,15,14,13,13,14,15,15,14,15,14,16,15,15,15,15,
604.8183 +	15,16,15,16,15,17,16,12,13,13,15,15,14,14,14,15,
604.8184 +	16,13,14,13,16,15,15,15,16,16,17,15,16,15,17,15,
604.8185 +	14,15,15,16,16,14,15,15,16,16,15,16,16,17,16,15,
604.8186 +	15,16,15,17,16,17,17,18,17,14,15,15,16,16,15,16,
604.8187 +	16,16,17,14,15,15,17,16,17,17,17,17,18,15,16,16,
604.8188 +	18,15, 6, 9, 9,12,12, 9,10,11,12,13, 8,10,10,13,
604.8189 +	12,11,12,13,14,14,10,12,12,14,13, 9,10,10,12,13,
604.8190 +	10,10,12,13,14,10,11,11,13,13,12,13,13,14,15,12,
604.8191 +	13,13,15,14, 8,10,10,12,12,10,11,11,13,13, 9,11,
604.8192 +	10,13,13,12,13,13,14,15,12,13,12,15,13,11,12,12,
604.8193 +	14,14,12,13,13,13,15,13,13,13,14,15,14,14,15,14,
604.8194 +	16,14,15,15,15,15,11,12,12,14,13,12,13,13,15,14,
604.8195 +	12,13,12,15,13,14,14,15,16,16,13,14,13,16,13, 7,
604.8196 +	10,10,12,12,10,10,12,12,14,10,11,11,13,12,12,13,
604.8197 +	13,13,15,12,13,13,15,14,10,11,11,13,13,10,10,12,
604.8198 +	12,14,12,12,12,14,13,13,13,14,13,15,13,14,14,15,
604.8199 +	14, 9,10,11,13,13,11,12,12,13,14,10,12,10,14,12,
604.8200 +	13,13,14,14,15,13,13,12,15,13,12,13,13,14,14,12,
604.8201 +	13,13,14,15,13,14,14,15,15,13,13,15,13,16,15,15,
604.8202 +	15,16,16,12,13,13,14,14,13,14,14,15,15,12,13,12,
604.8203 +	15,14,15,15,15,16,16,13,14,13,15,13, 7,10, 9,12,
604.8204 +	12, 9,10,11,13,13, 9,11,10,13,13,11,13,13,14,15,
604.8205 +	11,13,12,15,14, 9,11,11,13,13,10,10,12,13,14,11,
604.8206 +	12,12,14,14,12,13,14,14,15,13,13,13,15,15, 9,11,
604.8207 +	10,13,12,11,12,11,14,14,10,12,10,14,13,13,14,13,
604.8208 +	15,15,12,14,12,15,14,12,13,13,14,15,13,13,14,14,
604.8209 +	15,13,14,14,15,15,14,14,15,14,17,14,15,15,16,16,
604.8210 +	12,13,12,15,13,13,14,14,15,15,12,14,13,15,13,14,
604.8211 +	15,15,16,16,14,15,14,16,14,11,12,12,14,14,13,13,
604.8212 +	14,14,15,13,14,13,15,15,14,15,15,16,17,14,15,15,
604.8213 +	16,15,12,13,13,15,15,13,13,14,15,16,14,14,14,16,
604.8214 +	15,15,15,16,15,17,15,16,15,17,16,12,13,13,14,15,
604.8215 +	14,14,15,15,16,13,14,13,15,15,15,15,16,16,17,15,
604.8216 +	15,15,16,15,14,15,15,16,16,14,15,15,16,17,15,16,
604.8217 +	16,17,17,16,15,16,15,17,16,17,17,17,17,14,15,15,
604.8218 +	15,16,15,15,16,16,17,14,15,15,16,16,16,16,17,17,
604.8219 +	18,15,16,15,17,15,11,13,12,14,14,12,13,13,15,15,
604.8220 +	12,14,13,15,14,14,15,15,16,16,14,15,14,16,15,12,
604.8221 +	13,13,15,15,13,14,14,15,16,13,14,14,16,16,15,15,
604.8222 +	16,16,17,15,16,15,17,16,12,13,13,15,14,13,14,14,
604.8223 +	16,15,13,14,13,16,14,15,16,15,17,16,15,15,14,18,
604.8224 +	15,14,15,15,16,16,15,15,16,16,17,15,16,15,17,16,
604.8225 +	16,16,17,17,18,16,17,17,18,17,14,15,15,16,15,15,
604.8226 +	16,15,17,16,15,15,15,17,15,16,17,17,18,17,16,17,
604.8227 +	16,18,15,10,12,12,14,14,12,13,13,14,14,12,13,13,
604.8228 +	14,14,13,14,14,15,15,13,14,14,16,15,11,12,13,14,
604.8229 +	14,12,13,13,15,15,12,13,13,15,15,13,14,15,15,16,
604.8230 +	14,15,15,16,16,12,13,13,14,14,13,13,14,15,15,13,
604.8231 +	14,13,15,15,14,15,15,16,16,14,15,14,16,15,13,14,
604.8232 +	14,15,15,13,14,14,15,16,14,14,15,16,16,14,15,15,
604.8233 +	15,17,15,16,16,17,17,13,14,14,15,15,14,15,15,16,
604.8234 +	16,14,15,15,16,16,15,16,16,16,17,15,16,15,17,16,
604.8235 +	11,12,12,14,14,12,13,13,14,15,12,13,13,15,14,13,
604.8236 +	14,14,15,16,13,14,14,16,15,12,13,13,14,15,13,13,
604.8237 +	14,15,15,13,14,14,15,15,14,14,15,15,17,14,15,15,
604.8238 +	16,16,12,13,13,15,15,13,14,14,15,15,13,14,13,15,
604.8239 +	15,14,15,15,16,17,14,15,15,16,16,13,13,14,15,16,
604.8240 +	14,14,15,15,16,14,15,15,16,16,15,15,16,15,18,15,
604.8241 +	16,16,17,17,14,15,15,16,16,15,15,15,16,16,14,15,
604.8242 +	15,17,16,16,16,16,17,17,15,16,16,17,16,10,12,12,
604.8243 +	14,14,12,13,13,14,15,12,13,13,15,14,14,14,15,15,
604.8244 +	16,14,15,14,16,15,12,13,13,15,14,13,13,14,15,15,
604.8245 +	13,14,14,15,15,14,14,15,15,16,14,15,15,16,16,12,
604.8246 +	13,13,15,15,13,14,14,15,16,13,14,13,15,14,15,15,
604.8247 +	15,16,16,14,15,15,16,15,13,14,14,16,15,14,14,14,
604.8248 +	15,16,14,15,15,16,16,15,15,16,15,17,16,17,16,17,
604.8249 +	17,14,14,15,15,16,15,15,16,16,16,14,15,14,16,15,
604.8250 +	16,16,16,17,17,15,16,15,17,15,11,13,13,14,15,13,
604.8251 +	13,14,15,15,13,14,13,15,15,14,15,15,15,16,14,15,
604.8252 +	15,17,15,13,13,14,15,15,13,14,15,15,16,14,14,14,
604.8253 +	16,16,15,14,16,15,17,15,16,16,17,16,13,14,14,15,
604.8254 +	15,14,14,14,16,16,13,15,14,16,15,15,15,16,17,17,
604.8255 +	15,16,15,17,16,14,15,15,15,16,15,15,16,15,17,15,
604.8256 +	16,16,16,17,16,16,17,15,18,16,17,17,17,17,14,15,
604.8257 +	15,16,16,15,16,16,17,17,15,16,15,17,16,16,17,17,
604.8258 +	18,18,16,17,15,18,16,10,12,12,14,14,13,13,14,14,
604.8259 +	15,13,14,13,15,14,14,15,15,15,16,15,15,15,16,15,
604.8260 +	12,13,13,15,14,12,12,14,14,15,14,15,14,16,15,15,
604.8261 +	14,15,14,17,15,16,16,17,16,12,13,13,14,15,14,14,
604.8262 +	15,15,16,13,14,12,16,14,15,16,16,16,17,15,16,14,
604.8263 +	17,15,14,15,14,16,15,14,14,15,15,15,15,16,15,17,
604.8264 +	16,15,14,16,14,16,16,17,17,18,17,14,14,15,15,16,
604.8265 +	15,16,16,16,17,14,15,14,16,15,16,16,17,17,17,15,
604.8266 +	16,14,17,14,10,12,12,14,13,12,13,13,14,14,11,13,
604.8267 +	12,14,14,13,14,14,15,16,13,14,14,16,15,12,13,13,
604.8268 +	14,14,13,13,14,15,15,13,14,13,15,15,14,14,15,15,
604.8269 +	16,14,15,15,16,16,11,13,12,14,14,12,13,13,15,15,
604.8270 +	12,13,13,15,15,14,15,15,16,16,13,14,14,16,15,13,
604.8271 +	14,14,15,15,14,15,15,15,16,14,15,15,16,16,15,16,
604.8272 +	16,16,17,16,16,16,17,17,13,14,14,15,15,14,15,15,
604.8273 +	16,16,13,14,14,16,15,15,16,16,17,17,15,15,15,17,
604.8274 +	15,11,12,12,14,14,12,13,13,14,15,12,13,13,15,14,
604.8275 +	14,14,15,15,16,14,14,14,16,15,12,13,13,15,14,13,
604.8276 +	13,14,15,15,13,14,14,16,15,14,15,15,15,16,15,15,
604.8277 +	15,16,16,12,13,13,14,15,13,13,14,15,15,13,14,13,
604.8278 +	15,15,15,15,15,16,16,14,15,14,16,15,14,14,15,16,
604.8279 +	16,14,15,15,15,16,15,16,15,16,16,15,15,16,15,17,
604.8280 +	16,16,16,17,17,13,14,14,15,16,14,15,15,16,16,14,
604.8281 +	14,14,16,16,16,16,16,17,17,15,15,15,17,15,11,12,
604.8282 +	12,14,14,12,13,13,14,15,12,13,13,15,14,14,14,14,
604.8283 +	15,16,13,14,14,16,15,12,13,13,15,15,13,13,14,15,
604.8284 +	16,13,14,14,15,15,14,15,15,16,17,14,15,15,17,16,
604.8285 +	12,13,13,15,14,13,14,14,15,15,13,14,13,15,15,14,
604.8286 +	15,15,16,16,14,15,14,17,15,14,15,15,16,16,14,15,
604.8287 +	15,16,17,15,15,15,17,17,15,16,16,16,17,16,17,16,
604.8288 +	17,17,13,15,14,16,15,14,15,15,16,16,14,15,14,16,
604.8289 +	15,16,16,16,17,17,15,16,15,17,15,10,12,12,14,14,
604.8290 +	13,13,14,14,15,13,14,13,15,14,14,15,15,15,17,14,
604.8291 +	15,15,16,15,12,13,13,15,14,12,12,14,14,15,14,15,
604.8292 +	14,16,15,15,14,16,15,17,15,16,16,17,16,12,13,13,
604.8293 +	14,15,14,14,15,15,16,12,14,12,15,14,15,16,16,16,
604.8294 +	17,15,16,14,17,14,14,15,14,16,16,14,14,15,15,16,
604.8295 +	15,16,16,17,16,15,14,16,14,17,16,17,17,18,17,14,
604.8296 +	14,15,15,16,15,15,16,16,17,14,15,14,16,15,16,17,
604.8297 +	17,17,18,15,16,14,17,14,11,13,13,15,14,13,13,14,
604.8298 +	15,15,12,14,13,15,15,14,15,15,15,17,14,15,14,16,
604.8299 +	15,13,14,14,15,15,13,14,15,15,16,14,15,14,16,16,
604.8300 +	15,15,16,16,17,15,16,16,17,17,13,14,13,15,15,14,
604.8301 +	14,14,16,16,13,15,14,16,15,15,16,16,17,17,15,16,
604.8302 +	14,17,15,15,15,15,16,17,15,15,16,16,17,15,16,16,
604.8303 +	17,17,16,15,17,16,17,17,17,17,18,18,14,15,15,17,
604.8304 +	15,15,16,16,17,16,15,16,15,17,15,16,17,17,17,17,
604.8305 +	16,17,15,18,15,
604.8306 +};
604.8307 +
604.8308 +static const static_codebook _44p7_p5_0 = {
604.8309 +	5, 3125,
604.8310 +	(long *)_vq_lengthlist__44p7_p5_0,
604.8311 +	1, -528744448, 1616642048, 3, 0,
604.8312 +	(long *)_vq_quantlist__44p7_p5_0,
604.8313 +	0
604.8314 +};
604.8315 +
604.8316 +static const long _vq_quantlist__44p7_p5_1[] = {
604.8317 +	3,
604.8318 +	2,
604.8319 +	4,
604.8320 +	1,
604.8321 +	5,
604.8322 +	0,
604.8323 +	6,
604.8324 +};
604.8325 +
604.8326 +static const long _vq_lengthlist__44p7_p5_1[] = {
604.8327 +	 2, 3, 3, 3, 3, 3, 3,
604.8328 +};
604.8329 +
604.8330 +static const static_codebook _44p7_p5_1 = {
604.8331 +	1, 7,
604.8332 +	(long *)_vq_lengthlist__44p7_p5_1,
604.8333 +	1, -533200896, 1611661312, 3, 0,
604.8334 +	(long *)_vq_quantlist__44p7_p5_1,
604.8335 +	0
604.8336 +};
604.8337 +
604.8338 +static const long _vq_quantlist__44p7_p6_0[] = {
604.8339 +	1,
604.8340 +	0,
604.8341 +	2,
604.8342 +};
604.8343 +
604.8344 +static const long _vq_lengthlist__44p7_p6_0[] = {
604.8345 +	 2, 5, 6, 5, 7, 8, 5, 8, 7, 5, 7, 7, 7, 7, 9, 8,
604.8346 +	 9, 9, 5, 7, 7, 8, 9, 9, 7, 9, 7, 6, 8, 8, 8, 9,
604.8347 +	10, 8, 9, 9, 8, 9,10, 9, 9,11,10,10,11, 8,10, 9,
604.8348 +	10,10,11, 9,10,10, 6, 8, 8, 8, 9, 9, 8,10, 9, 8,
604.8349 +	 9,10, 9,10,10,10,11,10, 8,10, 9,10,11,10, 9,11,
604.8350 +	 9, 6, 8, 8, 7, 9, 9, 8, 9, 9, 7, 9, 9, 9, 9,10,
604.8351 +	 9,10,10, 8, 9, 9, 9,10,10, 9,10, 9, 7, 9, 9, 9,
604.8352 +	10,10, 9,10,10, 9, 9,10,10, 9,11,10,11,11, 9,10,
604.8353 +	10,10,11,11,10,11,10, 6, 9, 8, 9,10,10, 9,10, 9,
604.8354 +	 8,10,10, 9, 9,10,10,11,11, 9,10,10,10,11,11, 9,
604.8355 +	11, 9, 6, 8, 8, 8, 9, 9, 7, 9, 9, 8, 9, 9, 9, 9,
604.8356 +	10, 9,10,10, 7, 9, 9, 9,10,10, 9,10, 9, 6, 8, 9,
604.8357 +	 9, 9,10, 9,10,10, 9,10,10, 9, 9,11,10,11,11, 8,
604.8358 +	10,10,10,11,11, 9,10, 9, 7, 9, 9, 9,10,10, 9,10,
604.8359 +	10, 9,10,10,10,10,11,10,11,11, 9,10, 9,10,11,11,
604.8360 +	10,11, 9,
604.8361 +};
604.8362 +
604.8363 +static const static_codebook _44p7_p6_0 = {
604.8364 +	5, 243,
604.8365 +	(long *)_vq_lengthlist__44p7_p6_0,
604.8366 +	1, -527106048, 1620377600, 2, 0,
604.8367 +	(long *)_vq_quantlist__44p7_p6_0,
604.8368 +	0
604.8369 +};
604.8370 +
604.8371 +static const long _vq_quantlist__44p7_p6_1[] = {
604.8372 +	1,
604.8373 +	0,
604.8374 +	2,
604.8375 +};
604.8376 +
604.8377 +static const long _vq_lengthlist__44p7_p6_1[] = {
604.8378 +	 4, 7, 7, 6, 7, 8, 6, 8, 7, 7, 7, 8, 7, 7, 8, 8,
604.8379 +	 8, 8, 7, 7, 7, 8, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8,
604.8380 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8,
604.8381 +	 8, 9, 9, 8, 9, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.8382 +	 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9,
604.8383 +	 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.8384 +	 8, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9, 8, 7, 8, 8, 8,
604.8385 +	 8, 9, 8, 9, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8,
604.8386 +	 8, 9, 9, 9, 8, 9, 9, 7, 8, 8, 8, 8, 8, 8, 8, 8,
604.8387 +	 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8, 8, 9, 9, 8,
604.8388 +	 9, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.8389 +	 9, 8, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9, 8, 7, 8, 8,
604.8390 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8,
604.8391 +	 8, 8, 8, 9, 9, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.8392 +	 8, 8, 8, 8, 8, 9, 9, 8, 9, 9, 8, 8, 8, 9, 9, 9,
604.8393 +	 8, 9, 8,
604.8394 +};
604.8395 +
604.8396 +static const static_codebook _44p7_p6_1 = {
604.8397 +	5, 243,
604.8398 +	(long *)_vq_lengthlist__44p7_p6_1,
604.8399 +	1, -530841600, 1616642048, 2, 0,
604.8400 +	(long *)_vq_quantlist__44p7_p6_1,
604.8401 +	0
604.8402 +};
604.8403 +
604.8404 +static const long _vq_quantlist__44p7_p7_0[] = {
604.8405 +	1,
604.8406 +	0,
604.8407 +	2,
604.8408 +};
604.8409 +
604.8410 +static const long _vq_lengthlist__44p7_p7_0[] = {
604.8411 +	 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.8412 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8413 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8414 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8415 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8416 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8417 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8418 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8419 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8420 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8421 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8422 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8423 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8424 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8425 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.8426 +	 9, 9, 9,
604.8427 +};
604.8428 +
604.8429 +static const static_codebook _44p7_p7_0 = {
604.8430 +	5, 243,
604.8431 +	(long *)_vq_lengthlist__44p7_p7_0,
604.8432 +	1, -513979392, 1633504256, 2, 0,
604.8433 +	(long *)_vq_quantlist__44p7_p7_0,
604.8434 +	0
604.8435 +};
604.8436 +
604.8437 +static const long _vq_quantlist__44p7_p7_1[] = {
604.8438 +	1,
604.8439 +	0,
604.8440 +	2,
604.8441 +};
604.8442 +
604.8443 +static const long _vq_lengthlist__44p7_p7_1[] = {
604.8444 +	 1, 5, 5, 4,10,10, 5,10,10, 5,10,10,10,10,10,10,
604.8445 +	10,10, 5,10,10,10,10,10, 9,10,10, 6,10,10,10,10,
604.8446 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8447 +	10,10,10,10,10,10, 7,10,10,10,10,10,10,10,10,10,
604.8448 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8449 +	10, 6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8450 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8451 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8452 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8453 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8454 +	10,10, 6,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8455 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8456 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8457 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8458 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
604.8459 +	10,11,11,
604.8460 +};
604.8461 +
604.8462 +static const static_codebook _44p7_p7_1 = {
604.8463 +	5, 243,
604.8464 +	(long *)_vq_lengthlist__44p7_p7_1,
604.8465 +	1, -516716544, 1630767104, 2, 0,
604.8466 +	(long *)_vq_quantlist__44p7_p7_1,
604.8467 +	0
604.8468 +};
604.8469 +
604.8470 +static const long _vq_quantlist__44p7_p7_2[] = {
604.8471 +	12,
604.8472 +	11,
604.8473 +	13,
604.8474 +	10,
604.8475 +	14,
604.8476 +	9,
604.8477 +	15,
604.8478 +	8,
604.8479 +	16,
604.8480 +	7,
604.8481 +	17,
604.8482 +	6,
604.8483 +	18,
604.8484 +	5,
604.8485 +	19,
604.8486 +	4,
604.8487 +	20,
604.8488 +	3,
604.8489 +	21,
604.8490 +	2,
604.8491 +	22,
604.8492 +	1,
604.8493 +	23,
604.8494 +	0,
604.8495 +	24,
604.8496 +};
604.8497 +
604.8498 +static const long _vq_lengthlist__44p7_p7_2[] = {
604.8499 +	 1, 3, 2, 4, 5, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
604.8500 +	12,13,13,14,14,15,15,15,15,
604.8501 +};
604.8502 +
604.8503 +static const static_codebook _44p7_p7_2 = {
604.8504 +	1, 25,
604.8505 +	(long *)_vq_lengthlist__44p7_p7_2,
604.8506 +	1, -518864896, 1620639744, 5, 0,
604.8507 +	(long *)_vq_quantlist__44p7_p7_2,
604.8508 +	0
604.8509 +};
604.8510 +
604.8511 +static const long _vq_quantlist__44p7_p7_3[] = {
604.8512 +	12,
604.8513 +	11,
604.8514 +	13,
604.8515 +	10,
604.8516 +	14,
604.8517 +	9,
604.8518 +	15,
604.8519 +	8,
604.8520 +	16,
604.8521 +	7,
604.8522 +	17,
604.8523 +	6,
604.8524 +	18,
604.8525 +	5,
604.8526 +	19,
604.8527 +	4,
604.8528 +	20,
604.8529 +	3,
604.8530 +	21,
604.8531 +	2,
604.8532 +	22,
604.8533 +	1,
604.8534 +	23,
604.8535 +	0,
604.8536 +	24,
604.8537 +};
604.8538 +
604.8539 +static const long _vq_lengthlist__44p7_p7_3[] = {
604.8540 +	 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.8541 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.8542 +};
604.8543 +
604.8544 +static const static_codebook _44p7_p7_3 = {
604.8545 +	1, 25,
604.8546 +	(long *)_vq_lengthlist__44p7_p7_3,
604.8547 +	1, -529006592, 1611661312, 5, 0,
604.8548 +	(long *)_vq_quantlist__44p7_p7_3,
604.8549 +	0
604.8550 +};
604.8551 +
604.8552 +static const long _huff_lengthlist__44p7_short[] = {
604.8553 +	 3, 9,14,16,17,19,22,22, 5, 4, 6, 9,11,13,17,20,
604.8554 +	 9, 5, 5, 6, 9,11,15,19,11, 7, 5, 5, 7, 9,13,17,
604.8555 +	14, 9, 7, 6, 6, 7,11,14,16,11, 9, 7, 6, 4, 4, 8,
604.8556 +	19,15,13,11, 9, 4, 3, 4,21,16,16,15,12, 6, 4, 4,
604.8557 +};
604.8558 +
604.8559 +static const static_codebook _huff_book__44p7_short = {
604.8560 +	2, 64,
604.8561 +	(long *)_huff_lengthlist__44p7_short,
604.8562 +	0, 0, 0, 0, 0,
604.8563 +	NULL,
604.8564 +	0
604.8565 +};
604.8566 +
604.8567 +static const long _vq_quantlist__44p8_l0_0[] = {
604.8568 +	6,
604.8569 +	5,
604.8570 +	7,
604.8571 +	4,
604.8572 +	8,
604.8573 +	3,
604.8574 +	9,
604.8575 +	2,
604.8576 +	10,
604.8577 +	1,
604.8578 +	11,
604.8579 +	0,
604.8580 +	12,
604.8581 +};
604.8582 +
604.8583 +static const long _vq_lengthlist__44p8_l0_0[] = {
604.8584 +	 2, 4, 4, 7, 7, 8, 8,10,10,11,11,12,12, 4, 5, 5,
604.8585 +	 7, 7, 9, 9,10, 9,12,10,12,12, 4, 5, 5, 7, 7, 9,
604.8586 +	 9, 9,10,10,12,12,12, 7, 7, 7, 7, 8, 9, 8,11, 5,
604.8587 +	12, 6,12,10, 7, 7, 7, 8, 7, 8, 9, 5,11, 6,12,10,
604.8588 +	12, 8, 9, 9, 9, 9, 9, 9,11, 7,11, 7,11, 9, 8, 9,
604.8589 +	 9, 9, 9, 9, 9, 7,10, 7,11, 9,11,10,10,10,10,10,
604.8590 +	10,10,11,10,11, 8,12, 9,10,10,10,10,10,10,10,10,
604.8591 +	11, 8,11, 9,12,10,11,11,11,11,11,11,11,11,12,10,
604.8592 +	12,11,10,11,11,11,11,11,11,11,11,10,12,11,12,12,
604.8593 +	12,12,12,12,12,12,12,12,12,12,12,12,11,12,12,12,
604.8594 +	12,12,12,12,12,12,11,12,12,
604.8595 +};
604.8596 +
604.8597 +static const static_codebook _44p8_l0_0 = {
604.8598 +	2, 169,
604.8599 +	(long *)_vq_lengthlist__44p8_l0_0,
604.8600 +	1, -526516224, 1616117760, 4, 0,
604.8601 +	(long *)_vq_quantlist__44p8_l0_0,
604.8602 +	0
604.8603 +};
604.8604 +
604.8605 +static const long _vq_quantlist__44p8_l0_1[] = {
604.8606 +	2,
604.8607 +	1,
604.8608 +	3,
604.8609 +	0,
604.8610 +	4,
604.8611 +};
604.8612 +
604.8613 +static const long _vq_lengthlist__44p8_l0_1[] = {
604.8614 +	 4, 4, 4, 5, 5, 4, 4, 5, 5, 5, 4, 5, 4, 5, 5, 5,
604.8615 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.8616 +};
604.8617 +
604.8618 +static const static_codebook _44p8_l0_1 = {
604.8619 +	2, 25,
604.8620 +	(long *)_vq_lengthlist__44p8_l0_1,
604.8621 +	1, -533725184, 1611661312, 3, 0,
604.8622 +	(long *)_vq_quantlist__44p8_l0_1,
604.8623 +	0
604.8624 +};
604.8625 +
604.8626 +static const long _vq_quantlist__44p8_l1_0[] = {
604.8627 +	54,
604.8628 +	29,
604.8629 +	79,
604.8630 +	0,
604.8631 +	108,
604.8632 +};
604.8633 +
604.8634 +static const long _vq_lengthlist__44p8_l1_0[] = {
604.8635 +	 1, 2, 3, 6, 7, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8,
604.8636 +	 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.8637 +};
604.8638 +
604.8639 +static const static_codebook _44p8_l1_0 = {
604.8640 +	2, 25,
604.8641 +	(long *)_vq_lengthlist__44p8_l1_0,
604.8642 +	1, -514516992, 1620639744, 7, 0,
604.8643 +	(long *)_vq_quantlist__44p8_l1_0,
604.8644 +	0
604.8645 +};
604.8646 +
604.8647 +static const long _huff_lengthlist__44p8_lfe[] = {
604.8648 +	 2, 3, 1, 3,
604.8649 +};
604.8650 +
604.8651 +static const static_codebook _huff_book__44p8_lfe = {
604.8652 +	2, 4,
604.8653 +	(long *)_huff_lengthlist__44p8_lfe,
604.8654 +	0, 0, 0, 0, 0,
604.8655 +	NULL,
604.8656 +	0
604.8657 +};
604.8658 +
604.8659 +static const long _huff_lengthlist__44p8_long[] = {
604.8660 +	 2, 7,14,16,17,18,20,21, 7, 4, 6, 8,11,12,14,16,
604.8661 +	13, 5, 4, 4, 8, 9,11,13,15, 8, 4, 3, 5, 7, 9,10,
604.8662 +	17,11, 8, 4, 4, 6, 9, 9,17,11, 9, 7, 6, 5, 7, 8,
604.8663 +	19,13,11, 9, 9, 7, 8, 8,21,15,13,11,10, 8, 8, 7,
604.8664 +};
604.8665 +
604.8666 +static const static_codebook _huff_book__44p8_long = {
604.8667 +	2, 64,
604.8668 +	(long *)_huff_lengthlist__44p8_long,
604.8669 +	0, 0, 0, 0, 0,
604.8670 +	NULL,
604.8671 +	0
604.8672 +};
604.8673 +
604.8674 +static const long _vq_quantlist__44p8_p1_0[] = {
604.8675 +	1,
604.8676 +	0,
604.8677 +	2,
604.8678 +};
604.8679 +
604.8680 +static const long _vq_lengthlist__44p8_p1_0[] = {
604.8681 +	 2, 5, 5, 4, 7, 7, 4, 7, 7, 5, 7, 7, 7, 8, 9, 7,
604.8682 +	 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 8, 6, 7, 8, 8, 9,
604.8683 +	10, 8, 9,10, 8, 9,10,10,10,12,10,11,12, 8,10,10,
604.8684 +	10,11,12,10,11,11, 6, 8, 7, 8,10, 9, 8,10, 9, 8,
604.8685 +	10,10,10,11,11,10,12,11, 8,10, 9,10,12,11,10,12,
604.8686 +	10, 5, 8, 8, 8,10,10, 8,10,10, 7, 9,10, 9,10,11,
604.8687 +	 9,11,11, 8,10,10,10,12,12,10,12,11, 7, 9, 9, 9,
604.8688 +	10,11, 9,11,11, 9, 9,11,10,11,12,10,11,12, 9,11,
604.8689 +	11,11,12,12,11,12,12, 7, 9, 9,10,11,11,10,12,11,
604.8690 +	 9,11,10,11,11,12,11,13,12,10,11,11,12,13,13,11,
604.8691 +	13,11, 5, 8, 8, 8,10,10, 8,10,10, 8,10,10,10,11,
604.8692 +	12,10,12,11, 7,10, 9, 9,11,11, 9,11,10, 7, 9, 9,
604.8693 +	10,11,12,10,11,11,10,11,11,11,11,13,12,13,13, 9,
604.8694 +	10,11,12,12,13,11,12,11, 7, 9, 9, 9,11,11, 9,11,
604.8695 +	10, 9,11,11,11,12,12,11,12,12, 9,11, 9,10,12,11,
604.8696 +	10,12,11,
604.8697 +};
604.8698 +
604.8699 +static const static_codebook _44p8_p1_0 = {
604.8700 +	5, 243,
604.8701 +	(long *)_vq_lengthlist__44p8_p1_0,
604.8702 +	1, -535822336, 1611661312, 2, 0,
604.8703 +	(long *)_vq_quantlist__44p8_p1_0,
604.8704 +	0
604.8705 +};
604.8706 +
604.8707 +static const long _vq_quantlist__44p8_p2_0[] = {
604.8708 +	2,
604.8709 +	1,
604.8710 +	3,
604.8711 +	0,
604.8712 +	4,
604.8713 +};
604.8714 +
604.8715 +static const long _vq_lengthlist__44p8_p2_0[] = {
604.8716 +	 4, 6, 6, 9, 9, 6, 8, 8,10,10, 6, 8, 8,10,10, 8,
604.8717 +	 9,10,12,12, 8,10, 9,12,12, 6, 8, 8,10,10, 8, 8,
604.8718 +	 9,10,11, 8, 9, 9,11,11, 9,10,11,12,13,10,11,11,
604.8719 +	13,13, 6, 8, 8,10,10, 8, 9, 9,11,11, 8, 9, 8,11,
604.8720 +	10,10,11,11,13,13, 9,11,10,13,12, 9,10,10,12,12,
604.8721 +	10,10,11,12,13,10,11,11,13,13,12,12,13,12,15,12,
604.8722 +	13,13,15,14, 9,10,10,12,12,10,11,11,13,13,10,11,
604.8723 +	10,13,12,12,13,13,14,15,12,13,12,15,12, 7, 8, 8,
604.8724 +	10,11, 8, 9,10,11,12, 8, 9, 9,11,11,10,11,11,13,
604.8725 +	14,10,11,11,13,13, 8, 9, 9,11,12, 9,10,11,11,13,
604.8726 +	 9,10,10,12,12,11,11,12,13,15,11,12,12,14,14, 8,
604.8727 +	 9, 9,11,11, 9,10,11,12,13, 9,10,10,12,12,11,12,
604.8728 +	12,14,15,11,12,12,14,14,10,11,12,13,13,11,12,12,
604.8729 +	13,14,12,12,12,14,14,13,13,14,14,16,14,14,14,16,
604.8730 +	15,10,11,11,13,13,12,12,12,14,14,11,12,12,14,13,
604.8731 +	14,14,14,15,16,13,14,13,16,14, 7, 8, 8,11,10, 8,
604.8732 +	 9, 9,11,11, 8,10, 9,12,11,10,11,11,13,13,10,11,
604.8733 +	11,14,13, 8, 9, 9,12,11, 9,10,10,12,12, 9,11,10,
604.8734 +	13,12,11,12,12,13,14,11,12,12,15,14, 8, 9, 9,12,
604.8735 +	11, 9,10,10,12,12, 9,11,10,13,11,11,12,12,14,14,
604.8736 +	11,12,12,14,13,10,11,11,13,13,11,12,12,13,14,12,
604.8737 +	13,12,14,14,13,13,14,14,16,13,14,14,16,15,10,11,
604.8738 +	11,13,13,12,12,12,14,14,11,12,12,14,13,13,14,14,
604.8739 +	15,15,13,14,13,16,14, 9,10,11,12,13,11,11,12,12,
604.8740 +	14,11,11,12,13,14,13,13,14,14,16,13,13,14,15,15,
604.8741 +	11,11,12,12,14,12,12,13,13,15,12,12,13,13,15,14,
604.8742 +	14,15,15,16,14,14,14,15,16,11,12,12,13,14,12,12,
604.8743 +	13,14,15,12,13,12,14,14,14,14,15,15,16,14,14,14,
604.8744 +	16,16,13,13,14,15,16,14,14,15,15,16,14,15,15,16,
604.8745 +	16,15,15,16,16,18,16,16,16,17,17,13,14,14,15,15,
604.8746 +	14,14,15,16,16,14,15,14,16,16,16,16,16,17,18,15,
604.8747 +	16,16,17,16, 9,11,10,13,12,11,12,11,14,13,11,12,
604.8748 +	11,14,12,13,14,13,15,14,13,14,13,16,14,11,12,12,
604.8749 +	14,13,12,12,13,14,14,12,13,12,15,14,14,14,14,16,
604.8750 +	16,14,15,14,17,15,11,12,11,14,12,12,13,12,15,13,
604.8751 +	12,13,12,15,13,14,14,14,16,15,14,15,14,16,15,13,
604.8752 +	14,14,15,15,14,14,15,16,16,14,15,14,16,16,15,15,
604.8753 +	16,16,17,16,16,16,17,17,13,14,14,16,15,14,15,15,
604.8754 +	16,16,14,15,14,17,15,16,16,16,17,17,15,16,15,18,
604.8755 +	16, 7, 8, 8,10,11, 8, 9, 9,11,12, 8, 9, 9,12,11,
604.8756 +	10,11,11,13,14,10,11,11,14,13, 8, 9, 9,11,11, 9,
604.8757 +	10,10,12,12, 9,10,10,12,12,11,12,12,13,14,11,12,
604.8758 +	12,14,14, 8, 9, 9,12,11, 9,10,11,12,13, 9,11,10,
604.8759 +	13,12,11,12,12,14,14,11,12,12,14,13,10,11,11,13,
604.8760 +	13,11,12,12,13,14,11,12,12,14,14,13,13,14,14,16,
604.8761 +	13,14,14,16,15,10,12,11,13,13,12,12,12,14,14,11,
604.8762 +	12,12,14,13,14,14,14,15,16,13,14,14,16,14, 8, 9,
604.8763 +	 9,11,11, 9,10,10,12,12, 9,10,10,12,12,11,11,12,
604.8764 +	13,14,11,12,12,14,14, 9, 9,10,11,12,10,10,11,12,
604.8765 +	13,10,10,11,12,13,12,12,13,14,15,12,12,13,14,15,
604.8766 +	 9,10,10,12,12,10,11,11,13,13,10,11,11,13,13,12,
604.8767 +	13,13,15,15,12,13,13,15,14,11,11,12,13,14,12,12,
604.8768 +	13,13,15,12,12,13,14,15,14,14,15,14,16,14,14,15,
604.8769 +	15,16,11,12,12,14,14,12,13,13,15,15,12,13,13,15,
604.8770 +	14,14,15,15,16,16,14,15,14,17,15, 8, 9, 9,11,11,
604.8771 +	 9,10,10,12,12, 9,11,10,13,12,11,12,12,14,14,11,
604.8772 +	13,12,15,13, 9,10,10,12,12,10,10,11,12,13,10,12,
604.8773 +	11,13,13,12,12,13,13,15,12,13,13,15,14, 9,10,10,
604.8774 +	12,12,11,11,12,13,13,10,12,10,13,12,12,13,13,15,
604.8775 +	15,12,13,13,15,13,11,12,12,14,14,12,12,13,14,14,
604.8776 +	12,13,13,15,14,13,13,14,13,16,14,15,14,16,16,11,
604.8777 +	12,12,14,14,13,13,13,15,15,12,13,12,15,14,14,15,
604.8778 +	15,16,17,14,15,13,16,13,10,11,11,13,14,11,12,12,
604.8779 +	13,15,11,12,12,14,14,13,14,14,15,16,13,14,14,16,
604.8780 +	16,11,11,12,12,14,12,12,13,13,15,12,13,13,13,15,
604.8781 +	14,14,15,14,17,14,14,15,15,16,11,12,12,14,14,12,
604.8782 +	13,13,15,15,12,13,13,15,15,14,15,15,16,17,14,15,
604.8783 +	15,16,16,13,14,14,14,16,14,14,15,14,17,14,15,15,
604.8784 +	14,17,16,16,17,15,18,16,16,17,16,18,13,14,14,16,
604.8785 +	16,14,15,15,17,16,14,15,15,17,16,16,17,17,18,18,
604.8786 +	16,17,16,18,17,10,11,11,14,13,11,12,12,14,14,11,
604.8787 +	13,12,15,14,14,14,14,16,15,14,15,14,16,15,11,12,
604.8788 +	12,14,13,12,13,13,15,14,13,14,13,15,14,14,15,15,
604.8789 +	16,16,14,15,15,17,15,11,12,12,14,14,13,13,13,15,
604.8790 +	15,12,13,13,15,14,15,15,15,17,17,14,15,15,17,15,
604.8791 +	13,14,14,16,15,14,15,15,16,16,15,15,15,17,16,16,
604.8792 +	16,16,16,17,16,17,16,18,17,14,14,14,16,16,15,15,
604.8793 +	15,16,16,14,15,14,17,16,16,17,17,17,18,16,17,16,
604.8794 +	18,16, 7, 8, 8,11,11, 8, 9, 9,11,12, 8, 9, 9,12,
604.8795 +	11,10,11,11,13,14,10,11,11,14,13, 8, 9, 9,11,12,
604.8796 +	 9,10,11,12,13, 9,11,10,13,12,11,12,12,13,14,11,
604.8797 +	12,12,14,14, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
604.8798 +	10,13,12,11,12,12,14,14,11,12,11,14,13,10,11,12,
604.8799 +	13,13,11,12,12,13,14,12,13,12,14,14,13,13,14,14,
604.8800 +	16,13,14,14,16,15,10,11,11,13,13,11,12,12,14,14,
604.8801 +	11,12,12,14,13,13,14,14,15,16,13,14,13,16,14, 8,
604.8802 +	 9, 9,11,11, 9,10,11,12,13, 9,10,10,12,12,11,12,
604.8803 +	13,13,14,11,12,12,14,14, 9,10,10,12,12,10,10,11,
604.8804 +	12,13,11,12,11,13,13,12,12,13,13,15,12,13,13,15,
604.8805 +	15, 9,10,10,12,12,10,11,12,13,14,10,11,10,13,12,
604.8806 +	12,13,13,14,15,12,13,12,15,13,12,12,12,14,14,12,
604.8807 +	12,13,14,15,13,13,13,15,15,14,14,15,13,16,14,15,
604.8808 +	15,16,16,11,12,12,14,14,12,13,13,14,15,12,13,12,
604.8809 +	14,14,14,14,15,16,16,13,14,13,16,14, 8, 9, 9,11,
604.8810 +	11, 9,10,10,12,12, 9,10,10,12,12,11,12,12,14,14,
604.8811 +	11,12,11,14,14, 9,10,10,12,12,10,11,11,13,13,10,
604.8812 +	11,11,13,13,12,13,13,14,15,12,13,13,15,14, 9,10,
604.8813 +	 9,12,11,10,11,10,13,12,10,11,10,13,12,12,13,12,
604.8814 +	15,14,12,13,12,15,14,11,12,12,14,14,12,13,13,14,
604.8815 +	15,12,13,13,15,15,14,14,15,15,17,14,15,15,16,16,
604.8816 +	11,12,11,14,13,12,13,12,15,14,12,13,12,15,13,14,
604.8817 +	15,14,16,15,13,15,14,17,14,10,11,11,13,14,11,12,
604.8818 +	13,13,15,11,12,12,14,14,14,14,15,15,17,13,14,14,
604.8819 +	15,16,11,12,12,14,14,12,12,13,14,15,13,13,13,15,
604.8820 +	15,14,15,15,15,17,15,15,15,16,16,11,12,12,13,14,
604.8821 +	13,13,14,14,15,12,13,13,14,15,14,15,15,16,17,14,
604.8822 +	15,15,16,16,14,14,14,16,16,14,14,15,15,17,15,15,
604.8823 +	15,17,16,16,16,17,16,18,16,17,17,18,17,13,14,14,
604.8824 +	15,16,14,15,15,16,17,14,15,15,16,16,16,17,17,17,
604.8825 +	18,16,16,16,17,16,10,11,11,14,13,11,12,12,14,14,
604.8826 +	11,12,12,15,13,13,14,14,16,15,13,14,14,16,15,11,
604.8827 +	12,12,14,14,12,13,13,15,15,12,13,13,15,15,14,15,
604.8828 +	15,16,17,14,15,15,17,16,11,12,11,14,12,12,13,13,
604.8829 +	15,13,12,13,12,15,13,14,15,15,16,15,14,15,14,17,
604.8830 +	14,13,14,14,16,16,14,15,15,16,17,14,15,15,16,17,
604.8831 +	16,16,17,17,18,16,17,17,18,18,13,14,14,16,13,14,
604.8832 +	15,15,17,14,14,15,14,17,14,16,17,16,17,16,16,17,
604.8833 +	16,18,15, 8,11,11,13,13,10,12,12,14,14,11,12,12,
604.8834 +	14,14,13,13,14,15,16,13,14,14,16,15,10,11,11,14,
604.8835 +	14,11,12,12,14,15,11,12,12,15,14,13,14,14,15,16,
604.8836 +	13,14,14,16,16,11,12,12,14,14,12,13,13,15,15,12,
604.8837 +	13,12,15,14,14,14,15,16,16,14,15,14,16,16,12,13,
604.8838 +	13,15,15,12,13,14,15,16,13,14,14,16,16,14,15,15,
604.8839 +	16,17,15,15,16,17,17,13,14,14,16,15,14,15,15,16,
604.8840 +	16,14,15,14,16,16,16,16,16,17,17,15,16,16,18,16,
604.8841 +	10,11,11,13,14,11,12,12,14,15,11,12,12,15,14,13,
604.8842 +	14,14,16,16,13,14,14,16,16,11,11,12,14,14,12,12,
604.8843 +	13,14,15,12,13,13,15,15,14,14,15,15,17,14,14,15,
604.8844 +	16,16,11,12,12,15,14,12,13,13,15,15,12,13,13,15,
604.8845 +	15,14,15,15,17,17,14,15,15,17,16,13,12,14,14,16,
604.8846 +	13,13,15,14,17,14,13,15,15,17,15,14,16,15,18,16,
604.8847 +	15,16,16,18,13,14,14,16,16,14,15,15,17,17,14,15,
604.8848 +	15,17,16,16,17,17,18,18,16,17,16,18,17,10,11,11,
604.8849 +	14,13,11,12,12,14,14,11,13,12,15,14,13,14,14,15,
604.8850 +	16,13,14,14,16,16,11,12,12,14,14,12,13,13,14,15,
604.8851 +	12,13,13,15,15,14,14,15,15,16,14,15,15,17,16,11,
604.8852 +	12,12,14,14,13,13,13,15,15,12,13,13,15,14,14,15,
604.8853 +	15,16,17,14,15,14,17,15,13,14,13,16,15,14,14,14,
604.8854 +	15,16,14,15,14,16,16,15,15,16,16,17,16,16,16,18,
604.8855 +	17,14,14,14,16,16,15,15,15,17,16,14,15,14,17,16,
604.8856 +	16,16,17,17,18,16,17,16,18,16,11,13,13,15,15,12,
604.8857 +	13,14,15,16,12,14,14,15,15,14,15,15,16,17,14,15,
604.8858 +	15,17,17,12,13,14,14,16,13,14,14,14,16,14,14,14,
604.8859 +	15,16,15,15,16,15,18,15,16,16,17,17,13,14,14,16,
604.8860 +	16,14,14,15,16,16,14,15,14,16,16,15,16,16,17,18,
604.8861 +	15,16,16,18,17,14,14,16,13,17,15,15,16,14,18,15,
604.8862 +	15,16,14,18,16,16,18,15,19,17,17,18,16,18,15,16,
604.8863 +	15,17,17,15,16,17,18,18,16,16,16,18,17,17,18,18,
604.8864 +	19,19,17,18,17,19,18,11,12,12,15,14,13,13,14,15,
604.8865 +	16,13,14,13,16,14,15,15,15,16,17,15,16,15,17,16,
604.8866 +	12,13,13,15,14,13,13,14,15,15,14,15,14,16,15,15,
604.8867 +	15,16,16,17,16,16,16,18,17,12,13,13,15,15,14,14,
604.8868 +	15,16,16,13,14,13,16,15,16,16,16,17,18,15,16,15,
604.8869 +	17,16,14,15,14,17,15,14,15,15,16,16,15,16,15,17,
604.8870 +	16,16,15,16,15,17,17,18,17,18,17,15,15,15,16,17,
604.8871 +	16,16,16,17,17,15,16,15,17,16,17,18,18,18,18,16,
604.8872 +	17,16,18,15, 8,11,11,13,13,11,12,12,14,14,10,12,
604.8873 +	12,14,14,13,14,14,15,16,13,14,13,16,15,11,12,12,
604.8874 +	14,14,12,12,13,14,15,12,13,13,15,15,14,14,15,15,
604.8875 +	16,14,14,14,16,16,10,11,11,14,14,11,12,12,14,15,
604.8876 +	11,12,12,15,14,13,14,14,16,16,13,14,14,16,15,13,
604.8877 +	14,14,15,16,14,14,15,16,16,14,15,15,16,16,15,16,
604.8878 +	16,16,18,16,16,16,17,17,12,13,13,15,15,13,14,14,
604.8879 +	16,16,12,14,13,16,15,15,16,15,17,17,14,16,15,17,
604.8880 +	16,10,11,11,13,14,11,12,13,14,15,11,13,12,14,14,
604.8881 +	14,14,15,16,16,13,14,14,16,16,11,12,12,14,14,12,
604.8882 +	13,13,14,15,13,14,13,15,15,14,15,15,16,17,14,15,
604.8883 +	15,17,16,11,12,12,14,14,12,13,13,15,15,12,13,12,
604.8884 +	15,14,14,15,15,16,17,14,15,15,16,16,14,14,14,16,
604.8885 +	16,14,14,15,16,16,15,15,15,16,16,16,16,17,16,18,
604.8886 +	16,17,17,18,18,13,13,14,15,16,14,14,15,16,17,13,
604.8887 +	14,14,16,16,16,16,17,17,18,15,16,15,17,16,10,11,
604.8888 +	11,14,13,11,12,12,14,14,11,12,12,15,14,13,14,14,
604.8889 +	16,16,13,14,14,16,16,11,12,12,14,14,12,13,13,15,
604.8890 +	15,12,13,13,15,15,14,15,15,16,17,14,15,15,17,16,
604.8891 +	11,12,11,14,14,12,13,13,15,15,12,13,12,15,14,14,
604.8892 +	15,14,16,16,14,15,14,17,16,14,14,14,16,16,14,15,
604.8893 +	15,16,17,14,15,15,17,17,16,16,17,17,18,16,17,17,
604.8894 +	18,18,13,14,12,16,14,14,15,13,17,15,13,15,13,17,
604.8895 +	14,16,16,15,18,16,15,17,14,18,15,11,12,12,14,15,
604.8896 +	13,13,14,14,16,13,14,13,15,14,15,15,16,16,17,15,
604.8897 +	16,15,17,16,12,13,13,15,15,13,13,14,15,16,14,15,
604.8898 +	14,16,16,15,15,16,15,18,16,16,16,18,17,12,13,13,
604.8899 +	15,15,14,14,15,15,16,13,14,13,15,15,16,16,16,16,
604.8900 +	18,15,16,15,17,16,15,15,15,17,16,15,15,16,16,17,
604.8901 +	16,16,16,18,17,16,16,17,15,18,17,18,17,19,18,14,
604.8902 +	14,15,15,17,15,15,16,16,17,14,15,15,16,16,17,17,
604.8903 +	18,17,19,16,17,15,17,15,11,13,12,15,15,12,14,14,
604.8904 +	15,15,12,14,13,16,15,15,15,15,17,17,14,15,15,17,
604.8905 +	16,12,14,14,16,16,14,14,15,16,16,14,14,14,16,16,
604.8906 +	15,16,17,17,18,15,16,16,18,17,12,14,13,16,14,13,
604.8907 +	14,14,16,15,13,15,14,16,14,15,16,16,17,17,15,16,
604.8908 +	15,18,15,15,15,16,17,17,15,16,16,17,18,16,16,16,
604.8909 +	18,18,17,17,18,18,19,17,17,18,19,19,14,15,14,17,
604.8910 +	13,15,16,15,18,14,15,16,15,18,14,17,18,17,18,16,
604.8911 +	16,18,16,19,15,
604.8912 +};
604.8913 +
604.8914 +static const static_codebook _44p8_p2_0 = {
604.8915 +	5, 3125,
604.8916 +	(long *)_vq_lengthlist__44p8_p2_0,
604.8917 +	1, -533725184, 1611661312, 3, 0,
604.8918 +	(long *)_vq_quantlist__44p8_p2_0,
604.8919 +	0
604.8920 +};
604.8921 +
604.8922 +static const long _vq_quantlist__44p8_p3_0[] = {
604.8923 +	1,
604.8924 +	0,
604.8925 +	2,
604.8926 +};
604.8927 +
604.8928 +static const long _vq_lengthlist__44p8_p3_0[] = {
604.8929 +	 2, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 8, 9, 7,
604.8930 +	 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 8, 5, 7, 8, 7, 9,
604.8931 +	10, 8, 9, 9, 8, 9,10, 9,10,12,10,11,11, 8,10, 9,
604.8932 +	10,11,12, 9,11,10, 5, 8, 7, 8,10, 9, 7,10, 9, 8,
604.8933 +	 9,10, 9,10,11,10,12,11, 8,10, 9,10,11,11, 9,12,
604.8934 +	10, 5, 8, 8, 7, 9,10, 8,10, 9, 7, 9,10, 9,10,11,
604.8935 +	 9,11,11, 8,10, 9,10,11,11,10,12,10, 7, 9,10, 9,
604.8936 +	10,12, 9,11,11, 9, 9,12,11,10,13,11,11,13,10,12,
604.8937 +	11,11,13,13,11,13,12, 7, 9, 9, 9,11,11, 9,12,11,
604.8938 +	 9,11,10,10,11,12,11,13,12, 9,11,11,12,13,13,11,
604.8939 +	13,11, 5, 8, 8, 8, 9,10, 7,10, 9, 8, 9,10,10,10,
604.8940 +	12,10,11,11, 7,10, 9, 9,11,11, 9,11,10, 7, 9, 9,
604.8941 +	 9,11,12, 9,11,11, 9,11,11,11,11,13,12,13,13, 9,
604.8942 +	10,11,11,12,13,10,12,11, 7,10, 9, 9,11,11, 9,12,
604.8943 +	10,10,11,12,11,12,13,12,13,13, 9,12, 9,11,13,11,
604.8944 +	10,13,10,
604.8945 +};
604.8946 +
604.8947 +static const static_codebook _44p8_p3_0 = {
604.8948 +	5, 243,
604.8949 +	(long *)_vq_lengthlist__44p8_p3_0,
604.8950 +	1, -533200896, 1614282752, 2, 0,
604.8951 +	(long *)_vq_quantlist__44p8_p3_0,
604.8952 +	0
604.8953 +};
604.8954 +
604.8955 +static const long _vq_quantlist__44p8_p3_1[] = {
604.8956 +	1,
604.8957 +	0,
604.8958 +	2,
604.8959 +};
604.8960 +
604.8961 +static const long _vq_lengthlist__44p8_p3_1[] = {
604.8962 +	 6, 7, 7, 7, 7, 8, 7, 8, 7, 7, 7, 8, 7, 8, 8, 8,
604.8963 +	 8, 8, 7, 8, 7, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8,
604.8964 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.8965 +	 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.8966 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.8967 +	 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.8968 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8,
604.8969 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8,
604.8970 +	 8, 8, 9, 9, 8, 9, 9, 7, 8, 8, 8, 8, 8, 8, 8, 8,
604.8971 +	 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 9, 9, 8,
604.8972 +	 9, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.8973 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8,
604.8974 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8,
604.8975 +	 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.8976 +	 8, 8, 8, 8, 8, 9, 9, 8, 9, 9, 8, 8, 8, 8, 9, 8,
604.8977 +	 8, 9, 8,
604.8978 +};
604.8979 +
604.8980 +static const static_codebook _44p8_p3_1 = {
604.8981 +	5, 243,
604.8982 +	(long *)_vq_lengthlist__44p8_p3_1,
604.8983 +	1, -535822336, 1611661312, 2, 0,
604.8984 +	(long *)_vq_quantlist__44p8_p3_1,
604.8985 +	0
604.8986 +};
604.8987 +
604.8988 +static const long _vq_quantlist__44p8_p4_0[] = {
604.8989 +	1,
604.8990 +	0,
604.8991 +	2,
604.8992 +};
604.8993 +
604.8994 +static const long _vq_lengthlist__44p8_p4_0[] = {
604.8995 +	 2, 5, 5, 4, 7, 8, 4, 8, 7, 5, 7, 8, 7, 7,10, 8,
604.8996 +	 9, 9, 5, 7, 7, 8, 9, 9, 7,10, 7, 5, 7, 8, 8, 9,
604.8997 +	11, 8,10,10, 8, 9,10,10,10,12,11,12,12, 8,10,10,
604.8998 +	10,12,12,10,12,11, 5, 8, 7, 8,10,10, 8,11, 9, 8,
604.8999 +	10,10,10,11,12,10,12,12, 8,10, 9,11,12,12,10,12,
604.9000 +	10, 5, 8, 8, 7,10,10, 8,11,10, 7, 9,10, 9,10,12,
604.9001 +	10,12,12, 8,10,10,10,12,12,10,12,11, 7, 9,10, 9,
604.9002 +	11,12,10,12,11, 9, 9,12,10,10,13,12,12,13,10,12,
604.9003 +	11,12,13,13,11,13,11, 7,10, 9,10,11,12,10,13,11,
604.9004 +	 9,11,11,11,11,13,12,14,13,10,11,11,12,14,14,11,
604.9005 +	14,11, 5, 8, 8, 8,10,11, 7,10,10, 8,10,10,10,11,
604.9006 +	12,10,12,12, 7,10, 9,10,12,12, 9,12,10, 7, 9,10,
604.9007 +	10,11,13,10,12,11,10,11,11,11,11,14,12,14,14, 9,
604.9008 +	11,11,12,13,14,11,13,11, 7,10, 9,10,11,12, 9,12,
604.9009 +	10,10,11,12,11,11,13,12,13,13, 9,12, 9,12,13,12,
604.9010 +	10,13,10,
604.9011 +};
604.9012 +
604.9013 +static const static_codebook _44p8_p4_0 = {
604.9014 +	5, 243,
604.9015 +	(long *)_vq_lengthlist__44p8_p4_0,
604.9016 +	1, -531365888, 1616117760, 2, 0,
604.9017 +	(long *)_vq_quantlist__44p8_p4_0,
604.9018 +	0
604.9019 +};
604.9020 +
604.9021 +static const long _vq_quantlist__44p8_p4_1[] = {
604.9022 +	2,
604.9023 +	1,
604.9024 +	3,
604.9025 +	0,
604.9026 +	4,
604.9027 +};
604.9028 +
604.9029 +static const long _vq_lengthlist__44p8_p4_1[] = {
604.9030 +	 7, 9, 9,10,10, 9,10,10,10,11, 9,10,10,11,10, 9,
604.9031 +	10,10,11,11, 9,10,10,11,11, 9,10,10,11,11,10,10,
604.9032 +	10,11,11,10,10,10,11,11,10,11,11,11,11,10,11,11,
604.9033 +	11,11, 9,10,10,11,11,10,10,10,11,11, 9,10,10,11,
604.9034 +	11,10,11,11,11,11,10,11,11,11,11,10,11,11,11,11,
604.9035 +	10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
604.9036 +	11,11,11,12,10,11,11,11,11,11,11,11,11,11,10,11,
604.9037 +	11,11,11,11,11,11,11,11,11,11,11,11,11, 9,10,10,
604.9038 +	11,11,10,10,11,11,11,10,10,11,11,11,10,11,11,11,
604.9039 +	12,10,11,11,12,12,10,10,11,11,11,10,11,11,11,12,
604.9040 +	11,11,11,12,12,11,11,12,12,12,11,11,12,12,12,10,
604.9041 +	11,11,11,11,11,11,11,12,12,10,11,11,12,12,11,12,
604.9042 +	11,12,12,11,12,11,12,12,11,11,11,11,12,11,11,12,
604.9043 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9044 +	12,11,11,11,12,12,11,12,12,12,12,11,12,11,12,12,
604.9045 +	12,12,12,12,12,12,12,12,12,12, 9,10,10,11,11,10,
604.9046 +	11,10,11,11,10,11,10,11,11,10,11,11,12,12,10,11,
604.9047 +	11,12,11,10,11,11,11,11,10,11,11,11,12,11,11,11,
604.9048 +	12,12,11,11,12,12,12,11,11,11,12,12,10,11,10,11,
604.9049 +	11,11,11,11,12,12,10,11,11,12,11,11,12,11,12,12,
604.9050 +	11,12,11,12,12,11,11,11,12,12,11,11,12,12,12,11,
604.9051 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,11,
604.9052 +	11,12,11,11,12,12,12,12,11,12,11,12,12,12,12,12,
604.9053 +	12,12,12,12,12,12,12,10,11,11,11,11,11,11,11,12,
604.9054 +	12,11,11,11,12,12,11,12,12,12,12,11,12,12,12,12,
604.9055 +	11,11,11,12,12,11,11,12,12,12,11,12,12,12,12,12,
604.9056 +	12,12,12,12,12,12,12,12,12,11,11,11,12,12,11,12,
604.9057 +	12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.9058 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9059 +	12,12,12,13,12,13,12,12,12,12,13,12,12,12,12,12,
604.9060 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9061 +	12,12,13,12,10,11,11,11,11,11,11,11,12,12,11,11,
604.9062 +	11,12,12,11,12,12,12,12,11,12,12,12,12,11,11,11,
604.9063 +	12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,12,
604.9064 +	12,12,12,12,12,12,11,11,11,12,12,11,12,12,12,12,
604.9065 +	11,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9066 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9067 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9068 +	12,12,12,12,12,12,12,12,12,12,13,12,12,13,12,13,
604.9069 +	12, 9,10,10,11,11,10,10,11,11,11,10,11,10,11,11,
604.9070 +	10,11,11,12,12,10,11,11,12,12,10,10,11,11,11,10,
604.9071 +	11,11,11,12,10,11,11,12,12,11,11,12,12,12,11,11,
604.9072 +	11,12,12,10,11,10,11,11,11,11,11,12,12,10,11,11,
604.9073 +	12,11,11,12,11,12,12,11,12,11,12,12,11,11,11,11,
604.9074 +	12,11,11,12,12,12,11,12,12,12,12,11,12,12,12,12,
604.9075 +	11,12,12,12,12,11,11,11,12,11,11,12,12,12,12,11,
604.9076 +	12,11,12,12,12,12,12,12,12,12,12,12,12,12,10,10,
604.9077 +	11,11,11,10,11,11,12,12,10,11,11,12,12,11,11,11,
604.9078 +	12,12,11,11,12,12,12,10,11,11,11,12,11,11,12,12,
604.9079 +	12,11,11,12,12,12,11,11,12,12,12,11,12,12,12,12,
604.9080 +	11,11,11,12,12,11,12,12,12,12,11,12,11,12,12,11,
604.9081 +	12,12,12,12,11,12,12,12,12,11,11,12,12,12,11,12,
604.9082 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9083 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9084 +	12,12,12,12,12,12,12,12,12,12,12, 9,10,10,11,11,
604.9085 +	10,11,11,11,12,10,11,11,12,11,11,12,11,12,12,11,
604.9086 +	12,11,12,12,10,11,11,12,11,11,11,11,12,12,11,12,
604.9087 +	11,12,12,11,12,12,12,12,11,12,12,12,12,10,11,11,
604.9088 +	12,12,11,12,11,12,12,11,12,11,12,12,12,12,12,12,
604.9089 +	12,11,12,12,12,12,11,12,11,12,12,11,12,12,12,12,
604.9090 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,
604.9091 +	12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,
604.9092 +	12,12,12,12,12,12,12,12,11,11,11,12,12,11,12,12,
604.9093 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9094 +	12,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9095 +	12,12,12,12,13,12,12,12,12,12,11,12,12,12,12,12,
604.9096 +	12,12,12,12,12,12,12,12,12,12,12,12,13,13,12,12,
604.9097 +	12,13,13,12,12,12,12,12,12,12,12,12,13,12,12,12,
604.9098 +	12,13,12,12,13,12,13,12,13,13,13,13,12,12,12,12,
604.9099 +	12,12,12,12,13,12,12,12,12,13,12,12,13,13,13,13,
604.9100 +	12,13,13,13,13,10,11,11,12,12,11,12,12,12,12,11,
604.9101 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,11,
604.9102 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9103 +	12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,
604.9104 +	12,12,12,12,13,12,12,12,12,13,13,12,12,12,13,12,
604.9105 +	12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,12,
604.9106 +	13,13,12,13,12,13,13,13,13,12,12,12,12,12,12,12,
604.9107 +	12,13,12,12,12,12,13,12,12,13,13,13,13,12,13,13,
604.9108 +	13,13, 9,10,10,11,11,10,10,11,11,11,10,11,10,11,
604.9109 +	11,10,11,11,12,12,10,11,11,12,12,10,11,11,11,11,
604.9110 +	10,11,11,12,12,11,11,11,12,12,11,11,12,12,12,11,
604.9111 +	11,12,12,12,10,11,10,11,11,10,11,11,12,12,10,11,
604.9112 +	11,12,11,11,12,11,12,12,11,11,11,12,12,11,11,11,
604.9113 +	11,12,11,11,12,12,12,11,12,12,12,12,12,12,12,12,
604.9114 +	12,12,12,12,12,12,11,11,11,12,11,11,12,12,12,12,
604.9115 +	11,12,11,12,12,12,12,12,12,12,11,12,12,12,12, 9,
604.9116 +	10,10,11,11,10,11,11,11,12,10,11,11,12,11,11,11,
604.9117 +	12,12,12,11,11,12,12,12,10,11,11,12,12,11,11,12,
604.9118 +	12,12,11,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.9119 +	12,10,11,11,12,12,11,11,11,12,12,11,11,11,12,12,
604.9120 +	11,12,12,12,12,11,12,12,12,12,11,12,12,12,12,11,
604.9121 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9122 +	12,12,12,11,11,12,12,12,12,12,12,12,12,11,12,12,
604.9123 +	12,12,12,12,12,12,12,12,12,12,12,12,10,11,10,11,
604.9124 +	11,10,11,11,12,12,10,11,11,12,12,11,11,11,12,12,
604.9125 +	11,12,11,12,12,11,11,11,12,12,11,11,12,12,12,11,
604.9126 +	11,12,12,12,11,12,12,12,12,11,12,12,12,12,10,11,
604.9127 +	11,12,11,11,12,11,12,12,11,12,11,12,12,11,12,12,
604.9128 +	12,12,11,12,11,12,12,11,12,12,12,12,12,12,12,12,
604.9129 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9130 +	11,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9131 +	12,12,12,12,12,12,12,12,12,11,11,11,12,12,11,11,
604.9132 +	12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.9133 +	12,12,11,12,12,12,12,12,12,12,12,13,12,12,12,12,
604.9134 +	12,12,12,12,13,13,12,12,12,13,13,11,12,12,12,12,
604.9135 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,12,
604.9136 +	12,12,12,12,12,12,12,12,12,12,12,13,12,13,12,12,
604.9137 +	12,13,13,12,13,13,12,13,12,13,13,13,13,12,12,12,
604.9138 +	12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,
604.9139 +	13,12,13,12,13,12,11,11,11,12,12,11,12,12,12,12,
604.9140 +	11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,
604.9141 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9142 +	12,13,13,12,12,12,13,13,11,12,11,12,12,12,12,12,
604.9143 +	12,12,12,12,12,12,12,12,12,12,13,12,12,12,12,13,
604.9144 +	12,12,12,12,12,12,12,12,12,13,13,12,12,12,12,13,
604.9145 +	12,13,13,13,13,12,13,13,13,13,12,12,12,12,12,12,
604.9146 +	12,12,13,12,12,12,12,13,12,12,13,13,13,13,12,13,
604.9147 +	13,13,12,10,11,11,12,12,11,11,11,12,12,11,11,11,
604.9148 +	12,12,11,12,12,12,12,11,12,12,12,12,11,11,11,12,
604.9149 +	12,11,11,12,12,12,11,12,12,12,12,11,12,12,12,12,
604.9150 +	12,12,12,12,12,11,11,11,12,12,11,12,12,12,12,11,
604.9151 +	12,11,12,12,12,12,12,12,12,12,12,12,12,12,11,12,
604.9152 +	12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.9153 +	12,13,12,12,12,12,12,11,12,12,12,12,12,12,12,12,
604.9154 +	12,12,12,12,12,12,12,12,12,13,12,12,12,12,12,12,
604.9155 +	11,11,11,12,12,11,12,12,12,12,11,12,12,12,12,12,
604.9156 +	12,12,12,12,11,12,12,12,12,11,11,12,12,12,11,12,
604.9157 +	12,12,12,12,12,12,12,12,12,12,12,12,13,12,12,12,
604.9158 +	13,13,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9159 +	12,12,12,12,13,13,12,12,12,13,13,12,12,12,12,12,
604.9160 +	12,12,12,12,13,12,12,12,12,13,12,12,13,12,13,12,
604.9161 +	12,13,13,13,12,12,12,12,12,12,12,12,12,13,12,12,
604.9162 +	12,13,12,12,13,13,13,13,12,13,13,13,13,10,11,11,
604.9163 +	12,12,11,12,12,12,12,11,12,12,12,12,11,12,12,12,
604.9164 +	12,12,12,12,12,12,11,11,12,12,12,11,12,12,12,12,
604.9165 +	12,12,12,12,12,12,12,12,12,13,12,12,12,13,13,11,
604.9166 +	12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,
604.9167 +	12,13,13,12,12,12,13,12,12,12,12,12,12,12,12,12,
604.9168 +	12,12,12,12,12,13,12,12,12,12,12,13,12,13,12,13,
604.9169 +	13,12,12,12,12,12,12,12,12,13,12,12,12,12,13,12,
604.9170 +	12,13,12,13,13,12,13,12,13,12,11,11,11,12,12,11,
604.9171 +	12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,
604.9172 +	12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.9173 +	12,12,12,12,13,12,13,12,12,13,13,13,11,12,12,12,
604.9174 +	12,12,12,12,12,12,12,12,12,13,12,12,12,12,13,13,
604.9175 +	12,12,12,13,12,12,12,12,12,12,12,12,13,12,13,12,
604.9176 +	12,12,12,13,12,12,13,12,13,12,13,13,12,13,12,12,
604.9177 +	12,12,12,12,13,13,13,12,12,12,12,13,12,12,13,13,
604.9178 +	13,13,12,13,13,13,12,11,11,11,12,12,11,12,12,12,
604.9179 +	12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9180 +	11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9181 +	12,12,12,13,12,12,13,13,13,11,12,12,12,12,12,12,
604.9182 +	12,12,13,12,12,12,13,12,12,13,12,13,13,12,13,12,
604.9183 +	13,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9184 +	12,12,12,13,12,13,12,13,13,13,12,12,12,12,12,12,
604.9185 +	12,13,12,13,12,12,12,12,13,12,12,13,13,13,12,12,
604.9186 +	13,12,13,12,10,11,11,12,12,11,11,11,12,12,11,11,
604.9187 +	11,12,12,11,12,12,12,12,11,12,12,12,12,11,11,11,
604.9188 +	12,12,11,11,12,12,12,11,12,12,12,12,12,12,12,12,
604.9189 +	12,12,12,12,12,12,11,11,11,12,12,11,12,12,12,12,
604.9190 +	11,12,11,12,12,12,12,12,12,12,11,12,12,12,12,11,
604.9191 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9192 +	12,12,13,12,12,12,12,12,11,12,12,12,12,12,12,12,
604.9193 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9194 +	12,10,11,11,12,12,11,11,12,12,12,11,12,12,12,12,
604.9195 +	11,12,12,12,12,12,12,12,12,12,11,11,12,12,12,12,
604.9196 +	12,12,12,12,12,12,12,12,12,12,12,12,12,13,12,12,
604.9197 +	12,13,13,11,11,11,12,12,12,12,12,12,12,11,12,12,
604.9198 +	12,12,12,12,12,13,13,12,12,12,13,13,12,12,12,12,
604.9199 +	12,12,12,12,12,13,12,12,12,12,13,12,12,13,12,13,
604.9200 +	12,12,13,13,13,12,12,12,12,12,12,12,12,12,13,12,
604.9201 +	12,12,12,12,12,12,13,13,13,12,12,12,13,12,11,11,
604.9202 +	11,12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,
604.9203 +	12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,12,
604.9204 +	12,12,12,12,12,12,12,12,12,13,13,12,12,12,13,13,
604.9205 +	11,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,
604.9206 +	12,12,13,13,12,12,12,13,12,12,12,12,12,12,12,12,
604.9207 +	12,12,13,12,12,12,13,13,12,13,13,13,13,12,13,13,
604.9208 +	13,13,12,12,12,12,12,12,12,12,13,12,12,12,12,13,
604.9209 +	12,12,13,12,13,13,12,13,12,13,12,11,11,11,12,12,
604.9210 +	11,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,
604.9211 +	12,12,12,12,11,12,12,12,12,12,12,12,12,13,12,12,
604.9212 +	12,13,13,12,12,13,12,13,12,12,13,13,13,11,12,12,
604.9213 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,
604.9214 +	13,12,12,12,13,12,12,12,12,12,12,12,12,12,12,13,
604.9215 +	12,12,12,13,13,12,12,13,12,13,12,13,13,13,13,12,
604.9216 +	12,12,12,12,12,12,13,12,13,12,12,12,12,12,12,13,
604.9217 +	13,12,12,12,13,12,12,12,11,11,11,12,12,11,12,12,
604.9218 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.9219 +	12,11,12,12,12,12,12,12,12,12,13,12,12,12,12,13,
604.9220 +	12,12,13,13,13,12,12,12,13,13,11,12,12,12,12,12,
604.9221 +	12,12,12,12,12,12,12,12,12,12,13,12,13,13,12,13,
604.9222 +	12,13,12,12,12,12,12,12,12,12,12,12,13,12,13,12,
604.9223 +	13,13,12,13,13,12,13,12,13,13,13,13,12,12,12,12,
604.9224 +	12,12,12,12,13,12,12,13,12,13,12,12,13,12,13,12,
604.9225 +	12,13,12,13,12,
604.9226 +};
604.9227 +
604.9228 +static const static_codebook _44p8_p4_1 = {
604.9229 +	5, 3125,
604.9230 +	(long *)_vq_lengthlist__44p8_p4_1,
604.9231 +	1, -533725184, 1611661312, 3, 0,
604.9232 +	(long *)_vq_quantlist__44p8_p4_1,
604.9233 +	0
604.9234 +};
604.9235 +
604.9236 +static const long _vq_quantlist__44p8_p5_0[] = {
604.9237 +	2,
604.9238 +	1,
604.9239 +	3,
604.9240 +	0,
604.9241 +	4,
604.9242 +};
604.9243 +
604.9244 +static const long _vq_lengthlist__44p8_p5_0[] = {
604.9245 +	 2, 6, 6, 9, 9, 5, 7, 8,10,11, 5, 8, 7,11,10, 8,
604.9246 +	10,11,12,13, 8,11,10,13,12, 6, 7, 8,10,11, 7, 8,
604.9247 +	10,10,12, 8, 9, 9,12,12,10,10,12,12,14,10,12,12,
604.9248 +	14,13, 6, 8, 7,11,10, 8, 9, 9,12,12, 7,10, 8,12,
604.9249 +	11,10,12,12,13,14,10,12,10,14,12, 9,10,11,11,13,
604.9250 +	10,10,11,11,13,11,12,12,13,14,12,12,13,11,15,13,
604.9251 +	14,14,15,14, 9,11,10,13,11,11,12,12,13,13,10,11,
604.9252 +	10,13,11,13,14,14,15,15,12,13,12,15,11, 6, 8, 9,
604.9253 +	11,12, 8, 9,11,12,13, 8,10,10,13,13,11,12,13,14,
604.9254 +	15,11,12,13,14,14, 9, 9,10,12,13,10,10,12,12,14,
604.9255 +	10,11,11,13,14,12,12,14,14,15,13,13,14,15,15, 9,
604.9256 +	10,10,13,13,10,11,11,13,14,10,11,10,14,13,13,13,
604.9257 +	14,15,15,12,14,13,15,14,12,12,13,13,14,12,13,14,
604.9258 +	13,15,13,14,14,15,15,14,14,15,14,16,15,15,15,16,
604.9259 +	16,12,13,13,14,14,13,14,14,15,15,12,14,13,15,14,
604.9260 +	14,15,15,16,16,14,15,14,16,14, 6, 9, 8,12,11, 8,
604.9261 +	10,10,13,13, 8,11, 9,13,12,11,12,12,14,14,11,13,
604.9262 +	12,15,14, 9,10,10,13,13,10,10,11,13,14,10,12,11,
604.9263 +	14,13,12,13,14,14,15,13,13,13,15,14, 9,10, 9,13,
604.9264 +	12,10,11,11,14,13,10,12,10,14,12,13,14,13,15,15,
604.9265 +	12,14,12,15,14,12,13,13,14,14,13,13,13,14,15,13,
604.9266 +	14,14,15,15,14,14,15,14,16,14,15,15,16,16,12,13,
604.9267 +	12,14,13,13,14,14,15,15,12,14,13,15,13,15,15,15,
604.9268 +	16,16,14,15,14,16,14,11,12,12,13,14,12,13,14,14,
604.9269 +	16,12,13,13,15,15,14,14,16,15,17,14,15,15,16,16,
604.9270 +	12,13,14,14,15,13,13,15,15,16,14,14,14,15,16,15,
604.9271 +	15,16,16,17,15,15,16,16,17,13,13,13,15,15,14,14,
604.9272 +	15,15,16,13,14,14,15,16,15,15,16,16,17,15,16,15,
604.9273 +	17,16,14,15,15,16,16,15,15,16,16,17,15,16,16,17,
604.9274 +	17,16,16,17,16,18,16,17,17,17,17,15,15,15,16,16,
604.9275 +	15,16,16,17,17,15,16,16,17,16,16,17,17,18,18,16,
604.9276 +	17,16,17,16,11,12,12,15,13,13,13,13,15,15,12,14,
604.9277 +	13,16,14,14,15,15,16,16,14,15,14,17,15,13,13,13,
604.9278 +	15,14,13,14,14,16,15,14,14,14,16,15,15,15,16,16,
604.9279 +	17,15,16,15,17,16,12,14,13,15,14,14,14,14,16,15,
604.9280 +	13,14,13,16,15,15,16,16,17,16,15,16,15,17,16,15,
604.9281 +	15,15,16,16,15,15,16,16,17,15,16,16,17,17,16,16,
604.9282 +	17,17,17,17,17,17,18,17,14,15,15,16,16,15,16,16,
604.9283 +	17,16,15,16,15,17,16,17,17,17,18,17,16,17,16,18,
604.9284 +	16, 6, 9, 9,12,12, 8,10,10,12,13, 8,10,10,13,12,
604.9285 +	10,12,12,14,15,11,13,12,15,14, 8, 9,10,12,13, 9,
604.9286 +	10,11,13,14,10,11,11,14,13,12,12,13,14,15,12,13,
604.9287 +	13,15,15, 8,10,10,13,13,10,11,11,13,14,10,12,10,
604.9288 +	14,13,12,13,13,15,15,12,14,13,15,14,11,12,12,13,
604.9289 +	14,12,12,13,13,15,12,13,13,15,15,14,13,15,14,16,
604.9290 +	14,15,15,16,16,12,13,13,14,14,13,13,14,15,14,12,
604.9291 +	14,13,15,14,14,15,15,16,15,14,15,14,16,14, 7, 9,
604.9292 +	10,12,12, 9,10,11,13,14, 9,11,10,13,13,11,12,13,
604.9293 +	14,15,12,13,13,15,14, 9,10,11,12,13,10,10,12,13,
604.9294 +	14,11,11,12,14,14,12,12,14,14,15,13,13,14,15,15,
604.9295 +	 9,11,11,13,13,11,12,12,14,14,10,12,10,14,13,13,
604.9296 +	14,14,15,15,13,14,13,16,14,12,12,13,14,15,13,13,
604.9297 +	14,14,16,13,14,14,15,15,14,14,15,14,17,14,15,15,
604.9298 +	16,16,12,13,13,15,14,13,14,14,15,15,13,14,13,16,
604.9299 +	14,15,15,15,16,16,14,15,14,16,14, 7,10, 9,13,12,
604.9300 +	10,11,12,12,14,10,12,11,14,12,12,13,13,14,15,12,
604.9301 +	14,13,15,14, 9,11,10,13,13,10,11,12,13,14,12,13,
604.9302 +	12,15,13,13,13,14,13,15,13,14,14,16,15,10,11,11,
604.9303 +	13,13,12,12,13,14,14,11,12,11,14,13,14,14,14,15,
604.9304 +	16,13,14,13,16,13,12,13,13,14,14,12,13,13,14,15,
604.9305 +	14,14,14,15,15,14,13,15,13,16,15,15,15,17,16,13,
604.9306 +	13,13,14,14,14,14,14,15,15,12,13,13,15,14,15,16,
604.9307 +	16,16,16,14,15,14,16,13,11,12,13,14,15,12,13,14,
604.9308 +	15,16,13,14,14,15,15,14,14,15,15,17,14,15,15,16,
604.9309 +	16,13,13,14,14,15,13,13,15,14,16,14,14,15,15,16,
604.9310 +	15,14,16,15,17,15,16,16,16,17,13,14,14,15,15,14,
604.9311 +	14,15,16,16,13,15,14,16,16,15,16,16,17,17,15,16,
604.9312 +	15,17,16,14,15,15,15,17,15,15,16,15,17,15,16,16,
604.9313 +	16,17,16,16,17,16,18,17,17,17,17,18,15,15,15,17,
604.9314 +	16,15,16,16,17,17,15,16,16,17,16,16,17,17,18,18,
604.9315 +	16,17,16,18,17,11,13,12,15,14,13,13,14,15,15,13,
604.9316 +	14,13,16,14,15,15,15,16,16,15,16,15,17,16,13,14,
604.9317 +	13,15,14,13,13,14,15,15,14,15,14,16,15,15,15,16,
604.9318 +	16,16,15,16,15,18,16,13,14,14,15,15,14,15,15,15,
604.9319 +	16,13,15,13,16,15,15,16,16,17,17,15,16,15,17,16,
604.9320 +	15,15,15,16,16,15,15,15,16,17,16,16,16,17,16,16,
604.9321 +	16,17,16,17,17,17,17,18,17,15,15,15,16,16,16,16,
604.9322 +	16,17,17,15,16,15,17,16,17,17,17,18,18,16,17,16,
604.9323 +	17,15, 6, 9, 9,12,12, 8,10,10,12,13, 8,10,10,13,
604.9324 +	12,11,12,13,14,15,10,12,12,14,14, 9,10,10,13,13,
604.9325 +	10,10,12,13,14,10,11,11,14,13,12,13,14,14,15,12,
604.9326 +	13,13,15,15, 8,10, 9,13,12,10,11,11,13,14, 9,11,
604.9327 +	10,14,13,12,13,13,15,15,12,13,12,15,14,12,13,13,
604.9328 +	14,14,12,13,13,14,15,13,14,14,14,15,14,14,15,14,
604.9329 +	16,14,15,15,16,16,11,12,12,14,13,13,13,13,15,15,
604.9330 +	12,13,12,15,13,14,15,15,16,16,14,15,14,16,14, 7,
604.9331 +	 9,10,12,13,10,10,12,12,14,10,12,11,14,13,12,13,
604.9332 +	14,14,15,12,13,13,15,14,10,11,11,13,13,11,11,12,
604.9333 +	13,14,12,13,12,14,14,13,13,14,13,16,14,14,14,15,
604.9334 +	15, 9,10,11,13,14,12,12,13,13,15,10,12,10,14,13,
604.9335 +	13,14,14,15,16,13,14,13,15,13,13,14,13,14,15,12,
604.9336 +	13,13,14,15,14,14,14,15,15,14,13,15,13,16,15,16,
604.9337 +	16,16,16,12,13,13,14,14,14,14,14,15,15,12,13,13,
604.9338 +	15,14,15,15,16,16,16,14,15,13,16,13, 7,10, 9,12,
604.9339 +	12, 9,10,11,13,13, 9,11,10,14,13,12,13,13,14,15,
604.9340 +	11,13,12,15,14, 9,11,11,13,13,10,10,12,13,14,11,
604.9341 +	12,12,14,14,13,13,14,14,16,13,14,14,16,15, 9,11,
604.9342 +	10,13,12,11,12,11,14,14,10,12,10,14,13,13,14,13,
604.9343 +	15,15,12,14,12,16,14,12,13,13,14,15,13,13,14,14,
604.9344 +	16,13,14,14,15,15,14,14,15,14,16,15,15,15,16,16,
604.9345 +	12,13,12,15,14,13,14,14,15,15,12,14,13,16,14,14,
604.9346 +	15,15,16,16,14,15,14,17,14,11,12,13,14,15,13,13,
604.9347 +	14,14,16,13,14,13,15,15,15,15,16,16,17,15,15,15,
604.9348 +	16,16,13,14,13,15,15,13,13,15,15,16,14,15,15,16,
604.9349 +	16,15,15,16,15,17,16,16,16,17,17,13,13,14,14,15,
604.9350 +	14,14,15,15,16,13,14,13,15,15,15,16,16,16,17,15,
604.9351 +	16,15,16,16,15,15,15,16,16,15,15,16,16,17,16,16,
604.9352 +	16,17,17,16,16,17,16,18,17,17,17,18,18,15,15,15,
604.9353 +	16,16,16,16,16,17,17,15,15,15,16,16,17,17,17,17,
604.9354 +	18,16,16,16,17,15,11,13,12,15,14,13,13,14,15,15,
604.9355 +	12,14,13,16,14,14,15,15,16,16,14,15,14,16,15,13,
604.9356 +	14,14,15,15,13,14,14,16,16,14,15,14,16,16,15,15,
604.9357 +	16,17,17,15,16,16,17,17,13,14,13,15,14,14,14,14,
604.9358 +	16,15,13,15,13,16,14,15,16,15,17,16,15,16,14,17,
604.9359 +	15,14,16,15,16,17,15,16,16,16,17,15,16,16,17,17,
604.9360 +	16,16,17,17,18,16,17,17,18,17,14,15,15,17,15,15,
604.9361 +	16,16,17,16,15,16,15,17,15,16,17,17,18,17,16,17,
604.9362 +	16,18,15,10,12,12,14,14,12,13,13,15,15,12,13,13,
604.9363 +	15,15,13,14,14,15,16,14,15,14,16,16,12,13,13,15,
604.9364 +	15,12,13,14,15,15,13,14,14,15,15,14,14,15,16,17,
604.9365 +	14,15,15,17,16,12,13,13,15,15,13,14,14,15,16,13,
604.9366 +	14,14,16,15,14,15,15,16,17,14,15,15,17,16,13,14,
604.9367 +	14,15,16,14,14,15,15,16,14,15,15,16,16,15,15,16,
604.9368 +	16,17,15,16,16,17,17,14,15,15,16,16,15,15,15,16,
604.9369 +	16,15,15,15,16,16,16,17,16,17,17,16,16,16,18,16,
604.9370 +	11,12,12,14,14,12,13,14,15,15,12,13,13,15,15,13,
604.9371 +	14,15,16,16,14,15,15,16,16,12,13,13,15,15,13,13,
604.9372 +	14,15,16,13,14,14,15,16,14,14,15,16,17,15,15,15,
604.9373 +	16,17,12,13,13,15,15,13,14,14,15,16,13,14,14,16,
604.9374 +	15,15,15,15,16,17,15,16,15,17,16,14,14,15,15,16,
604.9375 +	14,14,15,15,17,15,15,16,16,17,15,15,16,15,18,16,
604.9376 +	16,16,17,17,14,15,15,16,16,15,16,16,17,17,15,15,
604.9377 +	15,17,16,16,17,16,17,17,16,16,16,18,16,11,12,12,
604.9378 +	14,14,13,13,14,15,15,13,14,13,15,15,14,15,15,16,
604.9379 +	16,14,15,15,16,16,12,13,13,15,15,13,13,14,15,15,
604.9380 +	14,14,14,16,15,15,15,15,15,16,15,16,15,17,16,12,
604.9381 +	13,13,15,15,14,14,15,15,16,13,14,13,16,15,15,15,
604.9382 +	16,16,17,15,16,15,17,15,14,15,14,16,16,14,15,15,
604.9383 +	16,16,15,16,15,17,16,15,15,16,15,17,16,17,16,17,
604.9384 +	17,14,15,15,16,16,15,16,16,16,17,14,15,15,16,16,
604.9385 +	16,17,17,17,18,16,16,16,17,16,12,13,13,15,15,13,
604.9386 +	13,14,15,16,13,14,14,16,15,14,15,15,16,17,14,15,
604.9387 +	15,17,16,13,14,14,15,16,14,14,15,15,17,14,15,15,
604.9388 +	16,16,15,14,16,15,17,15,16,16,17,17,13,14,14,16,
604.9389 +	16,14,15,15,16,16,14,15,14,16,16,15,16,16,17,17,
604.9390 +	15,16,15,17,16,15,15,16,15,17,15,15,16,15,17,15,
604.9391 +	16,16,16,17,16,15,17,15,18,17,17,17,17,17,15,15,
604.9392 +	15,17,17,16,16,16,17,17,15,16,15,17,17,16,17,17,
604.9393 +	18,18,16,17,15,18,15,11,12,12,15,15,13,13,15,14,
604.9394 +	16,13,14,13,16,14,15,15,16,16,17,15,16,15,17,15,
604.9395 +	12,14,13,16,14,13,13,14,14,16,14,15,14,16,15,15,
604.9396 +	15,16,15,17,16,16,16,17,16,12,13,14,15,16,15,15,
604.9397 +	15,15,16,13,15,13,16,14,16,16,16,17,17,15,16,15,
604.9398 +	17,15,15,16,15,16,15,14,14,15,16,16,16,16,16,17,
604.9399 +	16,15,15,16,15,17,17,17,17,18,17,15,15,15,16,16,
604.9400 +	16,16,16,16,17,14,15,15,17,16,17,17,17,17,18,15,
604.9401 +	16,15,18,14,10,12,12,14,14,12,13,13,15,15,12,13,
604.9402 +	13,15,15,14,14,15,15,16,13,15,14,16,16,12,13,13,
604.9403 +	15,15,13,14,14,15,16,13,14,14,15,15,14,15,15,16,
604.9404 +	17,14,15,15,17,16,12,13,13,15,15,13,14,14,15,15,
604.9405 +	12,14,13,15,15,14,15,15,16,17,14,15,14,17,15,14,
604.9406 +	15,15,16,16,14,15,15,16,17,15,15,15,17,16,16,16,
604.9407 +	16,16,17,16,16,16,17,17,13,14,14,16,15,14,15,15,
604.9408 +	16,16,14,15,14,16,16,15,16,16,17,17,15,16,15,17,
604.9409 +	16,11,12,12,14,15,13,13,14,14,15,13,14,13,15,15,
604.9410 +	14,15,15,16,16,14,15,15,16,16,12,14,13,15,15,13,
604.9411 +	13,14,15,16,14,15,14,16,15,15,15,16,15,17,15,16,
604.9412 +	16,17,16,12,13,13,15,15,14,14,15,15,16,13,14,13,
604.9413 +	16,15,15,15,16,16,17,15,15,15,16,16,14,15,15,16,
604.9414 +	16,14,15,15,16,16,15,16,16,17,17,16,16,16,16,17,
604.9415 +	16,17,17,18,17,14,14,15,15,16,15,15,16,16,17,14,
604.9416 +	15,15,16,16,16,16,16,17,17,15,16,15,17,15,11,12,
604.9417 +	12,14,14,12,13,14,15,15,12,13,13,15,15,14,15,15,
604.9418 +	16,16,13,15,14,16,16,12,13,13,15,15,13,14,14,15,
604.9419 +	16,13,14,14,16,16,15,15,15,16,17,15,15,15,17,16,
604.9420 +	12,13,13,15,15,13,14,14,16,15,13,14,13,16,15,15,
604.9421 +	16,15,17,17,14,15,14,17,16,14,15,15,16,16,15,15,
604.9422 +	16,16,17,15,16,16,17,17,16,16,16,16,18,16,17,16,
604.9423 +	18,17,14,15,14,16,15,15,15,15,17,16,14,15,14,17,
604.9424 +	15,16,17,16,17,17,15,16,15,17,15,11,12,12,15,15,
604.9425 +	13,13,15,14,16,13,15,13,16,14,15,15,16,15,17,15,
604.9426 +	16,15,17,16,12,14,13,15,15,13,13,15,15,16,15,15,
604.9427 +	15,16,15,15,15,16,15,17,16,16,16,17,16,12,13,14,
604.9428 +	15,16,14,14,15,15,16,13,14,13,16,14,16,16,16,16,
604.9429 +	17,15,16,15,17,15,15,16,15,16,16,14,15,15,16,16,
604.9430 +	16,16,16,17,16,15,15,16,15,17,17,17,17,18,17,15,
604.9431 +	15,15,15,16,16,16,16,16,17,14,15,14,16,15,17,17,
604.9432 +	17,17,18,15,16,15,17,15,12,13,13,15,15,13,14,14,
604.9433 +	15,16,13,14,14,16,15,14,15,15,16,17,14,15,15,17,
604.9434 +	16,13,14,14,16,15,13,14,15,16,16,14,15,15,16,16,
604.9435 +	15,15,16,16,17,15,16,16,17,17,13,14,13,16,15,14,
604.9436 +	15,15,16,16,13,15,14,16,15,15,16,16,17,17,15,16,
604.9437 +	14,17,15,15,15,16,17,17,15,15,16,16,17,16,16,16,
604.9438 +	17,17,16,15,17,16,18,17,17,17,18,18,15,15,15,17,
604.9439 +	14,16,16,16,17,16,15,16,15,17,15,16,17,17,18,17,
604.9440 +	16,17,15,18,15,
604.9441 +};
604.9442 +
604.9443 +static const static_codebook _44p8_p5_0 = {
604.9444 +	5, 3125,
604.9445 +	(long *)_vq_lengthlist__44p8_p5_0,
604.9446 +	1, -528744448, 1616642048, 3, 0,
604.9447 +	(long *)_vq_quantlist__44p8_p5_0,
604.9448 +	0
604.9449 +};
604.9450 +
604.9451 +static const long _vq_quantlist__44p8_p5_1[] = {
604.9452 +	3,
604.9453 +	2,
604.9454 +	4,
604.9455 +	1,
604.9456 +	5,
604.9457 +	0,
604.9458 +	6,
604.9459 +};
604.9460 +
604.9461 +static const long _vq_lengthlist__44p8_p5_1[] = {
604.9462 +	 2, 3, 3, 3, 3, 3, 3,
604.9463 +};
604.9464 +
604.9465 +static const static_codebook _44p8_p5_1 = {
604.9466 +	1, 7,
604.9467 +	(long *)_vq_lengthlist__44p8_p5_1,
604.9468 +	1, -533200896, 1611661312, 3, 0,
604.9469 +	(long *)_vq_quantlist__44p8_p5_1,
604.9470 +	0
604.9471 +};
604.9472 +
604.9473 +static const long _vq_quantlist__44p8_p6_0[] = {
604.9474 +	1,
604.9475 +	0,
604.9476 +	2,
604.9477 +};
604.9478 +
604.9479 +static const long _vq_lengthlist__44p8_p6_0[] = {
604.9480 +	 2, 6, 6, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 7, 9, 7,
604.9481 +	 9, 9, 6, 7, 7, 8, 9, 9, 7, 9, 7, 6, 8, 8, 8, 9,
604.9482 +	10, 8, 9, 9, 8, 9,10, 9, 9,10,10,10,10, 8, 9, 9,
604.9483 +	10,10,11, 9,10,10, 6, 8, 8, 8, 9, 9, 8,10, 9, 8,
604.9484 +	 9, 9, 9,10,10,10,11,10, 8,10, 9,10,11,10, 9,11,
604.9485 +	 9, 6, 8, 8, 7, 9, 9, 7, 9, 9, 7, 9, 9, 8, 9,10,
604.9486 +	 9,10,10, 8, 9, 9, 9,10,10, 9,10, 9, 7, 9, 9, 9,
604.9487 +	 9,10, 9,10,10, 9, 9,10,10, 9,11,10,11,11, 9,10,
604.9488 +	10,10,11,11,10,11,10, 6, 9, 8, 9, 9,10, 9,10, 9,
604.9489 +	 8,10,10, 9, 9,10,10,11,11, 9,10,10,10,11,11, 9,
604.9490 +	11, 9, 6, 8, 8, 7, 9, 9, 7, 9, 9, 8, 9, 9, 9, 9,
604.9491 +	10, 9,10,10, 7, 9, 9, 9,10,10, 8,10, 9, 6, 8, 9,
604.9492 +	 9, 9,10, 9,10, 9, 9,10,10, 9, 9,11,10,11,11, 8,
604.9493 +	 9,10,10,11,11, 9,10, 9, 7, 9, 9, 9,10,10, 9,10,
604.9494 +	 9, 9,10,10,10,10,11,10,11,11, 9,10, 9,10,11,11,
604.9495 +	10,11, 9,
604.9496 +};
604.9497 +
604.9498 +static const static_codebook _44p8_p6_0 = {
604.9499 +	5, 243,
604.9500 +	(long *)_vq_lengthlist__44p8_p6_0,
604.9501 +	1, -527106048, 1620377600, 2, 0,
604.9502 +	(long *)_vq_quantlist__44p8_p6_0,
604.9503 +	0
604.9504 +};
604.9505 +
604.9506 +static const long _vq_quantlist__44p8_p6_1[] = {
604.9507 +	1,
604.9508 +	0,
604.9509 +	2,
604.9510 +};
604.9511 +
604.9512 +static const long _vq_lengthlist__44p8_p6_1[] = {
604.9513 +	 4, 7, 7, 7, 7, 8, 7, 8, 7, 7, 7, 8, 7, 8, 8, 8,
604.9514 +	 8, 8, 7, 8, 7, 8, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8,
604.9515 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 8,
604.9516 +	 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.9517 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9,
604.9518 +	 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.9519 +	 8, 8, 9, 8, 8, 8, 8, 9, 9, 8, 9, 8, 8, 8, 8, 8,
604.9520 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8,
604.9521 +	 8, 8, 9, 9, 8, 9, 9, 7, 8, 8, 8, 8, 8, 8, 8, 8,
604.9522 +	 8, 8, 8, 8, 8, 9, 8, 9, 8, 8, 8, 8, 8, 9, 9, 8,
604.9523 +	 9, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.9524 +	 9, 8, 9, 9, 8, 8, 8, 8, 9, 8, 8, 9, 8, 7, 8, 8,
604.9525 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8,
604.9526 +	 8, 8, 8, 9, 9, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.9527 +	 8, 8, 8, 8, 8, 9, 9, 8, 9, 9, 8, 8, 8, 8, 9, 9,
604.9528 +	 8, 9, 8,
604.9529 +};
604.9530 +
604.9531 +static const static_codebook _44p8_p6_1 = {
604.9532 +	5, 243,
604.9533 +	(long *)_vq_lengthlist__44p8_p6_1,
604.9534 +	1, -530841600, 1616642048, 2, 0,
604.9535 +	(long *)_vq_quantlist__44p8_p6_1,
604.9536 +	0
604.9537 +};
604.9538 +
604.9539 +static const long _vq_quantlist__44p8_p7_0[] = {
604.9540 +	1,
604.9541 +	0,
604.9542 +	2,
604.9543 +};
604.9544 +
604.9545 +static const long _vq_lengthlist__44p8_p7_0[] = {
604.9546 +	 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.9547 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9548 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9549 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9550 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9551 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9552 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9553 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9554 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9555 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9556 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9557 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9558 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9559 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9560 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9561 +	 9, 9, 9,
604.9562 +};
604.9563 +
604.9564 +static const static_codebook _44p8_p7_0 = {
604.9565 +	5, 243,
604.9566 +	(long *)_vq_lengthlist__44p8_p7_0,
604.9567 +	1, -512202240, 1635281408, 2, 0,
604.9568 +	(long *)_vq_quantlist__44p8_p7_0,
604.9569 +	0
604.9570 +};
604.9571 +
604.9572 +static const long _vq_quantlist__44p8_p7_1[] = {
604.9573 +	2,
604.9574 +	1,
604.9575 +	3,
604.9576 +	0,
604.9577 +	4,
604.9578 +};
604.9579 +
604.9580 +static const long _vq_lengthlist__44p8_p7_1[] = {
604.9581 +	 1, 7, 7,12,12, 5,11,12,12,12, 5,12,11,12,12,12,
604.9582 +	12,12,12,12,12,13,13,13,13, 7,11,11,13,13,13,12,
604.9583 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9584 +	13,13, 7,13,10,13,13,13,13,13,13,13,12,13,13,13,
604.9585 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9586 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9587 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9588 +	13,13,13,13,13,13,13,13,13,13,13,13,13, 7,13,12,
604.9589 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9590 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9591 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,
604.9592 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9593 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9594 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9595 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9596 +	13,13,13,13,13,13,13,13,13,13, 8,13,13,13,13,13,
604.9597 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9598 +	13,13,13,12,13,13,13,13,13,13,13,13,13,13,13,13,
604.9599 +	13,13,13,13,13,13,13,13,13,13,13,13,12,13,13,13,
604.9600 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9601 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9602 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9603 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9604 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9605 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9606 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9607 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9608 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9609 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9610 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9611 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9612 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9613 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9614 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9615 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9616 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9617 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9618 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9619 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9620 +	13, 8,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9621 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9622 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9623 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9624 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9625 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9626 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9627 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9628 +	13,13,13,12,13,13,13,13,13,13,13,13,13,13,13,13,
604.9629 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9630 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9631 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9632 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9633 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9634 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9635 +	13,13,13,13,13,13,13,13,13,13,13,10,13,13,13,13,
604.9636 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9637 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9638 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9639 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9640 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9641 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9642 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9643 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9644 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9645 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9646 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9647 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9648 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9649 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9650 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9651 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9652 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9653 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9654 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9655 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9656 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9657 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9658 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9659 +	13,13, 8,13,12,13,13,13,13,13,13,13,13,13,13,13,
604.9660 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9661 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9662 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9663 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9664 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9665 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9666 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,11,
604.9667 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9668 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9669 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9670 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9671 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9672 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9673 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9674 +	13,13,13,13,13,13,13,13,13,13,13,13,11,13,13,13,
604.9675 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9676 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9677 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9678 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9679 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9680 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9681 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9682 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9683 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9684 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9685 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9686 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9687 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9688 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9689 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9690 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9691 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9692 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9693 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9694 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9695 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9696 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9697 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9698 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9699 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9700 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9701 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9702 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9703 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9704 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9705 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9706 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9707 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9708 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9709 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9710 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9711 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9712 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9713 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9714 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9715 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9716 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9717 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9718 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9719 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9720 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9721 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9722 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9723 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9724 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9725 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9726 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9727 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9728 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9729 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9730 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9731 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9732 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9733 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9734 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9735 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9736 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9737 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9738 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9739 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9740 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9741 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9742 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9743 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9744 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9745 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9746 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9747 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9748 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9749 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9750 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9751 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9752 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9753 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9754 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9755 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9756 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9757 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9758 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9759 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9760 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9761 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9762 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9763 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9764 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9765 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9766 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9767 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9768 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9769 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9770 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9771 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9772 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9773 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9774 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9775 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.9776 +	13,13,13,13,13,
604.9777 +};
604.9778 +
604.9779 +static const static_codebook _44p8_p7_1 = {
604.9780 +	5, 3125,
604.9781 +	(long *)_vq_lengthlist__44p8_p7_1,
604.9782 +	1, -514619392, 1630767104, 3, 0,
604.9783 +	(long *)_vq_quantlist__44p8_p7_1,
604.9784 +	0
604.9785 +};
604.9786 +
604.9787 +static const long _vq_quantlist__44p8_p7_2[] = {
604.9788 +	12,
604.9789 +	11,
604.9790 +	13,
604.9791 +	10,
604.9792 +	14,
604.9793 +	9,
604.9794 +	15,
604.9795 +	8,
604.9796 +	16,
604.9797 +	7,
604.9798 +	17,
604.9799 +	6,
604.9800 +	18,
604.9801 +	5,
604.9802 +	19,
604.9803 +	4,
604.9804 +	20,
604.9805 +	3,
604.9806 +	21,
604.9807 +	2,
604.9808 +	22,
604.9809 +	1,
604.9810 +	23,
604.9811 +	0,
604.9812 +	24,
604.9813 +};
604.9814 +
604.9815 +static const long _vq_lengthlist__44p8_p7_2[] = {
604.9816 +	 1, 3, 2, 4, 5, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
604.9817 +	12,13,13,14,14,15,15,15,15,
604.9818 +};
604.9819 +
604.9820 +static const static_codebook _44p8_p7_2 = {
604.9821 +	1, 25,
604.9822 +	(long *)_vq_lengthlist__44p8_p7_2,
604.9823 +	1, -518864896, 1620639744, 5, 0,
604.9824 +	(long *)_vq_quantlist__44p8_p7_2,
604.9825 +	0
604.9826 +};
604.9827 +
604.9828 +static const long _vq_quantlist__44p8_p7_3[] = {
604.9829 +	12,
604.9830 +	11,
604.9831 +	13,
604.9832 +	10,
604.9833 +	14,
604.9834 +	9,
604.9835 +	15,
604.9836 +	8,
604.9837 +	16,
604.9838 +	7,
604.9839 +	17,
604.9840 +	6,
604.9841 +	18,
604.9842 +	5,
604.9843 +	19,
604.9844 +	4,
604.9845 +	20,
604.9846 +	3,
604.9847 +	21,
604.9848 +	2,
604.9849 +	22,
604.9850 +	1,
604.9851 +	23,
604.9852 +	0,
604.9853 +	24,
604.9854 +};
604.9855 +
604.9856 +static const long _vq_lengthlist__44p8_p7_3[] = {
604.9857 +	 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.9858 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.9859 +};
604.9860 +
604.9861 +static const static_codebook _44p8_p7_3 = {
604.9862 +	1, 25,
604.9863 +	(long *)_vq_lengthlist__44p8_p7_3,
604.9864 +	1, -529006592, 1611661312, 5, 0,
604.9865 +	(long *)_vq_quantlist__44p8_p7_3,
604.9866 +	0
604.9867 +};
604.9868 +
604.9869 +static const long _huff_lengthlist__44p8_short[] = {
604.9870 +	 3, 9,15,17,20,21,22,23, 5, 5, 7, 9,11,13,17,20,
604.9871 +	 9, 5, 5, 6, 8,10,15,18,11, 7, 5, 4, 6, 9,13,17,
604.9872 +	14, 9, 7, 5, 6, 7,10,14,17,10, 8, 6, 6, 4, 5, 8,
604.9873 +	20,14,13,10, 8, 4, 3, 4,23,17,16,14,12, 6, 4, 4,
604.9874 +};
604.9875 +
604.9876 +static const static_codebook _huff_book__44p8_short = {
604.9877 +	2, 64,
604.9878 +	(long *)_huff_lengthlist__44p8_short,
604.9879 +	0, 0, 0, 0, 0,
604.9880 +	NULL,
604.9881 +	0
604.9882 +};
604.9883 +
604.9884 +static const long _vq_quantlist__44p9_l0_0[] = {
604.9885 +	6,
604.9886 +	5,
604.9887 +	7,
604.9888 +	4,
604.9889 +	8,
604.9890 +	3,
604.9891 +	9,
604.9892 +	2,
604.9893 +	10,
604.9894 +	1,
604.9895 +	11,
604.9896 +	0,
604.9897 +	12,
604.9898 +};
604.9899 +
604.9900 +static const long _vq_lengthlist__44p9_l0_0[] = {
604.9901 +	 2, 5, 5, 7, 6, 8, 8, 9, 9,10,10,11,11, 4, 5, 5,
604.9902 +	 6, 7, 8, 8, 9, 9,10,10,11,10, 4, 5, 5, 7, 6, 8,
604.9903 +	 8, 9, 9,10,10,10,10, 6, 6, 7, 6, 7, 8, 8, 9, 9,
604.9904 +	10, 9,11, 9, 6, 6, 6, 7, 6, 8, 8, 9, 9, 9,10, 9,
604.9905 +	11, 7, 7, 8, 8, 8, 8, 9, 9, 9,10, 9,11, 9, 7, 8,
604.9906 +	 8, 8, 8, 9, 8, 9, 9, 9,10, 9,11, 8, 9, 9, 9, 9,
604.9907 +	 9, 9,10,10,11,10,12,10, 8, 9, 9, 9, 9, 9, 9,10,
604.9908 +	 9,10,11,11,12, 9,10,10,10,10,10,10,10,11,11,11,
604.9909 +	11,12, 9,10,10,10,10,11,10,11,10,11,11,12,11,11,
604.9910 +	11,11,11,11,11,11,11,12,11,12,11,12,11,11,11,11,
604.9911 +	11,11,11,12,11,12,11,12,11,
604.9912 +};
604.9913 +
604.9914 +static const static_codebook _44p9_l0_0 = {
604.9915 +	2, 169,
604.9916 +	(long *)_vq_lengthlist__44p9_l0_0,
604.9917 +	1, -526516224, 1616117760, 4, 0,
604.9918 +	(long *)_vq_quantlist__44p9_l0_0,
604.9919 +	0
604.9920 +};
604.9921 +
604.9922 +static const long _vq_quantlist__44p9_l0_1[] = {
604.9923 +	2,
604.9924 +	1,
604.9925 +	3,
604.9926 +	0,
604.9927 +	4,
604.9928 +};
604.9929 +
604.9930 +static const long _vq_lengthlist__44p9_l0_1[] = {
604.9931 +	 4, 4, 4, 5, 5, 4, 4, 5, 5, 5, 4, 5, 4, 5, 5, 5,
604.9932 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.9933 +};
604.9934 +
604.9935 +static const static_codebook _44p9_l0_1 = {
604.9936 +	2, 25,
604.9937 +	(long *)_vq_lengthlist__44p9_l0_1,
604.9938 +	1, -533725184, 1611661312, 3, 0,
604.9939 +	(long *)_vq_quantlist__44p9_l0_1,
604.9940 +	0
604.9941 +};
604.9942 +
604.9943 +static const long _vq_quantlist__44p9_l1_0[] = {
604.9944 +	2,
604.9945 +	1,
604.9946 +	3,
604.9947 +	0,
604.9948 +	4,
604.9949 +};
604.9950 +
604.9951 +static const long _vq_lengthlist__44p9_l1_0[] = {
604.9952 +	 1, 2, 3, 5, 9, 9, 4, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.9953 +	 9,10,10,10,10,10,10,10,10,
604.9954 +};
604.9955 +
604.9956 +static const static_codebook _44p9_l1_0 = {
604.9957 +	2, 25,
604.9958 +	(long *)_vq_lengthlist__44p9_l1_0,
604.9959 +	1, -514619392, 1630767104, 3, 0,
604.9960 +	(long *)_vq_quantlist__44p9_l1_0,
604.9961 +	0
604.9962 +};
604.9963 +
604.9964 +static const long _huff_lengthlist__44p9_lfe[] = {
604.9965 +	 1, 1,
604.9966 +};
604.9967 +
604.9968 +static const static_codebook _huff_book__44p9_lfe = {
604.9969 +	1, 2,
604.9970 +	(long *)_huff_lengthlist__44p9_lfe,
604.9971 +	0, 0, 0, 0, 0,
604.9972 +	NULL,
604.9973 +	0
604.9974 +};
604.9975 +
604.9976 +static const long _huff_lengthlist__44p9_long[] = {
604.9977 +	 3, 3, 3, 3, 3, 3, 3, 3,
604.9978 +};
604.9979 +
604.9980 +static const static_codebook _huff_book__44p9_long = {
604.9981 +	1, 8,
604.9982 +	(long *)_huff_lengthlist__44p9_long,
604.9983 +	0, 0, 0, 0, 0,
604.9984 +	NULL,
604.9985 +	0
604.9986 +};
604.9987 +
604.9988 +static const long _vq_quantlist__44p9_p1_0[] = {
604.9989 +	1,
604.9990 +	0,
604.9991 +	2,
604.9992 +};
604.9993 +
604.9994 +static const long _vq_lengthlist__44p9_p1_0[] = {
604.9995 +	 1, 5, 5, 4, 8, 8, 4, 8, 8, 5, 7, 8, 8, 9,10, 8,
604.9996 +	10,10, 5, 8, 7, 8,10,10, 8,10, 9, 7, 9, 9, 9,11,
604.9997 +	11, 9,11,11, 9,11,11,11,12,13,11,13,13, 9,11,11,
604.9998 +	11,13,13,11,13,13, 7, 9, 9, 9,11,11, 9,11,11, 9,
604.9999 +	11,11,11,13,13,11,13,13, 9,11,11,11,13,13,11,13,
604.10000 +	12, 5, 9, 9, 9,11,11, 9,11,11, 9,11,11,11,12,13,
604.10001 +	11,13,13, 9,11,11,11,13,13,11,13,13, 9,11,12,11,
604.10002 +	13,13,12,13,13,11,12,13,13,14,15,13,14,14,12,13,
604.10003 +	13,13,15,15,13,15,14, 8,10,10,11,13,13,12,14,13,
604.10004 +	11,12,12,13,14,15,13,15,15,11,12,12,13,15,15,13,
604.10005 +	15,14, 5, 9, 9, 9,11,11, 9,11,11, 9,11,11,11,13,
604.10006 +	13,11,13,13, 9,11,10,11,13,13,11,13,12, 8,10,10,
604.10007 +	11,13,13,12,13,13,11,12,12,13,14,15,14,15,15,10,
604.10008 +	12,12,13,14,15,13,15,14, 9,12,11,12,13,13,11,13,
604.10009 +	13,12,13,13,13,15,15,13,14,15,11,13,12,13,15,14,
604.10010 +	13,15,14,
604.10011 +};
604.10012 +
604.10013 +static const static_codebook _44p9_p1_0 = {
604.10014 +	5, 243,
604.10015 +	(long *)_vq_lengthlist__44p9_p1_0,
604.10016 +	1, -535822336, 1611661312, 2, 0,
604.10017 +	(long *)_vq_quantlist__44p9_p1_0,
604.10018 +	0
604.10019 +};
604.10020 +
604.10021 +static const long _vq_quantlist__44p9_p2_0[] = {
604.10022 +	2,
604.10023 +	1,
604.10024 +	3,
604.10025 +	0,
604.10026 +	4,
604.10027 +};
604.10028 +
604.10029 +static const long _vq_lengthlist__44p9_p2_0[] = {
604.10030 +	 4, 6, 6, 8, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 6,
604.10031 +	 8, 8,11,11, 6, 8, 8,11,11, 6, 7, 7, 9, 9, 7, 8,
604.10032 +	 9,10,11, 7, 9, 9,11,10, 8, 9,10,12,12, 8,10,10,
604.10033 +	12,12, 6, 7, 7, 9, 9, 7, 9, 9,10,10, 7, 9, 8,11,
604.10034 +	10, 8,10,10,12,12, 8,10, 9,12,12, 8, 9, 9,11,11,
604.10035 +	 9,10,10,12,12, 9,11,11,12,13,11,12,12,13,14,11,
604.10036 +	12,12,14,14, 8, 9, 9,11,11, 9,11,10,13,12, 9,10,
604.10037 +	10,13,12,11,12,12,14,14,11,12,12,14,13, 7, 8, 9,
604.10038 +	10,10, 8,10,10,11,11, 8,10,10,11,11,10,11,11,13,
604.10039 +	13,10,11,11,13,13, 8, 9,10,10,11,10,11,11,12,13,
604.10040 +	10,11,11,12,12,11,11,12,13,14,11,12,12,14,14, 8,
604.10041 +	10,10,11,11,10,11,11,12,13,10,11,11,12,12,11,12,
604.10042 +	12,14,14,11,12,12,14,14,10,11,11,12,13,11,12,12,
604.10043 +	13,14,12,13,13,14,14,13,13,14,14,16,13,14,14,15,
604.10044 +	16,10,11,11,13,13,12,12,12,14,14,11,12,12,14,14,
604.10045 +	13,14,14,15,16,13,14,14,16,15, 7, 8, 8,10,10, 8,
604.10046 +	10,10,11,11, 8,10,10,12,11,10,11,11,13,13,10,11,
604.10047 +	11,13,13, 8,10,10,11,11,10,11,11,12,12,10,11,11,
604.10048 +	12,12,11,12,12,14,14,11,12,12,14,14, 8,10, 9,11,
604.10049 +	10,10,11,11,13,12,10,11,10,13,12,11,12,12,14,14,
604.10050 +	11,12,11,14,13,10,11,11,13,13,11,12,12,14,14,12,
604.10051 +	12,12,14,14,13,14,14,15,16,13,14,14,15,15,10,11,
604.10052 +	11,13,12,12,12,12,14,14,11,12,12,14,13,13,14,14,
604.10053 +	16,15,13,14,13,16,14,10,11,11,13,13,12,12,13,14,
604.10054 +	15,12,13,13,14,15,13,14,15,15,16,13,14,14,16,16,
604.10055 +	11,12,13,14,14,13,13,14,15,16,13,14,14,15,16,14,
604.10056 +	15,15,16,17,14,15,16,17,17,11,12,12,14,14,13,14,
604.10057 +	14,15,16,13,14,14,15,15,14,15,15,16,18,14,15,15,
604.10058 +	17,16,13,14,15,15,16,15,15,16,16,18,15,15,15,17,
604.10059 +	17,16,16,17,17,18,16,16,16,18,18,14,14,14,16,16,
604.10060 +	15,15,15,16,17,15,15,15,16,17,16,17,17,18,18,16,
604.10061 +	16,17,18,17,10,11,11,14,13,12,13,13,15,14,11,13,
604.10062 +	13,15,14,13,15,15,16,16,13,14,14,16,16,11,12,12,
604.10063 +	14,14,13,13,13,15,15,13,14,13,15,15,15,15,15,17,
604.10064 +	16,14,15,15,17,16,11,13,12,14,14,13,14,13,15,15,
604.10065 +	13,14,13,15,15,14,15,15,17,17,14,15,15,17,16,14,
604.10066 +	14,14,16,16,14,15,15,17,17,15,15,16,17,16,17,16,
604.10067 +	17,18,18,16,17,17,18,18,13,14,14,16,15,15,15,15,
604.10068 +	17,17,14,16,15,16,16,17,17,17,18,18,16,17,16,20,
604.10069 +	19, 6, 8, 8,10,10, 8,10,10,11,11, 8,10,10,12,11,
604.10070 +	10,11,11,13,13,10,11,11,13,13, 8, 9,10,11,11,10,
604.10071 +	11,11,12,12,10,11,11,13,12,11,12,12,14,14,11,12,
604.10072 +	12,14,14, 9,10,10,11,11,10,11,11,12,12,10,11,11,
604.10073 +	13,12,11,12,12,14,14,11,12,12,14,14,10,10,11,12,
604.10074 +	13,11,12,12,14,14,11,12,12,14,14,13,14,14,15,16,
604.10075 +	13,14,14,15,16,10,11,11,13,13,12,12,12,14,14,12,
604.10076 +	13,12,14,14,13,14,14,16,16,13,14,14,15,15, 9,10,
604.10077 +	10,11,12,10,11,11,12,13,10,11,11,13,12,11,12,12,
604.10078 +	14,14,11,12,12,14,14,10,10,11,12,13,11,12,12,13,
604.10079 +	14,11,12,12,13,14,12,13,14,14,15,12,13,13,15,15,
604.10080 +	10,11,11,13,13,11,12,12,13,14,11,12,12,14,13,12,
604.10081 +	13,13,15,15,12,13,13,15,15,12,11,13,12,14,13,13,
604.10082 +	14,14,15,13,13,14,14,15,14,15,15,16,17,14,15,15,
604.10083 +	16,17,12,13,12,14,14,13,14,14,15,15,13,14,14,15,
604.10084 +	15,14,15,15,16,17,14,15,15,16,17, 8, 9, 9,11,11,
604.10085 +	10,11,11,12,13,10,11,11,13,12,12,13,13,14,15,11,
604.10086 +	13,12,15,14, 9,11,10,12,12,11,12,12,13,14,11,12,
604.10087 +	12,14,13,13,13,14,15,15,13,14,13,15,15, 9,11,11,
604.10088 +	12,12,11,12,12,14,14,11,12,12,14,13,13,14,14,15,
604.10089 +	16,13,14,13,15,14,11,12,12,14,13,12,13,13,14,15,
604.10090 +	13,14,14,16,15,15,15,15,15,16,15,16,15,17,17,11,
604.10091 +	12,12,14,14,13,14,14,15,15,12,13,13,15,14,15,15,
604.10092 +	15,17,17,14,15,15,17,15,11,12,12,14,14,12,13,13,
604.10093 +	15,15,12,13,13,15,15,14,15,15,17,17,14,15,15,16,
604.10094 +	16,12,13,13,14,15,13,14,14,16,16,14,14,14,15,16,
604.10095 +	15,16,16,17,17,15,16,16,17,17,12,13,13,15,15,14,
604.10096 +	14,14,16,16,14,14,15,16,16,15,16,16,17,17,15,16,
604.10097 +	16,17,17,14,15,15,15,16,15,15,16,16,18,15,16,16,
604.10098 +	17,17,17,17,17,18,18,16,17,17,19,18,14,15,15,16,
604.10099 +	17,15,16,16,17,17,15,16,16,18,17,16,17,17,19,18,
604.10100 +	17,17,17,19,18,10,12,12,14,14,13,13,14,15,15,12,
604.10101 +	14,13,16,15,15,15,15,17,17,14,15,15,17,16,12,13,
604.10102 +	13,15,14,13,14,14,16,16,14,14,15,17,16,15,16,16,
604.10103 +	17,17,15,16,16,18,17,12,13,13,15,14,14,15,15,16,
604.10104 +	16,13,15,14,16,15,16,17,16,19,17,15,16,16,17,17,
604.10105 +	14,15,15,17,15,15,16,15,17,17,16,17,16,18,17,17,
604.10106 +	17,18,18,18,17,17,18,19,18,14,15,15,16,16,15,16,
604.10107 +	16,17,18,15,16,16,18,16,17,18,18,19,19,17,18,17,
604.10108 +	18,19, 6, 8, 8,10,10, 8,10,10,11,11, 8,10,10,12,
604.10109 +	11,10,11,11,13,13, 9,11,11,13,13, 9,10,10,11,11,
604.10110 +	10,11,11,12,12,10,11,11,12,12,11,12,12,14,14,11,
604.10111 +	12,12,14,14, 8,10, 9,11,11,10,11,11,12,12,10,11,
604.10112 +	11,12,12,11,12,12,14,14,11,12,12,14,14,10,11,11,
604.10113 +	13,13,11,12,13,14,14,12,12,12,14,14,13,14,14,15,
604.10114 +	16,13,14,14,16,16,10,11,10,13,12,11,12,12,14,14,
604.10115 +	11,12,12,14,14,13,14,14,15,16,13,14,14,16,15, 8,
604.10116 +	 9, 9,11,11,10,11,11,12,13,10,11,11,13,12,12,13,
604.10117 +	13,14,15,12,13,13,15,14,10,11,11,12,12,11,11,12,
604.10118 +	13,14,11,12,12,14,14,13,13,14,15,16,13,14,14,15,
604.10119 +	15, 9,10,11,12,12,11,12,12,13,14,11,12,12,14,13,
604.10120 +	13,14,14,15,16,12,14,13,15,15,11,12,12,14,14,12,
604.10121 +	13,13,14,15,13,14,14,16,15,14,15,15,15,17,15,15,
604.10122 +	16,16,17,11,12,12,13,14,13,14,14,15,15,12,13,13,
604.10123 +	15,14,15,16,15,16,17,14,16,15,17,15, 9,10,10,12,
604.10124 +	11,10,11,11,13,13,10,11,11,13,12,11,12,12,14,14,
604.10125 +	11,12,12,14,14,10,11,11,12,13,11,12,12,13,14,11,
604.10126 +	12,12,14,14,12,13,13,15,15,12,13,13,15,15,10,11,
604.10127 +	10,13,12,11,12,12,13,13,11,12,12,14,13,12,13,13,
604.10128 +	15,15,12,13,13,15,14,12,13,12,14,14,13,14,14,15,
604.10129 +	15,13,14,14,15,15,14,15,15,16,16,14,15,15,16,16,
604.10130 +	11,13,11,14,12,13,13,13,15,14,12,14,13,15,14,15,
604.10131 +	15,15,17,16,14,15,14,17,15,10,12,12,14,14,13,13,
604.10132 +	14,15,16,12,14,13,15,15,14,15,16,17,17,14,15,16,
604.10133 +	17,17,12,13,13,14,15,13,14,14,16,16,14,14,15,16,
604.10134 +	16,16,16,16,17,17,16,16,16,18,18,12,13,13,14,15,
604.10135 +	14,14,15,16,16,13,14,14,16,15,16,16,16,17,18,15,
604.10136 +	16,16,17,17,14,15,15,16,16,15,15,16,17,17,15,16,
604.10137 +	16,17,18,17,18,18,18,19,17,18,18,19,19,14,15,15,
604.10138 +	16,16,15,16,16,17,17,15,16,16,17,17,17,17,18,20,
604.10139 +	18,17,18,17,18,18,11,12,12,14,14,12,13,14,15,15,
604.10140 +	12,13,13,15,15,14,15,15,16,17,14,15,15,16,17,12,
604.10141 +	13,13,15,15,14,14,14,16,16,14,14,14,16,16,15,16,
604.10142 +	16,17,17,15,16,16,17,17,12,13,13,15,14,13,14,14,
604.10143 +	16,15,14,15,14,16,15,15,16,16,17,17,15,16,16,17,
604.10144 +	16,14,15,15,16,16,15,16,16,17,17,16,16,16,17,17,
604.10145 +	17,17,17,19,18,17,17,17,18,19,14,15,14,17,15,15,
604.10146 +	16,16,17,17,15,16,15,17,17,16,17,17,18,18,16,17,
604.10147 +	17,18,17, 6,11,11,13,13,11,12,12,14,14,11,12,12,
604.10148 +	14,14,13,14,14,16,16,13,14,14,16,16,11,12,12,14,
604.10149 +	14,12,13,13,15,15,12,13,13,15,15,14,15,15,16,17,
604.10150 +	14,15,15,17,18,11,12,12,14,14,12,13,13,15,15,12,
604.10151 +	13,13,15,15,14,15,15,17,17,14,15,15,16,16,13,14,
604.10152 +	14,15,16,14,15,15,16,17,14,15,15,17,16,15,16,17,
604.10153 +	18,17,16,16,16,18,17,14,14,15,16,16,14,15,15,18,
604.10154 +	16,14,15,15,17,16,16,17,17,18,18,16,17,16,18,17,
604.10155 +	11,12,12,14,14,12,13,13,15,15,12,13,13,15,15,14,
604.10156 +	15,15,17,17,14,15,15,16,16,12,13,13,15,15,13,14,
604.10157 +	14,15,16,13,14,14,16,16,15,16,16,17,17,15,15,16,
604.10158 +	17,17,12,13,13,15,15,14,14,14,16,16,13,14,14,16,
604.10159 +	16,15,16,16,17,17,15,16,16,17,17,14,14,15,15,16,
604.10160 +	15,15,16,16,17,15,15,16,16,17,16,17,17,17,18,16,
604.10161 +	17,17,18,18,14,15,15,16,16,15,16,16,17,17,15,16,
604.10162 +	16,17,17,17,17,17,18,19,17,17,17,18,18,10,12,12,
604.10163 +	14,14,12,13,14,15,16,13,14,13,15,15,14,15,15,17,
604.10164 +	17,14,15,16,17,17,12,13,13,15,15,13,14,14,15,15,
604.10165 +	14,15,14,16,16,15,16,16,17,18,15,17,16,18,17,12,
604.10166 +	13,13,15,15,14,14,14,16,16,13,14,14,16,15,15,16,
604.10167 +	16,17,18,15,16,16,17,17,14,14,14,16,16,15,15,16,
604.10168 +	17,17,15,16,16,17,17,17,17,17,18,20,17,17,17,19,
604.10169 +	19,14,15,15,16,16,15,17,16,18,18,15,16,15,17,16,
604.10170 +	17,18,19,19,19,17,17,17,18,17,13,14,14,16,16,14,
604.10171 +	15,15,17,17,14,15,15,16,17,15,17,17,18,18,16,16,
604.10172 +	17,18,17,14,15,15,16,17,15,16,16,17,17,15,16,16,
604.10173 +	17,17,16,17,17,18,18,17,17,17,18,19,14,15,15,16,
604.10174 +	17,15,16,16,17,17,15,16,16,17,17,16,17,17,18,18,
604.10175 +	17,17,17,19,19,16,16,16,16,18,16,17,17,17,18,17,
604.10176 +	17,17,17,19,18,18,18,19,19,18,18,18,19,20,16,16,
604.10177 +	17,18,18,16,18,17,18,18,17,17,17,20,19,18,18,19,
604.10178 +	21,20,18,20,18,18,19,10,12,12,14,14,14,14,15,15,
604.10179 +	17,14,15,14,17,15,16,16,17,18,18,16,18,17,19,18,
604.10180 +	12,14,13,16,15,14,14,15,15,17,15,16,16,18,17,16,
604.10181 +	17,18,17,19,17,19,18,20,19,12,13,13,15,15,15,16,
604.10182 +	17,17,18,14,16,14,17,16,17,18,18,19,19,17,17,17,
604.10183 +	18,18,15,15,15,17,16,15,16,16,17,17,17,19,17,18,
604.10184 +	18,18,18,18,18,21,19,20,19,20,19,15,15,16,16,17,
604.10185 +	17,17,18,20,20,15,16,16,18,17,18,19,19,19,20,18,
604.10186 +	19,18,19,17, 6,11,11,13,13,11,12,12,14,14,11,12,
604.10187 +	12,14,14,13,14,14,16,16,13,14,14,16,16,11,12,12,
604.10188 +	14,14,12,13,13,15,15,12,13,13,15,15,14,15,15,17,
604.10189 +	17,14,15,15,17,16,11,12,12,14,14,12,13,13,15,15,
604.10190 +	12,13,13,15,15,14,15,15,16,16,14,15,15,16,16,13,
604.10191 +	14,14,16,16,15,15,15,16,16,14,15,15,17,16,16,17,
604.10192 +	17,19,18,16,17,17,18,18,13,14,14,15,15,14,15,15,
604.10193 +	17,16,14,15,15,17,16,16,17,16,17,18,15,16,16,18,
604.10194 +	18,10,12,12,14,14,12,13,14,15,15,12,13,13,15,15,
604.10195 +	14,15,15,17,17,14,15,15,17,16,12,13,13,15,15,14,
604.10196 +	14,14,15,16,14,15,15,16,16,15,16,16,17,18,16,16,
604.10197 +	16,18,18,12,13,13,14,14,14,14,15,16,16,13,14,14,
604.10198 +	16,16,15,16,16,18,18,15,16,16,19,17,14,15,15,16,
604.10199 +	17,15,15,16,17,17,16,17,16,17,18,17,17,18,17,19,
604.10200 +	17,17,18,18,19,14,14,14,16,16,15,16,16,17,17,15,
604.10201 +	16,15,17,17,17,17,17,19,20,16,17,17,18,18,11,12,
604.10202 +	12,14,14,12,13,13,15,15,12,13,13,15,15,14,15,15,
604.10203 +	16,16,14,15,14,16,16,12,13,13,15,15,14,14,14,16,
604.10204 +	16,13,14,14,16,16,15,16,16,18,17,15,16,16,17,17,
604.10205 +	12,13,13,15,15,13,14,14,16,16,13,14,14,16,16,15,
604.10206 +	16,15,18,18,15,16,15,17,16,14,15,15,16,16,15,16,
604.10207 +	16,17,17,15,16,16,18,17,16,17,17,18,18,16,17,17,
604.10208 +	18,18,14,15,14,16,15,15,16,15,17,17,15,16,15,17,
604.10209 +	16,16,17,17,18,18,17,17,16,19,17,10,12,12,14,15,
604.10210 +	14,14,15,15,17,14,15,14,17,15,16,17,17,17,18,16,
604.10211 +	17,17,18,18,12,14,13,16,15,14,14,16,15,17,15,17,
604.10212 +	16,18,17,17,17,18,17,19,18,18,18,19,18,12,13,14,
604.10213 +	15,15,15,16,16,16,17,14,15,14,18,16,18,17,18,19,
604.10214 +	19,17,18,17,20,18,15,15,15,17,17,15,16,16,17,18,
604.10215 +	18,18,18,19,18,18,18,19,18,20,18,19,19,21,21,15,
604.10216 +	15,16,16,17,17,18,18,18,18,15,16,16,17,17,17,19,
604.10217 +	20,19,20,17,18,18,19,17,13,14,14,16,16,14,15,15,
604.10218 +	16,17,14,15,15,17,17,16,16,17,17,18,15,17,16,17,
604.10219 +	17,14,15,15,16,16,15,16,16,17,17,16,16,16,17,17,
604.10220 +	17,17,18,17,18,17,17,17,18,20,14,15,15,17,16,15,
604.10221 +	16,16,17,17,15,16,16,17,17,17,17,17,18,18,16,17,
604.10222 +	17,19,18,16,16,17,17,17,17,18,17,19,18,17,17,17,
604.10223 +	18,19,17,20,18,19,21,17,19,18,19,20,15,17,15,17,
604.10224 +	16,16,17,17,18,18,17,17,17,18,17,18,19,18,19,21,
604.10225 +	18,18,17,19,19,
604.10226 +};
604.10227 +
604.10228 +static const static_codebook _44p9_p2_0 = {
604.10229 +	5, 3125,
604.10230 +	(long *)_vq_lengthlist__44p9_p2_0,
604.10231 +	1, -533725184, 1611661312, 3, 0,
604.10232 +	(long *)_vq_quantlist__44p9_p2_0,
604.10233 +	0
604.10234 +};
604.10235 +
604.10236 +static const long _vq_quantlist__44p9_p3_0[] = {
604.10237 +	1,
604.10238 +	0,
604.10239 +	2,
604.10240 +};
604.10241 +
604.10242 +static const long _vq_lengthlist__44p9_p3_0[] = {
604.10243 +	 2, 5, 4, 4, 7, 7, 4, 7, 6, 5, 6, 7, 7, 8, 9, 7,
604.10244 +	 9, 9, 5, 7, 6, 7, 9, 9, 7, 9, 8, 6, 8, 8, 8,10,
604.10245 +	10, 8,10,10, 8, 9,10,10,11,12,10,12,12, 8,10,10,
604.10246 +	10,12,12,10,12,11, 6, 8, 8, 8,10,10, 8,10,10, 8,
604.10247 +	10,10,10,11,12,10,12,12, 8,10, 9,10,12,11,10,12,
604.10248 +	11, 5, 8, 8, 8,10,10, 8,10,10, 8, 9,10,10,11,11,
604.10249 +	10,11,11, 8,10,10,10,11,12,10,12,11, 8,10,10,10,
604.10250 +	11,11,10,11,11,10,11,11,11,12,13,11,12,13,10,11,
604.10251 +	11,11,13,13,11,13,13, 7, 9, 9,10,11,12,10,12,11,
604.10252 +	 9,11,11,11,12,13,12,14,13, 9,11,11,12,13,14,11,
604.10253 +	13,12, 5, 8, 8, 8,10,10, 8,10,10, 8,10,10,10,11,
604.10254 +	12,10,12,12, 8,10, 9,10,12,11, 9,11,11, 7, 9, 9,
604.10255 +	10,11,12,10,12,11, 9,11,11,11,12,13,12,14,13, 9,
604.10256 +	11,11,12,13,14,11,13,12, 8,10,10,10,11,11,10,11,
604.10257 +	11,10,11,11,11,13,13,11,13,13,10,11,10,11,13,12,
604.10258 +	11,13,12,
604.10259 +};
604.10260 +
604.10261 +static const static_codebook _44p9_p3_0 = {
604.10262 +	5, 243,
604.10263 +	(long *)_vq_lengthlist__44p9_p3_0,
604.10264 +	1, -533200896, 1614282752, 2, 0,
604.10265 +	(long *)_vq_quantlist__44p9_p3_0,
604.10266 +	0
604.10267 +};
604.10268 +
604.10269 +static const long _vq_quantlist__44p9_p3_1[] = {
604.10270 +	1,
604.10271 +	0,
604.10272 +	2,
604.10273 +};
604.10274 +
604.10275 +static const long _vq_lengthlist__44p9_p3_1[] = {
604.10276 +	 4, 6, 6, 6, 7, 7, 6, 7, 7, 6, 7, 7, 7, 7, 8, 7,
604.10277 +	 7, 8, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
604.10278 +	 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 8, 9, 9, 8, 8, 8,
604.10279 +	 8, 9, 9, 8, 9, 9, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.10280 +	 8, 8, 8, 9, 9, 8, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9,
604.10281 +	 9, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9,
604.10282 +	 8, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9, 9, 8, 8, 8, 8,
604.10283 +	 9, 9, 8, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 8, 9,
604.10284 +	 9, 9, 9, 9, 9, 9, 9, 7, 8, 8, 8, 9, 9, 8, 9, 9,
604.10285 +	 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9,
604.10286 +	 9, 9, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.10287 +	 9, 8, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9, 9, 7, 8, 8,
604.10288 +	 8, 9, 9, 8, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 8,
604.10289 +	 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 9, 9, 8, 9,
604.10290 +	 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9,
604.10291 +	 9, 9, 9,
604.10292 +};
604.10293 +
604.10294 +static const static_codebook _44p9_p3_1 = {
604.10295 +	5, 243,
604.10296 +	(long *)_vq_lengthlist__44p9_p3_1,
604.10297 +	1, -535822336, 1611661312, 2, 0,
604.10298 +	(long *)_vq_quantlist__44p9_p3_1,
604.10299 +	0
604.10300 +};
604.10301 +
604.10302 +static const long _vq_quantlist__44p9_p4_0[] = {
604.10303 +	1,
604.10304 +	0,
604.10305 +	2,
604.10306 +};
604.10307 +
604.10308 +static const long _vq_lengthlist__44p9_p4_0[] = {
604.10309 +	 2, 5, 5, 4, 7, 7, 4, 7, 6, 5, 7, 7, 7, 8, 9, 7,
604.10310 +	 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 8, 6, 7, 8, 8, 9,
604.10311 +	10, 8,10,10, 8, 9,10,10,11,12,10,11,12, 8,10,10,
604.10312 +	10,11,12,10,12,11, 6, 8, 7, 8,10,10, 8,10, 9, 8,
604.10313 +	10,10,10,11,12,10,12,12, 8,10, 9,10,12,11,10,12,
604.10314 +	11, 5, 8, 8, 8,10,10, 8,10,10, 7, 9,10, 9,10,11,
604.10315 +	10,11,11, 8,10,10,10,12,12,10,12,11, 7, 9, 9, 9,
604.10316 +	11,11, 9,11,11, 9,10,11,11,11,12,11,12,12, 9,11,
604.10317 +	11,11,12,12,11,12,12, 7, 9, 9,10,11,12,10,12,11,
604.10318 +	 9,11,10,11,11,12,12,13,13, 9,11,11,12,13,13,11,
604.10319 +	13,11, 5, 8, 8, 8,10,10, 8,10,10, 8,10,10,10,11,
604.10320 +	12,10,12,12, 7, 9, 9, 9,11,11, 9,11,10, 7, 9, 9,
604.10321 +	10,11,12,10,12,11, 9,11,11,11,11,13,12,13,13, 9,
604.10322 +	10,11,12,13,13,11,12,11, 7, 9, 9, 9,11,11, 9,11,
604.10323 +	11, 9,11,11,11,12,12,11,12,12, 9,11,10,11,12,12,
604.10324 +	10,12,11,
604.10325 +};
604.10326 +
604.10327 +static const static_codebook _44p9_p4_0 = {
604.10328 +	5, 243,
604.10329 +	(long *)_vq_lengthlist__44p9_p4_0,
604.10330 +	1, -531365888, 1616117760, 2, 0,
604.10331 +	(long *)_vq_quantlist__44p9_p4_0,
604.10332 +	0
604.10333 +};
604.10334 +
604.10335 +static const long _vq_quantlist__44p9_p4_1[] = {
604.10336 +	2,
604.10337 +	1,
604.10338 +	3,
604.10339 +	0,
604.10340 +	4,
604.10341 +};
604.10342 +
604.10343 +static const long _vq_lengthlist__44p9_p4_1[] = {
604.10344 +	 6, 8, 8,10, 9, 8, 9, 9,10,10, 8, 9, 9,10,10, 8,
604.10345 +	10,10,10,10, 8,10,10,10,10, 9, 9, 9,10,10, 9,10,
604.10346 +	10,10,11, 9,10,10,11,11,10,10,10,11,11,10,10,10,
604.10347 +	11,11, 9, 9, 9,10,10, 9,10,10,11,11, 9,10,10,11,
604.10348 +	10,10,10,10,11,11,10,10,10,11,11,10,10,10,10,11,
604.10349 +	10,10,11,11,11,10,11,11,11,11,11,11,11,11,11,11,
604.10350 +	11,11,11,11,10,10,10,11,10,10,11,11,11,11,10,11,
604.10351 +	10,11,11,11,11,11,11,11,10,11,11,11,11, 9,10,10,
604.10352 +	10,11,10,10,11,11,11,10,11,11,11,11,10,11,11,11,
604.10353 +	11,10,11,11,11,11,10,10,11,11,11,11,11,11,11,11,
604.10354 +	11,11,11,11,12,11,11,12,12,12,11,11,11,12,12,10,
604.10355 +	11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,
604.10356 +	11,12,12,11,11,11,12,12,11,11,11,11,11,11,12,12,
604.10357 +	12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,12,
604.10358 +	12,11,11,11,11,11,11,12,12,12,12,11,12,11,12,12,
604.10359 +	11,12,12,12,12,12,12,12,12,12, 9,10,10,11,10,10,
604.10360 +	11,11,11,11,10,11,11,11,11,10,11,11,11,11,10,11,
604.10361 +	11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,
604.10362 +	12,12,11,11,12,12,12,11,11,11,12,12,10,11,10,11,
604.10363 +	11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,
604.10364 +	11,11,11,12,12,11,11,11,11,11,11,12,12,12,12,11,
604.10365 +	12,12,12,12,11,12,12,12,12,12,12,12,12,12,11,11,
604.10366 +	11,11,11,11,12,12,12,12,11,12,11,12,12,12,12,12,
604.10367 +	12,12,11,12,12,12,12,11,11,11,11,11,11,12,12,12,
604.10368 +	12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10369 +	11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10370 +	12,12,13,13,12,12,12,13,13,11,12,12,12,12,12,12,
604.10371 +	12,12,12,12,12,12,12,12,12,12,12,13,13,12,12,12,
604.10372 +	13,13,12,12,12,12,12,12,12,12,12,13,12,12,12,13,
604.10373 +	13,12,13,13,13,13,12,13,13,13,13,12,12,12,12,12,
604.10374 +	12,12,12,13,13,12,12,12,13,13,12,13,13,13,13,12,
604.10375 +	13,13,13,13,11,11,11,11,11,11,12,12,12,12,11,12,
604.10376 +	12,12,12,12,12,12,12,12,12,12,12,12,12,11,12,12,
604.10377 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,
604.10378 +	13,12,12,12,13,13,11,12,12,12,12,12,12,12,12,12,
604.10379 +	12,12,12,12,12,12,12,12,13,13,12,12,12,13,13,12,
604.10380 +	12,12,12,12,12,12,12,13,13,12,12,12,13,13,12,13,
604.10381 +	13,13,13,12,13,13,13,13,12,12,12,12,12,12,12,12,
604.10382 +	13,13,12,12,12,13,12,12,13,13,13,13,12,13,13,13,
604.10383 +	13, 7,10,10,11,11,10,10,11,11,11,10,11,11,11,11,
604.10384 +	10,11,11,11,11,10,11,11,11,11,10,10,10,11,11,10,
604.10385 +	11,11,11,11,11,11,11,11,12,11,11,11,12,12,11,11,
604.10386 +	11,12,12,10,11,11,11,11,11,11,11,12,11,11,11,11,
604.10387 +	12,11,11,11,11,12,12,11,11,11,12,12,11,11,11,11,
604.10388 +	11,11,11,11,12,12,11,11,12,12,12,11,12,12,12,12,
604.10389 +	11,12,12,12,12,11,11,11,11,11,11,12,12,12,12,11,
604.10390 +	11,12,12,12,11,12,12,12,12,11,12,12,12,12,10,11,
604.10391 +	11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,
604.10392 +	12,12,11,11,11,12,12,11,11,11,11,11,11,11,12,12,
604.10393 +	12,11,11,11,12,12,11,12,12,12,12,11,12,12,12,12,
604.10394 +	11,11,11,11,11,11,12,11,12,12,11,11,11,12,12,11,
604.10395 +	12,12,12,12,11,12,12,12,12,11,11,11,11,12,11,12,
604.10396 +	12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.10397 +	12,12,11,11,11,12,12,11,12,12,12,12,11,12,12,12,
604.10398 +	12,12,12,12,12,12,12,12,12,12,12,10,11,10,11,11,
604.10399 +	11,11,11,12,12,11,11,11,12,12,11,12,12,12,12,11,
604.10400 +	12,12,12,12,10,11,11,12,11,11,11,12,12,12,11,12,
604.10401 +	12,12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,
604.10402 +	12,11,11,12,12,12,12,11,12,11,12,12,12,12,12,12,
604.10403 +	12,12,12,12,12,12,11,12,11,12,12,12,12,12,12,12,
604.10404 +	12,12,12,12,12,12,12,12,12,13,12,12,12,12,12,11,
604.10405 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10406 +	12,12,13,12,12,12,13,12,11,11,11,12,12,12,12,12,
604.10407 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10408 +	13,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10409 +	12,12,13,13,13,12,12,12,13,13,11,12,12,12,12,12,
604.10410 +	12,12,12,13,12,12,12,12,12,12,12,13,13,13,12,13,
604.10411 +	12,13,13,12,12,12,12,12,12,12,12,13,13,12,12,12,
604.10412 +	13,13,12,13,13,13,13,12,13,13,13,13,12,12,12,12,
604.10413 +	12,12,12,12,13,13,12,13,12,13,13,12,13,13,13,13,
604.10414 +	12,13,13,13,13,11,11,11,12,12,12,12,12,12,12,11,
604.10415 +	12,12,12,12,12,12,12,13,13,12,12,12,13,13,11,12,
604.10416 +	12,12,12,12,12,12,12,12,12,12,12,13,13,12,13,12,
604.10417 +	13,13,12,13,13,13,13,11,12,12,12,12,12,12,12,13,
604.10418 +	13,12,12,12,13,12,12,13,13,13,13,12,13,13,13,13,
604.10419 +	12,12,12,12,12,12,12,13,13,13,12,13,13,13,13,13,
604.10420 +	13,13,13,13,13,13,13,13,13,12,12,12,12,12,12,13,
604.10421 +	13,13,13,12,12,12,13,13,13,13,13,13,13,13,13,13,
604.10422 +	13,13, 7,10,10,11,11,10,11,11,11,11,10,11,11,11,
604.10423 +	11,10,11,11,11,11,10,11,11,11,11,10,11,11,11,11,
604.10424 +	11,11,11,11,11,11,11,11,12,11,11,11,12,12,12,11,
604.10425 +	11,11,12,12,10,10,10,11,11,11,11,11,12,11,10,11,
604.10426 +	11,11,11,11,11,11,12,12,11,11,11,12,12,11,11,11,
604.10427 +	11,11,11,11,12,12,12,11,12,11,12,12,11,12,12,12,
604.10428 +	12,11,12,12,12,12,11,11,11,11,11,11,11,11,12,12,
604.10429 +	11,12,11,12,12,11,12,12,12,12,11,12,12,12,12,10,
604.10430 +	10,10,11,11,11,11,11,12,12,11,11,11,12,12,11,12,
604.10431 +	12,12,12,11,12,12,12,12,11,11,11,11,11,11,11,12,
604.10432 +	12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10433 +	12,11,11,11,11,11,11,12,12,12,12,11,12,11,12,12,
604.10434 +	12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,
604.10435 +	12,12,12,12,12,12,12,12,12,12,12,12,12,13,12,12,
604.10436 +	12,13,12,11,11,11,12,12,12,12,12,12,12,12,12,12,
604.10437 +	12,12,12,12,12,12,12,12,12,12,12,12,10,11,11,11,
604.10438 +	11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,
604.10439 +	11,11,11,12,12,11,11,11,11,11,11,11,12,12,12,11,
604.10440 +	12,11,12,12,11,12,12,12,12,11,12,12,12,12,11,11,
604.10441 +	11,11,11,11,11,11,12,12,11,11,11,12,12,11,12,12,
604.10442 +	12,12,11,12,12,12,12,11,11,11,12,11,12,12,12,12,
604.10443 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10444 +	11,11,11,12,11,11,12,12,12,12,11,12,12,12,12,12,
604.10445 +	12,12,12,12,12,12,12,12,12,11,11,11,12,12,11,12,
604.10446 +	12,12,12,12,12,12,12,12,12,12,12,13,13,12,12,12,
604.10447 +	13,12,11,12,12,12,12,12,12,12,12,13,12,12,12,13,
604.10448 +	13,12,13,13,13,13,12,13,13,13,13,11,12,12,12,12,
604.10449 +	12,12,12,12,13,12,12,12,12,12,12,13,13,13,13,12,
604.10450 +	13,13,13,13,12,12,12,12,12,12,12,13,13,13,12,13,
604.10451 +	12,13,13,13,13,13,13,13,13,13,13,13,13,12,12,12,
604.10452 +	12,12,12,13,13,13,13,12,13,12,13,13,13,13,13,13,
604.10453 +	13,13,13,13,13,13,11,11,11,12,12,11,12,12,12,12,
604.10454 +	11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,
604.10455 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,
604.10456 +	12,13,13,12,12,12,13,13,11,12,12,12,12,12,12,12,
604.10457 +	12,12,12,12,12,12,12,12,12,12,13,13,12,13,12,13,
604.10458 +	13,12,12,12,12,12,12,12,12,13,13,12,12,12,13,13,
604.10459 +	13,13,13,13,13,12,13,13,13,13,12,12,12,12,12,12,
604.10460 +	13,12,13,13,12,13,12,13,12,12,13,13,13,13,12,13,
604.10461 +	13,13,13, 8,11,11,12,12,11,12,12,12,12,11,12,12,
604.10462 +	12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,12,
604.10463 +	12,11,12,12,12,12,12,12,12,12,12,12,12,12,13,13,
604.10464 +	12,12,12,13,13,11,11,11,12,12,12,12,12,12,12,12,
604.10465 +	12,12,12,12,12,12,12,13,13,12,12,12,13,13,11,12,
604.10466 +	12,12,12,12,12,12,12,13,12,12,12,12,12,12,12,13,
604.10467 +	13,13,12,12,13,13,13,11,12,12,12,12,12,12,12,13,
604.10468 +	12,12,12,12,13,13,12,13,13,13,13,12,13,13,13,13,
604.10469 +	11,11,11,12,12,11,12,12,12,12,11,12,12,12,12,12,
604.10470 +	12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,
604.10471 +	12,12,12,12,12,12,12,12,12,12,12,13,13,12,12,12,
604.10472 +	13,13,11,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10473 +	12,12,13,12,13,13,12,13,12,13,13,12,12,12,12,12,
604.10474 +	12,12,12,12,13,12,12,12,13,13,12,13,13,13,13,12,
604.10475 +	13,13,13,13,12,12,12,12,12,12,12,12,13,13,12,12,
604.10476 +	12,13,13,12,13,13,13,13,12,13,13,13,13,11,11,11,
604.10477 +	12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,13,
604.10478 +	12,12,12,12,12,13,11,12,12,12,12,12,12,12,12,13,
604.10479 +	12,12,12,12,13,12,13,13,13,13,12,13,13,13,13,11,
604.10480 +	12,12,12,12,12,12,12,12,13,12,12,12,13,12,12,13,
604.10481 +	13,13,13,12,13,13,13,13,12,12,12,12,12,12,12,12,
604.10482 +	13,13,12,12,13,13,13,12,13,13,13,13,12,13,13,13,
604.10483 +	13,12,12,12,12,12,12,13,13,13,13,12,13,12,13,13,
604.10484 +	12,13,13,13,13,13,13,13,13,13,11,11,11,12,12,12,
604.10485 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10486 +	12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,
604.10487 +	12,12,12,12,13,13,13,12,13,13,13,13,11,12,12,12,
604.10488 +	12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,
604.10489 +	12,13,12,13,13,12,12,12,12,12,12,12,12,13,13,12,
604.10490 +	12,12,13,13,12,13,13,13,13,12,13,13,13,13,12,12,
604.10491 +	12,12,12,12,13,12,13,13,12,12,12,13,13,13,13,13,
604.10492 +	13,13,12,13,13,13,13,11,11,11,12,12,12,12,12,12,
604.10493 +	12,12,12,12,12,12,12,12,12,12,13,12,12,12,13,12,
604.10494 +	11,12,12,12,12,12,12,12,12,12,12,12,12,13,13,12,
604.10495 +	12,13,13,13,12,13,13,13,13,11,12,12,12,12,12,12,
604.10496 +	12,12,13,12,12,12,13,12,12,13,13,13,13,12,13,13,
604.10497 +	13,13,12,12,12,12,12,12,12,12,13,13,12,12,12,13,
604.10498 +	13,13,13,13,13,13,13,13,13,13,13,12,12,12,12,12,
604.10499 +	12,13,13,13,13,12,13,12,13,13,13,13,13,13,13,13,
604.10500 +	13,13,13,13, 8,11,11,11,11,11,12,12,12,12,11,12,
604.10501 +	12,12,12,12,12,12,12,12,11,12,12,12,12,11,11,11,
604.10502 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10503 +	13,12,12,12,13,13,11,11,11,12,12,12,12,12,12,12,
604.10504 +	12,12,12,12,12,12,12,12,13,13,12,12,12,13,12,12,
604.10505 +	12,12,12,12,12,12,12,12,12,12,12,12,13,13,12,13,
604.10506 +	13,13,13,12,13,13,13,13,11,12,12,12,12,12,12,12,
604.10507 +	12,13,12,12,12,13,12,12,13,13,13,13,12,13,12,13,
604.10508 +	13,11,11,11,12,12,12,12,12,12,12,11,12,12,12,12,
604.10509 +	12,12,12,13,13,12,12,12,13,12,11,12,12,12,12,12,
604.10510 +	12,12,12,12,12,12,12,13,13,12,12,13,13,13,12,13,
604.10511 +	13,13,13,11,12,12,12,12,12,12,12,13,13,12,12,12,
604.10512 +	12,12,12,13,13,13,13,12,13,13,13,13,12,12,12,12,
604.10513 +	12,12,12,13,13,13,12,12,13,13,13,13,13,13,13,13,
604.10514 +	12,13,13,13,13,12,12,12,12,12,12,13,12,13,13,12,
604.10515 +	12,12,13,13,13,13,13,13,13,12,13,13,13,13,11,11,
604.10516 +	11,12,12,11,12,12,12,12,11,12,12,12,12,12,12,12,
604.10517 +	12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,
604.10518 +	12,12,12,12,12,12,12,13,12,13,13,12,12,12,13,13,
604.10519 +	11,12,12,12,12,12,12,12,12,13,12,12,12,12,12,12,
604.10520 +	12,12,13,13,12,13,12,13,13,12,12,12,12,12,12,12,
604.10521 +	12,13,12,12,12,12,13,13,12,13,13,13,13,12,13,13,
604.10522 +	13,13,12,12,12,12,12,12,12,12,13,13,12,12,12,13,
604.10523 +	12,12,13,13,13,13,12,13,13,13,13,11,11,11,12,12,
604.10524 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10525 +	12,12,13,13,11,12,12,12,12,12,12,12,12,13,12,12,
604.10526 +	12,12,12,12,13,13,13,13,12,13,13,13,13,11,12,12,
604.10527 +	12,12,12,12,12,12,13,12,12,12,12,12,12,13,13,13,
604.10528 +	13,12,13,13,13,13,12,12,12,12,12,12,12,12,13,13,
604.10529 +	12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,12,
604.10530 +	12,12,12,12,12,13,13,13,13,12,12,12,13,12,13,13,
604.10531 +	13,13,13,12,13,13,13,13,11,11,11,12,12,12,12,12,
604.10532 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10533 +	13,11,12,12,12,12,12,12,12,12,12,12,12,12,13,12,
604.10534 +	12,12,12,13,13,12,13,13,13,13,11,12,12,12,12,12,
604.10535 +	12,12,12,12,12,12,12,12,12,12,13,13,13,13,12,13,
604.10536 +	12,13,13,12,12,12,12,12,12,12,13,13,13,12,13,12,
604.10537 +	13,13,12,13,13,13,13,13,13,13,13,13,12,12,12,12,
604.10538 +	12,12,12,12,12,13,12,12,12,13,13,13,13,13,13,13,
604.10539 +	12,13,13,13,13,
604.10540 +};
604.10541 +
604.10542 +static const static_codebook _44p9_p4_1 = {
604.10543 +	5, 3125,
604.10544 +	(long *)_vq_lengthlist__44p9_p4_1,
604.10545 +	1, -533725184, 1611661312, 3, 0,
604.10546 +	(long *)_vq_quantlist__44p9_p4_1,
604.10547 +	0
604.10548 +};
604.10549 +
604.10550 +static const long _vq_quantlist__44p9_p5_0[] = {
604.10551 +	2,
604.10552 +	1,
604.10553 +	3,
604.10554 +	0,
604.10555 +	4,
604.10556 +};
604.10557 +
604.10558 +static const long _vq_lengthlist__44p9_p5_0[] = {
604.10559 +	 4, 6, 6, 9, 9, 6, 7, 8,10,11, 6, 8, 7,10,10, 8,
604.10560 +	10,10,12,12, 8,10,10,12,12, 6, 7, 8,10,10, 7, 8,
604.10561 +	 9,10,11, 8, 9, 9,11,11,10,10,11,12,13,10,11,11,
604.10562 +	13,13, 6, 8, 7,10,10, 8, 9, 9,11,11, 7, 9, 8,11,
604.10563 +	10,10,11,11,13,13,10,11,10,13,12, 9,10,10,11,12,
604.10564 +	10,10,11,12,13,10,11,11,12,13,12,12,13,12,14,12,
604.10565 +	13,13,14,14, 9,10,10,12,11,10,11,11,13,12,10,11,
604.10566 +	10,13,12,12,13,13,14,14,12,13,12,14,12, 7, 8, 8,
604.10567 +	10,11, 8, 9,10,11,12, 8, 9, 9,11,12,10,11,12,13,
604.10568 +	14,10,11,11,13,13, 8, 9,10,11,12, 9,10,11,12,13,
604.10569 +	10,10,11,12,12,11,12,12,13,14,11,12,12,14,14, 8,
604.10570 +	 9, 9,11,12,10,10,11,12,13, 9,10,10,12,12,11,12,
604.10571 +	12,14,14,11,12,12,14,13,11,11,12,12,13,11,12,12,
604.10572 +	13,14,12,12,13,14,14,13,13,14,14,16,13,14,14,15,
604.10573 +	15,11,12,11,13,13,12,12,12,14,14,11,12,12,14,13,
604.10574 +	13,14,14,15,15,13,14,13,15,14, 7, 8, 8,11,10, 8,
604.10575 +	10, 9,12,11, 8,10, 9,12,11,10,11,11,13,13,10,12,
604.10576 +	11,14,13, 8, 9, 9,12,11, 9,10,10,12,12,10,11,10,
604.10577 +	13,12,11,12,12,13,14,11,12,12,14,14, 8,10, 9,12,
604.10578 +	11,10,11,10,12,12, 9,11,10,13,11,11,12,12,14,14,
604.10579 +	11,12,12,14,13,11,11,12,13,13,11,12,12,13,14,12,
604.10580 +	12,12,14,14,13,13,14,14,15,13,14,14,15,15,11,12,
604.10581 +	11,13,12,12,12,12,14,14,11,12,12,14,13,13,14,14,
604.10582 +	15,15,13,14,13,15,14,10,11,11,12,13,11,12,12,13,
604.10583 +	14,11,12,12,13,14,13,13,14,14,16,13,14,14,15,15,
604.10584 +	11,12,12,12,14,12,12,13,13,15,12,13,13,13,15,14,
604.10585 +	14,15,15,16,14,14,15,15,16,11,12,12,13,14,12,13,
604.10586 +	13,14,15,12,13,13,14,14,14,14,15,15,16,14,14,14,
604.10587 +	15,15,13,14,14,14,15,14,14,15,15,16,14,15,15,15,
604.10588 +	16,15,15,16,16,18,16,16,16,17,17,13,14,14,15,15,
604.10589 +	14,14,15,16,16,14,14,14,16,15,16,16,16,17,17,15,
604.10590 +	16,16,17,16,10,11,11,13,12,11,12,12,14,13,11,12,
604.10591 +	12,14,13,13,14,14,15,15,13,14,13,16,14,11,12,12,
604.10592 +	14,13,12,13,13,14,14,12,13,13,15,14,14,14,14,15,
604.10593 +	15,14,15,14,16,15,11,12,12,14,12,12,13,13,15,14,
604.10594 +	12,13,12,15,13,14,15,14,16,15,14,15,14,16,15,13,
604.10595 +	14,14,15,15,14,14,14,15,16,14,15,14,16,16,15,16,
604.10596 +	16,16,17,16,16,16,17,17,13,14,14,15,14,14,15,15,
604.10597 +	16,15,14,15,14,16,15,16,16,16,17,17,15,16,15,18,
604.10598 +	16, 6, 8, 8,11,11, 8, 9,10,11,12, 8,10, 9,12,12,
604.10599 +	10,11,11,13,13,10,12,11,14,13, 8, 9, 9,11,12, 9,
604.10600 +	10,10,12,12, 9,10,10,12,12,11,11,12,13,14,11,12,
604.10601 +	12,14,14, 8,10, 9,12,11,10,11,11,12,12, 9,11,10,
604.10602 +	13,12,11,12,12,14,14,11,12,12,14,13,10,11,11,13,
604.10603 +	13,11,12,12,13,14,11,12,12,14,14,13,13,14,13,15,
604.10604 +	13,14,14,15,15,11,12,11,13,13,12,12,12,14,14,11,
604.10605 +	12,12,14,13,13,14,14,15,15,13,14,13,15,14, 8, 9,
604.10606 +	 9,11,11, 9,10,10,12,12, 9,10,10,12,12,11,12,12,
604.10607 +	13,14,11,12,12,14,14, 9, 9,10,11,12,10,10,11,12,
604.10608 +	13,10,10,11,12,13,12,12,13,13,15,12,12,13,14,14,
604.10609 +	 9,10,10,12,12,10,11,11,13,13,10,11,11,13,13,12,
604.10610 +	13,13,14,15,12,13,12,14,14,11,11,12,12,14,12,12,
604.10611 +	13,13,14,12,12,13,13,14,13,13,14,14,16,14,14,14,
604.10612 +	15,15,11,12,12,14,13,12,13,13,14,14,12,13,13,15,
604.10613 +	14,14,14,14,16,16,13,14,14,16,14, 7, 9, 9,12,11,
604.10614 +	 9,10,10,12,12, 9,11,10,13,12,11,12,12,13,14,11,
604.10615 +	13,12,14,13, 9,10,10,12,12,10,10,11,12,13,10,12,
604.10616 +	11,13,13,12,12,13,13,14,12,13,13,15,14, 9,10,10,
604.10617 +	12,12,11,11,11,13,13,10,12,10,13,12,12,13,13,14,
604.10618 +	15,12,13,12,15,13,11,12,12,14,13,12,12,13,13,14,
604.10619 +	12,13,13,15,14,13,13,14,13,16,14,15,14,16,15,12,
604.10620 +	12,12,14,14,13,13,13,14,14,12,13,12,14,13,14,15,
604.10621 +	15,16,16,13,14,13,16,13,10,11,12,13,14,11,12,13,
604.10622 +	13,15,12,12,13,14,14,13,14,14,15,16,13,14,14,16,
604.10623 +	15,12,12,13,12,14,12,12,13,13,15,13,13,13,13,15,
604.10624 +	14,14,15,14,16,14,15,15,15,16,12,13,12,14,14,13,
604.10625 +	13,13,15,15,12,13,13,15,15,14,15,15,16,16,14,15,
604.10626 +	15,16,16,13,14,14,13,16,14,14,15,14,16,14,14,15,
604.10627 +	14,16,15,15,16,15,18,16,16,16,16,17,14,14,14,16,
604.10628 +	15,14,15,15,16,16,14,15,15,16,16,16,16,16,17,17,
604.10629 +	15,16,16,17,16,10,12,11,14,13,12,13,13,14,14,12,
604.10630 +	13,12,15,14,14,14,14,15,15,14,15,14,16,15,12,13,
604.10631 +	12,14,13,12,13,13,15,14,13,14,13,15,14,14,15,15,
604.10632 +	16,16,14,15,15,17,15,12,13,12,14,14,13,14,14,15,
604.10633 +	15,13,14,13,15,14,15,15,15,16,16,14,15,15,17,15,
604.10634 +	14,14,14,16,15,14,15,15,16,16,14,15,15,16,15,16,
604.10635 +	16,16,16,17,16,17,16,18,17,14,14,14,16,15,15,15,
604.10636 +	15,16,16,14,15,14,16,15,16,16,17,17,17,15,16,15,
604.10637 +	17,16, 6, 8, 8,11,11, 8, 9,10,12,12, 8,10, 9,12,
604.10638 +	11,10,11,12,13,13,10,11,11,13,13, 8, 9,10,11,12,
604.10639 +	 9,10,11,12,13,10,11,11,12,12,11,12,12,13,14,11,
604.10640 +	12,12,14,14, 8, 9, 9,12,11, 9,10,10,12,12, 9,10,
604.10641 +	10,12,12,11,12,12,14,14,11,12,11,14,13,11,11,12,
604.10642 +	13,13,11,12,12,13,14,12,12,12,14,14,13,13,14,14,
604.10643 +	15,13,14,14,15,15,10,11,11,13,13,11,12,12,14,14,
604.10644 +	11,12,12,14,13,13,14,14,15,15,13,14,13,15,13, 7,
604.10645 +	 9, 9,11,12, 9,10,11,12,13, 9,10,10,12,12,11,12,
604.10646 +	13,13,14,11,12,12,14,14, 9,10,10,12,12,10,10,11,
604.10647 +	12,13,11,12,11,13,13,12,12,13,13,15,12,13,13,15,
604.10648 +	14, 9,10,10,12,12,10,11,12,13,13,10,11,10,13,12,
604.10649 +	12,13,13,14,15,12,13,12,14,13,12,12,12,14,14,12,
604.10650 +	12,13,13,14,13,13,13,15,14,14,13,14,13,16,14,15,
604.10651 +	15,16,16,11,12,12,13,14,12,13,13,14,15,12,13,12,
604.10652 +	14,13,14,14,15,15,16,13,14,13,15,13, 8, 9, 9,11,
604.10653 +	11, 9,10,10,12,12, 9,10,10,12,12,11,12,12,14,14,
604.10654 +	11,12,11,14,13, 9,10,10,12,12,10,11,11,13,13,10,
604.10655 +	11,11,13,13,12,12,13,14,15,12,13,13,15,14, 9,10,
604.10656 +	 9,12,11,10,11,10,13,12,10,11,10,13,12,12,13,12,
604.10657 +	14,14,12,13,12,15,13,11,12,12,13,14,12,13,13,14,
604.10658 +	14,12,13,13,14,14,14,14,14,14,16,14,14,14,16,15,
604.10659 +	11,12,11,14,12,12,13,12,15,13,12,13,12,15,13,14,
604.10660 +	14,14,16,15,13,14,13,16,14,10,11,12,13,14,12,12,
604.10661 +	13,13,15,12,13,13,14,14,14,14,15,15,16,14,14,14,
604.10662 +	15,16,12,12,13,14,14,12,13,14,14,15,13,14,14,15,
604.10663 +	15,14,15,15,15,17,15,15,15,16,16,12,12,13,13,14,
604.10664 +	13,13,14,14,15,12,13,13,14,15,15,15,15,15,17,14,
604.10665 +	15,15,15,15,14,14,14,16,16,14,15,15,15,16,15,15,
604.10666 +	15,16,16,16,15,16,16,18,16,16,17,17,17,14,14,14,
604.10667 +	15,16,15,15,15,16,17,14,15,14,16,16,16,16,17,17,
604.10668 +	18,16,16,15,17,16,10,12,11,14,13,12,12,12,14,14,
604.10669 +	11,13,12,14,13,13,14,14,15,15,13,14,13,16,15,12,
604.10670 +	12,13,14,14,12,13,13,15,15,13,13,13,15,15,14,15,
604.10671 +	15,16,16,14,15,15,17,16,12,13,12,14,12,13,13,13,
604.10672 +	15,13,12,13,12,15,13,14,15,15,16,15,14,15,14,16,
604.10673 +	14,14,14,14,16,16,14,15,15,16,16,14,15,15,16,16,
604.10674 +	15,16,16,16,17,16,17,16,18,17,13,14,14,16,13,14,
604.10675 +	15,15,16,14,14,15,14,16,14,16,16,16,17,16,15,16,
604.10676 +	15,18,15, 9,11,11,13,13,11,12,12,14,14,11,12,12,
604.10677 +	14,14,13,14,14,15,15,13,14,14,15,15,11,12,12,14,
604.10678 +	14,11,12,13,14,15,12,13,13,15,14,13,14,14,15,16,
604.10679 +	13,14,14,16,16,11,12,12,14,14,12,13,13,15,15,12,
604.10680 +	13,13,15,14,14,14,14,16,16,14,15,14,16,15,12,13,
604.10681 +	13,14,15,12,13,14,15,16,13,14,14,16,16,14,14,15,
604.10682 +	16,17,15,15,15,17,17,13,14,14,15,15,14,15,14,16,
604.10683 +	16,14,15,14,16,15,15,16,16,17,17,15,16,15,17,16,
604.10684 +	10,12,12,13,14,11,12,13,14,14,12,13,12,14,14,13,
604.10685 +	14,14,15,16,13,14,14,16,15,11,12,12,14,14,12,12,
604.10686 +	13,14,15,12,13,13,15,15,13,13,15,15,17,14,14,15,
604.10687 +	16,16,12,13,12,14,14,12,13,13,15,15,12,13,13,15,
604.10688 +	14,14,15,15,16,16,14,15,14,16,16,13,12,14,13,16,
604.10689 +	13,13,15,14,16,14,13,15,15,16,14,14,16,15,17,15,
604.10690 +	15,16,16,17,13,14,14,16,15,14,15,15,16,16,14,15,
604.10691 +	14,16,15,16,16,16,17,17,15,16,16,18,16,10,12,12,
604.10692 +	14,14,12,12,13,14,14,12,13,12,15,14,13,14,14,15,
604.10693 +	16,14,15,14,16,15,11,12,12,14,14,12,13,13,14,15,
604.10694 +	13,14,13,15,15,14,14,15,15,16,14,15,15,17,16,12,
604.10695 +	13,13,14,14,13,13,14,15,15,12,14,13,15,15,14,15,
604.10696 +	15,16,16,14,15,15,17,15,13,14,13,15,15,13,14,14,
604.10697 +	15,16,14,15,14,17,16,15,15,15,15,17,16,16,16,18,
604.10698 +	17,14,14,14,16,16,15,15,15,16,16,14,15,14,16,16,
604.10699 +	16,16,17,17,17,16,16,16,17,16,11,12,13,14,14,12,
604.10700 +	13,13,15,15,12,13,13,15,15,14,15,15,16,16,14,15,
604.10701 +	15,17,16,12,13,13,14,15,13,13,14,14,16,13,14,14,
604.10702 +	15,16,15,14,16,15,17,15,15,16,16,17,12,13,13,15,
604.10703 +	15,13,14,14,16,16,13,14,14,16,15,15,15,16,17,17,
604.10704 +	15,16,15,17,16,14,14,15,13,16,15,14,16,14,17,15,
604.10705 +	15,16,14,17,16,15,17,15,18,16,16,17,16,18,14,15,
604.10706 +	15,17,16,15,16,16,17,17,15,16,15,17,16,16,17,17,
604.10707 +	18,18,16,17,15,18,16,11,12,12,14,14,13,13,14,14,
604.10708 +	15,13,14,13,16,14,15,15,15,16,16,15,16,15,17,16,
604.10709 +	12,13,13,15,14,13,13,14,15,15,14,15,14,16,15,15,
604.10710 +	15,16,15,16,16,16,16,18,16,12,13,13,15,15,14,14,
604.10711 +	15,15,16,13,14,13,16,15,16,16,16,17,17,15,16,15,
604.10712 +	17,15,14,15,14,16,15,14,15,15,16,16,15,16,15,17,
604.10713 +	16,16,15,16,15,17,17,18,17,18,17,15,15,15,16,16,
604.10714 +	16,16,16,17,17,14,15,15,17,16,17,17,18,18,18,16,
604.10715 +	17,15,18,15, 9,11,11,13,13,11,12,12,14,14,11,12,
604.10716 +	12,14,14,13,14,14,15,16,13,14,14,15,15,11,12,12,
604.10717 +	14,14,12,13,13,14,15,12,13,13,14,14,14,14,15,15,
604.10718 +	16,14,14,14,16,16,11,12,12,14,14,12,13,13,14,15,
604.10719 +	11,13,12,14,14,13,14,14,16,16,13,14,14,16,15,13,
604.10720 +	14,14,15,15,14,14,15,15,16,14,15,14,16,16,15,15,
604.10721 +	16,16,17,15,16,16,17,17,12,13,13,15,15,13,14,14,
604.10722 +	16,15,12,14,13,16,15,15,16,15,17,17,14,15,15,17,
604.10723 +	15,10,12,12,14,14,12,12,13,14,15,12,13,12,14,14,
604.10724 +	14,14,15,15,16,13,14,14,16,16,12,13,13,14,14,13,
604.10725 +	13,14,14,15,13,14,13,15,15,14,15,15,15,17,14,15,
604.10726 +	15,16,16,11,12,12,14,14,13,13,14,15,15,12,13,13,
604.10727 +	15,14,14,15,15,16,17,14,15,14,16,15,14,14,14,16,
604.10728 +	16,14,15,15,16,16,15,15,15,16,16,15,16,16,16,18,
604.10729 +	16,17,16,18,17,13,13,14,15,15,14,14,15,16,16,13,
604.10730 +	14,14,16,15,16,16,17,17,17,15,15,15,17,15,10,12,
604.10731 +	12,14,13,12,12,13,14,14,11,13,12,14,14,13,14,14,
604.10732 +	16,16,13,14,14,16,15,12,12,13,14,14,12,13,13,14,
604.10733 +	15,13,13,13,15,15,14,14,15,16,16,14,15,15,16,16,
604.10734 +	11,12,12,14,14,12,13,13,15,15,12,13,12,15,14,14,
604.10735 +	15,14,16,16,13,15,13,16,15,13,14,14,15,16,14,15,
604.10736 +	15,15,17,14,15,15,16,16,16,15,16,16,17,16,16,16,
604.10737 +	17,17,13,14,12,16,13,14,15,13,16,15,13,15,13,16,
604.10738 +	14,15,16,15,17,16,15,16,14,17,15,11,12,12,14,15,
604.10739 +	13,13,14,14,16,13,14,13,15,14,15,15,16,16,17,15,
604.10740 +	15,15,16,16,12,13,13,15,15,13,13,14,15,16,14,15,
604.10741 +	14,16,15,15,15,16,15,17,16,16,16,17,17,12,13,13,
604.10742 +	14,15,14,14,15,15,16,13,14,13,15,15,16,16,16,17,
604.10743 +	17,15,16,15,16,15,15,15,15,16,16,14,15,15,16,17,
604.10744 +	16,16,16,17,17,16,15,17,15,18,17,18,17,18,18,14,
604.10745 +	14,15,15,17,15,15,16,16,17,14,15,15,16,16,17,17,
604.10746 +	17,17,18,16,16,15,17,15,11,12,12,14,14,12,13,13,
604.10747 +	15,15,12,13,13,15,15,14,15,15,16,16,14,15,14,17,
604.10748 +	16,13,13,13,15,15,13,14,14,15,16,13,14,14,16,16,
604.10749 +	15,15,16,16,17,15,16,16,17,17,12,13,13,15,14,13,
604.10750 +	14,14,16,15,13,14,13,16,14,15,16,16,17,16,15,16,
604.10751 +	14,17,15,14,15,15,16,17,15,15,16,16,17,15,16,16,
604.10752 +	17,17,16,15,17,16,18,16,17,17,18,18,14,15,14,16,
604.10753 +	13,15,16,15,17,14,15,16,14,17,14,16,17,16,18,16,
604.10754 +	16,17,15,18,15,
604.10755 +};
604.10756 +
604.10757 +static const static_codebook _44p9_p5_0 = {
604.10758 +	5, 3125,
604.10759 +	(long *)_vq_lengthlist__44p9_p5_0,
604.10760 +	1, -528744448, 1616642048, 3, 0,
604.10761 +	(long *)_vq_quantlist__44p9_p5_0,
604.10762 +	0
604.10763 +};
604.10764 +
604.10765 +static const long _vq_quantlist__44p9_p5_1[] = {
604.10766 +	3,
604.10767 +	2,
604.10768 +	4,
604.10769 +	1,
604.10770 +	5,
604.10771 +	0,
604.10772 +	6,
604.10773 +};
604.10774 +
604.10775 +static const long _vq_lengthlist__44p9_p5_1[] = {
604.10776 +	 2, 3, 3, 3, 3, 3, 3,
604.10777 +};
604.10778 +
604.10779 +static const static_codebook _44p9_p5_1 = {
604.10780 +	1, 7,
604.10781 +	(long *)_vq_lengthlist__44p9_p5_1,
604.10782 +	1, -533200896, 1611661312, 3, 0,
604.10783 +	(long *)_vq_quantlist__44p9_p5_1,
604.10784 +	0
604.10785 +};
604.10786 +
604.10787 +static const long _vq_quantlist__44p9_p6_0[] = {
604.10788 +	1,
604.10789 +	0,
604.10790 +	2,
604.10791 +};
604.10792 +
604.10793 +static const long _vq_lengthlist__44p9_p6_0[] = {
604.10794 +	 2, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 8, 9, 7,
604.10795 +	 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 8, 5, 7, 8, 8, 9,
604.10796 +	10, 8, 9,10, 8, 9,10,10,10,12,10,11,11, 8,10,10,
604.10797 +	10,11,12,10,11,10, 5, 8, 7, 8,10,10, 8,10, 9, 8,
604.10798 +	10,10,10,10,11,10,12,11, 8,10, 9,10,11,11,10,12,
604.10799 +	10, 5, 8, 8, 7, 9,10, 8,10, 9, 7, 9,10, 9,10,11,
604.10800 +	 9,11,11, 8,10, 9,10,11,11, 9,11,10, 7, 9, 9, 9,
604.10801 +	10,11, 9,11,11, 9, 9,11,10,10,13,11,12,12, 9,11,
604.10802 +	11,11,12,13,11,13,11, 7, 9, 9, 9,10,11, 9,11,10,
604.10803 +	 9,11,10,10,10,12,11,13,12, 9,11,11,11,12,12,10,
604.10804 +	12,10, 5, 8, 8, 8, 9,10, 7,10, 9, 8, 9,10, 9,10,
604.10805 +	11,10,11,11, 7,10, 9, 9,11,11, 9,11,10, 7, 9, 9,
604.10806 +	 9,10,11, 9,11,10, 9,11,11,10,10,12,11,12,12, 9,
604.10807 +	10,11,11,12,13,10,12,10, 7, 9, 9, 9,11,11, 9,11,
604.10808 +	10, 9,11,11,11,11,13,11,13,12, 9,11, 9,11,12,12,
604.10809 +	10,13,10,
604.10810 +};
604.10811 +
604.10812 +static const static_codebook _44p9_p6_0 = {
604.10813 +	5, 243,
604.10814 +	(long *)_vq_lengthlist__44p9_p6_0,
604.10815 +	1, -527106048, 1620377600, 2, 0,
604.10816 +	(long *)_vq_quantlist__44p9_p6_0,
604.10817 +	0
604.10818 +};
604.10819 +
604.10820 +static const long _vq_quantlist__44p9_p6_1[] = {
604.10821 +	1,
604.10822 +	0,
604.10823 +	2,
604.10824 +};
604.10825 +
604.10826 +static const long _vq_lengthlist__44p9_p6_1[] = {
604.10827 +	 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 8, 7,
604.10828 +	 8, 8, 7, 8, 7, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 8,
604.10829 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 8,
604.10830 +	 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.10831 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
604.10832 +	 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.10833 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.10834 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8,
604.10835 +	 8, 8, 9, 9, 8, 9, 9, 7, 8, 8, 8, 8, 8, 8, 8, 8,
604.10836 +	 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 9, 9, 8,
604.10837 +	 9, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.10838 +	 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8,
604.10839 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8,
604.10840 +	 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
604.10841 +	 8, 8, 8, 8, 8, 9, 9, 8, 9, 9, 8, 8, 8, 8, 9, 8,
604.10842 +	 8, 9, 8,
604.10843 +};
604.10844 +
604.10845 +static const static_codebook _44p9_p6_1 = {
604.10846 +	5, 243,
604.10847 +	(long *)_vq_lengthlist__44p9_p6_1,
604.10848 +	1, -530841600, 1616642048, 2, 0,
604.10849 +	(long *)_vq_quantlist__44p9_p6_1,
604.10850 +	0
604.10851 +};
604.10852 +
604.10853 +static const long _vq_quantlist__44p9_p7_0[] = {
604.10854 +	2,
604.10855 +	1,
604.10856 +	3,
604.10857 +	0,
604.10858 +	4,
604.10859 +};
604.10860 +
604.10861 +static const long _vq_lengthlist__44p9_p7_0[] = {
604.10862 +	 1,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10863 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10864 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10865 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10866 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10867 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10868 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10869 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10870 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10871 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10872 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10873 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10874 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10875 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10876 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10877 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10878 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10879 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10880 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10881 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10882 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10883 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10884 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10885 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10886 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10887 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10888 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10889 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10890 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10891 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10892 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10893 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10894 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10895 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10896 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10897 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10898 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10899 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10900 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10901 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10902 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10903 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10904 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10905 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10906 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10907 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10908 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10909 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10910 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10911 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10912 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10913 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10914 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10915 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10916 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10917 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10918 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10919 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10920 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10921 +	12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
604.10922 +	12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,
604.10923 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10924 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10925 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10926 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10927 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10928 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10929 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10930 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10931 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10932 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10933 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10934 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10935 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10936 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10937 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10938 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10939 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10940 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10941 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10942 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10943 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10944 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10945 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10946 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10947 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10948 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10949 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10950 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10951 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10952 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10953 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10954 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10955 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10956 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10957 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10958 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10959 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10960 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10961 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10962 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10963 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10964 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10965 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10966 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10967 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10968 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10969 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10970 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10971 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10972 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10973 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10974 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10975 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10976 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10977 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10978 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10979 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10980 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10981 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10982 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10983 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10984 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10985 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10986 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10987 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10988 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10989 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10990 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10991 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10992 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10993 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10994 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10995 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10996 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10997 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10998 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.10999 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11000 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11001 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11002 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11003 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11004 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11005 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11006 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11007 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11008 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11009 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11010 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11011 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11012 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11013 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11014 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11015 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11016 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11017 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11018 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11019 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11020 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11021 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11022 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11023 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11024 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11025 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11026 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11027 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11028 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11029 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11030 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11031 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11032 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11033 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11034 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11035 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11036 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11037 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11038 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11039 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11040 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11041 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11042 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11043 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11044 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11045 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11046 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11047 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11048 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11049 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11050 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11051 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11052 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11053 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11054 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11055 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11056 +	13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
604.11057 +	13,13,13,13,13,
604.11058 +};
604.11059 +
604.11060 +static const static_codebook _44p9_p7_0 = {
604.11061 +	5, 3125,
604.11062 +	(long *)_vq_lengthlist__44p9_p7_0,
604.11063 +	1, -510105088, 1635281408, 3, 0,
604.11064 +	(long *)_vq_quantlist__44p9_p7_0,
604.11065 +	0
604.11066 +};
604.11067 +
604.11068 +static const long _vq_quantlist__44p9_p7_1[] = {
604.11069 +	2,
604.11070 +	1,
604.11071 +	3,
604.11072 +	0,
604.11073 +	4,
604.11074 +};
604.11075 +
604.11076 +static const long _vq_lengthlist__44p9_p7_1[] = {
604.11077 +	 1, 4, 4,16,16, 4, 9,11,15,16, 4,12, 8,16,16,12,
604.11078 +	16,16,16,16,13,16,16,16,16, 5, 8,10,16,16, 9, 9,
604.11079 +	14,15,16,12,14,14,16,16,16,16,16,16,16,16,16,16,
604.11080 +	16,16, 5,11, 8,16,15,12,14,16,16,16, 9,15, 9,16,
604.11081 +	16,16,16,16,16,16,16,16,16,16,16,15,16,16,16,16,
604.11082 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11083 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11084 +	16,16,16,16,16,16,16,16,16,16,16,16,16, 6,11,11,
604.11085 +	16,16,12,13,16,16,16,12,16,14,16,16,16,16,16,16,
604.11086 +	16,16,16,16,16,16,11,15,15,16,16,14,16,16,16,16,
604.11087 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,12,
604.11088 +	15,16,16,16,16,16,16,16,16,14,16,15,16,16,16,16,
604.11089 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11090 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11091 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11092 +	16,16,16,16,16,16,16,16,16,16, 5,11,11,16,16,12,
604.11093 +	15,16,16,16,12,16,14,16,16,16,16,16,16,16,16,16,
604.11094 +	16,16,16,12,15,15,16,16,14,16,16,16,16,16,16,16,
604.11095 +	16,16,16,16,16,16,16,16,16,16,16,16,11,15,15,16,
604.11096 +	16,16,16,16,16,16,15,16,14,16,16,16,16,16,16,16,
604.11097 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11098 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11099 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11100 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11101 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11102 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11103 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11104 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11105 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11106 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11107 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11108 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11109 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11110 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11111 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11112 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11113 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11114 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11115 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11116 +	16, 6,11,12,16,16,11,15,16,16,16,13,16,14,16,16,
604.11117 +	16,16,16,16,16,16,16,16,16,16,11,16,14,16,16,14,
604.11118 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11119 +	16,16,16,12,14,14,16,16,16,16,16,16,16,15,16,16,
604.11120 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11121 +	16,16,15,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11122 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11123 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16, 8,13,
604.11124 +	15,16,16,15,15,16,16,16,14,16,16,16,16,16,16,16,
604.11125 +	16,16,16,16,16,16,16,14,16,16,16,16,16,16,16,16,
604.11126 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11127 +	15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11128 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11129 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11130 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11131 +	16,16,16,16,16,16,16,16,16,16,16, 7,12,12,16,16,
604.11132 +	13,12,16,16,16,14,16,14,16,16,16,16,16,16,16,16,
604.11133 +	16,16,16,16,13,16,16,16,16,14,14,16,16,16,16,16,
604.11134 +	16,16,16,16,16,16,16,16,16,16,16,16,16,12,14,16,
604.11135 +	16,16,16,16,16,16,16,14,16,14,16,16,16,16,16,16,
604.11136 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11137 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11138 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11139 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11140 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11141 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11142 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11143 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11144 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11145 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11146 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11147 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11148 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11149 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11150 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11151 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11152 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11153 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11154 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11155 +	16,16, 6,11,11,16,16,13,15,16,16,16,11,15,14,16,
604.11156 +	16,16,16,16,16,16,14,16,16,16,16,11,16,16,16,16,
604.11157 +	16,16,16,16,16,15,16,16,16,16,16,16,16,16,16,16,
604.11158 +	16,16,16,16,11,16,14,16,16,14,16,16,16,16,13,15,
604.11159 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11160 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11161 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11162 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 7,
604.11163 +	11,11,16,16,13,13,16,16,16,13,16,13,16,16,16,16,
604.11164 +	16,16,16,16,16,16,16,16,12,16,15,16,16,14,16,16,
604.11165 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11166 +	16,12,14,16,16,16,16,16,16,16,16,14,16,13,16,16,
604.11167 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11168 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11169 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11170 +	16,16,16,16,16,16,16,16,16,16,16,16, 8,13,14,16,
604.11171 +	16,15,16,16,16,16,14,16,16,16,16,16,16,16,16,16,
604.11172 +	16,16,16,16,16,15,16,16,16,16,16,16,16,16,16,16,
604.11173 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,15,16,
604.11174 +	15,16,16,16,16,16,16,16,16,16,15,16,16,16,16,16,
604.11175 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11176 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11177 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11178 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11179 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11180 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11181 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11182 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11183 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11184 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11185 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11186 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11187 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11188 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11189 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11190 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11191 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11192 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11193 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11194 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11195 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11196 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11197 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11198 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11199 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11200 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11201 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11202 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11203 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11204 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11205 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11206 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11207 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11208 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11209 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11210 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11211 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11212 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11213 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11214 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11215 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11216 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11217 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11218 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11219 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11220 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11221 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11222 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11223 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11224 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11225 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11226 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11227 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11228 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11229 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11230 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11231 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11232 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11233 +	16,16,16,16,15,16,16,16,16,16,16,16,16,16,16,16,
604.11234 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11235 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11236 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11237 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11238 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11239 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11240 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11241 +	16,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11242 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11243 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11244 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11245 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11246 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11247 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11248 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11249 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11250 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11251 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11252 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11253 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11254 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11255 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11256 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11257 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11258 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11259 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11260 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11261 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11262 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11263 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11264 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11265 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11266 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11267 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11268 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11269 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11270 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11271 +	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
604.11272 +	16,16,16,16,16,
604.11273 +};
604.11274 +
604.11275 +static const static_codebook _44p9_p7_1 = {
604.11276 +	5, 3125,
604.11277 +	(long *)_vq_lengthlist__44p9_p7_1,
604.11278 +	1, -514619392, 1630767104, 3, 0,
604.11279 +	(long *)_vq_quantlist__44p9_p7_1,
604.11280 +	0
604.11281 +};
604.11282 +
604.11283 +static const long _vq_quantlist__44p9_p7_2[] = {
604.11284 +	12,
604.11285 +	11,
604.11286 +	13,
604.11287 +	10,
604.11288 +	14,
604.11289 +	9,
604.11290 +	15,
604.11291 +	8,
604.11292 +	16,
604.11293 +	7,
604.11294 +	17,
604.11295 +	6,
604.11296 +	18,
604.11297 +	5,
604.11298 +	19,
604.11299 +	4,
604.11300 +	20,
604.11301 +	3,
604.11302 +	21,
604.11303 +	2,
604.11304 +	22,
604.11305 +	1,
604.11306 +	23,
604.11307 +	0,
604.11308 +	24,
604.11309 +};
604.11310 +
604.11311 +static const long _vq_lengthlist__44p9_p7_2[] = {
604.11312 +	 1, 3, 2, 5, 4, 7, 7, 8, 8, 9,10,10,10,11,11,11,
604.11313 +	12,12,12,13,13,13,13,13,13,
604.11314 +};
604.11315 +
604.11316 +static const static_codebook _44p9_p7_2 = {
604.11317 +	1, 25,
604.11318 +	(long *)_vq_lengthlist__44p9_p7_2,
604.11319 +	1, -518864896, 1620639744, 5, 0,
604.11320 +	(long *)_vq_quantlist__44p9_p7_2,
604.11321 +	0
604.11322 +};
604.11323 +
604.11324 +static const long _vq_quantlist__44p9_p7_3[] = {
604.11325 +	12,
604.11326 +	11,
604.11327 +	13,
604.11328 +	10,
604.11329 +	14,
604.11330 +	9,
604.11331 +	15,
604.11332 +	8,
604.11333 +	16,
604.11334 +	7,
604.11335 +	17,
604.11336 +	6,
604.11337 +	18,
604.11338 +	5,
604.11339 +	19,
604.11340 +	4,
604.11341 +	20,
604.11342 +	3,
604.11343 +	21,
604.11344 +	2,
604.11345 +	22,
604.11346 +	1,
604.11347 +	23,
604.11348 +	0,
604.11349 +	24,
604.11350 +};
604.11351 +
604.11352 +static const long _vq_lengthlist__44p9_p7_3[] = {
604.11353 +	 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.11354 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.11355 +};
604.11356 +
604.11357 +static const static_codebook _44p9_p7_3 = {
604.11358 +	1, 25,
604.11359 +	(long *)_vq_lengthlist__44p9_p7_3,
604.11360 +	1, -529006592, 1611661312, 5, 0,
604.11361 +	(long *)_vq_quantlist__44p9_p7_3,
604.11362 +	0
604.11363 +};
604.11364 +
604.11365 +static const long _huff_lengthlist__44p9_short[] = {
604.11366 +	 3, 3, 3, 3, 3, 3, 3, 3,
604.11367 +};
604.11368 +
604.11369 +static const static_codebook _huff_book__44p9_short = {
604.11370 +	1, 8,
604.11371 +	(long *)_huff_lengthlist__44p9_short,
604.11372 +	0, 0, 0, 0, 0,
604.11373 +	NULL,
604.11374 +	0
604.11375 +};
604.11376 +
604.11377 +static const long _vq_quantlist__44pn1_l0_0[] = {
604.11378 +	6,
604.11379 +	5,
604.11380 +	7,
604.11381 +	4,
604.11382 +	8,
604.11383 +	3,
604.11384 +	9,
604.11385 +	2,
604.11386 +	10,
604.11387 +	1,
604.11388 +	11,
604.11389 +	0,
604.11390 +	12,
604.11391 +};
604.11392 +
604.11393 +static const long _vq_lengthlist__44pn1_l0_0[] = {
604.11394 +	 1, 3, 3, 8, 8,10,10,10,10,10,10,10,10, 5, 7, 5,
604.11395 +	 9, 8,10,10,10,10,11,10,11,10, 5, 5, 7, 8, 9,10,
604.11396 +	10,11,10,10,11,10,11,10,10,10,11,11,11,11,11,11,
604.11397 +	11,10,11,11,10,10,10,10,11,11,11,11,11,10,11,11,
604.11398 +	11,11,11,11,11,11,12,11,10,11,11,11,11,11,11,11,
604.11399 +	11,11,11,11,11,10,10,11,11,12,11,11,11,11,11,11,
604.11400 +	12,11,11,11,10,11,11,11,11,11,11,11,11,10,11,11,
604.11401 +	10,11,10,11,11,11,11,11,11,11,11,11,11,12,11,11,
604.11402 +	12,12,11,11,11,11,11,11,11,11,11,11,11,11,12,11,
604.11403 +	10,11,11,11,11,11,11,11,12,11,13,11,11,11,11,11,
604.11404 +	11,11,11,11,11,11,12,11,13,
604.11405 +};
604.11406 +
604.11407 +static const static_codebook _44pn1_l0_0 = {
604.11408 +	2, 169,
604.11409 +	(long *)_vq_lengthlist__44pn1_l0_0,
604.11410 +	1, -526516224, 1616117760, 4, 0,
604.11411 +	(long *)_vq_quantlist__44pn1_l0_0,
604.11412 +	0
604.11413 +};
604.11414 +
604.11415 +static const long _vq_quantlist__44pn1_l0_1[] = {
604.11416 +	2,
604.11417 +	1,
604.11418 +	3,
604.11419 +	0,
604.11420 +	4,
604.11421 +};
604.11422 +
604.11423 +static const long _vq_lengthlist__44pn1_l0_1[] = {
604.11424 +	 1, 4, 4, 7, 7, 4, 5, 6, 7, 7, 4, 6, 5, 7, 7, 7,
604.11425 +	 6, 7, 6, 7, 7, 7, 6, 7, 6,
604.11426 +};
604.11427 +
604.11428 +static const static_codebook _44pn1_l0_1 = {
604.11429 +	2, 25,
604.11430 +	(long *)_vq_lengthlist__44pn1_l0_1,
604.11431 +	1, -533725184, 1611661312, 3, 0,
604.11432 +	(long *)_vq_quantlist__44pn1_l0_1,
604.11433 +	0
604.11434 +};
604.11435 +
604.11436 +static const long _vq_quantlist__44pn1_l1_0[] = {
604.11437 +	1,
604.11438 +	0,
604.11439 +	2,
604.11440 +};
604.11441 +
604.11442 +static const long _vq_lengthlist__44pn1_l1_0[] = {
604.11443 +	 1, 4, 4, 4, 4, 4, 4, 4, 4,
604.11444 +};
604.11445 +
604.11446 +static const static_codebook _44pn1_l1_0 = {
604.11447 +	2, 9,
604.11448 +	(long *)_vq_lengthlist__44pn1_l1_0,
604.11449 +	1, -516716544, 1630767104, 2, 0,
604.11450 +	(long *)_vq_quantlist__44pn1_l1_0,
604.11451 +	0
604.11452 +};
604.11453 +
604.11454 +static const long _huff_lengthlist__44pn1_lfe[] = {
604.11455 +	 1, 3, 2, 3,
604.11456 +};
604.11457 +
604.11458 +static const static_codebook _huff_book__44pn1_lfe = {
604.11459 +	2, 4,
604.11460 +	(long *)_huff_lengthlist__44pn1_lfe,
604.11461 +	0, 0, 0, 0, 0,
604.11462 +	NULL,
604.11463 +	0
604.11464 +};
604.11465 +
604.11466 +static const long _huff_lengthlist__44pn1_long[] = {
604.11467 +	 2, 3, 6, 7, 9,13,17, 3, 2, 5, 7, 9,13,17, 6, 5,
604.11468 +	 5, 6, 9,12,16, 7, 7, 6, 6, 7,10,13,10,10, 9, 7,
604.11469 +	 6,10,13,13,13,12,10,10,11,15,17,17,17,14,14,15,
604.11470 +	17,
604.11471 +};
604.11472 +
604.11473 +static const static_codebook _huff_book__44pn1_long = {
604.11474 +	2, 49,
604.11475 +	(long *)_huff_lengthlist__44pn1_long,
604.11476 +	0, 0, 0, 0, 0,
604.11477 +	NULL,
604.11478 +	0
604.11479 +};
604.11480 +
604.11481 +static const long _vq_quantlist__44pn1_p1_0[] = {
604.11482 +	1,
604.11483 +	0,
604.11484 +	2,
604.11485 +};
604.11486 +
604.11487 +static const long _vq_lengthlist__44pn1_p1_0[] = {
604.11488 +	 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11489 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11490 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11491 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11492 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11493 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11494 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11495 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11496 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11497 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11498 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11499 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11500 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11501 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11502 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11503 +	 0, 0, 0,
604.11504 +};
604.11505 +
604.11506 +static const static_codebook _44pn1_p1_0 = {
604.11507 +	5, 243,
604.11508 +	(long *)_vq_lengthlist__44pn1_p1_0,
604.11509 +	1, -535822336, 1611661312, 2, 0,
604.11510 +	(long *)_vq_quantlist__44pn1_p1_0,
604.11511 +	0
604.11512 +};
604.11513 +
604.11514 +static const long _vq_quantlist__44pn1_p2_0[] = {
604.11515 +	1,
604.11516 +	0,
604.11517 +	2,
604.11518 +};
604.11519 +
604.11520 +static const long _vq_lengthlist__44pn1_p2_0[] = {
604.11521 +	 1, 5, 5, 0, 7, 7, 0, 8, 8, 0, 9, 9, 0,12,12, 0,
604.11522 +	 8, 8, 0, 9, 9, 0,13,13, 0, 8, 8, 0, 6, 6, 0,11,
604.11523 +	11, 0,12,12, 0,12,12, 0,14,14, 0,11,12, 0,12,12,
604.11524 +	 0,15,15, 0,12,12, 0, 5, 5, 0, 5, 5, 0, 6, 6, 0,
604.11525 +	 7, 7, 0,10,10, 0, 6, 6, 0, 7, 7, 0,11,11, 0, 6,
604.11526 +	 6, 0, 7, 7, 0,11,11, 0,12,11, 0,11,11, 0,14,14,
604.11527 +	 0,10,10, 0,12,12, 0,15,15, 0,12,12, 0, 6, 6, 0,
604.11528 +	12,12, 0,12,12, 0,12,12, 0,14,14, 0,11,11, 0,12,
604.11529 +	12, 0,16,16, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11530 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11531 +	 0, 0, 0, 8, 8, 0,12,12, 0,12,12, 0,12,12, 0,15,
604.11532 +	15, 0,12,12, 0,11,11, 0,16,16, 0,11,11, 0, 6, 6,
604.11533 +	 0,12,12, 0,12,12, 0,13,13, 0,15,15, 0,12,12, 0,
604.11534 +	13,13, 0,15,15, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0,
604.11535 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11536 +	 0, 0, 0,
604.11537 +};
604.11538 +
604.11539 +static const static_codebook _44pn1_p2_0 = {
604.11540 +	5, 243,
604.11541 +	(long *)_vq_lengthlist__44pn1_p2_0,
604.11542 +	1, -533200896, 1614282752, 2, 0,
604.11543 +	(long *)_vq_quantlist__44pn1_p2_0,
604.11544 +	0
604.11545 +};
604.11546 +
604.11547 +static const long _vq_quantlist__44pn1_p2_1[] = {
604.11548 +	1,
604.11549 +	0,
604.11550 +	2,
604.11551 +};
604.11552 +
604.11553 +static const long _vq_lengthlist__44pn1_p2_1[] = {
604.11554 +	 1, 3, 3, 0, 9, 9, 0, 9, 9, 0,10,10, 0, 9, 9, 0,
604.11555 +	10,10, 0,10,10, 0,10,10, 0,10,10, 0, 7, 7, 0, 7,
604.11556 +	 7, 0, 6, 6, 0, 8, 8, 0, 7, 7, 0, 8, 8, 0, 8, 8,
604.11557 +	 0, 7, 7, 0, 8, 8, 0, 7, 7, 0, 9, 9, 0, 8, 9, 0,
604.11558 +	10,10, 0, 9, 9, 0,10,10, 0,10,11, 0, 9, 9, 0,10,
604.11559 +	10, 0, 9, 9, 0,11,11, 0,12,12, 0,12,12, 0,11,11,
604.11560 +	 0,12,12, 0,13,13, 0,12,12, 0,13,13, 0, 8, 8, 0,
604.11561 +	12,12, 0,12,12, 0,13,13, 0,13,13, 0,13,13, 0,13,
604.11562 +	13, 0,13,13, 0,13,13, 0, 7, 7, 0, 0, 0, 0, 0, 0,
604.11563 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11564 +	 0, 0, 0, 9, 9, 0,11,11, 0,12,12, 0,13,13, 0,12,
604.11565 +	12, 0,13,13, 0,13,13, 0,12,12, 0,12,12, 0, 9, 9,
604.11566 +	 0,12,12, 0,13,13, 0,14,14, 0,13,13, 0,14,14, 0,
604.11567 +	14,14, 0,13,13, 0,14,14, 0, 7, 7, 0, 0, 0, 0, 0,
604.11568 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604.11569 +	 0, 0, 0,
604.11570 +};
604.11571 +
604.11572 +static const static_codebook _44pn1_p2_1 = {
604.11573 +	5, 243,
604.11574 +	(long *)_vq_lengthlist__44pn1_p2_1,
604.11575 +	1, -535822336, 1611661312, 2, 0,
604.11576 +	(long *)_vq_quantlist__44pn1_p2_1,
604.11577 +	0
604.11578 +};
604.11579 +
604.11580 +static const long _vq_quantlist__44pn1_p3_0[] = {
604.11581 +	1,
604.11582 +	0,
604.11583 +	2,
604.11584 +};
604.11585 +
604.11586 +static const long _vq_lengthlist__44pn1_p3_0[] = {
604.11587 +	 1, 6, 6, 6, 8, 8, 6, 8, 8, 7, 9, 9,10,11,11, 8,
604.11588 +	 8, 8, 7, 9, 9,11,12,12, 9, 9, 9, 6, 7, 7,10,11,
604.11589 +	11,10,11,11,10,11,11,13,13,13,12,12,12,10,12,11,
604.11590 +	14,14,14,12,12,12, 6, 5, 5, 9, 6, 6, 9, 6, 6, 9,
604.11591 +	 7, 7,12,10,10,11, 7, 6, 9, 7, 7,13,11,11,12, 7,
604.11592 +	 7, 7, 8, 8,12,10,10,12,10,10,11,10,10,15,13,13,
604.11593 +	13, 9, 9,12,11,11,15,14,14,15,11,11, 8, 7, 7,12,
604.11594 +	11,11,12,11,11,11,11,11,14,13,14,14,12,12,12,11,
604.11595 +	11,16,15,15,14,12,12, 0,10,10, 0,12,12, 0,12,12,
604.11596 +	 0,11,11, 0,14,14, 0,11,11, 0,11,11, 0,15,15, 0,
604.11597 +	11,11, 7, 8, 8,13,11,11,12,10,10,12,11,11,15,13,
604.11598 +	13,14,11,11,12,10,10,16,14,14,15,10,10, 9, 7, 7,
604.11599 +	13,11,12,13,12,11,12,11,11,15,14,14,14,12,12,13,
604.11600 +	12,12,16,15,15,15,12,12, 0,11,11, 0,12,12, 0,12,
604.11601 +	13, 0,12,12, 0,15,15, 0,12,12, 0,12,12, 0,16,15,
604.11602 +	 0,12,12,
604.11603 +};
604.11604 +
604.11605 +static const static_codebook _44pn1_p3_0 = {
604.11606 +	5, 243,
604.11607 +	(long *)_vq_lengthlist__44pn1_p3_0,
604.11608 +	1, -531365888, 1616117760, 2, 0,
604.11609 +	(long *)_vq_quantlist__44pn1_p3_0,
604.11610 +	0
604.11611 +};
604.11612 +
604.11613 +static const long _vq_quantlist__44pn1_p3_1[] = {
604.11614 +	2,
604.11615 +	1,
604.11616 +	3,
604.11617 +	0,
604.11618 +	4,
604.11619 +};
604.11620 +
604.11621 +static const long _vq_lengthlist__44pn1_p3_1[] = {
604.11622 +	 2, 3, 4, 9, 9,10,12,12,12,11,10,12,12,13,12,11,
604.11623 +	13,12,11,11,11,12,12,12,11,11,13,13,13,13,11,12,
604.11624 +	12,14,14,12,13,13,13,13,11,13,13,13,13,11,13,13,
604.11625 +	13,13,11,13,13,13,13,11,12,12,14,14,12,13,13,12,
604.11626 +	12,11,13,13,13,13,11,13,13,12,12,11,13,13,13,13,
604.11627 +	12,12,13,14,14,12,13,13,12,12,11,13,13,13,13,11,
604.11628 +	13,13,12,12,11,13,13,13,13,12,13,13,14,14,12,13,
604.11629 +	13,12,12,11,13,13,13,13,11,13,13,12,12,11,10,10,
604.11630 +	10,10,12,10,10,11,11,12, 9, 9,11,11,13,11,11,10,
604.11631 +	10,13,10,10,10,10,13,11,11,12,12,13,10,10,12,12,
604.11632 +	14,12,11,12,12,13,11,11,11,12,13,12,12,12,12,13,
604.11633 +	11,11,12,12,13,10,10,12,12,14,11,11,12,12,13,11,
604.11634 +	11,12,12,13,11,11,12,12,14,12,12,12,12,14,10,10,
604.11635 +	11,11,14,12,11,11,11,13,11,11,11,11,13,12,12,11,
604.11636 +	11,14,12,12,12,11,14,10,10,11,11,14,12,11,11,11,
604.11637 +	13,11,11,11,11,13,12,12,11,11,11,11,11,10,10,12,
604.11638 +	10,11, 9, 9,12,12,12,11,11,13,12,12, 9, 9,13,13,
604.11639 +	13,10,10,13,13,13,12,12,13,13,13,14,14,13,12,12,
604.11640 +	11,11,14,13,13,12,12,14,13,13,11,11,13,13,13,12,
604.11641 +	11,13,13,13,14,14,13,12,12,10,10,14,13,13,11,11,
604.11642 +	13,13,13,10,10,13,13,13,11,11,14,13,13,14,14,14,
604.11643 +	12,12,10,10,13,13,13,11,11,13,13,13,10,10,13,13,
604.11644 +	13,11,11,14,13,13,14,14,14,13,13,10,10,13,13,13,
604.11645 +	11,11,13,13,13,10,10,14,12,12, 8, 8,14,12,12, 9,
604.11646 +	 9,14,11,11, 9, 9,14,12,12, 8, 8,14,12,12, 7, 7,
604.11647 +	15,13,13,10,10,15,12,12,10,10,15,13,13,10,10,15,
604.11648 +	12,13, 9, 9,15,13,13,10,10,15,13,13,10,10,15,12,
604.11649 +	12,10,10,15,13,13,10,10,15,13,13, 9, 9,15,13,13,
604.11650 +	10,10,15,13,13,10,10,15,12,12,10,10,15,13,13, 9,
604.11651 +	 9,14,13,12, 9, 9,14,13,13, 9, 9,15,13,13,10,10,
604.11652 +	15,12,12,10,10,15,13,13, 9, 9,15,13,13, 9, 9,14,
604.11653 +	13,13, 9, 9,14,12,12, 8, 8,13,13,13, 8, 8,14,14,
604.11654 +	13, 9, 9,14,14,13, 7, 7,14,14,14, 8, 8,14,14,14,
604.11655 +	10,10,15,14,14,12,12,14,14,14, 9, 9,15,14,14,10,
604.11656 +	10,14,14,14, 9, 9,14,14,14,10, 9,15,14,14,12,12,
604.11657 +	14,14,14, 9, 9,15,14,14,10,10,14,14,14, 9, 9,15,
604.11658 +	14,15, 9, 9,15,14,14,11,11,14,14,14, 8, 8,14,14,
604.11659 +	14, 9, 9,14,14,14, 8, 8,14,15,14,10,10,15,14,14,
604.11660 +	11,11,14,14,14, 8, 8,15,14,14, 9, 9,14,14,14, 8,
604.11661 +	 8,12,12,12,13,13,16,16,15,12,12,17,16,16,13,13,
604.11662 +	17,16,16,11,11,17,16,16,12,12,17,16,17,13,13,17,
604.11663 +	16,16,14,14,17,17,16,12,12,18,16,16,13,13,17,16,
604.11664 +	17,12,12,17,17,17,13,13,18,16,16,14,14,18,17,17,
604.11665 +	12,12,17,17,17,13,13,18,17,17,13,13,17,17,17,13,
604.11666 +	13,17,16,16,14,14,17,17,17,12,12,16,16,17,13,13,
604.11667 +	17,17,16,12,12,18,17,17,13,13,18,16,16,14,14,18,
604.11668 +	17,17,12,12,19,16,17,13,13,17,16,17,12,12,13,14,
604.11669 +	14,10,10,16,14,14,13,13,17,15,15,14,14,17,14,14,
604.11670 +	13,13,16,14,14,13,13,17,16,15,14,14,16,16,16,15,
604.11671 +	15,17,15,15,14,14,17,15,15,14,14,17,15,15,14,14,
604.11672 +	17,16,15,14,14,16,16,16,15,15,18,15,15,13,13,16,
604.11673 +	16,15,14,14,17,15,15,14,13,17,15,15,14,14,16,16,
604.11674 +	16,15,15,18,15,14,13,13,17,15,15,14,14,18,14,15,
604.11675 +	13,13,18,15,15,14,14,16,16,16,15,15,17,15,15,13,
604.11676 +	13,17,15,15,14,14,17,15,15,13,13,13,11,11,10,10,
604.11677 +	16,14,14,13,13,17,14,15,14,14,17,15,15,12,12,17,
604.11678 +	14,14,12,12,16,15,15,14,14,16,14,14,14,14,16,15,
604.11679 +	15,14,14,16,15,15,14,14,16,15,15,14,14,16,15,15,
604.11680 +	14,14,16,15,14,15,15,17,15,15,14,14,17,15,15,14,
604.11681 +	14,17,15,15,14,14,17,15,16,14,14,16,14,14,14,14,
604.11682 +	17,15,15,13,13,17,15,15,13,13,16,15,15,13,13,17,
604.11683 +	16,16,14,14,17,15,14,15,14,17,15,15,13,13,17,15,
604.11684 +	15,13,13,17,15,15,13,13,14,14,14, 9, 9,14,14,14,
604.11685 +	18,19,14,15,15,19,18,14,14,14,19,19,15,14,14,19,
604.11686 +	19,15,16,16,19,19,15,16,16,19,19,15,15,15,19,19,
604.11687 +	15,16,16,19,20,15,15,15,19,19,15,15,15,19,19,15,
604.11688 +	16,16,20,20,15,15,15,18,19,15,15,16,19,20,15,15,
604.11689 +	15,19,18,15,15,15,18,18,15,16,16,21,20,15,15,15,
604.11690 +	19,19,15,15,15,19,19,15,15,14,19,20,15,15,15,20,
604.11691 +	19,15,16,16,19,20,15,15,15,19,19,15,15,15,20,21,
604.11692 +	15,14,15,19,19,14,12,12, 9, 9,14,14,15,21,19,14,
604.11693 +	14,14,18,19,14,15,15,19,20,14,14,14,19,19,15,15,
604.11694 +	15,19,20,15,15,14,21,19,15,15,15,20,19,15,14,15,
604.11695 +	20,21,15,15,15,18,18,15,15,15,20,21,16,14,14,18,
604.11696 +	19,15,15,15,20,19,15,15,15,18,21,15,15,15,19,19,
604.11697 +	15,15,15,19,20,16,15,14,20,19,15,16,15,19,19,15,
604.11698 +	15,15,19, 0,14,15,15,19,19,15,15,15,19,19,15,15,
604.11699 +	14,20,19,15,15,15,20,19,15,15,15,19,19,15,15,15,
604.11700 +	20,19,12,12,12,13,13,16,15,16,11,11,16,16,16,12,
604.11701 +	12,17,16,16,11,11,17,16,16,12,11,17,17,17,13,13,
604.11702 +	18,16,16,14,14,18,18,17,13,13,17,16,16,13,13,17,
604.11703 +	17,17,13,13,17,16,17,12,12,17,15,16,13,13,17,16,
604.11704 +	17,12,12,17,16,16,13,12,17,16,16,12,12,18,17,17,
604.11705 +	13,13,18,16,16,13,14,18,17,17,12,12,17,16,16,12,
604.11706 +	12,17,17,17,12,12,18,17,17,13,13,17,16,16,14,14,
604.11707 +	17,17,17,12,12,17,16,16,12,12,18,17,17,12,12,13,
604.11708 +	14,14, 9, 9,16,14,14,13,13,16,15,15,14,14,16,14,
604.11709 +	14,13,13,16,14,14,13,13,17,16,15,15,15,16,15,16,
604.11710 +	16,15,17,15,15,14,14,17,15,15,15,15,17,15,15,14,
604.11711 +	14,17,15,15,14,14,16,15,16,16,16,17,15,15,14,14,
604.11712 +	16,15,15,14,15,16,15,15,14,14,17,15,15,15,15,16,
604.11713 +	16,16,15,16,18,15,14,13,14,17,15,15,14,14,17,14,
604.11714 +	14,13,13,17,15,15,14,14,16,15,15,15,15,17,15,14,
604.11715 +	14,14,17,15,15,14,14,17,14,14,13,13,13,11,11,11,
604.11716 +	11,16,14,14,12,12,16,14,14,13,13,16,14,14,12,12,
604.11717 +	16,14,14,12,12,16,15,15,13,13,17,14,14,14,14,17,
604.11718 +	15,15,13,13,16,15,15,14,13,16,15,15,13,13,16,15,
604.11719 +	15,13,13,16,14,14,14,14,16,15,15,13,13,16,14,15,
604.11720 +	13,13,17,15,15,13,13,17,15,15,13,13,16,14,14,14,
604.11721 +	14,17,15,15,12,12,17,14,15,13,13,17,15,15,12,12,
604.11722 +	16,15,15,13,13,17,14,14,14,14,17,15,15,12,12,17,
604.11723 +	15,15,13,13,16,15,15,12,12,14,15,15, 8, 8,14,14,
604.11724 +	14,19,18,14,15,15,19,20,14,14,14,19,19,14,14,15,
604.11725 +	19,20,15,16,15,19,21,15,16,16,21,19,15,15,15,20,
604.11726 +	19,15,16,16,19,20,15,15,15,19,18,15,16,15,20,19,
604.11727 +	15,16,16,19,20,15,15,15,19,19,15,16,15,20,20,14,
604.11728 +	15,15,19,19,15,15,15,21,19,15,17,16,19,20,15,14,
604.11729 +	15, 0,21,15,15,15,19,20,14,14,14,19,19,15,15,15,
604.11730 +	20,19,15,16,16,19,19,15,15,15,19,18,15,15,15,20,
604.11731 +	19,14,14,15,18,18,14,12,12, 9, 9,14,14,14,18,18,
604.11732 +	14,14,14,18,18,14,15,14,19,18,14,14,14,19,18,15,
604.11733 +	15,15,19,20,15,14,14,18,18,15,15,15,20,19,15,15,
604.11734 +	15,18,20,15,15,15,19,18,15,15,15,19,19,15,14,14,
604.11735 +	19,21,15,15,15,20,20,15,15,15,18,19,14,15,15,19,
604.11736 +	20,15,15,15,20,19,15,14,14,19,21,15,15,15,18,19,
604.11737 +	15,14,15,20,19,14,15,15,21,21,14,15,15,19,20,15,
604.11738 +	14,14,19,20,15,15,15,19,20,15,15,14,20,20,14,15,
604.11739 +	15,20,19,13,12,12,13,13,17,16,16,11,11,17,16,16,
604.11740 +	12,12,18,17,16,11,11,18,16,16,11,11,17,17,17,13,
604.11741 +	13,18,16,16,13,13,18,17,17,12,12,18,16,16,13,13,
604.11742 +	18,17,17,12,12,18,17,17,13,13,18,16,16,14,14,18,
604.11743 +	16,17,12,12,18,17,17,13,13,17,17,17,12,12,17,17,
604.11744 +	17,12,12,17,16,15,13,13,18,16,16,11,11,17,16,16,
604.11745 +	12,12,17,16,17,11,11,18,17,17,13,12,17,16,16,13,
604.11746 +	13,17,17,17,12,12,17,16,17,12,12,18,17,17,11,11,
604.11747 +	14,14,14, 9, 9,16,14,14,13,13,17,15,15,14,14,17,
604.11748 +	14,14,13,13,16,14,14,13,13,17,15,15,14,14,16,16,
604.11749 +	16,16,15,18,15,15,14,14,17,16,15,15,15,17,15,15,
604.11750 +	14,14,17,15,15,14,15,16,16,16,15,16,18,15,15,14,
604.11751 +	14,17,15,15,14,15,17,15,15,14,14,17,15,15,14,14,
604.11752 +	16,16,16,15,16,17,14,14,13,13,17,15,15,14,14,18,
604.11753 +	15,15,13,13,17,15,15,14,14,16,16,16,15,15,17,14,
604.11754 +	14,13,13,17,15,15,14,14,17,14,14,13,13,13,11,11,
604.11755 +	11,11,16,14,14,12,12,16,14,14,12,13,17,15,14,11,
604.11756 +	11,17,14,14,11,11,17,15,15,13,14,17,14,14,14,14,
604.11757 +	17,15,15,13,13,17,14,14,13,13,17,15,15,13,13,17,
604.11758 +	15,15,13,13,17,14,14,14,14,17,15,15,13,13,18,14,
604.11759 +	15,13,13,17,15,15,13,13,16,15,15,13,13,17,14,14,
604.11760 +	13,13,17,15,15,12,12,16,14,14,12,12,16,15,15,12,
604.11761 +	12,17,16,15,13,13,17,14,14,13,13,17,15,15,12,12,
604.11762 +	16,15,15,12,12,16,15,15,12,12,13,15,15, 8, 8,14,
604.11763 +	14,14,18,19,14,15,15,19,20,14,14,14,18,18,14,15,
604.11764 +	15,18,18,15,16,16,19,19,15,16,17,20,20,15,15,15,
604.11765 +	19,19,15,16,16,18,20,15,15,15,19,19,15,15,16,18,
604.11766 +	18,15,17,16,19,19,15,15,15,18,21,15,16,16,21,20,
604.11767 +	15,15,15,19,21,15,16,15,20,19,15,16,17,20,20,15,
604.11768 +	15,15,19,19,15,16,16,21,20,15,15,15,19,20,15,15,
604.11769 +	15,19,19,15,16,16,20,19,15,15,15,19,19,15,16,15,
604.11770 +	20,21,15,15,15,21,19,14,12,12, 8, 8,14,14,14,20,
604.11771 +	18,14,13,13,19,19,14,14,14,19,18,15,14,14,19,20,
604.11772 +	14,15,15,20,20,15,14,14,21,20,15,15,15,20,20,15,
604.11773 +	15,14,21,19,15,15,15,19,19,15,15,15,19,20,15,14,
604.11774 +	14,20,20,15,15,15,19,20,15,14,14,19,20,15,15,15,
604.11775 +	20,20,15,15,15,20,19,15,14,14,20,21,15,15,15,20,
604.11776 +	21,15,14,14,20, 0,15,16,15,20,21,15,15,15,19,20,
604.11777 +	15,14,14,19,19,15,15,15,19,20,15,15,15,19,19,15,
604.11778 +	15,15,18,20,13,12,12,13,13,18,16,17,12,12,17,16,
604.11779 +	16,12,12,17,17,16,11,11,18,16,16,11,11,17,17,18,
604.11780 +	13,13,18,16,16,14,14,18,17,17,13,13,18,16,16,13,
604.11781 +	13,18,17,17,12,12,17,17,16,13,13,17,16,16,13,14,
604.11782 +	18,17,17,12,12,18,16,16,12,13,17,16,17,12,12,17,
604.11783 +	18,17,13,13,18,16,16,13,13,18,17,17,12,12,17,16,
604.11784 +	16,12,12,17,17,17,11,11,17,16,17,12,12,17,16,16,
604.11785 +	13,13,17,16,16,11,11,17,16,16,12,12,18,16,17,11,
604.11786 +	11,14,14,14, 9, 9,16,14,15,13,13,17,15,15,14,14,
604.11787 +	17,14,14,12,12,16,14,14,13,13,18,15,15,15,15,17,
604.11788 +	15,16,15,16,18,15,15,14,14,17,15,16,15,15,17,15,
604.11789 +	15,14,14,18,15,15,14,14,16,16,16,16,15,17,15,15,
604.11790 +	14,14,16,15,15,14,14,17,15,15,14,14,17,15,15,14,
604.11791 +	14,17,16,16,15,15,17,15,14,13,13,17,15,15,14,14,
604.11792 +	17,15,15,13,13,17,15,15,14,14,16,16,16,15,15,18,
604.11793 +	15,14,14,14,17,15,15,14,14,18,15,15,13,13,13,12,
604.11794 +	12,11,11,16,14,14,12,12,16,14,14,13,13,17,15,15,
604.11795 +	12,12,17,14,14,12,12,17,15,15,14,14,17,14,14,14,
604.11796 +	14,17,15,15,13,13,17,15,14,13,13,17,15,15,13,13,
604.11797 +	17,15,15,13,13,16,14,14,14,14,17,15,15,13,13,16,
604.11798 +	14,14,13,13,16,15,15,13,13,17,15,16,13,13,17,14,
604.11799 +	14,14,13,17,15,15,12,12,16,15,14,12,12,17,15,15,
604.11800 +	12,12,16,15,16,13,13,16,14,14,14,13,17,15,15,12,
604.11801 +	12,16,14,14,12,12,17,15,15,12,12,14,15,15, 8, 8,
604.11802 +	14,14,14,18,18,14,15,15,19,18,14,14,14,18,18,14,
604.11803 +	15,15,19,20,15,16,15,21,18,15,16,16,18, 0,15,15,
604.11804 +	15,19,20,15,16,16,20, 0,15,16,15,19,18,15,15,15,
604.11805 +	19,19,15,16,16,21,19,15,15,15,19,19,15,16,16,20,
604.11806 +	20,15,15,15,19,19,15,15,15,19,18,15,16,16,20,20,
604.11807 +	15,14,15,20,19,15,15,15,19,20,15,15,15,19,19,15,
604.11808 +	16,15,19,20,15,16,16,19,20,15,15,15,19,19,15,16,
604.11809 +	15,20,20,15,15,15,20,18,13,12,12, 8, 8,14,14,14,
604.11810 +	19,20,14,14,14,19,19,14,15,15,20,20,14,14,14,18,
604.11811 +	19,15,15,15,20, 0,15,14,14,18,20,15,15,15,19,19,
604.11812 +	15,15,15,21,19,15,15,15,19,20,15,15,15,20,21,15,
604.11813 +	14,14,20,19,15,15,15,20,19,15,15,14,21,19,15,15,
604.11814 +	15,19,18,15,15,15,20,19,15,14,14,19,19,15,15,16,
604.11815 +	20,19,15,15,15,20, 0,15,15,15,19,21,15,15,15,22,
604.11816 +	20,15,14,14,22,19,15,15,15,19,20,15,14,14,20,19,
604.11817 +	14,15,15,19,21,
604.11818 +};
604.11819 +
604.11820 +static const static_codebook _44pn1_p3_1 = {
604.11821 +	5, 3125,
604.11822 +	(long *)_vq_lengthlist__44pn1_p3_1,
604.11823 +	1, -533725184, 1611661312, 3, 0,
604.11824 +	(long *)_vq_quantlist__44pn1_p3_1,
604.11825 +	0
604.11826 +};
604.11827 +
604.11828 +static const long _vq_quantlist__44pn1_p4_0[] = {
604.11829 +	2,
604.11830 +	1,
604.11831 +	3,
604.11832 +	0,
604.11833 +	4,
604.11834 +};
604.11835 +
604.11836 +static const long _vq_lengthlist__44pn1_p4_0[] = {
604.11837 +	 1, 7, 7,14,14, 6, 8, 8,15,16, 7, 8, 8,16,15, 0,
604.11838 +	14,14,17,17, 0,14,14,16,16, 7, 9, 9,16,16,10,11,
604.11839 +	11,17,18, 9, 8, 8,16,16, 0,14,14,19,19, 0,14,14,
604.11840 +	17,16, 8, 9, 9,16,16,12,12,12,17,17,10, 9, 9,16,
604.11841 +	16, 0,15,14,18,20, 0,14,14,17,17, 0,15,15,18,17,
604.11842 +	 0,21, 0, 0,21, 0,13,13,17,17, 0,17,17, 0, 0, 0,
604.11843 +	15,15,17,17, 0,15,15,17,18, 0, 0, 0, 0,21, 0,13,
604.11844 +	13,17,17, 0,18,18, 0,21, 0,16,15,17,18, 6, 7, 7,
604.11845 +	14,14, 9,10,10,16,16,11,10,10,15,15, 0,21, 0,20,
604.11846 +	21, 0, 0, 0,18,20,10,10,10,15,16,12,13,13,18,18,
604.11847 +	12,11,11,15,15, 0, 0, 0,20,20, 0, 0,21,19,19,12,
604.11848 +	11,11,15,15,15,14,14,18,18,13,11,11,15,16, 0, 0,
604.11849 +	 0,20,19, 0, 0, 0,20,21, 0, 0,20,19,19, 0, 0, 0,
604.11850 +	 0, 0, 0,20, 0,17,18, 0, 0,21, 0, 0, 0, 0, 0,21,
604.11851 +	 0, 0,21, 0,20,19, 0, 0, 0, 0, 0, 0,21, 0,18,18,
604.11852 +	 0, 0, 0,21, 0, 0, 0, 0, 0,20, 7, 6, 6,13,13, 9,
604.11853 +	 6, 6,12,12, 9, 7, 7,14,14, 0,10,10,12,12, 0,11,
604.11854 +	11,15,15, 9, 7, 7,14,14,12, 9, 9,14,14,10, 7, 7,
604.11855 +	14,13, 0,11,11,16,15, 0,11,11,14,14, 9, 7, 7,14,
604.11856 +	14,13,10,10,14,14,11, 7, 7,14,13, 0,11,11,16,16,
604.11857 +	 0,11,11,14,14, 0,12,12,16,16, 0,19, 0,17,18, 0,
604.11858 +	10,10,14,14, 0,15,14, 0, 0, 0,12,12,14,14, 0,12,
604.11859 +	12,15,15, 0,20, 0,18,19, 0,10,10,14,14, 0,16,15,
604.11860 +	 0,20, 0,13,13,14,14, 0,11,11,13,13, 0,12,13,16,
604.11861 +	16, 0,12,12,16,16, 0,16,16, 0,21, 0,17,18, 0, 0,
604.11862 +	 0,12,12,16,16, 0,15,15,18, 0, 0,12,12,16,16, 0,
604.11863 +	17,16,21,21, 0,16,17, 0, 0, 0,13,13,17,16, 0,16,
604.11864 +	16,20,21, 0,12,12,17,16, 0,17,17, 0,21, 0,17,17,
604.11865 +	21,21, 0,17,18, 0, 0, 0, 0, 0, 0, 0, 0,15,15, 0,
604.11866 +	 0, 0,18,21, 0, 0, 0,18,19, 0, 0, 0,18,17,21,21,
604.11867 +	 0, 0, 0, 0, 0, 0,16,16, 0, 0, 0, 0, 0, 0, 0, 0,
604.11868 +	19,19, 0, 0, 0,11,11,12,12, 0,11,11,10,10, 0,12,
604.11869 +	12,13,13, 0,12,12, 9, 9, 0,14,14,13,13, 0,12,12,
604.11870 +	13,13, 0,14,14,12,13, 0,11,11,12,12, 0,13,13,13,
604.11871 +	13, 0,13,13,13,13, 0,12,12,13,13, 0,14,14,12,12,
604.11872 +	 0,11,11,12,12, 0,14,13,14,14, 0,13,13,13,13, 0,
604.11873 +	15,15,14,15, 0, 0, 0,16,16, 0,12,12,13,13, 0,16,
604.11874 +	17,20,21, 0,14,13,12,12, 0,14,14,14,14, 0,21, 0,
604.11875 +	16,16, 0,12,12,13,13, 0,18,17,21, 0, 0,14,14,13,
604.11876 +	13, 7, 8, 8,17,17,11,10,10,18,18,12,10,10,17,17,
604.11877 +	 0,15,15,20,18, 0,15,15,17,17,11, 9, 9,17,17,14,
604.11878 +	12,12,19,19,13, 9, 9,16,16, 0,15,14, 0,19, 0,14,
604.11879 +	14,16,16,12,10,10,20,18,16,13,13,21,20,14,10,10,
604.11880 +	17,17, 0,15,15,21,20, 0,15,14,17,17, 0,15,15,21,
604.11881 +	21, 0, 0,21, 0, 0, 0,13,13,18,18, 0,19,16, 0, 0,
604.11882 +	 0,15,15,17,16, 0,16,16, 0,21, 0, 0, 0, 0,21, 0,
604.11883 +	13,14,18,17, 0,20,19, 0, 0, 0,15,15,18,18, 8, 7,
604.11884 +	 7,15,15,12,11,11,17,16,13,11,11,16,16, 0, 0, 0,
604.11885 +	21,20, 0, 0, 0, 0,20,11,10,10,17,17,14,13,13,19,
604.11886 +	18,14,11,11,16,16, 0,20, 0,21,19, 0, 0,21, 0,20,
604.11887 +	12,11,11,17,17,16,15,15, 0,19,14,11,11,17,16, 0,
604.11888 +	21, 0, 0,19, 0, 0, 0,21,20, 0, 0,21,20, 0, 0, 0,
604.11889 +	 0, 0, 0, 0, 0, 0,19,21, 0, 0, 0, 0, 0, 0, 0, 0,
604.11890 +	19,20, 0, 0, 0,20,21, 0, 0, 0, 0, 0, 0,20, 0,19,
604.11891 +	21, 0, 0, 0, 0, 0, 0, 0, 0,21,20,11,10, 9,15,15,
604.11892 +	14,11,11,15,15,14,11,11,16,16, 0,14,14,14,14, 0,
604.11893 +	16,15,17,16,13,11,11,16,16,16,13,13,16,16,15,10,
604.11894 +	10,15,15, 0,14,15,17,17, 0,14,14,16,15,13,11,11,
604.11895 +	16,16,17,15,14,16,16,15,10,10,15,15, 0,15,15,17,
604.11896 +	18, 0,15,15,16,16, 0,16,16,17,17, 0,21, 0,21,20,
604.11897 +	 0,13,13,15,15, 0,18,18, 0,21, 0,15,15,15,15, 0,
604.11898 +	16,16,17,17, 0, 0, 0, 0,18, 0,13,13,15,15, 0,19,
604.11899 +	18, 0, 0, 0,15,15,16,16, 0,12,12,15,15, 0,13,13,
604.11900 +	17,17, 0,13,13,17,18, 0,16,17,21, 0, 0,20,18, 0,
604.11901 +	 0, 0,13,13,17,17, 0,15,15, 0,18, 0,12,12,17,18,
604.11902 +	 0,16,16, 0, 0, 0,17,17,21, 0, 0,13,13,18,18, 0,
604.11903 +	16,16,21,21, 0,12,12,17,18, 0,16,17,21, 0, 0,17,
604.11904 +	17, 0,21, 0,17,18, 0, 0, 0, 0, 0, 0, 0, 0,16,15,
604.11905 +	 0,21, 0,21,19, 0, 0, 0,18,18, 0, 0, 0,18,19, 0,
604.11906 +	 0, 0, 0, 0, 0, 0, 0,16,16,21,21, 0,20,19, 0, 0,
604.11907 +	 0,19,21, 0,21, 0,12,12,15,15, 0,12,12,15,16, 0,
604.11908 +	13,13,16,16, 0,14,14,15,15, 0,16,15,17,17, 0,13,
604.11909 +	13,17,17, 0,15,15,16,18, 0,12,12,16,16, 0,14,14,
604.11910 +	17,17, 0,15,14,16,16, 0,13,13,16,16, 0,16,15,17,
604.11911 +	17, 0,12,12,16,16, 0,15,15,18,18, 0,14,14,17,16,
604.11912 +	 0,16,16,17,18, 0, 0, 0,20,21, 0,13,13,16,17, 0,
604.11913 +	17,17, 0, 0, 0,15,15,16,16, 0,15,16,17,17, 0, 0,
604.11914 +	 0,19, 0, 0,13,13,15,16, 0,19,18, 0, 0, 0,16,15,
604.11915 +	16,17, 8, 8, 8,17,17,13,11,10,17,18,13,10,10,17,
604.11916 +	17, 0,15,15,20,19, 0,15,15,17,17,12,10,10,19,18,
604.11917 +	15,12,12,20,18,14,10,10,17,16, 0,15,15,20,20, 0,
604.11918 +	14,15,16,16,13,10,10,17,17,17,14,14, 0,18,15,10,
604.11919 +	10,17,17, 0,16,15,20,20, 0,14,14,17,17, 0,15,16,
604.11920 +	20,20, 0, 0,21, 0, 0, 0,13,13,17,17, 0,18,17, 0,
604.11921 +	 0, 0,15,16,17,18, 0,15,15,18,21, 0, 0, 0,21, 0,
604.11922 +	 0,13,13,18,18, 0,19,19, 0, 0, 0,16,16,18,17, 9,
604.11923 +	 8, 8,15,15,12,11,11,16,16,13,11,11,16,15, 0, 0,
604.11924 +	 0, 0,21, 0,21, 0,19,19,12,11,11,17,18,15,13,13,
604.11925 +	18,19,14,11,11,16,16, 0, 0,21,21,19, 0, 0, 0,21,
604.11926 +	20,13,11,11,18,17,17,14,15,20,21,15,11,12,16,16,
604.11927 +	 0, 0, 0,20, 0, 0, 0,21, 0,19, 0, 0, 0, 0,19, 0,
604.11928 +	 0, 0, 0, 0, 0,21,21,19,19, 0, 0, 0,21, 0, 0, 0,
604.11929 +	 0,19,21, 0, 0, 0,19,20, 0, 0, 0,21, 0, 0, 0,21,
604.11930 +	19,19, 0, 0, 0, 0, 0, 0, 0, 0,21,20, 0,11,11,15,
604.11931 +	15, 0,12,12,15,16, 0,12,12,16,16, 0,15,15,16,15,
604.11932 +	 0,16,16,17,17, 0,12,12,17,17, 0,14,14,17,17, 0,
604.11933 +	11,11,16,16, 0,15,15,19,18, 0,15,15,16,16, 0,12,
604.11934 +	12,17,16, 0,14,15,16,16, 0,11,11,15,15, 0,16,16,
604.11935 +	18,19, 0,15,15,15,16, 0,17,17,18,20, 0,21, 0,21,
604.11936 +	19, 0,14,14,16,16, 0,18,18, 0, 0, 0,16,16,15,15,
604.11937 +	 0,16,16,18,17, 0, 0, 0,19,20, 0,14,14,16,16, 0,
604.11938 +	19,19, 0, 0, 0,16,17,15,15, 0,12,12,14,15, 0,13,
604.11939 +	13,16,17, 0,12,12,17,17, 0,17,16, 0, 0, 0,18,17,
604.11940 +	21, 0, 0,13,13,19,17, 0,15,15,20,21, 0,12,12,17,
604.11941 +	17, 0,17,17, 0, 0, 0,17,17, 0, 0, 0,13,13,17,18,
604.11942 +	 0,16,16,21, 0, 0,12,12,17,17, 0,17,17, 0, 0, 0,
604.11943 +	17,17, 0, 0, 0,18,21, 0, 0, 0, 0, 0, 0, 0, 0,15,
604.11944 +	15,21, 0, 0,20,21, 0, 0, 0,18,19, 0, 0, 0,18,17,
604.11945 +	 0, 0, 0, 0, 0, 0, 0, 0,16,16,21, 0, 0,21,21, 0,
604.11946 +	 0, 0,18,19, 0, 0, 0,12,12,16,16, 0,13,13,16,17,
604.11947 +	 0,13,13,17,16, 0,14,14,16,16, 0,16,15,19,18, 0,
604.11948 +	13,13,17,17, 0,15,15,18,18, 0,12,12,16,16, 0,15,
604.11949 +	15,18,19, 0,15,15,17,16, 0,13,13,17,17, 0,16,16,
604.11950 +	18,17, 0,12,12,17,16, 0,15,15,18,18, 0,15,15,17,
604.11951 +	17, 0,16,16, 0,19, 0, 0, 0, 0, 0, 0,14,14,16,17,
604.11952 +	 0,18,18, 0, 0, 0,15,15,17,17, 0,16,16,21,19, 0,
604.11953 +	21, 0,21,21, 0,13,14,16,16, 0,19,19, 0, 0, 0,15,
604.11954 +	16,16,16, 0,11,11,17,16, 0,15,14,19,18, 0,14,14,
604.11955 +	19,19, 0,18,17,18,20, 0,17,17,18,19, 0,13,13,17,
604.11956 +	17, 0,16,17,21,18, 0,13,13,17,16, 0,18,17,19, 0,
604.11957 +	 0,16,17,18,18, 0,12,12,19,18, 0,18,18,20,20, 0,
604.11958 +	13,13,17,17, 0,17,17,21, 0, 0,16,17,17,18, 0,18,
604.11959 +	17,19,18, 0, 0, 0, 0, 0, 0,14,14,17,17, 0,19,19,
604.11960 +	21, 0, 0,16,16,16,17, 0,17,17,19,20, 0, 0, 0, 0,
604.11961 +	21, 0,15,15,17,18, 0,21,21, 0, 0, 0,17,17,17,18,
604.11962 +	 0,10,10,15,15, 0,15,14,17,18, 0,14,14,16,16, 0,
604.11963 +	 0, 0,18, 0, 0,21, 0,19, 0, 0,13,13,17,16, 0,17,
604.11964 +	17,18, 0, 0,14,14,16,15, 0, 0, 0,21, 0, 0,21, 0,
604.11965 +	19,18, 0,13,13,17,17, 0,18,18,20,20, 0,15,15,16,
604.11966 +	16, 0, 0, 0,21,21, 0, 0, 0,20,20, 0, 0, 0,19, 0,
604.11967 +	 0, 0, 0, 0, 0, 0,21,20,18,18, 0, 0, 0, 0, 0, 0,
604.11968 +	 0, 0, 0,20, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,
604.11969 +	 0,19,18, 0, 0, 0, 0,21, 0, 0, 0,18,20, 0,18,19,
604.11970 +	16,17, 0,21,19,17,17, 0, 0,21,18,18, 0, 0,21,20,
604.11971 +	19, 0, 0, 0,20,20, 0, 0,21,17,17, 0, 0, 0,19,19,
604.11972 +	 0,20,20,17,17, 0, 0, 0, 0,20, 0, 0,20,18,18, 0,
604.11973 +	21,20,17,17, 0, 0, 0,20,21, 0,19, 0,17,17, 0, 0,
604.11974 +	21, 0, 0, 0,20, 0,18,19, 0, 0, 0,21,21, 0, 0, 0,
604.11975 +	 0,21, 0,20,20,17,17, 0, 0, 0, 0, 0, 0,21, 0,18,
604.11976 +	17, 0, 0, 0,20,19, 0, 0, 0, 0,21, 0,20,20,17,17,
604.11977 +	 0, 0, 0, 0, 0, 0,21,21,18,18, 0,12,12,15,14, 0,
604.11978 +	14,14,17,17, 0,14,14,17,16, 0,18,18,21, 0, 0,19,
604.11979 +	20, 0, 0, 0,13,13,18,17, 0,16,16,19,18, 0,13,13,
604.11980 +	17,17, 0,17,17, 0, 0, 0,17,17,21, 0, 0,13,13,17,
604.11981 +	17, 0,17,17,21,20, 0,13,13,18,17, 0,18,19,21,21,
604.11982 +	 0,19,18, 0, 0, 0,18,17, 0, 0, 0, 0, 0, 0, 0, 0,
604.11983 +	15,16, 0, 0, 0,21,21, 0, 0, 0,20,18,21, 0, 0,17,
604.11984 +	18, 0, 0, 0, 0, 0, 0, 0, 0,15,16, 0, 0, 0, 0,20,
604.11985 +	 0, 0, 0, 0,19, 0, 0, 0,15,15,18,19, 0,18,17,21,
604.11986 +	 0, 0,16,18, 0,20, 0,17,18,21, 0, 0,18,20, 0, 0,
604.11987 +	 0,16,16,21,21, 0,19,20,21, 0, 0,16,15, 0,21, 0,
604.11988 +	18,20, 0, 0, 0,18,19, 0, 0, 0,16,15,21,21, 0,21,
604.11989 +	 0, 0, 0, 0,16,15,21, 0, 0,20,19, 0, 0, 0,18,21,
604.11990 +	21, 0, 0,20,18, 0, 0, 0, 0, 0, 0, 0, 0,16,16, 0,
604.11991 +	20, 0,21, 0, 0, 0, 0,17,18,20,21, 0,18,18,21,21,
604.11992 +	 0, 0, 0, 0, 0, 0,16,16,20, 0, 0, 0,21, 0, 0, 0,
604.11993 +	21,18, 0, 0, 0,12,12,20,17, 0,15,15,19,18, 0,14,
604.11994 +	14,19,18, 0,18,17,21,19, 0,17,17,21,17, 0,13,13,
604.11995 +	21,19, 0,16,17,20,19, 0,13,13,16,16, 0,17,17,20,
604.11996 +	21, 0,16,16,19,17, 0,13,13,18,18, 0,17,19,19,19,
604.11997 +	 0,13,13,17,17, 0,18,18, 0,19, 0,16,17,18,18, 0,
604.11998 +	16,17,19,21, 0, 0, 0, 0, 0, 0,15,15,16,17, 0,20,
604.11999 +	19,21, 0, 0,17,17,17,17, 0,17,17,21,19, 0, 0, 0,
604.12000 +	 0, 0, 0,15,15,17,17, 0,21, 0, 0, 0, 0,18,18,17,
604.12001 +	17, 0,10,10,15,15, 0,15,15,17,17, 0,15,14,16,16,
604.12002 +	 0, 0, 0,21,19, 0,21,21,19,21, 0,13,13,17,16, 0,
604.12003 +	17,17,18,19, 0,14,15,16,15, 0, 0, 0,21,19, 0,21,
604.12004 +	21,18,19, 0,14,14,16,17, 0,18,18,18,19, 0,15,15,
604.12005 +	15,16, 0, 0,21, 0,21, 0, 0, 0,19,20, 0, 0, 0,21,
604.12006 +	19, 0, 0, 0, 0, 0, 0,21,21,19,17, 0, 0, 0, 0, 0,
604.12007 +	 0, 0, 0,21,21, 0,21, 0, 0,21, 0, 0, 0, 0, 0, 0,
604.12008 +	21,21,19,18, 0, 0, 0, 0, 0, 0, 0, 0, 0,19, 0,21,
604.12009 +	18,18,17, 0,21, 0,20,20, 0, 0, 0,18,20, 0, 0,21,
604.12010 +	18,21, 0, 0, 0,21,18, 0, 0, 0, 0,19, 0, 0, 0,21,
604.12011 +	21, 0,20,21,17,19, 0,21, 0,21, 0, 0,21, 0,18,18,
604.12012 +	 0,20,21,17,18, 0, 0, 0,21,19, 0,20,21,17,18, 0,
604.12013 +	 0, 0,21,21, 0, 0, 0,20,19, 0, 0, 0,21,21, 0, 0,
604.12014 +	 0, 0, 0, 0,21,21,19,18, 0, 0, 0, 0, 0, 0, 0,21,
604.12015 +	19,18, 0,21,21,19, 0, 0, 0, 0,21, 0, 0,21,21,18,
604.12016 +	17, 0, 0, 0, 0, 0, 0,21, 0,21,18, 0,12,12,14,14,
604.12017 +	 0,15,14,17,17, 0,14,14,17,16, 0,19,17, 0, 0, 0,
604.12018 +	19,19, 0, 0, 0,13,13,17,17, 0,17,17,20,20, 0,13,
604.12019 +	13,18,18, 0,18,17, 0, 0, 0,18,21, 0, 0, 0,13,13,
604.12020 +	17,17, 0,18,18,21,20, 0,14,14,18,19, 0,19,18,21,
604.12021 +	 0, 0,19,19, 0, 0, 0,20,18,20, 0, 0, 0, 0, 0, 0,
604.12022 +	 0,15,16, 0, 0, 0,21,21, 0, 0, 0,19,19, 0, 0, 0,
604.12023 +	18,18, 0, 0, 0, 0, 0, 0, 0, 0,16,16, 0,21, 0, 0,
604.12024 +	 0, 0, 0, 0,19,20, 0, 0, 0,15,15,20,21, 0,17,17,
604.12025 +	21,21, 0,17,17, 0, 0, 0,19,18, 0, 0, 0,18,19, 0,
604.12026 +	 0, 0,17,16, 0,21, 0, 0,20, 0, 0, 0,16,16, 0,20,
604.12027 +	 0,19,19, 0,21, 0,19,18, 0,21, 0,16,16, 0, 0, 0,
604.12028 +	21,21, 0, 0, 0,16,16, 0, 0, 0,21,21, 0, 0, 0,19,
604.12029 +	19, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0, 0, 0,17,17,
604.12030 +	 0,21, 0, 0,20, 0, 0, 0,20,18,21,21, 0,19,18, 0,
604.12031 +	20, 0, 0, 0, 0, 0, 0,16,17,21, 0, 0, 0,21, 0, 0,
604.12032 +	 0,19,20,21,20,
604.12033 +};
604.12034 +
604.12035 +static const static_codebook _44pn1_p4_0 = {
604.12036 +	5, 3125,
604.12037 +	(long *)_vq_lengthlist__44pn1_p4_0,
604.12038 +	1, -528744448, 1616642048, 3, 0,
604.12039 +	(long *)_vq_quantlist__44pn1_p4_0,
604.12040 +	0
604.12041 +};
604.12042 +
604.12043 +static const long _vq_quantlist__44pn1_p4_1[] = {
604.12044 +	3,
604.12045 +	2,
604.12046 +	4,
604.12047 +	1,
604.12048 +	5,
604.12049 +	0,
604.12050 +	6,
604.12051 +};
604.12052 +
604.12053 +static const long _vq_lengthlist__44pn1_p4_1[] = {
604.12054 +	 2, 3, 3, 3, 3, 3, 3,
604.12055 +};
604.12056 +
604.12057 +static const static_codebook _44pn1_p4_1 = {
604.12058 +	1, 7,
604.12059 +	(long *)_vq_lengthlist__44pn1_p4_1,
604.12060 +	1, -533200896, 1611661312, 3, 0,
604.12061 +	(long *)_vq_quantlist__44pn1_p4_1,
604.12062 +	0
604.12063 +};
604.12064 +
604.12065 +static const long _vq_quantlist__44pn1_p5_0[] = {
604.12066 +	1,
604.12067 +	0,
604.12068 +	2,
604.12069 +};
604.12070 +
604.12071 +static const long _vq_lengthlist__44pn1_p5_0[] = {
604.12072 +	 1, 7, 7, 6, 8, 8, 7, 8, 8, 7, 9, 9,11,11,11, 9,
604.12073 +	 8, 8, 7, 9, 9,11,12,11, 9, 9, 9, 6, 7, 7,10,11,
604.12074 +	11,10,10,10,10,11,11,15,14,14,12,12,12,11,11,11,
604.12075 +	14,14,14,12,12,12, 5, 6, 6, 8, 5, 5, 8, 7, 7, 8,
604.12076 +	 8, 8,12,10,10,10, 7, 7, 8, 7, 7,12,10,10,10, 7,
604.12077 +	 7, 6, 7, 7,12,11,11,12,10,10,11,10,10,14,14,13,
604.12078 +	13,10,10,11,10,10,16,14,14,14,11,10, 7, 7, 7,13,
604.12079 +	12,12,12,12,11,11,11,11,15,14,17,13,12,12,12,11,
604.12080 +	11,15,15,15,14,13,13,10, 9, 9,14,12,11,13,11,11,
604.12081 +	12,11,11,16,15,14,14,11,11,12,11,11,17,14,14,15,
604.12082 +	11,11, 7, 8, 8,12,11,11,13,10,10,11,10,10,17,14,
604.12083 +	13,14,10,10,12,10,10,18,15,15,14,10,10, 8, 7, 7,
604.12084 +	13,12,12,13,11,11,12,11,11,16,14,15,14,12,12,12,
604.12085 +	11,11,18,16,16,14,12,12,11,10,10,13,12,11,13,11,
604.12086 +	11,13,12,12, 0,15,14,14,11,11,13,11,11,16,15,15,
604.12087 +	15,11,11,
604.12088 +};
604.12089 +
604.12090 +static const static_codebook _44pn1_p5_0 = {
604.12091 +	5, 243,
604.12092 +	(long *)_vq_lengthlist__44pn1_p5_0,
604.12093 +	1, -527106048, 1620377600, 2, 0,
604.12094 +	(long *)_vq_quantlist__44pn1_p5_0,
604.12095 +	0
604.12096 +};
604.12097 +
604.12098 +static const long _vq_quantlist__44pn1_p5_1[] = {
604.12099 +	1,
604.12100 +	0,
604.12101 +	2,
604.12102 +};
604.12103 +
604.12104 +static const long _vq_lengthlist__44pn1_p5_1[] = {
604.12105 +	 2, 6, 7, 6, 8, 8, 7, 7, 8, 7, 8, 8, 9, 9, 9, 8,
604.12106 +	 7, 7, 8, 8, 8, 9, 9, 9, 9, 8, 8, 6, 6, 6, 9, 7,
604.12107 +	 7, 9, 7, 7, 9, 8, 8,10, 8, 8,10, 8, 8,10, 8, 8,
604.12108 +	10, 9, 8,10, 8, 8, 7, 6, 6, 9, 6, 6, 9, 6, 6, 9,
604.12109 +	 7, 7,10, 8, 8,10, 6, 6, 9, 7, 7,10, 8, 8,10, 6,
604.12110 +	 6, 7, 7, 7,11, 9, 9,11, 9, 9,10, 9, 9,12,10,10,
604.12111 +	12, 8, 8,11, 9, 9,13, 9,10,12, 8, 8, 8, 7, 7,11,
604.12112 +	 9,10,11,10,10,10, 9, 9,11,11,11,11, 9, 9,11,10,
604.12113 +	 9,12,11,11,11, 9,10,10, 8, 8,11, 9,10,11, 9, 9,
604.12114 +	11, 9, 9,12,10,10,11, 9, 9,11, 9, 9,12,10,11,11,
604.12115 +	 9, 9, 8, 8, 8,12, 9, 9,12, 9, 9,11, 9, 9,13, 9,
604.12116 +	 9,13, 8, 8,12, 9, 9,13,10,10,12, 8, 8, 9, 7, 7,
604.12117 +	11,10,10,11,10,10,11,10,10,12,11,11,11,10, 9,11,
604.12118 +	10,10,11,11,11,11, 9, 9,11, 9, 9,12,10,10,11,10,
604.12119 +	10,12,10,10,11,11,11,11, 9, 9,11,10,10,12,11,11,
604.12120 +	11, 9, 9,
604.12121 +};
604.12122 +
604.12123 +static const static_codebook _44pn1_p5_1 = {
604.12124 +	5, 243,
604.12125 +	(long *)_vq_lengthlist__44pn1_p5_1,
604.12126 +	1, -530841600, 1616642048, 2, 0,
604.12127 +	(long *)_vq_quantlist__44pn1_p5_1,
604.12128 +	0
604.12129 +};
604.12130 +
604.12131 +static const long _vq_quantlist__44pn1_p6_0[] = {
604.12132 +	1,
604.12133 +	0,
604.12134 +	2,
604.12135 +};
604.12136 +
604.12137 +static const long _vq_lengthlist__44pn1_p6_0[] = {
604.12138 +	 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9,
604.12139 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12140 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12141 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12142 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12143 +	 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12144 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12145 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12146 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12147 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12148 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12149 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12150 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12151 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12152 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
604.12153 +	 9, 9, 9,
604.12154 +};
604.12155 +
604.12156 +static const static_codebook _44pn1_p6_0 = {
604.12157 +	5, 243,
604.12158 +	(long *)_vq_lengthlist__44pn1_p6_0,
604.12159 +	1, -516716544, 1630767104, 2, 0,
604.12160 +	(long *)_vq_quantlist__44pn1_p6_0,
604.12161 +	0
604.12162 +};
604.12163 +
604.12164 +static const long _vq_quantlist__44pn1_p6_1[] = {
604.12165 +	12,
604.12166 +	11,
604.12167 +	13,
604.12168 +	10,
604.12169 +	14,
604.12170 +	9,
604.12171 +	15,
604.12172 +	8,
604.12173 +	16,
604.12174 +	7,
604.12175 +	17,
604.12176 +	6,
604.12177 +	18,
604.12178 +	5,
604.12179 +	19,
604.12180 +	4,
604.12181 +	20,
604.12182 +	3,
604.12183 +	21,
604.12184 +	2,
604.12185 +	22,
604.12186 +	1,
604.12187 +	23,
604.12188 +	0,
604.12189 +	24,
604.12190 +};
604.12191 +
604.12192 +static const long _vq_lengthlist__44pn1_p6_1[] = {
604.12193 +	 1, 3, 2, 5, 4, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
604.12194 +	12,13,13,14,14,15,15,15,15,
604.12195 +};
604.12196 +
604.12197 +static const static_codebook _44pn1_p6_1 = {
604.12198 +	1, 25,
604.12199 +	(long *)_vq_lengthlist__44pn1_p6_1,
604.12200 +	1, -518864896, 1620639744, 5, 0,
604.12201 +	(long *)_vq_quantlist__44pn1_p6_1,
604.12202 +	0
604.12203 +};
604.12204 +
604.12205 +static const long _vq_quantlist__44pn1_p6_2[] = {
604.12206 +	12,
604.12207 +	11,
604.12208 +	13,
604.12209 +	10,
604.12210 +	14,
604.12211 +	9,
604.12212 +	15,
604.12213 +	8,
604.12214 +	16,
604.12215 +	7,
604.12216 +	17,
604.12217 +	6,
604.12218 +	18,
604.12219 +	5,
604.12220 +	19,
604.12221 +	4,
604.12222 +	20,
604.12223 +	3,
604.12224 +	21,
604.12225 +	2,
604.12226 +	22,
604.12227 +	1,
604.12228 +	23,
604.12229 +	0,
604.12230 +	24,
604.12231 +};
604.12232 +
604.12233 +static const long _vq_lengthlist__44pn1_p6_2[] = {
604.12234 +	 3, 5, 4, 5, 4, 5, 4, 5, 5, 5, 4, 5, 5, 5, 5, 5,
604.12235 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
604.12236 +};
604.12237 +
604.12238 +static const static_codebook _44pn1_p6_2 = {
604.12239 +	1, 25,
604.12240 +	(long *)_vq_lengthlist__44pn1_p6_2,
604.12241 +	1, -529006592, 1611661312, 5, 0,
604.12242 +	(long *)_vq_quantlist__44pn1_p6_2,
604.12243 +	0
604.12244 +};
604.12245 +
604.12246 +static const long _huff_lengthlist__44pn1_short[] = {
604.12247 +	 4, 3, 7, 9,12,16,16, 3, 2, 5, 7,11,14,15, 7, 4,
604.12248 +	 5, 6, 9,12,15, 8, 5, 5, 5, 8,10,14, 9, 7, 6, 6,
604.12249 +	 8,10,12,12,10,10, 7, 6, 8,10,15,12,10, 6, 4, 7,
604.12250 +	 9,
604.12251 +};
604.12252 +
604.12253 +static const static_codebook _huff_book__44pn1_short = {
604.12254 +	2, 49,
604.12255 +	(long *)_huff_lengthlist__44pn1_short,
604.12256 +	0, 0, 0, 0, 0,
604.12257 +	NULL,
604.12258 +	0
604.12259 +};
604.12260 +
   605.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   605.2 +++ b/libs/vorbis/books/coupled/res_books_stereo.h	Sat Feb 01 19:58:19 2014 +0200
   605.3 @@ -0,0 +1,15783 @@
   605.4 +/********************************************************************
   605.5 + *                                                                  *
   605.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   605.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   605.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   605.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  605.10 + *                                                                  *
  605.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  605.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  605.13 + *                                                                  *
  605.14 + ********************************************************************
  605.15 +
  605.16 + function: static codebooks autogenerated by huff/huffbuld
  605.17 + last modified: $Id: res_books_stereo.h 17025 2010-03-25 04:56:56Z xiphmont $
  605.18 +
  605.19 + ********************************************************************/
  605.20 +
  605.21 +#include "codebook.h"
  605.22 +
  605.23 +static const long _vq_quantlist__16c0_s_p1_0[] = {
  605.24 +        1,
  605.25 +        0,
  605.26 +        2,
  605.27 +};
  605.28 +
  605.29 +static const long _vq_lengthlist__16c0_s_p1_0[] = {
  605.30 +         1, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
  605.31 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.32 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.33 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.34 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.35 +         0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0,
  605.36 +         0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.37 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.38 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.39 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.40 +         0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
  605.41 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.42 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.43 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.44 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.45 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.46 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.47 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.48 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.49 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.50 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.51 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.52 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.53 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.54 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.55 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.56 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.57 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.58 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.59 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.60 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.61 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.62 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.63 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.64 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.65 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.66 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.67 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.68 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.69 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.70 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.71 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.72 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.73 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.74 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.75 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0,
  605.76 +         0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0,
  605.77 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.78 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.79 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.80 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, 0,
  605.81 +         0, 0, 0, 9, 9,12, 0, 0, 0, 0, 0, 0,10,12,11, 0,
  605.82 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.83 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.84 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.85 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0,
  605.86 +         0, 0, 0, 0, 9,12,10, 0, 0, 0, 0, 0, 0,10,11,12,
  605.87 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.88 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.89 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.90 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.91 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.92 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.93 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.94 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.95 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.96 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.97 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.98 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  605.99 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.100 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.101 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.102 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.103 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.104 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.105 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.106 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.107 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.108 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.109 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.110 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.111 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.112 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.113 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.114 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.115 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.116 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.117 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.118 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.119 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.120 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.121 +         0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0,
 605.122 +         0, 0, 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.123 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.124 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.125 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.126 +         0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,12,11, 0,
 605.127 +         0, 0, 0, 0, 0, 9,10,12, 0, 0, 0, 0, 0, 0, 0, 0,
 605.128 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.129 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.130 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.131 +         0, 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,11,12,
 605.132 +         0, 0, 0, 0, 0, 0, 9,12, 9, 0, 0, 0, 0, 0, 0, 0,
 605.133 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.134 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.135 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.136 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.137 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.138 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.139 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.140 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.141 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.142 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.143 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.144 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.145 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.146 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.147 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.148 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.149 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.150 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.151 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.152 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.153 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.154 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.155 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.156 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.157 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.158 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.159 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.160 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.161 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.162 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.163 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.164 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.165 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.166 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.167 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.168 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.169 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.170 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.171 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.172 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.173 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.174 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.175 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.176 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.177 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.178 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.179 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.180 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.181 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.182 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.183 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.184 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.185 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.186 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.187 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.188 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.189 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.190 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.191 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.192 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.193 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.194 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.195 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.196 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.197 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.198 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.199 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.200 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.201 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.202 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.203 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.204 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.205 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.206 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.207 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.208 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.209 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.210 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.211 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.212 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.213 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.214 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.215 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.216 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.217 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.218 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.219 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.220 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.221 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.222 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.223 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.224 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.225 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.226 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.227 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.228 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.229 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.230 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.231 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.232 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.233 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.234 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.235 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.236 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.237 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.238 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.239 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.240 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.241 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.242 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.243 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.244 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.245 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.246 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.247 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.248 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.249 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.250 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.251 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.252 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.253 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.254 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.255 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.256 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.257 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.258 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.259 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.260 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.261 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.262 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.263 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.264 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.265 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.266 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.267 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.268 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.269 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.270 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.271 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.272 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.273 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.274 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.275 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.276 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.277 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.278 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.279 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.280 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.281 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.282 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.283 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.284 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.285 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.286 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.287 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.288 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.289 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.290 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.291 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.292 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.293 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.294 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.295 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.296 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.297 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.298 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.299 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.300 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.301 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.302 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.303 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.304 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.305 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.306 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.307 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.308 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.309 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.310 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.311 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.312 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.313 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.314 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.315 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.316 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.317 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.318 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.319 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.320 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.321 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.322 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.323 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.324 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.325 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.326 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.327 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.329 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.330 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.331 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.332 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.333 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.334 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.335 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.336 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.339 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.342 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.346 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.351 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.356 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.362 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.363 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.364 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.365 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.366 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.367 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.368 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.369 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.370 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.375 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.376 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.377 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.378 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.379 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.380 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.381 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.382 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.383 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.385 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.386 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.387 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.388 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.389 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.390 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.391 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.392 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.393 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.394 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.395 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.396 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.397 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.399 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.400 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.401 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.402 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.403 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.404 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.405 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.406 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.410 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.411 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.412 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.413 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.414 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.415 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.416 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.417 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.418 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.419 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.420 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.421 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.422 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.423 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.424 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.425 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.426 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.427 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.428 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.429 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.430 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.431 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.432 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.433 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.434 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.435 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.436 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.437 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.438 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.439 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.440 +         0,
 605.441 +};
 605.442 +
 605.443 +static const static_codebook _16c0_s_p1_0 = {
 605.444 +        8, 6561,
 605.445 +        (long *)_vq_lengthlist__16c0_s_p1_0,
 605.446 +        1, -535822336, 1611661312, 2, 0,
 605.447 +        (long *)_vq_quantlist__16c0_s_p1_0,
 605.448 +        0
 605.449 +};
 605.450 +
 605.451 +static const long _vq_quantlist__16c0_s_p3_0[] = {
 605.452 +        2,
 605.453 +        1,
 605.454 +        3,
 605.455 +        0,
 605.456 +        4,
 605.457 +};
 605.458 +
 605.459 +static const long _vq_lengthlist__16c0_s_p3_0[] = {
 605.460 +         1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 7, 6, 0, 0,
 605.462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.463 +         0, 0, 4, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.464 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9,
 605.465 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.466 +         0, 0, 0, 0, 6, 6, 6, 9, 9, 0, 0, 0, 0, 0, 0, 0,
 605.467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.468 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.469 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.470 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.471 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.472 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.473 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.474 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.475 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.476 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.477 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.478 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.479 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.480 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.481 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.482 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.483 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.484 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.485 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.486 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.487 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.488 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.489 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.490 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.491 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.492 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.493 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.494 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.495 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.496 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.497 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.498 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.499 +         0,
 605.500 +};
 605.501 +
 605.502 +static const static_codebook _16c0_s_p3_0 = {
 605.503 +        4, 625,
 605.504 +        (long *)_vq_lengthlist__16c0_s_p3_0,
 605.505 +        1, -533725184, 1611661312, 3, 0,
 605.506 +        (long *)_vq_quantlist__16c0_s_p3_0,
 605.507 +        0
 605.508 +};
 605.509 +
 605.510 +static const long _vq_quantlist__16c0_s_p4_0[] = {
 605.511 +        4,
 605.512 +        3,
 605.513 +        5,
 605.514 +        2,
 605.515 +        6,
 605.516 +        1,
 605.517 +        7,
 605.518 +        0,
 605.519 +        8,
 605.520 +};
 605.521 +
 605.522 +static const long _vq_lengthlist__16c0_s_p4_0[] = {
 605.523 +         1, 3, 2, 7, 8, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
 605.524 +         0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
 605.525 +         0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
 605.526 +         8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
 605.527 +         0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.528 +         0,
 605.529 +};
 605.530 +
 605.531 +static const static_codebook _16c0_s_p4_0 = {
 605.532 +        2, 81,
 605.533 +        (long *)_vq_lengthlist__16c0_s_p4_0,
 605.534 +        1, -531628032, 1611661312, 4, 0,
 605.535 +        (long *)_vq_quantlist__16c0_s_p4_0,
 605.536 +        0
 605.537 +};
 605.538 +
 605.539 +static const long _vq_quantlist__16c0_s_p5_0[] = {
 605.540 +        4,
 605.541 +        3,
 605.542 +        5,
 605.543 +        2,
 605.544 +        6,
 605.545 +        1,
 605.546 +        7,
 605.547 +        0,
 605.548 +        8,
 605.549 +};
 605.550 +
 605.551 +static const long _vq_lengthlist__16c0_s_p5_0[] = {
 605.552 +         1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7,
 605.553 +         8, 8, 0, 0, 0, 7, 7, 7, 7, 8, 8, 0, 0, 0, 7, 7,
 605.554 +         8, 8, 9, 9, 0, 0, 0, 7, 7, 8, 8, 9, 9, 0, 0, 0,
 605.555 +         8, 9, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0,
 605.556 +         0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
 605.557 +        10,
 605.558 +};
 605.559 +
 605.560 +static const static_codebook _16c0_s_p5_0 = {
 605.561 +        2, 81,
 605.562 +        (long *)_vq_lengthlist__16c0_s_p5_0,
 605.563 +        1, -531628032, 1611661312, 4, 0,
 605.564 +        (long *)_vq_quantlist__16c0_s_p5_0,
 605.565 +        0
 605.566 +};
 605.567 +
 605.568 +static const long _vq_quantlist__16c0_s_p6_0[] = {
 605.569 +        8,
 605.570 +        7,
 605.571 +        9,
 605.572 +        6,
 605.573 +        10,
 605.574 +        5,
 605.575 +        11,
 605.576 +        4,
 605.577 +        12,
 605.578 +        3,
 605.579 +        13,
 605.580 +        2,
 605.581 +        14,
 605.582 +        1,
 605.583 +        15,
 605.584 +        0,
 605.585 +        16,
 605.586 +};
 605.587 +
 605.588 +static const long _vq_lengthlist__16c0_s_p6_0[] = {
 605.589 +         1, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
 605.590 +        11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,11,
 605.591 +        11,11, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,
 605.592 +        11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
 605.593 +        11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
 605.594 +        10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,
 605.595 +        11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,
 605.596 +        10,11,11,12,12,12,13, 0, 0, 0, 9, 9, 9, 9,10,10,
 605.597 +        10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,10,10,10,
 605.598 +        10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
 605.599 +        10,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0, 0, 9,
 605.600 +         9,10,10,11,11,12,12,13,13,13,14, 0, 0, 0, 0, 0,
 605.601 +        10,10,10,11,11,11,12,12,13,13,13,14, 0, 0, 0, 0,
 605.602 +         0, 0, 0,10,10,11,11,12,12,13,13,14,14, 0, 0, 0,
 605.603 +         0, 0, 0, 0,11,11,12,12,13,13,13,13,14,14, 0, 0,
 605.604 +         0, 0, 0, 0, 0,11,11,12,12,12,13,13,14,15,14, 0,
 605.605 +         0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,14,14,15,
 605.606 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,14,13,14,
 605.607 +        14,
 605.608 +};
 605.609 +
 605.610 +static const static_codebook _16c0_s_p6_0 = {
 605.611 +        2, 289,
 605.612 +        (long *)_vq_lengthlist__16c0_s_p6_0,
 605.613 +        1, -529530880, 1611661312, 5, 0,
 605.614 +        (long *)_vq_quantlist__16c0_s_p6_0,
 605.615 +        0
 605.616 +};
 605.617 +
 605.618 +static const long _vq_quantlist__16c0_s_p7_0[] = {
 605.619 +        1,
 605.620 +        0,
 605.621 +        2,
 605.622 +};
 605.623 +
 605.624 +static const long _vq_lengthlist__16c0_s_p7_0[] = {
 605.625 +         1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,11,10,10,11,
 605.626 +        11,10, 4, 7, 7,10,10,10,11,10,10, 6,10,10,11,11,
 605.627 +        11,11,11,10, 6, 9, 9,11,12,12,11, 9, 9, 6, 9,10,
 605.628 +        11,12,12,11, 9,10, 7,11,11,11,11,11,12,13,12, 6,
 605.629 +         9,10,11,10,10,12,13,13, 6,10, 9,11,10,10,11,12,
 605.630 +        13,
 605.631 +};
 605.632 +
 605.633 +static const static_codebook _16c0_s_p7_0 = {
 605.634 +        4, 81,
 605.635 +        (long *)_vq_lengthlist__16c0_s_p7_0,
 605.636 +        1, -529137664, 1618345984, 2, 0,
 605.637 +        (long *)_vq_quantlist__16c0_s_p7_0,
 605.638 +        0
 605.639 +};
 605.640 +
 605.641 +static const long _vq_quantlist__16c0_s_p7_1[] = {
 605.642 +        5,
 605.643 +        4,
 605.644 +        6,
 605.645 +        3,
 605.646 +        7,
 605.647 +        2,
 605.648 +        8,
 605.649 +        1,
 605.650 +        9,
 605.651 +        0,
 605.652 +        10,
 605.653 +};
 605.654 +
 605.655 +static const long _vq_lengthlist__16c0_s_p7_1[] = {
 605.656 +         1, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7,
 605.657 +         8, 8, 8, 9, 9, 9,10,10,10, 6, 7, 8, 8, 8, 8, 9,
 605.658 +         8,10,10,10, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, 7,
 605.659 +         7, 8, 8, 9, 9, 8, 9,10,10,10, 8, 8, 9, 9, 9, 9,
 605.660 +         9, 9,11,11,11, 8, 8, 9, 9, 9, 9, 9,10,10,11,11,
 605.661 +         9, 9, 9, 9, 9, 9, 9,10,11,11,11,10,11, 9, 9, 9,
 605.662 +         9,10, 9,11,11,11,10,11,10,10, 9, 9,10,10,11,11,
 605.663 +        11,11,11, 9, 9, 9, 9,10,10,
 605.664 +};
 605.665 +
 605.666 +static const static_codebook _16c0_s_p7_1 = {
 605.667 +        2, 121,
 605.668 +        (long *)_vq_lengthlist__16c0_s_p7_1,
 605.669 +        1, -531365888, 1611661312, 4, 0,
 605.670 +        (long *)_vq_quantlist__16c0_s_p7_1,
 605.671 +        0
 605.672 +};
 605.673 +
 605.674 +static const long _vq_quantlist__16c0_s_p8_0[] = {
 605.675 +        6,
 605.676 +        5,
 605.677 +        7,
 605.678 +        4,
 605.679 +        8,
 605.680 +        3,
 605.681 +        9,
 605.682 +        2,
 605.683 +        10,
 605.684 +        1,
 605.685 +        11,
 605.686 +        0,
 605.687 +        12,
 605.688 +};
 605.689 +
 605.690 +static const long _vq_lengthlist__16c0_s_p8_0[] = {
 605.691 +         1, 4, 4, 7, 7, 7, 7, 7, 6, 8, 8,10,10, 6, 5, 6,
 605.692 +         8, 8, 8, 8, 8, 8, 8, 9,10,10, 7, 6, 6, 8, 8, 8,
 605.693 +         8, 8, 8, 8, 8,10,10, 0, 8, 8, 8, 8, 9, 8, 9, 9,
 605.694 +         9,10,10,10, 0, 9, 8, 8, 8, 9, 9, 8, 8, 9, 9,10,
 605.695 +        10, 0,12,11, 8, 8, 9, 9, 9, 9,10,10,11,10, 0,12,
 605.696 +        13, 8, 8, 9,10, 9, 9,11,11,11,12, 0, 0, 0, 8, 8,
 605.697 +         8, 8,10, 9,12,13,12,14, 0, 0, 0, 8, 8, 8, 9,10,
 605.698 +        10,12,12,13,14, 0, 0, 0,13,13, 9, 9,11,11, 0, 0,
 605.699 +        14, 0, 0, 0, 0,14,14,10,10,12,11,12,14,14,14, 0,
 605.700 +         0, 0, 0, 0,11,11,13,13,14,13,14,14, 0, 0, 0, 0,
 605.701 +         0,12,13,13,12,13,14,14,14,
 605.702 +};
 605.703 +
 605.704 +static const static_codebook _16c0_s_p8_0 = {
 605.705 +        2, 169,
 605.706 +        (long *)_vq_lengthlist__16c0_s_p8_0,
 605.707 +        1, -526516224, 1616117760, 4, 0,
 605.708 +        (long *)_vq_quantlist__16c0_s_p8_0,
 605.709 +        0
 605.710 +};
 605.711 +
 605.712 +static const long _vq_quantlist__16c0_s_p8_1[] = {
 605.713 +        2,
 605.714 +        1,
 605.715 +        3,
 605.716 +        0,
 605.717 +        4,
 605.718 +};
 605.719 +
 605.720 +static const long _vq_lengthlist__16c0_s_p8_1[] = {
 605.721 +         1, 4, 3, 5, 5, 7, 7, 7, 6, 6, 7, 7, 7, 5, 5, 7,
 605.722 +         7, 7, 6, 6, 7, 7, 7, 6, 6,
 605.723 +};
 605.724 +
 605.725 +static const static_codebook _16c0_s_p8_1 = {
 605.726 +        2, 25,
 605.727 +        (long *)_vq_lengthlist__16c0_s_p8_1,
 605.728 +        1, -533725184, 1611661312, 3, 0,
 605.729 +        (long *)_vq_quantlist__16c0_s_p8_1,
 605.730 +        0
 605.731 +};
 605.732 +
 605.733 +static const long _vq_quantlist__16c0_s_p9_0[] = {
 605.734 +        1,
 605.735 +        0,
 605.736 +        2,
 605.737 +};
 605.738 +
 605.739 +static const long _vq_lengthlist__16c0_s_p9_0[] = {
 605.740 +         1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 605.741 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 605.742 +         8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 605.743 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 605.744 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 605.745 +         7,
 605.746 +};
 605.747 +
 605.748 +static const static_codebook _16c0_s_p9_0 = {
 605.749 +        4, 81,
 605.750 +        (long *)_vq_lengthlist__16c0_s_p9_0,
 605.751 +        1, -518803456, 1628680192, 2, 0,
 605.752 +        (long *)_vq_quantlist__16c0_s_p9_0,
 605.753 +        0
 605.754 +};
 605.755 +
 605.756 +static const long _vq_quantlist__16c0_s_p9_1[] = {
 605.757 +        7,
 605.758 +        6,
 605.759 +        8,
 605.760 +        5,
 605.761 +        9,
 605.762 +        4,
 605.763 +        10,
 605.764 +        3,
 605.765 +        11,
 605.766 +        2,
 605.767 +        12,
 605.768 +        1,
 605.769 +        13,
 605.770 +        0,
 605.771 +        14,
 605.772 +};
 605.773 +
 605.774 +static const long _vq_lengthlist__16c0_s_p9_1[] = {
 605.775 +         1, 5, 5, 5, 5, 9,11,11,10,10,10,10,10,10,10, 7,
 605.776 +         6, 6, 6, 6,10,10,10,10,10,10,10,10,10,10, 7, 6,
 605.777 +         6, 6, 6,10, 9,10,10,10,10,10,10,10,10,10, 7, 7,
 605.778 +         8, 9,10,10,10,10,10,10,10,10,10,10,10, 8, 7,10,
 605.779 +        10,10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,
 605.780 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 605.781 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 605.782 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 605.783 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 605.784 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 605.785 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 605.786 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 605.787 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 605.788 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 605.789 +        10,
 605.790 +};
 605.791 +
 605.792 +static const static_codebook _16c0_s_p9_1 = {
 605.793 +        2, 225,
 605.794 +        (long *)_vq_lengthlist__16c0_s_p9_1,
 605.795 +        1, -520986624, 1620377600, 4, 0,
 605.796 +        (long *)_vq_quantlist__16c0_s_p9_1,
 605.797 +        0
 605.798 +};
 605.799 +
 605.800 +static const long _vq_quantlist__16c0_s_p9_2[] = {
 605.801 +        10,
 605.802 +        9,
 605.803 +        11,
 605.804 +        8,
 605.805 +        12,
 605.806 +        7,
 605.807 +        13,
 605.808 +        6,
 605.809 +        14,
 605.810 +        5,
 605.811 +        15,
 605.812 +        4,
 605.813 +        16,
 605.814 +        3,
 605.815 +        17,
 605.816 +        2,
 605.817 +        18,
 605.818 +        1,
 605.819 +        19,
 605.820 +        0,
 605.821 +        20,
 605.822 +};
 605.823 +
 605.824 +static const long _vq_lengthlist__16c0_s_p9_2[] = {
 605.825 +         1, 5, 5, 7, 8, 8, 7, 9, 9, 9,12,12,11,12,12,10,
 605.826 +        10,11,12,12,12,11,12,12, 8, 9, 8, 7, 9,10,10,11,
 605.827 +        11,10,11,12,10,12,10,12,12,12,11,12,11, 9, 8, 8,
 605.828 +         9,10, 9, 8, 9,10,12,12,11,11,12,11,10,11,12,11,
 605.829 +        12,12, 8, 9, 9, 9,10,11,12,11,12,11,11,11,11,12,
 605.830 +        12,11,11,12,12,11,11, 9, 9, 8, 9, 9,11, 9, 9,10,
 605.831 +         9,11,11,11,11,12,11,11,10,12,12,12, 9,12,11,10,
 605.832 +        11,11,11,11,12,12,12,11,11,11,12,10,12,12,12,10,
 605.833 +        10, 9,10, 9,10,10, 9, 9, 9,10,10,12,10,11,11, 9,
 605.834 +        11,11,10,11,11,11,10,10,10, 9, 9,10,10, 9, 9,10,
 605.835 +        11,11,10,11,10,11,10,11,11,10,11,11,11,10, 9,10,
 605.836 +        10, 9,10, 9, 9,11, 9, 9,11,10,10,11,11,10,10,11,
 605.837 +        10,11, 8, 9,11,11,10, 9,10,11,11,10,11,11,10,10,
 605.838 +        10,11,10, 9,10,10,11, 9,10,10, 9,11,10,10,10,10,
 605.839 +        11,10,11,11, 9,11,10,11,10,10,11,11,10,10,10, 9,
 605.840 +        10,10,11,11,11, 9,10,10,10,10,10,11,10,10,10, 9,
 605.841 +        10,10,11,10,10,10,10,10, 9,10,11,10,10,10,10,11,
 605.842 +        11,11,10,10,10,10,10,11,10,11,10,11,10,10,10, 9,
 605.843 +        11,11,10,10,10,11,11,10,10,10,10,10,10,10,10,11,
 605.844 +        11, 9,10,10,10,11,10,11,10,10,10,11, 9,10,11,10,
 605.845 +        11,10,10, 9,10,10,10,11,10,11,10,10,10,10,10,11,
 605.846 +        11,10,11,11,10,10,11,11,10, 9, 9,10,10,10,10,10,
 605.847 +         9,11, 9,10,10,10,11,11,10,10,10,10,11,11,11,10,
 605.848 +         9, 9,10,10,11,10,10,10,10,10,11,11,11,10,10,10,
 605.849 +        11,11,11, 9,10,10,10,10, 9,10, 9,10,11,10,11,10,
 605.850 +        10,11,11,10,11,11,11,11,11,10,11,10,10,10, 9,11,
 605.851 +        11,10,11,11,11,11,11,11,11,11,11,10,11,10,10,10,
 605.852 +        10,11,10,10,11, 9,10,10,10,
 605.853 +};
 605.854 +
 605.855 +static const static_codebook _16c0_s_p9_2 = {
 605.856 +        2, 441,
 605.857 +        (long *)_vq_lengthlist__16c0_s_p9_2,
 605.858 +        1, -529268736, 1611661312, 5, 0,
 605.859 +        (long *)_vq_quantlist__16c0_s_p9_2,
 605.860 +        0
 605.861 +};
 605.862 +
 605.863 +static const long _huff_lengthlist__16c0_s_single[] = {
 605.864 +         3, 4,19, 7, 9, 7, 8,11, 9,12, 4, 1,19, 6, 7, 7,
 605.865 +         8,10,11,13,18,18,18,18,18,18,18,18,18,18, 8, 6,
 605.866 +        18, 8, 9, 9,11,12,14,18, 9, 6,18, 9, 7, 8, 9,11,
 605.867 +        12,18, 7, 6,18, 8, 7, 7, 7, 9,11,17, 8, 8,18, 9,
 605.868 +         7, 6, 6, 8,11,17,10,10,18,12, 9, 8, 7, 9,12,18,
 605.869 +        13,15,18,15,13,11,10,11,15,18,14,18,18,18,18,18,
 605.870 +        16,16,18,18,
 605.871 +};
 605.872 +
 605.873 +static const static_codebook _huff_book__16c0_s_single = {
 605.874 +        2, 100,
 605.875 +        (long *)_huff_lengthlist__16c0_s_single,
 605.876 +        0, 0, 0, 0, 0,
 605.877 +        NULL,
 605.878 +        0
 605.879 +};
 605.880 +
 605.881 +static const long _huff_lengthlist__16c1_s_long[] = {
 605.882 +         2, 5,20, 7,10, 7, 8,10,11,11, 4, 2,20, 5, 8, 6,
 605.883 +         7, 9,10,10,20,20,20,20,19,19,19,19,19,19, 7, 5,
 605.884 +        19, 6,10, 7, 9,11,13,17,11, 8,19,10, 7, 7, 8,10,
 605.885 +        11,15, 7, 5,19, 7, 7, 5, 6, 9,11,16, 7, 6,19, 8,
 605.886 +         7, 6, 6, 7, 9,13, 9, 9,19,11, 9, 8, 6, 7, 8,13,
 605.887 +        12,14,19,16,13,10, 9, 8, 9,13,14,17,19,18,18,17,
 605.888 +        12,11,11,13,
 605.889 +};
 605.890 +
 605.891 +static const static_codebook _huff_book__16c1_s_long = {
 605.892 +        2, 100,
 605.893 +        (long *)_huff_lengthlist__16c1_s_long,
 605.894 +        0, 0, 0, 0, 0,
 605.895 +        NULL,
 605.896 +        0
 605.897 +};
 605.898 +
 605.899 +static const long _vq_quantlist__16c1_s_p1_0[] = {
 605.900 +        1,
 605.901 +        0,
 605.902 +        2,
 605.903 +};
 605.904 +
 605.905 +static const long _vq_lengthlist__16c1_s_p1_0[] = {
 605.906 +         1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
 605.907 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.908 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.909 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.910 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.911 +         0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
 605.912 +         0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.913 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.914 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.915 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.916 +         0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
 605.917 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.918 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.919 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.920 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.921 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.922 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.923 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.924 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.925 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.926 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.927 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.928 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.929 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.930 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.931 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.932 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.933 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.934 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.935 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.936 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.937 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.938 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.939 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.940 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.941 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.942 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.943 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.944 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.945 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.946 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.947 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.948 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.949 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.950 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.951 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0,
 605.952 +         0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
 605.953 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.954 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.955 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.956 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
 605.957 +         0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 9,11,10, 0,
 605.958 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.959 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.960 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.961 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
 605.962 +         0, 0, 0, 0, 8,11, 9, 0, 0, 0, 0, 0, 0, 9,10,11,
 605.963 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.964 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.965 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.966 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.967 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.968 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.969 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.970 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.971 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.972 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.973 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.974 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.975 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.976 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.977 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.978 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.979 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.980 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.981 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.982 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.983 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.984 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.985 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.986 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.987 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.988 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.989 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.990 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.991 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.992 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.993 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.994 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.995 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.996 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.997 +         0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
 605.998 +         0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 605.999 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1000 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1001 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1002 +         0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0,
605.1003 +         0, 0, 0, 0, 0, 8, 9,11, 0, 0, 0, 0, 0, 0, 0, 0,
605.1004 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1005 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1006 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1007 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,11,
605.1008 +         0, 0, 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0, 0,
605.1009 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1010 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1011 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1012 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1013 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1014 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1015 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1016 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1017 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1018 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1019 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1020 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1021 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1022 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1023 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1024 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1025 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1026 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1027 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1028 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1029 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1030 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1031 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1032 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1033 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1034 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1035 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1036 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1037 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1038 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1039 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1040 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1041 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1042 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1043 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1044 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1045 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1046 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1047 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1048 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1049 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1050 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1051 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1052 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1053 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1054 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1055 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1056 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1057 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1058 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1059 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1060 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1061 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1062 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1063 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1064 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1065 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1066 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1067 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1068 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1069 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1070 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1071 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1072 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1073 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1074 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1075 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1076 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1077 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1078 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1079 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1080 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1081 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1082 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1083 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1084 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1085 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1086 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1087 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1088 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1089 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1090 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1091 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1092 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1093 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1094 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1095 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1096 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1097 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1098 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1099 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1100 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1101 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1102 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1103 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1104 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1105 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1106 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1107 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1108 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1109 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1110 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1111 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1112 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1113 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1114 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1115 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1116 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1117 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1118 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1119 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1120 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1121 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1122 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1123 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1124 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1125 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1126 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1127 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1128 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1129 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1130 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1131 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1132 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1133 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1134 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1135 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1136 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1137 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1138 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1139 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1140 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1141 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1142 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1143 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1144 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1145 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1146 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1147 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1148 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1149 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1150 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1151 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1152 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1153 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1154 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1155 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1156 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1157 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1158 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1159 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1160 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1161 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1162 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1163 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1164 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1165 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1166 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1167 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1168 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1169 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1170 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1171 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1172 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1173 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1174 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1175 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1176 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1177 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1178 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1179 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1180 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1181 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1182 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1183 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1184 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1185 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1186 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1187 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1188 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1189 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1190 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1191 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1192 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1193 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1194 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1195 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1196 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1197 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1198 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1199 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1200 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1201 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1202 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1203 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1204 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1205 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1206 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1207 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1208 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1209 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1210 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1211 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1212 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1213 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1214 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1215 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1216 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1217 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1218 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1219 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1220 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1221 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1222 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1223 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1224 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1225 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1226 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1227 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1228 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1229 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1230 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1231 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1232 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1233 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1234 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1235 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1236 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1237 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1238 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1239 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1240 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1241 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1242 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1243 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1244 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1245 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1246 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1247 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1248 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1249 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1250 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1251 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1252 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1253 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1254 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1255 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1256 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1257 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1258 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1259 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1260 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1261 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1262 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1263 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1264 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1265 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1266 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1267 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1268 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1269 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1270 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1271 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1272 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1273 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1274 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1275 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1276 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1277 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1278 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1279 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1280 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1281 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1282 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1283 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1284 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1285 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1286 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1287 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1288 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1289 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1290 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1291 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1292 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1293 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1294 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1295 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1296 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1297 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1298 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1299 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1300 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1301 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1302 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1303 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1304 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1305 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1306 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1307 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1308 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1309 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1310 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1311 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1312 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1313 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1314 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1315 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1316 +         0,
605.1317 +};
605.1318 +
605.1319 +static const static_codebook _16c1_s_p1_0 = {
605.1320 +        8, 6561,
605.1321 +        (long *)_vq_lengthlist__16c1_s_p1_0,
605.1322 +        1, -535822336, 1611661312, 2, 0,
605.1323 +        (long *)_vq_quantlist__16c1_s_p1_0,
605.1324 +        0
605.1325 +};
605.1326 +
605.1327 +static const long _vq_quantlist__16c1_s_p3_0[] = {
605.1328 +        2,
605.1329 +        1,
605.1330 +        3,
605.1331 +        0,
605.1332 +        4,
605.1333 +};
605.1334 +
605.1335 +static const long _vq_lengthlist__16c1_s_p3_0[] = {
605.1336 +         1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0,
605.1338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1339 +         0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 9, 9,
605.1341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1342 +         0, 0, 0, 0, 6, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.1343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1346 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1351 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1356 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1362 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1363 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1364 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1365 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1366 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1367 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1368 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1369 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1370 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1375 +         0,
605.1376 +};
605.1377 +
605.1378 +static const static_codebook _16c1_s_p3_0 = {
605.1379 +        4, 625,
605.1380 +        (long *)_vq_lengthlist__16c1_s_p3_0,
605.1381 +        1, -533725184, 1611661312, 3, 0,
605.1382 +        (long *)_vq_quantlist__16c1_s_p3_0,
605.1383 +        0
605.1384 +};
605.1385 +
605.1386 +static const long _vq_quantlist__16c1_s_p4_0[] = {
605.1387 +        4,
605.1388 +        3,
605.1389 +        5,
605.1390 +        2,
605.1391 +        6,
605.1392 +        1,
605.1393 +        7,
605.1394 +        0,
605.1395 +        8,
605.1396 +};
605.1397 +
605.1398 +static const long _vq_lengthlist__16c1_s_p4_0[] = {
605.1399 +         1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
605.1400 +         0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
605.1401 +         0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
605.1402 +         8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0,
605.1403 +         0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1404 +         0,
605.1405 +};
605.1406 +
605.1407 +static const static_codebook _16c1_s_p4_0 = {
605.1408 +        2, 81,
605.1409 +        (long *)_vq_lengthlist__16c1_s_p4_0,
605.1410 +        1, -531628032, 1611661312, 4, 0,
605.1411 +        (long *)_vq_quantlist__16c1_s_p4_0,
605.1412 +        0
605.1413 +};
605.1414 +
605.1415 +static const long _vq_quantlist__16c1_s_p5_0[] = {
605.1416 +        4,
605.1417 +        3,
605.1418 +        5,
605.1419 +        2,
605.1420 +        6,
605.1421 +        1,
605.1422 +        7,
605.1423 +        0,
605.1424 +        8,
605.1425 +};
605.1426 +
605.1427 +static const long _vq_lengthlist__16c1_s_p5_0[] = {
605.1428 +         1, 3, 3, 5, 5, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7,
605.1429 +         9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 8, 8,
605.1430 +         8, 8, 9, 9, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0,
605.1431 +         9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0,
605.1432 +         0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
605.1433 +        10,
605.1434 +};
605.1435 +
605.1436 +static const static_codebook _16c1_s_p5_0 = {
605.1437 +        2, 81,
605.1438 +        (long *)_vq_lengthlist__16c1_s_p5_0,
605.1439 +        1, -531628032, 1611661312, 4, 0,
605.1440 +        (long *)_vq_quantlist__16c1_s_p5_0,
605.1441 +        0
605.1442 +};
605.1443 +
605.1444 +static const long _vq_quantlist__16c1_s_p6_0[] = {
605.1445 +        8,
605.1446 +        7,
605.1447 +        9,
605.1448 +        6,
605.1449 +        10,
605.1450 +        5,
605.1451 +        11,
605.1452 +        4,
605.1453 +        12,
605.1454 +        3,
605.1455 +        13,
605.1456 +        2,
605.1457 +        14,
605.1458 +        1,
605.1459 +        15,
605.1460 +        0,
605.1461 +        16,
605.1462 +};
605.1463 +
605.1464 +static const long _vq_lengthlist__16c1_s_p6_0[] = {
605.1465 +         1, 3, 3, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11,12,
605.1466 +        12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11,
605.1467 +        12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,
605.1468 +        11,12,12, 0, 0, 0, 8, 8, 8, 9,10, 9,10,10,10,10,
605.1469 +        11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,11,
605.1470 +        11,11,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,
605.1471 +        11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,
605.1472 +        10,11,11,12,12,13,13, 0, 0, 0, 9, 9, 9, 9,10,10,
605.1473 +        10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10,
605.1474 +        10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
605.1475 +        10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0, 9,
605.1476 +         9,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0,
605.1477 +        10,10,11,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0,
605.1478 +         0, 0, 0,10,10,11,11,12,12,13,13,13,13, 0, 0, 0,
605.1479 +         0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0, 0,
605.1480 +         0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0,
605.1481 +         0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14,
605.1482 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14,
605.1483 +        14,
605.1484 +};
605.1485 +
605.1486 +static const static_codebook _16c1_s_p6_0 = {
605.1487 +        2, 289,
605.1488 +        (long *)_vq_lengthlist__16c1_s_p6_0,
605.1489 +        1, -529530880, 1611661312, 5, 0,
605.1490 +        (long *)_vq_quantlist__16c1_s_p6_0,
605.1491 +        0
605.1492 +};
605.1493 +
605.1494 +static const long _vq_quantlist__16c1_s_p7_0[] = {
605.1495 +        1,
605.1496 +        0,
605.1497 +        2,
605.1498 +};
605.1499 +
605.1500 +static const long _vq_lengthlist__16c1_s_p7_0[] = {
605.1501 +         1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9,10,10,
605.1502 +        10, 9, 4, 7, 7,10,10,10,11,10,10, 6,10,10,11,11,
605.1503 +        11,11,10,10, 6,10, 9,11,11,11,11,10,10, 6,10,10,
605.1504 +        11,11,11,11,10,10, 7,11,11,11,11,11,12,12,11, 6,
605.1505 +        10,10,11,10,10,11,11,11, 6,10,10,10,11,10,11,11,
605.1506 +        11,
605.1507 +};
605.1508 +
605.1509 +static const static_codebook _16c1_s_p7_0 = {
605.1510 +        4, 81,
605.1511 +        (long *)_vq_lengthlist__16c1_s_p7_0,
605.1512 +        1, -529137664, 1618345984, 2, 0,
605.1513 +        (long *)_vq_quantlist__16c1_s_p7_0,
605.1514 +        0
605.1515 +};
605.1516 +
605.1517 +static const long _vq_quantlist__16c1_s_p7_1[] = {
605.1518 +        5,
605.1519 +        4,
605.1520 +        6,
605.1521 +        3,
605.1522 +        7,
605.1523 +        2,
605.1524 +        8,
605.1525 +        1,
605.1526 +        9,
605.1527 +        0,
605.1528 +        10,
605.1529 +};
605.1530 +
605.1531 +static const long _vq_lengthlist__16c1_s_p7_1[] = {
605.1532 +         2, 3, 3, 5, 6, 7, 7, 7, 7, 8, 8,10,10,10, 6, 6,
605.1533 +         7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8,
605.1534 +         8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
605.1535 +         7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8,
605.1536 +         8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
605.1537 +         8, 8, 8, 8, 8, 8, 9, 9,10,10,10,10,10, 8, 8, 8,
605.1538 +         8, 9, 9,10,10,10,10,10, 9, 9, 8, 8, 9, 9,10,10,
605.1539 +        10,10,10, 8, 8, 8, 8, 9, 9,
605.1540 +};
605.1541 +
605.1542 +static const static_codebook _16c1_s_p7_1 = {
605.1543 +        2, 121,
605.1544 +        (long *)_vq_lengthlist__16c1_s_p7_1,
605.1545 +        1, -531365888, 1611661312, 4, 0,
605.1546 +        (long *)_vq_quantlist__16c1_s_p7_1,
605.1547 +        0
605.1548 +};
605.1549 +
605.1550 +static const long _vq_quantlist__16c1_s_p8_0[] = {
605.1551 +        6,
605.1552 +        5,
605.1553 +        7,
605.1554 +        4,
605.1555 +        8,
605.1556 +        3,
605.1557 +        9,
605.1558 +        2,
605.1559 +        10,
605.1560 +        1,
605.1561 +        11,
605.1562 +        0,
605.1563 +        12,
605.1564 +};
605.1565 +
605.1566 +static const long _vq_lengthlist__16c1_s_p8_0[] = {
605.1567 +         1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 6, 5, 5,
605.1568 +         7, 8, 8, 9, 8, 8, 9, 9,10,11, 6, 5, 5, 8, 8, 9,
605.1569 +         9, 8, 8, 9,10,10,11, 0, 8, 8, 8, 9, 9, 9, 9, 9,
605.1570 +        10,10,11,11, 0, 9, 9, 9, 8, 9, 9, 9, 9,10,10,11,
605.1571 +        11, 0,13,13, 9, 9,10,10,10,10,11,11,12,12, 0,14,
605.1572 +        13, 9, 9,10,10,10,10,11,11,12,12, 0, 0, 0,10,10,
605.1573 +         9, 9,11,11,12,12,13,12, 0, 0, 0,10,10, 9, 9,10,
605.1574 +        10,12,12,13,13, 0, 0, 0,13,14,11,10,11,11,12,12,
605.1575 +        13,14, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0,
605.1576 +         0, 0, 0, 0,12,12,12,12,13,13,14,15, 0, 0, 0, 0,
605.1577 +         0,12,12,12,12,13,13,14,15,
605.1578 +};
605.1579 +
605.1580 +static const static_codebook _16c1_s_p8_0 = {
605.1581 +        2, 169,
605.1582 +        (long *)_vq_lengthlist__16c1_s_p8_0,
605.1583 +        1, -526516224, 1616117760, 4, 0,
605.1584 +        (long *)_vq_quantlist__16c1_s_p8_0,
605.1585 +        0
605.1586 +};
605.1587 +
605.1588 +static const long _vq_quantlist__16c1_s_p8_1[] = {
605.1589 +        2,
605.1590 +        1,
605.1591 +        3,
605.1592 +        0,
605.1593 +        4,
605.1594 +};
605.1595 +
605.1596 +static const long _vq_lengthlist__16c1_s_p8_1[] = {
605.1597 +         2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
605.1598 +         6, 6, 5, 5, 6, 6, 6, 5, 5,
605.1599 +};
605.1600 +
605.1601 +static const static_codebook _16c1_s_p8_1 = {
605.1602 +        2, 25,
605.1603 +        (long *)_vq_lengthlist__16c1_s_p8_1,
605.1604 +        1, -533725184, 1611661312, 3, 0,
605.1605 +        (long *)_vq_quantlist__16c1_s_p8_1,
605.1606 +        0
605.1607 +};
605.1608 +
605.1609 +static const long _vq_quantlist__16c1_s_p9_0[] = {
605.1610 +        6,
605.1611 +        5,
605.1612 +        7,
605.1613 +        4,
605.1614 +        8,
605.1615 +        3,
605.1616 +        9,
605.1617 +        2,
605.1618 +        10,
605.1619 +        1,
605.1620 +        11,
605.1621 +        0,
605.1622 +        12,
605.1623 +};
605.1624 +
605.1625 +static const long _vq_lengthlist__16c1_s_p9_0[] = {
605.1626 +         1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.1627 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.1628 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.1629 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.1630 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.1631 +         9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.1632 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.1633 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.1634 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.1635 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.1636 +         8, 8, 8, 8, 8, 8, 8, 8, 8,
605.1637 +};
605.1638 +
605.1639 +static const static_codebook _16c1_s_p9_0 = {
605.1640 +        2, 169,
605.1641 +        (long *)_vq_lengthlist__16c1_s_p9_0,
605.1642 +        1, -513964032, 1628680192, 4, 0,
605.1643 +        (long *)_vq_quantlist__16c1_s_p9_0,
605.1644 +        0
605.1645 +};
605.1646 +
605.1647 +static const long _vq_quantlist__16c1_s_p9_1[] = {
605.1648 +        7,
605.1649 +        6,
605.1650 +        8,
605.1651 +        5,
605.1652 +        9,
605.1653 +        4,
605.1654 +        10,
605.1655 +        3,
605.1656 +        11,
605.1657 +        2,
605.1658 +        12,
605.1659 +        1,
605.1660 +        13,
605.1661 +        0,
605.1662 +        14,
605.1663 +};
605.1664 +
605.1665 +static const long _vq_lengthlist__16c1_s_p9_1[] = {
605.1666 +         1, 4, 4, 4, 4, 8, 8,12,13,14,14,14,14,14,14, 6,
605.1667 +         6, 6, 6, 6,10, 9,14,14,14,14,14,14,14,14, 7, 6,
605.1668 +         5, 6, 6,10, 9,12,13,13,13,13,13,13,13,13, 7, 7,
605.1669 +         9, 9,11,11,12,13,13,13,13,13,13,13,13, 7, 7, 8,
605.1670 +         8,11,12,13,13,13,13,13,13,13,13,13,12,12,10,10,
605.1671 +        13,12,13,13,13,13,13,13,13,13,13,12,12,10,10,13,
605.1672 +        13,13,13,13,13,13,13,13,13,13,13,13,13,12,13,12,
605.1673 +        13,13,13,13,13,13,13,13,13,13,13,13,12,13,13,13,
605.1674 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.1675 +        13,13,13,13,13,13,13,13,13,13,13,13,12,13,13,13,
605.1676 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.1677 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.1678 +        13,13,13,13,13,13,13,13,13,12,13,13,13,13,13,13,
605.1679 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.1680 +        13,
605.1681 +};
605.1682 +
605.1683 +static const static_codebook _16c1_s_p9_1 = {
605.1684 +        2, 225,
605.1685 +        (long *)_vq_lengthlist__16c1_s_p9_1,
605.1686 +        1, -520986624, 1620377600, 4, 0,
605.1687 +        (long *)_vq_quantlist__16c1_s_p9_1,
605.1688 +        0
605.1689 +};
605.1690 +
605.1691 +static const long _vq_quantlist__16c1_s_p9_2[] = {
605.1692 +        10,
605.1693 +        9,
605.1694 +        11,
605.1695 +        8,
605.1696 +        12,
605.1697 +        7,
605.1698 +        13,
605.1699 +        6,
605.1700 +        14,
605.1701 +        5,
605.1702 +        15,
605.1703 +        4,
605.1704 +        16,
605.1705 +        3,
605.1706 +        17,
605.1707 +        2,
605.1708 +        18,
605.1709 +        1,
605.1710 +        19,
605.1711 +        0,
605.1712 +        20,
605.1713 +};
605.1714 +
605.1715 +static const long _vq_lengthlist__16c1_s_p9_2[] = {
605.1716 +         1, 4, 4, 6, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9,10,
605.1717 +        10,10, 9,10,10,11,12,12, 8, 8, 8, 8, 9, 9, 9, 9,
605.1718 +        10,10,10,10,10,11,11,10,12,11,11,13,11, 7, 7, 8,
605.1719 +         8, 8, 8, 9, 9, 9,10,10,10,10, 9,10,10,11,11,12,
605.1720 +        11,11, 8, 8, 8, 8, 9, 9,10,10,10,10,11,11,11,11,
605.1721 +        11,11,11,12,11,12,12, 8, 8, 9, 9, 9, 9, 9,10,10,
605.1722 +        10,10,10,10,11,11,11,11,11,11,12,11, 9, 9, 9, 9,
605.1723 +        10,10,10,10,11,10,11,11,11,11,11,11,12,12,12,12,
605.1724 +        11, 9, 9, 9, 9,10,10,10,10,11,11,11,11,11,11,11,
605.1725 +        11,11,12,12,12,13, 9,10,10, 9,11,10,10,10,10,11,
605.1726 +        11,11,11,11,10,11,12,11,12,12,11,12,11,10, 9,10,
605.1727 +        10,11,10,11,11,11,11,11,11,11,11,11,12,12,11,12,
605.1728 +        12,12,10,10,10,11,10,11,11,11,11,11,11,11,11,11,
605.1729 +        11,11,12,13,12,12,11, 9,10,10,11,11,10,11,11,11,
605.1730 +        12,11,11,11,11,11,12,12,13,13,12,13,10,10,12,10,
605.1731 +        11,11,11,11,11,11,11,11,11,12,12,11,13,12,12,12,
605.1732 +        12,13,12,11,11,11,11,11,11,12,11,12,11,11,11,11,
605.1733 +        12,12,13,12,11,12,12,11,11,11,11,11,12,11,11,11,
605.1734 +        11,12,11,11,12,11,12,13,13,12,12,12,12,11,11,11,
605.1735 +        11,11,12,11,11,12,11,12,11,11,11,11,13,12,12,12,
605.1736 +        12,13,11,11,11,12,12,11,11,11,12,11,12,12,12,11,
605.1737 +        12,13,12,11,11,12,12,11,12,11,11,11,12,12,11,12,
605.1738 +        11,11,11,12,12,12,12,13,12,13,12,12,12,12,11,11,
605.1739 +        12,11,11,11,11,11,11,12,12,12,13,12,11,13,13,12,
605.1740 +        12,11,12,10,11,11,11,11,12,11,12,12,11,12,12,13,
605.1741 +        12,12,13,12,12,12,12,12,11,12,12,12,11,12,11,11,
605.1742 +        11,12,13,12,13,13,13,13,13,12,13,13,12,12,13,11,
605.1743 +        11,11,11,11,12,11,11,12,11,
605.1744 +};
605.1745 +
605.1746 +static const static_codebook _16c1_s_p9_2 = {
605.1747 +        2, 441,
605.1748 +        (long *)_vq_lengthlist__16c1_s_p9_2,
605.1749 +        1, -529268736, 1611661312, 5, 0,
605.1750 +        (long *)_vq_quantlist__16c1_s_p9_2,
605.1751 +        0
605.1752 +};
605.1753 +
605.1754 +static const long _huff_lengthlist__16c1_s_short[] = {
605.1755 +         5, 6,17, 8,12, 9,10,10,12,13, 5, 2,17, 4, 9, 5,
605.1756 +         7, 8,11,13,16,16,16,16,16,16,16,16,16,16, 6, 4,
605.1757 +        16, 5,10, 5, 7,10,14,16,13, 9,16,11, 8, 7, 8, 9,
605.1758 +        13,16, 7, 4,16, 5, 7, 4, 6, 8,11,13, 8, 6,16, 7,
605.1759 +         8, 5, 5, 7, 9,13, 9, 8,16, 9, 8, 6, 6, 7, 9,13,
605.1760 +        11,11,16,10,10, 7, 7, 7, 9,13,13,13,16,13,13, 9,
605.1761 +         9, 9,10,13,
605.1762 +};
605.1763 +
605.1764 +static const static_codebook _huff_book__16c1_s_short = {
605.1765 +        2, 100,
605.1766 +        (long *)_huff_lengthlist__16c1_s_short,
605.1767 +        0, 0, 0, 0, 0,
605.1768 +        NULL,
605.1769 +        0
605.1770 +};
605.1771 +
605.1772 +static const long _huff_lengthlist__16c2_s_long[] = {
605.1773 +	 4, 7, 9, 9, 9, 8, 9,10,13,16, 5, 4, 5, 6, 7, 7,
605.1774 +	 8, 9,12,16, 6, 5, 5, 5, 7, 7, 9,10,12,15, 7, 6,
605.1775 +	 5, 4, 5, 6, 8, 9,10,13, 8, 7, 7, 5, 5, 5, 7, 9,
605.1776 +	10,12, 7, 7, 7, 6, 5, 5, 6, 7,10,12, 8, 8, 8, 7,
605.1777 +	 7, 5, 5, 6, 9,11, 8, 9, 9, 8, 8, 6, 6, 5, 8,11,
605.1778 +	10,11,12,12,11, 9, 9, 8, 9,12,13,14,15,15,14,12,
605.1779 +	12,11,11,13,
605.1780 +};
605.1781 +
605.1782 +static const static_codebook _huff_book__16c2_s_long = {
605.1783 +	2, 100,
605.1784 +	(long *)_huff_lengthlist__16c2_s_long,
605.1785 +	0, 0, 0, 0, 0,
605.1786 +	NULL,
605.1787 +	0
605.1788 +};
605.1789 +
605.1790 +static const long _vq_quantlist__16c2_s_p1_0[] = {
605.1791 +	1,
605.1792 +	0,
605.1793 +	2,
605.1794 +};
605.1795 +
605.1796 +static const long _vq_lengthlist__16c2_s_p1_0[] = {
605.1797 +	 1, 3, 3, 0, 0, 0, 0, 0, 0, 4, 5, 5, 0, 0, 0, 0,
605.1798 +	 0, 0, 4, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1799 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1800 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1801 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1802 +	 0,
605.1803 +};
605.1804 +
605.1805 +static const static_codebook _16c2_s_p1_0 = {
605.1806 +	4, 81,
605.1807 +	(long *)_vq_lengthlist__16c2_s_p1_0,
605.1808 +	1, -535822336, 1611661312, 2, 0,
605.1809 +	(long *)_vq_quantlist__16c2_s_p1_0,
605.1810 +	0
605.1811 +};
605.1812 +
605.1813 +static const long _vq_quantlist__16c2_s_p2_0[] = {
605.1814 +	2,
605.1815 +	1,
605.1816 +	3,
605.1817 +	0,
605.1818 +	4,
605.1819 +};
605.1820 +
605.1821 +static const long _vq_lengthlist__16c2_s_p2_0[] = {
605.1822 +	 2, 4, 4, 7, 7, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0,
605.1823 +	 0, 0, 8, 8, 0, 0, 0, 8, 8, 4, 4, 4, 8, 7, 0, 0,
605.1824 +	 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0,
605.1825 +	 9, 9, 4, 4, 4, 7, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8,
605.1826 +	 8, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 7, 8, 8,10, 9,
605.1827 +	 0, 0, 0,12,11, 0, 0, 0,11,12, 0, 0, 0,14,13, 0,
605.1828 +	 0, 0,14,14, 7, 8, 8, 9,10, 0, 0, 0,11,12, 0, 0,
605.1829 +	 0,11,11, 0, 0, 0,14,14, 0, 0, 0,14,14, 0, 0, 0,
605.1830 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1831 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1832 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1833 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1834 +	 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8,11,11, 0, 0, 0,
605.1835 +	12,11, 0, 0, 0,12,12, 0, 0, 0,13,12, 0, 0, 0,13,
605.1836 +	13, 8, 8, 8,11,11, 0, 0, 0,11,11, 0, 0, 0,12,12,
605.1837 +	 0, 0, 0,13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0,
605.1838 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1839 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1840 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1841 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1842 +	 0, 0, 0, 0, 0, 8, 9, 8,12,11, 0, 0, 0,12,12, 0,
605.1843 +	 0, 0,12,11, 0, 0, 0,13,13, 0, 0, 0,13,13, 8, 8,
605.1844 +	 8,11,12, 0, 0, 0,11,12, 0, 0, 0,11,12, 0, 0, 0,
605.1845 +	13,14, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1846 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1847 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1848 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1849 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1850 +	 0, 0, 8, 9, 9,14,14, 0, 0, 0,13,13, 0, 0, 0,13,
605.1851 +	13, 0, 0, 0,13,12, 0, 0, 0,13,13, 8, 9, 9,14,14,
605.1852 +	 0, 0, 0,13,13, 0, 0, 0,13,13, 0, 0, 0,12,13, 0,
605.1853 +	 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1854 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1855 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1856 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1857 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
605.1858 +	 9, 9,14,14, 0, 0, 0,13,13, 0, 0, 0,13,13, 0, 0,
605.1859 +	 0,13,13, 0, 0, 0,13,12, 8, 9, 9,14,14, 0, 0, 0,
605.1860 +	13,13, 0, 0, 0,13,13, 0, 0, 0,13,13, 0, 0, 0,12,
605.1861 +	12,
605.1862 +};
605.1863 +
605.1864 +static const static_codebook _16c2_s_p2_0 = {
605.1865 +	4, 625,
605.1866 +	(long *)_vq_lengthlist__16c2_s_p2_0,
605.1867 +	1, -533725184, 1611661312, 3, 0,
605.1868 +	(long *)_vq_quantlist__16c2_s_p2_0,
605.1869 +	0
605.1870 +};
605.1871 +
605.1872 +static const long _vq_quantlist__16c2_s_p3_0[] = {
605.1873 +	4,
605.1874 +	3,
605.1875 +	5,
605.1876 +	2,
605.1877 +	6,
605.1878 +	1,
605.1879 +	7,
605.1880 +	0,
605.1881 +	8,
605.1882 +};
605.1883 +
605.1884 +static const long _vq_lengthlist__16c2_s_p3_0[] = {
605.1885 +	 1, 3, 3, 5, 5, 7, 7, 8, 8, 0, 0, 0, 6, 6, 8, 8,
605.1886 +	 9, 9, 0, 0, 0, 6, 6, 8, 8, 9, 9, 0, 0, 0, 7, 7,
605.1887 +	 8, 9,10,10, 0, 0, 0, 7, 7, 9, 9,10,10, 0, 0, 0,
605.1888 +	 8, 8, 9, 9,11,11, 0, 0, 0, 7, 7, 9, 9,11,11, 0,
605.1889 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1890 +	 0,
605.1891 +};
605.1892 +
605.1893 +static const static_codebook _16c2_s_p3_0 = {
605.1894 +	2, 81,
605.1895 +	(long *)_vq_lengthlist__16c2_s_p3_0,
605.1896 +	1, -531628032, 1611661312, 4, 0,
605.1897 +	(long *)_vq_quantlist__16c2_s_p3_0,
605.1898 +	0
605.1899 +};
605.1900 +
605.1901 +static const long _vq_quantlist__16c2_s_p4_0[] = {
605.1902 +	8,
605.1903 +	7,
605.1904 +	9,
605.1905 +	6,
605.1906 +	10,
605.1907 +	5,
605.1908 +	11,
605.1909 +	4,
605.1910 +	12,
605.1911 +	3,
605.1912 +	13,
605.1913 +	2,
605.1914 +	14,
605.1915 +	1,
605.1916 +	15,
605.1917 +	0,
605.1918 +	16,
605.1919 +};
605.1920 +
605.1921 +static const long _vq_lengthlist__16c2_s_p4_0[] = {
605.1922 +	 2, 3, 3, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9,
605.1923 +	 9, 0, 0, 0, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,
605.1924 +	11,10, 0, 0, 0, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,
605.1925 +	10,10,10, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10,10,
605.1926 +	11,11,11,11, 0, 0, 0, 7, 6, 8, 8, 9, 9, 9, 9,10,
605.1927 +	10,11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10,
605.1928 +	11,11,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,
605.1929 +	10,11,11,11,11,12,12, 0, 0, 0, 7, 8, 8, 8, 9, 9,
605.1930 +	10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9,
605.1931 +	 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 0, 0,
605.1932 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1933 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1934 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1935 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1936 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1937 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1938 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1939 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.1940 +	 0,
605.1941 +};
605.1942 +
605.1943 +static const static_codebook _16c2_s_p4_0 = {
605.1944 +	2, 289,
605.1945 +	(long *)_vq_lengthlist__16c2_s_p4_0,
605.1946 +	1, -529530880, 1611661312, 5, 0,
605.1947 +	(long *)_vq_quantlist__16c2_s_p4_0,
605.1948 +	0
605.1949 +};
605.1950 +
605.1951 +static const long _vq_quantlist__16c2_s_p5_0[] = {
605.1952 +	1,
605.1953 +	0,
605.1954 +	2,
605.1955 +};
605.1956 +
605.1957 +static const long _vq_lengthlist__16c2_s_p5_0[] = {
605.1958 +	 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 6,10,11,10,10,
605.1959 +	10,11, 4, 6, 6,10,10,11,10,11,10, 5,10,10, 9,12,
605.1960 +	11,10,12,12, 7,10,10,12,12,12,12,13,13, 7,11,10,
605.1961 +	11,12,12,12,13,13, 6,11,10,10,12,12,11,12,12, 7,
605.1962 +	11,10,12,13,13,12,12,12, 7,10,11,12,13,13,12,12,
605.1963 +	12,
605.1964 +};
605.1965 +
605.1966 +static const static_codebook _16c2_s_p5_0 = {
605.1967 +	4, 81,
605.1968 +	(long *)_vq_lengthlist__16c2_s_p5_0,
605.1969 +	1, -529137664, 1618345984, 2, 0,
605.1970 +	(long *)_vq_quantlist__16c2_s_p5_0,
605.1971 +	0
605.1972 +};
605.1973 +
605.1974 +static const long _vq_quantlist__16c2_s_p5_1[] = {
605.1975 +	5,
605.1976 +	4,
605.1977 +	6,
605.1978 +	3,
605.1979 +	7,
605.1980 +	2,
605.1981 +	8,
605.1982 +	1,
605.1983 +	9,
605.1984 +	0,
605.1985 +	10,
605.1986 +};
605.1987 +
605.1988 +static const long _vq_lengthlist__16c2_s_p5_1[] = {
605.1989 +	 2, 3, 3, 6, 6, 6, 6, 7, 7, 7, 7,11,10,10, 6, 6,
605.1990 +	 7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8,
605.1991 +	 8,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9,11,11,11, 6,
605.1992 +	 7, 8, 8, 8, 8, 9, 9,11,11,11, 7, 7, 8, 8, 8, 8,
605.1993 +	 8, 8,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9,11,11,11,
605.1994 +	 8, 8, 8, 8, 8, 8, 8, 8,11,11,11,11,11, 8, 8, 8,
605.1995 +	 8, 8, 8,12,11,11,11,11, 8, 8, 8, 8, 8, 8,12,11,
605.1996 +	11,11,11, 7, 7, 8, 8, 8, 8,
605.1997 +};
605.1998 +
605.1999 +static const static_codebook _16c2_s_p5_1 = {
605.2000 +	2, 121,
605.2001 +	(long *)_vq_lengthlist__16c2_s_p5_1,
605.2002 +	1, -531365888, 1611661312, 4, 0,
605.2003 +	(long *)_vq_quantlist__16c2_s_p5_1,
605.2004 +	0
605.2005 +};
605.2006 +
605.2007 +static const long _vq_quantlist__16c2_s_p6_0[] = {
605.2008 +	6,
605.2009 +	5,
605.2010 +	7,
605.2011 +	4,
605.2012 +	8,
605.2013 +	3,
605.2014 +	9,
605.2015 +	2,
605.2016 +	10,
605.2017 +	1,
605.2018 +	11,
605.2019 +	0,
605.2020 +	12,
605.2021 +};
605.2022 +
605.2023 +static const long _vq_lengthlist__16c2_s_p6_0[] = {
605.2024 +	 1, 4, 4, 6, 6, 8, 7, 8, 8, 9, 9,10,10, 5, 5, 5,
605.2025 +	 7, 7, 9, 9, 9, 9,11,11,12,12, 6, 5, 5, 7, 7, 9,
605.2026 +	 9,10, 9,11,11,12,12, 0, 7, 7, 7, 7, 9, 9,10,10,
605.2027 +	11,11,12,12, 0, 7, 7, 7, 7, 9, 9,10,10,11,11,12,
605.2028 +	12, 0,11,11, 8, 8,10,10,11,11,12,12,13,13, 0,12,
605.2029 +	12, 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
605.2030 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2031 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2032 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2033 +	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2034 +	 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2035 +};
605.2036 +
605.2037 +static const static_codebook _16c2_s_p6_0 = {
605.2038 +	2, 169,
605.2039 +	(long *)_vq_lengthlist__16c2_s_p6_0,
605.2040 +	1, -526516224, 1616117760, 4, 0,
605.2041 +	(long *)_vq_quantlist__16c2_s_p6_0,
605.2042 +	0
605.2043 +};
605.2044 +
605.2045 +static const long _vq_quantlist__16c2_s_p6_1[] = {
605.2046 +	2,
605.2047 +	1,
605.2048 +	3,
605.2049 +	0,
605.2050 +	4,
605.2051 +};
605.2052 +
605.2053 +static const long _vq_lengthlist__16c2_s_p6_1[] = {
605.2054 +	 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
605.2055 +	 6, 6, 5, 5, 6, 6, 6, 5, 5,
605.2056 +};
605.2057 +
605.2058 +static const static_codebook _16c2_s_p6_1 = {
605.2059 +	2, 25,
605.2060 +	(long *)_vq_lengthlist__16c2_s_p6_1,
605.2061 +	1, -533725184, 1611661312, 3, 0,
605.2062 +	(long *)_vq_quantlist__16c2_s_p6_1,
605.2063 +	0
605.2064 +};
605.2065 +
605.2066 +static const long _vq_quantlist__16c2_s_p7_0[] = {
605.2067 +	6,
605.2068 +	5,
605.2069 +	7,
605.2070 +	4,
605.2071 +	8,
605.2072 +	3,
605.2073 +	9,
605.2074 +	2,
605.2075 +	10,
605.2076 +	1,
605.2077 +	11,
605.2078 +	0,
605.2079 +	12,
605.2080 +};
605.2081 +
605.2082 +static const long _vq_lengthlist__16c2_s_p7_0[] = {
605.2083 +	 1, 4, 4, 7, 7, 8, 8, 8, 8,10, 9,10,10, 5, 5, 5,
605.2084 +	 7, 7, 9, 9,10,10,11,10,12,11, 6, 5, 5, 7, 7, 9,
605.2085 +	 9,10,10,11,11,12,12,20, 7, 7, 7, 7, 9, 9,10,10,
605.2086 +	11,11,12,12,20, 7, 7, 7, 7, 9, 9,11,10,12,11,12,
605.2087 +	12,20,11,11, 8, 8,10,10,11,11,12,12,13,13,20,12,
605.2088 +	12, 8, 8, 9, 9,11,11,12,12,13,13,20,20,21,10,10,
605.2089 +	10,10,11,11,12,12,13,13,21,21,21,10,10,10,10,11,
605.2090 +	11,12,12,13,13,21,21,21,14,14,11,11,12,12,13,13,
605.2091 +	13,14,21,21,21,16,15,11,11,12,11,13,13,14,14,21,
605.2092 +	21,21,21,21,13,13,12,12,13,13,14,14,21,21,21,21,
605.2093 +	21,13,13,12,12,13,13,14,14,
605.2094 +};
605.2095 +
605.2096 +static const static_codebook _16c2_s_p7_0 = {
605.2097 +	2, 169,
605.2098 +	(long *)_vq_lengthlist__16c2_s_p7_0,
605.2099 +	1, -523206656, 1618345984, 4, 0,
605.2100 +	(long *)_vq_quantlist__16c2_s_p7_0,
605.2101 +	0
605.2102 +};
605.2103 +
605.2104 +static const long _vq_quantlist__16c2_s_p7_1[] = {
605.2105 +	5,
605.2106 +	4,
605.2107 +	6,
605.2108 +	3,
605.2109 +	7,
605.2110 +	2,
605.2111 +	8,
605.2112 +	1,
605.2113 +	9,
605.2114 +	0,
605.2115 +	10,
605.2116 +};
605.2117 +
605.2118 +static const long _vq_lengthlist__16c2_s_p7_1[] = {
605.2119 +	 2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 6, 7,
605.2120 +	 7, 7, 7, 7, 8, 8, 9, 9, 9, 6, 6, 7, 7, 7, 7, 8,
605.2121 +	 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 7,
605.2122 +	 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8,
605.2123 +	 8, 8, 9, 9, 9, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9,
605.2124 +	 7, 7, 8, 8, 7, 7, 8, 8, 9, 9, 9, 9, 9, 8, 8, 7,
605.2125 +	 7, 8, 8, 9, 9, 9, 9, 9, 8, 8, 7, 7, 8, 8, 9, 9,
605.2126 +	 9, 9, 9, 7, 7, 7, 7, 8, 8,
605.2127 +};
605.2128 +
605.2129 +static const static_codebook _16c2_s_p7_1 = {
605.2130 +	2, 121,
605.2131 +	(long *)_vq_lengthlist__16c2_s_p7_1,
605.2132 +	1, -531365888, 1611661312, 4, 0,
605.2133 +	(long *)_vq_quantlist__16c2_s_p7_1,
605.2134 +	0
605.2135 +};
605.2136 +
605.2137 +static const long _vq_quantlist__16c2_s_p8_0[] = {
605.2138 +	7,
605.2139 +	6,
605.2140 +	8,
605.2141 +	5,
605.2142 +	9,
605.2143 +	4,
605.2144 +	10,
605.2145 +	3,
605.2146 +	11,
605.2147 +	2,
605.2148 +	12,
605.2149 +	1,
605.2150 +	13,
605.2151 +	0,
605.2152 +	14,
605.2153 +};
605.2154 +
605.2155 +static const long _vq_lengthlist__16c2_s_p8_0[] = {
605.2156 +	 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9,10,10, 6,
605.2157 +	 6, 6, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,11, 6, 5,
605.2158 +	 5, 8, 7, 9, 9, 8, 8, 9, 9,10,10,11,11,20, 8, 8,
605.2159 +	 8, 8, 9, 9, 9, 9,10,10,11,10,12,11,20, 8, 8, 8,
605.2160 +	 8, 9, 9, 9, 9,10,10,11,11,12,12,20,12,12, 9, 9,
605.2161 +	10,10,10,10,11,11,12,12,13,12,20,13,13, 9, 9,10,
605.2162 +	10,10,10,11,11,12,12,13,13,20,20,20, 9, 9, 9, 9,
605.2163 +	10,10,11,11,12,12,13,12,20,20,20, 9, 9, 9, 8,10,
605.2164 +	10,12,11,12,12,13,13,20,20,20,13,13,10,10,11,11,
605.2165 +	12,12,13,13,13,13,20,20,20,13,13,10,10,11,10,12,
605.2166 +	11,13,13,14,14,20,20,20,20,20,11,11,11,11,12,12,
605.2167 +	13,13,14,14,20,20,20,20,20,11,10,11,11,13,11,13,
605.2168 +	13,14,14,20,20,21,21,21,14,14,11,12,13,13,13,13,
605.2169 +	14,14,21,21,21,21,21,15,15,12,11,13,12,14,13,15,
605.2170 +	14,
605.2171 +};
605.2172 +
605.2173 +static const static_codebook _16c2_s_p8_0 = {
605.2174 +	2, 225,
605.2175 +	(long *)_vq_lengthlist__16c2_s_p8_0,
605.2176 +	1, -520986624, 1620377600, 4, 0,
605.2177 +	(long *)_vq_quantlist__16c2_s_p8_0,
605.2178 +	0
605.2179 +};
605.2180 +
605.2181 +static const long _vq_quantlist__16c2_s_p8_1[] = {
605.2182 +	10,
605.2183 +	9,
605.2184 +	11,
605.2185 +	8,
605.2186 +	12,
605.2187 +	7,
605.2188 +	13,
605.2189 +	6,
605.2190 +	14,
605.2191 +	5,
605.2192 +	15,
605.2193 +	4,
605.2194 +	16,
605.2195 +	3,
605.2196 +	17,
605.2197 +	2,
605.2198 +	18,
605.2199 +	1,
605.2200 +	19,
605.2201 +	0,
605.2202 +	20,
605.2203 +};
605.2204 +
605.2205 +static const long _vq_lengthlist__16c2_s_p8_1[] = {
605.2206 +	 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.2207 +	 8, 8, 8, 8, 8,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9,
605.2208 +	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11,10, 7, 7, 8,
605.2209 +	 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
605.2210 +	11,11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.2211 +	 9, 9, 9, 9,11,11,11, 8, 8, 8, 8, 9, 9, 9, 9, 9,
605.2212 +	 9, 9, 9,10, 9,10,10,10,10,11,11,11, 8, 8, 9, 9,
605.2213 +	 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,11,11,
605.2214 +	11, 8, 8, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,
605.2215 +	10,10,10,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9,10,10,
605.2216 +	10,10,10,10,10,10,10,10,11,11,11,11,11, 9, 9, 9,
605.2217 +	 9, 9, 9,10,10,10,10,10,10,10,10,10,10,11,11,11,
605.2218 +	11,11, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,
605.2219 +	10,10,11,11,11,11,11, 9, 9, 9, 9,10,10,10,10,10,
605.2220 +	10,10,10,10,10,10,10,11,11,11,11,11,10, 9,10,10,
605.2221 +	10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,
605.2222 +	11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2223 +	10,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,
605.2224 +	10,10,10,10,10,10,11,11,11,11,11,11,11,10,10,10,
605.2225 +	10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,
605.2226 +	11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2227 +	11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
605.2228 +	10,10,10,10,10,11,11,11,11,11,11,11,11,11,10,10,
605.2229 +	10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
605.2230 +	11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,11,
605.2231 +	11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,
605.2232 +	10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,10,
605.2233 +	10,10,10,10,10,10,10,10,10,
605.2234 +};
605.2235 +
605.2236 +static const static_codebook _16c2_s_p8_1 = {
605.2237 +	2, 441,
605.2238 +	(long *)_vq_lengthlist__16c2_s_p8_1,
605.2239 +	1, -529268736, 1611661312, 5, 0,
605.2240 +	(long *)_vq_quantlist__16c2_s_p8_1,
605.2241 +	0
605.2242 +};
605.2243 +
605.2244 +static const long _vq_quantlist__16c2_s_p9_0[] = {
605.2245 +	8,
605.2246 +	7,
605.2247 +	9,
605.2248 +	6,
605.2249 +	10,
605.2250 +	5,
605.2251 +	11,
605.2252 +	4,
605.2253 +	12,
605.2254 +	3,
605.2255 +	13,
605.2256 +	2,
605.2257 +	14,
605.2258 +	1,
605.2259 +	15,
605.2260 +	0,
605.2261 +	16,
605.2262 +};
605.2263 +
605.2264 +static const long _vq_lengthlist__16c2_s_p9_0[] = {
605.2265 +	 1, 4, 3,10, 8,10,10,10,10,10,10,10,10,10,10,10,
605.2266 +	10, 6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2267 +	10,10, 6,10, 9,10,10,10,10,10,10,10,10,10,10,10,
605.2268 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2269 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2270 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2271 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2272 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2273 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2274 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2275 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2276 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2277 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2278 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2279 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2280 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2281 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2282 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.2283 +	10,
605.2284 +};
605.2285 +
605.2286 +static const static_codebook _16c2_s_p9_0 = {
605.2287 +	2, 289,
605.2288 +	(long *)_vq_lengthlist__16c2_s_p9_0,
605.2289 +	1, -509798400, 1631393792, 5, 0,
605.2290 +	(long *)_vq_quantlist__16c2_s_p9_0,
605.2291 +	0
605.2292 +};
605.2293 +
605.2294 +static const long _vq_quantlist__16c2_s_p9_1[] = {
605.2295 +	9,
605.2296 +	8,
605.2297 +	10,
605.2298 +	7,
605.2299 +	11,
605.2300 +	6,
605.2301 +	12,
605.2302 +	5,
605.2303 +	13,
605.2304 +	4,
605.2305 +	14,
605.2306 +	3,
605.2307 +	15,
605.2308 +	2,
605.2309 +	16,
605.2310 +	1,
605.2311 +	17,
605.2312 +	0,
605.2313 +	18,
605.2314 +};
605.2315 +
605.2316 +static const long _vq_lengthlist__16c2_s_p9_1[] = {
605.2317 +	 1, 4, 4, 7, 7, 7, 7, 7, 7, 8, 8,10, 9,11,10,13,
605.2318 +	11,14,13, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8,11, 9,
605.2319 +	13,11,14,12,14,13, 5, 6, 6, 8, 8, 8, 8, 8, 8, 9,
605.2320 +	 9,11,11,13,11,14,13,15,15,17, 8, 8, 8, 8, 9, 9,
605.2321 +	 9, 8,11, 9,12,10,13,11,14,12,14,13,17, 8, 8, 8,
605.2322 +	 8, 9, 9, 9, 9,10,10,11,11,13,13,13,14,16,15,17,
605.2323 +	12,12, 8, 8, 9, 9,10,10,11,11,12,11,13,12,13,12,
605.2324 +	14,13,16,12,12, 8, 8, 9, 9,10,10,11,11,12,12,13,
605.2325 +	13,14,14,15,15,17,17,17, 9, 9, 9, 9,11,11,12,12,
605.2326 +	12,13,13,13,16,14,14,14,17,17,17, 9, 8, 9, 8,11,
605.2327 +	10,12,12,13,13,14,14,15,15,16,16,17,17,17,12,12,
605.2328 +	10,10,11,12,12,13,13,14,13,15,15,14,16,15,17,17,
605.2329 +	17,12,12,10, 8,12, 9,13,12,14,14,15,14,15,16,16,
605.2330 +	16,17,17,17,17,17,11,11,12,12,14,14,14,16,15,16,
605.2331 +	15,16,15,17,17,17,17,17,17,11, 9,12,10,13,11,15,
605.2332 +	14,16,16,17,16,16,15,17,17,17,17,17,15,15,12,12,
605.2333 +	14,14,15,16,16,15,16,16,17,17,17,17,17,17,17,14,
605.2334 +	14,12,10,14,11,15,12,17,16,15,16,17,16,17,17,17,
605.2335 +	17,17,17,17,13,13,14,14,14,16,17,17,16,17,17,17,
605.2336 +	17,17,17,17,17,17,17,13, 9,13,12,15,13,16,16,17,
605.2337 +	17,17,17,17,17,17,17,17,17,17,15,17,14,14,15,16,
605.2338 +	16,17,16,17,16,17,17,17,17,17,17,17,17,17,17,14,
605.2339 +	13,15,16,16,17,16,17,17,17,
605.2340 +};
605.2341 +
605.2342 +static const static_codebook _16c2_s_p9_1 = {
605.2343 +	2, 361,
605.2344 +	(long *)_vq_lengthlist__16c2_s_p9_1,
605.2345 +	1, -518287360, 1622704128, 5, 0,
605.2346 +	(long *)_vq_quantlist__16c2_s_p9_1,
605.2347 +	0
605.2348 +};
605.2349 +
605.2350 +static const long _vq_quantlist__16c2_s_p9_2[] = {
605.2351 +	24,
605.2352 +	23,
605.2353 +	25,
605.2354 +	22,
605.2355 +	26,
605.2356 +	21,
605.2357 +	27,
605.2358 +	20,
605.2359 +	28,
605.2360 +	19,
605.2361 +	29,
605.2362 +	18,
605.2363 +	30,
605.2364 +	17,
605.2365 +	31,
605.2366 +	16,
605.2367 +	32,
605.2368 +	15,
605.2369 +	33,
605.2370 +	14,
605.2371 +	34,
605.2372 +	13,
605.2373 +	35,
605.2374 +	12,
605.2375 +	36,
605.2376 +	11,
605.2377 +	37,
605.2378 +	10,
605.2379 +	38,
605.2380 +	9,
605.2381 +	39,
605.2382 +	8,
605.2383 +	40,
605.2384 +	7,
605.2385 +	41,
605.2386 +	6,
605.2387 +	42,
605.2388 +	5,
605.2389 +	43,
605.2390 +	4,
605.2391 +	44,
605.2392 +	3,
605.2393 +	45,
605.2394 +	2,
605.2395 +	46,
605.2396 +	1,
605.2397 +	47,
605.2398 +	0,
605.2399 +	48,
605.2400 +};
605.2401 +
605.2402 +static const long _vq_lengthlist__16c2_s_p9_2[] = {
605.2403 +	 2, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6,
605.2404 +	 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.2405 +	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.2406 +	 7,
605.2407 +};
605.2408 +
605.2409 +static const static_codebook _16c2_s_p9_2 = {
605.2410 +	1, 49,
605.2411 +	(long *)_vq_lengthlist__16c2_s_p9_2,
605.2412 +	1, -526909440, 1611661312, 6, 0,
605.2413 +	(long *)_vq_quantlist__16c2_s_p9_2,
605.2414 +	0
605.2415 +};
605.2416 +
605.2417 +static const long _huff_lengthlist__16c2_s_short[] = {
605.2418 +	 7,10,12,11,12,13,15,16,18,15,10, 8, 8, 8, 9,10,
605.2419 +	12,13,14,17,10, 7, 7, 7, 7, 8,10,12,15,18,10, 7,
605.2420 +	 7, 5, 5, 6, 8,10,13,15,10, 7, 6, 5, 4, 4, 6, 9,
605.2421 +	12,15,11, 7, 7, 5, 4, 3, 4, 7,11,13,12, 9, 8, 7,
605.2422 +	 5, 4, 4, 5,10,13,11,11,11, 9, 7, 5, 5, 5, 9,12,
605.2423 +	13,12,13,12,10, 8, 8, 7, 9,13,14,14,14,14,13,11,
605.2424 +	11,10,10,13,
605.2425 +};
605.2426 +
605.2427 +static const static_codebook _huff_book__16c2_s_short = {
605.2428 +	2, 100,
605.2429 +	(long *)_huff_lengthlist__16c2_s_short,
605.2430 +	0, 0, 0, 0, 0,
605.2431 +	NULL,
605.2432 +	0
605.2433 +};
605.2434 +
605.2435 +static const long _vq_quantlist__8c0_s_p1_0[] = {
605.2436 +        1,
605.2437 +        0,
605.2438 +        2,
605.2439 +};
605.2440 +
605.2441 +static const long _vq_lengthlist__8c0_s_p1_0[] = {
605.2442 +         1, 5, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.2443 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2444 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2445 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2446 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2447 +         0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0,
605.2448 +         0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2449 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2450 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2451 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2452 +         0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.2453 +         0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2454 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2455 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2456 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2457 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2458 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2459 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2460 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2463 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2464 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2465 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2466 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2468 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2469 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2470 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2471 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2472 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2473 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2474 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2475 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2476 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2477 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2478 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2479 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2480 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2481 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2482 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2483 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2484 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2485 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2486 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2487 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0,
605.2488 +         0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
605.2489 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2490 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2491 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2492 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10, 9, 0, 0, 0,
605.2493 +         0, 0, 0, 8, 9,11, 0, 0, 0, 0, 0, 0, 9,11,11, 0,
605.2494 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2495 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2496 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2497 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9,10, 0, 0,
605.2498 +         0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 9,11,11,
605.2499 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2500 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2501 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2502 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2503 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2504 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2505 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2506 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2507 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2508 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2509 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2510 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2511 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2512 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2513 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2514 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2515 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2516 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2517 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2518 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2519 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2520 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2521 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2522 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2523 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2525 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2526 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2527 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2528 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2529 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2530 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2531 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2532 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2533 +         0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
605.2534 +         0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2535 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2536 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2537 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2538 +         0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,11, 0,
605.2539 +         0, 0, 0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 0, 0,
605.2540 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2541 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2542 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2543 +         0, 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 9,11,11,
605.2544 +         0, 0, 0, 0, 0, 0, 8,11, 9, 0, 0, 0, 0, 0, 0, 0,
605.2545 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2546 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2547 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2548 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2549 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2550 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2551 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2552 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2553 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2554 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2555 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2556 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2557 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2558 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2559 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2560 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2561 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2562 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2563 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2564 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2565 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2566 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2567 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2568 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2569 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2570 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2571 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2572 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2573 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2574 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2575 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2576 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2577 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2578 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2579 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2580 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2581 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2582 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2583 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2584 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2585 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2586 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2587 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2588 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2589 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2590 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2591 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2592 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2593 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2594 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2595 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2596 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2597 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2598 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2599 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2600 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2601 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2602 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2603 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2604 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2605 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2606 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2607 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2608 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2609 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2610 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2611 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2612 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2613 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2614 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2615 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2616 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2617 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2618 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2619 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2620 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2621 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2622 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2623 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2624 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2625 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2626 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2627 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2628 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2629 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2630 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2631 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2632 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2633 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2634 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2635 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2636 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2637 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2638 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2639 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2640 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2641 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2642 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2643 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2644 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2645 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2646 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2647 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2648 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2649 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2650 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2651 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2652 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2653 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2654 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2655 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2656 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2657 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2658 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2659 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2660 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2661 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2662 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2663 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2664 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2665 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2666 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2667 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2668 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2669 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2670 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2671 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2672 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2673 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2674 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2675 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2676 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2677 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2678 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2679 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2680 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2681 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2682 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2683 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2684 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2685 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2686 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2687 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2688 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2689 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2690 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2691 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2692 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2693 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2694 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2695 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2696 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2697 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2698 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2699 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2700 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2701 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2702 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2703 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2704 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2705 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2706 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2707 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2708 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2709 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2710 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2711 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2712 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2713 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2714 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2715 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2716 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2717 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2718 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2719 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2720 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2721 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2722 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2723 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2724 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2725 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2726 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2727 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2728 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2729 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2730 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2731 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2732 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2733 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2734 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2735 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2736 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2737 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2738 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2739 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2740 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2741 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2742 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2743 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2744 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2745 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2746 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2747 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2748 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2749 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2750 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2751 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2752 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2753 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2754 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2755 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2756 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2757 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2758 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2759 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2760 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2761 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2762 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2763 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2764 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2765 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2766 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2767 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2768 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2769 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2770 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2771 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2772 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2773 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2774 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2775 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2776 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2777 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2778 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2779 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2780 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2781 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2782 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2783 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2784 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2785 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2786 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2787 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2788 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2789 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2790 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2791 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2792 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2793 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2794 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2795 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2796 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2797 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2798 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2799 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2800 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2801 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2802 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2803 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2804 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2805 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2806 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2807 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2808 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2809 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2810 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2811 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2812 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2813 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2814 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2815 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2816 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2817 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2818 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2819 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2820 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2821 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2822 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2823 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2824 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2825 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2826 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2827 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2828 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2829 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2830 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2831 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2832 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2833 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2834 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2835 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2836 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2837 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2838 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2839 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2840 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2841 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2842 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2843 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2844 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2845 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2846 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2847 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2848 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2849 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2850 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2851 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2852 +         0,
605.2853 +};
605.2854 +
605.2855 +static const static_codebook _8c0_s_p1_0 = {
605.2856 +        8, 6561,
605.2857 +        (long *)_vq_lengthlist__8c0_s_p1_0,
605.2858 +        1, -535822336, 1611661312, 2, 0,
605.2859 +        (long *)_vq_quantlist__8c0_s_p1_0,
605.2860 +        0
605.2861 +};
605.2862 +
605.2863 +static const long _vq_quantlist__8c0_s_p3_0[] = {
605.2864 +        2,
605.2865 +        1,
605.2866 +        3,
605.2867 +        0,
605.2868 +        4,
605.2869 +};
605.2870 +
605.2871 +static const long _vq_lengthlist__8c0_s_p3_0[] = {
605.2872 +         1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2873 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 7, 0, 0,
605.2874 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2875 +         0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2876 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 8, 8,
605.2877 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2878 +         0, 0, 0, 0, 6, 7, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0,
605.2879 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2880 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2881 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2882 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2883 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2884 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2885 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2886 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2887 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2888 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2889 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2890 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2891 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2892 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2893 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2894 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2895 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2896 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2897 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2898 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2899 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2900 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2901 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2902 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2903 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2904 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2905 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2906 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2907 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2908 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2909 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2910 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2911 +         0,
605.2912 +};
605.2913 +
605.2914 +static const static_codebook _8c0_s_p3_0 = {
605.2915 +        4, 625,
605.2916 +        (long *)_vq_lengthlist__8c0_s_p3_0,
605.2917 +        1, -533725184, 1611661312, 3, 0,
605.2918 +        (long *)_vq_quantlist__8c0_s_p3_0,
605.2919 +        0
605.2920 +};
605.2921 +
605.2922 +static const long _vq_quantlist__8c0_s_p4_0[] = {
605.2923 +        4,
605.2924 +        3,
605.2925 +        5,
605.2926 +        2,
605.2927 +        6,
605.2928 +        1,
605.2929 +        7,
605.2930 +        0,
605.2931 +        8,
605.2932 +};
605.2933 +
605.2934 +static const long _vq_lengthlist__8c0_s_p4_0[] = {
605.2935 +         1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
605.2936 +         0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
605.2937 +         0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
605.2938 +         8, 8, 0, 0, 0, 0, 0, 0, 0, 9, 8, 0, 0, 0, 0, 0,
605.2939 +         0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.2940 +         0,
605.2941 +};
605.2942 +
605.2943 +static const static_codebook _8c0_s_p4_0 = {
605.2944 +        2, 81,
605.2945 +        (long *)_vq_lengthlist__8c0_s_p4_0,
605.2946 +        1, -531628032, 1611661312, 4, 0,
605.2947 +        (long *)_vq_quantlist__8c0_s_p4_0,
605.2948 +        0
605.2949 +};
605.2950 +
605.2951 +static const long _vq_quantlist__8c0_s_p5_0[] = {
605.2952 +        4,
605.2953 +        3,
605.2954 +        5,
605.2955 +        2,
605.2956 +        6,
605.2957 +        1,
605.2958 +        7,
605.2959 +        0,
605.2960 +        8,
605.2961 +};
605.2962 +
605.2963 +static const long _vq_lengthlist__8c0_s_p5_0[] = {
605.2964 +         1, 3, 3, 5, 5, 7, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7,
605.2965 +         8, 8, 0, 0, 0, 7, 7, 7, 7, 8, 9, 0, 0, 0, 8, 8,
605.2966 +         8, 8, 9, 9, 0, 0, 0, 8, 8, 8, 8, 9, 9, 0, 0, 0,
605.2967 +         9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0,
605.2968 +         0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
605.2969 +        10,
605.2970 +};
605.2971 +
605.2972 +static const static_codebook _8c0_s_p5_0 = {
605.2973 +        2, 81,
605.2974 +        (long *)_vq_lengthlist__8c0_s_p5_0,
605.2975 +        1, -531628032, 1611661312, 4, 0,
605.2976 +        (long *)_vq_quantlist__8c0_s_p5_0,
605.2977 +        0
605.2978 +};
605.2979 +
605.2980 +static const long _vq_quantlist__8c0_s_p6_0[] = {
605.2981 +        8,
605.2982 +        7,
605.2983 +        9,
605.2984 +        6,
605.2985 +        10,
605.2986 +        5,
605.2987 +        11,
605.2988 +        4,
605.2989 +        12,
605.2990 +        3,
605.2991 +        13,
605.2992 +        2,
605.2993 +        14,
605.2994 +        1,
605.2995 +        15,
605.2996 +        0,
605.2997 +        16,
605.2998 +};
605.2999 +
605.3000 +static const long _vq_lengthlist__8c0_s_p6_0[] = {
605.3001 +         1, 3, 3, 6, 6, 8, 8, 9, 9, 8, 8,10, 9,10,10,11,
605.3002 +        11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11,
605.3003 +        11,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,
605.3004 +        11,12,11, 0, 0, 0, 8, 8, 9, 9,10,10, 9, 9,10,10,
605.3005 +        11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10, 9, 9,11,
605.3006 +        10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,10,10,
605.3007 +        11,11,11,12,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,10,
605.3008 +        10,11,11,12,12,13,13, 0, 0, 0,10,10,10,10,11,11,
605.3009 +        10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,10, 9,10,
605.3010 +        11,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
605.3011 +        10, 9,10,11,12,12,13,13,14,13, 0, 0, 0, 0, 0, 9,
605.3012 +         9, 9,10,10,10,11,11,13,12,13,13, 0, 0, 0, 0, 0,
605.3013 +        10,10,10,10,11,11,12,12,13,13,14,14, 0, 0, 0, 0,
605.3014 +         0, 0, 0,10,10,11,11,12,12,13,13,13,14, 0, 0, 0,
605.3015 +         0, 0, 0, 0,11,11,11,11,12,12,13,14,14,14, 0, 0,
605.3016 +         0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,14,13, 0,
605.3017 +         0, 0, 0, 0, 0, 0,11,11,12,12,13,13,14,14,14,14,
605.3018 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14,
605.3019 +        14,
605.3020 +};
605.3021 +
605.3022 +static const static_codebook _8c0_s_p6_0 = {
605.3023 +        2, 289,
605.3024 +        (long *)_vq_lengthlist__8c0_s_p6_0,
605.3025 +        1, -529530880, 1611661312, 5, 0,
605.3026 +        (long *)_vq_quantlist__8c0_s_p6_0,
605.3027 +        0
605.3028 +};
605.3029 +
605.3030 +static const long _vq_quantlist__8c0_s_p7_0[] = {
605.3031 +        1,
605.3032 +        0,
605.3033 +        2,
605.3034 +};
605.3035 +
605.3036 +static const long _vq_lengthlist__8c0_s_p7_0[] = {
605.3037 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,11, 9,10,12,
605.3038 +         9,10, 4, 7, 7,10,10,10,11, 9, 9, 6,11,10,11,11,
605.3039 +        12,11,11,11, 6,10,10,11,11,12,11,10,10, 6, 9,10,
605.3040 +        11,11,11,11,10,10, 7,10,11,12,11,11,12,11,12, 6,
605.3041 +         9, 9,10, 9, 9,11,10,10, 6, 9, 9,10,10,10,11,10,
605.3042 +        10,
605.3043 +};
605.3044 +
605.3045 +static const static_codebook _8c0_s_p7_0 = {
605.3046 +        4, 81,
605.3047 +        (long *)_vq_lengthlist__8c0_s_p7_0,
605.3048 +        1, -529137664, 1618345984, 2, 0,
605.3049 +        (long *)_vq_quantlist__8c0_s_p7_0,
605.3050 +        0
605.3051 +};
605.3052 +
605.3053 +static const long _vq_quantlist__8c0_s_p7_1[] = {
605.3054 +        5,
605.3055 +        4,
605.3056 +        6,
605.3057 +        3,
605.3058 +        7,
605.3059 +        2,
605.3060 +        8,
605.3061 +        1,
605.3062 +        9,
605.3063 +        0,
605.3064 +        10,
605.3065 +};
605.3066 +
605.3067 +static const long _vq_lengthlist__8c0_s_p7_1[] = {
605.3068 +         1, 3, 3, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10, 7, 7,
605.3069 +         8, 8, 9, 9, 9, 9,10,10, 9, 7, 7, 8, 8, 9, 9, 9,
605.3070 +         9,10,10,10, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10, 8,
605.3071 +         8, 9, 9, 9, 9, 8, 9,10,10,10, 8, 8, 9, 9, 9,10,
605.3072 +        10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,10,11,10,11,
605.3073 +         9, 9, 9, 9,10,10,10,10,11,11,11,10,10, 9, 9,10,
605.3074 +        10,10, 9,11,10,10,10,10,10,10, 9, 9,10,10,11,11,
605.3075 +        10,10,10, 9, 9, 9,10,10,10,
605.3076 +};
605.3077 +
605.3078 +static const static_codebook _8c0_s_p7_1 = {
605.3079 +        2, 121,
605.3080 +        (long *)_vq_lengthlist__8c0_s_p7_1,
605.3081 +        1, -531365888, 1611661312, 4, 0,
605.3082 +        (long *)_vq_quantlist__8c0_s_p7_1,
605.3083 +        0
605.3084 +};
605.3085 +
605.3086 +static const long _vq_quantlist__8c0_s_p8_0[] = {
605.3087 +        6,
605.3088 +        5,
605.3089 +        7,
605.3090 +        4,
605.3091 +        8,
605.3092 +        3,
605.3093 +        9,
605.3094 +        2,
605.3095 +        10,
605.3096 +        1,
605.3097 +        11,
605.3098 +        0,
605.3099 +        12,
605.3100 +};
605.3101 +
605.3102 +static const long _vq_lengthlist__8c0_s_p8_0[] = {
605.3103 +         1, 4, 4, 7, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 6, 6,
605.3104 +         7, 7, 8, 8, 7, 7, 8, 9,10,10, 7, 6, 6, 7, 7, 8,
605.3105 +         7, 7, 7, 9, 9,10,12, 0, 8, 8, 8, 8, 8, 9, 8, 8,
605.3106 +         9, 9,10,10, 0, 8, 8, 8, 8, 8, 9, 8, 9, 9, 9,11,
605.3107 +        10, 0, 0,13, 9, 8, 9, 9, 9, 9,10,10,11,11, 0,13,
605.3108 +         0, 9, 9, 9, 9, 9, 9,11,10,11,11, 0, 0, 0, 8, 9,
605.3109 +        10, 9,10,10,13,11,12,12, 0, 0, 0, 8, 9, 9, 9,10,
605.3110 +        10,13,12,12,13, 0, 0, 0,12, 0,10,10,12,11,10,11,
605.3111 +        12,12, 0, 0, 0,13,13,10,10,10,11,12, 0,13, 0, 0,
605.3112 +         0, 0, 0, 0,13,11, 0,12,12,12,13,12, 0, 0, 0, 0,
605.3113 +         0, 0,13,13,11,13,13,11,12,
605.3114 +};
605.3115 +
605.3116 +static const static_codebook _8c0_s_p8_0 = {
605.3117 +        2, 169,
605.3118 +        (long *)_vq_lengthlist__8c0_s_p8_0,
605.3119 +        1, -526516224, 1616117760, 4, 0,
605.3120 +        (long *)_vq_quantlist__8c0_s_p8_0,
605.3121 +        0
605.3122 +};
605.3123 +
605.3124 +static const long _vq_quantlist__8c0_s_p8_1[] = {
605.3125 +        2,
605.3126 +        1,
605.3127 +        3,
605.3128 +        0,
605.3129 +        4,
605.3130 +};
605.3131 +
605.3132 +static const long _vq_lengthlist__8c0_s_p8_1[] = {
605.3133 +         1, 3, 4, 5, 5, 7, 6, 6, 6, 5, 7, 7, 7, 6, 6, 7,
605.3134 +         7, 7, 6, 6, 7, 7, 7, 6, 6,
605.3135 +};
605.3136 +
605.3137 +static const static_codebook _8c0_s_p8_1 = {
605.3138 +        2, 25,
605.3139 +        (long *)_vq_lengthlist__8c0_s_p8_1,
605.3140 +        1, -533725184, 1611661312, 3, 0,
605.3141 +        (long *)_vq_quantlist__8c0_s_p8_1,
605.3142 +        0
605.3143 +};
605.3144 +
605.3145 +static const long _vq_quantlist__8c0_s_p9_0[] = {
605.3146 +        1,
605.3147 +        0,
605.3148 +        2,
605.3149 +};
605.3150 +
605.3151 +static const long _vq_lengthlist__8c0_s_p9_0[] = {
605.3152 +         1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.3153 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.3154 +         8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.3155 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.3156 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.3157 +         7,
605.3158 +};
605.3159 +
605.3160 +static const static_codebook _8c0_s_p9_0 = {
605.3161 +        4, 81,
605.3162 +        (long *)_vq_lengthlist__8c0_s_p9_0,
605.3163 +        1, -518803456, 1628680192, 2, 0,
605.3164 +        (long *)_vq_quantlist__8c0_s_p9_0,
605.3165 +        0
605.3166 +};
605.3167 +
605.3168 +static const long _vq_quantlist__8c0_s_p9_1[] = {
605.3169 +        7,
605.3170 +        6,
605.3171 +        8,
605.3172 +        5,
605.3173 +        9,
605.3174 +        4,
605.3175 +        10,
605.3176 +        3,
605.3177 +        11,
605.3178 +        2,
605.3179 +        12,
605.3180 +        1,
605.3181 +        13,
605.3182 +        0,
605.3183 +        14,
605.3184 +};
605.3185 +
605.3186 +static const long _vq_lengthlist__8c0_s_p9_1[] = {
605.3187 +         1, 4, 4, 5, 5,10, 8,11,11,11,11,11,11,11,11, 6,
605.3188 +         6, 6, 7, 6,11,10,11,11,11,11,11,11,11,11, 7, 5,
605.3189 +         6, 6, 6, 8, 7,11,11,11,11,11,11,11,11,11, 7, 8,
605.3190 +         8, 8, 9, 9,11,11,11,11,11,11,11,11,11, 9, 8, 7,
605.3191 +         8, 9,11,11,11,11,11,11,11,11,11,11,11,10,11,11,
605.3192 +        11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,
605.3193 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.3194 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.3195 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.3196 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.3197 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.3198 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.3199 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.3200 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.3201 +        11,
605.3202 +};
605.3203 +
605.3204 +static const static_codebook _8c0_s_p9_1 = {
605.3205 +        2, 225,
605.3206 +        (long *)_vq_lengthlist__8c0_s_p9_1,
605.3207 +        1, -520986624, 1620377600, 4, 0,
605.3208 +        (long *)_vq_quantlist__8c0_s_p9_1,
605.3209 +        0
605.3210 +};
605.3211 +
605.3212 +static const long _vq_quantlist__8c0_s_p9_2[] = {
605.3213 +        10,
605.3214 +        9,
605.3215 +        11,
605.3216 +        8,
605.3217 +        12,
605.3218 +        7,
605.3219 +        13,
605.3220 +        6,
605.3221 +        14,
605.3222 +        5,
605.3223 +        15,
605.3224 +        4,
605.3225 +        16,
605.3226 +        3,
605.3227 +        17,
605.3228 +        2,
605.3229 +        18,
605.3230 +        1,
605.3231 +        19,
605.3232 +        0,
605.3233 +        20,
605.3234 +};
605.3235 +
605.3236 +static const long _vq_lengthlist__8c0_s_p9_2[] = {
605.3237 +         1, 5, 5, 7, 7, 8, 7, 8, 8,10,10, 9, 9,10,10,10,
605.3238 +        11,11,10,12,11,12,12,12, 9, 8, 8, 8, 8, 8, 9,10,
605.3239 +        10,10,10,11,11,11,10,11,11,12,12,11,12, 8, 8, 7,
605.3240 +         7, 8, 9,10,10,10, 9,10,10, 9,10,10,11,11,11,11,
605.3241 +        11,11, 9, 9, 9, 9, 8, 9,10,10,11,10,10,11,11,12,
605.3242 +        10,10,12,12,11,11,10, 9, 9,10, 8, 9,10,10,10, 9,
605.3243 +        10,10,11,11,10,11,10,10,10,12,12,12, 9,10, 9,10,
605.3244 +         9, 9,10,10,11,11,11,11,10,10,10,11,12,11,12,11,
605.3245 +        12,10,11,10,11, 9,10, 9,10, 9,10,10, 9,10,10,11,
605.3246 +        10,11,11,11,11,12,11, 9,10,10,10,10,11,11,11,11,
605.3247 +        11,10,11,11,11,11,10,12,10,12,12,11,12,10,10,11,
605.3248 +        10, 9,11,10,11, 9,10,11,10,10,10,11,11,11,11,12,
605.3249 +        12,10, 9, 9,11,10, 9,12,11,10,12,12,11,11,11,11,
605.3250 +        10,11,11,12,11,10,12, 9,11,10,11,10,10,11,10,11,
605.3251 +         9,10,10,10,11,12,11,11,12,11,10,10,11,11, 9,10,
605.3252 +        10,12,10,11,10,10,10, 9,10,10,10,10, 9,10,10,11,
605.3253 +        11,11,11,12,11,10,10,10,10,11,11,10,11,11, 9,11,
605.3254 +        10,12,10,12,11,10,11,10,10,10,11,10,10,11,11,10,
605.3255 +        11,10,10,10,10,11,11,12,10,10,10,11,10,11,12,11,
605.3256 +        10,11,10,10,11,11,10,12,10, 9,10,10,11,11,11,10,
605.3257 +        12,10,10,11,11,11,10,10,11,10,10,10,11,10,11,10,
605.3258 +        12,11,11,10,10,10,12,10,10,11, 9,10,11,11,11,10,
605.3259 +        10,11,10,10, 9,11,11,12,12,11,12,11,11,11,11,11,
605.3260 +        11, 9,10,11,10,12,10,10,10,10,11,10,10,11,10,10,
605.3261 +        12,10,10,10,10,10, 9,12,10,10,10,10,12, 9,11,10,
605.3262 +        10,11,10,12,12,10,12,12,12,10,10,10,10, 9,10,11,
605.3263 +        10,10,12,10,10,12,11,10,11,10,10,12,11,10,12,10,
605.3264 +        10,11, 9,11,10, 9,10, 9,10,
605.3265 +};
605.3266 +
605.3267 +static const static_codebook _8c0_s_p9_2 = {
605.3268 +        2, 441,
605.3269 +        (long *)_vq_lengthlist__8c0_s_p9_2,
605.3270 +        1, -529268736, 1611661312, 5, 0,
605.3271 +        (long *)_vq_quantlist__8c0_s_p9_2,
605.3272 +        0
605.3273 +};
605.3274 +
605.3275 +static const long _huff_lengthlist__8c0_s_single[] = {
605.3276 +         4, 5,18, 7,10, 6, 7, 8, 9,10, 5, 2,18, 5, 7, 5,
605.3277 +         6, 7, 8,11,17,17,17,17,17,17,17,17,17,17, 7, 4,
605.3278 +        17, 6, 9, 6, 8,10,12,15,11, 7,17, 9, 6, 6, 7, 9,
605.3279 +        11,15, 6, 4,17, 6, 6, 4, 5, 8,11,16, 6, 6,17, 8,
605.3280 +         6, 5, 6, 9,13,16, 8, 9,17,11, 9, 8, 8,11,13,17,
605.3281 +         9,12,17,15,14,13,12,13,14,17,12,15,17,17,17,17,
605.3282 +        17,16,17,17,
605.3283 +};
605.3284 +
605.3285 +static const static_codebook _huff_book__8c0_s_single = {
605.3286 +        2, 100,
605.3287 +        (long *)_huff_lengthlist__8c0_s_single,
605.3288 +        0, 0, 0, 0, 0,
605.3289 +        NULL,
605.3290 +        0
605.3291 +};
605.3292 +
605.3293 +static const long _vq_quantlist__8c1_s_p1_0[] = {
605.3294 +        1,
605.3295 +        0,
605.3296 +        2,
605.3297 +};
605.3298 +
605.3299 +static const long _vq_lengthlist__8c1_s_p1_0[] = {
605.3300 +         1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.3301 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3302 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3303 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3304 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3305 +         0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0,
605.3306 +         0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3307 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3308 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3309 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3310 +         0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
605.3311 +         0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3312 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3313 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3314 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3315 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3316 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3317 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3318 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3319 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3320 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3321 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3322 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3323 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3324 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3325 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3326 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3327 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3329 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3330 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3331 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3332 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3333 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3334 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3335 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3336 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3339 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3342 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0,
605.3346 +         0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
605.3347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
605.3351 +         0, 0, 0, 8, 8,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
605.3352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.3356 +         0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
605.3357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3362 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3363 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3364 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3365 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3366 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3367 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3368 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3369 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3370 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3375 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3376 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3377 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3378 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3379 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3380 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3381 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3382 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3383 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3385 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3386 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3387 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3388 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3389 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3390 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3391 +         0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
605.3392 +         0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3393 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3394 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3395 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3396 +         0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
605.3397 +         0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0,
605.3398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3399 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3400 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3401 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
605.3402 +         0, 0, 0, 0, 0, 0, 8,10, 8, 0, 0, 0, 0, 0, 0, 0,
605.3403 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3404 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3405 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3406 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3410 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3411 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3412 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3413 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3414 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3415 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3416 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3417 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3418 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3419 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3420 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3421 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3422 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3423 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3424 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3425 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3426 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3427 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3428 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3429 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3430 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3431 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3432 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3433 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3434 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3435 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3436 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3437 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3438 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3439 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3440 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3441 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3442 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3443 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3444 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3445 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3446 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3447 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3448 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3449 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3450 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3451 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3452 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3453 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3454 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3455 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3456 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3457 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3458 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3459 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3460 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3463 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3464 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3465 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3466 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3468 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3469 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3470 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3471 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3472 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3473 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3474 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3475 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3476 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3477 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3478 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3479 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3480 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3481 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3482 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3483 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3484 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3485 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3486 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3487 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3488 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3489 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3490 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3491 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3492 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3493 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3494 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3495 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3496 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3497 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3498 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3499 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3500 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3501 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3502 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3503 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3504 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3505 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3506 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3507 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3508 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3509 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3510 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3511 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3512 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3513 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3514 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3515 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3516 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3517 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3518 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3519 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3520 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3521 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3522 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3523 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3525 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3526 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3527 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3528 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3529 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3530 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3531 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3532 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3533 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3534 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3535 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3536 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3537 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3538 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3539 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3540 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3541 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3542 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3543 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3544 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3545 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3546 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3547 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3548 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3549 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3550 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3551 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3552 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3553 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3554 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3555 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3556 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3557 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3558 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3559 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3560 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3561 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3562 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3563 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3564 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3565 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3566 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3567 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3568 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3569 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3570 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3571 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3572 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3573 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3574 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3575 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3576 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3577 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3578 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3579 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3580 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3581 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3582 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3583 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3584 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3585 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3586 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3587 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3588 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3589 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3590 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3591 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3592 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3593 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3594 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3595 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3596 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3597 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3598 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3599 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3600 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3601 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3602 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3603 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3604 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3605 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3606 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3607 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3608 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3609 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3610 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3611 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3612 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3613 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3614 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3615 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3616 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3617 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3618 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3619 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3620 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3621 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3622 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3623 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3624 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3625 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3626 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3627 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3628 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3629 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3630 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3631 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3632 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3633 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3634 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3635 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3636 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3637 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3638 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3639 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3640 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3641 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3642 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3643 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3644 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3645 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3646 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3647 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3648 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3649 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3650 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3651 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3652 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3653 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3654 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3655 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3656 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3657 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3658 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3659 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3660 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3661 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3662 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3663 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3664 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3665 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3666 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3667 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3668 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3669 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3670 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3671 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3672 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3673 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3674 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3675 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3676 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3677 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3678 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3679 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3680 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3681 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3682 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3683 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3684 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3685 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3686 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3687 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3688 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3689 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3690 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3691 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3692 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3693 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3694 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3695 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3696 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3697 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3698 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3699 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3700 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3701 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3702 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3703 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3704 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3705 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3706 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3707 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3708 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3709 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3710 +         0,
605.3711 +};
605.3712 +
605.3713 +static const static_codebook _8c1_s_p1_0 = {
605.3714 +        8, 6561,
605.3715 +        (long *)_vq_lengthlist__8c1_s_p1_0,
605.3716 +        1, -535822336, 1611661312, 2, 0,
605.3717 +        (long *)_vq_quantlist__8c1_s_p1_0,
605.3718 +        0
605.3719 +};
605.3720 +
605.3721 +static const long _vq_quantlist__8c1_s_p3_0[] = {
605.3722 +        2,
605.3723 +        1,
605.3724 +        3,
605.3725 +        0,
605.3726 +        4,
605.3727 +};
605.3728 +
605.3729 +static const long _vq_lengthlist__8c1_s_p3_0[] = {
605.3730 +         2, 4, 4, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3731 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0,
605.3732 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3733 +         0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3734 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 7,
605.3735 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3736 +         0, 0, 0, 0, 6, 6, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0,
605.3737 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3738 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3739 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3740 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3741 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3742 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3743 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3744 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3745 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3746 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3747 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3748 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3749 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3750 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3751 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3752 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3753 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3754 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3755 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3756 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3757 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3758 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3759 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3760 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3761 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3762 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3763 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3764 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3765 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3766 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3767 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3768 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3769 +         0,
605.3770 +};
605.3771 +
605.3772 +static const static_codebook _8c1_s_p3_0 = {
605.3773 +        4, 625,
605.3774 +        (long *)_vq_lengthlist__8c1_s_p3_0,
605.3775 +        1, -533725184, 1611661312, 3, 0,
605.3776 +        (long *)_vq_quantlist__8c1_s_p3_0,
605.3777 +        0
605.3778 +};
605.3779 +
605.3780 +static const long _vq_quantlist__8c1_s_p4_0[] = {
605.3781 +        4,
605.3782 +        3,
605.3783 +        5,
605.3784 +        2,
605.3785 +        6,
605.3786 +        1,
605.3787 +        7,
605.3788 +        0,
605.3789 +        8,
605.3790 +};
605.3791 +
605.3792 +static const long _vq_lengthlist__8c1_s_p4_0[] = {
605.3793 +         1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
605.3794 +         0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
605.3795 +         0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
605.3796 +         8, 8, 0, 0, 0, 0, 0, 0, 0, 9, 8, 0, 0, 0, 0, 0,
605.3797 +         0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.3798 +         0,
605.3799 +};
605.3800 +
605.3801 +static const static_codebook _8c1_s_p4_0 = {
605.3802 +        2, 81,
605.3803 +        (long *)_vq_lengthlist__8c1_s_p4_0,
605.3804 +        1, -531628032, 1611661312, 4, 0,
605.3805 +        (long *)_vq_quantlist__8c1_s_p4_0,
605.3806 +        0
605.3807 +};
605.3808 +
605.3809 +static const long _vq_quantlist__8c1_s_p5_0[] = {
605.3810 +        4,
605.3811 +        3,
605.3812 +        5,
605.3813 +        2,
605.3814 +        6,
605.3815 +        1,
605.3816 +        7,
605.3817 +        0,
605.3818 +        8,
605.3819 +};
605.3820 +
605.3821 +static const long _vq_lengthlist__8c1_s_p5_0[] = {
605.3822 +         1, 3, 3, 4, 5, 6, 6, 8, 8, 0, 0, 0, 8, 8, 7, 7,
605.3823 +         9, 9, 0, 0, 0, 8, 8, 7, 7, 9, 9, 0, 0, 0, 9,10,
605.3824 +         8, 8, 9, 9, 0, 0, 0,10,10, 8, 8, 9, 9, 0, 0, 0,
605.3825 +        11,10, 8, 8,10,10, 0, 0, 0,11,11, 8, 8,10,10, 0,
605.3826 +         0, 0,12,12, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
605.3827 +        10,
605.3828 +};
605.3829 +
605.3830 +static const static_codebook _8c1_s_p5_0 = {
605.3831 +        2, 81,
605.3832 +        (long *)_vq_lengthlist__8c1_s_p5_0,
605.3833 +        1, -531628032, 1611661312, 4, 0,
605.3834 +        (long *)_vq_quantlist__8c1_s_p5_0,
605.3835 +        0
605.3836 +};
605.3837 +
605.3838 +static const long _vq_quantlist__8c1_s_p6_0[] = {
605.3839 +        8,
605.3840 +        7,
605.3841 +        9,
605.3842 +        6,
605.3843 +        10,
605.3844 +        5,
605.3845 +        11,
605.3846 +        4,
605.3847 +        12,
605.3848 +        3,
605.3849 +        13,
605.3850 +        2,
605.3851 +        14,
605.3852 +        1,
605.3853 +        15,
605.3854 +        0,
605.3855 +        16,
605.3856 +};
605.3857 +
605.3858 +static const long _vq_lengthlist__8c1_s_p6_0[] = {
605.3859 +         1, 3, 3, 5, 5, 8, 8, 8, 8, 9, 9,10,10,11,11,11,
605.3860 +        11, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,11,
605.3861 +        12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.3862 +        11,12,12, 0, 0, 0, 9, 9, 8, 8,10,10,10,10,11,11,
605.3863 +        12,12,12,12, 0, 0, 0, 9, 9, 8, 8,10,10,10,10,11,
605.3864 +        11,12,12,12,12, 0, 0, 0,10,10, 9, 9,10,10,10,10,
605.3865 +        11,11,12,12,13,13, 0, 0, 0,10,10, 9, 9,10,10,10,
605.3866 +        10,11,11,12,12,13,13, 0, 0, 0,11,11, 9, 9,10,10,
605.3867 +        10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10,
605.3868 +        10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
605.3869 +        10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0, 9,
605.3870 +         9,10,10,11,11,12,11,12,12,13,13, 0, 0, 0, 0, 0,
605.3871 +        10,10,11,11,11,11,12,12,13,12,13,13, 0, 0, 0, 0,
605.3872 +         0, 0, 0,11,10,11,11,12,12,13,13,13,13, 0, 0, 0,
605.3873 +         0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, 0,
605.3874 +         0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,13, 0,
605.3875 +         0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14,
605.3876 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14,
605.3877 +        14,
605.3878 +};
605.3879 +
605.3880 +static const static_codebook _8c1_s_p6_0 = {
605.3881 +        2, 289,
605.3882 +        (long *)_vq_lengthlist__8c1_s_p6_0,
605.3883 +        1, -529530880, 1611661312, 5, 0,
605.3884 +        (long *)_vq_quantlist__8c1_s_p6_0,
605.3885 +        0
605.3886 +};
605.3887 +
605.3888 +static const long _vq_quantlist__8c1_s_p7_0[] = {
605.3889 +        1,
605.3890 +        0,
605.3891 +        2,
605.3892 +};
605.3893 +
605.3894 +static const long _vq_lengthlist__8c1_s_p7_0[] = {
605.3895 +         1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10,
605.3896 +         9, 9, 5, 7, 7,10, 9, 9,10, 9, 9, 6,10,10,10,10,
605.3897 +        10,11,10,10, 6, 9, 9,10, 9,10,11,10,10, 6, 9, 9,
605.3898 +        10, 9, 9,11, 9,10, 7,10,10,11,11,11,11,10,10, 6,
605.3899 +         9, 9,10,10,10,11, 9, 9, 6, 9, 9,10,10,10,10, 9,
605.3900 +         9,
605.3901 +};
605.3902 +
605.3903 +static const static_codebook _8c1_s_p7_0 = {
605.3904 +        4, 81,
605.3905 +        (long *)_vq_lengthlist__8c1_s_p7_0,
605.3906 +        1, -529137664, 1618345984, 2, 0,
605.3907 +        (long *)_vq_quantlist__8c1_s_p7_0,
605.3908 +        0
605.3909 +};
605.3910 +
605.3911 +static const long _vq_quantlist__8c1_s_p7_1[] = {
605.3912 +        5,
605.3913 +        4,
605.3914 +        6,
605.3915 +        3,
605.3916 +        7,
605.3917 +        2,
605.3918 +        8,
605.3919 +        1,
605.3920 +        9,
605.3921 +        0,
605.3922 +        10,
605.3923 +};
605.3924 +
605.3925 +static const long _vq_lengthlist__8c1_s_p7_1[] = {
605.3926 +         2, 3, 3, 5, 5, 7, 7, 7, 7, 7, 7,10,10, 9, 7, 7,
605.3927 +         7, 7, 8, 8, 8, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8,
605.3928 +         8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
605.3929 +         7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8,
605.3930 +         8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,
605.3931 +         8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
605.3932 +         8, 8, 8,10,10,10,10,10, 8, 8, 8, 8, 8, 8,10,10,
605.3933 +        10,10,10, 8, 8, 8, 8, 8, 8,
605.3934 +};
605.3935 +
605.3936 +static const static_codebook _8c1_s_p7_1 = {
605.3937 +        2, 121,
605.3938 +        (long *)_vq_lengthlist__8c1_s_p7_1,
605.3939 +        1, -531365888, 1611661312, 4, 0,
605.3940 +        (long *)_vq_quantlist__8c1_s_p7_1,
605.3941 +        0
605.3942 +};
605.3943 +
605.3944 +static const long _vq_quantlist__8c1_s_p8_0[] = {
605.3945 +        6,
605.3946 +        5,
605.3947 +        7,
605.3948 +        4,
605.3949 +        8,
605.3950 +        3,
605.3951 +        9,
605.3952 +        2,
605.3953 +        10,
605.3954 +        1,
605.3955 +        11,
605.3956 +        0,
605.3957 +        12,
605.3958 +};
605.3959 +
605.3960 +static const long _vq_lengthlist__8c1_s_p8_0[] = {
605.3961 +         1, 4, 4, 6, 6, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 5,
605.3962 +         7, 7, 8, 8, 8, 8, 9,10,11,11, 7, 5, 5, 7, 7, 8,
605.3963 +         8, 9, 9,10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.3964 +         9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.3965 +        11, 0,12,12, 9, 9, 9, 9,10, 9,10,11,11,11, 0,13,
605.3966 +        12, 9, 8, 9, 9,10,10,11,11,12,11, 0, 0, 0, 9, 9,
605.3967 +         9, 9,10,10,11,11,12,12, 0, 0, 0,10,10, 9, 9,10,
605.3968 +        10,11,11,12,12, 0, 0, 0,13,13,10,10,11,11,12,11,
605.3969 +        13,12, 0, 0, 0,14,14,10,10,11,10,11,11,12,12, 0,
605.3970 +         0, 0, 0, 0,12,12,11,11,12,12,13,13, 0, 0, 0, 0,
605.3971 +         0,12,12,11,10,12,11,13,12,
605.3972 +};
605.3973 +
605.3974 +static const static_codebook _8c1_s_p8_0 = {
605.3975 +        2, 169,
605.3976 +        (long *)_vq_lengthlist__8c1_s_p8_0,
605.3977 +        1, -526516224, 1616117760, 4, 0,
605.3978 +        (long *)_vq_quantlist__8c1_s_p8_0,
605.3979 +        0
605.3980 +};
605.3981 +
605.3982 +static const long _vq_quantlist__8c1_s_p8_1[] = {
605.3983 +        2,
605.3984 +        1,
605.3985 +        3,
605.3986 +        0,
605.3987 +        4,
605.3988 +};
605.3989 +
605.3990 +static const long _vq_lengthlist__8c1_s_p8_1[] = {
605.3991 +         2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
605.3992 +         6, 6, 5, 5, 6, 6, 6, 5, 5,
605.3993 +};
605.3994 +
605.3995 +static const static_codebook _8c1_s_p8_1 = {
605.3996 +        2, 25,
605.3997 +        (long *)_vq_lengthlist__8c1_s_p8_1,
605.3998 +        1, -533725184, 1611661312, 3, 0,
605.3999 +        (long *)_vq_quantlist__8c1_s_p8_1,
605.4000 +        0
605.4001 +};
605.4002 +
605.4003 +static const long _vq_quantlist__8c1_s_p9_0[] = {
605.4004 +        6,
605.4005 +        5,
605.4006 +        7,
605.4007 +        4,
605.4008 +        8,
605.4009 +        3,
605.4010 +        9,
605.4011 +        2,
605.4012 +        10,
605.4013 +        1,
605.4014 +        11,
605.4015 +        0,
605.4016 +        12,
605.4017 +};
605.4018 +
605.4019 +static const long _vq_lengthlist__8c1_s_p9_0[] = {
605.4020 +         1, 3, 3,10,10,10,10,10,10,10,10,10,10, 5, 6, 6,
605.4021 +        10,10,10,10,10,10,10,10,10,10, 6, 7, 8,10,10,10,
605.4022 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.4023 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.4024 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.4025 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.4026 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.4027 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.4028 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.4029 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.4030 +        10,10,10,10,10, 9, 9, 9, 9,
605.4031 +};
605.4032 +
605.4033 +static const static_codebook _8c1_s_p9_0 = {
605.4034 +        2, 169,
605.4035 +        (long *)_vq_lengthlist__8c1_s_p9_0,
605.4036 +        1, -513964032, 1628680192, 4, 0,
605.4037 +        (long *)_vq_quantlist__8c1_s_p9_0,
605.4038 +        0
605.4039 +};
605.4040 +
605.4041 +static const long _vq_quantlist__8c1_s_p9_1[] = {
605.4042 +        7,
605.4043 +        6,
605.4044 +        8,
605.4045 +        5,
605.4046 +        9,
605.4047 +        4,
605.4048 +        10,
605.4049 +        3,
605.4050 +        11,
605.4051 +        2,
605.4052 +        12,
605.4053 +        1,
605.4054 +        13,
605.4055 +        0,
605.4056 +        14,
605.4057 +};
605.4058 +
605.4059 +static const long _vq_lengthlist__8c1_s_p9_1[] = {
605.4060 +         1, 4, 4, 5, 5, 7, 7, 9, 9,11,11,12,12,13,13, 6,
605.4061 +         5, 5, 6, 6, 9, 9,10,10,12,12,12,13,15,14, 6, 5,
605.4062 +         5, 7, 7, 9, 9,10,10,12,12,12,13,14,13,17, 7, 7,
605.4063 +         8, 8,10,10,11,11,12,13,13,13,13,13,17, 7, 7, 8,
605.4064 +         8,10,10,11,11,13,13,13,13,14,14,17,11,11, 9, 9,
605.4065 +        11,11,12,12,12,13,13,14,15,13,17,12,12, 9, 9,11,
605.4066 +        11,12,12,13,13,13,13,14,16,17,17,17,11,12,12,12,
605.4067 +        13,13,13,14,15,14,15,15,17,17,17,12,12,11,11,13,
605.4068 +        13,14,14,15,14,15,15,17,17,17,15,15,13,13,14,14,
605.4069 +        15,14,15,15,16,15,17,17,17,15,15,13,13,13,14,14,
605.4070 +        15,15,15,15,16,17,17,17,17,16,14,15,14,14,15,14,
605.4071 +        14,15,15,15,17,17,17,17,17,14,14,16,14,15,15,15,
605.4072 +        15,15,15,17,17,17,17,17,17,16,16,15,17,15,15,14,
605.4073 +        17,15,17,16,17,17,17,17,16,15,14,15,15,15,15,15,
605.4074 +        15,
605.4075 +};
605.4076 +
605.4077 +static const static_codebook _8c1_s_p9_1 = {
605.4078 +        2, 225,
605.4079 +        (long *)_vq_lengthlist__8c1_s_p9_1,
605.4080 +        1, -520986624, 1620377600, 4, 0,
605.4081 +        (long *)_vq_quantlist__8c1_s_p9_1,
605.4082 +        0
605.4083 +};
605.4084 +
605.4085 +static const long _vq_quantlist__8c1_s_p9_2[] = {
605.4086 +        10,
605.4087 +        9,
605.4088 +        11,
605.4089 +        8,
605.4090 +        12,
605.4091 +        7,
605.4092 +        13,
605.4093 +        6,
605.4094 +        14,
605.4095 +        5,
605.4096 +        15,
605.4097 +        4,
605.4098 +        16,
605.4099 +        3,
605.4100 +        17,
605.4101 +        2,
605.4102 +        18,
605.4103 +        1,
605.4104 +        19,
605.4105 +        0,
605.4106 +        20,
605.4107 +};
605.4108 +
605.4109 +static const long _vq_lengthlist__8c1_s_p9_2[] = {
605.4110 +         2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9,
605.4111 +         9, 9, 9, 9, 9,11,11,12, 7, 7, 7, 7, 8, 8, 9, 9,
605.4112 +         9, 9,10,10,10,10,10,10,10,10,11,11,11, 7, 7, 7,
605.4113 +         7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,11,
605.4114 +        11,12, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,
605.4115 +        10,10,10,10,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9, 9,
605.4116 +         9,10,10,10,10,10,10,10,10,11,11,11, 8, 8, 8, 8,
605.4117 +         9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,11,11,
605.4118 +        11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,10,
605.4119 +        10,10,10,11,12,11, 9, 9, 8, 9, 9, 9, 9, 9,10,10,
605.4120 +        10,10,10,10,10,10,10,10,11,11,11,11,11, 8, 8, 9,
605.4121 +         9, 9, 9,10,10,10,10,10,10,10,10,10,10,11,12,11,
605.4122 +        12,11, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,
605.4123 +        10,10,11,11,11,11,11, 9, 9, 9, 9,10,10,10,10,10,
605.4124 +        10,10,10,10,10,10,10,12,11,12,11,11, 9, 9, 9,10,
605.4125 +        10,10,10,10,10,10,10,10,10,10,10,10,12,11,11,11,
605.4126 +        11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.4127 +        11,11,11,12,11,11,12,11,10,10,10,10,10,10,10,10,
605.4128 +        10,10,10,10,11,10,11,11,11,11,11,11,11,10,10,10,
605.4129 +        10,10,10,10,10,10,10,10,10,10,10,11,11,12,11,12,
605.4130 +        11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.4131 +        11,11,12,11,12,11,11,11,11,10,10,10,10,10,10,10,
605.4132 +        10,10,10,10,10,11,11,12,11,11,12,11,11,12,10,10,
605.4133 +        11,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
605.4134 +        11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,12,
605.4135 +        12,11,12,11,11,12,12,12,11,11,10,10,10,10,10,10,
605.4136 +        10,10,10,11,12,12,11,12,12,11,12,11,11,11,11,10,
605.4137 +        10,10,10,10,10,10,10,10,10,
605.4138 +};
605.4139 +
605.4140 +static const static_codebook _8c1_s_p9_2 = {
605.4141 +        2, 441,
605.4142 +        (long *)_vq_lengthlist__8c1_s_p9_2,
605.4143 +        1, -529268736, 1611661312, 5, 0,
605.4144 +        (long *)_vq_quantlist__8c1_s_p9_2,
605.4145 +        0
605.4146 +};
605.4147 +
605.4148 +static const long _huff_lengthlist__8c1_s_single[] = {
605.4149 +         4, 6,18, 8,11, 8, 8, 9, 9,10, 4, 4,18, 5, 9, 5,
605.4150 +         6, 7, 8,10,18,18,18,18,17,17,17,17,17,17, 7, 5,
605.4151 +        17, 6,11, 6, 7, 8, 9,12,12, 9,17,12, 8, 8, 9,10,
605.4152 +        10,13, 7, 5,17, 6, 8, 4, 5, 6, 8,10, 6, 5,17, 6,
605.4153 +         8, 5, 4, 5, 7, 9, 7, 7,17, 8, 9, 6, 5, 5, 6, 8,
605.4154 +         8, 8,17, 9,11, 8, 6, 6, 6, 7, 9,10,17,12,12,10,
605.4155 +         9, 7, 7, 8,
605.4156 +};
605.4157 +
605.4158 +static const static_codebook _huff_book__8c1_s_single = {
605.4159 +        2, 100,
605.4160 +        (long *)_huff_lengthlist__8c1_s_single,
605.4161 +        0, 0, 0, 0, 0,
605.4162 +        NULL,
605.4163 +        0
605.4164 +};
605.4165 +
605.4166 +static const long _huff_lengthlist__44c2_s_long[] = {
605.4167 +         6, 6,12,10,10,10, 9,10,12,12, 6, 1,10, 5, 6, 6,
605.4168 +         7, 9,11,14,12, 9, 8,11, 7, 8, 9,11,13,15,10, 5,
605.4169 +        12, 7, 8, 7, 9,12,14,15,10, 6, 7, 8, 5, 6, 7, 9,
605.4170 +        12,14, 9, 6, 8, 7, 6, 6, 7, 9,12,12, 9, 7, 9, 9,
605.4171 +         7, 6, 6, 7,10,10,10, 9,10,11, 8, 7, 6, 6, 8,10,
605.4172 +        12,11,13,13,11,10, 8, 8, 8,10,11,13,15,15,14,13,
605.4173 +        10, 8, 8, 9,
605.4174 +};
605.4175 +
605.4176 +static const static_codebook _huff_book__44c2_s_long = {
605.4177 +        2, 100,
605.4178 +        (long *)_huff_lengthlist__44c2_s_long,
605.4179 +        0, 0, 0, 0, 0,
605.4180 +        NULL,
605.4181 +        0
605.4182 +};
605.4183 +
605.4184 +static const long _vq_quantlist__44c2_s_p1_0[] = {
605.4185 +        1,
605.4186 +        0,
605.4187 +        2,
605.4188 +};
605.4189 +
605.4190 +static const long _vq_lengthlist__44c2_s_p1_0[] = {
605.4191 +         2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0,
605.4192 +         0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4193 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4194 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4195 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4196 +         0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
605.4197 +         0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4198 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4199 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4200 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4201 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0,
605.4202 +         0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4203 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4204 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4205 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4206 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4207 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4208 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4209 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4210 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4211 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4212 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4213 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4214 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4215 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4216 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4217 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4218 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4219 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4220 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4221 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4222 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4223 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4224 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4225 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4226 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4227 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4228 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4229 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4230 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4231 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4232 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4233 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4234 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4235 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4236 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.4237 +         0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
605.4238 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4239 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4240 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4241 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
605.4242 +         0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
605.4243 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4244 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4245 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4246 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0,
605.4247 +         0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
605.4248 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4249 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4250 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4251 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4252 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4253 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4254 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4255 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4256 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4257 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4258 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4259 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4260 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4261 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4262 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4263 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4264 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4265 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4266 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4267 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4268 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4269 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4270 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4271 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4272 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4273 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4274 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4275 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4276 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4277 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4278 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4279 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4280 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4281 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4282 +         0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
605.4283 +         0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4284 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4285 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4286 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4287 +         0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
605.4288 +         0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0,
605.4289 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4290 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4291 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4292 +         0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
605.4293 +         0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.4294 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4295 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4296 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4297 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4298 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4299 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4300 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4301 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4302 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4303 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4304 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4305 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4306 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4307 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4308 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4309 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4310 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4311 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4312 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4313 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4314 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4315 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4316 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4317 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4318 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4319 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4320 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4321 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4322 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4323 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4324 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4325 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4326 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4327 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4329 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4330 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4331 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4332 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4333 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4334 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4335 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4336 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4339 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4342 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4346 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4351 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4356 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4362 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4363 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4364 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4365 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4366 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4367 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4368 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4369 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4370 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4375 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4376 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4377 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4378 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4379 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4380 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4381 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4382 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4383 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4385 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4386 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4387 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4388 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4389 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4390 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4391 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4392 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4393 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4394 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4395 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4396 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4397 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4399 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4400 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4401 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4402 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4403 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4404 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4405 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4406 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4410 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4411 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4412 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4413 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4414 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4415 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4416 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4417 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4418 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4419 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4420 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4421 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4422 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4423 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4424 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4425 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4426 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4427 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4428 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4429 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4430 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4431 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4432 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4433 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4434 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4435 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4436 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4437 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4438 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4439 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4440 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4441 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4442 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4443 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4444 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4445 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4446 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4447 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4448 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4449 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4450 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4451 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4452 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4453 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4454 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4455 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4456 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4457 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4458 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4459 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4460 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4463 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4464 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4465 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4466 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4468 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4469 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4470 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4471 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4472 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4473 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4474 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4475 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4476 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4477 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4478 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4479 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4480 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4481 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4482 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4483 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4484 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4485 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4486 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4487 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4488 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4489 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4490 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4491 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4492 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4493 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4494 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4495 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4496 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4497 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4498 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4499 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4500 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4501 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4502 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4503 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4504 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4505 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4506 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4507 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4508 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4509 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4510 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4511 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4512 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4513 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4514 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4515 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4516 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4517 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4518 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4519 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4520 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4521 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4522 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4523 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4525 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4526 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4527 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4528 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4529 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4530 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4531 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4532 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4533 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4534 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4535 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4536 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4537 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4538 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4539 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4540 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4541 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4542 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4543 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4544 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4545 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4546 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4547 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4548 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4549 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4550 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4551 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4552 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4553 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4554 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4555 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4556 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4557 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4558 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4559 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4560 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4561 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4562 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4563 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4564 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4565 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4566 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4567 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4568 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4569 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4570 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4571 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4572 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4573 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4574 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4575 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4576 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4577 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4578 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4579 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4580 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4581 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4582 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4583 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4584 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4585 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4586 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4587 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4588 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4589 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4590 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4591 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4592 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4593 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4594 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4595 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4596 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4597 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4598 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4599 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4600 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4601 +         0,
605.4602 +};
605.4603 +
605.4604 +static const static_codebook _44c2_s_p1_0 = {
605.4605 +        8, 6561,
605.4606 +        (long *)_vq_lengthlist__44c2_s_p1_0,
605.4607 +        1, -535822336, 1611661312, 2, 0,
605.4608 +        (long *)_vq_quantlist__44c2_s_p1_0,
605.4609 +        0
605.4610 +};
605.4611 +
605.4612 +static const long _vq_quantlist__44c2_s_p2_0[] = {
605.4613 +        2,
605.4614 +        1,
605.4615 +        3,
605.4616 +        0,
605.4617 +        4,
605.4618 +};
605.4619 +
605.4620 +static const long _vq_lengthlist__44c2_s_p2_0[] = {
605.4621 +         1, 4, 4, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0,
605.4622 +         8, 8, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 0, 0, 0, 8,
605.4623 +         8, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0,
605.4624 +         0, 0, 4, 6, 6, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0,
605.4625 +         0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4626 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4627 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4628 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4629 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4630 +         0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,11,11, 0, 0,
605.4631 +         0,11,11, 0, 0, 0,12,11, 0, 0, 0, 0, 0, 0, 0, 7,
605.4632 +         8, 8, 0, 0, 0,10,11, 0, 0, 0,11,11, 0, 0, 0,11,
605.4633 +        12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4634 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4635 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4636 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4637 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4638 +         0, 0, 0, 6, 8, 8, 0, 0, 0,11,11, 0, 0, 0,11,11,
605.4639 +         0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0,
605.4640 +         0, 0,10,11, 0, 0, 0,10,11, 0, 0, 0,11,11, 0, 0,
605.4641 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4642 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4643 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4644 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4645 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4646 +         8, 9, 9, 0, 0, 0,11,12, 0, 0, 0,11,12, 0, 0, 0,
605.4647 +        12,11, 0, 0, 0, 0, 0, 0, 0, 8,10, 9, 0, 0, 0,12,
605.4648 +        11, 0, 0, 0,12,11, 0, 0, 0,11,12, 0, 0, 0, 0, 0,
605.4649 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4650 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4651 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4652 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4653 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4654 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4655 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4656 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4657 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4658 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4659 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4660 +         0,
605.4661 +};
605.4662 +
605.4663 +static const static_codebook _44c2_s_p2_0 = {
605.4664 +        4, 625,
605.4665 +        (long *)_vq_lengthlist__44c2_s_p2_0,
605.4666 +        1, -533725184, 1611661312, 3, 0,
605.4667 +        (long *)_vq_quantlist__44c2_s_p2_0,
605.4668 +        0
605.4669 +};
605.4670 +
605.4671 +static const long _vq_quantlist__44c2_s_p3_0[] = {
605.4672 +        2,
605.4673 +        1,
605.4674 +        3,
605.4675 +        0,
605.4676 +        4,
605.4677 +};
605.4678 +
605.4679 +static const long _vq_lengthlist__44c2_s_p3_0[] = {
605.4680 +         2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4681 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0,
605.4682 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4683 +         0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4684 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9,
605.4685 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4686 +         0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.4687 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4688 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4689 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4690 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4691 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4692 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4693 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4694 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4695 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4696 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4697 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4698 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4699 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4700 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4701 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4702 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4703 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4704 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4705 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4706 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4707 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4708 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4709 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4710 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4711 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4712 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4713 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4714 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4715 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4716 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4717 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4718 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4719 +         0,
605.4720 +};
605.4721 +
605.4722 +static const static_codebook _44c2_s_p3_0 = {
605.4723 +        4, 625,
605.4724 +        (long *)_vq_lengthlist__44c2_s_p3_0,
605.4725 +        1, -533725184, 1611661312, 3, 0,
605.4726 +        (long *)_vq_quantlist__44c2_s_p3_0,
605.4727 +        0
605.4728 +};
605.4729 +
605.4730 +static const long _vq_quantlist__44c2_s_p4_0[] = {
605.4731 +        4,
605.4732 +        3,
605.4733 +        5,
605.4734 +        2,
605.4735 +        6,
605.4736 +        1,
605.4737 +        7,
605.4738 +        0,
605.4739 +        8,
605.4740 +};
605.4741 +
605.4742 +static const long _vq_lengthlist__44c2_s_p4_0[] = {
605.4743 +         1, 3, 3, 6, 6, 0, 0, 0, 0, 0, 6, 6, 6, 6, 0, 0,
605.4744 +         0, 0, 0, 6, 6, 6, 6, 0, 0, 0, 0, 0, 7, 7, 6, 6,
605.4745 +         0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0,
605.4746 +         7, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
605.4747 +         0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.4748 +         0,
605.4749 +};
605.4750 +
605.4751 +static const static_codebook _44c2_s_p4_0 = {
605.4752 +        2, 81,
605.4753 +        (long *)_vq_lengthlist__44c2_s_p4_0,
605.4754 +        1, -531628032, 1611661312, 4, 0,
605.4755 +        (long *)_vq_quantlist__44c2_s_p4_0,
605.4756 +        0
605.4757 +};
605.4758 +
605.4759 +static const long _vq_quantlist__44c2_s_p5_0[] = {
605.4760 +        4,
605.4761 +        3,
605.4762 +        5,
605.4763 +        2,
605.4764 +        6,
605.4765 +        1,
605.4766 +        7,
605.4767 +        0,
605.4768 +        8,
605.4769 +};
605.4770 +
605.4771 +static const long _vq_lengthlist__44c2_s_p5_0[] = {
605.4772 +         1, 3, 3, 6, 6, 7, 7, 9, 9, 0, 7, 7, 7, 7, 7, 7,
605.4773 +         9, 9, 0, 7, 7, 7, 7, 7, 7, 9, 9, 0, 8, 8, 7, 7,
605.4774 +         8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0,
605.4775 +         9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0,
605.4776 +         0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11,
605.4777 +        11,
605.4778 +};
605.4779 +
605.4780 +static const static_codebook _44c2_s_p5_0 = {
605.4781 +        2, 81,
605.4782 +        (long *)_vq_lengthlist__44c2_s_p5_0,
605.4783 +        1, -531628032, 1611661312, 4, 0,
605.4784 +        (long *)_vq_quantlist__44c2_s_p5_0,
605.4785 +        0
605.4786 +};
605.4787 +
605.4788 +static const long _vq_quantlist__44c2_s_p6_0[] = {
605.4789 +        8,
605.4790 +        7,
605.4791 +        9,
605.4792 +        6,
605.4793 +        10,
605.4794 +        5,
605.4795 +        11,
605.4796 +        4,
605.4797 +        12,
605.4798 +        3,
605.4799 +        13,
605.4800 +        2,
605.4801 +        14,
605.4802 +        1,
605.4803 +        15,
605.4804 +        0,
605.4805 +        16,
605.4806 +};
605.4807 +
605.4808 +static const long _vq_lengthlist__44c2_s_p6_0[] = {
605.4809 +         1, 4, 3, 6, 6, 8, 8, 9, 9, 9, 9, 9, 9,10,10,11,
605.4810 +        11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11,
605.4811 +        12,11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,
605.4812 +        11,11,12, 0, 8, 8, 7, 7, 9, 9,10,10, 9, 9,10,10,
605.4813 +        11,11,12,12, 0, 0, 0, 7, 7, 9, 9,10,10,10, 9,10,
605.4814 +        10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,
605.4815 +        11,11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,
605.4816 +        10,11,11,12,12,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
605.4817 +        10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10,
605.4818 +        10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
605.4819 +        10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
605.4820 +         9,10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, 0,
605.4821 +        10,10,10,10,11,11,12,12,13,12,13,13, 0, 0, 0, 0,
605.4822 +         0, 0, 0,10,10,11,11,12,12,13,13,13,13, 0, 0, 0,
605.4823 +         0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, 0,
605.4824 +         0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0,
605.4825 +         0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14,
605.4826 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14,
605.4827 +        14,
605.4828 +};
605.4829 +
605.4830 +static const static_codebook _44c2_s_p6_0 = {
605.4831 +        2, 289,
605.4832 +        (long *)_vq_lengthlist__44c2_s_p6_0,
605.4833 +        1, -529530880, 1611661312, 5, 0,
605.4834 +        (long *)_vq_quantlist__44c2_s_p6_0,
605.4835 +        0
605.4836 +};
605.4837 +
605.4838 +static const long _vq_quantlist__44c2_s_p7_0[] = {
605.4839 +        1,
605.4840 +        0,
605.4841 +        2,
605.4842 +};
605.4843 +
605.4844 +static const long _vq_lengthlist__44c2_s_p7_0[] = {
605.4845 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
605.4846 +         9, 9, 4, 7, 7,10, 9, 9,10, 9, 9, 7,10,10,11,10,
605.4847 +        11,11,10,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
605.4848 +        11,10,11,11,10,10, 7,11,10,11,11,11,12,11,11, 6,
605.4849 +         9, 9,11,10,10,11,11,10, 6, 9, 9,11,10,10,12,10,
605.4850 +        11,
605.4851 +};
605.4852 +
605.4853 +static const static_codebook _44c2_s_p7_0 = {
605.4854 +        4, 81,
605.4855 +        (long *)_vq_lengthlist__44c2_s_p7_0,
605.4856 +        1, -529137664, 1618345984, 2, 0,
605.4857 +        (long *)_vq_quantlist__44c2_s_p7_0,
605.4858 +        0
605.4859 +};
605.4860 +
605.4861 +static const long _vq_quantlist__44c2_s_p7_1[] = {
605.4862 +        5,
605.4863 +        4,
605.4864 +        6,
605.4865 +        3,
605.4866 +        7,
605.4867 +        2,
605.4868 +        8,
605.4869 +        1,
605.4870 +        9,
605.4871 +        0,
605.4872 +        10,
605.4873 +};
605.4874 +
605.4875 +static const long _vq_lengthlist__44c2_s_p7_1[] = {
605.4876 +         2, 3, 4, 6, 6, 7, 7, 7, 7, 7, 7, 9, 7, 7, 6, 6,
605.4877 +         7, 7, 8, 8, 8, 8, 9, 6, 6, 6, 6, 7, 7, 8, 8, 8,
605.4878 +         8,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
605.4879 +         7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8,
605.4880 +         8, 8,10,10,10, 7, 8, 8, 8, 8, 8, 8, 8,10,10,10,
605.4881 +         8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
605.4882 +         8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
605.4883 +        10,10,10, 8, 8, 8, 8, 8, 8,
605.4884 +};
605.4885 +
605.4886 +static const static_codebook _44c2_s_p7_1 = {
605.4887 +        2, 121,
605.4888 +        (long *)_vq_lengthlist__44c2_s_p7_1,
605.4889 +        1, -531365888, 1611661312, 4, 0,
605.4890 +        (long *)_vq_quantlist__44c2_s_p7_1,
605.4891 +        0
605.4892 +};
605.4893 +
605.4894 +static const long _vq_quantlist__44c2_s_p8_0[] = {
605.4895 +        6,
605.4896 +        5,
605.4897 +        7,
605.4898 +        4,
605.4899 +        8,
605.4900 +        3,
605.4901 +        9,
605.4902 +        2,
605.4903 +        10,
605.4904 +        1,
605.4905 +        11,
605.4906 +        0,
605.4907 +        12,
605.4908 +};
605.4909 +
605.4910 +static const long _vq_lengthlist__44c2_s_p8_0[] = {
605.4911 +         1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 6, 5, 5,
605.4912 +         7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 6, 5, 7, 7, 8,
605.4913 +         8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.4914 +        10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.4915 +        11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13,
605.4916 +        13, 9, 9,10,10,10,10,11,11,12,12, 0, 0, 0,10,10,
605.4917 +        10,10,11,11,12,12,12,13, 0, 0, 0,10,10,10,10,11,
605.4918 +        11,12,12,12,12, 0, 0, 0,14,14,10,11,11,11,12,12,
605.4919 +        13,13, 0, 0, 0,14,14,11,10,11,11,13,12,13,13, 0,
605.4920 +         0, 0, 0, 0,12,12,11,12,13,12,14,14, 0, 0, 0, 0,
605.4921 +         0,12,12,12,12,13,12,14,14,
605.4922 +};
605.4923 +
605.4924 +static const static_codebook _44c2_s_p8_0 = {
605.4925 +        2, 169,
605.4926 +        (long *)_vq_lengthlist__44c2_s_p8_0,
605.4927 +        1, -526516224, 1616117760, 4, 0,
605.4928 +        (long *)_vq_quantlist__44c2_s_p8_0,
605.4929 +        0
605.4930 +};
605.4931 +
605.4932 +static const long _vq_quantlist__44c2_s_p8_1[] = {
605.4933 +        2,
605.4934 +        1,
605.4935 +        3,
605.4936 +        0,
605.4937 +        4,
605.4938 +};
605.4939 +
605.4940 +static const long _vq_lengthlist__44c2_s_p8_1[] = {
605.4941 +         2, 4, 4, 5, 4, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6,
605.4942 +         5, 5, 5, 5, 6, 6, 6, 5, 5,
605.4943 +};
605.4944 +
605.4945 +static const static_codebook _44c2_s_p8_1 = {
605.4946 +        2, 25,
605.4947 +        (long *)_vq_lengthlist__44c2_s_p8_1,
605.4948 +        1, -533725184, 1611661312, 3, 0,
605.4949 +        (long *)_vq_quantlist__44c2_s_p8_1,
605.4950 +        0
605.4951 +};
605.4952 +
605.4953 +static const long _vq_quantlist__44c2_s_p9_0[] = {
605.4954 +        6,
605.4955 +        5,
605.4956 +        7,
605.4957 +        4,
605.4958 +        8,
605.4959 +        3,
605.4960 +        9,
605.4961 +        2,
605.4962 +        10,
605.4963 +        1,
605.4964 +        11,
605.4965 +        0,
605.4966 +        12,
605.4967 +};
605.4968 +
605.4969 +static const long _vq_lengthlist__44c2_s_p9_0[] = {
605.4970 +         1, 5, 4,12,12,12,12,12,12,12,12,12,12, 4, 9, 8,
605.4971 +        11,11,11,11,11,11,11,11,11,11, 2, 8, 7,11,11,11,
605.4972 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.4973 +        11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,
605.4974 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.4975 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.4976 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.4977 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.4978 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.4979 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.4980 +        11,11,11,11,11,11,11,11,11,
605.4981 +};
605.4982 +
605.4983 +static const static_codebook _44c2_s_p9_0 = {
605.4984 +        2, 169,
605.4985 +        (long *)_vq_lengthlist__44c2_s_p9_0,
605.4986 +        1, -514541568, 1627103232, 4, 0,
605.4987 +        (long *)_vq_quantlist__44c2_s_p9_0,
605.4988 +        0
605.4989 +};
605.4990 +
605.4991 +static const long _vq_quantlist__44c2_s_p9_1[] = {
605.4992 +        6,
605.4993 +        5,
605.4994 +        7,
605.4995 +        4,
605.4996 +        8,
605.4997 +        3,
605.4998 +        9,
605.4999 +        2,
605.5000 +        10,
605.5001 +        1,
605.5002 +        11,
605.5003 +        0,
605.5004 +        12,
605.5005 +};
605.5006 +
605.5007 +static const long _vq_lengthlist__44c2_s_p9_1[] = {
605.5008 +         1, 4, 4, 6, 6, 7, 6, 8, 8,10, 9,10,10, 6, 5, 5,
605.5009 +         7, 7, 8, 7,10, 9,11,11,12,13, 6, 5, 5, 7, 7, 8,
605.5010 +         8,10,10,11,11,13,13,18, 8, 8, 8, 8, 9, 9,10,10,
605.5011 +        12,12,12,13,18, 8, 8, 8, 8, 9, 9,10,10,12,12,13,
605.5012 +        13,18,11,11, 8, 8,10,10,11,11,12,11,13,12,18,11,
605.5013 +        11, 9, 7,10,10,11,11,11,12,12,13,17,17,17,10,10,
605.5014 +        11,11,12,12,12,10,12,12,17,17,17,11,10,11,10,13,
605.5015 +        12,11,12,12,12,17,17,17,15,14,11,11,12,11,13,10,
605.5016 +        13,12,17,17,17,14,14,12,10,11,11,13,13,13,13,17,
605.5017 +        17,16,17,16,13,13,12,10,13,10,14,13,17,16,17,16,
605.5018 +        17,13,12,12,10,13,11,14,14,
605.5019 +};
605.5020 +
605.5021 +static const static_codebook _44c2_s_p9_1 = {
605.5022 +        2, 169,
605.5023 +        (long *)_vq_lengthlist__44c2_s_p9_1,
605.5024 +        1, -522616832, 1620115456, 4, 0,
605.5025 +        (long *)_vq_quantlist__44c2_s_p9_1,
605.5026 +        0
605.5027 +};
605.5028 +
605.5029 +static const long _vq_quantlist__44c2_s_p9_2[] = {
605.5030 +        8,
605.5031 +        7,
605.5032 +        9,
605.5033 +        6,
605.5034 +        10,
605.5035 +        5,
605.5036 +        11,
605.5037 +        4,
605.5038 +        12,
605.5039 +        3,
605.5040 +        13,
605.5041 +        2,
605.5042 +        14,
605.5043 +        1,
605.5044 +        15,
605.5045 +        0,
605.5046 +        16,
605.5047 +};
605.5048 +
605.5049 +static const long _vq_lengthlist__44c2_s_p9_2[] = {
605.5050 +         2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
605.5051 +         8,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,
605.5052 +         9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9,
605.5053 +         9, 9, 9,10, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
605.5054 +         9, 9, 9, 9,10,10,10, 8, 7, 8, 8, 8, 8, 9, 9, 9,
605.5055 +         9, 9, 9, 9, 9,10,11,11, 8, 8, 8, 8, 9, 9, 9, 9,
605.5056 +         9, 9,10, 9, 9, 9,10,11,10, 8, 8, 8, 8, 9, 9, 9,
605.5057 +         9, 9, 9, 9,10,10,10,10,11,10, 8, 8, 9, 9, 9, 9,
605.5058 +         9, 9,10, 9, 9,10, 9,10,11,10,11,11,11, 8, 8, 9,
605.5059 +         9, 9, 9, 9, 9, 9, 9,10,10,11,11,11,11,11, 9, 9,
605.5060 +         9, 9, 9, 9,10, 9, 9, 9,10,10,11,11,11,11,11, 9,
605.5061 +         9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,11,11,11,11,11,
605.5062 +         9, 9, 9, 9,10,10, 9, 9, 9,10,10,10,11,11,11,11,
605.5063 +        11,11,11, 9, 9, 9,10, 9, 9,10,10,10,10,11,11,10,
605.5064 +        11,11,11,11,10, 9,10,10, 9, 9, 9, 9,10,10,11,10,
605.5065 +        11,11,11,11,11, 9, 9, 9, 9,10, 9,10,10,10,10,11,
605.5066 +        10,11,11,11,11,11,10,10, 9, 9,10, 9,10,10,10,10,
605.5067 +        10,10,10,11,11,11,11,11,11, 9, 9,10, 9,10, 9,10,
605.5068 +        10,
605.5069 +};
605.5070 +
605.5071 +static const static_codebook _44c2_s_p9_2 = {
605.5072 +        2, 289,
605.5073 +        (long *)_vq_lengthlist__44c2_s_p9_2,
605.5074 +        1, -529530880, 1611661312, 5, 0,
605.5075 +        (long *)_vq_quantlist__44c2_s_p9_2,
605.5076 +        0
605.5077 +};
605.5078 +
605.5079 +static const long _huff_lengthlist__44c2_s_short[] = {
605.5080 +        11, 9,13,12,12,11,12,12,13,15, 8, 2,11, 4, 8, 5,
605.5081 +         7,10,12,15,13, 7,10, 9, 8, 8,10,13,17,17,11, 4,
605.5082 +        12, 5, 9, 5, 8,11,14,16,12, 6, 8, 7, 6, 6, 8,11,
605.5083 +        13,16,11, 4, 9, 5, 6, 4, 6,10,13,16,11, 6,11, 7,
605.5084 +         7, 6, 7,10,13,15,13, 9,12, 9, 8, 6, 8,10,12,14,
605.5085 +        14,10,10, 8, 6, 5, 6, 9,11,13,15,11,11, 9, 6, 5,
605.5086 +         6, 8, 9,12,
605.5087 +};
605.5088 +
605.5089 +static const static_codebook _huff_book__44c2_s_short = {
605.5090 +        2, 100,
605.5091 +        (long *)_huff_lengthlist__44c2_s_short,
605.5092 +        0, 0, 0, 0, 0,
605.5093 +        NULL,
605.5094 +        0
605.5095 +};
605.5096 +
605.5097 +static const long _huff_lengthlist__44c3_s_long[] = {
605.5098 +         5, 6,11,11,11,11,10,10,12,11, 5, 2,11, 5, 6, 6,
605.5099 +         7, 9,11,13,13,10, 7,11, 6, 7, 8, 9,10,12,11, 5,
605.5100 +        11, 6, 8, 7, 9,11,14,15,11, 6, 6, 8, 4, 5, 7, 8,
605.5101 +        10,13,10, 5, 7, 7, 5, 5, 6, 8,10,11,10, 7, 7, 8,
605.5102 +         6, 5, 5, 7, 9, 9,11, 8, 8,11, 8, 7, 6, 6, 7, 9,
605.5103 +        12,11,10,13, 9, 9, 7, 7, 7, 9,11,13,12,15,12,11,
605.5104 +         9, 8, 8, 8,
605.5105 +};
605.5106 +
605.5107 +static const static_codebook _huff_book__44c3_s_long = {
605.5108 +        2, 100,
605.5109 +        (long *)_huff_lengthlist__44c3_s_long,
605.5110 +        0, 0, 0, 0, 0,
605.5111 +        NULL,
605.5112 +        0
605.5113 +};
605.5114 +
605.5115 +static const long _vq_quantlist__44c3_s_p1_0[] = {
605.5116 +        1,
605.5117 +        0,
605.5118 +        2,
605.5119 +};
605.5120 +
605.5121 +static const long _vq_lengthlist__44c3_s_p1_0[] = {
605.5122 +         2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0,
605.5123 +         0, 0, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5124 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5125 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5126 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5127 +         0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
605.5128 +         0, 0, 0, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5129 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5130 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5131 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5132 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0,
605.5133 +         0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5134 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5135 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5136 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5137 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5138 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5139 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5140 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5141 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5142 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5143 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5144 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5145 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5146 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5147 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5148 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5149 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5150 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5151 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5152 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5153 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5154 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5155 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5156 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5157 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5158 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5159 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5160 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5161 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5162 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5163 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5164 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5165 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5166 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5167 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.5168 +         0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
605.5169 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5170 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5171 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5172 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
605.5173 +         0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
605.5174 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5175 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5176 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5177 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0,
605.5178 +         0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
605.5179 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5180 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5181 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5182 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5183 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5184 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5185 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5186 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5187 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5188 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5189 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5190 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5191 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5192 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5193 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5194 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5195 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5196 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5197 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5198 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5199 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5200 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5201 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5202 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5203 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5204 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5205 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5206 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5207 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5208 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5209 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5210 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5211 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5212 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5213 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
605.5214 +         0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5215 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5216 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5217 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5218 +         0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
605.5219 +         0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0,
605.5220 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5221 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5222 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5223 +         0, 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
605.5224 +         0, 0, 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 0,
605.5225 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5226 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5227 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5228 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5229 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5230 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5231 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5232 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5233 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5234 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5235 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5236 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5237 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5238 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5239 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5240 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5241 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5242 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5243 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5244 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5245 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5246 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5247 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5248 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5249 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5250 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5251 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5252 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5253 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5254 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5255 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5256 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5257 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5258 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5259 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5260 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5261 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5262 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5263 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5264 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5265 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5266 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5267 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5268 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5269 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5270 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5271 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5272 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5273 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5274 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5275 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5276 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5277 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5278 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5279 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5280 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5281 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5282 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5283 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5284 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5285 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5286 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5287 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5288 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5289 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5290 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5291 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5292 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5293 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5294 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5295 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5296 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5297 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5298 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5299 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5300 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5301 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5302 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5303 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5304 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5305 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5306 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5307 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5308 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5309 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5310 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5311 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5312 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5313 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5314 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5315 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5316 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5317 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5318 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5319 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5320 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5321 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5322 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5323 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5324 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5325 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5326 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5327 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5329 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5330 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5331 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5332 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5333 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5334 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5335 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5336 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5339 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5342 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5346 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5351 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5356 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5362 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5363 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5364 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5365 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5366 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5367 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5368 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5369 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5370 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5375 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5376 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5377 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5378 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5379 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5380 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5381 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5382 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5383 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5385 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5386 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5387 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5388 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5389 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5390 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5391 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5392 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5393 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5394 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5395 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5396 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5397 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5399 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5400 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5401 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5402 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5403 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5404 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5405 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5406 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5410 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5411 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5412 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5413 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5414 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5415 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5416 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5417 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5418 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5419 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5420 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5421 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5422 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5423 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5424 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5425 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5426 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5427 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5428 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5429 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5430 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5431 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5432 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5433 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5434 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5435 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5436 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5437 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5438 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5439 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5440 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5441 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5442 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5443 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5444 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5445 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5446 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5447 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5448 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5449 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5450 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5451 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5452 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5453 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5454 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5455 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5456 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5457 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5458 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5459 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5460 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5463 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5464 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5465 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5466 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5468 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5469 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5470 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5471 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5472 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5473 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5474 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5475 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5476 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5477 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5478 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5479 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5480 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5481 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5482 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5483 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5484 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5485 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5486 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5487 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5488 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5489 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5490 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5491 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5492 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5493 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5494 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5495 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5496 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5497 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5498 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5499 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5500 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5501 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5502 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5503 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5504 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5505 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5506 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5507 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5508 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5509 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5510 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5511 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5512 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5513 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5514 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5515 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5516 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5517 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5518 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5519 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5520 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5521 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5522 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5523 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5525 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5526 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5527 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5528 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5529 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5530 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5531 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5532 +         0,
605.5533 +};
605.5534 +
605.5535 +static const static_codebook _44c3_s_p1_0 = {
605.5536 +        8, 6561,
605.5537 +        (long *)_vq_lengthlist__44c3_s_p1_0,
605.5538 +        1, -535822336, 1611661312, 2, 0,
605.5539 +        (long *)_vq_quantlist__44c3_s_p1_0,
605.5540 +        0
605.5541 +};
605.5542 +
605.5543 +static const long _vq_quantlist__44c3_s_p2_0[] = {
605.5544 +        2,
605.5545 +        1,
605.5546 +        3,
605.5547 +        0,
605.5548 +        4,
605.5549 +};
605.5550 +
605.5551 +static const long _vq_lengthlist__44c3_s_p2_0[] = {
605.5552 +         2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0,
605.5553 +         7, 8, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 7,
605.5554 +         7, 0, 0, 0, 7, 7, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
605.5555 +         0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0,
605.5556 +         0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5557 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5558 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5559 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5560 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5561 +         0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0,
605.5562 +         0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5,
605.5563 +         7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9,
605.5564 +         9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5565 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5566 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5567 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5568 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5569 +         0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7,
605.5570 +         0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0,
605.5571 +         0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0,
605.5572 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5573 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5574 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5575 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5576 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5577 +         8,10,10, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0,
605.5578 +        10,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0, 9,
605.5579 +         9, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
605.5580 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5581 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5582 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5583 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5584 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5585 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5586 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5587 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5588 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5589 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5590 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5591 +         0,
605.5592 +};
605.5593 +
605.5594 +static const static_codebook _44c3_s_p2_0 = {
605.5595 +        4, 625,
605.5596 +        (long *)_vq_lengthlist__44c3_s_p2_0,
605.5597 +        1, -533725184, 1611661312, 3, 0,
605.5598 +        (long *)_vq_quantlist__44c3_s_p2_0,
605.5599 +        0
605.5600 +};
605.5601 +
605.5602 +static const long _vq_quantlist__44c3_s_p3_0[] = {
605.5603 +        2,
605.5604 +        1,
605.5605 +        3,
605.5606 +        0,
605.5607 +        4,
605.5608 +};
605.5609 +
605.5610 +static const long _vq_lengthlist__44c3_s_p3_0[] = {
605.5611 +         2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5612 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0,
605.5613 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5614 +         0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5615 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9,
605.5616 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5617 +         0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.5618 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5619 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5620 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5621 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5622 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5623 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5624 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5625 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5626 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5627 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5628 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5629 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5630 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5631 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5632 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5633 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5634 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5635 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5636 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5637 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5638 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5639 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5640 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5641 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5642 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5643 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5644 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5645 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5646 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5647 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5648 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5649 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5650 +         0,
605.5651 +};
605.5652 +
605.5653 +static const static_codebook _44c3_s_p3_0 = {
605.5654 +        4, 625,
605.5655 +        (long *)_vq_lengthlist__44c3_s_p3_0,
605.5656 +        1, -533725184, 1611661312, 3, 0,
605.5657 +        (long *)_vq_quantlist__44c3_s_p3_0,
605.5658 +        0
605.5659 +};
605.5660 +
605.5661 +static const long _vq_quantlist__44c3_s_p4_0[] = {
605.5662 +        4,
605.5663 +        3,
605.5664 +        5,
605.5665 +        2,
605.5666 +        6,
605.5667 +        1,
605.5668 +        7,
605.5669 +        0,
605.5670 +        8,
605.5671 +};
605.5672 +
605.5673 +static const long _vq_lengthlist__44c3_s_p4_0[] = {
605.5674 +         2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0,
605.5675 +         0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6,
605.5676 +         0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0,
605.5677 +         7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0,
605.5678 +         0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.5679 +         0,
605.5680 +};
605.5681 +
605.5682 +static const static_codebook _44c3_s_p4_0 = {
605.5683 +        2, 81,
605.5684 +        (long *)_vq_lengthlist__44c3_s_p4_0,
605.5685 +        1, -531628032, 1611661312, 4, 0,
605.5686 +        (long *)_vq_quantlist__44c3_s_p4_0,
605.5687 +        0
605.5688 +};
605.5689 +
605.5690 +static const long _vq_quantlist__44c3_s_p5_0[] = {
605.5691 +        4,
605.5692 +        3,
605.5693 +        5,
605.5694 +        2,
605.5695 +        6,
605.5696 +        1,
605.5697 +        7,
605.5698 +        0,
605.5699 +        8,
605.5700 +};
605.5701 +
605.5702 +static const long _vq_lengthlist__44c3_s_p5_0[] = {
605.5703 +         1, 3, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 7, 8,
605.5704 +         9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8,
605.5705 +         8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0,
605.5706 +         9, 9, 9, 9,10,10, 0, 0, 0, 9, 9, 9, 9,10,10, 0,
605.5707 +         0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0,10,10,11,
605.5708 +        11,
605.5709 +};
605.5710 +
605.5711 +static const static_codebook _44c3_s_p5_0 = {
605.5712 +        2, 81,
605.5713 +        (long *)_vq_lengthlist__44c3_s_p5_0,
605.5714 +        1, -531628032, 1611661312, 4, 0,
605.5715 +        (long *)_vq_quantlist__44c3_s_p5_0,
605.5716 +        0
605.5717 +};
605.5718 +
605.5719 +static const long _vq_quantlist__44c3_s_p6_0[] = {
605.5720 +        8,
605.5721 +        7,
605.5722 +        9,
605.5723 +        6,
605.5724 +        10,
605.5725 +        5,
605.5726 +        11,
605.5727 +        4,
605.5728 +        12,
605.5729 +        3,
605.5730 +        13,
605.5731 +        2,
605.5732 +        14,
605.5733 +        1,
605.5734 +        15,
605.5735 +        0,
605.5736 +        16,
605.5737 +};
605.5738 +
605.5739 +static const long _vq_lengthlist__44c3_s_p6_0[] = {
605.5740 +         2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
605.5741 +        10, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10,
605.5742 +        11,11, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,
605.5743 +        10,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
605.5744 +        11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
605.5745 +        10,11,11,11,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.5746 +        10,10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9,
605.5747 +         9,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
605.5748 +        10,10,11,10,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,10,
605.5749 +        10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 8,
605.5750 +         9, 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8,
605.5751 +         8, 9, 9,10,10,11,11,12,11,12,12, 0, 0, 0, 0, 0,
605.5752 +         9,10,10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0,
605.5753 +         0, 0, 0,10,10,10,10,11,11,12,12,13,13, 0, 0, 0,
605.5754 +         0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0, 0,
605.5755 +         0, 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0,
605.5756 +         0, 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,13,
605.5757 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,
605.5758 +        13,
605.5759 +};
605.5760 +
605.5761 +static const static_codebook _44c3_s_p6_0 = {
605.5762 +        2, 289,
605.5763 +        (long *)_vq_lengthlist__44c3_s_p6_0,
605.5764 +        1, -529530880, 1611661312, 5, 0,
605.5765 +        (long *)_vq_quantlist__44c3_s_p6_0,
605.5766 +        0
605.5767 +};
605.5768 +
605.5769 +static const long _vq_quantlist__44c3_s_p7_0[] = {
605.5770 +        1,
605.5771 +        0,
605.5772 +        2,
605.5773 +};
605.5774 +
605.5775 +static const long _vq_lengthlist__44c3_s_p7_0[] = {
605.5776 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
605.5777 +         9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11,
605.5778 +        10,12,11,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
605.5779 +        11,10,10,11,10,10, 7,11,11,11,11,11,12,11,11, 6,
605.5780 +         9, 9,11,10,10,11,10,10, 6, 9, 9,11,10,10,11,10,
605.5781 +        10,
605.5782 +};
605.5783 +
605.5784 +static const static_codebook _44c3_s_p7_0 = {
605.5785 +        4, 81,
605.5786 +        (long *)_vq_lengthlist__44c3_s_p7_0,
605.5787 +        1, -529137664, 1618345984, 2, 0,
605.5788 +        (long *)_vq_quantlist__44c3_s_p7_0,
605.5789 +        0
605.5790 +};
605.5791 +
605.5792 +static const long _vq_quantlist__44c3_s_p7_1[] = {
605.5793 +        5,
605.5794 +        4,
605.5795 +        6,
605.5796 +        3,
605.5797 +        7,
605.5798 +        2,
605.5799 +        8,
605.5800 +        1,
605.5801 +        9,
605.5802 +        0,
605.5803 +        10,
605.5804 +};
605.5805 +
605.5806 +static const long _vq_lengthlist__44c3_s_p7_1[] = {
605.5807 +         2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6,
605.5808 +         7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8,
605.5809 +         8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
605.5810 +         7, 8, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8,
605.5811 +         8, 8,10,10,10, 7, 8, 8, 8, 8, 8, 8, 8,10,10,10,
605.5812 +         8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
605.5813 +         8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 9, 8,10,10,
605.5814 +        10,10,10, 8, 8, 8, 8, 8, 8,
605.5815 +};
605.5816 +
605.5817 +static const static_codebook _44c3_s_p7_1 = {
605.5818 +        2, 121,
605.5819 +        (long *)_vq_lengthlist__44c3_s_p7_1,
605.5820 +        1, -531365888, 1611661312, 4, 0,
605.5821 +        (long *)_vq_quantlist__44c3_s_p7_1,
605.5822 +        0
605.5823 +};
605.5824 +
605.5825 +static const long _vq_quantlist__44c3_s_p8_0[] = {
605.5826 +        6,
605.5827 +        5,
605.5828 +        7,
605.5829 +        4,
605.5830 +        8,
605.5831 +        3,
605.5832 +        9,
605.5833 +        2,
605.5834 +        10,
605.5835 +        1,
605.5836 +        11,
605.5837 +        0,
605.5838 +        12,
605.5839 +};
605.5840 +
605.5841 +static const long _vq_lengthlist__44c3_s_p8_0[] = {
605.5842 +         1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5,
605.5843 +         7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 5, 7, 7, 8,
605.5844 +         8, 8, 8, 9, 9,11,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.5845 +        10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.5846 +        11, 0,12,12, 9, 9,10,10,10,10,11,11,11,12, 0,13,
605.5847 +        13, 9, 9,10,10,10,10,11,11,12,12, 0, 0, 0,10,10,
605.5848 +        10,10,11,11,12,12,12,12, 0, 0, 0,10,10,10,10,11,
605.5849 +        11,12,12,12,12, 0, 0, 0,14,14,11,11,11,11,12,12,
605.5850 +        13,13, 0, 0, 0,14,14,11,11,11,11,12,12,13,13, 0,
605.5851 +         0, 0, 0, 0,12,12,12,12,13,13,14,13, 0, 0, 0, 0,
605.5852 +         0,13,13,12,12,13,12,14,13,
605.5853 +};
605.5854 +
605.5855 +static const static_codebook _44c3_s_p8_0 = {
605.5856 +        2, 169,
605.5857 +        (long *)_vq_lengthlist__44c3_s_p8_0,
605.5858 +        1, -526516224, 1616117760, 4, 0,
605.5859 +        (long *)_vq_quantlist__44c3_s_p8_0,
605.5860 +        0
605.5861 +};
605.5862 +
605.5863 +static const long _vq_quantlist__44c3_s_p8_1[] = {
605.5864 +        2,
605.5865 +        1,
605.5866 +        3,
605.5867 +        0,
605.5868 +        4,
605.5869 +};
605.5870 +
605.5871 +static const long _vq_lengthlist__44c3_s_p8_1[] = {
605.5872 +         2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, 6,
605.5873 +         5, 5, 5, 5, 6, 6, 6, 5, 5,
605.5874 +};
605.5875 +
605.5876 +static const static_codebook _44c3_s_p8_1 = {
605.5877 +        2, 25,
605.5878 +        (long *)_vq_lengthlist__44c3_s_p8_1,
605.5879 +        1, -533725184, 1611661312, 3, 0,
605.5880 +        (long *)_vq_quantlist__44c3_s_p8_1,
605.5881 +        0
605.5882 +};
605.5883 +
605.5884 +static const long _vq_quantlist__44c3_s_p9_0[] = {
605.5885 +        6,
605.5886 +        5,
605.5887 +        7,
605.5888 +        4,
605.5889 +        8,
605.5890 +        3,
605.5891 +        9,
605.5892 +        2,
605.5893 +        10,
605.5894 +        1,
605.5895 +        11,
605.5896 +        0,
605.5897 +        12,
605.5898 +};
605.5899 +
605.5900 +static const long _vq_lengthlist__44c3_s_p9_0[] = {
605.5901 +         1, 4, 4,12,12,12,12,12,12,12,12,12,12, 4, 9, 8,
605.5902 +        12,12,12,12,12,12,12,12,12,12, 2, 9, 7,12,12,12,
605.5903 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.5904 +        12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,
605.5905 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.5906 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.5907 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.5908 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.5909 +        12,12,12,12,12,12,12,12,12,12,11,11,11,11,11,11,
605.5910 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.5911 +        11,11,11,11,11,11,11,11,11,
605.5912 +};
605.5913 +
605.5914 +static const static_codebook _44c3_s_p9_0 = {
605.5915 +        2, 169,
605.5916 +        (long *)_vq_lengthlist__44c3_s_p9_0,
605.5917 +        1, -514332672, 1627381760, 4, 0,
605.5918 +        (long *)_vq_quantlist__44c3_s_p9_0,
605.5919 +        0
605.5920 +};
605.5921 +
605.5922 +static const long _vq_quantlist__44c3_s_p9_1[] = {
605.5923 +        7,
605.5924 +        6,
605.5925 +        8,
605.5926 +        5,
605.5927 +        9,
605.5928 +        4,
605.5929 +        10,
605.5930 +        3,
605.5931 +        11,
605.5932 +        2,
605.5933 +        12,
605.5934 +        1,
605.5935 +        13,
605.5936 +        0,
605.5937 +        14,
605.5938 +};
605.5939 +
605.5940 +static const long _vq_lengthlist__44c3_s_p9_1[] = {
605.5941 +         1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 9,10,10,10,10, 6,
605.5942 +         5, 5, 7, 7, 8, 8,10, 8,11,10,12,12,13,13, 6, 5,
605.5943 +         5, 7, 7, 8, 8,10, 9,11,11,12,12,13,12,18, 8, 8,
605.5944 +         8, 8, 9, 9,10, 9,11,10,12,12,13,13,18, 8, 8, 8,
605.5945 +         8, 9, 9,10,10,11,11,13,12,14,13,18,11,11, 9, 9,
605.5946 +        10,10,11,11,11,12,13,12,13,14,18,11,11, 9, 8,11,
605.5947 +        10,11,11,11,11,12,12,14,13,18,18,18,10,11,10,11,
605.5948 +        12,12,12,12,13,12,14,13,18,18,18,10,11,11, 9,12,
605.5949 +        11,12,12,12,13,13,13,18,18,17,14,14,11,11,12,12,
605.5950 +        13,12,14,12,14,13,18,18,18,14,14,11,10,12, 9,12,
605.5951 +        13,13,13,13,13,18,18,17,16,18,13,13,12,12,13,11,
605.5952 +        14,12,14,14,17,18,18,17,18,13,12,13,10,12,11,14,
605.5953 +        14,14,14,17,18,18,18,18,15,16,12,12,13,10,14,12,
605.5954 +        14,15,18,18,18,16,17,16,14,12,11,13,10,13,13,14,
605.5955 +        15,
605.5956 +};
605.5957 +
605.5958 +static const static_codebook _44c3_s_p9_1 = {
605.5959 +        2, 225,
605.5960 +        (long *)_vq_lengthlist__44c3_s_p9_1,
605.5961 +        1, -522338304, 1620115456, 4, 0,
605.5962 +        (long *)_vq_quantlist__44c3_s_p9_1,
605.5963 +        0
605.5964 +};
605.5965 +
605.5966 +static const long _vq_quantlist__44c3_s_p9_2[] = {
605.5967 +        8,
605.5968 +        7,
605.5969 +        9,
605.5970 +        6,
605.5971 +        10,
605.5972 +        5,
605.5973 +        11,
605.5974 +        4,
605.5975 +        12,
605.5976 +        3,
605.5977 +        13,
605.5978 +        2,
605.5979 +        14,
605.5980 +        1,
605.5981 +        15,
605.5982 +        0,
605.5983 +        16,
605.5984 +};
605.5985 +
605.5986 +static const long _vq_lengthlist__44c3_s_p9_2[] = {
605.5987 +         2, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
605.5988 +         8,10, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 8, 9, 9, 9,
605.5989 +         9, 9,10, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9,
605.5990 +         9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,
605.5991 +         9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 9, 9, 9, 9,
605.5992 +         9, 9, 9, 9, 9,11,11,11, 8, 8, 8, 8, 9, 9, 9, 9,
605.5993 +         9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9,
605.5994 +         9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 9, 9, 9, 9, 9,
605.5995 +         9, 9, 9, 9, 9, 9,10, 9,10,10,10,11,11, 9, 9, 9,
605.5996 +         9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,11,11,11, 9, 9,
605.5997 +         9, 9, 9, 9,10,10, 9, 9,10, 9,11,10,11,11,11, 9,
605.5998 +         9, 9, 9, 9, 9, 9, 9,10,10,10, 9,11,11,11,11,11,
605.5999 +         9, 9, 9, 9,10,10, 9, 9, 9, 9,10, 9,11,11,11,11,
605.6000 +        11,11,11, 9, 9, 9, 9, 9, 9,10,10,10,10,11,11,11,
605.6001 +        11,11,11,11,10, 9,10,10, 9,10, 9, 9,10, 9,11,10,
605.6002 +        10,11,11,11,11, 9,10, 9, 9, 9, 9,10,10,10,10,11,
605.6003 +        11,11,11,11,11,10,10,10, 9, 9,10, 9,10, 9,10,10,
605.6004 +        10,10,11,11,11,11,11,11,11, 9, 9, 9, 9, 9,10,10,
605.6005 +        10,
605.6006 +};
605.6007 +
605.6008 +static const static_codebook _44c3_s_p9_2 = {
605.6009 +        2, 289,
605.6010 +        (long *)_vq_lengthlist__44c3_s_p9_2,
605.6011 +        1, -529530880, 1611661312, 5, 0,
605.6012 +        (long *)_vq_quantlist__44c3_s_p9_2,
605.6013 +        0
605.6014 +};
605.6015 +
605.6016 +static const long _huff_lengthlist__44c3_s_short[] = {
605.6017 +        10, 9,13,11,14,10,12,13,13,14, 7, 2,12, 5,10, 5,
605.6018 +         7,10,12,14,12, 6, 9, 8, 7, 7, 9,11,13,16,10, 4,
605.6019 +        12, 5,10, 6, 8,12,14,16,12, 6, 8, 7, 6, 5, 7,11,
605.6020 +        12,16,10, 4, 8, 5, 6, 4, 6, 9,13,16,10, 6,10, 7,
605.6021 +         7, 6, 7, 9,13,15,12, 9,11, 9, 8, 6, 7,10,12,14,
605.6022 +        14,11,10, 9, 6, 5, 6, 9,11,13,15,13,11,10, 6, 5,
605.6023 +         6, 8, 9,11,
605.6024 +};
605.6025 +
605.6026 +static const static_codebook _huff_book__44c3_s_short = {
605.6027 +        2, 100,
605.6028 +        (long *)_huff_lengthlist__44c3_s_short,
605.6029 +        0, 0, 0, 0, 0,
605.6030 +        NULL,
605.6031 +        0
605.6032 +};
605.6033 +
605.6034 +static const long _huff_lengthlist__44c4_s_long[] = {
605.6035 +         4, 7,11,11,11,11,10,11,12,11, 5, 2,11, 5, 6, 6,
605.6036 +         7, 9,11,12,11, 9, 6,10, 6, 7, 8, 9,10,11,11, 5,
605.6037 +        11, 7, 8, 8, 9,11,13,14,11, 6, 5, 8, 4, 5, 7, 8,
605.6038 +        10,11,10, 6, 7, 7, 5, 5, 6, 8, 9,11,10, 7, 8, 9,
605.6039 +         6, 6, 6, 7, 8, 9,11, 9, 9,11, 7, 7, 6, 6, 7, 9,
605.6040 +        12,12,10,13, 9, 8, 7, 7, 7, 8,11,13,11,14,11,10,
605.6041 +         9, 8, 7, 7,
605.6042 +};
605.6043 +
605.6044 +static const static_codebook _huff_book__44c4_s_long = {
605.6045 +        2, 100,
605.6046 +        (long *)_huff_lengthlist__44c4_s_long,
605.6047 +        0, 0, 0, 0, 0,
605.6048 +        NULL,
605.6049 +        0
605.6050 +};
605.6051 +
605.6052 +static const long _vq_quantlist__44c4_s_p1_0[] = {
605.6053 +        1,
605.6054 +        0,
605.6055 +        2,
605.6056 +};
605.6057 +
605.6058 +static const long _vq_lengthlist__44c4_s_p1_0[] = {
605.6059 +         2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0,
605.6060 +         0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6061 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6062 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6063 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6064 +         0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
605.6065 +         0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6066 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6067 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6068 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6069 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0,
605.6070 +         0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6071 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6072 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6073 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6074 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6075 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6076 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6077 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6078 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6079 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6080 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6081 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6082 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6083 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6084 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6085 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6086 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6087 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6088 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6089 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6090 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6091 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6092 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6093 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6094 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6095 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6096 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6097 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6098 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6099 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6100 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6101 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6102 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6103 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6104 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.6105 +         0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
605.6106 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6107 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6108 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6109 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
605.6110 +         0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
605.6111 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6112 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6113 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6114 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0,
605.6115 +         0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
605.6116 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6117 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6118 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6119 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6120 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6121 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6122 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6123 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6124 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6125 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6126 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6127 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6128 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6129 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6130 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6131 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6132 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6133 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6134 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6135 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6136 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6137 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6138 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6139 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6140 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6141 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6142 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6143 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6144 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6145 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6146 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6147 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6148 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6149 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6150 +         0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
605.6151 +         0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6152 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6153 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6154 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6155 +         0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
605.6156 +         0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0,
605.6157 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6158 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6159 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6160 +         0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
605.6161 +         0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.6162 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6163 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6164 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6165 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6166 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6167 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6168 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6169 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6170 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6171 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6172 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6173 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6174 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6175 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6176 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6177 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6178 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6179 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6180 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6181 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6182 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6183 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6184 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6185 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6186 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6187 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6188 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6189 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6190 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6191 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6192 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6193 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6194 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6195 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6196 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6197 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6198 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6199 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6200 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6201 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6202 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6203 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6204 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6205 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6206 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6207 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6208 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6209 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6210 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6211 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6212 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6213 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6214 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6215 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6216 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6217 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6218 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6219 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6220 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6221 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6222 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6223 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6224 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6225 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6226 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6227 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6228 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6229 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6230 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6231 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6232 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6233 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6234 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6235 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6236 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6237 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6238 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6239 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6240 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6241 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6242 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6243 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6244 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6245 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6246 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6247 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6248 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6249 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6250 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6251 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6252 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6253 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6254 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6255 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6256 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6257 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6258 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6259 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6260 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6261 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6262 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6263 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6264 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6265 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6266 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6267 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6268 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6269 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6270 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6271 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6272 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6273 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6274 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6275 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6276 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6277 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6278 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6279 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6280 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6281 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6282 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6283 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6284 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6285 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6286 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6287 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6288 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6289 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6290 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6291 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6292 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6293 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6294 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6295 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6296 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6297 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6298 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6299 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6300 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6301 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6302 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6303 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6304 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6305 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6306 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6307 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6308 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6309 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6310 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6311 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6312 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6313 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6314 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6315 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6316 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6317 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6318 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6319 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6320 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6321 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6322 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6323 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6324 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6325 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6326 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6327 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6329 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6330 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6331 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6332 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6333 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6334 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6335 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6336 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6339 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6342 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6346 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6351 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6356 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6362 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6363 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6364 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6365 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6366 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6367 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6368 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6369 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6370 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6375 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6376 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6377 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6378 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6379 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6380 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6381 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6382 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6383 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6385 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6386 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6387 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6388 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6389 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6390 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6391 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6392 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6393 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6394 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6395 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6396 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6397 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6399 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6400 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6401 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6402 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6403 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6404 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6405 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6406 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6410 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6411 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6412 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6413 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6414 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6415 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6416 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6417 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6418 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6419 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6420 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6421 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6422 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6423 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6424 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6425 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6426 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6427 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6428 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6429 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6430 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6431 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6432 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6433 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6434 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6435 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6436 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6437 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6438 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6439 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6440 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6441 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6442 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6443 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6444 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6445 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6446 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6447 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6448 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6449 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6450 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6451 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6452 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6453 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6454 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6455 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6456 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6457 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6458 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6459 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6460 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6463 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6464 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6465 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6466 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6468 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6469 +         0,
605.6470 +};
605.6471 +
605.6472 +static const static_codebook _44c4_s_p1_0 = {
605.6473 +        8, 6561,
605.6474 +        (long *)_vq_lengthlist__44c4_s_p1_0,
605.6475 +        1, -535822336, 1611661312, 2, 0,
605.6476 +        (long *)_vq_quantlist__44c4_s_p1_0,
605.6477 +        0
605.6478 +};
605.6479 +
605.6480 +static const long _vq_quantlist__44c4_s_p2_0[] = {
605.6481 +        2,
605.6482 +        1,
605.6483 +        3,
605.6484 +        0,
605.6485 +        4,
605.6486 +};
605.6487 +
605.6488 +static const long _vq_lengthlist__44c4_s_p2_0[] = {
605.6489 +         2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0,
605.6490 +         7, 7, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 7,
605.6491 +         7, 0, 0, 0, 7, 7, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
605.6492 +         0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0,
605.6493 +         0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6494 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6495 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6496 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6497 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6498 +         0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 7, 7, 0, 0,
605.6499 +         0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5,
605.6500 +         7, 8, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9,
605.6501 +         9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6502 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6503 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6504 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6505 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6506 +         0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7,
605.6507 +         0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0,
605.6508 +         0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0,
605.6509 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6510 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6511 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6512 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6513 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6514 +         7,10,10, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0,
605.6515 +        10,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0, 9,
605.6516 +         9, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
605.6517 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6518 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6519 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6520 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6521 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6522 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6523 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6525 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6526 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6527 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6528 +         0,
605.6529 +};
605.6530 +
605.6531 +static const static_codebook _44c4_s_p2_0 = {
605.6532 +        4, 625,
605.6533 +        (long *)_vq_lengthlist__44c4_s_p2_0,
605.6534 +        1, -533725184, 1611661312, 3, 0,
605.6535 +        (long *)_vq_quantlist__44c4_s_p2_0,
605.6536 +        0
605.6537 +};
605.6538 +
605.6539 +static const long _vq_quantlist__44c4_s_p3_0[] = {
605.6540 +        2,
605.6541 +        1,
605.6542 +        3,
605.6543 +        0,
605.6544 +        4,
605.6545 +};
605.6546 +
605.6547 +static const long _vq_lengthlist__44c4_s_p3_0[] = {
605.6548 +         2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6549 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 4, 6, 6, 0, 0,
605.6550 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6551 +         0, 0, 4, 4, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6552 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9,
605.6553 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6554 +         0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.6555 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6556 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6557 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6558 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6559 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6560 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6561 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6562 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6563 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6564 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6565 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6566 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6567 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6568 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6569 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6570 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6571 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6572 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6573 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6574 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6575 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6576 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6577 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6578 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6579 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6580 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6581 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6582 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6583 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6584 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6585 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6586 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6587 +         0,
605.6588 +};
605.6589 +
605.6590 +static const static_codebook _44c4_s_p3_0 = {
605.6591 +        4, 625,
605.6592 +        (long *)_vq_lengthlist__44c4_s_p3_0,
605.6593 +        1, -533725184, 1611661312, 3, 0,
605.6594 +        (long *)_vq_quantlist__44c4_s_p3_0,
605.6595 +        0
605.6596 +};
605.6597 +
605.6598 +static const long _vq_quantlist__44c4_s_p4_0[] = {
605.6599 +        4,
605.6600 +        3,
605.6601 +        5,
605.6602 +        2,
605.6603 +        6,
605.6604 +        1,
605.6605 +        7,
605.6606 +        0,
605.6607 +        8,
605.6608 +};
605.6609 +
605.6610 +static const long _vq_lengthlist__44c4_s_p4_0[] = {
605.6611 +         2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0,
605.6612 +         0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6,
605.6613 +         0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0,
605.6614 +         7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0,
605.6615 +         0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.6616 +         0,
605.6617 +};
605.6618 +
605.6619 +static const static_codebook _44c4_s_p4_0 = {
605.6620 +        2, 81,
605.6621 +        (long *)_vq_lengthlist__44c4_s_p4_0,
605.6622 +        1, -531628032, 1611661312, 4, 0,
605.6623 +        (long *)_vq_quantlist__44c4_s_p4_0,
605.6624 +        0
605.6625 +};
605.6626 +
605.6627 +static const long _vq_quantlist__44c4_s_p5_0[] = {
605.6628 +        4,
605.6629 +        3,
605.6630 +        5,
605.6631 +        2,
605.6632 +        6,
605.6633 +        1,
605.6634 +        7,
605.6635 +        0,
605.6636 +        8,
605.6637 +};
605.6638 +
605.6639 +static const long _vq_lengthlist__44c4_s_p5_0[] = {
605.6640 +         2, 3, 3, 6, 6, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7,
605.6641 +         9, 9, 0, 4, 5, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7,
605.6642 +         8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10, 9, 0, 0, 0,
605.6643 +         9, 8, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0,
605.6644 +         0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,10,
605.6645 +        10,
605.6646 +};
605.6647 +
605.6648 +static const static_codebook _44c4_s_p5_0 = {
605.6649 +        2, 81,
605.6650 +        (long *)_vq_lengthlist__44c4_s_p5_0,
605.6651 +        1, -531628032, 1611661312, 4, 0,
605.6652 +        (long *)_vq_quantlist__44c4_s_p5_0,
605.6653 +        0
605.6654 +};
605.6655 +
605.6656 +static const long _vq_quantlist__44c4_s_p6_0[] = {
605.6657 +        8,
605.6658 +        7,
605.6659 +        9,
605.6660 +        6,
605.6661 +        10,
605.6662 +        5,
605.6663 +        11,
605.6664 +        4,
605.6665 +        12,
605.6666 +        3,
605.6667 +        13,
605.6668 +        2,
605.6669 +        14,
605.6670 +        1,
605.6671 +        15,
605.6672 +        0,
605.6673 +        16,
605.6674 +};
605.6675 +
605.6676 +static const long _vq_lengthlist__44c4_s_p6_0[] = {
605.6677 +         2, 4, 4, 6, 6, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,
605.6678 +        11, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11,
605.6679 +        11,11, 0, 4, 4, 7, 6, 8, 8, 9, 9, 9, 9,10,10,11,
605.6680 +        11,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
605.6681 +        11,11,11,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
605.6682 +        10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.6683 +        10,10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9,
605.6684 +         9,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
605.6685 +        10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,10,
605.6686 +        10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,
605.6687 +         9,10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9,
605.6688 +         9, 9, 9,10,10,11,11,11,12,12,12, 0, 0, 0, 0, 0,
605.6689 +        10,10,10,10,11,11,11,11,12,12,13,12, 0, 0, 0, 0,
605.6690 +         0, 0, 0,10,10,11,11,11,11,12,12,12,12, 0, 0, 0,
605.6691 +         0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0, 0,
605.6692 +         0, 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0,
605.6693 +         0, 0, 0, 0, 0, 0,12,12,12,12,12,12,13,13,13,13,
605.6694 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,12,13,13,
605.6695 +        13,
605.6696 +};
605.6697 +
605.6698 +static const static_codebook _44c4_s_p6_0 = {
605.6699 +        2, 289,
605.6700 +        (long *)_vq_lengthlist__44c4_s_p6_0,
605.6701 +        1, -529530880, 1611661312, 5, 0,
605.6702 +        (long *)_vq_quantlist__44c4_s_p6_0,
605.6703 +        0
605.6704 +};
605.6705 +
605.6706 +static const long _vq_quantlist__44c4_s_p7_0[] = {
605.6707 +        1,
605.6708 +        0,
605.6709 +        2,
605.6710 +};
605.6711 +
605.6712 +static const long _vq_lengthlist__44c4_s_p7_0[] = {
605.6713 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
605.6714 +         9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11,
605.6715 +        10,11,11,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
605.6716 +        11,10,10,11,10,10, 7,11,11,12,11,11,12,11,11, 6,
605.6717 +         9, 9,11,10,10,11,10,10, 6, 9, 9,11,10,10,11,10,
605.6718 +        10,
605.6719 +};
605.6720 +
605.6721 +static const static_codebook _44c4_s_p7_0 = {
605.6722 +        4, 81,
605.6723 +        (long *)_vq_lengthlist__44c4_s_p7_0,
605.6724 +        1, -529137664, 1618345984, 2, 0,
605.6725 +        (long *)_vq_quantlist__44c4_s_p7_0,
605.6726 +        0
605.6727 +};
605.6728 +
605.6729 +static const long _vq_quantlist__44c4_s_p7_1[] = {
605.6730 +        5,
605.6731 +        4,
605.6732 +        6,
605.6733 +        3,
605.6734 +        7,
605.6735 +        2,
605.6736 +        8,
605.6737 +        1,
605.6738 +        9,
605.6739 +        0,
605.6740 +        10,
605.6741 +};
605.6742 +
605.6743 +static const long _vq_lengthlist__44c4_s_p7_1[] = {
605.6744 +         2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6,
605.6745 +         7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8,
605.6746 +         8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
605.6747 +         7, 8, 8, 8, 8, 8, 8,10,10,10, 8, 7, 8, 8, 8, 8,
605.6748 +         8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
605.6749 +         8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
605.6750 +         8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 9, 8,10,10,
605.6751 +        10,10,10, 8, 8, 8, 8, 9, 9,
605.6752 +};
605.6753 +
605.6754 +static const static_codebook _44c4_s_p7_1 = {
605.6755 +        2, 121,
605.6756 +        (long *)_vq_lengthlist__44c4_s_p7_1,
605.6757 +        1, -531365888, 1611661312, 4, 0,
605.6758 +        (long *)_vq_quantlist__44c4_s_p7_1,
605.6759 +        0
605.6760 +};
605.6761 +
605.6762 +static const long _vq_quantlist__44c4_s_p8_0[] = {
605.6763 +        6,
605.6764 +        5,
605.6765 +        7,
605.6766 +        4,
605.6767 +        8,
605.6768 +        3,
605.6769 +        9,
605.6770 +        2,
605.6771 +        10,
605.6772 +        1,
605.6773 +        11,
605.6774 +        0,
605.6775 +        12,
605.6776 +};
605.6777 +
605.6778 +static const long _vq_lengthlist__44c4_s_p8_0[] = {
605.6779 +         1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5,
605.6780 +         7, 7, 8, 8, 8, 8, 9,10,11,11, 7, 5, 5, 7, 7, 8,
605.6781 +         8, 9, 9,10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.6782 +        10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.6783 +        11, 0,12,12, 9, 9, 9, 9,10,10,10,10,11,11, 0,13,
605.6784 +        13, 9, 9,10, 9,10,10,11,11,11,12, 0, 0, 0,10,10,
605.6785 +        10,10,10,10,11,11,12,12, 0, 0, 0,10,10,10,10,10,
605.6786 +        10,11,11,12,12, 0, 0, 0,14,14,11,11,11,11,12,12,
605.6787 +        12,12, 0, 0, 0,14,14,11,11,11,11,12,12,12,13, 0,
605.6788 +         0, 0, 0, 0,12,12,12,12,12,12,13,13, 0, 0, 0, 0,
605.6789 +         0,13,12,12,12,12,12,13,13,
605.6790 +};
605.6791 +
605.6792 +static const static_codebook _44c4_s_p8_0 = {
605.6793 +        2, 169,
605.6794 +        (long *)_vq_lengthlist__44c4_s_p8_0,
605.6795 +        1, -526516224, 1616117760, 4, 0,
605.6796 +        (long *)_vq_quantlist__44c4_s_p8_0,
605.6797 +        0
605.6798 +};
605.6799 +
605.6800 +static const long _vq_quantlist__44c4_s_p8_1[] = {
605.6801 +        2,
605.6802 +        1,
605.6803 +        3,
605.6804 +        0,
605.6805 +        4,
605.6806 +};
605.6807 +
605.6808 +static const long _vq_lengthlist__44c4_s_p8_1[] = {
605.6809 +         2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 5, 4, 5, 5, 6,
605.6810 +         5, 5, 5, 5, 6, 6, 6, 5, 5,
605.6811 +};
605.6812 +
605.6813 +static const static_codebook _44c4_s_p8_1 = {
605.6814 +        2, 25,
605.6815 +        (long *)_vq_lengthlist__44c4_s_p8_1,
605.6816 +        1, -533725184, 1611661312, 3, 0,
605.6817 +        (long *)_vq_quantlist__44c4_s_p8_1,
605.6818 +        0
605.6819 +};
605.6820 +
605.6821 +static const long _vq_quantlist__44c4_s_p9_0[] = {
605.6822 +        6,
605.6823 +        5,
605.6824 +        7,
605.6825 +        4,
605.6826 +        8,
605.6827 +        3,
605.6828 +        9,
605.6829 +        2,
605.6830 +        10,
605.6831 +        1,
605.6832 +        11,
605.6833 +        0,
605.6834 +        12,
605.6835 +};
605.6836 +
605.6837 +static const long _vq_lengthlist__44c4_s_p9_0[] = {
605.6838 +         1, 3, 3,12,12,12,12,12,12,12,12,12,12, 4, 7, 7,
605.6839 +        12,12,12,12,12,12,12,12,12,12, 3, 8, 8,12,12,12,
605.6840 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.6841 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.6842 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.6843 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.6844 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.6845 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.6846 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.6847 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.6848 +        12,12,12,12,12,12,12,12,12,
605.6849 +};
605.6850 +
605.6851 +static const static_codebook _44c4_s_p9_0 = {
605.6852 +        2, 169,
605.6853 +        (long *)_vq_lengthlist__44c4_s_p9_0,
605.6854 +        1, -513964032, 1628680192, 4, 0,
605.6855 +        (long *)_vq_quantlist__44c4_s_p9_0,
605.6856 +        0
605.6857 +};
605.6858 +
605.6859 +static const long _vq_quantlist__44c4_s_p9_1[] = {
605.6860 +        7,
605.6861 +        6,
605.6862 +        8,
605.6863 +        5,
605.6864 +        9,
605.6865 +        4,
605.6866 +        10,
605.6867 +        3,
605.6868 +        11,
605.6869 +        2,
605.6870 +        12,
605.6871 +        1,
605.6872 +        13,
605.6873 +        0,
605.6874 +        14,
605.6875 +};
605.6876 +
605.6877 +static const long _vq_lengthlist__44c4_s_p9_1[] = {
605.6878 +         1, 4, 4, 5, 5, 7, 7, 9, 8,10, 9,10,10,10,10, 6,
605.6879 +         5, 5, 7, 7, 9, 8,10, 9,11,10,12,12,13,13, 6, 5,
605.6880 +         5, 7, 7, 9, 9,10,10,11,11,12,12,12,13,19, 8, 8,
605.6881 +         8, 8, 9, 9,10,10,12,11,12,12,13,13,19, 8, 8, 8,
605.6882 +         8, 9, 9,11,11,12,12,13,13,13,13,19,12,12, 9, 9,
605.6883 +        11,11,11,11,12,11,13,12,13,13,18,12,12, 9, 9,11,
605.6884 +        10,11,11,12,12,12,13,13,14,19,18,18,11,11,11,11,
605.6885 +        12,12,13,12,13,13,14,14,16,18,18,11,11,11,10,12,
605.6886 +        11,13,13,13,13,13,14,17,18,18,14,15,11,12,12,13,
605.6887 +        13,13,13,14,14,14,18,18,18,15,15,12,10,13,10,13,
605.6888 +        13,13,13,13,14,18,17,18,17,18,12,13,12,13,13,13,
605.6889 +        14,14,16,14,18,17,18,18,17,13,12,13,10,12,12,14,
605.6890 +        14,14,14,17,18,18,18,18,14,15,12,12,13,12,14,14,
605.6891 +        15,15,18,18,18,17,18,15,14,12,11,12,12,14,14,14,
605.6892 +        15,
605.6893 +};
605.6894 +
605.6895 +static const static_codebook _44c4_s_p9_1 = {
605.6896 +        2, 225,
605.6897 +        (long *)_vq_lengthlist__44c4_s_p9_1,
605.6898 +        1, -520986624, 1620377600, 4, 0,
605.6899 +        (long *)_vq_quantlist__44c4_s_p9_1,
605.6900 +        0
605.6901 +};
605.6902 +
605.6903 +static const long _vq_quantlist__44c4_s_p9_2[] = {
605.6904 +        10,
605.6905 +        9,
605.6906 +        11,
605.6907 +        8,
605.6908 +        12,
605.6909 +        7,
605.6910 +        13,
605.6911 +        6,
605.6912 +        14,
605.6913 +        5,
605.6914 +        15,
605.6915 +        4,
605.6916 +        16,
605.6917 +        3,
605.6918 +        17,
605.6919 +        2,
605.6920 +        18,
605.6921 +        1,
605.6922 +        19,
605.6923 +        0,
605.6924 +        20,
605.6925 +};
605.6926 +
605.6927 +static const long _vq_lengthlist__44c4_s_p9_2[] = {
605.6928 +         2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
605.6929 +         8, 9, 9, 9, 9,11, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
605.6930 +         9, 9, 9, 9, 9, 9,10,10,10,10,11, 6, 6, 7, 7, 8,
605.6931 +         8, 8, 8, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,11,
605.6932 +         7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9,10,10,10,
605.6933 +        10,10,10,10,12,11,11, 7, 7, 8, 8, 9, 9, 9, 9, 9,
605.6934 +         9,10,10,10,10,10,10,10,10,12,11,12, 8, 8, 8, 8,
605.6935 +         9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,11,11,
605.6936 +        11, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,10,10,10,
605.6937 +        10,10,10,11,11,12, 9, 9, 9, 9, 9, 9,10, 9,10,10,
605.6938 +        10,10,10,10,10,10,10,10,11,11,11,11,11, 9, 9, 9,
605.6939 +         9,10,10,10,10,10,10,10,10,10,10,10,10,11,12,11,
605.6940 +        11,11, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
605.6941 +        10,10,11,11,11,11,11, 9, 9, 9, 9,10,10,10,10,10,
605.6942 +        10,10,10,10,10,10,10,11,11,11,12,12,10,10,10,10,
605.6943 +        10,10,10,10,10,10,10,10,10,10,10,10,11,12,11,12,
605.6944 +        11,11,11, 9,10,10,10,10,10,10,10,10,10,10,10,10,
605.6945 +        10,11,12,11,11,11,11,11,10,10,10,10,10,10,10,10,
605.6946 +        10,10,10,10,10,10,11,11,11,12,11,11,11,10,10,10,
605.6947 +        10,10,10,10,10,10,10,10,10,10,10,12,11,11,12,11,
605.6948 +        11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.6949 +        11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
605.6950 +        10,10,10,10,10,11,11,11,11,12,12,11,11,11,11,11,
605.6951 +        11,11,10,10,10,10,10,10,10,10,12,12,12,11,11,11,
605.6952 +        12,11,11,11,10,10,10,10,10,10,10,10,10,10,10,12,
605.6953 +        11,12,12,12,12,12,11,12,11,11,10,10,10,10,10,10,
605.6954 +        10,10,10,10,12,12,12,12,11,11,11,11,11,11,11,10,
605.6955 +        10,10,10,10,10,10,10,10,10,
605.6956 +};
605.6957 +
605.6958 +static const static_codebook _44c4_s_p9_2 = {
605.6959 +        2, 441,
605.6960 +        (long *)_vq_lengthlist__44c4_s_p9_2,
605.6961 +        1, -529268736, 1611661312, 5, 0,
605.6962 +        (long *)_vq_quantlist__44c4_s_p9_2,
605.6963 +        0
605.6964 +};
605.6965 +
605.6966 +static const long _huff_lengthlist__44c4_s_short[] = {
605.6967 +         4, 7,14,10,15,10,12,15,16,15, 4, 2,11, 5,10, 6,
605.6968 +         8,11,14,14,14,10, 7,11, 6, 8,10,11,13,15, 9, 4,
605.6969 +        11, 5, 9, 6, 9,12,14,15,14, 9, 6, 9, 4, 5, 7,10,
605.6970 +        12,13, 9, 5, 7, 6, 5, 5, 7,10,13,13,10, 8, 9, 8,
605.6971 +         7, 6, 8,10,14,14,13,11,10,10, 7, 7, 8,11,14,15,
605.6972 +        13,12, 9, 9, 6, 5, 7,10,14,17,15,13,11,10, 6, 6,
605.6973 +         7, 9,12,17,
605.6974 +};
605.6975 +
605.6976 +static const static_codebook _huff_book__44c4_s_short = {
605.6977 +        2, 100,
605.6978 +        (long *)_huff_lengthlist__44c4_s_short,
605.6979 +        0, 0, 0, 0, 0,
605.6980 +        NULL,
605.6981 +        0
605.6982 +};
605.6983 +
605.6984 +static const long _huff_lengthlist__44c5_s_long[] = {
605.6985 +         3, 8, 9,13,10,12,12,12,12,12, 6, 4, 6, 8, 6, 8,
605.6986 +        10,10,11,12, 8, 5, 4,10, 4, 7, 8, 9,10,11,13, 8,
605.6987 +        10, 8, 9, 9,11,12,13,14,10, 6, 4, 9, 3, 5, 6, 8,
605.6988 +        10,11,11, 8, 6, 9, 5, 5, 6, 7, 9,11,12, 9, 7,11,
605.6989 +         6, 6, 6, 7, 8,10,12,11, 9,12, 7, 7, 6, 6, 7, 9,
605.6990 +        13,12,10,13, 9, 8, 7, 7, 7, 8,11,15,11,15,11,10,
605.6991 +         9, 8, 7, 7,
605.6992 +};
605.6993 +
605.6994 +static const static_codebook _huff_book__44c5_s_long = {
605.6995 +        2, 100,
605.6996 +        (long *)_huff_lengthlist__44c5_s_long,
605.6997 +        0, 0, 0, 0, 0,
605.6998 +        NULL,
605.6999 +        0
605.7000 +};
605.7001 +
605.7002 +static const long _vq_quantlist__44c5_s_p1_0[] = {
605.7003 +        1,
605.7004 +        0,
605.7005 +        2,
605.7006 +};
605.7007 +
605.7008 +static const long _vq_lengthlist__44c5_s_p1_0[] = {
605.7009 +         2, 4, 4, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0,
605.7010 +         0, 0, 4, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7011 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7012 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7013 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7014 +         0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
605.7015 +         0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7016 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7017 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7018 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7019 +         0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
605.7020 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7021 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7022 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7023 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7024 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7025 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7026 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7027 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7028 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7029 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7030 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7031 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7032 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7033 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7034 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7035 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7036 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7037 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7038 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7039 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7040 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7041 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7042 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7043 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7044 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7045 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7046 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7047 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7048 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7049 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7050 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7051 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7052 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7053 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7054 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0,
605.7055 +         0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.7056 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7057 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7058 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7059 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
605.7060 +         0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
605.7061 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7062 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7063 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7064 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.7065 +         0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,11,
605.7066 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7067 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7068 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7069 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7070 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7071 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7072 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7073 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7074 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7075 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7076 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7077 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7078 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7079 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7080 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7081 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7082 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7083 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7084 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7085 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7086 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7087 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7088 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7089 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7090 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7091 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7092 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7093 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7094 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7095 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7096 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7097 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7098 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7099 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7100 +         0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.7101 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7102 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7103 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7104 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7105 +         0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0,
605.7106 +         0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0,
605.7107 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7108 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7109 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7110 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
605.7111 +         0, 0, 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 0,
605.7112 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7113 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7114 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7115 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7116 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7117 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7118 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7119 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7120 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7121 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7122 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7123 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7124 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7125 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7126 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7127 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7128 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7129 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7130 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7131 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7132 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7133 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7134 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7135 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7136 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7137 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7138 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7139 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7140 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7141 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7142 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7143 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7144 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7145 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7146 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7147 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7148 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7149 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7150 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7151 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7152 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7153 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7154 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7155 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7156 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7157 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7158 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7159 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7160 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7161 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7162 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7163 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7164 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7165 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7166 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7167 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7168 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7169 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7170 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7171 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7172 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7173 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7174 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7175 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7176 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7177 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7178 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7179 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7180 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7181 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7182 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7183 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7184 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7185 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7186 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7187 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7188 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7189 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7190 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7191 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7192 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7193 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7194 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7195 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7196 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7197 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7198 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7199 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7200 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7201 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7202 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7203 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7204 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7205 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7206 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7207 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7208 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7209 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7210 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7211 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7212 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7213 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7214 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7215 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7216 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7217 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7218 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7219 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7220 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7221 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7222 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7223 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7224 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7225 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7226 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7227 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7228 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7229 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7230 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7231 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7232 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7233 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7234 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7235 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7236 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7237 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7238 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7239 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7240 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7241 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7242 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7243 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7244 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7245 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7246 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7247 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7248 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7249 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7250 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7251 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7252 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7253 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7254 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7255 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7256 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7257 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7258 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7259 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7260 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7261 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7262 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7263 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7264 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7265 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7266 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7267 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7268 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7269 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7270 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7271 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7272 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7273 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7274 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7275 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7276 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7277 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7278 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7279 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7280 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7281 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7282 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7283 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7284 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7285 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7286 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7287 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7288 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7289 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7290 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7291 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7292 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7293 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7294 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7295 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7296 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7297 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7298 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7299 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7300 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7301 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7302 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7303 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7304 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7305 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7306 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7307 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7308 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7309 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7310 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7311 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7312 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7313 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7314 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7315 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7316 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7317 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7318 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7319 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7320 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7321 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7322 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7323 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7324 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7325 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7326 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7327 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7329 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7330 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7331 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7332 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7333 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7334 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7335 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7336 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7339 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7342 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7346 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7351 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7356 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7362 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7363 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7364 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7365 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7366 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7367 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7368 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7369 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7370 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7375 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7376 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7377 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7378 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7379 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7380 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7381 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7382 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7383 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7385 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7386 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7387 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7388 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7389 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7390 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7391 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7392 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7393 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7394 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7395 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7396 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7397 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7399 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7400 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7401 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7402 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7403 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7404 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7405 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7406 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7410 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7411 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7412 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7413 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7414 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7415 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7416 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7417 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7418 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7419 +         0,
605.7420 +};
605.7421 +
605.7422 +static const static_codebook _44c5_s_p1_0 = {
605.7423 +        8, 6561,
605.7424 +        (long *)_vq_lengthlist__44c5_s_p1_0,
605.7425 +        1, -535822336, 1611661312, 2, 0,
605.7426 +        (long *)_vq_quantlist__44c5_s_p1_0,
605.7427 +        0
605.7428 +};
605.7429 +
605.7430 +static const long _vq_quantlist__44c5_s_p2_0[] = {
605.7431 +        2,
605.7432 +        1,
605.7433 +        3,
605.7434 +        0,
605.7435 +        4,
605.7436 +};
605.7437 +
605.7438 +static const long _vq_lengthlist__44c5_s_p2_0[] = {
605.7439 +         2, 4, 4, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0,
605.7440 +         8, 7, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 0, 0, 0, 8,
605.7441 +         8, 0, 0, 0, 8, 7, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
605.7442 +         0, 0, 4, 6, 6, 0, 0, 0, 8, 8, 0, 0, 0, 7, 8, 0,
605.7443 +         0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7444 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7445 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7446 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7447 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7448 +         0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 8, 8, 0, 0,
605.7449 +         0, 8, 8, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 5,
605.7450 +         7, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,10,
605.7451 +        10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7452 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7453 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7454 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7455 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7456 +         0, 0, 0, 5, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8,
605.7457 +         0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0,
605.7458 +         0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0,
605.7459 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7460 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7463 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7464 +         8,10,10, 0, 0, 0,10,10, 0, 0, 0, 9,10, 0, 0, 0,
605.7465 +        11,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0,10,
605.7466 +        10, 0, 0, 0,10,10, 0, 0, 0,10,11, 0, 0, 0, 0, 0,
605.7467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7468 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7469 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7470 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7471 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7472 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7473 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7474 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7475 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7476 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7477 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7478 +         0,
605.7479 +};
605.7480 +
605.7481 +static const static_codebook _44c5_s_p2_0 = {
605.7482 +        4, 625,
605.7483 +        (long *)_vq_lengthlist__44c5_s_p2_0,
605.7484 +        1, -533725184, 1611661312, 3, 0,
605.7485 +        (long *)_vq_quantlist__44c5_s_p2_0,
605.7486 +        0
605.7487 +};
605.7488 +
605.7489 +static const long _vq_quantlist__44c5_s_p3_0[] = {
605.7490 +        2,
605.7491 +        1,
605.7492 +        3,
605.7493 +        0,
605.7494 +        4,
605.7495 +};
605.7496 +
605.7497 +static const long _vq_lengthlist__44c5_s_p3_0[] = {
605.7498 +         2, 4, 3, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7499 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 6, 6, 0, 0,
605.7500 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7501 +         0, 0, 3, 5, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7502 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 8, 8,
605.7503 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7504 +         0, 0, 0, 0, 5, 6, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0,
605.7505 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7506 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7507 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7508 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7509 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7510 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7511 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7512 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7513 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7514 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7515 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7516 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7517 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7518 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7519 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7520 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7521 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7522 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7523 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7525 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7526 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7527 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7528 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7529 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7530 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7531 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7532 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7533 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7534 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7535 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7536 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7537 +         0,
605.7538 +};
605.7539 +
605.7540 +static const static_codebook _44c5_s_p3_0 = {
605.7541 +        4, 625,
605.7542 +        (long *)_vq_lengthlist__44c5_s_p3_0,
605.7543 +        1, -533725184, 1611661312, 3, 0,
605.7544 +        (long *)_vq_quantlist__44c5_s_p3_0,
605.7545 +        0
605.7546 +};
605.7547 +
605.7548 +static const long _vq_quantlist__44c5_s_p4_0[] = {
605.7549 +        4,
605.7550 +        3,
605.7551 +        5,
605.7552 +        2,
605.7553 +        6,
605.7554 +        1,
605.7555 +        7,
605.7556 +        0,
605.7557 +        8,
605.7558 +};
605.7559 +
605.7560 +static const long _vq_lengthlist__44c5_s_p4_0[] = {
605.7561 +         2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0,
605.7562 +         0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6,
605.7563 +         0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0,
605.7564 +         7, 7, 0, 0, 0, 0, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0,
605.7565 +         0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.7566 +         0,
605.7567 +};
605.7568 +
605.7569 +static const static_codebook _44c5_s_p4_0 = {
605.7570 +        2, 81,
605.7571 +        (long *)_vq_lengthlist__44c5_s_p4_0,
605.7572 +        1, -531628032, 1611661312, 4, 0,
605.7573 +        (long *)_vq_quantlist__44c5_s_p4_0,
605.7574 +        0
605.7575 +};
605.7576 +
605.7577 +static const long _vq_quantlist__44c5_s_p5_0[] = {
605.7578 +        4,
605.7579 +        3,
605.7580 +        5,
605.7581 +        2,
605.7582 +        6,
605.7583 +        1,
605.7584 +        7,
605.7585 +        0,
605.7586 +        8,
605.7587 +};
605.7588 +
605.7589 +static const long _vq_lengthlist__44c5_s_p5_0[] = {
605.7590 +         2, 4, 3, 6, 6, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7,
605.7591 +         9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7,
605.7592 +         7, 7, 9, 9, 0, 0, 0, 7, 6, 7, 7, 9, 9, 0, 0, 0,
605.7593 +         8, 8, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0,
605.7594 +         0, 0, 9, 9, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
605.7595 +        10,
605.7596 +};
605.7597 +
605.7598 +static const static_codebook _44c5_s_p5_0 = {
605.7599 +        2, 81,
605.7600 +        (long *)_vq_lengthlist__44c5_s_p5_0,
605.7601 +        1, -531628032, 1611661312, 4, 0,
605.7602 +        (long *)_vq_quantlist__44c5_s_p5_0,
605.7603 +        0
605.7604 +};
605.7605 +
605.7606 +static const long _vq_quantlist__44c5_s_p6_0[] = {
605.7607 +        8,
605.7608 +        7,
605.7609 +        9,
605.7610 +        6,
605.7611 +        10,
605.7612 +        5,
605.7613 +        11,
605.7614 +        4,
605.7615 +        12,
605.7616 +        3,
605.7617 +        13,
605.7618 +        2,
605.7619 +        14,
605.7620 +        1,
605.7621 +        15,
605.7622 +        0,
605.7623 +        16,
605.7624 +};
605.7625 +
605.7626 +static const long _vq_lengthlist__44c5_s_p6_0[] = {
605.7627 +         2, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,10,11,
605.7628 +        11, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11,
605.7629 +        12,12, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,
605.7630 +        11,12,12, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
605.7631 +        11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
605.7632 +        10,11,11,12,12, 0, 0, 0, 7, 7, 9, 9,10,10,10,10,
605.7633 +        11,11,11,11,12,12, 0, 0, 0, 7, 7, 8, 9,10,10,10,
605.7634 +        10,11,11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,
605.7635 +        10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10,
605.7636 +        10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,
605.7637 +        10,10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9,
605.7638 +         9, 9,10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0,
605.7639 +        10,10,10,10,11,11,11,12,12,12,13,13, 0, 0, 0, 0,
605.7640 +         0, 0, 0,10,10,11,11,11,11,12,12,13,13, 0, 0, 0,
605.7641 +         0, 0, 0, 0,11,11,11,11,12,12,12,13,13,13, 0, 0,
605.7642 +         0, 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0,
605.7643 +         0, 0, 0, 0, 0, 0,12,12,12,12,13,12,13,13,13,13,
605.7644 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,
605.7645 +        13,
605.7646 +};
605.7647 +
605.7648 +static const static_codebook _44c5_s_p6_0 = {
605.7649 +        2, 289,
605.7650 +        (long *)_vq_lengthlist__44c5_s_p6_0,
605.7651 +        1, -529530880, 1611661312, 5, 0,
605.7652 +        (long *)_vq_quantlist__44c5_s_p6_0,
605.7653 +        0
605.7654 +};
605.7655 +
605.7656 +static const long _vq_quantlist__44c5_s_p7_0[] = {
605.7657 +        1,
605.7658 +        0,
605.7659 +        2,
605.7660 +};
605.7661 +
605.7662 +static const long _vq_lengthlist__44c5_s_p7_0[] = {
605.7663 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
605.7664 +         9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11,
605.7665 +        10,11,11,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
605.7666 +        11,10,10,11,10,10, 7,11,11,12,11,11,12,11,11, 6,
605.7667 +         9, 9,11,10,10,11,10,10, 6, 9, 9,11,10,10,11,10,
605.7668 +        10,
605.7669 +};
605.7670 +
605.7671 +static const static_codebook _44c5_s_p7_0 = {
605.7672 +        4, 81,
605.7673 +        (long *)_vq_lengthlist__44c5_s_p7_0,
605.7674 +        1, -529137664, 1618345984, 2, 0,
605.7675 +        (long *)_vq_quantlist__44c5_s_p7_0,
605.7676 +        0
605.7677 +};
605.7678 +
605.7679 +static const long _vq_quantlist__44c5_s_p7_1[] = {
605.7680 +        5,
605.7681 +        4,
605.7682 +        6,
605.7683 +        3,
605.7684 +        7,
605.7685 +        2,
605.7686 +        8,
605.7687 +        1,
605.7688 +        9,
605.7689 +        0,
605.7690 +        10,
605.7691 +};
605.7692 +
605.7693 +static const long _vq_lengthlist__44c5_s_p7_1[] = {
605.7694 +         2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6,
605.7695 +         7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8,
605.7696 +         8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
605.7697 +         7, 8, 8, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8,
605.7698 +         8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
605.7699 +         8, 8, 8, 8, 8, 8, 8, 9,10,10,10,10,10, 8, 8, 8,
605.7700 +         8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
605.7701 +        10,10,10, 8, 8, 8, 8, 8, 8,
605.7702 +};
605.7703 +
605.7704 +static const static_codebook _44c5_s_p7_1 = {
605.7705 +        2, 121,
605.7706 +        (long *)_vq_lengthlist__44c5_s_p7_1,
605.7707 +        1, -531365888, 1611661312, 4, 0,
605.7708 +        (long *)_vq_quantlist__44c5_s_p7_1,
605.7709 +        0
605.7710 +};
605.7711 +
605.7712 +static const long _vq_quantlist__44c5_s_p8_0[] = {
605.7713 +        6,
605.7714 +        5,
605.7715 +        7,
605.7716 +        4,
605.7717 +        8,
605.7718 +        3,
605.7719 +        9,
605.7720 +        2,
605.7721 +        10,
605.7722 +        1,
605.7723 +        11,
605.7724 +        0,
605.7725 +        12,
605.7726 +};
605.7727 +
605.7728 +static const long _vq_lengthlist__44c5_s_p8_0[] = {
605.7729 +         1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5,
605.7730 +         7, 7, 8, 8, 8, 9,10,10,10,10, 7, 5, 5, 7, 7, 8,
605.7731 +         8, 9, 9,10,10,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.7732 +        10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.7733 +        11, 0,12,12, 9, 9, 9,10,10,10,10,10,11,11, 0,13,
605.7734 +        13, 9, 9, 9, 9,10,10,11,11,11,11, 0, 0, 0,10,10,
605.7735 +        10,10,10,10,11,11,11,11, 0, 0, 0,10,10,10,10,10,
605.7736 +        10,11,11,12,12, 0, 0, 0,14,14,11,11,11,11,12,12,
605.7737 +        12,12, 0, 0, 0,14,14,11,11,11,11,12,12,12,12, 0,
605.7738 +         0, 0, 0, 0,12,12,12,12,12,12,13,13, 0, 0, 0, 0,
605.7739 +         0,12,12,12,12,12,12,13,13,
605.7740 +};
605.7741 +
605.7742 +static const static_codebook _44c5_s_p8_0 = {
605.7743 +        2, 169,
605.7744 +        (long *)_vq_lengthlist__44c5_s_p8_0,
605.7745 +        1, -526516224, 1616117760, 4, 0,
605.7746 +        (long *)_vq_quantlist__44c5_s_p8_0,
605.7747 +        0
605.7748 +};
605.7749 +
605.7750 +static const long _vq_quantlist__44c5_s_p8_1[] = {
605.7751 +        2,
605.7752 +        1,
605.7753 +        3,
605.7754 +        0,
605.7755 +        4,
605.7756 +};
605.7757 +
605.7758 +static const long _vq_lengthlist__44c5_s_p8_1[] = {
605.7759 +         2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, 6,
605.7760 +         5, 5, 5, 5, 6, 6, 6, 5, 5,
605.7761 +};
605.7762 +
605.7763 +static const static_codebook _44c5_s_p8_1 = {
605.7764 +        2, 25,
605.7765 +        (long *)_vq_lengthlist__44c5_s_p8_1,
605.7766 +        1, -533725184, 1611661312, 3, 0,
605.7767 +        (long *)_vq_quantlist__44c5_s_p8_1,
605.7768 +        0
605.7769 +};
605.7770 +
605.7771 +static const long _vq_quantlist__44c5_s_p9_0[] = {
605.7772 +        7,
605.7773 +        6,
605.7774 +        8,
605.7775 +        5,
605.7776 +        9,
605.7777 +        4,
605.7778 +        10,
605.7779 +        3,
605.7780 +        11,
605.7781 +        2,
605.7782 +        12,
605.7783 +        1,
605.7784 +        13,
605.7785 +        0,
605.7786 +        14,
605.7787 +};
605.7788 +
605.7789 +static const long _vq_lengthlist__44c5_s_p9_0[] = {
605.7790 +         1, 3, 3,13,13,13,13,13,13,13,13,13,13,13,13, 4,
605.7791 +         7, 7,13,13,13,13,13,13,13,13,13,13,13,13, 3, 8,
605.7792 +         6,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7793 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7794 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7795 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7796 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7797 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7798 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7799 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7800 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7801 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7802 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.7803 +        13,13,13,13,13,13,13,13,13,12,12,12,12,12,12,12,
605.7804 +        12,
605.7805 +};
605.7806 +
605.7807 +static const static_codebook _44c5_s_p9_0 = {
605.7808 +        2, 225,
605.7809 +        (long *)_vq_lengthlist__44c5_s_p9_0,
605.7810 +        1, -512522752, 1628852224, 4, 0,
605.7811 +        (long *)_vq_quantlist__44c5_s_p9_0,
605.7812 +        0
605.7813 +};
605.7814 +
605.7815 +static const long _vq_quantlist__44c5_s_p9_1[] = {
605.7816 +        8,
605.7817 +        7,
605.7818 +        9,
605.7819 +        6,
605.7820 +        10,
605.7821 +        5,
605.7822 +        11,
605.7823 +        4,
605.7824 +        12,
605.7825 +        3,
605.7826 +        13,
605.7827 +        2,
605.7828 +        14,
605.7829 +        1,
605.7830 +        15,
605.7831 +        0,
605.7832 +        16,
605.7833 +};
605.7834 +
605.7835 +static const long _vq_lengthlist__44c5_s_p9_1[] = {
605.7836 +         1, 4, 4, 5, 5, 7, 7, 9, 8,10, 9,10,10,11,10,11,
605.7837 +        11, 6, 5, 5, 7, 7, 8, 9,10,10,11,10,12,11,12,11,
605.7838 +        13,12, 6, 5, 5, 7, 7, 9, 9,10,10,11,11,12,12,13,
605.7839 +        12,13,13,18, 8, 8, 8, 8, 9, 9,10,11,11,11,12,11,
605.7840 +        13,11,13,12,18, 8, 8, 8, 8,10,10,11,11,12,12,13,
605.7841 +        13,13,13,13,14,18,12,12, 9, 9,11,11,11,11,12,12,
605.7842 +        13,12,13,12,13,13,20,13,12, 9, 9,11,11,11,11,12,
605.7843 +        12,13,13,13,14,14,13,20,18,19,11,12,11,11,12,12,
605.7844 +        13,13,13,13,13,13,14,13,18,19,19,12,11,11,11,12,
605.7845 +        12,13,12,13,13,13,14,14,13,18,17,19,14,15,12,12,
605.7846 +        12,13,13,13,14,14,14,14,14,14,19,19,19,16,15,12,
605.7847 +        11,13,12,14,14,14,13,13,14,14,14,19,18,19,18,19,
605.7848 +        13,13,13,13,14,14,14,13,14,14,14,14,18,17,19,19,
605.7849 +        19,13,13,13,11,13,11,13,14,14,14,14,14,19,17,17,
605.7850 +        18,18,16,16,13,13,13,13,14,13,15,15,14,14,19,19,
605.7851 +        17,17,18,16,16,13,11,14,10,13,12,14,14,14,14,19,
605.7852 +        19,19,19,19,18,17,13,14,13,11,14,13,14,14,15,15,
605.7853 +        19,19,19,17,19,18,18,14,13,12,11,14,11,15,15,15,
605.7854 +        15,
605.7855 +};
605.7856 +
605.7857 +static const static_codebook _44c5_s_p9_1 = {
605.7858 +        2, 289,
605.7859 +        (long *)_vq_lengthlist__44c5_s_p9_1,
605.7860 +        1, -520814592, 1620377600, 5, 0,
605.7861 +        (long *)_vq_quantlist__44c5_s_p9_1,
605.7862 +        0
605.7863 +};
605.7864 +
605.7865 +static const long _vq_quantlist__44c5_s_p9_2[] = {
605.7866 +        10,
605.7867 +        9,
605.7868 +        11,
605.7869 +        8,
605.7870 +        12,
605.7871 +        7,
605.7872 +        13,
605.7873 +        6,
605.7874 +        14,
605.7875 +        5,
605.7876 +        15,
605.7877 +        4,
605.7878 +        16,
605.7879 +        3,
605.7880 +        17,
605.7881 +        2,
605.7882 +        18,
605.7883 +        1,
605.7884 +        19,
605.7885 +        0,
605.7886 +        20,
605.7887 +};
605.7888 +
605.7889 +static const long _vq_lengthlist__44c5_s_p9_2[] = {
605.7890 +         3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
605.7891 +         8, 8, 8, 8, 9,11, 5, 6, 7, 7, 8, 7, 8, 8, 8, 8,
605.7892 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, 5, 5, 7, 7, 7,
605.7893 +         7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
605.7894 +         7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
605.7895 +         9,10, 9,10,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9, 9,
605.7896 +         9, 9, 9,10,10,10,10,10,10,11,11,11, 8, 8, 8, 8,
605.7897 +         9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,11,11,
605.7898 +        11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,10,
605.7899 +        10,10,10,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.7900 +        10,10,10,10,10,10,10,10,11,11,11,11,11, 9, 9, 9,
605.7901 +         9, 9, 9,10, 9,10,10,10,10,10,10,10,10,11,11,11,
605.7902 +        11,11, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,
605.7903 +        10,10,11,11,11,11,11, 9, 9, 9, 9, 9, 9,10,10,10,
605.7904 +        10,10,10,10,10,10,10,11,11,11,11,11, 9, 9,10, 9,
605.7905 +        10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,
605.7906 +        11,11,11, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
605.7907 +        10,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,
605.7908 +        10,10,10,10,10,10,11,11,11,11,11,11,11,10,10,10,
605.7909 +        10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,
605.7910 +        11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.7911 +        11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
605.7912 +        10,10,10,10,10,11,11,11,11,11,11,11,11,11,10,10,
605.7913 +        10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
605.7914 +        11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,11,
605.7915 +        11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,
605.7916 +        10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,10,
605.7917 +        10,10,10,10,10,10,10,10,10,
605.7918 +};
605.7919 +
605.7920 +static const static_codebook _44c5_s_p9_2 = {
605.7921 +        2, 441,
605.7922 +        (long *)_vq_lengthlist__44c5_s_p9_2,
605.7923 +        1, -529268736, 1611661312, 5, 0,
605.7924 +        (long *)_vq_quantlist__44c5_s_p9_2,
605.7925 +        0
605.7926 +};
605.7927 +
605.7928 +static const long _huff_lengthlist__44c5_s_short[] = {
605.7929 +         5, 8,10,14,11,11,12,16,15,17, 5, 5, 7, 9, 7, 8,
605.7930 +        10,13,17,17, 7, 5, 5,10, 5, 7, 8,11,13,15,10, 8,
605.7931 +        10, 8, 8, 8,11,15,18,18, 8, 5, 5, 8, 3, 4, 6,10,
605.7932 +        14,16, 9, 7, 6, 7, 4, 3, 5, 9,14,18,10, 9, 8,10,
605.7933 +         6, 5, 6, 9,14,18,12,12,11,12, 8, 7, 8,11,14,18,
605.7934 +        14,13,12,10, 7, 5, 6, 9,14,18,14,14,13,10, 6, 5,
605.7935 +         6, 8,11,16,
605.7936 +};
605.7937 +
605.7938 +static const static_codebook _huff_book__44c5_s_short = {
605.7939 +        2, 100,
605.7940 +        (long *)_huff_lengthlist__44c5_s_short,
605.7941 +        0, 0, 0, 0, 0,
605.7942 +        NULL,
605.7943 +        0
605.7944 +};
605.7945 +
605.7946 +static const long _huff_lengthlist__44c6_s_long[] = {
605.7947 +         3, 8,11,13,14,14,13,13,16,14, 6, 3, 4, 7, 9, 9,
605.7948 +        10,11,14,13,10, 4, 3, 5, 7, 7, 9,10,13,15,12, 7,
605.7949 +         4, 4, 6, 6, 8,10,13,15,12, 8, 6, 6, 6, 6, 8,10,
605.7950 +        13,14,11, 9, 7, 6, 6, 6, 7, 8,12,11,13,10, 9, 8,
605.7951 +         7, 6, 6, 7,11,11,13,11,10, 9, 9, 7, 7, 6,10,11,
605.7952 +        13,13,13,13,13,11, 9, 8,10,12,12,15,15,16,15,12,
605.7953 +        11,10,10,12,
605.7954 +};
605.7955 +
605.7956 +static const static_codebook _huff_book__44c6_s_long = {
605.7957 +        2, 100,
605.7958 +        (long *)_huff_lengthlist__44c6_s_long,
605.7959 +        0, 0, 0, 0, 0,
605.7960 +        NULL,
605.7961 +        0
605.7962 +};
605.7963 +
605.7964 +static const long _vq_quantlist__44c6_s_p1_0[] = {
605.7965 +        1,
605.7966 +        0,
605.7967 +        2,
605.7968 +};
605.7969 +
605.7970 +static const long _vq_lengthlist__44c6_s_p1_0[] = {
605.7971 +         1, 5, 5, 0, 5, 5, 0, 5, 5, 5, 8, 7, 0, 9, 9, 0,
605.7972 +         9, 8, 5, 7, 8, 0, 9, 9, 0, 8, 9, 0, 0, 0, 0, 0,
605.7973 +         0, 0, 0, 0, 5, 9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9,
605.7974 +         0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
605.7975 +         9, 9, 0, 8, 8, 0, 8, 8, 5, 9, 9, 0, 8, 8, 0, 8,
605.7976 +         8,
605.7977 +};
605.7978 +static const static_codebook _44c6_s_p1_0 = {
605.7979 +        4, 81,
605.7980 +        (long *)_vq_lengthlist__44c6_s_p1_0,
605.7981 +        1, -535822336, 1611661312, 2, 0,
605.7982 +        (long *)_vq_quantlist__44c6_s_p1_0,
605.7983 +        0
605.7984 +};
605.7985 +
605.7986 +static const long _vq_quantlist__44c6_s_p2_0[] = {
605.7987 +        2,
605.7988 +        1,
605.7989 +        3,
605.7990 +        0,
605.7991 +        4,
605.7992 +};
605.7993 +
605.7994 +static const long _vq_lengthlist__44c6_s_p2_0[] = {
605.7995 +         3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0,
605.7996 +         7, 7, 9, 9, 0, 0, 0, 9, 9, 5, 7, 7, 9, 9, 0, 8,
605.7997 +         8,10,10, 0, 8, 7,10, 9, 0,10,10,11,11, 0, 0, 0,
605.7998 +        11,11, 5, 7, 7, 9, 9, 0, 8, 8,10,10, 0, 7, 8, 9,
605.7999 +        10, 0,10,10,11,11, 0, 0, 0,11,11, 8, 9, 9,11,11,
605.8000 +         0,11,11,12,12, 0,11,10,12,12, 0,13,14,14,14, 0,
605.8001 +         0, 0,14,13, 8, 9, 9,11,11, 0,11,11,12,12, 0,10,
605.8002 +        11,12,12, 0,14,13,14,14, 0, 0, 0,13,14, 0, 0, 0,
605.8003 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8004 +         0, 0, 0, 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10,
605.8005 +         0, 7, 7,10,10, 0, 9, 9,11,10, 0, 0, 0,11,11, 5,
605.8006 +         7, 8,10,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9,
605.8007 +         9,10,11, 0, 0, 0,11,11, 8,10, 9,12,12, 0,10,10,
605.8008 +        12,12, 0,10,10,12,12, 0,12,12,13,13, 0, 0, 0,13,
605.8009 +        13, 8, 9,10,12,12, 0,10,10,11,12, 0,10,10,12,12,
605.8010 +         0,12,12,13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0,
605.8011 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8012 +         0, 0, 0, 5, 8, 8,11,11, 0, 7, 7,10,10, 0, 7, 7,
605.8013 +        10,10, 0, 9, 9,10,11, 0, 0, 0,11,10, 5, 8, 8,11,
605.8014 +        11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 9,11,11,
605.8015 +         0, 0, 0,10,11, 8,10,10,12,12, 0,10,10,12,12, 0,
605.8016 +        10,10,12,12, 0,12,13,13,13, 0, 0, 0,14,13, 8,10,
605.8017 +        10,12,12, 0,10,10,12,12, 0,10,10,12,12, 0,13,12,
605.8018 +        13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8019 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8020 +         7,10,10,14,13, 0, 9, 9,13,12, 0, 9, 9,12,12, 0,
605.8021 +        10,10,12,12, 0, 0, 0,12,12, 7,10,10,13,14, 0, 9,
605.8022 +         9,12,13, 0, 9, 9,12,12, 0,10,10,12,12, 0, 0, 0,
605.8023 +        12,12, 9,11,11,14,13, 0,11,10,14,13, 0,11,11,13,
605.8024 +        13, 0,12,12,13,13, 0, 0, 0,13,13, 9,11,11,13,14,
605.8025 +         0,10,11,13,14, 0,11,11,13,13, 0,12,12,13,13, 0,
605.8026 +         0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8027 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8028 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8029 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8030 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
605.8031 +        11,11,14,14, 0,11,11,13,13, 0,11,10,13,13, 0,12,
605.8032 +        12,13,13, 0, 0, 0,13,13, 9,11,11,14,14, 0,11,11,
605.8033 +        13,13, 0,10,11,13,13, 0,12,12,14,13, 0, 0, 0,13,
605.8034 +        13,
605.8035 +};
605.8036 +
605.8037 +static const static_codebook _44c6_s_p2_0 = {
605.8038 +        4, 625,
605.8039 +        (long *)_vq_lengthlist__44c6_s_p2_0,
605.8040 +        1, -533725184, 1611661312, 3, 0,
605.8041 +        (long *)_vq_quantlist__44c6_s_p2_0,
605.8042 +        0
605.8043 +};
605.8044 +
605.8045 +static const long _vq_quantlist__44c6_s_p3_0[] = {
605.8046 +        4,
605.8047 +        3,
605.8048 +        5,
605.8049 +        2,
605.8050 +        6,
605.8051 +        1,
605.8052 +        7,
605.8053 +        0,
605.8054 +        8,
605.8055 +};
605.8056 +
605.8057 +static const long _vq_lengthlist__44c6_s_p3_0[] = {
605.8058 +         2, 3, 4, 6, 6, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7,
605.8059 +         9,10, 0, 4, 4, 6, 6, 7, 7,10, 9, 0, 5, 5, 7, 7,
605.8060 +         8, 8,10,10, 0, 0, 0, 7, 6, 8, 8,10,10, 0, 0, 0,
605.8061 +         7, 7, 9, 9,11,11, 0, 0, 0, 7, 7, 9, 9,11,11, 0,
605.8062 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8063 +         0,
605.8064 +};
605.8065 +
605.8066 +static const static_codebook _44c6_s_p3_0 = {
605.8067 +        2, 81,
605.8068 +        (long *)_vq_lengthlist__44c6_s_p3_0,
605.8069 +        1, -531628032, 1611661312, 4, 0,
605.8070 +        (long *)_vq_quantlist__44c6_s_p3_0,
605.8071 +        0
605.8072 +};
605.8073 +
605.8074 +static const long _vq_quantlist__44c6_s_p4_0[] = {
605.8075 +        8,
605.8076 +        7,
605.8077 +        9,
605.8078 +        6,
605.8079 +        10,
605.8080 +        5,
605.8081 +        11,
605.8082 +        4,
605.8083 +        12,
605.8084 +        3,
605.8085 +        13,
605.8086 +        2,
605.8087 +        14,
605.8088 +        1,
605.8089 +        15,
605.8090 +        0,
605.8091 +        16,
605.8092 +};
605.8093 +
605.8094 +static const long _vq_lengthlist__44c6_s_p4_0[] = {
605.8095 +         2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9,10,10,
605.8096 +        10, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,10,
605.8097 +        11,11, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,
605.8098 +        10,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
605.8099 +        11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
605.8100 +        10,11,11,11,11, 0, 0, 0, 7, 7, 9, 9,10,10,10,10,
605.8101 +        11,11,11,11,12,12, 0, 0, 0, 7, 7, 9, 9,10,10,10,
605.8102 +        10,11,11,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,
605.8103 +        10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, 8, 9,
605.8104 +         9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 0, 0,
605.8105 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8106 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8107 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8108 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8109 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8110 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8111 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8112 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8113 +         0,
605.8114 +};
605.8115 +
605.8116 +static const static_codebook _44c6_s_p4_0 = {
605.8117 +        2, 289,
605.8118 +        (long *)_vq_lengthlist__44c6_s_p4_0,
605.8119 +        1, -529530880, 1611661312, 5, 0,
605.8120 +        (long *)_vq_quantlist__44c6_s_p4_0,
605.8121 +        0
605.8122 +};
605.8123 +
605.8124 +static const long _vq_quantlist__44c6_s_p5_0[] = {
605.8125 +        1,
605.8126 +        0,
605.8127 +        2,
605.8128 +};
605.8129 +
605.8130 +static const long _vq_lengthlist__44c6_s_p5_0[] = {
605.8131 +         1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 6, 9, 9,10,10,
605.8132 +        10, 9, 4, 6, 6, 9,10, 9,10, 9,10, 6, 9, 9,10,12,
605.8133 +        11,10,11,11, 7,10, 9,11,12,12,12,12,12, 7,10,10,
605.8134 +        11,12,12,12,12,12, 6,10,10,10,12,12,11,12,12, 7,
605.8135 +         9,10,11,12,12,12,12,12, 7,10, 9,12,12,12,12,12,
605.8136 +        12,
605.8137 +};
605.8138 +
605.8139 +static const static_codebook _44c6_s_p5_0 = {
605.8140 +        4, 81,
605.8141 +        (long *)_vq_lengthlist__44c6_s_p5_0,
605.8142 +        1, -529137664, 1618345984, 2, 0,
605.8143 +        (long *)_vq_quantlist__44c6_s_p5_0,
605.8144 +        0
605.8145 +};
605.8146 +
605.8147 +static const long _vq_quantlist__44c6_s_p5_1[] = {
605.8148 +        5,
605.8149 +        4,
605.8150 +        6,
605.8151 +        3,
605.8152 +        7,
605.8153 +        2,
605.8154 +        8,
605.8155 +        1,
605.8156 +        9,
605.8157 +        0,
605.8158 +        10,
605.8159 +};
605.8160 +
605.8161 +static const long _vq_lengthlist__44c6_s_p5_1[] = {
605.8162 +         3, 5, 4, 6, 6, 7, 7, 8, 8, 8, 8,11, 4, 4, 6, 6,
605.8163 +         7, 7, 8, 8, 8, 8,11, 4, 4, 6, 6, 7, 7, 8, 8, 8,
605.8164 +         8,11, 6, 6, 6, 6, 8, 8, 8, 8, 9, 9,11,11,11, 6,
605.8165 +         6, 7, 8, 8, 8, 8, 9,11,11,11, 7, 7, 8, 8, 8, 8,
605.8166 +         8, 8,11,11,11, 7, 7, 8, 8, 8, 8, 8, 8,11,11,11,
605.8167 +         8, 8, 8, 8, 8, 8, 8, 8,11,11,11,10,10, 8, 8, 8,
605.8168 +         8, 8, 8,11,11,11,10,10, 8, 8, 8, 8, 8, 8,11,11,
605.8169 +        11,10,10, 7, 7, 8, 8, 8, 8,
605.8170 +};
605.8171 +
605.8172 +static const static_codebook _44c6_s_p5_1 = {
605.8173 +        2, 121,
605.8174 +        (long *)_vq_lengthlist__44c6_s_p5_1,
605.8175 +        1, -531365888, 1611661312, 4, 0,
605.8176 +        (long *)_vq_quantlist__44c6_s_p5_1,
605.8177 +        0
605.8178 +};
605.8179 +
605.8180 +static const long _vq_quantlist__44c6_s_p6_0[] = {
605.8181 +        6,
605.8182 +        5,
605.8183 +        7,
605.8184 +        4,
605.8185 +        8,
605.8186 +        3,
605.8187 +        9,
605.8188 +        2,
605.8189 +        10,
605.8190 +        1,
605.8191 +        11,
605.8192 +        0,
605.8193 +        12,
605.8194 +};
605.8195 +
605.8196 +static const long _vq_lengthlist__44c6_s_p6_0[] = {
605.8197 +         1, 4, 4, 6, 6, 8, 8, 8, 8,10, 9,10,10, 6, 5, 5,
605.8198 +         7, 7, 9, 9, 9, 9,10,10,11,11, 6, 5, 5, 7, 7, 9,
605.8199 +         9,10, 9,11,10,11,11, 0, 6, 6, 7, 7, 9, 9,10,10,
605.8200 +        11,11,12,12, 0, 7, 7, 7, 7, 9, 9,10,10,11,11,12,
605.8201 +        12, 0,11,11, 8, 8,10,10,11,11,12,12,12,12, 0,11,
605.8202 +        12, 9, 8,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
605.8203 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8204 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8205 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8206 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8207 +         0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8208 +};
605.8209 +
605.8210 +static const static_codebook _44c6_s_p6_0 = {
605.8211 +        2, 169,
605.8212 +        (long *)_vq_lengthlist__44c6_s_p6_0,
605.8213 +        1, -526516224, 1616117760, 4, 0,
605.8214 +        (long *)_vq_quantlist__44c6_s_p6_0,
605.8215 +        0
605.8216 +};
605.8217 +
605.8218 +static const long _vq_quantlist__44c6_s_p6_1[] = {
605.8219 +        2,
605.8220 +        1,
605.8221 +        3,
605.8222 +        0,
605.8223 +        4,
605.8224 +};
605.8225 +
605.8226 +static const long _vq_lengthlist__44c6_s_p6_1[] = {
605.8227 +         3, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 6,
605.8228 +         5, 5, 5, 5, 6, 6, 6, 5, 5,
605.8229 +};
605.8230 +
605.8231 +static const static_codebook _44c6_s_p6_1 = {
605.8232 +        2, 25,
605.8233 +        (long *)_vq_lengthlist__44c6_s_p6_1,
605.8234 +        1, -533725184, 1611661312, 3, 0,
605.8235 +        (long *)_vq_quantlist__44c6_s_p6_1,
605.8236 +        0
605.8237 +};
605.8238 +
605.8239 +static const long _vq_quantlist__44c6_s_p7_0[] = {
605.8240 +        6,
605.8241 +        5,
605.8242 +        7,
605.8243 +        4,
605.8244 +        8,
605.8245 +        3,
605.8246 +        9,
605.8247 +        2,
605.8248 +        10,
605.8249 +        1,
605.8250 +        11,
605.8251 +        0,
605.8252 +        12,
605.8253 +};
605.8254 +
605.8255 +static const long _vq_lengthlist__44c6_s_p7_0[] = {
605.8256 +         1, 4, 4, 6, 6, 8, 8, 8, 8,10,10,11,10, 6, 5, 5,
605.8257 +         7, 7, 8, 8, 9, 9,10,10,12,11, 6, 5, 5, 7, 7, 8,
605.8258 +         8, 9, 9,10,10,12,11,21, 7, 7, 7, 7, 9, 9,10,10,
605.8259 +        11,11,12,12,21, 7, 7, 7, 7, 9, 9,10,10,11,11,12,
605.8260 +        12,21,12,12, 9, 9,10,10,11,11,11,11,12,12,21,12,
605.8261 +        12, 9, 9,10,10,11,11,12,12,12,12,21,21,21,11,11,
605.8262 +        10,10,11,12,12,12,13,13,21,21,21,11,11,10,10,12,
605.8263 +        12,12,12,13,13,21,21,21,15,15,11,11,12,12,13,13,
605.8264 +        13,13,21,21,21,15,16,11,11,12,12,13,13,14,14,21,
605.8265 +        21,21,21,20,13,13,13,13,13,13,14,14,20,20,20,20,
605.8266 +        20,13,13,13,13,13,13,14,14,
605.8267 +};
605.8268 +
605.8269 +static const static_codebook _44c6_s_p7_0 = {
605.8270 +        2, 169,
605.8271 +        (long *)_vq_lengthlist__44c6_s_p7_0,
605.8272 +        1, -523206656, 1618345984, 4, 0,
605.8273 +        (long *)_vq_quantlist__44c6_s_p7_0,
605.8274 +        0
605.8275 +};
605.8276 +
605.8277 +static const long _vq_quantlist__44c6_s_p7_1[] = {
605.8278 +        5,
605.8279 +        4,
605.8280 +        6,
605.8281 +        3,
605.8282 +        7,
605.8283 +        2,
605.8284 +        8,
605.8285 +        1,
605.8286 +        9,
605.8287 +        0,
605.8288 +        10,
605.8289 +};
605.8290 +
605.8291 +static const long _vq_lengthlist__44c6_s_p7_1[] = {
605.8292 +         3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 9, 5, 5, 6, 6,
605.8293 +         7, 7, 7, 7, 8, 7, 8, 5, 5, 6, 6, 7, 7, 7, 7, 7,
605.8294 +         7, 9, 6, 6, 7, 7, 7, 7, 8, 7, 7, 8, 9, 9, 9, 7,
605.8295 +         7, 7, 7, 7, 7, 7, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8,
605.8296 +         8, 8, 9, 9, 9, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9,
605.8297 +         8, 8, 8, 8, 7, 7, 8, 8, 9, 9, 9, 9, 8, 8, 8, 7,
605.8298 +         7, 8, 8, 9, 9, 9, 8, 8, 8, 8, 7, 7, 8, 8, 9, 9,
605.8299 +         9, 8, 8, 7, 7, 7, 7, 8, 8,
605.8300 +};
605.8301 +
605.8302 +static const static_codebook _44c6_s_p7_1 = {
605.8303 +        2, 121,
605.8304 +        (long *)_vq_lengthlist__44c6_s_p7_1,
605.8305 +        1, -531365888, 1611661312, 4, 0,
605.8306 +        (long *)_vq_quantlist__44c6_s_p7_1,
605.8307 +        0
605.8308 +};
605.8309 +
605.8310 +static const long _vq_quantlist__44c6_s_p8_0[] = {
605.8311 +        7,
605.8312 +        6,
605.8313 +        8,
605.8314 +        5,
605.8315 +        9,
605.8316 +        4,
605.8317 +        10,
605.8318 +        3,
605.8319 +        11,
605.8320 +        2,
605.8321 +        12,
605.8322 +        1,
605.8323 +        13,
605.8324 +        0,
605.8325 +        14,
605.8326 +};
605.8327 +
605.8328 +static const long _vq_lengthlist__44c6_s_p8_0[] = {
605.8329 +         1, 4, 4, 7, 7, 8, 8, 7, 7, 8, 7, 9, 8,10, 9, 6,
605.8330 +         5, 5, 8, 8, 9, 9, 8, 8, 9, 9,11,10,11,10, 6, 5,
605.8331 +         5, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,11,18, 8, 8,
605.8332 +         9, 8,10,10, 9, 9,10,10,10,10,11,10,18, 8, 8, 9,
605.8333 +         9,10,10, 9, 9,10,10,11,11,12,12,18,12,13, 9,10,
605.8334 +        10,10, 9,10,10,10,11,11,12,11,18,13,13, 9, 9,10,
605.8335 +        10,10,10,10,10,11,11,12,12,18,18,18,10,10, 9, 9,
605.8336 +        11,11,11,11,11,12,12,12,18,18,18,10, 9,10, 9,11,
605.8337 +        10,11,11,11,11,13,12,18,18,18,14,13,10,10,11,11,
605.8338 +        12,12,12,12,12,12,18,18,18,14,13,10,10,11,10,12,
605.8339 +        12,12,12,12,12,18,18,18,18,18,12,12,11,11,12,12,
605.8340 +        13,13,13,14,18,18,18,18,18,12,12,11,11,12,11,13,
605.8341 +        13,14,13,18,18,18,18,18,16,16,11,12,12,13,13,13,
605.8342 +        14,13,18,18,18,18,18,16,15,12,11,12,11,13,11,15,
605.8343 +        14,
605.8344 +};
605.8345 +
605.8346 +static const static_codebook _44c6_s_p8_0 = {
605.8347 +        2, 225,
605.8348 +        (long *)_vq_lengthlist__44c6_s_p8_0,
605.8349 +        1, -520986624, 1620377600, 4, 0,
605.8350 +        (long *)_vq_quantlist__44c6_s_p8_0,
605.8351 +        0
605.8352 +};
605.8353 +
605.8354 +static const long _vq_quantlist__44c6_s_p8_1[] = {
605.8355 +        10,
605.8356 +        9,
605.8357 +        11,
605.8358 +        8,
605.8359 +        12,
605.8360 +        7,
605.8361 +        13,
605.8362 +        6,
605.8363 +        14,
605.8364 +        5,
605.8365 +        15,
605.8366 +        4,
605.8367 +        16,
605.8368 +        3,
605.8369 +        17,
605.8370 +        2,
605.8371 +        18,
605.8372 +        1,
605.8373 +        19,
605.8374 +        0,
605.8375 +        20,
605.8376 +};
605.8377 +
605.8378 +static const long _vq_lengthlist__44c6_s_p8_1[] = {
605.8379 +         3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 8, 8, 8,
605.8380 +         8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,
605.8381 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8,
605.8382 +         8, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,10,
605.8383 +         7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.8384 +         9, 9, 9, 9,10,11,11, 8, 7, 8, 8, 8, 9, 9, 9, 9,
605.8385 +         9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,11, 8, 8, 8, 8,
605.8386 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,
605.8387 +        11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.8388 +         9, 9, 9,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.8389 +         9, 9, 9, 9, 9, 9, 9, 9,11,11,11,11,11, 9, 9, 9,
605.8390 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,11,11,11,
605.8391 +        11,11, 9, 9, 9, 9, 9, 9,10, 9, 9,10, 9,10, 9, 9,
605.8392 +        10, 9,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9,10,10,
605.8393 +        10,10, 9,10,10, 9,10,11,11,11,11,11, 9, 9, 9, 9,
605.8394 +        10,10,10, 9,10,10,10,10, 9,10,10, 9,11,11,11,11,
605.8395 +        11,11,11, 9, 9, 9, 9,10,10,10,10, 9,10,10,10,10,
605.8396 +        10,11,11,11,11,11,11,11,10, 9,10,10,10,10,10,10,
605.8397 +        10, 9,10, 9,10,10,11,11,11,11,11,11,11,10, 9,10,
605.8398 +         9,10,10, 9,10,10,10,10,10,10,10,11,11,11,11,11,
605.8399 +        11,11,10,10,10,10,10,10,10, 9,10,10,10,10,10, 9,
605.8400 +        11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
605.8401 +        10,10,10,10,10,11,11,11,11,11,11,11,11,11,10,10,
605.8402 +        10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
605.8403 +        11,11,11,10,10,10,10,10,10,10,10,10, 9,10,10,11,
605.8404 +        11,11,11,11,11,11,11,11,10,10,10, 9,10,10,10,10,
605.8405 +        10,10,10,10,10,11,11,11,11,11,11,11,11,10,11, 9,
605.8406 +        10,10,10,10,10,10,10,10,10,
605.8407 +};
605.8408 +
605.8409 +static const static_codebook _44c6_s_p8_1 = {
605.8410 +        2, 441,
605.8411 +        (long *)_vq_lengthlist__44c6_s_p8_1,
605.8412 +        1, -529268736, 1611661312, 5, 0,
605.8413 +        (long *)_vq_quantlist__44c6_s_p8_1,
605.8414 +        0
605.8415 +};
605.8416 +
605.8417 +static const long _vq_quantlist__44c6_s_p9_0[] = {
605.8418 +        6,
605.8419 +        5,
605.8420 +        7,
605.8421 +        4,
605.8422 +        8,
605.8423 +        3,
605.8424 +        9,
605.8425 +        2,
605.8426 +        10,
605.8427 +        1,
605.8428 +        11,
605.8429 +        0,
605.8430 +        12,
605.8431 +};
605.8432 +
605.8433 +static const long _vq_lengthlist__44c6_s_p9_0[] = {
605.8434 +         1, 3, 3,11,11,11,11,11,11,11,11,11,11, 4, 7, 7,
605.8435 +        11,11,11,11,11,11,11,11,11,11, 5, 8, 9,11,11,11,
605.8436 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.8437 +        11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,
605.8438 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.8439 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.8440 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.8441 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.8442 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.8443 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.8444 +        10,10,10,10,10,10,10,10,10,
605.8445 +};
605.8446 +
605.8447 +static const static_codebook _44c6_s_p9_0 = {
605.8448 +        2, 169,
605.8449 +        (long *)_vq_lengthlist__44c6_s_p9_0,
605.8450 +        1, -511845376, 1630791680, 4, 0,
605.8451 +        (long *)_vq_quantlist__44c6_s_p9_0,
605.8452 +        0
605.8453 +};
605.8454 +
605.8455 +static const long _vq_quantlist__44c6_s_p9_1[] = {
605.8456 +        6,
605.8457 +        5,
605.8458 +        7,
605.8459 +        4,
605.8460 +        8,
605.8461 +        3,
605.8462 +        9,
605.8463 +        2,
605.8464 +        10,
605.8465 +        1,
605.8466 +        11,
605.8467 +        0,
605.8468 +        12,
605.8469 +};
605.8470 +
605.8471 +static const long _vq_lengthlist__44c6_s_p9_1[] = {
605.8472 +         1, 4, 4, 7, 7, 7, 7, 7, 6, 8, 8, 8, 8, 6, 6, 6,
605.8473 +         8, 8, 8, 8, 8, 7, 9, 8,10,10, 5, 6, 6, 8, 8, 9,
605.8474 +         9, 8, 8,10,10,10,10,16, 9, 9, 9, 9, 9, 9, 9, 8,
605.8475 +        10, 9,11,11,16, 8, 9, 9, 9, 9, 9, 9, 9,10,10,11,
605.8476 +        11,16,13,13, 9, 9,10, 9, 9,10,11,11,11,12,16,13,
605.8477 +        14, 9, 8,10, 8, 9, 9,10,10,12,11,16,14,16, 9, 9,
605.8478 +         9, 9,11,11,12,11,12,11,16,16,16, 9, 7, 9, 6,11,
605.8479 +        11,11,10,11,11,16,16,16,11,12, 9,10,11,11,12,11,
605.8480 +        13,13,16,16,16,12,11,10, 7,12,10,12,12,12,12,16,
605.8481 +        16,15,16,16,10,11,10,11,13,13,14,12,16,16,16,15,
605.8482 +        15,12,10,11,11,13,11,12,13,
605.8483 +};
605.8484 +
605.8485 +static const static_codebook _44c6_s_p9_1 = {
605.8486 +        2, 169,
605.8487 +        (long *)_vq_lengthlist__44c6_s_p9_1,
605.8488 +        1, -518889472, 1622704128, 4, 0,
605.8489 +        (long *)_vq_quantlist__44c6_s_p9_1,
605.8490 +        0
605.8491 +};
605.8492 +
605.8493 +static const long _vq_quantlist__44c6_s_p9_2[] = {
605.8494 +        24,
605.8495 +        23,
605.8496 +        25,
605.8497 +        22,
605.8498 +        26,
605.8499 +        21,
605.8500 +        27,
605.8501 +        20,
605.8502 +        28,
605.8503 +        19,
605.8504 +        29,
605.8505 +        18,
605.8506 +        30,
605.8507 +        17,
605.8508 +        31,
605.8509 +        16,
605.8510 +        32,
605.8511 +        15,
605.8512 +        33,
605.8513 +        14,
605.8514 +        34,
605.8515 +        13,
605.8516 +        35,
605.8517 +        12,
605.8518 +        36,
605.8519 +        11,
605.8520 +        37,
605.8521 +        10,
605.8522 +        38,
605.8523 +        9,
605.8524 +        39,
605.8525 +        8,
605.8526 +        40,
605.8527 +        7,
605.8528 +        41,
605.8529 +        6,
605.8530 +        42,
605.8531 +        5,
605.8532 +        43,
605.8533 +        4,
605.8534 +        44,
605.8535 +        3,
605.8536 +        45,
605.8537 +        2,
605.8538 +        46,
605.8539 +        1,
605.8540 +        47,
605.8541 +        0,
605.8542 +        48,
605.8543 +};
605.8544 +
605.8545 +static const long _vq_lengthlist__44c6_s_p9_2[] = {
605.8546 +         2, 4, 3, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
605.8547 +         6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.8548 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.8549 +         7,
605.8550 +};
605.8551 +
605.8552 +static const static_codebook _44c6_s_p9_2 = {
605.8553 +        1, 49,
605.8554 +        (long *)_vq_lengthlist__44c6_s_p9_2,
605.8555 +        1, -526909440, 1611661312, 6, 0,
605.8556 +        (long *)_vq_quantlist__44c6_s_p9_2,
605.8557 +        0
605.8558 +};
605.8559 +
605.8560 +static const long _huff_lengthlist__44c6_s_short[] = {
605.8561 +         3, 9,11,11,13,14,19,17,17,19, 5, 4, 5, 8,10,10,
605.8562 +        13,16,18,19, 7, 4, 4, 5, 8, 9,12,14,17,19, 8, 6,
605.8563 +         5, 5, 7, 7,10,13,16,18,10, 8, 7, 6, 5, 5, 8,11,
605.8564 +        17,19,11, 9, 7, 7, 5, 4, 5, 8,17,19,13,11, 8, 7,
605.8565 +         7, 5, 5, 7,16,18,14,13, 8, 6, 6, 5, 5, 7,16,18,
605.8566 +        18,16,10, 8, 8, 7, 7, 9,16,18,18,18,12,10,10, 9,
605.8567 +         9,10,17,18,
605.8568 +};
605.8569 +
605.8570 +static const static_codebook _huff_book__44c6_s_short = {
605.8571 +        2, 100,
605.8572 +        (long *)_huff_lengthlist__44c6_s_short,
605.8573 +        0, 0, 0, 0, 0,
605.8574 +        NULL,
605.8575 +        0
605.8576 +};
605.8577 +
605.8578 +static const long _huff_lengthlist__44c7_s_long[] = {
605.8579 +         3, 8,11,13,15,14,14,13,15,14, 6, 4, 5, 7, 9,10,
605.8580 +        11,11,14,13,10, 4, 3, 5, 7, 8, 9,10,13,13,12, 7,
605.8581 +         4, 4, 5, 6, 8, 9,12,14,13, 9, 6, 5, 5, 6, 8, 9,
605.8582 +        12,14,12, 9, 7, 6, 5, 5, 6, 8,11,11,12,11, 9, 8,
605.8583 +         7, 6, 6, 7,10,11,13,11,10, 9, 8, 7, 6, 6, 9,11,
605.8584 +        13,13,12,12,12,10, 9, 8, 9,11,12,14,15,15,14,12,
605.8585 +        11,10,10,12,
605.8586 +};
605.8587 +
605.8588 +static const static_codebook _huff_book__44c7_s_long = {
605.8589 +        2, 100,
605.8590 +        (long *)_huff_lengthlist__44c7_s_long,
605.8591 +        0, 0, 0, 0, 0,
605.8592 +        NULL,
605.8593 +        0
605.8594 +};
605.8595 +
605.8596 +static const long _vq_quantlist__44c7_s_p1_0[] = {
605.8597 +        1,
605.8598 +        0,
605.8599 +        2,
605.8600 +};
605.8601 +
605.8602 +static const long _vq_lengthlist__44c7_s_p1_0[] = {
605.8603 +         1, 5, 5, 0, 5, 5, 0, 5, 5, 5, 8, 7, 0, 9, 9, 0,
605.8604 +         9, 8, 5, 7, 8, 0, 9, 9, 0, 8, 9, 0, 0, 0, 0, 0,
605.8605 +         0, 0, 0, 0, 5, 9, 9, 0, 8, 8, 0, 8, 8, 5, 8, 9,
605.8606 +         0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
605.8607 +         9, 9, 0, 8, 8, 0, 8, 8, 5, 8, 9, 0, 8, 8, 0, 8,
605.8608 +         8,
605.8609 +};
605.8610 +
605.8611 +static const static_codebook _44c7_s_p1_0 = {
605.8612 +        4, 81,
605.8613 +        (long *)_vq_lengthlist__44c7_s_p1_0,
605.8614 +        1, -535822336, 1611661312, 2, 0,
605.8615 +        (long *)_vq_quantlist__44c7_s_p1_0,
605.8616 +        0
605.8617 +};
605.8618 +
605.8619 +static const long _vq_quantlist__44c7_s_p2_0[] = {
605.8620 +        2,
605.8621 +        1,
605.8622 +        3,
605.8623 +        0,
605.8624 +        4,
605.8625 +};
605.8626 +
605.8627 +static const long _vq_lengthlist__44c7_s_p2_0[] = {
605.8628 +         3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0,
605.8629 +         7, 7, 9, 9, 0, 0, 0, 9, 9, 5, 7, 7, 9, 9, 0, 8,
605.8630 +         8,10,10, 0, 8, 7,10, 9, 0,10,10,11,11, 0, 0, 0,
605.8631 +        11,11, 5, 7, 7, 9, 9, 0, 8, 8,10,10, 0, 7, 8, 9,
605.8632 +        10, 0,10,10,11,11, 0, 0, 0,11,11, 8, 9, 9,11,10,
605.8633 +         0,11,11,12,12, 0,11,10,12,12, 0,13,14,14,14, 0,
605.8634 +         0, 0,14,13, 8, 9, 9,10,11, 0,11,11,12,12, 0,10,
605.8635 +        11,12,12, 0,13,13,14,14, 0, 0, 0,13,14, 0, 0, 0,
605.8636 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8637 +         0, 0, 0, 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10,
605.8638 +         0, 7, 7,10,10, 0, 9, 9,11,10, 0, 0, 0,11,11, 5,
605.8639 +         7, 8,10,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9,
605.8640 +         9,10,11, 0, 0, 0,11,11, 8,10, 9,12,12, 0,10,10,
605.8641 +        12,12, 0,10,10,12,12, 0,12,12,13,13, 0, 0, 0,13,
605.8642 +        13, 8, 9,10,12,12, 0,10,10,12,12, 0,10,10,11,12,
605.8643 +         0,12,12,13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0,
605.8644 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8645 +         0, 0, 0, 5, 8, 8,11,11, 0, 7, 7,10,10, 0, 7, 7,
605.8646 +        10,10, 0, 9, 9,10,11, 0, 0, 0,11,10, 5, 8, 8,10,
605.8647 +        11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 9,11,10,
605.8648 +         0, 0, 0,10,11, 9,10,10,12,12, 0,10,10,12,12, 0,
605.8649 +        10,10,12,12, 0,12,13,13,13, 0, 0, 0,13,12, 9,10,
605.8650 +        10,12,12, 0,10,10,12,12, 0,10,10,12,12, 0,13,12,
605.8651 +        13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8652 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8653 +         7,10,10,14,13, 0, 9, 9,12,12, 0, 9, 9,12,12, 0,
605.8654 +        10,10,12,12, 0, 0, 0,12,12, 7,10,10,13,14, 0, 9,
605.8655 +         9,12,13, 0, 9, 9,12,12, 0,10,10,12,12, 0, 0, 0,
605.8656 +        12,12, 9,11,11,14,13, 0,11,10,13,12, 0,11,11,13,
605.8657 +        13, 0,12,12,13,13, 0, 0, 0,13,13, 9,11,11,13,14,
605.8658 +         0,10,11,12,13, 0,11,11,13,13, 0,12,12,13,13, 0,
605.8659 +         0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8660 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8661 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8662 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8663 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
605.8664 +        11,11,14,14, 0,10,11,13,13, 0,11,10,13,13, 0,12,
605.8665 +        12,13,13, 0, 0, 0,13,12, 9,11,11,14,14, 0,11,10,
605.8666 +        13,13, 0,10,11,13,13, 0,12,12,14,13, 0, 0, 0,13,
605.8667 +        13,
605.8668 +};
605.8669 +
605.8670 +static const static_codebook _44c7_s_p2_0 = {
605.8671 +        4, 625,
605.8672 +        (long *)_vq_lengthlist__44c7_s_p2_0,
605.8673 +        1, -533725184, 1611661312, 3, 0,
605.8674 +        (long *)_vq_quantlist__44c7_s_p2_0,
605.8675 +        0
605.8676 +};
605.8677 +
605.8678 +static const long _vq_quantlist__44c7_s_p3_0[] = {
605.8679 +        4,
605.8680 +        3,
605.8681 +        5,
605.8682 +        2,
605.8683 +        6,
605.8684 +        1,
605.8685 +        7,
605.8686 +        0,
605.8687 +        8,
605.8688 +};
605.8689 +
605.8690 +static const long _vq_lengthlist__44c7_s_p3_0[] = {
605.8691 +         2, 4, 4, 5, 5, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7,
605.8692 +         9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 6, 6,
605.8693 +         8, 8,10,10, 0, 0, 0, 6, 6, 8, 8,10,10, 0, 0, 0,
605.8694 +         7, 7, 9, 9,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0,
605.8695 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8696 +         0,
605.8697 +};
605.8698 +
605.8699 +static const static_codebook _44c7_s_p3_0 = {
605.8700 +        2, 81,
605.8701 +        (long *)_vq_lengthlist__44c7_s_p3_0,
605.8702 +        1, -531628032, 1611661312, 4, 0,
605.8703 +        (long *)_vq_quantlist__44c7_s_p3_0,
605.8704 +        0
605.8705 +};
605.8706 +
605.8707 +static const long _vq_quantlist__44c7_s_p4_0[] = {
605.8708 +        8,
605.8709 +        7,
605.8710 +        9,
605.8711 +        6,
605.8712 +        10,
605.8713 +        5,
605.8714 +        11,
605.8715 +        4,
605.8716 +        12,
605.8717 +        3,
605.8718 +        13,
605.8719 +        2,
605.8720 +        14,
605.8721 +        1,
605.8722 +        15,
605.8723 +        0,
605.8724 +        16,
605.8725 +};
605.8726 +
605.8727 +static const long _vq_lengthlist__44c7_s_p4_0[] = {
605.8728 +         3, 4, 4, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
605.8729 +        11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,
605.8730 +        12,12, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,
605.8731 +        11,12,12, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10,
605.8732 +        11,12,12,12, 0, 0, 0, 6, 6, 8, 7, 9, 9, 9, 9,10,
605.8733 +        10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10,
605.8734 +        11,11,12,12,13,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,
605.8735 +        10,11,11,12,12,12,13, 0, 0, 0, 7, 7, 8, 8, 9, 9,
605.8736 +        10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9,
605.8737 +         9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 0, 0,
605.8738 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8739 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8740 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8741 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8742 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8743 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8744 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8745 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8746 +         0,
605.8747 +};
605.8748 +
605.8749 +static const static_codebook _44c7_s_p4_0 = {
605.8750 +        2, 289,
605.8751 +        (long *)_vq_lengthlist__44c7_s_p4_0,
605.8752 +        1, -529530880, 1611661312, 5, 0,
605.8753 +        (long *)_vq_quantlist__44c7_s_p4_0,
605.8754 +        0
605.8755 +};
605.8756 +
605.8757 +static const long _vq_quantlist__44c7_s_p5_0[] = {
605.8758 +        1,
605.8759 +        0,
605.8760 +        2,
605.8761 +};
605.8762 +
605.8763 +static const long _vq_lengthlist__44c7_s_p5_0[] = {
605.8764 +         1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 7,10,10,10,10,
605.8765 +        10, 9, 4, 6, 6,10,10,10,10, 9,10, 5,10,10, 9,11,
605.8766 +        12,10,11,12, 7,10,10,11,12,12,12,12,12, 7,10,10,
605.8767 +        11,12,12,12,12,12, 6,10,10,10,12,12,11,12,12, 7,
605.8768 +        10,10,12,12,12,12,11,12, 7,10,10,11,12,12,12,12,
605.8769 +        12,
605.8770 +};
605.8771 +
605.8772 +static const static_codebook _44c7_s_p5_0 = {
605.8773 +        4, 81,
605.8774 +        (long *)_vq_lengthlist__44c7_s_p5_0,
605.8775 +        1, -529137664, 1618345984, 2, 0,
605.8776 +        (long *)_vq_quantlist__44c7_s_p5_0,
605.8777 +        0
605.8778 +};
605.8779 +
605.8780 +static const long _vq_quantlist__44c7_s_p5_1[] = {
605.8781 +        5,
605.8782 +        4,
605.8783 +        6,
605.8784 +        3,
605.8785 +        7,
605.8786 +        2,
605.8787 +        8,
605.8788 +        1,
605.8789 +        9,
605.8790 +        0,
605.8791 +        10,
605.8792 +};
605.8793 +
605.8794 +static const long _vq_lengthlist__44c7_s_p5_1[] = {
605.8795 +         3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11, 4, 4, 6, 6,
605.8796 +         7, 7, 8, 8, 9, 9,11, 4, 4, 6, 6, 7, 7, 8, 8, 9,
605.8797 +         9,12, 5, 5, 6, 6, 7, 7, 9, 9, 9, 9,12,12,12, 6,
605.8798 +         6, 7, 7, 9, 9, 9, 9,11,11,11, 7, 7, 7, 7, 8, 8,
605.8799 +         9, 9,11,11,11, 7, 7, 7, 7, 8, 8, 9, 9,11,11,11,
605.8800 +         7, 7, 8, 8, 8, 8, 9, 9,11,11,11,11,11, 8, 8, 8,
605.8801 +         8, 8, 9,11,11,11,11,11, 8, 8, 8, 8, 8, 8,11,11,
605.8802 +        11,11,11, 7, 7, 8, 8, 8, 8,
605.8803 +};
605.8804 +
605.8805 +static const static_codebook _44c7_s_p5_1 = {
605.8806 +        2, 121,
605.8807 +        (long *)_vq_lengthlist__44c7_s_p5_1,
605.8808 +        1, -531365888, 1611661312, 4, 0,
605.8809 +        (long *)_vq_quantlist__44c7_s_p5_1,
605.8810 +        0
605.8811 +};
605.8812 +
605.8813 +static const long _vq_quantlist__44c7_s_p6_0[] = {
605.8814 +        6,
605.8815 +        5,
605.8816 +        7,
605.8817 +        4,
605.8818 +        8,
605.8819 +        3,
605.8820 +        9,
605.8821 +        2,
605.8822 +        10,
605.8823 +        1,
605.8824 +        11,
605.8825 +        0,
605.8826 +        12,
605.8827 +};
605.8828 +
605.8829 +static const long _vq_lengthlist__44c7_s_p6_0[] = {
605.8830 +         1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 8,10,10, 6, 5, 5,
605.8831 +         7, 7, 8, 8, 9, 9, 9,10,11,11, 7, 5, 5, 7, 7, 8,
605.8832 +         8, 9, 9,10,10,11,11, 0, 7, 7, 7, 7, 9, 8, 9, 9,
605.8833 +        10,10,11,11, 0, 8, 8, 7, 7, 8, 9, 9, 9,10,10,11,
605.8834 +        11, 0,11,11, 9, 9,10,10,11,10,11,11,12,12, 0,12,
605.8835 +        12, 9, 9,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0,
605.8836 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8837 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8838 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8839 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8840 +         0, 0, 0, 0, 0, 0, 0, 0, 0,
605.8841 +};
605.8842 +
605.8843 +static const static_codebook _44c7_s_p6_0 = {
605.8844 +        2, 169,
605.8845 +        (long *)_vq_lengthlist__44c7_s_p6_0,
605.8846 +        1, -526516224, 1616117760, 4, 0,
605.8847 +        (long *)_vq_quantlist__44c7_s_p6_0,
605.8848 +        0
605.8849 +};
605.8850 +
605.8851 +static const long _vq_quantlist__44c7_s_p6_1[] = {
605.8852 +        2,
605.8853 +        1,
605.8854 +        3,
605.8855 +        0,
605.8856 +        4,
605.8857 +};
605.8858 +
605.8859 +static const long _vq_lengthlist__44c7_s_p6_1[] = {
605.8860 +         3, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 6,
605.8861 +         5, 5, 5, 5, 6, 6, 6, 5, 5,
605.8862 +};
605.8863 +
605.8864 +static const static_codebook _44c7_s_p6_1 = {
605.8865 +        2, 25,
605.8866 +        (long *)_vq_lengthlist__44c7_s_p6_1,
605.8867 +        1, -533725184, 1611661312, 3, 0,
605.8868 +        (long *)_vq_quantlist__44c7_s_p6_1,
605.8869 +        0
605.8870 +};
605.8871 +
605.8872 +static const long _vq_quantlist__44c7_s_p7_0[] = {
605.8873 +        6,
605.8874 +        5,
605.8875 +        7,
605.8876 +        4,
605.8877 +        8,
605.8878 +        3,
605.8879 +        9,
605.8880 +        2,
605.8881 +        10,
605.8882 +        1,
605.8883 +        11,
605.8884 +        0,
605.8885 +        12,
605.8886 +};
605.8887 +
605.8888 +static const long _vq_lengthlist__44c7_s_p7_0[] = {
605.8889 +         1, 4, 4, 6, 6, 7, 8, 9, 9,10,10,12,11, 6, 5, 5,
605.8890 +         7, 7, 8, 8, 9,10,11,11,12,12, 7, 5, 5, 7, 7, 8,
605.8891 +         8,10,10,11,11,12,12,20, 7, 7, 7, 7, 8, 9,10,10,
605.8892 +        11,11,12,13,20, 7, 7, 7, 7, 9, 9,10,10,11,12,13,
605.8893 +        13,20,11,11, 8, 8, 9, 9,11,11,12,12,13,13,20,11,
605.8894 +        11, 8, 8, 9, 9,11,11,12,12,13,13,20,20,20,10,10,
605.8895 +        10,10,12,12,13,13,13,13,20,20,20,10,10,10,10,12,
605.8896 +        12,13,13,13,14,20,20,20,14,14,11,11,12,12,13,13,
605.8897 +        14,14,20,20,20,14,14,11,11,12,12,13,13,14,14,20,
605.8898 +        20,20,20,19,13,13,13,13,14,14,15,14,19,19,19,19,
605.8899 +        19,13,13,13,13,14,14,15,15,
605.8900 +};
605.8901 +
605.8902 +static const static_codebook _44c7_s_p7_0 = {
605.8903 +        2, 169,
605.8904 +        (long *)_vq_lengthlist__44c7_s_p7_0,
605.8905 +        1, -523206656, 1618345984, 4, 0,
605.8906 +        (long *)_vq_quantlist__44c7_s_p7_0,
605.8907 +        0
605.8908 +};
605.8909 +
605.8910 +static const long _vq_quantlist__44c7_s_p7_1[] = {
605.8911 +        5,
605.8912 +        4,
605.8913 +        6,
605.8914 +        3,
605.8915 +        7,
605.8916 +        2,
605.8917 +        8,
605.8918 +        1,
605.8919 +        9,
605.8920 +        0,
605.8921 +        10,
605.8922 +};
605.8923 +
605.8924 +static const long _vq_lengthlist__44c7_s_p7_1[] = {
605.8925 +         4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 6, 6, 7, 7,
605.8926 +         7, 7, 7, 7, 7, 7, 8, 6, 6, 6, 7, 7, 7, 7, 7, 7,
605.8927 +         7, 8, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7,
605.8928 +         7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7,
605.8929 +         7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
605.8930 +         7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7,
605.8931 +         7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8,
605.8932 +         8, 8, 8, 7, 7, 7, 7, 7, 7,
605.8933 +};
605.8934 +
605.8935 +static const static_codebook _44c7_s_p7_1 = {
605.8936 +        2, 121,
605.8937 +        (long *)_vq_lengthlist__44c7_s_p7_1,
605.8938 +        1, -531365888, 1611661312, 4, 0,
605.8939 +        (long *)_vq_quantlist__44c7_s_p7_1,
605.8940 +        0
605.8941 +};
605.8942 +
605.8943 +static const long _vq_quantlist__44c7_s_p8_0[] = {
605.8944 +        7,
605.8945 +        6,
605.8946 +        8,
605.8947 +        5,
605.8948 +        9,
605.8949 +        4,
605.8950 +        10,
605.8951 +        3,
605.8952 +        11,
605.8953 +        2,
605.8954 +        12,
605.8955 +        1,
605.8956 +        13,
605.8957 +        0,
605.8958 +        14,
605.8959 +};
605.8960 +
605.8961 +static const long _vq_lengthlist__44c7_s_p8_0[] = {
605.8962 +         1, 4, 4, 7, 7, 8, 8, 8, 7, 9, 8, 9, 9,10,10, 6,
605.8963 +         5, 5, 7, 7, 9, 9, 8, 8,10, 9,11,10,12,11, 6, 5,
605.8964 +         5, 8, 7, 9, 9, 8, 8,10,10,11,11,12,11,19, 8, 8,
605.8965 +         8, 8,10,10, 9, 9,10,10,11,11,12,11,19, 8, 8, 8,
605.8966 +         8,10,10, 9, 9,10,10,11,11,12,12,19,12,12, 9, 9,
605.8967 +        10,10, 9,10,10,10,11,11,12,12,19,12,12, 9, 9,10,
605.8968 +        10,10,10,10,10,12,12,12,12,19,19,19, 9, 9, 9, 9,
605.8969 +        11,10,11,11,12,11,13,13,19,19,19, 9, 9, 9, 9,11,
605.8970 +        10,11,11,11,12,13,13,19,19,19,13,13,10,10,11,11,
605.8971 +        12,12,12,12,13,12,19,19,19,14,13,10,10,11,11,12,
605.8972 +        12,12,13,13,13,19,19,19,19,19,12,12,12,11,12,13,
605.8973 +        14,13,13,13,19,19,19,19,19,12,12,12,11,12,12,13,
605.8974 +        14,13,14,19,19,19,19,19,16,16,12,13,12,13,13,14,
605.8975 +        15,14,19,18,18,18,18,16,15,12,11,12,11,14,12,14,
605.8976 +        14,
605.8977 +};
605.8978 +
605.8979 +static const static_codebook _44c7_s_p8_0 = {
605.8980 +        2, 225,
605.8981 +        (long *)_vq_lengthlist__44c7_s_p8_0,
605.8982 +        1, -520986624, 1620377600, 4, 0,
605.8983 +        (long *)_vq_quantlist__44c7_s_p8_0,
605.8984 +        0
605.8985 +};
605.8986 +
605.8987 +static const long _vq_quantlist__44c7_s_p8_1[] = {
605.8988 +        10,
605.8989 +        9,
605.8990 +        11,
605.8991 +        8,
605.8992 +        12,
605.8993 +        7,
605.8994 +        13,
605.8995 +        6,
605.8996 +        14,
605.8997 +        5,
605.8998 +        15,
605.8999 +        4,
605.9000 +        16,
605.9001 +        3,
605.9002 +        17,
605.9003 +        2,
605.9004 +        18,
605.9005 +        1,
605.9006 +        19,
605.9007 +        0,
605.9008 +        20,
605.9009 +};
605.9010 +
605.9011 +static const long _vq_lengthlist__44c7_s_p8_1[] = {
605.9012 +         3, 5, 5, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.9013 +         8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
605.9014 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8,
605.9015 +         8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,
605.9016 +         7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.9017 +         9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, 9,
605.9018 +         9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 9,
605.9019 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,
605.9020 +        10, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.9021 +         9, 9, 9,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.9022 +         9, 9, 9, 9, 9, 9, 9, 9,10,11,10,10,10, 9, 9, 9,
605.9023 +         9, 9, 9, 9, 9, 9, 9,10, 9, 9,10, 9, 9,10,11,10,
605.9024 +        11,10, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9,10, 9, 9,
605.9025 +         9, 9,11,10,11,10,10, 9, 9, 9, 9, 9, 9,10, 9, 9,
605.9026 +        10, 9, 9,10, 9, 9,10,11,10,10,11,10, 9, 9, 9, 9,
605.9027 +         9,10,10, 9,10,10,10,10, 9,10,10,10,10,10,10,11,
605.9028 +        11,11,10, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,
605.9029 +        10,10,10,11,11,10,10,10,10,10,10,10,10,10,10,10,
605.9030 +        10, 9,10,10, 9,10,11,11,10,11,10,11,10, 9,10,10,
605.9031 +         9,10,10,10,10,10,10,10,10,10,10,11,11,11,11,10,
605.9032 +        11,11,10,10,10,10,10,10, 9,10, 9,10,10, 9,10, 9,
605.9033 +        10,10,10,11,10,11,10,11,11,10,10,10,10,10,10, 9,
605.9034 +        10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,10,
605.9035 +        10,10,10,10,10,10,10,10,10,10,10,10,10,11,10,11,
605.9036 +        11,10,10,10,10, 9, 9,10,10, 9, 9,10, 9,10,10,10,
605.9037 +        10,11,11,10,10,10,10,10,10,10, 9, 9,10,10,10, 9,
605.9038 +         9,10,10,10,10,10,11,10,11,10,10,10,10,10,10, 9,
605.9039 +        10,10,10,10,10,10,10,10,10,
605.9040 +};
605.9041 +
605.9042 +static const static_codebook _44c7_s_p8_1 = {
605.9043 +        2, 441,
605.9044 +        (long *)_vq_lengthlist__44c7_s_p8_1,
605.9045 +        1, -529268736, 1611661312, 5, 0,
605.9046 +        (long *)_vq_quantlist__44c7_s_p8_1,
605.9047 +        0
605.9048 +};
605.9049 +
605.9050 +static const long _vq_quantlist__44c7_s_p9_0[] = {
605.9051 +        6,
605.9052 +        5,
605.9053 +        7,
605.9054 +        4,
605.9055 +        8,
605.9056 +        3,
605.9057 +        9,
605.9058 +        2,
605.9059 +        10,
605.9060 +        1,
605.9061 +        11,
605.9062 +        0,
605.9063 +        12,
605.9064 +};
605.9065 +
605.9066 +static const long _vq_lengthlist__44c7_s_p9_0[] = {
605.9067 +         1, 3, 3,11,11,11,11,11,11,11,11,11,11, 4, 6, 6,
605.9068 +        11,11,11,11,11,11,11,11,11,11, 4, 7, 7,11,11,11,
605.9069 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9070 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9071 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9072 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9073 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9074 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9075 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9076 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9077 +        11,11,11,11,11,11,11,11,11,
605.9078 +};
605.9079 +
605.9080 +static const static_codebook _44c7_s_p9_0 = {
605.9081 +        2, 169,
605.9082 +        (long *)_vq_lengthlist__44c7_s_p9_0,
605.9083 +        1, -511845376, 1630791680, 4, 0,
605.9084 +        (long *)_vq_quantlist__44c7_s_p9_0,
605.9085 +        0
605.9086 +};
605.9087 +
605.9088 +static const long _vq_quantlist__44c7_s_p9_1[] = {
605.9089 +        6,
605.9090 +        5,
605.9091 +        7,
605.9092 +        4,
605.9093 +        8,
605.9094 +        3,
605.9095 +        9,
605.9096 +        2,
605.9097 +        10,
605.9098 +        1,
605.9099 +        11,
605.9100 +        0,
605.9101 +        12,
605.9102 +};
605.9103 +
605.9104 +static const long _vq_lengthlist__44c7_s_p9_1[] = {
605.9105 +         1, 4, 4, 7, 7, 7, 7, 7, 6, 8, 8, 8, 8, 6, 6, 6,
605.9106 +         8, 8, 9, 8, 8, 7, 9, 8,11,10, 5, 6, 6, 8, 8, 9,
605.9107 +         8, 8, 8,10, 9,11,11,16, 8, 8, 9, 8, 9, 9, 9, 8,
605.9108 +        10, 9,11,10,16, 8, 8, 9, 9,10,10, 9, 9,10,10,11,
605.9109 +        11,16,13,13, 9, 9,10,10, 9,10,11,11,12,11,16,13,
605.9110 +        13, 9, 8,10, 9,10,10,10,10,11,11,16,14,16, 8, 9,
605.9111 +         9, 9,11,10,11,11,12,11,16,16,16, 9, 7,10, 7,11,
605.9112 +        10,11,11,12,11,16,16,16,12,12, 9,10,11,11,12,11,
605.9113 +        12,12,16,16,16,12,10,10, 7,11, 8,12,11,12,12,16,
605.9114 +        16,15,16,16,11,12,10,10,12,11,12,12,16,16,16,15,
605.9115 +        15,11,11,10,10,12,12,12,12,
605.9116 +};
605.9117 +
605.9118 +static const static_codebook _44c7_s_p9_1 = {
605.9119 +        2, 169,
605.9120 +        (long *)_vq_lengthlist__44c7_s_p9_1,
605.9121 +        1, -518889472, 1622704128, 4, 0,
605.9122 +        (long *)_vq_quantlist__44c7_s_p9_1,
605.9123 +        0
605.9124 +};
605.9125 +
605.9126 +static const long _vq_quantlist__44c7_s_p9_2[] = {
605.9127 +        24,
605.9128 +        23,
605.9129 +        25,
605.9130 +        22,
605.9131 +        26,
605.9132 +        21,
605.9133 +        27,
605.9134 +        20,
605.9135 +        28,
605.9136 +        19,
605.9137 +        29,
605.9138 +        18,
605.9139 +        30,
605.9140 +        17,
605.9141 +        31,
605.9142 +        16,
605.9143 +        32,
605.9144 +        15,
605.9145 +        33,
605.9146 +        14,
605.9147 +        34,
605.9148 +        13,
605.9149 +        35,
605.9150 +        12,
605.9151 +        36,
605.9152 +        11,
605.9153 +        37,
605.9154 +        10,
605.9155 +        38,
605.9156 +        9,
605.9157 +        39,
605.9158 +        8,
605.9159 +        40,
605.9160 +        7,
605.9161 +        41,
605.9162 +        6,
605.9163 +        42,
605.9164 +        5,
605.9165 +        43,
605.9166 +        4,
605.9167 +        44,
605.9168 +        3,
605.9169 +        45,
605.9170 +        2,
605.9171 +        46,
605.9172 +        1,
605.9173 +        47,
605.9174 +        0,
605.9175 +        48,
605.9176 +};
605.9177 +
605.9178 +static const long _vq_lengthlist__44c7_s_p9_2[] = {
605.9179 +         2, 4, 3, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
605.9180 +         6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.9181 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.9182 +         7,
605.9183 +};
605.9184 +
605.9185 +static const static_codebook _44c7_s_p9_2 = {
605.9186 +        1, 49,
605.9187 +        (long *)_vq_lengthlist__44c7_s_p9_2,
605.9188 +        1, -526909440, 1611661312, 6, 0,
605.9189 +        (long *)_vq_quantlist__44c7_s_p9_2,
605.9190 +        0
605.9191 +};
605.9192 +
605.9193 +static const long _huff_lengthlist__44c7_s_short[] = {
605.9194 +         4,11,12,14,15,15,17,17,18,18, 5, 6, 6, 8, 9,10,
605.9195 +        13,17,18,19, 7, 5, 4, 6, 8, 9,11,15,19,19, 8, 6,
605.9196 +         5, 5, 6, 7,11,14,16,17, 9, 7, 7, 6, 7, 7,10,13,
605.9197 +        15,19,10, 8, 7, 6, 7, 6, 7, 9,14,16,12,10, 9, 7,
605.9198 +         7, 6, 4, 5,10,15,14,13,11, 7, 6, 6, 4, 2, 7,13,
605.9199 +        16,16,15, 9, 8, 8, 8, 6, 9,13,19,19,17,12,11,10,
605.9200 +        10, 9,11,14,
605.9201 +};
605.9202 +
605.9203 +static const static_codebook _huff_book__44c7_s_short = {
605.9204 +        2, 100,
605.9205 +        (long *)_huff_lengthlist__44c7_s_short,
605.9206 +        0, 0, 0, 0, 0,
605.9207 +        NULL,
605.9208 +        0
605.9209 +};
605.9210 +
605.9211 +static const long _huff_lengthlist__44c8_s_long[] = {
605.9212 +         3, 8,12,13,14,14,14,13,14,14, 6, 4, 5, 8,10,10,
605.9213 +        11,11,14,13, 9, 5, 4, 5, 7, 8, 9,10,13,13,12, 7,
605.9214 +         5, 4, 5, 6, 8, 9,12,13,13, 9, 6, 5, 5, 5, 7, 9,
605.9215 +        11,14,12,10, 7, 6, 5, 4, 6, 7,10,11,12,11, 9, 8,
605.9216 +         7, 5, 5, 6,10,10,13,12,10, 9, 8, 6, 6, 5, 8,10,
605.9217 +        14,13,12,12,11,10, 9, 7, 8,10,12,13,14,14,13,12,
605.9218 +        11, 9, 9,10,
605.9219 +};
605.9220 +
605.9221 +static const static_codebook _huff_book__44c8_s_long = {
605.9222 +        2, 100,
605.9223 +        (long *)_huff_lengthlist__44c8_s_long,
605.9224 +        0, 0, 0, 0, 0,
605.9225 +        NULL,
605.9226 +        0
605.9227 +};
605.9228 +
605.9229 +static const long _vq_quantlist__44c8_s_p1_0[] = {
605.9230 +        1,
605.9231 +        0,
605.9232 +        2,
605.9233 +};
605.9234 +
605.9235 +static const long _vq_lengthlist__44c8_s_p1_0[] = {
605.9236 +         1, 5, 5, 0, 5, 5, 0, 5, 5, 5, 7, 7, 0, 9, 8, 0,
605.9237 +         9, 8, 6, 7, 7, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 0,
605.9238 +         0, 0, 0, 0, 5, 9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9,
605.9239 +         0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
605.9240 +         9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9, 0, 8, 8, 0, 8,
605.9241 +         8,
605.9242 +};
605.9243 +
605.9244 +static const static_codebook _44c8_s_p1_0 = {
605.9245 +        4, 81,
605.9246 +        (long *)_vq_lengthlist__44c8_s_p1_0,
605.9247 +        1, -535822336, 1611661312, 2, 0,
605.9248 +        (long *)_vq_quantlist__44c8_s_p1_0,
605.9249 +        0
605.9250 +};
605.9251 +
605.9252 +static const long _vq_quantlist__44c8_s_p2_0[] = {
605.9253 +        2,
605.9254 +        1,
605.9255 +        3,
605.9256 +        0,
605.9257 +        4,
605.9258 +};
605.9259 +
605.9260 +static const long _vq_lengthlist__44c8_s_p2_0[] = {
605.9261 +         3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0,
605.9262 +         7, 7, 9, 9, 0, 0, 0, 9, 9, 5, 7, 7, 9, 9, 0, 8,
605.9263 +         7,10, 9, 0, 8, 7,10, 9, 0,10,10,11,11, 0, 0, 0,
605.9264 +        11,11, 5, 7, 7, 9, 9, 0, 7, 8, 9,10, 0, 7, 8, 9,
605.9265 +        10, 0,10,10,11,11, 0, 0, 0,11,11, 8, 9, 9,11,10,
605.9266 +         0,11,10,12,11, 0,11,10,12,12, 0,13,13,14,14, 0,
605.9267 +         0, 0,14,13, 8, 9, 9,10,11, 0,10,11,12,12, 0,10,
605.9268 +        11,12,12, 0,13,13,14,14, 0, 0, 0,13,14, 0, 0, 0,
605.9269 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9270 +         0, 0, 0, 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10,
605.9271 +         0, 7, 7,10,10, 0, 9, 9,10,10, 0, 0, 0,11,10, 5,
605.9272 +         7, 8,10,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9,
605.9273 +         9,10,10, 0, 0, 0,10,10, 8,10, 9,12,12, 0,10,10,
605.9274 +        12,11, 0,10,10,12,12, 0,12,12,13,12, 0, 0, 0,13,
605.9275 +        12, 8, 9,10,12,12, 0,10,10,11,12, 0,10,10,11,12,
605.9276 +         0,12,12,13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0,
605.9277 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9278 +         0, 0, 0, 6, 8, 7,11,10, 0, 7, 7,10,10, 0, 7, 7,
605.9279 +        10,10, 0, 9, 9,10,11, 0, 0, 0,10,10, 6, 7, 8,10,
605.9280 +        11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 9,10,10,
605.9281 +         0, 0, 0,10,10, 9,10, 9,12,12, 0,10,10,12,12, 0,
605.9282 +        10,10,12,11, 0,12,12,13,13, 0, 0, 0,13,12, 8, 9,
605.9283 +        10,12,12, 0,10,10,12,12, 0,10,10,11,12, 0,12,12,
605.9284 +        13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9285 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9286 +         7,10,10,13,13, 0, 9, 9,12,12, 0, 9, 9,12,12, 0,
605.9287 +        10,10,12,12, 0, 0, 0,12,12, 7,10,10,13,13, 0, 9,
605.9288 +         9,12,12, 0, 9, 9,12,12, 0,10,10,12,12, 0, 0, 0,
605.9289 +        12,12, 9,11,11,14,13, 0,10,10,13,12, 0,11,10,13,
605.9290 +        12, 0,12,12,13,12, 0, 0, 0,13,13, 9,11,11,13,14,
605.9291 +         0,10,11,12,13, 0,10,11,13,13, 0,12,12,12,13, 0,
605.9292 +         0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9293 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9294 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9295 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9296 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
605.9297 +        11,11,14,14, 0,10,11,13,13, 0,11,10,13,13, 0,11,
605.9298 +        12,13,13, 0, 0, 0,13,12, 9,11,11,14,14, 0,11,10,
605.9299 +        13,13, 0,10,11,13,13, 0,12,12,13,13, 0, 0, 0,12,
605.9300 +        13,
605.9301 +};
605.9302 +
605.9303 +static const static_codebook _44c8_s_p2_0 = {
605.9304 +        4, 625,
605.9305 +        (long *)_vq_lengthlist__44c8_s_p2_0,
605.9306 +        1, -533725184, 1611661312, 3, 0,
605.9307 +        (long *)_vq_quantlist__44c8_s_p2_0,
605.9308 +        0
605.9309 +};
605.9310 +
605.9311 +static const long _vq_quantlist__44c8_s_p3_0[] = {
605.9312 +        4,
605.9313 +        3,
605.9314 +        5,
605.9315 +        2,
605.9316 +        6,
605.9317 +        1,
605.9318 +        7,
605.9319 +        0,
605.9320 +        8,
605.9321 +};
605.9322 +
605.9323 +static const long _vq_lengthlist__44c8_s_p3_0[] = {
605.9324 +         2, 4, 4, 5, 5, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7,
605.9325 +         9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 6, 6,
605.9326 +         8, 8,10,10, 0, 0, 0, 6, 6, 8, 8,10,10, 0, 0, 0,
605.9327 +         7, 7, 9, 9,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0,
605.9328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9329 +         0,
605.9330 +};
605.9331 +
605.9332 +static const static_codebook _44c8_s_p3_0 = {
605.9333 +        2, 81,
605.9334 +        (long *)_vq_lengthlist__44c8_s_p3_0,
605.9335 +        1, -531628032, 1611661312, 4, 0,
605.9336 +        (long *)_vq_quantlist__44c8_s_p3_0,
605.9337 +        0
605.9338 +};
605.9339 +
605.9340 +static const long _vq_quantlist__44c8_s_p4_0[] = {
605.9341 +        8,
605.9342 +        7,
605.9343 +        9,
605.9344 +        6,
605.9345 +        10,
605.9346 +        5,
605.9347 +        11,
605.9348 +        4,
605.9349 +        12,
605.9350 +        3,
605.9351 +        13,
605.9352 +        2,
605.9353 +        14,
605.9354 +        1,
605.9355 +        15,
605.9356 +        0,
605.9357 +        16,
605.9358 +};
605.9359 +
605.9360 +static const long _vq_lengthlist__44c8_s_p4_0[] = {
605.9361 +         3, 4, 4, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
605.9362 +        11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 8,10,10,11,11,
605.9363 +        11,11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,
605.9364 +        11,11,11, 0, 6, 5, 6, 6, 7, 7, 9, 9, 9, 9,10,10,
605.9365 +        11,11,12,12, 0, 0, 0, 6, 6, 7, 7, 9, 9, 9, 9,10,
605.9366 +        10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10,
605.9367 +        11,11,11,12,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,
605.9368 +        10,11,11,11,12,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,
605.9369 +        10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9,
605.9370 +         9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 0, 0,
605.9371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9375 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9376 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9377 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9378 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9379 +         0,
605.9380 +};
605.9381 +
605.9382 +static const static_codebook _44c8_s_p4_0 = {
605.9383 +        2, 289,
605.9384 +        (long *)_vq_lengthlist__44c8_s_p4_0,
605.9385 +        1, -529530880, 1611661312, 5, 0,
605.9386 +        (long *)_vq_quantlist__44c8_s_p4_0,
605.9387 +        0
605.9388 +};
605.9389 +
605.9390 +static const long _vq_quantlist__44c8_s_p5_0[] = {
605.9391 +        1,
605.9392 +        0,
605.9393 +        2,
605.9394 +};
605.9395 +
605.9396 +static const long _vq_lengthlist__44c8_s_p5_0[] = {
605.9397 +         1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 7, 6,10,10,10,10,
605.9398 +        10,10, 4, 6, 6,10,10,10,10, 9,10, 5,10,10, 9,11,
605.9399 +        11,10,11,11, 7,10,10,11,12,12,12,12,12, 7,10,10,
605.9400 +        11,12,12,12,12,12, 6,10,10,10,12,12,10,12,12, 7,
605.9401 +        10,10,11,12,12,12,12,12, 7,10,10,11,12,12,12,12,
605.9402 +        12,
605.9403 +};
605.9404 +
605.9405 +static const static_codebook _44c8_s_p5_0 = {
605.9406 +        4, 81,
605.9407 +        (long *)_vq_lengthlist__44c8_s_p5_0,
605.9408 +        1, -529137664, 1618345984, 2, 0,
605.9409 +        (long *)_vq_quantlist__44c8_s_p5_0,
605.9410 +        0
605.9411 +};
605.9412 +
605.9413 +static const long _vq_quantlist__44c8_s_p5_1[] = {
605.9414 +        5,
605.9415 +        4,
605.9416 +        6,
605.9417 +        3,
605.9418 +        7,
605.9419 +        2,
605.9420 +        8,
605.9421 +        1,
605.9422 +        9,
605.9423 +        0,
605.9424 +        10,
605.9425 +};
605.9426 +
605.9427 +static const long _vq_lengthlist__44c8_s_p5_1[] = {
605.9428 +         3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11, 4, 5, 6, 6,
605.9429 +         7, 7, 8, 8, 8, 8,11, 5, 5, 6, 6, 7, 7, 8, 8, 8,
605.9430 +         9,12, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,12,12,12, 6,
605.9431 +         6, 7, 7, 8, 8, 9, 9,11,11,11, 6, 6, 7, 7, 8, 8,
605.9432 +         8, 8,11,11,11, 6, 6, 7, 7, 8, 8, 8, 8,11,11,11,
605.9433 +         7, 7, 7, 8, 8, 8, 8, 8,11,11,11,11,11, 7, 7, 8,
605.9434 +         8, 8, 8,11,11,11,11,11, 7, 7, 7, 7, 8, 8,11,11,
605.9435 +        11,11,11, 7, 7, 7, 7, 8, 8,
605.9436 +};
605.9437 +
605.9438 +static const static_codebook _44c8_s_p5_1 = {
605.9439 +        2, 121,
605.9440 +        (long *)_vq_lengthlist__44c8_s_p5_1,
605.9441 +        1, -531365888, 1611661312, 4, 0,
605.9442 +        (long *)_vq_quantlist__44c8_s_p5_1,
605.9443 +        0
605.9444 +};
605.9445 +
605.9446 +static const long _vq_quantlist__44c8_s_p6_0[] = {
605.9447 +        6,
605.9448 +        5,
605.9449 +        7,
605.9450 +        4,
605.9451 +        8,
605.9452 +        3,
605.9453 +        9,
605.9454 +        2,
605.9455 +        10,
605.9456 +        1,
605.9457 +        11,
605.9458 +        0,
605.9459 +        12,
605.9460 +};
605.9461 +
605.9462 +static const long _vq_lengthlist__44c8_s_p6_0[] = {
605.9463 +         1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5,
605.9464 +         7, 7, 8, 8, 9, 9,10,10,11,11, 6, 5, 5, 7, 7, 8,
605.9465 +         8, 9, 9,10,10,11,11, 0, 7, 7, 7, 7, 9, 9,10,10,
605.9466 +        10,10,11,11, 0, 7, 7, 7, 7, 9, 9,10,10,10,10,11,
605.9467 +        11, 0,11,11, 9, 9,10,10,11,11,11,11,12,12, 0,12,
605.9468 +        12, 9, 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0,
605.9469 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9470 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9471 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9472 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9473 +         0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9474 +};
605.9475 +
605.9476 +static const static_codebook _44c8_s_p6_0 = {
605.9477 +        2, 169,
605.9478 +        (long *)_vq_lengthlist__44c8_s_p6_0,
605.9479 +        1, -526516224, 1616117760, 4, 0,
605.9480 +        (long *)_vq_quantlist__44c8_s_p6_0,
605.9481 +        0
605.9482 +};
605.9483 +
605.9484 +static const long _vq_quantlist__44c8_s_p6_1[] = {
605.9485 +        2,
605.9486 +        1,
605.9487 +        3,
605.9488 +        0,
605.9489 +        4,
605.9490 +};
605.9491 +
605.9492 +static const long _vq_lengthlist__44c8_s_p6_1[] = {
605.9493 +         3, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 6,
605.9494 +         5, 5, 5, 5, 6, 6, 6, 5, 5,
605.9495 +};
605.9496 +
605.9497 +static const static_codebook _44c8_s_p6_1 = {
605.9498 +        2, 25,
605.9499 +        (long *)_vq_lengthlist__44c8_s_p6_1,
605.9500 +        1, -533725184, 1611661312, 3, 0,
605.9501 +        (long *)_vq_quantlist__44c8_s_p6_1,
605.9502 +        0
605.9503 +};
605.9504 +
605.9505 +static const long _vq_quantlist__44c8_s_p7_0[] = {
605.9506 +        6,
605.9507 +        5,
605.9508 +        7,
605.9509 +        4,
605.9510 +        8,
605.9511 +        3,
605.9512 +        9,
605.9513 +        2,
605.9514 +        10,
605.9515 +        1,
605.9516 +        11,
605.9517 +        0,
605.9518 +        12,
605.9519 +};
605.9520 +
605.9521 +static const long _vq_lengthlist__44c8_s_p7_0[] = {
605.9522 +         1, 4, 4, 6, 6, 8, 7, 9, 9,10,10,12,12, 6, 5, 5,
605.9523 +         7, 7, 8, 8,10,10,11,11,12,12, 7, 5, 5, 7, 7, 8,
605.9524 +         8,10,10,11,11,12,12,21, 7, 7, 7, 7, 8, 9,10,10,
605.9525 +        11,11,12,12,21, 7, 7, 7, 7, 9, 9,10,10,12,12,13,
605.9526 +        13,21,11,11, 8, 8, 9, 9,11,11,12,12,13,13,21,11,
605.9527 +        11, 8, 8, 9, 9,11,11,12,12,13,13,21,21,21,10,10,
605.9528 +        10,10,11,11,12,13,13,13,21,21,21,10,10,10,10,11,
605.9529 +        11,13,13,14,13,21,21,21,13,13,11,11,12,12,13,13,
605.9530 +        14,14,21,21,21,14,14,11,11,12,12,13,13,14,14,21,
605.9531 +        21,21,21,20,13,13,13,12,14,14,16,15,20,20,20,20,
605.9532 +        20,13,13,13,13,14,13,15,15,
605.9533 +};
605.9534 +
605.9535 +static const static_codebook _44c8_s_p7_0 = {
605.9536 +        2, 169,
605.9537 +        (long *)_vq_lengthlist__44c8_s_p7_0,
605.9538 +        1, -523206656, 1618345984, 4, 0,
605.9539 +        (long *)_vq_quantlist__44c8_s_p7_0,
605.9540 +        0
605.9541 +};
605.9542 +
605.9543 +static const long _vq_quantlist__44c8_s_p7_1[] = {
605.9544 +        5,
605.9545 +        4,
605.9546 +        6,
605.9547 +        3,
605.9548 +        7,
605.9549 +        2,
605.9550 +        8,
605.9551 +        1,
605.9552 +        9,
605.9553 +        0,
605.9554 +        10,
605.9555 +};
605.9556 +
605.9557 +static const long _vq_lengthlist__44c8_s_p7_1[] = {
605.9558 +         4, 5, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 6, 6, 6, 7,
605.9559 +         7, 7, 7, 7, 7, 7, 8, 6, 6, 6, 6, 7, 7, 7, 7, 7,
605.9560 +         7, 8, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7,
605.9561 +         7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7,
605.9562 +         7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
605.9563 +         7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7,
605.9564 +         7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8,
605.9565 +         8, 8, 8, 7, 7, 7, 7, 7, 7,
605.9566 +};
605.9567 +
605.9568 +static const static_codebook _44c8_s_p7_1 = {
605.9569 +        2, 121,
605.9570 +        (long *)_vq_lengthlist__44c8_s_p7_1,
605.9571 +        1, -531365888, 1611661312, 4, 0,
605.9572 +        (long *)_vq_quantlist__44c8_s_p7_1,
605.9573 +        0
605.9574 +};
605.9575 +
605.9576 +static const long _vq_quantlist__44c8_s_p8_0[] = {
605.9577 +        7,
605.9578 +        6,
605.9579 +        8,
605.9580 +        5,
605.9581 +        9,
605.9582 +        4,
605.9583 +        10,
605.9584 +        3,
605.9585 +        11,
605.9586 +        2,
605.9587 +        12,
605.9588 +        1,
605.9589 +        13,
605.9590 +        0,
605.9591 +        14,
605.9592 +};
605.9593 +
605.9594 +static const long _vq_lengthlist__44c8_s_p8_0[] = {
605.9595 +         1, 4, 4, 7, 6, 8, 8, 8, 7, 9, 8,10,10,11,10, 6,
605.9596 +         5, 5, 7, 7, 9, 9, 8, 8,10,10,11,11,12,11, 6, 5,
605.9597 +         5, 7, 7, 9, 9, 9, 9,10,10,11,11,12,12,20, 8, 8,
605.9598 +         8, 8, 9, 9, 9, 9,10,10,11,11,12,12,20, 8, 8, 8,
605.9599 +         8,10, 9, 9, 9,10,10,11,11,12,12,20,12,12, 9, 9,
605.9600 +        10,10,10,10,10,11,12,12,12,12,20,12,12, 9, 9,10,
605.9601 +        10,10,10,11,11,12,12,13,13,20,20,20, 9, 9, 9, 9,
605.9602 +        11,10,11,11,12,12,12,13,20,19,19, 9, 9, 9, 9,11,
605.9603 +        11,11,12,12,12,13,13,19,19,19,13,13,10,10,11,11,
605.9604 +        12,12,13,13,13,13,19,19,19,14,13,11,10,11,11,12,
605.9605 +        12,12,13,13,13,19,19,19,19,19,12,12,12,12,13,13,
605.9606 +        13,13,14,13,19,19,19,19,19,12,12,12,11,12,12,13,
605.9607 +        14,14,14,19,19,19,19,19,16,15,13,12,13,13,13,14,
605.9608 +        14,14,19,19,19,19,19,17,17,13,12,13,11,14,13,15,
605.9609 +        15,
605.9610 +};
605.9611 +
605.9612 +static const static_codebook _44c8_s_p8_0 = {
605.9613 +        2, 225,
605.9614 +        (long *)_vq_lengthlist__44c8_s_p8_0,
605.9615 +        1, -520986624, 1620377600, 4, 0,
605.9616 +        (long *)_vq_quantlist__44c8_s_p8_0,
605.9617 +        0
605.9618 +};
605.9619 +
605.9620 +static const long _vq_quantlist__44c8_s_p8_1[] = {
605.9621 +        10,
605.9622 +        9,
605.9623 +        11,
605.9624 +        8,
605.9625 +        12,
605.9626 +        7,
605.9627 +        13,
605.9628 +        6,
605.9629 +        14,
605.9630 +        5,
605.9631 +        15,
605.9632 +        4,
605.9633 +        16,
605.9634 +        3,
605.9635 +        17,
605.9636 +        2,
605.9637 +        18,
605.9638 +        1,
605.9639 +        19,
605.9640 +        0,
605.9641 +        20,
605.9642 +};
605.9643 +
605.9644 +static const long _vq_lengthlist__44c8_s_p8_1[] = {
605.9645 +         4, 5, 5, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.9646 +         8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
605.9647 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8,
605.9648 +         8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,
605.9649 +         7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.9650 +         9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, 9,
605.9651 +         9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 9,
605.9652 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,
605.9653 +        10, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.9654 +         9, 9, 9,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.9655 +         9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9,
605.9656 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,
605.9657 +        10,10, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, 9,
605.9658 +         9, 9,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.9659 +         9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, 9,
605.9660 +         9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9,10,10,10,10,
605.9661 +        10,10,10, 9, 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9,
605.9662 +         9,10,10,10,10,10,10,10, 9,10,10, 9,10,10,10,10,
605.9663 +         9,10, 9,10,10, 9,10,10,10,10,10,10,10, 9,10,10,
605.9664 +        10,10,10,10, 9, 9,10,10, 9,10,10,10,10,10,10,10,
605.9665 +        10,10,10,10,10,10,10,10, 9, 9, 9,10, 9, 9, 9, 9,
605.9666 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9,
605.9667 +        10, 9,10, 9,10,10,10,10,10,10,10,10,10,10,10,10,
605.9668 +        10,10,10,10, 9, 9,10, 9, 9, 9,10,10,10,10,10,10,
605.9669 +        10,10,10,10,10, 9, 9, 9, 9, 9, 9,10, 9, 9,10,10,
605.9670 +        10,10,10,10,10,10,10,10,10,10,10,10,10, 9,10, 9,
605.9671 +         9,10, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,
605.9672 +        10, 9, 9,10,10, 9,10, 9, 9,
605.9673 +};
605.9674 +
605.9675 +static const static_codebook _44c8_s_p8_1 = {
605.9676 +        2, 441,
605.9677 +        (long *)_vq_lengthlist__44c8_s_p8_1,
605.9678 +        1, -529268736, 1611661312, 5, 0,
605.9679 +        (long *)_vq_quantlist__44c8_s_p8_1,
605.9680 +        0
605.9681 +};
605.9682 +
605.9683 +static const long _vq_quantlist__44c8_s_p9_0[] = {
605.9684 +        8,
605.9685 +        7,
605.9686 +        9,
605.9687 +        6,
605.9688 +        10,
605.9689 +        5,
605.9690 +        11,
605.9691 +        4,
605.9692 +        12,
605.9693 +        3,
605.9694 +        13,
605.9695 +        2,
605.9696 +        14,
605.9697 +        1,
605.9698 +        15,
605.9699 +        0,
605.9700 +        16,
605.9701 +};
605.9702 +
605.9703 +static const long _vq_lengthlist__44c8_s_p9_0[] = {
605.9704 +         1, 4, 3,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9705 +        11, 4, 7, 7,11,11,11,11,11,11,11,11,11,11,11,11,
605.9706 +        11,11, 4, 8,11,11,11,11,11,11,11,11,11,11,11,11,
605.9707 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9708 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9709 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9710 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9711 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9712 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9713 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9714 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9715 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9716 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9717 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.9718 +        11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.9719 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.9720 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.9721 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.9722 +        10,
605.9723 +};
605.9724 +
605.9725 +static const static_codebook _44c8_s_p9_0 = {
605.9726 +        2, 289,
605.9727 +        (long *)_vq_lengthlist__44c8_s_p9_0,
605.9728 +        1, -509798400, 1631393792, 5, 0,
605.9729 +        (long *)_vq_quantlist__44c8_s_p9_0,
605.9730 +        0
605.9731 +};
605.9732 +
605.9733 +static const long _vq_quantlist__44c8_s_p9_1[] = {
605.9734 +        9,
605.9735 +        8,
605.9736 +        10,
605.9737 +        7,
605.9738 +        11,
605.9739 +        6,
605.9740 +        12,
605.9741 +        5,
605.9742 +        13,
605.9743 +        4,
605.9744 +        14,
605.9745 +        3,
605.9746 +        15,
605.9747 +        2,
605.9748 +        16,
605.9749 +        1,
605.9750 +        17,
605.9751 +        0,
605.9752 +        18,
605.9753 +};
605.9754 +
605.9755 +static const long _vq_lengthlist__44c8_s_p9_1[] = {
605.9756 +         1, 4, 4, 7, 6, 7, 7, 7, 7, 8, 8, 9, 9,10,10,10,
605.9757 +        10,11,11, 6, 6, 6, 8, 8, 9, 8, 8, 7,10, 8,11,10,
605.9758 +        12,11,12,12,13,13, 5, 5, 6, 8, 8, 9, 9, 8, 8,10,
605.9759 +         9,11,11,12,12,13,13,13,13,17, 8, 8, 9, 9, 9, 9,
605.9760 +         9, 9,10, 9,12,10,12,12,13,12,13,13,17, 9, 8, 9,
605.9761 +         9, 9, 9, 9, 9,10,10,12,12,12,12,13,13,13,13,17,
605.9762 +        13,13, 9, 9,10,10,10,10,11,11,12,11,13,12,13,13,
605.9763 +        14,15,17,13,13, 9, 8,10, 9,10,10,11,11,12,12,14,
605.9764 +        13,15,13,14,15,17,17,17, 9,10, 9,10,11,11,12,12,
605.9765 +        12,12,13,13,14,14,15,15,17,17,17, 9, 8, 9, 8,11,
605.9766 +        11,12,12,12,12,14,13,14,14,14,15,17,17,17,12,14,
605.9767 +         9,10,11,11,12,12,14,13,13,14,15,13,15,15,17,17,
605.9768 +        17,13,11,10, 8,11, 9,13,12,13,13,13,13,13,14,14,
605.9769 +        14,17,17,17,17,17,11,12,11,11,13,13,14,13,15,14,
605.9770 +        13,15,16,15,17,17,17,17,17,11,11,12, 8,13,12,14,
605.9771 +        13,17,14,15,14,15,14,17,17,17,17,17,15,15,12,12,
605.9772 +        12,12,13,14,14,14,15,14,17,14,17,17,17,17,17,16,
605.9773 +        17,12,12,13,12,13,13,14,14,14,14,14,14,17,17,17,
605.9774 +        17,17,17,17,14,14,13,12,13,13,15,15,14,13,15,17,
605.9775 +        17,17,17,17,17,17,17,13,14,13,13,13,13,14,15,15,
605.9776 +        15,14,15,17,17,17,17,17,17,17,16,15,13,14,13,13,
605.9777 +        14,14,15,14,14,16,17,17,17,17,17,17,17,16,16,13,
605.9778 +        14,13,13,14,14,15,14,15,14,
605.9779 +};
605.9780 +
605.9781 +static const static_codebook _44c8_s_p9_1 = {
605.9782 +        2, 361,
605.9783 +        (long *)_vq_lengthlist__44c8_s_p9_1,
605.9784 +        1, -518287360, 1622704128, 5, 0,
605.9785 +        (long *)_vq_quantlist__44c8_s_p9_1,
605.9786 +        0
605.9787 +};
605.9788 +
605.9789 +static const long _vq_quantlist__44c8_s_p9_2[] = {
605.9790 +        24,
605.9791 +        23,
605.9792 +        25,
605.9793 +        22,
605.9794 +        26,
605.9795 +        21,
605.9796 +        27,
605.9797 +        20,
605.9798 +        28,
605.9799 +        19,
605.9800 +        29,
605.9801 +        18,
605.9802 +        30,
605.9803 +        17,
605.9804 +        31,
605.9805 +        16,
605.9806 +        32,
605.9807 +        15,
605.9808 +        33,
605.9809 +        14,
605.9810 +        34,
605.9811 +        13,
605.9812 +        35,
605.9813 +        12,
605.9814 +        36,
605.9815 +        11,
605.9816 +        37,
605.9817 +        10,
605.9818 +        38,
605.9819 +        9,
605.9820 +        39,
605.9821 +        8,
605.9822 +        40,
605.9823 +        7,
605.9824 +        41,
605.9825 +        6,
605.9826 +        42,
605.9827 +        5,
605.9828 +        43,
605.9829 +        4,
605.9830 +        44,
605.9831 +        3,
605.9832 +        45,
605.9833 +        2,
605.9834 +        46,
605.9835 +        1,
605.9836 +        47,
605.9837 +        0,
605.9838 +        48,
605.9839 +};
605.9840 +
605.9841 +static const long _vq_lengthlist__44c8_s_p9_2[] = {
605.9842 +         2, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6,
605.9843 +         6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.9844 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.9845 +         7,
605.9846 +};
605.9847 +
605.9848 +static const static_codebook _44c8_s_p9_2 = {
605.9849 +        1, 49,
605.9850 +        (long *)_vq_lengthlist__44c8_s_p9_2,
605.9851 +        1, -526909440, 1611661312, 6, 0,
605.9852 +        (long *)_vq_quantlist__44c8_s_p9_2,
605.9853 +        0
605.9854 +};
605.9855 +
605.9856 +static const long _huff_lengthlist__44c8_s_short[] = {
605.9857 +         4,11,13,14,15,15,18,17,19,17, 5, 6, 8, 9,10,10,
605.9858 +        12,15,19,19, 6, 6, 6, 6, 8, 8,11,14,18,19, 8, 6,
605.9859 +         5, 4, 6, 7,10,13,16,17, 9, 7, 6, 5, 6, 7, 9,12,
605.9860 +        15,19,10, 8, 7, 6, 6, 6, 7, 9,13,15,12,10, 9, 8,
605.9861 +         7, 6, 4, 5,10,15,13,13,11, 8, 6, 6, 4, 2, 7,12,
605.9862 +        17,15,16,10, 8, 8, 7, 6, 9,12,19,18,17,13,11,10,
605.9863 +        10, 9,11,14,
605.9864 +};
605.9865 +
605.9866 +static const static_codebook _huff_book__44c8_s_short = {
605.9867 +        2, 100,
605.9868 +        (long *)_huff_lengthlist__44c8_s_short,
605.9869 +        0, 0, 0, 0, 0,
605.9870 +        NULL,
605.9871 +        0
605.9872 +};
605.9873 +
605.9874 +static const long _huff_lengthlist__44c9_s_long[] = {
605.9875 +         3, 8,12,14,15,15,15,13,15,15, 6, 5, 8,10,12,12,
605.9876 +        13,12,14,13,10, 6, 5, 6, 8, 9,11,11,13,13,13, 8,
605.9877 +         5, 4, 5, 6, 8,10,11,13,14,10, 7, 5, 4, 5, 7, 9,
605.9878 +        11,12,13,11, 8, 6, 5, 4, 5, 7, 9,11,12,11,10, 8,
605.9879 +         7, 5, 4, 5, 9,10,13,13,11,10, 8, 6, 5, 4, 7, 9,
605.9880 +        15,14,13,12,10, 9, 8, 7, 8, 9,12,12,14,13,12,11,
605.9881 +        10, 9, 8, 9,
605.9882 +};
605.9883 +
605.9884 +static const static_codebook _huff_book__44c9_s_long = {
605.9885 +        2, 100,
605.9886 +        (long *)_huff_lengthlist__44c9_s_long,
605.9887 +        0, 0, 0, 0, 0,
605.9888 +        NULL,
605.9889 +        0
605.9890 +};
605.9891 +
605.9892 +static const long _vq_quantlist__44c9_s_p1_0[] = {
605.9893 +        1,
605.9894 +        0,
605.9895 +        2,
605.9896 +};
605.9897 +
605.9898 +static const long _vq_lengthlist__44c9_s_p1_0[] = {
605.9899 +         1, 5, 5, 0, 5, 5, 0, 5, 5, 6, 8, 8, 0, 9, 8, 0,
605.9900 +         9, 8, 6, 8, 8, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 0,
605.9901 +         0, 0, 0, 0, 5, 8, 8, 0, 7, 7, 0, 8, 8, 5, 8, 8,
605.9902 +         0, 7, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
605.9903 +         9, 8, 0, 8, 8, 0, 7, 7, 5, 8, 9, 0, 8, 8, 0, 7,
605.9904 +         7,
605.9905 +};
605.9906 +
605.9907 +static const static_codebook _44c9_s_p1_0 = {
605.9908 +        4, 81,
605.9909 +        (long *)_vq_lengthlist__44c9_s_p1_0,
605.9910 +        1, -535822336, 1611661312, 2, 0,
605.9911 +        (long *)_vq_quantlist__44c9_s_p1_0,
605.9912 +        0
605.9913 +};
605.9914 +
605.9915 +static const long _vq_quantlist__44c9_s_p2_0[] = {
605.9916 +        2,
605.9917 +        1,
605.9918 +        3,
605.9919 +        0,
605.9920 +        4,
605.9921 +};
605.9922 +
605.9923 +static const long _vq_lengthlist__44c9_s_p2_0[] = {
605.9924 +         3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0,
605.9925 +         7, 7, 9, 9, 0, 0, 0, 9, 9, 6, 7, 7, 9, 8, 0, 8,
605.9926 +         8, 9, 9, 0, 8, 7, 9, 9, 0, 9,10,10,10, 0, 0, 0,
605.9927 +        11,10, 6, 7, 7, 8, 9, 0, 8, 8, 9, 9, 0, 7, 8, 9,
605.9928 +         9, 0,10, 9,11,10, 0, 0, 0,10,10, 8, 9, 8,10,10,
605.9929 +         0,10,10,12,11, 0,10,10,11,11, 0,12,13,13,13, 0,
605.9930 +         0, 0,13,12, 8, 8, 9,10,10, 0,10,10,11,12, 0,10,
605.9931 +        10,11,11, 0,13,12,13,13, 0, 0, 0,13,13, 0, 0, 0,
605.9932 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9933 +         0, 0, 0, 0, 0, 0, 6, 8, 7,10,10, 0, 7, 7,10, 9,
605.9934 +         0, 7, 7,10,10, 0, 9, 9,10,10, 0, 0, 0,10,10, 6,
605.9935 +         7, 8,10,10, 0, 7, 7, 9,10, 0, 7, 7,10,10, 0, 9,
605.9936 +         9,10,10, 0, 0, 0,10,10, 8, 9, 9,11,11, 0,10,10,
605.9937 +        11,11, 0,10,10,11,11, 0,12,12,12,12, 0, 0, 0,12,
605.9938 +        12, 8, 9,10,11,11, 0, 9,10,11,11, 0,10,10,11,11,
605.9939 +         0,12,12,12,12, 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0,
605.9940 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9941 +         0, 0, 0, 5, 8, 7,10,10, 0, 7, 7,10,10, 0, 7, 7,
605.9942 +        10, 9, 0, 9, 9,10,10, 0, 0, 0,10,10, 6, 7, 8,10,
605.9943 +        10, 0, 7, 7,10,10, 0, 7, 7, 9,10, 0, 9, 9,10,10,
605.9944 +         0, 0, 0,10,10, 8,10, 9,12,11, 0,10,10,12,11, 0,
605.9945 +        10, 9,11,11, 0,11,12,12,12, 0, 0, 0,12,12, 8, 9,
605.9946 +        10,11,12, 0,10,10,11,11, 0, 9,10,11,11, 0,12,11,
605.9947 +        12,12, 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9948 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9949 +         7,10, 9,12,12, 0, 9, 9,12,11, 0, 9, 9,11,11, 0,
605.9950 +        10,10,12,11, 0, 0, 0,11,12, 7, 9,10,12,12, 0, 9,
605.9951 +         9,11,12, 0, 9, 9,11,11, 0,10,10,11,12, 0, 0, 0,
605.9952 +        11,11, 9,11,10,13,12, 0,10,10,12,12, 0,10,10,12,
605.9953 +        12, 0,11,11,12,12, 0, 0, 0,13,12, 9,10,11,12,13,
605.9954 +         0,10,10,12,12, 0,10,10,12,12, 0,11,12,12,12, 0,
605.9955 +         0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9956 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9957 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9958 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9959 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
605.9960 +        11,10,13,13, 0,10,10,12,12, 0,10,10,12,12, 0,11,
605.9961 +        12,12,12, 0, 0, 0,12,12, 9,10,11,13,13, 0,10,10,
605.9962 +        12,12, 0,10,10,12,12, 0,12,11,13,12, 0, 0, 0,12,
605.9963 +        12,
605.9964 +};
605.9965 +
605.9966 +static const static_codebook _44c9_s_p2_0 = {
605.9967 +        4, 625,
605.9968 +        (long *)_vq_lengthlist__44c9_s_p2_0,
605.9969 +        1, -533725184, 1611661312, 3, 0,
605.9970 +        (long *)_vq_quantlist__44c9_s_p2_0,
605.9971 +        0
605.9972 +};
605.9973 +
605.9974 +static const long _vq_quantlist__44c9_s_p3_0[] = {
605.9975 +        4,
605.9976 +        3,
605.9977 +        5,
605.9978 +        2,
605.9979 +        6,
605.9980 +        1,
605.9981 +        7,
605.9982 +        0,
605.9983 +        8,
605.9984 +};
605.9985 +
605.9986 +static const long _vq_lengthlist__44c9_s_p3_0[] = {
605.9987 +         3, 4, 4, 5, 5, 6, 6, 8, 8, 0, 4, 4, 5, 5, 6, 7,
605.9988 +         8, 8, 0, 4, 4, 5, 5, 7, 7, 8, 8, 0, 5, 5, 6, 6,
605.9989 +         7, 7, 9, 9, 0, 0, 0, 6, 6, 7, 7, 9, 9, 0, 0, 0,
605.9990 +         7, 7, 8, 8, 9, 9, 0, 0, 0, 7, 7, 8, 8, 9, 9, 0,
605.9991 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.9992 +         0,
605.9993 +};
605.9994 +
605.9995 +static const static_codebook _44c9_s_p3_0 = {
605.9996 +        2, 81,
605.9997 +        (long *)_vq_lengthlist__44c9_s_p3_0,
605.9998 +        1, -531628032, 1611661312, 4, 0,
605.9999 +        (long *)_vq_quantlist__44c9_s_p3_0,
605.10000 +        0
605.10001 +};
605.10002 +
605.10003 +static const long _vq_quantlist__44c9_s_p4_0[] = {
605.10004 +        8,
605.10005 +        7,
605.10006 +        9,
605.10007 +        6,
605.10008 +        10,
605.10009 +        5,
605.10010 +        11,
605.10011 +        4,
605.10012 +        12,
605.10013 +        3,
605.10014 +        13,
605.10015 +        2,
605.10016 +        14,
605.10017 +        1,
605.10018 +        15,
605.10019 +        0,
605.10020 +        16,
605.10021 +};
605.10022 +
605.10023 +static const long _vq_lengthlist__44c9_s_p4_0[] = {
605.10024 +         3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,10,
605.10025 +        10, 0, 5, 4, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10,10,
605.10026 +        11,11, 0, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,
605.10027 +        10,11,11, 0, 6, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,
605.10028 +        11,11,11,12, 0, 0, 0, 6, 6, 7, 7, 8, 8, 9, 9,10,
605.10029 +        10,11,11,12,12, 0, 0, 0, 7, 7, 7, 7, 9, 9, 9, 9,
605.10030 +        10,10,11,11,12,12, 0, 0, 0, 7, 7, 7, 8, 9, 9, 9,
605.10031 +         9,10,10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,
605.10032 +        10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9,
605.10033 +         9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 0, 0,
605.10034 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10035 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10036 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10037 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10038 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10039 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10040 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10041 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10042 +         0,
605.10043 +};
605.10044 +
605.10045 +static const static_codebook _44c9_s_p4_0 = {
605.10046 +        2, 289,
605.10047 +        (long *)_vq_lengthlist__44c9_s_p4_0,
605.10048 +        1, -529530880, 1611661312, 5, 0,
605.10049 +        (long *)_vq_quantlist__44c9_s_p4_0,
605.10050 +        0
605.10051 +};
605.10052 +
605.10053 +static const long _vq_quantlist__44c9_s_p5_0[] = {
605.10054 +        1,
605.10055 +        0,
605.10056 +        2,
605.10057 +};
605.10058 +
605.10059 +static const long _vq_lengthlist__44c9_s_p5_0[] = {
605.10060 +         1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 7, 6, 9,10,10,10,
605.10061 +        10, 9, 4, 6, 7, 9,10,10,10, 9,10, 5, 9, 9, 9,11,
605.10062 +        11,10,11,11, 7,10, 9,11,12,11,12,12,12, 7, 9,10,
605.10063 +        11,11,12,12,12,12, 6,10,10,10,12,12,10,12,11, 7,
605.10064 +        10,10,11,12,12,11,12,12, 7,10,10,11,12,12,12,12,
605.10065 +        12,
605.10066 +};
605.10067 +
605.10068 +static const static_codebook _44c9_s_p5_0 = {
605.10069 +        4, 81,
605.10070 +        (long *)_vq_lengthlist__44c9_s_p5_0,
605.10071 +        1, -529137664, 1618345984, 2, 0,
605.10072 +        (long *)_vq_quantlist__44c9_s_p5_0,
605.10073 +        0
605.10074 +};
605.10075 +
605.10076 +static const long _vq_quantlist__44c9_s_p5_1[] = {
605.10077 +        5,
605.10078 +        4,
605.10079 +        6,
605.10080 +        3,
605.10081 +        7,
605.10082 +        2,
605.10083 +        8,
605.10084 +        1,
605.10085 +        9,
605.10086 +        0,
605.10087 +        10,
605.10088 +};
605.10089 +
605.10090 +static const long _vq_lengthlist__44c9_s_p5_1[] = {
605.10091 +         4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7,11, 5, 5, 6, 6,
605.10092 +         7, 7, 7, 7, 8, 8,11, 5, 5, 6, 6, 7, 7, 7, 7, 8,
605.10093 +         8,11, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11,11,11, 6,
605.10094 +         6, 7, 7, 7, 8, 8, 8,11,11,11, 6, 6, 7, 7, 7, 8,
605.10095 +         8, 8,11,11,11, 6, 6, 7, 7, 7, 7, 8, 8,11,11,11,
605.10096 +         7, 7, 7, 7, 7, 7, 8, 8,11,11,11,10,10, 7, 7, 7,
605.10097 +         7, 8, 8,11,11,11,11,11, 7, 7, 7, 7, 7, 7,11,11,
605.10098 +        11,11,11, 7, 7, 7, 7, 7, 7,
605.10099 +};
605.10100 +
605.10101 +static const static_codebook _44c9_s_p5_1 = {
605.10102 +        2, 121,
605.10103 +        (long *)_vq_lengthlist__44c9_s_p5_1,
605.10104 +        1, -531365888, 1611661312, 4, 0,
605.10105 +        (long *)_vq_quantlist__44c9_s_p5_1,
605.10106 +        0
605.10107 +};
605.10108 +
605.10109 +static const long _vq_quantlist__44c9_s_p6_0[] = {
605.10110 +        6,
605.10111 +        5,
605.10112 +        7,
605.10113 +        4,
605.10114 +        8,
605.10115 +        3,
605.10116 +        9,
605.10117 +        2,
605.10118 +        10,
605.10119 +        1,
605.10120 +        11,
605.10121 +        0,
605.10122 +        12,
605.10123 +};
605.10124 +
605.10125 +static const long _vq_lengthlist__44c9_s_p6_0[] = {
605.10126 +         2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 5, 4, 4,
605.10127 +         6, 6, 8, 8, 9, 9, 9, 9,10,10, 6, 4, 4, 6, 6, 8,
605.10128 +         8, 9, 9, 9, 9,10,10, 0, 6, 6, 7, 7, 8, 8, 9, 9,
605.10129 +        10,10,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,
605.10130 +        11, 0,10,10, 8, 8, 9, 9,10,10,11,11,12,12, 0,11,
605.10131 +        11, 8, 8, 9, 9,10,10,11,11,12,12, 0, 0, 0, 0, 0,
605.10132 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10133 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10134 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10135 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10136 +         0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10137 +};
605.10138 +
605.10139 +static const static_codebook _44c9_s_p6_0 = {
605.10140 +        2, 169,
605.10141 +        (long *)_vq_lengthlist__44c9_s_p6_0,
605.10142 +        1, -526516224, 1616117760, 4, 0,
605.10143 +        (long *)_vq_quantlist__44c9_s_p6_0,
605.10144 +        0
605.10145 +};
605.10146 +
605.10147 +static const long _vq_quantlist__44c9_s_p6_1[] = {
605.10148 +        2,
605.10149 +        1,
605.10150 +        3,
605.10151 +        0,
605.10152 +        4,
605.10153 +};
605.10154 +
605.10155 +static const long _vq_lengthlist__44c9_s_p6_1[] = {
605.10156 +         4, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5,
605.10157 +         5, 5, 5, 5, 5, 5, 5, 5, 5,
605.10158 +};
605.10159 +
605.10160 +static const static_codebook _44c9_s_p6_1 = {
605.10161 +        2, 25,
605.10162 +        (long *)_vq_lengthlist__44c9_s_p6_1,
605.10163 +        1, -533725184, 1611661312, 3, 0,
605.10164 +        (long *)_vq_quantlist__44c9_s_p6_1,
605.10165 +        0
605.10166 +};
605.10167 +
605.10168 +static const long _vq_quantlist__44c9_s_p7_0[] = {
605.10169 +        6,
605.10170 +        5,
605.10171 +        7,
605.10172 +        4,
605.10173 +        8,
605.10174 +        3,
605.10175 +        9,
605.10176 +        2,
605.10177 +        10,
605.10178 +        1,
605.10179 +        11,
605.10180 +        0,
605.10181 +        12,
605.10182 +};
605.10183 +
605.10184 +static const long _vq_lengthlist__44c9_s_p7_0[] = {
605.10185 +         2, 4, 4, 6, 6, 7, 7, 8, 8,10,10,11,11, 6, 4, 4,
605.10186 +         6, 6, 8, 8, 9, 9,10,10,12,12, 6, 4, 5, 6, 6, 8,
605.10187 +         8, 9, 9,10,10,12,12,20, 6, 6, 6, 6, 8, 8, 9,10,
605.10188 +        11,11,12,12,20, 6, 6, 6, 6, 8, 8,10,10,11,11,12,
605.10189 +        12,20,10,10, 7, 7, 9, 9,10,10,11,11,12,12,20,11,
605.10190 +        11, 7, 7, 9, 9,10,10,11,11,12,12,20,20,20, 9, 9,
605.10191 +         9, 9,11,11,12,12,13,13,20,20,20, 9, 9, 9, 9,11,
605.10192 +        11,12,12,13,13,20,20,20,13,13,10,10,11,11,12,13,
605.10193 +        13,13,20,20,20,13,13,10,10,11,11,12,13,13,13,20,
605.10194 +        20,20,20,19,12,12,12,12,13,13,14,15,19,19,19,19,
605.10195 +        19,12,12,12,12,13,13,14,14,
605.10196 +};
605.10197 +
605.10198 +static const static_codebook _44c9_s_p7_0 = {
605.10199 +        2, 169,
605.10200 +        (long *)_vq_lengthlist__44c9_s_p7_0,
605.10201 +        1, -523206656, 1618345984, 4, 0,
605.10202 +        (long *)_vq_quantlist__44c9_s_p7_0,
605.10203 +        0
605.10204 +};
605.10205 +
605.10206 +static const long _vq_quantlist__44c9_s_p7_1[] = {
605.10207 +        5,
605.10208 +        4,
605.10209 +        6,
605.10210 +        3,
605.10211 +        7,
605.10212 +        2,
605.10213 +        8,
605.10214 +        1,
605.10215 +        9,
605.10216 +        0,
605.10217 +        10,
605.10218 +};
605.10219 +
605.10220 +static const long _vq_lengthlist__44c9_s_p7_1[] = {
605.10221 +         5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
605.10222 +         7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 7, 7, 7, 7, 7,
605.10223 +         7, 8, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 6,
605.10224 +         6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7,
605.10225 +         7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
605.10226 +         7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7,
605.10227 +         7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8,
605.10228 +         8, 8, 8, 7, 7, 7, 7, 7, 7,
605.10229 +};
605.10230 +
605.10231 +static const static_codebook _44c9_s_p7_1 = {
605.10232 +        2, 121,
605.10233 +        (long *)_vq_lengthlist__44c9_s_p7_1,
605.10234 +        1, -531365888, 1611661312, 4, 0,
605.10235 +        (long *)_vq_quantlist__44c9_s_p7_1,
605.10236 +        0
605.10237 +};
605.10238 +
605.10239 +static const long _vq_quantlist__44c9_s_p8_0[] = {
605.10240 +        7,
605.10241 +        6,
605.10242 +        8,
605.10243 +        5,
605.10244 +        9,
605.10245 +        4,
605.10246 +        10,
605.10247 +        3,
605.10248 +        11,
605.10249 +        2,
605.10250 +        12,
605.10251 +        1,
605.10252 +        13,
605.10253 +        0,
605.10254 +        14,
605.10255 +};
605.10256 +
605.10257 +static const long _vq_lengthlist__44c9_s_p8_0[] = {
605.10258 +         1, 4, 4, 7, 6, 8, 8, 8, 8, 9, 9,10,10,11,10, 6,
605.10259 +         5, 5, 7, 7, 9, 9, 8, 9,10,10,11,11,12,12, 6, 5,
605.10260 +         5, 7, 7, 9, 9, 9, 9,10,10,11,11,12,12,21, 7, 8,
605.10261 +         8, 8, 9, 9, 9, 9,10,10,11,11,12,12,21, 8, 8, 8,
605.10262 +         8, 9, 9, 9, 9,10,10,11,11,12,12,21,11,12, 9, 9,
605.10263 +        10,10,10,10,10,11,11,12,12,12,21,12,12, 9, 8,10,
605.10264 +        10,10,10,11,11,12,12,13,13,21,21,21, 9, 9, 9, 9,
605.10265 +        11,11,11,11,12,12,12,13,21,20,20, 9, 9, 9, 9,10,
605.10266 +        11,11,11,12,12,13,13,20,20,20,13,13,10,10,11,11,
605.10267 +        12,12,13,13,13,13,20,20,20,13,13,10,10,11,11,12,
605.10268 +        12,13,13,13,13,20,20,20,20,20,12,12,12,12,12,12,
605.10269 +        13,13,14,14,20,20,20,20,20,12,12,12,11,13,12,13,
605.10270 +        13,14,14,20,20,20,20,20,15,16,13,12,13,13,14,13,
605.10271 +        14,14,20,20,20,20,20,16,15,12,12,13,12,14,13,14,
605.10272 +        14,
605.10273 +};
605.10274 +
605.10275 +static const static_codebook _44c9_s_p8_0 = {
605.10276 +        2, 225,
605.10277 +        (long *)_vq_lengthlist__44c9_s_p8_0,
605.10278 +        1, -520986624, 1620377600, 4, 0,
605.10279 +        (long *)_vq_quantlist__44c9_s_p8_0,
605.10280 +        0
605.10281 +};
605.10282 +
605.10283 +static const long _vq_quantlist__44c9_s_p8_1[] = {
605.10284 +        10,
605.10285 +        9,
605.10286 +        11,
605.10287 +        8,
605.10288 +        12,
605.10289 +        7,
605.10290 +        13,
605.10291 +        6,
605.10292 +        14,
605.10293 +        5,
605.10294 +        15,
605.10295 +        4,
605.10296 +        16,
605.10297 +        3,
605.10298 +        17,
605.10299 +        2,
605.10300 +        18,
605.10301 +        1,
605.10302 +        19,
605.10303 +        0,
605.10304 +        20,
605.10305 +};
605.10306 +
605.10307 +static const long _vq_lengthlist__44c9_s_p8_1[] = {
605.10308 +         4, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
605.10309 +         8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
605.10310 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8,
605.10311 +         8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,
605.10312 +         7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.10313 +         9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, 9,
605.10314 +         9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8,
605.10315 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,
605.10316 +        10, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.10317 +         9, 9, 9,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.10318 +         9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9,
605.10319 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,
605.10320 +        10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.10321 +         9, 9,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9,
605.10322 +         9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, 9,
605.10323 +         9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10,10,10,10,
605.10324 +        10,10,10, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, 9, 9,
605.10325 +         9,10,10,10,10,10,10,10, 9, 9, 9,10,10,10,10,10,
605.10326 +         9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10, 9, 9,10,
605.10327 +         9,10, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,
605.10328 +        10,10,10,10, 9, 9,10,10, 9, 9, 9, 9, 9, 9, 9, 9,
605.10329 +        10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
605.10330 +         9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
605.10331 +        10,10, 9, 9,10, 9, 9, 9, 9, 9,10,10,10,10,10,10,
605.10332 +        10,10,10,10,10, 9, 9,10,10, 9, 9,10, 9, 9, 9,10,
605.10333 +        10,10,10,10,10,10,10,10,10,10, 9, 9,10, 9, 9, 9,
605.10334 +         9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10, 9,
605.10335 +         9, 9, 9,10, 9, 9, 9, 9, 9,
605.10336 +};
605.10337 +
605.10338 +static const static_codebook _44c9_s_p8_1 = {
605.10339 +        2, 441,
605.10340 +        (long *)_vq_lengthlist__44c9_s_p8_1,
605.10341 +        1, -529268736, 1611661312, 5, 0,
605.10342 +        (long *)_vq_quantlist__44c9_s_p8_1,
605.10343 +        0
605.10344 +};
605.10345 +
605.10346 +static const long _vq_quantlist__44c9_s_p9_0[] = {
605.10347 +        9,
605.10348 +        8,
605.10349 +        10,
605.10350 +        7,
605.10351 +        11,
605.10352 +        6,
605.10353 +        12,
605.10354 +        5,
605.10355 +        13,
605.10356 +        4,
605.10357 +        14,
605.10358 +        3,
605.10359 +        15,
605.10360 +        2,
605.10361 +        16,
605.10362 +        1,
605.10363 +        17,
605.10364 +        0,
605.10365 +        18,
605.10366 +};
605.10367 +
605.10368 +static const long _vq_lengthlist__44c9_s_p9_0[] = {
605.10369 +         1, 4, 3,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10370 +        12,12,12, 4, 5, 6,12,12,12,12,12,12,12,12,12,12,
605.10371 +        12,12,12,12,12,12, 4, 6, 6,12,12,12,12,12,12,12,
605.10372 +        12,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,
605.10373 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10374 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10375 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10376 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10377 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10378 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10379 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10380 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10381 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10382 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10383 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10384 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.10385 +        12,12,12,12,12,12,12,12,12,12,11,11,11,11,11,11,
605.10386 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.10387 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.10388 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.10389 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.10390 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.10391 +        11,11,11,11,11,11,11,11,11,
605.10392 +};
605.10393 +
605.10394 +static const static_codebook _44c9_s_p9_0 = {
605.10395 +        2, 361,
605.10396 +        (long *)_vq_lengthlist__44c9_s_p9_0,
605.10397 +        1, -508535424, 1631393792, 5, 0,
605.10398 +        (long *)_vq_quantlist__44c9_s_p9_0,
605.10399 +        0
605.10400 +};
605.10401 +
605.10402 +static const long _vq_quantlist__44c9_s_p9_1[] = {
605.10403 +        9,
605.10404 +        8,
605.10405 +        10,
605.10406 +        7,
605.10407 +        11,
605.10408 +        6,
605.10409 +        12,
605.10410 +        5,
605.10411 +        13,
605.10412 +        4,
605.10413 +        14,
605.10414 +        3,
605.10415 +        15,
605.10416 +        2,
605.10417 +        16,
605.10418 +        1,
605.10419 +        17,
605.10420 +        0,
605.10421 +        18,
605.10422 +};
605.10423 +
605.10424 +static const long _vq_lengthlist__44c9_s_p9_1[] = {
605.10425 +         1, 4, 4, 7, 7, 7, 7, 8, 7, 9, 8, 9, 9,10,10,11,
605.10426 +        11,11,11, 6, 5, 5, 8, 8, 9, 9, 9, 8,10, 9,11,10,
605.10427 +        12,12,13,12,13,13, 5, 5, 5, 8, 8, 9, 9, 9, 9,10,
605.10428 +        10,11,11,12,12,13,12,13,13,17, 8, 8, 9, 9, 9, 9,
605.10429 +         9, 9,10,10,12,11,13,12,13,13,13,13,18, 8, 8, 9,
605.10430 +         9, 9, 9, 9, 9,11,11,12,12,13,13,13,13,13,13,17,
605.10431 +        13,12, 9, 9,10,10,10,10,11,11,12,12,12,13,13,13,
605.10432 +        14,14,18,13,12, 9, 9,10,10,10,10,11,11,12,12,13,
605.10433 +        13,13,14,14,14,17,18,18,10,10,10,10,11,11,11,12,
605.10434 +        12,12,14,13,14,13,13,14,18,18,18,10, 9,10, 9,11,
605.10435 +        11,12,12,12,12,13,13,15,14,14,14,18,18,16,13,14,
605.10436 +        10,11,11,11,12,13,13,13,13,14,13,13,14,14,18,18,
605.10437 +        18,14,12,11, 9,11,10,13,12,13,13,13,14,14,14,13,
605.10438 +        14,18,18,17,18,18,11,12,12,12,13,13,14,13,14,14,
605.10439 +        13,14,14,14,18,18,18,18,17,12,10,12, 9,13,11,13,
605.10440 +        14,14,14,14,14,15,14,18,18,17,17,18,14,15,12,13,
605.10441 +        13,13,14,13,14,14,15,14,15,14,18,17,18,18,18,15,
605.10442 +        15,12,10,14,10,14,14,13,13,14,14,14,14,18,16,18,
605.10443 +        18,18,18,17,14,14,13,14,14,13,13,14,14,14,15,15,
605.10444 +        18,18,18,18,17,17,17,14,14,14,12,14,13,14,14,15,
605.10445 +        14,15,14,18,18,18,18,18,18,18,17,16,13,13,13,14,
605.10446 +        14,14,14,15,16,15,18,18,18,18,18,18,18,17,17,13,
605.10447 +        13,13,13,14,13,14,15,15,15,
605.10448 +};
605.10449 +
605.10450 +static const static_codebook _44c9_s_p9_1 = {
605.10451 +        2, 361,
605.10452 +        (long *)_vq_lengthlist__44c9_s_p9_1,
605.10453 +        1, -518287360, 1622704128, 5, 0,
605.10454 +        (long *)_vq_quantlist__44c9_s_p9_1,
605.10455 +        0
605.10456 +};
605.10457 +
605.10458 +static const long _vq_quantlist__44c9_s_p9_2[] = {
605.10459 +        24,
605.10460 +        23,
605.10461 +        25,
605.10462 +        22,
605.10463 +        26,
605.10464 +        21,
605.10465 +        27,
605.10466 +        20,
605.10467 +        28,
605.10468 +        19,
605.10469 +        29,
605.10470 +        18,
605.10471 +        30,
605.10472 +        17,
605.10473 +        31,
605.10474 +        16,
605.10475 +        32,
605.10476 +        15,
605.10477 +        33,
605.10478 +        14,
605.10479 +        34,
605.10480 +        13,
605.10481 +        35,
605.10482 +        12,
605.10483 +        36,
605.10484 +        11,
605.10485 +        37,
605.10486 +        10,
605.10487 +        38,
605.10488 +        9,
605.10489 +        39,
605.10490 +        8,
605.10491 +        40,
605.10492 +        7,
605.10493 +        41,
605.10494 +        6,
605.10495 +        42,
605.10496 +        5,
605.10497 +        43,
605.10498 +        4,
605.10499 +        44,
605.10500 +        3,
605.10501 +        45,
605.10502 +        2,
605.10503 +        46,
605.10504 +        1,
605.10505 +        47,
605.10506 +        0,
605.10507 +        48,
605.10508 +};
605.10509 +
605.10510 +static const long _vq_lengthlist__44c9_s_p9_2[] = {
605.10511 +         2, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6,
605.10512 +         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7,
605.10513 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
605.10514 +         7,
605.10515 +};
605.10516 +
605.10517 +static const static_codebook _44c9_s_p9_2 = {
605.10518 +        1, 49,
605.10519 +        (long *)_vq_lengthlist__44c9_s_p9_2,
605.10520 +        1, -526909440, 1611661312, 6, 0,
605.10521 +        (long *)_vq_quantlist__44c9_s_p9_2,
605.10522 +        0
605.10523 +};
605.10524 +
605.10525 +static const long _huff_lengthlist__44c9_s_short[] = {
605.10526 +         5,13,18,16,17,17,19,18,19,19, 5, 7,10,11,12,12,
605.10527 +        13,16,17,18, 6, 6, 7, 7, 9, 9,10,14,17,19, 8, 7,
605.10528 +         6, 5, 6, 7, 9,12,19,17, 8, 7, 7, 6, 5, 6, 8,11,
605.10529 +        15,19, 9, 8, 7, 6, 5, 5, 6, 8,13,15,11,10, 8, 8,
605.10530 +         7, 5, 4, 4,10,14,12,13,11, 9, 7, 6, 4, 2, 6,12,
605.10531 +        18,16,16,13, 8, 7, 7, 5, 8,13,16,17,18,15,11, 9,
605.10532 +         9, 8,10,13,
605.10533 +};
605.10534 +
605.10535 +static const static_codebook _huff_book__44c9_s_short = {
605.10536 +        2, 100,
605.10537 +        (long *)_huff_lengthlist__44c9_s_short,
605.10538 +        0, 0, 0, 0, 0,
605.10539 +        NULL,
605.10540 +        0
605.10541 +};
605.10542 +
605.10543 +static const long _huff_lengthlist__44c0_s_long[] = {
605.10544 +         5, 4, 8, 9, 8, 9,10,12,15, 4, 1, 5, 5, 6, 8,11,
605.10545 +        12,12, 8, 5, 8, 9, 9,11,13,12,12, 9, 5, 8, 5, 7,
605.10546 +         9,12,13,13, 8, 6, 8, 7, 7, 9,11,11,11, 9, 7, 9,
605.10547 +         7, 7, 7, 7,10,12,10,10,11, 9, 8, 7, 7, 9,11,11,
605.10548 +        12,13,12,11, 9, 8, 9,11,13,16,16,15,15,12,10,11,
605.10549 +        12,
605.10550 +};
605.10551 +
605.10552 +static const static_codebook _huff_book__44c0_s_long = {
605.10553 +        2, 81,
605.10554 +        (long *)_huff_lengthlist__44c0_s_long,
605.10555 +        0, 0, 0, 0, 0,
605.10556 +        NULL,
605.10557 +        0
605.10558 +};
605.10559 +
605.10560 +static const long _vq_quantlist__44c0_s_p1_0[] = {
605.10561 +        1,
605.10562 +        0,
605.10563 +        2,
605.10564 +};
605.10565 +
605.10566 +static const long _vq_lengthlist__44c0_s_p1_0[] = {
605.10567 +         1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.10568 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10569 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10570 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10571 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10572 +         0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
605.10573 +         0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10574 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10575 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10576 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10577 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.10578 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10579 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10580 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10581 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10582 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10583 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10584 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10585 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10586 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10587 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10588 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10589 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10590 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10591 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10592 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10593 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10594 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10595 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10596 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10597 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10598 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10599 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10600 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10601 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10602 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10603 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10604 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10605 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10606 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10607 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10608 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10609 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10610 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10611 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10612 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.10613 +         0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.10614 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10615 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10616 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10617 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
605.10618 +         0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 9,11,10, 0,
605.10619 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10620 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10621 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10622 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.10623 +         0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0, 9,10,11,
605.10624 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10625 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10626 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10627 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10628 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10629 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10630 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10631 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10632 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10633 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10634 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10635 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10636 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10637 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10638 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10639 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10640 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10641 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10642 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10643 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10644 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10645 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10646 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10647 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10648 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10649 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10650 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10651 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10652 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10653 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10654 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10655 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10656 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10657 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10658 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.10659 +         0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10660 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10661 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10662 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10663 +         0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0,
605.10664 +         0, 0, 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 0, 0,
605.10665 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10666 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10667 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10668 +         0, 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 9,10,11,
605.10669 +         0, 0, 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 0,
605.10670 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10671 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10672 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10673 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10674 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10675 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10676 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10677 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10678 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10679 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10680 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10681 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10682 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10683 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10684 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10685 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10686 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10687 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10688 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10689 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10690 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10691 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10692 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10693 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10694 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10695 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10696 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10697 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10698 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10699 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10700 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10701 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10702 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10703 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10704 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10705 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10706 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10707 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10708 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10709 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10710 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10711 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10712 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10713 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10714 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10715 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10716 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10717 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10718 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10719 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10720 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10721 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10722 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10723 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10724 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10725 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10726 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10727 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10728 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10729 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10730 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10731 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10732 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10733 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10734 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10735 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10736 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10737 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10738 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10739 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10740 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10741 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10742 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10743 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10744 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10745 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10746 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10747 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10748 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10749 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10750 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10751 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10752 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10753 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10754 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10755 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10756 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10757 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10758 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10759 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10760 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10761 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10762 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10763 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10764 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10765 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10766 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10767 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10768 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10769 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10770 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10771 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10772 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10773 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10774 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10775 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10776 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10777 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10778 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10779 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10780 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10781 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10782 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10783 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10784 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10785 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10786 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10787 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10788 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10789 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10790 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10791 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10792 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10793 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10794 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10795 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10796 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10797 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10798 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10799 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10800 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10801 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10802 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10803 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10804 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10805 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10806 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10807 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10808 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10809 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10810 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10811 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10812 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10813 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10814 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10815 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10816 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10817 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10818 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10819 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10820 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10821 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10822 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10823 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10824 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10825 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10826 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10827 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10828 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10829 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10830 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10831 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10832 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10833 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10834 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10835 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10836 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10837 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10838 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10839 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10840 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10841 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10842 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10843 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10844 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10845 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10846 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10847 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10848 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10849 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10850 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10851 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10852 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10853 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10854 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10855 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10856 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10857 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10858 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10859 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10860 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10861 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10862 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10863 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10864 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10865 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10866 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10867 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10868 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10869 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10870 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10871 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10872 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10873 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10874 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10875 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10876 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10877 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10878 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10879 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10880 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10881 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10882 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10883 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10884 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10885 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10886 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10887 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10888 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10889 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10890 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10891 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10892 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10893 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10894 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10895 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10896 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10897 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10898 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10899 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10900 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10901 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10902 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10903 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10904 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10905 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10906 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10907 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10908 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10909 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10910 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10911 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10912 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10913 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10914 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10915 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10916 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10917 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10918 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10919 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10920 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10921 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10922 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10923 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10924 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10925 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10926 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10927 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10928 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10929 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10930 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10931 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10932 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10933 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10934 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10935 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10936 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10937 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10938 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10939 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10940 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10941 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10942 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10943 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10944 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10945 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10946 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10947 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10948 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10949 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10950 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10951 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10952 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10953 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10954 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10955 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10956 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10957 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10958 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10959 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10960 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10961 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10962 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10963 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10964 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10965 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10966 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10967 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10968 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10969 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10970 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10971 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10972 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10973 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10974 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10975 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10976 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10977 +         0,
605.10978 +};
605.10979 +
605.10980 +static const static_codebook _44c0_s_p1_0 = {
605.10981 +        8, 6561,
605.10982 +        (long *)_vq_lengthlist__44c0_s_p1_0,
605.10983 +        1, -535822336, 1611661312, 2, 0,
605.10984 +        (long *)_vq_quantlist__44c0_s_p1_0,
605.10985 +        0
605.10986 +};
605.10987 +
605.10988 +static const long _vq_quantlist__44c0_s_p2_0[] = {
605.10989 +        2,
605.10990 +        1,
605.10991 +        3,
605.10992 +        0,
605.10993 +        4,
605.10994 +};
605.10995 +
605.10996 +static const long _vq_lengthlist__44c0_s_p2_0[] = {
605.10997 +         1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.10998 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 6, 0, 0,
605.10999 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11000 +         0, 0, 4, 5, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11001 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9,
605.11002 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11003 +         0, 0, 0, 0, 6, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.11004 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11005 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11006 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11007 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11008 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11009 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11010 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11011 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11012 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11013 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11014 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11015 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11016 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11017 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11018 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11019 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11020 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11021 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11022 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11023 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11024 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11025 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11026 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11027 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11028 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11029 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11030 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11031 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11032 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11033 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11034 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11035 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11036 +         0,
605.11037 +};
605.11038 +
605.11039 +static const static_codebook _44c0_s_p2_0 = {
605.11040 +        4, 625,
605.11041 +        (long *)_vq_lengthlist__44c0_s_p2_0,
605.11042 +        1, -533725184, 1611661312, 3, 0,
605.11043 +        (long *)_vq_quantlist__44c0_s_p2_0,
605.11044 +        0
605.11045 +};
605.11046 +
605.11047 +static const long _vq_quantlist__44c0_s_p3_0[] = {
605.11048 +        4,
605.11049 +        3,
605.11050 +        5,
605.11051 +        2,
605.11052 +        6,
605.11053 +        1,
605.11054 +        7,
605.11055 +        0,
605.11056 +        8,
605.11057 +};
605.11058 +
605.11059 +static const long _vq_lengthlist__44c0_s_p3_0[] = {
605.11060 +         1, 3, 2, 8, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
605.11061 +         0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
605.11062 +         0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
605.11063 +         8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
605.11064 +         0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11065 +         0,
605.11066 +};
605.11067 +
605.11068 +static const static_codebook _44c0_s_p3_0 = {
605.11069 +        2, 81,
605.11070 +        (long *)_vq_lengthlist__44c0_s_p3_0,
605.11071 +        1, -531628032, 1611661312, 4, 0,
605.11072 +        (long *)_vq_quantlist__44c0_s_p3_0,
605.11073 +        0
605.11074 +};
605.11075 +
605.11076 +static const long _vq_quantlist__44c0_s_p4_0[] = {
605.11077 +        4,
605.11078 +        3,
605.11079 +        5,
605.11080 +        2,
605.11081 +        6,
605.11082 +        1,
605.11083 +        7,
605.11084 +        0,
605.11085 +        8,
605.11086 +};
605.11087 +
605.11088 +static const long _vq_lengthlist__44c0_s_p4_0[] = {
605.11089 +         1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7,
605.11090 +         9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 7, 7,
605.11091 +         7, 8, 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0,
605.11092 +         9, 9, 8, 8,10,10, 0, 0, 0, 8, 9, 8, 8,10,10, 0,
605.11093 +         0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
605.11094 +        10,
605.11095 +};
605.11096 +
605.11097 +static const static_codebook _44c0_s_p4_0 = {
605.11098 +        2, 81,
605.11099 +        (long *)_vq_lengthlist__44c0_s_p4_0,
605.11100 +        1, -531628032, 1611661312, 4, 0,
605.11101 +        (long *)_vq_quantlist__44c0_s_p4_0,
605.11102 +        0
605.11103 +};
605.11104 +
605.11105 +static const long _vq_quantlist__44c0_s_p5_0[] = {
605.11106 +        8,
605.11107 +        7,
605.11108 +        9,
605.11109 +        6,
605.11110 +        10,
605.11111 +        5,
605.11112 +        11,
605.11113 +        4,
605.11114 +        12,
605.11115 +        3,
605.11116 +        13,
605.11117 +        2,
605.11118 +        14,
605.11119 +        1,
605.11120 +        15,
605.11121 +        0,
605.11122 +        16,
605.11123 +};
605.11124 +
605.11125 +static const long _vq_lengthlist__44c0_s_p5_0[] = {
605.11126 +         1, 4, 3, 6, 6, 8, 7, 8, 8, 8, 8, 9, 9,10,10,11,
605.11127 +        11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9, 9,10,10,10,
605.11128 +        11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,
605.11129 +        10,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
605.11130 +        11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
605.11131 +        10,11,11,11,11, 0, 0, 0, 8, 8, 9, 9, 9, 9,10,10,
605.11132 +        10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9, 9,10,
605.11133 +        10,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
605.11134 +        10,10,11,11,11,12,12,12, 0, 0, 0, 0, 0, 9, 9,10,
605.11135 +        10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,
605.11136 +        10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
605.11137 +         9,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
605.11138 +        10,10,11,11,11,11,11,12,12,12,13,13, 0, 0, 0, 0,
605.11139 +         0, 0, 0,11,10,11,11,11,11,12,12,13,13, 0, 0, 0,
605.11140 +         0, 0, 0, 0,11,11,12,11,12,12,12,12,13,13, 0, 0,
605.11141 +         0, 0, 0, 0, 0,11,11,11,12,12,12,12,13,13,13, 0,
605.11142 +         0, 0, 0, 0, 0, 0,12,12,12,12,12,13,13,13,14,14,
605.11143 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14,
605.11144 +        14,
605.11145 +};
605.11146 +
605.11147 +static const static_codebook _44c0_s_p5_0 = {
605.11148 +        2, 289,
605.11149 +        (long *)_vq_lengthlist__44c0_s_p5_0,
605.11150 +        1, -529530880, 1611661312, 5, 0,
605.11151 +        (long *)_vq_quantlist__44c0_s_p5_0,
605.11152 +        0
605.11153 +};
605.11154 +
605.11155 +static const long _vq_quantlist__44c0_s_p6_0[] = {
605.11156 +        1,
605.11157 +        0,
605.11158 +        2,
605.11159 +};
605.11160 +
605.11161 +static const long _vq_lengthlist__44c0_s_p6_0[] = {
605.11162 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10,
605.11163 +         9, 9, 4, 6, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11,
605.11164 +        11,12,10,11, 6, 9, 9,11,10,11,11,10,10, 6, 9, 9,
605.11165 +        11,10,11,11,10,10, 7,11,10,12,11,11,11,11,11, 7,
605.11166 +         9, 9,10,10,10,11,11,10, 6, 9, 9,11,10,10,11,10,
605.11167 +        10,
605.11168 +};
605.11169 +
605.11170 +static const static_codebook _44c0_s_p6_0 = {
605.11171 +        4, 81,
605.11172 +        (long *)_vq_lengthlist__44c0_s_p6_0,
605.11173 +        1, -529137664, 1618345984, 2, 0,
605.11174 +        (long *)_vq_quantlist__44c0_s_p6_0,
605.11175 +        0
605.11176 +};
605.11177 +
605.11178 +static const long _vq_quantlist__44c0_s_p6_1[] = {
605.11179 +        5,
605.11180 +        4,
605.11181 +        6,
605.11182 +        3,
605.11183 +        7,
605.11184 +        2,
605.11185 +        8,
605.11186 +        1,
605.11187 +        9,
605.11188 +        0,
605.11189 +        10,
605.11190 +};
605.11191 +
605.11192 +static const long _vq_lengthlist__44c0_s_p6_1[] = {
605.11193 +         2, 3, 3, 6, 6, 7, 7, 7, 7, 7, 8,10,10,10, 6, 6,
605.11194 +         7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8,
605.11195 +         8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
605.11196 +         7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 7, 8, 8, 8, 8,
605.11197 +         8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
605.11198 +         8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
605.11199 +         8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
605.11200 +        10,10,10, 8, 8, 8, 8, 8, 8,
605.11201 +};
605.11202 +
605.11203 +static const static_codebook _44c0_s_p6_1 = {
605.11204 +        2, 121,
605.11205 +        (long *)_vq_lengthlist__44c0_s_p6_1,
605.11206 +        1, -531365888, 1611661312, 4, 0,
605.11207 +        (long *)_vq_quantlist__44c0_s_p6_1,
605.11208 +        0
605.11209 +};
605.11210 +
605.11211 +static const long _vq_quantlist__44c0_s_p7_0[] = {
605.11212 +        6,
605.11213 +        5,
605.11214 +        7,
605.11215 +        4,
605.11216 +        8,
605.11217 +        3,
605.11218 +        9,
605.11219 +        2,
605.11220 +        10,
605.11221 +        1,
605.11222 +        11,
605.11223 +        0,
605.11224 +        12,
605.11225 +};
605.11226 +
605.11227 +static const long _vq_lengthlist__44c0_s_p7_0[] = {
605.11228 +         1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 5, 5,
605.11229 +         7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 6, 7, 7, 8,
605.11230 +         8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.11231 +        10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.11232 +        11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13,
605.11233 +        13, 9, 9, 9, 9,10,10,11,11,11,12, 0, 0, 0,10,10,
605.11234 +        10,10,11,11,11,11,12,12, 0, 0, 0,10,10, 9, 9,11,
605.11235 +        11,11,12,12,12, 0, 0, 0,13,13,10,10,11,11,12,12,
605.11236 +        13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0,
605.11237 +         0, 0, 0, 0,11,11,11,11,13,12,13,13, 0, 0, 0, 0,
605.11238 +         0,12,12,11,11,12,12,13,13,
605.11239 +};
605.11240 +
605.11241 +static const static_codebook _44c0_s_p7_0 = {
605.11242 +        2, 169,
605.11243 +        (long *)_vq_lengthlist__44c0_s_p7_0,
605.11244 +        1, -526516224, 1616117760, 4, 0,
605.11245 +        (long *)_vq_quantlist__44c0_s_p7_0,
605.11246 +        0
605.11247 +};
605.11248 +
605.11249 +static const long _vq_quantlist__44c0_s_p7_1[] = {
605.11250 +        2,
605.11251 +        1,
605.11252 +        3,
605.11253 +        0,
605.11254 +        4,
605.11255 +};
605.11256 +
605.11257 +static const long _vq_lengthlist__44c0_s_p7_1[] = {
605.11258 +         2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
605.11259 +         6, 6, 5, 5, 6, 6, 6, 5, 5,
605.11260 +};
605.11261 +
605.11262 +static const static_codebook _44c0_s_p7_1 = {
605.11263 +        2, 25,
605.11264 +        (long *)_vq_lengthlist__44c0_s_p7_1,
605.11265 +        1, -533725184, 1611661312, 3, 0,
605.11266 +        (long *)_vq_quantlist__44c0_s_p7_1,
605.11267 +        0
605.11268 +};
605.11269 +
605.11270 +static const long _vq_quantlist__44c0_s_p8_0[] = {
605.11271 +        2,
605.11272 +        1,
605.11273 +        3,
605.11274 +        0,
605.11275 +        4,
605.11276 +};
605.11277 +
605.11278 +static const long _vq_lengthlist__44c0_s_p8_0[] = {
605.11279 +         1, 5, 5,10,10, 6, 9, 8,10,10, 6,10, 9,10,10,10,
605.11280 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.11281 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.11282 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.11283 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.11284 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.11285 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.11286 +        10,10,10,10,10,10,10,10,10,10,10,10,10, 8,10,10,
605.11287 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.11288 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.11289 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.11290 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.11291 +        10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,
605.11292 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11293 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11294 +        11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,
605.11295 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11296 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11297 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11298 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11299 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11300 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11301 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11302 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11303 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11304 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11305 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11306 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11307 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11308 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11309 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11310 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11311 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11312 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11313 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11314 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11315 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11316 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11317 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.11318 +        11,
605.11319 +};
605.11320 +
605.11321 +static const static_codebook _44c0_s_p8_0 = {
605.11322 +        4, 625,
605.11323 +        (long *)_vq_lengthlist__44c0_s_p8_0,
605.11324 +        1, -518283264, 1627103232, 3, 0,
605.11325 +        (long *)_vq_quantlist__44c0_s_p8_0,
605.11326 +        0
605.11327 +};
605.11328 +
605.11329 +static const long _vq_quantlist__44c0_s_p8_1[] = {
605.11330 +        6,
605.11331 +        5,
605.11332 +        7,
605.11333 +        4,
605.11334 +        8,
605.11335 +        3,
605.11336 +        9,
605.11337 +        2,
605.11338 +        10,
605.11339 +        1,
605.11340 +        11,
605.11341 +        0,
605.11342 +        12,
605.11343 +};
605.11344 +
605.11345 +static const long _vq_lengthlist__44c0_s_p8_1[] = {
605.11346 +         1, 4, 4, 6, 6, 7, 7, 9, 9,11,12,13,12, 6, 5, 5,
605.11347 +         7, 7, 8, 8,10, 9,12,12,12,12, 6, 5, 5, 7, 7, 8,
605.11348 +         8,10, 9,12,11,11,13,16, 7, 7, 8, 8, 9, 9,10,10,
605.11349 +        12,12,13,12,16, 7, 7, 8, 7, 9, 9,10,10,11,12,12,
605.11350 +        13,16,10,10, 8, 8,10,10,11,12,12,12,13,13,16,11,
605.11351 +        10, 8, 7,11,10,11,11,12,11,13,13,16,16,16,10,10,
605.11352 +        10,10,11,11,13,12,13,13,16,16,16,11, 9,11, 9,15,
605.11353 +        13,12,13,13,13,16,16,16,15,13,11,11,12,13,12,12,
605.11354 +        14,13,16,16,16,14,13,11,11,13,12,14,13,13,13,16,
605.11355 +        16,16,16,16,13,13,13,12,14,13,14,14,16,16,16,16,
605.11356 +        16,13,13,12,12,14,14,15,13,
605.11357 +};
605.11358 +
605.11359 +static const static_codebook _44c0_s_p8_1 = {
605.11360 +        2, 169,
605.11361 +        (long *)_vq_lengthlist__44c0_s_p8_1,
605.11362 +        1, -522616832, 1620115456, 4, 0,
605.11363 +        (long *)_vq_quantlist__44c0_s_p8_1,
605.11364 +        0
605.11365 +};
605.11366 +
605.11367 +static const long _vq_quantlist__44c0_s_p8_2[] = {
605.11368 +        8,
605.11369 +        7,
605.11370 +        9,
605.11371 +        6,
605.11372 +        10,
605.11373 +        5,
605.11374 +        11,
605.11375 +        4,
605.11376 +        12,
605.11377 +        3,
605.11378 +        13,
605.11379 +        2,
605.11380 +        14,
605.11381 +        1,
605.11382 +        15,
605.11383 +        0,
605.11384 +        16,
605.11385 +};
605.11386 +
605.11387 +static const long _vq_lengthlist__44c0_s_p8_2[] = {
605.11388 +         2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
605.11389 +         8,10,10,10, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9,
605.11390 +         9, 9,10,10,10, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9,
605.11391 +         9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,
605.11392 +         9,10, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9,
605.11393 +         9,10, 9, 9,10,10,10,10, 8, 8, 8, 8, 9, 8, 9, 9,
605.11394 +         9, 9, 9,10, 9,10,10,10,10, 7, 7, 8, 8, 9, 9, 9,
605.11395 +         9, 9, 9,10, 9,10,10,10,10,10, 8, 8, 8, 9, 9, 9,
605.11396 +         9, 9, 9, 9,10,10,10, 9,11,10,10,10,10, 8, 8, 9,
605.11397 +         9, 9, 9, 9,10, 9, 9, 9,10,10,10,10,11,11, 9, 9,
605.11398 +         9, 9, 9, 9, 9, 9,10, 9, 9,10,11,10,10,11,11, 9,
605.11399 +         9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,11,10,11,11,
605.11400 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,10,10,11,
605.11401 +        11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,
605.11402 +        11,11,11,11, 9,10, 9,10, 9, 9, 9, 9,10, 9,10,11,
605.11403 +        10,11,10,10,10,10,10, 9, 9, 9,10, 9, 9, 9,10,11,
605.11404 +        11,10,11,11,10,11,10,10,10, 9, 9, 9, 9,10, 9, 9,
605.11405 +        10,11,10,11,11,11,11,10,11,10,10, 9,10, 9, 9, 9,
605.11406 +        10,
605.11407 +};
605.11408 +
605.11409 +static const static_codebook _44c0_s_p8_2 = {
605.11410 +        2, 289,
605.11411 +        (long *)_vq_lengthlist__44c0_s_p8_2,
605.11412 +        1, -529530880, 1611661312, 5, 0,
605.11413 +        (long *)_vq_quantlist__44c0_s_p8_2,
605.11414 +        0
605.11415 +};
605.11416 +
605.11417 +static const long _huff_lengthlist__44c0_s_short[] = {
605.11418 +         9, 8,12,11,12,13,14,14,16, 6, 1, 5, 6, 6, 9,12,
605.11419 +        14,17, 9, 4, 5, 9, 7, 9,13,15,16, 8, 5, 8, 6, 8,
605.11420 +        10,13,17,17, 9, 6, 7, 7, 8, 9,13,15,17,11, 8, 9,
605.11421 +         9, 9,10,12,16,16,13, 7, 8, 7, 7, 9,12,14,15,13,
605.11422 +         6, 7, 5, 5, 7,10,13,13,14, 7, 8, 5, 6, 7, 9,10,
605.11423 +        12,
605.11424 +};
605.11425 +
605.11426 +static const static_codebook _huff_book__44c0_s_short = {
605.11427 +        2, 81,
605.11428 +        (long *)_huff_lengthlist__44c0_s_short,
605.11429 +        0, 0, 0, 0, 0,
605.11430 +        NULL,
605.11431 +        0
605.11432 +};
605.11433 +
605.11434 +static const long _huff_lengthlist__44c0_sm_long[] = {
605.11435 +         5, 4, 9,10, 9,10,11,12,13, 4, 1, 5, 7, 7, 9,11,
605.11436 +        12,14, 8, 5, 7, 9, 8,10,13,13,13,10, 7, 9, 4, 6,
605.11437 +         7,10,12,14, 9, 6, 7, 6, 6, 7,10,12,12, 9, 8, 9,
605.11438 +         7, 6, 7, 8,11,12,11,11,11, 9, 8, 7, 8,10,12,12,
605.11439 +        13,14,12,11, 9, 9, 9,12,12,17,17,15,16,12,10,11,
605.11440 +        13,
605.11441 +};
605.11442 +
605.11443 +static const static_codebook _huff_book__44c0_sm_long = {
605.11444 +        2, 81,
605.11445 +        (long *)_huff_lengthlist__44c0_sm_long,
605.11446 +        0, 0, 0, 0, 0,
605.11447 +        NULL,
605.11448 +        0
605.11449 +};
605.11450 +
605.11451 +static const long _vq_quantlist__44c0_sm_p1_0[] = {
605.11452 +        1,
605.11453 +        0,
605.11454 +        2,
605.11455 +};
605.11456 +
605.11457 +static const long _vq_lengthlist__44c0_sm_p1_0[] = {
605.11458 +         1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.11459 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11460 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11463 +         0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
605.11464 +         0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11465 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11466 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11468 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
605.11469 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11470 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11471 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11472 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11473 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11474 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11475 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11476 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11477 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11478 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11479 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11480 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11481 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11482 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11483 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11484 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11485 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11486 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11487 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11488 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11489 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11490 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11491 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11492 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11493 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11494 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11495 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11496 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11497 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11498 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11499 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11500 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11501 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11502 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11503 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0,
605.11504 +         0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
605.11505 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11506 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11507 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11508 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
605.11509 +         0, 0, 0, 9,10,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
605.11510 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11511 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11512 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11513 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.11514 +         0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
605.11515 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11516 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11517 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11518 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11519 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11520 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11521 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11522 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11523 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11525 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11526 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11527 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11528 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11529 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11530 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11531 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11532 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11533 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11534 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11535 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11536 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11537 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11538 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11539 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11540 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11541 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11542 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11543 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11544 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11545 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11546 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11547 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11548 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11549 +         0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.11550 +         0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11551 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11552 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11553 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11554 +         0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
605.11555 +         0, 0, 0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 0, 0,
605.11556 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11557 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11558 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11559 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
605.11560 +         0, 0, 0, 0, 0, 0, 9,10,10, 0, 0, 0, 0, 0, 0, 0,
605.11561 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11562 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11563 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11564 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11565 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11566 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11567 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11568 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11569 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11570 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11571 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11572 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11573 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11574 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11575 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11576 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11577 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11578 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11579 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11580 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11581 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11582 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11583 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11584 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11585 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11586 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11587 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11588 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11589 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11590 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11591 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11592 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11593 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11594 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11595 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11596 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11597 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11598 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11599 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11600 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11601 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11602 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11603 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11604 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11605 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11606 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11607 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11608 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11609 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11610 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11611 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11612 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11613 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11614 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11615 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11616 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11617 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11618 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11619 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11620 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11621 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11622 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11623 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11624 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11625 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11626 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11627 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11628 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11629 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11630 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11631 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11632 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11633 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11634 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11635 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11636 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11637 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11638 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11639 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11640 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11641 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11642 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11643 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11644 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11645 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11646 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11647 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11648 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11649 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11650 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11651 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11652 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11653 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11654 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11655 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11656 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11657 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11658 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11659 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11660 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11661 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11662 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11663 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11664 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11665 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11666 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11667 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11668 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11669 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11670 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11671 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11672 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11673 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11674 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11675 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11676 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11677 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11678 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11679 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11680 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11681 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11682 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11683 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11684 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11685 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11686 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11687 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11688 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11689 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11690 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11691 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11692 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11693 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11694 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11695 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11696 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11697 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11698 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11699 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11700 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11701 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11702 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11703 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11704 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11705 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11706 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11707 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11708 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11709 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11710 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11711 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11712 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11713 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11714 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11715 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11716 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11717 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11718 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11719 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11720 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11721 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11722 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11723 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11724 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11725 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11726 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11727 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11728 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11729 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11730 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11731 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11732 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11733 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11734 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11735 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11736 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11737 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11738 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11739 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11740 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11741 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11742 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11743 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11744 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11745 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11746 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11747 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11748 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11749 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11750 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11751 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11752 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11753 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11754 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11755 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11756 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11757 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11758 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11759 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11760 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11761 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11762 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11763 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11764 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11765 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11766 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11767 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11768 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11769 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11770 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11771 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11772 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11773 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11774 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11775 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11776 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11777 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11778 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11779 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11780 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11781 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11782 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11783 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11784 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11785 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11786 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11787 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11788 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11789 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11790 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11791 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11792 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11793 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11794 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11795 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11796 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11797 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11798 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11799 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11800 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11801 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11802 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11803 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11804 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11805 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11806 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11807 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11808 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11809 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11810 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11811 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11812 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11813 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11814 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11815 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11816 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11817 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11818 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11819 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11820 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11821 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11822 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11823 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11824 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11825 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11826 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11827 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11828 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11829 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11830 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11831 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11832 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11833 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11834 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11835 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11836 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11837 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11838 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11839 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11840 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11841 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11842 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11843 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11844 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11845 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11846 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11847 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11848 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11849 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11850 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11851 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11852 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11853 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11854 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11855 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11856 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11857 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11858 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11859 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11860 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11861 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11862 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11863 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11864 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11865 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11866 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11867 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11868 +         0,
605.11869 +};
605.11870 +
605.11871 +static const static_codebook _44c0_sm_p1_0 = {
605.11872 +        8, 6561,
605.11873 +        (long *)_vq_lengthlist__44c0_sm_p1_0,
605.11874 +        1, -535822336, 1611661312, 2, 0,
605.11875 +        (long *)_vq_quantlist__44c0_sm_p1_0,
605.11876 +        0
605.11877 +};
605.11878 +
605.11879 +static const long _vq_quantlist__44c0_sm_p2_0[] = {
605.11880 +        2,
605.11881 +        1,
605.11882 +        3,
605.11883 +        0,
605.11884 +        4,
605.11885 +};
605.11886 +
605.11887 +static const long _vq_lengthlist__44c0_sm_p2_0[] = {
605.11888 +         1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11889 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0,
605.11890 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11891 +         0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11892 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9,
605.11893 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11894 +         0, 0, 0, 0, 7, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.11895 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11896 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11897 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11898 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11899 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11900 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11901 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11902 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11903 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11904 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11905 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11906 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11907 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11908 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11909 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11910 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11911 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11912 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11913 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11914 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11915 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11916 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11917 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11918 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11919 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11920 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11921 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11922 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11923 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11924 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11925 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11926 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11927 +         0,
605.11928 +};
605.11929 +
605.11930 +static const static_codebook _44c0_sm_p2_0 = {
605.11931 +        4, 625,
605.11932 +        (long *)_vq_lengthlist__44c0_sm_p2_0,
605.11933 +        1, -533725184, 1611661312, 3, 0,
605.11934 +        (long *)_vq_quantlist__44c0_sm_p2_0,
605.11935 +        0
605.11936 +};
605.11937 +
605.11938 +static const long _vq_quantlist__44c0_sm_p3_0[] = {
605.11939 +        4,
605.11940 +        3,
605.11941 +        5,
605.11942 +        2,
605.11943 +        6,
605.11944 +        1,
605.11945 +        7,
605.11946 +        0,
605.11947 +        8,
605.11948 +};
605.11949 +
605.11950 +static const long _vq_lengthlist__44c0_sm_p3_0[] = {
605.11951 +         1, 3, 3, 7, 7, 0, 0, 0, 0, 0, 5, 4, 7, 7, 0, 0,
605.11952 +         0, 0, 0, 5, 5, 7, 7, 0, 0, 0, 0, 0, 6, 7, 8, 8,
605.11953 +         0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0,
605.11954 +         9,10, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0,
605.11955 +         0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.11956 +         0,
605.11957 +};
605.11958 +
605.11959 +static const static_codebook _44c0_sm_p3_0 = {
605.11960 +        2, 81,
605.11961 +        (long *)_vq_lengthlist__44c0_sm_p3_0,
605.11962 +        1, -531628032, 1611661312, 4, 0,
605.11963 +        (long *)_vq_quantlist__44c0_sm_p3_0,
605.11964 +        0
605.11965 +};
605.11966 +
605.11967 +static const long _vq_quantlist__44c0_sm_p4_0[] = {
605.11968 +        4,
605.11969 +        3,
605.11970 +        5,
605.11971 +        2,
605.11972 +        6,
605.11973 +        1,
605.11974 +        7,
605.11975 +        0,
605.11976 +        8,
605.11977 +};
605.11978 +
605.11979 +static const long _vq_lengthlist__44c0_sm_p4_0[] = {
605.11980 +         1, 4, 3, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 8, 7,
605.11981 +         9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8,
605.11982 +         8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0,
605.11983 +         9, 9, 9, 9,11,11, 0, 0, 0, 9, 9, 9, 9,11,11, 0,
605.11984 +         0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0, 9, 9,11,
605.11985 +        11,
605.11986 +};
605.11987 +
605.11988 +static const static_codebook _44c0_sm_p4_0 = {
605.11989 +        2, 81,
605.11990 +        (long *)_vq_lengthlist__44c0_sm_p4_0,
605.11991 +        1, -531628032, 1611661312, 4, 0,
605.11992 +        (long *)_vq_quantlist__44c0_sm_p4_0,
605.11993 +        0
605.11994 +};
605.11995 +
605.11996 +static const long _vq_quantlist__44c0_sm_p5_0[] = {
605.11997 +        8,
605.11998 +        7,
605.11999 +        9,
605.12000 +        6,
605.12001 +        10,
605.12002 +        5,
605.12003 +        11,
605.12004 +        4,
605.12005 +        12,
605.12006 +        3,
605.12007 +        13,
605.12008 +        2,
605.12009 +        14,
605.12010 +        1,
605.12011 +        15,
605.12012 +        0,
605.12013 +        16,
605.12014 +};
605.12015 +
605.12016 +static const long _vq_lengthlist__44c0_sm_p5_0[] = {
605.12017 +         1, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 9, 9,10,10,11,
605.12018 +        11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,11,
605.12019 +        11,11, 0, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,
605.12020 +        11,11,11, 0, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,
605.12021 +        11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,
605.12022 +        10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,
605.12023 +        11,11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,
605.12024 +        10,11,11,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
605.12025 +        10,10,11,11,12,12,12,13, 0, 0, 0, 0, 0, 9, 9,10,
605.12026 +        10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
605.12027 +        10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
605.12028 +         9,10,10,11,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
605.12029 +        10,10,10,10,11,11,12,12,12,13,13,13, 0, 0, 0, 0,
605.12030 +         0, 0, 0,10,10,11,11,12,12,12,13,13,13, 0, 0, 0,
605.12031 +         0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0, 0,
605.12032 +         0, 0, 0, 0, 0,11,11,12,11,12,12,13,13,13,13, 0,
605.12033 +         0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14,
605.12034 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14,
605.12035 +        14,
605.12036 +};
605.12037 +
605.12038 +static const static_codebook _44c0_sm_p5_0 = {
605.12039 +        2, 289,
605.12040 +        (long *)_vq_lengthlist__44c0_sm_p5_0,
605.12041 +        1, -529530880, 1611661312, 5, 0,
605.12042 +        (long *)_vq_quantlist__44c0_sm_p5_0,
605.12043 +        0
605.12044 +};
605.12045 +
605.12046 +static const long _vq_quantlist__44c0_sm_p6_0[] = {
605.12047 +        1,
605.12048 +        0,
605.12049 +        2,
605.12050 +};
605.12051 +
605.12052 +static const long _vq_lengthlist__44c0_sm_p6_0[] = {
605.12053 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
605.12054 +         9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,10,11,
605.12055 +        11,11,10,10, 6, 9, 9,11,11,10,11,10,10, 6, 9, 9,
605.12056 +        11,10,11,11,10,10, 7,11,10,11,11,11,11,11,11, 6,
605.12057 +         9, 9,11,10,10,11,11,10, 6, 9, 9,11,10,10,11,10,
605.12058 +        11,
605.12059 +};
605.12060 +
605.12061 +static const static_codebook _44c0_sm_p6_0 = {
605.12062 +        4, 81,
605.12063 +        (long *)_vq_lengthlist__44c0_sm_p6_0,
605.12064 +        1, -529137664, 1618345984, 2, 0,
605.12065 +        (long *)_vq_quantlist__44c0_sm_p6_0,
605.12066 +        0
605.12067 +};
605.12068 +
605.12069 +static const long _vq_quantlist__44c0_sm_p6_1[] = {
605.12070 +        5,
605.12071 +        4,
605.12072 +        6,
605.12073 +        3,
605.12074 +        7,
605.12075 +        2,
605.12076 +        8,
605.12077 +        1,
605.12078 +        9,
605.12079 +        0,
605.12080 +        10,
605.12081 +};
605.12082 +
605.12083 +static const long _vq_lengthlist__44c0_sm_p6_1[] = {
605.12084 +         2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 8, 9, 5, 5, 6, 6,
605.12085 +         7, 7, 8, 8, 8, 8, 9, 5, 5, 6, 6, 7, 7, 8, 8, 8,
605.12086 +         8,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
605.12087 +         7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8,
605.12088 +         8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,
605.12089 +         8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
605.12090 +         8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
605.12091 +        10,10,10, 8, 8, 8, 8, 8, 8,
605.12092 +};
605.12093 +
605.12094 +static const static_codebook _44c0_sm_p6_1 = {
605.12095 +        2, 121,
605.12096 +        (long *)_vq_lengthlist__44c0_sm_p6_1,
605.12097 +        1, -531365888, 1611661312, 4, 0,
605.12098 +        (long *)_vq_quantlist__44c0_sm_p6_1,
605.12099 +        0
605.12100 +};
605.12101 +
605.12102 +static const long _vq_quantlist__44c0_sm_p7_0[] = {
605.12103 +        6,
605.12104 +        5,
605.12105 +        7,
605.12106 +        4,
605.12107 +        8,
605.12108 +        3,
605.12109 +        9,
605.12110 +        2,
605.12111 +        10,
605.12112 +        1,
605.12113 +        11,
605.12114 +        0,
605.12115 +        12,
605.12116 +};
605.12117 +
605.12118 +static const long _vq_lengthlist__44c0_sm_p7_0[] = {
605.12119 +         1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 5, 5,
605.12120 +         7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 6, 5, 7, 7, 8,
605.12121 +         8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.12122 +        10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.12123 +        11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13,
605.12124 +        13, 9, 9, 9, 9,10,10,11,11,11,12, 0, 0, 0, 9,10,
605.12125 +        10,10,11,11,12,11,12,12, 0, 0, 0,10,10, 9, 9,11,
605.12126 +        11,12,12,12,12, 0, 0, 0,13,13,10,10,11,11,12,12,
605.12127 +        13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0,
605.12128 +         0, 0, 0, 0,11,12,11,11,13,12,13,13, 0, 0, 0, 0,
605.12129 +         0,12,12,11,11,13,12,14,14,
605.12130 +};
605.12131 +
605.12132 +static const static_codebook _44c0_sm_p7_0 = {
605.12133 +        2, 169,
605.12134 +        (long *)_vq_lengthlist__44c0_sm_p7_0,
605.12135 +        1, -526516224, 1616117760, 4, 0,
605.12136 +        (long *)_vq_quantlist__44c0_sm_p7_0,
605.12137 +        0
605.12138 +};
605.12139 +
605.12140 +static const long _vq_quantlist__44c0_sm_p7_1[] = {
605.12141 +        2,
605.12142 +        1,
605.12143 +        3,
605.12144 +        0,
605.12145 +        4,
605.12146 +};
605.12147 +
605.12148 +static const long _vq_lengthlist__44c0_sm_p7_1[] = {
605.12149 +         2, 4, 4, 4, 4, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6,
605.12150 +         6, 6, 5, 5, 6, 6, 6, 5, 5,
605.12151 +};
605.12152 +
605.12153 +static const static_codebook _44c0_sm_p7_1 = {
605.12154 +        2, 25,
605.12155 +        (long *)_vq_lengthlist__44c0_sm_p7_1,
605.12156 +        1, -533725184, 1611661312, 3, 0,
605.12157 +        (long *)_vq_quantlist__44c0_sm_p7_1,
605.12158 +        0
605.12159 +};
605.12160 +
605.12161 +static const long _vq_quantlist__44c0_sm_p8_0[] = {
605.12162 +        4,
605.12163 +        3,
605.12164 +        5,
605.12165 +        2,
605.12166 +        6,
605.12167 +        1,
605.12168 +        7,
605.12169 +        0,
605.12170 +        8,
605.12171 +};
605.12172 +
605.12173 +static const long _vq_lengthlist__44c0_sm_p8_0[] = {
605.12174 +         1, 3, 3,11,11,11,11,11,11, 3, 7, 6,11,11,11,11,
605.12175 +        11,11, 4, 8, 7,11,11,11,11,11,11,11,11,11,11,11,
605.12176 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.12177 +        11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.12178 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.12179 +        12,
605.12180 +};
605.12181 +
605.12182 +static const static_codebook _44c0_sm_p8_0 = {
605.12183 +        2, 81,
605.12184 +        (long *)_vq_lengthlist__44c0_sm_p8_0,
605.12185 +        1, -516186112, 1627103232, 4, 0,
605.12186 +        (long *)_vq_quantlist__44c0_sm_p8_0,
605.12187 +        0
605.12188 +};
605.12189 +
605.12190 +static const long _vq_quantlist__44c0_sm_p8_1[] = {
605.12191 +        6,
605.12192 +        5,
605.12193 +        7,
605.12194 +        4,
605.12195 +        8,
605.12196 +        3,
605.12197 +        9,
605.12198 +        2,
605.12199 +        10,
605.12200 +        1,
605.12201 +        11,
605.12202 +        0,
605.12203 +        12,
605.12204 +};
605.12205 +
605.12206 +static const long _vq_lengthlist__44c0_sm_p8_1[] = {
605.12207 +         1, 4, 4, 6, 6, 7, 7, 9, 9,10,11,12,12, 6, 5, 5,
605.12208 +         7, 7, 8, 8,10,10,12,11,12,12, 6, 5, 5, 7, 7, 8,
605.12209 +         8,10,10,12,11,12,12,17, 7, 7, 8, 8, 9, 9,10,10,
605.12210 +        12,12,13,13,18, 7, 7, 8, 7, 9, 9,10,10,12,12,12,
605.12211 +        13,19,10,10, 8, 8,10,10,11,11,12,12,13,14,19,11,
605.12212 +        10, 8, 7,10,10,11,11,12,12,13,12,19,19,19,10,10,
605.12213 +        10,10,11,11,12,12,13,13,19,19,19,11, 9,11, 9,14,
605.12214 +        12,13,12,13,13,19,20,18,13,14,11,11,12,12,13,13,
605.12215 +        14,13,20,20,20,15,13,11,10,13,11,13,13,14,13,20,
605.12216 +        20,20,20,20,13,14,12,12,13,13,13,13,20,20,20,20,
605.12217 +        20,13,13,12,12,16,13,15,13,
605.12218 +};
605.12219 +
605.12220 +static const static_codebook _44c0_sm_p8_1 = {
605.12221 +        2, 169,
605.12222 +        (long *)_vq_lengthlist__44c0_sm_p8_1,
605.12223 +        1, -522616832, 1620115456, 4, 0,
605.12224 +        (long *)_vq_quantlist__44c0_sm_p8_1,
605.12225 +        0
605.12226 +};
605.12227 +
605.12228 +static const long _vq_quantlist__44c0_sm_p8_2[] = {
605.12229 +        8,
605.12230 +        7,
605.12231 +        9,
605.12232 +        6,
605.12233 +        10,
605.12234 +        5,
605.12235 +        11,
605.12236 +        4,
605.12237 +        12,
605.12238 +        3,
605.12239 +        13,
605.12240 +        2,
605.12241 +        14,
605.12242 +        1,
605.12243 +        15,
605.12244 +        0,
605.12245 +        16,
605.12246 +};
605.12247 +
605.12248 +static const long _vq_lengthlist__44c0_sm_p8_2[] = {
605.12249 +         2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
605.12250 +         8,10, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
605.12251 +         9, 9,10, 6, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9,
605.12252 +         9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9,
605.12253 +         9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9,
605.12254 +         9,10, 9, 9,10,10,10,11, 8, 8, 8, 8, 9, 9, 9, 9,
605.12255 +         9, 9, 9,10, 9,10,10,10,10, 8, 8, 8, 8, 9, 9, 9,
605.12256 +         9, 9, 9, 9, 9,10,10,11,10,10, 8, 8, 9, 9, 9, 9,
605.12257 +         9, 9, 9, 9, 9, 9,10,10,10,10,10,11,11, 8, 8, 9,
605.12258 +         9, 9, 9, 9, 9, 9, 9, 9,10,11,11,11,11,11, 9, 9,
605.12259 +         9, 9, 9, 9, 9, 9,10, 9,10, 9,11,11,10,11,11, 9,
605.12260 +         9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,11,10,11,11,
605.12261 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,10,11,11,
605.12262 +        11,11,11, 9, 9,10, 9, 9, 9, 9, 9, 9, 9,10,11,10,
605.12263 +        11,11,11,11,10,10,10,10, 9, 9, 9, 9, 9, 9,10,11,
605.12264 +        11,11,11,11,11, 9,10, 9, 9, 9, 9, 9, 9, 9, 9,11,
605.12265 +        11,10,11,11,11,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,
605.12266 +        10,11,10,11,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9,
605.12267 +         9,
605.12268 +};
605.12269 +
605.12270 +static const static_codebook _44c0_sm_p8_2 = {
605.12271 +        2, 289,
605.12272 +        (long *)_vq_lengthlist__44c0_sm_p8_2,
605.12273 +        1, -529530880, 1611661312, 5, 0,
605.12274 +        (long *)_vq_quantlist__44c0_sm_p8_2,
605.12275 +        0
605.12276 +};
605.12277 +
605.12278 +static const long _huff_lengthlist__44c0_sm_short[] = {
605.12279 +         6, 6,12,13,13,14,16,17,17, 4, 2, 5, 8, 7, 9,12,
605.12280 +        15,15, 9, 4, 5, 9, 7, 9,12,16,18,11, 6, 7, 4, 6,
605.12281 +         8,11,14,18,10, 5, 6, 5, 5, 7,10,14,17,10, 5, 7,
605.12282 +         7, 6, 7,10,13,16,11, 5, 7, 7, 7, 8,10,12,15,13,
605.12283 +         6, 7, 5, 5, 7, 9,12,13,16, 8, 9, 6, 6, 7, 9,10,
605.12284 +        12,
605.12285 +};
605.12286 +
605.12287 +static const static_codebook _huff_book__44c0_sm_short = {
605.12288 +        2, 81,
605.12289 +        (long *)_huff_lengthlist__44c0_sm_short,
605.12290 +        0, 0, 0, 0, 0,
605.12291 +        NULL,
605.12292 +        0
605.12293 +};
605.12294 +
605.12295 +static const long _huff_lengthlist__44c1_s_long[] = {
605.12296 +         5, 5, 9,10, 9, 9,10,11,12, 5, 1, 5, 6, 6, 7,10,
605.12297 +        12,14, 9, 5, 6, 8, 8,10,12,14,14,10, 5, 8, 5, 6,
605.12298 +         8,11,13,14, 9, 5, 7, 6, 6, 8,10,12,11, 9, 7, 9,
605.12299 +         7, 6, 6, 7,10,10,10, 9,12, 9, 8, 7, 7,10,12,11,
605.12300 +        11,13,12,10, 9, 8, 9,11,11,14,15,15,13,11, 9, 9,
605.12301 +        11,
605.12302 +};
605.12303 +
605.12304 +static const static_codebook _huff_book__44c1_s_long = {
605.12305 +        2, 81,
605.12306 +        (long *)_huff_lengthlist__44c1_s_long,
605.12307 +        0, 0, 0, 0, 0,
605.12308 +        NULL,
605.12309 +        0
605.12310 +};
605.12311 +
605.12312 +static const long _vq_quantlist__44c1_s_p1_0[] = {
605.12313 +        1,
605.12314 +        0,
605.12315 +        2,
605.12316 +};
605.12317 +
605.12318 +static const long _vq_lengthlist__44c1_s_p1_0[] = {
605.12319 +         2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 6, 0, 0, 0, 0,
605.12320 +         0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12321 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12322 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12323 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12324 +         0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
605.12325 +         0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12326 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12327 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12329 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
605.12330 +         0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12331 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12332 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12333 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12334 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12335 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12336 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12339 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12342 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12346 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12351 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12356 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12362 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12363 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12364 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0,
605.12365 +         0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
605.12366 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12367 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12368 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12369 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
605.12370 +         0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
605.12371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0,
605.12375 +         0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
605.12376 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12377 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12378 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12379 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12380 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12381 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12382 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12383 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12385 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12386 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12387 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12388 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12389 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12390 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12391 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12392 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12393 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12394 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12395 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12396 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12397 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12399 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12400 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12401 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12402 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12403 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12404 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12405 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12406 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12410 +         0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
605.12411 +         0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12412 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12413 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12414 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12415 +         0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8,10, 9, 0,
605.12416 +         0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0,
605.12417 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12418 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12419 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12420 +         0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
605.12421 +         0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.12422 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12423 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12424 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12425 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12426 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12427 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12428 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12429 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12430 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12431 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12432 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12433 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12434 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12435 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12436 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12437 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12438 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12439 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12440 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12441 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12442 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12443 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12444 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12445 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12446 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12447 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12448 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12449 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12450 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12451 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12452 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12453 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12454 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12455 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12456 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12457 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12458 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12459 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12460 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12463 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12464 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12465 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12466 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12468 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12469 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12470 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12471 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12472 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12473 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12474 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12475 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12476 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12477 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12478 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12479 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12480 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12481 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12482 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12483 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12484 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12485 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12486 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12487 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12488 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12489 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12490 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12491 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12492 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12493 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12494 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12495 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12496 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12497 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12498 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12499 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12500 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12501 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12502 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12503 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12504 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12505 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12506 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12507 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12508 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12509 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12510 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12511 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12512 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12513 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12514 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12515 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12516 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12517 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12518 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12519 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12520 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12521 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12522 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12523 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12525 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12526 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12527 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12528 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12529 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12530 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12531 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12532 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12533 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12534 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12535 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12536 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12537 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12538 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12539 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12540 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12541 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12542 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12543 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12544 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12545 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12546 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12547 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12548 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12549 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12550 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12551 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12552 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12553 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12554 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12555 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12556 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12557 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12558 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12559 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12560 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12561 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12562 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12563 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12564 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12565 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12566 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12567 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12568 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12569 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12570 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12571 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12572 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12573 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12574 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12575 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12576 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12577 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12578 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12579 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12580 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12581 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12582 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12583 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12584 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12585 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12586 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12587 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12588 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12589 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12590 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12591 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12592 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12593 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12594 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12595 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12596 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12597 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12598 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12599 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12600 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12601 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12602 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12603 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12604 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12605 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12606 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12607 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12608 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12609 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12610 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12611 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12612 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12613 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12614 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12615 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12616 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12617 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12618 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12619 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12620 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12621 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12622 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12623 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12624 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12625 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12626 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12627 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12628 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12629 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12630 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12631 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12632 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12633 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12634 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12635 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12636 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12637 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12638 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12639 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12640 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12641 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12642 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12643 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12644 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12645 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12646 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12647 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12648 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12649 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12650 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12651 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12652 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12653 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12654 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12655 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12656 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12657 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12658 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12659 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12660 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12661 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12662 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12663 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12664 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12665 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12666 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12667 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12668 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12669 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12670 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12671 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12672 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12673 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12674 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12675 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12676 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12677 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12678 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12679 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12680 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12681 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12682 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12683 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12684 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12685 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12686 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12687 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12688 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12689 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12690 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12691 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12692 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12693 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12694 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12695 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12696 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12697 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12698 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12699 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12700 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12701 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12702 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12703 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12704 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12705 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12706 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12707 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12708 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12709 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12710 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12711 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12712 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12713 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12714 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12715 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12716 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12717 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12718 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12719 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12720 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12721 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12722 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12723 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12724 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12725 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12726 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12727 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12728 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12729 +         0,
605.12730 +};
605.12731 +
605.12732 +static const static_codebook _44c1_s_p1_0 = {
605.12733 +        8, 6561,
605.12734 +        (long *)_vq_lengthlist__44c1_s_p1_0,
605.12735 +        1, -535822336, 1611661312, 2, 0,
605.12736 +        (long *)_vq_quantlist__44c1_s_p1_0,
605.12737 +        0
605.12738 +};
605.12739 +
605.12740 +static const long _vq_quantlist__44c1_s_p2_0[] = {
605.12741 +        2,
605.12742 +        1,
605.12743 +        3,
605.12744 +        0,
605.12745 +        4,
605.12746 +};
605.12747 +
605.12748 +static const long _vq_lengthlist__44c1_s_p2_0[] = {
605.12749 +         2, 3, 4, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12750 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0,
605.12751 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12752 +         0, 0, 4, 4, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12753 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 8, 8,
605.12754 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12755 +         0, 0, 0, 0, 6, 6, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0,
605.12756 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12757 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12758 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12759 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12760 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12761 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12762 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12763 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12764 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12765 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12766 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12767 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12768 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12769 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12770 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12771 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12772 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12773 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12774 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12775 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12776 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12777 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12778 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12779 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12780 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12781 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12782 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12783 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12784 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12785 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12786 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12787 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12788 +         0,
605.12789 +};
605.12790 +
605.12791 +static const static_codebook _44c1_s_p2_0 = {
605.12792 +        4, 625,
605.12793 +        (long *)_vq_lengthlist__44c1_s_p2_0,
605.12794 +        1, -533725184, 1611661312, 3, 0,
605.12795 +        (long *)_vq_quantlist__44c1_s_p2_0,
605.12796 +        0
605.12797 +};
605.12798 +
605.12799 +static const long _vq_quantlist__44c1_s_p3_0[] = {
605.12800 +        4,
605.12801 +        3,
605.12802 +        5,
605.12803 +        2,
605.12804 +        6,
605.12805 +        1,
605.12806 +        7,
605.12807 +        0,
605.12808 +        8,
605.12809 +};
605.12810 +
605.12811 +static const long _vq_lengthlist__44c1_s_p3_0[] = {
605.12812 +         1, 3, 2, 7, 7, 0, 0, 0, 0, 0,13,13, 6, 6, 0, 0,
605.12813 +         0, 0, 0,12, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
605.12814 +         0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
605.12815 +         8, 9, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
605.12816 +         0, 0,11,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.12817 +         0,
605.12818 +};
605.12819 +
605.12820 +static const static_codebook _44c1_s_p3_0 = {
605.12821 +        2, 81,
605.12822 +        (long *)_vq_lengthlist__44c1_s_p3_0,
605.12823 +        1, -531628032, 1611661312, 4, 0,
605.12824 +        (long *)_vq_quantlist__44c1_s_p3_0,
605.12825 +        0
605.12826 +};
605.12827 +
605.12828 +static const long _vq_quantlist__44c1_s_p4_0[] = {
605.12829 +        4,
605.12830 +        3,
605.12831 +        5,
605.12832 +        2,
605.12833 +        6,
605.12834 +        1,
605.12835 +        7,
605.12836 +        0,
605.12837 +        8,
605.12838 +};
605.12839 +
605.12840 +static const long _vq_lengthlist__44c1_s_p4_0[] = {
605.12841 +         1, 3, 3, 6, 5, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7,
605.12842 +         9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 7, 7,
605.12843 +         8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0,
605.12844 +         9, 9, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0,
605.12845 +         0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11,
605.12846 +        11,
605.12847 +};
605.12848 +
605.12849 +static const static_codebook _44c1_s_p4_0 = {
605.12850 +        2, 81,
605.12851 +        (long *)_vq_lengthlist__44c1_s_p4_0,
605.12852 +        1, -531628032, 1611661312, 4, 0,
605.12853 +        (long *)_vq_quantlist__44c1_s_p4_0,
605.12854 +        0
605.12855 +};
605.12856 +
605.12857 +static const long _vq_quantlist__44c1_s_p5_0[] = {
605.12858 +        8,
605.12859 +        7,
605.12860 +        9,
605.12861 +        6,
605.12862 +        10,
605.12863 +        5,
605.12864 +        11,
605.12865 +        4,
605.12866 +        12,
605.12867 +        3,
605.12868 +        13,
605.12869 +        2,
605.12870 +        14,
605.12871 +        1,
605.12872 +        15,
605.12873 +        0,
605.12874 +        16,
605.12875 +};
605.12876 +
605.12877 +static const long _vq_lengthlist__44c1_s_p5_0[] = {
605.12878 +         1, 4, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
605.12879 +        11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10,
605.12880 +        11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,
605.12881 +        10,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
605.12882 +        11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
605.12883 +        10,11,11,12,11, 0, 0, 0, 8, 8, 9, 9, 9,10,10,10,
605.12884 +        10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10, 9,10,
605.12885 +        10,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
605.12886 +        10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10,
605.12887 +        10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,
605.12888 +        10,10,10,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
605.12889 +         9,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
605.12890 +        10,10,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0,
605.12891 +         0, 0, 0,10,10,11,11,12,12,12,12,13,13, 0, 0, 0,
605.12892 +         0, 0, 0, 0,11,11,12,12,12,12,13,13,13,13, 0, 0,
605.12893 +         0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0,
605.12894 +         0, 0, 0, 0, 0, 0,12,12,12,12,12,12,13,13,14,14,
605.12895 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14,
605.12896 +        14,
605.12897 +};
605.12898 +
605.12899 +static const static_codebook _44c1_s_p5_0 = {
605.12900 +        2, 289,
605.12901 +        (long *)_vq_lengthlist__44c1_s_p5_0,
605.12902 +        1, -529530880, 1611661312, 5, 0,
605.12903 +        (long *)_vq_quantlist__44c1_s_p5_0,
605.12904 +        0
605.12905 +};
605.12906 +
605.12907 +static const long _vq_quantlist__44c1_s_p6_0[] = {
605.12908 +        1,
605.12909 +        0,
605.12910 +        2,
605.12911 +};
605.12912 +
605.12913 +static const long _vq_lengthlist__44c1_s_p6_0[] = {
605.12914 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
605.12915 +         9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 6,10,10,11,11,
605.12916 +        11,11,10,10, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
605.12917 +        11,10,11,11,10,10, 7,11,10,11,11,11,12,11,11, 7,
605.12918 +         9, 9,11,10,10,11,11,10, 6, 9, 9,10,10,10,12,10,
605.12919 +        11,
605.12920 +};
605.12921 +
605.12922 +static const static_codebook _44c1_s_p6_0 = {
605.12923 +        4, 81,
605.12924 +        (long *)_vq_lengthlist__44c1_s_p6_0,
605.12925 +        1, -529137664, 1618345984, 2, 0,
605.12926 +        (long *)_vq_quantlist__44c1_s_p6_0,
605.12927 +        0
605.12928 +};
605.12929 +
605.12930 +static const long _vq_quantlist__44c1_s_p6_1[] = {
605.12931 +        5,
605.12932 +        4,
605.12933 +        6,
605.12934 +        3,
605.12935 +        7,
605.12936 +        2,
605.12937 +        8,
605.12938 +        1,
605.12939 +        9,
605.12940 +        0,
605.12941 +        10,
605.12942 +};
605.12943 +
605.12944 +static const long _vq_lengthlist__44c1_s_p6_1[] = {
605.12945 +         2, 3, 3, 6, 6, 7, 7, 7, 7, 8, 8,10,10,10, 6, 6,
605.12946 +         7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8,
605.12947 +         8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
605.12948 +         7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8,
605.12949 +         8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
605.12950 +         8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
605.12951 +         8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
605.12952 +        10,10,10, 8, 8, 8, 8, 8, 8,
605.12953 +};
605.12954 +
605.12955 +static const static_codebook _44c1_s_p6_1 = {
605.12956 +        2, 121,
605.12957 +        (long *)_vq_lengthlist__44c1_s_p6_1,
605.12958 +        1, -531365888, 1611661312, 4, 0,
605.12959 +        (long *)_vq_quantlist__44c1_s_p6_1,
605.12960 +        0
605.12961 +};
605.12962 +
605.12963 +static const long _vq_quantlist__44c1_s_p7_0[] = {
605.12964 +        6,
605.12965 +        5,
605.12966 +        7,
605.12967 +        4,
605.12968 +        8,
605.12969 +        3,
605.12970 +        9,
605.12971 +        2,
605.12972 +        10,
605.12973 +        1,
605.12974 +        11,
605.12975 +        0,
605.12976 +        12,
605.12977 +};
605.12978 +
605.12979 +static const long _vq_lengthlist__44c1_s_p7_0[] = {
605.12980 +         1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 9, 7, 5, 6,
605.12981 +         7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 5, 7, 7, 8,
605.12982 +         8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.12983 +        10,10,11,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.12984 +        11, 0,12,12, 9, 9, 9,10,10,10,11,11,11,11, 0,13,
605.12985 +        13, 9, 9, 9, 9,10,10,11,11,11,11, 0, 0, 0,10,10,
605.12986 +        10,10,11,11,12,11,12,12, 0, 0, 0,10,10,10, 9,11,
605.12987 +        11,12,11,13,12, 0, 0, 0,13,13,10,10,11,11,12,12,
605.12988 +        13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0,
605.12989 +         0, 0, 0, 0,11,12,11,11,12,12,14,13, 0, 0, 0, 0,
605.12990 +         0,12,11,11,11,13,10,14,13,
605.12991 +};
605.12992 +
605.12993 +static const static_codebook _44c1_s_p7_0 = {
605.12994 +        2, 169,
605.12995 +        (long *)_vq_lengthlist__44c1_s_p7_0,
605.12996 +        1, -526516224, 1616117760, 4, 0,
605.12997 +        (long *)_vq_quantlist__44c1_s_p7_0,
605.12998 +        0
605.12999 +};
605.13000 +
605.13001 +static const long _vq_quantlist__44c1_s_p7_1[] = {
605.13002 +        2,
605.13003 +        1,
605.13004 +        3,
605.13005 +        0,
605.13006 +        4,
605.13007 +};
605.13008 +
605.13009 +static const long _vq_lengthlist__44c1_s_p7_1[] = {
605.13010 +         2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
605.13011 +         6, 6, 5, 5, 6, 6, 6, 5, 5,
605.13012 +};
605.13013 +
605.13014 +static const static_codebook _44c1_s_p7_1 = {
605.13015 +        2, 25,
605.13016 +        (long *)_vq_lengthlist__44c1_s_p7_1,
605.13017 +        1, -533725184, 1611661312, 3, 0,
605.13018 +        (long *)_vq_quantlist__44c1_s_p7_1,
605.13019 +        0
605.13020 +};
605.13021 +
605.13022 +static const long _vq_quantlist__44c1_s_p8_0[] = {
605.13023 +        6,
605.13024 +        5,
605.13025 +        7,
605.13026 +        4,
605.13027 +        8,
605.13028 +        3,
605.13029 +        9,
605.13030 +        2,
605.13031 +        10,
605.13032 +        1,
605.13033 +        11,
605.13034 +        0,
605.13035 +        12,
605.13036 +};
605.13037 +
605.13038 +static const long _vq_lengthlist__44c1_s_p8_0[] = {
605.13039 +         1, 4, 3,10,10,10,10,10,10,10,10,10,10, 4, 8, 6,
605.13040 +        10,10,10,10,10,10,10,10,10,10, 4, 8, 7,10,10,10,
605.13041 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.13042 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.13043 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.13044 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.13045 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.13046 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.13047 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.13048 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
605.13049 +        10,10,10,10,10,10,10,10,10,
605.13050 +};
605.13051 +
605.13052 +static const static_codebook _44c1_s_p8_0 = {
605.13053 +        2, 169,
605.13054 +        (long *)_vq_lengthlist__44c1_s_p8_0,
605.13055 +        1, -514541568, 1627103232, 4, 0,
605.13056 +        (long *)_vq_quantlist__44c1_s_p8_0,
605.13057 +        0
605.13058 +};
605.13059 +
605.13060 +static const long _vq_quantlist__44c1_s_p8_1[] = {
605.13061 +        6,
605.13062 +        5,
605.13063 +        7,
605.13064 +        4,
605.13065 +        8,
605.13066 +        3,
605.13067 +        9,
605.13068 +        2,
605.13069 +        10,
605.13070 +        1,
605.13071 +        11,
605.13072 +        0,
605.13073 +        12,
605.13074 +};
605.13075 +
605.13076 +static const long _vq_lengthlist__44c1_s_p8_1[] = {
605.13077 +         1, 4, 4, 6, 5, 7, 7, 9, 9,10,10,12,12, 6, 5, 5,
605.13078 +         7, 7, 8, 8,10,10,12,11,12,12, 6, 5, 5, 7, 7, 8,
605.13079 +         8,10,10,11,11,12,12,15, 7, 7, 8, 8, 9, 9,11,11,
605.13080 +        12,12,13,12,15, 8, 8, 8, 7, 9, 9,10,10,12,12,13,
605.13081 +        13,16,11,10, 8, 8,10,10,11,11,12,12,13,13,16,11,
605.13082 +        11, 9, 8,11,10,11,11,12,12,13,12,16,16,16,10,11,
605.13083 +        10,11,12,12,12,12,13,13,16,16,16,11, 9,11, 9,14,
605.13084 +        12,12,12,13,13,16,16,16,12,14,11,12,12,12,13,13,
605.13085 +        14,13,16,16,16,15,13,12,10,13,10,13,14,13,13,16,
605.13086 +        16,16,16,16,13,14,12,13,13,12,13,13,16,16,16,16,
605.13087 +        16,13,12,12,11,14,12,15,13,
605.13088 +};
605.13089 +
605.13090 +static const static_codebook _44c1_s_p8_1 = {
605.13091 +        2, 169,
605.13092 +        (long *)_vq_lengthlist__44c1_s_p8_1,
605.13093 +        1, -522616832, 1620115456, 4, 0,
605.13094 +        (long *)_vq_quantlist__44c1_s_p8_1,
605.13095 +        0
605.13096 +};
605.13097 +
605.13098 +static const long _vq_quantlist__44c1_s_p8_2[] = {
605.13099 +        8,
605.13100 +        7,
605.13101 +        9,
605.13102 +        6,
605.13103 +        10,
605.13104 +        5,
605.13105 +        11,
605.13106 +        4,
605.13107 +        12,
605.13108 +        3,
605.13109 +        13,
605.13110 +        2,
605.13111 +        14,
605.13112 +        1,
605.13113 +        15,
605.13114 +        0,
605.13115 +        16,
605.13116 +};
605.13117 +
605.13118 +static const long _vq_lengthlist__44c1_s_p8_2[] = {
605.13119 +         2, 4, 4, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8,
605.13120 +         8,10,10,10, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
605.13121 +         9, 9,10,10,10, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9,
605.13122 +         9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9,
605.13123 +         9,10, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9,
605.13124 +         9,10, 9, 9,10,10,11,11, 8, 8, 8, 8, 9, 9, 9, 9,
605.13125 +         9, 9,10, 9, 9,10,10,10,10, 8, 8, 8, 8, 9, 9, 9,
605.13126 +         9, 9, 9, 9, 9,10,10,11,11,11, 8, 8, 9, 9, 9, 9,
605.13127 +         9, 9, 9, 9, 9, 9,10,10,10,10,11,11,11, 8, 8, 9,
605.13128 +         9, 9, 9,10, 9, 9, 9, 9, 9,11,11,11,11,11, 9, 9,
605.13129 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,10,11,11, 9,
605.13130 +         9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11,10,11,11,
605.13131 +         9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10,10,11,11,
605.13132 +        11,11,11, 9, 9, 9,10, 9, 9, 9, 9, 9, 9,10,11,11,
605.13133 +        11,11,11,11,10,10,10,10, 9, 9, 9, 9, 9, 9,10,11,
605.13134 +        11,11,11,11,11, 9,10, 9, 9, 9, 9,10, 9, 9, 9,11,
605.13135 +        11,11,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9,10, 9,
605.13136 +        11,11,10,11,11,11,11,10,11, 9, 9, 9, 9, 9, 9, 9,
605.13137 +         9,
605.13138 +};
605.13139 +
605.13140 +static const static_codebook _44c1_s_p8_2 = {
605.13141 +        2, 289,
605.13142 +        (long *)_vq_lengthlist__44c1_s_p8_2,
605.13143 +        1, -529530880, 1611661312, 5, 0,
605.13144 +        (long *)_vq_quantlist__44c1_s_p8_2,
605.13145 +        0
605.13146 +};
605.13147 +
605.13148 +static const long _huff_lengthlist__44c1_s_short[] = {
605.13149 +         6, 8,13,12,13,14,15,16,16, 4, 2, 4, 7, 6, 8,11,
605.13150 +        13,15,10, 4, 4, 8, 6, 8,11,14,17,11, 5, 6, 5, 6,
605.13151 +         8,12,14,17,11, 5, 5, 6, 5, 7,10,13,16,12, 6, 7,
605.13152 +         8, 7, 8,10,13,15,13, 8, 8, 7, 7, 8,10,12,15,15,
605.13153 +         7, 7, 5, 5, 7, 9,12,14,15, 8, 8, 6, 6, 7, 8,10,
605.13154 +        11,
605.13155 +};
605.13156 +
605.13157 +static const static_codebook _huff_book__44c1_s_short = {
605.13158 +        2, 81,
605.13159 +        (long *)_huff_lengthlist__44c1_s_short,
605.13160 +        0, 0, 0, 0, 0,
605.13161 +        NULL,
605.13162 +        0
605.13163 +};
605.13164 +
605.13165 +static const long _huff_lengthlist__44c1_sm_long[] = {
605.13166 +         5, 4, 8,10, 9, 9,10,11,12, 4, 2, 5, 6, 6, 8,10,
605.13167 +        11,13, 8, 4, 6, 8, 7, 9,12,12,14,10, 6, 8, 4, 5,
605.13168 +         6, 9,11,12, 9, 5, 6, 5, 5, 6, 9,11,11, 9, 7, 9,
605.13169 +         6, 5, 5, 7,10,10,10, 9,11, 8, 7, 6, 7, 9,11,11,
605.13170 +        12,13,10,10, 9, 8, 9,11,11,15,15,12,13,11, 9,10,
605.13171 +        11,
605.13172 +};
605.13173 +
605.13174 +static const static_codebook _huff_book__44c1_sm_long = {
605.13175 +        2, 81,
605.13176 +        (long *)_huff_lengthlist__44c1_sm_long,
605.13177 +        0, 0, 0, 0, 0,
605.13178 +        NULL,
605.13179 +        0
605.13180 +};
605.13181 +
605.13182 +static const long _vq_quantlist__44c1_sm_p1_0[] = {
605.13183 +        1,
605.13184 +        0,
605.13185 +        2,
605.13186 +};
605.13187 +
605.13188 +static const long _vq_lengthlist__44c1_sm_p1_0[] = {
605.13189 +         1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.13190 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13191 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13192 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13193 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13194 +         0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
605.13195 +         0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13196 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13197 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13198 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13199 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
605.13200 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13201 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13202 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13203 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13204 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13205 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13206 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13207 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13208 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13209 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13210 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13211 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13212 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13213 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13214 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13215 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13216 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13217 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13218 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13219 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13220 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13221 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13222 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13223 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13224 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13225 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13226 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13227 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13228 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13229 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13230 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13231 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13232 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13233 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13234 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0,
605.13235 +         0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
605.13236 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13237 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13238 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13239 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
605.13240 +         0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
605.13241 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13242 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13243 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13244 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.13245 +         0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
605.13246 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13247 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13248 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13249 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13250 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13251 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13252 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13253 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13254 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13255 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13256 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13257 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13258 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13259 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13260 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13261 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13262 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13263 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13264 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13265 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13266 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13267 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13268 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13269 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13270 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13271 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13272 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13273 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13274 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13275 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13276 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13277 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13278 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13279 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13280 +         0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
605.13281 +         0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13282 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13283 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13284 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13285 +         0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
605.13286 +         0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0,
605.13287 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13288 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13289 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13290 +         0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
605.13291 +         0, 0, 0, 0, 0, 0, 9,10, 9, 0, 0, 0, 0, 0, 0, 0,
605.13292 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13293 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13294 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13295 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13296 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13297 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13298 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13299 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13300 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13301 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13302 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13303 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13304 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13305 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13306 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13307 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13308 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13309 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13310 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13311 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13312 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13313 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13314 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13315 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13316 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13317 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13318 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13319 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13320 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13321 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13322 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13323 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13324 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13325 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13326 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13327 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13329 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13330 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13331 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13332 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13333 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13334 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13335 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13336 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13339 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13342 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13346 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13351 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13356 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13362 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13363 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13364 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13365 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13366 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13367 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13368 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13369 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13370 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13375 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13376 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13377 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13378 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13379 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13380 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13381 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13382 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13383 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13385 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13386 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13387 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13388 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13389 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13390 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13391 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13392 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13393 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13394 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13395 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13396 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13397 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13399 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13400 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13401 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13402 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13403 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13404 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13405 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13406 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13410 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13411 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13412 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13413 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13414 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13415 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13416 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13417 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13418 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13419 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13420 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13421 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13422 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13423 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13424 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13425 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13426 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13427 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13428 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13429 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13430 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13431 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13432 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13433 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13434 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13435 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13436 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13437 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13438 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13439 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13440 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13441 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13442 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13443 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13444 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13445 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13446 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13447 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13448 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13449 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13450 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13451 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13452 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13453 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13454 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13455 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13456 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13457 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13458 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13459 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13460 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13463 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13464 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13465 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13466 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13468 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13469 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13470 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13471 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13472 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13473 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13474 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13475 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13476 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13477 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13478 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13479 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13480 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13481 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13482 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13483 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13484 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13485 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13486 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13487 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13488 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13489 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13490 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13491 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13492 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13493 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13494 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13495 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13496 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13497 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13498 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13499 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13500 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13501 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13502 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13503 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13504 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13505 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13506 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13507 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13508 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13509 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13510 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13511 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13512 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13513 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13514 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13515 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13516 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13517 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13518 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13519 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13520 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13521 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13522 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13523 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13525 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13526 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13527 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13528 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13529 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13530 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13531 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13532 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13533 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13534 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13535 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13536 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13537 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13538 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13539 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13540 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13541 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13542 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13543 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13544 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13545 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13546 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13547 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13548 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13549 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13550 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13551 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13552 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13553 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13554 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13555 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13556 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13557 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13558 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13559 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13560 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13561 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13562 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13563 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13564 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13565 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13566 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13567 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13568 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13569 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13570 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13571 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13572 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13573 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13574 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13575 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13576 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13577 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13578 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13579 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13580 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13581 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13582 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13583 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13584 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13585 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13586 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13587 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13588 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13589 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13590 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13591 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13592 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13593 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13594 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13595 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13596 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13597 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13598 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13599 +         0,
605.13600 +};
605.13601 +
605.13602 +static const static_codebook _44c1_sm_p1_0 = {
605.13603 +        8, 6561,
605.13604 +        (long *)_vq_lengthlist__44c1_sm_p1_0,
605.13605 +        1, -535822336, 1611661312, 2, 0,
605.13606 +        (long *)_vq_quantlist__44c1_sm_p1_0,
605.13607 +        0
605.13608 +};
605.13609 +
605.13610 +static const long _vq_quantlist__44c1_sm_p2_0[] = {
605.13611 +        2,
605.13612 +        1,
605.13613 +        3,
605.13614 +        0,
605.13615 +        4,
605.13616 +};
605.13617 +
605.13618 +static const long _vq_lengthlist__44c1_sm_p2_0[] = {
605.13619 +         2, 3, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13620 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0,
605.13621 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13622 +         0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13623 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9,
605.13624 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13625 +         0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.13626 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13627 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13628 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13629 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13630 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13631 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13632 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13633 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13634 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13635 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13636 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13637 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13638 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13639 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13640 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13641 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13642 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13643 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13644 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13645 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13646 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13647 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13648 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13649 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13650 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13651 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13652 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13653 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13654 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13655 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13656 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13657 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13658 +         0,
605.13659 +};
605.13660 +
605.13661 +static const static_codebook _44c1_sm_p2_0 = {
605.13662 +        4, 625,
605.13663 +        (long *)_vq_lengthlist__44c1_sm_p2_0,
605.13664 +        1, -533725184, 1611661312, 3, 0,
605.13665 +        (long *)_vq_quantlist__44c1_sm_p2_0,
605.13666 +        0
605.13667 +};
605.13668 +
605.13669 +static const long _vq_quantlist__44c1_sm_p3_0[] = {
605.13670 +        4,
605.13671 +        3,
605.13672 +        5,
605.13673 +        2,
605.13674 +        6,
605.13675 +        1,
605.13676 +        7,
605.13677 +        0,
605.13678 +        8,
605.13679 +};
605.13680 +
605.13681 +static const long _vq_lengthlist__44c1_sm_p3_0[] = {
605.13682 +         1, 3, 3, 7, 7, 0, 0, 0, 0, 0, 5, 5, 6, 6, 0, 0,
605.13683 +         0, 0, 0, 5, 5, 7, 7, 0, 0, 0, 0, 0, 7, 7, 7, 7,
605.13684 +         0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
605.13685 +         8, 9, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
605.13686 +         0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.13687 +         0,
605.13688 +};
605.13689 +
605.13690 +static const static_codebook _44c1_sm_p3_0 = {
605.13691 +        2, 81,
605.13692 +        (long *)_vq_lengthlist__44c1_sm_p3_0,
605.13693 +        1, -531628032, 1611661312, 4, 0,
605.13694 +        (long *)_vq_quantlist__44c1_sm_p3_0,
605.13695 +        0
605.13696 +};
605.13697 +
605.13698 +static const long _vq_quantlist__44c1_sm_p4_0[] = {
605.13699 +        4,
605.13700 +        3,
605.13701 +        5,
605.13702 +        2,
605.13703 +        6,
605.13704 +        1,
605.13705 +        7,
605.13706 +        0,
605.13707 +        8,
605.13708 +};
605.13709 +
605.13710 +static const long _vq_lengthlist__44c1_sm_p4_0[] = {
605.13711 +         1, 3, 3, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7, 8, 8,
605.13712 +         9, 9, 0, 6, 6, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8,
605.13713 +         8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0,
605.13714 +         8, 8, 9, 9,11,11, 0, 0, 0, 9, 9, 9, 9,11,11, 0,
605.13715 +         0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0, 9, 9,11,
605.13716 +        11,
605.13717 +};
605.13718 +
605.13719 +static const static_codebook _44c1_sm_p4_0 = {
605.13720 +        2, 81,
605.13721 +        (long *)_vq_lengthlist__44c1_sm_p4_0,
605.13722 +        1, -531628032, 1611661312, 4, 0,
605.13723 +        (long *)_vq_quantlist__44c1_sm_p4_0,
605.13724 +        0
605.13725 +};
605.13726 +
605.13727 +static const long _vq_quantlist__44c1_sm_p5_0[] = {
605.13728 +        8,
605.13729 +        7,
605.13730 +        9,
605.13731 +        6,
605.13732 +        10,
605.13733 +        5,
605.13734 +        11,
605.13735 +        4,
605.13736 +        12,
605.13737 +        3,
605.13738 +        13,
605.13739 +        2,
605.13740 +        14,
605.13741 +        1,
605.13742 +        15,
605.13743 +        0,
605.13744 +        16,
605.13745 +};
605.13746 +
605.13747 +static const long _vq_lengthlist__44c1_sm_p5_0[] = {
605.13748 +         2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
605.13749 +        11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,10,
605.13750 +        11,11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,
605.13751 +        10,11,11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
605.13752 +        11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
605.13753 +        10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9,10,10,
605.13754 +        10,11,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9,10,
605.13755 +        10,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
605.13756 +        10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10,
605.13757 +        10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
605.13758 +         9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
605.13759 +         9, 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
605.13760 +         9, 9,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0,
605.13761 +         0, 0, 0,10,10,11,11,12,12,12,12,13,13, 0, 0, 0,
605.13762 +         0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0, 0,
605.13763 +         0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0,
605.13764 +         0, 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14,
605.13765 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14,
605.13766 +        14,
605.13767 +};
605.13768 +
605.13769 +static const static_codebook _44c1_sm_p5_0 = {
605.13770 +        2, 289,
605.13771 +        (long *)_vq_lengthlist__44c1_sm_p5_0,
605.13772 +        1, -529530880, 1611661312, 5, 0,
605.13773 +        (long *)_vq_quantlist__44c1_sm_p5_0,
605.13774 +        0
605.13775 +};
605.13776 +
605.13777 +static const long _vq_quantlist__44c1_sm_p6_0[] = {
605.13778 +        1,
605.13779 +        0,
605.13780 +        2,
605.13781 +};
605.13782 +
605.13783 +static const long _vq_lengthlist__44c1_sm_p6_0[] = {
605.13784 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
605.13785 +         9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,10,11,
605.13786 +        11,11,10,10, 6, 9, 9,11,11,10,11,10,10, 6, 9, 9,
605.13787 +        11,10,11,11,10,10, 7,11,11,11,11,11,11,11,11, 6,
605.13788 +         9, 9,11,10,10,11,11,10, 6, 9, 9,10,10,10,11,10,
605.13789 +        11,
605.13790 +};
605.13791 +
605.13792 +static const static_codebook _44c1_sm_p6_0 = {
605.13793 +        4, 81,
605.13794 +        (long *)_vq_lengthlist__44c1_sm_p6_0,
605.13795 +        1, -529137664, 1618345984, 2, 0,
605.13796 +        (long *)_vq_quantlist__44c1_sm_p6_0,
605.13797 +        0
605.13798 +};
605.13799 +
605.13800 +static const long _vq_quantlist__44c1_sm_p6_1[] = {
605.13801 +        5,
605.13802 +        4,
605.13803 +        6,
605.13804 +        3,
605.13805 +        7,
605.13806 +        2,
605.13807 +        8,
605.13808 +        1,
605.13809 +        9,
605.13810 +        0,
605.13811 +        10,
605.13812 +};
605.13813 +
605.13814 +static const long _vq_lengthlist__44c1_sm_p6_1[] = {
605.13815 +         2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6,
605.13816 +         7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8,
605.13817 +         8,10, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
605.13818 +         7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8,
605.13819 +         8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
605.13820 +         8, 8, 8, 8, 8, 8, 9, 8,10,10,10,10,10, 8, 8, 8,
605.13821 +         8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
605.13822 +        10,10,10, 8, 8, 8, 8, 8, 8,
605.13823 +};
605.13824 +
605.13825 +static const static_codebook _44c1_sm_p6_1 = {
605.13826 +        2, 121,
605.13827 +        (long *)_vq_lengthlist__44c1_sm_p6_1,
605.13828 +        1, -531365888, 1611661312, 4, 0,
605.13829 +        (long *)_vq_quantlist__44c1_sm_p6_1,
605.13830 +        0
605.13831 +};
605.13832 +
605.13833 +static const long _vq_quantlist__44c1_sm_p7_0[] = {
605.13834 +        6,
605.13835 +        5,
605.13836 +        7,
605.13837 +        4,
605.13838 +        8,
605.13839 +        3,
605.13840 +        9,
605.13841 +        2,
605.13842 +        10,
605.13843 +        1,
605.13844 +        11,
605.13845 +        0,
605.13846 +        12,
605.13847 +};
605.13848 +
605.13849 +static const long _vq_lengthlist__44c1_sm_p7_0[] = {
605.13850 +         1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 5, 5,
605.13851 +         7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 6, 7, 7, 8,
605.13852 +         8, 8, 8, 9, 9,11,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.13853 +        10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.13854 +        11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13,
605.13855 +        13, 9, 9, 9, 9,10,10,11,11,12,12, 0, 0, 0, 9,10,
605.13856 +         9,10,11,11,12,11,13,12, 0, 0, 0,10,10, 9, 9,11,
605.13857 +        11,12,12,13,12, 0, 0, 0,13,13,10,10,11,11,12,12,
605.13858 +        13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0,
605.13859 +         0, 0, 0, 0,11,12,11,11,12,13,14,13, 0, 0, 0, 0,
605.13860 +         0,12,12,11,11,13,12,14,13,
605.13861 +};
605.13862 +
605.13863 +static const static_codebook _44c1_sm_p7_0 = {
605.13864 +        2, 169,
605.13865 +        (long *)_vq_lengthlist__44c1_sm_p7_0,
605.13866 +        1, -526516224, 1616117760, 4, 0,
605.13867 +        (long *)_vq_quantlist__44c1_sm_p7_0,
605.13868 +        0
605.13869 +};
605.13870 +
605.13871 +static const long _vq_quantlist__44c1_sm_p7_1[] = {
605.13872 +        2,
605.13873 +        1,
605.13874 +        3,
605.13875 +        0,
605.13876 +        4,
605.13877 +};
605.13878 +
605.13879 +static const long _vq_lengthlist__44c1_sm_p7_1[] = {
605.13880 +         2, 4, 4, 4, 5, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6,
605.13881 +         5, 5, 5, 5, 6, 6, 6, 5, 5,
605.13882 +};
605.13883 +
605.13884 +static const static_codebook _44c1_sm_p7_1 = {
605.13885 +        2, 25,
605.13886 +        (long *)_vq_lengthlist__44c1_sm_p7_1,
605.13887 +        1, -533725184, 1611661312, 3, 0,
605.13888 +        (long *)_vq_quantlist__44c1_sm_p7_1,
605.13889 +        0
605.13890 +};
605.13891 +
605.13892 +static const long _vq_quantlist__44c1_sm_p8_0[] = {
605.13893 +        6,
605.13894 +        5,
605.13895 +        7,
605.13896 +        4,
605.13897 +        8,
605.13898 +        3,
605.13899 +        9,
605.13900 +        2,
605.13901 +        10,
605.13902 +        1,
605.13903 +        11,
605.13904 +        0,
605.13905 +        12,
605.13906 +};
605.13907 +
605.13908 +static const long _vq_lengthlist__44c1_sm_p8_0[] = {
605.13909 +         1, 3, 3,13,13,13,13,13,13,13,13,13,13, 3, 6, 6,
605.13910 +        13,13,13,13,13,13,13,13,13,13, 4, 8, 7,13,13,13,
605.13911 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.13912 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.13913 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.13914 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.13915 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.13916 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.13917 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.13918 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
605.13919 +        13,13,13,13,13,13,13,13,13,
605.13920 +};
605.13921 +
605.13922 +static const static_codebook _44c1_sm_p8_0 = {
605.13923 +        2, 169,
605.13924 +        (long *)_vq_lengthlist__44c1_sm_p8_0,
605.13925 +        1, -514541568, 1627103232, 4, 0,
605.13926 +        (long *)_vq_quantlist__44c1_sm_p8_0,
605.13927 +        0
605.13928 +};
605.13929 +
605.13930 +static const long _vq_quantlist__44c1_sm_p8_1[] = {
605.13931 +        6,
605.13932 +        5,
605.13933 +        7,
605.13934 +        4,
605.13935 +        8,
605.13936 +        3,
605.13937 +        9,
605.13938 +        2,
605.13939 +        10,
605.13940 +        1,
605.13941 +        11,
605.13942 +        0,
605.13943 +        12,
605.13944 +};
605.13945 +
605.13946 +static const long _vq_lengthlist__44c1_sm_p8_1[] = {
605.13947 +         1, 4, 4, 6, 6, 7, 7, 9, 9,10,11,12,12, 6, 5, 5,
605.13948 +         7, 7, 8, 7,10,10,11,11,12,12, 6, 5, 5, 7, 7, 8,
605.13949 +         8,10,10,11,11,12,12,16, 7, 7, 8, 8, 9, 9,11,11,
605.13950 +        12,12,13,13,17, 7, 7, 8, 7, 9, 9,11,10,12,12,13,
605.13951 +        13,19,11,10, 8, 8,10,10,11,11,12,12,13,13,19,11,
605.13952 +        11, 9, 7,11,10,11,11,12,12,13,12,19,19,19,10,10,
605.13953 +        10,10,11,12,12,12,13,14,18,19,19,11, 9,11, 9,13,
605.13954 +        12,12,12,13,13,19,20,19,13,15,11,11,12,12,13,13,
605.13955 +        14,13,18,19,20,15,13,12,10,13,10,13,13,13,14,20,
605.13956 +        20,20,20,20,13,14,12,12,13,12,13,13,20,20,20,20,
605.13957 +        20,13,12,12,12,14,12,14,13,
605.13958 +};
605.13959 +
605.13960 +static const static_codebook _44c1_sm_p8_1 = {
605.13961 +        2, 169,
605.13962 +        (long *)_vq_lengthlist__44c1_sm_p8_1,
605.13963 +        1, -522616832, 1620115456, 4, 0,
605.13964 +        (long *)_vq_quantlist__44c1_sm_p8_1,
605.13965 +        0
605.13966 +};
605.13967 +
605.13968 +static const long _vq_quantlist__44c1_sm_p8_2[] = {
605.13969 +        8,
605.13970 +        7,
605.13971 +        9,
605.13972 +        6,
605.13973 +        10,
605.13974 +        5,
605.13975 +        11,
605.13976 +        4,
605.13977 +        12,
605.13978 +        3,
605.13979 +        13,
605.13980 +        2,
605.13981 +        14,
605.13982 +        1,
605.13983 +        15,
605.13984 +        0,
605.13985 +        16,
605.13986 +};
605.13987 +
605.13988 +static const long _vq_lengthlist__44c1_sm_p8_2[] = {
605.13989 +         2, 5, 5, 6, 6, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8,
605.13990 +         8,10, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
605.13991 +         9, 9,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
605.13992 +         9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9,
605.13993 +         9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 9, 9, 9, 9, 9,
605.13994 +         9, 9, 9, 9, 9,10,11,11, 8, 8, 8, 8, 9, 9, 9, 9,
605.13995 +         9, 9,10,10, 9,10,10,10,10, 8, 8, 8, 8, 9, 9, 9,
605.13996 +         9, 9, 9, 9, 9,10,10,11,10,10, 8, 8, 9, 9, 9, 9,
605.13997 +         9, 9, 9, 9, 9, 9,10, 9,10,10,10,11,11, 8, 8, 9,
605.13998 +         9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,11,11,11, 9, 9,
605.13999 +         9, 9, 9, 9, 9, 9,10, 9,10, 9,11,11,11,11,11, 9,
605.14000 +         8, 9, 9, 9, 9, 9, 9, 9,10,10, 9,11,11,10,11,11,
605.14001 +         9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,11,11,11,11,
605.14002 +        11,11,11, 9, 9,10, 9, 9, 9, 9,10, 9,10,10,11,10,
605.14003 +        11,11,11,11, 9,10,10,10, 9, 9, 9, 9, 9, 9,10,11,
605.14004 +        11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,
605.14005 +        11,10,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9,10, 9,
605.14006 +        10,11,10,11,11,11,11,11,11, 9, 9,10, 9, 9, 9, 9,
605.14007 +         9,
605.14008 +};
605.14009 +
605.14010 +static const static_codebook _44c1_sm_p8_2 = {
605.14011 +        2, 289,
605.14012 +        (long *)_vq_lengthlist__44c1_sm_p8_2,
605.14013 +        1, -529530880, 1611661312, 5, 0,
605.14014 +        (long *)_vq_quantlist__44c1_sm_p8_2,
605.14015 +        0
605.14016 +};
605.14017 +
605.14018 +static const long _huff_lengthlist__44c1_sm_short[] = {
605.14019 +         4, 7,13,14,14,15,16,18,18, 4, 2, 5, 8, 7, 9,12,
605.14020 +        15,15,10, 4, 5,10, 6, 8,11,15,17,12, 5, 7, 5, 6,
605.14021 +         8,11,14,17,11, 5, 6, 6, 5, 6, 9,13,17,12, 6, 7,
605.14022 +         6, 5, 6, 8,12,14,14, 7, 8, 6, 6, 7, 9,11,14,14,
605.14023 +         8, 9, 6, 5, 6, 9,11,13,16,10,10, 7, 6, 7, 8,10,
605.14024 +        11,
605.14025 +};
605.14026 +
605.14027 +static const static_codebook _huff_book__44c1_sm_short = {
605.14028 +        2, 81,
605.14029 +        (long *)_huff_lengthlist__44c1_sm_short,
605.14030 +        0, 0, 0, 0, 0,
605.14031 +        NULL,
605.14032 +        0
605.14033 +};
605.14034 +
605.14035 +static const long _huff_lengthlist__44cn1_s_long[] = {
605.14036 +         4, 4, 7, 8, 7, 8,10,12,17, 3, 1, 6, 6, 7, 8,10,
605.14037 +        12,15, 7, 6, 9, 9, 9,11,12,14,17, 8, 6, 9, 6, 7,
605.14038 +         9,11,13,17, 7, 6, 9, 7, 7, 8, 9,12,15, 8, 8,10,
605.14039 +         8, 7, 7, 7,10,14, 9,10,12,10, 8, 8, 8,10,14,11,
605.14040 +        13,15,13,12,11,11,12,16,17,18,18,19,20,18,16,16,
605.14041 +        20,
605.14042 +};
605.14043 +
605.14044 +static const static_codebook _huff_book__44cn1_s_long = {
605.14045 +        2, 81,
605.14046 +        (long *)_huff_lengthlist__44cn1_s_long,
605.14047 +        0, 0, 0, 0, 0,
605.14048 +        NULL,
605.14049 +        0
605.14050 +};
605.14051 +
605.14052 +static const long _vq_quantlist__44cn1_s_p1_0[] = {
605.14053 +        1,
605.14054 +        0,
605.14055 +        2,
605.14056 +};
605.14057 +
605.14058 +static const long _vq_lengthlist__44cn1_s_p1_0[] = {
605.14059 +         1, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.14060 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14061 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14062 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14063 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14064 +         0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0,
605.14065 +         0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14066 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14067 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14068 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14069 +         0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7,10, 9, 0, 0,
605.14070 +         0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14071 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14072 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14073 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14074 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14075 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14076 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14077 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14078 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14079 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14080 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14081 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14082 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14083 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14084 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14085 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14086 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14087 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14088 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14089 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14090 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14091 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14092 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14093 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14094 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14095 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14096 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14097 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14098 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14099 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14100 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14101 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14102 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14103 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14104 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0,
605.14105 +         0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8, 9,10, 0, 0,
605.14106 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14107 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14108 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14109 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, 0,
605.14110 +         0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0,10,11,11, 0,
605.14111 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14112 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14113 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14114 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0,
605.14115 +         0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0,10,11,11,
605.14116 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14117 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14118 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14119 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14120 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14121 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14122 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14123 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14124 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14125 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14126 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14127 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14128 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14129 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14130 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14131 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14132 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14133 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14134 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14135 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14136 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14137 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14138 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14139 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14140 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14141 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14142 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14143 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14144 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14145 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14146 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14147 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14148 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14149 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14150 +         0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0,
605.14151 +         0, 0, 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14152 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14153 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14154 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14155 +         0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,11,11, 0,
605.14156 +         0, 0, 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 0, 0,
605.14157 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14158 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14159 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14160 +         0, 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,11,11,
605.14161 +         0, 0, 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0, 0,
605.14162 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14163 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14164 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14165 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14166 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14167 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14168 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14169 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14170 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14171 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14172 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14173 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14174 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14175 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14176 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14177 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14178 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14179 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14180 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14181 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14182 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14183 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14184 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14185 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14186 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14187 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14188 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14189 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14190 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14191 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14192 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14193 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14194 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14195 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14196 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14197 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14198 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14199 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14200 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14201 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14202 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14203 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14204 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14205 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14206 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14207 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14208 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14209 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14210 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14211 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14212 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14213 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14214 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14215 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14216 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14217 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14218 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14219 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14220 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14221 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14222 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14223 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14224 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14225 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14226 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14227 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14228 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14229 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14230 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14231 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14232 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14233 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14234 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14235 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14236 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14237 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14238 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14239 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14240 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14241 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14242 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14243 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14244 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14245 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14246 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14247 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14248 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14249 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14250 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14251 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14252 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14253 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14254 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14255 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14256 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14257 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14258 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14259 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14260 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14261 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14262 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14263 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14264 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14265 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14266 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14267 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14268 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14269 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14270 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14271 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14272 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14273 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14274 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14275 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14276 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14277 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14278 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14279 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14280 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14281 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14282 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14283 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14284 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14285 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14286 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14287 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14288 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14289 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14290 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14291 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14292 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14293 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14294 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14295 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14296 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14297 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14298 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14299 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14300 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14301 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14302 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14303 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14304 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14305 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14306 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14307 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14308 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14309 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14310 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14311 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14312 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14313 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14314 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14315 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14316 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14317 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14318 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14319 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14320 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14321 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14322 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14323 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14324 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14325 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14326 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14327 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14329 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14330 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14331 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14332 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14333 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14334 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14335 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14336 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14339 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14342 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14346 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14351 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14356 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14362 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14363 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14364 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14365 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14366 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14367 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14368 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14369 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14370 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14371 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14372 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14373 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14374 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14375 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14376 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14377 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14378 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14379 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14380 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14381 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14382 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14383 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14385 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14386 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14387 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14388 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14389 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14390 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14391 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14392 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14393 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14394 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14395 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14396 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14397 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14399 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14400 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14401 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14402 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14403 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14404 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14405 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14406 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14410 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14411 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14412 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14413 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14414 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14415 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14416 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14417 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14418 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14419 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14420 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14421 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14422 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14423 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14424 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14425 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14426 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14427 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14428 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14429 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14430 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14431 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14432 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14433 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14434 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14435 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14436 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14437 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14438 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14439 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14440 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14441 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14442 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14443 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14444 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14445 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14446 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14447 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14448 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14449 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14450 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14451 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14452 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14453 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14454 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14455 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14456 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14457 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14458 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14459 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14460 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14461 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14462 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14463 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14464 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14465 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14466 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14467 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14468 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14469 +         0,
605.14470 +};
605.14471 +
605.14472 +static const static_codebook _44cn1_s_p1_0 = {
605.14473 +        8, 6561,
605.14474 +        (long *)_vq_lengthlist__44cn1_s_p1_0,
605.14475 +        1, -535822336, 1611661312, 2, 0,
605.14476 +        (long *)_vq_quantlist__44cn1_s_p1_0,
605.14477 +        0
605.14478 +};
605.14479 +
605.14480 +static const long _vq_quantlist__44cn1_s_p2_0[] = {
605.14481 +        2,
605.14482 +        1,
605.14483 +        3,
605.14484 +        0,
605.14485 +        4,
605.14486 +};
605.14487 +
605.14488 +static const long _vq_lengthlist__44cn1_s_p2_0[] = {
605.14489 +         1, 4, 4, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14490 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0,
605.14491 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14492 +         0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14493 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9,
605.14494 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14495 +         0, 0, 0, 0, 6, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.14496 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14497 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14498 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14499 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14500 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14501 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14502 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14503 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14504 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14505 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14506 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14507 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14508 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14509 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14510 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14511 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14512 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14513 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14514 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14515 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14516 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14517 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14518 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14519 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14520 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14521 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14522 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14523 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14525 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14526 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14527 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14528 +         0,
605.14529 +};
605.14530 +
605.14531 +static const static_codebook _44cn1_s_p2_0 = {
605.14532 +        4, 625,
605.14533 +        (long *)_vq_lengthlist__44cn1_s_p2_0,
605.14534 +        1, -533725184, 1611661312, 3, 0,
605.14535 +        (long *)_vq_quantlist__44cn1_s_p2_0,
605.14536 +        0
605.14537 +};
605.14538 +
605.14539 +static const long _vq_quantlist__44cn1_s_p3_0[] = {
605.14540 +        4,
605.14541 +        3,
605.14542 +        5,
605.14543 +        2,
605.14544 +        6,
605.14545 +        1,
605.14546 +        7,
605.14547 +        0,
605.14548 +        8,
605.14549 +};
605.14550 +
605.14551 +static const long _vq_lengthlist__44cn1_s_p3_0[] = {
605.14552 +         1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
605.14553 +         0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
605.14554 +         0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
605.14555 +         9, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
605.14556 +         0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14557 +         0,
605.14558 +};
605.14559 +
605.14560 +static const static_codebook _44cn1_s_p3_0 = {
605.14561 +        2, 81,
605.14562 +        (long *)_vq_lengthlist__44cn1_s_p3_0,
605.14563 +        1, -531628032, 1611661312, 4, 0,
605.14564 +        (long *)_vq_quantlist__44cn1_s_p3_0,
605.14565 +        0
605.14566 +};
605.14567 +
605.14568 +static const long _vq_quantlist__44cn1_s_p4_0[] = {
605.14569 +        4,
605.14570 +        3,
605.14571 +        5,
605.14572 +        2,
605.14573 +        6,
605.14574 +        1,
605.14575 +        7,
605.14576 +        0,
605.14577 +        8,
605.14578 +};
605.14579 +
605.14580 +static const long _vq_lengthlist__44cn1_s_p4_0[] = {
605.14581 +         1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 6, 6, 7, 7,
605.14582 +         9, 9, 0, 0, 0, 6, 6, 7, 7, 9, 9, 0, 0, 0, 7, 7,
605.14583 +         8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0,
605.14584 +         9, 9, 9, 9,10,10, 0, 0, 0, 9, 9, 9, 9,10,10, 0,
605.14585 +         0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0,10,10,11,
605.14586 +        11,
605.14587 +};
605.14588 +
605.14589 +static const static_codebook _44cn1_s_p4_0 = {
605.14590 +        2, 81,
605.14591 +        (long *)_vq_lengthlist__44cn1_s_p4_0,
605.14592 +        1, -531628032, 1611661312, 4, 0,
605.14593 +        (long *)_vq_quantlist__44cn1_s_p4_0,
605.14594 +        0
605.14595 +};
605.14596 +
605.14597 +static const long _vq_quantlist__44cn1_s_p5_0[] = {
605.14598 +        8,
605.14599 +        7,
605.14600 +        9,
605.14601 +        6,
605.14602 +        10,
605.14603 +        5,
605.14604 +        11,
605.14605 +        4,
605.14606 +        12,
605.14607 +        3,
605.14608 +        13,
605.14609 +        2,
605.14610 +        14,
605.14611 +        1,
605.14612 +        15,
605.14613 +        0,
605.14614 +        16,
605.14615 +};
605.14616 +
605.14617 +static const long _vq_lengthlist__44cn1_s_p5_0[] = {
605.14618 +         1, 4, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,10,
605.14619 +        10, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10,
605.14620 +        11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,
605.14621 +        10,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
605.14622 +        11,11,11,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
605.14623 +        10,11,11,11,11, 0, 0, 0, 8, 8, 9, 9, 9, 9,10,10,
605.14624 +        10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9, 9,10,
605.14625 +        10,10,11,11,11,12,12, 0, 0, 0, 9, 9,10, 9,10,10,
605.14626 +        10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,10,
605.14627 +        10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,
605.14628 +        10,10,10,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
605.14629 +         9,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
605.14630 +        10,10,11,10,11,11,11,12,13,12,13,13, 0, 0, 0, 0,
605.14631 +         0, 0, 0,11,10,11,11,12,12,12,12,13,13, 0, 0, 0,
605.14632 +         0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, 0,
605.14633 +         0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0,
605.14634 +         0, 0, 0, 0, 0, 0,12,12,12,13,13,13,13,13,14,14,
605.14635 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,12,13,13,14,
605.14636 +        14,
605.14637 +};
605.14638 +
605.14639 +static const static_codebook _44cn1_s_p5_0 = {
605.14640 +        2, 289,
605.14641 +        (long *)_vq_lengthlist__44cn1_s_p5_0,
605.14642 +        1, -529530880, 1611661312, 5, 0,
605.14643 +        (long *)_vq_quantlist__44cn1_s_p5_0,
605.14644 +        0
605.14645 +};
605.14646 +
605.14647 +static const long _vq_quantlist__44cn1_s_p6_0[] = {
605.14648 +        1,
605.14649 +        0,
605.14650 +        2,
605.14651 +};
605.14652 +
605.14653 +static const long _vq_lengthlist__44cn1_s_p6_0[] = {
605.14654 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 6, 6,10, 9, 9,11,
605.14655 +         9, 9, 4, 6, 6,10, 9, 9,10, 9, 9, 7,10,10,11,11,
605.14656 +        11,12,11,11, 7, 9, 9,11,11,10,11,10,10, 7, 9, 9,
605.14657 +        11,10,11,11,10,10, 7,10,10,11,11,11,12,11,11, 7,
605.14658 +         9, 9,11,10,10,11,10,10, 7, 9, 9,11,10,10,11,10,
605.14659 +        10,
605.14660 +};
605.14661 +
605.14662 +static const static_codebook _44cn1_s_p6_0 = {
605.14663 +        4, 81,
605.14664 +        (long *)_vq_lengthlist__44cn1_s_p6_0,
605.14665 +        1, -529137664, 1618345984, 2, 0,
605.14666 +        (long *)_vq_quantlist__44cn1_s_p6_0,
605.14667 +        0
605.14668 +};
605.14669 +
605.14670 +static const long _vq_quantlist__44cn1_s_p6_1[] = {
605.14671 +        5,
605.14672 +        4,
605.14673 +        6,
605.14674 +        3,
605.14675 +        7,
605.14676 +        2,
605.14677 +        8,
605.14678 +        1,
605.14679 +        9,
605.14680 +        0,
605.14681 +        10,
605.14682 +};
605.14683 +
605.14684 +static const long _vq_lengthlist__44cn1_s_p6_1[] = {
605.14685 +         1, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,10, 7, 6,
605.14686 +         8, 8, 8, 8, 8, 8,10,10,10, 7, 6, 7, 7, 8, 8, 8,
605.14687 +         8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
605.14688 +         7, 8, 8, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 9, 9,
605.14689 +         9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,
605.14690 +         9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9,
605.14691 +         9, 9, 9,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,10,
605.14692 +        10,10,10, 9, 9, 9, 9, 9, 9,
605.14693 +};
605.14694 +
605.14695 +static const static_codebook _44cn1_s_p6_1 = {
605.14696 +        2, 121,
605.14697 +        (long *)_vq_lengthlist__44cn1_s_p6_1,
605.14698 +        1, -531365888, 1611661312, 4, 0,
605.14699 +        (long *)_vq_quantlist__44cn1_s_p6_1,
605.14700 +        0
605.14701 +};
605.14702 +
605.14703 +static const long _vq_quantlist__44cn1_s_p7_0[] = {
605.14704 +        6,
605.14705 +        5,
605.14706 +        7,
605.14707 +        4,
605.14708 +        8,
605.14709 +        3,
605.14710 +        9,
605.14711 +        2,
605.14712 +        10,
605.14713 +        1,
605.14714 +        11,
605.14715 +        0,
605.14716 +        12,
605.14717 +};
605.14718 +
605.14719 +static const long _vq_lengthlist__44cn1_s_p7_0[] = {
605.14720 +         1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5,
605.14721 +         7, 7, 8, 8, 8, 8, 9, 9,11,11, 7, 5, 5, 7, 7, 8,
605.14722 +         8, 8, 8, 9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.14723 +        10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.14724 +        11, 0,12,12, 9, 9, 9,10,10,10,11,11,11,12, 0,13,
605.14725 +        13, 9, 9, 9, 9,10,10,11,11,11,12, 0, 0, 0,10,10,
605.14726 +        10,10,11,11,12,12,12,13, 0, 0, 0,10,10,10,10,11,
605.14727 +        11,12,12,13,12, 0, 0, 0,14,14,11,10,11,12,12,13,
605.14728 +        13,14, 0, 0, 0,15,15,11,11,12,11,12,12,14,13, 0,
605.14729 +         0, 0, 0, 0,12,12,12,12,13,13,14,14, 0, 0, 0, 0,
605.14730 +         0,13,13,12,12,13,13,13,14,
605.14731 +};
605.14732 +
605.14733 +static const static_codebook _44cn1_s_p7_0 = {
605.14734 +        2, 169,
605.14735 +        (long *)_vq_lengthlist__44cn1_s_p7_0,
605.14736 +        1, -526516224, 1616117760, 4, 0,
605.14737 +        (long *)_vq_quantlist__44cn1_s_p7_0,
605.14738 +        0
605.14739 +};
605.14740 +
605.14741 +static const long _vq_quantlist__44cn1_s_p7_1[] = {
605.14742 +        2,
605.14743 +        1,
605.14744 +        3,
605.14745 +        0,
605.14746 +        4,
605.14747 +};
605.14748 +
605.14749 +static const long _vq_lengthlist__44cn1_s_p7_1[] = {
605.14750 +         2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
605.14751 +         6, 6, 5, 5, 6, 6, 6, 5, 5,
605.14752 +};
605.14753 +
605.14754 +static const static_codebook _44cn1_s_p7_1 = {
605.14755 +        2, 25,
605.14756 +        (long *)_vq_lengthlist__44cn1_s_p7_1,
605.14757 +        1, -533725184, 1611661312, 3, 0,
605.14758 +        (long *)_vq_quantlist__44cn1_s_p7_1,
605.14759 +        0
605.14760 +};
605.14761 +
605.14762 +static const long _vq_quantlist__44cn1_s_p8_0[] = {
605.14763 +        2,
605.14764 +        1,
605.14765 +        3,
605.14766 +        0,
605.14767 +        4,
605.14768 +};
605.14769 +
605.14770 +static const long _vq_lengthlist__44cn1_s_p8_0[] = {
605.14771 +         1, 7, 7,11,11, 8,11,11,11,11, 4,11, 3,11,11,11,
605.14772 +        11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,
605.14773 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14774 +        11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,
605.14775 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14776 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14777 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14778 +        11,11,11,11,11,11,11,11,11,11,11,11,11, 7,11,11,
605.14779 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14780 +        11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,
605.14781 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,
605.14782 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14783 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14784 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14785 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14786 +        11,11,11,11,11,11,11,11,11,11, 8,11,11,11,11,11,
605.14787 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14788 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14789 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14790 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14791 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14792 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14793 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14794 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14795 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14796 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14797 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14798 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14799 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14800 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14801 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14802 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14803 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
605.14804 +        11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,
605.14805 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.14806 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.14807 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.14808 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.14809 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
605.14810 +        12,
605.14811 +};
605.14812 +
605.14813 +static const static_codebook _44cn1_s_p8_0 = {
605.14814 +        4, 625,
605.14815 +        (long *)_vq_lengthlist__44cn1_s_p8_0,
605.14816 +        1, -518283264, 1627103232, 3, 0,
605.14817 +        (long *)_vq_quantlist__44cn1_s_p8_0,
605.14818 +        0
605.14819 +};
605.14820 +
605.14821 +static const long _vq_quantlist__44cn1_s_p8_1[] = {
605.14822 +        6,
605.14823 +        5,
605.14824 +        7,
605.14825 +        4,
605.14826 +        8,
605.14827 +        3,
605.14828 +        9,
605.14829 +        2,
605.14830 +        10,
605.14831 +        1,
605.14832 +        11,
605.14833 +        0,
605.14834 +        12,
605.14835 +};
605.14836 +
605.14837 +static const long _vq_lengthlist__44cn1_s_p8_1[] = {
605.14838 +         1, 4, 4, 6, 6, 8, 8, 9,10,10,11,11,11, 6, 5, 5,
605.14839 +         7, 7, 8, 8, 9,10, 9,11,11,12, 5, 5, 5, 7, 7, 8,
605.14840 +         9,10,10,12,12,14,13,15, 7, 7, 8, 8, 9,10,11,11,
605.14841 +        10,12,10,11,15, 7, 8, 8, 8, 9, 9,11,11,13,12,12,
605.14842 +        13,15,10,10, 8, 8,10,10,12,12,11,14,10,10,15,11,
605.14843 +        11, 8, 8,10,10,12,13,13,14,15,13,15,15,15,10,10,
605.14844 +        10,10,12,12,13,12,13,10,15,15,15,10,10,11,10,13,
605.14845 +        11,13,13,15,13,15,15,15,13,13,10,11,11,11,12,10,
605.14846 +        14,11,15,15,14,14,13,10,10,12,11,13,13,14,14,15,
605.14847 +        15,15,15,15,11,11,11,11,12,11,15,12,15,15,15,15,
605.14848 +        15,12,12,11,11,14,12,13,14,
605.14849 +};
605.14850 +
605.14851 +static const static_codebook _44cn1_s_p8_1 = {
605.14852 +        2, 169,
605.14853 +        (long *)_vq_lengthlist__44cn1_s_p8_1,
605.14854 +        1, -522616832, 1620115456, 4, 0,
605.14855 +        (long *)_vq_quantlist__44cn1_s_p8_1,
605.14856 +        0
605.14857 +};
605.14858 +
605.14859 +static const long _vq_quantlist__44cn1_s_p8_2[] = {
605.14860 +        8,
605.14861 +        7,
605.14862 +        9,
605.14863 +        6,
605.14864 +        10,
605.14865 +        5,
605.14866 +        11,
605.14867 +        4,
605.14868 +        12,
605.14869 +        3,
605.14870 +        13,
605.14871 +        2,
605.14872 +        14,
605.14873 +        1,
605.14874 +        15,
605.14875 +        0,
605.14876 +        16,
605.14877 +};
605.14878 +
605.14879 +static const long _vq_lengthlist__44cn1_s_p8_2[] = {
605.14880 +         3, 4, 3, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9,
605.14881 +         9,10,11,11, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
605.14882 +         9, 9,10,10,10, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9,
605.14883 +         9, 9, 9,10,10,10, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9,
605.14884 +         9, 9,10, 9,10,11,10, 7, 6, 7, 7, 8, 8, 9, 9, 9,
605.14885 +         9, 9, 9, 9,10,10,10,11, 7, 7, 8, 8, 8, 8, 9, 9,
605.14886 +         9, 9, 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9,
605.14887 +         9, 9, 9, 9, 9, 9,10,11,11,11, 8, 8, 8, 8, 8, 8,
605.14888 +         9, 9, 9, 9, 9, 9, 9, 9,11,10,10,11,11, 8, 8, 8,
605.14889 +         9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,11,11, 9, 9,
605.14890 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,10,11,11, 9,
605.14891 +         9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11,10,11,11,
605.14892 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,10,11,
605.14893 +        11,11,11, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,11,11,
605.14894 +        10,11,11,11, 9,10,10, 9, 9, 9, 9, 9, 9, 9,10,11,
605.14895 +        11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
605.14896 +        11,11,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9, 9, 9,
605.14897 +        11,11,11,10,11,11,11,11,11, 9, 9, 9,10, 9, 9, 9,
605.14898 +         9,
605.14899 +};
605.14900 +
605.14901 +static const static_codebook _44cn1_s_p8_2 = {
605.14902 +        2, 289,
605.14903 +        (long *)_vq_lengthlist__44cn1_s_p8_2,
605.14904 +        1, -529530880, 1611661312, 5, 0,
605.14905 +        (long *)_vq_quantlist__44cn1_s_p8_2,
605.14906 +        0
605.14907 +};
605.14908 +
605.14909 +static const long _huff_lengthlist__44cn1_s_short[] = {
605.14910 +        10, 9,12,15,12,13,16,14,16, 7, 1, 5,14, 7,10,13,
605.14911 +        16,16, 9, 4, 6,16, 8,11,16,16,16,14, 4, 7,16, 9,
605.14912 +        12,14,16,16,10, 5, 7,14, 9,12,14,15,15,13, 8, 9,
605.14913 +        14,10,12,13,14,15,13, 9, 9, 7, 6, 8,11,12,12,14,
605.14914 +         8, 8, 5, 4, 5, 8,11,12,16,10,10, 6, 5, 6, 8, 9,
605.14915 +        10,
605.14916 +};
605.14917 +
605.14918 +static const static_codebook _huff_book__44cn1_s_short = {
605.14919 +        2, 81,
605.14920 +        (long *)_huff_lengthlist__44cn1_s_short,
605.14921 +        0, 0, 0, 0, 0,
605.14922 +        NULL,
605.14923 +        0
605.14924 +};
605.14925 +
605.14926 +static const long _huff_lengthlist__44cn1_sm_long[] = {
605.14927 +         3, 3, 8, 8, 8, 8,10,12,14, 3, 2, 6, 7, 7, 8,10,
605.14928 +        12,16, 7, 6, 7, 9, 8,10,12,14,16, 8, 6, 8, 4, 5,
605.14929 +         7, 9,11,13, 7, 6, 8, 5, 6, 7, 9,11,14, 8, 8,10,
605.14930 +         7, 7, 6, 8,10,13, 9,11,12, 9, 9, 7, 8,10,12,10,
605.14931 +        13,15,11,11,10, 9,10,13,13,16,17,14,15,14,13,14,
605.14932 +        17,
605.14933 +};
605.14934 +
605.14935 +static const static_codebook _huff_book__44cn1_sm_long = {
605.14936 +        2, 81,
605.14937 +        (long *)_huff_lengthlist__44cn1_sm_long,
605.14938 +        0, 0, 0, 0, 0,
605.14939 +        NULL,
605.14940 +        0
605.14941 +};
605.14942 +
605.14943 +static const long _vq_quantlist__44cn1_sm_p1_0[] = {
605.14944 +        1,
605.14945 +        0,
605.14946 +        2,
605.14947 +};
605.14948 +
605.14949 +static const long _vq_lengthlist__44cn1_sm_p1_0[] = {
605.14950 +         1, 4, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
605.14951 +         0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14952 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14953 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14954 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14955 +         0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0,
605.14956 +         0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14957 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14958 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14959 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14960 +         0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
605.14961 +         0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14962 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14963 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14964 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14965 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14966 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14967 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14968 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14969 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14970 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14971 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14972 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14973 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14974 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14975 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14976 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14977 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14978 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14979 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14980 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14981 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14982 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14983 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14984 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14985 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14986 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14987 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14988 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14989 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14990 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14991 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14992 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14993 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14994 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14995 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0,
605.14996 +         0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
605.14997 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14998 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.14999 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15000 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10, 9, 0, 0, 0,
605.15001 +         0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
605.15002 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15003 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15004 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15005 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
605.15006 +         0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
605.15007 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15008 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15009 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15010 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15011 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15012 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15013 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15014 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15015 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15016 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15017 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15018 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15019 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15020 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15021 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15022 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15023 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15024 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15025 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15026 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15027 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15028 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15029 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15030 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15031 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15032 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15033 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15034 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15035 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15036 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15037 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15038 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15039 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15040 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15041 +         0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
605.15042 +         0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15043 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15044 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15045 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15046 +         0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
605.15047 +         0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0,
605.15048 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15049 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15050 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15051 +         0, 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10,
605.15052 +         0, 0, 0, 0, 0, 0, 9,10, 9, 0, 0, 0, 0, 0, 0, 0,
605.15053 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15054 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15055 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15056 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15057 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15058 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15059 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15060 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15061 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15062 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15063 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15064 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15065 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15066 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15067 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15068 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15069 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15070 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15071 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15072 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15073 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15074 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15075 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15076 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15077 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15078 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15079 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15080 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15081 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15082 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15083 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15084 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15085 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15086 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15087 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15088 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15089 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15090 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15091 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15092 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15093 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15094 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15095 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15096 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15097 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15098 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15099 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15100 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15101 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15102 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15103 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15104 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15105 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15106 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15107 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15108 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15109 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15110 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15111 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15112 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15113 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15114 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15115 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15116 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15117 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15118 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15119 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15120 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15121 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15122 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15123 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15124 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15125 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15126 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15127 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15128 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15129 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15130 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15131 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15132 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15133 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15134 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15135 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15136 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15137 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15138 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15139 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15140 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15141 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15142 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15143 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15144 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15145 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15146 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15147 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15148 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15149 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15150 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15151 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15152 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15153 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15154 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15155 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15156 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15157 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15158 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15159 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15160 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15161 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15162 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15163 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15164 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15165 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15166 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15167 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15168 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15169 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15170 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15171 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15172 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15173 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15174 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15175 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15176 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15177 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15178 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15179 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15180 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15181 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15182 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15183 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15184 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15185 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15186 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15187 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15188 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15189 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15190 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15191 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15192 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15193 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15194 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15195 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15196 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15197 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15198 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15199 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15200 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15201 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15202 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15203 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15204 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15205 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15206 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15207 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15208 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15209 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15210 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15211 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15212 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15213 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15214 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15215 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15216 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15217 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15218 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15219 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15220 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15221 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15222 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15223 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15224 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15225 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15226 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15227 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15228 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15229 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15230 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15231 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15232 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15233 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15234 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15235 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15236 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15237 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15238 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15239 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15240 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15241 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15242 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15243 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15244 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15245 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15246 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15247 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15248 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15249 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15250 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15251 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15252 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15253 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15254 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15255 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15256 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15257 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15258 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15259 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15260 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15261 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15262 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15263 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15264 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15265 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15266 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15267 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15268 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15269 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15270 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15271 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15272 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15273 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15274 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15275 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15276 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15277 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15278 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15279 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15280 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15281 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15282 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15283 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15284 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15285 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15286 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15287 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15288 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15289 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15290 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15291 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15292 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15293 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15294 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15295 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15296 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15297 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15298 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15299 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15300 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15301 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15302 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15303 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15304 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15305 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15306 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15307 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15308 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15309 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15310 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15311 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15312 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15313 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15314 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15315 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15316 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15317 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15318 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15319 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15320 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15321 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15322 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15323 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15324 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15325 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15326 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15327 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15329 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15330 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15331 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15332 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15333 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15334 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15335 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15336 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15337 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15338 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15339 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15340 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15341 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15342 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15343 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15344 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15345 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15346 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15347 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15348 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15349 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15350 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15351 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15352 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15353 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15354 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15355 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15356 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15357 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15358 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15359 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15360 +         0,
605.15361 +};
605.15362 +
605.15363 +static const static_codebook _44cn1_sm_p1_0 = {
605.15364 +        8, 6561,
605.15365 +        (long *)_vq_lengthlist__44cn1_sm_p1_0,
605.15366 +        1, -535822336, 1611661312, 2, 0,
605.15367 +        (long *)_vq_quantlist__44cn1_sm_p1_0,
605.15368 +        0
605.15369 +};
605.15370 +
605.15371 +static const long _vq_quantlist__44cn1_sm_p2_0[] = {
605.15372 +        2,
605.15373 +        1,
605.15374 +        3,
605.15375 +        0,
605.15376 +        4,
605.15377 +};
605.15378 +
605.15379 +static const long _vq_lengthlist__44cn1_sm_p2_0[] = {
605.15380 +         1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15381 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0,
605.15382 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15383 +         0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9,
605.15385 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15386 +         0, 0, 0, 0, 7, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
605.15387 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15388 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15389 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15390 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15391 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15392 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15393 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15394 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15395 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15396 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15397 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15399 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15400 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15401 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15402 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15403 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15404 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15405 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15406 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15410 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15411 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15412 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15413 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15414 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15415 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15416 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15417 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15418 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15419 +         0,
605.15420 +};
605.15421 +
605.15422 +static const static_codebook _44cn1_sm_p2_0 = {
605.15423 +        4, 625,
605.15424 +        (long *)_vq_lengthlist__44cn1_sm_p2_0,
605.15425 +        1, -533725184, 1611661312, 3, 0,
605.15426 +        (long *)_vq_quantlist__44cn1_sm_p2_0,
605.15427 +        0
605.15428 +};
605.15429 +
605.15430 +static const long _vq_quantlist__44cn1_sm_p3_0[] = {
605.15431 +        4,
605.15432 +        3,
605.15433 +        5,
605.15434 +        2,
605.15435 +        6,
605.15436 +        1,
605.15437 +        7,
605.15438 +        0,
605.15439 +        8,
605.15440 +};
605.15441 +
605.15442 +static const long _vq_lengthlist__44cn1_sm_p3_0[] = {
605.15443 +         1, 3, 4, 7, 7, 0, 0, 0, 0, 0, 4, 4, 7, 7, 0, 0,
605.15444 +         0, 0, 0, 4, 5, 7, 7, 0, 0, 0, 0, 0, 6, 7, 8, 8,
605.15445 +         0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0,
605.15446 +         9, 9, 0, 0, 0, 0, 0, 0, 0,10, 9, 0, 0, 0, 0, 0,
605.15447 +         0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605.15448 +         0,
605.15449 +};
605.15450 +
605.15451 +static const static_codebook _44cn1_sm_p3_0 = {
605.15452 +        2, 81,
605.15453 +        (long *)_vq_lengthlist__44cn1_sm_p3_0,
605.15454 +        1, -531628032, 1611661312, 4, 0,
605.15455 +        (long *)_vq_quantlist__44cn1_sm_p3_0,
605.15456 +        0
605.15457 +};
605.15458 +
605.15459 +static const long _vq_quantlist__44cn1_sm_p4_0[] = {
605.15460 +        4,
605.15461 +        3,
605.15462 +        5,
605.15463 +        2,
605.15464 +        6,
605.15465 +        1,
605.15466 +        7,
605.15467 +        0,
605.15468 +        8,
605.15469 +};
605.15470 +
605.15471 +static const long _vq_lengthlist__44cn1_sm_p4_0[] = {
605.15472 +         1, 4, 3, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 8, 7,
605.15473 +         9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8,
605.15474 +         8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0,
605.15475 +         9, 9, 9, 9,10,10, 0, 0, 0, 9, 9, 9, 9,10,10, 0,
605.15476 +         0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0,10,10,11,
605.15477 +        11,
605.15478 +};
605.15479 +
605.15480 +static const static_codebook _44cn1_sm_p4_0 = {
605.15481 +        2, 81,
605.15482 +        (long *)_vq_lengthlist__44cn1_sm_p4_0,
605.15483 +        1, -531628032, 1611661312, 4, 0,
605.15484 +        (long *)_vq_quantlist__44cn1_sm_p4_0,
605.15485 +        0
605.15486 +};
605.15487 +
605.15488 +static const long _vq_quantlist__44cn1_sm_p5_0[] = {
605.15489 +        8,
605.15490 +        7,
605.15491 +        9,
605.15492 +        6,
605.15493 +        10,
605.15494 +        5,
605.15495 +        11,
605.15496 +        4,
605.15497 +        12,
605.15498 +        3,
605.15499 +        13,
605.15500 +        2,
605.15501 +        14,
605.15502 +        1,
605.15503 +        15,
605.15504 +        0,
605.15505 +        16,
605.15506 +};
605.15507 +
605.15508 +static const long _vq_lengthlist__44cn1_sm_p5_0[] = {
605.15509 +         1, 4, 4, 6, 6, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,
605.15510 +        11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11,
605.15511 +        12,12, 0, 6, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,
605.15512 +        11,12,12, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
605.15513 +        11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10,11,
605.15514 +        11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,
605.15515 +        11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,
605.15516 +        10,11,11,12,12,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
605.15517 +        10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10,
605.15518 +        10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
605.15519 +        10,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0, 0, 9,
605.15520 +         9,10,10,11,11,12,12,12,13,13,13, 0, 0, 0, 0, 0,
605.15521 +        10,10,11,11,11,11,12,12,13,13,14,14, 0, 0, 0, 0,
605.15522 +         0, 0, 0,11,11,11,11,12,12,13,13,14,14, 0, 0, 0,
605.15523 +         0, 0, 0, 0,11,11,12,12,13,13,13,13,14,14, 0, 0,
605.15524 +         0, 0, 0, 0, 0,11,11,12,12,13,13,13,13,14,14, 0,
605.15525 +         0, 0, 0, 0, 0, 0,12,12,12,13,13,13,14,14,14,14,
605.15526 +         0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,14,14,14,
605.15527 +        14,
605.15528 +};
605.15529 +
605.15530 +static const static_codebook _44cn1_sm_p5_0 = {
605.15531 +        2, 289,
605.15532 +        (long *)_vq_lengthlist__44cn1_sm_p5_0,
605.15533 +        1, -529530880, 1611661312, 5, 0,
605.15534 +        (long *)_vq_quantlist__44cn1_sm_p5_0,
605.15535 +        0
605.15536 +};
605.15537 +
605.15538 +static const long _vq_quantlist__44cn1_sm_p6_0[] = {
605.15539 +        1,
605.15540 +        0,
605.15541 +        2,
605.15542 +};
605.15543 +
605.15544 +static const long _vq_lengthlist__44cn1_sm_p6_0[] = {
605.15545 +         1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 6,10, 9, 9,11,
605.15546 +         9, 9, 4, 6, 7,10, 9, 9,11, 9, 9, 7,10,10,10,11,
605.15547 +        11,11,11,10, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
605.15548 +        11,10,11,11,10,10, 7,11,11,11,11,11,12,11,11, 7,
605.15549 +         9, 9,11,10,10,12,10,10, 7, 9, 9,11,10,10,11,10,
605.15550 +        10,
605.15551 +};
605.15552 +
605.15553 +static const static_codebook _44cn1_sm_p6_0 = {
605.15554 +        4, 81,
605.15555 +        (long *)_vq_lengthlist__44cn1_sm_p6_0,
605.15556 +        1, -529137664, 1618345984, 2, 0,
605.15557 +        (long *)_vq_quantlist__44cn1_sm_p6_0,
605.15558 +        0
605.15559 +};
605.15560 +
605.15561 +static const long _vq_quantlist__44cn1_sm_p6_1[] = {
605.15562 +        5,
605.15563 +        4,
605.15564 +        6,
605.15565 +        3,
605.15566 +        7,
605.15567 +        2,
605.15568 +        8,
605.15569 +        1,
605.15570 +        9,
605.15571 +        0,
605.15572 +        10,
605.15573 +};
605.15574 +
605.15575 +static const long _vq_lengthlist__44cn1_sm_p6_1[] = {
605.15576 +         2, 4, 4, 5, 5, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6,
605.15577 +         7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8,
605.15578 +         8,10, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
605.15579 +         7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8,
605.15580 +         8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,
605.15581 +         8, 8, 8, 8, 8, 8, 9, 9,10,10,10,10,10, 8, 8, 8,
605.15582 +         8, 9, 9,10,10,10,10,10, 9, 9, 9, 9, 8, 9,10,10,
605.15583 +        10,10,10, 8, 9, 8, 8, 9, 8,
605.15584 +};
605.15585 +
605.15586 +static const static_codebook _44cn1_sm_p6_1 = {
605.15587 +        2, 121,
605.15588 +        (long *)_vq_lengthlist__44cn1_sm_p6_1,
605.15589 +        1, -531365888, 1611661312, 4, 0,
605.15590 +        (long *)_vq_quantlist__44cn1_sm_p6_1,
605.15591 +        0
605.15592 +};
605.15593 +
605.15594 +static const long _vq_quantlist__44cn1_sm_p7_0[] = {
605.15595 +        6,
605.15596 +        5,
605.15597 +        7,
605.15598 +        4,
605.15599 +        8,
605.15600 +        3,
605.15601 +        9,
605.15602 +        2,
605.15603 +        10,
605.15604 +        1,
605.15605 +        11,
605.15606 +        0,
605.15607 +        12,
605.15608 +};
605.15609 +
605.15610 +static const long _vq_lengthlist__44cn1_sm_p7_0[] = {
605.15611 +         1, 4, 4, 6, 6, 7, 7, 7, 7, 9, 9,10,10, 7, 5, 5,
605.15612 +         7, 7, 8, 8, 8, 8,10, 9,11,10, 7, 5, 5, 7, 7, 8,
605.15613 +         8, 8, 8, 9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,
605.15614 +        10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
605.15615 +        11, 0,12,12, 9, 9, 9,10,10,10,11,11,12,12, 0,13,
605.15616 +        13, 9, 9, 9, 9,10,10,11,11,12,12, 0, 0, 0,10,10,
605.15617 +        10,10,11,11,12,12,12,13, 0, 0, 0,10,10,10,10,11,
605.15618 +        11,12,12,12,12, 0, 0, 0,14,14,11,11,11,11,12,13,
605.15619 +        13,13, 0, 0, 0,14,14,11,10,11,11,12,12,13,13, 0,
605.15620 +         0, 0, 0, 0,12,12,12,12,13,13,13,14, 0, 0, 0, 0,
605.15621 +         0,13,12,12,12,13,13,13,14,
605.15622 +};
605.15623 +
605.15624 +static const static_codebook _44cn1_sm_p7_0 = {
605.15625 +        2, 169,
605.15626 +        (long *)_vq_lengthlist__44cn1_sm_p7_0,
605.15627 +        1, -526516224, 1616117760, 4, 0,
605.15628 +        (long *)_vq_quantlist__44cn1_sm_p7_0,
605.15629 +        0
605.15630 +};
605.15631 +
605.15632 +static const long _vq_quantlist__44cn1_sm_p7_1[] = {
605.15633 +        2,
605.15634 +        1,
605.15635 +        3,
605.15636 +        0,
605.15637 +        4,
605.15638 +};
605.15639 +
605.15640 +static const long _vq_lengthlist__44cn1_sm_p7_1[] = {
605.15641 +         2, 4, 4, 4, 5, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6,
605.15642 +         5, 5, 5, 5, 6, 6, 6, 5, 5,
605.15643 +};
605.15644 +
605.15645 +static const static_codebook _44cn1_sm_p7_1 = {
605.15646 +        2, 25,
605.15647 +        (long *)_vq_lengthlist__44cn1_sm_p7_1,
605.15648 +        1, -533725184, 1611661312, 3, 0,
605.15649 +        (long *)_vq_quantlist__44cn1_sm_p7_1,
605.15650 +        0
605.15651 +};
605.15652 +
605.15653 +static const long _vq_quantlist__44cn1_sm_p8_0[] = {
605.15654 +        4,
605.15655 +        3,
605.15656 +        5,
605.15657 +        2,
605.15658 +        6,
605.15659 +        1,
605.15660 +        7,
605.15661 +        0,
605.15662 +        8,
605.15663 +};
605.15664 +
605.15665 +static const long _vq_lengthlist__44cn1_sm_p8_0[] = {
605.15666 +         1, 4, 4,12,11,13,13,14,14, 4, 7, 7,11,13,14,14,
605.15667 +        14,14, 3, 8, 3,14,14,14,14,14,14,14,10,12,14,14,
605.15668 +        14,14,14,14,14,14, 5,14, 8,14,14,14,14,14,12,14,
605.15669 +        13,14,14,14,14,14,14,14,13,14,10,14,14,14,14,14,
605.15670 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
605.15671 +        14,
605.15672 +};
605.15673 +
605.15674 +static const static_codebook _44cn1_sm_p8_0 = {
605.15675 +        2, 81,
605.15676 +        (long *)_vq_lengthlist__44cn1_sm_p8_0,
605.15677 +        1, -516186112, 1627103232, 4, 0,
605.15678 +        (long *)_vq_quantlist__44cn1_sm_p8_0,
605.15679 +        0
605.15680 +};
605.15681 +
605.15682 +static const long _vq_quantlist__44cn1_sm_p8_1[] = {
605.15683 +        6,
605.15684 +        5,
605.15685 +        7,
605.15686 +        4,
605.15687 +        8,
605.15688 +        3,
605.15689 +        9,
605.15690 +        2,
605.15691 +        10,
605.15692 +        1,
605.15693 +        11,
605.15694 +        0,
605.15695 +        12,
605.15696 +};
605.15697 +
605.15698 +static const long _vq_lengthlist__44cn1_sm_p8_1[] = {
605.15699 +         1, 4, 4, 6, 6, 8, 8, 9, 9,10,11,11,11, 6, 5, 5,
605.15700 +         7, 7, 8, 8,10,10,10,11,11,11, 6, 5, 5, 7, 7, 8,
605.15701 +         8,10,10,11,12,12,12,14, 7, 7, 7, 8, 9, 9,11,11,
605.15702 +        11,12,11,12,17, 7, 7, 8, 7, 9, 9,11,11,12,12,12,
605.15703 +        12,14,11,11, 8, 8,10,10,11,12,12,13,11,12,14,11,
605.15704 +        11, 8, 8,10,10,11,12,12,13,13,12,14,15,14,10,10,
605.15705 +        10,10,11,12,12,12,12,11,14,13,16,10,10,10, 9,12,
605.15706 +        11,12,12,13,14,14,15,14,14,13,10,10,11,11,12,11,
605.15707 +        13,11,14,12,15,13,14,11,10,12,10,12,12,13,13,13,
605.15708 +        13,14,15,15,12,12,11,11,12,11,13,12,14,14,14,14,
605.15709 +        17,12,12,11,10,13,11,13,13,
605.15710 +};
605.15711 +
605.15712 +static const static_codebook _44cn1_sm_p8_1 = {
605.15713 +        2, 169,
605.15714 +        (long *)_vq_lengthlist__44cn1_sm_p8_1,
605.15715 +        1, -522616832, 1620115456, 4, 0,
605.15716 +        (long *)_vq_quantlist__44cn1_sm_p8_1,
605.15717 +        0
605.15718 +};
605.15719 +
605.15720 +static const long _vq_quantlist__44cn1_sm_p8_2[] = {
605.15721 +        8,
605.15722 +        7,
605.15723 +        9,
605.15724 +        6,
605.15725 +        10,
605.15726 +        5,
605.15727 +        11,
605.15728 +        4,
605.15729 +        12,
605.15730 +        3,
605.15731 +        13,
605.15732 +        2,
605.15733 +        14,
605.15734 +        1,
605.15735 +        15,
605.15736 +        0,
605.15737 +        16,
605.15738 +};
605.15739 +
605.15740 +static const long _vq_lengthlist__44cn1_sm_p8_2[] = {
605.15741 +         3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
605.15742 +         9,10, 6, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9,
605.15743 +         9, 9,10, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9,
605.15744 +         9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,
605.15745 +         9, 9, 9, 9,10,10,10, 7, 7, 7, 8, 8, 8, 9, 9, 9,
605.15746 +         9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 8, 8, 9, 9,
605.15747 +         9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 8, 8, 9,
605.15748 +         9, 9, 9, 9, 9, 9, 9,11,10,11, 8, 8, 8, 8, 8, 8,
605.15749 +         9, 9, 9, 9, 9, 9, 9, 9,10,10,10,11,11, 8, 8, 8,
605.15750 +         8, 9, 9, 9, 9, 9, 9, 9, 9,11,10,11,11,11, 9, 9,
605.15751 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11,10,11,11, 9,
605.15752 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11,11,10,11,11,
605.15753 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,11,11,
605.15754 +        11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11,11,
605.15755 +        11,11,11,11, 9,10,10,10, 9, 9, 9, 9, 9, 9,11,10,
605.15756 +        11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
605.15757 +        11,11,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9, 9, 9,
605.15758 +        10,11,11,11,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9,
605.15759 +         9,
605.15760 +};
605.15761 +
605.15762 +static const static_codebook _44cn1_sm_p8_2 = {
605.15763 +        2, 289,
605.15764 +        (long *)_vq_lengthlist__44cn1_sm_p8_2,
605.15765 +        1, -529530880, 1611661312, 5, 0,
605.15766 +        (long *)_vq_quantlist__44cn1_sm_p8_2,
605.15767 +        0
605.15768 +};
605.15769 +
605.15770 +static const long _huff_lengthlist__44cn1_sm_short[] = {
605.15771 +         5, 6,12,14,12,14,16,17,18, 4, 2, 5,11, 7,10,12,
605.15772 +        14,15, 9, 4, 5,11, 7,10,13,15,18,15, 6, 7, 5, 6,
605.15773 +         8,11,13,16,11, 5, 6, 5, 5, 6, 9,13,15,12, 5, 7,
605.15774 +         6, 5, 6, 9,12,14,12, 6, 7, 8, 6, 7, 9,12,13,14,
605.15775 +         8, 8, 7, 5, 5, 8,10,12,16, 9, 9, 8, 6, 6, 7, 9,
605.15776 +         9,
605.15777 +};
605.15778 +
605.15779 +static const static_codebook _huff_book__44cn1_sm_short = {
605.15780 +        2, 81,
605.15781 +        (long *)_huff_lengthlist__44cn1_sm_short,
605.15782 +        0, 0, 0, 0, 0,
605.15783 +        NULL,
605.15784 +        0
605.15785 +};
605.15786 +
   606.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   606.2 +++ b/libs/vorbis/books/floor/floor_books.h	Sat Feb 01 19:58:19 2014 +0200
   606.3 @@ -0,0 +1,1547 @@
   606.4 +/********************************************************************
   606.5 + *                                                                  *
   606.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   606.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   606.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   606.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  606.10 + *                                                                  *
  606.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  606.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  606.13 + *                                                                  *
  606.14 + ********************************************************************
  606.15 +
  606.16 + function: static codebooks autogenerated by huff/huffbuld
  606.17 + last modified: $Id: floor_books.h 16939 2010-03-01 08:38:14Z xiphmont $
  606.18 +
  606.19 + ********************************************************************/
  606.20 +
  606.21 +#include "codebook.h"
  606.22 +
  606.23 +static const long _huff_lengthlist_line_256x7_0sub1[] = {
  606.24 +         0, 2, 3, 3, 3, 3, 4, 3, 4,
  606.25 +};
  606.26 +
  606.27 +static const static_codebook _huff_book_line_256x7_0sub1 = {
  606.28 +        1, 9,
  606.29 +        (long *)_huff_lengthlist_line_256x7_0sub1,
  606.30 +        0, 0, 0, 0, 0,
  606.31 +        NULL,
  606.32 +        0
  606.33 +};
  606.34 +
  606.35 +static const long _huff_lengthlist_line_256x7_0sub2[] = {
  606.36 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 3, 4, 3, 5, 3,
  606.37 +         6, 3, 6, 4, 6, 4, 7, 5, 7,
  606.38 +};
  606.39 +
  606.40 +static const static_codebook _huff_book_line_256x7_0sub2 = {
  606.41 +        1, 25,
  606.42 +        (long *)_huff_lengthlist_line_256x7_0sub2,
  606.43 +        0, 0, 0, 0, 0,
  606.44 +        NULL,
  606.45 +        0
  606.46 +};
  606.47 +
  606.48 +static const long _huff_lengthlist_line_256x7_0sub3[] = {
  606.49 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  606.50 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 2, 5, 3, 5, 3,
  606.51 +         6, 3, 6, 4, 7, 6, 7, 8, 7, 9, 8, 9, 9, 9,10, 9,
  606.52 +        11,13,11,13,10,10,13,13,13,13,13,13,12,12,12,12,
  606.53 +};
  606.54 +
  606.55 +static const static_codebook _huff_book_line_256x7_0sub3 = {
  606.56 +        1, 64,
  606.57 +        (long *)_huff_lengthlist_line_256x7_0sub3,
  606.58 +        0, 0, 0, 0, 0,
  606.59 +        NULL,
  606.60 +        0
  606.61 +};
  606.62 +
  606.63 +static const long _huff_lengthlist_line_256x7_1sub1[] = {
  606.64 +         0, 3, 3, 3, 3, 2, 4, 3, 4,
  606.65 +};
  606.66 +
  606.67 +static const static_codebook _huff_book_line_256x7_1sub1 = {
  606.68 +        1, 9,
  606.69 +        (long *)_huff_lengthlist_line_256x7_1sub1,
  606.70 +        0, 0, 0, 0, 0,
  606.71 +        NULL,
  606.72 +        0
  606.73 +};
  606.74 +
  606.75 +static const long _huff_lengthlist_line_256x7_1sub2[] = {
  606.76 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 4, 3, 4, 4,
  606.77 +         5, 4, 6, 5, 6, 7, 6, 8, 8,
  606.78 +};
  606.79 +
  606.80 +static const static_codebook _huff_book_line_256x7_1sub2 = {
  606.81 +        1, 25,
  606.82 +        (long *)_huff_lengthlist_line_256x7_1sub2,
  606.83 +        0, 0, 0, 0, 0,
  606.84 +        NULL,
  606.85 +        0
  606.86 +};
  606.87 +
  606.88 +static const long _huff_lengthlist_line_256x7_1sub3[] = {
  606.89 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  606.90 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 4, 3, 6, 3, 7,
  606.91 +         3, 8, 5, 8, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  606.92 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
  606.93 +};
  606.94 +
  606.95 +static const static_codebook _huff_book_line_256x7_1sub3 = {
  606.96 +        1, 64,
  606.97 +        (long *)_huff_lengthlist_line_256x7_1sub3,
  606.98 +        0, 0, 0, 0, 0,
  606.99 +        NULL,
 606.100 +        0
 606.101 +};
 606.102 +
 606.103 +static const long _huff_lengthlist_line_256x7_class0[] = {
 606.104 +         7, 5, 5, 9, 9, 6, 6, 9,12, 8, 7, 8,11, 8, 9,15,
 606.105 +         6, 3, 3, 7, 7, 4, 3, 6, 9, 6, 5, 6, 8, 6, 8,15,
 606.106 +         8, 5, 5, 9, 8, 5, 4, 6,10, 7, 5, 5,11, 8, 7,15,
 606.107 +        14,15,13,13,13,13, 8,11,15,10, 7, 6,11, 9,10,15,
 606.108 +};
 606.109 +
 606.110 +static const static_codebook _huff_book_line_256x7_class0 = {
 606.111 +        1, 64,
 606.112 +        (long *)_huff_lengthlist_line_256x7_class0,
 606.113 +        0, 0, 0, 0, 0,
 606.114 +        NULL,
 606.115 +        0
 606.116 +};
 606.117 +
 606.118 +static const long _huff_lengthlist_line_256x7_class1[] = {
 606.119 +         5, 6, 8,15, 6, 9,10,15,10,11,12,15,15,15,15,15,
 606.120 +         4, 6, 7,15, 6, 7, 8,15, 9, 8, 9,15,15,15,15,15,
 606.121 +         6, 8, 9,15, 7, 7, 8,15,10, 9,10,15,15,15,15,15,
 606.122 +        15,13,15,15,15,10,11,15,15,13,13,15,15,15,15,15,
 606.123 +         4, 6, 7,15, 6, 8, 9,15,10,10,12,15,15,15,15,15,
 606.124 +         2, 5, 6,15, 5, 6, 7,15, 8, 6, 7,15,15,15,15,15,
 606.125 +         5, 6, 8,15, 5, 6, 7,15, 9, 6, 7,15,15,15,15,15,
 606.126 +        14,12,13,15,12,10,11,15,15,15,15,15,15,15,15,15,
 606.127 +         7, 8, 9,15, 9,10,10,15,15,14,14,15,15,15,15,15,
 606.128 +         5, 6, 7,15, 7, 8, 9,15,12, 9,10,15,15,15,15,15,
 606.129 +         7, 7, 9,15, 7, 7, 8,15,12, 8, 9,15,15,15,15,15,
 606.130 +        13,13,14,15,12,11,12,15,15,15,15,15,15,15,15,15,
 606.131 +        15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
 606.132 +        13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,
 606.133 +        15,12,13,15,15,12,13,15,15,14,15,15,15,15,15,15,
 606.134 +        15,15,15,15,15,15,13,15,15,15,15,15,15,15,15,15,
 606.135 +};
 606.136 +
 606.137 +static const static_codebook _huff_book_line_256x7_class1 = {
 606.138 +        1, 256,
 606.139 +        (long *)_huff_lengthlist_line_256x7_class1,
 606.140 +        0, 0, 0, 0, 0,
 606.141 +        NULL,
 606.142 +        0
 606.143 +};
 606.144 +
 606.145 +static const long _huff_lengthlist_line_512x17_0sub0[] = {
 606.146 +         4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 606.147 +         5, 6, 5, 6, 6, 6, 6, 5, 6, 6, 7, 6, 7, 6, 7, 6,
 606.148 +         7, 6, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 9, 7, 9, 7,
 606.149 +         9, 7, 9, 8, 9, 8,10, 8,10, 8,10, 7,10, 6,10, 8,
 606.150 +        10, 8,11, 7,10, 7,11, 8,11,11,12,12,11,11,12,11,
 606.151 +        13,11,13,11,13,12,15,12,13,13,14,14,14,14,14,15,
 606.152 +        15,15,16,14,17,19,19,18,18,18,18,18,18,18,18,18,
 606.153 +        18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
 606.154 +};
 606.155 +
 606.156 +static const static_codebook _huff_book_line_512x17_0sub0 = {
 606.157 +        1, 128,
 606.158 +        (long *)_huff_lengthlist_line_512x17_0sub0,
 606.159 +        0, 0, 0, 0, 0,
 606.160 +        NULL,
 606.161 +        0
 606.162 +};
 606.163 +
 606.164 +static const long _huff_lengthlist_line_512x17_1sub0[] = {
 606.165 +         2, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 6, 5,
 606.166 +         6, 5, 6, 6, 7, 6, 7, 6, 8, 7, 8, 7, 8, 7, 8, 7,
 606.167 +};
 606.168 +
 606.169 +static const static_codebook _huff_book_line_512x17_1sub0 = {
 606.170 +        1, 32,
 606.171 +        (long *)_huff_lengthlist_line_512x17_1sub0,
 606.172 +        0, 0, 0, 0, 0,
 606.173 +        NULL,
 606.174 +        0
 606.175 +};
 606.176 +
 606.177 +static const long _huff_lengthlist_line_512x17_1sub1[] = {
 606.178 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.179 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.180 +         4, 3, 5, 3, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 6, 5,
 606.181 +         6, 5, 7, 5, 8, 6, 8, 6, 8, 6, 8, 6, 8, 7, 9, 7,
 606.182 +         9, 7,11, 9,11,11,12,11,14,12,14,16,14,16,13,16,
 606.183 +        14,16,12,15,13,16,14,16,13,14,12,15,13,15,13,13,
 606.184 +        13,15,12,14,14,15,13,15,12,15,15,15,15,15,15,15,
 606.185 +        15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
 606.186 +};
 606.187 +
 606.188 +static const static_codebook _huff_book_line_512x17_1sub1 = {
 606.189 +        1, 128,
 606.190 +        (long *)_huff_lengthlist_line_512x17_1sub1,
 606.191 +        0, 0, 0, 0, 0,
 606.192 +        NULL,
 606.193 +        0
 606.194 +};
 606.195 +
 606.196 +static const long _huff_lengthlist_line_512x17_2sub1[] = {
 606.197 +         0, 4, 5, 4, 4, 4, 5, 4, 4, 4, 5, 4, 5, 4, 5, 3,
 606.198 +         5, 3,
 606.199 +};
 606.200 +
 606.201 +static const static_codebook _huff_book_line_512x17_2sub1 = {
 606.202 +        1, 18,
 606.203 +        (long *)_huff_lengthlist_line_512x17_2sub1,
 606.204 +        0, 0, 0, 0, 0,
 606.205 +        NULL,
 606.206 +        0
 606.207 +};
 606.208 +
 606.209 +static const long _huff_lengthlist_line_512x17_2sub2[] = {
 606.210 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.211 +         0, 0, 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 6, 4, 6, 5,
 606.212 +         6, 5, 7, 5, 7, 6, 8, 6, 8, 6, 8, 7, 8, 7, 9, 7,
 606.213 +         9, 8,
 606.214 +};
 606.215 +
 606.216 +static const static_codebook _huff_book_line_512x17_2sub2 = {
 606.217 +        1, 50,
 606.218 +        (long *)_huff_lengthlist_line_512x17_2sub2,
 606.219 +        0, 0, 0, 0, 0,
 606.220 +        NULL,
 606.221 +        0
 606.222 +};
 606.223 +
 606.224 +static const long _huff_lengthlist_line_512x17_2sub3[] = {
 606.225 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.226 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.227 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.228 +         0, 0, 3, 3, 3, 3, 4, 3, 4, 4, 5, 5, 6, 6, 7, 7,
 606.229 +         7, 8, 8,11, 8, 9, 9, 9,10,11,11,11, 9,10,10,11,
 606.230 +        11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,
 606.231 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 606.232 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 606.233 +};
 606.234 +
 606.235 +static const static_codebook _huff_book_line_512x17_2sub3 = {
 606.236 +        1, 128,
 606.237 +        (long *)_huff_lengthlist_line_512x17_2sub3,
 606.238 +        0, 0, 0, 0, 0,
 606.239 +        NULL,
 606.240 +        0
 606.241 +};
 606.242 +
 606.243 +static const long _huff_lengthlist_line_512x17_3sub1[] = {
 606.244 +         0, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 5, 4, 5,
 606.245 +         5, 5,
 606.246 +};
 606.247 +
 606.248 +static const static_codebook _huff_book_line_512x17_3sub1 = {
 606.249 +        1, 18,
 606.250 +        (long *)_huff_lengthlist_line_512x17_3sub1,
 606.251 +        0, 0, 0, 0, 0,
 606.252 +        NULL,
 606.253 +        0
 606.254 +};
 606.255 +
 606.256 +static const long _huff_lengthlist_line_512x17_3sub2[] = {
 606.257 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.258 +         0, 0, 2, 3, 3, 4, 3, 5, 4, 6, 4, 6, 5, 7, 6, 7,
 606.259 +         6, 8, 6, 8, 7, 9, 8,10, 8,12, 9,13,10,15,10,15,
 606.260 +        11,14,
 606.261 +};
 606.262 +
 606.263 +static const static_codebook _huff_book_line_512x17_3sub2 = {
 606.264 +        1, 50,
 606.265 +        (long *)_huff_lengthlist_line_512x17_3sub2,
 606.266 +        0, 0, 0, 0, 0,
 606.267 +        NULL,
 606.268 +        0
 606.269 +};
 606.270 +
 606.271 +static const long _huff_lengthlist_line_512x17_3sub3[] = {
 606.272 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.273 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.274 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.275 +         0, 0, 4, 8, 4, 8, 4, 8, 4, 8, 5, 8, 5, 8, 6, 8,
 606.276 +         4, 8, 4, 8, 5, 8, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 606.277 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 606.278 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 606.279 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 606.280 +};
 606.281 +
 606.282 +static const static_codebook _huff_book_line_512x17_3sub3 = {
 606.283 +        1, 128,
 606.284 +        (long *)_huff_lengthlist_line_512x17_3sub3,
 606.285 +        0, 0, 0, 0, 0,
 606.286 +        NULL,
 606.287 +        0
 606.288 +};
 606.289 +
 606.290 +static const long _huff_lengthlist_line_512x17_class1[] = {
 606.291 +         1, 2, 3, 6, 5, 4, 7, 7,
 606.292 +};
 606.293 +
 606.294 +static const static_codebook _huff_book_line_512x17_class1 = {
 606.295 +        1, 8,
 606.296 +        (long *)_huff_lengthlist_line_512x17_class1,
 606.297 +        0, 0, 0, 0, 0,
 606.298 +        NULL,
 606.299 +        0
 606.300 +};
 606.301 +
 606.302 +static const long _huff_lengthlist_line_512x17_class2[] = {
 606.303 +         3, 3, 3,14, 5, 4, 4,11, 8, 6, 6,10,17,12,11,17,
 606.304 +         6, 5, 5,15, 5, 3, 4,11, 8, 5, 5, 8,16, 9,10,14,
 606.305 +        10, 8, 9,17, 8, 6, 6,13,10, 7, 7,10,16,11,13,14,
 606.306 +        17,17,17,17,17,16,16,16,16,15,16,16,16,16,16,16,
 606.307 +};
 606.308 +
 606.309 +static const static_codebook _huff_book_line_512x17_class2 = {
 606.310 +        1, 64,
 606.311 +        (long *)_huff_lengthlist_line_512x17_class2,
 606.312 +        0, 0, 0, 0, 0,
 606.313 +        NULL,
 606.314 +        0
 606.315 +};
 606.316 +
 606.317 +static const long _huff_lengthlist_line_512x17_class3[] = {
 606.318 +         2, 4, 6,17, 4, 5, 7,17, 8, 7,10,17,17,17,17,17,
 606.319 +         3, 4, 6,15, 3, 3, 6,15, 7, 6, 9,17,17,17,17,17,
 606.320 +         6, 8,10,17, 6, 6, 8,16, 9, 8,10,17,17,15,16,17,
 606.321 +        17,17,17,17,12,15,15,16,12,15,15,16,16,16,16,16,
 606.322 +};
 606.323 +
 606.324 +static const static_codebook _huff_book_line_512x17_class3 = {
 606.325 +        1, 64,
 606.326 +        (long *)_huff_lengthlist_line_512x17_class3,
 606.327 +        0, 0, 0, 0, 0,
 606.328 +        NULL,
 606.329 +        0
 606.330 +};
 606.331 +
 606.332 +static const long _huff_lengthlist_line_128x4_class0[] = {
 606.333 +         7, 7, 7,11, 6, 6, 7,11, 7, 6, 6,10,12,10,10,13,
 606.334 +         7, 7, 8,11, 7, 7, 7,11, 7, 6, 7,10,11,10,10,13,
 606.335 +        10,10, 9,12, 9, 9, 9,11, 8, 8, 8,11,13,11,10,14,
 606.336 +        15,15,14,15,15,14,13,14,15,12,12,17,17,17,17,17,
 606.337 +         7, 7, 6, 9, 6, 6, 6, 9, 7, 6, 6, 8,11,11,10,12,
 606.338 +         7, 7, 7, 9, 7, 6, 6, 9, 7, 6, 6, 9,13,10,10,11,
 606.339 +        10, 9, 8,10, 9, 8, 8,10, 8, 8, 7, 9,13,12,10,11,
 606.340 +        17,14,14,13,15,14,12,13,17,13,12,15,17,17,14,17,
 606.341 +         7, 6, 6, 7, 6, 6, 5, 7, 6, 6, 6, 6,11, 9, 9, 9,
 606.342 +         7, 7, 6, 7, 7, 6, 6, 7, 6, 6, 6, 6,10, 9, 8, 9,
 606.343 +        10, 9, 8, 8, 9, 8, 7, 8, 8, 7, 6, 8,11,10, 9,10,
 606.344 +        17,17,12,15,15,15,12,14,14,14,10,12,15,13,12,13,
 606.345 +        11,10, 8,10,11,10, 8, 8,10, 9, 7, 7,10, 9, 9,11,
 606.346 +        11,11, 9,10,11,10, 8, 9,10, 8, 6, 8,10, 9, 9,11,
 606.347 +        14,13,10,12,12,11,10,10, 8, 7, 8,10,10,11,11,12,
 606.348 +        17,17,15,17,17,17,17,17,17,13,12,17,17,17,14,17,
 606.349 +};
 606.350 +
 606.351 +static const static_codebook _huff_book_line_128x4_class0 = {
 606.352 +        1, 256,
 606.353 +        (long *)_huff_lengthlist_line_128x4_class0,
 606.354 +        0, 0, 0, 0, 0,
 606.355 +        NULL,
 606.356 +        0
 606.357 +};
 606.358 +
 606.359 +static const long _huff_lengthlist_line_128x4_0sub0[] = {
 606.360 +         2, 2, 2, 2,
 606.361 +};
 606.362 +
 606.363 +static const static_codebook _huff_book_line_128x4_0sub0 = {
 606.364 +        1, 4,
 606.365 +        (long *)_huff_lengthlist_line_128x4_0sub0,
 606.366 +        0, 0, 0, 0, 0,
 606.367 +        NULL,
 606.368 +        0
 606.369 +};
 606.370 +
 606.371 +static const long _huff_lengthlist_line_128x4_0sub1[] = {
 606.372 +         0, 0, 0, 0, 3, 2, 3, 2, 3, 3,
 606.373 +};
 606.374 +
 606.375 +static const static_codebook _huff_book_line_128x4_0sub1 = {
 606.376 +        1, 10,
 606.377 +        (long *)_huff_lengthlist_line_128x4_0sub1,
 606.378 +        0, 0, 0, 0, 0,
 606.379 +        NULL,
 606.380 +        0
 606.381 +};
 606.382 +
 606.383 +static const long _huff_lengthlist_line_128x4_0sub2[] = {
 606.384 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 4, 3, 4, 3,
 606.385 +         4, 4, 5, 4, 5, 4, 6, 5, 6,
 606.386 +};
 606.387 +
 606.388 +static const static_codebook _huff_book_line_128x4_0sub2 = {
 606.389 +        1, 25,
 606.390 +        (long *)_huff_lengthlist_line_128x4_0sub2,
 606.391 +        0, 0, 0, 0, 0,
 606.392 +        NULL,
 606.393 +        0
 606.394 +};
 606.395 +
 606.396 +static const long _huff_lengthlist_line_128x4_0sub3[] = {
 606.397 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.398 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3, 5, 3, 5, 3,
 606.399 +         5, 4, 6, 5, 6, 5, 7, 6, 6, 7, 7, 9, 9,11,11,16,
 606.400 +        11,14,10,11,11,13,16,15,15,15,15,15,15,15,15,15,
 606.401 +};
 606.402 +
 606.403 +static const static_codebook _huff_book_line_128x4_0sub3 = {
 606.404 +        1, 64,
 606.405 +        (long *)_huff_lengthlist_line_128x4_0sub3,
 606.406 +        0, 0, 0, 0, 0,
 606.407 +        NULL,
 606.408 +        0
 606.409 +};
 606.410 +
 606.411 +static const long _huff_lengthlist_line_256x4_class0[] = {
 606.412 +         6, 7, 7,12, 6, 6, 7,12, 7, 6, 6,10,15,12,11,13,
 606.413 +         7, 7, 8,13, 7, 7, 8,12, 7, 7, 7,11,12,12,11,13,
 606.414 +        10, 9, 9,11, 9, 9, 9,10,10, 8, 8,12,14,12,12,14,
 606.415 +        11,11,12,14,11,12,11,15,15,12,13,15,15,15,15,15,
 606.416 +         6, 6, 7,10, 6, 6, 6,11, 7, 6, 6, 9,14,12,11,13,
 606.417 +         7, 7, 7,10, 6, 6, 7, 9, 7, 7, 6,10,13,12,10,12,
 606.418 +         9, 9, 9,11, 9, 9, 8, 9, 9, 8, 8,10,13,12,10,12,
 606.419 +        12,12,11,13,12,12,11,12,15,13,12,15,15,15,14,14,
 606.420 +         6, 6, 6, 8, 6, 6, 5, 6, 7, 7, 6, 5,11,10, 9, 8,
 606.421 +         7, 6, 6, 7, 6, 6, 5, 6, 7, 7, 6, 6,11,10, 9, 8,
 606.422 +         8, 8, 8, 9, 8, 8, 7, 8, 8, 8, 6, 7,11,10, 9, 9,
 606.423 +        14,11,10,14,14,11,10,15,13,11, 9,11,15,12,12,11,
 606.424 +        11, 9, 8, 8,10, 9, 8, 9,11,10, 9, 8,12,11,12,11,
 606.425 +        13,10, 8, 9,11,10, 8, 9,10, 9, 8, 9,10, 8,12,12,
 606.426 +        15,11,10,10,13,11,10,10, 8, 8, 7,12,10, 9,11,12,
 606.427 +        15,12,11,15,13,11,11,15,12,14,11,13,15,15,13,13,
 606.428 +};
 606.429 +
 606.430 +static const static_codebook _huff_book_line_256x4_class0 = {
 606.431 +        1, 256,
 606.432 +        (long *)_huff_lengthlist_line_256x4_class0,
 606.433 +        0, 0, 0, 0, 0,
 606.434 +        NULL,
 606.435 +        0
 606.436 +};
 606.437 +
 606.438 +static const long _huff_lengthlist_line_256x4_0sub0[] = {
 606.439 +         2, 2, 2, 2,
 606.440 +};
 606.441 +
 606.442 +static const static_codebook _huff_book_line_256x4_0sub0 = {
 606.443 +        1, 4,
 606.444 +        (long *)_huff_lengthlist_line_256x4_0sub0,
 606.445 +        0, 0, 0, 0, 0,
 606.446 +        NULL,
 606.447 +        0
 606.448 +};
 606.449 +
 606.450 +static const long _huff_lengthlist_line_256x4_0sub1[] = {
 606.451 +         0, 0, 0, 0, 2, 2, 3, 3, 3, 3,
 606.452 +};
 606.453 +
 606.454 +static const static_codebook _huff_book_line_256x4_0sub1 = {
 606.455 +        1, 10,
 606.456 +        (long *)_huff_lengthlist_line_256x4_0sub1,
 606.457 +        0, 0, 0, 0, 0,
 606.458 +        NULL,
 606.459 +        0
 606.460 +};
 606.461 +
 606.462 +static const long _huff_lengthlist_line_256x4_0sub2[] = {
 606.463 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 4, 3, 4, 3,
 606.464 +         5, 3, 5, 4, 5, 4, 6, 4, 6,
 606.465 +};
 606.466 +
 606.467 +static const static_codebook _huff_book_line_256x4_0sub2 = {
 606.468 +        1, 25,
 606.469 +        (long *)_huff_lengthlist_line_256x4_0sub2,
 606.470 +        0, 0, 0, 0, 0,
 606.471 +        NULL,
 606.472 +        0
 606.473 +};
 606.474 +
 606.475 +static const long _huff_lengthlist_line_256x4_0sub3[] = {
 606.476 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.477 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3, 5, 3, 5, 3,
 606.478 +         6, 4, 7, 4, 7, 5, 7, 6, 7, 6, 7, 8,10,13,13,13,
 606.479 +        13,13,13,13,13,13,13,13,13,13,13,12,12,12,12,12,
 606.480 +};
 606.481 +
 606.482 +static const static_codebook _huff_book_line_256x4_0sub3 = {
 606.483 +        1, 64,
 606.484 +        (long *)_huff_lengthlist_line_256x4_0sub3,
 606.485 +        0, 0, 0, 0, 0,
 606.486 +        NULL,
 606.487 +        0
 606.488 +};
 606.489 +
 606.490 +static const long _huff_lengthlist_line_128x7_class0[] = {
 606.491 +        10, 7, 8,13, 9, 6, 7,11,10, 8, 8,12,17,17,17,17,
 606.492 +         7, 5, 5, 9, 6, 4, 4, 8, 8, 5, 5, 8,16,14,13,16,
 606.493 +         7, 5, 5, 7, 6, 3, 3, 5, 8, 5, 4, 7,14,12,12,15,
 606.494 +        10, 7, 8, 9, 7, 5, 5, 6, 9, 6, 5, 5,15,12, 9,10,
 606.495 +};
 606.496 +
 606.497 +static const static_codebook _huff_book_line_128x7_class0 = {
 606.498 +        1, 64,
 606.499 +        (long *)_huff_lengthlist_line_128x7_class0,
 606.500 +        0, 0, 0, 0, 0,
 606.501 +        NULL,
 606.502 +        0
 606.503 +};
 606.504 +
 606.505 +static const long _huff_lengthlist_line_128x7_class1[] = {
 606.506 +         8,13,17,17, 8,11,17,17,11,13,17,17,17,17,17,17,
 606.507 +         6,10,16,17, 6,10,15,17, 8,10,16,17,17,17,17,17,
 606.508 +         9,13,15,17, 8,11,17,17,10,12,17,17,17,17,17,17,
 606.509 +        17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
 606.510 +         6,11,15,17, 7,10,15,17, 8,10,17,17,17,15,17,17,
 606.511 +         4, 8,13,17, 4, 7,13,17, 6, 8,15,17,16,15,17,17,
 606.512 +         6,11,15,17, 6, 9,13,17, 8,10,17,17,15,17,17,17,
 606.513 +        16,17,17,17,12,14,15,17,13,14,15,17,17,17,17,17,
 606.514 +         5,10,14,17, 5, 9,14,17, 7, 9,15,17,15,15,17,17,
 606.515 +         3, 7,12,17, 3, 6,11,17, 5, 7,13,17,12,12,17,17,
 606.516 +         5, 9,14,17, 3, 7,11,17, 5, 8,13,17,13,11,16,17,
 606.517 +        12,17,17,17, 9,14,15,17,10,11,14,17,16,14,17,17,
 606.518 +         8,12,17,17, 8,12,17,17,10,12,17,17,17,17,17,17,
 606.519 +         5,10,17,17, 5, 9,15,17, 7, 9,17,17,13,13,17,17,
 606.520 +         7,11,17,17, 6,10,15,17, 7, 9,15,17,12,11,17,17,
 606.521 +        12,15,17,17,11,14,17,17,11,10,15,17,17,16,17,17,
 606.522 +};
 606.523 +
 606.524 +static const static_codebook _huff_book_line_128x7_class1 = {
 606.525 +        1, 256,
 606.526 +        (long *)_huff_lengthlist_line_128x7_class1,
 606.527 +        0, 0, 0, 0, 0,
 606.528 +        NULL,
 606.529 +        0
 606.530 +};
 606.531 +
 606.532 +static const long _huff_lengthlist_line_128x7_0sub1[] = {
 606.533 +         0, 3, 3, 3, 3, 3, 3, 3, 3,
 606.534 +};
 606.535 +
 606.536 +static const static_codebook _huff_book_line_128x7_0sub1 = {
 606.537 +        1, 9,
 606.538 +        (long *)_huff_lengthlist_line_128x7_0sub1,
 606.539 +        0, 0, 0, 0, 0,
 606.540 +        NULL,
 606.541 +        0
 606.542 +};
 606.543 +
 606.544 +static const long _huff_lengthlist_line_128x7_0sub2[] = {
 606.545 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 4, 4, 4,
 606.546 +         5, 4, 5, 4, 5, 4, 6, 4, 6,
 606.547 +};
 606.548 +
 606.549 +static const static_codebook _huff_book_line_128x7_0sub2 = {
 606.550 +        1, 25,
 606.551 +        (long *)_huff_lengthlist_line_128x7_0sub2,
 606.552 +        0, 0, 0, 0, 0,
 606.553 +        NULL,
 606.554 +        0
 606.555 +};
 606.556 +
 606.557 +static const long _huff_lengthlist_line_128x7_0sub3[] = {
 606.558 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.559 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 3, 5, 3, 5, 4,
 606.560 +         5, 4, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
 606.561 +         7, 8, 9,11,13,13,13,13,13,13,13,13,13,13,13,13,
 606.562 +};
 606.563 +
 606.564 +static const static_codebook _huff_book_line_128x7_0sub3 = {
 606.565 +        1, 64,
 606.566 +        (long *)_huff_lengthlist_line_128x7_0sub3,
 606.567 +        0, 0, 0, 0, 0,
 606.568 +        NULL,
 606.569 +        0
 606.570 +};
 606.571 +
 606.572 +static const long _huff_lengthlist_line_128x7_1sub1[] = {
 606.573 +         0, 3, 3, 2, 3, 3, 4, 3, 4,
 606.574 +};
 606.575 +
 606.576 +static const static_codebook _huff_book_line_128x7_1sub1 = {
 606.577 +        1, 9,
 606.578 +        (long *)_huff_lengthlist_line_128x7_1sub1,
 606.579 +        0, 0, 0, 0, 0,
 606.580 +        NULL,
 606.581 +        0
 606.582 +};
 606.583 +
 606.584 +static const long _huff_lengthlist_line_128x7_1sub2[] = {
 606.585 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 3, 6, 3, 6, 3,
 606.586 +         6, 3, 7, 3, 8, 4, 9, 4, 9,
 606.587 +};
 606.588 +
 606.589 +static const static_codebook _huff_book_line_128x7_1sub2 = {
 606.590 +        1, 25,
 606.591 +        (long *)_huff_lengthlist_line_128x7_1sub2,
 606.592 +        0, 0, 0, 0, 0,
 606.593 +        NULL,
 606.594 +        0
 606.595 +};
 606.596 +
 606.597 +static const long _huff_lengthlist_line_128x7_1sub3[] = {
 606.598 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.599 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 2, 7, 3, 8, 4,
 606.600 +         9, 5, 9, 8,10,11,11,12,14,14,14,14,14,14,14,14,
 606.601 +        14,14,14,14,14,14,14,14,14,14,14,14,13,13,13,13,
 606.602 +};
 606.603 +
 606.604 +static const static_codebook _huff_book_line_128x7_1sub3 = {
 606.605 +        1, 64,
 606.606 +        (long *)_huff_lengthlist_line_128x7_1sub3,
 606.607 +        0, 0, 0, 0, 0,
 606.608 +        NULL,
 606.609 +        0
 606.610 +};
 606.611 +
 606.612 +static const long _huff_lengthlist_line_128x11_class1[] = {
 606.613 +         1, 6, 3, 7, 2, 4, 5, 7,
 606.614 +};
 606.615 +
 606.616 +static const static_codebook _huff_book_line_128x11_class1 = {
 606.617 +        1, 8,
 606.618 +        (long *)_huff_lengthlist_line_128x11_class1,
 606.619 +        0, 0, 0, 0, 0,
 606.620 +        NULL,
 606.621 +        0
 606.622 +};
 606.623 +
 606.624 +static const long _huff_lengthlist_line_128x11_class2[] = {
 606.625 +         1, 6,12,16, 4,12,15,16, 9,15,16,16,16,16,16,16,
 606.626 +         2, 5,11,16, 5,11,13,16, 9,13,16,16,16,16,16,16,
 606.627 +         4, 8,12,16, 5, 9,12,16, 9,13,15,16,16,16,16,16,
 606.628 +        15,16,16,16,11,14,13,16,12,15,16,16,16,16,16,15,
 606.629 +};
 606.630 +
 606.631 +static const static_codebook _huff_book_line_128x11_class2 = {
 606.632 +        1, 64,
 606.633 +        (long *)_huff_lengthlist_line_128x11_class2,
 606.634 +        0, 0, 0, 0, 0,
 606.635 +        NULL,
 606.636 +        0
 606.637 +};
 606.638 +
 606.639 +static const long _huff_lengthlist_line_128x11_class3[] = {
 606.640 +         7, 6, 9,17, 7, 6, 8,17,12, 9,11,16,16,16,16,16,
 606.641 +         5, 4, 7,16, 5, 3, 6,14, 9, 6, 8,15,16,16,16,16,
 606.642 +         5, 4, 6,13, 3, 2, 4,11, 7, 4, 6,13,16,11,10,14,
 606.643 +        12,12,12,16, 9, 7,10,15,12, 9,11,16,16,15,15,16,
 606.644 +};
 606.645 +
 606.646 +static const static_codebook _huff_book_line_128x11_class3 = {
 606.647 +        1, 64,
 606.648 +        (long *)_huff_lengthlist_line_128x11_class3,
 606.649 +        0, 0, 0, 0, 0,
 606.650 +        NULL,
 606.651 +        0
 606.652 +};
 606.653 +
 606.654 +static const long _huff_lengthlist_line_128x11_0sub0[] = {
 606.655 +         5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
 606.656 +         6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 6, 6, 6, 7, 6,
 606.657 +         7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 8, 6, 8, 6, 8, 7,
 606.658 +         8, 7, 8, 7, 8, 7, 9, 7, 9, 8, 9, 8, 9, 8,10, 8,
 606.659 +        10, 9,10, 9,10, 9,11, 9,11, 9,10,10,11,10,11,10,
 606.660 +        11,11,11,11,11,11,12,13,14,14,14,15,15,16,16,16,
 606.661 +        17,15,16,15,16,16,17,17,16,17,17,17,17,17,17,17,
 606.662 +        17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
 606.663 +};
 606.664 +
 606.665 +static const static_codebook _huff_book_line_128x11_0sub0 = {
 606.666 +        1, 128,
 606.667 +        (long *)_huff_lengthlist_line_128x11_0sub0,
 606.668 +        0, 0, 0, 0, 0,
 606.669 +        NULL,
 606.670 +        0
 606.671 +};
 606.672 +
 606.673 +static const long _huff_lengthlist_line_128x11_1sub0[] = {
 606.674 +         2, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5,
 606.675 +         6, 5, 6, 5, 6, 5, 7, 6, 7, 6, 7, 6, 8, 6, 8, 6,
 606.676 +};
 606.677 +
 606.678 +static const static_codebook _huff_book_line_128x11_1sub0 = {
 606.679 +        1, 32,
 606.680 +        (long *)_huff_lengthlist_line_128x11_1sub0,
 606.681 +        0, 0, 0, 0, 0,
 606.682 +        NULL,
 606.683 +        0
 606.684 +};
 606.685 +
 606.686 +static const long _huff_lengthlist_line_128x11_1sub1[] = {
 606.687 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.688 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.689 +         5, 3, 5, 3, 6, 4, 6, 4, 7, 4, 7, 4, 7, 4, 8, 4,
 606.690 +         8, 4, 9, 5, 9, 5, 9, 5, 9, 6,10, 6,10, 6,11, 7,
 606.691 +        10, 7,10, 8,11, 9,11, 9,11,10,11,11,12,11,11,12,
 606.692 +        15,15,12,14,11,14,12,14,11,14,13,14,12,14,11,14,
 606.693 +        11,14,12,14,11,14,11,14,13,13,14,14,14,14,14,14,
 606.694 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
 606.695 +};
 606.696 +
 606.697 +static const static_codebook _huff_book_line_128x11_1sub1 = {
 606.698 +        1, 128,
 606.699 +        (long *)_huff_lengthlist_line_128x11_1sub1,
 606.700 +        0, 0, 0, 0, 0,
 606.701 +        NULL,
 606.702 +        0
 606.703 +};
 606.704 +
 606.705 +static const long _huff_lengthlist_line_128x11_2sub1[] = {
 606.706 +         0, 4, 5, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 4, 4,
 606.707 +         5, 5,
 606.708 +};
 606.709 +
 606.710 +static const static_codebook _huff_book_line_128x11_2sub1 = {
 606.711 +        1, 18,
 606.712 +        (long *)_huff_lengthlist_line_128x11_2sub1,
 606.713 +        0, 0, 0, 0, 0,
 606.714 +        NULL,
 606.715 +        0
 606.716 +};
 606.717 +
 606.718 +static const long _huff_lengthlist_line_128x11_2sub2[] = {
 606.719 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.720 +         0, 0, 3, 3, 3, 4, 4, 4, 4, 5, 4, 5, 4, 6, 5, 7,
 606.721 +         5, 7, 6, 8, 6, 8, 6, 9, 7, 9, 7,10, 7, 9, 8,11,
 606.722 +         8,11,
 606.723 +};
 606.724 +
 606.725 +static const static_codebook _huff_book_line_128x11_2sub2 = {
 606.726 +        1, 50,
 606.727 +        (long *)_huff_lengthlist_line_128x11_2sub2,
 606.728 +        0, 0, 0, 0, 0,
 606.729 +        NULL,
 606.730 +        0
 606.731 +};
 606.732 +
 606.733 +static const long _huff_lengthlist_line_128x11_2sub3[] = {
 606.734 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.735 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.736 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.737 +         0, 0, 4, 8, 3, 8, 4, 8, 4, 8, 6, 8, 5, 8, 4, 8,
 606.738 +         4, 8, 6, 8, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 606.739 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 606.740 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 606.741 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 606.742 +};
 606.743 +
 606.744 +static const static_codebook _huff_book_line_128x11_2sub3 = {
 606.745 +        1, 128,
 606.746 +        (long *)_huff_lengthlist_line_128x11_2sub3,
 606.747 +        0, 0, 0, 0, 0,
 606.748 +        NULL,
 606.749 +        0
 606.750 +};
 606.751 +
 606.752 +static const long _huff_lengthlist_line_128x11_3sub1[] = {
 606.753 +         0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4,
 606.754 +         5, 4,
 606.755 +};
 606.756 +
 606.757 +static const static_codebook _huff_book_line_128x11_3sub1 = {
 606.758 +        1, 18,
 606.759 +        (long *)_huff_lengthlist_line_128x11_3sub1,
 606.760 +        0, 0, 0, 0, 0,
 606.761 +        NULL,
 606.762 +        0
 606.763 +};
 606.764 +
 606.765 +static const long _huff_lengthlist_line_128x11_3sub2[] = {
 606.766 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.767 +         0, 0, 5, 3, 5, 4, 6, 4, 6, 4, 7, 4, 7, 4, 8, 4,
 606.768 +         8, 4, 9, 4, 9, 4,10, 4,10, 5,10, 5,11, 5,12, 6,
 606.769 +        12, 6,
 606.770 +};
 606.771 +
 606.772 +static const static_codebook _huff_book_line_128x11_3sub2 = {
 606.773 +        1, 50,
 606.774 +        (long *)_huff_lengthlist_line_128x11_3sub2,
 606.775 +        0, 0, 0, 0, 0,
 606.776 +        NULL,
 606.777 +        0
 606.778 +};
 606.779 +
 606.780 +static const long _huff_lengthlist_line_128x11_3sub3[] = {
 606.781 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.782 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.783 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.784 +         0, 0, 7, 1, 6, 3, 7, 3, 8, 4, 8, 5, 8, 8, 8, 9,
 606.785 +         7, 8, 8, 7, 7, 7, 8, 9,10, 9, 9,10,10,10,10,10,
 606.786 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 606.787 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 606.788 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9,
 606.789 +};
 606.790 +
 606.791 +static const static_codebook _huff_book_line_128x11_3sub3 = {
 606.792 +        1, 128,
 606.793 +        (long *)_huff_lengthlist_line_128x11_3sub3,
 606.794 +        0, 0, 0, 0, 0,
 606.795 +        NULL,
 606.796 +        0
 606.797 +};
 606.798 +
 606.799 +static const long _huff_lengthlist_line_128x17_class1[] = {
 606.800 +         1, 3, 4, 7, 2, 5, 6, 7,
 606.801 +};
 606.802 +
 606.803 +static const static_codebook _huff_book_line_128x17_class1 = {
 606.804 +        1, 8,
 606.805 +        (long *)_huff_lengthlist_line_128x17_class1,
 606.806 +        0, 0, 0, 0, 0,
 606.807 +        NULL,
 606.808 +        0
 606.809 +};
 606.810 +
 606.811 +static const long _huff_lengthlist_line_128x17_class2[] = {
 606.812 +         1, 4,10,19, 3, 8,13,19, 7,12,19,19,19,19,19,19,
 606.813 +         2, 6,11,19, 8,13,19,19, 9,11,19,19,19,19,19,19,
 606.814 +         6, 7,13,19, 9,13,19,19,10,13,18,18,18,18,18,18,
 606.815 +        18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
 606.816 +};
 606.817 +
 606.818 +static const static_codebook _huff_book_line_128x17_class2 = {
 606.819 +        1, 64,
 606.820 +        (long *)_huff_lengthlist_line_128x17_class2,
 606.821 +        0, 0, 0, 0, 0,
 606.822 +        NULL,
 606.823 +        0
 606.824 +};
 606.825 +
 606.826 +static const long _huff_lengthlist_line_128x17_class3[] = {
 606.827 +         3, 6,10,17, 4, 8,11,20, 8,10,11,20,20,20,20,20,
 606.828 +         2, 4, 8,18, 4, 6, 8,17, 7, 8,10,20,20,17,20,20,
 606.829 +         3, 5, 8,17, 3, 4, 6,17, 8, 8,10,17,17,12,16,20,
 606.830 +        13,13,15,20,10,10,12,20,15,14,15,20,20,20,19,19,
 606.831 +};
 606.832 +
 606.833 +static const static_codebook _huff_book_line_128x17_class3 = {
 606.834 +        1, 64,
 606.835 +        (long *)_huff_lengthlist_line_128x17_class3,
 606.836 +        0, 0, 0, 0, 0,
 606.837 +        NULL,
 606.838 +        0
 606.839 +};
 606.840 +
 606.841 +static const long _huff_lengthlist_line_128x17_0sub0[] = {
 606.842 +         5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
 606.843 +         7, 5, 7, 5, 7, 5, 7, 5, 7, 5, 7, 5, 8, 5, 8, 5,
 606.844 +         8, 5, 8, 5, 8, 6, 8, 6, 8, 6, 9, 6, 9, 6, 9, 6,
 606.845 +         9, 6, 9, 7, 9, 7, 9, 7, 9, 7,10, 7,10, 8,10, 8,
 606.846 +        10, 8,10, 8,10, 8,11, 8,11, 8,11, 8,11, 8,11, 9,
 606.847 +        12, 9,12, 9,12, 9,12, 9,12,10,12,10,13,11,13,11,
 606.848 +        14,12,14,13,15,14,16,14,17,15,18,16,20,20,20,20,
 606.849 +        20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
 606.850 +};
 606.851 +
 606.852 +static const static_codebook _huff_book_line_128x17_0sub0 = {
 606.853 +        1, 128,
 606.854 +        (long *)_huff_lengthlist_line_128x17_0sub0,
 606.855 +        0, 0, 0, 0, 0,
 606.856 +        NULL,
 606.857 +        0
 606.858 +};
 606.859 +
 606.860 +static const long _huff_lengthlist_line_128x17_1sub0[] = {
 606.861 +         2, 5, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 6, 5,
 606.862 +         6, 5, 6, 5, 7, 6, 7, 6, 7, 6, 8, 6, 9, 7, 9, 7,
 606.863 +};
 606.864 +
 606.865 +static const static_codebook _huff_book_line_128x17_1sub0 = {
 606.866 +        1, 32,
 606.867 +        (long *)_huff_lengthlist_line_128x17_1sub0,
 606.868 +        0, 0, 0, 0, 0,
 606.869 +        NULL,
 606.870 +        0
 606.871 +};
 606.872 +
 606.873 +static const long _huff_lengthlist_line_128x17_1sub1[] = {
 606.874 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.875 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.876 +         4, 3, 5, 3, 5, 3, 6, 3, 6, 4, 6, 4, 7, 4, 7, 5,
 606.877 +         8, 5, 8, 6, 9, 7, 9, 7, 9, 8,10, 9,10, 9,11,10,
 606.878 +        11,11,11,11,11,11,12,12,12,13,12,13,12,14,12,15,
 606.879 +        12,14,12,16,13,17,13,17,14,17,14,16,13,17,14,17,
 606.880 +        14,17,15,17,15,15,16,17,17,17,17,17,17,17,17,17,
 606.881 +        17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,
 606.882 +};
 606.883 +
 606.884 +static const static_codebook _huff_book_line_128x17_1sub1 = {
 606.885 +        1, 128,
 606.886 +        (long *)_huff_lengthlist_line_128x17_1sub1,
 606.887 +        0, 0, 0, 0, 0,
 606.888 +        NULL,
 606.889 +        0
 606.890 +};
 606.891 +
 606.892 +static const long _huff_lengthlist_line_128x17_2sub1[] = {
 606.893 +         0, 4, 5, 4, 6, 4, 8, 3, 9, 3, 9, 2, 9, 3, 8, 4,
 606.894 +         9, 4,
 606.895 +};
 606.896 +
 606.897 +static const static_codebook _huff_book_line_128x17_2sub1 = {
 606.898 +        1, 18,
 606.899 +        (long *)_huff_lengthlist_line_128x17_2sub1,
 606.900 +        0, 0, 0, 0, 0,
 606.901 +        NULL,
 606.902 +        0
 606.903 +};
 606.904 +
 606.905 +static const long _huff_lengthlist_line_128x17_2sub2[] = {
 606.906 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.907 +         0, 0, 5, 1, 5, 3, 5, 3, 5, 4, 7, 5,10, 7,10, 7,
 606.908 +        12,10,14,10,14, 9,14,11,14,14,14,13,13,13,13,13,
 606.909 +        13,13,
 606.910 +};
 606.911 +
 606.912 +static const static_codebook _huff_book_line_128x17_2sub2 = {
 606.913 +        1, 50,
 606.914 +        (long *)_huff_lengthlist_line_128x17_2sub2,
 606.915 +        0, 0, 0, 0, 0,
 606.916 +        NULL,
 606.917 +        0
 606.918 +};
 606.919 +
 606.920 +static const long _huff_lengthlist_line_128x17_2sub3[] = {
 606.921 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.922 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.923 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.924 +         0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 606.925 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6,
 606.926 +         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 606.927 +         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 606.928 +         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 606.929 +};
 606.930 +
 606.931 +static const static_codebook _huff_book_line_128x17_2sub3 = {
 606.932 +        1, 128,
 606.933 +        (long *)_huff_lengthlist_line_128x17_2sub3,
 606.934 +        0, 0, 0, 0, 0,
 606.935 +        NULL,
 606.936 +        0
 606.937 +};
 606.938 +
 606.939 +static const long _huff_lengthlist_line_128x17_3sub1[] = {
 606.940 +         0, 4, 4, 4, 4, 4, 4, 4, 5, 3, 5, 3, 5, 4, 6, 4,
 606.941 +         6, 4,
 606.942 +};
 606.943 +
 606.944 +static const static_codebook _huff_book_line_128x17_3sub1 = {
 606.945 +        1, 18,
 606.946 +        (long *)_huff_lengthlist_line_128x17_3sub1,
 606.947 +        0, 0, 0, 0, 0,
 606.948 +        NULL,
 606.949 +        0
 606.950 +};
 606.951 +
 606.952 +static const long _huff_lengthlist_line_128x17_3sub2[] = {
 606.953 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.954 +         0, 0, 5, 3, 6, 3, 6, 4, 7, 4, 7, 4, 7, 4, 8, 4,
 606.955 +         8, 4, 8, 4, 8, 4, 9, 4, 9, 5,10, 5,10, 7,10, 8,
 606.956 +        10, 8,
 606.957 +};
 606.958 +
 606.959 +static const static_codebook _huff_book_line_128x17_3sub2 = {
 606.960 +        1, 50,
 606.961 +        (long *)_huff_lengthlist_line_128x17_3sub2,
 606.962 +        0, 0, 0, 0, 0,
 606.963 +        NULL,
 606.964 +        0
 606.965 +};
 606.966 +
 606.967 +static const long _huff_lengthlist_line_128x17_3sub3[] = {
 606.968 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.969 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.970 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 606.971 +         0, 0, 3, 2, 4, 3, 4, 4, 4, 5, 4, 7, 5, 8, 5,11,
 606.972 +         6,10, 6,12, 7,12, 7,12, 8,12, 8,12,10,12,12,12,
 606.973 +        12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
 606.974 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
 606.975 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
 606.976 +};
 606.977 +
 606.978 +static const static_codebook _huff_book_line_128x17_3sub3 = {
 606.979 +        1, 128,
 606.980 +        (long *)_huff_lengthlist_line_128x17_3sub3,
 606.981 +        0, 0, 0, 0, 0,
 606.982 +        NULL,
 606.983 +        0
 606.984 +};
 606.985 +
 606.986 +static const long _huff_lengthlist_line_1024x27_class1[] = {
 606.987 +         2,10, 8,14, 7,12,11,14, 1, 5, 3, 7, 4, 9, 7,13,
 606.988 +};
 606.989 +
 606.990 +static const static_codebook _huff_book_line_1024x27_class1 = {
 606.991 +        1, 16,
 606.992 +        (long *)_huff_lengthlist_line_1024x27_class1,
 606.993 +        0, 0, 0, 0, 0,
 606.994 +        NULL,
 606.995 +        0
 606.996 +};
 606.997 +
 606.998 +static const long _huff_lengthlist_line_1024x27_class2[] = {
 606.999 +         1, 4, 2, 6, 3, 7, 5, 7,
606.1000 +};
606.1001 +
606.1002 +static const static_codebook _huff_book_line_1024x27_class2 = {
606.1003 +        1, 8,
606.1004 +        (long *)_huff_lengthlist_line_1024x27_class2,
606.1005 +        0, 0, 0, 0, 0,
606.1006 +        NULL,
606.1007 +        0
606.1008 +};
606.1009 +
606.1010 +static const long _huff_lengthlist_line_1024x27_class3[] = {
606.1011 +         1, 5, 7,21, 5, 8, 9,21,10, 9,12,20,20,16,20,20,
606.1012 +         4, 8, 9,20, 6, 8, 9,20,11,11,13,20,20,15,17,20,
606.1013 +         9,11,14,20, 8,10,15,20,11,13,15,20,20,20,20,20,
606.1014 +        20,20,20,20,13,20,20,20,18,18,20,20,20,20,20,20,
606.1015 +         3, 6, 8,20, 6, 7, 9,20,10, 9,12,20,20,20,20,20,
606.1016 +         5, 7, 9,20, 6, 6, 9,20,10, 9,12,20,20,20,20,20,
606.1017 +         8,10,13,20, 8, 9,12,20,11,10,12,20,20,20,20,20,
606.1018 +        18,20,20,20,15,17,18,20,18,17,18,20,20,20,20,20,
606.1019 +         7,10,12,20, 8, 9,11,20,14,13,14,20,20,20,20,20,
606.1020 +         6, 9,12,20, 7, 8,11,20,12,11,13,20,20,20,20,20,
606.1021 +         9,11,15,20, 8,10,14,20,12,11,14,20,20,20,20,20,
606.1022 +        20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
606.1023 +        11,16,18,20,15,15,17,20,20,17,20,20,20,20,20,20,
606.1024 +         9,14,16,20,12,12,15,20,17,15,18,20,20,20,20,20,
606.1025 +        16,19,18,20,15,16,20,20,17,17,20,20,20,20,20,20,
606.1026 +        20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
606.1027 +};
606.1028 +
606.1029 +static const static_codebook _huff_book_line_1024x27_class3 = {
606.1030 +        1, 256,
606.1031 +        (long *)_huff_lengthlist_line_1024x27_class3,
606.1032 +        0, 0, 0, 0, 0,
606.1033 +        NULL,
606.1034 +        0
606.1035 +};
606.1036 +
606.1037 +static const long _huff_lengthlist_line_1024x27_class4[] = {
606.1038 +         2, 3, 7,13, 4, 4, 7,15, 8, 6, 9,17,21,16,15,21,
606.1039 +         2, 5, 7,11, 5, 5, 7,14, 9, 7,10,16,17,15,16,21,
606.1040 +         4, 7,10,17, 7, 7, 9,15,11, 9,11,16,21,18,15,21,
606.1041 +        18,21,21,21,15,17,17,19,21,19,18,20,21,21,21,20,
606.1042 +};
606.1043 +
606.1044 +static const static_codebook _huff_book_line_1024x27_class4 = {
606.1045 +        1, 64,
606.1046 +        (long *)_huff_lengthlist_line_1024x27_class4,
606.1047 +        0, 0, 0, 0, 0,
606.1048 +        NULL,
606.1049 +        0
606.1050 +};
606.1051 +
606.1052 +static const long _huff_lengthlist_line_1024x27_0sub0[] = {
606.1053 +         5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
606.1054 +         6, 5, 6, 5, 6, 5, 6, 5, 7, 5, 7, 5, 7, 5, 7, 5,
606.1055 +         8, 6, 8, 6, 8, 6, 9, 6, 9, 6,10, 6,10, 6,11, 6,
606.1056 +        11, 7,11, 7,12, 7,12, 7,12, 7,12, 7,12, 7,12, 7,
606.1057 +        12, 7,12, 8,13, 8,12, 8,12, 8,13, 8,13, 9,13, 9,
606.1058 +        13, 9,13, 9,12,10,12,10,13,10,14,11,14,12,14,13,
606.1059 +        14,13,14,14,15,16,15,15,15,14,15,17,21,22,22,21,
606.1060 +        22,22,22,22,22,22,21,21,21,21,21,21,21,21,21,21,
606.1061 +};
606.1062 +
606.1063 +static const static_codebook _huff_book_line_1024x27_0sub0 = {
606.1064 +        1, 128,
606.1065 +        (long *)_huff_lengthlist_line_1024x27_0sub0,
606.1066 +        0, 0, 0, 0, 0,
606.1067 +        NULL,
606.1068 +        0
606.1069 +};
606.1070 +
606.1071 +static const long _huff_lengthlist_line_1024x27_1sub0[] = {
606.1072 +         2, 5, 5, 4, 5, 4, 5, 4, 5, 4, 6, 5, 6, 5, 6, 5,
606.1073 +         6, 5, 7, 5, 7, 6, 8, 6, 8, 6, 8, 6, 9, 6, 9, 6,
606.1074 +};
606.1075 +
606.1076 +static const static_codebook _huff_book_line_1024x27_1sub0 = {
606.1077 +        1, 32,
606.1078 +        (long *)_huff_lengthlist_line_1024x27_1sub0,
606.1079 +        0, 0, 0, 0, 0,
606.1080 +        NULL,
606.1081 +        0
606.1082 +};
606.1083 +
606.1084 +static const long _huff_lengthlist_line_1024x27_1sub1[] = {
606.1085 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1086 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1087 +         8, 5, 8, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4,
606.1088 +         9, 4, 9, 4, 9, 4, 8, 4, 8, 4, 9, 5, 9, 5, 9, 5,
606.1089 +         9, 5, 9, 6,10, 6,10, 7,10, 8,11, 9,11,11,12,13,
606.1090 +        12,14,13,15,13,15,14,16,14,17,15,17,15,15,16,16,
606.1091 +        15,16,16,16,15,18,16,15,17,17,19,19,19,19,19,19,
606.1092 +        19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
606.1093 +};
606.1094 +
606.1095 +static const static_codebook _huff_book_line_1024x27_1sub1 = {
606.1096 +        1, 128,
606.1097 +        (long *)_huff_lengthlist_line_1024x27_1sub1,
606.1098 +        0, 0, 0, 0, 0,
606.1099 +        NULL,
606.1100 +        0
606.1101 +};
606.1102 +
606.1103 +static const long _huff_lengthlist_line_1024x27_2sub0[] = {
606.1104 +         1, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5,
606.1105 +         6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 9, 8,10, 9,10, 9,
606.1106 +};
606.1107 +
606.1108 +static const static_codebook _huff_book_line_1024x27_2sub0 = {
606.1109 +        1, 32,
606.1110 +        (long *)_huff_lengthlist_line_1024x27_2sub0,
606.1111 +        0, 0, 0, 0, 0,
606.1112 +        NULL,
606.1113 +        0
606.1114 +};
606.1115 +
606.1116 +static const long _huff_lengthlist_line_1024x27_2sub1[] = {
606.1117 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1118 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1119 +         4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 5, 5, 6, 5, 6, 5,
606.1120 +         7, 5, 7, 6, 7, 6, 8, 7, 8, 7, 8, 7, 9, 8, 9, 9,
606.1121 +         9, 9,10,10,10,11, 9,12, 9,12, 9,15,10,14, 9,13,
606.1122 +        10,13,10,12,10,12,10,13,10,12,11,13,11,14,12,13,
606.1123 +        13,14,14,13,14,15,14,16,13,13,14,16,16,16,16,16,
606.1124 +        16,16,16,16,16,16,16,16,16,16,16,16,16,16,15,15,
606.1125 +};
606.1126 +
606.1127 +static const static_codebook _huff_book_line_1024x27_2sub1 = {
606.1128 +        1, 128,
606.1129 +        (long *)_huff_lengthlist_line_1024x27_2sub1,
606.1130 +        0, 0, 0, 0, 0,
606.1131 +        NULL,
606.1132 +        0
606.1133 +};
606.1134 +
606.1135 +static const long _huff_lengthlist_line_1024x27_3sub1[] = {
606.1136 +         0, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 4, 4, 4, 5,
606.1137 +         5, 5,
606.1138 +};
606.1139 +
606.1140 +static const static_codebook _huff_book_line_1024x27_3sub1 = {
606.1141 +        1, 18,
606.1142 +        (long *)_huff_lengthlist_line_1024x27_3sub1,
606.1143 +        0, 0, 0, 0, 0,
606.1144 +        NULL,
606.1145 +        0
606.1146 +};
606.1147 +
606.1148 +static const long _huff_lengthlist_line_1024x27_3sub2[] = {
606.1149 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1150 +         0, 0, 3, 3, 4, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
606.1151 +         5, 7, 5, 8, 6, 8, 6, 9, 7,10, 7,10, 8,10, 8,11,
606.1152 +         9,11,
606.1153 +};
606.1154 +
606.1155 +static const static_codebook _huff_book_line_1024x27_3sub2 = {
606.1156 +        1, 50,
606.1157 +        (long *)_huff_lengthlist_line_1024x27_3sub2,
606.1158 +        0, 0, 0, 0, 0,
606.1159 +        NULL,
606.1160 +        0
606.1161 +};
606.1162 +
606.1163 +static const long _huff_lengthlist_line_1024x27_3sub3[] = {
606.1164 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1165 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1166 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1167 +         0, 0, 3, 7, 3, 8, 3,10, 3, 8, 3, 9, 3, 8, 4, 9,
606.1168 +         4, 9, 5, 9, 6,10, 6, 9, 7,11, 7,12, 9,13,10,13,
606.1169 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
606.1170 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
606.1171 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
606.1172 +};
606.1173 +
606.1174 +static const static_codebook _huff_book_line_1024x27_3sub3 = {
606.1175 +        1, 128,
606.1176 +        (long *)_huff_lengthlist_line_1024x27_3sub3,
606.1177 +        0, 0, 0, 0, 0,
606.1178 +        NULL,
606.1179 +        0
606.1180 +};
606.1181 +
606.1182 +static const long _huff_lengthlist_line_1024x27_4sub1[] = {
606.1183 +         0, 4, 5, 4, 5, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4,
606.1184 +         5, 4,
606.1185 +};
606.1186 +
606.1187 +static const static_codebook _huff_book_line_1024x27_4sub1 = {
606.1188 +        1, 18,
606.1189 +        (long *)_huff_lengthlist_line_1024x27_4sub1,
606.1190 +        0, 0, 0, 0, 0,
606.1191 +        NULL,
606.1192 +        0
606.1193 +};
606.1194 +
606.1195 +static const long _huff_lengthlist_line_1024x27_4sub2[] = {
606.1196 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1197 +         0, 0, 4, 2, 4, 2, 5, 3, 5, 4, 6, 6, 6, 7, 7, 8,
606.1198 +         7, 8, 7, 8, 7, 9, 8, 9, 8, 9, 8,10, 8,11, 9,12,
606.1199 +         9,12,
606.1200 +};
606.1201 +
606.1202 +static const static_codebook _huff_book_line_1024x27_4sub2 = {
606.1203 +        1, 50,
606.1204 +        (long *)_huff_lengthlist_line_1024x27_4sub2,
606.1205 +        0, 0, 0, 0, 0,
606.1206 +        NULL,
606.1207 +        0
606.1208 +};
606.1209 +
606.1210 +static const long _huff_lengthlist_line_1024x27_4sub3[] = {
606.1211 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1212 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1213 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1214 +         0, 0, 2, 5, 2, 6, 3, 6, 4, 7, 4, 7, 5, 9, 5,11,
606.1215 +         6,11, 6,11, 7,11, 6,11, 6,11, 9,11, 8,11,11,11,
606.1216 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
606.1217 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
606.1218 +        11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,
606.1219 +};
606.1220 +
606.1221 +static const static_codebook _huff_book_line_1024x27_4sub3 = {
606.1222 +        1, 128,
606.1223 +        (long *)_huff_lengthlist_line_1024x27_4sub3,
606.1224 +        0, 0, 0, 0, 0,
606.1225 +        NULL,
606.1226 +        0
606.1227 +};
606.1228 +
606.1229 +static const long _huff_lengthlist_line_2048x27_class1[] = {
606.1230 +         2, 6, 8, 9, 7,11,13,13, 1, 3, 5, 5, 6, 6,12,10,
606.1231 +};
606.1232 +
606.1233 +static const static_codebook _huff_book_line_2048x27_class1 = {
606.1234 +        1, 16,
606.1235 +        (long *)_huff_lengthlist_line_2048x27_class1,
606.1236 +        0, 0, 0, 0, 0,
606.1237 +        NULL,
606.1238 +        0
606.1239 +};
606.1240 +
606.1241 +static const long _huff_lengthlist_line_2048x27_class2[] = {
606.1242 +         1, 2, 3, 6, 4, 7, 5, 7,
606.1243 +};
606.1244 +
606.1245 +static const static_codebook _huff_book_line_2048x27_class2 = {
606.1246 +        1, 8,
606.1247 +        (long *)_huff_lengthlist_line_2048x27_class2,
606.1248 +        0, 0, 0, 0, 0,
606.1249 +        NULL,
606.1250 +        0
606.1251 +};
606.1252 +
606.1253 +static const long _huff_lengthlist_line_2048x27_class3[] = {
606.1254 +         3, 3, 6,16, 5, 5, 7,16, 9, 8,11,16,16,16,16,16,
606.1255 +         5, 5, 8,16, 5, 5, 7,16, 8, 7, 9,16,16,16,16,16,
606.1256 +         9, 9,12,16, 6, 8,11,16, 9,10,11,16,16,16,16,16,
606.1257 +        16,16,16,16,13,16,16,16,15,16,16,16,16,16,16,16,
606.1258 +         5, 4, 7,16, 6, 5, 8,16, 9, 8,10,16,16,16,16,16,
606.1259 +         5, 5, 7,15, 5, 4, 6,15, 7, 6, 8,16,16,16,16,16,
606.1260 +         9, 9,11,15, 7, 7, 9,16, 8, 8, 9,16,16,16,16,16,
606.1261 +        16,16,16,16,15,15,15,16,15,15,14,16,16,16,16,16,
606.1262 +         8, 8,11,16, 8, 9,10,16,11,10,14,16,16,16,16,16,
606.1263 +         6, 8,10,16, 6, 7,10,16, 8, 8,11,16,14,16,16,16,
606.1264 +        10,11,14,16, 9, 9,11,16,10,10,11,16,16,16,16,16,
606.1265 +        16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
606.1266 +        16,16,16,16,15,16,16,16,16,16,16,16,16,16,16,16,
606.1267 +        12,16,15,16,12,14,16,16,16,16,16,16,16,16,16,16,
606.1268 +        16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
606.1269 +        16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
606.1270 +};
606.1271 +
606.1272 +static const static_codebook _huff_book_line_2048x27_class3 = {
606.1273 +        1, 256,
606.1274 +        (long *)_huff_lengthlist_line_2048x27_class3,
606.1275 +        0, 0, 0, 0, 0,
606.1276 +        NULL,
606.1277 +        0
606.1278 +};
606.1279 +
606.1280 +static const long _huff_lengthlist_line_2048x27_class4[] = {
606.1281 +         2, 4, 7,13, 4, 5, 7,15, 8, 7,10,16,16,14,16,16,
606.1282 +         2, 4, 7,16, 3, 4, 7,14, 8, 8,10,16,16,16,15,16,
606.1283 +         6, 8,11,16, 7, 7, 9,16,11, 9,13,16,16,16,15,16,
606.1284 +        16,16,16,16,14,16,16,16,16,16,16,16,16,16,16,16,
606.1285 +};
606.1286 +
606.1287 +static const static_codebook _huff_book_line_2048x27_class4 = {
606.1288 +        1, 64,
606.1289 +        (long *)_huff_lengthlist_line_2048x27_class4,
606.1290 +        0, 0, 0, 0, 0,
606.1291 +        NULL,
606.1292 +        0
606.1293 +};
606.1294 +
606.1295 +static const long _huff_lengthlist_line_2048x27_0sub0[] = {
606.1296 +         5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
606.1297 +         6, 5, 7, 5, 7, 5, 7, 5, 8, 5, 8, 5, 8, 5, 9, 5,
606.1298 +         9, 6,10, 6,10, 6,11, 6,11, 6,11, 6,11, 6,11, 6,
606.1299 +        11, 6,11, 6,12, 7,11, 7,11, 7,11, 7,11, 7,10, 7,
606.1300 +        11, 7,11, 7,12, 7,11, 8,11, 8,11, 8,11, 8,13, 8,
606.1301 +        12, 9,11, 9,11, 9,11,10,12,10,12, 9,12,10,12,11,
606.1302 +        14,12,16,12,12,11,14,16,17,17,17,17,17,17,17,17,
606.1303 +        17,17,17,17,17,17,17,17,17,17,17,17,16,16,16,16,
606.1304 +};
606.1305 +
606.1306 +static const static_codebook _huff_book_line_2048x27_0sub0 = {
606.1307 +        1, 128,
606.1308 +        (long *)_huff_lengthlist_line_2048x27_0sub0,
606.1309 +        0, 0, 0, 0, 0,
606.1310 +        NULL,
606.1311 +        0
606.1312 +};
606.1313 +
606.1314 +static const long _huff_lengthlist_line_2048x27_1sub0[] = {
606.1315 +         4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
606.1316 +         5, 5, 6, 6, 6, 6, 6, 6, 7, 6, 7, 6, 7, 6, 7, 6,
606.1317 +};
606.1318 +
606.1319 +static const static_codebook _huff_book_line_2048x27_1sub0 = {
606.1320 +        1, 32,
606.1321 +        (long *)_huff_lengthlist_line_2048x27_1sub0,
606.1322 +        0, 0, 0, 0, 0,
606.1323 +        NULL,
606.1324 +        0
606.1325 +};
606.1326 +
606.1327 +static const long _huff_lengthlist_line_2048x27_1sub1[] = {
606.1328 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1329 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1330 +         6, 5, 7, 5, 7, 4, 7, 4, 8, 4, 8, 4, 8, 4, 8, 3,
606.1331 +         8, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 5, 9, 5, 9, 6,
606.1332 +         9, 7, 9, 8, 9, 9, 9,10, 9,11, 9,14, 9,15,10,15,
606.1333 +        10,15,10,15,10,15,11,15,10,14,12,14,11,14,13,14,
606.1334 +        13,15,15,15,12,15,15,15,13,15,13,15,13,15,15,15,
606.1335 +        15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,
606.1336 +};
606.1337 +
606.1338 +static const static_codebook _huff_book_line_2048x27_1sub1 = {
606.1339 +        1, 128,
606.1340 +        (long *)_huff_lengthlist_line_2048x27_1sub1,
606.1341 +        0, 0, 0, 0, 0,
606.1342 +        NULL,
606.1343 +        0
606.1344 +};
606.1345 +
606.1346 +static const long _huff_lengthlist_line_2048x27_2sub0[] = {
606.1347 +         2, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 6, 5,
606.1348 +         6, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
606.1349 +};
606.1350 +
606.1351 +static const static_codebook _huff_book_line_2048x27_2sub0 = {
606.1352 +        1, 32,
606.1353 +        (long *)_huff_lengthlist_line_2048x27_2sub0,
606.1354 +        0, 0, 0, 0, 0,
606.1355 +        NULL,
606.1356 +        0
606.1357 +};
606.1358 +
606.1359 +static const long _huff_lengthlist_line_2048x27_2sub1[] = {
606.1360 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1361 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1362 +         3, 4, 3, 4, 3, 4, 4, 5, 4, 5, 5, 5, 6, 6, 6, 7,
606.1363 +         6, 8, 6, 8, 6, 9, 7,10, 7,10, 7,10, 7,12, 7,12,
606.1364 +         7,12, 9,12,11,12,10,12,10,12,11,12,12,12,10,12,
606.1365 +        10,12,10,12, 9,12,11,12,12,12,12,12,11,12,11,12,
606.1366 +        12,12,12,12,12,12,12,12,10,10,12,12,12,12,12,10,
606.1367 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
606.1368 +};
606.1369 +
606.1370 +static const static_codebook _huff_book_line_2048x27_2sub1 = {
606.1371 +        1, 128,
606.1372 +        (long *)_huff_lengthlist_line_2048x27_2sub1,
606.1373 +        0, 0, 0, 0, 0,
606.1374 +        NULL,
606.1375 +        0
606.1376 +};
606.1377 +
606.1378 +static const long _huff_lengthlist_line_2048x27_3sub1[] = {
606.1379 +         0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
606.1380 +         5, 5,
606.1381 +};
606.1382 +
606.1383 +static const static_codebook _huff_book_line_2048x27_3sub1 = {
606.1384 +        1, 18,
606.1385 +        (long *)_huff_lengthlist_line_2048x27_3sub1,
606.1386 +        0, 0, 0, 0, 0,
606.1387 +        NULL,
606.1388 +        0
606.1389 +};
606.1390 +
606.1391 +static const long _huff_lengthlist_line_2048x27_3sub2[] = {
606.1392 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1393 +         0, 0, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6,
606.1394 +         6, 7, 6, 7, 6, 8, 6, 9, 7, 9, 7, 9, 9,11, 9,12,
606.1395 +        10,12,
606.1396 +};
606.1397 +
606.1398 +static const static_codebook _huff_book_line_2048x27_3sub2 = {
606.1399 +        1, 50,
606.1400 +        (long *)_huff_lengthlist_line_2048x27_3sub2,
606.1401 +        0, 0, 0, 0, 0,
606.1402 +        NULL,
606.1403 +        0
606.1404 +};
606.1405 +
606.1406 +static const long _huff_lengthlist_line_2048x27_3sub3[] = {
606.1407 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1408 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1409 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1410 +         0, 0, 3, 6, 3, 7, 3, 7, 5, 7, 7, 7, 7, 7, 6, 7,
606.1411 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
606.1412 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
606.1413 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
606.1414 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
606.1415 +};
606.1416 +
606.1417 +static const static_codebook _huff_book_line_2048x27_3sub3 = {
606.1418 +        1, 128,
606.1419 +        (long *)_huff_lengthlist_line_2048x27_3sub3,
606.1420 +        0, 0, 0, 0, 0,
606.1421 +        NULL,
606.1422 +        0
606.1423 +};
606.1424 +
606.1425 +static const long _huff_lengthlist_line_2048x27_4sub1[] = {
606.1426 +         0, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 5, 4, 5, 4,
606.1427 +         4, 5,
606.1428 +};
606.1429 +
606.1430 +static const static_codebook _huff_book_line_2048x27_4sub1 = {
606.1431 +        1, 18,
606.1432 +        (long *)_huff_lengthlist_line_2048x27_4sub1,
606.1433 +        0, 0, 0, 0, 0,
606.1434 +        NULL,
606.1435 +        0
606.1436 +};
606.1437 +
606.1438 +static const long _huff_lengthlist_line_2048x27_4sub2[] = {
606.1439 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1440 +         0, 0, 3, 2, 4, 3, 4, 4, 4, 5, 5, 6, 5, 6, 5, 7,
606.1441 +         6, 6, 6, 7, 7, 7, 8, 9, 9, 9,12,10,11,10,10,12,
606.1442 +        10,10,
606.1443 +};
606.1444 +
606.1445 +static const static_codebook _huff_book_line_2048x27_4sub2 = {
606.1446 +        1, 50,
606.1447 +        (long *)_huff_lengthlist_line_2048x27_4sub2,
606.1448 +        0, 0, 0, 0, 0,
606.1449 +        NULL,
606.1450 +        0
606.1451 +};
606.1452 +
606.1453 +static const long _huff_lengthlist_line_2048x27_4sub3[] = {
606.1454 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1455 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1456 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1457 +         0, 0, 3, 6, 5, 7, 5, 7, 7, 7, 7, 7, 5, 7, 5, 7,
606.1458 +         5, 7, 5, 7, 7, 7, 7, 7, 4, 7, 7, 7, 7, 7, 7, 7,
606.1459 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
606.1460 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
606.1461 +         7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6,
606.1462 +};
606.1463 +
606.1464 +static const static_codebook _huff_book_line_2048x27_4sub3 = {
606.1465 +        1, 128,
606.1466 +        (long *)_huff_lengthlist_line_2048x27_4sub3,
606.1467 +        0, 0, 0, 0, 0,
606.1468 +        NULL,
606.1469 +        0
606.1470 +};
606.1471 +
606.1472 +static const long _huff_lengthlist_line_256x4low_class0[] = {
606.1473 +         4, 5, 6,11, 5, 5, 6,10, 7, 7, 6, 6,14,13, 9, 9,
606.1474 +         6, 6, 6,10, 6, 6, 6, 9, 8, 7, 7, 9,14,12, 8,11,
606.1475 +         8, 7, 7,11, 8, 8, 7,11, 9, 9, 7, 9,13,11, 9,13,
606.1476 +        19,19,18,19,15,16,16,19,11,11,10,13,10,10, 9,15,
606.1477 +         5, 5, 6,13, 6, 6, 6,11, 8, 7, 6, 7,14,11,10,11,
606.1478 +         6, 6, 6,12, 7, 6, 6,11, 8, 7, 7,11,13,11, 9,11,
606.1479 +         9, 7, 6,12, 8, 7, 6,12, 9, 8, 8,11,13,10, 7,13,
606.1480 +        19,19,17,19,17,14,14,19,12,10, 8,12,13,10, 9,16,
606.1481 +         7, 8, 7,12, 7, 7, 7,11, 8, 7, 7, 8,12,12,11,11,
606.1482 +         8, 8, 7,12, 8, 7, 6,11, 8, 7, 7,10,10,11,10,11,
606.1483 +         9, 8, 8,13, 9, 8, 7,12,10, 9, 7,11, 9, 8, 7,11,
606.1484 +        18,18,15,18,18,16,17,18,15,11,10,18,11, 9, 9,18,
606.1485 +        16,16,13,16,12,11,10,16,12,11, 9, 6,15,12,11,13,
606.1486 +        16,16,14,14,13,11,12,16,12, 9, 9,13,13,10,10,12,
606.1487 +        17,18,17,17,14,15,14,16,14,12,14,15,12,10,11,12,
606.1488 +        18,18,18,18,18,18,18,18,18,12,13,18,16,11, 9,18,
606.1489 +};
606.1490 +
606.1491 +static const static_codebook _huff_book_line_256x4low_class0 = {
606.1492 +        1, 256,
606.1493 +        (long *)_huff_lengthlist_line_256x4low_class0,
606.1494 +        0, 0, 0, 0, 0,
606.1495 +        NULL,
606.1496 +        0
606.1497 +};
606.1498 +
606.1499 +static const long _huff_lengthlist_line_256x4low_0sub0[] = {
606.1500 +         1, 3, 2, 3,
606.1501 +};
606.1502 +
606.1503 +static const static_codebook _huff_book_line_256x4low_0sub0 = {
606.1504 +        1, 4,
606.1505 +        (long *)_huff_lengthlist_line_256x4low_0sub0,
606.1506 +        0, 0, 0, 0, 0,
606.1507 +        NULL,
606.1508 +        0
606.1509 +};
606.1510 +
606.1511 +static const long _huff_lengthlist_line_256x4low_0sub1[] = {
606.1512 +         0, 0, 0, 0, 2, 3, 2, 3, 3, 3,
606.1513 +};
606.1514 +
606.1515 +static const static_codebook _huff_book_line_256x4low_0sub1 = {
606.1516 +        1, 10,
606.1517 +        (long *)_huff_lengthlist_line_256x4low_0sub1,
606.1518 +        0, 0, 0, 0, 0,
606.1519 +        NULL,
606.1520 +        0
606.1521 +};
606.1522 +
606.1523 +static const long _huff_lengthlist_line_256x4low_0sub2[] = {
606.1524 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 3, 4,
606.1525 +         4, 4, 4, 4, 5, 5, 5, 6, 6,
606.1526 +};
606.1527 +
606.1528 +static const static_codebook _huff_book_line_256x4low_0sub2 = {
606.1529 +        1, 25,
606.1530 +        (long *)_huff_lengthlist_line_256x4low_0sub2,
606.1531 +        0, 0, 0, 0, 0,
606.1532 +        NULL,
606.1533 +        0
606.1534 +};
606.1535 +
606.1536 +static const long _huff_lengthlist_line_256x4low_0sub3[] = {
606.1537 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606.1538 +         0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 2, 4, 3, 5, 4,
606.1539 +         5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 6, 9,
606.1540 +         7,12,11,16,13,16,12,15,13,15,12,14,12,15,15,15,
606.1541 +};
606.1542 +
606.1543 +static const static_codebook _huff_book_line_256x4low_0sub3 = {
606.1544 +        1, 64,
606.1545 +        (long *)_huff_lengthlist_line_256x4low_0sub3,
606.1546 +        0, 0, 0, 0, 0,
606.1547 +        NULL,
606.1548 +        0
606.1549 +};
606.1550 +
   607.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   607.2 +++ b/libs/vorbis/books/uncoupled/res_books_uncoupled.h	Sat Feb 01 19:58:19 2014 +0200
   607.3 @@ -0,0 +1,7758 @@
   607.4 +/********************************************************************
   607.5 + *                                                                  *
   607.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   607.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   607.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   607.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  607.10 + *                                                                  *
  607.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  607.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  607.13 + *                                                                  *
  607.14 + ********************************************************************
  607.15 +
  607.16 + function: static codebooks autogenerated by huff/huffbuld
  607.17 + last modified: $Id: res_books_uncoupled.h 17022 2010-03-25 03:45:42Z xiphmont $
  607.18 +
  607.19 + ********************************************************************/
  607.20 +
  607.21 +#include "codebook.h"
  607.22 +
  607.23 +static const long _vq_quantlist__16u0__p1_0[] = {
  607.24 +        1,
  607.25 +        0,
  607.26 +        2,
  607.27 +};
  607.28 +
  607.29 +static const long _vq_lengthlist__16u0__p1_0[] = {
  607.30 +         1, 4, 4, 5, 7, 7, 5, 7, 8, 5, 8, 8, 8,10,10, 8,
  607.31 +        10,11, 5, 8, 8, 8,10,10, 8,10,10, 4, 9, 9, 9,12,
  607.32 +        11, 8,11,11, 8,12,11,10,12,14,10,13,13, 7,11,11,
  607.33 +        10,14,12,11,14,14, 4, 9, 9, 8,11,11, 9,11,12, 7,
  607.34 +        11,11,10,13,14,10,12,14, 8,11,12,10,14,14,10,13,
  607.35 +        12,
  607.36 +};
  607.37 +
  607.38 +static const static_codebook _16u0__p1_0 = {
  607.39 +        4, 81,
  607.40 +        (long *)_vq_lengthlist__16u0__p1_0,
  607.41 +        1, -535822336, 1611661312, 2, 0,
  607.42 +        (long *)_vq_quantlist__16u0__p1_0,
  607.43 +        0
  607.44 +};
  607.45 +
  607.46 +static const long _vq_quantlist__16u0__p2_0[] = {
  607.47 +        1,
  607.48 +        0,
  607.49 +        2,
  607.50 +};
  607.51 +
  607.52 +static const long _vq_lengthlist__16u0__p2_0[] = {
  607.53 +         2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 9, 7,
  607.54 +         8, 9, 5, 7, 7, 7, 9, 8, 7, 9, 7, 4, 7, 7, 7, 9,
  607.55 +         9, 7, 8, 8, 6, 9, 8, 7, 8,11, 9,11,10, 6, 8, 9,
  607.56 +         8,11, 8, 9,10,11, 4, 7, 7, 7, 8, 8, 7, 9, 9, 6,
  607.57 +         9, 8, 9,11,10, 8, 8,11, 6, 8, 9, 9,10,11, 8,11,
  607.58 +         8,
  607.59 +};
  607.60 +
  607.61 +static const static_codebook _16u0__p2_0 = {
  607.62 +        4, 81,
  607.63 +        (long *)_vq_lengthlist__16u0__p2_0,
  607.64 +        1, -535822336, 1611661312, 2, 0,
  607.65 +        (long *)_vq_quantlist__16u0__p2_0,
  607.66 +        0
  607.67 +};
  607.68 +
  607.69 +static const long _vq_quantlist__16u0__p3_0[] = {
  607.70 +        2,
  607.71 +        1,
  607.72 +        3,
  607.73 +        0,
  607.74 +        4,
  607.75 +};
  607.76 +
  607.77 +static const long _vq_lengthlist__16u0__p3_0[] = {
  607.78 +         1, 5, 5, 7, 7, 6, 7, 7, 8, 8, 6, 7, 8, 8, 8, 8,
  607.79 +         9, 9,11,11, 8, 9, 9,11,11, 6, 9, 8,10,10, 8,10,
  607.80 +        10,11,11, 8,10,10,11,11,10,11,10,13,12, 9,11,10,
  607.81 +        13,13, 6, 8, 9,10,10, 8,10,10,11,11, 8,10,10,11,
  607.82 +        11, 9,10,11,13,12,10,10,11,12,12, 8,11,11,14,13,
  607.83 +        10,12,11,15,13, 9,12,11,15,14,12,14,13,16,14,12,
  607.84 +        13,13,17,14, 8,11,11,13,14, 9,11,12,14,15,10,11,
  607.85 +        12,13,15,11,13,13,14,16,12,13,14,14,16, 5, 9, 9,
  607.86 +        11,11, 9,11,11,12,12, 8,11,11,12,12,11,12,12,15,
  607.87 +        14,10,12,12,15,15, 8,11,11,13,12,10,12,12,13,13,
  607.88 +        10,12,12,14,13,12,12,13,14,15,11,13,13,17,16, 7,
  607.89 +        11,11,13,13,10,12,12,14,13,10,12,12,13,14,12,13,
  607.90 +        12,15,14,11,13,13,15,14, 9,12,12,16,15,11,13,13,
  607.91 +        17,16,10,13,13,16,16,13,14,15,15,16,13,15,14,19,
  607.92 +        17, 9,12,12,14,16,11,13,13,15,16,10,13,13,17,16,
  607.93 +        13,14,13,17,15,12,15,15,16,17, 5, 9, 9,11,11, 8,
  607.94 +        11,11,13,12, 9,11,11,12,12,10,12,12,14,15,11,12,
  607.95 +        12,14,14, 7,11,10,13,12,10,12,12,14,13,10,11,12,
  607.96 +        13,13,11,13,13,15,16,12,12,13,15,15, 7,11,11,13,
  607.97 +        13,10,13,13,14,14,10,12,12,13,13,11,13,13,16,15,
  607.98 +        12,13,13,15,14, 9,12,12,15,15,10,13,13,17,16,11,
  607.99 +        12,13,15,15,12,15,14,18,18,13,14,14,16,17, 9,12,
 607.100 +        12,15,16,10,13,13,15,16,11,13,13,15,16,13,15,15,
 607.101 +        17,17,13,15,14,16,15, 7,11,11,15,16,10,13,12,16,
 607.102 +        17,10,12,13,15,17,15,16,16,18,17,13,15,15,17,18,
 607.103 +         8,12,12,16,16,11,13,14,17,18,11,13,13,18,16,15,
 607.104 +        17,16,17,19,14,15,15,17,16, 8,12,12,16,15,11,14,
 607.105 +        13,18,17,11,13,14,18,17,15,16,16,18,17,13,16,16,
 607.106 +        18,18,11,15,14,18,17,13,14,15,18, 0,12,15,15, 0,
 607.107 +        17,17,16,17,17,18,14,16,18,18, 0,11,14,14,17, 0,
 607.108 +        12,15,14,17,19,12,15,14,18, 0,15,18,16, 0,17,14,
 607.109 +        18,16,18, 0, 7,11,11,16,15,10,12,12,18,16,10,13,
 607.110 +        13,16,15,13,15,14,17,17,14,16,16,19,18, 8,12,12,
 607.111 +        16,16,11,13,13,18,16,11,13,14,17,16,14,15,15,19,
 607.112 +        18,15,16,16, 0,19, 8,12,12,16,17,11,13,13,17,17,
 607.113 +        11,14,13,17,17,13,15,15,17,19,15,17,17,19, 0,11,
 607.114 +        14,15,19,17,12,15,16,18,18,12,14,15,19,17,14,16,
 607.115 +        17, 0,18,16,16,19,17, 0,11,14,14,18,19,12,15,14,
 607.116 +        17,17,13,16,14,17,16,14,17,16,18,18,15,18,15, 0,
 607.117 +        18,
 607.118 +};
 607.119 +
 607.120 +static const static_codebook _16u0__p3_0 = {
 607.121 +        4, 625,
 607.122 +        (long *)_vq_lengthlist__16u0__p3_0,
 607.123 +        1, -533725184, 1611661312, 3, 0,
 607.124 +        (long *)_vq_quantlist__16u0__p3_0,
 607.125 +        0
 607.126 +};
 607.127 +
 607.128 +static const long _vq_quantlist__16u0__p4_0[] = {
 607.129 +        2,
 607.130 +        1,
 607.131 +        3,
 607.132 +        0,
 607.133 +        4,
 607.134 +};
 607.135 +
 607.136 +static const long _vq_lengthlist__16u0__p4_0[] = {
 607.137 +         3, 5, 5, 8, 8, 6, 6, 6, 9, 9, 6, 6, 6, 9, 9, 9,
 607.138 +        10, 9,11,11, 9, 9, 9,11,11, 6, 7, 7,10,10, 7, 7,
 607.139 +         8,10,10, 7, 7, 8,10,10,10,10,10,11,12, 9,10,10,
 607.140 +        11,12, 6, 7, 7,10,10, 7, 8, 7,10,10, 7, 8, 7,10,
 607.141 +        10,10,11,10,12,11,10,10,10,13,10, 9,10,10,12,12,
 607.142 +        10,11,10,14,12, 9,11,11,13,13,11,12,13,13,13,11,
 607.143 +        12,12,15,13, 9,10,10,12,13, 9,11,10,12,13,10,10,
 607.144 +        11,12,13,11,12,12,12,13,11,12,12,13,13, 5, 7, 7,
 607.145 +        10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,12,
 607.146 +        13,10,10,11,12,12, 6, 8, 8,11,10, 7, 8, 9,10,12,
 607.147 +         8, 9, 9,11,11,11,10,11,11,12,10,11,11,13,12, 7,
 607.148 +         8, 8,10,11, 8, 9, 8,11,10, 8, 9, 9,11,11,10,12,
 607.149 +        10,13,11,10,11,11,13,13,10,11,10,14,13,10,10,11,
 607.150 +        13,13,10,12,11,14,13,12,11,13,12,13,13,12,13,14,
 607.151 +        14,10,11,11,13,13,10,11,10,12,13,10,12,12,12,14,
 607.152 +        12,12,12,14,12,12,13,12,17,15, 5, 7, 7,10,10, 7,
 607.153 +         8, 8,10,10, 7, 8, 8,11,10,10,10,11,12,12,10,11,
 607.154 +        11,12,13, 6, 8, 8,11,10, 8, 9, 9,11,11, 7, 8, 9,
 607.155 +        10,11,11,11,11,12,12,10,10,11,12,13, 6, 8, 8,10,
 607.156 +        11, 8, 9, 9,11,11, 7, 9, 7,11,10,10,12,12,13,13,
 607.157 +        11,11,10,13,11, 9,11,10,14,13,11,11,11,15,13,10,
 607.158 +        10,11,13,13,12,13,13,14,14,12,11,12,12,13,10,11,
 607.159 +        11,12,13,10,11,12,13,13,10,11,10,13,12,12,12,13,
 607.160 +        14, 0,12,13,11,13,11, 8,10,10,13,13,10,11,11,14,
 607.161 +        13,10,11,11,13,12,13,14,14,14,15,12,12,12,15,14,
 607.162 +         9,11,10,13,12,10,10,11,13,14,11,11,11,15,12,13,
 607.163 +        12,14,15,16,13,13,13,14,13, 9,11,11,12,12,10,12,
 607.164 +        11,13,13,10,11,11,13,14,13,13,13,15,15,13,13,14,
 607.165 +        17,15,11,12,12,14,14,10,11,12,13,15,12,13,13, 0,
 607.166 +        15,13,11,14,12,16,14,16,14, 0,15,11,12,12,14,16,
 607.167 +        11,13,12,16,15,12,13,13,14,15,12,14,12,15,13,15,
 607.168 +        14,14,16,16, 8,10,10,13,13,10,11,10,13,14,10,11,
 607.169 +        11,13,13,13,13,12,14,14,14,13,13,16,17, 9,10,10,
 607.170 +        12,14,10,12,11,14,13,10,11,12,13,14,12,12,12,15,
 607.171 +        15,13,13,13,14,14, 9,10,10,13,13,10,11,12,12,14,
 607.172 +        10,11,10,13,13,13,13,13,14,16,13,13,13,14,14,11,
 607.173 +        12,13,15,13,12,14,13,14,16,12,12,13,13,14,13,14,
 607.174 +        14,17,15,13,12,17,13,16,11,12,13,14,15,12,13,14,
 607.175 +        14,17,11,12,11,14,14,13,16,14,16, 0,14,15,11,15,
 607.176 +        11,
 607.177 +};
 607.178 +
 607.179 +static const static_codebook _16u0__p4_0 = {
 607.180 +        4, 625,
 607.181 +        (long *)_vq_lengthlist__16u0__p4_0,
 607.182 +        1, -533725184, 1611661312, 3, 0,
 607.183 +        (long *)_vq_quantlist__16u0__p4_0,
 607.184 +        0
 607.185 +};
 607.186 +
 607.187 +static const long _vq_quantlist__16u0__p5_0[] = {
 607.188 +        4,
 607.189 +        3,
 607.190 +        5,
 607.191 +        2,
 607.192 +        6,
 607.193 +        1,
 607.194 +        7,
 607.195 +        0,
 607.196 +        8,
 607.197 +};
 607.198 +
 607.199 +static const long _vq_lengthlist__16u0__p5_0[] = {
 607.200 +         1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8,
 607.201 +         9, 9, 4, 6, 6, 8, 8, 8, 8, 9, 9, 7, 8, 8, 9, 9,
 607.202 +         9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,11, 7, 8, 8,
 607.203 +         9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
 607.204 +         9, 9,10,10,11,11,12,12, 9, 9, 9,10,10,11,11,12,
 607.205 +        12,
 607.206 +};
 607.207 +
 607.208 +static const static_codebook _16u0__p5_0 = {
 607.209 +        2, 81,
 607.210 +        (long *)_vq_lengthlist__16u0__p5_0,
 607.211 +        1, -531628032, 1611661312, 4, 0,
 607.212 +        (long *)_vq_quantlist__16u0__p5_0,
 607.213 +        0
 607.214 +};
 607.215 +
 607.216 +static const long _vq_quantlist__16u0__p6_0[] = {
 607.217 +        6,
 607.218 +        5,
 607.219 +        7,
 607.220 +        4,
 607.221 +        8,
 607.222 +        3,
 607.223 +        9,
 607.224 +        2,
 607.225 +        10,
 607.226 +        1,
 607.227 +        11,
 607.228 +        0,
 607.229 +        12,
 607.230 +};
 607.231 +
 607.232 +static const long _vq_lengthlist__16u0__p6_0[] = {
 607.233 +         1, 4, 4, 7, 7,10,10,12,12,13,13,18,17, 3, 6, 6,
 607.234 +         9, 9,11,11,13,13,14,14,18,17, 3, 6, 6, 9, 9,11,
 607.235 +        11,13,13,14,14,17,18, 7, 9, 9,11,11,13,13,14,14,
 607.236 +        15,15, 0, 0, 7, 9, 9,11,11,13,13,14,14,15,16,19,
 607.237 +        18,10,11,11,13,13,14,14,16,15,17,18, 0, 0,10,11,
 607.238 +        11,13,13,14,14,15,15,16,18, 0, 0,11,13,13,14,14,
 607.239 +        15,15,17,17, 0,19, 0, 0,11,13,13,14,14,14,15,16,
 607.240 +        18, 0,19, 0, 0,13,14,14,15,15,18,17,18,18, 0,19,
 607.241 +         0, 0,13,14,14,15,16,16,16,18,18,19, 0, 0, 0,16,
 607.242 +        17,17, 0,17,19,19, 0,19, 0, 0, 0, 0,16,19,16,17,
 607.243 +        18, 0,19, 0, 0, 0, 0, 0, 0,
 607.244 +};
 607.245 +
 607.246 +static const static_codebook _16u0__p6_0 = {
 607.247 +        2, 169,
 607.248 +        (long *)_vq_lengthlist__16u0__p6_0,
 607.249 +        1, -526516224, 1616117760, 4, 0,
 607.250 +        (long *)_vq_quantlist__16u0__p6_0,
 607.251 +        0
 607.252 +};
 607.253 +
 607.254 +static const long _vq_quantlist__16u0__p6_1[] = {
 607.255 +        2,
 607.256 +        1,
 607.257 +        3,
 607.258 +        0,
 607.259 +        4,
 607.260 +};
 607.261 +
 607.262 +static const long _vq_lengthlist__16u0__p6_1[] = {
 607.263 +         1, 4, 5, 6, 6, 4, 6, 6, 6, 6, 4, 6, 6, 6, 6, 6,
 607.264 +         6, 6, 7, 7, 6, 6, 6, 7, 7,
 607.265 +};
 607.266 +
 607.267 +static const static_codebook _16u0__p6_1 = {
 607.268 +        2, 25,
 607.269 +        (long *)_vq_lengthlist__16u0__p6_1,
 607.270 +        1, -533725184, 1611661312, 3, 0,
 607.271 +        (long *)_vq_quantlist__16u0__p6_1,
 607.272 +        0
 607.273 +};
 607.274 +
 607.275 +static const long _vq_quantlist__16u0__p7_0[] = {
 607.276 +        1,
 607.277 +        0,
 607.278 +        2,
 607.279 +};
 607.280 +
 607.281 +static const long _vq_lengthlist__16u0__p7_0[] = {
 607.282 +         1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 607.283 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 607.284 +         8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 607.285 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 607.286 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 607.287 +         7,
 607.288 +};
 607.289 +
 607.290 +static const static_codebook _16u0__p7_0 = {
 607.291 +        4, 81,
 607.292 +        (long *)_vq_lengthlist__16u0__p7_0,
 607.293 +        1, -518803456, 1628680192, 2, 0,
 607.294 +        (long *)_vq_quantlist__16u0__p7_0,
 607.295 +        0
 607.296 +};
 607.297 +
 607.298 +static const long _vq_quantlist__16u0__p7_1[] = {
 607.299 +        7,
 607.300 +        6,
 607.301 +        8,
 607.302 +        5,
 607.303 +        9,
 607.304 +        4,
 607.305 +        10,
 607.306 +        3,
 607.307 +        11,
 607.308 +        2,
 607.309 +        12,
 607.310 +        1,
 607.311 +        13,
 607.312 +        0,
 607.313 +        14,
 607.314 +};
 607.315 +
 607.316 +static const long _vq_lengthlist__16u0__p7_1[] = {
 607.317 +         1, 5, 5, 6, 5, 9,10,11,11,10,10,10,10,10,10, 5,
 607.318 +         8, 8, 8,10,10,10,10,10,10,10,10,10,10,10, 5, 8,
 607.319 +         9, 9, 9,10,10,10,10,10,10,10,10,10,10, 5,10, 8,
 607.320 +        10,10,10,10,10,10,10,10,10,10,10,10, 4, 8, 9,10,
 607.321 +        10,10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10,
 607.322 +        10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10,10,
 607.323 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 607.324 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 607.325 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 607.326 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 607.327 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 607.328 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 607.329 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 607.330 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 607.331 +        10,
 607.332 +};
 607.333 +
 607.334 +static const static_codebook _16u0__p7_1 = {
 607.335 +        2, 225,
 607.336 +        (long *)_vq_lengthlist__16u0__p7_1,
 607.337 +        1, -520986624, 1620377600, 4, 0,
 607.338 +        (long *)_vq_quantlist__16u0__p7_1,
 607.339 +        0
 607.340 +};
 607.341 +
 607.342 +static const long _vq_quantlist__16u0__p7_2[] = {
 607.343 +        10,
 607.344 +        9,
 607.345 +        11,
 607.346 +        8,
 607.347 +        12,
 607.348 +        7,
 607.349 +        13,
 607.350 +        6,
 607.351 +        14,
 607.352 +        5,
 607.353 +        15,
 607.354 +        4,
 607.355 +        16,
 607.356 +        3,
 607.357 +        17,
 607.358 +        2,
 607.359 +        18,
 607.360 +        1,
 607.361 +        19,
 607.362 +        0,
 607.363 +        20,
 607.364 +};
 607.365 +
 607.366 +static const long _vq_lengthlist__16u0__p7_2[] = {
 607.367 +         1, 6, 6, 7, 8, 7, 7,10, 9,10, 9,11,10, 9,11,10,
 607.368 +         9, 9, 9, 9,10, 6, 8, 7, 9, 9, 8, 8,10,10, 9,11,
 607.369 +        11,12,12,10, 9,11, 9,12,10, 9, 6, 9, 8, 9,12, 8,
 607.370 +         8,11, 9,11,11,12,11,12,12,10,11,11,10,10,11, 7,
 607.371 +        10, 9, 9, 9, 9, 9,10, 9,10, 9,10,10,12,10,10,10,
 607.372 +        11,12,10,10, 7, 9, 9, 9,10, 9, 9,10,10, 9, 9, 9,
 607.373 +        11,11,10,10,10,10, 9, 9,12, 7, 9,10, 9,11, 9,10,
 607.374 +         9,10,11,11,11,10,11,12, 9,12,11,10,10,10, 7, 9,
 607.375 +         9, 9, 9,10,12,10, 9,11,12,10,11,12,12,11, 9,10,
 607.376 +        11,10,11, 7, 9,10,10,11,10, 9,10,11,11,11,10,12,
 607.377 +        12,12,11,11,10,11,11,12, 8, 9,10,12,11,10,10,12,
 607.378 +        12,12,12,12,10,11,11, 9,11,10,12,11,11, 8, 9,10,
 607.379 +        10,11,12,11,11,10,10,10,12,12,12, 9,10,12,12,12,
 607.380 +        12,12, 8,10,11,10,10,12, 9,11,12,12,11,12,12,12,
 607.381 +        12,10,12,10,10,10,10, 8,12,11,11,11,10,10,11,12,
 607.382 +        12,12,12,11,12,12,12,11,11,11,12,10, 9,10,10,12,
 607.383 +        10,12,10,12,12,10,10,10,11,12,12,12,11,12,12,12,
 607.384 +        11,10,11,12,12,12,11,12,12,11,12,12,11,12,12,12,
 607.385 +        12,11,12,12,10,10,10,10,11,11,12,11,12,12,12,12,
 607.386 +        12,12,12,11,12,11,10,11,11,12,11,11, 9,10,10,10,
 607.387 +        12,10,10,11, 9,11,12,11,12,11,12,12,10,11,10,12,
 607.388 +         9, 9, 9,12,11,10,11,10,12,10,12,10,12,12,12,11,
 607.389 +        11,11,11,11,10, 9,10,10,11,10,11,11,12,11,10,11,
 607.390 +        12,12,12,11,11, 9,12,10,12, 9,10,12,10,10,11,10,
 607.391 +        11,11,12,11,10,11,10,11,11,11,11,12,11,11,10, 9,
 607.392 +        10,10,10, 9,11,11,10, 9,12,10,11,12,11,12,12,11,
 607.393 +        12,11,12,11,10,11,10,12,11,12,11,12,11,12,10,11,
 607.394 +        10,10,12,11,10,11,11,11,10,
 607.395 +};
 607.396 +
 607.397 +static const static_codebook _16u0__p7_2 = {
 607.398 +        2, 441,
 607.399 +        (long *)_vq_lengthlist__16u0__p7_2,
 607.400 +        1, -529268736, 1611661312, 5, 0,
 607.401 +        (long *)_vq_quantlist__16u0__p7_2,
 607.402 +        0
 607.403 +};
 607.404 +
 607.405 +static const long _huff_lengthlist__16u0__single[] = {
 607.406 +         3, 5, 8, 7,14, 8, 9,19, 5, 2, 5, 5, 9, 6, 9,19,
 607.407 +         8, 4, 5, 7, 8, 9,13,19, 7, 4, 6, 5, 9, 6, 9,19,
 607.408 +        12, 8, 7, 9,10,11,13,19, 8, 5, 8, 6, 9, 6, 7,19,
 607.409 +         8, 8,10, 7, 7, 4, 5,19,12,17,19,15,18,13,11,18,
 607.410 +};
 607.411 +
 607.412 +static const static_codebook _huff_book__16u0__single = {
 607.413 +        2, 64,
 607.414 +        (long *)_huff_lengthlist__16u0__single,
 607.415 +        0, 0, 0, 0, 0,
 607.416 +        NULL,
 607.417 +        0
 607.418 +};
 607.419 +
 607.420 +static const long _huff_lengthlist__16u1__long[] = {
 607.421 +         3, 6,10, 8,12, 8,14, 8,14,19, 5, 3, 5, 5, 7, 6,
 607.422 +        11, 7,16,19, 7, 5, 6, 7, 7, 9,11,12,19,19, 6, 4,
 607.423 +         7, 5, 7, 6,10, 7,18,18, 8, 6, 7, 7, 7, 7, 8, 9,
 607.424 +        18,18, 7, 5, 8, 5, 7, 5, 8, 6,18,18,12, 9,10, 9,
 607.425 +         9, 9, 8, 9,18,18, 8, 7,10, 6, 8, 5, 6, 4,11,18,
 607.426 +        11,15,16,12,11, 8, 8, 6, 9,18,14,18,18,18,16,16,
 607.427 +        16,13,16,18,
 607.428 +};
 607.429 +
 607.430 +static const static_codebook _huff_book__16u1__long = {
 607.431 +        2, 100,
 607.432 +        (long *)_huff_lengthlist__16u1__long,
 607.433 +        0, 0, 0, 0, 0,
 607.434 +        NULL,
 607.435 +        0
 607.436 +};
 607.437 +
 607.438 +static const long _vq_quantlist__16u1__p1_0[] = {
 607.439 +        1,
 607.440 +        0,
 607.441 +        2,
 607.442 +};
 607.443 +
 607.444 +static const long _vq_lengthlist__16u1__p1_0[] = {
 607.445 +         1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 7, 7,10,10, 7,
 607.446 +         9,10, 5, 7, 8, 7,10, 9, 7,10,10, 5, 8, 8, 8,10,
 607.447 +        10, 8,10,10, 7,10,10,10,11,12,10,12,13, 7,10,10,
 607.448 +         9,13,11,10,12,13, 5, 8, 8, 8,10,10, 8,10,10, 7,
 607.449 +        10,10,10,12,12, 9,11,12, 7,10,11,10,12,12,10,13,
 607.450 +        11,
 607.451 +};
 607.452 +
 607.453 +static const static_codebook _16u1__p1_0 = {
 607.454 +        4, 81,
 607.455 +        (long *)_vq_lengthlist__16u1__p1_0,
 607.456 +        1, -535822336, 1611661312, 2, 0,
 607.457 +        (long *)_vq_quantlist__16u1__p1_0,
 607.458 +        0
 607.459 +};
 607.460 +
 607.461 +static const long _vq_quantlist__16u1__p2_0[] = {
 607.462 +        1,
 607.463 +        0,
 607.464 +        2,
 607.465 +};
 607.466 +
 607.467 +static const long _vq_lengthlist__16u1__p2_0[] = {
 607.468 +         3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 7, 8, 6,
 607.469 +         7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 7, 5, 6, 6, 6, 8,
 607.470 +         8, 6, 8, 8, 6, 8, 8, 7, 7,10, 8, 9, 9, 6, 8, 8,
 607.471 +         7, 9, 8, 8, 9,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6,
 607.472 +         8, 8, 8,10, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 7,10,
 607.473 +         8,
 607.474 +};
 607.475 +
 607.476 +static const static_codebook _16u1__p2_0 = {
 607.477 +        4, 81,
 607.478 +        (long *)_vq_lengthlist__16u1__p2_0,
 607.479 +        1, -535822336, 1611661312, 2, 0,
 607.480 +        (long *)_vq_quantlist__16u1__p2_0,
 607.481 +        0
 607.482 +};
 607.483 +
 607.484 +static const long _vq_quantlist__16u1__p3_0[] = {
 607.485 +        2,
 607.486 +        1,
 607.487 +        3,
 607.488 +        0,
 607.489 +        4,
 607.490 +};
 607.491 +
 607.492 +static const long _vq_lengthlist__16u1__p3_0[] = {
 607.493 +         1, 5, 5, 8, 8, 6, 7, 7, 9, 9, 5, 7, 7, 9, 9, 9,
 607.494 +        10, 9,11,11, 9, 9,10,11,11, 6, 8, 8,10,10, 8, 9,
 607.495 +        10,11,11, 8, 9,10,11,11,10,11,11,12,13,10,11,11,
 607.496 +        13,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10, 9,11,
 607.497 +        11,10,11,11,13,13,10,11,11,13,12, 9,11,11,14,13,
 607.498 +        10,12,12,15,14,10,12,11,14,13,12,13,13,15,15,12,
 607.499 +        13,13,16,14, 9,11,11,13,14,10,11,12,14,14,10,12,
 607.500 +        12,14,15,12,13,13,14,15,12,13,14,15,16, 5, 8, 8,
 607.501 +        11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14,
 607.502 +        14,11,12,12,14,14, 8,10,10,12,12, 9,11,12,12,13,
 607.503 +        10,12,12,13,13,12,12,13,14,15,11,13,13,15,15, 7,
 607.504 +        10,10,12,12, 9,12,11,13,12,10,11,12,13,13,12,13,
 607.505 +        12,15,14,11,12,13,15,15,10,12,12,15,14,11,13,13,
 607.506 +        16,15,11,13,13,16,15,14,13,14,15,16,13,15,15,17,
 607.507 +        17,10,12,12,14,15,11,12,12,15,15,11,13,13,15,16,
 607.508 +        13,15,13,16,15,13,15,15,16,17, 5, 8, 8,11,11, 8,
 607.509 +        10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12,
 607.510 +        12,14,14, 7,10,10,12,12,10,12,12,14,13, 9,11,12,
 607.511 +        12,13,12,13,13,15,15,12,12,13,13,15, 7,10,10,12,
 607.512 +        13,10,11,12,13,13,10,12,11,13,13,11,13,13,15,15,
 607.513 +        12,13,12,15,14, 9,12,12,15,14,11,13,13,15,15,11,
 607.514 +        12,13,15,15,13,14,14,17,19,13,13,14,16,16,10,12,
 607.515 +        12,14,15,11,13,13,15,16,11,13,12,16,15,13,15,15,
 607.516 +        17,18,14,15,13,16,15, 8,11,11,15,14,10,12,12,16,
 607.517 +        15,10,12,12,16,16,14,15,15,18,17,13,14,15,16,18,
 607.518 +         9,12,12,15,15,11,12,14,16,17,11,13,13,16,15,15,
 607.519 +        15,15,17,18,14,15,16,17,17, 9,12,12,15,15,11,14,
 607.520 +        13,16,16,11,13,13,16,16,15,16,15,17,18,14,16,15,
 607.521 +        17,16,12,14,14,17,16,12,14,15,18,17,13,15,15,17,
 607.522 +        17,15,15,18,16,20,15,16,17,18,18,11,14,14,16,17,
 607.523 +        13,15,14,18,17,13,15,15,17,17,15,17,15,18,17,15,
 607.524 +        17,16,19,18, 8,11,11,14,15,10,12,12,15,15,10,12,
 607.525 +        12,16,16,13,14,14,17,16,14,15,15,17,17, 9,12,12,
 607.526 +        15,16,11,13,13,16,16,11,12,13,16,16,14,16,15,20,
 607.527 +        17,14,16,16,17,17, 9,12,12,15,16,11,13,13,16,17,
 607.528 +        11,13,13,17,16,14,15,15,17,18,15,15,15,18,18,11,
 607.529 +        14,14,17,16,13,15,15,17,17,13,14,14,18,17,15,16,
 607.530 +        16,18,19,15,15,17,17,19,11,14,14,16,17,13,15,14,
 607.531 +        17,19,13,15,14,18,17,15,17,16,18,18,15,17,15,18,
 607.532 +        16,
 607.533 +};
 607.534 +
 607.535 +static const static_codebook _16u1__p3_0 = {
 607.536 +        4, 625,
 607.537 +        (long *)_vq_lengthlist__16u1__p3_0,
 607.538 +        1, -533725184, 1611661312, 3, 0,
 607.539 +        (long *)_vq_quantlist__16u1__p3_0,
 607.540 +        0
 607.541 +};
 607.542 +
 607.543 +static const long _vq_quantlist__16u1__p4_0[] = {
 607.544 +        2,
 607.545 +        1,
 607.546 +        3,
 607.547 +        0,
 607.548 +        4,
 607.549 +};
 607.550 +
 607.551 +static const long _vq_lengthlist__16u1__p4_0[] = {
 607.552 +         4, 5, 5, 8, 8, 6, 6, 7, 9, 9, 6, 6, 6, 9, 9, 9,
 607.553 +        10, 9,11,11, 9, 9,10,11,11, 6, 7, 7,10, 9, 7, 7,
 607.554 +         8, 9,10, 7, 7, 8,10,10,10,10,10,10,12, 9, 9,10,
 607.555 +        11,12, 6, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 7,10,
 607.556 +        10, 9,10, 9,12,11,10,10, 9,12,10, 9,10,10,12,11,
 607.557 +        10,10,10,12,12, 9,10,10,12,12,12,11,12,13,13,11,
 607.558 +        11,12,12,13, 9,10,10,11,12, 9,10,10,12,12,10,10,
 607.559 +        10,12,12,11,12,11,14,13,11,12,12,14,13, 5, 7, 7,
 607.560 +        10,10, 7, 8, 8,10,10, 7, 8, 7,10,10,10,10,10,12,
 607.561 +        12,10,10,10,12,12, 6, 8, 7,10,10, 7, 7, 9,10,11,
 607.562 +         8, 9, 9,11,10,10,10,11,11,13,10,10,11,12,13, 6,
 607.563 +         8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,10,11,10,11,
 607.564 +        10,13,11,10,11,10,12,12,10,11,10,12,11,10,10,10,
 607.565 +        12,13,10,11,11,13,12,11,11,13,11,14,12,12,13,14,
 607.566 +        14, 9,10,10,12,13,10,11,10,13,12,10,11,11,12,13,
 607.567 +        11,12,11,14,12,12,13,13,15,14, 5, 7, 7,10,10, 7,
 607.568 +         7, 8,10,10, 7, 8, 8,10,10,10,10,10,11,12,10,10,
 607.569 +        10,12,12, 7, 8, 8,10,10, 8, 9, 8,11,10, 7, 8, 9,
 607.570 +        10,11,10,11,11,12,12,10,10,11,11,13, 7, 7, 8,10,
 607.571 +        10, 8, 8, 9,10,11, 7, 9, 7,11,10,10,11,11,13,12,
 607.572 +        11,11,10,13,11, 9,10,10,12,12,10,11,11,13,12,10,
 607.573 +        10,11,12,12,12,13,13,14,14,11,11,12,12,14,10,10,
 607.574 +        11,12,12,10,11,11,12,13,10,10,10,13,12,12,13,13,
 607.575 +        15,14,12,13,10,14,11, 8,10,10,12,12,10,11,10,13,
 607.576 +        13, 9,10,10,12,12,12,13,13,15,14,11,12,12,13,13,
 607.577 +         9,10,10,13,12,10,10,11,13,13,10,11,10,13,12,12,
 607.578 +        12,13,14,15,12,13,12,15,13, 9,10,10,12,13,10,11,
 607.579 +        10,13,12,10,10,11,12,13,12,14,12,15,13,12,12,13,
 607.580 +        14,15,11,12,11,14,13,11,11,12,14,15,12,13,12,15,
 607.581 +        14,13,11,15,11,16,13,14,14,16,15,11,12,12,14,14,
 607.582 +        11,12,11,14,13,12,12,13,14,15,13,14,12,16,12,14,
 607.583 +        14,14,15,15, 8,10,10,12,12, 9,10,10,12,12,10,10,
 607.584 +        11,13,13,11,12,12,13,13,12,13,13,14,15, 9,10,10,
 607.585 +        13,12,10,11,11,13,12,10,10,11,13,13,12,13,12,15,
 607.586 +        14,12,12,13,13,16, 9, 9,10,12,13,10,10,11,12,13,
 607.587 +        10,11,10,13,13,12,12,13,13,15,13,13,12,15,13,11,
 607.588 +        12,12,14,14,12,13,12,15,14,11,11,12,13,14,14,14,
 607.589 +        14,16,15,13,12,15,12,16,11,11,12,13,14,12,13,13,
 607.590 +        14,15,10,12,11,14,13,14,15,14,16,16,13,14,11,15,
 607.591 +        11,
 607.592 +};
 607.593 +
 607.594 +static const static_codebook _16u1__p4_0 = {
 607.595 +        4, 625,
 607.596 +        (long *)_vq_lengthlist__16u1__p4_0,
 607.597 +        1, -533725184, 1611661312, 3, 0,
 607.598 +        (long *)_vq_quantlist__16u1__p4_0,
 607.599 +        0
 607.600 +};
 607.601 +
 607.602 +static const long _vq_quantlist__16u1__p5_0[] = {
 607.603 +        4,
 607.604 +        3,
 607.605 +        5,
 607.606 +        2,
 607.607 +        6,
 607.608 +        1,
 607.609 +        7,
 607.610 +        0,
 607.611 +        8,
 607.612 +};
 607.613 +
 607.614 +static const long _vq_lengthlist__16u1__p5_0[] = {
 607.615 +         1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8,
 607.616 +        10,10, 4, 5, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9,
 607.617 +         9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 7, 8, 8,
 607.618 +        10, 9,11,11,12,11, 7, 8, 8, 9, 9,11,11,12,12, 9,
 607.619 +        10,10,11,11,12,12,13,12, 9,10,10,11,11,12,12,12,
 607.620 +        13,
 607.621 +};
 607.622 +
 607.623 +static const static_codebook _16u1__p5_0 = {
 607.624 +        2, 81,
 607.625 +        (long *)_vq_lengthlist__16u1__p5_0,
 607.626 +        1, -531628032, 1611661312, 4, 0,
 607.627 +        (long *)_vq_quantlist__16u1__p5_0,
 607.628 +        0
 607.629 +};
 607.630 +
 607.631 +static const long _vq_quantlist__16u1__p6_0[] = {
 607.632 +        4,
 607.633 +        3,
 607.634 +        5,
 607.635 +        2,
 607.636 +        6,
 607.637 +        1,
 607.638 +        7,
 607.639 +        0,
 607.640 +        8,
 607.641 +};
 607.642 +
 607.643 +static const long _vq_lengthlist__16u1__p6_0[] = {
 607.644 +         3, 4, 4, 6, 6, 7, 7, 9, 9, 4, 4, 4, 6, 6, 8, 8,
 607.645 +         9, 9, 4, 4, 4, 6, 6, 7, 7, 9, 9, 6, 6, 6, 7, 7,
 607.646 +         8, 8,10, 9, 6, 6, 6, 7, 7, 8, 8, 9,10, 7, 8, 7,
 607.647 +         8, 8, 9, 9,10,10, 7, 8, 8, 8, 8, 9, 9,10,10, 9,
 607.648 +         9, 9,10,10,10,10,11,11, 9, 9, 9,10,10,10,10,11,
 607.649 +        11,
 607.650 +};
 607.651 +
 607.652 +static const static_codebook _16u1__p6_0 = {
 607.653 +        2, 81,
 607.654 +        (long *)_vq_lengthlist__16u1__p6_0,
 607.655 +        1, -531628032, 1611661312, 4, 0,
 607.656 +        (long *)_vq_quantlist__16u1__p6_0,
 607.657 +        0
 607.658 +};
 607.659 +
 607.660 +static const long _vq_quantlist__16u1__p7_0[] = {
 607.661 +        1,
 607.662 +        0,
 607.663 +        2,
 607.664 +};
 607.665 +
 607.666 +static const long _vq_lengthlist__16u1__p7_0[] = {
 607.667 +         1, 4, 4, 4, 8, 8, 4, 8, 8, 5,11, 9, 8,12,11, 8,
 607.668 +        12,11, 5,10,11, 8,11,12, 8,11,12, 4,11,11,11,14,
 607.669 +        13,10,13,13, 8,14,13,12,14,16,12,16,15, 8,14,14,
 607.670 +        13,16,14,12,15,16, 4,11,11,10,14,13,11,14,14, 8,
 607.671 +        15,14,12,15,15,12,14,16, 8,14,14,11,16,15,12,15,
 607.672 +        13,
 607.673 +};
 607.674 +
 607.675 +static const static_codebook _16u1__p7_0 = {
 607.676 +        4, 81,
 607.677 +        (long *)_vq_lengthlist__16u1__p7_0,
 607.678 +        1, -529137664, 1618345984, 2, 0,
 607.679 +        (long *)_vq_quantlist__16u1__p7_0,
 607.680 +        0
 607.681 +};
 607.682 +
 607.683 +static const long _vq_quantlist__16u1__p7_1[] = {
 607.684 +        5,
 607.685 +        4,
 607.686 +        6,
 607.687 +        3,
 607.688 +        7,
 607.689 +        2,
 607.690 +        8,
 607.691 +        1,
 607.692 +        9,
 607.693 +        0,
 607.694 +        10,
 607.695 +};
 607.696 +
 607.697 +static const long _vq_lengthlist__16u1__p7_1[] = {
 607.698 +         2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 6, 5, 7, 7,
 607.699 +         8, 8, 8, 8, 8, 8, 4, 5, 6, 7, 7, 8, 8, 8, 8, 8,
 607.700 +         8, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8,
 607.701 +         8, 8, 8, 9, 9, 9, 9, 7, 8, 8, 8, 8, 9, 9, 9,10,
 607.702 +         9,10, 7, 8, 8, 8, 8, 9, 9, 9, 9,10, 9, 8, 8, 8,
 607.703 +         9, 9,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9,10,
 607.704 +        10,10,10, 8, 8, 8, 9, 9, 9,10,10,10,10,10, 8, 8,
 607.705 +         8, 9, 9,10,10,10,10,10,10,
 607.706 +};
 607.707 +
 607.708 +static const static_codebook _16u1__p7_1 = {
 607.709 +        2, 121,
 607.710 +        (long *)_vq_lengthlist__16u1__p7_1,
 607.711 +        1, -531365888, 1611661312, 4, 0,
 607.712 +        (long *)_vq_quantlist__16u1__p7_1,
 607.713 +        0
 607.714 +};
 607.715 +
 607.716 +static const long _vq_quantlist__16u1__p8_0[] = {
 607.717 +        5,
 607.718 +        4,
 607.719 +        6,
 607.720 +        3,
 607.721 +        7,
 607.722 +        2,
 607.723 +        8,
 607.724 +        1,
 607.725 +        9,
 607.726 +        0,
 607.727 +        10,
 607.728 +};
 607.729 +
 607.730 +static const long _vq_lengthlist__16u1__p8_0[] = {
 607.731 +         1, 4, 4, 5, 5, 8, 8,10,10,12,12, 4, 7, 7, 8, 8,
 607.732 +         9, 9,12,11,14,13, 4, 7, 7, 7, 8, 9,10,11,11,13,
 607.733 +        12, 5, 8, 8, 9, 9,11,11,12,13,15,14, 5, 7, 8, 9,
 607.734 +         9,11,11,13,13,17,15, 8, 9,10,11,11,12,13,17,14,
 607.735 +        17,16, 8,10, 9,11,11,12,12,13,15,15,17,10,11,11,
 607.736 +        12,13,14,15,15,16,16,17, 9,11,11,12,12,14,15,17,
 607.737 +        15,15,16,11,14,12,14,15,16,15,16,16,16,15,11,13,
 607.738 +        13,14,14,15,15,16,16,15,16,
 607.739 +};
 607.740 +
 607.741 +static const static_codebook _16u1__p8_0 = {
 607.742 +        2, 121,
 607.743 +        (long *)_vq_lengthlist__16u1__p8_0,
 607.744 +        1, -524582912, 1618345984, 4, 0,
 607.745 +        (long *)_vq_quantlist__16u1__p8_0,
 607.746 +        0
 607.747 +};
 607.748 +
 607.749 +static const long _vq_quantlist__16u1__p8_1[] = {
 607.750 +        5,
 607.751 +        4,
 607.752 +        6,
 607.753 +        3,
 607.754 +        7,
 607.755 +        2,
 607.756 +        8,
 607.757 +        1,
 607.758 +        9,
 607.759 +        0,
 607.760 +        10,
 607.761 +};
 607.762 +
 607.763 +static const long _vq_lengthlist__16u1__p8_1[] = {
 607.764 +         2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 4, 6, 6, 7, 7,
 607.765 +         8, 7, 8, 8, 8, 8, 4, 6, 6, 7, 7, 7, 7, 8, 8, 8,
 607.766 +         8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 6, 7, 7, 7,
 607.767 +         7, 8, 8, 8, 8, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9,
 607.768 +         9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8,
 607.769 +         8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9,
 607.770 +         9, 9, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 8,
 607.771 +         8, 9, 9, 9, 9, 9, 9, 9, 9,
 607.772 +};
 607.773 +
 607.774 +static const static_codebook _16u1__p8_1 = {
 607.775 +        2, 121,
 607.776 +        (long *)_vq_lengthlist__16u1__p8_1,
 607.777 +        1, -531365888, 1611661312, 4, 0,
 607.778 +        (long *)_vq_quantlist__16u1__p8_1,
 607.779 +        0
 607.780 +};
 607.781 +
 607.782 +static const long _vq_quantlist__16u1__p9_0[] = {
 607.783 +        7,
 607.784 +        6,
 607.785 +        8,
 607.786 +        5,
 607.787 +        9,
 607.788 +        4,
 607.789 +        10,
 607.790 +        3,
 607.791 +        11,
 607.792 +        2,
 607.793 +        12,
 607.794 +        1,
 607.795 +        13,
 607.796 +        0,
 607.797 +        14,
 607.798 +};
 607.799 +
 607.800 +static const long _vq_lengthlist__16u1__p9_0[] = {
 607.801 +         1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.802 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.803 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.804 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.805 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.806 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.807 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.808 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.809 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.810 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.811 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.812 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.813 +         9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 607.814 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 607.815 +         8,
 607.816 +};
 607.817 +
 607.818 +static const static_codebook _16u1__p9_0 = {
 607.819 +        2, 225,
 607.820 +        (long *)_vq_lengthlist__16u1__p9_0,
 607.821 +        1, -514071552, 1627381760, 4, 0,
 607.822 +        (long *)_vq_quantlist__16u1__p9_0,
 607.823 +        0
 607.824 +};
 607.825 +
 607.826 +static const long _vq_quantlist__16u1__p9_1[] = {
 607.827 +        7,
 607.828 +        6,
 607.829 +        8,
 607.830 +        5,
 607.831 +        9,
 607.832 +        4,
 607.833 +        10,
 607.834 +        3,
 607.835 +        11,
 607.836 +        2,
 607.837 +        12,
 607.838 +        1,
 607.839 +        13,
 607.840 +        0,
 607.841 +        14,
 607.842 +};
 607.843 +
 607.844 +static const long _vq_lengthlist__16u1__p9_1[] = {
 607.845 +         1, 6, 5, 9, 9,10,10, 6, 7, 9, 9,10,10,10,10, 5,
 607.846 +        10, 8,10, 8,10,10, 8, 8,10, 9,10,10,10,10, 5, 8,
 607.847 +         9,10,10,10,10, 8,10,10,10,10,10,10,10, 9,10,10,
 607.848 +        10,10,10,10, 9, 9,10,10,10,10,10,10, 9, 9, 8, 9,
 607.849 +        10,10,10, 9,10,10,10,10,10,10,10,10,10,10,10,10,
 607.850 +        10,10,10,10,10,10,10,10,10,10,10, 8,10,10,10,10,
 607.851 +        10,10,10,10,10,10,10,10,10, 6, 8, 8,10,10,10, 8,
 607.852 +        10,10,10,10,10,10,10,10, 5, 8, 8,10,10,10, 9, 9,
 607.853 +        10,10,10,10,10,10,10,10, 9,10,10,10,10,10,10,10,
 607.854 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
 607.855 +        10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,
 607.856 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.857 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.858 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 607.859 +         9,
 607.860 +};
 607.861 +
 607.862 +static const static_codebook _16u1__p9_1 = {
 607.863 +        2, 225,
 607.864 +        (long *)_vq_lengthlist__16u1__p9_1,
 607.865 +        1, -522338304, 1620115456, 4, 0,
 607.866 +        (long *)_vq_quantlist__16u1__p9_1,
 607.867 +        0
 607.868 +};
 607.869 +
 607.870 +static const long _vq_quantlist__16u1__p9_2[] = {
 607.871 +        8,
 607.872 +        7,
 607.873 +        9,
 607.874 +        6,
 607.875 +        10,
 607.876 +        5,
 607.877 +        11,
 607.878 +        4,
 607.879 +        12,
 607.880 +        3,
 607.881 +        13,
 607.882 +        2,
 607.883 +        14,
 607.884 +        1,
 607.885 +        15,
 607.886 +        0,
 607.887 +        16,
 607.888 +};
 607.889 +
 607.890 +static const long _vq_lengthlist__16u1__p9_2[] = {
 607.891 +         1, 6, 6, 7, 8, 8,11,10, 9, 9,11, 9,10, 9,11,11,
 607.892 +         9, 6, 7, 6,11, 8,11, 9,10,10,11, 9,11,10,10,10,
 607.893 +        11, 9, 5, 7, 7, 8, 8,10,11, 8, 8,11, 9, 9,10,11,
 607.894 +         9,10,11, 8, 9, 6, 8, 8, 9, 9,10,10,11,11,11, 9,
 607.895 +        11,10, 9,11, 8, 8, 8, 9, 8, 9,10,11, 9, 9,11,11,
 607.896 +        10, 9, 9,11,10, 8,11, 8, 9, 8,11, 9,10, 9,10,11,
 607.897 +        11,10,10, 9,10,10, 8, 8, 9,10,10,10, 9,11, 9,10,
 607.898 +        11,11,11,11,10, 9,11, 9, 9,11,11,10, 8,11,11,11,
 607.899 +         9,10,10,11,10,11,11, 9,11,10, 9,11,10,10,10,10,
 607.900 +         9,11,10,11,10, 9, 9,10,11, 9, 8,10,11,11,10,10,
 607.901 +        11, 9,11,10,11,11,10,11, 9, 9, 8,10, 8, 9,11, 9,
 607.902 +         8,10,10, 9,11,10,11,10,11, 9,11, 8,10,11,11,11,
 607.903 +        11,10,10,11,11,11,11,10,11,11,10, 9, 8,10,10, 9,
 607.904 +        11,10,11,11,11, 9, 9, 9,11,11,11,10,10, 9, 9,10,
 607.905 +         9,11,11,11,11, 8,10,11,10,11,11,10,11,11, 9, 9,
 607.906 +         9,10, 9,11, 9,11,11,11,11,11,10,11,11,10,11,10,
 607.907 +        11,11, 9,11,10,11,10, 9,10, 9,10,10,11,11,11,11,
 607.908 +         9,10, 9,10,11,11,10,11,11,11,11,11,11,10,11,11,
 607.909 +        10,
 607.910 +};
 607.911 +
 607.912 +static const static_codebook _16u1__p9_2 = {
 607.913 +        2, 289,
 607.914 +        (long *)_vq_lengthlist__16u1__p9_2,
 607.915 +        1, -529530880, 1611661312, 5, 0,
 607.916 +        (long *)_vq_quantlist__16u1__p9_2,
 607.917 +        0
 607.918 +};
 607.919 +
 607.920 +static const long _huff_lengthlist__16u1__short[] = {
 607.921 +         5, 7,10, 9,11,10,15,11,13,16, 6, 4, 6, 6, 7, 7,
 607.922 +        10, 9,12,16,10, 6, 5, 6, 6, 7,10,11,16,16, 9, 6,
 607.923 +         7, 6, 7, 7,10, 8,14,16,11, 6, 5, 4, 5, 6, 8, 9,
 607.924 +        15,16, 9, 6, 6, 5, 6, 6, 9, 8,14,16,12, 7, 6, 6,
 607.925 +         5, 6, 6, 7,13,16, 8, 6, 7, 6, 5, 5, 4, 4,11,16,
 607.926 +         9, 8, 9, 9, 7, 7, 6, 5,13,16,14,14,16,15,16,15,
 607.927 +        16,16,16,16,
 607.928 +};
 607.929 +
 607.930 +static const static_codebook _huff_book__16u1__short = {
 607.931 +        2, 100,
 607.932 +        (long *)_huff_lengthlist__16u1__short,
 607.933 +        0, 0, 0, 0, 0,
 607.934 +        NULL,
 607.935 +        0
 607.936 +};
 607.937 +
 607.938 +static const long _huff_lengthlist__16u2__long[] = {
 607.939 +	 5, 8,10,10,10,11,11,12,14,18, 7, 5, 5, 6, 8, 9,
 607.940 +	10,12,14,17, 9, 5, 4, 5, 6, 8,10,11,13,19, 9, 5,
 607.941 +	 4, 4, 5, 6, 9,10,12,17, 8, 6, 5, 4, 4, 5, 7,10,
 607.942 +	11,15, 8, 7, 7, 6, 5, 5, 6, 9,11,14, 8, 9, 8, 7,
 607.943 +	 6, 5, 6, 7,11,14, 9,11,11, 9, 7, 6, 6, 6, 9,14,
 607.944 +	11,14,15,13, 9, 8, 7, 7, 9,14,13,15,19,17,12,11,
 607.945 +	10, 9,10,14,
 607.946 +};
 607.947 +
 607.948 +static const static_codebook _huff_book__16u2__long = {
 607.949 +	2, 100,
 607.950 +	(long *)_huff_lengthlist__16u2__long,
 607.951 +	0, 0, 0, 0, 0,
 607.952 +	NULL,
 607.953 +	0
 607.954 +};
 607.955 +
 607.956 +static const long _vq_quantlist__16u2_p1_0[] = {
 607.957 +	1,
 607.958 +	0,
 607.959 +	2,
 607.960 +};
 607.961 +
 607.962 +static const long _vq_lengthlist__16u2_p1_0[] = {
 607.963 +	 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 9, 9, 7,
 607.964 +	 9, 9, 5, 7, 7, 7, 9, 9, 8, 9, 9, 5, 7, 7, 8, 9,
 607.965 +	 9, 7, 9, 9, 7, 9, 9, 9,10,11, 9,10,10, 7, 9, 9,
 607.966 +	 9,10, 9, 9,10,11, 5, 8, 7, 7, 9, 9, 8, 9, 9, 7,
 607.967 +	 9, 9, 9,11,10, 9, 9,10, 7, 9, 9, 9,10,10, 9,11,
 607.968 +	10,
 607.969 +};
 607.970 +
 607.971 +static const static_codebook _16u2_p1_0 = {
 607.972 +	4, 81,
 607.973 +	(long *)_vq_lengthlist__16u2_p1_0,
 607.974 +	1, -535822336, 1611661312, 2, 0,
 607.975 +	(long *)_vq_quantlist__16u2_p1_0,
 607.976 +	0
 607.977 +};
 607.978 +
 607.979 +static const long _vq_quantlist__16u2_p2_0[] = {
 607.980 +	2,
 607.981 +	1,
 607.982 +	3,
 607.983 +	0,
 607.984 +	4,
 607.985 +};
 607.986 +
 607.987 +static const long _vq_lengthlist__16u2_p2_0[] = {
 607.988 +	 3, 5, 5, 8, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 9,
 607.989 +	10, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8,
 607.990 +	 8,10,10, 7, 8, 8,10,10,10,10,10,12,12, 9,10,10,
 607.991 +	11,12, 5, 7, 7, 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,
 607.992 +	10, 9,10,10,12,11,10,10,10,12,12, 9,10,10,12,12,
 607.993 +	10,10,10,12,12, 9,10,10,12,12,12,12,12,14,14,11,
 607.994 +	12,12,13,14, 9,10,10,12,12, 9,10,10,12,12,10,10,
 607.995 +	10,12,12,11,12,12,14,13,12,12,12,14,13, 5, 7, 7,
 607.996 +	 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,
 607.997 +	12,10,10,10,12,12, 7, 8, 8,11,10, 8, 9, 9,11,11,
 607.998 +	 8, 9, 9,11,11,10,11,11,12,13,10,11,11,12,13, 7,
 607.999 +	 8, 8,10,10, 8, 9, 8,11,10, 8, 9, 9,11,11,10,11,
607.1000 +	10,13,12,10,11,11,13,13,10,11,10,13,12,10,11,11,
607.1001 +	13,13,10,11,11,13,13,12,12,13,13,14,12,13,13,14,
607.1002 +	14, 9,10,10,12,12,10,11,10,13,12,10,11,11,13,13,
607.1003 +	12,13,12,14,13,12,13,13,14,15, 5, 7, 7, 9,10, 7,
607.1004 +	 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,12,10,10,
607.1005 +	11,12,12, 7, 8, 8,10,10, 8, 9, 9,11,11, 8, 8, 9,
607.1006 +	10,11,10,11,11,13,13,10,10,11,12,13, 7, 8, 8,10,
607.1007 +	10, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,11,13,12,
607.1008 +	10,11,11,13,12, 9,10,10,12,12,10,11,11,13,13,10,
607.1009 +	10,11,12,13,12,13,13,15,14,12,12,13,12,14, 9,10,
607.1010 +	11,12,13,10,11,11,13,13,10,11,11,13,13,12,13,13,
607.1011 +	14,14,12,13,12,14,13, 8,10,10,12,12, 9,11,10,13,
607.1012 +	12, 9,10,10,12,13,12,13,13,14,14,12,12,12,14,14,
607.1013 +	 9,10,10,13,13,10,11,11,13,13,10,11,11,13,13,13,
607.1014 +	13,13,14,15,12,13,13,14,15, 9,10,10,12,13,10,11,
607.1015 +	10,13,13,10,11,11,12,13,12,13,12,15,14,12,13,13,
607.1016 +	14,15,11,12,12,15,14,12,12,13,14,15,12,13,13,15,
607.1017 +	14,13,13,15,14,16,14,14,14,16,15,11,12,12,14,14,
607.1018 +	11,12,12,14,14,12,13,13,14,15,13,14,13,15,13,14,
607.1019 +	14,14,15,16, 8, 9,10,12,12, 9,10,10,13,12, 9,10,
607.1020 +	11,12,13,12,12,12,14,14,12,13,13,14,14, 9,10,10,
607.1021 +	13,12,10,11,11,13,13,10,10,11,13,13,12,13,13,15,
607.1022 +	14,12,12,13,14,15, 9,10,10,13,13,10,11,11,13,13,
607.1023 +	10,11,11,13,13,12,13,13,14,14,13,13,13,15,15,11,
607.1024 +	12,12,14,13,12,13,13,15,14,11,12,12,14,14,14,14,
607.1025 +	14,16,15,13,13,14,13,16,11,12,12,14,14,12,13,13,
607.1026 +	14,15,12,13,12,14,14,14,14,14,16,16,14,15,13,16,
607.1027 +	14,
607.1028 +};
607.1029 +
607.1030 +static const static_codebook _16u2_p2_0 = {
607.1031 +	4, 625,
607.1032 +	(long *)_vq_lengthlist__16u2_p2_0,
607.1033 +	1, -533725184, 1611661312, 3, 0,
607.1034 +	(long *)_vq_quantlist__16u2_p2_0,
607.1035 +	0
607.1036 +};
607.1037 +
607.1038 +static const long _vq_quantlist__16u2_p3_0[] = {
607.1039 +	4,
607.1040 +	3,
607.1041 +	5,
607.1042 +	2,
607.1043 +	6,
607.1044 +	1,
607.1045 +	7,
607.1046 +	0,
607.1047 +	8,
607.1048 +};
607.1049 +
607.1050 +static const long _vq_lengthlist__16u2_p3_0[] = {
607.1051 +	 2, 4, 4, 6, 6, 7, 7, 9, 9, 4, 5, 5, 6, 6, 8, 7,
607.1052 +	 9, 9, 4, 5, 5, 6, 6, 7, 8, 9, 9, 6, 6, 6, 7, 7,
607.1053 +	 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8,10,10, 7, 8, 7,
607.1054 +	 8, 8, 9, 9,11,10, 7, 7, 8, 8, 8, 9, 9,10,11, 9,
607.1055 +	 9, 9,10,10,11,10,11,11, 9, 9, 9,10,10,10,11,11,
607.1056 +	11,
607.1057 +};
607.1058 +
607.1059 +static const static_codebook _16u2_p3_0 = {
607.1060 +	2, 81,
607.1061 +	(long *)_vq_lengthlist__16u2_p3_0,
607.1062 +	1, -531628032, 1611661312, 4, 0,
607.1063 +	(long *)_vq_quantlist__16u2_p3_0,
607.1064 +	0
607.1065 +};
607.1066 +
607.1067 +static const long _vq_quantlist__16u2_p4_0[] = {
607.1068 +	8,
607.1069 +	7,
607.1070 +	9,
607.1071 +	6,
607.1072 +	10,
607.1073 +	5,
607.1074 +	11,
607.1075 +	4,
607.1076 +	12,
607.1077 +	3,
607.1078 +	13,
607.1079 +	2,
607.1080 +	14,
607.1081 +	1,
607.1082 +	15,
607.1083 +	0,
607.1084 +	16,
607.1085 +};
607.1086 +
607.1087 +static const long _vq_lengthlist__16u2_p4_0[] = {
607.1088 +	 2, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,11,
607.1089 +	11, 5, 5, 5, 7, 6, 8, 7, 9, 9, 9, 9,10,10,11,11,
607.1090 +	12,12, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 9,10,10,11,
607.1091 +	11,12,12, 6, 7, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
607.1092 +	11,11,12,12, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,
607.1093 +	10,11,11,12,12, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,
607.1094 +	11,11,11,11,12,12, 7, 7, 8, 8, 8, 9, 9, 9, 9,10,
607.1095 +	10,11,11,11,11,12,12, 8, 9, 9, 9, 9, 9, 9,10,10,
607.1096 +	10,10,11,11,12,12,12,12, 8, 9, 9, 9, 9, 9, 9,10,
607.1097 +	10,10,10,11,11,12,12,12,12, 9, 9, 9, 9, 9,10,10,
607.1098 +	10,10,10,11,11,11,12,12,13,13, 9, 9, 9, 9, 9,10,
607.1099 +	10,10,10,11,10,11,11,12,12,13,13,10,10,10,10,10,
607.1100 +	11,11,11,11,11,11,11,12,12,12,13,13,10,10,10,10,
607.1101 +	10,11,11,11,11,11,11,12,11,12,12,13,13,11,11,11,
607.1102 +	11,11,11,11,12,12,12,12,12,12,13,13,13,13,11,11,
607.1103 +	11,11,11,11,11,12,12,12,12,13,12,13,13,13,13,11,
607.1104 +	12,12,12,12,12,12,12,12,13,13,13,13,13,13,14,14,
607.1105 +	11,12,12,12,12,12,12,12,13,13,13,13,13,13,13,14,
607.1106 +	14,
607.1107 +};
607.1108 +
607.1109 +static const static_codebook _16u2_p4_0 = {
607.1110 +	2, 289,
607.1111 +	(long *)_vq_lengthlist__16u2_p4_0,
607.1112 +	1, -529530880, 1611661312, 5, 0,
607.1113 +	(long *)_vq_quantlist__16u2_p4_0,
607.1114 +	0
607.1115 +};
607.1116 +
607.1117 +static const long _vq_quantlist__16u2_p5_0[] = {
607.1118 +	1,
607.1119 +	0,
607.1120 +	2,
607.1121 +};
607.1122 +
607.1123 +static const long _vq_lengthlist__16u2_p5_0[] = {
607.1124 +	 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 7, 9, 9, 7,
607.1125 +	 9,10, 5, 8, 8, 7,10, 9, 7,10, 9, 5, 8, 8, 8,11,
607.1126 +	10, 8,10,10, 7,10,10, 9, 9,12,10,12,12, 7,10,10,
607.1127 +	 9,12,10,10,11,12, 5, 8, 8, 8,10,10, 8,11,11, 7,
607.1128 +	11,10,10,12,11, 9,10,12, 7,10,11,10,12,12, 9,12,
607.1129 +	 9,
607.1130 +};
607.1131 +
607.1132 +static const static_codebook _16u2_p5_0 = {
607.1133 +	4, 81,
607.1134 +	(long *)_vq_lengthlist__16u2_p5_0,
607.1135 +	1, -529137664, 1618345984, 2, 0,
607.1136 +	(long *)_vq_quantlist__16u2_p5_0,
607.1137 +	0
607.1138 +};
607.1139 +
607.1140 +static const long _vq_quantlist__16u2_p5_1[] = {
607.1141 +	5,
607.1142 +	4,
607.1143 +	6,
607.1144 +	3,
607.1145 +	7,
607.1146 +	2,
607.1147 +	8,
607.1148 +	1,
607.1149 +	9,
607.1150 +	0,
607.1151 +	10,
607.1152 +};
607.1153 +
607.1154 +static const long _vq_lengthlist__16u2_p5_1[] = {
607.1155 +	 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 5, 6, 6, 7, 7,
607.1156 +	 7, 7, 8, 8, 8, 8, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
607.1157 +	 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7,
607.1158 +	 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8,
607.1159 +	 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
607.1160 +	 8, 8, 8, 8, 8, 8, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8,
607.1161 +	 8, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8,
607.1162 +	 8, 8, 8, 8, 8, 9, 9, 9, 9,
607.1163 +};
607.1164 +
607.1165 +static const static_codebook _16u2_p5_1 = {
607.1166 +	2, 121,
607.1167 +	(long *)_vq_lengthlist__16u2_p5_1,
607.1168 +	1, -531365888, 1611661312, 4, 0,
607.1169 +	(long *)_vq_quantlist__16u2_p5_1,
607.1170 +	0
607.1171 +};
607.1172 +
607.1173 +static const long _vq_quantlist__16u2_p6_0[] = {
607.1174 +	6,
607.1175 +	5,
607.1176 +	7,
607.1177 +	4,
607.1178 +	8,
607.1179 +	3,
607.1180 +	9,
607.1181 +	2,
607.1182 +	10,
607.1183 +	1,
607.1184 +	11,
607.1185 +	0,
607.1186 +	12,
607.1187 +};
607.1188 +
607.1189 +static const long _vq_lengthlist__16u2_p6_0[] = {
607.1190 +	 1, 5, 4, 7, 7, 8, 8, 8, 8,10,10,11,11, 4, 6, 6,
607.1191 +	 7, 7, 9, 9, 9, 9,10,10,11,11, 4, 6, 6, 7, 7, 9,
607.1192 +	 9, 9, 9,10,10,11,11, 7, 8, 8, 9, 9, 9, 9,10,10,
607.1193 +	11,11,12,12, 7, 7, 7, 9, 8,10, 9,10,10,11,11,12,
607.1194 +	12, 8, 9, 9, 9,10,10,10,11,11,12,12,13,13, 8, 9,
607.1195 +	 9,10, 9,10,10,11,11,12,12,13,13, 8, 9, 9,10,10,
607.1196 +	11,11,11,11,12,12,13,13, 8, 9, 9,10,10,11,11,12,
607.1197 +	11,12,12,13,13,10,10,10,11,11,12,12,12,12,13,13,
607.1198 +	14,14,10,10,10,11,11,12,12,12,12,13,13,14,14,11,
607.1199 +	11,11,12,12,13,13,13,13,14,14,14,14,11,11,11,12,
607.1200 +	12,13,13,13,13,14,14,14,14,
607.1201 +};
607.1202 +
607.1203 +static const static_codebook _16u2_p6_0 = {
607.1204 +	2, 169,
607.1205 +	(long *)_vq_lengthlist__16u2_p6_0,
607.1206 +	1, -526516224, 1616117760, 4, 0,
607.1207 +	(long *)_vq_quantlist__16u2_p6_0,
607.1208 +	0
607.1209 +};
607.1210 +
607.1211 +static const long _vq_quantlist__16u2_p6_1[] = {
607.1212 +	2,
607.1213 +	1,
607.1214 +	3,
607.1215 +	0,
607.1216 +	4,
607.1217 +};
607.1218 +
607.1219 +static const long _vq_lengthlist__16u2_p6_1[] = {
607.1220 +	 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
607.1221 +	 5, 5, 5, 5, 5, 5, 5, 5, 5,
607.1222 +};
607.1223 +
607.1224 +static const static_codebook _16u2_p6_1 = {
607.1225 +	2, 25,
607.1226 +	(long *)_vq_lengthlist__16u2_p6_1,
607.1227 +	1, -533725184, 1611661312, 3, 0,
607.1228 +	(long *)_vq_quantlist__16u2_p6_1,
607.1229 +	0
607.1230 +};
607.1231 +
607.1232 +static const long _vq_quantlist__16u2_p7_0[] = {
607.1233 +	6,
607.1234 +	5,
607.1235 +	7,
607.1236 +	4,
607.1237 +	8,
607.1238 +	3,
607.1239 +	9,
607.1240 +	2,
607.1241 +	10,
607.1242 +	1,
607.1243 +	11,
607.1244 +	0,
607.1245 +	12,
607.1246 +};
607.1247 +
607.1248 +static const long _vq_lengthlist__16u2_p7_0[] = {
607.1249 +	 1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 6, 6,
607.1250 +	 8, 8, 9, 9, 9, 9,10,10,11,10, 4, 6, 6, 8, 8, 9,
607.1251 +	 9, 9, 9,10,10,11,11, 7, 8, 8,10, 9,10,10,10,10,
607.1252 +	11,11,12,12, 7, 8, 8,10,10,10,10,10,10,11,11,12,
607.1253 +	12, 8, 9, 9,10,10,11,11,11,11,12,12,13,13, 8, 9,
607.1254 +	 9,10,10,11,11,11,11,12,12,13,13, 8, 9, 9,11,10,
607.1255 +	11,11,12,12,13,13,14,13, 8, 9, 9,10,10,11,11,12,
607.1256 +	12,13,13,13,13, 9,10,10,11,11,12,12,13,13,13,13,
607.1257 +	14,14, 9,10,10,11,11,12,12,13,13,13,13,14,14,10,
607.1258 +	11,11,12,12,13,13,14,13,14,14,15,14,10,11,11,12,
607.1259 +	12,13,13,14,13,14,14,15,14,
607.1260 +};
607.1261 +
607.1262 +static const static_codebook _16u2_p7_0 = {
607.1263 +	2, 169,
607.1264 +	(long *)_vq_lengthlist__16u2_p7_0,
607.1265 +	1, -523206656, 1618345984, 4, 0,
607.1266 +	(long *)_vq_quantlist__16u2_p7_0,
607.1267 +	0
607.1268 +};
607.1269 +
607.1270 +static const long _vq_quantlist__16u2_p7_1[] = {
607.1271 +	5,
607.1272 +	4,
607.1273 +	6,
607.1274 +	3,
607.1275 +	7,
607.1276 +	2,
607.1277 +	8,
607.1278 +	1,
607.1279 +	9,
607.1280 +	0,
607.1281 +	10,
607.1282 +};
607.1283 +
607.1284 +static const long _vq_lengthlist__16u2_p7_1[] = {
607.1285 +	 2, 5, 5, 7, 7, 7, 7, 7, 7, 8, 8, 5, 6, 6, 7, 7,
607.1286 +	 7, 7, 8, 8, 8, 8, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8,
607.1287 +	 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7,
607.1288 +	 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8,
607.1289 +	 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8,
607.1290 +	 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8,
607.1291 +	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
607.1292 +	 8, 8, 8, 8, 8, 8, 8, 8, 8,
607.1293 +};
607.1294 +
607.1295 +static const static_codebook _16u2_p7_1 = {
607.1296 +	2, 121,
607.1297 +	(long *)_vq_lengthlist__16u2_p7_1,
607.1298 +	1, -531365888, 1611661312, 4, 0,
607.1299 +	(long *)_vq_quantlist__16u2_p7_1,
607.1300 +	0
607.1301 +};
607.1302 +
607.1303 +static const long _vq_quantlist__16u2_p8_0[] = {
607.1304 +	7,
607.1305 +	6,
607.1306 +	8,
607.1307 +	5,
607.1308 +	9,
607.1309 +	4,
607.1310 +	10,
607.1311 +	3,
607.1312 +	11,
607.1313 +	2,
607.1314 +	12,
607.1315 +	1,
607.1316 +	13,
607.1317 +	0,
607.1318 +	14,
607.1319 +};
607.1320 +
607.1321 +static const long _vq_lengthlist__16u2_p8_0[] = {
607.1322 +	 1, 4, 4, 7, 7, 8, 8, 7, 7, 9, 8,10, 9,11,11, 4,
607.1323 +	 7, 6, 9, 8, 9, 9, 9, 9,10, 9,11, 9,12, 9, 4, 6,
607.1324 +	 7, 8, 8, 9, 9, 9, 9,10,10,10,11,11,12, 7, 9, 8,
607.1325 +	10,10,11,11,10,10,11,11,12,12,13,12, 7, 8, 8,10,
607.1326 +	10,10,11,10,10,11,11,11,12,12,13, 8, 9, 9,11,11,
607.1327 +	11,11,11,11,12,12,13,13,13,13, 8, 9, 9,11,11,11,
607.1328 +	11,11,11,12,12,13,13,13,14, 8, 9, 9,10,10,11,11,
607.1329 +	12,11,13,13,14,13,14,14, 8, 9, 9,10,10,11,11,12,
607.1330 +	12,12,12,13,13,14,14, 9,10,10,11,11,12,12,13,12,
607.1331 +	13,13,14,14,15,15, 9,10,10,11,11,12,12,12,13,13,
607.1332 +	13,14,14,14,15,10,11,11,12,12,13,13,14,13,14,14,
607.1333 +	15,14,15,15,10,11,11,12,12,13,12,13,14,14,14,14,
607.1334 +	14,15,15,11,12,12,13,13,13,13,14,14,15,14,15,15,
607.1335 +	16,16,11,12,12,13,13,13,13,14,14,14,15,15,15,16,
607.1336 +	16,
607.1337 +};
607.1338 +
607.1339 +static const static_codebook _16u2_p8_0 = {
607.1340 +	2, 225,
607.1341 +	(long *)_vq_lengthlist__16u2_p8_0,
607.1342 +	1, -520986624, 1620377600, 4, 0,
607.1343 +	(long *)_vq_quantlist__16u2_p8_0,
607.1344 +	0
607.1345 +};
607.1346 +
607.1347 +static const long _vq_quantlist__16u2_p8_1[] = {
607.1348 +	10,
607.1349 +	9,
607.1350 +	11,
607.1351 +	8,
607.1352 +	12,
607.1353 +	7,
607.1354 +	13,
607.1355 +	6,
607.1356 +	14,
607.1357 +	5,
607.1358 +	15,
607.1359 +	4,
607.1360 +	16,
607.1361 +	3,
607.1362 +	17,
607.1363 +	2,
607.1364 +	18,
607.1365 +	1,
607.1366 +	19,
607.1367 +	0,
607.1368 +	20,
607.1369 +};
607.1370 +
607.1371 +static const long _vq_lengthlist__16u2_p8_1[] = {
607.1372 +	 3, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
607.1373 +	 9, 9, 9, 9, 9, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,
607.1374 +	 9, 9, 9, 9, 9, 9,10,10,10,10, 5, 6, 6, 7, 7, 8,
607.1375 +	 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7,
607.1376 +	 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,
607.1377 +	10,10,10,10, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9,
607.1378 +	 9,10, 9,10,10,10, 9,10, 9, 8, 8, 8, 9, 8, 9, 9,
607.1379 +	 9, 9,10, 9,10,10,10,10,10,10,10,10,10,10, 8, 8,
607.1380 +	 8, 8, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,
607.1381 +	10,10,10, 8, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,
607.1382 +	10,10,10,10,10,10,10,10, 8, 9, 9, 9, 9, 9, 9, 9,
607.1383 +	10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
607.1384 +	 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,
607.1385 +	10,10, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,
607.1386 +	10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,10,10,10,
607.1387 +	10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
607.1388 +	 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1389 +	10, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,
607.1390 +	10,10,10,10,10,10, 9, 9, 9,10,10,10,10,10,10,10,
607.1391 +	10,10,10,10,10,10,10,10,10,10,10, 9, 9,10,10,10,
607.1392 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1393 +	 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1394 +	10,10,10,10,10, 9,10,10,10,10,10,10,10,10,10,10,
607.1395 +	10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10,10,
607.1396 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,
607.1397 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1398 +	10,10,10,10, 9,10,10,10,10,10,10,10,10,10,10,10,
607.1399 +	10,10,10,10,10,10,10,10,10,
607.1400 +};
607.1401 +
607.1402 +static const static_codebook _16u2_p8_1 = {
607.1403 +	2, 441,
607.1404 +	(long *)_vq_lengthlist__16u2_p8_1,
607.1405 +	1, -529268736, 1611661312, 5, 0,
607.1406 +	(long *)_vq_quantlist__16u2_p8_1,
607.1407 +	0
607.1408 +};
607.1409 +
607.1410 +static const long _vq_quantlist__16u2_p9_0[] = {
607.1411 +	7,
607.1412 +	6,
607.1413 +	8,
607.1414 +	5,
607.1415 +	9,
607.1416 +	4,
607.1417 +	10,
607.1418 +	3,
607.1419 +	11,
607.1420 +	2,
607.1421 +	12,
607.1422 +	1,
607.1423 +	13,
607.1424 +	0,
607.1425 +	14,
607.1426 +};
607.1427 +
607.1428 +static const long _vq_lengthlist__16u2_p9_0[] = {
607.1429 +	 1, 5, 3, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5,
607.1430 +	 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 7,
607.1431 +	 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.1432 +	 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,
607.1433 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1434 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1435 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1436 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1437 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1438 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1439 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1440 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1441 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1442 +	10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1443 +	10,
607.1444 +};
607.1445 +
607.1446 +static const static_codebook _16u2_p9_0 = {
607.1447 +	2, 225,
607.1448 +	(long *)_vq_lengthlist__16u2_p9_0,
607.1449 +	1, -510036736, 1631393792, 4, 0,
607.1450 +	(long *)_vq_quantlist__16u2_p9_0,
607.1451 +	0
607.1452 +};
607.1453 +
607.1454 +static const long _vq_quantlist__16u2_p9_1[] = {
607.1455 +	9,
607.1456 +	8,
607.1457 +	10,
607.1458 +	7,
607.1459 +	11,
607.1460 +	6,
607.1461 +	12,
607.1462 +	5,
607.1463 +	13,
607.1464 +	4,
607.1465 +	14,
607.1466 +	3,
607.1467 +	15,
607.1468 +	2,
607.1469 +	16,
607.1470 +	1,
607.1471 +	17,
607.1472 +	0,
607.1473 +	18,
607.1474 +};
607.1475 +
607.1476 +static const long _vq_lengthlist__16u2_p9_1[] = {
607.1477 +	 1, 4, 4, 7, 7, 7, 7, 7, 6, 9, 7,10, 8,12,12,13,
607.1478 +	13,14,14, 4, 7, 7, 9, 9, 9, 8, 9, 8,10, 9,11, 9,
607.1479 +	14, 9,14,10,13,11, 4, 7, 7, 9, 9, 9, 9, 8, 9,10,
607.1480 +	10,11,11,12,13,12,13,14,15, 7, 9, 9,10,11,10,10,
607.1481 +	10,10,11,12,13,13,13,14,17,14,15,16, 7, 9, 9,10,
607.1482 +	10,10,10,10,10,11,12,13,13,14,14,15,15,18,18, 8,
607.1483 +	 9, 9,11,10,11,11,11,12,13,12,14,14,16,15,15,17,
607.1484 +	18,15, 8, 9, 9,10,10,11,11,11,11,13,13,14,14,15,
607.1485 +	15,15,16,16,18, 7, 9, 8,10,10,11,11,12,12,14,14,
607.1486 +	15,15,16,16,15,17,16,18, 8, 9, 9,10,10,11,12,12,
607.1487 +	12,13,13,16,15,17,16,17,18,17,18, 9,10,10,12,11,
607.1488 +	13,13,14,13,14,14,15,17,16,18,17,18,17,18, 9,10,
607.1489 +	10,12,11,12,13,13,14,15,16,14,15,16,18,18,18,18,
607.1490 +	17,11,11,11,13,13,14,14,16,15,15,15,16,15,15,18,
607.1491 +	18,18,17,16,11,11,12,13,13,15,14,15,16,16,16,17,
607.1492 +	16,15,18,17,18,16,18,12,13,13,15,15,15,16,18,16,
607.1493 +	17,16,17,16,17,17,17,18,18,17,13,13,13,15,13,16,
607.1494 +	15,17,16,16,16,18,18,18,18,16,17,17,18,13,15,14,
607.1495 +	15,15,18,17,18,18,18,16,18,17,18,17,18,16,17,17,
607.1496 +	14,14,14,15,16,17,16,18,18,18,17,18,17,18,18,18,
607.1497 +	16,16,16,14,17,16,17,15,16,18,18,17,18,17,18,17,
607.1498 +	18,18,18,17,18,17,15,16,15,18,15,18,17,16,18,18,
607.1499 +	18,18,18,18,17,18,16,18,17,
607.1500 +};
607.1501 +
607.1502 +static const static_codebook _16u2_p9_1 = {
607.1503 +	2, 361,
607.1504 +	(long *)_vq_lengthlist__16u2_p9_1,
607.1505 +	1, -518287360, 1622704128, 5, 0,
607.1506 +	(long *)_vq_quantlist__16u2_p9_1,
607.1507 +	0
607.1508 +};
607.1509 +
607.1510 +static const long _vq_quantlist__16u2_p9_2[] = {
607.1511 +	24,
607.1512 +	23,
607.1513 +	25,
607.1514 +	22,
607.1515 +	26,
607.1516 +	21,
607.1517 +	27,
607.1518 +	20,
607.1519 +	28,
607.1520 +	19,
607.1521 +	29,
607.1522 +	18,
607.1523 +	30,
607.1524 +	17,
607.1525 +	31,
607.1526 +	16,
607.1527 +	32,
607.1528 +	15,
607.1529 +	33,
607.1530 +	14,
607.1531 +	34,
607.1532 +	13,
607.1533 +	35,
607.1534 +	12,
607.1535 +	36,
607.1536 +	11,
607.1537 +	37,
607.1538 +	10,
607.1539 +	38,
607.1540 +	9,
607.1541 +	39,
607.1542 +	8,
607.1543 +	40,
607.1544 +	7,
607.1545 +	41,
607.1546 +	6,
607.1547 +	42,
607.1548 +	5,
607.1549 +	43,
607.1550 +	4,
607.1551 +	44,
607.1552 +	3,
607.1553 +	45,
607.1554 +	2,
607.1555 +	46,
607.1556 +	1,
607.1557 +	47,
607.1558 +	0,
607.1559 +	48,
607.1560 +};
607.1561 +
607.1562 +static const long _vq_lengthlist__16u2_p9_2[] = {
607.1563 +	 2, 3, 4, 4, 4, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 7,
607.1564 +	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.1565 +	 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 7, 8, 8, 8, 8, 8,
607.1566 +	 8,
607.1567 +};
607.1568 +
607.1569 +static const static_codebook _16u2_p9_2 = {
607.1570 +	1, 49,
607.1571 +	(long *)_vq_lengthlist__16u2_p9_2,
607.1572 +	1, -526909440, 1611661312, 6, 0,
607.1573 +	(long *)_vq_quantlist__16u2_p9_2,
607.1574 +	0
607.1575 +};
607.1576 +
607.1577 +static const long _huff_lengthlist__16u2__short[] = {
607.1578 +	 8,11,13,13,15,16,19,19,19,19,11, 8, 8, 9, 9,11,
607.1579 +	13,15,19,20,14, 8, 7, 7, 8, 9,12,13,15,20,15, 9,
607.1580 +	 6, 5, 5, 7,10,12,14,18,14, 9, 7, 5, 3, 4, 7,10,
607.1581 +	12,16,13,10, 8, 6, 3, 3, 5, 8,11,14,11,10, 9, 7,
607.1582 +	 5, 4, 4, 6,11,14,10,10,10, 8, 6, 5, 5, 6,10,14,
607.1583 +	10,10,10, 9, 8, 7, 7, 7,10,14,11,12,12,12,11,10,
607.1584 +	10,10,12,16,
607.1585 +};
607.1586 +
607.1587 +static const static_codebook _huff_book__16u2__short = {
607.1588 +	2, 100,
607.1589 +	(long *)_huff_lengthlist__16u2__short,
607.1590 +	0, 0, 0, 0, 0,
607.1591 +	NULL,
607.1592 +	0
607.1593 +};
607.1594 +
607.1595 +static const long _vq_quantlist__8u0__p1_0[] = {
607.1596 +        1,
607.1597 +        0,
607.1598 +        2,
607.1599 +};
607.1600 +
607.1601 +static const long _vq_lengthlist__8u0__p1_0[] = {
607.1602 +         1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7,
607.1603 +        10,10, 5, 8, 8, 7,10,10, 8,10,10, 4, 9, 8, 8,11,
607.1604 +        11, 8,11,11, 7,11,11,10,11,13,10,13,13, 7,11,11,
607.1605 +        10,13,12,10,13,13, 5, 9, 8, 8,11,11, 8,11,11, 7,
607.1606 +        11,11, 9,13,13,10,12,13, 7,11,11,10,13,13,10,13,
607.1607 +        11,
607.1608 +};
607.1609 +
607.1610 +static const static_codebook _8u0__p1_0 = {
607.1611 +        4, 81,
607.1612 +        (long *)_vq_lengthlist__8u0__p1_0,
607.1613 +        1, -535822336, 1611661312, 2, 0,
607.1614 +        (long *)_vq_quantlist__8u0__p1_0,
607.1615 +        0
607.1616 +};
607.1617 +
607.1618 +static const long _vq_quantlist__8u0__p2_0[] = {
607.1619 +        1,
607.1620 +        0,
607.1621 +        2,
607.1622 +};
607.1623 +
607.1624 +static const long _vq_lengthlist__8u0__p2_0[] = {
607.1625 +         2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 6, 7, 8, 6,
607.1626 +         7, 8, 5, 7, 7, 6, 8, 8, 7, 9, 7, 5, 7, 7, 7, 9,
607.1627 +         9, 7, 8, 8, 6, 9, 8, 7, 7,10, 8,10,10, 6, 8, 8,
607.1628 +         8,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 9, 6,
607.1629 +         8, 8, 8,10,10, 8, 8,10, 6, 8, 9, 8,10,10, 7,10,
607.1630 +         8,
607.1631 +};
607.1632 +
607.1633 +static const static_codebook _8u0__p2_0 = {
607.1634 +        4, 81,
607.1635 +        (long *)_vq_lengthlist__8u0__p2_0,
607.1636 +        1, -535822336, 1611661312, 2, 0,
607.1637 +        (long *)_vq_quantlist__8u0__p2_0,
607.1638 +        0
607.1639 +};
607.1640 +
607.1641 +static const long _vq_quantlist__8u0__p3_0[] = {
607.1642 +        2,
607.1643 +        1,
607.1644 +        3,
607.1645 +        0,
607.1646 +        4,
607.1647 +};
607.1648 +
607.1649 +static const long _vq_lengthlist__8u0__p3_0[] = {
607.1650 +         1, 5, 5, 7, 7, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8,
607.1651 +        10, 9,11,11, 8, 9, 9,11,11, 6, 8, 8,10,10, 8,10,
607.1652 +        10,11,11, 8,10,10,11,11,10,11,11,12,12,10,11,11,
607.1653 +        12,13, 6, 8, 8,10,10, 8,10,10,11,11, 8,10,10,11,
607.1654 +        11, 9,10,11,12,12,10,11,11,12,12, 8,11,11,14,13,
607.1655 +        10,12,11,15,13,10,12,11,14,14,12,13,12,16,14,12,
607.1656 +        14,12,16,15, 8,11,11,13,14,10,11,12,13,15,10,11,
607.1657 +        12,13,15,11,12,13,14,15,12,12,14,14,16, 5, 8, 8,
607.1658 +        11,11, 9,11,11,12,12, 8,10,11,12,12,11,12,12,15,
607.1659 +        14,11,12,12,14,14, 7,11,10,13,12,10,11,12,13,14,
607.1660 +        10,12,12,14,13,12,13,13,14,15,12,13,13,15,15, 7,
607.1661 +        10,11,12,13,10,12,11,14,13,10,12,13,13,15,12,13,
607.1662 +        12,14,14,11,13,13,15,16, 9,12,12,15,14,11,13,13,
607.1663 +        15,16,11,13,13,16,16,13,14,15,15,15,12,14,15,17,
607.1664 +        16, 9,12,12,14,15,11,13,13,15,16,11,13,13,16,18,
607.1665 +        13,14,14,17,16,13,15,15,17,18, 5, 8, 9,11,11, 8,
607.1666 +        11,11,12,12, 8,10,11,12,12,11,12,12,14,14,11,12,
607.1667 +        12,14,15, 7,11,10,12,13,10,12,12,14,13,10,11,12,
607.1668 +        13,14,11,13,13,15,14,12,13,13,14,15, 7,10,11,13,
607.1669 +        13,10,12,12,13,14,10,12,12,13,13,11,13,13,16,16,
607.1670 +        12,13,13,15,14, 9,12,12,16,15,10,13,13,15,15,11,
607.1671 +        13,13,17,15,12,15,15,18,17,13,14,14,15,16, 9,12,
607.1672 +        12,15,15,11,13,13,15,16,11,13,13,15,15,12,15,15,
607.1673 +        16,16,13,15,14,17,15, 7,11,11,15,15,10,13,13,16,
607.1674 +        15,10,13,13,15,16,14,15,15,17,19,13,15,14,15,18,
607.1675 +         9,12,12,16,16,11,13,14,17,16,11,13,13,17,16,15,
607.1676 +        15,16,17,19,13,15,16, 0,18, 9,12,12,16,15,11,14,
607.1677 +        13,17,17,11,13,14,16,16,15,16,16,19,18,13,15,15,
607.1678 +        17,19,11,14,14,19,16,12,14,15, 0,18,12,16,15,18,
607.1679 +        17,15,15,18,16,19,14,15,17,19,19,11,14,14,18,19,
607.1680 +        13,15,14,19,19,12,16,15,18,17,15,17,15, 0,16,14,
607.1681 +        17,16,19, 0, 7,11,11,14,14,10,12,12,15,15,10,13,
607.1682 +        13,16,15,13,15,15,17, 0,14,15,15,16,19, 9,12,12,
607.1683 +        16,16,11,14,14,16,16,11,13,13,16,16,14,17,16,19,
607.1684 +         0,14,18,17,17,19, 9,12,12,15,16,11,13,13,15,17,
607.1685 +        12,14,13,19,16,13,15,15,17,19,15,17,16,17,19,11,
607.1686 +        14,14,19,16,12,15,15,19,17,13,14,15,17,19,14,16,
607.1687 +        17,19,19,16,15,16,17,19,11,15,14,16,16,12,15,15,
607.1688 +        19, 0,12,14,15,19,19,14,16,16, 0,18,15,19,14,18,
607.1689 +        16,
607.1690 +};
607.1691 +
607.1692 +static const static_codebook _8u0__p3_0 = {
607.1693 +        4, 625,
607.1694 +        (long *)_vq_lengthlist__8u0__p3_0,
607.1695 +        1, -533725184, 1611661312, 3, 0,
607.1696 +        (long *)_vq_quantlist__8u0__p3_0,
607.1697 +        0
607.1698 +};
607.1699 +
607.1700 +static const long _vq_quantlist__8u0__p4_0[] = {
607.1701 +        2,
607.1702 +        1,
607.1703 +        3,
607.1704 +        0,
607.1705 +        4,
607.1706 +};
607.1707 +
607.1708 +static const long _vq_lengthlist__8u0__p4_0[] = {
607.1709 +         3, 5, 5, 8, 8, 5, 6, 7, 9, 9, 6, 7, 6, 9, 9, 9,
607.1710 +         9, 9,10,11, 9, 9, 9,11,10, 6, 7, 7,10,10, 7, 7,
607.1711 +         8,10,10, 7, 8, 8,10,10,10,10,10,10,11, 9,10,10,
607.1712 +        11,12, 6, 7, 7,10,10, 7, 8, 8,10,10, 7, 8, 7,10,
607.1713 +        10, 9,10,10,12,11,10,10,10,11,10, 9,10,10,12,11,
607.1714 +        10,10,10,13,11, 9,10,10,12,12,11,11,12,12,13,11,
607.1715 +        11,11,12,13, 9,10,10,12,12,10,10,11,12,12,10,10,
607.1716 +        11,12,12,11,11,11,13,13,11,12,12,13,13, 5, 7, 7,
607.1717 +        10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,11,12,
607.1718 +        12,10,11,10,12,12, 7, 8, 8,11,11, 7, 8, 9,10,11,
607.1719 +         8, 9, 9,11,11,11,10,11,10,12,10,11,11,12,13, 7,
607.1720 +         8, 8,10,11, 8, 9, 8,12,10, 8, 9, 9,11,12,10,11,
607.1721 +        10,13,11,10,11,11,13,12, 9,11,10,13,12,10,10,11,
607.1722 +        12,12,10,11,11,13,13,12,10,13,11,14,11,12,12,15,
607.1723 +        13, 9,11,11,13,13,10,11,11,13,12,10,11,11,12,14,
607.1724 +        12,13,11,14,12,12,12,12,14,14, 5, 7, 7,10,10, 7,
607.1725 +         8, 8,10,10, 7, 8, 8,11,10,10,11,11,12,12,10,11,
607.1726 +        10,12,12, 7, 8, 8,10,11, 8, 9, 9,12,11, 8, 8, 9,
607.1727 +        10,11,10,11,11,12,13,11,10,11,11,13, 6, 8, 8,10,
607.1728 +        11, 8, 9, 9,11,11, 7, 9, 7,11,10,10,11,11,12,12,
607.1729 +        10,11,10,13,10, 9,11,10,13,12,10,12,11,13,13,10,
607.1730 +        10,11,12,13,11,12,13,15,14,11,11,13,12,13, 9,10,
607.1731 +        11,12,13,10,11,11,12,13,10,11,10,13,12,12,13,13,
607.1732 +        13,14,12,12,11,14,11, 8,10,10,12,13,10,11,11,13,
607.1733 +        13,10,11,10,13,13,12,13,14,15,14,12,12,12,14,13,
607.1734 +         9,10,10,13,12,10,10,12,13,13,10,11,11,15,12,12,
607.1735 +        12,13,15,14,12,13,13,15,13, 9,10,11,12,13,10,12,
607.1736 +        10,13,12,10,11,11,12,13,12,14,12,15,13,12,12,12,
607.1737 +        15,14,11,12,11,14,13,11,11,12,14,14,12,13,13,14,
607.1738 +        13,13,11,15,11,15,14,14,14,16,15,11,12,12,13,14,
607.1739 +        11,13,11,14,14,12,12,13,14,15,12,14,12,15,12,13,
607.1740 +        15,14,16,15, 8,10,10,12,12,10,10,10,12,13,10,11,
607.1741 +        11,13,13,12,12,12,13,14,13,13,13,15,15, 9,10,10,
607.1742 +        12,12,10,11,11,13,12,10,10,11,13,13,12,12,12,14,
607.1743 +        14,12,12,13,15,14, 9,10,10,13,12,10,10,12,12,13,
607.1744 +        10,11,10,13,13,12,13,13,14,14,12,13,12,14,13,11,
607.1745 +        12,12,14,13,12,13,12,14,14,10,12,12,14,14,14,14,
607.1746 +        14,16,14,13,12,14,12,15,10,12,12,14,15,12,13,13,
607.1747 +        14,16,11,12,11,15,14,13,14,14,14,15,13,14,11,14,
607.1748 +        12,
607.1749 +};
607.1750 +
607.1751 +static const static_codebook _8u0__p4_0 = {
607.1752 +        4, 625,
607.1753 +        (long *)_vq_lengthlist__8u0__p4_0,
607.1754 +        1, -533725184, 1611661312, 3, 0,
607.1755 +        (long *)_vq_quantlist__8u0__p4_0,
607.1756 +        0
607.1757 +};
607.1758 +
607.1759 +static const long _vq_quantlist__8u0__p5_0[] = {
607.1760 +        4,
607.1761 +        3,
607.1762 +        5,
607.1763 +        2,
607.1764 +        6,
607.1765 +        1,
607.1766 +        7,
607.1767 +        0,
607.1768 +        8,
607.1769 +};
607.1770 +
607.1771 +static const long _vq_lengthlist__8u0__p5_0[] = {
607.1772 +         1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 7, 8, 8,
607.1773 +        10,10, 4, 6, 6, 8, 8, 8, 8,10,10, 6, 8, 8, 9, 9,
607.1774 +         9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 7, 8, 8,
607.1775 +         9, 9,10,10,12,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
607.1776 +        10,10,11,11,11,12,12,12, 9,10,10,11,11,12,12,12,
607.1777 +        12,
607.1778 +};
607.1779 +
607.1780 +static const static_codebook _8u0__p5_0 = {
607.1781 +        2, 81,
607.1782 +        (long *)_vq_lengthlist__8u0__p5_0,
607.1783 +        1, -531628032, 1611661312, 4, 0,
607.1784 +        (long *)_vq_quantlist__8u0__p5_0,
607.1785 +        0
607.1786 +};
607.1787 +
607.1788 +static const long _vq_quantlist__8u0__p6_0[] = {
607.1789 +        6,
607.1790 +        5,
607.1791 +        7,
607.1792 +        4,
607.1793 +        8,
607.1794 +        3,
607.1795 +        9,
607.1796 +        2,
607.1797 +        10,
607.1798 +        1,
607.1799 +        11,
607.1800 +        0,
607.1801 +        12,
607.1802 +};
607.1803 +
607.1804 +static const long _vq_lengthlist__8u0__p6_0[] = {
607.1805 +         1, 4, 4, 7, 7, 9, 9,11,11,12,12,16,16, 3, 6, 6,
607.1806 +         9, 9,11,11,12,12,13,14,18,16, 3, 6, 7, 9, 9,11,
607.1807 +        11,13,12,14,14,17,16, 7, 9, 9,11,11,12,12,14,14,
607.1808 +        14,14,17,16, 7, 9, 9,11,11,13,12,13,13,14,14,17,
607.1809 +         0, 9,11,11,12,13,14,14,14,13,15,14,17,17, 9,11,
607.1810 +        11,12,12,14,14,13,14,14,15, 0, 0,11,12,12,15,14,
607.1811 +        15,14,15,14,15,16,17, 0,11,12,13,13,13,14,14,15,
607.1812 +        14,15,15, 0, 0,12,14,14,15,15,14,16,15,15,17,16,
607.1813 +         0,18,13,14,14,15,14,15,14,15,16,17,16, 0, 0,17,
607.1814 +        17,18, 0,16,18,16, 0, 0, 0,17, 0, 0,16, 0, 0,16,
607.1815 +        16, 0,15, 0,17, 0, 0, 0, 0,
607.1816 +};
607.1817 +
607.1818 +static const static_codebook _8u0__p6_0 = {
607.1819 +        2, 169,
607.1820 +        (long *)_vq_lengthlist__8u0__p6_0,
607.1821 +        1, -526516224, 1616117760, 4, 0,
607.1822 +        (long *)_vq_quantlist__8u0__p6_0,
607.1823 +        0
607.1824 +};
607.1825 +
607.1826 +static const long _vq_quantlist__8u0__p6_1[] = {
607.1827 +        2,
607.1828 +        1,
607.1829 +        3,
607.1830 +        0,
607.1831 +        4,
607.1832 +};
607.1833 +
607.1834 +static const long _vq_lengthlist__8u0__p6_1[] = {
607.1835 +         1, 4, 4, 6, 6, 4, 6, 5, 7, 7, 4, 5, 6, 7, 7, 6,
607.1836 +         7, 7, 7, 7, 6, 7, 7, 7, 7,
607.1837 +};
607.1838 +
607.1839 +static const static_codebook _8u0__p6_1 = {
607.1840 +        2, 25,
607.1841 +        (long *)_vq_lengthlist__8u0__p6_1,
607.1842 +        1, -533725184, 1611661312, 3, 0,
607.1843 +        (long *)_vq_quantlist__8u0__p6_1,
607.1844 +        0
607.1845 +};
607.1846 +
607.1847 +static const long _vq_quantlist__8u0__p7_0[] = {
607.1848 +        1,
607.1849 +        0,
607.1850 +        2,
607.1851 +};
607.1852 +
607.1853 +static const long _vq_lengthlist__8u0__p7_0[] = {
607.1854 +         1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
607.1855 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
607.1856 +         8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.1857 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.1858 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.1859 +         7,
607.1860 +};
607.1861 +
607.1862 +static const static_codebook _8u0__p7_0 = {
607.1863 +        4, 81,
607.1864 +        (long *)_vq_lengthlist__8u0__p7_0,
607.1865 +        1, -518803456, 1628680192, 2, 0,
607.1866 +        (long *)_vq_quantlist__8u0__p7_0,
607.1867 +        0
607.1868 +};
607.1869 +
607.1870 +static const long _vq_quantlist__8u0__p7_1[] = {
607.1871 +        7,
607.1872 +        6,
607.1873 +        8,
607.1874 +        5,
607.1875 +        9,
607.1876 +        4,
607.1877 +        10,
607.1878 +        3,
607.1879 +        11,
607.1880 +        2,
607.1881 +        12,
607.1882 +        1,
607.1883 +        13,
607.1884 +        0,
607.1885 +        14,
607.1886 +};
607.1887 +
607.1888 +static const long _vq_lengthlist__8u0__p7_1[] = {
607.1889 +         1, 5, 5, 5, 5,10,10,11,11,11,11,11,11,11,11, 5,
607.1890 +         7, 6, 8, 8, 9,10,11,11,11,11,11,11,11,11, 6, 6,
607.1891 +         7, 9, 7,11,10,11,11,11,11,11,11,11,11, 5, 6, 6,
607.1892 +        11, 8,11,11,11,11,11,11,11,11,11,11, 5, 6, 6, 9,
607.1893 +        10,11,10,11,11,11,11,11,11,11,11, 7,10,10,11,11,
607.1894 +        11,11,11,11,11,11,11,11,11,11, 7,11, 8,11,11,11,
607.1895 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.1896 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.1897 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.1898 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.1899 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.1900 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.1901 +        11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,
607.1902 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.1903 +        10,
607.1904 +};
607.1905 +
607.1906 +static const static_codebook _8u0__p7_1 = {
607.1907 +        2, 225,
607.1908 +        (long *)_vq_lengthlist__8u0__p7_1,
607.1909 +        1, -520986624, 1620377600, 4, 0,
607.1910 +        (long *)_vq_quantlist__8u0__p7_1,
607.1911 +        0
607.1912 +};
607.1913 +
607.1914 +static const long _vq_quantlist__8u0__p7_2[] = {
607.1915 +        10,
607.1916 +        9,
607.1917 +        11,
607.1918 +        8,
607.1919 +        12,
607.1920 +        7,
607.1921 +        13,
607.1922 +        6,
607.1923 +        14,
607.1924 +        5,
607.1925 +        15,
607.1926 +        4,
607.1927 +        16,
607.1928 +        3,
607.1929 +        17,
607.1930 +        2,
607.1931 +        18,
607.1932 +        1,
607.1933 +        19,
607.1934 +        0,
607.1935 +        20,
607.1936 +};
607.1937 +
607.1938 +static const long _vq_lengthlist__8u0__p7_2[] = {
607.1939 +         1, 6, 5, 7, 7, 9, 9, 9, 9,10,12,12,10,11,11,10,
607.1940 +        11,11,11,10,11, 6, 8, 8, 9, 9,10,10, 9,10,11,11,
607.1941 +        10,11,11,11,11,10,11,11,11,11, 6, 7, 8, 9, 9, 9,
607.1942 +        10,11,10,11,12,11,10,11,11,11,11,11,11,12,10, 8,
607.1943 +         9, 9,10, 9,10,10, 9,10,10,10,10,10, 9,10,10,10,
607.1944 +        10, 9,10,10, 9, 9, 9, 9,10,10, 9, 9,10,10,11,10,
607.1945 +         9,12,10,11,10, 9,10,10,10, 8, 9, 9,10, 9,10, 9,
607.1946 +         9,10,10, 9,10, 9,11,10,10,10,10,10, 9,10, 8, 8,
607.1947 +         9, 9,10, 9,11, 9, 8, 9, 9,10,11,10,10,10,11,12,
607.1948 +         9, 9,11, 8, 9, 8,11,10,11,10,10, 9,11,10,10,10,
607.1949 +        10,10,10,10,11,11,11,11, 8, 9, 9, 9,10,10,10,11,
607.1950 +        11,12,11,12,11,10,10,10,12,11,11,11,10, 8,10, 9,
607.1951 +        11,10,10,11,12,10,11,12,11,11,12,11,12,12,10,11,
607.1952 +        11,10, 9, 9,10,11,12,10,10,10,11,10,11,11,10,12,
607.1953 +        12,10,11,10,11,12,10, 9,10,10,11,10,11,11,11,11,
607.1954 +        11,12,11,11,11, 9,11,10,11,10,11,10, 9, 9,10,11,
607.1955 +        11,11,10,10,11,12,12,11,12,11,11,11,12,12,12,12,
607.1956 +        11, 9,11,11,12,10,11,11,11,11,11,11,12,11,11,12,
607.1957 +        11,11,11,10,11,11, 9,11,10,11,11,11,10,10,10,11,
607.1958 +        11,11,12,10,11,10,11,11,11,11,12, 9,11,10,11,11,
607.1959 +        10,10,11,11, 9,11,11,12,10,10,10,10,10,11,11,10,
607.1960 +         9,10,11,11,12,11,10,10,12,11,11,12,11,12,11,11,
607.1961 +        10,10,11,11,10,12,11,10,11,10,11,10,10,10,11,11,
607.1962 +        10,10,11,11,11,11,10,10,10,12,11,11,11,11,10, 9,
607.1963 +        10,11,11,11,12,11,11,11,12,10,11,11,11, 9,10,11,
607.1964 +        11,11,11,11,11,10,10,11,11,12,11,10,11,12,11,10,
607.1965 +        10,11, 9,10,11,11,11,11,11,10,11,11,10,12,11,11,
607.1966 +        11,12,11,11,11,10,10,11,11,
607.1967 +};
607.1968 +
607.1969 +static const static_codebook _8u0__p7_2 = {
607.1970 +        2, 441,
607.1971 +        (long *)_vq_lengthlist__8u0__p7_2,
607.1972 +        1, -529268736, 1611661312, 5, 0,
607.1973 +        (long *)_vq_quantlist__8u0__p7_2,
607.1974 +        0
607.1975 +};
607.1976 +
607.1977 +static const long _huff_lengthlist__8u0__single[] = {
607.1978 +         4, 7,11, 9,12, 8, 7,10, 6, 4, 5, 5, 7, 5, 6,16,
607.1979 +         9, 5, 5, 6, 7, 7, 9,16, 7, 4, 6, 5, 7, 5, 7,17,
607.1980 +        10, 7, 7, 8, 7, 7, 8,18, 7, 5, 6, 4, 5, 4, 5,15,
607.1981 +         7, 6, 7, 5, 6, 4, 5,15,12,13,18,12,17,11, 9,17,
607.1982 +};
607.1983 +
607.1984 +static const static_codebook _huff_book__8u0__single = {
607.1985 +        2, 64,
607.1986 +        (long *)_huff_lengthlist__8u0__single,
607.1987 +        0, 0, 0, 0, 0,
607.1988 +        NULL,
607.1989 +        0
607.1990 +};
607.1991 +
607.1992 +static const long _vq_quantlist__8u1__p1_0[] = {
607.1993 +        1,
607.1994 +        0,
607.1995 +        2,
607.1996 +};
607.1997 +
607.1998 +static const long _vq_lengthlist__8u1__p1_0[] = {
607.1999 +         1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 7, 9,10, 7,
607.2000 +         9, 9, 5, 8, 8, 7,10, 9, 7, 9, 9, 5, 8, 8, 8,10,
607.2001 +        10, 8,10,10, 7,10,10, 9,10,12,10,12,12, 7,10,10,
607.2002 +         9,12,11,10,12,12, 5, 8, 8, 8,10,10, 8,10,10, 7,
607.2003 +        10,10,10,12,12, 9,11,12, 7,10,10,10,12,12, 9,12,
607.2004 +        10,
607.2005 +};
607.2006 +
607.2007 +static const static_codebook _8u1__p1_0 = {
607.2008 +        4, 81,
607.2009 +        (long *)_vq_lengthlist__8u1__p1_0,
607.2010 +        1, -535822336, 1611661312, 2, 0,
607.2011 +        (long *)_vq_quantlist__8u1__p1_0,
607.2012 +        0
607.2013 +};
607.2014 +
607.2015 +static const long _vq_quantlist__8u1__p2_0[] = {
607.2016 +        1,
607.2017 +        0,
607.2018 +        2,
607.2019 +};
607.2020 +
607.2021 +static const long _vq_lengthlist__8u1__p2_0[] = {
607.2022 +         3, 4, 5, 5, 6, 6, 5, 6, 6, 5, 7, 6, 6, 7, 8, 6,
607.2023 +         7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 7, 5, 6, 6, 7, 8,
607.2024 +         8, 6, 7, 7, 6, 8, 7, 7, 7, 9, 8, 9, 9, 6, 7, 8,
607.2025 +         7, 9, 7, 8, 9, 9, 5, 6, 6, 6, 7, 7, 7, 8, 8, 6,
607.2026 +         8, 7, 8, 9, 9, 7, 7, 9, 6, 7, 8, 8, 9, 9, 7, 9,
607.2027 +         7,
607.2028 +};
607.2029 +
607.2030 +static const static_codebook _8u1__p2_0 = {
607.2031 +        4, 81,
607.2032 +        (long *)_vq_lengthlist__8u1__p2_0,
607.2033 +        1, -535822336, 1611661312, 2, 0,
607.2034 +        (long *)_vq_quantlist__8u1__p2_0,
607.2035 +        0
607.2036 +};
607.2037 +
607.2038 +static const long _vq_quantlist__8u1__p3_0[] = {
607.2039 +        2,
607.2040 +        1,
607.2041 +        3,
607.2042 +        0,
607.2043 +        4,
607.2044 +};
607.2045 +
607.2046 +static const long _vq_lengthlist__8u1__p3_0[] = {
607.2047 +         1, 5, 5, 7, 7, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8,
607.2048 +        10, 9,11,11, 9, 9, 9,11,11, 6, 8, 8,10,10, 8,10,
607.2049 +        10,11,11, 8, 9,10,11,11,10,11,11,12,12,10,11,11,
607.2050 +        12,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10, 9,11,
607.2051 +        11,10,11,11,12,12,10,11,11,12,12, 9,11,11,14,13,
607.2052 +        10,12,11,14,14,10,12,11,14,13,12,13,13,15,14,12,
607.2053 +        13,13,15,14, 8,11,11,13,14,10,11,12,13,15,10,11,
607.2054 +        12,14,14,12,13,13,14,15,12,13,13,14,15, 5, 8, 8,
607.2055 +        11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14,
607.2056 +        13,11,12,12,13,14, 8,10,10,12,12, 9,11,12,13,14,
607.2057 +        10,12,12,13,13,12,12,13,14,14,11,13,13,15,15, 7,
607.2058 +        10,10,12,12, 9,12,11,14,12,10,11,12,13,14,12,13,
607.2059 +        12,14,14,12,13,13,15,16,10,12,12,15,14,11,12,13,
607.2060 +        15,15,11,13,13,15,16,14,14,15,15,16,13,14,15,17,
607.2061 +        15, 9,12,12,14,15,11,13,12,15,15,11,13,13,15,15,
607.2062 +        13,14,13,15,14,13,14,14,17, 0, 5, 8, 8,11,11, 8,
607.2063 +        10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12,
607.2064 +        12,14,14, 7,10,10,12,12,10,12,12,13,13, 9,11,12,
607.2065 +        12,13,11,12,13,15,15,11,12,13,14,15, 8,10,10,12,
607.2066 +        12,10,12,11,13,13,10,12,11,13,13,11,13,13,15,14,
607.2067 +        12,13,12,15,13, 9,12,12,14,14,11,13,13,16,15,11,
607.2068 +        12,13,16,15,13,14,15,16,16,13,13,15,15,16,10,12,
607.2069 +        12,15,14,11,13,13,14,16,11,13,13,15,16,13,15,15,
607.2070 +        16,17,13,15,14,16,15, 8,11,11,14,15,10,12,12,15,
607.2071 +        15,10,12,12,15,16,14,15,15,16,17,13,14,14,16,16,
607.2072 +         9,12,12,15,15,11,13,14,15,17,11,13,13,15,16,14,
607.2073 +        15,16,19,17,13,15,15, 0,17, 9,12,12,15,15,11,14,
607.2074 +        13,16,15,11,13,13,15,16,15,15,15,18,17,13,15,15,
607.2075 +        17,17,11,15,14,18,16,12,14,15,17,17,12,15,15,18,
607.2076 +        18,15,15,16,15,19,14,16,16, 0, 0,11,14,14,16,17,
607.2077 +        12,15,14,18,17,12,15,15,18,18,15,17,15,18,16,14,
607.2078 +        16,16,18,18, 7,11,11,14,14,10,12,12,15,15,10,12,
607.2079 +        13,15,15,13,14,15,16,16,14,15,15,18,18, 9,12,12,
607.2080 +        15,15,11,13,13,16,15,11,12,13,16,16,14,15,15,17,
607.2081 +        16,15,16,16,17,17, 9,12,12,15,15,11,13,13,15,17,
607.2082 +        11,14,13,16,15,13,15,15,17,17,15,15,15,18,17,11,
607.2083 +        14,14,17,15,12,14,15,17,18,13,13,15,17,17,14,16,
607.2084 +        16,19,18,16,15,17,17, 0,11,14,14,17,17,12,15,15,
607.2085 +        18, 0,12,15,14,18,16,14,17,17,19, 0,16,18,15, 0,
607.2086 +        16,
607.2087 +};
607.2088 +
607.2089 +static const static_codebook _8u1__p3_0 = {
607.2090 +        4, 625,
607.2091 +        (long *)_vq_lengthlist__8u1__p3_0,
607.2092 +        1, -533725184, 1611661312, 3, 0,
607.2093 +        (long *)_vq_quantlist__8u1__p3_0,
607.2094 +        0
607.2095 +};
607.2096 +
607.2097 +static const long _vq_quantlist__8u1__p4_0[] = {
607.2098 +        2,
607.2099 +        1,
607.2100 +        3,
607.2101 +        0,
607.2102 +        4,
607.2103 +};
607.2104 +
607.2105 +static const long _vq_lengthlist__8u1__p4_0[] = {
607.2106 +         4, 5, 5, 9, 9, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 9,
607.2107 +         9, 9,11,11, 9, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 7,
607.2108 +         8, 9,10, 7, 7, 8, 9,10, 9, 9,10,10,11, 9, 9,10,
607.2109 +        10,12, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 7,10,
607.2110 +         9, 9,10, 9,12,11,10,10, 9,12,10, 9,10,10,12,11,
607.2111 +         9,10,10,12,11, 9,10,10,12,12,11,11,12,12,13,11,
607.2112 +        11,12,12,13, 9, 9,10,12,11, 9,10,10,12,12,10,10,
607.2113 +        10,12,12,11,12,11,13,12,11,12,11,13,12, 6, 7, 7,
607.2114 +         9, 9, 7, 8, 8,10,10, 7, 8, 7,10, 9,10,10,10,12,
607.2115 +        12,10,10,10,12,11, 7, 8, 7,10,10, 7, 7, 9,10,11,
607.2116 +         8, 9, 9,11,10,10,10,11,10,12,10,10,11,12,12, 7,
607.2117 +         8, 8,10,10, 7, 9, 8,11,10, 8, 8, 9,11,11,10,11,
607.2118 +        10,12,11,10,11,11,12,12, 9,10,10,12,12, 9,10,10,
607.2119 +        12,12,10,11,11,13,12,11,10,12,10,14,12,12,12,13,
607.2120 +        14, 9,10,10,12,12, 9,11,10,12,12,10,11,11,12,12,
607.2121 +        11,12,11,14,12,12,12,12,14,14, 5, 7, 7, 9, 9, 7,
607.2122 +         7, 7, 9,10, 7, 8, 8,10,10,10,10,10,11,11,10,10,
607.2123 +        10,12,12, 7, 8, 8,10,10, 8, 9, 8,11,10, 7, 8, 9,
607.2124 +        10,11,10,10,10,11,12,10,10,11,11,13, 6, 7, 8,10,
607.2125 +        10, 8, 9, 9,10,10, 7, 9, 7,11,10,10,11,10,12,12,
607.2126 +        10,11,10,12,10, 9,10,10,12,12,10,11,11,13,12, 9,
607.2127 +        10,10,12,12,12,12,12,14,13,11,11,12,11,14, 9,10,
607.2128 +        10,11,12,10,11,11,12,13, 9,10,10,12,12,12,12,12,
607.2129 +        14,13,11,12,10,14,11, 9, 9,10,11,12, 9,10,10,12,
607.2130 +        12, 9,10,10,12,12,12,12,12,14,14,11,12,12,13,12,
607.2131 +         9,10, 9,12,12, 9,10,11,12,13,10,11,10,13,11,12,
607.2132 +        12,13,13,14,12,12,12,13,13, 9,10,10,12,12,10,11,
607.2133 +        10,13,12,10,10,11,12,13,12,13,12,14,13,12,12,12,
607.2134 +        13,14,11,12,11,14,13,10,10,11,13,13,12,12,12,14,
607.2135 +        13,12,10,14,10,15,13,14,14,14,14,11,11,12,13,14,
607.2136 +        10,12,11,13,13,12,12,12,13,15,12,13,11,15,12,13,
607.2137 +        13,14,14,14, 9,10, 9,12,12, 9,10,10,12,12,10,10,
607.2138 +        10,12,12,11,11,12,12,13,12,12,12,14,14, 9,10,10,
607.2139 +        12,12,10,11,10,13,12,10,10,11,12,13,12,12,12,14,
607.2140 +        13,12,12,13,13,14, 9,10,10,12,13,10,10,11,11,12,
607.2141 +         9,11,10,13,12,12,12,12,13,14,12,13,12,14,13,11,
607.2142 +        12,11,13,13,12,13,12,14,13,10,11,12,13,13,13,13,
607.2143 +        13,14,15,12,11,14,12,14,11,11,12,12,13,12,12,12,
607.2144 +        13,14,10,12,10,14,13,13,13,13,14,15,12,14,11,15,
607.2145 +        10,
607.2146 +};
607.2147 +
607.2148 +static const static_codebook _8u1__p4_0 = {
607.2149 +        4, 625,
607.2150 +        (long *)_vq_lengthlist__8u1__p4_0,
607.2151 +        1, -533725184, 1611661312, 3, 0,
607.2152 +        (long *)_vq_quantlist__8u1__p4_0,
607.2153 +        0
607.2154 +};
607.2155 +
607.2156 +static const long _vq_quantlist__8u1__p5_0[] = {
607.2157 +        4,
607.2158 +        3,
607.2159 +        5,
607.2160 +        2,
607.2161 +        6,
607.2162 +        1,
607.2163 +        7,
607.2164 +        0,
607.2165 +        8,
607.2166 +};
607.2167 +
607.2168 +static const long _vq_lengthlist__8u1__p5_0[] = {
607.2169 +         1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 5, 8, 7, 8, 8,
607.2170 +        10,10, 4, 6, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9,
607.2171 +         9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 8, 8, 8,
607.2172 +         9, 9,10,10,12,11, 8, 8, 8, 9, 9,10,10,11,11, 9,
607.2173 +        10,10,11,11,11,11,13,12, 9,10,10,11,11,12,12,12,
607.2174 +        13,
607.2175 +};
607.2176 +
607.2177 +static const static_codebook _8u1__p5_0 = {
607.2178 +        2, 81,
607.2179 +        (long *)_vq_lengthlist__8u1__p5_0,
607.2180 +        1, -531628032, 1611661312, 4, 0,
607.2181 +        (long *)_vq_quantlist__8u1__p5_0,
607.2182 +        0
607.2183 +};
607.2184 +
607.2185 +static const long _vq_quantlist__8u1__p6_0[] = {
607.2186 +        4,
607.2187 +        3,
607.2188 +        5,
607.2189 +        2,
607.2190 +        6,
607.2191 +        1,
607.2192 +        7,
607.2193 +        0,
607.2194 +        8,
607.2195 +};
607.2196 +
607.2197 +static const long _vq_lengthlist__8u1__p6_0[] = {
607.2198 +         3, 4, 4, 6, 6, 7, 7, 9, 9, 4, 4, 5, 6, 6, 7, 7,
607.2199 +         9, 9, 4, 4, 4, 6, 6, 7, 7, 9, 9, 6, 6, 6, 7, 7,
607.2200 +         8, 8, 9, 9, 6, 6, 6, 7, 7, 8, 8, 9, 9, 7, 7, 7,
607.2201 +         8, 8, 8, 9,10,10, 7, 7, 7, 8, 8, 9, 8,10,10, 9,
607.2202 +         9, 9, 9, 9,10,10,10,10, 9, 9, 9, 9, 9,10,10,10,
607.2203 +        10,
607.2204 +};
607.2205 +
607.2206 +static const static_codebook _8u1__p6_0 = {
607.2207 +        2, 81,
607.2208 +        (long *)_vq_lengthlist__8u1__p6_0,
607.2209 +        1, -531628032, 1611661312, 4, 0,
607.2210 +        (long *)_vq_quantlist__8u1__p6_0,
607.2211 +        0
607.2212 +};
607.2213 +
607.2214 +static const long _vq_quantlist__8u1__p7_0[] = {
607.2215 +        1,
607.2216 +        0,
607.2217 +        2,
607.2218 +};
607.2219 +
607.2220 +static const long _vq_lengthlist__8u1__p7_0[] = {
607.2221 +         1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 9, 8,10,10, 8,
607.2222 +        10,10, 5, 9, 9, 7,10,10, 8,10,10, 4,10,10, 9,12,
607.2223 +        12, 9,11,11, 7,12,11,10,11,13,10,13,13, 7,12,12,
607.2224 +        10,13,12,10,13,13, 4,10,10, 9,12,12, 9,12,12, 7,
607.2225 +        12,12,10,13,13,10,12,13, 7,11,12,10,13,13,10,13,
607.2226 +        11,
607.2227 +};
607.2228 +
607.2229 +static const static_codebook _8u1__p7_0 = {
607.2230 +        4, 81,
607.2231 +        (long *)_vq_lengthlist__8u1__p7_0,
607.2232 +        1, -529137664, 1618345984, 2, 0,
607.2233 +        (long *)_vq_quantlist__8u1__p7_0,
607.2234 +        0
607.2235 +};
607.2236 +
607.2237 +static const long _vq_quantlist__8u1__p7_1[] = {
607.2238 +        5,
607.2239 +        4,
607.2240 +        6,
607.2241 +        3,
607.2242 +        7,
607.2243 +        2,
607.2244 +        8,
607.2245 +        1,
607.2246 +        9,
607.2247 +        0,
607.2248 +        10,
607.2249 +};
607.2250 +
607.2251 +static const long _vq_lengthlist__8u1__p7_1[] = {
607.2252 +         2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 7,
607.2253 +         8, 8, 9, 9, 9, 9, 4, 5, 5, 7, 7, 8, 8, 9, 9, 9,
607.2254 +         9, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8,
607.2255 +         8, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9,
607.2256 +         9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 9, 9,
607.2257 +         9, 9, 9, 9,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10,
607.2258 +        10,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10, 8, 9,
607.2259 +         9, 9, 9, 9, 9,10,10,10,10,
607.2260 +};
607.2261 +
607.2262 +static const static_codebook _8u1__p7_1 = {
607.2263 +        2, 121,
607.2264 +        (long *)_vq_lengthlist__8u1__p7_1,
607.2265 +        1, -531365888, 1611661312, 4, 0,
607.2266 +        (long *)_vq_quantlist__8u1__p7_1,
607.2267 +        0
607.2268 +};
607.2269 +
607.2270 +static const long _vq_quantlist__8u1__p8_0[] = {
607.2271 +        5,
607.2272 +        4,
607.2273 +        6,
607.2274 +        3,
607.2275 +        7,
607.2276 +        2,
607.2277 +        8,
607.2278 +        1,
607.2279 +        9,
607.2280 +        0,
607.2281 +        10,
607.2282 +};
607.2283 +
607.2284 +static const long _vq_lengthlist__8u1__p8_0[] = {
607.2285 +         1, 4, 4, 6, 6, 8, 8,10,10,11,11, 4, 6, 6, 7, 7,
607.2286 +         9, 9,11,11,13,12, 4, 6, 6, 7, 7, 9, 9,11,11,12,
607.2287 +        12, 6, 7, 7, 9, 9,11,11,12,12,13,13, 6, 7, 7, 9,
607.2288 +         9,11,11,12,12,13,13, 8, 9, 9,11,11,12,12,13,13,
607.2289 +        14,14, 8, 9, 9,11,11,12,12,13,13,14,14, 9,11,11,
607.2290 +        12,12,13,13,14,14,15,15, 9,11,11,12,12,13,13,14,
607.2291 +        14,15,14,11,12,12,13,13,14,14,15,15,16,16,11,12,
607.2292 +        12,13,13,14,14,15,15,15,15,
607.2293 +};
607.2294 +
607.2295 +static const static_codebook _8u1__p8_0 = {
607.2296 +        2, 121,
607.2297 +        (long *)_vq_lengthlist__8u1__p8_0,
607.2298 +        1, -524582912, 1618345984, 4, 0,
607.2299 +        (long *)_vq_quantlist__8u1__p8_0,
607.2300 +        0
607.2301 +};
607.2302 +
607.2303 +static const long _vq_quantlist__8u1__p8_1[] = {
607.2304 +        5,
607.2305 +        4,
607.2306 +        6,
607.2307 +        3,
607.2308 +        7,
607.2309 +        2,
607.2310 +        8,
607.2311 +        1,
607.2312 +        9,
607.2313 +        0,
607.2314 +        10,
607.2315 +};
607.2316 +
607.2317 +static const long _vq_lengthlist__8u1__p8_1[] = {
607.2318 +         2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 5, 6, 6, 7, 7,
607.2319 +         7, 7, 8, 8, 8, 8, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8,
607.2320 +         8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7,
607.2321 +         7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8,
607.2322 +         8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
607.2323 +         8, 8, 8, 8, 9, 8, 9, 9, 7, 8, 8, 8, 8, 8, 8, 9,
607.2324 +         8, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8,
607.2325 +         8, 8, 8, 8, 8, 9, 9, 9, 9,
607.2326 +};
607.2327 +
607.2328 +static const static_codebook _8u1__p8_1 = {
607.2329 +        2, 121,
607.2330 +        (long *)_vq_lengthlist__8u1__p8_1,
607.2331 +        1, -531365888, 1611661312, 4, 0,
607.2332 +        (long *)_vq_quantlist__8u1__p8_1,
607.2333 +        0
607.2334 +};
607.2335 +
607.2336 +static const long _vq_quantlist__8u1__p9_0[] = {
607.2337 +        7,
607.2338 +        6,
607.2339 +        8,
607.2340 +        5,
607.2341 +        9,
607.2342 +        4,
607.2343 +        10,
607.2344 +        3,
607.2345 +        11,
607.2346 +        2,
607.2347 +        12,
607.2348 +        1,
607.2349 +        13,
607.2350 +        0,
607.2351 +        14,
607.2352 +};
607.2353 +
607.2354 +static const long _vq_lengthlist__8u1__p9_0[] = {
607.2355 +         1, 4, 4,11,11,11,11,11,11,11,11,11,11,11,11, 3,
607.2356 +        11, 8,11,11,11,11,11,11,11,11,11,11,11,11, 3, 9,
607.2357 +         9,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2358 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2359 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2360 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2361 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2362 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2363 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2364 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2365 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2366 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2367 +        11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,
607.2368 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2369 +        10,
607.2370 +};
607.2371 +
607.2372 +static const static_codebook _8u1__p9_0 = {
607.2373 +        2, 225,
607.2374 +        (long *)_vq_lengthlist__8u1__p9_0,
607.2375 +        1, -514071552, 1627381760, 4, 0,
607.2376 +        (long *)_vq_quantlist__8u1__p9_0,
607.2377 +        0
607.2378 +};
607.2379 +
607.2380 +static const long _vq_quantlist__8u1__p9_1[] = {
607.2381 +        7,
607.2382 +        6,
607.2383 +        8,
607.2384 +        5,
607.2385 +        9,
607.2386 +        4,
607.2387 +        10,
607.2388 +        3,
607.2389 +        11,
607.2390 +        2,
607.2391 +        12,
607.2392 +        1,
607.2393 +        13,
607.2394 +        0,
607.2395 +        14,
607.2396 +};
607.2397 +
607.2398 +static const long _vq_lengthlist__8u1__p9_1[] = {
607.2399 +         1, 4, 4, 7, 7, 9, 9, 7, 7, 8, 8,10,10,11,11, 4,
607.2400 +         7, 7, 9, 9,10,10, 8, 8,10,10,10,11,10,11, 4, 7,
607.2401 +         7, 9, 9,10,10, 8, 8,10, 9,11,11,11,11, 7, 9, 9,
607.2402 +        12,12,11,12,10,10,11,10,12,11,11,11, 7, 9, 9,11,
607.2403 +        11,13,12, 9, 9,11,10,11,11,12,11, 9,10,10,12,12,
607.2404 +        14,14,10,10,11,12,12,11,11,11, 9,10,11,11,13,14,
607.2405 +        13,10,11,11,11,12,11,12,12, 7, 8, 8,10, 9,11,10,
607.2406 +        11,12,12,11,12,14,12,13, 7, 8, 8, 9,10,10,11,12,
607.2407 +        12,12,11,12,12,12,13, 9, 9, 9,11,11,13,12,12,12,
607.2408 +        12,11,12,12,13,12, 8,10,10,11,10,11,12,12,12,12,
607.2409 +        12,12,14,12,12, 9,11,11,11,12,12,12,12,13,13,12,
607.2410 +        12,13,13,12,10,11,11,12,11,12,12,12,11,12,13,12,
607.2411 +        12,12,13,11,11,12,12,12,13,12,12,11,12,13,13,12,
607.2412 +        12,13,12,11,12,12,13,13,12,13,12,13,13,13,13,14,
607.2413 +        13,
607.2414 +};
607.2415 +
607.2416 +static const static_codebook _8u1__p9_1 = {
607.2417 +        2, 225,
607.2418 +        (long *)_vq_lengthlist__8u1__p9_1,
607.2419 +        1, -522338304, 1620115456, 4, 0,
607.2420 +        (long *)_vq_quantlist__8u1__p9_1,
607.2421 +        0
607.2422 +};
607.2423 +
607.2424 +static const long _vq_quantlist__8u1__p9_2[] = {
607.2425 +        8,
607.2426 +        7,
607.2427 +        9,
607.2428 +        6,
607.2429 +        10,
607.2430 +        5,
607.2431 +        11,
607.2432 +        4,
607.2433 +        12,
607.2434 +        3,
607.2435 +        13,
607.2436 +        2,
607.2437 +        14,
607.2438 +        1,
607.2439 +        15,
607.2440 +        0,
607.2441 +        16,
607.2442 +};
607.2443 +
607.2444 +static const long _vq_lengthlist__8u1__p9_2[] = {
607.2445 +         2, 5, 4, 6, 6, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.2446 +         9, 5, 6, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,
607.2447 +         9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.2448 +         9, 9, 9, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
607.2449 +         9,10,10, 9, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9,
607.2450 +         9, 9, 9,10,10, 8, 8, 8, 9, 9, 9, 9,10,10,10, 9,
607.2451 +        10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
607.2452 +        10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10,
607.2453 +        10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,10,10,
607.2454 +        10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,
607.2455 +        10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,
607.2456 +        10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,10,
607.2457 +        10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
607.2458 +         9,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
607.2459 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,10,
607.2460 +         9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, 9,
607.2461 +        10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2462 +         9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2463 +        10,
607.2464 +};
607.2465 +
607.2466 +static const static_codebook _8u1__p9_2 = {
607.2467 +        2, 289,
607.2468 +        (long *)_vq_lengthlist__8u1__p9_2,
607.2469 +        1, -529530880, 1611661312, 5, 0,
607.2470 +        (long *)_vq_quantlist__8u1__p9_2,
607.2471 +        0
607.2472 +};
607.2473 +
607.2474 +static const long _huff_lengthlist__8u1__single[] = {
607.2475 +         4, 7,13, 9,15, 9,16, 8,10,13, 7, 5, 8, 6, 9, 7,
607.2476 +        10, 7,10,11,11, 6, 7, 8, 8, 9, 9, 9,12,16, 8, 5,
607.2477 +         8, 6, 8, 6, 9, 7,10,12,11, 7, 7, 7, 6, 7, 7, 7,
607.2478 +        11,15, 7, 5, 8, 6, 7, 5, 7, 6, 9,13,13, 9, 9, 8,
607.2479 +         6, 6, 5, 5, 9,14, 8, 6, 8, 6, 6, 4, 5, 3, 5,13,
607.2480 +         9, 9,11, 8,10, 7, 8, 4, 5,12,11,16,17,15,17,12,
607.2481 +        13, 8, 8,15,
607.2482 +};
607.2483 +
607.2484 +static const static_codebook _huff_book__8u1__single = {
607.2485 +        2, 100,
607.2486 +        (long *)_huff_lengthlist__8u1__single,
607.2487 +        0, 0, 0, 0, 0,
607.2488 +        NULL,
607.2489 +        0
607.2490 +};
607.2491 +
607.2492 +static const long _huff_lengthlist__44u0__long[] = {
607.2493 +         5, 8,13,10,17,11,11,15, 7, 2, 4, 5, 8, 7, 9,16,
607.2494 +        13, 4, 3, 5, 6, 8,11,20,10, 4, 5, 5, 7, 6, 8,18,
607.2495 +        15, 7, 6, 7, 8,10,14,20,10, 6, 7, 6, 9, 7, 8,17,
607.2496 +         9, 8,10, 8,10, 5, 4,11,12,17,19,14,16,10, 7,12,
607.2497 +};
607.2498 +
607.2499 +static const static_codebook _huff_book__44u0__long = {
607.2500 +        2, 64,
607.2501 +        (long *)_huff_lengthlist__44u0__long,
607.2502 +        0, 0, 0, 0, 0,
607.2503 +        NULL,
607.2504 +        0
607.2505 +};
607.2506 +
607.2507 +static const long _vq_quantlist__44u0__p1_0[] = {
607.2508 +        1,
607.2509 +        0,
607.2510 +        2,
607.2511 +};
607.2512 +
607.2513 +static const long _vq_lengthlist__44u0__p1_0[] = {
607.2514 +         1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8,
607.2515 +        10,10, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11,
607.2516 +        11, 8,11,11, 8,12,11,11,13,13,11,13,14, 7,11,11,
607.2517 +        10,13,12,11,13,14, 4, 8, 8, 8,11,11, 8,11,12, 8,
607.2518 +        11,11,11,13,13,10,12,13, 8,11,11,11,14,13,11,14,
607.2519 +        13,
607.2520 +};
607.2521 +
607.2522 +static const static_codebook _44u0__p1_0 = {
607.2523 +        4, 81,
607.2524 +        (long *)_vq_lengthlist__44u0__p1_0,
607.2525 +        1, -535822336, 1611661312, 2, 0,
607.2526 +        (long *)_vq_quantlist__44u0__p1_0,
607.2527 +        0
607.2528 +};
607.2529 +
607.2530 +static const long _vq_quantlist__44u0__p2_0[] = {
607.2531 +        1,
607.2532 +        0,
607.2533 +        2,
607.2534 +};
607.2535 +
607.2536 +static const long _vq_lengthlist__44u0__p2_0[] = {
607.2537 +         2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 8, 6,
607.2538 +         8, 8, 5, 7, 7, 6, 8, 8, 7, 8, 8, 4, 7, 7, 7, 8,
607.2539 +         8, 7, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8,
607.2540 +         8,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 8, 6,
607.2541 +         8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10,
607.2542 +         9,
607.2543 +};
607.2544 +
607.2545 +static const static_codebook _44u0__p2_0 = {
607.2546 +        4, 81,
607.2547 +        (long *)_vq_lengthlist__44u0__p2_0,
607.2548 +        1, -535822336, 1611661312, 2, 0,
607.2549 +        (long *)_vq_quantlist__44u0__p2_0,
607.2550 +        0
607.2551 +};
607.2552 +
607.2553 +static const long _vq_quantlist__44u0__p3_0[] = {
607.2554 +        2,
607.2555 +        1,
607.2556 +        3,
607.2557 +        0,
607.2558 +        4,
607.2559 +};
607.2560 +
607.2561 +static const long _vq_lengthlist__44u0__p3_0[] = {
607.2562 +         1, 5, 5, 8, 8, 5, 8, 7, 9, 9, 5, 7, 8, 9, 9, 9,
607.2563 +        10, 9,12,12, 9, 9,10,12,12, 6, 8, 8,11,10, 8,10,
607.2564 +        10,11,11, 8, 9,10,11,11,10,11,11,14,13,10,11,11,
607.2565 +        13,13, 5, 8, 8,10,10, 8,10,10,11,11, 8,10,10,11,
607.2566 +        11,10,11,11,13,13,10,11,11,13,13, 9,11,11,15,14,
607.2567 +        10,12,12,15,14,10,12,11,15,14,13,14,14,16,16,12,
607.2568 +        14,13,17,15, 9,11,11,14,15,10,11,12,14,16,10,11,
607.2569 +        12,14,16,12,13,14,16,16,13,13,15,15,18, 5, 8, 8,
607.2570 +        11,11, 8,10,10,12,12, 8,10,10,12,13,11,12,12,14,
607.2571 +        14,11,12,12,15,15, 8,10,10,13,13,10,12,12,13,13,
607.2572 +        10,12,12,14,14,12,13,13,15,15,12,13,13,16,16, 7,
607.2573 +        10,10,12,12,10,12,11,13,13,10,12,12,13,14,12,13,
607.2574 +        12,15,14,12,13,13,16,16,10,12,12,17,16,12,13,13,
607.2575 +        16,15,11,13,13,17,17,15,15,15,16,17,14,15,15,19,
607.2576 +        19,10,12,12,15,16,11,13,12,15,18,11,13,13,16,16,
607.2577 +        14,15,15,17,17,14,15,15,17,19, 5, 8, 8,11,11, 8,
607.2578 +        10,10,12,12, 8,10,10,12,12,11,12,12,16,15,11,12,
607.2579 +        12,14,15, 7,10,10,13,13,10,12,12,14,13,10,11,12,
607.2580 +        13,13,12,13,13,16,16,12,12,13,15,15, 8,10,10,13,
607.2581 +        13,10,12,12,14,14,10,12,12,13,13,12,13,13,16,16,
607.2582 +        12,13,13,15,15,10,12,12,16,15,11,13,13,17,16,11,
607.2583 +        12,13,16,15,13,15,15,19,17,14,15,14,17,16,10,12,
607.2584 +        12,16,16,11,13,13,16,17,12,13,13,15,17,14,15,15,
607.2585 +        17,19,14,15,15,17,17, 8,11,11,16,16,10,13,12,17,
607.2586 +        17,10,12,13,16,16,15,17,16,20,19,14,15,17,18,19,
607.2587 +         9,12,12,16,17,11,13,14,17,18,11,13,13,19,18,16,
607.2588 +        17,18,19,19,15,16,16,19,19, 9,12,12,16,17,11,14,
607.2589 +        13,18,17,11,13,13,17,17,16,17,16,20,19,14,16,16,
607.2590 +        18,18,12,15,15,19,17,14,15,16, 0,20,13,15,16,20,
607.2591 +        17,18,16,20, 0, 0,15,16,19,20, 0,12,15,14,18,19,
607.2592 +        13,16,15,20,19,13,16,15,20,18,17,18,17, 0,20,16,
607.2593 +        17,16, 0, 0, 8,11,11,16,15,10,12,12,17,17,10,13,
607.2594 +        13,17,16,14,16,15,18,20,15,16,16,19,19, 9,12,12,
607.2595 +        16,16,11,13,13,17,16,11,13,14,17,18,15,15,16,20,
607.2596 +        20,16,16,17,19,19, 9,13,12,16,17,11,14,13,17,17,
607.2597 +        11,14,14,18,17,14,16,15,18,19,16,17,18,18,19,12,
607.2598 +        14,15,19,18,13,15,16,18, 0,13,14,15, 0, 0,16,16,
607.2599 +        17,20, 0,17,17,20,20, 0,12,15,15,19,20,13,15,15,
607.2600 +         0, 0,14,16,15, 0, 0,15,18,16, 0, 0,17,18,16, 0,
607.2601 +        19,
607.2602 +};
607.2603 +
607.2604 +static const static_codebook _44u0__p3_0 = {
607.2605 +        4, 625,
607.2606 +        (long *)_vq_lengthlist__44u0__p3_0,
607.2607 +        1, -533725184, 1611661312, 3, 0,
607.2608 +        (long *)_vq_quantlist__44u0__p3_0,
607.2609 +        0
607.2610 +};
607.2611 +
607.2612 +static const long _vq_quantlist__44u0__p4_0[] = {
607.2613 +        2,
607.2614 +        1,
607.2615 +        3,
607.2616 +        0,
607.2617 +        4,
607.2618 +};
607.2619 +
607.2620 +static const long _vq_lengthlist__44u0__p4_0[] = {
607.2621 +         4, 5, 5, 9, 9, 5, 6, 6, 9, 9, 5, 6, 6, 9, 9, 9,
607.2622 +        10, 9,12,12, 9, 9,10,12,12, 5, 7, 7,10,10, 7, 7,
607.2623 +         8,10,10, 6, 7, 8,10,10,10,10,10,11,13,10, 9,10,
607.2624 +        12,13, 5, 7, 7,10,10, 6, 8, 7,10,10, 7, 8, 7,10,
607.2625 +        10, 9,10,10,12,12,10,10,10,13,11, 9,10,10,13,13,
607.2626 +        10,11,10,13,13,10,10,10,13,13,12,12,13,14,14,12,
607.2627 +        12,13,14,14, 9,10,10,13,13,10,10,10,13,13,10,10,
607.2628 +        10,13,13,12,13,12,15,14,12,13,12,15,15, 5, 7, 6,
607.2629 +        10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,13,
607.2630 +        13,10,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,10,11,
607.2631 +         8, 9, 9,11,11,11,10,11,11,14,11,11,11,13,13, 6,
607.2632 +         8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
607.2633 +        10,14,11,10,11,11,13,13,10,11,11,14,13,10,10,11,
607.2634 +        14,13,10,11,11,14,14,12,11,13,12,16,13,14,14,15,
607.2635 +        15,10,10,11,13,14,10,11,10,14,13,10,11,11,14,14,
607.2636 +        12,13,12,15,13,13,13,14,15,16, 5, 7, 7,10,10, 7,
607.2637 +         8, 8,10,10, 7, 8, 8,10,10,10,10,10,13,13,10,10,
607.2638 +        11,12,13, 6, 8, 8,11,10, 8, 9, 9,11,11, 7, 8, 9,
607.2639 +        10,11,10,11,11,13,13,10,10,11,11,13, 6, 8, 8,10,
607.2640 +        11, 8, 9, 9,11,11, 8, 9, 8,12,10,10,11,11,13,13,
607.2641 +        10,11,10,14,11,10,10,10,14,13,10,11,11,14,13,10,
607.2642 +        10,11,13,13,12,14,14,16,16,12,12,13,13,15,10,11,
607.2643 +        11,13,14,10,11,11,14,15,10,11,10,13,13,13,14,13,
607.2644 +        16,16,12,13,11,15,12, 9,10,10,13,13,10,11,11,14,
607.2645 +        13,10,10,11,13,14,13,14,13,16,16,13,13,13,15,16,
607.2646 +         9,10,10,13,13,10,10,11,13,14,10,11,11,15,13,13,
607.2647 +        13,14,14,18,13,13,14,16,15, 9,10,10,13,14,10,11,
607.2648 +        10,14,13,10,11,11,13,14,13,14,13,16,15,13,13,14,
607.2649 +        15,16,12,13,12,16,14,11,11,13,15,15,13,14,13,16,
607.2650 +        15,15,12,16,12,17,14,15,15,17,17,12,13,13,14,16,
607.2651 +        11,13,11,16,15,12,13,14,15,16,14,15,13, 0,14,14,
607.2652 +        16,16, 0, 0, 9,10,10,13,13,10,11,10,14,14,10,11,
607.2653 +        11,13,13,12,13,13,14,16,13,14,14,16,16, 9,10,10,
607.2654 +        14,14,11,11,11,14,13,10,10,11,14,14,13,13,13,16,
607.2655 +        16,13,13,14,14,17, 9,10,10,13,14,10,11,11,13,15,
607.2656 +        10,11,10,14,14,13,13,13,14,17,13,14,13,17,14,12,
607.2657 +        13,13,16,14,13,14,13,16,15,12,12,13,15,16,15,15,
607.2658 +        16,18,16,15,13,15,14, 0,12,12,13,14,16,13,13,14,
607.2659 +        15,16,11,12,11,16,14,15,16,16,17,17,14,15,12,17,
607.2660 +        12,
607.2661 +};
607.2662 +
607.2663 +static const static_codebook _44u0__p4_0 = {
607.2664 +        4, 625,
607.2665 +        (long *)_vq_lengthlist__44u0__p4_0,
607.2666 +        1, -533725184, 1611661312, 3, 0,
607.2667 +        (long *)_vq_quantlist__44u0__p4_0,
607.2668 +        0
607.2669 +};
607.2670 +
607.2671 +static const long _vq_quantlist__44u0__p5_0[] = {
607.2672 +        4,
607.2673 +        3,
607.2674 +        5,
607.2675 +        2,
607.2676 +        6,
607.2677 +        1,
607.2678 +        7,
607.2679 +        0,
607.2680 +        8,
607.2681 +};
607.2682 +
607.2683 +static const long _vq_lengthlist__44u0__p5_0[] = {
607.2684 +         1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8,
607.2685 +         9, 9, 4, 6, 6, 8, 8, 8, 8, 9, 9, 7, 8, 8, 9, 9,
607.2686 +         9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,10, 7, 8, 8,
607.2687 +         9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
607.2688 +         9, 9,10,10,11,11,12,12, 9, 9, 9,10,11,11,11,12,
607.2689 +        12,
607.2690 +};
607.2691 +
607.2692 +static const static_codebook _44u0__p5_0 = {
607.2693 +        2, 81,
607.2694 +        (long *)_vq_lengthlist__44u0__p5_0,
607.2695 +        1, -531628032, 1611661312, 4, 0,
607.2696 +        (long *)_vq_quantlist__44u0__p5_0,
607.2697 +        0
607.2698 +};
607.2699 +
607.2700 +static const long _vq_quantlist__44u0__p6_0[] = {
607.2701 +        6,
607.2702 +        5,
607.2703 +        7,
607.2704 +        4,
607.2705 +        8,
607.2706 +        3,
607.2707 +        9,
607.2708 +        2,
607.2709 +        10,
607.2710 +        1,
607.2711 +        11,
607.2712 +        0,
607.2713 +        12,
607.2714 +};
607.2715 +
607.2716 +static const long _vq_lengthlist__44u0__p6_0[] = {
607.2717 +         1, 4, 4, 6, 6, 8, 8,10, 9,11,10,14,13, 4, 6, 5,
607.2718 +         8, 8, 9, 9,11,10,11,11,14,14, 4, 5, 6, 8, 8, 9,
607.2719 +         9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11,
607.2720 +        12,12,16,15, 7, 8, 8, 9, 9,10,10,11,11,12,12,15,
607.2721 +        15, 9,10,10,10,10,11,11,12,12,12,12,15,15, 9,10,
607.2722 +         9,10,11,11,11,12,12,12,13,15,15,10,10,11,11,11,
607.2723 +        12,12,13,12,13,13,16,15,10,11,11,11,11,12,12,13,
607.2724 +        12,13,13,16,17,11,11,12,12,12,13,13,13,14,14,15,
607.2725 +        17,17,11,11,12,12,12,13,13,13,14,14,14,16,18,14,
607.2726 +        15,15,15,15,16,16,16,16,17,18, 0, 0,14,15,15,15,
607.2727 +        15,17,16,17,18,17,17,18, 0,
607.2728 +};
607.2729 +
607.2730 +static const static_codebook _44u0__p6_0 = {
607.2731 +        2, 169,
607.2732 +        (long *)_vq_lengthlist__44u0__p6_0,
607.2733 +        1, -526516224, 1616117760, 4, 0,
607.2734 +        (long *)_vq_quantlist__44u0__p6_0,
607.2735 +        0
607.2736 +};
607.2737 +
607.2738 +static const long _vq_quantlist__44u0__p6_1[] = {
607.2739 +        2,
607.2740 +        1,
607.2741 +        3,
607.2742 +        0,
607.2743 +        4,
607.2744 +};
607.2745 +
607.2746 +static const long _vq_lengthlist__44u0__p6_1[] = {
607.2747 +         2, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5,
607.2748 +         6, 6, 6, 6, 5, 6, 6, 6, 6,
607.2749 +};
607.2750 +
607.2751 +static const static_codebook _44u0__p6_1 = {
607.2752 +        2, 25,
607.2753 +        (long *)_vq_lengthlist__44u0__p6_1,
607.2754 +        1, -533725184, 1611661312, 3, 0,
607.2755 +        (long *)_vq_quantlist__44u0__p6_1,
607.2756 +        0
607.2757 +};
607.2758 +
607.2759 +static const long _vq_quantlist__44u0__p7_0[] = {
607.2760 +        2,
607.2761 +        1,
607.2762 +        3,
607.2763 +        0,
607.2764 +        4,
607.2765 +};
607.2766 +
607.2767 +static const long _vq_lengthlist__44u0__p7_0[] = {
607.2768 +         1, 4, 4,11,11, 9,11,11,11,11,11,11,11,11,11,11,
607.2769 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2770 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2771 +        11,11, 9,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2772 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2773 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2774 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2775 +        11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,
607.2776 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2777 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2778 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2779 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2780 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2781 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2782 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2783 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2784 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2785 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2786 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2787 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2788 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2789 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2790 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2791 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2792 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2793 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2794 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2795 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2796 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2797 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.2798 +        11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,
607.2799 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2800 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2801 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2802 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2803 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2804 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2805 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2806 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.2807 +        10,
607.2808 +};
607.2809 +
607.2810 +static const static_codebook _44u0__p7_0 = {
607.2811 +        4, 625,
607.2812 +        (long *)_vq_lengthlist__44u0__p7_0,
607.2813 +        1, -518709248, 1626677248, 3, 0,
607.2814 +        (long *)_vq_quantlist__44u0__p7_0,
607.2815 +        0
607.2816 +};
607.2817 +
607.2818 +static const long _vq_quantlist__44u0__p7_1[] = {
607.2819 +        6,
607.2820 +        5,
607.2821 +        7,
607.2822 +        4,
607.2823 +        8,
607.2824 +        3,
607.2825 +        9,
607.2826 +        2,
607.2827 +        10,
607.2828 +        1,
607.2829 +        11,
607.2830 +        0,
607.2831 +        12,
607.2832 +};
607.2833 +
607.2834 +static const long _vq_lengthlist__44u0__p7_1[] = {
607.2835 +         1, 4, 4, 6, 6, 6, 6, 7, 7, 8, 8, 9, 9, 5, 7, 7,
607.2836 +         8, 7, 7, 7, 9, 8,10, 9,10,11, 5, 7, 7, 8, 8, 7,
607.2837 +         7, 8, 9,10,10,11,11, 6, 8, 8, 9, 9, 9, 9,11,10,
607.2838 +        12,12,15,12, 6, 8, 8, 9, 9, 9, 9,11,11,12,11,14,
607.2839 +        12, 7, 8, 8,10,10,12,12,13,13,13,15,13,13, 7, 8,
607.2840 +         8,10,10,11,11,13,12,14,15,15,15, 9,10,10,11,12,
607.2841 +        13,13,14,15,14,15,14,15, 8,10,10,12,12,14,14,15,
607.2842 +        14,14,15,15,14,10,12,12,14,14,15,14,15,15,15,14,
607.2843 +        15,15,10,12,12,13,14,15,14,15,15,14,15,15,15,12,
607.2844 +        15,13,15,14,15,15,15,15,15,15,15,15,13,13,15,15,
607.2845 +        15,15,15,15,15,15,15,15,15,
607.2846 +};
607.2847 +
607.2848 +static const static_codebook _44u0__p7_1 = {
607.2849 +        2, 169,
607.2850 +        (long *)_vq_lengthlist__44u0__p7_1,
607.2851 +        1, -523010048, 1618608128, 4, 0,
607.2852 +        (long *)_vq_quantlist__44u0__p7_1,
607.2853 +        0
607.2854 +};
607.2855 +
607.2856 +static const long _vq_quantlist__44u0__p7_2[] = {
607.2857 +        6,
607.2858 +        5,
607.2859 +        7,
607.2860 +        4,
607.2861 +        8,
607.2862 +        3,
607.2863 +        9,
607.2864 +        2,
607.2865 +        10,
607.2866 +        1,
607.2867 +        11,
607.2868 +        0,
607.2869 +        12,
607.2870 +};
607.2871 +
607.2872 +static const long _vq_lengthlist__44u0__p7_2[] = {
607.2873 +         2, 5, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 5, 5, 6,
607.2874 +         7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 5, 6, 5, 7, 7, 8,
607.2875 +         8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8, 8, 8, 8, 9, 8,
607.2876 +         9, 9, 9, 9, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9,
607.2877 +         9, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 7, 8,
607.2878 +         8, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9,
607.2879 +         9, 9, 9, 9, 9, 9,10,10, 8, 8, 9, 9, 9, 9, 9, 9,
607.2880 +         9, 9,10, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.2881 +         9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.2882 +         9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9,
607.2883 +         9, 9, 9,10, 9, 9,10,10, 9,
607.2884 +};
607.2885 +
607.2886 +static const static_codebook _44u0__p7_2 = {
607.2887 +        2, 169,
607.2888 +        (long *)_vq_lengthlist__44u0__p7_2,
607.2889 +        1, -531103744, 1611661312, 4, 0,
607.2890 +        (long *)_vq_quantlist__44u0__p7_2,
607.2891 +        0
607.2892 +};
607.2893 +
607.2894 +static const long _huff_lengthlist__44u0__short[] = {
607.2895 +        12,13,14,13,17,12,15,17, 5, 5, 6,10,10,11,15,16,
607.2896 +         4, 3, 3, 7, 5, 7,10,16, 7, 7, 7,10, 9,11,12,16,
607.2897 +         6, 5, 5, 9, 5, 6,10,16, 8, 7, 7, 9, 6, 7, 9,16,
607.2898 +        11, 7, 3, 6, 4, 5, 8,16,12, 9, 4, 8, 5, 7, 9,16,
607.2899 +};
607.2900 +
607.2901 +static const static_codebook _huff_book__44u0__short = {
607.2902 +        2, 64,
607.2903 +        (long *)_huff_lengthlist__44u0__short,
607.2904 +        0, 0, 0, 0, 0,
607.2905 +        NULL,
607.2906 +        0
607.2907 +};
607.2908 +
607.2909 +static const long _huff_lengthlist__44u1__long[] = {
607.2910 +         5, 8,13,10,17,11,11,15, 7, 2, 4, 5, 8, 7, 9,16,
607.2911 +        13, 4, 3, 5, 6, 8,11,20,10, 4, 5, 5, 7, 6, 8,18,
607.2912 +        15, 7, 6, 7, 8,10,14,20,10, 6, 7, 6, 9, 7, 8,17,
607.2913 +         9, 8,10, 8,10, 5, 4,11,12,17,19,14,16,10, 7,12,
607.2914 +};
607.2915 +
607.2916 +static const static_codebook _huff_book__44u1__long = {
607.2917 +        2, 64,
607.2918 +        (long *)_huff_lengthlist__44u1__long,
607.2919 +        0, 0, 0, 0, 0,
607.2920 +        NULL,
607.2921 +        0
607.2922 +};
607.2923 +
607.2924 +static const long _vq_quantlist__44u1__p1_0[] = {
607.2925 +        1,
607.2926 +        0,
607.2927 +        2,
607.2928 +};
607.2929 +
607.2930 +static const long _vq_lengthlist__44u1__p1_0[] = {
607.2931 +         1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8,
607.2932 +        10,10, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11,
607.2933 +        11, 8,11,11, 8,12,11,11,13,13,11,13,14, 7,11,11,
607.2934 +        10,13,12,11,13,14, 4, 8, 8, 8,11,11, 8,11,12, 8,
607.2935 +        11,11,11,13,13,10,12,13, 8,11,11,11,14,13,11,14,
607.2936 +        13,
607.2937 +};
607.2938 +
607.2939 +static const static_codebook _44u1__p1_0 = {
607.2940 +        4, 81,
607.2941 +        (long *)_vq_lengthlist__44u1__p1_0,
607.2942 +        1, -535822336, 1611661312, 2, 0,
607.2943 +        (long *)_vq_quantlist__44u1__p1_0,
607.2944 +        0
607.2945 +};
607.2946 +
607.2947 +static const long _vq_quantlist__44u1__p2_0[] = {
607.2948 +        1,
607.2949 +        0,
607.2950 +        2,
607.2951 +};
607.2952 +
607.2953 +static const long _vq_lengthlist__44u1__p2_0[] = {
607.2954 +         2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 8, 6,
607.2955 +         8, 8, 5, 7, 7, 6, 8, 8, 7, 8, 8, 4, 7, 7, 7, 8,
607.2956 +         8, 7, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8,
607.2957 +         8,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 8, 6,
607.2958 +         8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10,
607.2959 +         9,
607.2960 +};
607.2961 +
607.2962 +static const static_codebook _44u1__p2_0 = {
607.2963 +        4, 81,
607.2964 +        (long *)_vq_lengthlist__44u1__p2_0,
607.2965 +        1, -535822336, 1611661312, 2, 0,
607.2966 +        (long *)_vq_quantlist__44u1__p2_0,
607.2967 +        0
607.2968 +};
607.2969 +
607.2970 +static const long _vq_quantlist__44u1__p3_0[] = {
607.2971 +        2,
607.2972 +        1,
607.2973 +        3,
607.2974 +        0,
607.2975 +        4,
607.2976 +};
607.2977 +
607.2978 +static const long _vq_lengthlist__44u1__p3_0[] = {
607.2979 +         1, 5, 5, 8, 8, 5, 8, 7, 9, 9, 5, 7, 8, 9, 9, 9,
607.2980 +        10, 9,12,12, 9, 9,10,12,12, 6, 8, 8,11,10, 8,10,
607.2981 +        10,11,11, 8, 9,10,11,11,10,11,11,14,13,10,11,11,
607.2982 +        13,13, 5, 8, 8,10,10, 8,10,10,11,11, 8,10,10,11,
607.2983 +        11,10,11,11,13,13,10,11,11,13,13, 9,11,11,15,14,
607.2984 +        10,12,12,15,14,10,12,11,15,14,13,14,14,16,16,12,
607.2985 +        14,13,17,15, 9,11,11,14,15,10,11,12,14,16,10,11,
607.2986 +        12,14,16,12,13,14,16,16,13,13,15,15,18, 5, 8, 8,
607.2987 +        11,11, 8,10,10,12,12, 8,10,10,12,13,11,12,12,14,
607.2988 +        14,11,12,12,15,15, 8,10,10,13,13,10,12,12,13,13,
607.2989 +        10,12,12,14,14,12,13,13,15,15,12,13,13,16,16, 7,
607.2990 +        10,10,12,12,10,12,11,13,13,10,12,12,13,14,12,13,
607.2991 +        12,15,14,12,13,13,16,16,10,12,12,17,16,12,13,13,
607.2992 +        16,15,11,13,13,17,17,15,15,15,16,17,14,15,15,19,
607.2993 +        19,10,12,12,15,16,11,13,12,15,18,11,13,13,16,16,
607.2994 +        14,15,15,17,17,14,15,15,17,19, 5, 8, 8,11,11, 8,
607.2995 +        10,10,12,12, 8,10,10,12,12,11,12,12,16,15,11,12,
607.2996 +        12,14,15, 7,10,10,13,13,10,12,12,14,13,10,11,12,
607.2997 +        13,13,12,13,13,16,16,12,12,13,15,15, 8,10,10,13,
607.2998 +        13,10,12,12,14,14,10,12,12,13,13,12,13,13,16,16,
607.2999 +        12,13,13,15,15,10,12,12,16,15,11,13,13,17,16,11,
607.3000 +        12,13,16,15,13,15,15,19,17,14,15,14,17,16,10,12,
607.3001 +        12,16,16,11,13,13,16,17,12,13,13,15,17,14,15,15,
607.3002 +        17,19,14,15,15,17,17, 8,11,11,16,16,10,13,12,17,
607.3003 +        17,10,12,13,16,16,15,17,16,20,19,14,15,17,18,19,
607.3004 +         9,12,12,16,17,11,13,14,17,18,11,13,13,19,18,16,
607.3005 +        17,18,19,19,15,16,16,19,19, 9,12,12,16,17,11,14,
607.3006 +        13,18,17,11,13,13,17,17,16,17,16,20,19,14,16,16,
607.3007 +        18,18,12,15,15,19,17,14,15,16, 0,20,13,15,16,20,
607.3008 +        17,18,16,20, 0, 0,15,16,19,20, 0,12,15,14,18,19,
607.3009 +        13,16,15,20,19,13,16,15,20,18,17,18,17, 0,20,16,
607.3010 +        17,16, 0, 0, 8,11,11,16,15,10,12,12,17,17,10,13,
607.3011 +        13,17,16,14,16,15,18,20,15,16,16,19,19, 9,12,12,
607.3012 +        16,16,11,13,13,17,16,11,13,14,17,18,15,15,16,20,
607.3013 +        20,16,16,17,19,19, 9,13,12,16,17,11,14,13,17,17,
607.3014 +        11,14,14,18,17,14,16,15,18,19,16,17,18,18,19,12,
607.3015 +        14,15,19,18,13,15,16,18, 0,13,14,15, 0, 0,16,16,
607.3016 +        17,20, 0,17,17,20,20, 0,12,15,15,19,20,13,15,15,
607.3017 +         0, 0,14,16,15, 0, 0,15,18,16, 0, 0,17,18,16, 0,
607.3018 +        19,
607.3019 +};
607.3020 +
607.3021 +static const static_codebook _44u1__p3_0 = {
607.3022 +        4, 625,
607.3023 +        (long *)_vq_lengthlist__44u1__p3_0,
607.3024 +        1, -533725184, 1611661312, 3, 0,
607.3025 +        (long *)_vq_quantlist__44u1__p3_0,
607.3026 +        0
607.3027 +};
607.3028 +
607.3029 +static const long _vq_quantlist__44u1__p4_0[] = {
607.3030 +        2,
607.3031 +        1,
607.3032 +        3,
607.3033 +        0,
607.3034 +        4,
607.3035 +};
607.3036 +
607.3037 +static const long _vq_lengthlist__44u1__p4_0[] = {
607.3038 +         4, 5, 5, 9, 9, 5, 6, 6, 9, 9, 5, 6, 6, 9, 9, 9,
607.3039 +        10, 9,12,12, 9, 9,10,12,12, 5, 7, 7,10,10, 7, 7,
607.3040 +         8,10,10, 6, 7, 8,10,10,10,10,10,11,13,10, 9,10,
607.3041 +        12,13, 5, 7, 7,10,10, 6, 8, 7,10,10, 7, 8, 7,10,
607.3042 +        10, 9,10,10,12,12,10,10,10,13,11, 9,10,10,13,13,
607.3043 +        10,11,10,13,13,10,10,10,13,13,12,12,13,14,14,12,
607.3044 +        12,13,14,14, 9,10,10,13,13,10,10,10,13,13,10,10,
607.3045 +        10,13,13,12,13,12,15,14,12,13,12,15,15, 5, 7, 6,
607.3046 +        10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,13,
607.3047 +        13,10,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,10,11,
607.3048 +         8, 9, 9,11,11,11,10,11,11,14,11,11,11,13,13, 6,
607.3049 +         8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
607.3050 +        10,14,11,10,11,11,13,13,10,11,11,14,13,10,10,11,
607.3051 +        14,13,10,11,11,14,14,12,11,13,12,16,13,14,14,15,
607.3052 +        15,10,10,11,13,14,10,11,10,14,13,10,11,11,14,14,
607.3053 +        12,13,12,15,13,13,13,14,15,16, 5, 7, 7,10,10, 7,
607.3054 +         8, 8,10,10, 7, 8, 8,10,10,10,10,10,13,13,10,10,
607.3055 +        11,12,13, 6, 8, 8,11,10, 8, 9, 9,11,11, 7, 8, 9,
607.3056 +        10,11,10,11,11,13,13,10,10,11,11,13, 6, 8, 8,10,
607.3057 +        11, 8, 9, 9,11,11, 8, 9, 8,12,10,10,11,11,13,13,
607.3058 +        10,11,10,14,11,10,10,10,14,13,10,11,11,14,13,10,
607.3059 +        10,11,13,13,12,14,14,16,16,12,12,13,13,15,10,11,
607.3060 +        11,13,14,10,11,11,14,15,10,11,10,13,13,13,14,13,
607.3061 +        16,16,12,13,11,15,12, 9,10,10,13,13,10,11,11,14,
607.3062 +        13,10,10,11,13,14,13,14,13,16,16,13,13,13,15,16,
607.3063 +         9,10,10,13,13,10,10,11,13,14,10,11,11,15,13,13,
607.3064 +        13,14,14,18,13,13,14,16,15, 9,10,10,13,14,10,11,
607.3065 +        10,14,13,10,11,11,13,14,13,14,13,16,15,13,13,14,
607.3066 +        15,16,12,13,12,16,14,11,11,13,15,15,13,14,13,16,
607.3067 +        15,15,12,16,12,17,14,15,15,17,17,12,13,13,14,16,
607.3068 +        11,13,11,16,15,12,13,14,15,16,14,15,13, 0,14,14,
607.3069 +        16,16, 0, 0, 9,10,10,13,13,10,11,10,14,14,10,11,
607.3070 +        11,13,13,12,13,13,14,16,13,14,14,16,16, 9,10,10,
607.3071 +        14,14,11,11,11,14,13,10,10,11,14,14,13,13,13,16,
607.3072 +        16,13,13,14,14,17, 9,10,10,13,14,10,11,11,13,15,
607.3073 +        10,11,10,14,14,13,13,13,14,17,13,14,13,17,14,12,
607.3074 +        13,13,16,14,13,14,13,16,15,12,12,13,15,16,15,15,
607.3075 +        16,18,16,15,13,15,14, 0,12,12,13,14,16,13,13,14,
607.3076 +        15,16,11,12,11,16,14,15,16,16,17,17,14,15,12,17,
607.3077 +        12,
607.3078 +};
607.3079 +
607.3080 +static const static_codebook _44u1__p4_0 = {
607.3081 +        4, 625,
607.3082 +        (long *)_vq_lengthlist__44u1__p4_0,
607.3083 +        1, -533725184, 1611661312, 3, 0,
607.3084 +        (long *)_vq_quantlist__44u1__p4_0,
607.3085 +        0
607.3086 +};
607.3087 +
607.3088 +static const long _vq_quantlist__44u1__p5_0[] = {
607.3089 +        4,
607.3090 +        3,
607.3091 +        5,
607.3092 +        2,
607.3093 +        6,
607.3094 +        1,
607.3095 +        7,
607.3096 +        0,
607.3097 +        8,
607.3098 +};
607.3099 +
607.3100 +static const long _vq_lengthlist__44u1__p5_0[] = {
607.3101 +         1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8,
607.3102 +         9, 9, 4, 6, 6, 8, 8, 8, 8, 9, 9, 7, 8, 8, 9, 9,
607.3103 +         9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,10, 7, 8, 8,
607.3104 +         9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
607.3105 +         9, 9,10,10,11,11,12,12, 9, 9, 9,10,11,11,11,12,
607.3106 +        12,
607.3107 +};
607.3108 +
607.3109 +static const static_codebook _44u1__p5_0 = {
607.3110 +        2, 81,
607.3111 +        (long *)_vq_lengthlist__44u1__p5_0,
607.3112 +        1, -531628032, 1611661312, 4, 0,
607.3113 +        (long *)_vq_quantlist__44u1__p5_0,
607.3114 +        0
607.3115 +};
607.3116 +
607.3117 +static const long _vq_quantlist__44u1__p6_0[] = {
607.3118 +        6,
607.3119 +        5,
607.3120 +        7,
607.3121 +        4,
607.3122 +        8,
607.3123 +        3,
607.3124 +        9,
607.3125 +        2,
607.3126 +        10,
607.3127 +        1,
607.3128 +        11,
607.3129 +        0,
607.3130 +        12,
607.3131 +};
607.3132 +
607.3133 +static const long _vq_lengthlist__44u1__p6_0[] = {
607.3134 +         1, 4, 4, 6, 6, 8, 8,10, 9,11,10,14,13, 4, 6, 5,
607.3135 +         8, 8, 9, 9,11,10,11,11,14,14, 4, 5, 6, 8, 8, 9,
607.3136 +         9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11,
607.3137 +        12,12,16,15, 7, 8, 8, 9, 9,10,10,11,11,12,12,15,
607.3138 +        15, 9,10,10,10,10,11,11,12,12,12,12,15,15, 9,10,
607.3139 +         9,10,11,11,11,12,12,12,13,15,15,10,10,11,11,11,
607.3140 +        12,12,13,12,13,13,16,15,10,11,11,11,11,12,12,13,
607.3141 +        12,13,13,16,17,11,11,12,12,12,13,13,13,14,14,15,
607.3142 +        17,17,11,11,12,12,12,13,13,13,14,14,14,16,18,14,
607.3143 +        15,15,15,15,16,16,16,16,17,18, 0, 0,14,15,15,15,
607.3144 +        15,17,16,17,18,17,17,18, 0,
607.3145 +};
607.3146 +
607.3147 +static const static_codebook _44u1__p6_0 = {
607.3148 +        2, 169,
607.3149 +        (long *)_vq_lengthlist__44u1__p6_0,
607.3150 +        1, -526516224, 1616117760, 4, 0,
607.3151 +        (long *)_vq_quantlist__44u1__p6_0,
607.3152 +        0
607.3153 +};
607.3154 +
607.3155 +static const long _vq_quantlist__44u1__p6_1[] = {
607.3156 +        2,
607.3157 +        1,
607.3158 +        3,
607.3159 +        0,
607.3160 +        4,
607.3161 +};
607.3162 +
607.3163 +static const long _vq_lengthlist__44u1__p6_1[] = {
607.3164 +         2, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5,
607.3165 +         6, 6, 6, 6, 5, 6, 6, 6, 6,
607.3166 +};
607.3167 +
607.3168 +static const static_codebook _44u1__p6_1 = {
607.3169 +        2, 25,
607.3170 +        (long *)_vq_lengthlist__44u1__p6_1,
607.3171 +        1, -533725184, 1611661312, 3, 0,
607.3172 +        (long *)_vq_quantlist__44u1__p6_1,
607.3173 +        0
607.3174 +};
607.3175 +
607.3176 +static const long _vq_quantlist__44u1__p7_0[] = {
607.3177 +        3,
607.3178 +        2,
607.3179 +        4,
607.3180 +        1,
607.3181 +        5,
607.3182 +        0,
607.3183 +        6,
607.3184 +};
607.3185 +
607.3186 +static const long _vq_lengthlist__44u1__p7_0[] = {
607.3187 +         1, 3, 2, 9, 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.3188 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.3189 +         9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
607.3190 +         8,
607.3191 +};
607.3192 +
607.3193 +static const static_codebook _44u1__p7_0 = {
607.3194 +        2, 49,
607.3195 +        (long *)_vq_lengthlist__44u1__p7_0,
607.3196 +        1, -518017024, 1626677248, 3, 0,
607.3197 +        (long *)_vq_quantlist__44u1__p7_0,
607.3198 +        0
607.3199 +};
607.3200 +
607.3201 +static const long _vq_quantlist__44u1__p7_1[] = {
607.3202 +        6,
607.3203 +        5,
607.3204 +        7,
607.3205 +        4,
607.3206 +        8,
607.3207 +        3,
607.3208 +        9,
607.3209 +        2,
607.3210 +        10,
607.3211 +        1,
607.3212 +        11,
607.3213 +        0,
607.3214 +        12,
607.3215 +};
607.3216 +
607.3217 +static const long _vq_lengthlist__44u1__p7_1[] = {
607.3218 +         1, 4, 4, 6, 6, 6, 6, 7, 7, 8, 8, 9, 9, 5, 7, 7,
607.3219 +         8, 7, 7, 7, 9, 8,10, 9,10,11, 5, 7, 7, 8, 8, 7,
607.3220 +         7, 8, 9,10,10,11,11, 6, 8, 8, 9, 9, 9, 9,11,10,
607.3221 +        12,12,15,12, 6, 8, 8, 9, 9, 9, 9,11,11,12,11,14,
607.3222 +        12, 7, 8, 8,10,10,12,12,13,13,13,15,13,13, 7, 8,
607.3223 +         8,10,10,11,11,13,12,14,15,15,15, 9,10,10,11,12,
607.3224 +        13,13,14,15,14,15,14,15, 8,10,10,12,12,14,14,15,
607.3225 +        14,14,15,15,14,10,12,12,14,14,15,14,15,15,15,14,
607.3226 +        15,15,10,12,12,13,14,15,14,15,15,14,15,15,15,12,
607.3227 +        15,13,15,14,15,15,15,15,15,15,15,15,13,13,15,15,
607.3228 +        15,15,15,15,15,15,15,15,15,
607.3229 +};
607.3230 +
607.3231 +static const static_codebook _44u1__p7_1 = {
607.3232 +        2, 169,
607.3233 +        (long *)_vq_lengthlist__44u1__p7_1,
607.3234 +        1, -523010048, 1618608128, 4, 0,
607.3235 +        (long *)_vq_quantlist__44u1__p7_1,
607.3236 +        0
607.3237 +};
607.3238 +
607.3239 +static const long _vq_quantlist__44u1__p7_2[] = {
607.3240 +        6,
607.3241 +        5,
607.3242 +        7,
607.3243 +        4,
607.3244 +        8,
607.3245 +        3,
607.3246 +        9,
607.3247 +        2,
607.3248 +        10,
607.3249 +        1,
607.3250 +        11,
607.3251 +        0,
607.3252 +        12,
607.3253 +};
607.3254 +
607.3255 +static const long _vq_lengthlist__44u1__p7_2[] = {
607.3256 +         2, 5, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 5, 5, 6,
607.3257 +         7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 5, 6, 5, 7, 7, 8,
607.3258 +         8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8, 8, 8, 8, 9, 8,
607.3259 +         9, 9, 9, 9, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9,
607.3260 +         9, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 7, 8,
607.3261 +         8, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9,
607.3262 +         9, 9, 9, 9, 9, 9,10,10, 8, 8, 9, 9, 9, 9, 9, 9,
607.3263 +         9, 9,10, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.3264 +         9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.3265 +         9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9,
607.3266 +         9, 9, 9,10, 9, 9,10,10, 9,
607.3267 +};
607.3268 +
607.3269 +static const static_codebook _44u1__p7_2 = {
607.3270 +        2, 169,
607.3271 +        (long *)_vq_lengthlist__44u1__p7_2,
607.3272 +        1, -531103744, 1611661312, 4, 0,
607.3273 +        (long *)_vq_quantlist__44u1__p7_2,
607.3274 +        0
607.3275 +};
607.3276 +
607.3277 +static const long _huff_lengthlist__44u1__short[] = {
607.3278 +        12,13,14,13,17,12,15,17, 5, 5, 6,10,10,11,15,16,
607.3279 +         4, 3, 3, 7, 5, 7,10,16, 7, 7, 7,10, 9,11,12,16,
607.3280 +         6, 5, 5, 9, 5, 6,10,16, 8, 7, 7, 9, 6, 7, 9,16,
607.3281 +        11, 7, 3, 6, 4, 5, 8,16,12, 9, 4, 8, 5, 7, 9,16,
607.3282 +};
607.3283 +
607.3284 +static const static_codebook _huff_book__44u1__short = {
607.3285 +        2, 64,
607.3286 +        (long *)_huff_lengthlist__44u1__short,
607.3287 +        0, 0, 0, 0, 0,
607.3288 +        NULL,
607.3289 +        0
607.3290 +};
607.3291 +
607.3292 +static const long _huff_lengthlist__44u2__long[] = {
607.3293 +         5, 9,14,12,15,13,10,13, 7, 4, 5, 6, 8, 7, 8,12,
607.3294 +        13, 4, 3, 5, 5, 6, 9,15,12, 6, 5, 6, 6, 6, 7,14,
607.3295 +        14, 7, 4, 6, 4, 6, 8,15,12, 6, 6, 5, 5, 5, 6,14,
607.3296 +         9, 7, 8, 6, 7, 5, 4,10,10,13,14,14,15,10, 6, 8,
607.3297 +};
607.3298 +
607.3299 +static const static_codebook _huff_book__44u2__long = {
607.3300 +        2, 64,
607.3301 +        (long *)_huff_lengthlist__44u2__long,
607.3302 +        0, 0, 0, 0, 0,
607.3303 +        NULL,
607.3304 +        0
607.3305 +};
607.3306 +
607.3307 +static const long _vq_quantlist__44u2__p1_0[] = {
607.3308 +        1,
607.3309 +        0,
607.3310 +        2,
607.3311 +};
607.3312 +
607.3313 +static const long _vq_lengthlist__44u2__p1_0[] = {
607.3314 +         1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8,
607.3315 +        10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11,
607.3316 +        11, 8,11,11, 8,11,11,11,13,14,11,13,13, 7,11,11,
607.3317 +        10,13,12,11,14,14, 4, 8, 8, 8,11,11, 8,11,11, 8,
607.3318 +        11,11,11,14,13,10,12,13, 8,11,11,11,13,13,11,13,
607.3319 +        13,
607.3320 +};
607.3321 +
607.3322 +static const static_codebook _44u2__p1_0 = {
607.3323 +        4, 81,
607.3324 +        (long *)_vq_lengthlist__44u2__p1_0,
607.3325 +        1, -535822336, 1611661312, 2, 0,
607.3326 +        (long *)_vq_quantlist__44u2__p1_0,
607.3327 +        0
607.3328 +};
607.3329 +
607.3330 +static const long _vq_quantlist__44u2__p2_0[] = {
607.3331 +        1,
607.3332 +        0,
607.3333 +        2,
607.3334 +};
607.3335 +
607.3336 +static const long _vq_lengthlist__44u2__p2_0[] = {
607.3337 +         2, 5, 5, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6,
607.3338 +         8, 8, 5, 6, 6, 6, 8, 7, 7, 8, 8, 5, 6, 6, 7, 8,
607.3339 +         8, 6, 8, 8, 6, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8,
607.3340 +         7,10, 8, 8,10,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6,
607.3341 +         8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10,
607.3342 +         9,
607.3343 +};
607.3344 +
607.3345 +static const static_codebook _44u2__p2_0 = {
607.3346 +        4, 81,
607.3347 +        (long *)_vq_lengthlist__44u2__p2_0,
607.3348 +        1, -535822336, 1611661312, 2, 0,
607.3349 +        (long *)_vq_quantlist__44u2__p2_0,
607.3350 +        0
607.3351 +};
607.3352 +
607.3353 +static const long _vq_quantlist__44u2__p3_0[] = {
607.3354 +        2,
607.3355 +        1,
607.3356 +        3,
607.3357 +        0,
607.3358 +        4,
607.3359 +};
607.3360 +
607.3361 +static const long _vq_lengthlist__44u2__p3_0[] = {
607.3362 +         2, 4, 4, 7, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8,
607.3363 +         9, 9,12,11, 8, 9, 9,11,12, 5, 7, 7,10,10, 7, 9,
607.3364 +         9,11,11, 7, 9, 9,10,11,10,11,11,13,13, 9,10,11,
607.3365 +        12,13, 5, 7, 7,10,10, 7, 9, 9,11,10, 7, 9, 9,11,
607.3366 +        11, 9,11,10,13,13,10,11,11,13,13, 8,10,10,14,13,
607.3367 +        10,11,11,15,14, 9,11,11,15,14,13,14,13,16,14,12,
607.3368 +        13,13,15,16, 8,10,10,13,14, 9,11,11,14,15,10,11,
607.3369 +        11,14,15,12,13,13,15,15,12,13,14,15,16, 5, 7, 7,
607.3370 +        10,10, 7, 9, 9,11,11, 7, 9, 9,11,12,10,11,11,14,
607.3371 +        13,10,11,11,14,14, 7, 9, 9,12,12, 9,11,11,13,13,
607.3372 +         9,11,11,13,13,12,13,12,14,14,11,12,13,15,15, 7,
607.3373 +         9, 9,12,12, 8,11,10,13,12, 9,11,11,13,13,11,13,
607.3374 +        12,15,13,11,13,13,15,16, 9,12,11,15,15,11,12,12,
607.3375 +        16,15,11,12,13,16,16,13,14,15,16,15,13,15,15,17,
607.3376 +        17, 9,11,11,14,15,10,12,12,15,15,11,13,12,15,16,
607.3377 +        13,15,14,16,16,13,15,15,17,19, 5, 7, 7,10,10, 7,
607.3378 +         9, 9,12,11, 7, 9, 9,11,11,10,11,11,14,14,10,11,
607.3379 +        11,13,14, 7, 9, 9,12,12, 9,11,11,13,13, 9,10,11,
607.3380 +        12,13,11,13,12,16,15,11,12,12,14,15, 7, 9, 9,12,
607.3381 +        12, 9,11,11,13,13, 9,11,11,13,12,11,13,12,15,16,
607.3382 +        12,13,13,15,14, 9,11,11,15,14,11,13,12,16,15,10,
607.3383 +        11,12,15,15,13,14,14,18,17,13,14,14,15,17,10,11,
607.3384 +        11,14,15,11,13,12,15,17,11,13,12,15,16,13,15,14,
607.3385 +        18,17,14,15,15,16,18, 7,10,10,14,14,10,12,12,15,
607.3386 +        15,10,12,12,15,15,14,15,15,18,17,13,15,15,16,16,
607.3387 +         9,11,11,16,15,11,13,13,16,18,11,13,13,16,16,15,
607.3388 +        16,16, 0, 0,14,15,16,18,17, 9,11,11,15,15,10,13,
607.3389 +        12,17,16,11,12,13,16,17,14,15,16,19,19,14,15,15,
607.3390 +         0,20,12,14,14, 0, 0,13,14,16,19,18,13,15,16,20,
607.3391 +        17,16,18, 0, 0, 0,15,16,17,18,19,11,14,14, 0,19,
607.3392 +        12,15,14,17,17,13,15,15, 0, 0,16,17,15,20,19,15,
607.3393 +        17,16,19, 0, 8,10,10,14,15,10,12,11,15,15,10,11,
607.3394 +        12,16,15,13,14,14,19,17,14,15,15, 0, 0, 9,11,11,
607.3395 +        16,15,11,13,13,17,16,10,12,13,16,17,14,15,15,18,
607.3396 +        18,14,15,16,20,19, 9,12,12, 0,15,11,13,13,16,17,
607.3397 +        11,13,13,19,17,14,16,16,18,17,15,16,16,17,19,11,
607.3398 +        14,14,18,18,13,14,15, 0, 0,12,14,15,19,18,15,16,
607.3399 +        19, 0,19,15,16,19,19,17,12,14,14,16,19,13,15,15,
607.3400 +         0,17,13,15,14,18,18,15,16,15, 0,18,16,17,17, 0,
607.3401 +         0,
607.3402 +};
607.3403 +
607.3404 +static const static_codebook _44u2__p3_0 = {
607.3405 +        4, 625,
607.3406 +        (long *)_vq_lengthlist__44u2__p3_0,
607.3407 +        1, -533725184, 1611661312, 3, 0,
607.3408 +        (long *)_vq_quantlist__44u2__p3_0,
607.3409 +        0
607.3410 +};
607.3411 +
607.3412 +static const long _vq_quantlist__44u2__p4_0[] = {
607.3413 +        2,
607.3414 +        1,
607.3415 +        3,
607.3416 +        0,
607.3417 +        4,
607.3418 +};
607.3419 +
607.3420 +static const long _vq_lengthlist__44u2__p4_0[] = {
607.3421 +         4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 9,
607.3422 +         9, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8,
607.3423 +         8,10,10, 7, 7, 8,10,10,10,10,10,11,12, 9,10,10,
607.3424 +        11,12, 5, 7, 7, 9, 9, 6, 8, 7,10,10, 7, 8, 8,10,
607.3425 +        10, 9,10,10,12,11, 9,10,10,12,11, 9,10,10,12,12,
607.3426 +        10,10,10,13,12, 9,10,10,12,13,12,12,12,14,14,11,
607.3427 +        12,12,13,14, 9,10,10,12,12, 9,10,10,12,13,10,10,
607.3428 +        10,12,13,11,12,12,14,13,12,12,12,14,13, 5, 7, 7,
607.3429 +        10, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,
607.3430 +        12,10,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,11,11,
607.3431 +         8, 9, 9,11,11,10,11,11,12,13,10,11,11,13,13, 6,
607.3432 +         8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
607.3433 +        10,13,11,10,11,11,13,13, 9,10,10,13,13,10,11,11,
607.3434 +        13,13,10,11,11,14,13,12,11,13,12,15,12,13,13,15,
607.3435 +        15, 9,10,10,12,13,10,11,10,13,13,10,11,11,13,13,
607.3436 +        12,13,11,15,13,12,13,13,15,15, 5, 7, 7, 9,10, 7,
607.3437 +         8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,12,10,10,
607.3438 +        11,12,12, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 8, 9,
607.3439 +        10,11,10,11,11,13,13,10,10,11,11,13, 7, 8, 8,10,
607.3440 +        11, 8, 9, 9,11,11, 8, 9, 8,11,11,10,11,11,13,13,
607.3441 +        10,11,11,13,12, 9,10,10,13,12,10,11,11,14,13,10,
607.3442 +        10,11,13,13,12,13,13,15,15,12,11,13,12,14, 9,10,
607.3443 +        10,12,13,10,11,11,13,14,10,11,11,13,13,12,13,13,
607.3444 +        15,15,12,13,12,15,12, 8, 9, 9,12,12, 9,11,10,13,
607.3445 +        13, 9,10,10,13,13,12,13,13,15,15,12,12,12,14,14,
607.3446 +         9,10,10,13,13,10,11,11,13,14,10,11,11,14,12,13,
607.3447 +        13,14,14,16,12,13,13,15,14, 9,10,10,13,13,10,11,
607.3448 +        10,14,13,10,11,11,13,14,12,14,13,16,14,13,13,13,
607.3449 +        14,15,11,13,12,15,14,11,12,13,14,15,12,13,13,16,
607.3450 +        15,14,12,15,12,16,14,15,15,17,16,11,12,12,14,15,
607.3451 +        11,13,11,15,14,12,13,13,15,16,13,15,12,17,13,14,
607.3452 +        15,15,16,16, 8, 9, 9,12,12, 9,10,10,13,13, 9,10,
607.3453 +        10,13,13,12,13,12,14,14,12,13,13,15,15, 9,10,10,
607.3454 +        13,13,10,11,11,14,13,10,10,11,13,14,12,13,13,15,
607.3455 +        14,12,12,14,14,16, 9,10,10,13,13,10,11,11,13,14,
607.3456 +        10,11,11,14,13,13,13,13,15,15,13,14,13,16,14,11,
607.3457 +        12,12,14,14,12,13,13,16,15,11,12,13,14,15,14,15,
607.3458 +        15,16,16,14,13,15,13,17,11,12,12,14,15,12,13,13,
607.3459 +        15,16,11,13,12,15,15,14,15,14,16,16,14,15,12,17,
607.3460 +        13,
607.3461 +};
607.3462 +
607.3463 +static const static_codebook _44u2__p4_0 = {
607.3464 +        4, 625,
607.3465 +        (long *)_vq_lengthlist__44u2__p4_0,
607.3466 +        1, -533725184, 1611661312, 3, 0,
607.3467 +        (long *)_vq_quantlist__44u2__p4_0,
607.3468 +        0
607.3469 +};
607.3470 +
607.3471 +static const long _vq_quantlist__44u2__p5_0[] = {
607.3472 +        4,
607.3473 +        3,
607.3474 +        5,
607.3475 +        2,
607.3476 +        6,
607.3477 +        1,
607.3478 +        7,
607.3479 +        0,
607.3480 +        8,
607.3481 +};
607.3482 +
607.3483 +static const long _vq_lengthlist__44u2__p5_0[] = {
607.3484 +         1, 4, 4, 7, 7, 8, 8, 9, 9, 4, 6, 5, 8, 8, 8, 8,
607.3485 +        10,10, 4, 5, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9,
607.3486 +         9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 8, 8, 8,
607.3487 +         9, 9,10,11,12,12, 8, 8, 8, 9, 9,10,10,12,12,10,
607.3488 +        10,10,11,11,12,12,13,13,10,10,10,11,11,12,12,13,
607.3489 +        13,
607.3490 +};
607.3491 +
607.3492 +static const static_codebook _44u2__p5_0 = {
607.3493 +        2, 81,
607.3494 +        (long *)_vq_lengthlist__44u2__p5_0,
607.3495 +        1, -531628032, 1611661312, 4, 0,
607.3496 +        (long *)_vq_quantlist__44u2__p5_0,
607.3497 +        0
607.3498 +};
607.3499 +
607.3500 +static const long _vq_quantlist__44u2__p6_0[] = {
607.3501 +        6,
607.3502 +        5,
607.3503 +        7,
607.3504 +        4,
607.3505 +        8,
607.3506 +        3,
607.3507 +        9,
607.3508 +        2,
607.3509 +        10,
607.3510 +        1,
607.3511 +        11,
607.3512 +        0,
607.3513 +        12,
607.3514 +};
607.3515 +
607.3516 +static const long _vq_lengthlist__44u2__p6_0[] = {
607.3517 +         1, 4, 4, 6, 6, 8, 8,10,10,11,11,14,13, 4, 6, 5,
607.3518 +         8, 8, 9, 9,11,10,12,11,15,14, 4, 5, 6, 8, 8, 9,
607.3519 +         9,11,11,11,11,14,14, 6, 8, 8,10, 9,11,11,11,11,
607.3520 +        12,12,15,15, 6, 8, 8, 9, 9,11,11,11,12,12,12,15,
607.3521 +        15, 8,10,10,11,11,11,11,12,12,13,13,15,16, 8,10,
607.3522 +        10,11,11,11,11,12,12,13,13,16,16,10,11,11,12,12,
607.3523 +        12,12,13,13,13,13,17,16,10,11,11,12,12,12,12,13,
607.3524 +        13,13,14,16,17,11,12,12,13,13,13,13,14,14,15,14,
607.3525 +        18,17,11,12,12,13,13,13,13,14,14,14,15,19,18,14,
607.3526 +        15,15,15,15,16,16,18,19,18,18, 0, 0,14,15,15,16,
607.3527 +        15,17,17,16,18,17,18, 0, 0,
607.3528 +};
607.3529 +
607.3530 +static const static_codebook _44u2__p6_0 = {
607.3531 +        2, 169,
607.3532 +        (long *)_vq_lengthlist__44u2__p6_0,
607.3533 +        1, -526516224, 1616117760, 4, 0,
607.3534 +        (long *)_vq_quantlist__44u2__p6_0,
607.3535 +        0
607.3536 +};
607.3537 +
607.3538 +static const long _vq_quantlist__44u2__p6_1[] = {
607.3539 +        2,
607.3540 +        1,
607.3541 +        3,
607.3542 +        0,
607.3543 +        4,
607.3544 +};
607.3545 +
607.3546 +static const long _vq_lengthlist__44u2__p6_1[] = {
607.3547 +         2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5,
607.3548 +         6, 5, 6, 6, 5, 5, 6, 6, 6,
607.3549 +};
607.3550 +
607.3551 +static const static_codebook _44u2__p6_1 = {
607.3552 +        2, 25,
607.3553 +        (long *)_vq_lengthlist__44u2__p6_1,
607.3554 +        1, -533725184, 1611661312, 3, 0,
607.3555 +        (long *)_vq_quantlist__44u2__p6_1,
607.3556 +        0
607.3557 +};
607.3558 +
607.3559 +static const long _vq_quantlist__44u2__p7_0[] = {
607.3560 +        4,
607.3561 +        3,
607.3562 +        5,
607.3563 +        2,
607.3564 +        6,
607.3565 +        1,
607.3566 +        7,
607.3567 +        0,
607.3568 +        8,
607.3569 +};
607.3570 +
607.3571 +static const long _vq_lengthlist__44u2__p7_0[] = {
607.3572 +         1, 3, 2,12,12,12,12,12,12, 4,12,12,12,12,12,12,
607.3573 +        12,12, 5,12,12,12,12,12,12,12,12,12,12,11,11,11,
607.3574 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.3575 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.3576 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.3577 +        11,
607.3578 +};
607.3579 +
607.3580 +static const static_codebook _44u2__p7_0 = {
607.3581 +        2, 81,
607.3582 +        (long *)_vq_lengthlist__44u2__p7_0,
607.3583 +        1, -516612096, 1626677248, 4, 0,
607.3584 +        (long *)_vq_quantlist__44u2__p7_0,
607.3585 +        0
607.3586 +};
607.3587 +
607.3588 +static const long _vq_quantlist__44u2__p7_1[] = {
607.3589 +        6,
607.3590 +        5,
607.3591 +        7,
607.3592 +        4,
607.3593 +        8,
607.3594 +        3,
607.3595 +        9,
607.3596 +        2,
607.3597 +        10,
607.3598 +        1,
607.3599 +        11,
607.3600 +        0,
607.3601 +        12,
607.3602 +};
607.3603 +
607.3604 +static const long _vq_lengthlist__44u2__p7_1[] = {
607.3605 +         1, 4, 4, 7, 6, 7, 6, 8, 7, 9, 7, 9, 8, 4, 7, 6,
607.3606 +         8, 8, 9, 8,10, 9,10,10,11,11, 4, 7, 7, 8, 8, 8,
607.3607 +         8, 9,10,11,11,11,11, 6, 8, 8,10,10,10,10,11,11,
607.3608 +        12,12,12,12, 7, 8, 8,10,10,10,10,11,11,12,12,13,
607.3609 +        13, 7, 9, 9,11,10,12,12,13,13,14,13,14,14, 7, 9,
607.3610 +         9,10,11,11,12,13,13,13,13,16,14, 9,10,10,12,12,
607.3611 +        13,13,14,14,15,16,15,16, 9,10,10,12,12,12,13,14,
607.3612 +        14,14,15,16,15,10,12,12,13,13,15,13,16,16,15,17,
607.3613 +        17,17,10,11,11,12,14,14,14,15,15,17,17,15,17,11,
607.3614 +        12,12,14,14,14,15,15,15,17,16,17,17,10,12,12,13,
607.3615 +        14,14,14,17,15,17,17,17,17,
607.3616 +};
607.3617 +
607.3618 +static const static_codebook _44u2__p7_1 = {
607.3619 +        2, 169,
607.3620 +        (long *)_vq_lengthlist__44u2__p7_1,
607.3621 +        1, -523010048, 1618608128, 4, 0,
607.3622 +        (long *)_vq_quantlist__44u2__p7_1,
607.3623 +        0
607.3624 +};
607.3625 +
607.3626 +static const long _vq_quantlist__44u2__p7_2[] = {
607.3627 +        6,
607.3628 +        5,
607.3629 +        7,
607.3630 +        4,
607.3631 +        8,
607.3632 +        3,
607.3633 +        9,
607.3634 +        2,
607.3635 +        10,
607.3636 +        1,
607.3637 +        11,
607.3638 +        0,
607.3639 +        12,
607.3640 +};
607.3641 +
607.3642 +static const long _vq_lengthlist__44u2__p7_2[] = {
607.3643 +         2, 5, 5, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 5, 6, 6,
607.3644 +         7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 5, 6, 6, 7, 7, 8,
607.3645 +         7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7, 8, 8, 8, 8, 8,
607.3646 +         9, 9, 9, 9, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9,
607.3647 +         9, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 7, 8,
607.3648 +         8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 9,
607.3649 +         9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9,
607.3650 +         9, 9, 9, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.3651 +         9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
607.3652 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9,
607.3653 +         9, 9, 9, 9, 9, 9, 9, 9, 9,
607.3654 +};
607.3655 +
607.3656 +static const static_codebook _44u2__p7_2 = {
607.3657 +        2, 169,
607.3658 +        (long *)_vq_lengthlist__44u2__p7_2,
607.3659 +        1, -531103744, 1611661312, 4, 0,
607.3660 +        (long *)_vq_quantlist__44u2__p7_2,
607.3661 +        0
607.3662 +};
607.3663 +
607.3664 +static const long _huff_lengthlist__44u2__short[] = {
607.3665 +        13,15,17,17,15,15,12,17,11, 9, 7,10,10, 9,12,17,
607.3666 +        10, 6, 3, 6, 5, 7,10,17,15,10, 6, 9, 8, 9,11,17,
607.3667 +        15, 8, 4, 7, 3, 5, 9,16,16,10, 5, 8, 4, 5, 8,16,
607.3668 +        13,11, 5, 8, 3, 3, 5,14,13,12, 7,10, 5, 5, 7,14,
607.3669 +};
607.3670 +
607.3671 +static const static_codebook _huff_book__44u2__short = {
607.3672 +        2, 64,
607.3673 +        (long *)_huff_lengthlist__44u2__short,
607.3674 +        0, 0, 0, 0, 0,
607.3675 +        NULL,
607.3676 +        0
607.3677 +};
607.3678 +
607.3679 +static const long _huff_lengthlist__44u3__long[] = {
607.3680 +         6, 9,13,12,14,11,10,13, 8, 4, 5, 7, 8, 7, 8,12,
607.3681 +        11, 4, 3, 5, 5, 7, 9,14,11, 6, 5, 6, 6, 6, 7,13,
607.3682 +        13, 7, 5, 6, 4, 5, 7,14,11, 7, 6, 6, 5, 5, 6,13,
607.3683 +         9, 7, 8, 6, 7, 5, 3, 9, 9,12,13,12,14,10, 6, 7,
607.3684 +};
607.3685 +
607.3686 +static const static_codebook _huff_book__44u3__long = {
607.3687 +        2, 64,
607.3688 +        (long *)_huff_lengthlist__44u3__long,
607.3689 +        0, 0, 0, 0, 0,
607.3690 +        NULL,
607.3691 +        0
607.3692 +};
607.3693 +
607.3694 +static const long _vq_quantlist__44u3__p1_0[] = {
607.3695 +        1,
607.3696 +        0,
607.3697 +        2,
607.3698 +};
607.3699 +
607.3700 +static const long _vq_lengthlist__44u3__p1_0[] = {
607.3701 +         1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,10,11, 8,
607.3702 +        10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11,
607.3703 +        11, 8,11,11, 8,11,11,11,13,14,11,14,14, 8,11,11,
607.3704 +        10,14,12,11,14,14, 4, 8, 8, 8,11,11, 8,11,11, 7,
607.3705 +        11,11,11,14,14,10,12,14, 8,11,11,11,14,14,11,14,
607.3706 +        13,
607.3707 +};
607.3708 +
607.3709 +static const static_codebook _44u3__p1_0 = {
607.3710 +        4, 81,
607.3711 +        (long *)_vq_lengthlist__44u3__p1_0,
607.3712 +        1, -535822336, 1611661312, 2, 0,
607.3713 +        (long *)_vq_quantlist__44u3__p1_0,
607.3714 +        0
607.3715 +};
607.3716 +
607.3717 +static const long _vq_quantlist__44u3__p2_0[] = {
607.3718 +        1,
607.3719 +        0,
607.3720 +        2,
607.3721 +};
607.3722 +
607.3723 +static const long _vq_lengthlist__44u3__p2_0[] = {
607.3724 +         2, 5, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6,
607.3725 +         8, 8, 5, 6, 6, 6, 8, 8, 7, 8, 8, 5, 7, 6, 7, 8,
607.3726 +         8, 6, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8,
607.3727 +         8,10, 8, 8,10,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6,
607.3728 +         8, 8, 8,10,10, 8, 8,10, 7, 8, 8, 8,10,10, 8,10,
607.3729 +         9,
607.3730 +};
607.3731 +
607.3732 +static const static_codebook _44u3__p2_0 = {
607.3733 +        4, 81,
607.3734 +        (long *)_vq_lengthlist__44u3__p2_0,
607.3735 +        1, -535822336, 1611661312, 2, 0,
607.3736 +        (long *)_vq_quantlist__44u3__p2_0,
607.3737 +        0
607.3738 +};
607.3739 +
607.3740 +static const long _vq_quantlist__44u3__p3_0[] = {
607.3741 +        2,
607.3742 +        1,
607.3743 +        3,
607.3744 +        0,
607.3745 +        4,
607.3746 +};
607.3747 +
607.3748 +static const long _vq_lengthlist__44u3__p3_0[] = {
607.3749 +         2, 4, 4, 7, 7, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8,
607.3750 +         9, 9,12,12, 8, 9, 9,11,12, 5, 7, 7,10,10, 7, 9,
607.3751 +         9,11,11, 7, 9, 9,10,11,10,11,11,13,13, 9,10,11,
607.3752 +        13,13, 5, 7, 7,10,10, 7, 9, 9,11,10, 7, 9, 9,11,
607.3753 +        11, 9,11,10,13,13,10,11,11,14,13, 8,10,10,14,13,
607.3754 +        10,11,11,15,14, 9,11,11,14,14,13,14,13,16,16,12,
607.3755 +        13,13,15,15, 8,10,10,13,14, 9,11,11,14,14,10,11,
607.3756 +        11,14,15,12,13,13,15,15,13,14,14,15,16, 5, 7, 7,
607.3757 +        10,10, 7, 9, 9,11,11, 7, 9, 9,11,12,10,11,11,14,
607.3758 +        14,10,11,11,14,14, 7, 9, 9,12,12, 9,11,11,13,13,
607.3759 +         9,11,11,13,13,12,12,13,15,15,11,12,13,15,16, 7,
607.3760 +         9, 9,11,11, 8,11,10,13,12, 9,11,11,13,13,11,13,
607.3761 +        12,15,13,11,13,13,15,16, 9,12,11,15,14,11,12,13,
607.3762 +        16,15,11,13,13,15,16,14,14,15,17,16,13,15,16, 0,
607.3763 +        17, 9,11,11,15,15,10,13,12,15,15,11,13,13,15,16,
607.3764 +        13,15,13,16,15,14,16,15, 0,19, 5, 7, 7,10,10, 7,
607.3765 +         9, 9,11,11, 7, 9, 9,11,11,10,12,11,14,14,10,11,
607.3766 +        12,14,14, 7, 9, 9,12,12, 9,11,11,14,13, 9,10,11,
607.3767 +        12,13,11,13,13,16,16,11,12,13,13,16, 7, 9, 9,12,
607.3768 +        12, 9,11,11,13,13, 9,11,11,13,13,11,13,13,15,15,
607.3769 +        12,13,12,15,14, 9,11,11,15,14,11,13,12,16,16,10,
607.3770 +        12,12,15,15,13,15,15,17,19,13,14,15,16,17,10,12,
607.3771 +        12,15,15,11,13,13,16,16,11,13,13,15,16,13,15,15,
607.3772 +         0, 0,14,15,15,16,16, 8,10,10,14,14,10,12,12,15,
607.3773 +        15,10,12,11,15,16,14,15,15,19,20,13,14,14,18,16,
607.3774 +         9,11,11,15,15,11,13,13,17,16,11,13,13,16,16,15,
607.3775 +        17,17,20,20,14,15,16,17,20, 9,11,11,15,15,10,13,
607.3776 +        12,16,15,11,13,13,15,17,14,16,15,18, 0,14,16,15,
607.3777 +        18,20,12,14,14, 0, 0,14,14,16, 0, 0,13,16,15, 0,
607.3778 +         0,17,17,18, 0, 0,16,17,19,19, 0,12,14,14,18, 0,
607.3779 +        12,16,14, 0,17,13,15,15,18, 0,16,18,17, 0,17,16,
607.3780 +        18,17, 0, 0, 7,10,10,14,14,10,12,11,15,15,10,12,
607.3781 +        12,16,15,13,15,15,18, 0,14,15,15,17, 0, 9,11,11,
607.3782 +        15,15,11,13,13,16,16,11,12,13,16,16,14,15,16,17,
607.3783 +        17,14,16,16,16,18, 9,11,12,16,16,11,13,13,17,17,
607.3784 +        11,14,13,20,17,15,16,16,19, 0,15,16,17, 0,19,11,
607.3785 +        13,14,17,16,14,15,15,20,18,13,14,15,17,19,16,18,
607.3786 +        18, 0,20,16,16,19,17, 0,12,15,14,17, 0,14,15,15,
607.3787 +        18,19,13,16,15,19,20,15,18,18, 0,20,17, 0,16, 0,
607.3788 +         0,
607.3789 +};
607.3790 +
607.3791 +static const static_codebook _44u3__p3_0 = {
607.3792 +        4, 625,
607.3793 +        (long *)_vq_lengthlist__44u3__p3_0,
607.3794 +        1, -533725184, 1611661312, 3, 0,
607.3795 +        (long *)_vq_quantlist__44u3__p3_0,
607.3796 +        0
607.3797 +};
607.3798 +
607.3799 +static const long _vq_quantlist__44u3__p4_0[] = {
607.3800 +        2,
607.3801 +        1,
607.3802 +        3,
607.3803 +        0,
607.3804 +        4,
607.3805 +};
607.3806 +
607.3807 +static const long _vq_lengthlist__44u3__p4_0[] = {
607.3808 +         4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 9,
607.3809 +         9, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8,
607.3810 +         8,10,10, 7, 7, 8,10,10, 9,10,10,11,12, 9,10,10,
607.3811 +        11,12, 5, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 8,10,
607.3812 +        10, 9,10, 9,12,11, 9,10,10,12,11, 9,10, 9,12,12,
607.3813 +         9,10,10,13,12, 9,10,10,12,13,12,12,12,14,14,11,
607.3814 +        12,12,13,14, 9, 9,10,12,12, 9,10,10,12,12, 9,10,
607.3815 +        10,12,13,11,12,11,14,13,12,12,12,14,13, 5, 7, 7,
607.3816 +         9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,
607.3817 +        12, 9,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,11,11,
607.3818 +         8, 9, 9,11,11,11,11,11,12,13,10,11,11,13,13, 6,
607.3819 +         8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
607.3820 +        10,13,11,10,11,11,13,13, 9,11,10,13,12,10,11,11,
607.3821 +        13,13,10,11,11,13,13,12,12,13,12,15,12,13,13,15,
607.3822 +        15, 9,10,10,12,13,10,11,10,13,12,10,11,11,13,14,
607.3823 +        12,13,11,15,13,12,13,13,15,15, 5, 7, 7, 9, 9, 7,
607.3824 +         8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12,10,10,
607.3825 +        11,12,12, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 8, 9,
607.3826 +        10,11,10,11,11,13,13,10,10,11,11,13, 7, 8, 8,10,
607.3827 +        10, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,11,13,13,
607.3828 +        11,11,11,13,12, 9,10,10,13,12,10,11,11,14,13,10,
607.3829 +        10,11,12,13,12,13,13,15,15,12,11,13,13,14, 9,10,
607.3830 +        11,12,13,10,11,11,13,13,10,11,11,13,13,12,13,13,
607.3831 +        15,15,12,13,12,15,12, 8, 9, 9,12,12, 9,11,10,13,
607.3832 +        13, 9,10,10,13,13,12,13,13,15,14,12,12,12,14,13,
607.3833 +         9,10,10,13,12,10,11,11,13,13,10,11,11,14,12,13,
607.3834 +        13,14,14,16,12,13,13,15,15, 9,10,10,13,13,10,11,
607.3835 +        10,14,13,10,11,11,13,14,12,14,13,15,14,13,13,13,
607.3836 +        15,15,11,13,12,15,14,11,12,13,14,15,12,13,13,16,
607.3837 +        14,14,12,15,12,16,14,15,15,17,15,11,12,12,14,14,
607.3838 +        11,13,11,15,14,12,13,13,15,15,13,15,12,17,13,14,
607.3839 +        15,15,16,16, 8, 9, 9,12,12, 9,10,10,12,13, 9,10,
607.3840 +        10,13,13,12,12,12,14,14,12,13,13,15,15, 9,10,10,
607.3841 +        13,12,10,11,11,14,13,10,10,11,13,14,12,13,13,15,
607.3842 +        15,12,12,13,14,16, 9,10,10,13,13,10,11,11,13,14,
607.3843 +        10,11,11,14,13,12,13,13,14,15,13,14,13,16,14,11,
607.3844 +        12,12,14,14,12,13,13,15,14,11,12,13,14,15,14,15,
607.3845 +        15,16,16,13,13,15,13,16,11,12,12,14,15,12,13,13,
607.3846 +        14,15,11,13,12,15,14,14,15,15,16,16,14,15,12,16,
607.3847 +        13,
607.3848 +};
607.3849 +
607.3850 +static const static_codebook _44u3__p4_0 = {
607.3851 +        4, 625,
607.3852 +        (long *)_vq_lengthlist__44u3__p4_0,
607.3853 +        1, -533725184, 1611661312, 3, 0,
607.3854 +        (long *)_vq_quantlist__44u3__p4_0,
607.3855 +        0
607.3856 +};
607.3857 +
607.3858 +static const long _vq_quantlist__44u3__p5_0[] = {
607.3859 +        4,
607.3860 +        3,
607.3861 +        5,
607.3862 +        2,
607.3863 +        6,
607.3864 +        1,
607.3865 +        7,
607.3866 +        0,
607.3867 +        8,
607.3868 +};
607.3869 +
607.3870 +static const long _vq_lengthlist__44u3__p5_0[] = {
607.3871 +         2, 3, 3, 6, 6, 7, 7, 9, 9, 4, 5, 5, 7, 7, 8, 8,
607.3872 +        10,10, 4, 5, 5, 7, 7, 8, 8,10,10, 6, 7, 7, 8, 8,
607.3873 +         9, 9,11,10, 6, 7, 7, 8, 8, 9, 9,10,10, 7, 8, 8,
607.3874 +         9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
607.3875 +        10,10,11,10,11,11,12,12, 9,10,10,10,10,11,11,12,
607.3876 +        12,
607.3877 +};
607.3878 +
607.3879 +static const static_codebook _44u3__p5_0 = {
607.3880 +        2, 81,
607.3881 +        (long *)_vq_lengthlist__44u3__p5_0,
607.3882 +        1, -531628032, 1611661312, 4, 0,
607.3883 +        (long *)_vq_quantlist__44u3__p5_0,
607.3884 +        0
607.3885 +};
607.3886 +
607.3887 +static const long _vq_quantlist__44u3__p6_0[] = {
607.3888 +        6,
607.3889 +        5,
607.3890 +        7,
607.3891 +        4,
607.3892 +        8,
607.3893 +        3,
607.3894 +        9,
607.3895 +        2,
607.3896 +        10,
607.3897 +        1,
607.3898 +        11,
607.3899 +        0,
607.3900 +        12,
607.3901 +};
607.3902 +
607.3903 +static const long _vq_lengthlist__44u3__p6_0[] = {
607.3904 +         1, 4, 4, 6, 6, 8, 8, 9, 9,10,11,13,14, 4, 6, 5,
607.3905 +         8, 8, 9, 9,10,10,11,11,14,14, 4, 6, 6, 8, 8, 9,
607.3906 +         9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11,
607.3907 +        12,12,15,15, 6, 8, 8, 9, 9,10,11,11,11,12,12,15,
607.3908 +        15, 8, 9, 9,11,10,11,11,12,12,13,13,15,16, 8, 9,
607.3909 +         9,10,11,11,11,12,12,13,13,16,16,10,10,11,11,11,
607.3910 +        12,12,13,13,13,14,17,16, 9,10,11,12,11,12,12,13,
607.3911 +        13,13,13,16,18,11,12,11,12,12,13,13,13,14,15,14,
607.3912 +        17,17,11,11,12,12,12,13,13,13,14,14,15,18,17,14,
607.3913 +        15,15,15,15,16,16,17,17,19,18, 0,20,14,15,14,15,
607.3914 +        15,16,16,16,17,18,16,20,18,
607.3915 +};
607.3916 +
607.3917 +static const static_codebook _44u3__p6_0 = {
607.3918 +        2, 169,
607.3919 +        (long *)_vq_lengthlist__44u3__p6_0,
607.3920 +        1, -526516224, 1616117760, 4, 0,
607.3921 +        (long *)_vq_quantlist__44u3__p6_0,
607.3922 +        0
607.3923 +};
607.3924 +
607.3925 +static const long _vq_quantlist__44u3__p6_1[] = {
607.3926 +        2,
607.3927 +        1,
607.3928 +        3,
607.3929 +        0,
607.3930 +        4,
607.3931 +};
607.3932 +
607.3933 +static const long _vq_lengthlist__44u3__p6_1[] = {
607.3934 +         2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5,
607.3935 +         6, 5, 6, 6, 5, 5, 6, 6, 6,
607.3936 +};
607.3937 +
607.3938 +static const static_codebook _44u3__p6_1 = {
607.3939 +        2, 25,
607.3940 +        (long *)_vq_lengthlist__44u3__p6_1,
607.3941 +        1, -533725184, 1611661312, 3, 0,
607.3942 +        (long *)_vq_quantlist__44u3__p6_1,
607.3943 +        0
607.3944 +};
607.3945 +
607.3946 +static const long _vq_quantlist__44u3__p7_0[] = {
607.3947 +        4,
607.3948 +        3,
607.3949 +        5,
607.3950 +        2,
607.3951 +        6,
607.3952 +        1,
607.3953 +        7,
607.3954 +        0,
607.3955 +        8,
607.3956 +};
607.3957 +
607.3958 +static const long _vq_lengthlist__44u3__p7_0[] = {
607.3959 +         1, 3, 3,10,10,10,10,10,10, 4,10,10,10,10,10,10,
607.3960 +        10,10, 4,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
607.3961 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.3962 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.3963 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.3964 +         9,
607.3965 +};
607.3966 +
607.3967 +static const static_codebook _44u3__p7_0 = {
607.3968 +        2, 81,
607.3969 +        (long *)_vq_lengthlist__44u3__p7_0,
607.3970 +        1, -515907584, 1627381760, 4, 0,
607.3971 +        (long *)_vq_quantlist__44u3__p7_0,
607.3972 +        0
607.3973 +};
607.3974 +
607.3975 +static const long _vq_quantlist__44u3__p7_1[] = {
607.3976 +        7,
607.3977 +        6,
607.3978 +        8,
607.3979 +        5,
607.3980 +        9,
607.3981 +        4,
607.3982 +        10,
607.3983 +        3,
607.3984 +        11,
607.3985 +        2,
607.3986 +        12,
607.3987 +        1,
607.3988 +        13,
607.3989 +        0,
607.3990 +        14,
607.3991 +};
607.3992 +
607.3993 +static const long _vq_lengthlist__44u3__p7_1[] = {
607.3994 +         1, 4, 4, 6, 6, 7, 6, 8, 7, 9, 8,10, 9,11,11, 4,
607.3995 +         7, 7, 8, 7, 9, 9,10,10,11,11,11,11,12,12, 4, 7,
607.3996 +         7, 7, 7, 9, 9,10,10,11,11,12,12,12,11, 6, 8, 8,
607.3997 +         9, 9,10,10,11,11,12,12,13,12,13,13, 6, 8, 8, 9,
607.3998 +         9,10,11,11,11,12,12,13,14,13,13, 8, 9, 9,11,11,
607.3999 +        12,12,12,13,14,13,14,14,14,15, 8, 9, 9,11,11,11,
607.4000 +        12,13,14,13,14,15,17,14,15, 9,10,10,12,12,13,13,
607.4001 +        13,14,15,15,15,16,16,16, 9,11,11,12,12,13,13,14,
607.4002 +        14,14,15,16,16,16,16,10,12,12,13,13,14,14,15,15,
607.4003 +        15,16,17,17,17,17,10,12,11,13,13,15,14,15,14,16,
607.4004 +        17,16,16,16,16,11,13,12,14,14,14,14,15,16,17,16,
607.4005 +        17,17,17,17,11,13,12,14,14,14,15,17,16,17,17,17,
607.4006 +        17,17,17,12,13,13,15,16,15,16,17,17,16,16,17,17,
607.4007 +        17,17,12,13,13,15,15,15,16,17,17,17,16,17,16,17,
607.4008 +        17,
607.4009 +};
607.4010 +
607.4011 +static const static_codebook _44u3__p7_1 = {
607.4012 +        2, 225,
607.4013 +        (long *)_vq_lengthlist__44u3__p7_1,
607.4014 +        1, -522338304, 1620115456, 4, 0,
607.4015 +        (long *)_vq_quantlist__44u3__p7_1,
607.4016 +        0
607.4017 +};
607.4018 +
607.4019 +static const long _vq_quantlist__44u3__p7_2[] = {
607.4020 +        8,
607.4021 +        7,
607.4022 +        9,
607.4023 +        6,
607.4024 +        10,
607.4025 +        5,
607.4026 +        11,
607.4027 +        4,
607.4028 +        12,
607.4029 +        3,
607.4030 +        13,
607.4031 +        2,
607.4032 +        14,
607.4033 +        1,
607.4034 +        15,
607.4035 +        0,
607.4036 +        16,
607.4037 +};
607.4038 +
607.4039 +static const long _vq_lengthlist__44u3__p7_2[] = {
607.4040 +         2, 5, 5, 7, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
607.4041 +         9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.4042 +        10,10, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9,
607.4043 +         9,10, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.4044 +        10,10,10,10, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,
607.4045 +         9,10,10,10,10, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.4046 +        10,10,10,10,10,10, 7, 8, 8, 9, 8, 9, 9, 9, 9,10,
607.4047 +         9,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.4048 +         9,10,10,10,10,10,10,10, 8, 9, 8, 9, 9, 9, 9,10,
607.4049 +         9,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,
607.4050 +         9,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,
607.4051 +         9,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,10, 9,
607.4052 +        10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,10,
607.4053 +        10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
607.4054 +        10,10,10,10,10,10,10,10,10,10,10,10,10,11, 9,10,
607.4055 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,11, 9,
607.4056 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.4057 +         9,10,10,10,10,10,10,10,10,10,10,10,11,11,11,10,
607.4058 +        11,
607.4059 +};
607.4060 +
607.4061 +static const static_codebook _44u3__p7_2 = {
607.4062 +        2, 289,
607.4063 +        (long *)_vq_lengthlist__44u3__p7_2,
607.4064 +        1, -529530880, 1611661312, 5, 0,
607.4065 +        (long *)_vq_quantlist__44u3__p7_2,
607.4066 +        0
607.4067 +};
607.4068 +
607.4069 +static const long _huff_lengthlist__44u3__short[] = {
607.4070 +        14,14,14,15,13,15,12,16,10, 8, 7, 9, 9, 8,12,16,
607.4071 +        10, 5, 4, 6, 5, 6, 9,16,14, 8, 6, 8, 7, 8,10,16,
607.4072 +        14, 7, 4, 6, 3, 5, 8,16,15, 9, 5, 7, 4, 4, 7,16,
607.4073 +        13,10, 6, 7, 4, 3, 4,13,13,12, 7, 9, 5, 5, 6,12,
607.4074 +};
607.4075 +
607.4076 +static const static_codebook _huff_book__44u3__short = {
607.4077 +        2, 64,
607.4078 +        (long *)_huff_lengthlist__44u3__short,
607.4079 +        0, 0, 0, 0, 0,
607.4080 +        NULL,
607.4081 +        0
607.4082 +};
607.4083 +
607.4084 +static const long _huff_lengthlist__44u4__long[] = {
607.4085 +         3, 8,12,12,13,12,11,13, 5, 4, 6, 7, 8, 8, 9,13,
607.4086 +         9, 5, 4, 5, 5, 7, 9,13, 9, 6, 5, 6, 6, 7, 8,12,
607.4087 +        12, 7, 5, 6, 4, 5, 8,13,11, 7, 6, 6, 5, 5, 6,12,
607.4088 +        10, 8, 8, 7, 7, 5, 3, 8,10,12,13,12,12, 9, 6, 7,
607.4089 +};
607.4090 +
607.4091 +static const static_codebook _huff_book__44u4__long = {
607.4092 +        2, 64,
607.4093 +        (long *)_huff_lengthlist__44u4__long,
607.4094 +        0, 0, 0, 0, 0,
607.4095 +        NULL,
607.4096 +        0
607.4097 +};
607.4098 +
607.4099 +static const long _vq_quantlist__44u4__p1_0[] = {
607.4100 +        1,
607.4101 +        0,
607.4102 +        2,
607.4103 +};
607.4104 +
607.4105 +static const long _vq_lengthlist__44u4__p1_0[] = {
607.4106 +         1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,10,11, 8,
607.4107 +        10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11,
607.4108 +        11, 8,11,11, 8,11,11,11,13,14,11,15,14, 8,11,11,
607.4109 +        10,13,12,11,14,14, 4, 8, 8, 8,11,11, 8,11,11, 7,
607.4110 +        11,11,11,15,14,10,12,14, 8,11,11,11,14,14,11,14,
607.4111 +        13,
607.4112 +};
607.4113 +
607.4114 +static const static_codebook _44u4__p1_0 = {
607.4115 +        4, 81,
607.4116 +        (long *)_vq_lengthlist__44u4__p1_0,
607.4117 +        1, -535822336, 1611661312, 2, 0,
607.4118 +        (long *)_vq_quantlist__44u4__p1_0,
607.4119 +        0
607.4120 +};
607.4121 +
607.4122 +static const long _vq_quantlist__44u4__p2_0[] = {
607.4123 +        1,
607.4124 +        0,
607.4125 +        2,
607.4126 +};
607.4127 +
607.4128 +static const long _vq_lengthlist__44u4__p2_0[] = {
607.4129 +         2, 5, 5, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6,
607.4130 +         8, 8, 5, 6, 6, 6, 8, 8, 7, 8, 8, 5, 7, 6, 6, 8,
607.4131 +         8, 6, 8, 8, 6, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8,
607.4132 +         8,10, 8, 8,10,10, 5, 6, 6, 6, 8, 8, 6, 8, 8, 6,
607.4133 +         8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10,
607.4134 +         9,
607.4135 +};
607.4136 +
607.4137 +static const static_codebook _44u4__p2_0 = {
607.4138 +        4, 81,
607.4139 +        (long *)_vq_lengthlist__44u4__p2_0,
607.4140 +        1, -535822336, 1611661312, 2, 0,
607.4141 +        (long *)_vq_quantlist__44u4__p2_0,
607.4142 +        0
607.4143 +};
607.4144 +
607.4145 +static const long _vq_quantlist__44u4__p3_0[] = {
607.4146 +        2,
607.4147 +        1,
607.4148 +        3,
607.4149 +        0,
607.4150 +        4,
607.4151 +};
607.4152 +
607.4153 +static const long _vq_lengthlist__44u4__p3_0[] = {
607.4154 +         2, 4, 4, 8, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8,
607.4155 +        10, 9,12,12, 8, 9,10,12,12, 5, 7, 7,10,10, 7, 9,
607.4156 +         9,11,11, 7, 9, 9,11,11,10,12,11,14,14, 9,10,11,
607.4157 +        13,14, 5, 7, 7,10,10, 7, 9, 9,11,11, 7, 9, 9,11,
607.4158 +        11, 9,11,10,14,13,10,11,11,14,14, 8,10,10,14,13,
607.4159 +        10,12,12,15,14, 9,11,11,15,14,13,14,14,17,17,12,
607.4160 +        14,14,16,16, 8,10,10,14,14, 9,11,11,14,15,10,12,
607.4161 +        12,14,15,12,14,13,16,16,13,14,15,15,18, 4, 7, 7,
607.4162 +        10,10, 7, 9, 9,12,11, 7, 9, 9,11,12,10,12,11,15,
607.4163 +        14,10,11,12,14,15, 7, 9, 9,12,12, 9,11,12,13,13,
607.4164 +         9,11,12,13,13,12,13,13,15,16,11,13,13,15,16, 7,
607.4165 +         9, 9,12,12, 9,11,10,13,12, 9,11,12,13,14,11,13,
607.4166 +        12,16,14,12,13,13,15,16,10,12,12,16,15,11,13,13,
607.4167 +        17,16,11,13,13,17,16,14,15,15,17,17,14,16,16,18,
607.4168 +        20, 9,11,11,15,16,11,13,12,16,16,11,13,13,16,17,
607.4169 +        14,15,14,18,16,14,16,16,17,20, 5, 7, 7,10,10, 7,
607.4170 +         9, 9,12,11, 7, 9,10,11,12,10,12,11,15,15,10,12,
607.4171 +        12,14,14, 7, 9, 9,12,12, 9,12,11,14,13, 9,10,11,
607.4172 +        12,13,12,13,14,16,16,11,12,13,14,16, 7, 9, 9,12,
607.4173 +        12, 9,12,11,13,13, 9,12,11,13,13,11,13,13,16,16,
607.4174 +        12,13,13,16,15, 9,11,11,16,14,11,13,13,16,16,11,
607.4175 +        12,13,16,16,14,16,16,17,17,13,14,15,16,17,10,12,
607.4176 +        12,15,15,11,13,13,16,17,11,13,13,16,16,14,16,15,
607.4177 +        19,19,14,15,15,17,18, 8,10,10,14,14,10,12,12,15,
607.4178 +        15,10,12,12,16,16,14,16,15,20,19,13,15,15,17,16,
607.4179 +         9,12,12,16,16,11,13,13,16,18,11,14,13,16,17,16,
607.4180 +        17,16,20, 0,15,16,18,18,20, 9,11,11,15,15,11,14,
607.4181 +        12,17,16,11,13,13,17,17,15,17,15,20,20,14,16,16,
607.4182 +        17, 0,13,15,14,18,16,14,15,16, 0,18,14,16,16, 0,
607.4183 +         0,18,16, 0, 0,20,16,18,18, 0, 0,12,14,14,17,18,
607.4184 +        13,15,14,20,18,14,16,15,19,19,16,20,16, 0,18,16,
607.4185 +        19,17,19, 0, 8,10,10,14,14,10,12,12,16,15,10,12,
607.4186 +        12,16,16,13,15,15,18,17,14,16,16,19, 0, 9,11,11,
607.4187 +        16,15,11,14,13,18,17,11,12,13,17,18,14,17,16,18,
607.4188 +        18,15,16,17,18,18, 9,12,12,16,16,11,13,13,16,18,
607.4189 +        11,14,13,17,17,15,16,16,18,20,16,17,17,20,20,12,
607.4190 +        14,14,18,17,14,16,16, 0,19,13,14,15,18, 0,16, 0,
607.4191 +         0, 0, 0,16,16, 0,19,20,13,15,14, 0, 0,14,16,16,
607.4192 +        18,19,14,16,15, 0,20,16,20,18, 0,20,17,20,17, 0,
607.4193 +         0,
607.4194 +};
607.4195 +
607.4196 +static const static_codebook _44u4__p3_0 = {
607.4197 +        4, 625,
607.4198 +        (long *)_vq_lengthlist__44u4__p3_0,
607.4199 +        1, -533725184, 1611661312, 3, 0,
607.4200 +        (long *)_vq_quantlist__44u4__p3_0,
607.4201 +        0
607.4202 +};
607.4203 +
607.4204 +static const long _vq_quantlist__44u4__p4_0[] = {
607.4205 +        2,
607.4206 +        1,
607.4207 +        3,
607.4208 +        0,
607.4209 +        4,
607.4210 +};
607.4211 +
607.4212 +static const long _vq_lengthlist__44u4__p4_0[] = {
607.4213 +         4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 9,
607.4214 +         9, 9,11,11, 8, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8,
607.4215 +         8,10,10, 7, 7, 8,10,10, 9,10,10,11,12, 9,10,10,
607.4216 +        11,12, 5, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 8,10,
607.4217 +        10, 9,10,10,12,11, 9,10,10,12,11, 9,10, 9,12,12,
607.4218 +         9,10,10,13,12, 9,10,10,12,12,12,12,12,14,14,11,
607.4219 +        12,12,13,14, 9, 9,10,12,12, 9,10,10,13,13, 9,10,
607.4220 +        10,12,13,11,12,12,14,13,11,12,12,14,14, 5, 7, 7,
607.4221 +         9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,
607.4222 +        12, 9,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,11,11,
607.4223 +         8, 9, 9,11,11,11,11,11,12,13,10,11,11,13,13, 6,
607.4224 +         8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
607.4225 +        10,13,11,10,11,11,13,13, 9,11,10,13,12,10,11,11,
607.4226 +        13,14,10,11,11,14,13,12,12,13,12,15,12,13,13,15,
607.4227 +        15, 9,10,10,12,13,10,11,10,13,12,10,11,11,13,14,
607.4228 +        12,13,11,15,13,13,13,13,15,15, 5, 7, 7, 9, 9, 7,
607.4229 +         8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12,10,10,
607.4230 +        11,12,13, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 8, 9,
607.4231 +        10,11,10,11,11,13,13,10,10,11,11,13, 7, 8, 8,10,
607.4232 +        11, 8, 9, 9,11,11, 8, 9, 8,11,11,10,11,11,13,13,
607.4233 +        11,12,11,13,12, 9,10,10,13,12,10,11,11,14,13,10,
607.4234 +        10,11,12,13,12,13,13,15,15,12,11,13,13,14, 9,10,
607.4235 +        11,12,13,10,11,11,13,14,10,11,11,13,13,12,13,13,
607.4236 +        15,15,12,13,12,15,12, 8, 9, 9,12,12, 9,11,10,13,
607.4237 +        13, 9,10,10,13,13,12,13,13,15,15,12,12,12,14,14,
607.4238 +         9,10,10,13,13,10,11,11,13,14,10,11,11,14,13,13,
607.4239 +        13,14,14,16,13,13,13,15,15, 9,10,10,13,13,10,11,
607.4240 +        10,14,13,10,11,11,13,14,12,14,13,16,14,12,13,13,
607.4241 +        14,15,11,12,12,15,14,11,12,13,14,15,12,13,13,16,
607.4242 +        15,14,12,15,12,16,14,15,15,16,16,11,12,12,14,14,
607.4243 +        11,13,12,15,14,12,13,13,15,16,13,15,13,17,13,14,
607.4244 +        15,15,16,17, 8, 9, 9,12,12, 9,10,10,12,13, 9,10,
607.4245 +        10,13,13,12,12,12,14,14,12,13,13,15,15, 9,10,10,
607.4246 +        13,12,10,11,11,14,13,10,10,11,13,14,13,13,13,15,
607.4247 +        15,12,13,14,14,16, 9,10,10,13,13,10,11,11,13,14,
607.4248 +        10,11,11,14,14,13,13,13,15,15,13,14,13,16,14,11,
607.4249 +        12,12,15,14,12,13,13,16,15,11,12,13,14,15,14,15,
607.4250 +        15,17,16,13,13,15,13,16,11,12,13,14,15,13,13,13,
607.4251 +        15,16,11,13,12,15,14,14,15,15,16,16,14,15,12,17,
607.4252 +        13,
607.4253 +};
607.4254 +
607.4255 +static const static_codebook _44u4__p4_0 = {
607.4256 +        4, 625,
607.4257 +        (long *)_vq_lengthlist__44u4__p4_0,
607.4258 +        1, -533725184, 1611661312, 3, 0,
607.4259 +        (long *)_vq_quantlist__44u4__p4_0,
607.4260 +        0
607.4261 +};
607.4262 +
607.4263 +static const long _vq_quantlist__44u4__p5_0[] = {
607.4264 +        4,
607.4265 +        3,
607.4266 +        5,
607.4267 +        2,
607.4268 +        6,
607.4269 +        1,
607.4270 +        7,
607.4271 +        0,
607.4272 +        8,
607.4273 +};
607.4274 +
607.4275 +static const long _vq_lengthlist__44u4__p5_0[] = {
607.4276 +         2, 3, 3, 6, 6, 7, 7, 9, 9, 4, 5, 5, 7, 7, 8, 8,
607.4277 +        10, 9, 4, 5, 5, 7, 7, 8, 8,10,10, 6, 7, 7, 8, 8,
607.4278 +         9, 9,11,10, 6, 7, 7, 8, 8, 9, 9,10,11, 7, 8, 8,
607.4279 +         9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
607.4280 +        10,10,11,10,11,11,12,12, 9,10,10,10,11,11,11,12,
607.4281 +        12,
607.4282 +};
607.4283 +
607.4284 +static const static_codebook _44u4__p5_0 = {
607.4285 +        2, 81,
607.4286 +        (long *)_vq_lengthlist__44u4__p5_0,
607.4287 +        1, -531628032, 1611661312, 4, 0,
607.4288 +        (long *)_vq_quantlist__44u4__p5_0,
607.4289 +        0
607.4290 +};
607.4291 +
607.4292 +static const long _vq_quantlist__44u4__p6_0[] = {
607.4293 +        6,
607.4294 +        5,
607.4295 +        7,
607.4296 +        4,
607.4297 +        8,
607.4298 +        3,
607.4299 +        9,
607.4300 +        2,
607.4301 +        10,
607.4302 +        1,
607.4303 +        11,
607.4304 +        0,
607.4305 +        12,
607.4306 +};
607.4307 +
607.4308 +static const long _vq_lengthlist__44u4__p6_0[] = {
607.4309 +         1, 4, 4, 6, 6, 8, 8, 9, 9,11,10,13,13, 4, 6, 5,
607.4310 +         8, 8, 9, 9,10,10,11,11,14,14, 4, 6, 6, 8, 8, 9,
607.4311 +         9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11,
607.4312 +        12,12,15,15, 6, 8, 8, 9, 9,10,11,11,11,12,12,15,
607.4313 +        15, 8, 9, 9,11,10,11,11,12,12,13,13,16,16, 8, 9,
607.4314 +         9,10,10,11,11,12,12,13,13,16,16,10,10,10,12,11,
607.4315 +        12,12,13,13,14,14,16,16,10,10,10,11,12,12,12,13,
607.4316 +        13,13,14,16,17,11,12,11,12,12,13,13,14,14,15,14,
607.4317 +        18,17,11,11,12,12,12,13,13,14,14,14,15,19,18,14,
607.4318 +        15,14,15,15,17,16,17,17,17,17,21, 0,14,15,15,16,
607.4319 +        16,16,16,17,17,18,17,20,21,
607.4320 +};
607.4321 +
607.4322 +static const static_codebook _44u4__p6_0 = {
607.4323 +        2, 169,
607.4324 +        (long *)_vq_lengthlist__44u4__p6_0,
607.4325 +        1, -526516224, 1616117760, 4, 0,
607.4326 +        (long *)_vq_quantlist__44u4__p6_0,
607.4327 +        0
607.4328 +};
607.4329 +
607.4330 +static const long _vq_quantlist__44u4__p6_1[] = {
607.4331 +        2,
607.4332 +        1,
607.4333 +        3,
607.4334 +        0,
607.4335 +        4,
607.4336 +};
607.4337 +
607.4338 +static const long _vq_lengthlist__44u4__p6_1[] = {
607.4339 +         2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5,
607.4340 +         6, 5, 6, 6, 5, 5, 6, 6, 6,
607.4341 +};
607.4342 +
607.4343 +static const static_codebook _44u4__p6_1 = {
607.4344 +        2, 25,
607.4345 +        (long *)_vq_lengthlist__44u4__p6_1,
607.4346 +        1, -533725184, 1611661312, 3, 0,
607.4347 +        (long *)_vq_quantlist__44u4__p6_1,
607.4348 +        0
607.4349 +};
607.4350 +
607.4351 +static const long _vq_quantlist__44u4__p7_0[] = {
607.4352 +        6,
607.4353 +        5,
607.4354 +        7,
607.4355 +        4,
607.4356 +        8,
607.4357 +        3,
607.4358 +        9,
607.4359 +        2,
607.4360 +        10,
607.4361 +        1,
607.4362 +        11,
607.4363 +        0,
607.4364 +        12,
607.4365 +};
607.4366 +
607.4367 +static const long _vq_lengthlist__44u4__p7_0[] = {
607.4368 +         1, 3, 3,12,12,12,12,12,12,12,12,12,12, 3,12,11,
607.4369 +        12,12,12,12,12,12,12,12,12,12, 4,11,10,12,12,12,
607.4370 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
607.4371 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
607.4372 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
607.4373 +        12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.4374 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.4375 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.4376 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.4377 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.4378 +        11,11,11,11,11,11,11,11,11,
607.4379 +};
607.4380 +
607.4381 +static const static_codebook _44u4__p7_0 = {
607.4382 +        2, 169,
607.4383 +        (long *)_vq_lengthlist__44u4__p7_0,
607.4384 +        1, -514332672, 1627381760, 4, 0,
607.4385 +        (long *)_vq_quantlist__44u4__p7_0,
607.4386 +        0
607.4387 +};
607.4388 +
607.4389 +static const long _vq_quantlist__44u4__p7_1[] = {
607.4390 +        7,
607.4391 +        6,
607.4392 +        8,
607.4393 +        5,
607.4394 +        9,
607.4395 +        4,
607.4396 +        10,
607.4397 +        3,
607.4398 +        11,
607.4399 +        2,
607.4400 +        12,
607.4401 +        1,
607.4402 +        13,
607.4403 +        0,
607.4404 +        14,
607.4405 +};
607.4406 +
607.4407 +static const long _vq_lengthlist__44u4__p7_1[] = {
607.4408 +         1, 4, 4, 6, 6, 7, 7, 9, 8,10, 8,10, 9,11,11, 4,
607.4409 +         7, 6, 8, 7, 9, 9,10,10,11,10,11,10,12,10, 4, 6,
607.4410 +         7, 8, 8, 9, 9,10,10,11,11,11,11,12,12, 6, 8, 8,
607.4411 +        10, 9,11,10,12,11,12,12,12,12,13,13, 6, 8, 8,10,
607.4412 +        10,10,11,11,11,12,12,13,12,13,13, 8, 9, 9,11,11,
607.4413 +        12,11,12,12,13,13,13,13,13,13, 8, 9, 9,11,11,11,
607.4414 +        12,12,12,13,13,13,13,13,13, 9,10,10,12,11,13,13,
607.4415 +        13,13,14,13,13,14,14,14, 9,10,11,11,12,12,13,13,
607.4416 +        13,13,13,14,15,14,14,10,11,11,12,12,13,13,14,14,
607.4417 +        14,14,14,15,16,16,10,11,11,12,13,13,13,13,15,14,
607.4418 +        14,15,16,15,16,10,12,12,13,13,14,14,14,15,15,15,
607.4419 +        15,15,15,16,11,12,12,13,13,14,14,14,15,15,15,16,
607.4420 +        15,17,16,11,12,12,13,13,13,15,15,14,16,16,16,16,
607.4421 +        16,17,11,12,12,13,13,14,14,15,14,15,15,17,17,16,
607.4422 +        16,
607.4423 +};
607.4424 +
607.4425 +static const static_codebook _44u4__p7_1 = {
607.4426 +        2, 225,
607.4427 +        (long *)_vq_lengthlist__44u4__p7_1,
607.4428 +        1, -522338304, 1620115456, 4, 0,
607.4429 +        (long *)_vq_quantlist__44u4__p7_1,
607.4430 +        0
607.4431 +};
607.4432 +
607.4433 +static const long _vq_quantlist__44u4__p7_2[] = {
607.4434 +        8,
607.4435 +        7,
607.4436 +        9,
607.4437 +        6,
607.4438 +        10,
607.4439 +        5,
607.4440 +        11,
607.4441 +        4,
607.4442 +        12,
607.4443 +        3,
607.4444 +        13,
607.4445 +        2,
607.4446 +        14,
607.4447 +        1,
607.4448 +        15,
607.4449 +        0,
607.4450 +        16,
607.4451 +};
607.4452 +
607.4453 +static const long _vq_lengthlist__44u4__p7_2[] = {
607.4454 +         2, 5, 5, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
607.4455 +         9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.4456 +         9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
607.4457 +         9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.4458 +        10,10,10,10, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,
607.4459 +         9,10, 9,10,10, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.4460 +        10,10,10,10,10,10, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
607.4461 +         9,10,10,10,10,10,10, 8, 9, 8, 9, 9, 9, 9, 9, 9,
607.4462 +        10,10,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9,
607.4463 +        10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,10,
607.4464 +        10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,
607.4465 +        10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,10,
607.4466 +        10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
607.4467 +        10,10,10,10,10,10,10,10,10,11,10,10,10, 9, 9, 9,
607.4468 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9,
607.4469 +         9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,
607.4470 +        10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.4471 +         9,10, 9,10,10,10,10,10,10,10,10,10,10,11,10,10,
607.4472 +        10,
607.4473 +};
607.4474 +
607.4475 +static const static_codebook _44u4__p7_2 = {
607.4476 +        2, 289,
607.4477 +        (long *)_vq_lengthlist__44u4__p7_2,
607.4478 +        1, -529530880, 1611661312, 5, 0,
607.4479 +        (long *)_vq_quantlist__44u4__p7_2,
607.4480 +        0
607.4481 +};
607.4482 +
607.4483 +static const long _huff_lengthlist__44u4__short[] = {
607.4484 +        14,17,15,17,16,14,13,16,10, 7, 7,10,13,10,15,16,
607.4485 +         9, 4, 4, 6, 5, 7, 9,16,12, 8, 7, 8, 8, 8,11,16,
607.4486 +        14, 7, 4, 6, 3, 5, 8,15,13, 8, 5, 7, 4, 5, 7,16,
607.4487 +        12, 9, 6, 8, 3, 3, 5,16,14,13, 7,10, 5, 5, 7,15,
607.4488 +};
607.4489 +
607.4490 +static const static_codebook _huff_book__44u4__short = {
607.4491 +        2, 64,
607.4492 +        (long *)_huff_lengthlist__44u4__short,
607.4493 +        0, 0, 0, 0, 0,
607.4494 +        NULL,
607.4495 +        0
607.4496 +};
607.4497 +
607.4498 +static const long _huff_lengthlist__44u5__long[] = {
607.4499 +         3, 8,13,12,14,12,16,11,13,14, 5, 4, 5, 6, 7, 8,
607.4500 +        10, 9,12,15,10, 5, 5, 5, 6, 8, 9, 9,13,15,10, 5,
607.4501 +         5, 6, 6, 7, 8, 8,11,13,12, 7, 5, 6, 4, 6, 7, 7,
607.4502 +        11,14,11, 7, 7, 6, 6, 6, 7, 6,10,14,14, 9, 8, 8,
607.4503 +         6, 7, 7, 7,11,16,11, 8, 8, 7, 6, 6, 7, 4, 7,12,
607.4504 +        10,10,12,10,10, 9,10, 5, 6, 9,10,12,15,13,14,14,
607.4505 +        14, 8, 7, 8,
607.4506 +};
607.4507 +
607.4508 +static const static_codebook _huff_book__44u5__long = {
607.4509 +        2, 100,
607.4510 +        (long *)_huff_lengthlist__44u5__long,
607.4511 +        0, 0, 0, 0, 0,
607.4512 +        NULL,
607.4513 +        0
607.4514 +};
607.4515 +
607.4516 +static const long _vq_quantlist__44u5__p1_0[] = {
607.4517 +        1,
607.4518 +        0,
607.4519 +        2,
607.4520 +};
607.4521 +
607.4522 +static const long _vq_lengthlist__44u5__p1_0[] = {
607.4523 +         1, 4, 4, 5, 8, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7,
607.4524 +         9,10, 5, 8, 8, 7,10, 9, 8,10,10, 5, 8, 8, 8,10,
607.4525 +        10, 8,10,10, 8,10,10,10,12,13,10,13,13, 7,10,10,
607.4526 +        10,13,11,10,13,13, 4, 8, 8, 8,11,10, 8,10,10, 7,
607.4527 +        10,10,10,13,13,10,11,13, 8,10,11,10,13,13,10,13,
607.4528 +        12,
607.4529 +};
607.4530 +
607.4531 +static const static_codebook _44u5__p1_0 = {
607.4532 +        4, 81,
607.4533 +        (long *)_vq_lengthlist__44u5__p1_0,
607.4534 +        1, -535822336, 1611661312, 2, 0,
607.4535 +        (long *)_vq_quantlist__44u5__p1_0,
607.4536 +        0
607.4537 +};
607.4538 +
607.4539 +static const long _vq_quantlist__44u5__p2_0[] = {
607.4540 +        1,
607.4541 +        0,
607.4542 +        2,
607.4543 +};
607.4544 +
607.4545 +static const long _vq_lengthlist__44u5__p2_0[] = {
607.4546 +         3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6,
607.4547 +         7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8,
607.4548 +         8, 6, 8, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 8, 7,
607.4549 +         7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 8, 8, 6,
607.4550 +         8, 7, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9,
607.4551 +         9,
607.4552 +};
607.4553 +
607.4554 +static const static_codebook _44u5__p2_0 = {
607.4555 +        4, 81,
607.4556 +        (long *)_vq_lengthlist__44u5__p2_0,
607.4557 +        1, -535822336, 1611661312, 2, 0,
607.4558 +        (long *)_vq_quantlist__44u5__p2_0,
607.4559 +        0
607.4560 +};
607.4561 +
607.4562 +static const long _vq_quantlist__44u5__p3_0[] = {
607.4563 +        2,
607.4564 +        1,
607.4565 +        3,
607.4566 +        0,
607.4567 +        4,
607.4568 +};
607.4569 +
607.4570 +static const long _vq_lengthlist__44u5__p3_0[] = {
607.4571 +         2, 4, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8,
607.4572 +        10, 9,13,12, 8, 9,10,12,12, 5, 7, 7,10,10, 7, 9,
607.4573 +         9,11,11, 6, 8, 9,11,11,10,11,11,14,14, 9,10,11,
607.4574 +        13,14, 5, 7, 7, 9,10, 7, 9, 8,11,11, 7, 9, 9,11,
607.4575 +        11, 9,11,10,14,13,10,11,11,14,14, 8,10,10,13,13,
607.4576 +        10,11,11,15,14, 9,11,11,14,14,13,14,14,17,16,12,
607.4577 +        13,13,15,16, 8,10,10,13,13, 9,11,11,14,15,10,11,
607.4578 +        11,14,15,12,14,13,16,16,13,15,14,15,17, 5, 7, 7,
607.4579 +        10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,11,11,14,
607.4580 +        14,10,11,12,14,14, 7, 9, 9,12,11, 9,11,11,13,13,
607.4581 +         9,11,11,13,13,12,13,13,15,16,11,12,13,15,16, 6,
607.4582 +         9, 9,11,11, 8,11,10,13,12, 9,11,11,13,14,11,13,
607.4583 +        12,16,14,11,13,13,16,17,10,12,11,15,15,11,13,13,
607.4584 +        16,16,11,13,13,17,16,14,15,15,17,17,14,16,16,17,
607.4585 +        18, 9,11,11,14,15,10,12,12,15,15,11,13,13,16,17,
607.4586 +        13,15,13,17,15,14,15,16,18, 0, 5, 7, 7,10,10, 7,
607.4587 +         9, 9,11,11, 7, 9, 9,11,11,10,11,11,14,14,10,11,
607.4588 +        12,14,15, 6, 9, 9,12,11, 9,11,11,13,13, 8,10,11,
607.4589 +        12,13,11,13,13,16,15,11,12,13,14,15, 7, 9, 9,11,
607.4590 +        12, 9,11,11,13,13, 9,11,11,13,13,11,13,13,15,16,
607.4591 +        11,13,13,15,14, 9,11,11,15,14,11,13,13,17,15,10,
607.4592 +        12,12,15,15,14,16,16,17,17,13,13,15,15,17,10,11,
607.4593 +        12,15,15,11,13,13,16,16,11,13,13,15,15,14,15,15,
607.4594 +        18,18,14,15,15,17,17, 8,10,10,13,13,10,12,11,15,
607.4595 +        15,10,11,12,15,15,14,15,15,18,18,13,14,14,18,18,
607.4596 +         9,11,11,15,16,11,13,13,17,17,11,13,13,16,16,15,
607.4597 +        15,16,17, 0,14,15,17, 0, 0, 9,11,11,15,15,10,13,
607.4598 +        12,18,16,11,13,13,15,16,14,16,15,20,20,14,15,16,
607.4599 +        17, 0,13,14,14,20,16,14,15,16,19,18,14,15,15,19,
607.4600 +         0,18,16, 0,20,20,16,18,18, 0, 0,12,14,14,18,18,
607.4601 +        13,15,14,18,16,14,15,16,18,20,16,19,16, 0,17,17,
607.4602 +        18,18,19, 0, 8,10,10,14,14,10,11,11,14,15,10,11,
607.4603 +        12,15,15,13,15,14,19,17,13,15,15,17, 0, 9,11,11,
607.4604 +        16,15,11,13,13,16,16,10,12,13,15,17,14,16,16,18,
607.4605 +        18,14,15,15,18, 0, 9,11,11,15,15,11,13,13,16,17,
607.4606 +        11,13,13,18,17,14,18,16,18,18,15,17,17,18, 0,12,
607.4607 +        14,14,18,18,14,15,15,20, 0,13,14,15,17, 0,16,18,
607.4608 +        17, 0, 0,16,16, 0,17,20,12,14,14,18,18,14,16,15,
607.4609 +         0,18,14,16,15,18, 0,16,19,17, 0, 0,17,18,16, 0,
607.4610 +         0,
607.4611 +};
607.4612 +
607.4613 +static const static_codebook _44u5__p3_0 = {
607.4614 +        4, 625,
607.4615 +        (long *)_vq_lengthlist__44u5__p3_0,
607.4616 +        1, -533725184, 1611661312, 3, 0,
607.4617 +        (long *)_vq_quantlist__44u5__p3_0,
607.4618 +        0
607.4619 +};
607.4620 +
607.4621 +static const long _vq_quantlist__44u5__p4_0[] = {
607.4622 +        2,
607.4623 +        1,
607.4624 +        3,
607.4625 +        0,
607.4626 +        4,
607.4627 +};
607.4628 +
607.4629 +static const long _vq_lengthlist__44u5__p4_0[] = {
607.4630 +         4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8,
607.4631 +         9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8,
607.4632 +         8,10,10, 6, 7, 8, 9,10, 9,10,10,11,12, 9, 9,10,
607.4633 +        11,12, 6, 7, 7, 9, 9, 6, 8, 7,10, 9, 7, 8, 8,10,
607.4634 +        10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,12,11,
607.4635 +         9,10,10,12,12, 9,10,10,12,12,11,12,12,13,14,11,
607.4636 +        11,12,13,14, 8, 9, 9,11,12, 9,10,10,12,12, 9,10,
607.4637 +        10,12,12,11,12,11,14,13,11,12,12,13,13, 5, 7, 7,
607.4638 +         9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,
607.4639 +        12, 9,10,10,12,12, 7, 8, 8,10,10, 8, 8, 9,10,11,
607.4640 +         8, 9, 9,11,11,10,10,11,11,13,10,11,11,12,13, 6,
607.4641 +         7, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
607.4642 +        10,13,11,10,11,11,12,12, 9,10,10,12,12,10,10,11,
607.4643 +        12,13,10,11,11,13,13,12,11,13,12,15,12,13,13,14,
607.4644 +        15, 9,10,10,12,12, 9,11,10,13,12,10,11,11,13,13,
607.4645 +        11,13,11,14,12,12,13,13,14,15, 5, 7, 7, 9, 9, 7,
607.4646 +         8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12, 9,10,
607.4647 +        10,12,12, 6, 8, 7,10,10, 8, 9, 9,11,11, 7, 8, 9,
607.4648 +        10,11,10,11,11,12,12,10,10,11,11,13, 7, 8, 8,10,
607.4649 +        10, 8, 9, 9,11,11, 8, 9, 8,11,10,10,11,11,13,12,
607.4650 +        10,11,10,13,11, 9,10,10,12,12,10,11,11,13,12, 9,
607.4651 +        10,10,12,13,12,13,13,14,15,11,11,13,12,14, 9,10,
607.4652 +        10,12,12,10,11,11,13,13,10,11,10,13,12,12,13,13,
607.4653 +        14,14,12,13,11,14,12, 8, 9, 9,12,12, 9,10,10,12,
607.4654 +        12, 9,10,10,12,12,12,12,12,14,14,11,12,12,14,13,
607.4655 +         9,10,10,12,12,10,11,11,13,13,10,11,11,13,12,12,
607.4656 +        12,13,14,15,12,13,13,15,14, 9,10,10,12,12,10,11,
607.4657 +        10,13,12,10,11,11,12,13,12,13,12,15,13,12,13,13,
607.4658 +        14,15,11,12,12,14,13,11,12,12,14,15,12,13,13,15,
607.4659 +        14,13,12,14,12,16,13,14,14,15,15,11,11,12,14,14,
607.4660 +        11,12,11,14,13,12,13,13,14,15,13,14,12,16,12,14,
607.4661 +        14,15,16,16, 8, 9, 9,11,12, 9,10,10,12,12, 9,10,
607.4662 +        10,12,13,11,12,12,13,13,12,12,13,14,14, 9,10,10,
607.4663 +        12,12,10,11,10,13,12,10,10,11,12,13,12,13,13,15,
607.4664 +        14,12,12,13,13,15, 9,10,10,12,13,10,11,11,12,13,
607.4665 +        10,11,11,13,13,12,13,13,14,15,12,13,12,15,14,11,
607.4666 +        12,11,14,13,12,13,13,15,14,11,11,12,13,14,14,15,
607.4667 +        14,16,15,13,12,14,13,16,11,12,12,13,14,12,13,13,
607.4668 +        14,15,11,12,11,14,14,14,14,14,15,16,13,15,12,16,
607.4669 +        12,
607.4670 +};
607.4671 +
607.4672 +static const static_codebook _44u5__p4_0 = {
607.4673 +        4, 625,
607.4674 +        (long *)_vq_lengthlist__44u5__p4_0,
607.4675 +        1, -533725184, 1611661312, 3, 0,
607.4676 +        (long *)_vq_quantlist__44u5__p4_0,
607.4677 +        0
607.4678 +};
607.4679 +
607.4680 +static const long _vq_quantlist__44u5__p5_0[] = {
607.4681 +        4,
607.4682 +        3,
607.4683 +        5,
607.4684 +        2,
607.4685 +        6,
607.4686 +        1,
607.4687 +        7,
607.4688 +        0,
607.4689 +        8,
607.4690 +};
607.4691 +
607.4692 +static const long _vq_lengthlist__44u5__p5_0[] = {
607.4693 +         2, 3, 3, 6, 6, 8, 8,10,10, 4, 5, 5, 8, 7, 8, 8,
607.4694 +        11,10, 3, 5, 5, 7, 8, 8, 8,10,11, 6, 8, 7,10, 9,
607.4695 +        10,10,11,11, 6, 7, 8, 9, 9, 9,10,11,12, 8, 8, 8,
607.4696 +        10,10,11,11,13,12, 8, 8, 9, 9,10,11,11,12,13,10,
607.4697 +        11,10,12,11,13,12,14,14,10,10,11,11,12,12,13,14,
607.4698 +        14,
607.4699 +};
607.4700 +
607.4701 +static const static_codebook _44u5__p5_0 = {
607.4702 +        2, 81,
607.4703 +        (long *)_vq_lengthlist__44u5__p5_0,
607.4704 +        1, -531628032, 1611661312, 4, 0,
607.4705 +        (long *)_vq_quantlist__44u5__p5_0,
607.4706 +        0
607.4707 +};
607.4708 +
607.4709 +static const long _vq_quantlist__44u5__p6_0[] = {
607.4710 +        4,
607.4711 +        3,
607.4712 +        5,
607.4713 +        2,
607.4714 +        6,
607.4715 +        1,
607.4716 +        7,
607.4717 +        0,
607.4718 +        8,
607.4719 +};
607.4720 +
607.4721 +static const long _vq_lengthlist__44u5__p6_0[] = {
607.4722 +         3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7,
607.4723 +         9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7,
607.4724 +         8, 8,10,10, 6, 6, 6, 7, 7, 8, 8,10,10, 7, 7, 7,
607.4725 +         8, 8, 9, 9,11,10, 7, 7, 7, 8, 8, 9, 9,10,11, 9,
607.4726 +         9, 9,10,10,11,10,11,11, 9, 9, 9,10,10,11,10,11,
607.4727 +        11,
607.4728 +};
607.4729 +
607.4730 +static const static_codebook _44u5__p6_0 = {
607.4731 +        2, 81,
607.4732 +        (long *)_vq_lengthlist__44u5__p6_0,
607.4733 +        1, -531628032, 1611661312, 4, 0,
607.4734 +        (long *)_vq_quantlist__44u5__p6_0,
607.4735 +        0
607.4736 +};
607.4737 +
607.4738 +static const long _vq_quantlist__44u5__p7_0[] = {
607.4739 +        1,
607.4740 +        0,
607.4741 +        2,
607.4742 +};
607.4743 +
607.4744 +static const long _vq_lengthlist__44u5__p7_0[] = {
607.4745 +         1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 9, 8,11,10, 7,
607.4746 +        11,10, 5, 9, 9, 7,10,10, 8,10,11, 4, 9, 9, 9,12,
607.4747 +        12, 9,12,12, 8,12,12,11,12,12,10,12,13, 7,12,12,
607.4748 +        11,12,12,10,12,13, 4, 9, 9, 9,12,12, 9,12,12, 7,
607.4749 +        12,11,10,13,13,11,12,12, 7,12,12,10,13,13,11,12,
607.4750 +        12,
607.4751 +};
607.4752 +
607.4753 +static const static_codebook _44u5__p7_0 = {
607.4754 +        4, 81,
607.4755 +        (long *)_vq_lengthlist__44u5__p7_0,
607.4756 +        1, -529137664, 1618345984, 2, 0,
607.4757 +        (long *)_vq_quantlist__44u5__p7_0,
607.4758 +        0
607.4759 +};
607.4760 +
607.4761 +static const long _vq_quantlist__44u5__p7_1[] = {
607.4762 +        5,
607.4763 +        4,
607.4764 +        6,
607.4765 +        3,
607.4766 +        7,
607.4767 +        2,
607.4768 +        8,
607.4769 +        1,
607.4770 +        9,
607.4771 +        0,
607.4772 +        10,
607.4773 +};
607.4774 +
607.4775 +static const long _vq_lengthlist__44u5__p7_1[] = {
607.4776 +         2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 7,
607.4777 +         8, 8, 9, 8, 8, 9, 4, 5, 5, 7, 7, 8, 8, 9, 9, 8,
607.4778 +         9, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 6, 7, 7, 8,
607.4779 +         8, 9, 9, 9, 9, 9, 9, 7, 8, 8, 9, 9, 9, 9, 9, 9,
607.4780 +         9, 9, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9,
607.4781 +         9, 9, 9, 9,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10,
607.4782 +        10,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10, 8, 9,
607.4783 +         9, 9, 9, 9, 9,10,10,10,10,
607.4784 +};
607.4785 +
607.4786 +static const static_codebook _44u5__p7_1 = {
607.4787 +        2, 121,
607.4788 +        (long *)_vq_lengthlist__44u5__p7_1,
607.4789 +        1, -531365888, 1611661312, 4, 0,
607.4790 +        (long *)_vq_quantlist__44u5__p7_1,
607.4791 +        0
607.4792 +};
607.4793 +
607.4794 +static const long _vq_quantlist__44u5__p8_0[] = {
607.4795 +        5,
607.4796 +        4,
607.4797 +        6,
607.4798 +        3,
607.4799 +        7,
607.4800 +        2,
607.4801 +        8,
607.4802 +        1,
607.4803 +        9,
607.4804 +        0,
607.4805 +        10,
607.4806 +};
607.4807 +
607.4808 +static const long _vq_lengthlist__44u5__p8_0[] = {
607.4809 +         1, 4, 4, 6, 6, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7,
607.4810 +         9, 9,10,10,11,11, 4, 6, 6, 7, 7, 9, 9,10,10,11,
607.4811 +        11, 6, 8, 7, 9, 9,10,10,11,11,13,12, 6, 8, 8, 9,
607.4812 +         9,10,10,11,11,12,13, 8, 9, 9,10,10,12,12,13,12,
607.4813 +        14,13, 8, 9, 9,10,10,12,12,13,13,14,14, 9,11,11,
607.4814 +        12,12,13,13,14,14,15,14, 9,11,11,12,12,13,13,14,
607.4815 +        14,15,14,11,12,12,13,13,14,14,15,14,15,14,11,11,
607.4816 +        12,13,13,14,14,14,14,15,15,
607.4817 +};
607.4818 +
607.4819 +static const static_codebook _44u5__p8_0 = {
607.4820 +        2, 121,
607.4821 +        (long *)_vq_lengthlist__44u5__p8_0,
607.4822 +        1, -524582912, 1618345984, 4, 0,
607.4823 +        (long *)_vq_quantlist__44u5__p8_0,
607.4824 +        0
607.4825 +};
607.4826 +
607.4827 +static const long _vq_quantlist__44u5__p8_1[] = {
607.4828 +        5,
607.4829 +        4,
607.4830 +        6,
607.4831 +        3,
607.4832 +        7,
607.4833 +        2,
607.4834 +        8,
607.4835 +        1,
607.4836 +        9,
607.4837 +        0,
607.4838 +        10,
607.4839 +};
607.4840 +
607.4841 +static const long _vq_lengthlist__44u5__p8_1[] = {
607.4842 +         3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 5, 7, 6,
607.4843 +         7, 7, 8, 8, 8, 8, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8,
607.4844 +         8, 6, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8, 6, 6, 7, 7,
607.4845 +         7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8,
607.4846 +         8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8,
607.4847 +         8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8,
607.4848 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
607.4849 +         8, 8, 8, 8, 8, 8, 8, 8, 8,
607.4850 +};
607.4851 +
607.4852 +static const static_codebook _44u5__p8_1 = {
607.4853 +        2, 121,
607.4854 +        (long *)_vq_lengthlist__44u5__p8_1,
607.4855 +        1, -531365888, 1611661312, 4, 0,
607.4856 +        (long *)_vq_quantlist__44u5__p8_1,
607.4857 +        0
607.4858 +};
607.4859 +
607.4860 +static const long _vq_quantlist__44u5__p9_0[] = {
607.4861 +        6,
607.4862 +        5,
607.4863 +        7,
607.4864 +        4,
607.4865 +        8,
607.4866 +        3,
607.4867 +        9,
607.4868 +        2,
607.4869 +        10,
607.4870 +        1,
607.4871 +        11,
607.4872 +        0,
607.4873 +        12,
607.4874 +};
607.4875 +
607.4876 +static const long _vq_lengthlist__44u5__p9_0[] = {
607.4877 +         1, 3, 2,12,10,13,13,13,13,13,13,13,13, 4, 9, 9,
607.4878 +        13,13,13,13,13,13,13,13,13,13, 5,10, 9,13,13,13,
607.4879 +        13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,13,
607.4880 +        13,13,13,13,11,13,13,13,13,13,13,13,13,13,13,13,
607.4881 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
607.4882 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
607.4883 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
607.4884 +        13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
607.4885 +        13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,12,
607.4886 +        12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
607.4887 +        12,12,12,12,12,12,12,12,12,
607.4888 +};
607.4889 +
607.4890 +static const static_codebook _44u5__p9_0 = {
607.4891 +        2, 169,
607.4892 +        (long *)_vq_lengthlist__44u5__p9_0,
607.4893 +        1, -514332672, 1627381760, 4, 0,
607.4894 +        (long *)_vq_quantlist__44u5__p9_0,
607.4895 +        0
607.4896 +};
607.4897 +
607.4898 +static const long _vq_quantlist__44u5__p9_1[] = {
607.4899 +        7,
607.4900 +        6,
607.4901 +        8,
607.4902 +        5,
607.4903 +        9,
607.4904 +        4,
607.4905 +        10,
607.4906 +        3,
607.4907 +        11,
607.4908 +        2,
607.4909 +        12,
607.4910 +        1,
607.4911 +        13,
607.4912 +        0,
607.4913 +        14,
607.4914 +};
607.4915 +
607.4916 +static const long _vq_lengthlist__44u5__p9_1[] = {
607.4917 +         1, 4, 4, 7, 7, 8, 8, 8, 7, 8, 7, 9, 8, 9, 9, 4,
607.4918 +         7, 6, 9, 8,10,10, 9, 8, 9, 9, 9, 9, 9, 8, 5, 6,
607.4919 +         6, 8, 9,10,10, 9, 9, 9,10,10,10,10,11, 7, 8, 8,
607.4920 +        10,10,11,11,10,10,11,11,11,12,11,11, 7, 8, 8,10,
607.4921 +        10,11,11,10,10,11,11,12,11,11,11, 8, 9, 9,11,11,
607.4922 +        12,12,11,11,12,11,12,12,12,12, 8, 9,10,11,11,12,
607.4923 +        12,11,11,12,12,12,12,12,12, 8, 9, 9,10,10,12,11,
607.4924 +        12,12,12,12,12,12,12,13, 8, 9, 9,11,11,11,11,12,
607.4925 +        12,12,12,13,12,13,13, 9,10,10,11,11,12,12,12,13,
607.4926 +        12,13,13,13,14,13, 9,10,10,11,11,12,12,12,13,13,
607.4927 +        12,13,13,14,13, 9,11,10,12,11,13,12,12,13,13,13,
607.4928 +        13,13,13,14, 9,10,10,12,12,12,12,12,13,13,13,13,
607.4929 +        13,14,14,10,11,11,12,12,12,13,13,13,14,14,13,14,
607.4930 +        14,14,10,11,11,12,12,12,12,13,12,13,14,13,14,14,
607.4931 +        14,
607.4932 +};
607.4933 +
607.4934 +static const static_codebook _44u5__p9_1 = {
607.4935 +        2, 225,
607.4936 +        (long *)_vq_lengthlist__44u5__p9_1,
607.4937 +        1, -522338304, 1620115456, 4, 0,
607.4938 +        (long *)_vq_quantlist__44u5__p9_1,
607.4939 +        0
607.4940 +};
607.4941 +
607.4942 +static const long _vq_quantlist__44u5__p9_2[] = {
607.4943 +        8,
607.4944 +        7,
607.4945 +        9,
607.4946 +        6,
607.4947 +        10,
607.4948 +        5,
607.4949 +        11,
607.4950 +        4,
607.4951 +        12,
607.4952 +        3,
607.4953 +        13,
607.4954 +        2,
607.4955 +        14,
607.4956 +        1,
607.4957 +        15,
607.4958 +        0,
607.4959 +        16,
607.4960 +};
607.4961 +
607.4962 +static const long _vq_lengthlist__44u5__p9_2[] = {
607.4963 +         2, 5, 5, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9,
607.4964 +         9, 5, 6, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,
607.4965 +         9, 9, 5, 6, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9,
607.4966 +         9, 9, 9, 7, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,
607.4967 +         9, 9, 9, 9, 7, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9,
607.4968 +         9, 9, 9, 9, 9, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
607.4969 +         9,10, 9,10,10,10, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9,
607.4970 +         9, 9,10, 9,10, 9,10, 8, 9, 9, 9, 9, 9, 9, 9, 9,
607.4971 +         9,10, 9,10,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10,
607.4972 +         9,10, 9,10,10,10,10,10,10, 9, 9, 9, 9, 9,10, 9,
607.4973 +        10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9,
607.4974 +         9,10, 9,10, 9,10,10,10,10,10,10, 9, 9, 9, 9, 9,
607.4975 +        10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
607.4976 +         9, 9,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
607.4977 +         9,10,10, 9,10,10,10,10,10,10,10,10,10,10, 9, 9,
607.4978 +         9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, 9,
607.4979 +         9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,
607.4980 +         9, 9, 9,10, 9,10,10,10,10,10,10,10,10,10,10,10,
607.4981 +        10,
607.4982 +};
607.4983 +
607.4984 +static const static_codebook _44u5__p9_2 = {
607.4985 +        2, 289,
607.4986 +        (long *)_vq_lengthlist__44u5__p9_2,
607.4987 +        1, -529530880, 1611661312, 5, 0,
607.4988 +        (long *)_vq_quantlist__44u5__p9_2,
607.4989 +        0
607.4990 +};
607.4991 +
607.4992 +static const long _huff_lengthlist__44u5__short[] = {
607.4993 +         4,10,17,13,17,13,17,17,17,17, 3, 6, 8, 9,11, 9,
607.4994 +        15,12,16,17, 6, 5, 5, 7, 7, 8,10,11,17,17, 7, 8,
607.4995 +         7, 9, 9,10,13,13,17,17, 8, 6, 5, 7, 4, 7, 5, 8,
607.4996 +        14,17, 9, 9, 8, 9, 7, 9, 8,10,16,17,12,10, 7, 8,
607.4997 +         4, 7, 4, 7,16,17,12,11, 9,10, 6, 9, 5, 7,14,17,
607.4998 +        14,13,10,15, 4, 8, 3, 5,14,17,17,14,11,15, 6,10,
607.4999 +         6, 8,15,17,
607.5000 +};
607.5001 +
607.5002 +static const static_codebook _huff_book__44u5__short = {
607.5003 +        2, 100,
607.5004 +        (long *)_huff_lengthlist__44u5__short,
607.5005 +        0, 0, 0, 0, 0,
607.5006 +        NULL,
607.5007 +        0
607.5008 +};
607.5009 +
607.5010 +static const long _huff_lengthlist__44u6__long[] = {
607.5011 +         3, 9,14,13,14,13,16,12,13,14, 5, 4, 6, 6, 8, 9,
607.5012 +        11,10,12,15,10, 5, 5, 6, 6, 8,10,10,13,16,10, 6,
607.5013 +         6, 6, 6, 8, 9, 9,12,14,13, 7, 6, 6, 4, 6, 6, 7,
607.5014 +        11,14,10, 7, 7, 7, 6, 6, 6, 7,10,13,15,10, 9, 8,
607.5015 +         5, 6, 5, 6,10,14,10, 9, 8, 8, 6, 6, 5, 4, 6,11,
607.5016 +        11,11,12,11,10, 9, 9, 5, 5, 9,10,12,15,13,13,13,
607.5017 +        13, 8, 7, 7,
607.5018 +};
607.5019 +
607.5020 +static const static_codebook _huff_book__44u6__long = {
607.5021 +        2, 100,
607.5022 +        (long *)_huff_lengthlist__44u6__long,
607.5023 +        0, 0, 0, 0, 0,
607.5024 +        NULL,
607.5025 +        0
607.5026 +};
607.5027 +
607.5028 +static const long _vq_quantlist__44u6__p1_0[] = {
607.5029 +        1,
607.5030 +        0,
607.5031 +        2,
607.5032 +};
607.5033 +
607.5034 +static const long _vq_lengthlist__44u6__p1_0[] = {
607.5035 +         1, 4, 4, 4, 8, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7,
607.5036 +         9,10, 5, 8, 8, 7,10, 9, 8,10,10, 5, 8, 8, 8,10,
607.5037 +        10, 8,10,10, 8,10,10,10,12,13,10,13,13, 7,10,10,
607.5038 +        10,13,11,10,13,13, 5, 8, 8, 8,11,10, 8,10,10, 7,
607.5039 +        10,10,10,13,13,10,11,13, 8,10,11,10,13,13,10,13,
607.5040 +        12,
607.5041 +};
607.5042 +
607.5043 +static const static_codebook _44u6__p1_0 = {
607.5044 +        4, 81,
607.5045 +        (long *)_vq_lengthlist__44u6__p1_0,
607.5046 +        1, -535822336, 1611661312, 2, 0,
607.5047 +        (long *)_vq_quantlist__44u6__p1_0,
607.5048 +        0
607.5049 +};
607.5050 +
607.5051 +static const long _vq_quantlist__44u6__p2_0[] = {
607.5052 +        1,
607.5053 +        0,
607.5054 +        2,
607.5055 +};
607.5056 +
607.5057 +static const long _vq_lengthlist__44u6__p2_0[] = {
607.5058 +         3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6,
607.5059 +         7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8,
607.5060 +         8, 6, 8, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 7, 7,
607.5061 +         7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 8, 8, 6,
607.5062 +         8, 8, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9,
607.5063 +         9,
607.5064 +};
607.5065 +
607.5066 +static const static_codebook _44u6__p2_0 = {
607.5067 +        4, 81,
607.5068 +        (long *)_vq_lengthlist__44u6__p2_0,
607.5069 +        1, -535822336, 1611661312, 2, 0,
607.5070 +        (long *)_vq_quantlist__44u6__p2_0,
607.5071 +        0
607.5072 +};
607.5073 +
607.5074 +static const long _vq_quantlist__44u6__p3_0[] = {
607.5075 +        2,
607.5076 +        1,
607.5077 +        3,
607.5078 +        0,
607.5079 +        4,
607.5080 +};
607.5081 +
607.5082 +static const long _vq_lengthlist__44u6__p3_0[] = {
607.5083 +         2, 5, 4, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8,
607.5084 +         9, 9,13,12, 8, 9,10,12,13, 5, 7, 7,10, 9, 7, 9,
607.5085 +         9,11,11, 7, 8, 9,11,11,10,11,11,14,14, 9,10,11,
607.5086 +        13,14, 5, 7, 7, 9,10, 6, 9, 8,11,11, 7, 9, 9,11,
607.5087 +        11, 9,11,10,14,13,10,11,11,14,13, 8,10,10,13,13,
607.5088 +        10,11,11,15,15, 9,11,11,14,14,13,14,14,17,16,12,
607.5089 +        13,14,16,16, 8,10,10,13,14, 9,11,11,14,15,10,11,
607.5090 +        12,14,15,12,14,13,16,15,13,14,14,15,17, 5, 7, 7,
607.5091 +        10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,12,11,14,
607.5092 +        14,10,11,11,14,14, 7, 9, 9,12,11, 9,11,11,13,13,
607.5093 +         9,11,11,13,13,11,13,13,14,15,11,12,13,15,16, 6,
607.5094 +         9, 9,11,12, 8,11,10,13,12, 9,11,11,13,14,11,13,
607.5095 +        12,16,14,11,13,13,15,16,10,12,11,14,15,11,13,13,
607.5096 +        15,17,11,13,13,17,16,15,15,16,17,16,14,15,16,18,
607.5097 +         0, 9,11,11,14,15,10,12,12,16,15,11,13,13,16,16,
607.5098 +        13,15,14,18,15,14,16,16, 0, 0, 5, 7, 7,10,10, 7,
607.5099 +         9, 9,11,11, 7, 9, 9,11,11,10,11,11,14,14,10,11,
607.5100 +        12,14,14, 6, 9, 9,11,11, 9,11,11,13,13, 8,10,11,
607.5101 +        12,13,11,13,13,16,15,11,12,13,14,16, 7, 9, 9,11,
607.5102 +        12, 9,11,11,13,13, 9,11,11,13,13,11,13,13,16,15,
607.5103 +        11,13,12,15,15, 9,11,11,15,14,11,13,13,17,16,10,
607.5104 +        12,13,15,16,14,16,16, 0,18,14,14,15,15,17,10,11,
607.5105 +        12,15,15,11,13,13,16,16,11,13,13,16,16,14,16,16,
607.5106 +        19,17,14,15,15,17,17, 8,10,10,14,14,10,12,11,15,
607.5107 +        15,10,11,12,16,15,14,15,15,18,20,13,14,16,17,18,
607.5108 +         9,11,11,15,16,11,13,13,17,17,11,13,13,17,16,15,
607.5109 +        16,16, 0, 0,15,16,16, 0, 0, 9,11,11,15,15,10,13,
607.5110 +        12,17,15,11,13,13,17,16,15,17,15,20,19,15,16,16,
607.5111 +        19, 0,13,15,14, 0,17,14,15,16, 0,20,15,16,16, 0,
607.5112 +        19,17,18, 0, 0, 0,16,17,18, 0, 0,12,14,14,19,18,
607.5113 +        13,15,14, 0,17,14,15,16,19,19,16,18,16, 0,19,19,
607.5114 +        20,17,20, 0, 8,10,10,13,14,10,11,11,15,15,10,12,
607.5115 +        12,15,16,14,15,14,19,16,14,15,15, 0,18, 9,11,11,
607.5116 +        16,15,11,13,13, 0,16,11,12,13,16,17,14,16,17, 0,
607.5117 +        19,15,16,16,18, 0, 9,11,11,15,16,11,13,13,16,16,
607.5118 +        11,14,13,18,17,15,16,16,18,20,15,17,19, 0, 0,12,
607.5119 +        14,14,17,17,14,16,15, 0, 0,13,14,15,19, 0,16,18,
607.5120 +        20, 0, 0,16,16,18,18, 0,12,14,14,17,20,14,16,16,
607.5121 +        19, 0,14,16,14, 0,20,16,20,17, 0, 0,17, 0,15, 0,
607.5122 +        19,
607.5123 +};
607.5124 +
607.5125 +static const static_codebook _44u6__p3_0 = {
607.5126 +        4, 625,
607.5127 +        (long *)_vq_lengthlist__44u6__p3_0,
607.5128 +        1, -533725184, 1611661312, 3, 0,
607.5129 +        (long *)_vq_quantlist__44u6__p3_0,
607.5130 +        0
607.5131 +};
607.5132 +
607.5133 +static const long _vq_quantlist__44u6__p4_0[] = {
607.5134 +        2,
607.5135 +        1,
607.5136 +        3,
607.5137 +        0,
607.5138 +        4,
607.5139 +};
607.5140 +
607.5141 +static const long _vq_lengthlist__44u6__p4_0[] = {
607.5142 +         4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8,
607.5143 +         9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8,
607.5144 +         8,10,10, 7, 7, 8, 9,10, 9,10,10,11,11, 9, 9,10,
607.5145 +        11,12, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 8,10,
607.5146 +        10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,11,11,
607.5147 +         9,10,10,12,12, 9,10,10,12,12,11,12,12,14,13,11,
607.5148 +        11,12,13,13, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
607.5149 +        10,12,12,11,12,11,13,12,11,12,12,13,13, 5, 7, 7,
607.5150 +         9, 9, 7, 8, 7,10,10, 7, 7, 8,10,10, 9,10,10,12,
607.5151 +        11, 9,10,10,11,12, 7, 8, 8,10,10, 8, 8, 9,11,11,
607.5152 +         8, 9, 9,11,11,10,10,11,12,13,10,10,11,12,12, 6,
607.5153 +         7, 7,10,10, 7, 9, 8,11,10, 8, 8, 9,10,11,10,11,
607.5154 +        10,13,11,10,11,11,12,12, 9,10,10,12,12,10,10,11,
607.5155 +        13,13,10,11,11,12,13,12,12,12,13,14,12,12,13,14,
607.5156 +        14, 9,10,10,12,12, 9,10,10,13,12,10,11,11,13,13,
607.5157 +        11,12,11,14,12,12,13,13,14,14, 6, 7, 7, 9, 9, 7,
607.5158 +         8, 7,10,10, 7, 8, 8,10,10, 9,10,10,12,11, 9,10,
607.5159 +        10,11,12, 6, 7, 7,10,10, 8, 9, 8,11,10, 7, 8, 9,
607.5160 +        10,11,10,11,11,12,12,10,10,11,11,13, 7, 8, 8,10,
607.5161 +        10, 8, 9, 9,11,11, 8, 9, 8,11,11,10,11,10,13,12,
607.5162 +        10,11,11,13,12, 9,10,10,12,12,10,11,11,13,12, 9,
607.5163 +        10,10,12,13,12,13,12,14,14,11,11,12,12,14, 9,10,
607.5164 +        10,12,12,10,11,11,13,13,10,11,10,13,12,12,12,12,
607.5165 +        14,14,12,13,12,14,13, 8, 9, 9,11,11, 9,10,10,12,
607.5166 +        12, 9,10,10,12,12,11,12,12,14,13,11,12,12,13,14,
607.5167 +         9,10,10,12,12,10,11,11,13,13,10,11,11,13,13,12,
607.5168 +        12,13,14,15,12,12,13,14,14, 9,10,10,12,12, 9,11,
607.5169 +        10,13,12,10,10,11,12,13,12,13,12,14,13,12,12,13,
607.5170 +        14,15,11,12,12,14,13,11,12,12,14,14,12,13,13,14,
607.5171 +        14,13,13,14,14,16,13,14,14,15,15,11,12,11,13,13,
607.5172 +        11,12,11,14,13,12,12,13,14,15,12,14,12,15,12,13,
607.5173 +        14,15,15,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
607.5174 +        10,12,12,11,12,12,14,13,11,12,12,13,13, 9,10,10,
607.5175 +        12,12,10,11,10,13,12, 9,10,11,12,13,12,13,12,14,
607.5176 +        14,12,12,13,13,14, 9,10,10,12,12,10,11,11,13,13,
607.5177 +        10,11,11,13,13,12,13,12,14,14,12,13,13,14,14,11,
607.5178 +        11,11,13,13,12,13,12,14,14,11,11,12,13,14,14,14,
607.5179 +        14,16,15,12,12,14,12,15,11,12,12,13,14,12,13,13,
607.5180 +        14,15,11,12,12,14,14,13,14,14,16,16,13,14,13,16,
607.5181 +        13,
607.5182 +};
607.5183 +
607.5184 +static const static_codebook _44u6__p4_0 = {
607.5185 +        4, 625,
607.5186 +        (long *)_vq_lengthlist__44u6__p4_0,
607.5187 +        1, -533725184, 1611661312, 3, 0,
607.5188 +        (long *)_vq_quantlist__44u6__p4_0,
607.5189 +        0
607.5190 +};
607.5191 +
607.5192 +static const long _vq_quantlist__44u6__p5_0[] = {
607.5193 +        4,
607.5194 +        3,
607.5195 +        5,
607.5196 +        2,
607.5197 +        6,
607.5198 +        1,
607.5199 +        7,
607.5200 +        0,
607.5201 +        8,
607.5202 +};
607.5203 +
607.5204 +static const long _vq_lengthlist__44u6__p5_0[] = {
607.5205 +         2, 3, 3, 6, 6, 8, 8,10,10, 4, 5, 5, 8, 7, 8, 8,
607.5206 +        11,11, 3, 5, 5, 7, 8, 8, 8,11,11, 6, 8, 7, 9, 9,
607.5207 +        10, 9,12,11, 6, 7, 8, 9, 9, 9,10,11,12, 8, 8, 8,
607.5208 +        10, 9,12,11,13,13, 8, 8, 9, 9,10,11,12,13,13,10,
607.5209 +        11,11,12,12,13,13,14,14,10,10,11,11,12,13,13,14,
607.5210 +        14,
607.5211 +};
607.5212 +
607.5213 +static const static_codebook _44u6__p5_0 = {
607.5214 +        2, 81,
607.5215 +        (long *)_vq_lengthlist__44u6__p5_0,
607.5216 +        1, -531628032, 1611661312, 4, 0,
607.5217 +        (long *)_vq_quantlist__44u6__p5_0,
607.5218 +        0
607.5219 +};
607.5220 +
607.5221 +static const long _vq_quantlist__44u6__p6_0[] = {
607.5222 +        4,
607.5223 +        3,
607.5224 +        5,
607.5225 +        2,
607.5226 +        6,
607.5227 +        1,
607.5228 +        7,
607.5229 +        0,
607.5230 +        8,
607.5231 +};
607.5232 +
607.5233 +static const long _vq_lengthlist__44u6__p6_0[] = {
607.5234 +         3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7,
607.5235 +         9, 9, 4, 4, 5, 6, 6, 7, 8, 9, 9, 5, 6, 6, 7, 7,
607.5236 +         8, 8,10,10, 5, 6, 6, 7, 7, 8, 8,10,10, 7, 8, 7,
607.5237 +         8, 8,10, 9,11,11, 7, 7, 8, 8, 8, 9,10,10,11, 9,
607.5238 +         9, 9,10,10,11,11,12,11, 9, 9, 9,10,10,11,11,11,
607.5239 +        12,
607.5240 +};
607.5241 +
607.5242 +static const static_codebook _44u6__p6_0 = {
607.5243 +        2, 81,
607.5244 +        (long *)_vq_lengthlist__44u6__p6_0,
607.5245 +        1, -531628032, 1611661312, 4, 0,
607.5246 +        (long *)_vq_quantlist__44u6__p6_0,
607.5247 +        0
607.5248 +};
607.5249 +
607.5250 +static const long _vq_quantlist__44u6__p7_0[] = {
607.5251 +        1,
607.5252 +        0,
607.5253 +        2,
607.5254 +};
607.5255 +
607.5256 +static const long _vq_lengthlist__44u6__p7_0[] = {
607.5257 +         1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 7,10,10, 8,
607.5258 +        10,10, 5, 8, 9, 7,10,10, 7,10, 9, 4, 8, 8, 9,11,
607.5259 +        11, 8,11,11, 7,11,11,10,10,13,10,13,13, 7,11,11,
607.5260 +        10,13,12,10,13,13, 5, 9, 8, 8,11,11, 9,11,11, 7,
607.5261 +        11,11,10,13,13,10,12,13, 7,11,11,10,13,13, 9,13,
607.5262 +        10,
607.5263 +};
607.5264 +
607.5265 +static const static_codebook _44u6__p7_0 = {
607.5266 +        4, 81,
607.5267 +        (long *)_vq_lengthlist__44u6__p7_0,
607.5268 +        1, -529137664, 1618345984, 2, 0,
607.5269 +        (long *)_vq_quantlist__44u6__p7_0,
607.5270 +        0
607.5271 +};
607.5272 +
607.5273 +static const long _vq_quantlist__44u6__p7_1[] = {
607.5274 +        5,
607.5275 +        4,
607.5276 +        6,
607.5277 +        3,
607.5278 +        7,
607.5279 +        2,
607.5280 +        8,
607.5281 +        1,
607.5282 +        9,
607.5283 +        0,
607.5284 +        10,
607.5285 +};
607.5286 +
607.5287 +static const long _vq_lengthlist__44u6__p7_1[] = {
607.5288 +         3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 6,
607.5289 +         8, 8, 8, 8, 8, 8, 4, 5, 5, 6, 7, 8, 8, 8, 8, 8,
607.5290 +         8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7,
607.5291 +         7, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 9, 9,
607.5292 +         9, 9, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8,
607.5293 +         8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9,
607.5294 +         9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8,
607.5295 +         8, 8, 8, 9, 9, 9, 9, 9, 9,
607.5296 +};
607.5297 +
607.5298 +static const static_codebook _44u6__p7_1 = {
607.5299 +        2, 121,
607.5300 +        (long *)_vq_lengthlist__44u6__p7_1,
607.5301 +        1, -531365888, 1611661312, 4, 0,
607.5302 +        (long *)_vq_quantlist__44u6__p7_1,
607.5303 +        0
607.5304 +};
607.5305 +
607.5306 +static const long _vq_quantlist__44u6__p8_0[] = {
607.5307 +        5,
607.5308 +        4,
607.5309 +        6,
607.5310 +        3,
607.5311 +        7,
607.5312 +        2,
607.5313 +        8,
607.5314 +        1,
607.5315 +        9,
607.5316 +        0,
607.5317 +        10,
607.5318 +};
607.5319 +
607.5320 +static const long _vq_lengthlist__44u6__p8_0[] = {
607.5321 +         1, 4, 4, 6, 6, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7,
607.5322 +         9, 9,10,10,11,11, 4, 6, 6, 7, 7, 9, 9,10,10,11,
607.5323 +        11, 6, 8, 8, 9, 9,10,10,11,11,12,12, 6, 8, 8, 9,
607.5324 +         9,10,10,11,11,12,12, 8, 9, 9,10,10,11,11,12,12,
607.5325 +        13,13, 8, 9, 9,10,10,11,11,12,12,13,13,10,10,10,
607.5326 +        11,11,13,13,13,13,15,14, 9,10,10,12,11,12,13,13,
607.5327 +        13,14,15,11,12,12,13,13,13,13,15,14,15,15,11,11,
607.5328 +        12,13,13,14,14,14,15,15,15,
607.5329 +};
607.5330 +
607.5331 +static const static_codebook _44u6__p8_0 = {
607.5332 +        2, 121,
607.5333 +        (long *)_vq_lengthlist__44u6__p8_0,
607.5334 +        1, -524582912, 1618345984, 4, 0,
607.5335 +        (long *)_vq_quantlist__44u6__p8_0,
607.5336 +        0
607.5337 +};
607.5338 +
607.5339 +static const long _vq_quantlist__44u6__p8_1[] = {
607.5340 +        5,
607.5341 +        4,
607.5342 +        6,
607.5343 +        3,
607.5344 +        7,
607.5345 +        2,
607.5346 +        8,
607.5347 +        1,
607.5348 +        9,
607.5349 +        0,
607.5350 +        10,
607.5351 +};
607.5352 +
607.5353 +static const long _vq_lengthlist__44u6__p8_1[] = {
607.5354 +         3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 5, 7, 7,
607.5355 +         7, 7, 8, 7, 8, 8, 5, 5, 6, 6, 7, 7, 7, 7, 7, 8,
607.5356 +         8, 6, 7, 7, 7, 7, 8, 7, 8, 8, 8, 8, 6, 6, 7, 7,
607.5357 +         7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8,
607.5358 +         8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7,
607.5359 +         8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8,
607.5360 +         8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8,
607.5361 +         8, 8, 8, 8, 8, 8, 8, 8, 8,
607.5362 +};
607.5363 +
607.5364 +static const static_codebook _44u6__p8_1 = {
607.5365 +        2, 121,
607.5366 +        (long *)_vq_lengthlist__44u6__p8_1,
607.5367 +        1, -531365888, 1611661312, 4, 0,
607.5368 +        (long *)_vq_quantlist__44u6__p8_1,
607.5369 +        0
607.5370 +};
607.5371 +
607.5372 +static const long _vq_quantlist__44u6__p9_0[] = {
607.5373 +        7,
607.5374 +        6,
607.5375 +        8,
607.5376 +        5,
607.5377 +        9,
607.5378 +        4,
607.5379 +        10,
607.5380 +        3,
607.5381 +        11,
607.5382 +        2,
607.5383 +        12,
607.5384 +        1,
607.5385 +        13,
607.5386 +        0,
607.5387 +        14,
607.5388 +};
607.5389 +
607.5390 +static const long _vq_lengthlist__44u6__p9_0[] = {
607.5391 +         1, 3, 2, 9, 8,15,15,15,15,15,15,15,15,15,15, 4,
607.5392 +         8, 9,13,14,14,14,14,14,14,14,14,14,14,14, 5, 8,
607.5393 +         9,14,14,14,14,14,14,14,14,14,14,14,14,11,14,14,
607.5394 +        14,14,14,14,14,14,14,14,14,14,14,14,11,14,14,14,
607.5395 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
607.5396 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
607.5397 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
607.5398 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
607.5399 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
607.5400 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
607.5401 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
607.5402 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
607.5403 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
607.5404 +        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
607.5405 +        14,
607.5406 +};
607.5407 +
607.5408 +static const static_codebook _44u6__p9_0 = {
607.5409 +        2, 225,
607.5410 +        (long *)_vq_lengthlist__44u6__p9_0,
607.5411 +        1, -514071552, 1627381760, 4, 0,
607.5412 +        (long *)_vq_quantlist__44u6__p9_0,
607.5413 +        0
607.5414 +};
607.5415 +
607.5416 +static const long _vq_quantlist__44u6__p9_1[] = {
607.5417 +        7,
607.5418 +        6,
607.5419 +        8,
607.5420 +        5,
607.5421 +        9,
607.5422 +        4,
607.5423 +        10,
607.5424 +        3,
607.5425 +        11,
607.5426 +        2,
607.5427 +        12,
607.5428 +        1,
607.5429 +        13,
607.5430 +        0,
607.5431 +        14,
607.5432 +};
607.5433 +
607.5434 +static const long _vq_lengthlist__44u6__p9_1[] = {
607.5435 +         1, 4, 4, 7, 7, 8, 9, 8, 8, 9, 8, 9, 8, 9, 9, 4,
607.5436 +         7, 6, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 7,
607.5437 +         6, 9, 9,10,10, 9, 9,10,10,10,10,11,11, 7, 9, 8,
607.5438 +        10,10,11,11,10,10,11,11,11,11,11,11, 7, 8, 9,10,
607.5439 +        10,11,11,10,10,11,11,11,11,11,12, 8,10,10,11,11,
607.5440 +        12,12,11,11,12,12,12,12,13,12, 8,10,10,11,11,12,
607.5441 +        11,11,11,11,12,12,12,12,13, 8, 9, 9,11,10,11,11,
607.5442 +        12,12,12,12,13,12,13,12, 8, 9, 9,11,11,11,11,12,
607.5443 +        12,12,12,12,13,13,13, 9,10,10,11,12,12,12,12,12,
607.5444 +        13,13,13,13,13,13, 9,10,10,11,11,12,12,12,12,13,
607.5445 +        13,13,13,14,13,10,10,10,12,11,12,12,13,13,13,13,
607.5446 +        13,13,13,13,10,10,11,11,11,12,12,13,13,13,13,13,
607.5447 +        13,13,13,10,11,11,12,12,13,12,12,13,13,13,13,13,
607.5448 +        13,14,10,11,11,12,12,13,12,13,13,13,14,13,13,14,
607.5449 +        13,
607.5450 +};
607.5451 +
607.5452 +static const static_codebook _44u6__p9_1 = {
607.5453 +        2, 225,
607.5454 +        (long *)_vq_lengthlist__44u6__p9_1,
607.5455 +        1, -522338304, 1620115456, 4, 0,
607.5456 +        (long *)_vq_quantlist__44u6__p9_1,
607.5457 +        0
607.5458 +};
607.5459 +
607.5460 +static const long _vq_quantlist__44u6__p9_2[] = {
607.5461 +        8,
607.5462 +        7,
607.5463 +        9,
607.5464 +        6,
607.5465 +        10,
607.5466 +        5,
607.5467 +        11,
607.5468 +        4,
607.5469 +        12,
607.5470 +        3,
607.5471 +        13,
607.5472 +        2,
607.5473 +        14,
607.5474 +        1,
607.5475 +        15,
607.5476 +        0,
607.5477 +        16,
607.5478 +};
607.5479 +
607.5480 +static const long _vq_lengthlist__44u6__p9_2[] = {
607.5481 +         3, 5, 5, 7, 7, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 9,
607.5482 +         9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
607.5483 +         9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9,
607.5484 +         9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.5485 +         9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
607.5486 +         9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.5487 +         9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9,
607.5488 +         9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, 9,
607.5489 +         9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9,
607.5490 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9,
607.5491 +         9, 9, 9, 9, 9, 9, 9, 9,10, 9, 8, 9, 9, 9, 9, 9,
607.5492 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.5493 +         9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9, 9, 9, 9, 9,
607.5494 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,
607.5495 +         9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10, 9, 9, 9,
607.5496 +         9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10, 9, 9,10, 9,
607.5497 +         9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9,10, 9,10,10,
607.5498 +         9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10,10, 9, 9,
607.5499 +        10,
607.5500 +};
607.5501 +
607.5502 +static const static_codebook _44u6__p9_2 = {
607.5503 +        2, 289,
607.5504 +        (long *)_vq_lengthlist__44u6__p9_2,
607.5505 +        1, -529530880, 1611661312, 5, 0,
607.5506 +        (long *)_vq_quantlist__44u6__p9_2,
607.5507 +        0
607.5508 +};
607.5509 +
607.5510 +static const long _huff_lengthlist__44u6__short[] = {
607.5511 +         4,11,16,13,17,13,17,16,17,17, 4, 7, 9, 9,13,10,
607.5512 +        16,12,16,17, 7, 6, 5, 7, 8, 9,12,12,16,17, 6, 9,
607.5513 +         7, 9,10,10,15,15,17,17, 6, 7, 5, 7, 5, 7, 7,10,
607.5514 +        16,17, 7, 9, 8, 9, 8,10,11,11,15,17, 7, 7, 7, 8,
607.5515 +         5, 8, 8, 9,15,17, 8, 7, 9, 9, 7, 8, 7, 2, 7,15,
607.5516 +        14,13,13,15, 5,10, 4, 3, 6,17,17,15,13,17, 7,11,
607.5517 +         7, 6, 9,16,
607.5518 +};
607.5519 +
607.5520 +static const static_codebook _huff_book__44u6__short = {
607.5521 +        2, 100,
607.5522 +        (long *)_huff_lengthlist__44u6__short,
607.5523 +        0, 0, 0, 0, 0,
607.5524 +        NULL,
607.5525 +        0
607.5526 +};
607.5527 +
607.5528 +static const long _huff_lengthlist__44u7__long[] = {
607.5529 +         3, 9,14,13,15,14,16,13,13,14, 5, 5, 7, 7, 8, 9,
607.5530 +        11,10,12,15,10, 6, 5, 6, 6, 9,10,10,13,16,10, 6,
607.5531 +         6, 6, 6, 8, 9, 9,12,15,14, 7, 6, 6, 5, 6, 6, 8,
607.5532 +        12,15,10, 8, 7, 7, 6, 7, 7, 7,11,13,14,10, 9, 8,
607.5533 +         5, 6, 4, 5, 9,12,10, 9, 9, 8, 6, 6, 5, 3, 6,11,
607.5534 +        12,11,12,12,10, 9, 8, 5, 5, 8,10,11,15,13,13,13,
607.5535 +        12, 8, 6, 7,
607.5536 +};
607.5537 +
607.5538 +static const static_codebook _huff_book__44u7__long = {
607.5539 +        2, 100,
607.5540 +        (long *)_huff_lengthlist__44u7__long,
607.5541 +        0, 0, 0, 0, 0,
607.5542 +        NULL,
607.5543 +        0
607.5544 +};
607.5545 +
607.5546 +static const long _vq_quantlist__44u7__p1_0[] = {
607.5547 +        1,
607.5548 +        0,
607.5549 +        2,
607.5550 +};
607.5551 +
607.5552 +static const long _vq_lengthlist__44u7__p1_0[] = {
607.5553 +         1, 4, 4, 4, 7, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7,
607.5554 +        10,10, 5, 8, 8, 7,10,10, 8,10,10, 5, 8, 8, 8,11,
607.5555 +        10, 8,10,10, 8,10,10,10,12,13,10,13,13, 7,10,10,
607.5556 +        10,13,12,10,13,13, 5, 8, 8, 8,11,10, 8,10,11, 7,
607.5557 +        10,10,10,13,13,10,12,13, 8,11,11,10,13,13,10,13,
607.5558 +        12,
607.5559 +};
607.5560 +
607.5561 +static const static_codebook _44u7__p1_0 = {
607.5562 +        4, 81,
607.5563 +        (long *)_vq_lengthlist__44u7__p1_0,
607.5564 +        1, -535822336, 1611661312, 2, 0,
607.5565 +        (long *)_vq_quantlist__44u7__p1_0,
607.5566 +        0
607.5567 +};
607.5568 +
607.5569 +static const long _vq_quantlist__44u7__p2_0[] = {
607.5570 +        1,
607.5571 +        0,
607.5572 +        2,
607.5573 +};
607.5574 +
607.5575 +static const long _vq_lengthlist__44u7__p2_0[] = {
607.5576 +         3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6,
607.5577 +         7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8,
607.5578 +         7, 6, 8, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 8, 7,
607.5579 +         7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 8, 8, 6,
607.5580 +         8, 8, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9,
607.5581 +         9,
607.5582 +};
607.5583 +
607.5584 +static const static_codebook _44u7__p2_0 = {
607.5585 +        4, 81,
607.5586 +        (long *)_vq_lengthlist__44u7__p2_0,
607.5587 +        1, -535822336, 1611661312, 2, 0,
607.5588 +        (long *)_vq_quantlist__44u7__p2_0,
607.5589 +        0
607.5590 +};
607.5591 +
607.5592 +static const long _vq_quantlist__44u7__p3_0[] = {
607.5593 +        2,
607.5594 +        1,
607.5595 +        3,
607.5596 +        0,
607.5597 +        4,
607.5598 +};
607.5599 +
607.5600 +static const long _vq_lengthlist__44u7__p3_0[] = {
607.5601 +         2, 5, 4, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8,
607.5602 +         9, 9,13,12, 8, 9,10,12,13, 5, 7, 7,10, 9, 7, 9,
607.5603 +         9,11,11, 6, 8, 9,11,11,10,11,11,14,14, 9,10,11,
607.5604 +        13,14, 5, 7, 7, 9, 9, 7, 9, 8,11,11, 7, 9, 9,11,
607.5605 +        11, 9,11,10,14,13,10,11,11,14,14, 8,10,10,14,13,
607.5606 +        10,11,12,15,14, 9,11,11,15,14,13,14,14,16,16,12,
607.5607 +        13,14,17,16, 8,10,10,13,13, 9,11,11,14,15,10,11,
607.5608 +        12,14,15,12,14,13,16,16,13,14,15,15,17, 5, 7, 7,
607.5609 +        10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,12,11,15,
607.5610 +        14,10,11,12,14,14, 7, 9, 9,12,12, 9,11,11,13,13,
607.5611 +         9,11,11,13,13,11,13,13,14,17,11,13,13,15,16, 6,
607.5612 +         9, 9,11,11, 8,11,10,13,12, 9,11,11,13,13,11,13,
607.5613 +        12,16,14,11,13,13,16,16,10,12,12,15,15,11,13,13,
607.5614 +        16,16,11,13,13,16,15,14,16,17,17,19,14,16,16,18,
607.5615 +         0, 9,11,11,14,15,10,13,12,16,15,11,13,13,16,16,
607.5616 +        14,15,14, 0,16,14,16,16,18, 0, 5, 7, 7,10,10, 7,
607.5617 +         9, 9,12,11, 7, 9, 9,11,12,10,11,11,15,14,10,11,
607.5618 +        12,14,14, 6, 9, 9,11,11, 9,11,11,13,13, 8,10,11,
607.5619 +        12,13,11,13,13,17,15,11,12,13,14,15, 7, 9, 9,11,
607.5620 +        12, 9,11,11,13,13, 9,11,11,13,13,11,13,12,16,16,
607.5621 +        11,13,13,15,14, 9,11,11,14,15,11,13,13,16,15,10,
607.5622 +        12,13,16,16,15,16,16, 0, 0,14,13,15,16,18,10,11,
607.5623 +        11,15,15,11,13,14,16,18,11,13,13,16,15,15,16,16,
607.5624 +        19, 0,14,15,15,16,16, 8,10,10,13,13,10,12,11,16,
607.5625 +        15,10,11,11,16,15,13,15,16,18, 0,13,14,15,17,17,
607.5626 +         9,11,11,15,15,11,13,13,16,18,11,13,13,16,17,15,
607.5627 +        16,16, 0, 0,15,18,16, 0,17, 9,11,11,15,15,11,13,
607.5628 +        12,17,15,11,13,14,16,17,15,18,15, 0,17,15,16,16,
607.5629 +        18,19,13,15,14, 0,18,14,16,16,19,18,14,16,15,19,
607.5630 +        19,16,18,19, 0, 0,16,17, 0, 0, 0,12,14,14,17,17,
607.5631 +        13,16,14, 0,18,14,16,15,18, 0,16,18,16,19,17,18,
607.5632 +        19,17, 0, 0, 8,10,10,14,14, 9,12,11,15,15,10,11,
607.5633 +        12,15,17,13,15,15,18,16,14,16,15,18,17, 9,11,11,
607.5634 +        16,15,11,13,13, 0,16,11,12,13,16,15,15,16,16, 0,
607.5635 +        17,15,15,16,18,17, 9,12,11,15,17,11,13,13,16,16,
607.5636 +        11,14,13,16,16,15,15,16,18,19,16,18,16, 0, 0,12,
607.5637 +        14,14, 0,16,14,16,16, 0,18,13,14,15,16, 0,17,16,
607.5638 +        18, 0, 0,16,16,17,19, 0,13,14,14,17, 0,14,17,16,
607.5639 +         0,19,14,15,15,18,19,17,16,18, 0, 0,15,19,16, 0,
607.5640 +         0,
607.5641 +};
607.5642 +
607.5643 +static const static_codebook _44u7__p3_0 = {
607.5644 +        4, 625,
607.5645 +        (long *)_vq_lengthlist__44u7__p3_0,
607.5646 +        1, -533725184, 1611661312, 3, 0,
607.5647 +        (long *)_vq_quantlist__44u7__p3_0,
607.5648 +        0
607.5649 +};
607.5650 +
607.5651 +static const long _vq_quantlist__44u7__p4_0[] = {
607.5652 +        2,
607.5653 +        1,
607.5654 +        3,
607.5655 +        0,
607.5656 +        4,
607.5657 +};
607.5658 +
607.5659 +static const long _vq_lengthlist__44u7__p4_0[] = {
607.5660 +         4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8,
607.5661 +         9, 9,11,11, 8, 9, 9,10,11, 6, 7, 7, 9, 9, 7, 8,
607.5662 +         8,10,10, 6, 7, 8, 9,10, 9,10,10,12,12, 9, 9,10,
607.5663 +        11,12, 6, 7, 7, 9, 9, 6, 8, 7,10, 9, 7, 8, 8,10,
607.5664 +        10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,11,11,
607.5665 +         9,10,10,12,12, 9,10,10,12,12,11,12,12,13,14,11,
607.5666 +        11,12,13,13, 8, 9, 9,11,11, 9,10,10,12,11, 9,10,
607.5667 +        10,12,12,11,12,11,13,13,11,12,12,13,13, 6, 7, 7,
607.5668 +         9, 9, 7, 8, 7,10,10, 7, 7, 8,10,10, 9,10,10,12,
607.5669 +        11, 9,10,10,12,12, 7, 8, 8,10,10, 8, 8, 9,11,11,
607.5670 +         8, 9, 9,11,11,10,11,11,12,12,10,10,11,12,13, 6,
607.5671 +         7, 7,10,10, 7, 9, 8,11,10, 8, 8, 9,10,11,10,11,
607.5672 +        10,13,11,10,11,11,12,12, 9,10,10,12,12,10,10,11,
607.5673 +        13,13,10,11,11,13,12,12,12,13,13,14,12,12,13,14,
607.5674 +        14, 9,10,10,12,12, 9,10,10,12,12,10,11,11,13,13,
607.5675 +        11,12,11,14,12,12,13,13,14,14, 6, 7, 7, 9, 9, 7,
607.5676 +         8, 7,10,10, 7, 7, 8,10,10, 9,10,10,12,11, 9,10,
607.5677 +        10,11,12, 6, 7, 7,10,10, 8, 9, 8,11,10, 7, 8, 9,
607.5678 +        10,11,10,11,11,13,12,10,10,11,11,13, 7, 8, 8,10,
607.5679 +        10, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,10,13,12,
607.5680 +        10,11,11,12,12, 9,10,10,12,12,10,11,11,13,12, 9,
607.5681 +        10,10,12,13,12,13,12,14,14,11,11,12,12,14, 9,10,
607.5682 +        10,12,12,10,11,11,13,13,10,11,11,13,13,12,13,12,
607.5683 +        14,14,12,13,12,14,13, 8, 9, 9,11,11, 9,10,10,12,
607.5684 +        12, 9,10,10,12,12,11,12,12,14,13,11,12,12,13,13,
607.5685 +         9,10,10,12,12,10,11,11,13,13,10,11,11,13,12,12,
607.5686 +        13,13,14,14,12,12,13,14,14, 9,10,10,12,12, 9,11,
607.5687 +        10,13,12,10,10,11,12,13,11,13,12,14,13,12,12,13,
607.5688 +        14,14,11,12,12,13,13,11,12,13,14,14,12,13,13,14,
607.5689 +        14,13,13,14,14,16,13,14,14,16,16,11,11,11,13,13,
607.5690 +        11,12,11,14,13,12,12,13,14,15,13,14,12,16,13,14,
607.5691 +        14,14,15,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
607.5692 +        10,12,12,11,12,12,14,13,11,12,12,13,14, 9,10,10,
607.5693 +        12,12,10,11,10,13,12, 9,10,11,12,13,12,13,12,14,
607.5694 +        14,12,12,13,13,14, 9,10,10,12,12,10,11,11,12,13,
607.5695 +        10,11,11,13,13,12,13,12,14,14,12,13,13,14,14,11,
607.5696 +        12,12,13,13,12,13,12,14,14,11,11,12,13,14,13,15,
607.5697 +        14,16,15,13,12,14,13,16,11,12,12,13,13,12,13,13,
607.5698 +        14,14,12,12,12,14,14,13,14,14,15,15,13,14,13,16,
607.5699 +        14,
607.5700 +};
607.5701 +
607.5702 +static const static_codebook _44u7__p4_0 = {
607.5703 +        4, 625,
607.5704 +        (long *)_vq_lengthlist__44u7__p4_0,
607.5705 +        1, -533725184, 1611661312, 3, 0,
607.5706 +        (long *)_vq_quantlist__44u7__p4_0,
607.5707 +        0
607.5708 +};
607.5709 +
607.5710 +static const long _vq_quantlist__44u7__p5_0[] = {
607.5711 +        4,
607.5712 +        3,
607.5713 +        5,
607.5714 +        2,
607.5715 +        6,
607.5716 +        1,
607.5717 +        7,
607.5718 +        0,
607.5719 +        8,
607.5720 +};
607.5721 +
607.5722 +static const long _vq_lengthlist__44u7__p5_0[] = {
607.5723 +         2, 3, 3, 6, 6, 7, 8,10,10, 4, 5, 5, 8, 7, 8, 8,
607.5724 +        11,11, 3, 5, 5, 7, 7, 8, 9,11,11, 6, 8, 7, 9, 9,
607.5725 +        10,10,12,12, 6, 7, 8, 9,10,10,10,12,12, 8, 8, 8,
607.5726 +        10,10,12,11,13,13, 8, 8, 9,10,10,11,11,13,13,10,
607.5727 +        11,11,12,12,13,13,14,14,10,11,11,12,12,13,13,14,
607.5728 +        14,
607.5729 +};
607.5730 +
607.5731 +static const static_codebook _44u7__p5_0 = {
607.5732 +        2, 81,
607.5733 +        (long *)_vq_lengthlist__44u7__p5_0,
607.5734 +        1, -531628032, 1611661312, 4, 0,
607.5735 +        (long *)_vq_quantlist__44u7__p5_0,
607.5736 +        0
607.5737 +};
607.5738 +
607.5739 +static const long _vq_quantlist__44u7__p6_0[] = {
607.5740 +        4,
607.5741 +        3,
607.5742 +        5,
607.5743 +        2,
607.5744 +        6,
607.5745 +        1,
607.5746 +        7,
607.5747 +        0,
607.5748 +        8,
607.5749 +};
607.5750 +
607.5751 +static const long _vq_lengthlist__44u7__p6_0[] = {
607.5752 +         3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 8, 7,
607.5753 +         9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7,
607.5754 +         8, 8,10,10, 5, 6, 6, 7, 7, 8, 8,10,10, 7, 8, 7,
607.5755 +         8, 8,10, 9,11,11, 7, 7, 8, 8, 8, 9,10,11,11, 9,
607.5756 +         9, 9,10,10,11,10,12,11, 9, 9, 9,10,10,11,11,11,
607.5757 +        12,
607.5758 +};
607.5759 +
607.5760 +static const static_codebook _44u7__p6_0 = {
607.5761 +        2, 81,
607.5762 +        (long *)_vq_lengthlist__44u7__p6_0,
607.5763 +        1, -531628032, 1611661312, 4, 0,
607.5764 +        (long *)_vq_quantlist__44u7__p6_0,
607.5765 +        0
607.5766 +};
607.5767 +
607.5768 +static const long _vq_quantlist__44u7__p7_0[] = {
607.5769 +        1,
607.5770 +        0,
607.5771 +        2,
607.5772 +};
607.5773 +
607.5774 +static const long _vq_lengthlist__44u7__p7_0[] = {
607.5775 +         1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 8, 9, 9, 7,
607.5776 +        10,10, 5, 8, 9, 7, 9,10, 8, 9, 9, 4, 9, 9, 9,11,
607.5777 +        10, 8,10,10, 7,11,10,10,10,12,10,12,12, 7,10,10,
607.5778 +        10,12,11,10,12,12, 5, 9, 9, 8,10,10, 9,11,11, 7,
607.5779 +        11,10,10,12,12,10,11,12, 7,10,11,10,12,12,10,12,
607.5780 +        10,
607.5781 +};
607.5782 +
607.5783 +static const static_codebook _44u7__p7_0 = {
607.5784 +        4, 81,
607.5785 +        (long *)_vq_lengthlist__44u7__p7_0,
607.5786 +        1, -529137664, 1618345984, 2, 0,
607.5787 +        (long *)_vq_quantlist__44u7__p7_0,
607.5788 +        0
607.5789 +};
607.5790 +
607.5791 +static const long _vq_quantlist__44u7__p7_1[] = {
607.5792 +        5,
607.5793 +        4,
607.5794 +        6,
607.5795 +        3,
607.5796 +        7,
607.5797 +        2,
607.5798 +        8,
607.5799 +        1,
607.5800 +        9,
607.5801 +        0,
607.5802 +        10,
607.5803 +};
607.5804 +
607.5805 +static const long _vq_lengthlist__44u7__p7_1[] = {
607.5806 +         3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 6, 6,
607.5807 +         8, 7, 8, 8, 8, 8, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
607.5808 +         8, 6, 7, 6, 7, 7, 8, 8, 9, 9, 9, 9, 6, 6, 7, 7,
607.5809 +         7, 8, 8, 9, 9, 9, 9, 7, 8, 7, 8, 8, 9, 9, 9, 9,
607.5810 +         9, 9, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8,
607.5811 +         9, 9, 9, 9,10, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9,
607.5812 +         9, 9,10, 8, 8, 8, 9, 9, 9, 9,10, 9,10,10, 8, 8,
607.5813 +         8, 9, 9, 9, 9, 9,10,10,10,
607.5814 +};
607.5815 +
607.5816 +static const static_codebook _44u7__p7_1 = {
607.5817 +        2, 121,
607.5818 +        (long *)_vq_lengthlist__44u7__p7_1,
607.5819 +        1, -531365888, 1611661312, 4, 0,
607.5820 +        (long *)_vq_quantlist__44u7__p7_1,
607.5821 +        0
607.5822 +};
607.5823 +
607.5824 +static const long _vq_quantlist__44u7__p8_0[] = {
607.5825 +        5,
607.5826 +        4,
607.5827 +        6,
607.5828 +        3,
607.5829 +        7,
607.5830 +        2,
607.5831 +        8,
607.5832 +        1,
607.5833 +        9,
607.5834 +        0,
607.5835 +        10,
607.5836 +};
607.5837 +
607.5838 +static const long _vq_lengthlist__44u7__p8_0[] = {
607.5839 +         1, 4, 4, 6, 6, 8, 8,10,10,11,11, 4, 6, 6, 7, 7,
607.5840 +         9, 9,11,10,12,12, 5, 6, 5, 7, 7, 9, 9,10,11,12,
607.5841 +        12, 6, 7, 7, 8, 8,10,10,11,11,13,13, 6, 7, 7, 8,
607.5842 +         8,10,10,11,12,13,13, 8, 9, 9,10,10,11,11,12,12,
607.5843 +        14,14, 8, 9, 9,10,10,11,11,12,12,14,14,10,10,10,
607.5844 +        11,11,13,12,14,14,15,15,10,10,10,12,12,13,13,14,
607.5845 +        14,15,15,11,12,12,13,13,14,14,15,14,16,15,11,12,
607.5846 +        12,13,13,14,14,15,15,15,16,
607.5847 +};
607.5848 +
607.5849 +static const static_codebook _44u7__p8_0 = {
607.5850 +        2, 121,
607.5851 +        (long *)_vq_lengthlist__44u7__p8_0,
607.5852 +        1, -524582912, 1618345984, 4, 0,
607.5853 +        (long *)_vq_quantlist__44u7__p8_0,
607.5854 +        0
607.5855 +};
607.5856 +
607.5857 +static const long _vq_quantlist__44u7__p8_1[] = {
607.5858 +        5,
607.5859 +        4,
607.5860 +        6,
607.5861 +        3,
607.5862 +        7,
607.5863 +        2,
607.5864 +        8,
607.5865 +        1,
607.5866 +        9,
607.5867 +        0,
607.5868 +        10,
607.5869 +};
607.5870 +
607.5871 +static const long _vq_lengthlist__44u7__p8_1[] = {
607.5872 +         4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7,
607.5873 +         7, 7, 7, 7, 7, 7, 5, 6, 6, 6, 7, 7, 7, 7, 7, 7,
607.5874 +         7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 6, 7, 7, 7,
607.5875 +         7, 7, 7, 7, 7, 8, 8, 7, 7, 7, 7, 7, 8, 7, 8, 8,
607.5876 +         8, 8, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7,
607.5877 +         7, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8,
607.5878 +         8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7,
607.5879 +         7, 8, 8, 8, 8, 8, 8, 8, 8,
607.5880 +};
607.5881 +
607.5882 +static const static_codebook _44u7__p8_1 = {
607.5883 +        2, 121,
607.5884 +        (long *)_vq_lengthlist__44u7__p8_1,
607.5885 +        1, -531365888, 1611661312, 4, 0,
607.5886 +        (long *)_vq_quantlist__44u7__p8_1,
607.5887 +        0
607.5888 +};
607.5889 +
607.5890 +static const long _vq_quantlist__44u7__p9_0[] = {
607.5891 +        5,
607.5892 +        4,
607.5893 +        6,
607.5894 +        3,
607.5895 +        7,
607.5896 +        2,
607.5897 +        8,
607.5898 +        1,
607.5899 +        9,
607.5900 +        0,
607.5901 +        10,
607.5902 +};
607.5903 +
607.5904 +static const long _vq_lengthlist__44u7__p9_0[] = {
607.5905 +         1, 3, 3,10,10,10,10,10,10,10,10, 4,10,10,10,10,
607.5906 +        10,10,10,10,10,10, 4,10,10,10,10,10,10,10,10,10,
607.5907 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.5908 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.5909 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.5910 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.5911 +        10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
607.5912 +         9, 9, 9, 9, 9, 9, 9, 9, 9,
607.5913 +};
607.5914 +
607.5915 +static const static_codebook _44u7__p9_0 = {
607.5916 +        2, 121,
607.5917 +        (long *)_vq_lengthlist__44u7__p9_0,
607.5918 +        1, -512171520, 1630791680, 4, 0,
607.5919 +        (long *)_vq_quantlist__44u7__p9_0,
607.5920 +        0
607.5921 +};
607.5922 +
607.5923 +static const long _vq_quantlist__44u7__p9_1[] = {
607.5924 +        6,
607.5925 +        5,
607.5926 +        7,
607.5927 +        4,
607.5928 +        8,
607.5929 +        3,
607.5930 +        9,
607.5931 +        2,
607.5932 +        10,
607.5933 +        1,
607.5934 +        11,
607.5935 +        0,
607.5936 +        12,
607.5937 +};
607.5938 +
607.5939 +static const long _vq_lengthlist__44u7__p9_1[] = {
607.5940 +         1, 4, 4, 6, 5, 8, 6, 9, 8,10, 9,11,10, 4, 6, 6,
607.5941 +         8, 8, 9, 9,11,10,11,11,11,11, 4, 6, 6, 8, 8,10,
607.5942 +         9,11,11,11,11,11,12, 6, 8, 8,10,10,11,11,12,12,
607.5943 +        13,12,13,13, 6, 8, 8,10,10,11,11,12,12,12,13,14,
607.5944 +        13, 8,10,10,11,11,12,13,14,14,14,14,15,15, 8,10,
607.5945 +        10,11,12,12,13,13,14,14,14,14,15, 9,11,11,13,13,
607.5946 +        14,14,15,14,16,15,17,15, 9,11,11,12,13,14,14,15,
607.5947 +        14,15,15,15,16,10,12,12,13,14,15,15,15,15,16,17,
607.5948 +        16,17,10,13,12,13,14,14,16,16,16,16,15,16,17,11,
607.5949 +        13,13,14,15,14,17,15,16,17,17,17,17,11,13,13,14,
607.5950 +        15,15,15,15,17,17,16,17,16,
607.5951 +};
607.5952 +
607.5953 +static const static_codebook _44u7__p9_1 = {
607.5954 +        2, 169,
607.5955 +        (long *)_vq_lengthlist__44u7__p9_1,
607.5956 +        1, -518889472, 1622704128, 4, 0,
607.5957 +        (long *)_vq_quantlist__44u7__p9_1,
607.5958 +        0
607.5959 +};
607.5960 +
607.5961 +static const long _vq_quantlist__44u7__p9_2[] = {
607.5962 +        24,
607.5963 +        23,
607.5964 +        25,
607.5965 +        22,
607.5966 +        26,
607.5967 +        21,
607.5968 +        27,
607.5969 +        20,
607.5970 +        28,
607.5971 +        19,
607.5972 +        29,
607.5973 +        18,
607.5974 +        30,
607.5975 +        17,
607.5976 +        31,
607.5977 +        16,
607.5978 +        32,
607.5979 +        15,
607.5980 +        33,
607.5981 +        14,
607.5982 +        34,
607.5983 +        13,
607.5984 +        35,
607.5985 +        12,
607.5986 +        36,
607.5987 +        11,
607.5988 +        37,
607.5989 +        10,
607.5990 +        38,
607.5991 +        9,
607.5992 +        39,
607.5993 +        8,
607.5994 +        40,
607.5995 +        7,
607.5996 +        41,
607.5997 +        6,
607.5998 +        42,
607.5999 +        5,
607.6000 +        43,
607.6001 +        4,
607.6002 +        44,
607.6003 +        3,
607.6004 +        45,
607.6005 +        2,
607.6006 +        46,
607.6007 +        1,
607.6008 +        47,
607.6009 +        0,
607.6010 +        48,
607.6011 +};
607.6012 +
607.6013 +static const long _vq_lengthlist__44u7__p9_2[] = {
607.6014 +         2, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6,
607.6015 +         6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.6016 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
607.6017 +         8,
607.6018 +};
607.6019 +
607.6020 +static const static_codebook _44u7__p9_2 = {
607.6021 +        1, 49,
607.6022 +        (long *)_vq_lengthlist__44u7__p9_2,
607.6023 +        1, -526909440, 1611661312, 6, 0,
607.6024 +        (long *)_vq_quantlist__44u7__p9_2,
607.6025 +        0
607.6026 +};
607.6027 +
607.6028 +static const long _huff_lengthlist__44u7__short[] = {
607.6029 +         5,12,17,16,16,17,17,17,17,17, 4, 7,11,11,12, 9,
607.6030 +        17,10,17,17, 7, 7, 8, 9, 7, 9,11,10,15,17, 7, 9,
607.6031 +        10,11,10,12,14,12,16,17, 7, 8, 5, 7, 4, 7, 7, 8,
607.6032 +        16,16, 6,10, 9,10, 7,10,11,11,16,17, 6, 8, 8, 9,
607.6033 +         5, 7, 5, 8,16,17, 5, 5, 8, 7, 6, 7, 7, 6, 6,14,
607.6034 +        12,10,12,11, 7,11, 4, 4, 2, 7,17,15,15,15, 8,15,
607.6035 +         6, 8, 5, 9,
607.6036 +};
607.6037 +
607.6038 +static const static_codebook _huff_book__44u7__short = {
607.6039 +        2, 100,
607.6040 +        (long *)_huff_lengthlist__44u7__short,
607.6041 +        0, 0, 0, 0, 0,
607.6042 +        NULL,
607.6043 +        0
607.6044 +};
607.6045 +
607.6046 +static const long _huff_lengthlist__44u8__long[] = {
607.6047 +         3, 9,13,14,14,15,14,14,15,15, 5, 4, 6, 8,10,12,
607.6048 +        12,14,15,15, 9, 5, 4, 5, 8,10,11,13,16,16,10, 7,
607.6049 +         4, 3, 5, 7, 9,11,13,13,10, 9, 7, 4, 4, 6, 8,10,
607.6050 +        12,14,13,11, 9, 6, 5, 5, 6, 8,12,14,13,11,10, 8,
607.6051 +         7, 6, 6, 7,10,14,13,11,12,10, 8, 7, 6, 6, 9,13,
607.6052 +        12,11,14,12,11, 9, 8, 7, 9,11,11,12,14,13,14,11,
607.6053 +        10, 8, 8, 9,
607.6054 +};
607.6055 +
607.6056 +static const static_codebook _huff_book__44u8__long = {
607.6057 +        2, 100,
607.6058 +        (long *)_huff_lengthlist__44u8__long,
607.6059 +        0, 0, 0, 0, 0,
607.6060 +        NULL,
607.6061 +        0
607.6062 +};
607.6063 +
607.6064 +static const long _huff_lengthlist__44u8__short[] = {
607.6065 +         6,14,18,18,17,17,17,17,17,17, 4, 7, 9, 9,10,13,
607.6066 +        15,17,17,17, 6, 7, 5, 6, 8,11,16,17,16,17, 5, 7,
607.6067 +         5, 4, 6,10,14,17,17,17, 6, 6, 6, 5, 7,10,13,16,
607.6068 +        17,17, 7, 6, 7, 7, 7, 8, 7,10,15,16,12, 9, 9, 6,
607.6069 +         6, 5, 3, 5,11,15,14,14,13, 5, 5, 7, 3, 4, 8,15,
607.6070 +        17,17,13, 7, 7,10, 6, 6,10,15,17,17,16,10,11,14,
607.6071 +        10,10,15,17,
607.6072 +};
607.6073 +
607.6074 +static const static_codebook _huff_book__44u8__short = {
607.6075 +        2, 100,
607.6076 +        (long *)_huff_lengthlist__44u8__short,
607.6077 +        0, 0, 0, 0, 0,
607.6078 +        NULL,
607.6079 +        0
607.6080 +};
607.6081 +
607.6082 +static const long _vq_quantlist__44u8_p1_0[] = {
607.6083 +        1,
607.6084 +        0,
607.6085 +        2,
607.6086 +};
607.6087 +
607.6088 +static const long _vq_lengthlist__44u8_p1_0[] = {
607.6089 +         1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 8, 9, 9, 7,
607.6090 +         9, 9, 5, 7, 7, 7, 9, 9, 8, 9, 9, 5, 7, 7, 7, 9,
607.6091 +         9, 7, 9, 9, 7, 9, 9, 9,10,11, 9,11,10, 7, 9, 9,
607.6092 +         9,11,10, 9,10,11, 5, 7, 7, 7, 9, 9, 7, 9, 9, 7,
607.6093 +         9, 9, 9,11,10, 9,10,10, 8, 9, 9, 9,11,11, 9,11,
607.6094 +        10,
607.6095 +};
607.6096 +
607.6097 +static const static_codebook _44u8_p1_0 = {
607.6098 +        4, 81,
607.6099 +        (long *)_vq_lengthlist__44u8_p1_0,
607.6100 +        1, -535822336, 1611661312, 2, 0,
607.6101 +        (long *)_vq_quantlist__44u8_p1_0,
607.6102 +        0
607.6103 +};
607.6104 +
607.6105 +static const long _vq_quantlist__44u8_p2_0[] = {
607.6106 +        2,
607.6107 +        1,
607.6108 +        3,
607.6109 +        0,
607.6110 +        4,
607.6111 +};
607.6112 +
607.6113 +static const long _vq_lengthlist__44u8_p2_0[] = {
607.6114 +         4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8,
607.6115 +         9, 9,11,11, 8, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8,
607.6116 +         8,10,10, 7, 8, 8,10,10, 9,10,10,12,12, 9,10,10,
607.6117 +        11,12, 5, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 8,10,
607.6118 +        10, 9,10, 9,12,11, 9,10,10,12,12, 8, 9, 9,12,11,
607.6119 +         9,10,10,12,12, 9,10,10,12,12,11,12,12,14,14,11,
607.6120 +        11,12,13,14, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
607.6121 +        10,12,12,11,12,11,13,13,11,12,12,14,14, 5, 7, 7,
607.6122 +         9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,
607.6123 +        12, 9,10,10,11,12, 7, 8, 8,10,10, 8, 9, 9,11,11,
607.6124 +         8, 9, 9,11,11,10,11,11,12,13,10,11,11,12,13, 6,
607.6125 +         8, 8,10,10, 8, 9, 8,11,10, 8, 9, 9,11,11,10,11,
607.6126 +        10,13,12,10,11,11,13,13, 9,10,10,12,12,10,11,11,
607.6127 +        13,13,10,11,11,13,13,12,12,13,13,14,12,13,13,14,
607.6128 +        14, 9,10,10,12,12,10,11,10,13,12,10,11,11,13,13,
607.6129 +        11,13,12,14,13,12,13,13,14,14, 5, 7, 7, 9, 9, 7,
607.6130 +         8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12, 9,10,
607.6131 +        10,12,12, 7, 8, 8,10,10, 8, 9, 9,11,11, 8, 8, 9,
607.6132 +        10,11,10,11,11,13,13,10,10,11,12,13, 7, 8, 8,10,
607.6133 +        10, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,11,13,13,
607.6134 +        10,11,11,13,12, 9,10,10,12,12,10,11,11,13,13,10,
607.6135 +        10,11,12,13,12,13,13,14,14,12,12,13,13,14, 9,10,
607.6136 +        10,12,12,10,11,11,13,13,10,11,11,13,13,12,13,13,
607.6137 +        15,14,12,13,13,14,13, 8, 9, 9,11,11, 9,10,10,12,
607.6138 +        12, 9,10,10,12,12,12,12,12,14,13,11,12,12,14,14,
607.6139 +         9,10,10,12,12,10,11,11,13,13,10,11,11,13,13,12,
607.6140 +        13,13,14,15,12,13,13,14,15, 9,10,10,12,12,10,11,
607.6141 +        10,13,12,10,11,11,13,13,12,13,12,15,14,12,13,13,
607.6142 +        14,15,11,12,12,14,14,12,13,13,14,14,12,13,13,15,
607.6143 +        14,14,14,14,14,16,14,14,15,16,16,11,12,12,14,14,
607.6144 +        11,12,12,14,14,12,13,13,14,15,13,14,13,16,14,14,
607.6145 +        14,14,16,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
607.6146 +        10,12,12,11,12,12,14,13,11,12,12,14,14, 9,10,10,
607.6147 +        12,12,10,11,11,13,13,10,10,11,12,13,12,13,13,15,
607.6148 +        14,12,12,13,13,14, 9,10,10,12,12,10,11,11,13,13,
607.6149 +        10,11,11,13,13,12,13,13,14,14,12,13,13,15,14,11,
607.6150 +        12,12,14,13,12,13,13,15,14,11,12,12,13,14,14,15,
607.6151 +        14,16,15,13,13,14,13,16,11,12,12,14,14,12,13,13,
607.6152 +        14,15,12,13,12,15,14,14,14,14,16,15,14,15,13,16,
607.6153 +        14,
607.6154 +};
607.6155 +
607.6156 +static const static_codebook _44u8_p2_0 = {
607.6157 +        4, 625,
607.6158 +        (long *)_vq_lengthlist__44u8_p2_0,
607.6159 +        1, -533725184, 1611661312, 3, 0,
607.6160 +        (long *)_vq_quantlist__44u8_p2_0,
607.6161 +        0
607.6162 +};
607.6163 +
607.6164 +static const long _vq_quantlist__44u8_p3_0[] = {
607.6165 +        4,
607.6166 +        3,
607.6167 +        5,
607.6168 +        2,
607.6169 +        6,
607.6170 +        1,
607.6171 +        7,
607.6172 +        0,
607.6173 +        8,
607.6174 +};
607.6175 +
607.6176 +static const long _vq_lengthlist__44u8_p3_0[] = {
607.6177 +         3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7,
607.6178 +         9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7,
607.6179 +         8, 8,10,10, 6, 6, 6, 7, 7, 8, 8,10,10, 7, 7, 7,
607.6180 +         8, 8, 9, 9,11,10, 7, 7, 7, 8, 8, 9, 9,10,11, 9,
607.6181 +         9, 9,10,10,11,10,12,11, 9, 9, 9, 9,10,11,11,11,
607.6182 +        12,
607.6183 +};
607.6184 +
607.6185 +static const static_codebook _44u8_p3_0 = {
607.6186 +        2, 81,
607.6187 +        (long *)_vq_lengthlist__44u8_p3_0,
607.6188 +        1, -531628032, 1611661312, 4, 0,
607.6189 +        (long *)_vq_quantlist__44u8_p3_0,
607.6190 +        0
607.6191 +};
607.6192 +
607.6193 +static const long _vq_quantlist__44u8_p4_0[] = {
607.6194 +        8,
607.6195 +        7,
607.6196 +        9,
607.6197 +        6,
607.6198 +        10,
607.6199 +        5,
607.6200 +        11,
607.6201 +        4,
607.6202 +        12,
607.6203 +        3,
607.6204 +        13,
607.6205 +        2,
607.6206 +        14,
607.6207 +        1,
607.6208 +        15,
607.6209 +        0,
607.6210 +        16,
607.6211 +};
607.6212 +
607.6213 +static const long _vq_lengthlist__44u8_p4_0[] = {
607.6214 +         4, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,11,11,11,
607.6215 +        11, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,
607.6216 +        12,12, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,
607.6217 +        11,12,12, 6, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
607.6218 +        11,11,12,12, 6, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,
607.6219 +        10,11,11,12,12, 7, 7, 7, 8, 8, 9, 8,10, 9,10, 9,
607.6220 +        11,10,12,11,13,12, 7, 7, 7, 8, 8, 8, 9, 9,10, 9,
607.6221 +        10,10,11,11,12,12,13, 8, 8, 8, 9, 9, 9, 9,10,10,
607.6222 +        11,10,11,11,12,12,13,13, 8, 8, 8, 9, 9, 9,10,10,
607.6223 +        10,10,11,11,11,12,12,12,13, 8, 9, 9, 9, 9,10, 9,
607.6224 +        11,10,11,11,12,11,13,12,13,13, 8, 9, 9, 9, 9, 9,
607.6225 +        10,10,11,11,11,11,12,12,13,13,13,10,10,10,10,10,
607.6226 +        11,10,11,11,12,11,13,12,13,13,14,13,10,10,10,10,
607.6227 +        10,10,11,11,11,11,12,12,13,13,13,13,14,11,11,11,
607.6228 +        11,11,12,11,12,12,13,12,13,13,14,13,14,14,11,11,
607.6229 +        11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,11,
607.6230 +        12,12,12,12,13,12,13,12,13,13,14,13,14,14,14,14,
607.6231 +        11,12,12,12,12,12,12,13,13,13,13,13,14,14,14,14,
607.6232 +        14,
607.6233 +};
607.6234 +
607.6235 +static const static_codebook _44u8_p4_0 = {
607.6236 +        2, 289,
607.6237 +        (long *)_vq_lengthlist__44u8_p4_0,
607.6238 +        1, -529530880, 1611661312, 5, 0,
607.6239 +        (long *)_vq_quantlist__44u8_p4_0,
607.6240 +        0
607.6241 +};
607.6242 +
607.6243 +static const long _vq_quantlist__44u8_p5_0[] = {
607.6244 +        1,
607.6245 +        0,
607.6246 +        2,
607.6247 +};
607.6248 +
607.6249 +static const long _vq_lengthlist__44u8_p5_0[] = {
607.6250 +         1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 8, 9, 9, 7,
607.6251 +         9, 9, 5, 8, 8, 7, 9, 9, 8, 9, 9, 5, 8, 8, 8,10,
607.6252 +        10, 8,10,10, 7,10,10, 9,10,12, 9,12,11, 7,10,10,
607.6253 +         9,11,10, 9,11,12, 5, 8, 8, 8,10,10, 8,10,10, 7,
607.6254 +        10,10, 9,11,11, 9,10,11, 7,10,10, 9,11,11,10,12,
607.6255 +        10,
607.6256 +};
607.6257 +
607.6258 +static const static_codebook _44u8_p5_0 = {
607.6259 +        4, 81,
607.6260 +        (long *)_vq_lengthlist__44u8_p5_0,
607.6261 +        1, -529137664, 1618345984, 2, 0,
607.6262 +        (long *)_vq_quantlist__44u8_p5_0,
607.6263 +        0
607.6264 +};
607.6265 +
607.6266 +static const long _vq_quantlist__44u8_p5_1[] = {
607.6267 +        5,
607.6268 +        4,
607.6269 +        6,
607.6270 +        3,
607.6271 +        7,
607.6272 +        2,
607.6273 +        8,
607.6274 +        1,
607.6275 +        9,
607.6276 +        0,
607.6277 +        10,
607.6278 +};
607.6279 +
607.6280 +static const long _vq_lengthlist__44u8_p5_1[] = {
607.6281 +         4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 5, 5, 5, 6, 6,
607.6282 +         7, 7, 8, 8, 8, 8, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8,
607.6283 +         8, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 6, 6, 6, 7,
607.6284 +         7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8,
607.6285 +         8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 7, 8, 7,
607.6286 +         8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8,
607.6287 +         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 8, 8,
607.6288 +         8, 8, 8, 8, 8, 8, 8, 9, 9,
607.6289 +};
607.6290 +
607.6291 +static const static_codebook _44u8_p5_1 = {
607.6292 +        2, 121,
607.6293 +        (long *)_vq_lengthlist__44u8_p5_1,
607.6294 +        1, -531365888, 1611661312, 4, 0,
607.6295 +        (long *)_vq_quantlist__44u8_p5_1,
607.6296 +        0
607.6297 +};
607.6298 +
607.6299 +static const long _vq_quantlist__44u8_p6_0[] = {
607.6300 +        6,
607.6301 +        5,
607.6302 +        7,
607.6303 +        4,
607.6304 +        8,
607.6305 +        3,
607.6306 +        9,
607.6307 +        2,
607.6308 +        10,
607.6309 +        1,
607.6310 +        11,
607.6311 +        0,
607.6312 +        12,
607.6313 +};
607.6314 +
607.6315 +static const long _vq_lengthlist__44u8_p6_0[] = {
607.6316 +         2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 4, 6, 5,
607.6317 +         7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7, 8,
607.6318 +         8, 8, 8, 9, 9,10,10, 6, 7, 7, 7, 8, 8, 8, 8, 9,
607.6319 +         9,10,10,10, 6, 7, 7, 8, 8, 8, 8, 9, 8,10, 9,11,
607.6320 +        10, 7, 8, 8, 8, 8, 8, 9, 9, 9,10,10,11,11, 7, 8,
607.6321 +         8, 8, 8, 9, 8, 9, 9,10,10,11,11, 8, 8, 8, 9, 9,
607.6322 +         9, 9, 9,10,10,10,11,11, 8, 8, 8, 9, 9, 9, 9,10,
607.6323 +         9,10,10,11,11, 9, 9, 9, 9,10,10,10,10,10,10,11,
607.6324 +        11,12, 9, 9, 9,10, 9,10,10,10,10,11,10,12,11,10,
607.6325 +        10,10,10,10,11,11,11,11,11,12,12,12,10,10,10,10,
607.6326 +        11,11,11,11,11,12,11,12,12,
607.6327 +};
607.6328 +
607.6329 +static const static_codebook _44u8_p6_0 = {
607.6330 +        2, 169,
607.6331 +        (long *)_vq_lengthlist__44u8_p6_0,
607.6332 +        1, -526516224, 1616117760, 4, 0,
607.6333 +        (long *)_vq_quantlist__44u8_p6_0,
607.6334 +        0
607.6335 +};
607.6336 +
607.6337 +static const long _vq_quantlist__44u8_p6_1[] = {
607.6338 +        2,
607.6339 +        1,
607.6340 +        3,
607.6341 +        0,
607.6342 +        4,
607.6343 +};
607.6344 +
607.6345 +static const long _vq_lengthlist__44u8_p6_1[] = {
607.6346 +         3, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5,
607.6347 +         5, 5, 5, 5, 5, 5, 5, 5, 5,
607.6348 +};
607.6349 +
607.6350 +static const static_codebook _44u8_p6_1 = {
607.6351 +        2, 25,
607.6352 +        (long *)_vq_lengthlist__44u8_p6_1,
607.6353 +        1, -533725184, 1611661312, 3, 0,
607.6354 +        (long *)_vq_quantlist__44u8_p6_1,
607.6355 +        0
607.6356 +};
607.6357 +
607.6358 +static const long _vq_quantlist__44u8_p7_0[] = {
607.6359 +        6,
607.6360 +        5,
607.6361 +        7,
607.6362 +        4,
607.6363 +        8,
607.6364 +        3,
607.6365 +        9,
607.6366 +        2,
607.6367 +        10,
607.6368 +        1,
607.6369 +        11,
607.6370 +        0,
607.6371 +        12,
607.6372 +};
607.6373 +
607.6374 +static const long _vq_lengthlist__44u8_p7_0[] = {
607.6375 +         1, 4, 5, 6, 6, 7, 7, 8, 8,10,10,11,11, 5, 6, 6,
607.6376 +         7, 7, 8, 8, 9, 9,11,10,12,11, 5, 6, 6, 7, 7, 8,
607.6377 +         8, 9, 9,10,11,11,12, 6, 7, 7, 8, 8, 9, 9,10,10,
607.6378 +        11,11,12,12, 6, 7, 7, 8, 8, 9, 9,10,10,11,12,13,
607.6379 +        12, 7, 8, 8, 9, 9,10,10,11,11,12,12,13,13, 8, 8,
607.6380 +         8, 9, 9,10,10,11,11,12,12,13,13, 9, 9, 9,10,10,
607.6381 +        11,11,12,12,13,13,14,14, 9, 9, 9,10,10,11,11,12,
607.6382 +        12,13,13,14,14,10,11,11,12,11,13,12,13,13,14,14,
607.6383 +        15,15,10,11,11,11,12,12,13,13,14,14,14,15,15,11,
607.6384 +        12,12,13,13,14,13,15,14,15,15,16,15,11,11,12,13,
607.6385 +        13,13,14,14,14,15,15,15,16,
607.6386 +};
607.6387 +
607.6388 +static const static_codebook _44u8_p7_0 = {
607.6389 +        2, 169,
607.6390 +        (long *)_vq_lengthlist__44u8_p7_0,
607.6391 +        1, -523206656, 1618345984, 4, 0,
607.6392 +        (long *)_vq_quantlist__44u8_p7_0,
607.6393 +        0
607.6394 +};
607.6395 +
607.6396 +static const long _vq_quantlist__44u8_p7_1[] = {
607.6397 +        5,
607.6398 +        4,
607.6399 +        6,
607.6400 +        3,
607.6401 +        7,
607.6402 +        2,
607.6403 +        8,
607.6404 +        1,
607.6405 +        9,
607.6406 +        0,
607.6407 +        10,
607.6408 +};
607.6409 +
607.6410 +static const long _vq_lengthlist__44u8_p7_1[] = {
607.6411 +         4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7,
607.6412 +         7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7, 7, 7, 7, 7, 7,
607.6413 +         7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 6, 7, 7, 7,
607.6414 +         7, 7, 7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 8, 8,
607.6415 +         8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 7, 7, 7,
607.6416 +         8, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8,
607.6417 +         8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7,
607.6418 +         7, 8, 8, 8, 8, 8, 8, 8, 8,
607.6419 +};
607.6420 +
607.6421 +static const static_codebook _44u8_p7_1 = {
607.6422 +        2, 121,
607.6423 +        (long *)_vq_lengthlist__44u8_p7_1,
607.6424 +        1, -531365888, 1611661312, 4, 0,
607.6425 +        (long *)_vq_quantlist__44u8_p7_1,
607.6426 +        0
607.6427 +};
607.6428 +
607.6429 +static const long _vq_quantlist__44u8_p8_0[] = {
607.6430 +        7,
607.6431 +        6,
607.6432 +        8,
607.6433 +        5,
607.6434 +        9,
607.6435 +        4,
607.6436 +        10,
607.6437 +        3,
607.6438 +        11,
607.6439 +        2,
607.6440 +        12,
607.6441 +        1,
607.6442 +        13,
607.6443 +        0,
607.6444 +        14,
607.6445 +};
607.6446 +
607.6447 +static const long _vq_lengthlist__44u8_p8_0[] = {
607.6448 +         1, 4, 4, 7, 7, 8, 8, 8, 7, 9, 8,10, 9,11,10, 4,
607.6449 +         6, 6, 8, 8,10, 9, 9, 9,10,10,11,10,12,10, 4, 6,
607.6450 +         6, 8, 8,10,10, 9, 9,10,10,11,11,11,12, 7, 8, 8,
607.6451 +        10,10,11,11,11,10,12,11,12,12,13,11, 7, 8, 8,10,
607.6452 +        10,11,11,10,10,11,11,12,12,13,13, 8,10,10,11,11,
607.6453 +        12,11,12,11,13,12,13,12,14,13, 8,10, 9,11,11,12,
607.6454 +        12,12,12,12,12,13,13,14,13, 8, 9, 9,11,10,12,11,
607.6455 +        13,12,13,13,14,13,14,13, 8, 9, 9,10,11,12,12,12,
607.6456 +        12,13,13,14,15,14,14, 9,10,10,12,11,13,12,13,13,
607.6457 +        14,13,14,14,14,14, 9,10,10,12,12,12,12,13,13,14,
607.6458 +        14,14,15,14,14,10,11,11,13,12,13,12,14,14,14,14,
607.6459 +        14,14,15,15,10,11,11,12,12,13,13,14,14,14,15,15,
607.6460 +        14,16,15,11,12,12,13,12,14,14,14,13,15,14,15,15,
607.6461 +        15,17,11,12,12,13,13,14,14,14,15,15,14,15,15,14,
607.6462 +        17,
607.6463 +};
607.6464 +
607.6465 +static const static_codebook _44u8_p8_0 = {
607.6466 +        2, 225,
607.6467 +        (long *)_vq_lengthlist__44u8_p8_0,
607.6468 +        1, -520986624, 1620377600, 4, 0,
607.6469 +        (long *)_vq_quantlist__44u8_p8_0,
607.6470 +        0
607.6471 +};
607.6472 +
607.6473 +static const long _vq_quantlist__44u8_p8_1[] = {
607.6474 +        10,
607.6475 +        9,
607.6476 +        11,
607.6477 +        8,
607.6478 +        12,
607.6479 +        7,
607.6480 +        13,
607.6481 +        6,
607.6482 +        14,
607.6483 +        5,
607.6484 +        15,
607.6485 +        4,
607.6486 +        16,
607.6487 +        3,
607.6488 +        17,
607.6489 +        2,
607.6490 +        18,
607.6491 +        1,
607.6492 +        19,
607.6493 +        0,
607.6494 +        20,
607.6495 +};
607.6496 +
607.6497 +static const long _vq_lengthlist__44u8_p8_1[] = {
607.6498 +         4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
607.6499 +         9, 9, 9, 9, 9, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
607.6500 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 6, 6, 7, 7, 8,
607.6501 +         8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7,
607.6502 +         7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.6503 +         9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
607.6504 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9,
607.6505 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10, 8, 8,
607.6506 +         8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,
607.6507 +        10, 9,10, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,
607.6508 +        10,10,10,10,10,10,10,10, 8, 9, 8, 9, 9, 9, 9, 9,
607.6509 +         9, 9, 9, 9, 9, 9,10,10,10,10, 9,10,10, 9, 9, 9,
607.6510 +         9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10,10,
607.6511 +        10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,
607.6512 +        10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9,10, 9,
607.6513 +        10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
607.6514 +         9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,
607.6515 +        10, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,
607.6516 +        10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9,10,10,10,
607.6517 +        10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,
607.6518 +         9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.6519 +         9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
607.6520 +        10,10,10,10,10, 9, 9, 9,10, 9,10,10,10,10,10,10,
607.6521 +        10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,
607.6522 +         9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,
607.6523 +         9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
607.6524 +        10,10,10,10, 9, 9, 9,10, 9,10, 9,10,10,10,10,10,
607.6525 +        10,10,10,10,10,10,10,10,10,
607.6526 +};
607.6527 +
607.6528 +static const static_codebook _44u8_p8_1 = {
607.6529 +        2, 441,
607.6530 +        (long *)_vq_lengthlist__44u8_p8_1,
607.6531 +        1, -529268736, 1611661312, 5, 0,
607.6532 +        (long *)_vq_quantlist__44u8_p8_1,
607.6533 +        0
607.6534 +};
607.6535 +
607.6536 +static const long _vq_quantlist__44u8_p9_0[] = {
607.6537 +        4,
607.6538 +        3,
607.6539 +        5,
607.6540 +        2,
607.6541 +        6,
607.6542 +        1,
607.6543 +        7,
607.6544 +        0,
607.6545 +        8,
607.6546 +};
607.6547 +
607.6548 +static const long _vq_lengthlist__44u8_p9_0[] = {
607.6549 +         1, 3, 3, 9, 9, 9, 9, 9, 9, 4, 9, 9, 9, 9, 9, 9,
607.6550 +         9, 9, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.6551 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.6552 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.6553 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8,
607.6554 +         8,
607.6555 +};
607.6556 +
607.6557 +static const static_codebook _44u8_p9_0 = {
607.6558 +        2, 81,
607.6559 +        (long *)_vq_lengthlist__44u8_p9_0,
607.6560 +        1, -511895552, 1631393792, 4, 0,
607.6561 +        (long *)_vq_quantlist__44u8_p9_0,
607.6562 +        0
607.6563 +};
607.6564 +
607.6565 +static const long _vq_quantlist__44u8_p9_1[] = {
607.6566 +        9,
607.6567 +        8,
607.6568 +        10,
607.6569 +        7,
607.6570 +        11,
607.6571 +        6,
607.6572 +        12,
607.6573 +        5,
607.6574 +        13,
607.6575 +        4,
607.6576 +        14,
607.6577 +        3,
607.6578 +        15,
607.6579 +        2,
607.6580 +        16,
607.6581 +        1,
607.6582 +        17,
607.6583 +        0,
607.6584 +        18,
607.6585 +};
607.6586 +
607.6587 +static const long _vq_lengthlist__44u8_p9_1[] = {
607.6588 +         1, 4, 4, 7, 7, 8, 7, 8, 6, 9, 7,10, 8,11,10,11,
607.6589 +        11,11,11, 4, 7, 6, 9, 9,10, 9, 9, 9,10,10,11,10,
607.6590 +        11,10,11,11,13,11, 4, 7, 7, 9, 9, 9, 9, 9, 9,10,
607.6591 +        10,11,10,11,11,11,12,11,12, 7, 9, 8,11,11,11,11,
607.6592 +        10,10,11,11,12,12,12,12,12,12,14,13, 7, 8, 9,10,
607.6593 +        11,11,11,10,10,11,11,11,11,12,12,14,12,13,14, 8,
607.6594 +         9, 9,11,11,11,11,11,11,12,12,14,12,15,14,14,14,
607.6595 +        15,14, 8, 9, 9,11,11,11,11,12,11,12,12,13,13,13,
607.6596 +        13,13,13,14,14, 8, 9, 9,11,10,12,11,12,12,13,13,
607.6597 +        13,13,15,14,14,14,16,16, 8, 9, 9,10,11,11,12,12,
607.6598 +        12,13,13,13,14,14,14,15,16,15,15, 9,10,10,11,12,
607.6599 +        12,13,13,13,14,14,16,14,14,16,16,16,16,15, 9,10,
607.6600 +        10,11,11,12,13,13,14,15,14,16,14,15,16,16,16,16,
607.6601 +        15,10,11,11,12,13,13,14,15,15,15,15,15,16,15,16,
607.6602 +        15,16,15,15,10,11,11,13,13,14,13,13,15,14,15,15,
607.6603 +        16,15,15,15,16,15,16,10,12,12,14,14,14,14,14,16,
607.6604 +        16,15,15,15,16,16,16,16,16,16,11,12,12,14,14,14,
607.6605 +        14,15,15,16,15,16,15,16,15,16,16,16,16,12,12,13,
607.6606 +        14,14,15,16,16,16,16,16,16,15,16,16,16,16,16,16,
607.6607 +        12,13,13,14,14,14,14,15,16,15,16,16,16,16,16,16,
607.6608 +        16,16,16,12,13,14,14,14,16,15,16,15,16,16,16,16,
607.6609 +        16,16,16,16,16,16,12,14,13,14,15,15,15,16,15,16,
607.6610 +        16,15,16,16,16,16,16,16,16,
607.6611 +};
607.6612 +
607.6613 +static const static_codebook _44u8_p9_1 = {
607.6614 +        2, 361,
607.6615 +        (long *)_vq_lengthlist__44u8_p9_1,
607.6616 +        1, -518287360, 1622704128, 5, 0,
607.6617 +        (long *)_vq_quantlist__44u8_p9_1,
607.6618 +        0
607.6619 +};
607.6620 +
607.6621 +static const long _vq_quantlist__44u8_p9_2[] = {
607.6622 +        24,
607.6623 +        23,
607.6624 +        25,
607.6625 +        22,
607.6626 +        26,
607.6627 +        21,
607.6628 +        27,
607.6629 +        20,
607.6630 +        28,
607.6631 +        19,
607.6632 +        29,
607.6633 +        18,
607.6634 +        30,
607.6635 +        17,
607.6636 +        31,
607.6637 +        16,
607.6638 +        32,
607.6639 +        15,
607.6640 +        33,
607.6641 +        14,
607.6642 +        34,
607.6643 +        13,
607.6644 +        35,
607.6645 +        12,
607.6646 +        36,
607.6647 +        11,
607.6648 +        37,
607.6649 +        10,
607.6650 +        38,
607.6651 +        9,
607.6652 +        39,
607.6653 +        8,
607.6654 +        40,
607.6655 +        7,
607.6656 +        41,
607.6657 +        6,
607.6658 +        42,
607.6659 +        5,
607.6660 +        43,
607.6661 +        4,
607.6662 +        44,
607.6663 +        3,
607.6664 +        45,
607.6665 +        2,
607.6666 +        46,
607.6667 +        1,
607.6668 +        47,
607.6669 +        0,
607.6670 +        48,
607.6671 +};
607.6672 +
607.6673 +static const long _vq_lengthlist__44u8_p9_2[] = {
607.6674 +         2, 3, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6,
607.6675 +         6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.6676 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.6677 +         7,
607.6678 +};
607.6679 +
607.6680 +static const static_codebook _44u8_p9_2 = {
607.6681 +        1, 49,
607.6682 +        (long *)_vq_lengthlist__44u8_p9_2,
607.6683 +        1, -526909440, 1611661312, 6, 0,
607.6684 +        (long *)_vq_quantlist__44u8_p9_2,
607.6685 +        0
607.6686 +};
607.6687 +
607.6688 +static const long _huff_lengthlist__44u9__long[] = {
607.6689 +         3, 9,13,13,14,15,14,14,15,15, 5, 5, 9,10,12,12,
607.6690 +        13,14,16,15,10, 6, 6, 6, 8,11,12,13,16,15,11, 7,
607.6691 +         5, 3, 5, 8,10,12,15,15,10,10, 7, 4, 3, 5, 8,10,
607.6692 +        12,12,12,12, 9, 7, 5, 4, 6, 8,10,13,13,12,11, 9,
607.6693 +         7, 5, 5, 6, 9,12,14,12,12,10, 8, 6, 6, 6, 7,11,
607.6694 +        13,12,14,13,10, 8, 7, 7, 7,10,11,11,12,13,12,11,
607.6695 +        10, 8, 8, 9,
607.6696 +};
607.6697 +
607.6698 +static const static_codebook _huff_book__44u9__long = {
607.6699 +        2, 100,
607.6700 +        (long *)_huff_lengthlist__44u9__long,
607.6701 +        0, 0, 0, 0, 0,
607.6702 +        NULL,
607.6703 +        0
607.6704 +};
607.6705 +
607.6706 +static const long _huff_lengthlist__44u9__short[] = {
607.6707 +         9,16,18,18,17,17,17,17,17,17, 5, 8,11,12,11,12,
607.6708 +        17,17,16,16, 6, 6, 8, 8, 9,10,14,15,16,16, 6, 7,
607.6709 +         7, 4, 6, 9,13,16,16,16, 6, 6, 7, 4, 5, 8,11,15,
607.6710 +        17,16, 7, 6, 7, 6, 6, 8, 9,10,14,16,11, 8, 8, 7,
607.6711 +         6, 6, 3, 4,10,15,14,12,12,10, 5, 6, 3, 3, 8,13,
607.6712 +        15,17,15,11, 6, 8, 6, 6, 9,14,17,15,15,12, 8,10,
607.6713 +         9, 9,12,15,
607.6714 +};
607.6715 +
607.6716 +static const static_codebook _huff_book__44u9__short = {
607.6717 +        2, 100,
607.6718 +        (long *)_huff_lengthlist__44u9__short,
607.6719 +        0, 0, 0, 0, 0,
607.6720 +        NULL,
607.6721 +        0
607.6722 +};
607.6723 +
607.6724 +static const long _vq_quantlist__44u9_p1_0[] = {
607.6725 +        1,
607.6726 +        0,
607.6727 +        2,
607.6728 +};
607.6729 +
607.6730 +static const long _vq_lengthlist__44u9_p1_0[] = {
607.6731 +         1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 9, 9, 7,
607.6732 +         9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 9, 5, 7, 7, 7, 9,
607.6733 +         9, 7, 9, 9, 8, 9, 9, 9,10,11, 9,11,11, 7, 9, 9,
607.6734 +         9,11,10, 9,11,11, 5, 7, 7, 7, 9, 9, 8, 9,10, 7,
607.6735 +         9, 9, 9,11,11, 9,10,11, 7, 9,10, 9,11,11, 9,11,
607.6736 +        10,
607.6737 +};
607.6738 +
607.6739 +static const static_codebook _44u9_p1_0 = {
607.6740 +        4, 81,
607.6741 +        (long *)_vq_lengthlist__44u9_p1_0,
607.6742 +        1, -535822336, 1611661312, 2, 0,
607.6743 +        (long *)_vq_quantlist__44u9_p1_0,
607.6744 +        0
607.6745 +};
607.6746 +
607.6747 +static const long _vq_quantlist__44u9_p2_0[] = {
607.6748 +        2,
607.6749 +        1,
607.6750 +        3,
607.6751 +        0,
607.6752 +        4,
607.6753 +};
607.6754 +
607.6755 +static const long _vq_lengthlist__44u9_p2_0[] = {
607.6756 +         3, 5, 5, 8, 8, 5, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8,
607.6757 +         9, 9,11,10, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8,
607.6758 +         8,10,10, 7, 8, 8, 9,10, 9,10,10,11,11, 9, 9,10,
607.6759 +        11,11, 6, 7, 7, 9, 9, 7, 8, 8,10, 9, 7, 8, 8,10,
607.6760 +        10, 9,10, 9,11,11, 9,10,10,11,11, 8, 9, 9,11,11,
607.6761 +         9,10,10,12,11, 9,10,10,11,12,11,11,11,13,13,11,
607.6762 +        11,11,12,13, 8, 9, 9,11,11, 9,10,10,11,11, 9,10,
607.6763 +        10,12,11,11,12,11,13,12,11,11,12,13,13, 6, 7, 7,
607.6764 +         9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,
607.6765 +        11, 9,10,10,11,12, 7, 8, 8,10,10, 8, 9, 9,11,11,
607.6766 +         8, 9, 9,10,10,10,11,11,12,12,10,10,11,12,12, 7,
607.6767 +         8, 8,10,10, 8, 9, 8,10,10, 8, 9, 9,10,10,10,11,
607.6768 +        10,12,11,10,10,11,12,12, 9,10,10,11,12,10,11,11,
607.6769 +        12,12,10,11,10,12,12,12,12,12,13,13,11,12,12,13,
607.6770 +        13, 9,10,10,11,11, 9,10,10,12,12,10,11,11,12,13,
607.6771 +        11,12,11,13,12,12,12,12,13,14, 6, 7, 7, 9, 9, 7,
607.6772 +         8, 8,10,10, 7, 8, 8,10,10, 9,10,10,11,11, 9,10,
607.6773 +        10,11,12, 7, 8, 8,10,10, 8, 9, 9,11,10, 8, 8, 9,
607.6774 +        10,10,10,11,10,12,12,10,10,11,11,12, 7, 8, 8,10,
607.6775 +        10, 8, 9, 9,10,10, 8, 9, 9,10,10,10,11,10,12,12,
607.6776 +        10,11,10,12,12, 9,10,10,12,11,10,11,11,12,12, 9,
607.6777 +        10,10,12,12,12,12,12,13,13,11,11,12,12,14, 9,10,
607.6778 +        10,11,12,10,11,11,12,12,10,11,11,12,12,11,12,12,
607.6779 +        14,14,12,12,12,13,13, 8, 9, 9,11,11, 9,10,10,12,
607.6780 +        11, 9,10,10,12,12,11,12,11,13,13,11,11,12,13,13,
607.6781 +         9,10,10,12,12,10,11,11,12,12,10,11,11,12,12,12,
607.6782 +        12,12,14,14,12,12,12,13,13, 9,10,10,12,11,10,11,
607.6783 +        10,12,12,10,11,11,12,12,11,12,12,14,13,12,12,12,
607.6784 +        13,14,11,12,11,13,13,11,12,12,13,13,12,12,12,14,
607.6785 +        14,13,13,13,13,15,13,13,14,15,15,11,11,11,13,13,
607.6786 +        11,12,11,13,13,11,12,12,13,13,12,13,12,15,13,13,
607.6787 +        13,14,14,15, 8, 9, 9,11,11, 9,10,10,11,12, 9,10,
607.6788 +        10,11,12,11,12,11,13,13,11,12,12,13,13, 9,10,10,
607.6789 +        11,12,10,11,10,12,12,10,10,11,12,13,12,12,12,14,
607.6790 +        13,11,12,12,13,14, 9,10,10,12,12,10,11,11,12,12,
607.6791 +        10,11,11,12,12,12,12,12,14,13,12,12,12,14,13,11,
607.6792 +        11,11,13,13,11,12,12,14,13,11,11,12,13,13,13,13,
607.6793 +        13,15,14,12,12,13,13,15,11,12,12,13,13,12,12,12,
607.6794 +        13,14,11,12,12,13,13,13,13,14,14,15,13,13,13,14,
607.6795 +        14,
607.6796 +};
607.6797 +
607.6798 +static const static_codebook _44u9_p2_0 = {
607.6799 +        4, 625,
607.6800 +        (long *)_vq_lengthlist__44u9_p2_0,
607.6801 +        1, -533725184, 1611661312, 3, 0,
607.6802 +        (long *)_vq_quantlist__44u9_p2_0,
607.6803 +        0
607.6804 +};
607.6805 +
607.6806 +static const long _vq_quantlist__44u9_p3_0[] = {
607.6807 +        4,
607.6808 +        3,
607.6809 +        5,
607.6810 +        2,
607.6811 +        6,
607.6812 +        1,
607.6813 +        7,
607.6814 +        0,
607.6815 +        8,
607.6816 +};
607.6817 +
607.6818 +static const long _vq_lengthlist__44u9_p3_0[] = {
607.6819 +         3, 4, 4, 5, 5, 7, 7, 8, 8, 4, 5, 5, 6, 6, 7, 7,
607.6820 +         9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7,
607.6821 +         8, 8, 9, 9, 5, 6, 6, 7, 7, 8, 8, 9, 9, 7, 7, 7,
607.6822 +         8, 8, 9, 9,10,10, 7, 7, 7, 8, 8, 9, 9,10,10, 8,
607.6823 +         9, 9,10, 9,10,10,11,11, 8, 9, 9, 9,10,10,10,11,
607.6824 +        11,
607.6825 +};
607.6826 +
607.6827 +static const static_codebook _44u9_p3_0 = {
607.6828 +        2, 81,
607.6829 +        (long *)_vq_lengthlist__44u9_p3_0,
607.6830 +        1, -531628032, 1611661312, 4, 0,
607.6831 +        (long *)_vq_quantlist__44u9_p3_0,
607.6832 +        0
607.6833 +};
607.6834 +
607.6835 +static const long _vq_quantlist__44u9_p4_0[] = {
607.6836 +        8,
607.6837 +        7,
607.6838 +        9,
607.6839 +        6,
607.6840 +        10,
607.6841 +        5,
607.6842 +        11,
607.6843 +        4,
607.6844 +        12,
607.6845 +        3,
607.6846 +        13,
607.6847 +        2,
607.6848 +        14,
607.6849 +        1,
607.6850 +        15,
607.6851 +        0,
607.6852 +        16,
607.6853 +};
607.6854 +
607.6855 +static const long _vq_lengthlist__44u9_p4_0[] = {
607.6856 +         4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
607.6857 +        11, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,
607.6858 +        11,11, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,
607.6859 +        10,11,11, 6, 6, 6, 7, 6, 7, 7, 8, 8, 9, 9,10,10,
607.6860 +        11,11,12,11, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9,10,
607.6861 +        10,11,11,11,12, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,
607.6862 +        10,10,11,11,12,12, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9,
607.6863 +         9,10,10,11,11,12,12, 8, 8, 8, 8, 8, 9, 8,10, 9,
607.6864 +        10,10,11,10,12,11,13,12, 8, 8, 8, 8, 8, 9, 9, 9,
607.6865 +        10,10,10,10,11,11,12,12,12, 8, 8, 8, 9, 9, 9, 9,
607.6866 +        10,10,11,10,12,11,12,12,13,12, 8, 8, 8, 9, 9, 9,
607.6867 +         9,10,10,10,11,11,11,12,12,12,13, 9, 9, 9,10,10,
607.6868 +        10,10,11,10,11,11,12,11,13,12,13,13, 9, 9,10,10,
607.6869 +        10,10,10,10,11,11,11,11,12,12,13,13,13,10,11,10,
607.6870 +        11,11,11,11,12,11,12,12,13,12,13,13,14,13,10,10,
607.6871 +        10,11,11,11,11,11,12,12,12,12,13,13,13,13,14,11,
607.6872 +        11,11,12,11,12,12,12,12,13,13,13,13,14,13,14,14,
607.6873 +        11,11,11,11,12,12,12,12,12,12,13,13,13,13,14,14,
607.6874 +        14,
607.6875 +};
607.6876 +
607.6877 +static const static_codebook _44u9_p4_0 = {
607.6878 +        2, 289,
607.6879 +        (long *)_vq_lengthlist__44u9_p4_0,
607.6880 +        1, -529530880, 1611661312, 5, 0,
607.6881 +        (long *)_vq_quantlist__44u9_p4_0,
607.6882 +        0
607.6883 +};
607.6884 +
607.6885 +static const long _vq_quantlist__44u9_p5_0[] = {
607.6886 +        1,
607.6887 +        0,
607.6888 +        2,
607.6889 +};
607.6890 +
607.6891 +static const long _vq_lengthlist__44u9_p5_0[] = {
607.6892 +         1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 8, 9, 9, 7,
607.6893 +         9, 9, 5, 8, 8, 7, 9, 9, 8, 9, 9, 5, 8, 8, 8,10,
607.6894 +        10, 8,10,10, 7,10,10, 9,10,12, 9,11,11, 7,10,10,
607.6895 +         9,11,10, 9,11,12, 5, 8, 8, 8,10,10, 8,10,10, 7,
607.6896 +        10,10, 9,12,11, 9,10,11, 7,10,10, 9,11,11,10,12,
607.6897 +        10,
607.6898 +};
607.6899 +
607.6900 +static const static_codebook _44u9_p5_0 = {
607.6901 +        4, 81,
607.6902 +        (long *)_vq_lengthlist__44u9_p5_0,
607.6903 +        1, -529137664, 1618345984, 2, 0,
607.6904 +        (long *)_vq_quantlist__44u9_p5_0,
607.6905 +        0
607.6906 +};
607.6907 +
607.6908 +static const long _vq_quantlist__44u9_p5_1[] = {
607.6909 +        5,
607.6910 +        4,
607.6911 +        6,
607.6912 +        3,
607.6913 +        7,
607.6914 +        2,
607.6915 +        8,
607.6916 +        1,
607.6917 +        9,
607.6918 +        0,
607.6919 +        10,
607.6920 +};
607.6921 +
607.6922 +static const long _vq_lengthlist__44u9_p5_1[] = {
607.6923 +         5, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 6, 6,
607.6924 +         7, 7, 7, 7, 8, 7, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7,
607.6925 +         7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 6, 6, 6, 7,
607.6926 +         7, 7, 7, 7, 7, 8, 8, 7, 7, 7, 7, 7, 8, 7, 8, 8,
607.6927 +         8, 8, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7,
607.6928 +         8, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 8, 8, 8, 8,
607.6929 +         8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8,
607.6930 +         8, 8, 8, 8, 8, 8, 8, 8, 8,
607.6931 +};
607.6932 +
607.6933 +static const static_codebook _44u9_p5_1 = {
607.6934 +        2, 121,
607.6935 +        (long *)_vq_lengthlist__44u9_p5_1,
607.6936 +        1, -531365888, 1611661312, 4, 0,
607.6937 +        (long *)_vq_quantlist__44u9_p5_1,
607.6938 +        0
607.6939 +};
607.6940 +
607.6941 +static const long _vq_quantlist__44u9_p6_0[] = {
607.6942 +        6,
607.6943 +        5,
607.6944 +        7,
607.6945 +        4,
607.6946 +        8,
607.6947 +        3,
607.6948 +        9,
607.6949 +        2,
607.6950 +        10,
607.6951 +        1,
607.6952 +        11,
607.6953 +        0,
607.6954 +        12,
607.6955 +};
607.6956 +
607.6957 +static const long _vq_lengthlist__44u9_p6_0[] = {
607.6958 +         2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 4, 6, 5,
607.6959 +         7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 5, 6, 7, 7, 8,
607.6960 +         8, 8, 8, 9, 9,10,10, 6, 7, 7, 8, 8, 8, 8, 9, 9,
607.6961 +        10,10,10,10, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,10,
607.6962 +        10, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,11, 7, 8,
607.6963 +         8, 8, 8, 9, 9, 9, 9,10,10,11,11, 8, 8, 8, 9, 9,
607.6964 +         9, 9, 9,10,10,10,11,11, 8, 8, 8, 9, 9, 9, 9,10,
607.6965 +         9,10,10,11,11, 9, 9, 9,10,10,10,10,10,11,11,11,
607.6966 +        11,12, 9, 9, 9,10,10,10,10,10,10,11,10,12,11,10,
607.6967 +        10,10,10,10,11,11,11,11,11,12,12,12,10,10,10,10,
607.6968 +        10,11,11,11,11,12,11,12,12,
607.6969 +};
607.6970 +
607.6971 +static const static_codebook _44u9_p6_0 = {
607.6972 +        2, 169,
607.6973 +        (long *)_vq_lengthlist__44u9_p6_0,
607.6974 +        1, -526516224, 1616117760, 4, 0,
607.6975 +        (long *)_vq_quantlist__44u9_p6_0,
607.6976 +        0
607.6977 +};
607.6978 +
607.6979 +static const long _vq_quantlist__44u9_p6_1[] = {
607.6980 +        2,
607.6981 +        1,
607.6982 +        3,
607.6983 +        0,
607.6984 +        4,
607.6985 +};
607.6986 +
607.6987 +static const long _vq_lengthlist__44u9_p6_1[] = {
607.6988 +         4, 4, 4, 5, 5, 4, 5, 4, 5, 5, 4, 4, 5, 5, 5, 5,
607.6989 +         5, 5, 5, 5, 5, 5, 5, 5, 5,
607.6990 +};
607.6991 +
607.6992 +static const static_codebook _44u9_p6_1 = {
607.6993 +        2, 25,
607.6994 +        (long *)_vq_lengthlist__44u9_p6_1,
607.6995 +        1, -533725184, 1611661312, 3, 0,
607.6996 +        (long *)_vq_quantlist__44u9_p6_1,
607.6997 +        0
607.6998 +};
607.6999 +
607.7000 +static const long _vq_quantlist__44u9_p7_0[] = {
607.7001 +        6,
607.7002 +        5,
607.7003 +        7,
607.7004 +        4,
607.7005 +        8,
607.7006 +        3,
607.7007 +        9,
607.7008 +        2,
607.7009 +        10,
607.7010 +        1,
607.7011 +        11,
607.7012 +        0,
607.7013 +        12,
607.7014 +};
607.7015 +
607.7016 +static const long _vq_lengthlist__44u9_p7_0[] = {
607.7017 +         1, 4, 5, 6, 6, 7, 7, 8, 9,10,10,11,11, 5, 6, 6,
607.7018 +         7, 7, 8, 8, 9, 9,10,10,11,11, 5, 6, 6, 7, 7, 8,
607.7019 +         8, 9, 9,10,10,11,11, 6, 7, 7, 8, 8, 9, 9,10,10,
607.7020 +        11,11,12,12, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
607.7021 +        12, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13, 8, 8,
607.7022 +         8, 9, 9,10,10,11,11,12,12,13,13, 9, 9, 9,10,10,
607.7023 +        11,11,12,12,13,13,13,13, 9, 9, 9,10,10,11,11,12,
607.7024 +        12,13,13,14,14,10,10,10,11,11,12,12,13,13,14,13,
607.7025 +        15,14,10,10,10,11,11,12,12,13,13,14,14,14,14,11,
607.7026 +        11,12,12,12,13,13,14,14,14,14,15,15,11,11,12,12,
607.7027 +        12,13,13,14,14,14,15,15,15,
607.7028 +};
607.7029 +
607.7030 +static const static_codebook _44u9_p7_0 = {
607.7031 +        2, 169,
607.7032 +        (long *)_vq_lengthlist__44u9_p7_0,
607.7033 +        1, -523206656, 1618345984, 4, 0,
607.7034 +        (long *)_vq_quantlist__44u9_p7_0,
607.7035 +        0
607.7036 +};
607.7037 +
607.7038 +static const long _vq_quantlist__44u9_p7_1[] = {
607.7039 +        5,
607.7040 +        4,
607.7041 +        6,
607.7042 +        3,
607.7043 +        7,
607.7044 +        2,
607.7045 +        8,
607.7046 +        1,
607.7047 +        9,
607.7048 +        0,
607.7049 +        10,
607.7050 +};
607.7051 +
607.7052 +static const long _vq_lengthlist__44u9_p7_1[] = {
607.7053 +         5, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 7, 7,
607.7054 +         7, 7, 7, 7, 7, 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
607.7055 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7,
607.7056 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.7057 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.7058 +         7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.7059 +         7, 8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 8, 7, 7,
607.7060 +         7, 7, 7, 7, 7, 8, 8, 8, 8,
607.7061 +};
607.7062 +
607.7063 +static const static_codebook _44u9_p7_1 = {
607.7064 +        2, 121,
607.7065 +        (long *)_vq_lengthlist__44u9_p7_1,
607.7066 +        1, -531365888, 1611661312, 4, 0,
607.7067 +        (long *)_vq_quantlist__44u9_p7_1,
607.7068 +        0
607.7069 +};
607.7070 +
607.7071 +static const long _vq_quantlist__44u9_p8_0[] = {
607.7072 +        7,
607.7073 +        6,
607.7074 +        8,
607.7075 +        5,
607.7076 +        9,
607.7077 +        4,
607.7078 +        10,
607.7079 +        3,
607.7080 +        11,
607.7081 +        2,
607.7082 +        12,
607.7083 +        1,
607.7084 +        13,
607.7085 +        0,
607.7086 +        14,
607.7087 +};
607.7088 +
607.7089 +static const long _vq_lengthlist__44u9_p8_0[] = {
607.7090 +         1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9,10, 9,11,10, 4,
607.7091 +         6, 6, 8, 8, 9, 9, 9, 9,10,10,11,10,12,10, 4, 6,
607.7092 +         6, 8, 8, 9,10, 9, 9,10,10,11,11,12,12, 7, 8, 8,
607.7093 +        10,10,11,11,10,10,11,11,12,12,13,12, 7, 8, 8,10,
607.7094 +        10,11,11,10,10,11,11,12,12,12,13, 8,10, 9,11,11,
607.7095 +        12,12,11,11,12,12,13,13,14,13, 8, 9, 9,11,11,12,
607.7096 +        12,11,12,12,12,13,13,14,13, 8, 9, 9,10,10,12,11,
607.7097 +        13,12,13,13,14,13,15,14, 8, 9, 9,10,10,11,12,12,
607.7098 +        12,13,13,13,14,14,14, 9,10,10,12,11,13,12,13,13,
607.7099 +        14,13,14,14,14,15, 9,10,10,11,12,12,12,13,13,14,
607.7100 +        14,14,15,15,15,10,11,11,12,12,13,13,14,14,14,14,
607.7101 +        15,14,16,15,10,11,11,12,12,13,13,13,14,14,14,14,
607.7102 +        14,15,16,11,12,12,13,13,14,13,14,14,15,14,15,16,
607.7103 +        16,16,11,12,12,13,13,14,13,14,14,15,15,15,16,15,
607.7104 +        15,
607.7105 +};
607.7106 +
607.7107 +static const static_codebook _44u9_p8_0 = {
607.7108 +        2, 225,
607.7109 +        (long *)_vq_lengthlist__44u9_p8_0,
607.7110 +        1, -520986624, 1620377600, 4, 0,
607.7111 +        (long *)_vq_quantlist__44u9_p8_0,
607.7112 +        0
607.7113 +};
607.7114 +
607.7115 +static const long _vq_quantlist__44u9_p8_1[] = {
607.7116 +        10,
607.7117 +        9,
607.7118 +        11,
607.7119 +        8,
607.7120 +        12,
607.7121 +        7,
607.7122 +        13,
607.7123 +        6,
607.7124 +        14,
607.7125 +        5,
607.7126 +        15,
607.7127 +        4,
607.7128 +        16,
607.7129 +        3,
607.7130 +        17,
607.7131 +        2,
607.7132 +        18,
607.7133 +        1,
607.7134 +        19,
607.7135 +        0,
607.7136 +        20,
607.7137 +};
607.7138 +
607.7139 +static const long _vq_lengthlist__44u9_p8_1[] = {
607.7140 +         4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
607.7141 +         9, 9, 9, 9, 9, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
607.7142 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 6, 6, 7, 7, 8,
607.7143 +         8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7,
607.7144 +         7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,
607.7145 +         9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
607.7146 +         9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9,
607.7147 +         9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10, 8, 8,
607.7148 +         8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.7149 +         9,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.7150 +        10, 9,10, 9,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9,
607.7151 +         9, 9, 9, 9, 9,10,10, 9,10,10,10,10,10, 9, 9, 9,
607.7152 +         9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10,10,
607.7153 +        10,10, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,
607.7154 +        10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9,
607.7155 +         9, 9,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
607.7156 +         9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,
607.7157 +        10, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10,10,
607.7158 +        10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10,10,
607.7159 +        10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,
607.7160 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.7161 +         9, 9, 9, 9,10, 9, 9,10,10,10,10,10,10,10,10,10,
607.7162 +        10,10,10,10,10, 9, 9, 9,10, 9,10, 9,10,10,10,10,
607.7163 +        10,10,10,10,10,10,10,10,10,10, 9, 9, 9,10, 9,10,
607.7164 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,
607.7165 +         9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,
607.7166 +        10,10,10,10, 9, 9, 9,10,10,10,10,10,10,10,10,10,
607.7167 +        10,10,10,10,10,10,10,10,10,
607.7168 +};
607.7169 +
607.7170 +static const static_codebook _44u9_p8_1 = {
607.7171 +        2, 441,
607.7172 +        (long *)_vq_lengthlist__44u9_p8_1,
607.7173 +        1, -529268736, 1611661312, 5, 0,
607.7174 +        (long *)_vq_quantlist__44u9_p8_1,
607.7175 +        0
607.7176 +};
607.7177 +
607.7178 +static const long _vq_quantlist__44u9_p9_0[] = {
607.7179 +        7,
607.7180 +        6,
607.7181 +        8,
607.7182 +        5,
607.7183 +        9,
607.7184 +        4,
607.7185 +        10,
607.7186 +        3,
607.7187 +        11,
607.7188 +        2,
607.7189 +        12,
607.7190 +        1,
607.7191 +        13,
607.7192 +        0,
607.7193 +        14,
607.7194 +};
607.7195 +
607.7196 +static const long _vq_lengthlist__44u9_p9_0[] = {
607.7197 +         1, 3, 3,11,11,11,11,11,11,11,11,11,11,11,11, 4,
607.7198 +        10,11,11,11,11,11,11,11,11,11,11,11,11,11, 4,10,
607.7199 +        10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7200 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7201 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7202 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7203 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7204 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7205 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7206 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7207 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7208 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7209 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.7210 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.7211 +        10,
607.7212 +};
607.7213 +
607.7214 +static const static_codebook _44u9_p9_0 = {
607.7215 +        2, 225,
607.7216 +        (long *)_vq_lengthlist__44u9_p9_0,
607.7217 +        1, -510036736, 1631393792, 4, 0,
607.7218 +        (long *)_vq_quantlist__44u9_p9_0,
607.7219 +        0
607.7220 +};
607.7221 +
607.7222 +static const long _vq_quantlist__44u9_p9_1[] = {
607.7223 +        9,
607.7224 +        8,
607.7225 +        10,
607.7226 +        7,
607.7227 +        11,
607.7228 +        6,
607.7229 +        12,
607.7230 +        5,
607.7231 +        13,
607.7232 +        4,
607.7233 +        14,
607.7234 +        3,
607.7235 +        15,
607.7236 +        2,
607.7237 +        16,
607.7238 +        1,
607.7239 +        17,
607.7240 +        0,
607.7241 +        18,
607.7242 +};
607.7243 +
607.7244 +static const long _vq_lengthlist__44u9_p9_1[] = {
607.7245 +         1, 4, 4, 7, 7, 8, 7, 8, 7, 9, 8,10, 9,10,10,11,
607.7246 +        11,12,12, 4, 7, 6, 9, 9,10, 9, 9, 8,10,10,11,10,
607.7247 +        12,10,13,12,13,12, 4, 6, 6, 9, 9, 9, 9, 9, 9,10,
607.7248 +        10,11,11,11,12,12,12,12,12, 7, 9, 8,11,10,10,10,
607.7249 +        11,10,11,11,12,12,13,12,13,13,13,13, 7, 8, 9,10,
607.7250 +        10,11,11,10,10,11,11,11,12,13,13,13,13,14,14, 8,
607.7251 +         9, 9,11,11,12,11,12,12,13,12,12,13,13,14,15,14,
607.7252 +        14,14, 8, 9, 9,10,11,11,11,12,12,13,12,13,13,14,
607.7253 +        14,14,15,14,16, 8, 9, 9,11,10,12,12,12,12,15,13,
607.7254 +        13,13,17,14,15,15,15,14, 8, 9, 9,10,11,11,12,13,
607.7255 +        12,13,13,13,14,15,14,14,14,16,15, 9,11,10,12,12,
607.7256 +        13,13,13,13,14,14,16,15,14,14,14,15,15,17, 9,10,
607.7257 +        10,11,11,13,13,13,14,14,13,15,14,15,14,15,16,15,
607.7258 +        16,10,11,11,12,12,13,14,15,14,15,14,14,15,17,16,
607.7259 +        15,15,17,17,10,12,11,13,12,14,14,13,14,15,15,15,
607.7260 +        15,16,17,17,15,17,16,11,12,12,14,13,15,14,15,16,
607.7261 +        17,15,17,15,17,15,15,16,17,15,11,11,12,14,14,14,
607.7262 +        14,14,15,15,16,15,17,17,17,16,17,16,15,12,12,13,
607.7263 +        14,14,14,15,14,15,15,16,16,17,16,17,15,17,17,16,
607.7264 +        12,14,12,14,14,15,15,15,14,14,16,16,16,15,16,16,
607.7265 +        15,17,15,12,13,13,14,15,14,15,17,15,17,16,17,17,
607.7266 +        17,16,17,16,17,17,12,13,13,14,16,15,15,15,16,15,
607.7267 +        17,17,15,17,15,17,16,16,17,
607.7268 +};
607.7269 +
607.7270 +static const static_codebook _44u9_p9_1 = {
607.7271 +        2, 361,
607.7272 +        (long *)_vq_lengthlist__44u9_p9_1,
607.7273 +        1, -518287360, 1622704128, 5, 0,
607.7274 +        (long *)_vq_quantlist__44u9_p9_1,
607.7275 +        0
607.7276 +};
607.7277 +
607.7278 +static const long _vq_quantlist__44u9_p9_2[] = {
607.7279 +        24,
607.7280 +        23,
607.7281 +        25,
607.7282 +        22,
607.7283 +        26,
607.7284 +        21,
607.7285 +        27,
607.7286 +        20,
607.7287 +        28,
607.7288 +        19,
607.7289 +        29,
607.7290 +        18,
607.7291 +        30,
607.7292 +        17,
607.7293 +        31,
607.7294 +        16,
607.7295 +        32,
607.7296 +        15,
607.7297 +        33,
607.7298 +        14,
607.7299 +        34,
607.7300 +        13,
607.7301 +        35,
607.7302 +        12,
607.7303 +        36,
607.7304 +        11,
607.7305 +        37,
607.7306 +        10,
607.7307 +        38,
607.7308 +        9,
607.7309 +        39,
607.7310 +        8,
607.7311 +        40,
607.7312 +        7,
607.7313 +        41,
607.7314 +        6,
607.7315 +        42,
607.7316 +        5,
607.7317 +        43,
607.7318 +        4,
607.7319 +        44,
607.7320 +        3,
607.7321 +        45,
607.7322 +        2,
607.7323 +        46,
607.7324 +        1,
607.7325 +        47,
607.7326 +        0,
607.7327 +        48,
607.7328 +};
607.7329 +
607.7330 +static const long _vq_lengthlist__44u9_p9_2[] = {
607.7331 +         2, 4, 4, 5, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6,
607.7332 +         6, 6, 6, 7, 6, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.7333 +         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
607.7334 +         7,
607.7335 +};
607.7336 +
607.7337 +static const static_codebook _44u9_p9_2 = {
607.7338 +        1, 49,
607.7339 +        (long *)_vq_lengthlist__44u9_p9_2,
607.7340 +        1, -526909440, 1611661312, 6, 0,
607.7341 +        (long *)_vq_quantlist__44u9_p9_2,
607.7342 +        0
607.7343 +};
607.7344 +
607.7345 +static const long _huff_lengthlist__44un1__long[] = {
607.7346 +         5, 6,12, 9,14, 9, 9,19, 6, 1, 5, 5, 8, 7, 9,19,
607.7347 +        12, 4, 4, 7, 7, 9,11,18, 9, 5, 6, 6, 8, 7, 8,17,
607.7348 +        14, 8, 7, 8, 8,10,12,18, 9, 6, 8, 6, 8, 6, 8,18,
607.7349 +         9, 8,11, 8,11, 7, 5,15,16,18,18,18,17,15,11,18,
607.7350 +};
607.7351 +
607.7352 +static const static_codebook _huff_book__44un1__long = {
607.7353 +        2, 64,
607.7354 +        (long *)_huff_lengthlist__44un1__long,
607.7355 +        0, 0, 0, 0, 0,
607.7356 +        NULL,
607.7357 +        0
607.7358 +};
607.7359 +
607.7360 +static const long _vq_quantlist__44un1__p1_0[] = {
607.7361 +        1,
607.7362 +        0,
607.7363 +        2,
607.7364 +};
607.7365 +
607.7366 +static const long _vq_lengthlist__44un1__p1_0[] = {
607.7367 +         1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,10,11, 8,
607.7368 +        10,11, 5, 8, 8, 8,11,10, 8,11,10, 4, 9, 9, 8,11,
607.7369 +        11, 8,11,11, 8,12,11,10,12,14,11,13,13, 7,11,11,
607.7370 +        10,13,11,11,13,14, 4, 8, 9, 8,11,11, 8,11,12, 7,
607.7371 +        11,11,11,14,13,10,11,13, 8,11,12,11,13,13,10,14,
607.7372 +        12,
607.7373 +};
607.7374 +
607.7375 +static const static_codebook _44un1__p1_0 = {
607.7376 +        4, 81,
607.7377 +        (long *)_vq_lengthlist__44un1__p1_0,
607.7378 +        1, -535822336, 1611661312, 2, 0,
607.7379 +        (long *)_vq_quantlist__44un1__p1_0,
607.7380 +        0
607.7381 +};
607.7382 +
607.7383 +static const long _vq_quantlist__44un1__p2_0[] = {
607.7384 +        1,
607.7385 +        0,
607.7386 +        2,
607.7387 +};
607.7388 +
607.7389 +static const long _vq_lengthlist__44un1__p2_0[] = {
607.7390 +         2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 8, 6,
607.7391 +         7, 9, 5, 7, 7, 6, 8, 7, 7, 9, 8, 4, 7, 7, 7, 9,
607.7392 +         8, 7, 8, 8, 7, 9, 8, 8, 8,10, 9,10,10, 6, 8, 8,
607.7393 +         7,10, 8, 9,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 9, 6,
607.7394 +         8, 8, 9,10,10, 7, 8,10, 6, 8, 9, 9,10,10, 8,10,
607.7395 +         8,
607.7396 +};
607.7397 +
607.7398 +static const static_codebook _44un1__p2_0 = {
607.7399 +        4, 81,
607.7400 +        (long *)_vq_lengthlist__44un1__p2_0,
607.7401 +        1, -535822336, 1611661312, 2, 0,
607.7402 +        (long *)_vq_quantlist__44un1__p2_0,
607.7403 +        0
607.7404 +};
607.7405 +
607.7406 +static const long _vq_quantlist__44un1__p3_0[] = {
607.7407 +        2,
607.7408 +        1,
607.7409 +        3,
607.7410 +        0,
607.7411 +        4,
607.7412 +};
607.7413 +
607.7414 +static const long _vq_lengthlist__44un1__p3_0[] = {
607.7415 +         1, 5, 5, 8, 8, 5, 8, 7, 9, 9, 5, 7, 8, 9, 9, 9,
607.7416 +        10, 9,12,12, 9, 9,10,11,12, 6, 8, 8,10,10, 8,10,
607.7417 +        10,11,11, 8, 9,10,11,11,10,11,11,13,13,10,11,11,
607.7418 +        12,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10,10,11,
607.7419 +        11,10,11,11,13,12,10,11,11,13,12, 9,11,11,15,13,
607.7420 +        10,12,11,15,13,10,11,11,15,14,12,14,13,16,15,12,
607.7421 +        13,13,17,16, 9,11,11,13,15,10,11,12,14,15,10,11,
607.7422 +        12,14,15,12,13,13,15,16,12,13,13,16,16, 5, 8, 8,
607.7423 +        11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14,
607.7424 +        14,11,12,12,14,14, 8,11,10,13,12,10,11,12,12,13,
607.7425 +        10,12,12,13,13,12,12,13,13,15,11,12,13,15,14, 7,
607.7426 +        10,10,12,12, 9,12,11,13,12,10,12,12,13,14,12,13,
607.7427 +        12,15,13,11,13,12,14,15,10,12,12,16,14,11,12,12,
607.7428 +        16,15,11,13,12,17,16,13,13,15,15,17,13,15,15,20,
607.7429 +        17,10,12,12,14,16,11,12,12,15,15,11,13,13,15,18,
607.7430 +        13,14,13,15,15,13,15,14,16,16, 5, 8, 8,11,11, 8,
607.7431 +        10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12,
607.7432 +        12,14,15, 7,10,10,13,12,10,12,12,14,13, 9,10,12,
607.7433 +        12,13,11,13,13,15,15,11,12,13,13,15, 8,10,10,12,
607.7434 +        13,10,12,12,13,13,10,12,11,13,13,11,13,12,15,15,
607.7435 +        12,13,12,15,13,10,12,12,16,14,11,12,12,16,15,10,
607.7436 +        12,12,16,14,14,15,14,18,16,13,13,14,15,16,10,12,
607.7437 +        12,14,16,11,13,13,16,16,11,13,12,14,16,13,15,15,
607.7438 +        18,18,13,15,13,16,14, 8,11,11,16,16,10,13,13,17,
607.7439 +        16,10,12,12,16,15,14,16,15,20,17,13,14,14,17,17,
607.7440 +         9,12,12,16,16,11,13,14,16,17,11,13,13,16,16,15,
607.7441 +        15,19,18, 0,14,15,15,18,18, 9,12,12,17,16,11,13,
607.7442 +        12,17,16,11,12,13,15,17,15,16,15, 0,19,14,15,14,
607.7443 +        19,18,12,14,14, 0,16,13,14,14,19,18,13,15,16,17,
607.7444 +        16,15,15,17,18, 0,14,16,16,19, 0,12,14,14,16,18,
607.7445 +        13,15,13,17,18,13,15,14,17,18,15,18,14,18,18,16,
607.7446 +        17,16, 0,17, 8,11,11,15,15,10,12,12,16,16,10,13,
607.7447 +        13,16,16,13,15,14,17,17,14,15,17,17,18, 9,12,12,
607.7448 +        16,15,11,13,13,16,16,11,12,13,17,17,14,14,15,17,
607.7449 +        17,14,15,16, 0,18, 9,12,12,16,17,11,13,13,16,17,
607.7450 +        11,14,13,18,17,14,16,14,17,17,15,17,17,18,18,12,
607.7451 +        14,14, 0,16,13,15,15,19, 0,12,13,15, 0, 0,14,17,
607.7452 +        16,19, 0,16,15,18,18, 0,12,14,14,17, 0,13,14,14,
607.7453 +        17, 0,13,15,14, 0,18,15,16,16, 0,18,15,18,15, 0,
607.7454 +        17,
607.7455 +};
607.7456 +
607.7457 +static const static_codebook _44un1__p3_0 = {
607.7458 +        4, 625,
607.7459 +        (long *)_vq_lengthlist__44un1__p3_0,
607.7460 +        1, -533725184, 1611661312, 3, 0,
607.7461 +        (long *)_vq_quantlist__44un1__p3_0,
607.7462 +        0
607.7463 +};
607.7464 +
607.7465 +static const long _vq_quantlist__44un1__p4_0[] = {
607.7466 +        2,
607.7467 +        1,
607.7468 +        3,
607.7469 +        0,
607.7470 +        4,
607.7471 +};
607.7472 +
607.7473 +static const long _vq_lengthlist__44un1__p4_0[] = {
607.7474 +         3, 5, 5, 9, 9, 5, 6, 6,10, 9, 5, 6, 6, 9,10,10,
607.7475 +        10,10,12,11, 9,10,10,12,12, 5, 7, 7,10,10, 7, 7,
607.7476 +         8,10,11, 7, 7, 8,10,11,10,10,11,11,13,10,10,11,
607.7477 +        11,13, 6, 7, 7,10,10, 7, 8, 7,11,10, 7, 8, 7,10,
607.7478 +        10,10,11, 9,13,11,10,11,10,13,11,10,10,10,14,13,
607.7479 +        10,11,11,14,13,10,10,11,13,14,12,12,13,15,15,12,
607.7480 +        12,13,13,14,10,10,10,12,13,10,11,10,13,13,10,11,
607.7481 +        11,13,13,12,13,12,14,13,12,13,13,14,13, 5, 7, 7,
607.7482 +        10,10, 7, 8, 8,11,10, 7, 8, 8,10,10,11,11,11,13,
607.7483 +        13,10,11,11,12,12, 7, 8, 8,11,11, 7, 8, 9,10,12,
607.7484 +         8, 9, 9,11,11,11,10,12,11,14,11,11,12,13,13, 6,
607.7485 +         8, 8,10,11, 7, 9, 7,12,10, 8, 9,10,11,12,10,12,
607.7486 +        10,14,11,11,12,11,13,13,10,11,11,14,14,10,10,11,
607.7487 +        13,14,11,12,12,15,13,12,11,14,12,16,12,13,14,15,
607.7488 +        16,10,10,11,13,14,10,11,10,14,12,11,12,12,13,14,
607.7489 +        12,13,11,15,12,14,14,14,15,15, 5, 7, 7,10,10, 7,
607.7490 +         8, 8,10,10, 7, 8, 8,10,11,10,11,10,12,12,10,11,
607.7491 +        11,12,13, 6, 8, 8,11,11, 8, 9, 9,12,11, 7, 7, 9,
607.7492 +        10,12,11,11,11,12,13,11,10,12,11,15, 7, 8, 8,11,
607.7493 +        11, 8, 9, 9,11,11, 7, 9, 8,12,10,11,12,11,13,12,
607.7494 +        11,12,10,15,11,10,11,10,14,12,11,12,11,14,13,10,
607.7495 +        10,11,13,14,13,13,13,17,15,12,11,14,12,15,10,10,
607.7496 +        11,13,14,11,12,12,14,14,10,11,10,14,13,13,14,13,
607.7497 +        16,17,12,14,11,16,12, 9,10,10,14,13,10,11,10,14,
607.7498 +        14,10,11,11,13,13,13,14,14,16,15,12,13,13,14,14,
607.7499 +         9,11,10,14,13,10,10,12,13,14,11,12,11,14,13,13,
607.7500 +        14,14,14,15,13,14,14,15,15, 9,10,11,13,14,10,11,
607.7501 +        10,15,13,11,11,12,12,15,13,14,12,15,14,13,13,14,
607.7502 +        14,15,12,13,12,16,14,11,11,12,15,14,13,15,13,16,
607.7503 +        14,13,12,15,12,17,15,16,15,16,16,12,12,13,13,15,
607.7504 +        11,13,11,15,14,13,13,14,15,17,13,14,12, 0,13,14,
607.7505 +        15,14,15, 0, 9,10,10,13,13,10,11,11,13,13,10,11,
607.7506 +        11,13,13,12,13,12,14,14,13,14,14,15,17, 9,10,10,
607.7507 +        13,13,11,12,11,15,12,10,10,11,13,16,13,14,13,15,
607.7508 +        14,13,13,14,15,16,10,10,11,13,14,11,11,12,13,14,
607.7509 +        10,12,11,14,14,13,13,13,14,15,13,15,13,16,15,12,
607.7510 +        13,12,15,13,12,15,13,15,15,11,11,13,14,15,15,15,
607.7511 +        15,15,17,13,12,14,13,17,12,12,14,14,15,13,13,14,
607.7512 +        14,16,11,13,11,16,15,14,16,16,17, 0,14,13,11,16,
607.7513 +        12,
607.7514 +};
607.7515 +
607.7516 +static const static_codebook _44un1__p4_0 = {
607.7517 +        4, 625,
607.7518 +        (long *)_vq_lengthlist__44un1__p4_0,
607.7519 +        1, -533725184, 1611661312, 3, 0,
607.7520 +        (long *)_vq_quantlist__44un1__p4_0,
607.7521 +        0
607.7522 +};
607.7523 +
607.7524 +static const long _vq_quantlist__44un1__p5_0[] = {
607.7525 +        4,
607.7526 +        3,
607.7527 +        5,
607.7528 +        2,
607.7529 +        6,
607.7530 +        1,
607.7531 +        7,
607.7532 +        0,
607.7533 +        8,
607.7534 +};
607.7535 +
607.7536 +static const long _vq_lengthlist__44un1__p5_0[] = {
607.7537 +         1, 4, 4, 7, 7, 8, 8, 9, 9, 4, 6, 5, 8, 7, 8, 8,
607.7538 +        10, 9, 4, 6, 6, 8, 8, 8, 8,10,10, 7, 8, 7, 9, 9,
607.7539 +         9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,11, 8, 8, 8,
607.7540 +         9, 9,10,10,11,11, 8, 8, 8, 9, 9,10,10,11,11, 9,
607.7541 +        10,10,11,10,11,11,12,12, 9,10,10,10,11,11,11,12,
607.7542 +        12,
607.7543 +};
607.7544 +
607.7545 +static const static_codebook _44un1__p5_0 = {
607.7546 +        2, 81,
607.7547 +        (long *)_vq_lengthlist__44un1__p5_0,
607.7548 +        1, -531628032, 1611661312, 4, 0,
607.7549 +        (long *)_vq_quantlist__44un1__p5_0,
607.7550 +        0
607.7551 +};
607.7552 +
607.7553 +static const long _vq_quantlist__44un1__p6_0[] = {
607.7554 +        6,
607.7555 +        5,
607.7556 +        7,
607.7557 +        4,
607.7558 +        8,
607.7559 +        3,
607.7560 +        9,
607.7561 +        2,
607.7562 +        10,
607.7563 +        1,
607.7564 +        11,
607.7565 +        0,
607.7566 +        12,
607.7567 +};
607.7568 +
607.7569 +static const long _vq_lengthlist__44un1__p6_0[] = {
607.7570 +         1, 4, 4, 6, 6, 8, 8,10,10,11,11,15,15, 4, 5, 5,
607.7571 +         8, 8, 9, 9,11,11,12,12,16,16, 4, 5, 6, 8, 8, 9,
607.7572 +         9,11,11,12,12,14,14, 7, 8, 8, 9, 9,10,10,11,12,
607.7573 +        13,13,16,17, 7, 8, 8, 9, 9,10,10,12,12,12,13,15,
607.7574 +        15, 9,10,10,10,10,11,11,12,12,13,13,15,16, 9, 9,
607.7575 +         9,10,10,11,11,13,12,13,13,17,17,10,11,11,11,12,
607.7576 +        12,12,13,13,14,15, 0,18,10,11,11,12,12,12,13,14,
607.7577 +        13,14,14,17,16,11,12,12,13,13,14,14,14,14,15,16,
607.7578 +        17,16,11,12,12,13,13,14,14,14,14,15,15,17,17,14,
607.7579 +        15,15,16,16,16,17,17,16, 0,17, 0,18,14,15,15,16,
607.7580 +        16, 0,15,18,18, 0,16, 0, 0,
607.7581 +};
607.7582 +
607.7583 +static const static_codebook _44un1__p6_0 = {
607.7584 +        2, 169,
607.7585 +        (long *)_vq_lengthlist__44un1__p6_0,
607.7586 +        1, -526516224, 1616117760, 4, 0,
607.7587 +        (long *)_vq_quantlist__44un1__p6_0,
607.7588 +        0
607.7589 +};
607.7590 +
607.7591 +static const long _vq_quantlist__44un1__p6_1[] = {
607.7592 +        2,
607.7593 +        1,
607.7594 +        3,
607.7595 +        0,
607.7596 +        4,
607.7597 +};
607.7598 +
607.7599 +static const long _vq_lengthlist__44un1__p6_1[] = {
607.7600 +         2, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 6, 5, 5,
607.7601 +         6, 5, 6, 6, 5, 6, 6, 6, 6,
607.7602 +};
607.7603 +
607.7604 +static const static_codebook _44un1__p6_1 = {
607.7605 +        2, 25,
607.7606 +        (long *)_vq_lengthlist__44un1__p6_1,
607.7607 +        1, -533725184, 1611661312, 3, 0,
607.7608 +        (long *)_vq_quantlist__44un1__p6_1,
607.7609 +        0
607.7610 +};
607.7611 +
607.7612 +static const long _vq_quantlist__44un1__p7_0[] = {
607.7613 +        2,
607.7614 +        1,
607.7615 +        3,
607.7616 +        0,
607.7617 +        4,
607.7618 +};
607.7619 +
607.7620 +static const long _vq_lengthlist__44un1__p7_0[] = {
607.7621 +         1, 5, 3,11,11,11,11,11,11,11, 8,11,11,11,11,11,
607.7622 +        11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,
607.7623 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7624 +        11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7625 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7626 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7627 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7628 +        11,11,11,11,11,11,11,11,11,11,11,11,11, 8,11,11,
607.7629 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7630 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7631 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,
607.7632 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7633 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7634 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7635 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7636 +        11,11,11,11,11,11,11,11,11,11, 7,11,11,11,11,11,
607.7637 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7638 +        11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,
607.7639 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7640 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7641 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7642 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7643 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7644 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7645 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7646 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7647 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7648 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7649 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7650 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7651 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7652 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7653 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7654 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7655 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7656 +        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
607.7657 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.7658 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.7659 +        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
607.7660 +        10,
607.7661 +};
607.7662 +
607.7663 +static const static_codebook _44un1__p7_0 = {
607.7664 +        4, 625,
607.7665 +        (long *)_vq_lengthlist__44un1__p7_0,
607.7666 +        1, -518709248, 1626677248, 3, 0,
607.7667 +        (long *)_vq_quantlist__44un1__p7_0,
607.7668 +        0
607.7669 +};
607.7670 +
607.7671 +static const long _vq_quantlist__44un1__p7_1[] = {
607.7672 +        6,
607.7673 +        5,
607.7674 +        7,
607.7675 +        4,
607.7676 +        8,
607.7677 +        3,
607.7678 +        9,
607.7679 +        2,
607.7680 +        10,
607.7681 +        1,
607.7682 +        11,
607.7683 +        0,
607.7684 +        12,
607.7685 +};
607.7686 +
607.7687 +static const long _vq_lengthlist__44un1__p7_1[] = {
607.7688 +         1, 4, 4, 6, 6, 6, 6, 9, 8, 9, 8, 8, 8, 5, 7, 7,
607.7689 +         7, 7, 8, 8, 8,10, 8,10, 8, 9, 5, 7, 7, 8, 7, 7,
607.7690 +         8,10,10,11,10,12,11, 7, 8, 8, 9, 9, 9,10,11,11,
607.7691 +        11,11,11,11, 7, 8, 8, 8, 9, 9, 9,10,10,10,11,11,
607.7692 +        12, 7, 8, 8, 9, 9,10,11,11,12,11,12,11,11, 7, 8,
607.7693 +         8, 9, 9,10,10,11,11,11,12,12,11, 8,10,10,10,10,
607.7694 +        11,11,14,11,12,12,12,13, 9,10,10,10,10,12,11,14,
607.7695 +        11,14,11,12,13,10,11,11,11,11,13,11,14,14,13,13,
607.7696 +        13,14,11,11,11,12,11,12,12,12,13,14,14,13,14,12,
607.7697 +        11,12,12,12,12,13,13,13,14,13,14,14,11,12,12,14,
607.7698 +        12,13,13,12,13,13,14,14,14,
607.7699 +};
607.7700 +
607.7701 +static const static_codebook _44un1__p7_1 = {
607.7702 +        2, 169,
607.7703 +        (long *)_vq_lengthlist__44un1__p7_1,
607.7704 +        1, -523010048, 1618608128, 4, 0,
607.7705 +        (long *)_vq_quantlist__44un1__p7_1,
607.7706 +        0
607.7707 +};
607.7708 +
607.7709 +static const long _vq_quantlist__44un1__p7_2[] = {
607.7710 +        6,
607.7711 +        5,
607.7712 +        7,
607.7713 +        4,
607.7714 +        8,
607.7715 +        3,
607.7716 +        9,
607.7717 +        2,
607.7718 +        10,
607.7719 +        1,
607.7720 +        11,
607.7721 +        0,
607.7722 +        12,
607.7723 +};
607.7724 +
607.7725 +static const long _vq_lengthlist__44un1__p7_2[] = {
607.7726 +         3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 9, 8, 4, 5, 5,
607.7727 +         6, 6, 8, 8, 9, 8, 9, 9, 9, 9, 4, 5, 5, 7, 6, 8,
607.7728 +         8, 8, 8, 9, 8, 9, 8, 6, 7, 7, 7, 8, 8, 8, 9, 9,
607.7729 +         9, 9, 9, 9, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9,
607.7730 +         9, 7, 8, 8, 8, 8, 9, 8, 9, 9,10, 9, 9,10, 7, 8,
607.7731 +         8, 8, 8, 9, 9, 9, 9, 9, 9,10,10, 8, 9, 9, 9, 9,
607.7732 +         9, 9, 9, 9,10,10, 9,10, 8, 9, 9, 9, 9, 9, 9, 9,
607.7733 +         9, 9, 9,10,10, 9, 9, 9,10, 9, 9,10, 9, 9,10,10,
607.7734 +        10,10, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10, 9,
607.7735 +         9, 9,10, 9, 9,10,10, 9,10,10,10,10, 9, 9, 9,10,
607.7736 +         9, 9, 9,10,10,10,10,10,10,
607.7737 +};
607.7738 +
607.7739 +static const static_codebook _44un1__p7_2 = {
607.7740 +        2, 169,
607.7741 +        (long *)_vq_lengthlist__44un1__p7_2,
607.7742 +        1, -531103744, 1611661312, 4, 0,
607.7743 +        (long *)_vq_quantlist__44un1__p7_2,
607.7744 +        0
607.7745 +};
607.7746 +
607.7747 +static const long _huff_lengthlist__44un1__short[] = {
607.7748 +        12,12,14,12,14,14,14,14,12, 6, 6, 8, 9, 9,11,14,
607.7749 +        12, 4, 2, 6, 6, 7,11,14,13, 6, 5, 7, 8, 9,11,14,
607.7750 +        13, 8, 5, 8, 6, 8,12,14,12, 7, 7, 8, 8, 8,10,14,
607.7751 +        12, 6, 3, 4, 4, 4, 7,14,11, 7, 4, 6, 6, 6, 8,14,
607.7752 +};
607.7753 +
607.7754 +static const static_codebook _huff_book__44un1__short = {
607.7755 +        2, 64,
607.7756 +        (long *)_huff_lengthlist__44un1__short,
607.7757 +        0, 0, 0, 0, 0,
607.7758 +        NULL,
607.7759 +        0
607.7760 +};
607.7761 +
   608.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   608.2 +++ b/libs/vorbis/codebook.c	Sat Feb 01 19:58:19 2014 +0200
   608.3 @@ -0,0 +1,484 @@
   608.4 +/********************************************************************
   608.5 + *                                                                  *
   608.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   608.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   608.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   608.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  608.10 + *                                                                  *
  608.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  608.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  608.13 + *                                                                  *
  608.14 + ********************************************************************
  608.15 +
  608.16 + function: basic codebook pack/unpack/code/decode operations
  608.17 + last mod: $Id: codebook.c 18183 2012-02-03 20:51:27Z xiphmont $
  608.18 +
  608.19 + ********************************************************************/
  608.20 +
  608.21 +#include <stdlib.h>
  608.22 +#include <string.h>
  608.23 +#include <math.h>
  608.24 +#include <ogg/ogg.h>
  608.25 +#include "vorbis/codec.h"
  608.26 +#include "codebook.h"
  608.27 +#include "scales.h"
  608.28 +#include "misc.h"
  608.29 +#include "os.h"
  608.30 +
  608.31 +/* packs the given codebook into the bitstream **************************/
  608.32 +
  608.33 +int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
  608.34 +  long i,j;
  608.35 +  int ordered=0;
  608.36 +
  608.37 +  /* first the basic parameters */
  608.38 +  oggpack_write(opb,0x564342,24);
  608.39 +  oggpack_write(opb,c->dim,16);
  608.40 +  oggpack_write(opb,c->entries,24);
  608.41 +
  608.42 +  /* pack the codewords.  There are two packings; length ordered and
  608.43 +     length random.  Decide between the two now. */
  608.44 +
  608.45 +  for(i=1;i<c->entries;i++)
  608.46 +    if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break;
  608.47 +  if(i==c->entries)ordered=1;
  608.48 +
  608.49 +  if(ordered){
  608.50 +    /* length ordered.  We only need to say how many codewords of
  608.51 +       each length.  The actual codewords are generated
  608.52 +       deterministically */
  608.53 +
  608.54 +    long count=0;
  608.55 +    oggpack_write(opb,1,1);  /* ordered */
  608.56 +    oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */
  608.57 +
  608.58 +    for(i=1;i<c->entries;i++){
  608.59 +      long this=c->lengthlist[i];
  608.60 +      long last=c->lengthlist[i-1];
  608.61 +      if(this>last){
  608.62 +        for(j=last;j<this;j++){
  608.63 +          oggpack_write(opb,i-count,_ilog(c->entries-count));
  608.64 +          count=i;
  608.65 +        }
  608.66 +      }
  608.67 +    }
  608.68 +    oggpack_write(opb,i-count,_ilog(c->entries-count));
  608.69 +
  608.70 +  }else{
  608.71 +    /* length random.  Again, we don't code the codeword itself, just
  608.72 +       the length.  This time, though, we have to encode each length */
  608.73 +    oggpack_write(opb,0,1);   /* unordered */
  608.74 +
  608.75 +    /* algortihmic mapping has use for 'unused entries', which we tag
  608.76 +       here.  The algorithmic mapping happens as usual, but the unused
  608.77 +       entry has no codeword. */
  608.78 +    for(i=0;i<c->entries;i++)
  608.79 +      if(c->lengthlist[i]==0)break;
  608.80 +
  608.81 +    if(i==c->entries){
  608.82 +      oggpack_write(opb,0,1); /* no unused entries */
  608.83 +      for(i=0;i<c->entries;i++)
  608.84 +        oggpack_write(opb,c->lengthlist[i]-1,5);
  608.85 +    }else{
  608.86 +      oggpack_write(opb,1,1); /* we have unused entries; thus we tag */
  608.87 +      for(i=0;i<c->entries;i++){
  608.88 +        if(c->lengthlist[i]==0){
  608.89 +          oggpack_write(opb,0,1);
  608.90 +        }else{
  608.91 +          oggpack_write(opb,1,1);
  608.92 +          oggpack_write(opb,c->lengthlist[i]-1,5);
  608.93 +        }
  608.94 +      }
  608.95 +    }
  608.96 +  }
  608.97 +
  608.98 +  /* is the entry number the desired return value, or do we have a
  608.99 +     mapping? If we have a mapping, what type? */
 608.100 +  oggpack_write(opb,c->maptype,4);
 608.101 +  switch(c->maptype){
 608.102 +  case 0:
 608.103 +    /* no mapping */
 608.104 +    break;
 608.105 +  case 1:case 2:
 608.106 +    /* implicitly populated value mapping */
 608.107 +    /* explicitly populated value mapping */
 608.108 +
 608.109 +    if(!c->quantlist){
 608.110 +      /* no quantlist?  error */
 608.111 +      return(-1);
 608.112 +    }
 608.113 +
 608.114 +    /* values that define the dequantization */
 608.115 +    oggpack_write(opb,c->q_min,32);
 608.116 +    oggpack_write(opb,c->q_delta,32);
 608.117 +    oggpack_write(opb,c->q_quant-1,4);
 608.118 +    oggpack_write(opb,c->q_sequencep,1);
 608.119 +
 608.120 +    {
 608.121 +      int quantvals;
 608.122 +      switch(c->maptype){
 608.123 +      case 1:
 608.124 +        /* a single column of (c->entries/c->dim) quantized values for
 608.125 +           building a full value list algorithmically (square lattice) */
 608.126 +        quantvals=_book_maptype1_quantvals(c);
 608.127 +        break;
 608.128 +      case 2:
 608.129 +        /* every value (c->entries*c->dim total) specified explicitly */
 608.130 +        quantvals=c->entries*c->dim;
 608.131 +        break;
 608.132 +      default: /* NOT_REACHABLE */
 608.133 +        quantvals=-1;
 608.134 +      }
 608.135 +
 608.136 +      /* quantized values */
 608.137 +      for(i=0;i<quantvals;i++)
 608.138 +        oggpack_write(opb,labs(c->quantlist[i]),c->q_quant);
 608.139 +
 608.140 +    }
 608.141 +    break;
 608.142 +  default:
 608.143 +    /* error case; we don't have any other map types now */
 608.144 +    return(-1);
 608.145 +  }
 608.146 +
 608.147 +  return(0);
 608.148 +}
 608.149 +
 608.150 +/* unpacks a codebook from the packet buffer into the codebook struct,
 608.151 +   readies the codebook auxiliary structures for decode *************/
 608.152 +static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
 608.153 +  long i,j;
 608.154 +  static_codebook *s=_ogg_calloc(1,sizeof(*s));
 608.155 +  s->allocedp=1;
 608.156 +
 608.157 +  /* make sure alignment is correct */
 608.158 +  if(oggpack_read(opb,24)!=0x564342)goto _eofout;
 608.159 +
 608.160 +  /* first the basic parameters */
 608.161 +  s->dim=oggpack_read(opb,16);
 608.162 +  s->entries=oggpack_read(opb,24);
 608.163 +  if(s->entries==-1)goto _eofout;
 608.164 +
 608.165 +  if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
 608.166 +
 608.167 +  /* codeword ordering.... length ordered or unordered? */
 608.168 +  switch((int)oggpack_read(opb,1)){
 608.169 +  case 0:{
 608.170 +    long unused;
 608.171 +    /* allocated but unused entries? */
 608.172 +    unused=oggpack_read(opb,1);
 608.173 +    if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb))
 608.174 +      goto _eofout;
 608.175 +    /* unordered */
 608.176 +    s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
 608.177 +
 608.178 +    /* allocated but unused entries? */
 608.179 +    if(unused){
 608.180 +      /* yes, unused entries */
 608.181 +
 608.182 +      for(i=0;i<s->entries;i++){
 608.183 +        if(oggpack_read(opb,1)){
 608.184 +          long num=oggpack_read(opb,5);
 608.185 +          if(num==-1)goto _eofout;
 608.186 +          s->lengthlist[i]=num+1;
 608.187 +        }else
 608.188 +          s->lengthlist[i]=0;
 608.189 +      }
 608.190 +    }else{
 608.191 +      /* all entries used; no tagging */
 608.192 +      for(i=0;i<s->entries;i++){
 608.193 +        long num=oggpack_read(opb,5);
 608.194 +        if(num==-1)goto _eofout;
 608.195 +        s->lengthlist[i]=num+1;
 608.196 +      }
 608.197 +    }
 608.198 +
 608.199 +    break;
 608.200 +  }
 608.201 +  case 1:
 608.202 +    /* ordered */
 608.203 +    {
 608.204 +      long length=oggpack_read(opb,5)+1;
 608.205 +      if(length==0)goto _eofout;
 608.206 +      s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
 608.207 +
 608.208 +      for(i=0;i<s->entries;){
 608.209 +        long num=oggpack_read(opb,_ilog(s->entries-i));
 608.210 +        if(num==-1)goto _eofout;
 608.211 +        if(length>32 || num>s->entries-i ||
 608.212 +           (num>0 && (num-1)>>(length-1)>1)){
 608.213 +          goto _errout;
 608.214 +        }
 608.215 +        if(length>32)goto _errout;
 608.216 +        for(j=0;j<num;j++,i++)
 608.217 +          s->lengthlist[i]=length;
 608.218 +        length++;
 608.219 +      }
 608.220 +    }
 608.221 +    break;
 608.222 +  default:
 608.223 +    /* EOF */
 608.224 +    goto _eofout;
 608.225 +  }
 608.226 +
 608.227 +  /* Do we have a mapping to unpack? */
 608.228 +  switch((s->maptype=oggpack_read(opb,4))){
 608.229 +  case 0:
 608.230 +    /* no mapping */
 608.231 +    break;
 608.232 +  case 1: case 2:
 608.233 +    /* implicitly populated value mapping */
 608.234 +    /* explicitly populated value mapping */
 608.235 +
 608.236 +    s->q_min=oggpack_read(opb,32);
 608.237 +    s->q_delta=oggpack_read(opb,32);
 608.238 +    s->q_quant=oggpack_read(opb,4)+1;
 608.239 +    s->q_sequencep=oggpack_read(opb,1);
 608.240 +    if(s->q_sequencep==-1)goto _eofout;
 608.241 +
 608.242 +    {
 608.243 +      int quantvals=0;
 608.244 +      switch(s->maptype){
 608.245 +      case 1:
 608.246 +        quantvals=(s->dim==0?0:_book_maptype1_quantvals(s));
 608.247 +        break;
 608.248 +      case 2:
 608.249 +        quantvals=s->entries*s->dim;
 608.250 +        break;
 608.251 +      }
 608.252 +
 608.253 +      /* quantized values */
 608.254 +      if(((quantvals*s->q_quant+7)>>3)>opb->storage-oggpack_bytes(opb))
 608.255 +        goto _eofout;
 608.256 +      s->quantlist=_ogg_malloc(sizeof(*s->quantlist)*quantvals);
 608.257 +      for(i=0;i<quantvals;i++)
 608.258 +        s->quantlist[i]=oggpack_read(opb,s->q_quant);
 608.259 +
 608.260 +      if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
 608.261 +    }
 608.262 +    break;
 608.263 +  default:
 608.264 +    goto _errout;
 608.265 +  }
 608.266 +
 608.267 +  /* all set */
 608.268 +  return(s);
 608.269 +
 608.270 + _errout:
 608.271 + _eofout:
 608.272 +  vorbis_staticbook_destroy(s);
 608.273 +  return(NULL);
 608.274 +}
 608.275 +
 608.276 +/* returns the number of bits ************************************************/
 608.277 +int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){
 608.278 +  if(a<0 || a>=book->c->entries)return(0);
 608.279 +  oggpack_write(b,book->codelist[a],book->c->lengthlist[a]);
 608.280 +  return(book->c->lengthlist[a]);
 608.281 +}
 608.282 +
 608.283 +/* the 'eliminate the decode tree' optimization actually requires the
 608.284 +   codewords to be MSb first, not LSb.  This is an annoying inelegancy
 608.285 +   (and one of the first places where carefully thought out design
 608.286 +   turned out to be wrong; Vorbis II and future Ogg codecs should go
 608.287 +   to an MSb bitpacker), but not actually the huge hit it appears to
 608.288 +   be.  The first-stage decode table catches most words so that
 608.289 +   bitreverse is not in the main execution path. */
 608.290 +
 608.291 +static ogg_uint32_t bitreverse(ogg_uint32_t x){
 608.292 +  x=    ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
 608.293 +  x=    ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
 608.294 +  x=    ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
 608.295 +  x=    ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
 608.296 +  return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
 608.297 +}
 608.298 +
 608.299 +STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){
 608.300 +  int  read=book->dec_maxlength;
 608.301 +  long lo,hi;
 608.302 +  long lok = oggpack_look(b,book->dec_firsttablen);
 608.303 +
 608.304 +  if (lok >= 0) {
 608.305 +    long entry = book->dec_firsttable[lok];
 608.306 +    if(entry&0x80000000UL){
 608.307 +      lo=(entry>>15)&0x7fff;
 608.308 +      hi=book->used_entries-(entry&0x7fff);
 608.309 +    }else{
 608.310 +      oggpack_adv(b, book->dec_codelengths[entry-1]);
 608.311 +      return(entry-1);
 608.312 +    }
 608.313 +  }else{
 608.314 +    lo=0;
 608.315 +    hi=book->used_entries;
 608.316 +  }
 608.317 +
 608.318 +  lok = oggpack_look(b, read);
 608.319 +
 608.320 +  while(lok<0 && read>1)
 608.321 +    lok = oggpack_look(b, --read);
 608.322 +  if(lok<0)return -1;
 608.323 +
 608.324 +  /* bisect search for the codeword in the ordered list */
 608.325 +  {
 608.326 +    ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
 608.327 +
 608.328 +    while(hi-lo>1){
 608.329 +      long p=(hi-lo)>>1;
 608.330 +      long test=book->codelist[lo+p]>testword;
 608.331 +      lo+=p&(test-1);
 608.332 +      hi-=p&(-test);
 608.333 +      }
 608.334 +
 608.335 +    if(book->dec_codelengths[lo]<=read){
 608.336 +      oggpack_adv(b, book->dec_codelengths[lo]);
 608.337 +      return(lo);
 608.338 +    }
 608.339 +  }
 608.340 +
 608.341 +  oggpack_adv(b, read);
 608.342 +
 608.343 +  return(-1);
 608.344 +}
 608.345 +
 608.346 +/* Decode side is specced and easier, because we don't need to find
 608.347 +   matches using different criteria; we simply read and map.  There are
 608.348 +   two things we need to do 'depending':
 608.349 +
 608.350 +   We may need to support interleave.  We don't really, but it's
 608.351 +   convenient to do it here rather than rebuild the vector later.
 608.352 +
 608.353 +   Cascades may be additive or multiplicitive; this is not inherent in
 608.354 +   the codebook, but set in the code using the codebook.  Like
 608.355 +   interleaving, it's easiest to do it here.
 608.356 +   addmul==0 -> declarative (set the value)
 608.357 +   addmul==1 -> additive
 608.358 +   addmul==2 -> multiplicitive */
 608.359 +
 608.360 +/* returns the [original, not compacted] entry number or -1 on eof *********/
 608.361 +long vorbis_book_decode(codebook *book, oggpack_buffer *b){
 608.362 +  if(book->used_entries>0){
 608.363 +    long packed_entry=decode_packed_entry_number(book,b);
 608.364 +    if(packed_entry>=0)
 608.365 +      return(book->dec_index[packed_entry]);
 608.366 +  }
 608.367 +
 608.368 +  /* if there's no dec_index, the codebook unpacking isn't collapsed */
 608.369 +  return(-1);
 608.370 +}
 608.371 +
 608.372 +/* returns 0 on OK or -1 on eof *************************************/
 608.373 +/* decode vector / dim granularity gaurding is done in the upper layer */
 608.374 +long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){
 608.375 +  if(book->used_entries>0){
 608.376 +    int step=n/book->dim;
 608.377 +    long *entry = alloca(sizeof(*entry)*step);
 608.378 +    float **t = alloca(sizeof(*t)*step);
 608.379 +    int i,j,o;
 608.380 +
 608.381 +    for (i = 0; i < step; i++) {
 608.382 +      entry[i]=decode_packed_entry_number(book,b);
 608.383 +      if(entry[i]==-1)return(-1);
 608.384 +      t[i] = book->valuelist+entry[i]*book->dim;
 608.385 +    }
 608.386 +    for(i=0,o=0;i<book->dim;i++,o+=step)
 608.387 +      for (j=0;j<step;j++)
 608.388 +        a[o+j]+=t[j][i];
 608.389 +  }
 608.390 +  return(0);
 608.391 +}
 608.392 +
 608.393 +/* decode vector / dim granularity gaurding is done in the upper layer */
 608.394 +long vorbis_book_decodev_add(codebook *book,float *a,oggpack_buffer *b,int n){
 608.395 +  if(book->used_entries>0){
 608.396 +    int i,j,entry;
 608.397 +    float *t;
 608.398 +
 608.399 +    if(book->dim>8){
 608.400 +      for(i=0;i<n;){
 608.401 +        entry = decode_packed_entry_number(book,b);
 608.402 +        if(entry==-1)return(-1);
 608.403 +        t     = book->valuelist+entry*book->dim;
 608.404 +        for (j=0;j<book->dim;)
 608.405 +          a[i++]+=t[j++];
 608.406 +      }
 608.407 +    }else{
 608.408 +      for(i=0;i<n;){
 608.409 +        entry = decode_packed_entry_number(book,b);
 608.410 +        if(entry==-1)return(-1);
 608.411 +        t     = book->valuelist+entry*book->dim;
 608.412 +        j=0;
 608.413 +        switch((int)book->dim){
 608.414 +        case 8:
 608.415 +          a[i++]+=t[j++];
 608.416 +        case 7:
 608.417 +          a[i++]+=t[j++];
 608.418 +        case 6:
 608.419 +          a[i++]+=t[j++];
 608.420 +        case 5:
 608.421 +          a[i++]+=t[j++];
 608.422 +        case 4:
 608.423 +          a[i++]+=t[j++];
 608.424 +        case 3:
 608.425 +          a[i++]+=t[j++];
 608.426 +        case 2:
 608.427 +          a[i++]+=t[j++];
 608.428 +        case 1:
 608.429 +          a[i++]+=t[j++];
 608.430 +        case 0:
 608.431 +          break;
 608.432 +        }
 608.433 +      }
 608.434 +    }
 608.435 +  }
 608.436 +  return(0);
 608.437 +}
 608.438 +
 608.439 +/* unlike the others, we guard against n not being an integer number
 608.440 +   of <dim> internally rather than in the upper layer (called only by
 608.441 +   floor0) */
 608.442 +long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){
 608.443 +  if(book->used_entries>0){
 608.444 +    int i,j,entry;
 608.445 +    float *t;
 608.446 +
 608.447 +    for(i=0;i<n;){
 608.448 +      entry = decode_packed_entry_number(book,b);
 608.449 +      if(entry==-1)return(-1);
 608.450 +      t     = book->valuelist+entry*book->dim;
 608.451 +      for (j=0;i<n && j<book->dim;){
 608.452 +        a[i++]=t[j++];
 608.453 +      }
 608.454 +    }
 608.455 +  }else{
 608.456 +    int i;
 608.457 +
 608.458 +    for(i=0;i<n;){
 608.459 +      a[i++]=0.f;
 608.460 +    }
 608.461 +  }
 608.462 +  return(0);
 608.463 +}
 608.464 +
 608.465 +long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch,
 608.466 +                              oggpack_buffer *b,int n){
 608.467 +
 608.468 +  long i,j,entry;
 608.469 +  int chptr=0;
 608.470 +  if(book->used_entries>0){
 608.471 +    for(i=offset/ch;i<(offset+n)/ch;){
 608.472 +      entry = decode_packed_entry_number(book,b);
 608.473 +      if(entry==-1)return(-1);
 608.474 +      {
 608.475 +        const float *t = book->valuelist+entry*book->dim;
 608.476 +        for (j=0;j<book->dim;j++){
 608.477 +          a[chptr++][i]+=t[j];
 608.478 +          if(chptr==ch){
 608.479 +            chptr=0;
 608.480 +            i++;
 608.481 +          }
 608.482 +        }
 608.483 +      }
 608.484 +    }
 608.485 +  }
 608.486 +  return(0);
 608.487 +}
   609.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   609.2 +++ b/libs/vorbis/codebook.h	Sat Feb 01 19:58:19 2014 +0200
   609.3 @@ -0,0 +1,119 @@
   609.4 +/********************************************************************
   609.5 + *                                                                  *
   609.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   609.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   609.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   609.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  609.10 + *                                                                  *
  609.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  609.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  609.13 + *                                                                  *
  609.14 + ********************************************************************
  609.15 +
  609.16 + function: basic shared codebook operations
  609.17 + last mod: $Id: codebook.h 17030 2010-03-25 06:52:55Z xiphmont $
  609.18 +
  609.19 + ********************************************************************/
  609.20 +
  609.21 +#ifndef _V_CODEBOOK_H_
  609.22 +#define _V_CODEBOOK_H_
  609.23 +
  609.24 +#include <ogg/ogg.h>
  609.25 +
  609.26 +/* This structure encapsulates huffman and VQ style encoding books; it
  609.27 +   doesn't do anything specific to either.
  609.28 +
  609.29 +   valuelist/quantlist are nonNULL (and q_* significant) only if
  609.30 +   there's entry->value mapping to be done.
  609.31 +
  609.32 +   If encode-side mapping must be done (and thus the entry needs to be
  609.33 +   hunted), the auxiliary encode pointer will point to a decision
  609.34 +   tree.  This is true of both VQ and huffman, but is mostly useful
  609.35 +   with VQ.
  609.36 +
  609.37 +*/
  609.38 +
  609.39 +typedef struct static_codebook{
  609.40 +  long   dim;            /* codebook dimensions (elements per vector) */
  609.41 +  long   entries;        /* codebook entries */
  609.42 +  long  *lengthlist;     /* codeword lengths in bits */
  609.43 +
  609.44 +  /* mapping ***************************************************************/
  609.45 +  int    maptype;        /* 0=none
  609.46 +                            1=implicitly populated values from map column
  609.47 +                            2=listed arbitrary values */
  609.48 +
  609.49 +  /* The below does a linear, single monotonic sequence mapping. */
  609.50 +  long     q_min;       /* packed 32 bit float; quant value 0 maps to minval */
  609.51 +  long     q_delta;     /* packed 32 bit float; val 1 - val 0 == delta */
  609.52 +  int      q_quant;     /* bits: 0 < quant <= 16 */
  609.53 +  int      q_sequencep; /* bitflag */
  609.54 +
  609.55 +  long     *quantlist;  /* map == 1: (int)(entries^(1/dim)) element column map
  609.56 +                           map == 2: list of dim*entries quantized entry vals
  609.57 +                        */
  609.58 +  int allocedp;
  609.59 +} static_codebook;
  609.60 +
  609.61 +typedef struct codebook{
  609.62 +  long dim;           /* codebook dimensions (elements per vector) */
  609.63 +  long entries;       /* codebook entries */
  609.64 +  long used_entries;  /* populated codebook entries */
  609.65 +  const static_codebook *c;
  609.66 +
  609.67 +  /* for encode, the below are entry-ordered, fully populated */
  609.68 +  /* for decode, the below are ordered by bitreversed codeword and only
  609.69 +     used entries are populated */
  609.70 +  float        *valuelist;  /* list of dim*entries actual entry values */
  609.71 +  ogg_uint32_t *codelist;   /* list of bitstream codewords for each entry */
  609.72 +
  609.73 +  int          *dec_index;  /* only used if sparseness collapsed */
  609.74 +  char         *dec_codelengths;
  609.75 +  ogg_uint32_t *dec_firsttable;
  609.76 +  int           dec_firsttablen;
  609.77 +  int           dec_maxlength;
  609.78 +
  609.79 +  /* The current encoder uses only centered, integer-only lattice books. */
  609.80 +  int           quantvals;
  609.81 +  int           minval;
  609.82 +  int           delta;
  609.83 +} codebook;
  609.84 +
  609.85 +extern void vorbis_staticbook_destroy(static_codebook *b);
  609.86 +extern int vorbis_book_init_encode(codebook *dest,const static_codebook *source);
  609.87 +extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source);
  609.88 +extern void vorbis_book_clear(codebook *b);
  609.89 +
  609.90 +extern float *_book_unquantize(const static_codebook *b,int n,int *map);
  609.91 +extern float *_book_logdist(const static_codebook *b,float *vals);
  609.92 +extern float _float32_unpack(long val);
  609.93 +extern long   _float32_pack(float val);
  609.94 +extern int  _best(codebook *book, float *a, int step);
  609.95 +extern int _ilog(unsigned int v);
  609.96 +extern long _book_maptype1_quantvals(const static_codebook *b);
  609.97 +
  609.98 +extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul);
  609.99 +extern long vorbis_book_codeword(codebook *book,int entry);
 609.100 +extern long vorbis_book_codelen(codebook *book,int entry);
 609.101 +
 609.102 +
 609.103 +
 609.104 +extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b);
 609.105 +extern static_codebook *vorbis_staticbook_unpack(oggpack_buffer *b);
 609.106 +
 609.107 +extern int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b);
 609.108 +
 609.109 +extern long vorbis_book_decode(codebook *book, oggpack_buffer *b);
 609.110 +extern long vorbis_book_decodevs_add(codebook *book, float *a,
 609.111 +                                     oggpack_buffer *b,int n);
 609.112 +extern long vorbis_book_decodev_set(codebook *book, float *a,
 609.113 +                                    oggpack_buffer *b,int n);
 609.114 +extern long vorbis_book_decodev_add(codebook *book, float *a,
 609.115 +                                    oggpack_buffer *b,int n);
 609.116 +extern long vorbis_book_decodevv_add(codebook *book, float **a,
 609.117 +                                     long off,int ch,
 609.118 +                                    oggpack_buffer *b,int n);
 609.119 +
 609.120 +
 609.121 +
 609.122 +#endif
   610.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   610.2 +++ b/libs/vorbis/codec.h	Sat Feb 01 19:58:19 2014 +0200
   610.3 @@ -0,0 +1,243 @@
   610.4 +/********************************************************************
   610.5 + *                                                                  *
   610.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   610.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   610.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   610.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  610.10 + *                                                                  *
  610.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
  610.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  610.13 +
  610.14 + ********************************************************************
  610.15 +
  610.16 + function: libvorbis codec headers
  610.17 + last mod: $Id: codec.h 17021 2010-03-24 09:29:41Z xiphmont $
  610.18 +
  610.19 + ********************************************************************/
  610.20 +
  610.21 +#ifndef _vorbis_codec_h_
  610.22 +#define _vorbis_codec_h_
  610.23 +
  610.24 +#ifdef __cplusplus
  610.25 +extern "C"
  610.26 +{
  610.27 +#endif /* __cplusplus */
  610.28 +
  610.29 +#include <ogg/ogg.h>
  610.30 +
  610.31 +typedef struct vorbis_info{
  610.32 +  int version;
  610.33 +  int channels;
  610.34 +  long rate;
  610.35 +
  610.36 +  /* The below bitrate declarations are *hints*.
  610.37 +     Combinations of the three values carry the following implications:
  610.38 +
  610.39 +     all three set to the same value:
  610.40 +       implies a fixed rate bitstream
  610.41 +     only nominal set:
  610.42 +       implies a VBR stream that averages the nominal bitrate.  No hard
  610.43 +       upper/lower limit
  610.44 +     upper and or lower set:
  610.45 +       implies a VBR bitstream that obeys the bitrate limits. nominal
  610.46 +       may also be set to give a nominal rate.
  610.47 +     none set:
  610.48 +       the coder does not care to speculate.
  610.49 +  */
  610.50 +
  610.51 +  long bitrate_upper;
  610.52 +  long bitrate_nominal;
  610.53 +  long bitrate_lower;
  610.54 +  long bitrate_window;
  610.55 +
  610.56 +  void *codec_setup;
  610.57 +} vorbis_info;
  610.58 +
  610.59 +/* vorbis_dsp_state buffers the current vorbis audio
  610.60 +   analysis/synthesis state.  The DSP state belongs to a specific
  610.61 +   logical bitstream ****************************************************/
  610.62 +typedef struct vorbis_dsp_state{
  610.63 +  int analysisp;
  610.64 +  vorbis_info *vi;
  610.65 +
  610.66 +  float **pcm;
  610.67 +  float **pcmret;
  610.68 +  int      pcm_storage;
  610.69 +  int      pcm_current;
  610.70 +  int      pcm_returned;
  610.71 +
  610.72 +  int  preextrapolate;
  610.73 +  int  eofflag;
  610.74 +
  610.75 +  long lW;
  610.76 +  long W;
  610.77 +  long nW;
  610.78 +  long centerW;
  610.79 +
  610.80 +  ogg_int64_t granulepos;
  610.81 +  ogg_int64_t sequence;
  610.82 +
  610.83 +  ogg_int64_t glue_bits;
  610.84 +  ogg_int64_t time_bits;
  610.85 +  ogg_int64_t floor_bits;
  610.86 +  ogg_int64_t res_bits;
  610.87 +
  610.88 +  void       *backend_state;
  610.89 +} vorbis_dsp_state;
  610.90 +
  610.91 +typedef struct vorbis_block{
  610.92 +  /* necessary stream state for linking to the framing abstraction */
  610.93 +  float  **pcm;       /* this is a pointer into local storage */
  610.94 +  oggpack_buffer opb;
  610.95 +
  610.96 +  long  lW;
  610.97 +  long  W;
  610.98 +  long  nW;
  610.99 +  int   pcmend;
 610.100 +  int   mode;
 610.101 +
 610.102 +  int         eofflag;
 610.103 +  ogg_int64_t granulepos;
 610.104 +  ogg_int64_t sequence;
 610.105 +  vorbis_dsp_state *vd; /* For read-only access of configuration */
 610.106 +
 610.107 +  /* local storage to avoid remallocing; it's up to the mapping to
 610.108 +     structure it */
 610.109 +  void               *localstore;
 610.110 +  long                localtop;
 610.111 +  long                localalloc;
 610.112 +  long                totaluse;
 610.113 +  struct alloc_chain *reap;
 610.114 +
 610.115 +  /* bitmetrics for the frame */
 610.116 +  long glue_bits;
 610.117 +  long time_bits;
 610.118 +  long floor_bits;
 610.119 +  long res_bits;
 610.120 +
 610.121 +  void *internal;
 610.122 +
 610.123 +} vorbis_block;
 610.124 +
 610.125 +/* vorbis_block is a single block of data to be processed as part of
 610.126 +the analysis/synthesis stream; it belongs to a specific logical
 610.127 +bitstream, but is independent from other vorbis_blocks belonging to
 610.128 +that logical bitstream. *************************************************/
 610.129 +
 610.130 +struct alloc_chain{
 610.131 +  void *ptr;
 610.132 +  struct alloc_chain *next;
 610.133 +};
 610.134 +
 610.135 +/* vorbis_info contains all the setup information specific to the
 610.136 +   specific compression/decompression mode in progress (eg,
 610.137 +   psychoacoustic settings, channel setup, options, codebook
 610.138 +   etc). vorbis_info and substructures are in backends.h.
 610.139 +*********************************************************************/
 610.140 +
 610.141 +/* the comments are not part of vorbis_info so that vorbis_info can be
 610.142 +   static storage */
 610.143 +typedef struct vorbis_comment{
 610.144 +  /* unlimited user comment fields.  libvorbis writes 'libvorbis'
 610.145 +     whatever vendor is set to in encode */
 610.146 +  char **user_comments;
 610.147 +  int   *comment_lengths;
 610.148 +  int    comments;
 610.149 +  char  *vendor;
 610.150 +
 610.151 +} vorbis_comment;
 610.152 +
 610.153 +
 610.154 +/* libvorbis encodes in two abstraction layers; first we perform DSP
 610.155 +   and produce a packet (see docs/analysis.txt).  The packet is then
 610.156 +   coded into a framed OggSquish bitstream by the second layer (see
 610.157 +   docs/framing.txt).  Decode is the reverse process; we sync/frame
 610.158 +   the bitstream and extract individual packets, then decode the
 610.159 +   packet back into PCM audio.
 610.160 +
 610.161 +   The extra framing/packetizing is used in streaming formats, such as
 610.162 +   files.  Over the net (such as with UDP), the framing and
 610.163 +   packetization aren't necessary as they're provided by the transport
 610.164 +   and the streaming layer is not used */
 610.165 +
 610.166 +/* Vorbis PRIMITIVES: general ***************************************/
 610.167 +
 610.168 +extern void     vorbis_info_init(vorbis_info *vi);
 610.169 +extern void     vorbis_info_clear(vorbis_info *vi);
 610.170 +extern int      vorbis_info_blocksize(vorbis_info *vi,int zo);
 610.171 +extern void     vorbis_comment_init(vorbis_comment *vc);
 610.172 +extern void     vorbis_comment_add(vorbis_comment *vc, const char *comment);
 610.173 +extern void     vorbis_comment_add_tag(vorbis_comment *vc,
 610.174 +                                       const char *tag, const char *contents);
 610.175 +extern char    *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count);
 610.176 +extern int      vorbis_comment_query_count(vorbis_comment *vc, const char *tag);
 610.177 +extern void     vorbis_comment_clear(vorbis_comment *vc);
 610.178 +
 610.179 +extern int      vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
 610.180 +extern int      vorbis_block_clear(vorbis_block *vb);
 610.181 +extern void     vorbis_dsp_clear(vorbis_dsp_state *v);
 610.182 +extern double   vorbis_granule_time(vorbis_dsp_state *v,
 610.183 +                                    ogg_int64_t granulepos);
 610.184 +
 610.185 +extern const char *vorbis_version_string(void);
 610.186 +
 610.187 +/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/
 610.188 +
 610.189 +extern int      vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi);
 610.190 +extern int      vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op);
 610.191 +extern int      vorbis_analysis_headerout(vorbis_dsp_state *v,
 610.192 +                                          vorbis_comment *vc,
 610.193 +                                          ogg_packet *op,
 610.194 +                                          ogg_packet *op_comm,
 610.195 +                                          ogg_packet *op_code);
 610.196 +extern float  **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals);
 610.197 +extern int      vorbis_analysis_wrote(vorbis_dsp_state *v,int vals);
 610.198 +extern int      vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb);
 610.199 +extern int      vorbis_analysis(vorbis_block *vb,ogg_packet *op);
 610.200 +
 610.201 +extern int      vorbis_bitrate_addblock(vorbis_block *vb);
 610.202 +extern int      vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,
 610.203 +                                           ogg_packet *op);
 610.204 +
 610.205 +/* Vorbis PRIMITIVES: synthesis layer *******************************/
 610.206 +extern int      vorbis_synthesis_idheader(ogg_packet *op);
 610.207 +extern int      vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,
 610.208 +                                          ogg_packet *op);
 610.209 +
 610.210 +extern int      vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi);
 610.211 +extern int      vorbis_synthesis_restart(vorbis_dsp_state *v);
 610.212 +extern int      vorbis_synthesis(vorbis_block *vb,ogg_packet *op);
 610.213 +extern int      vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op);
 610.214 +extern int      vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb);
 610.215 +extern int      vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm);
 610.216 +extern int      vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm);
 610.217 +extern int      vorbis_synthesis_read(vorbis_dsp_state *v,int samples);
 610.218 +extern long     vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
 610.219 +
 610.220 +extern int      vorbis_synthesis_halfrate(vorbis_info *v,int flag);
 610.221 +extern int      vorbis_synthesis_halfrate_p(vorbis_info *v);
 610.222 +
 610.223 +/* Vorbis ERRORS and return codes ***********************************/
 610.224 +
 610.225 +#define OV_FALSE      -1
 610.226 +#define OV_EOF        -2
 610.227 +#define OV_HOLE       -3
 610.228 +
 610.229 +#define OV_EREAD      -128
 610.230 +#define OV_EFAULT     -129
 610.231 +#define OV_EIMPL      -130
 610.232 +#define OV_EINVAL     -131
 610.233 +#define OV_ENOTVORBIS -132
 610.234 +#define OV_EBADHEADER -133
 610.235 +#define OV_EVERSION   -134
 610.236 +#define OV_ENOTAUDIO  -135
 610.237 +#define OV_EBADPACKET -136
 610.238 +#define OV_EBADLINK   -137
 610.239 +#define OV_ENOSEEK    -138
 610.240 +
 610.241 +#ifdef __cplusplus
 610.242 +}
 610.243 +#endif /* __cplusplus */
 610.244 +
 610.245 +#endif
 610.246 +
   611.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   611.2 +++ b/libs/vorbis/codec_internal.h	Sat Feb 01 19:58:19 2014 +0200
   611.3 @@ -0,0 +1,167 @@
   611.4 +/********************************************************************
   611.5 + *                                                                  *
   611.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   611.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   611.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   611.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  611.10 + *                                                                  *
  611.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  611.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  611.13 + *                                                                  *
  611.14 + ********************************************************************
  611.15 +
  611.16 + function: libvorbis codec headers
  611.17 + last mod: $Id: codec_internal.h 16227 2009-07-08 06:58:46Z xiphmont $
  611.18 +
  611.19 + ********************************************************************/
  611.20 +
  611.21 +#ifndef _V_CODECI_H_
  611.22 +#define _V_CODECI_H_
  611.23 +
  611.24 +#include "envelope.h"
  611.25 +#include "codebook.h"
  611.26 +
  611.27 +#define BLOCKTYPE_IMPULSE    0
  611.28 +#define BLOCKTYPE_PADDING    1
  611.29 +#define BLOCKTYPE_TRANSITION 0
  611.30 +#define BLOCKTYPE_LONG       1
  611.31 +
  611.32 +#define PACKETBLOBS 15
  611.33 +
  611.34 +typedef struct vorbis_block_internal{
  611.35 +  float  **pcmdelay;  /* this is a pointer into local storage */
  611.36 +  float  ampmax;
  611.37 +  int    blocktype;
  611.38 +
  611.39 +  oggpack_buffer *packetblob[PACKETBLOBS]; /* initialized, must be freed;
  611.40 +                                              blob [PACKETBLOBS/2] points to
  611.41 +                                              the oggpack_buffer in the
  611.42 +                                              main vorbis_block */
  611.43 +} vorbis_block_internal;
  611.44 +
  611.45 +typedef void vorbis_look_floor;
  611.46 +typedef void vorbis_look_residue;
  611.47 +typedef void vorbis_look_transform;
  611.48 +
  611.49 +/* mode ************************************************************/
  611.50 +typedef struct {
  611.51 +  int blockflag;
  611.52 +  int windowtype;
  611.53 +  int transformtype;
  611.54 +  int mapping;
  611.55 +} vorbis_info_mode;
  611.56 +
  611.57 +typedef void vorbis_info_floor;
  611.58 +typedef void vorbis_info_residue;
  611.59 +typedef void vorbis_info_mapping;
  611.60 +
  611.61 +#include "psy.h"
  611.62 +#include "bitrate.h"
  611.63 +
  611.64 +typedef struct private_state {
  611.65 +  /* local lookup storage */
  611.66 +  envelope_lookup        *ve; /* envelope lookup */
  611.67 +  int                     window[2];
  611.68 +  vorbis_look_transform **transform[2];    /* block, type */
  611.69 +  drft_lookup             fft_look[2];
  611.70 +
  611.71 +  int                     modebits;
  611.72 +  vorbis_look_floor     **flr;
  611.73 +  vorbis_look_residue   **residue;
  611.74 +  vorbis_look_psy        *psy;
  611.75 +  vorbis_look_psy_global *psy_g_look;
  611.76 +
  611.77 +  /* local storage, only used on the encoding side.  This way the
  611.78 +     application does not need to worry about freeing some packets'
  611.79 +     memory and not others'; packet storage is always tracked.
  611.80 +     Cleared next call to a _dsp_ function */
  611.81 +  unsigned char *header;
  611.82 +  unsigned char *header1;
  611.83 +  unsigned char *header2;
  611.84 +
  611.85 +  bitrate_manager_state bms;
  611.86 +
  611.87 +  ogg_int64_t sample_count;
  611.88 +} private_state;
  611.89 +
  611.90 +/* codec_setup_info contains all the setup information specific to the
  611.91 +   specific compression/decompression mode in progress (eg,
  611.92 +   psychoacoustic settings, channel setup, options, codebook
  611.93 +   etc).
  611.94 +*********************************************************************/
  611.95 +
  611.96 +#include "highlevel.h"
  611.97 +typedef struct codec_setup_info {
  611.98 +
  611.99 +  /* Vorbis supports only short and long blocks, but allows the
 611.100 +     encoder to choose the sizes */
 611.101 +
 611.102 +  long blocksizes[2];
 611.103 +
 611.104 +  /* modes are the primary means of supporting on-the-fly different
 611.105 +     blocksizes, different channel mappings (LR or M/A),
 611.106 +     different residue backends, etc.  Each mode consists of a
 611.107 +     blocksize flag and a mapping (along with the mapping setup */
 611.108 +
 611.109 +  int        modes;
 611.110 +  int        maps;
 611.111 +  int        floors;
 611.112 +  int        residues;
 611.113 +  int        books;
 611.114 +  int        psys;     /* encode only */
 611.115 +
 611.116 +  vorbis_info_mode       *mode_param[64];
 611.117 +  int                     map_type[64];
 611.118 +  vorbis_info_mapping    *map_param[64];
 611.119 +  int                     floor_type[64];
 611.120 +  vorbis_info_floor      *floor_param[64];
 611.121 +  int                     residue_type[64];
 611.122 +  vorbis_info_residue    *residue_param[64];
 611.123 +  static_codebook        *book_param[256];
 611.124 +  codebook               *fullbooks;
 611.125 +
 611.126 +  vorbis_info_psy        *psy_param[4]; /* encode only */
 611.127 +  vorbis_info_psy_global psy_g_param;
 611.128 +
 611.129 +  bitrate_manager_info   bi;
 611.130 +  highlevel_encode_setup hi; /* used only by vorbisenc.c.  It's a
 611.131 +                                highly redundant structure, but
 611.132 +                                improves clarity of program flow. */
 611.133 +  int         halfrate_flag; /* painless downsample for decode */
 611.134 +} codec_setup_info;
 611.135 +
 611.136 +extern vorbis_look_psy_global *_vp_global_look(vorbis_info *vi);
 611.137 +extern void _vp_global_free(vorbis_look_psy_global *look);
 611.138 +
 611.139 +
 611.140 +
 611.141 +typedef struct {
 611.142 +  int sorted_index[VIF_POSIT+2];
 611.143 +  int forward_index[VIF_POSIT+2];
 611.144 +  int reverse_index[VIF_POSIT+2];
 611.145 +
 611.146 +  int hineighbor[VIF_POSIT];
 611.147 +  int loneighbor[VIF_POSIT];
 611.148 +  int posts;
 611.149 +
 611.150 +  int n;
 611.151 +  int quant_q;
 611.152 +  vorbis_info_floor1 *vi;
 611.153 +
 611.154 +  long phrasebits;
 611.155 +  long postbits;
 611.156 +  long frames;
 611.157 +} vorbis_look_floor1;
 611.158 +
 611.159 +
 611.160 +
 611.161 +extern int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
 611.162 +                          const float *logmdct,   /* in */
 611.163 +                          const float *logmask);
 611.164 +extern int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
 611.165 +                          int *A,int *B,
 611.166 +                          int del);
 611.167 +extern int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
 611.168 +                  vorbis_look_floor1 *look,
 611.169 +                  int *post,int *ilogmask);
 611.170 +#endif
   612.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   612.2 +++ b/libs/vorbis/envelope.c	Sat Feb 01 19:58:19 2014 +0200
   612.3 @@ -0,0 +1,375 @@
   612.4 +/********************************************************************
   612.5 + *                                                                  *
   612.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   612.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   612.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   612.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  612.10 + *                                                                  *
  612.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  612.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  612.13 + *                                                                  *
  612.14 + ********************************************************************
  612.15 +
  612.16 + function: PCM data envelope analysis
  612.17 + last mod: $Id: envelope.c 16227 2009-07-08 06:58:46Z xiphmont $
  612.18 +
  612.19 + ********************************************************************/
  612.20 +
  612.21 +#include <stdlib.h>
  612.22 +#include <string.h>
  612.23 +#include <stdio.h>
  612.24 +#include <math.h>
  612.25 +#include <ogg/ogg.h>
  612.26 +#include "vorbis/codec.h"
  612.27 +#include "codec_internal.h"
  612.28 +
  612.29 +#include "os.h"
  612.30 +#include "scales.h"
  612.31 +#include "envelope.h"
  612.32 +#include "mdct.h"
  612.33 +#include "misc.h"
  612.34 +
  612.35 +void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){
  612.36 +  codec_setup_info *ci=vi->codec_setup;
  612.37 +  vorbis_info_psy_global *gi=&ci->psy_g_param;
  612.38 +  int ch=vi->channels;
  612.39 +  int i,j;
  612.40 +  int n=e->winlength=128;
  612.41 +  e->searchstep=64; /* not random */
  612.42 +
  612.43 +  e->minenergy=gi->preecho_minenergy;
  612.44 +  e->ch=ch;
  612.45 +  e->storage=128;
  612.46 +  e->cursor=ci->blocksizes[1]/2;
  612.47 +  e->mdct_win=_ogg_calloc(n,sizeof(*e->mdct_win));
  612.48 +  mdct_init(&e->mdct,n);
  612.49 +
  612.50 +  for(i=0;i<n;i++){
  612.51 +    e->mdct_win[i]=sin(i/(n-1.)*M_PI);
  612.52 +    e->mdct_win[i]*=e->mdct_win[i];
  612.53 +  }
  612.54 +
  612.55 +  /* magic follows */
  612.56 +  e->band[0].begin=2;  e->band[0].end=4;
  612.57 +  e->band[1].begin=4;  e->band[1].end=5;
  612.58 +  e->band[2].begin=6;  e->band[2].end=6;
  612.59 +  e->band[3].begin=9;  e->band[3].end=8;
  612.60 +  e->band[4].begin=13;  e->band[4].end=8;
  612.61 +  e->band[5].begin=17;  e->band[5].end=8;
  612.62 +  e->band[6].begin=22;  e->band[6].end=8;
  612.63 +
  612.64 +  for(j=0;j<VE_BANDS;j++){
  612.65 +    n=e->band[j].end;
  612.66 +    e->band[j].window=_ogg_malloc(n*sizeof(*e->band[0].window));
  612.67 +    for(i=0;i<n;i++){
  612.68 +      e->band[j].window[i]=sin((i+.5)/n*M_PI);
  612.69 +      e->band[j].total+=e->band[j].window[i];
  612.70 +    }
  612.71 +    e->band[j].total=1./e->band[j].total;
  612.72 +  }
  612.73 +
  612.74 +  e->filter=_ogg_calloc(VE_BANDS*ch,sizeof(*e->filter));
  612.75 +  e->mark=_ogg_calloc(e->storage,sizeof(*e->mark));
  612.76 +
  612.77 +}
  612.78 +
  612.79 +void _ve_envelope_clear(envelope_lookup *e){
  612.80 +  int i;
  612.81 +  mdct_clear(&e->mdct);
  612.82 +  for(i=0;i<VE_BANDS;i++)
  612.83 +    _ogg_free(e->band[i].window);
  612.84 +  _ogg_free(e->mdct_win);
  612.85 +  _ogg_free(e->filter);
  612.86 +  _ogg_free(e->mark);
  612.87 +  memset(e,0,sizeof(*e));
  612.88 +}
  612.89 +
  612.90 +/* fairly straight threshhold-by-band based until we find something
  612.91 +   that works better and isn't patented. */
  612.92 +
  612.93 +static int _ve_amp(envelope_lookup *ve,
  612.94 +                   vorbis_info_psy_global *gi,
  612.95 +                   float *data,
  612.96 +                   envelope_band *bands,
  612.97 +                   envelope_filter_state *filters){
  612.98 +  long n=ve->winlength;
  612.99 +  int ret=0;
 612.100 +  long i,j;
 612.101 +  float decay;
 612.102 +
 612.103 +  /* we want to have a 'minimum bar' for energy, else we're just
 612.104 +     basing blocks on quantization noise that outweighs the signal
 612.105 +     itself (for low power signals) */
 612.106 +
 612.107 +  float minV=ve->minenergy;
 612.108 +  float *vec=alloca(n*sizeof(*vec));
 612.109 +
 612.110 +  /* stretch is used to gradually lengthen the number of windows
 612.111 +     considered prevoius-to-potential-trigger */
 612.112 +  int stretch=max(VE_MINSTRETCH,ve->stretch/2);
 612.113 +  float penalty=gi->stretch_penalty-(ve->stretch/2-VE_MINSTRETCH);
 612.114 +  if(penalty<0.f)penalty=0.f;
 612.115 +  if(penalty>gi->stretch_penalty)penalty=gi->stretch_penalty;
 612.116 +
 612.117 +  /*_analysis_output_always("lpcm",seq2,data,n,0,0,
 612.118 +    totalshift+pos*ve->searchstep);*/
 612.119 +
 612.120 + /* window and transform */
 612.121 +  for(i=0;i<n;i++)
 612.122 +    vec[i]=data[i]*ve->mdct_win[i];
 612.123 +  mdct_forward(&ve->mdct,vec,vec);
 612.124 +
 612.125 +  /*_analysis_output_always("mdct",seq2,vec,n/2,0,1,0); */
 612.126 +
 612.127 +  /* near-DC spreading function; this has nothing to do with
 612.128 +     psychoacoustics, just sidelobe leakage and window size */
 612.129 +  {
 612.130 +    float temp=vec[0]*vec[0]+.7*vec[1]*vec[1]+.2*vec[2]*vec[2];
 612.131 +    int ptr=filters->nearptr;
 612.132 +
 612.133 +    /* the accumulation is regularly refreshed from scratch to avoid
 612.134 +       floating point creep */
 612.135 +    if(ptr==0){
 612.136 +      decay=filters->nearDC_acc=filters->nearDC_partialacc+temp;
 612.137 +      filters->nearDC_partialacc=temp;
 612.138 +    }else{
 612.139 +      decay=filters->nearDC_acc+=temp;
 612.140 +      filters->nearDC_partialacc+=temp;
 612.141 +    }
 612.142 +    filters->nearDC_acc-=filters->nearDC[ptr];
 612.143 +    filters->nearDC[ptr]=temp;
 612.144 +
 612.145 +    decay*=(1./(VE_NEARDC+1));
 612.146 +    filters->nearptr++;
 612.147 +    if(filters->nearptr>=VE_NEARDC)filters->nearptr=0;
 612.148 +    decay=todB(&decay)*.5-15.f;
 612.149 +  }
 612.150 +
 612.151 +  /* perform spreading and limiting, also smooth the spectrum.  yes,
 612.152 +     the MDCT results in all real coefficients, but it still *behaves*
 612.153 +     like real/imaginary pairs */
 612.154 +  for(i=0;i<n/2;i+=2){
 612.155 +    float val=vec[i]*vec[i]+vec[i+1]*vec[i+1];
 612.156 +    val=todB(&val)*.5f;
 612.157 +    if(val<decay)val=decay;
 612.158 +    if(val<minV)val=minV;
 612.159 +    vec[i>>1]=val;
 612.160 +    decay-=8.;
 612.161 +  }
 612.162 +
 612.163 +  /*_analysis_output_always("spread",seq2++,vec,n/4,0,0,0);*/
 612.164 +
 612.165 +  /* perform preecho/postecho triggering by band */
 612.166 +  for(j=0;j<VE_BANDS;j++){
 612.167 +    float acc=0.;
 612.168 +    float valmax,valmin;
 612.169 +
 612.170 +    /* accumulate amplitude */
 612.171 +    for(i=0;i<bands[j].end;i++)
 612.172 +      acc+=vec[i+bands[j].begin]*bands[j].window[i];
 612.173 +
 612.174 +    acc*=bands[j].total;
 612.175 +
 612.176 +    /* convert amplitude to delta */
 612.177 +    {
 612.178 +      int p,this=filters[j].ampptr;
 612.179 +      float postmax,postmin,premax=-99999.f,premin=99999.f;
 612.180 +
 612.181 +      p=this;
 612.182 +      p--;
 612.183 +      if(p<0)p+=VE_AMP;
 612.184 +      postmax=max(acc,filters[j].ampbuf[p]);
 612.185 +      postmin=min(acc,filters[j].ampbuf[p]);
 612.186 +
 612.187 +      for(i=0;i<stretch;i++){
 612.188 +        p--;
 612.189 +        if(p<0)p+=VE_AMP;
 612.190 +        premax=max(premax,filters[j].ampbuf[p]);
 612.191 +        premin=min(premin,filters[j].ampbuf[p]);
 612.192 +      }
 612.193 +
 612.194 +      valmin=postmin-premin;
 612.195 +      valmax=postmax-premax;
 612.196 +
 612.197 +      /*filters[j].markers[pos]=valmax;*/
 612.198 +      filters[j].ampbuf[this]=acc;
 612.199 +      filters[j].ampptr++;
 612.200 +      if(filters[j].ampptr>=VE_AMP)filters[j].ampptr=0;
 612.201 +    }
 612.202 +
 612.203 +    /* look at min/max, decide trigger */
 612.204 +    if(valmax>gi->preecho_thresh[j]+penalty){
 612.205 +      ret|=1;
 612.206 +      ret|=4;
 612.207 +    }
 612.208 +    if(valmin<gi->postecho_thresh[j]-penalty)ret|=2;
 612.209 +  }
 612.210 +
 612.211 +  return(ret);
 612.212 +}
 612.213 +
 612.214 +#if 0
 612.215 +static int seq=0;
 612.216 +static ogg_int64_t totalshift=-1024;
 612.217 +#endif
 612.218 +
 612.219 +long _ve_envelope_search(vorbis_dsp_state *v){
 612.220 +  vorbis_info *vi=v->vi;
 612.221 +  codec_setup_info *ci=vi->codec_setup;
 612.222 +  vorbis_info_psy_global *gi=&ci->psy_g_param;
 612.223 +  envelope_lookup *ve=((private_state *)(v->backend_state))->ve;
 612.224 +  long i,j;
 612.225 +
 612.226 +  int first=ve->current/ve->searchstep;
 612.227 +  int last=v->pcm_current/ve->searchstep-VE_WIN;
 612.228 +  if(first<0)first=0;
 612.229 +
 612.230 +  /* make sure we have enough storage to match the PCM */
 612.231 +  if(last+VE_WIN+VE_POST>ve->storage){
 612.232 +    ve->storage=last+VE_WIN+VE_POST; /* be sure */
 612.233 +    ve->mark=_ogg_realloc(ve->mark,ve->storage*sizeof(*ve->mark));
 612.234 +  }
 612.235 +
 612.236 +  for(j=first;j<last;j++){
 612.237 +    int ret=0;
 612.238 +
 612.239 +    ve->stretch++;
 612.240 +    if(ve->stretch>VE_MAXSTRETCH*2)
 612.241 +      ve->stretch=VE_MAXSTRETCH*2;
 612.242 +
 612.243 +    for(i=0;i<ve->ch;i++){
 612.244 +      float *pcm=v->pcm[i]+ve->searchstep*(j);
 612.245 +      ret|=_ve_amp(ve,gi,pcm,ve->band,ve->filter+i*VE_BANDS);
 612.246 +    }
 612.247 +
 612.248 +    ve->mark[j+VE_POST]=0;
 612.249 +    if(ret&1){
 612.250 +      ve->mark[j]=1;
 612.251 +      ve->mark[j+1]=1;
 612.252 +    }
 612.253 +
 612.254 +    if(ret&2){
 612.255 +      ve->mark[j]=1;
 612.256 +      if(j>0)ve->mark[j-1]=1;
 612.257 +    }
 612.258 +
 612.259 +    if(ret&4)ve->stretch=-1;
 612.260 +  }
 612.261 +
 612.262 +  ve->current=last*ve->searchstep;
 612.263 +
 612.264 +  {
 612.265 +    long centerW=v->centerW;
 612.266 +    long testW=
 612.267 +      centerW+
 612.268 +      ci->blocksizes[v->W]/4+
 612.269 +      ci->blocksizes[1]/2+
 612.270 +      ci->blocksizes[0]/4;
 612.271 +
 612.272 +    j=ve->cursor;
 612.273 +
 612.274 +    while(j<ve->current-(ve->searchstep)){/* account for postecho
 612.275 +                                             working back one window */
 612.276 +      if(j>=testW)return(1);
 612.277 +
 612.278 +      ve->cursor=j;
 612.279 +
 612.280 +      if(ve->mark[j/ve->searchstep]){
 612.281 +        if(j>centerW){
 612.282 +
 612.283 +#if 0
 612.284 +          if(j>ve->curmark){
 612.285 +            float *marker=alloca(v->pcm_current*sizeof(*marker));
 612.286 +            int l,m;
 612.287 +            memset(marker,0,sizeof(*marker)*v->pcm_current);
 612.288 +            fprintf(stderr,"mark! seq=%d, cursor:%fs time:%fs\n",
 612.289 +                    seq,
 612.290 +                    (totalshift+ve->cursor)/44100.,
 612.291 +                    (totalshift+j)/44100.);
 612.292 +            _analysis_output_always("pcmL",seq,v->pcm[0],v->pcm_current,0,0,totalshift);
 612.293 +            _analysis_output_always("pcmR",seq,v->pcm[1],v->pcm_current,0,0,totalshift);
 612.294 +
 612.295 +            _analysis_output_always("markL",seq,v->pcm[0],j,0,0,totalshift);
 612.296 +            _analysis_output_always("markR",seq,v->pcm[1],j,0,0,totalshift);
 612.297 +
 612.298 +            for(m=0;m<VE_BANDS;m++){
 612.299 +              char buf[80];
 612.300 +              sprintf(buf,"delL%d",m);
 612.301 +              for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->filter[m].markers[l]*.1;
 612.302 +              _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift);
 612.303 +            }
 612.304 +
 612.305 +            for(m=0;m<VE_BANDS;m++){
 612.306 +              char buf[80];
 612.307 +              sprintf(buf,"delR%d",m);
 612.308 +              for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->filter[m+VE_BANDS].markers[l]*.1;
 612.309 +              _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift);
 612.310 +            }
 612.311 +
 612.312 +            for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->mark[l]*.4;
 612.313 +            _analysis_output_always("mark",seq,marker,v->pcm_current,0,0,totalshift);
 612.314 +
 612.315 +
 612.316 +            seq++;
 612.317 +
 612.318 +          }
 612.319 +#endif
 612.320 +
 612.321 +          ve->curmark=j;
 612.322 +          if(j>=testW)return(1);
 612.323 +          return(0);
 612.324 +        }
 612.325 +      }
 612.326 +      j+=ve->searchstep;
 612.327 +    }
 612.328 +  }
 612.329 +
 612.330 +  return(-1);
 612.331 +}
 612.332 +
 612.333 +int _ve_envelope_mark(vorbis_dsp_state *v){
 612.334 +  envelope_lookup *ve=((private_state *)(v->backend_state))->ve;
 612.335 +  vorbis_info *vi=v->vi;
 612.336 +  codec_setup_info *ci=vi->codec_setup;
 612.337 +  long centerW=v->centerW;
 612.338 +  long beginW=centerW-ci->blocksizes[v->W]/4;
 612.339 +  long endW=centerW+ci->blocksizes[v->W]/4;
 612.340 +  if(v->W){
 612.341 +    beginW-=ci->blocksizes[v->lW]/4;
 612.342 +    endW+=ci->blocksizes[v->nW]/4;
 612.343 +  }else{
 612.344 +    beginW-=ci->blocksizes[0]/4;
 612.345 +    endW+=ci->blocksizes[0]/4;
 612.346 +  }
 612.347 +
 612.348 +  if(ve->curmark>=beginW && ve->curmark<endW)return(1);
 612.349 +  {
 612.350 +    long first=beginW/ve->searchstep;
 612.351 +    long last=endW/ve->searchstep;
 612.352 +    long i;
 612.353 +    for(i=first;i<last;i++)
 612.354 +      if(ve->mark[i])return(1);
 612.355 +  }
 612.356 +  return(0);
 612.357 +}
 612.358 +
 612.359 +void _ve_envelope_shift(envelope_lookup *e,long shift){
 612.360 +  int smallsize=e->current/e->searchstep+VE_POST; /* adjust for placing marks
 612.361 +                                                     ahead of ve->current */
 612.362 +  int smallshift=shift/e->searchstep;
 612.363 +
 612.364 +  memmove(e->mark,e->mark+smallshift,(smallsize-smallshift)*sizeof(*e->mark));
 612.365 +
 612.366 +#if 0
 612.367 +  for(i=0;i<VE_BANDS*e->ch;i++)
 612.368 +    memmove(e->filter[i].markers,
 612.369 +            e->filter[i].markers+smallshift,
 612.370 +            (1024-smallshift)*sizeof(*(*e->filter).markers));
 612.371 +  totalshift+=shift;
 612.372 +#endif
 612.373 +
 612.374 +  e->current-=shift;
 612.375 +  if(e->curmark>=0)
 612.376 +    e->curmark-=shift;
 612.377 +  e->cursor-=shift;
 612.378 +}
   613.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   613.2 +++ b/libs/vorbis/envelope.h	Sat Feb 01 19:58:19 2014 +0200
   613.3 @@ -0,0 +1,80 @@
   613.4 +/********************************************************************
   613.5 + *                                                                  *
   613.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   613.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   613.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   613.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  613.10 + *                                                                  *
  613.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  613.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  613.13 + *                                                                  *
  613.14 + ********************************************************************
  613.15 +
  613.16 + function: PCM data envelope analysis and manipulation
  613.17 + last mod: $Id: envelope.h 16227 2009-07-08 06:58:46Z xiphmont $
  613.18 +
  613.19 + ********************************************************************/
  613.20 +
  613.21 +#ifndef _V_ENVELOPE_
  613.22 +#define _V_ENVELOPE_
  613.23 +
  613.24 +#include "mdct.h"
  613.25 +
  613.26 +#define VE_PRE    16
  613.27 +#define VE_WIN    4
  613.28 +#define VE_POST   2
  613.29 +#define VE_AMP    (VE_PRE+VE_POST-1)
  613.30 +
  613.31 +#define VE_BANDS  7
  613.32 +#define VE_NEARDC 15
  613.33 +
  613.34 +#define VE_MINSTRETCH 2   /* a bit less than short block */
  613.35 +#define VE_MAXSTRETCH 12  /* one-third full block */
  613.36 +
  613.37 +typedef struct {
  613.38 +  float ampbuf[VE_AMP];
  613.39 +  int   ampptr;
  613.40 +
  613.41 +  float nearDC[VE_NEARDC];
  613.42 +  float nearDC_acc;
  613.43 +  float nearDC_partialacc;
  613.44 +  int   nearptr;
  613.45 +
  613.46 +} envelope_filter_state;
  613.47 +
  613.48 +typedef struct {
  613.49 +  int begin;
  613.50 +  int end;
  613.51 +  float *window;
  613.52 +  float total;
  613.53 +} envelope_band;
  613.54 +
  613.55 +typedef struct {
  613.56 +  int ch;
  613.57 +  int winlength;
  613.58 +  int searchstep;
  613.59 +  float minenergy;
  613.60 +
  613.61 +  mdct_lookup  mdct;
  613.62 +  float       *mdct_win;
  613.63 +
  613.64 +  envelope_band          band[VE_BANDS];
  613.65 +  envelope_filter_state *filter;
  613.66 +  int   stretch;
  613.67 +
  613.68 +  int                   *mark;
  613.69 +
  613.70 +  long storage;
  613.71 +  long current;
  613.72 +  long curmark;
  613.73 +  long cursor;
  613.74 +} envelope_lookup;
  613.75 +
  613.76 +extern void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi);
  613.77 +extern void _ve_envelope_clear(envelope_lookup *e);
  613.78 +extern long _ve_envelope_search(vorbis_dsp_state *v);
  613.79 +extern void _ve_envelope_shift(envelope_lookup *e,long shift);
  613.80 +extern int  _ve_envelope_mark(vorbis_dsp_state *v);
  613.81 +
  613.82 +
  613.83 +#endif
   614.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   614.2 +++ b/libs/vorbis/floor0.c	Sat Feb 01 19:58:19 2014 +0200
   614.3 @@ -0,0 +1,221 @@
   614.4 +/********************************************************************
   614.5 + *                                                                  *
   614.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   614.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   614.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   614.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  614.10 + *                                                                  *
  614.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  614.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  614.13 + *                                                                  *
  614.14 + ********************************************************************
  614.15 +
  614.16 + function: floor backend 0 implementation
  614.17 + last mod: $Id: floor0.c 18184 2012-02-03 20:55:12Z xiphmont $
  614.18 +
  614.19 + ********************************************************************/
  614.20 +
  614.21 +#include <stdlib.h>
  614.22 +#include <string.h>
  614.23 +#include <math.h>
  614.24 +#include <ogg/ogg.h>
  614.25 +#include "vorbis/codec.h"
  614.26 +#include "codec_internal.h"
  614.27 +#include "registry.h"
  614.28 +#include "lpc.h"
  614.29 +#include "lsp.h"
  614.30 +#include "codebook.h"
  614.31 +#include "scales.h"
  614.32 +#include "misc.h"
  614.33 +#include "os.h"
  614.34 +
  614.35 +#include "misc.h"
  614.36 +#include <stdio.h>
  614.37 +
  614.38 +typedef struct {
  614.39 +  int ln;
  614.40 +  int  m;
  614.41 +  int **linearmap;
  614.42 +  int  n[2];
  614.43 +
  614.44 +  vorbis_info_floor0 *vi;
  614.45 +
  614.46 +  long bits;
  614.47 +  long frames;
  614.48 +} vorbis_look_floor0;
  614.49 +
  614.50 +
  614.51 +/***********************************************/
  614.52 +
  614.53 +static void floor0_free_info(vorbis_info_floor *i){
  614.54 +  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
  614.55 +  if(info){
  614.56 +    memset(info,0,sizeof(*info));
  614.57 +    _ogg_free(info);
  614.58 +  }
  614.59 +}
  614.60 +
  614.61 +static void floor0_free_look(vorbis_look_floor *i){
  614.62 +  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
  614.63 +  if(look){
  614.64 +
  614.65 +    if(look->linearmap){
  614.66 +
  614.67 +      if(look->linearmap[0])_ogg_free(look->linearmap[0]);
  614.68 +      if(look->linearmap[1])_ogg_free(look->linearmap[1]);
  614.69 +
  614.70 +      _ogg_free(look->linearmap);
  614.71 +    }
  614.72 +    memset(look,0,sizeof(*look));
  614.73 +    _ogg_free(look);
  614.74 +  }
  614.75 +}
  614.76 +
  614.77 +static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
  614.78 +  codec_setup_info     *ci=vi->codec_setup;
  614.79 +  int j;
  614.80 +
  614.81 +  vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
  614.82 +  info->order=oggpack_read(opb,8);
  614.83 +  info->rate=oggpack_read(opb,16);
  614.84 +  info->barkmap=oggpack_read(opb,16);
  614.85 +  info->ampbits=oggpack_read(opb,6);
  614.86 +  info->ampdB=oggpack_read(opb,8);
  614.87 +  info->numbooks=oggpack_read(opb,4)+1;
  614.88 +
  614.89 +  if(info->order<1)goto err_out;
  614.90 +  if(info->rate<1)goto err_out;
  614.91 +  if(info->barkmap<1)goto err_out;
  614.92 +  if(info->numbooks<1)goto err_out;
  614.93 +
  614.94 +  for(j=0;j<info->numbooks;j++){
  614.95 +    info->books[j]=oggpack_read(opb,8);
  614.96 +    if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
  614.97 +    if(ci->book_param[info->books[j]]->maptype==0)goto err_out;
  614.98 +    if(ci->book_param[info->books[j]]->dim<1)goto err_out;
  614.99 +  }
 614.100 +  return(info);
 614.101 +
 614.102 + err_out:
 614.103 +  floor0_free_info(info);
 614.104 +  return(NULL);
 614.105 +}
 614.106 +
 614.107 +/* initialize Bark scale and normalization lookups.  We could do this
 614.108 +   with static tables, but Vorbis allows a number of possible
 614.109 +   combinations, so it's best to do it computationally.
 614.110 +
 614.111 +   The below is authoritative in terms of defining scale mapping.
 614.112 +   Note that the scale depends on the sampling rate as well as the
 614.113 +   linear block and mapping sizes */
 614.114 +
 614.115 +static void floor0_map_lazy_init(vorbis_block      *vb,
 614.116 +                                 vorbis_info_floor *infoX,
 614.117 +                                 vorbis_look_floor0 *look){
 614.118 +  if(!look->linearmap[vb->W]){
 614.119 +    vorbis_dsp_state   *vd=vb->vd;
 614.120 +    vorbis_info        *vi=vd->vi;
 614.121 +    codec_setup_info   *ci=vi->codec_setup;
 614.122 +    vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
 614.123 +    int W=vb->W;
 614.124 +    int n=ci->blocksizes[W]/2,j;
 614.125 +
 614.126 +    /* we choose a scaling constant so that:
 614.127 +       floor(bark(rate/2-1)*C)=mapped-1
 614.128 +     floor(bark(rate/2)*C)=mapped */
 614.129 +    float scale=look->ln/toBARK(info->rate/2.f);
 614.130 +
 614.131 +    /* the mapping from a linear scale to a smaller bark scale is
 614.132 +       straightforward.  We do *not* make sure that the linear mapping
 614.133 +       does not skip bark-scale bins; the decoder simply skips them and
 614.134 +       the encoder may do what it wishes in filling them.  They're
 614.135 +       necessary in some mapping combinations to keep the scale spacing
 614.136 +       accurate */
 614.137 +    look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
 614.138 +    for(j=0;j<n;j++){
 614.139 +      int val=floor( toBARK((info->rate/2.f)/n*j)
 614.140 +                     *scale); /* bark numbers represent band edges */
 614.141 +      if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
 614.142 +      look->linearmap[W][j]=val;
 614.143 +    }
 614.144 +    look->linearmap[W][j]=-1;
 614.145 +    look->n[W]=n;
 614.146 +  }
 614.147 +}
 614.148 +
 614.149 +static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
 614.150 +                                      vorbis_info_floor *i){
 614.151 +  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
 614.152 +  vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
 614.153 +  look->m=info->order;
 614.154 +  look->ln=info->barkmap;
 614.155 +  look->vi=info;
 614.156 +
 614.157 +  look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
 614.158 +
 614.159 +  return look;
 614.160 +}
 614.161 +
 614.162 +static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
 614.163 +  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
 614.164 +  vorbis_info_floor0 *info=look->vi;
 614.165 +  int j,k;
 614.166 +
 614.167 +  int ampraw=oggpack_read(&vb->opb,info->ampbits);
 614.168 +  if(ampraw>0){ /* also handles the -1 out of data case */
 614.169 +    long maxval=(1<<info->ampbits)-1;
 614.170 +    float amp=(float)ampraw/maxval*info->ampdB;
 614.171 +    int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
 614.172 +
 614.173 +    if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
 614.174 +      codec_setup_info  *ci=vb->vd->vi->codec_setup;
 614.175 +      codebook *b=ci->fullbooks+info->books[booknum];
 614.176 +      float last=0.f;
 614.177 +
 614.178 +      /* the additional b->dim is a guard against any possible stack
 614.179 +         smash; b->dim is provably more than we can overflow the
 614.180 +         vector */
 614.181 +      float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
 614.182 +
 614.183 +      if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop;
 614.184 +      for(j=0;j<look->m;){
 614.185 +        for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
 614.186 +        last=lsp[j-1];
 614.187 +      }
 614.188 +
 614.189 +      lsp[look->m]=amp;
 614.190 +      return(lsp);
 614.191 +    }
 614.192 +  }
 614.193 + eop:
 614.194 +  return(NULL);
 614.195 +}
 614.196 +
 614.197 +static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
 614.198 +                           void *memo,float *out){
 614.199 +  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
 614.200 +  vorbis_info_floor0 *info=look->vi;
 614.201 +
 614.202 +  floor0_map_lazy_init(vb,info,look);
 614.203 +
 614.204 +  if(memo){
 614.205 +    float *lsp=(float *)memo;
 614.206 +    float amp=lsp[look->m];
 614.207 +
 614.208 +    /* take the coefficients back to a spectral envelope curve */
 614.209 +    vorbis_lsp_to_curve(out,
 614.210 +                        look->linearmap[vb->W],
 614.211 +                        look->n[vb->W],
 614.212 +                        look->ln,
 614.213 +                        lsp,look->m,amp,(float)info->ampdB);
 614.214 +    return(1);
 614.215 +  }
 614.216 +  memset(out,0,sizeof(*out)*look->n[vb->W]);
 614.217 +  return(0);
 614.218 +}
 614.219 +
 614.220 +/* export hooks */
 614.221 +const vorbis_func_floor floor0_exportbundle={
 614.222 +  NULL,&floor0_unpack,&floor0_look,&floor0_free_info,
 614.223 +  &floor0_free_look,&floor0_inverse1,&floor0_inverse2
 614.224 +};
   615.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   615.2 +++ b/libs/vorbis/floor1.c	Sat Feb 01 19:58:19 2014 +0200
   615.3 @@ -0,0 +1,1100 @@
   615.4 +/********************************************************************
   615.5 + *                                                                  *
   615.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   615.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   615.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   615.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  615.10 + *                                                                  *
  615.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  615.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  615.13 + *                                                                  *
  615.14 + ********************************************************************
  615.15 +
  615.16 + function: floor backend 1 implementation
  615.17 + last mod: $Id: floor1.c 18151 2012-01-20 07:35:26Z xiphmont $
  615.18 +
  615.19 + ********************************************************************/
  615.20 +
  615.21 +#include <stdlib.h>
  615.22 +#include <string.h>
  615.23 +#include <math.h>
  615.24 +#include <ogg/ogg.h>
  615.25 +#include "vorbis/codec.h"
  615.26 +#include "codec_internal.h"
  615.27 +#include "registry.h"
  615.28 +#include "codebook.h"
  615.29 +#include "misc.h"
  615.30 +#include "scales.h"
  615.31 +
  615.32 +#include <stdio.h>
  615.33 +
  615.34 +#define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
  615.35 +
  615.36 +typedef struct lsfit_acc{
  615.37 +  int x0;
  615.38 +  int x1;
  615.39 +
  615.40 +  int xa;
  615.41 +  int ya;
  615.42 +  int x2a;
  615.43 +  int y2a;
  615.44 +  int xya;
  615.45 +  int an;
  615.46 +
  615.47 +  int xb;
  615.48 +  int yb;
  615.49 +  int x2b;
  615.50 +  int y2b;
  615.51 +  int xyb;
  615.52 +  int bn;
  615.53 +} lsfit_acc;
  615.54 +
  615.55 +/***********************************************/
  615.56 +
  615.57 +static void floor1_free_info(vorbis_info_floor *i){
  615.58 +  vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
  615.59 +  if(info){
  615.60 +    memset(info,0,sizeof(*info));
  615.61 +    _ogg_free(info);
  615.62 +  }
  615.63 +}
  615.64 +
  615.65 +static void floor1_free_look(vorbis_look_floor *i){
  615.66 +  vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
  615.67 +  if(look){
  615.68 +    /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n",
  615.69 +            (float)look->phrasebits/look->frames,
  615.70 +            (float)look->postbits/look->frames,
  615.71 +            (float)(look->postbits+look->phrasebits)/look->frames);*/
  615.72 +
  615.73 +    memset(look,0,sizeof(*look));
  615.74 +    _ogg_free(look);
  615.75 +  }
  615.76 +}
  615.77 +
  615.78 +static int ilog(unsigned int v){
  615.79 +  int ret=0;
  615.80 +  while(v){
  615.81 +    ret++;
  615.82 +    v>>=1;
  615.83 +  }
  615.84 +  return(ret);
  615.85 +}
  615.86 +
  615.87 +static int ilog2(unsigned int v){
  615.88 +  int ret=0;
  615.89 +  if(v)--v;
  615.90 +  while(v){
  615.91 +    ret++;
  615.92 +    v>>=1;
  615.93 +  }
  615.94 +  return(ret);
  615.95 +}
  615.96 +
  615.97 +static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
  615.98 +  vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
  615.99 +  int j,k;
 615.100 +  int count=0;
 615.101 +  int rangebits;
 615.102 +  int maxposit=info->postlist[1];
 615.103 +  int maxclass=-1;
 615.104 +
 615.105 +  /* save out partitions */
 615.106 +  oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */
 615.107 +  for(j=0;j<info->partitions;j++){
 615.108 +    oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */
 615.109 +    if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
 615.110 +  }
 615.111 +
 615.112 +  /* save out partition classes */
 615.113 +  for(j=0;j<maxclass+1;j++){
 615.114 +    oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
 615.115 +    oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
 615.116 +    if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
 615.117 +    for(k=0;k<(1<<info->class_subs[j]);k++)
 615.118 +      oggpack_write(opb,info->class_subbook[j][k]+1,8);
 615.119 +  }
 615.120 +
 615.121 +  /* save out the post list */
 615.122 +  oggpack_write(opb,info->mult-1,2);     /* only 1,2,3,4 legal now */
 615.123 +  oggpack_write(opb,ilog2(maxposit),4);
 615.124 +  rangebits=ilog2(maxposit);
 615.125 +
 615.126 +  for(j=0,k=0;j<info->partitions;j++){
 615.127 +    count+=info->class_dim[info->partitionclass[j]];
 615.128 +    for(;k<count;k++)
 615.129 +      oggpack_write(opb,info->postlist[k+2],rangebits);
 615.130 +  }
 615.131 +}
 615.132 +
 615.133 +static int icomp(const void *a,const void *b){
 615.134 +  return(**(int **)a-**(int **)b);
 615.135 +}
 615.136 +
 615.137 +static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
 615.138 +  codec_setup_info     *ci=vi->codec_setup;
 615.139 +  int j,k,count=0,maxclass=-1,rangebits;
 615.140 +
 615.141 +  vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info));
 615.142 +  /* read partitions */
 615.143 +  info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
 615.144 +  for(j=0;j<info->partitions;j++){
 615.145 +    info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
 615.146 +    if(info->partitionclass[j]<0)goto err_out;
 615.147 +    if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
 615.148 +  }
 615.149 +
 615.150 +  /* read partition classes */
 615.151 +  for(j=0;j<maxclass+1;j++){
 615.152 +    info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
 615.153 +    info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
 615.154 +    if(info->class_subs[j]<0)
 615.155 +      goto err_out;
 615.156 +    if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
 615.157 +    if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
 615.158 +      goto err_out;
 615.159 +    for(k=0;k<(1<<info->class_subs[j]);k++){
 615.160 +      info->class_subbook[j][k]=oggpack_read(opb,8)-1;
 615.161 +      if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
 615.162 +        goto err_out;
 615.163 +    }
 615.164 +  }
 615.165 +
 615.166 +  /* read the post list */
 615.167 +  info->mult=oggpack_read(opb,2)+1;     /* only 1,2,3,4 legal now */
 615.168 +  rangebits=oggpack_read(opb,4);
 615.169 +  if(rangebits<0)goto err_out;
 615.170 +
 615.171 +  for(j=0,k=0;j<info->partitions;j++){
 615.172 +    count+=info->class_dim[info->partitionclass[j]];
 615.173 +    if(count>VIF_POSIT) goto err_out;
 615.174 +    for(;k<count;k++){
 615.175 +      int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
 615.176 +      if(t<0 || t>=(1<<rangebits))
 615.177 +        goto err_out;
 615.178 +    }
 615.179 +  }
 615.180 +  info->postlist[0]=0;
 615.181 +  info->postlist[1]=1<<rangebits;
 615.182 +
 615.183 +  /* don't allow repeated values in post list as they'd result in
 615.184 +     zero-length segments */
 615.185 +  {
 615.186 +    int *sortpointer[VIF_POSIT+2];
 615.187 +    for(j=0;j<count+2;j++)sortpointer[j]=info->postlist+j;
 615.188 +    qsort(sortpointer,count+2,sizeof(*sortpointer),icomp);
 615.189 +
 615.190 +    for(j=1;j<count+2;j++)
 615.191 +      if(*sortpointer[j-1]==*sortpointer[j])goto err_out;
 615.192 +  }
 615.193 +
 615.194 +  return(info);
 615.195 +
 615.196 + err_out:
 615.197 +  floor1_free_info(info);
 615.198 +  return(NULL);
 615.199 +}
 615.200 +
 615.201 +static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,
 615.202 +                                      vorbis_info_floor *in){
 615.203 +
 615.204 +  int *sortpointer[VIF_POSIT+2];
 615.205 +  vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
 615.206 +  vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(*look));
 615.207 +  int i,j,n=0;
 615.208 +
 615.209 +  look->vi=info;
 615.210 +  look->n=info->postlist[1];
 615.211 +
 615.212 +  /* we drop each position value in-between already decoded values,
 615.213 +     and use linear interpolation to predict each new value past the
 615.214 +     edges.  The positions are read in the order of the position
 615.215 +     list... we precompute the bounding positions in the lookup.  Of
 615.216 +     course, the neighbors can change (if a position is declined), but
 615.217 +     this is an initial mapping */
 615.218 +
 615.219 +  for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
 615.220 +  n+=2;
 615.221 +  look->posts=n;
 615.222 +
 615.223 +  /* also store a sorted position index */
 615.224 +  for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
 615.225 +  qsort(sortpointer,n,sizeof(*sortpointer),icomp);
 615.226 +
 615.227 +  /* points from sort order back to range number */
 615.228 +  for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
 615.229 +  /* points from range order to sorted position */
 615.230 +  for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
 615.231 +  /* we actually need the post values too */
 615.232 +  for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
 615.233 +
 615.234 +  /* quantize values to multiplier spec */
 615.235 +  switch(info->mult){
 615.236 +  case 1: /* 1024 -> 256 */
 615.237 +    look->quant_q=256;
 615.238 +    break;
 615.239 +  case 2: /* 1024 -> 128 */
 615.240 +    look->quant_q=128;
 615.241 +    break;
 615.242 +  case 3: /* 1024 -> 86 */
 615.243 +    look->quant_q=86;
 615.244 +    break;
 615.245 +  case 4: /* 1024 -> 64 */
 615.246 +    look->quant_q=64;
 615.247 +    break;
 615.248 +  }
 615.249 +
 615.250 +  /* discover our neighbors for decode where we don't use fit flags
 615.251 +     (that would push the neighbors outward) */
 615.252 +  for(i=0;i<n-2;i++){
 615.253 +    int lo=0;
 615.254 +    int hi=1;
 615.255 +    int lx=0;
 615.256 +    int hx=look->n;
 615.257 +    int currentx=info->postlist[i+2];
 615.258 +    for(j=0;j<i+2;j++){
 615.259 +      int x=info->postlist[j];
 615.260 +      if(x>lx && x<currentx){
 615.261 +        lo=j;
 615.262 +        lx=x;
 615.263 +      }
 615.264 +      if(x<hx && x>currentx){
 615.265 +        hi=j;
 615.266 +        hx=x;
 615.267 +      }
 615.268 +    }
 615.269 +    look->loneighbor[i]=lo;
 615.270 +    look->hineighbor[i]=hi;
 615.271 +  }
 615.272 +
 615.273 +  return(look);
 615.274 +}
 615.275 +
 615.276 +static int render_point(int x0,int x1,int y0,int y1,int x){
 615.277 +  y0&=0x7fff; /* mask off flag */
 615.278 +  y1&=0x7fff;
 615.279 +
 615.280 +  {
 615.281 +    int dy=y1-y0;
 615.282 +    int adx=x1-x0;
 615.283 +    int ady=abs(dy);
 615.284 +    int err=ady*(x-x0);
 615.285 +
 615.286 +    int off=err/adx;
 615.287 +    if(dy<0)return(y0-off);
 615.288 +    return(y0+off);
 615.289 +  }
 615.290 +}
 615.291 +
 615.292 +static int vorbis_dBquant(const float *x){
 615.293 +  int i= *x*7.3142857f+1023.5f;
 615.294 +  if(i>1023)return(1023);
 615.295 +  if(i<0)return(0);
 615.296 +  return i;
 615.297 +}
 615.298 +
 615.299 +static const float FLOOR1_fromdB_LOOKUP[256]={
 615.300 +  1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
 615.301 +  1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
 615.302 +  1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
 615.303 +  2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
 615.304 +  2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
 615.305 +  3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
 615.306 +  4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
 615.307 +  6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
 615.308 +  7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
 615.309 +  1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
 615.310 +  1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
 615.311 +  1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
 615.312 +  2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
 615.313 +  2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
 615.314 +  3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
 615.315 +  4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
 615.316 +  5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
 615.317 +  7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
 615.318 +  9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
 615.319 +  1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
 615.320 +  1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
 615.321 +  2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
 615.322 +  2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
 615.323 +  3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
 615.324 +  4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
 615.325 +  5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
 615.326 +  7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
 615.327 +  9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
 615.328 +  0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
 615.329 +  0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
 615.330 +  0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
 615.331 +  0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
 615.332 +  0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
 615.333 +  0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
 615.334 +  0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
 615.335 +  0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
 615.336 +  0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
 615.337 +  0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
 615.338 +  0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
 615.339 +  0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
 615.340 +  0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
 615.341 +  0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
 615.342 +  0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
 615.343 +  0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
 615.344 +  0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
 615.345 +  0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
 615.346 +  0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
 615.347 +  0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
 615.348 +  0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
 615.349 +  0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
 615.350 +  0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
 615.351 +  0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
 615.352 +  0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
 615.353 +  0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
 615.354 +  0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
 615.355 +  0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
 615.356 +  0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
 615.357 +  0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
 615.358 +  0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
 615.359 +  0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
 615.360 +  0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
 615.361 +  0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
 615.362 +  0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
 615.363 +  0.82788260F, 0.88168307F, 0.9389798F, 1.F,
 615.364 +};
 615.365 +
 615.366 +static void render_line(int n, int x0,int x1,int y0,int y1,float *d){
 615.367 +  int dy=y1-y0;
 615.368 +  int adx=x1-x0;
 615.369 +  int ady=abs(dy);
 615.370 +  int base=dy/adx;
 615.371 +  int sy=(dy<0?base-1:base+1);
 615.372 +  int x=x0;
 615.373 +  int y=y0;
 615.374 +  int err=0;
 615.375 +
 615.376 +  ady-=abs(base*adx);
 615.377 +
 615.378 +  if(n>x1)n=x1;
 615.379 +
 615.380 +  if(x<n)
 615.381 +    d[x]*=FLOOR1_fromdB_LOOKUP[y];
 615.382 +
 615.383 +  while(++x<n){
 615.384 +    err=err+ady;
 615.385 +    if(err>=adx){
 615.386 +      err-=adx;
 615.387 +      y+=sy;
 615.388 +    }else{
 615.389 +      y+=base;
 615.390 +    }
 615.391 +    d[x]*=FLOOR1_fromdB_LOOKUP[y];
 615.392 +  }
 615.393 +}
 615.394 +
 615.395 +static void render_line0(int n, int x0,int x1,int y0,int y1,int *d){
 615.396 +  int dy=y1-y0;
 615.397 +  int adx=x1-x0;
 615.398 +  int ady=abs(dy);
 615.399 +  int base=dy/adx;
 615.400 +  int sy=(dy<0?base-1:base+1);
 615.401 +  int x=x0;
 615.402 +  int y=y0;
 615.403 +  int err=0;
 615.404 +
 615.405 +  ady-=abs(base*adx);
 615.406 +
 615.407 +  if(n>x1)n=x1;
 615.408 +
 615.409 +  if(x<n)
 615.410 +    d[x]=y;
 615.411 +
 615.412 +  while(++x<n){
 615.413 +    err=err+ady;
 615.414 +    if(err>=adx){
 615.415 +      err-=adx;
 615.416 +      y+=sy;
 615.417 +    }else{
 615.418 +      y+=base;
 615.419 +    }
 615.420 +    d[x]=y;
 615.421 +  }
 615.422 +}
 615.423 +
 615.424 +/* the floor has already been filtered to only include relevant sections */
 615.425 +static int accumulate_fit(const float *flr,const float *mdct,
 615.426 +                          int x0, int x1,lsfit_acc *a,
 615.427 +                          int n,vorbis_info_floor1 *info){
 615.428 +  long i;
 615.429 +
 615.430 +  int xa=0,ya=0,x2a=0,y2a=0,xya=0,na=0, xb=0,yb=0,x2b=0,y2b=0,xyb=0,nb=0;
 615.431 +
 615.432 +  memset(a,0,sizeof(*a));
 615.433 +  a->x0=x0;
 615.434 +  a->x1=x1;
 615.435 +  if(x1>=n)x1=n-1;
 615.436 +
 615.437 +  for(i=x0;i<=x1;i++){
 615.438 +    int quantized=vorbis_dBquant(flr+i);
 615.439 +    if(quantized){
 615.440 +      if(mdct[i]+info->twofitatten>=flr[i]){
 615.441 +        xa  += i;
 615.442 +        ya  += quantized;
 615.443 +        x2a += i*i;
 615.444 +        y2a += quantized*quantized;
 615.445 +        xya += i*quantized;
 615.446 +        na++;
 615.447 +      }else{
 615.448 +        xb  += i;
 615.449 +        yb  += quantized;
 615.450 +        x2b += i*i;
 615.451 +        y2b += quantized*quantized;
 615.452 +        xyb += i*quantized;
 615.453 +        nb++;
 615.454 +      }
 615.455 +    }
 615.456 +  }
 615.457 +
 615.458 +  a->xa=xa;
 615.459 +  a->ya=ya;
 615.460 +  a->x2a=x2a;
 615.461 +  a->y2a=y2a;
 615.462 +  a->xya=xya;
 615.463 +  a->an=na;
 615.464 +
 615.465 +  a->xb=xb;
 615.466 +  a->yb=yb;
 615.467 +  a->x2b=x2b;
 615.468 +  a->y2b=y2b;
 615.469 +  a->xyb=xyb;
 615.470 +  a->bn=nb;
 615.471 +
 615.472 +  return(na);
 615.473 +}
 615.474 +
 615.475 +static int fit_line(lsfit_acc *a,int fits,int *y0,int *y1,
 615.476 +                    vorbis_info_floor1 *info){
 615.477 +  double xb=0,yb=0,x2b=0,y2b=0,xyb=0,bn=0;
 615.478 +  int i;
 615.479 +  int x0=a[0].x0;
 615.480 +  int x1=a[fits-1].x1;
 615.481 +
 615.482 +  for(i=0;i<fits;i++){
 615.483 +    double weight = (a[i].bn+a[i].an)*info->twofitweight/(a[i].an+1)+1.;
 615.484 +
 615.485 +    xb+=a[i].xb + a[i].xa * weight;
 615.486 +    yb+=a[i].yb + a[i].ya * weight;
 615.487 +    x2b+=a[i].x2b + a[i].x2a * weight;
 615.488 +    y2b+=a[i].y2b + a[i].y2a * weight;
 615.489 +    xyb+=a[i].xyb + a[i].xya * weight;
 615.490 +    bn+=a[i].bn + a[i].an * weight;
 615.491 +  }
 615.492 +
 615.493 +  if(*y0>=0){
 615.494 +    xb+=   x0;
 615.495 +    yb+=  *y0;
 615.496 +    x2b+=  x0 *  x0;
 615.497 +    y2b+= *y0 * *y0;
 615.498 +    xyb+= *y0 *  x0;
 615.499 +    bn++;
 615.500 +  }
 615.501 +
 615.502 +  if(*y1>=0){
 615.503 +    xb+=   x1;
 615.504 +    yb+=  *y1;
 615.505 +    x2b+=  x1 *  x1;
 615.506 +    y2b+= *y1 * *y1;
 615.507 +    xyb+= *y1 *  x1;
 615.508 +    bn++;
 615.509 +  }
 615.510 +
 615.511 +  {
 615.512 +    double denom=(bn*x2b-xb*xb);
 615.513 +
 615.514 +    if(denom>0.){
 615.515 +      double a=(yb*x2b-xyb*xb)/denom;
 615.516 +      double b=(bn*xyb-xb*yb)/denom;
 615.517 +      *y0=rint(a+b*x0);
 615.518 +      *y1=rint(a+b*x1);
 615.519 +
 615.520 +      /* limit to our range! */
 615.521 +      if(*y0>1023)*y0=1023;
 615.522 +      if(*y1>1023)*y1=1023;
 615.523 +      if(*y0<0)*y0=0;
 615.524 +      if(*y1<0)*y1=0;
 615.525 +
 615.526 +      return 0;
 615.527 +    }else{
 615.528 +      *y0=0;
 615.529 +      *y1=0;
 615.530 +      return 1;
 615.531 +    }
 615.532 +  }
 615.533 +}
 615.534 +
 615.535 +static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
 615.536 +                         const float *mdct,
 615.537 +                         vorbis_info_floor1 *info){
 615.538 +  int dy=y1-y0;
 615.539 +  int adx=x1-x0;
 615.540 +  int ady=abs(dy);
 615.541 +  int base=dy/adx;
 615.542 +  int sy=(dy<0?base-1:base+1);
 615.543 +  int x=x0;
 615.544 +  int y=y0;
 615.545 +  int err=0;
 615.546 +  int val=vorbis_dBquant(mask+x);
 615.547 +  int mse=0;
 615.548 +  int n=0;
 615.549 +
 615.550 +  ady-=abs(base*adx);
 615.551 +
 615.552 +  mse=(y-val);
 615.553 +  mse*=mse;
 615.554 +  n++;
 615.555 +  if(mdct[x]+info->twofitatten>=mask[x]){
 615.556 +    if(y+info->maxover<val)return(1);
 615.557 +    if(y-info->maxunder>val)return(1);
 615.558 +  }
 615.559 +
 615.560 +  while(++x<x1){
 615.561 +    err=err+ady;
 615.562 +    if(err>=adx){
 615.563 +      err-=adx;
 615.564 +      y+=sy;
 615.565 +    }else{
 615.566 +      y+=base;
 615.567 +    }
 615.568 +
 615.569 +    val=vorbis_dBquant(mask+x);
 615.570 +    mse+=((y-val)*(y-val));
 615.571 +    n++;
 615.572 +    if(mdct[x]+info->twofitatten>=mask[x]){
 615.573 +      if(val){
 615.574 +        if(y+info->maxover<val)return(1);
 615.575 +        if(y-info->maxunder>val)return(1);
 615.576 +      }
 615.577 +    }
 615.578 +  }
 615.579 +
 615.580 +  if(info->maxover*info->maxover/n>info->maxerr)return(0);
 615.581 +  if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
 615.582 +  if(mse/n>info->maxerr)return(1);
 615.583 +  return(0);
 615.584 +}
 615.585 +
 615.586 +static int post_Y(int *A,int *B,int pos){
 615.587 +  if(A[pos]<0)
 615.588 +    return B[pos];
 615.589 +  if(B[pos]<0)
 615.590 +    return A[pos];
 615.591 +
 615.592 +  return (A[pos]+B[pos])>>1;
 615.593 +}
 615.594 +
 615.595 +int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
 615.596 +                          const float *logmdct,   /* in */
 615.597 +                          const float *logmask){
 615.598 +  long i,j;
 615.599 +  vorbis_info_floor1 *info=look->vi;
 615.600 +  long n=look->n;
 615.601 +  long posts=look->posts;
 615.602 +  long nonzero=0;
 615.603 +  lsfit_acc fits[VIF_POSIT+1];
 615.604 +  int fit_valueA[VIF_POSIT+2]; /* index by range list position */
 615.605 +  int fit_valueB[VIF_POSIT+2]; /* index by range list position */
 615.606 +
 615.607 +  int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
 615.608 +  int hineighbor[VIF_POSIT+2];
 615.609 +  int *output=NULL;
 615.610 +  int memo[VIF_POSIT+2];
 615.611 +
 615.612 +  for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
 615.613 +  for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
 615.614 +  for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
 615.615 +  for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
 615.616 +  for(i=0;i<posts;i++)memo[i]=-1;      /* no neighbor yet */
 615.617 +
 615.618 +  /* quantize the relevant floor points and collect them into line fit
 615.619 +     structures (one per minimal division) at the same time */
 615.620 +  if(posts==0){
 615.621 +    nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
 615.622 +  }else{
 615.623 +    for(i=0;i<posts-1;i++)
 615.624 +      nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
 615.625 +                              look->sorted_index[i+1],fits+i,
 615.626 +                              n,info);
 615.627 +  }
 615.628 +
 615.629 +  if(nonzero){
 615.630 +    /* start by fitting the implicit base case.... */
 615.631 +    int y0=-200;
 615.632 +    int y1=-200;
 615.633 +    fit_line(fits,posts-1,&y0,&y1,info);
 615.634 +
 615.635 +    fit_valueA[0]=y0;
 615.636 +    fit_valueB[0]=y0;
 615.637 +    fit_valueB[1]=y1;
 615.638 +    fit_valueA[1]=y1;
 615.639 +
 615.640 +    /* Non degenerate case */
 615.641 +    /* start progressive splitting.  This is a greedy, non-optimal
 615.642 +       algorithm, but simple and close enough to the best
 615.643 +       answer. */
 615.644 +    for(i=2;i<posts;i++){
 615.645 +      int sortpos=look->reverse_index[i];
 615.646 +      int ln=loneighbor[sortpos];
 615.647 +      int hn=hineighbor[sortpos];
 615.648 +
 615.649 +      /* eliminate repeat searches of a particular range with a memo */
 615.650 +      if(memo[ln]!=hn){
 615.651 +        /* haven't performed this error search yet */
 615.652 +        int lsortpos=look->reverse_index[ln];
 615.653 +        int hsortpos=look->reverse_index[hn];
 615.654 +        memo[ln]=hn;
 615.655 +
 615.656 +        {
 615.657 +          /* A note: we want to bound/minimize *local*, not global, error */
 615.658 +          int lx=info->postlist[ln];
 615.659 +          int hx=info->postlist[hn];
 615.660 +          int ly=post_Y(fit_valueA,fit_valueB,ln);
 615.661 +          int hy=post_Y(fit_valueA,fit_valueB,hn);
 615.662 +
 615.663 +          if(ly==-1 || hy==-1){
 615.664 +            exit(1);
 615.665 +          }
 615.666 +
 615.667 +          if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
 615.668 +            /* outside error bounds/begin search area.  Split it. */
 615.669 +            int ly0=-200;
 615.670 +            int ly1=-200;
 615.671 +            int hy0=-200;
 615.672 +            int hy1=-200;
 615.673 +            int ret0=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1,info);
 615.674 +            int ret1=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1,info);
 615.675 +
 615.676 +            if(ret0){
 615.677 +              ly0=ly;
 615.678 +              ly1=hy0;
 615.679 +            }
 615.680 +            if(ret1){
 615.681 +              hy0=ly1;
 615.682 +              hy1=hy;
 615.683 +            }
 615.684 +
 615.685 +            if(ret0 && ret1){
 615.686 +              fit_valueA[i]=-200;
 615.687 +              fit_valueB[i]=-200;
 615.688 +            }else{
 615.689 +              /* store new edge values */
 615.690 +              fit_valueB[ln]=ly0;
 615.691 +              if(ln==0)fit_valueA[ln]=ly0;
 615.692 +              fit_valueA[i]=ly1;
 615.693 +              fit_valueB[i]=hy0;
 615.694 +              fit_valueA[hn]=hy1;
 615.695 +              if(hn==1)fit_valueB[hn]=hy1;
 615.696 +
 615.697 +              if(ly1>=0 || hy0>=0){
 615.698 +                /* store new neighbor values */
 615.699 +                for(j=sortpos-1;j>=0;j--)
 615.700 +                  if(hineighbor[j]==hn)
 615.701 +                    hineighbor[j]=i;
 615.702 +                  else
 615.703 +                    break;
 615.704 +                for(j=sortpos+1;j<posts;j++)
 615.705 +                  if(loneighbor[j]==ln)
 615.706 +                    loneighbor[j]=i;
 615.707 +                  else
 615.708 +                    break;
 615.709 +              }
 615.710 +            }
 615.711 +          }else{
 615.712 +            fit_valueA[i]=-200;
 615.713 +            fit_valueB[i]=-200;
 615.714 +          }
 615.715 +        }
 615.716 +      }
 615.717 +    }
 615.718 +
 615.719 +    output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
 615.720 +
 615.721 +    output[0]=post_Y(fit_valueA,fit_valueB,0);
 615.722 +    output[1]=post_Y(fit_valueA,fit_valueB,1);
 615.723 +
 615.724 +    /* fill in posts marked as not using a fit; we will zero
 615.725 +       back out to 'unused' when encoding them so long as curve
 615.726 +       interpolation doesn't force them into use */
 615.727 +    for(i=2;i<posts;i++){
 615.728 +      int ln=look->loneighbor[i-2];
 615.729 +      int hn=look->hineighbor[i-2];
 615.730 +      int x0=info->postlist[ln];
 615.731 +      int x1=info->postlist[hn];
 615.732 +      int y0=output[ln];
 615.733 +      int y1=output[hn];
 615.734 +
 615.735 +      int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
 615.736 +      int vx=post_Y(fit_valueA,fit_valueB,i);
 615.737 +
 615.738 +      if(vx>=0 && predicted!=vx){
 615.739 +        output[i]=vx;
 615.740 +      }else{
 615.741 +        output[i]= predicted|0x8000;
 615.742 +      }
 615.743 +    }
 615.744 +  }
 615.745 +
 615.746 +  return(output);
 615.747 +
 615.748 +}
 615.749 +
 615.750 +int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
 615.751 +                          int *A,int *B,
 615.752 +                          int del){
 615.753 +
 615.754 +  long i;
 615.755 +  long posts=look->posts;
 615.756 +  int *output=NULL;
 615.757 +
 615.758 +  if(A && B){
 615.759 +    output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
 615.760 +
 615.761 +    /* overly simpleminded--- look again post 1.2 */
 615.762 +    for(i=0;i<posts;i++){
 615.763 +      output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
 615.764 +      if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
 615.765 +    }
 615.766 +  }
 615.767 +
 615.768 +  return(output);
 615.769 +}
 615.770 +
 615.771 +
 615.772 +int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
 615.773 +                  vorbis_look_floor1 *look,
 615.774 +                  int *post,int *ilogmask){
 615.775 +
 615.776 +  long i,j;
 615.777 +  vorbis_info_floor1 *info=look->vi;
 615.778 +  long posts=look->posts;
 615.779 +  codec_setup_info *ci=vb->vd->vi->codec_setup;
 615.780 +  int out[VIF_POSIT+2];
 615.781 +  static_codebook **sbooks=ci->book_param;
 615.782 +  codebook *books=ci->fullbooks;
 615.783 +
 615.784 +  /* quantize values to multiplier spec */
 615.785 +  if(post){
 615.786 +    for(i=0;i<posts;i++){
 615.787 +      int val=post[i]&0x7fff;
 615.788 +      switch(info->mult){
 615.789 +      case 1: /* 1024 -> 256 */
 615.790 +        val>>=2;
 615.791 +        break;
 615.792 +      case 2: /* 1024 -> 128 */
 615.793 +        val>>=3;
 615.794 +        break;
 615.795 +      case 3: /* 1024 -> 86 */
 615.796 +        val/=12;
 615.797 +        break;
 615.798 +      case 4: /* 1024 -> 64 */
 615.799 +        val>>=4;
 615.800 +        break;
 615.801 +      }
 615.802 +      post[i]=val | (post[i]&0x8000);
 615.803 +    }
 615.804 +
 615.805 +    out[0]=post[0];
 615.806 +    out[1]=post[1];
 615.807 +
 615.808 +    /* find prediction values for each post and subtract them */
 615.809 +    for(i=2;i<posts;i++){
 615.810 +      int ln=look->loneighbor[i-2];
 615.811 +      int hn=look->hineighbor[i-2];
 615.812 +      int x0=info->postlist[ln];
 615.813 +      int x1=info->postlist[hn];
 615.814 +      int y0=post[ln];
 615.815 +      int y1=post[hn];
 615.816 +
 615.817 +      int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
 615.818 +
 615.819 +      if((post[i]&0x8000) || (predicted==post[i])){
 615.820 +        post[i]=predicted|0x8000; /* in case there was roundoff jitter
 615.821 +                                     in interpolation */
 615.822 +        out[i]=0;
 615.823 +      }else{
 615.824 +        int headroom=(look->quant_q-predicted<predicted?
 615.825 +                      look->quant_q-predicted:predicted);
 615.826 +
 615.827 +        int val=post[i]-predicted;
 615.828 +
 615.829 +        /* at this point the 'deviation' value is in the range +/- max
 615.830 +           range, but the real, unique range can always be mapped to
 615.831 +           only [0-maxrange).  So we want to wrap the deviation into
 615.832 +           this limited range, but do it in the way that least screws
 615.833 +           an essentially gaussian probability distribution. */
 615.834 +
 615.835 +        if(val<0)
 615.836 +          if(val<-headroom)
 615.837 +            val=headroom-val-1;
 615.838 +          else
 615.839 +            val=-1-(val<<1);
 615.840 +        else
 615.841 +          if(val>=headroom)
 615.842 +            val= val+headroom;
 615.843 +          else
 615.844 +            val<<=1;
 615.845 +
 615.846 +        out[i]=val;
 615.847 +        post[ln]&=0x7fff;
 615.848 +        post[hn]&=0x7fff;
 615.849 +      }
 615.850 +    }
 615.851 +
 615.852 +    /* we have everything we need. pack it out */
 615.853 +    /* mark nontrivial floor */
 615.854 +    oggpack_write(opb,1,1);
 615.855 +
 615.856 +    /* beginning/end post */
 615.857 +    look->frames++;
 615.858 +    look->postbits+=ilog(look->quant_q-1)*2;
 615.859 +    oggpack_write(opb,out[0],ilog(look->quant_q-1));
 615.860 +    oggpack_write(opb,out[1],ilog(look->quant_q-1));
 615.861 +
 615.862 +
 615.863 +    /* partition by partition */
 615.864 +    for(i=0,j=2;i<info->partitions;i++){
 615.865 +      int class=info->partitionclass[i];
 615.866 +      int cdim=info->class_dim[class];
 615.867 +      int csubbits=info->class_subs[class];
 615.868 +      int csub=1<<csubbits;
 615.869 +      int bookas[8]={0,0,0,0,0,0,0,0};
 615.870 +      int cval=0;
 615.871 +      int cshift=0;
 615.872 +      int k,l;
 615.873 +
 615.874 +      /* generate the partition's first stage cascade value */
 615.875 +      if(csubbits){
 615.876 +        int maxval[8];
 615.877 +        for(k=0;k<csub;k++){
 615.878 +          int booknum=info->class_subbook[class][k];
 615.879 +          if(booknum<0){
 615.880 +            maxval[k]=1;
 615.881 +          }else{
 615.882 +            maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
 615.883 +          }
 615.884 +        }
 615.885 +        for(k=0;k<cdim;k++){
 615.886 +          for(l=0;l<csub;l++){
 615.887 +            int val=out[j+k];
 615.888 +            if(val<maxval[l]){
 615.889 +              bookas[k]=l;
 615.890 +              break;
 615.891 +            }
 615.892 +          }
 615.893 +          cval|= bookas[k]<<cshift;
 615.894 +          cshift+=csubbits;
 615.895 +        }
 615.896 +        /* write it */
 615.897 +        look->phrasebits+=
 615.898 +          vorbis_book_encode(books+info->class_book[class],cval,opb);
 615.899 +
 615.900 +#ifdef TRAIN_FLOOR1
 615.901 +        {
 615.902 +          FILE *of;
 615.903 +          char buffer[80];
 615.904 +          sprintf(buffer,"line_%dx%ld_class%d.vqd",
 615.905 +                  vb->pcmend/2,posts-2,class);
 615.906 +          of=fopen(buffer,"a");
 615.907 +          fprintf(of,"%d\n",cval);
 615.908 +          fclose(of);
 615.909 +        }
 615.910 +#endif
 615.911 +      }
 615.912 +
 615.913 +      /* write post values */
 615.914 +      for(k=0;k<cdim;k++){
 615.915 +        int book=info->class_subbook[class][bookas[k]];
 615.916 +        if(book>=0){
 615.917 +          /* hack to allow training with 'bad' books */
 615.918 +          if(out[j+k]<(books+book)->entries)
 615.919 +            look->postbits+=vorbis_book_encode(books+book,
 615.920 +                                               out[j+k],opb);
 615.921 +          /*else
 615.922 +            fprintf(stderr,"+!");*/
 615.923 +
 615.924 +#ifdef TRAIN_FLOOR1
 615.925 +          {
 615.926 +            FILE *of;
 615.927 +            char buffer[80];
 615.928 +            sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
 615.929 +                    vb->pcmend/2,posts-2,class,bookas[k]);
 615.930 +            of=fopen(buffer,"a");
 615.931 +            fprintf(of,"%d\n",out[j+k]);
 615.932 +            fclose(of);
 615.933 +          }
 615.934 +#endif
 615.935 +        }
 615.936 +      }
 615.937 +      j+=cdim;
 615.938 +    }
 615.939 +
 615.940 +    {
 615.941 +      /* generate quantized floor equivalent to what we'd unpack in decode */
 615.942 +      /* render the lines */
 615.943 +      int hx=0;
 615.944 +      int lx=0;
 615.945 +      int ly=post[0]*info->mult;
 615.946 +      int n=ci->blocksizes[vb->W]/2;
 615.947 +
 615.948 +      for(j=1;j<look->posts;j++){
 615.949 +        int current=look->forward_index[j];
 615.950 +        int hy=post[current]&0x7fff;
 615.951 +        if(hy==post[current]){
 615.952 +
 615.953 +          hy*=info->mult;
 615.954 +          hx=info->postlist[current];
 615.955 +
 615.956 +          render_line0(n,lx,hx,ly,hy,ilogmask);
 615.957 +
 615.958 +          lx=hx;
 615.959 +          ly=hy;
 615.960 +        }
 615.961 +      }
 615.962 +      for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
 615.963 +      return(1);
 615.964 +    }
 615.965 +  }else{
 615.966 +    oggpack_write(opb,0,1);
 615.967 +    memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
 615.968 +    return(0);
 615.969 +  }
 615.970 +}
 615.971 +
 615.972 +static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
 615.973 +  vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
 615.974 +  vorbis_info_floor1 *info=look->vi;
 615.975 +  codec_setup_info   *ci=vb->vd->vi->codec_setup;
 615.976 +
 615.977 +  int i,j,k;
 615.978 +  codebook *books=ci->fullbooks;
 615.979 +
 615.980 +  /* unpack wrapped/predicted values from stream */
 615.981 +  if(oggpack_read(&vb->opb,1)==1){
 615.982 +    int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
 615.983 +
 615.984 +    fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
 615.985 +    fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
 615.986 +
 615.987 +    /* partition by partition */
 615.988 +    for(i=0,j=2;i<info->partitions;i++){
 615.989 +      int class=info->partitionclass[i];
 615.990 +      int cdim=info->class_dim[class];
 615.991 +      int csubbits=info->class_subs[class];
 615.992 +      int csub=1<<csubbits;
 615.993 +      int cval=0;
 615.994 +
 615.995 +      /* decode the partition's first stage cascade value */
 615.996 +      if(csubbits){
 615.997 +        cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
 615.998 +
 615.999 +        if(cval==-1)goto eop;
615.1000 +      }
615.1001 +
615.1002 +      for(k=0;k<cdim;k++){
615.1003 +        int book=info->class_subbook[class][cval&(csub-1)];
615.1004 +        cval>>=csubbits;
615.1005 +        if(book>=0){
615.1006 +          if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
615.1007 +            goto eop;
615.1008 +        }else{
615.1009 +          fit_value[j+k]=0;
615.1010 +        }
615.1011 +      }
615.1012 +      j+=cdim;
615.1013 +    }
615.1014 +
615.1015 +    /* unwrap positive values and reconsitute via linear interpolation */
615.1016 +    for(i=2;i<look->posts;i++){
615.1017 +      int predicted=render_point(info->postlist[look->loneighbor[i-2]],
615.1018 +                                 info->postlist[look->hineighbor[i-2]],
615.1019 +                                 fit_value[look->loneighbor[i-2]],
615.1020 +                                 fit_value[look->hineighbor[i-2]],
615.1021 +                                 info->postlist[i]);
615.1022 +      int hiroom=look->quant_q-predicted;
615.1023 +      int loroom=predicted;
615.1024 +      int room=(hiroom<loroom?hiroom:loroom)<<1;
615.1025 +      int val=fit_value[i];
615.1026 +
615.1027 +      if(val){
615.1028 +        if(val>=room){
615.1029 +          if(hiroom>loroom){
615.1030 +            val = val-loroom;
615.1031 +          }else{
615.1032 +            val = -1-(val-hiroom);
615.1033 +          }
615.1034 +        }else{
615.1035 +          if(val&1){
615.1036 +            val= -((val+1)>>1);
615.1037 +          }else{
615.1038 +            val>>=1;
615.1039 +          }
615.1040 +        }
615.1041 +
615.1042 +        fit_value[i]=(val+predicted)&0x7fff;
615.1043 +        fit_value[look->loneighbor[i-2]]&=0x7fff;
615.1044 +        fit_value[look->hineighbor[i-2]]&=0x7fff;
615.1045 +
615.1046 +      }else{
615.1047 +        fit_value[i]=predicted|0x8000;
615.1048 +      }
615.1049 +
615.1050 +    }
615.1051 +
615.1052 +    return(fit_value);
615.1053 +  }
615.1054 + eop:
615.1055 +  return(NULL);
615.1056 +}
615.1057 +
615.1058 +static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
615.1059 +                          float *out){
615.1060 +  vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
615.1061 +  vorbis_info_floor1 *info=look->vi;
615.1062 +
615.1063 +  codec_setup_info   *ci=vb->vd->vi->codec_setup;
615.1064 +  int                  n=ci->blocksizes[vb->W]/2;
615.1065 +  int j;
615.1066 +
615.1067 +  if(memo){
615.1068 +    /* render the lines */
615.1069 +    int *fit_value=(int *)memo;
615.1070 +    int hx=0;
615.1071 +    int lx=0;
615.1072 +    int ly=fit_value[0]*info->mult;
615.1073 +    /* guard lookup against out-of-range values */
615.1074 +    ly=(ly<0?0:ly>255?255:ly);
615.1075 +
615.1076 +    for(j=1;j<look->posts;j++){
615.1077 +      int current=look->forward_index[j];
615.1078 +      int hy=fit_value[current]&0x7fff;
615.1079 +      if(hy==fit_value[current]){
615.1080 +
615.1081 +        hx=info->postlist[current];
615.1082 +        hy*=info->mult;
615.1083 +        /* guard lookup against out-of-range values */
615.1084 +        hy=(hy<0?0:hy>255?255:hy);
615.1085 +
615.1086 +        render_line(n,lx,hx,ly,hy,out);
615.1087 +
615.1088 +        lx=hx;
615.1089 +        ly=hy;
615.1090 +      }
615.1091 +    }
615.1092 +    for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
615.1093 +    return(1);
615.1094 +  }
615.1095 +  memset(out,0,sizeof(*out)*n);
615.1096 +  return(0);
615.1097 +}
615.1098 +
615.1099 +/* export hooks */
615.1100 +const vorbis_func_floor floor1_exportbundle={
615.1101 +  &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
615.1102 +  &floor1_free_look,&floor1_inverse1,&floor1_inverse2
615.1103 +};
   616.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   616.2 +++ b/libs/vorbis/highlevel.h	Sat Feb 01 19:58:19 2014 +0200
   616.3 @@ -0,0 +1,58 @@
   616.4 +/********************************************************************
   616.5 + *                                                                  *
   616.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   616.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   616.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   616.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  616.10 + *                                                                  *
  616.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  616.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  616.13 + *                                                                  *
  616.14 + ********************************************************************
  616.15 +
  616.16 + function: highlevel encoder setup struct separated out for vorbisenc clarity
  616.17 + last mod: $Id: highlevel.h 17195 2010-05-05 21:49:51Z giles $
  616.18 +
  616.19 + ********************************************************************/
  616.20 +
  616.21 +typedef struct highlevel_byblocktype {
  616.22 +  double tone_mask_setting;
  616.23 +  double tone_peaklimit_setting;
  616.24 +  double noise_bias_setting;
  616.25 +  double noise_compand_setting;
  616.26 +} highlevel_byblocktype;
  616.27 +
  616.28 +typedef struct highlevel_encode_setup {
  616.29 +  int   set_in_stone;
  616.30 +  const void *setup;
  616.31 +  double base_setting;
  616.32 +
  616.33 +  double impulse_noisetune;
  616.34 +
  616.35 +  /* bitrate management below all settable */
  616.36 +  float  req;
  616.37 +  int    managed;
  616.38 +  long   bitrate_min;
  616.39 +  long   bitrate_av;
  616.40 +  double bitrate_av_damp;
  616.41 +  long   bitrate_max;
  616.42 +  long   bitrate_reservoir;
  616.43 +  double bitrate_reservoir_bias;
  616.44 +
  616.45 +  int impulse_block_p;
  616.46 +  int noise_normalize_p;
  616.47 +  int coupling_p;
  616.48 +
  616.49 +  double stereo_point_setting;
  616.50 +  double lowpass_kHz;
  616.51 +  int    lowpass_altered;
  616.52 +
  616.53 +  double ath_floating_dB;
  616.54 +  double ath_absolute_dB;
  616.55 +
  616.56 +  double amplitude_track_dBpersec;
  616.57 +  double trigger_setting;
  616.58 +
  616.59 +  highlevel_byblocktype block[4]; /* padding, impulse, transition, long */
  616.60 +
  616.61 +} highlevel_encode_setup;
   617.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   617.2 +++ b/libs/vorbis/info.c	Sat Feb 01 19:58:19 2014 +0200
   617.3 @@ -0,0 +1,668 @@
   617.4 +/********************************************************************
   617.5 + *                                                                  *
   617.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   617.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   617.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   617.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  617.10 + *                                                                  *
  617.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
  617.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  617.13 + *                                                                  *
  617.14 + ********************************************************************
  617.15 +
  617.16 + function: maintain the info structure, info <-> header packets
  617.17 + last mod: $Id: info.c 18186 2012-02-03 22:08:44Z xiphmont $
  617.18 +
  617.19 + ********************************************************************/
  617.20 +
  617.21 +/* general handling of the header and the vorbis_info structure (and
  617.22 +   substructures) */
  617.23 +
  617.24 +#include <stdlib.h>
  617.25 +#include <string.h>
  617.26 +#include <ctype.h>
  617.27 +#include <ogg/ogg.h>
  617.28 +#include "vorbis/codec.h"
  617.29 +#include "codec_internal.h"
  617.30 +#include "codebook.h"
  617.31 +#include "registry.h"
  617.32 +#include "window.h"
  617.33 +#include "psy.h"
  617.34 +#include "misc.h"
  617.35 +#include "os.h"
  617.36 +
  617.37 +#define GENERAL_VENDOR_STRING "Xiph.Org libVorbis 1.3.3"
  617.38 +#define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20120203 (Omnipresent)"
  617.39 +
  617.40 +/* helpers */
  617.41 +static int ilog2(unsigned int v){
  617.42 +  int ret=0;
  617.43 +  if(v)--v;
  617.44 +  while(v){
  617.45 +    ret++;
  617.46 +    v>>=1;
  617.47 +  }
  617.48 +  return(ret);
  617.49 +}
  617.50 +
  617.51 +static void _v_writestring(oggpack_buffer *o,const char *s, int bytes){
  617.52 +
  617.53 +  while(bytes--){
  617.54 +    oggpack_write(o,*s++,8);
  617.55 +  }
  617.56 +}
  617.57 +
  617.58 +static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
  617.59 +  while(bytes--){
  617.60 +    *buf++=oggpack_read(o,8);
  617.61 +  }
  617.62 +}
  617.63 +
  617.64 +void vorbis_comment_init(vorbis_comment *vc){
  617.65 +  memset(vc,0,sizeof(*vc));
  617.66 +}
  617.67 +
  617.68 +void vorbis_comment_add(vorbis_comment *vc,const char *comment){
  617.69 +  vc->user_comments=_ogg_realloc(vc->user_comments,
  617.70 +                            (vc->comments+2)*sizeof(*vc->user_comments));
  617.71 +  vc->comment_lengths=_ogg_realloc(vc->comment_lengths,
  617.72 +                                  (vc->comments+2)*sizeof(*vc->comment_lengths));
  617.73 +  vc->comment_lengths[vc->comments]=strlen(comment);
  617.74 +  vc->user_comments[vc->comments]=_ogg_malloc(vc->comment_lengths[vc->comments]+1);
  617.75 +  strcpy(vc->user_comments[vc->comments], comment);
  617.76 +  vc->comments++;
  617.77 +  vc->user_comments[vc->comments]=NULL;
  617.78 +}
  617.79 +
  617.80 +void vorbis_comment_add_tag(vorbis_comment *vc, const char *tag, const char *contents){
  617.81 +  char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
  617.82 +  strcpy(comment, tag);
  617.83 +  strcat(comment, "=");
  617.84 +  strcat(comment, contents);
  617.85 +  vorbis_comment_add(vc, comment);
  617.86 +}
  617.87 +
  617.88 +/* This is more or less the same as strncasecmp - but that doesn't exist
  617.89 + * everywhere, and this is a fairly trivial function, so we include it */
  617.90 +static int tagcompare(const char *s1, const char *s2, int n){
  617.91 +  int c=0;
  617.92 +  while(c < n){
  617.93 +    if(toupper(s1[c]) != toupper(s2[c]))
  617.94 +      return !0;
  617.95 +    c++;
  617.96 +  }
  617.97 +  return 0;
  617.98 +}
  617.99 +
 617.100 +char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count){
 617.101 +  long i;
 617.102 +  int found = 0;
 617.103 +  int taglen = strlen(tag)+1; /* +1 for the = we append */
 617.104 +  char *fulltag = alloca(taglen+ 1);
 617.105 +
 617.106 +  strcpy(fulltag, tag);
 617.107 +  strcat(fulltag, "=");
 617.108 +
 617.109 +  for(i=0;i<vc->comments;i++){
 617.110 +    if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
 617.111 +      if(count == found)
 617.112 +        /* We return a pointer to the data, not a copy */
 617.113 +              return vc->user_comments[i] + taglen;
 617.114 +      else
 617.115 +        found++;
 617.116 +    }
 617.117 +  }
 617.118 +  return NULL; /* didn't find anything */
 617.119 +}
 617.120 +
 617.121 +int vorbis_comment_query_count(vorbis_comment *vc, const char *tag){
 617.122 +  int i,count=0;
 617.123 +  int taglen = strlen(tag)+1; /* +1 for the = we append */
 617.124 +  char *fulltag = alloca(taglen+1);
 617.125 +  strcpy(fulltag,tag);
 617.126 +  strcat(fulltag, "=");
 617.127 +
 617.128 +  for(i=0;i<vc->comments;i++){
 617.129 +    if(!tagcompare(vc->user_comments[i], fulltag, taglen))
 617.130 +      count++;
 617.131 +  }
 617.132 +
 617.133 +  return count;
 617.134 +}
 617.135 +
 617.136 +void vorbis_comment_clear(vorbis_comment *vc){
 617.137 +  if(vc){
 617.138 +    long i;
 617.139 +    if(vc->user_comments){
 617.140 +      for(i=0;i<vc->comments;i++)
 617.141 +        if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
 617.142 +      _ogg_free(vc->user_comments);
 617.143 +    }
 617.144 +    if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
 617.145 +    if(vc->vendor)_ogg_free(vc->vendor);
 617.146 +    memset(vc,0,sizeof(*vc));
 617.147 +  }
 617.148 +}
 617.149 +
 617.150 +/* blocksize 0 is guaranteed to be short, 1 is guaranteed to be long.
 617.151 +   They may be equal, but short will never ge greater than long */
 617.152 +int vorbis_info_blocksize(vorbis_info *vi,int zo){
 617.153 +  codec_setup_info *ci = vi->codec_setup;
 617.154 +  return ci ? ci->blocksizes[zo] : -1;
 617.155 +}
 617.156 +
 617.157 +/* used by synthesis, which has a full, alloced vi */
 617.158 +void vorbis_info_init(vorbis_info *vi){
 617.159 +  memset(vi,0,sizeof(*vi));
 617.160 +  vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info));
 617.161 +}
 617.162 +
 617.163 +void vorbis_info_clear(vorbis_info *vi){
 617.164 +  codec_setup_info     *ci=vi->codec_setup;
 617.165 +  int i;
 617.166 +
 617.167 +  if(ci){
 617.168 +
 617.169 +    for(i=0;i<ci->modes;i++)
 617.170 +      if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
 617.171 +
 617.172 +    for(i=0;i<ci->maps;i++) /* unpack does the range checking */
 617.173 +      if(ci->map_param[i]) /* this may be cleaning up an aborted
 617.174 +                              unpack, in which case the below type
 617.175 +                              cannot be trusted */
 617.176 +        _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
 617.177 +
 617.178 +    for(i=0;i<ci->floors;i++) /* unpack does the range checking */
 617.179 +      if(ci->floor_param[i]) /* this may be cleaning up an aborted
 617.180 +                                unpack, in which case the below type
 617.181 +                                cannot be trusted */
 617.182 +        _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
 617.183 +
 617.184 +    for(i=0;i<ci->residues;i++) /* unpack does the range checking */
 617.185 +      if(ci->residue_param[i]) /* this may be cleaning up an aborted
 617.186 +                                  unpack, in which case the below type
 617.187 +                                  cannot be trusted */
 617.188 +        _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
 617.189 +
 617.190 +    for(i=0;i<ci->books;i++){
 617.191 +      if(ci->book_param[i]){
 617.192 +        /* knows if the book was not alloced */
 617.193 +        vorbis_staticbook_destroy(ci->book_param[i]);
 617.194 +      }
 617.195 +      if(ci->fullbooks)
 617.196 +        vorbis_book_clear(ci->fullbooks+i);
 617.197 +    }
 617.198 +    if(ci->fullbooks)
 617.199 +        _ogg_free(ci->fullbooks);
 617.200 +
 617.201 +    for(i=0;i<ci->psys;i++)
 617.202 +      _vi_psy_free(ci->psy_param[i]);
 617.203 +
 617.204 +    _ogg_free(ci);
 617.205 +  }
 617.206 +
 617.207 +  memset(vi,0,sizeof(*vi));
 617.208 +}
 617.209 +
 617.210 +/* Header packing/unpacking ********************************************/
 617.211 +
 617.212 +static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
 617.213 +  codec_setup_info     *ci=vi->codec_setup;
 617.214 +  if(!ci)return(OV_EFAULT);
 617.215 +
 617.216 +  vi->version=oggpack_read(opb,32);
 617.217 +  if(vi->version!=0)return(OV_EVERSION);
 617.218 +
 617.219 +  vi->channels=oggpack_read(opb,8);
 617.220 +  vi->rate=oggpack_read(opb,32);
 617.221 +
 617.222 +  vi->bitrate_upper=oggpack_read(opb,32);
 617.223 +  vi->bitrate_nominal=oggpack_read(opb,32);
 617.224 +  vi->bitrate_lower=oggpack_read(opb,32);
 617.225 +
 617.226 +  ci->blocksizes[0]=1<<oggpack_read(opb,4);
 617.227 +  ci->blocksizes[1]=1<<oggpack_read(opb,4);
 617.228 +
 617.229 +  if(vi->rate<1)goto err_out;
 617.230 +  if(vi->channels<1)goto err_out;
 617.231 +  if(ci->blocksizes[0]<64)goto err_out;
 617.232 +  if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
 617.233 +  if(ci->blocksizes[1]>8192)goto err_out;
 617.234 +
 617.235 +  if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
 617.236 +
 617.237 +  return(0);
 617.238 + err_out:
 617.239 +  vorbis_info_clear(vi);
 617.240 +  return(OV_EBADHEADER);
 617.241 +}
 617.242 +
 617.243 +static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
 617.244 +  int i;
 617.245 +  int vendorlen=oggpack_read(opb,32);
 617.246 +  if(vendorlen<0)goto err_out;
 617.247 +  if(vendorlen>opb->storage-8)goto err_out;
 617.248 +  vc->vendor=_ogg_calloc(vendorlen+1,1);
 617.249 +  _v_readstring(opb,vc->vendor,vendorlen);
 617.250 +  i=oggpack_read(opb,32);
 617.251 +  if(i<0)goto err_out;
 617.252 +  if(i>((opb->storage-oggpack_bytes(opb))>>2))goto err_out;
 617.253 +  vc->comments=i;
 617.254 +  vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
 617.255 +  vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
 617.256 +
 617.257 +  for(i=0;i<vc->comments;i++){
 617.258 +    int len=oggpack_read(opb,32);
 617.259 +    if(len<0)goto err_out;
 617.260 +    if(len>opb->storage-oggpack_bytes(opb))goto err_out;
 617.261 +    vc->comment_lengths[i]=len;
 617.262 +    vc->user_comments[i]=_ogg_calloc(len+1,1);
 617.263 +    _v_readstring(opb,vc->user_comments[i],len);
 617.264 +  }
 617.265 +  if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
 617.266 +
 617.267 +  return(0);
 617.268 + err_out:
 617.269 +  vorbis_comment_clear(vc);
 617.270 +  return(OV_EBADHEADER);
 617.271 +}
 617.272 +
 617.273 +/* all of the real encoding details are here.  The modes, books,
 617.274 +   everything */
 617.275 +static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
 617.276 +  codec_setup_info     *ci=vi->codec_setup;
 617.277 +  int i;
 617.278 +  if(!ci)return(OV_EFAULT);
 617.279 +
 617.280 +  /* codebooks */
 617.281 +  ci->books=oggpack_read(opb,8)+1;
 617.282 +  if(ci->books<=0)goto err_out;
 617.283 +  for(i=0;i<ci->books;i++){
 617.284 +    ci->book_param[i]=vorbis_staticbook_unpack(opb);
 617.285 +    if(!ci->book_param[i])goto err_out;
 617.286 +  }
 617.287 +
 617.288 +  /* time backend settings; hooks are unused */
 617.289 +  {
 617.290 +    int times=oggpack_read(opb,6)+1;
 617.291 +    if(times<=0)goto err_out;
 617.292 +    for(i=0;i<times;i++){
 617.293 +      int test=oggpack_read(opb,16);
 617.294 +      if(test<0 || test>=VI_TIMEB)goto err_out;
 617.295 +    }
 617.296 +  }
 617.297 +
 617.298 +  /* floor backend settings */
 617.299 +  ci->floors=oggpack_read(opb,6)+1;
 617.300 +  if(ci->floors<=0)goto err_out;
 617.301 +  for(i=0;i<ci->floors;i++){
 617.302 +    ci->floor_type[i]=oggpack_read(opb,16);
 617.303 +    if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
 617.304 +    ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
 617.305 +    if(!ci->floor_param[i])goto err_out;
 617.306 +  }
 617.307 +
 617.308 +  /* residue backend settings */
 617.309 +  ci->residues=oggpack_read(opb,6)+1;
 617.310 +  if(ci->residues<=0)goto err_out;
 617.311 +  for(i=0;i<ci->residues;i++){
 617.312 +    ci->residue_type[i]=oggpack_read(opb,16);
 617.313 +    if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
 617.314 +    ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
 617.315 +    if(!ci->residue_param[i])goto err_out;
 617.316 +  }
 617.317 +
 617.318 +  /* map backend settings */
 617.319 +  ci->maps=oggpack_read(opb,6)+1;
 617.320 +  if(ci->maps<=0)goto err_out;
 617.321 +  for(i=0;i<ci->maps;i++){
 617.322 +    ci->map_type[i]=oggpack_read(opb,16);
 617.323 +    if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
 617.324 +    ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
 617.325 +    if(!ci->map_param[i])goto err_out;
 617.326 +  }
 617.327 +
 617.328 +  /* mode settings */
 617.329 +  ci->modes=oggpack_read(opb,6)+1;
 617.330 +  if(ci->modes<=0)goto err_out;
 617.331 +  for(i=0;i<ci->modes;i++){
 617.332 +    ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i]));
 617.333 +    ci->mode_param[i]->blockflag=oggpack_read(opb,1);
 617.334 +    ci->mode_param[i]->windowtype=oggpack_read(opb,16);
 617.335 +    ci->mode_param[i]->transformtype=oggpack_read(opb,16);
 617.336 +    ci->mode_param[i]->mapping=oggpack_read(opb,8);
 617.337 +
 617.338 +    if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
 617.339 +    if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
 617.340 +    if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
 617.341 +    if(ci->mode_param[i]->mapping<0)goto err_out;
 617.342 +  }
 617.343 +
 617.344 +  if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
 617.345 +
 617.346 +  return(0);
 617.347 + err_out:
 617.348 +  vorbis_info_clear(vi);
 617.349 +  return(OV_EBADHEADER);
 617.350 +}
 617.351 +
 617.352 +/* Is this packet a vorbis ID header? */
 617.353 +int vorbis_synthesis_idheader(ogg_packet *op){
 617.354 +  oggpack_buffer opb;
 617.355 +  char buffer[6];
 617.356 +
 617.357 +  if(op){
 617.358 +    oggpack_readinit(&opb,op->packet,op->bytes);
 617.359 +
 617.360 +    if(!op->b_o_s)
 617.361 +      return(0); /* Not the initial packet */
 617.362 +
 617.363 +    if(oggpack_read(&opb,8) != 1)
 617.364 +      return 0; /* not an ID header */
 617.365 +
 617.366 +    memset(buffer,0,6);
 617.367 +    _v_readstring(&opb,buffer,6);
 617.368 +    if(memcmp(buffer,"vorbis",6))
 617.369 +      return 0; /* not vorbis */
 617.370 +
 617.371 +    return 1;
 617.372 +  }
 617.373 +
 617.374 +  return 0;
 617.375 +}
 617.376 +
 617.377 +/* The Vorbis header is in three packets; the initial small packet in
 617.378 +   the first page that identifies basic parameters, a second packet
 617.379 +   with bitstream comments and a third packet that holds the
 617.380 +   codebook. */
 617.381 +
 617.382 +int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
 617.383 +  oggpack_buffer opb;
 617.384 +
 617.385 +  if(op){
 617.386 +    oggpack_readinit(&opb,op->packet,op->bytes);
 617.387 +
 617.388 +    /* Which of the three types of header is this? */
 617.389 +    /* Also verify header-ness, vorbis */
 617.390 +    {
 617.391 +      char buffer[6];
 617.392 +      int packtype=oggpack_read(&opb,8);
 617.393 +      memset(buffer,0,6);
 617.394 +      _v_readstring(&opb,buffer,6);
 617.395 +      if(memcmp(buffer,"vorbis",6)){
 617.396 +        /* not a vorbis header */
 617.397 +        return(OV_ENOTVORBIS);
 617.398 +      }
 617.399 +      switch(packtype){
 617.400 +      case 0x01: /* least significant *bit* is read first */
 617.401 +        if(!op->b_o_s){
 617.402 +          /* Not the initial packet */
 617.403 +          return(OV_EBADHEADER);
 617.404 +        }
 617.405 +        if(vi->rate!=0){
 617.406 +          /* previously initialized info header */
 617.407 +          return(OV_EBADHEADER);
 617.408 +        }
 617.409 +
 617.410 +        return(_vorbis_unpack_info(vi,&opb));
 617.411 +
 617.412 +      case 0x03: /* least significant *bit* is read first */
 617.413 +        if(vi->rate==0){
 617.414 +          /* um... we didn't get the initial header */
 617.415 +          return(OV_EBADHEADER);
 617.416 +        }
 617.417 +
 617.418 +        return(_vorbis_unpack_comment(vc,&opb));
 617.419 +
 617.420 +      case 0x05: /* least significant *bit* is read first */
 617.421 +        if(vi->rate==0 || vc->vendor==NULL){
 617.422 +          /* um... we didn;t get the initial header or comments yet */
 617.423 +          return(OV_EBADHEADER);
 617.424 +        }
 617.425 +
 617.426 +        return(_vorbis_unpack_books(vi,&opb));
 617.427 +
 617.428 +      default:
 617.429 +        /* Not a valid vorbis header type */
 617.430 +        return(OV_EBADHEADER);
 617.431 +        break;
 617.432 +      }
 617.433 +    }
 617.434 +  }
 617.435 +  return(OV_EBADHEADER);
 617.436 +}
 617.437 +
 617.438 +/* pack side **********************************************************/
 617.439 +
 617.440 +static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
 617.441 +  codec_setup_info     *ci=vi->codec_setup;
 617.442 +  if(!ci)return(OV_EFAULT);
 617.443 +
 617.444 +  /* preamble */
 617.445 +  oggpack_write(opb,0x01,8);
 617.446 +  _v_writestring(opb,"vorbis", 6);
 617.447 +
 617.448 +  /* basic information about the stream */
 617.449 +  oggpack_write(opb,0x00,32);
 617.450 +  oggpack_write(opb,vi->channels,8);
 617.451 +  oggpack_write(opb,vi->rate,32);
 617.452 +
 617.453 +  oggpack_write(opb,vi->bitrate_upper,32);
 617.454 +  oggpack_write(opb,vi->bitrate_nominal,32);
 617.455 +  oggpack_write(opb,vi->bitrate_lower,32);
 617.456 +
 617.457 +  oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
 617.458 +  oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
 617.459 +  oggpack_write(opb,1,1);
 617.460 +
 617.461 +  return(0);
 617.462 +}
 617.463 +
 617.464 +static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
 617.465 +  int bytes = strlen(ENCODE_VENDOR_STRING);
 617.466 +
 617.467 +  /* preamble */
 617.468 +  oggpack_write(opb,0x03,8);
 617.469 +  _v_writestring(opb,"vorbis", 6);
 617.470 +
 617.471 +  /* vendor */
 617.472 +  oggpack_write(opb,bytes,32);
 617.473 +  _v_writestring(opb,ENCODE_VENDOR_STRING, bytes);
 617.474 +
 617.475 +  /* comments */
 617.476 +
 617.477 +  oggpack_write(opb,vc->comments,32);
 617.478 +  if(vc->comments){
 617.479 +    int i;
 617.480 +    for(i=0;i<vc->comments;i++){
 617.481 +      if(vc->user_comments[i]){
 617.482 +        oggpack_write(opb,vc->comment_lengths[i],32);
 617.483 +        _v_writestring(opb,vc->user_comments[i], vc->comment_lengths[i]);
 617.484 +      }else{
 617.485 +        oggpack_write(opb,0,32);
 617.486 +      }
 617.487 +    }
 617.488 +  }
 617.489 +  oggpack_write(opb,1,1);
 617.490 +
 617.491 +  return(0);
 617.492 +}
 617.493 +
 617.494 +static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
 617.495 +  codec_setup_info     *ci=vi->codec_setup;
 617.496 +  int i;
 617.497 +  if(!ci)return(OV_EFAULT);
 617.498 +
 617.499 +  oggpack_write(opb,0x05,8);
 617.500 +  _v_writestring(opb,"vorbis", 6);
 617.501 +
 617.502 +  /* books */
 617.503 +  oggpack_write(opb,ci->books-1,8);
 617.504 +  for(i=0;i<ci->books;i++)
 617.505 +    if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out;
 617.506 +
 617.507 +  /* times; hook placeholders */
 617.508 +  oggpack_write(opb,0,6);
 617.509 +  oggpack_write(opb,0,16);
 617.510 +
 617.511 +  /* floors */
 617.512 +  oggpack_write(opb,ci->floors-1,6);
 617.513 +  for(i=0;i<ci->floors;i++){
 617.514 +    oggpack_write(opb,ci->floor_type[i],16);
 617.515 +    if(_floor_P[ci->floor_type[i]]->pack)
 617.516 +      _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb);
 617.517 +    else
 617.518 +      goto err_out;
 617.519 +  }
 617.520 +
 617.521 +  /* residues */
 617.522 +  oggpack_write(opb,ci->residues-1,6);
 617.523 +  for(i=0;i<ci->residues;i++){
 617.524 +    oggpack_write(opb,ci->residue_type[i],16);
 617.525 +    _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb);
 617.526 +  }
 617.527 +
 617.528 +  /* maps */
 617.529 +  oggpack_write(opb,ci->maps-1,6);
 617.530 +  for(i=0;i<ci->maps;i++){
 617.531 +    oggpack_write(opb,ci->map_type[i],16);
 617.532 +    _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb);
 617.533 +  }
 617.534 +
 617.535 +  /* modes */
 617.536 +  oggpack_write(opb,ci->modes-1,6);
 617.537 +  for(i=0;i<ci->modes;i++){
 617.538 +    oggpack_write(opb,ci->mode_param[i]->blockflag,1);
 617.539 +    oggpack_write(opb,ci->mode_param[i]->windowtype,16);
 617.540 +    oggpack_write(opb,ci->mode_param[i]->transformtype,16);
 617.541 +    oggpack_write(opb,ci->mode_param[i]->mapping,8);
 617.542 +  }
 617.543 +  oggpack_write(opb,1,1);
 617.544 +
 617.545 +  return(0);
 617.546 +err_out:
 617.547 +  return(-1);
 617.548 +}
 617.549 +
 617.550 +int vorbis_commentheader_out(vorbis_comment *vc,
 617.551 +                                          ogg_packet *op){
 617.552 +
 617.553 +  oggpack_buffer opb;
 617.554 +
 617.555 +  oggpack_writeinit(&opb);
 617.556 +  if(_vorbis_pack_comment(&opb,vc)){
 617.557 +    oggpack_writeclear(&opb);
 617.558 +    return OV_EIMPL;
 617.559 +  }
 617.560 +
 617.561 +  op->packet = _ogg_malloc(oggpack_bytes(&opb));
 617.562 +  memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
 617.563 +
 617.564 +  op->bytes=oggpack_bytes(&opb);
 617.565 +  op->b_o_s=0;
 617.566 +  op->e_o_s=0;
 617.567 +  op->granulepos=0;
 617.568 +  op->packetno=1;
 617.569 +
 617.570 +  oggpack_writeclear(&opb);
 617.571 +  return 0;
 617.572 +}
 617.573 +
 617.574 +int vorbis_analysis_headerout(vorbis_dsp_state *v,
 617.575 +                              vorbis_comment *vc,
 617.576 +                              ogg_packet *op,
 617.577 +                              ogg_packet *op_comm,
 617.578 +                              ogg_packet *op_code){
 617.579 +  int ret=OV_EIMPL;
 617.580 +  vorbis_info *vi=v->vi;
 617.581 +  oggpack_buffer opb;
 617.582 +  private_state *b=v->backend_state;
 617.583 +
 617.584 +  if(!b){
 617.585 +    ret=OV_EFAULT;
 617.586 +    goto err_out;
 617.587 +  }
 617.588 +
 617.589 +  /* first header packet **********************************************/
 617.590 +
 617.591 +  oggpack_writeinit(&opb);
 617.592 +  if(_vorbis_pack_info(&opb,vi))goto err_out;
 617.593 +
 617.594 +  /* build the packet */
 617.595 +  if(b->header)_ogg_free(b->header);
 617.596 +  b->header=_ogg_malloc(oggpack_bytes(&opb));
 617.597 +  memcpy(b->header,opb.buffer,oggpack_bytes(&opb));
 617.598 +  op->packet=b->header;
 617.599 +  op->bytes=oggpack_bytes(&opb);
 617.600 +  op->b_o_s=1;
 617.601 +  op->e_o_s=0;
 617.602 +  op->granulepos=0;
 617.603 +  op->packetno=0;
 617.604 +
 617.605 +  /* second header packet (comments) **********************************/
 617.606 +
 617.607 +  oggpack_reset(&opb);
 617.608 +  if(_vorbis_pack_comment(&opb,vc))goto err_out;
 617.609 +
 617.610 +  if(b->header1)_ogg_free(b->header1);
 617.611 +  b->header1=_ogg_malloc(oggpack_bytes(&opb));
 617.612 +  memcpy(b->header1,opb.buffer,oggpack_bytes(&opb));
 617.613 +  op_comm->packet=b->header1;
 617.614 +  op_comm->bytes=oggpack_bytes(&opb);
 617.615 +  op_comm->b_o_s=0;
 617.616 +  op_comm->e_o_s=0;
 617.617 +  op_comm->granulepos=0;
 617.618 +  op_comm->packetno=1;
 617.619 +
 617.620 +  /* third header packet (modes/codebooks) ****************************/
 617.621 +
 617.622 +  oggpack_reset(&opb);
 617.623 +  if(_vorbis_pack_books(&opb,vi))goto err_out;
 617.624 +
 617.625 +  if(b->header2)_ogg_free(b->header2);
 617.626 +  b->header2=_ogg_malloc(oggpack_bytes(&opb));
 617.627 +  memcpy(b->header2,opb.buffer,oggpack_bytes(&opb));
 617.628 +  op_code->packet=b->header2;
 617.629 +  op_code->bytes=oggpack_bytes(&opb);
 617.630 +  op_code->b_o_s=0;
 617.631 +  op_code->e_o_s=0;
 617.632 +  op_code->granulepos=0;
 617.633 +  op_code->packetno=2;
 617.634 +
 617.635 +  oggpack_writeclear(&opb);
 617.636 +  return(0);
 617.637 + err_out:
 617.638 +  memset(op,0,sizeof(*op));
 617.639 +  memset(op_comm,0,sizeof(*op_comm));
 617.640 +  memset(op_code,0,sizeof(*op_code));
 617.641 +
 617.642 +  if(b){
 617.643 +    oggpack_writeclear(&opb);
 617.644 +    if(b->header)_ogg_free(b->header);
 617.645 +    if(b->header1)_ogg_free(b->header1);
 617.646 +    if(b->header2)_ogg_free(b->header2);
 617.647 +    b->header=NULL;
 617.648 +    b->header1=NULL;
 617.649 +    b->header2=NULL;
 617.650 +  }
 617.651 +  return(ret);
 617.652 +}
 617.653 +
 617.654 +double vorbis_granule_time(vorbis_dsp_state *v,ogg_int64_t granulepos){
 617.655 +  if(granulepos == -1) return -1;
 617.656 +
 617.657 +  /* We're not guaranteed a 64 bit unsigned type everywhere, so we
 617.658 +     have to put the unsigned granpo in a signed type. */
 617.659 +  if(granulepos>=0){
 617.660 +    return((double)granulepos/v->vi->rate);
 617.661 +  }else{
 617.662 +    ogg_int64_t granuleoff=0xffffffff;
 617.663 +    granuleoff<<=31;
 617.664 +    granuleoff|=0x7ffffffff;
 617.665 +    return(((double)granulepos+2+granuleoff+granuleoff)/v->vi->rate);
 617.666 +  }
 617.667 +}
 617.668 +
 617.669 +const char *vorbis_version_string(void){
 617.670 +  return GENERAL_VENDOR_STRING;
 617.671 +}
   618.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   618.2 +++ b/libs/vorbis/lookup.c	Sat Feb 01 19:58:19 2014 +0200
   618.3 @@ -0,0 +1,94 @@
   618.4 +/********************************************************************
   618.5 + *                                                                  *
   618.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   618.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   618.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   618.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  618.10 + *                                                                  *
  618.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  618.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  618.13 + *                                                                  *
  618.14 + ********************************************************************
  618.15 +
  618.16 +  function: lookup based functions
  618.17 +  last mod: $Id: lookup.c 16227 2009-07-08 06:58:46Z xiphmont $
  618.18 +
  618.19 + ********************************************************************/
  618.20 +
  618.21 +#include <math.h>
  618.22 +#include "lookup.h"
  618.23 +#include "lookup_data.h"
  618.24 +#include "os.h"
  618.25 +#include "misc.h"
  618.26 +
  618.27 +#ifdef FLOAT_LOOKUP
  618.28 +
  618.29 +/* interpolated lookup based cos function, domain 0 to PI only */
  618.30 +float vorbis_coslook(float a){
  618.31 +  double d=a*(.31830989*(float)COS_LOOKUP_SZ);
  618.32 +  int i=vorbis_ftoi(d-.5);
  618.33 +
  618.34 +  return COS_LOOKUP[i]+ (d-i)*(COS_LOOKUP[i+1]-COS_LOOKUP[i]);
  618.35 +}
  618.36 +
  618.37 +/* interpolated 1./sqrt(p) where .5 <= p < 1. */
  618.38 +float vorbis_invsqlook(float a){
  618.39 +  double d=a*(2.f*(float)INVSQ_LOOKUP_SZ)-(float)INVSQ_LOOKUP_SZ;
  618.40 +  int i=vorbis_ftoi(d-.5f);
  618.41 +  return INVSQ_LOOKUP[i]+ (d-i)*(INVSQ_LOOKUP[i+1]-INVSQ_LOOKUP[i]);
  618.42 +}
  618.43 +
  618.44 +/* interpolated 1./sqrt(p) where .5 <= p < 1. */
  618.45 +float vorbis_invsq2explook(int a){
  618.46 +  return INVSQ2EXP_LOOKUP[a-INVSQ2EXP_LOOKUP_MIN];
  618.47 +}
  618.48 +
  618.49 +#include <stdio.h>
  618.50 +/* interpolated lookup based fromdB function, domain -140dB to 0dB only */
  618.51 +float vorbis_fromdBlook(float a){
  618.52 +  int i=vorbis_ftoi(a*((float)(-(1<<FROMdB2_SHIFT)))-.5f);
  618.53 +  return (i<0)?1.f:
  618.54 +    ((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f:
  618.55 +     FROMdB_LOOKUP[i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]);
  618.56 +}
  618.57 +
  618.58 +#endif
  618.59 +
  618.60 +#ifdef INT_LOOKUP
  618.61 +/* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
  618.62 +   16.16 format
  618.63 +
  618.64 +   returns in m.8 format */
  618.65 +long vorbis_invsqlook_i(long a,long e){
  618.66 +  long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1);
  618.67 +  long d=(a&INVSQ_LOOKUP_I_MASK)<<(16-INVSQ_LOOKUP_I_SHIFT); /*  0.16 */
  618.68 +  long val=INVSQ_LOOKUP_I[i]-                                /*  1.16 */
  618.69 +    (((INVSQ_LOOKUP_I[i]-INVSQ_LOOKUP_I[i+1])*               /*  0.16 */
  618.70 +      d)>>16);                                               /* result 1.16 */
  618.71 +
  618.72 +  e+=32;
  618.73 +  if(e&1)val=(val*5792)>>13; /* multiply val by 1/sqrt(2) */
  618.74 +  e=(e>>1)-8;
  618.75 +
  618.76 +  return(val>>e);
  618.77 +}
  618.78 +
  618.79 +/* interpolated lookup based fromdB function, domain -140dB to 0dB only */
  618.80 +/* a is in n.12 format */
  618.81 +float vorbis_fromdBlook_i(long a){
  618.82 +  int i=(-a)>>(12-FROMdB2_SHIFT);
  618.83 +  return (i<0)?1.f:
  618.84 +    ((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f:
  618.85 +     FROMdB_LOOKUP[i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]);
  618.86 +}
  618.87 +
  618.88 +/* interpolated lookup based cos function, domain 0 to PI only */
  618.89 +/* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
  618.90 +long vorbis_coslook_i(long a){
  618.91 +  int i=a>>COS_LOOKUP_I_SHIFT;
  618.92 +  int d=a&COS_LOOKUP_I_MASK;
  618.93 +  return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
  618.94 +                           COS_LOOKUP_I_SHIFT);
  618.95 +}
  618.96 +
  618.97 +#endif
   619.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   619.2 +++ b/libs/vorbis/lookup.h	Sat Feb 01 19:58:19 2014 +0200
   619.3 @@ -0,0 +1,32 @@
   619.4 +/********************************************************************
   619.5 + *                                                                  *
   619.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   619.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   619.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   619.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  619.10 + *                                                                  *
  619.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  619.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  619.13 + *                                                                  *
  619.14 + ********************************************************************
  619.15 +
  619.16 +  function: lookup based functions
  619.17 +  last mod: $Id: lookup.h 16227 2009-07-08 06:58:46Z xiphmont $
  619.18 +
  619.19 + ********************************************************************/
  619.20 +
  619.21 +#ifndef _V_LOOKUP_H_
  619.22 +
  619.23 +#ifdef FLOAT_LOOKUP
  619.24 +extern float vorbis_coslook(float a);
  619.25 +extern float vorbis_invsqlook(float a);
  619.26 +extern float vorbis_invsq2explook(int a);
  619.27 +extern float vorbis_fromdBlook(float a);
  619.28 +#endif
  619.29 +#ifdef INT_LOOKUP
  619.30 +extern long vorbis_invsqlook_i(long a,long e);
  619.31 +extern long vorbis_coslook_i(long a);
  619.32 +extern float vorbis_fromdBlook_i(long a);
  619.33 +#endif
  619.34 +
  619.35 +#endif
   620.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   620.2 +++ b/libs/vorbis/lookup_data.h	Sat Feb 01 19:58:19 2014 +0200
   620.3 @@ -0,0 +1,192 @@
   620.4 +/********************************************************************
   620.5 + *                                                                  *
   620.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   620.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   620.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   620.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  620.10 + *                                                                  *
  620.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  620.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  620.13 + *                                                                  *
  620.14 + ********************************************************************
  620.15 +
  620.16 +  function: lookup data; generated by lookups.pl; edit there
  620.17 +  last mod: $Id: lookup_data.h 16037 2009-05-26 21:10:58Z xiphmont $
  620.18 +
  620.19 + ********************************************************************/
  620.20 +
  620.21 +#ifndef _V_LOOKUP_DATA_H_
  620.22 +
  620.23 +#ifdef FLOAT_LOOKUP
  620.24 +#define COS_LOOKUP_SZ 128
  620.25 +static const float COS_LOOKUP[COS_LOOKUP_SZ+1]={
  620.26 +        +1.0000000000000f,+0.9996988186962f,+0.9987954562052f,+0.9972904566787f,
  620.27 +        +0.9951847266722f,+0.9924795345987f,+0.9891765099648f,+0.9852776423889f,
  620.28 +        +0.9807852804032f,+0.9757021300385f,+0.9700312531945f,+0.9637760657954f,
  620.29 +        +0.9569403357322f,+0.9495281805930f,+0.9415440651830f,+0.9329927988347f,
  620.30 +        +0.9238795325113f,+0.9142097557035f,+0.9039892931234f,+0.8932243011955f,
  620.31 +        +0.8819212643484f,+0.8700869911087f,+0.8577286100003f,+0.8448535652497f,
  620.32 +        +0.8314696123025f,+0.8175848131516f,+0.8032075314806f,+0.7883464276266f,
  620.33 +        +0.7730104533627f,+0.7572088465065f,+0.7409511253550f,+0.7242470829515f,
  620.34 +        +0.7071067811865f,+0.6895405447371f,+0.6715589548470f,+0.6531728429538f,
  620.35 +        +0.6343932841636f,+0.6152315905806f,+0.5956993044924f,+0.5758081914178f,
  620.36 +        +0.5555702330196f,+0.5349976198871f,+0.5141027441932f,+0.4928981922298f,
  620.37 +        +0.4713967368260f,+0.4496113296546f,+0.4275550934303f,+0.4052413140050f,
  620.38 +        +0.3826834323651f,+0.3598950365350f,+0.3368898533922f,+0.3136817403989f,
  620.39 +        +0.2902846772545f,+0.2667127574749f,+0.2429801799033f,+0.2191012401569f,
  620.40 +        +0.1950903220161f,+0.1709618887603f,+0.1467304744554f,+0.1224106751992f,
  620.41 +        +0.0980171403296f,+0.0735645635997f,+0.0490676743274f,+0.0245412285229f,
  620.42 +        +0.0000000000000f,-0.0245412285229f,-0.0490676743274f,-0.0735645635997f,
  620.43 +        -0.0980171403296f,-0.1224106751992f,-0.1467304744554f,-0.1709618887603f,
  620.44 +        -0.1950903220161f,-0.2191012401569f,-0.2429801799033f,-0.2667127574749f,
  620.45 +        -0.2902846772545f,-0.3136817403989f,-0.3368898533922f,-0.3598950365350f,
  620.46 +        -0.3826834323651f,-0.4052413140050f,-0.4275550934303f,-0.4496113296546f,
  620.47 +        -0.4713967368260f,-0.4928981922298f,-0.5141027441932f,-0.5349976198871f,
  620.48 +        -0.5555702330196f,-0.5758081914178f,-0.5956993044924f,-0.6152315905806f,
  620.49 +        -0.6343932841636f,-0.6531728429538f,-0.6715589548470f,-0.6895405447371f,
  620.50 +        -0.7071067811865f,-0.7242470829515f,-0.7409511253550f,-0.7572088465065f,
  620.51 +        -0.7730104533627f,-0.7883464276266f,-0.8032075314806f,-0.8175848131516f,
  620.52 +        -0.8314696123025f,-0.8448535652497f,-0.8577286100003f,-0.8700869911087f,
  620.53 +        -0.8819212643484f,-0.8932243011955f,-0.9039892931234f,-0.9142097557035f,
  620.54 +        -0.9238795325113f,-0.9329927988347f,-0.9415440651830f,-0.9495281805930f,
  620.55 +        -0.9569403357322f,-0.9637760657954f,-0.9700312531945f,-0.9757021300385f,
  620.56 +        -0.9807852804032f,-0.9852776423889f,-0.9891765099648f,-0.9924795345987f,
  620.57 +        -0.9951847266722f,-0.9972904566787f,-0.9987954562052f,-0.9996988186962f,
  620.58 +        -1.0000000000000f,
  620.59 +};
  620.60 +
  620.61 +#define INVSQ_LOOKUP_SZ 32
  620.62 +static const float INVSQ_LOOKUP[INVSQ_LOOKUP_SZ+1]={
  620.63 +        1.414213562373f,1.392621247646f,1.371988681140f,1.352246807566f,
  620.64 +        1.333333333333f,1.315191898443f,1.297771369046f,1.281025230441f,
  620.65 +        1.264911064067f,1.249390095109f,1.234426799697f,1.219988562661f,
  620.66 +        1.206045378311f,1.192569588000f,1.179535649239f,1.166919931983f,
  620.67 +        1.154700538379f,1.142857142857f,1.131370849898f,1.120224067222f,
  620.68 +        1.109400392450f,1.098884511590f,1.088662107904f,1.078719779941f,
  620.69 +        1.069044967650f,1.059625885652f,1.050451462878f,1.041511287847f,
  620.70 +        1.032795558989f,1.024295039463f,1.016001016002f,1.007905261358f,
  620.71 +        1.000000000000f,
  620.72 +};
  620.73 +
  620.74 +#define INVSQ2EXP_LOOKUP_MIN (-32)
  620.75 +#define INVSQ2EXP_LOOKUP_MAX 32
  620.76 +static const float INVSQ2EXP_LOOKUP[INVSQ2EXP_LOOKUP_MAX-\
  620.77 +                              INVSQ2EXP_LOOKUP_MIN+1]={
  620.78 +                 65536.f,    46340.95001f,         32768.f,    23170.47501f,
  620.79 +                 16384.f,     11585.2375f,          8192.f,    5792.618751f,
  620.80 +                  4096.f,    2896.309376f,          2048.f,    1448.154688f,
  620.81 +                  1024.f,    724.0773439f,           512.f,     362.038672f,
  620.82 +                   256.f,     181.019336f,           128.f,    90.50966799f,
  620.83 +                    64.f,      45.254834f,            32.f,      22.627417f,
  620.84 +                    16.f,     11.3137085f,             8.f,    5.656854249f,
  620.85 +                     4.f,    2.828427125f,             2.f,    1.414213562f,
  620.86 +                     1.f,   0.7071067812f,            0.5f,   0.3535533906f,
  620.87 +                   0.25f,   0.1767766953f,          0.125f,  0.08838834765f,
  620.88 +                 0.0625f,  0.04419417382f,        0.03125f,  0.02209708691f,
  620.89 +               0.015625f,  0.01104854346f,      0.0078125f, 0.005524271728f,
  620.90 +             0.00390625f, 0.002762135864f,    0.001953125f, 0.001381067932f,
  620.91 +           0.0009765625f, 0.000690533966f,  0.00048828125f, 0.000345266983f,
  620.92 +         0.000244140625f,0.0001726334915f,0.0001220703125f,8.631674575e-05f,
  620.93 +        6.103515625e-05f,4.315837288e-05f,3.051757812e-05f,2.157918644e-05f,
  620.94 +        1.525878906e-05f,
  620.95 +};
  620.96 +
  620.97 +#endif
  620.98 +
  620.99 +#define FROMdB_LOOKUP_SZ 35
 620.100 +#define FROMdB2_LOOKUP_SZ 32
 620.101 +#define FROMdB_SHIFT 5
 620.102 +#define FROMdB2_SHIFT 3
 620.103 +#define FROMdB2_MASK 31
 620.104 +
 620.105 +#ifdef FLOAT_LOOKUP
 620.106 +static const float FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={
 620.107 +                     1.f,   0.6309573445f,   0.3981071706f,   0.2511886432f,
 620.108 +           0.1584893192f,            0.1f,  0.06309573445f,  0.03981071706f,
 620.109 +          0.02511886432f,  0.01584893192f,           0.01f, 0.006309573445f,
 620.110 +         0.003981071706f, 0.002511886432f, 0.001584893192f,          0.001f,
 620.111 +        0.0006309573445f,0.0003981071706f,0.0002511886432f,0.0001584893192f,
 620.112 +                 0.0001f,6.309573445e-05f,3.981071706e-05f,2.511886432e-05f,
 620.113 +        1.584893192e-05f,          1e-05f,6.309573445e-06f,3.981071706e-06f,
 620.114 +        2.511886432e-06f,1.584893192e-06f,          1e-06f,6.309573445e-07f,
 620.115 +        3.981071706e-07f,2.511886432e-07f,1.584893192e-07f,
 620.116 +};
 620.117 +
 620.118 +static const float FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={
 620.119 +           0.9928302478f,   0.9786445908f,   0.9646616199f,   0.9508784391f,
 620.120 +           0.9372921937f,     0.92390007f,   0.9106992942f,   0.8976871324f,
 620.121 +           0.8848608897f,   0.8722179097f,   0.8597555737f,   0.8474713009f,
 620.122 +            0.835362547f,   0.8234268041f,   0.8116616003f,   0.8000644989f,
 620.123 +           0.7886330981f,   0.7773650302f,   0.7662579617f,    0.755309592f,
 620.124 +           0.7445176537f,   0.7338799116f,   0.7233941627f,   0.7130582353f,
 620.125 +           0.7028699885f,   0.6928273125f,   0.6829281272f,   0.6731703824f,
 620.126 +           0.6635520573f,   0.6540711597f,   0.6447257262f,   0.6355138211f,
 620.127 +};
 620.128 +#endif
 620.129 +
 620.130 +#ifdef INT_LOOKUP
 620.131 +
 620.132 +#define INVSQ_LOOKUP_I_SHIFT 10
 620.133 +#define INVSQ_LOOKUP_I_MASK 1023
 620.134 +static const long INVSQ_LOOKUP_I[64+1]={
 620.135 +           92682l,   91966l,   91267l,   90583l,
 620.136 +           89915l,   89261l,   88621l,   87995l,
 620.137 +           87381l,   86781l,   86192l,   85616l,
 620.138 +           85051l,   84497l,   83953l,   83420l,
 620.139 +           82897l,   82384l,   81880l,   81385l,
 620.140 +           80899l,   80422l,   79953l,   79492l,
 620.141 +           79039l,   78594l,   78156l,   77726l,
 620.142 +           77302l,   76885l,   76475l,   76072l,
 620.143 +           75674l,   75283l,   74898l,   74519l,
 620.144 +           74146l,   73778l,   73415l,   73058l,
 620.145 +           72706l,   72359l,   72016l,   71679l,
 620.146 +           71347l,   71019l,   70695l,   70376l,
 620.147 +           70061l,   69750l,   69444l,   69141l,
 620.148 +           68842l,   68548l,   68256l,   67969l,
 620.149 +           67685l,   67405l,   67128l,   66855l,
 620.150 +           66585l,   66318l,   66054l,   65794l,
 620.151 +           65536l,
 620.152 +};
 620.153 +
 620.154 +#define COS_LOOKUP_I_SHIFT 9
 620.155 +#define COS_LOOKUP_I_MASK 511
 620.156 +#define COS_LOOKUP_I_SZ 128
 620.157 +static const long COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={
 620.158 +           16384l,   16379l,   16364l,   16340l,
 620.159 +           16305l,   16261l,   16207l,   16143l,
 620.160 +           16069l,   15986l,   15893l,   15791l,
 620.161 +           15679l,   15557l,   15426l,   15286l,
 620.162 +           15137l,   14978l,   14811l,   14635l,
 620.163 +           14449l,   14256l,   14053l,   13842l,
 620.164 +           13623l,   13395l,   13160l,   12916l,
 620.165 +           12665l,   12406l,   12140l,   11866l,
 620.166 +           11585l,   11297l,   11003l,   10702l,
 620.167 +           10394l,   10080l,    9760l,    9434l,
 620.168 +            9102l,    8765l,    8423l,    8076l,
 620.169 +            7723l,    7366l,    7005l,    6639l,
 620.170 +            6270l,    5897l,    5520l,    5139l,
 620.171 +            4756l,    4370l,    3981l,    3590l,
 620.172 +            3196l,    2801l,    2404l,    2006l,
 620.173 +            1606l,    1205l,     804l,     402l,
 620.174 +               0l,    -401l,    -803l,   -1204l,
 620.175 +           -1605l,   -2005l,   -2403l,   -2800l,
 620.176 +           -3195l,   -3589l,   -3980l,   -4369l,
 620.177 +           -4755l,   -5138l,   -5519l,   -5896l,
 620.178 +           -6269l,   -6638l,   -7004l,   -7365l,
 620.179 +           -7722l,   -8075l,   -8422l,   -8764l,
 620.180 +           -9101l,   -9433l,   -9759l,  -10079l,
 620.181 +          -10393l,  -10701l,  -11002l,  -11296l,
 620.182 +          -11584l,  -11865l,  -12139l,  -12405l,
 620.183 +          -12664l,  -12915l,  -13159l,  -13394l,
 620.184 +          -13622l,  -13841l,  -14052l,  -14255l,
 620.185 +          -14448l,  -14634l,  -14810l,  -14977l,
 620.186 +          -15136l,  -15285l,  -15425l,  -15556l,
 620.187 +          -15678l,  -15790l,  -15892l,  -15985l,
 620.188 +          -16068l,  -16142l,  -16206l,  -16260l,
 620.189 +          -16304l,  -16339l,  -16363l,  -16378l,
 620.190 +          -16383l,
 620.191 +};
 620.192 +
 620.193 +#endif
 620.194 +
 620.195 +#endif
   621.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   621.2 +++ b/libs/vorbis/lpc.c	Sat Feb 01 19:58:19 2014 +0200
   621.3 @@ -0,0 +1,160 @@
   621.4 +/********************************************************************
   621.5 + *                                                                  *
   621.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   621.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   621.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   621.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  621.10 + *                                                                  *
  621.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  621.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  621.13 + *                                                                  *
  621.14 + ********************************************************************
  621.15 +
  621.16 +  function: LPC low level routines
  621.17 +  last mod: $Id: lpc.c 16227 2009-07-08 06:58:46Z xiphmont $
  621.18 +
  621.19 + ********************************************************************/
  621.20 +
  621.21 +/* Some of these routines (autocorrelator, LPC coefficient estimator)
  621.22 +   are derived from code written by Jutta Degener and Carsten Bormann;
  621.23 +   thus we include their copyright below.  The entirety of this file
  621.24 +   is freely redistributable on the condition that both of these
  621.25 +   copyright notices are preserved without modification.  */
  621.26 +
  621.27 +/* Preserved Copyright: *********************************************/
  621.28 +
  621.29 +/* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
  621.30 +Technische Universita"t Berlin
  621.31 +
  621.32 +Any use of this software is permitted provided that this notice is not
  621.33 +removed and that neither the authors nor the Technische Universita"t
  621.34 +Berlin are deemed to have made any representations as to the
  621.35 +suitability of this software for any purpose nor are held responsible
  621.36 +for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR
  621.37 +THIS SOFTWARE.
  621.38 +
  621.39 +As a matter of courtesy, the authors request to be informed about uses
  621.40 +this software has found, about bugs in this software, and about any
  621.41 +improvements that may be of general interest.
  621.42 +
  621.43 +Berlin, 28.11.1994
  621.44 +Jutta Degener
  621.45 +Carsten Bormann
  621.46 +
  621.47 +*********************************************************************/
  621.48 +
  621.49 +#include <stdlib.h>
  621.50 +#include <string.h>
  621.51 +#include <math.h>
  621.52 +#include "os.h"
  621.53 +#include "smallft.h"
  621.54 +#include "lpc.h"
  621.55 +#include "scales.h"
  621.56 +#include "misc.h"
  621.57 +
  621.58 +/* Autocorrelation LPC coeff generation algorithm invented by
  621.59 +   N. Levinson in 1947, modified by J. Durbin in 1959. */
  621.60 +
  621.61 +/* Input : n elements of time doamin data
  621.62 +   Output: m lpc coefficients, excitation energy */
  621.63 +
  621.64 +float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){
  621.65 +  double *aut=alloca(sizeof(*aut)*(m+1));
  621.66 +  double *lpc=alloca(sizeof(*lpc)*(m));
  621.67 +  double error;
  621.68 +  double epsilon;
  621.69 +  int i,j;
  621.70 +
  621.71 +  /* autocorrelation, p+1 lag coefficients */
  621.72 +  j=m+1;
  621.73 +  while(j--){
  621.74 +    double d=0; /* double needed for accumulator depth */
  621.75 +    for(i=j;i<n;i++)d+=(double)data[i]*data[i-j];
  621.76 +    aut[j]=d;
  621.77 +  }
  621.78 +
  621.79 +  /* Generate lpc coefficients from autocorr values */
  621.80 +
  621.81 +  /* set our noise floor to about -100dB */
  621.82 +  error=aut[0] * (1. + 1e-10);
  621.83 +  epsilon=1e-9*aut[0]+1e-10;
  621.84 +
  621.85 +  for(i=0;i<m;i++){
  621.86 +    double r= -aut[i+1];
  621.87 +
  621.88 +    if(error<epsilon){
  621.89 +      memset(lpc+i,0,(m-i)*sizeof(*lpc));
  621.90 +      goto done;
  621.91 +    }
  621.92 +
  621.93 +    /* Sum up this iteration's reflection coefficient; note that in
  621.94 +       Vorbis we don't save it.  If anyone wants to recycle this code
  621.95 +       and needs reflection coefficients, save the results of 'r' from
  621.96 +       each iteration. */
  621.97 +
  621.98 +    for(j=0;j<i;j++)r-=lpc[j]*aut[i-j];
  621.99 +    r/=error;
 621.100 +
 621.101 +    /* Update LPC coefficients and total error */
 621.102 +
 621.103 +    lpc[i]=r;
 621.104 +    for(j=0;j<i/2;j++){
 621.105 +      double tmp=lpc[j];
 621.106 +
 621.107 +      lpc[j]+=r*lpc[i-1-j];
 621.108 +      lpc[i-1-j]+=r*tmp;
 621.109 +    }
 621.110 +    if(i&1)lpc[j]+=lpc[j]*r;
 621.111 +
 621.112 +    error*=1.-r*r;
 621.113 +
 621.114 +  }
 621.115 +
 621.116 + done:
 621.117 +
 621.118 +  /* slightly damp the filter */
 621.119 +  {
 621.120 +    double g = .99;
 621.121 +    double damp = g;
 621.122 +    for(j=0;j<m;j++){
 621.123 +      lpc[j]*=damp;
 621.124 +      damp*=g;
 621.125 +    }
 621.126 +  }
 621.127 +
 621.128 +  for(j=0;j<m;j++)lpci[j]=(float)lpc[j];
 621.129 +
 621.130 +  /* we need the error value to know how big an impulse to hit the
 621.131 +     filter with later */
 621.132 +
 621.133 +  return error;
 621.134 +}
 621.135 +
 621.136 +void vorbis_lpc_predict(float *coeff,float *prime,int m,
 621.137 +                     float *data,long n){
 621.138 +
 621.139 +  /* in: coeff[0...m-1] LPC coefficients
 621.140 +         prime[0...m-1] initial values (allocated size of n+m-1)
 621.141 +    out: data[0...n-1] data samples */
 621.142 +
 621.143 +  long i,j,o,p;
 621.144 +  float y;
 621.145 +  float *work=alloca(sizeof(*work)*(m+n));
 621.146 +
 621.147 +  if(!prime)
 621.148 +    for(i=0;i<m;i++)
 621.149 +      work[i]=0.f;
 621.150 +  else
 621.151 +    for(i=0;i<m;i++)
 621.152 +      work[i]=prime[i];
 621.153 +
 621.154 +  for(i=0;i<n;i++){
 621.155 +    y=0;
 621.156 +    o=i;
 621.157 +    p=m;
 621.158 +    for(j=0;j<m;j++)
 621.159 +      y-=work[o++]*coeff[--p];
 621.160 +
 621.161 +    data[i]=work[o]=y;
 621.162 +  }
 621.163 +}
   622.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   622.2 +++ b/libs/vorbis/lpc.h	Sat Feb 01 19:58:19 2014 +0200
   622.3 @@ -0,0 +1,29 @@
   622.4 +/********************************************************************
   622.5 + *                                                                  *
   622.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   622.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   622.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   622.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  622.10 + *                                                                  *
  622.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  622.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  622.13 + *                                                                  *
  622.14 + ********************************************************************
  622.15 +
  622.16 +  function: LPC low level routines
  622.17 +  last mod: $Id: lpc.h 16037 2009-05-26 21:10:58Z xiphmont $
  622.18 +
  622.19 + ********************************************************************/
  622.20 +
  622.21 +#ifndef _V_LPC_H_
  622.22 +#define _V_LPC_H_
  622.23 +
  622.24 +#include "vorbis/codec.h"
  622.25 +
  622.26 +/* simple linear scale LPC code */
  622.27 +extern float vorbis_lpc_from_data(float *data,float *lpc,int n,int m);
  622.28 +
  622.29 +extern void vorbis_lpc_predict(float *coeff,float *prime,int m,
  622.30 +                               float *data,long n);
  622.31 +
  622.32 +#endif
   623.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   623.2 +++ b/libs/vorbis/lsp.c	Sat Feb 01 19:58:19 2014 +0200
   623.3 @@ -0,0 +1,454 @@
   623.4 +/********************************************************************
   623.5 + *                                                                  *
   623.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   623.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   623.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   623.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  623.10 + *                                                                  *
  623.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  623.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  623.13 + *                                                                  *
  623.14 + ********************************************************************
  623.15 +
  623.16 +  function: LSP (also called LSF) conversion routines
  623.17 +  last mod: $Id: lsp.c 17538 2010-10-15 02:52:29Z tterribe $
  623.18 +
  623.19 +  The LSP generation code is taken (with minimal modification and a
  623.20 +  few bugfixes) from "On the Computation of the LSP Frequencies" by
  623.21 +  Joseph Rothweiler (see http://www.rothweiler.us for contact info).
  623.22 +  The paper is available at:
  623.23 +
  623.24 +  http://www.myown1.com/joe/lsf
  623.25 +
  623.26 + ********************************************************************/
  623.27 +
  623.28 +/* Note that the lpc-lsp conversion finds the roots of polynomial with
  623.29 +   an iterative root polisher (CACM algorithm 283).  It *is* possible
  623.30 +   to confuse this algorithm into not converging; that should only
  623.31 +   happen with absurdly closely spaced roots (very sharp peaks in the
  623.32 +   LPC f response) which in turn should be impossible in our use of
  623.33 +   the code.  If this *does* happen anyway, it's a bug in the floor
  623.34 +   finder; find the cause of the confusion (probably a single bin
  623.35 +   spike or accidental near-float-limit resolution problems) and
  623.36 +   correct it. */
  623.37 +
  623.38 +#include <math.h>
  623.39 +#include <string.h>
  623.40 +#include <stdlib.h>
  623.41 +#include "lsp.h"
  623.42 +#include "os.h"
  623.43 +#include "misc.h"
  623.44 +#include "lookup.h"
  623.45 +#include "scales.h"
  623.46 +
  623.47 +/* three possible LSP to f curve functions; the exact computation
  623.48 +   (float), a lookup based float implementation, and an integer
  623.49 +   implementation.  The float lookup is likely the optimal choice on
  623.50 +   any machine with an FPU.  The integer implementation is *not* fixed
  623.51 +   point (due to the need for a large dynamic range and thus a
  623.52 +   separately tracked exponent) and thus much more complex than the
  623.53 +   relatively simple float implementations. It's mostly for future
  623.54 +   work on a fully fixed point implementation for processors like the
  623.55 +   ARM family. */
  623.56 +
  623.57 +/* define either of these (preferably FLOAT_LOOKUP) to have faster
  623.58 +   but less precise implementation. */
  623.59 +#undef FLOAT_LOOKUP
  623.60 +#undef INT_LOOKUP
  623.61 +
  623.62 +#ifdef FLOAT_LOOKUP
  623.63 +#include "lookup.c" /* catch this in the build system; we #include for
  623.64 +                       compilers (like gcc) that can't inline across
  623.65 +                       modules */
  623.66 +
  623.67 +/* side effect: changes *lsp to cosines of lsp */
  623.68 +void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
  623.69 +                            float amp,float ampoffset){
  623.70 +  int i;
  623.71 +  float wdel=M_PI/ln;
  623.72 +  vorbis_fpu_control fpu;
  623.73 +
  623.74 +  vorbis_fpu_setround(&fpu);
  623.75 +  for(i=0;i<m;i++)lsp[i]=vorbis_coslook(lsp[i]);
  623.76 +
  623.77 +  i=0;
  623.78 +  while(i<n){
  623.79 +    int k=map[i];
  623.80 +    int qexp;
  623.81 +    float p=.7071067812f;
  623.82 +    float q=.7071067812f;
  623.83 +    float w=vorbis_coslook(wdel*k);
  623.84 +    float *ftmp=lsp;
  623.85 +    int c=m>>1;
  623.86 +
  623.87 +    while(c--){
  623.88 +      q*=ftmp[0]-w;
  623.89 +      p*=ftmp[1]-w;
  623.90 +      ftmp+=2;
  623.91 +    }
  623.92 +
  623.93 +    if(m&1){
  623.94 +      /* odd order filter; slightly assymetric */
  623.95 +      /* the last coefficient */
  623.96 +      q*=ftmp[0]-w;
  623.97 +      q*=q;
  623.98 +      p*=p*(1.f-w*w);
  623.99 +    }else{
 623.100 +      /* even order filter; still symmetric */
 623.101 +      q*=q*(1.f+w);
 623.102 +      p*=p*(1.f-w);
 623.103 +    }
 623.104 +
 623.105 +    q=frexp(p+q,&qexp);
 623.106 +    q=vorbis_fromdBlook(amp*
 623.107 +                        vorbis_invsqlook(q)*
 623.108 +                        vorbis_invsq2explook(qexp+m)-
 623.109 +                        ampoffset);
 623.110 +
 623.111 +    do{
 623.112 +      curve[i++]*=q;
 623.113 +    }while(map[i]==k);
 623.114 +  }
 623.115 +  vorbis_fpu_restore(fpu);
 623.116 +}
 623.117 +
 623.118 +#else
 623.119 +
 623.120 +#ifdef INT_LOOKUP
 623.121 +#include "lookup.c" /* catch this in the build system; we #include for
 623.122 +                       compilers (like gcc) that can't inline across
 623.123 +                       modules */
 623.124 +
 623.125 +static const int MLOOP_1[64]={
 623.126 +   0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
 623.127 +  14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14,
 623.128 +  15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
 623.129 +  15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
 623.130 +};
 623.131 +
 623.132 +static const int MLOOP_2[64]={
 623.133 +  0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7,
 623.134 +  8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,
 623.135 +  9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
 623.136 +  9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
 623.137 +};
 623.138 +
 623.139 +static const int MLOOP_3[8]={0,1,2,2,3,3,3,3};
 623.140 +
 623.141 +
 623.142 +/* side effect: changes *lsp to cosines of lsp */
 623.143 +void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
 623.144 +                            float amp,float ampoffset){
 623.145 +
 623.146 +  /* 0 <= m < 256 */
 623.147 +
 623.148 +  /* set up for using all int later */
 623.149 +  int i;
 623.150 +  int ampoffseti=rint(ampoffset*4096.f);
 623.151 +  int ampi=rint(amp*16.f);
 623.152 +  long *ilsp=alloca(m*sizeof(*ilsp));
 623.153 +  for(i=0;i<m;i++)ilsp[i]=vorbis_coslook_i(lsp[i]/M_PI*65536.f+.5f);
 623.154 +
 623.155 +  i=0;
 623.156 +  while(i<n){
 623.157 +    int j,k=map[i];
 623.158 +    unsigned long pi=46341; /* 2**-.5 in 0.16 */
 623.159 +    unsigned long qi=46341;
 623.160 +    int qexp=0,shift;
 623.161 +    long wi=vorbis_coslook_i(k*65536/ln);
 623.162 +
 623.163 +    qi*=labs(ilsp[0]-wi);
 623.164 +    pi*=labs(ilsp[1]-wi);
 623.165 +
 623.166 +    for(j=3;j<m;j+=2){
 623.167 +      if(!(shift=MLOOP_1[(pi|qi)>>25]))
 623.168 +        if(!(shift=MLOOP_2[(pi|qi)>>19]))
 623.169 +          shift=MLOOP_3[(pi|qi)>>16];
 623.170 +      qi=(qi>>shift)*labs(ilsp[j-1]-wi);
 623.171 +      pi=(pi>>shift)*labs(ilsp[j]-wi);
 623.172 +      qexp+=shift;
 623.173 +    }
 623.174 +    if(!(shift=MLOOP_1[(pi|qi)>>25]))
 623.175 +      if(!(shift=MLOOP_2[(pi|qi)>>19]))
 623.176 +        shift=MLOOP_3[(pi|qi)>>16];
 623.177 +
 623.178 +    /* pi,qi normalized collectively, both tracked using qexp */
 623.179 +
 623.180 +    if(m&1){
 623.181 +      /* odd order filter; slightly assymetric */
 623.182 +      /* the last coefficient */
 623.183 +      qi=(qi>>shift)*labs(ilsp[j-1]-wi);
 623.184 +      pi=(pi>>shift)<<14;
 623.185 +      qexp+=shift;
 623.186 +
 623.187 +      if(!(shift=MLOOP_1[(pi|qi)>>25]))
 623.188 +        if(!(shift=MLOOP_2[(pi|qi)>>19]))
 623.189 +          shift=MLOOP_3[(pi|qi)>>16];
 623.190 +
 623.191 +      pi>>=shift;
 623.192 +      qi>>=shift;
 623.193 +      qexp+=shift-14*((m+1)>>1);
 623.194 +
 623.195 +      pi=((pi*pi)>>16);
 623.196 +      qi=((qi*qi)>>16);
 623.197 +      qexp=qexp*2+m;
 623.198 +
 623.199 +      pi*=(1<<14)-((wi*wi)>>14);
 623.200 +      qi+=pi>>14;
 623.201 +
 623.202 +    }else{
 623.203 +      /* even order filter; still symmetric */
 623.204 +
 623.205 +      /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't
 623.206 +         worth tracking step by step */
 623.207 +
 623.208 +      pi>>=shift;
 623.209 +      qi>>=shift;
 623.210 +      qexp+=shift-7*m;
 623.211 +
 623.212 +      pi=((pi*pi)>>16);
 623.213 +      qi=((qi*qi)>>16);
 623.214 +      qexp=qexp*2+m;
 623.215 +
 623.216 +      pi*=(1<<14)-wi;
 623.217 +      qi*=(1<<14)+wi;
 623.218 +      qi=(qi+pi)>>14;
 623.219 +
 623.220 +    }
 623.221 +
 623.222 +
 623.223 +    /* we've let the normalization drift because it wasn't important;
 623.224 +       however, for the lookup, things must be normalized again.  We
 623.225 +       need at most one right shift or a number of left shifts */
 623.226 +
 623.227 +    if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
 623.228 +      qi>>=1; qexp++;
 623.229 +    }else
 623.230 +      while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/
 623.231 +        qi<<=1; qexp--;
 623.232 +      }
 623.233 +
 623.234 +    amp=vorbis_fromdBlook_i(ampi*                     /*  n.4         */
 623.235 +                            vorbis_invsqlook_i(qi,qexp)-
 623.236 +                                                      /*  m.8, m+n<=8 */
 623.237 +                            ampoffseti);              /*  8.12[0]     */
 623.238 +
 623.239 +    curve[i]*=amp;
 623.240 +    while(map[++i]==k)curve[i]*=amp;
 623.241 +  }
 623.242 +}
 623.243 +
 623.244 +#else
 623.245 +
 623.246 +/* old, nonoptimized but simple version for any poor sap who needs to
 623.247 +   figure out what the hell this code does, or wants the other
 623.248 +   fraction of a dB precision */
 623.249 +
 623.250 +/* side effect: changes *lsp to cosines of lsp */
 623.251 +void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
 623.252 +                            float amp,float ampoffset){
 623.253 +  int i;
 623.254 +  float wdel=M_PI/ln;
 623.255 +  for(i=0;i<m;i++)lsp[i]=2.f*cos(lsp[i]);
 623.256 +
 623.257 +  i=0;
 623.258 +  while(i<n){
 623.259 +    int j,k=map[i];
 623.260 +    float p=.5f;
 623.261 +    float q=.5f;
 623.262 +    float w=2.f*cos(wdel*k);
 623.263 +    for(j=1;j<m;j+=2){
 623.264 +      q *= w-lsp[j-1];
 623.265 +      p *= w-lsp[j];
 623.266 +    }
 623.267 +    if(j==m){
 623.268 +      /* odd order filter; slightly assymetric */
 623.269 +      /* the last coefficient */
 623.270 +      q*=w-lsp[j-1];
 623.271 +      p*=p*(4.f-w*w);
 623.272 +      q*=q;
 623.273 +    }else{
 623.274 +      /* even order filter; still symmetric */
 623.275 +      p*=p*(2.f-w);
 623.276 +      q*=q*(2.f+w);
 623.277 +    }
 623.278 +
 623.279 +    q=fromdB(amp/sqrt(p+q)-ampoffset);
 623.280 +
 623.281 +    curve[i]*=q;
 623.282 +    while(map[++i]==k)curve[i]*=q;
 623.283 +  }
 623.284 +}
 623.285 +
 623.286 +#endif
 623.287 +#endif
 623.288 +
 623.289 +static void cheby(float *g, int ord) {
 623.290 +  int i, j;
 623.291 +
 623.292 +  g[0] *= .5f;
 623.293 +  for(i=2; i<= ord; i++) {
 623.294 +    for(j=ord; j >= i; j--) {
 623.295 +      g[j-2] -= g[j];
 623.296 +      g[j] += g[j];
 623.297 +    }
 623.298 +  }
 623.299 +}
 623.300 +
 623.301 +static int comp(const void *a,const void *b){
 623.302 +  return (*(float *)a<*(float *)b)-(*(float *)a>*(float *)b);
 623.303 +}
 623.304 +
 623.305 +/* Newton-Raphson-Maehly actually functioned as a decent root finder,
 623.306 +   but there are root sets for which it gets into limit cycles
 623.307 +   (exacerbated by zero suppression) and fails.  We can't afford to
 623.308 +   fail, even if the failure is 1 in 100,000,000, so we now use
 623.309 +   Laguerre and later polish with Newton-Raphson (which can then
 623.310 +   afford to fail) */
 623.311 +
 623.312 +#define EPSILON 10e-7
 623.313 +static int Laguerre_With_Deflation(float *a,int ord,float *r){
 623.314 +  int i,m;
 623.315 +  double *defl=alloca(sizeof(*defl)*(ord+1));
 623.316 +  for(i=0;i<=ord;i++)defl[i]=a[i];
 623.317 +
 623.318 +  for(m=ord;m>0;m--){
 623.319 +    double new=0.f,delta;
 623.320 +
 623.321 +    /* iterate a root */
 623.322 +    while(1){
 623.323 +      double p=defl[m],pp=0.f,ppp=0.f,denom;
 623.324 +
 623.325 +      /* eval the polynomial and its first two derivatives */
 623.326 +      for(i=m;i>0;i--){
 623.327 +        ppp = new*ppp + pp;
 623.328 +        pp  = new*pp  + p;
 623.329 +        p   = new*p   + defl[i-1];
 623.330 +      }
 623.331 +
 623.332 +      /* Laguerre's method */
 623.333 +      denom=(m-1) * ((m-1)*pp*pp - m*p*ppp);
 623.334 +      if(denom<0)
 623.335 +        return(-1);  /* complex root!  The LPC generator handed us a bad filter */
 623.336 +
 623.337 +      if(pp>0){
 623.338 +        denom = pp + sqrt(denom);
 623.339 +        if(denom<EPSILON)denom=EPSILON;
 623.340 +      }else{
 623.341 +        denom = pp - sqrt(denom);
 623.342 +        if(denom>-(EPSILON))denom=-(EPSILON);
 623.343 +      }
 623.344 +
 623.345 +      delta  = m*p/denom;
 623.346 +      new   -= delta;
 623.347 +
 623.348 +      if(delta<0.f)delta*=-1;
 623.349 +
 623.350 +      if(fabs(delta/new)<10e-12)break;
 623.351 +    }
 623.352 +
 623.353 +    r[m-1]=new;
 623.354 +
 623.355 +    /* forward deflation */
 623.356 +
 623.357 +    for(i=m;i>0;i--)
 623.358 +      defl[i-1]+=new*defl[i];
 623.359 +    defl++;
 623.360 +
 623.361 +  }
 623.362 +  return(0);
 623.363 +}
 623.364 +
 623.365 +
 623.366 +/* for spit-and-polish only */
 623.367 +static int Newton_Raphson(float *a,int ord,float *r){
 623.368 +  int i, k, count=0;
 623.369 +  double error=1.f;
 623.370 +  double *root=alloca(ord*sizeof(*root));
 623.371 +
 623.372 +  for(i=0; i<ord;i++) root[i] = r[i];
 623.373 +
 623.374 +  while(error>1e-20){
 623.375 +    error=0;
 623.376 +
 623.377 +    for(i=0; i<ord; i++) { /* Update each point. */
 623.378 +      double pp=0.,delta;
 623.379 +      double rooti=root[i];
 623.380 +      double p=a[ord];
 623.381 +      for(k=ord-1; k>= 0; k--) {
 623.382 +
 623.383 +        pp= pp* rooti + p;
 623.384 +        p = p * rooti + a[k];
 623.385 +      }
 623.386 +
 623.387 +      delta = p/pp;
 623.388 +      root[i] -= delta;
 623.389 +      error+= delta*delta;
 623.390 +    }
 623.391 +
 623.392 +    if(count>40)return(-1);
 623.393 +
 623.394 +    count++;
 623.395 +  }
 623.396 +
 623.397 +  /* Replaced the original bubble sort with a real sort.  With your
 623.398 +     help, we can eliminate the bubble sort in our lifetime. --Monty */
 623.399 +
 623.400 +  for(i=0; i<ord;i++) r[i] = root[i];
 623.401 +  return(0);
 623.402 +}
 623.403 +
 623.404 +
 623.405 +/* Convert lpc coefficients to lsp coefficients */
 623.406 +int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m){
 623.407 +  int order2=(m+1)>>1;
 623.408 +  int g1_order,g2_order;
 623.409 +  float *g1=alloca(sizeof(*g1)*(order2+1));
 623.410 +  float *g2=alloca(sizeof(*g2)*(order2+1));
 623.411 +  float *g1r=alloca(sizeof(*g1r)*(order2+1));
 623.412 +  float *g2r=alloca(sizeof(*g2r)*(order2+1));
 623.413 +  int i;
 623.414 +
 623.415 +  /* even and odd are slightly different base cases */
 623.416 +  g1_order=(m+1)>>1;
 623.417 +  g2_order=(m)  >>1;
 623.418 +
 623.419 +  /* Compute the lengths of the x polynomials. */
 623.420 +  /* Compute the first half of K & R F1 & F2 polynomials. */
 623.421 +  /* Compute half of the symmetric and antisymmetric polynomials. */
 623.422 +  /* Remove the roots at +1 and -1. */
 623.423 +
 623.424 +  g1[g1_order] = 1.f;
 623.425 +  for(i=1;i<=g1_order;i++) g1[g1_order-i] = lpc[i-1]+lpc[m-i];
 623.426 +  g2[g2_order] = 1.f;
 623.427 +  for(i=1;i<=g2_order;i++) g2[g2_order-i] = lpc[i-1]-lpc[m-i];
 623.428 +
 623.429 +  if(g1_order>g2_order){
 623.430 +    for(i=2; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+2];
 623.431 +  }else{
 623.432 +    for(i=1; i<=g1_order;i++) g1[g1_order-i] -= g1[g1_order-i+1];
 623.433 +    for(i=1; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+1];
 623.434 +  }
 623.435 +
 623.436 +  /* Convert into polynomials in cos(alpha) */
 623.437 +  cheby(g1,g1_order);
 623.438 +  cheby(g2,g2_order);
 623.439 +
 623.440 +  /* Find the roots of the 2 even polynomials.*/
 623.441 +  if(Laguerre_With_Deflation(g1,g1_order,g1r) ||
 623.442 +     Laguerre_With_Deflation(g2,g2_order,g2r))
 623.443 +    return(-1);
 623.444 +
 623.445 +  Newton_Raphson(g1,g1_order,g1r); /* if it fails, it leaves g1r alone */
 623.446 +  Newton_Raphson(g2,g2_order,g2r); /* if it fails, it leaves g2r alone */
 623.447 +
 623.448 +  qsort(g1r,g1_order,sizeof(*g1r),comp);
 623.449 +  qsort(g2r,g2_order,sizeof(*g2r),comp);
 623.450 +
 623.451 +  for(i=0;i<g1_order;i++)
 623.452 +    lsp[i*2] = acos(g1r[i]);
 623.453 +
 623.454 +  for(i=0;i<g2_order;i++)
 623.455 +    lsp[i*2+1] = acos(g2r[i]);
 623.456 +  return(0);
 623.457 +}
   624.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   624.2 +++ b/libs/vorbis/lsp.h	Sat Feb 01 19:58:19 2014 +0200
   624.3 @@ -0,0 +1,28 @@
   624.4 +/********************************************************************
   624.5 + *                                                                  *
   624.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   624.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   624.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   624.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  624.10 + *                                                                  *
  624.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  624.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  624.13 + *                                                                  *
  624.14 + ********************************************************************
  624.15 +
  624.16 +  function: LSP (also called LSF) conversion routines
  624.17 +  last mod: $Id: lsp.h 16227 2009-07-08 06:58:46Z xiphmont $
  624.18 +
  624.19 + ********************************************************************/
  624.20 +
  624.21 +
  624.22 +#ifndef _V_LSP_H_
  624.23 +#define _V_LSP_H_
  624.24 +
  624.25 +extern int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m);
  624.26 +
  624.27 +extern void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,
  624.28 +                                float *lsp,int m,
  624.29 +                                float amp,float ampoffset);
  624.30 +
  624.31 +#endif
   625.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   625.2 +++ b/libs/vorbis/mapping0.c	Sat Feb 01 19:58:19 2014 +0200
   625.3 @@ -0,0 +1,816 @@
   625.4 +/********************************************************************
   625.5 + *                                                                  *
   625.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   625.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   625.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   625.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  625.10 + *                                                                  *
  625.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
  625.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  625.13 + *                                                                  *
  625.14 + ********************************************************************
  625.15 +
  625.16 + function: channel mapping 0 implementation
  625.17 + last mod: $Id: mapping0.c 17022 2010-03-25 03:45:42Z xiphmont $
  625.18 +
  625.19 + ********************************************************************/
  625.20 +
  625.21 +#include <stdlib.h>
  625.22 +#include <stdio.h>
  625.23 +#include <string.h>
  625.24 +#include <math.h>
  625.25 +#include <ogg/ogg.h>
  625.26 +#include "vorbis/codec.h"
  625.27 +#include "codec_internal.h"
  625.28 +#include "codebook.h"
  625.29 +#include "window.h"
  625.30 +#include "registry.h"
  625.31 +#include "psy.h"
  625.32 +#include "misc.h"
  625.33 +
  625.34 +/* simplistic, wasteful way of doing this (unique lookup for each
  625.35 +   mode/submapping); there should be a central repository for
  625.36 +   identical lookups.  That will require minor work, so I'm putting it
  625.37 +   off as low priority.
  625.38 +
  625.39 +   Why a lookup for each backend in a given mode?  Because the
  625.40 +   blocksize is set by the mode, and low backend lookups may require
  625.41 +   parameters from other areas of the mode/mapping */
  625.42 +
  625.43 +static void mapping0_free_info(vorbis_info_mapping *i){
  625.44 +  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i;
  625.45 +  if(info){
  625.46 +    memset(info,0,sizeof(*info));
  625.47 +    _ogg_free(info);
  625.48 +  }
  625.49 +}
  625.50 +
  625.51 +static int ilog(unsigned int v){
  625.52 +  int ret=0;
  625.53 +  if(v)--v;
  625.54 +  while(v){
  625.55 +    ret++;
  625.56 +    v>>=1;
  625.57 +  }
  625.58 +  return(ret);
  625.59 +}
  625.60 +
  625.61 +static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,
  625.62 +                          oggpack_buffer *opb){
  625.63 +  int i;
  625.64 +  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
  625.65 +
  625.66 +  /* another 'we meant to do it this way' hack...  up to beta 4, we
  625.67 +     packed 4 binary zeros here to signify one submapping in use.  We
  625.68 +     now redefine that to mean four bitflags that indicate use of
  625.69 +     deeper features; bit0:submappings, bit1:coupling,
  625.70 +     bit2,3:reserved. This is backward compatable with all actual uses
  625.71 +     of the beta code. */
  625.72 +
  625.73 +  if(info->submaps>1){
  625.74 +    oggpack_write(opb,1,1);
  625.75 +    oggpack_write(opb,info->submaps-1,4);
  625.76 +  }else
  625.77 +    oggpack_write(opb,0,1);
  625.78 +
  625.79 +  if(info->coupling_steps>0){
  625.80 +    oggpack_write(opb,1,1);
  625.81 +    oggpack_write(opb,info->coupling_steps-1,8);
  625.82 +
  625.83 +    for(i=0;i<info->coupling_steps;i++){
  625.84 +      oggpack_write(opb,info->coupling_mag[i],ilog(vi->channels));
  625.85 +      oggpack_write(opb,info->coupling_ang[i],ilog(vi->channels));
  625.86 +    }
  625.87 +  }else
  625.88 +    oggpack_write(opb,0,1);
  625.89 +
  625.90 +  oggpack_write(opb,0,2); /* 2,3:reserved */
  625.91 +
  625.92 +  /* we don't write the channel submappings if we only have one... */
  625.93 +  if(info->submaps>1){
  625.94 +    for(i=0;i<vi->channels;i++)
  625.95 +      oggpack_write(opb,info->chmuxlist[i],4);
  625.96 +  }
  625.97 +  for(i=0;i<info->submaps;i++){
  625.98 +    oggpack_write(opb,0,8); /* time submap unused */
  625.99 +    oggpack_write(opb,info->floorsubmap[i],8);
 625.100 +    oggpack_write(opb,info->residuesubmap[i],8);
 625.101 +  }
 625.102 +}
 625.103 +
 625.104 +/* also responsible for range checking */
 625.105 +static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
 625.106 +  int i,b;
 625.107 +  vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info));
 625.108 +  codec_setup_info     *ci=vi->codec_setup;
 625.109 +  memset(info,0,sizeof(*info));
 625.110 +
 625.111 +  b=oggpack_read(opb,1);
 625.112 +  if(b<0)goto err_out;
 625.113 +  if(b){
 625.114 +    info->submaps=oggpack_read(opb,4)+1;
 625.115 +    if(info->submaps<=0)goto err_out;
 625.116 +  }else
 625.117 +    info->submaps=1;
 625.118 +
 625.119 +  b=oggpack_read(opb,1);
 625.120 +  if(b<0)goto err_out;
 625.121 +  if(b){
 625.122 +    info->coupling_steps=oggpack_read(opb,8)+1;
 625.123 +    if(info->coupling_steps<=0)goto err_out;
 625.124 +    for(i=0;i<info->coupling_steps;i++){
 625.125 +      int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels));
 625.126 +      int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels));
 625.127 +
 625.128 +      if(testM<0 ||
 625.129 +         testA<0 ||
 625.130 +         testM==testA ||
 625.131 +         testM>=vi->channels ||
 625.132 +         testA>=vi->channels) goto err_out;
 625.133 +    }
 625.134 +
 625.135 +  }
 625.136 +
 625.137 +  if(oggpack_read(opb,2)!=0)goto err_out; /* 2,3:reserved */
 625.138 +
 625.139 +  if(info->submaps>1){
 625.140 +    for(i=0;i<vi->channels;i++){
 625.141 +      info->chmuxlist[i]=oggpack_read(opb,4);
 625.142 +      if(info->chmuxlist[i]>=info->submaps || info->chmuxlist[i]<0)goto err_out;
 625.143 +    }
 625.144 +  }
 625.145 +  for(i=0;i<info->submaps;i++){
 625.146 +    oggpack_read(opb,8); /* time submap unused */
 625.147 +    info->floorsubmap[i]=oggpack_read(opb,8);
 625.148 +    if(info->floorsubmap[i]>=ci->floors || info->floorsubmap[i]<0)goto err_out;
 625.149 +    info->residuesubmap[i]=oggpack_read(opb,8);
 625.150 +    if(info->residuesubmap[i]>=ci->residues || info->residuesubmap[i]<0)goto err_out;
 625.151 +  }
 625.152 +
 625.153 +  return info;
 625.154 +
 625.155 + err_out:
 625.156 +  mapping0_free_info(info);
 625.157 +  return(NULL);
 625.158 +}
 625.159 +
 625.160 +#include "os.h"
 625.161 +#include "lpc.h"
 625.162 +#include "lsp.h"
 625.163 +#include "envelope.h"
 625.164 +#include "mdct.h"
 625.165 +#include "psy.h"
 625.166 +#include "scales.h"
 625.167 +
 625.168 +#if 0
 625.169 +static long seq=0;
 625.170 +static ogg_int64_t total=0;
 625.171 +static float FLOOR1_fromdB_LOOKUP[256]={
 625.172 +  1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
 625.173 +  1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
 625.174 +  1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
 625.175 +  2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
 625.176 +  2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
 625.177 +  3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
 625.178 +  4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
 625.179 +  6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
 625.180 +  7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
 625.181 +  1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
 625.182 +  1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
 625.183 +  1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
 625.184 +  2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
 625.185 +  2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
 625.186 +  3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
 625.187 +  4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
 625.188 +  5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
 625.189 +  7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
 625.190 +  9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
 625.191 +  1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
 625.192 +  1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
 625.193 +  2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
 625.194 +  2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
 625.195 +  3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
 625.196 +  4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
 625.197 +  5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
 625.198 +  7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
 625.199 +  9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
 625.200 +  0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
 625.201 +  0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
 625.202 +  0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
 625.203 +  0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
 625.204 +  0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
 625.205 +  0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
 625.206 +  0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
 625.207 +  0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
 625.208 +  0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
 625.209 +  0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
 625.210 +  0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
 625.211 +  0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
 625.212 +  0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
 625.213 +  0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
 625.214 +  0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
 625.215 +  0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
 625.216 +  0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
 625.217 +  0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
 625.218 +  0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
 625.219 +  0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
 625.220 +  0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
 625.221 +  0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
 625.222 +  0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
 625.223 +  0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
 625.224 +  0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
 625.225 +  0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
 625.226 +  0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
 625.227 +  0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
 625.228 +  0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
 625.229 +  0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
 625.230 +  0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
 625.231 +  0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
 625.232 +  0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
 625.233 +  0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
 625.234 +  0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
 625.235 +  0.82788260F, 0.88168307F, 0.9389798F, 1.F,
 625.236 +};
 625.237 +
 625.238 +#endif
 625.239 +
 625.240 +
 625.241 +static int mapping0_forward(vorbis_block *vb){
 625.242 +  vorbis_dsp_state      *vd=vb->vd;
 625.243 +  vorbis_info           *vi=vd->vi;
 625.244 +  codec_setup_info      *ci=vi->codec_setup;
 625.245 +  private_state         *b=vb->vd->backend_state;
 625.246 +  vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
 625.247 +  int                    n=vb->pcmend;
 625.248 +  int i,j,k;
 625.249 +
 625.250 +  int    *nonzero    = alloca(sizeof(*nonzero)*vi->channels);
 625.251 +  float  **gmdct     = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct));
 625.252 +  int    **iwork      = _vorbis_block_alloc(vb,vi->channels*sizeof(*iwork));
 625.253 +  int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts));
 625.254 +
 625.255 +  float global_ampmax=vbi->ampmax;
 625.256 +  float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels);
 625.257 +  int blocktype=vbi->blocktype;
 625.258 +
 625.259 +  int modenumber=vb->W;
 625.260 +  vorbis_info_mapping0 *info=ci->map_param[modenumber];
 625.261 +  vorbis_look_psy *psy_look=b->psy+blocktype+(vb->W?2:0);
 625.262 +
 625.263 +  vb->mode=modenumber;
 625.264 +
 625.265 +  for(i=0;i<vi->channels;i++){
 625.266 +    float scale=4.f/n;
 625.267 +    float scale_dB;
 625.268 +
 625.269 +    float *pcm     =vb->pcm[i];
 625.270 +    float *logfft  =pcm;
 625.271 +
 625.272 +    iwork[i]=_vorbis_block_alloc(vb,n/2*sizeof(**iwork));
 625.273 +    gmdct[i]=_vorbis_block_alloc(vb,n/2*sizeof(**gmdct));
 625.274 +
 625.275 +    scale_dB=todB(&scale) + .345; /* + .345 is a hack; the original
 625.276 +                                     todB estimation used on IEEE 754
 625.277 +                                     compliant machines had a bug that
 625.278 +                                     returned dB values about a third
 625.279 +                                     of a decibel too high.  The bug
 625.280 +                                     was harmless because tunings
 625.281 +                                     implicitly took that into
 625.282 +                                     account.  However, fixing the bug
 625.283 +                                     in the estimator requires
 625.284 +                                     changing all the tunings as well.
 625.285 +                                     For now, it's easier to sync
 625.286 +                                     things back up here, and
 625.287 +                                     recalibrate the tunings in the
 625.288 +                                     next major model upgrade. */
 625.289 +
 625.290 +#if 0
 625.291 +    if(vi->channels==2){
 625.292 +      if(i==0)
 625.293 +        _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2);
 625.294 +      else
 625.295 +        _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2);
 625.296 +    }else{
 625.297 +      _analysis_output("pcm",seq,pcm,n,0,0,total-n/2);
 625.298 +    }
 625.299 +#endif
 625.300 +
 625.301 +    /* window the PCM data */
 625.302 +    _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
 625.303 +
 625.304 +#if 0
 625.305 +    if(vi->channels==2){
 625.306 +      if(i==0)
 625.307 +        _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2);
 625.308 +      else
 625.309 +        _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2);
 625.310 +    }else{
 625.311 +      _analysis_output("windowed",seq,pcm,n,0,0,total-n/2);
 625.312 +    }
 625.313 +#endif
 625.314 +
 625.315 +    /* transform the PCM data */
 625.316 +    /* only MDCT right now.... */
 625.317 +    mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]);
 625.318 +
 625.319 +    /* FFT yields more accurate tonal estimation (not phase sensitive) */
 625.320 +    drft_forward(&b->fft_look[vb->W],pcm);
 625.321 +    logfft[0]=scale_dB+todB(pcm)  + .345; /* + .345 is a hack; the
 625.322 +                                     original todB estimation used on
 625.323 +                                     IEEE 754 compliant machines had a
 625.324 +                                     bug that returned dB values about
 625.325 +                                     a third of a decibel too high.
 625.326 +                                     The bug was harmless because
 625.327 +                                     tunings implicitly took that into
 625.328 +                                     account.  However, fixing the bug
 625.329 +                                     in the estimator requires
 625.330 +                                     changing all the tunings as well.
 625.331 +                                     For now, it's easier to sync
 625.332 +                                     things back up here, and
 625.333 +                                     recalibrate the tunings in the
 625.334 +                                     next major model upgrade. */
 625.335 +    local_ampmax[i]=logfft[0];
 625.336 +    for(j=1;j<n-1;j+=2){
 625.337 +      float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1];
 625.338 +      temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp)  + .345; /* +
 625.339 +                                     .345 is a hack; the original todB
 625.340 +                                     estimation used on IEEE 754
 625.341 +                                     compliant machines had a bug that
 625.342 +                                     returned dB values about a third
 625.343 +                                     of a decibel too high.  The bug
 625.344 +                                     was harmless because tunings
 625.345 +                                     implicitly took that into
 625.346 +                                     account.  However, fixing the bug
 625.347 +                                     in the estimator requires
 625.348 +                                     changing all the tunings as well.
 625.349 +                                     For now, it's easier to sync
 625.350 +                                     things back up here, and
 625.351 +                                     recalibrate the tunings in the
 625.352 +                                     next major model upgrade. */
 625.353 +      if(temp>local_ampmax[i])local_ampmax[i]=temp;
 625.354 +    }
 625.355 +
 625.356 +    if(local_ampmax[i]>0.f)local_ampmax[i]=0.f;
 625.357 +    if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
 625.358 +
 625.359 +#if 0
 625.360 +    if(vi->channels==2){
 625.361 +      if(i==0){
 625.362 +        _analysis_output("fftL",seq,logfft,n/2,1,0,0);
 625.363 +      }else{
 625.364 +        _analysis_output("fftR",seq,logfft,n/2,1,0,0);
 625.365 +      }
 625.366 +    }else{
 625.367 +      _analysis_output("fft",seq,logfft,n/2,1,0,0);
 625.368 +    }
 625.369 +#endif
 625.370 +
 625.371 +  }
 625.372 +
 625.373 +  {
 625.374 +    float   *noise        = _vorbis_block_alloc(vb,n/2*sizeof(*noise));
 625.375 +    float   *tone         = _vorbis_block_alloc(vb,n/2*sizeof(*tone));
 625.376 +
 625.377 +    for(i=0;i<vi->channels;i++){
 625.378 +      /* the encoder setup assumes that all the modes used by any
 625.379 +         specific bitrate tweaking use the same floor */
 625.380 +
 625.381 +      int submap=info->chmuxlist[i];
 625.382 +
 625.383 +      /* the following makes things clearer to *me* anyway */
 625.384 +      float *mdct    =gmdct[i];
 625.385 +      float *logfft  =vb->pcm[i];
 625.386 +
 625.387 +      float *logmdct =logfft+n/2;
 625.388 +      float *logmask =logfft;
 625.389 +
 625.390 +      vb->mode=modenumber;
 625.391 +
 625.392 +      floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts));
 625.393 +      memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS);
 625.394 +
 625.395 +      for(j=0;j<n/2;j++)
 625.396 +        logmdct[j]=todB(mdct+j)  + .345; /* + .345 is a hack; the original
 625.397 +                                     todB estimation used on IEEE 754
 625.398 +                                     compliant machines had a bug that
 625.399 +                                     returned dB values about a third
 625.400 +                                     of a decibel too high.  The bug
 625.401 +                                     was harmless because tunings
 625.402 +                                     implicitly took that into
 625.403 +                                     account.  However, fixing the bug
 625.404 +                                     in the estimator requires
 625.405 +                                     changing all the tunings as well.
 625.406 +                                     For now, it's easier to sync
 625.407 +                                     things back up here, and
 625.408 +                                     recalibrate the tunings in the
 625.409 +                                     next major model upgrade. */
 625.410 +
 625.411 +#if 0
 625.412 +      if(vi->channels==2){
 625.413 +        if(i==0)
 625.414 +          _analysis_output("mdctL",seq,logmdct,n/2,1,0,0);
 625.415 +        else
 625.416 +          _analysis_output("mdctR",seq,logmdct,n/2,1,0,0);
 625.417 +      }else{
 625.418 +        _analysis_output("mdct",seq,logmdct,n/2,1,0,0);
 625.419 +      }
 625.420 +#endif
 625.421 +
 625.422 +      /* first step; noise masking.  Not only does 'noise masking'
 625.423 +         give us curves from which we can decide how much resolution
 625.424 +         to give noise parts of the spectrum, it also implicitly hands
 625.425 +         us a tonality estimate (the larger the value in the
 625.426 +         'noise_depth' vector, the more tonal that area is) */
 625.427 +
 625.428 +      _vp_noisemask(psy_look,
 625.429 +                    logmdct,
 625.430 +                    noise); /* noise does not have by-frequency offset
 625.431 +                               bias applied yet */
 625.432 +#if 0
 625.433 +      if(vi->channels==2){
 625.434 +        if(i==0)
 625.435 +          _analysis_output("noiseL",seq,noise,n/2,1,0,0);
 625.436 +        else
 625.437 +          _analysis_output("noiseR",seq,noise,n/2,1,0,0);
 625.438 +      }else{
 625.439 +        _analysis_output("noise",seq,noise,n/2,1,0,0);
 625.440 +      }
 625.441 +#endif
 625.442 +
 625.443 +      /* second step: 'all the other crap'; all the stuff that isn't
 625.444 +         computed/fit for bitrate management goes in the second psy
 625.445 +         vector.  This includes tone masking, peak limiting and ATH */
 625.446 +
 625.447 +      _vp_tonemask(psy_look,
 625.448 +                   logfft,
 625.449 +                   tone,
 625.450 +                   global_ampmax,
 625.451 +                   local_ampmax[i]);
 625.452 +
 625.453 +#if 0
 625.454 +      if(vi->channels==2){
 625.455 +        if(i==0)
 625.456 +          _analysis_output("toneL",seq,tone,n/2,1,0,0);
 625.457 +        else
 625.458 +          _analysis_output("toneR",seq,tone,n/2,1,0,0);
 625.459 +      }else{
 625.460 +        _analysis_output("tone",seq,tone,n/2,1,0,0);
 625.461 +      }
 625.462 +#endif
 625.463 +
 625.464 +      /* third step; we offset the noise vectors, overlay tone
 625.465 +         masking.  We then do a floor1-specific line fit.  If we're
 625.466 +         performing bitrate management, the line fit is performed
 625.467 +         multiple times for up/down tweakage on demand. */
 625.468 +
 625.469 +#if 0
 625.470 +      {
 625.471 +      float aotuv[psy_look->n];
 625.472 +#endif
 625.473 +
 625.474 +        _vp_offset_and_mix(psy_look,
 625.475 +                           noise,
 625.476 +                           tone,
 625.477 +                           1,
 625.478 +                           logmask,
 625.479 +                           mdct,
 625.480 +                           logmdct);
 625.481 +
 625.482 +#if 0
 625.483 +        if(vi->channels==2){
 625.484 +          if(i==0)
 625.485 +            _analysis_output("aotuvM1_L",seq,aotuv,psy_look->n,1,1,0);
 625.486 +          else
 625.487 +            _analysis_output("aotuvM1_R",seq,aotuv,psy_look->n,1,1,0);
 625.488 +        }else{
 625.489 +          _analysis_output("aotuvM1",seq,aotuv,psy_look->n,1,1,0);
 625.490 +        }
 625.491 +      }
 625.492 +#endif
 625.493 +
 625.494 +
 625.495 +#if 0
 625.496 +      if(vi->channels==2){
 625.497 +        if(i==0)
 625.498 +          _analysis_output("mask1L",seq,logmask,n/2,1,0,0);
 625.499 +        else
 625.500 +          _analysis_output("mask1R",seq,logmask,n/2,1,0,0);
 625.501 +      }else{
 625.502 +        _analysis_output("mask1",seq,logmask,n/2,1,0,0);
 625.503 +      }
 625.504 +#endif
 625.505 +
 625.506 +      /* this algorithm is hardwired to floor 1 for now; abort out if
 625.507 +         we're *not* floor1.  This won't happen unless someone has
 625.508 +         broken the encode setup lib.  Guard it anyway. */
 625.509 +      if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1);
 625.510 +
 625.511 +      floor_posts[i][PACKETBLOBS/2]=
 625.512 +        floor1_fit(vb,b->flr[info->floorsubmap[submap]],
 625.513 +                   logmdct,
 625.514 +                   logmask);
 625.515 +
 625.516 +      /* are we managing bitrate?  If so, perform two more fits for
 625.517 +         later rate tweaking (fits represent hi/lo) */
 625.518 +      if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){
 625.519 +        /* higher rate by way of lower noise curve */
 625.520 +
 625.521 +        _vp_offset_and_mix(psy_look,
 625.522 +                           noise,
 625.523 +                           tone,
 625.524 +                           2,
 625.525 +                           logmask,
 625.526 +                           mdct,
 625.527 +                           logmdct);
 625.528 +
 625.529 +#if 0
 625.530 +        if(vi->channels==2){
 625.531 +          if(i==0)
 625.532 +            _analysis_output("mask2L",seq,logmask,n/2,1,0,0);
 625.533 +          else
 625.534 +            _analysis_output("mask2R",seq,logmask,n/2,1,0,0);
 625.535 +        }else{
 625.536 +          _analysis_output("mask2",seq,logmask,n/2,1,0,0);
 625.537 +        }
 625.538 +#endif
 625.539 +
 625.540 +        floor_posts[i][PACKETBLOBS-1]=
 625.541 +          floor1_fit(vb,b->flr[info->floorsubmap[submap]],
 625.542 +                     logmdct,
 625.543 +                     logmask);
 625.544 +
 625.545 +        /* lower rate by way of higher noise curve */
 625.546 +        _vp_offset_and_mix(psy_look,
 625.547 +                           noise,
 625.548 +                           tone,
 625.549 +                           0,
 625.550 +                           logmask,
 625.551 +                           mdct,
 625.552 +                           logmdct);
 625.553 +
 625.554 +#if 0
 625.555 +        if(vi->channels==2){
 625.556 +          if(i==0)
 625.557 +            _analysis_output("mask0L",seq,logmask,n/2,1,0,0);
 625.558 +          else
 625.559 +            _analysis_output("mask0R",seq,logmask,n/2,1,0,0);
 625.560 +        }else{
 625.561 +          _analysis_output("mask0",seq,logmask,n/2,1,0,0);
 625.562 +        }
 625.563 +#endif
 625.564 +
 625.565 +        floor_posts[i][0]=
 625.566 +          floor1_fit(vb,b->flr[info->floorsubmap[submap]],
 625.567 +                     logmdct,
 625.568 +                     logmask);
 625.569 +
 625.570 +        /* we also interpolate a range of intermediate curves for
 625.571 +           intermediate rates */
 625.572 +        for(k=1;k<PACKETBLOBS/2;k++)
 625.573 +          floor_posts[i][k]=
 625.574 +            floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
 625.575 +                                   floor_posts[i][0],
 625.576 +                                   floor_posts[i][PACKETBLOBS/2],
 625.577 +                                   k*65536/(PACKETBLOBS/2));
 625.578 +        for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++)
 625.579 +          floor_posts[i][k]=
 625.580 +            floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
 625.581 +                                   floor_posts[i][PACKETBLOBS/2],
 625.582 +                                   floor_posts[i][PACKETBLOBS-1],
 625.583 +                                   (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2));
 625.584 +      }
 625.585 +    }
 625.586 +  }
 625.587 +  vbi->ampmax=global_ampmax;
 625.588 +
 625.589 +  /*
 625.590 +    the next phases are performed once for vbr-only and PACKETBLOB
 625.591 +    times for bitrate managed modes.
 625.592 +
 625.593 +    1) encode actual mode being used
 625.594 +    2) encode the floor for each channel, compute coded mask curve/res
 625.595 +    3) normalize and couple.
 625.596 +    4) encode residue
 625.597 +    5) save packet bytes to the packetblob vector
 625.598 +
 625.599 +  */
 625.600 +
 625.601 +  /* iterate over the many masking curve fits we've created */
 625.602 +
 625.603 +  {
 625.604 +    int **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels);
 625.605 +    int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
 625.606 +
 625.607 +    for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2);
 625.608 +        k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2);
 625.609 +        k++){
 625.610 +      oggpack_buffer *opb=vbi->packetblob[k];
 625.611 +
 625.612 +      /* start out our new packet blob with packet type and mode */
 625.613 +      /* Encode the packet type */
 625.614 +      oggpack_write(opb,0,1);
 625.615 +      /* Encode the modenumber */
 625.616 +      /* Encode frame mode, pre,post windowsize, then dispatch */
 625.617 +      oggpack_write(opb,modenumber,b->modebits);
 625.618 +      if(vb->W){
 625.619 +        oggpack_write(opb,vb->lW,1);
 625.620 +        oggpack_write(opb,vb->nW,1);
 625.621 +      }
 625.622 +
 625.623 +      /* encode floor, compute masking curve, sep out residue */
 625.624 +      for(i=0;i<vi->channels;i++){
 625.625 +        int submap=info->chmuxlist[i];
 625.626 +        int *ilogmask=iwork[i];
 625.627 +
 625.628 +        nonzero[i]=floor1_encode(opb,vb,b->flr[info->floorsubmap[submap]],
 625.629 +                                 floor_posts[i][k],
 625.630 +                                 ilogmask);
 625.631 +#if 0
 625.632 +        {
 625.633 +          char buf[80];
 625.634 +          sprintf(buf,"maskI%c%d",i?'R':'L',k);
 625.635 +          float work[n/2];
 625.636 +          for(j=0;j<n/2;j++)
 625.637 +            work[j]=FLOOR1_fromdB_LOOKUP[iwork[i][j]];
 625.638 +          _analysis_output(buf,seq,work,n/2,1,1,0);
 625.639 +        }
 625.640 +#endif
 625.641 +      }
 625.642 +
 625.643 +      /* our iteration is now based on masking curve, not prequant and
 625.644 +         coupling.  Only one prequant/coupling step */
 625.645 +
 625.646 +      /* quantize/couple */
 625.647 +      /* incomplete implementation that assumes the tree is all depth
 625.648 +         one, or no tree at all */
 625.649 +      _vp_couple_quantize_normalize(k,
 625.650 +                                    &ci->psy_g_param,
 625.651 +                                    psy_look,
 625.652 +                                    info,
 625.653 +                                    gmdct,
 625.654 +                                    iwork,
 625.655 +                                    nonzero,
 625.656 +                                    ci->psy_g_param.sliding_lowpass[vb->W][k],
 625.657 +                                    vi->channels);
 625.658 +
 625.659 +#if 0
 625.660 +      for(i=0;i<vi->channels;i++){
 625.661 +        char buf[80];
 625.662 +        sprintf(buf,"res%c%d",i?'R':'L',k);
 625.663 +        float work[n/2];
 625.664 +        for(j=0;j<n/2;j++)
 625.665 +          work[j]=iwork[i][j];
 625.666 +        _analysis_output(buf,seq,work,n/2,1,0,0);
 625.667 +      }
 625.668 +#endif
 625.669 +
 625.670 +      /* classify and encode by submap */
 625.671 +      for(i=0;i<info->submaps;i++){
 625.672 +        int ch_in_bundle=0;
 625.673 +        long **classifications;
 625.674 +        int resnum=info->residuesubmap[i];
 625.675 +
 625.676 +        for(j=0;j<vi->channels;j++){
 625.677 +          if(info->chmuxlist[j]==i){
 625.678 +            zerobundle[ch_in_bundle]=0;
 625.679 +            if(nonzero[j])zerobundle[ch_in_bundle]=1;
 625.680 +            couple_bundle[ch_in_bundle++]=iwork[j];
 625.681 +          }
 625.682 +        }
 625.683 +
 625.684 +        classifications=_residue_P[ci->residue_type[resnum]]->
 625.685 +          class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle);
 625.686 +
 625.687 +        ch_in_bundle=0;
 625.688 +        for(j=0;j<vi->channels;j++)
 625.689 +          if(info->chmuxlist[j]==i)
 625.690 +            couple_bundle[ch_in_bundle++]=iwork[j];
 625.691 +
 625.692 +        _residue_P[ci->residue_type[resnum]]->
 625.693 +          forward(opb,vb,b->residue[resnum],
 625.694 +                  couple_bundle,zerobundle,ch_in_bundle,classifications,i);
 625.695 +      }
 625.696 +
 625.697 +      /* ok, done encoding.  Next protopacket. */
 625.698 +    }
 625.699 +
 625.700 +  }
 625.701 +
 625.702 +#if 0
 625.703 +  seq++;
 625.704 +  total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;
 625.705 +#endif
 625.706 +  return(0);
 625.707 +}
 625.708 +
 625.709 +static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){
 625.710 +  vorbis_dsp_state     *vd=vb->vd;
 625.711 +  vorbis_info          *vi=vd->vi;
 625.712 +  codec_setup_info     *ci=vi->codec_setup;
 625.713 +  private_state        *b=vd->backend_state;
 625.714 +  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
 625.715 +
 625.716 +  int                   i,j;
 625.717 +  long                  n=vb->pcmend=ci->blocksizes[vb->W];
 625.718 +
 625.719 +  float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels);
 625.720 +  int    *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
 625.721 +
 625.722 +  int   *nonzero  =alloca(sizeof(*nonzero)*vi->channels);
 625.723 +  void **floormemo=alloca(sizeof(*floormemo)*vi->channels);
 625.724 +
 625.725 +  /* recover the spectral envelope; store it in the PCM vector for now */
 625.726 +  for(i=0;i<vi->channels;i++){
 625.727 +    int submap=info->chmuxlist[i];
 625.728 +    floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]->
 625.729 +      inverse1(vb,b->flr[info->floorsubmap[submap]]);
 625.730 +    if(floormemo[i])
 625.731 +      nonzero[i]=1;
 625.732 +    else
 625.733 +      nonzero[i]=0;
 625.734 +    memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
 625.735 +  }
 625.736 +
 625.737 +  /* channel coupling can 'dirty' the nonzero listing */
 625.738 +  for(i=0;i<info->coupling_steps;i++){
 625.739 +    if(nonzero[info->coupling_mag[i]] ||
 625.740 +       nonzero[info->coupling_ang[i]]){
 625.741 +      nonzero[info->coupling_mag[i]]=1;
 625.742 +      nonzero[info->coupling_ang[i]]=1;
 625.743 +    }
 625.744 +  }
 625.745 +
 625.746 +  /* recover the residue into our working vectors */
 625.747 +  for(i=0;i<info->submaps;i++){
 625.748 +    int ch_in_bundle=0;
 625.749 +    for(j=0;j<vi->channels;j++){
 625.750 +      if(info->chmuxlist[j]==i){
 625.751 +        if(nonzero[j])
 625.752 +          zerobundle[ch_in_bundle]=1;
 625.753 +        else
 625.754 +          zerobundle[ch_in_bundle]=0;
 625.755 +        pcmbundle[ch_in_bundle++]=vb->pcm[j];
 625.756 +      }
 625.757 +    }
 625.758 +
 625.759 +    _residue_P[ci->residue_type[info->residuesubmap[i]]]->
 625.760 +      inverse(vb,b->residue[info->residuesubmap[i]],
 625.761 +              pcmbundle,zerobundle,ch_in_bundle);
 625.762 +  }
 625.763 +
 625.764 +  /* channel coupling */
 625.765 +  for(i=info->coupling_steps-1;i>=0;i--){
 625.766 +    float *pcmM=vb->pcm[info->coupling_mag[i]];
 625.767 +    float *pcmA=vb->pcm[info->coupling_ang[i]];
 625.768 +
 625.769 +    for(j=0;j<n/2;j++){
 625.770 +      float mag=pcmM[j];
 625.771 +      float ang=pcmA[j];
 625.772 +
 625.773 +      if(mag>0)
 625.774 +        if(ang>0){
 625.775 +          pcmM[j]=mag;
 625.776 +          pcmA[j]=mag-ang;
 625.777 +        }else{
 625.778 +          pcmA[j]=mag;
 625.779 +          pcmM[j]=mag+ang;
 625.780 +        }
 625.781 +      else
 625.782 +        if(ang>0){
 625.783 +          pcmM[j]=mag;
 625.784 +          pcmA[j]=mag+ang;
 625.785 +        }else{
 625.786 +          pcmA[j]=mag;
 625.787 +          pcmM[j]=mag-ang;
 625.788 +        }
 625.789 +    }
 625.790 +  }
 625.791 +
 625.792 +  /* compute and apply spectral envelope */
 625.793 +  for(i=0;i<vi->channels;i++){
 625.794 +    float *pcm=vb->pcm[i];
 625.795 +    int submap=info->chmuxlist[i];
 625.796 +    _floor_P[ci->floor_type[info->floorsubmap[submap]]]->
 625.797 +      inverse2(vb,b->flr[info->floorsubmap[submap]],
 625.798 +               floormemo[i],pcm);
 625.799 +  }
 625.800 +
 625.801 +  /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
 625.802 +  /* only MDCT right now.... */
 625.803 +  for(i=0;i<vi->channels;i++){
 625.804 +    float *pcm=vb->pcm[i];
 625.805 +    mdct_backward(b->transform[vb->W][0],pcm,pcm);
 625.806 +  }
 625.807 +
 625.808 +  /* all done! */
 625.809 +  return(0);
 625.810 +}
 625.811 +
 625.812 +/* export hooks */
 625.813 +const vorbis_func_mapping mapping0_exportbundle={
 625.814 +  &mapping0_pack,
 625.815 +  &mapping0_unpack,
 625.816 +  &mapping0_free_info,
 625.817 +  &mapping0_forward,
 625.818 +  &mapping0_inverse
 625.819 +};
   626.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   626.2 +++ b/libs/vorbis/masking.h	Sat Feb 01 19:58:19 2014 +0200
   626.3 @@ -0,0 +1,785 @@
   626.4 +/********************************************************************
   626.5 + *                                                                  *
   626.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   626.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   626.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   626.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  626.10 + *                                                                  *
  626.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  626.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  626.13 + *                                                                  *
  626.14 + ********************************************************************
  626.15 +
  626.16 + function: masking curve data for psychoacoustics
  626.17 + last mod: $Id: masking.h 16227 2009-07-08 06:58:46Z xiphmont $
  626.18 +
  626.19 + ********************************************************************/
  626.20 +
  626.21 +#ifndef _V_MASKING_H_
  626.22 +#define _V_MASKING_H_
  626.23 +
  626.24 +/* more detailed ATH; the bass if flat to save stressing the floor
  626.25 +   overly for only a bin or two of savings. */
  626.26 +
  626.27 +#define MAX_ATH 88
  626.28 +static const float ATH[]={
  626.29 +  /*15*/  -51, -52, -53, -54, -55, -56, -57, -58,
  626.30 +  /*31*/  -59, -60, -61, -62, -63, -64, -65, -66,
  626.31 +  /*63*/  -67, -68, -69, -70, -71, -72, -73, -74,
  626.32 +  /*125*/ -75, -76, -77, -78, -80, -81, -82, -83,
  626.33 +  /*250*/ -84, -85, -86, -87, -88, -88, -89, -89,
  626.34 +  /*500*/ -90, -91, -91, -92, -93, -94, -95, -96,
  626.35 +  /*1k*/  -96, -97, -98, -98, -99, -99,-100,-100,
  626.36 +  /*2k*/ -101,-102,-103,-104,-106,-107,-107,-107,
  626.37 +  /*4k*/ -107,-105,-103,-102,-101, -99, -98, -96,
  626.38 +  /*8k*/  -95, -95, -96, -97, -96, -95, -93, -90,
  626.39 +  /*16k*/ -80, -70, -50, -40, -30, -30, -30, -30
  626.40 +};
  626.41 +
  626.42 +/* The tone masking curves from Ehmer's and Fielder's papers have been
  626.43 +   replaced by an empirically collected data set.  The previously
  626.44 +   published values were, far too often, simply on crack. */
  626.45 +
  626.46 +#define EHMER_OFFSET 16
  626.47 +#define EHMER_MAX 56
  626.48 +
  626.49 +/* masking tones from -50 to 0dB, 62.5 through 16kHz at half octaves
  626.50 +   test tones from -2 octaves to +5 octaves sampled at eighth octaves */
  626.51 +/* (Vorbis 0dB, the loudest possible tone, is assumed to be ~100dB SPL
  626.52 +   for collection of these curves) */
  626.53 +
  626.54 +static const float tonemasks[P_BANDS][6][EHMER_MAX]={
  626.55 +  /* 62.5 Hz */
  626.56 +  {{ -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,
  626.57 +     -60,  -60,  -60,  -60,  -62,  -62,  -65,  -73,
  626.58 +     -69,  -68,  -68,  -67,  -70,  -70,  -72,  -74,
  626.59 +     -75,  -79,  -79,  -80,  -83,  -88,  -93, -100,
  626.60 +     -110, -999, -999, -999, -999, -999, -999, -999,
  626.61 +     -999, -999, -999, -999, -999, -999, -999, -999,
  626.62 +     -999, -999, -999, -999, -999, -999, -999, -999},
  626.63 +   { -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
  626.64 +     -48,  -48,  -48,  -48,  -48,  -53,  -61,  -66,
  626.65 +     -66,  -68,  -67,  -70,  -76,  -76,  -72,  -73,
  626.66 +     -75,  -76,  -78,  -79,  -83,  -88,  -93, -100,
  626.67 +     -110, -999, -999, -999, -999, -999, -999, -999,
  626.68 +     -999, -999, -999, -999, -999, -999, -999, -999,
  626.69 +     -999, -999, -999, -999, -999, -999, -999, -999},
  626.70 +   { -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
  626.71 +     -38,  -40,  -42,  -46,  -48,  -53,  -55,  -62,
  626.72 +     -65,  -58,  -56,  -56,  -61,  -60,  -65,  -67,
  626.73 +     -69,  -71,  -77,  -77,  -78,  -80,  -82,  -84,
  626.74 +     -88,  -93,  -98, -106, -112, -999, -999, -999,
  626.75 +     -999, -999, -999, -999, -999, -999, -999, -999,
  626.76 +     -999, -999, -999, -999, -999, -999, -999, -999},
  626.77 +   { -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
  626.78 +     -25,  -26,  -27,  -29,  -32,  -38,  -48,  -52,
  626.79 +     -52,  -50,  -48,  -48,  -51,  -52,  -54,  -60,
  626.80 +     -67,  -67,  -66,  -68,  -69,  -73,  -73,  -76,
  626.81 +     -80,  -81,  -81,  -85,  -85,  -86,  -88,  -93,
  626.82 +     -100, -110, -999, -999, -999, -999, -999, -999,
  626.83 +     -999, -999, -999, -999, -999, -999, -999, -999},
  626.84 +   { -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
  626.85 +     -17,  -19,  -20,  -22,  -26,  -28,  -31,  -40,
  626.86 +     -47,  -39,  -39,  -40,  -42,  -43,  -47,  -51,
  626.87 +     -57,  -52,  -55,  -55,  -60,  -58,  -62,  -63,
  626.88 +     -70,  -67,  -69,  -72,  -73,  -77,  -80,  -82,
  626.89 +     -83,  -87,  -90,  -94,  -98, -104, -115, -999,
  626.90 +     -999, -999, -999, -999, -999, -999, -999, -999},
  626.91 +   {  -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,
  626.92 +      -8,   -8,  -10,  -11,  -15,  -19,  -25,  -30,
  626.93 +      -34,  -31,  -30,  -31,  -29,  -32,  -35,  -42,
  626.94 +      -48,  -42,  -44,  -46,  -50,  -50,  -51,  -52,
  626.95 +      -59,  -54,  -55,  -55,  -58,  -62,  -63,  -66,
  626.96 +      -72,  -73,  -76,  -75,  -78,  -80,  -80,  -81,
  626.97 +      -84,  -88,  -90,  -94,  -98, -101, -106, -110}},
  626.98 +  /* 88Hz */
  626.99 +  {{ -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,
 626.100 +     -66,  -66,  -66,  -66,  -66,  -67,  -67,  -67,
 626.101 +     -76,  -72,  -71,  -74,  -76,  -76,  -75,  -78,
 626.102 +     -79,  -79,  -81,  -83,  -86,  -89,  -93,  -97,
 626.103 +     -100, -105, -110, -999, -999, -999, -999, -999,
 626.104 +     -999, -999, -999, -999, -999, -999, -999, -999,
 626.105 +     -999, -999, -999, -999, -999, -999, -999, -999},
 626.106 +   { -47,  -47,  -47,  -47,  -47,  -47,  -47,  -47,
 626.107 +     -47,  -47,  -47,  -48,  -51,  -55,  -59,  -66,
 626.108 +     -66,  -66,  -67,  -66,  -68,  -69,  -70,  -74,
 626.109 +     -79,  -77,  -77,  -78,  -80,  -81,  -82,  -84,
 626.110 +     -86,  -88,  -91,  -95, -100, -108, -116, -999,
 626.111 +     -999, -999, -999, -999, -999, -999, -999, -999,
 626.112 +     -999, -999, -999, -999, -999, -999, -999, -999},
 626.113 +   { -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
 626.114 +     -36,  -37,  -37,  -41,  -44,  -48,  -51,  -58,
 626.115 +     -62,  -60,  -57,  -59,  -59,  -60,  -63,  -65,
 626.116 +     -72,  -71,  -70,  -72,  -74,  -77,  -76,  -78,
 626.117 +     -81,  -81,  -80,  -83,  -86,  -91,  -96, -100,
 626.118 +     -105, -110, -999, -999, -999, -999, -999, -999,
 626.119 +     -999, -999, -999, -999, -999, -999, -999, -999},
 626.120 +   { -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28,
 626.121 +     -28,  -30,  -32,  -32,  -33,  -35,  -41,  -49,
 626.122 +     -50,  -49,  -47,  -48,  -48,  -52,  -51,  -57,
 626.123 +     -65,  -61,  -59,  -61,  -64,  -69,  -70,  -74,
 626.124 +     -77,  -77,  -78,  -81,  -84,  -85,  -87,  -90,
 626.125 +     -92,  -96, -100, -107, -112, -999, -999, -999,
 626.126 +     -999, -999, -999, -999, -999, -999, -999, -999},
 626.127 +   { -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,
 626.128 +     -20,  -21,  -23,  -27,  -30,  -35,  -36,  -41,
 626.129 +     -46,  -44,  -42,  -40,  -41,  -41,  -43,  -48,
 626.130 +     -55,  -53,  -52,  -53,  -56,  -59,  -58,  -60,
 626.131 +     -67,  -66,  -69,  -71,  -72,  -75,  -79,  -81,
 626.132 +     -84,  -87,  -90,  -93,  -97, -101, -107, -114,
 626.133 +     -999, -999, -999, -999, -999, -999, -999, -999},
 626.134 +   {  -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,
 626.135 +      -11,  -12,  -12,  -15,  -16,  -20,  -23,  -30,
 626.136 +      -37,  -34,  -33,  -34,  -31,  -32,  -32,  -38,
 626.137 +      -47,  -44,  -41,  -40,  -47,  -49,  -46,  -46,
 626.138 +      -58,  -50,  -50,  -54,  -58,  -62,  -64,  -67,
 626.139 +      -67,  -70,  -72,  -76,  -79,  -83,  -87,  -91,
 626.140 +      -96, -100, -104, -110, -999, -999, -999, -999}},
 626.141 +  /* 125 Hz */
 626.142 +  {{ -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,
 626.143 +     -62,  -62,  -63,  -64,  -66,  -67,  -66,  -68,
 626.144 +     -75,  -72,  -76,  -75,  -76,  -78,  -79,  -82,
 626.145 +     -84,  -85,  -90,  -94, -101, -110, -999, -999,
 626.146 +     -999, -999, -999, -999, -999, -999, -999, -999,
 626.147 +     -999, -999, -999, -999, -999, -999, -999, -999,
 626.148 +     -999, -999, -999, -999, -999, -999, -999, -999},
 626.149 +   { -59,  -59,  -59,  -59,  -59,  -59,  -59,  -59,
 626.150 +     -59,  -59,  -59,  -60,  -60,  -61,  -63,  -66,
 626.151 +     -71,  -68,  -70,  -70,  -71,  -72,  -72,  -75,
 626.152 +     -81,  -78,  -79,  -82,  -83,  -86,  -90,  -97,
 626.153 +     -103, -113, -999, -999, -999, -999, -999, -999,
 626.154 +     -999, -999, -999, -999, -999, -999, -999, -999,
 626.155 +     -999, -999, -999, -999, -999, -999, -999, -999},
 626.156 +   { -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
 626.157 +     -53,  -54,  -55,  -57,  -56,  -57,  -55,  -61,
 626.158 +     -65,  -60,  -60,  -62,  -63,  -63,  -66,  -68,
 626.159 +     -74,  -73,  -75,  -75,  -78,  -80,  -80,  -82,
 626.160 +     -85,  -90,  -96, -101, -108, -999, -999, -999,
 626.161 +     -999, -999, -999, -999, -999, -999, -999, -999,
 626.162 +     -999, -999, -999, -999, -999, -999, -999, -999},
 626.163 +   { -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,
 626.164 +     -46,  -46,  -47,  -47,  -47,  -47,  -48,  -51,
 626.165 +     -57,  -51,  -49,  -50,  -51,  -53,  -54,  -59,
 626.166 +     -66,  -60,  -62,  -67,  -67,  -70,  -72,  -75,
 626.167 +     -76,  -78,  -81,  -85,  -88,  -94,  -97, -104,
 626.168 +     -112, -999, -999, -999, -999, -999, -999, -999,
 626.169 +     -999, -999, -999, -999, -999, -999, -999, -999},
 626.170 +   { -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
 626.171 +     -39,  -41,  -42,  -42,  -39,  -38,  -41,  -43,
 626.172 +     -52,  -44,  -40,  -39,  -37,  -37,  -40,  -47,
 626.173 +     -54,  -50,  -48,  -50,  -55,  -61,  -59,  -62,
 626.174 +     -66,  -66,  -66,  -69,  -69,  -73,  -74,  -74,
 626.175 +     -75,  -77,  -79,  -82,  -87,  -91,  -95, -100,
 626.176 +     -108, -115, -999, -999, -999, -999, -999, -999},
 626.177 +   { -28,  -26,  -24,  -22,  -20,  -20,  -23,  -29,
 626.178 +     -30,  -31,  -28,  -27,  -28,  -28,  -28,  -35,
 626.179 +     -40,  -33,  -32,  -29,  -30,  -30,  -30,  -37,
 626.180 +     -45,  -41,  -37,  -38,  -45,  -47,  -47,  -48,
 626.181 +     -53,  -49,  -48,  -50,  -49,  -49,  -51,  -52,
 626.182 +     -58,  -56,  -57,  -56,  -60,  -61,  -62,  -70,
 626.183 +     -72,  -74,  -78,  -83,  -88,  -93, -100, -106}},
 626.184 +  /* 177 Hz */
 626.185 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.186 +    -999, -110, -105, -100,  -95,  -91,  -87,  -83,
 626.187 +    -80,  -78,  -76,  -78,  -78,  -81,  -83,  -85,
 626.188 +    -86,  -85,  -86,  -87,  -90,  -97, -107, -999,
 626.189 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.190 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.191 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.192 +   {-999, -999, -999, -110, -105, -100,  -95,  -90,
 626.193 +    -85,  -81,  -77,  -73,  -70,  -67,  -67,  -68,
 626.194 +    -75,  -73,  -70,  -69,  -70,  -72,  -75,  -79,
 626.195 +    -84,  -83,  -84,  -86,  -88,  -89,  -89,  -93,
 626.196 +    -98, -105, -112, -999, -999, -999, -999, -999,
 626.197 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.198 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.199 +   {-105, -100,  -95,  -90,  -85,  -80,  -76,  -71,
 626.200 +    -68,  -68,  -65,  -63,  -63,  -62,  -62,  -64,
 626.201 +    -65,  -64,  -61,  -62,  -63,  -64,  -66,  -68,
 626.202 +    -73,  -73,  -74,  -75,  -76,  -81,  -83,  -85,
 626.203 +    -88,  -89,  -92,  -95, -100, -108, -999, -999,
 626.204 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.205 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.206 +   { -80,  -75,  -71,  -68,  -65,  -63,  -62,  -61,
 626.207 +     -61,  -61,  -61,  -59,  -56,  -57,  -53,  -50,
 626.208 +     -58,  -52,  -50,  -50,  -52,  -53,  -54,  -58,
 626.209 +     -67,  -63,  -67,  -68,  -72,  -75,  -78,  -80,
 626.210 +     -81,  -81,  -82,  -85,  -89,  -90,  -93,  -97,
 626.211 +     -101, -107, -114, -999, -999, -999, -999, -999,
 626.212 +     -999, -999, -999, -999, -999, -999, -999, -999},
 626.213 +   { -65,  -61,  -59,  -57,  -56,  -55,  -55,  -56,
 626.214 +     -56,  -57,  -55,  -53,  -52,  -47,  -44,  -44,
 626.215 +     -50,  -44,  -41,  -39,  -39,  -42,  -40,  -46,
 626.216 +     -51,  -49,  -50,  -53,  -54,  -63,  -60,  -61,
 626.217 +     -62,  -66,  -66,  -66,  -70,  -73,  -74,  -75,
 626.218 +     -76,  -75,  -79,  -85,  -89,  -91,  -96, -102,
 626.219 +     -110, -999, -999, -999, -999, -999, -999, -999},
 626.220 +   { -52,  -50,  -49,  -49,  -48,  -48,  -48,  -49,
 626.221 +     -50,  -50,  -49,  -46,  -43,  -39,  -35,  -33,
 626.222 +     -38,  -36,  -32,  -29,  -32,  -32,  -32,  -35,
 626.223 +     -44,  -39,  -38,  -38,  -46,  -50,  -45,  -46,
 626.224 +     -53,  -50,  -50,  -50,  -54,  -54,  -53,  -53,
 626.225 +     -56,  -57,  -59,  -66,  -70,  -72,  -74,  -79,
 626.226 +     -83,  -85,  -90, -97, -114, -999, -999, -999}},
 626.227 +  /* 250 Hz */
 626.228 +  {{-999, -999, -999, -999, -999, -999, -110, -105,
 626.229 +    -100,  -95,  -90,  -86,  -80,  -75,  -75,  -79,
 626.230 +    -80,  -79,  -80,  -81,  -82,  -88,  -95, -103,
 626.231 +    -110, -999, -999, -999, -999, -999, -999, -999,
 626.232 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.233 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.234 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.235 +   {-999, -999, -999, -999, -108, -103,  -98,  -93,
 626.236 +    -88,  -83,  -79,  -78,  -75,  -71,  -67,  -68,
 626.237 +    -73,  -73,  -72,  -73,  -75,  -77,  -80,  -82,
 626.238 +    -88,  -93, -100, -107, -114, -999, -999, -999,
 626.239 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.240 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.241 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.242 +   {-999, -999, -999, -110, -105, -101,  -96,  -90,
 626.243 +    -86,  -81,  -77,  -73,  -69,  -66,  -61,  -62,
 626.244 +    -66,  -64,  -62,  -65,  -66,  -70,  -72,  -76,
 626.245 +    -81,  -80,  -84,  -90,  -95, -102, -110, -999,
 626.246 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.247 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.248 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.249 +   {-999, -999, -999, -107, -103,  -97,  -92,  -88,
 626.250 +    -83,  -79,  -74,  -70,  -66,  -59,  -53,  -58,
 626.251 +    -62,  -55,  -54,  -54,  -54,  -58,  -61,  -62,
 626.252 +    -72,  -70,  -72,  -75,  -78,  -80,  -81,  -80,
 626.253 +    -83,  -83,  -88,  -93, -100, -107, -115, -999,
 626.254 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.255 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.256 +   {-999, -999, -999, -105, -100,  -95,  -90,  -85,
 626.257 +    -80,  -75,  -70,  -66,  -62,  -56,  -48,  -44,
 626.258 +    -48,  -46,  -46,  -43,  -46,  -48,  -48,  -51,
 626.259 +    -58,  -58,  -59,  -60,  -62,  -62,  -61,  -61,
 626.260 +    -65,  -64,  -65,  -68,  -70,  -74,  -75,  -78,
 626.261 +    -81,  -86,  -95, -110, -999, -999, -999, -999,
 626.262 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.263 +   {-999,  -999, -105, -100,  -95,  -90,  -85,  -80,
 626.264 +    -75,  -70,  -65,  -61,  -55,  -49,  -39,  -33,
 626.265 +    -40,  -35,  -32,  -38,  -40,  -33,  -35,  -37,
 626.266 +    -46,  -41,  -45,  -44,  -46,  -42,  -45,  -46,
 626.267 +    -52,  -50,  -50,  -50,  -54,  -54,  -55,  -57,
 626.268 +    -62,  -64,  -66,  -68,  -70,  -76,  -81,  -90,
 626.269 +    -100, -110, -999, -999, -999, -999, -999, -999}},
 626.270 +  /* 354 hz */
 626.271 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.272 +    -105,  -98,  -90,  -85,  -82,  -83,  -80,  -78,
 626.273 +    -84,  -79,  -80,  -83,  -87,  -89,  -91,  -93,
 626.274 +    -99, -106, -117, -999, -999, -999, -999, -999,
 626.275 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.276 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.277 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.278 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.279 +    -105,  -98,  -90,  -85,  -80,  -75,  -70,  -68,
 626.280 +    -74,  -72,  -74,  -77,  -80,  -82,  -85,  -87,
 626.281 +    -92,  -89,  -91,  -95, -100, -106, -112, -999,
 626.282 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.283 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.284 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.285 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.286 +    -105,  -98,  -90,  -83,  -75,  -71,  -63,  -64,
 626.287 +    -67,  -62,  -64,  -67,  -70,  -73,  -77,  -81,
 626.288 +    -84,  -83,  -85,  -89,  -90,  -93,  -98, -104,
 626.289 +    -109, -114, -999, -999, -999, -999, -999, -999,
 626.290 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.291 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.292 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.293 +    -103,  -96,  -88,  -81,  -75,  -68,  -58,  -54,
 626.294 +    -56,  -54,  -56,  -56,  -58,  -60,  -63,  -66,
 626.295 +    -74,  -69,  -72,  -72,  -75,  -74,  -77,  -81,
 626.296 +    -81,  -82,  -84,  -87,  -93,  -96,  -99, -104,
 626.297 +    -110, -999, -999, -999, -999, -999, -999, -999,
 626.298 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.299 +   {-999, -999, -999, -999, -999, -108, -102,  -96,
 626.300 +    -91,  -85,  -80,  -74,  -68,  -60,  -51,  -46,
 626.301 +    -48,  -46,  -43,  -45,  -47,  -47,  -49,  -48,
 626.302 +    -56,  -53,  -55,  -58,  -57,  -63,  -58,  -60,
 626.303 +    -66,  -64,  -67,  -70,  -70,  -74,  -77,  -84,
 626.304 +    -86,  -89,  -91,  -93,  -94, -101, -109, -118,
 626.305 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.306 +   {-999, -999, -999, -108, -103,  -98,  -93,  -88,
 626.307 +    -83,  -78,  -73,  -68,  -60,  -53,  -44,  -35,
 626.308 +    -38,  -38,  -34,  -34,  -36,  -40,  -41,  -44,
 626.309 +    -51,  -45,  -46,  -47,  -46,  -54,  -50,  -49,
 626.310 +    -50,  -50,  -50,  -51,  -54,  -57,  -58,  -60,
 626.311 +    -66,  -66,  -66,  -64,  -65,  -68,  -77,  -82,
 626.312 +    -87,  -95, -110, -999, -999, -999, -999, -999}},
 626.313 +  /* 500 Hz */
 626.314 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.315 +    -107, -102,  -97,  -92,  -87,  -83,  -78,  -75,
 626.316 +    -82,  -79,  -83,  -85,  -89,  -92,  -95,  -98,
 626.317 +    -101, -105, -109, -113, -999, -999, -999, -999,
 626.318 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.319 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.320 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.321 +   {-999, -999, -999, -999, -999, -999, -999, -106,
 626.322 +    -100,  -95,  -90,  -86,  -81,  -78,  -74,  -69,
 626.323 +    -74,  -74,  -76,  -79,  -83,  -84,  -86,  -89,
 626.324 +    -92,  -97,  -93, -100, -103, -107, -110, -999,
 626.325 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.326 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.327 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.328 +   {-999, -999, -999, -999, -999, -999, -106, -100,
 626.329 +    -95, -90, -87, -83, -80, -75, -69, -60,
 626.330 +    -66, -66, -68, -70, -74, -78, -79, -81,
 626.331 +    -81, -83, -84, -87, -93, -96, -99, -103,
 626.332 +    -107, -110, -999, -999, -999, -999, -999, -999,
 626.333 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.334 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.335 +   {-999, -999, -999, -999, -999, -108, -103, -98,
 626.336 +    -93, -89, -85, -82, -78, -71, -62, -55,
 626.337 +    -58, -58, -54, -54, -55, -59, -61, -62,
 626.338 +    -70, -66, -66, -67, -70, -72, -75, -78,
 626.339 +    -84, -84, -84, -88, -91, -90, -95, -98,
 626.340 +    -102, -103, -106, -110, -999, -999, -999, -999,
 626.341 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.342 +   {-999, -999, -999, -999, -108, -103,  -98,  -94,
 626.343 +    -90,  -87,  -82,  -79,  -73,  -67,  -58,  -47,
 626.344 +    -50,  -45,  -41,  -45,  -48,  -44,  -44,  -49,
 626.345 +    -54,  -51,  -48,  -47,  -49,  -50,  -51,  -57,
 626.346 +    -58,  -60,  -63,  -69,  -70,  -69,  -71,  -74,
 626.347 +    -78,  -82,  -90,  -95, -101, -105, -110, -999,
 626.348 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.349 +   {-999, -999, -999, -105, -101, -97, -93, -90,
 626.350 +    -85, -80, -77, -72, -65, -56, -48, -37,
 626.351 +    -40, -36, -34, -40, -50, -47, -38, -41,
 626.352 +    -47, -38, -35, -39, -38, -43, -40, -45,
 626.353 +    -50, -45, -44, -47, -50, -55, -48, -48,
 626.354 +    -52, -66, -70, -76, -82, -90, -97, -105,
 626.355 +    -110, -999, -999, -999, -999, -999, -999, -999}},
 626.356 +  /* 707 Hz */
 626.357 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.358 +    -999, -108, -103,  -98,  -93,  -86,  -79,  -76,
 626.359 +    -83,  -81,  -85,  -87,  -89,  -93,  -98, -102,
 626.360 +    -107, -112, -999, -999, -999, -999, -999, -999,
 626.361 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.362 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.363 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.364 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.365 +    -999, -108, -103,  -98,  -93,  -86,  -79,  -71,
 626.366 +    -77,  -74,  -77,  -79,  -81,  -84,  -85,  -90,
 626.367 +    -92,  -93,  -92,  -98, -101, -108, -112, -999,
 626.368 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.369 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.370 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.371 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.372 +    -108, -103,  -98,  -93,  -87,  -78,  -68,  -65,
 626.373 +    -66,  -62,  -65,  -67,  -70,  -73,  -75,  -78,
 626.374 +    -82,  -82,  -83,  -84,  -91,  -93,  -98, -102,
 626.375 +    -106, -110, -999, -999, -999, -999, -999, -999,
 626.376 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.377 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.378 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.379 +    -105, -100, -95, -90, -82, -74, -62, -57,
 626.380 +    -58, -56, -51, -52, -52, -54, -54, -58,
 626.381 +    -66, -59, -60, -63, -66, -69, -73, -79,
 626.382 +    -83, -84, -80, -81, -81, -82, -88, -92,
 626.383 +    -98, -105, -113, -999, -999, -999, -999, -999,
 626.384 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.385 +   {-999, -999, -999, -999, -999, -999, -999, -107,
 626.386 +    -102,  -97,  -92,  -84,  -79,  -69,  -57,  -47,
 626.387 +    -52,  -47,  -44,  -45,  -50,  -52,  -42,  -42,
 626.388 +    -53,  -43,  -43,  -48,  -51,  -56,  -55,  -52,
 626.389 +    -57,  -59,  -61,  -62,  -67,  -71,  -78,  -83,
 626.390 +    -86,  -94,  -98, -103, -110, -999, -999, -999,
 626.391 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.392 +   {-999, -999, -999, -999, -999, -999, -105, -100,
 626.393 +    -95,  -90,  -84,  -78,  -70,  -61,  -51,  -41,
 626.394 +    -40,  -38,  -40,  -46,  -52,  -51,  -41,  -40,
 626.395 +    -46,  -40,  -38,  -38,  -41,  -46,  -41,  -46,
 626.396 +    -47,  -43,  -43,  -45,  -41,  -45,  -56,  -67,
 626.397 +    -68,  -83,  -87,  -90,  -95, -102, -107, -113,
 626.398 +    -999, -999, -999, -999, -999, -999, -999, -999}},
 626.399 +  /* 1000 Hz */
 626.400 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.401 +    -999, -109, -105, -101,  -96,  -91,  -84,  -77,
 626.402 +    -82,  -82,  -85,  -89,  -94, -100, -106, -110,
 626.403 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.404 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.405 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.406 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.407 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.408 +    -999, -106, -103,  -98,  -92,  -85,  -80,  -71,
 626.409 +    -75,  -72,  -76,  -80,  -84,  -86,  -89,  -93,
 626.410 +    -100, -107, -113, -999, -999, -999, -999, -999,
 626.411 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.412 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.413 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.414 +   {-999, -999, -999, -999, -999, -999, -999, -107,
 626.415 +    -104, -101,  -97,  -92,  -88,  -84,  -80,  -64,
 626.416 +    -66,  -63,  -64,  -66,  -69,  -73,  -77,  -83,
 626.417 +    -83,  -86,  -91,  -98, -104, -111, -999, -999,
 626.418 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.419 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.420 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.421 +   {-999, -999, -999, -999, -999, -999, -999, -107,
 626.422 +    -104, -101,  -97,  -92,  -90,  -84,  -74,  -57,
 626.423 +    -58,  -52,  -55,  -54,  -50,  -52,  -50,  -52,
 626.424 +    -63,  -62,  -69,  -76,  -77,  -78,  -78,  -79,
 626.425 +    -82,  -88,  -94, -100, -106, -111, -999, -999,
 626.426 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.427 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.428 +   {-999, -999, -999, -999, -999, -999, -106, -102,
 626.429 +    -98,  -95,  -90,  -85,  -83,  -78,  -70,  -50,
 626.430 +    -50,  -41,  -44,  -49,  -47,  -50,  -50,  -44,
 626.431 +    -55,  -46,  -47,  -48,  -48,  -54,  -49,  -49,
 626.432 +    -58,  -62,  -71,  -81,  -87,  -92,  -97, -102,
 626.433 +    -108, -114, -999, -999, -999, -999, -999, -999,
 626.434 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.435 +   {-999, -999, -999, -999, -999, -999, -106, -102,
 626.436 +    -98,  -95,  -90,  -85,  -83,  -78,  -70,  -45,
 626.437 +    -43,  -41,  -47,  -50,  -51,  -50,  -49,  -45,
 626.438 +    -47,  -41,  -44,  -41,  -39,  -43,  -38,  -37,
 626.439 +    -40,  -41,  -44,  -50,  -58,  -65,  -73,  -79,
 626.440 +    -85,  -92,  -97, -101, -105, -109, -113, -999,
 626.441 +    -999, -999, -999, -999, -999, -999, -999, -999}},
 626.442 +  /* 1414 Hz */
 626.443 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.444 +    -999, -999, -999, -107, -100,  -95,  -87,  -81,
 626.445 +    -85,  -83,  -88,  -93, -100, -107, -114, -999,
 626.446 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.447 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.448 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.449 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.450 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.451 +    -999, -999, -107, -101,  -95,  -88,  -83,  -76,
 626.452 +    -73,  -72,  -79,  -84,  -90,  -95, -100, -105,
 626.453 +    -110, -115, -999, -999, -999, -999, -999, -999,
 626.454 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.455 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.456 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.457 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.458 +    -999, -999, -104,  -98,  -92,  -87,  -81,  -70,
 626.459 +    -65,  -62,  -67,  -71,  -74,  -80,  -85,  -91,
 626.460 +    -95,  -99, -103, -108, -111, -114, -999, -999,
 626.461 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.462 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.463 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.464 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.465 +    -999, -999, -103,  -97,  -90,  -85,  -76,  -60,
 626.466 +    -56,  -54,  -60,  -62,  -61,  -56,  -63,  -65,
 626.467 +    -73,  -74,  -77,  -75,  -78,  -81,  -86,  -87,
 626.468 +    -88,  -91,  -94,  -98, -103, -110, -999, -999,
 626.469 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.470 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.471 +   {-999, -999, -999, -999, -999, -999, -999, -105,
 626.472 +    -100,  -97,  -92,  -86,  -81,  -79,  -70,  -57,
 626.473 +    -51,  -47,  -51,  -58,  -60,  -56,  -53,  -50,
 626.474 +    -58,  -52,  -50,  -50,  -53,  -55,  -64,  -69,
 626.475 +    -71,  -85,  -82,  -78,  -81,  -85,  -95, -102,
 626.476 +    -112, -999, -999, -999, -999, -999, -999, -999,
 626.477 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.478 +   {-999, -999, -999, -999, -999, -999, -999, -105,
 626.479 +    -100,  -97,  -92,  -85,  -83,  -79,  -72,  -49,
 626.480 +    -40,  -43,  -43,  -54,  -56,  -51,  -50,  -40,
 626.481 +    -43,  -38,  -36,  -35,  -37,  -38,  -37,  -44,
 626.482 +    -54,  -60,  -57,  -60,  -70,  -75,  -84,  -92,
 626.483 +    -103, -112, -999, -999, -999, -999, -999, -999,
 626.484 +    -999, -999, -999, -999, -999, -999, -999, -999}},
 626.485 +  /* 2000 Hz */
 626.486 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.487 +    -999, -999, -999, -110, -102,  -95,  -89,  -82,
 626.488 +    -83,  -84,  -90,  -92,  -99, -107, -113, -999,
 626.489 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.490 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.491 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.492 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.493 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.494 +    -999, -999, -107, -101,  -95,  -89,  -83,  -72,
 626.495 +    -74,  -78,  -85,  -88,  -88,  -90,  -92,  -98,
 626.496 +    -105, -111, -999, -999, -999, -999, -999, -999,
 626.497 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.498 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.499 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.500 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.501 +    -999, -109, -103, -97, -93, -87, -81, -70,
 626.502 +    -70, -67, -75, -73, -76, -79, -81, -83,
 626.503 +    -88, -89, -97, -103, -110, -999, -999, -999,
 626.504 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.505 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.506 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.507 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.508 +    -999, -107, -100,  -94,  -88,  -83,  -75,  -63,
 626.509 +    -59,  -59,  -63,  -66,  -60,  -62,  -67,  -67,
 626.510 +    -77,  -76,  -81,  -88,  -86,  -92,  -96, -102,
 626.511 +    -109, -116, -999, -999, -999, -999, -999, -999,
 626.512 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.513 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.514 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.515 +    -999, -105,  -98,  -92,  -86,  -81,  -73,  -56,
 626.516 +    -52,  -47,  -55,  -60,  -58,  -52,  -51,  -45,
 626.517 +    -49,  -50,  -53,  -54,  -61,  -71,  -70,  -69,
 626.518 +    -78,  -79,  -87,  -90,  -96, -104, -112, -999,
 626.519 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.520 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.521 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.522 +    -999, -103,  -96,  -90,  -86,  -78,  -70,  -51,
 626.523 +    -42,  -47,  -48,  -55,  -54,  -54,  -53,  -42,
 626.524 +    -35,  -28,  -33,  -38,  -37,  -44,  -47,  -49,
 626.525 +    -54,  -63,  -68,  -78,  -82,  -89,  -94,  -99,
 626.526 +    -104, -109, -114, -999, -999, -999, -999, -999,
 626.527 +    -999, -999, -999, -999, -999, -999, -999, -999}},
 626.528 +  /* 2828 Hz */
 626.529 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.530 +    -999, -999, -999, -999, -110, -100,  -90,  -79,
 626.531 +    -85,  -81,  -82,  -82,  -89,  -94,  -99, -103,
 626.532 +    -109, -115, -999, -999, -999, -999, -999, -999,
 626.533 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.534 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.535 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.536 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.537 +    -999, -999, -999, -999, -105,  -97,  -85,  -72,
 626.538 +    -74,  -70,  -70,  -70,  -76,  -85,  -91,  -93,
 626.539 +    -97, -103, -109, -115, -999, -999, -999, -999,
 626.540 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.541 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.542 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.543 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.544 +    -999, -999, -999, -999, -112,  -93,  -81,  -68,
 626.545 +    -62,  -60,  -60,  -57,  -63,  -70,  -77,  -82,
 626.546 +    -90,  -93,  -98, -104, -109, -113, -999, -999,
 626.547 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.548 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.549 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.550 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.551 +    -999, -999, -999, -113, -100,  -93,  -84,  -63,
 626.552 +    -58,  -48,  -53,  -54,  -52,  -52,  -57,  -64,
 626.553 +    -66,  -76,  -83,  -81,  -85,  -85,  -90,  -95,
 626.554 +    -98, -101, -103, -106, -108, -111, -999, -999,
 626.555 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.556 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.557 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.558 +    -999, -999, -999, -105,  -95,  -86,  -74,  -53,
 626.559 +    -50,  -38,  -43,  -49,  -43,  -42,  -39,  -39,
 626.560 +    -46,  -52,  -57,  -56,  -72,  -69,  -74,  -81,
 626.561 +    -87,  -92,  -94,  -97,  -99, -102, -105, -108,
 626.562 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.563 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.564 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.565 +    -999, -999, -108,  -99,  -90,  -76,  -66,  -45,
 626.566 +    -43,  -41,  -44,  -47,  -43,  -47,  -40,  -30,
 626.567 +    -31,  -31,  -39,  -33,  -40,  -41,  -43,  -53,
 626.568 +    -59,  -70,  -73,  -77,  -79,  -82,  -84,  -87,
 626.569 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.570 +    -999, -999, -999, -999, -999, -999, -999, -999}},
 626.571 +  /* 4000 Hz */
 626.572 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.573 +    -999, -999, -999, -999, -999, -110,  -91,  -76,
 626.574 +    -75,  -85,  -93,  -98, -104, -110, -999, -999,
 626.575 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.576 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.577 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.578 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.579 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.580 +    -999, -999, -999, -999, -999, -110,  -91,  -70,
 626.581 +    -70,  -75,  -86,  -89,  -94,  -98, -101, -106,
 626.582 +    -110, -999, -999, -999, -999, -999, -999, -999,
 626.583 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.584 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.585 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.586 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.587 +    -999, -999, -999, -999, -110,  -95,  -80,  -60,
 626.588 +    -65,  -64,  -74,  -83,  -88,  -91,  -95,  -99,
 626.589 +    -103, -107, -110, -999, -999, -999, -999, -999,
 626.590 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.591 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.592 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.593 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.594 +    -999, -999, -999, -999, -110,  -95,  -80,  -58,
 626.595 +    -55,  -49,  -66,  -68,  -71,  -78,  -78,  -80,
 626.596 +    -88,  -85,  -89,  -97, -100, -105, -110, -999,
 626.597 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.598 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.599 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.600 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.601 +    -999, -999, -999, -999, -110,  -95,  -80,  -53,
 626.602 +    -52,  -41,  -59,  -59,  -49,  -58,  -56,  -63,
 626.603 +    -86,  -79,  -90,  -93,  -98, -103, -107, -112,
 626.604 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.605 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.606 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.607 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.608 +    -999, -999, -999, -110,  -97,  -91,  -73,  -45,
 626.609 +    -40,  -33,  -53,  -61,  -49,  -54,  -50,  -50,
 626.610 +    -60,  -52,  -67,  -74,  -81,  -92,  -96, -100,
 626.611 +    -105, -110, -999, -999, -999, -999, -999, -999,
 626.612 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.613 +    -999, -999, -999, -999, -999, -999, -999, -999}},
 626.614 +  /* 5657 Hz */
 626.615 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.616 +    -999, -999, -999, -113, -106,  -99,  -92,  -77,
 626.617 +    -80,  -88,  -97, -106, -115, -999, -999, -999,
 626.618 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.619 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.620 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.621 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.622 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.623 +    -999, -999, -116, -109, -102,  -95,  -89,  -74,
 626.624 +    -72,  -88,  -87,  -95, -102, -109, -116, -999,
 626.625 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.626 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.627 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.628 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.629 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.630 +    -999, -999, -116, -109, -102,  -95,  -89,  -75,
 626.631 +    -66,  -74,  -77,  -78,  -86,  -87,  -90,  -96,
 626.632 +    -105, -115, -999, -999, -999, -999, -999, -999,
 626.633 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.634 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.635 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.636 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.637 +    -999, -999, -115, -108, -101,  -94,  -88,  -66,
 626.638 +    -56,  -61,  -70,  -65,  -78,  -72,  -83,  -84,
 626.639 +    -93,  -98, -105, -110, -999, -999, -999, -999,
 626.640 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.641 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.642 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.643 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.644 +    -999, -999, -110, -105,  -95,  -89,  -82,  -57,
 626.645 +    -52,  -52,  -59,  -56,  -59,  -58,  -69,  -67,
 626.646 +    -88,  -82,  -82,  -89,  -94, -100, -108, -999,
 626.647 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.648 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.649 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.650 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.651 +    -999, -110, -101,  -96,  -90,  -83,  -77,  -54,
 626.652 +    -43,  -38,  -50,  -48,  -52,  -48,  -42,  -42,
 626.653 +    -51,  -52,  -53,  -59,  -65,  -71,  -78,  -85,
 626.654 +    -95, -999, -999, -999, -999, -999, -999, -999,
 626.655 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.656 +    -999, -999, -999, -999, -999, -999, -999, -999}},
 626.657 +  /* 8000 Hz */
 626.658 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.659 +    -999, -999, -999, -999, -120, -105,  -86,  -68,
 626.660 +    -78,  -79,  -90, -100, -110, -999, -999, -999,
 626.661 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.662 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.663 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.664 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.665 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.666 +    -999, -999, -999, -999, -120, -105,  -86,  -66,
 626.667 +    -73,  -77,  -88,  -96, -105, -115, -999, -999,
 626.668 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.669 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.670 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.671 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.672 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.673 +    -999, -999, -999, -120, -105,  -92,  -80,  -61,
 626.674 +    -64,  -68,  -80,  -87,  -92, -100, -110, -999,
 626.675 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.676 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.677 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.678 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.679 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.680 +    -999, -999, -999, -120, -104,  -91,  -79,  -52,
 626.681 +    -60,  -54,  -64,  -69,  -77,  -80,  -82,  -84,
 626.682 +    -85,  -87,  -88,  -90, -999, -999, -999, -999,
 626.683 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.684 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.685 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.686 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.687 +    -999, -999, -999, -118, -100,  -87,  -77,  -49,
 626.688 +    -50,  -44,  -58,  -61,  -61,  -67,  -65,  -62,
 626.689 +    -62,  -62,  -65,  -68, -999, -999, -999, -999,
 626.690 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.691 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.692 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.693 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.694 +    -999, -999, -999, -115,  -98,  -84,  -62,  -49,
 626.695 +    -44,  -38,  -46,  -49,  -49,  -46,  -39,  -37,
 626.696 +    -39,  -40,  -42,  -43, -999, -999, -999, -999,
 626.697 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.698 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.699 +    -999, -999, -999, -999, -999, -999, -999, -999}},
 626.700 +  /* 11314 Hz */
 626.701 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.702 +    -999, -999, -999, -999, -999, -110,  -88,  -74,
 626.703 +    -77,  -82,  -82,  -85,  -90,  -94,  -99, -104,
 626.704 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.705 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.706 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.707 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.708 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.709 +    -999, -999, -999, -999, -999, -110,  -88,  -66,
 626.710 +    -70,  -81,  -80,  -81,  -84,  -88,  -91,  -93,
 626.711 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.712 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.713 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.714 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.715 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.716 +    -999, -999, -999, -999, -999, -110,  -88,  -61,
 626.717 +    -63,  -70,  -71,  -74,  -77,  -80,  -83,  -85,
 626.718 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.719 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.720 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.721 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.722 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.723 +    -999, -999, -999, -999, -999, -110, -86, -62,
 626.724 +    -63,  -62,  -62,  -58,  -52,  -50,  -50,  -52,
 626.725 +    -54, -999, -999, -999, -999, -999, -999, -999,
 626.726 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.727 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.728 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.729 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.730 +    -999, -999, -999, -999, -118, -108,  -84,  -53,
 626.731 +    -50,  -50,  -50,  -55,  -47,  -45,  -40,  -40,
 626.732 +    -40, -999, -999, -999, -999, -999, -999, -999,
 626.733 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.734 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.735 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.736 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.737 +    -999, -999, -999, -999, -118, -100,  -73,  -43,
 626.738 +    -37,  -42,  -43,  -53,  -38,  -37,  -35,  -35,
 626.739 +    -38, -999, -999, -999, -999, -999, -999, -999,
 626.740 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.741 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.742 +    -999, -999, -999, -999, -999, -999, -999, -999}},
 626.743 +  /* 16000 Hz */
 626.744 +  {{-999, -999, -999, -999, -999, -999, -999, -999,
 626.745 +    -999, -999, -999, -110, -100,  -91,  -84,  -74,
 626.746 +    -80,  -80,  -80,  -80,  -80, -999, -999, -999,
 626.747 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.748 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.749 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.750 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.751 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.752 +    -999, -999, -999, -110, -100,  -91,  -84,  -74,
 626.753 +    -68,  -68,  -68,  -68,  -68, -999, -999, -999,
 626.754 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.755 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.756 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.757 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.758 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.759 +    -999, -999, -999, -110, -100,  -86,  -78,  -70,
 626.760 +    -60,  -45,  -30,  -21, -999, -999, -999, -999,
 626.761 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.762 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.763 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.764 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.765 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.766 +    -999, -999, -999, -110, -100,  -87,  -78,  -67,
 626.767 +    -48,  -38,  -29,  -21, -999, -999, -999, -999,
 626.768 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.769 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.770 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.771 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.772 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.773 +    -999, -999, -999, -110, -100,  -86,  -69,  -56,
 626.774 +    -45,  -35,  -33,  -29, -999, -999, -999, -999,
 626.775 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.776 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.777 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.778 +    -999, -999, -999, -999, -999, -999, -999, -999},
 626.779 +   {-999, -999, -999, -999, -999, -999, -999, -999,
 626.780 +    -999, -999, -999, -110, -100,  -83,  -71,  -48,
 626.781 +    -27,  -38,  -37,  -34, -999, -999, -999, -999,
 626.782 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.783 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.784 +    -999, -999, -999, -999, -999, -999, -999, -999,
 626.785 +    -999, -999, -999, -999, -999, -999, -999, -999}}
 626.786 +};
 626.787 +
 626.788 +#endif
   627.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   627.2 +++ b/libs/vorbis/mdct.c	Sat Feb 01 19:58:19 2014 +0200
   627.3 @@ -0,0 +1,563 @@
   627.4 +/********************************************************************
   627.5 + *                                                                  *
   627.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   627.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   627.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   627.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  627.10 + *                                                                  *
  627.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  627.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  627.13 + *                                                                  *
  627.14 + ********************************************************************
  627.15 +
  627.16 + function: normalized modified discrete cosine transform
  627.17 +           power of two length transform only [64 <= n ]
  627.18 + last mod: $Id: mdct.c 16227 2009-07-08 06:58:46Z xiphmont $
  627.19 +
  627.20 + Original algorithm adapted long ago from _The use of multirate filter
  627.21 + banks for coding of high quality digital audio_, by T. Sporer,
  627.22 + K. Brandenburg and B. Edler, collection of the European Signal
  627.23 + Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp
  627.24 + 211-214
  627.25 +
  627.26 + The below code implements an algorithm that no longer looks much like
  627.27 + that presented in the paper, but the basic structure remains if you
  627.28 + dig deep enough to see it.
  627.29 +
  627.30 + This module DOES NOT INCLUDE code to generate/apply the window
  627.31 + function.  Everybody has their own weird favorite including me... I
  627.32 + happen to like the properties of y=sin(.5PI*sin^2(x)), but others may
  627.33 + vehemently disagree.
  627.34 +
  627.35 + ********************************************************************/
  627.36 +
  627.37 +/* this can also be run as an integer transform by uncommenting a
  627.38 +   define in mdct.h; the integerization is a first pass and although
  627.39 +   it's likely stable for Vorbis, the dynamic range is constrained and
  627.40 +   roundoff isn't done (so it's noisy).  Consider it functional, but
  627.41 +   only a starting point.  There's no point on a machine with an FPU */
  627.42 +
  627.43 +#include <stdio.h>
  627.44 +#include <stdlib.h>
  627.45 +#include <string.h>
  627.46 +#include <math.h>
  627.47 +#include "vorbis/codec.h"
  627.48 +#include "mdct.h"
  627.49 +#include "os.h"
  627.50 +#include "misc.h"
  627.51 +
  627.52 +/* build lookups for trig functions; also pre-figure scaling and
  627.53 +   some window function algebra. */
  627.54 +
  627.55 +void mdct_init(mdct_lookup *lookup,int n){
  627.56 +  int   *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4));
  627.57 +  DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4));
  627.58 +
  627.59 +  int i;
  627.60 +  int n2=n>>1;
  627.61 +  int log2n=lookup->log2n=rint(log((float)n)/log(2.f));
  627.62 +  lookup->n=n;
  627.63 +  lookup->trig=T;
  627.64 +  lookup->bitrev=bitrev;
  627.65 +
  627.66 +/* trig lookups... */
  627.67 +
  627.68 +  for(i=0;i<n/4;i++){
  627.69 +    T[i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i)));
  627.70 +    T[i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i)));
  627.71 +    T[n2+i*2]=FLOAT_CONV(cos((M_PI/(2*n))*(2*i+1)));
  627.72 +    T[n2+i*2+1]=FLOAT_CONV(sin((M_PI/(2*n))*(2*i+1)));
  627.73 +  }
  627.74 +  for(i=0;i<n/8;i++){
  627.75 +    T[n+i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i+2))*.5);
  627.76 +    T[n+i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i+2))*.5);
  627.77 +  }
  627.78 +
  627.79 +  /* bitreverse lookup... */
  627.80 +
  627.81 +  {
  627.82 +    int mask=(1<<(log2n-1))-1,i,j;
  627.83 +    int msb=1<<(log2n-2);
  627.84 +    for(i=0;i<n/8;i++){
  627.85 +      int acc=0;
  627.86 +      for(j=0;msb>>j;j++)
  627.87 +        if((msb>>j)&i)acc|=1<<j;
  627.88 +      bitrev[i*2]=((~acc)&mask)-1;
  627.89 +      bitrev[i*2+1]=acc;
  627.90 +
  627.91 +    }
  627.92 +  }
  627.93 +  lookup->scale=FLOAT_CONV(4.f/n);
  627.94 +}
  627.95 +
  627.96 +/* 8 point butterfly (in place, 4 register) */
  627.97 +STIN void mdct_butterfly_8(DATA_TYPE *x){
  627.98 +  REG_TYPE r0   = x[6] + x[2];
  627.99 +  REG_TYPE r1   = x[6] - x[2];
 627.100 +  REG_TYPE r2   = x[4] + x[0];
 627.101 +  REG_TYPE r3   = x[4] - x[0];
 627.102 +
 627.103 +           x[6] = r0   + r2;
 627.104 +           x[4] = r0   - r2;
 627.105 +
 627.106 +           r0   = x[5] - x[1];
 627.107 +           r2   = x[7] - x[3];
 627.108 +           x[0] = r1   + r0;
 627.109 +           x[2] = r1   - r0;
 627.110 +
 627.111 +           r0   = x[5] + x[1];
 627.112 +           r1   = x[7] + x[3];
 627.113 +           x[3] = r2   + r3;
 627.114 +           x[1] = r2   - r3;
 627.115 +           x[7] = r1   + r0;
 627.116 +           x[5] = r1   - r0;
 627.117 +
 627.118 +}
 627.119 +
 627.120 +/* 16 point butterfly (in place, 4 register) */
 627.121 +STIN void mdct_butterfly_16(DATA_TYPE *x){
 627.122 +  REG_TYPE r0     = x[1]  - x[9];
 627.123 +  REG_TYPE r1     = x[0]  - x[8];
 627.124 +
 627.125 +           x[8]  += x[0];
 627.126 +           x[9]  += x[1];
 627.127 +           x[0]   = MULT_NORM((r0   + r1) * cPI2_8);
 627.128 +           x[1]   = MULT_NORM((r0   - r1) * cPI2_8);
 627.129 +
 627.130 +           r0     = x[3]  - x[11];
 627.131 +           r1     = x[10] - x[2];
 627.132 +           x[10] += x[2];
 627.133 +           x[11] += x[3];
 627.134 +           x[2]   = r0;
 627.135 +           x[3]   = r1;
 627.136 +
 627.137 +           r0     = x[12] - x[4];
 627.138 +           r1     = x[13] - x[5];
 627.139 +           x[12] += x[4];
 627.140 +           x[13] += x[5];
 627.141 +           x[4]   = MULT_NORM((r0   - r1) * cPI2_8);
 627.142 +           x[5]   = MULT_NORM((r0   + r1) * cPI2_8);
 627.143 +
 627.144 +           r0     = x[14] - x[6];
 627.145 +           r1     = x[15] - x[7];
 627.146 +           x[14] += x[6];
 627.147 +           x[15] += x[7];
 627.148 +           x[6]  = r0;
 627.149 +           x[7]  = r1;
 627.150 +
 627.151 +           mdct_butterfly_8(x);
 627.152 +           mdct_butterfly_8(x+8);
 627.153 +}
 627.154 +
 627.155 +/* 32 point butterfly (in place, 4 register) */
 627.156 +STIN void mdct_butterfly_32(DATA_TYPE *x){
 627.157 +  REG_TYPE r0     = x[30] - x[14];
 627.158 +  REG_TYPE r1     = x[31] - x[15];
 627.159 +
 627.160 +           x[30] +=         x[14];
 627.161 +           x[31] +=         x[15];
 627.162 +           x[14]  =         r0;
 627.163 +           x[15]  =         r1;
 627.164 +
 627.165 +           r0     = x[28] - x[12];
 627.166 +           r1     = x[29] - x[13];
 627.167 +           x[28] +=         x[12];
 627.168 +           x[29] +=         x[13];
 627.169 +           x[12]  = MULT_NORM( r0 * cPI1_8  -  r1 * cPI3_8 );
 627.170 +           x[13]  = MULT_NORM( r0 * cPI3_8  +  r1 * cPI1_8 );
 627.171 +
 627.172 +           r0     = x[26] - x[10];
 627.173 +           r1     = x[27] - x[11];
 627.174 +           x[26] +=         x[10];
 627.175 +           x[27] +=         x[11];
 627.176 +           x[10]  = MULT_NORM(( r0  - r1 ) * cPI2_8);
 627.177 +           x[11]  = MULT_NORM(( r0  + r1 ) * cPI2_8);
 627.178 +
 627.179 +           r0     = x[24] - x[8];
 627.180 +           r1     = x[25] - x[9];
 627.181 +           x[24] += x[8];
 627.182 +           x[25] += x[9];
 627.183 +           x[8]   = MULT_NORM( r0 * cPI3_8  -  r1 * cPI1_8 );
 627.184 +           x[9]   = MULT_NORM( r1 * cPI3_8  +  r0 * cPI1_8 );
 627.185 +
 627.186 +           r0     = x[22] - x[6];
 627.187 +           r1     = x[7]  - x[23];
 627.188 +           x[22] += x[6];
 627.189 +           x[23] += x[7];
 627.190 +           x[6]   = r1;
 627.191 +           x[7]   = r0;
 627.192 +
 627.193 +           r0     = x[4]  - x[20];
 627.194 +           r1     = x[5]  - x[21];
 627.195 +           x[20] += x[4];
 627.196 +           x[21] += x[5];
 627.197 +           x[4]   = MULT_NORM( r1 * cPI1_8  +  r0 * cPI3_8 );
 627.198 +           x[5]   = MULT_NORM( r1 * cPI3_8  -  r0 * cPI1_8 );
 627.199 +
 627.200 +           r0     = x[2]  - x[18];
 627.201 +           r1     = x[3]  - x[19];
 627.202 +           x[18] += x[2];
 627.203 +           x[19] += x[3];
 627.204 +           x[2]   = MULT_NORM(( r1  + r0 ) * cPI2_8);
 627.205 +           x[3]   = MULT_NORM(( r1  - r0 ) * cPI2_8);
 627.206 +
 627.207 +           r0     = x[0]  - x[16];
 627.208 +           r1     = x[1]  - x[17];
 627.209 +           x[16] += x[0];
 627.210 +           x[17] += x[1];
 627.211 +           x[0]   = MULT_NORM( r1 * cPI3_8  +  r0 * cPI1_8 );
 627.212 +           x[1]   = MULT_NORM( r1 * cPI1_8  -  r0 * cPI3_8 );
 627.213 +
 627.214 +           mdct_butterfly_16(x);
 627.215 +           mdct_butterfly_16(x+16);
 627.216 +
 627.217 +}
 627.218 +
 627.219 +/* N point first stage butterfly (in place, 2 register) */
 627.220 +STIN void mdct_butterfly_first(DATA_TYPE *T,
 627.221 +                                        DATA_TYPE *x,
 627.222 +                                        int points){
 627.223 +
 627.224 +  DATA_TYPE *x1        = x          + points      - 8;
 627.225 +  DATA_TYPE *x2        = x          + (points>>1) - 8;
 627.226 +  REG_TYPE   r0;
 627.227 +  REG_TYPE   r1;
 627.228 +
 627.229 +  do{
 627.230 +
 627.231 +               r0      = x1[6]      -  x2[6];
 627.232 +               r1      = x1[7]      -  x2[7];
 627.233 +               x1[6]  += x2[6];
 627.234 +               x1[7]  += x2[7];
 627.235 +               x2[6]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
 627.236 +               x2[7]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
 627.237 +
 627.238 +               r0      = x1[4]      -  x2[4];
 627.239 +               r1      = x1[5]      -  x2[5];
 627.240 +               x1[4]  += x2[4];
 627.241 +               x1[5]  += x2[5];
 627.242 +               x2[4]   = MULT_NORM(r1 * T[5]  +  r0 * T[4]);
 627.243 +               x2[5]   = MULT_NORM(r1 * T[4]  -  r0 * T[5]);
 627.244 +
 627.245 +               r0      = x1[2]      -  x2[2];
 627.246 +               r1      = x1[3]      -  x2[3];
 627.247 +               x1[2]  += x2[2];
 627.248 +               x1[3]  += x2[3];
 627.249 +               x2[2]   = MULT_NORM(r1 * T[9]  +  r0 * T[8]);
 627.250 +               x2[3]   = MULT_NORM(r1 * T[8]  -  r0 * T[9]);
 627.251 +
 627.252 +               r0      = x1[0]      -  x2[0];
 627.253 +               r1      = x1[1]      -  x2[1];
 627.254 +               x1[0]  += x2[0];
 627.255 +               x1[1]  += x2[1];
 627.256 +               x2[0]   = MULT_NORM(r1 * T[13] +  r0 * T[12]);
 627.257 +               x2[1]   = MULT_NORM(r1 * T[12] -  r0 * T[13]);
 627.258 +
 627.259 +    x1-=8;
 627.260 +    x2-=8;
 627.261 +    T+=16;
 627.262 +
 627.263 +  }while(x2>=x);
 627.264 +}
 627.265 +
 627.266 +/* N/stage point generic N stage butterfly (in place, 2 register) */
 627.267 +STIN void mdct_butterfly_generic(DATA_TYPE *T,
 627.268 +                                          DATA_TYPE *x,
 627.269 +                                          int points,
 627.270 +                                          int trigint){
 627.271 +
 627.272 +  DATA_TYPE *x1        = x          + points      - 8;
 627.273 +  DATA_TYPE *x2        = x          + (points>>1) - 8;
 627.274 +  REG_TYPE   r0;
 627.275 +  REG_TYPE   r1;
 627.276 +
 627.277 +  do{
 627.278 +
 627.279 +               r0      = x1[6]      -  x2[6];
 627.280 +               r1      = x1[7]      -  x2[7];
 627.281 +               x1[6]  += x2[6];
 627.282 +               x1[7]  += x2[7];
 627.283 +               x2[6]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
 627.284 +               x2[7]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
 627.285 +
 627.286 +               T+=trigint;
 627.287 +
 627.288 +               r0      = x1[4]      -  x2[4];
 627.289 +               r1      = x1[5]      -  x2[5];
 627.290 +               x1[4]  += x2[4];
 627.291 +               x1[5]  += x2[5];
 627.292 +               x2[4]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
 627.293 +               x2[5]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
 627.294 +
 627.295 +               T+=trigint;
 627.296 +
 627.297 +               r0      = x1[2]      -  x2[2];
 627.298 +               r1      = x1[3]      -  x2[3];
 627.299 +               x1[2]  += x2[2];
 627.300 +               x1[3]  += x2[3];
 627.301 +               x2[2]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
 627.302 +               x2[3]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
 627.303 +
 627.304 +               T+=trigint;
 627.305 +
 627.306 +               r0      = x1[0]      -  x2[0];
 627.307 +               r1      = x1[1]      -  x2[1];
 627.308 +               x1[0]  += x2[0];
 627.309 +               x1[1]  += x2[1];
 627.310 +               x2[0]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
 627.311 +               x2[1]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
 627.312 +
 627.313 +               T+=trigint;
 627.314 +    x1-=8;
 627.315 +    x2-=8;
 627.316 +
 627.317 +  }while(x2>=x);
 627.318 +}
 627.319 +
 627.320 +STIN void mdct_butterflies(mdct_lookup *init,
 627.321 +                             DATA_TYPE *x,
 627.322 +                             int points){
 627.323 +
 627.324 +  DATA_TYPE *T=init->trig;
 627.325 +  int stages=init->log2n-5;
 627.326 +  int i,j;
 627.327 +
 627.328 +  if(--stages>0){
 627.329 +    mdct_butterfly_first(T,x,points);
 627.330 +  }
 627.331 +
 627.332 +  for(i=1;--stages>0;i++){
 627.333 +    for(j=0;j<(1<<i);j++)
 627.334 +      mdct_butterfly_generic(T,x+(points>>i)*j,points>>i,4<<i);
 627.335 +  }
 627.336 +
 627.337 +  for(j=0;j<points;j+=32)
 627.338 +    mdct_butterfly_32(x+j);
 627.339 +
 627.340 +}
 627.341 +
 627.342 +void mdct_clear(mdct_lookup *l){
 627.343 +  if(l){
 627.344 +    if(l->trig)_ogg_free(l->trig);
 627.345 +    if(l->bitrev)_ogg_free(l->bitrev);
 627.346 +    memset(l,0,sizeof(*l));
 627.347 +  }
 627.348 +}
 627.349 +
 627.350 +STIN void mdct_bitreverse(mdct_lookup *init,
 627.351 +                            DATA_TYPE *x){
 627.352 +  int        n       = init->n;
 627.353 +  int       *bit     = init->bitrev;
 627.354 +  DATA_TYPE *w0      = x;
 627.355 +  DATA_TYPE *w1      = x = w0+(n>>1);
 627.356 +  DATA_TYPE *T       = init->trig+n;
 627.357 +
 627.358 +  do{
 627.359 +    DATA_TYPE *x0    = x+bit[0];
 627.360 +    DATA_TYPE *x1    = x+bit[1];
 627.361 +
 627.362 +    REG_TYPE  r0     = x0[1]  - x1[1];
 627.363 +    REG_TYPE  r1     = x0[0]  + x1[0];
 627.364 +    REG_TYPE  r2     = MULT_NORM(r1     * T[0]   + r0 * T[1]);
 627.365 +    REG_TYPE  r3     = MULT_NORM(r1     * T[1]   - r0 * T[0]);
 627.366 +
 627.367 +              w1    -= 4;
 627.368 +
 627.369 +              r0     = HALVE(x0[1] + x1[1]);
 627.370 +              r1     = HALVE(x0[0] - x1[0]);
 627.371 +
 627.372 +              w0[0]  = r0     + r2;
 627.373 +              w1[2]  = r0     - r2;
 627.374 +              w0[1]  = r1     + r3;
 627.375 +              w1[3]  = r3     - r1;
 627.376 +
 627.377 +              x0     = x+bit[2];
 627.378 +              x1     = x+bit[3];
 627.379 +
 627.380 +              r0     = x0[1]  - x1[1];
 627.381 +              r1     = x0[0]  + x1[0];
 627.382 +              r2     = MULT_NORM(r1     * T[2]   + r0 * T[3]);
 627.383 +              r3     = MULT_NORM(r1     * T[3]   - r0 * T[2]);
 627.384 +
 627.385 +              r0     = HALVE(x0[1] + x1[1]);
 627.386 +              r1     = HALVE(x0[0] - x1[0]);
 627.387 +
 627.388 +              w0[2]  = r0     + r2;
 627.389 +              w1[0]  = r0     - r2;
 627.390 +              w0[3]  = r1     + r3;
 627.391 +              w1[1]  = r3     - r1;
 627.392 +
 627.393 +              T     += 4;
 627.394 +              bit   += 4;
 627.395 +              w0    += 4;
 627.396 +
 627.397 +  }while(w0<w1);
 627.398 +}
 627.399 +
 627.400 +void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
 627.401 +  int n=init->n;
 627.402 +  int n2=n>>1;
 627.403 +  int n4=n>>2;
 627.404 +
 627.405 +  /* rotate */
 627.406 +
 627.407 +  DATA_TYPE *iX = in+n2-7;
 627.408 +  DATA_TYPE *oX = out+n2+n4;
 627.409 +  DATA_TYPE *T  = init->trig+n4;
 627.410 +
 627.411 +  do{
 627.412 +    oX         -= 4;
 627.413 +    oX[0]       = MULT_NORM(-iX[2] * T[3] - iX[0]  * T[2]);
 627.414 +    oX[1]       = MULT_NORM (iX[0] * T[3] - iX[2]  * T[2]);
 627.415 +    oX[2]       = MULT_NORM(-iX[6] * T[1] - iX[4]  * T[0]);
 627.416 +    oX[3]       = MULT_NORM (iX[4] * T[1] - iX[6]  * T[0]);
 627.417 +    iX         -= 8;
 627.418 +    T          += 4;
 627.419 +  }while(iX>=in);
 627.420 +
 627.421 +  iX            = in+n2-8;
 627.422 +  oX            = out+n2+n4;
 627.423 +  T             = init->trig+n4;
 627.424 +
 627.425 +  do{
 627.426 +    T          -= 4;
 627.427 +    oX[0]       =  MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
 627.428 +    oX[1]       =  MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
 627.429 +    oX[2]       =  MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
 627.430 +    oX[3]       =  MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
 627.431 +    iX         -= 8;
 627.432 +    oX         += 4;
 627.433 +  }while(iX>=in);
 627.434 +
 627.435 +  mdct_butterflies(init,out+n2,n2);
 627.436 +  mdct_bitreverse(init,out);
 627.437 +
 627.438 +  /* roatate + window */
 627.439 +
 627.440 +  {
 627.441 +    DATA_TYPE *oX1=out+n2+n4;
 627.442 +    DATA_TYPE *oX2=out+n2+n4;
 627.443 +    DATA_TYPE *iX =out;
 627.444 +    T             =init->trig+n2;
 627.445 +
 627.446 +    do{
 627.447 +      oX1-=4;
 627.448 +
 627.449 +      oX1[3]  =  MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
 627.450 +      oX2[0]  = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
 627.451 +
 627.452 +      oX1[2]  =  MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
 627.453 +      oX2[1]  = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
 627.454 +
 627.455 +      oX1[1]  =  MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
 627.456 +      oX2[2]  = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
 627.457 +
 627.458 +      oX1[0]  =  MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
 627.459 +      oX2[3]  = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
 627.460 +
 627.461 +      oX2+=4;
 627.462 +      iX    +=   8;
 627.463 +      T     +=   8;
 627.464 +    }while(iX<oX1);
 627.465 +
 627.466 +    iX=out+n2+n4;
 627.467 +    oX1=out+n4;
 627.468 +    oX2=oX1;
 627.469 +
 627.470 +    do{
 627.471 +      oX1-=4;
 627.472 +      iX-=4;
 627.473 +
 627.474 +      oX2[0] = -(oX1[3] = iX[3]);
 627.475 +      oX2[1] = -(oX1[2] = iX[2]);
 627.476 +      oX2[2] = -(oX1[1] = iX[1]);
 627.477 +      oX2[3] = -(oX1[0] = iX[0]);
 627.478 +
 627.479 +      oX2+=4;
 627.480 +    }while(oX2<iX);
 627.481 +
 627.482 +    iX=out+n2+n4;
 627.483 +    oX1=out+n2+n4;
 627.484 +    oX2=out+n2;
 627.485 +    do{
 627.486 +      oX1-=4;
 627.487 +      oX1[0]= iX[3];
 627.488 +      oX1[1]= iX[2];
 627.489 +      oX1[2]= iX[1];
 627.490 +      oX1[3]= iX[0];
 627.491 +      iX+=4;
 627.492 +    }while(oX1>oX2);
 627.493 +  }
 627.494 +}
 627.495 +
 627.496 +void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
 627.497 +  int n=init->n;
 627.498 +  int n2=n>>1;
 627.499 +  int n4=n>>2;
 627.500 +  int n8=n>>3;
 627.501 +  DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */
 627.502 +  DATA_TYPE *w2=w+n2;
 627.503 +
 627.504 +  /* rotate */
 627.505 +
 627.506 +  /* window + rotate + step 1 */
 627.507 +
 627.508 +  REG_TYPE r0;
 627.509 +  REG_TYPE r1;
 627.510 +  DATA_TYPE *x0=in+n2+n4;
 627.511 +  DATA_TYPE *x1=x0+1;
 627.512 +  DATA_TYPE *T=init->trig+n2;
 627.513 +
 627.514 +  int i=0;
 627.515 +
 627.516 +  for(i=0;i<n8;i+=2){
 627.517 +    x0 -=4;
 627.518 +    T-=2;
 627.519 +    r0= x0[2] + x1[0];
 627.520 +    r1= x0[0] + x1[2];
 627.521 +    w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
 627.522 +    w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
 627.523 +    x1 +=4;
 627.524 +  }
 627.525 +
 627.526 +  x1=in+1;
 627.527 +
 627.528 +  for(;i<n2-n8;i+=2){
 627.529 +    T-=2;
 627.530 +    x0 -=4;
 627.531 +    r0= x0[2] - x1[0];
 627.532 +    r1= x0[0] - x1[2];
 627.533 +    w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
 627.534 +    w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
 627.535 +    x1 +=4;
 627.536 +  }
 627.537 +
 627.538 +  x0=in+n;
 627.539 +
 627.540 +  for(;i<n2;i+=2){
 627.541 +    T-=2;
 627.542 +    x0 -=4;
 627.543 +    r0= -x0[2] - x1[0];
 627.544 +    r1= -x0[0] - x1[2];
 627.545 +    w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
 627.546 +    w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
 627.547 +    x1 +=4;
 627.548 +  }
 627.549 +
 627.550 +
 627.551 +  mdct_butterflies(init,w+n2,n2);
 627.552 +  mdct_bitreverse(init,w);
 627.553 +
 627.554 +  /* roatate + window */
 627.555 +
 627.556 +  T=init->trig+n2;
 627.557 +  x0=out+n2;
 627.558 +
 627.559 +  for(i=0;i<n4;i++){
 627.560 +    x0--;
 627.561 +    out[i] =MULT_NORM((w[0]*T[0]+w[1]*T[1])*init->scale);
 627.562 +    x0[0]  =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale);
 627.563 +    w+=2;
 627.564 +    T+=2;
 627.565 +  }
 627.566 +}
   628.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   628.2 +++ b/libs/vorbis/mdct.h	Sat Feb 01 19:58:19 2014 +0200
   628.3 @@ -0,0 +1,71 @@
   628.4 +/********************************************************************
   628.5 + *                                                                  *
   628.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   628.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   628.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   628.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  628.10 + *                                                                  *
  628.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  628.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  628.13 + *                                                                  *
  628.14 + ********************************************************************
  628.15 +
  628.16 + function: modified discrete cosine transform prototypes
  628.17 + last mod: $Id: mdct.h 16227 2009-07-08 06:58:46Z xiphmont $
  628.18 +
  628.19 + ********************************************************************/
  628.20 +
  628.21 +#ifndef _OGG_mdct_H_
  628.22 +#define _OGG_mdct_H_
  628.23 +
  628.24 +#include "vorbis/codec.h"
  628.25 +
  628.26 +
  628.27 +
  628.28 +
  628.29 +
  628.30 +/*#define MDCT_INTEGERIZED  <- be warned there could be some hurt left here*/
  628.31 +#ifdef MDCT_INTEGERIZED
  628.32 +
  628.33 +#define DATA_TYPE int
  628.34 +#define REG_TYPE  register int
  628.35 +#define TRIGBITS 14
  628.36 +#define cPI3_8 6270
  628.37 +#define cPI2_8 11585
  628.38 +#define cPI1_8 15137
  628.39 +
  628.40 +#define FLOAT_CONV(x) ((int)((x)*(1<<TRIGBITS)+.5))
  628.41 +#define MULT_NORM(x) ((x)>>TRIGBITS)
  628.42 +#define HALVE(x) ((x)>>1)
  628.43 +
  628.44 +#else
  628.45 +
  628.46 +#define DATA_TYPE float
  628.47 +#define REG_TYPE  float
  628.48 +#define cPI3_8 .38268343236508977175F
  628.49 +#define cPI2_8 .70710678118654752441F
  628.50 +#define cPI1_8 .92387953251128675613F
  628.51 +
  628.52 +#define FLOAT_CONV(x) (x)
  628.53 +#define MULT_NORM(x) (x)
  628.54 +#define HALVE(x) ((x)*.5f)
  628.55 +
  628.56 +#endif
  628.57 +
  628.58 +
  628.59 +typedef struct {
  628.60 +  int n;
  628.61 +  int log2n;
  628.62 +
  628.63 +  DATA_TYPE *trig;
  628.64 +  int       *bitrev;
  628.65 +
  628.66 +  DATA_TYPE scale;
  628.67 +} mdct_lookup;
  628.68 +
  628.69 +extern void mdct_init(mdct_lookup *lookup,int n);
  628.70 +extern void mdct_clear(mdct_lookup *l);
  628.71 +extern void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out);
  628.72 +extern void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out);
  628.73 +
  628.74 +#endif
   629.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   629.2 +++ b/libs/vorbis/misc.h	Sat Feb 01 19:58:19 2014 +0200
   629.3 @@ -0,0 +1,57 @@
   629.4 +/********************************************************************
   629.5 + *                                                                  *
   629.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   629.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   629.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   629.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  629.10 + *                                                                  *
  629.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  629.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  629.13 + *                                                                  *
  629.14 + ********************************************************************
  629.15 +
  629.16 + function: miscellaneous prototypes
  629.17 + last mod: $Id: misc.h 16227 2009-07-08 06:58:46Z xiphmont $
  629.18 +
  629.19 + ********************************************************************/
  629.20 +
  629.21 +#ifndef _V_RANDOM_H_
  629.22 +#define _V_RANDOM_H_
  629.23 +#include "vorbis/codec.h"
  629.24 +
  629.25 +extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes);
  629.26 +extern void _vorbis_block_ripcord(vorbis_block *vb);
  629.27 +
  629.28 +#ifdef ANALYSIS
  629.29 +extern int analysis_noisy;
  629.30 +extern void _analysis_output(char *base,int i,float *v,int n,int bark,int dB,
  629.31 +                             ogg_int64_t off);
  629.32 +extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,
  629.33 +                             ogg_int64_t off);
  629.34 +#endif
  629.35 +
  629.36 +#ifdef DEBUG_MALLOC
  629.37 +
  629.38 +#define _VDBG_GRAPHFILE "malloc.m"
  629.39 +#undef _VDBG_GRAPHFILE
  629.40 +extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line);
  629.41 +extern void _VDBG_free(void *ptr,char *file,long line);
  629.42 +
  629.43 +#ifndef MISC_C
  629.44 +#undef _ogg_malloc
  629.45 +#undef _ogg_calloc
  629.46 +#undef _ogg_realloc
  629.47 +#undef _ogg_free
  629.48 +
  629.49 +#define _ogg_malloc(x) _VDBG_malloc(NULL,(x),__FILE__,__LINE__)
  629.50 +#define _ogg_calloc(x,y) _VDBG_malloc(NULL,(x)*(y),__FILE__,__LINE__)
  629.51 +#define _ogg_realloc(x,y) _VDBG_malloc((x),(y),__FILE__,__LINE__)
  629.52 +#define _ogg_free(x) _VDBG_free((x),__FILE__,__LINE__)
  629.53 +#endif
  629.54 +#endif
  629.55 +
  629.56 +#endif
  629.57 +
  629.58 +
  629.59 +
  629.60 +
   630.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   630.2 +++ b/libs/vorbis/modes/floor_all.h	Sat Feb 01 19:58:19 2014 +0200
   630.3 @@ -0,0 +1,260 @@
   630.4 +/********************************************************************
   630.5 + *                                                                  *
   630.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   630.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   630.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   630.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  630.10 + *                                                                  *
  630.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  630.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  630.13 + *                                                                  *
  630.14 + ********************************************************************
  630.15 +
  630.16 + function: key floor settings
  630.17 + last mod: $Id: floor_all.h 17050 2010-03-26 01:34:42Z xiphmont $
  630.18 +
  630.19 + ********************************************************************/
  630.20 +
  630.21 +#include "vorbis/codec.h"
  630.22 +#include "backends.h"
  630.23 +#include "books/floor/floor_books.h"
  630.24 +
  630.25 +static const static_codebook*const _floor_128x4_books[]={
  630.26 +  &_huff_book_line_128x4_class0,
  630.27 +  &_huff_book_line_128x4_0sub0,
  630.28 +  &_huff_book_line_128x4_0sub1,
  630.29 +  &_huff_book_line_128x4_0sub2,
  630.30 +  &_huff_book_line_128x4_0sub3,
  630.31 +};
  630.32 +static const static_codebook*const _floor_256x4_books[]={
  630.33 +  &_huff_book_line_256x4_class0,
  630.34 +  &_huff_book_line_256x4_0sub0,
  630.35 +  &_huff_book_line_256x4_0sub1,
  630.36 +  &_huff_book_line_256x4_0sub2,
  630.37 +  &_huff_book_line_256x4_0sub3,
  630.38 +};
  630.39 +static const static_codebook*const _floor_128x7_books[]={
  630.40 +  &_huff_book_line_128x7_class0,
  630.41 +  &_huff_book_line_128x7_class1,
  630.42 +
  630.43 +  &_huff_book_line_128x7_0sub1,
  630.44 +  &_huff_book_line_128x7_0sub2,
  630.45 +  &_huff_book_line_128x7_0sub3,
  630.46 +  &_huff_book_line_128x7_1sub1,
  630.47 +  &_huff_book_line_128x7_1sub2,
  630.48 +  &_huff_book_line_128x7_1sub3,
  630.49 +};
  630.50 +static const static_codebook*const _floor_256x7_books[]={
  630.51 +  &_huff_book_line_256x7_class0,
  630.52 +  &_huff_book_line_256x7_class1,
  630.53 +
  630.54 +  &_huff_book_line_256x7_0sub1,
  630.55 +  &_huff_book_line_256x7_0sub2,
  630.56 +  &_huff_book_line_256x7_0sub3,
  630.57 +  &_huff_book_line_256x7_1sub1,
  630.58 +  &_huff_book_line_256x7_1sub2,
  630.59 +  &_huff_book_line_256x7_1sub3,
  630.60 +};
  630.61 +static const static_codebook*const _floor_128x11_books[]={
  630.62 +  &_huff_book_line_128x11_class1,
  630.63 +  &_huff_book_line_128x11_class2,
  630.64 +  &_huff_book_line_128x11_class3,
  630.65 +
  630.66 +  &_huff_book_line_128x11_0sub0,
  630.67 +  &_huff_book_line_128x11_1sub0,
  630.68 +  &_huff_book_line_128x11_1sub1,
  630.69 +  &_huff_book_line_128x11_2sub1,
  630.70 +  &_huff_book_line_128x11_2sub2,
  630.71 +  &_huff_book_line_128x11_2sub3,
  630.72 +  &_huff_book_line_128x11_3sub1,
  630.73 +  &_huff_book_line_128x11_3sub2,
  630.74 +  &_huff_book_line_128x11_3sub3,
  630.75 +};
  630.76 +static const static_codebook*const _floor_128x17_books[]={
  630.77 +  &_huff_book_line_128x17_class1,
  630.78 +  &_huff_book_line_128x17_class2,
  630.79 +  &_huff_book_line_128x17_class3,
  630.80 +
  630.81 +  &_huff_book_line_128x17_0sub0,
  630.82 +  &_huff_book_line_128x17_1sub0,
  630.83 +  &_huff_book_line_128x17_1sub1,
  630.84 +  &_huff_book_line_128x17_2sub1,
  630.85 +  &_huff_book_line_128x17_2sub2,
  630.86 +  &_huff_book_line_128x17_2sub3,
  630.87 +  &_huff_book_line_128x17_3sub1,
  630.88 +  &_huff_book_line_128x17_3sub2,
  630.89 +  &_huff_book_line_128x17_3sub3,
  630.90 +};
  630.91 +static const static_codebook*const _floor_256x4low_books[]={
  630.92 +  &_huff_book_line_256x4low_class0,
  630.93 +  &_huff_book_line_256x4low_0sub0,
  630.94 +  &_huff_book_line_256x4low_0sub1,
  630.95 +  &_huff_book_line_256x4low_0sub2,
  630.96 +  &_huff_book_line_256x4low_0sub3,
  630.97 +};
  630.98 +static const static_codebook*const _floor_1024x27_books[]={
  630.99 +  &_huff_book_line_1024x27_class1,
 630.100 +  &_huff_book_line_1024x27_class2,
 630.101 +  &_huff_book_line_1024x27_class3,
 630.102 +  &_huff_book_line_1024x27_class4,
 630.103 +
 630.104 +  &_huff_book_line_1024x27_0sub0,
 630.105 +  &_huff_book_line_1024x27_1sub0,
 630.106 +  &_huff_book_line_1024x27_1sub1,
 630.107 +  &_huff_book_line_1024x27_2sub0,
 630.108 +  &_huff_book_line_1024x27_2sub1,
 630.109 +  &_huff_book_line_1024x27_3sub1,
 630.110 +  &_huff_book_line_1024x27_3sub2,
 630.111 +  &_huff_book_line_1024x27_3sub3,
 630.112 +  &_huff_book_line_1024x27_4sub1,
 630.113 +  &_huff_book_line_1024x27_4sub2,
 630.114 +  &_huff_book_line_1024x27_4sub3,
 630.115 +};
 630.116 +static const static_codebook*const _floor_2048x27_books[]={
 630.117 +  &_huff_book_line_2048x27_class1,
 630.118 +  &_huff_book_line_2048x27_class2,
 630.119 +  &_huff_book_line_2048x27_class3,
 630.120 +  &_huff_book_line_2048x27_class4,
 630.121 +
 630.122 +  &_huff_book_line_2048x27_0sub0,
 630.123 +  &_huff_book_line_2048x27_1sub0,
 630.124 +  &_huff_book_line_2048x27_1sub1,
 630.125 +  &_huff_book_line_2048x27_2sub0,
 630.126 +  &_huff_book_line_2048x27_2sub1,
 630.127 +  &_huff_book_line_2048x27_3sub1,
 630.128 +  &_huff_book_line_2048x27_3sub2,
 630.129 +  &_huff_book_line_2048x27_3sub3,
 630.130 +  &_huff_book_line_2048x27_4sub1,
 630.131 +  &_huff_book_line_2048x27_4sub2,
 630.132 +  &_huff_book_line_2048x27_4sub3,
 630.133 +};
 630.134 +
 630.135 +static const static_codebook*const _floor_512x17_books[]={
 630.136 +  &_huff_book_line_512x17_class1,
 630.137 +  &_huff_book_line_512x17_class2,
 630.138 +  &_huff_book_line_512x17_class3,
 630.139 +
 630.140 +  &_huff_book_line_512x17_0sub0,
 630.141 +  &_huff_book_line_512x17_1sub0,
 630.142 +  &_huff_book_line_512x17_1sub1,
 630.143 +  &_huff_book_line_512x17_2sub1,
 630.144 +  &_huff_book_line_512x17_2sub2,
 630.145 +  &_huff_book_line_512x17_2sub3,
 630.146 +  &_huff_book_line_512x17_3sub1,
 630.147 +  &_huff_book_line_512x17_3sub2,
 630.148 +  &_huff_book_line_512x17_3sub3,
 630.149 +};
 630.150 +
 630.151 +static const static_codebook*const _floor_Xx0_books[]={
 630.152 +  0
 630.153 +};
 630.154 +
 630.155 +static const static_codebook*const *const _floor_books[11]={
 630.156 +  _floor_128x4_books,
 630.157 +  _floor_256x4_books,
 630.158 +  _floor_128x7_books,
 630.159 +  _floor_256x7_books,
 630.160 +  _floor_128x11_books,
 630.161 +  _floor_128x17_books,
 630.162 +  _floor_256x4low_books,
 630.163 +  _floor_1024x27_books,
 630.164 +  _floor_2048x27_books,
 630.165 +  _floor_512x17_books,
 630.166 +  _floor_Xx0_books,
 630.167 +};
 630.168 +
 630.169 +static const vorbis_info_floor1 _floor[11]={
 630.170 +  /* 0: 128 x 4 */
 630.171 +  {
 630.172 +    1,{0},{4},{2},{0},
 630.173 +    {{1,2,3,4}},
 630.174 +    4,{0,128, 33,8,16,70},
 630.175 +
 630.176 +    60,30,500,   1.,18.,  128
 630.177 +  },
 630.178 +  /* 1: 256 x 4 */
 630.179 +  {
 630.180 +    1,{0},{4},{2},{0},
 630.181 +    {{1,2,3,4}},
 630.182 +    4,{0,256, 66,16,32,140},
 630.183 +
 630.184 +    60,30,500,   1.,18.,  256
 630.185 +  },
 630.186 +  /* 2: 128 x 7 */
 630.187 +  {
 630.188 +    2,{0,1},{3,4},{2,2},{0,1},
 630.189 +    {{-1,2,3,4},{-1,5,6,7}},
 630.190 +    4,{0,128, 14,4,58, 2,8,28,90},
 630.191 +
 630.192 +    60,30,500,   1.,18.,  128
 630.193 +  },
 630.194 +  /* 3: 256 x 7 */
 630.195 +  {
 630.196 +    2,{0,1},{3,4},{2,2},{0,1},
 630.197 +    {{-1,2,3,4},{-1,5,6,7}},
 630.198 +    4,{0,256, 28,8,116, 4,16,56,180},
 630.199 +
 630.200 +    60,30,500,   1.,18.,  256
 630.201 +  },
 630.202 +  /* 4: 128 x 11 */
 630.203 +  {
 630.204 +    4,{0,1,2,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2},
 630.205 +    {{3},{4,5},{-1,6,7,8},{-1,9,10,11}},
 630.206 +
 630.207 +    2,{0,128,  8,33,  4,16,70,  2,6,12,  23,46,90},
 630.208 +
 630.209 +     60,30,500,   1,18.,  128
 630.210 +  },
 630.211 +  /* 5: 128 x 17 */
 630.212 +  {
 630.213 +    6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2},
 630.214 +    {{3},{4,5},{-1,6,7,8},{-1,9,10,11}},
 630.215 +    2,{0,128,  12,46,  4,8,16,  23,33,70,  2,6,10,  14,19,28,  39,58,90},
 630.216 +
 630.217 +    60,30,500,    1,18.,  128
 630.218 +  },
 630.219 +  /* 6: 256 x 4 (low bitrate version) */
 630.220 +  {
 630.221 +    1,{0},{4},{2},{0},
 630.222 +    {{1,2,3,4}},
 630.223 +    4,{0,256, 66,16,32,140},
 630.224 +
 630.225 +    60,30,500,   1.,18.,  256
 630.226 +  },
 630.227 +  /* 7: 1024 x 27 */
 630.228 +  {
 630.229 +    8,{0,1,2,2,3,3,4,4},{3,4,3,4,3},{0,1,1,2,2},{-1,0,1,2,3},
 630.230 +    {{4},{5,6},{7,8},{-1,9,10,11},{-1,12,13,14}},
 630.231 +    2,{0,1024,   93,23,372, 6,46,186,750,  14,33,65, 130,260,556,
 630.232 +       3,10,18,28,  39,55,79,111,  158,220,312,  464,650,850},
 630.233 +
 630.234 +    60,30,500,    3,18.,  1024
 630.235 +  },
 630.236 +  /* 8: 2048 x 27 */
 630.237 +  {
 630.238 +    8,{0,1,2,2,3,3,4,4},{3,4,3,4,3},{0,1,1,2,2},{-1,0,1,2,3},
 630.239 +    {{4},{5,6},{7,8},{-1,9,10,11},{-1,12,13,14}},
 630.240 +    2,{0,2048,   186,46,744, 12,92,372,1500,  28,66,130, 260,520,1112,
 630.241 +       6,20,36,56,  78,110,158,222,  316,440,624,  928,1300,1700},
 630.242 +
 630.243 +    60,30,500,    3,18.,  2048
 630.244 +  },
 630.245 +  /* 9: 512 x 17 */
 630.246 +  {
 630.247 +    6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2},
 630.248 +    {{3},{4,5},{-1,6,7,8},{-1,9,10,11}},
 630.249 +    2,{0,512,  46,186,  16,33,65,  93,130,278,
 630.250 +       7,23,39,  55,79,110,  156,232,360},
 630.251 +
 630.252 +    60,30,500,    1,18.,  512
 630.253 +  },
 630.254 +
 630.255 +  /* 10: X x 0 (LFE floor; edge posts only) */
 630.256 +  {
 630.257 +    0,{0}, {0},{0},{-1},
 630.258 +    {{-1}},
 630.259 +    2,{0,12},
 630.260 +    60,30,500,   1.,18.,  10
 630.261 +  },
 630.262 +
 630.263 +};
   631.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   631.2 +++ b/libs/vorbis/modes/psych_11.h	Sat Feb 01 19:58:19 2014 +0200
   631.3 @@ -0,0 +1,51 @@
   631.4 +/********************************************************************
   631.5 + *                                                                  *
   631.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   631.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   631.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   631.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  631.10 + *                                                                  *
  631.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  631.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  631.13 + *                                                                  *
  631.14 + ********************************************************************
  631.15 +
  631.16 + function: 11kHz settings
  631.17 + last mod: $Id: psych_11.h 16227 2009-07-08 06:58:46Z xiphmont $
  631.18 +
  631.19 + ********************************************************************/
  631.20 +
  631.21 +static const double _psy_lowpass_11[3]={4.5,5.5,30.,};
  631.22 +
  631.23 +static const att3 _psy_tone_masteratt_11[3]={
  631.24 +  {{ 30,  25,  12},  0,   0},  /* 0 */
  631.25 +  {{ 30,  25,  12},  0,   0},  /* 0 */
  631.26 +  {{ 20,   0, -14},  0,   0}, /* 0 */
  631.27 +};
  631.28 +
  631.29 +static const vp_adjblock _vp_tonemask_adj_11[3]={
  631.30 +  /* adjust for mode zero */
  631.31 +  /* 63     125     250     500     1     2     4     8    16 */
  631.32 +  {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 2, 0,99,99,99}}, /* 0 */
  631.33 +  {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 5, 0, 0,99,99,99}}, /* 1 */
  631.34 +  {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 0, 0, 0,99,99,99}}, /* 2 */
  631.35 +};
  631.36 +
  631.37 +
  631.38 +static const noise3 _psy_noisebias_11[3]={
  631.39 +  /*  63     125     250     500      1k       2k      4k      8k     16k*/
  631.40 +  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4, 10, 10, 12, 12, 12, 99, 99, 99},
  631.41 +    {-15,-15,-15,-15,-10,-10, -5,  0,  0,  4,  4,  5,  5, 10, 99, 99, 99},
  631.42 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
  631.43 +
  631.44 +  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4, 10, 10, 12, 12, 12, 99, 99, 99},
  631.45 +    {-15,-15,-15,-15,-10,-10, -5, -5, -5,  0,  0,  0,  0,  0, 99, 99, 99},
  631.46 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
  631.47 +
  631.48 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5, 99, 99, 99},
  631.49 +    {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10, 99, 99, 99},
  631.50 +    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24, 99, 99, 99}}},
  631.51 +};
  631.52 +
  631.53 +static const double _noise_thresh_11[3]={ .3,.5,.5 };
  631.54 +
   632.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   632.2 +++ b/libs/vorbis/modes/psych_16.h	Sat Feb 01 19:58:19 2014 +0200
   632.3 @@ -0,0 +1,133 @@
   632.4 +/********************************************************************
   632.5 + *                                                                  *
   632.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   632.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   632.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   632.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  632.10 + *                                                                  *
  632.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  632.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  632.13 + *                                                                  *
  632.14 + ********************************************************************
  632.15 +
  632.16 + function: 16kHz settings
  632.17 + last mod: $Id: psych_16.h 16227 2009-07-08 06:58:46Z xiphmont $
  632.18 +
  632.19 + ********************************************************************/
  632.20 +
  632.21 +/* stereo mode by base quality level */
  632.22 +static const adj_stereo _psy_stereo_modes_16[4]={
  632.23 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  */
  632.24 +  {{  4,  4,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
  632.25 +   {  6,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
  632.26 +   {  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  4,  4},
  632.27 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
  632.28 +  {{  4,  4,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
  632.29 +   {  6,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
  632.30 +   {  2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  4,  4,  4,  4,  4},
  632.31 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
  632.32 +  {{  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
  632.33 +   {  5,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
  632.34 +   {  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
  632.35 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
  632.36 +  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  632.37 +   {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  632.38 +   {  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8},
  632.39 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
  632.40 +};
  632.41 +
  632.42 +static const double _psy_lowpass_16[4]={6.5,8,30.,99.};
  632.43 +
  632.44 +static const att3 _psy_tone_masteratt_16[4]={
  632.45 +  {{ 30,  25,  12},  0,   0},  /* 0 */
  632.46 +  {{ 25,  22,  12},  0,   0},  /* 0 */
  632.47 +  {{ 20,  12,   0},  0,   0},  /* 0 */
  632.48 +  {{ 15,   0, -14},  0,   0}, /* 0 */
  632.49 +};
  632.50 +
  632.51 +static const vp_adjblock _vp_tonemask_adj_16[4]={
  632.52 +  /* adjust for mode zero */
  632.53 +  /* 63     125     250     500       1     2     4     8    16 */
  632.54 +  {{-20,-20,-20,-20,-20,-16,-10,  0,  0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 0 */
  632.55 +  {{-20,-20,-20,-20,-20,-16,-10,  0,  0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 1 */
  632.56 +  {{-20,-20,-20,-20,-20,-16,-10,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */
  632.57 +  {{-30,-30,-30,-30,-30,-26,-20,-10, -5, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */
  632.58 +};
  632.59 +
  632.60 +
  632.61 +static const noise3 _psy_noisebias_16_short[4]={
  632.62 +  /*  63     125     250     500      1k       2k      4k      8k     16k*/
  632.63 +  {{{-15,-15,-15,-15,-15,-10,-10,-5,   4, 10, 10, 10, 10, 12, 12, 14, 20},
  632.64 +    {-15,-15,-15,-15,-15,-10,-10, -5,  0,  0,  4,  5,  5,  6,  8,  8, 15},
  632.65 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
  632.66 +
  632.67 +  {{{-15,-15,-15,-15,-15,-10,-10,-5,   4,  6,  6,  6,  6,  8, 10, 12, 20},
  632.68 +    {-15,-15,-15,-15,-15,-15,-15,-10, -5, -5, -5,  4,  5,  6,  8,  8, 15},
  632.69 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10,-10,-10,-10,-10,-10,-10,-10,-10}}},
  632.70 +
  632.71 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5,  5,  8, 12},
  632.72 +    {-20,-20,-20,-20,-16,-12,-20,-14,-10,-10, -8,  0,  0,  0,  0,  2,  5},
  632.73 +    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
  632.74 +
  632.75 +  {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5,  0,  0,  0,  6},
  632.76 +    {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10,-10,-10, -6},
  632.77 +    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
  632.78 +};
  632.79 +
  632.80 +static const noise3 _psy_noisebias_16_impulse[4]={
  632.81 +  /*  63     125     250     500      1k       2k      4k      8k     16k*/
  632.82 +  {{{-15,-15,-15,-15,-15,-10,-10,-5,   4, 10, 10, 10, 10, 12, 12, 14, 20},
  632.83 +    {-15,-15,-15,-15,-15,-10,-10, -5,  0,  0,  4,  5,  5,  6,  8,  8, 15},
  632.84 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
  632.85 +
  632.86 +  {{{-15,-15,-15,-15,-15,-10,-10,-5,   4,  4,  4,  4,  5,  5,  6,  8, 15},
  632.87 +    {-15,-15,-15,-15,-15,-15,-15,-10, -5, -5, -5,  0,  0,  0,  0,  4, 10},
  632.88 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10,-10,-10,-10,-10,-10,-10,-10,-10}}},
  632.89 +
  632.90 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  4, 10},
  632.91 +    {-20,-20,-20,-20,-16,-12,-20,-14,-10,-10,-10,-10,-10,-10,-10, -7, -5},
  632.92 +    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
  632.93 +
  632.94 +  {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5,  0,  0,  0,  6},
  632.95 +    {-30,-30,-30,-30,-26,-22,-20,-18,-18,-18,-20,-20,-20,-20,-20,-20,-16},
  632.96 +    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
  632.97 +};
  632.98 +
  632.99 +static const noise3 _psy_noisebias_16[4]={
 632.100 +  /*  63     125     250     500      1k       2k      4k      8k     16k*/
 632.101 +  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4,  6,  8,  8, 10, 10, 10, 14, 20},
 632.102 +    {-10,-10,-10,-10,-10, -5, -2, -2,  0,  0,  0,  4,  5,  6,  8,  8, 15},
 632.103 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
 632.104 +
 632.105 +  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4,  6,  6,  6,  6,  8, 10, 12, 20},
 632.106 +    {-15,-15,-15,-15,-15,-10, -5, -5,  0,  0,  0,  4,  5,  6,  8,  8, 15},
 632.107 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
 632.108 +
 632.109 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5,  5,  8, 12},
 632.110 +    {-20,-20,-20,-20,-16,-12,-20,-10, -5, -5,  0,  0,  0,  0,  0,  2,  5},
 632.111 +    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
 632.112 +
 632.113 +  {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5,  0,  0,  0,  6},
 632.114 +    {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10,-10,-10, -6},
 632.115 +    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
 632.116 +};
 632.117 +
 632.118 +static const noiseguard _psy_noiseguards_16[4]={
 632.119 +  {10,10,-1},
 632.120 +  {10,10,-1},
 632.121 +  {20,20,-1},
 632.122 +  {20,20,-1},
 632.123 +};
 632.124 +
 632.125 +static const double _noise_thresh_16[4]={ .3,.5,.5,.5 };
 632.126 +
 632.127 +static const int _noise_start_16[3]={ 256,256,9999 };
 632.128 +static const int _noise_part_16[4]={ 8,8,8,8 };
 632.129 +
 632.130 +static const int _psy_ath_floater_16[4]={
 632.131 +  -100,-100,-100,-105,
 632.132 +};
 632.133 +
 632.134 +static const int _psy_ath_abs_16[4]={
 632.135 +  -130,-130,-130,-140,
 632.136 +};
   633.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   633.2 +++ b/libs/vorbis/modes/psych_44.h	Sat Feb 01 19:58:19 2014 +0200
   633.3 @@ -0,0 +1,642 @@
   633.4 +/********************************************************************
   633.5 + *                                                                  *
   633.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   633.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   633.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   633.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  633.10 + *                                                                  *
  633.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  633.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  633.13 + *                                                                  *
  633.14 + ********************************************************************
  633.15 +
  633.16 + function: key psychoacoustic settings for 44.1/48kHz
  633.17 + last mod: $Id: psych_44.h 16962 2010-03-11 07:30:34Z xiphmont $
  633.18 +
  633.19 + ********************************************************************/
  633.20 +
  633.21 +
  633.22 +/* preecho trigger settings *****************************************/
  633.23 +
  633.24 +static const vorbis_info_psy_global _psy_global_44[5]={
  633.25 +
  633.26 +  {8,   /* lines per eighth octave */
  633.27 +   {20.f,14.f,12.f,12.f,12.f,12.f,12.f},
  633.28 +   {-60.f,-30.f,-40.f,-40.f,-40.f,-40.f,-40.f}, 2,-75.f,
  633.29 +   -6.f,
  633.30 +   {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
  633.31 +  },
  633.32 +  {8,   /* lines per eighth octave */
  633.33 +   {14.f,10.f,10.f,10.f,10.f,10.f,10.f},
  633.34 +   {-40.f,-30.f,-25.f,-25.f,-25.f,-25.f,-25.f}, 2,-80.f,
  633.35 +   -6.f,
  633.36 +   {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
  633.37 +  },
  633.38 +  {8,   /* lines per eighth octave */
  633.39 +   {12.f,10.f,10.f,10.f,10.f,10.f,10.f},
  633.40 +   {-20.f,-20.f,-15.f,-15.f,-15.f,-15.f,-15.f}, 0,-80.f,
  633.41 +   -6.f,
  633.42 +   {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
  633.43 +  },
  633.44 +  {8,   /* lines per eighth octave */
  633.45 +   {10.f,8.f,8.f,8.f,8.f,8.f,8.f},
  633.46 +   {-20.f,-15.f,-12.f,-12.f,-12.f,-12.f,-12.f}, 0,-80.f,
  633.47 +   -6.f,
  633.48 +   {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
  633.49 +  },
  633.50 +  {8,   /* lines per eighth octave */
  633.51 +   {10.f,6.f,6.f,6.f,6.f,6.f,6.f},
  633.52 +   {-15.f,-15.f,-12.f,-12.f,-12.f,-12.f,-12.f}, 0,-85.f,
  633.53 +   -6.f,
  633.54 +   {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
  633.55 +  },
  633.56 +};
  633.57 +
  633.58 +/* noise compander lookups * low, mid, high quality ****************/
  633.59 +static const compandblock _psy_compand_44[6]={
  633.60 +  /* sub-mode Z short */
  633.61 +  {{
  633.62 +    0, 1, 2, 3, 4, 5, 6,  7,     /* 7dB */
  633.63 +    8, 9,10,11,12,13,14, 15,     /* 15dB */
  633.64 +    16,17,18,19,20,21,22, 23,     /* 23dB */
  633.65 +    24,25,26,27,28,29,30, 31,     /* 31dB */
  633.66 +    32,33,34,35,36,37,38, 39,     /* 39dB */
  633.67 +  }},
  633.68 +  /* mode_Z nominal short */
  633.69 +  {{
  633.70 +     0, 1, 2, 3, 4, 5, 6,  6,     /* 7dB */
  633.71 +     7, 7, 7, 7, 6, 6, 6,  7,     /* 15dB */
  633.72 +     7, 8, 9,10,11,12,13, 14,     /* 23dB */
  633.73 +    15,16,17,17,17,18,18, 19,     /* 31dB */
  633.74 +    19,19,20,21,22,23,24, 25,     /* 39dB */
  633.75 +  }},
  633.76 +  /* mode A short */
  633.77 +  {{
  633.78 +    0, 1, 2, 3, 4, 5, 5,  5,     /* 7dB */
  633.79 +    6, 6, 6, 5, 4, 4, 4,  4,     /* 15dB */
  633.80 +    4, 4, 5, 5, 5, 6, 6,  6,     /* 23dB */
  633.81 +    7, 7, 7, 8, 8, 8, 9, 10,     /* 31dB */
  633.82 +    11,12,13,14,15,16,17, 18,     /* 39dB */
  633.83 +  }},
  633.84 +  /* sub-mode Z long */
  633.85 +  {{
  633.86 +     0, 1, 2, 3, 4, 5, 6,  7,     /* 7dB */
  633.87 +     8, 9,10,11,12,13,14, 15,     /* 15dB */
  633.88 +    16,17,18,19,20,21,22, 23,     /* 23dB */
  633.89 +    24,25,26,27,28,29,30, 31,     /* 31dB */
  633.90 +    32,33,34,35,36,37,38, 39,     /* 39dB */
  633.91 +  }},
  633.92 +  /* mode_Z nominal long */
  633.93 +  {{
  633.94 +    0, 1, 2, 3, 4, 5, 6,  7,     /* 7dB */
  633.95 +    8, 9,10,11,12,12,13, 13,     /* 15dB */
  633.96 +    13,14,14,14,15,15,15, 15,     /* 23dB */
  633.97 +    16,16,17,17,17,18,18, 19,     /* 31dB */
  633.98 +    19,19,20,21,22,23,24, 25,     /* 39dB */
  633.99 +  }},
 633.100 +  /* mode A long */
 633.101 +  {{
 633.102 +    0, 1, 2, 3, 4, 5, 6,  7,     /* 7dB */
 633.103 +    8, 8, 7, 6, 5, 4, 4,  4,     /* 15dB */
 633.104 +    4, 4, 5, 5, 5, 6, 6,  6,     /* 23dB */
 633.105 +    7, 7, 7, 8, 8, 8, 9, 10,     /* 31dB */
 633.106 +    11,12,13,14,15,16,17, 18,     /* 39dB */
 633.107 +  }}
 633.108 +};
 633.109 +
 633.110 +/* tonal masking curve level adjustments *************************/
 633.111 +
 633.112 +static const vp_adjblock _vp_tonemask_adj_longblock[12]={
 633.113 +
 633.114 +   /* 63     125     250     500       1       2       4       8      16 */
 633.115 +
 633.116 +   {{ -3, -8,-13,-15,-10,-10,-10,-10,-10,-10,-10,  0,  0,  0,  0,  0,  0}}, /* -1 */
 633.117 +
 633.118 +/* {{-15,-15,-15,-15,-10, -8, -4, -2,  0,  0,  0, 10,  0,  0,  0,  0,  0}},    0 */
 633.119 +   {{ -4,-10,-14,-16,-15,-14,-13,-12,-12,-12,-11, -1, -1, -1, -1, -1,  0}}, /* 0 */
 633.120 +
 633.121 +/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  5,  0,  0,  0,  0,  0}},    1 */
 633.122 +   {{ -6,-12,-14,-16,-15,-15,-14,-13,-13,-12,-12, -2, -2, -1, -1, -1,  0}}, /* 1 */
 633.123 +
 633.124 +/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    2 */
 633.125 +   {{-12,-13,-14,-16,-16,-16,-15,-14,-13,-12,-12, -6, -3, -1, -1, -1,  0}}, /* 2 */
 633.126 +
 633.127 +/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    3 */
 633.128 +   {{-15,-15,-15,-16,-16,-16,-16,-14,-13,-13,-13,-10, -4, -2, -1, -1,  0}}, /* 3 */
 633.129 +
 633.130 +/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}}, *//* 4 */
 633.131 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7  -3, -1, -1 , 0}}, /* 4 */
 633.132 +
 633.133 +/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    5 */
 633.134 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7  -3, -1, -1 , 0}}, /* 5 */
 633.135 +
 633.136 +/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    6 */
 633.137 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -8, -4, -2, -2,  0}}, /* 6 */
 633.138 +
 633.139 +/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    7 */
 633.140 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 7 */
 633.141 +
 633.142 +/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    8 */
 633.143 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 8 */
 633.144 +
 633.145 +/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    9 */
 633.146 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 9 */
 633.147 +
 633.148 +/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    10 */
 633.149 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 10 */
 633.150 +};
 633.151 +
 633.152 +static const vp_adjblock _vp_tonemask_adj_otherblock[12]={
 633.153 +   /* 63     125     250     500       1       2       4       8      16 */
 633.154 +
 633.155 +   {{ -3, -8,-13,-15,-10,-10, -9, -9, -9, -9, -9,  1,  1,  1,  1,  1,  1}}, /* -1 */
 633.156 +
 633.157 +/* {{-20,-20,-20,-20,-14,-12,-10, -8, -4,  0,  0, 10,  0,  0,  0,  0,  0}},    0 */
 633.158 +   {{ -4,-10,-14,-16,-14,-13,-12,-12,-11,-11,-10,  0,  0,  0,  0,  0,  0}}, /* 0 */
 633.159 +
 633.160 +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  5,  0,  0,  0,  0,  0}},    1 */
 633.161 +   {{ -6,-12,-14,-16,-15,-15,-14,-13,-13,-12,-12, -2, -2, -1,  0,  0,  0}}, /* 1 */
 633.162 +
 633.163 +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    2 */
 633.164 +   {{-12,-13,-14,-16,-16,-16,-15,-14,-13,-12,-12, -5, -2, -1,  0,  0,  0}}, /* 2 */
 633.165 +
 633.166 +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    3 */
 633.167 +   {{-15,-15,-15,-16,-16,-16,-16,-14,-13,-13,-13,-10, -4, -2,  0,  0,  0}}, /* 3 */
 633.168 +
 633.169 +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    4 */
 633.170 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7  -3, -1, -1 , 0}}, /* 4 */
 633.171 +
 633.172 +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    5 */
 633.173 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7  -3, -1, -1 , 0}}, /* 5 */
 633.174 +
 633.175 +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    6 */
 633.176 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -8, -4, -2, -2,  0}}, /* 6 */
 633.177 +
 633.178 +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    7 */
 633.179 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 7 */
 633.180 +
 633.181 +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    8 */
 633.182 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 8 */
 633.183 +
 633.184 +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    9 */
 633.185 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 9 */
 633.186 +
 633.187 +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    10 */
 633.188 +   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 10 */
 633.189 +};
 633.190 +
 633.191 +/* noise bias (transition block) */
 633.192 +static const noise3 _psy_noisebias_trans[12]={
 633.193 +  /*  63     125     250     500      1k       2k      4k      8k     16k*/
 633.194 +  /* -1 */
 633.195 +  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  8,  8,  8,  8, 10, 12, 14, 20},
 633.196 +    {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2,  2,  2,  3,  6,  6, 15},
 633.197 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
 633.198 +  /* 0
 633.199 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5,  5,  8,  10},
 633.200 +    {-30,-30,-30,-30,-26,-22,-20,-14, -8, -4,  0,  0,  0,  0,  2,  4,  10},
 633.201 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -4, -4, -4,  -2}}},*/
 633.202 +  {{{-15,-15,-15,-15,-15,-12, -6, -4,  0,  2,  4,  4,  5,  5,  5,  8,  10},
 633.203 +    {-30,-30,-30,-30,-26,-22,-20,-14, -8, -4,  0,  0,  0,  0,  2,  3,   6},
 633.204 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -4, -4, -4,  -2}}},
 633.205 +  /* 1
 633.206 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5,  5,  8,  10},
 633.207 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2,  0,  2,  8},
 633.208 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},*/
 633.209 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5,  5,  8,  10},
 633.210 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2,  0,  1,   4},
 633.211 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6,  -4}}},
 633.212 +  /* 2
 633.213 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  2,  2,  4,  4,  5,  6,  10},
 633.214 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2,  0,  2,  6},
 633.215 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, */
 633.216 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  2,  2,  4,  4,  5,  6,  10},
 633.217 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -2, -1,  0,  3},
 633.218 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -7, -4}}},
 633.219 +  /* 3
 633.220 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  2,  2,  4,  4,  4,  5,  8},
 633.221 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -1,  1,  6},
 633.222 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
 633.223 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  2,  2,  4,  4,  4,  5,  8},
 633.224 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -2,  0,  2},
 633.225 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},
 633.226 +  /* 4
 633.227 +  {{{-20,-20,-20,-20,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
 633.228 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -1,  1,  5},
 633.229 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
 633.230 +  {{{-20,-20,-20,-20,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
 633.231 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -2, -1,  1},
 633.232 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},
 633.233 +  /* 5
 633.234 +  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
 633.235 +    {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -4, -4, -4, -4, -2, -1,  2},
 633.236 +    {-34,-34,-34,-34,-30,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}}, */
 633.237 +  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
 633.238 +    {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -4, -4, -4, -4, -3, -1,  0},
 633.239 +    {-34,-34,-34,-34,-30,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}},
 633.240 +  /* 6
 633.241 +  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
 633.242 +    {-32,-32,-32,-32,-28,-24,-24,-18,-14, -8, -6, -6, -6, -6, -4, -2,  1},
 633.243 +    {-34,-34,-34,-34,-30,-26,-24,-18,-17,-15,-15,-15,-15,-13,-13,-12, -8}}},*/
 633.244 +  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
 633.245 +    {-32,-32,-32,-32,-28,-24,-24,-18,-14, -8, -6, -6, -6, -6, -5, -2,  0},
 633.246 +    {-34,-34,-34,-34,-30,-26,-26,-24,-22,-19,-19,-19,-19,-18,-17,-16,-12}}},
 633.247 +  /* 7
 633.248 +  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
 633.249 +    {-32,-32,-32,-32,-28,-24,-24,-18,-14,-12,-10, -8, -8, -8, -6, -4,  0},
 633.250 +    {-34,-34,-34,-34,-30,-26,-26,-24,-22,-19,-19,-19,-19,-18,-17,-16,-12}}},*/
 633.251 +  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
 633.252 +    {-32,-32,-32,-32,-28,-24,-24,-24,-18,-14,-12,-10,-10,-10, -8, -6, -2},
 633.253 +    {-34,-34,-34,-34,-30,-26,-26,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},
 633.254 +  /* 8
 633.255 +  {{{-24,-24,-24,-24,-22,-20,-15,-10, -8, -2,  0,  0,  0,  1,  2,  3,  7},
 633.256 +    {-36,-36,-36,-36,-30,-30,-30,-24,-18,-14,-12,-10,-10,-10, -8, -6, -2},
 633.257 +    {-36,-36,-36,-36,-34,-30,-28,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},*/
 633.258 +  {{{-24,-24,-24,-24,-22,-20,-15,-10, -8, -2,  0,  0,  0,  1,  2,  3,  7},
 633.259 +    {-36,-36,-36,-36,-30,-30,-30,-24,-20,-16,-16,-16,-16,-14,-12,-10, -7},
 633.260 +    {-36,-36,-36,-36,-34,-30,-28,-26,-24,-30,-30,-30,-30,-30,-30,-24,-20}}},
 633.261 +  /* 9
 633.262 +  {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2,  2},
 633.263 +    {-36,-36,-36,-36,-34,-32,-32,-28,-20,-16,-16,-16,-16,-14,-12,-10, -7},
 633.264 +    {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},*/
 633.265 +  {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2,  2},
 633.266 +    {-38,-38,-38,-38,-36,-34,-34,-30,-24,-20,-20,-20,-20,-18,-16,-12,-10},
 633.267 +    {-40,-40,-40,-40,-40,-40,-40,-38,-35,-35,-35,-35,-35,-35,-35,-35,-30}}},
 633.268 +  /* 10 */
 633.269 +  {{{-30,-30,-30,-30,-30,-30,-30,-28,-20,-14,-14,-14,-14,-14,-14,-12,-10},
 633.270 +    {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-30,-30,-30,-30,-30,-30,-20},
 633.271 +    {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
 633.272 +};
 633.273 +
 633.274 +/*  noise bias (long block) */
 633.275 +static const noise3 _psy_noisebias_long[12]={
 633.276 +  /*63     125     250     500      1k       2k      4k      8k     16k*/
 633.277 +  /* -1 */
 633.278 +  {{{-10,-10,-10,-10,-10, -4,  0,  0,  0,  6,  6,  6,  6, 10, 10, 12,  20},
 633.279 +    {-20,-20,-20,-20,-20,-20,-10, -2,  0,  0,  0,  0,  0,  2,  4,  6,  15},
 633.280 +    {-20,-20,-20,-20,-20,-20,-20,-10, -6, -6, -6, -6, -6, -4, -4, -4, -2}}},
 633.281 +
 633.282 +  /* 0 */
 633.283 +  /*  {{{-10,-10,-10,-10,-10,-10, -8,  2,  2,  2,  4,  4,  5,  5,  5,  8,  10},
 633.284 +      {-20,-20,-20,-20,-20,-20,-20,-14, -6,  0,  0,  0,  0,  0,  2,  4,  10},
 633.285 +      {-20,-20,-20,-20,-20,-20,-20,-14, -8, -6, -6, -6, -6, -4, -4, -4, -2}}},*/
 633.286 +  {{{-10,-10,-10,-10,-10,-10, -8,  2,  2,  2,  4,  4,  5,  5,  5,  8,  10},
 633.287 +    {-20,-20,-20,-20,-20,-20,-20,-14, -6,  0,  0,  0,  0,  0,  2,  3,  6},
 633.288 +    {-20,-20,-20,-20,-20,-20,-20,-14, -8, -6, -6, -6, -6, -4, -4, -4, -2}}},
 633.289 +  /* 1 */
 633.290 +  /*  {{{-10,-10,-10,-10,-10,-10, -8, -4,  0,  2,  4,  4,  5,  5,  5,  8,  10},
 633.291 +      {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2,  0,  2,  8},
 633.292 +      {-20,-20,-20,-20,-20,-20,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},*/
 633.293 +  {{{-10,-10,-10,-10,-10,-10, -8, -4,  0,  2,  4,  4,  5,  5,  5,  8,  10},
 633.294 +    {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2,  0,  1,  4},
 633.295 +    {-20,-20,-20,-20,-20,-20,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},
 633.296 +  /* 2 */
 633.297 +  /*  {{{-10,-10,-10,-10,-10,-10,-10, -8,  0,  2,  2,  2,  4,  4,  5,  6,  10},
 633.298 +      {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2,  0,  2,  6},
 633.299 +      {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
 633.300 +  {{{-10,-10,-10,-10,-10,-10,-10, -8,  0,  2,  2,  2,  4,  4,  5,  6,  10},
 633.301 +    {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -2, -1,  0,  3},
 633.302 +    {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},
 633.303 +  /* 3 */
 633.304 +  /*  {{{-10,-10,-10,-10,-10,-10,-10, -8,  0,  2,  2,  2,  4,  4,  4,  5,  8},
 633.305 +      {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -1,  1,  6},
 633.306 +      {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
 633.307 +  {{{-10,-10,-10,-10,-10,-10,-10, -8,  0,  2,  2,  2,  4,  4,  4,  5,  8},
 633.308 +    {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -2,  0,  2},
 633.309 +    {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -5}}},
 633.310 +  /* 4 */
 633.311 +  /*  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
 633.312 +      {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -1,  1,  5},
 633.313 +      {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
 633.314 +  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
 633.315 +    {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -2, -1,  1},
 633.316 +    {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -7}}},
 633.317 +  /* 5 */
 633.318 +  /*  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
 633.319 +      {-22,-22,-22,-22,-22,-22,-22,-16,-12, -6, -4, -4, -4, -4, -2, -1,  2},
 633.320 +      {-24,-24,-24,-24,-24,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}},*/
 633.321 +  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
 633.322 +    {-22,-22,-22,-22,-22,-22,-22,-16,-12, -6, -4, -4, -4, -4, -3, -1,  0},
 633.323 +    {-24,-24,-24,-24,-24,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -8}}},
 633.324 +  /* 6 */
 633.325 +  /*  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
 633.326 +      {-24,-24,-24,-24,-24,-24,-24,-18,-14, -8, -6, -6, -6, -6, -4, -2,  1},
 633.327 +      {-26,-26,-26,-26,-26,-26,-26,-18,-16,-15,-15,-15,-15,-13,-13,-12, -8}}},*/
 633.328 +  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
 633.329 +    {-24,-24,-24,-24,-24,-24,-24,-18,-14, -8, -6, -6, -6, -6, -5, -2,  0},
 633.330 +    {-26,-26,-26,-26,-26,-26,-26,-18,-16,-15,-15,-15,-15,-13,-13,-12,-10}}},
 633.331 +  /* 7 */
 633.332 +  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
 633.333 +    {-24,-24,-24,-24,-24,-24,-24,-18,-14,-10, -8, -8, -8, -8, -6, -4,  0},
 633.334 +    {-26,-26,-26,-26,-26,-26,-26,-22,-20,-19,-19,-19,-19,-18,-17,-16,-12}}},
 633.335 +  /* 8 */
 633.336 +  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  0,  0,  0,  0,  1,  2,  3,  7},
 633.337 +    {-26,-26,-26,-26,-26,-26,-26,-20,-16,-12,-10,-10,-10,-10, -8, -6, -2},
 633.338 +    {-28,-28,-28,-28,-28,-28,-28,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},
 633.339 +  /* 9 */
 633.340 +  {{{-22,-22,-22,-22,-22,-22,-22,-18,-14, -8, -4, -4, -4, -4, -4, -2,  2},
 633.341 +    {-26,-26,-26,-26,-26,-26,-26,-22,-18,-16,-16,-16,-16,-14,-12,-10, -7},
 633.342 +    {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},
 633.343 +  /* 10 */
 633.344 +  {{{-24,-24,-24,-24,-24,-24,-24,-24,-24,-18,-14,-14,-14,-14,-14,-12,-10},
 633.345 +    {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-20},
 633.346 +    {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
 633.347 +};
 633.348 +
 633.349 +/* noise bias (impulse block) */
 633.350 +static const noise3 _psy_noisebias_impulse[12]={
 633.351 +  /*  63     125     250     500      1k      2k      4k      8k     16k*/
 633.352 +  /* -1 */
 633.353 +  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  8,  8,  8,  8, 10, 12, 14, 20},
 633.354 +    {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2,  2,  2,  3,  6,  6, 15},
 633.355 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
 633.356 +
 633.357 +  /* 0 */
 633.358 +  /*  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  4,  8,  8,  8, 10, 12, 14, 20},
 633.359 +      {-30,-30,-30,-30,-26,-22,-20,-14, -6, -2,  0,  0,  0,  0,  2,  4,  10},
 633.360 +      {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},*/
 633.361 +  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  4,  8,  8,  8, 10, 12, 14, 20},
 633.362 +    {-30,-30,-30,-30,-26,-22,-20,-14, -6, -2,  0,  0,  0,  0,  2,  3,  6},
 633.363 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
 633.364 +  /* 1 */
 633.365 +  {{{-12,-12,-12,-12,-12, -8, -6, -4,  0,  4,  4,  4,  4, 10, 12, 14, 20},
 633.366 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -4, -4, -2, -2, -2, -2,  2},
 633.367 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8,-10,-10, -8, -8, -8, -6, -4}}},
 633.368 +  /* 2 */
 633.369 +  {{{-14,-14,-14,-14,-14,-10, -8, -6, -2,  2,  2,  2,  2,  8, 10, 10, 16},
 633.370 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2,  0},
 633.371 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}},
 633.372 +  /* 3 */
 633.373 +  {{{-14,-14,-14,-14,-14,-10, -8, -6, -2,  2,  2,  2,  2,  6,  8,  8, 14},
 633.374 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2,  0},
 633.375 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}},
 633.376 +  /* 4 */
 633.377 +  {{{-16,-16,-16,-16,-16,-12,-10, -6, -2,  0,  0,  0,  0,  4,  6,  6, 12},
 633.378 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2,  0},
 633.379 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}},
 633.380 +  /* 5 */
 633.381 +  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  4,  6, 11},
 633.382 +    {-32,-32,-32,-32,-28,-24,-22,-16,-10, -6, -8, -8, -6, -6, -6, -4, -2},
 633.383 +    {-34,-34,-34,-34,-30,-26,-24,-18,-14,-12,-12,-12,-12,-12,-10, -9, -5}}},
 633.384 +  /* 6
 633.385 +  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  4,  6, 11},
 633.386 +      {-34,-34,-34,-34,-30,-30,-24,-20,-12,-12,-14,-14,-10, -9, -8, -6, -4},
 633.387 +      {-34,-34,-34,-34,-34,-30,-26,-20,-16,-15,-15,-15,-15,-15,-13,-12, -8}}},*/
 633.388 +  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  4,  6, 11},
 633.389 +    {-34,-34,-34,-34,-30,-30,-30,-24,-16,-16,-16,-16,-16,-16,-14,-14,-12},
 633.390 +    {-36,-36,-36,-36,-36,-34,-28,-24,-20,-20,-20,-20,-20,-20,-20,-18,-16}}},
 633.391 +  /* 7 */
 633.392 +  /*  {{{-22,-22,-22,-22,-22,-20,-14,-10, -6,  0,  0,  0,  0,  4,  4,  6, 11},
 633.393 +      {-34,-34,-34,-34,-30,-30,-24,-20,-14,-14,-16,-16,-14,-12,-10,-10,-10},
 633.394 +      {-34,-34,-34,-34,-32,-32,-30,-24,-20,-19,-19,-19,-19,-19,-17,-16,-12}}},*/
 633.395 +  {{{-22,-22,-22,-22,-22,-20,-14,-10, -6,  0,  0,  0,  0,  4,  4,  6, 11},
 633.396 +    {-34,-34,-34,-34,-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-24,-22},
 633.397 +    {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-30,-24}}},
 633.398 +  /* 8 */
 633.399 +  /*  {{{-24,-24,-24,-24,-24,-22,-14,-10, -6, -1, -1, -1, -1,  3,  3,  5, 10},
 633.400 +      {-34,-34,-34,-34,-30,-30,-30,-24,-20,-20,-20,-20,-20,-18,-16,-16,-14},
 633.401 +      {-36,-36,-36,-36,-36,-34,-28,-24,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},*/
 633.402 +  {{{-24,-24,-24,-24,-24,-22,-14,-10, -6, -1, -1, -1, -1,  3,  3,  5, 10},
 633.403 +    {-34,-34,-34,-34,-34,-32,-32,-30,-26,-26,-26,-26,-26,-26,-26,-26,-24},
 633.404 +    {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-30,-24}}},
 633.405 +  /* 9 */
 633.406 +  /*  {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2,  2},
 633.407 +      {-36,-36,-36,-36,-34,-32,-32,-30,-26,-26,-26,-26,-26,-22,-20,-20,-18},
 633.408 +      {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},*/
 633.409 +  {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2,  2},
 633.410 +    {-36,-36,-36,-36,-34,-32,-32,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26},
 633.411 +    {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},
 633.412 +  /* 10 */
 633.413 +  {{{-30,-30,-30,-30,-30,-26,-24,-24,-24,-20,-16,-16,-16,-16,-16,-14,-12},
 633.414 +    {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-30,-30,-30,-30,-30,-30,-26},
 633.415 +    {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
 633.416 +};
 633.417 +
 633.418 +/* noise bias (padding block) */
 633.419 +static const noise3 _psy_noisebias_padding[12]={
 633.420 +  /*  63     125     250     500      1k       2k      4k      8k     16k*/
 633.421 +
 633.422 +  /* -1 */
 633.423 +  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  8,  8,  8,  8, 10, 12, 14, 20},
 633.424 +    {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2,  2,  2,  3,  6,  6, 15},
 633.425 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
 633.426 +
 633.427 +  /* 0 */
 633.428 +  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  8,  8,  8,  8, 10, 12, 14, 20},
 633.429 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2,  2,  3,  6,  6,  8, 10},
 633.430 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -4, -4, -4, -4, -2,  0,  2}}},
 633.431 +  /* 1 */
 633.432 +  {{{-12,-12,-12,-12,-12, -8, -6, -4,  0,  4,  4,  4,  4, 10, 12, 14, 20},
 633.433 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4,  0,  0,  0,  2,  2,  4,  8},
 633.434 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -6, -4, -2,  0}}},
 633.435 +  /* 2 */
 633.436 +  /*  {{{-14,-14,-14,-14,-14,-10, -8, -6, -2,  2,  2,  2,  2,  8, 10, 10, 16},
 633.437 +      {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4,  0,  0,  0,  2,  2,  4,  8},
 633.438 +      {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},*/
 633.439 +  {{{-14,-14,-14,-14,-14,-10, -8, -6, -2,  2,  2,  2,  2,  8, 10, 10, 16},
 633.440 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1,  0,  0,  2,  6},
 633.441 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},
 633.442 +  /* 3 */
 633.443 +  {{{-14,-14,-14,-14,-14,-10, -8, -6, -2,  2,  2,  2,  2,  6,  8,  8, 14},
 633.444 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1,  0,  0,  2,  6},
 633.445 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},
 633.446 +  /* 4 */
 633.447 +  {{{-16,-16,-16,-16,-16,-12,-10, -6, -2,  0,  0,  0,  0,  4,  6,  6, 12},
 633.448 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1, -1,  0,  2,  6},
 633.449 +    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},
 633.450 +  /* 5 */
 633.451 +  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  6,  6, 12},
 633.452 +    {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -3, -3, -3, -3, -2,  0,  4},
 633.453 +    {-34,-34,-34,-34,-30,-26,-24,-18,-14,-10,-10,-10,-10,-10, -8, -5, -3}}},
 633.454 +  /* 6 */
 633.455 +  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  6,  6, 12},
 633.456 +    {-34,-34,-34,-34,-30,-30,-24,-20,-14, -8, -4, -4, -4, -4, -3, -1,  4},
 633.457 +    {-34,-34,-34,-34,-34,-30,-26,-20,-16,-13,-13,-13,-13,-13,-11, -8, -6}}},
 633.458 +  /* 7 */
 633.459 +  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  6,  6, 12},
 633.460 +    {-34,-34,-34,-34,-30,-30,-30,-24,-16,-10, -8, -6, -6, -6, -5, -3,  1},
 633.461 +    {-34,-34,-34,-34,-32,-32,-28,-22,-18,-16,-16,-16,-16,-16,-14,-12,-10}}},
 633.462 +  /* 8 */
 633.463 +  {{{-22,-22,-22,-22,-22,-20,-14,-10, -4,  0,  0,  0,  0,  3,  5,  5, 11},
 633.464 +    {-34,-34,-34,-34,-30,-30,-30,-24,-16,-12,-10, -8, -8, -8, -7, -5, -2},
 633.465 +    {-36,-36,-36,-36,-36,-34,-28,-22,-20,-20,-20,-20,-20,-20,-20,-16,-14}}},
 633.466 +  /* 9 */
 633.467 +  {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -2, -2, -2, -2,  0,  2,  6},
 633.468 +    {-36,-36,-36,-36,-34,-32,-32,-24,-16,-12,-12,-12,-12,-12,-10, -8, -5},
 633.469 +    {-40,-40,-40,-40,-40,-40,-40,-32,-26,-24,-24,-24,-24,-24,-24,-20,-18}}},
 633.470 +  /* 10 */
 633.471 +  {{{-30,-30,-30,-30,-30,-26,-24,-24,-24,-20,-12,-12,-12,-12,-12,-10, -8},
 633.472 +    {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-25,-25,-25,-25,-25,-25,-15},
 633.473 +    {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
 633.474 +};
 633.475 +
 633.476 +
 633.477 +static const noiseguard _psy_noiseguards_44[4]={
 633.478 +  {3,3,15},
 633.479 +  {3,3,15},
 633.480 +  {10,10,100},
 633.481 +  {10,10,100},
 633.482 +};
 633.483 +
 633.484 +static const int _psy_tone_suppress[12]={
 633.485 +  -20,-20,-20,-20,-20,-24,-30,-40,-40,-45,-45,-45,
 633.486 +};
 633.487 +static const int _psy_tone_0dB[12]={
 633.488 +  90,90,95,95,95,95,105,105,105,105,105,105,
 633.489 +};
 633.490 +static const int _psy_noise_suppress[12]={
 633.491 +  -20,-20,-24,-24,-24,-24,-30,-40,-40,-45,-45,-45,
 633.492 +};
 633.493 +
 633.494 +static const vorbis_info_psy _psy_info_template={
 633.495 +  /* blockflag */
 633.496 +  -1,
 633.497 +  /* ath_adjatt, ath_maxatt */
 633.498 +  -140.,-140.,
 633.499 +  /* tonemask att boost/decay,suppr,curves */
 633.500 +  {0.f,0.f,0.f},     0.,0.,    -40.f, {0.},
 633.501 +
 633.502 +  /*noisemaskp,supp, low/high window, low/hi guard, minimum */
 633.503 +  1,          -0.f,           .5f, .5f,         0,0,0,
 633.504 +  /* noiseoffset*3, noisecompand, max_curve_dB */
 633.505 +  {{-1},{-1},{-1}},{-1},105.f,
 633.506 +  /* noise normalization - noise_p, start, partition, thresh. */
 633.507 +  0,-1,-1,0.,
 633.508 +};
 633.509 +
 633.510 +/* ath ****************/
 633.511 +
 633.512 +static const int _psy_ath_floater[12]={
 633.513 +  -100,-100,-100,-100,-100,-100,-105,-105,-105,-105,-110,-120,
 633.514 +};
 633.515 +static const int _psy_ath_abs[12]={
 633.516 +  -130,-130,-130,-130,-140,-140,-140,-140,-140,-140,-140,-150,
 633.517 +};
 633.518 +
 633.519 +/* stereo setup.  These don't map directly to quality level, there's
 633.520 +   an additional indirection as several of the below may be used in a
 633.521 +   single bitmanaged stream
 633.522 +
 633.523 +****************/
 633.524 +
 633.525 +/* various stereo possibilities */
 633.526 +
 633.527 +/* stereo mode by base quality level */
 633.528 +static const adj_stereo _psy_stereo_modes_44[12]={
 633.529 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         -1  */
 633.530 +  {{  4,  4,  4,  4,  4,  4,  4,  3,  2,  2,  1,  0,  0,  0,  0},
 633.531 +   {  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  5,  4,  3},
 633.532 +   {  1,  2,  3,  4,  4,  4,  4,  4,  4,  5,  6,  7,  8,  8,  8},
 633.533 +   { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.534 +
 633.535 +/*    0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         0  */
 633.536 +  {{  4,  4,  4,  4,  4,  4,  4,  3,  2,  1,  0,  0,  0,  0,  0},
 633.537 +   {  8,  8,  8,  8,  6,  6,  5,  5,  5,  5,  5,  5,  5,  4,  3},
 633.538 +   {  1,  2,  3,  4,  4,  5,  6,  6,  6,  6,  6,  8,  8,  8,  8},
 633.539 +   { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.540 +
 633.541 +
 633.542 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         1  */
 633.543 +  {{  3,  3,  3,  3,  3,  3,  3,  3,  2,  1,  0,  0,  0,  0,  0},
 633.544 +   {  8,  8,  8,  8,  6,  6,  5,  5,  5,  5,  5,  5,  5,  4,  3},
 633.545 +   {  1,  2,  3,  4,  4,  5,  6,  6,  6,  6,  6,  8,  8,  8,  8},
 633.546 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.547 +
 633.548 +
 633.549 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         2  */
 633.550 +  {{  3,  3,  3,  3,  3,  3,  3,  2,  1,  1,  0,  0,  0,  0,  0},
 633.551 +   {  8,  8,  6,  6,  5,  5,  4,  4,  4,  4,  4,  4,  3,  2,  1},
 633.552 +   {  3,  4,  4,  5,  5,  6,  6,  6,  6,  6,  6,  8,  8,  8,  8},
 633.553 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.554 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         3  */
 633.555 +  {{  2,  2,  2,  2,  2,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0},
 633.556 +   {  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  3,  2,  1},
 633.557 +   {  4,  4,  5,  6,  6,  6,  6,  6,  8,  8, 10, 10, 10, 10, 10},
 633.558 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.559 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         4  */
 633.560 +  {{  2,  2,  2,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.561 +   {  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  3,  3,  2,  1,  0},
 633.562 +   {  6,  6,  6,  8,  8,  8,  8,  8,  8,  8, 10, 10, 10, 10, 10},
 633.563 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.564 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         5  */
 633.565 +  {{  2,  2,  2,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.566 +   {  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0},
 633.567 +   {  6,  7,  8,  8,  8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12},
 633.568 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.569 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         6  */
 633.570 +  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.571 +   {  3,  3,  3,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.572 +   {  8,  8,  8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
 633.573 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.574 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         7  */
 633.575 +  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.576 +   {  3,  3,  3,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.577 +   {  8,  8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
 633.578 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.579 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         8  */
 633.580 +  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.581 +   {  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.582 +   {  8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
 633.583 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.584 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         9  */
 633.585 +  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.586 +   {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.587 +   {  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
 633.588 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.589 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14        10  */
 633.590 +  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.591 +   {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
 633.592 +   {  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
 633.593 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
 633.594 +};
 633.595 +
 633.596 +/* tone master attenuation by base quality mode and bitrate tweak */
 633.597 +static const att3 _psy_tone_masteratt_44[12]={
 633.598 +  {{ 35,  21,   9},  0,    0}, /* -1 */
 633.599 +  {{ 30,  20,   8}, -2, 1.25}, /* 0 */
 633.600 +  /*  {{ 25,  14,   4},  0,    0}, *//* 1 */
 633.601 +  {{ 25,  12,   2},  0,    0}, /* 1 */
 633.602 +  /*  {{ 20,  10,  -2},  0,    0}, *//* 2 */
 633.603 +  {{ 20,   9,  -3},  0,    0}, /* 2 */
 633.604 +  {{ 20,   9,  -4},  0,    0}, /* 3 */
 633.605 +  {{ 20,   9,  -4},  0,    0}, /* 4 */
 633.606 +  {{ 20,   6,  -6},  0,    0}, /* 5 */
 633.607 +  {{ 20,   3, -10},  0,    0}, /* 6 */
 633.608 +  {{ 18,   1, -14},  0,    0}, /* 7 */
 633.609 +  {{ 18,   0, -16},  0,    0}, /* 8 */
 633.610 +  {{ 18,  -2, -16},  0,    0}, /* 9 */
 633.611 +  {{ 12,  -2, -20},  0,    0}, /* 10 */
 633.612 +};
 633.613 +
 633.614 +/* lowpass by mode **************/
 633.615 +static const double _psy_lowpass_44[12]={
 633.616 +  /*  15.1,15.8,16.5,17.9,20.5,48.,999.,999.,999.,999.,999. */
 633.617 +  13.9,15.1,15.8,16.5,17.2,18.9,20.1,48.,999.,999.,999.,999.
 633.618 +};
 633.619 +
 633.620 +/* noise normalization **********/
 633.621 +
 633.622 +static const int _noise_start_short_44[11]={
 633.623 +  /*  16,16,16,16,32,32,9999,9999,9999,9999 */
 633.624 +  32,16,16,16,32,9999,9999,9999,9999,9999,9999
 633.625 +};
 633.626 +static const int _noise_start_long_44[11]={
 633.627 +  /*  128,128,128,256,512,512,9999,9999,9999,9999 */
 633.628 +  256,128,128,256,512,9999,9999,9999,9999,9999,9999
 633.629 +};
 633.630 +
 633.631 +static const int _noise_part_short_44[11]={
 633.632 +    8,8,8,8,8,8,8,8,8,8,8
 633.633 +};
 633.634 +static const int _noise_part_long_44[11]={
 633.635 +    32,32,32,32,32,32,32,32,32,32,32
 633.636 +};
 633.637 +
 633.638 +static const double _noise_thresh_44[11]={
 633.639 +  /*  .2,.2,.3,.4,.5,.5,9999.,9999.,9999.,9999., */
 633.640 +   .2,.2,.2,.4,.6,9999.,9999.,9999.,9999.,9999.,9999.,
 633.641 +};
 633.642 +
 633.643 +static const double _noise_thresh_5only[2]={
 633.644 + .5,.5,
 633.645 +};
   634.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   634.2 +++ b/libs/vorbis/modes/psych_8.h	Sat Feb 01 19:58:19 2014 +0200
   634.3 @@ -0,0 +1,101 @@
   634.4 +/********************************************************************
   634.5 + *                                                                  *
   634.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   634.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   634.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   634.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  634.10 + *                                                                  *
  634.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  634.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  634.13 + *                                                                  *
  634.14 + ********************************************************************
  634.15 +
  634.16 + function: 8kHz psychoacoustic settings
  634.17 + last mod: $Id: psych_8.h 16227 2009-07-08 06:58:46Z xiphmont $
  634.18 +
  634.19 + ********************************************************************/
  634.20 +
  634.21 +static const att3 _psy_tone_masteratt_8[3]={
  634.22 +  {{ 32,  25,  12},  0,   0},  /* 0 */
  634.23 +  {{ 30,  25,  12},  0,   0},  /* 0 */
  634.24 +  {{ 20,   0, -14},  0,   0}, /* 0 */
  634.25 +};
  634.26 +
  634.27 +static const vp_adjblock _vp_tonemask_adj_8[3]={
  634.28 +  /* adjust for mode zero */
  634.29 +  /* 63     125     250     500     1     2     4     8    16 */
  634.30 +  {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0,10, 0, 0,99,99,99}}, /* 1 */
  634.31 +  {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0,10, 0, 0,99,99,99}}, /* 1 */
  634.32 +  {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0, 0, 0, 0,99,99,99}}, /* 1 */
  634.33 +};
  634.34 +
  634.35 +
  634.36 +static const noise3 _psy_noisebias_8[3]={
  634.37 +  /*  63     125     250     500      1k       2k      4k      8k     16k*/
  634.38 +  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4,  8,  8,  8, 10, 10, 99, 99, 99},
  634.39 +    {-10,-10,-10,-10, -5, -5, -5,  0,  0,  4,  4,  4,  4,  4, 99, 99, 99},
  634.40 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
  634.41 +
  634.42 +  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4,  8,  8,  8, 10, 10, 99, 99, 99},
  634.43 +    {-10,-10,-10,-10,-10,-10, -5, -5, -5,  0,  0,  0,  0,  0, 99, 99, 99},
  634.44 +    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
  634.45 +
  634.46 +  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5, 99, 99, 99},
  634.47 +    {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10, 99, 99, 99},
  634.48 +    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24, 99, 99, 99}}},
  634.49 +};
  634.50 +
  634.51 +/* stereo mode by base quality level */
  634.52 +static const adj_stereo _psy_stereo_modes_8[3]={
  634.53 +  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  */
  634.54 +  {{  4,  4,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
  634.55 +   {  6,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
  634.56 +   {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1},
  634.57 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
  634.58 +  {{  4,  4,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
  634.59 +   {  6,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
  634.60 +   {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1},
  634.61 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
  634.62 +  {{  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
  634.63 +   {  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
  634.64 +   {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1},
  634.65 +   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
  634.66 +};
  634.67 +
  634.68 +static const noiseguard _psy_noiseguards_8[2]={
  634.69 +  {10,10,-1},
  634.70 +  {10,10,-1},
  634.71 +};
  634.72 +
  634.73 +static const compandblock _psy_compand_8[2]={
  634.74 +  {{
  634.75 +     0, 1, 2, 3, 4, 5, 6,  7,     /* 7dB */
  634.76 +     8, 8, 9, 9,10,10,11, 11,     /* 15dB */
  634.77 +    12,12,13,13,14,14,15, 15,     /* 23dB */
  634.78 +    16,16,17,17,17,18,18, 19,     /* 31dB */
  634.79 +    19,19,20,21,22,23,24, 25,     /* 39dB */
  634.80 +  }},
  634.81 +  {{
  634.82 +     0, 1, 2, 3, 4, 5, 6,  6,     /* 7dB */
  634.83 +     7, 7, 6, 6, 5, 5, 4,  4,     /* 15dB */
  634.84 +     3, 3, 3, 4, 5, 6, 7,  8,     /* 23dB */
  634.85 +     9,10,11,12,13,14,15, 16,     /* 31dB */
  634.86 +    17,18,19,20,21,22,23, 24,     /* 39dB */
  634.87 +  }},
  634.88 +};
  634.89 +
  634.90 +static const double _psy_lowpass_8[3]={3.,4.,4.};
  634.91 +static const int _noise_start_8[2]={
  634.92 +  64,64,
  634.93 +};
  634.94 +static const int _noise_part_8[2]={
  634.95 +  8,8,
  634.96 +};
  634.97 +
  634.98 +static const int _psy_ath_floater_8[3]={
  634.99 +  -100,-100,-105,
 634.100 +};
 634.101 +
 634.102 +static const int _psy_ath_abs_8[3]={
 634.103 +  -130,-130,-140,
 634.104 +};
   635.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   635.2 +++ b/libs/vorbis/modes/residue_16.h	Sat Feb 01 19:58:19 2014 +0200
   635.3 @@ -0,0 +1,163 @@
   635.4 +/********************************************************************
   635.5 + *                                                                  *
   635.6 + * This FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   635.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   635.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   635.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  635.10 + *                                                                  *
  635.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  635.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  635.13 + *                                                                  *
  635.14 + ********************************************************************
  635.15 +
  635.16 + function: toplevel residue templates 16/22kHz
  635.17 + last mod: $Id: residue_16.h 16962 2010-03-11 07:30:34Z xiphmont $
  635.18 +
  635.19 + ********************************************************************/
  635.20 +
  635.21 +/***** residue backends *********************************************/
  635.22 +
  635.23 +static const static_bookblock _resbook_16s_0={
  635.24 +  {
  635.25 +    {0},
  635.26 +    {0,0,&_16c0_s_p1_0},
  635.27 +    {0},
  635.28 +    {0,0,&_16c0_s_p3_0},
  635.29 +    {0,0,&_16c0_s_p4_0},
  635.30 +    {0,0,&_16c0_s_p5_0},
  635.31 +    {0,0,&_16c0_s_p6_0},
  635.32 +    {&_16c0_s_p7_0,&_16c0_s_p7_1},
  635.33 +    {&_16c0_s_p8_0,&_16c0_s_p8_1},
  635.34 +    {&_16c0_s_p9_0,&_16c0_s_p9_1,&_16c0_s_p9_2}
  635.35 +   }
  635.36 +};
  635.37 +static const static_bookblock _resbook_16s_1={
  635.38 +  {
  635.39 +    {0},
  635.40 +    {0,0,&_16c1_s_p1_0},
  635.41 +    {0},
  635.42 +    {0,0,&_16c1_s_p3_0},
  635.43 +    {0,0,&_16c1_s_p4_0},
  635.44 +    {0,0,&_16c1_s_p5_0},
  635.45 +    {0,0,&_16c1_s_p6_0},
  635.46 +    {&_16c1_s_p7_0,&_16c1_s_p7_1},
  635.47 +    {&_16c1_s_p8_0,&_16c1_s_p8_1},
  635.48 +    {&_16c1_s_p9_0,&_16c1_s_p9_1,&_16c1_s_p9_2}
  635.49 +   }
  635.50 +};
  635.51 +static const static_bookblock _resbook_16s_2={
  635.52 +  {
  635.53 +    {0},
  635.54 +    {0,0,&_16c2_s_p1_0},
  635.55 +    {0,0,&_16c2_s_p2_0},
  635.56 +    {0,0,&_16c2_s_p3_0},
  635.57 +    {0,0,&_16c2_s_p4_0},
  635.58 +    {&_16c2_s_p5_0,&_16c2_s_p5_1},
  635.59 +    {&_16c2_s_p6_0,&_16c2_s_p6_1},
  635.60 +    {&_16c2_s_p7_0,&_16c2_s_p7_1},
  635.61 +    {&_16c2_s_p8_0,&_16c2_s_p8_1},
  635.62 +    {&_16c2_s_p9_0,&_16c2_s_p9_1,&_16c2_s_p9_2}
  635.63 +   }
  635.64 +};
  635.65 +
  635.66 +static const vorbis_residue_template _res_16s_0[]={
  635.67 +  {2,0,32,  &_residue_44_mid,
  635.68 +   &_huff_book__16c0_s_single,&_huff_book__16c0_s_single,
  635.69 +   &_resbook_16s_0,&_resbook_16s_0},
  635.70 +};
  635.71 +static const vorbis_residue_template _res_16s_1[]={
  635.72 +  {2,0,32,  &_residue_44_mid,
  635.73 +   &_huff_book__16c1_s_short,&_huff_book__16c1_s_short,
  635.74 +   &_resbook_16s_1,&_resbook_16s_1},
  635.75 +
  635.76 +  {2,0,32,  &_residue_44_mid,
  635.77 +   &_huff_book__16c1_s_long,&_huff_book__16c1_s_long,
  635.78 +   &_resbook_16s_1,&_resbook_16s_1}
  635.79 +};
  635.80 +static const vorbis_residue_template _res_16s_2[]={
  635.81 +  {2,0,32,  &_residue_44_high,
  635.82 +   &_huff_book__16c2_s_short,&_huff_book__16c2_s_short,
  635.83 +   &_resbook_16s_2,&_resbook_16s_2},
  635.84 +
  635.85 +  {2,0,32,  &_residue_44_high,
  635.86 +   &_huff_book__16c2_s_long,&_huff_book__16c2_s_long,
  635.87 +   &_resbook_16s_2,&_resbook_16s_2}
  635.88 +};
  635.89 +
  635.90 +static const vorbis_mapping_template _mapres_template_16_stereo[3]={
  635.91 +  { _map_nominal, _res_16s_0 }, /* 0 */
  635.92 +  { _map_nominal, _res_16s_1 }, /* 1 */
  635.93 +  { _map_nominal, _res_16s_2 }, /* 2 */
  635.94 +};
  635.95 +
  635.96 +static const static_bookblock _resbook_16u_0={
  635.97 +  {
  635.98 +    {0},
  635.99 +    {0,0,&_16u0__p1_0},
 635.100 +    {0,0,&_16u0__p2_0},
 635.101 +    {0,0,&_16u0__p3_0},
 635.102 +    {0,0,&_16u0__p4_0},
 635.103 +    {0,0,&_16u0__p5_0},
 635.104 +    {&_16u0__p6_0,&_16u0__p6_1},
 635.105 +    {&_16u0__p7_0,&_16u0__p7_1,&_16u0__p7_2}
 635.106 +   }
 635.107 +};
 635.108 +static const static_bookblock _resbook_16u_1={
 635.109 +  {
 635.110 +    {0},
 635.111 +    {0,0,&_16u1__p1_0},
 635.112 +    {0,0,&_16u1__p2_0},
 635.113 +    {0,0,&_16u1__p3_0},
 635.114 +    {0,0,&_16u1__p4_0},
 635.115 +    {0,0,&_16u1__p5_0},
 635.116 +    {0,0,&_16u1__p6_0},
 635.117 +    {&_16u1__p7_0,&_16u1__p7_1},
 635.118 +    {&_16u1__p8_0,&_16u1__p8_1},
 635.119 +    {&_16u1__p9_0,&_16u1__p9_1,&_16u1__p9_2}
 635.120 +   }
 635.121 +};
 635.122 +static const static_bookblock _resbook_16u_2={
 635.123 +  {
 635.124 +    {0},
 635.125 +    {0,0,&_16u2_p1_0},
 635.126 +    {0,0,&_16u2_p2_0},
 635.127 +    {0,0,&_16u2_p3_0},
 635.128 +    {0,0,&_16u2_p4_0},
 635.129 +    {&_16u2_p5_0,&_16u2_p5_1},
 635.130 +    {&_16u2_p6_0,&_16u2_p6_1},
 635.131 +    {&_16u2_p7_0,&_16u2_p7_1},
 635.132 +    {&_16u2_p8_0,&_16u2_p8_1},
 635.133 +    {&_16u2_p9_0,&_16u2_p9_1,&_16u2_p9_2}
 635.134 +   }
 635.135 +};
 635.136 +
 635.137 +static const vorbis_residue_template _res_16u_0[]={
 635.138 +  {1,0,32,  &_residue_44_low_un,
 635.139 +   &_huff_book__16u0__single,&_huff_book__16u0__single,
 635.140 +   &_resbook_16u_0,&_resbook_16u_0},
 635.141 +};
 635.142 +static const vorbis_residue_template _res_16u_1[]={
 635.143 +  {1,0,32,  &_residue_44_mid_un,
 635.144 +   &_huff_book__16u1__short,&_huff_book__16u1__short,
 635.145 +   &_resbook_16u_1,&_resbook_16u_1},
 635.146 +
 635.147 +  {1,0,32,  &_residue_44_mid_un,
 635.148 +   &_huff_book__16u1__long,&_huff_book__16u1__long,
 635.149 +   &_resbook_16u_1,&_resbook_16u_1}
 635.150 +};
 635.151 +static const vorbis_residue_template _res_16u_2[]={
 635.152 +  {1,0,32,  &_residue_44_hi_un,
 635.153 +   &_huff_book__16u2__short,&_huff_book__16u2__short,
 635.154 +   &_resbook_16u_2,&_resbook_16u_2},
 635.155 +
 635.156 +  {1,0,32,  &_residue_44_hi_un,
 635.157 +   &_huff_book__16u2__long,&_huff_book__16u2__long,
 635.158 +   &_resbook_16u_2,&_resbook_16u_2}
 635.159 +};
 635.160 +
 635.161 +
 635.162 +static const vorbis_mapping_template _mapres_template_16_uncoupled[3]={
 635.163 +  { _map_nominal_u, _res_16u_0 }, /* 0 */
 635.164 +  { _map_nominal_u, _res_16u_1 }, /* 1 */
 635.165 +  { _map_nominal_u, _res_16u_2 }, /* 2 */
 635.166 +};
   636.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   636.2 +++ b/libs/vorbis/modes/residue_44.h	Sat Feb 01 19:58:19 2014 +0200
   636.3 @@ -0,0 +1,292 @@
   636.4 +/********************************************************************
   636.5 + *                                                                  *
   636.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   636.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   636.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   636.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  636.10 + *                                                                  *
  636.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  636.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  636.13 + *                                                                  *
  636.14 + ********************************************************************
  636.15 +
  636.16 + function: toplevel residue templates for 32/44.1/48kHz
  636.17 + last mod: $Id: residue_44.h 16962 2010-03-11 07:30:34Z xiphmont $
  636.18 +
  636.19 + ********************************************************************/
  636.20 +
  636.21 +#include "vorbis/codec.h"
  636.22 +#include "backends.h"
  636.23 +#include "books/coupled/res_books_stereo.h"
  636.24 +
  636.25 +/***** residue backends *********************************************/
  636.26 +
  636.27 +static const vorbis_info_residue0 _residue_44_low={
  636.28 +  0,-1, -1, 9,-1,-1,
  636.29 +  /* 0   1   2   3   4   5   6   7  */
  636.30 +  {0},
  636.31 +  {-1},
  636.32 +  {  0,  1,  2,  2,  4,  8, 16, 32},
  636.33 +  {  0,  0,  0,999,  4,  8, 16, 32},
  636.34 +};
  636.35 +
  636.36 +static const vorbis_info_residue0 _residue_44_mid={
  636.37 +  0,-1, -1, 10,-1,-1,
  636.38 +  /* 0   1   2   3   4   5   6   7   8  */
  636.39 +  {0},
  636.40 +  {-1},
  636.41 +  {  0,  1,  1,  2,  2,  4,  8, 16, 32},
  636.42 +  {  0,  0,999,  0,999,  4,  8, 16, 32},
  636.43 +};
  636.44 +
  636.45 +static const vorbis_info_residue0 _residue_44_high={
  636.46 +  0,-1, -1, 10,-1,-1,
  636.47 +  /* 0   1   2   3   4   5   6   7   8  */
  636.48 +  {0},
  636.49 +  {-1},
  636.50 +  {  0,  1,  2,  4,  8, 16, 32, 71,157},
  636.51 +  {  0,  1,  2,  3,  4,  8, 16, 71,157},
  636.52 +};
  636.53 +
  636.54 +static const static_bookblock _resbook_44s_n1={
  636.55 +  {
  636.56 +    {0},{0,0,&_44cn1_s_p1_0},{0,0,&_44cn1_s_p2_0},
  636.57 +    {0,0,&_44cn1_s_p3_0},{0,0,&_44cn1_s_p4_0},{0,0,&_44cn1_s_p5_0},
  636.58 +    {&_44cn1_s_p6_0,&_44cn1_s_p6_1},{&_44cn1_s_p7_0,&_44cn1_s_p7_1},
  636.59 +    {&_44cn1_s_p8_0,&_44cn1_s_p8_1,&_44cn1_s_p8_2}
  636.60 +   }
  636.61 +};
  636.62 +static const static_bookblock _resbook_44sm_n1={
  636.63 +  {
  636.64 +    {0},{0,0,&_44cn1_sm_p1_0},{0,0,&_44cn1_sm_p2_0},
  636.65 +    {0,0,&_44cn1_sm_p3_0},{0,0,&_44cn1_sm_p4_0},{0,0,&_44cn1_sm_p5_0},
  636.66 +    {&_44cn1_sm_p6_0,&_44cn1_sm_p6_1},{&_44cn1_sm_p7_0,&_44cn1_sm_p7_1},
  636.67 +    {&_44cn1_sm_p8_0,&_44cn1_sm_p8_1,&_44cn1_sm_p8_2}
  636.68 +   }
  636.69 +};
  636.70 +
  636.71 +static const static_bookblock _resbook_44s_0={
  636.72 +  {
  636.73 +    {0},{0,0,&_44c0_s_p1_0},{0,0,&_44c0_s_p2_0},
  636.74 +    {0,0,&_44c0_s_p3_0},{0,0,&_44c0_s_p4_0},{0,0,&_44c0_s_p5_0},
  636.75 +    {&_44c0_s_p6_0,&_44c0_s_p6_1},{&_44c0_s_p7_0,&_44c0_s_p7_1},
  636.76 +    {&_44c0_s_p8_0,&_44c0_s_p8_1,&_44c0_s_p8_2}
  636.77 +   }
  636.78 +};
  636.79 +static const static_bookblock _resbook_44sm_0={
  636.80 +  {
  636.81 +    {0},{0,0,&_44c0_sm_p1_0},{0,0,&_44c0_sm_p2_0},
  636.82 +    {0,0,&_44c0_sm_p3_0},{0,0,&_44c0_sm_p4_0},{0,0,&_44c0_sm_p5_0},
  636.83 +    {&_44c0_sm_p6_0,&_44c0_sm_p6_1},{&_44c0_sm_p7_0,&_44c0_sm_p7_1},
  636.84 +    {&_44c0_sm_p8_0,&_44c0_sm_p8_1,&_44c0_sm_p8_2}
  636.85 +   }
  636.86 +};
  636.87 +
  636.88 +static const static_bookblock _resbook_44s_1={
  636.89 +  {
  636.90 +    {0},{0,0,&_44c1_s_p1_0},{0,0,&_44c1_s_p2_0},
  636.91 +    {0,0,&_44c1_s_p3_0},{0,0,&_44c1_s_p4_0},{0,0,&_44c1_s_p5_0},
  636.92 +    {&_44c1_s_p6_0,&_44c1_s_p6_1},{&_44c1_s_p7_0,&_44c1_s_p7_1},
  636.93 +    {&_44c1_s_p8_0,&_44c1_s_p8_1,&_44c1_s_p8_2}
  636.94 +   }
  636.95 +};
  636.96 +static const static_bookblock _resbook_44sm_1={
  636.97 +  {
  636.98 +    {0},{0,0,&_44c1_sm_p1_0},{0,0,&_44c1_sm_p2_0},
  636.99 +    {0,0,&_44c1_sm_p3_0},{0,0,&_44c1_sm_p4_0},{0,0,&_44c1_sm_p5_0},
 636.100 +    {&_44c1_sm_p6_0,&_44c1_sm_p6_1},{&_44c1_sm_p7_0,&_44c1_sm_p7_1},
 636.101 +    {&_44c1_sm_p8_0,&_44c1_sm_p8_1,&_44c1_sm_p8_2}
 636.102 +   }
 636.103 +};
 636.104 +
 636.105 +static const static_bookblock _resbook_44s_2={
 636.106 +  {
 636.107 +    {0},{0,0,&_44c2_s_p1_0},{0,0,&_44c2_s_p2_0},{0,0,&_44c2_s_p3_0},
 636.108 +    {0,0,&_44c2_s_p4_0},{0,0,&_44c2_s_p5_0},{0,0,&_44c2_s_p6_0},
 636.109 +    {&_44c2_s_p7_0,&_44c2_s_p7_1},{&_44c2_s_p8_0,&_44c2_s_p8_1},
 636.110 +    {&_44c2_s_p9_0,&_44c2_s_p9_1,&_44c2_s_p9_2}
 636.111 +   }
 636.112 +};
 636.113 +static const static_bookblock _resbook_44s_3={
 636.114 +  {
 636.115 +    {0},{0,0,&_44c3_s_p1_0},{0,0,&_44c3_s_p2_0},{0,0,&_44c3_s_p3_0},
 636.116 +    {0,0,&_44c3_s_p4_0},{0,0,&_44c3_s_p5_0},{0,0,&_44c3_s_p6_0},
 636.117 +    {&_44c3_s_p7_0,&_44c3_s_p7_1},{&_44c3_s_p8_0,&_44c3_s_p8_1},
 636.118 +    {&_44c3_s_p9_0,&_44c3_s_p9_1,&_44c3_s_p9_2}
 636.119 +   }
 636.120 +};
 636.121 +static const static_bookblock _resbook_44s_4={
 636.122 +  {
 636.123 +    {0},{0,0,&_44c4_s_p1_0},{0,0,&_44c4_s_p2_0},{0,0,&_44c4_s_p3_0},
 636.124 +    {0,0,&_44c4_s_p4_0},{0,0,&_44c4_s_p5_0},{0,0,&_44c4_s_p6_0},
 636.125 +    {&_44c4_s_p7_0,&_44c4_s_p7_1},{&_44c4_s_p8_0,&_44c4_s_p8_1},
 636.126 +    {&_44c4_s_p9_0,&_44c4_s_p9_1,&_44c4_s_p9_2}
 636.127 +   }
 636.128 +};
 636.129 +static const static_bookblock _resbook_44s_5={
 636.130 +  {
 636.131 +    {0},{0,0,&_44c5_s_p1_0},{0,0,&_44c5_s_p2_0},{0,0,&_44c5_s_p3_0},
 636.132 +    {0,0,&_44c5_s_p4_0},{0,0,&_44c5_s_p5_0},{0,0,&_44c5_s_p6_0},
 636.133 +    {&_44c5_s_p7_0,&_44c5_s_p7_1},{&_44c5_s_p8_0,&_44c5_s_p8_1},
 636.134 +    {&_44c5_s_p9_0,&_44c5_s_p9_1,&_44c5_s_p9_2}
 636.135 +   }
 636.136 +};
 636.137 +static const static_bookblock _resbook_44s_6={
 636.138 +  {
 636.139 +    {0},{0,0,&_44c6_s_p1_0},{0,0,&_44c6_s_p2_0},{0,0,&_44c6_s_p3_0},
 636.140 +    {0,0,&_44c6_s_p4_0},
 636.141 +    {&_44c6_s_p5_0,&_44c6_s_p5_1},
 636.142 +    {&_44c6_s_p6_0,&_44c6_s_p6_1},
 636.143 +    {&_44c6_s_p7_0,&_44c6_s_p7_1},
 636.144 +    {&_44c6_s_p8_0,&_44c6_s_p8_1},
 636.145 +    {&_44c6_s_p9_0,&_44c6_s_p9_1,&_44c6_s_p9_2}
 636.146 +   }
 636.147 +};
 636.148 +static const static_bookblock _resbook_44s_7={
 636.149 +  {
 636.150 +    {0},{0,0,&_44c7_s_p1_0},{0,0,&_44c7_s_p2_0},{0,0,&_44c7_s_p3_0},
 636.151 +    {0,0,&_44c7_s_p4_0},
 636.152 +    {&_44c7_s_p5_0,&_44c7_s_p5_1},
 636.153 +    {&_44c7_s_p6_0,&_44c7_s_p6_1},
 636.154 +    {&_44c7_s_p7_0,&_44c7_s_p7_1},
 636.155 +    {&_44c7_s_p8_0,&_44c7_s_p8_1},
 636.156 +    {&_44c7_s_p9_0,&_44c7_s_p9_1,&_44c7_s_p9_2}
 636.157 +   }
 636.158 +};
 636.159 +static const static_bookblock _resbook_44s_8={
 636.160 +  {
 636.161 +    {0},{0,0,&_44c8_s_p1_0},{0,0,&_44c8_s_p2_0},{0,0,&_44c8_s_p3_0},
 636.162 +    {0,0,&_44c8_s_p4_0},
 636.163 +    {&_44c8_s_p5_0,&_44c8_s_p5_1},
 636.164 +    {&_44c8_s_p6_0,&_44c8_s_p6_1},
 636.165 +    {&_44c8_s_p7_0,&_44c8_s_p7_1},
 636.166 +    {&_44c8_s_p8_0,&_44c8_s_p8_1},
 636.167 +    {&_44c8_s_p9_0,&_44c8_s_p9_1,&_44c8_s_p9_2}
 636.168 +   }
 636.169 +};
 636.170 +static const static_bookblock _resbook_44s_9={
 636.171 +  {
 636.172 +    {0},{0,0,&_44c9_s_p1_0},{0,0,&_44c9_s_p2_0},{0,0,&_44c9_s_p3_0},
 636.173 +    {0,0,&_44c9_s_p4_0},
 636.174 +    {&_44c9_s_p5_0,&_44c9_s_p5_1},
 636.175 +    {&_44c9_s_p6_0,&_44c9_s_p6_1},
 636.176 +    {&_44c9_s_p7_0,&_44c9_s_p7_1},
 636.177 +    {&_44c9_s_p8_0,&_44c9_s_p8_1},
 636.178 +    {&_44c9_s_p9_0,&_44c9_s_p9_1,&_44c9_s_p9_2}
 636.179 +   }
 636.180 +};
 636.181 +
 636.182 +static const vorbis_residue_template _res_44s_n1[]={
 636.183 +  {2,0,32,  &_residue_44_low,
 636.184 +   &_huff_book__44cn1_s_short,&_huff_book__44cn1_sm_short,
 636.185 +   &_resbook_44s_n1,&_resbook_44sm_n1},
 636.186 +
 636.187 +  {2,0,32,  &_residue_44_low,
 636.188 +   &_huff_book__44cn1_s_long,&_huff_book__44cn1_sm_long,
 636.189 +   &_resbook_44s_n1,&_resbook_44sm_n1}
 636.190 +};
 636.191 +static const vorbis_residue_template _res_44s_0[]={
 636.192 +  {2,0,16,  &_residue_44_low,
 636.193 +   &_huff_book__44c0_s_short,&_huff_book__44c0_sm_short,
 636.194 +   &_resbook_44s_0,&_resbook_44sm_0},
 636.195 +
 636.196 +  {2,0,32,  &_residue_44_low,
 636.197 +   &_huff_book__44c0_s_long,&_huff_book__44c0_sm_long,
 636.198 +   &_resbook_44s_0,&_resbook_44sm_0}
 636.199 +};
 636.200 +static const vorbis_residue_template _res_44s_1[]={
 636.201 +  {2,0,16,  &_residue_44_low,
 636.202 +   &_huff_book__44c1_s_short,&_huff_book__44c1_sm_short,
 636.203 +   &_resbook_44s_1,&_resbook_44sm_1},
 636.204 +
 636.205 +  {2,0,32,  &_residue_44_low,
 636.206 +   &_huff_book__44c1_s_long,&_huff_book__44c1_sm_long,
 636.207 +   &_resbook_44s_1,&_resbook_44sm_1}
 636.208 +};
 636.209 +
 636.210 +static const vorbis_residue_template _res_44s_2[]={
 636.211 +  {2,0,16,  &_residue_44_mid,
 636.212 +   &_huff_book__44c2_s_short,&_huff_book__44c2_s_short,
 636.213 +   &_resbook_44s_2,&_resbook_44s_2},
 636.214 +
 636.215 +  {2,0,32,  &_residue_44_mid,
 636.216 +   &_huff_book__44c2_s_long,&_huff_book__44c2_s_long,
 636.217 +   &_resbook_44s_2,&_resbook_44s_2}
 636.218 +};
 636.219 +static const vorbis_residue_template _res_44s_3[]={
 636.220 +  {2,0,16,  &_residue_44_mid,
 636.221 +   &_huff_book__44c3_s_short,&_huff_book__44c3_s_short,
 636.222 +   &_resbook_44s_3,&_resbook_44s_3},
 636.223 +
 636.224 +  {2,0,32,  &_residue_44_mid,
 636.225 +   &_huff_book__44c3_s_long,&_huff_book__44c3_s_long,
 636.226 +   &_resbook_44s_3,&_resbook_44s_3}
 636.227 +};
 636.228 +static const vorbis_residue_template _res_44s_4[]={
 636.229 +  {2,0,16,  &_residue_44_mid,
 636.230 +   &_huff_book__44c4_s_short,&_huff_book__44c4_s_short,
 636.231 +   &_resbook_44s_4,&_resbook_44s_4},
 636.232 +
 636.233 +  {2,0,32,  &_residue_44_mid,
 636.234 +   &_huff_book__44c4_s_long,&_huff_book__44c4_s_long,
 636.235 +   &_resbook_44s_4,&_resbook_44s_4}
 636.236 +};
 636.237 +static const vorbis_residue_template _res_44s_5[]={
 636.238 +  {2,0,16,  &_residue_44_mid,
 636.239 +   &_huff_book__44c5_s_short,&_huff_book__44c5_s_short,
 636.240 +   &_resbook_44s_5,&_resbook_44s_5},
 636.241 +
 636.242 +  {2,0,32,  &_residue_44_mid,
 636.243 +   &_huff_book__44c5_s_long,&_huff_book__44c5_s_long,
 636.244 +   &_resbook_44s_5,&_resbook_44s_5}
 636.245 +};
 636.246 +static const vorbis_residue_template _res_44s_6[]={
 636.247 +  {2,0,16,  &_residue_44_high,
 636.248 +   &_huff_book__44c6_s_short,&_huff_book__44c6_s_short,
 636.249 +   &_resbook_44s_6,&_resbook_44s_6},
 636.250 +
 636.251 +  {2,0,32,  &_residue_44_high,
 636.252 +   &_huff_book__44c6_s_long,&_huff_book__44c6_s_long,
 636.253 +   &_resbook_44s_6,&_resbook_44s_6}
 636.254 +};
 636.255 +static const vorbis_residue_template _res_44s_7[]={
 636.256 +  {2,0,16,  &_residue_44_high,
 636.257 +   &_huff_book__44c7_s_short,&_huff_book__44c7_s_short,
 636.258 +   &_resbook_44s_7,&_resbook_44s_7},
 636.259 +
 636.260 +  {2,0,32,  &_residue_44_high,
 636.261 +   &_huff_book__44c7_s_long,&_huff_book__44c7_s_long,
 636.262 +   &_resbook_44s_7,&_resbook_44s_7}
 636.263 +};
 636.264 +static const vorbis_residue_template _res_44s_8[]={
 636.265 +  {2,0,16,  &_residue_44_high,
 636.266 +   &_huff_book__44c8_s_short,&_huff_book__44c8_s_short,
 636.267 +   &_resbook_44s_8,&_resbook_44s_8},
 636.268 +
 636.269 +  {2,0,32,  &_residue_44_high,
 636.270 +   &_huff_book__44c8_s_long,&_huff_book__44c8_s_long,
 636.271 +   &_resbook_44s_8,&_resbook_44s_8}
 636.272 +};
 636.273 +static const vorbis_residue_template _res_44s_9[]={
 636.274 +  {2,0,16,  &_residue_44_high,
 636.275 +   &_huff_book__44c9_s_short,&_huff_book__44c9_s_short,
 636.276 +   &_resbook_44s_9,&_resbook_44s_9},
 636.277 +
 636.278 +  {2,0,32,  &_residue_44_high,
 636.279 +   &_huff_book__44c9_s_long,&_huff_book__44c9_s_long,
 636.280 +   &_resbook_44s_9,&_resbook_44s_9}
 636.281 +};
 636.282 +
 636.283 +static const vorbis_mapping_template _mapres_template_44_stereo[]={
 636.284 +  { _map_nominal, _res_44s_n1 }, /* -1 */
 636.285 +  { _map_nominal, _res_44s_0 }, /* 0 */
 636.286 +  { _map_nominal, _res_44s_1 }, /* 1 */
 636.287 +  { _map_nominal, _res_44s_2 }, /* 2 */
 636.288 +  { _map_nominal, _res_44s_3 }, /* 3 */
 636.289 +  { _map_nominal, _res_44s_4 }, /* 4 */
 636.290 +  { _map_nominal, _res_44s_5 }, /* 5 */
 636.291 +  { _map_nominal, _res_44s_6 }, /* 6 */
 636.292 +  { _map_nominal, _res_44s_7 }, /* 7 */
 636.293 +  { _map_nominal, _res_44s_8 }, /* 8 */
 636.294 +  { _map_nominal, _res_44s_9 }, /* 9 */
 636.295 +};
   637.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   637.2 +++ b/libs/vorbis/modes/residue_44p51.h	Sat Feb 01 19:58:19 2014 +0200
   637.3 @@ -0,0 +1,451 @@
   637.4 +/********************************************************************
   637.5 + *                                                                  *
   637.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   637.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   637.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   637.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  637.10 + *                                                                  *
  637.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
  637.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  637.13 + *                                                                  *
  637.14 + ********************************************************************
  637.15 +
  637.16 + function: toplevel residue templates for 32/44.1/48kHz uncoupled
  637.17 + last mod: $Id$
  637.18 +
  637.19 + ********************************************************************/
  637.20 +
  637.21 +#include "vorbis/codec.h"
  637.22 +#include "backends.h"
  637.23 +
  637.24 +#include "books/coupled/res_books_51.h"
  637.25 +
  637.26 +/***** residue backends *********************************************/
  637.27 +
  637.28 +static const vorbis_info_residue0 _residue_44p_lo={
  637.29 +  0,-1, -1, 7,-1,-1,
  637.30 +  /* 0   1   2   3   4   5   6   7   8  */
  637.31 +  {0},
  637.32 +  {-1},
  637.33 +  {  0,  1,  2,  7, 17, 31},
  637.34 +  {  0,  0, 99,  7, 17, 31},
  637.35 +};
  637.36 +
  637.37 +static const vorbis_info_residue0 _residue_44p={
  637.38 +  0,-1, -1, 8,-1,-1,
  637.39 +  /* 0   1   2   3   4   5   6   7   8  */
  637.40 +  {0},
  637.41 +  {-1},
  637.42 +  {  0,  1,  1,   2,  7, 17, 31},
  637.43 +  {  0,  0, 99,  99,  7, 17, 31},
  637.44 +};
  637.45 +
  637.46 +static const vorbis_info_residue0 _residue_44p_hi={
  637.47 +  0,-1, -1, 8,-1,-1,
  637.48 +  /* 0   1   2   3   4   5   6   7   8  */
  637.49 +  {0},
  637.50 +  {-1},
  637.51 +  {  0,  1,  2,  4,  7, 17, 31},
  637.52 +  {  0,  1,  2,  4,  7, 17, 31},
  637.53 +};
  637.54 +
  637.55 +static const vorbis_info_residue0 _residue_44p_lfe={
  637.56 +  0,-1, -1, 2,-1,-1,
  637.57 +  /* 0   1   2   3   4   5   6   7   8  */
  637.58 +  {0},
  637.59 +  {-1},
  637.60 +  { 32},
  637.61 +  { -1}
  637.62 +};
  637.63 +
  637.64 +static const static_bookblock _resbook_44p_n1={
  637.65 +  {
  637.66 +    {0},
  637.67 +    {0,&_44pn1_p1_0},
  637.68 +
  637.69 +    {&_44pn1_p2_0,&_44pn1_p2_1,0},
  637.70 +    {&_44pn1_p3_0,&_44pn1_p3_1,0},
  637.71 +    {&_44pn1_p4_0,&_44pn1_p4_1,0},
  637.72 +
  637.73 +    {&_44pn1_p5_0,&_44pn1_p5_1,&_44pn1_p4_1},
  637.74 +    {&_44pn1_p6_0,&_44pn1_p6_1,&_44pn1_p6_2},
  637.75 +   }
  637.76 +};
  637.77 +
  637.78 +static const static_bookblock _resbook_44p_0={
  637.79 +  {
  637.80 +    {0},
  637.81 +    {0,&_44p0_p1_0},
  637.82 +
  637.83 +    {&_44p0_p2_0,&_44p0_p2_1,0},
  637.84 +    {&_44p0_p3_0,&_44p0_p3_1,0},
  637.85 +    {&_44p0_p4_0,&_44p0_p4_1,0},
  637.86 +
  637.87 +    {&_44p0_p5_0,&_44p0_p5_1,&_44p0_p4_1},
  637.88 +    {&_44p0_p6_0,&_44p0_p6_1,&_44p0_p6_2},
  637.89 +   }
  637.90 +};
  637.91 +
  637.92 +static const static_bookblock _resbook_44p_1={
  637.93 +  {
  637.94 +    {0},
  637.95 +    {0,&_44p1_p1_0},
  637.96 +
  637.97 +    {&_44p1_p2_0,&_44p1_p2_1,0},
  637.98 +    {&_44p1_p3_0,&_44p1_p3_1,0},
  637.99 +    {&_44p1_p4_0,&_44p1_p4_1,0},
 637.100 +
 637.101 +    {&_44p1_p5_0,&_44p1_p5_1,&_44p1_p4_1},
 637.102 +    {&_44p1_p6_0,&_44p1_p6_1,&_44p1_p6_2},
 637.103 +   }
 637.104 +};
 637.105 +
 637.106 +static const static_bookblock _resbook_44p_2={
 637.107 +  {
 637.108 +    {0},
 637.109 +    {0,0,&_44p2_p1_0},
 637.110 +    {0,&_44p2_p2_0,0},
 637.111 +
 637.112 +    {&_44p2_p3_0,&_44p2_p3_1,0},
 637.113 +    {&_44p2_p4_0,&_44p2_p4_1,0},
 637.114 +    {&_44p2_p5_0,&_44p2_p5_1,0},
 637.115 +
 637.116 +    {&_44p2_p6_0,&_44p2_p6_1,&_44p2_p5_1},
 637.117 +    {&_44p2_p7_0,&_44p2_p7_1,&_44p2_p7_2,&_44p2_p7_3}
 637.118 +   }
 637.119 +};
 637.120 +static const static_bookblock _resbook_44p_3={
 637.121 +  {
 637.122 +    {0},
 637.123 +    {0,0,&_44p3_p1_0},
 637.124 +    {0,&_44p3_p2_0,0},
 637.125 +
 637.126 +    {&_44p3_p3_0,&_44p3_p3_1,0},
 637.127 +    {&_44p3_p4_0,&_44p3_p4_1,0},
 637.128 +    {&_44p3_p5_0,&_44p3_p5_1,0},
 637.129 +
 637.130 +    {&_44p3_p6_0,&_44p3_p6_1,&_44p3_p5_1},
 637.131 +    {&_44p3_p7_0,&_44p3_p7_1,&_44p3_p7_2,&_44p3_p7_3}
 637.132 +   }
 637.133 +};
 637.134 +static const static_bookblock _resbook_44p_4={
 637.135 +  {
 637.136 +    {0},
 637.137 +    {0,0,&_44p4_p1_0},
 637.138 +    {0,&_44p4_p2_0,0},
 637.139 +
 637.140 +    {&_44p4_p3_0,&_44p4_p3_1,0},
 637.141 +    {&_44p4_p4_0,&_44p4_p4_1,0},
 637.142 +    {&_44p4_p5_0,&_44p4_p5_1,0},
 637.143 +
 637.144 +    {&_44p4_p6_0,&_44p4_p6_1,&_44p4_p5_1},
 637.145 +    {&_44p4_p7_0,&_44p4_p7_1,&_44p4_p7_2,&_44p4_p7_3}
 637.146 +   }
 637.147 +};
 637.148 +static const static_bookblock _resbook_44p_5={
 637.149 +  {
 637.150 +    {0},
 637.151 +    {0,0,&_44p5_p1_0},
 637.152 +    {0,&_44p5_p2_0,0},
 637.153 +
 637.154 +    {&_44p5_p3_0,&_44p5_p3_1,0},
 637.155 +    {&_44p5_p4_0,&_44p5_p4_1,0},
 637.156 +    {&_44p5_p5_0,&_44p5_p5_1,0},
 637.157 +
 637.158 +    {&_44p5_p6_0,&_44p5_p6_1,&_44p5_p5_1},
 637.159 +    {&_44p5_p7_0,&_44p5_p7_1,&_44p5_p7_2,&_44p5_p7_3}
 637.160 +   }
 637.161 +};
 637.162 +static const static_bookblock _resbook_44p_6={
 637.163 +  {
 637.164 +    {0},
 637.165 +    {0,0,&_44p6_p1_0},
 637.166 +    {0,&_44p6_p2_0,0},
 637.167 +
 637.168 +    {&_44p6_p3_0,&_44p6_p3_1,0},
 637.169 +    {&_44p6_p4_0,&_44p6_p4_1,0},
 637.170 +    {&_44p6_p5_0,&_44p6_p5_1,0},
 637.171 +
 637.172 +    {&_44p6_p6_0,&_44p6_p6_1,&_44p6_p5_1},
 637.173 +    {&_44p6_p7_0,&_44p6_p7_1,&_44p6_p7_2,&_44p6_p7_3}
 637.174 +   }
 637.175 +};
 637.176 +static const static_bookblock _resbook_44p_7={
 637.177 +  {
 637.178 +    {0},
 637.179 +    {0,0,&_44p7_p1_0},
 637.180 +    {0,&_44p7_p2_0,0},
 637.181 +
 637.182 +    {&_44p7_p3_0,&_44p7_p3_1,0},
 637.183 +    {&_44p7_p4_0,&_44p7_p4_1,0},
 637.184 +    {&_44p7_p5_0,&_44p7_p5_1,0},
 637.185 +
 637.186 +    {&_44p7_p6_0,&_44p7_p6_1,&_44p7_p5_1},
 637.187 +    {&_44p7_p7_0,&_44p7_p7_1,&_44p7_p7_2,&_44p7_p7_3}
 637.188 +   }
 637.189 +};
 637.190 +static const static_bookblock _resbook_44p_8={
 637.191 +  {
 637.192 +    {0},
 637.193 +    {0,0,&_44p8_p1_0},
 637.194 +    {0,&_44p8_p2_0,0},
 637.195 +
 637.196 +    {&_44p8_p3_0,&_44p8_p3_1,0},
 637.197 +    {&_44p8_p4_0,&_44p8_p4_1,0},
 637.198 +    {&_44p8_p5_0,&_44p8_p5_1,0},
 637.199 +
 637.200 +    {&_44p8_p6_0,&_44p8_p6_1,&_44p8_p5_1},
 637.201 +    {&_44p8_p7_0,&_44p8_p7_1,&_44p8_p7_2,&_44p8_p7_3}
 637.202 +   }
 637.203 +};
 637.204 +static const static_bookblock _resbook_44p_9={
 637.205 +  {
 637.206 +    {0},
 637.207 +    {0,0,&_44p9_p1_0},
 637.208 +    {0,&_44p9_p2_0,0},
 637.209 +
 637.210 +    {&_44p9_p3_0,&_44p9_p3_1,0},
 637.211 +    {&_44p9_p4_0,&_44p9_p4_1,0},
 637.212 +    {&_44p9_p5_0,&_44p9_p5_1,0},
 637.213 +
 637.214 +    {&_44p9_p6_0,&_44p9_p6_1,&_44p9_p5_1},
 637.215 +    {&_44p9_p7_0,&_44p9_p7_1,&_44p9_p7_2,&_44p9_p7_3}
 637.216 +   }
 637.217 +};
 637.218 +
 637.219 +static const static_bookblock _resbook_44p_ln1={
 637.220 +  {
 637.221 +    {&_44pn1_l0_0,&_44pn1_l0_1,0},
 637.222 +    {&_44pn1_l1_0,&_44pn1_p6_1,&_44pn1_p6_2},
 637.223 +   }
 637.224 +};
 637.225 +static const static_bookblock _resbook_44p_l0={
 637.226 +  {
 637.227 +    {&_44p0_l0_0,&_44p0_l0_1,0},
 637.228 +    {&_44p0_l1_0,&_44p0_p6_1,&_44p0_p6_2},
 637.229 +   }
 637.230 +};
 637.231 +static const static_bookblock _resbook_44p_l1={
 637.232 +  {
 637.233 +    {&_44p1_l0_0,&_44p1_l0_1,0},
 637.234 +    {&_44p1_l1_0,&_44p1_p6_1,&_44p1_p6_2},
 637.235 +   }
 637.236 +};
 637.237 +static const static_bookblock _resbook_44p_l2={
 637.238 +  {
 637.239 +    {&_44p2_l0_0,&_44p2_l0_1,0},
 637.240 +    {&_44p2_l1_0,&_44p2_p7_2,&_44p2_p7_3},
 637.241 +   }
 637.242 +};
 637.243 +static const static_bookblock _resbook_44p_l3={
 637.244 +  {
 637.245 +    {&_44p3_l0_0,&_44p3_l0_1,0},
 637.246 +    {&_44p3_l1_0,&_44p3_p7_2,&_44p3_p7_3},
 637.247 +   }
 637.248 +};
 637.249 +static const static_bookblock _resbook_44p_l4={
 637.250 +  {
 637.251 +    {&_44p4_l0_0,&_44p4_l0_1,0},
 637.252 +    {&_44p4_l1_0,&_44p4_p7_2,&_44p4_p7_3},
 637.253 +   }
 637.254 +};
 637.255 +static const static_bookblock _resbook_44p_l5={
 637.256 +  {
 637.257 +    {&_44p5_l0_0,&_44p5_l0_1,0},
 637.258 +    {&_44p5_l1_0,&_44p5_p7_2,&_44p5_p7_3},
 637.259 +   }
 637.260 +};
 637.261 +static const static_bookblock _resbook_44p_l6={
 637.262 +  {
 637.263 +    {&_44p6_l0_0,&_44p6_l0_1,0},
 637.264 +    {&_44p6_l1_0,&_44p6_p7_2,&_44p6_p7_3},
 637.265 +   }
 637.266 +};
 637.267 +static const static_bookblock _resbook_44p_l7={
 637.268 +  {
 637.269 +    {&_44p7_l0_0,&_44p7_l0_1,0},
 637.270 +    {&_44p7_l1_0,&_44p7_p7_2,&_44p7_p7_3},
 637.271 +   }
 637.272 +};
 637.273 +static const static_bookblock _resbook_44p_l8={
 637.274 +  {
 637.275 +    {&_44p8_l0_0,&_44p8_l0_1,0},
 637.276 +    {&_44p8_l1_0,&_44p8_p7_2,&_44p8_p7_3},
 637.277 +   }
 637.278 +};
 637.279 +static const static_bookblock _resbook_44p_l9={
 637.280 +  {
 637.281 +    {&_44p9_l0_0,&_44p9_l0_1,0},
 637.282 +    {&_44p9_l1_0,&_44p9_p7_2,&_44p9_p7_3},
 637.283 +   }
 637.284 +};
 637.285 +
 637.286 +
 637.287 +static const vorbis_info_mapping0 _map_nominal_51[2]={
 637.288 +  {2, {0,0,0,0,0,1}, {0,2}, {0,2}, 4,{0,3,0,0},{2,4,1,3}},
 637.289 +  {2, {0,0,0,0,0,1}, {1,2}, {1,2}, 4,{0,3,0,0},{2,4,1,3}}
 637.290 +};
 637.291 +static const vorbis_info_mapping0 _map_nominal_51u[2]={
 637.292 +  {2, {0,0,0,0,0,1}, {0,2}, {0,2}, 0,{0},{0}},
 637.293 +  {2, {0,0,0,0,0,1}, {1,2}, {1,2}, 0,{0},{0}}
 637.294 +};
 637.295 +
 637.296 +static const vorbis_residue_template _res_44p51_n1[]={
 637.297 +  {2,0,30,  &_residue_44p_lo,
 637.298 +   &_huff_book__44pn1_short,&_huff_book__44pn1_short,
 637.299 +   &_resbook_44p_n1,&_resbook_44p_n1},
 637.300 +
 637.301 +  {2,0,30,  &_residue_44p_lo,
 637.302 +   &_huff_book__44pn1_long,&_huff_book__44pn1_long,
 637.303 +   &_resbook_44p_n1,&_resbook_44p_n1},
 637.304 +
 637.305 +  {1,2,6,  &_residue_44p_lfe,
 637.306 +   &_huff_book__44pn1_lfe,&_huff_book__44pn1_lfe,
 637.307 +   &_resbook_44p_ln1,&_resbook_44p_ln1}
 637.308 +};
 637.309 +static const vorbis_residue_template _res_44p51_0[]={
 637.310 +  {2,0,15,  &_residue_44p_lo,
 637.311 +   &_huff_book__44p0_short,&_huff_book__44p0_short,
 637.312 +   &_resbook_44p_0,&_resbook_44p_0},
 637.313 +
 637.314 +  {2,0,30,  &_residue_44p_lo,
 637.315 +   &_huff_book__44p0_long,&_huff_book__44p0_long,
 637.316 +   &_resbook_44p_0,&_resbook_44p_0},
 637.317 +
 637.318 +  {1,2,6,  &_residue_44p_lfe,
 637.319 +   &_huff_book__44p0_lfe,&_huff_book__44p0_lfe,
 637.320 +   &_resbook_44p_l0,&_resbook_44p_l0}
 637.321 +};
 637.322 +static const vorbis_residue_template _res_44p51_1[]={
 637.323 +  {2,0,15,  &_residue_44p_lo,
 637.324 +   &_huff_book__44p1_short,&_huff_book__44p1_short,
 637.325 +   &_resbook_44p_1,&_resbook_44p_1},
 637.326 +
 637.327 +  {2,0,30,  &_residue_44p_lo,
 637.328 +   &_huff_book__44p1_long,&_huff_book__44p1_long,
 637.329 +   &_resbook_44p_1,&_resbook_44p_1},
 637.330 +
 637.331 +  {1,2,6,  &_residue_44p_lfe,
 637.332 +   &_huff_book__44p1_lfe,&_huff_book__44p1_lfe,
 637.333 +   &_resbook_44p_l1,&_resbook_44p_l1}
 637.334 +};
 637.335 +static const vorbis_residue_template _res_44p51_2[]={
 637.336 +  {2,0,15,  &_residue_44p,
 637.337 +   &_huff_book__44p2_short,&_huff_book__44p2_short,
 637.338 +   &_resbook_44p_2,&_resbook_44p_2},
 637.339 +
 637.340 +  {2,0,30,  &_residue_44p,
 637.341 +   &_huff_book__44p2_long,&_huff_book__44p2_long,
 637.342 +   &_resbook_44p_2,&_resbook_44p_2},
 637.343 +
 637.344 +  {1,2,6,  &_residue_44p_lfe,
 637.345 +   &_huff_book__44p2_lfe,&_huff_book__44p2_lfe,
 637.346 +   &_resbook_44p_l2,&_resbook_44p_l2}
 637.347 +};
 637.348 +static const vorbis_residue_template _res_44p51_3[]={
 637.349 +  {2,0,15,  &_residue_44p,
 637.350 +   &_huff_book__44p3_short,&_huff_book__44p3_short,
 637.351 +   &_resbook_44p_3,&_resbook_44p_3},
 637.352 +
 637.353 +  {2,0,30,  &_residue_44p,
 637.354 +   &_huff_book__44p3_long,&_huff_book__44p3_long,
 637.355 +   &_resbook_44p_3,&_resbook_44p_3},
 637.356 +
 637.357 +  {1,2,6,  &_residue_44p_lfe,
 637.358 +   &_huff_book__44p3_lfe,&_huff_book__44p3_lfe,
 637.359 +   &_resbook_44p_l3,&_resbook_44p_l3}
 637.360 +};
 637.361 +static const vorbis_residue_template _res_44p51_4[]={
 637.362 +  {2,0,15,  &_residue_44p,
 637.363 +   &_huff_book__44p4_short,&_huff_book__44p4_short,
 637.364 +   &_resbook_44p_4,&_resbook_44p_4},
 637.365 +
 637.366 +  {2,0,30,  &_residue_44p,
 637.367 +   &_huff_book__44p4_long,&_huff_book__44p4_long,
 637.368 +   &_resbook_44p_4,&_resbook_44p_4},
 637.369 +
 637.370 +  {1,2,6,  &_residue_44p_lfe,
 637.371 +   &_huff_book__44p4_lfe,&_huff_book__44p4_lfe,
 637.372 +   &_resbook_44p_l4,&_resbook_44p_l4}
 637.373 +};
 637.374 +static const vorbis_residue_template _res_44p51_5[]={
 637.375 +  {2,0,15,  &_residue_44p_hi,
 637.376 +   &_huff_book__44p5_short,&_huff_book__44p5_short,
 637.377 +   &_resbook_44p_5,&_resbook_44p_5},
 637.378 +
 637.379 +  {2,0,30,  &_residue_44p_hi,
 637.380 +   &_huff_book__44p5_long,&_huff_book__44p5_long,
 637.381 +   &_resbook_44p_5,&_resbook_44p_5},
 637.382 +
 637.383 +  {1,2,6,  &_residue_44p_lfe,
 637.384 +   &_huff_book__44p5_lfe,&_huff_book__44p5_lfe,
 637.385 +   &_resbook_44p_l5,&_resbook_44p_l5}
 637.386 +};
 637.387 +static const vorbis_residue_template _res_44p51_6[]={
 637.388 +  {2,0,15,  &_residue_44p_hi,
 637.389 +   &_huff_book__44p6_short,&_huff_book__44p6_short,
 637.390 +   &_resbook_44p_6,&_resbook_44p_6},
 637.391 +
 637.392 +  {2,0,30,  &_residue_44p_hi,
 637.393 +   &_huff_book__44p6_long,&_huff_book__44p6_long,
 637.394 +   &_resbook_44p_6,&_resbook_44p_6},
 637.395 +
 637.396 +  {1,2,6,  &_residue_44p_lfe,
 637.397 +   &_huff_book__44p6_lfe,&_huff_book__44p6_lfe,
 637.398 +   &_resbook_44p_l6,&_resbook_44p_l6}
 637.399 +};
 637.400 +
 637.401 +
 637.402 +static const vorbis_residue_template _res_44p51_7[]={
 637.403 +  {2,0,15,  &_residue_44p_hi,
 637.404 +   &_huff_book__44p7_short,&_huff_book__44p7_short,
 637.405 +   &_resbook_44p_7,&_resbook_44p_7},
 637.406 +
 637.407 +  {2,0,30,  &_residue_44p_hi,
 637.408 +   &_huff_book__44p7_long,&_huff_book__44p7_long,
 637.409 +   &_resbook_44p_7,&_resbook_44p_7},
 637.410 +
 637.411 +  {1,2,6,  &_residue_44p_lfe,
 637.412 +   &_huff_book__44p6_lfe,&_huff_book__44p6_lfe,
 637.413 +   &_resbook_44p_l6,&_resbook_44p_l6}
 637.414 +};
 637.415 +static const vorbis_residue_template _res_44p51_8[]={
 637.416 +  {2,0,15,  &_residue_44p_hi,
 637.417 +   &_huff_book__44p8_short,&_huff_book__44p8_short,
 637.418 +   &_resbook_44p_8,&_resbook_44p_8},
 637.419 +
 637.420 +  {2,0,30,  &_residue_44p_hi,
 637.421 +   &_huff_book__44p8_long,&_huff_book__44p8_long,
 637.422 +   &_resbook_44p_8,&_resbook_44p_8},
 637.423 +
 637.424 +  {1,2,6,  &_residue_44p_lfe,
 637.425 +   &_huff_book__44p6_lfe,&_huff_book__44p6_lfe,
 637.426 +   &_resbook_44p_l6,&_resbook_44p_l6}
 637.427 +};
 637.428 +static const vorbis_residue_template _res_44p51_9[]={
 637.429 +  {2,0,15,  &_residue_44p_hi,
 637.430 +   &_huff_book__44p9_short,&_huff_book__44p9_short,
 637.431 +   &_resbook_44p_9,&_resbook_44p_9},
 637.432 +
 637.433 +  {2,0,30,  &_residue_44p_hi,
 637.434 +   &_huff_book__44p9_long,&_huff_book__44p9_long,
 637.435 +   &_resbook_44p_9,&_resbook_44p_9},
 637.436 +
 637.437 +  {1,2,6,  &_residue_44p_lfe,
 637.438 +   &_huff_book__44p6_lfe,&_huff_book__44p6_lfe,
 637.439 +   &_resbook_44p_l6,&_resbook_44p_l6}
 637.440 +};
 637.441 +
 637.442 +static const vorbis_mapping_template _mapres_template_44_51[]={
 637.443 +  { _map_nominal_51, _res_44p51_n1 }, /* -1 */
 637.444 +  { _map_nominal_51, _res_44p51_0 }, /* 0 */
 637.445 +  { _map_nominal_51, _res_44p51_1 }, /* 1 */
 637.446 +  { _map_nominal_51, _res_44p51_2 }, /* 2 */
 637.447 +  { _map_nominal_51, _res_44p51_3 }, /* 3 */
 637.448 +  { _map_nominal_51, _res_44p51_4 }, /* 4 */
 637.449 +  { _map_nominal_51u, _res_44p51_5 }, /* 5 */
 637.450 +  { _map_nominal_51u, _res_44p51_6 }, /* 6 */
 637.451 +  { _map_nominal_51u, _res_44p51_7 }, /* 7 */
 637.452 +  { _map_nominal_51u, _res_44p51_8 }, /* 8 */
 637.453 +  { _map_nominal_51u, _res_44p51_9 }, /* 9 */
 637.454 +};
   638.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   638.2 +++ b/libs/vorbis/modes/residue_44u.h	Sat Feb 01 19:58:19 2014 +0200
   638.3 @@ -0,0 +1,318 @@
   638.4 +/********************************************************************
   638.5 + *                                                                  *
   638.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   638.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   638.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   638.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  638.10 + *                                                                  *
  638.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  638.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  638.13 + *                                                                  *
  638.14 + ********************************************************************
  638.15 +
  638.16 + function: toplevel residue templates for 32/44.1/48kHz uncoupled
  638.17 + last mod: $Id: residue_44u.h 16962 2010-03-11 07:30:34Z xiphmont $
  638.18 +
  638.19 + ********************************************************************/
  638.20 +
  638.21 +#include "vorbis/codec.h"
  638.22 +#include "backends.h"
  638.23 +#include "books/uncoupled/res_books_uncoupled.h"
  638.24 +
  638.25 +/***** residue backends *********************************************/
  638.26 +
  638.27 +
  638.28 +static const vorbis_info_residue0 _residue_44_low_un={
  638.29 +  0,-1, -1, 8,-1,-1,
  638.30 +  {0},
  638.31 +  {-1},
  638.32 +  {  0,  1,  1,  2,  2,  4, 28},
  638.33 +  { -1, 25, -1, 45, -1, -1, -1}
  638.34 +};
  638.35 +
  638.36 +static const vorbis_info_residue0 _residue_44_mid_un={
  638.37 +  0,-1, -1, 10,-1,-1,
  638.38 +  /* 0   1   2   3   4   5   6   7   8   9 */
  638.39 +  {0},
  638.40 +  {-1},
  638.41 +  {  0,  1,  1,  2,  2,  4,  4, 16, 60},
  638.42 +  { -1, 30, -1, 50, -1, 80, -1, -1, -1}
  638.43 +};
  638.44 +
  638.45 +static const vorbis_info_residue0 _residue_44_hi_un={
  638.46 +  0,-1, -1, 10,-1,-1,
  638.47 +  /* 0   1   2   3   4   5   6   7   8   9 */
  638.48 +  {0},
  638.49 +  {-1},
  638.50 +  {  0,  1,  2,  4,  8, 16, 32, 71,157},
  638.51 +  { -1, -1, -1, -1, -1, -1, -1, -1, -1}
  638.52 +};
  638.53 +
  638.54 +/* mapping conventions:
  638.55 +   only one submap (this would change for efficient 5.1 support for example)*/
  638.56 +/* Four psychoacoustic profiles are used, one for each blocktype */
  638.57 +static const vorbis_info_mapping0 _map_nominal_u[2]={
  638.58 +  {1, {0,0,0,0,0,0}, {0}, {0}, 0,{0},{0}},
  638.59 +  {1, {0,0,0,0,0,0}, {1}, {1}, 0,{0},{0}}
  638.60 +};
  638.61 +
  638.62 +static const static_bookblock _resbook_44u_n1={
  638.63 +  {
  638.64 +    {0},
  638.65 +    {0,0,&_44un1__p1_0},
  638.66 +    {0,0,&_44un1__p2_0},
  638.67 +    {0,0,&_44un1__p3_0},
  638.68 +    {0,0,&_44un1__p4_0},
  638.69 +    {0,0,&_44un1__p5_0},
  638.70 +    {&_44un1__p6_0,&_44un1__p6_1},
  638.71 +    {&_44un1__p7_0,&_44un1__p7_1,&_44un1__p7_2}
  638.72 +   }
  638.73 +};
  638.74 +static const static_bookblock _resbook_44u_0={
  638.75 +  {
  638.76 +    {0},
  638.77 +    {0,0,&_44u0__p1_0},
  638.78 +    {0,0,&_44u0__p2_0},
  638.79 +    {0,0,&_44u0__p3_0},
  638.80 +    {0,0,&_44u0__p4_0},
  638.81 +    {0,0,&_44u0__p5_0},
  638.82 +    {&_44u0__p6_0,&_44u0__p6_1},
  638.83 +    {&_44u0__p7_0,&_44u0__p7_1,&_44u0__p7_2}
  638.84 +   }
  638.85 +};
  638.86 +static const static_bookblock _resbook_44u_1={
  638.87 +  {
  638.88 +    {0},
  638.89 +    {0,0,&_44u1__p1_0},
  638.90 +    {0,0,&_44u1__p2_0},
  638.91 +    {0,0,&_44u1__p3_0},
  638.92 +    {0,0,&_44u1__p4_0},
  638.93 +    {0,0,&_44u1__p5_0},
  638.94 +    {&_44u1__p6_0,&_44u1__p6_1},
  638.95 +    {&_44u1__p7_0,&_44u1__p7_1,&_44u1__p7_2}
  638.96 +   }
  638.97 +};
  638.98 +static const static_bookblock _resbook_44u_2={
  638.99 +  {
 638.100 +    {0},
 638.101 +    {0,0,&_44u2__p1_0},
 638.102 +    {0,0,&_44u2__p2_0},
 638.103 +    {0,0,&_44u2__p3_0},
 638.104 +    {0,0,&_44u2__p4_0},
 638.105 +    {0,0,&_44u2__p5_0},
 638.106 +    {&_44u2__p6_0,&_44u2__p6_1},
 638.107 +    {&_44u2__p7_0,&_44u2__p7_1,&_44u2__p7_2}
 638.108 +   }
 638.109 +};
 638.110 +static const static_bookblock _resbook_44u_3={
 638.111 +  {
 638.112 +    {0},
 638.113 +    {0,0,&_44u3__p1_0},
 638.114 +    {0,0,&_44u3__p2_0},
 638.115 +    {0,0,&_44u3__p3_0},
 638.116 +    {0,0,&_44u3__p4_0},
 638.117 +    {0,0,&_44u3__p5_0},
 638.118 +    {&_44u3__p6_0,&_44u3__p6_1},
 638.119 +    {&_44u3__p7_0,&_44u3__p7_1,&_44u3__p7_2}
 638.120 +   }
 638.121 +};
 638.122 +static const static_bookblock _resbook_44u_4={
 638.123 +  {
 638.124 +    {0},
 638.125 +    {0,0,&_44u4__p1_0},
 638.126 +    {0,0,&_44u4__p2_0},
 638.127 +    {0,0,&_44u4__p3_0},
 638.128 +    {0,0,&_44u4__p4_0},
 638.129 +    {0,0,&_44u4__p5_0},
 638.130 +    {&_44u4__p6_0,&_44u4__p6_1},
 638.131 +    {&_44u4__p7_0,&_44u4__p7_1,&_44u4__p7_2}
 638.132 +   }
 638.133 +};
 638.134 +static const static_bookblock _resbook_44u_5={
 638.135 +  {
 638.136 +    {0},
 638.137 +    {0,0,&_44u5__p1_0},
 638.138 +    {0,0,&_44u5__p2_0},
 638.139 +    {0,0,&_44u5__p3_0},
 638.140 +    {0,0,&_44u5__p4_0},
 638.141 +    {0,0,&_44u5__p5_0},
 638.142 +    {0,0,&_44u5__p6_0},
 638.143 +    {&_44u5__p7_0,&_44u5__p7_1},
 638.144 +    {&_44u5__p8_0,&_44u5__p8_1},
 638.145 +    {&_44u5__p9_0,&_44u5__p9_1,&_44u5__p9_2}
 638.146 +   }
 638.147 +};
 638.148 +static const static_bookblock _resbook_44u_6={
 638.149 +  {
 638.150 +    {0},
 638.151 +    {0,0,&_44u6__p1_0},
 638.152 +    {0,0,&_44u6__p2_0},
 638.153 +    {0,0,&_44u6__p3_0},
 638.154 +    {0,0,&_44u6__p4_0},
 638.155 +    {0,0,&_44u6__p5_0},
 638.156 +    {0,0,&_44u6__p6_0},
 638.157 +    {&_44u6__p7_0,&_44u6__p7_1},
 638.158 +    {&_44u6__p8_0,&_44u6__p8_1},
 638.159 +    {&_44u6__p9_0,&_44u6__p9_1,&_44u6__p9_2}
 638.160 +   }
 638.161 +};
 638.162 +static const static_bookblock _resbook_44u_7={
 638.163 +  {
 638.164 +    {0},
 638.165 +    {0,0,&_44u7__p1_0},
 638.166 +    {0,0,&_44u7__p2_0},
 638.167 +    {0,0,&_44u7__p3_0},
 638.168 +    {0,0,&_44u7__p4_0},
 638.169 +    {0,0,&_44u7__p5_0},
 638.170 +    {0,0,&_44u7__p6_0},
 638.171 +    {&_44u7__p7_0,&_44u7__p7_1},
 638.172 +    {&_44u7__p8_0,&_44u7__p8_1},
 638.173 +    {&_44u7__p9_0,&_44u7__p9_1,&_44u7__p9_2}
 638.174 +   }
 638.175 +};
 638.176 +static const static_bookblock _resbook_44u_8={
 638.177 +  {
 638.178 +    {0},
 638.179 +    {0,0,&_44u8_p1_0},
 638.180 +    {0,0,&_44u8_p2_0},
 638.181 +    {0,0,&_44u8_p3_0},
 638.182 +    {0,0,&_44u8_p4_0},
 638.183 +    {&_44u8_p5_0,&_44u8_p5_1},
 638.184 +    {&_44u8_p6_0,&_44u8_p6_1},
 638.185 +    {&_44u8_p7_0,&_44u8_p7_1},
 638.186 +    {&_44u8_p8_0,&_44u8_p8_1},
 638.187 +    {&_44u8_p9_0,&_44u8_p9_1,&_44u8_p9_2}
 638.188 +   }
 638.189 +};
 638.190 +static const static_bookblock _resbook_44u_9={
 638.191 +  {
 638.192 +    {0},
 638.193 +    {0,0,&_44u9_p1_0},
 638.194 +    {0,0,&_44u9_p2_0},
 638.195 +    {0,0,&_44u9_p3_0},
 638.196 +    {0,0,&_44u9_p4_0},
 638.197 +    {&_44u9_p5_0,&_44u9_p5_1},
 638.198 +    {&_44u9_p6_0,&_44u9_p6_1},
 638.199 +    {&_44u9_p7_0,&_44u9_p7_1},
 638.200 +    {&_44u9_p8_0,&_44u9_p8_1},
 638.201 +    {&_44u9_p9_0,&_44u9_p9_1,&_44u9_p9_2}
 638.202 +   }
 638.203 +};
 638.204 +
 638.205 +static const vorbis_residue_template _res_44u_n1[]={
 638.206 +  {1,0,32,  &_residue_44_low_un,
 638.207 +   &_huff_book__44un1__short,&_huff_book__44un1__short,
 638.208 +   &_resbook_44u_n1,&_resbook_44u_n1},
 638.209 +
 638.210 +  {1,0,32,  &_residue_44_low_un,
 638.211 +   &_huff_book__44un1__long,&_huff_book__44un1__long,
 638.212 +   &_resbook_44u_n1,&_resbook_44u_n1}
 638.213 +};
 638.214 +static const vorbis_residue_template _res_44u_0[]={
 638.215 +  {1,0,16,  &_residue_44_low_un,
 638.216 +   &_huff_book__44u0__short,&_huff_book__44u0__short,
 638.217 +   &_resbook_44u_0,&_resbook_44u_0},
 638.218 +
 638.219 +  {1,0,32,  &_residue_44_low_un,
 638.220 +   &_huff_book__44u0__long,&_huff_book__44u0__long,
 638.221 +   &_resbook_44u_0,&_resbook_44u_0}
 638.222 +};
 638.223 +static const vorbis_residue_template _res_44u_1[]={
 638.224 +  {1,0,16,  &_residue_44_low_un,
 638.225 +   &_huff_book__44u1__short,&_huff_book__44u1__short,
 638.226 +   &_resbook_44u_1,&_resbook_44u_1},
 638.227 +
 638.228 +  {1,0,32,  &_residue_44_low_un,
 638.229 +   &_huff_book__44u1__long,&_huff_book__44u1__long,
 638.230 +   &_resbook_44u_1,&_resbook_44u_1}
 638.231 +};
 638.232 +static const vorbis_residue_template _res_44u_2[]={
 638.233 +  {1,0,16,  &_residue_44_low_un,
 638.234 +   &_huff_book__44u2__short,&_huff_book__44u2__short,
 638.235 +   &_resbook_44u_2,&_resbook_44u_2},
 638.236 +
 638.237 +  {1,0,32,  &_residue_44_low_un,
 638.238 +   &_huff_book__44u2__long,&_huff_book__44u2__long,
 638.239 +   &_resbook_44u_2,&_resbook_44u_2}
 638.240 +};
 638.241 +static const vorbis_residue_template _res_44u_3[]={
 638.242 +  {1,0,16,  &_residue_44_low_un,
 638.243 +   &_huff_book__44u3__short,&_huff_book__44u3__short,
 638.244 +   &_resbook_44u_3,&_resbook_44u_3},
 638.245 +
 638.246 +  {1,0,32,  &_residue_44_low_un,
 638.247 +   &_huff_book__44u3__long,&_huff_book__44u3__long,
 638.248 +   &_resbook_44u_3,&_resbook_44u_3}
 638.249 +};
 638.250 +static const vorbis_residue_template _res_44u_4[]={
 638.251 +  {1,0,16,  &_residue_44_low_un,
 638.252 +   &_huff_book__44u4__short,&_huff_book__44u4__short,
 638.253 +   &_resbook_44u_4,&_resbook_44u_4},
 638.254 +
 638.255 +  {1,0,32,  &_residue_44_low_un,
 638.256 +   &_huff_book__44u4__long,&_huff_book__44u4__long,
 638.257 +   &_resbook_44u_4,&_resbook_44u_4}
 638.258 +};
 638.259 +
 638.260 +static const vorbis_residue_template _res_44u_5[]={
 638.261 +  {1,0,16,  &_residue_44_mid_un,
 638.262 +   &_huff_book__44u5__short,&_huff_book__44u5__short,
 638.263 +   &_resbook_44u_5,&_resbook_44u_5},
 638.264 +
 638.265 +  {1,0,32,  &_residue_44_mid_un,
 638.266 +   &_huff_book__44u5__long,&_huff_book__44u5__long,
 638.267 +   &_resbook_44u_5,&_resbook_44u_5}
 638.268 +};
 638.269 +
 638.270 +static const vorbis_residue_template _res_44u_6[]={
 638.271 +  {1,0,16,  &_residue_44_mid_un,
 638.272 +   &_huff_book__44u6__short,&_huff_book__44u6__short,
 638.273 +   &_resbook_44u_6,&_resbook_44u_6},
 638.274 +
 638.275 +  {1,0,32,  &_residue_44_mid_un,
 638.276 +   &_huff_book__44u6__long,&_huff_book__44u6__long,
 638.277 +   &_resbook_44u_6,&_resbook_44u_6}
 638.278 +};
 638.279 +
 638.280 +static const vorbis_residue_template _res_44u_7[]={
 638.281 +  {1,0,16,  &_residue_44_mid_un,
 638.282 +   &_huff_book__44u7__short,&_huff_book__44u7__short,
 638.283 +   &_resbook_44u_7,&_resbook_44u_7},
 638.284 +
 638.285 +  {1,0,32,  &_residue_44_mid_un,
 638.286 +   &_huff_book__44u7__long,&_huff_book__44u7__long,
 638.287 +   &_resbook_44u_7,&_resbook_44u_7}
 638.288 +};
 638.289 +
 638.290 +static const vorbis_residue_template _res_44u_8[]={
 638.291 +  {1,0,16,  &_residue_44_hi_un,
 638.292 +   &_huff_book__44u8__short,&_huff_book__44u8__short,
 638.293 +   &_resbook_44u_8,&_resbook_44u_8},
 638.294 +
 638.295 +  {1,0,32,  &_residue_44_hi_un,
 638.296 +   &_huff_book__44u8__long,&_huff_book__44u8__long,
 638.297 +   &_resbook_44u_8,&_resbook_44u_8}
 638.298 +};
 638.299 +static const vorbis_residue_template _res_44u_9[]={
 638.300 +  {1,0,16,  &_residue_44_hi_un,
 638.301 +   &_huff_book__44u9__short,&_huff_book__44u9__short,
 638.302 +   &_resbook_44u_9,&_resbook_44u_9},
 638.303 +
 638.304 +  {1,0,32,  &_residue_44_hi_un,
 638.305 +   &_huff_book__44u9__long,&_huff_book__44u9__long,
 638.306 +   &_resbook_44u_9,&_resbook_44u_9}
 638.307 +};
 638.308 +
 638.309 +static const vorbis_mapping_template _mapres_template_44_uncoupled[]={
 638.310 +  { _map_nominal_u, _res_44u_n1 }, /* -1 */
 638.311 +  { _map_nominal_u, _res_44u_0 }, /* 0 */
 638.312 +  { _map_nominal_u, _res_44u_1 }, /* 1 */
 638.313 +  { _map_nominal_u, _res_44u_2 }, /* 2 */
 638.314 +  { _map_nominal_u, _res_44u_3 }, /* 3 */
 638.315 +  { _map_nominal_u, _res_44u_4 }, /* 4 */
 638.316 +  { _map_nominal_u, _res_44u_5 }, /* 5 */
 638.317 +  { _map_nominal_u, _res_44u_6 }, /* 6 */
 638.318 +  { _map_nominal_u, _res_44u_7 }, /* 7 */
 638.319 +  { _map_nominal_u, _res_44u_8 }, /* 8 */
 638.320 +  { _map_nominal_u, _res_44u_9 }, /* 9 */
 638.321 +};
   639.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   639.2 +++ b/libs/vorbis/modes/residue_8.h	Sat Feb 01 19:58:19 2014 +0200
   639.3 @@ -0,0 +1,109 @@
   639.4 +/********************************************************************
   639.5 + *                                                                  *
   639.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   639.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   639.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   639.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  639.10 + *                                                                  *
  639.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  639.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  639.13 + *                                                                  *
  639.14 + ********************************************************************
  639.15 +
  639.16 + function: toplevel residue templates 8/11kHz
  639.17 + last mod: $Id: residue_8.h 16962 2010-03-11 07:30:34Z xiphmont $
  639.18 +
  639.19 + ********************************************************************/
  639.20 +
  639.21 +#include "vorbis/codec.h"
  639.22 +#include "backends.h"
  639.23 +
  639.24 +/***** residue backends *********************************************/
  639.25 +
  639.26 +static const static_bookblock _resbook_8s_0={
  639.27 +  {
  639.28 +    {0},
  639.29 +    {0,0,&_8c0_s_p1_0},
  639.30 +    {0},
  639.31 +    {0,0,&_8c0_s_p3_0},
  639.32 +    {0,0,&_8c0_s_p4_0},
  639.33 +    {0,0,&_8c0_s_p5_0},
  639.34 +    {0,0,&_8c0_s_p6_0},
  639.35 +    {&_8c0_s_p7_0,&_8c0_s_p7_1},
  639.36 +    {&_8c0_s_p8_0,&_8c0_s_p8_1},
  639.37 +    {&_8c0_s_p9_0,&_8c0_s_p9_1,&_8c0_s_p9_2}
  639.38 +   }
  639.39 +};
  639.40 +static const static_bookblock _resbook_8s_1={
  639.41 +  {
  639.42 +    {0},
  639.43 +    {0,0,&_8c1_s_p1_0},
  639.44 +    {0},
  639.45 +    {0,0,&_8c1_s_p3_0},
  639.46 +    {0,0,&_8c1_s_p4_0},
  639.47 +    {0,0,&_8c1_s_p5_0},
  639.48 +    {0,0,&_8c1_s_p6_0},
  639.49 +    {&_8c1_s_p7_0,&_8c1_s_p7_1},
  639.50 +    {&_8c1_s_p8_0,&_8c1_s_p8_1},
  639.51 +    {&_8c1_s_p9_0,&_8c1_s_p9_1,&_8c1_s_p9_2}
  639.52 +   }
  639.53 +};
  639.54 +
  639.55 +static const vorbis_residue_template _res_8s_0[]={
  639.56 +  {2,0,32,  &_residue_44_mid,
  639.57 +   &_huff_book__8c0_s_single,&_huff_book__8c0_s_single,
  639.58 +   &_resbook_8s_0,&_resbook_8s_0},
  639.59 +};
  639.60 +static const vorbis_residue_template _res_8s_1[]={
  639.61 +  {2,0,32,  &_residue_44_mid,
  639.62 +   &_huff_book__8c1_s_single,&_huff_book__8c1_s_single,
  639.63 +   &_resbook_8s_1,&_resbook_8s_1},
  639.64 +};
  639.65 +
  639.66 +static const vorbis_mapping_template _mapres_template_8_stereo[2]={
  639.67 +  { _map_nominal, _res_8s_0 }, /* 0 */
  639.68 +  { _map_nominal, _res_8s_1 }, /* 1 */
  639.69 +};
  639.70 +
  639.71 +static const static_bookblock _resbook_8u_0={
  639.72 +  {
  639.73 +    {0},
  639.74 +    {0,0,&_8u0__p1_0},
  639.75 +    {0,0,&_8u0__p2_0},
  639.76 +    {0,0,&_8u0__p3_0},
  639.77 +    {0,0,&_8u0__p4_0},
  639.78 +    {0,0,&_8u0__p5_0},
  639.79 +    {&_8u0__p6_0,&_8u0__p6_1},
  639.80 +    {&_8u0__p7_0,&_8u0__p7_1,&_8u0__p7_2}
  639.81 +   }
  639.82 +};
  639.83 +static const static_bookblock _resbook_8u_1={
  639.84 +  {
  639.85 +    {0},
  639.86 +    {0,0,&_8u1__p1_0},
  639.87 +    {0,0,&_8u1__p2_0},
  639.88 +    {0,0,&_8u1__p3_0},
  639.89 +    {0,0,&_8u1__p4_0},
  639.90 +    {0,0,&_8u1__p5_0},
  639.91 +    {0,0,&_8u1__p6_0},
  639.92 +    {&_8u1__p7_0,&_8u1__p7_1},
  639.93 +    {&_8u1__p8_0,&_8u1__p8_1},
  639.94 +    {&_8u1__p9_0,&_8u1__p9_1,&_8u1__p9_2}
  639.95 +   }
  639.96 +};
  639.97 +
  639.98 +static const vorbis_residue_template _res_8u_0[]={
  639.99 +  {1,0,32,  &_residue_44_low_un,
 639.100 +   &_huff_book__8u0__single,&_huff_book__8u0__single,
 639.101 +   &_resbook_8u_0,&_resbook_8u_0},
 639.102 +};
 639.103 +static const vorbis_residue_template _res_8u_1[]={
 639.104 +  {1,0,32,  &_residue_44_mid_un,
 639.105 +   &_huff_book__8u1__single,&_huff_book__8u1__single,
 639.106 +   &_resbook_8u_1,&_resbook_8u_1},
 639.107 +};
 639.108 +
 639.109 +static const vorbis_mapping_template _mapres_template_8_uncoupled[2]={
 639.110 +  { _map_nominal_u, _res_8u_0 }, /* 0 */
 639.111 +  { _map_nominal_u, _res_8u_1 }, /* 1 */
 639.112 +};
   640.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   640.2 +++ b/libs/vorbis/modes/setup_11.h	Sat Feb 01 19:58:19 2014 +0200
   640.3 @@ -0,0 +1,143 @@
   640.4 +/********************************************************************
   640.5 + *                                                                  *
   640.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   640.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   640.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   640.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  640.10 + *                                                                  *
  640.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  640.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  640.13 + *                                                                  *
  640.14 + ********************************************************************
  640.15 +
  640.16 + function: 11kHz settings
  640.17 + last mod: $Id: setup_11.h 16894 2010-02-12 20:32:12Z xiphmont $
  640.18 +
  640.19 + ********************************************************************/
  640.20 +
  640.21 +#include "psych_11.h"
  640.22 +
  640.23 +static const int blocksize_11[2]={
  640.24 +  512,512
  640.25 +};
  640.26 +
  640.27 +static const int _floor_mapping_11a[]={
  640.28 +  6,6
  640.29 +};
  640.30 +static const int *_floor_mapping_11[]={
  640.31 +  _floor_mapping_11a
  640.32 +};
  640.33 +
  640.34 +static const double rate_mapping_11[3]={
  640.35 +  8000.,13000.,44000.,
  640.36 +};
  640.37 +
  640.38 +static const double rate_mapping_11_uncoupled[3]={
  640.39 +  12000.,20000.,50000.,
  640.40 +};
  640.41 +
  640.42 +static const double quality_mapping_11[3]={
  640.43 +  -.1,.0,1.
  640.44 +};
  640.45 +
  640.46 +static const ve_setup_data_template ve_setup_11_stereo={
  640.47 +  2,
  640.48 +  rate_mapping_11,
  640.49 +  quality_mapping_11,
  640.50 +  2,
  640.51 +  9000,
  640.52 +  15000,
  640.53 +
  640.54 +  blocksize_11,
  640.55 +  blocksize_11,
  640.56 +
  640.57 +  _psy_tone_masteratt_11,
  640.58 +  _psy_tone_0dB,
  640.59 +  _psy_tone_suppress,
  640.60 +
  640.61 +  _vp_tonemask_adj_11,
  640.62 +  NULL,
  640.63 +  _vp_tonemask_adj_11,
  640.64 +
  640.65 +  _psy_noiseguards_8,
  640.66 +  _psy_noisebias_11,
  640.67 +  _psy_noisebias_11,
  640.68 +  NULL,
  640.69 +  NULL,
  640.70 +  _psy_noise_suppress,
  640.71 +
  640.72 +  _psy_compand_8,
  640.73 +  _psy_compand_8_mapping,
  640.74 +  NULL,
  640.75 +
  640.76 +  {_noise_start_8,_noise_start_8},
  640.77 +  {_noise_part_8,_noise_part_8},
  640.78 +  _noise_thresh_11,
  640.79 +
  640.80 +  _psy_ath_floater_8,
  640.81 +  _psy_ath_abs_8,
  640.82 +
  640.83 +  _psy_lowpass_11,
  640.84 +
  640.85 +  _psy_global_44,
  640.86 +  _global_mapping_8,
  640.87 +  _psy_stereo_modes_8,
  640.88 +
  640.89 +  _floor_books,
  640.90 +  _floor,
  640.91 +  1,
  640.92 +  _floor_mapping_11,
  640.93 +
  640.94 +  _mapres_template_8_stereo
  640.95 +};
  640.96 +
  640.97 +static const ve_setup_data_template ve_setup_11_uncoupled={
  640.98 +  2,
  640.99 +  rate_mapping_11_uncoupled,
 640.100 +  quality_mapping_11,
 640.101 +  -1,
 640.102 +  9000,
 640.103 +  15000,
 640.104 +
 640.105 +  blocksize_11,
 640.106 +  blocksize_11,
 640.107 +
 640.108 +  _psy_tone_masteratt_11,
 640.109 +  _psy_tone_0dB,
 640.110 +  _psy_tone_suppress,
 640.111 +
 640.112 +  _vp_tonemask_adj_11,
 640.113 +  NULL,
 640.114 +  _vp_tonemask_adj_11,
 640.115 +
 640.116 +  _psy_noiseguards_8,
 640.117 +  _psy_noisebias_11,
 640.118 +  _psy_noisebias_11,
 640.119 +  NULL,
 640.120 +  NULL,
 640.121 +  _psy_noise_suppress,
 640.122 +
 640.123 +  _psy_compand_8,
 640.124 +  _psy_compand_8_mapping,
 640.125 +  NULL,
 640.126 +
 640.127 +  {_noise_start_8,_noise_start_8},
 640.128 +  {_noise_part_8,_noise_part_8},
 640.129 +  _noise_thresh_11,
 640.130 +
 640.131 +  _psy_ath_floater_8,
 640.132 +  _psy_ath_abs_8,
 640.133 +
 640.134 +  _psy_lowpass_11,
 640.135 +
 640.136 +  _psy_global_44,
 640.137 +  _global_mapping_8,
 640.138 +  _psy_stereo_modes_8,
 640.139 +
 640.140 +  _floor_books,
 640.141 +  _floor,
 640.142 +  1,
 640.143 +  _floor_mapping_11,
 640.144 +
 640.145 +  _mapres_template_8_uncoupled
 640.146 +};
   641.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   641.2 +++ b/libs/vorbis/modes/setup_16.h	Sat Feb 01 19:58:19 2014 +0200
   641.3 @@ -0,0 +1,153 @@
   641.4 +/********************************************************************
   641.5 + *                                                                  *
   641.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   641.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   641.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   641.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  641.10 + *                                                                  *
  641.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  641.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  641.13 + *                                                                  *
  641.14 + ********************************************************************
  641.15 +
  641.16 + function: 16kHz settings
  641.17 + last mod: $Id: setup_16.h 16894 2010-02-12 20:32:12Z xiphmont $
  641.18 +
  641.19 + ********************************************************************/
  641.20 +
  641.21 +#include "psych_16.h"
  641.22 +#include "residue_16.h"
  641.23 +
  641.24 +static const int blocksize_16_short[3]={
  641.25 +  1024,512,512
  641.26 +};
  641.27 +static const int blocksize_16_long[3]={
  641.28 +  1024,1024,1024
  641.29 +};
  641.30 +
  641.31 +static const int _floor_mapping_16a[]={
  641.32 +  9,3,3
  641.33 +};
  641.34 +static const int _floor_mapping_16b[]={
  641.35 +  9,9,9
  641.36 +};
  641.37 +static const int *_floor_mapping_16[]={
  641.38 +  _floor_mapping_16a,
  641.39 +  _floor_mapping_16b
  641.40 +};
  641.41 +
  641.42 +static const double rate_mapping_16[4]={
  641.43 +  12000.,20000.,44000.,86000.
  641.44 +};
  641.45 +
  641.46 +static const double rate_mapping_16_uncoupled[4]={
  641.47 +  16000.,28000.,64000.,100000.
  641.48 +};
  641.49 +
  641.50 +static const double _global_mapping_16[4]={ 1., 2., 3., 4. };
  641.51 +
  641.52 +static const double quality_mapping_16[4]={ -.1,.05,.5,1. };
  641.53 +
  641.54 +static const double _psy_compand_16_mapping[4]={ 0., .8, 1., 1.};
  641.55 +
  641.56 +static const ve_setup_data_template ve_setup_16_stereo={
  641.57 +  3,
  641.58 +  rate_mapping_16,
  641.59 +  quality_mapping_16,
  641.60 +  2,
  641.61 +  15000,
  641.62 +  19000,
  641.63 +
  641.64 +  blocksize_16_short,
  641.65 +  blocksize_16_long,
  641.66 +
  641.67 +  _psy_tone_masteratt_16,
  641.68 +  _psy_tone_0dB,
  641.69 +  _psy_tone_suppress,
  641.70 +
  641.71 +  _vp_tonemask_adj_16,
  641.72 +  _vp_tonemask_adj_16,
  641.73 +  _vp_tonemask_adj_16,
  641.74 +
  641.75 +  _psy_noiseguards_16,
  641.76 +  _psy_noisebias_16_impulse,
  641.77 +  _psy_noisebias_16_short,
  641.78 +  _psy_noisebias_16_short,
  641.79 +  _psy_noisebias_16,
  641.80 +  _psy_noise_suppress,
  641.81 +
  641.82 +  _psy_compand_8,
  641.83 +  _psy_compand_16_mapping,
  641.84 +  _psy_compand_16_mapping,
  641.85 +
  641.86 +  {_noise_start_16,_noise_start_16},
  641.87 +  { _noise_part_16, _noise_part_16},
  641.88 +  _noise_thresh_16,
  641.89 +
  641.90 +  _psy_ath_floater_16,
  641.91 +  _psy_ath_abs_16,
  641.92 +
  641.93 +  _psy_lowpass_16,
  641.94 +
  641.95 +  _psy_global_44,
  641.96 +  _global_mapping_16,
  641.97 +  _psy_stereo_modes_16,
  641.98 +
  641.99 +  _floor_books,
 641.100 +  _floor,
 641.101 +  2,
 641.102 +  _floor_mapping_16,
 641.103 +
 641.104 +  _mapres_template_16_stereo
 641.105 +};
 641.106 +
 641.107 +static const ve_setup_data_template ve_setup_16_uncoupled={
 641.108 +  3,
 641.109 +  rate_mapping_16_uncoupled,
 641.110 +  quality_mapping_16,
 641.111 +  -1,
 641.112 +  15000,
 641.113 +  19000,
 641.114 +
 641.115 +  blocksize_16_short,
 641.116 +  blocksize_16_long,
 641.117 +
 641.118 +  _psy_tone_masteratt_16,
 641.119 +  _psy_tone_0dB,
 641.120 +  _psy_tone_suppress,
 641.121 +
 641.122 +  _vp_tonemask_adj_16,
 641.123 +  _vp_tonemask_adj_16,
 641.124 +  _vp_tonemask_adj_16,
 641.125 +
 641.126 +  _psy_noiseguards_16,
 641.127 +  _psy_noisebias_16_impulse,
 641.128 +  _psy_noisebias_16_short,
 641.129 +  _psy_noisebias_16_short,
 641.130 +  _psy_noisebias_16,
 641.131 +  _psy_noise_suppress,
 641.132 +
 641.133 +  _psy_compand_8,
 641.134 +  _psy_compand_16_mapping,
 641.135 +  _psy_compand_16_mapping,
 641.136 +
 641.137 +  {_noise_start_16,_noise_start_16},
 641.138 +  { _noise_part_16, _noise_part_16},
 641.139 +  _noise_thresh_16,
 641.140 +
 641.141 +  _psy_ath_floater_16,
 641.142 +  _psy_ath_abs_16,
 641.143 +
 641.144 +  _psy_lowpass_16,
 641.145 +
 641.146 +  _psy_global_44,
 641.147 +  _global_mapping_16,
 641.148 +  _psy_stereo_modes_16,
 641.149 +
 641.150 +  _floor_books,
 641.151 +  _floor,
 641.152 +  2,
 641.153 +  _floor_mapping_16,
 641.154 +
 641.155 +  _mapres_template_16_uncoupled
 641.156 +};
   642.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   642.2 +++ b/libs/vorbis/modes/setup_22.h	Sat Feb 01 19:58:19 2014 +0200
   642.3 @@ -0,0 +1,128 @@
   642.4 +/********************************************************************
   642.5 + *                                                                  *
   642.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   642.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   642.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   642.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  642.10 + *                                                                  *
  642.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  642.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  642.13 + *                                                                  *
  642.14 + ********************************************************************
  642.15 +
  642.16 + function: 22kHz settings
  642.17 + last mod: $Id: setup_22.h 17026 2010-03-25 05:00:27Z xiphmont $
  642.18 +
  642.19 + ********************************************************************/
  642.20 +
  642.21 +static const double rate_mapping_22[4]={
  642.22 +  15000.,20000.,44000.,86000.
  642.23 +};
  642.24 +
  642.25 +static const double rate_mapping_22_uncoupled[4]={
  642.26 +  16000.,28000.,50000.,90000.
  642.27 +};
  642.28 +
  642.29 +static const double _psy_lowpass_22[4]={9.5,11.,30.,99.};
  642.30 +
  642.31 +static const ve_setup_data_template ve_setup_22_stereo={
  642.32 +  3,
  642.33 +  rate_mapping_22,
  642.34 +  quality_mapping_16,
  642.35 +  2,
  642.36 +  19000,
  642.37 +  26000,
  642.38 +
  642.39 +  blocksize_16_short,
  642.40 +  blocksize_16_long,
  642.41 +
  642.42 +  _psy_tone_masteratt_16,
  642.43 +  _psy_tone_0dB,
  642.44 +  _psy_tone_suppress,
  642.45 +
  642.46 +  _vp_tonemask_adj_16,
  642.47 +  _vp_tonemask_adj_16,
  642.48 +  _vp_tonemask_adj_16,
  642.49 +
  642.50 +  _psy_noiseguards_16,
  642.51 +  _psy_noisebias_16_impulse,
  642.52 +  _psy_noisebias_16_short,
  642.53 +  _psy_noisebias_16_short,
  642.54 +  _psy_noisebias_16,
  642.55 +  _psy_noise_suppress,
  642.56 +
  642.57 +  _psy_compand_8,
  642.58 +  _psy_compand_16_mapping,
  642.59 +  _psy_compand_16_mapping,
  642.60 +
  642.61 +  {_noise_start_16,_noise_start_16},
  642.62 +  { _noise_part_16, _noise_part_16},
  642.63 +  _noise_thresh_16,
  642.64 +
  642.65 +  _psy_ath_floater_16,
  642.66 +  _psy_ath_abs_16,
  642.67 +
  642.68 +  _psy_lowpass_22,
  642.69 +
  642.70 +  _psy_global_44,
  642.71 +  _global_mapping_16,
  642.72 +  _psy_stereo_modes_16,
  642.73 +
  642.74 +  _floor_books,
  642.75 +  _floor,
  642.76 +  2,
  642.77 +  _floor_mapping_16,
  642.78 +
  642.79 +  _mapres_template_16_stereo
  642.80 +};
  642.81 +
  642.82 +static const ve_setup_data_template ve_setup_22_uncoupled={
  642.83 +  3,
  642.84 +  rate_mapping_22_uncoupled,
  642.85 +  quality_mapping_16,
  642.86 +  -1,
  642.87 +  19000,
  642.88 +  26000,
  642.89 +
  642.90 +  blocksize_16_short,
  642.91 +  blocksize_16_long,
  642.92 +
  642.93 +  _psy_tone_masteratt_16,
  642.94 +  _psy_tone_0dB,
  642.95 +  _psy_tone_suppress,
  642.96 +
  642.97 +  _vp_tonemask_adj_16,
  642.98 +  _vp_tonemask_adj_16,
  642.99 +  _vp_tonemask_adj_16,
 642.100 +
 642.101 +  _psy_noiseguards_16,
 642.102 +  _psy_noisebias_16_impulse,
 642.103 +  _psy_noisebias_16_short,
 642.104 +  _psy_noisebias_16_short,
 642.105 +  _psy_noisebias_16,
 642.106 +  _psy_noise_suppress,
 642.107 +
 642.108 +  _psy_compand_8,
 642.109 +  _psy_compand_16_mapping,
 642.110 +  _psy_compand_16_mapping,
 642.111 +
 642.112 +  {_noise_start_16,_noise_start_16},
 642.113 +  { _noise_part_16, _noise_part_16},
 642.114 +  _noise_thresh_16,
 642.115 +
 642.116 +  _psy_ath_floater_16,
 642.117 +  _psy_ath_abs_16,
 642.118 +
 642.119 +  _psy_lowpass_22,
 642.120 +
 642.121 +  _psy_global_44,
 642.122 +  _global_mapping_16,
 642.123 +  _psy_stereo_modes_16,
 642.124 +
 642.125 +  _floor_books,
 642.126 +  _floor,
 642.127 +  2,
 642.128 +  _floor_mapping_16,
 642.129 +
 642.130 +  _mapres_template_16_uncoupled
 642.131 +};
   643.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   643.2 +++ b/libs/vorbis/modes/setup_32.h	Sat Feb 01 19:58:19 2014 +0200
   643.3 @@ -0,0 +1,132 @@
   643.4 +/********************************************************************
   643.5 + *                                                                  *
   643.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   643.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   643.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   643.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  643.10 + *                                                                  *
  643.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  643.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  643.13 + *                                                                  *
  643.14 + ********************************************************************
  643.15 +
  643.16 + function: toplevel settings for 32kHz
  643.17 + last mod: $Id: setup_32.h 16894 2010-02-12 20:32:12Z xiphmont $
  643.18 +
  643.19 + ********************************************************************/
  643.20 +
  643.21 +static const double rate_mapping_32[12]={
  643.22 +  18000.,28000.,35000.,45000.,56000.,60000.,
  643.23 +  75000.,90000.,100000.,115000.,150000.,190000.,
  643.24 +};
  643.25 +
  643.26 +static const double rate_mapping_32_un[12]={
  643.27 +  30000.,42000.,52000.,64000.,72000.,78000.,
  643.28 +  86000.,92000.,110000.,120000.,140000.,190000.,
  643.29 +};
  643.30 +
  643.31 +static const double _psy_lowpass_32[12]={
  643.32 +  12.3,13.,13.,14.,15.,99.,99.,99.,99.,99.,99.,99.
  643.33 +};
  643.34 +
  643.35 +static const ve_setup_data_template ve_setup_32_stereo={
  643.36 +  11,
  643.37 +  rate_mapping_32,
  643.38 +  quality_mapping_44,
  643.39 +  2,
  643.40 +  26000,
  643.41 +  40000,
  643.42 +
  643.43 +  blocksize_short_44,
  643.44 +  blocksize_long_44,
  643.45 +
  643.46 +  _psy_tone_masteratt_44,
  643.47 +  _psy_tone_0dB,
  643.48 +  _psy_tone_suppress,
  643.49 +
  643.50 +  _vp_tonemask_adj_otherblock,
  643.51 +  _vp_tonemask_adj_longblock,
  643.52 +  _vp_tonemask_adj_otherblock,
  643.53 +
  643.54 +  _psy_noiseguards_44,
  643.55 +  _psy_noisebias_impulse,
  643.56 +  _psy_noisebias_padding,
  643.57 +  _psy_noisebias_trans,
  643.58 +  _psy_noisebias_long,
  643.59 +  _psy_noise_suppress,
  643.60 +
  643.61 +  _psy_compand_44,
  643.62 +  _psy_compand_short_mapping,
  643.63 +  _psy_compand_long_mapping,
  643.64 +
  643.65 +  {_noise_start_short_44,_noise_start_long_44},
  643.66 +  {_noise_part_short_44,_noise_part_long_44},
  643.67 +  _noise_thresh_44,
  643.68 +
  643.69 +  _psy_ath_floater,
  643.70 +  _psy_ath_abs,
  643.71 +
  643.72 +  _psy_lowpass_32,
  643.73 +
  643.74 +  _psy_global_44,
  643.75 +  _global_mapping_44,
  643.76 +  _psy_stereo_modes_44,
  643.77 +
  643.78 +  _floor_books,
  643.79 +  _floor,
  643.80 +  2,
  643.81 +  _floor_mapping_44,
  643.82 +
  643.83 +  _mapres_template_44_stereo
  643.84 +};
  643.85 +
  643.86 +static const ve_setup_data_template ve_setup_32_uncoupled={
  643.87 +  11,
  643.88 +  rate_mapping_32_un,
  643.89 +  quality_mapping_44,
  643.90 +  -1,
  643.91 +  26000,
  643.92 +  40000,
  643.93 +
  643.94 +  blocksize_short_44,
  643.95 +  blocksize_long_44,
  643.96 +
  643.97 +  _psy_tone_masteratt_44,
  643.98 +  _psy_tone_0dB,
  643.99 +  _psy_tone_suppress,
 643.100 +
 643.101 +  _vp_tonemask_adj_otherblock,
 643.102 +  _vp_tonemask_adj_longblock,
 643.103 +  _vp_tonemask_adj_otherblock,
 643.104 +
 643.105 +  _psy_noiseguards_44,
 643.106 +  _psy_noisebias_impulse,
 643.107 +  _psy_noisebias_padding,
 643.108 +  _psy_noisebias_trans,
 643.109 +  _psy_noisebias_long,
 643.110 +  _psy_noise_suppress,
 643.111 +
 643.112 +  _psy_compand_44,
 643.113 +  _psy_compand_short_mapping,
 643.114 +  _psy_compand_long_mapping,
 643.115 +
 643.116 +  {_noise_start_short_44,_noise_start_long_44},
 643.117 +  {_noise_part_short_44,_noise_part_long_44},
 643.118 +  _noise_thresh_44,
 643.119 +
 643.120 +  _psy_ath_floater,
 643.121 +  _psy_ath_abs,
 643.122 +
 643.123 +  _psy_lowpass_32,
 643.124 +
 643.125 +  _psy_global_44,
 643.126 +  _global_mapping_44,
 643.127 +  NULL,
 643.128 +
 643.129 +  _floor_books,
 643.130 +  _floor,
 643.131 +  2,
 643.132 +  _floor_mapping_44,
 643.133 +
 643.134 +  _mapres_template_44_uncoupled
 643.135 +};
   644.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   644.2 +++ b/libs/vorbis/modes/setup_44.h	Sat Feb 01 19:58:19 2014 +0200
   644.3 @@ -0,0 +1,117 @@
   644.4 +/********************************************************************
   644.5 + *                                                                  *
   644.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   644.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   644.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   644.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  644.10 + *                                                                  *
  644.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  644.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  644.13 + *                                                                  *
  644.14 + ********************************************************************
  644.15 +
  644.16 + function: toplevel settings for 44.1/48kHz
  644.17 + last mod: $Id: setup_44.h 16962 2010-03-11 07:30:34Z xiphmont $
  644.18 +
  644.19 + ********************************************************************/
  644.20 +
  644.21 +#include "modes/floor_all.h"
  644.22 +#include "modes/residue_44.h"
  644.23 +#include "modes/psych_44.h"
  644.24 +
  644.25 +static const double rate_mapping_44_stereo[12]={
  644.26 +  22500.,32000.,40000.,48000.,56000.,64000.,
  644.27 +  80000.,96000.,112000.,128000.,160000.,250001.
  644.28 +};
  644.29 +
  644.30 +static const double quality_mapping_44[12]={
  644.31 +  -.1,.0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1.0
  644.32 +};
  644.33 +
  644.34 +static const int blocksize_short_44[11]={
  644.35 +  512,256,256,256,256,256,256,256,256,256,256
  644.36 +};
  644.37 +static const int blocksize_long_44[11]={
  644.38 +  4096,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048
  644.39 +};
  644.40 +
  644.41 +static const double _psy_compand_short_mapping[12]={
  644.42 +  0.5, 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.
  644.43 +};
  644.44 +static const double _psy_compand_long_mapping[12]={
  644.45 +  3.5, 4., 4., 4.3, 4.6, 5., 5., 5., 5., 5., 5., 5.
  644.46 +};
  644.47 +
  644.48 +static const double _global_mapping_44[12]={
  644.49 +  /* 1., 1., 1.5, 2., 2., 2.5, 2.7, 3.0, 3.5, 4., 4. */
  644.50 + 0., 1., 1., 1.5, 2., 2., 2.5, 2.7, 3.0, 3.7, 4., 4.
  644.51 +};
  644.52 +
  644.53 +static const int _floor_mapping_44a[11]={
  644.54 +  1,0,0,2,2,4,5,5,5,5,5
  644.55 +};
  644.56 +
  644.57 +static const int _floor_mapping_44b[11]={
  644.58 +  8,7,7,7,7,7,7,7,7,7,7
  644.59 +};
  644.60 +
  644.61 +static const int _floor_mapping_44c[11]={
  644.62 +  10,10,10,10,10,10,10,10,10,10,10
  644.63 +};
  644.64 +
  644.65 +static const int *_floor_mapping_44[]={
  644.66 +  _floor_mapping_44a,
  644.67 +  _floor_mapping_44b,
  644.68 +  _floor_mapping_44c,
  644.69 +};
  644.70 +
  644.71 +static const ve_setup_data_template ve_setup_44_stereo={
  644.72 +  11,
  644.73 +  rate_mapping_44_stereo,
  644.74 +  quality_mapping_44,
  644.75 +  2,
  644.76 +  40000,
  644.77 +  50000,
  644.78 +
  644.79 +  blocksize_short_44,
  644.80 +  blocksize_long_44,
  644.81 +
  644.82 +  _psy_tone_masteratt_44,
  644.83 +  _psy_tone_0dB,
  644.84 +  _psy_tone_suppress,
  644.85 +
  644.86 +  _vp_tonemask_adj_otherblock,
  644.87 +  _vp_tonemask_adj_longblock,
  644.88 +  _vp_tonemask_adj_otherblock,
  644.89 +
  644.90 +  _psy_noiseguards_44,
  644.91 +  _psy_noisebias_impulse,
  644.92 +  _psy_noisebias_padding,
  644.93 +  _psy_noisebias_trans,
  644.94 +  _psy_noisebias_long,
  644.95 +  _psy_noise_suppress,
  644.96 +
  644.97 +  _psy_compand_44,
  644.98 +  _psy_compand_short_mapping,
  644.99 +  _psy_compand_long_mapping,
 644.100 +
 644.101 +  {_noise_start_short_44,_noise_start_long_44},
 644.102 +  {_noise_part_short_44,_noise_part_long_44},
 644.103 +  _noise_thresh_44,
 644.104 +
 644.105 +  _psy_ath_floater,
 644.106 +  _psy_ath_abs,
 644.107 +
 644.108 +  _psy_lowpass_44,
 644.109 +
 644.110 +  _psy_global_44,
 644.111 +  _global_mapping_44,
 644.112 +  _psy_stereo_modes_44,
 644.113 +
 644.114 +  _floor_books,
 644.115 +  _floor,
 644.116 +  2,
 644.117 +  _floor_mapping_44,
 644.118 +
 644.119 +  _mapres_template_44_stereo
 644.120 +};
   645.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   645.2 +++ b/libs/vorbis/modes/setup_44p51.h	Sat Feb 01 19:58:19 2014 +0200
   645.3 @@ -0,0 +1,74 @@
   645.4 +/********************************************************************
   645.5 + *                                                                  *
   645.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   645.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   645.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   645.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  645.10 + *                                                                  *
  645.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
  645.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  645.13 + *                                                                  *
  645.14 + ********************************************************************
  645.15 +
  645.16 + function: toplevel settings for 44.1/48kHz 5.1 surround modes
  645.17 + last mod: $Id$
  645.18 +
  645.19 + ********************************************************************/
  645.20 +
  645.21 +#include "modes/residue_44p51.h"
  645.22 +
  645.23 +static const double rate_mapping_44p51[12]={
  645.24 +  14000.,20000.,28000.,38000.,46000.,54000.,
  645.25 +  75000.,96000.,120000.,140000.,180000.,240001.
  645.26 +};
  645.27 +
  645.28 +static const ve_setup_data_template ve_setup_44_51={
  645.29 +  11,
  645.30 +  rate_mapping_44p51,
  645.31 +  quality_mapping_44,
  645.32 +  6,
  645.33 +  40000,
  645.34 +  70000,
  645.35 +
  645.36 +  blocksize_short_44,
  645.37 +  blocksize_long_44,
  645.38 +
  645.39 +  _psy_tone_masteratt_44,
  645.40 +  _psy_tone_0dB,
  645.41 +  _psy_tone_suppress,
  645.42 +
  645.43 +  _vp_tonemask_adj_otherblock,
  645.44 +  _vp_tonemask_adj_longblock,
  645.45 +  _vp_tonemask_adj_otherblock,
  645.46 +
  645.47 +  _psy_noiseguards_44,
  645.48 +  _psy_noisebias_impulse,
  645.49 +  _psy_noisebias_padding,
  645.50 +  _psy_noisebias_trans,
  645.51 +  _psy_noisebias_long,
  645.52 +  _psy_noise_suppress,
  645.53 +
  645.54 +  _psy_compand_44,
  645.55 +  _psy_compand_short_mapping,
  645.56 +  _psy_compand_long_mapping,
  645.57 +
  645.58 +  {_noise_start_short_44,_noise_start_long_44},
  645.59 +  {_noise_part_short_44,_noise_part_long_44},
  645.60 +  _noise_thresh_44,
  645.61 +
  645.62 +  _psy_ath_floater,
  645.63 +  _psy_ath_abs,
  645.64 +
  645.65 +  _psy_lowpass_44,
  645.66 +
  645.67 +  _psy_global_44,
  645.68 +  _global_mapping_44,
  645.69 +  _psy_stereo_modes_44,
  645.70 +
  645.71 +  _floor_books,
  645.72 +  _floor,
  645.73 +  3,
  645.74 +  _floor_mapping_44,
  645.75 +
  645.76 +  _mapres_template_44_51
  645.77 +};
   646.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   646.2 +++ b/libs/vorbis/modes/setup_44u.h	Sat Feb 01 19:58:19 2014 +0200
   646.3 @@ -0,0 +1,74 @@
   646.4 +/********************************************************************
   646.5 + *                                                                  *
   646.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   646.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   646.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   646.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  646.10 + *                                                                  *
  646.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  646.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  646.13 + *                                                                  *
  646.14 + ********************************************************************
  646.15 +
  646.16 + function: toplevel settings for 44.1/48kHz uncoupled modes
  646.17 + last mod: $Id: setup_44u.h 16962 2010-03-11 07:30:34Z xiphmont $
  646.18 +
  646.19 + ********************************************************************/
  646.20 +
  646.21 +#include "modes/residue_44u.h"
  646.22 +
  646.23 +static const double rate_mapping_44_un[12]={
  646.24 +  32000.,48000.,60000.,70000.,80000.,86000.,
  646.25 +  96000.,110000.,120000.,140000.,160000.,240001.
  646.26 +};
  646.27 +
  646.28 +static const ve_setup_data_template ve_setup_44_uncoupled={
  646.29 +  11,
  646.30 +  rate_mapping_44_un,
  646.31 +  quality_mapping_44,
  646.32 +  -1,
  646.33 +  40000,
  646.34 +  50000,
  646.35 +
  646.36 +  blocksize_short_44,
  646.37 +  blocksize_long_44,
  646.38 +
  646.39 +  _psy_tone_masteratt_44,
  646.40 +  _psy_tone_0dB,
  646.41 +  _psy_tone_suppress,
  646.42 +
  646.43 +  _vp_tonemask_adj_otherblock,
  646.44 +  _vp_tonemask_adj_longblock,
  646.45 +  _vp_tonemask_adj_otherblock,
  646.46 +
  646.47 +  _psy_noiseguards_44,
  646.48 +  _psy_noisebias_impulse,
  646.49 +  _psy_noisebias_padding,
  646.50 +  _psy_noisebias_trans,
  646.51 +  _psy_noisebias_long,
  646.52 +  _psy_noise_suppress,
  646.53 +
  646.54 +  _psy_compand_44,
  646.55 +  _psy_compand_short_mapping,
  646.56 +  _psy_compand_long_mapping,
  646.57 +
  646.58 +  {_noise_start_short_44,_noise_start_long_44},
  646.59 +  {_noise_part_short_44,_noise_part_long_44},
  646.60 +  _noise_thresh_44,
  646.61 +
  646.62 +  _psy_ath_floater,
  646.63 +  _psy_ath_abs,
  646.64 +
  646.65 +  _psy_lowpass_44,
  646.66 +
  646.67 +  _psy_global_44,
  646.68 +  _global_mapping_44,
  646.69 +  _psy_stereo_modes_44,
  646.70 +
  646.71 +  _floor_books,
  646.72 +  _floor,
  646.73 +  2,
  646.74 +  _floor_mapping_44,
  646.75 +
  646.76 +  _mapres_template_44_uncoupled
  646.77 +};
   647.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   647.2 +++ b/libs/vorbis/modes/setup_8.h	Sat Feb 01 19:58:19 2014 +0200
   647.3 @@ -0,0 +1,149 @@
   647.4 +/********************************************************************
   647.5 + *                                                                  *
   647.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   647.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   647.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   647.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  647.10 + *                                                                  *
  647.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  647.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  647.13 + *                                                                  *
  647.14 + ********************************************************************
  647.15 +
  647.16 + function: 8kHz settings
  647.17 + last mod: $Id: setup_8.h 16894 2010-02-12 20:32:12Z xiphmont $
  647.18 +
  647.19 + ********************************************************************/
  647.20 +
  647.21 +#include "psych_8.h"
  647.22 +#include "residue_8.h"
  647.23 +
  647.24 +static const int blocksize_8[2]={
  647.25 +  512,512
  647.26 +};
  647.27 +
  647.28 +static const int _floor_mapping_8a[]={
  647.29 +  6,6
  647.30 +};
  647.31 +
  647.32 +static const int *_floor_mapping_8[]={
  647.33 +  _floor_mapping_8a
  647.34 +};
  647.35 +
  647.36 +static const double rate_mapping_8[3]={
  647.37 +  6000.,9000.,32000.,
  647.38 +};
  647.39 +
  647.40 +static const double rate_mapping_8_uncoupled[3]={
  647.41 +  8000.,14000.,42000.,
  647.42 +};
  647.43 +
  647.44 +static const double quality_mapping_8[3]={
  647.45 +  -.1,.0,1.
  647.46 +};
  647.47 +
  647.48 +static const double _psy_compand_8_mapping[3]={ 0., 1., 1.};
  647.49 +
  647.50 +static const double _global_mapping_8[3]={ 1., 2., 3. };
  647.51 +
  647.52 +static const ve_setup_data_template ve_setup_8_stereo={
  647.53 +  2,
  647.54 +  rate_mapping_8,
  647.55 +  quality_mapping_8,
  647.56 +  2,
  647.57 +  8000,
  647.58 +  9000,
  647.59 +
  647.60 +  blocksize_8,
  647.61 +  blocksize_8,
  647.62 +
  647.63 +  _psy_tone_masteratt_8,
  647.64 +  _psy_tone_0dB,
  647.65 +  _psy_tone_suppress,
  647.66 +
  647.67 +  _vp_tonemask_adj_8,
  647.68 +  NULL,
  647.69 +  _vp_tonemask_adj_8,
  647.70 +
  647.71 +  _psy_noiseguards_8,
  647.72 +  _psy_noisebias_8,
  647.73 +  _psy_noisebias_8,
  647.74 +  NULL,
  647.75 +  NULL,
  647.76 +  _psy_noise_suppress,
  647.77 +
  647.78 +  _psy_compand_8,
  647.79 +  _psy_compand_8_mapping,
  647.80 +  NULL,
  647.81 +
  647.82 +  {_noise_start_8,_noise_start_8},
  647.83 +  {_noise_part_8,_noise_part_8},
  647.84 +  _noise_thresh_5only,
  647.85 +
  647.86 +  _psy_ath_floater_8,
  647.87 +  _psy_ath_abs_8,
  647.88 +
  647.89 +  _psy_lowpass_8,
  647.90 +
  647.91 +  _psy_global_44,
  647.92 +  _global_mapping_8,
  647.93 +  _psy_stereo_modes_8,
  647.94 +
  647.95 +  _floor_books,
  647.96 +  _floor,
  647.97 +  1,
  647.98 +  _floor_mapping_8,
  647.99 +
 647.100 +  _mapres_template_8_stereo
 647.101 +};
 647.102 +
 647.103 +static const ve_setup_data_template ve_setup_8_uncoupled={
 647.104 +  2,
 647.105 +  rate_mapping_8_uncoupled,
 647.106 +  quality_mapping_8,
 647.107 +  -1,
 647.108 +  8000,
 647.109 +  9000,
 647.110 +
 647.111 +  blocksize_8,
 647.112 +  blocksize_8,
 647.113 +
 647.114 +  _psy_tone_masteratt_8,
 647.115 +  _psy_tone_0dB,
 647.116 +  _psy_tone_suppress,
 647.117 +
 647.118 +  _vp_tonemask_adj_8,
 647.119 +  NULL,
 647.120 +  _vp_tonemask_adj_8,
 647.121 +
 647.122 +  _psy_noiseguards_8,
 647.123 +  _psy_noisebias_8,
 647.124 +  _psy_noisebias_8,
 647.125 +  NULL,
 647.126 +  NULL,
 647.127 +  _psy_noise_suppress,
 647.128 +
 647.129 +  _psy_compand_8,
 647.130 +  _psy_compand_8_mapping,
 647.131 +  NULL,
 647.132 +
 647.133 +  {_noise_start_8,_noise_start_8},
 647.134 +  {_noise_part_8,_noise_part_8},
 647.135 +  _noise_thresh_5only,
 647.136 +
 647.137 +  _psy_ath_floater_8,
 647.138 +  _psy_ath_abs_8,
 647.139 +
 647.140 +  _psy_lowpass_8,
 647.141 +
 647.142 +  _psy_global_44,
 647.143 +  _global_mapping_8,
 647.144 +  _psy_stereo_modes_8,
 647.145 +
 647.146 +  _floor_books,
 647.147 +  _floor,
 647.148 +  1,
 647.149 +  _floor_mapping_8,
 647.150 +
 647.151 +  _mapres_template_8_uncoupled
 647.152 +};
   648.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   648.2 +++ b/libs/vorbis/modes/setup_X.h	Sat Feb 01 19:58:19 2014 +0200
   648.3 @@ -0,0 +1,225 @@
   648.4 +/********************************************************************
   648.5 + *                                                                  *
   648.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   648.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   648.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   648.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  648.10 + *                                                                  *
  648.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  648.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  648.13 + *                                                                  *
  648.14 + ********************************************************************
  648.15 +
  648.16 + function: catch-all toplevel settings for q modes only
  648.17 + last mod: $Id: setup_X.h 16894 2010-02-12 20:32:12Z xiphmont $
  648.18 +
  648.19 + ********************************************************************/
  648.20 +
  648.21 +static const double rate_mapping_X[12]={
  648.22 +  -1.,-1.,-1.,-1.,-1.,-1.,
  648.23 +  -1.,-1.,-1.,-1.,-1.,-1.
  648.24 +};
  648.25 +
  648.26 +static const ve_setup_data_template ve_setup_X_stereo={
  648.27 +  11,
  648.28 +  rate_mapping_X,
  648.29 +  quality_mapping_44,
  648.30 +  2,
  648.31 +  50000,
  648.32 +  200000,
  648.33 +
  648.34 +  blocksize_short_44,
  648.35 +  blocksize_long_44,
  648.36 +
  648.37 +  _psy_tone_masteratt_44,
  648.38 +  _psy_tone_0dB,
  648.39 +  _psy_tone_suppress,
  648.40 +
  648.41 +  _vp_tonemask_adj_otherblock,
  648.42 +  _vp_tonemask_adj_longblock,
  648.43 +  _vp_tonemask_adj_otherblock,
  648.44 +
  648.45 +  _psy_noiseguards_44,
  648.46 +  _psy_noisebias_impulse,
  648.47 +  _psy_noisebias_padding,
  648.48 +  _psy_noisebias_trans,
  648.49 +  _psy_noisebias_long,
  648.50 +  _psy_noise_suppress,
  648.51 +
  648.52 +  _psy_compand_44,
  648.53 +  _psy_compand_short_mapping,
  648.54 +  _psy_compand_long_mapping,
  648.55 +
  648.56 +  {_noise_start_short_44,_noise_start_long_44},
  648.57 +  {_noise_part_short_44,_noise_part_long_44},
  648.58 +  _noise_thresh_44,
  648.59 +
  648.60 +  _psy_ath_floater,
  648.61 +  _psy_ath_abs,
  648.62 +
  648.63 +  _psy_lowpass_44,
  648.64 +
  648.65 +  _psy_global_44,
  648.66 +  _global_mapping_44,
  648.67 +  _psy_stereo_modes_44,
  648.68 +
  648.69 +  _floor_books,
  648.70 +  _floor,
  648.71 +  2,
  648.72 +  _floor_mapping_44,
  648.73 +
  648.74 +  _mapres_template_44_stereo
  648.75 +};
  648.76 +
  648.77 +static const ve_setup_data_template ve_setup_X_uncoupled={
  648.78 +  11,
  648.79 +  rate_mapping_X,
  648.80 +  quality_mapping_44,
  648.81 +  -1,
  648.82 +  50000,
  648.83 +  200000,
  648.84 +
  648.85 +  blocksize_short_44,
  648.86 +  blocksize_long_44,
  648.87 +
  648.88 +  _psy_tone_masteratt_44,
  648.89 +  _psy_tone_0dB,
  648.90 +  _psy_tone_suppress,
  648.91 +
  648.92 +  _vp_tonemask_adj_otherblock,
  648.93 +  _vp_tonemask_adj_longblock,
  648.94 +  _vp_tonemask_adj_otherblock,
  648.95 +
  648.96 +  _psy_noiseguards_44,
  648.97 +  _psy_noisebias_impulse,
  648.98 +  _psy_noisebias_padding,
  648.99 +  _psy_noisebias_trans,
 648.100 +  _psy_noisebias_long,
 648.101 +  _psy_noise_suppress,
 648.102 +
 648.103 +  _psy_compand_44,
 648.104 +  _psy_compand_short_mapping,
 648.105 +  _psy_compand_long_mapping,
 648.106 +
 648.107 +  {_noise_start_short_44,_noise_start_long_44},
 648.108 +  {_noise_part_short_44,_noise_part_long_44},
 648.109 +  _noise_thresh_44,
 648.110 +
 648.111 +  _psy_ath_floater,
 648.112 +  _psy_ath_abs,
 648.113 +
 648.114 +  _psy_lowpass_44,
 648.115 +
 648.116 +  _psy_global_44,
 648.117 +  _global_mapping_44,
 648.118 +  NULL,
 648.119 +
 648.120 +  _floor_books,
 648.121 +  _floor,
 648.122 +  2,
 648.123 +  _floor_mapping_44,
 648.124 +
 648.125 +  _mapres_template_44_uncoupled
 648.126 +};
 648.127 +
 648.128 +static const ve_setup_data_template ve_setup_XX_stereo={
 648.129 +  2,
 648.130 +  rate_mapping_X,
 648.131 +  quality_mapping_8,
 648.132 +  2,
 648.133 +  0,
 648.134 +  8000,
 648.135 +
 648.136 +  blocksize_8,
 648.137 +  blocksize_8,
 648.138 +
 648.139 +  _psy_tone_masteratt_8,
 648.140 +  _psy_tone_0dB,
 648.141 +  _psy_tone_suppress,
 648.142 +
 648.143 +  _vp_tonemask_adj_8,
 648.144 +  NULL,
 648.145 +  _vp_tonemask_adj_8,
 648.146 +
 648.147 +  _psy_noiseguards_8,
 648.148 +  _psy_noisebias_8,
 648.149 +  _psy_noisebias_8,
 648.150 +  NULL,
 648.151 +  NULL,
 648.152 +  _psy_noise_suppress,
 648.153 +
 648.154 +  _psy_compand_8,
 648.155 +  _psy_compand_8_mapping,
 648.156 +  NULL,
 648.157 +
 648.158 +  {_noise_start_8,_noise_start_8},
 648.159 +  {_noise_part_8,_noise_part_8},
 648.160 +  _noise_thresh_5only,
 648.161 +
 648.162 +  _psy_ath_floater_8,
 648.163 +  _psy_ath_abs_8,
 648.164 +
 648.165 +  _psy_lowpass_8,
 648.166 +
 648.167 +  _psy_global_44,
 648.168 +  _global_mapping_8,
 648.169 +  _psy_stereo_modes_8,
 648.170 +
 648.171 +  _floor_books,
 648.172 +  _floor,
 648.173 +  1,
 648.174 +  _floor_mapping_8,
 648.175 +
 648.176 +  _mapres_template_8_stereo
 648.177 +};
 648.178 +
 648.179 +static const ve_setup_data_template ve_setup_XX_uncoupled={
 648.180 +  2,
 648.181 +  rate_mapping_X,
 648.182 +  quality_mapping_8,
 648.183 +  -1,
 648.184 +  0,
 648.185 +  8000,
 648.186 +
 648.187 +  blocksize_8,
 648.188 +  blocksize_8,
 648.189 +
 648.190 +  _psy_tone_masteratt_8,
 648.191 +  _psy_tone_0dB,
 648.192 +  _psy_tone_suppress,
 648.193 +
 648.194 +  _vp_tonemask_adj_8,
 648.195 +  NULL,
 648.196 +  _vp_tonemask_adj_8,
 648.197 +
 648.198 +  _psy_noiseguards_8,
 648.199 +  _psy_noisebias_8,
 648.200 +  _psy_noisebias_8,
 648.201 +  NULL,
 648.202 +  NULL,
 648.203 +  _psy_noise_suppress,
 648.204 +
 648.205 +  _psy_compand_8,
 648.206 +  _psy_compand_8_mapping,
 648.207 +  NULL,
 648.208 +
 648.209 +  {_noise_start_8,_noise_start_8},
 648.210 +  {_noise_part_8,_noise_part_8},
 648.211 +  _noise_thresh_5only,
 648.212 +
 648.213 +  _psy_ath_floater_8,
 648.214 +  _psy_ath_abs_8,
 648.215 +
 648.216 +  _psy_lowpass_8,
 648.217 +
 648.218 +  _psy_global_44,
 648.219 +  _global_mapping_8,
 648.220 +  _psy_stereo_modes_8,
 648.221 +
 648.222 +  _floor_books,
 648.223 +  _floor,
 648.224 +  1,
 648.225 +  _floor_mapping_8,
 648.226 +
 648.227 +  _mapres_template_8_uncoupled
 648.228 +};
   649.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   649.2 +++ b/libs/vorbis/os.h	Sat Feb 01 19:58:19 2014 +0200
   649.3 @@ -0,0 +1,186 @@
   649.4 +#ifndef _OS_H
   649.5 +#define _OS_H
   649.6 +/********************************************************************
   649.7 + *                                                                  *
   649.8 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   649.9 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  649.10 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  649.11 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  649.12 + *                                                                  *
  649.13 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  649.14 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  649.15 + *                                                                  *
  649.16 + ********************************************************************
  649.17 +
  649.18 + function: #ifdef jail to whip a few platforms into the UNIX ideal.
  649.19 + last mod: $Id: os.h 16227 2009-07-08 06:58:46Z xiphmont $
  649.20 +
  649.21 + ********************************************************************/
  649.22 +
  649.23 +#ifdef HAVE_CONFIG_H
  649.24 +#include "config.h"
  649.25 +#endif
  649.26 +
  649.27 +#include <math.h>
  649.28 +#include <ogg/os_types.h>
  649.29 +
  649.30 +#include "misc.h"
  649.31 +
  649.32 +#ifndef _V_IFDEFJAIL_H_
  649.33 +#  define _V_IFDEFJAIL_H_
  649.34 +
  649.35 +#  ifdef __GNUC__
  649.36 +#    define STIN static __inline__
  649.37 +#  elif _WIN32
  649.38 +#    define STIN static __inline
  649.39 +#  else
  649.40 +#    define STIN static
  649.41 +#  endif
  649.42 +
  649.43 +#ifdef DJGPP
  649.44 +#  define rint(x)   (floor((x)+0.5f))
  649.45 +#endif
  649.46 +
  649.47 +#ifndef M_PI
  649.48 +#  define M_PI (3.1415926536f)
  649.49 +#endif
  649.50 +
  649.51 +#if defined(_WIN32) && !defined(__SYMBIAN32__)
  649.52 +#  include <malloc.h>
  649.53 +#  define rint(x)   (floor((x)+0.5f))
  649.54 +#  define NO_FLOAT_MATH_LIB
  649.55 +#  define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b))
  649.56 +#endif
  649.57 +
  649.58 +#if defined(__SYMBIAN32__) && defined(__WINS__)
  649.59 +void *_alloca(size_t size);
  649.60 +#  define alloca _alloca
  649.61 +#endif
  649.62 +
  649.63 +#ifndef FAST_HYPOT
  649.64 +#  define FAST_HYPOT hypot
  649.65 +#endif
  649.66 +
  649.67 +#endif
  649.68 +
  649.69 +#ifdef HAVE_ALLOCA_H
  649.70 +#  include <alloca.h>
  649.71 +#endif
  649.72 +
  649.73 +#ifdef USE_MEMORY_H
  649.74 +#  include <memory.h>
  649.75 +#endif
  649.76 +
  649.77 +#ifndef min
  649.78 +#  define min(x,y)  ((x)>(y)?(y):(x))
  649.79 +#endif
  649.80 +
  649.81 +#ifndef max
  649.82 +#  define max(x,y)  ((x)<(y)?(y):(x))
  649.83 +#endif
  649.84 +
  649.85 +
  649.86 +/* Special i386 GCC implementation */
  649.87 +#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__)
  649.88 +#  define VORBIS_FPU_CONTROL
  649.89 +/* both GCC and MSVC are kinda stupid about rounding/casting to int.
  649.90 +   Because of encapsulation constraints (GCC can't see inside the asm
  649.91 +   block and so we end up doing stupid things like a store/load that
  649.92 +   is collectively a noop), we do it this way */
  649.93 +
  649.94 +/* we must set up the fpu before this works!! */
  649.95 +
  649.96 +typedef ogg_int16_t vorbis_fpu_control;
  649.97 +
  649.98 +static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
  649.99 +  ogg_int16_t ret;
 649.100 +  ogg_int16_t temp;
 649.101 +  __asm__ __volatile__("fnstcw %0\n\t"
 649.102 +          "movw %0,%%dx\n\t"
 649.103 +          "andw $62463,%%dx\n\t"
 649.104 +          "movw %%dx,%1\n\t"
 649.105 +          "fldcw %1\n\t":"=m"(ret):"m"(temp): "dx");
 649.106 +  *fpu=ret;
 649.107 +}
 649.108 +
 649.109 +static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
 649.110 +  __asm__ __volatile__("fldcw %0":: "m"(fpu));
 649.111 +}
 649.112 +
 649.113 +/* assumes the FPU is in round mode! */
 649.114 +static inline int vorbis_ftoi(double f){  /* yes, double!  Otherwise,
 649.115 +                                             we get extra fst/fld to
 649.116 +                                             truncate precision */
 649.117 +  int i;
 649.118 +  __asm__("fistl %0": "=m"(i) : "t"(f));
 649.119 +  return(i);
 649.120 +}
 649.121 +#endif /* Special i386 GCC implementation */
 649.122 +
 649.123 +
 649.124 +/* MSVC inline assembly. 32 bit only; inline ASM isn't implemented in the
 649.125 + * 64 bit compiler */
 649.126 +#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_WIN32_WCE)
 649.127 +#  define VORBIS_FPU_CONTROL
 649.128 +
 649.129 +typedef ogg_int16_t vorbis_fpu_control;
 649.130 +
 649.131 +static __inline int vorbis_ftoi(double f){
 649.132 +        int i;
 649.133 +        __asm{
 649.134 +                fld f
 649.135 +                fistp i
 649.136 +        }
 649.137 +        return i;
 649.138 +}
 649.139 +
 649.140 +static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
 649.141 +}
 649.142 +
 649.143 +static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
 649.144 +}
 649.145 +
 649.146 +#endif /* Special MSVC 32 bit implementation */
 649.147 +
 649.148 +
 649.149 +/* Optimized code path for x86_64 builds. Uses SSE2 intrinsics. This can be
 649.150 +   done safely because all x86_64 CPUs supports SSE2. */
 649.151 +#if (defined(_MSC_VER) && defined(_WIN64)) || (defined(__GNUC__) && defined (__x86_64__))
 649.152 +#  define VORBIS_FPU_CONTROL
 649.153 +
 649.154 +typedef ogg_int16_t vorbis_fpu_control;
 649.155 +
 649.156 +#include <emmintrin.h>
 649.157 +static __inline int vorbis_ftoi(double f){
 649.158 +        return _mm_cvtsd_si32(_mm_load_sd(&f));
 649.159 +}
 649.160 +
 649.161 +static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
 649.162 +}
 649.163 +
 649.164 +static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
 649.165 +}
 649.166 +
 649.167 +#endif /* Special MSVC x64 implementation */
 649.168 +
 649.169 +
 649.170 +/* If no special implementation was found for the current compiler / platform,
 649.171 +   use the default implementation here: */
 649.172 +#ifndef VORBIS_FPU_CONTROL
 649.173 +
 649.174 +typedef int vorbis_fpu_control;
 649.175 +
 649.176 +static int vorbis_ftoi(double f){
 649.177 +        /* Note: MSVC and GCC (at least on some systems) round towards zero, thus,
 649.178 +           the floor() call is required to ensure correct roudning of
 649.179 +           negative numbers */
 649.180 +        return (int)floor(f+.5);
 649.181 +}
 649.182 +
 649.183 +/* We don't have special code for this compiler/arch, so do it the slow way */
 649.184 +#  define vorbis_fpu_setround(vorbis_fpu_control) {}
 649.185 +#  define vorbis_fpu_restore(vorbis_fpu_control) {}
 649.186 +
 649.187 +#endif /* default implementation */
 649.188 +
 649.189 +#endif /* _OS_H */
   650.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   650.2 +++ b/libs/vorbis/psy.c	Sat Feb 01 19:58:19 2014 +0200
   650.3 @@ -0,0 +1,1206 @@
   650.4 +/********************************************************************
   650.5 + *                                                                  *
   650.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   650.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   650.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   650.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  650.10 + *                                                                  *
  650.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
  650.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  650.13 + *                                                                  *
  650.14 + ********************************************************************
  650.15 +
  650.16 + function: psychoacoustics not including preecho
  650.17 + last mod: $Id: psy.c 18077 2011-09-02 02:49:00Z giles $
  650.18 +
  650.19 + ********************************************************************/
  650.20 +
  650.21 +#include <stdlib.h>
  650.22 +#include <math.h>
  650.23 +#include <string.h>
  650.24 +#include "vorbis/codec.h"
  650.25 +#include "codec_internal.h"
  650.26 +
  650.27 +#include "masking.h"
  650.28 +#include "psy.h"
  650.29 +#include "os.h"
  650.30 +#include "lpc.h"
  650.31 +#include "smallft.h"
  650.32 +#include "scales.h"
  650.33 +#include "misc.h"
  650.34 +
  650.35 +#define NEGINF -9999.f
  650.36 +static const double stereo_threshholds[]={0.0, .5, 1.0, 1.5, 2.5, 4.5, 8.5, 16.5, 9e10};
  650.37 +static const double stereo_threshholds_limited[]={0.0, .5, 1.0, 1.5, 2.0, 2.5, 4.5, 8.5, 9e10};
  650.38 +
  650.39 +vorbis_look_psy_global *_vp_global_look(vorbis_info *vi){
  650.40 +  codec_setup_info *ci=vi->codec_setup;
  650.41 +  vorbis_info_psy_global *gi=&ci->psy_g_param;
  650.42 +  vorbis_look_psy_global *look=_ogg_calloc(1,sizeof(*look));
  650.43 +
  650.44 +  look->channels=vi->channels;
  650.45 +
  650.46 +  look->ampmax=-9999.;
  650.47 +  look->gi=gi;
  650.48 +  return(look);
  650.49 +}
  650.50 +
  650.51 +void _vp_global_free(vorbis_look_psy_global *look){
  650.52 +  if(look){
  650.53 +    memset(look,0,sizeof(*look));
  650.54 +    _ogg_free(look);
  650.55 +  }
  650.56 +}
  650.57 +
  650.58 +void _vi_gpsy_free(vorbis_info_psy_global *i){
  650.59 +  if(i){
  650.60 +    memset(i,0,sizeof(*i));
  650.61 +    _ogg_free(i);
  650.62 +  }
  650.63 +}
  650.64 +
  650.65 +void _vi_psy_free(vorbis_info_psy *i){
  650.66 +  if(i){
  650.67 +    memset(i,0,sizeof(*i));
  650.68 +    _ogg_free(i);
  650.69 +  }
  650.70 +}
  650.71 +
  650.72 +static void min_curve(float *c,
  650.73 +                       float *c2){
  650.74 +  int i;
  650.75 +  for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i];
  650.76 +}
  650.77 +static void max_curve(float *c,
  650.78 +                       float *c2){
  650.79 +  int i;
  650.80 +  for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i];
  650.81 +}
  650.82 +
  650.83 +static void attenuate_curve(float *c,float att){
  650.84 +  int i;
  650.85 +  for(i=0;i<EHMER_MAX;i++)
  650.86 +    c[i]+=att;
  650.87 +}
  650.88 +
  650.89 +static float ***setup_tone_curves(float curveatt_dB[P_BANDS],float binHz,int n,
  650.90 +                                  float center_boost, float center_decay_rate){
  650.91 +  int i,j,k,m;
  650.92 +  float ath[EHMER_MAX];
  650.93 +  float workc[P_BANDS][P_LEVELS][EHMER_MAX];
  650.94 +  float athc[P_LEVELS][EHMER_MAX];
  650.95 +  float *brute_buffer=alloca(n*sizeof(*brute_buffer));
  650.96 +
  650.97 +  float ***ret=_ogg_malloc(sizeof(*ret)*P_BANDS);
  650.98 +
  650.99 +  memset(workc,0,sizeof(workc));
 650.100 +
 650.101 +  for(i=0;i<P_BANDS;i++){
 650.102 +    /* we add back in the ATH to avoid low level curves falling off to
 650.103 +       -infinity and unnecessarily cutting off high level curves in the
 650.104 +       curve limiting (last step). */
 650.105 +
 650.106 +    /* A half-band's settings must be valid over the whole band, and
 650.107 +       it's better to mask too little than too much */
 650.108 +    int ath_offset=i*4;
 650.109 +    for(j=0;j<EHMER_MAX;j++){
 650.110 +      float min=999.;
 650.111 +      for(k=0;k<4;k++)
 650.112 +        if(j+k+ath_offset<MAX_ATH){
 650.113 +          if(min>ATH[j+k+ath_offset])min=ATH[j+k+ath_offset];
 650.114 +        }else{
 650.115 +          if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1];
 650.116 +        }
 650.117 +      ath[j]=min;
 650.118 +    }
 650.119 +
 650.120 +    /* copy curves into working space, replicate the 50dB curve to 30
 650.121 +       and 40, replicate the 100dB curve to 110 */
 650.122 +    for(j=0;j<6;j++)
 650.123 +      memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j]));
 650.124 +    memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
 650.125 +    memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
 650.126 +
 650.127 +    /* apply centered curve boost/decay */
 650.128 +    for(j=0;j<P_LEVELS;j++){
 650.129 +      for(k=0;k<EHMER_MAX;k++){
 650.130 +        float adj=center_boost+abs(EHMER_OFFSET-k)*center_decay_rate;
 650.131 +        if(adj<0. && center_boost>0)adj=0.;
 650.132 +        if(adj>0. && center_boost<0)adj=0.;
 650.133 +        workc[i][j][k]+=adj;
 650.134 +      }
 650.135 +    }
 650.136 +
 650.137 +    /* normalize curves so the driving amplitude is 0dB */
 650.138 +    /* make temp curves with the ATH overlayed */
 650.139 +    for(j=0;j<P_LEVELS;j++){
 650.140 +      attenuate_curve(workc[i][j],curveatt_dB[i]+100.-(j<2?2:j)*10.-P_LEVEL_0);
 650.141 +      memcpy(athc[j],ath,EHMER_MAX*sizeof(**athc));
 650.142 +      attenuate_curve(athc[j],+100.-j*10.f-P_LEVEL_0);
 650.143 +      max_curve(athc[j],workc[i][j]);
 650.144 +    }
 650.145 +
 650.146 +    /* Now limit the louder curves.
 650.147 +
 650.148 +       the idea is this: We don't know what the playback attenuation
 650.149 +       will be; 0dB SL moves every time the user twiddles the volume
 650.150 +       knob. So that means we have to use a single 'most pessimal' curve
 650.151 +       for all masking amplitudes, right?  Wrong.  The *loudest* sound
 650.152 +       can be in (we assume) a range of ...+100dB] SL.  However, sounds
 650.153 +       20dB down will be in a range ...+80], 40dB down is from ...+60],
 650.154 +       etc... */
 650.155 +
 650.156 +    for(j=1;j<P_LEVELS;j++){
 650.157 +      min_curve(athc[j],athc[j-1]);
 650.158 +      min_curve(workc[i][j],athc[j]);
 650.159 +    }
 650.160 +  }
 650.161 +
 650.162 +  for(i=0;i<P_BANDS;i++){
 650.163 +    int hi_curve,lo_curve,bin;
 650.164 +    ret[i]=_ogg_malloc(sizeof(**ret)*P_LEVELS);
 650.165 +
 650.166 +    /* low frequency curves are measured with greater resolution than
 650.167 +       the MDCT/FFT will actually give us; we want the curve applied
 650.168 +       to the tone data to be pessimistic and thus apply the minimum
 650.169 +       masking possible for a given bin.  That means that a single bin
 650.170 +       could span more than one octave and that the curve will be a
 650.171 +       composite of multiple octaves.  It also may mean that a single
 650.172 +       bin may span > an eighth of an octave and that the eighth
 650.173 +       octave values may also be composited. */
 650.174 +
 650.175 +    /* which octave curves will we be compositing? */
 650.176 +    bin=floor(fromOC(i*.5)/binHz);
 650.177 +    lo_curve=  ceil(toOC(bin*binHz+1)*2);
 650.178 +    hi_curve=  floor(toOC((bin+1)*binHz)*2);
 650.179 +    if(lo_curve>i)lo_curve=i;
 650.180 +    if(lo_curve<0)lo_curve=0;
 650.181 +    if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1;
 650.182 +
 650.183 +    for(m=0;m<P_LEVELS;m++){
 650.184 +      ret[i][m]=_ogg_malloc(sizeof(***ret)*(EHMER_MAX+2));
 650.185 +
 650.186 +      for(j=0;j<n;j++)brute_buffer[j]=999.;
 650.187 +
 650.188 +      /* render the curve into bins, then pull values back into curve.
 650.189 +         The point is that any inherent subsampling aliasing results in
 650.190 +         a safe minimum */
 650.191 +      for(k=lo_curve;k<=hi_curve;k++){
 650.192 +        int l=0;
 650.193 +
 650.194 +        for(j=0;j<EHMER_MAX;j++){
 650.195 +          int lo_bin= fromOC(j*.125+k*.5-2.0625)/binHz;
 650.196 +          int hi_bin= fromOC(j*.125+k*.5-1.9375)/binHz+1;
 650.197 +
 650.198 +          if(lo_bin<0)lo_bin=0;
 650.199 +          if(lo_bin>n)lo_bin=n;
 650.200 +          if(lo_bin<l)l=lo_bin;
 650.201 +          if(hi_bin<0)hi_bin=0;
 650.202 +          if(hi_bin>n)hi_bin=n;
 650.203 +
 650.204 +          for(;l<hi_bin && l<n;l++)
 650.205 +            if(brute_buffer[l]>workc[k][m][j])
 650.206 +              brute_buffer[l]=workc[k][m][j];
 650.207 +        }
 650.208 +
 650.209 +        for(;l<n;l++)
 650.210 +          if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
 650.211 +            brute_buffer[l]=workc[k][m][EHMER_MAX-1];
 650.212 +
 650.213 +      }
 650.214 +
 650.215 +      /* be equally paranoid about being valid up to next half ocatve */
 650.216 +      if(i+1<P_BANDS){
 650.217 +        int l=0;
 650.218 +        k=i+1;
 650.219 +        for(j=0;j<EHMER_MAX;j++){
 650.220 +          int lo_bin= fromOC(j*.125+i*.5-2.0625)/binHz;
 650.221 +          int hi_bin= fromOC(j*.125+i*.5-1.9375)/binHz+1;
 650.222 +
 650.223 +          if(lo_bin<0)lo_bin=0;
 650.224 +          if(lo_bin>n)lo_bin=n;
 650.225 +          if(lo_bin<l)l=lo_bin;
 650.226 +          if(hi_bin<0)hi_bin=0;
 650.227 +          if(hi_bin>n)hi_bin=n;
 650.228 +
 650.229 +          for(;l<hi_bin && l<n;l++)
 650.230 +            if(brute_buffer[l]>workc[k][m][j])
 650.231 +              brute_buffer[l]=workc[k][m][j];
 650.232 +        }
 650.233 +
 650.234 +        for(;l<n;l++)
 650.235 +          if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
 650.236 +            brute_buffer[l]=workc[k][m][EHMER_MAX-1];
 650.237 +
 650.238 +      }
 650.239 +
 650.240 +
 650.241 +      for(j=0;j<EHMER_MAX;j++){
 650.242 +        int bin=fromOC(j*.125+i*.5-2.)/binHz;
 650.243 +        if(bin<0){
 650.244 +          ret[i][m][j+2]=-999.;
 650.245 +        }else{
 650.246 +          if(bin>=n){
 650.247 +            ret[i][m][j+2]=-999.;
 650.248 +          }else{
 650.249 +            ret[i][m][j+2]=brute_buffer[bin];
 650.250 +          }
 650.251 +        }
 650.252 +      }
 650.253 +
 650.254 +      /* add fenceposts */
 650.255 +      for(j=0;j<EHMER_OFFSET;j++)
 650.256 +        if(ret[i][m][j+2]>-200.f)break;
 650.257 +      ret[i][m][0]=j;
 650.258 +
 650.259 +      for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--)
 650.260 +        if(ret[i][m][j+2]>-200.f)
 650.261 +          break;
 650.262 +      ret[i][m][1]=j;
 650.263 +
 650.264 +    }
 650.265 +  }
 650.266 +
 650.267 +  return(ret);
 650.268 +}
 650.269 +
 650.270 +void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
 650.271 +                  vorbis_info_psy_global *gi,int n,long rate){
 650.272 +  long i,j,lo=-99,hi=1;
 650.273 +  long maxoc;
 650.274 +  memset(p,0,sizeof(*p));
 650.275 +
 650.276 +  p->eighth_octave_lines=gi->eighth_octave_lines;
 650.277 +  p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1;
 650.278 +
 650.279 +  p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines;
 650.280 +  maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f;
 650.281 +  p->total_octave_lines=maxoc-p->firstoc+1;
 650.282 +  p->ath=_ogg_malloc(n*sizeof(*p->ath));
 650.283 +
 650.284 +  p->octave=_ogg_malloc(n*sizeof(*p->octave));
 650.285 +  p->bark=_ogg_malloc(n*sizeof(*p->bark));
 650.286 +  p->vi=vi;
 650.287 +  p->n=n;
 650.288 +  p->rate=rate;
 650.289 +
 650.290 +  /* AoTuV HF weighting */
 650.291 +  p->m_val = 1.;
 650.292 +  if(rate < 26000) p->m_val = 0;
 650.293 +  else if(rate < 38000) p->m_val = .94;   /* 32kHz */
 650.294 +  else if(rate > 46000) p->m_val = 1.275; /* 48kHz */
 650.295 +
 650.296 +  /* set up the lookups for a given blocksize and sample rate */
 650.297 +
 650.298 +  for(i=0,j=0;i<MAX_ATH-1;i++){
 650.299 +    int endpos=rint(fromOC((i+1)*.125-2.)*2*n/rate);
 650.300 +    float base=ATH[i];
 650.301 +    if(j<endpos){
 650.302 +      float delta=(ATH[i+1]-base)/(endpos-j);
 650.303 +      for(;j<endpos && j<n;j++){
 650.304 +        p->ath[j]=base+100.;
 650.305 +        base+=delta;
 650.306 +      }
 650.307 +    }
 650.308 +  }
 650.309 +
 650.310 +  for(;j<n;j++){
 650.311 +    p->ath[j]=p->ath[j-1];
 650.312 +  }
 650.313 +
 650.314 +  for(i=0;i<n;i++){
 650.315 +    float bark=toBARK(rate/(2*n)*i);
 650.316 +
 650.317 +    for(;lo+vi->noisewindowlomin<i &&
 650.318 +          toBARK(rate/(2*n)*lo)<(bark-vi->noisewindowlo);lo++);
 650.319 +
 650.320 +    for(;hi<=n && (hi<i+vi->noisewindowhimin ||
 650.321 +          toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++);
 650.322 +
 650.323 +    p->bark[i]=((lo-1)<<16)+(hi-1);
 650.324 +
 650.325 +  }
 650.326 +
 650.327 +  for(i=0;i<n;i++)
 650.328 +    p->octave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f;
 650.329 +
 650.330 +  p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n,
 650.331 +                                  vi->tone_centerboost,vi->tone_decay);
 650.332 +
 650.333 +  /* set up rolling noise median */
 650.334 +  p->noiseoffset=_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset));
 650.335 +  for(i=0;i<P_NOISECURVES;i++)
 650.336 +    p->noiseoffset[i]=_ogg_malloc(n*sizeof(**p->noiseoffset));
 650.337 +
 650.338 +  for(i=0;i<n;i++){
 650.339 +    float halfoc=toOC((i+.5)*rate/(2.*n))*2.;
 650.340 +    int inthalfoc;
 650.341 +    float del;
 650.342 +
 650.343 +    if(halfoc<0)halfoc=0;
 650.344 +    if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
 650.345 +    inthalfoc=(int)halfoc;
 650.346 +    del=halfoc-inthalfoc;
 650.347 +
 650.348 +    for(j=0;j<P_NOISECURVES;j++)
 650.349 +      p->noiseoffset[j][i]=
 650.350 +        p->vi->noiseoff[j][inthalfoc]*(1.-del) +
 650.351 +        p->vi->noiseoff[j][inthalfoc+1]*del;
 650.352 +
 650.353 +  }
 650.354 +#if 0
 650.355 +  {
 650.356 +    static int ls=0;
 650.357 +    _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0);
 650.358 +    _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0);
 650.359 +    _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0);
 650.360 +  }
 650.361 +#endif
 650.362 +}
 650.363 +
 650.364 +void _vp_psy_clear(vorbis_look_psy *p){
 650.365 +  int i,j;
 650.366 +  if(p){
 650.367 +    if(p->ath)_ogg_free(p->ath);
 650.368 +    if(p->octave)_ogg_free(p->octave);
 650.369 +    if(p->bark)_ogg_free(p->bark);
 650.370 +    if(p->tonecurves){
 650.371 +      for(i=0;i<P_BANDS;i++){
 650.372 +        for(j=0;j<P_LEVELS;j++){
 650.373 +          _ogg_free(p->tonecurves[i][j]);
 650.374 +        }
 650.375 +        _ogg_free(p->tonecurves[i]);
 650.376 +      }
 650.377 +      _ogg_free(p->tonecurves);
 650.378 +    }
 650.379 +    if(p->noiseoffset){
 650.380 +      for(i=0;i<P_NOISECURVES;i++){
 650.381 +        _ogg_free(p->noiseoffset[i]);
 650.382 +      }
 650.383 +      _ogg_free(p->noiseoffset);
 650.384 +    }
 650.385 +    memset(p,0,sizeof(*p));
 650.386 +  }
 650.387 +}
 650.388 +
 650.389 +/* octave/(8*eighth_octave_lines) x scale and dB y scale */
 650.390 +static void seed_curve(float *seed,
 650.391 +                       const float **curves,
 650.392 +                       float amp,
 650.393 +                       int oc, int n,
 650.394 +                       int linesper,float dBoffset){
 650.395 +  int i,post1;
 650.396 +  int seedptr;
 650.397 +  const float *posts,*curve;
 650.398 +
 650.399 +  int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f);
 650.400 +  choice=max(choice,0);
 650.401 +  choice=min(choice,P_LEVELS-1);
 650.402 +  posts=curves[choice];
 650.403 +  curve=posts+2;
 650.404 +  post1=(int)posts[1];
 650.405 +  seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1);
 650.406 +
 650.407 +  for(i=posts[0];i<post1;i++){
 650.408 +    if(seedptr>0){
 650.409 +      float lin=amp+curve[i];
 650.410 +      if(seed[seedptr]<lin)seed[seedptr]=lin;
 650.411 +    }
 650.412 +    seedptr+=linesper;
 650.413 +    if(seedptr>=n)break;
 650.414 +  }
 650.415 +}
 650.416 +
 650.417 +static void seed_loop(vorbis_look_psy *p,
 650.418 +                      const float ***curves,
 650.419 +                      const float *f,
 650.420 +                      const float *flr,
 650.421 +                      float *seed,
 650.422 +                      float specmax){
 650.423 +  vorbis_info_psy *vi=p->vi;
 650.424 +  long n=p->n,i;
 650.425 +  float dBoffset=vi->max_curve_dB-specmax;
 650.426 +
 650.427 +  /* prime the working vector with peak values */
 650.428 +
 650.429 +  for(i=0;i<n;i++){
 650.430 +    float max=f[i];
 650.431 +    long oc=p->octave[i];
 650.432 +    while(i+1<n && p->octave[i+1]==oc){
 650.433 +      i++;
 650.434 +      if(f[i]>max)max=f[i];
 650.435 +    }
 650.436 +
 650.437 +    if(max+6.f>flr[i]){
 650.438 +      oc=oc>>p->shiftoc;
 650.439 +
 650.440 +      if(oc>=P_BANDS)oc=P_BANDS-1;
 650.441 +      if(oc<0)oc=0;
 650.442 +
 650.443 +      seed_curve(seed,
 650.444 +                 curves[oc],
 650.445 +                 max,
 650.446 +                 p->octave[i]-p->firstoc,
 650.447 +                 p->total_octave_lines,
 650.448 +                 p->eighth_octave_lines,
 650.449 +                 dBoffset);
 650.450 +    }
 650.451 +  }
 650.452 +}
 650.453 +
 650.454 +static void seed_chase(float *seeds, int linesper, long n){
 650.455 +  long  *posstack=alloca(n*sizeof(*posstack));
 650.456 +  float *ampstack=alloca(n*sizeof(*ampstack));
 650.457 +  long   stack=0;
 650.458 +  long   pos=0;
 650.459 +  long   i;
 650.460 +
 650.461 +  for(i=0;i<n;i++){
 650.462 +    if(stack<2){
 650.463 +      posstack[stack]=i;
 650.464 +      ampstack[stack++]=seeds[i];
 650.465 +    }else{
 650.466 +      while(1){
 650.467 +        if(seeds[i]<ampstack[stack-1]){
 650.468 +          posstack[stack]=i;
 650.469 +          ampstack[stack++]=seeds[i];
 650.470 +          break;
 650.471 +        }else{
 650.472 +          if(i<posstack[stack-1]+linesper){
 650.473 +            if(stack>1 && ampstack[stack-1]<=ampstack[stack-2] &&
 650.474 +               i<posstack[stack-2]+linesper){
 650.475 +              /* we completely overlap, making stack-1 irrelevant.  pop it */
 650.476 +              stack--;
 650.477 +              continue;
 650.478 +            }
 650.479 +          }
 650.480 +          posstack[stack]=i;
 650.481 +          ampstack[stack++]=seeds[i];
 650.482 +          break;
 650.483 +
 650.484 +        }
 650.485 +      }
 650.486 +    }
 650.487 +  }
 650.488 +
 650.489 +  /* the stack now contains only the positions that are relevant. Scan
 650.490 +     'em straight through */
 650.491 +
 650.492 +  for(i=0;i<stack;i++){
 650.493 +    long endpos;
 650.494 +    if(i<stack-1 && ampstack[i+1]>ampstack[i]){
 650.495 +      endpos=posstack[i+1];
 650.496 +    }else{
 650.497 +      endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is
 650.498 +                                        discarded in short frames */
 650.499 +    }
 650.500 +    if(endpos>n)endpos=n;
 650.501 +    for(;pos<endpos;pos++)
 650.502 +      seeds[pos]=ampstack[i];
 650.503 +  }
 650.504 +
 650.505 +  /* there.  Linear time.  I now remember this was on a problem set I
 650.506 +     had in Grad Skool... I didn't solve it at the time ;-) */
 650.507 +
 650.508 +}
 650.509 +
 650.510 +/* bleaugh, this is more complicated than it needs to be */
 650.511 +#include<stdio.h>
 650.512 +static void max_seeds(vorbis_look_psy *p,
 650.513 +                      float *seed,
 650.514 +                      float *flr){
 650.515 +  long   n=p->total_octave_lines;
 650.516 +  int    linesper=p->eighth_octave_lines;
 650.517 +  long   linpos=0;
 650.518 +  long   pos;
 650.519 +
 650.520 +  seed_chase(seed,linesper,n); /* for masking */
 650.521 +
 650.522 +  pos=p->octave[0]-p->firstoc-(linesper>>1);
 650.523 +
 650.524 +  while(linpos+1<p->n){
 650.525 +    float minV=seed[pos];
 650.526 +    long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc;
 650.527 +    if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit;
 650.528 +    while(pos+1<=end){
 650.529 +      pos++;
 650.530 +      if((seed[pos]>NEGINF && seed[pos]<minV) || minV==NEGINF)
 650.531 +        minV=seed[pos];
 650.532 +    }
 650.533 +
 650.534 +    end=pos+p->firstoc;
 650.535 +    for(;linpos<p->n && p->octave[linpos]<=end;linpos++)
 650.536 +      if(flr[linpos]<minV)flr[linpos]=minV;
 650.537 +  }
 650.538 +
 650.539 +  {
 650.540 +    float minV=seed[p->total_octave_lines-1];
 650.541 +    for(;linpos<p->n;linpos++)
 650.542 +      if(flr[linpos]<minV)flr[linpos]=minV;
 650.543 +  }
 650.544 +
 650.545 +}
 650.546 +
 650.547 +static void bark_noise_hybridmp(int n,const long *b,
 650.548 +                                const float *f,
 650.549 +                                float *noise,
 650.550 +                                const float offset,
 650.551 +                                const int fixed){
 650.552 +
 650.553 +  float *N=alloca(n*sizeof(*N));
 650.554 +  float *X=alloca(n*sizeof(*N));
 650.555 +  float *XX=alloca(n*sizeof(*N));
 650.556 +  float *Y=alloca(n*sizeof(*N));
 650.557 +  float *XY=alloca(n*sizeof(*N));
 650.558 +
 650.559 +  float tN, tX, tXX, tY, tXY;
 650.560 +  int i;
 650.561 +
 650.562 +  int lo, hi;
 650.563 +  float R=0.f;
 650.564 +  float A=0.f;
 650.565 +  float B=0.f;
 650.566 +  float D=1.f;
 650.567 +  float w, x, y;
 650.568 +
 650.569 +  tN = tX = tXX = tY = tXY = 0.f;
 650.570 +
 650.571 +  y = f[0] + offset;
 650.572 +  if (y < 1.f) y = 1.f;
 650.573 +
 650.574 +  w = y * y * .5;
 650.575 +
 650.576 +  tN += w;
 650.577 +  tX += w;
 650.578 +  tY += w * y;
 650.579 +
 650.580 +  N[0] = tN;
 650.581 +  X[0] = tX;
 650.582 +  XX[0] = tXX;
 650.583 +  Y[0] = tY;
 650.584 +  XY[0] = tXY;
 650.585 +
 650.586 +  for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
 650.587 +
 650.588 +    y = f[i] + offset;
 650.589 +    if (y < 1.f) y = 1.f;
 650.590 +
 650.591 +    w = y * y;
 650.592 +
 650.593 +    tN += w;
 650.594 +    tX += w * x;
 650.595 +    tXX += w * x * x;
 650.596 +    tY += w * y;
 650.597 +    tXY += w * x * y;
 650.598 +
 650.599 +    N[i] = tN;
 650.600 +    X[i] = tX;
 650.601 +    XX[i] = tXX;
 650.602 +    Y[i] = tY;
 650.603 +    XY[i] = tXY;
 650.604 +  }
 650.605 +
 650.606 +  for (i = 0, x = 0.f;; i++, x += 1.f) {
 650.607 +
 650.608 +    lo = b[i] >> 16;
 650.609 +    if( lo>=0 ) break;
 650.610 +    hi = b[i] & 0xffff;
 650.611 +
 650.612 +    tN = N[hi] + N[-lo];
 650.613 +    tX = X[hi] - X[-lo];
 650.614 +    tXX = XX[hi] + XX[-lo];
 650.615 +    tY = Y[hi] + Y[-lo];
 650.616 +    tXY = XY[hi] - XY[-lo];
 650.617 +
 650.618 +    A = tY * tXX - tX * tXY;
 650.619 +    B = tN * tXY - tX * tY;
 650.620 +    D = tN * tXX - tX * tX;
 650.621 +    R = (A + x * B) / D;
 650.622 +    if (R < 0.f)
 650.623 +      R = 0.f;
 650.624 +
 650.625 +    noise[i] = R - offset;
 650.626 +  }
 650.627 +
 650.628 +  for ( ;; i++, x += 1.f) {
 650.629 +
 650.630 +    lo = b[i] >> 16;
 650.631 +    hi = b[i] & 0xffff;
 650.632 +    if(hi>=n)break;
 650.633 +
 650.634 +    tN = N[hi] - N[lo];
 650.635 +    tX = X[hi] - X[lo];
 650.636 +    tXX = XX[hi] - XX[lo];
 650.637 +    tY = Y[hi] - Y[lo];
 650.638 +    tXY = XY[hi] - XY[lo];
 650.639 +
 650.640 +    A = tY * tXX - tX * tXY;
 650.641 +    B = tN * tXY - tX * tY;
 650.642 +    D = tN * tXX - tX * tX;
 650.643 +    R = (A + x * B) / D;
 650.644 +    if (R < 0.f) R = 0.f;
 650.645 +
 650.646 +    noise[i] = R - offset;
 650.647 +  }
 650.648 +  for ( ; i < n; i++, x += 1.f) {
 650.649 +
 650.650 +    R = (A + x * B) / D;
 650.651 +    if (R < 0.f) R = 0.f;
 650.652 +
 650.653 +    noise[i] = R - offset;
 650.654 +  }
 650.655 +
 650.656 +  if (fixed <= 0) return;
 650.657 +
 650.658 +  for (i = 0, x = 0.f;; i++, x += 1.f) {
 650.659 +    hi = i + fixed / 2;
 650.660 +    lo = hi - fixed;
 650.661 +    if(lo>=0)break;
 650.662 +
 650.663 +    tN = N[hi] + N[-lo];
 650.664 +    tX = X[hi] - X[-lo];
 650.665 +    tXX = XX[hi] + XX[-lo];
 650.666 +    tY = Y[hi] + Y[-lo];
 650.667 +    tXY = XY[hi] - XY[-lo];
 650.668 +
 650.669 +
 650.670 +    A = tY * tXX - tX * tXY;
 650.671 +    B = tN * tXY - tX * tY;
 650.672 +    D = tN * tXX - tX * tX;
 650.673 +    R = (A + x * B) / D;
 650.674 +
 650.675 +    if (R - offset < noise[i]) noise[i] = R - offset;
 650.676 +  }
 650.677 +  for ( ;; i++, x += 1.f) {
 650.678 +
 650.679 +    hi = i + fixed / 2;
 650.680 +    lo = hi - fixed;
 650.681 +    if(hi>=n)break;
 650.682 +
 650.683 +    tN = N[hi] - N[lo];
 650.684 +    tX = X[hi] - X[lo];
 650.685 +    tXX = XX[hi] - XX[lo];
 650.686 +    tY = Y[hi] - Y[lo];
 650.687 +    tXY = XY[hi] - XY[lo];
 650.688 +
 650.689 +    A = tY * tXX - tX * tXY;
 650.690 +    B = tN * tXY - tX * tY;
 650.691 +    D = tN * tXX - tX * tX;
 650.692 +    R = (A + x * B) / D;
 650.693 +
 650.694 +    if (R - offset < noise[i]) noise[i] = R - offset;
 650.695 +  }
 650.696 +  for ( ; i < n; i++, x += 1.f) {
 650.697 +    R = (A + x * B) / D;
 650.698 +    if (R - offset < noise[i]) noise[i] = R - offset;
 650.699 +  }
 650.700 +}
 650.701 +
 650.702 +void _vp_noisemask(vorbis_look_psy *p,
 650.703 +                   float *logmdct,
 650.704 +                   float *logmask){
 650.705 +
 650.706 +  int i,n=p->n;
 650.707 +  float *work=alloca(n*sizeof(*work));
 650.708 +
 650.709 +  bark_noise_hybridmp(n,p->bark,logmdct,logmask,
 650.710 +                      140.,-1);
 650.711 +
 650.712 +  for(i=0;i<n;i++)work[i]=logmdct[i]-logmask[i];
 650.713 +
 650.714 +  bark_noise_hybridmp(n,p->bark,work,logmask,0.,
 650.715 +                      p->vi->noisewindowfixed);
 650.716 +
 650.717 +  for(i=0;i<n;i++)work[i]=logmdct[i]-work[i];
 650.718 +
 650.719 +#if 0
 650.720 +  {
 650.721 +    static int seq=0;
 650.722 +
 650.723 +    float work2[n];
 650.724 +    for(i=0;i<n;i++){
 650.725 +      work2[i]=logmask[i]+work[i];
 650.726 +    }
 650.727 +
 650.728 +    if(seq&1)
 650.729 +      _analysis_output("median2R",seq/2,work,n,1,0,0);
 650.730 +    else
 650.731 +      _analysis_output("median2L",seq/2,work,n,1,0,0);
 650.732 +
 650.733 +    if(seq&1)
 650.734 +      _analysis_output("envelope2R",seq/2,work2,n,1,0,0);
 650.735 +    else
 650.736 +      _analysis_output("envelope2L",seq/2,work2,n,1,0,0);
 650.737 +    seq++;
 650.738 +  }
 650.739 +#endif
 650.740 +
 650.741 +  for(i=0;i<n;i++){
 650.742 +    int dB=logmask[i]+.5;
 650.743 +    if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;
 650.744 +    if(dB<0)dB=0;
 650.745 +    logmask[i]= work[i]+p->vi->noisecompand[dB];
 650.746 +  }
 650.747 +
 650.748 +}
 650.749 +
 650.750 +void _vp_tonemask(vorbis_look_psy *p,
 650.751 +                  float *logfft,
 650.752 +                  float *logmask,
 650.753 +                  float global_specmax,
 650.754 +                  float local_specmax){
 650.755 +
 650.756 +  int i,n=p->n;
 650.757 +
 650.758 +  float *seed=alloca(sizeof(*seed)*p->total_octave_lines);
 650.759 +  float att=local_specmax+p->vi->ath_adjatt;
 650.760 +  for(i=0;i<p->total_octave_lines;i++)seed[i]=NEGINF;
 650.761 +
 650.762 +  /* set the ATH (floating below localmax, not global max by a
 650.763 +     specified att) */
 650.764 +  if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
 650.765 +
 650.766 +  for(i=0;i<n;i++)
 650.767 +    logmask[i]=p->ath[i]+att;
 650.768 +
 650.769 +  /* tone masking */
 650.770 +  seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax);
 650.771 +  max_seeds(p,seed,logmask);
 650.772 +
 650.773 +}
 650.774 +
 650.775 +void _vp_offset_and_mix(vorbis_look_psy *p,
 650.776 +                        float *noise,
 650.777 +                        float *tone,
 650.778 +                        int offset_select,
 650.779 +                        float *logmask,
 650.780 +                        float *mdct,
 650.781 +                        float *logmdct){
 650.782 +  int i,n=p->n;
 650.783 +  float de, coeffi, cx;/* AoTuV */
 650.784 +  float toneatt=p->vi->tone_masteratt[offset_select];
 650.785 +
 650.786 +  cx = p->m_val;
 650.787 +
 650.788 +  for(i=0;i<n;i++){
 650.789 +    float val= noise[i]+p->noiseoffset[offset_select][i];
 650.790 +    if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp;
 650.791 +    logmask[i]=max(val,tone[i]+toneatt);
 650.792 +
 650.793 +
 650.794 +    /* AoTuV */
 650.795 +    /** @ M1 **
 650.796 +        The following codes improve a noise problem.
 650.797 +        A fundamental idea uses the value of masking and carries out
 650.798 +        the relative compensation of the MDCT.
 650.799 +        However, this code is not perfect and all noise problems cannot be solved.
 650.800 +        by Aoyumi @ 2004/04/18
 650.801 +    */
 650.802 +
 650.803 +    if(offset_select == 1) {
 650.804 +      coeffi = -17.2;       /* coeffi is a -17.2dB threshold */
 650.805 +      val = val - logmdct[i];  /* val == mdct line value relative to floor in dB */
 650.806 +
 650.807 +      if(val > coeffi){
 650.808 +        /* mdct value is > -17.2 dB below floor */
 650.809 +
 650.810 +        de = 1.0-((val-coeffi)*0.005*cx);
 650.811 +        /* pro-rated attenuation:
 650.812 +           -0.00 dB boost if mdct value is -17.2dB (relative to floor)
 650.813 +           -0.77 dB boost if mdct value is 0dB (relative to floor)
 650.814 +           -1.64 dB boost if mdct value is +17.2dB (relative to floor)
 650.815 +           etc... */
 650.816 +
 650.817 +        if(de < 0) de = 0.0001;
 650.818 +      }else
 650.819 +        /* mdct value is <= -17.2 dB below floor */
 650.820 +
 650.821 +        de = 1.0-((val-coeffi)*0.0003*cx);
 650.822 +      /* pro-rated attenuation:
 650.823 +         +0.00 dB atten if mdct value is -17.2dB (relative to floor)
 650.824 +         +0.45 dB atten if mdct value is -34.4dB (relative to floor)
 650.825 +         etc... */
 650.826 +
 650.827 +      mdct[i] *= de;
 650.828 +
 650.829 +    }
 650.830 +  }
 650.831 +}
 650.832 +
 650.833 +float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){
 650.834 +  vorbis_info *vi=vd->vi;
 650.835 +  codec_setup_info *ci=vi->codec_setup;
 650.836 +  vorbis_info_psy_global *gi=&ci->psy_g_param;
 650.837 +
 650.838 +  int n=ci->blocksizes[vd->W]/2;
 650.839 +  float secs=(float)n/vi->rate;
 650.840 +
 650.841 +  amp+=secs*gi->ampmax_att_per_sec;
 650.842 +  if(amp<-9999)amp=-9999;
 650.843 +  return(amp);
 650.844 +}
 650.845 +
 650.846 +static float FLOOR1_fromdB_LOOKUP[256]={
 650.847 +  1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
 650.848 +  1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
 650.849 +  1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
 650.850 +  2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
 650.851 +  2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
 650.852 +  3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
 650.853 +  4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
 650.854 +  6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
 650.855 +  7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
 650.856 +  1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
 650.857 +  1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
 650.858 +  1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
 650.859 +  2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
 650.860 +  2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
 650.861 +  3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
 650.862 +  4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
 650.863 +  5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
 650.864 +  7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
 650.865 +  9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
 650.866 +  1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
 650.867 +  1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
 650.868 +  2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
 650.869 +  2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
 650.870 +  3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
 650.871 +  4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
 650.872 +  5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
 650.873 +  7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
 650.874 +  9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
 650.875 +  0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
 650.876 +  0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
 650.877 +  0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
 650.878 +  0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
 650.879 +  0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
 650.880 +  0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
 650.881 +  0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
 650.882 +  0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
 650.883 +  0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
 650.884 +  0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
 650.885 +  0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
 650.886 +  0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
 650.887 +  0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
 650.888 +  0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
 650.889 +  0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
 650.890 +  0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
 650.891 +  0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
 650.892 +  0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
 650.893 +  0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
 650.894 +  0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
 650.895 +  0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
 650.896 +  0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
 650.897 +  0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
 650.898 +  0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
 650.899 +  0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
 650.900 +  0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
 650.901 +  0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
 650.902 +  0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
 650.903 +  0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
 650.904 +  0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
 650.905 +  0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
 650.906 +  0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
 650.907 +  0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
 650.908 +  0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
 650.909 +  0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
 650.910 +  0.82788260F, 0.88168307F, 0.9389798F, 1.F,
 650.911 +};
 650.912 +
 650.913 +/* this is for per-channel noise normalization */
 650.914 +static int apsort(const void *a, const void *b){
 650.915 +  float f1=**(float**)a;
 650.916 +  float f2=**(float**)b;
 650.917 +  return (f1<f2)-(f1>f2);
 650.918 +}
 650.919 +
 650.920 +static void flag_lossless(int limit, float prepoint, float postpoint, float *mdct,
 650.921 +                         float *floor, int *flag, int i, int jn){
 650.922 +  int j;
 650.923 +  for(j=0;j<jn;j++){
 650.924 +    float point = j>=limit-i ? postpoint : prepoint;
 650.925 +    float r = fabs(mdct[j])/floor[j];
 650.926 +    if(r<point)
 650.927 +      flag[j]=0;
 650.928 +    else
 650.929 +      flag[j]=1;
 650.930 +  }
 650.931 +}
 650.932 +
 650.933 +/* Overload/Side effect: On input, the *q vector holds either the
 650.934 +   quantized energy (for elements with the flag set) or the absolute
 650.935 +   values of the *r vector (for elements with flag unset).  On output,
 650.936 +   *q holds the quantized energy for all elements */
 650.937 +static float noise_normalize(vorbis_look_psy *p, int limit, float *r, float *q, float *f, int *flags, float acc, int i, int n, int *out){
 650.938 +
 650.939 +  vorbis_info_psy *vi=p->vi;
 650.940 +  float **sort = alloca(n*sizeof(*sort));
 650.941 +  int j,count=0;
 650.942 +  int start = (vi->normal_p ? vi->normal_start-i : n);
 650.943 +  if(start>n)start=n;
 650.944 +
 650.945 +  /* force classic behavior where only energy in the current band is considered */
 650.946 +  acc=0.f;
 650.947 +
 650.948 +  /* still responsible for populating *out where noise norm not in
 650.949 +     effect.  There's no need to [re]populate *q in these areas */
 650.950 +  for(j=0;j<start;j++){
 650.951 +    if(!flags || !flags[j]){ /* lossless coupling already quantized.
 650.952 +                                Don't touch; requantizing based on
 650.953 +                                energy would be incorrect. */
 650.954 +      float ve = q[j]/f[j];
 650.955 +      if(r[j]<0)
 650.956 +        out[j] = -rint(sqrt(ve));
 650.957 +      else
 650.958 +        out[j] = rint(sqrt(ve));
 650.959 +    }
 650.960 +  }
 650.961 +
 650.962 +  /* sort magnitudes for noise norm portion of partition */
 650.963 +  for(;j<n;j++){
 650.964 +    if(!flags || !flags[j]){ /* can't noise norm elements that have
 650.965 +                                already been loslessly coupled; we can
 650.966 +                                only account for their energy error */
 650.967 +      float ve = q[j]/f[j];
 650.968 +      /* Despite all the new, more capable coupling code, for now we
 650.969 +         implement noise norm as it has been up to this point. Only
 650.970 +         consider promotions to unit magnitude from 0.  In addition
 650.971 +         the only energy error counted is quantizations to zero. */
 650.972 +      /* also-- the original point code only applied noise norm at > pointlimit */
 650.973 +      if(ve<.25f && (!flags || j>=limit-i)){
 650.974 +        acc += ve;
 650.975 +        sort[count++]=q+j; /* q is fabs(r) for unflagged element */
 650.976 +      }else{
 650.977 +        /* For now: no acc adjustment for nonzero quantization.  populate *out and q as this value is final. */
 650.978 +        if(r[j]<0)
 650.979 +          out[j] = -rint(sqrt(ve));
 650.980 +        else
 650.981 +          out[j] = rint(sqrt(ve));
 650.982 +        q[j] = out[j]*out[j]*f[j];
 650.983 +      }
 650.984 +    }/* else{
 650.985 +        again, no energy adjustment for error in nonzero quant-- for now
 650.986 +        }*/
 650.987 +  }
 650.988 +
 650.989 +  if(count){
 650.990 +    /* noise norm to do */
 650.991 +    qsort(sort,count,sizeof(*sort),apsort);
 650.992 +    for(j=0;j<count;j++){
 650.993 +      int k=sort[j]-q;
 650.994 +      if(acc>=vi->normal_thresh){
 650.995 +        out[k]=unitnorm(r[k]);
 650.996 +        acc-=1.f;
 650.997 +        q[k]=f[k];
 650.998 +      }else{
 650.999 +        out[k]=0;
650.1000 +        q[k]=0.f;
650.1001 +      }
650.1002 +    }
650.1003 +  }
650.1004 +
650.1005 +  return acc;
650.1006 +}
650.1007 +
650.1008 +/* Noise normalization, quantization and coupling are not wholly
650.1009 +   seperable processes in depth>1 coupling. */
650.1010 +void _vp_couple_quantize_normalize(int blobno,
650.1011 +                                   vorbis_info_psy_global *g,
650.1012 +                                   vorbis_look_psy *p,
650.1013 +                                   vorbis_info_mapping0 *vi,
650.1014 +                                   float **mdct,
650.1015 +                                   int   **iwork,
650.1016 +                                   int    *nonzero,
650.1017 +                                   int     sliding_lowpass,
650.1018 +                                   int     ch){
650.1019 +
650.1020 +  int i;
650.1021 +  int n = p->n;
650.1022 +  int partition=(p->vi->normal_p ? p->vi->normal_partition : 16);
650.1023 +  int limit = g->coupling_pointlimit[p->vi->blockflag][blobno];
650.1024 +  float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]];
650.1025 +  float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]];
650.1026 +#if 0
650.1027 +  float de=0.1*p->m_val; /* a blend of the AoTuV M2 and M3 code here and below */
650.1028 +#endif
650.1029 +
650.1030 +  /* mdct is our raw mdct output, floor not removed. */
650.1031 +  /* inout passes in the ifloor, passes back quantized result */
650.1032 +
650.1033 +  /* unquantized energy (negative indicates amplitude has negative sign) */
650.1034 +  float **raw = alloca(ch*sizeof(*raw));
650.1035 +
650.1036 +  /* dual pupose; quantized energy (if flag set), othersize fabs(raw) */
650.1037 +  float **quant = alloca(ch*sizeof(*quant));
650.1038 +
650.1039 +  /* floor energy */
650.1040 +  float **floor = alloca(ch*sizeof(*floor));
650.1041 +
650.1042 +  /* flags indicating raw/quantized status of elements in raw vector */
650.1043 +  int   **flag  = alloca(ch*sizeof(*flag));
650.1044 +
650.1045 +  /* non-zero flag working vector */
650.1046 +  int    *nz    = alloca(ch*sizeof(*nz));
650.1047 +
650.1048 +  /* energy surplus/defecit tracking */
650.1049 +  float  *acc   = alloca((ch+vi->coupling_steps)*sizeof(*acc));
650.1050 +
650.1051 +  /* The threshold of a stereo is changed with the size of n */
650.1052 +  if(n > 1000)
650.1053 +    postpoint=stereo_threshholds_limited[g->coupling_postpointamp[blobno]];
650.1054 +
650.1055 +  raw[0]   = alloca(ch*partition*sizeof(**raw));
650.1056 +  quant[0] = alloca(ch*partition*sizeof(**quant));
650.1057 +  floor[0] = alloca(ch*partition*sizeof(**floor));
650.1058 +  flag[0]  = alloca(ch*partition*sizeof(**flag));
650.1059 +
650.1060 +  for(i=1;i<ch;i++){
650.1061 +    raw[i]   = &raw[0][partition*i];
650.1062 +    quant[i] = &quant[0][partition*i];
650.1063 +    floor[i] = &floor[0][partition*i];
650.1064 +    flag[i]  = &flag[0][partition*i];
650.1065 +  }
650.1066 +  for(i=0;i<ch+vi->coupling_steps;i++)
650.1067 +    acc[i]=0.f;
650.1068 +
650.1069 +  for(i=0;i<n;i+=partition){
650.1070 +    int k,j,jn = partition > n-i ? n-i : partition;
650.1071 +    int step,track = 0;
650.1072 +
650.1073 +    memcpy(nz,nonzero,sizeof(*nz)*ch);
650.1074 +
650.1075 +    /* prefill */
650.1076 +    memset(flag[0],0,ch*partition*sizeof(**flag));
650.1077 +    for(k=0;k<ch;k++){
650.1078 +      int *iout = &iwork[k][i];
650.1079 +      if(nz[k]){
650.1080 +
650.1081 +        for(j=0;j<jn;j++)
650.1082 +          floor[k][j] = FLOOR1_fromdB_LOOKUP[iout[j]];
650.1083 +
650.1084 +        flag_lossless(limit,prepoint,postpoint,&mdct[k][i],floor[k],flag[k],i,jn);
650.1085 +
650.1086 +        for(j=0;j<jn;j++){
650.1087 +          quant[k][j] = raw[k][j] = mdct[k][i+j]*mdct[k][i+j];
650.1088 +          if(mdct[k][i+j]<0.f) raw[k][j]*=-1.f;
650.1089 +          floor[k][j]*=floor[k][j];
650.1090 +        }
650.1091 +
650.1092 +        acc[track]=noise_normalize(p,limit,raw[k],quant[k],floor[k],NULL,acc[track],i,jn,iout);
650.1093 +
650.1094 +      }else{
650.1095 +        for(j=0;j<jn;j++){
650.1096 +          floor[k][j] = 1e-10f;
650.1097 +          raw[k][j] = 0.f;
650.1098 +          quant[k][j] = 0.f;
650.1099 +          flag[k][j] = 0;
650.1100 +          iout[j]=0;
650.1101 +        }
650.1102 +        acc[track]=0.f;
650.1103 +      }
650.1104 +      track++;
650.1105 +    }
650.1106 +
650.1107 +    /* coupling */
650.1108 +    for(step=0;step<vi->coupling_steps;step++){
650.1109 +      int Mi = vi->coupling_mag[step];
650.1110 +      int Ai = vi->coupling_ang[step];
650.1111 +      int *iM = &iwork[Mi][i];
650.1112 +      int *iA = &iwork[Ai][i];
650.1113 +      float *reM = raw[Mi];
650.1114 +      float *reA = raw[Ai];
650.1115 +      float *qeM = quant[Mi];
650.1116 +      float *qeA = quant[Ai];
650.1117 +      float *floorM = floor[Mi];
650.1118 +      float *floorA = floor[Ai];
650.1119 +      int *fM = flag[Mi];
650.1120 +      int *fA = flag[Ai];
650.1121 +
650.1122 +      if(nz[Mi] || nz[Ai]){
650.1123 +        nz[Mi] = nz[Ai] = 1;
650.1124 +
650.1125 +        for(j=0;j<jn;j++){
650.1126 +
650.1127 +          if(j<sliding_lowpass-i){
650.1128 +            if(fM[j] || fA[j]){
650.1129 +              /* lossless coupling */
650.1130 +
650.1131 +              reM[j] = fabs(reM[j])+fabs(reA[j]);
650.1132 +              qeM[j] = qeM[j]+qeA[j];
650.1133 +              fM[j]=fA[j]=1;
650.1134 +
650.1135 +              /* couple iM/iA */
650.1136 +              {
650.1137 +                int A = iM[j];
650.1138 +                int B = iA[j];
650.1139 +
650.1140 +                if(abs(A)>abs(B)){
650.1141 +                  iA[j]=(A>0?A-B:B-A);
650.1142 +                }else{
650.1143 +                  iA[j]=(B>0?A-B:B-A);
650.1144 +                  iM[j]=B;
650.1145 +                }
650.1146 +
650.1147 +                /* collapse two equivalent tuples to one */
650.1148 +                if(iA[j]>=abs(iM[j])*2){
650.1149 +                  iA[j]= -iA[j];
650.1150 +                  iM[j]= -iM[j];
650.1151 +                }
650.1152 +
650.1153 +              }
650.1154 +
650.1155 +            }else{
650.1156 +              /* lossy (point) coupling */
650.1157 +              if(j<limit-i){
650.1158 +                /* dipole */
650.1159 +                reM[j] += reA[j];
650.1160 +                qeM[j] = fabs(reM[j]);
650.1161 +              }else{
650.1162 +#if 0
650.1163 +                /* AoTuV */
650.1164 +                /** @ M2 **
650.1165 +                    The boost problem by the combination of noise normalization and point stereo is eased.
650.1166 +                    However, this is a temporary patch.
650.1167 +                    by Aoyumi @ 2004/04/18
650.1168 +                */
650.1169 +                float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit)));
650.1170 +                /* elliptical */
650.1171 +                if(reM[j]+reA[j]<0){
650.1172 +                  reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
650.1173 +                }else{
650.1174 +                  reM[j] =   (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
650.1175 +                }
650.1176 +#else
650.1177 +                /* elliptical */
650.1178 +                if(reM[j]+reA[j]<0){
650.1179 +                  reM[j] = - (qeM[j] = fabs(reM[j])+fabs(reA[j]));
650.1180 +                }else{
650.1181 +                  reM[j] =   (qeM[j] = fabs(reM[j])+fabs(reA[j]));
650.1182 +                }
650.1183 +#endif
650.1184 +
650.1185 +              }
650.1186 +              reA[j]=qeA[j]=0.f;
650.1187 +              fA[j]=1;
650.1188 +              iA[j]=0;
650.1189 +            }
650.1190 +          }
650.1191 +          floorM[j]=floorA[j]=floorM[j]+floorA[j];
650.1192 +        }
650.1193 +        /* normalize the resulting mag vector */
650.1194 +        acc[track]=noise_normalize(p,limit,raw[Mi],quant[Mi],floor[Mi],flag[Mi],acc[track],i,jn,iM);
650.1195 +        track++;
650.1196 +      }
650.1197 +    }
650.1198 +  }
650.1199 +
650.1200 +  for(i=0;i<vi->coupling_steps;i++){
650.1201 +    /* make sure coupling a zero and a nonzero channel results in two
650.1202 +       nonzero channels. */
650.1203 +    if(nonzero[vi->coupling_mag[i]] ||
650.1204 +       nonzero[vi->coupling_ang[i]]){
650.1205 +      nonzero[vi->coupling_mag[i]]=1;
650.1206 +      nonzero[vi->coupling_ang[i]]=1;
650.1207 +    }
650.1208 +  }
650.1209 +}
   651.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   651.2 +++ b/libs/vorbis/psy.h	Sat Feb 01 19:58:19 2014 +0200
   651.3 @@ -0,0 +1,154 @@
   651.4 +/********************************************************************
   651.5 + *                                                                  *
   651.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   651.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   651.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   651.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  651.10 + *                                                                  *
  651.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  651.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  651.13 + *                                                                  *
  651.14 + ********************************************************************
  651.15 +
  651.16 + function: random psychoacoustics (not including preecho)
  651.17 + last mod: $Id: psy.h 16946 2010-03-03 16:12:40Z xiphmont $
  651.18 +
  651.19 + ********************************************************************/
  651.20 +
  651.21 +#ifndef _V_PSY_H_
  651.22 +#define _V_PSY_H_
  651.23 +#include "smallft.h"
  651.24 +
  651.25 +#include "backends.h"
  651.26 +#include "envelope.h"
  651.27 +
  651.28 +#ifndef EHMER_MAX
  651.29 +#define EHMER_MAX 56
  651.30 +#endif
  651.31 +
  651.32 +/* psychoacoustic setup ********************************************/
  651.33 +#define P_BANDS 17      /* 62Hz to 16kHz */
  651.34 +#define P_LEVELS 8      /* 30dB to 100dB */
  651.35 +#define P_LEVEL_0 30.    /* 30 dB */
  651.36 +#define P_NOISECURVES 3
  651.37 +
  651.38 +#define NOISE_COMPAND_LEVELS 40
  651.39 +typedef struct vorbis_info_psy{
  651.40 +  int   blockflag;
  651.41 +
  651.42 +  float ath_adjatt;
  651.43 +  float ath_maxatt;
  651.44 +
  651.45 +  float tone_masteratt[P_NOISECURVES];
  651.46 +  float tone_centerboost;
  651.47 +  float tone_decay;
  651.48 +  float tone_abs_limit;
  651.49 +  float toneatt[P_BANDS];
  651.50 +
  651.51 +  int noisemaskp;
  651.52 +  float noisemaxsupp;
  651.53 +  float noisewindowlo;
  651.54 +  float noisewindowhi;
  651.55 +  int   noisewindowlomin;
  651.56 +  int   noisewindowhimin;
  651.57 +  int   noisewindowfixed;
  651.58 +  float noiseoff[P_NOISECURVES][P_BANDS];
  651.59 +  float noisecompand[NOISE_COMPAND_LEVELS];
  651.60 +
  651.61 +  float max_curve_dB;
  651.62 +
  651.63 +  int normal_p;
  651.64 +  int normal_start;
  651.65 +  int normal_partition;
  651.66 +  double normal_thresh;
  651.67 +} vorbis_info_psy;
  651.68 +
  651.69 +typedef struct{
  651.70 +  int   eighth_octave_lines;
  651.71 +
  651.72 +  /* for block long/short tuning; encode only */
  651.73 +  float preecho_thresh[VE_BANDS];
  651.74 +  float postecho_thresh[VE_BANDS];
  651.75 +  float stretch_penalty;
  651.76 +  float preecho_minenergy;
  651.77 +
  651.78 +  float ampmax_att_per_sec;
  651.79 +
  651.80 +  /* channel coupling config */
  651.81 +  int   coupling_pkHz[PACKETBLOBS];
  651.82 +  int   coupling_pointlimit[2][PACKETBLOBS];
  651.83 +  int   coupling_prepointamp[PACKETBLOBS];
  651.84 +  int   coupling_postpointamp[PACKETBLOBS];
  651.85 +  int   sliding_lowpass[2][PACKETBLOBS];
  651.86 +
  651.87 +} vorbis_info_psy_global;
  651.88 +
  651.89 +typedef struct {
  651.90 +  float ampmax;
  651.91 +  int   channels;
  651.92 +
  651.93 +  vorbis_info_psy_global *gi;
  651.94 +  int   coupling_pointlimit[2][P_NOISECURVES];
  651.95 +} vorbis_look_psy_global;
  651.96 +
  651.97 +
  651.98 +typedef struct {
  651.99 +  int n;
 651.100 +  struct vorbis_info_psy *vi;
 651.101 +
 651.102 +  float ***tonecurves;
 651.103 +  float **noiseoffset;
 651.104 +
 651.105 +  float *ath;
 651.106 +  long  *octave;             /* in n.ocshift format */
 651.107 +  long  *bark;
 651.108 +
 651.109 +  long  firstoc;
 651.110 +  long  shiftoc;
 651.111 +  int   eighth_octave_lines; /* power of two, please */
 651.112 +  int   total_octave_lines;
 651.113 +  long  rate; /* cache it */
 651.114 +
 651.115 +  float m_val; /* Masking compensation value */
 651.116 +
 651.117 +} vorbis_look_psy;
 651.118 +
 651.119 +extern void   _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
 651.120 +                           vorbis_info_psy_global *gi,int n,long rate);
 651.121 +extern void   _vp_psy_clear(vorbis_look_psy *p);
 651.122 +extern void  *_vi_psy_dup(void *source);
 651.123 +
 651.124 +extern void   _vi_psy_free(vorbis_info_psy *i);
 651.125 +extern vorbis_info_psy *_vi_psy_copy(vorbis_info_psy *i);
 651.126 +
 651.127 +extern void _vp_noisemask(vorbis_look_psy *p,
 651.128 +                          float *logmdct,
 651.129 +                          float *logmask);
 651.130 +
 651.131 +extern void _vp_tonemask(vorbis_look_psy *p,
 651.132 +                         float *logfft,
 651.133 +                         float *logmask,
 651.134 +                         float global_specmax,
 651.135 +                         float local_specmax);
 651.136 +
 651.137 +extern void _vp_offset_and_mix(vorbis_look_psy *p,
 651.138 +                               float *noise,
 651.139 +                               float *tone,
 651.140 +                               int offset_select,
 651.141 +                               float *logmask,
 651.142 +                               float *mdct,
 651.143 +                               float *logmdct);
 651.144 +
 651.145 +extern float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd);
 651.146 +
 651.147 +extern void _vp_couple_quantize_normalize(int blobno,
 651.148 +                                          vorbis_info_psy_global *g,
 651.149 +                                          vorbis_look_psy *p,
 651.150 +                                          vorbis_info_mapping0 *vi,
 651.151 +                                          float **mdct,
 651.152 +                                          int   **iwork,
 651.153 +                                          int    *nonzero,
 651.154 +                                          int     sliding_lowpass,
 651.155 +                                          int     ch);
 651.156 +
 651.157 +#endif
   652.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   652.2 +++ b/libs/vorbis/registry.c	Sat Feb 01 19:58:19 2014 +0200
   652.3 @@ -0,0 +1,45 @@
   652.4 +/********************************************************************
   652.5 + *                                                                  *
   652.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   652.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   652.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   652.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  652.10 + *                                                                  *
  652.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  652.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  652.13 + *                                                                  *
  652.14 + ********************************************************************
  652.15 +
  652.16 + function: registry for time, floor, res backends and channel mappings
  652.17 + last mod: $Id: registry.c 16227 2009-07-08 06:58:46Z xiphmont $
  652.18 +
  652.19 + ********************************************************************/
  652.20 +
  652.21 +#include "vorbis/codec.h"
  652.22 +#include "codec_internal.h"
  652.23 +#include "registry.h"
  652.24 +#include "misc.h"
  652.25 +/* seems like major overkill now; the backend numbers will grow into
  652.26 +   the infrastructure soon enough */
  652.27 +
  652.28 +extern const vorbis_func_floor     floor0_exportbundle;
  652.29 +extern const vorbis_func_floor     floor1_exportbundle;
  652.30 +extern const vorbis_func_residue   residue0_exportbundle;
  652.31 +extern const vorbis_func_residue   residue1_exportbundle;
  652.32 +extern const vorbis_func_residue   residue2_exportbundle;
  652.33 +extern const vorbis_func_mapping   mapping0_exportbundle;
  652.34 +
  652.35 +const vorbis_func_floor     *const _floor_P[]={
  652.36 +  &floor0_exportbundle,
  652.37 +  &floor1_exportbundle,
  652.38 +};
  652.39 +
  652.40 +const vorbis_func_residue   *const _residue_P[]={
  652.41 +  &residue0_exportbundle,
  652.42 +  &residue1_exportbundle,
  652.43 +  &residue2_exportbundle,
  652.44 +};
  652.45 +
  652.46 +const vorbis_func_mapping   *const _mapping_P[]={
  652.47 +  &mapping0_exportbundle,
  652.48 +};
   653.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   653.2 +++ b/libs/vorbis/registry.h	Sat Feb 01 19:58:19 2014 +0200
   653.3 @@ -0,0 +1,32 @@
   653.4 +/********************************************************************
   653.5 + *                                                                  *
   653.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   653.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   653.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   653.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  653.10 + *                                                                  *
  653.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  653.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  653.13 + *                                                                  *
  653.14 + ********************************************************************
  653.15 +
  653.16 + function: registry for time, floor, res backends and channel mappings
  653.17 + last mod: $Id: registry.h 15531 2008-11-24 23:50:06Z xiphmont $
  653.18 +
  653.19 + ********************************************************************/
  653.20 +
  653.21 +#ifndef _V_REG_H_
  653.22 +#define _V_REG_H_
  653.23 +
  653.24 +#define VI_TRANSFORMB 1
  653.25 +#define VI_WINDOWB 1
  653.26 +#define VI_TIMEB 1
  653.27 +#define VI_FLOORB 2
  653.28 +#define VI_RESB 3
  653.29 +#define VI_MAPB 1
  653.30 +
  653.31 +extern const vorbis_func_floor     *const _floor_P[];
  653.32 +extern const vorbis_func_residue   *const _residue_P[];
  653.33 +extern const vorbis_func_mapping   *const _mapping_P[];
  653.34 +
  653.35 +#endif
   654.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   654.2 +++ b/libs/vorbis/res0.c	Sat Feb 01 19:58:19 2014 +0200
   654.3 @@ -0,0 +1,889 @@
   654.4 +/********************************************************************
   654.5 + *                                                                  *
   654.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   654.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   654.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   654.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  654.10 + *                                                                  *
  654.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
  654.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  654.13 + *                                                                  *
  654.14 + ********************************************************************
  654.15 +
  654.16 + function: residue backend 0, 1 and 2 implementation
  654.17 + last mod: $Id: res0.c 17556 2010-10-21 18:25:19Z tterribe $
  654.18 +
  654.19 + ********************************************************************/
  654.20 +
  654.21 +/* Slow, slow, slow, simpleminded and did I mention it was slow?  The
  654.22 +   encode/decode loops are coded for clarity and performance is not
  654.23 +   yet even a nagging little idea lurking in the shadows.  Oh and BTW,
  654.24 +   it's slow. */
  654.25 +
  654.26 +#include <stdlib.h>
  654.27 +#include <string.h>
  654.28 +#include <math.h>
  654.29 +#include <ogg/ogg.h>
  654.30 +#include "vorbis/codec.h"
  654.31 +#include "codec_internal.h"
  654.32 +#include "registry.h"
  654.33 +#include "codebook.h"
  654.34 +#include "misc.h"
  654.35 +#include "os.h"
  654.36 +
  654.37 +/*#define TRAIN_RES 1*/
  654.38 +/*#define TRAIN_RESAUX 1*/
  654.39 +
  654.40 +#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
  654.41 +#include <stdio.h>
  654.42 +#endif
  654.43 +
  654.44 +typedef struct {
  654.45 +  vorbis_info_residue0 *info;
  654.46 +
  654.47 +  int         parts;
  654.48 +  int         stages;
  654.49 +  codebook   *fullbooks;
  654.50 +  codebook   *phrasebook;
  654.51 +  codebook ***partbooks;
  654.52 +
  654.53 +  int         partvals;
  654.54 +  int       **decodemap;
  654.55 +
  654.56 +  long      postbits;
  654.57 +  long      phrasebits;
  654.58 +  long      frames;
  654.59 +
  654.60 +#if defined(TRAIN_RES) || defined(TRAIN_RESAUX)
  654.61 +  int        train_seq;
  654.62 +  long      *training_data[8][64];
  654.63 +  float      training_max[8][64];
  654.64 +  float      training_min[8][64];
  654.65 +  float     tmin;
  654.66 +  float     tmax;
  654.67 +  int       submap;
  654.68 +#endif
  654.69 +
  654.70 +} vorbis_look_residue0;
  654.71 +
  654.72 +void res0_free_info(vorbis_info_residue *i){
  654.73 +  vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
  654.74 +  if(info){
  654.75 +    memset(info,0,sizeof(*info));
  654.76 +    _ogg_free(info);
  654.77 +  }
  654.78 +}
  654.79 +
  654.80 +void res0_free_look(vorbis_look_residue *i){
  654.81 +  int j;
  654.82 +  if(i){
  654.83 +
  654.84 +    vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
  654.85 +
  654.86 +#ifdef TRAIN_RES
  654.87 +    {
  654.88 +      int j,k,l;
  654.89 +      for(j=0;j<look->parts;j++){
  654.90 +        /*fprintf(stderr,"partition %d: ",j);*/
  654.91 +        for(k=0;k<8;k++)
  654.92 +          if(look->training_data[k][j]){
  654.93 +            char buffer[80];
  654.94 +            FILE *of;
  654.95 +            codebook *statebook=look->partbooks[j][k];
  654.96 +
  654.97 +            /* long and short into the same bucket by current convention */
  654.98 +            sprintf(buffer,"res_sub%d_part%d_pass%d.vqd",look->submap,j,k);
  654.99 +            of=fopen(buffer,"a");
 654.100 +
 654.101 +            for(l=0;l<statebook->entries;l++)
 654.102 +              fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]);
 654.103 +
 654.104 +            fclose(of);
 654.105 +
 654.106 +            /*fprintf(stderr,"%d(%.2f|%.2f) ",k,
 654.107 +              look->training_min[k][j],look->training_max[k][j]);*/
 654.108 +
 654.109 +            _ogg_free(look->training_data[k][j]);
 654.110 +            look->training_data[k][j]=NULL;
 654.111 +          }
 654.112 +        /*fprintf(stderr,"\n");*/
 654.113 +      }
 654.114 +    }
 654.115 +    fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax);
 654.116 +
 654.117 +    /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n",
 654.118 +            (float)look->phrasebits/look->frames,
 654.119 +            (float)look->postbits/look->frames,
 654.120 +            (float)(look->postbits+look->phrasebits)/look->frames);*/
 654.121 +#endif
 654.122 +
 654.123 +
 654.124 +    /*vorbis_info_residue0 *info=look->info;
 654.125 +
 654.126 +    fprintf(stderr,
 654.127 +            "%ld frames encoded in %ld phrasebits and %ld residue bits "
 654.128 +            "(%g/frame) \n",look->frames,look->phrasebits,
 654.129 +            look->resbitsflat,
 654.130 +            (look->phrasebits+look->resbitsflat)/(float)look->frames);
 654.131 +
 654.132 +    for(j=0;j<look->parts;j++){
 654.133 +      long acc=0;
 654.134 +      fprintf(stderr,"\t[%d] == ",j);
 654.135 +      for(k=0;k<look->stages;k++)
 654.136 +        if((info->secondstages[j]>>k)&1){
 654.137 +          fprintf(stderr,"%ld,",look->resbits[j][k]);
 654.138 +          acc+=look->resbits[j][k];
 654.139 +        }
 654.140 +
 654.141 +      fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j],
 654.142 +              acc?(float)acc/(look->resvals[j]*info->grouping):0);
 654.143 +    }
 654.144 +    fprintf(stderr,"\n");*/
 654.145 +
 654.146 +    for(j=0;j<look->parts;j++)
 654.147 +      if(look->partbooks[j])_ogg_free(look->partbooks[j]);
 654.148 +    _ogg_free(look->partbooks);
 654.149 +    for(j=0;j<look->partvals;j++)
 654.150 +      _ogg_free(look->decodemap[j]);
 654.151 +    _ogg_free(look->decodemap);
 654.152 +
 654.153 +    memset(look,0,sizeof(*look));
 654.154 +    _ogg_free(look);
 654.155 +  }
 654.156 +}
 654.157 +
 654.158 +static int ilog(unsigned int v){
 654.159 +  int ret=0;
 654.160 +  while(v){
 654.161 +    ret++;
 654.162 +    v>>=1;
 654.163 +  }
 654.164 +  return(ret);
 654.165 +}
 654.166 +
 654.167 +static int icount(unsigned int v){
 654.168 +  int ret=0;
 654.169 +  while(v){
 654.170 +    ret+=v&1;
 654.171 +    v>>=1;
 654.172 +  }
 654.173 +  return(ret);
 654.174 +}
 654.175 +
 654.176 +
 654.177 +void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
 654.178 +  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
 654.179 +  int j,acc=0;
 654.180 +  oggpack_write(opb,info->begin,24);
 654.181 +  oggpack_write(opb,info->end,24);
 654.182 +
 654.183 +  oggpack_write(opb,info->grouping-1,24);  /* residue vectors to group and
 654.184 +                                             code with a partitioned book */
 654.185 +  oggpack_write(opb,info->partitions-1,6); /* possible partition choices */
 654.186 +  oggpack_write(opb,info->groupbook,8);  /* group huffman book */
 654.187 +
 654.188 +  /* secondstages is a bitmask; as encoding progresses pass by pass, a
 654.189 +     bitmask of one indicates this partition class has bits to write
 654.190 +     this pass */
 654.191 +  for(j=0;j<info->partitions;j++){
 654.192 +    if(ilog(info->secondstages[j])>3){
 654.193 +      /* yes, this is a minor hack due to not thinking ahead */
 654.194 +      oggpack_write(opb,info->secondstages[j],3);
 654.195 +      oggpack_write(opb,1,1);
 654.196 +      oggpack_write(opb,info->secondstages[j]>>3,5);
 654.197 +    }else
 654.198 +      oggpack_write(opb,info->secondstages[j],4); /* trailing zero */
 654.199 +    acc+=icount(info->secondstages[j]);
 654.200 +  }
 654.201 +  for(j=0;j<acc;j++)
 654.202 +    oggpack_write(opb,info->booklist[j],8);
 654.203 +
 654.204 +}
 654.205 +
 654.206 +/* vorbis_info is for range checking */
 654.207 +vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
 654.208 +  int j,acc=0;
 654.209 +  vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info));
 654.210 +  codec_setup_info     *ci=vi->codec_setup;
 654.211 +
 654.212 +  info->begin=oggpack_read(opb,24);
 654.213 +  info->end=oggpack_read(opb,24);
 654.214 +  info->grouping=oggpack_read(opb,24)+1;
 654.215 +  info->partitions=oggpack_read(opb,6)+1;
 654.216 +  info->groupbook=oggpack_read(opb,8);
 654.217 +
 654.218 +  /* check for premature EOP */
 654.219 +  if(info->groupbook<0)goto errout;
 654.220 +
 654.221 +  for(j=0;j<info->partitions;j++){
 654.222 +    int cascade=oggpack_read(opb,3);
 654.223 +    int cflag=oggpack_read(opb,1);
 654.224 +    if(cflag<0) goto errout;
 654.225 +    if(cflag){
 654.226 +      int c=oggpack_read(opb,5);
 654.227 +      if(c<0) goto errout;
 654.228 +      cascade|=(c<<3);
 654.229 +    }
 654.230 +    info->secondstages[j]=cascade;
 654.231 +
 654.232 +    acc+=icount(cascade);
 654.233 +  }
 654.234 +  for(j=0;j<acc;j++){
 654.235 +    int book=oggpack_read(opb,8);
 654.236 +    if(book<0) goto errout;
 654.237 +    info->booklist[j]=book;
 654.238 +  }
 654.239 +
 654.240 +  if(info->groupbook>=ci->books)goto errout;
 654.241 +  for(j=0;j<acc;j++){
 654.242 +    if(info->booklist[j]>=ci->books)goto errout;
 654.243 +    if(ci->book_param[info->booklist[j]]->maptype==0)goto errout;
 654.244 +  }
 654.245 +
 654.246 +  /* verify the phrasebook is not specifying an impossible or
 654.247 +     inconsistent partitioning scheme. */
 654.248 +  /* modify the phrasebook ranging check from r16327; an early beta
 654.249 +     encoder had a bug where it used an oversized phrasebook by
 654.250 +     accident.  These files should continue to be playable, but don't
 654.251 +     allow an exploit */
 654.252 +  {
 654.253 +    int entries = ci->book_param[info->groupbook]->entries;
 654.254 +    int dim = ci->book_param[info->groupbook]->dim;
 654.255 +    int partvals = 1;
 654.256 +    if (dim<1) goto errout;
 654.257 +    while(dim>0){
 654.258 +      partvals *= info->partitions;
 654.259 +      if(partvals > entries) goto errout;
 654.260 +      dim--;
 654.261 +    }
 654.262 +    info->partvals = partvals;
 654.263 +  }
 654.264 +
 654.265 +  return(info);
 654.266 + errout:
 654.267 +  res0_free_info(info);
 654.268 +  return(NULL);
 654.269 +}
 654.270 +
 654.271 +vorbis_look_residue *res0_look(vorbis_dsp_state *vd,
 654.272 +                               vorbis_info_residue *vr){
 654.273 +  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
 654.274 +  vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look));
 654.275 +  codec_setup_info     *ci=vd->vi->codec_setup;
 654.276 +
 654.277 +  int j,k,acc=0;
 654.278 +  int dim;
 654.279 +  int maxstage=0;
 654.280 +  look->info=info;
 654.281 +
 654.282 +  look->parts=info->partitions;
 654.283 +  look->fullbooks=ci->fullbooks;
 654.284 +  look->phrasebook=ci->fullbooks+info->groupbook;
 654.285 +  dim=look->phrasebook->dim;
 654.286 +
 654.287 +  look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks));
 654.288 +
 654.289 +  for(j=0;j<look->parts;j++){
 654.290 +    int stages=ilog(info->secondstages[j]);
 654.291 +    if(stages){
 654.292 +      if(stages>maxstage)maxstage=stages;
 654.293 +      look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j]));
 654.294 +      for(k=0;k<stages;k++)
 654.295 +        if(info->secondstages[j]&(1<<k)){
 654.296 +          look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
 654.297 +#ifdef TRAIN_RES
 654.298 +          look->training_data[k][j]=_ogg_calloc(look->partbooks[j][k]->entries,
 654.299 +                                           sizeof(***look->training_data));
 654.300 +#endif
 654.301 +        }
 654.302 +    }
 654.303 +  }
 654.304 +
 654.305 +  look->partvals=1;
 654.306 +  for(j=0;j<dim;j++)
 654.307 +      look->partvals*=look->parts;
 654.308 +
 654.309 +  look->stages=maxstage;
 654.310 +  look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap));
 654.311 +  for(j=0;j<look->partvals;j++){
 654.312 +    long val=j;
 654.313 +    long mult=look->partvals/look->parts;
 654.314 +    look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j]));
 654.315 +    for(k=0;k<dim;k++){
 654.316 +      long deco=val/mult;
 654.317 +      val-=deco*mult;
 654.318 +      mult/=look->parts;
 654.319 +      look->decodemap[j][k]=deco;
 654.320 +    }
 654.321 +  }
 654.322 +#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
 654.323 +  {
 654.324 +    static int train_seq=0;
 654.325 +    look->train_seq=train_seq++;
 654.326 +  }
 654.327 +#endif
 654.328 +  return(look);
 654.329 +}
 654.330 +
 654.331 +/* break an abstraction and copy some code for performance purposes */
 654.332 +static int local_book_besterror(codebook *book,int *a){
 654.333 +  int dim=book->dim;
 654.334 +  int i,j,o;
 654.335 +  int minval=book->minval;
 654.336 +  int del=book->delta;
 654.337 +  int qv=book->quantvals;
 654.338 +  int ze=(qv>>1);
 654.339 +  int index=0;
 654.340 +  /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
 654.341 +  int p[8]={0,0,0,0,0,0,0,0};
 654.342 +
 654.343 +  if(del!=1){
 654.344 +    for(i=0,o=dim;i<dim;i++){
 654.345 +      int v = (a[--o]-minval+(del>>1))/del;
 654.346 +      int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
 654.347 +      index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
 654.348 +      p[o]=v*del+minval;
 654.349 +    }
 654.350 +  }else{
 654.351 +    for(i=0,o=dim;i<dim;i++){
 654.352 +      int v = a[--o]-minval;
 654.353 +      int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
 654.354 +      index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
 654.355 +      p[o]=v*del+minval;
 654.356 +    }
 654.357 +  }
 654.358 +
 654.359 +  if(book->c->lengthlist[index]<=0){
 654.360 +    const static_codebook *c=book->c;
 654.361 +    int best=-1;
 654.362 +    /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
 654.363 +    int e[8]={0,0,0,0,0,0,0,0};
 654.364 +    int maxval = book->minval + book->delta*(book->quantvals-1);
 654.365 +    for(i=0;i<book->entries;i++){
 654.366 +      if(c->lengthlist[i]>0){
 654.367 +        int this=0;
 654.368 +        for(j=0;j<dim;j++){
 654.369 +          int val=(e[j]-a[j]);
 654.370 +          this+=val*val;
 654.371 +        }
 654.372 +        if(best==-1 || this<best){
 654.373 +          memcpy(p,e,sizeof(p));
 654.374 +          best=this;
 654.375 +          index=i;
 654.376 +        }
 654.377 +      }
 654.378 +      /* assumes the value patterning created by the tools in vq/ */
 654.379 +      j=0;
 654.380 +      while(e[j]>=maxval)
 654.381 +        e[j++]=0;
 654.382 +      if(e[j]>=0)
 654.383 +        e[j]+=book->delta;
 654.384 +      e[j]= -e[j];
 654.385 +    }
 654.386 +  }
 654.387 +
 654.388 +  if(index>-1){
 654.389 +    for(i=0;i<dim;i++)
 654.390 +      *a++ -= p[i];
 654.391 +  }
 654.392 +
 654.393 +  return(index);
 654.394 +}
 654.395 +
 654.396 +static int _encodepart(oggpack_buffer *opb,int *vec, int n,
 654.397 +                       codebook *book,long *acc){
 654.398 +  int i,bits=0;
 654.399 +  int dim=book->dim;
 654.400 +  int step=n/dim;
 654.401 +
 654.402 +  for(i=0;i<step;i++){
 654.403 +    int entry=local_book_besterror(book,vec+i*dim);
 654.404 +
 654.405 +#ifdef TRAIN_RES
 654.406 +    if(entry>=0)
 654.407 +      acc[entry]++;
 654.408 +#endif
 654.409 +
 654.410 +    bits+=vorbis_book_encode(book,entry,opb);
 654.411 +
 654.412 +  }
 654.413 +
 654.414 +  return(bits);
 654.415 +}
 654.416 +
 654.417 +static long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
 654.418 +                       int **in,int ch){
 654.419 +  long i,j,k;
 654.420 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
 654.421 +  vorbis_info_residue0 *info=look->info;
 654.422 +
 654.423 +  /* move all this setup out later */
 654.424 +  int samples_per_partition=info->grouping;
 654.425 +  int possible_partitions=info->partitions;
 654.426 +  int n=info->end-info->begin;
 654.427 +
 654.428 +  int partvals=n/samples_per_partition;
 654.429 +  long **partword=_vorbis_block_alloc(vb,ch*sizeof(*partword));
 654.430 +  float scale=100./samples_per_partition;
 654.431 +
 654.432 +  /* we find the partition type for each partition of each
 654.433 +     channel.  We'll go back and do the interleaved encoding in a
 654.434 +     bit.  For now, clarity */
 654.435 +
 654.436 +  for(i=0;i<ch;i++){
 654.437 +    partword[i]=_vorbis_block_alloc(vb,n/samples_per_partition*sizeof(*partword[i]));
 654.438 +    memset(partword[i],0,n/samples_per_partition*sizeof(*partword[i]));
 654.439 +  }
 654.440 +
 654.441 +  for(i=0;i<partvals;i++){
 654.442 +    int offset=i*samples_per_partition+info->begin;
 654.443 +    for(j=0;j<ch;j++){
 654.444 +      int max=0;
 654.445 +      int ent=0;
 654.446 +      for(k=0;k<samples_per_partition;k++){
 654.447 +        if(abs(in[j][offset+k])>max)max=abs(in[j][offset+k]);
 654.448 +        ent+=abs(in[j][offset+k]);
 654.449 +      }
 654.450 +      ent*=scale;
 654.451 +
 654.452 +      for(k=0;k<possible_partitions-1;k++)
 654.453 +        if(max<=info->classmetric1[k] &&
 654.454 +           (info->classmetric2[k]<0 || ent<info->classmetric2[k]))
 654.455 +          break;
 654.456 +
 654.457 +      partword[j][i]=k;
 654.458 +    }
 654.459 +  }
 654.460 +
 654.461 +#ifdef TRAIN_RESAUX
 654.462 +  {
 654.463 +    FILE *of;
 654.464 +    char buffer[80];
 654.465 +
 654.466 +    for(i=0;i<ch;i++){
 654.467 +      sprintf(buffer,"resaux_%d.vqd",look->train_seq);
 654.468 +      of=fopen(buffer,"a");
 654.469 +      for(j=0;j<partvals;j++)
 654.470 +        fprintf(of,"%ld, ",partword[i][j]);
 654.471 +      fprintf(of,"\n");
 654.472 +      fclose(of);
 654.473 +    }
 654.474 +  }
 654.475 +#endif
 654.476 +  look->frames++;
 654.477 +
 654.478 +  return(partword);
 654.479 +}
 654.480 +
 654.481 +/* designed for stereo or other modes where the partition size is an
 654.482 +   integer multiple of the number of channels encoded in the current
 654.483 +   submap */
 654.484 +static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,int **in,
 654.485 +                      int ch){
 654.486 +  long i,j,k,l;
 654.487 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
 654.488 +  vorbis_info_residue0 *info=look->info;
 654.489 +
 654.490 +  /* move all this setup out later */
 654.491 +  int samples_per_partition=info->grouping;
 654.492 +  int possible_partitions=info->partitions;
 654.493 +  int n=info->end-info->begin;
 654.494 +
 654.495 +  int partvals=n/samples_per_partition;
 654.496 +  long **partword=_vorbis_block_alloc(vb,sizeof(*partword));
 654.497 +
 654.498 +#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
 654.499 +  FILE *of;
 654.500 +  char buffer[80];
 654.501 +#endif
 654.502 +
 654.503 +  partword[0]=_vorbis_block_alloc(vb,partvals*sizeof(*partword[0]));
 654.504 +  memset(partword[0],0,partvals*sizeof(*partword[0]));
 654.505 +
 654.506 +  for(i=0,l=info->begin/ch;i<partvals;i++){
 654.507 +    int magmax=0;
 654.508 +    int angmax=0;
 654.509 +    for(j=0;j<samples_per_partition;j+=ch){
 654.510 +      if(abs(in[0][l])>magmax)magmax=abs(in[0][l]);
 654.511 +      for(k=1;k<ch;k++)
 654.512 +        if(abs(in[k][l])>angmax)angmax=abs(in[k][l]);
 654.513 +      l++;
 654.514 +    }
 654.515 +
 654.516 +    for(j=0;j<possible_partitions-1;j++)
 654.517 +      if(magmax<=info->classmetric1[j] &&
 654.518 +         angmax<=info->classmetric2[j])
 654.519 +        break;
 654.520 +
 654.521 +    partword[0][i]=j;
 654.522 +
 654.523 +  }
 654.524 +
 654.525 +#ifdef TRAIN_RESAUX
 654.526 +  sprintf(buffer,"resaux_%d.vqd",look->train_seq);
 654.527 +  of=fopen(buffer,"a");
 654.528 +  for(i=0;i<partvals;i++)
 654.529 +    fprintf(of,"%ld, ",partword[0][i]);
 654.530 +  fprintf(of,"\n");
 654.531 +  fclose(of);
 654.532 +#endif
 654.533 +
 654.534 +  look->frames++;
 654.535 +
 654.536 +  return(partword);
 654.537 +}
 654.538 +
 654.539 +static int _01forward(oggpack_buffer *opb,
 654.540 +                      vorbis_block *vb,vorbis_look_residue *vl,
 654.541 +                      int **in,int ch,
 654.542 +                      long **partword,
 654.543 +                      int (*encode)(oggpack_buffer *,int *,int,
 654.544 +                                    codebook *,long *),
 654.545 +                      int submap){
 654.546 +  long i,j,k,s;
 654.547 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
 654.548 +  vorbis_info_residue0 *info=look->info;
 654.549 +
 654.550 +#ifdef TRAIN_RES
 654.551 +  look->submap=submap;
 654.552 +#endif
 654.553 +
 654.554 +  /* move all this setup out later */
 654.555 +  int samples_per_partition=info->grouping;
 654.556 +  int possible_partitions=info->partitions;
 654.557 +  int partitions_per_word=look->phrasebook->dim;
 654.558 +  int n=info->end-info->begin;
 654.559 +
 654.560 +  int partvals=n/samples_per_partition;
 654.561 +  long resbits[128];
 654.562 +  long resvals[128];
 654.563 +
 654.564 +#ifdef TRAIN_RES
 654.565 +  for(i=0;i<ch;i++)
 654.566 +    for(j=info->begin;j<info->end;j++){
 654.567 +      if(in[i][j]>look->tmax)look->tmax=in[i][j];
 654.568 +      if(in[i][j]<look->tmin)look->tmin=in[i][j];
 654.569 +    }
 654.570 +#endif
 654.571 +
 654.572 +  memset(resbits,0,sizeof(resbits));
 654.573 +  memset(resvals,0,sizeof(resvals));
 654.574 +
 654.575 +  /* we code the partition words for each channel, then the residual
 654.576 +     words for a partition per channel until we've written all the
 654.577 +     residual words for that partition word.  Then write the next
 654.578 +     partition channel words... */
 654.579 +
 654.580 +  for(s=0;s<look->stages;s++){
 654.581 +
 654.582 +    for(i=0;i<partvals;){
 654.583 +
 654.584 +      /* first we encode a partition codeword for each channel */
 654.585 +      if(s==0){
 654.586 +        for(j=0;j<ch;j++){
 654.587 +          long val=partword[j][i];
 654.588 +          for(k=1;k<partitions_per_word;k++){
 654.589 +            val*=possible_partitions;
 654.590 +            if(i+k<partvals)
 654.591 +              val+=partword[j][i+k];
 654.592 +          }
 654.593 +
 654.594 +          /* training hack */
 654.595 +          if(val<look->phrasebook->entries)
 654.596 +            look->phrasebits+=vorbis_book_encode(look->phrasebook,val,opb);
 654.597 +#if 0 /*def TRAIN_RES*/
 654.598 +          else
 654.599 +            fprintf(stderr,"!");
 654.600 +#endif
 654.601 +
 654.602 +        }
 654.603 +      }
 654.604 +
 654.605 +      /* now we encode interleaved residual values for the partitions */
 654.606 +      for(k=0;k<partitions_per_word && i<partvals;k++,i++){
 654.607 +        long offset=i*samples_per_partition+info->begin;
 654.608 +
 654.609 +        for(j=0;j<ch;j++){
 654.610 +          if(s==0)resvals[partword[j][i]]+=samples_per_partition;
 654.611 +          if(info->secondstages[partword[j][i]]&(1<<s)){
 654.612 +            codebook *statebook=look->partbooks[partword[j][i]][s];
 654.613 +            if(statebook){
 654.614 +              int ret;
 654.615 +              long *accumulator=NULL;
 654.616 +
 654.617 +#ifdef TRAIN_RES
 654.618 +              accumulator=look->training_data[s][partword[j][i]];
 654.619 +              {
 654.620 +                int l;
 654.621 +                int *samples=in[j]+offset;
 654.622 +                for(l=0;l<samples_per_partition;l++){
 654.623 +                  if(samples[l]<look->training_min[s][partword[j][i]])
 654.624 +                    look->training_min[s][partword[j][i]]=samples[l];
 654.625 +                  if(samples[l]>look->training_max[s][partword[j][i]])
 654.626 +                    look->training_max[s][partword[j][i]]=samples[l];
 654.627 +                }
 654.628 +              }
 654.629 +#endif
 654.630 +
 654.631 +              ret=encode(opb,in[j]+offset,samples_per_partition,
 654.632 +                         statebook,accumulator);
 654.633 +
 654.634 +              look->postbits+=ret;
 654.635 +              resbits[partword[j][i]]+=ret;
 654.636 +            }
 654.637 +          }
 654.638 +        }
 654.639 +      }
 654.640 +    }
 654.641 +  }
 654.642 +
 654.643 +  /*{
 654.644 +    long total=0;
 654.645 +    long totalbits=0;
 654.646 +    fprintf(stderr,"%d :: ",vb->mode);
 654.647 +    for(k=0;k<possible_partitions;k++){
 654.648 +    fprintf(stderr,"%ld/%1.2g, ",resvals[k],(float)resbits[k]/resvals[k]);
 654.649 +    total+=resvals[k];
 654.650 +    totalbits+=resbits[k];
 654.651 +    }
 654.652 +
 654.653 +    fprintf(stderr,":: %ld:%1.2g\n",total,(double)totalbits/total);
 654.654 +    }*/
 654.655 +
 654.656 +  return(0);
 654.657 +}
 654.658 +
 654.659 +/* a truncated packet here just means 'stop working'; it's not an error */
 654.660 +static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
 654.661 +                      float **in,int ch,
 654.662 +                      long (*decodepart)(codebook *, float *,
 654.663 +                                         oggpack_buffer *,int)){
 654.664 +
 654.665 +  long i,j,k,l,s;
 654.666 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
 654.667 +  vorbis_info_residue0 *info=look->info;
 654.668 +
 654.669 +  /* move all this setup out later */
 654.670 +  int samples_per_partition=info->grouping;
 654.671 +  int partitions_per_word=look->phrasebook->dim;
 654.672 +  int max=vb->pcmend>>1;
 654.673 +  int end=(info->end<max?info->end:max);
 654.674 +  int n=end-info->begin;
 654.675 +
 654.676 +  if(n>0){
 654.677 +    int partvals=n/samples_per_partition;
 654.678 +    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
 654.679 +    int ***partword=alloca(ch*sizeof(*partword));
 654.680 +
 654.681 +    for(j=0;j<ch;j++)
 654.682 +      partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
 654.683 +
 654.684 +    for(s=0;s<look->stages;s++){
 654.685 +
 654.686 +      /* each loop decodes on partition codeword containing
 654.687 +         partitions_per_word partitions */
 654.688 +      for(i=0,l=0;i<partvals;l++){
 654.689 +        if(s==0){
 654.690 +          /* fetch the partition word for each channel */
 654.691 +          for(j=0;j<ch;j++){
 654.692 +            int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
 654.693 +
 654.694 +            if(temp==-1 || temp>=info->partvals)goto eopbreak;
 654.695 +            partword[j][l]=look->decodemap[temp];
 654.696 +            if(partword[j][l]==NULL)goto errout;
 654.697 +          }
 654.698 +        }
 654.699 +
 654.700 +        /* now we decode residual values for the partitions */
 654.701 +        for(k=0;k<partitions_per_word && i<partvals;k++,i++)
 654.702 +          for(j=0;j<ch;j++){
 654.703 +            long offset=info->begin+i*samples_per_partition;
 654.704 +            if(info->secondstages[partword[j][l][k]]&(1<<s)){
 654.705 +              codebook *stagebook=look->partbooks[partword[j][l][k]][s];
 654.706 +              if(stagebook){
 654.707 +                if(decodepart(stagebook,in[j]+offset,&vb->opb,
 654.708 +                              samples_per_partition)==-1)goto eopbreak;
 654.709 +              }
 654.710 +            }
 654.711 +          }
 654.712 +      }
 654.713 +    }
 654.714 +  }
 654.715 + errout:
 654.716 + eopbreak:
 654.717 +  return(0);
 654.718 +}
 654.719 +
 654.720 +int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
 654.721 +                 float **in,int *nonzero,int ch){
 654.722 +  int i,used=0;
 654.723 +  for(i=0;i<ch;i++)
 654.724 +    if(nonzero[i])
 654.725 +      in[used++]=in[i];
 654.726 +  if(used)
 654.727 +    return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
 654.728 +  else
 654.729 +    return(0);
 654.730 +}
 654.731 +
 654.732 +int res1_forward(oggpack_buffer *opb,vorbis_block *vb,vorbis_look_residue *vl,
 654.733 +                 int **in,int *nonzero,int ch, long **partword, int submap){
 654.734 +  int i,used=0;
 654.735 +  for(i=0;i<ch;i++)
 654.736 +    if(nonzero[i])
 654.737 +      in[used++]=in[i];
 654.738 +
 654.739 +  if(used){
 654.740 +    return _01forward(opb,vb,vl,in,used,partword,_encodepart,submap);
 654.741 +  }else{
 654.742 +    return(0);
 654.743 +  }
 654.744 +}
 654.745 +
 654.746 +long **res1_class(vorbis_block *vb,vorbis_look_residue *vl,
 654.747 +                  int **in,int *nonzero,int ch){
 654.748 +  int i,used=0;
 654.749 +  for(i=0;i<ch;i++)
 654.750 +    if(nonzero[i])
 654.751 +      in[used++]=in[i];
 654.752 +  if(used)
 654.753 +    return(_01class(vb,vl,in,used));
 654.754 +  else
 654.755 +    return(0);
 654.756 +}
 654.757 +
 654.758 +int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
 654.759 +                 float **in,int *nonzero,int ch){
 654.760 +  int i,used=0;
 654.761 +  for(i=0;i<ch;i++)
 654.762 +    if(nonzero[i])
 654.763 +      in[used++]=in[i];
 654.764 +  if(used)
 654.765 +    return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
 654.766 +  else
 654.767 +    return(0);
 654.768 +}
 654.769 +
 654.770 +long **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
 654.771 +                  int **in,int *nonzero,int ch){
 654.772 +  int i,used=0;
 654.773 +  for(i=0;i<ch;i++)
 654.774 +    if(nonzero[i])used++;
 654.775 +  if(used)
 654.776 +    return(_2class(vb,vl,in,ch));
 654.777 +  else
 654.778 +    return(0);
 654.779 +}
 654.780 +
 654.781 +/* res2 is slightly more different; all the channels are interleaved
 654.782 +   into a single vector and encoded. */
 654.783 +
 654.784 +int res2_forward(oggpack_buffer *opb,
 654.785 +                 vorbis_block *vb,vorbis_look_residue *vl,
 654.786 +                 int **in,int *nonzero,int ch, long **partword,int submap){
 654.787 +  long i,j,k,n=vb->pcmend/2,used=0;
 654.788 +
 654.789 +  /* don't duplicate the code; use a working vector hack for now and
 654.790 +     reshape ourselves into a single channel res1 */
 654.791 +  /* ugly; reallocs for each coupling pass :-( */
 654.792 +  int *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work));
 654.793 +  for(i=0;i<ch;i++){
 654.794 +    int *pcm=in[i];
 654.795 +    if(nonzero[i])used++;
 654.796 +    for(j=0,k=i;j<n;j++,k+=ch)
 654.797 +      work[k]=pcm[j];
 654.798 +  }
 654.799 +
 654.800 +  if(used){
 654.801 +    return _01forward(opb,vb,vl,&work,1,partword,_encodepart,submap);
 654.802 +  }else{
 654.803 +    return(0);
 654.804 +  }
 654.805 +}
 654.806 +
 654.807 +/* duplicate code here as speed is somewhat more important */
 654.808 +int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
 654.809 +                 float **in,int *nonzero,int ch){
 654.810 +  long i,k,l,s;
 654.811 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
 654.812 +  vorbis_info_residue0 *info=look->info;
 654.813 +
 654.814 +  /* move all this setup out later */
 654.815 +  int samples_per_partition=info->grouping;
 654.816 +  int partitions_per_word=look->phrasebook->dim;
 654.817 +  int max=(vb->pcmend*ch)>>1;
 654.818 +  int end=(info->end<max?info->end:max);
 654.819 +  int n=end-info->begin;
 654.820 +
 654.821 +  if(n>0){
 654.822 +    int partvals=n/samples_per_partition;
 654.823 +    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
 654.824 +    int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword));
 654.825 +
 654.826 +    for(i=0;i<ch;i++)if(nonzero[i])break;
 654.827 +    if(i==ch)return(0); /* no nonzero vectors */
 654.828 +
 654.829 +    for(s=0;s<look->stages;s++){
 654.830 +      for(i=0,l=0;i<partvals;l++){
 654.831 +
 654.832 +        if(s==0){
 654.833 +          /* fetch the partition word */
 654.834 +          int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
 654.835 +          if(temp==-1 || temp>=info->partvals)goto eopbreak;
 654.836 +          partword[l]=look->decodemap[temp];
 654.837 +          if(partword[l]==NULL)goto errout;
 654.838 +        }
 654.839 +
 654.840 +        /* now we decode residual values for the partitions */
 654.841 +        for(k=0;k<partitions_per_word && i<partvals;k++,i++)
 654.842 +          if(info->secondstages[partword[l][k]]&(1<<s)){
 654.843 +            codebook *stagebook=look->partbooks[partword[l][k]][s];
 654.844 +
 654.845 +            if(stagebook){
 654.846 +              if(vorbis_book_decodevv_add(stagebook,in,
 654.847 +                                          i*samples_per_partition+info->begin,ch,
 654.848 +                                          &vb->opb,samples_per_partition)==-1)
 654.849 +                goto eopbreak;
 654.850 +            }
 654.851 +          }
 654.852 +      }
 654.853 +    }
 654.854 +  }
 654.855 + errout:
 654.856 + eopbreak:
 654.857 +  return(0);
 654.858 +}
 654.859 +
 654.860 +
 654.861 +const vorbis_func_residue residue0_exportbundle={
 654.862 +  NULL,
 654.863 +  &res0_unpack,
 654.864 +  &res0_look,
 654.865 +  &res0_free_info,
 654.866 +  &res0_free_look,
 654.867 +  NULL,
 654.868 +  NULL,
 654.869 +  &res0_inverse
 654.870 +};
 654.871 +
 654.872 +const vorbis_func_residue residue1_exportbundle={
 654.873 +  &res0_pack,
 654.874 +  &res0_unpack,
 654.875 +  &res0_look,
 654.876 +  &res0_free_info,
 654.877 +  &res0_free_look,
 654.878 +  &res1_class,
 654.879 +  &res1_forward,
 654.880 +  &res1_inverse
 654.881 +};
 654.882 +
 654.883 +const vorbis_func_residue residue2_exportbundle={
 654.884 +  &res0_pack,
 654.885 +  &res0_unpack,
 654.886 +  &res0_look,
 654.887 +  &res0_free_info,
 654.888 +  &res0_free_look,
 654.889 +  &res2_class,
 654.890 +  &res2_forward,
 654.891 +  &res2_inverse
 654.892 +};
   655.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   655.2 +++ b/libs/vorbis/scales.h	Sat Feb 01 19:58:19 2014 +0200
   655.3 @@ -0,0 +1,90 @@
   655.4 +/********************************************************************
   655.5 + *                                                                  *
   655.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   655.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   655.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   655.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  655.10 + *                                                                  *
  655.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  655.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  655.13 + *                                                                  *
  655.14 + ********************************************************************
  655.15 +
  655.16 + function: linear scale -> dB, Bark and Mel scales
  655.17 + last mod: $Id: scales.h 16227 2009-07-08 06:58:46Z xiphmont $
  655.18 +
  655.19 + ********************************************************************/
  655.20 +
  655.21 +#ifndef _V_SCALES_H_
  655.22 +#define _V_SCALES_H_
  655.23 +
  655.24 +#include <math.h>
  655.25 +#include "os.h"
  655.26 +
  655.27 +#ifdef _MSC_VER
  655.28 +/* MS Visual Studio doesn't have C99 inline keyword. */
  655.29 +#define inline __inline
  655.30 +#endif
  655.31 +
  655.32 +/* 20log10(x) */
  655.33 +#define VORBIS_IEEE_FLOAT32 1
  655.34 +#ifdef VORBIS_IEEE_FLOAT32
  655.35 +
  655.36 +static inline float unitnorm(float x){
  655.37 +  union {
  655.38 +    ogg_uint32_t i;
  655.39 +    float f;
  655.40 +  } ix;
  655.41 +  ix.f = x;
  655.42 +  ix.i = (ix.i & 0x80000000U) | (0x3f800000U);
  655.43 +  return ix.f;
  655.44 +}
  655.45 +
  655.46 +/* Segher was off (too high) by ~ .3 decibel.  Center the conversion correctly. */
  655.47 +static inline float todB(const float *x){
  655.48 +  union {
  655.49 +    ogg_uint32_t i;
  655.50 +    float f;
  655.51 +  } ix;
  655.52 +  ix.f = *x;
  655.53 +  ix.i = ix.i&0x7fffffff;
  655.54 +  return (float)(ix.i * 7.17711438e-7f -764.6161886f);
  655.55 +}
  655.56 +
  655.57 +#define todB_nn(x) todB(x)
  655.58 +
  655.59 +#else
  655.60 +
  655.61 +static float unitnorm(float x){
  655.62 +  if(x<0)return(-1.f);
  655.63 +  return(1.f);
  655.64 +}
  655.65 +
  655.66 +#define todB(x)   (*(x)==0?-400.f:log(*(x)**(x))*4.34294480f)
  655.67 +#define todB_nn(x)   (*(x)==0.f?-400.f:log(*(x))*8.6858896f)
  655.68 +
  655.69 +#endif
  655.70 +
  655.71 +#define fromdB(x) (exp((x)*.11512925f))
  655.72 +
  655.73 +/* The bark scale equations are approximations, since the original
  655.74 +   table was somewhat hand rolled.  The below are chosen to have the
  655.75 +   best possible fit to the rolled tables, thus their somewhat odd
  655.76 +   appearance (these are more accurate and over a longer range than
  655.77 +   the oft-quoted bark equations found in the texts I have).  The
  655.78 +   approximations are valid from 0 - 30kHz (nyquist) or so.
  655.79 +
  655.80 +   all f in Hz, z in Bark */
  655.81 +
  655.82 +#define toBARK(n)   (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
  655.83 +#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f)
  655.84 +#define toMEL(n)    (log(1.f+(n)*.001f)*1442.695f)
  655.85 +#define fromMEL(m)  (1000.f*exp((m)/1442.695f)-1000.f)
  655.86 +
  655.87 +/* Frequency to octave.  We arbitrarily declare 63.5 Hz to be octave
  655.88 +   0.0 */
  655.89 +
  655.90 +#define toOC(n)     (log(n)*1.442695f-5.965784f)
  655.91 +#define fromOC(o)   (exp(((o)+5.965784f)*.693147f))
  655.92 +
  655.93 +#endif
   656.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   656.2 +++ b/libs/vorbis/sharedbook.c	Sat Feb 01 19:58:19 2014 +0200
   656.3 @@ -0,0 +1,579 @@
   656.4 +/********************************************************************
   656.5 + *                                                                  *
   656.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   656.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   656.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   656.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  656.10 + *                                                                  *
  656.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  656.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  656.13 + *                                                                  *
  656.14 + ********************************************************************
  656.15 +
  656.16 + function: basic shared codebook operations
  656.17 + last mod: $Id: sharedbook.c 17030 2010-03-25 06:52:55Z xiphmont $
  656.18 +
  656.19 + ********************************************************************/
  656.20 +
  656.21 +#include <stdlib.h>
  656.22 +#include <math.h>
  656.23 +#include <string.h>
  656.24 +#include <ogg/ogg.h>
  656.25 +#include "os.h"
  656.26 +#include "misc.h"
  656.27 +#include "vorbis/codec.h"
  656.28 +#include "codebook.h"
  656.29 +#include "scales.h"
  656.30 +
  656.31 +/**** pack/unpack helpers ******************************************/
  656.32 +int _ilog(unsigned int v){
  656.33 +  int ret=0;
  656.34 +  while(v){
  656.35 +    ret++;
  656.36 +    v>>=1;
  656.37 +  }
  656.38 +  return(ret);
  656.39 +}
  656.40 +
  656.41 +/* 32 bit float (not IEEE; nonnormalized mantissa +
  656.42 +   biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
  656.43 +   Why not IEEE?  It's just not that important here. */
  656.44 +
  656.45 +#define VQ_FEXP 10
  656.46 +#define VQ_FMAN 21
  656.47 +#define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */
  656.48 +
  656.49 +/* doesn't currently guard under/overflow */
  656.50 +long _float32_pack(float val){
  656.51 +  int sign=0;
  656.52 +  long exp;
  656.53 +  long mant;
  656.54 +  if(val<0){
  656.55 +    sign=0x80000000;
  656.56 +    val= -val;
  656.57 +  }
  656.58 +  exp= floor(log(val)/log(2.f)+.001); /*+epsilon*/
  656.59 +  mant=rint(ldexp(val,(VQ_FMAN-1)-exp));
  656.60 +  exp=(exp+VQ_FEXP_BIAS)<<VQ_FMAN;
  656.61 +
  656.62 +  return(sign|exp|mant);
  656.63 +}
  656.64 +
  656.65 +float _float32_unpack(long val){
  656.66 +  double mant=val&0x1fffff;
  656.67 +  int    sign=val&0x80000000;
  656.68 +  long   exp =(val&0x7fe00000L)>>VQ_FMAN;
  656.69 +  if(sign)mant= -mant;
  656.70 +  return(ldexp(mant,exp-(VQ_FMAN-1)-VQ_FEXP_BIAS));
  656.71 +}
  656.72 +
  656.73 +/* given a list of word lengths, generate a list of codewords.  Works
  656.74 +   for length ordered or unordered, always assigns the lowest valued
  656.75 +   codewords first.  Extended to handle unused entries (length 0) */
  656.76 +ogg_uint32_t *_make_words(long *l,long n,long sparsecount){
  656.77 +  long i,j,count=0;
  656.78 +  ogg_uint32_t marker[33];
  656.79 +  ogg_uint32_t *r=_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r));
  656.80 +  memset(marker,0,sizeof(marker));
  656.81 +
  656.82 +  for(i=0;i<n;i++){
  656.83 +    long length=l[i];
  656.84 +    if(length>0){
  656.85 +      ogg_uint32_t entry=marker[length];
  656.86 +
  656.87 +      /* when we claim a node for an entry, we also claim the nodes
  656.88 +         below it (pruning off the imagined tree that may have dangled
  656.89 +         from it) as well as blocking the use of any nodes directly
  656.90 +         above for leaves */
  656.91 +
  656.92 +      /* update ourself */
  656.93 +      if(length<32 && (entry>>length)){
  656.94 +        /* error condition; the lengths must specify an overpopulated tree */
  656.95 +        _ogg_free(r);
  656.96 +        return(NULL);
  656.97 +      }
  656.98 +      r[count++]=entry;
  656.99 +
 656.100 +      /* Look to see if the next shorter marker points to the node
 656.101 +         above. if so, update it and repeat.  */
 656.102 +      {
 656.103 +        for(j=length;j>0;j--){
 656.104 +
 656.105 +          if(marker[j]&1){
 656.106 +            /* have to jump branches */
 656.107 +            if(j==1)
 656.108 +              marker[1]++;
 656.109 +            else
 656.110 +              marker[j]=marker[j-1]<<1;
 656.111 +            break; /* invariant says next upper marker would already
 656.112 +                      have been moved if it was on the same path */
 656.113 +          }
 656.114 +          marker[j]++;
 656.115 +        }
 656.116 +      }
 656.117 +
 656.118 +      /* prune the tree; the implicit invariant says all the longer
 656.119 +         markers were dangling from our just-taken node.  Dangle them
 656.120 +         from our *new* node. */
 656.121 +      for(j=length+1;j<33;j++)
 656.122 +        if((marker[j]>>1) == entry){
 656.123 +          entry=marker[j];
 656.124 +          marker[j]=marker[j-1]<<1;
 656.125 +        }else
 656.126 +          break;
 656.127 +    }else
 656.128 +      if(sparsecount==0)count++;
 656.129 +  }
 656.130 +
 656.131 +  /* sanity check the huffman tree; an underpopulated tree must be
 656.132 +     rejected. The only exception is the one-node pseudo-nil tree,
 656.133 +     which appears to be underpopulated because the tree doesn't
 656.134 +     really exist; there's only one possible 'codeword' or zero bits,
 656.135 +     but the above tree-gen code doesn't mark that. */
 656.136 +  if(sparsecount != 1){
 656.137 +    for(i=1;i<33;i++)
 656.138 +      if(marker[i] & (0xffffffffUL>>(32-i))){
 656.139 +	_ogg_free(r);
 656.140 +	return(NULL);
 656.141 +      }
 656.142 +  }
 656.143 +
 656.144 +  /* bitreverse the words because our bitwise packer/unpacker is LSb
 656.145 +     endian */
 656.146 +  for(i=0,count=0;i<n;i++){
 656.147 +    ogg_uint32_t temp=0;
 656.148 +    for(j=0;j<l[i];j++){
 656.149 +      temp<<=1;
 656.150 +      temp|=(r[count]>>j)&1;
 656.151 +    }
 656.152 +
 656.153 +    if(sparsecount){
 656.154 +      if(l[i])
 656.155 +        r[count++]=temp;
 656.156 +    }else
 656.157 +      r[count++]=temp;
 656.158 +  }
 656.159 +
 656.160 +  return(r);
 656.161 +}
 656.162 +
 656.163 +/* there might be a straightforward one-line way to do the below
 656.164 +   that's portable and totally safe against roundoff, but I haven't
 656.165 +   thought of it.  Therefore, we opt on the side of caution */
 656.166 +long _book_maptype1_quantvals(const static_codebook *b){
 656.167 +  long vals=floor(pow((float)b->entries,1.f/b->dim));
 656.168 +
 656.169 +  /* the above *should* be reliable, but we'll not assume that FP is
 656.170 +     ever reliable when bitstream sync is at stake; verify via integer
 656.171 +     means that vals really is the greatest value of dim for which
 656.172 +     vals^b->bim <= b->entries */
 656.173 +  /* treat the above as an initial guess */
 656.174 +  while(1){
 656.175 +    long acc=1;
 656.176 +    long acc1=1;
 656.177 +    int i;
 656.178 +    for(i=0;i<b->dim;i++){
 656.179 +      acc*=vals;
 656.180 +      acc1*=vals+1;
 656.181 +    }
 656.182 +    if(acc<=b->entries && acc1>b->entries){
 656.183 +      return(vals);
 656.184 +    }else{
 656.185 +      if(acc>b->entries){
 656.186 +        vals--;
 656.187 +      }else{
 656.188 +        vals++;
 656.189 +      }
 656.190 +    }
 656.191 +  }
 656.192 +}
 656.193 +
 656.194 +/* unpack the quantized list of values for encode/decode ***********/
 656.195 +/* we need to deal with two map types: in map type 1, the values are
 656.196 +   generated algorithmically (each column of the vector counts through
 656.197 +   the values in the quant vector). in map type 2, all the values came
 656.198 +   in in an explicit list.  Both value lists must be unpacked */
 656.199 +float *_book_unquantize(const static_codebook *b,int n,int *sparsemap){
 656.200 +  long j,k,count=0;
 656.201 +  if(b->maptype==1 || b->maptype==2){
 656.202 +    int quantvals;
 656.203 +    float mindel=_float32_unpack(b->q_min);
 656.204 +    float delta=_float32_unpack(b->q_delta);
 656.205 +    float *r=_ogg_calloc(n*b->dim,sizeof(*r));
 656.206 +
 656.207 +    /* maptype 1 and 2 both use a quantized value vector, but
 656.208 +       different sizes */
 656.209 +    switch(b->maptype){
 656.210 +    case 1:
 656.211 +      /* most of the time, entries%dimensions == 0, but we need to be
 656.212 +         well defined.  We define that the possible vales at each
 656.213 +         scalar is values == entries/dim.  If entries%dim != 0, we'll
 656.214 +         have 'too few' values (values*dim<entries), which means that
 656.215 +         we'll have 'left over' entries; left over entries use zeroed
 656.216 +         values (and are wasted).  So don't generate codebooks like
 656.217 +         that */
 656.218 +      quantvals=_book_maptype1_quantvals(b);
 656.219 +      for(j=0;j<b->entries;j++){
 656.220 +        if((sparsemap && b->lengthlist[j]) || !sparsemap){
 656.221 +          float last=0.f;
 656.222 +          int indexdiv=1;
 656.223 +          for(k=0;k<b->dim;k++){
 656.224 +            int index= (j/indexdiv)%quantvals;
 656.225 +            float val=b->quantlist[index];
 656.226 +            val=fabs(val)*delta+mindel+last;
 656.227 +            if(b->q_sequencep)last=val;
 656.228 +            if(sparsemap)
 656.229 +              r[sparsemap[count]*b->dim+k]=val;
 656.230 +            else
 656.231 +              r[count*b->dim+k]=val;
 656.232 +            indexdiv*=quantvals;
 656.233 +          }
 656.234 +          count++;
 656.235 +        }
 656.236 +
 656.237 +      }
 656.238 +      break;
 656.239 +    case 2:
 656.240 +      for(j=0;j<b->entries;j++){
 656.241 +        if((sparsemap && b->lengthlist[j]) || !sparsemap){
 656.242 +          float last=0.f;
 656.243 +
 656.244 +          for(k=0;k<b->dim;k++){
 656.245 +            float val=b->quantlist[j*b->dim+k];
 656.246 +            val=fabs(val)*delta+mindel+last;
 656.247 +            if(b->q_sequencep)last=val;
 656.248 +            if(sparsemap)
 656.249 +              r[sparsemap[count]*b->dim+k]=val;
 656.250 +            else
 656.251 +              r[count*b->dim+k]=val;
 656.252 +          }
 656.253 +          count++;
 656.254 +        }
 656.255 +      }
 656.256 +      break;
 656.257 +    }
 656.258 +
 656.259 +    return(r);
 656.260 +  }
 656.261 +  return(NULL);
 656.262 +}
 656.263 +
 656.264 +void vorbis_staticbook_destroy(static_codebook *b){
 656.265 +  if(b->allocedp){
 656.266 +    if(b->quantlist)_ogg_free(b->quantlist);
 656.267 +    if(b->lengthlist)_ogg_free(b->lengthlist);
 656.268 +    memset(b,0,sizeof(*b));
 656.269 +    _ogg_free(b);
 656.270 +  } /* otherwise, it is in static memory */
 656.271 +}
 656.272 +
 656.273 +void vorbis_book_clear(codebook *b){
 656.274 +  /* static book is not cleared; we're likely called on the lookup and
 656.275 +     the static codebook belongs to the info struct */
 656.276 +  if(b->valuelist)_ogg_free(b->valuelist);
 656.277 +  if(b->codelist)_ogg_free(b->codelist);
 656.278 +
 656.279 +  if(b->dec_index)_ogg_free(b->dec_index);
 656.280 +  if(b->dec_codelengths)_ogg_free(b->dec_codelengths);
 656.281 +  if(b->dec_firsttable)_ogg_free(b->dec_firsttable);
 656.282 +
 656.283 +  memset(b,0,sizeof(*b));
 656.284 +}
 656.285 +
 656.286 +int vorbis_book_init_encode(codebook *c,const static_codebook *s){
 656.287 +
 656.288 +  memset(c,0,sizeof(*c));
 656.289 +  c->c=s;
 656.290 +  c->entries=s->entries;
 656.291 +  c->used_entries=s->entries;
 656.292 +  c->dim=s->dim;
 656.293 +  c->codelist=_make_words(s->lengthlist,s->entries,0);
 656.294 +  /*c->valuelist=_book_unquantize(s,s->entries,NULL);*/
 656.295 +  c->quantvals=_book_maptype1_quantvals(s);
 656.296 +  c->minval=(int)rint(_float32_unpack(s->q_min));
 656.297 +  c->delta=(int)rint(_float32_unpack(s->q_delta));
 656.298 +
 656.299 +  return(0);
 656.300 +}
 656.301 +
 656.302 +static ogg_uint32_t bitreverse(ogg_uint32_t x){
 656.303 +  x=    ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL);
 656.304 +  x=    ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL);
 656.305 +  x=    ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL);
 656.306 +  x=    ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL);
 656.307 +  return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL);
 656.308 +}
 656.309 +
 656.310 +static int sort32a(const void *a,const void *b){
 656.311 +  return ( **(ogg_uint32_t **)a>**(ogg_uint32_t **)b)-
 656.312 +    ( **(ogg_uint32_t **)a<**(ogg_uint32_t **)b);
 656.313 +}
 656.314 +
 656.315 +/* decode codebook arrangement is more heavily optimized than encode */
 656.316 +int vorbis_book_init_decode(codebook *c,const static_codebook *s){
 656.317 +  int i,j,n=0,tabn;
 656.318 +  int *sortindex;
 656.319 +  memset(c,0,sizeof(*c));
 656.320 +
 656.321 +  /* count actually used entries */
 656.322 +  for(i=0;i<s->entries;i++)
 656.323 +    if(s->lengthlist[i]>0)
 656.324 +      n++;
 656.325 +
 656.326 +  c->entries=s->entries;
 656.327 +  c->used_entries=n;
 656.328 +  c->dim=s->dim;
 656.329 +
 656.330 +  if(n>0){
 656.331 +
 656.332 +    /* two different remappings go on here.
 656.333 +
 656.334 +    First, we collapse the likely sparse codebook down only to
 656.335 +    actually represented values/words.  This collapsing needs to be
 656.336 +    indexed as map-valueless books are used to encode original entry
 656.337 +    positions as integers.
 656.338 +
 656.339 +    Second, we reorder all vectors, including the entry index above,
 656.340 +    by sorted bitreversed codeword to allow treeless decode. */
 656.341 +
 656.342 +    /* perform sort */
 656.343 +    ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries);
 656.344 +    ogg_uint32_t **codep=alloca(sizeof(*codep)*n);
 656.345 +
 656.346 +    if(codes==NULL)goto err_out;
 656.347 +
 656.348 +    for(i=0;i<n;i++){
 656.349 +      codes[i]=bitreverse(codes[i]);
 656.350 +      codep[i]=codes+i;
 656.351 +    }
 656.352 +
 656.353 +    qsort(codep,n,sizeof(*codep),sort32a);
 656.354 +
 656.355 +    sortindex=alloca(n*sizeof(*sortindex));
 656.356 +    c->codelist=_ogg_malloc(n*sizeof(*c->codelist));
 656.357 +    /* the index is a reverse index */
 656.358 +    for(i=0;i<n;i++){
 656.359 +      int position=codep[i]-codes;
 656.360 +      sortindex[position]=i;
 656.361 +    }
 656.362 +
 656.363 +    for(i=0;i<n;i++)
 656.364 +      c->codelist[sortindex[i]]=codes[i];
 656.365 +    _ogg_free(codes);
 656.366 +
 656.367 +
 656.368 +    c->valuelist=_book_unquantize(s,n,sortindex);
 656.369 +    c->dec_index=_ogg_malloc(n*sizeof(*c->dec_index));
 656.370 +
 656.371 +    for(n=0,i=0;i<s->entries;i++)
 656.372 +      if(s->lengthlist[i]>0)
 656.373 +        c->dec_index[sortindex[n++]]=i;
 656.374 +
 656.375 +    c->dec_codelengths=_ogg_malloc(n*sizeof(*c->dec_codelengths));
 656.376 +    for(n=0,i=0;i<s->entries;i++)
 656.377 +      if(s->lengthlist[i]>0)
 656.378 +        c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
 656.379 +
 656.380 +    c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */
 656.381 +    if(c->dec_firsttablen<5)c->dec_firsttablen=5;
 656.382 +    if(c->dec_firsttablen>8)c->dec_firsttablen=8;
 656.383 +
 656.384 +    tabn=1<<c->dec_firsttablen;
 656.385 +    c->dec_firsttable=_ogg_calloc(tabn,sizeof(*c->dec_firsttable));
 656.386 +    c->dec_maxlength=0;
 656.387 +
 656.388 +    for(i=0;i<n;i++){
 656.389 +      if(c->dec_maxlength<c->dec_codelengths[i])
 656.390 +        c->dec_maxlength=c->dec_codelengths[i];
 656.391 +      if(c->dec_codelengths[i]<=c->dec_firsttablen){
 656.392 +        ogg_uint32_t orig=bitreverse(c->codelist[i]);
 656.393 +        for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++)
 656.394 +          c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1;
 656.395 +      }
 656.396 +    }
 656.397 +
 656.398 +    /* now fill in 'unused' entries in the firsttable with hi/lo search
 656.399 +       hints for the non-direct-hits */
 656.400 +    {
 656.401 +      ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen);
 656.402 +      long lo=0,hi=0;
 656.403 +
 656.404 +      for(i=0;i<tabn;i++){
 656.405 +        ogg_uint32_t word=i<<(32-c->dec_firsttablen);
 656.406 +        if(c->dec_firsttable[bitreverse(word)]==0){
 656.407 +          while((lo+1)<n && c->codelist[lo+1]<=word)lo++;
 656.408 +          while(    hi<n && word>=(c->codelist[hi]&mask))hi++;
 656.409 +
 656.410 +          /* we only actually have 15 bits per hint to play with here.
 656.411 +             In order to overflow gracefully (nothing breaks, efficiency
 656.412 +             just drops), encode as the difference from the extremes. */
 656.413 +          {
 656.414 +            unsigned long loval=lo;
 656.415 +            unsigned long hival=n-hi;
 656.416 +
 656.417 +            if(loval>0x7fff)loval=0x7fff;
 656.418 +            if(hival>0x7fff)hival=0x7fff;
 656.419 +            c->dec_firsttable[bitreverse(word)]=
 656.420 +              0x80000000UL | (loval<<15) | hival;
 656.421 +          }
 656.422 +        }
 656.423 +      }
 656.424 +    }
 656.425 +  }
 656.426 +
 656.427 +  return(0);
 656.428 + err_out:
 656.429 +  vorbis_book_clear(c);
 656.430 +  return(-1);
 656.431 +}
 656.432 +
 656.433 +long vorbis_book_codeword(codebook *book,int entry){
 656.434 +  if(book->c) /* only use with encode; decode optimizations are
 656.435 +                 allowed to break this */
 656.436 +    return book->codelist[entry];
 656.437 +  return -1;
 656.438 +}
 656.439 +
 656.440 +long vorbis_book_codelen(codebook *book,int entry){
 656.441 +  if(book->c) /* only use with encode; decode optimizations are
 656.442 +                 allowed to break this */
 656.443 +    return book->c->lengthlist[entry];
 656.444 +  return -1;
 656.445 +}
 656.446 +
 656.447 +#ifdef _V_SELFTEST
 656.448 +
 656.449 +/* Unit tests of the dequantizer; this stuff will be OK
 656.450 +   cross-platform, I simply want to be sure that special mapping cases
 656.451 +   actually work properly; a bug could go unnoticed for a while */
 656.452 +
 656.453 +#include <stdio.h>
 656.454 +
 656.455 +/* cases:
 656.456 +
 656.457 +   no mapping
 656.458 +   full, explicit mapping
 656.459 +   algorithmic mapping
 656.460 +
 656.461 +   nonsequential
 656.462 +   sequential
 656.463 +*/
 656.464 +
 656.465 +static long full_quantlist1[]={0,1,2,3,    4,5,6,7, 8,3,6,1};
 656.466 +static long partial_quantlist1[]={0,7,2};
 656.467 +
 656.468 +/* no mapping */
 656.469 +static_codebook test1={
 656.470 +  4,16,
 656.471 +  NULL,
 656.472 +  0,
 656.473 +  0,0,0,0,
 656.474 +  NULL,
 656.475 +  0
 656.476 +};
 656.477 +static float *test1_result=NULL;
 656.478 +
 656.479 +/* linear, full mapping, nonsequential */
 656.480 +static_codebook test2={
 656.481 +  4,3,
 656.482 +  NULL,
 656.483 +  2,
 656.484 +  -533200896,1611661312,4,0,
 656.485 +  full_quantlist1,
 656.486 +  0
 656.487 +};
 656.488 +static float test2_result[]={-3,-2,-1,0, 1,2,3,4, 5,0,3,-2};
 656.489 +
 656.490 +/* linear, full mapping, sequential */
 656.491 +static_codebook test3={
 656.492 +  4,3,
 656.493 +  NULL,
 656.494 +  2,
 656.495 +  -533200896,1611661312,4,1,
 656.496 +  full_quantlist1,
 656.497 +  0
 656.498 +};
 656.499 +static float test3_result[]={-3,-5,-6,-6, 1,3,6,10, 5,5,8,6};
 656.500 +
 656.501 +/* linear, algorithmic mapping, nonsequential */
 656.502 +static_codebook test4={
 656.503 +  3,27,
 656.504 +  NULL,
 656.505 +  1,
 656.506 +  -533200896,1611661312,4,0,
 656.507 +  partial_quantlist1,
 656.508 +  0
 656.509 +};
 656.510 +static float test4_result[]={-3,-3,-3, 4,-3,-3, -1,-3,-3,
 656.511 +                              -3, 4,-3, 4, 4,-3, -1, 4,-3,
 656.512 +                              -3,-1,-3, 4,-1,-3, -1,-1,-3,
 656.513 +                              -3,-3, 4, 4,-3, 4, -1,-3, 4,
 656.514 +                              -3, 4, 4, 4, 4, 4, -1, 4, 4,
 656.515 +                              -3,-1, 4, 4,-1, 4, -1,-1, 4,
 656.516 +                              -3,-3,-1, 4,-3,-1, -1,-3,-1,
 656.517 +                              -3, 4,-1, 4, 4,-1, -1, 4,-1,
 656.518 +                              -3,-1,-1, 4,-1,-1, -1,-1,-1};
 656.519 +
 656.520 +/* linear, algorithmic mapping, sequential */
 656.521 +static_codebook test5={
 656.522 +  3,27,
 656.523 +  NULL,
 656.524 +  1,
 656.525 +  -533200896,1611661312,4,1,
 656.526 +  partial_quantlist1,
 656.527 +  0
 656.528 +};
 656.529 +static float test5_result[]={-3,-6,-9, 4, 1,-2, -1,-4,-7,
 656.530 +                              -3, 1,-2, 4, 8, 5, -1, 3, 0,
 656.531 +                              -3,-4,-7, 4, 3, 0, -1,-2,-5,
 656.532 +                              -3,-6,-2, 4, 1, 5, -1,-4, 0,
 656.533 +                              -3, 1, 5, 4, 8,12, -1, 3, 7,
 656.534 +                              -3,-4, 0, 4, 3, 7, -1,-2, 2,
 656.535 +                              -3,-6,-7, 4, 1, 0, -1,-4,-5,
 656.536 +                              -3, 1, 0, 4, 8, 7, -1, 3, 2,
 656.537 +                              -3,-4,-5, 4, 3, 2, -1,-2,-3};
 656.538 +
 656.539 +void run_test(static_codebook *b,float *comp){
 656.540 +  float *out=_book_unquantize(b,b->entries,NULL);
 656.541 +  int i;
 656.542 +
 656.543 +  if(comp){
 656.544 +    if(!out){
 656.545 +      fprintf(stderr,"_book_unquantize incorrectly returned NULL\n");
 656.546 +      exit(1);
 656.547 +    }
 656.548 +
 656.549 +    for(i=0;i<b->entries*b->dim;i++)
 656.550 +      if(fabs(out[i]-comp[i])>.0001){
 656.551 +        fprintf(stderr,"disagreement in unquantized and reference data:\n"
 656.552 +                "position %d, %g != %g\n",i,out[i],comp[i]);
 656.553 +        exit(1);
 656.554 +      }
 656.555 +
 656.556 +  }else{
 656.557 +    if(out){
 656.558 +      fprintf(stderr,"_book_unquantize returned a value array: \n"
 656.559 +              " correct result should have been NULL\n");
 656.560 +      exit(1);
 656.561 +    }
 656.562 +  }
 656.563 +}
 656.564 +
 656.565 +int main(){
 656.566 +  /* run the nine dequant tests, and compare to the hand-rolled results */
 656.567 +  fprintf(stderr,"Dequant test 1... ");
 656.568 +  run_test(&test1,test1_result);
 656.569 +  fprintf(stderr,"OK\nDequant test 2... ");
 656.570 +  run_test(&test2,test2_result);
 656.571 +  fprintf(stderr,"OK\nDequant test 3... ");
 656.572 +  run_test(&test3,test3_result);
 656.573 +  fprintf(stderr,"OK\nDequant test 4... ");
 656.574 +  run_test(&test4,test4_result);
 656.575 +  fprintf(stderr,"OK\nDequant test 5... ");
 656.576 +  run_test(&test5,test5_result);
 656.577 +  fprintf(stderr,"OK\n\n");
 656.578 +
 656.579 +  return(0);
 656.580 +}
 656.581 +
 656.582 +#endif
   657.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   657.2 +++ b/libs/vorbis/smallft.c	Sat Feb 01 19:58:19 2014 +0200
   657.3 @@ -0,0 +1,1255 @@
   657.4 +/********************************************************************
   657.5 + *                                                                  *
   657.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   657.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   657.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   657.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  657.10 + *                                                                  *
  657.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  657.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  657.13 + *                                                                  *
  657.14 + ********************************************************************
  657.15 +
  657.16 + function: *unnormalized* fft transform
  657.17 + last mod: $Id: smallft.c 16227 2009-07-08 06:58:46Z xiphmont $
  657.18 +
  657.19 + ********************************************************************/
  657.20 +
  657.21 +/* FFT implementation from OggSquish, minus cosine transforms,
  657.22 + * minus all but radix 2/4 case.  In Vorbis we only need this
  657.23 + * cut-down version.
  657.24 + *
  657.25 + * To do more than just power-of-two sized vectors, see the full
  657.26 + * version I wrote for NetLib.
  657.27 + *
  657.28 + * Note that the packing is a little strange; rather than the FFT r/i
  657.29 + * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1,
  657.30 + * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the
  657.31 + * FORTRAN version
  657.32 + */
  657.33 +
  657.34 +#include <stdlib.h>
  657.35 +#include <string.h>
  657.36 +#include <math.h>
  657.37 +#include "smallft.h"
  657.38 +#include "os.h"
  657.39 +#include "misc.h"
  657.40 +
  657.41 +static void drfti1(int n, float *wa, int *ifac){
  657.42 +  static int ntryh[4] = { 4,2,3,5 };
  657.43 +  static float tpi = 6.28318530717958648f;
  657.44 +  float arg,argh,argld,fi;
  657.45 +  int ntry=0,i,j=-1;
  657.46 +  int k1, l1, l2, ib;
  657.47 +  int ld, ii, ip, is, nq, nr;
  657.48 +  int ido, ipm, nfm1;
  657.49 +  int nl=n;
  657.50 +  int nf=0;
  657.51 +
  657.52 + L101:
  657.53 +  j++;
  657.54 +  if (j < 4)
  657.55 +    ntry=ntryh[j];
  657.56 +  else
  657.57 +    ntry+=2;
  657.58 +
  657.59 + L104:
  657.60 +  nq=nl/ntry;
  657.61 +  nr=nl-ntry*nq;
  657.62 +  if (nr!=0) goto L101;
  657.63 +
  657.64 +  nf++;
  657.65 +  ifac[nf+1]=ntry;
  657.66 +  nl=nq;
  657.67 +  if(ntry!=2)goto L107;
  657.68 +  if(nf==1)goto L107;
  657.69 +
  657.70 +  for (i=1;i<nf;i++){
  657.71 +    ib=nf-i+1;
  657.72 +    ifac[ib+1]=ifac[ib];
  657.73 +  }
  657.74 +  ifac[2] = 2;
  657.75 +
  657.76 + L107:
  657.77 +  if(nl!=1)goto L104;
  657.78 +  ifac[0]=n;
  657.79 +  ifac[1]=nf;
  657.80 +  argh=tpi/n;
  657.81 +  is=0;
  657.82 +  nfm1=nf-1;
  657.83 +  l1=1;
  657.84 +
  657.85 +  if(nfm1==0)return;
  657.86 +
  657.87 +  for (k1=0;k1<nfm1;k1++){
  657.88 +    ip=ifac[k1+2];
  657.89 +    ld=0;
  657.90 +    l2=l1*ip;
  657.91 +    ido=n/l2;
  657.92 +    ipm=ip-1;
  657.93 +
  657.94 +    for (j=0;j<ipm;j++){
  657.95 +      ld+=l1;
  657.96 +      i=is;
  657.97 +      argld=(float)ld*argh;
  657.98 +      fi=0.f;
  657.99 +      for (ii=2;ii<ido;ii+=2){
 657.100 +        fi+=1.f;
 657.101 +        arg=fi*argld;
 657.102 +        wa[i++]=cos(arg);
 657.103 +        wa[i++]=sin(arg);
 657.104 +      }
 657.105 +      is+=ido;
 657.106 +    }
 657.107 +    l1=l2;
 657.108 +  }
 657.109 +}
 657.110 +
 657.111 +static void fdrffti(int n, float *wsave, int *ifac){
 657.112 +
 657.113 +  if (n == 1) return;
 657.114 +  drfti1(n, wsave+n, ifac);
 657.115 +}
 657.116 +
 657.117 +static void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){
 657.118 +  int i,k;
 657.119 +  float ti2,tr2;
 657.120 +  int t0,t1,t2,t3,t4,t5,t6;
 657.121 +
 657.122 +  t1=0;
 657.123 +  t0=(t2=l1*ido);
 657.124 +  t3=ido<<1;
 657.125 +  for(k=0;k<l1;k++){
 657.126 +    ch[t1<<1]=cc[t1]+cc[t2];
 657.127 +    ch[(t1<<1)+t3-1]=cc[t1]-cc[t2];
 657.128 +    t1+=ido;
 657.129 +    t2+=ido;
 657.130 +  }
 657.131 +
 657.132 +  if(ido<2)return;
 657.133 +  if(ido==2)goto L105;
 657.134 +
 657.135 +  t1=0;
 657.136 +  t2=t0;
 657.137 +  for(k=0;k<l1;k++){
 657.138 +    t3=t2;
 657.139 +    t4=(t1<<1)+(ido<<1);
 657.140 +    t5=t1;
 657.141 +    t6=t1+t1;
 657.142 +    for(i=2;i<ido;i+=2){
 657.143 +      t3+=2;
 657.144 +      t4-=2;
 657.145 +      t5+=2;
 657.146 +      t6+=2;
 657.147 +      tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
 657.148 +      ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
 657.149 +      ch[t6]=cc[t5]+ti2;
 657.150 +      ch[t4]=ti2-cc[t5];
 657.151 +      ch[t6-1]=cc[t5-1]+tr2;
 657.152 +      ch[t4-1]=cc[t5-1]-tr2;
 657.153 +    }
 657.154 +    t1+=ido;
 657.155 +    t2+=ido;
 657.156 +  }
 657.157 +
 657.158 +  if(ido%2==1)return;
 657.159 +
 657.160 + L105:
 657.161 +  t3=(t2=(t1=ido)-1);
 657.162 +  t2+=t0;
 657.163 +  for(k=0;k<l1;k++){
 657.164 +    ch[t1]=-cc[t2];
 657.165 +    ch[t1-1]=cc[t3];
 657.166 +    t1+=ido<<1;
 657.167 +    t2+=ido;
 657.168 +    t3+=ido;
 657.169 +  }
 657.170 +}
 657.171 +
 657.172 +static void dradf4(int ido,int l1,float *cc,float *ch,float *wa1,
 657.173 +            float *wa2,float *wa3){
 657.174 +  static float hsqt2 = .70710678118654752f;
 657.175 +  int i,k,t0,t1,t2,t3,t4,t5,t6;
 657.176 +  float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
 657.177 +  t0=l1*ido;
 657.178 +
 657.179 +  t1=t0;
 657.180 +  t4=t1<<1;
 657.181 +  t2=t1+(t1<<1);
 657.182 +  t3=0;
 657.183 +
 657.184 +  for(k=0;k<l1;k++){
 657.185 +    tr1=cc[t1]+cc[t2];
 657.186 +    tr2=cc[t3]+cc[t4];
 657.187 +
 657.188 +    ch[t5=t3<<2]=tr1+tr2;
 657.189 +    ch[(ido<<2)+t5-1]=tr2-tr1;
 657.190 +    ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4];
 657.191 +    ch[t5]=cc[t2]-cc[t1];
 657.192 +
 657.193 +    t1+=ido;
 657.194 +    t2+=ido;
 657.195 +    t3+=ido;
 657.196 +    t4+=ido;
 657.197 +  }
 657.198 +
 657.199 +  if(ido<2)return;
 657.200 +  if(ido==2)goto L105;
 657.201 +
 657.202 +
 657.203 +  t1=0;
 657.204 +  for(k=0;k<l1;k++){
 657.205 +    t2=t1;
 657.206 +    t4=t1<<2;
 657.207 +    t5=(t6=ido<<1)+t4;
 657.208 +    for(i=2;i<ido;i+=2){
 657.209 +      t3=(t2+=2);
 657.210 +      t4+=2;
 657.211 +      t5-=2;
 657.212 +
 657.213 +      t3+=t0;
 657.214 +      cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
 657.215 +      ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
 657.216 +      t3+=t0;
 657.217 +      cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3];
 657.218 +      ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1];
 657.219 +      t3+=t0;
 657.220 +      cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3];
 657.221 +      ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1];
 657.222 +
 657.223 +      tr1=cr2+cr4;
 657.224 +      tr4=cr4-cr2;
 657.225 +      ti1=ci2+ci4;
 657.226 +      ti4=ci2-ci4;
 657.227 +
 657.228 +      ti2=cc[t2]+ci3;
 657.229 +      ti3=cc[t2]-ci3;
 657.230 +      tr2=cc[t2-1]+cr3;
 657.231 +      tr3=cc[t2-1]-cr3;
 657.232 +
 657.233 +      ch[t4-1]=tr1+tr2;
 657.234 +      ch[t4]=ti1+ti2;
 657.235 +
 657.236 +      ch[t5-1]=tr3-ti4;
 657.237 +      ch[t5]=tr4-ti3;
 657.238 +
 657.239 +      ch[t4+t6-1]=ti4+tr3;
 657.240 +      ch[t4+t6]=tr4+ti3;
 657.241 +
 657.242 +      ch[t5+t6-1]=tr2-tr1;
 657.243 +      ch[t5+t6]=ti1-ti2;
 657.244 +    }
 657.245 +    t1+=ido;
 657.246 +  }
 657.247 +  if(ido&1)return;
 657.248 +
 657.249 + L105:
 657.250 +
 657.251 +  t2=(t1=t0+ido-1)+(t0<<1);
 657.252 +  t3=ido<<2;
 657.253 +  t4=ido;
 657.254 +  t5=ido<<1;
 657.255 +  t6=ido;
 657.256 +
 657.257 +  for(k=0;k<l1;k++){
 657.258 +    ti1=-hsqt2*(cc[t1]+cc[t2]);
 657.259 +    tr1=hsqt2*(cc[t1]-cc[t2]);
 657.260 +
 657.261 +    ch[t4-1]=tr1+cc[t6-1];
 657.262 +    ch[t4+t5-1]=cc[t6-1]-tr1;
 657.263 +
 657.264 +    ch[t4]=ti1-cc[t1+t0];
 657.265 +    ch[t4+t5]=ti1+cc[t1+t0];
 657.266 +
 657.267 +    t1+=ido;
 657.268 +    t2+=ido;
 657.269 +    t4+=t3;
 657.270 +    t6+=ido;
 657.271 +  }
 657.272 +}
 657.273 +
 657.274 +static void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
 657.275 +                          float *c2,float *ch,float *ch2,float *wa){
 657.276 +
 657.277 +  static float tpi=6.283185307179586f;
 657.278 +  int idij,ipph,i,j,k,l,ic,ik,is;
 657.279 +  int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
 657.280 +  float dc2,ai1,ai2,ar1,ar2,ds2;
 657.281 +  int nbd;
 657.282 +  float dcp,arg,dsp,ar1h,ar2h;
 657.283 +  int idp2,ipp2;
 657.284 +
 657.285 +  arg=tpi/(float)ip;
 657.286 +  dcp=cos(arg);
 657.287 +  dsp=sin(arg);
 657.288 +  ipph=(ip+1)>>1;
 657.289 +  ipp2=ip;
 657.290 +  idp2=ido;
 657.291 +  nbd=(ido-1)>>1;
 657.292 +  t0=l1*ido;
 657.293 +  t10=ip*ido;
 657.294 +
 657.295 +  if(ido==1)goto L119;
 657.296 +  for(ik=0;ik<idl1;ik++)ch2[ik]=c2[ik];
 657.297 +
 657.298 +  t1=0;
 657.299 +  for(j=1;j<ip;j++){
 657.300 +    t1+=t0;
 657.301 +    t2=t1;
 657.302 +    for(k=0;k<l1;k++){
 657.303 +      ch[t2]=c1[t2];
 657.304 +      t2+=ido;
 657.305 +    }
 657.306 +  }
 657.307 +
 657.308 +  is=-ido;
 657.309 +  t1=0;
 657.310 +  if(nbd>l1){
 657.311 +    for(j=1;j<ip;j++){
 657.312 +      t1+=t0;
 657.313 +      is+=ido;
 657.314 +      t2= -ido+t1;
 657.315 +      for(k=0;k<l1;k++){
 657.316 +        idij=is-1;
 657.317 +        t2+=ido;
 657.318 +        t3=t2;
 657.319 +        for(i=2;i<ido;i+=2){
 657.320 +          idij+=2;
 657.321 +          t3+=2;
 657.322 +          ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
 657.323 +          ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
 657.324 +        }
 657.325 +      }
 657.326 +    }
 657.327 +  }else{
 657.328 +
 657.329 +    for(j=1;j<ip;j++){
 657.330 +      is+=ido;
 657.331 +      idij=is-1;
 657.332 +      t1+=t0;
 657.333 +      t2=t1;
 657.334 +      for(i=2;i<ido;i+=2){
 657.335 +        idij+=2;
 657.336 +        t2+=2;
 657.337 +        t3=t2;
 657.338 +        for(k=0;k<l1;k++){
 657.339 +          ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
 657.340 +          ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
 657.341 +          t3+=ido;
 657.342 +        }
 657.343 +      }
 657.344 +    }
 657.345 +  }
 657.346 +
 657.347 +  t1=0;
 657.348 +  t2=ipp2*t0;
 657.349 +  if(nbd<l1){
 657.350 +    for(j=1;j<ipph;j++){
 657.351 +      t1+=t0;
 657.352 +      t2-=t0;
 657.353 +      t3=t1;
 657.354 +      t4=t2;
 657.355 +      for(i=2;i<ido;i+=2){
 657.356 +        t3+=2;
 657.357 +        t4+=2;
 657.358 +        t5=t3-ido;
 657.359 +        t6=t4-ido;
 657.360 +        for(k=0;k<l1;k++){
 657.361 +          t5+=ido;
 657.362 +          t6+=ido;
 657.363 +          c1[t5-1]=ch[t5-1]+ch[t6-1];
 657.364 +          c1[t6-1]=ch[t5]-ch[t6];
 657.365 +          c1[t5]=ch[t5]+ch[t6];
 657.366 +          c1[t6]=ch[t6-1]-ch[t5-1];
 657.367 +        }
 657.368 +      }
 657.369 +    }
 657.370 +  }else{
 657.371 +    for(j=1;j<ipph;j++){
 657.372 +      t1+=t0;
 657.373 +      t2-=t0;
 657.374 +      t3=t1;
 657.375 +      t4=t2;
 657.376 +      for(k=0;k<l1;k++){
 657.377 +        t5=t3;
 657.378 +        t6=t4;
 657.379 +        for(i=2;i<ido;i+=2){
 657.380 +          t5+=2;
 657.381 +          t6+=2;
 657.382 +          c1[t5-1]=ch[t5-1]+ch[t6-1];
 657.383 +          c1[t6-1]=ch[t5]-ch[t6];
 657.384 +          c1[t5]=ch[t5]+ch[t6];
 657.385 +          c1[t6]=ch[t6-1]-ch[t5-1];
 657.386 +        }
 657.387 +        t3+=ido;
 657.388 +        t4+=ido;
 657.389 +      }
 657.390 +    }
 657.391 +  }
 657.392 +
 657.393 +L119:
 657.394 +  for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
 657.395 +
 657.396 +  t1=0;
 657.397 +  t2=ipp2*idl1;
 657.398 +  for(j=1;j<ipph;j++){
 657.399 +    t1+=t0;
 657.400 +    t2-=t0;
 657.401 +    t3=t1-ido;
 657.402 +    t4=t2-ido;
 657.403 +    for(k=0;k<l1;k++){
 657.404 +      t3+=ido;
 657.405 +      t4+=ido;
 657.406 +      c1[t3]=ch[t3]+ch[t4];
 657.407 +      c1[t4]=ch[t4]-ch[t3];
 657.408 +    }
 657.409 +  }
 657.410 +
 657.411 +  ar1=1.f;
 657.412 +  ai1=0.f;
 657.413 +  t1=0;
 657.414 +  t2=ipp2*idl1;
 657.415 +  t3=(ip-1)*idl1;
 657.416 +  for(l=1;l<ipph;l++){
 657.417 +    t1+=idl1;
 657.418 +    t2-=idl1;
 657.419 +    ar1h=dcp*ar1-dsp*ai1;
 657.420 +    ai1=dcp*ai1+dsp*ar1;
 657.421 +    ar1=ar1h;
 657.422 +    t4=t1;
 657.423 +    t5=t2;
 657.424 +    t6=t3;
 657.425 +    t7=idl1;
 657.426 +
 657.427 +    for(ik=0;ik<idl1;ik++){
 657.428 +      ch2[t4++]=c2[ik]+ar1*c2[t7++];
 657.429 +      ch2[t5++]=ai1*c2[t6++];
 657.430 +    }
 657.431 +
 657.432 +    dc2=ar1;
 657.433 +    ds2=ai1;
 657.434 +    ar2=ar1;
 657.435 +    ai2=ai1;
 657.436 +
 657.437 +    t4=idl1;
 657.438 +    t5=(ipp2-1)*idl1;
 657.439 +    for(j=2;j<ipph;j++){
 657.440 +      t4+=idl1;
 657.441 +      t5-=idl1;
 657.442 +
 657.443 +      ar2h=dc2*ar2-ds2*ai2;
 657.444 +      ai2=dc2*ai2+ds2*ar2;
 657.445 +      ar2=ar2h;
 657.446 +
 657.447 +      t6=t1;
 657.448 +      t7=t2;
 657.449 +      t8=t4;
 657.450 +      t9=t5;
 657.451 +      for(ik=0;ik<idl1;ik++){
 657.452 +        ch2[t6++]+=ar2*c2[t8++];
 657.453 +        ch2[t7++]+=ai2*c2[t9++];
 657.454 +      }
 657.455 +    }
 657.456 +  }
 657.457 +
 657.458 +  t1=0;
 657.459 +  for(j=1;j<ipph;j++){
 657.460 +    t1+=idl1;
 657.461 +    t2=t1;
 657.462 +    for(ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++];
 657.463 +  }
 657.464 +
 657.465 +  if(ido<l1)goto L132;
 657.466 +
 657.467 +  t1=0;
 657.468 +  t2=0;
 657.469 +  for(k=0;k<l1;k++){
 657.470 +    t3=t1;
 657.471 +    t4=t2;
 657.472 +    for(i=0;i<ido;i++)cc[t4++]=ch[t3++];
 657.473 +    t1+=ido;
 657.474 +    t2+=t10;
 657.475 +  }
 657.476 +
 657.477 +  goto L135;
 657.478 +
 657.479 + L132:
 657.480 +  for(i=0;i<ido;i++){
 657.481 +    t1=i;
 657.482 +    t2=i;
 657.483 +    for(k=0;k<l1;k++){
 657.484 +      cc[t2]=ch[t1];
 657.485 +      t1+=ido;
 657.486 +      t2+=t10;
 657.487 +    }
 657.488 +  }
 657.489 +
 657.490 + L135:
 657.491 +  t1=0;
 657.492 +  t2=ido<<1;
 657.493 +  t3=0;
 657.494 +  t4=ipp2*t0;
 657.495 +  for(j=1;j<ipph;j++){
 657.496 +
 657.497 +    t1+=t2;
 657.498 +    t3+=t0;
 657.499 +    t4-=t0;
 657.500 +
 657.501 +    t5=t1;
 657.502 +    t6=t3;
 657.503 +    t7=t4;
 657.504 +
 657.505 +    for(k=0;k<l1;k++){
 657.506 +      cc[t5-1]=ch[t6];
 657.507 +      cc[t5]=ch[t7];
 657.508 +      t5+=t10;
 657.509 +      t6+=ido;
 657.510 +      t7+=ido;
 657.511 +    }
 657.512 +  }
 657.513 +
 657.514 +  if(ido==1)return;
 657.515 +  if(nbd<l1)goto L141;
 657.516 +
 657.517 +  t1=-ido;
 657.518 +  t3=0;
 657.519 +  t4=0;
 657.520 +  t5=ipp2*t0;
 657.521 +  for(j=1;j<ipph;j++){
 657.522 +    t1+=t2;
 657.523 +    t3+=t2;
 657.524 +    t4+=t0;
 657.525 +    t5-=t0;
 657.526 +    t6=t1;
 657.527 +    t7=t3;
 657.528 +    t8=t4;
 657.529 +    t9=t5;
 657.530 +    for(k=0;k<l1;k++){
 657.531 +      for(i=2;i<ido;i+=2){
 657.532 +        ic=idp2-i;
 657.533 +        cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1];
 657.534 +        cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1];
 657.535 +        cc[i+t7]=ch[i+t8]+ch[i+t9];
 657.536 +        cc[ic+t6]=ch[i+t9]-ch[i+t8];
 657.537 +      }
 657.538 +      t6+=t10;
 657.539 +      t7+=t10;
 657.540 +      t8+=ido;
 657.541 +      t9+=ido;
 657.542 +    }
 657.543 +  }
 657.544 +  return;
 657.545 +
 657.546 + L141:
 657.547 +
 657.548 +  t1=-ido;
 657.549 +  t3=0;
 657.550 +  t4=0;
 657.551 +  t5=ipp2*t0;
 657.552 +  for(j=1;j<ipph;j++){
 657.553 +    t1+=t2;
 657.554 +    t3+=t2;
 657.555 +    t4+=t0;
 657.556 +    t5-=t0;
 657.557 +    for(i=2;i<ido;i+=2){
 657.558 +      t6=idp2+t1-i;
 657.559 +      t7=i+t3;
 657.560 +      t8=i+t4;
 657.561 +      t9=i+t5;
 657.562 +      for(k=0;k<l1;k++){
 657.563 +        cc[t7-1]=ch[t8-1]+ch[t9-1];
 657.564 +        cc[t6-1]=ch[t8-1]-ch[t9-1];
 657.565 +        cc[t7]=ch[t8]+ch[t9];
 657.566 +        cc[t6]=ch[t9]-ch[t8];
 657.567 +        t6+=t10;
 657.568 +        t7+=t10;
 657.569 +        t8+=ido;
 657.570 +        t9+=ido;
 657.571 +      }
 657.572 +    }
 657.573 +  }
 657.574 +}
 657.575 +
 657.576 +static void drftf1(int n,float *c,float *ch,float *wa,int *ifac){
 657.577 +  int i,k1,l1,l2;
 657.578 +  int na,kh,nf;
 657.579 +  int ip,iw,ido,idl1,ix2,ix3;
 657.580 +
 657.581 +  nf=ifac[1];
 657.582 +  na=1;
 657.583 +  l2=n;
 657.584 +  iw=n;
 657.585 +
 657.586 +  for(k1=0;k1<nf;k1++){
 657.587 +    kh=nf-k1;
 657.588 +    ip=ifac[kh+1];
 657.589 +    l1=l2/ip;
 657.590 +    ido=n/l2;
 657.591 +    idl1=ido*l1;
 657.592 +    iw-=(ip-1)*ido;
 657.593 +    na=1-na;
 657.594 +
 657.595 +    if(ip!=4)goto L102;
 657.596 +
 657.597 +    ix2=iw+ido;
 657.598 +    ix3=ix2+ido;
 657.599 +    if(na!=0)
 657.600 +      dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
 657.601 +    else
 657.602 +      dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
 657.603 +    goto L110;
 657.604 +
 657.605 + L102:
 657.606 +    if(ip!=2)goto L104;
 657.607 +    if(na!=0)goto L103;
 657.608 +
 657.609 +    dradf2(ido,l1,c,ch,wa+iw-1);
 657.610 +    goto L110;
 657.611 +
 657.612 +  L103:
 657.613 +    dradf2(ido,l1,ch,c,wa+iw-1);
 657.614 +    goto L110;
 657.615 +
 657.616 +  L104:
 657.617 +    if(ido==1)na=1-na;
 657.618 +    if(na!=0)goto L109;
 657.619 +
 657.620 +    dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
 657.621 +    na=1;
 657.622 +    goto L110;
 657.623 +
 657.624 +  L109:
 657.625 +    dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
 657.626 +    na=0;
 657.627 +
 657.628 +  L110:
 657.629 +    l2=l1;
 657.630 +  }
 657.631 +
 657.632 +  if(na==1)return;
 657.633 +
 657.634 +  for(i=0;i<n;i++)c[i]=ch[i];
 657.635 +}
 657.636 +
 657.637 +static void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){
 657.638 +  int i,k,t0,t1,t2,t3,t4,t5,t6;
 657.639 +  float ti2,tr2;
 657.640 +
 657.641 +  t0=l1*ido;
 657.642 +
 657.643 +  t1=0;
 657.644 +  t2=0;
 657.645 +  t3=(ido<<1)-1;
 657.646 +  for(k=0;k<l1;k++){
 657.647 +    ch[t1]=cc[t2]+cc[t3+t2];
 657.648 +    ch[t1+t0]=cc[t2]-cc[t3+t2];
 657.649 +    t2=(t1+=ido)<<1;
 657.650 +  }
 657.651 +
 657.652 +  if(ido<2)return;
 657.653 +  if(ido==2)goto L105;
 657.654 +
 657.655 +  t1=0;
 657.656 +  t2=0;
 657.657 +  for(k=0;k<l1;k++){
 657.658 +    t3=t1;
 657.659 +    t5=(t4=t2)+(ido<<1);
 657.660 +    t6=t0+t1;
 657.661 +    for(i=2;i<ido;i+=2){
 657.662 +      t3+=2;
 657.663 +      t4+=2;
 657.664 +      t5-=2;
 657.665 +      t6+=2;
 657.666 +      ch[t3-1]=cc[t4-1]+cc[t5-1];
 657.667 +      tr2=cc[t4-1]-cc[t5-1];
 657.668 +      ch[t3]=cc[t4]-cc[t5];
 657.669 +      ti2=cc[t4]+cc[t5];
 657.670 +      ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2;
 657.671 +      ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2;
 657.672 +    }
 657.673 +    t2=(t1+=ido)<<1;
 657.674 +  }
 657.675 +
 657.676 +  if(ido%2==1)return;
 657.677 +
 657.678 +L105:
 657.679 +  t1=ido-1;
 657.680 +  t2=ido-1;
 657.681 +  for(k=0;k<l1;k++){
 657.682 +    ch[t1]=cc[t2]+cc[t2];
 657.683 +    ch[t1+t0]=-(cc[t2+1]+cc[t2+1]);
 657.684 +    t1+=ido;
 657.685 +    t2+=ido<<1;
 657.686 +  }
 657.687 +}
 657.688 +
 657.689 +static void dradb3(int ido,int l1,float *cc,float *ch,float *wa1,
 657.690 +                          float *wa2){
 657.691 +  static float taur = -.5f;
 657.692 +  static float taui = .8660254037844386f;
 657.693 +  int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
 657.694 +  float ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2;
 657.695 +  t0=l1*ido;
 657.696 +
 657.697 +  t1=0;
 657.698 +  t2=t0<<1;
 657.699 +  t3=ido<<1;
 657.700 +  t4=ido+(ido<<1);
 657.701 +  t5=0;
 657.702 +  for(k=0;k<l1;k++){
 657.703 +    tr2=cc[t3-1]+cc[t3-1];
 657.704 +    cr2=cc[t5]+(taur*tr2);
 657.705 +    ch[t1]=cc[t5]+tr2;
 657.706 +    ci3=taui*(cc[t3]+cc[t3]);
 657.707 +    ch[t1+t0]=cr2-ci3;
 657.708 +    ch[t1+t2]=cr2+ci3;
 657.709 +    t1+=ido;
 657.710 +    t3+=t4;
 657.711 +    t5+=t4;
 657.712 +  }
 657.713 +
 657.714 +  if(ido==1)return;
 657.715 +
 657.716 +  t1=0;
 657.717 +  t3=ido<<1;
 657.718 +  for(k=0;k<l1;k++){
 657.719 +    t7=t1+(t1<<1);
 657.720 +    t6=(t5=t7+t3);
 657.721 +    t8=t1;
 657.722 +    t10=(t9=t1+t0)+t0;
 657.723 +
 657.724 +    for(i=2;i<ido;i+=2){
 657.725 +      t5+=2;
 657.726 +      t6-=2;
 657.727 +      t7+=2;
 657.728 +      t8+=2;
 657.729 +      t9+=2;
 657.730 +      t10+=2;
 657.731 +      tr2=cc[t5-1]+cc[t6-1];
 657.732 +      cr2=cc[t7-1]+(taur*tr2);
 657.733 +      ch[t8-1]=cc[t7-1]+tr2;
 657.734 +      ti2=cc[t5]-cc[t6];
 657.735 +      ci2=cc[t7]+(taur*ti2);
 657.736 +      ch[t8]=cc[t7]+ti2;
 657.737 +      cr3=taui*(cc[t5-1]-cc[t6-1]);
 657.738 +      ci3=taui*(cc[t5]+cc[t6]);
 657.739 +      dr2=cr2-ci3;
 657.740 +      dr3=cr2+ci3;
 657.741 +      di2=ci2+cr3;
 657.742 +      di3=ci2-cr3;
 657.743 +      ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2;
 657.744 +      ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2;
 657.745 +      ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3;
 657.746 +      ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3;
 657.747 +    }
 657.748 +    t1+=ido;
 657.749 +  }
 657.750 +}
 657.751 +
 657.752 +static void dradb4(int ido,int l1,float *cc,float *ch,float *wa1,
 657.753 +                          float *wa2,float *wa3){
 657.754 +  static float sqrt2=1.414213562373095f;
 657.755 +  int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8;
 657.756 +  float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
 657.757 +  t0=l1*ido;
 657.758 +
 657.759 +  t1=0;
 657.760 +  t2=ido<<2;
 657.761 +  t3=0;
 657.762 +  t6=ido<<1;
 657.763 +  for(k=0;k<l1;k++){
 657.764 +    t4=t3+t6;
 657.765 +    t5=t1;
 657.766 +    tr3=cc[t4-1]+cc[t4-1];
 657.767 +    tr4=cc[t4]+cc[t4];
 657.768 +    tr1=cc[t3]-cc[(t4+=t6)-1];
 657.769 +    tr2=cc[t3]+cc[t4-1];
 657.770 +    ch[t5]=tr2+tr3;
 657.771 +    ch[t5+=t0]=tr1-tr4;
 657.772 +    ch[t5+=t0]=tr2-tr3;
 657.773 +    ch[t5+=t0]=tr1+tr4;
 657.774 +    t1+=ido;
 657.775 +    t3+=t2;
 657.776 +  }
 657.777 +
 657.778 +  if(ido<2)return;
 657.779 +  if(ido==2)goto L105;
 657.780 +
 657.781 +  t1=0;
 657.782 +  for(k=0;k<l1;k++){
 657.783 +    t5=(t4=(t3=(t2=t1<<2)+t6))+t6;
 657.784 +    t7=t1;
 657.785 +    for(i=2;i<ido;i+=2){
 657.786 +      t2+=2;
 657.787 +      t3+=2;
 657.788 +      t4-=2;
 657.789 +      t5-=2;
 657.790 +      t7+=2;
 657.791 +      ti1=cc[t2]+cc[t5];
 657.792 +      ti2=cc[t2]-cc[t5];
 657.793 +      ti3=cc[t3]-cc[t4];
 657.794 +      tr4=cc[t3]+cc[t4];
 657.795 +      tr1=cc[t2-1]-cc[t5-1];
 657.796 +      tr2=cc[t2-1]+cc[t5-1];
 657.797 +      ti4=cc[t3-1]-cc[t4-1];
 657.798 +      tr3=cc[t3-1]+cc[t4-1];
 657.799 +      ch[t7-1]=tr2+tr3;
 657.800 +      cr3=tr2-tr3;
 657.801 +      ch[t7]=ti2+ti3;
 657.802 +      ci3=ti2-ti3;
 657.803 +      cr2=tr1-tr4;
 657.804 +      cr4=tr1+tr4;
 657.805 +      ci2=ti1+ti4;
 657.806 +      ci4=ti1-ti4;
 657.807 +
 657.808 +      ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2;
 657.809 +      ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2;
 657.810 +      ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3;
 657.811 +      ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3;
 657.812 +      ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4;
 657.813 +      ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4;
 657.814 +    }
 657.815 +    t1+=ido;
 657.816 +  }
 657.817 +
 657.818 +  if(ido%2 == 1)return;
 657.819 +
 657.820 + L105:
 657.821 +
 657.822 +  t1=ido;
 657.823 +  t2=ido<<2;
 657.824 +  t3=ido-1;
 657.825 +  t4=ido+(ido<<1);
 657.826 +  for(k=0;k<l1;k++){
 657.827 +    t5=t3;
 657.828 +    ti1=cc[t1]+cc[t4];
 657.829 +    ti2=cc[t4]-cc[t1];
 657.830 +    tr1=cc[t1-1]-cc[t4-1];
 657.831 +    tr2=cc[t1-1]+cc[t4-1];
 657.832 +    ch[t5]=tr2+tr2;
 657.833 +    ch[t5+=t0]=sqrt2*(tr1-ti1);
 657.834 +    ch[t5+=t0]=ti2+ti2;
 657.835 +    ch[t5+=t0]=-sqrt2*(tr1+ti1);
 657.836 +
 657.837 +    t3+=ido;
 657.838 +    t1+=t2;
 657.839 +    t4+=t2;
 657.840 +  }
 657.841 +}
 657.842 +
 657.843 +static void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
 657.844 +            float *c2,float *ch,float *ch2,float *wa){
 657.845 +  static float tpi=6.283185307179586f;
 657.846 +  int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,
 657.847 +      t11,t12;
 657.848 +  float dc2,ai1,ai2,ar1,ar2,ds2;
 657.849 +  int nbd;
 657.850 +  float dcp,arg,dsp,ar1h,ar2h;
 657.851 +  int ipp2;
 657.852 +
 657.853 +  t10=ip*ido;
 657.854 +  t0=l1*ido;
 657.855 +  arg=tpi/(float)ip;
 657.856 +  dcp=cos(arg);
 657.857 +  dsp=sin(arg);
 657.858 +  nbd=(ido-1)>>1;
 657.859 +  ipp2=ip;
 657.860 +  ipph=(ip+1)>>1;
 657.861 +  if(ido<l1)goto L103;
 657.862 +
 657.863 +  t1=0;
 657.864 +  t2=0;
 657.865 +  for(k=0;k<l1;k++){
 657.866 +    t3=t1;
 657.867 +    t4=t2;
 657.868 +    for(i=0;i<ido;i++){
 657.869 +      ch[t3]=cc[t4];
 657.870 +      t3++;
 657.871 +      t4++;
 657.872 +    }
 657.873 +    t1+=ido;
 657.874 +    t2+=t10;
 657.875 +  }
 657.876 +  goto L106;
 657.877 +
 657.878 + L103:
 657.879 +  t1=0;
 657.880 +  for(i=0;i<ido;i++){
 657.881 +    t2=t1;
 657.882 +    t3=t1;
 657.883 +    for(k=0;k<l1;k++){
 657.884 +      ch[t2]=cc[t3];
 657.885 +      t2+=ido;
 657.886 +      t3+=t10;
 657.887 +    }
 657.888 +    t1++;
 657.889 +  }
 657.890 +
 657.891 + L106:
 657.892 +  t1=0;
 657.893 +  t2=ipp2*t0;
 657.894 +  t7=(t5=ido<<1);
 657.895 +  for(j=1;j<ipph;j++){
 657.896 +    t1+=t0;
 657.897 +    t2-=t0;
 657.898 +    t3=t1;
 657.899 +    t4=t2;
 657.900 +    t6=t5;
 657.901 +    for(k=0;k<l1;k++){
 657.902 +      ch[t3]=cc[t6-1]+cc[t6-1];
 657.903 +      ch[t4]=cc[t6]+cc[t6];
 657.904 +      t3+=ido;
 657.905 +      t4+=ido;
 657.906 +      t6+=t10;
 657.907 +    }
 657.908 +    t5+=t7;
 657.909 +  }
 657.910 +
 657.911 +  if (ido == 1)goto L116;
 657.912 +  if(nbd<l1)goto L112;
 657.913 +
 657.914 +  t1=0;
 657.915 +  t2=ipp2*t0;
 657.916 +  t7=0;
 657.917 +  for(j=1;j<ipph;j++){
 657.918 +    t1+=t0;
 657.919 +    t2-=t0;
 657.920 +    t3=t1;
 657.921 +    t4=t2;
 657.922 +
 657.923 +    t7+=(ido<<1);
 657.924 +    t8=t7;
 657.925 +    for(k=0;k<l1;k++){
 657.926 +      t5=t3;
 657.927 +      t6=t4;
 657.928 +      t9=t8;
 657.929 +      t11=t8;
 657.930 +      for(i=2;i<ido;i+=2){
 657.931 +        t5+=2;
 657.932 +        t6+=2;
 657.933 +        t9+=2;
 657.934 +        t11-=2;
 657.935 +        ch[t5-1]=cc[t9-1]+cc[t11-1];
 657.936 +        ch[t6-1]=cc[t9-1]-cc[t11-1];
 657.937 +        ch[t5]=cc[t9]-cc[t11];
 657.938 +        ch[t6]=cc[t9]+cc[t11];
 657.939 +      }
 657.940 +      t3+=ido;
 657.941 +      t4+=ido;
 657.942 +      t8+=t10;
 657.943 +    }
 657.944 +  }
 657.945 +  goto L116;
 657.946 +
 657.947 + L112:
 657.948 +  t1=0;
 657.949 +  t2=ipp2*t0;
 657.950 +  t7=0;
 657.951 +  for(j=1;j<ipph;j++){
 657.952 +    t1+=t0;
 657.953 +    t2-=t0;
 657.954 +    t3=t1;
 657.955 +    t4=t2;
 657.956 +    t7+=(ido<<1);
 657.957 +    t8=t7;
 657.958 +    t9=t7;
 657.959 +    for(i=2;i<ido;i+=2){
 657.960 +      t3+=2;
 657.961 +      t4+=2;
 657.962 +      t8+=2;
 657.963 +      t9-=2;
 657.964 +      t5=t3;
 657.965 +      t6=t4;
 657.966 +      t11=t8;
 657.967 +      t12=t9;
 657.968 +      for(k=0;k<l1;k++){
 657.969 +        ch[t5-1]=cc[t11-1]+cc[t12-1];
 657.970 +        ch[t6-1]=cc[t11-1]-cc[t12-1];
 657.971 +        ch[t5]=cc[t11]-cc[t12];
 657.972 +        ch[t6]=cc[t11]+cc[t12];
 657.973 +        t5+=ido;
 657.974 +        t6+=ido;
 657.975 +        t11+=t10;
 657.976 +        t12+=t10;
 657.977 +      }
 657.978 +    }
 657.979 +  }
 657.980 +
 657.981 +L116:
 657.982 +  ar1=1.f;
 657.983 +  ai1=0.f;
 657.984 +  t1=0;
 657.985 +  t9=(t2=ipp2*idl1);
 657.986 +  t3=(ip-1)*idl1;
 657.987 +  for(l=1;l<ipph;l++){
 657.988 +    t1+=idl1;
 657.989 +    t2-=idl1;
 657.990 +
 657.991 +    ar1h=dcp*ar1-dsp*ai1;
 657.992 +    ai1=dcp*ai1+dsp*ar1;
 657.993 +    ar1=ar1h;
 657.994 +    t4=t1;
 657.995 +    t5=t2;
 657.996 +    t6=0;
 657.997 +    t7=idl1;
 657.998 +    t8=t3;
 657.999 +    for(ik=0;ik<idl1;ik++){
657.1000 +      c2[t4++]=ch2[t6++]+ar1*ch2[t7++];
657.1001 +      c2[t5++]=ai1*ch2[t8++];
657.1002 +    }
657.1003 +    dc2=ar1;
657.1004 +    ds2=ai1;
657.1005 +    ar2=ar1;
657.1006 +    ai2=ai1;
657.1007 +
657.1008 +    t6=idl1;
657.1009 +    t7=t9-idl1;
657.1010 +    for(j=2;j<ipph;j++){
657.1011 +      t6+=idl1;
657.1012 +      t7-=idl1;
657.1013 +      ar2h=dc2*ar2-ds2*ai2;
657.1014 +      ai2=dc2*ai2+ds2*ar2;
657.1015 +      ar2=ar2h;
657.1016 +      t4=t1;
657.1017 +      t5=t2;
657.1018 +      t11=t6;
657.1019 +      t12=t7;
657.1020 +      for(ik=0;ik<idl1;ik++){
657.1021 +        c2[t4++]+=ar2*ch2[t11++];
657.1022 +        c2[t5++]+=ai2*ch2[t12++];
657.1023 +      }
657.1024 +    }
657.1025 +  }
657.1026 +
657.1027 +  t1=0;
657.1028 +  for(j=1;j<ipph;j++){
657.1029 +    t1+=idl1;
657.1030 +    t2=t1;
657.1031 +    for(ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++];
657.1032 +  }
657.1033 +
657.1034 +  t1=0;
657.1035 +  t2=ipp2*t0;
657.1036 +  for(j=1;j<ipph;j++){
657.1037 +    t1+=t0;
657.1038 +    t2-=t0;
657.1039 +    t3=t1;
657.1040 +    t4=t2;
657.1041 +    for(k=0;k<l1;k++){
657.1042 +      ch[t3]=c1[t3]-c1[t4];
657.1043 +      ch[t4]=c1[t3]+c1[t4];
657.1044 +      t3+=ido;
657.1045 +      t4+=ido;
657.1046 +    }
657.1047 +  }
657.1048 +
657.1049 +  if(ido==1)goto L132;
657.1050 +  if(nbd<l1)goto L128;
657.1051 +
657.1052 +  t1=0;
657.1053 +  t2=ipp2*t0;
657.1054 +  for(j=1;j<ipph;j++){
657.1055 +    t1+=t0;
657.1056 +    t2-=t0;
657.1057 +    t3=t1;
657.1058 +    t4=t2;
657.1059 +    for(k=0;k<l1;k++){
657.1060 +      t5=t3;
657.1061 +      t6=t4;
657.1062 +      for(i=2;i<ido;i+=2){
657.1063 +        t5+=2;
657.1064 +        t6+=2;
657.1065 +        ch[t5-1]=c1[t5-1]-c1[t6];
657.1066 +        ch[t6-1]=c1[t5-1]+c1[t6];
657.1067 +        ch[t5]=c1[t5]+c1[t6-1];
657.1068 +        ch[t6]=c1[t5]-c1[t6-1];
657.1069 +      }
657.1070 +      t3+=ido;
657.1071 +      t4+=ido;
657.1072 +    }
657.1073 +  }
657.1074 +  goto L132;
657.1075 +
657.1076 + L128:
657.1077 +  t1=0;
657.1078 +  t2=ipp2*t0;
657.1079 +  for(j=1;j<ipph;j++){
657.1080 +    t1+=t0;
657.1081 +    t2-=t0;
657.1082 +    t3=t1;
657.1083 +    t4=t2;
657.1084 +    for(i=2;i<ido;i+=2){
657.1085 +      t3+=2;
657.1086 +      t4+=2;
657.1087 +      t5=t3;
657.1088 +      t6=t4;
657.1089 +      for(k=0;k<l1;k++){
657.1090 +        ch[t5-1]=c1[t5-1]-c1[t6];
657.1091 +        ch[t6-1]=c1[t5-1]+c1[t6];
657.1092 +        ch[t5]=c1[t5]+c1[t6-1];
657.1093 +        ch[t6]=c1[t5]-c1[t6-1];
657.1094 +        t5+=ido;
657.1095 +        t6+=ido;
657.1096 +      }
657.1097 +    }
657.1098 +  }
657.1099 +
657.1100 +L132:
657.1101 +  if(ido==1)return;
657.1102 +
657.1103 +  for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
657.1104 +
657.1105 +  t1=0;
657.1106 +  for(j=1;j<ip;j++){
657.1107 +    t2=(t1+=t0);
657.1108 +    for(k=0;k<l1;k++){
657.1109 +      c1[t2]=ch[t2];
657.1110 +      t2+=ido;
657.1111 +    }
657.1112 +  }
657.1113 +
657.1114 +  if(nbd>l1)goto L139;
657.1115 +
657.1116 +  is= -ido-1;
657.1117 +  t1=0;
657.1118 +  for(j=1;j<ip;j++){
657.1119 +    is+=ido;
657.1120 +    t1+=t0;
657.1121 +    idij=is;
657.1122 +    t2=t1;
657.1123 +    for(i=2;i<ido;i+=2){
657.1124 +      t2+=2;
657.1125 +      idij+=2;
657.1126 +      t3=t2;
657.1127 +      for(k=0;k<l1;k++){
657.1128 +        c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
657.1129 +        c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
657.1130 +        t3+=ido;
657.1131 +      }
657.1132 +    }
657.1133 +  }
657.1134 +  return;
657.1135 +
657.1136 + L139:
657.1137 +  is= -ido-1;
657.1138 +  t1=0;
657.1139 +  for(j=1;j<ip;j++){
657.1140 +    is+=ido;
657.1141 +    t1+=t0;
657.1142 +    t2=t1;
657.1143 +    for(k=0;k<l1;k++){
657.1144 +      idij=is;
657.1145 +      t3=t2;
657.1146 +      for(i=2;i<ido;i+=2){
657.1147 +        idij+=2;
657.1148 +        t3+=2;
657.1149 +        c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
657.1150 +        c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
657.1151 +      }
657.1152 +      t2+=ido;
657.1153 +    }
657.1154 +  }
657.1155 +}
657.1156 +
657.1157 +static void drftb1(int n, float *c, float *ch, float *wa, int *ifac){
657.1158 +  int i,k1,l1,l2;
657.1159 +  int na;
657.1160 +  int nf,ip,iw,ix2,ix3,ido,idl1;
657.1161 +
657.1162 +  nf=ifac[1];
657.1163 +  na=0;
657.1164 +  l1=1;
657.1165 +  iw=1;
657.1166 +
657.1167 +  for(k1=0;k1<nf;k1++){
657.1168 +    ip=ifac[k1 + 2];
657.1169 +    l2=ip*l1;
657.1170 +    ido=n/l2;
657.1171 +    idl1=ido*l1;
657.1172 +    if(ip!=4)goto L103;
657.1173 +    ix2=iw+ido;
657.1174 +    ix3=ix2+ido;
657.1175 +
657.1176 +    if(na!=0)
657.1177 +      dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
657.1178 +    else
657.1179 +      dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
657.1180 +    na=1-na;
657.1181 +    goto L115;
657.1182 +
657.1183 +  L103:
657.1184 +    if(ip!=2)goto L106;
657.1185 +
657.1186 +    if(na!=0)
657.1187 +      dradb2(ido,l1,ch,c,wa+iw-1);
657.1188 +    else
657.1189 +      dradb2(ido,l1,c,ch,wa+iw-1);
657.1190 +    na=1-na;
657.1191 +    goto L115;
657.1192 +
657.1193 +  L106:
657.1194 +    if(ip!=3)goto L109;
657.1195 +
657.1196 +    ix2=iw+ido;
657.1197 +    if(na!=0)
657.1198 +      dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1);
657.1199 +    else
657.1200 +      dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1);
657.1201 +    na=1-na;
657.1202 +    goto L115;
657.1203 +
657.1204 +  L109:
657.1205 +/*    The radix five case can be translated later..... */
657.1206 +/*    if(ip!=5)goto L112;
657.1207 +
657.1208 +    ix2=iw+ido;
657.1209 +    ix3=ix2+ido;
657.1210 +    ix4=ix3+ido;
657.1211 +    if(na!=0)
657.1212 +      dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
657.1213 +    else
657.1214 +      dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
657.1215 +    na=1-na;
657.1216 +    goto L115;
657.1217 +
657.1218 +  L112:*/
657.1219 +    if(na!=0)
657.1220 +      dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
657.1221 +    else
657.1222 +      dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
657.1223 +    if(ido==1)na=1-na;
657.1224 +
657.1225 +  L115:
657.1226 +    l1=l2;
657.1227 +    iw+=(ip-1)*ido;
657.1228 +  }
657.1229 +
657.1230 +  if(na==0)return;
657.1231 +
657.1232 +  for(i=0;i<n;i++)c[i]=ch[i];
657.1233 +}
657.1234 +
657.1235 +void drft_forward(drft_lookup *l,float *data){
657.1236 +  if(l->n==1)return;
657.1237 +  drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);
657.1238 +}
657.1239 +
657.1240 +void drft_backward(drft_lookup *l,float *data){
657.1241 +  if (l->n==1)return;
657.1242 +  drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);
657.1243 +}
657.1244 +
657.1245 +void drft_init(drft_lookup *l,int n){
657.1246 +  l->n=n;
657.1247 +  l->trigcache=_ogg_calloc(3*n,sizeof(*l->trigcache));
657.1248 +  l->splitcache=_ogg_calloc(32,sizeof(*l->splitcache));
657.1249 +  fdrffti(n, l->trigcache, l->splitcache);
657.1250 +}
657.1251 +
657.1252 +void drft_clear(drft_lookup *l){
657.1253 +  if(l){
657.1254 +    if(l->trigcache)_ogg_free(l->trigcache);
657.1255 +    if(l->splitcache)_ogg_free(l->splitcache);
657.1256 +    memset(l,0,sizeof(*l));
657.1257 +  }
657.1258 +}
   658.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   658.2 +++ b/libs/vorbis/smallft.h	Sat Feb 01 19:58:19 2014 +0200
   658.3 @@ -0,0 +1,34 @@
   658.4 +/********************************************************************
   658.5 + *                                                                  *
   658.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   658.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   658.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   658.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  658.10 + *                                                                  *
  658.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  658.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  658.13 + *                                                                  *
  658.14 + ********************************************************************
  658.15 +
  658.16 + function: fft transform
  658.17 + last mod: $Id: smallft.h 13293 2007-07-24 00:09:47Z xiphmont $
  658.18 +
  658.19 + ********************************************************************/
  658.20 +
  658.21 +#ifndef _V_SMFT_H_
  658.22 +#define _V_SMFT_H_
  658.23 +
  658.24 +#include "vorbis/codec.h"
  658.25 +
  658.26 +typedef struct {
  658.27 +  int n;
  658.28 +  float *trigcache;
  658.29 +  int *splitcache;
  658.30 +} drft_lookup;
  658.31 +
  658.32 +extern void drft_forward(drft_lookup *l,float *data);
  658.33 +extern void drft_backward(drft_lookup *l,float *data);
  658.34 +extern void drft_init(drft_lookup *l,int n);
  658.35 +extern void drft_clear(drft_lookup *l);
  658.36 +
  658.37 +#endif
   659.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   659.2 +++ b/libs/vorbis/synthesis.c	Sat Feb 01 19:58:19 2014 +0200
   659.3 @@ -0,0 +1,184 @@
   659.4 +/********************************************************************
   659.5 + *                                                                  *
   659.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   659.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   659.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   659.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  659.10 + *                                                                  *
  659.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  659.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  659.13 + *                                                                  *
  659.14 + ********************************************************************
  659.15 +
  659.16 + function: single-block PCM synthesis
  659.17 + last mod: $Id: synthesis.c 17474 2010-09-30 03:41:41Z gmaxwell $
  659.18 +
  659.19 + ********************************************************************/
  659.20 +
  659.21 +#include <stdio.h>
  659.22 +#include <ogg/ogg.h>
  659.23 +#include "vorbis/codec.h"
  659.24 +#include "codec_internal.h"
  659.25 +#include "registry.h"
  659.26 +#include "misc.h"
  659.27 +#include "os.h"
  659.28 +
  659.29 +int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
  659.30 +  vorbis_dsp_state     *vd= vb ? vb->vd : 0;
  659.31 +  private_state        *b= vd ? vd->backend_state : 0;
  659.32 +  vorbis_info          *vi= vd ? vd->vi : 0;
  659.33 +  codec_setup_info     *ci= vi ? vi->codec_setup : 0;
  659.34 +  oggpack_buffer       *opb=vb ? &vb->opb : 0;
  659.35 +  int                   type,mode,i;
  659.36 +
  659.37 +  if (!vd || !b || !vi || !ci || !opb) {
  659.38 +    return OV_EBADPACKET;
  659.39 +  }
  659.40 +
  659.41 +  /* first things first.  Make sure decode is ready */
  659.42 +  _vorbis_block_ripcord(vb);
  659.43 +  oggpack_readinit(opb,op->packet,op->bytes);
  659.44 +
  659.45 +  /* Check the packet type */
  659.46 +  if(oggpack_read(opb,1)!=0){
  659.47 +    /* Oops.  This is not an audio data packet */
  659.48 +    return(OV_ENOTAUDIO);
  659.49 +  }
  659.50 +
  659.51 +  /* read our mode and pre/post windowsize */
  659.52 +  mode=oggpack_read(opb,b->modebits);
  659.53 +  if(mode==-1){
  659.54 +    return(OV_EBADPACKET);
  659.55 +  }
  659.56 +
  659.57 +  vb->mode=mode;
  659.58 +  if(!ci->mode_param[mode]){
  659.59 +    return(OV_EBADPACKET);
  659.60 +  }
  659.61 +
  659.62 +  vb->W=ci->mode_param[mode]->blockflag;
  659.63 +  if(vb->W){
  659.64 +
  659.65 +    /* this doesn;t get mapped through mode selection as it's used
  659.66 +       only for window selection */
  659.67 +    vb->lW=oggpack_read(opb,1);
  659.68 +    vb->nW=oggpack_read(opb,1);
  659.69 +    if(vb->nW==-1){
  659.70 +      return(OV_EBADPACKET);
  659.71 +    }
  659.72 +  }else{
  659.73 +    vb->lW=0;
  659.74 +    vb->nW=0;
  659.75 +  }
  659.76 +
  659.77 +  /* more setup */
  659.78 +  vb->granulepos=op->granulepos;
  659.79 +  vb->sequence=op->packetno;
  659.80 +  vb->eofflag=op->e_o_s;
  659.81 +
  659.82 +  /* alloc pcm passback storage */
  659.83 +  vb->pcmend=ci->blocksizes[vb->W];
  659.84 +  vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
  659.85 +  for(i=0;i<vi->channels;i++)
  659.86 +    vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
  659.87 +
  659.88 +  /* unpack_header enforces range checking */
  659.89 +  type=ci->map_type[ci->mode_param[mode]->mapping];
  659.90 +
  659.91 +  return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]->
  659.92 +                                                   mapping]));
  659.93 +}
  659.94 +
  659.95 +/* used to track pcm position without actually performing decode.
  659.96 +   Useful for sequential 'fast forward' */
  659.97 +int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
  659.98 +  vorbis_dsp_state     *vd=vb->vd;
  659.99 +  private_state        *b=vd->backend_state;
 659.100 +  vorbis_info          *vi=vd->vi;
 659.101 +  codec_setup_info     *ci=vi->codec_setup;
 659.102 +  oggpack_buffer       *opb=&vb->opb;
 659.103 +  int                   mode;
 659.104 +
 659.105 +  /* first things first.  Make sure decode is ready */
 659.106 +  _vorbis_block_ripcord(vb);
 659.107 +  oggpack_readinit(opb,op->packet,op->bytes);
 659.108 +
 659.109 +  /* Check the packet type */
 659.110 +  if(oggpack_read(opb,1)!=0){
 659.111 +    /* Oops.  This is not an audio data packet */
 659.112 +    return(OV_ENOTAUDIO);
 659.113 +  }
 659.114 +
 659.115 +  /* read our mode and pre/post windowsize */
 659.116 +  mode=oggpack_read(opb,b->modebits);
 659.117 +  if(mode==-1)return(OV_EBADPACKET);
 659.118 +
 659.119 +  vb->mode=mode;
 659.120 +  if(!ci->mode_param[mode]){
 659.121 +    return(OV_EBADPACKET);
 659.122 +  }
 659.123 +  
 659.124 +  vb->W=ci->mode_param[mode]->blockflag;
 659.125 +  if(vb->W){
 659.126 +    vb->lW=oggpack_read(opb,1);
 659.127 +    vb->nW=oggpack_read(opb,1);
 659.128 +    if(vb->nW==-1)   return(OV_EBADPACKET);
 659.129 +  }else{
 659.130 +    vb->lW=0;
 659.131 +    vb->nW=0;
 659.132 +  }
 659.133 +
 659.134 +  /* more setup */
 659.135 +  vb->granulepos=op->granulepos;
 659.136 +  vb->sequence=op->packetno;
 659.137 +  vb->eofflag=op->e_o_s;
 659.138 +
 659.139 +  /* no pcm */
 659.140 +  vb->pcmend=0;
 659.141 +  vb->pcm=NULL;
 659.142 +
 659.143 +  return(0);
 659.144 +}
 659.145 +
 659.146 +long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
 659.147 +  codec_setup_info     *ci=vi->codec_setup;
 659.148 +  oggpack_buffer       opb;
 659.149 +  int                  mode;
 659.150 +
 659.151 +  oggpack_readinit(&opb,op->packet,op->bytes);
 659.152 +
 659.153 +  /* Check the packet type */
 659.154 +  if(oggpack_read(&opb,1)!=0){
 659.155 +    /* Oops.  This is not an audio data packet */
 659.156 +    return(OV_ENOTAUDIO);
 659.157 +  }
 659.158 +
 659.159 +  {
 659.160 +    int modebits=0;
 659.161 +    int v=ci->modes;
 659.162 +    while(v>1){
 659.163 +      modebits++;
 659.164 +      v>>=1;
 659.165 +    }
 659.166 +
 659.167 +    /* read our mode and pre/post windowsize */
 659.168 +    mode=oggpack_read(&opb,modebits);
 659.169 +  }
 659.170 +  if(mode==-1)return(OV_EBADPACKET);
 659.171 +  return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
 659.172 +}
 659.173 +
 659.174 +int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){
 659.175 +  /* set / clear half-sample-rate mode */
 659.176 +  codec_setup_info     *ci=vi->codec_setup;
 659.177 +
 659.178 +  /* right now, our MDCT can't handle < 64 sample windows. */
 659.179 +  if(ci->blocksizes[0]<=64 && flag)return -1;
 659.180 +  ci->halfrate_flag=(flag?1:0);
 659.181 +  return 0;
 659.182 +}
 659.183 +
 659.184 +int vorbis_synthesis_halfrate_p(vorbis_info *vi){
 659.185 +  codec_setup_info     *ci=vi->codec_setup;
 659.186 +  return ci->halfrate_flag;
 659.187 +}
   660.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   660.2 +++ b/libs/vorbis/vorbisenc.c	Sat Feb 01 19:58:19 2014 +0200
   660.3 @@ -0,0 +1,1215 @@
   660.4 +/********************************************************************
   660.5 + *                                                                  *
   660.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   660.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   660.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   660.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  660.10 + *                                                                  *
  660.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  660.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  660.13 + *                                                                  *
  660.14 + ********************************************************************
  660.15 +
  660.16 + function: simple programmatic interface for encoder mode setup
  660.17 + last mod: $Id: vorbisenc.c 17028 2010-03-25 05:22:15Z xiphmont $
  660.18 +
  660.19 + ********************************************************************/
  660.20 +
  660.21 +#include <stdlib.h>
  660.22 +#include <string.h>
  660.23 +#include <math.h>
  660.24 +
  660.25 +#include "vorbis/codec.h"
  660.26 +#include "vorbis/vorbisenc.h"
  660.27 +
  660.28 +#include "codec_internal.h"
  660.29 +
  660.30 +#include "os.h"
  660.31 +#include "misc.h"
  660.32 +
  660.33 +/* careful with this; it's using static array sizing to make managing
  660.34 +   all the modes a little less annoying.  If we use a residue backend
  660.35 +   with > 12 partition types, or a different division of iteration,
  660.36 +   this needs to be updated. */
  660.37 +typedef struct {
  660.38 +  const static_codebook *books[12][4];
  660.39 +} static_bookblock;
  660.40 +
  660.41 +typedef struct {
  660.42 +  int res_type;
  660.43 +  int limit_type; /* 0 lowpass limited, 1 point stereo limited */
  660.44 +  int grouping;
  660.45 +  const vorbis_info_residue0 *res;
  660.46 +  const static_codebook  *book_aux;
  660.47 +  const static_codebook  *book_aux_managed;
  660.48 +  const static_bookblock *books_base;
  660.49 +  const static_bookblock *books_base_managed;
  660.50 +} vorbis_residue_template;
  660.51 +
  660.52 +typedef struct {
  660.53 +  const vorbis_info_mapping0    *map;
  660.54 +  const vorbis_residue_template *res;
  660.55 +} vorbis_mapping_template;
  660.56 +
  660.57 +typedef struct vp_adjblock{
  660.58 +  int block[P_BANDS];
  660.59 +} vp_adjblock;
  660.60 +
  660.61 +typedef struct {
  660.62 +  int data[NOISE_COMPAND_LEVELS];
  660.63 +} compandblock;
  660.64 +
  660.65 +/* high level configuration information for setting things up
  660.66 +   step-by-step with the detailed vorbis_encode_ctl interface.
  660.67 +   There's a fair amount of redundancy such that interactive setup
  660.68 +   does not directly deal with any vorbis_info or codec_setup_info
  660.69 +   initialization; it's all stored (until full init) in this highlevel
  660.70 +   setup, then flushed out to the real codec setup structs later. */
  660.71 +
  660.72 +typedef struct {
  660.73 +  int att[P_NOISECURVES];
  660.74 +  float boost;
  660.75 +  float decay;
  660.76 +} att3;
  660.77 +typedef struct { int data[P_NOISECURVES]; } adj3;
  660.78 +
  660.79 +typedef struct {
  660.80 +  int   pre[PACKETBLOBS];
  660.81 +  int   post[PACKETBLOBS];
  660.82 +  float kHz[PACKETBLOBS];
  660.83 +  float lowpasskHz[PACKETBLOBS];
  660.84 +} adj_stereo;
  660.85 +
  660.86 +typedef struct {
  660.87 +  int lo;
  660.88 +  int hi;
  660.89 +  int fixed;
  660.90 +} noiseguard;
  660.91 +typedef struct {
  660.92 +  int data[P_NOISECURVES][17];
  660.93 +} noise3;
  660.94 +
  660.95 +typedef struct {
  660.96 +  int      mappings;
  660.97 +  const double  *rate_mapping;
  660.98 +  const double  *quality_mapping;
  660.99 +  int      coupling_restriction;
 660.100 +  long     samplerate_min_restriction;
 660.101 +  long     samplerate_max_restriction;
 660.102 +
 660.103 +
 660.104 +  const int     *blocksize_short;
 660.105 +  const int     *blocksize_long;
 660.106 +
 660.107 +  const att3    *psy_tone_masteratt;
 660.108 +  const int     *psy_tone_0dB;
 660.109 +  const int     *psy_tone_dBsuppress;
 660.110 +
 660.111 +  const vp_adjblock *psy_tone_adj_impulse;
 660.112 +  const vp_adjblock *psy_tone_adj_long;
 660.113 +  const vp_adjblock *psy_tone_adj_other;
 660.114 +
 660.115 +  const noiseguard  *psy_noiseguards;
 660.116 +  const noise3      *psy_noise_bias_impulse;
 660.117 +  const noise3      *psy_noise_bias_padding;
 660.118 +  const noise3      *psy_noise_bias_trans;
 660.119 +  const noise3      *psy_noise_bias_long;
 660.120 +  const int         *psy_noise_dBsuppress;
 660.121 +
 660.122 +  const compandblock  *psy_noise_compand;
 660.123 +  const double        *psy_noise_compand_short_mapping;
 660.124 +  const double        *psy_noise_compand_long_mapping;
 660.125 +
 660.126 +  const int      *psy_noise_normal_start[2];
 660.127 +  const int      *psy_noise_normal_partition[2];
 660.128 +  const double   *psy_noise_normal_thresh;
 660.129 +
 660.130 +  const int      *psy_ath_float;
 660.131 +  const int      *psy_ath_abs;
 660.132 +
 660.133 +  const double   *psy_lowpass;
 660.134 +
 660.135 +  const vorbis_info_psy_global *global_params;
 660.136 +  const double     *global_mapping;
 660.137 +  const adj_stereo *stereo_modes;
 660.138 +
 660.139 +  const static_codebook *const *const *const floor_books;
 660.140 +  const vorbis_info_floor1 *floor_params;
 660.141 +  const int floor_mappings;
 660.142 +  const int **floor_mapping_list;
 660.143 +
 660.144 +  const vorbis_mapping_template *maps;
 660.145 +} ve_setup_data_template;
 660.146 +
 660.147 +/* a few static coder conventions */
 660.148 +static const vorbis_info_mode _mode_template[2]={
 660.149 +  {0,0,0,0},
 660.150 +  {1,0,0,1}
 660.151 +};
 660.152 +
 660.153 +static const vorbis_info_mapping0 _map_nominal[2]={
 660.154 +  {1, {0,0}, {0}, {0}, 1,{0},{1}},
 660.155 +  {1, {0,0}, {1}, {1}, 1,{0},{1}}
 660.156 +};
 660.157 +
 660.158 +#include "modes/setup_44.h"
 660.159 +#include "modes/setup_44u.h"
 660.160 +#include "modes/setup_44p51.h"
 660.161 +#include "modes/setup_32.h"
 660.162 +#include "modes/setup_8.h"
 660.163 +#include "modes/setup_11.h"
 660.164 +#include "modes/setup_16.h"
 660.165 +#include "modes/setup_22.h"
 660.166 +#include "modes/setup_X.h"
 660.167 +
 660.168 +static const ve_setup_data_template *const setup_list[]={
 660.169 +  &ve_setup_44_stereo,
 660.170 +  &ve_setup_44_51,
 660.171 +  &ve_setup_44_uncoupled,
 660.172 +
 660.173 +  &ve_setup_32_stereo,
 660.174 +  &ve_setup_32_uncoupled,
 660.175 +
 660.176 +  &ve_setup_22_stereo,
 660.177 +  &ve_setup_22_uncoupled,
 660.178 +  &ve_setup_16_stereo,
 660.179 +  &ve_setup_16_uncoupled,
 660.180 +
 660.181 +  &ve_setup_11_stereo,
 660.182 +  &ve_setup_11_uncoupled,
 660.183 +  &ve_setup_8_stereo,
 660.184 +  &ve_setup_8_uncoupled,
 660.185 +
 660.186 +  &ve_setup_X_stereo,
 660.187 +  &ve_setup_X_uncoupled,
 660.188 +  &ve_setup_XX_stereo,
 660.189 +  &ve_setup_XX_uncoupled,
 660.190 +  0
 660.191 +};
 660.192 +
 660.193 +static void vorbis_encode_floor_setup(vorbis_info *vi,int s,
 660.194 +                                     const static_codebook *const *const *const books,
 660.195 +                                     const vorbis_info_floor1 *in,
 660.196 +                                     const int *x){
 660.197 +  int i,k,is=s;
 660.198 +  vorbis_info_floor1 *f=_ogg_calloc(1,sizeof(*f));
 660.199 +  codec_setup_info *ci=vi->codec_setup;
 660.200 +
 660.201 +  memcpy(f,in+x[is],sizeof(*f));
 660.202 +
 660.203 +  /* books */
 660.204 +  {
 660.205 +    int partitions=f->partitions;
 660.206 +    int maxclass=-1;
 660.207 +    int maxbook=-1;
 660.208 +    for(i=0;i<partitions;i++)
 660.209 +      if(f->partitionclass[i]>maxclass)maxclass=f->partitionclass[i];
 660.210 +    for(i=0;i<=maxclass;i++){
 660.211 +      if(f->class_book[i]>maxbook)maxbook=f->class_book[i];
 660.212 +      f->class_book[i]+=ci->books;
 660.213 +      for(k=0;k<(1<<f->class_subs[i]);k++){
 660.214 +        if(f->class_subbook[i][k]>maxbook)maxbook=f->class_subbook[i][k];
 660.215 +        if(f->class_subbook[i][k]>=0)f->class_subbook[i][k]+=ci->books;
 660.216 +      }
 660.217 +    }
 660.218 +
 660.219 +    for(i=0;i<=maxbook;i++)
 660.220 +      ci->book_param[ci->books++]=(static_codebook *)books[x[is]][i];
 660.221 +  }
 660.222 +
 660.223 +  /* for now, we're only using floor 1 */
 660.224 +  ci->floor_type[ci->floors]=1;
 660.225 +  ci->floor_param[ci->floors]=f;
 660.226 +  ci->floors++;
 660.227 +
 660.228 +  return;
 660.229 +}
 660.230 +
 660.231 +static void vorbis_encode_global_psych_setup(vorbis_info *vi,double s,
 660.232 +                                            const vorbis_info_psy_global *in,
 660.233 +                                            const double *x){
 660.234 +  int i,is=s;
 660.235 +  double ds=s-is;
 660.236 +  codec_setup_info *ci=vi->codec_setup;
 660.237 +  vorbis_info_psy_global *g=&ci->psy_g_param;
 660.238 +
 660.239 +  memcpy(g,in+(int)x[is],sizeof(*g));
 660.240 +
 660.241 +  ds=x[is]*(1.-ds)+x[is+1]*ds;
 660.242 +  is=(int)ds;
 660.243 +  ds-=is;
 660.244 +  if(ds==0 && is>0){
 660.245 +    is--;
 660.246 +    ds=1.;
 660.247 +  }
 660.248 +
 660.249 +  /* interpolate the trigger threshholds */
 660.250 +  for(i=0;i<4;i++){
 660.251 +    g->preecho_thresh[i]=in[is].preecho_thresh[i]*(1.-ds)+in[is+1].preecho_thresh[i]*ds;
 660.252 +    g->postecho_thresh[i]=in[is].postecho_thresh[i]*(1.-ds)+in[is+1].postecho_thresh[i]*ds;
 660.253 +  }
 660.254 +  g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec;
 660.255 +  return;
 660.256 +}
 660.257 +
 660.258 +static void vorbis_encode_global_stereo(vorbis_info *vi,
 660.259 +                                        const highlevel_encode_setup *const hi,
 660.260 +                                        const adj_stereo *p){
 660.261 +  float s=hi->stereo_point_setting;
 660.262 +  int i,is=s;
 660.263 +  double ds=s-is;
 660.264 +  codec_setup_info *ci=vi->codec_setup;
 660.265 +  vorbis_info_psy_global *g=&ci->psy_g_param;
 660.266 +
 660.267 +  if(p){
 660.268 +    memcpy(g->coupling_prepointamp,p[is].pre,sizeof(*p[is].pre)*PACKETBLOBS);
 660.269 +    memcpy(g->coupling_postpointamp,p[is].post,sizeof(*p[is].post)*PACKETBLOBS);
 660.270 +
 660.271 +    if(hi->managed){
 660.272 +      /* interpolate the kHz threshholds */
 660.273 +      for(i=0;i<PACKETBLOBS;i++){
 660.274 +        float kHz=p[is].kHz[i]*(1.-ds)+p[is+1].kHz[i]*ds;
 660.275 +        g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
 660.276 +        g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
 660.277 +        g->coupling_pkHz[i]=kHz;
 660.278 +
 660.279 +        kHz=p[is].lowpasskHz[i]*(1.-ds)+p[is+1].lowpasskHz[i]*ds;
 660.280 +        g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
 660.281 +        g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
 660.282 +
 660.283 +      }
 660.284 +    }else{
 660.285 +      float kHz=p[is].kHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].kHz[PACKETBLOBS/2]*ds;
 660.286 +      for(i=0;i<PACKETBLOBS;i++){
 660.287 +        g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
 660.288 +        g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
 660.289 +        g->coupling_pkHz[i]=kHz;
 660.290 +      }
 660.291 +
 660.292 +      kHz=p[is].lowpasskHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].lowpasskHz[PACKETBLOBS/2]*ds;
 660.293 +      for(i=0;i<PACKETBLOBS;i++){
 660.294 +        g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
 660.295 +        g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
 660.296 +      }
 660.297 +    }
 660.298 +  }else{
 660.299 +    for(i=0;i<PACKETBLOBS;i++){
 660.300 +      g->sliding_lowpass[0][i]=ci->blocksizes[0];
 660.301 +      g->sliding_lowpass[1][i]=ci->blocksizes[1];
 660.302 +    }
 660.303 +  }
 660.304 +  return;
 660.305 +}
 660.306 +
 660.307 +static void vorbis_encode_psyset_setup(vorbis_info *vi,double s,
 660.308 +                                       const int *nn_start,
 660.309 +                                       const int *nn_partition,
 660.310 +                                       const double *nn_thresh,
 660.311 +                                       int block){
 660.312 +  codec_setup_info *ci=vi->codec_setup;
 660.313 +  vorbis_info_psy *p=ci->psy_param[block];
 660.314 +  highlevel_encode_setup *hi=&ci->hi;
 660.315 +  int is=s;
 660.316 +
 660.317 +  if(block>=ci->psys)
 660.318 +    ci->psys=block+1;
 660.319 +  if(!p){
 660.320 +    p=_ogg_calloc(1,sizeof(*p));
 660.321 +    ci->psy_param[block]=p;
 660.322 +  }
 660.323 +
 660.324 +  memcpy(p,&_psy_info_template,sizeof(*p));
 660.325 +  p->blockflag=block>>1;
 660.326 +
 660.327 +  if(hi->noise_normalize_p){
 660.328 +    p->normal_p=1;
 660.329 +    p->normal_start=nn_start[is];
 660.330 +    p->normal_partition=nn_partition[is];
 660.331 +    p->normal_thresh=nn_thresh[is];
 660.332 +  }
 660.333 +
 660.334 +  return;
 660.335 +}
 660.336 +
 660.337 +static void vorbis_encode_tonemask_setup(vorbis_info *vi,double s,int block,
 660.338 +                                         const att3 *att,
 660.339 +                                         const int  *max,
 660.340 +                                         const vp_adjblock *in){
 660.341 +  int i,is=s;
 660.342 +  double ds=s-is;
 660.343 +  codec_setup_info *ci=vi->codec_setup;
 660.344 +  vorbis_info_psy *p=ci->psy_param[block];
 660.345 +
 660.346 +  /* 0 and 2 are only used by bitmanagement, but there's no harm to always
 660.347 +     filling the values in here */
 660.348 +  p->tone_masteratt[0]=att[is].att[0]*(1.-ds)+att[is+1].att[0]*ds;
 660.349 +  p->tone_masteratt[1]=att[is].att[1]*(1.-ds)+att[is+1].att[1]*ds;
 660.350 +  p->tone_masteratt[2]=att[is].att[2]*(1.-ds)+att[is+1].att[2]*ds;
 660.351 +  p->tone_centerboost=att[is].boost*(1.-ds)+att[is+1].boost*ds;
 660.352 +  p->tone_decay=att[is].decay*(1.-ds)+att[is+1].decay*ds;
 660.353 +
 660.354 +  p->max_curve_dB=max[is]*(1.-ds)+max[is+1]*ds;
 660.355 +
 660.356 +  for(i=0;i<P_BANDS;i++)
 660.357 +    p->toneatt[i]=in[is].block[i]*(1.-ds)+in[is+1].block[i]*ds;
 660.358 +  return;
 660.359 +}
 660.360 +
 660.361 +
 660.362 +static void vorbis_encode_compand_setup(vorbis_info *vi,double s,int block,
 660.363 +                                        const compandblock *in,
 660.364 +                                        const double *x){
 660.365 +  int i,is=s;
 660.366 +  double ds=s-is;
 660.367 +  codec_setup_info *ci=vi->codec_setup;
 660.368 +  vorbis_info_psy *p=ci->psy_param[block];
 660.369 +
 660.370 +  ds=x[is]*(1.-ds)+x[is+1]*ds;
 660.371 +  is=(int)ds;
 660.372 +  ds-=is;
 660.373 +  if(ds==0 && is>0){
 660.374 +    is--;
 660.375 +    ds=1.;
 660.376 +  }
 660.377 +
 660.378 +  /* interpolate the compander settings */
 660.379 +  for(i=0;i<NOISE_COMPAND_LEVELS;i++)
 660.380 +    p->noisecompand[i]=in[is].data[i]*(1.-ds)+in[is+1].data[i]*ds;
 660.381 +  return;
 660.382 +}
 660.383 +
 660.384 +static void vorbis_encode_peak_setup(vorbis_info *vi,double s,int block,
 660.385 +                                    const int *suppress){
 660.386 +  int is=s;
 660.387 +  double ds=s-is;
 660.388 +  codec_setup_info *ci=vi->codec_setup;
 660.389 +  vorbis_info_psy *p=ci->psy_param[block];
 660.390 +
 660.391 +  p->tone_abs_limit=suppress[is]*(1.-ds)+suppress[is+1]*ds;
 660.392 +
 660.393 +  return;
 660.394 +}
 660.395 +
 660.396 +static void vorbis_encode_noisebias_setup(vorbis_info *vi,double s,int block,
 660.397 +                                         const int *suppress,
 660.398 +                                         const noise3 *in,
 660.399 +                                         const noiseguard *guard,
 660.400 +                                         double userbias){
 660.401 +  int i,is=s,j;
 660.402 +  double ds=s-is;
 660.403 +  codec_setup_info *ci=vi->codec_setup;
 660.404 +  vorbis_info_psy *p=ci->psy_param[block];
 660.405 +
 660.406 +  p->noisemaxsupp=suppress[is]*(1.-ds)+suppress[is+1]*ds;
 660.407 +  p->noisewindowlomin=guard[block].lo;
 660.408 +  p->noisewindowhimin=guard[block].hi;
 660.409 +  p->noisewindowfixed=guard[block].fixed;
 660.410 +
 660.411 +  for(j=0;j<P_NOISECURVES;j++)
 660.412 +    for(i=0;i<P_BANDS;i++)
 660.413 +      p->noiseoff[j][i]=in[is].data[j][i]*(1.-ds)+in[is+1].data[j][i]*ds;
 660.414 +
 660.415 +  /* impulse blocks may take a user specified bias to boost the
 660.416 +     nominal/high noise encoding depth */
 660.417 +  for(j=0;j<P_NOISECURVES;j++){
 660.418 +    float min=p->noiseoff[j][0]+6; /* the lowest it can go */
 660.419 +    for(i=0;i<P_BANDS;i++){
 660.420 +      p->noiseoff[j][i]+=userbias;
 660.421 +      if(p->noiseoff[j][i]<min)p->noiseoff[j][i]=min;
 660.422 +    }
 660.423 +  }
 660.424 +
 660.425 +  return;
 660.426 +}
 660.427 +
 660.428 +static void vorbis_encode_ath_setup(vorbis_info *vi,int block){
 660.429 +  codec_setup_info *ci=vi->codec_setup;
 660.430 +  vorbis_info_psy *p=ci->psy_param[block];
 660.431 +
 660.432 +  p->ath_adjatt=ci->hi.ath_floating_dB;
 660.433 +  p->ath_maxatt=ci->hi.ath_absolute_dB;
 660.434 +  return;
 660.435 +}
 660.436 +
 660.437 +
 660.438 +static int book_dup_or_new(codec_setup_info *ci,const static_codebook *book){
 660.439 +  int i;
 660.440 +  for(i=0;i<ci->books;i++)
 660.441 +    if(ci->book_param[i]==book)return(i);
 660.442 +
 660.443 +  return(ci->books++);
 660.444 +}
 660.445 +
 660.446 +static void vorbis_encode_blocksize_setup(vorbis_info *vi,double s,
 660.447 +                                         const int *shortb,const int *longb){
 660.448 +
 660.449 +  codec_setup_info *ci=vi->codec_setup;
 660.450 +  int is=s;
 660.451 +
 660.452 +  int blockshort=shortb[is];
 660.453 +  int blocklong=longb[is];
 660.454 +  ci->blocksizes[0]=blockshort;
 660.455 +  ci->blocksizes[1]=blocklong;
 660.456 +
 660.457 +}
 660.458 +
 660.459 +static void vorbis_encode_residue_setup(vorbis_info *vi,
 660.460 +                                        int number, int block,
 660.461 +                                        const vorbis_residue_template *res){
 660.462 +
 660.463 +  codec_setup_info *ci=vi->codec_setup;
 660.464 +  int i;
 660.465 +
 660.466 +  vorbis_info_residue0 *r=ci->residue_param[number]=
 660.467 +    _ogg_malloc(sizeof(*r));
 660.468 +
 660.469 +  memcpy(r,res->res,sizeof(*r));
 660.470 +  if(ci->residues<=number)ci->residues=number+1;
 660.471 +
 660.472 +  r->grouping=res->grouping;
 660.473 +  ci->residue_type[number]=res->res_type;
 660.474 +
 660.475 +  /* fill in all the books */
 660.476 +  {
 660.477 +    int booklist=0,k;
 660.478 +
 660.479 +    if(ci->hi.managed){
 660.480 +      for(i=0;i<r->partitions;i++)
 660.481 +        for(k=0;k<4;k++)
 660.482 +          if(res->books_base_managed->books[i][k])
 660.483 +            r->secondstages[i]|=(1<<k);
 660.484 +
 660.485 +      r->groupbook=book_dup_or_new(ci,res->book_aux_managed);
 660.486 +      ci->book_param[r->groupbook]=(static_codebook *)res->book_aux_managed;
 660.487 +
 660.488 +      for(i=0;i<r->partitions;i++){
 660.489 +        for(k=0;k<4;k++){
 660.490 +          if(res->books_base_managed->books[i][k]){
 660.491 +            int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]);
 660.492 +            r->booklist[booklist++]=bookid;
 660.493 +            ci->book_param[bookid]=(static_codebook *)res->books_base_managed->books[i][k];
 660.494 +          }
 660.495 +        }
 660.496 +      }
 660.497 +
 660.498 +    }else{
 660.499 +
 660.500 +      for(i=0;i<r->partitions;i++)
 660.501 +        for(k=0;k<4;k++)
 660.502 +          if(res->books_base->books[i][k])
 660.503 +            r->secondstages[i]|=(1<<k);
 660.504 +
 660.505 +      r->groupbook=book_dup_or_new(ci,res->book_aux);
 660.506 +      ci->book_param[r->groupbook]=(static_codebook *)res->book_aux;
 660.507 +
 660.508 +      for(i=0;i<r->partitions;i++){
 660.509 +        for(k=0;k<4;k++){
 660.510 +          if(res->books_base->books[i][k]){
 660.511 +            int bookid=book_dup_or_new(ci,res->books_base->books[i][k]);
 660.512 +            r->booklist[booklist++]=bookid;
 660.513 +            ci->book_param[bookid]=(static_codebook *)res->books_base->books[i][k];
 660.514 +          }
 660.515 +        }
 660.516 +      }
 660.517 +    }
 660.518 +  }
 660.519 +
 660.520 +  /* lowpass setup/pointlimit */
 660.521 +  {
 660.522 +    double freq=ci->hi.lowpass_kHz*1000.;
 660.523 +    vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */
 660.524 +    double nyq=vi->rate/2.;
 660.525 +    long blocksize=ci->blocksizes[block]>>1;
 660.526 +
 660.527 +    /* lowpass needs to be set in the floor and the residue. */
 660.528 +    if(freq>nyq)freq=nyq;
 660.529 +    /* in the floor, the granularity can be very fine; it doesn't alter
 660.530 +       the encoding structure, only the samples used to fit the floor
 660.531 +       approximation */
 660.532 +    f->n=freq/nyq*blocksize;
 660.533 +
 660.534 +    /* this res may by limited by the maximum pointlimit of the mode,
 660.535 +       not the lowpass. the floor is always lowpass limited. */
 660.536 +    switch(res->limit_type){
 660.537 +    case 1: /* point stereo limited */
 660.538 +      if(ci->hi.managed)
 660.539 +        freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.;
 660.540 +      else
 660.541 +        freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.;
 660.542 +      if(freq>nyq)freq=nyq;
 660.543 +      break;
 660.544 +    case 2: /* LFE channel; lowpass at ~ 250Hz */
 660.545 +      freq=250;
 660.546 +      break;
 660.547 +    default:
 660.548 +      /* already set */
 660.549 +      break;
 660.550 +    }
 660.551 +
 660.552 +    /* in the residue, we're constrained, physically, by partition
 660.553 +       boundaries.  We still lowpass 'wherever', but we have to round up
 660.554 +       here to next boundary, or the vorbis spec will round it *down* to
 660.555 +       previous boundary in encode/decode */
 660.556 +    if(ci->residue_type[number]==2){
 660.557 +      /* residue 2 bundles together multiple channels; used by stereo
 660.558 +         and surround.  Count the channels in use */
 660.559 +      /* Multiple maps/submaps can point to the same residue.  In the case
 660.560 +         of residue 2, they all better have the same number of
 660.561 +         channels/samples. */
 660.562 +      int j,k,ch=0;
 660.563 +      for(i=0;i<ci->maps&&ch==0;i++){
 660.564 +        vorbis_info_mapping0 *mi=(vorbis_info_mapping0 *)ci->map_param[i];
 660.565 +        for(j=0;j<mi->submaps && ch==0;j++)
 660.566 +          if(mi->residuesubmap[j]==number) /* we found a submap referencing theis residue backend */
 660.567 +            for(k=0;k<vi->channels;k++)
 660.568 +              if(mi->chmuxlist[k]==j) /* this channel belongs to the submap */
 660.569 +                ch++;
 660.570 +      }
 660.571 +
 660.572 +      r->end=(int)((freq/nyq*blocksize*ch)/r->grouping+.9)* /* round up only if we're well past */
 660.573 +        r->grouping;
 660.574 +      /* the blocksize and grouping may disagree at the end */
 660.575 +      if(r->end>blocksize*ch)r->end=blocksize*ch/r->grouping*r->grouping;
 660.576 +
 660.577 +    }else{
 660.578 +
 660.579 +      r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */
 660.580 +        r->grouping;
 660.581 +      /* the blocksize and grouping may disagree at the end */
 660.582 +      if(r->end>blocksize)r->end=blocksize/r->grouping*r->grouping;
 660.583 +
 660.584 +    }
 660.585 +
 660.586 +    if(r->end==0)r->end=r->grouping; /* LFE channel */
 660.587 +
 660.588 +  }
 660.589 +}
 660.590 +
 660.591 +/* we assume two maps in this encoder */
 660.592 +static void vorbis_encode_map_n_res_setup(vorbis_info *vi,double s,
 660.593 +                                          const vorbis_mapping_template *maps){
 660.594 +
 660.595 +  codec_setup_info *ci=vi->codec_setup;
 660.596 +  int i,j,is=s,modes=2;
 660.597 +  const vorbis_info_mapping0 *map=maps[is].map;
 660.598 +  const vorbis_info_mode *mode=_mode_template;
 660.599 +  const vorbis_residue_template *res=maps[is].res;
 660.600 +
 660.601 +  if(ci->blocksizes[0]==ci->blocksizes[1])modes=1;
 660.602 +
 660.603 +  for(i=0;i<modes;i++){
 660.604 +
 660.605 +    ci->map_param[i]=_ogg_calloc(1,sizeof(*map));
 660.606 +    ci->mode_param[i]=_ogg_calloc(1,sizeof(*mode));
 660.607 +
 660.608 +    memcpy(ci->mode_param[i],mode+i,sizeof(*_mode_template));
 660.609 +    if(i>=ci->modes)ci->modes=i+1;
 660.610 +
 660.611 +    ci->map_type[i]=0;
 660.612 +    memcpy(ci->map_param[i],map+i,sizeof(*map));
 660.613 +    if(i>=ci->maps)ci->maps=i+1;
 660.614 +
 660.615 +    for(j=0;j<map[i].submaps;j++)
 660.616 +      vorbis_encode_residue_setup(vi,map[i].residuesubmap[j],i
 660.617 +                                  ,res+map[i].residuesubmap[j]);
 660.618 +  }
 660.619 +}
 660.620 +
 660.621 +static double setting_to_approx_bitrate(vorbis_info *vi){
 660.622 +  codec_setup_info *ci=vi->codec_setup;
 660.623 +  highlevel_encode_setup *hi=&ci->hi;
 660.624 +  ve_setup_data_template *setup=(ve_setup_data_template *)hi->setup;
 660.625 +  int is=hi->base_setting;
 660.626 +  double ds=hi->base_setting-is;
 660.627 +  int ch=vi->channels;
 660.628 +  const double *r=setup->rate_mapping;
 660.629 +
 660.630 +  if(r==NULL)
 660.631 +    return(-1);
 660.632 +
 660.633 +  return((r[is]*(1.-ds)+r[is+1]*ds)*ch);
 660.634 +}
 660.635 +
 660.636 +static const void *get_setup_template(long ch,long srate,
 660.637 +                                      double req,int q_or_bitrate,
 660.638 +                                      double *base_setting){
 660.639 +  int i=0,j;
 660.640 +  if(q_or_bitrate)req/=ch;
 660.641 +
 660.642 +  while(setup_list[i]){
 660.643 +    if(setup_list[i]->coupling_restriction==-1 ||
 660.644 +       setup_list[i]->coupling_restriction==ch){
 660.645 +      if(srate>=setup_list[i]->samplerate_min_restriction &&
 660.646 +         srate<=setup_list[i]->samplerate_max_restriction){
 660.647 +        int mappings=setup_list[i]->mappings;
 660.648 +        const double *map=(q_or_bitrate?
 660.649 +                     setup_list[i]->rate_mapping:
 660.650 +                     setup_list[i]->quality_mapping);
 660.651 +
 660.652 +        /* the template matches.  Does the requested quality mode
 660.653 +           fall within this template's modes? */
 660.654 +        if(req<map[0]){++i;continue;}
 660.655 +        if(req>map[setup_list[i]->mappings]){++i;continue;}
 660.656 +        for(j=0;j<mappings;j++)
 660.657 +          if(req>=map[j] && req<map[j+1])break;
 660.658 +        /* an all-points match */
 660.659 +        if(j==mappings)
 660.660 +          *base_setting=j-.001;
 660.661 +        else{
 660.662 +          float low=map[j];
 660.663 +          float high=map[j+1];
 660.664 +          float del=(req-low)/(high-low);
 660.665 +          *base_setting=j+del;
 660.666 +        }
 660.667 +
 660.668 +        return(setup_list[i]);
 660.669 +      }
 660.670 +    }
 660.671 +    i++;
 660.672 +  }
 660.673 +
 660.674 +  return NULL;
 660.675 +}
 660.676 +
 660.677 +/* encoders will need to use vorbis_info_init beforehand and call
 660.678 +   vorbis_info clear when all done */
 660.679 +
 660.680 +/* two interfaces; this, more detailed one, and later a convenience
 660.681 +   layer on top */
 660.682 +
 660.683 +/* the final setup call */
 660.684 +int vorbis_encode_setup_init(vorbis_info *vi){
 660.685 +  int i,i0=0,singleblock=0;
 660.686 +  codec_setup_info *ci=vi->codec_setup;
 660.687 +  ve_setup_data_template *setup=NULL;
 660.688 +  highlevel_encode_setup *hi=&ci->hi;
 660.689 +
 660.690 +  if(ci==NULL)return(OV_EINVAL);
 660.691 +  if(!hi->impulse_block_p)i0=1;
 660.692 +
 660.693 +  /* too low/high an ATH floater is nonsensical, but doesn't break anything */
 660.694 +  if(hi->ath_floating_dB>-80)hi->ath_floating_dB=-80;
 660.695 +  if(hi->ath_floating_dB<-200)hi->ath_floating_dB=-200;
 660.696 +
 660.697 +  /* again, bound this to avoid the app shooting itself int he foot
 660.698 +     too badly */
 660.699 +  if(hi->amplitude_track_dBpersec>0.)hi->amplitude_track_dBpersec=0.;
 660.700 +  if(hi->amplitude_track_dBpersec<-99999.)hi->amplitude_track_dBpersec=-99999.;
 660.701 +
 660.702 +  /* get the appropriate setup template; matches the fetch in previous
 660.703 +     stages */
 660.704 +  setup=(ve_setup_data_template *)hi->setup;
 660.705 +  if(setup==NULL)return(OV_EINVAL);
 660.706 +
 660.707 +  hi->set_in_stone=1;
 660.708 +  /* choose block sizes from configured sizes as well as paying
 660.709 +     attention to long_block_p and short_block_p.  If the configured
 660.710 +     short and long blocks are the same length, we set long_block_p
 660.711 +     and unset short_block_p */
 660.712 +  vorbis_encode_blocksize_setup(vi,hi->base_setting,
 660.713 +                                setup->blocksize_short,
 660.714 +                                setup->blocksize_long);
 660.715 +  if(ci->blocksizes[0]==ci->blocksizes[1])singleblock=1;
 660.716 +
 660.717 +  /* floor setup; choose proper floor params.  Allocated on the floor
 660.718 +     stack in order; if we alloc only a single long floor, it's 0 */
 660.719 +  for(i=0;i<setup->floor_mappings;i++)
 660.720 +    vorbis_encode_floor_setup(vi,hi->base_setting,
 660.721 +                              setup->floor_books,
 660.722 +                              setup->floor_params,
 660.723 +                              setup->floor_mapping_list[i]);
 660.724 +
 660.725 +  /* setup of [mostly] short block detection and stereo*/
 660.726 +  vorbis_encode_global_psych_setup(vi,hi->trigger_setting,
 660.727 +                                   setup->global_params,
 660.728 +                                   setup->global_mapping);
 660.729 +  vorbis_encode_global_stereo(vi,hi,setup->stereo_modes);
 660.730 +
 660.731 +  /* basic psych setup and noise normalization */
 660.732 +  vorbis_encode_psyset_setup(vi,hi->base_setting,
 660.733 +                             setup->psy_noise_normal_start[0],
 660.734 +                             setup->psy_noise_normal_partition[0],
 660.735 +                             setup->psy_noise_normal_thresh,
 660.736 +                             0);
 660.737 +  vorbis_encode_psyset_setup(vi,hi->base_setting,
 660.738 +                             setup->psy_noise_normal_start[0],
 660.739 +                             setup->psy_noise_normal_partition[0],
 660.740 +                             setup->psy_noise_normal_thresh,
 660.741 +                             1);
 660.742 +  if(!singleblock){
 660.743 +    vorbis_encode_psyset_setup(vi,hi->base_setting,
 660.744 +                               setup->psy_noise_normal_start[1],
 660.745 +                               setup->psy_noise_normal_partition[1],
 660.746 +                                    setup->psy_noise_normal_thresh,
 660.747 +                               2);
 660.748 +    vorbis_encode_psyset_setup(vi,hi->base_setting,
 660.749 +                               setup->psy_noise_normal_start[1],
 660.750 +                               setup->psy_noise_normal_partition[1],
 660.751 +                               setup->psy_noise_normal_thresh,
 660.752 +                               3);
 660.753 +  }
 660.754 +
 660.755 +  /* tone masking setup */
 660.756 +  vorbis_encode_tonemask_setup(vi,hi->block[i0].tone_mask_setting,0,
 660.757 +                               setup->psy_tone_masteratt,
 660.758 +                               setup->psy_tone_0dB,
 660.759 +                               setup->psy_tone_adj_impulse);
 660.760 +  vorbis_encode_tonemask_setup(vi,hi->block[1].tone_mask_setting,1,
 660.761 +                               setup->psy_tone_masteratt,
 660.762 +                               setup->psy_tone_0dB,
 660.763 +                               setup->psy_tone_adj_other);
 660.764 +  if(!singleblock){
 660.765 +    vorbis_encode_tonemask_setup(vi,hi->block[2].tone_mask_setting,2,
 660.766 +                                 setup->psy_tone_masteratt,
 660.767 +                                 setup->psy_tone_0dB,
 660.768 +                                 setup->psy_tone_adj_other);
 660.769 +    vorbis_encode_tonemask_setup(vi,hi->block[3].tone_mask_setting,3,
 660.770 +                                 setup->psy_tone_masteratt,
 660.771 +                                 setup->psy_tone_0dB,
 660.772 +                                 setup->psy_tone_adj_long);
 660.773 +  }
 660.774 +
 660.775 +  /* noise companding setup */
 660.776 +  vorbis_encode_compand_setup(vi,hi->block[i0].noise_compand_setting,0,
 660.777 +                              setup->psy_noise_compand,
 660.778 +                              setup->psy_noise_compand_short_mapping);
 660.779 +  vorbis_encode_compand_setup(vi,hi->block[1].noise_compand_setting,1,
 660.780 +                              setup->psy_noise_compand,
 660.781 +                              setup->psy_noise_compand_short_mapping);
 660.782 +  if(!singleblock){
 660.783 +    vorbis_encode_compand_setup(vi,hi->block[2].noise_compand_setting,2,
 660.784 +                                setup->psy_noise_compand,
 660.785 +                                setup->psy_noise_compand_long_mapping);
 660.786 +    vorbis_encode_compand_setup(vi,hi->block[3].noise_compand_setting,3,
 660.787 +                                setup->psy_noise_compand,
 660.788 +                                setup->psy_noise_compand_long_mapping);
 660.789 +  }
 660.790 +
 660.791 +  /* peak guarding setup  */
 660.792 +  vorbis_encode_peak_setup(vi,hi->block[i0].tone_peaklimit_setting,0,
 660.793 +                           setup->psy_tone_dBsuppress);
 660.794 +  vorbis_encode_peak_setup(vi,hi->block[1].tone_peaklimit_setting,1,
 660.795 +                           setup->psy_tone_dBsuppress);
 660.796 +  if(!singleblock){
 660.797 +    vorbis_encode_peak_setup(vi,hi->block[2].tone_peaklimit_setting,2,
 660.798 +                             setup->psy_tone_dBsuppress);
 660.799 +    vorbis_encode_peak_setup(vi,hi->block[3].tone_peaklimit_setting,3,
 660.800 +                             setup->psy_tone_dBsuppress);
 660.801 +  }
 660.802 +
 660.803 +  /* noise bias setup */
 660.804 +  vorbis_encode_noisebias_setup(vi,hi->block[i0].noise_bias_setting,0,
 660.805 +                                setup->psy_noise_dBsuppress,
 660.806 +                                setup->psy_noise_bias_impulse,
 660.807 +                                setup->psy_noiseguards,
 660.808 +                                (i0==0?hi->impulse_noisetune:0.));
 660.809 +  vorbis_encode_noisebias_setup(vi,hi->block[1].noise_bias_setting,1,
 660.810 +                                setup->psy_noise_dBsuppress,
 660.811 +                                setup->psy_noise_bias_padding,
 660.812 +                                setup->psy_noiseguards,0.);
 660.813 +  if(!singleblock){
 660.814 +    vorbis_encode_noisebias_setup(vi,hi->block[2].noise_bias_setting,2,
 660.815 +                                  setup->psy_noise_dBsuppress,
 660.816 +                                  setup->psy_noise_bias_trans,
 660.817 +                                  setup->psy_noiseguards,0.);
 660.818 +    vorbis_encode_noisebias_setup(vi,hi->block[3].noise_bias_setting,3,
 660.819 +                                  setup->psy_noise_dBsuppress,
 660.820 +                                  setup->psy_noise_bias_long,
 660.821 +                                  setup->psy_noiseguards,0.);
 660.822 +  }
 660.823 +
 660.824 +  vorbis_encode_ath_setup(vi,0);
 660.825 +  vorbis_encode_ath_setup(vi,1);
 660.826 +  if(!singleblock){
 660.827 +    vorbis_encode_ath_setup(vi,2);
 660.828 +    vorbis_encode_ath_setup(vi,3);
 660.829 +  }
 660.830 +
 660.831 +  vorbis_encode_map_n_res_setup(vi,hi->base_setting,setup->maps);
 660.832 +
 660.833 +  /* set bitrate readonlies and management */
 660.834 +  if(hi->bitrate_av>0)
 660.835 +    vi->bitrate_nominal=hi->bitrate_av;
 660.836 +  else{
 660.837 +    vi->bitrate_nominal=setting_to_approx_bitrate(vi);
 660.838 +  }
 660.839 +
 660.840 +  vi->bitrate_lower=hi->bitrate_min;
 660.841 +  vi->bitrate_upper=hi->bitrate_max;
 660.842 +  if(hi->bitrate_av)
 660.843 +    vi->bitrate_window=(double)hi->bitrate_reservoir/hi->bitrate_av;
 660.844 +  else
 660.845 +    vi->bitrate_window=0.;
 660.846 +
 660.847 +  if(hi->managed){
 660.848 +    ci->bi.avg_rate=hi->bitrate_av;
 660.849 +    ci->bi.min_rate=hi->bitrate_min;
 660.850 +    ci->bi.max_rate=hi->bitrate_max;
 660.851 +
 660.852 +    ci->bi.reservoir_bits=hi->bitrate_reservoir;
 660.853 +    ci->bi.reservoir_bias=
 660.854 +      hi->bitrate_reservoir_bias;
 660.855 +
 660.856 +    ci->bi.slew_damp=hi->bitrate_av_damp;
 660.857 +
 660.858 +  }
 660.859 +
 660.860 +  return(0);
 660.861 +
 660.862 +}
 660.863 +
 660.864 +static void vorbis_encode_setup_setting(vorbis_info *vi,
 660.865 +                                       long  channels,
 660.866 +                                       long  rate){
 660.867 +  int i,is;
 660.868 +  codec_setup_info *ci=vi->codec_setup;
 660.869 +  highlevel_encode_setup *hi=&ci->hi;
 660.870 +  const ve_setup_data_template *setup=hi->setup;
 660.871 +  double ds;
 660.872 +
 660.873 +  vi->version=0;
 660.874 +  vi->channels=channels;
 660.875 +  vi->rate=rate;
 660.876 +
 660.877 +  hi->impulse_block_p=1;
 660.878 +  hi->noise_normalize_p=1;
 660.879 +
 660.880 +  is=hi->base_setting;
 660.881 +  ds=hi->base_setting-is;
 660.882 +
 660.883 +  hi->stereo_point_setting=hi->base_setting;
 660.884 +
 660.885 +  if(!hi->lowpass_altered)
 660.886 +    hi->lowpass_kHz=
 660.887 +      setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds;
 660.888 +
 660.889 +  hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+
 660.890 +    setup->psy_ath_float[is+1]*ds;
 660.891 +  hi->ath_absolute_dB=setup->psy_ath_abs[is]*(1.-ds)+
 660.892 +    setup->psy_ath_abs[is+1]*ds;
 660.893 +
 660.894 +  hi->amplitude_track_dBpersec=-6.;
 660.895 +  hi->trigger_setting=hi->base_setting;
 660.896 +
 660.897 +  for(i=0;i<4;i++){
 660.898 +    hi->block[i].tone_mask_setting=hi->base_setting;
 660.899 +    hi->block[i].tone_peaklimit_setting=hi->base_setting;
 660.900 +    hi->block[i].noise_bias_setting=hi->base_setting;
 660.901 +    hi->block[i].noise_compand_setting=hi->base_setting;
 660.902 +  }
 660.903 +}
 660.904 +
 660.905 +int vorbis_encode_setup_vbr(vorbis_info *vi,
 660.906 +                            long  channels,
 660.907 +                            long  rate,
 660.908 +                            float quality){
 660.909 +  codec_setup_info *ci=vi->codec_setup;
 660.910 +  highlevel_encode_setup *hi=&ci->hi;
 660.911 +
 660.912 +  quality+=.0000001;
 660.913 +  if(quality>=1.)quality=.9999;
 660.914 +
 660.915 +  hi->req=quality;
 660.916 +  hi->setup=get_setup_template(channels,rate,quality,0,&hi->base_setting);
 660.917 +  if(!hi->setup)return OV_EIMPL;
 660.918 +
 660.919 +  vorbis_encode_setup_setting(vi,channels,rate);
 660.920 +  hi->managed=0;
 660.921 +  hi->coupling_p=1;
 660.922 +
 660.923 +  return 0;
 660.924 +}
 660.925 +
 660.926 +int vorbis_encode_init_vbr(vorbis_info *vi,
 660.927 +                           long channels,
 660.928 +                           long rate,
 660.929 +
 660.930 +                           float base_quality /* 0. to 1. */
 660.931 +                           ){
 660.932 +  int ret=0;
 660.933 +
 660.934 +  ret=vorbis_encode_setup_vbr(vi,channels,rate,base_quality);
 660.935 +
 660.936 +  if(ret){
 660.937 +    vorbis_info_clear(vi);
 660.938 +    return ret;
 660.939 +  }
 660.940 +  ret=vorbis_encode_setup_init(vi);
 660.941 +  if(ret)
 660.942 +    vorbis_info_clear(vi);
 660.943 +  return(ret);
 660.944 +}
 660.945 +
 660.946 +int vorbis_encode_setup_managed(vorbis_info *vi,
 660.947 +                                long channels,
 660.948 +                                long rate,
 660.949 +
 660.950 +                                long max_bitrate,
 660.951 +                                long nominal_bitrate,
 660.952 +                                long min_bitrate){
 660.953 +
 660.954 +  codec_setup_info *ci=vi->codec_setup;
 660.955 +  highlevel_encode_setup *hi=&ci->hi;
 660.956 +  double tnominal=nominal_bitrate;
 660.957 +
 660.958 +  if(nominal_bitrate<=0.){
 660.959 +    if(max_bitrate>0.){
 660.960 +      if(min_bitrate>0.)
 660.961 +        nominal_bitrate=(max_bitrate+min_bitrate)*.5;
 660.962 +      else
 660.963 +        nominal_bitrate=max_bitrate*.875;
 660.964 +    }else{
 660.965 +      if(min_bitrate>0.){
 660.966 +        nominal_bitrate=min_bitrate;
 660.967 +      }else{
 660.968 +        return(OV_EINVAL);
 660.969 +      }
 660.970 +    }
 660.971 +  }
 660.972 +
 660.973 +  hi->req=nominal_bitrate;
 660.974 +  hi->setup=get_setup_template(channels,rate,nominal_bitrate,1,&hi->base_setting);
 660.975 +  if(!hi->setup)return OV_EIMPL;
 660.976 +
 660.977 +  vorbis_encode_setup_setting(vi,channels,rate);
 660.978 +
 660.979 +  /* initialize management with sane defaults */
 660.980 +  hi->coupling_p=1;
 660.981 +  hi->managed=1;
 660.982 +  hi->bitrate_min=min_bitrate;
 660.983 +  hi->bitrate_max=max_bitrate;
 660.984 +  hi->bitrate_av=tnominal;
 660.985 +  hi->bitrate_av_damp=1.5f; /* full range in no less than 1.5 second */
 660.986 +  hi->bitrate_reservoir=nominal_bitrate*2;
 660.987 +  hi->bitrate_reservoir_bias=.1; /* bias toward hoarding bits */
 660.988 +
 660.989 +  return(0);
 660.990 +
 660.991 +}
 660.992 +
 660.993 +int vorbis_encode_init(vorbis_info *vi,
 660.994 +                       long channels,
 660.995 +                       long rate,
 660.996 +
 660.997 +                       long max_bitrate,
 660.998 +                       long nominal_bitrate,
 660.999 +                       long min_bitrate){
660.1000 +
660.1001 +  int ret=vorbis_encode_setup_managed(vi,channels,rate,
660.1002 +                                      max_bitrate,
660.1003 +                                      nominal_bitrate,
660.1004 +                                      min_bitrate);
660.1005 +  if(ret){
660.1006 +    vorbis_info_clear(vi);
660.1007 +    return(ret);
660.1008 +  }
660.1009 +
660.1010 +  ret=vorbis_encode_setup_init(vi);
660.1011 +  if(ret)
660.1012 +    vorbis_info_clear(vi);
660.1013 +  return(ret);
660.1014 +}
660.1015 +
660.1016 +int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
660.1017 +  if(vi){
660.1018 +    codec_setup_info *ci=vi->codec_setup;
660.1019 +    highlevel_encode_setup *hi=&ci->hi;
660.1020 +    int setp=(number&0xf); /* a read request has a low nibble of 0 */
660.1021 +
660.1022 +    if(setp && hi->set_in_stone)return(OV_EINVAL);
660.1023 +
660.1024 +    switch(number){
660.1025 +
660.1026 +    /* now deprecated *****************/
660.1027 +    case OV_ECTL_RATEMANAGE_GET:
660.1028 +      {
660.1029 +
660.1030 +        struct ovectl_ratemanage_arg *ai=
660.1031 +          (struct ovectl_ratemanage_arg *)arg;
660.1032 +
660.1033 +        ai->management_active=hi->managed;
660.1034 +        ai->bitrate_hard_window=ai->bitrate_av_window=
660.1035 +          (double)hi->bitrate_reservoir/vi->rate;
660.1036 +        ai->bitrate_av_window_center=1.;
660.1037 +        ai->bitrate_hard_min=hi->bitrate_min;
660.1038 +        ai->bitrate_hard_max=hi->bitrate_max;
660.1039 +        ai->bitrate_av_lo=hi->bitrate_av;
660.1040 +        ai->bitrate_av_hi=hi->bitrate_av;
660.1041 +
660.1042 +      }
660.1043 +      return(0);
660.1044 +
660.1045 +    /* now deprecated *****************/
660.1046 +    case OV_ECTL_RATEMANAGE_SET:
660.1047 +      {
660.1048 +        struct ovectl_ratemanage_arg *ai=
660.1049 +          (struct ovectl_ratemanage_arg *)arg;
660.1050 +        if(ai==NULL){
660.1051 +          hi->managed=0;
660.1052 +        }else{
660.1053 +          hi->managed=ai->management_active;
660.1054 +          vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_AVG,arg);
660.1055 +          vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_HARD,arg);
660.1056 +        }
660.1057 +      }
660.1058 +      return 0;
660.1059 +
660.1060 +    /* now deprecated *****************/
660.1061 +    case OV_ECTL_RATEMANAGE_AVG:
660.1062 +      {
660.1063 +        struct ovectl_ratemanage_arg *ai=
660.1064 +          (struct ovectl_ratemanage_arg *)arg;
660.1065 +        if(ai==NULL){
660.1066 +          hi->bitrate_av=0;
660.1067 +        }else{
660.1068 +          hi->bitrate_av=(ai->bitrate_av_lo+ai->bitrate_av_hi)*.5;
660.1069 +        }
660.1070 +      }
660.1071 +      return(0);
660.1072 +    /* now deprecated *****************/
660.1073 +    case OV_ECTL_RATEMANAGE_HARD:
660.1074 +      {
660.1075 +        struct ovectl_ratemanage_arg *ai=
660.1076 +          (struct ovectl_ratemanage_arg *)arg;
660.1077 +        if(ai==NULL){
660.1078 +          hi->bitrate_min=0;
660.1079 +          hi->bitrate_max=0;
660.1080 +        }else{
660.1081 +          hi->bitrate_min=ai->bitrate_hard_min;
660.1082 +          hi->bitrate_max=ai->bitrate_hard_max;
660.1083 +          hi->bitrate_reservoir=ai->bitrate_hard_window*
660.1084 +            (hi->bitrate_max+hi->bitrate_min)*.5;
660.1085 +        }
660.1086 +        if(hi->bitrate_reservoir<128.)
660.1087 +          hi->bitrate_reservoir=128.;
660.1088 +      }
660.1089 +      return(0);
660.1090 +
660.1091 +      /* replacement ratemanage interface */
660.1092 +    case OV_ECTL_RATEMANAGE2_GET:
660.1093 +      {
660.1094 +        struct ovectl_ratemanage2_arg *ai=
660.1095 +          (struct ovectl_ratemanage2_arg *)arg;
660.1096 +        if(ai==NULL)return OV_EINVAL;
660.1097 +
660.1098 +        ai->management_active=hi->managed;
660.1099 +        ai->bitrate_limit_min_kbps=hi->bitrate_min/1000;
660.1100 +        ai->bitrate_limit_max_kbps=hi->bitrate_max/1000;
660.1101 +        ai->bitrate_average_kbps=hi->bitrate_av/1000;
660.1102 +        ai->bitrate_average_damping=hi->bitrate_av_damp;
660.1103 +        ai->bitrate_limit_reservoir_bits=hi->bitrate_reservoir;
660.1104 +        ai->bitrate_limit_reservoir_bias=hi->bitrate_reservoir_bias;
660.1105 +      }
660.1106 +      return (0);
660.1107 +    case OV_ECTL_RATEMANAGE2_SET:
660.1108 +      {
660.1109 +        struct ovectl_ratemanage2_arg *ai=
660.1110 +          (struct ovectl_ratemanage2_arg *)arg;
660.1111 +        if(ai==NULL){
660.1112 +          hi->managed=0;
660.1113 +        }else{
660.1114 +          /* sanity check; only catch invariant violations */
660.1115 +          if(ai->bitrate_limit_min_kbps>0 &&
660.1116 +             ai->bitrate_average_kbps>0 &&
660.1117 +             ai->bitrate_limit_min_kbps>ai->bitrate_average_kbps)
660.1118 +            return OV_EINVAL;
660.1119 +
660.1120 +          if(ai->bitrate_limit_max_kbps>0 &&
660.1121 +             ai->bitrate_average_kbps>0 &&
660.1122 +             ai->bitrate_limit_max_kbps<ai->bitrate_average_kbps)
660.1123 +            return OV_EINVAL;
660.1124 +
660.1125 +          if(ai->bitrate_limit_min_kbps>0 &&
660.1126 +             ai->bitrate_limit_max_kbps>0 &&
660.1127 +             ai->bitrate_limit_min_kbps>ai->bitrate_limit_max_kbps)
660.1128 +            return OV_EINVAL;
660.1129 +
660.1130 +          if(ai->bitrate_average_damping <= 0.)
660.1131 +            return OV_EINVAL;
660.1132 +
660.1133 +          if(ai->bitrate_limit_reservoir_bits < 0)
660.1134 +            return OV_EINVAL;
660.1135 +
660.1136 +          if(ai->bitrate_limit_reservoir_bias < 0.)
660.1137 +            return OV_EINVAL;
660.1138 +
660.1139 +          if(ai->bitrate_limit_reservoir_bias > 1.)
660.1140 +            return OV_EINVAL;
660.1141 +
660.1142 +          hi->managed=ai->management_active;
660.1143 +          hi->bitrate_min=ai->bitrate_limit_min_kbps * 1000;
660.1144 +          hi->bitrate_max=ai->bitrate_limit_max_kbps * 1000;
660.1145 +          hi->bitrate_av=ai->bitrate_average_kbps * 1000;
660.1146 +          hi->bitrate_av_damp=ai->bitrate_average_damping;
660.1147 +          hi->bitrate_reservoir=ai->bitrate_limit_reservoir_bits;
660.1148 +          hi->bitrate_reservoir_bias=ai->bitrate_limit_reservoir_bias;
660.1149 +        }
660.1150 +      }
660.1151 +      return 0;
660.1152 +
660.1153 +    case OV_ECTL_LOWPASS_GET:
660.1154 +      {
660.1155 +        double *farg=(double *)arg;
660.1156 +        *farg=hi->lowpass_kHz;
660.1157 +      }
660.1158 +      return(0);
660.1159 +    case OV_ECTL_LOWPASS_SET:
660.1160 +      {
660.1161 +        double *farg=(double *)arg;
660.1162 +        hi->lowpass_kHz=*farg;
660.1163 +
660.1164 +        if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.;
660.1165 +        if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.;
660.1166 +        hi->lowpass_altered=1;
660.1167 +      }
660.1168 +      return(0);
660.1169 +    case OV_ECTL_IBLOCK_GET:
660.1170 +      {
660.1171 +        double *farg=(double *)arg;
660.1172 +        *farg=hi->impulse_noisetune;
660.1173 +      }
660.1174 +      return(0);
660.1175 +    case OV_ECTL_IBLOCK_SET:
660.1176 +      {
660.1177 +        double *farg=(double *)arg;
660.1178 +        hi->impulse_noisetune=*farg;
660.1179 +
660.1180 +        if(hi->impulse_noisetune>0.)hi->impulse_noisetune=0.;
660.1181 +        if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.;
660.1182 +      }
660.1183 +      return(0);
660.1184 +    case OV_ECTL_COUPLING_GET:
660.1185 +      {
660.1186 +        int *iarg=(int *)arg;
660.1187 +        *iarg=hi->coupling_p;
660.1188 +      }
660.1189 +      return(0);
660.1190 +    case OV_ECTL_COUPLING_SET:
660.1191 +      {
660.1192 +        const void *new_template;
660.1193 +        double new_base=0.;
660.1194 +        int *iarg=(int *)arg;
660.1195 +        hi->coupling_p=((*iarg)!=0);
660.1196 +
660.1197 +        /* Fetching a new template can alter the base_setting, which
660.1198 +           many other parameters are based on.  Right now, the only
660.1199 +           parameter drawn from the base_setting that can be altered
660.1200 +           by an encctl is the lowpass, so that is explictly flagged
660.1201 +           to not be overwritten when we fetch a new template and
660.1202 +           recompute the dependant settings */
660.1203 +        new_template = get_setup_template(hi->coupling_p?vi->channels:-1,
660.1204 +                                          vi->rate,
660.1205 +                                          hi->req,
660.1206 +                                          hi->managed,
660.1207 +                                          &new_base);
660.1208 +        if(!hi->setup)return OV_EIMPL;
660.1209 +        hi->setup=new_template;
660.1210 +        hi->base_setting=new_base;
660.1211 +        vorbis_encode_setup_setting(vi,vi->channels,vi->rate);
660.1212 +      }
660.1213 +      return(0);
660.1214 +    }
660.1215 +    return(OV_EIMPL);
660.1216 +  }
660.1217 +  return(OV_EINVAL);
660.1218 +}
   661.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   661.2 +++ b/libs/vorbis/vorbisenc.h	Sat Feb 01 19:58:19 2014 +0200
   661.3 @@ -0,0 +1,436 @@
   661.4 +/********************************************************************
   661.5 + *                                                                  *
   661.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   661.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   661.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   661.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  661.10 + *                                                                  *
  661.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
  661.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  661.13 + *                                                                  *
  661.14 + ********************************************************************
  661.15 +
  661.16 + function: vorbis encode-engine setup
  661.17 + last mod: $Id: vorbisenc.h 17021 2010-03-24 09:29:41Z xiphmont $
  661.18 +
  661.19 + ********************************************************************/
  661.20 +
  661.21 +/** \file
  661.22 + * Libvorbisenc is a convenient API for setting up an encoding
  661.23 + * environment using libvorbis. Libvorbisenc encapsulates the
  661.24 + * actions needed to set up the encoder properly.
  661.25 + */
  661.26 +
  661.27 +#ifndef _OV_ENC_H_
  661.28 +#define _OV_ENC_H_
  661.29 +
  661.30 +#ifdef __cplusplus
  661.31 +extern "C"
  661.32 +{
  661.33 +#endif /* __cplusplus */
  661.34 +
  661.35 +#include "codec.h"
  661.36 +
  661.37 +/**
  661.38 + * This is the primary function within libvorbisenc for setting up managed
  661.39 + * bitrate modes.
  661.40 + *
  661.41 + * Before this function is called, the \ref vorbis_info
  661.42 + * struct should be initialized by using vorbis_info_init() from the libvorbis
  661.43 + * API.  After encoding, vorbis_info_clear() should be called.
  661.44 + *
  661.45 + * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set
  661.46 + * constraints for the encoded file.  This function uses these settings to
  661.47 + * select the appropriate encoding mode and set it up.
  661.48 + *
  661.49 + * \param vi               Pointer to an initialized \ref vorbis_info struct.
  661.50 + * \param channels         The number of channels to be encoded.
  661.51 + * \param rate             The sampling rate of the source audio.
  661.52 + * \param max_bitrate      Desired maximum bitrate (limit). -1 indicates unset.
  661.53 + * \param nominal_bitrate  Desired average, or central, bitrate. -1 indicates unset.
  661.54 + * \param min_bitrate      Desired minimum bitrate. -1 indicates unset.
  661.55 + *
  661.56 + * \return Zero for success, and negative values for failure.
  661.57 + *
  661.58 + * \retval 0          Success.
  661.59 + * \retval OV_EFAULT  Internal logic fault; indicates a bug or heap/stack corruption.
  661.60 + * \retval OV_EINVAL  Invalid setup request, eg, out of range argument.
  661.61 + * \retval OV_EIMPL   Unimplemented mode; unable to comply with bitrate request.
  661.62 + */
  661.63 +extern int vorbis_encode_init(vorbis_info *vi,
  661.64 +                              long channels,
  661.65 +                              long rate,
  661.66 +
  661.67 +                              long max_bitrate,
  661.68 +                              long nominal_bitrate,
  661.69 +                              long min_bitrate);
  661.70 +
  661.71 +/**
  661.72 + * This function performs step-one of a three-step bitrate-managed encode
  661.73 + * setup.  It functions similarly to the one-step setup performed by \ref
  661.74 + * vorbis_encode_init but allows an application to make further encode setup
  661.75 + * tweaks using \ref vorbis_encode_ctl before finally calling \ref
  661.76 + * vorbis_encode_setup_init to complete the setup process.
  661.77 + *
  661.78 + * Before this function is called, the \ref vorbis_info struct should be
  661.79 + * initialized by using vorbis_info_init() from the libvorbis API.  After
  661.80 + * encoding, vorbis_info_clear() should be called.
  661.81 + *
  661.82 + * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set
  661.83 + * constraints for the encoded file.  This function uses these settings to
  661.84 + * select the appropriate encoding mode and set it up.
  661.85 + *
  661.86 + * \param vi                Pointer to an initialized vorbis_info struct.
  661.87 + * \param channels          The number of channels to be encoded.
  661.88 + * \param rate              The sampling rate of the source audio.
  661.89 + * \param max_bitrate       Desired maximum bitrate (limit). -1 indicates unset.
  661.90 + * \param nominal_bitrate   Desired average, or central, bitrate. -1 indicates unset.
  661.91 + * \param min_bitrate       Desired minimum bitrate. -1 indicates unset.
  661.92 + *
  661.93 + * \return Zero for success, and negative for failure.
  661.94 + *
  661.95 + * \retval 0           Success
  661.96 + * \retval OV_EFAULT   Internal logic fault; indicates a bug or heap/stack corruption.
  661.97 + * \retval OV_EINVAL   Invalid setup request, eg, out of range argument.
  661.98 + * \retval OV_EIMPL    Unimplemented mode; unable to comply with bitrate request.
  661.99 + */
 661.100 +extern int vorbis_encode_setup_managed(vorbis_info *vi,
 661.101 +                                       long channels,
 661.102 +                                       long rate,
 661.103 +
 661.104 +                                       long max_bitrate,
 661.105 +                                       long nominal_bitrate,
 661.106 +                                       long min_bitrate);
 661.107 +
 661.108 +/**
 661.109 + * This function performs step-one of a three-step variable bitrate
 661.110 + * (quality-based) encode setup.  It functions similarly to the one-step setup
 661.111 + * performed by \ref vorbis_encode_init_vbr() but allows an application to
 661.112 + * make further encode setup tweaks using \ref vorbis_encode_ctl() before
 661.113 + * finally calling \ref vorbis_encode_setup_init to complete the setup
 661.114 + * process.
 661.115 + *
 661.116 + * Before this function is called, the \ref vorbis_info struct should be
 661.117 + * initialized by using \ref vorbis_info_init() from the libvorbis API.  After
 661.118 + * encoding, vorbis_info_clear() should be called.
 661.119 + *
 661.120 + * \param vi        Pointer to an initialized vorbis_info struct.
 661.121 + * \param channels  The number of channels to be encoded.
 661.122 + * \param rate      The sampling rate of the source audio.
 661.123 + * \param quality   Desired quality level, currently from -0.1 to 1.0 (lo to hi).
 661.124 + *
 661.125 + * \return Zero for success, and negative values for failure.
 661.126 + *
 661.127 + * \retval  0          Success
 661.128 + * \retval  OV_EFAULT  Internal logic fault; indicates a bug or heap/stack corruption.
 661.129 + * \retval  OV_EINVAL  Invalid setup request, eg, out of range argument.
 661.130 + * \retval  OV_EIMPL   Unimplemented mode; unable to comply with quality level request.
 661.131 + */
 661.132 +extern int vorbis_encode_setup_vbr(vorbis_info *vi,
 661.133 +                                  long channels,
 661.134 +                                  long rate,
 661.135 +
 661.136 +                                  float quality
 661.137 +                                  );
 661.138 +
 661.139 +/**
 661.140 + * This is the primary function within libvorbisenc for setting up variable
 661.141 + * bitrate ("quality" based) modes.
 661.142 + *
 661.143 + *
 661.144 + * Before this function is called, the vorbis_info struct should be
 661.145 + * initialized by using vorbis_info_init() from the libvorbis API. After
 661.146 + * encoding, vorbis_info_clear() should be called.
 661.147 + *
 661.148 + * \param vi           Pointer to an initialized vorbis_info struct.
 661.149 + * \param channels     The number of channels to be encoded.
 661.150 + * \param rate         The sampling rate of the source audio.
 661.151 + * \param base_quality Desired quality level, currently from -0.1 to 1.0 (lo to hi).
 661.152 + *
 661.153 + *
 661.154 + * \return Zero for success, or a negative number for failure.
 661.155 + *
 661.156 + * \retval 0           Success
 661.157 + * \retval OV_EFAULT   Internal logic fault; indicates a bug or heap/stack corruption.
 661.158 + * \retval OV_EINVAL   Invalid setup request, eg, out of range argument.
 661.159 + * \retval OV_EIMPL    Unimplemented mode; unable to comply with quality level request.
 661.160 + */
 661.161 +extern int vorbis_encode_init_vbr(vorbis_info *vi,
 661.162 +                                  long channels,
 661.163 +                                  long rate,
 661.164 +
 661.165 +                                  float base_quality
 661.166 +                                  );
 661.167 +
 661.168 +/**
 661.169 + * This function performs the last stage of three-step encoding setup, as
 661.170 + * described in the API overview under managed bitrate modes.
 661.171 + *
 661.172 + * Before this function is called, the \ref vorbis_info struct should be
 661.173 + * initialized by using vorbis_info_init() from the libvorbis API, one of
 661.174 + * \ref vorbis_encode_setup_managed() or \ref vorbis_encode_setup_vbr() called to
 661.175 + * initialize the high-level encoding setup, and \ref vorbis_encode_ctl()
 661.176 + * called if necessary to make encoding setup changes.
 661.177 + * vorbis_encode_setup_init() finalizes the highlevel encoding structure into
 661.178 + * a complete encoding setup after which the application may make no further
 661.179 + * setup changes.
 661.180 + *
 661.181 + * After encoding, vorbis_info_clear() should be called.
 661.182 + *
 661.183 + * \param vi Pointer to an initialized \ref vorbis_info struct.
 661.184 + *
 661.185 + * \return Zero for success, and negative values for failure.
 661.186 + *
 661.187 + * \retval  0           Success.
 661.188 + * \retval  OV_EFAULT  Internal logic fault; indicates a bug or heap/stack corruption.
 661.189 + *
 661.190 + * \retval OV_EINVAL   Attempt to use vorbis_encode_setup_init() without first
 661.191 + * calling one of vorbis_encode_setup_managed() or vorbis_encode_setup_vbr() to
 661.192 + * initialize the high-level encoding setup
 661.193 + *
 661.194 + */
 661.195 +extern int vorbis_encode_setup_init(vorbis_info *vi);
 661.196 +
 661.197 +/**
 661.198 + * This function implements a generic interface to miscellaneous encoder
 661.199 + * settings similar to the classic UNIX 'ioctl()' system call.  Applications
 661.200 + * may use vorbis_encode_ctl() to query or set bitrate management or quality
 661.201 + * mode details by using one of several \e request arguments detailed below.
 661.202 + * vorbis_encode_ctl() must be called after one of
 661.203 + * vorbis_encode_setup_managed() or vorbis_encode_setup_vbr().  When used
 661.204 + * to modify settings, \ref vorbis_encode_ctl() must be called before \ref
 661.205 + * vorbis_encode_setup_init().
 661.206 + *
 661.207 + * \param vi      Pointer to an initialized vorbis_info struct.
 661.208 + *
 661.209 + * \param number Specifies the desired action; See \ref encctlcodes "the list
 661.210 + * of available requests".
 661.211 + *
 661.212 + * \param arg void * pointing to a data structure matching the request
 661.213 + * argument.
 661.214 + *
 661.215 + * \retval 0          Success. Any further return information (such as the result of a
 661.216 + * query) is placed into the storage pointed to by *arg.
 661.217 + *
 661.218 + * \retval OV_EINVAL  Invalid argument, or an attempt to modify a setting after
 661.219 + * calling vorbis_encode_setup_init().
 661.220 + *
 661.221 + * \retval OV_EIMPL   Unimplemented or unknown request
 661.222 + */
 661.223 +extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg);
 661.224 +
 661.225 +/**
 661.226 + * \deprecated This is a deprecated interface. Please use vorbis_encode_ctl()
 661.227 + * with the \ref ovectl_ratemanage2_arg struct and \ref
 661.228 + * OV_ECTL_RATEMANAGE2_GET and \ref OV_ECTL_RATEMANAGE2_SET calls in new code.
 661.229 + *
 661.230 + * The \ref ovectl_ratemanage_arg structure is used with vorbis_encode_ctl()
 661.231 + * and the \ref OV_ECTL_RATEMANAGE_GET, \ref OV_ECTL_RATEMANAGE_SET, \ref
 661.232 + * OV_ECTL_RATEMANAGE_AVG, \ref OV_ECTL_RATEMANAGE_HARD calls in order to
 661.233 + * query and modify specifics of the encoder's bitrate management
 661.234 + * configuration.
 661.235 +*/
 661.236 +struct ovectl_ratemanage_arg {
 661.237 +  int    management_active; /**< nonzero if bitrate management is active*/
 661.238 +/** hard lower limit (in kilobits per second) below which the stream bitrate
 661.239 +    will never be allowed for any given bitrate_hard_window seconds of time.*/
 661.240 +  long   bitrate_hard_min;
 661.241 +/** hard upper limit (in kilobits per second) above which the stream bitrate
 661.242 +    will never be allowed for any given bitrate_hard_window seconds of time.*/
 661.243 +  long   bitrate_hard_max;
 661.244 +/** the window period (in seconds) used to regulate the hard bitrate minimum
 661.245 +    and maximum*/
 661.246 +  double bitrate_hard_window;
 661.247 +/** soft lower limit (in kilobits per second) below which the average bitrate
 661.248 +    tracker will start nudging the bitrate higher.*/
 661.249 +  long   bitrate_av_lo;
 661.250 +/** soft upper limit (in kilobits per second) above which the average bitrate
 661.251 +    tracker will start nudging the bitrate lower.*/
 661.252 +  long   bitrate_av_hi;
 661.253 +/** the window period (in seconds) used to regulate the average bitrate
 661.254 +    minimum and maximum.*/
 661.255 +  double bitrate_av_window;
 661.256 +/** Regulates the relative centering of the average and hard windows; in
 661.257 +    libvorbis 1.0 and 1.0.1, the hard window regulation overlapped but
 661.258 +    followed the average window regulation. In libvorbis 1.1 a bit-reservoir
 661.259 +    interface replaces the old windowing interface; the older windowing
 661.260 +    interface is simulated and this field has no effect.*/
 661.261 +  double bitrate_av_window_center;
 661.262 +};
 661.263 +
 661.264 +/**
 661.265 + * \name struct ovectl_ratemanage2_arg
 661.266 + *
 661.267 + * The ovectl_ratemanage2_arg structure is used with vorbis_encode_ctl() and
 661.268 + * the OV_ECTL_RATEMANAGE2_GET and OV_ECTL_RATEMANAGE2_SET calls in order to
 661.269 + * query and modify specifics of the encoder's bitrate management
 661.270 + * configuration.
 661.271 + *
 661.272 +*/
 661.273 +struct ovectl_ratemanage2_arg {
 661.274 +  int    management_active; /**< nonzero if bitrate management is active */
 661.275 +/** Lower allowed bitrate limit in kilobits per second */
 661.276 +  long   bitrate_limit_min_kbps;
 661.277 +/** Upper allowed bitrate limit in kilobits per second */
 661.278 +  long   bitrate_limit_max_kbps;
 661.279 +  long   bitrate_limit_reservoir_bits; /**<Size of the bitrate reservoir in bits */
 661.280 +/** Regulates the bitrate reservoir's preferred fill level in a range from 0.0
 661.281 + * to 1.0; 0.0 tries to bank bits to buffer against future bitrate spikes, 1.0
 661.282 + * buffers against future sudden drops in instantaneous bitrate. Default is
 661.283 + * 0.1
 661.284 + */
 661.285 +  double bitrate_limit_reservoir_bias;
 661.286 +/** Average bitrate setting in kilobits per second */
 661.287 +  long   bitrate_average_kbps;
 661.288 +/** Slew rate limit setting for average bitrate adjustment; sets the minimum
 661.289 + *  time in seconds the bitrate tracker may swing from one extreme to the
 661.290 + *  other when boosting or damping average bitrate.
 661.291 + */
 661.292 +  double bitrate_average_damping;
 661.293 +};
 661.294 +
 661.295 +
 661.296 +/**
 661.297 + * \name vorbis_encode_ctl() codes
 661.298 + *
 661.299 + * \anchor encctlcodes
 661.300 + *
 661.301 + * These values are passed as the \c number parameter of vorbis_encode_ctl().
 661.302 + * The type of the referent of that function's \c arg pointer depends on these
 661.303 + * codes.
 661.304 + */
 661.305 +/*@{*/
 661.306 +
 661.307 +/**
 661.308 + * Query the current encoder bitrate management setting.
 661.309 + *
 661.310 + *Argument: <tt>struct ovectl_ratemanage2_arg *</tt>
 661.311 + *
 661.312 + * Used to query the current encoder bitrate management setting. Also used to
 661.313 + * initialize fields of an ovectl_ratemanage2_arg structure for use with
 661.314 + * \ref OV_ECTL_RATEMANAGE2_SET.
 661.315 + */
 661.316 +#define OV_ECTL_RATEMANAGE2_GET      0x14
 661.317 +
 661.318 +/**
 661.319 + * Set the current encoder bitrate management settings.
 661.320 + *
 661.321 + * Argument: <tt>struct ovectl_ratemanage2_arg *</tt>
 661.322 + *
 661.323 + * Used to set the current encoder bitrate management settings to the values
 661.324 + * listed in the ovectl_ratemanage2_arg. Passing a NULL pointer will disable
 661.325 + * bitrate management.
 661.326 +*/
 661.327 +#define OV_ECTL_RATEMANAGE2_SET      0x15
 661.328 +
 661.329 +/**
 661.330 + * Returns the current encoder hard-lowpass setting (kHz) in the double
 661.331 + * pointed to by arg.
 661.332 + *
 661.333 + * Argument: <tt>double *</tt>
 661.334 +*/
 661.335 +#define OV_ECTL_LOWPASS_GET          0x20
 661.336 +
 661.337 +/**
 661.338 + *  Sets the encoder hard-lowpass to the value (kHz) pointed to by arg. Valid
 661.339 + *  lowpass settings range from 2 to 99.
 661.340 + *
 661.341 + * Argument: <tt>double *</tt>
 661.342 +*/
 661.343 +#define OV_ECTL_LOWPASS_SET          0x21
 661.344 +
 661.345 +/**
 661.346 + *  Returns the current encoder impulse block setting in the double pointed
 661.347 + *  to by arg.
 661.348 + *
 661.349 + * Argument: <tt>double *</tt>
 661.350 +*/
 661.351 +#define OV_ECTL_IBLOCK_GET           0x30
 661.352 +
 661.353 +/**
 661.354 + *  Sets the impulse block bias to the the value pointed to by arg.
 661.355 + *
 661.356 + * Argument: <tt>double *</tt>
 661.357 + *
 661.358 + *  Valid range is -15.0 to 0.0 [default]. A negative impulse block bias will
 661.359 + *  direct to encoder to use more bits when incoding short blocks that contain
 661.360 + *  strong impulses, thus improving the accuracy of impulse encoding.
 661.361 + */
 661.362 +#define OV_ECTL_IBLOCK_SET           0x31
 661.363 +
 661.364 +/**
 661.365 + *  Returns the current encoder coupling setting in the int pointed
 661.366 + *  to by arg.
 661.367 + *
 661.368 + * Argument: <tt>int *</tt>
 661.369 +*/
 661.370 +#define OV_ECTL_COUPLING_GET         0x40
 661.371 +
 661.372 +/**
 661.373 + *  Enables/disables channel coupling in multichannel encoding according to arg.
 661.374 + *
 661.375 + * Argument: <tt>int *</tt>
 661.376 + *
 661.377 + *  Zero disables channel coupling for multichannel inputs, nonzer enables
 661.378 + *  channel coupling.  Setting has no effect on monophonic encoding or
 661.379 + *  multichannel counts that do not offer coupling.  At present, coupling is
 661.380 + *  available for stereo and 5.1 encoding.
 661.381 + */
 661.382 +#define OV_ECTL_COUPLING_SET         0x41
 661.383 +
 661.384 +  /* deprecated rate management supported only for compatibility */
 661.385 +
 661.386 +/**
 661.387 + * Old interface to querying bitrate management settings.
 661.388 + *
 661.389 + * Deprecated after move to bit-reservoir style management in 1.1 rendered
 661.390 + * this interface partially obsolete.
 661.391 +
 661.392 + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_GET instead.
 661.393 + *
 661.394 + * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
 661.395 + */
 661.396 +#define OV_ECTL_RATEMANAGE_GET       0x10
 661.397 +/**
 661.398 + * Old interface to modifying bitrate management settings.
 661.399 + *
 661.400 + *  deprecated after move to bit-reservoir style management in 1.1 rendered
 661.401 + *  this interface partially obsolete.
 661.402 + *
 661.403 + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
 661.404 + *
 661.405 + * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
 661.406 + */
 661.407 +#define OV_ECTL_RATEMANAGE_SET       0x11
 661.408 +/**
 661.409 + * Old interface to setting average-bitrate encoding mode.
 661.410 + *
 661.411 + * Deprecated after move to bit-reservoir style management in 1.1 rendered
 661.412 + * this interface partially obsolete.
 661.413 + *
 661.414 + *  \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
 661.415 + *
 661.416 + * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
 661.417 + */
 661.418 +#define OV_ECTL_RATEMANAGE_AVG       0x12
 661.419 +/**
 661.420 + * Old interface to setting bounded-bitrate encoding modes.
 661.421 + *
 661.422 + * deprecated after move to bit-reservoir style management in 1.1 rendered
 661.423 + * this interface partially obsolete.
 661.424 + *
 661.425 + *  \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
 661.426 + *
 661.427 + * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
 661.428 + */
 661.429 +#define OV_ECTL_RATEMANAGE_HARD      0x13
 661.430 +
 661.431 +/*@}*/
 661.432 +
 661.433 +
 661.434 +
 661.435 +#ifdef __cplusplus
 661.436 +}
 661.437 +#endif /* __cplusplus */
 661.438 +
 661.439 +#endif
   662.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   662.2 +++ b/libs/vorbis/vorbisfile.c	Sat Feb 01 19:58:19 2014 +0200
   662.3 @@ -0,0 +1,2337 @@
   662.4 +/********************************************************************
   662.5 + *                                                                  *
   662.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   662.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   662.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   662.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  662.10 + *                                                                  *
  662.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  662.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  662.13 + *                                                                  *
  662.14 + ********************************************************************
  662.15 +
  662.16 + function: stdio-based convenience library for opening/seeking/decoding
  662.17 + last mod: $Id: vorbisfile.c 17573 2010-10-27 14:53:59Z xiphmont $
  662.18 +
  662.19 + ********************************************************************/
  662.20 +
  662.21 +#include <stdlib.h>
  662.22 +#include <stdio.h>
  662.23 +#include <errno.h>
  662.24 +#include <string.h>
  662.25 +#include <math.h>
  662.26 +
  662.27 +#include "vorbis/codec.h"
  662.28 +
  662.29 +/* we don't need or want the static callback symbols here */
  662.30 +#define OV_EXCLUDE_STATIC_CALLBACKS
  662.31 +#include "vorbis/vorbisfile.h"
  662.32 +
  662.33 +#include "os.h"
  662.34 +#include "misc.h"
  662.35 +
  662.36 +/* A 'chained bitstream' is a Vorbis bitstream that contains more than
  662.37 +   one logical bitstream arranged end to end (the only form of Ogg
  662.38 +   multiplexing allowed in a Vorbis bitstream; grouping [parallel
  662.39 +   multiplexing] is not allowed in Vorbis) */
  662.40 +
  662.41 +/* A Vorbis file can be played beginning to end (streamed) without
  662.42 +   worrying ahead of time about chaining (see decoder_example.c).  If
  662.43 +   we have the whole file, however, and want random access
  662.44 +   (seeking/scrubbing) or desire to know the total length/time of a
  662.45 +   file, we need to account for the possibility of chaining. */
  662.46 +
  662.47 +/* We can handle things a number of ways; we can determine the entire
  662.48 +   bitstream structure right off the bat, or find pieces on demand.
  662.49 +   This example determines and caches structure for the entire
  662.50 +   bitstream, but builds a virtual decoder on the fly when moving
  662.51 +   between links in the chain. */
  662.52 +
  662.53 +/* There are also different ways to implement seeking.  Enough
  662.54 +   information exists in an Ogg bitstream to seek to
  662.55 +   sample-granularity positions in the output.  Or, one can seek by
  662.56 +   picking some portion of the stream roughly in the desired area if
  662.57 +   we only want coarse navigation through the stream. */
  662.58 +
  662.59 +/*************************************************************************
  662.60 + * Many, many internal helpers.  The intention is not to be confusing;
  662.61 + * rampant duplication and monolithic function implementation would be
  662.62 + * harder to understand anyway.  The high level functions are last.  Begin
  662.63 + * grokking near the end of the file */
  662.64 +
  662.65 +/* read a little more data from the file/pipe into the ogg_sync framer
  662.66 +*/
  662.67 +#define CHUNKSIZE 65536 /* greater-than-page-size granularity seeking */
  662.68 +#define READSIZE 2048 /* a smaller read size is needed for low-rate streaming. */
  662.69 +
  662.70 +static long _get_data(OggVorbis_File *vf){
  662.71 +  errno=0;
  662.72 +  if(!(vf->callbacks.read_func))return(-1);
  662.73 +  if(vf->datasource){
  662.74 +    char *buffer=ogg_sync_buffer(&vf->oy,READSIZE);
  662.75 +    long bytes=(vf->callbacks.read_func)(buffer,1,READSIZE,vf->datasource);
  662.76 +    if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
  662.77 +    if(bytes==0 && errno)return(-1);
  662.78 +    return(bytes);
  662.79 +  }else
  662.80 +    return(0);
  662.81 +}
  662.82 +
  662.83 +/* save a tiny smidge of verbosity to make the code more readable */
  662.84 +static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
  662.85 +  if(vf->datasource){
  662.86 +    if(!(vf->callbacks.seek_func)||
  662.87 +       (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
  662.88 +      return OV_EREAD;
  662.89 +    vf->offset=offset;
  662.90 +    ogg_sync_reset(&vf->oy);
  662.91 +  }else{
  662.92 +    /* shouldn't happen unless someone writes a broken callback */
  662.93 +    return OV_EFAULT;
  662.94 +  }
  662.95 +  return 0;
  662.96 +}
  662.97 +
  662.98 +/* The read/seek functions track absolute position within the stream */
  662.99 +
 662.100 +/* from the head of the stream, get the next page.  boundary specifies
 662.101 +   if the function is allowed to fetch more data from the stream (and
 662.102 +   how much) or only use internally buffered data.
 662.103 +
 662.104 +   boundary: -1) unbounded search
 662.105 +              0) read no additional data; use cached only
 662.106 +              n) search for a new page beginning for n bytes
 662.107 +
 662.108 +   return:   <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
 662.109 +              n) found a page at absolute offset n */
 662.110 +
 662.111 +static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
 662.112 +                                  ogg_int64_t boundary){
 662.113 +  if(boundary>0)boundary+=vf->offset;
 662.114 +  while(1){
 662.115 +    long more;
 662.116 +
 662.117 +    if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
 662.118 +    more=ogg_sync_pageseek(&vf->oy,og);
 662.119 +
 662.120 +    if(more<0){
 662.121 +      /* skipped n bytes */
 662.122 +      vf->offset-=more;
 662.123 +    }else{
 662.124 +      if(more==0){
 662.125 +        /* send more paramedics */
 662.126 +        if(!boundary)return(OV_FALSE);
 662.127 +        {
 662.128 +          long ret=_get_data(vf);
 662.129 +          if(ret==0)return(OV_EOF);
 662.130 +          if(ret<0)return(OV_EREAD);
 662.131 +        }
 662.132 +      }else{
 662.133 +        /* got a page.  Return the offset at the page beginning,
 662.134 +           advance the internal offset past the page end */
 662.135 +        ogg_int64_t ret=vf->offset;
 662.136 +        vf->offset+=more;
 662.137 +        return(ret);
 662.138 +
 662.139 +      }
 662.140 +    }
 662.141 +  }
 662.142 +}
 662.143 +
 662.144 +/* find the latest page beginning before the current stream cursor
 662.145 +   position. Much dirtier than the above as Ogg doesn't have any
 662.146 +   backward search linkage.  no 'readp' as it will certainly have to
 662.147 +   read. */
 662.148 +/* returns offset or OV_EREAD, OV_FAULT */
 662.149 +static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
 662.150 +  ogg_int64_t begin=vf->offset;
 662.151 +  ogg_int64_t end=begin;
 662.152 +  ogg_int64_t ret;
 662.153 +  ogg_int64_t offset=-1;
 662.154 +
 662.155 +  while(offset==-1){
 662.156 +    begin-=CHUNKSIZE;
 662.157 +    if(begin<0)
 662.158 +      begin=0;
 662.159 +
 662.160 +    ret=_seek_helper(vf,begin);
 662.161 +    if(ret)return(ret);
 662.162 +
 662.163 +    while(vf->offset<end){
 662.164 +      memset(og,0,sizeof(*og));
 662.165 +      ret=_get_next_page(vf,og,end-vf->offset);
 662.166 +      if(ret==OV_EREAD)return(OV_EREAD);
 662.167 +      if(ret<0){
 662.168 +        break;
 662.169 +      }else{
 662.170 +        offset=ret;
 662.171 +      }
 662.172 +    }
 662.173 +  }
 662.174 +
 662.175 +  /* In a fully compliant, non-multiplexed stream, we'll still be
 662.176 +     holding the last page.  In multiplexed (or noncompliant streams),
 662.177 +     we will probably have to re-read the last page we saw */
 662.178 +  if(og->header_len==0){
 662.179 +    ret=_seek_helper(vf,offset);
 662.180 +    if(ret)return(ret);
 662.181 +
 662.182 +    ret=_get_next_page(vf,og,CHUNKSIZE);
 662.183 +    if(ret<0)
 662.184 +      /* this shouldn't be possible */
 662.185 +      return(OV_EFAULT);
 662.186 +  }
 662.187 +
 662.188 +  return(offset);
 662.189 +}
 662.190 +
 662.191 +static void _add_serialno(ogg_page *og,long **serialno_list, int *n){
 662.192 +  long s = ogg_page_serialno(og);
 662.193 +  (*n)++;
 662.194 +
 662.195 +  if(*serialno_list){
 662.196 +    *serialno_list = _ogg_realloc(*serialno_list, sizeof(**serialno_list)*(*n));
 662.197 +  }else{
 662.198 +    *serialno_list = _ogg_malloc(sizeof(**serialno_list));
 662.199 +  }
 662.200 +
 662.201 +  (*serialno_list)[(*n)-1] = s;
 662.202 +}
 662.203 +
 662.204 +/* returns nonzero if found */
 662.205 +static int _lookup_serialno(long s, long *serialno_list, int n){
 662.206 +  if(serialno_list){
 662.207 +    while(n--){
 662.208 +      if(*serialno_list == s) return 1;
 662.209 +      serialno_list++;
 662.210 +    }
 662.211 +  }
 662.212 +  return 0;
 662.213 +}
 662.214 +
 662.215 +static int _lookup_page_serialno(ogg_page *og, long *serialno_list, int n){
 662.216 +  long s = ogg_page_serialno(og);
 662.217 +  return _lookup_serialno(s,serialno_list,n);
 662.218 +}
 662.219 +
 662.220 +/* performs the same search as _get_prev_page, but prefers pages of
 662.221 +   the specified serial number. If a page of the specified serialno is
 662.222 +   spotted during the seek-back-and-read-forward, it will return the
 662.223 +   info of last page of the matching serial number instead of the very
 662.224 +   last page.  If no page of the specified serialno is seen, it will
 662.225 +   return the info of last page and alter *serialno.  */
 662.226 +static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf,
 662.227 +                                         long *serial_list, int serial_n,
 662.228 +                                         int *serialno, ogg_int64_t *granpos){
 662.229 +  ogg_page og;
 662.230 +  ogg_int64_t begin=vf->offset;
 662.231 +  ogg_int64_t end=begin;
 662.232 +  ogg_int64_t ret;
 662.233 +
 662.234 +  ogg_int64_t prefoffset=-1;
 662.235 +  ogg_int64_t offset=-1;
 662.236 +  ogg_int64_t ret_serialno=-1;
 662.237 +  ogg_int64_t ret_gran=-1;
 662.238 +
 662.239 +  while(offset==-1){
 662.240 +    begin-=CHUNKSIZE;
 662.241 +    if(begin<0)
 662.242 +      begin=0;
 662.243 +
 662.244 +    ret=_seek_helper(vf,begin);
 662.245 +    if(ret)return(ret);
 662.246 +
 662.247 +    while(vf->offset<end){
 662.248 +      ret=_get_next_page(vf,&og,end-vf->offset);
 662.249 +      if(ret==OV_EREAD)return(OV_EREAD);
 662.250 +      if(ret<0){
 662.251 +        break;
 662.252 +      }else{
 662.253 +        ret_serialno=ogg_page_serialno(&og);
 662.254 +        ret_gran=ogg_page_granulepos(&og);
 662.255 +        offset=ret;
 662.256 +
 662.257 +        if(ret_serialno == *serialno){
 662.258 +          prefoffset=ret;
 662.259 +          *granpos=ret_gran;
 662.260 +        }
 662.261 +
 662.262 +        if(!_lookup_serialno(ret_serialno,serial_list,serial_n)){
 662.263 +          /* we fell off the end of the link, which means we seeked
 662.264 +             back too far and shouldn't have been looking in that link
 662.265 +             to begin with.  If we found the preferred serial number,
 662.266 +             forget that we saw it. */
 662.267 +          prefoffset=-1;
 662.268 +        }
 662.269 +      }
 662.270 +    }
 662.271 +  }
 662.272 +
 662.273 +  /* we're not interested in the page... just the serialno and granpos. */
 662.274 +  if(prefoffset>=0)return(prefoffset);
 662.275 +
 662.276 +  *serialno = ret_serialno;
 662.277 +  *granpos = ret_gran;
 662.278 +  return(offset);
 662.279 +
 662.280 +}
 662.281 +
 662.282 +/* uses the local ogg_stream storage in vf; this is important for
 662.283 +   non-streaming input sources */
 662.284 +static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
 662.285 +                          long **serialno_list, int *serialno_n,
 662.286 +                          ogg_page *og_ptr){
 662.287 +  ogg_page og;
 662.288 +  ogg_packet op;
 662.289 +  int i,ret;
 662.290 +  int allbos=0;
 662.291 +
 662.292 +  if(!og_ptr){
 662.293 +    ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
 662.294 +    if(llret==OV_EREAD)return(OV_EREAD);
 662.295 +    if(llret<0)return(OV_ENOTVORBIS);
 662.296 +    og_ptr=&og;
 662.297 +  }
 662.298 +
 662.299 +  vorbis_info_init(vi);
 662.300 +  vorbis_comment_init(vc);
 662.301 +  vf->ready_state=OPENED;
 662.302 +
 662.303 +  /* extract the serialnos of all BOS pages + the first set of vorbis
 662.304 +     headers we see in the link */
 662.305 +
 662.306 +  while(ogg_page_bos(og_ptr)){
 662.307 +    if(serialno_list){
 662.308 +      if(_lookup_page_serialno(og_ptr,*serialno_list,*serialno_n)){
 662.309 +        /* a dupe serialnumber in an initial header packet set == invalid stream */
 662.310 +        if(*serialno_list)_ogg_free(*serialno_list);
 662.311 +        *serialno_list=0;
 662.312 +        *serialno_n=0;
 662.313 +        ret=OV_EBADHEADER;
 662.314 +        goto bail_header;
 662.315 +      }
 662.316 +
 662.317 +      _add_serialno(og_ptr,serialno_list,serialno_n);
 662.318 +    }
 662.319 +
 662.320 +    if(vf->ready_state<STREAMSET){
 662.321 +      /* we don't have a vorbis stream in this link yet, so begin
 662.322 +         prospective stream setup. We need a stream to get packets */
 662.323 +      ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
 662.324 +      ogg_stream_pagein(&vf->os,og_ptr);
 662.325 +
 662.326 +      if(ogg_stream_packetout(&vf->os,&op) > 0 &&
 662.327 +         vorbis_synthesis_idheader(&op)){
 662.328 +        /* vorbis header; continue setup */
 662.329 +        vf->ready_state=STREAMSET;
 662.330 +        if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
 662.331 +          ret=OV_EBADHEADER;
 662.332 +          goto bail_header;
 662.333 +        }
 662.334 +      }
 662.335 +    }
 662.336 +
 662.337 +    /* get next page */
 662.338 +    {
 662.339 +      ogg_int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE);
 662.340 +      if(llret==OV_EREAD){
 662.341 +        ret=OV_EREAD;
 662.342 +        goto bail_header;
 662.343 +      }
 662.344 +      if(llret<0){
 662.345 +        ret=OV_ENOTVORBIS;
 662.346 +        goto bail_header;
 662.347 +      }
 662.348 +
 662.349 +      /* if this page also belongs to our vorbis stream, submit it and break */
 662.350 +      if(vf->ready_state==STREAMSET &&
 662.351 +         vf->os.serialno == ogg_page_serialno(og_ptr)){
 662.352 +        ogg_stream_pagein(&vf->os,og_ptr);
 662.353 +        break;
 662.354 +      }
 662.355 +    }
 662.356 +  }
 662.357 +
 662.358 +  if(vf->ready_state!=STREAMSET){
 662.359 +    ret = OV_ENOTVORBIS;
 662.360 +    goto bail_header;
 662.361 +  }
 662.362 +
 662.363 +  while(1){
 662.364 +
 662.365 +    i=0;
 662.366 +    while(i<2){ /* get a page loop */
 662.367 +
 662.368 +      while(i<2){ /* get a packet loop */
 662.369 +
 662.370 +        int result=ogg_stream_packetout(&vf->os,&op);
 662.371 +        if(result==0)break;
 662.372 +        if(result==-1){
 662.373 +          ret=OV_EBADHEADER;
 662.374 +          goto bail_header;
 662.375 +        }
 662.376 +
 662.377 +        if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
 662.378 +          goto bail_header;
 662.379 +
 662.380 +        i++;
 662.381 +      }
 662.382 +
 662.383 +      while(i<2){
 662.384 +        if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
 662.385 +          ret=OV_EBADHEADER;
 662.386 +          goto bail_header;
 662.387 +        }
 662.388 +
 662.389 +        /* if this page belongs to the correct stream, go parse it */
 662.390 +        if(vf->os.serialno == ogg_page_serialno(og_ptr)){
 662.391 +          ogg_stream_pagein(&vf->os,og_ptr);
 662.392 +          break;
 662.393 +        }
 662.394 +
 662.395 +        /* if we never see the final vorbis headers before the link
 662.396 +           ends, abort */
 662.397 +        if(ogg_page_bos(og_ptr)){
 662.398 +          if(allbos){
 662.399 +            ret = OV_EBADHEADER;
 662.400 +            goto bail_header;
 662.401 +          }else
 662.402 +            allbos=1;
 662.403 +        }
 662.404 +
 662.405 +        /* otherwise, keep looking */
 662.406 +      }
 662.407 +    }
 662.408 +
 662.409 +    return 0;
 662.410 +  }
 662.411 +
 662.412 + bail_header:
 662.413 +  vorbis_info_clear(vi);
 662.414 +  vorbis_comment_clear(vc);
 662.415 +  vf->ready_state=OPENED;
 662.416 +
 662.417 +  return ret;
 662.418 +}
 662.419 +
 662.420 +/* Starting from current cursor position, get initial PCM offset of
 662.421 +   next page.  Consumes the page in the process without decoding
 662.422 +   audio, however this is only called during stream parsing upon
 662.423 +   seekable open. */
 662.424 +static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
 662.425 +  ogg_page    og;
 662.426 +  ogg_int64_t accumulated=0;
 662.427 +  long        lastblock=-1;
 662.428 +  int         result;
 662.429 +  int         serialno = vf->os.serialno;
 662.430 +
 662.431 +  while(1){
 662.432 +    ogg_packet op;
 662.433 +    if(_get_next_page(vf,&og,-1)<0)
 662.434 +      break; /* should not be possible unless the file is truncated/mangled */
 662.435 +
 662.436 +    if(ogg_page_bos(&og)) break;
 662.437 +    if(ogg_page_serialno(&og)!=serialno) continue;
 662.438 +
 662.439 +    /* count blocksizes of all frames in the page */
 662.440 +    ogg_stream_pagein(&vf->os,&og);
 662.441 +    while((result=ogg_stream_packetout(&vf->os,&op))){
 662.442 +      if(result>0){ /* ignore holes */
 662.443 +        long thisblock=vorbis_packet_blocksize(vi,&op);
 662.444 +        if(lastblock!=-1)
 662.445 +          accumulated+=(lastblock+thisblock)>>2;
 662.446 +        lastblock=thisblock;
 662.447 +      }
 662.448 +    }
 662.449 +
 662.450 +    if(ogg_page_granulepos(&og)!=-1){
 662.451 +      /* pcm offset of last packet on the first audio page */
 662.452 +      accumulated= ogg_page_granulepos(&og)-accumulated;
 662.453 +      break;
 662.454 +    }
 662.455 +  }
 662.456 +
 662.457 +  /* less than zero?  Either a corrupt file or a stream with samples
 662.458 +     trimmed off the beginning, a normal occurrence; in both cases set
 662.459 +     the offset to zero */
 662.460 +  if(accumulated<0)accumulated=0;
 662.461 +
 662.462 +  return accumulated;
 662.463 +}
 662.464 +
 662.465 +/* finds each bitstream link one at a time using a bisection search
 662.466 +   (has to begin by knowing the offset of the lb's initial page).
 662.467 +   Recurses for each link so it can alloc the link storage after
 662.468 +   finding them all, then unroll and fill the cache at the same time */
 662.469 +static int _bisect_forward_serialno(OggVorbis_File *vf,
 662.470 +                                    ogg_int64_t begin,
 662.471 +                                    ogg_int64_t searched,
 662.472 +                                    ogg_int64_t end,
 662.473 +                                    ogg_int64_t endgran,
 662.474 +                                    int endserial,
 662.475 +                                    long *currentno_list,
 662.476 +                                    int  currentnos,
 662.477 +                                    long m){
 662.478 +  ogg_int64_t pcmoffset;
 662.479 +  ogg_int64_t dataoffset=searched;
 662.480 +  ogg_int64_t endsearched=end;
 662.481 +  ogg_int64_t next=end;
 662.482 +  ogg_int64_t searchgran=-1;
 662.483 +  ogg_page og;
 662.484 +  ogg_int64_t ret,last;
 662.485 +  int serialno = vf->os.serialno;
 662.486 +
 662.487 +  /* invariants:
 662.488 +     we have the headers and serialnos for the link beginning at 'begin'
 662.489 +     we have the offset and granpos of the last page in the file (potentially
 662.490 +       not a page we care about)
 662.491 +  */
 662.492 +
 662.493 +  /* Is the last page in our list of current serialnumbers? */
 662.494 +  if(_lookup_serialno(endserial,currentno_list,currentnos)){
 662.495 +
 662.496 +    /* last page is in the starting serialno list, so we've bisected
 662.497 +       down to (or just started with) a single link.  Now we need to
 662.498 +       find the last vorbis page belonging to the first vorbis stream
 662.499 +       for this link. */
 662.500 +
 662.501 +    while(endserial != serialno){
 662.502 +      endserial = serialno;
 662.503 +      vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&endserial,&endgran);
 662.504 +    }
 662.505 +
 662.506 +    vf->links=m+1;
 662.507 +    if(vf->offsets)_ogg_free(vf->offsets);
 662.508 +    if(vf->serialnos)_ogg_free(vf->serialnos);
 662.509 +    if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
 662.510 +
 662.511 +    vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
 662.512 +    vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
 662.513 +    vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
 662.514 +    vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
 662.515 +    vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
 662.516 +    vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
 662.517 +
 662.518 +    vf->offsets[m+1]=end;
 662.519 +    vf->offsets[m]=begin;
 662.520 +    vf->pcmlengths[m*2+1]=(endgran<0?0:endgran);
 662.521 +
 662.522 +  }else{
 662.523 +
 662.524 +    long *next_serialno_list=NULL;
 662.525 +    int next_serialnos=0;
 662.526 +    vorbis_info vi;
 662.527 +    vorbis_comment vc;
 662.528 +
 662.529 +    /* the below guards against garbage seperating the last and
 662.530 +       first pages of two links. */
 662.531 +    while(searched<endsearched){
 662.532 +      ogg_int64_t bisect;
 662.533 +
 662.534 +      if(endsearched-searched<CHUNKSIZE){
 662.535 +        bisect=searched;
 662.536 +      }else{
 662.537 +        bisect=(searched+endsearched)/2;
 662.538 +      }
 662.539 +
 662.540 +      if(bisect != vf->offset){
 662.541 +        ret=_seek_helper(vf,bisect);
 662.542 +        if(ret)return(ret);
 662.543 +      }
 662.544 +
 662.545 +      last=_get_next_page(vf,&og,-1);
 662.546 +      if(last==OV_EREAD)return(OV_EREAD);
 662.547 +      if(last<0 || !_lookup_page_serialno(&og,currentno_list,currentnos)){
 662.548 +        endsearched=bisect;
 662.549 +        if(last>=0)next=last;
 662.550 +      }else{
 662.551 +        searched=vf->offset;
 662.552 +      }
 662.553 +    }
 662.554 +
 662.555 +    /* Bisection point found */
 662.556 +
 662.557 +    /* for the time being, fetch end PCM offset the simple way */
 662.558 +    {
 662.559 +      int testserial = serialno+1;
 662.560 +      vf->offset = next;
 662.561 +      while(testserial != serialno){
 662.562 +        testserial = serialno;
 662.563 +        vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&testserial,&searchgran);
 662.564 +      }
 662.565 +    }
 662.566 +
 662.567 +    if(vf->offset!=next){
 662.568 +      ret=_seek_helper(vf,next);
 662.569 +      if(ret)return(ret);
 662.570 +    }
 662.571 +
 662.572 +    ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
 662.573 +    if(ret)return(ret);
 662.574 +    serialno = vf->os.serialno;
 662.575 +    dataoffset = vf->offset;
 662.576 +
 662.577 +    /* this will consume a page, however the next bistection always
 662.578 +       starts with a raw seek */
 662.579 +    pcmoffset = _initial_pcmoffset(vf,&vi);
 662.580 +
 662.581 +    ret=_bisect_forward_serialno(vf,next,vf->offset,end,endgran,endserial,
 662.582 +                                 next_serialno_list,next_serialnos,m+1);
 662.583 +    if(ret)return(ret);
 662.584 +
 662.585 +    if(next_serialno_list)_ogg_free(next_serialno_list);
 662.586 +
 662.587 +    vf->offsets[m+1]=next;
 662.588 +    vf->serialnos[m+1]=serialno;
 662.589 +    vf->dataoffsets[m+1]=dataoffset;
 662.590 +
 662.591 +    vf->vi[m+1]=vi;
 662.592 +    vf->vc[m+1]=vc;
 662.593 +
 662.594 +    vf->pcmlengths[m*2+1]=searchgran;
 662.595 +    vf->pcmlengths[m*2+2]=pcmoffset;
 662.596 +    vf->pcmlengths[m*2+3]-=pcmoffset;
 662.597 +    if(vf->pcmlengths[m*2+3]<0)vf->pcmlengths[m*2+3]=0;
 662.598 +  }
 662.599 +  return(0);
 662.600 +}
 662.601 +
 662.602 +static int _make_decode_ready(OggVorbis_File *vf){
 662.603 +  if(vf->ready_state>STREAMSET)return 0;
 662.604 +  if(vf->ready_state<STREAMSET)return OV_EFAULT;
 662.605 +  if(vf->seekable){
 662.606 +    if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
 662.607 +      return OV_EBADLINK;
 662.608 +  }else{
 662.609 +    if(vorbis_synthesis_init(&vf->vd,vf->vi))
 662.610 +      return OV_EBADLINK;
 662.611 +  }
 662.612 +  vorbis_block_init(&vf->vd,&vf->vb);
 662.613 +  vf->ready_state=INITSET;
 662.614 +  vf->bittrack=0.f;
 662.615 +  vf->samptrack=0.f;
 662.616 +  return 0;
 662.617 +}
 662.618 +
 662.619 +static int _open_seekable2(OggVorbis_File *vf){
 662.620 +  ogg_int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1;
 662.621 +  int endserial=vf->os.serialno;
 662.622 +  int serialno=vf->os.serialno;
 662.623 +
 662.624 +  /* we're partially open and have a first link header state in
 662.625 +     storage in vf */
 662.626 +
 662.627 +  /* fetch initial PCM offset */
 662.628 +  ogg_int64_t pcmoffset = _initial_pcmoffset(vf,vf->vi);
 662.629 +
 662.630 +  /* we can seek, so set out learning all about this file */
 662.631 +  if(vf->callbacks.seek_func && vf->callbacks.tell_func){
 662.632 +    (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
 662.633 +    vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
 662.634 +  }else{
 662.635 +    vf->offset=vf->end=-1;
 662.636 +  }
 662.637 +
 662.638 +  /* If seek_func is implemented, tell_func must also be implemented */
 662.639 +  if(vf->end==-1) return(OV_EINVAL);
 662.640 +
 662.641 +  /* Get the offset of the last page of the physical bitstream, or, if
 662.642 +     we're lucky the last vorbis page of this link as most OggVorbis
 662.643 +     files will contain a single logical bitstream */
 662.644 +  end=_get_prev_page_serial(vf,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
 662.645 +  if(end<0)return(end);
 662.646 +
 662.647 +  /* now determine bitstream structure recursively */
 662.648 +  if(_bisect_forward_serialno(vf,0,dataoffset,vf->offset,endgran,endserial,
 662.649 +                              vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
 662.650 +
 662.651 +  vf->offsets[0]=0;
 662.652 +  vf->serialnos[0]=serialno;
 662.653 +  vf->dataoffsets[0]=dataoffset;
 662.654 +  vf->pcmlengths[0]=pcmoffset;
 662.655 +  vf->pcmlengths[1]-=pcmoffset;
 662.656 +  if(vf->pcmlengths[1]<0)vf->pcmlengths[1]=0;
 662.657 +
 662.658 +  return(ov_raw_seek(vf,dataoffset));
 662.659 +}
 662.660 +
 662.661 +/* clear out the current logical bitstream decoder */
 662.662 +static void _decode_clear(OggVorbis_File *vf){
 662.663 +  vorbis_dsp_clear(&vf->vd);
 662.664 +  vorbis_block_clear(&vf->vb);
 662.665 +  vf->ready_state=OPENED;
 662.666 +}
 662.667 +
 662.668 +/* fetch and process a packet.  Handles the case where we're at a
 662.669 +   bitstream boundary and dumps the decoding machine.  If the decoding
 662.670 +   machine is unloaded, it loads it.  It also keeps pcm_offset up to
 662.671 +   date (seek and read both use this.  seek uses a special hack with
 662.672 +   readp).
 662.673 +
 662.674 +   return: <0) error, OV_HOLE (lost packet) or OV_EOF
 662.675 +            0) need more data (only if readp==0)
 662.676 +            1) got a packet
 662.677 +*/
 662.678 +
 662.679 +static int _fetch_and_process_packet(OggVorbis_File *vf,
 662.680 +                                     ogg_packet *op_in,
 662.681 +                                     int readp,
 662.682 +                                     int spanp){
 662.683 +  ogg_page og;
 662.684 +
 662.685 +  /* handle one packet.  Try to fetch it from current stream state */
 662.686 +  /* extract packets from page */
 662.687 +  while(1){
 662.688 +
 662.689 +    if(vf->ready_state==STREAMSET){
 662.690 +      int ret=_make_decode_ready(vf);
 662.691 +      if(ret<0)return ret;
 662.692 +    }
 662.693 +
 662.694 +    /* process a packet if we can. */
 662.695 +
 662.696 +    if(vf->ready_state==INITSET){
 662.697 +      int hs=vorbis_synthesis_halfrate_p(vf->vi);
 662.698 +
 662.699 +      while(1) {
 662.700 +              ogg_packet op;
 662.701 +              ogg_packet *op_ptr=(op_in?op_in:&op);
 662.702 +        int result=ogg_stream_packetout(&vf->os,op_ptr);
 662.703 +        ogg_int64_t granulepos;
 662.704 +
 662.705 +        op_in=NULL;
 662.706 +        if(result==-1)return(OV_HOLE); /* hole in the data. */
 662.707 +        if(result>0){
 662.708 +          /* got a packet.  process it */
 662.709 +          granulepos=op_ptr->granulepos;
 662.710 +          if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
 662.711 +                                                    header handling.  The
 662.712 +                                                    header packets aren't
 662.713 +                                                    audio, so if/when we
 662.714 +                                                    submit them,
 662.715 +                                                    vorbis_synthesis will
 662.716 +                                                    reject them */
 662.717 +
 662.718 +            /* suck in the synthesis data and track bitrate */
 662.719 +            {
 662.720 +              int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
 662.721 +              /* for proper use of libvorbis within libvorbisfile,
 662.722 +                 oldsamples will always be zero. */
 662.723 +              if(oldsamples)return(OV_EFAULT);
 662.724 +
 662.725 +              vorbis_synthesis_blockin(&vf->vd,&vf->vb);
 662.726 +              vf->samptrack+=(vorbis_synthesis_pcmout(&vf->vd,NULL)<<hs);
 662.727 +              vf->bittrack+=op_ptr->bytes*8;
 662.728 +            }
 662.729 +
 662.730 +            /* update the pcm offset. */
 662.731 +            if(granulepos!=-1 && !op_ptr->e_o_s){
 662.732 +              int link=(vf->seekable?vf->current_link:0);
 662.733 +              int i,samples;
 662.734 +
 662.735 +              /* this packet has a pcm_offset on it (the last packet
 662.736 +                 completed on a page carries the offset) After processing
 662.737 +                 (above), we know the pcm position of the *last* sample
 662.738 +                 ready to be returned. Find the offset of the *first*
 662.739 +
 662.740 +                 As an aside, this trick is inaccurate if we begin
 662.741 +                 reading anew right at the last page; the end-of-stream
 662.742 +                 granulepos declares the last frame in the stream, and the
 662.743 +                 last packet of the last page may be a partial frame.
 662.744 +                 So, we need a previous granulepos from an in-sequence page
 662.745 +                 to have a reference point.  Thus the !op_ptr->e_o_s clause
 662.746 +                 above */
 662.747 +
 662.748 +              if(vf->seekable && link>0)
 662.749 +                granulepos-=vf->pcmlengths[link*2];
 662.750 +              if(granulepos<0)granulepos=0; /* actually, this
 662.751 +                                               shouldn't be possible
 662.752 +                                               here unless the stream
 662.753 +                                               is very broken */
 662.754 +
 662.755 +              samples=(vorbis_synthesis_pcmout(&vf->vd,NULL)<<hs);
 662.756 +
 662.757 +              granulepos-=samples;
 662.758 +              for(i=0;i<link;i++)
 662.759 +                granulepos+=vf->pcmlengths[i*2+1];
 662.760 +              vf->pcm_offset=granulepos;
 662.761 +            }
 662.762 +            return(1);
 662.763 +          }
 662.764 +        }
 662.765 +        else
 662.766 +          break;
 662.767 +      }
 662.768 +    }
 662.769 +
 662.770 +    if(vf->ready_state>=OPENED){
 662.771 +      ogg_int64_t ret;
 662.772 +
 662.773 +      while(1){
 662.774 +        /* the loop is not strictly necessary, but there's no sense in
 662.775 +           doing the extra checks of the larger loop for the common
 662.776 +           case in a multiplexed bistream where the page is simply
 662.777 +           part of a different logical bitstream; keep reading until
 662.778 +           we get one with the correct serialno */
 662.779 +
 662.780 +        if(!readp)return(0);
 662.781 +        if((ret=_get_next_page(vf,&og,-1))<0){
 662.782 +          return(OV_EOF); /* eof. leave unitialized */
 662.783 +        }
 662.784 +
 662.785 +        /* bitrate tracking; add the header's bytes here, the body bytes
 662.786 +           are done by packet above */
 662.787 +        vf->bittrack+=og.header_len*8;
 662.788 +
 662.789 +        if(vf->ready_state==INITSET){
 662.790 +          if(vf->current_serialno!=ogg_page_serialno(&og)){
 662.791 +
 662.792 +            /* two possibilities:
 662.793 +               1) our decoding just traversed a bitstream boundary
 662.794 +               2) another stream is multiplexed into this logical section */
 662.795 +
 662.796 +            if(ogg_page_bos(&og)){
 662.797 +              /* boundary case */
 662.798 +              if(!spanp)
 662.799 +                return(OV_EOF);
 662.800 +
 662.801 +              _decode_clear(vf);
 662.802 +
 662.803 +              if(!vf->seekable){
 662.804 +                vorbis_info_clear(vf->vi);
 662.805 +                vorbis_comment_clear(vf->vc);
 662.806 +              }
 662.807 +              break;
 662.808 +
 662.809 +            }else
 662.810 +              continue; /* possibility #2 */
 662.811 +          }
 662.812 +        }
 662.813 +
 662.814 +        break;
 662.815 +      }
 662.816 +    }
 662.817 +
 662.818 +    /* Do we need to load a new machine before submitting the page? */
 662.819 +    /* This is different in the seekable and non-seekable cases.
 662.820 +
 662.821 +       In the seekable case, we already have all the header
 662.822 +       information loaded and cached; we just initialize the machine
 662.823 +       with it and continue on our merry way.
 662.824 +
 662.825 +       In the non-seekable (streaming) case, we'll only be at a
 662.826 +       boundary if we just left the previous logical bitstream and
 662.827 +       we're now nominally at the header of the next bitstream
 662.828 +    */
 662.829 +
 662.830 +    if(vf->ready_state!=INITSET){
 662.831 +      int link;
 662.832 +
 662.833 +      if(vf->ready_state<STREAMSET){
 662.834 +        if(vf->seekable){
 662.835 +          long serialno = ogg_page_serialno(&og);
 662.836 +
 662.837 +          /* match the serialno to bitstream section.  We use this rather than
 662.838 +             offset positions to avoid problems near logical bitstream
 662.839 +             boundaries */
 662.840 +
 662.841 +          for(link=0;link<vf->links;link++)
 662.842 +            if(vf->serialnos[link]==serialno)break;
 662.843 +
 662.844 +          if(link==vf->links) continue; /* not the desired Vorbis
 662.845 +                                           bitstream section; keep
 662.846 +                                           trying */
 662.847 +
 662.848 +          vf->current_serialno=serialno;
 662.849 +          vf->current_link=link;
 662.850 +
 662.851 +          ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
 662.852 +          vf->ready_state=STREAMSET;
 662.853 +
 662.854 +        }else{
 662.855 +          /* we're streaming */
 662.856 +          /* fetch the three header packets, build the info struct */
 662.857 +
 662.858 +          int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
 662.859 +          if(ret)return(ret);
 662.860 +          vf->current_serialno=vf->os.serialno;
 662.861 +          vf->current_link++;
 662.862 +          link=0;
 662.863 +        }
 662.864 +      }
 662.865 +    }
 662.866 +
 662.867 +    /* the buffered page is the data we want, and we're ready for it;
 662.868 +       add it to the stream state */
 662.869 +    ogg_stream_pagein(&vf->os,&og);
 662.870 +
 662.871 +  }
 662.872 +}
 662.873 +
 662.874 +/* if, eg, 64 bit stdio is configured by default, this will build with
 662.875 +   fseek64 */
 662.876 +static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
 662.877 +  if(f==NULL)return(-1);
 662.878 +  return fseek(f,off,whence);
 662.879 +}
 662.880 +
 662.881 +static int _ov_open1(void *f,OggVorbis_File *vf,const char *initial,
 662.882 +                     long ibytes, ov_callbacks callbacks){
 662.883 +  int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
 662.884 +  long *serialno_list=NULL;
 662.885 +  int serialno_list_size=0;
 662.886 +  int ret;
 662.887 +
 662.888 +  memset(vf,0,sizeof(*vf));
 662.889 +  vf->datasource=f;
 662.890 +  vf->callbacks = callbacks;
 662.891 +
 662.892 +  /* init the framing state */
 662.893 +  ogg_sync_init(&vf->oy);
 662.894 +
 662.895 +  /* perhaps some data was previously read into a buffer for testing
 662.896 +     against other stream types.  Allow initialization from this
 662.897 +     previously read data (especially as we may be reading from a
 662.898 +     non-seekable stream) */
 662.899 +  if(initial){
 662.900 +    char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
 662.901 +    memcpy(buffer,initial,ibytes);
 662.902 +    ogg_sync_wrote(&vf->oy,ibytes);
 662.903 +  }
 662.904 +
 662.905 +  /* can we seek? Stevens suggests the seek test was portable */
 662.906 +  if(offsettest!=-1)vf->seekable=1;
 662.907 +
 662.908 +  /* No seeking yet; Set up a 'single' (current) logical bitstream
 662.909 +     entry for partial open */
 662.910 +  vf->links=1;
 662.911 +  vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
 662.912 +  vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
 662.913 +  ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
 662.914 +
 662.915 +  /* Fetch all BOS pages, store the vorbis header and all seen serial
 662.916 +     numbers, load subsequent vorbis setup headers */
 662.917 +  if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){
 662.918 +    vf->datasource=NULL;
 662.919 +    ov_clear(vf);
 662.920 +  }else{
 662.921 +    /* serial number list for first link needs to be held somewhere
 662.922 +       for second stage of seekable stream open; this saves having to
 662.923 +       seek/reread first link's serialnumber data then. */
 662.924 +    vf->serialnos=_ogg_calloc(serialno_list_size+2,sizeof(*vf->serialnos));
 662.925 +    vf->serialnos[0]=vf->current_serialno=vf->os.serialno;
 662.926 +    vf->serialnos[1]=serialno_list_size;
 662.927 +    memcpy(vf->serialnos+2,serialno_list,serialno_list_size*sizeof(*vf->serialnos));
 662.928 +
 662.929 +    vf->offsets=_ogg_calloc(1,sizeof(*vf->offsets));
 662.930 +    vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets));
 662.931 +    vf->offsets[0]=0;
 662.932 +    vf->dataoffsets[0]=vf->offset;
 662.933 +
 662.934 +    vf->ready_state=PARTOPEN;
 662.935 +  }
 662.936 +  if(serialno_list)_ogg_free(serialno_list);
 662.937 +  return(ret);
 662.938 +}
 662.939 +
 662.940 +static int _ov_open2(OggVorbis_File *vf){
 662.941 +  if(vf->ready_state != PARTOPEN) return OV_EINVAL;
 662.942 +  vf->ready_state=OPENED;
 662.943 +  if(vf->seekable){
 662.944 +    int ret=_open_seekable2(vf);
 662.945 +    if(ret){
 662.946 +      vf->datasource=NULL;
 662.947 +      ov_clear(vf);
 662.948 +    }
 662.949 +    return(ret);
 662.950 +  }else
 662.951 +    vf->ready_state=STREAMSET;
 662.952 +
 662.953 +  return 0;
 662.954 +}
 662.955 +
 662.956 +
 662.957 +/* clear out the OggVorbis_File struct */
 662.958 +int ov_clear(OggVorbis_File *vf){
 662.959 +  if(vf){
 662.960 +    vorbis_block_clear(&vf->vb);
 662.961 +    vorbis_dsp_clear(&vf->vd);
 662.962 +    ogg_stream_clear(&vf->os);
 662.963 +
 662.964 +    if(vf->vi && vf->links){
 662.965 +      int i;
 662.966 +      for(i=0;i<vf->links;i++){
 662.967 +        vorbis_info_clear(vf->vi+i);
 662.968 +        vorbis_comment_clear(vf->vc+i);
 662.969 +      }
 662.970 +      _ogg_free(vf->vi);
 662.971 +      _ogg_free(vf->vc);
 662.972 +    }
 662.973 +    if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
 662.974 +    if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
 662.975 +    if(vf->serialnos)_ogg_free(vf->serialnos);
 662.976 +    if(vf->offsets)_ogg_free(vf->offsets);
 662.977 +    ogg_sync_clear(&vf->oy);
 662.978 +    if(vf->datasource && vf->callbacks.close_func)
 662.979 +      (vf->callbacks.close_func)(vf->datasource);
 662.980 +    memset(vf,0,sizeof(*vf));
 662.981 +  }
 662.982 +#ifdef DEBUG_LEAKS
 662.983 +  _VDBG_dump();
 662.984 +#endif
 662.985 +  return(0);
 662.986 +}
 662.987 +
 662.988 +/* inspects the OggVorbis file and finds/documents all the logical
 662.989 +   bitstreams contained in it.  Tries to be tolerant of logical
 662.990 +   bitstream sections that are truncated/woogie.
 662.991 +
 662.992 +   return: -1) error
 662.993 +            0) OK
 662.994 +*/
 662.995 +
 662.996 +int ov_open_callbacks(void *f,OggVorbis_File *vf,
 662.997 +    const char *initial,long ibytes,ov_callbacks callbacks){
 662.998 +  int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
 662.999 +  if(ret)return ret;
662.1000 +  return _ov_open2(vf);
662.1001 +}
662.1002 +
662.1003 +int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes){
662.1004 +  ov_callbacks callbacks = {
662.1005 +    (size_t (*)(void *, size_t, size_t, void *))  fread,
662.1006 +    (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
662.1007 +    (int (*)(void *))                             fclose,
662.1008 +    (long (*)(void *))                            ftell
662.1009 +  };
662.1010 +
662.1011 +  return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
662.1012 +}
662.1013 +
662.1014 +int ov_fopen(const char *path,OggVorbis_File *vf){
662.1015 +  int ret;
662.1016 +  FILE *f = fopen(path,"rb");
662.1017 +  if(!f) return -1;
662.1018 +
662.1019 +  ret = ov_open(f,vf,NULL,0);
662.1020 +  if(ret) fclose(f);
662.1021 +  return ret;
662.1022 +}
662.1023 +
662.1024 +
662.1025 +/* cheap hack for game usage where downsampling is desirable; there's
662.1026 +   no need for SRC as we can just do it cheaply in libvorbis. */
662.1027 +
662.1028 +int ov_halfrate(OggVorbis_File *vf,int flag){
662.1029 +  int i;
662.1030 +  if(vf->vi==NULL)return OV_EINVAL;
662.1031 +  if(vf->ready_state>STREAMSET){
662.1032 +    /* clear out stream state; dumping the decode machine is needed to
662.1033 +       reinit the MDCT lookups. */
662.1034 +    vorbis_dsp_clear(&vf->vd);
662.1035 +    vorbis_block_clear(&vf->vb);
662.1036 +    vf->ready_state=STREAMSET;
662.1037 +    if(vf->pcm_offset>=0){
662.1038 +      ogg_int64_t pos=vf->pcm_offset;
662.1039 +      vf->pcm_offset=-1; /* make sure the pos is dumped if unseekable */
662.1040 +      ov_pcm_seek(vf,pos);
662.1041 +    }
662.1042 +  }
662.1043 +
662.1044 +  for(i=0;i<vf->links;i++){
662.1045 +    if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
662.1046 +      if(flag) ov_halfrate(vf,0);
662.1047 +      return OV_EINVAL;
662.1048 +    }
662.1049 +  }
662.1050 +  return 0;
662.1051 +}
662.1052 +
662.1053 +int ov_halfrate_p(OggVorbis_File *vf){
662.1054 +  if(vf->vi==NULL)return OV_EINVAL;
662.1055 +  return vorbis_synthesis_halfrate_p(vf->vi);
662.1056 +}
662.1057 +
662.1058 +/* Only partially open the vorbis file; test for Vorbisness, and load
662.1059 +   the headers for the first chain.  Do not seek (although test for
662.1060 +   seekability).  Use ov_test_open to finish opening the file, else
662.1061 +   ov_clear to close/free it. Same return codes as open. */
662.1062 +
662.1063 +int ov_test_callbacks(void *f,OggVorbis_File *vf,
662.1064 +    const char *initial,long ibytes,ov_callbacks callbacks)
662.1065 +{
662.1066 +  return _ov_open1(f,vf,initial,ibytes,callbacks);
662.1067 +}
662.1068 +
662.1069 +int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes){
662.1070 +  ov_callbacks callbacks = {
662.1071 +    (size_t (*)(void *, size_t, size_t, void *))  fread,
662.1072 +    (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
662.1073 +    (int (*)(void *))                             fclose,
662.1074 +    (long (*)(void *))                            ftell
662.1075 +  };
662.1076 +
662.1077 +  return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
662.1078 +}
662.1079 +
662.1080 +int ov_test_open(OggVorbis_File *vf){
662.1081 +  if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
662.1082 +  return _ov_open2(vf);
662.1083 +}
662.1084 +
662.1085 +/* How many logical bitstreams in this physical bitstream? */
662.1086 +long ov_streams(OggVorbis_File *vf){
662.1087 +  return vf->links;
662.1088 +}
662.1089 +
662.1090 +/* Is the FILE * associated with vf seekable? */
662.1091 +long ov_seekable(OggVorbis_File *vf){
662.1092 +  return vf->seekable;
662.1093 +}
662.1094 +
662.1095 +/* returns the bitrate for a given logical bitstream or the entire
662.1096 +   physical bitstream.  If the file is open for random access, it will
662.1097 +   find the *actual* average bitrate.  If the file is streaming, it
662.1098 +   returns the nominal bitrate (if set) else the average of the
662.1099 +   upper/lower bounds (if set) else -1 (unset).
662.1100 +
662.1101 +   If you want the actual bitrate field settings, get them from the
662.1102 +   vorbis_info structs */
662.1103 +
662.1104 +long ov_bitrate(OggVorbis_File *vf,int i){
662.1105 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1106 +  if(i>=vf->links)return(OV_EINVAL);
662.1107 +  if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
662.1108 +  if(i<0){
662.1109 +    ogg_int64_t bits=0;
662.1110 +    int i;
662.1111 +    float br;
662.1112 +    for(i=0;i<vf->links;i++)
662.1113 +      bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
662.1114 +    /* This once read: return(rint(bits/ov_time_total(vf,-1)));
662.1115 +     * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
662.1116 +     * so this is slightly transformed to make it work.
662.1117 +     */
662.1118 +    br = bits/ov_time_total(vf,-1);
662.1119 +    return(rint(br));
662.1120 +  }else{
662.1121 +    if(vf->seekable){
662.1122 +      /* return the actual bitrate */
662.1123 +      return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
662.1124 +    }else{
662.1125 +      /* return nominal if set */
662.1126 +      if(vf->vi[i].bitrate_nominal>0){
662.1127 +        return vf->vi[i].bitrate_nominal;
662.1128 +      }else{
662.1129 +        if(vf->vi[i].bitrate_upper>0){
662.1130 +          if(vf->vi[i].bitrate_lower>0){
662.1131 +            return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
662.1132 +          }else{
662.1133 +            return vf->vi[i].bitrate_upper;
662.1134 +          }
662.1135 +        }
662.1136 +        return(OV_FALSE);
662.1137 +      }
662.1138 +    }
662.1139 +  }
662.1140 +}
662.1141 +
662.1142 +/* returns the actual bitrate since last call.  returns -1 if no
662.1143 +   additional data to offer since last call (or at beginning of stream),
662.1144 +   EINVAL if stream is only partially open
662.1145 +*/
662.1146 +long ov_bitrate_instant(OggVorbis_File *vf){
662.1147 +  int link=(vf->seekable?vf->current_link:0);
662.1148 +  long ret;
662.1149 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1150 +  if(vf->samptrack==0)return(OV_FALSE);
662.1151 +  ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
662.1152 +  vf->bittrack=0.f;
662.1153 +  vf->samptrack=0.f;
662.1154 +  return(ret);
662.1155 +}
662.1156 +
662.1157 +/* Guess */
662.1158 +long ov_serialnumber(OggVorbis_File *vf,int i){
662.1159 +  if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
662.1160 +  if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
662.1161 +  if(i<0){
662.1162 +    return(vf->current_serialno);
662.1163 +  }else{
662.1164 +    return(vf->serialnos[i]);
662.1165 +  }
662.1166 +}
662.1167 +
662.1168 +/* returns: total raw (compressed) length of content if i==-1
662.1169 +            raw (compressed) length of that logical bitstream for i==0 to n
662.1170 +            OV_EINVAL if the stream is not seekable (we can't know the length)
662.1171 +            or if stream is only partially open
662.1172 +*/
662.1173 +ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
662.1174 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1175 +  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
662.1176 +  if(i<0){
662.1177 +    ogg_int64_t acc=0;
662.1178 +    int i;
662.1179 +    for(i=0;i<vf->links;i++)
662.1180 +      acc+=ov_raw_total(vf,i);
662.1181 +    return(acc);
662.1182 +  }else{
662.1183 +    return(vf->offsets[i+1]-vf->offsets[i]);
662.1184 +  }
662.1185 +}
662.1186 +
662.1187 +/* returns: total PCM length (samples) of content if i==-1 PCM length
662.1188 +            (samples) of that logical bitstream for i==0 to n
662.1189 +            OV_EINVAL if the stream is not seekable (we can't know the
662.1190 +            length) or only partially open
662.1191 +*/
662.1192 +ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
662.1193 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1194 +  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
662.1195 +  if(i<0){
662.1196 +    ogg_int64_t acc=0;
662.1197 +    int i;
662.1198 +    for(i=0;i<vf->links;i++)
662.1199 +      acc+=ov_pcm_total(vf,i);
662.1200 +    return(acc);
662.1201 +  }else{
662.1202 +    return(vf->pcmlengths[i*2+1]);
662.1203 +  }
662.1204 +}
662.1205 +
662.1206 +/* returns: total seconds of content if i==-1
662.1207 +            seconds in that logical bitstream for i==0 to n
662.1208 +            OV_EINVAL if the stream is not seekable (we can't know the
662.1209 +            length) or only partially open
662.1210 +*/
662.1211 +double ov_time_total(OggVorbis_File *vf,int i){
662.1212 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1213 +  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
662.1214 +  if(i<0){
662.1215 +    double acc=0;
662.1216 +    int i;
662.1217 +    for(i=0;i<vf->links;i++)
662.1218 +      acc+=ov_time_total(vf,i);
662.1219 +    return(acc);
662.1220 +  }else{
662.1221 +    return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
662.1222 +  }
662.1223 +}
662.1224 +
662.1225 +/* seek to an offset relative to the *compressed* data. This also
662.1226 +   scans packets to update the PCM cursor. It will cross a logical
662.1227 +   bitstream boundary, but only if it can't get any packets out of the
662.1228 +   tail of the bitstream we seek to (so no surprises).
662.1229 +
662.1230 +   returns zero on success, nonzero on failure */
662.1231 +
662.1232 +int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
662.1233 +  ogg_stream_state work_os;
662.1234 +  int ret;
662.1235 +
662.1236 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1237 +  if(!vf->seekable)
662.1238 +    return(OV_ENOSEEK); /* don't dump machine if we can't seek */
662.1239 +
662.1240 +  if(pos<0 || pos>vf->end)return(OV_EINVAL);
662.1241 +
662.1242 +  /* is the seek position outside our current link [if any]? */
662.1243 +  if(vf->ready_state>=STREAMSET){
662.1244 +    if(pos<vf->offsets[vf->current_link] || pos>=vf->offsets[vf->current_link+1])
662.1245 +      _decode_clear(vf); /* clear out stream state */
662.1246 +  }
662.1247 +
662.1248 +  /* don't yet clear out decoding machine (if it's initialized), in
662.1249 +     the case we're in the same link.  Restart the decode lapping, and
662.1250 +     let _fetch_and_process_packet deal with a potential bitstream
662.1251 +     boundary */
662.1252 +  vf->pcm_offset=-1;
662.1253 +  ogg_stream_reset_serialno(&vf->os,
662.1254 +                            vf->current_serialno); /* must set serialno */
662.1255 +  vorbis_synthesis_restart(&vf->vd);
662.1256 +
662.1257 +  ret=_seek_helper(vf,pos);
662.1258 +  if(ret)goto seek_error;
662.1259 +
662.1260 +  /* we need to make sure the pcm_offset is set, but we don't want to
662.1261 +     advance the raw cursor past good packets just to get to the first
662.1262 +     with a granulepos.  That's not equivalent behavior to beginning
662.1263 +     decoding as immediately after the seek position as possible.
662.1264 +
662.1265 +     So, a hack.  We use two stream states; a local scratch state and
662.1266 +     the shared vf->os stream state.  We use the local state to
662.1267 +     scan, and the shared state as a buffer for later decode.
662.1268 +
662.1269 +     Unfortuantely, on the last page we still advance to last packet
662.1270 +     because the granulepos on the last page is not necessarily on a
662.1271 +     packet boundary, and we need to make sure the granpos is
662.1272 +     correct.
662.1273 +  */
662.1274 +
662.1275 +  {
662.1276 +    ogg_page og;
662.1277 +    ogg_packet op;
662.1278 +    int lastblock=0;
662.1279 +    int accblock=0;
662.1280 +    int thisblock=0;
662.1281 +    int lastflag=0;
662.1282 +    int firstflag=0;
662.1283 +    ogg_int64_t pagepos=-1;
662.1284 +
662.1285 +    ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
662.1286 +    ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
662.1287 +                                   return from not necessarily
662.1288 +                                   starting from the beginning */
662.1289 +
662.1290 +    while(1){
662.1291 +      if(vf->ready_state>=STREAMSET){
662.1292 +        /* snarf/scan a packet if we can */
662.1293 +        int result=ogg_stream_packetout(&work_os,&op);
662.1294 +
662.1295 +        if(result>0){
662.1296 +
662.1297 +          if(vf->vi[vf->current_link].codec_setup){
662.1298 +            thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
662.1299 +            if(thisblock<0){
662.1300 +              ogg_stream_packetout(&vf->os,NULL);
662.1301 +              thisblock=0;
662.1302 +            }else{
662.1303 +
662.1304 +              /* We can't get a guaranteed correct pcm position out of the
662.1305 +                 last page in a stream because it might have a 'short'
662.1306 +                 granpos, which can only be detected in the presence of a
662.1307 +                 preceding page.  However, if the last page is also the first
662.1308 +                 page, the granpos rules of a first page take precedence.  Not
662.1309 +                 only that, but for first==last, the EOS page must be treated
662.1310 +                 as if its a normal first page for the stream to open/play. */
662.1311 +              if(lastflag && !firstflag)
662.1312 +                ogg_stream_packetout(&vf->os,NULL);
662.1313 +              else
662.1314 +                if(lastblock)accblock+=(lastblock+thisblock)>>2;
662.1315 +            }
662.1316 +
662.1317 +            if(op.granulepos!=-1){
662.1318 +              int i,link=vf->current_link;
662.1319 +              ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
662.1320 +              if(granulepos<0)granulepos=0;
662.1321 +
662.1322 +              for(i=0;i<link;i++)
662.1323 +                granulepos+=vf->pcmlengths[i*2+1];
662.1324 +              vf->pcm_offset=granulepos-accblock;
662.1325 +              if(vf->pcm_offset<0)vf->pcm_offset=0;
662.1326 +              break;
662.1327 +            }
662.1328 +            lastblock=thisblock;
662.1329 +            continue;
662.1330 +          }else
662.1331 +            ogg_stream_packetout(&vf->os,NULL);
662.1332 +        }
662.1333 +      }
662.1334 +
662.1335 +      if(!lastblock){
662.1336 +        pagepos=_get_next_page(vf,&og,-1);
662.1337 +        if(pagepos<0){
662.1338 +          vf->pcm_offset=ov_pcm_total(vf,-1);
662.1339 +          break;
662.1340 +        }
662.1341 +      }else{
662.1342 +        /* huh?  Bogus stream with packets but no granulepos */
662.1343 +        vf->pcm_offset=-1;
662.1344 +        break;
662.1345 +      }
662.1346 +
662.1347 +      /* has our decoding just traversed a bitstream boundary? */
662.1348 +      if(vf->ready_state>=STREAMSET){
662.1349 +        if(vf->current_serialno!=ogg_page_serialno(&og)){
662.1350 +
662.1351 +          /* two possibilities:
662.1352 +             1) our decoding just traversed a bitstream boundary
662.1353 +             2) another stream is multiplexed into this logical section? */
662.1354 +
662.1355 +          if(ogg_page_bos(&og)){
662.1356 +            /* we traversed */
662.1357 +            _decode_clear(vf); /* clear out stream state */
662.1358 +            ogg_stream_clear(&work_os);
662.1359 +          } /* else, do nothing; next loop will scoop another page */
662.1360 +        }
662.1361 +      }
662.1362 +
662.1363 +      if(vf->ready_state<STREAMSET){
662.1364 +        int link;
662.1365 +        long serialno = ogg_page_serialno(&og);
662.1366 +
662.1367 +        for(link=0;link<vf->links;link++)
662.1368 +          if(vf->serialnos[link]==serialno)break;
662.1369 +
662.1370 +        if(link==vf->links) continue; /* not the desired Vorbis
662.1371 +                                         bitstream section; keep
662.1372 +                                         trying */
662.1373 +        vf->current_link=link;
662.1374 +        vf->current_serialno=serialno;
662.1375 +        ogg_stream_reset_serialno(&vf->os,serialno);
662.1376 +        ogg_stream_reset_serialno(&work_os,serialno);
662.1377 +        vf->ready_state=STREAMSET;
662.1378 +        firstflag=(pagepos<=vf->dataoffsets[link]);
662.1379 +      }
662.1380 +
662.1381 +      ogg_stream_pagein(&vf->os,&og);
662.1382 +      ogg_stream_pagein(&work_os,&og);
662.1383 +      lastflag=ogg_page_eos(&og);
662.1384 +
662.1385 +    }
662.1386 +  }
662.1387 +
662.1388 +  ogg_stream_clear(&work_os);
662.1389 +  vf->bittrack=0.f;
662.1390 +  vf->samptrack=0.f;
662.1391 +  return(0);
662.1392 +
662.1393 + seek_error:
662.1394 +  /* dump the machine so we're in a known state */
662.1395 +  vf->pcm_offset=-1;
662.1396 +  ogg_stream_clear(&work_os);
662.1397 +  _decode_clear(vf);
662.1398 +  return OV_EBADLINK;
662.1399 +}
662.1400 +
662.1401 +/* Page granularity seek (faster than sample granularity because we
662.1402 +   don't do the last bit of decode to find a specific sample).
662.1403 +
662.1404 +   Seek to the last [granule marked] page preceding the specified pos
662.1405 +   location, such that decoding past the returned point will quickly
662.1406 +   arrive at the requested position. */
662.1407 +int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
662.1408 +  int link=-1;
662.1409 +  ogg_int64_t result=0;
662.1410 +  ogg_int64_t total=ov_pcm_total(vf,-1);
662.1411 +
662.1412 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1413 +  if(!vf->seekable)return(OV_ENOSEEK);
662.1414 +
662.1415 +  if(pos<0 || pos>total)return(OV_EINVAL);
662.1416 +
662.1417 +  /* which bitstream section does this pcm offset occur in? */
662.1418 +  for(link=vf->links-1;link>=0;link--){
662.1419 +    total-=vf->pcmlengths[link*2+1];
662.1420 +    if(pos>=total)break;
662.1421 +  }
662.1422 +
662.1423 +  /* search within the logical bitstream for the page with the highest
662.1424 +     pcm_pos preceding (or equal to) pos.  There is a danger here;
662.1425 +     missing pages or incorrect frame number information in the
662.1426 +     bitstream could make our task impossible.  Account for that (it
662.1427 +     would be an error condition) */
662.1428 +
662.1429 +  /* new search algorithm by HB (Nicholas Vinen) */
662.1430 +  {
662.1431 +    ogg_int64_t end=vf->offsets[link+1];
662.1432 +    ogg_int64_t begin=vf->offsets[link];
662.1433 +    ogg_int64_t begintime = vf->pcmlengths[link*2];
662.1434 +    ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
662.1435 +    ogg_int64_t target=pos-total+begintime;
662.1436 +    ogg_int64_t best=begin;
662.1437 +
662.1438 +    ogg_page og;
662.1439 +    while(begin<end){
662.1440 +      ogg_int64_t bisect;
662.1441 +
662.1442 +      if(end-begin<CHUNKSIZE){
662.1443 +        bisect=begin;
662.1444 +      }else{
662.1445 +        /* take a (pretty decent) guess. */
662.1446 +        bisect=begin +
662.1447 +          (ogg_int64_t)((double)(target-begintime)*(end-begin)/(endtime-begintime))
662.1448 +          - CHUNKSIZE;
662.1449 +        if(bisect<begin+CHUNKSIZE)
662.1450 +          bisect=begin;
662.1451 +      }
662.1452 +
662.1453 +      if(bisect!=vf->offset){
662.1454 +        result=_seek_helper(vf,bisect);
662.1455 +        if(result) goto seek_error;
662.1456 +      }
662.1457 +
662.1458 +      while(begin<end){
662.1459 +        result=_get_next_page(vf,&og,end-vf->offset);
662.1460 +        if(result==OV_EREAD) goto seek_error;
662.1461 +        if(result<0){
662.1462 +          if(bisect<=begin+1)
662.1463 +            end=begin; /* found it */
662.1464 +          else{
662.1465 +            if(bisect==0) goto seek_error;
662.1466 +            bisect-=CHUNKSIZE;
662.1467 +            if(bisect<=begin)bisect=begin+1;
662.1468 +            result=_seek_helper(vf,bisect);
662.1469 +            if(result) goto seek_error;
662.1470 +          }
662.1471 +        }else{
662.1472 +          ogg_int64_t granulepos;
662.1473 +
662.1474 +          if(ogg_page_serialno(&og)!=vf->serialnos[link])
662.1475 +            continue;
662.1476 +
662.1477 +          granulepos=ogg_page_granulepos(&og);
662.1478 +          if(granulepos==-1)continue;
662.1479 +
662.1480 +          if(granulepos<target){
662.1481 +            best=result;  /* raw offset of packet with granulepos */
662.1482 +            begin=vf->offset; /* raw offset of next page */
662.1483 +            begintime=granulepos;
662.1484 +
662.1485 +            if(target-begintime>44100)break;
662.1486 +            bisect=begin; /* *not* begin + 1 */
662.1487 +          }else{
662.1488 +            if(bisect<=begin+1)
662.1489 +              end=begin;  /* found it */
662.1490 +            else{
662.1491 +              if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
662.1492 +                end=result;
662.1493 +                bisect-=CHUNKSIZE; /* an endless loop otherwise. */
662.1494 +                if(bisect<=begin)bisect=begin+1;
662.1495 +                result=_seek_helper(vf,bisect);
662.1496 +                if(result) goto seek_error;
662.1497 +              }else{
662.1498 +                end=bisect;
662.1499 +                endtime=granulepos;
662.1500 +                break;
662.1501 +              }
662.1502 +            }
662.1503 +          }
662.1504 +        }
662.1505 +      }
662.1506 +    }
662.1507 +
662.1508 +    /* found our page. seek to it, update pcm offset. Easier case than
662.1509 +       raw_seek, don't keep packets preceding granulepos. */
662.1510 +    {
662.1511 +      ogg_page og;
662.1512 +      ogg_packet op;
662.1513 +
662.1514 +      /* seek */
662.1515 +      result=_seek_helper(vf,best);
662.1516 +      vf->pcm_offset=-1;
662.1517 +      if(result) goto seek_error;
662.1518 +      result=_get_next_page(vf,&og,-1);
662.1519 +      if(result<0) goto seek_error;
662.1520 +
662.1521 +      if(link!=vf->current_link){
662.1522 +        /* Different link; dump entire decode machine */
662.1523 +        _decode_clear(vf);
662.1524 +
662.1525 +        vf->current_link=link;
662.1526 +        vf->current_serialno=vf->serialnos[link];
662.1527 +        vf->ready_state=STREAMSET;
662.1528 +
662.1529 +      }else{
662.1530 +        vorbis_synthesis_restart(&vf->vd);
662.1531 +      }
662.1532 +
662.1533 +      ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
662.1534 +      ogg_stream_pagein(&vf->os,&og);
662.1535 +
662.1536 +      /* pull out all but last packet; the one with granulepos */
662.1537 +      while(1){
662.1538 +        result=ogg_stream_packetpeek(&vf->os,&op);
662.1539 +        if(result==0){
662.1540 +          /* !!! the packet finishing this page originated on a
662.1541 +             preceding page. Keep fetching previous pages until we
662.1542 +             get one with a granulepos or without the 'continued' flag
662.1543 +             set.  Then just use raw_seek for simplicity. */
662.1544 +
662.1545 +          result=_seek_helper(vf,best);
662.1546 +          if(result<0) goto seek_error;
662.1547 +
662.1548 +          while(1){
662.1549 +            result=_get_prev_page(vf,&og);
662.1550 +            if(result<0) goto seek_error;
662.1551 +            if(ogg_page_serialno(&og)==vf->current_serialno &&
662.1552 +               (ogg_page_granulepos(&og)>-1 ||
662.1553 +                !ogg_page_continued(&og))){
662.1554 +              return ov_raw_seek(vf,result);
662.1555 +            }
662.1556 +            vf->offset=result;
662.1557 +          }
662.1558 +        }
662.1559 +        if(result<0){
662.1560 +          result = OV_EBADPACKET;
662.1561 +          goto seek_error;
662.1562 +        }
662.1563 +        if(op.granulepos!=-1){
662.1564 +          vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
662.1565 +          if(vf->pcm_offset<0)vf->pcm_offset=0;
662.1566 +          vf->pcm_offset+=total;
662.1567 +          break;
662.1568 +        }else
662.1569 +          result=ogg_stream_packetout(&vf->os,NULL);
662.1570 +      }
662.1571 +    }
662.1572 +  }
662.1573 +
662.1574 +  /* verify result */
662.1575 +  if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
662.1576 +    result=OV_EFAULT;
662.1577 +    goto seek_error;
662.1578 +  }
662.1579 +  vf->bittrack=0.f;
662.1580 +  vf->samptrack=0.f;
662.1581 +  return(0);
662.1582 +
662.1583 + seek_error:
662.1584 +  /* dump machine so we're in a known state */
662.1585 +  vf->pcm_offset=-1;
662.1586 +  _decode_clear(vf);
662.1587 +  return (int)result;
662.1588 +}
662.1589 +
662.1590 +/* seek to a sample offset relative to the decompressed pcm stream
662.1591 +   returns zero on success, nonzero on failure */
662.1592 +
662.1593 +int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
662.1594 +  int thisblock,lastblock=0;
662.1595 +  int ret=ov_pcm_seek_page(vf,pos);
662.1596 +  if(ret<0)return(ret);
662.1597 +  if((ret=_make_decode_ready(vf)))return ret;
662.1598 +
662.1599 +  /* discard leading packets we don't need for the lapping of the
662.1600 +     position we want; don't decode them */
662.1601 +
662.1602 +  while(1){
662.1603 +    ogg_packet op;
662.1604 +    ogg_page og;
662.1605 +
662.1606 +    int ret=ogg_stream_packetpeek(&vf->os,&op);
662.1607 +    if(ret>0){
662.1608 +      thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
662.1609 +      if(thisblock<0){
662.1610 +        ogg_stream_packetout(&vf->os,NULL);
662.1611 +        continue; /* non audio packet */
662.1612 +      }
662.1613 +      if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
662.1614 +
662.1615 +      if(vf->pcm_offset+((thisblock+
662.1616 +                          vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
662.1617 +
662.1618 +      /* remove the packet from packet queue and track its granulepos */
662.1619 +      ogg_stream_packetout(&vf->os,NULL);
662.1620 +      vorbis_synthesis_trackonly(&vf->vb,&op);  /* set up a vb with
662.1621 +                                                   only tracking, no
662.1622 +                                                   pcm_decode */
662.1623 +      vorbis_synthesis_blockin(&vf->vd,&vf->vb);
662.1624 +
662.1625 +      /* end of logical stream case is hard, especially with exact
662.1626 +         length positioning. */
662.1627 +
662.1628 +      if(op.granulepos>-1){
662.1629 +        int i;
662.1630 +        /* always believe the stream markers */
662.1631 +        vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
662.1632 +        if(vf->pcm_offset<0)vf->pcm_offset=0;
662.1633 +        for(i=0;i<vf->current_link;i++)
662.1634 +          vf->pcm_offset+=vf->pcmlengths[i*2+1];
662.1635 +      }
662.1636 +
662.1637 +      lastblock=thisblock;
662.1638 +
662.1639 +    }else{
662.1640 +      if(ret<0 && ret!=OV_HOLE)break;
662.1641 +
662.1642 +      /* suck in a new page */
662.1643 +      if(_get_next_page(vf,&og,-1)<0)break;
662.1644 +      if(ogg_page_bos(&og))_decode_clear(vf);
662.1645 +
662.1646 +      if(vf->ready_state<STREAMSET){
662.1647 +        long serialno=ogg_page_serialno(&og);
662.1648 +        int link;
662.1649 +
662.1650 +        for(link=0;link<vf->links;link++)
662.1651 +          if(vf->serialnos[link]==serialno)break;
662.1652 +        if(link==vf->links) continue;
662.1653 +        vf->current_link=link;
662.1654 +
662.1655 +        vf->ready_state=STREAMSET;
662.1656 +        vf->current_serialno=ogg_page_serialno(&og);
662.1657 +        ogg_stream_reset_serialno(&vf->os,serialno);
662.1658 +        ret=_make_decode_ready(vf);
662.1659 +        if(ret)return ret;
662.1660 +        lastblock=0;
662.1661 +      }
662.1662 +
662.1663 +      ogg_stream_pagein(&vf->os,&og);
662.1664 +    }
662.1665 +  }
662.1666 +
662.1667 +  vf->bittrack=0.f;
662.1668 +  vf->samptrack=0.f;
662.1669 +  /* discard samples until we reach the desired position. Crossing a
662.1670 +     logical bitstream boundary with abandon is OK. */
662.1671 +  {
662.1672 +    /* note that halfrate could be set differently in each link, but
662.1673 +       vorbisfile encoforces all links are set or unset */
662.1674 +    int hs=vorbis_synthesis_halfrate_p(vf->vi);
662.1675 +    while(vf->pcm_offset<((pos>>hs)<<hs)){
662.1676 +      ogg_int64_t target=(pos-vf->pcm_offset)>>hs;
662.1677 +      long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
662.1678 +
662.1679 +      if(samples>target)samples=target;
662.1680 +      vorbis_synthesis_read(&vf->vd,samples);
662.1681 +      vf->pcm_offset+=samples<<hs;
662.1682 +
662.1683 +      if(samples<target)
662.1684 +        if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
662.1685 +          vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
662.1686 +    }
662.1687 +  }
662.1688 +  return 0;
662.1689 +}
662.1690 +
662.1691 +/* seek to a playback time relative to the decompressed pcm stream
662.1692 +   returns zero on success, nonzero on failure */
662.1693 +int ov_time_seek(OggVorbis_File *vf,double seconds){
662.1694 +  /* translate time to PCM position and call ov_pcm_seek */
662.1695 +
662.1696 +  int link=-1;
662.1697 +  ogg_int64_t pcm_total=0;
662.1698 +  double time_total=0.;
662.1699 +
662.1700 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1701 +  if(!vf->seekable)return(OV_ENOSEEK);
662.1702 +  if(seconds<0)return(OV_EINVAL);
662.1703 +
662.1704 +  /* which bitstream section does this time offset occur in? */
662.1705 +  for(link=0;link<vf->links;link++){
662.1706 +    double addsec = ov_time_total(vf,link);
662.1707 +    if(seconds<time_total+addsec)break;
662.1708 +    time_total+=addsec;
662.1709 +    pcm_total+=vf->pcmlengths[link*2+1];
662.1710 +  }
662.1711 +
662.1712 +  if(link==vf->links)return(OV_EINVAL);
662.1713 +
662.1714 +  /* enough information to convert time offset to pcm offset */
662.1715 +  {
662.1716 +    ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
662.1717 +    return(ov_pcm_seek(vf,target));
662.1718 +  }
662.1719 +}
662.1720 +
662.1721 +/* page-granularity version of ov_time_seek
662.1722 +   returns zero on success, nonzero on failure */
662.1723 +int ov_time_seek_page(OggVorbis_File *vf,double seconds){
662.1724 +  /* translate time to PCM position and call ov_pcm_seek */
662.1725 +
662.1726 +  int link=-1;
662.1727 +  ogg_int64_t pcm_total=0;
662.1728 +  double time_total=0.;
662.1729 +
662.1730 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1731 +  if(!vf->seekable)return(OV_ENOSEEK);
662.1732 +  if(seconds<0)return(OV_EINVAL);
662.1733 +
662.1734 +  /* which bitstream section does this time offset occur in? */
662.1735 +  for(link=0;link<vf->links;link++){
662.1736 +    double addsec = ov_time_total(vf,link);
662.1737 +    if(seconds<time_total+addsec)break;
662.1738 +    time_total+=addsec;
662.1739 +    pcm_total+=vf->pcmlengths[link*2+1];
662.1740 +  }
662.1741 +
662.1742 +  if(link==vf->links)return(OV_EINVAL);
662.1743 +
662.1744 +  /* enough information to convert time offset to pcm offset */
662.1745 +  {
662.1746 +    ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
662.1747 +    return(ov_pcm_seek_page(vf,target));
662.1748 +  }
662.1749 +}
662.1750 +
662.1751 +/* tell the current stream offset cursor.  Note that seek followed by
662.1752 +   tell will likely not give the set offset due to caching */
662.1753 +ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
662.1754 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1755 +  return(vf->offset);
662.1756 +}
662.1757 +
662.1758 +/* return PCM offset (sample) of next PCM sample to be read */
662.1759 +ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
662.1760 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1761 +  return(vf->pcm_offset);
662.1762 +}
662.1763 +
662.1764 +/* return time offset (seconds) of next PCM sample to be read */
662.1765 +double ov_time_tell(OggVorbis_File *vf){
662.1766 +  int link=0;
662.1767 +  ogg_int64_t pcm_total=0;
662.1768 +  double time_total=0.f;
662.1769 +
662.1770 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1771 +  if(vf->seekable){
662.1772 +    pcm_total=ov_pcm_total(vf,-1);
662.1773 +    time_total=ov_time_total(vf,-1);
662.1774 +
662.1775 +    /* which bitstream section does this time offset occur in? */
662.1776 +    for(link=vf->links-1;link>=0;link--){
662.1777 +      pcm_total-=vf->pcmlengths[link*2+1];
662.1778 +      time_total-=ov_time_total(vf,link);
662.1779 +      if(vf->pcm_offset>=pcm_total)break;
662.1780 +    }
662.1781 +  }
662.1782 +
662.1783 +  return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
662.1784 +}
662.1785 +
662.1786 +/*  link:   -1) return the vorbis_info struct for the bitstream section
662.1787 +                currently being decoded
662.1788 +           0-n) to request information for a specific bitstream section
662.1789 +
662.1790 +    In the case of a non-seekable bitstream, any call returns the
662.1791 +    current bitstream.  NULL in the case that the machine is not
662.1792 +    initialized */
662.1793 +
662.1794 +vorbis_info *ov_info(OggVorbis_File *vf,int link){
662.1795 +  if(vf->seekable){
662.1796 +    if(link<0)
662.1797 +      if(vf->ready_state>=STREAMSET)
662.1798 +        return vf->vi+vf->current_link;
662.1799 +      else
662.1800 +      return vf->vi;
662.1801 +    else
662.1802 +      if(link>=vf->links)
662.1803 +        return NULL;
662.1804 +      else
662.1805 +        return vf->vi+link;
662.1806 +  }else{
662.1807 +    return vf->vi;
662.1808 +  }
662.1809 +}
662.1810 +
662.1811 +/* grr, strong typing, grr, no templates/inheritence, grr */
662.1812 +vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
662.1813 +  if(vf->seekable){
662.1814 +    if(link<0)
662.1815 +      if(vf->ready_state>=STREAMSET)
662.1816 +        return vf->vc+vf->current_link;
662.1817 +      else
662.1818 +        return vf->vc;
662.1819 +    else
662.1820 +      if(link>=vf->links)
662.1821 +        return NULL;
662.1822 +      else
662.1823 +        return vf->vc+link;
662.1824 +  }else{
662.1825 +    return vf->vc;
662.1826 +  }
662.1827 +}
662.1828 +
662.1829 +static int host_is_big_endian() {
662.1830 +  ogg_int32_t pattern = 0xfeedface; /* deadbeef */
662.1831 +  unsigned char *bytewise = (unsigned char *)&pattern;
662.1832 +  if (bytewise[0] == 0xfe) return 1;
662.1833 +  return 0;
662.1834 +}
662.1835 +
662.1836 +/* up to this point, everything could more or less hide the multiple
662.1837 +   logical bitstream nature of chaining from the toplevel application
662.1838 +   if the toplevel application didn't particularly care.  However, at
662.1839 +   the point that we actually read audio back, the multiple-section
662.1840 +   nature must surface: Multiple bitstream sections do not necessarily
662.1841 +   have to have the same number of channels or sampling rate.
662.1842 +
662.1843 +   ov_read returns the sequential logical bitstream number currently
662.1844 +   being decoded along with the PCM data in order that the toplevel
662.1845 +   application can take action on channel/sample rate changes.  This
662.1846 +   number will be incremented even for streamed (non-seekable) streams
662.1847 +   (for seekable streams, it represents the actual logical bitstream
662.1848 +   index within the physical bitstream.  Note that the accessor
662.1849 +   functions above are aware of this dichotomy).
662.1850 +
662.1851 +   ov_read_filter is exactly the same as ov_read except that it processes
662.1852 +   the decoded audio data through a filter before packing it into the
662.1853 +   requested format. This gives greater accuracy than applying a filter
662.1854 +   after the audio has been converted into integral PCM.
662.1855 +
662.1856 +   input values: buffer) a buffer to hold packed PCM data for return
662.1857 +                 length) the byte length requested to be placed into buffer
662.1858 +                 bigendianp) should the data be packed LSB first (0) or
662.1859 +                             MSB first (1)
662.1860 +                 word) word size for output.  currently 1 (byte) or
662.1861 +                       2 (16 bit short)
662.1862 +
662.1863 +   return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
662.1864 +                   0) EOF
662.1865 +                   n) number of bytes of PCM actually returned.  The
662.1866 +                   below works on a packet-by-packet basis, so the
662.1867 +                   return length is not related to the 'length' passed
662.1868 +                   in, just guaranteed to fit.
662.1869 +
662.1870 +            *section) set to the logical bitstream number */
662.1871 +
662.1872 +long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
662.1873 +                    int bigendianp,int word,int sgned,int *bitstream,
662.1874 +                    void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){
662.1875 +  int i,j;
662.1876 +  int host_endian = host_is_big_endian();
662.1877 +  int hs;
662.1878 +
662.1879 +  float **pcm;
662.1880 +  long samples;
662.1881 +
662.1882 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.1883 +
662.1884 +  while(1){
662.1885 +    if(vf->ready_state==INITSET){
662.1886 +      samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
662.1887 +      if(samples)break;
662.1888 +    }
662.1889 +
662.1890 +    /* suck in another packet */
662.1891 +    {
662.1892 +      int ret=_fetch_and_process_packet(vf,NULL,1,1);
662.1893 +      if(ret==OV_EOF)
662.1894 +        return(0);
662.1895 +      if(ret<=0)
662.1896 +        return(ret);
662.1897 +    }
662.1898 +
662.1899 +  }
662.1900 +
662.1901 +  if(samples>0){
662.1902 +
662.1903 +    /* yay! proceed to pack data into the byte buffer */
662.1904 +
662.1905 +    long channels=ov_info(vf,-1)->channels;
662.1906 +    long bytespersample=word * channels;
662.1907 +    vorbis_fpu_control fpu;
662.1908 +    if(samples>length/bytespersample)samples=length/bytespersample;
662.1909 +
662.1910 +    if(samples <= 0)
662.1911 +      return OV_EINVAL;
662.1912 +
662.1913 +    /* Here. */
662.1914 +    if(filter)
662.1915 +      filter(pcm,channels,samples,filter_param);
662.1916 +
662.1917 +    /* a tight loop to pack each size */
662.1918 +    {
662.1919 +      int val;
662.1920 +      if(word==1){
662.1921 +        int off=(sgned?0:128);
662.1922 +        vorbis_fpu_setround(&fpu);
662.1923 +        for(j=0;j<samples;j++)
662.1924 +          for(i=0;i<channels;i++){
662.1925 +            val=vorbis_ftoi(pcm[i][j]*128.f);
662.1926 +            if(val>127)val=127;
662.1927 +            else if(val<-128)val=-128;
662.1928 +            *buffer++=val+off;
662.1929 +          }
662.1930 +        vorbis_fpu_restore(fpu);
662.1931 +      }else{
662.1932 +        int off=(sgned?0:32768);
662.1933 +
662.1934 +        if(host_endian==bigendianp){
662.1935 +          if(sgned){
662.1936 +
662.1937 +            vorbis_fpu_setround(&fpu);
662.1938 +            for(i=0;i<channels;i++) { /* It's faster in this order */
662.1939 +              float *src=pcm[i];
662.1940 +              short *dest=((short *)buffer)+i;
662.1941 +              for(j=0;j<samples;j++) {
662.1942 +                val=vorbis_ftoi(src[j]*32768.f);
662.1943 +                if(val>32767)val=32767;
662.1944 +                else if(val<-32768)val=-32768;
662.1945 +                *dest=val;
662.1946 +                dest+=channels;
662.1947 +              }
662.1948 +            }
662.1949 +            vorbis_fpu_restore(fpu);
662.1950 +
662.1951 +          }else{
662.1952 +
662.1953 +            vorbis_fpu_setround(&fpu);
662.1954 +            for(i=0;i<channels;i++) {
662.1955 +              float *src=pcm[i];
662.1956 +              short *dest=((short *)buffer)+i;
662.1957 +              for(j=0;j<samples;j++) {
662.1958 +                val=vorbis_ftoi(src[j]*32768.f);
662.1959 +                if(val>32767)val=32767;
662.1960 +                else if(val<-32768)val=-32768;
662.1961 +                *dest=val+off;
662.1962 +                dest+=channels;
662.1963 +              }
662.1964 +            }
662.1965 +            vorbis_fpu_restore(fpu);
662.1966 +
662.1967 +          }
662.1968 +        }else if(bigendianp){
662.1969 +
662.1970 +          vorbis_fpu_setround(&fpu);
662.1971 +          for(j=0;j<samples;j++)
662.1972 +            for(i=0;i<channels;i++){
662.1973 +              val=vorbis_ftoi(pcm[i][j]*32768.f);
662.1974 +              if(val>32767)val=32767;
662.1975 +              else if(val<-32768)val=-32768;
662.1976 +              val+=off;
662.1977 +              *buffer++=(val>>8);
662.1978 +              *buffer++=(val&0xff);
662.1979 +            }
662.1980 +          vorbis_fpu_restore(fpu);
662.1981 +
662.1982 +        }else{
662.1983 +          int val;
662.1984 +          vorbis_fpu_setround(&fpu);
662.1985 +          for(j=0;j<samples;j++)
662.1986 +            for(i=0;i<channels;i++){
662.1987 +              val=vorbis_ftoi(pcm[i][j]*32768.f);
662.1988 +              if(val>32767)val=32767;
662.1989 +              else if(val<-32768)val=-32768;
662.1990 +              val+=off;
662.1991 +              *buffer++=(val&0xff);
662.1992 +              *buffer++=(val>>8);
662.1993 +                  }
662.1994 +          vorbis_fpu_restore(fpu);
662.1995 +
662.1996 +        }
662.1997 +      }
662.1998 +    }
662.1999 +
662.2000 +    vorbis_synthesis_read(&vf->vd,samples);
662.2001 +    hs=vorbis_synthesis_halfrate_p(vf->vi);
662.2002 +    vf->pcm_offset+=(samples<<hs);
662.2003 +    if(bitstream)*bitstream=vf->current_link;
662.2004 +    return(samples*bytespersample);
662.2005 +  }else{
662.2006 +    return(samples);
662.2007 +  }
662.2008 +}
662.2009 +
662.2010 +long ov_read(OggVorbis_File *vf,char *buffer,int length,
662.2011 +             int bigendianp,int word,int sgned,int *bitstream){
662.2012 +  return ov_read_filter(vf, buffer, length, bigendianp, word, sgned, bitstream, NULL, NULL);
662.2013 +}
662.2014 +
662.2015 +/* input values: pcm_channels) a float vector per channel of output
662.2016 +                 length) the sample length being read by the app
662.2017 +
662.2018 +   return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
662.2019 +                   0) EOF
662.2020 +                   n) number of samples of PCM actually returned.  The
662.2021 +                   below works on a packet-by-packet basis, so the
662.2022 +                   return length is not related to the 'length' passed
662.2023 +                   in, just guaranteed to fit.
662.2024 +
662.2025 +            *section) set to the logical bitstream number */
662.2026 +
662.2027 +
662.2028 +
662.2029 +long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
662.2030 +                   int *bitstream){
662.2031 +
662.2032 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.2033 +
662.2034 +  while(1){
662.2035 +    if(vf->ready_state==INITSET){
662.2036 +      float **pcm;
662.2037 +      long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
662.2038 +      if(samples){
662.2039 +        int hs=vorbis_synthesis_halfrate_p(vf->vi);
662.2040 +        if(pcm_channels)*pcm_channels=pcm;
662.2041 +        if(samples>length)samples=length;
662.2042 +        vorbis_synthesis_read(&vf->vd,samples);
662.2043 +        vf->pcm_offset+=samples<<hs;
662.2044 +        if(bitstream)*bitstream=vf->current_link;
662.2045 +        return samples;
662.2046 +
662.2047 +      }
662.2048 +    }
662.2049 +
662.2050 +    /* suck in another packet */
662.2051 +    {
662.2052 +      int ret=_fetch_and_process_packet(vf,NULL,1,1);
662.2053 +      if(ret==OV_EOF)return(0);
662.2054 +      if(ret<=0)return(ret);
662.2055 +    }
662.2056 +
662.2057 +  }
662.2058 +}
662.2059 +
662.2060 +extern float *vorbis_window(vorbis_dsp_state *v,int W);
662.2061 +
662.2062 +static void _ov_splice(float **pcm,float **lappcm,
662.2063 +                       int n1, int n2,
662.2064 +                       int ch1, int ch2,
662.2065 +                       float *w1, float *w2){
662.2066 +  int i,j;
662.2067 +  float *w=w1;
662.2068 +  int n=n1;
662.2069 +
662.2070 +  if(n1>n2){
662.2071 +    n=n2;
662.2072 +    w=w2;
662.2073 +  }
662.2074 +
662.2075 +  /* splice */
662.2076 +  for(j=0;j<ch1 && j<ch2;j++){
662.2077 +    float *s=lappcm[j];
662.2078 +    float *d=pcm[j];
662.2079 +
662.2080 +    for(i=0;i<n;i++){
662.2081 +      float wd=w[i]*w[i];
662.2082 +      float ws=1.-wd;
662.2083 +      d[i]=d[i]*wd + s[i]*ws;
662.2084 +    }
662.2085 +  }
662.2086 +  /* window from zero */
662.2087 +  for(;j<ch2;j++){
662.2088 +    float *d=pcm[j];
662.2089 +    for(i=0;i<n;i++){
662.2090 +      float wd=w[i]*w[i];
662.2091 +      d[i]=d[i]*wd;
662.2092 +    }
662.2093 +  }
662.2094 +
662.2095 +}
662.2096 +
662.2097 +/* make sure vf is INITSET */
662.2098 +static int _ov_initset(OggVorbis_File *vf){
662.2099 +  while(1){
662.2100 +    if(vf->ready_state==INITSET)break;
662.2101 +    /* suck in another packet */
662.2102 +    {
662.2103 +      int ret=_fetch_and_process_packet(vf,NULL,1,0);
662.2104 +      if(ret<0 && ret!=OV_HOLE)return(ret);
662.2105 +    }
662.2106 +  }
662.2107 +  return 0;
662.2108 +}
662.2109 +
662.2110 +/* make sure vf is INITSET and that we have a primed buffer; if
662.2111 +   we're crosslapping at a stream section boundary, this also makes
662.2112 +   sure we're sanity checking against the right stream information */
662.2113 +static int _ov_initprime(OggVorbis_File *vf){
662.2114 +  vorbis_dsp_state *vd=&vf->vd;
662.2115 +  while(1){
662.2116 +    if(vf->ready_state==INITSET)
662.2117 +      if(vorbis_synthesis_pcmout(vd,NULL))break;
662.2118 +
662.2119 +    /* suck in another packet */
662.2120 +    {
662.2121 +      int ret=_fetch_and_process_packet(vf,NULL,1,0);
662.2122 +      if(ret<0 && ret!=OV_HOLE)return(ret);
662.2123 +    }
662.2124 +  }
662.2125 +  return 0;
662.2126 +}
662.2127 +
662.2128 +/* grab enough data for lapping from vf; this may be in the form of
662.2129 +   unreturned, already-decoded pcm, remaining PCM we will need to
662.2130 +   decode, or synthetic postextrapolation from last packets. */
662.2131 +static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
662.2132 +                       float **lappcm,int lapsize){
662.2133 +  int lapcount=0,i;
662.2134 +  float **pcm;
662.2135 +
662.2136 +  /* try first to decode the lapping data */
662.2137 +  while(lapcount<lapsize){
662.2138 +    int samples=vorbis_synthesis_pcmout(vd,&pcm);
662.2139 +    if(samples){
662.2140 +      if(samples>lapsize-lapcount)samples=lapsize-lapcount;
662.2141 +      for(i=0;i<vi->channels;i++)
662.2142 +        memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
662.2143 +      lapcount+=samples;
662.2144 +      vorbis_synthesis_read(vd,samples);
662.2145 +    }else{
662.2146 +    /* suck in another packet */
662.2147 +      int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
662.2148 +      if(ret==OV_EOF)break;
662.2149 +    }
662.2150 +  }
662.2151 +  if(lapcount<lapsize){
662.2152 +    /* failed to get lapping data from normal decode; pry it from the
662.2153 +       postextrapolation buffering, or the second half of the MDCT
662.2154 +       from the last packet */
662.2155 +    int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
662.2156 +    if(samples==0){
662.2157 +      for(i=0;i<vi->channels;i++)
662.2158 +        memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
662.2159 +      lapcount=lapsize;
662.2160 +    }else{
662.2161 +      if(samples>lapsize-lapcount)samples=lapsize-lapcount;
662.2162 +      for(i=0;i<vi->channels;i++)
662.2163 +        memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
662.2164 +      lapcount+=samples;
662.2165 +    }
662.2166 +  }
662.2167 +}
662.2168 +
662.2169 +/* this sets up crosslapping of a sample by using trailing data from
662.2170 +   sample 1 and lapping it into the windowing buffer of sample 2 */
662.2171 +int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
662.2172 +  vorbis_info *vi1,*vi2;
662.2173 +  float **lappcm;
662.2174 +  float **pcm;
662.2175 +  float *w1,*w2;
662.2176 +  int n1,n2,i,ret,hs1,hs2;
662.2177 +
662.2178 +  if(vf1==vf2)return(0); /* degenerate case */
662.2179 +  if(vf1->ready_state<OPENED)return(OV_EINVAL);
662.2180 +  if(vf2->ready_state<OPENED)return(OV_EINVAL);
662.2181 +
662.2182 +  /* the relevant overlap buffers must be pre-checked and pre-primed
662.2183 +     before looking at settings in the event that priming would cross
662.2184 +     a bitstream boundary.  So, do it now */
662.2185 +
662.2186 +  ret=_ov_initset(vf1);
662.2187 +  if(ret)return(ret);
662.2188 +  ret=_ov_initprime(vf2);
662.2189 +  if(ret)return(ret);
662.2190 +
662.2191 +  vi1=ov_info(vf1,-1);
662.2192 +  vi2=ov_info(vf2,-1);
662.2193 +  hs1=ov_halfrate_p(vf1);
662.2194 +  hs2=ov_halfrate_p(vf2);
662.2195 +
662.2196 +  lappcm=alloca(sizeof(*lappcm)*vi1->channels);
662.2197 +  n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
662.2198 +  n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
662.2199 +  w1=vorbis_window(&vf1->vd,0);
662.2200 +  w2=vorbis_window(&vf2->vd,0);
662.2201 +
662.2202 +  for(i=0;i<vi1->channels;i++)
662.2203 +    lappcm[i]=alloca(sizeof(**lappcm)*n1);
662.2204 +
662.2205 +  _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
662.2206 +
662.2207 +  /* have a lapping buffer from vf1; now to splice it into the lapping
662.2208 +     buffer of vf2 */
662.2209 +  /* consolidate and expose the buffer. */
662.2210 +  vorbis_synthesis_lapout(&vf2->vd,&pcm);
662.2211 +
662.2212 +#if 0
662.2213 +  _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
662.2214 +  _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
662.2215 +#endif
662.2216 +
662.2217 +  /* splice */
662.2218 +  _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
662.2219 +
662.2220 +  /* done */
662.2221 +  return(0);
662.2222 +}
662.2223 +
662.2224 +static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
662.2225 +                           int (*localseek)(OggVorbis_File *,ogg_int64_t)){
662.2226 +  vorbis_info *vi;
662.2227 +  float **lappcm;
662.2228 +  float **pcm;
662.2229 +  float *w1,*w2;
662.2230 +  int n1,n2,ch1,ch2,hs;
662.2231 +  int i,ret;
662.2232 +
662.2233 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.2234 +  ret=_ov_initset(vf);
662.2235 +  if(ret)return(ret);
662.2236 +  vi=ov_info(vf,-1);
662.2237 +  hs=ov_halfrate_p(vf);
662.2238 +
662.2239 +  ch1=vi->channels;
662.2240 +  n1=vorbis_info_blocksize(vi,0)>>(1+hs);
662.2241 +  w1=vorbis_window(&vf->vd,0);  /* window arrays from libvorbis are
662.2242 +                                   persistent; even if the decode state
662.2243 +                                   from this link gets dumped, this
662.2244 +                                   window array continues to exist */
662.2245 +
662.2246 +  lappcm=alloca(sizeof(*lappcm)*ch1);
662.2247 +  for(i=0;i<ch1;i++)
662.2248 +    lappcm[i]=alloca(sizeof(**lappcm)*n1);
662.2249 +  _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
662.2250 +
662.2251 +  /* have lapping data; seek and prime the buffer */
662.2252 +  ret=localseek(vf,pos);
662.2253 +  if(ret)return ret;
662.2254 +  ret=_ov_initprime(vf);
662.2255 +  if(ret)return(ret);
662.2256 +
662.2257 + /* Guard against cross-link changes; they're perfectly legal */
662.2258 +  vi=ov_info(vf,-1);
662.2259 +  ch2=vi->channels;
662.2260 +  n2=vorbis_info_blocksize(vi,0)>>(1+hs);
662.2261 +  w2=vorbis_window(&vf->vd,0);
662.2262 +
662.2263 +  /* consolidate and expose the buffer. */
662.2264 +  vorbis_synthesis_lapout(&vf->vd,&pcm);
662.2265 +
662.2266 +  /* splice */
662.2267 +  _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
662.2268 +
662.2269 +  /* done */
662.2270 +  return(0);
662.2271 +}
662.2272 +
662.2273 +int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
662.2274 +  return _ov_64_seek_lap(vf,pos,ov_raw_seek);
662.2275 +}
662.2276 +
662.2277 +int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
662.2278 +  return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
662.2279 +}
662.2280 +
662.2281 +int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
662.2282 +  return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
662.2283 +}
662.2284 +
662.2285 +static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
662.2286 +                           int (*localseek)(OggVorbis_File *,double)){
662.2287 +  vorbis_info *vi;
662.2288 +  float **lappcm;
662.2289 +  float **pcm;
662.2290 +  float *w1,*w2;
662.2291 +  int n1,n2,ch1,ch2,hs;
662.2292 +  int i,ret;
662.2293 +
662.2294 +  if(vf->ready_state<OPENED)return(OV_EINVAL);
662.2295 +  ret=_ov_initset(vf);
662.2296 +  if(ret)return(ret);
662.2297 +  vi=ov_info(vf,-1);
662.2298 +  hs=ov_halfrate_p(vf);
662.2299 +
662.2300 +  ch1=vi->channels;
662.2301 +  n1=vorbis_info_blocksize(vi,0)>>(1+hs);
662.2302 +  w1=vorbis_window(&vf->vd,0);  /* window arrays from libvorbis are
662.2303 +                                   persistent; even if the decode state
662.2304 +                                   from this link gets dumped, this
662.2305 +                                   window array continues to exist */
662.2306 +
662.2307 +  lappcm=alloca(sizeof(*lappcm)*ch1);
662.2308 +  for(i=0;i<ch1;i++)
662.2309 +    lappcm[i]=alloca(sizeof(**lappcm)*n1);
662.2310 +  _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
662.2311 +
662.2312 +  /* have lapping data; seek and prime the buffer */
662.2313 +  ret=localseek(vf,pos);
662.2314 +  if(ret)return ret;
662.2315 +  ret=_ov_initprime(vf);
662.2316 +  if(ret)return(ret);
662.2317 +
662.2318 + /* Guard against cross-link changes; they're perfectly legal */
662.2319 +  vi=ov_info(vf,-1);
662.2320 +  ch2=vi->channels;
662.2321 +  n2=vorbis_info_blocksize(vi,0)>>(1+hs);
662.2322 +  w2=vorbis_window(&vf->vd,0);
662.2323 +
662.2324 +  /* consolidate and expose the buffer. */
662.2325 +  vorbis_synthesis_lapout(&vf->vd,&pcm);
662.2326 +
662.2327 +  /* splice */
662.2328 +  _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
662.2329 +
662.2330 +  /* done */
662.2331 +  return(0);
662.2332 +}
662.2333 +
662.2334 +int ov_time_seek_lap(OggVorbis_File *vf,double pos){
662.2335 +  return _ov_d_seek_lap(vf,pos,ov_time_seek);
662.2336 +}
662.2337 +
662.2338 +int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
662.2339 +  return _ov_d_seek_lap(vf,pos,ov_time_seek_page);
662.2340 +}
   663.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   663.2 +++ b/libs/vorbis/vorbisfile.h	Sat Feb 01 19:58:19 2014 +0200
   663.3 @@ -0,0 +1,206 @@
   663.4 +/********************************************************************
   663.5 + *                                                                  *
   663.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   663.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   663.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   663.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  663.10 + *                                                                  *
  663.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  663.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  663.13 + *                                                                  *
  663.14 + ********************************************************************
  663.15 +
  663.16 + function: stdio-based convenience library for opening/seeking/decoding
  663.17 + last mod: $Id: vorbisfile.h 17182 2010-04-29 03:48:32Z xiphmont $
  663.18 +
  663.19 + ********************************************************************/
  663.20 +
  663.21 +#ifndef _OV_FILE_H_
  663.22 +#define _OV_FILE_H_
  663.23 +
  663.24 +#ifdef __cplusplus
  663.25 +extern "C"
  663.26 +{
  663.27 +#endif /* __cplusplus */
  663.28 +
  663.29 +#include <stdio.h>
  663.30 +#include "codec.h"
  663.31 +
  663.32 +/* The function prototypes for the callbacks are basically the same as for
  663.33 + * the stdio functions fread, fseek, fclose, ftell.
  663.34 + * The one difference is that the FILE * arguments have been replaced with
  663.35 + * a void * - this is to be used as a pointer to whatever internal data these
  663.36 + * functions might need. In the stdio case, it's just a FILE * cast to a void *
  663.37 + *
  663.38 + * If you use other functions, check the docs for these functions and return
  663.39 + * the right values. For seek_func(), you *MUST* return -1 if the stream is
  663.40 + * unseekable
  663.41 + */
  663.42 +typedef struct {
  663.43 +  size_t (*read_func)  (void *ptr, size_t size, size_t nmemb, void *datasource);
  663.44 +  int    (*seek_func)  (void *datasource, ogg_int64_t offset, int whence);
  663.45 +  int    (*close_func) (void *datasource);
  663.46 +  long   (*tell_func)  (void *datasource);
  663.47 +} ov_callbacks;
  663.48 +
  663.49 +#ifndef OV_EXCLUDE_STATIC_CALLBACKS
  663.50 +
  663.51 +/* a few sets of convenient callbacks, especially for use under
  663.52 + * Windows where ov_open_callbacks() should always be used instead of
  663.53 + * ov_open() to avoid problems with incompatible crt.o version linking
  663.54 + * issues. */
  663.55 +
  663.56 +static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){
  663.57 +  if(f==NULL)return(-1);
  663.58 +
  663.59 +#ifdef __MINGW32__
  663.60 +  return fseeko64(f,off,whence);
  663.61 +#elif defined (_WIN32)
  663.62 +  return _fseeki64(f,off,whence);
  663.63 +#else
  663.64 +  return fseek(f,off,whence);
  663.65 +#endif
  663.66 +}
  663.67 +
  663.68 +/* These structs below (OV_CALLBACKS_DEFAULT etc) are defined here as
  663.69 + * static data. That means that every file which includes this header
  663.70 + * will get its own copy of these structs whether it uses them or
  663.71 + * not unless it #defines OV_EXCLUDE_STATIC_CALLBACKS.
  663.72 + * These static symbols are essential on platforms such as Windows on
  663.73 + * which several different versions of stdio support may be linked to
  663.74 + * by different DLLs, and we need to be certain we know which one
  663.75 + * we're using (the same one as the main application).
  663.76 + */
  663.77 +
  663.78 +static ov_callbacks OV_CALLBACKS_DEFAULT = {
  663.79 +  (size_t (*)(void *, size_t, size_t, void *))  fread,
  663.80 +  (int (*)(void *, ogg_int64_t, int))           _ov_header_fseek_wrap,
  663.81 +  (int (*)(void *))                             fclose,
  663.82 +  (long (*)(void *))                            ftell
  663.83 +};
  663.84 +
  663.85 +static ov_callbacks OV_CALLBACKS_NOCLOSE = {
  663.86 +  (size_t (*)(void *, size_t, size_t, void *))  fread,
  663.87 +  (int (*)(void *, ogg_int64_t, int))           _ov_header_fseek_wrap,
  663.88 +  (int (*)(void *))                             NULL,
  663.89 +  (long (*)(void *))                            ftell
  663.90 +};
  663.91 +
  663.92 +static ov_callbacks OV_CALLBACKS_STREAMONLY = {
  663.93 +  (size_t (*)(void *, size_t, size_t, void *))  fread,
  663.94 +  (int (*)(void *, ogg_int64_t, int))           NULL,
  663.95 +  (int (*)(void *))                             fclose,
  663.96 +  (long (*)(void *))                            NULL
  663.97 +};
  663.98 +
  663.99 +static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = {
 663.100 +  (size_t (*)(void *, size_t, size_t, void *))  fread,
 663.101 +  (int (*)(void *, ogg_int64_t, int))           NULL,
 663.102 +  (int (*)(void *))                             NULL,
 663.103 +  (long (*)(void *))                            NULL
 663.104 +};
 663.105 +
 663.106 +#endif
 663.107 +
 663.108 +#define  NOTOPEN   0
 663.109 +#define  PARTOPEN  1
 663.110 +#define  OPENED    2
 663.111 +#define  STREAMSET 3
 663.112 +#define  INITSET   4
 663.113 +
 663.114 +typedef struct OggVorbis_File {
 663.115 +  void            *datasource; /* Pointer to a FILE *, etc. */
 663.116 +  int              seekable;
 663.117 +  ogg_int64_t      offset;
 663.118 +  ogg_int64_t      end;
 663.119 +  ogg_sync_state   oy;
 663.120 +
 663.121 +  /* If the FILE handle isn't seekable (eg, a pipe), only the current
 663.122 +     stream appears */
 663.123 +  int              links;
 663.124 +  ogg_int64_t     *offsets;
 663.125 +  ogg_int64_t     *dataoffsets;
 663.126 +  long            *serialnos;
 663.127 +  ogg_int64_t     *pcmlengths; /* overloaded to maintain binary
 663.128 +                                  compatibility; x2 size, stores both
 663.129 +                                  beginning and end values */
 663.130 +  vorbis_info     *vi;
 663.131 +  vorbis_comment  *vc;
 663.132 +
 663.133 +  /* Decoding working state local storage */
 663.134 +  ogg_int64_t      pcm_offset;
 663.135 +  int              ready_state;
 663.136 +  long             current_serialno;
 663.137 +  int              current_link;
 663.138 +
 663.139 +  double           bittrack;
 663.140 +  double           samptrack;
 663.141 +
 663.142 +  ogg_stream_state os; /* take physical pages, weld into a logical
 663.143 +                          stream of packets */
 663.144 +  vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
 663.145 +  vorbis_block     vb; /* local working space for packet->PCM decode */
 663.146 +
 663.147 +  ov_callbacks callbacks;
 663.148 +
 663.149 +} OggVorbis_File;
 663.150 +
 663.151 +
 663.152 +extern int ov_clear(OggVorbis_File *vf);
 663.153 +extern int ov_fopen(const char *path,OggVorbis_File *vf);
 663.154 +extern int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
 663.155 +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
 663.156 +                const char *initial, long ibytes, ov_callbacks callbacks);
 663.157 +
 663.158 +extern int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
 663.159 +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf,
 663.160 +                const char *initial, long ibytes, ov_callbacks callbacks);
 663.161 +extern int ov_test_open(OggVorbis_File *vf);
 663.162 +
 663.163 +extern long ov_bitrate(OggVorbis_File *vf,int i);
 663.164 +extern long ov_bitrate_instant(OggVorbis_File *vf);
 663.165 +extern long ov_streams(OggVorbis_File *vf);
 663.166 +extern long ov_seekable(OggVorbis_File *vf);
 663.167 +extern long ov_serialnumber(OggVorbis_File *vf,int i);
 663.168 +
 663.169 +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i);
 663.170 +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i);
 663.171 +extern double ov_time_total(OggVorbis_File *vf,int i);
 663.172 +
 663.173 +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos);
 663.174 +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos);
 663.175 +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos);
 663.176 +extern int ov_time_seek(OggVorbis_File *vf,double pos);
 663.177 +extern int ov_time_seek_page(OggVorbis_File *vf,double pos);
 663.178 +
 663.179 +extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos);
 663.180 +extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos);
 663.181 +extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos);
 663.182 +extern int ov_time_seek_lap(OggVorbis_File *vf,double pos);
 663.183 +extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos);
 663.184 +
 663.185 +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf);
 663.186 +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf);
 663.187 +extern double ov_time_tell(OggVorbis_File *vf);
 663.188 +
 663.189 +extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
 663.190 +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
 663.191 +
 663.192 +extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples,
 663.193 +                          int *bitstream);
 663.194 +extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
 663.195 +                          int bigendianp,int word,int sgned,int *bitstream,
 663.196 +                          void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param);
 663.197 +extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
 663.198 +                    int bigendianp,int word,int sgned,int *bitstream);
 663.199 +extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2);
 663.200 +
 663.201 +extern int ov_halfrate(OggVorbis_File *vf,int flag);
 663.202 +extern int ov_halfrate_p(OggVorbis_File *vf);
 663.203 +
 663.204 +#ifdef __cplusplus
 663.205 +}
 663.206 +#endif /* __cplusplus */
 663.207 +
 663.208 +#endif
 663.209 +
   664.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   664.2 +++ b/libs/vorbis/window.c	Sat Feb 01 19:58:19 2014 +0200
   664.3 @@ -0,0 +1,2135 @@
   664.4 +/********************************************************************
   664.5 + *                                                                  *
   664.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   664.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   664.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   664.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  664.10 + *                                                                  *
  664.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  664.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  664.13 + *                                                                  *
  664.14 + ********************************************************************
  664.15 +
  664.16 + function: window functions
  664.17 + last mod: $Id: window.c 16227 2009-07-08 06:58:46Z xiphmont $
  664.18 +
  664.19 + ********************************************************************/
  664.20 +
  664.21 +#include <stdlib.h>
  664.22 +#include <math.h>
  664.23 +#include "os.h"
  664.24 +#include "misc.h"
  664.25 +
  664.26 +static const float vwin64[32] = {
  664.27 +  0.0009460463F, 0.0085006468F, 0.0235352254F, 0.0458950567F,
  664.28 +  0.0753351908F, 0.1115073077F, 0.1539457973F, 0.2020557475F,
  664.29 +  0.2551056759F, 0.3122276645F, 0.3724270287F, 0.4346027792F,
  664.30 +  0.4975789974F, 0.5601459521F, 0.6211085051F, 0.6793382689F,
  664.31 +  0.7338252629F, 0.7837245849F, 0.8283939355F, 0.8674186656F,
  664.32 +  0.9006222429F, 0.9280614787F, 0.9500073081F, 0.9669131782F,
  664.33 +  0.9793740220F, 0.9880792941F, 0.9937636139F, 0.9971582668F,
  664.34 +  0.9989462667F, 0.9997230082F, 0.9999638688F, 0.9999995525F,
  664.35 +};
  664.36 +
  664.37 +static const float vwin128[64] = {
  664.38 +  0.0002365472F, 0.0021280687F, 0.0059065254F, 0.0115626550F,
  664.39 +  0.0190823442F, 0.0284463735F, 0.0396300935F, 0.0526030430F,
  664.40 +  0.0673285281F, 0.0837631763F, 0.1018564887F, 0.1215504095F,
  664.41 +  0.1427789367F, 0.1654677960F, 0.1895342001F, 0.2148867160F,
  664.42 +  0.2414252576F, 0.2690412240F, 0.2976177952F, 0.3270303960F,
  664.43 +  0.3571473350F, 0.3878306189F, 0.4189369387F, 0.4503188188F,
  664.44 +  0.4818259135F, 0.5133064334F, 0.5446086751F, 0.5755826278F,
  664.45 +  0.6060816248F, 0.6359640047F, 0.6650947483F, 0.6933470543F,
  664.46 +  0.7206038179F, 0.7467589810F, 0.7717187213F, 0.7954024542F,
  664.47 +  0.8177436264F, 0.8386902831F, 0.8582053981F, 0.8762669622F,
  664.48 +  0.8928678298F, 0.9080153310F, 0.9217306608F, 0.9340480615F,
  664.49 +  0.9450138200F, 0.9546851041F, 0.9631286621F, 0.9704194171F,
  664.50 +  0.9766389810F, 0.9818741197F, 0.9862151938F, 0.9897546035F,
  664.51 +  0.9925852598F, 0.9947991032F, 0.9964856900F, 0.9977308602F,
  664.52 +  0.9986155015F, 0.9992144193F, 0.9995953200F, 0.9998179155F,
  664.53 +  0.9999331503F, 0.9999825563F, 0.9999977357F, 0.9999999720F,
  664.54 +};
  664.55 +
  664.56 +static const float vwin256[128] = {
  664.57 +  0.0000591390F, 0.0005321979F, 0.0014780301F, 0.0028960636F,
  664.58 +  0.0047854363F, 0.0071449926F, 0.0099732775F, 0.0132685298F,
  664.59 +  0.0170286741F, 0.0212513119F, 0.0259337111F, 0.0310727950F,
  664.60 +  0.0366651302F, 0.0427069140F, 0.0491939614F, 0.0561216907F,
  664.61 +  0.0634851102F, 0.0712788035F, 0.0794969160F, 0.0881331402F,
  664.62 +  0.0971807028F, 0.1066323515F, 0.1164803426F, 0.1267164297F,
  664.63 +  0.1373318534F, 0.1483173323F, 0.1596630553F, 0.1713586755F,
  664.64 +  0.1833933062F, 0.1957555184F, 0.2084333404F, 0.2214142599F,
  664.65 +  0.2346852280F, 0.2482326664F, 0.2620424757F, 0.2761000481F,
  664.66 +  0.2903902813F, 0.3048975959F, 0.3196059553F, 0.3344988887F,
  664.67 +  0.3495595160F, 0.3647705766F, 0.3801144597F, 0.3955732382F,
  664.68 +  0.4111287047F, 0.4267624093F, 0.4424557009F, 0.4581897696F,
  664.69 +  0.4739456913F, 0.4897044744F, 0.5054471075F, 0.5211546088F,
  664.70 +  0.5368080763F, 0.5523887395F, 0.5678780103F, 0.5832575361F,
  664.71 +  0.5985092508F, 0.6136154277F, 0.6285587300F, 0.6433222619F,
  664.72 +  0.6578896175F, 0.6722449294F, 0.6863729144F, 0.7002589187F,
  664.73 +  0.7138889597F, 0.7272497662F, 0.7403288154F, 0.7531143679F,
  664.74 +  0.7655954985F, 0.7777621249F, 0.7896050322F, 0.8011158947F,
  664.75 +  0.8122872932F, 0.8231127294F, 0.8335866365F, 0.8437043850F,
  664.76 +  0.8534622861F, 0.8628575905F, 0.8718884835F, 0.8805540765F,
  664.77 +  0.8888543947F, 0.8967903616F, 0.9043637797F, 0.9115773078F,
  664.78 +  0.9184344360F, 0.9249394562F, 0.9310974312F, 0.9369141608F,
  664.79 +  0.9423961446F, 0.9475505439F, 0.9523851406F, 0.9569082947F,
  664.80 +  0.9611289005F, 0.9650563408F, 0.9687004405F, 0.9720714191F,
  664.81 +  0.9751798427F, 0.9780365753F, 0.9806527301F, 0.9830396204F,
  664.82 +  0.9852087111F, 0.9871715701F, 0.9889398207F, 0.9905250941F,
  664.83 +  0.9919389832F, 0.9931929973F, 0.9942985174F, 0.9952667537F,
  664.84 +  0.9961087037F, 0.9968351119F, 0.9974564312F, 0.9979827858F,
  664.85 +  0.9984239359F, 0.9987892441F, 0.9990876435F, 0.9993276081F,
  664.86 +  0.9995171241F, 0.9996636648F, 0.9997741654F, 0.9998550016F,
  664.87 +  0.9999119692F, 0.9999502656F, 0.9999744742F, 0.9999885497F,
  664.88 +  0.9999958064F, 0.9999989077F, 0.9999998584F, 0.9999999983F,
  664.89 +};
  664.90 +
  664.91 +static const float vwin512[256] = {
  664.92 +  0.0000147849F, 0.0001330607F, 0.0003695946F, 0.0007243509F,
  664.93 +  0.0011972759F, 0.0017882983F, 0.0024973285F, 0.0033242588F,
  664.94 +  0.0042689632F, 0.0053312973F, 0.0065110982F, 0.0078081841F,
  664.95 +  0.0092223540F, 0.0107533880F, 0.0124010466F, 0.0141650703F,
  664.96 +  0.0160451800F, 0.0180410758F, 0.0201524373F, 0.0223789233F,
  664.97 +  0.0247201710F, 0.0271757958F, 0.0297453914F, 0.0324285286F,
  664.98 +  0.0352247556F, 0.0381335972F, 0.0411545545F, 0.0442871045F,
  664.99 +  0.0475306997F, 0.0508847676F, 0.0543487103F, 0.0579219038F,
 664.100 +  0.0616036982F, 0.0653934164F, 0.0692903546F, 0.0732937809F,
 664.101 +  0.0774029356F, 0.0816170305F, 0.0859352485F, 0.0903567428F,
 664.102 +  0.0948806375F, 0.0995060259F, 0.1042319712F, 0.1090575056F,
 664.103 +  0.1139816300F, 0.1190033137F, 0.1241214941F, 0.1293350764F,
 664.104 +  0.1346429333F, 0.1400439046F, 0.1455367974F, 0.1511203852F,
 664.105 +  0.1567934083F, 0.1625545735F, 0.1684025537F, 0.1743359881F,
 664.106 +  0.1803534820F, 0.1864536069F, 0.1926349000F, 0.1988958650F,
 664.107 +  0.2052349715F, 0.2116506555F, 0.2181413191F, 0.2247053313F,
 664.108 +  0.2313410275F, 0.2380467105F, 0.2448206500F, 0.2516610835F,
 664.109 +  0.2585662164F, 0.2655342226F, 0.2725632448F, 0.2796513950F,
 664.110 +  0.2867967551F, 0.2939973773F, 0.3012512852F, 0.3085564739F,
 664.111 +  0.3159109111F, 0.3233125375F, 0.3307592680F, 0.3382489922F,
 664.112 +  0.3457795756F, 0.3533488602F, 0.3609546657F, 0.3685947904F,
 664.113 +  0.3762670121F, 0.3839690896F, 0.3916987634F, 0.3994537572F,
 664.114 +  0.4072317788F, 0.4150305215F, 0.4228476653F, 0.4306808783F,
 664.115 +  0.4385278181F, 0.4463861329F, 0.4542534630F, 0.4621274424F,
 664.116 +  0.4700057001F, 0.4778858615F, 0.4857655502F, 0.4936423891F,
 664.117 +  0.5015140023F, 0.5093780165F, 0.5172320626F, 0.5250737772F,
 664.118 +  0.5329008043F, 0.5407107971F, 0.5485014192F, 0.5562703465F,
 664.119 +  0.5640152688F, 0.5717338914F, 0.5794239366F, 0.5870831457F,
 664.120 +  0.5947092801F, 0.6023001235F, 0.6098534829F, 0.6173671907F,
 664.121 +  0.6248391059F, 0.6322671161F, 0.6396491384F, 0.6469831217F,
 664.122 +  0.6542670475F, 0.6614989319F, 0.6686768267F, 0.6757988210F,
 664.123 +  0.6828630426F, 0.6898676592F, 0.6968108799F, 0.7036909564F,
 664.124 +  0.7105061843F, 0.7172549043F, 0.7239355032F, 0.7305464154F,
 664.125 +  0.7370861235F, 0.7435531598F, 0.7499461068F, 0.7562635986F,
 664.126 +  0.7625043214F, 0.7686670148F, 0.7747504721F, 0.7807535410F,
 664.127 +  0.7866751247F, 0.7925141825F, 0.7982697296F, 0.8039408387F,
 664.128 +  0.8095266395F, 0.8150263196F, 0.8204391248F, 0.8257643590F,
 664.129 +  0.8310013848F, 0.8361496236F, 0.8412085555F, 0.8461777194F,
 664.130 +  0.8510567129F, 0.8558451924F, 0.8605428730F, 0.8651495278F,
 664.131 +  0.8696649882F, 0.8740891432F, 0.8784219392F, 0.8826633797F,
 664.132 +  0.8868135244F, 0.8908724888F, 0.8948404441F, 0.8987176157F,
 664.133 +  0.9025042831F, 0.9062007791F, 0.9098074886F, 0.9133248482F,
 664.134 +  0.9167533451F, 0.9200935163F, 0.9233459472F, 0.9265112712F,
 664.135 +  0.9295901680F, 0.9325833632F, 0.9354916263F, 0.9383157705F,
 664.136 +  0.9410566504F, 0.9437151618F, 0.9462922398F, 0.9487888576F,
 664.137 +  0.9512060252F, 0.9535447882F, 0.9558062262F, 0.9579914516F,
 664.138 +  0.9601016078F, 0.9621378683F, 0.9641014348F, 0.9659935361F,
 664.139 +  0.9678154261F, 0.9695683830F, 0.9712537071F, 0.9728727198F,
 664.140 +  0.9744267618F, 0.9759171916F, 0.9773453842F, 0.9787127293F,
 664.141 +  0.9800206298F, 0.9812705006F, 0.9824637665F, 0.9836018613F,
 664.142 +  0.9846862258F, 0.9857183066F, 0.9866995544F, 0.9876314227F,
 664.143 +  0.9885153662F, 0.9893528393F, 0.9901452948F, 0.9908941823F,
 664.144 +  0.9916009470F, 0.9922670279F, 0.9928938570F, 0.9934828574F,
 664.145 +  0.9940354423F, 0.9945530133F, 0.9950369595F, 0.9954886562F,
 664.146 +  0.9959094633F, 0.9963007242F, 0.9966637649F, 0.9969998925F,
 664.147 +  0.9973103939F, 0.9975965351F, 0.9978595598F, 0.9981006885F,
 664.148 +  0.9983211172F, 0.9985220166F, 0.9987045311F, 0.9988697776F,
 664.149 +  0.9990188449F, 0.9991527924F, 0.9992726499F, 0.9993794157F,
 664.150 +  0.9994740570F, 0.9995575079F, 0.9996306699F, 0.9996944099F,
 664.151 +  0.9997495605F, 0.9997969190F, 0.9998372465F, 0.9998712678F,
 664.152 +  0.9998996704F, 0.9999231041F, 0.9999421807F, 0.9999574732F,
 664.153 +  0.9999695157F, 0.9999788026F, 0.9999857885F, 0.9999908879F,
 664.154 +  0.9999944746F, 0.9999968817F, 0.9999984010F, 0.9999992833F,
 664.155 +  0.9999997377F, 0.9999999317F, 0.9999999911F, 0.9999999999F,
 664.156 +};
 664.157 +
 664.158 +static const float vwin1024[512] = {
 664.159 +  0.0000036962F, 0.0000332659F, 0.0000924041F, 0.0001811086F,
 664.160 +  0.0002993761F, 0.0004472021F, 0.0006245811F, 0.0008315063F,
 664.161 +  0.0010679699F, 0.0013339631F, 0.0016294757F, 0.0019544965F,
 664.162 +  0.0023090133F, 0.0026930125F, 0.0031064797F, 0.0035493989F,
 664.163 +  0.0040217533F, 0.0045235250F, 0.0050546946F, 0.0056152418F,
 664.164 +  0.0062051451F, 0.0068243817F, 0.0074729278F, 0.0081507582F,
 664.165 +  0.0088578466F, 0.0095941655F, 0.0103596863F, 0.0111543789F,
 664.166 +  0.0119782122F, 0.0128311538F, 0.0137131701F, 0.0146242260F,
 664.167 +  0.0155642855F, 0.0165333111F, 0.0175312640F, 0.0185581042F,
 664.168 +  0.0196137903F, 0.0206982797F, 0.0218115284F, 0.0229534910F,
 664.169 +  0.0241241208F, 0.0253233698F, 0.0265511886F, 0.0278075263F,
 664.170 +  0.0290923308F, 0.0304055484F, 0.0317471241F, 0.0331170013F,
 664.171 +  0.0345151222F, 0.0359414274F, 0.0373958560F, 0.0388783456F,
 664.172 +  0.0403888325F, 0.0419272511F, 0.0434935347F, 0.0450876148F,
 664.173 +  0.0467094213F, 0.0483588828F, 0.0500359261F, 0.0517404765F,
 664.174 +  0.0534724575F, 0.0552317913F, 0.0570183983F, 0.0588321971F,
 664.175 +  0.0606731048F, 0.0625410369F, 0.0644359070F, 0.0663576272F,
 664.176 +  0.0683061077F, 0.0702812571F, 0.0722829821F, 0.0743111878F,
 664.177 +  0.0763657775F, 0.0784466526F, 0.0805537129F, 0.0826868561F,
 664.178 +  0.0848459782F, 0.0870309736F, 0.0892417345F, 0.0914781514F,
 664.179 +  0.0937401128F, 0.0960275056F, 0.0983402145F, 0.1006781223F,
 664.180 +  0.1030411101F, 0.1054290568F, 0.1078418397F, 0.1102793336F,
 664.181 +  0.1127414119F, 0.1152279457F, 0.1177388042F, 0.1202738544F,
 664.182 +  0.1228329618F, 0.1254159892F, 0.1280227980F, 0.1306532471F,
 664.183 +  0.1333071937F, 0.1359844927F, 0.1386849970F, 0.1414085575F,
 664.184 +  0.1441550230F, 0.1469242403F, 0.1497160539F, 0.1525303063F,
 664.185 +  0.1553668381F, 0.1582254875F, 0.1611060909F, 0.1640084822F,
 664.186 +  0.1669324936F, 0.1698779549F, 0.1728446939F, 0.1758325362F,
 664.187 +  0.1788413055F, 0.1818708232F, 0.1849209084F, 0.1879913785F,
 664.188 +  0.1910820485F, 0.1941927312F, 0.1973232376F, 0.2004733764F,
 664.189 +  0.2036429541F, 0.2068317752F, 0.2100396421F, 0.2132663552F,
 664.190 +  0.2165117125F, 0.2197755102F, 0.2230575422F, 0.2263576007F,
 664.191 +  0.2296754753F, 0.2330109540F, 0.2363638225F, 0.2397338646F,
 664.192 +  0.2431208619F, 0.2465245941F, 0.2499448389F, 0.2533813719F,
 664.193 +  0.2568339669F, 0.2603023956F, 0.2637864277F, 0.2672858312F,
 664.194 +  0.2708003718F, 0.2743298135F, 0.2778739186F, 0.2814324472F,
 664.195 +  0.2850051576F, 0.2885918065F, 0.2921921485F, 0.2958059366F,
 664.196 +  0.2994329219F, 0.3030728538F, 0.3067254799F, 0.3103905462F,
 664.197 +  0.3140677969F, 0.3177569747F, 0.3214578205F, 0.3251700736F,
 664.198 +  0.3288934718F, 0.3326277513F, 0.3363726468F, 0.3401278914F,
 664.199 +  0.3438932168F, 0.3476683533F, 0.3514530297F, 0.3552469734F,
 664.200 +  0.3590499106F, 0.3628615659F, 0.3666816630F, 0.3705099239F,
 664.201 +  0.3743460698F, 0.3781898204F, 0.3820408945F, 0.3858990095F,
 664.202 +  0.3897638820F, 0.3936352274F, 0.3975127601F, 0.4013961936F,
 664.203 +  0.4052852405F, 0.4091796123F, 0.4130790198F, 0.4169831732F,
 664.204 +  0.4208917815F, 0.4248045534F, 0.4287211965F, 0.4326414181F,
 664.205 +  0.4365649248F, 0.4404914225F, 0.4444206167F, 0.4483522125F,
 664.206 +  0.4522859146F, 0.4562214270F, 0.4601584538F, 0.4640966984F,
 664.207 +  0.4680358644F, 0.4719756548F, 0.4759157726F, 0.4798559209F,
 664.208 +  0.4837958024F, 0.4877351199F, 0.4916735765F, 0.4956108751F,
 664.209 +  0.4995467188F, 0.5034808109F, 0.5074128550F, 0.5113425550F,
 664.210 +  0.5152696149F, 0.5191937395F, 0.5231146336F, 0.5270320028F,
 664.211 +  0.5309455530F, 0.5348549910F, 0.5387600239F, 0.5426603597F,
 664.212 +  0.5465557070F, 0.5504457754F, 0.5543302752F, 0.5582089175F,
 664.213 +  0.5620814145F, 0.5659474793F, 0.5698068262F, 0.5736591704F,
 664.214 +  0.5775042283F, 0.5813417176F, 0.5851713571F, 0.5889928670F,
 664.215 +  0.5928059689F, 0.5966103856F, 0.6004058415F, 0.6041920626F,
 664.216 +  0.6079687761F, 0.6117357113F, 0.6154925986F, 0.6192391705F,
 664.217 +  0.6229751612F, 0.6267003064F, 0.6304143441F, 0.6341170137F,
 664.218 +  0.6378080569F, 0.6414872173F, 0.6451542405F, 0.6488088741F,
 664.219 +  0.6524508681F, 0.6560799742F, 0.6596959469F, 0.6632985424F,
 664.220 +  0.6668875197F, 0.6704626398F, 0.6740236662F, 0.6775703649F,
 664.221 +  0.6811025043F, 0.6846198554F, 0.6881221916F, 0.6916092892F,
 664.222 +  0.6950809269F, 0.6985368861F, 0.7019769510F, 0.7054009085F,
 664.223 +  0.7088085484F, 0.7121996632F, 0.7155740484F, 0.7189315023F,
 664.224 +  0.7222718263F, 0.7255948245F, 0.7289003043F, 0.7321880760F,
 664.225 +  0.7354579530F, 0.7387097518F, 0.7419432921F, 0.7451583966F,
 664.226 +  0.7483548915F, 0.7515326059F, 0.7546913723F, 0.7578310265F,
 664.227 +  0.7609514077F, 0.7640523581F, 0.7671337237F, 0.7701953535F,
 664.228 +  0.7732371001F, 0.7762588195F, 0.7792603711F, 0.7822416178F,
 664.229 +  0.7852024259F, 0.7881426654F, 0.7910622097F, 0.7939609356F,
 664.230 +  0.7968387237F, 0.7996954579F, 0.8025310261F, 0.8053453193F,
 664.231 +  0.8081382324F, 0.8109096638F, 0.8136595156F, 0.8163876936F,
 664.232 +  0.8190941071F, 0.8217786690F, 0.8244412960F, 0.8270819086F,
 664.233 +  0.8297004305F, 0.8322967896F, 0.8348709171F, 0.8374227481F,
 664.234 +  0.8399522213F, 0.8424592789F, 0.8449438672F, 0.8474059356F,
 664.235 +  0.8498454378F, 0.8522623306F, 0.8546565748F, 0.8570281348F,
 664.236 +  0.8593769787F, 0.8617030779F, 0.8640064080F, 0.8662869477F,
 664.237 +  0.8685446796F, 0.8707795899F, 0.8729916682F, 0.8751809079F,
 664.238 +  0.8773473059F, 0.8794908626F, 0.8816115819F, 0.8837094713F,
 664.239 +  0.8857845418F, 0.8878368079F, 0.8898662874F, 0.8918730019F,
 664.240 +  0.8938569760F, 0.8958182380F, 0.8977568194F, 0.8996727552F,
 664.241 +  0.9015660837F, 0.9034368465F, 0.9052850885F, 0.9071108577F,
 664.242 +  0.9089142057F, 0.9106951869F, 0.9124538591F, 0.9141902832F,
 664.243 +  0.9159045233F, 0.9175966464F, 0.9192667228F, 0.9209148257F,
 664.244 +  0.9225410313F, 0.9241454187F, 0.9257280701F, 0.9272890704F,
 664.245 +  0.9288285075F, 0.9303464720F, 0.9318430576F, 0.9333183603F,
 664.246 +  0.9347724792F, 0.9362055158F, 0.9376175745F, 0.9390087622F,
 664.247 +  0.9403791881F, 0.9417289644F, 0.9430582055F, 0.9443670283F,
 664.248 +  0.9456555521F, 0.9469238986F, 0.9481721917F, 0.9494005577F,
 664.249 +  0.9506091252F, 0.9517980248F, 0.9529673894F, 0.9541173540F,
 664.250 +  0.9552480557F, 0.9563596334F, 0.9574522282F, 0.9585259830F,
 664.251 +  0.9595810428F, 0.9606175542F, 0.9616356656F, 0.9626355274F,
 664.252 +  0.9636172915F, 0.9645811114F, 0.9655271425F, 0.9664555414F,
 664.253 +  0.9673664664F, 0.9682600774F, 0.9691365355F, 0.9699960034F,
 664.254 +  0.9708386448F, 0.9716646250F, 0.9724741103F, 0.9732672685F,
 664.255 +  0.9740442683F, 0.9748052795F, 0.9755504729F, 0.9762800205F,
 664.256 +  0.9769940950F, 0.9776928703F, 0.9783765210F, 0.9790452223F,
 664.257 +  0.9796991504F, 0.9803384823F, 0.9809633954F, 0.9815740679F,
 664.258 +  0.9821706784F, 0.9827534063F, 0.9833224312F, 0.9838779332F,
 664.259 +  0.9844200928F, 0.9849490910F, 0.9854651087F, 0.9859683274F,
 664.260 +  0.9864589286F, 0.9869370940F, 0.9874030054F, 0.9878568447F,
 664.261 +  0.9882987937F, 0.9887290343F, 0.9891477481F, 0.9895551169F,
 664.262 +  0.9899513220F, 0.9903365446F, 0.9907109658F, 0.9910747662F,
 664.263 +  0.9914281260F, 0.9917712252F, 0.9921042433F, 0.9924273593F,
 664.264 +  0.9927407516F, 0.9930445982F, 0.9933390763F, 0.9936243626F,
 664.265 +  0.9939006331F, 0.9941680631F, 0.9944268269F, 0.9946770982F,
 664.266 +  0.9949190498F, 0.9951528537F, 0.9953786808F, 0.9955967011F,
 664.267 +  0.9958070836F, 0.9960099963F, 0.9962056061F, 0.9963940787F,
 664.268 +  0.9965755786F, 0.9967502693F, 0.9969183129F, 0.9970798704F,
 664.269 +  0.9972351013F, 0.9973841640F, 0.9975272151F, 0.9976644103F,
 664.270 +  0.9977959036F, 0.9979218476F, 0.9980423932F, 0.9981576901F,
 664.271 +  0.9982678862F, 0.9983731278F, 0.9984735596F, 0.9985693247F,
 664.272 +  0.9986605645F, 0.9987474186F, 0.9988300248F, 0.9989085193F,
 664.273 +  0.9989830364F, 0.9990537085F, 0.9991206662F, 0.9991840382F,
 664.274 +  0.9992439513F, 0.9993005303F, 0.9993538982F, 0.9994041757F,
 664.275 +  0.9994514817F, 0.9994959330F, 0.9995376444F, 0.9995767286F,
 664.276 +  0.9996132960F, 0.9996474550F, 0.9996793121F, 0.9997089710F,
 664.277 +  0.9997365339F, 0.9997621003F, 0.9997857677F, 0.9998076311F,
 664.278 +  0.9998277836F, 0.9998463156F, 0.9998633155F, 0.9998788692F,
 664.279 +  0.9998930603F, 0.9999059701F, 0.9999176774F, 0.9999282586F,
 664.280 +  0.9999377880F, 0.9999463370F, 0.9999539749F, 0.9999607685F,
 664.281 +  0.9999667820F, 0.9999720773F, 0.9999767136F, 0.9999807479F,
 664.282 +  0.9999842344F, 0.9999872249F, 0.9999897688F, 0.9999919127F,
 664.283 +  0.9999937009F, 0.9999951749F, 0.9999963738F, 0.9999973342F,
 664.284 +  0.9999980900F, 0.9999986724F, 0.9999991103F, 0.9999994297F,
 664.285 +  0.9999996543F, 0.9999998049F, 0.9999999000F, 0.9999999552F,
 664.286 +  0.9999999836F, 0.9999999957F, 0.9999999994F, 1.0000000000F,
 664.287 +};
 664.288 +
 664.289 +static const float vwin2048[1024] = {
 664.290 +  0.0000009241F, 0.0000083165F, 0.0000231014F, 0.0000452785F,
 664.291 +  0.0000748476F, 0.0001118085F, 0.0001561608F, 0.0002079041F,
 664.292 +  0.0002670379F, 0.0003335617F, 0.0004074748F, 0.0004887765F,
 664.293 +  0.0005774661F, 0.0006735427F, 0.0007770054F, 0.0008878533F,
 664.294 +  0.0010060853F, 0.0011317002F, 0.0012646969F, 0.0014050742F,
 664.295 +  0.0015528307F, 0.0017079650F, 0.0018704756F, 0.0020403610F,
 664.296 +  0.0022176196F, 0.0024022497F, 0.0025942495F, 0.0027936173F,
 664.297 +  0.0030003511F, 0.0032144490F, 0.0034359088F, 0.0036647286F,
 664.298 +  0.0039009061F, 0.0041444391F, 0.0043953253F, 0.0046535621F,
 664.299 +  0.0049191472F, 0.0051920781F, 0.0054723520F, 0.0057599664F,
 664.300 +  0.0060549184F, 0.0063572052F, 0.0066668239F, 0.0069837715F,
 664.301 +  0.0073080449F, 0.0076396410F, 0.0079785566F, 0.0083247884F,
 664.302 +  0.0086783330F, 0.0090391871F, 0.0094073470F, 0.0097828092F,
 664.303 +  0.0101655700F, 0.0105556258F, 0.0109529726F, 0.0113576065F,
 664.304 +  0.0117695237F, 0.0121887200F, 0.0126151913F, 0.0130489335F,
 664.305 +  0.0134899422F, 0.0139382130F, 0.0143937415F, 0.0148565233F,
 664.306 +  0.0153265536F, 0.0158038279F, 0.0162883413F, 0.0167800889F,
 664.307 +  0.0172790660F, 0.0177852675F, 0.0182986882F, 0.0188193231F,
 664.308 +  0.0193471668F, 0.0198822141F, 0.0204244594F, 0.0209738974F,
 664.309 +  0.0215305225F, 0.0220943289F, 0.0226653109F, 0.0232434627F,
 664.310 +  0.0238287784F, 0.0244212519F, 0.0250208772F, 0.0256276481F,
 664.311 +  0.0262415582F, 0.0268626014F, 0.0274907711F, 0.0281260608F,
 664.312 +  0.0287684638F, 0.0294179736F, 0.0300745833F, 0.0307382859F,
 664.313 +  0.0314090747F, 0.0320869424F, 0.0327718819F, 0.0334638860F,
 664.314 +  0.0341629474F, 0.0348690586F, 0.0355822122F, 0.0363024004F,
 664.315 +  0.0370296157F, 0.0377638502F, 0.0385050960F, 0.0392533451F,
 664.316 +  0.0400085896F, 0.0407708211F, 0.0415400315F, 0.0423162123F,
 664.317 +  0.0430993552F, 0.0438894515F, 0.0446864926F, 0.0454904698F,
 664.318 +  0.0463013742F, 0.0471191969F, 0.0479439288F, 0.0487755607F,
 664.319 +  0.0496140836F, 0.0504594879F, 0.0513117642F, 0.0521709031F,
 664.320 +  0.0530368949F, 0.0539097297F, 0.0547893979F, 0.0556758894F,
 664.321 +  0.0565691941F, 0.0574693019F, 0.0583762026F, 0.0592898858F,
 664.322 +  0.0602103410F, 0.0611375576F, 0.0620715250F, 0.0630122324F,
 664.323 +  0.0639596688F, 0.0649138234F, 0.0658746848F, 0.0668422421F,
 664.324 +  0.0678164838F, 0.0687973985F, 0.0697849746F, 0.0707792005F,
 664.325 +  0.0717800645F, 0.0727875547F, 0.0738016591F, 0.0748223656F,
 664.326 +  0.0758496620F, 0.0768835359F, 0.0779239751F, 0.0789709668F,
 664.327 +  0.0800244985F, 0.0810845574F, 0.0821511306F, 0.0832242052F,
 664.328 +  0.0843037679F, 0.0853898056F, 0.0864823050F, 0.0875812525F,
 664.329 +  0.0886866347F, 0.0897984378F, 0.0909166480F, 0.0920412513F,
 664.330 +  0.0931722338F, 0.0943095813F, 0.0954532795F, 0.0966033140F,
 664.331 +  0.0977596702F, 0.0989223336F, 0.1000912894F, 0.1012665227F,
 664.332 +  0.1024480185F, 0.1036357616F, 0.1048297369F, 0.1060299290F,
 664.333 +  0.1072363224F, 0.1084489014F, 0.1096676504F, 0.1108925534F,
 664.334 +  0.1121235946F, 0.1133607577F, 0.1146040267F, 0.1158533850F,
 664.335 +  0.1171088163F, 0.1183703040F, 0.1196378312F, 0.1209113812F,
 664.336 +  0.1221909370F, 0.1234764815F, 0.1247679974F, 0.1260654674F,
 664.337 +  0.1273688740F, 0.1286781995F, 0.1299934263F, 0.1313145365F,
 664.338 +  0.1326415121F, 0.1339743349F, 0.1353129866F, 0.1366574490F,
 664.339 +  0.1380077035F, 0.1393637315F, 0.1407255141F, 0.1420930325F,
 664.340 +  0.1434662677F, 0.1448452004F, 0.1462298115F, 0.1476200814F,
 664.341 +  0.1490159906F, 0.1504175195F, 0.1518246482F, 0.1532373569F,
 664.342 +  0.1546556253F, 0.1560794333F, 0.1575087606F, 0.1589435866F,
 664.343 +  0.1603838909F, 0.1618296526F, 0.1632808509F, 0.1647374648F,
 664.344 +  0.1661994731F, 0.1676668546F, 0.1691395880F, 0.1706176516F,
 664.345 +  0.1721010238F, 0.1735896829F, 0.1750836068F, 0.1765827736F,
 664.346 +  0.1780871610F, 0.1795967468F, 0.1811115084F, 0.1826314234F,
 664.347 +  0.1841564689F, 0.1856866221F, 0.1872218600F, 0.1887621595F,
 664.348 +  0.1903074974F, 0.1918578503F, 0.1934131947F, 0.1949735068F,
 664.349 +  0.1965387630F, 0.1981089393F, 0.1996840117F, 0.2012639560F,
 664.350 +  0.2028487479F, 0.2044383630F, 0.2060327766F, 0.2076319642F,
 664.351 +  0.2092359007F, 0.2108445614F, 0.2124579211F, 0.2140759545F,
 664.352 +  0.2156986364F, 0.2173259411F, 0.2189578432F, 0.2205943168F,
 664.353 +  0.2222353361F, 0.2238808751F, 0.2255309076F, 0.2271854073F,
 664.354 +  0.2288443480F, 0.2305077030F, 0.2321754457F, 0.2338475493F,
 664.355 +  0.2355239869F, 0.2372047315F, 0.2388897560F, 0.2405790329F,
 664.356 +  0.2422725350F, 0.2439702347F, 0.2456721043F, 0.2473781159F,
 664.357 +  0.2490882418F, 0.2508024539F, 0.2525207240F, 0.2542430237F,
 664.358 +  0.2559693248F, 0.2576995986F, 0.2594338166F, 0.2611719498F,
 664.359 +  0.2629139695F, 0.2646598466F, 0.2664095520F, 0.2681630564F,
 664.360 +  0.2699203304F, 0.2716813445F, 0.2734460691F, 0.2752144744F,
 664.361 +  0.2769865307F, 0.2787622079F, 0.2805414760F, 0.2823243047F,
 664.362 +  0.2841106637F, 0.2859005227F, 0.2876938509F, 0.2894906179F,
 664.363 +  0.2912907928F, 0.2930943447F, 0.2949012426F, 0.2967114554F,
 664.364 +  0.2985249520F, 0.3003417009F, 0.3021616708F, 0.3039848301F,
 664.365 +  0.3058111471F, 0.3076405901F, 0.3094731273F, 0.3113087266F,
 664.366 +  0.3131473560F, 0.3149889833F, 0.3168335762F, 0.3186811024F,
 664.367 +  0.3205315294F, 0.3223848245F, 0.3242409552F, 0.3260998886F,
 664.368 +  0.3279615918F, 0.3298260319F, 0.3316931758F, 0.3335629903F,
 664.369 +  0.3354354423F, 0.3373104982F, 0.3391881247F, 0.3410682882F,
 664.370 +  0.3429509551F, 0.3448360917F, 0.3467236642F, 0.3486136387F,
 664.371 +  0.3505059811F, 0.3524006575F, 0.3542976336F, 0.3561968753F,
 664.372 +  0.3580983482F, 0.3600020179F, 0.3619078499F, 0.3638158096F,
 664.373 +  0.3657258625F, 0.3676379737F, 0.3695521086F, 0.3714682321F,
 664.374 +  0.3733863094F, 0.3753063055F, 0.3772281852F, 0.3791519134F,
 664.375 +  0.3810774548F, 0.3830047742F, 0.3849338362F, 0.3868646053F,
 664.376 +  0.3887970459F, 0.3907311227F, 0.3926667998F, 0.3946040417F,
 664.377 +  0.3965428125F, 0.3984830765F, 0.4004247978F, 0.4023679403F,
 664.378 +  0.4043124683F, 0.4062583455F, 0.4082055359F, 0.4101540034F,
 664.379 +  0.4121037117F, 0.4140546246F, 0.4160067058F, 0.4179599190F,
 664.380 +  0.4199142277F, 0.4218695956F, 0.4238259861F, 0.4257833627F,
 664.381 +  0.4277416888F, 0.4297009279F, 0.4316610433F, 0.4336219983F,
 664.382 +  0.4355837562F, 0.4375462803F, 0.4395095337F, 0.4414734797F,
 664.383 +  0.4434380815F, 0.4454033021F, 0.4473691046F, 0.4493354521F,
 664.384 +  0.4513023078F, 0.4532696345F, 0.4552373954F, 0.4572055533F,
 664.385 +  0.4591740713F, 0.4611429123F, 0.4631120393F, 0.4650814151F,
 664.386 +  0.4670510028F, 0.4690207650F, 0.4709906649F, 0.4729606651F,
 664.387 +  0.4749307287F, 0.4769008185F, 0.4788708972F, 0.4808409279F,
 664.388 +  0.4828108732F, 0.4847806962F, 0.4867503597F, 0.4887198264F,
 664.389 +  0.4906890593F, 0.4926580213F, 0.4946266753F, 0.4965949840F,
 664.390 +  0.4985629105F, 0.5005304176F, 0.5024974683F, 0.5044640255F,
 664.391 +  0.5064300522F, 0.5083955114F, 0.5103603659F, 0.5123245790F,
 664.392 +  0.5142881136F, 0.5162509328F, 0.5182129997F, 0.5201742774F,
 664.393 +  0.5221347290F, 0.5240943178F, 0.5260530070F, 0.5280107598F,
 664.394 +  0.5299675395F, 0.5319233095F, 0.5338780330F, 0.5358316736F,
 664.395 +  0.5377841946F, 0.5397355596F, 0.5416857320F, 0.5436346755F,
 664.396 +  0.5455823538F, 0.5475287304F, 0.5494737691F, 0.5514174337F,
 664.397 +  0.5533596881F, 0.5553004962F, 0.5572398218F, 0.5591776291F,
 664.398 +  0.5611138821F, 0.5630485449F, 0.5649815818F, 0.5669129570F,
 664.399 +  0.5688426349F, 0.5707705799F, 0.5726967564F, 0.5746211290F,
 664.400 +  0.5765436624F, 0.5784643212F, 0.5803830702F, 0.5822998743F,
 664.401 +  0.5842146984F, 0.5861275076F, 0.5880382669F, 0.5899469416F,
 664.402 +  0.5918534968F, 0.5937578981F, 0.5956601107F, 0.5975601004F,
 664.403 +  0.5994578326F, 0.6013532732F, 0.6032463880F, 0.6051371429F,
 664.404 +  0.6070255039F, 0.6089114372F, 0.6107949090F, 0.6126758856F,
 664.405 +  0.6145543334F, 0.6164302191F, 0.6183035092F, 0.6201741706F,
 664.406 +  0.6220421700F, 0.6239074745F, 0.6257700513F, 0.6276298674F,
 664.407 +  0.6294868903F, 0.6313410873F, 0.6331924262F, 0.6350408745F,
 664.408 +  0.6368864001F, 0.6387289710F, 0.6405685552F, 0.6424051209F,
 664.409 +  0.6442386364F, 0.6460690702F, 0.6478963910F, 0.6497205673F,
 664.410 +  0.6515415682F, 0.6533593625F, 0.6551739194F, 0.6569852082F,
 664.411 +  0.6587931984F, 0.6605978593F, 0.6623991609F, 0.6641970728F,
 664.412 +  0.6659915652F, 0.6677826081F, 0.6695701718F, 0.6713542268F,
 664.413 +  0.6731347437F, 0.6749116932F, 0.6766850461F, 0.6784547736F,
 664.414 +  0.6802208469F, 0.6819832374F, 0.6837419164F, 0.6854968559F,
 664.415 +  0.6872480275F, 0.6889954034F, 0.6907389556F, 0.6924786566F,
 664.416 +  0.6942144788F, 0.6959463950F, 0.6976743780F, 0.6993984008F,
 664.417 +  0.7011184365F, 0.7028344587F, 0.7045464407F, 0.7062543564F,
 664.418 +  0.7079581796F, 0.7096578844F, 0.7113534450F, 0.7130448359F,
 664.419 +  0.7147320316F, 0.7164150070F, 0.7180937371F, 0.7197681970F,
 664.420 +  0.7214383620F, 0.7231042077F, 0.7247657098F, 0.7264228443F,
 664.421 +  0.7280755871F, 0.7297239147F, 0.7313678035F, 0.7330072301F,
 664.422 +  0.7346421715F, 0.7362726046F, 0.7378985069F, 0.7395198556F,
 664.423 +  0.7411366285F, 0.7427488034F, 0.7443563584F, 0.7459592717F,
 664.424 +  0.7475575218F, 0.7491510873F, 0.7507399471F, 0.7523240803F,
 664.425 +  0.7539034661F, 0.7554780839F, 0.7570479136F, 0.7586129349F,
 664.426 +  0.7601731279F, 0.7617284730F, 0.7632789506F, 0.7648245416F,
 664.427 +  0.7663652267F, 0.7679009872F, 0.7694318044F, 0.7709576599F,
 664.428 +  0.7724785354F, 0.7739944130F, 0.7755052749F, 0.7770111035F,
 664.429 +  0.7785118815F, 0.7800075916F, 0.7814982170F, 0.7829837410F,
 664.430 +  0.7844641472F, 0.7859394191F, 0.7874095408F, 0.7888744965F,
 664.431 +  0.7903342706F, 0.7917888476F, 0.7932382124F, 0.7946823501F,
 664.432 +  0.7961212460F, 0.7975548855F, 0.7989832544F, 0.8004063386F,
 664.433 +  0.8018241244F, 0.8032365981F, 0.8046437463F, 0.8060455560F,
 664.434 +  0.8074420141F, 0.8088331080F, 0.8102188253F, 0.8115991536F,
 664.435 +  0.8129740810F, 0.8143435957F, 0.8157076861F, 0.8170663409F,
 664.436 +  0.8184195489F, 0.8197672994F, 0.8211095817F, 0.8224463853F,
 664.437 +  0.8237777001F, 0.8251035161F, 0.8264238235F, 0.8277386129F,
 664.438 +  0.8290478750F, 0.8303516008F, 0.8316497814F, 0.8329424083F,
 664.439 +  0.8342294731F, 0.8355109677F, 0.8367868841F, 0.8380572148F,
 664.440 +  0.8393219523F, 0.8405810893F, 0.8418346190F, 0.8430825345F,
 664.441 +  0.8443248294F, 0.8455614974F, 0.8467925323F, 0.8480179285F,
 664.442 +  0.8492376802F, 0.8504517822F, 0.8516602292F, 0.8528630164F,
 664.443 +  0.8540601391F, 0.8552515928F, 0.8564373733F, 0.8576174766F,
 664.444 +  0.8587918990F, 0.8599606368F, 0.8611236868F, 0.8622810460F,
 664.445 +  0.8634327113F, 0.8645786802F, 0.8657189504F, 0.8668535195F,
 664.446 +  0.8679823857F, 0.8691055472F, 0.8702230025F, 0.8713347503F,
 664.447 +  0.8724407896F, 0.8735411194F, 0.8746357394F, 0.8757246489F,
 664.448 +  0.8768078479F, 0.8778853364F, 0.8789571146F, 0.8800231832F,
 664.449 +  0.8810835427F, 0.8821381942F, 0.8831871387F, 0.8842303777F,
 664.450 +  0.8852679127F, 0.8862997456F, 0.8873258784F, 0.8883463132F,
 664.451 +  0.8893610527F, 0.8903700994F, 0.8913734562F, 0.8923711263F,
 664.452 +  0.8933631129F, 0.8943494196F, 0.8953300500F, 0.8963050083F,
 664.453 +  0.8972742985F, 0.8982379249F, 0.8991958922F, 0.9001482052F,
 664.454 +  0.9010948688F, 0.9020358883F, 0.9029712690F, 0.9039010165F,
 664.455 +  0.9048251367F, 0.9057436357F, 0.9066565195F, 0.9075637946F,
 664.456 +  0.9084654678F, 0.9093615456F, 0.9102520353F, 0.9111369440F,
 664.457 +  0.9120162792F, 0.9128900484F, 0.9137582595F, 0.9146209204F,
 664.458 +  0.9154780394F, 0.9163296248F, 0.9171756853F, 0.9180162296F,
 664.459 +  0.9188512667F, 0.9196808057F, 0.9205048559F, 0.9213234270F,
 664.460 +  0.9221365285F, 0.9229441704F, 0.9237463629F, 0.9245431160F,
 664.461 +  0.9253344404F, 0.9261203465F, 0.9269008453F, 0.9276759477F,
 664.462 +  0.9284456648F, 0.9292100080F, 0.9299689889F, 0.9307226190F,
 664.463 +  0.9314709103F, 0.9322138747F, 0.9329515245F, 0.9336838721F,
 664.464 +  0.9344109300F, 0.9351327108F, 0.9358492275F, 0.9365604931F,
 664.465 +  0.9372665208F, 0.9379673239F, 0.9386629160F, 0.9393533107F,
 664.466 +  0.9400385220F, 0.9407185637F, 0.9413934501F, 0.9420631954F,
 664.467 +  0.9427278141F, 0.9433873208F, 0.9440417304F, 0.9446910576F,
 664.468 +  0.9453353176F, 0.9459745255F, 0.9466086968F, 0.9472378469F,
 664.469 +  0.9478619915F, 0.9484811463F, 0.9490953274F, 0.9497045506F,
 664.470 +  0.9503088323F, 0.9509081888F, 0.9515026365F, 0.9520921921F,
 664.471 +  0.9526768723F, 0.9532566940F, 0.9538316742F, 0.9544018300F,
 664.472 +  0.9549671786F, 0.9555277375F, 0.9560835241F, 0.9566345562F,
 664.473 +  0.9571808513F, 0.9577224275F, 0.9582593027F, 0.9587914949F,
 664.474 +  0.9593190225F, 0.9598419038F, 0.9603601571F, 0.9608738012F,
 664.475 +  0.9613828546F, 0.9618873361F, 0.9623872646F, 0.9628826591F,
 664.476 +  0.9633735388F, 0.9638599227F, 0.9643418303F, 0.9648192808F,
 664.477 +  0.9652922939F, 0.9657608890F, 0.9662250860F, 0.9666849046F,
 664.478 +  0.9671403646F, 0.9675914861F, 0.9680382891F, 0.9684807937F,
 664.479 +  0.9689190202F, 0.9693529890F, 0.9697827203F, 0.9702082347F,
 664.480 +  0.9706295529F, 0.9710466953F, 0.9714596828F, 0.9718685362F,
 664.481 +  0.9722732762F, 0.9726739240F, 0.9730705005F, 0.9734630267F,
 664.482 +  0.9738515239F, 0.9742360134F, 0.9746165163F, 0.9749930540F,
 664.483 +  0.9753656481F, 0.9757343198F, 0.9760990909F, 0.9764599829F,
 664.484 +  0.9768170175F, 0.9771702164F, 0.9775196013F, 0.9778651941F,
 664.485 +  0.9782070167F, 0.9785450909F, 0.9788794388F, 0.9792100824F,
 664.486 +  0.9795370437F, 0.9798603449F, 0.9801800080F, 0.9804960554F,
 664.487 +  0.9808085092F, 0.9811173916F, 0.9814227251F, 0.9817245318F,
 664.488 +  0.9820228343F, 0.9823176549F, 0.9826090160F, 0.9828969402F,
 664.489 +  0.9831814498F, 0.9834625674F, 0.9837403156F, 0.9840147169F,
 664.490 +  0.9842857939F, 0.9845535692F, 0.9848180654F, 0.9850793052F,
 664.491 +  0.9853373113F, 0.9855921062F, 0.9858437127F, 0.9860921535F,
 664.492 +  0.9863374512F, 0.9865796287F, 0.9868187085F, 0.9870547136F,
 664.493 +  0.9872876664F, 0.9875175899F, 0.9877445067F, 0.9879684396F,
 664.494 +  0.9881894112F, 0.9884074444F, 0.9886225619F, 0.9888347863F,
 664.495 +  0.9890441404F, 0.9892506468F, 0.9894543284F, 0.9896552077F,
 664.496 +  0.9898533074F, 0.9900486502F, 0.9902412587F, 0.9904311555F,
 664.497 +  0.9906183633F, 0.9908029045F, 0.9909848019F, 0.9911640779F,
 664.498 +  0.9913407550F, 0.9915148557F, 0.9916864025F, 0.9918554179F,
 664.499 +  0.9920219241F, 0.9921859437F, 0.9923474989F, 0.9925066120F,
 664.500 +  0.9926633054F, 0.9928176012F, 0.9929695218F, 0.9931190891F,
 664.501 +  0.9932663254F, 0.9934112527F, 0.9935538932F, 0.9936942686F,
 664.502 +  0.9938324012F, 0.9939683126F, 0.9941020248F, 0.9942335597F,
 664.503 +  0.9943629388F, 0.9944901841F, 0.9946153170F, 0.9947383593F,
 664.504 +  0.9948593325F, 0.9949782579F, 0.9950951572F, 0.9952100516F,
 664.505 +  0.9953229625F, 0.9954339111F, 0.9955429186F, 0.9956500062F,
 664.506 +  0.9957551948F, 0.9958585056F, 0.9959599593F, 0.9960595769F,
 664.507 +  0.9961573792F, 0.9962533869F, 0.9963476206F, 0.9964401009F,
 664.508 +  0.9965308483F, 0.9966198833F, 0.9967072261F, 0.9967928971F,
 664.509 +  0.9968769164F, 0.9969593041F, 0.9970400804F, 0.9971192651F,
 664.510 +  0.9971968781F, 0.9972729391F, 0.9973474680F, 0.9974204842F,
 664.511 +  0.9974920074F, 0.9975620569F, 0.9976306521F, 0.9976978122F,
 664.512 +  0.9977635565F, 0.9978279039F, 0.9978908736F, 0.9979524842F,
 664.513 +  0.9980127547F, 0.9980717037F, 0.9981293499F, 0.9981857116F,
 664.514 +  0.9982408073F, 0.9982946554F, 0.9983472739F, 0.9983986810F,
 664.515 +  0.9984488947F, 0.9984979328F, 0.9985458132F, 0.9985925534F,
 664.516 +  0.9986381711F, 0.9986826838F, 0.9987261086F, 0.9987684630F,
 664.517 +  0.9988097640F, 0.9988500286F, 0.9988892738F, 0.9989275163F,
 664.518 +  0.9989647727F, 0.9990010597F, 0.9990363938F, 0.9990707911F,
 664.519 +  0.9991042679F, 0.9991368404F, 0.9991685244F, 0.9991993358F,
 664.520 +  0.9992292905F, 0.9992584038F, 0.9992866914F, 0.9993141686F,
 664.521 +  0.9993408506F, 0.9993667526F, 0.9993918895F, 0.9994162761F,
 664.522 +  0.9994399273F, 0.9994628576F, 0.9994850815F, 0.9995066133F,
 664.523 +  0.9995274672F, 0.9995476574F, 0.9995671978F, 0.9995861021F,
 664.524 +  0.9996043841F, 0.9996220573F, 0.9996391352F, 0.9996556310F,
 664.525 +  0.9996715579F, 0.9996869288F, 0.9997017568F, 0.9997160543F,
 664.526 +  0.9997298342F, 0.9997431088F, 0.9997558905F, 0.9997681914F,
 664.527 +  0.9997800236F, 0.9997913990F, 0.9998023292F, 0.9998128261F,
 664.528 +  0.9998229009F, 0.9998325650F, 0.9998418296F, 0.9998507058F,
 664.529 +  0.9998592044F, 0.9998673362F, 0.9998751117F, 0.9998825415F,
 664.530 +  0.9998896358F, 0.9998964047F, 0.9999028584F, 0.9999090066F,
 664.531 +  0.9999148590F, 0.9999204253F, 0.9999257148F, 0.9999307368F,
 664.532 +  0.9999355003F, 0.9999400144F, 0.9999442878F, 0.9999483293F,
 664.533 +  0.9999521472F, 0.9999557499F, 0.9999591457F, 0.9999623426F,
 664.534 +  0.9999653483F, 0.9999681708F, 0.9999708175F, 0.9999732959F,
 664.535 +  0.9999756132F, 0.9999777765F, 0.9999797928F, 0.9999816688F,
 664.536 +  0.9999834113F, 0.9999850266F, 0.9999865211F, 0.9999879009F,
 664.537 +  0.9999891721F, 0.9999903405F, 0.9999914118F, 0.9999923914F,
 664.538 +  0.9999932849F, 0.9999940972F, 0.9999948336F, 0.9999954989F,
 664.539 +  0.9999960978F, 0.9999966349F, 0.9999971146F, 0.9999975411F,
 664.540 +  0.9999979185F, 0.9999982507F, 0.9999985414F, 0.9999987944F,
 664.541 +  0.9999990129F, 0.9999992003F, 0.9999993596F, 0.9999994939F,
 664.542 +  0.9999996059F, 0.9999996981F, 0.9999997732F, 0.9999998333F,
 664.543 +  0.9999998805F, 0.9999999170F, 0.9999999444F, 0.9999999643F,
 664.544 +  0.9999999784F, 0.9999999878F, 0.9999999937F, 0.9999999972F,
 664.545 +  0.9999999990F, 0.9999999997F, 1.0000000000F, 1.0000000000F,
 664.546 +};
 664.547 +
 664.548 +static const float vwin4096[2048] = {
 664.549 +  0.0000002310F, 0.0000020791F, 0.0000057754F, 0.0000113197F,
 664.550 +  0.0000187121F, 0.0000279526F, 0.0000390412F, 0.0000519777F,
 664.551 +  0.0000667623F, 0.0000833949F, 0.0001018753F, 0.0001222036F,
 664.552 +  0.0001443798F, 0.0001684037F, 0.0001942754F, 0.0002219947F,
 664.553 +  0.0002515616F, 0.0002829761F, 0.0003162380F, 0.0003513472F,
 664.554 +  0.0003883038F, 0.0004271076F, 0.0004677584F, 0.0005102563F,
 664.555 +  0.0005546011F, 0.0006007928F, 0.0006488311F, 0.0006987160F,
 664.556 +  0.0007504474F, 0.0008040251F, 0.0008594490F, 0.0009167191F,
 664.557 +  0.0009758351F, 0.0010367969F, 0.0010996044F, 0.0011642574F,
 664.558 +  0.0012307558F, 0.0012990994F, 0.0013692880F, 0.0014413216F,
 664.559 +  0.0015151998F, 0.0015909226F, 0.0016684898F, 0.0017479011F,
 664.560 +  0.0018291565F, 0.0019122556F, 0.0019971983F, 0.0020839845F,
 664.561 +  0.0021726138F, 0.0022630861F, 0.0023554012F, 0.0024495588F,
 664.562 +  0.0025455588F, 0.0026434008F, 0.0027430847F, 0.0028446103F,
 664.563 +  0.0029479772F, 0.0030531853F, 0.0031602342F, 0.0032691238F,
 664.564 +  0.0033798538F, 0.0034924239F, 0.0036068338F, 0.0037230833F,
 664.565 +  0.0038411721F, 0.0039610999F, 0.0040828664F, 0.0042064714F,
 664.566 +  0.0043319145F, 0.0044591954F, 0.0045883139F, 0.0047192696F,
 664.567 +  0.0048520622F, 0.0049866914F, 0.0051231569F, 0.0052614583F,
 664.568 +  0.0054015953F, 0.0055435676F, 0.0056873748F, 0.0058330166F,
 664.569 +  0.0059804926F, 0.0061298026F, 0.0062809460F, 0.0064339226F,
 664.570 +  0.0065887320F, 0.0067453738F, 0.0069038476F, 0.0070641531F,
 664.571 +  0.0072262899F, 0.0073902575F, 0.0075560556F, 0.0077236838F,
 664.572 +  0.0078931417F, 0.0080644288F, 0.0082375447F, 0.0084124891F,
 664.573 +  0.0085892615F, 0.0087678614F, 0.0089482885F, 0.0091305422F,
 664.574 +  0.0093146223F, 0.0095005281F, 0.0096882592F, 0.0098778153F,
 664.575 +  0.0100691958F, 0.0102624002F, 0.0104574281F, 0.0106542791F,
 664.576 +  0.0108529525F, 0.0110534480F, 0.0112557651F, 0.0114599032F,
 664.577 +  0.0116658618F, 0.0118736405F, 0.0120832387F, 0.0122946560F,
 664.578 +  0.0125078917F, 0.0127229454F, 0.0129398166F, 0.0131585046F,
 664.579 +  0.0133790090F, 0.0136013292F, 0.0138254647F, 0.0140514149F,
 664.580 +  0.0142791792F, 0.0145087572F, 0.0147401481F, 0.0149733515F,
 664.581 +  0.0152083667F, 0.0154451932F, 0.0156838304F, 0.0159242777F,
 664.582 +  0.0161665345F, 0.0164106001F, 0.0166564741F, 0.0169041557F,
 664.583 +  0.0171536443F, 0.0174049393F, 0.0176580401F, 0.0179129461F,
 664.584 +  0.0181696565F, 0.0184281708F, 0.0186884883F, 0.0189506084F,
 664.585 +  0.0192145303F, 0.0194802535F, 0.0197477772F, 0.0200171008F,
 664.586 +  0.0202882236F, 0.0205611449F, 0.0208358639F, 0.0211123801F,
 664.587 +  0.0213906927F, 0.0216708011F, 0.0219527043F, 0.0222364019F,
 664.588 +  0.0225218930F, 0.0228091769F, 0.0230982529F, 0.0233891203F,
 664.589 +  0.0236817782F, 0.0239762259F, 0.0242724628F, 0.0245704880F,
 664.590 +  0.0248703007F, 0.0251719002F, 0.0254752858F, 0.0257804565F,
 664.591 +  0.0260874117F, 0.0263961506F, 0.0267066722F, 0.0270189760F,
 664.592 +  0.0273330609F, 0.0276489263F, 0.0279665712F, 0.0282859949F,
 664.593 +  0.0286071966F, 0.0289301753F, 0.0292549303F, 0.0295814607F,
 664.594 +  0.0299097656F, 0.0302398442F, 0.0305716957F, 0.0309053191F,
 664.595 +  0.0312407135F, 0.0315778782F, 0.0319168122F, 0.0322575145F,
 664.596 +  0.0325999844F, 0.0329442209F, 0.0332902231F, 0.0336379900F,
 664.597 +  0.0339875208F, 0.0343388146F, 0.0346918703F, 0.0350466871F,
 664.598 +  0.0354032640F, 0.0357616000F, 0.0361216943F, 0.0364835458F,
 664.599 +  0.0368471535F, 0.0372125166F, 0.0375796339F, 0.0379485046F,
 664.600 +  0.0383191276F, 0.0386915020F, 0.0390656267F, 0.0394415008F,
 664.601 +  0.0398191231F, 0.0401984927F, 0.0405796086F, 0.0409624698F,
 664.602 +  0.0413470751F, 0.0417334235F, 0.0421215141F, 0.0425113457F,
 664.603 +  0.0429029172F, 0.0432962277F, 0.0436912760F, 0.0440880610F,
 664.604 +  0.0444865817F, 0.0448868370F, 0.0452888257F, 0.0456925468F,
 664.605 +  0.0460979992F, 0.0465051816F, 0.0469140931F, 0.0473247325F,
 664.606 +  0.0477370986F, 0.0481511902F, 0.0485670064F, 0.0489845458F,
 664.607 +  0.0494038074F, 0.0498247899F, 0.0502474922F, 0.0506719131F,
 664.608 +  0.0510980514F, 0.0515259060F, 0.0519554756F, 0.0523867590F,
 664.609 +  0.0528197550F, 0.0532544624F, 0.0536908800F, 0.0541290066F,
 664.610 +  0.0545688408F, 0.0550103815F, 0.0554536274F, 0.0558985772F,
 664.611 +  0.0563452297F, 0.0567935837F, 0.0572436377F, 0.0576953907F,
 664.612 +  0.0581488412F, 0.0586039880F, 0.0590608297F, 0.0595193651F,
 664.613 +  0.0599795929F, 0.0604415117F, 0.0609051202F, 0.0613704170F,
 664.614 +  0.0618374009F, 0.0623060704F, 0.0627764243F, 0.0632484611F,
 664.615 +  0.0637221795F, 0.0641975781F, 0.0646746555F, 0.0651534104F,
 664.616 +  0.0656338413F, 0.0661159469F, 0.0665997257F, 0.0670851763F,
 664.617 +  0.0675722973F, 0.0680610873F, 0.0685515448F, 0.0690436684F,
 664.618 +  0.0695374567F, 0.0700329081F, 0.0705300213F, 0.0710287947F,
 664.619 +  0.0715292269F, 0.0720313163F, 0.0725350616F, 0.0730404612F,
 664.620 +  0.0735475136F, 0.0740562172F, 0.0745665707F, 0.0750785723F,
 664.621 +  0.0755922207F, 0.0761075143F, 0.0766244515F, 0.0771430307F,
 664.622 +  0.0776632505F, 0.0781851092F, 0.0787086052F, 0.0792337371F,
 664.623 +  0.0797605032F, 0.0802889018F, 0.0808189315F, 0.0813505905F,
 664.624 +  0.0818838773F, 0.0824187903F, 0.0829553277F, 0.0834934881F,
 664.625 +  0.0840332697F, 0.0845746708F, 0.0851176899F, 0.0856623252F,
 664.626 +  0.0862085751F, 0.0867564379F, 0.0873059119F, 0.0878569954F,
 664.627 +  0.0884096867F, 0.0889639840F, 0.0895198858F, 0.0900773902F,
 664.628 +  0.0906364955F, 0.0911972000F, 0.0917595019F, 0.0923233995F,
 664.629 +  0.0928888909F, 0.0934559745F, 0.0940246485F, 0.0945949110F,
 664.630 +  0.0951667604F, 0.0957401946F, 0.0963152121F, 0.0968918109F,
 664.631 +  0.0974699893F, 0.0980497454F, 0.0986310773F, 0.0992139832F,
 664.632 +  0.0997984614F, 0.1003845098F, 0.1009721267F, 0.1015613101F,
 664.633 +  0.1021520582F, 0.1027443692F, 0.1033382410F, 0.1039336718F,
 664.634 +  0.1045306597F, 0.1051292027F, 0.1057292990F, 0.1063309466F,
 664.635 +  0.1069341435F, 0.1075388878F, 0.1081451776F, 0.1087530108F,
 664.636 +  0.1093623856F, 0.1099732998F, 0.1105857516F, 0.1111997389F,
 664.637 +  0.1118152597F, 0.1124323121F, 0.1130508939F, 0.1136710032F,
 664.638 +  0.1142926379F, 0.1149157960F, 0.1155404755F, 0.1161666742F,
 664.639 +  0.1167943901F, 0.1174236211F, 0.1180543652F, 0.1186866202F,
 664.640 +  0.1193203841F, 0.1199556548F, 0.1205924300F, 0.1212307078F,
 664.641 +  0.1218704860F, 0.1225117624F, 0.1231545349F, 0.1237988013F,
 664.642 +  0.1244445596F, 0.1250918074F, 0.1257405427F, 0.1263907632F,
 664.643 +  0.1270424667F, 0.1276956512F, 0.1283503142F, 0.1290064537F,
 664.644 +  0.1296640674F, 0.1303231530F, 0.1309837084F, 0.1316457312F,
 664.645 +  0.1323092193F, 0.1329741703F, 0.1336405820F, 0.1343084520F,
 664.646 +  0.1349777782F, 0.1356485582F, 0.1363207897F, 0.1369944704F,
 664.647 +  0.1376695979F, 0.1383461700F, 0.1390241842F, 0.1397036384F,
 664.648 +  0.1403845300F, 0.1410668567F, 0.1417506162F, 0.1424358061F,
 664.649 +  0.1431224240F, 0.1438104674F, 0.1444999341F, 0.1451908216F,
 664.650 +  0.1458831274F, 0.1465768492F, 0.1472719844F, 0.1479685308F,
 664.651 +  0.1486664857F, 0.1493658468F, 0.1500666115F, 0.1507687775F,
 664.652 +  0.1514723422F, 0.1521773031F, 0.1528836577F, 0.1535914035F,
 664.653 +  0.1543005380F, 0.1550110587F, 0.1557229631F, 0.1564362485F,
 664.654 +  0.1571509124F, 0.1578669524F, 0.1585843657F, 0.1593031499F,
 664.655 +  0.1600233024F, 0.1607448205F, 0.1614677017F, 0.1621919433F,
 664.656 +  0.1629175428F, 0.1636444975F, 0.1643728047F, 0.1651024619F,
 664.657 +  0.1658334665F, 0.1665658156F, 0.1672995067F, 0.1680345371F,
 664.658 +  0.1687709041F, 0.1695086050F, 0.1702476372F, 0.1709879978F,
 664.659 +  0.1717296843F, 0.1724726938F, 0.1732170237F, 0.1739626711F,
 664.660 +  0.1747096335F, 0.1754579079F, 0.1762074916F, 0.1769583819F,
 664.661 +  0.1777105760F, 0.1784640710F, 0.1792188642F, 0.1799749529F,
 664.662 +  0.1807323340F, 0.1814910049F, 0.1822509628F, 0.1830122046F,
 664.663 +  0.1837747277F, 0.1845385292F, 0.1853036062F, 0.1860699558F,
 664.664 +  0.1868375751F, 0.1876064613F, 0.1883766114F, 0.1891480226F,
 664.665 +  0.1899206919F, 0.1906946164F, 0.1914697932F, 0.1922462194F,
 664.666 +  0.1930238919F, 0.1938028079F, 0.1945829643F, 0.1953643583F,
 664.667 +  0.1961469868F, 0.1969308468F, 0.1977159353F, 0.1985022494F,
 664.668 +  0.1992897859F, 0.2000785420F, 0.2008685145F, 0.2016597005F,
 664.669 +  0.2024520968F, 0.2032457005F, 0.2040405084F, 0.2048365175F,
 664.670 +  0.2056337247F, 0.2064321269F, 0.2072317211F, 0.2080325041F,
 664.671 +  0.2088344727F, 0.2096376240F, 0.2104419547F, 0.2112474618F,
 664.672 +  0.2120541420F, 0.2128619923F, 0.2136710094F, 0.2144811902F,
 664.673 +  0.2152925315F, 0.2161050301F, 0.2169186829F, 0.2177334866F,
 664.674 +  0.2185494381F, 0.2193665340F, 0.2201847712F, 0.2210041465F,
 664.675 +  0.2218246565F, 0.2226462981F, 0.2234690680F, 0.2242929629F,
 664.676 +  0.2251179796F, 0.2259441147F, 0.2267713650F, 0.2275997272F,
 664.677 +  0.2284291979F, 0.2292597739F, 0.2300914518F, 0.2309242283F,
 664.678 +  0.2317581001F, 0.2325930638F, 0.2334291160F, 0.2342662534F,
 664.679 +  0.2351044727F, 0.2359437703F, 0.2367841431F, 0.2376255875F,
 664.680 +  0.2384681001F, 0.2393116776F, 0.2401563165F, 0.2410020134F,
 664.681 +  0.2418487649F, 0.2426965675F, 0.2435454178F, 0.2443953122F,
 664.682 +  0.2452462474F, 0.2460982199F, 0.2469512262F, 0.2478052628F,
 664.683 +  0.2486603262F, 0.2495164129F, 0.2503735194F, 0.2512316421F,
 664.684 +  0.2520907776F, 0.2529509222F, 0.2538120726F, 0.2546742250F,
 664.685 +  0.2555373760F, 0.2564015219F, 0.2572666593F, 0.2581327845F,
 664.686 +  0.2589998939F, 0.2598679840F, 0.2607370510F, 0.2616070916F,
 664.687 +  0.2624781019F, 0.2633500783F, 0.2642230173F, 0.2650969152F,
 664.688 +  0.2659717684F, 0.2668475731F, 0.2677243257F, 0.2686020226F,
 664.689 +  0.2694806601F, 0.2703602344F, 0.2712407419F, 0.2721221789F,
 664.690 +  0.2730045417F, 0.2738878265F, 0.2747720297F, 0.2756571474F,
 664.691 +  0.2765431760F, 0.2774301117F, 0.2783179508F, 0.2792066895F,
 664.692 +  0.2800963240F, 0.2809868505F, 0.2818782654F, 0.2827705647F,
 664.693 +  0.2836637447F, 0.2845578016F, 0.2854527315F, 0.2863485307F,
 664.694 +  0.2872451953F, 0.2881427215F, 0.2890411055F, 0.2899403433F,
 664.695 +  0.2908404312F, 0.2917413654F, 0.2926431418F, 0.2935457567F,
 664.696 +  0.2944492061F, 0.2953534863F, 0.2962585932F, 0.2971645230F,
 664.697 +  0.2980712717F, 0.2989788356F, 0.2998872105F, 0.3007963927F,
 664.698 +  0.3017063781F, 0.3026171629F, 0.3035287430F, 0.3044411145F,
 664.699 +  0.3053542736F, 0.3062682161F, 0.3071829381F, 0.3080984356F,
 664.700 +  0.3090147047F, 0.3099317413F, 0.3108495414F, 0.3117681011F,
 664.701 +  0.3126874163F, 0.3136074830F, 0.3145282972F, 0.3154498548F,
 664.702 +  0.3163721517F, 0.3172951841F, 0.3182189477F, 0.3191434385F,
 664.703 +  0.3200686525F, 0.3209945856F, 0.3219212336F, 0.3228485927F,
 664.704 +  0.3237766585F, 0.3247054271F, 0.3256348943F, 0.3265650560F,
 664.705 +  0.3274959081F, 0.3284274465F, 0.3293596671F, 0.3302925657F,
 664.706 +  0.3312261382F, 0.3321603804F, 0.3330952882F, 0.3340308574F,
 664.707 +  0.3349670838F, 0.3359039634F, 0.3368414919F, 0.3377796651F,
 664.708 +  0.3387184789F, 0.3396579290F, 0.3405980113F, 0.3415387216F,
 664.709 +  0.3424800556F, 0.3434220091F, 0.3443645779F, 0.3453077578F,
 664.710 +  0.3462515446F, 0.3471959340F, 0.3481409217F, 0.3490865036F,
 664.711 +  0.3500326754F, 0.3509794328F, 0.3519267715F, 0.3528746873F,
 664.712 +  0.3538231759F, 0.3547722330F, 0.3557218544F, 0.3566720357F,
 664.713 +  0.3576227727F, 0.3585740610F, 0.3595258964F, 0.3604782745F,
 664.714 +  0.3614311910F, 0.3623846417F, 0.3633386221F, 0.3642931280F,
 664.715 +  0.3652481549F, 0.3662036987F, 0.3671597548F, 0.3681163191F,
 664.716 +  0.3690733870F, 0.3700309544F, 0.3709890167F, 0.3719475696F,
 664.717 +  0.3729066089F, 0.3738661299F, 0.3748261285F, 0.3757866002F,
 664.718 +  0.3767475406F, 0.3777089453F, 0.3786708100F, 0.3796331302F,
 664.719 +  0.3805959014F, 0.3815591194F, 0.3825227796F, 0.3834868777F,
 664.720 +  0.3844514093F, 0.3854163698F, 0.3863817549F, 0.3873475601F,
 664.721 +  0.3883137810F, 0.3892804131F, 0.3902474521F, 0.3912148933F,
 664.722 +  0.3921827325F, 0.3931509650F, 0.3941195865F, 0.3950885925F,
 664.723 +  0.3960579785F, 0.3970277400F, 0.3979978725F, 0.3989683716F,
 664.724 +  0.3999392328F, 0.4009104516F, 0.4018820234F, 0.4028539438F,
 664.725 +  0.4038262084F, 0.4047988125F, 0.4057717516F, 0.4067450214F,
 664.726 +  0.4077186172F, 0.4086925345F, 0.4096667688F, 0.4106413155F,
 664.727 +  0.4116161703F, 0.4125913284F, 0.4135667854F, 0.4145425368F,
 664.728 +  0.4155185780F, 0.4164949044F, 0.4174715116F, 0.4184483949F,
 664.729 +  0.4194255498F, 0.4204029718F, 0.4213806563F, 0.4223585987F,
 664.730 +  0.4233367946F, 0.4243152392F, 0.4252939281F, 0.4262728566F,
 664.731 +  0.4272520202F, 0.4282314144F, 0.4292110345F, 0.4301908760F,
 664.732 +  0.4311709343F, 0.4321512047F, 0.4331316828F, 0.4341123639F,
 664.733 +  0.4350932435F, 0.4360743168F, 0.4370555794F, 0.4380370267F,
 664.734 +  0.4390186540F, 0.4400004567F, 0.4409824303F, 0.4419645701F,
 664.735 +  0.4429468716F, 0.4439293300F, 0.4449119409F, 0.4458946996F,
 664.736 +  0.4468776014F, 0.4478606418F, 0.4488438162F, 0.4498271199F,
 664.737 +  0.4508105483F, 0.4517940967F, 0.4527777607F, 0.4537615355F,
 664.738 +  0.4547454165F, 0.4557293991F, 0.4567134786F, 0.4576976505F,
 664.739 +  0.4586819101F, 0.4596662527F, 0.4606506738F, 0.4616351687F,
 664.740 +  0.4626197328F, 0.4636043614F, 0.4645890499F, 0.4655737936F,
 664.741 +  0.4665585880F, 0.4675434284F, 0.4685283101F, 0.4695132286F,
 664.742 +  0.4704981791F, 0.4714831570F, 0.4724681577F, 0.4734531766F,
 664.743 +  0.4744382089F, 0.4754232501F, 0.4764082956F, 0.4773933406F,
 664.744 +  0.4783783806F, 0.4793634108F, 0.4803484267F, 0.4813334237F,
 664.745 +  0.4823183969F, 0.4833033419F, 0.4842882540F, 0.4852731285F,
 664.746 +  0.4862579608F, 0.4872427462F, 0.4882274802F, 0.4892121580F,
 664.747 +  0.4901967751F, 0.4911813267F, 0.4921658083F, 0.4931502151F,
 664.748 +  0.4941345427F, 0.4951187863F, 0.4961029412F, 0.4970870029F,
 664.749 +  0.4980709667F, 0.4990548280F, 0.5000385822F, 0.5010222245F,
 664.750 +  0.5020057505F, 0.5029891553F, 0.5039724345F, 0.5049555834F,
 664.751 +  0.5059385973F, 0.5069214716F, 0.5079042018F, 0.5088867831F,
 664.752 +  0.5098692110F, 0.5108514808F, 0.5118335879F, 0.5128155277F,
 664.753 +  0.5137972956F, 0.5147788869F, 0.5157602971F, 0.5167415215F,
 664.754 +  0.5177225555F, 0.5187033945F, 0.5196840339F, 0.5206644692F,
 664.755 +  0.5216446956F, 0.5226247086F, 0.5236045035F, 0.5245840759F,
 664.756 +  0.5255634211F, 0.5265425344F, 0.5275214114F, 0.5285000474F,
 664.757 +  0.5294784378F, 0.5304565781F, 0.5314344637F, 0.5324120899F,
 664.758 +  0.5333894522F, 0.5343665461F, 0.5353433670F, 0.5363199102F,
 664.759 +  0.5372961713F, 0.5382721457F, 0.5392478287F, 0.5402232159F,
 664.760 +  0.5411983027F, 0.5421730845F, 0.5431475569F, 0.5441217151F,
 664.761 +  0.5450955548F, 0.5460690714F, 0.5470422602F, 0.5480151169F,
 664.762 +  0.5489876368F, 0.5499598155F, 0.5509316484F, 0.5519031310F,
 664.763 +  0.5528742587F, 0.5538450271F, 0.5548154317F, 0.5557854680F,
 664.764 +  0.5567551314F, 0.5577244174F, 0.5586933216F, 0.5596618395F,
 664.765 +  0.5606299665F, 0.5615976983F, 0.5625650302F, 0.5635319580F,
 664.766 +  0.5644984770F, 0.5654645828F, 0.5664302709F, 0.5673955370F,
 664.767 +  0.5683603765F, 0.5693247850F, 0.5702887580F, 0.5712522912F,
 664.768 +  0.5722153800F, 0.5731780200F, 0.5741402069F, 0.5751019362F,
 664.769 +  0.5760632034F, 0.5770240042F, 0.5779843341F, 0.5789441889F,
 664.770 +  0.5799035639F, 0.5808624549F, 0.5818208575F, 0.5827787673F,
 664.771 +  0.5837361800F, 0.5846930910F, 0.5856494961F, 0.5866053910F,
 664.772 +  0.5875607712F, 0.5885156324F, 0.5894699703F, 0.5904237804F,
 664.773 +  0.5913770586F, 0.5923298004F, 0.5932820016F, 0.5942336578F,
 664.774 +  0.5951847646F, 0.5961353179F, 0.5970853132F, 0.5980347464F,
 664.775 +  0.5989836131F, 0.5999319090F, 0.6008796298F, 0.6018267713F,
 664.776 +  0.6027733292F, 0.6037192993F, 0.6046646773F, 0.6056094589F,
 664.777 +  0.6065536400F, 0.6074972162F, 0.6084401833F, 0.6093825372F,
 664.778 +  0.6103242736F, 0.6112653884F, 0.6122058772F, 0.6131457359F,
 664.779 +  0.6140849604F, 0.6150235464F, 0.6159614897F, 0.6168987862F,
 664.780 +  0.6178354318F, 0.6187714223F, 0.6197067535F, 0.6206414213F,
 664.781 +  0.6215754215F, 0.6225087501F, 0.6234414028F, 0.6243733757F,
 664.782 +  0.6253046646F, 0.6262352654F, 0.6271651739F, 0.6280943862F,
 664.783 +  0.6290228982F, 0.6299507057F, 0.6308778048F, 0.6318041913F,
 664.784 +  0.6327298612F, 0.6336548105F, 0.6345790352F, 0.6355025312F,
 664.785 +  0.6364252945F, 0.6373473211F, 0.6382686070F, 0.6391891483F,
 664.786 +  0.6401089409F, 0.6410279808F, 0.6419462642F, 0.6428637869F,
 664.787 +  0.6437805452F, 0.6446965350F, 0.6456117524F, 0.6465261935F,
 664.788 +  0.6474398544F, 0.6483527311F, 0.6492648197F, 0.6501761165F,
 664.789 +  0.6510866174F, 0.6519963186F, 0.6529052162F, 0.6538133064F,
 664.790 +  0.6547205854F, 0.6556270492F, 0.6565326941F, 0.6574375162F,
 664.791 +  0.6583415117F, 0.6592446769F, 0.6601470079F, 0.6610485009F,
 664.792 +  0.6619491521F, 0.6628489578F, 0.6637479143F, 0.6646460177F,
 664.793 +  0.6655432643F, 0.6664396505F, 0.6673351724F, 0.6682298264F,
 664.794 +  0.6691236087F, 0.6700165157F, 0.6709085436F, 0.6717996889F,
 664.795 +  0.6726899478F, 0.6735793167F, 0.6744677918F, 0.6753553697F,
 664.796 +  0.6762420466F, 0.6771278190F, 0.6780126832F, 0.6788966357F,
 664.797 +  0.6797796728F, 0.6806617909F, 0.6815429866F, 0.6824232562F,
 664.798 +  0.6833025961F, 0.6841810030F, 0.6850584731F, 0.6859350031F,
 664.799 +  0.6868105894F, 0.6876852284F, 0.6885589168F, 0.6894316510F,
 664.800 +  0.6903034275F, 0.6911742430F, 0.6920440939F, 0.6929129769F,
 664.801 +  0.6937808884F, 0.6946478251F, 0.6955137837F, 0.6963787606F,
 664.802 +  0.6972427525F, 0.6981057560F, 0.6989677678F, 0.6998287845F,
 664.803 +  0.7006888028F, 0.7015478194F, 0.7024058309F, 0.7032628340F,
 664.804 +  0.7041188254F, 0.7049738019F, 0.7058277601F, 0.7066806969F,
 664.805 +  0.7075326089F, 0.7083834929F, 0.7092333457F, 0.7100821640F,
 664.806 +  0.7109299447F, 0.7117766846F, 0.7126223804F, 0.7134670291F,
 664.807 +  0.7143106273F, 0.7151531721F, 0.7159946602F, 0.7168350885F,
 664.808 +  0.7176744539F, 0.7185127534F, 0.7193499837F, 0.7201861418F,
 664.809 +  0.7210212247F, 0.7218552293F, 0.7226881526F, 0.7235199914F,
 664.810 +  0.7243507428F, 0.7251804039F, 0.7260089715F, 0.7268364426F,
 664.811 +  0.7276628144F, 0.7284880839F, 0.7293122481F, 0.7301353040F,
 664.812 +  0.7309572487F, 0.7317780794F, 0.7325977930F, 0.7334163868F,
 664.813 +  0.7342338579F, 0.7350502033F, 0.7358654202F, 0.7366795059F,
 664.814 +  0.7374924573F, 0.7383042718F, 0.7391149465F, 0.7399244787F,
 664.815 +  0.7407328655F, 0.7415401041F, 0.7423461920F, 0.7431511261F,
 664.816 +  0.7439549040F, 0.7447575227F, 0.7455589797F, 0.7463592723F,
 664.817 +  0.7471583976F, 0.7479563532F, 0.7487531363F, 0.7495487443F,
 664.818 +  0.7503431745F, 0.7511364244F, 0.7519284913F, 0.7527193726F,
 664.819 +  0.7535090658F, 0.7542975683F, 0.7550848776F, 0.7558709910F,
 664.820 +  0.7566559062F, 0.7574396205F, 0.7582221314F, 0.7590034366F,
 664.821 +  0.7597835334F, 0.7605624194F, 0.7613400923F, 0.7621165495F,
 664.822 +  0.7628917886F, 0.7636658072F, 0.7644386030F, 0.7652101735F,
 664.823 +  0.7659805164F, 0.7667496292F, 0.7675175098F, 0.7682841556F,
 664.824 +  0.7690495645F, 0.7698137341F, 0.7705766622F, 0.7713383463F,
 664.825 +  0.7720987844F, 0.7728579741F, 0.7736159132F, 0.7743725994F,
 664.826 +  0.7751280306F, 0.7758822046F, 0.7766351192F, 0.7773867722F,
 664.827 +  0.7781371614F, 0.7788862848F, 0.7796341401F, 0.7803807253F,
 664.828 +  0.7811260383F, 0.7818700769F, 0.7826128392F, 0.7833543230F,
 664.829 +  0.7840945263F, 0.7848334471F, 0.7855710833F, 0.7863074330F,
 664.830 +  0.7870424941F, 0.7877762647F, 0.7885087428F, 0.7892399264F,
 664.831 +  0.7899698137F, 0.7906984026F, 0.7914256914F, 0.7921516780F,
 664.832 +  0.7928763607F, 0.7935997375F, 0.7943218065F, 0.7950425661F,
 664.833 +  0.7957620142F, 0.7964801492F, 0.7971969692F, 0.7979124724F,
 664.834 +  0.7986266570F, 0.7993395214F, 0.8000510638F, 0.8007612823F,
 664.835 +  0.8014701754F, 0.8021777413F, 0.8028839784F, 0.8035888849F,
 664.836 +  0.8042924592F, 0.8049946997F, 0.8056956048F, 0.8063951727F,
 664.837 +  0.8070934020F, 0.8077902910F, 0.8084858381F, 0.8091800419F,
 664.838 +  0.8098729007F, 0.8105644130F, 0.8112545774F, 0.8119433922F,
 664.839 +  0.8126308561F, 0.8133169676F, 0.8140017251F, 0.8146851272F,
 664.840 +  0.8153671726F, 0.8160478598F, 0.8167271874F, 0.8174051539F,
 664.841 +  0.8180817582F, 0.8187569986F, 0.8194308741F, 0.8201033831F,
 664.842 +  0.8207745244F, 0.8214442966F, 0.8221126986F, 0.8227797290F,
 664.843 +  0.8234453865F, 0.8241096700F, 0.8247725781F, 0.8254341097F,
 664.844 +  0.8260942636F, 0.8267530385F, 0.8274104334F, 0.8280664470F,
 664.845 +  0.8287210782F, 0.8293743259F, 0.8300261889F, 0.8306766662F,
 664.846 +  0.8313257566F, 0.8319734591F, 0.8326197727F, 0.8332646963F,
 664.847 +  0.8339082288F, 0.8345503692F, 0.8351911167F, 0.8358304700F,
 664.848 +  0.8364684284F, 0.8371049907F, 0.8377401562F, 0.8383739238F,
 664.849 +  0.8390062927F, 0.8396372618F, 0.8402668305F, 0.8408949977F,
 664.850 +  0.8415217626F, 0.8421471245F, 0.8427710823F, 0.8433936354F,
 664.851 +  0.8440147830F, 0.8446345242F, 0.8452528582F, 0.8458697844F,
 664.852 +  0.8464853020F, 0.8470994102F, 0.8477121084F, 0.8483233958F,
 664.853 +  0.8489332718F, 0.8495417356F, 0.8501487866F, 0.8507544243F,
 664.854 +  0.8513586479F, 0.8519614568F, 0.8525628505F, 0.8531628283F,
 664.855 +  0.8537613897F, 0.8543585341F, 0.8549542611F, 0.8555485699F,
 664.856 +  0.8561414603F, 0.8567329315F, 0.8573229832F, 0.8579116149F,
 664.857 +  0.8584988262F, 0.8590846165F, 0.8596689855F, 0.8602519327F,
 664.858 +  0.8608334577F, 0.8614135603F, 0.8619922399F, 0.8625694962F,
 664.859 +  0.8631453289F, 0.8637197377F, 0.8642927222F, 0.8648642821F,
 664.860 +  0.8654344172F, 0.8660031272F, 0.8665704118F, 0.8671362708F,
 664.861 +  0.8677007039F, 0.8682637109F, 0.8688252917F, 0.8693854460F,
 664.862 +  0.8699441737F, 0.8705014745F, 0.8710573485F, 0.8716117953F,
 664.863 +  0.8721648150F, 0.8727164073F, 0.8732665723F, 0.8738153098F,
 664.864 +  0.8743626197F, 0.8749085021F, 0.8754529569F, 0.8759959840F,
 664.865 +  0.8765375835F, 0.8770777553F, 0.8776164996F, 0.8781538162F,
 664.866 +  0.8786897054F, 0.8792241670F, 0.8797572013F, 0.8802888082F,
 664.867 +  0.8808189880F, 0.8813477407F, 0.8818750664F, 0.8824009653F,
 664.868 +  0.8829254375F, 0.8834484833F, 0.8839701028F, 0.8844902961F,
 664.869 +  0.8850090636F, 0.8855264054F, 0.8860423218F, 0.8865568131F,
 664.870 +  0.8870698794F, 0.8875815212F, 0.8880917386F, 0.8886005319F,
 664.871 +  0.8891079016F, 0.8896138479F, 0.8901183712F, 0.8906214719F,
 664.872 +  0.8911231503F, 0.8916234067F, 0.8921222417F, 0.8926196556F,
 664.873 +  0.8931156489F, 0.8936102219F, 0.8941033752F, 0.8945951092F,
 664.874 +  0.8950854244F, 0.8955743212F, 0.8960618003F, 0.8965478621F,
 664.875 +  0.8970325071F, 0.8975157359F, 0.8979975490F, 0.8984779471F,
 664.876 +  0.8989569307F, 0.8994345004F, 0.8999106568F, 0.9003854005F,
 664.877 +  0.9008587323F, 0.9013306526F, 0.9018011623F, 0.9022702619F,
 664.878 +  0.9027379521F, 0.9032042337F, 0.9036691074F, 0.9041325739F,
 664.879 +  0.9045946339F, 0.9050552882F, 0.9055145376F, 0.9059723828F,
 664.880 +  0.9064288246F, 0.9068838638F, 0.9073375013F, 0.9077897379F,
 664.881 +  0.9082405743F, 0.9086900115F, 0.9091380503F, 0.9095846917F,
 664.882 +  0.9100299364F, 0.9104737854F, 0.9109162397F, 0.9113573001F,
 664.883 +  0.9117969675F, 0.9122352430F, 0.9126721275F, 0.9131076219F,
 664.884 +  0.9135417273F, 0.9139744447F, 0.9144057750F, 0.9148357194F,
 664.885 +  0.9152642787F, 0.9156914542F, 0.9161172468F, 0.9165416576F,
 664.886 +  0.9169646877F, 0.9173863382F, 0.9178066102F, 0.9182255048F,
 664.887 +  0.9186430232F, 0.9190591665F, 0.9194739359F, 0.9198873324F,
 664.888 +  0.9202993574F, 0.9207100120F, 0.9211192973F, 0.9215272147F,
 664.889 +  0.9219337653F, 0.9223389504F, 0.9227427713F, 0.9231452290F,
 664.890 +  0.9235463251F, 0.9239460607F, 0.9243444371F, 0.9247414557F,
 664.891 +  0.9251371177F, 0.9255314245F, 0.9259243774F, 0.9263159778F,
 664.892 +  0.9267062270F, 0.9270951264F, 0.9274826774F, 0.9278688814F,
 664.893 +  0.9282537398F, 0.9286372540F, 0.9290194254F, 0.9294002555F,
 664.894 +  0.9297797458F, 0.9301578976F, 0.9305347125F, 0.9309101919F,
 664.895 +  0.9312843373F, 0.9316571503F, 0.9320286323F, 0.9323987849F,
 664.896 +  0.9327676097F, 0.9331351080F, 0.9335012816F, 0.9338661320F,
 664.897 +  0.9342296607F, 0.9345918694F, 0.9349527596F, 0.9353123330F,
 664.898 +  0.9356705911F, 0.9360275357F, 0.9363831683F, 0.9367374905F,
 664.899 +  0.9370905042F, 0.9374422108F, 0.9377926122F, 0.9381417099F,
 664.900 +  0.9384895057F, 0.9388360014F, 0.9391811985F, 0.9395250989F,
 664.901 +  0.9398677043F, 0.9402090165F, 0.9405490371F, 0.9408877680F,
 664.902 +  0.9412252110F, 0.9415613678F, 0.9418962402F, 0.9422298301F,
 664.903 +  0.9425621392F, 0.9428931695F, 0.9432229226F, 0.9435514005F,
 664.904 +  0.9438786050F, 0.9442045381F, 0.9445292014F, 0.9448525971F,
 664.905 +  0.9451747268F, 0.9454955926F, 0.9458151963F, 0.9461335399F,
 664.906 +  0.9464506253F, 0.9467664545F, 0.9470810293F, 0.9473943517F,
 664.907 +  0.9477064238F, 0.9480172474F, 0.9483268246F, 0.9486351573F,
 664.908 +  0.9489422475F, 0.9492480973F, 0.9495527087F, 0.9498560837F,
 664.909 +  0.9501582243F, 0.9504591325F, 0.9507588105F, 0.9510572603F,
 664.910 +  0.9513544839F, 0.9516504834F, 0.9519452609F, 0.9522388186F,
 664.911 +  0.9525311584F, 0.9528222826F, 0.9531121932F, 0.9534008923F,
 664.912 +  0.9536883821F, 0.9539746647F, 0.9542597424F, 0.9545436171F,
 664.913 +  0.9548262912F, 0.9551077667F, 0.9553880459F, 0.9556671309F,
 664.914 +  0.9559450239F, 0.9562217272F, 0.9564972429F, 0.9567715733F,
 664.915 +  0.9570447206F, 0.9573166871F, 0.9575874749F, 0.9578570863F,
 664.916 +  0.9581255236F, 0.9583927890F, 0.9586588849F, 0.9589238134F,
 664.917 +  0.9591875769F, 0.9594501777F, 0.9597116180F, 0.9599719003F,
 664.918 +  0.9602310267F, 0.9604889995F, 0.9607458213F, 0.9610014942F,
 664.919 +  0.9612560206F, 0.9615094028F, 0.9617616433F, 0.9620127443F,
 664.920 +  0.9622627083F, 0.9625115376F, 0.9627592345F, 0.9630058016F,
 664.921 +  0.9632512411F, 0.9634955555F, 0.9637387471F, 0.9639808185F,
 664.922 +  0.9642217720F, 0.9644616100F, 0.9647003349F, 0.9649379493F,
 664.923 +  0.9651744556F, 0.9654098561F, 0.9656441534F, 0.9658773499F,
 664.924 +  0.9661094480F, 0.9663404504F, 0.9665703593F, 0.9667991774F,
 664.925 +  0.9670269071F, 0.9672535509F, 0.9674791114F, 0.9677035909F,
 664.926 +  0.9679269921F, 0.9681493174F, 0.9683705694F, 0.9685907506F,
 664.927 +  0.9688098636F, 0.9690279108F, 0.9692448948F, 0.9694608182F,
 664.928 +  0.9696756836F, 0.9698894934F, 0.9701022503F, 0.9703139569F,
 664.929 +  0.9705246156F, 0.9707342291F, 0.9709428000F, 0.9711503309F,
 664.930 +  0.9713568243F, 0.9715622829F, 0.9717667093F, 0.9719701060F,
 664.931 +  0.9721724757F, 0.9723738210F, 0.9725741446F, 0.9727734490F,
 664.932 +  0.9729717369F, 0.9731690109F, 0.9733652737F, 0.9735605279F,
 664.933 +  0.9737547762F, 0.9739480212F, 0.9741402656F, 0.9743315120F,
 664.934 +  0.9745217631F, 0.9747110216F, 0.9748992901F, 0.9750865714F,
 664.935 +  0.9752728681F, 0.9754581829F, 0.9756425184F, 0.9758258775F,
 664.936 +  0.9760082627F, 0.9761896768F, 0.9763701224F, 0.9765496024F,
 664.937 +  0.9767281193F, 0.9769056760F, 0.9770822751F, 0.9772579193F,
 664.938 +  0.9774326114F, 0.9776063542F, 0.9777791502F, 0.9779510023F,
 664.939 +  0.9781219133F, 0.9782918858F, 0.9784609226F, 0.9786290264F,
 664.940 +  0.9787962000F, 0.9789624461F, 0.9791277676F, 0.9792921671F,
 664.941 +  0.9794556474F, 0.9796182113F, 0.9797798615F, 0.9799406009F,
 664.942 +  0.9801004321F, 0.9802593580F, 0.9804173813F, 0.9805745049F,
 664.943 +  0.9807307314F, 0.9808860637F, 0.9810405046F, 0.9811940568F,
 664.944 +  0.9813467232F, 0.9814985065F, 0.9816494095F, 0.9817994351F,
 664.945 +  0.9819485860F, 0.9820968650F, 0.9822442750F, 0.9823908186F,
 664.946 +  0.9825364988F, 0.9826813184F, 0.9828252801F, 0.9829683868F,
 664.947 +  0.9831106413F, 0.9832520463F, 0.9833926048F, 0.9835323195F,
 664.948 +  0.9836711932F, 0.9838092288F, 0.9839464291F, 0.9840827969F,
 664.949 +  0.9842183351F, 0.9843530464F, 0.9844869337F, 0.9846199998F,
 664.950 +  0.9847522475F, 0.9848836798F, 0.9850142993F, 0.9851441090F,
 664.951 +  0.9852731117F, 0.9854013101F, 0.9855287073F, 0.9856553058F,
 664.952 +  0.9857811087F, 0.9859061188F, 0.9860303388F, 0.9861537717F,
 664.953 +  0.9862764202F, 0.9863982872F, 0.9865193756F, 0.9866396882F,
 664.954 +  0.9867592277F, 0.9868779972F, 0.9869959993F, 0.9871132370F,
 664.955 +  0.9872297131F, 0.9873454304F, 0.9874603918F, 0.9875746001F,
 664.956 +  0.9876880581F, 0.9878007688F, 0.9879127348F, 0.9880239592F,
 664.957 +  0.9881344447F, 0.9882441941F, 0.9883532104F, 0.9884614962F,
 664.958 +  0.9885690546F, 0.9886758883F, 0.9887820001F, 0.9888873930F,
 664.959 +  0.9889920697F, 0.9890960331F, 0.9891992859F, 0.9893018312F,
 664.960 +  0.9894036716F, 0.9895048100F, 0.9896052493F, 0.9897049923F,
 664.961 +  0.9898040418F, 0.9899024006F, 0.9900000717F, 0.9900970577F,
 664.962 +  0.9901933616F, 0.9902889862F, 0.9903839343F, 0.9904782087F,
 664.963 +  0.9905718122F, 0.9906647477F, 0.9907570180F, 0.9908486259F,
 664.964 +  0.9909395742F, 0.9910298658F, 0.9911195034F, 0.9912084899F,
 664.965 +  0.9912968281F, 0.9913845208F, 0.9914715708F, 0.9915579810F,
 664.966 +  0.9916437540F, 0.9917288928F, 0.9918134001F, 0.9918972788F,
 664.967 +  0.9919805316F, 0.9920631613F, 0.9921451707F, 0.9922265626F,
 664.968 +  0.9923073399F, 0.9923875052F, 0.9924670615F, 0.9925460114F,
 664.969 +  0.9926243577F, 0.9927021033F, 0.9927792508F, 0.9928558032F,
 664.970 +  0.9929317631F, 0.9930071333F, 0.9930819167F, 0.9931561158F,
 664.971 +  0.9932297337F, 0.9933027728F, 0.9933752362F, 0.9934471264F,
 664.972 +  0.9935184462F, 0.9935891985F, 0.9936593859F, 0.9937290112F,
 664.973 +  0.9937980771F, 0.9938665864F, 0.9939345418F, 0.9940019460F,
 664.974 +  0.9940688018F, 0.9941351118F, 0.9942008789F, 0.9942661057F,
 664.975 +  0.9943307950F, 0.9943949494F, 0.9944585717F, 0.9945216645F,
 664.976 +  0.9945842307F, 0.9946462728F, 0.9947077936F, 0.9947687957F,
 664.977 +  0.9948292820F, 0.9948892550F, 0.9949487174F, 0.9950076719F,
 664.978 +  0.9950661212F, 0.9951240679F, 0.9951815148F, 0.9952384645F,
 664.979 +  0.9952949196F, 0.9953508828F, 0.9954063568F, 0.9954613442F,
 664.980 +  0.9955158476F, 0.9955698697F, 0.9956234132F, 0.9956764806F,
 664.981 +  0.9957290746F, 0.9957811978F, 0.9958328528F, 0.9958840423F,
 664.982 +  0.9959347688F, 0.9959850351F, 0.9960348435F, 0.9960841969F,
 664.983 +  0.9961330977F, 0.9961815486F, 0.9962295521F, 0.9962771108F,
 664.984 +  0.9963242274F, 0.9963709043F, 0.9964171441F, 0.9964629494F,
 664.985 +  0.9965083228F, 0.9965532668F, 0.9965977840F, 0.9966418768F,
 664.986 +  0.9966855479F, 0.9967287998F, 0.9967716350F, 0.9968140559F,
 664.987 +  0.9968560653F, 0.9968976655F, 0.9969388591F, 0.9969796485F,
 664.988 +  0.9970200363F, 0.9970600250F, 0.9970996170F, 0.9971388149F,
 664.989 +  0.9971776211F, 0.9972160380F, 0.9972540683F, 0.9972917142F,
 664.990 +  0.9973289783F, 0.9973658631F, 0.9974023709F, 0.9974385042F,
 664.991 +  0.9974742655F, 0.9975096571F, 0.9975446816F, 0.9975793413F,
 664.992 +  0.9976136386F, 0.9976475759F, 0.9976811557F, 0.9977143803F,
 664.993 +  0.9977472521F, 0.9977797736F, 0.9978119470F, 0.9978437748F,
 664.994 +  0.9978752593F, 0.9979064029F, 0.9979372079F, 0.9979676768F,
 664.995 +  0.9979978117F, 0.9980276151F, 0.9980570893F, 0.9980862367F,
 664.996 +  0.9981150595F, 0.9981435600F, 0.9981717406F, 0.9981996035F,
 664.997 +  0.9982271511F, 0.9982543856F, 0.9982813093F, 0.9983079246F,
 664.998 +  0.9983342336F, 0.9983602386F, 0.9983859418F, 0.9984113456F,
 664.999 +  0.9984364522F, 0.9984612638F, 0.9984857825F, 0.9985100108F,
664.1000 +  0.9985339507F, 0.9985576044F, 0.9985809743F, 0.9986040624F,
664.1001 +  0.9986268710F, 0.9986494022F, 0.9986716583F, 0.9986936413F,
664.1002 +  0.9987153535F, 0.9987367969F, 0.9987579738F, 0.9987788864F,
664.1003 +  0.9987995366F, 0.9988199267F, 0.9988400587F, 0.9988599348F,
664.1004 +  0.9988795572F, 0.9988989278F, 0.9989180487F, 0.9989369222F,
664.1005 +  0.9989555501F, 0.9989739347F, 0.9989920780F, 0.9990099820F,
664.1006 +  0.9990276487F, 0.9990450803F, 0.9990622787F, 0.9990792460F,
664.1007 +  0.9990959841F, 0.9991124952F, 0.9991287812F, 0.9991448440F,
664.1008 +  0.9991606858F, 0.9991763084F, 0.9991917139F, 0.9992069042F,
664.1009 +  0.9992218813F, 0.9992366471F, 0.9992512035F, 0.9992655525F,
664.1010 +  0.9992796961F, 0.9992936361F, 0.9993073744F, 0.9993209131F,
664.1011 +  0.9993342538F, 0.9993473987F, 0.9993603494F, 0.9993731080F,
664.1012 +  0.9993856762F, 0.9993980559F, 0.9994102490F, 0.9994222573F,
664.1013 +  0.9994340827F, 0.9994457269F, 0.9994571918F, 0.9994684793F,
664.1014 +  0.9994795910F, 0.9994905288F, 0.9995012945F, 0.9995118898F,
664.1015 +  0.9995223165F, 0.9995325765F, 0.9995426713F, 0.9995526029F,
664.1016 +  0.9995623728F, 0.9995719829F, 0.9995814349F, 0.9995907304F,
664.1017 +  0.9995998712F, 0.9996088590F, 0.9996176954F, 0.9996263821F,
664.1018 +  0.9996349208F, 0.9996433132F, 0.9996515609F, 0.9996596656F,
664.1019 +  0.9996676288F, 0.9996754522F, 0.9996831375F, 0.9996906862F,
664.1020 +  0.9996981000F, 0.9997053804F, 0.9997125290F, 0.9997195474F,
664.1021 +  0.9997264371F, 0.9997331998F, 0.9997398369F, 0.9997463500F,
664.1022 +  0.9997527406F, 0.9997590103F, 0.9997651606F, 0.9997711930F,
664.1023 +  0.9997771089F, 0.9997829098F, 0.9997885973F, 0.9997941728F,
664.1024 +  0.9997996378F, 0.9998049936F, 0.9998102419F, 0.9998153839F,
664.1025 +  0.9998204211F, 0.9998253550F, 0.9998301868F, 0.9998349182F,
664.1026 +  0.9998395503F, 0.9998440847F, 0.9998485226F, 0.9998528654F,
664.1027 +  0.9998571146F, 0.9998612713F, 0.9998653370F, 0.9998693130F,
664.1028 +  0.9998732007F, 0.9998770012F, 0.9998807159F, 0.9998843461F,
664.1029 +  0.9998878931F, 0.9998913581F, 0.9998947424F, 0.9998980473F,
664.1030 +  0.9999012740F, 0.9999044237F, 0.9999074976F, 0.9999104971F,
664.1031 +  0.9999134231F, 0.9999162771F, 0.9999190601F, 0.9999217733F,
664.1032 +  0.9999244179F, 0.9999269950F, 0.9999295058F, 0.9999319515F,
664.1033 +  0.9999343332F, 0.9999366519F, 0.9999389088F, 0.9999411050F,
664.1034 +  0.9999432416F, 0.9999453196F, 0.9999473402F, 0.9999493044F,
664.1035 +  0.9999512132F, 0.9999530677F, 0.9999548690F, 0.9999566180F,
664.1036 +  0.9999583157F, 0.9999599633F, 0.9999615616F, 0.9999631116F,
664.1037 +  0.9999646144F, 0.9999660709F, 0.9999674820F, 0.9999688487F,
664.1038 +  0.9999701719F, 0.9999714526F, 0.9999726917F, 0.9999738900F,
664.1039 +  0.9999750486F, 0.9999761682F, 0.9999772497F, 0.9999782941F,
664.1040 +  0.9999793021F, 0.9999802747F, 0.9999812126F, 0.9999821167F,
664.1041 +  0.9999829878F, 0.9999838268F, 0.9999846343F, 0.9999854113F,
664.1042 +  0.9999861584F, 0.9999868765F, 0.9999875664F, 0.9999882287F,
664.1043 +  0.9999888642F, 0.9999894736F, 0.9999900577F, 0.9999906172F,
664.1044 +  0.9999911528F, 0.9999916651F, 0.9999921548F, 0.9999926227F,
664.1045 +  0.9999930693F, 0.9999934954F, 0.9999939015F, 0.9999942883F,
664.1046 +  0.9999946564F, 0.9999950064F, 0.9999953390F, 0.9999956547F,
664.1047 +  0.9999959541F, 0.9999962377F, 0.9999965062F, 0.9999967601F,
664.1048 +  0.9999969998F, 0.9999972260F, 0.9999974392F, 0.9999976399F,
664.1049 +  0.9999978285F, 0.9999980056F, 0.9999981716F, 0.9999983271F,
664.1050 +  0.9999984724F, 0.9999986081F, 0.9999987345F, 0.9999988521F,
664.1051 +  0.9999989613F, 0.9999990625F, 0.9999991562F, 0.9999992426F,
664.1052 +  0.9999993223F, 0.9999993954F, 0.9999994625F, 0.9999995239F,
664.1053 +  0.9999995798F, 0.9999996307F, 0.9999996768F, 0.9999997184F,
664.1054 +  0.9999997559F, 0.9999997895F, 0.9999998195F, 0.9999998462F,
664.1055 +  0.9999998698F, 0.9999998906F, 0.9999999088F, 0.9999999246F,
664.1056 +  0.9999999383F, 0.9999999500F, 0.9999999600F, 0.9999999684F,
664.1057 +  0.9999999754F, 0.9999999811F, 0.9999999858F, 0.9999999896F,
664.1058 +  0.9999999925F, 0.9999999948F, 0.9999999965F, 0.9999999978F,
664.1059 +  0.9999999986F, 0.9999999992F, 0.9999999996F, 0.9999999998F,
664.1060 +  0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F,
664.1061 +};
664.1062 +
664.1063 +static const float vwin8192[4096] = {
664.1064 +  0.0000000578F, 0.0000005198F, 0.0000014438F, 0.0000028299F,
664.1065 +  0.0000046780F, 0.0000069882F, 0.0000097604F, 0.0000129945F,
664.1066 +  0.0000166908F, 0.0000208490F, 0.0000254692F, 0.0000305515F,
664.1067 +  0.0000360958F, 0.0000421021F, 0.0000485704F, 0.0000555006F,
664.1068 +  0.0000628929F, 0.0000707472F, 0.0000790635F, 0.0000878417F,
664.1069 +  0.0000970820F, 0.0001067842F, 0.0001169483F, 0.0001275744F,
664.1070 +  0.0001386625F, 0.0001502126F, 0.0001622245F, 0.0001746984F,
664.1071 +  0.0001876343F, 0.0002010320F, 0.0002148917F, 0.0002292132F,
664.1072 +  0.0002439967F, 0.0002592421F, 0.0002749493F, 0.0002911184F,
664.1073 +  0.0003077493F, 0.0003248421F, 0.0003423967F, 0.0003604132F,
664.1074 +  0.0003788915F, 0.0003978316F, 0.0004172335F, 0.0004370971F,
664.1075 +  0.0004574226F, 0.0004782098F, 0.0004994587F, 0.0005211694F,
664.1076 +  0.0005433418F, 0.0005659759F, 0.0005890717F, 0.0006126292F,
664.1077 +  0.0006366484F, 0.0006611292F, 0.0006860716F, 0.0007114757F,
664.1078 +  0.0007373414F, 0.0007636687F, 0.0007904576F, 0.0008177080F,
664.1079 +  0.0008454200F, 0.0008735935F, 0.0009022285F, 0.0009313250F,
664.1080 +  0.0009608830F, 0.0009909025F, 0.0010213834F, 0.0010523257F,
664.1081 +  0.0010837295F, 0.0011155946F, 0.0011479211F, 0.0011807090F,
664.1082 +  0.0012139582F, 0.0012476687F, 0.0012818405F, 0.0013164736F,
664.1083 +  0.0013515679F, 0.0013871235F, 0.0014231402F, 0.0014596182F,
664.1084 +  0.0014965573F, 0.0015339576F, 0.0015718190F, 0.0016101415F,
664.1085 +  0.0016489251F, 0.0016881698F, 0.0017278754F, 0.0017680421F,
664.1086 +  0.0018086698F, 0.0018497584F, 0.0018913080F, 0.0019333185F,
664.1087 +  0.0019757898F, 0.0020187221F, 0.0020621151F, 0.0021059690F,
664.1088 +  0.0021502837F, 0.0021950591F, 0.0022402953F, 0.0022859921F,
664.1089 +  0.0023321497F, 0.0023787679F, 0.0024258467F, 0.0024733861F,
664.1090 +  0.0025213861F, 0.0025698466F, 0.0026187676F, 0.0026681491F,
664.1091 +  0.0027179911F, 0.0027682935F, 0.0028190562F, 0.0028702794F,
664.1092 +  0.0029219628F, 0.0029741066F, 0.0030267107F, 0.0030797749F,
664.1093 +  0.0031332994F, 0.0031872841F, 0.0032417289F, 0.0032966338F,
664.1094 +  0.0033519988F, 0.0034078238F, 0.0034641089F, 0.0035208539F,
664.1095 +  0.0035780589F, 0.0036357237F, 0.0036938485F, 0.0037524331F,
664.1096 +  0.0038114775F, 0.0038709817F, 0.0039309456F, 0.0039913692F,
664.1097 +  0.0040522524F, 0.0041135953F, 0.0041753978F, 0.0042376599F,
664.1098 +  0.0043003814F, 0.0043635624F, 0.0044272029F, 0.0044913028F,
664.1099 +  0.0045558620F, 0.0046208806F, 0.0046863585F, 0.0047522955F,
664.1100 +  0.0048186919F, 0.0048855473F, 0.0049528619F, 0.0050206356F,
664.1101 +  0.0050888684F, 0.0051575601F, 0.0052267108F, 0.0052963204F,
664.1102 +  0.0053663890F, 0.0054369163F, 0.0055079025F, 0.0055793474F,
664.1103 +  0.0056512510F, 0.0057236133F, 0.0057964342F, 0.0058697137F,
664.1104 +  0.0059434517F, 0.0060176482F, 0.0060923032F, 0.0061674166F,
664.1105 +  0.0062429883F, 0.0063190183F, 0.0063955066F, 0.0064724532F,
664.1106 +  0.0065498579F, 0.0066277207F, 0.0067060416F, 0.0067848205F,
664.1107 +  0.0068640575F, 0.0069437523F, 0.0070239051F, 0.0071045157F,
664.1108 +  0.0071855840F, 0.0072671102F, 0.0073490940F, 0.0074315355F,
664.1109 +  0.0075144345F, 0.0075977911F, 0.0076816052F, 0.0077658768F,
664.1110 +  0.0078506057F, 0.0079357920F, 0.0080214355F, 0.0081075363F,
664.1111 +  0.0081940943F, 0.0082811094F, 0.0083685816F, 0.0084565108F,
664.1112 +  0.0085448970F, 0.0086337401F, 0.0087230401F, 0.0088127969F,
664.1113 +  0.0089030104F, 0.0089936807F, 0.0090848076F, 0.0091763911F,
664.1114 +  0.0092684311F, 0.0093609276F, 0.0094538805F, 0.0095472898F,
664.1115 +  0.0096411554F, 0.0097354772F, 0.0098302552F, 0.0099254894F,
664.1116 +  0.0100211796F, 0.0101173259F, 0.0102139281F, 0.0103109863F,
664.1117 +  0.0104085002F, 0.0105064700F, 0.0106048955F, 0.0107037766F,
664.1118 +  0.0108031133F, 0.0109029056F, 0.0110031534F, 0.0111038565F,
664.1119 +  0.0112050151F, 0.0113066289F, 0.0114086980F, 0.0115112222F,
664.1120 +  0.0116142015F, 0.0117176359F, 0.0118215252F, 0.0119258695F,
664.1121 +  0.0120306686F, 0.0121359225F, 0.0122416312F, 0.0123477944F,
664.1122 +  0.0124544123F, 0.0125614847F, 0.0126690116F, 0.0127769928F,
664.1123 +  0.0128854284F, 0.0129943182F, 0.0131036623F, 0.0132134604F,
664.1124 +  0.0133237126F, 0.0134344188F, 0.0135455790F, 0.0136571929F,
664.1125 +  0.0137692607F, 0.0138817821F, 0.0139947572F, 0.0141081859F,
664.1126 +  0.0142220681F, 0.0143364037F, 0.0144511927F, 0.0145664350F,
664.1127 +  0.0146821304F, 0.0147982791F, 0.0149148808F, 0.0150319355F,
664.1128 +  0.0151494431F, 0.0152674036F, 0.0153858168F, 0.0155046828F,
664.1129 +  0.0156240014F, 0.0157437726F, 0.0158639962F, 0.0159846723F,
664.1130 +  0.0161058007F, 0.0162273814F, 0.0163494142F, 0.0164718991F,
664.1131 +  0.0165948361F, 0.0167182250F, 0.0168420658F, 0.0169663584F,
664.1132 +  0.0170911027F, 0.0172162987F, 0.0173419462F, 0.0174680452F,
664.1133 +  0.0175945956F, 0.0177215974F, 0.0178490504F, 0.0179769545F,
664.1134 +  0.0181053098F, 0.0182341160F, 0.0183633732F, 0.0184930812F,
664.1135 +  0.0186232399F, 0.0187538494F, 0.0188849094F, 0.0190164200F,
664.1136 +  0.0191483809F, 0.0192807923F, 0.0194136539F, 0.0195469656F,
664.1137 +  0.0196807275F, 0.0198149394F, 0.0199496012F, 0.0200847128F,
664.1138 +  0.0202202742F, 0.0203562853F, 0.0204927460F, 0.0206296561F,
664.1139 +  0.0207670157F, 0.0209048245F, 0.0210430826F, 0.0211817899F,
664.1140 +  0.0213209462F, 0.0214605515F, 0.0216006057F, 0.0217411086F,
664.1141 +  0.0218820603F, 0.0220234605F, 0.0221653093F, 0.0223076066F,
664.1142 +  0.0224503521F, 0.0225935459F, 0.0227371879F, 0.0228812779F,
664.1143 +  0.0230258160F, 0.0231708018F, 0.0233162355F, 0.0234621169F,
664.1144 +  0.0236084459F, 0.0237552224F, 0.0239024462F, 0.0240501175F,
664.1145 +  0.0241982359F, 0.0243468015F, 0.0244958141F, 0.0246452736F,
664.1146 +  0.0247951800F, 0.0249455331F, 0.0250963329F, 0.0252475792F,
664.1147 +  0.0253992720F, 0.0255514111F, 0.0257039965F, 0.0258570281F,
664.1148 +  0.0260105057F, 0.0261644293F, 0.0263187987F, 0.0264736139F,
664.1149 +  0.0266288747F, 0.0267845811F, 0.0269407330F, 0.0270973302F,
664.1150 +  0.0272543727F, 0.0274118604F, 0.0275697930F, 0.0277281707F,
664.1151 +  0.0278869932F, 0.0280462604F, 0.0282059723F, 0.0283661287F,
664.1152 +  0.0285267295F, 0.0286877747F, 0.0288492641F, 0.0290111976F,
664.1153 +  0.0291735751F, 0.0293363965F, 0.0294996617F, 0.0296633706F,
664.1154 +  0.0298275231F, 0.0299921190F, 0.0301571583F, 0.0303226409F,
664.1155 +  0.0304885667F, 0.0306549354F, 0.0308217472F, 0.0309890017F,
664.1156 +  0.0311566989F, 0.0313248388F, 0.0314934211F, 0.0316624459F,
664.1157 +  0.0318319128F, 0.0320018220F, 0.0321721732F, 0.0323429663F,
664.1158 +  0.0325142013F, 0.0326858779F, 0.0328579962F, 0.0330305559F,
664.1159 +  0.0332035570F, 0.0333769994F, 0.0335508829F, 0.0337252074F,
664.1160 +  0.0338999728F, 0.0340751790F, 0.0342508259F, 0.0344269134F,
664.1161 +  0.0346034412F, 0.0347804094F, 0.0349578178F, 0.0351356663F,
664.1162 +  0.0353139548F, 0.0354926831F, 0.0356718511F, 0.0358514588F,
664.1163 +  0.0360315059F, 0.0362119924F, 0.0363929182F, 0.0365742831F,
664.1164 +  0.0367560870F, 0.0369383297F, 0.0371210113F, 0.0373041315F,
664.1165 +  0.0374876902F, 0.0376716873F, 0.0378561226F, 0.0380409961F,
664.1166 +  0.0382263077F, 0.0384120571F, 0.0385982443F, 0.0387848691F,
664.1167 +  0.0389719315F, 0.0391594313F, 0.0393473683F, 0.0395357425F,
664.1168 +  0.0397245537F, 0.0399138017F, 0.0401034866F, 0.0402936080F,
664.1169 +  0.0404841660F, 0.0406751603F, 0.0408665909F, 0.0410584576F,
664.1170 +  0.0412507603F, 0.0414434988F, 0.0416366731F, 0.0418302829F,
664.1171 +  0.0420243282F, 0.0422188088F, 0.0424137246F, 0.0426090755F,
664.1172 +  0.0428048613F, 0.0430010819F, 0.0431977371F, 0.0433948269F,
664.1173 +  0.0435923511F, 0.0437903095F, 0.0439887020F, 0.0441875285F,
664.1174 +  0.0443867889F, 0.0445864830F, 0.0447866106F, 0.0449871717F,
664.1175 +  0.0451881661F, 0.0453895936F, 0.0455914542F, 0.0457937477F,
664.1176 +  0.0459964738F, 0.0461996326F, 0.0464032239F, 0.0466072475F,
664.1177 +  0.0468117032F, 0.0470165910F, 0.0472219107F, 0.0474276622F,
664.1178 +  0.0476338452F, 0.0478404597F, 0.0480475056F, 0.0482549827F,
664.1179 +  0.0484628907F, 0.0486712297F, 0.0488799994F, 0.0490891998F,
664.1180 +  0.0492988306F, 0.0495088917F, 0.0497193830F, 0.0499303043F,
664.1181 +  0.0501416554F, 0.0503534363F, 0.0505656468F, 0.0507782867F,
664.1182 +  0.0509913559F, 0.0512048542F, 0.0514187815F, 0.0516331376F,
664.1183 +  0.0518479225F, 0.0520631358F, 0.0522787775F, 0.0524948475F,
664.1184 +  0.0527113455F, 0.0529282715F, 0.0531456252F, 0.0533634066F,
664.1185 +  0.0535816154F, 0.0538002515F, 0.0540193148F, 0.0542388051F,
664.1186 +  0.0544587222F, 0.0546790660F, 0.0548998364F, 0.0551210331F,
664.1187 +  0.0553426561F, 0.0555647051F, 0.0557871801F, 0.0560100807F,
664.1188 +  0.0562334070F, 0.0564571587F, 0.0566813357F, 0.0569059378F,
664.1189 +  0.0571309649F, 0.0573564168F, 0.0575822933F, 0.0578085942F,
664.1190 +  0.0580353195F, 0.0582624689F, 0.0584900423F, 0.0587180396F,
664.1191 +  0.0589464605F, 0.0591753049F, 0.0594045726F, 0.0596342635F,
664.1192 +  0.0598643774F, 0.0600949141F, 0.0603258735F, 0.0605572555F,
664.1193 +  0.0607890597F, 0.0610212862F, 0.0612539346F, 0.0614870049F,
664.1194 +  0.0617204968F, 0.0619544103F, 0.0621887451F, 0.0624235010F,
664.1195 +  0.0626586780F, 0.0628942758F, 0.0631302942F, 0.0633667331F,
664.1196 +  0.0636035923F, 0.0638408717F, 0.0640785710F, 0.0643166901F,
664.1197 +  0.0645552288F, 0.0647941870F, 0.0650335645F, 0.0652733610F,
664.1198 +  0.0655135765F, 0.0657542108F, 0.0659952636F, 0.0662367348F,
664.1199 +  0.0664786242F, 0.0667209316F, 0.0669636570F, 0.0672068000F,
664.1200 +  0.0674503605F, 0.0676943384F, 0.0679387334F, 0.0681835454F,
664.1201 +  0.0684287742F, 0.0686744196F, 0.0689204814F, 0.0691669595F,
664.1202 +  0.0694138536F, 0.0696611637F, 0.0699088894F, 0.0701570307F,
664.1203 +  0.0704055873F, 0.0706545590F, 0.0709039458F, 0.0711537473F,
664.1204 +  0.0714039634F, 0.0716545939F, 0.0719056387F, 0.0721570975F,
664.1205 +  0.0724089702F, 0.0726612565F, 0.0729139563F, 0.0731670694F,
664.1206 +  0.0734205956F, 0.0736745347F, 0.0739288866F, 0.0741836510F,
664.1207 +  0.0744388277F, 0.0746944166F, 0.0749504175F, 0.0752068301F,
664.1208 +  0.0754636543F, 0.0757208899F, 0.0759785367F, 0.0762365946F,
664.1209 +  0.0764950632F, 0.0767539424F, 0.0770132320F, 0.0772729319F,
664.1210 +  0.0775330418F, 0.0777935616F, 0.0780544909F, 0.0783158298F,
664.1211 +  0.0785775778F, 0.0788397349F, 0.0791023009F, 0.0793652755F,
664.1212 +  0.0796286585F, 0.0798924498F, 0.0801566492F, 0.0804212564F,
664.1213 +  0.0806862712F, 0.0809516935F, 0.0812175231F, 0.0814837597F,
664.1214 +  0.0817504031F, 0.0820174532F, 0.0822849097F, 0.0825527724F,
664.1215 +  0.0828210412F, 0.0830897158F, 0.0833587960F, 0.0836282816F,
664.1216 +  0.0838981724F, 0.0841684682F, 0.0844391688F, 0.0847102740F,
664.1217 +  0.0849817835F, 0.0852536973F, 0.0855260150F, 0.0857987364F,
664.1218 +  0.0860718614F, 0.0863453897F, 0.0866193211F, 0.0868936554F,
664.1219 +  0.0871683924F, 0.0874435319F, 0.0877190737F, 0.0879950175F,
664.1220 +  0.0882713632F, 0.0885481105F, 0.0888252592F, 0.0891028091F,
664.1221 +  0.0893807600F, 0.0896591117F, 0.0899378639F, 0.0902170165F,
664.1222 +  0.0904965692F, 0.0907765218F, 0.0910568740F, 0.0913376258F,
664.1223 +  0.0916187767F, 0.0919003268F, 0.0921822756F, 0.0924646230F,
664.1224 +  0.0927473687F, 0.0930305126F, 0.0933140545F, 0.0935979940F,
664.1225 +  0.0938823310F, 0.0941670653F, 0.0944521966F, 0.0947377247F,
664.1226 +  0.0950236494F, 0.0953099704F, 0.0955966876F, 0.0958838007F,
664.1227 +  0.0961713094F, 0.0964592136F, 0.0967475131F, 0.0970362075F,
664.1228 +  0.0973252967F, 0.0976147805F, 0.0979046585F, 0.0981949307F,
664.1229 +  0.0984855967F, 0.0987766563F, 0.0990681093F, 0.0993599555F,
664.1230 +  0.0996521945F, 0.0999448263F, 0.1002378506F, 0.1005312671F,
664.1231 +  0.1008250755F, 0.1011192757F, 0.1014138675F, 0.1017088505F,
664.1232 +  0.1020042246F, 0.1022999895F, 0.1025961450F, 0.1028926909F,
664.1233 +  0.1031896268F, 0.1034869526F, 0.1037846680F, 0.1040827729F,
664.1234 +  0.1043812668F, 0.1046801497F, 0.1049794213F, 0.1052790813F,
664.1235 +  0.1055791294F, 0.1058795656F, 0.1061803894F, 0.1064816006F,
664.1236 +  0.1067831991F, 0.1070851846F, 0.1073875568F, 0.1076903155F,
664.1237 +  0.1079934604F, 0.1082969913F, 0.1086009079F, 0.1089052101F,
664.1238 +  0.1092098975F, 0.1095149699F, 0.1098204270F, 0.1101262687F,
664.1239 +  0.1104324946F, 0.1107391045F, 0.1110460982F, 0.1113534754F,
664.1240 +  0.1116612359F, 0.1119693793F, 0.1122779055F, 0.1125868142F,
664.1241 +  0.1128961052F, 0.1132057781F, 0.1135158328F, 0.1138262690F,
664.1242 +  0.1141370863F, 0.1144482847F, 0.1147598638F, 0.1150718233F,
664.1243 +  0.1153841631F, 0.1156968828F, 0.1160099822F, 0.1163234610F,
664.1244 +  0.1166373190F, 0.1169515559F, 0.1172661714F, 0.1175811654F,
664.1245 +  0.1178965374F, 0.1182122874F, 0.1185284149F, 0.1188449198F,
664.1246 +  0.1191618018F, 0.1194790606F, 0.1197966960F, 0.1201147076F,
664.1247 +  0.1204330953F, 0.1207518587F, 0.1210709976F, 0.1213905118F,
664.1248 +  0.1217104009F, 0.1220306647F, 0.1223513029F, 0.1226723153F,
664.1249 +  0.1229937016F, 0.1233154615F, 0.1236375948F, 0.1239601011F,
664.1250 +  0.1242829803F, 0.1246062319F, 0.1249298559F, 0.1252538518F,
664.1251 +  0.1255782195F, 0.1259029586F, 0.1262280689F, 0.1265535501F,
664.1252 +  0.1268794019F, 0.1272056241F, 0.1275322163F, 0.1278591784F,
664.1253 +  0.1281865099F, 0.1285142108F, 0.1288422805F, 0.1291707190F,
664.1254 +  0.1294995259F, 0.1298287009F, 0.1301582437F, 0.1304881542F,
664.1255 +  0.1308184319F, 0.1311490766F, 0.1314800881F, 0.1318114660F,
664.1256 +  0.1321432100F, 0.1324753200F, 0.1328077955F, 0.1331406364F,
664.1257 +  0.1334738422F, 0.1338074129F, 0.1341413479F, 0.1344756472F,
664.1258 +  0.1348103103F, 0.1351453370F, 0.1354807270F, 0.1358164801F,
664.1259 +  0.1361525959F, 0.1364890741F, 0.1368259145F, 0.1371631167F,
664.1260 +  0.1375006805F, 0.1378386056F, 0.1381768917F, 0.1385155384F,
664.1261 +  0.1388545456F, 0.1391939129F, 0.1395336400F, 0.1398737266F,
664.1262 +  0.1402141724F, 0.1405549772F, 0.1408961406F, 0.1412376623F,
664.1263 +  0.1415795421F, 0.1419217797F, 0.1422643746F, 0.1426073268F,
664.1264 +  0.1429506358F, 0.1432943013F, 0.1436383231F, 0.1439827008F,
664.1265 +  0.1443274342F, 0.1446725229F, 0.1450179667F, 0.1453637652F,
664.1266 +  0.1457099181F, 0.1460564252F, 0.1464032861F, 0.1467505006F,
664.1267 +  0.1470980682F, 0.1474459888F, 0.1477942620F, 0.1481428875F,
664.1268 +  0.1484918651F, 0.1488411942F, 0.1491908748F, 0.1495409065F,
664.1269 +  0.1498912889F, 0.1502420218F, 0.1505931048F, 0.1509445376F,
664.1270 +  0.1512963200F, 0.1516484516F, 0.1520009321F, 0.1523537612F,
664.1271 +  0.1527069385F, 0.1530604638F, 0.1534143368F, 0.1537685571F,
664.1272 +  0.1541231244F, 0.1544780384F, 0.1548332987F, 0.1551889052F,
664.1273 +  0.1555448574F, 0.1559011550F, 0.1562577978F, 0.1566147853F,
664.1274 +  0.1569721173F, 0.1573297935F, 0.1576878135F, 0.1580461771F,
664.1275 +  0.1584048838F, 0.1587639334F, 0.1591233255F, 0.1594830599F,
664.1276 +  0.1598431361F, 0.1602035540F, 0.1605643131F, 0.1609254131F,
664.1277 +  0.1612868537F, 0.1616486346F, 0.1620107555F, 0.1623732160F,
664.1278 +  0.1627360158F, 0.1630991545F, 0.1634626319F, 0.1638264476F,
664.1279 +  0.1641906013F, 0.1645550926F, 0.1649199212F, 0.1652850869F,
664.1280 +  0.1656505892F, 0.1660164278F, 0.1663826024F, 0.1667491127F,
664.1281 +  0.1671159583F, 0.1674831388F, 0.1678506541F, 0.1682185036F,
664.1282 +  0.1685866872F, 0.1689552044F, 0.1693240549F, 0.1696932384F,
664.1283 +  0.1700627545F, 0.1704326029F, 0.1708027833F, 0.1711732952F,
664.1284 +  0.1715441385F, 0.1719153127F, 0.1722868175F, 0.1726586526F,
664.1285 +  0.1730308176F, 0.1734033121F, 0.1737761359F, 0.1741492886F,
664.1286 +  0.1745227698F, 0.1748965792F, 0.1752707164F, 0.1756451812F,
664.1287 +  0.1760199731F, 0.1763950918F, 0.1767705370F, 0.1771463083F,
664.1288 +  0.1775224054F, 0.1778988279F, 0.1782755754F, 0.1786526477F,
664.1289 +  0.1790300444F, 0.1794077651F, 0.1797858094F, 0.1801641771F,
664.1290 +  0.1805428677F, 0.1809218810F, 0.1813012165F, 0.1816808739F,
664.1291 +  0.1820608528F, 0.1824411530F, 0.1828217739F, 0.1832027154F,
664.1292 +  0.1835839770F, 0.1839655584F, 0.1843474592F, 0.1847296790F,
664.1293 +  0.1851122175F, 0.1854950744F, 0.1858782492F, 0.1862617417F,
664.1294 +  0.1866455514F, 0.1870296780F, 0.1874141211F, 0.1877988804F,
664.1295 +  0.1881839555F, 0.1885693461F, 0.1889550517F, 0.1893410721F,
664.1296 +  0.1897274068F, 0.1901140555F, 0.1905010178F, 0.1908882933F,
664.1297 +  0.1912758818F, 0.1916637828F, 0.1920519959F, 0.1924405208F,
664.1298 +  0.1928293571F, 0.1932185044F, 0.1936079625F, 0.1939977308F,
664.1299 +  0.1943878091F, 0.1947781969F, 0.1951688939F, 0.1955598998F,
664.1300 +  0.1959512141F, 0.1963428364F, 0.1967347665F, 0.1971270038F,
664.1301 +  0.1975195482F, 0.1979123990F, 0.1983055561F, 0.1986990190F,
664.1302 +  0.1990927873F, 0.1994868607F, 0.1998812388F, 0.2002759212F,
664.1303 +  0.2006709075F, 0.2010661974F, 0.2014617904F, 0.2018576862F,
664.1304 +  0.2022538844F, 0.2026503847F, 0.2030471865F, 0.2034442897F,
664.1305 +  0.2038416937F, 0.2042393982F, 0.2046374028F, 0.2050357071F,
664.1306 +  0.2054343107F, 0.2058332133F, 0.2062324145F, 0.2066319138F,
664.1307 +  0.2070317110F, 0.2074318055F, 0.2078321970F, 0.2082328852F,
664.1308 +  0.2086338696F, 0.2090351498F, 0.2094367255F, 0.2098385962F,
664.1309 +  0.2102407617F, 0.2106432213F, 0.2110459749F, 0.2114490220F,
664.1310 +  0.2118523621F, 0.2122559950F, 0.2126599202F, 0.2130641373F,
664.1311 +  0.2134686459F, 0.2138734456F, 0.2142785361F, 0.2146839168F,
664.1312 +  0.2150895875F, 0.2154955478F, 0.2159017972F, 0.2163083353F,
664.1313 +  0.2167151617F, 0.2171222761F, 0.2175296780F, 0.2179373670F,
664.1314 +  0.2183453428F, 0.2187536049F, 0.2191621529F, 0.2195709864F,
664.1315 +  0.2199801051F, 0.2203895085F, 0.2207991961F, 0.2212091677F,
664.1316 +  0.2216194228F, 0.2220299610F, 0.2224407818F, 0.2228518850F,
664.1317 +  0.2232632699F, 0.2236749364F, 0.2240868839F, 0.2244991121F,
664.1318 +  0.2249116204F, 0.2253244086F, 0.2257374763F, 0.2261508229F,
664.1319 +  0.2265644481F, 0.2269783514F, 0.2273925326F, 0.2278069911F,
664.1320 +  0.2282217265F, 0.2286367384F, 0.2290520265F, 0.2294675902F,
664.1321 +  0.2298834292F, 0.2302995431F, 0.2307159314F, 0.2311325937F,
664.1322 +  0.2315495297F, 0.2319667388F, 0.2323842207F, 0.2328019749F,
664.1323 +  0.2332200011F, 0.2336382988F, 0.2340568675F, 0.2344757070F,
664.1324 +  0.2348948166F, 0.2353141961F, 0.2357338450F, 0.2361537629F,
664.1325 +  0.2365739493F, 0.2369944038F, 0.2374151261F, 0.2378361156F,
664.1326 +  0.2382573720F, 0.2386788948F, 0.2391006836F, 0.2395227380F,
664.1327 +  0.2399450575F, 0.2403676417F, 0.2407904902F, 0.2412136026F,
664.1328 +  0.2416369783F, 0.2420606171F, 0.2424845185F, 0.2429086820F,
664.1329 +  0.2433331072F, 0.2437577936F, 0.2441827409F, 0.2446079486F,
664.1330 +  0.2450334163F, 0.2454591435F, 0.2458851298F, 0.2463113747F,
664.1331 +  0.2467378779F, 0.2471646389F, 0.2475916573F, 0.2480189325F,
664.1332 +  0.2484464643F, 0.2488742521F, 0.2493022955F, 0.2497305940F,
664.1333 +  0.2501591473F, 0.2505879549F, 0.2510170163F, 0.2514463311F,
664.1334 +  0.2518758989F, 0.2523057193F, 0.2527357916F, 0.2531661157F,
664.1335 +  0.2535966909F, 0.2540275169F, 0.2544585931F, 0.2548899193F,
664.1336 +  0.2553214948F, 0.2557533193F, 0.2561853924F, 0.2566177135F,
664.1337 +  0.2570502822F, 0.2574830981F, 0.2579161608F, 0.2583494697F,
664.1338 +  0.2587830245F, 0.2592168246F, 0.2596508697F, 0.2600851593F,
664.1339 +  0.2605196929F, 0.2609544701F, 0.2613894904F, 0.2618247534F,
664.1340 +  0.2622602586F, 0.2626960055F, 0.2631319938F, 0.2635682230F,
664.1341 +  0.2640046925F, 0.2644414021F, 0.2648783511F, 0.2653155391F,
664.1342 +  0.2657529657F, 0.2661906305F, 0.2666285329F, 0.2670666725F,
664.1343 +  0.2675050489F, 0.2679436616F, 0.2683825101F, 0.2688215940F,
664.1344 +  0.2692609127F, 0.2697004660F, 0.2701402532F, 0.2705802739F,
664.1345 +  0.2710205278F, 0.2714610142F, 0.2719017327F, 0.2723426830F,
664.1346 +  0.2727838644F, 0.2732252766F, 0.2736669191F, 0.2741087914F,
664.1347 +  0.2745508930F, 0.2749932235F, 0.2754357824F, 0.2758785693F,
664.1348 +  0.2763215837F, 0.2767648251F, 0.2772082930F, 0.2776519870F,
664.1349 +  0.2780959066F, 0.2785400513F, 0.2789844207F, 0.2794290143F,
664.1350 +  0.2798738316F, 0.2803188722F, 0.2807641355F, 0.2812096211F,
664.1351 +  0.2816553286F, 0.2821012574F, 0.2825474071F, 0.2829937773F,
664.1352 +  0.2834403673F, 0.2838871768F, 0.2843342053F, 0.2847814523F,
664.1353 +  0.2852289174F, 0.2856765999F, 0.2861244996F, 0.2865726159F,
664.1354 +  0.2870209482F, 0.2874694962F, 0.2879182594F, 0.2883672372F,
664.1355 +  0.2888164293F, 0.2892658350F, 0.2897154540F, 0.2901652858F,
664.1356 +  0.2906153298F, 0.2910655856F, 0.2915160527F, 0.2919667306F,
664.1357 +  0.2924176189F, 0.2928687171F, 0.2933200246F, 0.2937715409F,
664.1358 +  0.2942232657F, 0.2946751984F, 0.2951273386F, 0.2955796856F,
664.1359 +  0.2960322391F, 0.2964849986F, 0.2969379636F, 0.2973911335F,
664.1360 +  0.2978445080F, 0.2982980864F, 0.2987518684F, 0.2992058534F,
664.1361 +  0.2996600409F, 0.3001144305F, 0.3005690217F, 0.3010238139F,
664.1362 +  0.3014788067F, 0.3019339995F, 0.3023893920F, 0.3028449835F,
664.1363 +  0.3033007736F, 0.3037567618F, 0.3042129477F, 0.3046693306F,
664.1364 +  0.3051259102F, 0.3055826859F, 0.3060396572F, 0.3064968236F,
664.1365 +  0.3069541847F, 0.3074117399F, 0.3078694887F, 0.3083274307F,
664.1366 +  0.3087855653F, 0.3092438920F, 0.3097024104F, 0.3101611199F,
664.1367 +  0.3106200200F, 0.3110791103F, 0.3115383902F, 0.3119978592F,
664.1368 +  0.3124575169F, 0.3129173627F, 0.3133773961F, 0.3138376166F,
664.1369 +  0.3142980238F, 0.3147586170F, 0.3152193959F, 0.3156803598F,
664.1370 +  0.3161415084F, 0.3166028410F, 0.3170643573F, 0.3175260566F,
664.1371 +  0.3179879384F, 0.3184500023F, 0.3189122478F, 0.3193746743F,
664.1372 +  0.3198372814F, 0.3203000685F, 0.3207630351F, 0.3212261807F,
664.1373 +  0.3216895048F, 0.3221530069F, 0.3226166865F, 0.3230805430F,
664.1374 +  0.3235445760F, 0.3240087849F, 0.3244731693F, 0.3249377285F,
664.1375 +  0.3254024622F, 0.3258673698F, 0.3263324507F, 0.3267977045F,
664.1376 +  0.3272631306F, 0.3277287286F, 0.3281944978F, 0.3286604379F,
664.1377 +  0.3291265482F, 0.3295928284F, 0.3300592777F, 0.3305258958F,
664.1378 +  0.3309926821F, 0.3314596361F, 0.3319267573F, 0.3323940451F,
664.1379 +  0.3328614990F, 0.3333291186F, 0.3337969033F, 0.3342648525F,
664.1380 +  0.3347329658F, 0.3352012427F, 0.3356696825F, 0.3361382849F,
664.1381 +  0.3366070492F, 0.3370759749F, 0.3375450616F, 0.3380143087F,
664.1382 +  0.3384837156F, 0.3389532819F, 0.3394230071F, 0.3398928905F,
664.1383 +  0.3403629317F, 0.3408331302F, 0.3413034854F, 0.3417739967F,
664.1384 +  0.3422446638F, 0.3427154860F, 0.3431864628F, 0.3436575938F,
664.1385 +  0.3441288782F, 0.3446003158F, 0.3450719058F, 0.3455436478F,
664.1386 +  0.3460155412F, 0.3464875856F, 0.3469597804F, 0.3474321250F,
664.1387 +  0.3479046189F, 0.3483772617F, 0.3488500527F, 0.3493229914F,
664.1388 +  0.3497960774F, 0.3502693100F, 0.3507426887F, 0.3512162131F,
664.1389 +  0.3516898825F, 0.3521636965F, 0.3526376545F, 0.3531117559F,
664.1390 +  0.3535860003F, 0.3540603870F, 0.3545349157F, 0.3550095856F,
664.1391 +  0.3554843964F, 0.3559593474F, 0.3564344381F, 0.3569096680F,
664.1392 +  0.3573850366F, 0.3578605432F, 0.3583361875F, 0.3588119687F,
664.1393 +  0.3592878865F, 0.3597639402F, 0.3602401293F, 0.3607164533F,
664.1394 +  0.3611929117F, 0.3616695038F, 0.3621462292F, 0.3626230873F,
664.1395 +  0.3631000776F, 0.3635771995F, 0.3640544525F, 0.3645318360F,
664.1396 +  0.3650093496F, 0.3654869926F, 0.3659647645F, 0.3664426648F,
664.1397 +  0.3669206930F, 0.3673988484F, 0.3678771306F, 0.3683555390F,
664.1398 +  0.3688340731F, 0.3693127322F, 0.3697915160F, 0.3702704237F,
664.1399 +  0.3707494549F, 0.3712286091F, 0.3717078857F, 0.3721872840F,
664.1400 +  0.3726668037F, 0.3731464441F, 0.3736262047F, 0.3741060850F,
664.1401 +  0.3745860843F, 0.3750662023F, 0.3755464382F, 0.3760267915F,
664.1402 +  0.3765072618F, 0.3769878484F, 0.3774685509F, 0.3779493686F,
664.1403 +  0.3784303010F, 0.3789113475F, 0.3793925076F, 0.3798737809F,
664.1404 +  0.3803551666F, 0.3808366642F, 0.3813182733F, 0.3817999932F,
664.1405 +  0.3822818234F, 0.3827637633F, 0.3832458124F, 0.3837279702F,
664.1406 +  0.3842102360F, 0.3846926093F, 0.3851750897F, 0.3856576764F,
664.1407 +  0.3861403690F, 0.3866231670F, 0.3871060696F, 0.3875890765F,
664.1408 +  0.3880721870F, 0.3885554007F, 0.3890387168F, 0.3895221349F,
664.1409 +  0.3900056544F, 0.3904892748F, 0.3909729955F, 0.3914568160F,
664.1410 +  0.3919407356F, 0.3924247539F, 0.3929088702F, 0.3933930841F,
664.1411 +  0.3938773949F, 0.3943618021F, 0.3948463052F, 0.3953309035F,
664.1412 +  0.3958155966F, 0.3963003838F, 0.3967852646F, 0.3972702385F,
664.1413 +  0.3977553048F, 0.3982404631F, 0.3987257127F, 0.3992110531F,
664.1414 +  0.3996964838F, 0.4001820041F, 0.4006676136F, 0.4011533116F,
664.1415 +  0.4016390976F, 0.4021249710F, 0.4026109313F, 0.4030969779F,
664.1416 +  0.4035831102F, 0.4040693277F, 0.4045556299F, 0.4050420160F,
664.1417 +  0.4055284857F, 0.4060150383F, 0.4065016732F, 0.4069883899F,
664.1418 +  0.4074751879F, 0.4079620665F, 0.4084490252F, 0.4089360635F,
664.1419 +  0.4094231807F, 0.4099103763F, 0.4103976498F, 0.4108850005F,
664.1420 +  0.4113724280F, 0.4118599315F, 0.4123475107F, 0.4128351648F,
664.1421 +  0.4133228934F, 0.4138106959F, 0.4142985716F, 0.4147865201F,
664.1422 +  0.4152745408F, 0.4157626330F, 0.4162507963F, 0.4167390301F,
664.1423 +  0.4172273337F, 0.4177157067F, 0.4182041484F, 0.4186926583F,
664.1424 +  0.4191812359F, 0.4196698805F, 0.4201585915F, 0.4206473685F,
664.1425 +  0.4211362108F, 0.4216251179F, 0.4221140892F, 0.4226031241F,
664.1426 +  0.4230922221F, 0.4235813826F, 0.4240706050F, 0.4245598887F,
664.1427 +  0.4250492332F, 0.4255386379F, 0.4260281022F, 0.4265176256F,
664.1428 +  0.4270072075F, 0.4274968473F, 0.4279865445F, 0.4284762984F,
664.1429 +  0.4289661086F, 0.4294559743F, 0.4299458951F, 0.4304358704F,
664.1430 +  0.4309258996F, 0.4314159822F, 0.4319061175F, 0.4323963050F,
664.1431 +  0.4328865441F, 0.4333768342F, 0.4338671749F, 0.4343575654F,
664.1432 +  0.4348480052F, 0.4353384938F, 0.4358290306F, 0.4363196149F,
664.1433 +  0.4368102463F, 0.4373009241F, 0.4377916478F, 0.4382824168F,
664.1434 +  0.4387732305F, 0.4392640884F, 0.4397549899F, 0.4402459343F,
664.1435 +  0.4407369212F, 0.4412279499F, 0.4417190198F, 0.4422101305F,
664.1436 +  0.4427012813F, 0.4431924717F, 0.4436837010F, 0.4441749686F,
664.1437 +  0.4446662742F, 0.4451576169F, 0.4456489963F, 0.4461404118F,
664.1438 +  0.4466318628F, 0.4471233487F, 0.4476148690F, 0.4481064230F,
664.1439 +  0.4485980103F, 0.4490896302F, 0.4495812821F, 0.4500729654F,
664.1440 +  0.4505646797F, 0.4510564243F, 0.4515481986F, 0.4520400021F,
664.1441 +  0.4525318341F, 0.4530236942F, 0.4535155816F, 0.4540074959F,
664.1442 +  0.4544994365F, 0.4549914028F, 0.4554833941F, 0.4559754100F,
664.1443 +  0.4564674499F, 0.4569595131F, 0.4574515991F, 0.4579437074F,
664.1444 +  0.4584358372F, 0.4589279881F, 0.4594201595F, 0.4599123508F,
664.1445 +  0.4604045615F, 0.4608967908F, 0.4613890383F, 0.4618813034F,
664.1446 +  0.4623735855F, 0.4628658841F, 0.4633581984F, 0.4638505281F,
664.1447 +  0.4643428724F, 0.4648352308F, 0.4653276028F, 0.4658199877F,
664.1448 +  0.4663123849F, 0.4668047940F, 0.4672972143F, 0.4677896451F,
664.1449 +  0.4682820861F, 0.4687745365F, 0.4692669958F, 0.4697594634F,
664.1450 +  0.4702519387F, 0.4707444211F, 0.4712369102F, 0.4717294052F,
664.1451 +  0.4722219056F, 0.4727144109F, 0.4732069204F, 0.4736994336F,
664.1452 +  0.4741919498F, 0.4746844686F, 0.4751769893F, 0.4756695113F,
664.1453 +  0.4761620341F, 0.4766545571F, 0.4771470797F, 0.4776396013F,
664.1454 +  0.4781321213F, 0.4786246392F, 0.4791171544F, 0.4796096663F,
664.1455 +  0.4801021744F, 0.4805946779F, 0.4810871765F, 0.4815796694F,
664.1456 +  0.4820721561F, 0.4825646360F, 0.4830571086F, 0.4835495732F,
664.1457 +  0.4840420293F, 0.4845344763F, 0.4850269136F, 0.4855193407F,
664.1458 +  0.4860117569F, 0.4865041617F, 0.4869965545F, 0.4874889347F,
664.1459 +  0.4879813018F, 0.4884736551F, 0.4889659941F, 0.4894583182F,
664.1460 +  0.4899506268F, 0.4904429193F, 0.4909351952F, 0.4914274538F,
664.1461 +  0.4919196947F, 0.4924119172F, 0.4929041207F, 0.4933963046F,
664.1462 +  0.4938884685F, 0.4943806116F, 0.4948727335F, 0.4953648335F,
664.1463 +  0.4958569110F, 0.4963489656F, 0.4968409965F, 0.4973330032F,
664.1464 +  0.4978249852F, 0.4983169419F, 0.4988088726F, 0.4993007768F,
664.1465 +  0.4997926539F, 0.5002845034F, 0.5007763247F, 0.5012681171F,
664.1466 +  0.5017598801F, 0.5022516132F, 0.5027433157F, 0.5032349871F,
664.1467 +  0.5037266268F, 0.5042182341F, 0.5047098086F, 0.5052013497F,
664.1468 +  0.5056928567F, 0.5061843292F, 0.5066757664F, 0.5071671679F,
664.1469 +  0.5076585330F, 0.5081498613F, 0.5086411520F, 0.5091324047F,
664.1470 +  0.5096236187F, 0.5101147934F, 0.5106059284F, 0.5110970230F,
664.1471 +  0.5115880766F, 0.5120790887F, 0.5125700587F, 0.5130609860F,
664.1472 +  0.5135518700F, 0.5140427102F, 0.5145335059F, 0.5150242566F,
664.1473 +  0.5155149618F, 0.5160056208F, 0.5164962331F, 0.5169867980F,
664.1474 +  0.5174773151F, 0.5179677837F, 0.5184582033F, 0.5189485733F,
664.1475 +  0.5194388931F, 0.5199291621F, 0.5204193798F, 0.5209095455F,
664.1476 +  0.5213996588F, 0.5218897190F, 0.5223797256F, 0.5228696779F,
664.1477 +  0.5233595755F, 0.5238494177F, 0.5243392039F, 0.5248289337F,
664.1478 +  0.5253186063F, 0.5258082213F, 0.5262977781F, 0.5267872760F,
664.1479 +  0.5272767146F, 0.5277660932F, 0.5282554112F, 0.5287446682F,
664.1480 +  0.5292338635F, 0.5297229965F, 0.5302120667F, 0.5307010736F,
664.1481 +  0.5311900164F, 0.5316788947F, 0.5321677079F, 0.5326564554F,
664.1482 +  0.5331451366F, 0.5336337511F, 0.5341222981F, 0.5346107771F,
664.1483 +  0.5350991876F, 0.5355875290F, 0.5360758007F, 0.5365640021F,
664.1484 +  0.5370521327F, 0.5375401920F, 0.5380281792F, 0.5385160939F,
664.1485 +  0.5390039355F, 0.5394917034F, 0.5399793971F, 0.5404670159F,
664.1486 +  0.5409545594F, 0.5414420269F, 0.5419294179F, 0.5424167318F,
664.1487 +  0.5429039680F, 0.5433911261F, 0.5438782053F, 0.5443652051F,
664.1488 +  0.5448521250F, 0.5453389644F, 0.5458257228F, 0.5463123995F,
664.1489 +  0.5467989940F, 0.5472855057F, 0.5477719341F, 0.5482582786F,
664.1490 +  0.5487445387F, 0.5492307137F, 0.5497168031F, 0.5502028063F,
664.1491 +  0.5506887228F, 0.5511745520F, 0.5516602934F, 0.5521459463F,
664.1492 +  0.5526315103F, 0.5531169847F, 0.5536023690F, 0.5540876626F,
664.1493 +  0.5545728649F, 0.5550579755F, 0.5555429937F, 0.5560279189F,
664.1494 +  0.5565127507F, 0.5569974884F, 0.5574821315F, 0.5579666794F,
664.1495 +  0.5584511316F, 0.5589354875F, 0.5594197465F, 0.5599039080F,
664.1496 +  0.5603879716F, 0.5608719367F, 0.5613558026F, 0.5618395689F,
664.1497 +  0.5623232350F, 0.5628068002F, 0.5632902642F, 0.5637736262F,
664.1498 +  0.5642568858F, 0.5647400423F, 0.5652230953F, 0.5657060442F,
664.1499 +  0.5661888883F, 0.5666716272F, 0.5671542603F, 0.5676367870F,
664.1500 +  0.5681192069F, 0.5686015192F, 0.5690837235F, 0.5695658192F,
664.1501 +  0.5700478058F, 0.5705296827F, 0.5710114494F, 0.5714931052F,
664.1502 +  0.5719746497F, 0.5724560822F, 0.5729374023F, 0.5734186094F,
664.1503 +  0.5738997029F, 0.5743806823F, 0.5748615470F, 0.5753422965F,
664.1504 +  0.5758229301F, 0.5763034475F, 0.5767838480F, 0.5772641310F,
664.1505 +  0.5777442960F, 0.5782243426F, 0.5787042700F, 0.5791840778F,
664.1506 +  0.5796637654F, 0.5801433322F, 0.5806227778F, 0.5811021016F,
664.1507 +  0.5815813029F, 0.5820603814F, 0.5825393363F, 0.5830181673F,
664.1508 +  0.5834968737F, 0.5839754549F, 0.5844539105F, 0.5849322399F,
664.1509 +  0.5854104425F, 0.5858885179F, 0.5863664653F, 0.5868442844F,
664.1510 +  0.5873219746F, 0.5877995353F, 0.5882769660F, 0.5887542661F,
664.1511 +  0.5892314351F, 0.5897084724F, 0.5901853776F, 0.5906621500F,
664.1512 +  0.5911387892F, 0.5916152945F, 0.5920916655F, 0.5925679016F,
664.1513 +  0.5930440022F, 0.5935199669F, 0.5939957950F, 0.5944714861F,
664.1514 +  0.5949470396F, 0.5954224550F, 0.5958977317F, 0.5963728692F,
664.1515 +  0.5968478669F, 0.5973227244F, 0.5977974411F, 0.5982720163F,
664.1516 +  0.5987464497F, 0.5992207407F, 0.5996948887F, 0.6001688932F,
664.1517 +  0.6006427537F, 0.6011164696F, 0.6015900405F, 0.6020634657F,
664.1518 +  0.6025367447F, 0.6030098770F, 0.6034828621F, 0.6039556995F,
664.1519 +  0.6044283885F, 0.6049009288F, 0.6053733196F, 0.6058455606F,
664.1520 +  0.6063176512F, 0.6067895909F, 0.6072613790F, 0.6077330152F,
664.1521 +  0.6082044989F, 0.6086758295F, 0.6091470065F, 0.6096180294F,
664.1522 +  0.6100888977F, 0.6105596108F, 0.6110301682F, 0.6115005694F,
664.1523 +  0.6119708139F, 0.6124409011F, 0.6129108305F, 0.6133806017F,
664.1524 +  0.6138502139F, 0.6143196669F, 0.6147889599F, 0.6152580926F,
664.1525 +  0.6157270643F, 0.6161958746F, 0.6166645230F, 0.6171330088F,
664.1526 +  0.6176013317F, 0.6180694910F, 0.6185374863F, 0.6190053171F,
664.1527 +  0.6194729827F, 0.6199404828F, 0.6204078167F, 0.6208749841F,
664.1528 +  0.6213419842F, 0.6218088168F, 0.6222754811F, 0.6227419768F,
664.1529 +  0.6232083032F, 0.6236744600F, 0.6241404465F, 0.6246062622F,
664.1530 +  0.6250719067F, 0.6255373795F, 0.6260026799F, 0.6264678076F,
664.1531 +  0.6269327619F, 0.6273975425F, 0.6278621487F, 0.6283265800F,
664.1532 +  0.6287908361F, 0.6292549163F, 0.6297188201F, 0.6301825471F,
664.1533 +  0.6306460966F, 0.6311094683F, 0.6315726617F, 0.6320356761F,
664.1534 +  0.6324985111F, 0.6329611662F, 0.6334236410F, 0.6338859348F,
664.1535 +  0.6343480472F, 0.6348099777F, 0.6352717257F, 0.6357332909F,
664.1536 +  0.6361946726F, 0.6366558704F, 0.6371168837F, 0.6375777122F,
664.1537 +  0.6380383552F, 0.6384988123F, 0.6389590830F, 0.6394191668F,
664.1538 +  0.6398790631F, 0.6403387716F, 0.6407982916F, 0.6412576228F,
664.1539 +  0.6417167645F, 0.6421757163F, 0.6426344778F, 0.6430930483F,
664.1540 +  0.6435514275F, 0.6440096149F, 0.6444676098F, 0.6449254119F,
664.1541 +  0.6453830207F, 0.6458404356F, 0.6462976562F, 0.6467546820F,
664.1542 +  0.6472115125F, 0.6476681472F, 0.6481245856F, 0.6485808273F,
664.1543 +  0.6490368717F, 0.6494927183F, 0.6499483667F, 0.6504038164F,
664.1544 +  0.6508590670F, 0.6513141178F, 0.6517689684F, 0.6522236185F,
664.1545 +  0.6526780673F, 0.6531323146F, 0.6535863598F, 0.6540402024F,
664.1546 +  0.6544938419F, 0.6549472779F, 0.6554005099F, 0.6558535373F,
664.1547 +  0.6563063598F, 0.6567589769F, 0.6572113880F, 0.6576635927F,
664.1548 +  0.6581155906F, 0.6585673810F, 0.6590189637F, 0.6594703380F,
664.1549 +  0.6599215035F, 0.6603724598F, 0.6608232064F, 0.6612737427F,
664.1550 +  0.6617240684F, 0.6621741829F, 0.6626240859F, 0.6630737767F,
664.1551 +  0.6635232550F, 0.6639725202F, 0.6644215720F, 0.6648704098F,
664.1552 +  0.6653190332F, 0.6657674417F, 0.6662156348F, 0.6666636121F,
664.1553 +  0.6671113731F, 0.6675589174F, 0.6680062445F, 0.6684533538F,
664.1554 +  0.6689002450F, 0.6693469177F, 0.6697933712F, 0.6702396052F,
664.1555 +  0.6706856193F, 0.6711314129F, 0.6715769855F, 0.6720223369F,
664.1556 +  0.6724674664F, 0.6729123736F, 0.6733570581F, 0.6738015194F,
664.1557 +  0.6742457570F, 0.6746897706F, 0.6751335596F, 0.6755771236F,
664.1558 +  0.6760204621F, 0.6764635747F, 0.6769064609F, 0.6773491204F,
664.1559 +  0.6777915525F, 0.6782337570F, 0.6786757332F, 0.6791174809F,
664.1560 +  0.6795589995F, 0.6800002886F, 0.6804413477F, 0.6808821765F,
664.1561 +  0.6813227743F, 0.6817631409F, 0.6822032758F, 0.6826431785F,
664.1562 +  0.6830828485F, 0.6835222855F, 0.6839614890F, 0.6844004585F,
664.1563 +  0.6848391936F, 0.6852776939F, 0.6857159589F, 0.6861539883F,
664.1564 +  0.6865917815F, 0.6870293381F, 0.6874666576F, 0.6879037398F,
664.1565 +  0.6883405840F, 0.6887771899F, 0.6892135571F, 0.6896496850F,
664.1566 +  0.6900855733F, 0.6905212216F, 0.6909566294F, 0.6913917963F,
664.1567 +  0.6918267218F, 0.6922614055F, 0.6926958471F, 0.6931300459F,
664.1568 +  0.6935640018F, 0.6939977141F, 0.6944311825F, 0.6948644066F,
664.1569 +  0.6952973859F, 0.6957301200F, 0.6961626085F, 0.6965948510F,
664.1570 +  0.6970268470F, 0.6974585961F, 0.6978900980F, 0.6983213521F,
664.1571 +  0.6987523580F, 0.6991831154F, 0.6996136238F, 0.7000438828F,
664.1572 +  0.7004738921F, 0.7009036510F, 0.7013331594F, 0.7017624166F,
664.1573 +  0.7021914224F, 0.7026201763F, 0.7030486779F, 0.7034769268F,
664.1574 +  0.7039049226F, 0.7043326648F, 0.7047601531F, 0.7051873870F,
664.1575 +  0.7056143662F, 0.7060410902F, 0.7064675586F, 0.7068937711F,
664.1576 +  0.7073197271F, 0.7077454264F, 0.7081708684F, 0.7085960529F,
664.1577 +  0.7090209793F, 0.7094456474F, 0.7098700566F, 0.7102942066F,
664.1578 +  0.7107180970F, 0.7111417274F, 0.7115650974F, 0.7119882066F,
664.1579 +  0.7124110545F, 0.7128336409F, 0.7132559653F, 0.7136780272F,
664.1580 +  0.7140998264F, 0.7145213624F, 0.7149426348F, 0.7153636433F,
664.1581 +  0.7157843874F, 0.7162048668F, 0.7166250810F, 0.7170450296F,
664.1582 +  0.7174647124F, 0.7178841289F, 0.7183032786F, 0.7187221613F,
664.1583 +  0.7191407765F, 0.7195591239F, 0.7199772030F, 0.7203950135F,
664.1584 +  0.7208125550F, 0.7212298271F, 0.7216468294F, 0.7220635616F,
664.1585 +  0.7224800233F, 0.7228962140F, 0.7233121335F, 0.7237277813F,
664.1586 +  0.7241431571F, 0.7245582604F, 0.7249730910F, 0.7253876484F,
664.1587 +  0.7258019322F, 0.7262159422F, 0.7266296778F, 0.7270431388F,
664.1588 +  0.7274563247F, 0.7278692353F, 0.7282818700F, 0.7286942287F,
664.1589 +  0.7291063108F, 0.7295181160F, 0.7299296440F, 0.7303408944F,
664.1590 +  0.7307518669F, 0.7311625609F, 0.7315729763F, 0.7319831126F,
664.1591 +  0.7323929695F, 0.7328025466F, 0.7332118435F, 0.7336208600F,
664.1592 +  0.7340295955F, 0.7344380499F, 0.7348462226F, 0.7352541134F,
664.1593 +  0.7356617220F, 0.7360690478F, 0.7364760907F, 0.7368828502F,
664.1594 +  0.7372893259F, 0.7376955176F, 0.7381014249F, 0.7385070475F,
664.1595 +  0.7389123849F, 0.7393174368F, 0.7397222029F, 0.7401266829F,
664.1596 +  0.7405308763F, 0.7409347829F, 0.7413384023F, 0.7417417341F,
664.1597 +  0.7421447780F, 0.7425475338F, 0.7429500009F, 0.7433521791F,
664.1598 +  0.7437540681F, 0.7441556674F, 0.7445569769F, 0.7449579960F,
664.1599 +  0.7453587245F, 0.7457591621F, 0.7461593084F, 0.7465591631F,
664.1600 +  0.7469587259F, 0.7473579963F, 0.7477569741F, 0.7481556590F,
664.1601 +  0.7485540506F, 0.7489521486F, 0.7493499526F, 0.7497474623F,
664.1602 +  0.7501446775F, 0.7505415977F, 0.7509382227F, 0.7513345521F,
664.1603 +  0.7517305856F, 0.7521263229F, 0.7525217636F, 0.7529169074F,
664.1604 +  0.7533117541F, 0.7537063032F, 0.7541005545F, 0.7544945076F,
664.1605 +  0.7548881623F, 0.7552815182F, 0.7556745749F, 0.7560673323F,
664.1606 +  0.7564597899F, 0.7568519474F, 0.7572438046F, 0.7576353611F,
664.1607 +  0.7580266166F, 0.7584175708F, 0.7588082235F, 0.7591985741F,
664.1608 +  0.7595886226F, 0.7599783685F, 0.7603678116F, 0.7607569515F,
664.1609 +  0.7611457879F, 0.7615343206F, 0.7619225493F, 0.7623104735F,
664.1610 +  0.7626980931F, 0.7630854078F, 0.7634724171F, 0.7638591209F,
664.1611 +  0.7642455188F, 0.7646316106F, 0.7650173959F, 0.7654028744F,
664.1612 +  0.7657880459F, 0.7661729100F, 0.7665574664F, 0.7669417150F,
664.1613 +  0.7673256553F, 0.7677092871F, 0.7680926100F, 0.7684756239F,
664.1614 +  0.7688583284F, 0.7692407232F, 0.7696228080F, 0.7700045826F,
664.1615 +  0.7703860467F, 0.7707671999F, 0.7711480420F, 0.7715285728F,
664.1616 +  0.7719087918F, 0.7722886989F, 0.7726682938F, 0.7730475762F,
664.1617 +  0.7734265458F, 0.7738052023F, 0.7741835454F, 0.7745615750F,
664.1618 +  0.7749392906F, 0.7753166921F, 0.7756937791F, 0.7760705514F,
664.1619 +  0.7764470087F, 0.7768231508F, 0.7771989773F, 0.7775744880F,
664.1620 +  0.7779496827F, 0.7783245610F, 0.7786991227F, 0.7790733676F,
664.1621 +  0.7794472953F, 0.7798209056F, 0.7801941982F, 0.7805671729F,
664.1622 +  0.7809398294F, 0.7813121675F, 0.7816841869F, 0.7820558873F,
664.1623 +  0.7824272684F, 0.7827983301F, 0.7831690720F, 0.7835394940F,
664.1624 +  0.7839095957F, 0.7842793768F, 0.7846488373F, 0.7850179767F,
664.1625 +  0.7853867948F, 0.7857552914F, 0.7861234663F, 0.7864913191F,
664.1626 +  0.7868588497F, 0.7872260578F, 0.7875929431F, 0.7879595055F,
664.1627 +  0.7883257445F, 0.7886916601F, 0.7890572520F, 0.7894225198F,
664.1628 +  0.7897874635F, 0.7901520827F, 0.7905163772F, 0.7908803468F,
664.1629 +  0.7912439912F, 0.7916073102F, 0.7919703035F, 0.7923329710F,
664.1630 +  0.7926953124F, 0.7930573274F, 0.7934190158F, 0.7937803774F,
664.1631 +  0.7941414120F, 0.7945021193F, 0.7948624991F, 0.7952225511F,
664.1632 +  0.7955822752F, 0.7959416711F, 0.7963007387F, 0.7966594775F,
664.1633 +  0.7970178875F, 0.7973759685F, 0.7977337201F, 0.7980911422F,
664.1634 +  0.7984482346F, 0.7988049970F, 0.7991614292F, 0.7995175310F,
664.1635 +  0.7998733022F, 0.8002287426F, 0.8005838519F, 0.8009386299F,
664.1636 +  0.8012930765F, 0.8016471914F, 0.8020009744F, 0.8023544253F,
664.1637 +  0.8027075438F, 0.8030603298F, 0.8034127831F, 0.8037649035F,
664.1638 +  0.8041166906F, 0.8044681445F, 0.8048192647F, 0.8051700512F,
664.1639 +  0.8055205038F, 0.8058706222F, 0.8062204062F, 0.8065698556F,
664.1640 +  0.8069189702F, 0.8072677499F, 0.8076161944F, 0.8079643036F,
664.1641 +  0.8083120772F, 0.8086595151F, 0.8090066170F, 0.8093533827F,
664.1642 +  0.8096998122F, 0.8100459051F, 0.8103916613F, 0.8107370806F,
664.1643 +  0.8110821628F, 0.8114269077F, 0.8117713151F, 0.8121153849F,
664.1644 +  0.8124591169F, 0.8128025108F, 0.8131455666F, 0.8134882839F,
664.1645 +  0.8138306627F, 0.8141727027F, 0.8145144038F, 0.8148557658F,
664.1646 +  0.8151967886F, 0.8155374718F, 0.8158778154F, 0.8162178192F,
664.1647 +  0.8165574830F, 0.8168968067F, 0.8172357900F, 0.8175744328F,
664.1648 +  0.8179127349F, 0.8182506962F, 0.8185883164F, 0.8189255955F,
664.1649 +  0.8192625332F, 0.8195991295F, 0.8199353840F, 0.8202712967F,
664.1650 +  0.8206068673F, 0.8209420958F, 0.8212769820F, 0.8216115256F,
664.1651 +  0.8219457266F, 0.8222795848F, 0.8226131000F, 0.8229462721F,
664.1652 +  0.8232791009F, 0.8236115863F, 0.8239437280F, 0.8242755260F,
664.1653 +  0.8246069801F, 0.8249380901F, 0.8252688559F, 0.8255992774F,
664.1654 +  0.8259293544F, 0.8262590867F, 0.8265884741F, 0.8269175167F,
664.1655 +  0.8272462141F, 0.8275745663F, 0.8279025732F, 0.8282302344F,
664.1656 +  0.8285575501F, 0.8288845199F, 0.8292111437F, 0.8295374215F,
664.1657 +  0.8298633530F, 0.8301889382F, 0.8305141768F, 0.8308390688F,
664.1658 +  0.8311636141F, 0.8314878124F, 0.8318116637F, 0.8321351678F,
664.1659 +  0.8324583246F, 0.8327811340F, 0.8331035957F, 0.8334257098F,
664.1660 +  0.8337474761F, 0.8340688944F, 0.8343899647F, 0.8347106867F,
664.1661 +  0.8350310605F, 0.8353510857F, 0.8356707624F, 0.8359900904F,
664.1662 +  0.8363090696F, 0.8366276999F, 0.8369459811F, 0.8372639131F,
664.1663 +  0.8375814958F, 0.8378987292F, 0.8382156130F, 0.8385321472F,
664.1664 +  0.8388483316F, 0.8391641662F, 0.8394796508F, 0.8397947853F,
664.1665 +  0.8401095697F, 0.8404240037F, 0.8407380873F, 0.8410518204F,
664.1666 +  0.8413652029F, 0.8416782347F, 0.8419909156F, 0.8423032456F,
664.1667 +  0.8426152245F, 0.8429268523F, 0.8432381289F, 0.8435490541F,
664.1668 +  0.8438596279F, 0.8441698502F, 0.8444797208F, 0.8447892396F,
664.1669 +  0.8450984067F, 0.8454072218F, 0.8457156849F, 0.8460237959F,
664.1670 +  0.8463315547F, 0.8466389612F, 0.8469460154F, 0.8472527170F,
664.1671 +  0.8475590661F, 0.8478650625F, 0.8481707063F, 0.8484759971F,
664.1672 +  0.8487809351F, 0.8490855201F, 0.8493897521F, 0.8496936308F,
664.1673 +  0.8499971564F, 0.8503003286F, 0.8506031474F, 0.8509056128F,
664.1674 +  0.8512077246F, 0.8515094828F, 0.8518108872F, 0.8521119379F,
664.1675 +  0.8524126348F, 0.8527129777F, 0.8530129666F, 0.8533126015F,
664.1676 +  0.8536118822F, 0.8539108087F, 0.8542093809F, 0.8545075988F,
664.1677 +  0.8548054623F, 0.8551029712F, 0.8554001257F, 0.8556969255F,
664.1678 +  0.8559933707F, 0.8562894611F, 0.8565851968F, 0.8568805775F,
664.1679 +  0.8571756034F, 0.8574702743F, 0.8577645902F, 0.8580585509F,
664.1680 +  0.8583521566F, 0.8586454070F, 0.8589383021F, 0.8592308420F,
664.1681 +  0.8595230265F, 0.8598148556F, 0.8601063292F, 0.8603974473F,
664.1682 +  0.8606882098F, 0.8609786167F, 0.8612686680F, 0.8615583636F,
664.1683 +  0.8618477034F, 0.8621366874F, 0.8624253156F, 0.8627135878F,
664.1684 +  0.8630015042F, 0.8632890646F, 0.8635762690F, 0.8638631173F,
664.1685 +  0.8641496096F, 0.8644357457F, 0.8647215257F, 0.8650069495F,
664.1686 +  0.8652920171F, 0.8655767283F, 0.8658610833F, 0.8661450820F,
664.1687 +  0.8664287243F, 0.8667120102F, 0.8669949397F, 0.8672775127F,
664.1688 +  0.8675597293F, 0.8678415894F, 0.8681230929F, 0.8684042398F,
664.1689 +  0.8686850302F, 0.8689654640F, 0.8692455412F, 0.8695252617F,
664.1690 +  0.8698046255F, 0.8700836327F, 0.8703622831F, 0.8706405768F,
664.1691 +  0.8709185138F, 0.8711960940F, 0.8714733174F, 0.8717501840F,
664.1692 +  0.8720266939F, 0.8723028469F, 0.8725786430F, 0.8728540824F,
664.1693 +  0.8731291648F, 0.8734038905F, 0.8736782592F, 0.8739522711F,
664.1694 +  0.8742259261F, 0.8744992242F, 0.8747721653F, 0.8750447496F,
664.1695 +  0.8753169770F, 0.8755888475F, 0.8758603611F, 0.8761315177F,
664.1696 +  0.8764023175F, 0.8766727603F, 0.8769428462F, 0.8772125752F,
664.1697 +  0.8774819474F, 0.8777509626F, 0.8780196209F, 0.8782879224F,
664.1698 +  0.8785558669F, 0.8788234546F, 0.8790906854F, 0.8793575594F,
664.1699 +  0.8796240765F, 0.8798902368F, 0.8801560403F, 0.8804214870F,
664.1700 +  0.8806865768F, 0.8809513099F, 0.8812156863F, 0.8814797059F,
664.1701 +  0.8817433687F, 0.8820066749F, 0.8822696243F, 0.8825322171F,
664.1702 +  0.8827944532F, 0.8830563327F, 0.8833178556F, 0.8835790219F,
664.1703 +  0.8838398316F, 0.8841002848F, 0.8843603815F, 0.8846201217F,
664.1704 +  0.8848795054F, 0.8851385327F, 0.8853972036F, 0.8856555182F,
664.1705 +  0.8859134764F, 0.8861710783F, 0.8864283239F, 0.8866852133F,
664.1706 +  0.8869417464F, 0.8871979234F, 0.8874537443F, 0.8877092090F,
664.1707 +  0.8879643177F, 0.8882190704F, 0.8884734671F, 0.8887275078F,
664.1708 +  0.8889811927F, 0.8892345216F, 0.8894874948F, 0.8897401122F,
664.1709 +  0.8899923738F, 0.8902442798F, 0.8904958301F, 0.8907470248F,
664.1710 +  0.8909978640F, 0.8912483477F, 0.8914984759F, 0.8917482487F,
664.1711 +  0.8919976662F, 0.8922467284F, 0.8924954353F, 0.8927437871F,
664.1712 +  0.8929917837F, 0.8932394252F, 0.8934867118F, 0.8937336433F,
664.1713 +  0.8939802199F, 0.8942264417F, 0.8944723087F, 0.8947178210F,
664.1714 +  0.8949629785F, 0.8952077815F, 0.8954522299F, 0.8956963239F,
664.1715 +  0.8959400634F, 0.8961834486F, 0.8964264795F, 0.8966691561F,
664.1716 +  0.8969114786F, 0.8971534470F, 0.8973950614F, 0.8976363219F,
664.1717 +  0.8978772284F, 0.8981177812F, 0.8983579802F, 0.8985978256F,
664.1718 +  0.8988373174F, 0.8990764556F, 0.8993152405F, 0.8995536720F,
664.1719 +  0.8997917502F, 0.9000294751F, 0.9002668470F, 0.9005038658F,
664.1720 +  0.9007405317F, 0.9009768446F, 0.9012128048F, 0.9014484123F,
664.1721 +  0.9016836671F, 0.9019185693F, 0.9021531191F, 0.9023873165F,
664.1722 +  0.9026211616F, 0.9028546546F, 0.9030877954F, 0.9033205841F,
664.1723 +  0.9035530210F, 0.9037851059F, 0.9040168392F, 0.9042482207F,
664.1724 +  0.9044792507F, 0.9047099293F, 0.9049402564F, 0.9051702323F,
664.1725 +  0.9053998569F, 0.9056291305F, 0.9058580531F, 0.9060866248F,
664.1726 +  0.9063148457F, 0.9065427159F, 0.9067702355F, 0.9069974046F,
664.1727 +  0.9072242233F, 0.9074506917F, 0.9076768100F, 0.9079025782F,
664.1728 +  0.9081279964F, 0.9083530647F, 0.9085777833F, 0.9088021523F,
664.1729 +  0.9090261717F, 0.9092498417F, 0.9094731623F, 0.9096961338F,
664.1730 +  0.9099187561F, 0.9101410295F, 0.9103629540F, 0.9105845297F,
664.1731 +  0.9108057568F, 0.9110266354F, 0.9112471656F, 0.9114673475F,
664.1732 +  0.9116871812F, 0.9119066668F, 0.9121258046F, 0.9123445945F,
664.1733 +  0.9125630367F, 0.9127811314F, 0.9129988786F, 0.9132162785F,
664.1734 +  0.9134333312F, 0.9136500368F, 0.9138663954F, 0.9140824073F,
664.1735 +  0.9142980724F, 0.9145133910F, 0.9147283632F, 0.9149429890F,
664.1736 +  0.9151572687F, 0.9153712023F, 0.9155847900F, 0.9157980319F,
664.1737 +  0.9160109282F, 0.9162234790F, 0.9164356844F, 0.9166475445F,
664.1738 +  0.9168590595F, 0.9170702296F, 0.9172810548F, 0.9174915354F,
664.1739 +  0.9177016714F, 0.9179114629F, 0.9181209102F, 0.9183300134F,
664.1740 +  0.9185387726F, 0.9187471879F, 0.9189552595F, 0.9191629876F,
664.1741 +  0.9193703723F, 0.9195774136F, 0.9197841119F, 0.9199904672F,
664.1742 +  0.9201964797F, 0.9204021495F, 0.9206074767F, 0.9208124616F,
664.1743 +  0.9210171043F, 0.9212214049F, 0.9214253636F, 0.9216289805F,
664.1744 +  0.9218322558F, 0.9220351896F, 0.9222377821F, 0.9224400335F,
664.1745 +  0.9226419439F, 0.9228435134F, 0.9230447423F, 0.9232456307F,
664.1746 +  0.9234461787F, 0.9236463865F, 0.9238462543F, 0.9240457822F,
664.1747 +  0.9242449704F, 0.9244438190F, 0.9246423282F, 0.9248404983F,
664.1748 +  0.9250383293F, 0.9252358214F, 0.9254329747F, 0.9256297896F,
664.1749 +  0.9258262660F, 0.9260224042F, 0.9262182044F, 0.9264136667F,
664.1750 +  0.9266087913F, 0.9268035783F, 0.9269980280F, 0.9271921405F,
664.1751 +  0.9273859160F, 0.9275793546F, 0.9277724566F, 0.9279652221F,
664.1752 +  0.9281576513F, 0.9283497443F, 0.9285415014F, 0.9287329227F,
664.1753 +  0.9289240084F, 0.9291147586F, 0.9293051737F, 0.9294952536F,
664.1754 +  0.9296849987F, 0.9298744091F, 0.9300634850F, 0.9302522266F,
664.1755 +  0.9304406340F, 0.9306287074F, 0.9308164471F, 0.9310038532F,
664.1756 +  0.9311909259F, 0.9313776654F, 0.9315640719F, 0.9317501455F,
664.1757 +  0.9319358865F, 0.9321212951F, 0.9323063713F, 0.9324911155F,
664.1758 +  0.9326755279F, 0.9328596085F, 0.9330433577F, 0.9332267756F,
664.1759 +  0.9334098623F, 0.9335926182F, 0.9337750434F, 0.9339571380F,
664.1760 +  0.9341389023F, 0.9343203366F, 0.9345014409F, 0.9346822155F,
664.1761 +  0.9348626606F, 0.9350427763F, 0.9352225630F, 0.9354020207F,
664.1762 +  0.9355811498F, 0.9357599503F, 0.9359384226F, 0.9361165667F,
664.1763 +  0.9362943830F, 0.9364718716F, 0.9366490327F, 0.9368258666F,
664.1764 +  0.9370023733F, 0.9371785533F, 0.9373544066F, 0.9375299335F,
664.1765 +  0.9377051341F, 0.9378800087F, 0.9380545576F, 0.9382287809F,
664.1766 +  0.9384026787F, 0.9385762515F, 0.9387494993F, 0.9389224223F,
664.1767 +  0.9390950209F, 0.9392672951F, 0.9394392453F, 0.9396108716F,
664.1768 +  0.9397821743F, 0.9399531536F, 0.9401238096F, 0.9402941427F,
664.1769 +  0.9404641530F, 0.9406338407F, 0.9408032061F, 0.9409722495F,
664.1770 +  0.9411409709F, 0.9413093707F, 0.9414774491F, 0.9416452062F,
664.1771 +  0.9418126424F, 0.9419797579F, 0.9421465528F, 0.9423130274F,
664.1772 +  0.9424791819F, 0.9426450166F, 0.9428105317F, 0.9429757274F,
664.1773 +  0.9431406039F, 0.9433051616F, 0.9434694005F, 0.9436333209F,
664.1774 +  0.9437969232F, 0.9439602074F, 0.9441231739F, 0.9442858229F,
664.1775 +  0.9444481545F, 0.9446101691F, 0.9447718669F, 0.9449332481F,
664.1776 +  0.9450943129F, 0.9452550617F, 0.9454154945F, 0.9455756118F,
664.1777 +  0.9457354136F, 0.9458949003F, 0.9460540721F, 0.9462129292F,
664.1778 +  0.9463714719F, 0.9465297003F, 0.9466876149F, 0.9468452157F,
664.1779 +  0.9470025031F, 0.9471594772F, 0.9473161384F, 0.9474724869F,
664.1780 +  0.9476285229F, 0.9477842466F, 0.9479396584F, 0.9480947585F,
664.1781 +  0.9482495470F, 0.9484040243F, 0.9485581906F, 0.9487120462F,
664.1782 +  0.9488655913F, 0.9490188262F, 0.9491717511F, 0.9493243662F,
664.1783 +  0.9494766718F, 0.9496286683F, 0.9497803557F, 0.9499317345F,
664.1784 +  0.9500828047F, 0.9502335668F, 0.9503840209F, 0.9505341673F,
664.1785 +  0.9506840062F, 0.9508335380F, 0.9509827629F, 0.9511316810F,
664.1786 +  0.9512802928F, 0.9514285984F, 0.9515765982F, 0.9517242923F,
664.1787 +  0.9518716810F, 0.9520187646F, 0.9521655434F, 0.9523120176F,
664.1788 +  0.9524581875F, 0.9526040534F, 0.9527496154F, 0.9528948739F,
664.1789 +  0.9530398292F, 0.9531844814F, 0.9533288310F, 0.9534728780F,
664.1790 +  0.9536166229F, 0.9537600659F, 0.9539032071F, 0.9540460470F,
664.1791 +  0.9541885858F, 0.9543308237F, 0.9544727611F, 0.9546143981F,
664.1792 +  0.9547557351F, 0.9548967723F, 0.9550375100F, 0.9551779485F,
664.1793 +  0.9553180881F, 0.9554579290F, 0.9555974714F, 0.9557367158F,
664.1794 +  0.9558756623F, 0.9560143112F, 0.9561526628F, 0.9562907174F,
664.1795 +  0.9564284752F, 0.9565659366F, 0.9567031017F, 0.9568399710F,
664.1796 +  0.9569765446F, 0.9571128229F, 0.9572488061F, 0.9573844944F,
664.1797 +  0.9575198883F, 0.9576549879F, 0.9577897936F, 0.9579243056F,
664.1798 +  0.9580585242F, 0.9581924497F, 0.9583260824F, 0.9584594226F,
664.1799 +  0.9585924705F, 0.9587252264F, 0.9588576906F, 0.9589898634F,
664.1800 +  0.9591217452F, 0.9592533360F, 0.9593846364F, 0.9595156465F,
664.1801 +  0.9596463666F, 0.9597767971F, 0.9599069382F, 0.9600367901F,
664.1802 +  0.9601663533F, 0.9602956279F, 0.9604246143F, 0.9605533128F,
664.1803 +  0.9606817236F, 0.9608098471F, 0.9609376835F, 0.9610652332F,
664.1804 +  0.9611924963F, 0.9613194733F, 0.9614461644F, 0.9615725699F,
664.1805 +  0.9616986901F, 0.9618245253F, 0.9619500757F, 0.9620753418F,
664.1806 +  0.9622003238F, 0.9623250219F, 0.9624494365F, 0.9625735679F,
664.1807 +  0.9626974163F, 0.9628209821F, 0.9629442656F, 0.9630672671F,
664.1808 +  0.9631899868F, 0.9633124251F, 0.9634345822F, 0.9635564585F,
664.1809 +  0.9636780543F, 0.9637993699F, 0.9639204056F, 0.9640411616F,
664.1810 +  0.9641616383F, 0.9642818359F, 0.9644017549F, 0.9645213955F,
664.1811 +  0.9646407579F, 0.9647598426F, 0.9648786497F, 0.9649971797F,
664.1812 +  0.9651154328F, 0.9652334092F, 0.9653511095F, 0.9654685337F,
664.1813 +  0.9655856823F, 0.9657025556F, 0.9658191538F, 0.9659354773F,
664.1814 +  0.9660515263F, 0.9661673013F, 0.9662828024F, 0.9663980300F,
664.1815 +  0.9665129845F, 0.9666276660F, 0.9667420750F, 0.9668562118F,
664.1816 +  0.9669700766F, 0.9670836698F, 0.9671969917F, 0.9673100425F,
664.1817 +  0.9674228227F, 0.9675353325F, 0.9676475722F, 0.9677595422F,
664.1818 +  0.9678712428F, 0.9679826742F, 0.9680938368F, 0.9682047309F,
664.1819 +  0.9683153569F, 0.9684257150F, 0.9685358056F, 0.9686456289F,
664.1820 +  0.9687551853F, 0.9688644752F, 0.9689734987F, 0.9690822564F,
664.1821 +  0.9691907483F, 0.9692989750F, 0.9694069367F, 0.9695146337F,
664.1822 +  0.9696220663F, 0.9697292349F, 0.9698361398F, 0.9699427813F,
664.1823 +  0.9700491597F, 0.9701552754F, 0.9702611286F, 0.9703667197F,
664.1824 +  0.9704720490F, 0.9705771169F, 0.9706819236F, 0.9707864695F,
664.1825 +  0.9708907549F, 0.9709947802F, 0.9710985456F, 0.9712020514F,
664.1826 +  0.9713052981F, 0.9714082859F, 0.9715110151F, 0.9716134862F,
664.1827 +  0.9717156993F, 0.9718176549F, 0.9719193532F, 0.9720207946F,
664.1828 +  0.9721219794F, 0.9722229080F, 0.9723235806F, 0.9724239976F,
664.1829 +  0.9725241593F, 0.9726240661F, 0.9727237183F, 0.9728231161F,
664.1830 +  0.9729222601F, 0.9730211503F, 0.9731197873F, 0.9732181713F,
664.1831 +  0.9733163027F, 0.9734141817F, 0.9735118088F, 0.9736091842F,
664.1832 +  0.9737063083F, 0.9738031814F, 0.9738998039F, 0.9739961760F,
664.1833 +  0.9740922981F, 0.9741881706F, 0.9742837938F, 0.9743791680F,
664.1834 +  0.9744742935F, 0.9745691707F, 0.9746637999F, 0.9747581814F,
664.1835 +  0.9748523157F, 0.9749462029F, 0.9750398435F, 0.9751332378F,
664.1836 +  0.9752263861F, 0.9753192887F, 0.9754119461F, 0.9755043585F,
664.1837 +  0.9755965262F, 0.9756884496F, 0.9757801291F, 0.9758715650F,
664.1838 +  0.9759627575F, 0.9760537071F, 0.9761444141F, 0.9762348789F,
664.1839 +  0.9763251016F, 0.9764150828F, 0.9765048228F, 0.9765943218F,
664.1840 +  0.9766835802F, 0.9767725984F, 0.9768613767F, 0.9769499154F,
664.1841 +  0.9770382149F, 0.9771262755F, 0.9772140976F, 0.9773016815F,
664.1842 +  0.9773890275F, 0.9774761360F, 0.9775630073F, 0.9776496418F,
664.1843 +  0.9777360398F, 0.9778222016F, 0.9779081277F, 0.9779938182F,
664.1844 +  0.9780792736F, 0.9781644943F, 0.9782494805F, 0.9783342326F,
664.1845 +  0.9784187509F, 0.9785030359F, 0.9785870877F, 0.9786709069F,
664.1846 +  0.9787544936F, 0.9788378484F, 0.9789209714F, 0.9790038631F,
664.1847 +  0.9790865238F, 0.9791689538F, 0.9792511535F, 0.9793331232F,
664.1848 +  0.9794148633F, 0.9794963742F, 0.9795776561F, 0.9796587094F,
664.1849 +  0.9797395345F, 0.9798201316F, 0.9799005013F, 0.9799806437F,
664.1850 +  0.9800605593F, 0.9801402483F, 0.9802197112F, 0.9802989483F,
664.1851 +  0.9803779600F, 0.9804567465F, 0.9805353082F, 0.9806136455F,
664.1852 +  0.9806917587F, 0.9807696482F, 0.9808473143F, 0.9809247574F,
664.1853 +  0.9810019778F, 0.9810789759F, 0.9811557519F, 0.9812323064F,
664.1854 +  0.9813086395F, 0.9813847517F, 0.9814606433F, 0.9815363147F,
664.1855 +  0.9816117662F, 0.9816869981F, 0.9817620108F, 0.9818368047F,
664.1856 +  0.9819113801F, 0.9819857374F, 0.9820598769F, 0.9821337989F,
664.1857 +  0.9822075038F, 0.9822809920F, 0.9823542638F, 0.9824273195F,
664.1858 +  0.9825001596F, 0.9825727843F, 0.9826451940F, 0.9827173891F,
664.1859 +  0.9827893700F, 0.9828611368F, 0.9829326901F, 0.9830040302F,
664.1860 +  0.9830751574F, 0.9831460720F, 0.9832167745F, 0.9832872652F,
664.1861 +  0.9833575444F, 0.9834276124F, 0.9834974697F, 0.9835671166F,
664.1862 +  0.9836365535F, 0.9837057806F, 0.9837747983F, 0.9838436071F,
664.1863 +  0.9839122072F, 0.9839805990F, 0.9840487829F, 0.9841167591F,
664.1864 +  0.9841845282F, 0.9842520903F, 0.9843194459F, 0.9843865953F,
664.1865 +  0.9844535389F, 0.9845202771F, 0.9845868101F, 0.9846531383F,
664.1866 +  0.9847192622F, 0.9847851820F, 0.9848508980F, 0.9849164108F,
664.1867 +  0.9849817205F, 0.9850468276F, 0.9851117324F, 0.9851764352F,
664.1868 +  0.9852409365F, 0.9853052366F, 0.9853693358F, 0.9854332344F,
664.1869 +  0.9854969330F, 0.9855604317F, 0.9856237309F, 0.9856868310F,
664.1870 +  0.9857497325F, 0.9858124355F, 0.9858749404F, 0.9859372477F,
664.1871 +  0.9859993577F, 0.9860612707F, 0.9861229871F, 0.9861845072F,
664.1872 +  0.9862458315F, 0.9863069601F, 0.9863678936F, 0.9864286322F,
664.1873 +  0.9864891764F, 0.9865495264F, 0.9866096826F, 0.9866696454F,
664.1874 +  0.9867294152F, 0.9867889922F, 0.9868483769F, 0.9869075695F,
664.1875 +  0.9869665706F, 0.9870253803F, 0.9870839991F, 0.9871424273F,
664.1876 +  0.9872006653F, 0.9872587135F, 0.9873165721F, 0.9873742415F,
664.1877 +  0.9874317222F, 0.9874890144F, 0.9875461185F, 0.9876030348F,
664.1878 +  0.9876597638F, 0.9877163057F, 0.9877726610F, 0.9878288300F,
664.1879 +  0.9878848130F, 0.9879406104F, 0.9879962225F, 0.9880516497F,
664.1880 +  0.9881068924F, 0.9881619509F, 0.9882168256F, 0.9882715168F,
664.1881 +  0.9883260249F, 0.9883803502F, 0.9884344931F, 0.9884884539F,
664.1882 +  0.9885422331F, 0.9885958309F, 0.9886492477F, 0.9887024838F,
664.1883 +  0.9887555397F, 0.9888084157F, 0.9888611120F, 0.9889136292F,
664.1884 +  0.9889659675F, 0.9890181273F, 0.9890701089F, 0.9891219128F,
664.1885 +  0.9891735392F, 0.9892249885F, 0.9892762610F, 0.9893273572F,
664.1886 +  0.9893782774F, 0.9894290219F, 0.9894795911F, 0.9895299853F,
664.1887 +  0.9895802049F, 0.9896302502F, 0.9896801217F, 0.9897298196F,
664.1888 +  0.9897793443F, 0.9898286961F, 0.9898778755F, 0.9899268828F,
664.1889 +  0.9899757183F, 0.9900243823F, 0.9900728753F, 0.9901211976F,
664.1890 +  0.9901693495F, 0.9902173314F, 0.9902651436F, 0.9903127865F,
664.1891 +  0.9903602605F, 0.9904075659F, 0.9904547031F, 0.9905016723F,
664.1892 +  0.9905484740F, 0.9905951086F, 0.9906415763F, 0.9906878775F,
664.1893 +  0.9907340126F, 0.9907799819F, 0.9908257858F, 0.9908714247F,
664.1894 +  0.9909168988F, 0.9909622086F, 0.9910073543F, 0.9910523364F,
664.1895 +  0.9910971552F, 0.9911418110F, 0.9911863042F, 0.9912306351F,
664.1896 +  0.9912748042F, 0.9913188117F, 0.9913626580F, 0.9914063435F,
664.1897 +  0.9914498684F, 0.9914932333F, 0.9915364383F, 0.9915794839F,
664.1898 +  0.9916223703F, 0.9916650981F, 0.9917076674F, 0.9917500787F,
664.1899 +  0.9917923323F, 0.9918344286F, 0.9918763679F, 0.9919181505F,
664.1900 +  0.9919597769F, 0.9920012473F, 0.9920425621F, 0.9920837217F,
664.1901 +  0.9921247263F, 0.9921655765F, 0.9922062724F, 0.9922468145F,
664.1902 +  0.9922872030F, 0.9923274385F, 0.9923675211F, 0.9924074513F,
664.1903 +  0.9924472294F, 0.9924868557F, 0.9925263306F, 0.9925656544F,
664.1904 +  0.9926048275F, 0.9926438503F, 0.9926827230F, 0.9927214461F,
664.1905 +  0.9927600199F, 0.9927984446F, 0.9928367208F, 0.9928748486F,
664.1906 +  0.9929128285F, 0.9929506608F, 0.9929883459F, 0.9930258841F,
664.1907 +  0.9930632757F, 0.9931005211F, 0.9931376207F, 0.9931745747F,
664.1908 +  0.9932113836F, 0.9932480476F, 0.9932845671F, 0.9933209425F,
664.1909 +  0.9933571742F, 0.9933932623F, 0.9934292074F, 0.9934650097F,
664.1910 +  0.9935006696F, 0.9935361874F, 0.9935715635F, 0.9936067982F,
664.1911 +  0.9936418919F, 0.9936768448F, 0.9937116574F, 0.9937463300F,
664.1912 +  0.9937808629F, 0.9938152565F, 0.9938495111F, 0.9938836271F,
664.1913 +  0.9939176047F, 0.9939514444F, 0.9939851465F, 0.9940187112F,
664.1914 +  0.9940521391F, 0.9940854303F, 0.9941185853F, 0.9941516044F,
664.1915 +  0.9941844879F, 0.9942172361F, 0.9942498495F, 0.9942823283F,
664.1916 +  0.9943146729F, 0.9943468836F, 0.9943789608F, 0.9944109047F,
664.1917 +  0.9944427158F, 0.9944743944F, 0.9945059408F, 0.9945373553F,
664.1918 +  0.9945686384F, 0.9945997902F, 0.9946308112F, 0.9946617017F,
664.1919 +  0.9946924621F, 0.9947230926F, 0.9947535937F, 0.9947839656F,
664.1920 +  0.9948142086F, 0.9948443232F, 0.9948743097F, 0.9949041683F,
664.1921 +  0.9949338995F, 0.9949635035F, 0.9949929807F, 0.9950223315F,
664.1922 +  0.9950515561F, 0.9950806549F, 0.9951096282F, 0.9951384764F,
664.1923 +  0.9951671998F, 0.9951957987F, 0.9952242735F, 0.9952526245F,
664.1924 +  0.9952808520F, 0.9953089564F, 0.9953369380F, 0.9953647971F,
664.1925 +  0.9953925340F, 0.9954201491F, 0.9954476428F, 0.9954750153F,
664.1926 +  0.9955022670F, 0.9955293981F, 0.9955564092F, 0.9955833003F,
664.1927 +  0.9956100720F, 0.9956367245F, 0.9956632582F, 0.9956896733F,
664.1928 +  0.9957159703F, 0.9957421494F, 0.9957682110F, 0.9957941553F,
664.1929 +  0.9958199828F, 0.9958456937F, 0.9958712884F, 0.9958967672F,
664.1930 +  0.9959221305F, 0.9959473784F, 0.9959725115F, 0.9959975300F,
664.1931 +  0.9960224342F, 0.9960472244F, 0.9960719011F, 0.9960964644F,
664.1932 +  0.9961209148F, 0.9961452525F, 0.9961694779F, 0.9961935913F,
664.1933 +  0.9962175930F, 0.9962414834F, 0.9962652627F, 0.9962889313F,
664.1934 +  0.9963124895F, 0.9963359377F, 0.9963592761F, 0.9963825051F,
664.1935 +  0.9964056250F, 0.9964286361F, 0.9964515387F, 0.9964743332F,
664.1936 +  0.9964970198F, 0.9965195990F, 0.9965420709F, 0.9965644360F,
664.1937 +  0.9965866946F, 0.9966088469F, 0.9966308932F, 0.9966528340F,
664.1938 +  0.9966746695F, 0.9966964001F, 0.9967180260F, 0.9967395475F,
664.1939 +  0.9967609651F, 0.9967822789F, 0.9968034894F, 0.9968245968F,
664.1940 +  0.9968456014F, 0.9968665036F, 0.9968873037F, 0.9969080019F,
664.1941 +  0.9969285987F, 0.9969490942F, 0.9969694889F, 0.9969897830F,
664.1942 +  0.9970099769F, 0.9970300708F, 0.9970500651F, 0.9970699601F,
664.1943 +  0.9970897561F, 0.9971094533F, 0.9971290522F, 0.9971485531F,
664.1944 +  0.9971679561F, 0.9971872617F, 0.9972064702F, 0.9972255818F,
664.1945 +  0.9972445968F, 0.9972635157F, 0.9972823386F, 0.9973010659F,
664.1946 +  0.9973196980F, 0.9973382350F, 0.9973566773F, 0.9973750253F,
664.1947 +  0.9973932791F, 0.9974114392F, 0.9974295059F, 0.9974474793F,
664.1948 +  0.9974653599F, 0.9974831480F, 0.9975008438F, 0.9975184476F,
664.1949 +  0.9975359598F, 0.9975533806F, 0.9975707104F, 0.9975879495F,
664.1950 +  0.9976050981F, 0.9976221566F, 0.9976391252F, 0.9976560043F,
664.1951 +  0.9976727941F, 0.9976894950F, 0.9977061073F, 0.9977226312F,
664.1952 +  0.9977390671F, 0.9977554152F, 0.9977716759F, 0.9977878495F,
664.1953 +  0.9978039361F, 0.9978199363F, 0.9978358501F, 0.9978516780F,
664.1954 +  0.9978674202F, 0.9978830771F, 0.9978986488F, 0.9979141358F,
664.1955 +  0.9979295383F, 0.9979448566F, 0.9979600909F, 0.9979752417F,
664.1956 +  0.9979903091F, 0.9980052936F, 0.9980201952F, 0.9980350145F,
664.1957 +  0.9980497515F, 0.9980644067F, 0.9980789804F, 0.9980934727F,
664.1958 +  0.9981078841F, 0.9981222147F, 0.9981364649F, 0.9981506350F,
664.1959 +  0.9981647253F, 0.9981787360F, 0.9981926674F, 0.9982065199F,
664.1960 +  0.9982202936F, 0.9982339890F, 0.9982476062F, 0.9982611456F,
664.1961 +  0.9982746074F, 0.9982879920F, 0.9983012996F, 0.9983145304F,
664.1962 +  0.9983276849F, 0.9983407632F, 0.9983537657F, 0.9983666926F,
664.1963 +  0.9983795442F, 0.9983923208F, 0.9984050226F, 0.9984176501F,
664.1964 +  0.9984302033F, 0.9984426827F, 0.9984550884F, 0.9984674208F,
664.1965 +  0.9984796802F, 0.9984918667F, 0.9985039808F, 0.9985160227F,
664.1966 +  0.9985279926F, 0.9985398909F, 0.9985517177F, 0.9985634734F,
664.1967 +  0.9985751583F, 0.9985867727F, 0.9985983167F, 0.9986097907F,
664.1968 +  0.9986211949F, 0.9986325297F, 0.9986437953F, 0.9986549919F,
664.1969 +  0.9986661199F, 0.9986771795F, 0.9986881710F, 0.9986990946F,
664.1970 +  0.9987099507F, 0.9987207394F, 0.9987314611F, 0.9987421161F,
664.1971 +  0.9987527045F, 0.9987632267F, 0.9987736829F, 0.9987840734F,
664.1972 +  0.9987943985F, 0.9988046584F, 0.9988148534F, 0.9988249838F,
664.1973 +  0.9988350498F, 0.9988450516F, 0.9988549897F, 0.9988648641F,
664.1974 +  0.9988746753F, 0.9988844233F, 0.9988941086F, 0.9989037313F,
664.1975 +  0.9989132918F, 0.9989227902F, 0.9989322269F, 0.9989416021F,
664.1976 +  0.9989509160F, 0.9989601690F, 0.9989693613F, 0.9989784931F,
664.1977 +  0.9989875647F, 0.9989965763F, 0.9990055283F, 0.9990144208F,
664.1978 +  0.9990232541F, 0.9990320286F, 0.9990407443F, 0.9990494016F,
664.1979 +  0.9990580008F, 0.9990665421F, 0.9990750257F, 0.9990834519F,
664.1980 +  0.9990918209F, 0.9991001331F, 0.9991083886F, 0.9991165877F,
664.1981 +  0.9991247307F, 0.9991328177F, 0.9991408491F, 0.9991488251F,
664.1982 +  0.9991567460F, 0.9991646119F, 0.9991724232F, 0.9991801801F,
664.1983 +  0.9991878828F, 0.9991955316F, 0.9992031267F, 0.9992106684F,
664.1984 +  0.9992181569F, 0.9992255925F, 0.9992329753F, 0.9992403057F,
664.1985 +  0.9992475839F, 0.9992548101F, 0.9992619846F, 0.9992691076F,
664.1986 +  0.9992761793F, 0.9992832001F, 0.9992901701F, 0.9992970895F,
664.1987 +  0.9993039587F, 0.9993107777F, 0.9993175470F, 0.9993242667F,
664.1988 +  0.9993309371F, 0.9993375583F, 0.9993441307F, 0.9993506545F,
664.1989 +  0.9993571298F, 0.9993635570F, 0.9993699362F, 0.9993762678F,
664.1990 +  0.9993825519F, 0.9993887887F, 0.9993949785F, 0.9994011216F,
664.1991 +  0.9994072181F, 0.9994132683F, 0.9994192725F, 0.9994252307F,
664.1992 +  0.9994311434F, 0.9994370107F, 0.9994428327F, 0.9994486099F,
664.1993 +  0.9994543423F, 0.9994600303F, 0.9994656739F, 0.9994712736F,
664.1994 +  0.9994768294F, 0.9994823417F, 0.9994878105F, 0.9994932363F,
664.1995 +  0.9994986191F, 0.9995039592F, 0.9995092568F, 0.9995145122F,
664.1996 +  0.9995197256F, 0.9995248971F, 0.9995300270F, 0.9995351156F,
664.1997 +  0.9995401630F, 0.9995451695F, 0.9995501352F, 0.9995550604F,
664.1998 +  0.9995599454F, 0.9995647903F, 0.9995695953F, 0.9995743607F,
664.1999 +  0.9995790866F, 0.9995837734F, 0.9995884211F, 0.9995930300F,
664.2000 +  0.9995976004F, 0.9996021324F, 0.9996066263F, 0.9996110822F,
664.2001 +  0.9996155004F, 0.9996198810F, 0.9996242244F, 0.9996285306F,
664.2002 +  0.9996327999F, 0.9996370326F, 0.9996412287F, 0.9996453886F,
664.2003 +  0.9996495125F, 0.9996536004F, 0.9996576527F, 0.9996616696F,
664.2004 +  0.9996656512F, 0.9996695977F, 0.9996735094F, 0.9996773865F,
664.2005 +  0.9996812291F, 0.9996850374F, 0.9996888118F, 0.9996925523F,
664.2006 +  0.9996962591F, 0.9996999325F, 0.9997035727F, 0.9997071798F,
664.2007 +  0.9997107541F, 0.9997142957F, 0.9997178049F, 0.9997212818F,
664.2008 +  0.9997247266F, 0.9997281396F, 0.9997315209F, 0.9997348708F,
664.2009 +  0.9997381893F, 0.9997414767F, 0.9997447333F, 0.9997479591F,
664.2010 +  0.9997511544F, 0.9997543194F, 0.9997574542F, 0.9997605591F,
664.2011 +  0.9997636342F, 0.9997666797F, 0.9997696958F, 0.9997726828F,
664.2012 +  0.9997756407F, 0.9997785698F, 0.9997814703F, 0.9997843423F,
664.2013 +  0.9997871860F, 0.9997900016F, 0.9997927894F, 0.9997955494F,
664.2014 +  0.9997982818F, 0.9998009869F, 0.9998036648F, 0.9998063157F,
664.2015 +  0.9998089398F, 0.9998115373F, 0.9998141082F, 0.9998166529F,
664.2016 +  0.9998191715F, 0.9998216642F, 0.9998241311F, 0.9998265724F,
664.2017 +  0.9998289884F, 0.9998313790F, 0.9998337447F, 0.9998360854F,
664.2018 +  0.9998384015F, 0.9998406930F, 0.9998429602F, 0.9998452031F,
664.2019 +  0.9998474221F, 0.9998496171F, 0.9998517885F, 0.9998539364F,
664.2020 +  0.9998560610F, 0.9998581624F, 0.9998602407F, 0.9998622962F,
664.2021 +  0.9998643291F, 0.9998663394F, 0.9998683274F, 0.9998702932F,
664.2022 +  0.9998722370F, 0.9998741589F, 0.9998760591F, 0.9998779378F,
664.2023 +  0.9998797952F, 0.9998816313F, 0.9998834464F, 0.9998852406F,
664.2024 +  0.9998870141F, 0.9998887670F, 0.9998904995F, 0.9998922117F,
664.2025 +  0.9998939039F, 0.9998955761F, 0.9998972285F, 0.9998988613F,
664.2026 +  0.9999004746F, 0.9999020686F, 0.9999036434F, 0.9999051992F,
664.2027 +  0.9999067362F, 0.9999082544F, 0.9999097541F, 0.9999112354F,
664.2028 +  0.9999126984F, 0.9999141433F, 0.9999155703F, 0.9999169794F,
664.2029 +  0.9999183709F, 0.9999197449F, 0.9999211014F, 0.9999224408F,
664.2030 +  0.9999237631F, 0.9999250684F, 0.9999263570F, 0.9999276289F,
664.2031 +  0.9999288843F, 0.9999301233F, 0.9999313461F, 0.9999325529F,
664.2032 +  0.9999337437F, 0.9999349187F, 0.9999360780F, 0.9999372218F,
664.2033 +  0.9999383503F, 0.9999394635F, 0.9999405616F, 0.9999416447F,
664.2034 +  0.9999427129F, 0.9999437665F, 0.9999448055F, 0.9999458301F,
664.2035 +  0.9999468404F, 0.9999478365F, 0.9999488185F, 0.9999497867F,
664.2036 +  0.9999507411F, 0.9999516819F, 0.9999526091F, 0.9999535230F,
664.2037 +  0.9999544236F, 0.9999553111F, 0.9999561856F, 0.9999570472F,
664.2038 +  0.9999578960F, 0.9999587323F, 0.9999595560F, 0.9999603674F,
664.2039 +  0.9999611666F, 0.9999619536F, 0.9999627286F, 0.9999634917F,
664.2040 +  0.9999642431F, 0.9999649828F, 0.9999657110F, 0.9999664278F,
664.2041 +  0.9999671334F, 0.9999678278F, 0.9999685111F, 0.9999691835F,
664.2042 +  0.9999698451F, 0.9999704960F, 0.9999711364F, 0.9999717662F,
664.2043 +  0.9999723858F, 0.9999729950F, 0.9999735942F, 0.9999741834F,
664.2044 +  0.9999747626F, 0.9999753321F, 0.9999758919F, 0.9999764421F,
664.2045 +  0.9999769828F, 0.9999775143F, 0.9999780364F, 0.9999785495F,
664.2046 +  0.9999790535F, 0.9999795485F, 0.9999800348F, 0.9999805124F,
664.2047 +  0.9999809813F, 0.9999814417F, 0.9999818938F, 0.9999823375F,
664.2048 +  0.9999827731F, 0.9999832005F, 0.9999836200F, 0.9999840316F,
664.2049 +  0.9999844353F, 0.9999848314F, 0.9999852199F, 0.9999856008F,
664.2050 +  0.9999859744F, 0.9999863407F, 0.9999866997F, 0.9999870516F,
664.2051 +  0.9999873965F, 0.9999877345F, 0.9999880656F, 0.9999883900F,
664.2052 +  0.9999887078F, 0.9999890190F, 0.9999893237F, 0.9999896220F,
664.2053 +  0.9999899140F, 0.9999901999F, 0.9999904796F, 0.9999907533F,
664.2054 +  0.9999910211F, 0.9999912830F, 0.9999915391F, 0.9999917896F,
664.2055 +  0.9999920345F, 0.9999922738F, 0.9999925077F, 0.9999927363F,
664.2056 +  0.9999929596F, 0.9999931777F, 0.9999933907F, 0.9999935987F,
664.2057 +  0.9999938018F, 0.9999940000F, 0.9999941934F, 0.9999943820F,
664.2058 +  0.9999945661F, 0.9999947456F, 0.9999949206F, 0.9999950912F,
664.2059 +  0.9999952575F, 0.9999954195F, 0.9999955773F, 0.9999957311F,
664.2060 +  0.9999958807F, 0.9999960265F, 0.9999961683F, 0.9999963063F,
664.2061 +  0.9999964405F, 0.9999965710F, 0.9999966979F, 0.9999968213F,
664.2062 +  0.9999969412F, 0.9999970576F, 0.9999971707F, 0.9999972805F,
664.2063 +  0.9999973871F, 0.9999974905F, 0.9999975909F, 0.9999976881F,
664.2064 +  0.9999977824F, 0.9999978738F, 0.9999979624F, 0.9999980481F,
664.2065 +  0.9999981311F, 0.9999982115F, 0.9999982892F, 0.9999983644F,
664.2066 +  0.9999984370F, 0.9999985072F, 0.9999985750F, 0.9999986405F,
664.2067 +  0.9999987037F, 0.9999987647F, 0.9999988235F, 0.9999988802F,
664.2068 +  0.9999989348F, 0.9999989873F, 0.9999990379F, 0.9999990866F,
664.2069 +  0.9999991334F, 0.9999991784F, 0.9999992217F, 0.9999992632F,
664.2070 +  0.9999993030F, 0.9999993411F, 0.9999993777F, 0.9999994128F,
664.2071 +  0.9999994463F, 0.9999994784F, 0.9999995091F, 0.9999995384F,
664.2072 +  0.9999995663F, 0.9999995930F, 0.9999996184F, 0.9999996426F,
664.2073 +  0.9999996657F, 0.9999996876F, 0.9999997084F, 0.9999997282F,
664.2074 +  0.9999997469F, 0.9999997647F, 0.9999997815F, 0.9999997973F,
664.2075 +  0.9999998123F, 0.9999998265F, 0.9999998398F, 0.9999998524F,
664.2076 +  0.9999998642F, 0.9999998753F, 0.9999998857F, 0.9999998954F,
664.2077 +  0.9999999045F, 0.9999999130F, 0.9999999209F, 0.9999999282F,
664.2078 +  0.9999999351F, 0.9999999414F, 0.9999999472F, 0.9999999526F,
664.2079 +  0.9999999576F, 0.9999999622F, 0.9999999664F, 0.9999999702F,
664.2080 +  0.9999999737F, 0.9999999769F, 0.9999999798F, 0.9999999824F,
664.2081 +  0.9999999847F, 0.9999999868F, 0.9999999887F, 0.9999999904F,
664.2082 +  0.9999999919F, 0.9999999932F, 0.9999999943F, 0.9999999953F,
664.2083 +  0.9999999961F, 0.9999999969F, 0.9999999975F, 0.9999999980F,
664.2084 +  0.9999999985F, 0.9999999988F, 0.9999999991F, 0.9999999993F,
664.2085 +  0.9999999995F, 0.9999999997F, 0.9999999998F, 0.9999999999F,
664.2086 +  0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F,
664.2087 +  1.0000000000F, 1.0000000000F, 1.0000000000F, 1.0000000000F,
664.2088 +};
664.2089 +
664.2090 +static const float *const vwin[8] = {
664.2091 +  vwin64,
664.2092 +  vwin128,
664.2093 +  vwin256,
664.2094 +  vwin512,
664.2095 +  vwin1024,
664.2096 +  vwin2048,
664.2097 +  vwin4096,
664.2098 +  vwin8192,
664.2099 +};
664.2100 +
664.2101 +const float *_vorbis_window_get(int n){
664.2102 +  return vwin[n];
664.2103 +}
664.2104 +
664.2105 +void _vorbis_apply_window(float *d,int *winno,long *blocksizes,
664.2106 +                          int lW,int W,int nW){
664.2107 +  lW=(W?lW:0);
664.2108 +  nW=(W?nW:0);
664.2109 +
664.2110 +  {
664.2111 +    const float *windowLW=vwin[winno[lW]];
664.2112 +    const float *windowNW=vwin[winno[nW]];
664.2113 +
664.2114 +    long n=blocksizes[W];
664.2115 +    long ln=blocksizes[lW];
664.2116 +    long rn=blocksizes[nW];
664.2117 +
664.2118 +    long leftbegin=n/4-ln/4;
664.2119 +    long leftend=leftbegin+ln/2;
664.2120 +
664.2121 +    long rightbegin=n/2+n/4-rn/4;
664.2122 +    long rightend=rightbegin+rn/2;
664.2123 +
664.2124 +    int i,p;
664.2125 +
664.2126 +    for(i=0;i<leftbegin;i++)
664.2127 +      d[i]=0.f;
664.2128 +
664.2129 +    for(p=0;i<leftend;i++,p++)
664.2130 +      d[i]*=windowLW[p];
664.2131 +
664.2132 +    for(i=rightbegin,p=rn/2-1;i<rightend;i++,p--)
664.2133 +      d[i]*=windowNW[p];
664.2134 +
664.2135 +    for(;i<n;i++)
664.2136 +      d[i]=0.f;
664.2137 +  }
664.2138 +}
   665.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   665.2 +++ b/libs/vorbis/window.h	Sat Feb 01 19:58:19 2014 +0200
   665.3 @@ -0,0 +1,26 @@
   665.4 +/********************************************************************
   665.5 + *                                                                  *
   665.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
   665.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
   665.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
   665.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  665.10 + *                                                                  *
  665.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
  665.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
  665.13 + *                                                                  *
  665.14 + ********************************************************************
  665.15 +
  665.16 + function: window functions
  665.17 + last mod: $Id: window.h 13293 2007-07-24 00:09:47Z xiphmont $
  665.18 +
  665.19 + ********************************************************************/
  665.20 +
  665.21 +#ifndef _V_WINDOW_
  665.22 +#define _V_WINDOW_
  665.23 +
  665.24 +extern float *_vorbis_window_get(int n);
  665.25 +extern void _vorbis_apply_window(float *d,int *winno,long *blocksizes,
  665.26 +                          int lW,int W,int nW);
  665.27 +
  665.28 +
  665.29 +#endif
   666.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   666.2 +++ b/libs/zlib/LICENSE	Sat Feb 01 19:58:19 2014 +0200
   666.3 @@ -0,0 +1,20 @@
   666.4 + (C) 1995-2010 Jean-loup Gailly and Mark Adler
   666.5 +
   666.6 +  This software is provided 'as-is', without any express or implied
   666.7 +  warranty.  In no event will the authors be held liable for any damages
   666.8 +  arising from the use of this software.
   666.9 +
  666.10 +  Permission is granted to anyone to use this software for any purpose,
  666.11 +  including commercial applications, and to alter it and redistribute it
  666.12 +  freely, subject to the following restrictions:
  666.13 +
  666.14 +  1. The origin of this software must not be misrepresented; you must not
  666.15 +     claim that you wrote the original software. If you use this software
  666.16 +     in a product, an acknowledgment in the product documentation would be
  666.17 +     appreciated but is not required.
  666.18 +  2. Altered source versions must be plainly marked as such, and must not be
  666.19 +     misrepresented as being the original software.
  666.20 +  3. This notice may not be removed or altered from any source distribution.
  666.21 +
  666.22 +  Jean-loup Gailly        Mark Adler
  666.23 +  jloup@gzip.org          madler@alumni.caltech.edu
   667.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   667.2 +++ b/libs/zlib/adler32.c	Sat Feb 01 19:58:19 2014 +0200
   667.3 @@ -0,0 +1,149 @@
   667.4 +/* adler32.c -- compute the Adler-32 checksum of a data stream
   667.5 + * Copyright (C) 1995-2004 Mark Adler
   667.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   667.7 + */
   667.8 +
   667.9 +/* @(#) $Id$ */
  667.10 +
  667.11 +#define ZLIB_INTERNAL
  667.12 +#include "zlib.h"
  667.13 +
  667.14 +#define BASE 65521UL    /* largest prime smaller than 65536 */
  667.15 +#define NMAX 5552
  667.16 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
  667.17 +
  667.18 +#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
  667.19 +#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
  667.20 +#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
  667.21 +#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
  667.22 +#define DO16(buf)   DO8(buf,0); DO8(buf,8);
  667.23 +
  667.24 +/* use NO_DIVIDE if your processor does not do division in hardware */
  667.25 +#ifdef NO_DIVIDE
  667.26 +#  define MOD(a) \
  667.27 +    do { \
  667.28 +        if (a >= (BASE << 16)) a -= (BASE << 16); \
  667.29 +        if (a >= (BASE << 15)) a -= (BASE << 15); \
  667.30 +        if (a >= (BASE << 14)) a -= (BASE << 14); \
  667.31 +        if (a >= (BASE << 13)) a -= (BASE << 13); \
  667.32 +        if (a >= (BASE << 12)) a -= (BASE << 12); \
  667.33 +        if (a >= (BASE << 11)) a -= (BASE << 11); \
  667.34 +        if (a >= (BASE << 10)) a -= (BASE << 10); \
  667.35 +        if (a >= (BASE << 9)) a -= (BASE << 9); \
  667.36 +        if (a >= (BASE << 8)) a -= (BASE << 8); \
  667.37 +        if (a >= (BASE << 7)) a -= (BASE << 7); \
  667.38 +        if (a >= (BASE << 6)) a -= (BASE << 6); \
  667.39 +        if (a >= (BASE << 5)) a -= (BASE << 5); \
  667.40 +        if (a >= (BASE << 4)) a -= (BASE << 4); \
  667.41 +        if (a >= (BASE << 3)) a -= (BASE << 3); \
  667.42 +        if (a >= (BASE << 2)) a -= (BASE << 2); \
  667.43 +        if (a >= (BASE << 1)) a -= (BASE << 1); \
  667.44 +        if (a >= BASE) a -= BASE; \
  667.45 +    } while (0)
  667.46 +#  define MOD4(a) \
  667.47 +    do { \
  667.48 +        if (a >= (BASE << 4)) a -= (BASE << 4); \
  667.49 +        if (a >= (BASE << 3)) a -= (BASE << 3); \
  667.50 +        if (a >= (BASE << 2)) a -= (BASE << 2); \
  667.51 +        if (a >= (BASE << 1)) a -= (BASE << 1); \
  667.52 +        if (a >= BASE) a -= BASE; \
  667.53 +    } while (0)
  667.54 +#else
  667.55 +#  define MOD(a) a %= BASE
  667.56 +#  define MOD4(a) a %= BASE
  667.57 +#endif
  667.58 +
  667.59 +/* ========================================================================= */
  667.60 +uLong ZEXPORT adler32(adler, buf, len)
  667.61 +    uLong adler;
  667.62 +    const Bytef *buf;
  667.63 +    uInt len;
  667.64 +{
  667.65 +    unsigned long sum2;
  667.66 +    unsigned n;
  667.67 +
  667.68 +    /* split Adler-32 into component sums */
  667.69 +    sum2 = (adler >> 16) & 0xffff;
  667.70 +    adler &= 0xffff;
  667.71 +
  667.72 +    /* in case user likes doing a byte at a time, keep it fast */
  667.73 +    if (len == 1) {
  667.74 +        adler += buf[0];
  667.75 +        if (adler >= BASE)
  667.76 +            adler -= BASE;
  667.77 +        sum2 += adler;
  667.78 +        if (sum2 >= BASE)
  667.79 +            sum2 -= BASE;
  667.80 +        return adler | (sum2 << 16);
  667.81 +    }
  667.82 +
  667.83 +    /* initial Adler-32 value (deferred check for len == 1 speed) */
  667.84 +    if (buf == Z_NULL)
  667.85 +        return 1L;
  667.86 +
  667.87 +    /* in case short lengths are provided, keep it somewhat fast */
  667.88 +    if (len < 16) {
  667.89 +        while (len--) {
  667.90 +            adler += *buf++;
  667.91 +            sum2 += adler;
  667.92 +        }
  667.93 +        if (adler >= BASE)
  667.94 +            adler -= BASE;
  667.95 +        MOD4(sum2);             /* only added so many BASE's */
  667.96 +        return adler | (sum2 << 16);
  667.97 +    }
  667.98 +
  667.99 +    /* do length NMAX blocks -- requires just one modulo operation */
 667.100 +    while (len >= NMAX) {
 667.101 +        len -= NMAX;
 667.102 +        n = NMAX / 16;          /* NMAX is divisible by 16 */
 667.103 +        do {
 667.104 +            DO16(buf);          /* 16 sums unrolled */
 667.105 +            buf += 16;
 667.106 +        } while (--n);
 667.107 +        MOD(adler);
 667.108 +        MOD(sum2);
 667.109 +    }
 667.110 +
 667.111 +    /* do remaining bytes (less than NMAX, still just one modulo) */
 667.112 +    if (len) {                  /* avoid modulos if none remaining */
 667.113 +        while (len >= 16) {
 667.114 +            len -= 16;
 667.115 +            DO16(buf);
 667.116 +            buf += 16;
 667.117 +        }
 667.118 +        while (len--) {
 667.119 +            adler += *buf++;
 667.120 +            sum2 += adler;
 667.121 +        }
 667.122 +        MOD(adler);
 667.123 +        MOD(sum2);
 667.124 +    }
 667.125 +
 667.126 +    /* return recombined sums */
 667.127 +    return adler | (sum2 << 16);
 667.128 +}
 667.129 +
 667.130 +/* ========================================================================= */
 667.131 +uLong ZEXPORT adler32_combine(adler1, adler2, len2)
 667.132 +    uLong adler1;
 667.133 +    uLong adler2;
 667.134 +    z_off_t len2;
 667.135 +{
 667.136 +    unsigned long sum1;
 667.137 +    unsigned long sum2;
 667.138 +    unsigned rem;
 667.139 +
 667.140 +    /* the derivation of this formula is left as an exercise for the reader */
 667.141 +    rem = (unsigned)(len2 % BASE);
 667.142 +    sum1 = adler1 & 0xffff;
 667.143 +    sum2 = rem * sum1;
 667.144 +    MOD(sum2);
 667.145 +    sum1 += (adler2 & 0xffff) + BASE - 1;
 667.146 +    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
 667.147 +    if (sum1 > BASE) sum1 -= BASE;
 667.148 +    if (sum1 > BASE) sum1 -= BASE;
 667.149 +    if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
 667.150 +    if (sum2 > BASE) sum2 -= BASE;
 667.151 +    return sum1 | (sum2 << 16);
 667.152 +}
   668.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   668.2 +++ b/libs/zlib/compress.c	Sat Feb 01 19:58:19 2014 +0200
   668.3 @@ -0,0 +1,79 @@
   668.4 +/* compress.c -- compress a memory buffer
   668.5 + * Copyright (C) 1995-2003 Jean-loup Gailly.
   668.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   668.7 + */
   668.8 +
   668.9 +/* @(#) $Id$ */
  668.10 +
  668.11 +#define ZLIB_INTERNAL
  668.12 +#include "zlib.h"
  668.13 +
  668.14 +/* ===========================================================================
  668.15 +     Compresses the source buffer into the destination buffer. The level
  668.16 +   parameter has the same meaning as in deflateInit.  sourceLen is the byte
  668.17 +   length of the source buffer. Upon entry, destLen is the total size of the
  668.18 +   destination buffer, which must be at least 0.1% larger than sourceLen plus
  668.19 +   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
  668.20 +
  668.21 +     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
  668.22 +   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
  668.23 +   Z_STREAM_ERROR if the level parameter is invalid.
  668.24 +*/
  668.25 +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
  668.26 +    Bytef *dest;
  668.27 +    uLongf *destLen;
  668.28 +    const Bytef *source;
  668.29 +    uLong sourceLen;
  668.30 +    int level;
  668.31 +{
  668.32 +    z_stream stream;
  668.33 +    int err;
  668.34 +
  668.35 +    stream.next_in = (Bytef*)source;
  668.36 +    stream.avail_in = (uInt)sourceLen;
  668.37 +#ifdef MAXSEG_64K
  668.38 +    /* Check for source > 64K on 16-bit machine: */
  668.39 +    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
  668.40 +#endif
  668.41 +    stream.next_out = dest;
  668.42 +    stream.avail_out = (uInt)*destLen;
  668.43 +    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
  668.44 +
  668.45 +    stream.zalloc = (alloc_func)0;
  668.46 +    stream.zfree = (free_func)0;
  668.47 +    stream.opaque = (voidpf)0;
  668.48 +
  668.49 +    err = deflateInit(&stream, level);
  668.50 +    if (err != Z_OK) return err;
  668.51 +
  668.52 +    err = deflate(&stream, Z_FINISH);
  668.53 +    if (err != Z_STREAM_END) {
  668.54 +        deflateEnd(&stream);
  668.55 +        return err == Z_OK ? Z_BUF_ERROR : err;
  668.56 +    }
  668.57 +    *destLen = stream.total_out;
  668.58 +
  668.59 +    err = deflateEnd(&stream);
  668.60 +    return err;
  668.61 +}
  668.62 +
  668.63 +/* ===========================================================================
  668.64 + */
  668.65 +int ZEXPORT compress (dest, destLen, source, sourceLen)
  668.66 +    Bytef *dest;
  668.67 +    uLongf *destLen;
  668.68 +    const Bytef *source;
  668.69 +    uLong sourceLen;
  668.70 +{
  668.71 +    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
  668.72 +}
  668.73 +
  668.74 +/* ===========================================================================
  668.75 +     If the default memLevel or windowBits for deflateInit() is changed, then
  668.76 +   this function needs to be updated.
  668.77 + */
  668.78 +uLong ZEXPORT compressBound (sourceLen)
  668.79 +    uLong sourceLen;
  668.80 +{
  668.81 +    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
  668.82 +}
   669.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   669.2 +++ b/libs/zlib/crc32.c	Sat Feb 01 19:58:19 2014 +0200
   669.3 @@ -0,0 +1,423 @@
   669.4 +/* crc32.c -- compute the CRC-32 of a data stream
   669.5 + * Copyright (C) 1995-2005 Mark Adler
   669.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   669.7 + *
   669.8 + * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
   669.9 + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
  669.10 + * tables for updating the shift register in one step with three exclusive-ors
  669.11 + * instead of four steps with four exclusive-ors.  This results in about a
  669.12 + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
  669.13 + */
  669.14 +
  669.15 +/* @(#) $Id$ */
  669.16 +
  669.17 +/*
  669.18 +  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
  669.19 +  protection on the static variables used to control the first-use generation
  669.20 +  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
  669.21 +  first call get_crc_table() to initialize the tables before allowing more than
  669.22 +  one thread to use crc32().
  669.23 + */
  669.24 +
  669.25 +#ifdef MAKECRCH
  669.26 +#  include <stdio.h>
  669.27 +#  ifndef DYNAMIC_CRC_TABLE
  669.28 +#    define DYNAMIC_CRC_TABLE
  669.29 +#  endif /* !DYNAMIC_CRC_TABLE */
  669.30 +#endif /* MAKECRCH */
  669.31 +
  669.32 +#include "zutil.h"      /* for STDC and FAR definitions */
  669.33 +
  669.34 +#define local static
  669.35 +
  669.36 +/* Find a four-byte integer type for crc32_little() and crc32_big(). */
  669.37 +#ifndef NOBYFOUR
  669.38 +#  ifdef STDC           /* need ANSI C limits.h to determine sizes */
  669.39 +#    include <limits.h>
  669.40 +#    define BYFOUR
  669.41 +#    if (UINT_MAX == 0xffffffffUL)
  669.42 +       typedef unsigned int u4;
  669.43 +#    else
  669.44 +#      if (ULONG_MAX == 0xffffffffUL)
  669.45 +         typedef unsigned long u4;
  669.46 +#      else
  669.47 +#        if (USHRT_MAX == 0xffffffffUL)
  669.48 +           typedef unsigned short u4;
  669.49 +#        else
  669.50 +#          undef BYFOUR     /* can't find a four-byte integer type! */
  669.51 +#        endif
  669.52 +#      endif
  669.53 +#    endif
  669.54 +#  endif /* STDC */
  669.55 +#endif /* !NOBYFOUR */
  669.56 +
  669.57 +/* Definitions for doing the crc four data bytes at a time. */
  669.58 +#ifdef BYFOUR
  669.59 +#  define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
  669.60 +                (((w)&0xff00)<<8)+(((w)&0xff)<<24))
  669.61 +   local unsigned long crc32_little OF((unsigned long,
  669.62 +                        const unsigned char FAR *, unsigned));
  669.63 +   local unsigned long crc32_big OF((unsigned long,
  669.64 +                        const unsigned char FAR *, unsigned));
  669.65 +#  define TBLS 8
  669.66 +#else
  669.67 +#  define TBLS 1
  669.68 +#endif /* BYFOUR */
  669.69 +
  669.70 +/* Local functions for crc concatenation */
  669.71 +local unsigned long gf2_matrix_times OF((unsigned long *mat,
  669.72 +                                         unsigned long vec));
  669.73 +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
  669.74 +
  669.75 +#ifdef DYNAMIC_CRC_TABLE
  669.76 +
  669.77 +local volatile int crc_table_empty = 1;
  669.78 +local unsigned long FAR crc_table[TBLS][256];
  669.79 +local void make_crc_table OF((void));
  669.80 +#ifdef MAKECRCH
  669.81 +   local void write_table OF((FILE *, const unsigned long FAR *));
  669.82 +#endif /* MAKECRCH */
  669.83 +/*
  669.84 +  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
  669.85 +  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
  669.86 +
  669.87 +  Polynomials over GF(2) are represented in binary, one bit per coefficient,
  669.88 +  with the lowest powers in the most significant bit.  Then adding polynomials
  669.89 +  is just exclusive-or, and multiplying a polynomial by x is a right shift by
  669.90 +  one.  If we call the above polynomial p, and represent a byte as the
  669.91 +  polynomial q, also with the lowest power in the most significant bit (so the
  669.92 +  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
  669.93 +  where a mod b means the remainder after dividing a by b.
  669.94 +
  669.95 +  This calculation is done using the shift-register method of multiplying and
  669.96 +  taking the remainder.  The register is initialized to zero, and for each
  669.97 +  incoming bit, x^32 is added mod p to the register if the bit is a one (where
  669.98 +  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
  669.99 +  x (which is shifting right by one and adding x^32 mod p if the bit shifted
 669.100 +  out is a one).  We start with the highest power (least significant bit) of
 669.101 +  q and repeat for all eight bits of q.
 669.102 +
 669.103 +  The first table is simply the CRC of all possible eight bit values.  This is
 669.104 +  all the information needed to generate CRCs on data a byte at a time for all
 669.105 +  combinations of CRC register values and incoming bytes.  The remaining tables
 669.106 +  allow for word-at-a-time CRC calculation for both big-endian and little-
 669.107 +  endian machines, where a word is four bytes.
 669.108 +*/
 669.109 +local void make_crc_table()
 669.110 +{
 669.111 +    unsigned long c;
 669.112 +    int n, k;
 669.113 +    unsigned long poly;                 /* polynomial exclusive-or pattern */
 669.114 +    /* terms of polynomial defining this crc (except x^32): */
 669.115 +    static volatile int first = 1;      /* flag to limit concurrent making */
 669.116 +    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
 669.117 +
 669.118 +    /* See if another task is already doing this (not thread-safe, but better
 669.119 +       than nothing -- significantly reduces duration of vulnerability in
 669.120 +       case the advice about DYNAMIC_CRC_TABLE is ignored) */
 669.121 +    if (first) {
 669.122 +        first = 0;
 669.123 +
 669.124 +        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
 669.125 +        poly = 0UL;
 669.126 +        for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
 669.127 +            poly |= 1UL << (31 - p[n]);
 669.128 +
 669.129 +        /* generate a crc for every 8-bit value */
 669.130 +        for (n = 0; n < 256; n++) {
 669.131 +            c = (unsigned long)n;
 669.132 +            for (k = 0; k < 8; k++)
 669.133 +                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
 669.134 +            crc_table[0][n] = c;
 669.135 +        }
 669.136 +
 669.137 +#ifdef BYFOUR
 669.138 +        /* generate crc for each value followed by one, two, and three zeros,
 669.139 +           and then the byte reversal of those as well as the first table */
 669.140 +        for (n = 0; n < 256; n++) {
 669.141 +            c = crc_table[0][n];
 669.142 +            crc_table[4][n] = REV(c);
 669.143 +            for (k = 1; k < 4; k++) {
 669.144 +                c = crc_table[0][c & 0xff] ^ (c >> 8);
 669.145 +                crc_table[k][n] = c;
 669.146 +                crc_table[k + 4][n] = REV(c);
 669.147 +            }
 669.148 +        }
 669.149 +#endif /* BYFOUR */
 669.150 +
 669.151 +        crc_table_empty = 0;
 669.152 +    }
 669.153 +    else {      /* not first */
 669.154 +        /* wait for the other guy to finish (not efficient, but rare) */
 669.155 +        while (crc_table_empty)
 669.156 +            ;
 669.157 +    }
 669.158 +
 669.159 +#ifdef MAKECRCH
 669.160 +    /* write out CRC tables to crc32.h */
 669.161 +    {
 669.162 +        FILE *out;
 669.163 +
 669.164 +        out = fopen("crc32.h", "w");
 669.165 +        if (out == NULL) return;
 669.166 +        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
 669.167 +        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
 669.168 +        fprintf(out, "local const unsigned long FAR ");
 669.169 +        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
 669.170 +        write_table(out, crc_table[0]);
 669.171 +#  ifdef BYFOUR
 669.172 +        fprintf(out, "#ifdef BYFOUR\n");
 669.173 +        for (k = 1; k < 8; k++) {
 669.174 +            fprintf(out, "  },\n  {\n");
 669.175 +            write_table(out, crc_table[k]);
 669.176 +        }
 669.177 +        fprintf(out, "#endif\n");
 669.178 +#  endif /* BYFOUR */
 669.179 +        fprintf(out, "  }\n};\n");
 669.180 +        fclose(out);
 669.181 +    }
 669.182 +#endif /* MAKECRCH */
 669.183 +}
 669.184 +
 669.185 +#ifdef MAKECRCH
 669.186 +local void write_table(out, table)
 669.187 +    FILE *out;
 669.188 +    const unsigned long FAR *table;
 669.189 +{
 669.190 +    int n;
 669.191 +
 669.192 +    for (n = 0; n < 256; n++)
 669.193 +        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ", table[n],
 669.194 +                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
 669.195 +}
 669.196 +#endif /* MAKECRCH */
 669.197 +
 669.198 +#else /* !DYNAMIC_CRC_TABLE */
 669.199 +/* ========================================================================
 669.200 + * Tables of CRC-32s of all single-byte values, made by make_crc_table().
 669.201 + */
 669.202 +#include "crc32.h"
 669.203 +#endif /* DYNAMIC_CRC_TABLE */
 669.204 +
 669.205 +/* =========================================================================
 669.206 + * This function can be used by asm versions of crc32()
 669.207 + */
 669.208 +const unsigned long FAR * ZEXPORT get_crc_table()
 669.209 +{
 669.210 +#ifdef DYNAMIC_CRC_TABLE
 669.211 +    if (crc_table_empty)
 669.212 +        make_crc_table();
 669.213 +#endif /* DYNAMIC_CRC_TABLE */
 669.214 +    return (const unsigned long FAR *)crc_table;
 669.215 +}
 669.216 +
 669.217 +/* ========================================================================= */
 669.218 +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
 669.219 +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
 669.220 +
 669.221 +/* ========================================================================= */
 669.222 +unsigned long ZEXPORT crc32(crc, buf, len)
 669.223 +    unsigned long crc;
 669.224 +    const unsigned char FAR *buf;
 669.225 +    unsigned len;
 669.226 +{
 669.227 +    if (buf == Z_NULL) return 0UL;
 669.228 +
 669.229 +#ifdef DYNAMIC_CRC_TABLE
 669.230 +    if (crc_table_empty)
 669.231 +        make_crc_table();
 669.232 +#endif /* DYNAMIC_CRC_TABLE */
 669.233 +
 669.234 +#ifdef BYFOUR
 669.235 +    if (sizeof(void *) == sizeof(ptrdiff_t)) {
 669.236 +        u4 endian;
 669.237 +
 669.238 +        endian = 1;
 669.239 +        if (*((unsigned char *)(&endian)))
 669.240 +            return crc32_little(crc, buf, len);
 669.241 +        else
 669.242 +            return crc32_big(crc, buf, len);
 669.243 +    }
 669.244 +#endif /* BYFOUR */
 669.245 +    crc = crc ^ 0xffffffffUL;
 669.246 +    while (len >= 8) {
 669.247 +        DO8;
 669.248 +        len -= 8;
 669.249 +    }
 669.250 +    if (len) do {
 669.251 +        DO1;
 669.252 +    } while (--len);
 669.253 +    return crc ^ 0xffffffffUL;
 669.254 +}
 669.255 +
 669.256 +#ifdef BYFOUR
 669.257 +
 669.258 +/* ========================================================================= */
 669.259 +#define DOLIT4 c ^= *buf4++; \
 669.260 +        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
 669.261 +            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
 669.262 +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
 669.263 +
 669.264 +/* ========================================================================= */
 669.265 +local unsigned long crc32_little(crc, buf, len)
 669.266 +    unsigned long crc;
 669.267 +    const unsigned char FAR *buf;
 669.268 +    unsigned len;
 669.269 +{
 669.270 +    register u4 c;
 669.271 +    register const u4 FAR *buf4;
 669.272 +
 669.273 +    c = (u4)crc;
 669.274 +    c = ~c;
 669.275 +    while (len && ((ptrdiff_t)buf & 3)) {
 669.276 +        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
 669.277 +        len--;
 669.278 +    }
 669.279 +
 669.280 +    buf4 = (const u4 FAR *)(const void FAR *)buf;
 669.281 +    while (len >= 32) {
 669.282 +        DOLIT32;
 669.283 +        len -= 32;
 669.284 +    }
 669.285 +    while (len >= 4) {
 669.286 +        DOLIT4;
 669.287 +        len -= 4;
 669.288 +    }
 669.289 +    buf = (const unsigned char FAR *)buf4;
 669.290 +
 669.291 +    if (len) do {
 669.292 +        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
 669.293 +    } while (--len);
 669.294 +    c = ~c;
 669.295 +    return (unsigned long)c;
 669.296 +}
 669.297 +
 669.298 +/* ========================================================================= */
 669.299 +#define DOBIG4 c ^= *++buf4; \
 669.300 +        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
 669.301 +            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
 669.302 +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
 669.303 +
 669.304 +/* ========================================================================= */
 669.305 +local unsigned long crc32_big(crc, buf, len)
 669.306 +    unsigned long crc;
 669.307 +    const unsigned char FAR *buf;
 669.308 +    unsigned len;
 669.309 +{
 669.310 +    register u4 c;
 669.311 +    register const u4 FAR *buf4;
 669.312 +
 669.313 +    c = REV((u4)crc);
 669.314 +    c = ~c;
 669.315 +    while (len && ((ptrdiff_t)buf & 3)) {
 669.316 +        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
 669.317 +        len--;
 669.318 +    }
 669.319 +
 669.320 +    buf4 = (const u4 FAR *)(const void FAR *)buf;
 669.321 +    buf4--;
 669.322 +    while (len >= 32) {
 669.323 +        DOBIG32;
 669.324 +        len -= 32;
 669.325 +    }
 669.326 +    while (len >= 4) {
 669.327 +        DOBIG4;
 669.328 +        len -= 4;
 669.329 +    }
 669.330 +    buf4++;
 669.331 +    buf = (const unsigned char FAR *)buf4;
 669.332 +
 669.333 +    if (len) do {
 669.334 +        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
 669.335 +    } while (--len);
 669.336 +    c = ~c;
 669.337 +    return (unsigned long)(REV(c));
 669.338 +}
 669.339 +
 669.340 +#endif /* BYFOUR */
 669.341 +
 669.342 +#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
 669.343 +
 669.344 +/* ========================================================================= */
 669.345 +local unsigned long gf2_matrix_times(mat, vec)
 669.346 +    unsigned long *mat;
 669.347 +    unsigned long vec;
 669.348 +{
 669.349 +    unsigned long sum;
 669.350 +
 669.351 +    sum = 0;
 669.352 +    while (vec) {
 669.353 +        if (vec & 1)
 669.354 +            sum ^= *mat;
 669.355 +        vec >>= 1;
 669.356 +        mat++;
 669.357 +    }
 669.358 +    return sum;
 669.359 +}
 669.360 +
 669.361 +/* ========================================================================= */
 669.362 +local void gf2_matrix_square(square, mat)
 669.363 +    unsigned long *square;
 669.364 +    unsigned long *mat;
 669.365 +{
 669.366 +    int n;
 669.367 +
 669.368 +    for (n = 0; n < GF2_DIM; n++)
 669.369 +        square[n] = gf2_matrix_times(mat, mat[n]);
 669.370 +}
 669.371 +
 669.372 +/* ========================================================================= */
 669.373 +uLong ZEXPORT crc32_combine(crc1, crc2, len2)
 669.374 +    uLong crc1;
 669.375 +    uLong crc2;
 669.376 +    z_off_t len2;
 669.377 +{
 669.378 +    int n;
 669.379 +    unsigned long row;
 669.380 +    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
 669.381 +    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
 669.382 +
 669.383 +    /* degenerate case */
 669.384 +    if (len2 == 0)
 669.385 +        return crc1;
 669.386 +
 669.387 +    /* put operator for one zero bit in odd */
 669.388 +    odd[0] = 0xedb88320L;           /* CRC-32 polynomial */
 669.389 +    row = 1;
 669.390 +    for (n = 1; n < GF2_DIM; n++) {
 669.391 +        odd[n] = row;
 669.392 +        row <<= 1;
 669.393 +    }
 669.394 +
 669.395 +    /* put operator for two zero bits in even */
 669.396 +    gf2_matrix_square(even, odd);
 669.397 +
 669.398 +    /* put operator for four zero bits in odd */
 669.399 +    gf2_matrix_square(odd, even);
 669.400 +
 669.401 +    /* apply len2 zeros to crc1 (first square will put the operator for one
 669.402 +       zero byte, eight zero bits, in even) */
 669.403 +    do {
 669.404 +        /* apply zeros operator for this bit of len2 */
 669.405 +        gf2_matrix_square(even, odd);
 669.406 +        if (len2 & 1)
 669.407 +            crc1 = gf2_matrix_times(even, crc1);
 669.408 +        len2 >>= 1;
 669.409 +
 669.410 +        /* if no more bits set, then done */
 669.411 +        if (len2 == 0)
 669.412 +            break;
 669.413 +
 669.414 +        /* another iteration of the loop with odd and even swapped */
 669.415 +        gf2_matrix_square(odd, even);
 669.416 +        if (len2 & 1)
 669.417 +            crc1 = gf2_matrix_times(odd, crc1);
 669.418 +        len2 >>= 1;
 669.419 +
 669.420 +        /* if no more bits set, then done */
 669.421 +    } while (len2 != 0);
 669.422 +
 669.423 +    /* return combined crc */
 669.424 +    crc1 ^= crc2;
 669.425 +    return crc1;
 669.426 +}
   670.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   670.2 +++ b/libs/zlib/crc32.h	Sat Feb 01 19:58:19 2014 +0200
   670.3 @@ -0,0 +1,441 @@
   670.4 +/* crc32.h -- tables for rapid CRC calculation
   670.5 + * Generated automatically by crc32.c
   670.6 + */
   670.7 +
   670.8 +local const unsigned long FAR crc_table[TBLS][256] =
   670.9 +{
  670.10 +  {
  670.11 +    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
  670.12 +    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
  670.13 +    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
  670.14 +    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
  670.15 +    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
  670.16 +    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
  670.17 +    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
  670.18 +    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
  670.19 +    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
  670.20 +    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
  670.21 +    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
  670.22 +    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
  670.23 +    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
  670.24 +    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
  670.25 +    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
  670.26 +    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
  670.27 +    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
  670.28 +    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
  670.29 +    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
  670.30 +    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
  670.31 +    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
  670.32 +    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
  670.33 +    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
  670.34 +    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
  670.35 +    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
  670.36 +    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
  670.37 +    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
  670.38 +    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
  670.39 +    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
  670.40 +    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
  670.41 +    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
  670.42 +    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
  670.43 +    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
  670.44 +    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
  670.45 +    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
  670.46 +    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
  670.47 +    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
  670.48 +    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
  670.49 +    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
  670.50 +    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
  670.51 +    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
  670.52 +    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
  670.53 +    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
  670.54 +    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
  670.55 +    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
  670.56 +    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
  670.57 +    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
  670.58 +    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
  670.59 +    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
  670.60 +    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
  670.61 +    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
  670.62 +    0x2d02ef8dUL
  670.63 +#ifdef BYFOUR
  670.64 +  },
  670.65 +  {
  670.66 +    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
  670.67 +    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
  670.68 +    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
  670.69 +    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
  670.70 +    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
  670.71 +    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
  670.72 +    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
  670.73 +    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
  670.74 +    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
  670.75 +    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
  670.76 +    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
  670.77 +    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
  670.78 +    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
  670.79 +    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
  670.80 +    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
  670.81 +    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
  670.82 +    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
  670.83 +    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
  670.84 +    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
  670.85 +    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
  670.86 +    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
  670.87 +    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
  670.88 +    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
  670.89 +    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
  670.90 +    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
  670.91 +    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
  670.92 +    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
  670.93 +    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
  670.94 +    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
  670.95 +    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
  670.96 +    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
  670.97 +    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
  670.98 +    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
  670.99 +    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
 670.100 +    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
 670.101 +    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
 670.102 +    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
 670.103 +    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
 670.104 +    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
 670.105 +    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
 670.106 +    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
 670.107 +    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
 670.108 +    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
 670.109 +    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
 670.110 +    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
 670.111 +    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
 670.112 +    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
 670.113 +    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
 670.114 +    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
 670.115 +    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
 670.116 +    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
 670.117 +    0x9324fd72UL
 670.118 +  },
 670.119 +  {
 670.120 +    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
 670.121 +    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
 670.122 +    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
 670.123 +    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
 670.124 +    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
 670.125 +    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
 670.126 +    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
 670.127 +    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
 670.128 +    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
 670.129 +    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
 670.130 +    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
 670.131 +    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
 670.132 +    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
 670.133 +    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
 670.134 +    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
 670.135 +    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
 670.136 +    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
 670.137 +    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
 670.138 +    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
 670.139 +    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
 670.140 +    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
 670.141 +    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
 670.142 +    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
 670.143 +    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
 670.144 +    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
 670.145 +    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
 670.146 +    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
 670.147 +    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
 670.148 +    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
 670.149 +    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
 670.150 +    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
 670.151 +    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
 670.152 +    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
 670.153 +    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
 670.154 +    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
 670.155 +    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
 670.156 +    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
 670.157 +    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
 670.158 +    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
 670.159 +    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
 670.160 +    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
 670.161 +    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
 670.162 +    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
 670.163 +    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
 670.164 +    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
 670.165 +    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
 670.166 +    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
 670.167 +    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
 670.168 +    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
 670.169 +    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
 670.170 +    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
 670.171 +    0xbe9834edUL
 670.172 +  },
 670.173 +  {
 670.174 +    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
 670.175 +    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
 670.176 +    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
 670.177 +    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
 670.178 +    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
 670.179 +    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
 670.180 +    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
 670.181 +    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
 670.182 +    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
 670.183 +    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
 670.184 +    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
 670.185 +    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
 670.186 +    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
 670.187 +    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
 670.188 +    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
 670.189 +    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
 670.190 +    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
 670.191 +    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
 670.192 +    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
 670.193 +    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
 670.194 +    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
 670.195 +    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
 670.196 +    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
 670.197 +    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
 670.198 +    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
 670.199 +    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
 670.200 +    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
 670.201 +    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
 670.202 +    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
 670.203 +    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
 670.204 +    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
 670.205 +    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
 670.206 +    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
 670.207 +    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
 670.208 +    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
 670.209 +    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
 670.210 +    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
 670.211 +    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
 670.212 +    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
 670.213 +    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
 670.214 +    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
 670.215 +    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
 670.216 +    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
 670.217 +    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
 670.218 +    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
 670.219 +    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
 670.220 +    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
 670.221 +    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
 670.222 +    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
 670.223 +    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
 670.224 +    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
 670.225 +    0xde0506f1UL
 670.226 +  },
 670.227 +  {
 670.228 +    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
 670.229 +    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
 670.230 +    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
 670.231 +    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
 670.232 +    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
 670.233 +    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
 670.234 +    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
 670.235 +    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
 670.236 +    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
 670.237 +    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
 670.238 +    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
 670.239 +    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
 670.240 +    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
 670.241 +    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
 670.242 +    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
 670.243 +    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
 670.244 +    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
 670.245 +    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
 670.246 +    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
 670.247 +    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
 670.248 +    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
 670.249 +    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
 670.250 +    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
 670.251 +    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
 670.252 +    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
 670.253 +    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
 670.254 +    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
 670.255 +    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
 670.256 +    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
 670.257 +    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
 670.258 +    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
 670.259 +    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
 670.260 +    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
 670.261 +    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
 670.262 +    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
 670.263 +    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
 670.264 +    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
 670.265 +    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
 670.266 +    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
 670.267 +    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
 670.268 +    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
 670.269 +    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
 670.270 +    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
 670.271 +    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
 670.272 +    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
 670.273 +    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
 670.274 +    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
 670.275 +    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
 670.276 +    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
 670.277 +    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
 670.278 +    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
 670.279 +    0x8def022dUL
 670.280 +  },
 670.281 +  {
 670.282 +    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
 670.283 +    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
 670.284 +    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
 670.285 +    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
 670.286 +    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
 670.287 +    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
 670.288 +    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
 670.289 +    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
 670.290 +    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
 670.291 +    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
 670.292 +    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
 670.293 +    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
 670.294 +    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
 670.295 +    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
 670.296 +    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
 670.297 +    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
 670.298 +    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
 670.299 +    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
 670.300 +    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
 670.301 +    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
 670.302 +    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
 670.303 +    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
 670.304 +    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
 670.305 +    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
 670.306 +    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
 670.307 +    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
 670.308 +    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
 670.309 +    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
 670.310 +    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
 670.311 +    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
 670.312 +    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
 670.313 +    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
 670.314 +    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
 670.315 +    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
 670.316 +    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
 670.317 +    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
 670.318 +    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
 670.319 +    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
 670.320 +    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
 670.321 +    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
 670.322 +    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
 670.323 +    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
 670.324 +    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
 670.325 +    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
 670.326 +    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
 670.327 +    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
 670.328 +    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
 670.329 +    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
 670.330 +    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
 670.331 +    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
 670.332 +    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
 670.333 +    0x72fd2493UL
 670.334 +  },
 670.335 +  {
 670.336 +    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
 670.337 +    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
 670.338 +    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
 670.339 +    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
 670.340 +    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
 670.341 +    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
 670.342 +    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
 670.343 +    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
 670.344 +    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
 670.345 +    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
 670.346 +    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
 670.347 +    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
 670.348 +    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
 670.349 +    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
 670.350 +    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
 670.351 +    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
 670.352 +    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
 670.353 +    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
 670.354 +    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
 670.355 +    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
 670.356 +    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
 670.357 +    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
 670.358 +    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
 670.359 +    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
 670.360 +    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
 670.361 +    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
 670.362 +    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
 670.363 +    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
 670.364 +    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
 670.365 +    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
 670.366 +    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
 670.367 +    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
 670.368 +    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
 670.369 +    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
 670.370 +    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
 670.371 +    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
 670.372 +    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
 670.373 +    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
 670.374 +    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
 670.375 +    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
 670.376 +    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
 670.377 +    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
 670.378 +    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
 670.379 +    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
 670.380 +    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
 670.381 +    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
 670.382 +    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
 670.383 +    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
 670.384 +    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
 670.385 +    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
 670.386 +    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
 670.387 +    0xed3498beUL
 670.388 +  },
 670.389 +  {
 670.390 +    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
 670.391 +    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
 670.392 +    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
 670.393 +    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
 670.394 +    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
 670.395 +    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
 670.396 +    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
 670.397 +    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
 670.398 +    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
 670.399 +    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
 670.400 +    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
 670.401 +    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
 670.402 +    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
 670.403 +    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
 670.404 +    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
 670.405 +    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
 670.406 +    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
 670.407 +    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
 670.408 +    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
 670.409 +    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
 670.410 +    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
 670.411 +    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
 670.412 +    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
 670.413 +    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
 670.414 +    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
 670.415 +    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
 670.416 +    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
 670.417 +    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
 670.418 +    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
 670.419 +    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
 670.420 +    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
 670.421 +    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
 670.422 +    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
 670.423 +    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
 670.424 +    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
 670.425 +    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
 670.426 +    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
 670.427 +    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
 670.428 +    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
 670.429 +    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
 670.430 +    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
 670.431 +    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
 670.432 +    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
 670.433 +    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
 670.434 +    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
 670.435 +    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
 670.436 +    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
 670.437 +    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
 670.438 +    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
 670.439 +    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
 670.440 +    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
 670.441 +    0xf10605deUL
 670.442 +#endif
 670.443 +  }
 670.444 +};
   671.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   671.2 +++ b/libs/zlib/deflate.c	Sat Feb 01 19:58:19 2014 +0200
   671.3 @@ -0,0 +1,1736 @@
   671.4 +/* deflate.c -- compress data using the deflation algorithm
   671.5 + * Copyright (C) 1995-2005 Jean-loup Gailly.
   671.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   671.7 + */
   671.8 +
   671.9 +/*
  671.10 + *  ALGORITHM
  671.11 + *
  671.12 + *      The "deflation" process depends on being able to identify portions
  671.13 + *      of the input text which are identical to earlier input (within a
  671.14 + *      sliding window trailing behind the input currently being processed).
  671.15 + *
  671.16 + *      The most straightforward technique turns out to be the fastest for
  671.17 + *      most input files: try all possible matches and select the longest.
  671.18 + *      The key feature of this algorithm is that insertions into the string
  671.19 + *      dictionary are very simple and thus fast, and deletions are avoided
  671.20 + *      completely. Insertions are performed at each input character, whereas
  671.21 + *      string matches are performed only when the previous match ends. So it
  671.22 + *      is preferable to spend more time in matches to allow very fast string
  671.23 + *      insertions and avoid deletions. The matching algorithm for small
  671.24 + *      strings is inspired from that of Rabin & Karp. A brute force approach
  671.25 + *      is used to find longer strings when a small match has been found.
  671.26 + *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
  671.27 + *      (by Leonid Broukhis).
  671.28 + *         A previous version of this file used a more sophisticated algorithm
  671.29 + *      (by Fiala and Greene) which is guaranteed to run in linear amortized
  671.30 + *      time, but has a larger average cost, uses more memory and is patented.
  671.31 + *      However the F&G algorithm may be faster for some highly redundant
  671.32 + *      files if the parameter max_chain_length (described below) is too large.
  671.33 + *
  671.34 + *  ACKNOWLEDGEMENTS
  671.35 + *
  671.36 + *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
  671.37 + *      I found it in 'freeze' written by Leonid Broukhis.
  671.38 + *      Thanks to many people for bug reports and testing.
  671.39 + *
  671.40 + *  REFERENCES
  671.41 + *
  671.42 + *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
  671.43 + *      Available in http://www.ietf.org/rfc/rfc1951.txt
  671.44 + *
  671.45 + *      A description of the Rabin and Karp algorithm is given in the book
  671.46 + *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
  671.47 + *
  671.48 + *      Fiala,E.R., and Greene,D.H.
  671.49 + *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
  671.50 + *
  671.51 + */
  671.52 +
  671.53 +/* @(#) $Id$ */
  671.54 +
  671.55 +#include "deflate.h"
  671.56 +
  671.57 +const char deflate_copyright[] =
  671.58 +   " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
  671.59 +/*
  671.60 +  If you use the zlib library in a product, an acknowledgment is welcome
  671.61 +  in the documentation of your product. If for some reason you cannot
  671.62 +  include such an acknowledgment, I would appreciate that you keep this
  671.63 +  copyright string in the executable of your product.
  671.64 + */
  671.65 +
  671.66 +/* ===========================================================================
  671.67 + *  Function prototypes.
  671.68 + */
  671.69 +typedef enum {
  671.70 +    need_more,      /* block not completed, need more input or more output */
  671.71 +    block_done,     /* block flush performed */
  671.72 +    finish_started, /* finish started, need only more output at next deflate */
  671.73 +    finish_done     /* finish done, accept no more input or output */
  671.74 +} block_state;
  671.75 +
  671.76 +typedef block_state (*compress_func) OF((deflate_state *s, int flush));
  671.77 +/* Compression function. Returns the block state after the call. */
  671.78 +
  671.79 +local void fill_window    OF((deflate_state *s));
  671.80 +local block_state deflate_stored OF((deflate_state *s, int flush));
  671.81 +local block_state deflate_fast   OF((deflate_state *s, int flush));
  671.82 +#ifndef FASTEST
  671.83 +local block_state deflate_slow   OF((deflate_state *s, int flush));
  671.84 +#endif
  671.85 +local void lm_init        OF((deflate_state *s));
  671.86 +local void putShortMSB    OF((deflate_state *s, uInt b));
  671.87 +local void flush_pending  OF((z_streamp strm));
  671.88 +local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
  671.89 +#ifndef FASTEST
  671.90 +#ifdef ASMV
  671.91 +      void match_init OF((void)); /* asm code initialization */
  671.92 +      uInt longest_match  OF((deflate_state *s, IPos cur_match));
  671.93 +#else
  671.94 +local uInt longest_match  OF((deflate_state *s, IPos cur_match));
  671.95 +#endif
  671.96 +#endif
  671.97 +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
  671.98 +
  671.99 +#ifdef DEBUG
 671.100 +local  void check_match OF((deflate_state *s, IPos start, IPos match,
 671.101 +                            int length));
 671.102 +#endif
 671.103 +
 671.104 +/* ===========================================================================
 671.105 + * Local data
 671.106 + */
 671.107 +
 671.108 +#define NIL 0
 671.109 +/* Tail of hash chains */
 671.110 +
 671.111 +#ifndef TOO_FAR
 671.112 +#  define TOO_FAR 4096
 671.113 +#endif
 671.114 +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
 671.115 +
 671.116 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
 671.117 +/* Minimum amount of lookahead, except at the end of the input file.
 671.118 + * See deflate.c for comments about the MIN_MATCH+1.
 671.119 + */
 671.120 +
 671.121 +/* Values for max_lazy_match, good_match and max_chain_length, depending on
 671.122 + * the desired pack level (0..9). The values given below have been tuned to
 671.123 + * exclude worst case performance for pathological files. Better values may be
 671.124 + * found for specific files.
 671.125 + */
 671.126 +typedef struct config_s {
 671.127 +   ush good_length; /* reduce lazy search above this match length */
 671.128 +   ush max_lazy;    /* do not perform lazy search above this match length */
 671.129 +   ush nice_length; /* quit search above this match length */
 671.130 +   ush max_chain;
 671.131 +   compress_func func;
 671.132 +} config;
 671.133 +
 671.134 +#ifdef FASTEST
 671.135 +local const config configuration_table[2] = {
 671.136 +/*      good lazy nice chain */
 671.137 +/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
 671.138 +/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
 671.139 +#else
 671.140 +local const config configuration_table[10] = {
 671.141 +/*      good lazy nice chain */
 671.142 +/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
 671.143 +/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
 671.144 +/* 2 */ {4,    5, 16,    8, deflate_fast},
 671.145 +/* 3 */ {4,    6, 32,   32, deflate_fast},
 671.146 +
 671.147 +/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
 671.148 +/* 5 */ {8,   16, 32,   32, deflate_slow},
 671.149 +/* 6 */ {8,   16, 128, 128, deflate_slow},
 671.150 +/* 7 */ {8,   32, 128, 256, deflate_slow},
 671.151 +/* 8 */ {32, 128, 258, 1024, deflate_slow},
 671.152 +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
 671.153 +#endif
 671.154 +
 671.155 +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
 671.156 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
 671.157 + * meaning.
 671.158 + */
 671.159 +
 671.160 +#define EQUAL 0
 671.161 +/* result of memcmp for equal strings */
 671.162 +
 671.163 +#ifndef NO_DUMMY_DECL
 671.164 +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
 671.165 +#endif
 671.166 +
 671.167 +/* ===========================================================================
 671.168 + * Update a hash value with the given input byte
 671.169 + * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
 671.170 + *    input characters, so that a running hash key can be computed from the
 671.171 + *    previous key instead of complete recalculation each time.
 671.172 + */
 671.173 +#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
 671.174 +
 671.175 +
 671.176 +/* ===========================================================================
 671.177 + * Insert string str in the dictionary and set match_head to the previous head
 671.178 + * of the hash chain (the most recent string with same hash key). Return
 671.179 + * the previous length of the hash chain.
 671.180 + * If this file is compiled with -DFASTEST, the compression level is forced
 671.181 + * to 1, and no hash chains are maintained.
 671.182 + * IN  assertion: all calls to to INSERT_STRING are made with consecutive
 671.183 + *    input characters and the first MIN_MATCH bytes of str are valid
 671.184 + *    (except for the last MIN_MATCH-1 bytes of the input file).
 671.185 + */
 671.186 +#ifdef FASTEST
 671.187 +#define INSERT_STRING(s, str, match_head) \
 671.188 +   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
 671.189 +    match_head = s->head[s->ins_h], \
 671.190 +    s->head[s->ins_h] = (Pos)(str))
 671.191 +#else
 671.192 +#define INSERT_STRING(s, str, match_head) \
 671.193 +   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
 671.194 +    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
 671.195 +    s->head[s->ins_h] = (Pos)(str))
 671.196 +#endif
 671.197 +
 671.198 +/* ===========================================================================
 671.199 + * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
 671.200 + * prev[] will be initialized on the fly.
 671.201 + */
 671.202 +#define CLEAR_HASH(s) \
 671.203 +    s->head[s->hash_size-1] = NIL; \
 671.204 +    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
 671.205 +
 671.206 +/* ========================================================================= */
 671.207 +int ZEXPORT deflateInit_(strm, level, version, stream_size)
 671.208 +    z_streamp strm;
 671.209 +    int level;
 671.210 +    const char *version;
 671.211 +    int stream_size;
 671.212 +{
 671.213 +    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
 671.214 +                         Z_DEFAULT_STRATEGY, version, stream_size);
 671.215 +    /* To do: ignore strm->next_in if we use it as window */
 671.216 +}
 671.217 +
 671.218 +/* ========================================================================= */
 671.219 +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
 671.220 +                  version, stream_size)
 671.221 +    z_streamp strm;
 671.222 +    int  level;
 671.223 +    int  method;
 671.224 +    int  windowBits;
 671.225 +    int  memLevel;
 671.226 +    int  strategy;
 671.227 +    const char *version;
 671.228 +    int stream_size;
 671.229 +{
 671.230 +    deflate_state *s;
 671.231 +    int wrap = 1;
 671.232 +    static const char my_version[] = ZLIB_VERSION;
 671.233 +
 671.234 +    ushf *overlay;
 671.235 +    /* We overlay pending_buf and d_buf+l_buf. This works since the average
 671.236 +     * output size for (length,distance) codes is <= 24 bits.
 671.237 +     */
 671.238 +
 671.239 +    if (version == Z_NULL || version[0] != my_version[0] ||
 671.240 +        stream_size != sizeof(z_stream)) {
 671.241 +        return Z_VERSION_ERROR;
 671.242 +    }
 671.243 +    if (strm == Z_NULL) return Z_STREAM_ERROR;
 671.244 +
 671.245 +    strm->msg = Z_NULL;
 671.246 +    if (strm->zalloc == (alloc_func)0) {
 671.247 +        strm->zalloc = zcalloc;
 671.248 +        strm->opaque = (voidpf)0;
 671.249 +    }
 671.250 +    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
 671.251 +
 671.252 +#ifdef FASTEST
 671.253 +    if (level != 0) level = 1;
 671.254 +#else
 671.255 +    if (level == Z_DEFAULT_COMPRESSION) level = 6;
 671.256 +#endif
 671.257 +
 671.258 +    if (windowBits < 0) { /* suppress zlib wrapper */
 671.259 +        wrap = 0;
 671.260 +        windowBits = -windowBits;
 671.261 +    }
 671.262 +#ifdef GZIP
 671.263 +    else if (windowBits > 15) {
 671.264 +        wrap = 2;       /* write gzip wrapper instead */
 671.265 +        windowBits -= 16;
 671.266 +    }
 671.267 +#endif
 671.268 +    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
 671.269 +        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
 671.270 +        strategy < 0 || strategy > Z_FIXED) {
 671.271 +        return Z_STREAM_ERROR;
 671.272 +    }
 671.273 +    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
 671.274 +    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
 671.275 +    if (s == Z_NULL) return Z_MEM_ERROR;
 671.276 +    strm->state = (struct internal_state FAR *)s;
 671.277 +    s->strm = strm;
 671.278 +
 671.279 +    s->wrap = wrap;
 671.280 +    s->gzhead = Z_NULL;
 671.281 +    s->w_bits = windowBits;
 671.282 +    s->w_size = 1 << s->w_bits;
 671.283 +    s->w_mask = s->w_size - 1;
 671.284 +
 671.285 +    s->hash_bits = memLevel + 7;
 671.286 +    s->hash_size = 1 << s->hash_bits;
 671.287 +    s->hash_mask = s->hash_size - 1;
 671.288 +    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
 671.289 +
 671.290 +    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
 671.291 +    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
 671.292 +    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
 671.293 +
 671.294 +    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
 671.295 +
 671.296 +    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
 671.297 +    s->pending_buf = (uchf *) overlay;
 671.298 +    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
 671.299 +
 671.300 +    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
 671.301 +        s->pending_buf == Z_NULL) {
 671.302 +        s->status = FINISH_STATE;
 671.303 +        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
 671.304 +        deflateEnd (strm);
 671.305 +        return Z_MEM_ERROR;
 671.306 +    }
 671.307 +    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
 671.308 +    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
 671.309 +
 671.310 +    s->level = level;
 671.311 +    s->strategy = strategy;
 671.312 +    s->method = (Byte)method;
 671.313 +
 671.314 +    return deflateReset(strm);
 671.315 +}
 671.316 +
 671.317 +/* ========================================================================= */
 671.318 +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
 671.319 +    z_streamp strm;
 671.320 +    const Bytef *dictionary;
 671.321 +    uInt  dictLength;
 671.322 +{
 671.323 +    deflate_state *s;
 671.324 +    uInt length = dictLength;
 671.325 +    uInt n;
 671.326 +    IPos hash_head = 0;
 671.327 +
 671.328 +    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
 671.329 +        strm->state->wrap == 2 ||
 671.330 +        (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
 671.331 +        return Z_STREAM_ERROR;
 671.332 +
 671.333 +    s = strm->state;
 671.334 +    if (s->wrap)
 671.335 +        strm->adler = adler32(strm->adler, dictionary, dictLength);
 671.336 +
 671.337 +    if (length < MIN_MATCH) return Z_OK;
 671.338 +    if (length > MAX_DIST(s)) {
 671.339 +        length = MAX_DIST(s);
 671.340 +        dictionary += dictLength - length; /* use the tail of the dictionary */
 671.341 +    }
 671.342 +    zmemcpy(s->window, dictionary, length);
 671.343 +    s->strstart = length;
 671.344 +    s->block_start = (long)length;
 671.345 +
 671.346 +    /* Insert all strings in the hash table (except for the last two bytes).
 671.347 +     * s->lookahead stays null, so s->ins_h will be recomputed at the next
 671.348 +     * call of fill_window.
 671.349 +     */
 671.350 +    s->ins_h = s->window[0];
 671.351 +    UPDATE_HASH(s, s->ins_h, s->window[1]);
 671.352 +    for (n = 0; n <= length - MIN_MATCH; n++) {
 671.353 +        INSERT_STRING(s, n, hash_head);
 671.354 +    }
 671.355 +    if (hash_head) hash_head = 0;  /* to make compiler happy */
 671.356 +    return Z_OK;
 671.357 +}
 671.358 +
 671.359 +/* ========================================================================= */
 671.360 +int ZEXPORT deflateReset (strm)
 671.361 +    z_streamp strm;
 671.362 +{
 671.363 +    deflate_state *s;
 671.364 +
 671.365 +    if (strm == Z_NULL || strm->state == Z_NULL ||
 671.366 +        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
 671.367 +        return Z_STREAM_ERROR;
 671.368 +    }
 671.369 +
 671.370 +    strm->total_in = strm->total_out = 0;
 671.371 +    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
 671.372 +    strm->data_type = Z_UNKNOWN;
 671.373 +
 671.374 +    s = (deflate_state *)strm->state;
 671.375 +    s->pending = 0;
 671.376 +    s->pending_out = s->pending_buf;
 671.377 +
 671.378 +    if (s->wrap < 0) {
 671.379 +        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
 671.380 +    }
 671.381 +    s->status = s->wrap ? INIT_STATE : BUSY_STATE;
 671.382 +    strm->adler =
 671.383 +#ifdef GZIP
 671.384 +        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
 671.385 +#endif
 671.386 +        adler32(0L, Z_NULL, 0);
 671.387 +    s->last_flush = Z_NO_FLUSH;
 671.388 +
 671.389 +    _tr_init(s);
 671.390 +    lm_init(s);
 671.391 +
 671.392 +    return Z_OK;
 671.393 +}
 671.394 +
 671.395 +/* ========================================================================= */
 671.396 +int ZEXPORT deflateSetHeader (strm, head)
 671.397 +    z_streamp strm;
 671.398 +    gz_headerp head;
 671.399 +{
 671.400 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
 671.401 +    if (strm->state->wrap != 2) return Z_STREAM_ERROR;
 671.402 +    strm->state->gzhead = head;
 671.403 +    return Z_OK;
 671.404 +}
 671.405 +
 671.406 +/* ========================================================================= */
 671.407 +int ZEXPORT deflatePrime (strm, bits, value)
 671.408 +    z_streamp strm;
 671.409 +    int bits;
 671.410 +    int value;
 671.411 +{
 671.412 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
 671.413 +    strm->state->bi_valid = bits;
 671.414 +    strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
 671.415 +    return Z_OK;
 671.416 +}
 671.417 +
 671.418 +/* ========================================================================= */
 671.419 +int ZEXPORT deflateParams(strm, level, strategy)
 671.420 +    z_streamp strm;
 671.421 +    int level;
 671.422 +    int strategy;
 671.423 +{
 671.424 +    deflate_state *s;
 671.425 +    compress_func func;
 671.426 +    int err = Z_OK;
 671.427 +
 671.428 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
 671.429 +    s = strm->state;
 671.430 +
 671.431 +#ifdef FASTEST
 671.432 +    if (level != 0) level = 1;
 671.433 +#else
 671.434 +    if (level == Z_DEFAULT_COMPRESSION) level = 6;
 671.435 +#endif
 671.436 +    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
 671.437 +        return Z_STREAM_ERROR;
 671.438 +    }
 671.439 +    func = configuration_table[s->level].func;
 671.440 +
 671.441 +    if (func != configuration_table[level].func && strm->total_in != 0) {
 671.442 +        /* Flush the last buffer: */
 671.443 +        err = deflate(strm, Z_PARTIAL_FLUSH);
 671.444 +    }
 671.445 +    if (s->level != level) {
 671.446 +        s->level = level;
 671.447 +        s->max_lazy_match   = configuration_table[level].max_lazy;
 671.448 +        s->good_match       = configuration_table[level].good_length;
 671.449 +        s->nice_match       = configuration_table[level].nice_length;
 671.450 +        s->max_chain_length = configuration_table[level].max_chain;
 671.451 +    }
 671.452 +    s->strategy = strategy;
 671.453 +    return err;
 671.454 +}
 671.455 +
 671.456 +/* ========================================================================= */
 671.457 +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
 671.458 +    z_streamp strm;
 671.459 +    int good_length;
 671.460 +    int max_lazy;
 671.461 +    int nice_length;
 671.462 +    int max_chain;
 671.463 +{
 671.464 +    deflate_state *s;
 671.465 +
 671.466 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
 671.467 +    s = strm->state;
 671.468 +    s->good_match = good_length;
 671.469 +    s->max_lazy_match = max_lazy;
 671.470 +    s->nice_match = nice_length;
 671.471 +    s->max_chain_length = max_chain;
 671.472 +    return Z_OK;
 671.473 +}
 671.474 +
 671.475 +/* =========================================================================
 671.476 + * For the default windowBits of 15 and memLevel of 8, this function returns
 671.477 + * a close to exact, as well as small, upper bound on the compressed size.
 671.478 + * They are coded as constants here for a reason--if the #define's are
 671.479 + * changed, then this function needs to be changed as well.  The return
 671.480 + * value for 15 and 8 only works for those exact settings.
 671.481 + *
 671.482 + * For any setting other than those defaults for windowBits and memLevel,
 671.483 + * the value returned is a conservative worst case for the maximum expansion
 671.484 + * resulting from using fixed blocks instead of stored blocks, which deflate
 671.485 + * can emit on compressed data for some combinations of the parameters.
 671.486 + *
 671.487 + * This function could be more sophisticated to provide closer upper bounds
 671.488 + * for every combination of windowBits and memLevel, as well as wrap.
 671.489 + * But even the conservative upper bound of about 14% expansion does not
 671.490 + * seem onerous for output buffer allocation.
 671.491 + */
 671.492 +uLong ZEXPORT deflateBound(strm, sourceLen)
 671.493 +    z_streamp strm;
 671.494 +    uLong sourceLen;
 671.495 +{
 671.496 +    deflate_state *s;
 671.497 +    uLong destLen;
 671.498 +
 671.499 +    /* conservative upper bound */
 671.500 +    destLen = sourceLen +
 671.501 +              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
 671.502 +
 671.503 +    /* if can't get parameters, return conservative bound */
 671.504 +    if (strm == Z_NULL || strm->state == Z_NULL)
 671.505 +        return destLen;
 671.506 +
 671.507 +    /* if not default parameters, return conservative bound */
 671.508 +    s = strm->state;
 671.509 +    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
 671.510 +        return destLen;
 671.511 +
 671.512 +    /* default settings: return tight bound for that case */
 671.513 +    return compressBound(sourceLen);
 671.514 +}
 671.515 +
 671.516 +/* =========================================================================
 671.517 + * Put a short in the pending buffer. The 16-bit value is put in MSB order.
 671.518 + * IN assertion: the stream state is correct and there is enough room in
 671.519 + * pending_buf.
 671.520 + */
 671.521 +local void putShortMSB (s, b)
 671.522 +    deflate_state *s;
 671.523 +    uInt b;
 671.524 +{
 671.525 +    put_byte(s, (Byte)(b >> 8));
 671.526 +    put_byte(s, (Byte)(b & 0xff));
 671.527 +}
 671.528 +
 671.529 +/* =========================================================================
 671.530 + * Flush as much pending output as possible. All deflate() output goes
 671.531 + * through this function so some applications may wish to modify it
 671.532 + * to avoid allocating a large strm->next_out buffer and copying into it.
 671.533 + * (See also read_buf()).
 671.534 + */
 671.535 +local void flush_pending(strm)
 671.536 +    z_streamp strm;
 671.537 +{
 671.538 +    unsigned len = strm->state->pending;
 671.539 +
 671.540 +    if (len > strm->avail_out) len = strm->avail_out;
 671.541 +    if (len == 0) return;
 671.542 +
 671.543 +    zmemcpy(strm->next_out, strm->state->pending_out, len);
 671.544 +    strm->next_out  += len;
 671.545 +    strm->state->pending_out  += len;
 671.546 +    strm->total_out += len;
 671.547 +    strm->avail_out  -= len;
 671.548 +    strm->state->pending -= len;
 671.549 +    if (strm->state->pending == 0) {
 671.550 +        strm->state->pending_out = strm->state->pending_buf;
 671.551 +    }
 671.552 +}
 671.553 +
 671.554 +/* ========================================================================= */
 671.555 +int ZEXPORT deflate (strm, flush)
 671.556 +    z_streamp strm;
 671.557 +    int flush;
 671.558 +{
 671.559 +    int old_flush; /* value of flush param for previous deflate call */
 671.560 +    deflate_state *s;
 671.561 +
 671.562 +    if (strm == Z_NULL || strm->state == Z_NULL ||
 671.563 +        flush > Z_FINISH || flush < 0) {
 671.564 +        return Z_STREAM_ERROR;
 671.565 +    }
 671.566 +    s = strm->state;
 671.567 +
 671.568 +    if (strm->next_out == Z_NULL ||
 671.569 +        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
 671.570 +        (s->status == FINISH_STATE && flush != Z_FINISH)) {
 671.571 +        ERR_RETURN(strm, Z_STREAM_ERROR);
 671.572 +    }
 671.573 +    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
 671.574 +
 671.575 +    s->strm = strm; /* just in case */
 671.576 +    old_flush = s->last_flush;
 671.577 +    s->last_flush = flush;
 671.578 +
 671.579 +    /* Write the header */
 671.580 +    if (s->status == INIT_STATE) {
 671.581 +#ifdef GZIP
 671.582 +        if (s->wrap == 2) {
 671.583 +            strm->adler = crc32(0L, Z_NULL, 0);
 671.584 +            put_byte(s, 31);
 671.585 +            put_byte(s, 139);
 671.586 +            put_byte(s, 8);
 671.587 +            if (s->gzhead == NULL) {
 671.588 +                put_byte(s, 0);
 671.589 +                put_byte(s, 0);
 671.590 +                put_byte(s, 0);
 671.591 +                put_byte(s, 0);
 671.592 +                put_byte(s, 0);
 671.593 +                put_byte(s, s->level == 9 ? 2 :
 671.594 +                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
 671.595 +                             4 : 0));
 671.596 +                put_byte(s, OS_CODE);
 671.597 +                s->status = BUSY_STATE;
 671.598 +            }
 671.599 +            else {
 671.600 +                put_byte(s, (s->gzhead->text ? 1 : 0) +
 671.601 +                            (s->gzhead->hcrc ? 2 : 0) +
 671.602 +                            (s->gzhead->extra == Z_NULL ? 0 : 4) +
 671.603 +                            (s->gzhead->name == Z_NULL ? 0 : 8) +
 671.604 +                            (s->gzhead->comment == Z_NULL ? 0 : 16)
 671.605 +                        );
 671.606 +                put_byte(s, (Byte)(s->gzhead->time & 0xff));
 671.607 +                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
 671.608 +                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
 671.609 +                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
 671.610 +                put_byte(s, s->level == 9 ? 2 :
 671.611 +                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
 671.612 +                             4 : 0));
 671.613 +                put_byte(s, s->gzhead->os & 0xff);
 671.614 +                if (s->gzhead->extra != NULL) {
 671.615 +                    put_byte(s, s->gzhead->extra_len & 0xff);
 671.616 +                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
 671.617 +                }
 671.618 +                if (s->gzhead->hcrc)
 671.619 +                    strm->adler = crc32(strm->adler, s->pending_buf,
 671.620 +                                        s->pending);
 671.621 +                s->gzindex = 0;
 671.622 +                s->status = EXTRA_STATE;
 671.623 +            }
 671.624 +        }
 671.625 +        else
 671.626 +#endif
 671.627 +        {
 671.628 +            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
 671.629 +            uInt level_flags;
 671.630 +
 671.631 +            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
 671.632 +                level_flags = 0;
 671.633 +            else if (s->level < 6)
 671.634 +                level_flags = 1;
 671.635 +            else if (s->level == 6)
 671.636 +                level_flags = 2;
 671.637 +            else
 671.638 +                level_flags = 3;
 671.639 +            header |= (level_flags << 6);
 671.640 +            if (s->strstart != 0) header |= PRESET_DICT;
 671.641 +            header += 31 - (header % 31);
 671.642 +
 671.643 +            s->status = BUSY_STATE;
 671.644 +            putShortMSB(s, header);
 671.645 +
 671.646 +            /* Save the adler32 of the preset dictionary: */
 671.647 +            if (s->strstart != 0) {
 671.648 +                putShortMSB(s, (uInt)(strm->adler >> 16));
 671.649 +                putShortMSB(s, (uInt)(strm->adler & 0xffff));
 671.650 +            }
 671.651 +            strm->adler = adler32(0L, Z_NULL, 0);
 671.652 +        }
 671.653 +    }
 671.654 +#ifdef GZIP
 671.655 +    if (s->status == EXTRA_STATE) {
 671.656 +        if (s->gzhead->extra != NULL) {
 671.657 +            uInt beg = s->pending;  /* start of bytes to update crc */
 671.658 +
 671.659 +            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
 671.660 +                if (s->pending == s->pending_buf_size) {
 671.661 +                    if (s->gzhead->hcrc && s->pending > beg)
 671.662 +                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
 671.663 +                                            s->pending - beg);
 671.664 +                    flush_pending(strm);
 671.665 +                    beg = s->pending;
 671.666 +                    if (s->pending == s->pending_buf_size)
 671.667 +                        break;
 671.668 +                }
 671.669 +                put_byte(s, s->gzhead->extra[s->gzindex]);
 671.670 +                s->gzindex++;
 671.671 +            }
 671.672 +            if (s->gzhead->hcrc && s->pending > beg)
 671.673 +                strm->adler = crc32(strm->adler, s->pending_buf + beg,
 671.674 +                                    s->pending - beg);
 671.675 +            if (s->gzindex == s->gzhead->extra_len) {
 671.676 +                s->gzindex = 0;
 671.677 +                s->status = NAME_STATE;
 671.678 +            }
 671.679 +        }
 671.680 +        else
 671.681 +            s->status = NAME_STATE;
 671.682 +    }
 671.683 +    if (s->status == NAME_STATE) {
 671.684 +        if (s->gzhead->name != NULL) {
 671.685 +            uInt beg = s->pending;  /* start of bytes to update crc */
 671.686 +            int val;
 671.687 +
 671.688 +            do {
 671.689 +                if (s->pending == s->pending_buf_size) {
 671.690 +                    if (s->gzhead->hcrc && s->pending > beg)
 671.691 +                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
 671.692 +                                            s->pending - beg);
 671.693 +                    flush_pending(strm);
 671.694 +                    beg = s->pending;
 671.695 +                    if (s->pending == s->pending_buf_size) {
 671.696 +                        val = 1;
 671.697 +                        break;
 671.698 +                    }
 671.699 +                }
 671.700 +                val = s->gzhead->name[s->gzindex++];
 671.701 +                put_byte(s, val);
 671.702 +            } while (val != 0);
 671.703 +            if (s->gzhead->hcrc && s->pending > beg)
 671.704 +                strm->adler = crc32(strm->adler, s->pending_buf + beg,
 671.705 +                                    s->pending - beg);
 671.706 +            if (val == 0) {
 671.707 +                s->gzindex = 0;
 671.708 +                s->status = COMMENT_STATE;
 671.709 +            }
 671.710 +        }
 671.711 +        else
 671.712 +            s->status = COMMENT_STATE;
 671.713 +    }
 671.714 +    if (s->status == COMMENT_STATE) {
 671.715 +        if (s->gzhead->comment != NULL) {
 671.716 +            uInt beg = s->pending;  /* start of bytes to update crc */
 671.717 +            int val;
 671.718 +
 671.719 +            do {
 671.720 +                if (s->pending == s->pending_buf_size) {
 671.721 +                    if (s->gzhead->hcrc && s->pending > beg)
 671.722 +                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
 671.723 +                                            s->pending - beg);
 671.724 +                    flush_pending(strm);
 671.725 +                    beg = s->pending;
 671.726 +                    if (s->pending == s->pending_buf_size) {
 671.727 +                        val = 1;
 671.728 +                        break;
 671.729 +                    }
 671.730 +                }
 671.731 +                val = s->gzhead->comment[s->gzindex++];
 671.732 +                put_byte(s, val);
 671.733 +            } while (val != 0);
 671.734 +            if (s->gzhead->hcrc && s->pending > beg)
 671.735 +                strm->adler = crc32(strm->adler, s->pending_buf + beg,
 671.736 +                                    s->pending - beg);
 671.737 +            if (val == 0)
 671.738 +                s->status = HCRC_STATE;
 671.739 +        }
 671.740 +        else
 671.741 +            s->status = HCRC_STATE;
 671.742 +    }
 671.743 +    if (s->status == HCRC_STATE) {
 671.744 +        if (s->gzhead->hcrc) {
 671.745 +            if (s->pending + 2 > s->pending_buf_size)
 671.746 +                flush_pending(strm);
 671.747 +            if (s->pending + 2 <= s->pending_buf_size) {
 671.748 +                put_byte(s, (Byte)(strm->adler & 0xff));
 671.749 +                put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
 671.750 +                strm->adler = crc32(0L, Z_NULL, 0);
 671.751 +                s->status = BUSY_STATE;
 671.752 +            }
 671.753 +        }
 671.754 +        else
 671.755 +            s->status = BUSY_STATE;
 671.756 +    }
 671.757 +#endif
 671.758 +
 671.759 +    /* Flush as much pending output as possible */
 671.760 +    if (s->pending != 0) {
 671.761 +        flush_pending(strm);
 671.762 +        if (strm->avail_out == 0) {
 671.763 +            /* Since avail_out is 0, deflate will be called again with
 671.764 +             * more output space, but possibly with both pending and
 671.765 +             * avail_in equal to zero. There won't be anything to do,
 671.766 +             * but this is not an error situation so make sure we
 671.767 +             * return OK instead of BUF_ERROR at next call of deflate:
 671.768 +             */
 671.769 +            s->last_flush = -1;
 671.770 +            return Z_OK;
 671.771 +        }
 671.772 +
 671.773 +    /* Make sure there is something to do and avoid duplicate consecutive
 671.774 +     * flushes. For repeated and useless calls with Z_FINISH, we keep
 671.775 +     * returning Z_STREAM_END instead of Z_BUF_ERROR.
 671.776 +     */
 671.777 +    } else if (strm->avail_in == 0 && flush <= old_flush &&
 671.778 +               flush != Z_FINISH) {
 671.779 +        ERR_RETURN(strm, Z_BUF_ERROR);
 671.780 +    }
 671.781 +
 671.782 +    /* User must not provide more input after the first FINISH: */
 671.783 +    if (s->status == FINISH_STATE && strm->avail_in != 0) {
 671.784 +        ERR_RETURN(strm, Z_BUF_ERROR);
 671.785 +    }
 671.786 +
 671.787 +    /* Start a new block or continue the current one.
 671.788 +     */
 671.789 +    if (strm->avail_in != 0 || s->lookahead != 0 ||
 671.790 +        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
 671.791 +        block_state bstate;
 671.792 +
 671.793 +        bstate = (*(configuration_table[s->level].func))(s, flush);
 671.794 +
 671.795 +        if (bstate == finish_started || bstate == finish_done) {
 671.796 +            s->status = FINISH_STATE;
 671.797 +        }
 671.798 +        if (bstate == need_more || bstate == finish_started) {
 671.799 +            if (strm->avail_out == 0) {
 671.800 +                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
 671.801 +            }
 671.802 +            return Z_OK;
 671.803 +            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
 671.804 +             * of deflate should use the same flush parameter to make sure
 671.805 +             * that the flush is complete. So we don't have to output an
 671.806 +             * empty block here, this will be done at next call. This also
 671.807 +             * ensures that for a very small output buffer, we emit at most
 671.808 +             * one empty block.
 671.809 +             */
 671.810 +        }
 671.811 +        if (bstate == block_done) {
 671.812 +            if (flush == Z_PARTIAL_FLUSH) {
 671.813 +                _tr_align(s);
 671.814 +            } else { /* FULL_FLUSH or SYNC_FLUSH */
 671.815 +                _tr_stored_block(s, (char*)0, 0L, 0);
 671.816 +                /* For a full flush, this empty block will be recognized
 671.817 +                 * as a special marker by inflate_sync().
 671.818 +                 */
 671.819 +                if (flush == Z_FULL_FLUSH) {
 671.820 +                    CLEAR_HASH(s);             /* forget history */
 671.821 +                }
 671.822 +            }
 671.823 +            flush_pending(strm);
 671.824 +            if (strm->avail_out == 0) {
 671.825 +              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
 671.826 +              return Z_OK;
 671.827 +            }
 671.828 +        }
 671.829 +    }
 671.830 +    Assert(strm->avail_out > 0, "bug2");
 671.831 +
 671.832 +    if (flush != Z_FINISH) return Z_OK;
 671.833 +    if (s->wrap <= 0) return Z_STREAM_END;
 671.834 +
 671.835 +    /* Write the trailer */
 671.836 +#ifdef GZIP
 671.837 +    if (s->wrap == 2) {
 671.838 +        put_byte(s, (Byte)(strm->adler & 0xff));
 671.839 +        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
 671.840 +        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
 671.841 +        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
 671.842 +        put_byte(s, (Byte)(strm->total_in & 0xff));
 671.843 +        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
 671.844 +        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
 671.845 +        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
 671.846 +    }
 671.847 +    else
 671.848 +#endif
 671.849 +    {
 671.850 +        putShortMSB(s, (uInt)(strm->adler >> 16));
 671.851 +        putShortMSB(s, (uInt)(strm->adler & 0xffff));
 671.852 +    }
 671.853 +    flush_pending(strm);
 671.854 +    /* If avail_out is zero, the application will call deflate again
 671.855 +     * to flush the rest.
 671.856 +     */
 671.857 +    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
 671.858 +    return s->pending != 0 ? Z_OK : Z_STREAM_END;
 671.859 +}
 671.860 +
 671.861 +/* ========================================================================= */
 671.862 +int ZEXPORT deflateEnd (strm)
 671.863 +    z_streamp strm;
 671.864 +{
 671.865 +    int status;
 671.866 +
 671.867 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
 671.868 +
 671.869 +    status = strm->state->status;
 671.870 +    if (status != INIT_STATE &&
 671.871 +        status != EXTRA_STATE &&
 671.872 +        status != NAME_STATE &&
 671.873 +        status != COMMENT_STATE &&
 671.874 +        status != HCRC_STATE &&
 671.875 +        status != BUSY_STATE &&
 671.876 +        status != FINISH_STATE) {
 671.877 +      return Z_STREAM_ERROR;
 671.878 +    }
 671.879 +
 671.880 +    /* Deallocate in reverse order of allocations: */
 671.881 +    TRY_FREE(strm, strm->state->pending_buf);
 671.882 +    TRY_FREE(strm, strm->state->head);
 671.883 +    TRY_FREE(strm, strm->state->prev);
 671.884 +    TRY_FREE(strm, strm->state->window);
 671.885 +
 671.886 +    ZFREE(strm, strm->state);
 671.887 +    strm->state = Z_NULL;
 671.888 +
 671.889 +    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
 671.890 +}
 671.891 +
 671.892 +/* =========================================================================
 671.893 + * Copy the source state to the destination state.
 671.894 + * To simplify the source, this is not supported for 16-bit MSDOS (which
 671.895 + * doesn't have enough memory anyway to duplicate compression states).
 671.896 + */
 671.897 +int ZEXPORT deflateCopy (dest, source)
 671.898 +    z_streamp dest;
 671.899 +    z_streamp source;
 671.900 +{
 671.901 +#ifdef MAXSEG_64K
 671.902 +    return Z_STREAM_ERROR;
 671.903 +#else
 671.904 +    deflate_state *ds;
 671.905 +    deflate_state *ss;
 671.906 +    ushf *overlay;
 671.907 +
 671.908 +
 671.909 +    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
 671.910 +        return Z_STREAM_ERROR;
 671.911 +    }
 671.912 +
 671.913 +    ss = source->state;
 671.914 +
 671.915 +    zmemcpy(dest, source, sizeof(z_stream));
 671.916 +
 671.917 +    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
 671.918 +    if (ds == Z_NULL) return Z_MEM_ERROR;
 671.919 +    dest->state = (struct internal_state FAR *) ds;
 671.920 +    zmemcpy(ds, ss, sizeof(deflate_state));
 671.921 +    ds->strm = dest;
 671.922 +
 671.923 +    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
 671.924 +    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
 671.925 +    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
 671.926 +    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
 671.927 +    ds->pending_buf = (uchf *) overlay;
 671.928 +
 671.929 +    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
 671.930 +        ds->pending_buf == Z_NULL) {
 671.931 +        deflateEnd (dest);
 671.932 +        return Z_MEM_ERROR;
 671.933 +    }
 671.934 +    /* following zmemcpy do not work for 16-bit MSDOS */
 671.935 +    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
 671.936 +    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
 671.937 +    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
 671.938 +    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
 671.939 +
 671.940 +    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
 671.941 +    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
 671.942 +    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
 671.943 +
 671.944 +    ds->l_desc.dyn_tree = ds->dyn_ltree;
 671.945 +    ds->d_desc.dyn_tree = ds->dyn_dtree;
 671.946 +    ds->bl_desc.dyn_tree = ds->bl_tree;
 671.947 +
 671.948 +    return Z_OK;
 671.949 +#endif /* MAXSEG_64K */
 671.950 +}
 671.951 +
 671.952 +/* ===========================================================================
 671.953 + * Read a new buffer from the current input stream, update the adler32
 671.954 + * and total number of bytes read.  All deflate() input goes through
 671.955 + * this function so some applications may wish to modify it to avoid
 671.956 + * allocating a large strm->next_in buffer and copying from it.
 671.957 + * (See also flush_pending()).
 671.958 + */
 671.959 +local int read_buf(strm, buf, size)
 671.960 +    z_streamp strm;
 671.961 +    Bytef *buf;
 671.962 +    unsigned size;
 671.963 +{
 671.964 +    unsigned len = strm->avail_in;
 671.965 +
 671.966 +    if (len > size) len = size;
 671.967 +    if (len == 0) return 0;
 671.968 +
 671.969 +    strm->avail_in  -= len;
 671.970 +
 671.971 +    if (strm->state->wrap == 1) {
 671.972 +        strm->adler = adler32(strm->adler, strm->next_in, len);
 671.973 +    }
 671.974 +#ifdef GZIP
 671.975 +    else if (strm->state->wrap == 2) {
 671.976 +        strm->adler = crc32(strm->adler, strm->next_in, len);
 671.977 +    }
 671.978 +#endif
 671.979 +    zmemcpy(buf, strm->next_in, len);
 671.980 +    strm->next_in  += len;
 671.981 +    strm->total_in += len;
 671.982 +
 671.983 +    return (int)len;
 671.984 +}
 671.985 +
 671.986 +/* ===========================================================================
 671.987 + * Initialize the "longest match" routines for a new zlib stream
 671.988 + */
 671.989 +local void lm_init (s)
 671.990 +    deflate_state *s;
 671.991 +{
 671.992 +    s->window_size = (ulg)2L*s->w_size;
 671.993 +
 671.994 +    CLEAR_HASH(s);
 671.995 +
 671.996 +    /* Set the default configuration parameters:
 671.997 +     */
 671.998 +    s->max_lazy_match   = configuration_table[s->level].max_lazy;
 671.999 +    s->good_match       = configuration_table[s->level].good_length;
671.1000 +    s->nice_match       = configuration_table[s->level].nice_length;
671.1001 +    s->max_chain_length = configuration_table[s->level].max_chain;
671.1002 +
671.1003 +    s->strstart = 0;
671.1004 +    s->block_start = 0L;
671.1005 +    s->lookahead = 0;
671.1006 +    s->match_length = s->prev_length = MIN_MATCH-1;
671.1007 +    s->match_available = 0;
671.1008 +    s->ins_h = 0;
671.1009 +#ifndef FASTEST
671.1010 +#ifdef ASMV
671.1011 +    match_init(); /* initialize the asm code */
671.1012 +#endif
671.1013 +#endif
671.1014 +}
671.1015 +
671.1016 +#ifndef FASTEST
671.1017 +/* ===========================================================================
671.1018 + * Set match_start to the longest match starting at the given string and
671.1019 + * return its length. Matches shorter or equal to prev_length are discarded,
671.1020 + * in which case the result is equal to prev_length and match_start is
671.1021 + * garbage.
671.1022 + * IN assertions: cur_match is the head of the hash chain for the current
671.1023 + *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
671.1024 + * OUT assertion: the match length is not greater than s->lookahead.
671.1025 + */
671.1026 +#ifndef ASMV
671.1027 +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
671.1028 + * match.S. The code will be functionally equivalent.
671.1029 + */
671.1030 +local uInt longest_match(s, cur_match)
671.1031 +    deflate_state *s;
671.1032 +    IPos cur_match;                             /* current match */
671.1033 +{
671.1034 +    unsigned chain_length = s->max_chain_length;/* max hash chain length */
671.1035 +    register Bytef *scan = s->window + s->strstart; /* current string */
671.1036 +    register Bytef *match;                       /* matched string */
671.1037 +    register int len;                           /* length of current match */
671.1038 +    int best_len = s->prev_length;              /* best match length so far */
671.1039 +    int nice_match = s->nice_match;             /* stop if match long enough */
671.1040 +    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
671.1041 +        s->strstart - (IPos)MAX_DIST(s) : NIL;
671.1042 +    /* Stop when cur_match becomes <= limit. To simplify the code,
671.1043 +     * we prevent matches with the string of window index 0.
671.1044 +     */
671.1045 +    Posf *prev = s->prev;
671.1046 +    uInt wmask = s->w_mask;
671.1047 +
671.1048 +#ifdef UNALIGNED_OK
671.1049 +    /* Compare two bytes at a time. Note: this is not always beneficial.
671.1050 +     * Try with and without -DUNALIGNED_OK to check.
671.1051 +     */
671.1052 +    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
671.1053 +    register ush scan_start = *(ushf*)scan;
671.1054 +    register ush scan_end   = *(ushf*)(scan+best_len-1);
671.1055 +#else
671.1056 +    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
671.1057 +    register Byte scan_end1  = scan[best_len-1];
671.1058 +    register Byte scan_end   = scan[best_len];
671.1059 +#endif
671.1060 +
671.1061 +    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
671.1062 +     * It is easy to get rid of this optimization if necessary.
671.1063 +     */
671.1064 +    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
671.1065 +
671.1066 +    /* Do not waste too much time if we already have a good match: */
671.1067 +    if (s->prev_length >= s->good_match) {
671.1068 +        chain_length >>= 2;
671.1069 +    }
671.1070 +    /* Do not look for matches beyond the end of the input. This is necessary
671.1071 +     * to make deflate deterministic.
671.1072 +     */
671.1073 +    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
671.1074 +
671.1075 +    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
671.1076 +
671.1077 +    do {
671.1078 +        Assert(cur_match < s->strstart, "no future");
671.1079 +        match = s->window + cur_match;
671.1080 +
671.1081 +        /* Skip to next match if the match length cannot increase
671.1082 +         * or if the match length is less than 2.  Note that the checks below
671.1083 +         * for insufficient lookahead only occur occasionally for performance
671.1084 +         * reasons.  Therefore uninitialized memory will be accessed, and
671.1085 +         * conditional jumps will be made that depend on those values.
671.1086 +         * However the length of the match is limited to the lookahead, so
671.1087 +         * the output of deflate is not affected by the uninitialized values.
671.1088 +         */
671.1089 +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
671.1090 +        /* This code assumes sizeof(unsigned short) == 2. Do not use
671.1091 +         * UNALIGNED_OK if your compiler uses a different size.
671.1092 +         */
671.1093 +        if (*(ushf*)(match+best_len-1) != scan_end ||
671.1094 +            *(ushf*)match != scan_start) continue;
671.1095 +
671.1096 +        /* It is not necessary to compare scan[2] and match[2] since they are
671.1097 +         * always equal when the other bytes match, given that the hash keys
671.1098 +         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
671.1099 +         * strstart+3, +5, ... up to strstart+257. We check for insufficient
671.1100 +         * lookahead only every 4th comparison; the 128th check will be made
671.1101 +         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
671.1102 +         * necessary to put more guard bytes at the end of the window, or
671.1103 +         * to check more often for insufficient lookahead.
671.1104 +         */
671.1105 +        Assert(scan[2] == match[2], "scan[2]?");
671.1106 +        scan++, match++;
671.1107 +        do {
671.1108 +        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
671.1109 +                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
671.1110 +                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
671.1111 +                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
671.1112 +                 scan < strend);
671.1113 +        /* The funny "do {}" generates better code on most compilers */
671.1114 +
671.1115 +        /* Here, scan <= window+strstart+257 */
671.1116 +        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
671.1117 +        if (*scan == *match) scan++;
671.1118 +
671.1119 +        len = (MAX_MATCH - 1) - (int)(strend-scan);
671.1120 +        scan = strend - (MAX_MATCH-1);
671.1121 +
671.1122 +#else /* UNALIGNED_OK */
671.1123 +
671.1124 +        if (match[best_len]   != scan_end  ||
671.1125 +            match[best_len-1] != scan_end1 ||
671.1126 +            *match            != *scan     ||
671.1127 +            *++match          != scan[1])      continue;
671.1128 +
671.1129 +        /* The check at best_len-1 can be removed because it will be made
671.1130 +         * again later. (This heuristic is not always a win.)
671.1131 +         * It is not necessary to compare scan[2] and match[2] since they
671.1132 +         * are always equal when the other bytes match, given that
671.1133 +         * the hash keys are equal and that HASH_BITS >= 8.
671.1134 +         */
671.1135 +        scan += 2, match++;
671.1136 +        Assert(*scan == *match, "match[2]?");
671.1137 +
671.1138 +        /* We check for insufficient lookahead only every 8th comparison;
671.1139 +         * the 256th check will be made at strstart+258.
671.1140 +         */
671.1141 +        do {
671.1142 +        } while (*++scan == *++match && *++scan == *++match &&
671.1143 +                 *++scan == *++match && *++scan == *++match &&
671.1144 +                 *++scan == *++match && *++scan == *++match &&
671.1145 +                 *++scan == *++match && *++scan == *++match &&
671.1146 +                 scan < strend);
671.1147 +
671.1148 +        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
671.1149 +
671.1150 +        len = MAX_MATCH - (int)(strend - scan);
671.1151 +        scan = strend - MAX_MATCH;
671.1152 +
671.1153 +#endif /* UNALIGNED_OK */
671.1154 +
671.1155 +        if (len > best_len) {
671.1156 +            s->match_start = cur_match;
671.1157 +            best_len = len;
671.1158 +            if (len >= nice_match) break;
671.1159 +#ifdef UNALIGNED_OK
671.1160 +            scan_end = *(ushf*)(scan+best_len-1);
671.1161 +#else
671.1162 +            scan_end1  = scan[best_len-1];
671.1163 +            scan_end   = scan[best_len];
671.1164 +#endif
671.1165 +        }
671.1166 +    } while ((cur_match = prev[cur_match & wmask]) > limit
671.1167 +             && --chain_length != 0);
671.1168 +
671.1169 +    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
671.1170 +    return s->lookahead;
671.1171 +}
671.1172 +#endif /* ASMV */
671.1173 +#endif /* FASTEST */
671.1174 +
671.1175 +/* ---------------------------------------------------------------------------
671.1176 + * Optimized version for level == 1 or strategy == Z_RLE only
671.1177 + */
671.1178 +local uInt longest_match_fast(s, cur_match)
671.1179 +    deflate_state *s;
671.1180 +    IPos cur_match;                             /* current match */
671.1181 +{
671.1182 +    register Bytef *scan = s->window + s->strstart; /* current string */
671.1183 +    register Bytef *match;                       /* matched string */
671.1184 +    register int len;                           /* length of current match */
671.1185 +    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
671.1186 +
671.1187 +    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
671.1188 +     * It is easy to get rid of this optimization if necessary.
671.1189 +     */
671.1190 +    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
671.1191 +
671.1192 +    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
671.1193 +
671.1194 +    Assert(cur_match < s->strstart, "no future");
671.1195 +
671.1196 +    match = s->window + cur_match;
671.1197 +
671.1198 +    /* Return failure if the match length is less than 2:
671.1199 +     */
671.1200 +    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
671.1201 +
671.1202 +    /* The check at best_len-1 can be removed because it will be made
671.1203 +     * again later. (This heuristic is not always a win.)
671.1204 +     * It is not necessary to compare scan[2] and match[2] since they
671.1205 +     * are always equal when the other bytes match, given that
671.1206 +     * the hash keys are equal and that HASH_BITS >= 8.
671.1207 +     */
671.1208 +    scan += 2, match += 2;
671.1209 +    Assert(*scan == *match, "match[2]?");
671.1210 +
671.1211 +    /* We check for insufficient lookahead only every 8th comparison;
671.1212 +     * the 256th check will be made at strstart+258.
671.1213 +     */
671.1214 +    do {
671.1215 +    } while (*++scan == *++match && *++scan == *++match &&
671.1216 +             *++scan == *++match && *++scan == *++match &&
671.1217 +             *++scan == *++match && *++scan == *++match &&
671.1218 +             *++scan == *++match && *++scan == *++match &&
671.1219 +             scan < strend);
671.1220 +
671.1221 +    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
671.1222 +
671.1223 +    len = MAX_MATCH - (int)(strend - scan);
671.1224 +
671.1225 +    if (len < MIN_MATCH) return MIN_MATCH - 1;
671.1226 +
671.1227 +    s->match_start = cur_match;
671.1228 +    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
671.1229 +}
671.1230 +
671.1231 +#ifdef DEBUG
671.1232 +/* ===========================================================================
671.1233 + * Check that the match at match_start is indeed a match.
671.1234 + */
671.1235 +local void check_match(s, start, match, length)
671.1236 +    deflate_state *s;
671.1237 +    IPos start, match;
671.1238 +    int length;
671.1239 +{
671.1240 +    /* check that the match is indeed a match */
671.1241 +    if (zmemcmp(s->window + match,
671.1242 +                s->window + start, length) != EQUAL) {
671.1243 +        fprintf(stderr, " start %u, match %u, length %d\n",
671.1244 +                start, match, length);
671.1245 +        do {
671.1246 +            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
671.1247 +        } while (--length != 0);
671.1248 +        z_error("invalid match");
671.1249 +    }
671.1250 +    if (z_verbose > 1) {
671.1251 +        fprintf(stderr,"\\[%d,%d]", start-match, length);
671.1252 +        do { putc(s->window[start++], stderr); } while (--length != 0);
671.1253 +    }
671.1254 +}
671.1255 +#else
671.1256 +#  define check_match(s, start, match, length)
671.1257 +#endif /* DEBUG */
671.1258 +
671.1259 +/* ===========================================================================
671.1260 + * Fill the window when the lookahead becomes insufficient.
671.1261 + * Updates strstart and lookahead.
671.1262 + *
671.1263 + * IN assertion: lookahead < MIN_LOOKAHEAD
671.1264 + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
671.1265 + *    At least one byte has been read, or avail_in == 0; reads are
671.1266 + *    performed for at least two bytes (required for the zip translate_eol
671.1267 + *    option -- not supported here).
671.1268 + */
671.1269 +local void fill_window(s)
671.1270 +    deflate_state *s;
671.1271 +{
671.1272 +    register unsigned n, m;
671.1273 +    register Posf *p;
671.1274 +    unsigned more;    /* Amount of free space at the end of the window. */
671.1275 +    uInt wsize = s->w_size;
671.1276 +
671.1277 +    do {
671.1278 +        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
671.1279 +
671.1280 +        /* Deal with !@#$% 64K limit: */
671.1281 +        if (sizeof(int) <= 2) {
671.1282 +            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
671.1283 +                more = wsize;
671.1284 +
671.1285 +            } else if (more == (unsigned)(-1)) {
671.1286 +                /* Very unlikely, but possible on 16 bit machine if
671.1287 +                 * strstart == 0 && lookahead == 1 (input done a byte at time)
671.1288 +                 */
671.1289 +                more--;
671.1290 +            }
671.1291 +        }
671.1292 +
671.1293 +        /* If the window is almost full and there is insufficient lookahead,
671.1294 +         * move the upper half to the lower one to make room in the upper half.
671.1295 +         */
671.1296 +        if (s->strstart >= wsize+MAX_DIST(s)) {
671.1297 +
671.1298 +            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
671.1299 +            s->match_start -= wsize;
671.1300 +            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
671.1301 +            s->block_start -= (long) wsize;
671.1302 +
671.1303 +            /* Slide the hash table (could be avoided with 32 bit values
671.1304 +               at the expense of memory usage). We slide even when level == 0
671.1305 +               to keep the hash table consistent if we switch back to level > 0
671.1306 +               later. (Using level 0 permanently is not an optimal usage of
671.1307 +               zlib, so we don't care about this pathological case.)
671.1308 +             */
671.1309 +            /* %%% avoid this when Z_RLE */
671.1310 +            n = s->hash_size;
671.1311 +            p = &s->head[n];
671.1312 +            do {
671.1313 +                m = *--p;
671.1314 +                *p = (Pos)(m >= wsize ? m-wsize : NIL);
671.1315 +            } while (--n);
671.1316 +
671.1317 +            n = wsize;
671.1318 +#ifndef FASTEST
671.1319 +            p = &s->prev[n];
671.1320 +            do {
671.1321 +                m = *--p;
671.1322 +                *p = (Pos)(m >= wsize ? m-wsize : NIL);
671.1323 +                /* If n is not on any hash chain, prev[n] is garbage but
671.1324 +                 * its value will never be used.
671.1325 +                 */
671.1326 +            } while (--n);
671.1327 +#endif
671.1328 +            more += wsize;
671.1329 +        }
671.1330 +        if (s->strm->avail_in == 0) return;
671.1331 +
671.1332 +        /* If there was no sliding:
671.1333 +         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
671.1334 +         *    more == window_size - lookahead - strstart
671.1335 +         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
671.1336 +         * => more >= window_size - 2*WSIZE + 2
671.1337 +         * In the BIG_MEM or MMAP case (not yet supported),
671.1338 +         *   window_size == input_size + MIN_LOOKAHEAD  &&
671.1339 +         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
671.1340 +         * Otherwise, window_size == 2*WSIZE so more >= 2.
671.1341 +         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
671.1342 +         */
671.1343 +        Assert(more >= 2, "more < 2");
671.1344 +
671.1345 +        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
671.1346 +        s->lookahead += n;
671.1347 +
671.1348 +        /* Initialize the hash value now that we have some input: */
671.1349 +        if (s->lookahead >= MIN_MATCH) {
671.1350 +            s->ins_h = s->window[s->strstart];
671.1351 +            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
671.1352 +#if MIN_MATCH != 3
671.1353 +            Call UPDATE_HASH() MIN_MATCH-3 more times
671.1354 +#endif
671.1355 +        }
671.1356 +        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
671.1357 +         * but this is not important since only literal bytes will be emitted.
671.1358 +         */
671.1359 +
671.1360 +    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
671.1361 +}
671.1362 +
671.1363 +/* ===========================================================================
671.1364 + * Flush the current block, with given end-of-file flag.
671.1365 + * IN assertion: strstart is set to the end of the current match.
671.1366 + */
671.1367 +#define FLUSH_BLOCK_ONLY(s, eof) { \
671.1368 +   _tr_flush_block(s, (s->block_start >= 0L ? \
671.1369 +                   (charf *)&s->window[(unsigned)s->block_start] : \
671.1370 +                   (charf *)Z_NULL), \
671.1371 +                (ulg)((long)s->strstart - s->block_start), \
671.1372 +                (eof)); \
671.1373 +   s->block_start = s->strstart; \
671.1374 +   flush_pending(s->strm); \
671.1375 +   Tracev((stderr,"[FLUSH]")); \
671.1376 +}
671.1377 +
671.1378 +/* Same but force premature exit if necessary. */
671.1379 +#define FLUSH_BLOCK(s, eof) { \
671.1380 +   FLUSH_BLOCK_ONLY(s, eof); \
671.1381 +   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
671.1382 +}
671.1383 +
671.1384 +/* ===========================================================================
671.1385 + * Copy without compression as much as possible from the input stream, return
671.1386 + * the current block state.
671.1387 + * This function does not insert new strings in the dictionary since
671.1388 + * uncompressible data is probably not useful. This function is used
671.1389 + * only for the level=0 compression option.
671.1390 + * NOTE: this function should be optimized to avoid extra copying from
671.1391 + * window to pending_buf.
671.1392 + */
671.1393 +local block_state deflate_stored(s, flush)
671.1394 +    deflate_state *s;
671.1395 +    int flush;
671.1396 +{
671.1397 +    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
671.1398 +     * to pending_buf_size, and each stored block has a 5 byte header:
671.1399 +     */
671.1400 +    ulg max_block_size = 0xffff;
671.1401 +    ulg max_start;
671.1402 +
671.1403 +    if (max_block_size > s->pending_buf_size - 5) {
671.1404 +        max_block_size = s->pending_buf_size - 5;
671.1405 +    }
671.1406 +
671.1407 +    /* Copy as much as possible from input to output: */
671.1408 +    for (;;) {
671.1409 +        /* Fill the window as much as possible: */
671.1410 +        if (s->lookahead <= 1) {
671.1411 +
671.1412 +            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
671.1413 +                   s->block_start >= (long)s->w_size, "slide too late");
671.1414 +
671.1415 +            fill_window(s);
671.1416 +            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
671.1417 +
671.1418 +            if (s->lookahead == 0) break; /* flush the current block */
671.1419 +        }
671.1420 +        Assert(s->block_start >= 0L, "block gone");
671.1421 +
671.1422 +        s->strstart += s->lookahead;
671.1423 +        s->lookahead = 0;
671.1424 +
671.1425 +        /* Emit a stored block if pending_buf will be full: */
671.1426 +        max_start = s->block_start + max_block_size;
671.1427 +        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
671.1428 +            /* strstart == 0 is possible when wraparound on 16-bit machine */
671.1429 +            s->lookahead = (uInt)(s->strstart - max_start);
671.1430 +            s->strstart = (uInt)max_start;
671.1431 +            FLUSH_BLOCK(s, 0);
671.1432 +        }
671.1433 +        /* Flush if we may have to slide, otherwise block_start may become
671.1434 +         * negative and the data will be gone:
671.1435 +         */
671.1436 +        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
671.1437 +            FLUSH_BLOCK(s, 0);
671.1438 +        }
671.1439 +    }
671.1440 +    FLUSH_BLOCK(s, flush == Z_FINISH);
671.1441 +    return flush == Z_FINISH ? finish_done : block_done;
671.1442 +}
671.1443 +
671.1444 +/* ===========================================================================
671.1445 + * Compress as much as possible from the input stream, return the current
671.1446 + * block state.
671.1447 + * This function does not perform lazy evaluation of matches and inserts
671.1448 + * new strings in the dictionary only for unmatched strings or for short
671.1449 + * matches. It is used only for the fast compression options.
671.1450 + */
671.1451 +local block_state deflate_fast(s, flush)
671.1452 +    deflate_state *s;
671.1453 +    int flush;
671.1454 +{
671.1455 +    IPos hash_head = NIL; /* head of the hash chain */
671.1456 +    int bflush;           /* set if current block must be flushed */
671.1457 +
671.1458 +    for (;;) {
671.1459 +        /* Make sure that we always have enough lookahead, except
671.1460 +         * at the end of the input file. We need MAX_MATCH bytes
671.1461 +         * for the next match, plus MIN_MATCH bytes to insert the
671.1462 +         * string following the next match.
671.1463 +         */
671.1464 +        if (s->lookahead < MIN_LOOKAHEAD) {
671.1465 +            fill_window(s);
671.1466 +            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
671.1467 +                return need_more;
671.1468 +            }
671.1469 +            if (s->lookahead == 0) break; /* flush the current block */
671.1470 +        }
671.1471 +
671.1472 +        /* Insert the string window[strstart .. strstart+2] in the
671.1473 +         * dictionary, and set hash_head to the head of the hash chain:
671.1474 +         */
671.1475 +        if (s->lookahead >= MIN_MATCH) {
671.1476 +            INSERT_STRING(s, s->strstart, hash_head);
671.1477 +        }
671.1478 +
671.1479 +        /* Find the longest match, discarding those <= prev_length.
671.1480 +         * At this point we have always match_length < MIN_MATCH
671.1481 +         */
671.1482 +        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
671.1483 +            /* To simplify the code, we prevent matches with the string
671.1484 +             * of window index 0 (in particular we have to avoid a match
671.1485 +             * of the string with itself at the start of the input file).
671.1486 +             */
671.1487 +#ifdef FASTEST
671.1488 +            if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
671.1489 +                (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
671.1490 +                s->match_length = longest_match_fast (s, hash_head);
671.1491 +            }
671.1492 +#else
671.1493 +            if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
671.1494 +                s->match_length = longest_match (s, hash_head);
671.1495 +            } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
671.1496 +                s->match_length = longest_match_fast (s, hash_head);
671.1497 +            }
671.1498 +#endif
671.1499 +            /* longest_match() or longest_match_fast() sets match_start */
671.1500 +        }
671.1501 +        if (s->match_length >= MIN_MATCH) {
671.1502 +            check_match(s, s->strstart, s->match_start, s->match_length);
671.1503 +
671.1504 +            _tr_tally_dist(s, s->strstart - s->match_start,
671.1505 +                           s->match_length - MIN_MATCH, bflush);
671.1506 +
671.1507 +            s->lookahead -= s->match_length;
671.1508 +
671.1509 +            /* Insert new strings in the hash table only if the match length
671.1510 +             * is not too large. This saves time but degrades compression.
671.1511 +             */
671.1512 +#ifndef FASTEST
671.1513 +            if (s->match_length <= s->max_insert_length &&
671.1514 +                s->lookahead >= MIN_MATCH) {
671.1515 +                s->match_length--; /* string at strstart already in table */
671.1516 +                do {
671.1517 +                    s->strstart++;
671.1518 +                    INSERT_STRING(s, s->strstart, hash_head);
671.1519 +                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
671.1520 +                     * always MIN_MATCH bytes ahead.
671.1521 +                     */
671.1522 +                } while (--s->match_length != 0);
671.1523 +                s->strstart++;
671.1524 +            } else
671.1525 +#endif
671.1526 +            {
671.1527 +                s->strstart += s->match_length;
671.1528 +                s->match_length = 0;
671.1529 +                s->ins_h = s->window[s->strstart];
671.1530 +                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
671.1531 +#if MIN_MATCH != 3
671.1532 +                Call UPDATE_HASH() MIN_MATCH-3 more times
671.1533 +#endif
671.1534 +                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
671.1535 +                 * matter since it will be recomputed at next deflate call.
671.1536 +                 */
671.1537 +            }
671.1538 +        } else {
671.1539 +            /* No match, output a literal byte */
671.1540 +            Tracevv((stderr,"%c", s->window[s->strstart]));
671.1541 +            _tr_tally_lit (s, s->window[s->strstart], bflush);
671.1542 +            s->lookahead--;
671.1543 +            s->strstart++;
671.1544 +        }
671.1545 +        if (bflush) FLUSH_BLOCK(s, 0);
671.1546 +    }
671.1547 +    FLUSH_BLOCK(s, flush == Z_FINISH);
671.1548 +    return flush == Z_FINISH ? finish_done : block_done;
671.1549 +}
671.1550 +
671.1551 +#ifndef FASTEST
671.1552 +/* ===========================================================================
671.1553 + * Same as above, but achieves better compression. We use a lazy
671.1554 + * evaluation for matches: a match is finally adopted only if there is
671.1555 + * no better match at the next window position.
671.1556 + */
671.1557 +local block_state deflate_slow(s, flush)
671.1558 +    deflate_state *s;
671.1559 +    int flush;
671.1560 +{
671.1561 +    IPos hash_head = NIL;    /* head of hash chain */
671.1562 +    int bflush;              /* set if current block must be flushed */
671.1563 +
671.1564 +    /* Process the input block. */
671.1565 +    for (;;) {
671.1566 +        /* Make sure that we always have enough lookahead, except
671.1567 +         * at the end of the input file. We need MAX_MATCH bytes
671.1568 +         * for the next match, plus MIN_MATCH bytes to insert the
671.1569 +         * string following the next match.
671.1570 +         */
671.1571 +        if (s->lookahead < MIN_LOOKAHEAD) {
671.1572 +            fill_window(s);
671.1573 +            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
671.1574 +                return need_more;
671.1575 +            }
671.1576 +            if (s->lookahead == 0) break; /* flush the current block */
671.1577 +        }
671.1578 +
671.1579 +        /* Insert the string window[strstart .. strstart+2] in the
671.1580 +         * dictionary, and set hash_head to the head of the hash chain:
671.1581 +         */
671.1582 +        if (s->lookahead >= MIN_MATCH) {
671.1583 +            INSERT_STRING(s, s->strstart, hash_head);
671.1584 +        }
671.1585 +
671.1586 +        /* Find the longest match, discarding those <= prev_length.
671.1587 +         */
671.1588 +        s->prev_length = s->match_length, s->prev_match = s->match_start;
671.1589 +        s->match_length = MIN_MATCH-1;
671.1590 +
671.1591 +        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
671.1592 +            s->strstart - hash_head <= MAX_DIST(s)) {
671.1593 +            /* To simplify the code, we prevent matches with the string
671.1594 +             * of window index 0 (in particular we have to avoid a match
671.1595 +             * of the string with itself at the start of the input file).
671.1596 +             */
671.1597 +            if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
671.1598 +                s->match_length = longest_match (s, hash_head);
671.1599 +            } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
671.1600 +                s->match_length = longest_match_fast (s, hash_head);
671.1601 +            }
671.1602 +            /* longest_match() or longest_match_fast() sets match_start */
671.1603 +
671.1604 +            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
671.1605 +#if TOO_FAR <= 32767
671.1606 +                || (s->match_length == MIN_MATCH &&
671.1607 +                    s->strstart - s->match_start > TOO_FAR)
671.1608 +#endif
671.1609 +                )) {
671.1610 +
671.1611 +                /* If prev_match is also MIN_MATCH, match_start is garbage
671.1612 +                 * but we will ignore the current match anyway.
671.1613 +                 */
671.1614 +                s->match_length = MIN_MATCH-1;
671.1615 +            }
671.1616 +        }
671.1617 +        /* If there was a match at the previous step and the current
671.1618 +         * match is not better, output the previous match:
671.1619 +         */
671.1620 +        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
671.1621 +            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
671.1622 +            /* Do not insert strings in hash table beyond this. */
671.1623 +
671.1624 +            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
671.1625 +
671.1626 +            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
671.1627 +                           s->prev_length - MIN_MATCH, bflush);
671.1628 +
671.1629 +            /* Insert in hash table all strings up to the end of the match.
671.1630 +             * strstart-1 and strstart are already inserted. If there is not
671.1631 +             * enough lookahead, the last two strings are not inserted in
671.1632 +             * the hash table.
671.1633 +             */
671.1634 +            s->lookahead -= s->prev_length-1;
671.1635 +            s->prev_length -= 2;
671.1636 +            do {
671.1637 +                if (++s->strstart <= max_insert) {
671.1638 +                    INSERT_STRING(s, s->strstart, hash_head);
671.1639 +                }
671.1640 +            } while (--s->prev_length != 0);
671.1641 +            s->match_available = 0;
671.1642 +            s->match_length = MIN_MATCH-1;
671.1643 +            s->strstart++;
671.1644 +
671.1645 +            if (bflush) FLUSH_BLOCK(s, 0);
671.1646 +
671.1647 +        } else if (s->match_available) {
671.1648 +            /* If there was no match at the previous position, output a
671.1649 +             * single literal. If there was a match but the current match
671.1650 +             * is longer, truncate the previous match to a single literal.
671.1651 +             */
671.1652 +            Tracevv((stderr,"%c", s->window[s->strstart-1]));
671.1653 +            _tr_tally_lit(s, s->window[s->strstart-1], bflush);
671.1654 +            if (bflush) {
671.1655 +                FLUSH_BLOCK_ONLY(s, 0);
671.1656 +            }
671.1657 +            s->strstart++;
671.1658 +            s->lookahead--;
671.1659 +            if (s->strm->avail_out == 0) return need_more;
671.1660 +        } else {
671.1661 +            /* There is no previous match to compare with, wait for
671.1662 +             * the next step to decide.
671.1663 +             */
671.1664 +            s->match_available = 1;
671.1665 +            s->strstart++;
671.1666 +            s->lookahead--;
671.1667 +        }
671.1668 +    }
671.1669 +    Assert (flush != Z_NO_FLUSH, "no flush?");
671.1670 +    if (s->match_available) {
671.1671 +        Tracevv((stderr,"%c", s->window[s->strstart-1]));
671.1672 +        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
671.1673 +        s->match_available = 0;
671.1674 +    }
671.1675 +    FLUSH_BLOCK(s, flush == Z_FINISH);
671.1676 +    return flush == Z_FINISH ? finish_done : block_done;
671.1677 +}
671.1678 +#endif /* FASTEST */
671.1679 +
671.1680 +#if 0
671.1681 +/* ===========================================================================
671.1682 + * For Z_RLE, simply look for runs of bytes, generate matches only of distance
671.1683 + * one.  Do not maintain a hash table.  (It will be regenerated if this run of
671.1684 + * deflate switches away from Z_RLE.)
671.1685 + */
671.1686 +local block_state deflate_rle(s, flush)
671.1687 +    deflate_state *s;
671.1688 +    int flush;
671.1689 +{
671.1690 +    int bflush;         /* set if current block must be flushed */
671.1691 +    uInt run;           /* length of run */
671.1692 +    uInt max;           /* maximum length of run */
671.1693 +    uInt prev;          /* byte at distance one to match */
671.1694 +    Bytef *scan;        /* scan for end of run */
671.1695 +
671.1696 +    for (;;) {
671.1697 +        /* Make sure that we always have enough lookahead, except
671.1698 +         * at the end of the input file. We need MAX_MATCH bytes
671.1699 +         * for the longest encodable run.
671.1700 +         */
671.1701 +        if (s->lookahead < MAX_MATCH) {
671.1702 +            fill_window(s);
671.1703 +            if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
671.1704 +                return need_more;
671.1705 +            }
671.1706 +            if (s->lookahead == 0) break; /* flush the current block */
671.1707 +        }
671.1708 +
671.1709 +        /* See how many times the previous byte repeats */
671.1710 +        run = 0;
671.1711 +        if (s->strstart > 0) {      /* if there is a previous byte, that is */
671.1712 +            max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
671.1713 +            scan = s->window + s->strstart - 1;
671.1714 +            prev = *scan++;
671.1715 +            do {
671.1716 +                if (*scan++ != prev)
671.1717 +                    break;
671.1718 +            } while (++run < max);
671.1719 +        }
671.1720 +
671.1721 +        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
671.1722 +        if (run >= MIN_MATCH) {
671.1723 +            check_match(s, s->strstart, s->strstart - 1, run);
671.1724 +            _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
671.1725 +            s->lookahead -= run;
671.1726 +            s->strstart += run;
671.1727 +        } else {
671.1728 +            /* No match, output a literal byte */
671.1729 +            Tracevv((stderr,"%c", s->window[s->strstart]));
671.1730 +            _tr_tally_lit (s, s->window[s->strstart], bflush);
671.1731 +            s->lookahead--;
671.1732 +            s->strstart++;
671.1733 +        }
671.1734 +        if (bflush) FLUSH_BLOCK(s, 0);
671.1735 +    }
671.1736 +    FLUSH_BLOCK(s, flush == Z_FINISH);
671.1737 +    return flush == Z_FINISH ? finish_done : block_done;
671.1738 +}
671.1739 +#endif
   672.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   672.2 +++ b/libs/zlib/deflate.h	Sat Feb 01 19:58:19 2014 +0200
   672.3 @@ -0,0 +1,331 @@
   672.4 +/* deflate.h -- internal compression state
   672.5 + * Copyright (C) 1995-2004 Jean-loup Gailly
   672.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   672.7 + */
   672.8 +
   672.9 +/* WARNING: this file should *not* be used by applications. It is
  672.10 +   part of the implementation of the compression library and is
  672.11 +   subject to change. Applications should only use zlib.h.
  672.12 + */
  672.13 +
  672.14 +/* @(#) $Id$ */
  672.15 +
  672.16 +#ifndef DEFLATE_H
  672.17 +#define DEFLATE_H
  672.18 +
  672.19 +#include "zutil.h"
  672.20 +
  672.21 +/* define NO_GZIP when compiling if you want to disable gzip header and
  672.22 +   trailer creation by deflate().  NO_GZIP would be used to avoid linking in
  672.23 +   the crc code when it is not needed.  For shared libraries, gzip encoding
  672.24 +   should be left enabled. */
  672.25 +#ifndef NO_GZIP
  672.26 +#  define GZIP
  672.27 +#endif
  672.28 +
  672.29 +/* ===========================================================================
  672.30 + * Internal compression state.
  672.31 + */
  672.32 +
  672.33 +#define LENGTH_CODES 29
  672.34 +/* number of length codes, not counting the special END_BLOCK code */
  672.35 +
  672.36 +#define LITERALS  256
  672.37 +/* number of literal bytes 0..255 */
  672.38 +
  672.39 +#define L_CODES (LITERALS+1+LENGTH_CODES)
  672.40 +/* number of Literal or Length codes, including the END_BLOCK code */
  672.41 +
  672.42 +#define D_CODES   30
  672.43 +/* number of distance codes */
  672.44 +
  672.45 +#define BL_CODES  19
  672.46 +/* number of codes used to transfer the bit lengths */
  672.47 +
  672.48 +#define HEAP_SIZE (2*L_CODES+1)
  672.49 +/* maximum heap size */
  672.50 +
  672.51 +#define MAX_BITS 15
  672.52 +/* All codes must not exceed MAX_BITS bits */
  672.53 +
  672.54 +#define INIT_STATE    42
  672.55 +#define EXTRA_STATE   69
  672.56 +#define NAME_STATE    73
  672.57 +#define COMMENT_STATE 91
  672.58 +#define HCRC_STATE   103
  672.59 +#define BUSY_STATE   113
  672.60 +#define FINISH_STATE 666
  672.61 +/* Stream status */
  672.62 +
  672.63 +
  672.64 +/* Data structure describing a single value and its code string. */
  672.65 +typedef struct ct_data_s {
  672.66 +    union {
  672.67 +        ush  freq;       /* frequency count */
  672.68 +        ush  code;       /* bit string */
  672.69 +    } fc;
  672.70 +    union {
  672.71 +        ush  dad;        /* father node in Huffman tree */
  672.72 +        ush  len;        /* length of bit string */
  672.73 +    } dl;
  672.74 +} FAR ct_data;
  672.75 +
  672.76 +#define Freq fc.freq
  672.77 +#define Code fc.code
  672.78 +#define Dad  dl.dad
  672.79 +#define Len  dl.len
  672.80 +
  672.81 +typedef struct static_tree_desc_s  static_tree_desc;
  672.82 +
  672.83 +typedef struct tree_desc_s {
  672.84 +    ct_data *dyn_tree;           /* the dynamic tree */
  672.85 +    int     max_code;            /* largest code with non zero frequency */
  672.86 +    static_tree_desc *stat_desc; /* the corresponding static tree */
  672.87 +} FAR tree_desc;
  672.88 +
  672.89 +typedef ush Pos;
  672.90 +typedef Pos FAR Posf;
  672.91 +typedef unsigned IPos;
  672.92 +
  672.93 +/* A Pos is an index in the character window. We use short instead of int to
  672.94 + * save space in the various tables. IPos is used only for parameter passing.
  672.95 + */
  672.96 +
  672.97 +typedef struct internal_state {
  672.98 +    z_streamp strm;      /* pointer back to this zlib stream */
  672.99 +    int   status;        /* as the name implies */
 672.100 +    Bytef *pending_buf;  /* output still pending */
 672.101 +    ulg   pending_buf_size; /* size of pending_buf */
 672.102 +    Bytef *pending_out;  /* next pending byte to output to the stream */
 672.103 +    uInt   pending;      /* nb of bytes in the pending buffer */
 672.104 +    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
 672.105 +    gz_headerp  gzhead;  /* gzip header information to write */
 672.106 +    uInt   gzindex;      /* where in extra, name, or comment */
 672.107 +    Byte  method;        /* STORED (for zip only) or DEFLATED */
 672.108 +    int   last_flush;    /* value of flush param for previous deflate call */
 672.109 +
 672.110 +                /* used by deflate.c: */
 672.111 +
 672.112 +    uInt  w_size;        /* LZ77 window size (32K by default) */
 672.113 +    uInt  w_bits;        /* log2(w_size)  (8..16) */
 672.114 +    uInt  w_mask;        /* w_size - 1 */
 672.115 +
 672.116 +    Bytef *window;
 672.117 +    /* Sliding window. Input bytes are read into the second half of the window,
 672.118 +     * and move to the first half later to keep a dictionary of at least wSize
 672.119 +     * bytes. With this organization, matches are limited to a distance of
 672.120 +     * wSize-MAX_MATCH bytes, but this ensures that IO is always
 672.121 +     * performed with a length multiple of the block size. Also, it limits
 672.122 +     * the window size to 64K, which is quite useful on MSDOS.
 672.123 +     * To do: use the user input buffer as sliding window.
 672.124 +     */
 672.125 +
 672.126 +    ulg window_size;
 672.127 +    /* Actual size of window: 2*wSize, except when the user input buffer
 672.128 +     * is directly used as sliding window.
 672.129 +     */
 672.130 +
 672.131 +    Posf *prev;
 672.132 +    /* Link to older string with same hash index. To limit the size of this
 672.133 +     * array to 64K, this link is maintained only for the last 32K strings.
 672.134 +     * An index in this array is thus a window index modulo 32K.
 672.135 +     */
 672.136 +
 672.137 +    Posf *head; /* Heads of the hash chains or NIL. */
 672.138 +
 672.139 +    uInt  ins_h;          /* hash index of string to be inserted */
 672.140 +    uInt  hash_size;      /* number of elements in hash table */
 672.141 +    uInt  hash_bits;      /* log2(hash_size) */
 672.142 +    uInt  hash_mask;      /* hash_size-1 */
 672.143 +
 672.144 +    uInt  hash_shift;
 672.145 +    /* Number of bits by which ins_h must be shifted at each input
 672.146 +     * step. It must be such that after MIN_MATCH steps, the oldest
 672.147 +     * byte no longer takes part in the hash key, that is:
 672.148 +     *   hash_shift * MIN_MATCH >= hash_bits
 672.149 +     */
 672.150 +
 672.151 +    long block_start;
 672.152 +    /* Window position at the beginning of the current output block. Gets
 672.153 +     * negative when the window is moved backwards.
 672.154 +     */
 672.155 +
 672.156 +    uInt match_length;           /* length of best match */
 672.157 +    IPos prev_match;             /* previous match */
 672.158 +    int match_available;         /* set if previous match exists */
 672.159 +    uInt strstart;               /* start of string to insert */
 672.160 +    uInt match_start;            /* start of matching string */
 672.161 +    uInt lookahead;              /* number of valid bytes ahead in window */
 672.162 +
 672.163 +    uInt prev_length;
 672.164 +    /* Length of the best match at previous step. Matches not greater than this
 672.165 +     * are discarded. This is used in the lazy match evaluation.
 672.166 +     */
 672.167 +
 672.168 +    uInt max_chain_length;
 672.169 +    /* To speed up deflation, hash chains are never searched beyond this
 672.170 +     * length.  A higher limit improves compression ratio but degrades the
 672.171 +     * speed.
 672.172 +     */
 672.173 +
 672.174 +    uInt max_lazy_match;
 672.175 +    /* Attempt to find a better match only when the current match is strictly
 672.176 +     * smaller than this value. This mechanism is used only for compression
 672.177 +     * levels >= 4.
 672.178 +     */
 672.179 +#   define max_insert_length  max_lazy_match
 672.180 +    /* Insert new strings in the hash table only if the match length is not
 672.181 +     * greater than this length. This saves time but degrades compression.
 672.182 +     * max_insert_length is used only for compression levels <= 3.
 672.183 +     */
 672.184 +
 672.185 +    int level;    /* compression level (1..9) */
 672.186 +    int strategy; /* favor or force Huffman coding*/
 672.187 +
 672.188 +    uInt good_match;
 672.189 +    /* Use a faster search when the previous match is longer than this */
 672.190 +
 672.191 +    int nice_match; /* Stop searching when current match exceeds this */
 672.192 +
 672.193 +                /* used by trees.c: */
 672.194 +    /* Didn't use ct_data typedef below to supress compiler warning */
 672.195 +    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
 672.196 +    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
 672.197 +    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
 672.198 +
 672.199 +    struct tree_desc_s l_desc;               /* desc. for literal tree */
 672.200 +    struct tree_desc_s d_desc;               /* desc. for distance tree */
 672.201 +    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
 672.202 +
 672.203 +    ush bl_count[MAX_BITS+1];
 672.204 +    /* number of codes at each bit length for an optimal tree */
 672.205 +
 672.206 +    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
 672.207 +    int heap_len;               /* number of elements in the heap */
 672.208 +    int heap_max;               /* element of largest frequency */
 672.209 +    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
 672.210 +     * The same heap array is used to build all trees.
 672.211 +     */
 672.212 +
 672.213 +    uch depth[2*L_CODES+1];
 672.214 +    /* Depth of each subtree used as tie breaker for trees of equal frequency
 672.215 +     */
 672.216 +
 672.217 +    uchf *l_buf;          /* buffer for literals or lengths */
 672.218 +
 672.219 +    uInt  lit_bufsize;
 672.220 +    /* Size of match buffer for literals/lengths.  There are 4 reasons for
 672.221 +     * limiting lit_bufsize to 64K:
 672.222 +     *   - frequencies can be kept in 16 bit counters
 672.223 +     *   - if compression is not successful for the first block, all input
 672.224 +     *     data is still in the window so we can still emit a stored block even
 672.225 +     *     when input comes from standard input.  (This can also be done for
 672.226 +     *     all blocks if lit_bufsize is not greater than 32K.)
 672.227 +     *   - if compression is not successful for a file smaller than 64K, we can
 672.228 +     *     even emit a stored file instead of a stored block (saving 5 bytes).
 672.229 +     *     This is applicable only for zip (not gzip or zlib).
 672.230 +     *   - creating new Huffman trees less frequently may not provide fast
 672.231 +     *     adaptation to changes in the input data statistics. (Take for
 672.232 +     *     example a binary file with poorly compressible code followed by
 672.233 +     *     a highly compressible string table.) Smaller buffer sizes give
 672.234 +     *     fast adaptation but have of course the overhead of transmitting
 672.235 +     *     trees more frequently.
 672.236 +     *   - I can't count above 4
 672.237 +     */
 672.238 +
 672.239 +    uInt last_lit;      /* running index in l_buf */
 672.240 +
 672.241 +    ushf *d_buf;
 672.242 +    /* Buffer for distances. To simplify the code, d_buf and l_buf have
 672.243 +     * the same number of elements. To use different lengths, an extra flag
 672.244 +     * array would be necessary.
 672.245 +     */
 672.246 +
 672.247 +    ulg opt_len;        /* bit length of current block with optimal trees */
 672.248 +    ulg static_len;     /* bit length of current block with static trees */
 672.249 +    uInt matches;       /* number of string matches in current block */
 672.250 +    int last_eob_len;   /* bit length of EOB code for last block */
 672.251 +
 672.252 +#ifdef DEBUG
 672.253 +    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
 672.254 +    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
 672.255 +#endif
 672.256 +
 672.257 +    ush bi_buf;
 672.258 +    /* Output buffer. bits are inserted starting at the bottom (least
 672.259 +     * significant bits).
 672.260 +     */
 672.261 +    int bi_valid;
 672.262 +    /* Number of valid bits in bi_buf.  All bits above the last valid bit
 672.263 +     * are always zero.
 672.264 +     */
 672.265 +
 672.266 +} FAR deflate_state;
 672.267 +
 672.268 +/* Output a byte on the stream.
 672.269 + * IN assertion: there is enough room in pending_buf.
 672.270 + */
 672.271 +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
 672.272 +
 672.273 +
 672.274 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
 672.275 +/* Minimum amount of lookahead, except at the end of the input file.
 672.276 + * See deflate.c for comments about the MIN_MATCH+1.
 672.277 + */
 672.278 +
 672.279 +#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
 672.280 +/* In order to simplify the code, particularly on 16 bit machines, match
 672.281 + * distances are limited to MAX_DIST instead of WSIZE.
 672.282 + */
 672.283 +
 672.284 +        /* in trees.c */
 672.285 +void _tr_init         OF((deflate_state *s));
 672.286 +int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
 672.287 +void _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
 672.288 +                          int eof));
 672.289 +void _tr_align        OF((deflate_state *s));
 672.290 +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
 672.291 +                          int eof));
 672.292 +
 672.293 +#define d_code(dist) \
 672.294 +   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
 672.295 +/* Mapping from a distance to a distance code. dist is the distance - 1 and
 672.296 + * must not have side effects. _dist_code[256] and _dist_code[257] are never
 672.297 + * used.
 672.298 + */
 672.299 +
 672.300 +#ifndef DEBUG
 672.301 +/* Inline versions of _tr_tally for speed: */
 672.302 +
 672.303 +#if defined(GEN_TREES_H) || !defined(STDC)
 672.304 +  extern uch _length_code[];
 672.305 +  extern uch _dist_code[];
 672.306 +#else
 672.307 +  extern const uch _length_code[];
 672.308 +  extern const uch _dist_code[];
 672.309 +#endif
 672.310 +
 672.311 +# define _tr_tally_lit(s, c, flush) \
 672.312 +  { uch cc = (c); \
 672.313 +    s->d_buf[s->last_lit] = 0; \
 672.314 +    s->l_buf[s->last_lit++] = cc; \
 672.315 +    s->dyn_ltree[cc].Freq++; \
 672.316 +    flush = (s->last_lit == s->lit_bufsize-1); \
 672.317 +   }
 672.318 +# define _tr_tally_dist(s, distance, length, flush) \
 672.319 +  { uch len = (length); \
 672.320 +    ush dist = (distance); \
 672.321 +    s->d_buf[s->last_lit] = dist; \
 672.322 +    s->l_buf[s->last_lit++] = len; \
 672.323 +    dist--; \
 672.324 +    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
 672.325 +    s->dyn_dtree[d_code(dist)].Freq++; \
 672.326 +    flush = (s->last_lit == s->lit_bufsize-1); \
 672.327 +  }
 672.328 +#else
 672.329 +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
 672.330 +# define _tr_tally_dist(s, distance, length, flush) \
 672.331 +              flush = _tr_tally(s, distance, length)
 672.332 +#endif
 672.333 +
 672.334 +#endif /* DEFLATE_H */
   673.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   673.2 +++ b/libs/zlib/gzio.c	Sat Feb 01 19:58:19 2014 +0200
   673.3 @@ -0,0 +1,1026 @@
   673.4 +/* gzio.c -- IO on .gz files
   673.5 + * Copyright (C) 1995-2005 Jean-loup Gailly.
   673.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   673.7 + *
   673.8 + * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
   673.9 + */
  673.10 +
  673.11 +/* @(#) $Id$ */
  673.12 +
  673.13 +#include <stdio.h>
  673.14 +
  673.15 +#include "zutil.h"
  673.16 +
  673.17 +#ifdef NO_DEFLATE       /* for compatibility with old definition */
  673.18 +#  define NO_GZCOMPRESS
  673.19 +#endif
  673.20 +
  673.21 +#ifndef NO_DUMMY_DECL
  673.22 +struct internal_state {int dummy;}; /* for buggy compilers */
  673.23 +#endif
  673.24 +
  673.25 +#ifndef Z_BUFSIZE
  673.26 +#  ifdef MAXSEG_64K
  673.27 +#    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
  673.28 +#  else
  673.29 +#    define Z_BUFSIZE 16384
  673.30 +#  endif
  673.31 +#endif
  673.32 +#ifndef Z_PRINTF_BUFSIZE
  673.33 +#  define Z_PRINTF_BUFSIZE 4096
  673.34 +#endif
  673.35 +
  673.36 +#ifdef __MVS__
  673.37 +#  pragma map (fdopen , "\174\174FDOPEN")
  673.38 +   FILE *fdopen(int, const char *);
  673.39 +#endif
  673.40 +
  673.41 +#ifndef STDC
  673.42 +extern voidp  malloc OF((uInt size));
  673.43 +extern void   free   OF((voidpf ptr));
  673.44 +#endif
  673.45 +
  673.46 +#define ALLOC(size) malloc(size)
  673.47 +#define TRYFREE(p) {if (p) free(p);}
  673.48 +
  673.49 +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
  673.50 +
  673.51 +/* gzip flag byte */
  673.52 +#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
  673.53 +#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
  673.54 +#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
  673.55 +#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
  673.56 +#define COMMENT      0x10 /* bit 4 set: file comment present */
  673.57 +#define RESERVED     0xE0 /* bits 5..7: reserved */
  673.58 +
  673.59 +typedef struct gz_stream {
  673.60 +    z_stream stream;
  673.61 +    int      z_err;   /* error code for last stream operation */
  673.62 +    int      z_eof;   /* set if end of input file */
  673.63 +    FILE     *file;   /* .gz file */
  673.64 +    Byte     *inbuf;  /* input buffer */
  673.65 +    Byte     *outbuf; /* output buffer */
  673.66 +    uLong    crc;     /* crc32 of uncompressed data */
  673.67 +    char     *msg;    /* error message */
  673.68 +    char     *path;   /* path name for debugging only */
  673.69 +    int      transparent; /* 1 if input file is not a .gz file */
  673.70 +    char     mode;    /* 'w' or 'r' */
  673.71 +    z_off_t  start;   /* start of compressed data in file (header skipped) */
  673.72 +    z_off_t  in;      /* bytes into deflate or inflate */
  673.73 +    z_off_t  out;     /* bytes out of deflate or inflate */
  673.74 +    int      back;    /* one character push-back */
  673.75 +    int      last;    /* true if push-back is last character */
  673.76 +} gz_stream;
  673.77 +
  673.78 +
  673.79 +local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
  673.80 +local int do_flush        OF((gzFile file, int flush));
  673.81 +local int    get_byte     OF((gz_stream *s));
  673.82 +local void   check_header OF((gz_stream *s));
  673.83 +local int    destroy      OF((gz_stream *s));
  673.84 +local void   putLong      OF((FILE *file, uLong x));
  673.85 +local uLong  getLong      OF((gz_stream *s));
  673.86 +
  673.87 +/* ===========================================================================
  673.88 +     Opens a gzip (.gz) file for reading or writing. The mode parameter
  673.89 +   is as in fopen ("rb" or "wb"). The file is given either by file descriptor
  673.90 +   or path name (if fd == -1).
  673.91 +     gz_open returns NULL if the file could not be opened or if there was
  673.92 +   insufficient memory to allocate the (de)compression state; errno
  673.93 +   can be checked to distinguish the two cases (if errno is zero, the
  673.94 +   zlib error is Z_MEM_ERROR).
  673.95 +*/
  673.96 +local gzFile gz_open (path, mode, fd)
  673.97 +    const char *path;
  673.98 +    const char *mode;
  673.99 +    int  fd;
 673.100 +{
 673.101 +    int err;
 673.102 +    int level = Z_DEFAULT_COMPRESSION; /* compression level */
 673.103 +    int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
 673.104 +    char *p = (char*)mode;
 673.105 +    gz_stream *s;
 673.106 +    char fmode[80]; /* copy of mode, without the compression level */
 673.107 +    char *m = fmode;
 673.108 +
 673.109 +    if (!path || !mode) return Z_NULL;
 673.110 +
 673.111 +    s = (gz_stream *)ALLOC(sizeof(gz_stream));
 673.112 +    if (!s) return Z_NULL;
 673.113 +
 673.114 +    s->stream.zalloc = (alloc_func)0;
 673.115 +    s->stream.zfree = (free_func)0;
 673.116 +    s->stream.opaque = (voidpf)0;
 673.117 +    s->stream.next_in = s->inbuf = Z_NULL;
 673.118 +    s->stream.next_out = s->outbuf = Z_NULL;
 673.119 +    s->stream.avail_in = s->stream.avail_out = 0;
 673.120 +    s->file = NULL;
 673.121 +    s->z_err = Z_OK;
 673.122 +    s->z_eof = 0;
 673.123 +    s->in = 0;
 673.124 +    s->out = 0;
 673.125 +    s->back = EOF;
 673.126 +    s->crc = crc32(0L, Z_NULL, 0);
 673.127 +    s->msg = NULL;
 673.128 +    s->transparent = 0;
 673.129 +
 673.130 +    s->path = (char*)ALLOC(strlen(path)+1);
 673.131 +    if (s->path == NULL) {
 673.132 +        return destroy(s), (gzFile)Z_NULL;
 673.133 +    }
 673.134 +    strcpy(s->path, path); /* do this early for debugging */
 673.135 +
 673.136 +    s->mode = '\0';
 673.137 +    do {
 673.138 +        if (*p == 'r') s->mode = 'r';
 673.139 +        if (*p == 'w' || *p == 'a') s->mode = 'w';
 673.140 +        if (*p >= '0' && *p <= '9') {
 673.141 +            level = *p - '0';
 673.142 +        } else if (*p == 'f') {
 673.143 +          strategy = Z_FILTERED;
 673.144 +        } else if (*p == 'h') {
 673.145 +          strategy = Z_HUFFMAN_ONLY;
 673.146 +        } else if (*p == 'R') {
 673.147 +          strategy = Z_RLE;
 673.148 +        } else {
 673.149 +            *m++ = *p; /* copy the mode */
 673.150 +        }
 673.151 +    } while (*p++ && m != fmode + sizeof(fmode));
 673.152 +    if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
 673.153 +
 673.154 +    if (s->mode == 'w') {
 673.155 +#ifdef NO_GZCOMPRESS
 673.156 +        err = Z_STREAM_ERROR;
 673.157 +#else
 673.158 +        err = deflateInit2(&(s->stream), level,
 673.159 +                           Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
 673.160 +        /* windowBits is passed < 0 to suppress zlib header */
 673.161 +
 673.162 +        s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
 673.163 +#endif
 673.164 +        if (err != Z_OK || s->outbuf == Z_NULL) {
 673.165 +            return destroy(s), (gzFile)Z_NULL;
 673.166 +        }
 673.167 +    } else {
 673.168 +        s->stream.next_in  = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
 673.169 +
 673.170 +        err = inflateInit2(&(s->stream), -MAX_WBITS);
 673.171 +        /* windowBits is passed < 0 to tell that there is no zlib header.
 673.172 +         * Note that in this case inflate *requires* an extra "dummy" byte
 673.173 +         * after the compressed stream in order to complete decompression and
 673.174 +         * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
 673.175 +         * present after the compressed stream.
 673.176 +         */
 673.177 +        if (err != Z_OK || s->inbuf == Z_NULL) {
 673.178 +            return destroy(s), (gzFile)Z_NULL;
 673.179 +        }
 673.180 +    }
 673.181 +    s->stream.avail_out = Z_BUFSIZE;
 673.182 +
 673.183 +    errno = 0;
 673.184 +    s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
 673.185 +
 673.186 +    if (s->file == NULL) {
 673.187 +        return destroy(s), (gzFile)Z_NULL;
 673.188 +    }
 673.189 +    if (s->mode == 'w') {
 673.190 +        /* Write a very simple .gz header:
 673.191 +         */
 673.192 +        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
 673.193 +             Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
 673.194 +        s->start = 10L;
 673.195 +        /* We use 10L instead of ftell(s->file) to because ftell causes an
 673.196 +         * fflush on some systems. This version of the library doesn't use
 673.197 +         * start anyway in write mode, so this initialization is not
 673.198 +         * necessary.
 673.199 +         */
 673.200 +    } else {
 673.201 +        check_header(s); /* skip the .gz header */
 673.202 +        s->start = ftell(s->file) - s->stream.avail_in;
 673.203 +    }
 673.204 +
 673.205 +    return (gzFile)s;
 673.206 +}
 673.207 +
 673.208 +/* ===========================================================================
 673.209 +     Opens a gzip (.gz) file for reading or writing.
 673.210 +*/
 673.211 +gzFile ZEXPORT gzopen (path, mode)
 673.212 +    const char *path;
 673.213 +    const char *mode;
 673.214 +{
 673.215 +    return gz_open (path, mode, -1);
 673.216 +}
 673.217 +
 673.218 +/* ===========================================================================
 673.219 +     Associate a gzFile with the file descriptor fd. fd is not dup'ed here
 673.220 +   to mimic the behavio(u)r of fdopen.
 673.221 +*/
 673.222 +gzFile ZEXPORT gzdopen (fd, mode)
 673.223 +    int fd;
 673.224 +    const char *mode;
 673.225 +{
 673.226 +    char name[46];      /* allow for up to 128-bit integers */
 673.227 +
 673.228 +    if (fd < 0) return (gzFile)Z_NULL;
 673.229 +    sprintf(name, "<fd:%d>", fd); /* for debugging */
 673.230 +
 673.231 +    return gz_open (name, mode, fd);
 673.232 +}
 673.233 +
 673.234 +/* ===========================================================================
 673.235 + * Update the compression level and strategy
 673.236 + */
 673.237 +int ZEXPORT gzsetparams (file, level, strategy)
 673.238 +    gzFile file;
 673.239 +    int level;
 673.240 +    int strategy;
 673.241 +{
 673.242 +    gz_stream *s = (gz_stream*)file;
 673.243 +
 673.244 +    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
 673.245 +
 673.246 +    /* Make room to allow flushing */
 673.247 +    if (s->stream.avail_out == 0) {
 673.248 +
 673.249 +        s->stream.next_out = s->outbuf;
 673.250 +        if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
 673.251 +            s->z_err = Z_ERRNO;
 673.252 +        }
 673.253 +        s->stream.avail_out = Z_BUFSIZE;
 673.254 +    }
 673.255 +
 673.256 +    return deflateParams (&(s->stream), level, strategy);
 673.257 +}
 673.258 +
 673.259 +/* ===========================================================================
 673.260 +     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
 673.261 +   for end of file.
 673.262 +   IN assertion: the stream s has been sucessfully opened for reading.
 673.263 +*/
 673.264 +local int get_byte(s)
 673.265 +    gz_stream *s;
 673.266 +{
 673.267 +    if (s->z_eof) return EOF;
 673.268 +    if (s->stream.avail_in == 0) {
 673.269 +        errno = 0;
 673.270 +        s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
 673.271 +        if (s->stream.avail_in == 0) {
 673.272 +            s->z_eof = 1;
 673.273 +            if (ferror(s->file)) s->z_err = Z_ERRNO;
 673.274 +            return EOF;
 673.275 +        }
 673.276 +        s->stream.next_in = s->inbuf;
 673.277 +    }
 673.278 +    s->stream.avail_in--;
 673.279 +    return *(s->stream.next_in)++;
 673.280 +}
 673.281 +
 673.282 +/* ===========================================================================
 673.283 +      Check the gzip header of a gz_stream opened for reading. Set the stream
 673.284 +    mode to transparent if the gzip magic header is not present; set s->err
 673.285 +    to Z_DATA_ERROR if the magic header is present but the rest of the header
 673.286 +    is incorrect.
 673.287 +    IN assertion: the stream s has already been created sucessfully;
 673.288 +       s->stream.avail_in is zero for the first time, but may be non-zero
 673.289 +       for concatenated .gz files.
 673.290 +*/
 673.291 +local void check_header(s)
 673.292 +    gz_stream *s;
 673.293 +{
 673.294 +    int method; /* method byte */
 673.295 +    int flags;  /* flags byte */
 673.296 +    uInt len;
 673.297 +    int c;
 673.298 +
 673.299 +    /* Assure two bytes in the buffer so we can peek ahead -- handle case
 673.300 +       where first byte of header is at the end of the buffer after the last
 673.301 +       gzip segment */
 673.302 +    len = s->stream.avail_in;
 673.303 +    if (len < 2) {
 673.304 +        if (len) s->inbuf[0] = s->stream.next_in[0];
 673.305 +        errno = 0;
 673.306 +        len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
 673.307 +        if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
 673.308 +        s->stream.avail_in += len;
 673.309 +        s->stream.next_in = s->inbuf;
 673.310 +        if (s->stream.avail_in < 2) {
 673.311 +            s->transparent = s->stream.avail_in;
 673.312 +            return;
 673.313 +        }
 673.314 +    }
 673.315 +
 673.316 +    /* Peek ahead to check the gzip magic header */
 673.317 +    if (s->stream.next_in[0] != gz_magic[0] ||
 673.318 +        s->stream.next_in[1] != gz_magic[1]) {
 673.319 +        s->transparent = 1;
 673.320 +        return;
 673.321 +    }
 673.322 +    s->stream.avail_in -= 2;
 673.323 +    s->stream.next_in += 2;
 673.324 +
 673.325 +    /* Check the rest of the gzip header */
 673.326 +    method = get_byte(s);
 673.327 +    flags = get_byte(s);
 673.328 +    if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
 673.329 +        s->z_err = Z_DATA_ERROR;
 673.330 +        return;
 673.331 +    }
 673.332 +
 673.333 +    /* Discard time, xflags and OS code: */
 673.334 +    for (len = 0; len < 6; len++) (void)get_byte(s);
 673.335 +
 673.336 +    if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
 673.337 +        len  =  (uInt)get_byte(s);
 673.338 +        len += ((uInt)get_byte(s))<<8;
 673.339 +        /* len is garbage if EOF but the loop below will quit anyway */
 673.340 +        while (len-- != 0 && get_byte(s) != EOF) ;
 673.341 +    }
 673.342 +    if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
 673.343 +        while ((c = get_byte(s)) != 0 && c != EOF) ;
 673.344 +    }
 673.345 +    if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
 673.346 +        while ((c = get_byte(s)) != 0 && c != EOF) ;
 673.347 +    }
 673.348 +    if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
 673.349 +        for (len = 0; len < 2; len++) (void)get_byte(s);
 673.350 +    }
 673.351 +    s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
 673.352 +}
 673.353 +
 673.354 + /* ===========================================================================
 673.355 + * Cleanup then free the given gz_stream. Return a zlib error code.
 673.356 +   Try freeing in the reverse order of allocations.
 673.357 + */
 673.358 +local int destroy (s)
 673.359 +    gz_stream *s;
 673.360 +{
 673.361 +    int err = Z_OK;
 673.362 +
 673.363 +    if (!s) return Z_STREAM_ERROR;
 673.364 +
 673.365 +    TRYFREE(s->msg);
 673.366 +
 673.367 +    if (s->stream.state != NULL) {
 673.368 +        if (s->mode == 'w') {
 673.369 +#ifdef NO_GZCOMPRESS
 673.370 +            err = Z_STREAM_ERROR;
 673.371 +#else
 673.372 +            err = deflateEnd(&(s->stream));
 673.373 +#endif
 673.374 +        } else if (s->mode == 'r') {
 673.375 +            err = inflateEnd(&(s->stream));
 673.376 +        }
 673.377 +    }
 673.378 +    if (s->file != NULL && fclose(s->file)) {
 673.379 +#ifdef ESPIPE
 673.380 +        if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
 673.381 +#endif
 673.382 +            err = Z_ERRNO;
 673.383 +    }
 673.384 +    if (s->z_err < 0) err = s->z_err;
 673.385 +
 673.386 +    TRYFREE(s->inbuf);
 673.387 +    TRYFREE(s->outbuf);
 673.388 +    TRYFREE(s->path);
 673.389 +    TRYFREE(s);
 673.390 +    return err;
 673.391 +}
 673.392 +
 673.393 +/* ===========================================================================
 673.394 +     Reads the given number of uncompressed bytes from the compressed file.
 673.395 +   gzread returns the number of bytes actually read (0 for end of file).
 673.396 +*/
 673.397 +int ZEXPORT gzread (file, buf, len)
 673.398 +    gzFile file;
 673.399 +    voidp buf;
 673.400 +    unsigned len;
 673.401 +{
 673.402 +    gz_stream *s = (gz_stream*)file;
 673.403 +    Bytef *start = (Bytef*)buf; /* starting point for crc computation */
 673.404 +    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */
 673.405 +
 673.406 +    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
 673.407 +
 673.408 +    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
 673.409 +    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */
 673.410 +
 673.411 +    next_out = (Byte*)buf;
 673.412 +    s->stream.next_out = (Bytef*)buf;
 673.413 +    s->stream.avail_out = len;
 673.414 +
 673.415 +    if (s->stream.avail_out && s->back != EOF) {
 673.416 +        *next_out++ = s->back;
 673.417 +        s->stream.next_out++;
 673.418 +        s->stream.avail_out--;
 673.419 +        s->back = EOF;
 673.420 +        s->out++;
 673.421 +        start++;
 673.422 +        if (s->last) {
 673.423 +            s->z_err = Z_STREAM_END;
 673.424 +            return 1;
 673.425 +        }
 673.426 +    }
 673.427 +
 673.428 +    while (s->stream.avail_out != 0) {
 673.429 +
 673.430 +        if (s->transparent) {
 673.431 +            /* Copy first the lookahead bytes: */
 673.432 +            uInt n = s->stream.avail_in;
 673.433 +            if (n > s->stream.avail_out) n = s->stream.avail_out;
 673.434 +            if (n > 0) {
 673.435 +                zmemcpy(s->stream.next_out, s->stream.next_in, n);
 673.436 +                next_out += n;
 673.437 +                s->stream.next_out = next_out;
 673.438 +                s->stream.next_in   += n;
 673.439 +                s->stream.avail_out -= n;
 673.440 +                s->stream.avail_in  -= n;
 673.441 +            }
 673.442 +            if (s->stream.avail_out > 0) {
 673.443 +                s->stream.avail_out -=
 673.444 +                    (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
 673.445 +            }
 673.446 +            len -= s->stream.avail_out;
 673.447 +            s->in  += len;
 673.448 +            s->out += len;
 673.449 +            if (len == 0) s->z_eof = 1;
 673.450 +            return (int)len;
 673.451 +        }
 673.452 +        if (s->stream.avail_in == 0 && !s->z_eof) {
 673.453 +
 673.454 +            errno = 0;
 673.455 +            s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
 673.456 +            if (s->stream.avail_in == 0) {
 673.457 +                s->z_eof = 1;
 673.458 +                if (ferror(s->file)) {
 673.459 +                    s->z_err = Z_ERRNO;
 673.460 +                    break;
 673.461 +                }
 673.462 +            }
 673.463 +            s->stream.next_in = s->inbuf;
 673.464 +        }
 673.465 +        s->in += s->stream.avail_in;
 673.466 +        s->out += s->stream.avail_out;
 673.467 +        s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
 673.468 +        s->in -= s->stream.avail_in;
 673.469 +        s->out -= s->stream.avail_out;
 673.470 +
 673.471 +        if (s->z_err == Z_STREAM_END) {
 673.472 +            /* Check CRC and original size */
 673.473 +            s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
 673.474 +            start = s->stream.next_out;
 673.475 +
 673.476 +            if (getLong(s) != s->crc) {
 673.477 +                s->z_err = Z_DATA_ERROR;
 673.478 +            } else {
 673.479 +                (void)getLong(s);
 673.480 +                /* The uncompressed length returned by above getlong() may be
 673.481 +                 * different from s->out in case of concatenated .gz files.
 673.482 +                 * Check for such files:
 673.483 +                 */
 673.484 +                check_header(s);
 673.485 +                if (s->z_err == Z_OK) {
 673.486 +                    inflateReset(&(s->stream));
 673.487 +                    s->crc = crc32(0L, Z_NULL, 0);
 673.488 +                }
 673.489 +            }
 673.490 +        }
 673.491 +        if (s->z_err != Z_OK || s->z_eof) break;
 673.492 +    }
 673.493 +    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
 673.494 +
 673.495 +    if (len == s->stream.avail_out &&
 673.496 +        (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
 673.497 +        return -1;
 673.498 +    return (int)(len - s->stream.avail_out);
 673.499 +}
 673.500 +
 673.501 +
 673.502 +/* ===========================================================================
 673.503 +      Reads one byte from the compressed file. gzgetc returns this byte
 673.504 +   or -1 in case of end of file or error.
 673.505 +*/
 673.506 +int ZEXPORT gzgetc(file)
 673.507 +    gzFile file;
 673.508 +{
 673.509 +    unsigned char c;
 673.510 +
 673.511 +    return gzread(file, &c, 1) == 1 ? c : -1;
 673.512 +}
 673.513 +
 673.514 +
 673.515 +/* ===========================================================================
 673.516 +      Push one byte back onto the stream.
 673.517 +*/
 673.518 +int ZEXPORT gzungetc(c, file)
 673.519 +    int c;
 673.520 +    gzFile file;
 673.521 +{
 673.522 +    gz_stream *s = (gz_stream*)file;
 673.523 +
 673.524 +    if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
 673.525 +    s->back = c;
 673.526 +    s->out--;
 673.527 +    s->last = (s->z_err == Z_STREAM_END);
 673.528 +    if (s->last) s->z_err = Z_OK;
 673.529 +    s->z_eof = 0;
 673.530 +    return c;
 673.531 +}
 673.532 +
 673.533 +
 673.534 +/* ===========================================================================
 673.535 +      Reads bytes from the compressed file until len-1 characters are
 673.536 +   read, or a newline character is read and transferred to buf, or an
 673.537 +   end-of-file condition is encountered.  The string is then terminated
 673.538 +   with a null character.
 673.539 +      gzgets returns buf, or Z_NULL in case of error.
 673.540 +
 673.541 +      The current implementation is not optimized at all.
 673.542 +*/
 673.543 +char * ZEXPORT gzgets(file, buf, len)
 673.544 +    gzFile file;
 673.545 +    char *buf;
 673.546 +    int len;
 673.547 +{
 673.548 +    char *b = buf;
 673.549 +    if (buf == Z_NULL || len <= 0) return Z_NULL;
 673.550 +
 673.551 +    while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
 673.552 +    *buf = '\0';
 673.553 +    return b == buf && len > 0 ? Z_NULL : b;
 673.554 +}
 673.555 +
 673.556 +
 673.557 +#ifndef NO_GZCOMPRESS
 673.558 +/* ===========================================================================
 673.559 +     Writes the given number of uncompressed bytes into the compressed file.
 673.560 +   gzwrite returns the number of bytes actually written (0 in case of error).
 673.561 +*/
 673.562 +int ZEXPORT gzwrite (file, buf, len)
 673.563 +    gzFile file;
 673.564 +    voidpc buf;
 673.565 +    unsigned len;
 673.566 +{
 673.567 +    gz_stream *s = (gz_stream*)file;
 673.568 +
 673.569 +    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
 673.570 +
 673.571 +    s->stream.next_in = (Bytef*)buf;
 673.572 +    s->stream.avail_in = len;
 673.573 +
 673.574 +    while (s->stream.avail_in != 0) {
 673.575 +
 673.576 +        if (s->stream.avail_out == 0) {
 673.577 +
 673.578 +            s->stream.next_out = s->outbuf;
 673.579 +            if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
 673.580 +                s->z_err = Z_ERRNO;
 673.581 +                break;
 673.582 +            }
 673.583 +            s->stream.avail_out = Z_BUFSIZE;
 673.584 +        }
 673.585 +        s->in += s->stream.avail_in;
 673.586 +        s->out += s->stream.avail_out;
 673.587 +        s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
 673.588 +        s->in -= s->stream.avail_in;
 673.589 +        s->out -= s->stream.avail_out;
 673.590 +        if (s->z_err != Z_OK) break;
 673.591 +    }
 673.592 +    s->crc = crc32(s->crc, (const Bytef *)buf, len);
 673.593 +
 673.594 +    return (int)(len - s->stream.avail_in);
 673.595 +}
 673.596 +
 673.597 +
 673.598 +/* ===========================================================================
 673.599 +     Converts, formats, and writes the args to the compressed file under
 673.600 +   control of the format string, as in fprintf. gzprintf returns the number of
 673.601 +   uncompressed bytes actually written (0 in case of error).
 673.602 +*/
 673.603 +#ifdef STDC
 673.604 +#include <stdarg.h>
 673.605 +
 673.606 +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
 673.607 +{
 673.608 +    char buf[Z_PRINTF_BUFSIZE];
 673.609 +    va_list va;
 673.610 +    int len;
 673.611 +
 673.612 +    buf[sizeof(buf) - 1] = 0;
 673.613 +    va_start(va, format);
 673.614 +#ifdef NO_vsnprintf
 673.615 +#  ifdef HAS_vsprintf_void
 673.616 +    (void)vsprintf(buf, format, va);
 673.617 +    va_end(va);
 673.618 +    for (len = 0; len < sizeof(buf); len++)
 673.619 +        if (buf[len] == 0) break;
 673.620 +#  else
 673.621 +    len = vsprintf(buf, format, va);
 673.622 +    va_end(va);
 673.623 +#  endif
 673.624 +#else
 673.625 +#  ifdef HAS_vsnprintf_void
 673.626 +    (void)vsnprintf(buf, sizeof(buf), format, va);
 673.627 +    va_end(va);
 673.628 +    len = strlen(buf);
 673.629 +#  else
 673.630 +    len = vsnprintf(buf, sizeof(buf), format, va);
 673.631 +    va_end(va);
 673.632 +#  endif
 673.633 +#endif
 673.634 +    if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
 673.635 +        return 0;
 673.636 +    return gzwrite(file, buf, (unsigned)len);
 673.637 +}
 673.638 +#else /* not ANSI C */
 673.639 +
 673.640 +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
 673.641 +                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
 673.642 +    gzFile file;
 673.643 +    const char *format;
 673.644 +    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
 673.645 +        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
 673.646 +{
 673.647 +    char buf[Z_PRINTF_BUFSIZE];
 673.648 +    int len;
 673.649 +
 673.650 +    buf[sizeof(buf) - 1] = 0;
 673.651 +#ifdef NO_snprintf
 673.652 +#  ifdef HAS_sprintf_void
 673.653 +    sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
 673.654 +            a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
 673.655 +    for (len = 0; len < sizeof(buf); len++)
 673.656 +        if (buf[len] == 0) break;
 673.657 +#  else
 673.658 +    len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
 673.659 +                a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
 673.660 +#  endif
 673.661 +#else
 673.662 +#  ifdef HAS_snprintf_void
 673.663 +    snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
 673.664 +             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
 673.665 +    len = strlen(buf);
 673.666 +#  else
 673.667 +    len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
 673.668 +                 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
 673.669 +#  endif
 673.670 +#endif
 673.671 +    if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
 673.672 +        return 0;
 673.673 +    return gzwrite(file, buf, len);
 673.674 +}
 673.675 +#endif
 673.676 +
 673.677 +/* ===========================================================================
 673.678 +      Writes c, converted to an unsigned char, into the compressed file.
 673.679 +   gzputc returns the value that was written, or -1 in case of error.
 673.680 +*/
 673.681 +int ZEXPORT gzputc(file, c)
 673.682 +    gzFile file;
 673.683 +    int c;
 673.684 +{
 673.685 +    unsigned char cc = (unsigned char) c; /* required for big endian systems */
 673.686 +
 673.687 +    return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
 673.688 +}
 673.689 +
 673.690 +
 673.691 +/* ===========================================================================
 673.692 +      Writes the given null-terminated string to the compressed file, excluding
 673.693 +   the terminating null character.
 673.694 +      gzputs returns the number of characters written, or -1 in case of error.
 673.695 +*/
 673.696 +int ZEXPORT gzputs(file, s)
 673.697 +    gzFile file;
 673.698 +    const char *s;
 673.699 +{
 673.700 +    return gzwrite(file, (char*)s, (unsigned)strlen(s));
 673.701 +}
 673.702 +
 673.703 +
 673.704 +/* ===========================================================================
 673.705 +     Flushes all pending output into the compressed file. The parameter
 673.706 +   flush is as in the deflate() function.
 673.707 +*/
 673.708 +local int do_flush (file, flush)
 673.709 +    gzFile file;
 673.710 +    int flush;
 673.711 +{
 673.712 +    uInt len;
 673.713 +    int done = 0;
 673.714 +    gz_stream *s = (gz_stream*)file;
 673.715 +
 673.716 +    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
 673.717 +
 673.718 +    s->stream.avail_in = 0; /* should be zero already anyway */
 673.719 +
 673.720 +    for (;;) {
 673.721 +        len = Z_BUFSIZE - s->stream.avail_out;
 673.722 +
 673.723 +        if (len != 0) {
 673.724 +            if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
 673.725 +                s->z_err = Z_ERRNO;
 673.726 +                return Z_ERRNO;
 673.727 +            }
 673.728 +            s->stream.next_out = s->outbuf;
 673.729 +            s->stream.avail_out = Z_BUFSIZE;
 673.730 +        }
 673.731 +        if (done) break;
 673.732 +        s->out += s->stream.avail_out;
 673.733 +        s->z_err = deflate(&(s->stream), flush);
 673.734 +        s->out -= s->stream.avail_out;
 673.735 +
 673.736 +        /* Ignore the second of two consecutive flushes: */
 673.737 +        if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
 673.738 +
 673.739 +        /* deflate has finished flushing only when it hasn't used up
 673.740 +         * all the available space in the output buffer:
 673.741 +         */
 673.742 +        done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
 673.743 +
 673.744 +        if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
 673.745 +    }
 673.746 +    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
 673.747 +}
 673.748 +
 673.749 +int ZEXPORT gzflush (file, flush)
 673.750 +     gzFile file;
 673.751 +     int flush;
 673.752 +{
 673.753 +    gz_stream *s = (gz_stream*)file;
 673.754 +    int err = do_flush (file, flush);
 673.755 +
 673.756 +    if (err) return err;
 673.757 +    fflush(s->file);
 673.758 +    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
 673.759 +}
 673.760 +#endif /* NO_GZCOMPRESS */
 673.761 +
 673.762 +/* ===========================================================================
 673.763 +      Sets the starting position for the next gzread or gzwrite on the given
 673.764 +   compressed file. The offset represents a number of bytes in the
 673.765 +      gzseek returns the resulting offset location as measured in bytes from
 673.766 +   the beginning of the uncompressed stream, or -1 in case of error.
 673.767 +      SEEK_END is not implemented, returns error.
 673.768 +      In this version of the library, gzseek can be extremely slow.
 673.769 +*/
 673.770 +z_off_t ZEXPORT gzseek (file, offset, whence)
 673.771 +    gzFile file;
 673.772 +    z_off_t offset;
 673.773 +    int whence;
 673.774 +{
 673.775 +    gz_stream *s = (gz_stream*)file;
 673.776 +
 673.777 +    if (s == NULL || whence == SEEK_END ||
 673.778 +        s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
 673.779 +        return -1L;
 673.780 +    }
 673.781 +
 673.782 +    if (s->mode == 'w') {
 673.783 +#ifdef NO_GZCOMPRESS
 673.784 +        return -1L;
 673.785 +#else
 673.786 +        if (whence == SEEK_SET) {
 673.787 +            offset -= s->in;
 673.788 +        }
 673.789 +        if (offset < 0) return -1L;
 673.790 +
 673.791 +        /* At this point, offset is the number of zero bytes to write. */
 673.792 +        if (s->inbuf == Z_NULL) {
 673.793 +            s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
 673.794 +            if (s->inbuf == Z_NULL) return -1L;
 673.795 +            zmemzero(s->inbuf, Z_BUFSIZE);
 673.796 +        }
 673.797 +        while (offset > 0)  {
 673.798 +            uInt size = Z_BUFSIZE;
 673.799 +            if (offset < Z_BUFSIZE) size = (uInt)offset;
 673.800 +
 673.801 +            size = gzwrite(file, s->inbuf, size);
 673.802 +            if (size == 0) return -1L;
 673.803 +
 673.804 +            offset -= size;
 673.805 +        }
 673.806 +        return s->in;
 673.807 +#endif
 673.808 +    }
 673.809 +    /* Rest of function is for reading only */
 673.810 +
 673.811 +    /* compute absolute position */
 673.812 +    if (whence == SEEK_CUR) {
 673.813 +        offset += s->out;
 673.814 +    }
 673.815 +    if (offset < 0) return -1L;
 673.816 +
 673.817 +    if (s->transparent) {
 673.818 +        /* map to fseek */
 673.819 +        s->back = EOF;
 673.820 +        s->stream.avail_in = 0;
 673.821 +        s->stream.next_in = s->inbuf;
 673.822 +        if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
 673.823 +
 673.824 +        s->in = s->out = offset;
 673.825 +        return offset;
 673.826 +    }
 673.827 +
 673.828 +    /* For a negative seek, rewind and use positive seek */
 673.829 +    if (offset >= s->out) {
 673.830 +        offset -= s->out;
 673.831 +    } else if (gzrewind(file) < 0) {
 673.832 +        return -1L;
 673.833 +    }
 673.834 +    /* offset is now the number of bytes to skip. */
 673.835 +
 673.836 +    if (offset != 0 && s->outbuf == Z_NULL) {
 673.837 +        s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
 673.838 +        if (s->outbuf == Z_NULL) return -1L;
 673.839 +    }
 673.840 +    if (offset && s->back != EOF) {
 673.841 +        s->back = EOF;
 673.842 +        s->out++;
 673.843 +        offset--;
 673.844 +        if (s->last) s->z_err = Z_STREAM_END;
 673.845 +    }
 673.846 +    while (offset > 0)  {
 673.847 +        int size = Z_BUFSIZE;
 673.848 +        if (offset < Z_BUFSIZE) size = (int)offset;
 673.849 +
 673.850 +        size = gzread(file, s->outbuf, (uInt)size);
 673.851 +        if (size <= 0) return -1L;
 673.852 +        offset -= size;
 673.853 +    }
 673.854 +    return s->out;
 673.855 +}
 673.856 +
 673.857 +/* ===========================================================================
 673.858 +     Rewinds input file.
 673.859 +*/
 673.860 +int ZEXPORT gzrewind (file)
 673.861 +    gzFile file;
 673.862 +{
 673.863 +    gz_stream *s = (gz_stream*)file;
 673.864 +
 673.865 +    if (s == NULL || s->mode != 'r') return -1;
 673.866 +
 673.867 +    s->z_err = Z_OK;
 673.868 +    s->z_eof = 0;
 673.869 +    s->back = EOF;
 673.870 +    s->stream.avail_in = 0;
 673.871 +    s->stream.next_in = s->inbuf;
 673.872 +    s->crc = crc32(0L, Z_NULL, 0);
 673.873 +    if (!s->transparent) (void)inflateReset(&s->stream);
 673.874 +    s->in = 0;
 673.875 +    s->out = 0;
 673.876 +    return fseek(s->file, s->start, SEEK_SET);
 673.877 +}
 673.878 +
 673.879 +/* ===========================================================================
 673.880 +     Returns the starting position for the next gzread or gzwrite on the
 673.881 +   given compressed file. This position represents a number of bytes in the
 673.882 +   uncompressed data stream.
 673.883 +*/
 673.884 +z_off_t ZEXPORT gztell (file)
 673.885 +    gzFile file;
 673.886 +{
 673.887 +    return gzseek(file, 0L, SEEK_CUR);
 673.888 +}
 673.889 +
 673.890 +/* ===========================================================================
 673.891 +     Returns 1 when EOF has previously been detected reading the given
 673.892 +   input stream, otherwise zero.
 673.893 +*/
 673.894 +int ZEXPORT gzeof (file)
 673.895 +    gzFile file;
 673.896 +{
 673.897 +    gz_stream *s = (gz_stream*)file;
 673.898 +
 673.899 +    /* With concatenated compressed files that can have embedded
 673.900 +     * crc trailers, z_eof is no longer the only/best indicator of EOF
 673.901 +     * on a gz_stream. Handle end-of-stream error explicitly here.
 673.902 +     */
 673.903 +    if (s == NULL || s->mode != 'r') return 0;
 673.904 +    if (s->z_eof) return 1;
 673.905 +    return s->z_err == Z_STREAM_END;
 673.906 +}
 673.907 +
 673.908 +/* ===========================================================================
 673.909 +     Returns 1 if reading and doing so transparently, otherwise zero.
 673.910 +*/
 673.911 +int ZEXPORT gzdirect (file)
 673.912 +    gzFile file;
 673.913 +{
 673.914 +    gz_stream *s = (gz_stream*)file;
 673.915 +
 673.916 +    if (s == NULL || s->mode != 'r') return 0;
 673.917 +    return s->transparent;
 673.918 +}
 673.919 +
 673.920 +/* ===========================================================================
 673.921 +   Outputs a long in LSB order to the given file
 673.922 +*/
 673.923 +local void putLong (file, x)
 673.924 +    FILE *file;
 673.925 +    uLong x;
 673.926 +{
 673.927 +    int n;
 673.928 +    for (n = 0; n < 4; n++) {
 673.929 +        fputc((int)(x & 0xff), file);
 673.930 +        x >>= 8;
 673.931 +    }
 673.932 +}
 673.933 +
 673.934 +/* ===========================================================================
 673.935 +   Reads a long in LSB order from the given gz_stream. Sets z_err in case
 673.936 +   of error.
 673.937 +*/
 673.938 +local uLong getLong (s)
 673.939 +    gz_stream *s;
 673.940 +{
 673.941 +    uLong x = (uLong)get_byte(s);
 673.942 +    int c;
 673.943 +
 673.944 +    x += ((uLong)get_byte(s))<<8;
 673.945 +    x += ((uLong)get_byte(s))<<16;
 673.946 +    c = get_byte(s);
 673.947 +    if (c == EOF) s->z_err = Z_DATA_ERROR;
 673.948 +    x += ((uLong)c)<<24;
 673.949 +    return x;
 673.950 +}
 673.951 +
 673.952 +/* ===========================================================================
 673.953 +     Flushes all pending output if necessary, closes the compressed file
 673.954 +   and deallocates all the (de)compression state.
 673.955 +*/
 673.956 +int ZEXPORT gzclose (file)
 673.957 +    gzFile file;
 673.958 +{
 673.959 +    gz_stream *s = (gz_stream*)file;
 673.960 +
 673.961 +    if (s == NULL) return Z_STREAM_ERROR;
 673.962 +
 673.963 +    if (s->mode == 'w') {
 673.964 +#ifdef NO_GZCOMPRESS
 673.965 +        return Z_STREAM_ERROR;
 673.966 +#else
 673.967 +        if (do_flush (file, Z_FINISH) != Z_OK)
 673.968 +            return destroy((gz_stream*)file);
 673.969 +
 673.970 +        putLong (s->file, s->crc);
 673.971 +        putLong (s->file, (uLong)(s->in & 0xffffffff));
 673.972 +#endif
 673.973 +    }
 673.974 +    return destroy((gz_stream*)file);
 673.975 +}
 673.976 +
 673.977 +#ifdef STDC
 673.978 +#  define zstrerror(errnum) strerror(errnum)
 673.979 +#else
 673.980 +#  define zstrerror(errnum) ""
 673.981 +#endif
 673.982 +
 673.983 +/* ===========================================================================
 673.984 +     Returns the error message for the last error which occurred on the
 673.985 +   given compressed file. errnum is set to zlib error number. If an
 673.986 +   error occurred in the file system and not in the compression library,
 673.987 +   errnum is set to Z_ERRNO and the application may consult errno
 673.988 +   to get the exact error code.
 673.989 +*/
 673.990 +const char * ZEXPORT gzerror (file, errnum)
 673.991 +    gzFile file;
 673.992 +    int *errnum;
 673.993 +{
 673.994 +    char *m;
 673.995 +    gz_stream *s = (gz_stream*)file;
 673.996 +
 673.997 +    if (s == NULL) {
 673.998 +        *errnum = Z_STREAM_ERROR;
 673.999 +        return (const char*)ERR_MSG(Z_STREAM_ERROR);
673.1000 +    }
673.1001 +    *errnum = s->z_err;
673.1002 +    if (*errnum == Z_OK) return (const char*)"";
673.1003 +
673.1004 +    m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
673.1005 +
673.1006 +    if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
673.1007 +
673.1008 +    TRYFREE(s->msg);
673.1009 +    s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
673.1010 +    if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
673.1011 +    strcpy(s->msg, s->path);
673.1012 +    strcat(s->msg, ": ");
673.1013 +    strcat(s->msg, m);
673.1014 +    return (const char*)s->msg;
673.1015 +}
673.1016 +
673.1017 +/* ===========================================================================
673.1018 +     Clear the error and end-of-file flags, and do the same for the real file.
673.1019 +*/
673.1020 +void ZEXPORT gzclearerr (file)
673.1021 +    gzFile file;
673.1022 +{
673.1023 +    gz_stream *s = (gz_stream*)file;
673.1024 +
673.1025 +    if (s == NULL) return;
673.1026 +    if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
673.1027 +    s->z_eof = 0;
673.1028 +    clearerr(s->file);
673.1029 +}
   674.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   674.2 +++ b/libs/zlib/infback.c	Sat Feb 01 19:58:19 2014 +0200
   674.3 @@ -0,0 +1,623 @@
   674.4 +/* infback.c -- inflate using a call-back interface
   674.5 + * Copyright (C) 1995-2005 Mark Adler
   674.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   674.7 + */
   674.8 +
   674.9 +/*
  674.10 +   This code is largely copied from inflate.c.  Normally either infback.o or
  674.11 +   inflate.o would be linked into an application--not both.  The interface
  674.12 +   with inffast.c is retained so that optimized assembler-coded versions of
  674.13 +   inflate_fast() can be used with either inflate.c or infback.c.
  674.14 + */
  674.15 +
  674.16 +#include "zutil.h"
  674.17 +#include "inftrees.h"
  674.18 +#include "inflate.h"
  674.19 +#include "inffast.h"
  674.20 +
  674.21 +/* function prototypes */
  674.22 +local void fixedtables OF((struct inflate_state FAR *state));
  674.23 +
  674.24 +/*
  674.25 +   strm provides memory allocation functions in zalloc and zfree, or
  674.26 +   Z_NULL to use the library memory allocation functions.
  674.27 +
  674.28 +   windowBits is in the range 8..15, and window is a user-supplied
  674.29 +   window and output buffer that is 2**windowBits bytes.
  674.30 + */
  674.31 +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
  674.32 +z_streamp strm;
  674.33 +int windowBits;
  674.34 +unsigned char FAR *window;
  674.35 +const char *version;
  674.36 +int stream_size;
  674.37 +{
  674.38 +    struct inflate_state FAR *state;
  674.39 +
  674.40 +    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
  674.41 +        stream_size != (int)(sizeof(z_stream)))
  674.42 +        return Z_VERSION_ERROR;
  674.43 +    if (strm == Z_NULL || window == Z_NULL ||
  674.44 +        windowBits < 8 || windowBits > 15)
  674.45 +        return Z_STREAM_ERROR;
  674.46 +    strm->msg = Z_NULL;                 /* in case we return an error */
  674.47 +    if (strm->zalloc == (alloc_func)0) {
  674.48 +        strm->zalloc = zcalloc;
  674.49 +        strm->opaque = (voidpf)0;
  674.50 +    }
  674.51 +    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
  674.52 +    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
  674.53 +                                               sizeof(struct inflate_state));
  674.54 +    if (state == Z_NULL) return Z_MEM_ERROR;
  674.55 +    Tracev((stderr, "inflate: allocated\n"));
  674.56 +    strm->state = (struct internal_state FAR *)state;
  674.57 +    state->dmax = 32768U;
  674.58 +    state->wbits = windowBits;
  674.59 +    state->wsize = 1U << windowBits;
  674.60 +    state->window = window;
  674.61 +    state->write = 0;
  674.62 +    state->whave = 0;
  674.63 +    return Z_OK;
  674.64 +}
  674.65 +
  674.66 +/*
  674.67 +   Return state with length and distance decoding tables and index sizes set to
  674.68 +   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
  674.69 +   If BUILDFIXED is defined, then instead this routine builds the tables the
  674.70 +   first time it's called, and returns those tables the first time and
  674.71 +   thereafter.  This reduces the size of the code by about 2K bytes, in
  674.72 +   exchange for a little execution time.  However, BUILDFIXED should not be
  674.73 +   used for threaded applications, since the rewriting of the tables and virgin
  674.74 +   may not be thread-safe.
  674.75 + */
  674.76 +local void fixedtables(state)
  674.77 +struct inflate_state FAR *state;
  674.78 +{
  674.79 +#ifdef BUILDFIXED
  674.80 +    static int virgin = 1;
  674.81 +    static code *lenfix, *distfix;
  674.82 +    static code fixed[544];
  674.83 +
  674.84 +    /* build fixed huffman tables if first call (may not be thread safe) */
  674.85 +    if (virgin) {
  674.86 +        unsigned sym, bits;
  674.87 +        static code *next;
  674.88 +
  674.89 +        /* literal/length table */
  674.90 +        sym = 0;
  674.91 +        while (sym < 144) state->lens[sym++] = 8;
  674.92 +        while (sym < 256) state->lens[sym++] = 9;
  674.93 +        while (sym < 280) state->lens[sym++] = 7;
  674.94 +        while (sym < 288) state->lens[sym++] = 8;
  674.95 +        next = fixed;
  674.96 +        lenfix = next;
  674.97 +        bits = 9;
  674.98 +        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
  674.99 +
 674.100 +        /* distance table */
 674.101 +        sym = 0;
 674.102 +        while (sym < 32) state->lens[sym++] = 5;
 674.103 +        distfix = next;
 674.104 +        bits = 5;
 674.105 +        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
 674.106 +
 674.107 +        /* do this just once */
 674.108 +        virgin = 0;
 674.109 +    }
 674.110 +#else /* !BUILDFIXED */
 674.111 +#   include "inffixed.h"
 674.112 +#endif /* BUILDFIXED */
 674.113 +    state->lencode = lenfix;
 674.114 +    state->lenbits = 9;
 674.115 +    state->distcode = distfix;
 674.116 +    state->distbits = 5;
 674.117 +}
 674.118 +
 674.119 +/* Macros for inflateBack(): */
 674.120 +
 674.121 +/* Load returned state from inflate_fast() */
 674.122 +#define LOAD() \
 674.123 +    do { \
 674.124 +        put = strm->next_out; \
 674.125 +        left = strm->avail_out; \
 674.126 +        next = strm->next_in; \
 674.127 +        have = strm->avail_in; \
 674.128 +        hold = state->hold; \
 674.129 +        bits = state->bits; \
 674.130 +    } while (0)
 674.131 +
 674.132 +/* Set state from registers for inflate_fast() */
 674.133 +#define RESTORE() \
 674.134 +    do { \
 674.135 +        strm->next_out = put; \
 674.136 +        strm->avail_out = left; \
 674.137 +        strm->next_in = next; \
 674.138 +        strm->avail_in = have; \
 674.139 +        state->hold = hold; \
 674.140 +        state->bits = bits; \
 674.141 +    } while (0)
 674.142 +
 674.143 +/* Clear the input bit accumulator */
 674.144 +#define INITBITS() \
 674.145 +    do { \
 674.146 +        hold = 0; \
 674.147 +        bits = 0; \
 674.148 +    } while (0)
 674.149 +
 674.150 +/* Assure that some input is available.  If input is requested, but denied,
 674.151 +   then return a Z_BUF_ERROR from inflateBack(). */
 674.152 +#define PULL() \
 674.153 +    do { \
 674.154 +        if (have == 0) { \
 674.155 +            have = in(in_desc, &next); \
 674.156 +            if (have == 0) { \
 674.157 +                next = Z_NULL; \
 674.158 +                ret = Z_BUF_ERROR; \
 674.159 +                goto inf_leave; \
 674.160 +            } \
 674.161 +        } \
 674.162 +    } while (0)
 674.163 +
 674.164 +/* Get a byte of input into the bit accumulator, or return from inflateBack()
 674.165 +   with an error if there is no input available. */
 674.166 +#define PULLBYTE() \
 674.167 +    do { \
 674.168 +        PULL(); \
 674.169 +        have--; \
 674.170 +        hold += (unsigned long)(*next++) << bits; \
 674.171 +        bits += 8; \
 674.172 +    } while (0)
 674.173 +
 674.174 +/* Assure that there are at least n bits in the bit accumulator.  If there is
 674.175 +   not enough available input to do that, then return from inflateBack() with
 674.176 +   an error. */
 674.177 +#define NEEDBITS(n) \
 674.178 +    do { \
 674.179 +        while (bits < (unsigned)(n)) \
 674.180 +            PULLBYTE(); \
 674.181 +    } while (0)
 674.182 +
 674.183 +/* Return the low n bits of the bit accumulator (n < 16) */
 674.184 +#define BITS(n) \
 674.185 +    ((unsigned)hold & ((1U << (n)) - 1))
 674.186 +
 674.187 +/* Remove n bits from the bit accumulator */
 674.188 +#define DROPBITS(n) \
 674.189 +    do { \
 674.190 +        hold >>= (n); \
 674.191 +        bits -= (unsigned)(n); \
 674.192 +    } while (0)
 674.193 +
 674.194 +/* Remove zero to seven bits as needed to go to a byte boundary */
 674.195 +#define BYTEBITS() \
 674.196 +    do { \
 674.197 +        hold >>= bits & 7; \
 674.198 +        bits -= bits & 7; \
 674.199 +    } while (0)
 674.200 +
 674.201 +/* Assure that some output space is available, by writing out the window
 674.202 +   if it's full.  If the write fails, return from inflateBack() with a
 674.203 +   Z_BUF_ERROR. */
 674.204 +#define ROOM() \
 674.205 +    do { \
 674.206 +        if (left == 0) { \
 674.207 +            put = state->window; \
 674.208 +            left = state->wsize; \
 674.209 +            state->whave = left; \
 674.210 +            if (out(out_desc, put, left)) { \
 674.211 +                ret = Z_BUF_ERROR; \
 674.212 +                goto inf_leave; \
 674.213 +            } \
 674.214 +        } \
 674.215 +    } while (0)
 674.216 +
 674.217 +/*
 674.218 +   strm provides the memory allocation functions and window buffer on input,
 674.219 +   and provides information on the unused input on return.  For Z_DATA_ERROR
 674.220 +   returns, strm will also provide an error message.
 674.221 +
 674.222 +   in() and out() are the call-back input and output functions.  When
 674.223 +   inflateBack() needs more input, it calls in().  When inflateBack() has
 674.224 +   filled the window with output, or when it completes with data in the
 674.225 +   window, it calls out() to write out the data.  The application must not
 674.226 +   change the provided input until in() is called again or inflateBack()
 674.227 +   returns.  The application must not change the window/output buffer until
 674.228 +   inflateBack() returns.
 674.229 +
 674.230 +   in() and out() are called with a descriptor parameter provided in the
 674.231 +   inflateBack() call.  This parameter can be a structure that provides the
 674.232 +   information required to do the read or write, as well as accumulated
 674.233 +   information on the input and output such as totals and check values.
 674.234 +
 674.235 +   in() should return zero on failure.  out() should return non-zero on
 674.236 +   failure.  If either in() or out() fails, than inflateBack() returns a
 674.237 +   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
 674.238 +   was in() or out() that caused in the error.  Otherwise,  inflateBack()
 674.239 +   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
 674.240 +   error, or Z_MEM_ERROR if it could not allocate memory for the state.
 674.241 +   inflateBack() can also return Z_STREAM_ERROR if the input parameters
 674.242 +   are not correct, i.e. strm is Z_NULL or the state was not initialized.
 674.243 + */
 674.244 +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
 674.245 +z_streamp strm;
 674.246 +in_func in;
 674.247 +void FAR *in_desc;
 674.248 +out_func out;
 674.249 +void FAR *out_desc;
 674.250 +{
 674.251 +    struct inflate_state FAR *state;
 674.252 +    unsigned char FAR *next;    /* next input */
 674.253 +    unsigned char FAR *put;     /* next output */
 674.254 +    unsigned have, left;        /* available input and output */
 674.255 +    unsigned long hold;         /* bit buffer */
 674.256 +    unsigned bits;              /* bits in bit buffer */
 674.257 +    unsigned copy;              /* number of stored or match bytes to copy */
 674.258 +    unsigned char FAR *from;    /* where to copy match bytes from */
 674.259 +    code this;                  /* current decoding table entry */
 674.260 +    code last;                  /* parent table entry */
 674.261 +    unsigned len;               /* length to copy for repeats, bits to drop */
 674.262 +    int ret;                    /* return code */
 674.263 +    static const unsigned short order[19] = /* permutation of code lengths */
 674.264 +        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
 674.265 +
 674.266 +    /* Check that the strm exists and that the state was initialized */
 674.267 +    if (strm == Z_NULL || strm->state == Z_NULL)
 674.268 +        return Z_STREAM_ERROR;
 674.269 +    state = (struct inflate_state FAR *)strm->state;
 674.270 +
 674.271 +    /* Reset the state */
 674.272 +    strm->msg = Z_NULL;
 674.273 +    state->mode = TYPE;
 674.274 +    state->last = 0;
 674.275 +    state->whave = 0;
 674.276 +    next = strm->next_in;
 674.277 +    have = next != Z_NULL ? strm->avail_in : 0;
 674.278 +    hold = 0;
 674.279 +    bits = 0;
 674.280 +    put = state->window;
 674.281 +    left = state->wsize;
 674.282 +
 674.283 +    /* Inflate until end of block marked as last */
 674.284 +    for (;;)
 674.285 +        switch (state->mode) {
 674.286 +        case TYPE:
 674.287 +            /* determine and dispatch block type */
 674.288 +            if (state->last) {
 674.289 +                BYTEBITS();
 674.290 +                state->mode = DONE;
 674.291 +                break;
 674.292 +            }
 674.293 +            NEEDBITS(3);
 674.294 +            state->last = BITS(1);
 674.295 +            DROPBITS(1);
 674.296 +            switch (BITS(2)) {
 674.297 +            case 0:                             /* stored block */
 674.298 +                Tracev((stderr, "inflate:     stored block%s\n",
 674.299 +                        state->last ? " (last)" : ""));
 674.300 +                state->mode = STORED;
 674.301 +                break;
 674.302 +            case 1:                             /* fixed block */
 674.303 +                fixedtables(state);
 674.304 +                Tracev((stderr, "inflate:     fixed codes block%s\n",
 674.305 +                        state->last ? " (last)" : ""));
 674.306 +                state->mode = LEN;              /* decode codes */
 674.307 +                break;
 674.308 +            case 2:                             /* dynamic block */
 674.309 +                Tracev((stderr, "inflate:     dynamic codes block%s\n",
 674.310 +                        state->last ? " (last)" : ""));
 674.311 +                state->mode = TABLE;
 674.312 +                break;
 674.313 +            case 3:
 674.314 +                strm->msg = (char *)"invalid block type";
 674.315 +                state->mode = BAD;
 674.316 +            }
 674.317 +            DROPBITS(2);
 674.318 +            break;
 674.319 +
 674.320 +        case STORED:
 674.321 +            /* get and verify stored block length */
 674.322 +            BYTEBITS();                         /* go to byte boundary */
 674.323 +            NEEDBITS(32);
 674.324 +            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
 674.325 +                strm->msg = (char *)"invalid stored block lengths";
 674.326 +                state->mode = BAD;
 674.327 +                break;
 674.328 +            }
 674.329 +            state->length = (unsigned)hold & 0xffff;
 674.330 +            Tracev((stderr, "inflate:       stored length %u\n",
 674.331 +                    state->length));
 674.332 +            INITBITS();
 674.333 +
 674.334 +            /* copy stored block from input to output */
 674.335 +            while (state->length != 0) {
 674.336 +                copy = state->length;
 674.337 +                PULL();
 674.338 +                ROOM();
 674.339 +                if (copy > have) copy = have;
 674.340 +                if (copy > left) copy = left;
 674.341 +                zmemcpy(put, next, copy);
 674.342 +                have -= copy;
 674.343 +                next += copy;
 674.344 +                left -= copy;
 674.345 +                put += copy;
 674.346 +                state->length -= copy;
 674.347 +            }
 674.348 +            Tracev((stderr, "inflate:       stored end\n"));
 674.349 +            state->mode = TYPE;
 674.350 +            break;
 674.351 +
 674.352 +        case TABLE:
 674.353 +            /* get dynamic table entries descriptor */
 674.354 +            NEEDBITS(14);
 674.355 +            state->nlen = BITS(5) + 257;
 674.356 +            DROPBITS(5);
 674.357 +            state->ndist = BITS(5) + 1;
 674.358 +            DROPBITS(5);
 674.359 +            state->ncode = BITS(4) + 4;
 674.360 +            DROPBITS(4);
 674.361 +#ifndef PKZIP_BUG_WORKAROUND
 674.362 +            if (state->nlen > 286 || state->ndist > 30) {
 674.363 +                strm->msg = (char *)"too many length or distance symbols";
 674.364 +                state->mode = BAD;
 674.365 +                break;
 674.366 +            }
 674.367 +#endif
 674.368 +            Tracev((stderr, "inflate:       table sizes ok\n"));
 674.369 +
 674.370 +            /* get code length code lengths (not a typo) */
 674.371 +            state->have = 0;
 674.372 +            while (state->have < state->ncode) {
 674.373 +                NEEDBITS(3);
 674.374 +                state->lens[order[state->have++]] = (unsigned short)BITS(3);
 674.375 +                DROPBITS(3);
 674.376 +            }
 674.377 +            while (state->have < 19)
 674.378 +                state->lens[order[state->have++]] = 0;
 674.379 +            state->next = state->codes;
 674.380 +            state->lencode = (code const FAR *)(state->next);
 674.381 +            state->lenbits = 7;
 674.382 +            ret = inflate_table(CODES, state->lens, 19, &(state->next),
 674.383 +                                &(state->lenbits), state->work);
 674.384 +            if (ret) {
 674.385 +                strm->msg = (char *)"invalid code lengths set";
 674.386 +                state->mode = BAD;
 674.387 +                break;
 674.388 +            }
 674.389 +            Tracev((stderr, "inflate:       code lengths ok\n"));
 674.390 +
 674.391 +            /* get length and distance code code lengths */
 674.392 +            state->have = 0;
 674.393 +            while (state->have < state->nlen + state->ndist) {
 674.394 +                for (;;) {
 674.395 +                    this = state->lencode[BITS(state->lenbits)];
 674.396 +                    if ((unsigned)(this.bits) <= bits) break;
 674.397 +                    PULLBYTE();
 674.398 +                }
 674.399 +                if (this.val < 16) {
 674.400 +                    NEEDBITS(this.bits);
 674.401 +                    DROPBITS(this.bits);
 674.402 +                    state->lens[state->have++] = this.val;
 674.403 +                }
 674.404 +                else {
 674.405 +                    if (this.val == 16) {
 674.406 +                        NEEDBITS(this.bits + 2);
 674.407 +                        DROPBITS(this.bits);
 674.408 +                        if (state->have == 0) {
 674.409 +                            strm->msg = (char *)"invalid bit length repeat";
 674.410 +                            state->mode = BAD;
 674.411 +                            break;
 674.412 +                        }
 674.413 +                        len = (unsigned)(state->lens[state->have - 1]);
 674.414 +                        copy = 3 + BITS(2);
 674.415 +                        DROPBITS(2);
 674.416 +                    }
 674.417 +                    else if (this.val == 17) {
 674.418 +                        NEEDBITS(this.bits + 3);
 674.419 +                        DROPBITS(this.bits);
 674.420 +                        len = 0;
 674.421 +                        copy = 3 + BITS(3);
 674.422 +                        DROPBITS(3);
 674.423 +                    }
 674.424 +                    else {
 674.425 +                        NEEDBITS(this.bits + 7);
 674.426 +                        DROPBITS(this.bits);
 674.427 +                        len = 0;
 674.428 +                        copy = 11 + BITS(7);
 674.429 +                        DROPBITS(7);
 674.430 +                    }
 674.431 +                    if (state->have + copy > state->nlen + state->ndist) {
 674.432 +                        strm->msg = (char *)"invalid bit length repeat";
 674.433 +                        state->mode = BAD;
 674.434 +                        break;
 674.435 +                    }
 674.436 +                    while (copy--)
 674.437 +                        state->lens[state->have++] = (unsigned short)len;
 674.438 +                }
 674.439 +            }
 674.440 +
 674.441 +            /* handle error breaks in while */
 674.442 +            if (state->mode == BAD) break;
 674.443 +
 674.444 +            /* build code tables */
 674.445 +            state->next = state->codes;
 674.446 +            state->lencode = (code const FAR *)(state->next);
 674.447 +            state->lenbits = 9;
 674.448 +            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
 674.449 +                                &(state->lenbits), state->work);
 674.450 +            if (ret) {
 674.451 +                strm->msg = (char *)"invalid literal/lengths set";
 674.452 +                state->mode = BAD;
 674.453 +                break;
 674.454 +            }
 674.455 +            state->distcode = (code const FAR *)(state->next);
 674.456 +            state->distbits = 6;
 674.457 +            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
 674.458 +                            &(state->next), &(state->distbits), state->work);
 674.459 +            if (ret) {
 674.460 +                strm->msg = (char *)"invalid distances set";
 674.461 +                state->mode = BAD;
 674.462 +                break;
 674.463 +            }
 674.464 +            Tracev((stderr, "inflate:       codes ok\n"));
 674.465 +            state->mode = LEN;
 674.466 +
 674.467 +        case LEN:
 674.468 +            /* use inflate_fast() if we have enough input and output */
 674.469 +            if (have >= 6 && left >= 258) {
 674.470 +                RESTORE();
 674.471 +                if (state->whave < state->wsize)
 674.472 +                    state->whave = state->wsize - left;
 674.473 +                inflate_fast(strm, state->wsize);
 674.474 +                LOAD();
 674.475 +                break;
 674.476 +            }
 674.477 +
 674.478 +            /* get a literal, length, or end-of-block code */
 674.479 +            for (;;) {
 674.480 +                this = state->lencode[BITS(state->lenbits)];
 674.481 +                if ((unsigned)(this.bits) <= bits) break;
 674.482 +                PULLBYTE();
 674.483 +            }
 674.484 +            if (this.op && (this.op & 0xf0) == 0) {
 674.485 +                last = this;
 674.486 +                for (;;) {
 674.487 +                    this = state->lencode[last.val +
 674.488 +                            (BITS(last.bits + last.op) >> last.bits)];
 674.489 +                    if ((unsigned)(last.bits + this.bits) <= bits) break;
 674.490 +                    PULLBYTE();
 674.491 +                }
 674.492 +                DROPBITS(last.bits);
 674.493 +            }
 674.494 +            DROPBITS(this.bits);
 674.495 +            state->length = (unsigned)this.val;
 674.496 +
 674.497 +            /* process literal */
 674.498 +            if (this.op == 0) {
 674.499 +                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
 674.500 +                        "inflate:         literal '%c'\n" :
 674.501 +                        "inflate:         literal 0x%02x\n", this.val));
 674.502 +                ROOM();
 674.503 +                *put++ = (unsigned char)(state->length);
 674.504 +                left--;
 674.505 +                state->mode = LEN;
 674.506 +                break;
 674.507 +            }
 674.508 +
 674.509 +            /* process end of block */
 674.510 +            if (this.op & 32) {
 674.511 +                Tracevv((stderr, "inflate:         end of block\n"));
 674.512 +                state->mode = TYPE;
 674.513 +                break;
 674.514 +            }
 674.515 +
 674.516 +            /* invalid code */
 674.517 +            if (this.op & 64) {
 674.518 +                strm->msg = (char *)"invalid literal/length code";
 674.519 +                state->mode = BAD;
 674.520 +                break;
 674.521 +            }
 674.522 +
 674.523 +            /* length code -- get extra bits, if any */
 674.524 +            state->extra = (unsigned)(this.op) & 15;
 674.525 +            if (state->extra != 0) {
 674.526 +                NEEDBITS(state->extra);
 674.527 +                state->length += BITS(state->extra);
 674.528 +                DROPBITS(state->extra);
 674.529 +            }
 674.530 +            Tracevv((stderr, "inflate:         length %u\n", state->length));
 674.531 +
 674.532 +            /* get distance code */
 674.533 +            for (;;) {
 674.534 +                this = state->distcode[BITS(state->distbits)];
 674.535 +                if ((unsigned)(this.bits) <= bits) break;
 674.536 +                PULLBYTE();
 674.537 +            }
 674.538 +            if ((this.op & 0xf0) == 0) {
 674.539 +                last = this;
 674.540 +                for (;;) {
 674.541 +                    this = state->distcode[last.val +
 674.542 +                            (BITS(last.bits + last.op) >> last.bits)];
 674.543 +                    if ((unsigned)(last.bits + this.bits) <= bits) break;
 674.544 +                    PULLBYTE();
 674.545 +                }
 674.546 +                DROPBITS(last.bits);
 674.547 +            }
 674.548 +            DROPBITS(this.bits);
 674.549 +            if (this.op & 64) {
 674.550 +                strm->msg = (char *)"invalid distance code";
 674.551 +                state->mode = BAD;
 674.552 +                break;
 674.553 +            }
 674.554 +            state->offset = (unsigned)this.val;
 674.555 +
 674.556 +            /* get distance extra bits, if any */
 674.557 +            state->extra = (unsigned)(this.op) & 15;
 674.558 +            if (state->extra != 0) {
 674.559 +                NEEDBITS(state->extra);
 674.560 +                state->offset += BITS(state->extra);
 674.561 +                DROPBITS(state->extra);
 674.562 +            }
 674.563 +            if (state->offset > state->wsize - (state->whave < state->wsize ?
 674.564 +                                                left : 0)) {
 674.565 +                strm->msg = (char *)"invalid distance too far back";
 674.566 +                state->mode = BAD;
 674.567 +                break;
 674.568 +            }
 674.569 +            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
 674.570 +
 674.571 +            /* copy match from window to output */
 674.572 +            do {
 674.573 +                ROOM();
 674.574 +                copy = state->wsize - state->offset;
 674.575 +                if (copy < left) {
 674.576 +                    from = put + copy;
 674.577 +                    copy = left - copy;
 674.578 +                }
 674.579 +                else {
 674.580 +                    from = put - state->offset;
 674.581 +                    copy = left;
 674.582 +                }
 674.583 +                if (copy > state->length) copy = state->length;
 674.584 +                state->length -= copy;
 674.585 +                left -= copy;
 674.586 +                do {
 674.587 +                    *put++ = *from++;
 674.588 +                } while (--copy);
 674.589 +            } while (state->length != 0);
 674.590 +            break;
 674.591 +
 674.592 +        case DONE:
 674.593 +            /* inflate stream terminated properly -- write leftover output */
 674.594 +            ret = Z_STREAM_END;
 674.595 +            if (left < state->wsize) {
 674.596 +                if (out(out_desc, state->window, state->wsize - left))
 674.597 +                    ret = Z_BUF_ERROR;
 674.598 +            }
 674.599 +            goto inf_leave;
 674.600 +
 674.601 +        case BAD:
 674.602 +            ret = Z_DATA_ERROR;
 674.603 +            goto inf_leave;
 674.604 +
 674.605 +        default:                /* can't happen, but makes compilers happy */
 674.606 +            ret = Z_STREAM_ERROR;
 674.607 +            goto inf_leave;
 674.608 +        }
 674.609 +
 674.610 +    /* Return unused input */
 674.611 +  inf_leave:
 674.612 +    strm->next_in = next;
 674.613 +    strm->avail_in = have;
 674.614 +    return ret;
 674.615 +}
 674.616 +
 674.617 +int ZEXPORT inflateBackEnd(strm)
 674.618 +z_streamp strm;
 674.619 +{
 674.620 +    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
 674.621 +        return Z_STREAM_ERROR;
 674.622 +    ZFREE(strm, strm->state);
 674.623 +    strm->state = Z_NULL;
 674.624 +    Tracev((stderr, "inflate: end\n"));
 674.625 +    return Z_OK;
 674.626 +}
   675.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   675.2 +++ b/libs/zlib/inffast.c	Sat Feb 01 19:58:19 2014 +0200
   675.3 @@ -0,0 +1,318 @@
   675.4 +/* inffast.c -- fast decoding
   675.5 + * Copyright (C) 1995-2004 Mark Adler
   675.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   675.7 + */
   675.8 +
   675.9 +#include "zutil.h"
  675.10 +#include "inftrees.h"
  675.11 +#include "inflate.h"
  675.12 +#include "inffast.h"
  675.13 +
  675.14 +#ifndef ASMINF
  675.15 +
  675.16 +/* Allow machine dependent optimization for post-increment or pre-increment.
  675.17 +   Based on testing to date,
  675.18 +   Pre-increment preferred for:
  675.19 +   - PowerPC G3 (Adler)
  675.20 +   - MIPS R5000 (Randers-Pehrson)
  675.21 +   Post-increment preferred for:
  675.22 +   - none
  675.23 +   No measurable difference:
  675.24 +   - Pentium III (Anderson)
  675.25 +   - M68060 (Nikl)
  675.26 + */
  675.27 +#ifdef POSTINC
  675.28 +#  define OFF 0
  675.29 +#  define PUP(a) *(a)++
  675.30 +#else
  675.31 +#  define OFF 1
  675.32 +#  define PUP(a) *++(a)
  675.33 +#endif
  675.34 +
  675.35 +/*
  675.36 +   Decode literal, length, and distance codes and write out the resulting
  675.37 +   literal and match bytes until either not enough input or output is
  675.38 +   available, an end-of-block is encountered, or a data error is encountered.
  675.39 +   When large enough input and output buffers are supplied to inflate(), for
  675.40 +   example, a 16K input buffer and a 64K output buffer, more than 95% of the
  675.41 +   inflate execution time is spent in this routine.
  675.42 +
  675.43 +   Entry assumptions:
  675.44 +
  675.45 +        state->mode == LEN
  675.46 +        strm->avail_in >= 6
  675.47 +        strm->avail_out >= 258
  675.48 +        start >= strm->avail_out
  675.49 +        state->bits < 8
  675.50 +
  675.51 +   On return, state->mode is one of:
  675.52 +
  675.53 +        LEN -- ran out of enough output space or enough available input
  675.54 +        TYPE -- reached end of block code, inflate() to interpret next block
  675.55 +        BAD -- error in block data
  675.56 +
  675.57 +   Notes:
  675.58 +
  675.59 +    - The maximum input bits used by a length/distance pair is 15 bits for the
  675.60 +      length code, 5 bits for the length extra, 15 bits for the distance code,
  675.61 +      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
  675.62 +      Therefore if strm->avail_in >= 6, then there is enough input to avoid
  675.63 +      checking for available input while decoding.
  675.64 +
  675.65 +    - The maximum bytes that a single length/distance pair can output is 258
  675.66 +      bytes, which is the maximum length that can be coded.  inflate_fast()
  675.67 +      requires strm->avail_out >= 258 for each loop to avoid checking for
  675.68 +      output space.
  675.69 + */
  675.70 +void inflate_fast(strm, start)
  675.71 +z_streamp strm;
  675.72 +unsigned start;         /* inflate()'s starting value for strm->avail_out */
  675.73 +{
  675.74 +    struct inflate_state FAR *state;
  675.75 +    unsigned char FAR *in;      /* local strm->next_in */
  675.76 +    unsigned char FAR *last;    /* while in < last, enough input available */
  675.77 +    unsigned char FAR *out;     /* local strm->next_out */
  675.78 +    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
  675.79 +    unsigned char FAR *end;     /* while out < end, enough space available */
  675.80 +#ifdef INFLATE_STRICT
  675.81 +    unsigned dmax;              /* maximum distance from zlib header */
  675.82 +#endif
  675.83 +    unsigned wsize;             /* window size or zero if not using window */
  675.84 +    unsigned whave;             /* valid bytes in the window */
  675.85 +    unsigned write;             /* window write index */
  675.86 +    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
  675.87 +    unsigned long hold;         /* local strm->hold */
  675.88 +    unsigned bits;              /* local strm->bits */
  675.89 +    code const FAR *lcode;      /* local strm->lencode */
  675.90 +    code const FAR *dcode;      /* local strm->distcode */
  675.91 +    unsigned lmask;             /* mask for first level of length codes */
  675.92 +    unsigned dmask;             /* mask for first level of distance codes */
  675.93 +    code this;                  /* retrieved table entry */
  675.94 +    unsigned op;                /* code bits, operation, extra bits, or */
  675.95 +                                /*  window position, window bytes to copy */
  675.96 +    unsigned len;               /* match length, unused bytes */
  675.97 +    unsigned dist;              /* match distance */
  675.98 +    unsigned char FAR *from;    /* where to copy match from */
  675.99 +
 675.100 +    /* copy state to local variables */
 675.101 +    state = (struct inflate_state FAR *)strm->state;
 675.102 +    in = strm->next_in - OFF;
 675.103 +    last = in + (strm->avail_in - 5);
 675.104 +    out = strm->next_out - OFF;
 675.105 +    beg = out - (start - strm->avail_out);
 675.106 +    end = out + (strm->avail_out - 257);
 675.107 +#ifdef INFLATE_STRICT
 675.108 +    dmax = state->dmax;
 675.109 +#endif
 675.110 +    wsize = state->wsize;
 675.111 +    whave = state->whave;
 675.112 +    write = state->write;
 675.113 +    window = state->window;
 675.114 +    hold = state->hold;
 675.115 +    bits = state->bits;
 675.116 +    lcode = state->lencode;
 675.117 +    dcode = state->distcode;
 675.118 +    lmask = (1U << state->lenbits) - 1;
 675.119 +    dmask = (1U << state->distbits) - 1;
 675.120 +
 675.121 +    /* decode literals and length/distances until end-of-block or not enough
 675.122 +       input data or output space */
 675.123 +    do {
 675.124 +        if (bits < 15) {
 675.125 +            hold += (unsigned long)(PUP(in)) << bits;
 675.126 +            bits += 8;
 675.127 +            hold += (unsigned long)(PUP(in)) << bits;
 675.128 +            bits += 8;
 675.129 +        }
 675.130 +        this = lcode[hold & lmask];
 675.131 +      dolen:
 675.132 +        op = (unsigned)(this.bits);
 675.133 +        hold >>= op;
 675.134 +        bits -= op;
 675.135 +        op = (unsigned)(this.op);
 675.136 +        if (op == 0) {                          /* literal */
 675.137 +            Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
 675.138 +                    "inflate:         literal '%c'\n" :
 675.139 +                    "inflate:         literal 0x%02x\n", this.val));
 675.140 +            PUP(out) = (unsigned char)(this.val);
 675.141 +        }
 675.142 +        else if (op & 16) {                     /* length base */
 675.143 +            len = (unsigned)(this.val);
 675.144 +            op &= 15;                           /* number of extra bits */
 675.145 +            if (op) {
 675.146 +                if (bits < op) {
 675.147 +                    hold += (unsigned long)(PUP(in)) << bits;
 675.148 +                    bits += 8;
 675.149 +                }
 675.150 +                len += (unsigned)hold & ((1U << op) - 1);
 675.151 +                hold >>= op;
 675.152 +                bits -= op;
 675.153 +            }
 675.154 +            Tracevv((stderr, "inflate:         length %u\n", len));
 675.155 +            if (bits < 15) {
 675.156 +                hold += (unsigned long)(PUP(in)) << bits;
 675.157 +                bits += 8;
 675.158 +                hold += (unsigned long)(PUP(in)) << bits;
 675.159 +                bits += 8;
 675.160 +            }
 675.161 +            this = dcode[hold & dmask];
 675.162 +          dodist:
 675.163 +            op = (unsigned)(this.bits);
 675.164 +            hold >>= op;
 675.165 +            bits -= op;
 675.166 +            op = (unsigned)(this.op);
 675.167 +            if (op & 16) {                      /* distance base */
 675.168 +                dist = (unsigned)(this.val);
 675.169 +                op &= 15;                       /* number of extra bits */
 675.170 +                if (bits < op) {
 675.171 +                    hold += (unsigned long)(PUP(in)) << bits;
 675.172 +                    bits += 8;
 675.173 +                    if (bits < op) {
 675.174 +                        hold += (unsigned long)(PUP(in)) << bits;
 675.175 +                        bits += 8;
 675.176 +                    }
 675.177 +                }
 675.178 +                dist += (unsigned)hold & ((1U << op) - 1);
 675.179 +#ifdef INFLATE_STRICT
 675.180 +                if (dist > dmax) {
 675.181 +                    strm->msg = (char *)"invalid distance too far back";
 675.182 +                    state->mode = BAD;
 675.183 +                    break;
 675.184 +                }
 675.185 +#endif
 675.186 +                hold >>= op;
 675.187 +                bits -= op;
 675.188 +                Tracevv((stderr, "inflate:         distance %u\n", dist));
 675.189 +                op = (unsigned)(out - beg);     /* max distance in output */
 675.190 +                if (dist > op) {                /* see if copy from window */
 675.191 +                    op = dist - op;             /* distance back in window */
 675.192 +                    if (op > whave) {
 675.193 +                        strm->msg = (char *)"invalid distance too far back";
 675.194 +                        state->mode = BAD;
 675.195 +                        break;
 675.196 +                    }
 675.197 +                    from = window - OFF;
 675.198 +                    if (write == 0) {           /* very common case */
 675.199 +                        from += wsize - op;
 675.200 +                        if (op < len) {         /* some from window */
 675.201 +                            len -= op;
 675.202 +                            do {
 675.203 +                                PUP(out) = PUP(from);
 675.204 +                            } while (--op);
 675.205 +                            from = out - dist;  /* rest from output */
 675.206 +                        }
 675.207 +                    }
 675.208 +                    else if (write < op) {      /* wrap around window */
 675.209 +                        from += wsize + write - op;
 675.210 +                        op -= write;
 675.211 +                        if (op < len) {         /* some from end of window */
 675.212 +                            len -= op;
 675.213 +                            do {
 675.214 +                                PUP(out) = PUP(from);
 675.215 +                            } while (--op);
 675.216 +                            from = window - OFF;
 675.217 +                            if (write < len) {  /* some from start of window */
 675.218 +                                op = write;
 675.219 +                                len -= op;
 675.220 +                                do {
 675.221 +                                    PUP(out) = PUP(from);
 675.222 +                                } while (--op);
 675.223 +                                from = out - dist;      /* rest from output */
 675.224 +                            }
 675.225 +                        }
 675.226 +                    }
 675.227 +                    else {                      /* contiguous in window */
 675.228 +                        from += write - op;
 675.229 +                        if (op < len) {         /* some from window */
 675.230 +                            len -= op;
 675.231 +                            do {
 675.232 +                                PUP(out) = PUP(from);
 675.233 +                            } while (--op);
 675.234 +                            from = out - dist;  /* rest from output */
 675.235 +                        }
 675.236 +                    }
 675.237 +                    while (len > 2) {
 675.238 +                        PUP(out) = PUP(from);
 675.239 +                        PUP(out) = PUP(from);
 675.240 +                        PUP(out) = PUP(from);
 675.241 +                        len -= 3;
 675.242 +                    }
 675.243 +                    if (len) {
 675.244 +                        PUP(out) = PUP(from);
 675.245 +                        if (len > 1)
 675.246 +                            PUP(out) = PUP(from);
 675.247 +                    }
 675.248 +                }
 675.249 +                else {
 675.250 +                    from = out - dist;          /* copy direct from output */
 675.251 +                    do {                        /* minimum length is three */
 675.252 +                        PUP(out) = PUP(from);
 675.253 +                        PUP(out) = PUP(from);
 675.254 +                        PUP(out) = PUP(from);
 675.255 +                        len -= 3;
 675.256 +                    } while (len > 2);
 675.257 +                    if (len) {
 675.258 +                        PUP(out) = PUP(from);
 675.259 +                        if (len > 1)
 675.260 +                            PUP(out) = PUP(from);
 675.261 +                    }
 675.262 +                }
 675.263 +            }
 675.264 +            else if ((op & 64) == 0) {          /* 2nd level distance code */
 675.265 +                this = dcode[this.val + (hold & ((1U << op) - 1))];
 675.266 +                goto dodist;
 675.267 +            }
 675.268 +            else {
 675.269 +                strm->msg = (char *)"invalid distance code";
 675.270 +                state->mode = BAD;
 675.271 +                break;
 675.272 +            }
 675.273 +        }
 675.274 +        else if ((op & 64) == 0) {              /* 2nd level length code */
 675.275 +            this = lcode[this.val + (hold & ((1U << op) - 1))];
 675.276 +            goto dolen;
 675.277 +        }
 675.278 +        else if (op & 32) {                     /* end-of-block */
 675.279 +            Tracevv((stderr, "inflate:         end of block\n"));
 675.280 +            state->mode = TYPE;
 675.281 +            break;
 675.282 +        }
 675.283 +        else {
 675.284 +            strm->msg = (char *)"invalid literal/length code";
 675.285 +            state->mode = BAD;
 675.286 +            break;
 675.287 +        }
 675.288 +    } while (in < last && out < end);
 675.289 +
 675.290 +    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
 675.291 +    len = bits >> 3;
 675.292 +    in -= len;
 675.293 +    bits -= len << 3;
 675.294 +    hold &= (1U << bits) - 1;
 675.295 +
 675.296 +    /* update state and return */
 675.297 +    strm->next_in = in + OFF;
 675.298 +    strm->next_out = out + OFF;
 675.299 +    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
 675.300 +    strm->avail_out = (unsigned)(out < end ?
 675.301 +                                 257 + (end - out) : 257 - (out - end));
 675.302 +    state->hold = hold;
 675.303 +    state->bits = bits;
 675.304 +    return;
 675.305 +}
 675.306 +
 675.307 +/*
 675.308 +   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
 675.309 +   - Using bit fields for code structure
 675.310 +   - Different op definition to avoid & for extra bits (do & for table bits)
 675.311 +   - Three separate decoding do-loops for direct, window, and write == 0
 675.312 +   - Special case for distance > 1 copies to do overlapped load and store copy
 675.313 +   - Explicit branch predictions (based on measured branch probabilities)
 675.314 +   - Deferring match copy and interspersed it with decoding subsequent codes
 675.315 +   - Swapping literal/length else
 675.316 +   - Swapping window/direct else
 675.317 +   - Larger unrolled copy loops (three is about right)
 675.318 +   - Moving len -= 3 statement into middle of loop
 675.319 + */
 675.320 +
 675.321 +#endif /* !ASMINF */
   676.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   676.2 +++ b/libs/zlib/inffast.h	Sat Feb 01 19:58:19 2014 +0200
   676.3 @@ -0,0 +1,11 @@
   676.4 +/* inffast.h -- header to use inffast.c
   676.5 + * Copyright (C) 1995-2003 Mark Adler
   676.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   676.7 + */
   676.8 +
   676.9 +/* WARNING: this file should *not* be used by applications. It is
  676.10 +   part of the implementation of the compression library and is
  676.11 +   subject to change. Applications should only use zlib.h.
  676.12 + */
  676.13 +
  676.14 +void inflate_fast OF((z_streamp strm, unsigned start));
   677.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   677.2 +++ b/libs/zlib/inffixed.h	Sat Feb 01 19:58:19 2014 +0200
   677.3 @@ -0,0 +1,94 @@
   677.4 +    /* inffixed.h -- table for decoding fixed codes
   677.5 +     * Generated automatically by makefixed().
   677.6 +     */
   677.7 +
   677.8 +    /* WARNING: this file should *not* be used by applications. It
   677.9 +       is part of the implementation of the compression library and
  677.10 +       is subject to change. Applications should only use zlib.h.
  677.11 +     */
  677.12 +
  677.13 +    static const code lenfix[512] = {
  677.14 +        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
  677.15 +        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
  677.16 +        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
  677.17 +        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
  677.18 +        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
  677.19 +        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
  677.20 +        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
  677.21 +        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
  677.22 +        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
  677.23 +        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
  677.24 +        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
  677.25 +        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
  677.26 +        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
  677.27 +        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
  677.28 +        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
  677.29 +        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
  677.30 +        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
  677.31 +        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
  677.32 +        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
  677.33 +        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
  677.34 +        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
  677.35 +        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
  677.36 +        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
  677.37 +        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
  677.38 +        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
  677.39 +        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
  677.40 +        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
  677.41 +        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
  677.42 +        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
  677.43 +        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
  677.44 +        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
  677.45 +        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
  677.46 +        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
  677.47 +        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
  677.48 +        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
  677.49 +        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
  677.50 +        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
  677.51 +        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
  677.52 +        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
  677.53 +        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
  677.54 +        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
  677.55 +        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
  677.56 +        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
  677.57 +        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
  677.58 +        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
  677.59 +        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
  677.60 +        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
  677.61 +        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
  677.62 +        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
  677.63 +        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
  677.64 +        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
  677.65 +        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
  677.66 +        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
  677.67 +        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
  677.68 +        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
  677.69 +        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
  677.70 +        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
  677.71 +        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
  677.72 +        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
  677.73 +        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
  677.74 +        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
  677.75 +        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
  677.76 +        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
  677.77 +        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
  677.78 +        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
  677.79 +        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
  677.80 +        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
  677.81 +        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
  677.82 +        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
  677.83 +        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
  677.84 +        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
  677.85 +        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
  677.86 +        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
  677.87 +        {0,9,255}
  677.88 +    };
  677.89 +
  677.90 +    static const code distfix[32] = {
  677.91 +        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
  677.92 +        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
  677.93 +        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
  677.94 +        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
  677.95 +        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
  677.96 +        {22,5,193},{64,5,0}
  677.97 +    };
   678.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   678.2 +++ b/libs/zlib/inflate.c	Sat Feb 01 19:58:19 2014 +0200
   678.3 @@ -0,0 +1,1368 @@
   678.4 +/* inflate.c -- zlib decompression
   678.5 + * Copyright (C) 1995-2005 Mark Adler
   678.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   678.7 + */
   678.8 +
   678.9 +/*
  678.10 + * Change history:
  678.11 + *
  678.12 + * 1.2.beta0    24 Nov 2002
  678.13 + * - First version -- complete rewrite of inflate to simplify code, avoid
  678.14 + *   creation of window when not needed, minimize use of window when it is
  678.15 + *   needed, make inffast.c even faster, implement gzip decoding, and to
  678.16 + *   improve code readability and style over the previous zlib inflate code
  678.17 + *
  678.18 + * 1.2.beta1    25 Nov 2002
  678.19 + * - Use pointers for available input and output checking in inffast.c
  678.20 + * - Remove input and output counters in inffast.c
  678.21 + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
  678.22 + * - Remove unnecessary second byte pull from length extra in inffast.c
  678.23 + * - Unroll direct copy to three copies per loop in inffast.c
  678.24 + *
  678.25 + * 1.2.beta2    4 Dec 2002
  678.26 + * - Change external routine names to reduce potential conflicts
  678.27 + * - Correct filename to inffixed.h for fixed tables in inflate.c
  678.28 + * - Make hbuf[] unsigned char to match parameter type in inflate.c
  678.29 + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
  678.30 + *   to avoid negation problem on Alphas (64 bit) in inflate.c
  678.31 + *
  678.32 + * 1.2.beta3    22 Dec 2002
  678.33 + * - Add comments on state->bits assertion in inffast.c
  678.34 + * - Add comments on op field in inftrees.h
  678.35 + * - Fix bug in reuse of allocated window after inflateReset()
  678.36 + * - Remove bit fields--back to byte structure for speed
  678.37 + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
  678.38 + * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
  678.39 + * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
  678.40 + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
  678.41 + * - Use local copies of stream next and avail values, as well as local bit
  678.42 + *   buffer and bit count in inflate()--for speed when inflate_fast() not used
  678.43 + *
  678.44 + * 1.2.beta4    1 Jan 2003
  678.45 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
  678.46 + * - Move a comment on output buffer sizes from inffast.c to inflate.c
  678.47 + * - Add comments in inffast.c to introduce the inflate_fast() routine
  678.48 + * - Rearrange window copies in inflate_fast() for speed and simplification
  678.49 + * - Unroll last copy for window match in inflate_fast()
  678.50 + * - Use local copies of window variables in inflate_fast() for speed
  678.51 + * - Pull out common write == 0 case for speed in inflate_fast()
  678.52 + * - Make op and len in inflate_fast() unsigned for consistency
  678.53 + * - Add FAR to lcode and dcode declarations in inflate_fast()
  678.54 + * - Simplified bad distance check in inflate_fast()
  678.55 + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
  678.56 + *   source file infback.c to provide a call-back interface to inflate for
  678.57 + *   programs like gzip and unzip -- uses window as output buffer to avoid
  678.58 + *   window copying
  678.59 + *
  678.60 + * 1.2.beta5    1 Jan 2003
  678.61 + * - Improved inflateBack() interface to allow the caller to provide initial
  678.62 + *   input in strm.
  678.63 + * - Fixed stored blocks bug in inflateBack()
  678.64 + *
  678.65 + * 1.2.beta6    4 Jan 2003
  678.66 + * - Added comments in inffast.c on effectiveness of POSTINC
  678.67 + * - Typecasting all around to reduce compiler warnings
  678.68 + * - Changed loops from while (1) or do {} while (1) to for (;;), again to
  678.69 + *   make compilers happy
  678.70 + * - Changed type of window in inflateBackInit() to unsigned char *
  678.71 + *
  678.72 + * 1.2.beta7    27 Jan 2003
  678.73 + * - Changed many types to unsigned or unsigned short to avoid warnings
  678.74 + * - Added inflateCopy() function
  678.75 + *
  678.76 + * 1.2.0        9 Mar 2003
  678.77 + * - Changed inflateBack() interface to provide separate opaque descriptors
  678.78 + *   for the in() and out() functions
  678.79 + * - Changed inflateBack() argument and in_func typedef to swap the length
  678.80 + *   and buffer address return values for the input function
  678.81 + * - Check next_in and next_out for Z_NULL on entry to inflate()
  678.82 + *
  678.83 + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
  678.84 + */
  678.85 +
  678.86 +#include "zutil.h"
  678.87 +#include "inftrees.h"
  678.88 +#include "inflate.h"
  678.89 +#include "inffast.h"
  678.90 +
  678.91 +#ifdef MAKEFIXED
  678.92 +#  ifndef BUILDFIXED
  678.93 +#    define BUILDFIXED
  678.94 +#  endif
  678.95 +#endif
  678.96 +
  678.97 +/* function prototypes */
  678.98 +local void fixedtables OF((struct inflate_state FAR *state));
  678.99 +local int updatewindow OF((z_streamp strm, unsigned out));
 678.100 +#ifdef BUILDFIXED
 678.101 +   void makefixed OF((void));
 678.102 +#endif
 678.103 +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
 678.104 +                              unsigned len));
 678.105 +
 678.106 +int ZEXPORT inflateReset(strm)
 678.107 +z_streamp strm;
 678.108 +{
 678.109 +    struct inflate_state FAR *state;
 678.110 +
 678.111 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
 678.112 +    state = (struct inflate_state FAR *)strm->state;
 678.113 +    strm->total_in = strm->total_out = state->total = 0;
 678.114 +    strm->msg = Z_NULL;
 678.115 +    strm->adler = 1;        /* to support ill-conceived Java test suite */
 678.116 +    state->mode = HEAD;
 678.117 +    state->last = 0;
 678.118 +    state->havedict = 0;
 678.119 +    state->dmax = 32768U;
 678.120 +    state->head = Z_NULL;
 678.121 +    state->wsize = 0;
 678.122 +    state->whave = 0;
 678.123 +    state->write = 0;
 678.124 +    state->hold = 0;
 678.125 +    state->bits = 0;
 678.126 +    state->lencode = state->distcode = state->next = state->codes;
 678.127 +    Tracev((stderr, "inflate: reset\n"));
 678.128 +    return Z_OK;
 678.129 +}
 678.130 +
 678.131 +int ZEXPORT inflatePrime(strm, bits, value)
 678.132 +z_streamp strm;
 678.133 +int bits;
 678.134 +int value;
 678.135 +{
 678.136 +    struct inflate_state FAR *state;
 678.137 +
 678.138 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
 678.139 +    state = (struct inflate_state FAR *)strm->state;
 678.140 +    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
 678.141 +    value &= (1L << bits) - 1;
 678.142 +    state->hold += value << state->bits;
 678.143 +    state->bits += bits;
 678.144 +    return Z_OK;
 678.145 +}
 678.146 +
 678.147 +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
 678.148 +z_streamp strm;
 678.149 +int windowBits;
 678.150 +const char *version;
 678.151 +int stream_size;
 678.152 +{
 678.153 +    struct inflate_state FAR *state;
 678.154 +
 678.155 +    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
 678.156 +        stream_size != (int)(sizeof(z_stream)))
 678.157 +        return Z_VERSION_ERROR;
 678.158 +    if (strm == Z_NULL) return Z_STREAM_ERROR;
 678.159 +    strm->msg = Z_NULL;                 /* in case we return an error */
 678.160 +    if (strm->zalloc == (alloc_func)0) {
 678.161 +        strm->zalloc = zcalloc;
 678.162 +        strm->opaque = (voidpf)0;
 678.163 +    }
 678.164 +    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
 678.165 +    state = (struct inflate_state FAR *)
 678.166 +            ZALLOC(strm, 1, sizeof(struct inflate_state));
 678.167 +    if (state == Z_NULL) return Z_MEM_ERROR;
 678.168 +    Tracev((stderr, "inflate: allocated\n"));
 678.169 +    strm->state = (struct internal_state FAR *)state;
 678.170 +    if (windowBits < 0) {
 678.171 +        state->wrap = 0;
 678.172 +        windowBits = -windowBits;
 678.173 +    }
 678.174 +    else {
 678.175 +        state->wrap = (windowBits >> 4) + 1;
 678.176 +#ifdef GUNZIP
 678.177 +        if (windowBits < 48) windowBits &= 15;
 678.178 +#endif
 678.179 +    }
 678.180 +    if (windowBits < 8 || windowBits > 15) {
 678.181 +        ZFREE(strm, state);
 678.182 +        strm->state = Z_NULL;
 678.183 +        return Z_STREAM_ERROR;
 678.184 +    }
 678.185 +    state->wbits = (unsigned)windowBits;
 678.186 +    state->window = Z_NULL;
 678.187 +    return inflateReset(strm);
 678.188 +}
 678.189 +
 678.190 +int ZEXPORT inflateInit_(strm, version, stream_size)
 678.191 +z_streamp strm;
 678.192 +const char *version;
 678.193 +int stream_size;
 678.194 +{
 678.195 +    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
 678.196 +}
 678.197 +
 678.198 +/*
 678.199 +   Return state with length and distance decoding tables and index sizes set to
 678.200 +   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
 678.201 +   If BUILDFIXED is defined, then instead this routine builds the tables the
 678.202 +   first time it's called, and returns those tables the first time and
 678.203 +   thereafter.  This reduces the size of the code by about 2K bytes, in
 678.204 +   exchange for a little execution time.  However, BUILDFIXED should not be
 678.205 +   used for threaded applications, since the rewriting of the tables and virgin
 678.206 +   may not be thread-safe.
 678.207 + */
 678.208 +local void fixedtables(state)
 678.209 +struct inflate_state FAR *state;
 678.210 +{
 678.211 +#ifdef BUILDFIXED
 678.212 +    static int virgin = 1;
 678.213 +    static code *lenfix, *distfix;
 678.214 +    static code fixed[544];
 678.215 +
 678.216 +    /* build fixed huffman tables if first call (may not be thread safe) */
 678.217 +    if (virgin) {
 678.218 +        unsigned sym, bits;
 678.219 +        static code *next;
 678.220 +
 678.221 +        /* literal/length table */
 678.222 +        sym = 0;
 678.223 +        while (sym < 144) state->lens[sym++] = 8;
 678.224 +        while (sym < 256) state->lens[sym++] = 9;
 678.225 +        while (sym < 280) state->lens[sym++] = 7;
 678.226 +        while (sym < 288) state->lens[sym++] = 8;
 678.227 +        next = fixed;
 678.228 +        lenfix = next;
 678.229 +        bits = 9;
 678.230 +        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
 678.231 +
 678.232 +        /* distance table */
 678.233 +        sym = 0;
 678.234 +        while (sym < 32) state->lens[sym++] = 5;
 678.235 +        distfix = next;
 678.236 +        bits = 5;
 678.237 +        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
 678.238 +
 678.239 +        /* do this just once */
 678.240 +        virgin = 0;
 678.241 +    }
 678.242 +#else /* !BUILDFIXED */
 678.243 +#   include "inffixed.h"
 678.244 +#endif /* BUILDFIXED */
 678.245 +    state->lencode = lenfix;
 678.246 +    state->lenbits = 9;
 678.247 +    state->distcode = distfix;
 678.248 +    state->distbits = 5;
 678.249 +}
 678.250 +
 678.251 +#ifdef MAKEFIXED
 678.252 +#include <stdio.h>
 678.253 +
 678.254 +/*
 678.255 +   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
 678.256 +   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
 678.257 +   those tables to stdout, which would be piped to inffixed.h.  A small program
 678.258 +   can simply call makefixed to do this:
 678.259 +
 678.260 +    void makefixed(void);
 678.261 +
 678.262 +    int main(void)
 678.263 +    {
 678.264 +        makefixed();
 678.265 +        return 0;
 678.266 +    }
 678.267 +
 678.268 +   Then that can be linked with zlib built with MAKEFIXED defined and run:
 678.269 +
 678.270 +    a.out > inffixed.h
 678.271 + */
 678.272 +void makefixed()
 678.273 +{
 678.274 +    unsigned low, size;
 678.275 +    struct inflate_state state;
 678.276 +
 678.277 +    fixedtables(&state);
 678.278 +    puts("    /* inffixed.h -- table for decoding fixed codes");
 678.279 +    puts("     * Generated automatically by makefixed().");
 678.280 +    puts("     */");
 678.281 +    puts("");
 678.282 +    puts("    /* WARNING: this file should *not* be used by applications.");
 678.283 +    puts("       It is part of the implementation of this library and is");
 678.284 +    puts("       subject to change. Applications should only use zlib.h.");
 678.285 +    puts("     */");
 678.286 +    puts("");
 678.287 +    size = 1U << 9;
 678.288 +    printf("    static const code lenfix[%u] = {", size);
 678.289 +    low = 0;
 678.290 +    for (;;) {
 678.291 +        if ((low % 7) == 0) printf("\n        ");
 678.292 +        printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
 678.293 +               state.lencode[low].val);
 678.294 +        if (++low == size) break;
 678.295 +        putchar(',');
 678.296 +    }
 678.297 +    puts("\n    };");
 678.298 +    size = 1U << 5;
 678.299 +    printf("\n    static const code distfix[%u] = {", size);
 678.300 +    low = 0;
 678.301 +    for (;;) {
 678.302 +        if ((low % 6) == 0) printf("\n        ");
 678.303 +        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
 678.304 +               state.distcode[low].val);
 678.305 +        if (++low == size) break;
 678.306 +        putchar(',');
 678.307 +    }
 678.308 +    puts("\n    };");
 678.309 +}
 678.310 +#endif /* MAKEFIXED */
 678.311 +
 678.312 +/*
 678.313 +   Update the window with the last wsize (normally 32K) bytes written before
 678.314 +   returning.  If window does not exist yet, create it.  This is only called
 678.315 +   when a window is already in use, or when output has been written during this
 678.316 +   inflate call, but the end of the deflate stream has not been reached yet.
 678.317 +   It is also called to create a window for dictionary data when a dictionary
 678.318 +   is loaded.
 678.319 +
 678.320 +   Providing output buffers larger than 32K to inflate() should provide a speed
 678.321 +   advantage, since only the last 32K of output is copied to the sliding window
 678.322 +   upon return from inflate(), and since all distances after the first 32K of
 678.323 +   output will fall in the output data, making match copies simpler and faster.
 678.324 +   The advantage may be dependent on the size of the processor's data caches.
 678.325 + */
 678.326 +local int updatewindow(strm, out)
 678.327 +z_streamp strm;
 678.328 +unsigned out;
 678.329 +{
 678.330 +    struct inflate_state FAR *state;
 678.331 +    unsigned copy, dist;
 678.332 +
 678.333 +    state = (struct inflate_state FAR *)strm->state;
 678.334 +
 678.335 +    /* if it hasn't been done already, allocate space for the window */
 678.336 +    if (state->window == Z_NULL) {
 678.337 +        state->window = (unsigned char FAR *)
 678.338 +                        ZALLOC(strm, 1U << state->wbits,
 678.339 +                               sizeof(unsigned char));
 678.340 +        if (state->window == Z_NULL) return 1;
 678.341 +    }
 678.342 +
 678.343 +    /* if window not in use yet, initialize */
 678.344 +    if (state->wsize == 0) {
 678.345 +        state->wsize = 1U << state->wbits;
 678.346 +        state->write = 0;
 678.347 +        state->whave = 0;
 678.348 +    }
 678.349 +
 678.350 +    /* copy state->wsize or less output bytes into the circular window */
 678.351 +    copy = out - strm->avail_out;
 678.352 +    if (copy >= state->wsize) {
 678.353 +        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
 678.354 +        state->write = 0;
 678.355 +        state->whave = state->wsize;
 678.356 +    }
 678.357 +    else {
 678.358 +        dist = state->wsize - state->write;
 678.359 +        if (dist > copy) dist = copy;
 678.360 +        zmemcpy(state->window + state->write, strm->next_out - copy, dist);
 678.361 +        copy -= dist;
 678.362 +        if (copy) {
 678.363 +            zmemcpy(state->window, strm->next_out - copy, copy);
 678.364 +            state->write = copy;
 678.365 +            state->whave = state->wsize;
 678.366 +        }
 678.367 +        else {
 678.368 +            state->write += dist;
 678.369 +            if (state->write == state->wsize) state->write = 0;
 678.370 +            if (state->whave < state->wsize) state->whave += dist;
 678.371 +        }
 678.372 +    }
 678.373 +    return 0;
 678.374 +}
 678.375 +
 678.376 +/* Macros for inflate(): */
 678.377 +
 678.378 +/* check function to use adler32() for zlib or crc32() for gzip */
 678.379 +#ifdef GUNZIP
 678.380 +#  define UPDATE(check, buf, len) \
 678.381 +    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
 678.382 +#else
 678.383 +#  define UPDATE(check, buf, len) adler32(check, buf, len)
 678.384 +#endif
 678.385 +
 678.386 +/* check macros for header crc */
 678.387 +#ifdef GUNZIP
 678.388 +#  define CRC2(check, word) \
 678.389 +    do { \
 678.390 +        hbuf[0] = (unsigned char)(word); \
 678.391 +        hbuf[1] = (unsigned char)((word) >> 8); \
 678.392 +        check = crc32(check, hbuf, 2); \
 678.393 +    } while (0)
 678.394 +
 678.395 +#  define CRC4(check, word) \
 678.396 +    do { \
 678.397 +        hbuf[0] = (unsigned char)(word); \
 678.398 +        hbuf[1] = (unsigned char)((word) >> 8); \
 678.399 +        hbuf[2] = (unsigned char)((word) >> 16); \
 678.400 +        hbuf[3] = (unsigned char)((word) >> 24); \
 678.401 +        check = crc32(check, hbuf, 4); \
 678.402 +    } while (0)
 678.403 +#endif
 678.404 +
 678.405 +/* Load registers with state in inflate() for speed */
 678.406 +#define LOAD() \
 678.407 +    do { \
 678.408 +        put = strm->next_out; \
 678.409 +        left = strm->avail_out; \
 678.410 +        next = strm->next_in; \
 678.411 +        have = strm->avail_in; \
 678.412 +        hold = state->hold; \
 678.413 +        bits = state->bits; \
 678.414 +    } while (0)
 678.415 +
 678.416 +/* Restore state from registers in inflate() */
 678.417 +#define RESTORE() \
 678.418 +    do { \
 678.419 +        strm->next_out = put; \
 678.420 +        strm->avail_out = left; \
 678.421 +        strm->next_in = next; \
 678.422 +        strm->avail_in = have; \
 678.423 +        state->hold = hold; \
 678.424 +        state->bits = bits; \
 678.425 +    } while (0)
 678.426 +
 678.427 +/* Clear the input bit accumulator */
 678.428 +#define INITBITS() \
 678.429 +    do { \
 678.430 +        hold = 0; \
 678.431 +        bits = 0; \
 678.432 +    } while (0)
 678.433 +
 678.434 +/* Get a byte of input into the bit accumulator, or return from inflate()
 678.435 +   if there is no input available. */
 678.436 +#define PULLBYTE() \
 678.437 +    do { \
 678.438 +        if (have == 0) goto inf_leave; \
 678.439 +        have--; \
 678.440 +        hold += (unsigned long)(*next++) << bits; \
 678.441 +        bits += 8; \
 678.442 +    } while (0)
 678.443 +
 678.444 +/* Assure that there are at least n bits in the bit accumulator.  If there is
 678.445 +   not enough available input to do that, then return from inflate(). */
 678.446 +#define NEEDBITS(n) \
 678.447 +    do { \
 678.448 +        while (bits < (unsigned)(n)) \
 678.449 +            PULLBYTE(); \
 678.450 +    } while (0)
 678.451 +
 678.452 +/* Return the low n bits of the bit accumulator (n < 16) */
 678.453 +#define BITS(n) \
 678.454 +    ((unsigned)hold & ((1U << (n)) - 1))
 678.455 +
 678.456 +/* Remove n bits from the bit accumulator */
 678.457 +#define DROPBITS(n) \
 678.458 +    do { \
 678.459 +        hold >>= (n); \
 678.460 +        bits -= (unsigned)(n); \
 678.461 +    } while (0)
 678.462 +
 678.463 +/* Remove zero to seven bits as needed to go to a byte boundary */
 678.464 +#define BYTEBITS() \
 678.465 +    do { \
 678.466 +        hold >>= bits & 7; \
 678.467 +        bits -= bits & 7; \
 678.468 +    } while (0)
 678.469 +
 678.470 +/* Reverse the bytes in a 32-bit value */
 678.471 +#define REVERSE(q) \
 678.472 +    ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
 678.473 +     (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
 678.474 +
 678.475 +/*
 678.476 +   inflate() uses a state machine to process as much input data and generate as
 678.477 +   much output data as possible before returning.  The state machine is
 678.478 +   structured roughly as follows:
 678.479 +
 678.480 +    for (;;) switch (state) {
 678.481 +    ...
 678.482 +    case STATEn:
 678.483 +        if (not enough input data or output space to make progress)
 678.484 +            return;
 678.485 +        ... make progress ...
 678.486 +        state = STATEm;
 678.487 +        break;
 678.488 +    ...
 678.489 +    }
 678.490 +
 678.491 +   so when inflate() is called again, the same case is attempted again, and
 678.492 +   if the appropriate resources are provided, the machine proceeds to the
 678.493 +   next state.  The NEEDBITS() macro is usually the way the state evaluates
 678.494 +   whether it can proceed or should return.  NEEDBITS() does the return if
 678.495 +   the requested bits are not available.  The typical use of the BITS macros
 678.496 +   is:
 678.497 +
 678.498 +        NEEDBITS(n);
 678.499 +        ... do something with BITS(n) ...
 678.500 +        DROPBITS(n);
 678.501 +
 678.502 +   where NEEDBITS(n) either returns from inflate() if there isn't enough
 678.503 +   input left to load n bits into the accumulator, or it continues.  BITS(n)
 678.504 +   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
 678.505 +   the low n bits off the accumulator.  INITBITS() clears the accumulator
 678.506 +   and sets the number of available bits to zero.  BYTEBITS() discards just
 678.507 +   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
 678.508 +   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
 678.509 +
 678.510 +   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
 678.511 +   if there is no input available.  The decoding of variable length codes uses
 678.512 +   PULLBYTE() directly in order to pull just enough bytes to decode the next
 678.513 +   code, and no more.
 678.514 +
 678.515 +   Some states loop until they get enough input, making sure that enough
 678.516 +   state information is maintained to continue the loop where it left off
 678.517 +   if NEEDBITS() returns in the loop.  For example, want, need, and keep
 678.518 +   would all have to actually be part of the saved state in case NEEDBITS()
 678.519 +   returns:
 678.520 +
 678.521 +    case STATEw:
 678.522 +        while (want < need) {
 678.523 +            NEEDBITS(n);
 678.524 +            keep[want++] = BITS(n);
 678.525 +            DROPBITS(n);
 678.526 +        }
 678.527 +        state = STATEx;
 678.528 +    case STATEx:
 678.529 +
 678.530 +   As shown above, if the next state is also the next case, then the break
 678.531 +   is omitted.
 678.532 +
 678.533 +   A state may also return if there is not enough output space available to
 678.534 +   complete that state.  Those states are copying stored data, writing a
 678.535 +   literal byte, and copying a matching string.
 678.536 +
 678.537 +   When returning, a "goto inf_leave" is used to update the total counters,
 678.538 +   update the check value, and determine whether any progress has been made
 678.539 +   during that inflate() call in order to return the proper return code.
 678.540 +   Progress is defined as a change in either strm->avail_in or strm->avail_out.
 678.541 +   When there is a window, goto inf_leave will update the window with the last
 678.542 +   output written.  If a goto inf_leave occurs in the middle of decompression
 678.543 +   and there is no window currently, goto inf_leave will create one and copy
 678.544 +   output to the window for the next call of inflate().
 678.545 +
 678.546 +   In this implementation, the flush parameter of inflate() only affects the
 678.547 +   return code (per zlib.h).  inflate() always writes as much as possible to
 678.548 +   strm->next_out, given the space available and the provided input--the effect
 678.549 +   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
 678.550 +   the allocation of and copying into a sliding window until necessary, which
 678.551 +   provides the effect documented in zlib.h for Z_FINISH when the entire input
 678.552 +   stream available.  So the only thing the flush parameter actually does is:
 678.553 +   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
 678.554 +   will return Z_BUF_ERROR if it has not reached the end of the stream.
 678.555 + */
 678.556 +
 678.557 +int ZEXPORT inflate(strm, flush)
 678.558 +z_streamp strm;
 678.559 +int flush;
 678.560 +{
 678.561 +    struct inflate_state FAR *state;
 678.562 +    unsigned char FAR *next;    /* next input */
 678.563 +    unsigned char FAR *put;     /* next output */
 678.564 +    unsigned have, left;        /* available input and output */
 678.565 +    unsigned long hold;         /* bit buffer */
 678.566 +    unsigned bits;              /* bits in bit buffer */
 678.567 +    unsigned in, out;           /* save starting available input and output */
 678.568 +    unsigned copy;              /* number of stored or match bytes to copy */
 678.569 +    unsigned char FAR *from;    /* where to copy match bytes from */
 678.570 +    code this;                  /* current decoding table entry */
 678.571 +    code last;                  /* parent table entry */
 678.572 +    unsigned len;               /* length to copy for repeats, bits to drop */
 678.573 +    int ret;                    /* return code */
 678.574 +#ifdef GUNZIP
 678.575 +    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
 678.576 +#endif
 678.577 +    static const unsigned short order[19] = /* permutation of code lengths */
 678.578 +        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
 678.579 +
 678.580 +    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
 678.581 +        (strm->next_in == Z_NULL && strm->avail_in != 0))
 678.582 +        return Z_STREAM_ERROR;
 678.583 +
 678.584 +    state = (struct inflate_state FAR *)strm->state;
 678.585 +    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
 678.586 +    LOAD();
 678.587 +    in = have;
 678.588 +    out = left;
 678.589 +    ret = Z_OK;
 678.590 +    for (;;)
 678.591 +        switch (state->mode) {
 678.592 +        case HEAD:
 678.593 +            if (state->wrap == 0) {
 678.594 +                state->mode = TYPEDO;
 678.595 +                break;
 678.596 +            }
 678.597 +            NEEDBITS(16);
 678.598 +#ifdef GUNZIP
 678.599 +            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
 678.600 +                state->check = crc32(0L, Z_NULL, 0);
 678.601 +                CRC2(state->check, hold);
 678.602 +                INITBITS();
 678.603 +                state->mode = FLAGS;
 678.604 +                break;
 678.605 +            }
 678.606 +            state->flags = 0;           /* expect zlib header */
 678.607 +            if (state->head != Z_NULL)
 678.608 +                state->head->done = -1;
 678.609 +            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
 678.610 +#else
 678.611 +            if (
 678.612 +#endif
 678.613 +                ((BITS(8) << 8) + (hold >> 8)) % 31) {
 678.614 +                strm->msg = (char *)"incorrect header check";
 678.615 +                state->mode = BAD;
 678.616 +                break;
 678.617 +            }
 678.618 +            if (BITS(4) != Z_DEFLATED) {
 678.619 +                strm->msg = (char *)"unknown compression method";
 678.620 +                state->mode = BAD;
 678.621 +                break;
 678.622 +            }
 678.623 +            DROPBITS(4);
 678.624 +            len = BITS(4) + 8;
 678.625 +            if (len > state->wbits) {
 678.626 +                strm->msg = (char *)"invalid window size";
 678.627 +                state->mode = BAD;
 678.628 +                break;
 678.629 +            }
 678.630 +            state->dmax = 1U << len;
 678.631 +            Tracev((stderr, "inflate:   zlib header ok\n"));
 678.632 +            strm->adler = state->check = adler32(0L, Z_NULL, 0);
 678.633 +            state->mode = hold & 0x200 ? DICTID : TYPE;
 678.634 +            INITBITS();
 678.635 +            break;
 678.636 +#ifdef GUNZIP
 678.637 +        case FLAGS:
 678.638 +            NEEDBITS(16);
 678.639 +            state->flags = (int)(hold);
 678.640 +            if ((state->flags & 0xff) != Z_DEFLATED) {
 678.641 +                strm->msg = (char *)"unknown compression method";
 678.642 +                state->mode = BAD;
 678.643 +                break;
 678.644 +            }
 678.645 +            if (state->flags & 0xe000) {
 678.646 +                strm->msg = (char *)"unknown header flags set";
 678.647 +                state->mode = BAD;
 678.648 +                break;
 678.649 +            }
 678.650 +            if (state->head != Z_NULL)
 678.651 +                state->head->text = (int)((hold >> 8) & 1);
 678.652 +            if (state->flags & 0x0200) CRC2(state->check, hold);
 678.653 +            INITBITS();
 678.654 +            state->mode = TIME;
 678.655 +        case TIME:
 678.656 +            NEEDBITS(32);
 678.657 +            if (state->head != Z_NULL)
 678.658 +                state->head->time = hold;
 678.659 +            if (state->flags & 0x0200) CRC4(state->check, hold);
 678.660 +            INITBITS();
 678.661 +            state->mode = OS;
 678.662 +        case OS:
 678.663 +            NEEDBITS(16);
 678.664 +            if (state->head != Z_NULL) {
 678.665 +                state->head->xflags = (int)(hold & 0xff);
 678.666 +                state->head->os = (int)(hold >> 8);
 678.667 +            }
 678.668 +            if (state->flags & 0x0200) CRC2(state->check, hold);
 678.669 +            INITBITS();
 678.670 +            state->mode = EXLEN;
 678.671 +        case EXLEN:
 678.672 +            if (state->flags & 0x0400) {
 678.673 +                NEEDBITS(16);
 678.674 +                state->length = (unsigned)(hold);
 678.675 +                if (state->head != Z_NULL)
 678.676 +                    state->head->extra_len = (unsigned)hold;
 678.677 +                if (state->flags & 0x0200) CRC2(state->check, hold);
 678.678 +                INITBITS();
 678.679 +            }
 678.680 +            else if (state->head != Z_NULL)
 678.681 +                state->head->extra = Z_NULL;
 678.682 +            state->mode = EXTRA;
 678.683 +        case EXTRA:
 678.684 +            if (state->flags & 0x0400) {
 678.685 +                copy = state->length;
 678.686 +                if (copy > have) copy = have;
 678.687 +                if (copy) {
 678.688 +                    if (state->head != Z_NULL &&
 678.689 +                        state->head->extra != Z_NULL) {
 678.690 +                        len = state->head->extra_len - state->length;
 678.691 +                        zmemcpy(state->head->extra + len, next,
 678.692 +                                len + copy > state->head->extra_max ?
 678.693 +                                state->head->extra_max - len : copy);
 678.694 +                    }
 678.695 +                    if (state->flags & 0x0200)
 678.696 +                        state->check = crc32(state->check, next, copy);
 678.697 +                    have -= copy;
 678.698 +                    next += copy;
 678.699 +                    state->length -= copy;
 678.700 +                }
 678.701 +                if (state->length) goto inf_leave;
 678.702 +            }
 678.703 +            state->length = 0;
 678.704 +            state->mode = NAME;
 678.705 +        case NAME:
 678.706 +            if (state->flags & 0x0800) {
 678.707 +                if (have == 0) goto inf_leave;
 678.708 +                copy = 0;
 678.709 +                do {
 678.710 +                    len = (unsigned)(next[copy++]);
 678.711 +                    if (state->head != Z_NULL &&
 678.712 +                            state->head->name != Z_NULL &&
 678.713 +                            state->length < state->head->name_max)
 678.714 +                        state->head->name[state->length++] = len;
 678.715 +                } while (len && copy < have);
 678.716 +                if (state->flags & 0x0200)
 678.717 +                    state->check = crc32(state->check, next, copy);
 678.718 +                have -= copy;
 678.719 +                next += copy;
 678.720 +                if (len) goto inf_leave;
 678.721 +            }
 678.722 +            else if (state->head != Z_NULL)
 678.723 +                state->head->name = Z_NULL;
 678.724 +            state->length = 0;
 678.725 +            state->mode = COMMENT;
 678.726 +        case COMMENT:
 678.727 +            if (state->flags & 0x1000) {
 678.728 +                if (have == 0) goto inf_leave;
 678.729 +                copy = 0;
 678.730 +                do {
 678.731 +                    len = (unsigned)(next[copy++]);
 678.732 +                    if (state->head != Z_NULL &&
 678.733 +                            state->head->comment != Z_NULL &&
 678.734 +                            state->length < state->head->comm_max)
 678.735 +                        state->head->comment[state->length++] = len;
 678.736 +                } while (len && copy < have);
 678.737 +                if (state->flags & 0x0200)
 678.738 +                    state->check = crc32(state->check, next, copy);
 678.739 +                have -= copy;
 678.740 +                next += copy;
 678.741 +                if (len) goto inf_leave;
 678.742 +            }
 678.743 +            else if (state->head != Z_NULL)
 678.744 +                state->head->comment = Z_NULL;
 678.745 +            state->mode = HCRC;
 678.746 +        case HCRC:
 678.747 +            if (state->flags & 0x0200) {
 678.748 +                NEEDBITS(16);
 678.749 +                if (hold != (state->check & 0xffff)) {
 678.750 +                    strm->msg = (char *)"header crc mismatch";
 678.751 +                    state->mode = BAD;
 678.752 +                    break;
 678.753 +                }
 678.754 +                INITBITS();
 678.755 +            }
 678.756 +            if (state->head != Z_NULL) {
 678.757 +                state->head->hcrc = (int)((state->flags >> 9) & 1);
 678.758 +                state->head->done = 1;
 678.759 +            }
 678.760 +            strm->adler = state->check = crc32(0L, Z_NULL, 0);
 678.761 +            state->mode = TYPE;
 678.762 +            break;
 678.763 +#endif
 678.764 +        case DICTID:
 678.765 +            NEEDBITS(32);
 678.766 +            strm->adler = state->check = REVERSE(hold);
 678.767 +            INITBITS();
 678.768 +            state->mode = DICT;
 678.769 +        case DICT:
 678.770 +            if (state->havedict == 0) {
 678.771 +                RESTORE();
 678.772 +                return Z_NEED_DICT;
 678.773 +            }
 678.774 +            strm->adler = state->check = adler32(0L, Z_NULL, 0);
 678.775 +            state->mode = TYPE;
 678.776 +        case TYPE:
 678.777 +            if (flush == Z_BLOCK) goto inf_leave;
 678.778 +        case TYPEDO:
 678.779 +            if (state->last) {
 678.780 +                BYTEBITS();
 678.781 +                state->mode = CHECK;
 678.782 +                break;
 678.783 +            }
 678.784 +            NEEDBITS(3);
 678.785 +            state->last = BITS(1);
 678.786 +            DROPBITS(1);
 678.787 +            switch (BITS(2)) {
 678.788 +            case 0:                             /* stored block */
 678.789 +                Tracev((stderr, "inflate:     stored block%s\n",
 678.790 +                        state->last ? " (last)" : ""));
 678.791 +                state->mode = STORED;
 678.792 +                break;
 678.793 +            case 1:                             /* fixed block */
 678.794 +                fixedtables(state);
 678.795 +                Tracev((stderr, "inflate:     fixed codes block%s\n",
 678.796 +                        state->last ? " (last)" : ""));
 678.797 +                state->mode = LEN;              /* decode codes */
 678.798 +                break;
 678.799 +            case 2:                             /* dynamic block */
 678.800 +                Tracev((stderr, "inflate:     dynamic codes block%s\n",
 678.801 +                        state->last ? " (last)" : ""));
 678.802 +                state->mode = TABLE;
 678.803 +                break;
 678.804 +            case 3:
 678.805 +                strm->msg = (char *)"invalid block type";
 678.806 +                state->mode = BAD;
 678.807 +            }
 678.808 +            DROPBITS(2);
 678.809 +            break;
 678.810 +        case STORED:
 678.811 +            BYTEBITS();                         /* go to byte boundary */
 678.812 +            NEEDBITS(32);
 678.813 +            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
 678.814 +                strm->msg = (char *)"invalid stored block lengths";
 678.815 +                state->mode = BAD;
 678.816 +                break;
 678.817 +            }
 678.818 +            state->length = (unsigned)hold & 0xffff;
 678.819 +            Tracev((stderr, "inflate:       stored length %u\n",
 678.820 +                    state->length));
 678.821 +            INITBITS();
 678.822 +            state->mode = COPY;
 678.823 +        case COPY:
 678.824 +            copy = state->length;
 678.825 +            if (copy) {
 678.826 +                if (copy > have) copy = have;
 678.827 +                if (copy > left) copy = left;
 678.828 +                if (copy == 0) goto inf_leave;
 678.829 +                zmemcpy(put, next, copy);
 678.830 +                have -= copy;
 678.831 +                next += copy;
 678.832 +                left -= copy;
 678.833 +                put += copy;
 678.834 +                state->length -= copy;
 678.835 +                break;
 678.836 +            }
 678.837 +            Tracev((stderr, "inflate:       stored end\n"));
 678.838 +            state->mode = TYPE;
 678.839 +            break;
 678.840 +        case TABLE:
 678.841 +            NEEDBITS(14);
 678.842 +            state->nlen = BITS(5) + 257;
 678.843 +            DROPBITS(5);
 678.844 +            state->ndist = BITS(5) + 1;
 678.845 +            DROPBITS(5);
 678.846 +            state->ncode = BITS(4) + 4;
 678.847 +            DROPBITS(4);
 678.848 +#ifndef PKZIP_BUG_WORKAROUND
 678.849 +            if (state->nlen > 286 || state->ndist > 30) {
 678.850 +                strm->msg = (char *)"too many length or distance symbols";
 678.851 +                state->mode = BAD;
 678.852 +                break;
 678.853 +            }
 678.854 +#endif
 678.855 +            Tracev((stderr, "inflate:       table sizes ok\n"));
 678.856 +            state->have = 0;
 678.857 +            state->mode = LENLENS;
 678.858 +        case LENLENS:
 678.859 +            while (state->have < state->ncode) {
 678.860 +                NEEDBITS(3);
 678.861 +                state->lens[order[state->have++]] = (unsigned short)BITS(3);
 678.862 +                DROPBITS(3);
 678.863 +            }
 678.864 +            while (state->have < 19)
 678.865 +                state->lens[order[state->have++]] = 0;
 678.866 +            state->next = state->codes;
 678.867 +            state->lencode = (code const FAR *)(state->next);
 678.868 +            state->lenbits = 7;
 678.869 +            ret = inflate_table(CODES, state->lens, 19, &(state->next),
 678.870 +                                &(state->lenbits), state->work);
 678.871 +            if (ret) {
 678.872 +                strm->msg = (char *)"invalid code lengths set";
 678.873 +                state->mode = BAD;
 678.874 +                break;
 678.875 +            }
 678.876 +            Tracev((stderr, "inflate:       code lengths ok\n"));
 678.877 +            state->have = 0;
 678.878 +            state->mode = CODELENS;
 678.879 +        case CODELENS:
 678.880 +            while (state->have < state->nlen + state->ndist) {
 678.881 +                for (;;) {
 678.882 +                    this = state->lencode[BITS(state->lenbits)];
 678.883 +                    if ((unsigned)(this.bits) <= bits) break;
 678.884 +                    PULLBYTE();
 678.885 +                }
 678.886 +                if (this.val < 16) {
 678.887 +                    NEEDBITS(this.bits);
 678.888 +                    DROPBITS(this.bits);
 678.889 +                    state->lens[state->have++] = this.val;
 678.890 +                }
 678.891 +                else {
 678.892 +                    if (this.val == 16) {
 678.893 +                        NEEDBITS(this.bits + 2);
 678.894 +                        DROPBITS(this.bits);
 678.895 +                        if (state->have == 0) {
 678.896 +                            strm->msg = (char *)"invalid bit length repeat";
 678.897 +                            state->mode = BAD;
 678.898 +                            break;
 678.899 +                        }
 678.900 +                        len = state->lens[state->have - 1];
 678.901 +                        copy = 3 + BITS(2);
 678.902 +                        DROPBITS(2);
 678.903 +                    }
 678.904 +                    else if (this.val == 17) {
 678.905 +                        NEEDBITS(this.bits + 3);
 678.906 +                        DROPBITS(this.bits);
 678.907 +                        len = 0;
 678.908 +                        copy = 3 + BITS(3);
 678.909 +                        DROPBITS(3);
 678.910 +                    }
 678.911 +                    else {
 678.912 +                        NEEDBITS(this.bits + 7);
 678.913 +                        DROPBITS(this.bits);
 678.914 +                        len = 0;
 678.915 +                        copy = 11 + BITS(7);
 678.916 +                        DROPBITS(7);
 678.917 +                    }
 678.918 +                    if (state->have + copy > state->nlen + state->ndist) {
 678.919 +                        strm->msg = (char *)"invalid bit length repeat";
 678.920 +                        state->mode = BAD;
 678.921 +                        break;
 678.922 +                    }
 678.923 +                    while (copy--)
 678.924 +                        state->lens[state->have++] = (unsigned short)len;
 678.925 +                }
 678.926 +            }
 678.927 +
 678.928 +            /* handle error breaks in while */
 678.929 +            if (state->mode == BAD) break;
 678.930 +
 678.931 +            /* build code tables */
 678.932 +            state->next = state->codes;
 678.933 +            state->lencode = (code const FAR *)(state->next);
 678.934 +            state->lenbits = 9;
 678.935 +            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
 678.936 +                                &(state->lenbits), state->work);
 678.937 +            if (ret) {
 678.938 +                strm->msg = (char *)"invalid literal/lengths set";
 678.939 +                state->mode = BAD;
 678.940 +                break;
 678.941 +            }
 678.942 +            state->distcode = (code const FAR *)(state->next);
 678.943 +            state->distbits = 6;
 678.944 +            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
 678.945 +                            &(state->next), &(state->distbits), state->work);
 678.946 +            if (ret) {
 678.947 +                strm->msg = (char *)"invalid distances set";
 678.948 +                state->mode = BAD;
 678.949 +                break;
 678.950 +            }
 678.951 +            Tracev((stderr, "inflate:       codes ok\n"));
 678.952 +            state->mode = LEN;
 678.953 +        case LEN:
 678.954 +            if (have >= 6 && left >= 258) {
 678.955 +                RESTORE();
 678.956 +                inflate_fast(strm, out);
 678.957 +                LOAD();
 678.958 +                break;
 678.959 +            }
 678.960 +            for (;;) {
 678.961 +                this = state->lencode[BITS(state->lenbits)];
 678.962 +                if ((unsigned)(this.bits) <= bits) break;
 678.963 +                PULLBYTE();
 678.964 +            }
 678.965 +            if (this.op && (this.op & 0xf0) == 0) {
 678.966 +                last = this;
 678.967 +                for (;;) {
 678.968 +                    this = state->lencode[last.val +
 678.969 +                            (BITS(last.bits + last.op) >> last.bits)];
 678.970 +                    if ((unsigned)(last.bits + this.bits) <= bits) break;
 678.971 +                    PULLBYTE();
 678.972 +                }
 678.973 +                DROPBITS(last.bits);
 678.974 +            }
 678.975 +            DROPBITS(this.bits);
 678.976 +            state->length = (unsigned)this.val;
 678.977 +            if ((int)(this.op) == 0) {
 678.978 +                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
 678.979 +                        "inflate:         literal '%c'\n" :
 678.980 +                        "inflate:         literal 0x%02x\n", this.val));
 678.981 +                state->mode = LIT;
 678.982 +                break;
 678.983 +            }
 678.984 +            if (this.op & 32) {
 678.985 +                Tracevv((stderr, "inflate:         end of block\n"));
 678.986 +                state->mode = TYPE;
 678.987 +                break;
 678.988 +            }
 678.989 +            if (this.op & 64) {
 678.990 +                strm->msg = (char *)"invalid literal/length code";
 678.991 +                state->mode = BAD;
 678.992 +                break;
 678.993 +            }
 678.994 +            state->extra = (unsigned)(this.op) & 15;
 678.995 +            state->mode = LENEXT;
 678.996 +        case LENEXT:
 678.997 +            if (state->extra) {
 678.998 +                NEEDBITS(state->extra);
 678.999 +                state->length += BITS(state->extra);
678.1000 +                DROPBITS(state->extra);
678.1001 +            }
678.1002 +            Tracevv((stderr, "inflate:         length %u\n", state->length));
678.1003 +            state->mode = DIST;
678.1004 +        case DIST:
678.1005 +            for (;;) {
678.1006 +                this = state->distcode[BITS(state->distbits)];
678.1007 +                if ((unsigned)(this.bits) <= bits) break;
678.1008 +                PULLBYTE();
678.1009 +            }
678.1010 +            if ((this.op & 0xf0) == 0) {
678.1011 +                last = this;
678.1012 +                for (;;) {
678.1013 +                    this = state->distcode[last.val +
678.1014 +                            (BITS(last.bits + last.op) >> last.bits)];
678.1015 +                    if ((unsigned)(last.bits + this.bits) <= bits) break;
678.1016 +                    PULLBYTE();
678.1017 +                }
678.1018 +                DROPBITS(last.bits);
678.1019 +            }
678.1020 +            DROPBITS(this.bits);
678.1021 +            if (this.op & 64) {
678.1022 +                strm->msg = (char *)"invalid distance code";
678.1023 +                state->mode = BAD;
678.1024 +                break;
678.1025 +            }
678.1026 +            state->offset = (unsigned)this.val;
678.1027 +            state->extra = (unsigned)(this.op) & 15;
678.1028 +            state->mode = DISTEXT;
678.1029 +        case DISTEXT:
678.1030 +            if (state->extra) {
678.1031 +                NEEDBITS(state->extra);
678.1032 +                state->offset += BITS(state->extra);
678.1033 +                DROPBITS(state->extra);
678.1034 +            }
678.1035 +#ifdef INFLATE_STRICT
678.1036 +            if (state->offset > state->dmax) {
678.1037 +                strm->msg = (char *)"invalid distance too far back";
678.1038 +                state->mode = BAD;
678.1039 +                break;
678.1040 +            }
678.1041 +#endif
678.1042 +            if (state->offset > state->whave + out - left) {
678.1043 +                strm->msg = (char *)"invalid distance too far back";
678.1044 +                state->mode = BAD;
678.1045 +                break;
678.1046 +            }
678.1047 +            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
678.1048 +            state->mode = MATCH;
678.1049 +        case MATCH:
678.1050 +            if (left == 0) goto inf_leave;
678.1051 +            copy = out - left;
678.1052 +            if (state->offset > copy) {         /* copy from window */
678.1053 +                copy = state->offset - copy;
678.1054 +                if (copy > state->write) {
678.1055 +                    copy -= state->write;
678.1056 +                    from = state->window + (state->wsize - copy);
678.1057 +                }
678.1058 +                else
678.1059 +                    from = state->window + (state->write - copy);
678.1060 +                if (copy > state->length) copy = state->length;
678.1061 +            }
678.1062 +            else {                              /* copy from output */
678.1063 +                from = put - state->offset;
678.1064 +                copy = state->length;
678.1065 +            }
678.1066 +            if (copy > left) copy = left;
678.1067 +            left -= copy;
678.1068 +            state->length -= copy;
678.1069 +            do {
678.1070 +                *put++ = *from++;
678.1071 +            } while (--copy);
678.1072 +            if (state->length == 0) state->mode = LEN;
678.1073 +            break;
678.1074 +        case LIT:
678.1075 +            if (left == 0) goto inf_leave;
678.1076 +            *put++ = (unsigned char)(state->length);
678.1077 +            left--;
678.1078 +            state->mode = LEN;
678.1079 +            break;
678.1080 +        case CHECK:
678.1081 +            if (state->wrap) {
678.1082 +                NEEDBITS(32);
678.1083 +                out -= left;
678.1084 +                strm->total_out += out;
678.1085 +                state->total += out;
678.1086 +                if (out)
678.1087 +                    strm->adler = state->check =
678.1088 +                        UPDATE(state->check, put - out, out);
678.1089 +                out = left;
678.1090 +                if ((
678.1091 +#ifdef GUNZIP
678.1092 +                     state->flags ? hold :
678.1093 +#endif
678.1094 +                     REVERSE(hold)) != state->check) {
678.1095 +                    strm->msg = (char *)"incorrect data check";
678.1096 +                    state->mode = BAD;
678.1097 +                    break;
678.1098 +                }
678.1099 +                INITBITS();
678.1100 +                Tracev((stderr, "inflate:   check matches trailer\n"));
678.1101 +            }
678.1102 +#ifdef GUNZIP
678.1103 +            state->mode = LENGTH;
678.1104 +        case LENGTH:
678.1105 +            if (state->wrap && state->flags) {
678.1106 +                NEEDBITS(32);
678.1107 +                if (hold != (state->total & 0xffffffffUL)) {
678.1108 +                    strm->msg = (char *)"incorrect length check";
678.1109 +                    state->mode = BAD;
678.1110 +                    break;
678.1111 +                }
678.1112 +                INITBITS();
678.1113 +                Tracev((stderr, "inflate:   length matches trailer\n"));
678.1114 +            }
678.1115 +#endif
678.1116 +            state->mode = DONE;
678.1117 +        case DONE:
678.1118 +            ret = Z_STREAM_END;
678.1119 +            goto inf_leave;
678.1120 +        case BAD:
678.1121 +            ret = Z_DATA_ERROR;
678.1122 +            goto inf_leave;
678.1123 +        case MEM:
678.1124 +            return Z_MEM_ERROR;
678.1125 +        case SYNC:
678.1126 +        default:
678.1127 +            return Z_STREAM_ERROR;
678.1128 +        }
678.1129 +
678.1130 +    /*
678.1131 +       Return from inflate(), updating the total counts and the check value.
678.1132 +       If there was no progress during the inflate() call, return a buffer
678.1133 +       error.  Call updatewindow() to create and/or update the window state.
678.1134 +       Note: a memory error from inflate() is non-recoverable.
678.1135 +     */
678.1136 +  inf_leave:
678.1137 +    RESTORE();
678.1138 +    if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
678.1139 +        if (updatewindow(strm, out)) {
678.1140 +            state->mode = MEM;
678.1141 +            return Z_MEM_ERROR;
678.1142 +        }
678.1143 +    in -= strm->avail_in;
678.1144 +    out -= strm->avail_out;
678.1145 +    strm->total_in += in;
678.1146 +    strm->total_out += out;
678.1147 +    state->total += out;
678.1148 +    if (state->wrap && out)
678.1149 +        strm->adler = state->check =
678.1150 +            UPDATE(state->check, strm->next_out - out, out);
678.1151 +    strm->data_type = state->bits + (state->last ? 64 : 0) +
678.1152 +                      (state->mode == TYPE ? 128 : 0);
678.1153 +    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
678.1154 +        ret = Z_BUF_ERROR;
678.1155 +    return ret;
678.1156 +}
678.1157 +
678.1158 +int ZEXPORT inflateEnd(strm)
678.1159 +z_streamp strm;
678.1160 +{
678.1161 +    struct inflate_state FAR *state;
678.1162 +    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
678.1163 +        return Z_STREAM_ERROR;
678.1164 +    state = (struct inflate_state FAR *)strm->state;
678.1165 +    if (state->window != Z_NULL) ZFREE(strm, state->window);
678.1166 +    ZFREE(strm, strm->state);
678.1167 +    strm->state = Z_NULL;
678.1168 +    Tracev((stderr, "inflate: end\n"));
678.1169 +    return Z_OK;
678.1170 +}
678.1171 +
678.1172 +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
678.1173 +z_streamp strm;
678.1174 +const Bytef *dictionary;
678.1175 +uInt dictLength;
678.1176 +{
678.1177 +    struct inflate_state FAR *state;
678.1178 +    unsigned long id;
678.1179 +
678.1180 +    /* check state */
678.1181 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
678.1182 +    state = (struct inflate_state FAR *)strm->state;
678.1183 +    if (state->wrap != 0 && state->mode != DICT)
678.1184 +        return Z_STREAM_ERROR;
678.1185 +
678.1186 +    /* check for correct dictionary id */
678.1187 +    if (state->mode == DICT) {
678.1188 +        id = adler32(0L, Z_NULL, 0);
678.1189 +        id = adler32(id, dictionary, dictLength);
678.1190 +        if (id != state->check)
678.1191 +            return Z_DATA_ERROR;
678.1192 +    }
678.1193 +
678.1194 +    /* copy dictionary to window */
678.1195 +    if (updatewindow(strm, strm->avail_out)) {
678.1196 +        state->mode = MEM;
678.1197 +        return Z_MEM_ERROR;
678.1198 +    }
678.1199 +    if (dictLength > state->wsize) {
678.1200 +        zmemcpy(state->window, dictionary + dictLength - state->wsize,
678.1201 +                state->wsize);
678.1202 +        state->whave = state->wsize;
678.1203 +    }
678.1204 +    else {
678.1205 +        zmemcpy(state->window + state->wsize - dictLength, dictionary,
678.1206 +                dictLength);
678.1207 +        state->whave = dictLength;
678.1208 +    }
678.1209 +    state->havedict = 1;
678.1210 +    Tracev((stderr, "inflate:   dictionary set\n"));
678.1211 +    return Z_OK;
678.1212 +}
678.1213 +
678.1214 +int ZEXPORT inflateGetHeader(strm, head)
678.1215 +z_streamp strm;
678.1216 +gz_headerp head;
678.1217 +{
678.1218 +    struct inflate_state FAR *state;
678.1219 +
678.1220 +    /* check state */
678.1221 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
678.1222 +    state = (struct inflate_state FAR *)strm->state;
678.1223 +    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
678.1224 +
678.1225 +    /* save header structure */
678.1226 +    state->head = head;
678.1227 +    head->done = 0;
678.1228 +    return Z_OK;
678.1229 +}
678.1230 +
678.1231 +/*
678.1232 +   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
678.1233 +   or when out of input.  When called, *have is the number of pattern bytes
678.1234 +   found in order so far, in 0..3.  On return *have is updated to the new
678.1235 +   state.  If on return *have equals four, then the pattern was found and the
678.1236 +   return value is how many bytes were read including the last byte of the
678.1237 +   pattern.  If *have is less than four, then the pattern has not been found
678.1238 +   yet and the return value is len.  In the latter case, syncsearch() can be
678.1239 +   called again with more data and the *have state.  *have is initialized to
678.1240 +   zero for the first call.
678.1241 + */
678.1242 +local unsigned syncsearch(have, buf, len)
678.1243 +unsigned FAR *have;
678.1244 +unsigned char FAR *buf;
678.1245 +unsigned len;
678.1246 +{
678.1247 +    unsigned got;
678.1248 +    unsigned next;
678.1249 +
678.1250 +    got = *have;
678.1251 +    next = 0;
678.1252 +    while (next < len && got < 4) {
678.1253 +        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
678.1254 +            got++;
678.1255 +        else if (buf[next])
678.1256 +            got = 0;
678.1257 +        else
678.1258 +            got = 4 - got;
678.1259 +        next++;
678.1260 +    }
678.1261 +    *have = got;
678.1262 +    return next;
678.1263 +}
678.1264 +
678.1265 +int ZEXPORT inflateSync(strm)
678.1266 +z_streamp strm;
678.1267 +{
678.1268 +    unsigned len;               /* number of bytes to look at or looked at */
678.1269 +    unsigned long in, out;      /* temporary to save total_in and total_out */
678.1270 +    unsigned char buf[4];       /* to restore bit buffer to byte string */
678.1271 +    struct inflate_state FAR *state;
678.1272 +
678.1273 +    /* check parameters */
678.1274 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
678.1275 +    state = (struct inflate_state FAR *)strm->state;
678.1276 +    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
678.1277 +
678.1278 +    /* if first time, start search in bit buffer */
678.1279 +    if (state->mode != SYNC) {
678.1280 +        state->mode = SYNC;
678.1281 +        state->hold <<= state->bits & 7;
678.1282 +        state->bits -= state->bits & 7;
678.1283 +        len = 0;
678.1284 +        while (state->bits >= 8) {
678.1285 +            buf[len++] = (unsigned char)(state->hold);
678.1286 +            state->hold >>= 8;
678.1287 +            state->bits -= 8;
678.1288 +        }
678.1289 +        state->have = 0;
678.1290 +        syncsearch(&(state->have), buf, len);
678.1291 +    }
678.1292 +
678.1293 +    /* search available input */
678.1294 +    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
678.1295 +    strm->avail_in -= len;
678.1296 +    strm->next_in += len;
678.1297 +    strm->total_in += len;
678.1298 +
678.1299 +    /* return no joy or set up to restart inflate() on a new block */
678.1300 +    if (state->have != 4) return Z_DATA_ERROR;
678.1301 +    in = strm->total_in;  out = strm->total_out;
678.1302 +    inflateReset(strm);
678.1303 +    strm->total_in = in;  strm->total_out = out;
678.1304 +    state->mode = TYPE;
678.1305 +    return Z_OK;
678.1306 +}
678.1307 +
678.1308 +/*
678.1309 +   Returns true if inflate is currently at the end of a block generated by
678.1310 +   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
678.1311 +   implementation to provide an additional safety check. PPP uses
678.1312 +   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
678.1313 +   block. When decompressing, PPP checks that at the end of input packet,
678.1314 +   inflate is waiting for these length bytes.
678.1315 + */
678.1316 +int ZEXPORT inflateSyncPoint(strm)
678.1317 +z_streamp strm;
678.1318 +{
678.1319 +    struct inflate_state FAR *state;
678.1320 +
678.1321 +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
678.1322 +    state = (struct inflate_state FAR *)strm->state;
678.1323 +    return state->mode == STORED && state->bits == 0;
678.1324 +}
678.1325 +
678.1326 +int ZEXPORT inflateCopy(dest, source)
678.1327 +z_streamp dest;
678.1328 +z_streamp source;
678.1329 +{
678.1330 +    struct inflate_state FAR *state;
678.1331 +    struct inflate_state FAR *copy;
678.1332 +    unsigned char FAR *window;
678.1333 +    unsigned wsize;
678.1334 +
678.1335 +    /* check input */
678.1336 +    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
678.1337 +        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
678.1338 +        return Z_STREAM_ERROR;
678.1339 +    state = (struct inflate_state FAR *)source->state;
678.1340 +
678.1341 +    /* allocate space */
678.1342 +    copy = (struct inflate_state FAR *)
678.1343 +           ZALLOC(source, 1, sizeof(struct inflate_state));
678.1344 +    if (copy == Z_NULL) return Z_MEM_ERROR;
678.1345 +    window = Z_NULL;
678.1346 +    if (state->window != Z_NULL) {
678.1347 +        window = (unsigned char FAR *)
678.1348 +                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
678.1349 +        if (window == Z_NULL) {
678.1350 +            ZFREE(source, copy);
678.1351 +            return Z_MEM_ERROR;
678.1352 +        }
678.1353 +    }
678.1354 +
678.1355 +    /* copy state */
678.1356 +    zmemcpy(dest, source, sizeof(z_stream));
678.1357 +    zmemcpy(copy, state, sizeof(struct inflate_state));
678.1358 +    if (state->lencode >= state->codes &&
678.1359 +        state->lencode <= state->codes + ENOUGH - 1) {
678.1360 +        copy->lencode = copy->codes + (state->lencode - state->codes);
678.1361 +        copy->distcode = copy->codes + (state->distcode - state->codes);
678.1362 +    }
678.1363 +    copy->next = copy->codes + (state->next - state->codes);
678.1364 +    if (window != Z_NULL) {
678.1365 +        wsize = 1U << state->wbits;
678.1366 +        zmemcpy(window, state->window, wsize);
678.1367 +    }
678.1368 +    copy->window = window;
678.1369 +    dest->state = (struct internal_state FAR *)copy;
678.1370 +    return Z_OK;
678.1371 +}
   679.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   679.2 +++ b/libs/zlib/inflate.h	Sat Feb 01 19:58:19 2014 +0200
   679.3 @@ -0,0 +1,115 @@
   679.4 +/* inflate.h -- internal inflate state definition
   679.5 + * Copyright (C) 1995-2004 Mark Adler
   679.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   679.7 + */
   679.8 +
   679.9 +/* WARNING: this file should *not* be used by applications. It is
  679.10 +   part of the implementation of the compression library and is
  679.11 +   subject to change. Applications should only use zlib.h.
  679.12 + */
  679.13 +
  679.14 +/* define NO_GZIP when compiling if you want to disable gzip header and
  679.15 +   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
  679.16 +   the crc code when it is not needed.  For shared libraries, gzip decoding
  679.17 +   should be left enabled. */
  679.18 +#ifndef NO_GZIP
  679.19 +#  define GUNZIP
  679.20 +#endif
  679.21 +
  679.22 +/* Possible inflate modes between inflate() calls */
  679.23 +typedef enum {
  679.24 +    HEAD,       /* i: waiting for magic header */
  679.25 +    FLAGS,      /* i: waiting for method and flags (gzip) */
  679.26 +    TIME,       /* i: waiting for modification time (gzip) */
  679.27 +    OS,         /* i: waiting for extra flags and operating system (gzip) */
  679.28 +    EXLEN,      /* i: waiting for extra length (gzip) */
  679.29 +    EXTRA,      /* i: waiting for extra bytes (gzip) */
  679.30 +    NAME,       /* i: waiting for end of file name (gzip) */
  679.31 +    COMMENT,    /* i: waiting for end of comment (gzip) */
  679.32 +    HCRC,       /* i: waiting for header crc (gzip) */
  679.33 +    DICTID,     /* i: waiting for dictionary check value */
  679.34 +    DICT,       /* waiting for inflateSetDictionary() call */
  679.35 +        TYPE,       /* i: waiting for type bits, including last-flag bit */
  679.36 +        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
  679.37 +        STORED,     /* i: waiting for stored size (length and complement) */
  679.38 +        COPY,       /* i/o: waiting for input or output to copy stored block */
  679.39 +        TABLE,      /* i: waiting for dynamic block table lengths */
  679.40 +        LENLENS,    /* i: waiting for code length code lengths */
  679.41 +        CODELENS,   /* i: waiting for length/lit and distance code lengths */
  679.42 +            LEN,        /* i: waiting for length/lit code */
  679.43 +            LENEXT,     /* i: waiting for length extra bits */
  679.44 +            DIST,       /* i: waiting for distance code */
  679.45 +            DISTEXT,    /* i: waiting for distance extra bits */
  679.46 +            MATCH,      /* o: waiting for output space to copy string */
  679.47 +            LIT,        /* o: waiting for output space to write literal */
  679.48 +    CHECK,      /* i: waiting for 32-bit check value */
  679.49 +    LENGTH,     /* i: waiting for 32-bit length (gzip) */
  679.50 +    DONE,       /* finished check, done -- remain here until reset */
  679.51 +    BAD,        /* got a data error -- remain here until reset */
  679.52 +    MEM,        /* got an inflate() memory error -- remain here until reset */
  679.53 +    SYNC        /* looking for synchronization bytes to restart inflate() */
  679.54 +} inflate_mode;
  679.55 +
  679.56 +/*
  679.57 +    State transitions between above modes -
  679.58 +
  679.59 +    (most modes can go to the BAD or MEM mode -- not shown for clarity)
  679.60 +
  679.61 +    Process header:
  679.62 +        HEAD -> (gzip) or (zlib)
  679.63 +        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
  679.64 +        NAME -> COMMENT -> HCRC -> TYPE
  679.65 +        (zlib) -> DICTID or TYPE
  679.66 +        DICTID -> DICT -> TYPE
  679.67 +    Read deflate blocks:
  679.68 +            TYPE -> STORED or TABLE or LEN or CHECK
  679.69 +            STORED -> COPY -> TYPE
  679.70 +            TABLE -> LENLENS -> CODELENS -> LEN
  679.71 +    Read deflate codes:
  679.72 +                LEN -> LENEXT or LIT or TYPE
  679.73 +                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
  679.74 +                LIT -> LEN
  679.75 +    Process trailer:
  679.76 +        CHECK -> LENGTH -> DONE
  679.77 + */
  679.78 +
  679.79 +/* state maintained between inflate() calls.  Approximately 7K bytes. */
  679.80 +struct inflate_state {
  679.81 +    inflate_mode mode;          /* current inflate mode */
  679.82 +    int last;                   /* true if processing last block */
  679.83 +    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
  679.84 +    int havedict;               /* true if dictionary provided */
  679.85 +    int flags;                  /* gzip header method and flags (0 if zlib) */
  679.86 +    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
  679.87 +    unsigned long check;        /* protected copy of check value */
  679.88 +    unsigned long total;        /* protected copy of output count */
  679.89 +    gz_headerp head;            /* where to save gzip header information */
  679.90 +        /* sliding window */
  679.91 +    unsigned wbits;             /* log base 2 of requested window size */
  679.92 +    unsigned wsize;             /* window size or zero if not using window */
  679.93 +    unsigned whave;             /* valid bytes in the window */
  679.94 +    unsigned write;             /* window write index */
  679.95 +    unsigned char FAR *window;  /* allocated sliding window, if needed */
  679.96 +        /* bit accumulator */
  679.97 +    unsigned long hold;         /* input bit accumulator */
  679.98 +    unsigned bits;              /* number of bits in "in" */
  679.99 +        /* for string and stored block copying */
 679.100 +    unsigned length;            /* literal or length of data to copy */
 679.101 +    unsigned offset;            /* distance back to copy string from */
 679.102 +        /* for table and code decoding */
 679.103 +    unsigned extra;             /* extra bits needed */
 679.104 +        /* fixed and dynamic code tables */
 679.105 +    code const FAR *lencode;    /* starting table for length/literal codes */
 679.106 +    code const FAR *distcode;   /* starting table for distance codes */
 679.107 +    unsigned lenbits;           /* index bits for lencode */
 679.108 +    unsigned distbits;          /* index bits for distcode */
 679.109 +        /* dynamic table building */
 679.110 +    unsigned ncode;             /* number of code length code lengths */
 679.111 +    unsigned nlen;              /* number of length code lengths */
 679.112 +    unsigned ndist;             /* number of distance code lengths */
 679.113 +    unsigned have;              /* number of code lengths in lens[] */
 679.114 +    code FAR *next;             /* next available space in codes[] */
 679.115 +    unsigned short lens[320];   /* temporary storage for code lengths */
 679.116 +    unsigned short work[288];   /* work area for code table building */
 679.117 +    code codes[ENOUGH];         /* space for code tables */
 679.118 +};
   680.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   680.2 +++ b/libs/zlib/inftrees.c	Sat Feb 01 19:58:19 2014 +0200
   680.3 @@ -0,0 +1,329 @@
   680.4 +/* inftrees.c -- generate Huffman trees for efficient decoding
   680.5 + * Copyright (C) 1995-2005 Mark Adler
   680.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   680.7 + */
   680.8 +
   680.9 +#include "zutil.h"
  680.10 +#include "inftrees.h"
  680.11 +
  680.12 +#define MAXBITS 15
  680.13 +
  680.14 +const char inflate_copyright[] =
  680.15 +   " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
  680.16 +/*
  680.17 +  If you use the zlib library in a product, an acknowledgment is welcome
  680.18 +  in the documentation of your product. If for some reason you cannot
  680.19 +  include such an acknowledgment, I would appreciate that you keep this
  680.20 +  copyright string in the executable of your product.
  680.21 + */
  680.22 +
  680.23 +/*
  680.24 +   Build a set of tables to decode the provided canonical Huffman code.
  680.25 +   The code lengths are lens[0..codes-1].  The result starts at *table,
  680.26 +   whose indices are 0..2^bits-1.  work is a writable array of at least
  680.27 +   lens shorts, which is used as a work area.  type is the type of code
  680.28 +   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
  680.29 +   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
  680.30 +   on return points to the next available entry's address.  bits is the
  680.31 +   requested root table index bits, and on return it is the actual root
  680.32 +   table index bits.  It will differ if the request is greater than the
  680.33 +   longest code or if it is less than the shortest code.
  680.34 + */
  680.35 +int inflate_table(type, lens, codes, table, bits, work)
  680.36 +codetype type;
  680.37 +unsigned short FAR *lens;
  680.38 +unsigned codes;
  680.39 +code FAR * FAR *table;
  680.40 +unsigned FAR *bits;
  680.41 +unsigned short FAR *work;
  680.42 +{
  680.43 +    unsigned len;               /* a code's length in bits */
  680.44 +    unsigned sym;               /* index of code symbols */
  680.45 +    unsigned min, max;          /* minimum and maximum code lengths */
  680.46 +    unsigned root;              /* number of index bits for root table */
  680.47 +    unsigned curr;              /* number of index bits for current table */
  680.48 +    unsigned drop;              /* code bits to drop for sub-table */
  680.49 +    int left;                   /* number of prefix codes available */
  680.50 +    unsigned used;              /* code entries in table used */
  680.51 +    unsigned huff;              /* Huffman code */
  680.52 +    unsigned incr;              /* for incrementing code, index */
  680.53 +    unsigned fill;              /* index for replicating entries */
  680.54 +    unsigned low;               /* low bits for current root entry */
  680.55 +    unsigned mask;              /* mask for low root bits */
  680.56 +    code this;                  /* table entry for duplication */
  680.57 +    code FAR *next;             /* next available space in table */
  680.58 +    const unsigned short FAR *base;     /* base value table to use */
  680.59 +    const unsigned short FAR *extra;    /* extra bits table to use */
  680.60 +    int end;                    /* use base and extra for symbol > end */
  680.61 +    unsigned short count[MAXBITS+1];    /* number of codes of each length */
  680.62 +    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
  680.63 +    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
  680.64 +        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
  680.65 +        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
  680.66 +    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
  680.67 +        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
  680.68 +        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
  680.69 +    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
  680.70 +        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
  680.71 +        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
  680.72 +        8193, 12289, 16385, 24577, 0, 0};
  680.73 +    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
  680.74 +        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
  680.75 +        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
  680.76 +        28, 28, 29, 29, 64, 64};
  680.77 +
  680.78 +    /*
  680.79 +       Process a set of code lengths to create a canonical Huffman code.  The
  680.80 +       code lengths are lens[0..codes-1].  Each length corresponds to the
  680.81 +       symbols 0..codes-1.  The Huffman code is generated by first sorting the
  680.82 +       symbols by length from short to long, and retaining the symbol order
  680.83 +       for codes with equal lengths.  Then the code starts with all zero bits
  680.84 +       for the first code of the shortest length, and the codes are integer
  680.85 +       increments for the same length, and zeros are appended as the length
  680.86 +       increases.  For the deflate format, these bits are stored backwards
  680.87 +       from their more natural integer increment ordering, and so when the
  680.88 +       decoding tables are built in the large loop below, the integer codes
  680.89 +       are incremented backwards.
  680.90 +
  680.91 +       This routine assumes, but does not check, that all of the entries in
  680.92 +       lens[] are in the range 0..MAXBITS.  The caller must assure this.
  680.93 +       1..MAXBITS is interpreted as that code length.  zero means that that
  680.94 +       symbol does not occur in this code.
  680.95 +
  680.96 +       The codes are sorted by computing a count of codes for each length,
  680.97 +       creating from that a table of starting indices for each length in the
  680.98 +       sorted table, and then entering the symbols in order in the sorted
  680.99 +       table.  The sorted table is work[], with that space being provided by
 680.100 +       the caller.
 680.101 +
 680.102 +       The length counts are used for other purposes as well, i.e. finding
 680.103 +       the minimum and maximum length codes, determining if there are any
 680.104 +       codes at all, checking for a valid set of lengths, and looking ahead
 680.105 +       at length counts to determine sub-table sizes when building the
 680.106 +       decoding tables.
 680.107 +     */
 680.108 +
 680.109 +    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
 680.110 +    for (len = 0; len <= MAXBITS; len++)
 680.111 +        count[len] = 0;
 680.112 +    for (sym = 0; sym < codes; sym++)
 680.113 +        count[lens[sym]]++;
 680.114 +
 680.115 +    /* bound code lengths, force root to be within code lengths */
 680.116 +    root = *bits;
 680.117 +    for (max = MAXBITS; max >= 1; max--)
 680.118 +        if (count[max] != 0) break;
 680.119 +    if (root > max) root = max;
 680.120 +    if (max == 0) {                     /* no symbols to code at all */
 680.121 +        this.op = (unsigned char)64;    /* invalid code marker */
 680.122 +        this.bits = (unsigned char)1;
 680.123 +        this.val = (unsigned short)0;
 680.124 +        *(*table)++ = this;             /* make a table to force an error */
 680.125 +        *(*table)++ = this;
 680.126 +        *bits = 1;
 680.127 +        return 0;     /* no symbols, but wait for decoding to report error */
 680.128 +    }
 680.129 +    for (min = 1; min <= MAXBITS; min++)
 680.130 +        if (count[min] != 0) break;
 680.131 +    if (root < min) root = min;
 680.132 +
 680.133 +    /* check for an over-subscribed or incomplete set of lengths */
 680.134 +    left = 1;
 680.135 +    for (len = 1; len <= MAXBITS; len++) {
 680.136 +        left <<= 1;
 680.137 +        left -= count[len];
 680.138 +        if (left < 0) return -1;        /* over-subscribed */
 680.139 +    }
 680.140 +    if (left > 0 && (type == CODES || max != 1))
 680.141 +        return -1;                      /* incomplete set */
 680.142 +
 680.143 +    /* generate offsets into symbol table for each length for sorting */
 680.144 +    offs[1] = 0;
 680.145 +    for (len = 1; len < MAXBITS; len++)
 680.146 +        offs[len + 1] = offs[len] + count[len];
 680.147 +
 680.148 +    /* sort symbols by length, by symbol order within each length */
 680.149 +    for (sym = 0; sym < codes; sym++)
 680.150 +        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
 680.151 +
 680.152 +    /*
 680.153 +       Create and fill in decoding tables.  In this loop, the table being
 680.154 +       filled is at next and has curr index bits.  The code being used is huff
 680.155 +       with length len.  That code is converted to an index by dropping drop
 680.156 +       bits off of the bottom.  For codes where len is less than drop + curr,
 680.157 +       those top drop + curr - len bits are incremented through all values to
 680.158 +       fill the table with replicated entries.
 680.159 +
 680.160 +       root is the number of index bits for the root table.  When len exceeds
 680.161 +       root, sub-tables are created pointed to by the root entry with an index
 680.162 +       of the low root bits of huff.  This is saved in low to check for when a
 680.163 +       new sub-table should be started.  drop is zero when the root table is
 680.164 +       being filled, and drop is root when sub-tables are being filled.
 680.165 +
 680.166 +       When a new sub-table is needed, it is necessary to look ahead in the
 680.167 +       code lengths to determine what size sub-table is needed.  The length
 680.168 +       counts are used for this, and so count[] is decremented as codes are
 680.169 +       entered in the tables.
 680.170 +
 680.171 +       used keeps track of how many table entries have been allocated from the
 680.172 +       provided *table space.  It is checked when a LENS table is being made
 680.173 +       against the space in *table, ENOUGH, minus the maximum space needed by
 680.174 +       the worst case distance code, MAXD.  This should never happen, but the
 680.175 +       sufficiency of ENOUGH has not been proven exhaustively, hence the check.
 680.176 +       This assumes that when type == LENS, bits == 9.
 680.177 +
 680.178 +       sym increments through all symbols, and the loop terminates when
 680.179 +       all codes of length max, i.e. all codes, have been processed.  This
 680.180 +       routine permits incomplete codes, so another loop after this one fills
 680.181 +       in the rest of the decoding tables with invalid code markers.
 680.182 +     */
 680.183 +
 680.184 +    /* set up for code type */
 680.185 +    switch (type) {
 680.186 +    case CODES:
 680.187 +        base = extra = work;    /* dummy value--not used */
 680.188 +        end = 19;
 680.189 +        break;
 680.190 +    case LENS:
 680.191 +        base = lbase;
 680.192 +        base -= 257;
 680.193 +        extra = lext;
 680.194 +        extra -= 257;
 680.195 +        end = 256;
 680.196 +        break;
 680.197 +    default:            /* DISTS */
 680.198 +        base = dbase;
 680.199 +        extra = dext;
 680.200 +        end = -1;
 680.201 +    }
 680.202 +
 680.203 +    /* initialize state for loop */
 680.204 +    huff = 0;                   /* starting code */
 680.205 +    sym = 0;                    /* starting code symbol */
 680.206 +    len = min;                  /* starting code length */
 680.207 +    next = *table;              /* current table to fill in */
 680.208 +    curr = root;                /* current table index bits */
 680.209 +    drop = 0;                   /* current bits to drop from code for index */
 680.210 +    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
 680.211 +    used = 1U << root;          /* use root table entries */
 680.212 +    mask = used - 1;            /* mask for comparing low */
 680.213 +
 680.214 +    /* check available table space */
 680.215 +    if (type == LENS && used >= ENOUGH - MAXD)
 680.216 +        return 1;
 680.217 +
 680.218 +    /* process all codes and make table entries */
 680.219 +    for (;;) {
 680.220 +        /* create table entry */
 680.221 +        this.bits = (unsigned char)(len - drop);
 680.222 +        if ((int)(work[sym]) < end) {
 680.223 +            this.op = (unsigned char)0;
 680.224 +            this.val = work[sym];
 680.225 +        }
 680.226 +        else if ((int)(work[sym]) > end) {
 680.227 +            this.op = (unsigned char)(extra[work[sym]]);
 680.228 +            this.val = base[work[sym]];
 680.229 +        }
 680.230 +        else {
 680.231 +            this.op = (unsigned char)(32 + 64);         /* end of block */
 680.232 +            this.val = 0;
 680.233 +        }
 680.234 +
 680.235 +        /* replicate for those indices with low len bits equal to huff */
 680.236 +        incr = 1U << (len - drop);
 680.237 +        fill = 1U << curr;
 680.238 +        min = fill;                 /* save offset to next table */
 680.239 +        do {
 680.240 +            fill -= incr;
 680.241 +            next[(huff >> drop) + fill] = this;
 680.242 +        } while (fill != 0);
 680.243 +
 680.244 +        /* backwards increment the len-bit code huff */
 680.245 +        incr = 1U << (len - 1);
 680.246 +        while (huff & incr)
 680.247 +            incr >>= 1;
 680.248 +        if (incr != 0) {
 680.249 +            huff &= incr - 1;
 680.250 +            huff += incr;
 680.251 +        }
 680.252 +        else
 680.253 +            huff = 0;
 680.254 +
 680.255 +        /* go to next symbol, update count, len */
 680.256 +        sym++;
 680.257 +        if (--(count[len]) == 0) {
 680.258 +            if (len == max) break;
 680.259 +            len = lens[work[sym]];
 680.260 +        }
 680.261 +
 680.262 +        /* create new sub-table if needed */
 680.263 +        if (len > root && (huff & mask) != low) {
 680.264 +            /* if first time, transition to sub-tables */
 680.265 +            if (drop == 0)
 680.266 +                drop = root;
 680.267 +
 680.268 +            /* increment past last table */
 680.269 +            next += min;            /* here min is 1 << curr */
 680.270 +
 680.271 +            /* determine length of next table */
 680.272 +            curr = len - drop;
 680.273 +            left = (int)(1 << curr);
 680.274 +            while (curr + drop < max) {
 680.275 +                left -= count[curr + drop];
 680.276 +                if (left <= 0) break;
 680.277 +                curr++;
 680.278 +                left <<= 1;
 680.279 +            }
 680.280 +
 680.281 +            /* check for enough space */
 680.282 +            used += 1U << curr;
 680.283 +            if (type == LENS && used >= ENOUGH - MAXD)
 680.284 +                return 1;
 680.285 +
 680.286 +            /* point entry in root table to sub-table */
 680.287 +            low = huff & mask;
 680.288 +            (*table)[low].op = (unsigned char)curr;
 680.289 +            (*table)[low].bits = (unsigned char)root;
 680.290 +            (*table)[low].val = (unsigned short)(next - *table);
 680.291 +        }
 680.292 +    }
 680.293 +
 680.294 +    /*
 680.295 +       Fill in rest of table for incomplete codes.  This loop is similar to the
 680.296 +       loop above in incrementing huff for table indices.  It is assumed that
 680.297 +       len is equal to curr + drop, so there is no loop needed to increment
 680.298 +       through high index bits.  When the current sub-table is filled, the loop
 680.299 +       drops back to the root table to fill in any remaining entries there.
 680.300 +     */
 680.301 +    this.op = (unsigned char)64;                /* invalid code marker */
 680.302 +    this.bits = (unsigned char)(len - drop);
 680.303 +    this.val = (unsigned short)0;
 680.304 +    while (huff != 0) {
 680.305 +        /* when done with sub-table, drop back to root table */
 680.306 +        if (drop != 0 && (huff & mask) != low) {
 680.307 +            drop = 0;
 680.308 +            len = root;
 680.309 +            next = *table;
 680.310 +            this.bits = (unsigned char)len;
 680.311 +        }
 680.312 +
 680.313 +        /* put invalid code marker in table */
 680.314 +        next[huff >> drop] = this;
 680.315 +
 680.316 +        /* backwards increment the len-bit code huff */
 680.317 +        incr = 1U << (len - 1);
 680.318 +        while (huff & incr)
 680.319 +            incr >>= 1;
 680.320 +        if (incr != 0) {
 680.321 +            huff &= incr - 1;
 680.322 +            huff += incr;
 680.323 +        }
 680.324 +        else
 680.325 +            huff = 0;
 680.326 +    }
 680.327 +
 680.328 +    /* set return parameters */
 680.329 +    *table += used;
 680.330 +    *bits = root;
 680.331 +    return 0;
 680.332 +}
   681.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   681.2 +++ b/libs/zlib/inftrees.h	Sat Feb 01 19:58:19 2014 +0200
   681.3 @@ -0,0 +1,55 @@
   681.4 +/* inftrees.h -- header to use inftrees.c
   681.5 + * Copyright (C) 1995-2005 Mark Adler
   681.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   681.7 + */
   681.8 +
   681.9 +/* WARNING: this file should *not* be used by applications. It is
  681.10 +   part of the implementation of the compression library and is
  681.11 +   subject to change. Applications should only use zlib.h.
  681.12 + */
  681.13 +
  681.14 +/* Structure for decoding tables.  Each entry provides either the
  681.15 +   information needed to do the operation requested by the code that
  681.16 +   indexed that table entry, or it provides a pointer to another
  681.17 +   table that indexes more bits of the code.  op indicates whether
  681.18 +   the entry is a pointer to another table, a literal, a length or
  681.19 +   distance, an end-of-block, or an invalid code.  For a table
  681.20 +   pointer, the low four bits of op is the number of index bits of
  681.21 +   that table.  For a length or distance, the low four bits of op
  681.22 +   is the number of extra bits to get after the code.  bits is
  681.23 +   the number of bits in this code or part of the code to drop off
  681.24 +   of the bit buffer.  val is the actual byte to output in the case
  681.25 +   of a literal, the base length or distance, or the offset from
  681.26 +   the current table to the next table.  Each entry is four bytes. */
  681.27 +typedef struct {
  681.28 +    unsigned char op;           /* operation, extra bits, table bits */
  681.29 +    unsigned char bits;         /* bits in this part of the code */
  681.30 +    unsigned short val;         /* offset in table or code value */
  681.31 +} code;
  681.32 +
  681.33 +/* op values as set by inflate_table():
  681.34 +    00000000 - literal
  681.35 +    0000tttt - table link, tttt != 0 is the number of table index bits
  681.36 +    0001eeee - length or distance, eeee is the number of extra bits
  681.37 +    01100000 - end of block
  681.38 +    01000000 - invalid code
  681.39 + */
  681.40 +
  681.41 +/* Maximum size of dynamic tree.  The maximum found in a long but non-
  681.42 +   exhaustive search was 1444 code structures (852 for length/literals
  681.43 +   and 592 for distances, the latter actually the result of an
  681.44 +   exhaustive search).  The true maximum is not known, but the value
  681.45 +   below is more than safe. */
  681.46 +#define ENOUGH 2048
  681.47 +#define MAXD 592
  681.48 +
  681.49 +/* Type of code to build for inftable() */
  681.50 +typedef enum {
  681.51 +    CODES,
  681.52 +    LENS,
  681.53 +    DISTS
  681.54 +} codetype;
  681.55 +
  681.56 +extern int inflate_table OF((codetype type, unsigned short FAR *lens,
  681.57 +                             unsigned codes, code FAR * FAR *table,
  681.58 +                             unsigned FAR *bits, unsigned short FAR *work));
   682.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   682.2 +++ b/libs/zlib/trees.c	Sat Feb 01 19:58:19 2014 +0200
   682.3 @@ -0,0 +1,1219 @@
   682.4 +/* trees.c -- output deflated data using Huffman coding
   682.5 + * Copyright (C) 1995-2005 Jean-loup Gailly
   682.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   682.7 + */
   682.8 +
   682.9 +/*
  682.10 + *  ALGORITHM
  682.11 + *
  682.12 + *      The "deflation" process uses several Huffman trees. The more
  682.13 + *      common source values are represented by shorter bit sequences.
  682.14 + *
  682.15 + *      Each code tree is stored in a compressed form which is itself
  682.16 + * a Huffman encoding of the lengths of all the code strings (in
  682.17 + * ascending order by source values).  The actual code strings are
  682.18 + * reconstructed from the lengths in the inflate process, as described
  682.19 + * in the deflate specification.
  682.20 + *
  682.21 + *  REFERENCES
  682.22 + *
  682.23 + *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
  682.24 + *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
  682.25 + *
  682.26 + *      Storer, James A.
  682.27 + *          Data Compression:  Methods and Theory, pp. 49-50.
  682.28 + *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
  682.29 + *
  682.30 + *      Sedgewick, R.
  682.31 + *          Algorithms, p290.
  682.32 + *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
  682.33 + */
  682.34 +
  682.35 +/* @(#) $Id$ */
  682.36 +
  682.37 +/* #define GEN_TREES_H */
  682.38 +
  682.39 +#include "deflate.h"
  682.40 +
  682.41 +#ifdef DEBUG
  682.42 +#  include <ctype.h>
  682.43 +#endif
  682.44 +
  682.45 +/* ===========================================================================
  682.46 + * Constants
  682.47 + */
  682.48 +
  682.49 +#define MAX_BL_BITS 7
  682.50 +/* Bit length codes must not exceed MAX_BL_BITS bits */
  682.51 +
  682.52 +#define END_BLOCK 256
  682.53 +/* end of block literal code */
  682.54 +
  682.55 +#define REP_3_6      16
  682.56 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */
  682.57 +
  682.58 +#define REPZ_3_10    17
  682.59 +/* repeat a zero length 3-10 times  (3 bits of repeat count) */
  682.60 +
  682.61 +#define REPZ_11_138  18
  682.62 +/* repeat a zero length 11-138 times  (7 bits of repeat count) */
  682.63 +
  682.64 +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
  682.65 +   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
  682.66 +
  682.67 +local const int extra_dbits[D_CODES] /* extra bits for each distance code */
  682.68 +   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
  682.69 +
  682.70 +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
  682.71 +   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
  682.72 +
  682.73 +local const uch bl_order[BL_CODES]
  682.74 +   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
  682.75 +/* The lengths of the bit length codes are sent in order of decreasing
  682.76 + * probability, to avoid transmitting the lengths for unused bit length codes.
  682.77 + */
  682.78 +
  682.79 +#define Buf_size (8 * 2*sizeof(char))
  682.80 +/* Number of bits used within bi_buf. (bi_buf might be implemented on
  682.81 + * more than 16 bits on some systems.)
  682.82 + */
  682.83 +
  682.84 +/* ===========================================================================
  682.85 + * Local data. These are initialized only once.
  682.86 + */
  682.87 +
  682.88 +#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
  682.89 +
  682.90 +#if defined(GEN_TREES_H) || !defined(STDC)
  682.91 +/* non ANSI compilers may not accept trees.h */
  682.92 +
  682.93 +local ct_data static_ltree[L_CODES+2];
  682.94 +/* The static literal tree. Since the bit lengths are imposed, there is no
  682.95 + * need for the L_CODES extra codes used during heap construction. However
  682.96 + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
  682.97 + * below).
  682.98 + */
  682.99 +
 682.100 +local ct_data static_dtree[D_CODES];
 682.101 +/* The static distance tree. (Actually a trivial tree since all codes use
 682.102 + * 5 bits.)
 682.103 + */
 682.104 +
 682.105 +uch _dist_code[DIST_CODE_LEN];
 682.106 +/* Distance codes. The first 256 values correspond to the distances
 682.107 + * 3 .. 258, the last 256 values correspond to the top 8 bits of
 682.108 + * the 15 bit distances.
 682.109 + */
 682.110 +
 682.111 +uch _length_code[MAX_MATCH-MIN_MATCH+1];
 682.112 +/* length code for each normalized match length (0 == MIN_MATCH) */
 682.113 +
 682.114 +local int base_length[LENGTH_CODES];
 682.115 +/* First normalized length for each code (0 = MIN_MATCH) */
 682.116 +
 682.117 +local int base_dist[D_CODES];
 682.118 +/* First normalized distance for each code (0 = distance of 1) */
 682.119 +
 682.120 +#else
 682.121 +#  include "trees.h"
 682.122 +#endif /* GEN_TREES_H */
 682.123 +
 682.124 +struct static_tree_desc_s {
 682.125 +    const ct_data *static_tree;  /* static tree or NULL */
 682.126 +    const intf *extra_bits;      /* extra bits for each code or NULL */
 682.127 +    int     extra_base;          /* base index for extra_bits */
 682.128 +    int     elems;               /* max number of elements in the tree */
 682.129 +    int     max_length;          /* max bit length for the codes */
 682.130 +};
 682.131 +
 682.132 +local static_tree_desc  static_l_desc =
 682.133 +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
 682.134 +
 682.135 +local static_tree_desc  static_d_desc =
 682.136 +{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
 682.137 +
 682.138 +local static_tree_desc  static_bl_desc =
 682.139 +{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
 682.140 +
 682.141 +/* ===========================================================================
 682.142 + * Local (static) routines in this file.
 682.143 + */
 682.144 +
 682.145 +local void tr_static_init OF((void));
 682.146 +local void init_block     OF((deflate_state *s));
 682.147 +local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
 682.148 +local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
 682.149 +local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
 682.150 +local void build_tree     OF((deflate_state *s, tree_desc *desc));
 682.151 +local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
 682.152 +local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
 682.153 +local int  build_bl_tree  OF((deflate_state *s));
 682.154 +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
 682.155 +                              int blcodes));
 682.156 +local void compress_block OF((deflate_state *s, ct_data *ltree,
 682.157 +                              ct_data *dtree));
 682.158 +local void set_data_type  OF((deflate_state *s));
 682.159 +local unsigned bi_reverse OF((unsigned value, int length));
 682.160 +local void bi_windup      OF((deflate_state *s));
 682.161 +local void bi_flush       OF((deflate_state *s));
 682.162 +local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
 682.163 +                              int header));
 682.164 +
 682.165 +#ifdef GEN_TREES_H
 682.166 +local void gen_trees_header OF((void));
 682.167 +#endif
 682.168 +
 682.169 +#ifndef DEBUG
 682.170 +#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
 682.171 +   /* Send a code of the given tree. c and tree must not have side effects */
 682.172 +
 682.173 +#else /* DEBUG */
 682.174 +#  define send_code(s, c, tree) \
 682.175 +     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
 682.176 +       send_bits(s, tree[c].Code, tree[c].Len); }
 682.177 +#endif
 682.178 +
 682.179 +/* ===========================================================================
 682.180 + * Output a short LSB first on the stream.
 682.181 + * IN assertion: there is enough room in pendingBuf.
 682.182 + */
 682.183 +#define put_short(s, w) { \
 682.184 +    put_byte(s, (uch)((w) & 0xff)); \
 682.185 +    put_byte(s, (uch)((ush)(w) >> 8)); \
 682.186 +}
 682.187 +
 682.188 +/* ===========================================================================
 682.189 + * Send a value on a given number of bits.
 682.190 + * IN assertion: length <= 16 and value fits in length bits.
 682.191 + */
 682.192 +#ifdef DEBUG
 682.193 +local void send_bits      OF((deflate_state *s, int value, int length));
 682.194 +
 682.195 +local void send_bits(s, value, length)
 682.196 +    deflate_state *s;
 682.197 +    int value;  /* value to send */
 682.198 +    int length; /* number of bits */
 682.199 +{
 682.200 +    Tracevv((stderr," l %2d v %4x ", length, value));
 682.201 +    Assert(length > 0 && length <= 15, "invalid length");
 682.202 +    s->bits_sent += (ulg)length;
 682.203 +
 682.204 +    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
 682.205 +     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
 682.206 +     * unused bits in value.
 682.207 +     */
 682.208 +    if (s->bi_valid > (int)Buf_size - length) {
 682.209 +        s->bi_buf |= (value << s->bi_valid);
 682.210 +        put_short(s, s->bi_buf);
 682.211 +        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
 682.212 +        s->bi_valid += length - Buf_size;
 682.213 +    } else {
 682.214 +        s->bi_buf |= value << s->bi_valid;
 682.215 +        s->bi_valid += length;
 682.216 +    }
 682.217 +}
 682.218 +#else /* !DEBUG */
 682.219 +
 682.220 +#define send_bits(s, value, length) \
 682.221 +{ int len = length;\
 682.222 +  if (s->bi_valid > (int)Buf_size - len) {\
 682.223 +    int val = value;\
 682.224 +    s->bi_buf |= (val << s->bi_valid);\
 682.225 +    put_short(s, s->bi_buf);\
 682.226 +    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
 682.227 +    s->bi_valid += len - Buf_size;\
 682.228 +  } else {\
 682.229 +    s->bi_buf |= (value) << s->bi_valid;\
 682.230 +    s->bi_valid += len;\
 682.231 +  }\
 682.232 +}
 682.233 +#endif /* DEBUG */
 682.234 +
 682.235 +
 682.236 +/* the arguments must not have side effects */
 682.237 +
 682.238 +/* ===========================================================================
 682.239 + * Initialize the various 'constant' tables.
 682.240 + */
 682.241 +local void tr_static_init()
 682.242 +{
 682.243 +#if defined(GEN_TREES_H) || !defined(STDC)
 682.244 +    static int static_init_done = 0;
 682.245 +    int n;        /* iterates over tree elements */
 682.246 +    int bits;     /* bit counter */
 682.247 +    int length;   /* length value */
 682.248 +    int code;     /* code value */
 682.249 +    int dist;     /* distance index */
 682.250 +    ush bl_count[MAX_BITS+1];
 682.251 +    /* number of codes at each bit length for an optimal tree */
 682.252 +
 682.253 +    if (static_init_done) return;
 682.254 +
 682.255 +    /* For some embedded targets, global variables are not initialized: */
 682.256 +    static_l_desc.static_tree = static_ltree;
 682.257 +    static_l_desc.extra_bits = extra_lbits;
 682.258 +    static_d_desc.static_tree = static_dtree;
 682.259 +    static_d_desc.extra_bits = extra_dbits;
 682.260 +    static_bl_desc.extra_bits = extra_blbits;
 682.261 +
 682.262 +    /* Initialize the mapping length (0..255) -> length code (0..28) */
 682.263 +    length = 0;
 682.264 +    for (code = 0; code < LENGTH_CODES-1; code++) {
 682.265 +        base_length[code] = length;
 682.266 +        for (n = 0; n < (1<<extra_lbits[code]); n++) {
 682.267 +            _length_code[length++] = (uch)code;
 682.268 +        }
 682.269 +    }
 682.270 +    Assert (length == 256, "tr_static_init: length != 256");
 682.271 +    /* Note that the length 255 (match length 258) can be represented
 682.272 +     * in two different ways: code 284 + 5 bits or code 285, so we
 682.273 +     * overwrite length_code[255] to use the best encoding:
 682.274 +     */
 682.275 +    _length_code[length-1] = (uch)code;
 682.276 +
 682.277 +    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
 682.278 +    dist = 0;
 682.279 +    for (code = 0 ; code < 16; code++) {
 682.280 +        base_dist[code] = dist;
 682.281 +        for (n = 0; n < (1<<extra_dbits[code]); n++) {
 682.282 +            _dist_code[dist++] = (uch)code;
 682.283 +        }
 682.284 +    }
 682.285 +    Assert (dist == 256, "tr_static_init: dist != 256");
 682.286 +    dist >>= 7; /* from now on, all distances are divided by 128 */
 682.287 +    for ( ; code < D_CODES; code++) {
 682.288 +        base_dist[code] = dist << 7;
 682.289 +        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
 682.290 +            _dist_code[256 + dist++] = (uch)code;
 682.291 +        }
 682.292 +    }
 682.293 +    Assert (dist == 256, "tr_static_init: 256+dist != 512");
 682.294 +
 682.295 +    /* Construct the codes of the static literal tree */
 682.296 +    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
 682.297 +    n = 0;
 682.298 +    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
 682.299 +    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
 682.300 +    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
 682.301 +    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
 682.302 +    /* Codes 286 and 287 do not exist, but we must include them in the
 682.303 +     * tree construction to get a canonical Huffman tree (longest code
 682.304 +     * all ones)
 682.305 +     */
 682.306 +    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
 682.307 +
 682.308 +    /* The static distance tree is trivial: */
 682.309 +    for (n = 0; n < D_CODES; n++) {
 682.310 +        static_dtree[n].Len = 5;
 682.311 +        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
 682.312 +    }
 682.313 +    static_init_done = 1;
 682.314 +
 682.315 +#  ifdef GEN_TREES_H
 682.316 +    gen_trees_header();
 682.317 +#  endif
 682.318 +#endif /* defined(GEN_TREES_H) || !defined(STDC) */
 682.319 +}
 682.320 +
 682.321 +/* ===========================================================================
 682.322 + * Genererate the file trees.h describing the static trees.
 682.323 + */
 682.324 +#ifdef GEN_TREES_H
 682.325 +#  ifndef DEBUG
 682.326 +#    include <stdio.h>
 682.327 +#  endif
 682.328 +
 682.329 +#  define SEPARATOR(i, last, width) \
 682.330 +      ((i) == (last)? "\n};\n\n" :    \
 682.331 +       ((i) % (width) == (width)-1 ? ",\n" : ", "))
 682.332 +
 682.333 +void gen_trees_header()
 682.334 +{
 682.335 +    FILE *header = fopen("trees.h", "w");
 682.336 +    int i;
 682.337 +
 682.338 +    Assert (header != NULL, "Can't open trees.h");
 682.339 +    fprintf(header,
 682.340 +            "/* header created automatically with -DGEN_TREES_H */\n\n");
 682.341 +
 682.342 +    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
 682.343 +    for (i = 0; i < L_CODES+2; i++) {
 682.344 +        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
 682.345 +                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
 682.346 +    }
 682.347 +
 682.348 +    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
 682.349 +    for (i = 0; i < D_CODES; i++) {
 682.350 +        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
 682.351 +                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
 682.352 +    }
 682.353 +
 682.354 +    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
 682.355 +    for (i = 0; i < DIST_CODE_LEN; i++) {
 682.356 +        fprintf(header, "%2u%s", _dist_code[i],
 682.357 +                SEPARATOR(i, DIST_CODE_LEN-1, 20));
 682.358 +    }
 682.359 +
 682.360 +    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
 682.361 +    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
 682.362 +        fprintf(header, "%2u%s", _length_code[i],
 682.363 +                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
 682.364 +    }
 682.365 +
 682.366 +    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
 682.367 +    for (i = 0; i < LENGTH_CODES; i++) {
 682.368 +        fprintf(header, "%1u%s", base_length[i],
 682.369 +                SEPARATOR(i, LENGTH_CODES-1, 20));
 682.370 +    }
 682.371 +
 682.372 +    fprintf(header, "local const int base_dist[D_CODES] = {\n");
 682.373 +    for (i = 0; i < D_CODES; i++) {
 682.374 +        fprintf(header, "%5u%s", base_dist[i],
 682.375 +                SEPARATOR(i, D_CODES-1, 10));
 682.376 +    }
 682.377 +
 682.378 +    fclose(header);
 682.379 +}
 682.380 +#endif /* GEN_TREES_H */
 682.381 +
 682.382 +/* ===========================================================================
 682.383 + * Initialize the tree data structures for a new zlib stream.
 682.384 + */
 682.385 +void _tr_init(s)
 682.386 +    deflate_state *s;
 682.387 +{
 682.388 +    tr_static_init();
 682.389 +
 682.390 +    s->l_desc.dyn_tree = s->dyn_ltree;
 682.391 +    s->l_desc.stat_desc = &static_l_desc;
 682.392 +
 682.393 +    s->d_desc.dyn_tree = s->dyn_dtree;
 682.394 +    s->d_desc.stat_desc = &static_d_desc;
 682.395 +
 682.396 +    s->bl_desc.dyn_tree = s->bl_tree;
 682.397 +    s->bl_desc.stat_desc = &static_bl_desc;
 682.398 +
 682.399 +    s->bi_buf = 0;
 682.400 +    s->bi_valid = 0;
 682.401 +    s->last_eob_len = 8; /* enough lookahead for inflate */
 682.402 +#ifdef DEBUG
 682.403 +    s->compressed_len = 0L;
 682.404 +    s->bits_sent = 0L;
 682.405 +#endif
 682.406 +
 682.407 +    /* Initialize the first block of the first file: */
 682.408 +    init_block(s);
 682.409 +}
 682.410 +
 682.411 +/* ===========================================================================
 682.412 + * Initialize a new block.
 682.413 + */
 682.414 +local void init_block(s)
 682.415 +    deflate_state *s;
 682.416 +{
 682.417 +    int n; /* iterates over tree elements */
 682.418 +
 682.419 +    /* Initialize the trees. */
 682.420 +    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
 682.421 +    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
 682.422 +    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
 682.423 +
 682.424 +    s->dyn_ltree[END_BLOCK].Freq = 1;
 682.425 +    s->opt_len = s->static_len = 0L;
 682.426 +    s->last_lit = s->matches = 0;
 682.427 +}
 682.428 +
 682.429 +#define SMALLEST 1
 682.430 +/* Index within the heap array of least frequent node in the Huffman tree */
 682.431 +
 682.432 +
 682.433 +/* ===========================================================================
 682.434 + * Remove the smallest element from the heap and recreate the heap with
 682.435 + * one less element. Updates heap and heap_len.
 682.436 + */
 682.437 +#define pqremove(s, tree, top) \
 682.438 +{\
 682.439 +    top = s->heap[SMALLEST]; \
 682.440 +    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
 682.441 +    pqdownheap(s, tree, SMALLEST); \
 682.442 +}
 682.443 +
 682.444 +/* ===========================================================================
 682.445 + * Compares to subtrees, using the tree depth as tie breaker when
 682.446 + * the subtrees have equal frequency. This minimizes the worst case length.
 682.447 + */
 682.448 +#define smaller(tree, n, m, depth) \
 682.449 +   (tree[n].Freq < tree[m].Freq || \
 682.450 +   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
 682.451 +
 682.452 +/* ===========================================================================
 682.453 + * Restore the heap property by moving down the tree starting at node k,
 682.454 + * exchanging a node with the smallest of its two sons if necessary, stopping
 682.455 + * when the heap property is re-established (each father smaller than its
 682.456 + * two sons).
 682.457 + */
 682.458 +local void pqdownheap(s, tree, k)
 682.459 +    deflate_state *s;
 682.460 +    ct_data *tree;  /* the tree to restore */
 682.461 +    int k;               /* node to move down */
 682.462 +{
 682.463 +    int v = s->heap[k];
 682.464 +    int j = k << 1;  /* left son of k */
 682.465 +    while (j <= s->heap_len) {
 682.466 +        /* Set j to the smallest of the two sons: */
 682.467 +        if (j < s->heap_len &&
 682.468 +            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
 682.469 +            j++;
 682.470 +        }
 682.471 +        /* Exit if v is smaller than both sons */
 682.472 +        if (smaller(tree, v, s->heap[j], s->depth)) break;
 682.473 +
 682.474 +        /* Exchange v with the smallest son */
 682.475 +        s->heap[k] = s->heap[j];  k = j;
 682.476 +
 682.477 +        /* And continue down the tree, setting j to the left son of k */
 682.478 +        j <<= 1;
 682.479 +    }
 682.480 +    s->heap[k] = v;
 682.481 +}
 682.482 +
 682.483 +/* ===========================================================================
 682.484 + * Compute the optimal bit lengths for a tree and update the total bit length
 682.485 + * for the current block.
 682.486 + * IN assertion: the fields freq and dad are set, heap[heap_max] and
 682.487 + *    above are the tree nodes sorted by increasing frequency.
 682.488 + * OUT assertions: the field len is set to the optimal bit length, the
 682.489 + *     array bl_count contains the frequencies for each bit length.
 682.490 + *     The length opt_len is updated; static_len is also updated if stree is
 682.491 + *     not null.
 682.492 + */
 682.493 +local void gen_bitlen(s, desc)
 682.494 +    deflate_state *s;
 682.495 +    tree_desc *desc;    /* the tree descriptor */
 682.496 +{
 682.497 +    ct_data *tree        = desc->dyn_tree;
 682.498 +    int max_code         = desc->max_code;
 682.499 +    const ct_data *stree = desc->stat_desc->static_tree;
 682.500 +    const intf *extra    = desc->stat_desc->extra_bits;
 682.501 +    int base             = desc->stat_desc->extra_base;
 682.502 +    int max_length       = desc->stat_desc->max_length;
 682.503 +    int h;              /* heap index */
 682.504 +    int n, m;           /* iterate over the tree elements */
 682.505 +    int bits;           /* bit length */
 682.506 +    int xbits;          /* extra bits */
 682.507 +    ush f;              /* frequency */
 682.508 +    int overflow = 0;   /* number of elements with bit length too large */
 682.509 +
 682.510 +    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
 682.511 +
 682.512 +    /* In a first pass, compute the optimal bit lengths (which may
 682.513 +     * overflow in the case of the bit length tree).
 682.514 +     */
 682.515 +    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
 682.516 +
 682.517 +    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
 682.518 +        n = s->heap[h];
 682.519 +        bits = tree[tree[n].Dad].Len + 1;
 682.520 +        if (bits > max_length) bits = max_length, overflow++;
 682.521 +        tree[n].Len = (ush)bits;
 682.522 +        /* We overwrite tree[n].Dad which is no longer needed */
 682.523 +
 682.524 +        if (n > max_code) continue; /* not a leaf node */
 682.525 +
 682.526 +        s->bl_count[bits]++;
 682.527 +        xbits = 0;
 682.528 +        if (n >= base) xbits = extra[n-base];
 682.529 +        f = tree[n].Freq;
 682.530 +        s->opt_len += (ulg)f * (bits + xbits);
 682.531 +        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
 682.532 +    }
 682.533 +    if (overflow == 0) return;
 682.534 +
 682.535 +    Trace((stderr,"\nbit length overflow\n"));
 682.536 +    /* This happens for example on obj2 and pic of the Calgary corpus */
 682.537 +
 682.538 +    /* Find the first bit length which could increase: */
 682.539 +    do {
 682.540 +        bits = max_length-1;
 682.541 +        while (s->bl_count[bits] == 0) bits--;
 682.542 +        s->bl_count[bits]--;      /* move one leaf down the tree */
 682.543 +        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
 682.544 +        s->bl_count[max_length]--;
 682.545 +        /* The brother of the overflow item also moves one step up,
 682.546 +         * but this does not affect bl_count[max_length]
 682.547 +         */
 682.548 +        overflow -= 2;
 682.549 +    } while (overflow > 0);
 682.550 +
 682.551 +    /* Now recompute all bit lengths, scanning in increasing frequency.
 682.552 +     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
 682.553 +     * lengths instead of fixing only the wrong ones. This idea is taken
 682.554 +     * from 'ar' written by Haruhiko Okumura.)
 682.555 +     */
 682.556 +    for (bits = max_length; bits != 0; bits--) {
 682.557 +        n = s->bl_count[bits];
 682.558 +        while (n != 0) {
 682.559 +            m = s->heap[--h];
 682.560 +            if (m > max_code) continue;
 682.561 +            if ((unsigned) tree[m].Len != (unsigned) bits) {
 682.562 +                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
 682.563 +                s->opt_len += ((long)bits - (long)tree[m].Len)
 682.564 +                              *(long)tree[m].Freq;
 682.565 +                tree[m].Len = (ush)bits;
 682.566 +            }
 682.567 +            n--;
 682.568 +        }
 682.569 +    }
 682.570 +}
 682.571 +
 682.572 +/* ===========================================================================
 682.573 + * Generate the codes for a given tree and bit counts (which need not be
 682.574 + * optimal).
 682.575 + * IN assertion: the array bl_count contains the bit length statistics for
 682.576 + * the given tree and the field len is set for all tree elements.
 682.577 + * OUT assertion: the field code is set for all tree elements of non
 682.578 + *     zero code length.
 682.579 + */
 682.580 +local void gen_codes (tree, max_code, bl_count)
 682.581 +    ct_data *tree;             /* the tree to decorate */
 682.582 +    int max_code;              /* largest code with non zero frequency */
 682.583 +    ushf *bl_count;            /* number of codes at each bit length */
 682.584 +{
 682.585 +    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
 682.586 +    ush code = 0;              /* running code value */
 682.587 +    int bits;                  /* bit index */
 682.588 +    int n;                     /* code index */
 682.589 +
 682.590 +    /* The distribution counts are first used to generate the code values
 682.591 +     * without bit reversal.
 682.592 +     */
 682.593 +    for (bits = 1; bits <= MAX_BITS; bits++) {
 682.594 +        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
 682.595 +    }
 682.596 +    /* Check that the bit counts in bl_count are consistent. The last code
 682.597 +     * must be all ones.
 682.598 +     */
 682.599 +    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
 682.600 +            "inconsistent bit counts");
 682.601 +    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
 682.602 +
 682.603 +    for (n = 0;  n <= max_code; n++) {
 682.604 +        int len = tree[n].Len;
 682.605 +        if (len == 0) continue;
 682.606 +        /* Now reverse the bits */
 682.607 +        tree[n].Code = bi_reverse(next_code[len]++, len);
 682.608 +
 682.609 +        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
 682.610 +             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
 682.611 +    }
 682.612 +}
 682.613 +
 682.614 +/* ===========================================================================
 682.615 + * Construct one Huffman tree and assigns the code bit strings and lengths.
 682.616 + * Update the total bit length for the current block.
 682.617 + * IN assertion: the field freq is set for all tree elements.
 682.618 + * OUT assertions: the fields len and code are set to the optimal bit length
 682.619 + *     and corresponding code. The length opt_len is updated; static_len is
 682.620 + *     also updated if stree is not null. The field max_code is set.
 682.621 + */
 682.622 +local void build_tree(s, desc)
 682.623 +    deflate_state *s;
 682.624 +    tree_desc *desc; /* the tree descriptor */
 682.625 +{
 682.626 +    ct_data *tree         = desc->dyn_tree;
 682.627 +    const ct_data *stree  = desc->stat_desc->static_tree;
 682.628 +    int elems             = desc->stat_desc->elems;
 682.629 +    int n, m;          /* iterate over heap elements */
 682.630 +    int max_code = -1; /* largest code with non zero frequency */
 682.631 +    int node;          /* new node being created */
 682.632 +
 682.633 +    /* Construct the initial heap, with least frequent element in
 682.634 +     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
 682.635 +     * heap[0] is not used.
 682.636 +     */
 682.637 +    s->heap_len = 0, s->heap_max = HEAP_SIZE;
 682.638 +
 682.639 +    for (n = 0; n < elems; n++) {
 682.640 +        if (tree[n].Freq != 0) {
 682.641 +            s->heap[++(s->heap_len)] = max_code = n;
 682.642 +            s->depth[n] = 0;
 682.643 +        } else {
 682.644 +            tree[n].Len = 0;
 682.645 +        }
 682.646 +    }
 682.647 +
 682.648 +    /* The pkzip format requires that at least one distance code exists,
 682.649 +     * and that at least one bit should be sent even if there is only one
 682.650 +     * possible code. So to avoid special checks later on we force at least
 682.651 +     * two codes of non zero frequency.
 682.652 +     */
 682.653 +    while (s->heap_len < 2) {
 682.654 +        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
 682.655 +        tree[node].Freq = 1;
 682.656 +        s->depth[node] = 0;
 682.657 +        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
 682.658 +        /* node is 0 or 1 so it does not have extra bits */
 682.659 +    }
 682.660 +    desc->max_code = max_code;
 682.661 +
 682.662 +    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
 682.663 +     * establish sub-heaps of increasing lengths:
 682.664 +     */
 682.665 +    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
 682.666 +
 682.667 +    /* Construct the Huffman tree by repeatedly combining the least two
 682.668 +     * frequent nodes.
 682.669 +     */
 682.670 +    node = elems;              /* next internal node of the tree */
 682.671 +    do {
 682.672 +        pqremove(s, tree, n);  /* n = node of least frequency */
 682.673 +        m = s->heap[SMALLEST]; /* m = node of next least frequency */
 682.674 +
 682.675 +        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
 682.676 +        s->heap[--(s->heap_max)] = m;
 682.677 +
 682.678 +        /* Create a new node father of n and m */
 682.679 +        tree[node].Freq = tree[n].Freq + tree[m].Freq;
 682.680 +        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
 682.681 +                                s->depth[n] : s->depth[m]) + 1);
 682.682 +        tree[n].Dad = tree[m].Dad = (ush)node;
 682.683 +#ifdef DUMP_BL_TREE
 682.684 +        if (tree == s->bl_tree) {
 682.685 +            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
 682.686 +                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
 682.687 +        }
 682.688 +#endif
 682.689 +        /* and insert the new node in the heap */
 682.690 +        s->heap[SMALLEST] = node++;
 682.691 +        pqdownheap(s, tree, SMALLEST);
 682.692 +
 682.693 +    } while (s->heap_len >= 2);
 682.694 +
 682.695 +    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
 682.696 +
 682.697 +    /* At this point, the fields freq and dad are set. We can now
 682.698 +     * generate the bit lengths.
 682.699 +     */
 682.700 +    gen_bitlen(s, (tree_desc *)desc);
 682.701 +
 682.702 +    /* The field len is now set, we can generate the bit codes */
 682.703 +    gen_codes ((ct_data *)tree, max_code, s->bl_count);
 682.704 +}
 682.705 +
 682.706 +/* ===========================================================================
 682.707 + * Scan a literal or distance tree to determine the frequencies of the codes
 682.708 + * in the bit length tree.
 682.709 + */
 682.710 +local void scan_tree (s, tree, max_code)
 682.711 +    deflate_state *s;
 682.712 +    ct_data *tree;   /* the tree to be scanned */
 682.713 +    int max_code;    /* and its largest code of non zero frequency */
 682.714 +{
 682.715 +    int n;                     /* iterates over all tree elements */
 682.716 +    int prevlen = -1;          /* last emitted length */
 682.717 +    int curlen;                /* length of current code */
 682.718 +    int nextlen = tree[0].Len; /* length of next code */
 682.719 +    int count = 0;             /* repeat count of the current code */
 682.720 +    int max_count = 7;         /* max repeat count */
 682.721 +    int min_count = 4;         /* min repeat count */
 682.722 +
 682.723 +    if (nextlen == 0) max_count = 138, min_count = 3;
 682.724 +    tree[max_code+1].Len = (ush)0xffff; /* guard */
 682.725 +
 682.726 +    for (n = 0; n <= max_code; n++) {
 682.727 +        curlen = nextlen; nextlen = tree[n+1].Len;
 682.728 +        if (++count < max_count && curlen == nextlen) {
 682.729 +            continue;
 682.730 +        } else if (count < min_count) {
 682.731 +            s->bl_tree[curlen].Freq += count;
 682.732 +        } else if (curlen != 0) {
 682.733 +            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
 682.734 +            s->bl_tree[REP_3_6].Freq++;
 682.735 +        } else if (count <= 10) {
 682.736 +            s->bl_tree[REPZ_3_10].Freq++;
 682.737 +        } else {
 682.738 +            s->bl_tree[REPZ_11_138].Freq++;
 682.739 +        }
 682.740 +        count = 0; prevlen = curlen;
 682.741 +        if (nextlen == 0) {
 682.742 +            max_count = 138, min_count = 3;
 682.743 +        } else if (curlen == nextlen) {
 682.744 +            max_count = 6, min_count = 3;
 682.745 +        } else {
 682.746 +            max_count = 7, min_count = 4;
 682.747 +        }
 682.748 +    }
 682.749 +}
 682.750 +
 682.751 +/* ===========================================================================
 682.752 + * Send a literal or distance tree in compressed form, using the codes in
 682.753 + * bl_tree.
 682.754 + */
 682.755 +local void send_tree (s, tree, max_code)
 682.756 +    deflate_state *s;
 682.757 +    ct_data *tree; /* the tree to be scanned */
 682.758 +    int max_code;       /* and its largest code of non zero frequency */
 682.759 +{
 682.760 +    int n;                     /* iterates over all tree elements */
 682.761 +    int prevlen = -1;          /* last emitted length */
 682.762 +    int curlen;                /* length of current code */
 682.763 +    int nextlen = tree[0].Len; /* length of next code */
 682.764 +    int count = 0;             /* repeat count of the current code */
 682.765 +    int max_count = 7;         /* max repeat count */
 682.766 +    int min_count = 4;         /* min repeat count */
 682.767 +
 682.768 +    /* tree[max_code+1].Len = -1; */  /* guard already set */
 682.769 +    if (nextlen == 0) max_count = 138, min_count = 3;
 682.770 +
 682.771 +    for (n = 0; n <= max_code; n++) {
 682.772 +        curlen = nextlen; nextlen = tree[n+1].Len;
 682.773 +        if (++count < max_count && curlen == nextlen) {
 682.774 +            continue;
 682.775 +        } else if (count < min_count) {
 682.776 +            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
 682.777 +
 682.778 +        } else if (curlen != 0) {
 682.779 +            if (curlen != prevlen) {
 682.780 +                send_code(s, curlen, s->bl_tree); count--;
 682.781 +            }
 682.782 +            Assert(count >= 3 && count <= 6, " 3_6?");
 682.783 +            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
 682.784 +
 682.785 +        } else if (count <= 10) {
 682.786 +            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
 682.787 +
 682.788 +        } else {
 682.789 +            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
 682.790 +        }
 682.791 +        count = 0; prevlen = curlen;
 682.792 +        if (nextlen == 0) {
 682.793 +            max_count = 138, min_count = 3;
 682.794 +        } else if (curlen == nextlen) {
 682.795 +            max_count = 6, min_count = 3;
 682.796 +        } else {
 682.797 +            max_count = 7, min_count = 4;
 682.798 +        }
 682.799 +    }
 682.800 +}
 682.801 +
 682.802 +/* ===========================================================================
 682.803 + * Construct the Huffman tree for the bit lengths and return the index in
 682.804 + * bl_order of the last bit length code to send.
 682.805 + */
 682.806 +local int build_bl_tree(s)
 682.807 +    deflate_state *s;
 682.808 +{
 682.809 +    int max_blindex;  /* index of last bit length code of non zero freq */
 682.810 +
 682.811 +    /* Determine the bit length frequencies for literal and distance trees */
 682.812 +    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
 682.813 +    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
 682.814 +
 682.815 +    /* Build the bit length tree: */
 682.816 +    build_tree(s, (tree_desc *)(&(s->bl_desc)));
 682.817 +    /* opt_len now includes the length of the tree representations, except
 682.818 +     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
 682.819 +     */
 682.820 +
 682.821 +    /* Determine the number of bit length codes to send. The pkzip format
 682.822 +     * requires that at least 4 bit length codes be sent. (appnote.txt says
 682.823 +     * 3 but the actual value used is 4.)
 682.824 +     */
 682.825 +    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
 682.826 +        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
 682.827 +    }
 682.828 +    /* Update opt_len to include the bit length tree and counts */
 682.829 +    s->opt_len += 3*(max_blindex+1) + 5+5+4;
 682.830 +    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
 682.831 +            s->opt_len, s->static_len));
 682.832 +
 682.833 +    return max_blindex;
 682.834 +}
 682.835 +
 682.836 +/* ===========================================================================
 682.837 + * Send the header for a block using dynamic Huffman trees: the counts, the
 682.838 + * lengths of the bit length codes, the literal tree and the distance tree.
 682.839 + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
 682.840 + */
 682.841 +local void send_all_trees(s, lcodes, dcodes, blcodes)
 682.842 +    deflate_state *s;
 682.843 +    int lcodes, dcodes, blcodes; /* number of codes for each tree */
 682.844 +{
 682.845 +    int rank;                    /* index in bl_order */
 682.846 +
 682.847 +    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
 682.848 +    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
 682.849 +            "too many codes");
 682.850 +    Tracev((stderr, "\nbl counts: "));
 682.851 +    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
 682.852 +    send_bits(s, dcodes-1,   5);
 682.853 +    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
 682.854 +    for (rank = 0; rank < blcodes; rank++) {
 682.855 +        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
 682.856 +        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
 682.857 +    }
 682.858 +    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
 682.859 +
 682.860 +    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
 682.861 +    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
 682.862 +
 682.863 +    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
 682.864 +    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
 682.865 +}
 682.866 +
 682.867 +/* ===========================================================================
 682.868 + * Send a stored block
 682.869 + */
 682.870 +void _tr_stored_block(s, buf, stored_len, eof)
 682.871 +    deflate_state *s;
 682.872 +    charf *buf;       /* input block */
 682.873 +    ulg stored_len;   /* length of input block */
 682.874 +    int eof;          /* true if this is the last block for a file */
 682.875 +{
 682.876 +    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
 682.877 +#ifdef DEBUG
 682.878 +    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
 682.879 +    s->compressed_len += (stored_len + 4) << 3;
 682.880 +#endif
 682.881 +    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
 682.882 +}
 682.883 +
 682.884 +/* ===========================================================================
 682.885 + * Send one empty static block to give enough lookahead for inflate.
 682.886 + * This takes 10 bits, of which 7 may remain in the bit buffer.
 682.887 + * The current inflate code requires 9 bits of lookahead. If the
 682.888 + * last two codes for the previous block (real code plus EOB) were coded
 682.889 + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
 682.890 + * the last real code. In this case we send two empty static blocks instead
 682.891 + * of one. (There are no problems if the previous block is stored or fixed.)
 682.892 + * To simplify the code, we assume the worst case of last real code encoded
 682.893 + * on one bit only.
 682.894 + */
 682.895 +void _tr_align(s)
 682.896 +    deflate_state *s;
 682.897 +{
 682.898 +    send_bits(s, STATIC_TREES<<1, 3);
 682.899 +    send_code(s, END_BLOCK, static_ltree);
 682.900 +#ifdef DEBUG
 682.901 +    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
 682.902 +#endif
 682.903 +    bi_flush(s);
 682.904 +    /* Of the 10 bits for the empty block, we have already sent
 682.905 +     * (10 - bi_valid) bits. The lookahead for the last real code (before
 682.906 +     * the EOB of the previous block) was thus at least one plus the length
 682.907 +     * of the EOB plus what we have just sent of the empty static block.
 682.908 +     */
 682.909 +    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
 682.910 +        send_bits(s, STATIC_TREES<<1, 3);
 682.911 +        send_code(s, END_BLOCK, static_ltree);
 682.912 +#ifdef DEBUG
 682.913 +        s->compressed_len += 10L;
 682.914 +#endif
 682.915 +        bi_flush(s);
 682.916 +    }
 682.917 +    s->last_eob_len = 7;
 682.918 +}
 682.919 +
 682.920 +/* ===========================================================================
 682.921 + * Determine the best encoding for the current block: dynamic trees, static
 682.922 + * trees or store, and output the encoded block to the zip file.
 682.923 + */
 682.924 +void _tr_flush_block(s, buf, stored_len, eof)
 682.925 +    deflate_state *s;
 682.926 +    charf *buf;       /* input block, or NULL if too old */
 682.927 +    ulg stored_len;   /* length of input block */
 682.928 +    int eof;          /* true if this is the last block for a file */
 682.929 +{
 682.930 +    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
 682.931 +    int max_blindex = 0;  /* index of last bit length code of non zero freq */
 682.932 +
 682.933 +    /* Build the Huffman trees unless a stored block is forced */
 682.934 +    if (s->level > 0) {
 682.935 +
 682.936 +        /* Check if the file is binary or text */
 682.937 +        if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
 682.938 +            set_data_type(s);
 682.939 +
 682.940 +        /* Construct the literal and distance trees */
 682.941 +        build_tree(s, (tree_desc *)(&(s->l_desc)));
 682.942 +        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
 682.943 +                s->static_len));
 682.944 +
 682.945 +        build_tree(s, (tree_desc *)(&(s->d_desc)));
 682.946 +        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
 682.947 +                s->static_len));
 682.948 +        /* At this point, opt_len and static_len are the total bit lengths of
 682.949 +         * the compressed block data, excluding the tree representations.
 682.950 +         */
 682.951 +
 682.952 +        /* Build the bit length tree for the above two trees, and get the index
 682.953 +         * in bl_order of the last bit length code to send.
 682.954 +         */
 682.955 +        max_blindex = build_bl_tree(s);
 682.956 +
 682.957 +        /* Determine the best encoding. Compute the block lengths in bytes. */
 682.958 +        opt_lenb = (s->opt_len+3+7)>>3;
 682.959 +        static_lenb = (s->static_len+3+7)>>3;
 682.960 +
 682.961 +        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
 682.962 +                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
 682.963 +                s->last_lit));
 682.964 +
 682.965 +        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
 682.966 +
 682.967 +    } else {
 682.968 +        Assert(buf != (char*)0, "lost buf");
 682.969 +        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
 682.970 +    }
 682.971 +
 682.972 +#ifdef FORCE_STORED
 682.973 +    if (buf != (char*)0) { /* force stored block */
 682.974 +#else
 682.975 +    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
 682.976 +                       /* 4: two words for the lengths */
 682.977 +#endif
 682.978 +        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
 682.979 +         * Otherwise we can't have processed more than WSIZE input bytes since
 682.980 +         * the last block flush, because compression would have been
 682.981 +         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
 682.982 +         * transform a block into a stored block.
 682.983 +         */
 682.984 +        _tr_stored_block(s, buf, stored_len, eof);
 682.985 +
 682.986 +#ifdef FORCE_STATIC
 682.987 +    } else if (static_lenb >= 0) { /* force static trees */
 682.988 +#else
 682.989 +    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
 682.990 +#endif
 682.991 +        send_bits(s, (STATIC_TREES<<1)+eof, 3);
 682.992 +        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
 682.993 +#ifdef DEBUG
 682.994 +        s->compressed_len += 3 + s->static_len;
 682.995 +#endif
 682.996 +    } else {
 682.997 +        send_bits(s, (DYN_TREES<<1)+eof, 3);
 682.998 +        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
 682.999 +                       max_blindex+1);
682.1000 +        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
682.1001 +#ifdef DEBUG
682.1002 +        s->compressed_len += 3 + s->opt_len;
682.1003 +#endif
682.1004 +    }
682.1005 +    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
682.1006 +    /* The above check is made mod 2^32, for files larger than 512 MB
682.1007 +     * and uLong implemented on 32 bits.
682.1008 +     */
682.1009 +    init_block(s);
682.1010 +
682.1011 +    if (eof) {
682.1012 +        bi_windup(s);
682.1013 +#ifdef DEBUG
682.1014 +        s->compressed_len += 7;  /* align on byte boundary */
682.1015 +#endif
682.1016 +    }
682.1017 +    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
682.1018 +           s->compressed_len-7*eof));
682.1019 +}
682.1020 +
682.1021 +/* ===========================================================================
682.1022 + * Save the match info and tally the frequency counts. Return true if
682.1023 + * the current block must be flushed.
682.1024 + */
682.1025 +int _tr_tally (s, dist, lc)
682.1026 +    deflate_state *s;
682.1027 +    unsigned dist;  /* distance of matched string */
682.1028 +    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
682.1029 +{
682.1030 +    s->d_buf[s->last_lit] = (ush)dist;
682.1031 +    s->l_buf[s->last_lit++] = (uch)lc;
682.1032 +    if (dist == 0) {
682.1033 +        /* lc is the unmatched char */
682.1034 +        s->dyn_ltree[lc].Freq++;
682.1035 +    } else {
682.1036 +        s->matches++;
682.1037 +        /* Here, lc is the match length - MIN_MATCH */
682.1038 +        dist--;             /* dist = match distance - 1 */
682.1039 +        Assert((ush)dist < (ush)MAX_DIST(s) &&
682.1040 +               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
682.1041 +               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
682.1042 +
682.1043 +        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
682.1044 +        s->dyn_dtree[d_code(dist)].Freq++;
682.1045 +    }
682.1046 +
682.1047 +#ifdef TRUNCATE_BLOCK
682.1048 +    /* Try to guess if it is profitable to stop the current block here */
682.1049 +    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
682.1050 +        /* Compute an upper bound for the compressed length */
682.1051 +        ulg out_length = (ulg)s->last_lit*8L;
682.1052 +        ulg in_length = (ulg)((long)s->strstart - s->block_start);
682.1053 +        int dcode;
682.1054 +        for (dcode = 0; dcode < D_CODES; dcode++) {
682.1055 +            out_length += (ulg)s->dyn_dtree[dcode].Freq *
682.1056 +                (5L+extra_dbits[dcode]);
682.1057 +        }
682.1058 +        out_length >>= 3;
682.1059 +        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
682.1060 +               s->last_lit, in_length, out_length,
682.1061 +               100L - out_length*100L/in_length));
682.1062 +        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
682.1063 +    }
682.1064 +#endif
682.1065 +    return (s->last_lit == s->lit_bufsize-1);
682.1066 +    /* We avoid equality with lit_bufsize because of wraparound at 64K
682.1067 +     * on 16 bit machines and because stored blocks are restricted to
682.1068 +     * 64K-1 bytes.
682.1069 +     */
682.1070 +}
682.1071 +
682.1072 +/* ===========================================================================
682.1073 + * Send the block data compressed using the given Huffman trees
682.1074 + */
682.1075 +local void compress_block(s, ltree, dtree)
682.1076 +    deflate_state *s;
682.1077 +    ct_data *ltree; /* literal tree */
682.1078 +    ct_data *dtree; /* distance tree */
682.1079 +{
682.1080 +    unsigned dist;      /* distance of matched string */
682.1081 +    int lc;             /* match length or unmatched char (if dist == 0) */
682.1082 +    unsigned lx = 0;    /* running index in l_buf */
682.1083 +    unsigned code;      /* the code to send */
682.1084 +    int extra;          /* number of extra bits to send */
682.1085 +
682.1086 +    if (s->last_lit != 0) do {
682.1087 +        dist = s->d_buf[lx];
682.1088 +        lc = s->l_buf[lx++];
682.1089 +        if (dist == 0) {
682.1090 +            send_code(s, lc, ltree); /* send a literal byte */
682.1091 +            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
682.1092 +        } else {
682.1093 +            /* Here, lc is the match length - MIN_MATCH */
682.1094 +            code = _length_code[lc];
682.1095 +            send_code(s, code+LITERALS+1, ltree); /* send the length code */
682.1096 +            extra = extra_lbits[code];
682.1097 +            if (extra != 0) {
682.1098 +                lc -= base_length[code];
682.1099 +                send_bits(s, lc, extra);       /* send the extra length bits */
682.1100 +            }
682.1101 +            dist--; /* dist is now the match distance - 1 */
682.1102 +            code = d_code(dist);
682.1103 +            Assert (code < D_CODES, "bad d_code");
682.1104 +
682.1105 +            send_code(s, code, dtree);       /* send the distance code */
682.1106 +            extra = extra_dbits[code];
682.1107 +            if (extra != 0) {
682.1108 +                dist -= base_dist[code];
682.1109 +                send_bits(s, dist, extra);   /* send the extra distance bits */
682.1110 +            }
682.1111 +        } /* literal or match pair ? */
682.1112 +
682.1113 +        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
682.1114 +        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
682.1115 +               "pendingBuf overflow");
682.1116 +
682.1117 +    } while (lx < s->last_lit);
682.1118 +
682.1119 +    send_code(s, END_BLOCK, ltree);
682.1120 +    s->last_eob_len = ltree[END_BLOCK].Len;
682.1121 +}
682.1122 +
682.1123 +/* ===========================================================================
682.1124 + * Set the data type to BINARY or TEXT, using a crude approximation:
682.1125 + * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
682.1126 + * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
682.1127 + * IN assertion: the fields Freq of dyn_ltree are set.
682.1128 + */
682.1129 +local void set_data_type(s)
682.1130 +    deflate_state *s;
682.1131 +{
682.1132 +    int n;
682.1133 +
682.1134 +    for (n = 0; n < 9; n++)
682.1135 +        if (s->dyn_ltree[n].Freq != 0)
682.1136 +            break;
682.1137 +    if (n == 9)
682.1138 +        for (n = 14; n < 32; n++)
682.1139 +            if (s->dyn_ltree[n].Freq != 0)
682.1140 +                break;
682.1141 +    s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
682.1142 +}
682.1143 +
682.1144 +/* ===========================================================================
682.1145 + * Reverse the first len bits of a code, using straightforward code (a faster
682.1146 + * method would use a table)
682.1147 + * IN assertion: 1 <= len <= 15
682.1148 + */
682.1149 +local unsigned bi_reverse(code, len)
682.1150 +    unsigned code; /* the value to invert */
682.1151 +    int len;       /* its bit length */
682.1152 +{
682.1153 +    register unsigned res = 0;
682.1154 +    do {
682.1155 +        res |= code & 1;
682.1156 +        code >>= 1, res <<= 1;
682.1157 +    } while (--len > 0);
682.1158 +    return res >> 1;
682.1159 +}
682.1160 +
682.1161 +/* ===========================================================================
682.1162 + * Flush the bit buffer, keeping at most 7 bits in it.
682.1163 + */
682.1164 +local void bi_flush(s)
682.1165 +    deflate_state *s;
682.1166 +{
682.1167 +    if (s->bi_valid == 16) {
682.1168 +        put_short(s, s->bi_buf);
682.1169 +        s->bi_buf = 0;
682.1170 +        s->bi_valid = 0;
682.1171 +    } else if (s->bi_valid >= 8) {
682.1172 +        put_byte(s, (Byte)s->bi_buf);
682.1173 +        s->bi_buf >>= 8;
682.1174 +        s->bi_valid -= 8;
682.1175 +    }
682.1176 +}
682.1177 +
682.1178 +/* ===========================================================================
682.1179 + * Flush the bit buffer and align the output on a byte boundary
682.1180 + */
682.1181 +local void bi_windup(s)
682.1182 +    deflate_state *s;
682.1183 +{
682.1184 +    if (s->bi_valid > 8) {
682.1185 +        put_short(s, s->bi_buf);
682.1186 +    } else if (s->bi_valid > 0) {
682.1187 +        put_byte(s, (Byte)s->bi_buf);
682.1188 +    }
682.1189 +    s->bi_buf = 0;
682.1190 +    s->bi_valid = 0;
682.1191 +#ifdef DEBUG
682.1192 +    s->bits_sent = (s->bits_sent+7) & ~7;
682.1193 +#endif
682.1194 +}
682.1195 +
682.1196 +/* ===========================================================================
682.1197 + * Copy a stored block, storing first the length and its
682.1198 + * one's complement if requested.
682.1199 + */
682.1200 +local void copy_block(s, buf, len, header)
682.1201 +    deflate_state *s;
682.1202 +    charf    *buf;    /* the input data */
682.1203 +    unsigned len;     /* its length */
682.1204 +    int      header;  /* true if block header must be written */
682.1205 +{
682.1206 +    bi_windup(s);        /* align on byte boundary */
682.1207 +    s->last_eob_len = 8; /* enough lookahead for inflate */
682.1208 +
682.1209 +    if (header) {
682.1210 +        put_short(s, (ush)len);
682.1211 +        put_short(s, (ush)~len);
682.1212 +#ifdef DEBUG
682.1213 +        s->bits_sent += 2*16;
682.1214 +#endif
682.1215 +    }
682.1216 +#ifdef DEBUG
682.1217 +    s->bits_sent += (ulg)len<<3;
682.1218 +#endif
682.1219 +    while (len--) {
682.1220 +        put_byte(s, *buf++);
682.1221 +    }
682.1222 +}
   683.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   683.2 +++ b/libs/zlib/trees.h	Sat Feb 01 19:58:19 2014 +0200
   683.3 @@ -0,0 +1,128 @@
   683.4 +/* header created automatically with -DGEN_TREES_H */
   683.5 +
   683.6 +local const ct_data static_ltree[L_CODES+2] = {
   683.7 +{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
   683.8 +{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
   683.9 +{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
  683.10 +{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
  683.11 +{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
  683.12 +{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
  683.13 +{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
  683.14 +{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
  683.15 +{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
  683.16 +{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
  683.17 +{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
  683.18 +{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
  683.19 +{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
  683.20 +{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
  683.21 +{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
  683.22 +{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
  683.23 +{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
  683.24 +{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
  683.25 +{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
  683.26 +{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
  683.27 +{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
  683.28 +{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
  683.29 +{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
  683.30 +{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
  683.31 +{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
  683.32 +{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
  683.33 +{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
  683.34 +{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
  683.35 +{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
  683.36 +{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
  683.37 +{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
  683.38 +{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
  683.39 +{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
  683.40 +{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
  683.41 +{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
  683.42 +{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
  683.43 +{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
  683.44 +{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
  683.45 +{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
  683.46 +{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
  683.47 +{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
  683.48 +{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
  683.49 +{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
  683.50 +{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
  683.51 +{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
  683.52 +{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
  683.53 +{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
  683.54 +{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
  683.55 +{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
  683.56 +{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
  683.57 +{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
  683.58 +{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
  683.59 +{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
  683.60 +{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
  683.61 +{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
  683.62 +{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
  683.63 +{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
  683.64 +{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
  683.65 +};
  683.66 +
  683.67 +local const ct_data static_dtree[D_CODES] = {
  683.68 +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
  683.69 +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
  683.70 +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
  683.71 +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
  683.72 +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
  683.73 +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
  683.74 +};
  683.75 +
  683.76 +const uch _dist_code[DIST_CODE_LEN] = {
  683.77 + 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
  683.78 + 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
  683.79 +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
  683.80 +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
  683.81 +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
  683.82 +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
  683.83 +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
  683.84 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
  683.85 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
  683.86 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
  683.87 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
  683.88 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
  683.89 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
  683.90 +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
  683.91 +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
  683.92 +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
  683.93 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
  683.94 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
  683.95 +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
  683.96 +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
  683.97 +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
  683.98 +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
  683.99 +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
 683.100 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
 683.101 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
 683.102 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
 683.103 +};
 683.104 +
 683.105 +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
 683.106 + 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
 683.107 +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
 683.108 +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
 683.109 +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
 683.110 +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
 683.111 +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
 683.112 +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
 683.113 +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
 683.114 +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
 683.115 +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
 683.116 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
 683.117 +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
 683.118 +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
 683.119 +};
 683.120 +
 683.121 +local const int base_length[LENGTH_CODES] = {
 683.122 +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
 683.123 +64, 80, 96, 112, 128, 160, 192, 224, 0
 683.124 +};
 683.125 +
 683.126 +local const int base_dist[D_CODES] = {
 683.127 +    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
 683.128 +   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
 683.129 + 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
 683.130 +};
 683.131 +
   684.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   684.2 +++ b/libs/zlib/uncompr.c	Sat Feb 01 19:58:19 2014 +0200
   684.3 @@ -0,0 +1,61 @@
   684.4 +/* uncompr.c -- decompress a memory buffer
   684.5 + * Copyright (C) 1995-2003 Jean-loup Gailly.
   684.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   684.7 + */
   684.8 +
   684.9 +/* @(#) $Id$ */
  684.10 +
  684.11 +#define ZLIB_INTERNAL
  684.12 +#include "zlib.h"
  684.13 +
  684.14 +/* ===========================================================================
  684.15 +     Decompresses the source buffer into the destination buffer.  sourceLen is
  684.16 +   the byte length of the source buffer. Upon entry, destLen is the total
  684.17 +   size of the destination buffer, which must be large enough to hold the
  684.18 +   entire uncompressed data. (The size of the uncompressed data must have
  684.19 +   been saved previously by the compressor and transmitted to the decompressor
  684.20 +   by some mechanism outside the scope of this compression library.)
  684.21 +   Upon exit, destLen is the actual size of the compressed buffer.
  684.22 +     This function can be used to decompress a whole file at once if the
  684.23 +   input file is mmap'ed.
  684.24 +
  684.25 +     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
  684.26 +   enough memory, Z_BUF_ERROR if there was not enough room in the output
  684.27 +   buffer, or Z_DATA_ERROR if the input data was corrupted.
  684.28 +*/
  684.29 +int ZEXPORT uncompress (dest, destLen, source, sourceLen)
  684.30 +    Bytef *dest;
  684.31 +    uLongf *destLen;
  684.32 +    const Bytef *source;
  684.33 +    uLong sourceLen;
  684.34 +{
  684.35 +    z_stream stream;
  684.36 +    int err;
  684.37 +
  684.38 +    stream.next_in = (Bytef*)source;
  684.39 +    stream.avail_in = (uInt)sourceLen;
  684.40 +    /* Check for source > 64K on 16-bit machine: */
  684.41 +    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
  684.42 +
  684.43 +    stream.next_out = dest;
  684.44 +    stream.avail_out = (uInt)*destLen;
  684.45 +    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
  684.46 +
  684.47 +    stream.zalloc = (alloc_func)0;
  684.48 +    stream.zfree = (free_func)0;
  684.49 +
  684.50 +    err = inflateInit(&stream);
  684.51 +    if (err != Z_OK) return err;
  684.52 +
  684.53 +    err = inflate(&stream, Z_FINISH);
  684.54 +    if (err != Z_STREAM_END) {
  684.55 +        inflateEnd(&stream);
  684.56 +        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
  684.57 +            return Z_DATA_ERROR;
  684.58 +        return err;
  684.59 +    }
  684.60 +    *destLen = stream.total_out;
  684.61 +
  684.62 +    err = inflateEnd(&stream);
  684.63 +    return err;
  684.64 +}
   685.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   685.2 +++ b/libs/zlib/zconf.h	Sat Feb 01 19:58:19 2014 +0200
   685.3 @@ -0,0 +1,332 @@
   685.4 +/* zconf.h -- configuration of the zlib compression library
   685.5 + * Copyright (C) 1995-2005 Jean-loup Gailly.
   685.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   685.7 + */
   685.8 +
   685.9 +/* @(#) $Id$ */
  685.10 +
  685.11 +#ifndef ZCONF_H
  685.12 +#define ZCONF_H
  685.13 +
  685.14 +/*
  685.15 + * If you *really* need a unique prefix for all types and library functions,
  685.16 + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
  685.17 + */
  685.18 +#ifdef Z_PREFIX
  685.19 +#  define deflateInit_          z_deflateInit_
  685.20 +#  define deflate               z_deflate
  685.21 +#  define deflateEnd            z_deflateEnd
  685.22 +#  define inflateInit_          z_inflateInit_
  685.23 +#  define inflate               z_inflate
  685.24 +#  define inflateEnd            z_inflateEnd
  685.25 +#  define deflateInit2_         z_deflateInit2_
  685.26 +#  define deflateSetDictionary  z_deflateSetDictionary
  685.27 +#  define deflateCopy           z_deflateCopy
  685.28 +#  define deflateReset          z_deflateReset
  685.29 +#  define deflateParams         z_deflateParams
  685.30 +#  define deflateBound          z_deflateBound
  685.31 +#  define deflatePrime          z_deflatePrime
  685.32 +#  define inflateInit2_         z_inflateInit2_
  685.33 +#  define inflateSetDictionary  z_inflateSetDictionary
  685.34 +#  define inflateSync           z_inflateSync
  685.35 +#  define inflateSyncPoint      z_inflateSyncPoint
  685.36 +#  define inflateCopy           z_inflateCopy
  685.37 +#  define inflateReset          z_inflateReset
  685.38 +#  define inflateBack           z_inflateBack
  685.39 +#  define inflateBackEnd        z_inflateBackEnd
  685.40 +#  define compress              z_compress
  685.41 +#  define compress2             z_compress2
  685.42 +#  define compressBound         z_compressBound
  685.43 +#  define uncompress            z_uncompress
  685.44 +#  define adler32               z_adler32
  685.45 +#  define crc32                 z_crc32
  685.46 +#  define get_crc_table         z_get_crc_table
  685.47 +#  define zError                z_zError
  685.48 +
  685.49 +#  define alloc_func            z_alloc_func
  685.50 +#  define free_func             z_free_func
  685.51 +#  define in_func               z_in_func
  685.52 +#  define out_func              z_out_func
  685.53 +#  define Byte                  z_Byte
  685.54 +#  define uInt                  z_uInt
  685.55 +#  define uLong                 z_uLong
  685.56 +#  define Bytef                 z_Bytef
  685.57 +#  define charf                 z_charf
  685.58 +#  define intf                  z_intf
  685.59 +#  define uIntf                 z_uIntf
  685.60 +#  define uLongf                z_uLongf
  685.61 +#  define voidpf                z_voidpf
  685.62 +#  define voidp                 z_voidp
  685.63 +#endif
  685.64 +
  685.65 +#if defined(__MSDOS__) && !defined(MSDOS)
  685.66 +#  define MSDOS
  685.67 +#endif
  685.68 +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
  685.69 +#  define OS2
  685.70 +#endif
  685.71 +#if defined(_WINDOWS) && !defined(WINDOWS)
  685.72 +#  define WINDOWS
  685.73 +#endif
  685.74 +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
  685.75 +#  ifndef WIN32
  685.76 +#    define WIN32
  685.77 +#  endif
  685.78 +#endif
  685.79 +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
  685.80 +#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
  685.81 +#    ifndef SYS16BIT
  685.82 +#      define SYS16BIT
  685.83 +#    endif
  685.84 +#  endif
  685.85 +#endif
  685.86 +
  685.87 +/*
  685.88 + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
  685.89 + * than 64k bytes at a time (needed on systems with 16-bit int).
  685.90 + */
  685.91 +#ifdef SYS16BIT
  685.92 +#  define MAXSEG_64K
  685.93 +#endif
  685.94 +#ifdef MSDOS
  685.95 +#  define UNALIGNED_OK
  685.96 +#endif
  685.97 +
  685.98 +#ifdef __STDC_VERSION__
  685.99 +#  ifndef STDC
 685.100 +#    define STDC
 685.101 +#  endif
 685.102 +#  if __STDC_VERSION__ >= 199901L
 685.103 +#    ifndef STDC99
 685.104 +#      define STDC99
 685.105 +#    endif
 685.106 +#  endif
 685.107 +#endif
 685.108 +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
 685.109 +#  define STDC
 685.110 +#endif
 685.111 +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
 685.112 +#  define STDC
 685.113 +#endif
 685.114 +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
 685.115 +#  define STDC
 685.116 +#endif
 685.117 +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
 685.118 +#  define STDC
 685.119 +#endif
 685.120 +
 685.121 +#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
 685.122 +#  define STDC
 685.123 +#endif
 685.124 +
 685.125 +#ifndef STDC
 685.126 +#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
 685.127 +#    define const       /* note: need a more gentle solution here */
 685.128 +#  endif
 685.129 +#endif
 685.130 +
 685.131 +/* Some Mac compilers merge all .h files incorrectly: */
 685.132 +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
 685.133 +#  define NO_DUMMY_DECL
 685.134 +#endif
 685.135 +
 685.136 +/* Maximum value for memLevel in deflateInit2 */
 685.137 +#ifndef MAX_MEM_LEVEL
 685.138 +#  ifdef MAXSEG_64K
 685.139 +#    define MAX_MEM_LEVEL 8
 685.140 +#  else
 685.141 +#    define MAX_MEM_LEVEL 9
 685.142 +#  endif
 685.143 +#endif
 685.144 +
 685.145 +/* Maximum value for windowBits in deflateInit2 and inflateInit2.
 685.146 + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
 685.147 + * created by gzip. (Files created by minigzip can still be extracted by
 685.148 + * gzip.)
 685.149 + */
 685.150 +#ifndef MAX_WBITS
 685.151 +#  define MAX_WBITS   15 /* 32K LZ77 window */
 685.152 +#endif
 685.153 +
 685.154 +/* The memory requirements for deflate are (in bytes):
 685.155 +            (1 << (windowBits+2)) +  (1 << (memLevel+9))
 685.156 + that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
 685.157 + plus a few kilobytes for small objects. For example, if you want to reduce
 685.158 + the default memory requirements from 256K to 128K, compile with
 685.159 +     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
 685.160 + Of course this will generally degrade compression (there's no free lunch).
 685.161 +
 685.162 +   The memory requirements for inflate are (in bytes) 1 << windowBits
 685.163 + that is, 32K for windowBits=15 (default value) plus a few kilobytes
 685.164 + for small objects.
 685.165 +*/
 685.166 +
 685.167 +                        /* Type declarations */
 685.168 +
 685.169 +#ifndef OF /* function prototypes */
 685.170 +#  ifdef STDC
 685.171 +#    define OF(args)  args
 685.172 +#  else
 685.173 +#    define OF(args)  ()
 685.174 +#  endif
 685.175 +#endif
 685.176 +
 685.177 +/* The following definitions for FAR are needed only for MSDOS mixed
 685.178 + * model programming (small or medium model with some far allocations).
 685.179 + * This was tested only with MSC; for other MSDOS compilers you may have
 685.180 + * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
 685.181 + * just define FAR to be empty.
 685.182 + */
 685.183 +#ifdef SYS16BIT
 685.184 +#  if defined(M_I86SM) || defined(M_I86MM)
 685.185 +     /* MSC small or medium model */
 685.186 +#    define SMALL_MEDIUM
 685.187 +#    ifdef _MSC_VER
 685.188 +#      define FAR _far
 685.189 +#    else
 685.190 +#      define FAR far
 685.191 +#    endif
 685.192 +#  endif
 685.193 +#  if (defined(__SMALL__) || defined(__MEDIUM__))
 685.194 +     /* Turbo C small or medium model */
 685.195 +#    define SMALL_MEDIUM
 685.196 +#    ifdef __BORLANDC__
 685.197 +#      define FAR _far
 685.198 +#    else
 685.199 +#      define FAR far
 685.200 +#    endif
 685.201 +#  endif
 685.202 +#endif
 685.203 +
 685.204 +#if defined(WINDOWS) || defined(WIN32)
 685.205 +   /* If building or using zlib as a DLL, define ZLIB_DLL.
 685.206 +    * This is not mandatory, but it offers a little performance increase.
 685.207 +    */
 685.208 +#  ifdef ZLIB_DLL
 685.209 +#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
 685.210 +#      ifdef ZLIB_INTERNAL
 685.211 +#        define ZEXTERN extern __declspec(dllexport)
 685.212 +#      else
 685.213 +#        define ZEXTERN extern __declspec(dllimport)
 685.214 +#      endif
 685.215 +#    endif
 685.216 +#  endif  /* ZLIB_DLL */
 685.217 +   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
 685.218 +    * define ZLIB_WINAPI.
 685.219 +    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
 685.220 +    */
 685.221 +#  ifdef ZLIB_WINAPI
 685.222 +#    ifdef FAR
 685.223 +#      undef FAR
 685.224 +#    endif
 685.225 +#    include <windows.h>
 685.226 +     /* No need for _export, use ZLIB.DEF instead. */
 685.227 +     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
 685.228 +#    define ZEXPORT WINAPI
 685.229 +#    ifdef WIN32
 685.230 +#      define ZEXPORTVA WINAPIV
 685.231 +#    else
 685.232 +#      define ZEXPORTVA FAR CDECL
 685.233 +#    endif
 685.234 +#  endif
 685.235 +#endif
 685.236 +
 685.237 +#if defined (__BEOS__)
 685.238 +#  ifdef ZLIB_DLL
 685.239 +#    ifdef ZLIB_INTERNAL
 685.240 +#      define ZEXPORT   __declspec(dllexport)
 685.241 +#      define ZEXPORTVA __declspec(dllexport)
 685.242 +#    else
 685.243 +#      define ZEXPORT   __declspec(dllimport)
 685.244 +#      define ZEXPORTVA __declspec(dllimport)
 685.245 +#    endif
 685.246 +#  endif
 685.247 +#endif
 685.248 +
 685.249 +#ifndef ZEXTERN
 685.250 +#  define ZEXTERN extern
 685.251 +#endif
 685.252 +#ifndef ZEXPORT
 685.253 +#  define ZEXPORT
 685.254 +#endif
 685.255 +#ifndef ZEXPORTVA
 685.256 +#  define ZEXPORTVA
 685.257 +#endif
 685.258 +
 685.259 +#ifndef FAR
 685.260 +#  define FAR
 685.261 +#endif
 685.262 +
 685.263 +#if !defined(__MACTYPES__)
 685.264 +typedef unsigned char  Byte;  /* 8 bits */
 685.265 +#endif
 685.266 +typedef unsigned int   uInt;  /* 16 bits or more */
 685.267 +typedef unsigned long  uLong; /* 32 bits or more */
 685.268 +
 685.269 +#ifdef SMALL_MEDIUM
 685.270 +   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
 685.271 +#  define Bytef Byte FAR
 685.272 +#else
 685.273 +   typedef Byte  FAR Bytef;
 685.274 +#endif
 685.275 +typedef char  FAR charf;
 685.276 +typedef int   FAR intf;
 685.277 +typedef uInt  FAR uIntf;
 685.278 +typedef uLong FAR uLongf;
 685.279 +
 685.280 +#ifdef STDC
 685.281 +   typedef void const *voidpc;
 685.282 +   typedef void FAR   *voidpf;
 685.283 +   typedef void       *voidp;
 685.284 +#else
 685.285 +   typedef Byte const *voidpc;
 685.286 +   typedef Byte FAR   *voidpf;
 685.287 +   typedef Byte       *voidp;
 685.288 +#endif
 685.289 +
 685.290 +#if 0           /* HAVE_UNISTD_H -- this line is updated by ./configure */
 685.291 +#  include <sys/types.h> /* for off_t */
 685.292 +#  include <unistd.h>    /* for SEEK_* and off_t */
 685.293 +#  ifdef VMS
 685.294 +#    include <unixio.h>   /* for off_t */
 685.295 +#  endif
 685.296 +#  define z_off_t off_t
 685.297 +#endif
 685.298 +#ifndef SEEK_SET
 685.299 +#  define SEEK_SET        0       /* Seek from beginning of file.  */
 685.300 +#  define SEEK_CUR        1       /* Seek from current position.  */
 685.301 +#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
 685.302 +#endif
 685.303 +#ifndef z_off_t
 685.304 +#  define z_off_t long
 685.305 +#endif
 685.306 +
 685.307 +#if defined(__OS400__)
 685.308 +#  define NO_vsnprintf
 685.309 +#endif
 685.310 +
 685.311 +#if defined(__MVS__)
 685.312 +#  define NO_vsnprintf
 685.313 +#  ifdef FAR
 685.314 +#    undef FAR
 685.315 +#  endif
 685.316 +#endif
 685.317 +
 685.318 +/* MVS linker does not support external names larger than 8 bytes */
 685.319 +#if defined(__MVS__)
 685.320 +#   pragma map(deflateInit_,"DEIN")
 685.321 +#   pragma map(deflateInit2_,"DEIN2")
 685.322 +#   pragma map(deflateEnd,"DEEND")
 685.323 +#   pragma map(deflateBound,"DEBND")
 685.324 +#   pragma map(inflateInit_,"ININ")
 685.325 +#   pragma map(inflateInit2_,"ININ2")
 685.326 +#   pragma map(inflateEnd,"INEND")
 685.327 +#   pragma map(inflateSync,"INSY")
 685.328 +#   pragma map(inflateSetDictionary,"INSEDI")
 685.329 +#   pragma map(compressBound,"CMBND")
 685.330 +#   pragma map(inflate_table,"INTABL")
 685.331 +#   pragma map(inflate_fast,"INFA")
 685.332 +#   pragma map(inflate_copyright,"INCOPY")
 685.333 +#endif
 685.334 +
 685.335 +#endif /* ZCONF_H */
   686.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   686.2 +++ b/libs/zlib/zlib.h	Sat Feb 01 19:58:19 2014 +0200
   686.3 @@ -0,0 +1,1357 @@
   686.4 +/* zlib.h -- interface of the 'zlib' general purpose compression library
   686.5 +  version 1.2.3, July 18th, 2005
   686.6 +
   686.7 +  Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
   686.8 +
   686.9 +  This software is provided 'as-is', without any express or implied
  686.10 +  warranty.  In no event will the authors be held liable for any damages
  686.11 +  arising from the use of this software.
  686.12 +
  686.13 +  Permission is granted to anyone to use this software for any purpose,
  686.14 +  including commercial applications, and to alter it and redistribute it
  686.15 +  freely, subject to the following restrictions:
  686.16 +
  686.17 +  1. The origin of this software must not be misrepresented; you must not
  686.18 +     claim that you wrote the original software. If you use this software
  686.19 +     in a product, an acknowledgment in the product documentation would be
  686.20 +     appreciated but is not required.
  686.21 +  2. Altered source versions must be plainly marked as such, and must not be
  686.22 +     misrepresented as being the original software.
  686.23 +  3. This notice may not be removed or altered from any source distribution.
  686.24 +
  686.25 +  Jean-loup Gailly        Mark Adler
  686.26 +  jloup@gzip.org          madler@alumni.caltech.edu
  686.27 +
  686.28 +
  686.29 +  The data format used by the zlib library is described by RFCs (Request for
  686.30 +  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
  686.31 +  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
  686.32 +*/
  686.33 +
  686.34 +#ifndef ZLIB_H
  686.35 +#define ZLIB_H
  686.36 +
  686.37 +#include "zconf.h"
  686.38 +
  686.39 +#ifdef __cplusplus
  686.40 +extern "C" {
  686.41 +#endif
  686.42 +
  686.43 +#define ZLIB_VERSION "1.2.3"
  686.44 +#define ZLIB_VERNUM 0x1230
  686.45 +
  686.46 +/*
  686.47 +     The 'zlib' compression library provides in-memory compression and
  686.48 +  decompression functions, including integrity checks of the uncompressed
  686.49 +  data.  This version of the library supports only one compression method
  686.50 +  (deflation) but other algorithms will be added later and will have the same
  686.51 +  stream interface.
  686.52 +
  686.53 +     Compression can be done in a single step if the buffers are large
  686.54 +  enough (for example if an input file is mmap'ed), or can be done by
  686.55 +  repeated calls of the compression function.  In the latter case, the
  686.56 +  application must provide more input and/or consume the output
  686.57 +  (providing more output space) before each call.
  686.58 +
  686.59 +     The compressed data format used by default by the in-memory functions is
  686.60 +  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
  686.61 +  around a deflate stream, which is itself documented in RFC 1951.
  686.62 +
  686.63 +     The library also supports reading and writing files in gzip (.gz) format
  686.64 +  with an interface similar to that of stdio using the functions that start
  686.65 +  with "gz".  The gzip format is different from the zlib format.  gzip is a
  686.66 +  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
  686.67 +
  686.68 +     This library can optionally read and write gzip streams in memory as well.
  686.69 +
  686.70 +     The zlib format was designed to be compact and fast for use in memory
  686.71 +  and on communications channels.  The gzip format was designed for single-
  686.72 +  file compression on file systems, has a larger header than zlib to maintain
  686.73 +  directory information, and uses a different, slower check method than zlib.
  686.74 +
  686.75 +     The library does not install any signal handler. The decoder checks
  686.76 +  the consistency of the compressed data, so the library should never
  686.77 +  crash even in case of corrupted input.
  686.78 +*/
  686.79 +
  686.80 +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
  686.81 +typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
  686.82 +
  686.83 +struct internal_state;
  686.84 +
  686.85 +typedef struct z_stream_s {
  686.86 +    Bytef    *next_in;  /* next input byte */
  686.87 +    uInt     avail_in;  /* number of bytes available at next_in */
  686.88 +    uLong    total_in;  /* total nb of input bytes read so far */
  686.89 +
  686.90 +    Bytef    *next_out; /* next output byte should be put there */
  686.91 +    uInt     avail_out; /* remaining free space at next_out */
  686.92 +    uLong    total_out; /* total nb of bytes output so far */
  686.93 +
  686.94 +    char     *msg;      /* last error message, NULL if no error */
  686.95 +    struct internal_state FAR *state; /* not visible by applications */
  686.96 +
  686.97 +    alloc_func zalloc;  /* used to allocate the internal state */
  686.98 +    free_func  zfree;   /* used to free the internal state */
  686.99 +    voidpf     opaque;  /* private data object passed to zalloc and zfree */
 686.100 +
 686.101 +    int     data_type;  /* best guess about the data type: binary or text */
 686.102 +    uLong   adler;      /* adler32 value of the uncompressed data */
 686.103 +    uLong   reserved;   /* reserved for future use */
 686.104 +} z_stream;
 686.105 +
 686.106 +typedef z_stream FAR *z_streamp;
 686.107 +
 686.108 +/*
 686.109 +     gzip header information passed to and from zlib routines.  See RFC 1952
 686.110 +  for more details on the meanings of these fields.
 686.111 +*/
 686.112 +typedef struct gz_header_s {
 686.113 +    int     text;       /* true if compressed data believed to be text */
 686.114 +    uLong   time;       /* modification time */
 686.115 +    int     xflags;     /* extra flags (not used when writing a gzip file) */
 686.116 +    int     os;         /* operating system */
 686.117 +    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
 686.118 +    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
 686.119 +    uInt    extra_max;  /* space at extra (only when reading header) */
 686.120 +    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
 686.121 +    uInt    name_max;   /* space at name (only when reading header) */
 686.122 +    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
 686.123 +    uInt    comm_max;   /* space at comment (only when reading header) */
 686.124 +    int     hcrc;       /* true if there was or will be a header crc */
 686.125 +    int     done;       /* true when done reading gzip header (not used
 686.126 +                           when writing a gzip file) */
 686.127 +} gz_header;
 686.128 +
 686.129 +typedef gz_header FAR *gz_headerp;
 686.130 +
 686.131 +/*
 686.132 +   The application must update next_in and avail_in when avail_in has
 686.133 +   dropped to zero. It must update next_out and avail_out when avail_out
 686.134 +   has dropped to zero. The application must initialize zalloc, zfree and
 686.135 +   opaque before calling the init function. All other fields are set by the
 686.136 +   compression library and must not be updated by the application.
 686.137 +
 686.138 +   The opaque value provided by the application will be passed as the first
 686.139 +   parameter for calls of zalloc and zfree. This can be useful for custom
 686.140 +   memory management. The compression library attaches no meaning to the
 686.141 +   opaque value.
 686.142 +
 686.143 +   zalloc must return Z_NULL if there is not enough memory for the object.
 686.144 +   If zlib is used in a multi-threaded application, zalloc and zfree must be
 686.145 +   thread safe.
 686.146 +
 686.147 +   On 16-bit systems, the functions zalloc and zfree must be able to allocate
 686.148 +   exactly 65536 bytes, but will not be required to allocate more than this
 686.149 +   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
 686.150 +   pointers returned by zalloc for objects of exactly 65536 bytes *must*
 686.151 +   have their offset normalized to zero. The default allocation function
 686.152 +   provided by this library ensures this (see zutil.c). To reduce memory
 686.153 +   requirements and avoid any allocation of 64K objects, at the expense of
 686.154 +   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
 686.155 +
 686.156 +   The fields total_in and total_out can be used for statistics or
 686.157 +   progress reports. After compression, total_in holds the total size of
 686.158 +   the uncompressed data and may be saved for use in the decompressor
 686.159 +   (particularly if the decompressor wants to decompress everything in
 686.160 +   a single step).
 686.161 +*/
 686.162 +
 686.163 +                        /* constants */
 686.164 +
 686.165 +#define Z_NO_FLUSH      0
 686.166 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
 686.167 +#define Z_SYNC_FLUSH    2
 686.168 +#define Z_FULL_FLUSH    3
 686.169 +#define Z_FINISH        4
 686.170 +#define Z_BLOCK         5
 686.171 +/* Allowed flush values; see deflate() and inflate() below for details */
 686.172 +
 686.173 +#define Z_OK            0
 686.174 +#define Z_STREAM_END    1
 686.175 +#define Z_NEED_DICT     2
 686.176 +#define Z_ERRNO        (-1)
 686.177 +#define Z_STREAM_ERROR (-2)
 686.178 +#define Z_DATA_ERROR   (-3)
 686.179 +#define Z_MEM_ERROR    (-4)
 686.180 +#define Z_BUF_ERROR    (-5)
 686.181 +#define Z_VERSION_ERROR (-6)
 686.182 +/* Return codes for the compression/decompression functions. Negative
 686.183 + * values are errors, positive values are used for special but normal events.
 686.184 + */
 686.185 +
 686.186 +#define Z_NO_COMPRESSION         0
 686.187 +#define Z_BEST_SPEED             1
 686.188 +#define Z_BEST_COMPRESSION       9
 686.189 +#define Z_DEFAULT_COMPRESSION  (-1)
 686.190 +/* compression levels */
 686.191 +
 686.192 +#define Z_FILTERED            1
 686.193 +#define Z_HUFFMAN_ONLY        2
 686.194 +#define Z_RLE                 3
 686.195 +#define Z_FIXED               4
 686.196 +#define Z_DEFAULT_STRATEGY    0
 686.197 +/* compression strategy; see deflateInit2() below for details */
 686.198 +
 686.199 +#define Z_BINARY   0
 686.200 +#define Z_TEXT     1
 686.201 +#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
 686.202 +#define Z_UNKNOWN  2
 686.203 +/* Possible values of the data_type field (though see inflate()) */
 686.204 +
 686.205 +#define Z_DEFLATED   8
 686.206 +/* The deflate compression method (the only one supported in this version) */
 686.207 +
 686.208 +#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
 686.209 +
 686.210 +#define zlib_version zlibVersion()
 686.211 +/* for compatibility with versions < 1.0.2 */
 686.212 +
 686.213 +                        /* basic functions */
 686.214 +
 686.215 +ZEXTERN const char * ZEXPORT zlibVersion OF((void));
 686.216 +/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
 686.217 +   If the first character differs, the library code actually used is
 686.218 +   not compatible with the zlib.h header file used by the application.
 686.219 +   This check is automatically made by deflateInit and inflateInit.
 686.220 + */
 686.221 +
 686.222 +/*
 686.223 +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
 686.224 +
 686.225 +     Initializes the internal stream state for compression. The fields
 686.226 +   zalloc, zfree and opaque must be initialized before by the caller.
 686.227 +   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
 686.228 +   use default allocation functions.
 686.229 +
 686.230 +     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
 686.231 +   1 gives best speed, 9 gives best compression, 0 gives no compression at
 686.232 +   all (the input data is simply copied a block at a time).
 686.233 +   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
 686.234 +   compression (currently equivalent to level 6).
 686.235 +
 686.236 +     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
 686.237 +   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
 686.238 +   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
 686.239 +   with the version assumed by the caller (ZLIB_VERSION).
 686.240 +   msg is set to null if there is no error message.  deflateInit does not
 686.241 +   perform any compression: this will be done by deflate().
 686.242 +*/
 686.243 +
 686.244 +
 686.245 +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
 686.246 +/*
 686.247 +    deflate compresses as much data as possible, and stops when the input
 686.248 +  buffer becomes empty or the output buffer becomes full. It may introduce some
 686.249 +  output latency (reading input without producing any output) except when
 686.250 +  forced to flush.
 686.251 +
 686.252 +    The detailed semantics are as follows. deflate performs one or both of the
 686.253 +  following actions:
 686.254 +
 686.255 +  - Compress more input starting at next_in and update next_in and avail_in
 686.256 +    accordingly. If not all input can be processed (because there is not
 686.257 +    enough room in the output buffer), next_in and avail_in are updated and
 686.258 +    processing will resume at this point for the next call of deflate().
 686.259 +
 686.260 +  - Provide more output starting at next_out and update next_out and avail_out
 686.261 +    accordingly. This action is forced if the parameter flush is non zero.
 686.262 +    Forcing flush frequently degrades the compression ratio, so this parameter
 686.263 +    should be set only when necessary (in interactive applications).
 686.264 +    Some output may be provided even if flush is not set.
 686.265 +
 686.266 +  Before the call of deflate(), the application should ensure that at least
 686.267 +  one of the actions is possible, by providing more input and/or consuming
 686.268 +  more output, and updating avail_in or avail_out accordingly; avail_out
 686.269 +  should never be zero before the call. The application can consume the
 686.270 +  compressed output when it wants, for example when the output buffer is full
 686.271 +  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
 686.272 +  and with zero avail_out, it must be called again after making room in the
 686.273 +  output buffer because there might be more output pending.
 686.274 +
 686.275 +    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
 686.276 +  decide how much data to accumualte before producing output, in order to
 686.277 +  maximize compression.
 686.278 +
 686.279 +    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
 686.280 +  flushed to the output buffer and the output is aligned on a byte boundary, so
 686.281 +  that the decompressor can get all input data available so far. (In particular
 686.282 +  avail_in is zero after the call if enough output space has been provided
 686.283 +  before the call.)  Flushing may degrade compression for some compression
 686.284 +  algorithms and so it should be used only when necessary.
 686.285 +
 686.286 +    If flush is set to Z_FULL_FLUSH, all output is flushed as with
 686.287 +  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
 686.288 +  restart from this point if previous compressed data has been damaged or if
 686.289 +  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
 686.290 +  compression.
 686.291 +
 686.292 +    If deflate returns with avail_out == 0, this function must be called again
 686.293 +  with the same value of the flush parameter and more output space (updated
 686.294 +  avail_out), until the flush is complete (deflate returns with non-zero
 686.295 +  avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
 686.296 +  avail_out is greater than six to avoid repeated flush markers due to
 686.297 +  avail_out == 0 on return.
 686.298 +
 686.299 +    If the parameter flush is set to Z_FINISH, pending input is processed,
 686.300 +  pending output is flushed and deflate returns with Z_STREAM_END if there
 686.301 +  was enough output space; if deflate returns with Z_OK, this function must be
 686.302 +  called again with Z_FINISH and more output space (updated avail_out) but no
 686.303 +  more input data, until it returns with Z_STREAM_END or an error. After
 686.304 +  deflate has returned Z_STREAM_END, the only possible operations on the
 686.305 +  stream are deflateReset or deflateEnd.
 686.306 +
 686.307 +    Z_FINISH can be used immediately after deflateInit if all the compression
 686.308 +  is to be done in a single step. In this case, avail_out must be at least
 686.309 +  the value returned by deflateBound (see below). If deflate does not return
 686.310 +  Z_STREAM_END, then it must be called again as described above.
 686.311 +
 686.312 +    deflate() sets strm->adler to the adler32 checksum of all input read
 686.313 +  so far (that is, total_in bytes).
 686.314 +
 686.315 +    deflate() may update strm->data_type if it can make a good guess about
 686.316 +  the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
 686.317 +  binary. This field is only for information purposes and does not affect
 686.318 +  the compression algorithm in any manner.
 686.319 +
 686.320 +    deflate() returns Z_OK if some progress has been made (more input
 686.321 +  processed or more output produced), Z_STREAM_END if all input has been
 686.322 +  consumed and all output has been produced (only when flush is set to
 686.323 +  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
 686.324 +  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
 686.325 +  (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
 686.326 +  fatal, and deflate() can be called again with more input and more output
 686.327 +  space to continue compressing.
 686.328 +*/
 686.329 +
 686.330 +
 686.331 +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
 686.332 +/*
 686.333 +     All dynamically allocated data structures for this stream are freed.
 686.334 +   This function discards any unprocessed input and does not flush any
 686.335 +   pending output.
 686.336 +
 686.337 +     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
 686.338 +   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
 686.339 +   prematurely (some input or output was discarded). In the error case,
 686.340 +   msg may be set but then points to a static string (which must not be
 686.341 +   deallocated).
 686.342 +*/
 686.343 +
 686.344 +
 686.345 +/*
 686.346 +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
 686.347 +
 686.348 +     Initializes the internal stream state for decompression. The fields
 686.349 +   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
 686.350 +   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
 686.351 +   value depends on the compression method), inflateInit determines the
 686.352 +   compression method from the zlib header and allocates all data structures
 686.353 +   accordingly; otherwise the allocation will be deferred to the first call of
 686.354 +   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
 686.355 +   use default allocation functions.
 686.356 +
 686.357 +     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
 686.358 +   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
 686.359 +   version assumed by the caller.  msg is set to null if there is no error
 686.360 +   message. inflateInit does not perform any decompression apart from reading
 686.361 +   the zlib header if present: this will be done by inflate().  (So next_in and
 686.362 +   avail_in may be modified, but next_out and avail_out are unchanged.)
 686.363 +*/
 686.364 +
 686.365 +
 686.366 +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
 686.367 +/*
 686.368 +    inflate decompresses as much data as possible, and stops when the input
 686.369 +  buffer becomes empty or the output buffer becomes full. It may introduce
 686.370 +  some output latency (reading input without producing any output) except when
 686.371 +  forced to flush.
 686.372 +
 686.373 +  The detailed semantics are as follows. inflate performs one or both of the
 686.374 +  following actions:
 686.375 +
 686.376 +  - Decompress more input starting at next_in and update next_in and avail_in
 686.377 +    accordingly. If not all input can be processed (because there is not
 686.378 +    enough room in the output buffer), next_in is updated and processing
 686.379 +    will resume at this point for the next call of inflate().
 686.380 +
 686.381 +  - Provide more output starting at next_out and update next_out and avail_out
 686.382 +    accordingly.  inflate() provides as much output as possible, until there
 686.383 +    is no more input data or no more space in the output buffer (see below
 686.384 +    about the flush parameter).
 686.385 +
 686.386 +  Before the call of inflate(), the application should ensure that at least
 686.387 +  one of the actions is possible, by providing more input and/or consuming
 686.388 +  more output, and updating the next_* and avail_* values accordingly.
 686.389 +  The application can consume the uncompressed output when it wants, for
 686.390 +  example when the output buffer is full (avail_out == 0), or after each
 686.391 +  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
 686.392 +  must be called again after making room in the output buffer because there
 686.393 +  might be more output pending.
 686.394 +
 686.395 +    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
 686.396 +  Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
 686.397 +  output as possible to the output buffer. Z_BLOCK requests that inflate() stop
 686.398 +  if and when it gets to the next deflate block boundary. When decoding the
 686.399 +  zlib or gzip format, this will cause inflate() to return immediately after
 686.400 +  the header and before the first block. When doing a raw inflate, inflate()
 686.401 +  will go ahead and process the first block, and will return when it gets to
 686.402 +  the end of that block, or when it runs out of data.
 686.403 +
 686.404 +    The Z_BLOCK option assists in appending to or combining deflate streams.
 686.405 +  Also to assist in this, on return inflate() will set strm->data_type to the
 686.406 +  number of unused bits in the last byte taken from strm->next_in, plus 64
 686.407 +  if inflate() is currently decoding the last block in the deflate stream,
 686.408 +  plus 128 if inflate() returned immediately after decoding an end-of-block
 686.409 +  code or decoding the complete header up to just before the first byte of the
 686.410 +  deflate stream. The end-of-block will not be indicated until all of the
 686.411 +  uncompressed data from that block has been written to strm->next_out.  The
 686.412 +  number of unused bits may in general be greater than seven, except when
 686.413 +  bit 7 of data_type is set, in which case the number of unused bits will be
 686.414 +  less than eight.
 686.415 +
 686.416 +    inflate() should normally be called until it returns Z_STREAM_END or an
 686.417 +  error. However if all decompression is to be performed in a single step
 686.418 +  (a single call of inflate), the parameter flush should be set to
 686.419 +  Z_FINISH. In this case all pending input is processed and all pending
 686.420 +  output is flushed; avail_out must be large enough to hold all the
 686.421 +  uncompressed data. (The size of the uncompressed data may have been saved
 686.422 +  by the compressor for this purpose.) The next operation on this stream must
 686.423 +  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
 686.424 +  is never required, but can be used to inform inflate that a faster approach
 686.425 +  may be used for the single inflate() call.
 686.426 +
 686.427 +     In this implementation, inflate() always flushes as much output as
 686.428 +  possible to the output buffer, and always uses the faster approach on the
 686.429 +  first call. So the only effect of the flush parameter in this implementation
 686.430 +  is on the return value of inflate(), as noted below, or when it returns early
 686.431 +  because Z_BLOCK is used.
 686.432 +
 686.433 +     If a preset dictionary is needed after this call (see inflateSetDictionary
 686.434 +  below), inflate sets strm->adler to the adler32 checksum of the dictionary
 686.435 +  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
 686.436 +  strm->adler to the adler32 checksum of all output produced so far (that is,
 686.437 +  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
 686.438 +  below. At the end of the stream, inflate() checks that its computed adler32
 686.439 +  checksum is equal to that saved by the compressor and returns Z_STREAM_END
 686.440 +  only if the checksum is correct.
 686.441 +
 686.442 +    inflate() will decompress and check either zlib-wrapped or gzip-wrapped
 686.443 +  deflate data.  The header type is detected automatically.  Any information
 686.444 +  contained in the gzip header is not retained, so applications that need that
 686.445 +  information should instead use raw inflate, see inflateInit2() below, or
 686.446 +  inflateBack() and perform their own processing of the gzip header and
 686.447 +  trailer.
 686.448 +
 686.449 +    inflate() returns Z_OK if some progress has been made (more input processed
 686.450 +  or more output produced), Z_STREAM_END if the end of the compressed data has
 686.451 +  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
 686.452 +  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
 686.453 +  corrupted (input stream not conforming to the zlib format or incorrect check
 686.454 +  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
 686.455 +  if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
 686.456 +  Z_BUF_ERROR if no progress is possible or if there was not enough room in the
 686.457 +  output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
 686.458 +  inflate() can be called again with more input and more output space to
 686.459 +  continue decompressing. If Z_DATA_ERROR is returned, the application may then
 686.460 +  call inflateSync() to look for a good compression block if a partial recovery
 686.461 +  of the data is desired.
 686.462 +*/
 686.463 +
 686.464 +
 686.465 +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
 686.466 +/*
 686.467 +     All dynamically allocated data structures for this stream are freed.
 686.468 +   This function discards any unprocessed input and does not flush any
 686.469 +   pending output.
 686.470 +
 686.471 +     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
 686.472 +   was inconsistent. In the error case, msg may be set but then points to a
 686.473 +   static string (which must not be deallocated).
 686.474 +*/
 686.475 +
 686.476 +                        /* Advanced functions */
 686.477 +
 686.478 +/*
 686.479 +    The following functions are needed only in some special applications.
 686.480 +*/
 686.481 +
 686.482 +/*
 686.483 +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
 686.484 +                                     int  level,
 686.485 +                                     int  method,
 686.486 +                                     int  windowBits,
 686.487 +                                     int  memLevel,
 686.488 +                                     int  strategy));
 686.489 +
 686.490 +     This is another version of deflateInit with more compression options. The
 686.491 +   fields next_in, zalloc, zfree and opaque must be initialized before by
 686.492 +   the caller.
 686.493 +
 686.494 +     The method parameter is the compression method. It must be Z_DEFLATED in
 686.495 +   this version of the library.
 686.496 +
 686.497 +     The windowBits parameter is the base two logarithm of the window size
 686.498 +   (the size of the history buffer). It should be in the range 8..15 for this
 686.499 +   version of the library. Larger values of this parameter result in better
 686.500 +   compression at the expense of memory usage. The default value is 15 if
 686.501 +   deflateInit is used instead.
 686.502 +
 686.503 +     windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
 686.504 +   determines the window size. deflate() will then generate raw deflate data
 686.505 +   with no zlib header or trailer, and will not compute an adler32 check value.
 686.506 +
 686.507 +     windowBits can also be greater than 15 for optional gzip encoding. Add
 686.508 +   16 to windowBits to write a simple gzip header and trailer around the
 686.509 +   compressed data instead of a zlib wrapper. The gzip header will have no
 686.510 +   file name, no extra data, no comment, no modification time (set to zero),
 686.511 +   no header crc, and the operating system will be set to 255 (unknown).  If a
 686.512 +   gzip stream is being written, strm->adler is a crc32 instead of an adler32.
 686.513 +
 686.514 +     The memLevel parameter specifies how much memory should be allocated
 686.515 +   for the internal compression state. memLevel=1 uses minimum memory but
 686.516 +   is slow and reduces compression ratio; memLevel=9 uses maximum memory
 686.517 +   for optimal speed. The default value is 8. See zconf.h for total memory
 686.518 +   usage as a function of windowBits and memLevel.
 686.519 +
 686.520 +     The strategy parameter is used to tune the compression algorithm. Use the
 686.521 +   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
 686.522 +   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
 686.523 +   string match), or Z_RLE to limit match distances to one (run-length
 686.524 +   encoding). Filtered data consists mostly of small values with a somewhat
 686.525 +   random distribution. In this case, the compression algorithm is tuned to
 686.526 +   compress them better. The effect of Z_FILTERED is to force more Huffman
 686.527 +   coding and less string matching; it is somewhat intermediate between
 686.528 +   Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
 686.529 +   Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
 686.530 +   parameter only affects the compression ratio but not the correctness of the
 686.531 +   compressed output even if it is not set appropriately.  Z_FIXED prevents the
 686.532 +   use of dynamic Huffman codes, allowing for a simpler decoder for special
 686.533 +   applications.
 686.534 +
 686.535 +      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
 686.536 +   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
 686.537 +   method). msg is set to null if there is no error message.  deflateInit2 does
 686.538 +   not perform any compression: this will be done by deflate().
 686.539 +*/
 686.540 +
 686.541 +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
 686.542 +                                             const Bytef *dictionary,
 686.543 +                                             uInt  dictLength));
 686.544 +/*
 686.545 +     Initializes the compression dictionary from the given byte sequence
 686.546 +   without producing any compressed output. This function must be called
 686.547 +   immediately after deflateInit, deflateInit2 or deflateReset, before any
 686.548 +   call of deflate. The compressor and decompressor must use exactly the same
 686.549 +   dictionary (see inflateSetDictionary).
 686.550 +
 686.551 +     The dictionary should consist of strings (byte sequences) that are likely
 686.552 +   to be encountered later in the data to be compressed, with the most commonly
 686.553 +   used strings preferably put towards the end of the dictionary. Using a
 686.554 +   dictionary is most useful when the data to be compressed is short and can be
 686.555 +   predicted with good accuracy; the data can then be compressed better than
 686.556 +   with the default empty dictionary.
 686.557 +
 686.558 +     Depending on the size of the compression data structures selected by
 686.559 +   deflateInit or deflateInit2, a part of the dictionary may in effect be
 686.560 +   discarded, for example if the dictionary is larger than the window size in
 686.561 +   deflate or deflate2. Thus the strings most likely to be useful should be
 686.562 +   put at the end of the dictionary, not at the front. In addition, the
 686.563 +   current implementation of deflate will use at most the window size minus
 686.564 +   262 bytes of the provided dictionary.
 686.565 +
 686.566 +     Upon return of this function, strm->adler is set to the adler32 value
 686.567 +   of the dictionary; the decompressor may later use this value to determine
 686.568 +   which dictionary has been used by the compressor. (The adler32 value
 686.569 +   applies to the whole dictionary even if only a subset of the dictionary is
 686.570 +   actually used by the compressor.) If a raw deflate was requested, then the
 686.571 +   adler32 value is not computed and strm->adler is not set.
 686.572 +
 686.573 +     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
 686.574 +   parameter is invalid (such as NULL dictionary) or the stream state is
 686.575 +   inconsistent (for example if deflate has already been called for this stream
 686.576 +   or if the compression method is bsort). deflateSetDictionary does not
 686.577 +   perform any compression: this will be done by deflate().
 686.578 +*/
 686.579 +
 686.580 +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
 686.581 +                                    z_streamp source));
 686.582 +/*
 686.583 +     Sets the destination stream as a complete copy of the source stream.
 686.584 +
 686.585 +     This function can be useful when several compression strategies will be
 686.586 +   tried, for example when there are several ways of pre-processing the input
 686.587 +   data with a filter. The streams that will be discarded should then be freed
 686.588 +   by calling deflateEnd.  Note that deflateCopy duplicates the internal
 686.589 +   compression state which can be quite large, so this strategy is slow and
 686.590 +   can consume lots of memory.
 686.591 +
 686.592 +     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
 686.593 +   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
 686.594 +   (such as zalloc being NULL). msg is left unchanged in both source and
 686.595 +   destination.
 686.596 +*/
 686.597 +
 686.598 +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
 686.599 +/*
 686.600 +     This function is equivalent to deflateEnd followed by deflateInit,
 686.601 +   but does not free and reallocate all the internal compression state.
 686.602 +   The stream will keep the same compression level and any other attributes
 686.603 +   that may have been set by deflateInit2.
 686.604 +
 686.605 +      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
 686.606 +   stream state was inconsistent (such as zalloc or state being NULL).
 686.607 +*/
 686.608 +
 686.609 +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
 686.610 +                                      int level,
 686.611 +                                      int strategy));
 686.612 +/*
 686.613 +     Dynamically update the compression level and compression strategy.  The
 686.614 +   interpretation of level and strategy is as in deflateInit2.  This can be
 686.615 +   used to switch between compression and straight copy of the input data, or
 686.616 +   to switch to a different kind of input data requiring a different
 686.617 +   strategy. If the compression level is changed, the input available so far
 686.618 +   is compressed with the old level (and may be flushed); the new level will
 686.619 +   take effect only at the next call of deflate().
 686.620 +
 686.621 +     Before the call of deflateParams, the stream state must be set as for
 686.622 +   a call of deflate(), since the currently available input may have to
 686.623 +   be compressed and flushed. In particular, strm->avail_out must be non-zero.
 686.624 +
 686.625 +     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
 686.626 +   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
 686.627 +   if strm->avail_out was zero.
 686.628 +*/
 686.629 +
 686.630 +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
 686.631 +                                    int good_length,
 686.632 +                                    int max_lazy,
 686.633 +                                    int nice_length,
 686.634 +                                    int max_chain));
 686.635 +/*
 686.636 +     Fine tune deflate's internal compression parameters.  This should only be
 686.637 +   used by someone who understands the algorithm used by zlib's deflate for
 686.638 +   searching for the best matching string, and even then only by the most
 686.639 +   fanatic optimizer trying to squeeze out the last compressed bit for their
 686.640 +   specific input data.  Read the deflate.c source code for the meaning of the
 686.641 +   max_lazy, good_length, nice_length, and max_chain parameters.
 686.642 +
 686.643 +     deflateTune() can be called after deflateInit() or deflateInit2(), and
 686.644 +   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
 686.645 + */
 686.646 +
 686.647 +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
 686.648 +                                       uLong sourceLen));
 686.649 +/*
 686.650 +     deflateBound() returns an upper bound on the compressed size after
 686.651 +   deflation of sourceLen bytes.  It must be called after deflateInit()
 686.652 +   or deflateInit2().  This would be used to allocate an output buffer
 686.653 +   for deflation in a single pass, and so would be called before deflate().
 686.654 +*/
 686.655 +
 686.656 +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
 686.657 +                                     int bits,
 686.658 +                                     int value));
 686.659 +/*
 686.660 +     deflatePrime() inserts bits in the deflate output stream.  The intent
 686.661 +  is that this function is used to start off the deflate output with the
 686.662 +  bits leftover from a previous deflate stream when appending to it.  As such,
 686.663 +  this function can only be used for raw deflate, and must be used before the
 686.664 +  first deflate() call after a deflateInit2() or deflateReset().  bits must be
 686.665 +  less than or equal to 16, and that many of the least significant bits of
 686.666 +  value will be inserted in the output.
 686.667 +
 686.668 +      deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
 686.669 +   stream state was inconsistent.
 686.670 +*/
 686.671 +
 686.672 +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
 686.673 +                                         gz_headerp head));
 686.674 +/*
 686.675 +      deflateSetHeader() provides gzip header information for when a gzip
 686.676 +   stream is requested by deflateInit2().  deflateSetHeader() may be called
 686.677 +   after deflateInit2() or deflateReset() and before the first call of
 686.678 +   deflate().  The text, time, os, extra field, name, and comment information
 686.679 +   in the provided gz_header structure are written to the gzip header (xflag is
 686.680 +   ignored -- the extra flags are set according to the compression level).  The
 686.681 +   caller must assure that, if not Z_NULL, name and comment are terminated with
 686.682 +   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
 686.683 +   available there.  If hcrc is true, a gzip header crc is included.  Note that
 686.684 +   the current versions of the command-line version of gzip (up through version
 686.685 +   1.3.x) do not support header crc's, and will report that it is a "multi-part
 686.686 +   gzip file" and give up.
 686.687 +
 686.688 +      If deflateSetHeader is not used, the default gzip header has text false,
 686.689 +   the time set to zero, and os set to 255, with no extra, name, or comment
 686.690 +   fields.  The gzip header is returned to the default state by deflateReset().
 686.691 +
 686.692 +      deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
 686.693 +   stream state was inconsistent.
 686.694 +*/
 686.695 +
 686.696 +/*
 686.697 +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
 686.698 +                                     int  windowBits));
 686.699 +
 686.700 +     This is another version of inflateInit with an extra parameter. The
 686.701 +   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
 686.702 +   before by the caller.
 686.703 +
 686.704 +     The windowBits parameter is the base two logarithm of the maximum window
 686.705 +   size (the size of the history buffer).  It should be in the range 8..15 for
 686.706 +   this version of the library. The default value is 15 if inflateInit is used
 686.707 +   instead. windowBits must be greater than or equal to the windowBits value
 686.708 +   provided to deflateInit2() while compressing, or it must be equal to 15 if
 686.709 +   deflateInit2() was not used. If a compressed stream with a larger window
 686.710 +   size is given as input, inflate() will return with the error code
 686.711 +   Z_DATA_ERROR instead of trying to allocate a larger window.
 686.712 +
 686.713 +     windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
 686.714 +   determines the window size. inflate() will then process raw deflate data,
 686.715 +   not looking for a zlib or gzip header, not generating a check value, and not
 686.716 +   looking for any check values for comparison at the end of the stream. This
 686.717 +   is for use with other formats that use the deflate compressed data format
 686.718 +   such as zip.  Those formats provide their own check values. If a custom
 686.719 +   format is developed using the raw deflate format for compressed data, it is
 686.720 +   recommended that a check value such as an adler32 or a crc32 be applied to
 686.721 +   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
 686.722 +   most applications, the zlib format should be used as is. Note that comments
 686.723 +   above on the use in deflateInit2() applies to the magnitude of windowBits.
 686.724 +
 686.725 +     windowBits can also be greater than 15 for optional gzip decoding. Add
 686.726 +   32 to windowBits to enable zlib and gzip decoding with automatic header
 686.727 +   detection, or add 16 to decode only the gzip format (the zlib format will
 686.728 +   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is
 686.729 +   a crc32 instead of an adler32.
 686.730 +
 686.731 +     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
 686.732 +   memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
 686.733 +   is set to null if there is no error message.  inflateInit2 does not perform
 686.734 +   any decompression apart from reading the zlib header if present: this will
 686.735 +   be done by inflate(). (So next_in and avail_in may be modified, but next_out
 686.736 +   and avail_out are unchanged.)
 686.737 +*/
 686.738 +
 686.739 +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
 686.740 +                                             const Bytef *dictionary,
 686.741 +                                             uInt  dictLength));
 686.742 +/*
 686.743 +     Initializes the decompression dictionary from the given uncompressed byte
 686.744 +   sequence. This function must be called immediately after a call of inflate,
 686.745 +   if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
 686.746 +   can be determined from the adler32 value returned by that call of inflate.
 686.747 +   The compressor and decompressor must use exactly the same dictionary (see
 686.748 +   deflateSetDictionary).  For raw inflate, this function can be called
 686.749 +   immediately after inflateInit2() or inflateReset() and before any call of
 686.750 +   inflate() to set the dictionary.  The application must insure that the
 686.751 +   dictionary that was used for compression is provided.
 686.752 +
 686.753 +     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
 686.754 +   parameter is invalid (such as NULL dictionary) or the stream state is
 686.755 +   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
 686.756 +   expected one (incorrect adler32 value). inflateSetDictionary does not
 686.757 +   perform any decompression: this will be done by subsequent calls of
 686.758 +   inflate().
 686.759 +*/
 686.760 +
 686.761 +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
 686.762 +/*
 686.763 +    Skips invalid compressed data until a full flush point (see above the
 686.764 +  description of deflate with Z_FULL_FLUSH) can be found, or until all
 686.765 +  available input is skipped. No output is provided.
 686.766 +
 686.767 +    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
 686.768 +  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
 686.769 +  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
 686.770 +  case, the application may save the current current value of total_in which
 686.771 +  indicates where valid compressed data was found. In the error case, the
 686.772 +  application may repeatedly call inflateSync, providing more input each time,
 686.773 +  until success or end of the input data.
 686.774 +*/
 686.775 +
 686.776 +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
 686.777 +                                    z_streamp source));
 686.778 +/*
 686.779 +     Sets the destination stream as a complete copy of the source stream.
 686.780 +
 686.781 +     This function can be useful when randomly accessing a large stream.  The
 686.782 +   first pass through the stream can periodically record the inflate state,
 686.783 +   allowing restarting inflate at those points when randomly accessing the
 686.784 +   stream.
 686.785 +
 686.786 +     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
 686.787 +   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
 686.788 +   (such as zalloc being NULL). msg is left unchanged in both source and
 686.789 +   destination.
 686.790 +*/
 686.791 +
 686.792 +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
 686.793 +/*
 686.794 +     This function is equivalent to inflateEnd followed by inflateInit,
 686.795 +   but does not free and reallocate all the internal decompression state.
 686.796 +   The stream will keep attributes that may have been set by inflateInit2.
 686.797 +
 686.798 +      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
 686.799 +   stream state was inconsistent (such as zalloc or state being NULL).
 686.800 +*/
 686.801 +
 686.802 +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
 686.803 +                                     int bits,
 686.804 +                                     int value));
 686.805 +/*
 686.806 +     This function inserts bits in the inflate input stream.  The intent is
 686.807 +  that this function is used to start inflating at a bit position in the
 686.808 +  middle of a byte.  The provided bits will be used before any bytes are used
 686.809 +  from next_in.  This function should only be used with raw inflate, and
 686.810 +  should be used before the first inflate() call after inflateInit2() or
 686.811 +  inflateReset().  bits must be less than or equal to 16, and that many of the
 686.812 +  least significant bits of value will be inserted in the input.
 686.813 +
 686.814 +      inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
 686.815 +   stream state was inconsistent.
 686.816 +*/
 686.817 +
 686.818 +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
 686.819 +                                         gz_headerp head));
 686.820 +/*
 686.821 +      inflateGetHeader() requests that gzip header information be stored in the
 686.822 +   provided gz_header structure.  inflateGetHeader() may be called after
 686.823 +   inflateInit2() or inflateReset(), and before the first call of inflate().
 686.824 +   As inflate() processes the gzip stream, head->done is zero until the header
 686.825 +   is completed, at which time head->done is set to one.  If a zlib stream is
 686.826 +   being decoded, then head->done is set to -1 to indicate that there will be
 686.827 +   no gzip header information forthcoming.  Note that Z_BLOCK can be used to
 686.828 +   force inflate() to return immediately after header processing is complete
 686.829 +   and before any actual data is decompressed.
 686.830 +
 686.831 +      The text, time, xflags, and os fields are filled in with the gzip header
 686.832 +   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
 686.833 +   was valid if done is set to one.)  If extra is not Z_NULL, then extra_max
 686.834 +   contains the maximum number of bytes to write to extra.  Once done is true,
 686.835 +   extra_len contains the actual extra field length, and extra contains the
 686.836 +   extra field, or that field truncated if extra_max is less than extra_len.
 686.837 +   If name is not Z_NULL, then up to name_max characters are written there,
 686.838 +   terminated with a zero unless the length is greater than name_max.  If
 686.839 +   comment is not Z_NULL, then up to comm_max characters are written there,
 686.840 +   terminated with a zero unless the length is greater than comm_max.  When
 686.841 +   any of extra, name, or comment are not Z_NULL and the respective field is
 686.842 +   not present in the header, then that field is set to Z_NULL to signal its
 686.843 +   absence.  This allows the use of deflateSetHeader() with the returned
 686.844 +   structure to duplicate the header.  However if those fields are set to
 686.845 +   allocated memory, then the application will need to save those pointers
 686.846 +   elsewhere so that they can be eventually freed.
 686.847 +
 686.848 +      If inflateGetHeader is not used, then the header information is simply
 686.849 +   discarded.  The header is always checked for validity, including the header
 686.850 +   CRC if present.  inflateReset() will reset the process to discard the header
 686.851 +   information.  The application would need to call inflateGetHeader() again to
 686.852 +   retrieve the header from the next gzip stream.
 686.853 +
 686.854 +      inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
 686.855 +   stream state was inconsistent.
 686.856 +*/
 686.857 +
 686.858 +/*
 686.859 +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
 686.860 +                                        unsigned char FAR *window));
 686.861 +
 686.862 +     Initialize the internal stream state for decompression using inflateBack()
 686.863 +   calls.  The fields zalloc, zfree and opaque in strm must be initialized
 686.864 +   before the call.  If zalloc and zfree are Z_NULL, then the default library-
 686.865 +   derived memory allocation routines are used.  windowBits is the base two
 686.866 +   logarithm of the window size, in the range 8..15.  window is a caller
 686.867 +   supplied buffer of that size.  Except for special applications where it is
 686.868 +   assured that deflate was used with small window sizes, windowBits must be 15
 686.869 +   and a 32K byte window must be supplied to be able to decompress general
 686.870 +   deflate streams.
 686.871 +
 686.872 +     See inflateBack() for the usage of these routines.
 686.873 +
 686.874 +     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
 686.875 +   the paramaters are invalid, Z_MEM_ERROR if the internal state could not
 686.876 +   be allocated, or Z_VERSION_ERROR if the version of the library does not
 686.877 +   match the version of the header file.
 686.878 +*/
 686.879 +
 686.880 +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
 686.881 +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
 686.882 +
 686.883 +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
 686.884 +                                    in_func in, void FAR *in_desc,
 686.885 +                                    out_func out, void FAR *out_desc));
 686.886 +/*
 686.887 +     inflateBack() does a raw inflate with a single call using a call-back
 686.888 +   interface for input and output.  This is more efficient than inflate() for
 686.889 +   file i/o applications in that it avoids copying between the output and the
 686.890 +   sliding window by simply making the window itself the output buffer.  This
 686.891 +   function trusts the application to not change the output buffer passed by
 686.892 +   the output function, at least until inflateBack() returns.
 686.893 +
 686.894 +     inflateBackInit() must be called first to allocate the internal state
 686.895 +   and to initialize the state with the user-provided window buffer.
 686.896 +   inflateBack() may then be used multiple times to inflate a complete, raw
 686.897 +   deflate stream with each call.  inflateBackEnd() is then called to free
 686.898 +   the allocated state.
 686.899 +
 686.900 +     A raw deflate stream is one with no zlib or gzip header or trailer.
 686.901 +   This routine would normally be used in a utility that reads zip or gzip
 686.902 +   files and writes out uncompressed files.  The utility would decode the
 686.903 +   header and process the trailer on its own, hence this routine expects
 686.904 +   only the raw deflate stream to decompress.  This is different from the
 686.905 +   normal behavior of inflate(), which expects either a zlib or gzip header and
 686.906 +   trailer around the deflate stream.
 686.907 +
 686.908 +     inflateBack() uses two subroutines supplied by the caller that are then
 686.909 +   called by inflateBack() for input and output.  inflateBack() calls those
 686.910 +   routines until it reads a complete deflate stream and writes out all of the
 686.911 +   uncompressed data, or until it encounters an error.  The function's
 686.912 +   parameters and return types are defined above in the in_func and out_func
 686.913 +   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
 686.914 +   number of bytes of provided input, and a pointer to that input in buf.  If
 686.915 +   there is no input available, in() must return zero--buf is ignored in that
 686.916 +   case--and inflateBack() will return a buffer error.  inflateBack() will call
 686.917 +   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out()
 686.918 +   should return zero on success, or non-zero on failure.  If out() returns
 686.919 +   non-zero, inflateBack() will return with an error.  Neither in() nor out()
 686.920 +   are permitted to change the contents of the window provided to
 686.921 +   inflateBackInit(), which is also the buffer that out() uses to write from.
 686.922 +   The length written by out() will be at most the window size.  Any non-zero
 686.923 +   amount of input may be provided by in().
 686.924 +
 686.925 +     For convenience, inflateBack() can be provided input on the first call by
 686.926 +   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
 686.927 +   in() will be called.  Therefore strm->next_in must be initialized before
 686.928 +   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
 686.929 +   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
 686.930 +   must also be initialized, and then if strm->avail_in is not zero, input will
 686.931 +   initially be taken from strm->next_in[0 .. strm->avail_in - 1].
 686.932 +
 686.933 +     The in_desc and out_desc parameters of inflateBack() is passed as the
 686.934 +   first parameter of in() and out() respectively when they are called.  These
 686.935 +   descriptors can be optionally used to pass any information that the caller-
 686.936 +   supplied in() and out() functions need to do their job.
 686.937 +
 686.938 +     On return, inflateBack() will set strm->next_in and strm->avail_in to
 686.939 +   pass back any unused input that was provided by the last in() call.  The
 686.940 +   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
 686.941 +   if in() or out() returned an error, Z_DATA_ERROR if there was a format
 686.942 +   error in the deflate stream (in which case strm->msg is set to indicate the
 686.943 +   nature of the error), or Z_STREAM_ERROR if the stream was not properly
 686.944 +   initialized.  In the case of Z_BUF_ERROR, an input or output error can be
 686.945 +   distinguished using strm->next_in which will be Z_NULL only if in() returned
 686.946 +   an error.  If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
 686.947 +   out() returning non-zero.  (in() will always be called before out(), so
 686.948 +   strm->next_in is assured to be defined if out() returns non-zero.)  Note
 686.949 +   that inflateBack() cannot return Z_OK.
 686.950 +*/
 686.951 +
 686.952 +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
 686.953 +/*
 686.954 +     All memory allocated by inflateBackInit() is freed.
 686.955 +
 686.956 +     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
 686.957 +   state was inconsistent.
 686.958 +*/
 686.959 +
 686.960 +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
 686.961 +/* Return flags indicating compile-time options.
 686.962 +
 686.963 +    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
 686.964 +     1.0: size of uInt
 686.965 +     3.2: size of uLong
 686.966 +     5.4: size of voidpf (pointer)
 686.967 +     7.6: size of z_off_t
 686.968 +
 686.969 +    Compiler, assembler, and debug options:
 686.970 +     8: DEBUG
 686.971 +     9: ASMV or ASMINF -- use ASM code
 686.972 +     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
 686.973 +     11: 0 (reserved)
 686.974 +
 686.975 +    One-time table building (smaller code, but not thread-safe if true):
 686.976 +     12: BUILDFIXED -- build static block decoding tables when needed
 686.977 +     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
 686.978 +     14,15: 0 (reserved)
 686.979 +
 686.980 +    Library content (indicates missing functionality):
 686.981 +     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
 686.982 +                          deflate code when not needed)
 686.983 +     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
 686.984 +                    and decode gzip streams (to avoid linking crc code)
 686.985 +     18-19: 0 (reserved)
 686.986 +
 686.987 +    Operation variations (changes in library functionality):
 686.988 +     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
 686.989 +     21: FASTEST -- deflate algorithm with only one, lowest compression level
 686.990 +     22,23: 0 (reserved)
 686.991 +
 686.992 +    The sprintf variant used by gzprintf (zero is best):
 686.993 +     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
 686.994 +     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
 686.995 +     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
 686.996 +
 686.997 +    Remainder:
 686.998 +     27-31: 0 (reserved)
 686.999 + */
686.1000 +
686.1001 +
686.1002 +                        /* utility functions */
686.1003 +
686.1004 +/*
686.1005 +     The following utility functions are implemented on top of the
686.1006 +   basic stream-oriented functions. To simplify the interface, some
686.1007 +   default options are assumed (compression level and memory usage,
686.1008 +   standard memory allocation functions). The source code of these
686.1009 +   utility functions can easily be modified if you need special options.
686.1010 +*/
686.1011 +
686.1012 +ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
686.1013 +                                 const Bytef *source, uLong sourceLen));
686.1014 +/*
686.1015 +     Compresses the source buffer into the destination buffer.  sourceLen is
686.1016 +   the byte length of the source buffer. Upon entry, destLen is the total
686.1017 +   size of the destination buffer, which must be at least the value returned
686.1018 +   by compressBound(sourceLen). Upon exit, destLen is the actual size of the
686.1019 +   compressed buffer.
686.1020 +     This function can be used to compress a whole file at once if the
686.1021 +   input file is mmap'ed.
686.1022 +     compress returns Z_OK if success, Z_MEM_ERROR if there was not
686.1023 +   enough memory, Z_BUF_ERROR if there was not enough room in the output
686.1024 +   buffer.
686.1025 +*/
686.1026 +
686.1027 +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
686.1028 +                                  const Bytef *source, uLong sourceLen,
686.1029 +                                  int level));
686.1030 +/*
686.1031 +     Compresses the source buffer into the destination buffer. The level
686.1032 +   parameter has the same meaning as in deflateInit.  sourceLen is the byte
686.1033 +   length of the source buffer. Upon entry, destLen is the total size of the
686.1034 +   destination buffer, which must be at least the value returned by
686.1035 +   compressBound(sourceLen). Upon exit, destLen is the actual size of the
686.1036 +   compressed buffer.
686.1037 +
686.1038 +     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
686.1039 +   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
686.1040 +   Z_STREAM_ERROR if the level parameter is invalid.
686.1041 +*/
686.1042 +
686.1043 +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
686.1044 +/*
686.1045 +     compressBound() returns an upper bound on the compressed size after
686.1046 +   compress() or compress2() on sourceLen bytes.  It would be used before
686.1047 +   a compress() or compress2() call to allocate the destination buffer.
686.1048 +*/
686.1049 +
686.1050 +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
686.1051 +                                   const Bytef *source, uLong sourceLen));
686.1052 +/*
686.1053 +     Decompresses the source buffer into the destination buffer.  sourceLen is
686.1054 +   the byte length of the source buffer. Upon entry, destLen is the total
686.1055 +   size of the destination buffer, which must be large enough to hold the
686.1056 +   entire uncompressed data. (The size of the uncompressed data must have
686.1057 +   been saved previously by the compressor and transmitted to the decompressor
686.1058 +   by some mechanism outside the scope of this compression library.)
686.1059 +   Upon exit, destLen is the actual size of the compressed buffer.
686.1060 +     This function can be used to decompress a whole file at once if the
686.1061 +   input file is mmap'ed.
686.1062 +
686.1063 +     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
686.1064 +   enough memory, Z_BUF_ERROR if there was not enough room in the output
686.1065 +   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
686.1066 +*/
686.1067 +
686.1068 +
686.1069 +typedef voidp gzFile;
686.1070 +
686.1071 +ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
686.1072 +/*
686.1073 +     Opens a gzip (.gz) file for reading or writing. The mode parameter
686.1074 +   is as in fopen ("rb" or "wb") but can also include a compression level
686.1075 +   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
686.1076 +   Huffman only compression as in "wb1h", or 'R' for run-length encoding
686.1077 +   as in "wb1R". (See the description of deflateInit2 for more information
686.1078 +   about the strategy parameter.)
686.1079 +
686.1080 +     gzopen can be used to read a file which is not in gzip format; in this
686.1081 +   case gzread will directly read from the file without decompression.
686.1082 +
686.1083 +     gzopen returns NULL if the file could not be opened or if there was
686.1084 +   insufficient memory to allocate the (de)compression state; errno
686.1085 +   can be checked to distinguish the two cases (if errno is zero, the
686.1086 +   zlib error is Z_MEM_ERROR).  */
686.1087 +
686.1088 +ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
686.1089 +/*
686.1090 +     gzdopen() associates a gzFile with the file descriptor fd.  File
686.1091 +   descriptors are obtained from calls like open, dup, creat, pipe or
686.1092 +   fileno (in the file has been previously opened with fopen).
686.1093 +   The mode parameter is as in gzopen.
686.1094 +     The next call of gzclose on the returned gzFile will also close the
686.1095 +   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
686.1096 +   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
686.1097 +     gzdopen returns NULL if there was insufficient memory to allocate
686.1098 +   the (de)compression state.
686.1099 +*/
686.1100 +
686.1101 +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
686.1102 +/*
686.1103 +     Dynamically update the compression level or strategy. See the description
686.1104 +   of deflateInit2 for the meaning of these parameters.
686.1105 +     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
686.1106 +   opened for writing.
686.1107 +*/
686.1108 +
686.1109 +ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
686.1110 +/*
686.1111 +     Reads the given number of uncompressed bytes from the compressed file.
686.1112 +   If the input file was not in gzip format, gzread copies the given number
686.1113 +   of bytes into the buffer.
686.1114 +     gzread returns the number of uncompressed bytes actually read (0 for
686.1115 +   end of file, -1 for error). */
686.1116 +
686.1117 +ZEXTERN int ZEXPORT    gzwrite OF((gzFile file,
686.1118 +                                   voidpc buf, unsigned len));
686.1119 +/*
686.1120 +     Writes the given number of uncompressed bytes into the compressed file.
686.1121 +   gzwrite returns the number of uncompressed bytes actually written
686.1122 +   (0 in case of error).
686.1123 +*/
686.1124 +
686.1125 +ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
686.1126 +/*
686.1127 +     Converts, formats, and writes the args to the compressed file under
686.1128 +   control of the format string, as in fprintf. gzprintf returns the number of
686.1129 +   uncompressed bytes actually written (0 in case of error).  The number of
686.1130 +   uncompressed bytes written is limited to 4095. The caller should assure that
686.1131 +   this limit is not exceeded. If it is exceeded, then gzprintf() will return
686.1132 +   return an error (0) with nothing written. In this case, there may also be a
686.1133 +   buffer overflow with unpredictable consequences, which is possible only if
686.1134 +   zlib was compiled with the insecure functions sprintf() or vsprintf()
686.1135 +   because the secure snprintf() or vsnprintf() functions were not available.
686.1136 +*/
686.1137 +
686.1138 +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
686.1139 +/*
686.1140 +      Writes the given null-terminated string to the compressed file, excluding
686.1141 +   the terminating null character.
686.1142 +      gzputs returns the number of characters written, or -1 in case of error.
686.1143 +*/
686.1144 +
686.1145 +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
686.1146 +/*
686.1147 +      Reads bytes from the compressed file until len-1 characters are read, or
686.1148 +   a newline character is read and transferred to buf, or an end-of-file
686.1149 +   condition is encountered.  The string is then terminated with a null
686.1150 +   character.
686.1151 +      gzgets returns buf, or Z_NULL in case of error.
686.1152 +*/
686.1153 +
686.1154 +ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c));
686.1155 +/*
686.1156 +      Writes c, converted to an unsigned char, into the compressed file.
686.1157 +   gzputc returns the value that was written, or -1 in case of error.
686.1158 +*/
686.1159 +
686.1160 +ZEXTERN int ZEXPORT    gzgetc OF((gzFile file));
686.1161 +/*
686.1162 +      Reads one byte from the compressed file. gzgetc returns this byte
686.1163 +   or -1 in case of end of file or error.
686.1164 +*/
686.1165 +
686.1166 +ZEXTERN int ZEXPORT    gzungetc OF((int c, gzFile file));
686.1167 +/*
686.1168 +      Push one character back onto the stream to be read again later.
686.1169 +   Only one character of push-back is allowed.  gzungetc() returns the
686.1170 +   character pushed, or -1 on failure.  gzungetc() will fail if a
686.1171 +   character has been pushed but not read yet, or if c is -1. The pushed
686.1172 +   character will be discarded if the stream is repositioned with gzseek()
686.1173 +   or gzrewind().
686.1174 +*/
686.1175 +
686.1176 +ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush));
686.1177 +/*
686.1178 +     Flushes all pending output into the compressed file. The parameter
686.1179 +   flush is as in the deflate() function. The return value is the zlib
686.1180 +   error number (see function gzerror below). gzflush returns Z_OK if
686.1181 +   the flush parameter is Z_FINISH and all output could be flushed.
686.1182 +     gzflush should be called only when strictly necessary because it can
686.1183 +   degrade compression.
686.1184 +*/
686.1185 +
686.1186 +ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file,
686.1187 +                                      z_off_t offset, int whence));
686.1188 +/*
686.1189 +      Sets the starting position for the next gzread or gzwrite on the
686.1190 +   given compressed file. The offset represents a number of bytes in the
686.1191 +   uncompressed data stream. The whence parameter is defined as in lseek(2);
686.1192 +   the value SEEK_END is not supported.
686.1193 +     If the file is opened for reading, this function is emulated but can be
686.1194 +   extremely slow. If the file is opened for writing, only forward seeks are
686.1195 +   supported; gzseek then compresses a sequence of zeroes up to the new
686.1196 +   starting position.
686.1197 +
686.1198 +      gzseek returns the resulting offset location as measured in bytes from
686.1199 +   the beginning of the uncompressed stream, or -1 in case of error, in
686.1200 +   particular if the file is opened for writing and the new starting position
686.1201 +   would be before the current position.
686.1202 +*/
686.1203 +
686.1204 +ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
686.1205 +/*
686.1206 +     Rewinds the given file. This function is supported only for reading.
686.1207 +
686.1208 +   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
686.1209 +*/
686.1210 +
686.1211 +ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
686.1212 +/*
686.1213 +     Returns the starting position for the next gzread or gzwrite on the
686.1214 +   given compressed file. This position represents a number of bytes in the
686.1215 +   uncompressed data stream.
686.1216 +
686.1217 +   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
686.1218 +*/
686.1219 +
686.1220 +ZEXTERN int ZEXPORT gzeof OF((gzFile file));
686.1221 +/*
686.1222 +     Returns 1 when EOF has previously been detected reading the given
686.1223 +   input stream, otherwise zero.
686.1224 +*/
686.1225 +
686.1226 +ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
686.1227 +/*
686.1228 +     Returns 1 if file is being read directly without decompression, otherwise
686.1229 +   zero.
686.1230 +*/
686.1231 +
686.1232 +ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
686.1233 +/*
686.1234 +     Flushes all pending output if necessary, closes the compressed file
686.1235 +   and deallocates all the (de)compression state. The return value is the zlib
686.1236 +   error number (see function gzerror below).
686.1237 +*/
686.1238 +
686.1239 +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
686.1240 +/*
686.1241 +     Returns the error message for the last error which occurred on the
686.1242 +   given compressed file. errnum is set to zlib error number. If an
686.1243 +   error occurred in the file system and not in the compression library,
686.1244 +   errnum is set to Z_ERRNO and the application may consult errno
686.1245 +   to get the exact error code.
686.1246 +*/
686.1247 +
686.1248 +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
686.1249 +/*
686.1250 +     Clears the error and end-of-file flags for file. This is analogous to the
686.1251 +   clearerr() function in stdio. This is useful for continuing to read a gzip
686.1252 +   file that is being written concurrently.
686.1253 +*/
686.1254 +
686.1255 +                        /* checksum functions */
686.1256 +
686.1257 +/*
686.1258 +     These functions are not related to compression but are exported
686.1259 +   anyway because they might be useful in applications using the
686.1260 +   compression library.
686.1261 +*/
686.1262 +
686.1263 +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
686.1264 +/*
686.1265 +     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
686.1266 +   return the updated checksum. If buf is NULL, this function returns
686.1267 +   the required initial value for the checksum.
686.1268 +   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
686.1269 +   much faster. Usage example:
686.1270 +
686.1271 +     uLong adler = adler32(0L, Z_NULL, 0);
686.1272 +
686.1273 +     while (read_buffer(buffer, length) != EOF) {
686.1274 +       adler = adler32(adler, buffer, length);
686.1275 +     }
686.1276 +     if (adler != original_adler) error();
686.1277 +*/
686.1278 +
686.1279 +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
686.1280 +                                          z_off_t len2));
686.1281 +/*
686.1282 +     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
686.1283 +   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
686.1284 +   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
686.1285 +   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
686.1286 +*/
686.1287 +
686.1288 +ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
686.1289 +/*
686.1290 +     Update a running CRC-32 with the bytes buf[0..len-1] and return the
686.1291 +   updated CRC-32. If buf is NULL, this function returns the required initial
686.1292 +   value for the for the crc. Pre- and post-conditioning (one's complement) is
686.1293 +   performed within this function so it shouldn't be done by the application.
686.1294 +   Usage example:
686.1295 +
686.1296 +     uLong crc = crc32(0L, Z_NULL, 0);
686.1297 +
686.1298 +     while (read_buffer(buffer, length) != EOF) {
686.1299 +       crc = crc32(crc, buffer, length);
686.1300 +     }
686.1301 +     if (crc != original_crc) error();
686.1302 +*/
686.1303 +
686.1304 +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
686.1305 +
686.1306 +/*
686.1307 +     Combine two CRC-32 check values into one.  For two sequences of bytes,
686.1308 +   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
686.1309 +   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
686.1310 +   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
686.1311 +   len2.
686.1312 +*/
686.1313 +
686.1314 +
686.1315 +                        /* various hacks, don't look :) */
686.1316 +
686.1317 +/* deflateInit and inflateInit are macros to allow checking the zlib version
686.1318 + * and the compiler's view of z_stream:
686.1319 + */
686.1320 +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
686.1321 +                                     const char *version, int stream_size));
686.1322 +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
686.1323 +                                     const char *version, int stream_size));
686.1324 +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
686.1325 +                                      int windowBits, int memLevel,
686.1326 +                                      int strategy, const char *version,
686.1327 +                                      int stream_size));
686.1328 +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
686.1329 +                                      const char *version, int stream_size));
686.1330 +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
686.1331 +                                         unsigned char FAR *window,
686.1332 +                                         const char *version,
686.1333 +                                         int stream_size));
686.1334 +#define deflateInit(strm, level) \
686.1335 +        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
686.1336 +#define inflateInit(strm) \
686.1337 +        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
686.1338 +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
686.1339 +        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
686.1340 +                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
686.1341 +#define inflateInit2(strm, windowBits) \
686.1342 +        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
686.1343 +#define inflateBackInit(strm, windowBits, window) \
686.1344 +        inflateBackInit_((strm), (windowBits), (window), \
686.1345 +        ZLIB_VERSION, sizeof(z_stream))
686.1346 +
686.1347 +
686.1348 +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
686.1349 +    struct internal_state {int dummy;}; /* hack for buggy compilers */
686.1350 +#endif
686.1351 +
686.1352 +ZEXTERN const char   * ZEXPORT zError           OF((int));
686.1353 +ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z));
686.1354 +ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
686.1355 +
686.1356 +#ifdef __cplusplus
686.1357 +}
686.1358 +#endif
686.1359 +
686.1360 +#endif /* ZLIB_H */
   687.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   687.2 +++ b/libs/zlib/zutil.c	Sat Feb 01 19:58:19 2014 +0200
   687.3 @@ -0,0 +1,318 @@
   687.4 +/* zutil.c -- target dependent utility functions for the compression library
   687.5 + * Copyright (C) 1995-2005 Jean-loup Gailly.
   687.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   687.7 + */
   687.8 +
   687.9 +/* @(#) $Id$ */
  687.10 +
  687.11 +#include "zutil.h"
  687.12 +
  687.13 +#ifndef NO_DUMMY_DECL
  687.14 +struct internal_state      {int dummy;}; /* for buggy compilers */
  687.15 +#endif
  687.16 +
  687.17 +const char * const z_errmsg[10] = {
  687.18 +"need dictionary",     /* Z_NEED_DICT       2  */
  687.19 +"stream end",          /* Z_STREAM_END      1  */
  687.20 +"",                    /* Z_OK              0  */
  687.21 +"file error",          /* Z_ERRNO         (-1) */
  687.22 +"stream error",        /* Z_STREAM_ERROR  (-2) */
  687.23 +"data error",          /* Z_DATA_ERROR    (-3) */
  687.24 +"insufficient memory", /* Z_MEM_ERROR     (-4) */
  687.25 +"buffer error",        /* Z_BUF_ERROR     (-5) */
  687.26 +"incompatible version",/* Z_VERSION_ERROR (-6) */
  687.27 +""};
  687.28 +
  687.29 +
  687.30 +const char * ZEXPORT zlibVersion()
  687.31 +{
  687.32 +    return ZLIB_VERSION;
  687.33 +}
  687.34 +
  687.35 +uLong ZEXPORT zlibCompileFlags()
  687.36 +{
  687.37 +    uLong flags;
  687.38 +
  687.39 +    flags = 0;
  687.40 +    switch (sizeof(uInt)) {
  687.41 +    case 2:     break;
  687.42 +    case 4:     flags += 1;     break;
  687.43 +    case 8:     flags += 2;     break;
  687.44 +    default:    flags += 3;
  687.45 +    }
  687.46 +    switch (sizeof(uLong)) {
  687.47 +    case 2:     break;
  687.48 +    case 4:     flags += 1 << 2;        break;
  687.49 +    case 8:     flags += 2 << 2;        break;
  687.50 +    default:    flags += 3 << 2;
  687.51 +    }
  687.52 +    switch (sizeof(voidpf)) {
  687.53 +    case 2:     break;
  687.54 +    case 4:     flags += 1 << 4;        break;
  687.55 +    case 8:     flags += 2 << 4;        break;
  687.56 +    default:    flags += 3 << 4;
  687.57 +    }
  687.58 +    switch (sizeof(z_off_t)) {
  687.59 +    case 2:     break;
  687.60 +    case 4:     flags += 1 << 6;        break;
  687.61 +    case 8:     flags += 2 << 6;        break;
  687.62 +    default:    flags += 3 << 6;
  687.63 +    }
  687.64 +#ifdef DEBUG
  687.65 +    flags += 1 << 8;
  687.66 +#endif
  687.67 +#if defined(ASMV) || defined(ASMINF)
  687.68 +    flags += 1 << 9;
  687.69 +#endif
  687.70 +#ifdef ZLIB_WINAPI
  687.71 +    flags += 1 << 10;
  687.72 +#endif
  687.73 +#ifdef BUILDFIXED
  687.74 +    flags += 1 << 12;
  687.75 +#endif
  687.76 +#ifdef DYNAMIC_CRC_TABLE
  687.77 +    flags += 1 << 13;
  687.78 +#endif
  687.79 +#ifdef NO_GZCOMPRESS
  687.80 +    flags += 1L << 16;
  687.81 +#endif
  687.82 +#ifdef NO_GZIP
  687.83 +    flags += 1L << 17;
  687.84 +#endif
  687.85 +#ifdef PKZIP_BUG_WORKAROUND
  687.86 +    flags += 1L << 20;
  687.87 +#endif
  687.88 +#ifdef FASTEST
  687.89 +    flags += 1L << 21;
  687.90 +#endif
  687.91 +#ifdef STDC
  687.92 +#  ifdef NO_vsnprintf
  687.93 +        flags += 1L << 25;
  687.94 +#    ifdef HAS_vsprintf_void
  687.95 +        flags += 1L << 26;
  687.96 +#    endif
  687.97 +#  else
  687.98 +#    ifdef HAS_vsnprintf_void
  687.99 +        flags += 1L << 26;
 687.100 +#    endif
 687.101 +#  endif
 687.102 +#else
 687.103 +        flags += 1L << 24;
 687.104 +#  ifdef NO_snprintf
 687.105 +        flags += 1L << 25;
 687.106 +#    ifdef HAS_sprintf_void
 687.107 +        flags += 1L << 26;
 687.108 +#    endif
 687.109 +#  else
 687.110 +#    ifdef HAS_snprintf_void
 687.111 +        flags += 1L << 26;
 687.112 +#    endif
 687.113 +#  endif
 687.114 +#endif
 687.115 +    return flags;
 687.116 +}
 687.117 +
 687.118 +#ifdef DEBUG
 687.119 +
 687.120 +#  ifndef verbose
 687.121 +#    define verbose 0
 687.122 +#  endif
 687.123 +int z_verbose = verbose;
 687.124 +
 687.125 +void z_error (m)
 687.126 +    char *m;
 687.127 +{
 687.128 +    fprintf(stderr, "%s\n", m);
 687.129 +    exit(1);
 687.130 +}
 687.131 +#endif
 687.132 +
 687.133 +/* exported to allow conversion of error code to string for compress() and
 687.134 + * uncompress()
 687.135 + */
 687.136 +const char * ZEXPORT zError(err)
 687.137 +    int err;
 687.138 +{
 687.139 +    return ERR_MSG(err);
 687.140 +}
 687.141 +
 687.142 +#if defined(_WIN32_WCE)
 687.143 +    /* The Microsoft C Run-Time Library for Windows CE doesn't have
 687.144 +     * errno.  We define it as a global variable to simplify porting.
 687.145 +     * Its value is always 0 and should not be used.
 687.146 +     */
 687.147 +    int errno = 0;
 687.148 +#endif
 687.149 +
 687.150 +#ifndef HAVE_MEMCPY
 687.151 +
 687.152 +void zmemcpy(dest, source, len)
 687.153 +    Bytef* dest;
 687.154 +    const Bytef* source;
 687.155 +    uInt  len;
 687.156 +{
 687.157 +    if (len == 0) return;
 687.158 +    do {
 687.159 +        *dest++ = *source++; /* ??? to be unrolled */
 687.160 +    } while (--len != 0);
 687.161 +}
 687.162 +
 687.163 +int zmemcmp(s1, s2, len)
 687.164 +    const Bytef* s1;
 687.165 +    const Bytef* s2;
 687.166 +    uInt  len;
 687.167 +{
 687.168 +    uInt j;
 687.169 +
 687.170 +    for (j = 0; j < len; j++) {
 687.171 +        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
 687.172 +    }
 687.173 +    return 0;
 687.174 +}
 687.175 +
 687.176 +void zmemzero(dest, len)
 687.177 +    Bytef* dest;
 687.178 +    uInt  len;
 687.179 +{
 687.180 +    if (len == 0) return;
 687.181 +    do {
 687.182 +        *dest++ = 0;  /* ??? to be unrolled */
 687.183 +    } while (--len != 0);
 687.184 +}
 687.185 +#endif
 687.186 +
 687.187 +
 687.188 +#ifdef SYS16BIT
 687.189 +
 687.190 +#ifdef __TURBOC__
 687.191 +/* Turbo C in 16-bit mode */
 687.192 +
 687.193 +#  define MY_ZCALLOC
 687.194 +
 687.195 +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
 687.196 + * and farmalloc(64K) returns a pointer with an offset of 8, so we
 687.197 + * must fix the pointer. Warning: the pointer must be put back to its
 687.198 + * original form in order to free it, use zcfree().
 687.199 + */
 687.200 +
 687.201 +#define MAX_PTR 10
 687.202 +/* 10*64K = 640K */
 687.203 +
 687.204 +local int next_ptr = 0;
 687.205 +
 687.206 +typedef struct ptr_table_s {
 687.207 +    voidpf org_ptr;
 687.208 +    voidpf new_ptr;
 687.209 +} ptr_table;
 687.210 +
 687.211 +local ptr_table table[MAX_PTR];
 687.212 +/* This table is used to remember the original form of pointers
 687.213 + * to large buffers (64K). Such pointers are normalized with a zero offset.
 687.214 + * Since MSDOS is not a preemptive multitasking OS, this table is not
 687.215 + * protected from concurrent access. This hack doesn't work anyway on
 687.216 + * a protected system like OS/2. Use Microsoft C instead.
 687.217 + */
 687.218 +
 687.219 +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
 687.220 +{
 687.221 +    voidpf buf = opaque; /* just to make some compilers happy */
 687.222 +    ulg bsize = (ulg)items*size;
 687.223 +
 687.224 +    /* If we allocate less than 65520 bytes, we assume that farmalloc
 687.225 +     * will return a usable pointer which doesn't have to be normalized.
 687.226 +     */
 687.227 +    if (bsize < 65520L) {
 687.228 +        buf = farmalloc(bsize);
 687.229 +        if (*(ush*)&buf != 0) return buf;
 687.230 +    } else {
 687.231 +        buf = farmalloc(bsize + 16L);
 687.232 +    }
 687.233 +    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
 687.234 +    table[next_ptr].org_ptr = buf;
 687.235 +
 687.236 +    /* Normalize the pointer to seg:0 */
 687.237 +    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
 687.238 +    *(ush*)&buf = 0;
 687.239 +    table[next_ptr++].new_ptr = buf;
 687.240 +    return buf;
 687.241 +}
 687.242 +
 687.243 +void  zcfree (voidpf opaque, voidpf ptr)
 687.244 +{
 687.245 +    int n;
 687.246 +    if (*(ush*)&ptr != 0) { /* object < 64K */
 687.247 +        farfree(ptr);
 687.248 +        return;
 687.249 +    }
 687.250 +    /* Find the original pointer */
 687.251 +    for (n = 0; n < next_ptr; n++) {
 687.252 +        if (ptr != table[n].new_ptr) continue;
 687.253 +
 687.254 +        farfree(table[n].org_ptr);
 687.255 +        while (++n < next_ptr) {
 687.256 +            table[n-1] = table[n];
 687.257 +        }
 687.258 +        next_ptr--;
 687.259 +        return;
 687.260 +    }
 687.261 +    ptr = opaque; /* just to make some compilers happy */
 687.262 +    Assert(0, "zcfree: ptr not found");
 687.263 +}
 687.264 +
 687.265 +#endif /* __TURBOC__ */
 687.266 +
 687.267 +
 687.268 +#ifdef M_I86
 687.269 +/* Microsoft C in 16-bit mode */
 687.270 +
 687.271 +#  define MY_ZCALLOC
 687.272 +
 687.273 +#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
 687.274 +#  define _halloc  halloc
 687.275 +#  define _hfree   hfree
 687.276 +#endif
 687.277 +
 687.278 +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
 687.279 +{
 687.280 +    if (opaque) opaque = 0; /* to make compiler happy */
 687.281 +    return _halloc((long)items, size);
 687.282 +}
 687.283 +
 687.284 +void  zcfree (voidpf opaque, voidpf ptr)
 687.285 +{
 687.286 +    if (opaque) opaque = 0; /* to make compiler happy */
 687.287 +    _hfree(ptr);
 687.288 +}
 687.289 +
 687.290 +#endif /* M_I86 */
 687.291 +
 687.292 +#endif /* SYS16BIT */
 687.293 +
 687.294 +
 687.295 +#ifndef MY_ZCALLOC /* Any system without a special alloc function */
 687.296 +
 687.297 +#ifndef STDC
 687.298 +extern voidp  malloc OF((uInt size));
 687.299 +extern voidp  calloc OF((uInt items, uInt size));
 687.300 +extern void   free   OF((voidpf ptr));
 687.301 +#endif
 687.302 +
 687.303 +voidpf zcalloc (opaque, items, size)
 687.304 +    voidpf opaque;
 687.305 +    unsigned items;
 687.306 +    unsigned size;
 687.307 +{
 687.308 +    if (opaque) items += size - size; /* make compiler happy */
 687.309 +    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
 687.310 +                              (voidpf)calloc(items, size);
 687.311 +}
 687.312 +
 687.313 +void  zcfree (opaque, ptr)
 687.314 +    voidpf opaque;
 687.315 +    voidpf ptr;
 687.316 +{
 687.317 +    free(ptr);
 687.318 +    if (opaque) return; /* make compiler happy */
 687.319 +}
 687.320 +
 687.321 +#endif /* MY_ZCALLOC */
   688.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   688.2 +++ b/libs/zlib/zutil.h	Sat Feb 01 19:58:19 2014 +0200
   688.3 @@ -0,0 +1,269 @@
   688.4 +/* zutil.h -- internal interface and configuration of the compression library
   688.5 + * Copyright (C) 1995-2005 Jean-loup Gailly.
   688.6 + * For conditions of distribution and use, see copyright notice in zlib.h
   688.7 + */
   688.8 +
   688.9 +/* WARNING: this file should *not* be used by applications. It is
  688.10 +   part of the implementation of the compression library and is
  688.11 +   subject to change. Applications should only use zlib.h.
  688.12 + */
  688.13 +
  688.14 +/* @(#) $Id$ */
  688.15 +
  688.16 +#ifndef ZUTIL_H
  688.17 +#define ZUTIL_H
  688.18 +
  688.19 +#define ZLIB_INTERNAL
  688.20 +#include "zlib.h"
  688.21 +
  688.22 +#ifdef STDC
  688.23 +#  ifndef _WIN32_WCE
  688.24 +#    include <stddef.h>
  688.25 +#  endif
  688.26 +#  include <string.h>
  688.27 +#  include <stdlib.h>
  688.28 +#endif
  688.29 +#ifdef NO_ERRNO_H
  688.30 +#   ifdef _WIN32_WCE
  688.31 +      /* The Microsoft C Run-Time Library for Windows CE doesn't have
  688.32 +       * errno.  We define it as a global variable to simplify porting.
  688.33 +       * Its value is always 0 and should not be used.  We rename it to
  688.34 +       * avoid conflict with other libraries that use the same workaround.
  688.35 +       */
  688.36 +#     define errno z_errno
  688.37 +#   endif
  688.38 +    extern int errno;
  688.39 +#else
  688.40 +#  ifndef _WIN32_WCE
  688.41 +#    include <errno.h>
  688.42 +#  endif
  688.43 +#endif
  688.44 +
  688.45 +#ifndef local
  688.46 +#  define local static
  688.47 +#endif
  688.48 +/* compile with -Dlocal if your debugger can't find static symbols */
  688.49 +
  688.50 +typedef unsigned char  uch;
  688.51 +typedef uch FAR uchf;
  688.52 +typedef unsigned short ush;
  688.53 +typedef ush FAR ushf;
  688.54 +typedef unsigned long  ulg;
  688.55 +
  688.56 +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
  688.57 +/* (size given to avoid silly warnings with Visual C++) */
  688.58 +
  688.59 +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
  688.60 +
  688.61 +#define ERR_RETURN(strm,err) \
  688.62 +  return (strm->msg = (char*)ERR_MSG(err), (err))
  688.63 +/* To be used only when the state is known to be valid */
  688.64 +
  688.65 +        /* common constants */
  688.66 +
  688.67 +#ifndef DEF_WBITS
  688.68 +#  define DEF_WBITS MAX_WBITS
  688.69 +#endif
  688.70 +/* default windowBits for decompression. MAX_WBITS is for compression only */
  688.71 +
  688.72 +#if MAX_MEM_LEVEL >= 8
  688.73 +#  define DEF_MEM_LEVEL 8
  688.74 +#else
  688.75 +#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
  688.76 +#endif
  688.77 +/* default memLevel */
  688.78 +
  688.79 +#define STORED_BLOCK 0
  688.80 +#define STATIC_TREES 1
  688.81 +#define DYN_TREES    2
  688.82 +/* The three kinds of block type */
  688.83 +
  688.84 +#define MIN_MATCH  3
  688.85 +#define MAX_MATCH  258
  688.86 +/* The minimum and maximum match lengths */
  688.87 +
  688.88 +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
  688.89 +
  688.90 +        /* target dependencies */
  688.91 +
  688.92 +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
  688.93 +#  define OS_CODE  0x00
  688.94 +#  if defined(__TURBOC__) || defined(__BORLANDC__)
  688.95 +#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
  688.96 +       /* Allow compilation with ANSI keywords only enabled */
  688.97 +       void _Cdecl farfree( void *block );
  688.98 +       void *_Cdecl farmalloc( unsigned long nbytes );
  688.99 +#    else
 688.100 +#      include <alloc.h>
 688.101 +#    endif
 688.102 +#  else /* MSC or DJGPP */
 688.103 +#    include <malloc.h>
 688.104 +#  endif
 688.105 +#endif
 688.106 +
 688.107 +#ifdef AMIGA
 688.108 +#  define OS_CODE  0x01
 688.109 +#endif
 688.110 +
 688.111 +#if defined(VAXC) || defined(VMS)
 688.112 +#  define OS_CODE  0x02
 688.113 +#  define F_OPEN(name, mode) \
 688.114 +     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
 688.115 +#endif
 688.116 +
 688.117 +#if defined(ATARI) || defined(atarist)
 688.118 +#  define OS_CODE  0x05
 688.119 +#endif
 688.120 +
 688.121 +#ifdef OS2
 688.122 +#  define OS_CODE  0x06
 688.123 +#  ifdef M_I86
 688.124 +     #include <malloc.h>
 688.125 +#  endif
 688.126 +#endif
 688.127 +
 688.128 +#if defined(MACOS) || defined(TARGET_OS_MAC)
 688.129 +#  define OS_CODE  0x07
 688.130 +#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
 688.131 +#    include <unix.h> /* for fdopen */
 688.132 +#  else
 688.133 +#    ifndef fdopen
 688.134 +#      define fdopen(fd,mode) NULL /* No fdopen() */
 688.135 +#    endif
 688.136 +#  endif
 688.137 +#endif
 688.138 +
 688.139 +#ifdef TOPS20
 688.140 +#  define OS_CODE  0x0a
 688.141 +#endif
 688.142 +
 688.143 +#ifdef WIN32
 688.144 +#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */
 688.145 +#    define OS_CODE  0x0b
 688.146 +#  endif
 688.147 +#endif
 688.148 +
 688.149 +#ifdef __50SERIES /* Prime/PRIMOS */
 688.150 +#  define OS_CODE  0x0f
 688.151 +#endif
 688.152 +
 688.153 +#if defined(_BEOS_) || defined(RISCOS)
 688.154 +#  define fdopen(fd,mode) NULL /* No fdopen() */
 688.155 +#endif
 688.156 +
 688.157 +#if (defined(_MSC_VER) && (_MSC_VER > 600))
 688.158 +#  if defined(_WIN32_WCE)
 688.159 +#    define fdopen(fd,mode) NULL /* No fdopen() */
 688.160 +#    ifndef _PTRDIFF_T_DEFINED
 688.161 +       typedef int ptrdiff_t;
 688.162 +#      define _PTRDIFF_T_DEFINED
 688.163 +#    endif
 688.164 +#  else
 688.165 +#    define fdopen(fd,type)  _fdopen(fd,type)
 688.166 +#  endif
 688.167 +#endif
 688.168 +
 688.169 +        /* common defaults */
 688.170 +
 688.171 +#ifndef OS_CODE
 688.172 +#  define OS_CODE  0x03  /* assume Unix */
 688.173 +#endif
 688.174 +
 688.175 +#ifndef F_OPEN
 688.176 +#  define F_OPEN(name, mode) fopen((name), (mode))
 688.177 +#endif
 688.178 +
 688.179 +         /* functions */
 688.180 +
 688.181 +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
 688.182 +#  ifndef HAVE_VSNPRINTF
 688.183 +#    define HAVE_VSNPRINTF
 688.184 +#  endif
 688.185 +#endif
 688.186 +#if defined(__CYGWIN__)
 688.187 +#  ifndef HAVE_VSNPRINTF
 688.188 +#    define HAVE_VSNPRINTF
 688.189 +#  endif
 688.190 +#endif
 688.191 +#ifndef HAVE_VSNPRINTF
 688.192 +#  ifdef MSDOS
 688.193 +     /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
 688.194 +        but for now we just assume it doesn't. */
 688.195 +#    define NO_vsnprintf
 688.196 +#  endif
 688.197 +#  ifdef __TURBOC__
 688.198 +#    define NO_vsnprintf
 688.199 +#  endif
 688.200 +#  ifdef WIN32
 688.201 +     /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
 688.202 +#    if !defined(vsnprintf) && !defined(NO_vsnprintf)
 688.203 +#      define vsnprintf _vsnprintf
 688.204 +#    endif
 688.205 +#  endif
 688.206 +#  ifdef __SASC
 688.207 +#    define NO_vsnprintf
 688.208 +#  endif
 688.209 +#endif
 688.210 +#ifdef VMS
 688.211 +#  define NO_vsnprintf
 688.212 +#endif
 688.213 +
 688.214 +#if defined(pyr)
 688.215 +#  define NO_MEMCPY
 688.216 +#endif
 688.217 +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
 688.218 + /* Use our own functions for small and medium model with MSC <= 5.0.
 688.219 +  * You may have to use the same strategy for Borland C (untested).
 688.220 +  * The __SC__ check is for Symantec.
 688.221 +  */
 688.222 +#  define NO_MEMCPY
 688.223 +#endif
 688.224 +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
 688.225 +#  define HAVE_MEMCPY
 688.226 +#endif
 688.227 +#ifdef HAVE_MEMCPY
 688.228 +#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
 688.229 +#    define zmemcpy _fmemcpy
 688.230 +#    define zmemcmp _fmemcmp
 688.231 +#    define zmemzero(dest, len) _fmemset(dest, 0, len)
 688.232 +#  else
 688.233 +#    define zmemcpy memcpy
 688.234 +#    define zmemcmp memcmp
 688.235 +#    define zmemzero(dest, len) memset(dest, 0, len)
 688.236 +#  endif
 688.237 +#else
 688.238 +   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
 688.239 +   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
 688.240 +   extern void zmemzero OF((Bytef* dest, uInt len));
 688.241 +#endif
 688.242 +
 688.243 +/* Diagnostic functions */
 688.244 +#ifdef DEBUG
 688.245 +#  include <stdio.h>
 688.246 +   extern int z_verbose;
 688.247 +   extern void z_error    OF((char *m));
 688.248 +#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
 688.249 +#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
 688.250 +#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
 688.251 +#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
 688.252 +#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
 688.253 +#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
 688.254 +#else
 688.255 +#  define Assert(cond,msg)
 688.256 +#  define Trace(x)
 688.257 +#  define Tracev(x)
 688.258 +#  define Tracevv(x)
 688.259 +#  define Tracec(c,x)
 688.260 +#  define Tracecv(c,x)
 688.261 +#endif
 688.262 +
 688.263 +
 688.264 +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
 688.265 +void   zcfree  OF((voidpf opaque, voidpf ptr));
 688.266 +
 688.267 +#define ZALLOC(strm, items, size) \
 688.268 +           (*((strm)->zalloc))((strm)->opaque, (items), (size))
 688.269 +#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
 688.270 +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
 688.271 +
 688.272 +#endif /* ZUTIL_H */
   689.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   689.2 +++ b/sdr/color.p.glsl	Sat Feb 01 19:58:19 2014 +0200
   689.3 @@ -0,0 +1,6 @@
   689.4 +uniform vec4 st_color;
   689.5 +
   689.6 +void main()
   689.7 +{
   689.8 +	gl_FragColor = st_color;
   689.9 +}
   690.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   690.2 +++ b/sdr/color.v.glsl	Sat Feb 01 19:58:19 2014 +0200
   690.3 @@ -0,0 +1,8 @@
   690.4 +attribute vec4 attr_vertex;
   690.5 +
   690.6 +uniform mat4 st_world_matrix, st_view_matrix, st_proj_matrix;
   690.7 +
   690.8 +void main()
   690.9 +{
  690.10 +	gl_Position = (st_proj_matrix * st_view_matrix * st_world_matrix) * attr_vertex;
  690.11 +}
   691.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   691.2 +++ b/sdr/default.p.glsl	Sat Feb 01 19:58:19 2014 +0200
   691.3 @@ -0,0 +1,28 @@
   691.4 +varying vec3 vpos, norm;
   691.5 +varying vec2 texcoord;
   691.6 +
   691.7 +void main()
   691.8 +{
   691.9 +	vec3 n = normalize(norm);
  691.10 +	vec3 ldir = normalize(vec3(-0.5, 0.5, 2));
  691.11 +
  691.12 +	float ndotl = max(dot(n, ldir), 0.0);
  691.13 +
  691.14 +	vec3 color = vec3(0.8, 0.8, 0.8) * ndotl;
  691.15 +
  691.16 +	float hpat = smoothstep(0.49, 0.5, mod(texcoord.x * 8.0, 1.0));
  691.17 +	float vpat = smoothstep(0.49, 0.5, mod(texcoord.y * 8.0, 1.0));
  691.18 +
  691.19 +	float pattern = 0.0;
  691.20 +	if((hpat > 0.5 && vpat > 0.5) || (hpat < 0.5 && vpat < 0.5)) {
  691.21 +		pattern = 1.0;
  691.22 +	} else {
  691.23 +		pattern = 0.0;
  691.24 +	}
  691.25 +
  691.26 +	vec3 tex = vec3(pattern * 0.5 + 0.5);
  691.27 +
  691.28 +
  691.29 +	gl_FragColor.rgb = color * tex;
  691.30 +	gl_FragColor.a = 1.0;
  691.31 +}
   692.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   692.2 +++ b/sdr/default.v.glsl	Sat Feb 01 19:58:19 2014 +0200
   692.3 @@ -0,0 +1,21 @@
   692.4 +attribute vec4 attr_vertex;
   692.5 +attribute vec3 attr_normal;
   692.6 +attribute vec2 attr_texcoord;
   692.7 +
   692.8 +uniform mat4 st_world_matrix, st_view_matrix, st_proj_matrix;
   692.9 +uniform mat3 st_world_matrix3, st_view_matrix3;
  692.10 +
  692.11 +varying vec3 vpos, norm;
  692.12 +varying vec2 texcoord;
  692.13 +
  692.14 +void main()
  692.15 +{
  692.16 +	mat4 worldview_matrix = st_view_matrix * st_world_matrix;
  692.17 +	mat4 mvp_matrix = st_proj_matrix * worldview_matrix;
  692.18 +
  692.19 +	gl_Position = mvp_matrix * attr_vertex;
  692.20 +
  692.21 +	vpos = (worldview_matrix * attr_vertex).xyz;
  692.22 +	norm = st_view_matrix3 * st_world_matrix3 * attr_normal;
  692.23 +	texcoord = attr_texcoord;
  692.24 +}
   693.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   693.2 +++ b/sdr/font.p.glsl	Sat Feb 01 19:58:19 2014 +0200
   693.3 @@ -0,0 +1,10 @@
   693.4 +uniform sampler2D tex;
   693.5 +uniform vec4 st_color;
   693.6 +
   693.7 +varying vec2 texcoord;
   693.8 +
   693.9 +void main()
  693.10 +{
  693.11 +	gl_FragColor.rgb = st_color.rgb;
  693.12 +	gl_FragColor.a = texture2D(tex, texcoord).a * st_color.a;
  693.13 +}
   694.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   694.2 +++ b/sdr/font.v.glsl	Sat Feb 01 19:58:19 2014 +0200
   694.3 @@ -0,0 +1,15 @@
   694.4 +uniform vec2 st_fbsize;
   694.5 +uniform mat4 st_world_matrix;
   694.6 +
   694.7 +attribute vec4 attr_vertex, attr_texcoord;
   694.8 +
   694.9 +varying vec2 texcoord;
  694.10 +
  694.11 +void main()
  694.12 +{
  694.13 +	vec4 pos = st_world_matrix * attr_vertex;
  694.14 +	pos.xy = (pos.xy / st_fbsize - 0.5) * 2.0;
  694.15 +
  694.16 +	gl_Position = pos;
  694.17 +	texcoord = attr_texcoord.st;
  694.18 +}
   695.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   695.2 +++ b/src/assload.cc	Sat Feb 01 19:58:19 2014 +0200
   695.3 @@ -0,0 +1,437 @@
   695.4 +#include <stdio.h>
   695.5 +#include "assload.h"
   695.6 +#include "logger.h"
   695.7 +#include "datapath.h"
   695.8 +
   695.9 +#ifdef USE_ASSIMP
  695.10 +
  695.11 +#include <vector>
  695.12 +#include <map>
  695.13 +#include "assimp/cimport.h"
  695.14 +#include "assimp/scene.h"
  695.15 +#include "assimp/postprocess.h"
  695.16 +#include "texman.h"
  695.17 +#include "material.h"
  695.18 +
  695.19 +using namespace std;
  695.20 +
  695.21 +static bool load_material(Material *mat, const aiMaterial *aimat);
  695.22 +static Object *load_node(const aiScene *aiscn, const aiNode *ainode);
  695.23 +static Mesh *load_mesh(const aiScene *aiscn, const aiMesh *aimesh);
  695.24 +static Curve *load_curve(const aiScene *aiscn, const aiMesh *aimesh);
  695.25 +static bool load_bones(Mesh *mesh, const aiMesh *aimesh);
  695.26 +
  695.27 +static Vector3 assimp_vector(const aiVector3D &v);
  695.28 +static Quaternion assimp_quat(const aiQuaternion &q);
  695.29 +static Matrix4x4 assimp_matrix(const aiMatrix4x4 &aim);
  695.30 +static long assimp_time(const aiAnimation *anim, double aitime);
  695.31 +static void print_hierarchy(const aiNode *node);
  695.32 +
  695.33 +static map<string, Object*> obj_by_name;
  695.34 +static map<aiMesh*, Mesh*> mesh_by_aimesh;
  695.35 +
  695.36 +bool load_ass(Scene *scn, const char *fname)
  695.37 +{
  695.38 +	static bool init_done;
  695.39 +
  695.40 +	if(!init_done) {
  695.41 +		static aiLogStream log_stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, 0);
  695.42 +		aiAttachLogStream(&log_stream);
  695.43 +		//aiEnableVerboseLogging(1);
  695.44 +		init_done = true;
  695.45 +	}
  695.46 +
  695.47 +	unsigned int proc_flags = aiProcess_JoinIdenticalVertices |
  695.48 +		aiProcess_CalcTangentSpace |
  695.49 +		aiProcess_Triangulate |
  695.50 +		aiProcess_SortByPType |
  695.51 +		aiProcess_FlipUVs;
  695.52 +
  695.53 +	const aiScene *aiscn = aiImportFile(datafile_path(fname).c_str(), proc_flags);
  695.54 +	if(!aiscn) {
  695.55 +		error_log("failed to load file: %s\n", fname);
  695.56 +		return false;
  695.57 +	}
  695.58 +
  695.59 +	info_log("NODE HIERARCHY:\n");
  695.60 +	print_hierarchy(aiscn->mRootNode);
  695.61 +	info_log("-------------------\n");
  695.62 +
  695.63 +	Vector3 root_pos, root_scaling(1.0, 1.0, 1.0);
  695.64 +	Quaternion root_rot;
  695.65 +
  695.66 +	if(aiscn->mRootNode) {
  695.67 +		Matrix4x4 root_matrix = assimp_matrix(aiscn->mRootNode->mTransformation);
  695.68 +		root_pos = root_matrix.get_translation();
  695.69 +		root_rot = root_matrix.get_rotation_quat();
  695.70 +		root_scaling = root_matrix.get_scaling();
  695.71 +	}
  695.72 +
  695.73 +	// load all meshes
  695.74 +	for(unsigned int i=0; i<aiscn->mNumMeshes; i++) {
  695.75 +		aiMesh *aimesh = aiscn->mMeshes[i];
  695.76 +		Mesh *mesh;
  695.77 +		Curve *curve;
  695.78 +
  695.79 +		switch(aimesh->mPrimitiveTypes) {
  695.80 +		case aiPrimitiveType_TRIANGLE:
  695.81 +			if((mesh = load_mesh(aiscn, aimesh))) {
  695.82 +				mesh_by_aimesh[aimesh] = mesh;
  695.83 +				scn->meshes.push_back(mesh);
  695.84 +			}
  695.85 +			break;
  695.86 +
  695.87 +		case aiPrimitiveType_LINE:
  695.88 +			if((curve = load_curve(aiscn, aimesh))) {
  695.89 +				scn->curves.push_back(curve);
  695.90 +			}
  695.91 +			break;
  695.92 +
  695.93 +		default:
  695.94 +			error_log("unsupported primitive type: %u\n", aimesh->mPrimitiveTypes);
  695.95 +			break;
  695.96 +		}
  695.97 +	}
  695.98 +
  695.99 +	// load all the nodes recursively
 695.100 +	for(unsigned int i=0; i<aiscn->mRootNode->mNumChildren; i++) {
 695.101 +		Object *obj = load_node(aiscn, aiscn->mRootNode->mChildren[i]);
 695.102 +		if(obj) {
 695.103 +			Object *dummy = new Object;
 695.104 +			dummy->set_name((string("dummyroot_") + string(obj->get_name())).c_str());
 695.105 +			dummy->set_position(root_pos);
 695.106 +			dummy->set_rotation(root_rot);
 695.107 +			dummy->set_scaling(root_scaling);
 695.108 +			dummy->add_child(obj);
 695.109 +
 695.110 +			obj = dummy;
 695.111 +			scn->objects.push_back(obj);
 695.112 +		}
 695.113 +	}
 695.114 +
 695.115 +	// load and attach the bones to the meshes
 695.116 +	for(unsigned int i=0; i<aiscn->mNumMeshes; i++) {
 695.117 +		aiMesh *aimesh = aiscn->mMeshes[i];
 695.118 +
 695.119 +		Mesh *mesh = mesh_by_aimesh[aimesh];
 695.120 +		load_bones(mesh, aimesh);
 695.121 +	}
 695.122 +
 695.123 +	obj_by_name.clear();
 695.124 +	mesh_by_aimesh.clear();
 695.125 +
 695.126 +	aiReleaseImport(aiscn);
 695.127 +	return true;
 695.128 +}
 695.129 +
 695.130 +static bool load_material(Material *mat, const aiMaterial *aimat)
 695.131 +{
 695.132 +	aiColor4D aicol;
 695.133 +	float shin, shin_str;
 695.134 +
 695.135 +	if(aiGetMaterialColor(aimat, AI_MATKEY_COLOR_DIFFUSE, &aicol) == 0) {
 695.136 +		mat->diffuse = Vector3(aicol[0], aicol[1], aicol[2]);
 695.137 +	}
 695.138 +	if(aiGetMaterialColor(aimat, AI_MATKEY_COLOR_SPECULAR, &aicol) == 0) {
 695.139 +		mat->specular = Vector3(aicol[0], aicol[1], aicol[2]);
 695.140 +	}
 695.141 +
 695.142 +	unsigned int count = 1;
 695.143 +	if(aiGetMaterialFloatArray(aimat, AI_MATKEY_SHININESS_STRENGTH, &shin_str, &count) != 0) {
 695.144 +		shin_str = 1.0;
 695.145 +	}
 695.146 +	if(aiGetMaterialFloatArray(aimat, AI_MATKEY_SHININESS, &shin, &count) == 0) {
 695.147 +		// XXX can't remember how I came up with this...
 695.148 +		mat->shininess = shin * shin_str * 0.0001 * 128.0;
 695.149 +	}
 695.150 +
 695.151 +	// load textures
 695.152 +	struct { int type; aiTextureType aitype; } textypes[] = {
 695.153 +		{TEX_DIFFUSE, aiTextureType_DIFFUSE},
 695.154 +		{TEX_NORMAL, aiTextureType_NORMALS},
 695.155 +		{TEX_SPECULAR, aiTextureType_SPECULAR}
 695.156 +	};
 695.157 +
 695.158 +	for(int i=0; i<sizeof textypes / sizeof *textypes; i++) {
 695.159 +		aiString aipath;
 695.160 +
 695.161 +		if(aiGetMaterialTexture(aimat, textypes[i].aitype, 0, &aipath) == 0) {
 695.162 +			char *tmp, *fname = aipath.data;
 695.163 +
 695.164 +			if((tmp = strrchr(fname, '/'))) {
 695.165 +				fname = tmp + 1;
 695.166 +			}
 695.167 +			if((tmp = strrchr(fname, '\\'))) {
 695.168 +				fname = tmp + 1;
 695.169 +			}
 695.170 +
 695.171 +			if(*fname) {
 695.172 +				mat->tex[textypes[i].type] = texset.get(fname);
 695.173 +			}
 695.174 +		}
 695.175 +	}
 695.176 +
 695.177 +	return true;
 695.178 +}
 695.179 +
 695.180 +static Object *load_node(const aiScene *aiscn, const aiNode *ainode)
 695.181 +{
 695.182 +	Object *obj = new Object;
 695.183 +	obj->set_name(ainode->mName.data);
 695.184 +
 695.185 +	if(ainode->mNumMeshes) {
 695.186 +		if(ainode->mNumMeshes > 1) {
 695.187 +			info_log("%s warning: node %s has more than one meshes (%u)\n", __FUNCTION__,
 695.188 +					ainode->mName.data, ainode->mNumMeshes);
 695.189 +		}
 695.190 +
 695.191 +		aiMesh *aimesh = aiscn->mMeshes[ainode->mMeshes[0]];
 695.192 +		obj->set_mesh(mesh_by_aimesh[aimesh]);
 695.193 +
 695.194 +		// also grab the material of this mesh
 695.195 +		load_material(&obj->material, aiscn->mMaterials[aimesh->mMaterialIndex]);
 695.196 +	}
 695.197 +
 695.198 +	// if there are animations, grab the first and try to use it
 695.199 +	if(aiscn->mNumAnimations) {
 695.200 +		aiAnimation *aianim = aiscn->mAnimations[0];
 695.201 +		aiNodeAnim *ainodeanim = 0;
 695.202 +		for(unsigned int i=0; i<aianim->mNumChannels; i++) {
 695.203 +			if(strcmp(aianim->mChannels[i]->mNodeName.data, ainode->mName.data) == 0) {
 695.204 +				ainodeanim = aianim->mChannels[i];
 695.205 +				break;
 695.206 +			}
 695.207 +		}
 695.208 +
 695.209 +		if(ainodeanim) {
 695.210 +			// load all position (translation) keyframes
 695.211 +			for(unsigned int i=0; i<ainodeanim->mNumPositionKeys; i++) {
 695.212 +				Vector3 pos = assimp_vector(ainodeanim->mPositionKeys[i].mValue);
 695.213 +				long msec = assimp_time(aianim, ainodeanim->mPositionKeys[i].mTime);
 695.214 +				obj->set_position(pos, msec);
 695.215 +			}
 695.216 +
 695.217 +			// load all rotation keyframes
 695.218 +			for(unsigned int i=0; i<ainodeanim->mNumRotationKeys; i++) {
 695.219 +				Quaternion rot = assimp_quat(ainodeanim->mRotationKeys[i].mValue);
 695.220 +				if(rot.length_sq() < SMALL_NUMBER) {
 695.221 +					continue;
 695.222 +				}
 695.223 +				rot.normalize();
 695.224 +				long msec = assimp_time(aianim, ainodeanim->mRotationKeys[i].mTime);
 695.225 +				obj->set_rotation(rot, msec);
 695.226 +			}
 695.227 +
 695.228 +			// load all scaling keyframes
 695.229 +			for(unsigned int i=0; i<ainodeanim->mNumScalingKeys; i++) {
 695.230 +				Vector3 scale = assimp_vector(ainodeanim->mScalingKeys[i].mValue);
 695.231 +				long msec = assimp_time(aianim, ainodeanim->mScalingKeys[i].mTime);
 695.232 +				obj->set_scaling(scale, msec);
 695.233 +			}
 695.234 +
 695.235 +			obj->set_extrapolator(EXTRAP_REPEAT);	// loop animation
 695.236 +		} else {
 695.237 +			Matrix4x4 local_matrix = assimp_matrix(ainode->mTransformation);
 695.238 +			obj->set_local_matrix(local_matrix);
 695.239 +		}
 695.240 +	}
 695.241 +
 695.242 +	/* recurse to all children */
 695.243 +	for(unsigned int i=0; i<ainode->mNumChildren; i++) {
 695.244 +		Object *child = load_node(aiscn, ainode->mChildren[i]);
 695.245 +		if(child) {
 695.246 +			obj->add_child(child);
 695.247 +		}
 695.248 +	}
 695.249 +
 695.250 +	obj_by_name[obj->get_name()] = obj;
 695.251 +	return obj;
 695.252 +}
 695.253 +
 695.254 +static Mesh *load_mesh(const aiScene *aiscn, const aiMesh *aimesh)
 695.255 +{
 695.256 +	Mesh *mesh = new Mesh;
 695.257 +
 695.258 +	int num_verts = aimesh->mNumVertices;
 695.259 +	int num_faces = aimesh->mNumFaces;
 695.260 +
 695.261 +	mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, (float*)aimesh->mVertices);
 695.262 +
 695.263 +	if(aimesh->mNormals) {
 695.264 +		mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, (float*)aimesh->mNormals);
 695.265 +	}
 695.266 +	if(aimesh->mTangents) {
 695.267 +		mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, (float*)aimesh->mTangents);
 695.268 +	}
 695.269 +	if(aimesh->mTextureCoords[0]) {
 695.270 +		mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 3, num_verts, (float*)aimesh->mTextureCoords[0]);
 695.271 +	}
 695.272 +
 695.273 +	if(aimesh->mBones) {
 695.274 +		float *weights = mesh->set_attrib_data(MESH_ATTR_BONEWEIGHTS, 4, num_verts, 0);
 695.275 +		float *boneidx = mesh->set_attrib_data(MESH_ATTR_BONEIDX, 4, num_verts, 0);
 695.276 +
 695.277 +		memset(weights, 0, num_verts * 4 * sizeof *weights);
 695.278 +		memset(boneidx, 0, num_verts * 4 * sizeof *boneidx);
 695.279 +
 695.280 +		int *vertex_bone_count = new int[num_verts];
 695.281 +		memset(vertex_bone_count, 0, num_verts * sizeof *vertex_bone_count);
 695.282 +
 695.283 +		for(unsigned int i=0; i<aimesh->mNumBones; i++) {
 695.284 +			aiBone *aibone = aimesh->mBones[i];
 695.285 +
 695.286 +			// for every vertex affected by this bone:
 695.287 +			for(unsigned int j=0; j<aibone->mNumWeights; j++) {
 695.288 +				aiVertexWeight *aiweight = aibone->mWeights + j;
 695.289 +				int vidx = aiweight->mVertexId;
 695.290 +				int vert_boneidx = vertex_bone_count[vidx];
 695.291 +				if(vert_boneidx >= 4) {
 695.292 +					error_log("WARNING vertex with more than 4 bones found\n");
 695.293 +					continue;
 695.294 +				}
 695.295 +
 695.296 +				weights[vidx * 4 + vert_boneidx] = aiweight->mWeight;
 695.297 +				boneidx[vidx * 4 + vert_boneidx] = (float)i;
 695.298 +				vertex_bone_count[vidx]++;
 695.299 +			}
 695.300 +		}
 695.301 +
 695.302 +		delete [] vertex_bone_count;
 695.303 +
 695.304 +		// normalize weights
 695.305 +		for(int i=0; i<num_verts; i++) {
 695.306 +
 695.307 +			float wsum = 0.0f;
 695.308 +
 695.309 +			for(int j=0; j<4; j++) {
 695.310 +				wsum += weights[i * 4 + j];
 695.311 +			}
 695.312 +
 695.313 +			if(1.0 - wsum > 1e-4) {
 695.314 +				error_log("WARNING vertex with weights < 1 (%f), normalizing...\n", wsum);
 695.315 +
 695.316 +				if(wsum < 1e-6) {
 695.317 +					// this is clearly broken, let's use the first bone in full
 695.318 +					weights[i * 4] = 1.0;
 695.319 +				} else {
 695.320 +					weights[i * 4] /= wsum;
 695.321 +					weights[i * 4 + 1] /= wsum;
 695.322 +					weights[i * 4 + 2] /= wsum;
 695.323 +					weights[i * 4 + 3] /= wsum;
 695.324 +				}
 695.325 +			}
 695.326 +		}
 695.327 +	}
 695.328 +
 695.329 +	unsigned int *iptr = mesh->set_index_data(num_faces * 3);
 695.330 +	for(int i=0; i<num_faces; i++) {
 695.331 +		for(int j=0; j<3; j++) {
 695.332 +			*iptr++ = aimesh->mFaces[i].mIndices[j];
 695.333 +		}
 695.334 +	}
 695.335 +
 695.336 +	return mesh;
 695.337 +}
 695.338 +
 695.339 +static Curve *load_curve(const aiScene *aiscn, const aiMesh *aimesh)
 695.340 +{
 695.341 +	Curve *curve = new Curve;
 695.342 +
 695.343 +	for(unsigned int i=0; i<aimesh->mNumVertices; i++) {
 695.344 +		Vector3 pt = assimp_vector(aimesh->mVertices[i]);
 695.345 +		curve->add_point(pt);
 695.346 +	}
 695.347 +	info_log("loaded curve with %d points\n", aimesh->mNumVertices);
 695.348 +
 695.349 +	return curve;
 695.350 +}
 695.351 +
 695.352 +static bool load_bones(Mesh *mesh, const aiMesh *aimesh)
 695.353 +{
 695.354 +	if(!aimesh->mNumBones) {
 695.355 +		return false;
 695.356 +	}
 695.357 +
 695.358 +	for(unsigned int i=0; i<aimesh->mNumBones; i++) {
 695.359 +		aiBone *aibone = aimesh->mBones[i];
 695.360 +		Object *obj = obj_by_name[aibone->mName.data];
 695.361 +		if(!obj) {
 695.362 +			error_log("bone %s not found\n", aibone->mName.data);
 695.363 +			continue;
 695.364 +		}
 695.365 +
 695.366 +		obj->set_bone_matrix(assimp_matrix(aibone->mOffsetMatrix));
 695.367 +		mesh->add_bone(obj);
 695.368 +
 695.369 +		info_log("adding bone: %s\n", obj->get_name());
 695.370 +	}
 695.371 +
 695.372 +	return true;
 695.373 +}
 695.374 +
 695.375 +static Vector3 assimp_vector(const aiVector3D &v)
 695.376 +{
 695.377 +	return Vector3(v[0], v[1], v[2]);
 695.378 +}
 695.379 +
 695.380 +static Quaternion assimp_quat(const aiQuaternion &q)
 695.381 +{
 695.382 +	return Quaternion(q.w, Vector3(q.x, q.y, q.z));
 695.383 +}
 695.384 +
 695.385 +static Matrix4x4 assimp_matrix(const aiMatrix4x4 &aim)
 695.386 +{
 695.387 +	Matrix4x4 m;
 695.388 +	memcpy(m[0], &aim, 16 * sizeof(float));
 695.389 +	return m;
 695.390 +}
 695.391 +
 695.392 +/* convert an assimp keyframe time (ticks) into milliseconds */
 695.393 +static long assimp_time(const aiAnimation *anim, double aitime)
 695.394 +{
 695.395 +	double sec;
 695.396 +	if(anim->mTicksPerSecond < 1e-6) {
 695.397 +		// assume time is in frames?
 695.398 +		sec = aitime / 30.0;
 695.399 +	} else {
 695.400 +		sec = aitime / anim->mTicksPerSecond;
 695.401 +	}
 695.402 +	return (long)(sec * 1000.0);
 695.403 +}
 695.404 +
 695.405 +static void print_hierarchy(const aiNode *node)
 695.406 +{
 695.407 +	static int lvl;
 695.408 +	static int lvlopen[256];
 695.409 +
 695.410 +	for(int i=0; i<lvl; i++) {
 695.411 +		putchar(' ');
 695.412 +		if(lvlopen[i]) {
 695.413 +			putchar(i >= lvl - 1 ? '+' : '|');
 695.414 +		} else {
 695.415 +			putchar(i >= lvl - 1 ? '+' : ' ');
 695.416 +		}
 695.417 +	}
 695.418 +	info_log("- \"%s\"\n", node->mName.data);
 695.419 +
 695.420 +	lvlopen[lvl] = 1;
 695.421 +
 695.422 +	lvl++;
 695.423 +	for(unsigned int i=0; i<node->mNumChildren; i++) {
 695.424 +		if(i == node->mNumChildren - 1) {
 695.425 +			lvlopen[lvl - 1] = 0;
 695.426 +		}
 695.427 +		print_hierarchy(node->mChildren[i]);
 695.428 +	}
 695.429 +	lvl--;
 695.430 +}
 695.431 +
 695.432 +#else	// !defined USE_ASSIMP
 695.433 +
 695.434 +bool load_ass(Scene *scn, const char *fname)
 695.435 +{
 695.436 +	error_log("load_ass: assimp support not compiled in\n");
 695.437 +	return false;
 695.438 +}
 695.439 +
 695.440 +#endif
   696.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   696.2 +++ b/src/assload.h	Sat Feb 01 19:58:19 2014 +0200
   696.3 @@ -0,0 +1,9 @@
   696.4 +#ifndef ASSLOAD_H_
   696.5 +#define ASSLOAD_H_
   696.6 +
   696.7 +#include <vector>
   696.8 +#include "scene.h"
   696.9 +
  696.10 +bool load_ass(Scene *scn, const char *fname);
  696.11 +
  696.12 +#endif	// ASSLOAD_H_
   697.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   697.2 +++ b/src/audio/audio.cc	Sat Feb 01 19:58:19 2014 +0200
   697.3 @@ -0,0 +1,70 @@
   697.4 +#include <stdio.h>
   697.5 +
   697.6 +#include "openal.h"
   697.7 +#include "audio.h"
   697.8 +
   697.9 +static ALCdevice *dev;
  697.10 +static ALCcontext *ctx;
  697.11 +
  697.12 +bool init_audio()
  697.13 +{
  697.14 +	if (dev) {
  697.15 +		// Already initiated.
  697.16 +		return true;
  697.17 +	}
  697.18 +	else if (!(dev = alcOpenDevice(0))) {
  697.19 +		fprintf(stderr, "failed to open OpenAL device\n");
  697.20 +		return false;
  697.21 +	}
  697.22 +
  697.23 +	if (ctx)
  697.24 +	{
  697.25 +		return true;
  697.26 +	}
  697.27 +	else if (!(ctx = alcCreateContext(dev, 0)))
  697.28 +	{
  697.29 +		fprintf(stderr, "failed to create context\n");
  697.30 +		alcCloseDevice(dev);
  697.31 +		return false;
  697.32 +	}
  697.33 +
  697.34 +	alcMakeContextCurrent(ctx);
  697.35 +
  697.36 +	// Clear error state.
  697.37 +	alGetError();
  697.38 +
  697.39 +	return true;
  697.40 +}
  697.41 +
  697.42 +void destroy_audio()
  697.43 +{
  697.44 +	alcMakeContextCurrent(0);
  697.45 +
  697.46 +	if (ctx) {
  697.47 +		alcDestroyContext(ctx);
  697.48 +	}
  697.49 +
  697.50 +	if (dev) {
  697.51 +		alcCloseDevice(dev);
  697.52 +	}
  697.53 +}
  697.54 +
  697.55 +void set_audio_listener(const Matrix4x4 &xform)
  697.56 +{
  697.57 +	float pos[3], orient[6];
  697.58 +
  697.59 +	pos[0] = xform[0][3];
  697.60 +	pos[1] = xform[1][3];
  697.61 +	pos[2] = xform[2][3];
  697.62 +
  697.63 +	orient[0] = xform[0][2];
  697.64 +	orient[1] = xform[1][2];
  697.65 +	orient[2] = -xform[2][2];
  697.66 +
  697.67 +	orient[3] = xform[0][1];
  697.68 +	orient[4] = xform[1][1];
  697.69 +	orient[5] = xform[2][1];
  697.70 +
  697.71 +	alListenerfv(AL_POSITION, pos);
  697.72 +	alListenerfv(AL_ORIENTATION, orient);
  697.73 +}
   698.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   698.2 +++ b/src/audio/audio.h	Sat Feb 01 19:58:19 2014 +0200
   698.3 @@ -0,0 +1,11 @@
   698.4 +#ifndef AUDIO_H_
   698.5 +#define AUDIO_H_
   698.6 +
   698.7 +#include "vmath/vmath.h"
   698.8 +
   698.9 +bool init_audio();
  698.10 +void destroy_audio();
  698.11 +
  698.12 +void set_audio_listener(const Matrix4x4 &xform);
  698.13 +
  698.14 +#endif  // AUDIO_H_
   699.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   699.2 +++ b/src/audio/openal.h	Sat Feb 01 19:58:19 2014 +0200
   699.3 @@ -0,0 +1,12 @@
   699.4 +#ifndef OPENAL_H_
   699.5 +#define OPENAL_H_
   699.6 +
   699.7 +#ifndef __APPLE__
   699.8 +#include <AL/al.h>
   699.9 +#include <AL/alc.h>
  699.10 +#else
  699.11 +#include <OpenAL/al.h>
  699.12 +#include <OpenAL/alc.h>
  699.13 +#endif
  699.14 +
  699.15 +#endif  /* OPENAL_H_ */
   700.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   700.2 +++ b/src/audio/ovstream.cc	Sat Feb 01 19:58:19 2014 +0200
   700.3 @@ -0,0 +1,100 @@
   700.4 +#include <stdio.h>
   700.5 +#include <assert.h>
   700.6 +#include "datapath.h"
   700.7 +#include "logger.h"
   700.8 +#include "ovstream.h"
   700.9 +
  700.10 +OggVorbisStream::OggVorbisStream()
  700.11 +{
  700.12 +	vfopen = false;
  700.13 +
  700.14 +	pthread_mutex_init(&vflock, 0);
  700.15 +}
  700.16 +
  700.17 +OggVorbisStream::~OggVorbisStream()
  700.18 +{
  700.19 +	close();
  700.20 +}
  700.21 +
  700.22 +bool OggVorbisStream::open(const char *fname)
  700.23 +{
  700.24 +	close();
  700.25 +
  700.26 +	pthread_mutex_lock(&vflock);
  700.27 +
  700.28 +	std::string fpath = datafile_path(fname);
  700.29 +	info_log("opening ogg/vorbis stream: %s -> %s\n", (fname && *fname) ? fname : "<not found>", (!fpath.empty()) ? fpath.c_str() : "<not found>");
  700.30 +
  700.31 +	if(fpath.empty() || ov_fopen(fpath.c_str(), &vf) != 0) {
  700.32 +		error_log("failed to open ogg/vorbis stream: %s\n", fname ? fname : "<not found>");
  700.33 +		pthread_mutex_unlock(&vflock);
  700.34 +		return false;
  700.35 +	}
  700.36 +
  700.37 +	vfopen = true;
  700.38 +	pthread_mutex_unlock(&vflock);
  700.39 +	return true;
  700.40 +}
  700.41 +
  700.42 +void OggVorbisStream::close()
  700.43 +{
  700.44 +	pthread_mutex_lock(&vflock);
  700.45 +	if(vfopen) {
  700.46 +		ov_clear(&vf);
  700.47 +		vfopen = false;
  700.48 +	}
  700.49 +	pthread_mutex_unlock(&vflock);
  700.50 +}
  700.51 +
  700.52 +void OggVorbisStream::play(AUDIO_PLAYMODE mode)
  700.53 +{
  700.54 +	if (vfopen)
  700.55 +	{
  700.56 +		AudioStream::play(mode);
  700.57 +	} else {
  700.58 +		error_log("failed to play audio track.\n");
  700.59 +	}
  700.60 +}
  700.61 +
  700.62 +void OggVorbisStream::rewind()
  700.63 +{
  700.64 +	pthread_mutex_lock(&vflock);
  700.65 +	if(vfopen) {
  700.66 +		ov_raw_seek(&vf, 0);
  700.67 +	}
  700.68 +	pthread_mutex_unlock(&vflock);
  700.69 +}
  700.70 +
  700.71 +bool OggVorbisStream::more_samples(AudioStreamBuffer *buf)
  700.72 +{
  700.73 +	pthread_mutex_lock(&vflock);
  700.74 +
  700.75 +	vorbis_info *vinfo = ov_info(&vf, -1);
  700.76 +	buf->channels = vinfo->channels;
  700.77 +	buf->sample_rate = vinfo->rate;
  700.78 +	assert(buf->channels == 2);
  700.79 +	assert(buf->sample_rate == 44100);
  700.80 +
  700.81 +	long bufsz = AUDIO_BUFFER_BYTES;
  700.82 +	long total_read = 0;
  700.83 +	while(total_read < bufsz) {
  700.84 +		int bitstream;
  700.85 +		long rd = ov_read(&vf, buf->samples + total_read, bufsz - total_read, 0, 2, 1, &bitstream);
  700.86 +
  700.87 +		if(!rd) {
  700.88 +			bufsz = total_read;
  700.89 +		} else {
  700.90 +			total_read += rd;
  700.91 +		}
  700.92 +	}
  700.93 +
  700.94 +	if(!total_read) {
  700.95 +		buf->num_samples = 0;
  700.96 +		pthread_mutex_unlock(&vflock);
  700.97 +		return false;
  700.98 +	}
  700.99 +
 700.100 +	buf->num_samples = bufsz / vinfo->channels / 2;
 700.101 +	pthread_mutex_unlock(&vflock);
 700.102 +	return true;
 700.103 +}
   701.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   701.2 +++ b/src/audio/ovstream.h	Sat Feb 01 19:58:19 2014 +0200
   701.3 @@ -0,0 +1,27 @@
   701.4 +#ifndef OVSTREAM_H_
   701.5 +#define OVSTREAM_H_
   701.6 +
   701.7 +#include <pthread.h>
   701.8 +#include <vorbis/vorbisfile.h>
   701.9 +#include "stream.h"
  701.10 +
  701.11 +class OggVorbisStream : public AudioStream {
  701.12 +private:
  701.13 +	OggVorbis_File vf;
  701.14 +	bool vfopen;
  701.15 +	pthread_mutex_t vflock;
  701.16 +
  701.17 +	virtual bool more_samples(AudioStreamBuffer *buf);
  701.18 +
  701.19 +public:
  701.20 +	OggVorbisStream();
  701.21 +	virtual ~OggVorbisStream();
  701.22 +
  701.23 +	bool open(const char *fname);
  701.24 +	void close();
  701.25 +
  701.26 +	virtual void play(AUDIO_PLAYMODE mode);
  701.27 +	virtual void rewind();
  701.28 +};
  701.29 +
  701.30 +#endif  // OVSTREAM_H_
   702.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   702.2 +++ b/src/audio/stream.cc	Sat Feb 01 19:58:19 2014 +0200
   702.3 @@ -0,0 +1,380 @@
   702.4 +#include <stdio.h>
   702.5 +#include <stdint.h>
   702.6 +#include <assert.h>
   702.7 +#include "openal.h"
   702.8 +#include "stream.h"
   702.9 +#include "logger.h"
  702.10 +#include "timer.h"
  702.11 +#include "kiss_fft.h"
  702.12 +
  702.13 +struct FFTState {
  702.14 +	kiss_fft_cfg kiss;
  702.15 +	kiss_fft_cpx *inbuf, *outbuf;
  702.16 +	int nsamples;
  702.17 +};
  702.18 +
  702.19 +static ALenum alformat(AudioStreamBuffer *buf)
  702.20 +{
  702.21 +	return buf->channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
  702.22 +}
  702.23 +
  702.24 +AudioStream::AudioStream()
  702.25 +{
  702.26 +	alsrc = 0;
  702.27 +	poll_interval = 25;
  702.28 +	done = true;
  702.29 +	loop = false;
  702.30 +	volume = 1.0;
  702.31 +
  702.32 +	freqhist = 0;
  702.33 +
  702.34 +	// by default disable FFT processing
  702.35 +	use_fft = false;
  702.36 +
  702.37 +	pthread_mutex_init(&mutex, 0);
  702.38 +}
  702.39 +
  702.40 +AudioStream::~AudioStream()
  702.41 +{
  702.42 +	stop();
  702.43 +}
  702.44 +
  702.45 +void AudioStream::enable_fft()
  702.46 +{
  702.47 +	use_fft = true;
  702.48 +}
  702.49 +
  702.50 +void AudioStream::disable_fft()
  702.51 +{
  702.52 +	use_fft = false;
  702.53 +}
  702.54 +
  702.55 +bool AudioStream::is_fft_enabled() const
  702.56 +{
  702.57 +	return use_fft;
  702.58 +}
  702.59 +
  702.60 +bool AudioStream::open(const char *fname)
  702.61 +{
  702.62 +	return false;
  702.63 +}
  702.64 +
  702.65 +void AudioStream::close()
  702.66 +{
  702.67 +}
  702.68 +
  702.69 +void AudioStream::set_volume(float vol)
  702.70 +{
  702.71 +	volume = vol;
  702.72 +
  702.73 +	pthread_mutex_lock(&mutex);
  702.74 +	if(alsrc) {
  702.75 +		alSourcef(alsrc, AL_GAIN, vol);
  702.76 +	}
  702.77 +	pthread_mutex_unlock(&mutex);
  702.78 +}
  702.79 +
  702.80 +float AudioStream::get_volume() const
  702.81 +{
  702.82 +	return volume;
  702.83 +}
  702.84 +
  702.85 +static void *thread_func(void *arg)
  702.86 +{
  702.87 +	AudioStream *astr = (AudioStream*)arg;
  702.88 +	astr->poll_loop();
  702.89 +	return 0;
  702.90 +}
  702.91 +
  702.92 +void AudioStream::play(AUDIO_PLAYMODE mode)
  702.93 +{
  702.94 +	loop = (mode == AUDIO_PLAYMODE_LOOP);
  702.95 +	done = false;
  702.96 +
  702.97 +	if(pthread_create(&play_thread, 0, thread_func, this) != 0) {
  702.98 +		error_log("failed to create music playback thread\n");
  702.99 +	}
 702.100 +}
 702.101 +
 702.102 +void AudioStream::stop()
 702.103 +{
 702.104 +	pthread_mutex_lock(&mutex);
 702.105 +
 702.106 +	if(alsrc) {
 702.107 +		done = true;
 702.108 +		alSourceStop(alsrc);
 702.109 +		printf("waiting for the music thread to stop\n");
 702.110 +		pthread_mutex_unlock(&mutex);
 702.111 +		pthread_join(play_thread, 0);
 702.112 +	} else {
 702.113 +		pthread_mutex_unlock(&mutex);
 702.114 +	}
 702.115 +}
 702.116 +
 702.117 +// gets an array of buffers and returns the index of the one matching id
 702.118 +static inline int find_buffer(unsigned int id, unsigned int *barr, int num)
 702.119 +{
 702.120 +	for(int i=0; i<num; i++) {
 702.121 +		if(barr[i] == id) {
 702.122 +			return i;
 702.123 +		}
 702.124 +	}
 702.125 +	return -1;
 702.126 +}
 702.127 +
 702.128 +
 702.129 +static int queued_idx_list[AUDIO_NUM_BUFFERS];
 702.130 +static int queued_idx_head = 0;
 702.131 +static int queued_idx_tail = 0;
 702.132 +
 702.133 +#define BUFQ_UNQUEUE() \
 702.134 +	do { \
 702.135 +		queued_idx_tail = (queued_idx_tail + 1) % AUDIO_NUM_BUFFERS; \
 702.136 +	} while(0)
 702.137 +
 702.138 +
 702.139 +#define BUFQ_QUEUE(idx)	\
 702.140 +	do { \
 702.141 +		queued_idx_head = (queued_idx_head + 1) % AUDIO_NUM_BUFFERS; \
 702.142 +		queued_idx_list[queued_idx_head] = idx; \
 702.143 +	} while(0)
 702.144 +
 702.145 +// thread function
 702.146 +void AudioStream::poll_loop()
 702.147 +{
 702.148 +	long prev_msec = -1000;
 702.149 +	unsigned int albuf[AUDIO_NUM_BUFFERS];
 702.150 +	int freqbins[AUDIO_NUM_BUFFERS][AUDIO_FFT_BINS];
 702.151 +
 702.152 +	pthread_mutex_lock(&mutex);
 702.153 +	alGenSources(1, &alsrc);
 702.154 +	alSourcei(alsrc, AL_LOOPING, AL_FALSE);
 702.155 +	alSourcef(alsrc, AL_GAIN, volume);
 702.156 +	alGenBuffers(AUDIO_NUM_BUFFERS, albuf);
 702.157 +	AudioStreamBuffer *buf = new AudioStreamBuffer;
 702.158 +
 702.159 +	FFTState fft;
 702.160 +	fft.kiss = kiss_fft_alloc(AUDIO_FFT_SAMPLES, 0, 0, 0);
 702.161 +	assert(fft.kiss);
 702.162 +	fft.inbuf = new kiss_fft_cpx[AUDIO_FFT_SAMPLES];
 702.163 +	fft.outbuf = new kiss_fft_cpx[AUDIO_FFT_SAMPLES];
 702.164 +	assert(fft.inbuf && fft.outbuf);
 702.165 +	fft.nsamples = AUDIO_FFT_SAMPLES;
 702.166 +
 702.167 +	// zero out the inbuf array to get rid of the imaginary parts
 702.168 +	memset(fft.inbuf, 0, AUDIO_FFT_SAMPLES * sizeof *fft.inbuf);
 702.169 +
 702.170 +	for(int i=0; i<AUDIO_NUM_BUFFERS; i++) {
 702.171 +		if(more_samples(buf)) {
 702.172 +			int bufsz = buf->num_samples * buf->channels * 2;       // 2 is for 16bit samples
 702.173 +			alBufferData(albuf[i], alformat(buf), buf->samples, bufsz, buf->sample_rate);
 702.174 +
 702.175 +			if(alGetError()) {
 702.176 +				fprintf(stderr, "failed to load sample data into OpenAL buffer\n");
 702.177 +			}
 702.178 +
 702.179 +			alSourceQueueBuffers(alsrc, 1, albuf + i);
 702.180 +			BUFQ_QUEUE(i);
 702.181 +
 702.182 +			if(alGetError()) {
 702.183 +				fprintf(stderr, "failed to start streaming audio buffers\n");
 702.184 +			}
 702.185 +
 702.186 +			// also calculate the frequencies
 702.187 +			calc_freq(buf, freqbins[i], &fft);
 702.188 +		} else {
 702.189 +			break;
 702.190 +		}
 702.191 +	}
 702.192 +
 702.193 +	// start playback
 702.194 +	alSourcePlay(alsrc);
 702.195 +	while(!done) {
 702.196 +		// XXX this doesn't work
 702.197 +		/*
 702.198 +		// first let's figure out which buffer is currently playing
 702.199 +		int cur_buf;
 702.200 +		alGetSourcei(alsrc, AL_BUFFER, &cur_buf);
 702.201 +		int cur_buf_idx = find_buffer(cur_buf, albuf, AUDIO_NUM_BUFFERS);
 702.202 +
 702.203 +		// make the fft histogram pointer point to the correct frequency bin array
 702.204 +		freqhist = cur_buf_idx != -1 ? freqbins[cur_buf_idx] : 0;
 702.205 +		if(!freqhist) {
 702.206 +			debug_log("skata\n");
 702.207 +		}
 702.208 +		*/
 702.209 +
 702.210 +		/* find out how many (if any) of the queued buffers are
 702.211 +		* done, and free to be reused.
 702.212 +		*/
 702.213 +		int num_buf_done;
 702.214 +		alGetSourcei(alsrc, AL_BUFFERS_PROCESSED, &num_buf_done);
 702.215 +		for(int i=0; i<num_buf_done; i++) {
 702.216 +			int err;
 702.217 +			// unqueue a buffer...
 702.218 +			unsigned int buf_id;
 702.219 +			alSourceUnqueueBuffers(alsrc, 1, &buf_id);
 702.220 +
 702.221 +			if((err = alGetError())) {
 702.222 +				fprintf(stderr, "failed to unqueue used buffer (error: %x)\n", err);
 702.223 +				num_buf_done = i;
 702.224 +				break;
 702.225 +			}
 702.226 +			BUFQ_UNQUEUE();
 702.227 +
 702.228 +			// find out which one of our al buffers we just unqueued
 702.229 +			int bidx = find_buffer(buf_id, albuf, AUDIO_NUM_BUFFERS);
 702.230 +			assert(bidx != -1);
 702.231 +
 702.232 +			int looping;
 702.233 +
 702.234 +			alGetSourcei(alsrc, AL_LOOPING, &looping);
 702.235 +			assert(looping == AL_FALSE);
 702.236 +			/*if((unsigned int)cur_buf == buf_id) {
 702.237 +				continue;
 702.238 +			}*/
 702.239 +
 702.240 +			// if there are more data, fill it up and requeue it
 702.241 +			if(more_samples(buf)) {
 702.242 +				int bufsz = buf->num_samples * buf->channels * 2;       // 2 is for 16bit samples
 702.243 +				alBufferData(buf_id, alformat(buf), buf->samples, bufsz, buf->sample_rate);
 702.244 +				if((err = alGetError())) {
 702.245 +					fprintf(stderr, "failed to load sample data into OpenAL buffer (error: %x)\n", err);
 702.246 +				}
 702.247 +
 702.248 +				alSourceQueueBuffers(alsrc, 1, &buf_id);
 702.249 +				if(alGetError()) {
 702.250 +					fprintf(stderr, "failed to start streaming audio buffers\n");
 702.251 +				}
 702.252 +				BUFQ_QUEUE(bidx);
 702.253 +
 702.254 +				// also calculate the frequencies if required
 702.255 +				if(use_fft) {
 702.256 +					calc_freq(buf, freqbins[bidx], &fft);
 702.257 +				}
 702.258 +			} else {
 702.259 +				// no more data...
 702.260 +				if(loop) {
 702.261 +					rewind();
 702.262 +				} else {
 702.263 +					done = true;
 702.264 +				}
 702.265 +			}
 702.266 +		}
 702.267 +		if(use_fft) {
 702.268 +			freqhist = freqbins[queued_idx_list[queued_idx_tail]];
 702.269 +		}
 702.270 +
 702.271 +		if(num_buf_done) {
 702.272 +			// make sure playback didn't stop
 702.273 +			int state;
 702.274 +			alGetSourcei(alsrc, AL_SOURCE_STATE, &state);
 702.275 +			if(state != AL_PLAYING) {
 702.276 +				alSourcePlay(alsrc);
 702.277 +			}
 702.278 +		}
 702.279 +
 702.280 +		pthread_mutex_unlock(&mutex);
 702.281 +		long msec = get_time_msec();
 702.282 +		long dt = msec - prev_msec;
 702.283 +		prev_msec = msec;
 702.284 +
 702.285 +		if(dt < poll_interval - 5) {
 702.286 +			sleep_msec(poll_interval - dt);
 702.287 +		} else {
 702.288 +			sched_yield();
 702.289 +		}
 702.290 +		pthread_mutex_lock(&mutex);
 702.291 +	}
 702.292 +
 702.293 +
 702.294 +	// done with the data, wait for the source to stop playing before cleanup
 702.295 +	int state;
 702.296 +	while(alGetSourcei(alsrc, AL_SOURCE_STATE, &state), state == AL_PLAYING) {
 702.297 +		sched_yield();
 702.298 +	}
 702.299 +
 702.300 +	freqhist = 0;
 702.301 +
 702.302 +	alDeleteBuffers(AUDIO_NUM_BUFFERS, albuf);
 702.303 +	alDeleteSources(1, &alsrc);
 702.304 +	alsrc = 0;
 702.305 +	pthread_mutex_unlock(&mutex);
 702.306 +
 702.307 +	delete buf;
 702.308 +
 702.309 +	delete [] fft.inbuf;
 702.310 +	delete [] fft.outbuf;
 702.311 +	kiss_fft_free(fft.kiss);
 702.312 +}
 702.313 +
 702.314 +int AudioStream::freq_count(int bin) const
 702.315 +{
 702.316 +	if(!freqhist || !use_fft || bin < 0 || bin >= AUDIO_BUFFER_SAMPLES) {
 702.317 +		return 0;
 702.318 +	}
 702.319 +	return freqhist[bin];
 702.320 +}
 702.321 +
 702.322 +#define NORM_FACTOR		(1.0f / (float)AUDIO_FFT_SAMPLES)
 702.323 +float AudioStream::freq_normalized(int bin) const
 702.324 +{
 702.325 +	// TODO remove the fudge factor
 702.326 +	return freq_count(bin) * NORM_FACTOR * 0.25;
 702.327 +}
 702.328 +
 702.329 +// frequency range in hertz
 702.330 +int AudioStream::freq_count(int range_start, int range_end) const
 702.331 +{
 702.332 +	// NOTE this will probably be something like sampling freq / num-bins Hz per bin...
 702.333 +	return 0;	// TODO
 702.334 +}
 702.335 +
 702.336 +// TODO ok this might be inefficient, copying the data around a lot, optimize later
 702.337 +void AudioStream::calc_freq(AudioStreamBuffer *buf, int *bins, FFTState *fft)
 702.338 +{
 702.339 +	kiss_fft_cpx *inptr = fft->inbuf;
 702.340 +	int16_t *samples = (int16_t*)buf->samples;
 702.341 +	for(int i=0; i<AUDIO_BUFFER_SAMPLES; i++) {
 702.342 +
 702.343 +		inptr->i = 0;
 702.344 +		if(i < buf->num_samples) {
 702.345 +			int left = samples[i * 2];
 702.346 +			int right = samples[i * 2 + 1];
 702.347 +
 702.348 +			(inptr++)->r = (left + right) / 2;
 702.349 +		} else {
 702.350 +			(inptr++)->r = 0;
 702.351 +		}
 702.352 +	}
 702.353 +
 702.354 +	kiss_fft(fft->kiss, fft->inbuf, fft->outbuf);
 702.355 +
 702.356 +	// then copy all the relevant data to the bins array
 702.357 +	int num_out_samples = AUDIO_BUFFER_SAMPLES / 2;
 702.358 +	int samples_per_bin = num_out_samples / AUDIO_FFT_BINS;
 702.359 +
 702.360 +	long abins[AUDIO_FFT_BINS];
 702.361 +
 702.362 +	int prev_bidx = -1;
 702.363 +	// ignore the DC bin (0)
 702.364 +	for(int i=1; i<num_out_samples; i++) {
 702.365 +		int bidx = i * AUDIO_FFT_BINS / num_out_samples;
 702.366 +		float x = fft->outbuf[i].r;
 702.367 +		float y = fft->outbuf[i].i;
 702.368 +		int val = x * x + y * y;
 702.369 +
 702.370 +		if(bidx != prev_bidx) {
 702.371 +			abins[bidx] = val;
 702.372 +			prev_bidx = bidx;
 702.373 +		} else {
 702.374 +			abins[bidx] += val;
 702.375 +		}
 702.376 +	}
 702.377 +
 702.378 +	for(int i=0; i<AUDIO_FFT_BINS; i++) {
 702.379 +		long res = abins[i] / (long)samples_per_bin;
 702.380 +		bins[i] = res;
 702.381 +		assert(bins[i] == res);
 702.382 +	}
 702.383 +}
   703.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   703.2 +++ b/src/audio/stream.h	Sat Feb 01 19:58:19 2014 +0200
   703.3 @@ -0,0 +1,79 @@
   703.4 +#ifndef STREAM_H_
   703.5 +#define STREAM_H_
   703.6 +
   703.7 +#include <pthread.h>
   703.8 +
   703.9 +#define AUDIO_FFT_BINS			16
  703.10 +#define AUDIO_FFT_DOWNSAMPLE	1
  703.11 +
  703.12 +#define AUDIO_NUM_BUFFERS		8
  703.13 +#define AUDIO_BUFFER_MSEC		32
  703.14 +// TODO should the sampling rate be hardcoded?
  703.15 +#define AUDIO_BUFFER_SAMPLES	(AUDIO_BUFFER_MSEC * 44100 / 1000)
  703.16 +// TODO unhardcode the channels number
  703.17 +#define AUDIO_BUFFER_BYTES		(AUDIO_BUFFER_SAMPLES * 2 * 2)
  703.18 +
  703.19 +#define AUDIO_FFT_SAMPLES		(AUDIO_BUFFER_SAMPLES / AUDIO_FFT_DOWNSAMPLE)
  703.20 +
  703.21 +enum AUDIO_PLAYMODE
  703.22 +{
  703.23 +	AUDIO_PLAYMODE_ONCE,
  703.24 +	AUDIO_PLAYMODE_LOOP
  703.25 +};
  703.26 +
  703.27 +struct AudioStreamBuffer {
  703.28 +	char samples[AUDIO_BUFFER_BYTES];
  703.29 +
  703.30 +	int num_samples;
  703.31 +	int channels;
  703.32 +	int sample_rate;
  703.33 +};
  703.34 +
  703.35 +struct FFTState;
  703.36 +
  703.37 +class AudioStream {
  703.38 +private:
  703.39 +	pthread_t play_thread;
  703.40 +	pthread_mutex_t mutex;
  703.41 +
  703.42 +	float volume;
  703.43 +	bool done, loop;
  703.44 +	unsigned int poll_interval;
  703.45 +	unsigned int alsrc;
  703.46 +
  703.47 +	int *freqhist;	// this will always point to the fft of the currently playing buffer
  703.48 +
  703.49 +	bool use_fft;
  703.50 +
  703.51 +	virtual bool more_samples(AudioStreamBuffer *buf) = 0;
  703.52 +	virtual void calc_freq(AudioStreamBuffer *buf, int *bins, FFTState *fft);
  703.53 +
  703.54 +public:
  703.55 +	void poll_loop();
  703.56 +
  703.57 +	AudioStream();
  703.58 +	virtual ~AudioStream();
  703.59 +
  703.60 +	virtual void enable_fft();
  703.61 +	virtual void disable_fft();
  703.62 +	virtual bool is_fft_enabled() const;
  703.63 +
  703.64 +	virtual bool open(const char *fname);
  703.65 +	virtual void close();
  703.66 +
  703.67 +	virtual void set_volume(float vol);
  703.68 +	virtual float get_volume() const;
  703.69 +
  703.70 +	virtual void play(AUDIO_PLAYMODE mode);
  703.71 +	virtual void stop();
  703.72 +
  703.73 +	virtual void rewind() = 0;
  703.74 +
  703.75 +	virtual int freq_count(int bin) const;
  703.76 +	virtual float freq_normalized(int bin) const;
  703.77 +
  703.78 +	// frequency range in hertz
  703.79 +	virtual int freq_count(int range_start, int range_end) const;
  703.80 +};
  703.81 +
  703.82 +#endif  // AUDIO_STREAM_H_
   704.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   704.2 +++ b/src/curve.cc	Sat Feb 01 19:58:19 2014 +0200
   704.3 @@ -0,0 +1,316 @@
   704.4 +#include <float.h>
   704.5 +#include <assert.h>
   704.6 +#include "curve.h"
   704.7 +#include "opengl.h"
   704.8 +#include "shader.h"
   704.9 +#include "logger.h"
  704.10 +
  704.11 +#define DEF_THICKNESS	0.075
  704.12 +#define DEF_SEGM_SUB	3
  704.13 +#define DEF_RING_SUB	6
  704.14 +
  704.15 +Curve::Curve()
  704.16 +{
  704.17 +	thickness = DEF_THICKNESS;
  704.18 +	mesh_valid = false;
  704.19 +	lengths_valid = false;
  704.20 +
  704.21 +	bbox_valid = false;
  704.22 +
  704.23 +	segm_subdiv = DEF_SEGM_SUB;
  704.24 +	ring_subdiv = DEF_RING_SUB;
  704.25 +}
  704.26 +
  704.27 +Curve::Curve(const Vector3 *points, int num_points)
  704.28 +{
  704.29 +	thickness = DEF_THICKNESS;
  704.30 +	mesh_valid = false;
  704.31 +	lengths_valid = false;
  704.32 +
  704.33 +	bbox_valid = false;
  704.34 +
  704.35 +	segm_subdiv = DEF_SEGM_SUB;
  704.36 +	ring_subdiv = DEF_RING_SUB;
  704.37 +
  704.38 +	for(int i=0; i<num_points; i++) {
  704.39 +		add_point(points[i]);
  704.40 +	}
  704.41 +}
  704.42 +
  704.43 +Curve::Curve(const Vector2 *points, int num_points)
  704.44 +{
  704.45 +	thickness = DEF_THICKNESS;
  704.46 +	mesh_valid = false;
  704.47 +	lengths_valid = false;
  704.48 +
  704.49 +	bbox_valid = false;
  704.50 +
  704.51 +	segm_subdiv = DEF_SEGM_SUB;
  704.52 +	ring_subdiv = DEF_RING_SUB;
  704.53 +
  704.54 +	for(int i=0; i<num_points; i++) {
  704.55 +		add_point(Vector3(points[i].x, points[i].y, 0.0));
  704.56 +	}
  704.57 +}
  704.58 +
  704.59 +void Curve::set_name(const char *name)
  704.60 +{
  704.61 +	this->name = name;
  704.62 +}
  704.63 +
  704.64 +const char *Curve::get_name() const
  704.65 +{
  704.66 +	return name.c_str();
  704.67 +}
  704.68 +
  704.69 +bool Curve::empty() const
  704.70 +{
  704.71 +	return cv.empty();
  704.72 +}
  704.73 +
  704.74 +void Curve::set_thickness(float thickness)
  704.75 +{
  704.76 +	this->thickness = thickness;
  704.77 +}
  704.78 +
  704.79 +void Curve::set_subdiv(int seg, int ring)
  704.80 +{
  704.81 +	if(seg < 1) seg = 1;
  704.82 +	if(ring < 3) ring = 3;
  704.83 +
  704.84 +	segm_subdiv = seg;
  704.85 +	ring_subdiv = ring;
  704.86 +}
  704.87 +
  704.88 +void Curve::clear()
  704.89 +{
  704.90 +	mesh_valid = false;
  704.91 +	lengths_valid = false;
  704.92 +	bbox_valid = false;
  704.93 +	cv.clear();
  704.94 +}
  704.95 +
  704.96 +void Curve::add_point(const Vector3 &pt)
  704.97 +{
  704.98 +	cv.push_back(pt);
  704.99 +	mesh_valid = false;
 704.100 +	lengths_valid = false;
 704.101 +	bbox_valid = false;
 704.102 +}
 704.103 +
 704.104 +Vector3 &Curve::get_point(int idx)
 704.105 +{
 704.106 +	mesh_valid = false;
 704.107 +	lengths_valid = false;
 704.108 +	bbox_valid = false;
 704.109 +	return cv[idx];
 704.110 +}
 704.111 +
 704.112 +const Vector3 &Curve::get_point(int idx) const
 704.113 +{
 704.114 +	return cv[idx];
 704.115 +}
 704.116 +
 704.117 +int Curve::get_count() const
 704.118 +{
 704.119 +	return (int)cv.size();
 704.120 +}
 704.121 +
 704.122 +Vector3 &Curve::operator[] (int idx)
 704.123 +{
 704.124 +	return get_point(idx);
 704.125 +}
 704.126 +
 704.127 +const Vector3 &Curve::operator[] (int idx) const
 704.128 +{
 704.129 +	return get_point(idx);
 704.130 +}
 704.131 +
 704.132 +void Curve::get_bbox(Vector3 *bbmin, Vector3 *bbmax) const
 704.133 +{
 704.134 +	if(!bbox_valid) {
 704.135 +		this->bbmin = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
 704.136 +		this->bbmax = -this->bbmin;
 704.137 +
 704.138 +		for(size_t i=0; i<cv.size(); i++) {
 704.139 +			for(int j=0; j<3; j++) {
 704.140 +				if(cv[i][j] < this->bbmin[j]) {
 704.141 +					this->bbmin[j] = cv[i][j];
 704.142 +				}
 704.143 +				if(cv[i][j] > this->bbmax[j]) {
 704.144 +					this->bbmax[j] = cv[i][j];
 704.145 +				}
 704.146 +			}
 704.147 +		}
 704.148 +		bbox_valid = true;
 704.149 +	}
 704.150 +
 704.151 +	if(bbmin) *bbmin = this->bbmin;
 704.152 +	if(bbmax) *bbmax = this->bbmax;
 704.153 +}
 704.154 +
 704.155 +void Curve::normalize()
 704.156 +{
 704.157 +	get_bbox(0, 0);	// force validation of the bounding box
 704.158 +
 704.159 +	float len = (bbmax - bbmin).length() * 0.5;
 704.160 +	if(len == 0.0) {
 704.161 +		return;
 704.162 +	}
 704.163 +
 704.164 +	for(size_t i=0; i<cv.size(); i++) {
 704.165 +		get_point(i) /= len;
 704.166 +	}
 704.167 +}
 704.168 +
 704.169 +Vector3 Curve::get_pos(float t) const
 704.170 +{
 704.171 +	if(cv.empty()) {
 704.172 +		return Vector3(0, 0, 0);
 704.173 +	}
 704.174 +	if(cv.size() == 1 || t <= 0.0) {
 704.175 +		return cv[0];
 704.176 +	}
 704.177 +	if(t >= 1.0) {
 704.178 +		return cv.back();
 704.179 +	}
 704.180 +
 704.181 +	t = reparametrize(t);
 704.182 +
 704.183 +	int numcv = (int)cv.size();
 704.184 +	int idx0 = t * (numcv - 1);
 704.185 +	int idx1 = idx0 + 1;
 704.186 +
 704.187 +	int idx_prev = idx0 <= 0 ? idx0 : idx0 - 1;
 704.188 +	int idx_next = idx1 >= numcv - 1 ? idx1 : idx1 + 1;
 704.189 +
 704.190 +	float dt = 1.0 / (float)(numcv - 1);
 704.191 +
 704.192 +	float t0 = (float)idx0 * dt;
 704.193 +	float t1 = (float)idx1 * dt;
 704.194 +
 704.195 +	t = (t - t0) / (t1 - t0);
 704.196 +	if(t < 0.0) t = 0.0;
 704.197 +	if(t > 1.0) t = 1.0;
 704.198 +
 704.199 +	//return catmull_rom_spline(cv[idx_prev], cv[idx0], cv[idx1], cv[idx_next], t);
 704.200 +	return bspline(cv[idx_prev], cv[idx0], cv[idx1], cv[idx_next], t);
 704.201 +}
 704.202 +
 704.203 +Vector3 Curve::operator() (float t) const
 704.204 +{
 704.205 +	return get_pos(t);
 704.206 +}
 704.207 +
 704.208 +void Curve::draw() const
 704.209 +{
 704.210 +	update_mesh();
 704.211 +	if(!mesh_valid) {
 704.212 +		return;
 704.213 +	}
 704.214 +
 704.215 +	mesh.draw();
 704.216 +}
 704.217 +
 704.218 +
 704.219 +float Curve::reparametrize(float t) const
 704.220 +{
 704.221 +	calc_cvlengths();
 704.222 +	return t;	// TODO
 704.223 +}
 704.224 +
 704.225 +void Curve::calc_cvlengths() const
 704.226 +{
 704.227 +	if(lengths_valid || cv.empty()) {
 704.228 +		return;
 704.229 +	}
 704.230 +
 704.231 +	length.clear();
 704.232 +	length.resize(cv.size());
 704.233 +
 704.234 +	length[0] = 0;
 704.235 +	for(size_t i=1; i<cv.size(); i++) {
 704.236 +		length[i] = length[i - 1] + (cv[i] - cv[i - 1]).length();
 704.237 +	}
 704.238 +
 704.239 +	lengths_valid = true;
 704.240 +}
 704.241 +
 704.242 +void Curve::update_mesh() const
 704.243 +{
 704.244 +	if(mesh_valid) return;
 704.245 +
 704.246 +	if(cv.size() < 2) {
 704.247 +		return;
 704.248 +	}
 704.249 +
 704.250 +	mesh.clear();
 704.251 +
 704.252 +	int nsub = segm_subdiv * (cv.size() - 1);
 704.253 +	int num_rings = nsub + 1;
 704.254 +
 704.255 +	int num_verts = ring_subdiv * num_rings;
 704.256 +	int num_quads = ring_subdiv * nsub;
 704.257 +	int num_tri = num_quads * 2;
 704.258 +	int num_idx = num_tri * 3;
 704.259 +
 704.260 +	float *varr = mesh.set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts);
 704.261 +	float *narr = mesh.set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts);
 704.262 +	float *tcarr = mesh.set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts);
 704.263 +	unsigned int *idxarr = mesh.set_index_data(num_idx);
 704.264 +
 704.265 +	float t = 0.0;
 704.266 +	float dt = 1.0 / (float)(num_rings - 1);
 704.267 +
 704.268 +	for(int i=0; i<num_rings; i++) {
 704.269 +		Vector3 p = get_pos(t);
 704.270 +		Vector3 dir = (get_pos(t + dt) - p).normalized();
 704.271 +
 704.272 +		Vector3 up = Vector3(0, 0, 1);
 704.273 +		float updotdir = dot_product(up, dir);
 704.274 +		if(1.0 - fabs(updotdir) < 1e-4) {
 704.275 +			up = Vector3(0, 1, 0);
 704.276 +		}
 704.277 +		Vector3 right = cross_product(up, dir).normalized();
 704.278 +		up = cross_product(dir, right);
 704.279 +
 704.280 +		for(int j=0; j<ring_subdiv; j++) {
 704.281 +			float u = (float)j / (float)ring_subdiv * M_PI * 2.0;
 704.282 +			Quaternion qrot(dir, u);
 704.283 +			Vector3 v = p + right.transformed(qrot) * thickness;
 704.284 +
 704.285 +			*varr++ = v.x;
 704.286 +			*varr++ = v.y;
 704.287 +			*varr++ = v.z;
 704.288 +
 704.289 +			Vector3 norm = (v - p).normalized();
 704.290 +			*narr++ = norm.x;
 704.291 +			*narr++ = norm.y;
 704.292 +			*narr++ = norm.z;
 704.293 +
 704.294 +			*tcarr++ = u;
 704.295 +			*tcarr++ = t;
 704.296 +
 704.297 +			if(i < nsub) {
 704.298 +				int quad = i * ring_subdiv + j;
 704.299 +
 704.300 +				int v0 = quad;
 704.301 +				int v1 = i * ring_subdiv + ((j + 1) % ring_subdiv);
 704.302 +				int v2 = (i + 1) * ring_subdiv + ((j + 1) % ring_subdiv);
 704.303 +				int v3 = (i + 1) * ring_subdiv + j;
 704.304 +
 704.305 +				idxarr[quad * 6] = v0;
 704.306 +				idxarr[quad * 6 + 1] = v1;
 704.307 +				idxarr[quad * 6 + 2] = v2;
 704.308 +
 704.309 +				idxarr[quad * 6 + 3] = v0;
 704.310 +				idxarr[quad * 6 + 4] = v2;
 704.311 +				idxarr[quad * 6 + 5] = v3;
 704.312 +			}
 704.313 +		}
 704.314 +
 704.315 +		t += dt;
 704.316 +	}
 704.317 +
 704.318 +	mesh_valid = true;
 704.319 +}
   705.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   705.2 +++ b/src/curve.h	Sat Feb 01 19:58:19 2014 +0200
   705.3 @@ -0,0 +1,64 @@
   705.4 +#ifndef CURVE_H_
   705.5 +#define CURVE_H_
   705.6 +
   705.7 +#include <string>
   705.8 +#include <vector>
   705.9 +#include "vmath/vmath.h"
  705.10 +#include "mesh.h"
  705.11 +
  705.12 +class Curve {
  705.13 +private:
  705.14 +	std::string name;
  705.15 +
  705.16 +	std::vector<Vector3> cv;
  705.17 +	float thickness;
  705.18 +
  705.19 +	int segm_subdiv, ring_subdiv;
  705.20 +
  705.21 +	/// normalized arc-lengths of each control vertex from the beginning
  705.22 +	mutable std::vector<float> length;
  705.23 +	mutable bool lengths_valid;
  705.24 +
  705.25 +	mutable Vector3 bbmin, bbmax;
  705.26 +	mutable bool bbox_valid;
  705.27 +
  705.28 +	mutable Mesh mesh;
  705.29 +	mutable bool mesh_valid;
  705.30 +
  705.31 +	float reparametrize(float t) const;
  705.32 +
  705.33 +	void calc_cvlengths() const;
  705.34 +	void update_mesh() const;
  705.35 +
  705.36 +public:
  705.37 +	Curve();
  705.38 +	Curve(const Vector3 *points, int num_points);
  705.39 +	Curve(const Vector2 *points, int num_points);
  705.40 +
  705.41 +	void set_name(const char *name);
  705.42 +	const char *get_name() const;
  705.43 +
  705.44 +	bool empty() const;
  705.45 +
  705.46 +	void set_thickness(float thickness);
  705.47 +	void set_subdiv(int seg, int ring);
  705.48 +
  705.49 +	void clear();
  705.50 +	void add_point(const Vector3 &pt);
  705.51 +	Vector3 &get_point(int idx);
  705.52 +	const Vector3 &get_point(int idx) const;
  705.53 +	int get_count() const;
  705.54 +
  705.55 +	Vector3 &operator[] (int idx);
  705.56 +	const Vector3 &operator[] (int idx) const;
  705.57 +
  705.58 +	void get_bbox(Vector3 *bbmin, Vector3 *bbmax) const;
  705.59 +	void normalize();
  705.60 +
  705.61 +	Vector3 get_pos(float t) const;
  705.62 +	Vector3 operator() (float t) const;
  705.63 +
  705.64 +	void draw() const;
  705.65 +};
  705.66 +
  705.67 +#endif	// CURVE_H_
   706.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   706.2 +++ b/src/datapath.cc	Sat Feb 01 19:58:19 2014 +0200
   706.3 @@ -0,0 +1,67 @@
   706.4 +#include <stdio.h>
   706.5 +#include <set>
   706.6 +#include <string>
   706.7 +#include "logger.h"
   706.8 +#include "datapath.h"
   706.9 +
  706.10 +static std::set<std::string> paths;
  706.11 +
  706.12 +void add_data_path(const char *path)
  706.13 +{
  706.14 +	paths.insert(path);
  706.15 +}
  706.16 +
  706.17 +#ifndef TARGET_IPHONE
  706.18 +std::string datafile_path(const char *fname)
  706.19 +{
  706.20 +	std::string res;
  706.21 +	if(!fname) {
  706.22 +		return res;
  706.23 +	}
  706.24 +
  706.25 +	std::set<std::string>::const_iterator it = paths.begin();
  706.26 +	while(it != paths.end()) {
  706.27 +		const std::string &path = *it++;
  706.28 +		res = path + "/" + std::string(fname);
  706.29 +		FILE *fp = fopen(res.c_str(), "r");
  706.30 +		if(fp) {
  706.31 +			fclose(fp);
  706.32 +			return res;
  706.33 +		}
  706.34 +	}
  706.35 +
  706.36 +	// It's not found. Return the name itself just in case it's right here
  706.37 +	return std::string(fname);
  706.38 +}
  706.39 +#else
  706.40 +#include <CoreFoundation/CoreFoundation.h>
  706.41 +
  706.42 +std::string datafile_path(const char *fname)
  706.43 +{
  706.44 +	std::string res;
  706.45 +	if(!fname) {
  706.46 +		return res;
  706.47 +	}
  706.48 +
  706.49 +	CFBundleRef bundle;
  706.50 +	CFURLRef url;
  706.51 +	CFStringRef cfname;
  706.52 +
  706.53 +	cfname = CFStringCreateWithCString(0, fname, kCFStringEncodingASCII);
  706.54 +
  706.55 +	bundle = CFBundleGetMainBundle();
  706.56 +	if(!(url = CFBundleCopyResourceURL(bundle, cfname, 0, 0))) {
  706.57 +		CFRelease(cfname);
  706.58 +		return fname;
  706.59 +	}
  706.60 +	CFRelease(cfname);
  706.61 +
  706.62 +	char path[1024];
  706.63 +	if(!CFURLGetFileSystemRepresentation(url, 1, (unsigned char*)path, sizeof path)) {
  706.64 +		CFRelease(url);
  706.65 +		return fname;
  706.66 +	}
  706.67 +	CFRelease(url);
  706.68 +	return std::string(path);
  706.69 +}
  706.70 +#endif
   707.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   707.2 +++ b/src/datapath.h	Sat Feb 01 19:58:19 2014 +0200
   707.3 @@ -0,0 +1,10 @@
   707.4 +#ifndef DATAPATH_H_
   707.5 +#define DATAPATH_H_
   707.6 +
   707.7 +#include <string>
   707.8 +
   707.9 +void add_data_path(const char *path);
  707.10 +
  707.11 +std::string datafile_path(const char *fname);
  707.12 +
  707.13 +#endif	// DATAPATH_H_
   708.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   708.2 +++ b/src/dataset.h	Sat Feb 01 19:58:19 2014 +0200
   708.3 @@ -0,0 +1,44 @@
   708.4 +/** DataSet is a generic resource database with fast O(logn) lookups by name
   708.5 + * it can be used for texture managers, mesh managers, sound effect managers etc
   708.6 + *
   708.7 + * The constructor takes a load function and a destructor function to be called
   708.8 + * when a nonexistent resource is requested and needs to be loaded, and when
   708.9 + * the DataSet is destroyed. The destructor is optional and can be set to null
  708.10 + * if not needed.
  708.11 + *
  708.12 + * Requesting a resource works by simply calling get, example:
  708.13 + * ----------------------------------------------------------
  708.14 + * \code
  708.15 + * Texture *load_texture(const char *fname);
  708.16 + * void free_texture(Texture *tex);
  708.17 + *
  708.18 + * DataSet<Texture*> texman(load_texture, free_texture);
  708.19 + * Texture *foo = texman.get("foo.png");
  708.20 + * \endcode
  708.21 + */
  708.22 +#ifndef DATASET_H_
  708.23 +#define DATASET_H_
  708.24 +
  708.25 +#include <string>
  708.26 +#include <map>
  708.27 +
  708.28 +template <typename T>
  708.29 +class DataSet {
  708.30 +protected:
  708.31 +	mutable std::map<std::string, T> data;
  708.32 +
  708.33 +	T (*load)(const char*);
  708.34 +	void (*destroy)(T);
  708.35 +
  708.36 +public:
  708.37 +	DataSet(T (*load_func)(const char*), void (*destr_func)(T) = 0);
  708.38 +	~DataSet();
  708.39 +
  708.40 +	void clear();
  708.41 +
  708.42 +	T get(const char *name) const;
  708.43 +};
  708.44 +
  708.45 +#include "dataset.inl"
  708.46 +
  708.47 +#endif	// DATASET_H_
   709.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   709.2 +++ b/src/dataset.inl	Sat Feb 01 19:58:19 2014 +0200
   709.3 @@ -0,0 +1,56 @@
   709.4 +#include <stdio.h>
   709.5 +#include <string.h>
   709.6 +#include "datapath.h"
   709.7 +
   709.8 +template <typename T>
   709.9 +DataSet<T>::DataSet(T (*load_func)(const char*), void (*destr_func)(T))
  709.10 +{
  709.11 +	load = load_func;
  709.12 +	destroy = destr_func;
  709.13 +}
  709.14 +
  709.15 +template <typename T>
  709.16 +DataSet<T>::~DataSet()
  709.17 +{
  709.18 +	clear();
  709.19 +}
  709.20 +
  709.21 +template <typename T>
  709.22 +void DataSet<T>::clear()
  709.23 +{
  709.24 +	if(destroy) {
  709.25 +		typename std::map<std::string, T>::iterator it = data.begin();
  709.26 +		while(it != data.end()) {
  709.27 +			destroy(it++->second);
  709.28 +		}
  709.29 +	}
  709.30 +	data.clear();
  709.31 +}
  709.32 +
  709.33 +template <typename T>
  709.34 +T DataSet<T>::get(const char *name) const
  709.35 +{
  709.36 +	typename std::map<std::string, T>::const_iterator iter = data.find(name);
  709.37 +	if(iter != data.end()) {
  709.38 +		return iter->second;
  709.39 +	}
  709.40 +
  709.41 +	const char *fname, *slash;
  709.42 +	if((slash = strrchr(name, '/'))) {
  709.43 +		fname = slash + 1;
  709.44 +	} else {
  709.45 +		fname = name;
  709.46 +	}
  709.47 +
  709.48 +	std::string path = datafile_path(fname);
  709.49 +	if(path.empty()) {
  709.50 +		fprintf(stderr, "can't find data file: %s\n", name);
  709.51 +		return 0;
  709.52 +	}
  709.53 +
  709.54 +	T res = load(path.c_str());
  709.55 +	if(res) {
  709.56 +		data[name] = res;
  709.57 +	}
  709.58 +	return res;
  709.59 +}
   710.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   710.2 +++ b/src/enemy.cc	Sat Feb 01 19:58:19 2014 +0200
   710.3 @@ -0,0 +1,40 @@
   710.4 +#include "enemy.h"
   710.5 +#include "object.h"
   710.6 +#include "scene.h"
   710.7 +
   710.8 +Enemy::Enemy()
   710.9 +{
  710.10 +	root = 0;
  710.11 +	scn = 0;
  710.12 +}
  710.13 +
  710.14 +Enemy::~Enemy()
  710.15 +{
  710.16 +	delete root;
  710.17 +	delete scn;
  710.18 +}
  710.19 +
  710.20 +bool Enemy::load(const char *fname)
  710.21 +{
  710.22 +	if(!scn->load(fname)) {
  710.23 +		return false;
  710.24 +	}
  710.25 +
  710.26 +	// reparent all root objects
  710.27 +	root = new XFormNode;
  710.28 +	for(size_t i=0; i<scn->objects.size(); i++) {
  710.29 +		if(!scn->objects[i]->get_parent()) {
  710.30 +			root->add_child(scn->objects[i]);
  710.31 +		}
  710.32 +	}
  710.33 +	return true;
  710.34 +}
  710.35 +
  710.36 +void Enemy::update(long tm)
  710.37 +{
  710.38 +}
  710.39 +
  710.40 +void Enemy::draw() const
  710.41 +{
  710.42 +	root->draw();
  710.43 +}
   711.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   711.2 +++ b/src/enemy.h	Sat Feb 01 19:58:19 2014 +0200
   711.3 @@ -0,0 +1,22 @@
   711.4 +#ifndef ENEMY_H_
   711.5 +#define ENEMY_H_
   711.6 +
   711.7 +class XFormNode;
   711.8 +class Scene;
   711.9 +
  711.10 +class Enemy {
  711.11 +private:
  711.12 +	Scene *scn;
  711.13 +	XFormNode *root;
  711.14 +
  711.15 +public:
  711.16 +	Enemy();
  711.17 +	~Enemy();
  711.18 +
  711.19 +	bool load(const char *fname);
  711.20 +
  711.21 +	void update(long tm);
  711.22 +	void draw() const;
  711.23 +};
  711.24 +
  711.25 +#endif	// ENEMY_H_
   712.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   712.2 +++ b/src/game.cc	Sat Feb 01 19:58:19 2014 +0200
   712.3 @@ -0,0 +1,241 @@
   712.4 +#include <vector>
   712.5 +#include <assert.h>
   712.6 +
   712.7 +#include "opengl.h"
   712.8 +#include "game.h"
   712.9 +#include "input.h"
  712.10 +#include "datapath.h"
  712.11 +#include "shader.h"
  712.12 +#include "sdrman.h"
  712.13 +#include "unistate.h"
  712.14 +#include "scr_debug.h"
  712.15 +#include "scr_game.h"
  712.16 +#include "logger.h"
  712.17 +#include "mesh.h"
  712.18 +#include "audio/audio.h"
  712.19 +#include "timer.h"
  712.20 +
  712.21 +static void toggle_debug();
  712.22 +
  712.23 +static char *def_argv[] = { (char*)"game", 0 };
  712.24 +
  712.25 +static int argc = 1;
  712.26 +static char **argv = def_argv;
  712.27 +static int width, height;
  712.28 +
  712.29 +static std::vector<Screen*> screens;
  712.30 +static Screen *debug_screen;
  712.31 +
  712.32 +static void standard_state_uniforms();
  712.33 +static bool create_screens();
  712.34 +
  712.35 +ShaderProg *defsdr;
  712.36 +Timer timer;
  712.37 +
  712.38 +void game_set_args(int argc, char **argv)
  712.39 +{
  712.40 +	::argc = argc;
  712.41 +	::argv = argv;
  712.42 +}
  712.43 +
  712.44 +bool game_init()
  712.45 +{
  712.46 +	init_opengl();
  712.47 +	CHECKGLERR;
  712.48 +
  712.49 +	/*
  712.50 +#ifdef __GLEW_H__
  712.51 +	if(GLEW_ARB_multisample) {
  712.52 +		info_log("enabling multisampling\n");
  712.53 +		glEnable(GL_MULTISAMPLE);
  712.54 +	} else {
  712.55 +		info_log("no multisampling support, will try old-style smoothing\n");
  712.56 +		// line smoothing enabled when needed (mostly by tools)
  712.57 +	}
  712.58 +#endif
  712.59 +	*/
  712.60 +
  712.61 +	// The configuration file is expected to be on the root
  712.62 +	// of our data archive.
  712.63 +	add_data_path("data");
  712.64 +	add_data_path("sdr");
  712.65 +
  712.66 +	standard_state_uniforms();
  712.67 +
  712.68 +	if(!(defsdr = get_sdrprog("default.v.glsl", "default.p.glsl"))) {
  712.69 +		error_log("failed to load default shader, aborting\n");
  712.70 +		return false;
  712.71 +	}
  712.72 +
  712.73 +	glEnable(GL_DEPTH_TEST);
  712.74 +	glEnable(GL_CULL_FACE);
  712.75 +
  712.76 +	init_audio();
  712.77 +
  712.78 +	if(!create_screens()) {
  712.79 +		error_log("failed to create scenes\n");
  712.80 +		return false;
  712.81 +	}
  712.82 +#if defined(TARGET_IPHONE) && !defined(NDEBUG)
  712.83 +	//toggle_debug();
  712.84 +#endif
  712.85 +
  712.86 +	return true;
  712.87 +}
  712.88 +
  712.89 +void game_cleanup()
  712.90 +{
  712.91 +	destroy_audio();
  712.92 +
  712.93 +	delete defsdr;
  712.94 +
  712.95 +	// pop all screens
  712.96 +	while(current_screen()) {
  712.97 +		pop_screen();
  712.98 +	}
  712.99 +	// and then destroy them
 712.100 +	for(size_t i=0; i<screens.size(); i++) {
 712.101 +		delete screens[i];
 712.102 +	}
 712.103 +	delete debug_screen;
 712.104 +}
 712.105 +
 712.106 +void game_display()
 712.107 +{
 712.108 +	unsigned long msec = timer.get_msec();
 712.109 +
 712.110 +	// set current global time state uniform
 712.111 +	static int st_time_idx = -1;
 712.112 +	if(st_time_idx == -1) {
 712.113 +		st_time_idx = get_unistate_index("st_time");
 712.114 +	}
 712.115 +	set_unistate(st_time_idx, (float)msec / 1000.0f);
 712.116 +
 712.117 +	current_screen()->update(msec);
 712.118 +
 712.119 +	glClearColor(0, 0, 0, 1);
 712.120 +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 712.121 +
 712.122 +	current_screen()->pre_draw();
 712.123 +	current_screen()->display();
 712.124 +	current_screen()->post_draw();
 712.125 +
 712.126 +	swap_buffers();
 712.127 +	CHECKGLERR;
 712.128 +}
 712.129 +
 712.130 +void game_reshape(int x, int y)
 712.131 +{
 712.132 +	width = x;
 712.133 +	height = y;
 712.134 +
 712.135 +	// set framebuffer size uniform
 712.136 +	static int st_fbsize_idx = -1;
 712.137 +	if(st_fbsize_idx == -1) {
 712.138 +		st_fbsize_idx = get_unistate_index("st_fbsize");
 712.139 +	}
 712.140 +	set_unistate(st_fbsize_idx, Vector2(x, y));
 712.141 +
 712.142 +	glViewport(0, 0, x, y);
 712.143 +	current_screen()->reshape(x, y);
 712.144 +}
 712.145 +
 712.146 +void game_key(int key, bool pressed)
 712.147 +{
 712.148 +	// special key processing
 712.149 +	if(pressed) {
 712.150 +		switch(key) {
 712.151 +		case 27:
 712.152 +			exit(0);
 712.153 +
 712.154 +		case '`':
 712.155 +			toggle_debug();
 712.156 +			break;
 712.157 +
 712.158 +		default:
 712.159 +			break;
 712.160 +		}
 712.161 +	}
 712.162 +	set_key_state(key, pressed);
 712.163 +	current_screen()->keyboard(key, pressed);
 712.164 +}
 712.165 +
 712.166 +
 712.167 +int get_screen_width()
 712.168 +{
 712.169 +	return width;
 712.170 +}
 712.171 +
 712.172 +int get_screen_height()
 712.173 +{
 712.174 +	return height;
 712.175 +}
 712.176 +
 712.177 +
 712.178 +
 712.179 +static void standard_state_uniforms()
 712.180 +{
 712.181 +	// setup all the standard state uniforms
 712.182 +	add_unistate("st_world_matrix", ST_MATRIX4);
 712.183 +	add_unistate("st_world_matrix_transpose", ST_MATRIX4);
 712.184 +	//add_unistate("st_world_matrix_inverse", ST_MATRIX4);
 712.185 +	add_unistate("st_world_matrix3", ST_MATRIX3);
 712.186 +
 712.187 +	add_unistate("st_view_matrix", ST_MATRIX4);
 712.188 +	add_unistate("st_view_matrix_transpose", ST_MATRIX4);
 712.189 +	//add_unistate("st_view_matrix_inverse", ST_MATRIX4);
 712.190 +	add_unistate("st_view_matrix3", ST_MATRIX3);
 712.191 +
 712.192 +	add_unistate("st_proj_matrix", ST_MATRIX4);
 712.193 +	//add_unistate("st_proj_matrix_inverse", ST_MATRIX4);
 712.194 +
 712.195 +	add_unistate("st_tex_matrix", ST_MATRIX4);
 712.196 +	//add_unistate("st_tex_matrix_inverse", ST_MATRIX4);
 712.197 +
 712.198 +	//add_unistate("st_mvp_matrix", ST_MATRIX4);
 712.199 +	//add_unistate("st_mvp_matrix_inverse", ST_MATRIX4);
 712.200 +
 712.201 +	add_unistate("st_fbsize", ST_FLOAT2);
 712.202 +
 712.203 +	add_unistate("st_time", ST_FLOAT);
 712.204 +
 712.205 +	add_unistate("st_light_pos", ST_FLOAT3);
 712.206 +	add_unistate("st_light_color", ST_FLOAT3);
 712.207 +	add_unistate("st_light_radius", ST_FLOAT);
 712.208 +
 712.209 +	add_unistate("st_mtl_diffuse", ST_FLOAT3);
 712.210 +	add_unistate("st_mtl_specular", ST_FLOAT3);
 712.211 +	add_unistate("st_mtl_shininess", ST_FLOAT);
 712.212 +	add_unistate("st_mtl_alpha", ST_FLOAT);
 712.213 +}
 712.214 +
 712.215 +static bool create_screens()
 712.216 +{
 712.217 +	Screen *scr;
 712.218 +
 712.219 +	// create the debug overlay screen
 712.220 +	debug_screen = new DebugScreen;
 712.221 +	if(!debug_screen->init()) {
 712.222 +		return false;
 712.223 +	}
 712.224 +
 712.225 +	// create the starting screen last
 712.226 +	scr = new GameScreen;
 712.227 +	if(!scr->init()) {
 712.228 +		return false;
 712.229 +	}
 712.230 +	screens.push_back(scr);
 712.231 +
 712.232 +	info_log("start-screen: %s\n", scr->get_name());
 712.233 +	push_screen(scr);
 712.234 +	return true;
 712.235 +}
 712.236 +
 712.237 +static void toggle_debug()
 712.238 +{
 712.239 +	if(dynamic_cast<DebugScreen*>(current_screen())) {
 712.240 +		pop_screen();
 712.241 +	} else {
 712.242 +		push_screen(debug_screen);
 712.243 +	}
 712.244 +}
   713.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   713.2 +++ b/src/game.h	Sat Feb 01 19:58:19 2014 +0200
   713.3 @@ -0,0 +1,26 @@
   713.4 +#ifndef GAME_H_
   713.5 +#define GAME_H_
   713.6 +
   713.7 +#include "shader.h"
   713.8 +#include "timer.h"
   713.9 +
  713.10 +extern ShaderProg *defsdr;
  713.11 +extern Timer timer;
  713.12 +
  713.13 +void game_set_args(int argc, char **argv);
  713.14 +
  713.15 +bool game_init();
  713.16 +void game_cleanup();
  713.17 +void game_display();
  713.18 +void game_reshape(int x, int y);
  713.19 +
  713.20 +void game_key(int key, bool pressed);
  713.21 +
  713.22 +int get_screen_width();
  713.23 +int get_screen_height();
  713.24 +
  713.25 +// defined by the system-glue code.
  713.26 +void request_redisplay();
  713.27 +void swap_buffers();
  713.28 +
  713.29 +#endif	// GAME_H_
   714.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   714.2 +++ b/src/geom.cc	Sat Feb 01 19:58:19 2014 +0200
   714.3 @@ -0,0 +1,252 @@
   714.4 +#include <algorithm>
   714.5 +#include <float.h>
   714.6 +#include "geom.h"
   714.7 +#include "logger.h"
   714.8 +
   714.9 +GeomObject::~GeomObject()
  714.10 +{
  714.11 +}
  714.12 +
  714.13 +
  714.14 +Sphere::Sphere()
  714.15 +{
  714.16 +	radius = 1.0;
  714.17 +}
  714.18 +
  714.19 +Sphere::Sphere(const Vector3 &cent, float radius)
  714.20 +	: center(cent)
  714.21 +{
  714.22 +	this->radius = radius;
  714.23 +}
  714.24 +
  714.25 +void Sphere::set_union(const GeomObject *obj1, const GeomObject *obj2)
  714.26 +{
  714.27 +	const Sphere *sph1 = dynamic_cast<const Sphere*>(obj1);
  714.28 +	const Sphere *sph2 = dynamic_cast<const Sphere*>(obj2);
  714.29 +
  714.30 +	if(!sph1 || !sph2) {
  714.31 +		error_log("Sphere::set_union: arguments must be spheres");
  714.32 +		return;
  714.33 +	}
  714.34 +
  714.35 +	float dist = (sph1->center - sph2->center).length();
  714.36 +	float surf_dist = dist - (sph1->radius + sph2->radius);
  714.37 +	float d1 = sph1->radius + surf_dist / 2.0;
  714.38 +	float d2 = sph2->radius + surf_dist / 2.0;
  714.39 +	float t = d1 / (d1 + d2);
  714.40 +
  714.41 +	if(t < 0.0) t = 0.0;
  714.42 +	if(t > 1.0) t = 1.0;
  714.43 +
  714.44 +	center = sph1->center * t + sph2->center * (1.0 - t);
  714.45 +	radius = std::max(dist * t + sph2->radius, dist * (1.0f - t) + sph1->radius);
  714.46 +}
  714.47 +
  714.48 +void Sphere::set_intersection(const GeomObject *obj1, const GeomObject *obj2)
  714.49 +{
  714.50 +	error_log("Sphere::intersection undefined\n");
  714.51 +}
  714.52 +
  714.53 +bool Sphere::intersect(const Ray &ray, HitPoint *hit) const
  714.54 +{
  714.55 +	float a = dot_product(ray.dir, ray.dir);
  714.56 +	float b = 2.0 * ray.dir.x * (ray.origin.x - center.x) +
  714.57 +		2.0 * ray.dir.y * (ray.origin.y - center.y) +
  714.58 +		2.0 * ray.dir.z * (ray.origin.z - center.z);
  714.59 +	float c = dot_product(ray.origin, ray.origin) + dot_product(center, center) -
  714.60 +		2.0 * dot_product(ray.origin, center) - radius * radius;
  714.61 +
  714.62 +	float discr = b * b - 4.0 * a * c;
  714.63 +	if(discr < 1e-4) {
  714.64 +		return false;
  714.65 +	}
  714.66 +
  714.67 +	float sqrt_discr = sqrt(discr);
  714.68 +	float t0 = (-b + sqrt_discr) / (2.0 * a);
  714.69 +	float t1 = (-b - sqrt_discr) / (2.0 * a);
  714.70 +
  714.71 +	if(t0 < 1e-4)
  714.72 +		t0 = t1;
  714.73 +	if(t1 < 1e-4)
  714.74 +		t1 = t0;
  714.75 +
  714.76 +	float t = t0 < t1 ? t0 : t1;
  714.77 +	if(t < 1e-4) {
  714.78 +		return false;
  714.79 +	}
  714.80 +
  714.81 +	// fill the HitPoint structure
  714.82 +	if(hit) {
  714.83 +		hit->obj = this;
  714.84 +		hit->dist = t;
  714.85 +		hit->pos = ray.origin + ray.dir * t;
  714.86 +		hit->normal = (hit->pos - center) / radius;
  714.87 +	}
  714.88 +	return true;
  714.89 +}
  714.90 +
  714.91 +
  714.92 +AABox::AABox()
  714.93 +{
  714.94 +}
  714.95 +
  714.96 +AABox::AABox(const Vector3 &vmin, const Vector3 &vmax)
  714.97 +	: min(vmin), max(vmax)
  714.98 +{
  714.99 +}
 714.100 +
 714.101 +void AABox::set_union(const GeomObject *obj1, const GeomObject *obj2)
 714.102 +{
 714.103 +	const AABox *box1 = dynamic_cast<const AABox*>(obj1);
 714.104 +	const AABox *box2 = dynamic_cast<const AABox*>(obj2);
 714.105 +
 714.106 +	if(!box1 || !box2) {
 714.107 +		error_log("AABox::set_union: arguments must be AABoxes too\n");
 714.108 +		return;
 714.109 +	}
 714.110 +
 714.111 +	min.x = std::min(box1->min.x, box2->min.x);
 714.112 +	min.y = std::min(box1->min.y, box2->min.y);
 714.113 +	min.z = std::min(box1->min.z, box2->min.z);
 714.114 +
 714.115 +	max.x = std::max(box1->max.x, box2->max.x);
 714.116 +	max.y = std::max(box1->max.y, box2->max.y);
 714.117 +	max.z = std::max(box1->max.z, box2->max.z);
 714.118 +}
 714.119 +
 714.120 +void AABox::set_intersection(const GeomObject *obj1, const GeomObject *obj2)
 714.121 +{
 714.122 +	const AABox *box1 = dynamic_cast<const AABox*>(obj1);
 714.123 +	const AABox *box2 = dynamic_cast<const AABox*>(obj2);
 714.124 +
 714.125 +	if(!box1 || !box2) {
 714.126 +		error_log("AABox::set_intersection: arguments must be AABoxes too\n");
 714.127 +		return;
 714.128 +	}
 714.129 +
 714.130 +	for(int i=0; i<3; i++) {
 714.131 +		min[i] = std::max(box1->min[i], box2->min[i]);
 714.132 +		max[i] = std::min(box1->max[i], box2->max[i]);
 714.133 +
 714.134 +		if(max[i] < min[i]) {
 714.135 +			max[i] = min[i];
 714.136 +		}
 714.137 +	}
 714.138 +}
 714.139 +
 714.140 +bool AABox::intersect(const Ray &ray, HitPoint *hit) const
 714.141 +{
 714.142 +	Vector3 param[2] = {min, max};
 714.143 +	Vector3 inv_dir(1.0 / ray.dir.x, 1.0 / ray.dir.y, 1.0 / ray.dir.z);
 714.144 +	int sign[3] = {inv_dir.x < 0, inv_dir.y < 0, inv_dir.z < 0};
 714.145 +
 714.146 +	float tmin = (param[sign[0]].x - ray.origin.x) * inv_dir.x;
 714.147 +	float tmax = (param[1 - sign[0]].x - ray.origin.x) * inv_dir.x;
 714.148 +	float tymin = (param[sign[1]].y - ray.origin.y) * inv_dir.y;
 714.149 +	float tymax = (param[1 - sign[1]].y - ray.origin.y) * inv_dir.y;
 714.150 +
 714.151 +	if(tmin > tymax || tymin > tmax) {
 714.152 +		return false;
 714.153 +	}
 714.154 +	if(tymin > tmin) {
 714.155 +		tmin = tymin;
 714.156 +	}
 714.157 +	if(tymax < tmax) {
 714.158 +		tmax = tymax;
 714.159 +	}
 714.160 +
 714.161 +	float tzmin = (param[sign[2]].z - ray.origin.z) * inv_dir.z;
 714.162 +	float tzmax = (param[1 - sign[2]].z - ray.origin.z) * inv_dir.z;
 714.163 +
 714.164 +	if(tmin > tzmax || tzmin > tmax) {
 714.165 +		return false;
 714.166 +	}
 714.167 +	if(tzmin > tmin) {
 714.168 +		tmin = tzmin;
 714.169 +	}
 714.170 +	if(tzmax < tmax) {
 714.171 +		tmax = tzmax;
 714.172 +	}
 714.173 +
 714.174 +	float t = tmin < 1e-4 ? tmax : tmin;
 714.175 +	if(t >= 1e-4) {
 714.176 +
 714.177 +		if(hit) {
 714.178 +			hit->obj = this;
 714.179 +			hit->dist = t;
 714.180 +			hit->pos = ray.origin + ray.dir * t;
 714.181 +
 714.182 +			float min_dist = FLT_MAX;
 714.183 +			Vector3 offs = min + (max - min) / 2.0;
 714.184 +			Vector3 local_hit = hit->pos - offs;
 714.185 +
 714.186 +			static const Vector3 axis[] = {
 714.187 +				Vector3(1, 0, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)
 714.188 +			};
 714.189 +			//int tcidx[][2] = {{2, 1}, {0, 2}, {0, 1}};
 714.190 +
 714.191 +			for(int i=0; i<3; i++) {
 714.192 +				float dist = fabs((max[i] - offs[i]) - fabs(local_hit[i]));
 714.193 +				if(dist < min_dist) {
 714.194 +					min_dist = dist;
 714.195 +					hit->normal = axis[i] * (local_hit[i] < 0.0 ? 1.0 : -1.0);
 714.196 +					//hit->texcoord = Vector2(hit->pos[tcidx[i][0]], hit->pos[tcidx[i][1]]);
 714.197 +				}
 714.198 +			}
 714.199 +		}
 714.200 +		return true;
 714.201 +	}
 714.202 +	return false;
 714.203 +
 714.204 +}
 714.205 +
 714.206 +Plane::Plane()
 714.207 +	: normal(0.0, 1.0, 0.0)
 714.208 +{
 714.209 +}
 714.210 +
 714.211 +Plane::Plane(const Vector3 &p, const Vector3 &norm)
 714.212 +	: pt(p)
 714.213 +{
 714.214 +	normal = norm.normalized();
 714.215 +}
 714.216 +
 714.217 +Plane::Plane(const Vector3 &p1, const Vector3 &p2, const Vector3 &p3)
 714.218 +	: pt(p1)
 714.219 +{
 714.220 +	normal = cross_product(p2 - p1, p3 - p1).normalized();
 714.221 +}
 714.222 +
 714.223 +Plane::Plane(const Vector3 &normal, float dist)
 714.224 +{
 714.225 +	this->normal = normal.normalized();
 714.226 +	pt = this->normal * dist;
 714.227 +}
 714.228 +
 714.229 +void Plane::set_union(const GeomObject *obj1, const GeomObject *obj2)
 714.230 +{
 714.231 +	error_log("Plane::set_union undefined\n");
 714.232 +}
 714.233 +
 714.234 +void Plane::set_intersection(const GeomObject *obj1, const GeomObject *obj2)
 714.235 +{
 714.236 +	error_log("Plane::set_intersection undefined\n");
 714.237 +}
 714.238 +
 714.239 +bool Plane::intersect(const Ray &ray, HitPoint *hit) const
 714.240 +{
 714.241 +	float ndotdir = dot_product(normal, ray.dir);
 714.242 +	if(fabs(ndotdir) < 1e-4) {
 714.243 +		return false;
 714.244 +	}
 714.245 +
 714.246 +	if(hit) {
 714.247 +		Vector3 ptdir = pt - ray.origin;
 714.248 +		float t = dot_product(normal, ptdir) / ndotdir;
 714.249 +
 714.250 +		hit->pos = ray.origin + ray.dir * t;
 714.251 +		hit->normal = normal;
 714.252 +		hit->obj = this;
 714.253 +	}
 714.254 +	return true;
 714.255 +}
   715.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   715.2 +++ b/src/geom.h	Sat Feb 01 19:58:19 2014 +0200
   715.3 @@ -0,0 +1,67 @@
   715.4 +#ifndef GEOMOBJ_H_
   715.5 +#define GEOMOBJ_H_
   715.6 +
   715.7 +#include "vmath/vmath.h"
   715.8 +
   715.9 +class GeomObject;
  715.10 +
  715.11 +struct HitPoint {
  715.12 +	float dist;				//< parametric distance along the ray
  715.13 +	Vector3 pos;			//< position of intersection (orig + dir * dist)
  715.14 +	Vector3 normal;			//< normal at the point of intersection
  715.15 +	const void *obj;		//< pointer to the intersected object
  715.16 +};
  715.17 +
  715.18 +class GeomObject {
  715.19 +public:
  715.20 +	virtual ~GeomObject();
  715.21 +
  715.22 +	virtual void set_union(const GeomObject *obj1, const GeomObject *obj2) = 0;
  715.23 +	virtual void set_intersection(const GeomObject *obj1, const GeomObject *obj2) = 0;
  715.24 +
  715.25 +	virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const = 0;
  715.26 +};
  715.27 +
  715.28 +class Sphere : public GeomObject {
  715.29 +public:
  715.30 +	Vector3 center;
  715.31 +	float radius;
  715.32 +
  715.33 +	Sphere();
  715.34 +	Sphere(const Vector3 &center, float radius);
  715.35 +
  715.36 +	void set_union(const GeomObject *obj1, const GeomObject *obj2);
  715.37 +	void set_intersection(const GeomObject *obj1, const GeomObject *obj2);
  715.38 +
  715.39 +	bool intersect(const Ray &ray, HitPoint *hit = 0) const;
  715.40 +};
  715.41 +
  715.42 +class AABox : public GeomObject {
  715.43 +public:
  715.44 +	Vector3 min, max;
  715.45 +
  715.46 +	AABox();
  715.47 +	AABox(const Vector3 &min, const Vector3 &max);
  715.48 +
  715.49 +	void set_union(const GeomObject *obj1, const GeomObject *obj2);
  715.50 +	void set_intersection(const GeomObject *obj1, const GeomObject *obj2);
  715.51 +
  715.52 +	bool intersect(const Ray &ray, HitPoint *hit = 0) const;
  715.53 +};
  715.54 +
  715.55 +class Plane : public GeomObject {
  715.56 +public:
  715.57 +	Vector3 pt, normal;
  715.58 +
  715.59 +	Plane();
  715.60 +	Plane(const Vector3 &pt, const Vector3 &normal);
  715.61 +	Plane(const Vector3 &p1, const Vector3 &p2, const Vector3 &p3);
  715.62 +	Plane(const Vector3 &normal, float dist);
  715.63 +
  715.64 +	void set_union(const GeomObject *obj1, const GeomObject *obj2);
  715.65 +	void set_intersection(const GeomObject *obj1, const GeomObject *obj2);
  715.66 +
  715.67 +	bool intersect(const Ray &ray, HitPoint *hit = 0) const;
  715.68 +};
  715.69 +
  715.70 +#endif	// GEOMOBJ_H_
   716.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   716.2 +++ b/src/gfxutil.cc	Sat Feb 01 19:58:19 2014 +0200
   716.3 @@ -0,0 +1,64 @@
   716.4 +#include <assert.h>
   716.5 +#include "gfxutil.h"
   716.6 +#include "mesh.h"
   716.7 +#include "meshgen.h"
   716.8 +#include "texture.h"
   716.9 +#include "shader.h"
  716.10 +#include "sdrman.h"
  716.11 +#include "opengl.h"
  716.12 +#include "logger.h"
  716.13 +
  716.14 +void draw_rect(const Vector3 &v1, const Vector3 &v2, Texture2D *tex, ShaderProg *sdr)
  716.15 +{
  716.16 +	static ShaderProg *defsdr;
  716.17 +
  716.18 +	if(!defsdr) {
  716.19 +		if(!(defsdr = get_sdrprog("defpost.v.glsl", "defpost.p.glsl"))) {
  716.20 +			static bool didlog;
  716.21 +			if(!didlog) {
  716.22 +				error_log("draw_rect: failed to load default shader\n");
  716.23 +				didlog = true;
  716.24 +			}
  716.25 +			if(!sdr) {
  716.26 +				return;
  716.27 +			}
  716.28 +		}
  716.29 +	}
  716.30 +
  716.31 +
  716.32 +	if(tex) {
  716.33 +		set_texture(tex);
  716.34 +	}
  716.35 +	if(sdr) {
  716.36 +		sdr->bind();
  716.37 +	} else {
  716.38 +		defsdr->bind();
  716.39 +
  716.40 +		assert(defsdr->get_attrib_location("attr_vertex") == MESH_ATTR_VERTEX);
  716.41 +		assert(defsdr->get_attrib_location("attr_texcoord") == MESH_ATTR_TEXCOORD);
  716.42 +	}
  716.43 +
  716.44 +
  716.45 +	float varr[] = {
  716.46 +		v1.x, v1.y, v1.z, v2.x, v1.y, v2.z,
  716.47 +		v2.x, v2.y, v2.z, v1.x, v2.y, v1.z
  716.48 +	};
  716.49 +	static const float tarr[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
  716.50 +	static const unsigned int idxarr[] = {0, 1, 2, 0, 2, 3};
  716.51 +
  716.52 +	// disable VBOs if they are enabled
  716.53 +	glBindBuffer(GL_ARRAY_BUFFER, 0);
  716.54 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  716.55 +
  716.56 +	glEnableVertexAttribArray(MESH_ATTR_VERTEX);
  716.57 +	glVertexAttribPointer(MESH_ATTR_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, varr);
  716.58 +	glEnableVertexAttribArray(MESH_ATTR_TEXCOORD);
  716.59 +	glVertexAttribPointer(MESH_ATTR_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, tarr);
  716.60 +
  716.61 +	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, idxarr);
  716.62 +
  716.63 +	glDisableVertexAttribArray(MESH_ATTR_VERTEX);
  716.64 +	glDisableVertexAttribArray(MESH_ATTR_TEXCOORD);
  716.65 +
  716.66 +	set_texture(0);
  716.67 +}
   717.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   717.2 +++ b/src/gfxutil.h	Sat Feb 01 19:58:19 2014 +0200
   717.3 @@ -0,0 +1,11 @@
   717.4 +#ifndef GFXUTIL_H_
   717.5 +#define GFXUTIL_H_
   717.6 +
   717.7 +#include <vmath/vmath.h>
   717.8 +
   717.9 +class Texture2D;
  717.10 +class ShaderProg;
  717.11 +
  717.12 +void draw_rect(const Vector3 &v1, const Vector3 &v2, Texture2D *tex = 0, ShaderProg *sdr = 0);
  717.13 +
  717.14 +#endif	// GFXUTIL_H_
   718.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   718.2 +++ b/src/image.cc	Sat Feb 01 19:58:19 2014 +0200
   718.3 @@ -0,0 +1,272 @@
   718.4 +#include <string.h>
   718.5 +
   718.6 +#ifndef _MSC_VER
   718.7 +#include <alloca.h>
   718.8 +#else
   718.9 +#include <malloc.h>
  718.10 +#endif
  718.11 +
  718.12 +#include "imago2.h"
  718.13 +#include "image.h"
  718.14 +#include "logger.h"
  718.15 +
  718.16 +static int pixel_elements(Image::Format fmt);
  718.17 +static int elem_size(Image::Format fmt);
  718.18 +static int pixel_size(Image::Format fmt);
  718.19 +
  718.20 +Image::Image()
  718.21 +{
  718.22 +	fmt = FMT_RGBA;
  718.23 +	width = height = 0;
  718.24 +	pixels = 0;
  718.25 +}
  718.26 +
  718.27 +Image::~Image()
  718.28 +{
  718.29 +	delete [] (char*)pixels;
  718.30 +}
  718.31 +
  718.32 +int Image::get_width() const
  718.33 +{
  718.34 +	return width;
  718.35 +}
  718.36 +
  718.37 +int Image::get_height() const
  718.38 +{
  718.39 +	return height;
  718.40 +}
  718.41 +
  718.42 +Image::Format Image::get_format() const
  718.43 +{
  718.44 +	return fmt;
  718.45 +}
  718.46 +
  718.47 +bool Image::create(int x, int y, Format fmt)
  718.48 +{
  718.49 +	width = x;
  718.50 +	height = y;
  718.51 +	this->fmt = fmt;
  718.52 +
  718.53 +	try {
  718.54 +		pixels = new char[x * y * pixel_size(fmt)];
  718.55 +	}
  718.56 +	catch(...) {
  718.57 +		return false;
  718.58 +	}
  718.59 +	return true;
  718.60 +}
  718.61 +
  718.62 +bool Image::set_pixels(int xsz, int ysz, void *pixels, Format fmt)
  718.63 +{
  718.64 +	if(!create(xsz, ysz, fmt)) {
  718.65 +		return false;
  718.66 +	}
  718.67 +	memcpy(this->pixels, pixels, xsz * ysz * pixel_size(fmt));
  718.68 +	return true;
  718.69 +}
  718.70 +
  718.71 +bool Image::set_pixels(int xsz, int ysz, void *pixels, int scan_width, Format fmt)
  718.72 +{
  718.73 +	return set_pixels(xsz, ysz, pixels, 0, 0, scan_width, fmt);
  718.74 +}
  718.75 +
  718.76 +bool Image::set_pixels(int xsz, int ysz, void *pixels, int x, int y, int scan_width, Format fmt)
  718.77 +{
  718.78 +	if(scan_width <= 0) {
  718.79 +		scan_width = xsz;
  718.80 +	}
  718.81 +
  718.82 +	if(!create(xsz, ysz, fmt)) {
  718.83 +		return false;
  718.84 +	}
  718.85 +
  718.86 +	int pixsz = pixel_size(fmt);
  718.87 +
  718.88 +	unsigned char *dest = (unsigned char*)this->pixels;
  718.89 +	unsigned char *src = (unsigned char*)pixels + (y * scan_width + x) * pixsz;
  718.90 +	for(int i=0; i<ysz; i++) {
  718.91 +		memcpy(dest, src, xsz * pixsz);
  718.92 +		dest += xsz * pixsz;
  718.93 +		src += scan_width * pixsz;
  718.94 +	}
  718.95 +	return true;
  718.96 +}
  718.97 +
  718.98 +void *Image::get_pixels() const
  718.99 +{
 718.100 +	return pixels;
 718.101 +}
 718.102 +
 718.103 +void Image::flip_horizontal()
 718.104 +{
 718.105 +	int pixsz = pixel_size(fmt);
 718.106 +
 718.107 +	unsigned char *tmppix = (unsigned char*)alloca(pixsz);
 718.108 +
 718.109 +	unsigned char *scan = (unsigned char*)pixels;
 718.110 +	for(int i=0; i<height; i++) {
 718.111 +		unsigned char *dest = scan;
 718.112 +		unsigned char *src = scan + (width - 1) * pixsz;
 718.113 +
 718.114 +		while(src > dest) {
 718.115 +			memcpy(tmppix, src, pixsz);
 718.116 +			memcpy(src, dest, pixsz);
 718.117 +			memcpy(dest, tmppix, pixsz);
 718.118 +			dest += pixsz;
 718.119 +			src -= pixsz;
 718.120 +		}
 718.121 +
 718.122 +		scan += width * pixsz;
 718.123 +	}
 718.124 +}
 718.125 +
 718.126 +void Image::flip_vertical()
 718.127 +{
 718.128 +	int pixsz = pixel_size(fmt);
 718.129 +
 718.130 +	unsigned char *tmpscan = (unsigned char*)alloca(width * pixsz);
 718.131 +
 718.132 +	unsigned char *dest = (unsigned char*)pixels;
 718.133 +	unsigned char *src = (unsigned char*)pixels + (height - 1) * width * pixsz;
 718.134 +
 718.135 +	while(src > dest) {
 718.136 +		memcpy(tmpscan, src, width * pixsz);
 718.137 +		memcpy(src, dest, width * pixsz);
 718.138 +		memcpy(dest, tmpscan, width * pixsz);
 718.139 +		dest += width * pixsz;
 718.140 +		src -= width * pixsz;
 718.141 +	}
 718.142 +}
 718.143 +
 718.144 +void Image::rotate_180()
 718.145 +{
 718.146 +	flip_vertical();
 718.147 +	flip_horizontal();
 718.148 +}
 718.149 +
 718.150 +bool Image::load(const char *fname)
 718.151 +{
 718.152 +	struct img_pixmap pixmap;
 718.153 +
 718.154 +	img_init(&pixmap);
 718.155 +	if(img_load(&pixmap, fname) == -1) {
 718.156 +		return false;
 718.157 +	}
 718.158 +
 718.159 +	Format fmt;
 718.160 +	switch(pixmap.fmt) {
 718.161 +	case IMG_FMT_GREY8:
 718.162 +		fmt = FMT_GREY;
 718.163 +		break;
 718.164 +	case IMG_FMT_RGB24:
 718.165 +		fmt = FMT_RGB;
 718.166 +		break;
 718.167 +	case IMG_FMT_RGBA32:
 718.168 +		fmt = FMT_RGBA;
 718.169 +		break;
 718.170 +	case IMG_FMT_GREYF:
 718.171 +		fmt = FMT_GREY_FLOAT;
 718.172 +		break;
 718.173 +	case IMG_FMT_RGBF:
 718.174 +		fmt = FMT_RGB_FLOAT;
 718.175 +		break;
 718.176 +	case IMG_FMT_RGBAF:
 718.177 +		fmt = FMT_RGBA_FLOAT;
 718.178 +		break;
 718.179 +	default:
 718.180 +		img_destroy(&pixmap);
 718.181 +		return false;
 718.182 +	}
 718.183 +
 718.184 +	if(!set_pixels(pixmap.width, pixmap.height, pixmap.pixels, fmt)) {
 718.185 +		img_destroy(&pixmap);
 718.186 +		return false;
 718.187 +	}
 718.188 +	img_destroy(&pixmap);
 718.189 +	return true;
 718.190 +}
 718.191 +
 718.192 +bool Image::save(const char *fname) const
 718.193 +{
 718.194 +	struct img_pixmap pixmap;
 718.195 +
 718.196 +	img_init(&pixmap);
 718.197 +
 718.198 +	switch(fmt) {
 718.199 +	case FMT_GREY:
 718.200 +		pixmap.fmt = IMG_FMT_GREY8;
 718.201 +		break;
 718.202 +	case FMT_GREY_FLOAT:
 718.203 +		pixmap.fmt = IMG_FMT_GREYF;
 718.204 +		break;
 718.205 +	case FMT_RGB:
 718.206 +		pixmap.fmt = IMG_FMT_RGB24;
 718.207 +		break;
 718.208 +	case FMT_RGB_FLOAT:
 718.209 +		pixmap.fmt = IMG_FMT_RGBF;
 718.210 +		break;
 718.211 +	case FMT_RGBA:
 718.212 +		pixmap.fmt = IMG_FMT_RGBA32;
 718.213 +		break;
 718.214 +	case FMT_RGBA_FLOAT:
 718.215 +		pixmap.fmt = IMG_FMT_RGBAF;
 718.216 +		break;
 718.217 +	default:
 718.218 +		return false;
 718.219 +	}
 718.220 +
 718.221 +	pixmap.width = width;
 718.222 +	pixmap.height = height;
 718.223 +	pixmap.pixels = pixels;
 718.224 +	pixmap.pixelsz = pixel_size(fmt);
 718.225 +
 718.226 +	if(img_save(&pixmap, fname) == -1) {
 718.227 +		return false;
 718.228 +	}
 718.229 +	return true;
 718.230 +}
 718.231 +
 718.232 +static int pixel_elements(Image::Format fmt)
 718.233 +{
 718.234 +	switch(fmt) {
 718.235 +	case Image::FMT_GREY:
 718.236 +	case Image::FMT_GREY_FLOAT:
 718.237 +		return 1;
 718.238 +
 718.239 +	case Image::FMT_RGB:
 718.240 +	case Image::FMT_RGB_FLOAT:
 718.241 +		return 3;
 718.242 +
 718.243 +	case Image::FMT_RGBA:
 718.244 +	case Image::FMT_RGBA_FLOAT:
 718.245 +		return 4;
 718.246 +
 718.247 +	default:
 718.248 +		break;
 718.249 +	}
 718.250 +	return 0;
 718.251 +}
 718.252 +
 718.253 +static int elem_size(Image::Format fmt)
 718.254 +{
 718.255 +	switch(fmt) {
 718.256 +	case Image::FMT_GREY:
 718.257 +	case Image::FMT_RGB:
 718.258 +	case Image::FMT_RGBA:
 718.259 +		return 1;
 718.260 +
 718.261 +	case Image::FMT_GREY_FLOAT:
 718.262 +	case Image::FMT_RGB_FLOAT:
 718.263 +	case Image::FMT_RGBA_FLOAT:
 718.264 +		return sizeof(float);
 718.265 +
 718.266 +	default:
 718.267 +		break;
 718.268 +	}
 718.269 +	return 0;
 718.270 +}
 718.271 +
 718.272 +static int pixel_size(Image::Format fmt)
 718.273 +{
 718.274 +	return elem_size(fmt) * pixel_elements(fmt);
 718.275 +}
   719.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   719.2 +++ b/src/image.h	Sat Feb 01 19:58:19 2014 +0200
   719.3 @@ -0,0 +1,43 @@
   719.4 +#ifndef IMAGE_H_
   719.5 +#define IMAGE_H_
   719.6 +
   719.7 +class Image {
   719.8 +public:
   719.9 +	enum Format {
  719.10 +		FMT_GREY,
  719.11 +		FMT_RGB,
  719.12 +		FMT_RGBA,
  719.13 +		FMT_GREY_FLOAT,
  719.14 +		FMT_RGB_FLOAT,
  719.15 +		FMT_RGBA_FLOAT
  719.16 +	};
  719.17 +
  719.18 +private:
  719.19 +	Format fmt;
  719.20 +	int width, height;
  719.21 +	void *pixels;
  719.22 +
  719.23 +public:
  719.24 +	Image();
  719.25 +	~Image();
  719.26 +
  719.27 +	int get_width() const;
  719.28 +	int get_height() const;
  719.29 +
  719.30 +	Format get_format() const;
  719.31 +
  719.32 +	bool create(int x, int y, Format fmt = FMT_RGBA);
  719.33 +	bool set_pixels(int xsz, int ysz, void *pixels, Format fmt = FMT_RGBA);
  719.34 +	bool set_pixels(int xsz, int ysz, void *pixels, int scan_width, Format fmt = FMT_RGBA);
  719.35 +	bool set_pixels(int xsz, int ysz, void *pixels, int x, int y, int scan_width = -1, Format fmt = FMT_RGBA);
  719.36 +	void *get_pixels() const;
  719.37 +
  719.38 +	void flip_horizontal();
  719.39 +	void flip_vertical();
  719.40 +	void rotate_180();
  719.41 +
  719.42 +	bool load(const char *fname);
  719.43 +	bool save(const char *fname) const;
  719.44 +};
  719.45 +
  719.46 +#endif	// IMAGE_H_
   720.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   720.2 +++ b/src/input.cc	Sat Feb 01 19:58:19 2014 +0200
   720.3 @@ -0,0 +1,84 @@
   720.4 +#include <vector>
   720.5 +#include <bitset>
   720.6 +#include "input.h"
   720.7 +#include "logger.h"
   720.8 +
   720.9 +#define NUM_KEYS	65536
  720.10 +static std::bitset<NUM_KEYS> keystate;
  720.11 +
  720.12 +void set_key_state(int key, bool state)
  720.13 +{
  720.14 +	if(key < 0 || key >= NUM_KEYS) {
  720.15 +		error_log("set_key_state: key (%d) out of bounds\n", key);
  720.16 +		return;
  720.17 +	}
  720.18 +	keystate[key] = state;
  720.19 +}
  720.20 +
  720.21 +bool get_key_state(int key)
  720.22 +{
  720.23 +	if(key < 0 || key >= NUM_KEYS) {
  720.24 +		error_log("get_key_state: key (%d) out of bounds\n", key);
  720.25 +		return false;
  720.26 +	}
  720.27 +	return keystate[key];
  720.28 +}
  720.29 +
  720.30 +struct ButtonState {
  720.31 +	bool pressed;
  720.32 +	int press_x, press_y;
  720.33 +};
  720.34 +static std::vector<ButtonState> bnstate(16);
  720.35 +#define MAX_BNSTATE		128
  720.36 +static int mouse_x, mouse_y;
  720.37 +
  720.38 +void set_mouse_state(int x, int y, int bn, bool state)
  720.39 +{
  720.40 +	mouse_x = x;
  720.41 +	mouse_y = y;
  720.42 +
  720.43 +	if(bn < 0 || bn >= MAX_BNSTATE) {
  720.44 +		return;
  720.45 +	}
  720.46 +	if((size_t)bn >= bnstate.size()) {
  720.47 +		bnstate.resize(bn + 1);
  720.48 +	}
  720.49 +
  720.50 +	bnstate[bn].pressed = state;
  720.51 +	if(state) {
  720.52 +		bnstate[bn].press_x = x;
  720.53 +		bnstate[bn].press_y = y;
  720.54 +	}
  720.55 +}
  720.56 +
  720.57 +bool mouse_button(int bn)
  720.58 +{
  720.59 +	if(bn < 0 || (size_t)bn >= bnstate.size()) {
  720.60 +		return false;
  720.61 +	}
  720.62 +	return bnstate[bn].pressed;
  720.63 +}
  720.64 +
  720.65 +bool mouse_dragging(int bn)
  720.66 +{
  720.67 +	if(bn < 0 || (size_t)bn >= bnstate.size()) {
  720.68 +		return false;
  720.69 +	}
  720.70 +
  720.71 +	return bnstate[bn].pressed && mouse_x != bnstate[bn].press_x &&
  720.72 +		mouse_y != bnstate[bn].press_y;
  720.73 +}
  720.74 +
  720.75 +bool mouse_drag_origin(int bn, int *xorig, int *yorig)
  720.76 +{
  720.77 +	if(!mouse_dragging()) {
  720.78 +		// this also handles bound issues, no need to recheck
  720.79 +		*xorig = mouse_x;
  720.80 +		*yorig = mouse_y;
  720.81 +		return false;
  720.82 +	}
  720.83 +
  720.84 +	*xorig = bnstate[bn].press_x;
  720.85 +	*yorig = bnstate[bn].press_y;
  720.86 +	return true;
  720.87 +}
   721.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   721.2 +++ b/src/input.h	Sat Feb 01 19:58:19 2014 +0200
   721.3 @@ -0,0 +1,69 @@
   721.4 +#ifndef INPUT_H_
   721.5 +#define INPUT_H_
   721.6 +
   721.7 +/// special (non-alpharithmetic/ascii) key enums
   721.8 +enum {
   721.9 +	KEY_PAUSE		= 0xff13,	// XK_Pause
  721.10 +	KEY_SCRLOCK		= 0xff14,	// XK_Scroll_Lock
  721.11 +	KEY_PRINTSCR	= 0xff15,	// XK_Sys_Req
  721.12 +
  721.13 +	KEY_HOME		= 0xff50,	// XK_Home
  721.14 +	KEY_LEFT		= 0xff51,	// XK_Left
  721.15 +	KEY_UP			= 0xff52,	// XK_Up
  721.16 +	KEY_RIGHT		= 0xff53,	// XK_Right
  721.17 +	KEY_DOWN		= 0xff54,	// XK_Down
  721.18 +	KEY_PGUP		= 0xff55,	// XK_Page_Up
  721.19 +	KEY_PGDOWN		= 0xff56,	// XK_Page_Down
  721.20 +	KEY_END			= 0xff57,	// XK_End
  721.21 +
  721.22 +	KEY_INSERT		= 0xff63,	// XK_Insert
  721.23 +
  721.24 +	KEY_F1			= 0xffbe,	// XK_F1
  721.25 +	KEY_F2			= 0xffbf,	// XK_F2
  721.26 +	KEY_F3			= 0xffc0,	// XK_F3
  721.27 +	KEY_F4			= 0xffc1,	// XK_F4
  721.28 +	KEY_F5			= 0xffc2,	// XK_F5
  721.29 +	KEY_F6			= 0xffc3,	// XK_F6
  721.30 +	KEY_F7			= 0xffc4,	// XK_F7
  721.31 +	KEY_F8			= 0xffc5,	// XK_F8
  721.32 +	KEY_F9			= 0xffc6,	// XK_F9
  721.33 +	KEY_F10			= 0xffc7,	// XK_F10
  721.34 +	KEY_F11			= 0xffc8,	// XK_F11
  721.35 +	KEY_F12			= 0xffc9,	// XK_F12
  721.36 +
  721.37 +	KEY_LSHIFT		= 0xffe1,	// XK_Shift_L
  721.38 +	KEY_RSHIFT		= 0xffe2,	// XK_Shift_R
  721.39 +	KEY_LCTRL		= 0xffe3,	// XK_Control_L
  721.40 +	KEY_RCTRL		= 0xffe4,	// XK_Control_R
  721.41 +	KEY_CAPSLOCK	= 0xffe5,	// XK_Caps_Lock
  721.42 +	KEY_SHIFTLOCK	= 0xffe6,	// XK_Shift_Lock
  721.43 +	KEY_LMETA		= 0xffe7,	// XK_Meta_L
  721.44 +	KEY_RMETA		= 0xffe8,	// XK_Meta_R
  721.45 +	KEY_LALT		= 0xffe9,	// XK_Alt_L
  721.46 +	KEY_RALT		= 0xffea,	// XK_Alt_R
  721.47 +
  721.48 +	KEY_DELETE		= 0xffff	// XK_Delete
  721.49 +};
  721.50 +
  721.51 +// aliases
  721.52 +enum {
  721.53 +	KEY_ALT = KEY_LALT,
  721.54 +	KEY_CTRL = KEY_LCTRL,
  721.55 +	KEY_SHIFT = KEY_LSHIFT
  721.56 +};
  721.57 +
  721.58 +void set_key_state(int key, bool state);
  721.59 +bool get_key_state(int key);
  721.60 +
  721.61 +
  721.62 +void set_mouse_state(int x, int y, int bn = -1, bool state = false);
  721.63 +
  721.64 +bool mouse_button(int bn = 0);
  721.65 +
  721.66 +/// are we in the middle of a mouse-drag ? (pressed and moved)
  721.67 +/// only valid between a mouse press and mouse release event
  721.68 +bool mouse_dragging(int bn = 0);
  721.69 +
  721.70 +bool mouse_drag_origin(int bn, int *xorig, int *yorig);
  721.71 +
  721.72 +#endif	// INPUT_H_
   722.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   722.2 +++ b/src/ios/app_delegate.h	Sat Feb 01 19:58:19 2014 +0200
   722.3 @@ -0,0 +1,10 @@
   722.4 +#import <UIKit/UIKit.h>
   722.5 +
   722.6 +@class GLView;
   722.7 +
   722.8 +@interface AppDelegate : NSObject <UIApplicationDelegate> {
   722.9 +    UIWindow *window;
  722.10 +    GLView *glview;
  722.11 +}
  722.12 +
  722.13 +@end
   723.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   723.2 +++ b/src/ios/app_delegate.m	Sat Feb 01 19:58:19 2014 +0200
   723.3 @@ -0,0 +1,44 @@
   723.4 +#import "app_delegate.h"
   723.5 +#import "glview.h"
   723.6 +
   723.7 +@implementation AppDelegate
   723.8 +
   723.9 +- (BOOL)application: (UIApplication*)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
  723.10 +{
  723.11 +	window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] applicationFrame]];
  723.12 +	glview = [[GLView alloc] initWithFrame: window.frame];
  723.13 +	
  723.14 +	[window addSubview: glview];
  723.15 +	[window makeKeyAndVisible];
  723.16 +	
  723.17 +	//window.rootViewController = [[UIViewController alloc] init];
  723.18 +	
  723.19 +    [glview startAnimation];
  723.20 +    return YES;
  723.21 +}
  723.22 +
  723.23 +- (void)applicationWillResignActive: (UIApplication*)application
  723.24 +{
  723.25 +    [glview stopAnimation];
  723.26 +}
  723.27 +
  723.28 +- (void)applicationDidBecomeActive: (UIApplication*)application
  723.29 +{
  723.30 +    [glview startAnimation];
  723.31 +}
  723.32 +
  723.33 +- (void)applicationWillTerminate: (UIApplication*)application
  723.34 +{
  723.35 +    [glview stopAnimation];
  723.36 +}
  723.37 +
  723.38 +- (void)dealloc
  723.39 +{
  723.40 +	//[window.rootViewController dealloc];
  723.41 +    [window release];
  723.42 +    [glview release];
  723.43 +
  723.44 +    [super dealloc];
  723.45 +}
  723.46 +
  723.47 +@end
   724.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   724.2 +++ b/src/ios/glview.h	Sat Feb 01 19:58:19 2014 +0200
   724.3 @@ -0,0 +1,34 @@
   724.4 +#import <UIKit/UIKit.h>
   724.5 +#import <QuartzCore/QuartzCore.h>
   724.6 +
   724.7 +#import <OpenGLES/ES2/gl.h>
   724.8 +#import <OpenGLES/ES2/glext.h>
   724.9 +
  724.10 +@interface GLView : UIView
  724.11 +{
  724.12 +@private
  724.13 +	int xsz, ysz;
  724.14 +	EAGLContext *context;
  724.15 +
  724.16 +	unsigned int fbo, rbuf_color, rbuf_depth;
  724.17 +
  724.18 +	BOOL animating;
  724.19 +	BOOL display_link_supported;
  724.20 +	NSInteger anim_frame_interval;
  724.21 +	// Use of the CADisplayLink class is the preferred method for controlling your animation timing.
  724.22 +	// CADisplayLink will link to the main display and fire every vsync when added to a given run-loop.
  724.23 +	// The NSTimer class is used only as fallback when running on a pre 3.1 device where CADisplayLink
  724.24 +	// isn't available.
  724.25 +	id display_link;
  724.26 +	NSTimer *anim_timer;
  724.27 +}
  724.28 +
  724.29 +@property (readonly, nonatomic, getter=isAnimating) BOOL animating;
  724.30 +@property (nonatomic) NSInteger anim_frame_interval;
  724.31 +
  724.32 +- (void)startAnimation;
  724.33 +- (void)stopAnimation;
  724.34 +- (void)drawView: (id)sender;
  724.35 +- (void)swap_buffers;
  724.36 +
  724.37 +@end
   725.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   725.2 +++ b/src/ios/glview.mm	Sat Feb 01 19:58:19 2014 +0200
   725.3 @@ -0,0 +1,261 @@
   725.4 +#import "glview.h"
   725.5 +#include "game.h"
   725.6 +#include "screen.h"
   725.7 +#include "logger.h"
   725.8 +
   725.9 +unsigned int default_fbo;
  725.10 +
  725.11 +static GLView *view;
  725.12 +
  725.13 +void request_redisplay()
  725.14 +{
  725.15 +	// TODO
  725.16 +}
  725.17 +
  725.18 +void swap_buffers()
  725.19 +{
  725.20 +	if(view) {
  725.21 +		[view swap_buffers];
  725.22 +	}
  725.23 +}
  725.24 +
  725.25 +
  725.26 +@implementation GLView
  725.27 +
  725.28 +@synthesize animating;
  725.29 +@dynamic anim_frame_interval;
  725.30 +
  725.31 +// You must implement this method
  725.32 ++ (Class)layerClass
  725.33 +{
  725.34 +	return [CAEAGLLayer class];
  725.35 +}
  725.36 +
  725.37 +
  725.38 +- (id)initWithFrame: (CGRect) frame
  725.39 +{
  725.40 +	if((self = [super initWithFrame: frame]))
  725.41 +	{
  725.42 +		// Get the layer
  725.43 +		CAEAGLLayer *eaglLayer = (CAEAGLLayer*)self.layer;
  725.44 +
  725.45 +		//self.contentScaleFactor = 2.0;
  725.46 +
  725.47 +		eaglLayer.opaque = TRUE;
  725.48 +		eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:FALSE],
  725.49 +				kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8,
  725.50 +				kEAGLDrawablePropertyColorFormat, nil];
  725.51 +
  725.52 +		// initialize OpenGL ES context
  725.53 +		context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
  725.54 +		if(!context || ![EAGLContext setCurrentContext: context]) {
  725.55 +			[self release];
  725.56 +			return self;
  725.57 +		}
  725.58 +
  725.59 +		// create the framebuffer
  725.60 +		glGenFramebuffers(1, &fbo);
  725.61 +		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  725.62 +
  725.63 +		glGenRenderbuffers(1, &rbuf_color);
  725.64 +		glBindRenderbuffer(GL_RENDERBUFFER, rbuf_color);
  725.65 +		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbuf_color);
  725.66 +
  725.67 +		glGenRenderbuffers(1, &rbuf_depth);
  725.68 +		glBindRenderbuffer(GL_RENDERBUFFER, rbuf_depth);
  725.69 +		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth);
  725.70 +
  725.71 +		default_fbo = fbo;
  725.72 +
  725.73 +		animating = FALSE;
  725.74 +		display_link_supported = FALSE;
  725.75 +		anim_frame_interval = 1;
  725.76 +		display_link = nil;
  725.77 +		anim_timer = nil;
  725.78 +
  725.79 +		// A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
  725.80 +		// class is used as fallback when it isn't available.
  725.81 +		NSString *reqSysVer = @"3.1";
  725.82 +		NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
  725.83 +		if([currSysVer compare: reqSysVer options: NSNumericSearch] != NSOrderedAscending) {
  725.84 +			display_link_supported = TRUE;
  725.85 +		}
  725.86 +
  725.87 +		self.multipleTouchEnabled = 1;
  725.88 +
  725.89 +		if(!game_init()) {
  725.90 +			exit(1);
  725.91 +		}
  725.92 +	}
  725.93 +
  725.94 +	view = self;
  725.95 +	return self;
  725.96 +}
  725.97 +
  725.98 +- (void)drawView: (id)sender
  725.99 +{
 725.100 +	game_display();
 725.101 +}
 725.102 +
 725.103 +- (void)swap_buffers
 725.104 +{
 725.105 +	glBindRenderbuffer(GL_RENDERBUFFER, rbuf_color);
 725.106 +	[context presentRenderbuffer: GL_RENDERBUFFER];
 725.107 +}
 725.108 +
 725.109 +- (BOOL)resize: (CAEAGLLayer*)layer
 725.110 +{
 725.111 +	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 725.112 +
 725.113 +	glBindRenderbuffer(GL_RENDERBUFFER, rbuf_color);
 725.114 +	[context renderbufferStorage: GL_RENDERBUFFER fromDrawable: layer];
 725.115 +	glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &xsz);
 725.116 +	glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &ysz);
 725.117 +
 725.118 +	glBindRenderbuffer(GL_RENDERBUFFER, rbuf_depth);
 725.119 +	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, xsz, ysz);
 725.120 +
 725.121 +	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
 725.122 +		error_log("resize failed, framebuffer incomplete\n");
 725.123 +		return FALSE;
 725.124 +	}
 725.125 +	assert(glGetError() == GL_NO_ERROR);
 725.126 +
 725.127 +	game_reshape(xsz, ysz);
 725.128 +	return TRUE;
 725.129 +}
 725.130 +
 725.131 +- (void)layoutSubviews
 725.132 +{
 725.133 +	[self resize: (CAEAGLLayer*)self.layer];
 725.134 +	[self drawView:nil];
 725.135 +}
 725.136 +
 725.137 +- (NSInteger)anim_frame_interval
 725.138 +{
 725.139 +	return anim_frame_interval;
 725.140 +}
 725.141 +
 725.142 +- (void)setAnimationFrameInterval: (NSInteger)frameInterval
 725.143 +{
 725.144 +	// Frame interval defines how many display frames must pass between each time the
 725.145 +	// display link fires. The display link will only fire 30 times a second when the
 725.146 +	// frame internal is two on a display that refreshes 60 times a second. The default
 725.147 +	// frame interval setting of one will fire 60 times a second when the display refreshes
 725.148 +	// at 60 times a second. A frame interval setting of less than one results in undefined
 725.149 +	// behavior.
 725.150 +	if(frameInterval >= 1) {
 725.151 +		anim_frame_interval = frameInterval;
 725.152 +
 725.153 +		if(animating) {
 725.154 +			[self stopAnimation];
 725.155 +			[self startAnimation];
 725.156 +		}
 725.157 +	}
 725.158 +}
 725.159 +
 725.160 +- (void)startAnimation
 725.161 +{
 725.162 +	if(!animating) {
 725.163 +		if(display_link_supported) {
 725.164 +			// CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
 725.165 +			// if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
 725.166 +			// not be called in system versions earlier than 3.1.
 725.167 +
 725.168 +			display_link = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)];
 725.169 +			[display_link setFrameInterval: anim_frame_interval];
 725.170 +			[display_link addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];
 725.171 +		} else {
 725.172 +			anim_timer = [NSTimer scheduledTimerWithTimeInterval: (NSTimeInterval)((1.0 / 60.0) * anim_frame_interval)
 725.173 +					target: self selector: @selector(drawView:) userInfo: nil repeats: TRUE];
 725.174 +		}
 725.175 +
 725.176 +		animating = TRUE;
 725.177 +	}
 725.178 +}
 725.179 +
 725.180 +- (void)stopAnimation
 725.181 +{
 725.182 +	if(animating) {
 725.183 +		if(display_link_supported) {
 725.184 +			[display_link invalidate];
 725.185 +			display_link = nil;
 725.186 +		} else {
 725.187 +			[anim_timer invalidate];
 725.188 +			anim_timer = nil;
 725.189 +		}
 725.190 +
 725.191 +		animating = FALSE;
 725.192 +	}
 725.193 +}
 725.194 +
 725.195 +- (void)dealloc
 725.196 +{
 725.197 +	game_cleanup();
 725.198 +
 725.199 +	if(fbo) {
 725.200 +		glDeleteFramebuffers(1, &fbo);
 725.201 +		fbo = 0;
 725.202 +		default_fbo = 0;
 725.203 +	}
 725.204 +	if(rbuf_color) {
 725.205 +		glDeleteRenderbuffers(1, &rbuf_color);
 725.206 +		rbuf_color = 0;
 725.207 +	}
 725.208 +	if(rbuf_depth) {
 725.209 +		glDeleteRenderbuffers(1, &rbuf_depth);
 725.210 +		rbuf_depth = 0;
 725.211 +	}
 725.212 +
 725.213 +	if([EAGLContext currentContext] == context) {
 725.214 +		[EAGLContext setCurrentContext: nil];
 725.215 +	}
 725.216 +	[context release];
 725.217 +	context = nil;
 725.218 +
 725.219 +	[super dealloc];
 725.220 +}
 725.221 +
 725.222 +#define MOUSEX(x)	((int)((x) * xsz / 320.0))
 725.223 +#define MOUSEY(y)	((int)((y) * ysz / 480.0))
 725.224 +static bool bn_pressed;
 725.225 +
 725.226 +- (void)touchesBegan: (NSSet*)touches withEvent: (UIEvent*)event
 725.227 +{
 725.228 +	UITouch *touch = [[touches allObjects] objectAtIndex: 0];
 725.229 +	CGPoint pt = [touch locationInView: self];
 725.230 +
 725.231 +	int x = MOUSEX(pt.x);
 725.232 +	int y = MOUSEY(pt.y);
 725.233 +	current_screen()->button(0, true, x, y);
 725.234 +
 725.235 +	bn_pressed = true;
 725.236 +}
 725.237 +
 725.238 +- (void)touchesMoved: (NSSet*)touches withEvent: (UIEvent*)event
 725.239 +{
 725.240 +	UITouch *touch = [[touches allObjects] objectAtIndex: 0];
 725.241 +	CGPoint pt = [touch locationInView: self];
 725.242 +
 725.243 +	int x = MOUSEX(pt.x);
 725.244 +	int y = MOUSEY(pt.y);
 725.245 +	current_screen()->motion(x, y, bn_pressed);
 725.246 +}
 725.247 +
 725.248 +- (void)touchesEnded: (NSSet*)touches withEvent: (UIEvent*)event
 725.249 +{
 725.250 +	UITouch *touch = [[touches allObjects] objectAtIndex: 0];
 725.251 +	CGPoint pt = [touch locationInView: self];
 725.252 +
 725.253 +	int x = MOUSEX(pt.x);
 725.254 +	int y = MOUSEY(pt.y);
 725.255 +	current_screen()->button(0, false, x, y);
 725.256 +	bn_pressed = false;
 725.257 +}
 725.258 +
 725.259 +- (void)touchesCancelled: (NSSet*)touches withEvent: (UIEvent*)event
 725.260 +{
 725.261 +	[self touchesEnded: touches withEvent: event];
 725.262 +}
 725.263 +
 725.264 +@end
   726.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   726.2 +++ b/src/ios/main.m	Sat Feb 01 19:58:19 2014 +0200
   726.3 @@ -0,0 +1,10 @@
   726.4 +#import <UIKit/UIKit.h>
   726.5 +#import "app_delegate.h"
   726.6 +
   726.7 +int main(int argc, char **argv)
   726.8 +{
   726.9 +	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  726.10 +	int retval = UIApplicationMain(argc, argv, nil, @"AppDelegate");
  726.11 +	[pool release];
  726.12 +	return retval;
  726.13 +}
   727.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   727.2 +++ b/src/level.cc	Sat Feb 01 19:58:19 2014 +0200
   727.3 @@ -0,0 +1,89 @@
   727.4 +#include "level.h"
   727.5 +#include "logger.h"
   727.6 +
   727.7 +static void gen_mesh(Mesh *mesh);
   727.8 +
   727.9 +Level::Level()
  727.10 +{
  727.11 +	dlimit_near = -2;
  727.12 +	dlimit_far = 8;
  727.13 +
  727.14 +	gen_mesh(&tile_mesh);
  727.15 +
  727.16 +	tile_obj = new Object;
  727.17 +	tile_obj->set_mesh(&tile_mesh);
  727.18 +}
  727.19 +
  727.20 +Level::~Level()
  727.21 +{
  727.22 +	delete tile_obj;
  727.23 +}
  727.24 +
  727.25 +void Level::set_draw_limits(float dnear, float dfar)
  727.26 +{
  727.27 +	dlimit_near = dnear;
  727.28 +	dlimit_far = dfar;
  727.29 +}
  727.30 +
  727.31 +void Level::draw() const
  727.32 +{
  727.33 +	AABox bbox = tile_obj->get_aabbox();
  727.34 +	float zsize = bbox.max.z - bbox.min.z;
  727.35 +	float zoffs = -zsize / 2.0;
  727.36 +
  727.37 +	float z = dlimit_near;
  727.38 +	while(z < dlimit_far) {
  727.39 +		tile_obj->set_position(Vector3(0, 0, -(z - zoffs)));
  727.40 +		tile_obj->draw();
  727.41 +		z += zsize;
  727.42 +	}
  727.43 +}
  727.44 +
  727.45 +static void gen_mesh(Mesh *mesh)
  727.46 +{
  727.47 +	/* left vertical side */
  727.48 +	mesh->normal(1, 0, 0);
  727.49 +	mesh->texcoord(0, 0); mesh->vertex(-2, 0, 1);
  727.50 +	mesh->texcoord(1, 0); mesh->vertex(-2, 0, -1);
  727.51 +	mesh->texcoord(1, 1); mesh->vertex(-2, 1, -1);
  727.52 +	mesh->texcoord(0, 1); mesh->vertex(-2, 1, 1);
  727.53 +
  727.54 +	/* left diagonal */
  727.55 +	Vector3 dnorm = Vector3(0.5, 1, 0).normalized();
  727.56 +	mesh->normal(dnorm.x, dnorm.y, dnorm.z);
  727.57 +	mesh->texcoord(0, 0); mesh->vertex(-1, -0.5, 1);
  727.58 +	mesh->texcoord(1, 0); mesh->vertex(-1, -0.5, -1);
  727.59 +	mesh->texcoord(1, 1); mesh->vertex(-2, 0, -1);
  727.60 +	mesh->texcoord(0, 1); mesh->vertex(-2, 0, 1);
  727.61 +
  727.62 +	/* floor */
  727.63 +	mesh->normal(0, 1, 0);
  727.64 +	mesh->texcoord(0, 0); mesh->vertex(-1, -0.5, 1);
  727.65 +	mesh->texcoord(1, 0); mesh->vertex(1, -0.5, 1);
  727.66 +	mesh->texcoord(1, 1); mesh->vertex(1, -0.5, -1);
  727.67 +	mesh->texcoord(0, 1); mesh->vertex(-1, -0.5, -1);
  727.68 +
  727.69 +	/* right vertical side */
  727.70 +	mesh->normal(-1, 0, 0);
  727.71 +	mesh->texcoord(0, 0); mesh->vertex(2, 0, -1);
  727.72 +	mesh->texcoord(1, 0); mesh->vertex(2, 0, 1);
  727.73 +	mesh->texcoord(1, 1); mesh->vertex(2, 1, 1);
  727.74 +	mesh->texcoord(0, 1); mesh->vertex(2, 1, -1);
  727.75 +
  727.76 +	/* right diagonal */
  727.77 +	dnorm = Vector3(-0.5, 1, 0).normalized();
  727.78 +	mesh->normal(dnorm.x, dnorm.y, dnorm.z);
  727.79 +	mesh->texcoord(0, 0); mesh->vertex(1, -0.5, -1);
  727.80 +	mesh->texcoord(1, 0); mesh->vertex(1, -0.5, 1);
  727.81 +	mesh->texcoord(1, 1); mesh->vertex(2, 0, 1);
  727.82 +	mesh->texcoord(0, 1); mesh->vertex(2, 0, -1);
  727.83 +
  727.84 +	// quad face index buffer
  727.85 +	int nverts = mesh->get_attrib_count(MESH_ATTR_VERTEX);
  727.86 +	for(int i=0; i<nverts; i+=4) {
  727.87 +		mesh->face(i, i + 1, i + 2);
  727.88 +		mesh->face(i, i + 2, i + 3);
  727.89 +	}
  727.90 +
  727.91 +	info_log("generated level trough mesh: %d polygons\n", mesh->get_poly_count());
  727.92 +}
   728.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   728.2 +++ b/src/level.h	Sat Feb 01 19:58:19 2014 +0200
   728.3 @@ -0,0 +1,26 @@
   728.4 +#ifndef LEVEL_H_
   728.5 +#define LEVEL_H_
   728.6 +
   728.7 +#include <list>
   728.8 +#include "enemy.h"
   728.9 +#include "mesh.h"
  728.10 +#include "object.h"
  728.11 +
  728.12 +class Level {
  728.13 +private:
  728.14 +	Object *tile_obj;
  728.15 +	Mesh tile_mesh;
  728.16 +	std::list<Enemy> enemies;
  728.17 +
  728.18 +	float dlimit_near, dlimit_far;
  728.19 +
  728.20 +public:
  728.21 +	Level();
  728.22 +	~Level();
  728.23 +
  728.24 +	void set_draw_limits(float dnear, float dfar);
  728.25 +
  728.26 +	void draw() const;
  728.27 +};
  728.28 +
  728.29 +#endif	// LEVEL_H_
   729.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   729.2 +++ b/src/logger.cc	Sat Feb 01 19:58:19 2014 +0200
   729.3 @@ -0,0 +1,118 @@
   729.4 +#include <stdio.h>
   729.5 +#include <stdarg.h>
   729.6 +#include "logger.h"
   729.7 +
   729.8 +#if defined(unix) || defined(__unix__) || defined(__APPLE__)
   729.9 +#include <unistd.h>
  729.10 +#elif defined(WIN32)
  729.11 +#include <windows.h>
  729.12 +#endif
  729.13 +
  729.14 +enum { LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL, LOG_DEBUG };
  729.15 +
  729.16 +static int typecolor(int type);
  729.17 +
  729.18 +static FILE *fp = stdout;
  729.19 +
  729.20 +static void logmsg(int type, const char *fmt, va_list ap)
  729.21 +{
  729.22 +#if defined(unix) || defined(__unix__) || (defined(__APPLE__) && !defined(TARGET_IPHONE))
  729.23 +	if(isatty(fileno(fp)) && type != LOG_INFO) {
  729.24 +		int c = typecolor(type);
  729.25 +		fprintf(fp, "\033[%dm", c);
  729.26 +		vfprintf(fp, fmt, ap);
  729.27 +		fprintf(fp, "\033[0m");
  729.28 +	} else
  729.29 +#endif
  729.30 +	{
  729.31 +		vfprintf(fp, fmt, ap);
  729.32 +	}
  729.33 +	if(type == LOG_ERROR || type == LOG_FATAL || type == LOG_DEBUG) {
  729.34 +		fflush(fp);
  729.35 +	}
  729.36 +
  729.37 +#ifdef WIN32
  729.38 +	if(type == LOG_FATAL) {
  729.39 +		static char msgbuf[1024];
  729.40 +		vsnprintf(msgbuf, sizeof msgbuf - 1, fmt, ap);
  729.41 +		msgbuf[sizeof msgbuf - 1] = 0;
  729.42 +		MessageBox(0, msgbuf, "Fatal error", MB_OK | MB_ICONSTOP);
  729.43 +	}
  729.44 +#endif
  729.45 +}
  729.46 +
  729.47 +void info_log(const char *fmt, ...)
  729.48 +{
  729.49 +	va_list ap;
  729.50 +
  729.51 +	va_start(ap, fmt);
  729.52 +	logmsg(LOG_INFO, fmt, ap);
  729.53 +	va_end(ap);
  729.54 +}
  729.55 +
  729.56 +void warning_log(const char *fmt, ...)
  729.57 +{
  729.58 +	va_list ap;
  729.59 +
  729.60 +	va_start(ap, fmt);
  729.61 +	logmsg(LOG_WARNING, fmt, ap);
  729.62 +	va_end(ap);
  729.63 +}
  729.64 +
  729.65 +void error_log(const char *fmt, ...)
  729.66 +{
  729.67 +	va_list ap;
  729.68 +
  729.69 +	va_start(ap, fmt);
  729.70 +	logmsg(LOG_ERROR, fmt, ap);
  729.71 +	va_end(ap);
  729.72 +}
  729.73 +
  729.74 +void fatal_log(const char *fmt, ...)
  729.75 +{
  729.76 +	va_list ap;
  729.77 +
  729.78 +	va_start(ap, fmt);
  729.79 +	logmsg(LOG_FATAL, fmt, ap);
  729.80 +	va_end(ap);
  729.81 +}
  729.82 +
  729.83 +void debug_log(const char *fmt, ...)
  729.84 +{
  729.85 +	va_list ap;
  729.86 +
  729.87 +	va_start(ap, fmt);
  729.88 +	logmsg(LOG_DEBUG, fmt, ap);
  729.89 +	va_end(ap);
  729.90 +}
  729.91 +
  729.92 +enum {
  729.93 +	BLACK = 0,
  729.94 +	RED,
  729.95 +	GREEN,
  729.96 +	YELLOW,
  729.97 +	BLUE,
  729.98 +	MAGENTA,
  729.99 +	CYAN,
 729.100 +	WHITE
 729.101 +};
 729.102 +
 729.103 +#define ANSI_FGCOLOR(x)	(30 + (x))
 729.104 +#define ANSI_BGCOLOR(x)	(40 + (x))
 729.105 +
 729.106 +static int typecolor(int type)
 729.107 +{
 729.108 +	switch(type) {
 729.109 +	case LOG_ERROR:
 729.110 +		return ANSI_FGCOLOR(RED);
 729.111 +	case LOG_FATAL:
 729.112 +		return ANSI_FGCOLOR(RED);	// TODO differentiate from LOG_ERROR
 729.113 +	case LOG_WARNING:
 729.114 +		return ANSI_FGCOLOR(YELLOW);
 729.115 +	case LOG_DEBUG:
 729.116 +		return ANSI_FGCOLOR(MAGENTA);
 729.117 +	default:
 729.118 +		break;
 729.119 +	}
 729.120 +	return 37;
 729.121 +}
   730.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   730.2 +++ b/src/logger.h	Sat Feb 01 19:58:19 2014 +0200
   730.3 @@ -0,0 +1,10 @@
   730.4 +#ifndef LOGGER_H_
   730.5 +#define LOGGER_H_
   730.6 +
   730.7 +void info_log(const char *fmt, ...);
   730.8 +void warning_log(const char *fmt, ...);
   730.9 +void error_log(const char *fmt, ...);
  730.10 +void fatal_log(const char *fmt, ...);
  730.11 +void debug_log(const char *fmt, ...);
  730.12 +
  730.13 +#endif	// LOGGER_H_
   731.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   731.2 +++ b/src/main_glut.cc	Sat Feb 01 19:58:19 2014 +0200
   731.3 @@ -0,0 +1,205 @@
   731.4 +#include <stdlib.h>
   731.5 +#include <ctype.h>
   731.6 +#include <assert.h>
   731.7 +#include "opengl.h"
   731.8 +
   731.9 +#include "game.h"
  731.10 +#include "input.h"
  731.11 +#include "screen.h"
  731.12 +#include "logger.h"
  731.13 +
  731.14 +/* called by any other part of the game when a redisplay is needed
  731.15 + * (mostly useful for tools which do not redisplay continuously)
  731.16 + */
  731.17 +void request_redisplay();
  731.18 +
  731.19 +void swap_buffers();
  731.20 +
  731.21 +static void display(void);
  731.22 +static void reshape(int x, int y);
  731.23 +static void keydown(unsigned char key, int x, int y);
  731.24 +static void keyup(unsigned char key, int x, int y);
  731.25 +static void skeydown(int key, int x, int y);
  731.26 +static void skeyup(int key, int x, int y);
  731.27 +static void mouse(int bn, int state, int x, int y);
  731.28 +static void motion(int x, int y);
  731.29 +static void passive_motion(int x, int y);
  731.30 +
  731.31 +static long redisp_interval;
  731.32 +
  731.33 +int main(int argc, char **argv)
  731.34 +{
  731.35 +	glutInit(&argc, argv);
  731.36 +	glutInitWindowSize(800, 600);
  731.37 +	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
  731.38 +	glutCreateWindow("Xmass inferno");
  731.39 +
  731.40 +	glutDisplayFunc(display);
  731.41 +	glutReshapeFunc(reshape);
  731.42 +	glutKeyboardFunc(keydown);
  731.43 +	glutKeyboardUpFunc(keyup);
  731.44 +	glutSpecialFunc(skeydown);
  731.45 +	glutSpecialUpFunc(skeyup);
  731.46 +	glutMouseFunc(mouse);
  731.47 +	glutMotionFunc(motion);
  731.48 +	glutPassiveMotionFunc(passive_motion);
  731.49 +
  731.50 +	game_set_args(argc, argv);
  731.51 +	if(!game_init()) {
  731.52 +		return 1;
  731.53 +	}
  731.54 +	atexit(game_cleanup);
  731.55 +
  731.56 +	glutMainLoop();
  731.57 +	return 0;
  731.58 +}
  731.59 +
  731.60 +void request_redisplay()
  731.61 +{
  731.62 +	glutPostRedisplay();
  731.63 +}
  731.64 +
  731.65 +void swap_buffers()
  731.66 +{
  731.67 +	glUseProgram(0);
  731.68 +	glutSwapBuffers();
  731.69 +}
  731.70 +
  731.71 +static void display()
  731.72 +{
  731.73 +	long ival = current_screen()->redisplay_interval();
  731.74 +	if(ival && !redisp_interval) {
  731.75 +		debug_log("switching to auto-redisplay (interval: %ld)\n", redisp_interval);
  731.76 +		glutIdleFunc(request_redisplay);
  731.77 +	}
  731.78 +	if(!ival && redisp_interval) {
  731.79 +		debug_log("switching to manual redisplay\n");
  731.80 +		glutIdleFunc(0);
  731.81 +	}
  731.82 +	redisp_interval = ival;
  731.83 +
  731.84 +	game_display();
  731.85 +	// TODO implement framerate limiter
  731.86 +}
  731.87 +
  731.88 +
  731.89 +static void reshape(int x, int y)
  731.90 +{
  731.91 +	game_reshape(x, y);
  731.92 +}
  731.93 +
  731.94 +/* GLUT doesn't have any callbacks for modifier keys, so we fake it by calling
  731.95 + * this function all over the place, to generate fake events whenever a modifier
  731.96 + * key is detected to have changed state.
  731.97 + * The limitation is that this will only detect modkey changes whenever a regular
  731.98 + * key is pressed or released, or when a mouse button is pressed or released.
  731.99 + */
 731.100 +static void handle_modkeys()
 731.101 +{
 731.102 +	static int modstate;
 731.103 +
 731.104 +	int mod = glutGetModifiers();
 731.105 +	if(mod != modstate) {
 731.106 +		int diff = mod ^ modstate;
 731.107 +
 731.108 +		if(diff & GLUT_ACTIVE_SHIFT) {
 731.109 +			bool pressed = mod & GLUT_ACTIVE_SHIFT;
 731.110 +			game_key(KEY_LSHIFT, pressed);
 731.111 +		}
 731.112 +		if(diff & GLUT_ACTIVE_CTRL) {
 731.113 +			bool pressed = mod & GLUT_ACTIVE_CTRL;
 731.114 +			game_key(KEY_LCTRL, pressed);
 731.115 +		}
 731.116 +		if(diff & GLUT_ACTIVE_ALT) {
 731.117 +			bool pressed = mod & GLUT_ACTIVE_ALT;
 731.118 +			game_key(KEY_LALT, pressed);
 731.119 +		}
 731.120 +	}
 731.121 +	modstate = mod;
 731.122 +}
 731.123 +
 731.124 +static int translate_special_key(int key)
 731.125 +{
 731.126 +	if(key >= GLUT_KEY_F1 && key <= GLUT_KEY_F12) {
 731.127 +		return (key - GLUT_KEY_F1) + KEY_F1;
 731.128 +	}
 731.129 +	if(key >= GLUT_KEY_LEFT && key <= GLUT_KEY_PAGE_DOWN) {
 731.130 +		return (key - GLUT_KEY_LEFT) + KEY_LEFT;
 731.131 +	}
 731.132 +
 731.133 +	switch(key) {
 731.134 +	case GLUT_KEY_HOME:
 731.135 +		return KEY_HOME;
 731.136 +	case GLUT_KEY_END:
 731.137 +		return KEY_END;
 731.138 +	case GLUT_KEY_INSERT:
 731.139 +		return KEY_INSERT;
 731.140 +
 731.141 +	default:
 731.142 +		break;
 731.143 +	}
 731.144 +	return 0;
 731.145 +}
 731.146 +
 731.147 +static void keydown(unsigned char c, int x, int y)
 731.148 +{
 731.149 +	int key = c;
 731.150 +	if(key == 127) {
 731.151 +		key = KEY_DELETE;
 731.152 +	}
 731.153 +
 731.154 +	handle_modkeys();
 731.155 +	game_key(key, true);
 731.156 +}
 731.157 +
 731.158 +static void keyup(unsigned char c, int x, int y)
 731.159 +{
 731.160 +	int key = c;
 731.161 +	if(key == 127) {
 731.162 +		key = KEY_DELETE;
 731.163 +	}
 731.164 +
 731.165 +	handle_modkeys();
 731.166 +	game_key(key, false);
 731.167 +}
 731.168 +
 731.169 +static void skeydown(int key, int x, int y)
 731.170 +{
 731.171 +	handle_modkeys();
 731.172 +
 731.173 +	if((key = translate_special_key(key)) > 0) {
 731.174 +		game_key(key, true);
 731.175 +	}
 731.176 +}
 731.177 +
 731.178 +static void skeyup(int key, int x, int y)
 731.179 +{
 731.180 +	handle_modkeys();
 731.181 +
 731.182 +	if((key = translate_special_key(key)) > 0) {
 731.183 +		game_key(key, false);
 731.184 +	}
 731.185 +}
 731.186 +
 731.187 +static void mouse(int bn, int state, int x, int y)
 731.188 +{
 731.189 +	handle_modkeys();
 731.190 +
 731.191 +	int bnidx = bn - GLUT_LEFT_BUTTON;
 731.192 +	bool bnstate = state == GLUT_DOWN;
 731.193 +
 731.194 +	current_screen()->button(bnidx, bnstate, x, y);
 731.195 +	set_mouse_state(x, y, bnidx, bnstate);	// this MUST be after the event dispatch
 731.196 +}
 731.197 +
 731.198 +static void motion(int x, int y)
 731.199 +{
 731.200 +	set_mouse_state(x, y);
 731.201 +	current_screen()->motion(x, y, false);
 731.202 +}
 731.203 +
 731.204 +static void passive_motion(int x, int y)
 731.205 +{
 731.206 +	set_mouse_state(x, y);
 731.207 +	current_screen()->motion(x, y, true);
 731.208 +}
   732.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   732.2 +++ b/src/material.cc	Sat Feb 01 19:58:19 2014 +0200
   732.3 @@ -0,0 +1,65 @@
   732.4 +#include "material.h"
   732.5 +#include "unistate.h"
   732.6 +
   732.7 +Material::Material()
   732.8 +	: diffuse(1, 1, 1), specular(0, 0, 0)
   732.9 +{
  732.10 +	alpha = 1.0;
  732.11 +	shininess = 1.0;
  732.12 +
  732.13 +	for(int i=0; i<MAX_MTL_TEXTURES; i++) {
  732.14 +		tex[i] = 0;
  732.15 +	}
  732.16 +}
  732.17 +
  732.18 +
  732.19 +void Material::setup(bool use_textures) const
  732.20 +{
  732.21 +	static bool done_init;
  732.22 +	static int st_diffuse_idx, st_specular_idx, st_shininess_idx, st_alpha_idx;
  732.23 +	static int st_tex_diffuse_idx, st_tex_specular_idx, st_tex_normal_idx;
  732.24 +	static int st_tex_idx[MAX_MTL_TEXTURES];
  732.25 +
  732.26 +	if(!done_init) {
  732.27 +		st_diffuse_idx = add_unistate("st_mtl_diffuse", ST_FLOAT3);
  732.28 +		st_specular_idx = add_unistate("st_mtl_specular", ST_FLOAT3);
  732.29 +		st_shininess_idx = add_unistate("st_mtl_shininess", ST_FLOAT);
  732.30 +		st_alpha_idx = add_unistate("st_mtl_alpha", ST_FLOAT);
  732.31 +		st_tex_diffuse_idx = add_unistate("st_tex_diffuse", ST_INT);
  732.32 +		st_tex_specular_idx = add_unistate("st_tex_specular", ST_INT);
  732.33 +		st_tex_normal_idx = add_unistate("st_tex_normal", ST_INT);
  732.34 +
  732.35 +		for(int i=0; i<MAX_MTL_TEXTURES; i++) {
  732.36 +			char name[32];
  732.37 +			sprintf(name, "st_tex%d", i);
  732.38 +			st_tex_idx[i] = add_unistate(name, ST_INT);
  732.39 +		}
  732.40 +		done_init = true;
  732.41 +	}
  732.42 +
  732.43 +	set_unistate(st_diffuse_idx, diffuse);
  732.44 +	set_unistate(st_specular_idx, specular);
  732.45 +	set_unistate(st_shininess_idx, shininess);
  732.46 +	set_unistate(st_alpha_idx, alpha);
  732.47 +
  732.48 +	if(!use_textures) {
  732.49 +		return;	// we're done
  732.50 +	}
  732.51 +
  732.52 +	const int tex_named_idx[] = {
  732.53 +		st_tex_diffuse_idx, st_tex_specular_idx, st_tex_normal_idx, -1
  732.54 +	};
  732.55 +
  732.56 +	int tex_unit = 0;
  732.57 +	for(int i=0; i<MAX_MTL_TEXTURES; i++) {
  732.58 +		if(tex[i]) {
  732.59 +			tex[i]->bind(tex_unit);
  732.60 +
  732.61 +			if(tex_named_idx[i]) {
  732.62 +				set_unistate(tex_named_idx[i], tex_unit);
  732.63 +			}
  732.64 +			set_unistate(st_tex_idx[i], tex_unit);
  732.65 +			tex_unit++;
  732.66 +		}
  732.67 +	}
  732.68 +}
   733.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   733.2 +++ b/src/material.h	Sat Feb 01 19:58:19 2014 +0200
   733.3 @@ -0,0 +1,29 @@
   733.4 +#ifndef MATERIAL_H_
   733.5 +#define MATERIAL_H_
   733.6 +
   733.7 +#include "vmath/vmath.h"
   733.8 +#include "texture.h"
   733.9 +
  733.10 +enum {
  733.11 +	TEX_DIFFUSE,
  733.12 +	TEX_SPECULAR,
  733.13 +	TEX_NORMAL,
  733.14 +	TEX_MISC,
  733.15 +
  733.16 +	MAX_MTL_TEXTURES
  733.17 +};
  733.18 +
  733.19 +class Material {
  733.20 +public:
  733.21 +	Vector3 diffuse, specular;
  733.22 +	float alpha;
  733.23 +	float shininess;
  733.24 +
  733.25 +	Texture *tex[MAX_MTL_TEXTURES];
  733.26 +
  733.27 +	Material();
  733.28 +
  733.29 +	void setup(bool use_textures = true) const;
  733.30 +};
  733.31 +
  733.32 +#endif	// MATERIAL_H_
   734.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   734.2 +++ b/src/mesh.cc	Sat Feb 01 19:58:19 2014 +0200
   734.3 @@ -0,0 +1,1059 @@
   734.4 +#include <stdio.h>
   734.5 +#include <stdlib.h>
   734.6 +#include <float.h>
   734.7 +#include <assert.h>
   734.8 +#include "opengl.h"
   734.9 +#include "mesh.h"
  734.10 +#include "xform_node.h"
  734.11 +#include "shader.h"
  734.12 +#include "logger.h"
  734.13 +
  734.14 +int Mesh::global_sdr_loc[NUM_MESH_ATTR] = { 0, 1, 2, 3, 4, 5 };
  734.15 +unsigned int Mesh::intersect_mode = ISECT_DEFAULT;
  734.16 +float Mesh::vertex_sel_dist = 0.01;
  734.17 +float Mesh::vis_vecsize = 1.0;
  734.18 +
  734.19 +Mesh::Mesh()
  734.20 +{
  734.21 +	clear();
  734.22 +
  734.23 +	glGenBuffers(NUM_MESH_ATTR + 1, buffer_objects);
  734.24 +
  734.25 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
  734.26 +		vattr[i].vbo = buffer_objects[i];
  734.27 +	}
  734.28 +	ibo = buffer_objects[NUM_MESH_ATTR];
  734.29 +	wire_ibo = 0;
  734.30 +}
  734.31 +
  734.32 +Mesh::~Mesh()
  734.33 +{
  734.34 +	glDeleteBuffers(NUM_MESH_ATTR + 1, buffer_objects);
  734.35 +
  734.36 +	if(wire_ibo) {
  734.37 +		glDeleteBuffers(1, &wire_ibo);
  734.38 +	}
  734.39 +}
  734.40 +
  734.41 +void Mesh::set_name(const char *name)
  734.42 +{
  734.43 +	this->name = name;
  734.44 +}
  734.45 +
  734.46 +const char *Mesh::get_name() const
  734.47 +{
  734.48 +	return name.c_str();
  734.49 +}
  734.50 +
  734.51 +bool Mesh::has_attrib(int attr) const
  734.52 +{
  734.53 +	if(attr < 0 || attr >= NUM_MESH_ATTR) {
  734.54 +		return false;
  734.55 +	}
  734.56 +
  734.57 +	// if neither of these is valid, then nobody has set this attribute
  734.58 +	return vattr[attr].vbo_valid || vattr[attr].data_valid;
  734.59 +}
  734.60 +
  734.61 +void Mesh::clear()
  734.62 +{
  734.63 +	bones.clear();
  734.64 +
  734.65 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
  734.66 +		vattr[i].nelem = 0;
  734.67 +		vattr[i].vbo_valid = false;
  734.68 +		vattr[i].data_valid = false;
  734.69 +		//vattr[i].sdr_loc = -1;
  734.70 +		vattr[i].data.clear();
  734.71 +	}
  734.72 +	ibo_valid = idata_valid = false;
  734.73 +	idata.clear();
  734.74 +
  734.75 +	wire_ibo_valid = false;
  734.76 +
  734.77 +	nverts = nfaces = 0;
  734.78 +
  734.79 +	bsph_valid = false;
  734.80 +	aabb_valid = false;
  734.81 +}
  734.82 +
  734.83 +float *Mesh::set_attrib_data(int attrib, int nelem, unsigned int num, const float *data)
  734.84 +{
  734.85 +	if(attrib < 0 || attrib >= NUM_MESH_ATTR) {
  734.86 +		error_log("%s: invalid attrib: %d\n", __FUNCTION__, attrib);
  734.87 +		return 0;
  734.88 +	}
  734.89 +
  734.90 +	if(nverts && num != nverts) {
  734.91 +		error_log("%s: attribute count missmatch (%d instead of %d)\n", __FUNCTION__, num, nverts);
  734.92 +		return 0;
  734.93 +	}
  734.94 +	nverts = num;
  734.95 +
  734.96 +	vattr[attrib].data.clear();
  734.97 +	vattr[attrib].nelem = nelem;
  734.98 +	vattr[attrib].data.resize(num * nelem);
  734.99 +
 734.100 +	if(data) {
 734.101 +		memcpy(&vattr[attrib].data[0], data, num * nelem * sizeof *data);
 734.102 +	}
 734.103 +
 734.104 +	vattr[attrib].data_valid = true;
 734.105 +	vattr[attrib].vbo_valid = false;
 734.106 +	return &vattr[attrib].data[0];
 734.107 +}
 734.108 +
 734.109 +float *Mesh::get_attrib_data(int attrib)
 734.110 +{
 734.111 +	if(attrib < 0 || attrib >= NUM_MESH_ATTR) {
 734.112 +		error_log("%s: invalid attrib: %d\n", __FUNCTION__, attrib);
 734.113 +		return 0;
 734.114 +	}
 734.115 +
 734.116 +	vattr[attrib].vbo_valid = false;
 734.117 +	return (float*)((const Mesh*)this)->get_attrib_data(attrib);
 734.118 +}
 734.119 +
 734.120 +const float *Mesh::get_attrib_data(int attrib) const
 734.121 +{
 734.122 +	if(attrib < 0 || attrib >= NUM_MESH_ATTR) {
 734.123 +		error_log("%s: invalid attrib: %d\n", __FUNCTION__, attrib);
 734.124 +		return 0;
 734.125 +	}
 734.126 +
 734.127 +	if(!vattr[attrib].data_valid) {
 734.128 +#if GL_ES_VERSION_2_0
 734.129 +		error_log("%s: can't read back attrib data on CrippledGL ES\n", __FUNCTION__);
 734.130 +		return 0;
 734.131 +#else
 734.132 +		if(!vattr[attrib].vbo_valid) {
 734.133 +			error_log("%s: unavailable attrib: %d\n", __FUNCTION__, attrib);
 734.134 +			return 0;
 734.135 +		}
 734.136 +
 734.137 +		// local data copy is unavailable, grab the data from the vbo
 734.138 +		Mesh *m = (Mesh*)this;
 734.139 +		m->vattr[attrib].data.resize(nverts * vattr[attrib].nelem);
 734.140 +
 734.141 +		glBindBuffer(GL_ARRAY_BUFFER, vattr[attrib].vbo);
 734.142 +		void *data = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
 734.143 +		memcpy(&m->vattr[attrib].data[0], data, nverts * vattr[attrib].nelem * sizeof(float));
 734.144 +		glUnmapBuffer(GL_ARRAY_BUFFER);
 734.145 +
 734.146 +		vattr[attrib].data_valid = true;
 734.147 +#endif
 734.148 +	}
 734.149 +
 734.150 +	return &vattr[attrib].data[0];
 734.151 +}
 734.152 +
 734.153 +void Mesh::set_attrib(int attrib, int idx, const Vector4 &v)
 734.154 +{
 734.155 +	float *data = get_attrib_data(attrib);
 734.156 +	if(data) {
 734.157 +		data += idx * vattr[attrib].nelem;
 734.158 +		for(int i=0; i<vattr[attrib].nelem; i++) {
 734.159 +			data[i] = v[i];
 734.160 +		}
 734.161 +	}
 734.162 +}
 734.163 +
 734.164 +Vector4 Mesh::get_attrib(int attrib, int idx) const
 734.165 +{
 734.166 +	Vector4 v(0.0, 0.0, 0.0, 1.0);
 734.167 +	const float *data = get_attrib_data(attrib);
 734.168 +	if(data) {
 734.169 +		data += idx * vattr[attrib].nelem;
 734.170 +		for(int i=0; i<vattr[attrib].nelem; i++) {
 734.171 +			v[i] = data[i];
 734.172 +		}
 734.173 +	}
 734.174 +	return v;
 734.175 +}
 734.176 +
 734.177 +int Mesh::get_attrib_count(int attrib) const
 734.178 +{
 734.179 +	return has_attrib(attrib) ? nverts : 0;
 734.180 +}
 734.181 +
 734.182 +
 734.183 +unsigned int *Mesh::set_index_data(int num, const unsigned int *indices)
 734.184 +{
 734.185 +	int nidx = nfaces * 3;
 734.186 +	if(nidx && num != nidx) {
 734.187 +		error_log("%s: index count missmatch (%d instead of %d)\n", __FUNCTION__, num, nidx);
 734.188 +		return 0;
 734.189 +	}
 734.190 +	nfaces = num / 3;
 734.191 +
 734.192 +	idata.clear();
 734.193 +	idata.resize(num);
 734.194 +
 734.195 +	if(indices) {
 734.196 +		memcpy(&idata[0], indices, num * sizeof *indices);
 734.197 +	}
 734.198 +
 734.199 +	idata_valid = true;
 734.200 +	ibo_valid = false;
 734.201 +
 734.202 +	return &idata[0];
 734.203 +}
 734.204 +
 734.205 +unsigned int *Mesh::get_index_data()
 734.206 +{
 734.207 +	ibo_valid = false;
 734.208 +	return (unsigned int*)((const Mesh*)this)->get_index_data();
 734.209 +}
 734.210 +
 734.211 +const unsigned int *Mesh::get_index_data() const
 734.212 +{
 734.213 +	if(!idata_valid) {
 734.214 +#if GL_ES_VERSION_2_0
 734.215 +		error_log("%s: can't read back index data in CrippledGL ES\n", __FUNCTION__);
 734.216 +		return 0;
 734.217 +#else
 734.218 +		if(!ibo_valid) {
 734.219 +			error_log("%s: indices unavailable\n", __FUNCTION__);
 734.220 +			return 0;
 734.221 +		}
 734.222 +
 734.223 +		// local data copy is unavailable, gram the data from the ibo
 734.224 +		Mesh *m = (Mesh*)this;
 734.225 +		int nidx = nfaces * 3;
 734.226 +		m->idata.resize(nidx);
 734.227 +
 734.228 +		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
 734.229 +		void *data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY);
 734.230 +		memcpy(&m->idata[0], data, nidx * sizeof(unsigned int));
 734.231 +		glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
 734.232 +
 734.233 +		idata_valid = true;
 734.234 +#endif
 734.235 +	}
 734.236 +
 734.237 +	return &idata[0];
 734.238 +}
 734.239 +
 734.240 +int Mesh::get_index_count() const
 734.241 +{
 734.242 +	return nfaces * 3;
 734.243 +}
 734.244 +
 734.245 +void Mesh::append(const Mesh &mesh)
 734.246 +{
 734.247 +	unsigned int idxoffs = nverts;
 734.248 +
 734.249 +	nverts += mesh.nverts;
 734.250 +	nfaces += mesh.nfaces;
 734.251 +
 734.252 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
 734.253 +		if(has_attrib(i) && mesh.has_attrib(i)) {
 734.254 +			// force validating the data arrays
 734.255 +			get_attrib_data(i);
 734.256 +			mesh.get_attrib_data(i);
 734.257 +
 734.258 +			// append the mesh data
 734.259 +			vattr[i].data.insert(vattr[i].data.end(), mesh.vattr[i].data.begin(), mesh.vattr[i].data.end());
 734.260 +		}
 734.261 +	}
 734.262 +
 734.263 +	if(ibo_valid || idata_valid) {
 734.264 +		// make index arrays valid
 734.265 +		get_index_data();
 734.266 +		mesh.get_index_data();
 734.267 +
 734.268 +		size_t orig_sz = idata.size();
 734.269 +
 734.270 +		idata.insert(idata.end(), mesh.idata.begin(), mesh.idata.end());
 734.271 +
 734.272 +		// fixup all the new indices
 734.273 +		for(size_t i=orig_sz; i<idata.size(); i++) {
 734.274 +			idata[i] += idxoffs;
 734.275 +		}
 734.276 +	}
 734.277 +
 734.278 +	// fuck everything
 734.279 +	wire_ibo_valid = false;
 734.280 +	aabb_valid = false;
 734.281 +	bsph_valid = false;
 734.282 +}
 734.283 +
 734.284 +// assemble a complete vertex by adding all the useful attributes
 734.285 +void Mesh::vertex(float x, float y, float z)
 734.286 +{
 734.287 +	cur_val[MESH_ATTR_VERTEX] = Vector4(x, y, z, 1.0f);
 734.288 +	vattr[MESH_ATTR_VERTEX].data_valid = true;
 734.289 +	vattr[MESH_ATTR_VERTEX].nelem = 3;
 734.290 +
 734.291 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
 734.292 +		if(vattr[i].data_valid) {
 734.293 +			for(int j=0; j<vattr[MESH_ATTR_VERTEX].nelem; j++) {
 734.294 +				vattr[i].data.push_back(cur_val[i][j]);
 734.295 +			}
 734.296 +		}
 734.297 +		vattr[i].vbo_valid = false;
 734.298 +	}
 734.299 +	nverts++;
 734.300 +
 734.301 +	/*if(idata_valid) {
 734.302 +		idata.clear();
 734.303 +	}
 734.304 +	ibo_valid = idata_valid = false;*/
 734.305 +}
 734.306 +
 734.307 +void Mesh::normal(float nx, float ny, float nz)
 734.308 +{
 734.309 +	cur_val[MESH_ATTR_NORMAL] = Vector4(nx, ny, nz, 1.0f);
 734.310 +	vattr[MESH_ATTR_NORMAL].data_valid = true;
 734.311 +	vattr[MESH_ATTR_NORMAL].nelem = 3;
 734.312 +}
 734.313 +
 734.314 +void Mesh::tangent(float tx, float ty, float tz)
 734.315 +{
 734.316 +	cur_val[MESH_ATTR_TANGENT] = Vector4(tx, ty, tz, 1.0f);
 734.317 +	vattr[MESH_ATTR_TANGENT].data_valid = true;
 734.318 +	vattr[MESH_ATTR_TANGENT].nelem = 3;
 734.319 +}
 734.320 +
 734.321 +void Mesh::texcoord(float u, float v, float w)
 734.322 +{
 734.323 +	cur_val[MESH_ATTR_TEXCOORD] = Vector4(u, v, w, 1.0f);
 734.324 +	vattr[MESH_ATTR_TEXCOORD].data_valid = true;
 734.325 +	vattr[MESH_ATTR_TEXCOORD].nelem = 3;
 734.326 +}
 734.327 +
 734.328 +void Mesh::boneweights(float w1, float w2, float w3, float w4)
 734.329 +{
 734.330 +	cur_val[MESH_ATTR_BONEWEIGHTS] = Vector4(w1, w2, w3, w4);
 734.331 +	vattr[MESH_ATTR_BONEWEIGHTS].data_valid = true;
 734.332 +	vattr[MESH_ATTR_BONEWEIGHTS].nelem = 4;
 734.333 +}
 734.334 +
 734.335 +void Mesh::boneidx(int idx1, int idx2, int idx3, int idx4)
 734.336 +{
 734.337 +	cur_val[MESH_ATTR_BONEIDX] = Vector4(idx1, idx2, idx3, idx4);
 734.338 +	vattr[MESH_ATTR_BONEIDX].data_valid = true;
 734.339 +	vattr[MESH_ATTR_BONEIDX].nelem = 4;
 734.340 +}
 734.341 +
 734.342 +void Mesh::face(unsigned int v0, unsigned int v1, unsigned int v2)
 734.343 +{
 734.344 +	idata.push_back(v0);
 734.345 +	idata.push_back(v1);
 734.346 +	idata.push_back(v2);
 734.347 +
 734.348 +	idata_valid = true;
 734.349 +	ibo_valid = false;
 734.350 +
 734.351 +	nfaces++;
 734.352 +}
 734.353 +
 734.354 +int Mesh::get_poly_count() const
 734.355 +{
 734.356 +	if(nfaces) {
 734.357 +		return nfaces;
 734.358 +	}
 734.359 +	if(nverts) {
 734.360 +		return nverts / 3;
 734.361 +	}
 734.362 +	return 0;
 734.363 +}
 734.364 +
 734.365 +/// static function
 734.366 +void Mesh::set_attrib_location(int attr, int loc)
 734.367 +{
 734.368 +	if(attr < 0 || attr >= NUM_MESH_ATTR) {
 734.369 +		return;
 734.370 +	}
 734.371 +	Mesh::global_sdr_loc[attr] = loc;
 734.372 +}
 734.373 +
 734.374 +/// static function
 734.375 +int Mesh::get_attrib_location(int attr)
 734.376 +{
 734.377 +	if(attr < 0 || attr >= NUM_MESH_ATTR) {
 734.378 +		return -1;
 734.379 +	}
 734.380 +	return Mesh::global_sdr_loc[attr];
 734.381 +}
 734.382 +
 734.383 +/// static function
 734.384 +void Mesh::clear_attrib_locations()
 734.385 +{
 734.386 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
 734.387 +		Mesh::global_sdr_loc[i] = -1;
 734.388 +	}
 734.389 +}
 734.390 +
 734.391 +/// static function
 734.392 +void Mesh::set_vis_vecsize(float sz)
 734.393 +{
 734.394 +	Mesh::vis_vecsize = sz;
 734.395 +}
 734.396 +
 734.397 +float Mesh::get_vis_vecsize()
 734.398 +{
 734.399 +	return Mesh::vis_vecsize;
 734.400 +}
 734.401 +
 734.402 +void Mesh::apply_xform(const Matrix4x4 &xform)
 734.403 +{
 734.404 +	Matrix4x4 dir_xform = xform;
 734.405 +	dir_xform[0][3] = dir_xform[1][3] = dir_xform[2][3] = 0.0f;
 734.406 +	dir_xform[3][0] = dir_xform[3][1] = dir_xform[3][2] = 0.0f;
 734.407 +	dir_xform[3][3] = 1.0f;
 734.408 +
 734.409 +	apply_xform(xform, dir_xform);
 734.410 +}
 734.411 +
 734.412 +void Mesh::apply_xform(const Matrix4x4 &xform, const Matrix4x4 &dir_xform)
 734.413 +{
 734.414 +	for(unsigned int i=0; i<nverts; i++) {
 734.415 +		Vector4 v = get_attrib(MESH_ATTR_VERTEX, i);
 734.416 +		set_attrib(MESH_ATTR_VERTEX, i, v.transformed(xform));
 734.417 +
 734.418 +		if(has_attrib(MESH_ATTR_NORMAL)) {
 734.419 +			Vector3 n = get_attrib(MESH_ATTR_NORMAL, i);
 734.420 +			set_attrib(MESH_ATTR_NORMAL, i, n.transformed(dir_xform));
 734.421 +		}
 734.422 +		if(has_attrib(MESH_ATTR_TANGENT)) {
 734.423 +			Vector3 t = get_attrib(MESH_ATTR_TANGENT, i);
 734.424 +			set_attrib(MESH_ATTR_TANGENT, i, t.transformed(dir_xform));
 734.425 +		}
 734.426 +	}
 734.427 +}
 734.428 +
 734.429 +int Mesh::add_bone(XFormNode *bone)
 734.430 +{
 734.431 +	int idx = bones.size();
 734.432 +	bones.push_back(bone);
 734.433 +	return idx;
 734.434 +}
 734.435 +
 734.436 +const XFormNode *Mesh::get_bone(int idx) const
 734.437 +{
 734.438 +	if(idx < 0 || idx >= (int)bones.size()) {
 734.439 +		return 0;
 734.440 +	}
 734.441 +	return bones[idx];
 734.442 +}
 734.443 +
 734.444 +int Mesh::get_bones_count() const
 734.445 +{
 734.446 +	return (int)bones.size();
 734.447 +}
 734.448 +
 734.449 +void Mesh::draw() const
 734.450 +{
 734.451 +	const ShaderProg *cur_sdr = get_current_shader();
 734.452 +#ifdef GL_ES_VERSION_2_0
 734.453 +	if(!cur_sdr) {
 734.454 +		error_log("%s: CrippledGL ES can't draw without a shader\n", __FUNCTION__);
 734.455 +		return;
 734.456 +	}
 734.457 +#endif
 734.458 +
 734.459 +	((Mesh*)this)->update_buffers();
 734.460 +
 734.461 +	if(!vattr[MESH_ATTR_VERTEX].vbo_valid) {
 734.462 +		error_log("%s: invalid vertex buffer\n", __FUNCTION__);
 734.463 +		return;
 734.464 +	}
 734.465 +
 734.466 +	if(cur_sdr) {
 734.467 +		// rendering with shaders
 734.468 +		if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) {
 734.469 +			error_log("%s: shader attribute location for vertices unset\n", __FUNCTION__);
 734.470 +			return;
 734.471 +		}
 734.472 +
 734.473 +		for(int i=0; i<NUM_MESH_ATTR; i++) {
 734.474 +			int loc = global_sdr_loc[i];
 734.475 +			if(loc >= 0 && vattr[i].vbo_valid) {
 734.476 +				glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo);
 734.477 +				glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0);
 734.478 +				glEnableVertexAttribArray(loc);
 734.479 +			}
 734.480 +		}
 734.481 +	} else {
 734.482 +#ifndef GL_ES_VERSION_2_0
 734.483 +		// rendering with fixed-function (not available in GLES2)
 734.484 +		glBindBuffer(GL_ARRAY_BUFFER, vattr[MESH_ATTR_VERTEX].vbo);
 734.485 +		glVertexPointer(vattr[MESH_ATTR_VERTEX].nelem, GL_FLOAT, 0, 0);
 734.486 +		glEnableClientState(GL_VERTEX_ARRAY);
 734.487 +
 734.488 +		if(vattr[MESH_ATTR_NORMAL].vbo_valid) {
 734.489 +			glBindBuffer(GL_ARRAY_BUFFER, vattr[MESH_ATTR_NORMAL].vbo);
 734.490 +			glNormalPointer(GL_FLOAT, 0, 0);
 734.491 +			glEnableClientState(GL_NORMAL_ARRAY);
 734.492 +		}
 734.493 +		if(vattr[MESH_ATTR_TEXCOORD].vbo_valid) {
 734.494 +			glBindBuffer(GL_ARRAY_BUFFER, vattr[MESH_ATTR_TEXCOORD].vbo);
 734.495 +			glTexCoordPointer(vattr[MESH_ATTR_TEXCOORD].nelem, GL_FLOAT, 0, 0);
 734.496 +			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 734.497 +		}
 734.498 +		if(vattr[MESH_ATTR_COLOR].vbo_valid) {
 734.499 +			glBindBuffer(GL_ARRAY_BUFFER, vattr[MESH_ATTR_COLOR].vbo);
 734.500 +			glColorPointer(vattr[MESH_ATTR_COLOR].nelem, GL_FLOAT, 0, 0);
 734.501 +			glEnableClientState(GL_COLOR_ARRAY);
 734.502 +		}
 734.503 +#endif
 734.504 +	}
 734.505 +	glBindBuffer(GL_ARRAY_BUFFER, 0);
 734.506 +
 734.507 +	if(ibo_valid) {
 734.508 +		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
 734.509 +		glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0);
 734.510 +		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 734.511 +	} else {
 734.512 +		glDrawArrays(GL_TRIANGLES, 0, nverts);
 734.513 +	}
 734.514 +
 734.515 +	if(cur_sdr) {
 734.516 +		// rendered with shaders
 734.517 +		for(int i=0; i<NUM_MESH_ATTR; i++) {
 734.518 +			int loc = global_sdr_loc[i];
 734.519 +			if(loc >= 0 && vattr[i].vbo_valid) {
 734.520 +				glDisableVertexAttribArray(loc);
 734.521 +			}
 734.522 +		}
 734.523 +	} else {
 734.524 +#ifndef GL_ES_VERSION_2_0
 734.525 +		// rendered with fixed-function
 734.526 +		glDisableClientState(GL_VERTEX_ARRAY);
 734.527 +		if(vattr[MESH_ATTR_NORMAL].vbo_valid) {
 734.528 +			glDisableClientState(GL_NORMAL_ARRAY);
 734.529 +		}
 734.530 +		if(vattr[MESH_ATTR_TEXCOORD].vbo_valid) {
 734.531 +			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 734.532 +		}
 734.533 +		if(vattr[MESH_ATTR_COLOR].vbo_valid) {
 734.534 +			glDisableClientState(GL_COLOR_ARRAY);
 734.535 +		}
 734.536 +#endif
 734.537 +	}
 734.538 +}
 734.539 +
 734.540 +void Mesh::draw_wire() const
 734.541 +{
 734.542 +	((Mesh*)this)->update_wire_ibo();
 734.543 +
 734.544 +	if(!vattr[MESH_ATTR_VERTEX].vbo_valid || !wire_ibo_valid) {
 734.545 +		error_log("%s: invalid vertex buffer\n", __FUNCTION__);
 734.546 +		return;
 734.547 +	}
 734.548 +	if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) {
 734.549 +		error_log("%s: shader attribute location for vertices unset\n", __FUNCTION__);
 734.550 +		return;
 734.551 +	}
 734.552 +
 734.553 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
 734.554 +		int loc = global_sdr_loc[i];
 734.555 +		if(loc >= 0 && vattr[i].vbo_valid) {
 734.556 +			glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo);
 734.557 +			glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0);
 734.558 +			glEnableVertexAttribArray(loc);
 734.559 +		}
 734.560 +	}
 734.561 +	glBindBuffer(GL_ARRAY_BUFFER, 0);
 734.562 +
 734.563 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wire_ibo);
 734.564 +	glDrawElements(GL_LINES, nfaces * 6, GL_UNSIGNED_INT, 0);
 734.565 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 734.566 +
 734.567 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
 734.568 +		int loc = global_sdr_loc[i];
 734.569 +		if(loc >= 0 && vattr[i].vbo_valid) {
 734.570 +			glDisableVertexAttribArray(loc);
 734.571 +		}
 734.572 +	}
 734.573 +}
 734.574 +
 734.575 +void Mesh::draw_vertices() const
 734.576 +{
 734.577 +	((Mesh*)this)->update_buffers();
 734.578 +
 734.579 +	if(!vattr[MESH_ATTR_VERTEX].vbo_valid) {
 734.580 +		error_log("%s: invalid vertex buffer\n", __FUNCTION__);
 734.581 +		return;
 734.582 +	}
 734.583 +	if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) {
 734.584 +		error_log("%s: shader attribute location for vertices unset\n", __FUNCTION__);
 734.585 +		return;
 734.586 +	}
 734.587 +
 734.588 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
 734.589 +		int loc = global_sdr_loc[i];
 734.590 +		if(loc >= 0 && vattr[i].vbo_valid) {
 734.591 +			glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo);
 734.592 +			glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0);
 734.593 +			glEnableVertexAttribArray(loc);
 734.594 +		}
 734.595 +	}
 734.596 +	glBindBuffer(GL_ARRAY_BUFFER, 0);
 734.597 +
 734.598 +	glDrawArrays(GL_POINTS, 0, nverts);
 734.599 +
 734.600 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
 734.601 +		int loc = global_sdr_loc[i];
 734.602 +		if(loc >= 0 && vattr[i].vbo_valid) {
 734.603 +			glDisableVertexAttribArray(loc);
 734.604 +		}
 734.605 +	}
 734.606 +}
 734.607 +
 734.608 +void Mesh::draw_normals() const
 734.609 +{
 734.610 +#ifdef USE_OLDGL
 734.611 +	int vert_loc = global_sdr_loc[MESH_ATTR_VERTEX];
 734.612 +	Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX);
 734.613 +	Vector3 *norm = (Vector3*)get_attrib_data(MESH_ATTR_NORMAL);
 734.614 +
 734.615 +	if(!varr || !norm || vert_loc < 0) {
 734.616 +		return;
 734.617 +	}
 734.618 +
 734.619 +	glBegin(GL_LINES);
 734.620 +	for(size_t i=0; i<nverts; i++) {
 734.621 +		glVertexAttrib3f(vert_loc, varr[i].x, varr[i].y, varr[i].z);
 734.622 +		Vector3 end = varr[i] + norm[i] * vis_vecsize;
 734.623 +		glVertexAttrib3f(vert_loc, end.x, end.y, end.z);
 734.624 +	}
 734.625 +	glEnd();
 734.626 +
 734.627 +#endif	// USE_OLDGL
 734.628 +}
 734.629 +
 734.630 +void Mesh::draw_tangents() const
 734.631 +{
 734.632 +#ifdef USE_OLDGL
 734.633 +	int vert_loc = global_sdr_loc[MESH_ATTR_VERTEX];
 734.634 +	Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX);
 734.635 +	Vector3 *tang = (Vector3*)get_attrib_data(MESH_ATTR_TANGENT);
 734.636 +
 734.637 +	if(!varr || !tang || vert_loc < 0) {
 734.638 +		return;
 734.639 +	}
 734.640 +
 734.641 +	glBegin(GL_LINES);
 734.642 +	for(size_t i=0; i<nverts; i++) {
 734.643 +		glVertexAttrib3f(vert_loc, varr[i].x, varr[i].y, varr[i].z);
 734.644 +		Vector3 end = varr[i] + tang[i] * vis_vecsize;
 734.645 +		glVertexAttrib3f(vert_loc, end.x, end.y, end.z);
 734.646 +	}
 734.647 +	glEnd();
 734.648 +
 734.649 +#endif	// USE_OLDGL
 734.650 +}
 734.651 +
 734.652 +void Mesh::get_aabbox(Vector3 *vmin, Vector3 *vmax) const
 734.653 +{
 734.654 +	if(!aabb_valid) {
 734.655 +		((Mesh*)this)->calc_aabb();
 734.656 +	}
 734.657 +	*vmin = aabb.min;
 734.658 +	*vmax = aabb.max;
 734.659 +}
 734.660 +
 734.661 +const AABox &Mesh::get_aabbox() const
 734.662 +{
 734.663 +	if(!aabb_valid) {
 734.664 +		((Mesh*)this)->calc_aabb();
 734.665 +	}
 734.666 +	return aabb;
 734.667 +}
 734.668 +
 734.669 +float Mesh::get_bsphere(Vector3 *center, float *rad) const
 734.670 +{
 734.671 +	if(!bsph_valid) {
 734.672 +		((Mesh*)this)->calc_bsph();
 734.673 +	}
 734.674 +	*center = bsph.center;
 734.675 +	*rad = bsph.radius;
 734.676 +	return bsph.radius;
 734.677 +}
 734.678 +
 734.679 +const Sphere &Mesh::get_bsphere() const
 734.680 +{
 734.681 +	if(!bsph_valid) {
 734.682 +		((Mesh*)this)->calc_bsph();
 734.683 +	}
 734.684 +	return bsph;
 734.685 +}
 734.686 +
 734.687 +/// static function
 734.688 +void Mesh::set_intersect_mode(unsigned int mode)
 734.689 +{
 734.690 +	Mesh::intersect_mode = mode;
 734.691 +}
 734.692 +
 734.693 +/// static function
 734.694 +unsigned int Mesh::get_intersect_mode()
 734.695 +{
 734.696 +	return Mesh::intersect_mode;
 734.697 +}
 734.698 +
 734.699 +/// static function
 734.700 +void Mesh::set_vertex_select_distance(float dist)
 734.701 +{
 734.702 +	Mesh::vertex_sel_dist = dist;
 734.703 +}
 734.704 +
 734.705 +/// static function
 734.706 +float Mesh::get_vertex_select_distance()
 734.707 +{
 734.708 +	return Mesh::vertex_sel_dist;
 734.709 +}
 734.710 +
 734.711 +bool Mesh::intersect(const Ray &ray, HitPoint *hit) const
 734.712 +{
 734.713 +	assert((Mesh::intersect_mode & (ISECT_VERTICES | ISECT_FACE)) != (ISECT_VERTICES | ISECT_FACE));
 734.714 +
 734.715 +	const Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX);
 734.716 +	const Vector3 *narr = (Vector3*)get_attrib_data(MESH_ATTR_NORMAL);
 734.717 +	if(!varr) {
 734.718 +		return false;
 734.719 +	}
 734.720 +	const unsigned int *idxarr = get_index_data();
 734.721 +
 734.722 +	// first test with the bounding box
 734.723 +	AABox box;
 734.724 +	get_aabbox(&box.min, &box.max);
 734.725 +	if(!box.intersect(ray)) {
 734.726 +		return false;
 734.727 +	}
 734.728 +
 734.729 +	HitPoint nearest_hit;
 734.730 +	nearest_hit.dist = FLT_MAX;
 734.731 +	nearest_hit.obj = 0;
 734.732 +
 734.733 +	if(Mesh::intersect_mode & ISECT_VERTICES) {
 734.734 +		// we asked for "intersections" with the vertices of the mesh
 734.735 +		long nearest_vidx = -1;
 734.736 +		float thres_sq = Mesh::vertex_sel_dist * Mesh::vertex_sel_dist;
 734.737 +
 734.738 +		for(unsigned int i=0; i<nverts; i++) {
 734.739 +
 734.740 +			if((Mesh::intersect_mode & ISECT_FRONT) && dot_product(narr[i], ray.dir) > 0) {
 734.741 +				continue;
 734.742 +			}
 734.743 +
 734.744 +			// project the vertex onto the ray line
 734.745 +			float t = dot_product(varr[i] - ray.origin, ray.dir);
 734.746 +			Vector3 vproj = ray.origin + ray.dir * t;
 734.747 +
 734.748 +			float dist_sq = (vproj - varr[i]).length_sq();
 734.749 +			if(dist_sq < thres_sq) {
 734.750 +				if(!hit) {
 734.751 +					return true;
 734.752 +				}
 734.753 +				if(t < nearest_hit.dist) {
 734.754 +					nearest_hit.dist = t;
 734.755 +					nearest_vidx = i;
 734.756 +				}
 734.757 +			}
 734.758 +		}
 734.759 +
 734.760 +		if(nearest_vidx != -1) {
 734.761 +			hitvert = varr[nearest_vidx];
 734.762 +			nearest_hit.obj = &hitvert;
 734.763 +		}
 734.764 +
 734.765 +	} else {
 734.766 +		// regular intersection test with polygons
 734.767 +
 734.768 +		for(unsigned int i=0; i<nfaces; i++) {
 734.769 +			Triangle face(i, varr, idxarr);
 734.770 +
 734.771 +			// ignore back-facing polygons if the mode flags include ISECT_FRONT
 734.772 +			if((Mesh::intersect_mode & ISECT_FRONT) && dot_product(face.get_normal(), ray.dir) > 0) {
 734.773 +				continue;
 734.774 +			}
 734.775 +
 734.776 +			HitPoint fhit;
 734.777 +			if(face.intersect(ray, hit ? &fhit : 0)) {
 734.778 +				if(!hit) {
 734.779 +					return true;
 734.780 +				}
 734.781 +				if(fhit.dist < nearest_hit.dist) {
 734.782 +					nearest_hit = fhit;
 734.783 +					hitface = face;
 734.784 +				}
 734.785 +			}
 734.786 +		}
 734.787 +	}
 734.788 +
 734.789 +	if(nearest_hit.obj) {
 734.790 +		if(hit) {
 734.791 +			*hit = nearest_hit;
 734.792 +
 734.793 +			// if we are interested in the mesh and not the faces set obj to this
 734.794 +			if(Mesh::intersect_mode & ISECT_FACE) {
 734.795 +				hit->obj = &hitface;
 734.796 +			} else if(Mesh::intersect_mode & ISECT_VERTICES) {
 734.797 +				hit->obj = &hitvert;
 734.798 +			} else {
 734.799 +				hit->obj = this;
 734.800 +			}
 734.801 +		}
 734.802 +		return true;
 734.803 +	}
 734.804 +	return false;
 734.805 +}
 734.806 +
 734.807 +
 734.808 +// ------ private member functions ------
 734.809 +
 734.810 +void Mesh::calc_aabb()
 734.811 +{
 734.812 +	// the cast is to force calling the const version which doesn't invalidate
 734.813 +	if(!((const Mesh*)this)->get_attrib_data(MESH_ATTR_VERTEX)) {
 734.814 +		return;
 734.815 +	}
 734.816 +
 734.817 +	aabb.min = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
 734.818 +	aabb.max = -aabb.min;
 734.819 +
 734.820 +	for(unsigned int i=0; i<nverts; i++) {
 734.821 +		Vector4 v = get_attrib(MESH_ATTR_VERTEX, i);
 734.822 +		for(int j=0; j<3; j++) {
 734.823 +			if(v[j] < aabb.min[j]) {
 734.824 +				aabb.min[j] = v[j];
 734.825 +			}
 734.826 +			if(v[j] > aabb.max[j]) {
 734.827 +				aabb.max[j] = v[j];
 734.828 +			}
 734.829 +		}
 734.830 +	}
 734.831 +	aabb_valid = true;
 734.832 +}
 734.833 +
 734.834 +void Mesh::calc_bsph()
 734.835 +{
 734.836 +	// the cast is to force calling the const version which doesn't invalidate
 734.837 +	if(!((const Mesh*)this)->get_attrib_data(MESH_ATTR_VERTEX)) {
 734.838 +		return;
 734.839 +	}
 734.840 +
 734.841 +	Vector3 v;
 734.842 +	bsph.center = Vector3(0, 0, 0);
 734.843 +
 734.844 +	// first find the center
 734.845 +	for(unsigned int i=0; i<nverts; i++) {
 734.846 +		v = get_attrib(MESH_ATTR_VERTEX, i);
 734.847 +		bsph.center += v;
 734.848 +	}
 734.849 +	bsph.center /= (float)nverts;
 734.850 +
 734.851 +	bsph.radius = 0.0f;
 734.852 +	for(unsigned int i=0; i<nverts; i++) {
 734.853 +		v = get_attrib(MESH_ATTR_VERTEX, i);
 734.854 +		float dist_sq = (v - bsph.center).length_sq();
 734.855 +		if(dist_sq > bsph.radius) {
 734.856 +			bsph.radius = dist_sq;
 734.857 +		}
 734.858 +	}
 734.859 +	bsph.radius = sqrt(bsph.radius);
 734.860 +
 734.861 +	bsph_valid = true;
 734.862 +}
 734.863 +
 734.864 +void Mesh::update_buffers()
 734.865 +{
 734.866 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
 734.867 +		if(has_attrib(i) && !vattr[i].vbo_valid) {
 734.868 +			glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo);
 734.869 +			glBufferData(GL_ARRAY_BUFFER, nverts * vattr[i].nelem * sizeof(float), &vattr[i].data[0], GL_STATIC_DRAW);
 734.870 +			vattr[i].vbo_valid = true;
 734.871 +		}
 734.872 +	}
 734.873 +	glBindBuffer(GL_ARRAY_BUFFER, 0);
 734.874 +
 734.875 +	if(idata_valid && !ibo_valid) {
 734.876 +		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
 734.877 +		glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 3 * sizeof(unsigned int), &idata[0], GL_STATIC_DRAW);
 734.878 +		ibo_valid = true;
 734.879 +	}
 734.880 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 734.881 +}
 734.882 +
 734.883 +void Mesh::update_wire_ibo()
 734.884 +{
 734.885 +	update_buffers();
 734.886 +
 734.887 +	if(wire_ibo_valid) {
 734.888 +		return;
 734.889 +	}
 734.890 +
 734.891 +	if(!wire_ibo) {
 734.892 +		glGenBuffers(1, &wire_ibo);
 734.893 +	}
 734.894 +
 734.895 +	unsigned int *wire_idxarr = new unsigned int[nfaces * 6];
 734.896 +	unsigned int *dest = wire_idxarr;
 734.897 +
 734.898 +	if(ibo_valid) {
 734.899 +		// we're dealing with an indexed mesh
 734.900 +		const unsigned int *idxarr = ((const Mesh*)this)->get_index_data();
 734.901 +
 734.902 +		for(unsigned int i=0; i<nfaces; i++) {
 734.903 +			*dest++ = idxarr[0];
 734.904 +			*dest++ = idxarr[1];
 734.905 +			*dest++ = idxarr[1];
 734.906 +			*dest++ = idxarr[2];
 734.907 +			*dest++ = idxarr[2];
 734.908 +			*dest++ = idxarr[0];
 734.909 +			idxarr += 3;
 734.910 +		}
 734.911 +	} else {
 734.912 +		// not an indexed mesh ...
 734.913 +		for(unsigned int i=0; i<nfaces; i++) {
 734.914 +			int vidx = i * 3;
 734.915 +			*dest++ = vidx;
 734.916 +			*dest++ = vidx + 1;
 734.917 +			*dest++ = vidx + 1;
 734.918 +			*dest++ = vidx + 2;
 734.919 +			*dest++ = vidx + 2;
 734.920 +			*dest++ = vidx;
 734.921 +		}
 734.922 +	}
 734.923 +
 734.924 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wire_ibo);
 734.925 +	glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 6 * sizeof(unsigned int), wire_idxarr, GL_STATIC_DRAW);
 734.926 +	delete [] wire_idxarr;
 734.927 +	wire_ibo_valid = true;
 734.928 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 734.929 +}
 734.930 +
 734.931 +
 734.932 +// ------ class Triangle ------
 734.933 +Triangle::Triangle()
 734.934 +{
 734.935 +	normal_valid = false;
 734.936 +	id = -1;
 734.937 +}
 734.938 +
 734.939 +Triangle::Triangle(const Vector3 &v0, const Vector3 &v1, const Vector3 &v2)
 734.940 +{
 734.941 +	v[0] = v0;
 734.942 +	v[1] = v1;
 734.943 +	v[2] = v2;
 734.944 +	normal_valid = false;
 734.945 +	id = -1;
 734.946 +}
 734.947 +
 734.948 +Triangle::Triangle(int n, const Vector3 *varr, const unsigned int *idxarr)
 734.949 +{
 734.950 +	if(idxarr) {
 734.951 +		v[0] = varr[idxarr[n * 3]];
 734.952 +		v[1] = varr[idxarr[n * 3 + 1]];
 734.953 +		v[2] = varr[idxarr[n * 3 + 2]];
 734.954 +	} else {
 734.955 +		v[0] = varr[n * 3];
 734.956 +		v[1] = varr[n * 3 + 1];
 734.957 +		v[2] = varr[n * 3 + 2];
 734.958 +	}
 734.959 +	normal_valid = false;
 734.960 +	id = n;
 734.961 +}
 734.962 +
 734.963 +void Triangle::calc_normal()
 734.964 +{
 734.965 +	normal = cross_product(v[1] - v[0], v[2] - v[0]).normalized();
 734.966 +	normal_valid = true;
 734.967 +}
 734.968 +
 734.969 +const Vector3 &Triangle::get_normal() const
 734.970 +{
 734.971 +	if(!normal_valid) {
 734.972 +		((Triangle*)this)->calc_normal();
 734.973 +	}
 734.974 +	return normal;
 734.975 +}
 734.976 +
 734.977 +void Triangle::transform(const Matrix4x4 &xform)
 734.978 +{
 734.979 +	v[0].transform(xform);
 734.980 +	v[1].transform(xform);
 734.981 +	v[2].transform(xform);
 734.982 +	normal_valid = false;
 734.983 +}
 734.984 +
 734.985 +void Triangle::draw() const
 734.986 +{
 734.987 +	Vector3 n[3];
 734.988 +	n[0] = get_normal();
 734.989 +	n[1] = get_normal();
 734.990 +	n[2] = get_normal();
 734.991 +
 734.992 +	int vloc = Mesh::get_attrib_location(MESH_ATTR_VERTEX);
 734.993 +	int nloc = Mesh::get_attrib_location(MESH_ATTR_NORMAL);
 734.994 +
 734.995 +	glEnableVertexAttribArray(vloc);
 734.996 +	glVertexAttribPointer(vloc, 3, GL_FLOAT, GL_FALSE, 0, &v[0].x);
 734.997 +	glVertexAttribPointer(nloc, 3, GL_FLOAT, GL_FALSE, 0, &n[0].x);
 734.998 +
 734.999 +	glDrawArrays(GL_TRIANGLES, 0, 3);
734.1000 +
734.1001 +	glDisableVertexAttribArray(vloc);
734.1002 +	glDisableVertexAttribArray(nloc);
734.1003 +	CHECKGLERR;
734.1004 +}
734.1005 +
734.1006 +void Triangle::draw_wire() const
734.1007 +{
734.1008 +	static const int idxarr[] = {0, 1, 1, 2, 2, 0};
734.1009 +	int vloc = Mesh::get_attrib_location(MESH_ATTR_VERTEX);
734.1010 +
734.1011 +	glEnableVertexAttribArray(vloc);
734.1012 +	glVertexAttribPointer(vloc, 3, GL_FLOAT, GL_FALSE, 0, &v[0].x);
734.1013 +
734.1014 +	glDrawElements(GL_LINES, 6, GL_UNSIGNED_INT, idxarr);
734.1015 +
734.1016 +	glDisableVertexAttribArray(vloc);
734.1017 +	CHECKGLERR;
734.1018 +}
734.1019 +
734.1020 +Vector3 Triangle::calc_barycentric(const Vector3 &pos) const
734.1021 +{
734.1022 +	Vector3 norm = get_normal();
734.1023 +
734.1024 +	float area_sq = fabs(dot_product(cross_product(v[1] - v[0], v[2] - v[0]), norm));
734.1025 +	if(area_sq < 1e-5) {
734.1026 +		return Vector3(0, 0, 0);
734.1027 +	}
734.1028 +
734.1029 +	float asq0 = fabs(dot_product(cross_product(v[1] - pos, v[2] - pos), norm));
734.1030 +	float asq1 = fabs(dot_product(cross_product(v[2] - pos, v[0] - pos), norm));
734.1031 +	float asq2 = fabs(dot_product(cross_product(v[0] - pos, v[1] - pos), norm));
734.1032 +
734.1033 +	return Vector3(asq0 / area_sq, asq1 / area_sq, asq2 / area_sq);
734.1034 +}
734.1035 +
734.1036 +bool Triangle::intersect(const Ray &ray, HitPoint *hit) const
734.1037 +{
734.1038 +	Vector3 normal = get_normal();
734.1039 +
734.1040 +	float ndotdir = dot_product(ray.dir, normal);
734.1041 +	if(fabs(ndotdir) < 1e-4) {
734.1042 +		return false;
734.1043 +	}
734.1044 +
734.1045 +	Vector3 vertdir = v[0] - ray.origin;
734.1046 +	float t = dot_product(normal, vertdir) / ndotdir;
734.1047 +
734.1048 +	Vector3 pos = ray.origin + ray.dir * t;
734.1049 +	Vector3 bary = calc_barycentric(pos);
734.1050 +
734.1051 +	if(bary.x + bary.y + bary.z > 1.00001) {
734.1052 +		return false;
734.1053 +	}
734.1054 +
734.1055 +	if(hit) {
734.1056 +		hit->dist = t;
734.1057 +		hit->pos = ray.origin + ray.dir * t;
734.1058 +		hit->normal = normal;
734.1059 +		hit->obj = this;
734.1060 +	}
734.1061 +	return true;
734.1062 +}
   735.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   735.2 +++ b/src/mesh.h	Sat Feb 01 19:58:19 2014 +0200
   735.3 @@ -0,0 +1,219 @@
   735.4 +#ifndef MESH_H_
   735.5 +#define MESH_H_
   735.6 +
   735.7 +#include <string>
   735.8 +#include <vector>
   735.9 +#include <vmath/vmath.h>
  735.10 +#include "geom.h"
  735.11 +
  735.12 +enum {
  735.13 +	MESH_ATTR_VERTEX,
  735.14 +	MESH_ATTR_NORMAL,
  735.15 +	MESH_ATTR_TANGENT,
  735.16 +	MESH_ATTR_TEXCOORD,
  735.17 +	MESH_ATTR_COLOR,
  735.18 +	MESH_ATTR_BONEWEIGHTS,
  735.19 +	MESH_ATTR_BONEIDX,
  735.20 +
  735.21 +	NUM_MESH_ATTR
  735.22 +};
  735.23 +
  735.24 +// intersection mode flags
  735.25 +enum {
  735.26 +	ISECT_DEFAULT	= 0,	// default (whole mesh, all intersections)
  735.27 +	ISECT_FRONT		= 1,	// front-faces only
  735.28 +	ISECT_FACE		= 2,	// return intersected face pointer instead of mesh
  735.29 +	ISECT_VERTICES	= 4		// return (?) TODO
  735.30 +};
  735.31 +
  735.32 +class XFormNode;
  735.33 +
  735.34 +
  735.35 +class Triangle {
  735.36 +public:
  735.37 +	Vector3 v[3];
  735.38 +	Vector3 normal;
  735.39 +	bool normal_valid;
  735.40 +	int id;
  735.41 +
  735.42 +	Triangle();
  735.43 +	Triangle(const Vector3 &v0, const Vector3 &v1, const Vector3 &v2);
  735.44 +	Triangle(int n, const Vector3 *varr, const unsigned int *idxarr = 0);
  735.45 +
  735.46 +	/// calculate normal (quite expensive)
  735.47 +	void calc_normal();
  735.48 +	const Vector3 &get_normal() const;
  735.49 +
  735.50 +	void transform(const Matrix4x4 &xform);
  735.51 +
  735.52 +	void draw() const;
  735.53 +	void draw_wire() const;
  735.54 +
  735.55 +	/// calculate barycentric coordinates of a point
  735.56 +	Vector3 calc_barycentric(const Vector3 &pos) const;
  735.57 +
  735.58 +	bool intersect(const Ray &ray, HitPoint *hit = 0) const;
  735.59 +};
  735.60 +
  735.61 +
  735.62 +class Mesh {
  735.63 +private:
  735.64 +	std::string name;
  735.65 +	unsigned int nverts, nfaces;
  735.66 +
  735.67 +	// current value for each attribute for the immedate mode
  735.68 +	// interface.
  735.69 +	Vector4 cur_val[NUM_MESH_ATTR];
  735.70 +
  735.71 +	unsigned int buffer_objects[NUM_MESH_ATTR + 1];
  735.72 +
  735.73 +	// vertex attribute data and buffer objects
  735.74 +	struct {
  735.75 +		int nelem;					// number of elements per attribute range: [1, 4]
  735.76 +		std::vector<float> data;
  735.77 +		unsigned int vbo;
  735.78 +		mutable bool vbo_valid;		// if this is false, the vbo needs updating from the data
  735.79 +		mutable bool data_valid;	// if this is false, the data needs to be pulled from the vbo
  735.80 +		//int sdr_loc;
  735.81 +	} vattr[NUM_MESH_ATTR];
  735.82 +
  735.83 +	static int global_sdr_loc[NUM_MESH_ATTR];
  735.84 +
  735.85 +	std::vector<XFormNode*> bones;	// bones affecting this mesh
  735.86 +
  735.87 +	// index data and buffer object
  735.88 +	std::vector<unsigned int> idata;
  735.89 +	unsigned int ibo;
  735.90 +	mutable bool ibo_valid;
  735.91 +	mutable bool idata_valid;
  735.92 +
  735.93 +	// index buffer object for wireframe rendering (constructed on demand)
  735.94 +	unsigned int wire_ibo;
  735.95 +	mutable bool wire_ibo_valid;
  735.96 +
  735.97 +	// axis-aligned bounding box
  735.98 +	mutable AABox aabb;
  735.99 +	mutable bool aabb_valid;
 735.100 +
 735.101 +	// bounding sphere
 735.102 +	mutable Sphere bsph;
 735.103 +	mutable bool bsph_valid;
 735.104 +
 735.105 +	// keeps the last intersected face
 735.106 +	mutable Triangle hitface;
 735.107 +	// keeps the last intersected vertex position
 735.108 +	mutable Vector3 hitvert;
 735.109 +
 735.110 +	void calc_aabb();
 735.111 +	void calc_bsph();
 735.112 +
 735.113 +	static unsigned int intersect_mode;
 735.114 +	static float vertex_sel_dist;
 735.115 +
 735.116 +	static float vis_vecsize;
 735.117 +
 735.118 +	/// update the VBOs after data has changed (invalid vbo/ibo)
 735.119 +	void update_buffers();
 735.120 +	/// construct/update the wireframe index buffer (called from draw_wire).
 735.121 +	void update_wire_ibo();
 735.122 +
 735.123 +
 735.124 +public:
 735.125 +	Mesh();
 735.126 +	~Mesh();
 735.127 +
 735.128 +	void set_name(const char *name);
 735.129 +	const char *get_name() const;
 735.130 +
 735.131 +	bool has_attrib(int attr) const;
 735.132 +
 735.133 +	// clears everything about this mesh, and returns to the newly constructed state
 735.134 +	void clear();
 735.135 +
 735.136 +	// access the vertex attribute data
 735.137 +	// if vdata == 0, space is just allocated
 735.138 +	float *set_attrib_data(int attrib, int nelem, unsigned int num, const float *vdata = 0); // invalidates vbo
 735.139 +	float *get_attrib_data(int attrib);	// invalidates vbo
 735.140 +	const float *get_attrib_data(int attrib) const;
 735.141 +
 735.142 +	// simple access to any particular attribute
 735.143 +	void set_attrib(int attrib, int idx, const Vector4 &v); // invalidates vbo
 735.144 +	Vector4 get_attrib(int attrib, int idx) const;
 735.145 +
 735.146 +	int get_attrib_count(int attrib) const;
 735.147 +
 735.148 +	// ... same for index data
 735.149 +	unsigned int *set_index_data(int num, const unsigned int *indices = 0); // invalidates ibo
 735.150 +	unsigned int *get_index_data();	// invalidates ibo
 735.151 +	const unsigned int *get_index_data() const;
 735.152 +
 735.153 +	int get_index_count() const;
 735.154 +
 735.155 +	void append(const Mesh &mesh);
 735.156 +
 735.157 +	// immediate-mode style mesh construction interface
 735.158 +	void vertex(float x, float y, float z);
 735.159 +	void normal(float nx, float ny, float nz);
 735.160 +	void tangent(float tx, float ty, float tz);
 735.161 +	void texcoord(float u, float v, float w = 0.0f);
 735.162 +	void boneweights(float w1, float w2, float w3, float w4);
 735.163 +	void boneidx(int idx1, int idx2, int idx3, int idx4);
 735.164 +
 735.165 +	// optional face function to easily append index data
 735.166 +	void face(unsigned int v0, unsigned int v1, unsigned int v2);
 735.167 +
 735.168 +	int get_poly_count() const;
 735.169 +
 735.170 +	/* apply a transformation to the vertices and its inverse-transpose
 735.171 +	 * to the normals and tangents.
 735.172 +	 */
 735.173 +	void apply_xform(const Matrix4x4 &xform);
 735.174 +	void apply_xform(const Matrix4x4 &xform, const Matrix4x4 &dir_xform);
 735.175 +
 735.176 +	// adds a bone and returns its index
 735.177 +	int add_bone(XFormNode *bone);
 735.178 +	const XFormNode *get_bone(int idx) const;
 735.179 +	int get_bones_count() const;
 735.180 +
 735.181 +	// access the shader attribute locations
 735.182 +	static void set_attrib_location(int attr, int loc);
 735.183 +	static int get_attrib_location(int attr);
 735.184 +	static void clear_attrib_locations();
 735.185 +
 735.186 +	static void set_vis_vecsize(float sz);
 735.187 +	static float get_vis_vecsize();
 735.188 +
 735.189 +	void draw() const;
 735.190 +	void draw_wire() const;
 735.191 +	void draw_vertices() const;
 735.192 +	void draw_normals() const;
 735.193 +	void draw_tangents() const;
 735.194 +
 735.195 +	/** get the bounding box in local space. The result will be cached, and subsequent
 735.196 +	 * calls will return the same box. The cache gets invalidated by any functions that can affect
 735.197 +	 * the vertex data (non-const variant of get_attrib_data(MESH_ATTR_VERTEX, ...) included).
 735.198 +	 * @{ */
 735.199 +	void get_aabbox(Vector3 *vmin, Vector3 *vmax) const;
 735.200 +	const AABox &get_aabbox() const;
 735.201 +	/// @}
 735.202 +
 735.203 +	/** get the bounding sphere in local space. The result will be cached, and subsequent
 735.204 +	 * calls will return the same box. The cache gets invalidated by any functions that can affect
 735.205 +	 * the vertex data (non-const variant of get_attrib_data(MESH_ATTR_VERTEX, ...) included).
 735.206 +	 * @{ */
 735.207 +	float get_bsphere(Vector3 *center, float *rad) const;
 735.208 +	const Sphere &get_bsphere() const;
 735.209 +
 735.210 +	static void set_intersect_mode(unsigned int mode);
 735.211 +	static unsigned int get_intersect_mode();
 735.212 +	static void set_vertex_select_distance(float dist);
 735.213 +	static float get_vertex_select_distance();
 735.214 +
 735.215 +	/** Find the intersection between the mesh and a ray.
 735.216 +	 * XXX Brute force at the moment, not intended to be used for anything other than picking in tools.
 735.217 +	 *     If you intend to use it in a speed-critical part of the code, you'll *have* to optimize it!
 735.218 +	 */
 735.219 +	bool intersect(const Ray &ray, HitPoint *hit = 0) const;
 735.220 +};
 735.221 +
 735.222 +#endif	// MESH_H_
   736.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   736.2 +++ b/src/meshgen.cc	Sat Feb 01 19:58:19 2014 +0200
   736.3 @@ -0,0 +1,373 @@
   736.4 +#include "meshgen.h"
   736.5 +#include "mesh.h"
   736.6 +#include "logger.h"
   736.7 +
   736.8 +// -------- sphere --------
   736.9 +
  736.10 +#define SURAD(u)	((u) * 2.0 * M_PI)
  736.11 +#define SVRAD(v)	((v) * M_PI)
  736.12 +
  736.13 +static Vector3 sphvec(float theta, float phi)
  736.14 +{
  736.15 +	return Vector3(sin(theta) * sin(phi),
  736.16 +			cos(phi),
  736.17 +			cos(theta) * sin(phi));
  736.18 +}
  736.19 +
  736.20 +void gen_sphere(Mesh *mesh, float rad, int usub, int vsub, float urange, float vrange)
  736.21 +{
  736.22 +	if(usub < 4) usub = 4;
  736.23 +	if(vsub < 2) vsub = 2;
  736.24 +
  736.25 +	int uverts = usub + 1;
  736.26 +	int vverts = vsub + 1;
  736.27 +
  736.28 +	int num_verts = uverts * vverts;
  736.29 +	int num_quads = usub * vsub;
  736.30 +	int num_tri = num_quads * 2;
  736.31 +
  736.32 +	mesh->clear();
  736.33 +	Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
  736.34 +	Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
  736.35 +	Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
  736.36 +	Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
  736.37 +	unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
  736.38 +
  736.39 +	float du = urange / (float)(uverts - 1);
  736.40 +	float dv = vrange / (float)(vverts - 1);
  736.41 +
  736.42 +	float u = 0.0;
  736.43 +	for(int i=0; i<uverts; i++) {
  736.44 +		float theta = SURAD(u * urange);
  736.45 +
  736.46 +		float v = 0.0;
  736.47 +		for(int j=0; j<vverts; j++) {
  736.48 +			float phi = SVRAD(v * vrange);
  736.49 +
  736.50 +			Vector3 pos = sphvec(theta, phi);
  736.51 +
  736.52 +			*varr++ = pos * rad;
  736.53 +			*narr++ = pos;
  736.54 +			*tarr++ = (sphvec(theta + 0.1, M_PI / 2.0) - sphvec(theta - 0.1, M_PI / 2.0)).normalized();
  736.55 +			*uvarr++ = Vector2(u * urange, v * vrange);
  736.56 +
  736.57 +			if(i < usub && j < vsub) {
  736.58 +				int idx = i * vverts + j;
  736.59 +				*idxarr++ = idx;
  736.60 +				*idxarr++ = idx + 1;
  736.61 +				*idxarr++ = idx + vverts + 1;
  736.62 +
  736.63 +				*idxarr++ = idx;
  736.64 +				*idxarr++ = idx + vverts + 1;
  736.65 +				*idxarr++ = idx + vverts;
  736.66 +			}
  736.67 +
  736.68 +			v += dv;
  736.69 +		}
  736.70 +		u += du;
  736.71 +	}
  736.72 +}
  736.73 +
  736.74 +
  736.75 +// -------- cylinder --------
  736.76 +
  736.77 +static Vector3 cylvec(float theta, float height)
  736.78 +{
  736.79 +	return Vector3(sin(theta), height, cos(theta));
  736.80 +}
  736.81 +
  736.82 +void gen_cylinder(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub, float urange, float vrange)
  736.83 +{
  736.84 +	if(usub < 4) usub = 4;
  736.85 +	if(vsub < 1) vsub = 1;
  736.86 +
  736.87 +	int uverts = usub + 1;
  736.88 +	int vverts = vsub + 1;
  736.89 +
  736.90 +	int num_body_verts = uverts * vverts;
  736.91 +	int num_body_quads = usub * vsub;
  736.92 +	int num_body_tri = num_body_quads * 2;
  736.93 +
  736.94 +	int capvverts = capsub ? capsub + 1 : 0;
  736.95 +	int num_cap_verts = uverts * capvverts;
  736.96 +	int num_cap_quads = usub * capsub;
  736.97 +	int num_cap_tri = num_cap_quads * 2;
  736.98 +
  736.99 +	int num_verts = num_body_verts + num_cap_verts * 2;
 736.100 +	int num_tri = num_body_tri + num_cap_tri * 2;
 736.101 +
 736.102 +	mesh->clear();
 736.103 +	Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
 736.104 +	Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
 736.105 +	Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
 736.106 +	Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
 736.107 +	unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
 736.108 +
 736.109 +	float du = urange / (float)(uverts - 1);
 736.110 +	float dv = vrange / (float)(vverts - 1);
 736.111 +
 736.112 +	float u = 0.0;
 736.113 +	for(int i=0; i<uverts; i++) {
 736.114 +		float theta = SURAD(u);
 736.115 +
 736.116 +		float v = 0.0;
 736.117 +		for(int j=0; j<vverts; j++) {
 736.118 +			float y = (v - 0.5) * height;
 736.119 +			Vector3 pos = cylvec(theta, y);
 736.120 +
 736.121 +			*varr++ = Vector3(pos.x * rad, pos.y, pos.z * rad);
 736.122 +			*narr++ = Vector3(pos.x, 0.0, pos.z);
 736.123 +			*tarr++ = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized();
 736.124 +			*uvarr++ = Vector2(u * urange, v * vrange);
 736.125 +
 736.126 +			if(i < usub && j < vsub) {
 736.127 +				int idx = i * vverts + j;
 736.128 +
 736.129 +				*idxarr++ = idx;
 736.130 +				*idxarr++ = idx + vverts + 1;
 736.131 +				*idxarr++ = idx + 1;
 736.132 +
 736.133 +				*idxarr++ = idx;
 736.134 +				*idxarr++ = idx + vverts;
 736.135 +				*idxarr++ = idx + vverts + 1;
 736.136 +			}
 736.137 +
 736.138 +			v += dv;
 736.139 +		}
 736.140 +		u += du;
 736.141 +	}
 736.142 +
 736.143 +
 736.144 +	// now the cap!
 736.145 +	if(!capsub) {
 736.146 +		return;
 736.147 +	}
 736.148 +
 736.149 +	dv = 1.0 / (float)(capvverts - 1);
 736.150 +
 736.151 +	u = 0.0;
 736.152 +	for(int i=0; i<uverts; i++) {
 736.153 +		float theta = SURAD(u);
 736.154 +
 736.155 +		float v = 0.0;
 736.156 +		for(int j=0; j<capvverts; j++) {
 736.157 +			float r = v * rad;
 736.158 +
 736.159 +			Vector3 pos = cylvec(theta, height / 2.0) * r;
 736.160 +			pos.y = height / 2.0;
 736.161 +			Vector3 tang = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized();
 736.162 +
 736.163 +			*varr++ = pos;
 736.164 +			*narr++ = Vector3(0, 1, 0);
 736.165 +			*tarr++ = tang;
 736.166 +			*uvarr++ = Vector2(u * urange, v);
 736.167 +
 736.168 +			pos.y = -height / 2.0;
 736.169 +			*varr++ = pos;
 736.170 +			*narr++ = Vector3(0, -1, 0);
 736.171 +			*tarr++ = -tang;
 736.172 +			*uvarr++ = Vector2(u * urange, v);
 736.173 +
 736.174 +			if(i < usub && j < capsub) {
 736.175 +				unsigned int idx = num_body_verts + (i * capvverts + j) * 2;
 736.176 +
 736.177 +				unsigned int vidx[4] = {
 736.178 +					idx,
 736.179 +					idx + capvverts * 2,
 736.180 +					idx + (capvverts + 1) * 2,
 736.181 +					idx + 2
 736.182 +				};
 736.183 +
 736.184 +				*idxarr++ = vidx[0];
 736.185 +				*idxarr++ = vidx[2];
 736.186 +				*idxarr++ = vidx[1];
 736.187 +				*idxarr++ = vidx[0];
 736.188 +				*idxarr++ = vidx[3];
 736.189 +				*idxarr++ = vidx[2];
 736.190 +
 736.191 +				*idxarr++ = vidx[0] + 1;
 736.192 +				*idxarr++ = vidx[1] + 1;
 736.193 +				*idxarr++ = vidx[2] + 1;
 736.194 +				*idxarr++ = vidx[0] + 1;
 736.195 +				*idxarr++ = vidx[2] + 1;
 736.196 +				*idxarr++ = vidx[3] + 1;
 736.197 +			}
 736.198 +
 736.199 +			v += dv;
 736.200 +		}
 736.201 +		u += du;
 736.202 +	}
 736.203 +}
 736.204 +
 736.205 +// -------- cone --------
 736.206 +
 736.207 +static Vector3 conevec(float theta, float y, float height)
 736.208 +{
 736.209 +	float scale = 1.0 - y / height;
 736.210 +	return Vector3(sin(theta) * scale, y, cos(theta) * scale);
 736.211 +}
 736.212 +
 736.213 +void gen_cone(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub, float urange, float vrange)
 736.214 +{
 736.215 +	if(usub < 4) usub = 4;
 736.216 +	if(vsub < 1) vsub = 1;
 736.217 +
 736.218 +	int uverts = usub + 1;
 736.219 +	int vverts = vsub + 1;
 736.220 +
 736.221 +	int num_body_verts = uverts * vverts;
 736.222 +	int num_body_quads = usub * vsub;
 736.223 +	int num_body_tri = num_body_quads * 2;
 736.224 +
 736.225 +	int capvverts = capsub ? capsub + 1 : 0;
 736.226 +	int num_cap_verts = uverts * capvverts;
 736.227 +	int num_cap_quads = usub * capsub;
 736.228 +	int num_cap_tri = num_cap_quads * 2;
 736.229 +
 736.230 +	int num_verts = num_body_verts + num_cap_verts;
 736.231 +	int num_tri = num_body_tri + num_cap_tri;
 736.232 +
 736.233 +	mesh->clear();
 736.234 +	Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
 736.235 +	Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
 736.236 +	Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
 736.237 +	Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
 736.238 +	unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
 736.239 +
 736.240 +	float du = urange / (float)(uverts - 1);
 736.241 +	float dv = vrange / (float)(vverts - 1);
 736.242 +
 736.243 +	float u = 0.0;
 736.244 +	for(int i=0; i<uverts; i++) {
 736.245 +		float theta = SURAD(u);
 736.246 +
 736.247 +		float v = 0.0;
 736.248 +		for(int j=0; j<vverts; j++) {
 736.249 +			float y = v * height;
 736.250 +			Vector3 pos = conevec(theta, y, height);
 736.251 +
 736.252 +			Vector3 tang = (conevec(theta + 0.1, 0.0, height) - conevec(theta - 0.1, 0.0, height)).normalized();
 736.253 +			Vector3 bitang = (conevec(theta, y + 0.1, height) - pos).normalized();
 736.254 +
 736.255 +			*varr++ = Vector3(pos.x * rad, pos.y, pos.z * rad);
 736.256 +			*narr++ = cross_product(tang, bitang);
 736.257 +			*tarr++ = tang;
 736.258 +			*uvarr++ = Vector2(u * urange, v * vrange);
 736.259 +
 736.260 +			if(i < usub && j < vsub) {
 736.261 +				int idx = i * vverts + j;
 736.262 +
 736.263 +				*idxarr++ = idx;
 736.264 +				*idxarr++ = idx + vverts + 1;
 736.265 +				*idxarr++ = idx + 1;
 736.266 +
 736.267 +				*idxarr++ = idx;
 736.268 +				*idxarr++ = idx + vverts;
 736.269 +				*idxarr++ = idx + vverts + 1;
 736.270 +			}
 736.271 +
 736.272 +			v += dv;
 736.273 +		}
 736.274 +		u += du;
 736.275 +	}
 736.276 +
 736.277 +
 736.278 +	// now the bottom cap!
 736.279 +	if(!capsub) {
 736.280 +		return;
 736.281 +	}
 736.282 +
 736.283 +	dv = 1.0 / (float)(capvverts - 1);
 736.284 +
 736.285 +	u = 0.0;
 736.286 +	for(int i=0; i<uverts; i++) {
 736.287 +		float theta = SURAD(u);
 736.288 +
 736.289 +		float v = 0.0;
 736.290 +		for(int j=0; j<capvverts; j++) {
 736.291 +			float r = v * rad;
 736.292 +
 736.293 +			Vector3 pos = conevec(theta, 0.0, height) * r;
 736.294 +			Vector3 tang = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized();
 736.295 +
 736.296 +			*varr++ = pos;
 736.297 +			*narr++ = Vector3(0, -1, 0);
 736.298 +			*tarr++ = tang;
 736.299 +			*uvarr++ = Vector2(u * urange, v);
 736.300 +
 736.301 +			if(i < usub && j < capsub) {
 736.302 +				unsigned int idx = num_body_verts + i * capvverts + j;
 736.303 +
 736.304 +				unsigned int vidx[4] = {
 736.305 +					idx,
 736.306 +					idx + capvverts,
 736.307 +					idx + (capvverts + 1),
 736.308 +					idx + 1
 736.309 +				};
 736.310 +
 736.311 +				*idxarr++ = vidx[0];
 736.312 +				*idxarr++ = vidx[1];
 736.313 +				*idxarr++ = vidx[2];
 736.314 +				*idxarr++ = vidx[0];
 736.315 +				*idxarr++ = vidx[2];
 736.316 +				*idxarr++ = vidx[3];
 736.317 +			}
 736.318 +
 736.319 +			v += dv;
 736.320 +		}
 736.321 +		u += du;
 736.322 +	}
 736.323 +}
 736.324 +
 736.325 +
 736.326 +// -------- plane --------
 736.327 +
 736.328 +void gen_plane(Mesh *mesh, float width, float height, int usub, int vsub)
 736.329 +{
 736.330 +	if(usub < 1) usub = 1;
 736.331 +	if(vsub < 1) vsub = 1;
 736.332 +
 736.333 +	mesh->clear();
 736.334 +
 736.335 +	int uverts = usub + 1;
 736.336 +	int vverts = vsub + 1;
 736.337 +	int num_verts = uverts * vverts;
 736.338 +
 736.339 +	int num_quads = usub * vsub;
 736.340 +	int num_tri = num_quads * 2;
 736.341 +
 736.342 +	Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
 736.343 +	Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
 736.344 +	Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
 736.345 +	Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
 736.346 +	unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
 736.347 +
 736.348 +	float du = 1.0 / (float)usub;
 736.349 +	float dv = 1.0 / (float)vsub;
 736.350 +
 736.351 +	float u = 0.0;
 736.352 +	for(int i=0; i<uverts; i++) {
 736.353 +		float v = 0.0;
 736.354 +		for(int j=0; j<vverts; j++) {
 736.355 +			*varr++ = Vector3((u - 0.5) * width, (v - 0.5) * height, 0.0);
 736.356 +			*narr++ = Vector3(0, 0, 1);
 736.357 +			*tarr++ = Vector3(1, 0, 0);
 736.358 +			*uvarr++ = Vector2(u, v);
 736.359 +
 736.360 +			if(i < usub && j < vsub) {
 736.361 +				int idx = i * vverts + j;
 736.362 +
 736.363 +				*idxarr++ = idx;
 736.364 +				*idxarr++ = idx + vverts + 1;
 736.365 +				*idxarr++ = idx + 1;
 736.366 +
 736.367 +				*idxarr++ = idx;
 736.368 +				*idxarr++ = idx + vverts;
 736.369 +				*idxarr++ = idx + vverts + 1;
 736.370 +			}
 736.371 +
 736.372 +			v += dv;
 736.373 +		}
 736.374 +		u += du;
 736.375 +	}
 736.376 +}
   737.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   737.2 +++ b/src/meshgen.h	Sat Feb 01 19:58:19 2014 +0200
   737.3 @@ -0,0 +1,11 @@
   737.4 +#ifndef MESHGEN_H_
   737.5 +#define MESHGEN_H_
   737.6 +
   737.7 +class Mesh;
   737.8 +
   737.9 +void gen_sphere(Mesh *mesh, float rad, int usub, int vsub, float urange = 1.0, float vrange = 1.0);
  737.10 +void gen_cylinder(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub = 0, float urange = 1.0, float vrange = 1.0);
  737.11 +void gen_cone(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub = 0, float urange = 1.0, float vrange = 1.0);
  737.12 +void gen_plane(Mesh *mesh, float width, float height, int usub = 1, int vsub = 1);
  737.13 +
  737.14 +#endif	// MESHGEN_H_
   738.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   738.2 +++ b/src/object.cc	Sat Feb 01 19:58:19 2014 +0200
   738.3 @@ -0,0 +1,332 @@
   738.4 +#include <float.h>
   738.5 +#include "object.h"
   738.6 +#include "opengl.h"
   738.7 +#include "shader.h"
   738.8 +#include "unistate.h"
   738.9 +#include "logger.h"
  738.10 +
  738.11 +static void destroy_all_rec(XFormNode *node);
  738.12 +static void get_all_meshes_rec(XFormNode *node, std::list<Mesh*> *reslist);
  738.13 +
  738.14 +DrawMode Object::draw_mode = DRAW_DEFAULT;
  738.15 +
  738.16 +Object::Object()
  738.17 +{
  738.18 +	type = NODE_OBJECT;
  738.19 +	mesh = 0;
  738.20 +}
  738.21 +
  738.22 +void Object::destroy_all()
  738.23 +{
  738.24 +	destroy_all_rec(this);
  738.25 +}
  738.26 +
  738.27 +static void destroy_all_rec(XFormNode *node)
  738.28 +{
  738.29 +	if(!node) {
  738.30 +		return;
  738.31 +	}
  738.32 +
  738.33 +	for(int i=0; i<node->get_children_count(); i++) {
  738.34 +		destroy_all_rec(node->get_child(i));
  738.35 +	}
  738.36 +	delete node;
  738.37 +}
  738.38 +
  738.39 +void Object::set_mesh(Mesh *m)
  738.40 +{
  738.41 +	mesh = m;
  738.42 +}
  738.43 +
  738.44 +Mesh *Object::get_mesh()
  738.45 +{
  738.46 +	return mesh;
  738.47 +}
  738.48 +
  738.49 +const Mesh *Object::get_mesh() const
  738.50 +{
  738.51 +	return mesh;
  738.52 +}
  738.53 +
  738.54 +std::list<Mesh*> Object::get_all_meshes()
  738.55 +{
  738.56 +	std::list<Mesh*> meshes;
  738.57 +	get_all_meshes_rec(this, &meshes);
  738.58 +	return meshes;
  738.59 +}
  738.60 +
  738.61 +std::list<const Mesh*> Object::get_all_meshes() const
  738.62 +{
  738.63 +	std::list<const Mesh*> meshes;
  738.64 +	get_all_meshes_rec((Object*)this, (std::list<Mesh*>*)&meshes);
  738.65 +	return meshes;
  738.66 +}
  738.67 +
  738.68 +static void get_all_meshes_rec(XFormNode *node, std::list<Mesh*> *reslist)
  738.69 +{
  738.70 +	if(!node) {
  738.71 +		return;
  738.72 +	}
  738.73 +
  738.74 +	if(node->get_type() == NODE_OBJECT) {
  738.75 +		Object *obj = (Object*)node;
  738.76 +		if(obj) {
  738.77 +			Mesh *mesh = obj->get_mesh();
  738.78 +			if(mesh) {
  738.79 +				reslist->push_back(mesh);
  738.80 +			}
  738.81 +		}
  738.82 +	}
  738.83 +
  738.84 +	for(int i=0; i<node->get_children_count(); i++) {
  738.85 +		get_all_meshes_rec(node->get_child(i), reslist);
  738.86 +	}
  738.87 +}
  738.88 +
  738.89 +long Object::count_polys() const
  738.90 +{
  738.91 +	long poly_count = mesh ? mesh->get_poly_count() : 0;
  738.92 +
  738.93 +	int nchildren = get_children_count();
  738.94 +	for(int i=0; i<nchildren; i++) {
  738.95 +		const XFormNode *child = get_child(i);
  738.96 +		if(child->get_type() == NODE_OBJECT) {
  738.97 +			poly_count += ((const Object*)child)->count_polys();
  738.98 +		}
  738.99 +	}
 738.100 +	return poly_count;
 738.101 +}
 738.102 +
 738.103 +AABox Object::get_aabbox() const
 738.104 +{
 738.105 +	AABox box;
 738.106 +
 738.107 +	if(mesh) {
 738.108 +		box = mesh->get_aabbox();
 738.109 +	} else {
 738.110 +		box.min = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
 738.111 +		box.max = -box.min;
 738.112 +	}
 738.113 +
 738.114 +	int num_children = get_children_count();
 738.115 +	for(int i=0; i<num_children; i++) {
 738.116 +		const Object *obj = dynamic_cast<const Object*>(get_child(i));
 738.117 +		if(obj) {
 738.118 +			AABox child_box = obj->get_aabbox();
 738.119 +			box.set_union(&box, &child_box);
 738.120 +		}
 738.121 +	}
 738.122 +	return box;
 738.123 +}
 738.124 +
 738.125 +Sphere Object::get_bsphere() const
 738.126 +{
 738.127 +	Sphere sph;
 738.128 +	bool valid = false;
 738.129 +
 738.130 +	if(mesh) {
 738.131 +		sph = mesh->get_bsphere();
 738.132 +		valid = true;
 738.133 +	} else {
 738.134 +		sph.radius = 0.0;
 738.135 +	}
 738.136 +
 738.137 +	int num_children = get_children_count();
 738.138 +	for(int i=0; i<num_children; i++) {
 738.139 +		// TODO: this is wrong
 738.140 +		const Object *obj = dynamic_cast<const Object*>(get_child(i));
 738.141 +		if(obj) {
 738.142 +			Sphere child_sph = obj->get_bsphere();
 738.143 +			if(valid) {
 738.144 +				sph.set_union(&sph, &child_sph);
 738.145 +			} else {
 738.146 +				sph = child_sph;
 738.147 +				valid = true;
 738.148 +			}
 738.149 +		}
 738.150 +	}
 738.151 +
 738.152 +	return sph;
 738.153 +}
 738.154 +
 738.155 +void Object::apply_xform(long msec)
 738.156 +{
 738.157 +	std::list<XFormNode*> nodelist = get_all_nodes(NODE_OBJECT);
 738.158 +
 738.159 +	std::list<XFormNode*>::iterator it = nodelist.begin();
 738.160 +	while(it != nodelist.end()) {
 738.161 +		Object *obj = (Object*)*it++;
 738.162 +
 738.163 +		Mesh *mesh = obj->get_mesh();
 738.164 +		if(mesh) {
 738.165 +			Matrix4x4 xform;
 738.166 +			obj->get_xform(msec, &xform);
 738.167 +			mesh->apply_xform(xform);
 738.168 +		}
 738.169 +	}
 738.170 +
 738.171 +	// go through the list a second time and clear the transformations
 738.172 +	it = nodelist.begin();
 738.173 +	while(it != nodelist.end()) {
 738.174 +		Object *obj = (Object*)*it++;
 738.175 +
 738.176 +		obj->clear_xform();
 738.177 +	}
 738.178 +}
 738.179 +
 738.180 +/*static const char *attr_name[] = {
 738.181 +	"attr_vertex",
 738.182 +	"attr_normal",
 738.183 +	"attr_tangent",
 738.184 +	"attr_texcoord",
 738.185 +	"attr_boneweights",
 738.186 +	"attr_boneidx"
 738.187 +};*/
 738.188 +
 738.189 +void Object::draw(long msec) const
 738.190 +{
 738.191 +	Matrix4x4 xform;
 738.192 +	get_xform(msec, &xform);
 738.193 +
 738.194 +	set_world_matrix(xform);
 738.195 +
 738.196 +	if(mesh) {
 738.197 +		/*unsigned int prog = sdrprog;
 738.198 +
 738.199 +		if(mesh->get_bones_count() > 0) {
 738.200 +			prog = sdrprog_skin;
 738.201 +		}
 738.202 +
 738.203 +		glUseProgram(prog);
 738.204 +		// get all the attribute locations
 738.205 +		for(int i=0; i<NUM_MESH_ATTR; i++) {
 738.206 +			int loc = glGetAttribLocation(prog, attr_name[i]);
 738.207 +			if(loc != -1) {
 738.208 +				Mesh::set_attrib_location(i, loc);
 738.209 +			}
 738.210 +		}
 738.211 +
 738.212 +		setup_bones(msec);
 738.213 +
 738.214 +		glUseProgram(prog);*/
 738.215 +
 738.216 +#ifndef GL_ES_VERSION_2_0
 738.217 +		if(!get_current_shader()) {
 738.218 +			setup_gl_matrices();
 738.219 +		}
 738.220 +#endif
 738.221 +
 738.222 +		material.setup();
 738.223 +		setup_unistate();	// set all state uniforms
 738.224 +
 738.225 +		switch(Object::draw_mode) {
 738.226 +		case DRAW_WIREFRAME:
 738.227 +			mesh->draw_wire();
 738.228 +			break;
 738.229 +
 738.230 +		case DRAW_VERTICES:
 738.231 +			mesh->draw_vertices();
 738.232 +			break;
 738.233 +
 738.234 +		case DRAW_DEFAULT:
 738.235 +		default:
 738.236 +			mesh->draw();
 738.237 +		}
 738.238 +	}
 738.239 +
 738.240 +	int num_children = get_children_count();
 738.241 +	for(int i=0; i<num_children; i++) {
 738.242 +		const XFormNode *c = get_child(i);
 738.243 +		c->draw(msec);
 738.244 +	}
 738.245 +}
 738.246 +
 738.247 +
 738.248 +bool Object::intersect(const Ray &inray, HitPoint *hit) const
 738.249 +{
 738.250 +	Ray ray = inray;
 738.251 +	Matrix4x4 xform, inv_xform;
 738.252 +	get_xform(ray.time, &xform/*, &inv_xform*/);
 738.253 +	ray.transform(xform.inverse());	// TODO find out what's wrong with get_xform's inv_xform and use that
 738.254 +
 738.255 +	HitPoint nearest_hit;
 738.256 +	nearest_hit.dist = FLT_MAX;
 738.257 +	nearest_hit.obj = 0;
 738.258 +
 738.259 +	if(mesh) {
 738.260 +		if(mesh->intersect(ray, hit ? &nearest_hit : 0)) {
 738.261 +			if(!hit) {
 738.262 +				return true;
 738.263 +			}
 738.264 +
 738.265 +			if(Mesh::get_intersect_mode() & ISECT_FACE) {
 738.266 +				Triangle *face = (Triangle*)nearest_hit.obj;
 738.267 +				face->transform(xform);
 738.268 +			} else if(Mesh::get_intersect_mode() & ISECT_VERTICES) {
 738.269 +				Vector3 *v = (Vector3*)nearest_hit.obj;
 738.270 +				v->transform(xform);
 738.271 +			} else {
 738.272 +				nearest_hit.obj = this;
 738.273 +			}
 738.274 +		}
 738.275 +	}
 738.276 +
 738.277 +	int num_children = get_children_count();
 738.278 +	for(int i=0; i<num_children; i++) {
 738.279 +		const Object *obj = dynamic_cast<const Object*>(get_child(i));
 738.280 +
 738.281 +		HitPoint chit;
 738.282 +		if(obj && obj->intersect(inray, hit ? &chit : 0)) {
 738.283 +			if(!hit) {
 738.284 +				return true;
 738.285 +			}
 738.286 +
 738.287 +			if(chit.dist < nearest_hit.dist) {
 738.288 +				nearest_hit = chit;
 738.289 +			}
 738.290 +		}
 738.291 +	}
 738.292 +
 738.293 +	if(nearest_hit.obj) {
 738.294 +		if(hit) {
 738.295 +			*hit = nearest_hit;
 738.296 +		}
 738.297 +		return true;
 738.298 +	}
 738.299 +	return false;
 738.300 +}
 738.301 +
 738.302 +
 738.303 +bool Object::setup_bones(long msec) const
 738.304 +{
 738.305 +	int num_bones;
 738.306 +	if(!mesh || !(num_bones = mesh->get_bones_count())) {
 738.307 +		return false;
 738.308 +	}
 738.309 +
 738.310 +	/*char uniname[32];
 738.311 +
 738.312 +	for(int i=0; i<num_bones; i++) {
 738.313 +		const XFormNode *bone = mesh->get_bone(i);
 738.314 +
 738.315 +		Matrix4x4 xform;
 738.316 +		bone->get_xform(msec, &xform);
 738.317 +
 738.318 +		xform = xform * bone->get_bone_matrix();
 738.319 +
 738.320 +		sprintf(uniname, "bone_xform[%d]", i);
 738.321 +		int loc = glGetUniformLocation(sdrprog_skin, uniname);
 738.322 +		if(loc == -1) {
 738.323 +			return false;
 738.324 +		}
 738.325 +		glUniformMatrix4fv(loc, 1, GL_TRUE, xform[0]);
 738.326 +	}*/
 738.327 +	return true;
 738.328 +}
 738.329 +
 738.330 +DrawMode Object::set_draw_mode(DrawMode mode)
 738.331 +{
 738.332 +	DrawMode prev = Object::draw_mode;
 738.333 +	Object::draw_mode = mode;
 738.334 +	return prev;
 738.335 +}
   739.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   739.2 +++ b/src/object.h	Sat Feb 01 19:58:19 2014 +0200
   739.3 @@ -0,0 +1,56 @@
   739.4 +#ifndef OBJECT_H_
   739.5 +#define OBJECT_H_
   739.6 +
   739.7 +#include <list>
   739.8 +#include "xform_node.h"
   739.9 +#include "mesh.h"
  739.10 +#include "material.h"
  739.11 +
  739.12 +enum DrawMode {
  739.13 +	DRAW_DEFAULT,
  739.14 +	DRAW_WIREFRAME,
  739.15 +	DRAW_VERTICES
  739.16 +};
  739.17 +
  739.18 +
  739.19 +class Object : public XFormNode {
  739.20 +private:
  739.21 +	Mesh *mesh;	///< no ownership, just keeping the pointer around
  739.22 +	static DrawMode draw_mode;
  739.23 +
  739.24 +	bool setup_bones(long msec) const;
  739.25 +
  739.26 +public:
  739.27 +	Material material;
  739.28 +
  739.29 +	Object();
  739.30 +
  739.31 +	/// destroy this object and all the hierarchy of objects hanging below it
  739.32 +	void destroy_all();
  739.33 +
  739.34 +	void set_mesh(Mesh *m);
  739.35 +	Mesh *get_mesh();
  739.36 +	const Mesh *get_mesh() const;
  739.37 +
  739.38 +	/// get all the meshes of the subtree rooted in this object @{
  739.39 +	std::list<Mesh*> get_all_meshes();
  739.40 +	std::list<const Mesh*> get_all_meshes() const;
  739.41 +	/// @}
  739.42 +
  739.43 +	/// counts the polygons of the mesh of this object and all it's descendants
  739.44 +	long count_polys() const;
  739.45 +
  739.46 +	AABox get_aabbox() const;
  739.47 +	Sphere get_bsphere() const;
  739.48 +
  739.49 +	void apply_xform(long msec = 0);
  739.50 +
  739.51 +	void draw(long msec = 0) const;
  739.52 +
  739.53 +	bool intersect(const Ray &ray, HitPoint *hit = 0) const;
  739.54 +
  739.55 +	/// this is mostly for tools, to allow drawing only the wireframe or vertices
  739.56 +	static DrawMode set_draw_mode(DrawMode mode);
  739.57 +};
  739.58 +
  739.59 +#endif	// OBJECT_H_
   740.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   740.2 +++ b/src/opengl.cc	Sat Feb 01 19:58:19 2014 +0200
   740.3 @@ -0,0 +1,29 @@
   740.4 +#include "opengl.h"
   740.5 +
   740.6 +void init_opengl()
   740.7 +{
   740.8 +#ifdef __GLEW_H__
   740.9 +	glewInit();
  740.10 +#endif
  740.11 +}
  740.12 +
  740.13 +const char *strglerr(int err)
  740.14 +{
  740.15 +	static const char *errnames[] = {
  740.16 +		"GL_INVALID_ENUM",
  740.17 +		"GL_INVALID_VALUE",
  740.18 +		"GL_INVALID_OPERATION",
  740.19 +		"GL_STACK_OVERFLOW",
  740.20 +		"GL_STACK_UNDERFLOW",
  740.21 +		"GL_OUT_OF_MEMORY",
  740.22 +		"GL_INVALID_FRAMEBUFFER_OPERATION"
  740.23 +	};
  740.24 +
  740.25 +	if(!err) {
  740.26 +		return "GL_NO_ERROR";
  740.27 +	}
  740.28 +	if(err < GL_INVALID_ENUM || err > GL_OUT_OF_MEMORY) {
  740.29 +		return "<invalid gl error>";
  740.30 +	}
  740.31 +	return errnames[err - GL_INVALID_ENUM];
  740.32 +}
   741.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   741.2 +++ b/src/opengl.h	Sat Feb 01 19:58:19 2014 +0200
   741.3 @@ -0,0 +1,71 @@
   741.4 +#ifndef OPENGL_H_
   741.5 +#define OPENGL_H_
   741.6 +
   741.7 +#include <stdlib.h>
   741.8 +
   741.9 +#ifdef __APPLE__
  741.10 +#include "TargetConditionals.h"
  741.11 +
  741.12 +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
  741.13 +/* iOS */
  741.14 +#include <OpenGLES/ES2/gl.h>
  741.15 +#include <OpenGLES/ES2/glext.h>
  741.16 +
  741.17 +#define GL_CLAMP			GL_CLAMP_TO_EDGE
  741.18 +#define GL_DEPTH24_STENCIL8	GL_DEPTH24_STENCIL8_OES
  741.19 +
  741.20 +#undef USE_OLDGL
  741.21 +
  741.22 +#define GL_WRITE_ONLY	GL_WRITE_ONLY_OES
  741.23 +#define glMapBuffer		glMapBufferOES
  741.24 +#define glUnmapBuffer	glUnmapBufferOES
  741.25 +
  741.26 +#else
  741.27 +/* MacOS X */
  741.28 +#include <GL/glew.h>
  741.29 +#include <GLUT/glut.h>
  741.30 +
  741.31 +#define USE_OLDGL
  741.32 +#endif
  741.33 +
  741.34 +#else
  741.35 +/* UNIX or Windows */
  741.36 +#include <GL/glew.h>
  741.37 +#include <GL/glut.h>
  741.38 +
  741.39 +#define USE_OLDGL
  741.40 +#endif
  741.41 +
  741.42 +#ifndef GL_RGB16F
  741.43 +#define GL_RGB16F	0x881b
  741.44 +#endif
  741.45 +#ifndef GL_RGBA16F
  741.46 +#define GL_RGBA16F	0x881a
  741.47 +#endif
  741.48 +#ifndef GL_RGB32F
  741.49 +#define GL_RGB32F	0x8815
  741.50 +#endif
  741.51 +#ifndef GL_RGBA32F
  741.52 +#define GL_RGBA32F	0x8814
  741.53 +#endif
  741.54 +#ifndef GL_LUMINANCE16F
  741.55 +#define GL_LUMINANCE16F	0x881e
  741.56 +#endif
  741.57 +#ifndef GL_LUMINANCE32F
  741.58 +#define GL_LUMINANCE32F	0x8818
  741.59 +#endif
  741.60 +
  741.61 +#define CHECKGLERR	\
  741.62 +	do { \
  741.63 +		int err = glGetError(); \
  741.64 +		if(err) { \
  741.65 +			fprintf(stderr, "%s:%d: OpenGL error 0x%x: %s\n", __FILE__, __LINE__, err, strglerr(err)); \
  741.66 +			abort(); \
  741.67 +		} \
  741.68 +	} while(0)
  741.69 +
  741.70 +void init_opengl();
  741.71 +
  741.72 +const char *strglerr(int err);
  741.73 +
  741.74 +#endif	// OPENGL_H_
   742.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   742.2 +++ b/src/psyspp.cc	Sat Feb 01 19:58:19 2014 +0200
   742.3 @@ -0,0 +1,460 @@
   742.4 +#include <limits.h>
   742.5 +#include "psyspp.h"
   742.6 +#include "sdrman.h"
   742.7 +#include "logger.h"
   742.8 +#include "mesh.h"	// just for the attrib enums
   742.9 +#include "unistate.h"
  742.10 +#include "datapath.h"
  742.11 +#include "texman.h"
  742.12 +#include "texgen.h"
  742.13 +#include "image.h"
  742.14 +
  742.15 +static void pdraw_start(const psys_emitter *em, void *cls);
  742.16 +static void pdraw(const psys_emitter *em, const psys_particle *part, void *cls);
  742.17 +static void pdraw_end(const psys_emitter *em, void *cls);
  742.18 +
  742.19 +static unsigned int psys_load_texture(const char *fname, void *cls);
  742.20 +
  742.21 +ParticleSystemAttributes::ParticleSystemAttributes()
  742.22 +{
  742.23 +	tex = 0;
  742.24 +	own_psattr = true;
  742.25 +	psattr = new psys_attributes;
  742.26 +	psys_init_attr(psattr);
  742.27 +}
  742.28 +
  742.29 +ParticleSystemAttributes::ParticleSystemAttributes(psys_attributes *psattr)
  742.30 +{
  742.31 +	tex = 0;
  742.32 +	own_psattr = false;
  742.33 +	this->psattr = psattr;
  742.34 +}
  742.35 +
  742.36 +ParticleSystemAttributes::~ParticleSystemAttributes()
  742.37 +{
  742.38 +	if(own_psattr) {
  742.39 +		psys_destroy_attr(psattr);
  742.40 +		delete psattr;
  742.41 +	}
  742.42 +}
  742.43 +
  742.44 +ParticleSystemAttributes::ParticleSystemAttributes(const ParticleSystemAttributes &rhs)
  742.45 +{
  742.46 +	own_psattr = true;
  742.47 +	tex = rhs.tex;
  742.48 +	psattr = new psys_attributes;
  742.49 +	psys_init_attr(psattr);
  742.50 +
  742.51 +	psys_copy_attr(psattr, rhs.psattr);
  742.52 +}
  742.53 +
  742.54 +ParticleSystemAttributes &ParticleSystemAttributes::operator =(const ParticleSystemAttributes &rhs)
  742.55 +{
  742.56 +	if(&rhs != this) {
  742.57 +		tex = rhs.tex;
  742.58 +		psys_copy_attr(psattr, rhs.psattr);
  742.59 +	}
  742.60 +	return *this;
  742.61 +}
  742.62 +
  742.63 +bool ParticleSystemAttributes::load(const char *fname)
  742.64 +{
  742.65 +	psys_texture_loader(psys_load_texture, 0, this);
  742.66 +	return psys_load_attr(psattr, datafile_path(fname).c_str()) != -1;
  742.67 +}
  742.68 +
  742.69 +bool ParticleSystemAttributes::load(FILE *fp)
  742.70 +{
  742.71 +	psys_texture_loader(psys_load_texture, 0, this);
  742.72 +	return psys_load_attr_stream(psattr, fp) != -1;
  742.73 +}
  742.74 +
  742.75 +bool ParticleSystemAttributes::save(const char *fname) const
  742.76 +{
  742.77 +	return psys_save_attr(psattr, fname) != -1;
  742.78 +}
  742.79 +
  742.80 +bool ParticleSystemAttributes::save(FILE *fp) const
  742.81 +{
  742.82 +	return psys_save_attr_stream(psattr, fp) != -1;
  742.83 +}
  742.84 +
  742.85 +void ParticleSystemAttributes::set_part_color(const Vector3 &color, float t)
  742.86 +{
  742.87 +	psys_set_value3(&psattr->part_attr.color, (anm_time_t)(t * 1000.0), v3_cons(color.x, color.y, color.z));
  742.88 +}
  742.89 +
  742.90 +void ParticleSystemAttributes::set_part_alpha(float alpha, float t)
  742.91 +{
  742.92 +	psys_set_value(&psattr->part_attr.alpha, (anm_time_t)(t * 1000.0), alpha);
  742.93 +}
  742.94 +
  742.95 +void ParticleSystemAttributes::set_part_scale(float size, float t)
  742.96 +{
  742.97 +	psys_set_value(&psattr->part_attr.size, (anm_time_t)(t * 1000.0), size);
  742.98 +}
  742.99 +
 742.100 +
 742.101 +// emmiter attributes
 742.102 +void ParticleSystemAttributes::set_texture(Texture *tex)
 742.103 +{
 742.104 +	this->tex = tex;
 742.105 +	psattr->tex = tex->get_id();
 742.106 +}
 742.107 +
 742.108 +Texture *ParticleSystemAttributes::get_texture() const
 742.109 +{
 742.110 +	return tex;
 742.111 +}
 742.112 +
 742.113 +void ParticleSystemAttributes::set_spawn_range(const Vector3 &range, long tm)
 742.114 +{
 742.115 +	psys_set_value3(&psattr->spawn_range, ANM_MSEC2TM(tm), v3_cons(range.x, range.y, range.z));
 742.116 +}
 742.117 +
 742.118 +void ParticleSystemAttributes::set_spawn_rate(float rate, long tm)
 742.119 +{
 742.120 +	psys_set_value(&psattr->rate, ANM_MSEC2TM(tm), rate);
 742.121 +}
 742.122 +
 742.123 +float ParticleSystemAttributes::get_spawn_rate(long tm) const
 742.124 +{
 742.125 +	return psys_get_value(&psattr->rate, ANM_MSEC2TM(tm));
 742.126 +}
 742.127 +
 742.128 +void ParticleSystemAttributes::set_life(float life, float range, long tm)
 742.129 +{
 742.130 +	psys_set_anm_rnd(&psattr->life, ANM_MSEC2TM(tm), life, range);
 742.131 +}
 742.132 +
 742.133 +void ParticleSystemAttributes::set_size(float sz, float range, long tm)
 742.134 +{
 742.135 +	psys_set_anm_rnd(&psattr->size, ANM_MSEC2TM(tm), sz, range);
 742.136 +}
 742.137 +
 742.138 +void ParticleSystemAttributes::set_spawn_dir(const Vector3 &dir, const Vector3 &range, long tm)
 742.139 +{
 742.140 +	psys_set_anm_rnd3(&psattr->dir, ANM_MSEC2TM(tm), v3_cons(dir.x, dir.y, dir.z), v3_cons(range.x, range.y, range.z));
 742.141 +}
 742.142 +
 742.143 +void ParticleSystemAttributes::set_gravity(const Vector3 &grav, long tm)
 742.144 +{
 742.145 +	psys_set_value3(&psattr->grav, ANM_MSEC2TM(tm), v3_cons(grav.x, grav.y, grav.z));
 742.146 +}
 742.147 +
 742.148 +void ParticleSystemAttributes::set_drag(float drag)
 742.149 +{
 742.150 +	psattr->drag = drag;
 742.151 +}
 742.152 +
 742.153 +void ParticleSystemAttributes::set_particle_limit(int lim)
 742.154 +{
 742.155 +	psattr->max_particles = lim;
 742.156 +}
 742.157 +
 742.158 +
 742.159 +// ---- ParticleSystem ----
 742.160 +
 742.161 +ParticleSystem::ParticleSystem()
 742.162 +	: attr(&psys.attr)
 742.163 +{
 742.164 +	psys_init(&psys);
 742.165 +	psys_draw_func(&psys, pdraw, pdraw_start, pdraw_end, (void*)this);
 742.166 +	start_time = LONG_MIN;
 742.167 +	last_upd_time = LONG_MIN;
 742.168 +}
 742.169 +
 742.170 +ParticleSystem::~ParticleSystem()
 742.171 +{
 742.172 +	psys_destroy(&psys);
 742.173 +}
 742.174 +
 742.175 +void ParticleSystem::set_start_time(long tm)
 742.176 +{
 742.177 +	start_time = tm;
 742.178 +}
 742.179 +
 742.180 +bool ParticleSystem::is_active() const
 742.181 +{
 742.182 +	float rate = attr.get_spawn_rate(last_upd_time);
 742.183 +	return psys.pcount > 0 || last_upd_time == 0;// || rate > 0.0;
 742.184 +}
 742.185 +
 742.186 +ParticleSystemAttributes *ParticleSystem::get_attr()
 742.187 +{
 742.188 +	return &attr;
 742.189 +}
 742.190 +
 742.191 +const ParticleSystemAttributes *ParticleSystem::get_attr() const
 742.192 +{
 742.193 +	return &attr;
 742.194 +}
 742.195 +
 742.196 +void ParticleSystem::set_attr(const ParticleSystemAttributes &pattr)
 742.197 +{
 742.198 +	attr = pattr;
 742.199 +}
 742.200 +
 742.201 +bool ParticleSystem::load(const char *fname)
 742.202 +{
 742.203 +	psys_texture_loader(psys_load_texture, 0, &attr);
 742.204 +	return attr.load(fname);
 742.205 +}
 742.206 +
 742.207 +bool ParticleSystem::save(const char *fname) const
 742.208 +{
 742.209 +	return attr.save(fname);
 742.210 +}
 742.211 +
 742.212 +void ParticleSystem::update(long tm)
 742.213 +{
 742.214 +	if(start_time > LONG_MIN) {
 742.215 +		tm -= start_time;
 742.216 +	}
 742.217 +
 742.218 +	Matrix4x4 xform;
 742.219 +	get_xform(tm, &xform);
 742.220 +
 742.221 +	Vector3 pos = Vector3(0, 0, 0).transformed(xform);
 742.222 +
 742.223 +	psys_set_pos(&psys, v3_cons(pos.x, pos.y, pos.z), 0);
 742.224 +	psys_update(&psys, (double)tm / 1000.0);
 742.225 +
 742.226 +	last_upd_time = tm;
 742.227 +}
 742.228 +
 742.229 +void ParticleSystem::draw() const
 742.230 +{
 742.231 +	psys_draw(&psys);
 742.232 +}
 742.233 +
 742.234 +// ---- particle drawing ----
 742.235 +struct PVertex {
 742.236 +	Vector4 color;
 742.237 +	Vector3 pos;
 742.238 +	Vector2 texcoord;
 742.239 +};
 742.240 +
 742.241 +
 742.242 +#define USE_VBO
 742.243 +#define USE_IBO
 742.244 +
 742.245 +
 742.246 +#define MAX_DRAW_PART	256
 742.247 +#define MAX_PVERTS		(MAX_DRAW_PART * 4)
 742.248 +static PVertex *pvarr, *pvptr;
 742.249 +
 742.250 +// double-buffered vbo set, write on one, while drawing from the other
 742.251 +
 742.252 +#ifdef USE_VBO
 742.253 +static unsigned int vbo[2];
 742.254 +static int cur_buf;		// current write vbo
 742.255 +#endif
 742.256 +static int num_buffered;	// number of particles bufferd, will flush when >= MAX_DRAW_PART
 742.257 +
 742.258 +// ok so the index array is constant, regardless of the particle system
 742.259 +// so this is a static index buffer created in init_particle_draw which should
 742.260 +// be called once.
 742.261 +#define MAX_PVIDX		(MAX_DRAW_PART * 6)
 742.262 +#ifdef USE_IBO
 742.263 +static unsigned int ibo;
 742.264 +#endif
 742.265 +unsigned int *pvidx;
 742.266 +
 742.267 +static ShaderProg *psdr;	// particle shader
 742.268 +static Texture2D *blank_tex;
 742.269 +
 742.270 +static inline void init_particle_draw()
 742.271 +{
 742.272 +	static bool done_init;
 742.273 +	if(done_init) {
 742.274 +		return;		// once
 742.275 +	}
 742.276 +
 742.277 +	pvidx = new unsigned int[MAX_PVIDX];
 742.278 +	unsigned int *ptr = pvidx;
 742.279 +
 742.280 +	static const unsigned int idxoffs[] = { 0, 1, 2, 0, 2, 3 };
 742.281 +
 742.282 +	for(int i=0; i<MAX_DRAW_PART; i++) {
 742.283 +		for(int j=0; j<6; j++) {
 742.284 +			*ptr++ = i * 4 + idxoffs[j];
 742.285 +		}
 742.286 +	}
 742.287 +
 742.288 +#ifdef USE_IBO
 742.289 +	glGenBuffers(1, &ibo);
 742.290 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
 742.291 +	glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_PVIDX * sizeof *pvidx, pvidx, GL_STATIC_DRAW);
 742.292 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 742.293 +
 742.294 +	delete [] pvidx;
 742.295 +#endif
 742.296 +
 742.297 +#ifdef USE_VBO
 742.298 +	// create the stream vertex buffers (double buffering)
 742.299 +	glGenBuffers(2, vbo);
 742.300 +	for(int i=0; i<2; i++) {
 742.301 +		glBindBuffer(GL_ARRAY_BUFFER, vbo[i]);
 742.302 +		glBufferData(GL_ARRAY_BUFFER, MAX_PVERTS * sizeof(PVertex), 0, GL_STREAM_DRAW);
 742.303 +	}
 742.304 +	glBindBuffer(GL_ARRAY_BUFFER, 0);
 742.305 +#else
 742.306 +	pvarr = new PVertex[MAX_PVERTS];
 742.307 +	pvptr = pvarr;
 742.308 +#endif
 742.309 +
 742.310 +	// load shader program
 742.311 +	if(!(psdr = get_sdrprog("psdr.v.glsl", "psdr.p.glsl"))) {
 742.312 +		error_log("failed to load particle shader!\n");
 742.313 +	}
 742.314 +
 742.315 +	// create empty texture
 742.316 +	Image *img = texgen_solid(8, 8, Vector4(1, 1, 1, 1));
 742.317 +	blank_tex = new Texture2D;
 742.318 +	blank_tex->set_image(*img);
 742.319 +	delete img;
 742.320 +
 742.321 +	done_init = true;
 742.322 +}
 742.323 +
 742.324 +static void pdraw_flush()
 742.325 +{
 742.326 +#ifdef USE_VBO
 742.327 +	// assuming vbo[cur_buf] is bound
 742.328 +	glUnmapBuffer(GL_ARRAY_BUFFER);
 742.329 +#endif
 742.330 +
 742.331 +	// draw from the bound buffer 6 indices per particle
 742.332 +#ifdef USE_IBO
 742.333 +	glDrawElements(GL_TRIANGLES, num_buffered * 6, GL_UNSIGNED_INT, 0);
 742.334 +#else
 742.335 +	glDrawElements(GL_TRIANGLES, num_buffered * 6, GL_UNSIGNED_INT, pvidx);
 742.336 +#endif
 742.337 +	num_buffered = 0;
 742.338 +
 742.339 +#ifdef USE_VBO
 742.340 +	// map the next buffer (write buffer) while the previous is drawing
 742.341 +	cur_buf = (cur_buf + 1) & 1;
 742.342 +	glBindBuffer(GL_ARRAY_BUFFER, vbo[cur_buf]);
 742.343 +	pvarr = (PVertex*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
 742.344 +#endif
 742.345 +	pvptr = pvarr;
 742.346 +}
 742.347 +
 742.348 +static void pdraw_start(const psys_emitter *em, void *cls)
 742.349 +{
 742.350 +	ParticleSystem *ps = (ParticleSystem*)cls;
 742.351 +
 742.352 +	init_particle_draw();
 742.353 +
 742.354 +	num_buffered = 0;
 742.355 +
 742.356 +#ifdef USE_IBO
 742.357 +	// bind the particle index buffer which is static
 742.358 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
 742.359 +#endif
 742.360 +
 742.361 +#ifdef USE_VBO
 742.362 +	// map the current write buffer
 742.363 +	glBindBuffer(GL_ARRAY_BUFFER, vbo[cur_buf]);
 742.364 +	pvarr = (PVertex*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
 742.365 +#endif
 742.366 +	pvptr = pvarr;
 742.367 +
 742.368 +	Texture *tex = ps->get_attr()->get_texture();
 742.369 +	if(tex) {
 742.370 +		tex->bind();
 742.371 +	} else {
 742.372 +		blank_tex->bind();
 742.373 +	}
 742.374 +	psdr->bind();
 742.375 +
 742.376 +	glDisable(GL_DEPTH_TEST);
 742.377 +	glDisable(GL_CULL_FACE);
 742.378 +	glEnable(GL_BLEND);
 742.379 +	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 742.380 +	glDepthMask(0);
 742.381 +
 742.382 +	glEnableVertexAttribArray(MESH_ATTR_VERTEX);
 742.383 +	glEnableVertexAttribArray(MESH_ATTR_COLOR);
 742.384 +	glEnableVertexAttribArray(MESH_ATTR_TEXCOORD);
 742.385 +
 742.386 +#ifdef USE_VBO
 742.387 +	glVertexAttribPointer(MESH_ATTR_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof *pvarr, (void*)((char*)&pvarr->pos - (char*)pvarr));
 742.388 +	glVertexAttribPointer(MESH_ATTR_COLOR, 4, GL_FLOAT, GL_TRUE, sizeof *pvarr, (void*)((char*)&pvarr->color - (char*)pvarr));
 742.389 +	glVertexAttribPointer(MESH_ATTR_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof *pvarr, (void*)((char*)&pvarr->texcoord - (char*)pvarr));
 742.390 +#else
 742.391 +	glVertexAttribPointer(MESH_ATTR_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof *pvarr, (void*)&pvarr->pos);
 742.392 +	glVertexAttribPointer(MESH_ATTR_COLOR, 4, GL_FLOAT, GL_TRUE, sizeof *pvarr, (void*)&pvarr->color);
 742.393 +	glVertexAttribPointer(MESH_ATTR_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof *pvarr, (void*)&pvarr->texcoord);
 742.394 +#endif
 742.395 +}
 742.396 +
 742.397 +static void pdraw(const psys_emitter *em, const psys_particle *part, void *cls)
 742.398 +{
 742.399 +	ParticleSystem *ps = (ParticleSystem*)cls;
 742.400 +
 742.401 +	static const Vector3 pv[] = {
 742.402 +		Vector3(-0.5, -0.5, 0),
 742.403 +		Vector3(0.5, -0.5, 0),
 742.404 +		Vector3(0.5, 0.5, 0),
 742.405 +		Vector3(-0.5, 0.5, 0)
 742.406 +	};
 742.407 +	static const Vector2 tex[] = {
 742.408 +		Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 0)
 742.409 +	};
 742.410 +	Vector4 color = Vector4(part->color.x, part->color.y, part->color.z, part->alpha);
 742.411 +
 742.412 +	for(int i=0; i<4; i++) {
 742.413 +		pvptr->color = color;
 742.414 +		pvptr->pos = pv[i] * part->size + part->pos;
 742.415 +		pvptr->texcoord = tex[i];
 742.416 +		pvptr++;
 742.417 +	}
 742.418 +	// XXX we don't need billboarding for this game, so don't bother
 742.419 +
 742.420 +	// if we reached the maximum number of buffered particles, draw them
 742.421 +	if(++num_buffered >= MAX_DRAW_PART) {
 742.422 +		pdraw_flush();	// this will reset the counter
 742.423 +	}
 742.424 +}
 742.425 +
 742.426 +static void pdraw_end(const psys_emitter *em, void *cls)
 742.427 +{
 742.428 +	// if we have leftover particles buffered, draw them before returning
 742.429 +	if(num_buffered) {
 742.430 +		pdraw_flush();
 742.431 +	}
 742.432 +
 742.433 +	// cleanup
 742.434 +	glDisableVertexAttribArray(MESH_ATTR_VERTEX);
 742.435 +	glDisableVertexAttribArray(MESH_ATTR_COLOR);
 742.436 +	glDisableVertexAttribArray(MESH_ATTR_TEXCOORD);
 742.437 +
 742.438 +#ifdef USE_VBO
 742.439 +	glUnmapBuffer(GL_ARRAY_BUFFER);
 742.440 +	glBindBuffer(GL_ARRAY_BUFFER, 0);
 742.441 +#endif
 742.442 +#ifdef USE_IBO
 742.443 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 742.444 +#endif
 742.445 +
 742.446 +	glDepthMask(1);
 742.447 +	glDisable(GL_BLEND);
 742.448 +
 742.449 +	glEnable(GL_DEPTH_TEST);
 742.450 +	glEnable(GL_CULL_FACE);
 742.451 +}
 742.452 +
 742.453 +static unsigned int psys_load_texture(const char *fname, void *cls)
 742.454 +{
 742.455 +	ParticleSystemAttributes *attr = (ParticleSystemAttributes*)cls;
 742.456 +
 742.457 +	Texture *tex = texset.get(fname);
 742.458 +	if(tex) {
 742.459 +		attr->set_texture(tex);
 742.460 +		return tex->get_id();
 742.461 +	}
 742.462 +	return 0;
 742.463 +}
   743.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   743.2 +++ b/src/psyspp.h	Sat Feb 01 19:58:19 2014 +0200
   743.3 @@ -0,0 +1,79 @@
   743.4 +#ifndef PSYSPP_H_
   743.5 +#define PSYSPP_H_
   743.6 +
   743.7 +#include "xform_node.h"
   743.8 +#include "texture.h"
   743.9 +#include <psys/psys.h>
  743.10 +
  743.11 +class ParticleSystemAttributes {
  743.12 +private:
  743.13 +	Texture *tex;
  743.14 +	psys_attributes *psattr;
  743.15 +	bool own_psattr;
  743.16 +
  743.17 +public:
  743.18 +	ParticleSystemAttributes();
  743.19 +	ParticleSystemAttributes(psys_attributes *psattr);
  743.20 +	~ParticleSystemAttributes();
  743.21 +
  743.22 +	ParticleSystemAttributes(const ParticleSystemAttributes &rhs);
  743.23 +	ParticleSystemAttributes &operator =(const ParticleSystemAttributes &rhs);
  743.24 +
  743.25 +	bool load(const char *fname);
  743.26 +	bool load(FILE *fp);
  743.27 +	bool save(const char *fname) const;
  743.28 +	bool save(FILE *fp) const;
  743.29 +
  743.30 +	// particle attributes
  743.31 +	void set_part_color(const Vector3 &color, float t = 0);
  743.32 +	void set_part_alpha(float alpha, float t = 0);
  743.33 +	void set_part_scale(float size, float t = 0);
  743.34 +
  743.35 +	// emmiter attributes
  743.36 +	void set_texture(Texture *tex);
  743.37 +	Texture *get_texture() const;
  743.38 +
  743.39 +	void set_spawn_range(const Vector3 &range, long tm = 0);
  743.40 +
  743.41 +	void set_spawn_rate(float rate, long tm = 0);
  743.42 +	float get_spawn_rate(long tm = 0) const;
  743.43 +
  743.44 +	void set_life(float life, float range = 0.0, long tm = 0);
  743.45 +	void set_size(float sz, float range = 0.0, long tm = 0);
  743.46 +	void set_spawn_dir(const Vector3 &dir, const Vector3 &range = Vector3(0, 0, 0), long tm = 0);
  743.47 +
  743.48 +	void set_gravity(const Vector3 &grav, long tm = 0);
  743.49 +	void set_drag(float drag);
  743.50 +
  743.51 +	void set_particle_limit(int lim);
  743.52 +};
  743.53 +
  743.54 +class ParticleSystem : public XFormNode {
  743.55 +private:
  743.56 +	psys_emitter psys;
  743.57 +	ParticleSystemAttributes attr;
  743.58 +
  743.59 +	long start_time;	// subtracted from all time calculations
  743.60 +	long last_upd_time;
  743.61 +
  743.62 +public:
  743.63 +	ParticleSystem();
  743.64 +	~ParticleSystem();
  743.65 +
  743.66 +	void set_start_time(long tm);
  743.67 +
  743.68 +	bool is_active() const;
  743.69 +
  743.70 +	ParticleSystemAttributes *get_attr();
  743.71 +	const ParticleSystemAttributes *get_attr() const;
  743.72 +
  743.73 +	void set_attr(const ParticleSystemAttributes &pattr);
  743.74 +
  743.75 +	bool load(const char *fname);
  743.76 +	bool save(const char *fname) const;
  743.77 +
  743.78 +	void update(long tm);
  743.79 +	void draw() const;
  743.80 +};
  743.81 +
  743.82 +#endif	// PSYSPP_H_
   744.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   744.2 +++ b/src/scene.cc	Sat Feb 01 19:58:19 2014 +0200
   744.3 @@ -0,0 +1,49 @@
   744.4 +#include "scene.h"
   744.5 +#include "assload.h"
   744.6 +#include "opengl.h"
   744.7 +
   744.8 +Scene::~Scene()
   744.9 +{
  744.10 +	destroy();
  744.11 +}
  744.12 +
  744.13 +void Scene::destroy()
  744.14 +{
  744.15 +	for(size_t i=0; i<objects.size(); i++) {
  744.16 +		delete objects[i];
  744.17 +	}
  744.18 +	objects.clear();
  744.19 +
  744.20 +	for(size_t i=0; i<meshes.size(); i++) {
  744.21 +		delete meshes[i];
  744.22 +	}
  744.23 +	meshes.clear();
  744.24 +
  744.25 +	for(size_t i=0; i<curves.size(); i++) {
  744.26 +		delete curves[i];
  744.27 +	}
  744.28 +	curves.clear();
  744.29 +}
  744.30 +
  744.31 +bool Scene::load(const char *fname)
  744.32 +{
  744.33 +	return load_ass(this, fname);
  744.34 +}
  744.35 +
  744.36 +bool Scene::save(const char *fname) const
  744.37 +{
  744.38 +	return false;	// TODO
  744.39 +}
  744.40 +
  744.41 +void Scene::draw(long msec) const
  744.42 +{
  744.43 +	for(size_t i=0; i<objects.size(); i++) {
  744.44 +		objects[i]->draw(msec);
  744.45 +	}
  744.46 +
  744.47 +	if(objects.empty()) {
  744.48 +		for(size_t i=0; i<meshes.size(); i++) {
  744.49 +			meshes[i]->draw();
  744.50 +		}
  744.51 +	}
  744.52 +}
   745.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   745.2 +++ b/src/scene.h	Sat Feb 01 19:58:19 2014 +0200
   745.3 @@ -0,0 +1,23 @@
   745.4 +#ifndef SCENE_H_
   745.5 +#define SCENE_H_
   745.6 +
   745.7 +#include <vector>
   745.8 +#include "object.h"
   745.9 +#include "curve.h"
  745.10 +
  745.11 +class Scene {
  745.12 +public:
  745.13 +	std::vector<Object*> objects;
  745.14 +	std::vector<Mesh*> meshes;
  745.15 +	std::vector<Curve*> curves;
  745.16 +
  745.17 +	~Scene();
  745.18 +	void destroy();
  745.19 +
  745.20 +	bool load(const char *fname);
  745.21 +	bool save(const char *fname) const;
  745.22 +
  745.23 +	void draw(long msec = 0) const;
  745.24 +};
  745.25 +
  745.26 +#endif	// SCENE_H_
   746.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   746.2 +++ b/src/scr_debug.cc	Sat Feb 01 19:58:19 2014 +0200
   746.3 @@ -0,0 +1,82 @@
   746.4 +#include <assert.h>
   746.5 +#include "scr_debug.h"
   746.6 +#include "opengl.h"
   746.7 +#include "unistate.h"
   746.8 +#include "sdrman.h"
   746.9 +#include "game.h"
  746.10 +#include "drawtext/drawtext.h"
  746.11 +#include "datapath.h"
  746.12 +#include "logger.h"
  746.13 +#include "timer.h"
  746.14 +#include "scr_game.h"
  746.15 +#include "gfxutil.h"
  746.16 +
  746.17 +static ShaderProg *sdr, *color_sdr;
  746.18 +static struct dtx_font *font;
  746.19 +
  746.20 +const char *DebugScreen::get_name() const
  746.21 +{
  746.22 +	return "DebugScreen";
  746.23 +}
  746.24 +
  746.25 +#define FONT_FILENAME	"consolas.ttf"
  746.26 +#define FONT_SIZE		20
  746.27 +
  746.28 +bool DebugScreen::init()
  746.29 +{
  746.30 +	if(!(sdr = get_sdrprog("font.v.glsl", "font.p.glsl"))) {
  746.31 +		return false;
  746.32 +	}
  746.33 +	int vattr = sdr->get_attrib_location("attr_vertex");
  746.34 +	int tcattr = sdr->get_attrib_location("attr_texcoord");
  746.35 +	assert(vattr != -1 && tcattr != -1);
  746.36 +
  746.37 +	dtx_vertex_attribs(vattr, tcattr);
  746.38 +
  746.39 +	if(!(font = dtx_open_font(datafile_path(FONT_FILENAME).c_str(), FONT_SIZE))) {
  746.40 +		return false;
  746.41 +	}
  746.42 +
  746.43 +	if(!(color_sdr = get_sdrprog("color.v.glsl", "color.p.glsl"))) {
  746.44 +		return false;
  746.45 +	}
  746.46 +	return true;
  746.47 +}
  746.48 +
  746.49 +void DebugScreen::cleanup()
  746.50 +{
  746.51 +	delete sdr;
  746.52 +	dtx_close_font(font);
  746.53 +}
  746.54 +
  746.55 +void DebugScreen::display() const
  746.56 +{
  746.57 +	OverlayScreen::display();	// this will draw the previous screen
  746.58 +
  746.59 +	static unsigned long frame;
  746.60 +	static unsigned long prev_tm;
  746.61 +	unsigned long tm = get_time_msec();
  746.62 +	static char fps_text[64];
  746.63 +
  746.64 +	frame++;
  746.65 +	unsigned long interval = tm - prev_tm;
  746.66 +	if(interval >= 1000) {
  746.67 +		float fps = (float)frame / ((float)interval / 1000.0f);
  746.68 +		sprintf(fps_text, "fps: %.1f", fps);
  746.69 +
  746.70 +		frame = 0;
  746.71 +		prev_tm = tm;
  746.72 +	}
  746.73 +
  746.74 +	Matrix4x4 mat;
  746.75 +	mat.set_translation(Vector3(5, get_screen_height() - 20, 0));
  746.76 +	set_world_matrix(mat);
  746.77 +
  746.78 +	set_unistate("st_color", Vector4(1, 1, 0, 1));
  746.79 +
  746.80 +	sdr->bind();
  746.81 +
  746.82 +	dtx_use_font(font, FONT_SIZE);
  746.83 +	dtx_string(fps_text);
  746.84 +	dtx_flush();
  746.85 +}
   747.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   747.2 +++ b/src/scr_debug.h	Sat Feb 01 19:58:19 2014 +0200
   747.3 @@ -0,0 +1,16 @@
   747.4 +#ifndef SCR_DEBUG_H_
   747.5 +#define SCR_DEBUG_H_
   747.6 +
   747.7 +#include "scr_overlay.h"
   747.8 +
   747.9 +class DebugScreen : public OverlayScreen {
  747.10 +public:
  747.11 +	const char *get_name() const;
  747.12 +
  747.13 +	bool init();
  747.14 +	void cleanup();
  747.15 +
  747.16 +	void display() const;
  747.17 +};
  747.18 +
  747.19 +#endif	// SCR_DEBUG_H_
   748.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   748.2 +++ b/src/scr_game.cc	Sat Feb 01 19:58:19 2014 +0200
   748.3 @@ -0,0 +1,107 @@
   748.4 +#include "scr_game.h"
   748.5 +#include "object.h"
   748.6 +#include "game.h"
   748.7 +#include "meshgen.h"
   748.8 +#include "opengl.h"
   748.9 +#include "unistate.h"
  748.10 +#include "logger.h"
  748.11 +#include "level.h"
  748.12 +
  748.13 +static int win_width, win_height;
  748.14 +static bool bnstate[32];
  748.15 +static int prev_x, prev_y;
  748.16 +static float cam_theta, cam_phi = 20, cam_dist = 10;
  748.17 +static Object *floor_obj;
  748.18 +static Level *level;
  748.19 +
  748.20 +const char *GameScreen::get_name() const
  748.21 +{
  748.22 +	return "game";
  748.23 +}
  748.24 +
  748.25 +bool GameScreen::init()
  748.26 +{
  748.27 +	glEnable(GL_LIGHTING);
  748.28 +	glEnable(GL_LIGHT0);
  748.29 +
  748.30 +	floor_obj = new Object;
  748.31 +	floor_obj->set_mesh(new Mesh);
  748.32 +	gen_plane(floor_obj->get_mesh(), 10, 10, 4, 4);
  748.33 +	floor_obj->set_rotation(Quaternion(Vector3(1, 0, 0), -DEG_TO_RAD(90)));
  748.34 +
  748.35 +	level = new Level;
  748.36 +
  748.37 +	return true;
  748.38 +}
  748.39 +
  748.40 +void GameScreen::cleanup()
  748.41 +{
  748.42 +}
  748.43 +
  748.44 +void GameScreen::update(unsigned long tmsec)
  748.45 +{
  748.46 +}
  748.47 +
  748.48 +void GameScreen::display() const
  748.49 +{
  748.50 +	Matrix4x4 matrix;
  748.51 +	matrix.translate(Vector3(0, 0, -cam_dist));
  748.52 +	matrix.rotate(Vector3(1, 0, 0), DEG_TO_RAD(cam_phi));
  748.53 +	matrix.rotate(Vector3(0, 1, 0), DEG_TO_RAD(cam_theta));
  748.54 +	set_view_matrix(matrix);
  748.55 +
  748.56 +	//glUseProgram(0);
  748.57 +
  748.58 +	bind_shader(defsdr);
  748.59 +	//floor_obj->draw();
  748.60 +
  748.61 +	level->draw();
  748.62 +}
  748.63 +
  748.64 +void GameScreen::reshape(int x, int y)
  748.65 +{
  748.66 +	glViewport(0, 0, x, y);
  748.67 +
  748.68 +	win_width = x;
  748.69 +	win_height = y;
  748.70 +
  748.71 +	Matrix4x4 proj;
  748.72 +	proj.set_perspective(M_PI / 4.0, (float)x / (float)y, 0.5, 500.0);
  748.73 +	set_projection_matrix(proj);
  748.74 +}
  748.75 +
  748.76 +void GameScreen::button(int bn, bool pressed, int x, int y)
  748.77 +{
  748.78 +	prev_x = x;
  748.79 +	prev_y = y;
  748.80 +	bnstate[bn] = pressed;
  748.81 +}
  748.82 +
  748.83 +void GameScreen::motion(int x, int y, bool pressed)
  748.84 +{
  748.85 +	int dx = x - prev_x;
  748.86 +	int dy = y - prev_y;
  748.87 +	prev_x = x;
  748.88 +	prev_y = y;
  748.89 +
  748.90 +	if(!dx && !dy) return;
  748.91 +
  748.92 +	if(bnstate[0]) {
  748.93 +		cam_theta += dx * 0.5;
  748.94 +		cam_phi += dy * 0.5;
  748.95 +
  748.96 +		if(cam_phi > 90) cam_phi = 90;
  748.97 +		if(cam_phi < 0) cam_phi = 0;
  748.98 +	}
  748.99 +
 748.100 +	if(bnstate[2]) {
 748.101 +		cam_dist += dy * 0.1;
 748.102 +
 748.103 +		if(cam_dist < 0) cam_dist = 0;
 748.104 +	}
 748.105 +}
 748.106 +
 748.107 +long GameScreen::redisplay_interval() const
 748.108 +{
 748.109 +	return 1;
 748.110 +}
   749.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   749.2 +++ b/src/scr_game.h	Sat Feb 01 19:58:19 2014 +0200
   749.3 @@ -0,0 +1,24 @@
   749.4 +#ifndef SCR_GAME_H_
   749.5 +#define SCR_GAME_H_
   749.6 +
   749.7 +#include "screen.h"
   749.8 +
   749.9 +class GameScreen : public Screen {
  749.10 +public:
  749.11 +	const char *get_name() const;
  749.12 +
  749.13 +	bool init();
  749.14 +	void cleanup();
  749.15 +
  749.16 +	void update(unsigned long tmsec);
  749.17 +	void display() const;
  749.18 +
  749.19 +	void reshape(int x, int y);
  749.20 +
  749.21 +	void button(int bn, bool pressed, int x, int y);
  749.22 +	void motion(int x, int y, bool pressed);
  749.23 +
  749.24 +	long redisplay_interval() const;
  749.25 +};
  749.26 +
  749.27 +#endif	// SCR_GAME_H_
   750.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   750.2 +++ b/src/scr_overlay.cc	Sat Feb 01 19:58:19 2014 +0200
   750.3 @@ -0,0 +1,55 @@
   750.4 +#include "scr_overlay.h"
   750.5 +#include "logger.h"
   750.6 +
   750.7 +void OverlayScreen::start()
   750.8 +{
   750.9 +	if(!(prev = previous_screen())) {
  750.10 +		error_log("Failed to start overlay screen: %s. No previous screen found.\n", get_name());
  750.11 +	}
  750.12 +	prev->start();
  750.13 +}
  750.14 +
  750.15 +void OverlayScreen::stop()
  750.16 +{
  750.17 +	prev->stop();
  750.18 +}
  750.19 +
  750.20 +long OverlayScreen::redisplay_interval() const
  750.21 +{
  750.22 +	return prev->redisplay_interval();
  750.23 +}
  750.24 +
  750.25 +void OverlayScreen::pre_draw() const
  750.26 +{
  750.27 +	prev->pre_draw();
  750.28 +}
  750.29 +
  750.30 +void OverlayScreen::display() const
  750.31 +{
  750.32 +	prev->display();
  750.33 +}
  750.34 +
  750.35 +void OverlayScreen::post_draw() const
  750.36 +{
  750.37 +	prev->post_draw();
  750.38 +}
  750.39 +
  750.40 +void OverlayScreen::keyboard(int key, bool pressed)
  750.41 +{
  750.42 +	prev->keyboard(key, pressed);
  750.43 +}
  750.44 +
  750.45 +void OverlayScreen::motion(int x, int y, bool pressed)
  750.46 +{
  750.47 +	prev->motion(x, y, pressed);
  750.48 +}
  750.49 +
  750.50 +void OverlayScreen::button(int bn, bool pressed, int x, int y)
  750.51 +{
  750.52 +	prev->button(bn, pressed, x, y);
  750.53 +}
  750.54 +
  750.55 +void OverlayScreen::reshape(int x, int y)
  750.56 +{
  750.57 +	prev->reshape(x, y);
  750.58 +}
   751.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   751.2 +++ b/src/scr_overlay.h	Sat Feb 01 19:58:19 2014 +0200
   751.3 @@ -0,0 +1,27 @@
   751.4 +#ifndef SCR_OVERLAY_H_
   751.5 +#define SCR_OVERLAY_H_
   751.6 +
   751.7 +#include "screen.h"
   751.8 +
   751.9 +// abstract base class for overlay screens
  751.10 +class OverlayScreen : public Screen {
  751.11 +protected:
  751.12 +	Screen *prev;
  751.13 +
  751.14 +public:
  751.15 +	virtual void start();
  751.16 +	virtual void stop();
  751.17 +
  751.18 +	virtual long redisplay_interval() const;
  751.19 +
  751.20 +	virtual void pre_draw() const;
  751.21 +	virtual void display() const;
  751.22 +	virtual void post_draw() const;
  751.23 +
  751.24 +	virtual void keyboard(int key, bool pressed);
  751.25 +	virtual void motion(int x, int y, bool pressed);
  751.26 +	virtual void button(int bn, bool pressed, int x, int y);
  751.27 +	virtual void reshape(int x, int y);
  751.28 +};
  751.29 +
  751.30 +#endif	// SCR_OVERLAY_H_
   752.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   752.2 +++ b/src/screen.cc	Sat Feb 01 19:58:19 2014 +0200
   752.3 @@ -0,0 +1,116 @@
   752.4 +#include <vector>
   752.5 +#include "opengl.h"
   752.6 +#include "screen.h"
   752.7 +#include "logger.h"
   752.8 +#include "unistate.h"
   752.9 +
  752.10 +static std::vector<Screen*> scrstack;
  752.11 +
  752.12 +void push_screen(Screen *screen)
  752.13 +{
  752.14 +	Screen *prev = current_screen();
  752.15 +	if(prev) {
  752.16 +		prev->stop();
  752.17 +	}
  752.18 +
  752.19 +	scrstack.push_back(screen);
  752.20 +	screen->start();
  752.21 +}
  752.22 +
  752.23 +Screen *pop_screen()
  752.24 +{
  752.25 +	if(scrstack.empty()) {
  752.26 +		error_log("trying to pop a screen, but the stack is empty!\n");
  752.27 +		return 0;
  752.28 +	}
  752.29 +	Screen *res = scrstack.back();
  752.30 +	scrstack.pop_back();
  752.31 +
  752.32 +	res->stop();
  752.33 +
  752.34 +	Screen *next = current_screen();
  752.35 +	if(next) {
  752.36 +		next->start();
  752.37 +	}
  752.38 +	return res;
  752.39 +}
  752.40 +
  752.41 +Screen *current_screen()
  752.42 +{
  752.43 +	if(scrstack.empty()) {
  752.44 +		return 0;
  752.45 +	}
  752.46 +	return scrstack.back();
  752.47 +}
  752.48 +
  752.49 +Screen *previous_screen()
  752.50 +{
  752.51 +	int sz = scrstack.size();
  752.52 +	if(sz < 2) {
  752.53 +		return 0;
  752.54 +	}
  752.55 +	return scrstack[sz - 2];
  752.56 +}
  752.57 +
  752.58 +Screen::~Screen()
  752.59 +{
  752.60 +}
  752.61 +
  752.62 +const char *Screen::get_name() const
  752.63 +{
  752.64 +	return "Screen";
  752.65 +}
  752.66 +
  752.67 +bool Screen::init()
  752.68 +{
  752.69 +	return true;
  752.70 +}
  752.71 +
  752.72 +void Screen::cleanup()
  752.73 +{
  752.74 +}
  752.75 +
  752.76 +void Screen::start()
  752.77 +{
  752.78 +}
  752.79 +
  752.80 +void Screen::stop()
  752.81 +{
  752.82 +}
  752.83 +
  752.84 +long Screen::redisplay_interval() const
  752.85 +{
  752.86 +	return 0;	// don't redisplay implicitly by default
  752.87 +}
  752.88 +
  752.89 +void Screen::update(unsigned long tmsec)
  752.90 +{
  752.91 +}
  752.92 +
  752.93 +void Screen::pre_draw() const
  752.94 +{
  752.95 +}
  752.96 +
  752.97 +void Screen::display() const
  752.98 +{
  752.99 +}
 752.100 +
 752.101 +void Screen::post_draw() const
 752.102 +{
 752.103 +}
 752.104 +
 752.105 +void Screen::keyboard(int key, bool pressed)
 752.106 +{
 752.107 +}
 752.108 +
 752.109 +void Screen::motion(int x, int y, bool pressed)
 752.110 +{
 752.111 +}
 752.112 +
 752.113 +void Screen::button(int bn, bool pressed, int x, int y)
 752.114 +{
 752.115 +}
 752.116 +
 752.117 +void Screen::reshape(int x, int y)
 752.118 +{
 752.119 +}
   753.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   753.2 +++ b/src/screen.h	Sat Feb 01 19:58:19 2014 +0200
   753.3 @@ -0,0 +1,55 @@
   753.4 +#ifndef SCREEN_H_
   753.5 +#define SCREEN_H_
   753.6 +
   753.7 +class Screen;
   753.8 +
   753.9 +void push_screen(Screen *screen);
  753.10 +Screen *pop_screen();
  753.11 +Screen *current_screen();
  753.12 +Screen *previous_screen();
  753.13 +
  753.14 +
  753.15 +class Screen {
  753.16 +public:
  753.17 +	virtual ~Screen();
  753.18 +
  753.19 +	virtual const char *get_name() const;
  753.20 +
  753.21 +	virtual bool init();
  753.22 +	virtual void cleanup();
  753.23 +
  753.24 +	/// start will be called just before a screen is going to be activated
  753.25 +	virtual void start();
  753.26 +	/// stop will be called when a screen is being deactivated
  753.27 +	virtual void stop();
  753.28 +
  753.29 +	/** each Screen subclass should override this function to specify
  753.30 +	 * the required redisplay interval:
  753.31 +	 * - 0 means no implcit redisplays are to be performed.
  753.32 +	 *   Use request_redisplay to queue up a redisplay.
  753.33 +	 * - Any values > 0 are treated as inter-frame intervals in milliseconds
  753.34 +	 * The default (if not overriden) is 0.
  753.35 +	 */
  753.36 +	virtual long redisplay_interval() const;
  753.37 +
  753.38 +	/// update will be called every frame before display
  753.39 +	virtual void update(unsigned long tmsec);
  753.40 +
  753.41 +	/// pre_draw will be called before display
  753.42 +	virtual void pre_draw() const;
  753.43 +	/// display will be called whenever a screen needs to redraw itself
  753.44 +	virtual void display() const;
  753.45 +	/// post_draw will be called after display
  753.46 +	virtual void post_draw() const;
  753.47 +
  753.48 +	/// keyboard event
  753.49 +	virtual void keyboard(int key, bool pressed);
  753.50 +	/// mouse motion event
  753.51 +	virtual void motion(int x, int y, bool pressed);
  753.52 +	/// mouse button event
  753.53 +	virtual void button(int bn, bool pressed, int x, int y);
  753.54 +	/// reshape event
  753.55 +	virtual void reshape(int x, int y);
  753.56 +};
  753.57 +
  753.58 +#endif	// SCREEN_H_
   754.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   754.2 +++ b/src/sdrman.cc	Sat Feb 01 19:58:19 2014 +0200
   754.3 @@ -0,0 +1,27 @@
   754.4 +#include "sdrman.h"
   754.5 +
   754.6 +ShaderSet vsdrset(GL_VERTEX_SHADER);
   754.7 +ShaderSet psdrset(GL_FRAGMENT_SHADER);
   754.8 +
   754.9 +ShaderProg *get_sdrprog(const char *vname, const char *pname)
  754.10 +{
  754.11 +	Shader *vsdr = vname ? vsdrset.get(vname) : 0;
  754.12 +	Shader *psdr = pname ? psdrset.get(pname) : 0;
  754.13 +
  754.14 +	if(vname && !vsdr) {
  754.15 +		return 0;
  754.16 +	}
  754.17 +	if(pname && !psdr) {
  754.18 +		return 0;
  754.19 +	}
  754.20 +	if(!vsdr && !psdr) {
  754.21 +		return 0;
  754.22 +	}
  754.23 +
  754.24 +	ShaderProg *prog = new ShaderProg;
  754.25 +	if(!prog->create(vsdr, psdr)) {
  754.26 +		delete prog;
  754.27 +		return 0;
  754.28 +	}
  754.29 +	return prog;
  754.30 +}
   755.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   755.2 +++ b/src/sdrman.h	Sat Feb 01 19:58:19 2014 +0200
   755.3 @@ -0,0 +1,11 @@
   755.4 +#ifndef SDRMAN_H_
   755.5 +#define SDRMAN_H_
   755.6 +
   755.7 +#include "shader.h"
   755.8 +
   755.9 +extern ShaderSet vsdrset;
  755.10 +extern ShaderSet psdrset;
  755.11 +
  755.12 +ShaderProg *get_sdrprog(const char *vname, const char *pname);
  755.13 +
  755.14 +#endif	// SDRMAN_H_
   756.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   756.2 +++ b/src/shader.cc	Sat Feb 01 19:58:19 2014 +0200
   756.3 @@ -0,0 +1,659 @@
   756.4 +#include <stdio.h>
   756.5 +#include <string.h>
   756.6 +#include <stdarg.h>
   756.7 +#include <errno.h>
   756.8 +#include "opengl.h"
   756.9 +#include "shader.h"
  756.10 +#include "logger.h"
  756.11 +#include "unistate.h"
  756.12 +#include "mesh.h"
  756.13 +
  756.14 +#ifdef _MSC_VER
  756.15 +#include <malloc.h>
  756.16 +#else
  756.17 +#include <alloca.h>
  756.18 +#endif
  756.19 +
  756.20 +#ifdef __GLEW_H__
  756.21 +#define HAVE_GEOMETRY_SHADER
  756.22 +#define HAVE_TESSELATION_SHADER
  756.23 +#endif
  756.24 +
  756.25 +static void bind_standard_attr(const ShaderProg *prog);
  756.26 +static const char *strtype(unsigned int type);
  756.27 +
  756.28 +ShaderProg *ShaderProg::current;
  756.29 +
  756.30 +void bind_shader(const ShaderProg *sdr)
  756.31 +{
  756.32 +	if(sdr) {
  756.33 +		sdr->bind();
  756.34 +	} else {
  756.35 +#ifndef GL_ES_VERSION_2_0
  756.36 +		glUseProgram(0);
  756.37 +		ShaderProg::current = 0;
  756.38 +#endif
  756.39 +	}
  756.40 +}
  756.41 +
  756.42 +const ShaderProg *get_current_shader()
  756.43 +{
  756.44 +	return ShaderProg::current;
  756.45 +}
  756.46 +
  756.47 +
  756.48 +Shader::Shader()
  756.49 +{
  756.50 +	sdr = type = 0;
  756.51 +	name = 0;
  756.52 +}
  756.53 +
  756.54 +Shader::~Shader()
  756.55 +{
  756.56 +	destroy();
  756.57 +}
  756.58 +
  756.59 +unsigned int Shader::get_id() const
  756.60 +{
  756.61 +	return sdr;
  756.62 +}
  756.63 +
  756.64 +void Shader::set_name(const char *name)
  756.65 +{
  756.66 +	delete [] this->name;
  756.67 +	this->name = new char[strlen(name) + 1];
  756.68 +	strcpy(this->name, name);
  756.69 +}
  756.70 +
  756.71 +const char *Shader::get_name() const
  756.72 +{
  756.73 +	return name;
  756.74 +}
  756.75 +
  756.76 +bool Shader::create(const char *src, unsigned int type)
  756.77 +{
  756.78 +#if !GL_ES_VERSION_2_0
  756.79 +	const char *src_arr[] = {src};
  756.80 +#else
  756.81 +	const char *src_arr[] = { "precision mediump float; ", src };
  756.82 +#endif
  756.83 +
  756.84 +	if(!sdr) {
  756.85 +		sdr = glCreateShader(type);
  756.86 +	}
  756.87 +
  756.88 +	info_log("compiling shader: %s... ", name ? name : "");
  756.89 +
  756.90 +	glShaderSource(sdr, sizeof src_arr / sizeof *src_arr, src_arr, 0);
  756.91 +	glCompileShader(sdr);
  756.92 +
  756.93 +	int status;
  756.94 +	glGetShaderiv(sdr, GL_COMPILE_STATUS, &status);
  756.95 +
  756.96 +	info_log(status ? "success\n" : "failed\n");
  756.97 +
  756.98 +	int info_len;
  756.99 +	glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len);
 756.100 +	if(info_len > 1) {
 756.101 +		char *buf = (char*)alloca(info_len);
 756.102 +		glGetShaderInfoLog(sdr, info_len, 0, buf);
 756.103 +		buf[info_len - 1] = 0;
 756.104 +
 756.105 +		if(status) {
 756.106 +			info_log("%s\n", buf);
 756.107 +		} else {
 756.108 +			error_log("%s\n", buf);
 756.109 +		}
 756.110 +	}
 756.111 +
 756.112 +	return status == GL_TRUE;
 756.113 +}
 756.114 +
 756.115 +void Shader::destroy()
 756.116 +{
 756.117 +	if(sdr) {
 756.118 +		glDeleteShader(sdr);
 756.119 +	}
 756.120 +	sdr = type = 0;
 756.121 +
 756.122 +	delete [] name;
 756.123 +	name = 0;
 756.124 +}
 756.125 +
 756.126 +bool Shader::load(const char *fname, unsigned int type)
 756.127 +{
 756.128 +	FILE *fp;
 756.129 +
 756.130 +	if(!(fp = fopen(fname, "rb"))) {
 756.131 +		error_log("failed to load %s shader: %s: %s\n", strtype(type), fname, strerror(errno));
 756.132 +		return false;
 756.133 +	}
 756.134 +
 756.135 +	fseek(fp, 0, SEEK_END);
 756.136 +	long sz = ftell(fp);
 756.137 +	rewind(fp);
 756.138 +
 756.139 +	char *src = (char*)alloca(sz + 1);
 756.140 +	if(fread(src, 1, sz, fp) < (size_t)sz) {
 756.141 +		error_log("failed to load %s shader: %s: %s\n", strtype(type), fname, strerror(errno));
 756.142 +		fclose(fp);
 756.143 +		return false;
 756.144 +	}
 756.145 +	src[sz] = 0;
 756.146 +	fclose(fp);
 756.147 +
 756.148 +	set_name(fname);
 756.149 +	return create(src, type);
 756.150 +}
 756.151 +
 756.152 +// ---- shader program ----
 756.153 +ShaderProg::ShaderProg()
 756.154 +{
 756.155 +	prog = 0;
 756.156 +	must_link = true;
 756.157 +}
 756.158 +
 756.159 +ShaderProg::~ShaderProg()
 756.160 +{
 756.161 +	destroy();
 756.162 +}
 756.163 +
 756.164 +unsigned int ShaderProg::get_id() const
 756.165 +{
 756.166 +	return prog;
 756.167 +}
 756.168 +
 756.169 +bool ShaderProg::create(const char *src, unsigned int type, ...)
 756.170 +{
 756.171 +	va_list ap;
 756.172 +
 756.173 +	va_start(ap, type);
 756.174 +	bool res = create(src, type, ap);
 756.175 +	va_end(ap);
 756.176 +
 756.177 +	return res;
 756.178 +}
 756.179 +
 756.180 +bool ShaderProg::create(const char *src, unsigned int type, va_list ap)
 756.181 +{
 756.182 +	destroy();
 756.183 +	prog = glCreateProgram();
 756.184 +
 756.185 +	while(src) {
 756.186 +		Shader *sdr = new Shader;
 756.187 +		if(!sdr->create(src, type)) {
 756.188 +			va_end(ap);
 756.189 +			return false;
 756.190 +		}
 756.191 +		add_shader(sdr);
 756.192 +		src = va_arg(ap, const char*);
 756.193 +		type = va_arg(ap, unsigned int);
 756.194 +	}
 756.195 +	return link();
 756.196 +}
 756.197 +
 756.198 +bool ShaderProg::create(const char *vsrc, const char *psrc)
 756.199 +{
 756.200 +	return create(VSDR(vsrc), PSDR(psrc), 0);
 756.201 +}
 756.202 +
 756.203 +bool ShaderProg::create(Shader *sdr, ...)
 756.204 +{
 756.205 +	va_list ap;
 756.206 +
 756.207 +	va_start(ap, sdr);
 756.208 +	bool res = create(sdr, ap);
 756.209 +	va_end(ap);
 756.210 +
 756.211 +	return res;
 756.212 +}
 756.213 +
 756.214 +bool ShaderProg::create(Shader *sdr, va_list ap)
 756.215 +{
 756.216 +	destroy();
 756.217 +	prog = glCreateProgram();
 756.218 +
 756.219 +	while(sdr) {
 756.220 +		add_shader(sdr);
 756.221 +		sdr = va_arg(ap, Shader*);
 756.222 +	}
 756.223 +	return link();
 756.224 +}
 756.225 +
 756.226 +bool ShaderProg::create(Shader *vsdr, Shader *psdr)
 756.227 +{
 756.228 +	return create(vsdr, psdr, 0);
 756.229 +}
 756.230 +
 756.231 +void ShaderProg::destroy()
 756.232 +{
 756.233 +	if(prog) {
 756.234 +		glDeleteProgram(prog);
 756.235 +	}
 756.236 +	prog = 0;
 756.237 +
 756.238 +	shaders.clear();
 756.239 +	// don't actually destroy the shaders, let the ShaderSet own them
 756.240 +}
 756.241 +
 756.242 +bool ShaderProg::load(const char *fname, unsigned int type, ...)
 756.243 +{
 756.244 +	va_list ap;
 756.245 +	va_start(ap, type);
 756.246 +	bool res = load(fname, type, ap);
 756.247 +	va_end(ap);
 756.248 +
 756.249 +	return res;
 756.250 +}
 756.251 +
 756.252 +bool ShaderProg::load(const char *fname, unsigned int type, va_list ap)
 756.253 +{
 756.254 +	destroy();
 756.255 +	prog = glCreateProgram();
 756.256 +
 756.257 +	while(fname) {
 756.258 +		Shader *sdr = new Shader;
 756.259 +		if(!sdr->load(fname, type)) {
 756.260 +			delete sdr;
 756.261 +			return false;
 756.262 +		}
 756.263 +		add_shader(sdr);
 756.264 +
 756.265 +		if((fname = va_arg(ap, const char*))) {
 756.266 +			type = va_arg(ap, unsigned int);
 756.267 +		}
 756.268 +	}
 756.269 +
 756.270 +	return link();
 756.271 +}
 756.272 +
 756.273 +bool ShaderProg::load(const char *vfname, const char *pfname)
 756.274 +{
 756.275 +	return load(VSDR(vfname), PSDR(pfname), 0);
 756.276 +}
 756.277 +
 756.278 +void ShaderProg::add_shader(Shader *sdr)
 756.279 +{
 756.280 +	glAttachShader(prog, sdr->get_id());
 756.281 +}
 756.282 +
 756.283 +bool ShaderProg::link() const
 756.284 +{
 756.285 +	bind_standard_attr(this);
 756.286 +
 756.287 +	CHECKGLERR;
 756.288 +	info_log("linking program ... ");
 756.289 +	glLinkProgram(prog);
 756.290 +
 756.291 +	int status;
 756.292 +	glGetProgramiv(prog, GL_LINK_STATUS, &status);
 756.293 +
 756.294 +	info_log(status ? "success\n" : "failed\n");
 756.295 +
 756.296 +	int info_len;
 756.297 +	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len);
 756.298 +	if(info_len > 1) {
 756.299 +		char *buf = (char*)alloca(info_len);
 756.300 +		glGetProgramInfoLog(prog, info_len, 0, buf);
 756.301 +		buf[info_len - 1] = 0;
 756.302 +
 756.303 +		if(status) {
 756.304 +			info_log("%s\n", buf);
 756.305 +		} else {
 756.306 +			error_log("%s\n", buf);
 756.307 +		}
 756.308 +	}
 756.309 +
 756.310 +	if(status) {
 756.311 +		must_link = false;
 756.312 +		cache_state_uniforms();
 756.313 +
 756.314 +		return true;
 756.315 +	}
 756.316 +	return false;
 756.317 +}
 756.318 +
 756.319 +void ShaderProg::bind() const
 756.320 +{
 756.321 +	CHECKGLERR;
 756.322 +	if(must_link) {
 756.323 +		if(!link()) {
 756.324 +			return;
 756.325 +		}
 756.326 +	}
 756.327 +	CHECKGLERR;
 756.328 +	glUseProgram(prog);
 756.329 +	ShaderProg::current = (ShaderProg*)this;
 756.330 +
 756.331 +	setup_state_uniforms();
 756.332 +}
 756.333 +
 756.334 +
 756.335 +int ShaderProg::get_attrib_location(const char *name) const
 756.336 +{
 756.337 +	glUseProgram(prog);
 756.338 +	return glGetAttribLocation(prog, name);
 756.339 +}
 756.340 +
 756.341 +void ShaderProg::set_attrib_location(const char *name, int loc) const
 756.342 +{
 756.343 +	glBindAttribLocation(prog, loc, name);
 756.344 +	must_link = true;
 756.345 +}
 756.346 +
 756.347 +int ShaderProg::get_uniform_location(const char *name) const
 756.348 +{
 756.349 +	glUseProgram(prog);
 756.350 +	return glGetUniformLocation(prog, name);
 756.351 +}
 756.352 +
 756.353 +bool ShaderProg::set_uniform(int loc, int val) const
 756.354 +{
 756.355 +	glUseProgram(prog);
 756.356 +	if(loc >= 0) {
 756.357 +		glUniform1i(loc, val);
 756.358 +		return true;
 756.359 +	}
 756.360 +	return false;
 756.361 +}
 756.362 +
 756.363 +bool ShaderProg::set_uniform(int loc, float val) const
 756.364 +{
 756.365 +	glUseProgram(prog);
 756.366 +	if(loc >= 0) {
 756.367 +		glUniform1f(loc, val);
 756.368 +		return true;
 756.369 +	}
 756.370 +	return false;
 756.371 +}
 756.372 +
 756.373 +bool ShaderProg::set_uniform(int loc, const Vector2 &v) const
 756.374 +{
 756.375 +	glUseProgram(prog);
 756.376 +	if(loc >= 0) {
 756.377 +		glUniform2f(loc, v.x, v.y);
 756.378 +		return true;
 756.379 +	}
 756.380 +	return false;
 756.381 +}
 756.382 +
 756.383 +bool ShaderProg::set_uniform(int loc, const Vector3 &v) const
 756.384 +{
 756.385 +	glUseProgram(prog);
 756.386 +	if(loc >= 0) {
 756.387 +		glUniform3f(loc, v.x, v.y, v.z);
 756.388 +		return true;
 756.389 +	}
 756.390 +	return false;
 756.391 +}
 756.392 +
 756.393 +bool ShaderProg::set_uniform(int loc, const Vector4 &v) const
 756.394 +{
 756.395 +	glUseProgram(prog);
 756.396 +	if(loc >= 0) {
 756.397 +		glUniform4f(loc, v.x, v.y, v.z, v.w);
 756.398 +		return true;
 756.399 +	}
 756.400 +	return false;
 756.401 +}
 756.402 +
 756.403 +bool ShaderProg::set_uniform(int loc, const Matrix3x3 &m) const
 756.404 +{
 756.405 +	glUseProgram(prog);
 756.406 +	if(loc >= 0) {
 756.407 +		glUniformMatrix3fv(loc, 1, GL_TRUE, m[0]);
 756.408 +		return true;
 756.409 +	}
 756.410 +	return false;
 756.411 +}
 756.412 +
 756.413 +bool ShaderProg::set_uniform(int loc, const Matrix4x4 &m) const
 756.414 +{
 756.415 +	glUseProgram(prog);
 756.416 +	if(loc >= 0) {
 756.417 +		glUniformMatrix4fv(loc, 1, GL_TRUE, m[0]);
 756.418 +		return true;
 756.419 +	}
 756.420 +	return false;
 756.421 +}
 756.422 +
 756.423 +
 756.424 +bool ShaderProg::set_uniform(const char *name, int val) const
 756.425 +{
 756.426 +	return set_uniform(get_uniform_location(name), val);
 756.427 +}
 756.428 +
 756.429 +bool ShaderProg::set_uniform(const char *name, float val) const
 756.430 +{
 756.431 +	return set_uniform(get_uniform_location(name), val);
 756.432 +}
 756.433 +
 756.434 +bool ShaderProg::set_uniform(const char *name, const Vector2 &v) const
 756.435 +{
 756.436 +	return set_uniform(get_uniform_location(name), v);
 756.437 +}
 756.438 +
 756.439 +bool ShaderProg::set_uniform(const char *name, const Vector3 &v) const
 756.440 +{
 756.441 +	return set_uniform(get_uniform_location(name), v);
 756.442 +}
 756.443 +
 756.444 +bool ShaderProg::set_uniform(const char *name, const Vector4 &v) const
 756.445 +{
 756.446 +	return set_uniform(get_uniform_location(name), v);
 756.447 +}
 756.448 +
 756.449 +bool ShaderProg::set_uniform(const char *name, const Matrix3x3 &m) const
 756.450 +{
 756.451 +	return set_uniform(get_uniform_location(name), m);
 756.452 +}
 756.453 +
 756.454 +bool ShaderProg::set_uniform(const char *name, const Matrix4x4 &m) const
 756.455 +{
 756.456 +	return set_uniform(get_uniform_location(name), m);
 756.457 +}
 756.458 +
 756.459 +static StType unist_type(GLenum type)
 756.460 +{
 756.461 +	switch(type) {
 756.462 +	case GL_FLOAT:
 756.463 +		return ST_FLOAT;
 756.464 +	case GL_FLOAT_VEC2:
 756.465 +		return ST_FLOAT2;
 756.466 +	case GL_FLOAT_VEC3:
 756.467 +		return ST_FLOAT3;
 756.468 +	case GL_FLOAT_VEC4:
 756.469 +		return ST_FLOAT4;
 756.470 +	case GL_INT:
 756.471 +	case GL_SAMPLER_2D:
 756.472 +	case GL_SAMPLER_CUBE:
 756.473 +#if !GL_ES_VERSION_2_0
 756.474 +	case GL_SAMPLER_1D:
 756.475 +	case GL_SAMPLER_3D:
 756.476 +	case GL_SAMPLER_1D_SHADOW:
 756.477 +	case GL_SAMPLER_2D_SHADOW:
 756.478 +#endif
 756.479 +		return ST_INT;
 756.480 +	case GL_INT_VEC2:
 756.481 +		return ST_INT2;
 756.482 +	case GL_INT_VEC3:
 756.483 +		return ST_INT3;
 756.484 +	case GL_INT_VEC4:
 756.485 +		return ST_INT4;
 756.486 +	case GL_FLOAT_MAT3:
 756.487 +		return ST_MATRIX3;
 756.488 +	case GL_FLOAT_MAT4:
 756.489 +		return ST_MATRIX4;
 756.490 +	default:
 756.491 +		break;
 756.492 +	}
 756.493 +	return ST_UNKNOWN;
 756.494 +}
 756.495 +
 756.496 +void ShaderProg::cache_state_uniforms() const
 756.497 +{
 756.498 +	if(!glIsProgram(prog)) {
 756.499 +		return;
 756.500 +	}
 756.501 +
 756.502 +	int num_uni;
 756.503 +	glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &num_uni);
 756.504 +
 756.505 +	char name[256];
 756.506 +	for(int i=0; i<num_uni; i++) {
 756.507 +		GLint sz;
 756.508 +		GLenum type;
 756.509 +		glGetActiveUniform(prog, i, sizeof name - 1, 0, &sz, &type, name);
 756.510 +
 756.511 +		if(strstr(name, "st_") == name) {
 756.512 +			StateLocCache s;
 756.513 +			s.sidx = add_unistate(name, unist_type(type));
 756.514 +			s.loc = glGetUniformLocation(prog, name);
 756.515 +			stloc_cache.push_back(s);
 756.516 +		}
 756.517 +	}
 756.518 +}
 756.519 +
 756.520 +void ShaderProg::setup_state_uniforms() const
 756.521 +{
 756.522 +	for(size_t i=0; i<stloc_cache.size(); i++) {
 756.523 +		setup_unistate(stloc_cache[i].sidx, this, stloc_cache[i].loc);
 756.524 +		CHECKGLERR;
 756.525 +	}
 756.526 +}
 756.527 +
 756.528 +// ---- ShaderSet ----
 756.529 +static Shader *load_shader(const char *fname, unsigned int type)
 756.530 +{
 756.531 +	Shader *sdr = new Shader;
 756.532 +	if(!sdr->load(fname, type)) {
 756.533 +		delete sdr;
 756.534 +		return 0;
 756.535 +	}
 756.536 +	return sdr;
 756.537 +}
 756.538 +
 756.539 +static Shader *load_vertex_shader(const char *fname)
 756.540 +{
 756.541 +	return load_shader(fname, GL_VERTEX_SHADER);
 756.542 +}
 756.543 +
 756.544 +static Shader *load_pixel_shader(const char *fname)
 756.545 +{
 756.546 +	return load_shader(fname, GL_FRAGMENT_SHADER);
 756.547 +}
 756.548 +
 756.549 +#ifdef HAVE_GEOMETRY_SHADER
 756.550 +static Shader *load_geom_shader(const char *fname)
 756.551 +{
 756.552 +	return load_shader(fname, GL_GEOMETRY_SHADER);
 756.553 +}
 756.554 +#endif
 756.555 +
 756.556 +#ifdef HAVE_TESSELATION_SHADER
 756.557 +static Shader *load_tc_shader(const char *fname)
 756.558 +{
 756.559 +	return load_shader(fname, GL_TESS_CONTROL_SHADER);
 756.560 +}
 756.561 +
 756.562 +static Shader *load_te_shader(const char *fname)
 756.563 +{
 756.564 +	return load_shader(fname, GL_TESS_EVALUATION_SHADER);
 756.565 +}
 756.566 +#endif
 756.567 +
 756.568 +static void destroy_shader(Shader *sdr)
 756.569 +{
 756.570 +	delete sdr;
 756.571 +}
 756.572 +
 756.573 +ShaderSet::ShaderSet(unsigned int type)
 756.574 +	: DataSet<Shader*>(0, destroy_shader)
 756.575 +{
 756.576 +	this->type = type;
 756.577 +
 756.578 +	switch(type) {
 756.579 +	case GL_VERTEX_SHADER:
 756.580 +		load = load_vertex_shader;
 756.581 +		break;
 756.582 +
 756.583 +	case GL_FRAGMENT_SHADER:
 756.584 +		load = load_pixel_shader;
 756.585 +		break;
 756.586 +
 756.587 +#ifdef HAVE_GEOMETRY_SHADER
 756.588 +	case GL_GEOMETRY_SHADER:
 756.589 +		load = load_geom_shader;
 756.590 +		break;
 756.591 +#endif
 756.592 +
 756.593 +#ifdef HAVE_TESSELATION_SHADER
 756.594 +	case GL_TESS_CONTROL_SHADER:
 756.595 +		load = load_tc_shader;
 756.596 +		break;
 756.597 +
 756.598 +	case GL_TESS_EVALUATION_SHADER:
 756.599 +		load = load_te_shader;
 756.600 +		break;
 756.601 +#endif
 756.602 +
 756.603 +	default:
 756.604 +		error_log("ShaderSet constructed with invalid shader type!\n");
 756.605 +	}
 756.606 +}
 756.607 +
 756.608 +static struct { const char *name; int loc; } attr_loc[] = {
 756.609 +	{"attr_vertex", MESH_ATTR_VERTEX},
 756.610 +	{"attr_normal", MESH_ATTR_NORMAL},
 756.611 +	{"attr_tangent", MESH_ATTR_TANGENT},
 756.612 +	{"attr_texcoord", MESH_ATTR_TEXCOORD},
 756.613 +	{"attr_color", MESH_ATTR_COLOR},
 756.614 +	{"attr_boneweights", MESH_ATTR_BONEWEIGHTS},
 756.615 +	{"attr_boneidx", MESH_ATTR_BONEIDX}
 756.616 +};
 756.617 +
 756.618 +static void bind_standard_attr(const ShaderProg *prog)
 756.619 +{
 756.620 +	// we must link once to find out which are the active attributes
 756.621 +	glLinkProgram(prog->get_id());
 756.622 +
 756.623 +	int num_attr;
 756.624 +	glGetProgramiv(prog->get_id(), GL_ACTIVE_ATTRIBUTES, &num_attr);
 756.625 +
 756.626 +	char name[256];
 756.627 +	for(int i=0; i<num_attr; i++) {
 756.628 +		GLint sz;
 756.629 +		GLenum type;
 756.630 +		glGetActiveAttrib(prog->get_id(), i, sizeof name - 1, 0, &sz, &type, name);
 756.631 +
 756.632 +		for(int j=0; j<(int)(sizeof attr_loc / sizeof *attr_loc); j++) {
 756.633 +			if(strcmp(name, attr_loc[j].name) == 0) {
 756.634 +				prog->set_attrib_location(name, attr_loc[j].loc);
 756.635 +			}
 756.636 +		}
 756.637 +	}
 756.638 +}
 756.639 +
 756.640 +
 756.641 +static const char *strtype(unsigned int type)
 756.642 +{
 756.643 +	switch(type) {
 756.644 +	case GL_VERTEX_SHADER:
 756.645 +		return "vertex";
 756.646 +	case GL_FRAGMENT_SHADER:
 756.647 +		return "fragment";
 756.648 +#ifdef HAVE_GEOMETRY_SHADER
 756.649 +	case GL_GEOMETRY_SHADER:
 756.650 +		return "geometry";
 756.651 +#endif
 756.652 +#ifdef HAVE_TESSELATION_SHADER
 756.653 +	case GL_TESS_CONTROL_SHADER:
 756.654 +		return "tesselation control";
 756.655 +	case GL_TESS_EVALUATION_SHADER:
 756.656 +		return "tesselation evaluation";
 756.657 +#endif
 756.658 +	default:
 756.659 +		break;
 756.660 +	}
 756.661 +	return "<unknown>";
 756.662 +}
   757.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   757.2 +++ b/src/shader.h	Sat Feb 01 19:58:19 2014 +0200
   757.3 @@ -0,0 +1,142 @@
   757.4 +#ifndef SHADER_H_
   757.5 +#define SHADER_H_
   757.6 +
   757.7 +#include <vector>
   757.8 +#include "vmath/vmath.h"
   757.9 +#include "opengl.h"
  757.10 +#include "dataset.h"
  757.11 +
  757.12 +class ShaderProg;
  757.13 +
  757.14 +
  757.15 +void bind_shader(const ShaderProg *sdr);
  757.16 +const ShaderProg *get_current_shader();
  757.17 +
  757.18 +
  757.19 +class Shader {
  757.20 +private:
  757.21 +	unsigned int sdr;
  757.22 +	unsigned int type;
  757.23 +	char *name;
  757.24 +
  757.25 +public:
  757.26 +	Shader();
  757.27 +	~Shader();
  757.28 +
  757.29 +	unsigned int get_id() const;
  757.30 +
  757.31 +	void set_name(const char *name);
  757.32 +	const char *get_name() const;
  757.33 +
  757.34 +	bool create(const char *src, unsigned int type);
  757.35 +	void destroy();
  757.36 +
  757.37 +	bool load(const char *fname, unsigned int type);
  757.38 +};
  757.39 +
  757.40 +#define VSDR(s)		s, GL_VERTEX_SHADER
  757.41 +#define FSDR(s)		s, GL_FRAGMENT_SHADER
  757.42 +#define PSDR(s)		FSDR(s)
  757.43 +#define GSDR(s)		s, GL_GEOMETRY_SHADER
  757.44 +#define TCSDR(s)	s, GL_TESS_CONTROL_SHADER
  757.45 +#define TESDR(s)	s, GL_TESS_EVALUATION_SHADER
  757.46 +
  757.47 +class ShaderProg {
  757.48 +private:
  757.49 +	unsigned int prog;
  757.50 +	mutable bool must_link;
  757.51 +	std::vector<Shader*> shaders;
  757.52 +
  757.53 +	struct StateLocCache { int sidx, loc; };
  757.54 +	/** a cache of all st_ prefixed uniform locations and their corresponding
  757.55 +	 * index in the global uniform state vector (see unistate.h)
  757.56 +	 */
  757.57 +	mutable std::vector<StateLocCache> stloc_cache;
  757.58 +
  757.59 +	void cache_state_uniforms() const;
  757.60 +	void setup_state_uniforms() const;
  757.61 +
  757.62 +public:
  757.63 +	static ShaderProg *current;
  757.64 +
  757.65 +	ShaderProg();
  757.66 +	~ShaderProg();
  757.67 +
  757.68 +	/// returns the OpenGL object id for this shader program
  757.69 +	unsigned int get_id() const;
  757.70 +
  757.71 +	/** takes a series of shaders, and constructs a program object by linking
  757.72 +	 * them together. Terminate with a null pointer (don't use 0!) */
  757.73 +	bool create(Shader *sdr, ...);
  757.74 +	/// same as above, but with a va_list instead of variable arguments.
  757.75 +	bool create(Shader *sdr, va_list ap);
  757.76 +	/** takes two shaders (vertex and pixel) and constructs a program object by
  757.77 +	 * linking them together. Either one can be null. */
  757.78 +	bool create(Shader *vsdr, Shader *psdr);
  757.79 +
  757.80 +	/** takes a series of shader source/shader type pairs and constructs a program
  757.81 +	 * object by linking them together. Terminate with a null pointer (don't use 0!)
  757.82 +	 * You can use the VSDR, PSDR, GSDR, TCSDR, TESDR convenience macros for passing
  757.83 +	 * the pairs.
  757.84 +	 * Example: create(VSDR(vsrc0), VSDR(vsrc1), PSDR(psrc), NULL);
  757.85 +	 */
  757.86 +	bool create(const char *src, unsigned int type, ...);
  757.87 +	/// same as above, but with a va_list instead of variable arguments.
  757.88 +	bool create(const char *src, unsigned int type, va_list ap);
  757.89 +	/** takes two shaders source strings (vertex and pixel) and constructs
  757.90 +	 * a program object by linking them together. Either one can be null. */
  757.91 +	bool create(const char *vsrc, const char *psrc);
  757.92 +
  757.93 +	void destroy();
  757.94 +
  757.95 +	/** takes a series of shader filename/shader type pairs, loads the shaders and
  757.96 +	 * constructs a program object by linking them together. Terminate with a null
  757.97 +	 * pointer (don't use 0!). You can use the VSDR, PSDR, GSDR, TCSDR, TESDR convenience
  757.98 +	 * macros for passing the pairs.
  757.99 +	 * Example: load(VSDR("vsdr1.glsl"), VSDR("vsdr2.glsl"), PSDR("pixel.glsl"), NULL);
 757.100 +	 */
 757.101 +	bool load(const char *fname, unsigned int type, ...);
 757.102 +	/// same as above, but with a va_list instead of variable arguments.
 757.103 +	bool load(const char *fname, unsigned int type, va_list ap);
 757.104 +	/** takes the filenames of two shader files (vertex and pixel), loads them and
 757.105 +	 * constructs a program object by linking them together. Either one can be null */
 757.106 +	bool load(const char *vsrc, const char *psrc);
 757.107 +
 757.108 +	void add_shader(Shader *sdr);
 757.109 +	bool link() const;
 757.110 +
 757.111 +	void bind() const;
 757.112 +
 757.113 +	int get_attrib_location(const char *name) const;
 757.114 +	void set_attrib_location(const char *name, int loc) const;
 757.115 +
 757.116 +	int get_uniform_location(const char *name) const;
 757.117 +
 757.118 +	bool set_uniform(int loc, int val) const;
 757.119 +	bool set_uniform(int loc, float val) const;
 757.120 +	bool set_uniform(int loc, const Vector2 &v) const;
 757.121 +	bool set_uniform(int loc, const Vector3 &v) const;
 757.122 +	bool set_uniform(int loc, const Vector4 &v) const;
 757.123 +	bool set_uniform(int loc, const Matrix3x3 &m) const;
 757.124 +	bool set_uniform(int loc, const Matrix4x4 &m) const;
 757.125 +
 757.126 +	bool set_uniform(const char *name, int val) const;
 757.127 +	bool set_uniform(const char *name, float val) const;
 757.128 +	bool set_uniform(const char *name, const Vector2 &v) const;
 757.129 +	bool set_uniform(const char *name, const Vector3 &v) const;
 757.130 +	bool set_uniform(const char *name, const Vector4 &v) const;
 757.131 +	bool set_uniform(const char *name, const Matrix3x3 &m) const;
 757.132 +	bool set_uniform(const char *name, const Matrix4x4 &m) const;
 757.133 +
 757.134 +	friend void setup_unistate(const ShaderProg*);
 757.135 +};
 757.136 +
 757.137 +class ShaderSet : public DataSet<Shader*> {
 757.138 +private:
 757.139 +	unsigned int type;
 757.140 +
 757.141 +public:
 757.142 +	ShaderSet(unsigned int type);
 757.143 +};
 757.144 +
 757.145 +#endif	// SHADER_H_
   758.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   758.2 +++ b/src/texgen.cc	Sat Feb 01 19:58:19 2014 +0200
   758.3 @@ -0,0 +1,137 @@
   758.4 +#include "texgen.h"
   758.5 +
   758.6 +static void intcolor(const Vector4 &color, int *icol);
   758.7 +
   758.8 +Image *texgen_solid(int xsz, int ysz, const Vector4 &color)
   758.9 +{
  758.10 +	Image *img = new Image;
  758.11 +	if(!img->create(xsz, ysz, Image::FMT_RGBA)) {
  758.12 +		delete img;
  758.13 +		return 0;
  758.14 +	}
  758.15 +
  758.16 +	int col[4];
  758.17 +	intcolor(color, col);
  758.18 +
  758.19 +	unsigned char *pix = (unsigned char*)img->get_pixels();
  758.20 +	for(int i=0; i<xsz * ysz; i++) {
  758.21 +		*pix++ = col[0];
  758.22 +		*pix++ = col[1];
  758.23 +		*pix++ = col[2];
  758.24 +		*pix++ = col[3];
  758.25 +	}
  758.26 +	return img;
  758.27 +}
  758.28 +
  758.29 +Image *texgen_chess(int xsz, int ysz, int usub, int vsub, const Vector4 &col1, const Vector4 &col2)
  758.30 +{
  758.31 +	Image *img = new Image;
  758.32 +	if(!img->create(xsz, ysz, Image::FMT_RGBA)) {
  758.33 +		delete img;
  758.34 +		return 0;
  758.35 +	}
  758.36 +
  758.37 +	int c1[4], c2[4];
  758.38 +	intcolor(col1, c1);
  758.39 +	intcolor(col2, c2);
  758.40 +
  758.41 +	int udiv = xsz / usub;
  758.42 +	int vdiv = ysz / vsub;
  758.43 +
  758.44 +	unsigned char *pix = (unsigned char*)img->get_pixels();
  758.45 +	for(int i=0; i<ysz; i++) {
  758.46 +		for(int j=0; j<xsz; j++) {
  758.47 +			if(((i / vdiv) & 1) == ((j / udiv) & 1)) {
  758.48 +				*pix++ = c1[0];
  758.49 +				*pix++ = c1[1];
  758.50 +				*pix++ = c1[2];
  758.51 +				*pix++ = c1[3];
  758.52 +			} else {
  758.53 +				*pix++ = c2[0];
  758.54 +				*pix++ = c2[1];
  758.55 +				*pix++ = c2[2];
  758.56 +				*pix++ = c2[3];
  758.57 +			}
  758.58 +		}
  758.59 +	}
  758.60 +	return img;
  758.61 +}
  758.62 +
  758.63 +
  758.64 +Image *texgen(int xsz, int ysz, float usize, float vsize, Vector4 (*eval)(float, float, void*), void *cls)
  758.65 +{
  758.66 +	Image *img = new Image;
  758.67 +	if(!img->create(xsz, ysz, Image::FMT_RGBA)) {
  758.68 +		delete img;
  758.69 +		return 0;
  758.70 +	}
  758.71 +
  758.72 +	unsigned char *pix = (unsigned char*)img->get_pixels();
  758.73 +	for(int i=0; i<ysz; i++) {
  758.74 +		for(int j=0; j<xsz; j++) {
  758.75 +			float x = usize * (float)j / (float)xsz;
  758.76 +			float y = vsize * (float)i / (float)ysz;
  758.77 +
  758.78 +			Vector4 color = eval(x, y, cls);
  758.79 +
  758.80 +			int icol[4];
  758.81 +			intcolor(color, icol);
  758.82 +
  758.83 +			*pix++ = icol[0];
  758.84 +			*pix++ = icol[1];
  758.85 +			*pix++ = icol[2];
  758.86 +			*pix++ = icol[3];
  758.87 +		}
  758.88 +	}
  758.89 +	return img;
  758.90 +}
  758.91 +
  758.92 +
  758.93 +struct NoiseArg {
  758.94 +	int octaves;
  758.95 +	Vector4 col1, col2;
  758.96 +};
  758.97 +
  758.98 +static Vector4 fbm_eval(float x, float y, void *cls)
  758.99 +{
 758.100 +	NoiseArg *arg = (NoiseArg*)cls;
 758.101 +
 758.102 +	float noise = fbm2(x, y, arg->octaves) * 0.5 + 0.5;
 758.103 +	return lerp(arg->col1, arg->col2, noise);
 758.104 +}
 758.105 +
 758.106 +static Vector4 fbm_abs_eval(float x, float y, void *cls)
 758.107 +{
 758.108 +	NoiseArg *arg = (NoiseArg*)cls;
 758.109 +
 758.110 +	float noise = turbulence2(x, y, arg->octaves) * 0.5 + 0.5;
 758.111 +	return lerp(arg->col1, arg->col2, noise);
 758.112 +}
 758.113 +
 758.114 +
 758.115 +Image *texgen_fbm(int xsz, int ysz, float usize, float vsize, int octaves, const Vector4 &col1, const Vector4 &col2)
 758.116 +{
 758.117 +	NoiseArg arg = {octaves, col1, col2};
 758.118 +	if(arg.octaves < 1) {
 758.119 +		arg.octaves = 1;
 758.120 +	}
 758.121 +
 758.122 +	return texgen(xsz, ysz, usize, vsize, fbm_eval, &arg);
 758.123 +}
 758.124 +
 758.125 +Image *texgen_fbm_abs(int xsz, int ysz, float usize, float vsize, int octaves, const Vector4 &col1, const Vector4 &col2)
 758.126 +{
 758.127 +	NoiseArg arg = {octaves, col1, col2};
 758.128 +	if(arg.octaves < 1) {
 758.129 +		arg.octaves = 1;
 758.130 +	}
 758.131 +
 758.132 +	return texgen(xsz, ysz, usize, vsize, fbm_abs_eval, &arg);
 758.133 +}
 758.134 +
 758.135 +static inline void intcolor(const Vector4 &color, int *icol)
 758.136 +{
 758.137 +	for(int i=0; i<4; i++) {
 758.138 +		icol[i] = std::max(std::min((int)(color[i] * 255.0), 255), 0);
 758.139 +	}
 758.140 +}
   759.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   759.2 +++ b/src/texgen.h	Sat Feb 01 19:58:19 2014 +0200
   759.3 @@ -0,0 +1,14 @@
   759.4 +#ifndef TEXGEN_H_
   759.5 +#define TEXGEN_H_
   759.6 +
   759.7 +#include "image.h"
   759.8 +#include "vmath/vmath.h"
   759.9 +
  759.10 +Image *texgen_solid(int xsz, int ysz, const Vector4 &color);
  759.11 +Image *texgen_chess(int xsz, int ysz, int usub, int vsub, const Vector4 &col1, const Vector4 &col2);
  759.12 +Image *texgen_fbm(int xsz, int ysz, float usize, float vsize, int octaves, const Vector4 &col1, const Vector4 &col2);
  759.13 +Image *texgen_fbm_abs(int xsz, int ysz, float usize, float vsize, int octaves, const Vector4 &col1, const Vector4 &col2);
  759.14 +
  759.15 +Image *texgen(int xsz, int ysz, float usize, float vsize, Vector4 (*eval)(float, float, void*), void *cls);
  759.16 +
  759.17 +#endif	// TEXGEN_H_
   760.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   760.2 +++ b/src/texman.cc	Sat Feb 01 19:58:19 2014 +0200
   760.3 @@ -0,0 +1,3 @@
   760.4 +#include "texman.h"
   760.5 +
   760.6 +TextureSet texset;
   761.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   761.2 +++ b/src/texman.h	Sat Feb 01 19:58:19 2014 +0200
   761.3 @@ -0,0 +1,8 @@
   761.4 +#ifndef TEXMAN_H_
   761.5 +#define TEXMAN_H_
   761.6 +
   761.7 +#include "texture.h"
   761.8 +
   761.9 +extern TextureSet texset;
  761.10 +
  761.11 +#endif	// TEXMAN_H_
   762.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   762.2 +++ b/src/texture.cc	Sat Feb 01 19:58:19 2014 +0200
   762.3 @@ -0,0 +1,437 @@
   762.4 +#include <math.h>
   762.5 +#include "texture.h"
   762.6 +#include "image.h"
   762.7 +#include "opengl.h"
   762.8 +#include "imago2.h"
   762.9 +#include "logger.h"
  762.10 +#include "datapath.h"
  762.11 +
  762.12 +static int glifmt_from_ifmt(unsigned int ifmt);
  762.13 +static int glfmt_from_ifmt(unsigned int ifmt);
  762.14 +static int gltype_from_ifmt(unsigned int ifmt);
  762.15 +
  762.16 +static int glifmt_from_imgfmt(Image::Format fmt);
  762.17 +
  762.18 +static unsigned int cur_target[8] = {
  762.19 +	GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D,
  762.20 +	GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D
  762.21 +};
  762.22 +
  762.23 +void set_texture(Texture *tex, int tunit)
  762.24 +{
  762.25 +	if(tex) {
  762.26 +		tex->bind(tunit);
  762.27 +	} else {
  762.28 +		glActiveTexture(GL_TEXTURE0 + tunit);
  762.29 +		glBindTexture(cur_target[tunit], 0);
  762.30 +		glActiveTexture(GL_TEXTURE0);
  762.31 +	}
  762.32 +}
  762.33 +
  762.34 +Texture *load_texture(const char *fname)
  762.35 +{
  762.36 +	TextureCube *texcube = new TextureCube;
  762.37 +	if(texcube->load(fname)) {
  762.38 +		return texcube;
  762.39 +	}
  762.40 +	delete texcube;
  762.41 +
  762.42 +	Texture2D *tex = new Texture2D;
  762.43 +	if(tex->load(fname)) {
  762.44 +		return tex;
  762.45 +	}
  762.46 +	delete tex;
  762.47 +	return 0;
  762.48 +}
  762.49 +
  762.50 +Texture::Texture()
  762.51 +{
  762.52 +	target = 0;
  762.53 +	sz[0] = sz[1] = sz[2] = 0;
  762.54 +	texfmt = 0;
  762.55 +
  762.56 +	glGenTextures(1, &id);
  762.57 +}
  762.58 +
  762.59 +Texture::~Texture()
  762.60 +{
  762.61 +	if(id) {
  762.62 +		glDeleteTextures(1, &id);
  762.63 +	}
  762.64 +}
  762.65 +
  762.66 +void Texture::set_wrapping(unsigned int wrap)
  762.67 +{
  762.68 +	if(!target) {
  762.69 +		return;
  762.70 +	}
  762.71 +
  762.72 +	glBindTexture(target, id);
  762.73 +	glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
  762.74 +	glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
  762.75 +}
  762.76 +
  762.77 +void Texture::set_filtering(unsigned int filt)
  762.78 +{
  762.79 +	unsigned int mag_filter;
  762.80 +
  762.81 +	if(!target) {
  762.82 +		return;
  762.83 +	}
  762.84 +
  762.85 +	switch(filt) {
  762.86 +	case GL_LINEAR_MIPMAP_NEAREST:
  762.87 +	case GL_LINEAR_MIPMAP_LINEAR:
  762.88 +		mag_filter = GL_LINEAR;
  762.89 +		break;
  762.90 +
  762.91 +	case GL_NEAREST_MIPMAP_NEAREST:
  762.92 +	case GL_NEAREST_MIPMAP_LINEAR:
  762.93 +		mag_filter = GL_NEAREST;
  762.94 +		break;
  762.95 +
  762.96 +	default:
  762.97 +		mag_filter = filt;
  762.98 +	}
  762.99 +
 762.100 +	set_filtering(filt, mag_filter);
 762.101 +}
 762.102 +
 762.103 +void Texture::set_filtering(unsigned int min_filt, unsigned int mag_filt)
 762.104 +{
 762.105 +	glBindTexture(target, id);
 762.106 +	glTexParameteri(target, GL_TEXTURE_MIN_FILTER, min_filt);
 762.107 +	glTexParameteri(target, GL_TEXTURE_MAG_FILTER, mag_filt);
 762.108 +}
 762.109 +
 762.110 +unsigned int Texture::get_format() const
 762.111 +{
 762.112 +	return texfmt;
 762.113 +}
 762.114 +
 762.115 +int Texture::get_size(int dim) const
 762.116 +{
 762.117 +	if(dim < 0 || dim >= 3) {
 762.118 +		return 0;
 762.119 +	}
 762.120 +	return sz[dim];
 762.121 +}
 762.122 +
 762.123 +unsigned int Texture::get_id() const
 762.124 +{
 762.125 +	return id;
 762.126 +}
 762.127 +
 762.128 +void Texture::bind(int tex_unit) const
 762.129 +{
 762.130 +	glActiveTexture(GL_TEXTURE0 + tex_unit);
 762.131 +	glBindTexture(target, id);
 762.132 +	glActiveTexture(GL_TEXTURE0);
 762.133 +
 762.134 +	cur_target[tex_unit] = target;
 762.135 +}
 762.136 +
 762.137 +
 762.138 +// ---- Texture2D ----
 762.139 +
 762.140 +Texture2D::Texture2D()
 762.141 +{
 762.142 +	target = GL_TEXTURE_2D;
 762.143 +}
 762.144 +
 762.145 +void Texture2D::create(int xsz, int ysz, unsigned int ifmt)
 762.146 +{
 762.147 +	int fmt = glfmt_from_ifmt(ifmt);
 762.148 +	int type = gltype_from_ifmt(ifmt);
 762.149 +
 762.150 +	glBindTexture(GL_TEXTURE_2D, id);
 762.151 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 762.152 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 762.153 +	glTexImage2D(GL_TEXTURE_2D, 0, glifmt_from_ifmt(ifmt), xsz, ysz, 0, fmt, type, 0);
 762.154 +	CHECKGLERR;
 762.155 +	sz[0] = xsz;
 762.156 +	sz[1] = ysz;
 762.157 +	texfmt = ifmt;
 762.158 +}
 762.159 +
 762.160 +void Texture2D::set_image(const Image &img, int idx)
 762.161 +{
 762.162 +	texfmt = glifmt_from_imgfmt(img.get_format());
 762.163 +	unsigned int fmt = glfmt_from_ifmt(texfmt);
 762.164 +	unsigned int type = gltype_from_ifmt(texfmt);
 762.165 +
 762.166 +	sz[0] = img.get_width();
 762.167 +	sz[1] = img.get_height();
 762.168 +
 762.169 +	glBindTexture(GL_TEXTURE_2D, id);
 762.170 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 762.171 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 762.172 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 762.173 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 762.174 +
 762.175 +#ifdef __GLEW_H__
 762.176 +	if(GLEW_SGIS_generate_mipmap) {
 762.177 +		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
 762.178 +#endif
 762.179 +		glTexImage2D(GL_TEXTURE_2D, 0, texfmt, sz[0], sz[1], 0, fmt, type, img.get_pixels());
 762.180 +#ifdef __GLEW_H__
 762.181 +	} else {
 762.182 +		gluBuild2DMipmaps(GL_TEXTURE_2D, texfmt, sz[0], sz[1], fmt, type, img.get_pixels());
 762.183 +	}
 762.184 +#endif
 762.185 +
 762.186 +#ifdef GL_ES_VERSION_2_0
 762.187 +	glGenerateMipmap(GL_TEXTURE_2D);
 762.188 +#endif
 762.189 +}
 762.190 +
 762.191 +bool Texture2D::load(const char *fname)
 762.192 +{
 762.193 +	Image img;
 762.194 +	if(!img.load(fname)) {
 762.195 +		error_log("failed to load 2D texture: %s\n", fname);
 762.196 +		return false;
 762.197 +	}
 762.198 +	set_image(img);
 762.199 +
 762.200 +	info_log("loaded 2D texture: %s\n", fname);
 762.201 +	return true;
 762.202 +}
 762.203 +
 762.204 +bool Texture2D::save(const char *fname) const
 762.205 +{
 762.206 +#ifndef GL_ES_VERSION_2_0
 762.207 +	unsigned char *pixels = new unsigned char[sz[0] * sz[1] * 4];
 762.208 +
 762.209 +	glBindTexture(GL_TEXTURE_2D, id);
 762.210 +	glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 762.211 +
 762.212 +	if(img_save_pixels(fname, pixels, sz[0], sz[1]) == -1) {
 762.213 +		error_log("failed to save 2D texture: %s\n", fname);
 762.214 +		delete [] pixels;
 762.215 +		return false;
 762.216 +	}
 762.217 +
 762.218 +	info_log("saved 2D texture: %s\n", fname);
 762.219 +	delete [] pixels;
 762.220 +	return true;
 762.221 +#else
 762.222 +	return false;	// TODO
 762.223 +#endif
 762.224 +}
 762.225 +
 762.226 +// ---- TextureCube ----
 762.227 +static unsigned int cube_faces[] = {
 762.228 +	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
 762.229 +	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
 762.230 +	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
 762.231 +	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
 762.232 +	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
 762.233 +	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
 762.234 +};
 762.235 +
 762.236 +TextureCube::TextureCube()
 762.237 +{
 762.238 +	target = GL_TEXTURE_CUBE_MAP;
 762.239 +}
 762.240 +
 762.241 +void TextureCube::create(int xsz, int ysz, unsigned int ifmt)
 762.242 +{
 762.243 +	if(xsz != ysz) {
 762.244 +		error_log("trying to create cubemap with different width and height (%dx%d)\n", xsz, ysz);
 762.245 +		return;
 762.246 +	}
 762.247 +
 762.248 +	texfmt = ifmt;
 762.249 +
 762.250 +	glBindTexture(GL_TEXTURE_CUBE_MAP, id);
 762.251 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 762.252 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 762.253 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 762.254 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 762.255 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
 762.256 +
 762.257 +	for(int i=0; i<6; i++) {
 762.258 +		glTexImage2D(cube_faces[i], 0, ifmt, xsz, ysz, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
 762.259 +	}
 762.260 +}
 762.261 +
 762.262 +void TextureCube::set_image(const Image &img, int idx)
 762.263 +{
 762.264 +	texfmt = glifmt_from_imgfmt(img.get_format());
 762.265 +	unsigned int fmt = glfmt_from_ifmt(texfmt);
 762.266 +	unsigned int type = gltype_from_ifmt(texfmt);
 762.267 +
 762.268 +	sz[0] = img.get_width();
 762.269 +	sz[1] = img.get_height();
 762.270 +
 762.271 +	glBindTexture(GL_TEXTURE_CUBE_MAP, id);
 762.272 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 762.273 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 762.274 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 762.275 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 762.276 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
 762.277 +
 762.278 +	glTexImage2D(cube_faces[idx], 0, texfmt, sz[0], sz[1], 0, fmt, type, img.get_pixels());
 762.279 +}
 762.280 +
 762.281 +bool TextureCube::load(const char *fname)
 762.282 +{
 762.283 +	static const float one_third = 1.0 / 3.0;
 762.284 +	static const float two_thirds = 2.0 / 3.0;
 762.285 +	static const float hcross[2][6] = {
 762.286 +		{0.5, 0.0, 0.25, 0.25, 0.25, 0.75}, {one_third, one_third, 0.0, two_thirds, one_third, one_third} };
 762.287 +	static const float vcross[2][6] = {
 762.288 +		{two_thirds, 0.0, one_third, one_third, one_third, one_third}, {0.25, 0.25, 0.0, 0.5, 0.25, 0.75} };
 762.289 +	static const float hsix[2][6] = {
 762.290 +		{0.0, 0.0, one_third, one_third, two_thirds, two_thirds}, {0.0, 0.5, 0.0, 0.5, 0.0, 0.5} };
 762.291 +
 762.292 +	Image img;
 762.293 +	if(!img.load(fname)) {
 762.294 +		return false;
 762.295 +	}
 762.296 +
 762.297 +	int xsz = img.get_width();
 762.298 +	int ysz = img.get_height();
 762.299 +
 762.300 +	if(xsz / 4 == ysz / 3) {
 762.301 +		// horizontal cross, assume the vertical bit is center-left
 762.302 +		return load_multi(img, hcross[0], hcross[1], xsz / 4);
 762.303 +	}
 762.304 +	if(xsz / 3 == ysz / 4) {
 762.305 +		// vertical cross, assume the horizontal bit is center-top (180-rotated image 5)
 762.306 +		return load_multi(img, vcross[0], vcross[1], ysz / 4, (1 << 5));
 762.307 +	}
 762.308 +	if(xsz / 3 == ysz / 2) {
 762.309 +		// horizontal sixpack
 762.310 +		return load_multi(img, hsix[0], hsix[1], ysz / 2);
 762.311 +	}
 762.312 +
 762.313 +	error_log("failed to load %s: unknown cubemap configuration\n", fname);
 762.314 +	return false;
 762.315 +}
 762.316 +
 762.317 +bool TextureCube::save(const char *fname) const
 762.318 +{
 762.319 +	return false;	// TODO
 762.320 +}
 762.321 +
 762.322 +bool TextureCube::load_multi(const Image &img, const float *xoffsets, const float *yoffsets, float sz,
 762.323 +		unsigned int rotmask)
 762.324 +{
 762.325 +	for(int i=0; i<6; i++) {
 762.326 +		Image face;
 762.327 +
 762.328 +		int xoffs = xoffsets[i] * img.get_width();
 762.329 +		int yoffs = yoffsets[i] * img.get_height();
 762.330 +
 762.331 +		if(!face.set_pixels(sz, sz, img.get_pixels(), xoffs, yoffs, img.get_width(), img.get_format())) {
 762.332 +			return false;
 762.333 +		}
 762.334 +
 762.335 +		if(rotmask & (1 << i)) {
 762.336 +			face.rotate_180();
 762.337 +		}
 762.338 +		set_image(face, i);
 762.339 +	}
 762.340 +	return true;
 762.341 +}
 762.342 +
 762.343 +static int glifmt_from_ifmt(unsigned int ifmt)
 762.344 +{
 762.345 +#ifdef GL_ES_VERSION_2_0
 762.346 +	switch(ifmt) {
 762.347 +	case GL_LUMINANCE16F:
 762.348 +	case GL_LUMINANCE32F:
 762.349 +		ifmt = GL_LUMINANCE;
 762.350 +		break;
 762.351 +
 762.352 +	case GL_RGB16F:
 762.353 +	case GL_RGB32F:
 762.354 +		ifmt = GL_RGB;
 762.355 +		break;
 762.356 +
 762.357 +	case GL_RGBA16F:
 762.358 +	case GL_RGBA32F:
 762.359 +		ifmt = GL_RGBA;
 762.360 +		break;
 762.361 +
 762.362 +	default:
 762.363 +		break;
 762.364 +	}
 762.365 +#endif
 762.366 +	return ifmt;	// by default just pass it through...
 762.367 +}
 762.368 +
 762.369 +static int glfmt_from_ifmt(unsigned int ifmt)
 762.370 +{
 762.371 +	switch(ifmt) {
 762.372 +	case GL_LUMINANCE16F:
 762.373 +	case GL_LUMINANCE32F:
 762.374 +		return GL_LUMINANCE;
 762.375 +
 762.376 +	case GL_RGB16F:
 762.377 +	case GL_RGB32F:
 762.378 +		return GL_RGB;
 762.379 +
 762.380 +	case GL_RGBA16F:
 762.381 +	case GL_RGBA32F:
 762.382 +		return GL_RGBA;
 762.383 +
 762.384 +	default:
 762.385 +		break;
 762.386 +	}
 762.387 +	return ifmt;
 762.388 +}
 762.389 +
 762.390 +static int gltype_from_ifmt(unsigned int ifmt)
 762.391 +{
 762.392 +	switch(ifmt) {
 762.393 +	case GL_RGB16F:
 762.394 +	case GL_RGBA16F:
 762.395 +	case GL_LUMINANCE16F:
 762.396 +#ifdef GL_ES_VERSION_2_0
 762.397 +		return GL_HALF_FLOAT_OES;
 762.398 +#endif
 762.399 +	case GL_RGB32F:
 762.400 +	case GL_RGBA32F:
 762.401 +	case GL_LUMINANCE32F:
 762.402 +		return GL_FLOAT;
 762.403 +
 762.404 +	default:
 762.405 +		break;
 762.406 +	}
 762.407 +	return GL_UNSIGNED_BYTE;
 762.408 +}
 762.409 +
 762.410 +static int glifmt_from_imgfmt(Image::Format fmt)
 762.411 +{
 762.412 +	switch(fmt) {
 762.413 +	case Image::FMT_GREY:
 762.414 +		return GL_LUMINANCE;
 762.415 +	case Image::FMT_GREY_FLOAT:
 762.416 +		return GL_LUMINANCE16F;
 762.417 +	case Image::FMT_RGB:
 762.418 +		return GL_RGB;
 762.419 +	case Image::FMT_RGB_FLOAT:
 762.420 +		return GL_RGB16F;
 762.421 +	case Image::FMT_RGBA:
 762.422 +		return GL_RGBA;
 762.423 +	case Image::FMT_RGBA_FLOAT:
 762.424 +		return GL_RGBA16F;
 762.425 +	default:
 762.426 +		break;
 762.427 +	}
 762.428 +	return 0;
 762.429 +}
 762.430 +
 762.431 +// ---- TextureSet ----
 762.432 +static void destroy_texture(Texture *tex)
 762.433 +{
 762.434 +	delete tex;
 762.435 +}
 762.436 +
 762.437 +TextureSet::TextureSet()
 762.438 +	: DataSet<Texture*>(load_texture, destroy_texture)
 762.439 +{
 762.440 +}
   763.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   763.2 +++ b/src/texture.h	Sat Feb 01 19:58:19 2014 +0200
   763.3 @@ -0,0 +1,80 @@
   763.4 +#ifndef TEXTURE_H_
   763.5 +#define TEXTURE_H_
   763.6 +
   763.7 +#include "dataset.h"
   763.8 +#include "opengl.h"
   763.9 +
  763.10 +class Image;
  763.11 +
  763.12 +class Texture {
  763.13 +protected:
  763.14 +	unsigned int id;
  763.15 +	unsigned int target;
  763.16 +	unsigned int texfmt;
  763.17 +	int sz[3];
  763.18 +
  763.19 +	Texture(const Texture &tex) {}
  763.20 +	Texture &operator =(const Texture &tex) { return *this; }
  763.21 +
  763.22 +public:
  763.23 +	Texture();
  763.24 +	virtual ~Texture();
  763.25 +
  763.26 +	void set_wrapping(unsigned int wrap);
  763.27 +	void set_filtering(unsigned int filt);
  763.28 +	void set_filtering(unsigned int min_filt, unsigned int mag_filt);
  763.29 +
  763.30 +	unsigned int get_format() const;
  763.31 +
  763.32 +	virtual int get_size(int dim) const;
  763.33 +
  763.34 +	virtual void create(int xsz, int ysz, unsigned int ifmt = GL_RGBA) = 0;
  763.35 +	virtual void set_image(const Image &img, int idx = 0) = 0;
  763.36 +
  763.37 +	virtual bool load(const char *fname) = 0;
  763.38 +	virtual bool save(const char *fname) const = 0;
  763.39 +
  763.40 +	virtual unsigned int get_id() const;
  763.41 +
  763.42 +	virtual void bind(int tex_unit = 0) const;
  763.43 +};
  763.44 +
  763.45 +class Texture2D : public Texture {
  763.46 +public:
  763.47 +	Texture2D();
  763.48 +
  763.49 +	virtual void create(int xsz, int ysz, unsigned int ifmt = GL_RGBA);
  763.50 +	virtual void set_image(const Image &img, int idx = 0);
  763.51 +
  763.52 +	virtual bool load(const char *fname);
  763.53 +	virtual bool save(const char *fname) const;
  763.54 +};
  763.55 +
  763.56 +class TextureCube : public Texture {
  763.57 +private:
  763.58 +	bool load_multi(const Image &img, const float *xoffsets, const float *yoffsets, float sz,
  763.59 +		unsigned int rotmask = 0);
  763.60 +
  763.61 +public:
  763.62 +	TextureCube();
  763.63 +
  763.64 +	virtual void create(int xsz, int ysz, unsigned int ifmt = GL_RGBA);
  763.65 +	virtual void set_image(const Image &img, int idx = 0);
  763.66 +
  763.67 +	virtual bool load(const char *fname);
  763.68 +	virtual bool save(const char *fname) const;
  763.69 +};
  763.70 +
  763.71 +void set_texture(Texture *tex, int tunit = 0);
  763.72 +
  763.73 +/** loads a texture autodetecting whether it's a 2D texture or
  763.74 + * cubemap and creating the correct Texture subclass instance.
  763.75 + */
  763.76 +Texture *load_texture(const char *fname);
  763.77 +
  763.78 +class TextureSet : public DataSet<Texture*> {
  763.79 +public:
  763.80 +	TextureSet();
  763.81 +};
  763.82 +
  763.83 +#endif	// TEXTURE_H_
   764.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   764.2 +++ b/src/timer.cc	Sat Feb 01 19:58:19 2014 +0200
   764.3 @@ -0,0 +1,118 @@
   764.4 +#include "timer.h"
   764.5 +
   764.6 +#if defined(__APPLE__) && !defined(__unix__)
   764.7 +#define __unix__
   764.8 +#endif
   764.9 +
  764.10 +#ifdef __unix__
  764.11 +#include <time.h>
  764.12 +#include <unistd.h>
  764.13 +#include <sys/time.h>
  764.14 +
  764.15 +#ifdef CLOCK_MONOTONIC
  764.16 +unsigned long get_time_msec(void)
  764.17 +{
  764.18 +	struct timespec ts;
  764.19 +	static struct timespec ts0;
  764.20 +
  764.21 +	clock_gettime(CLOCK_MONOTONIC, &ts);
  764.22 +	if(ts0.tv_sec == 0 && ts0.tv_nsec == 0) {
  764.23 +		ts0 = ts;
  764.24 +		return 0;
  764.25 +	}
  764.26 +	return (ts.tv_sec - ts0.tv_sec) * 1000 + (ts.tv_nsec - ts0.tv_nsec) / 1000000;
  764.27 +}
  764.28 +#else	/* no fancy POSIX clocks, fallback to good'ol gettimeofday */
  764.29 +unsigned long get_time_msec(void)
  764.30 +{
  764.31 +	struct timeval tv;
  764.32 +	static struct timeval tv0;
  764.33 +
  764.34 +	gettimeofday(&tv, 0);
  764.35 +	if(tv0.tv_sec == 0 && tv0.tv_usec == 0) {
  764.36 +		tv0 = tv;
  764.37 +		return 0;
  764.38 +	}
  764.39 +	return (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000;
  764.40 +}
  764.41 +#endif	/* !posix clock */
  764.42 +
  764.43 +void sleep_msec(unsigned long msec)
  764.44 +{
  764.45 +	usleep(msec * 1000);
  764.46 +}
  764.47 +#endif
  764.48 +
  764.49 +#ifdef WIN32
  764.50 +#include <windows.h>
  764.51 +#pragma comment(lib, "winmm.lib")
  764.52 +
  764.53 +unsigned long get_time_msec(void)
  764.54 +{
  764.55 +	return timeGetTime();
  764.56 +}
  764.57 +
  764.58 +void sleep_msec(unsigned long msec)
  764.59 +{
  764.60 +	Sleep(msec);
  764.61 +}
  764.62 +#endif
  764.63 +
  764.64 +double get_time_sec(void)
  764.65 +{
  764.66 +	return get_time_msec() / 1000.0f;
  764.67 +}
  764.68 +
  764.69 +void sleep_sec(double sec)
  764.70 +{
  764.71 +	if(sec > 0.0f) {
  764.72 +		sleep_msec(sec * 1000.0f);
  764.73 +	}
  764.74 +}
  764.75 +
  764.76 +
  764.77 +Timer::Timer()
  764.78 +{
  764.79 +	reset();
  764.80 +}
  764.81 +
  764.82 +void Timer::reset()
  764.83 +{
  764.84 +	pause_time = 0;
  764.85 +	start_time = get_time_msec();
  764.86 +}
  764.87 +
  764.88 +void Timer::start()
  764.89 +{
  764.90 +	if(!is_running()) {
  764.91 +		// resuming
  764.92 +		start_time += get_time_msec() - pause_time;
  764.93 +		pause_time = 0;
  764.94 +	}
  764.95 +}
  764.96 +
  764.97 +void Timer::stop()
  764.98 +{
  764.99 +	if(is_running()) {
 764.100 +		pause_time = get_time_msec();
 764.101 +	}
 764.102 +}
 764.103 +
 764.104 +bool Timer::is_running() const
 764.105 +{
 764.106 +	return pause_time == 0;
 764.107 +}
 764.108 +
 764.109 +unsigned long Timer::get_msec() const
 764.110 +{
 764.111 +	if(!is_running()) {
 764.112 +		// in paused state...
 764.113 +		return pause_time - start_time;
 764.114 +	}
 764.115 +	return get_time_msec() - start_time;
 764.116 +}
 764.117 +
 764.118 +double Timer::get_sec() const
 764.119 +{
 764.120 +	return (double)get_msec() / 1000.0;
 764.121 +}
   765.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   765.2 +++ b/src/timer.h	Sat Feb 01 19:58:19 2014 +0200
   765.3 @@ -0,0 +1,29 @@
   765.4 +#ifndef TIMER_H_
   765.5 +#define TIMER_H_
   765.6 +
   765.7 +unsigned long get_time_msec(void);
   765.8 +void sleep_msec(unsigned long msec);
   765.9 +
  765.10 +double get_time_sec(void);
  765.11 +void sleep_sec(double sec);
  765.12 +
  765.13 +
  765.14 +class Timer {
  765.15 +private:
  765.16 +	unsigned long start_time, pause_time;
  765.17 +
  765.18 +public:
  765.19 +	Timer();
  765.20 +
  765.21 +	void reset();
  765.22 +
  765.23 +	void start();
  765.24 +	void stop();
  765.25 +
  765.26 +	bool is_running() const;
  765.27 +
  765.28 +	unsigned long get_msec() const;
  765.29 +	double get_sec() const;
  765.30 +};
  765.31 +
  765.32 +#endif	// TIMER_H_
   766.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   766.2 +++ b/src/unistate.cc	Sat Feb 01 19:58:19 2014 +0200
   766.3 @@ -0,0 +1,678 @@
   766.4 +#include <map>
   766.5 +#include <vector>
   766.6 +#include "unistate.h"
   766.7 +#include "shader.h"
   766.8 +#include "logger.h"
   766.9 +
  766.10 +struct StateItem {
  766.11 +	StType type;
  766.12 +
  766.13 +	union {
  766.14 +		int ival[4];
  766.15 +		float fval[16];
  766.16 +	};
  766.17 +	int transpose;	// for matrices
  766.18 +};
  766.19 +
  766.20 +static const char *typestr(StType type);
  766.21 +static int type_nelem(StType type);
  766.22 +static StType float_type(int elem);
  766.23 +static StType int_type(int elem);
  766.24 +
  766.25 +std::vector<StateItem> state;
  766.26 +std::map<std::string, int> stateidx;
  766.27 +
  766.28 +
  766.29 +int add_unistate(const char *name, StType type)
  766.30 +{
  766.31 +	static const float ident3[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
  766.32 +	static const float ident4[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
  766.33 +
  766.34 +	if(stateidx.find(name) != stateidx.end()) {
  766.35 +		return stateidx[name];
  766.36 +	}
  766.37 +
  766.38 +	StateItem sitem;
  766.39 +	memset(&sitem, 0, sizeof sitem);
  766.40 +	sitem.type = type;
  766.41 +
  766.42 +	// initialize to a reasonable default value
  766.43 +	switch(type) {
  766.44 +	case ST_MATRIX3:
  766.45 +		memcpy(sitem.fval, ident3, sizeof ident3);
  766.46 +		break;
  766.47 +
  766.48 +	case ST_MATRIX4:
  766.49 +		memcpy(sitem.fval, ident4, sizeof ident4);
  766.50 +		break;
  766.51 +
  766.52 +	default:
  766.53 +		break;	// in all other cases leave it zero (see memset above)
  766.54 +	}
  766.55 +
  766.56 +	int sidx = state.size();
  766.57 +	state.push_back(sitem);
  766.58 +	stateidx[name] = sidx;
  766.59 +
  766.60 +	debug_log("adding uniform state [%d]: %s %s\n", sidx, typestr(sitem.type), name);
  766.61 +
  766.62 +	return sidx;
  766.63 +}
  766.64 +
  766.65 +int get_unistate_index(const char *name)
  766.66 +{
  766.67 +	std::map<std::string, int>::const_iterator it = stateidx.find(name);
  766.68 +	if(it != stateidx.end()) {
  766.69 +		return it->second;
  766.70 +	}
  766.71 +	return -1;
  766.72 +}
  766.73 +
  766.74 +#define CHECK_INDEX(i)	\
  766.75 +	if(i < 0 || i >= (int)state.size()) return
  766.76 +
  766.77 +#define CHECK_COUNT(count, type) \
  766.78 +	do { \
  766.79 +		int max_elem = type_nelem(type); \
  766.80 +		if(!(count) || (count) > max_elem) { \
  766.81 +			count = max_elem; \
  766.82 +		} \
  766.83 +	} while(0)
  766.84 +
  766.85 +void set_unistate(int sidx, const int *val, int count)
  766.86 +{
  766.87 +	CHECK_INDEX(sidx);
  766.88 +	CHECK_COUNT(count, state[sidx].type);
  766.89 +
  766.90 +	memcpy(state[sidx].ival, val, count * sizeof *state[sidx].ival);
  766.91 +}
  766.92 +
  766.93 +void set_unistate(int sidx, const float *val, int count)
  766.94 +{
  766.95 +	CHECK_INDEX(sidx);
  766.96 +	CHECK_COUNT(count, state[sidx].type);
  766.97 +
  766.98 +	memcpy(state[sidx].fval, val, count * sizeof *state[sidx].fval);
  766.99 +	state[sidx].transpose = 0;
 766.100 +}
 766.101 +
 766.102 +void get_unistate(int sidx, int *val, int count)
 766.103 +{
 766.104 +	CHECK_INDEX(sidx);
 766.105 +	CHECK_COUNT(count, state[sidx].type);
 766.106 +
 766.107 +	memcpy(val, state[sidx].ival, count * sizeof *val);
 766.108 +}
 766.109 +
 766.110 +void get_unistate(int sidx, float *val, int count)
 766.111 +{
 766.112 +	CHECK_INDEX(sidx);
 766.113 +	CHECK_COUNT(count, state[sidx].type);
 766.114 +
 766.115 +	memcpy(val, state[sidx].fval, count * sizeof *val);
 766.116 +}
 766.117 +
 766.118 +void set_unistate(int sidx, int val)
 766.119 +{
 766.120 +	set_unistate(sidx, &val, 1);
 766.121 +}
 766.122 +
 766.123 +void set_unistate(int sidx, float val)
 766.124 +{
 766.125 +	set_unistate(sidx, &val, 1);
 766.126 +}
 766.127 +
 766.128 +void set_unistate(int sidx, const Vector2 &vec)
 766.129 +{
 766.130 +	set_unistate(sidx, &vec.x, 2);
 766.131 +}
 766.132 +
 766.133 +void set_unistate(int sidx, const Vector3 &vec)
 766.134 +{
 766.135 +	set_unistate(sidx, &vec.x, 3);
 766.136 +}
 766.137 +
 766.138 +void set_unistate(int sidx, const Vector4 &vec)
 766.139 +{
 766.140 +	set_unistate(sidx, &vec.x, 4);
 766.141 +}
 766.142 +
 766.143 +void set_unistate(int sidx, const Matrix3x3 &mat)
 766.144 +{
 766.145 +	set_unistate(sidx, mat[0], 9);
 766.146 +	state[sidx].transpose = 1;
 766.147 +}
 766.148 +
 766.149 +void set_unistate(int sidx, const Matrix4x4 &mat)
 766.150 +{
 766.151 +	set_unistate(sidx, mat[0], 16);
 766.152 +	state[sidx].transpose = 1;
 766.153 +}
 766.154 +
 766.155 +
 766.156 +int set_unistate(const char *name, int *val, int count)
 766.157 +{
 766.158 +	int sidx = get_unistate_index(name);
 766.159 +	if(sidx < 0) {
 766.160 +		StType type = int_type(count);
 766.161 +		if(type == ST_UNKNOWN) {
 766.162 +			error_log("invalid element count (%d) while setting previously unknown unistate item \"%s\"\n",
 766.163 +					count, name);
 766.164 +			return -1;
 766.165 +		}
 766.166 +
 766.167 +		sidx = add_unistate(name, type);
 766.168 +	}
 766.169 +	set_unistate(sidx, val);
 766.170 +	return sidx;
 766.171 +}
 766.172 +
 766.173 +int set_unistate(const char *name, float *val, int count)
 766.174 +{
 766.175 +	int sidx = get_unistate_index(name);
 766.176 +	if(sidx < 0) {
 766.177 +		StType type = float_type(count);
 766.178 +		if(type == ST_UNKNOWN) {
 766.179 +			error_log("invalid element count (%d) while setting previously unknown unistate item \"%s\"\n",
 766.180 +					count, name);
 766.181 +			return -1;
 766.182 +		}
 766.183 +
 766.184 +		sidx = add_unistate(name, type);
 766.185 +	}
 766.186 +	set_unistate(sidx, val);
 766.187 +	return sidx;
 766.188 +}
 766.189 +
 766.190 +int set_unistate(const char *name, int val)
 766.191 +{
 766.192 +	int sidx = get_unistate_index(name);
 766.193 +	if(sidx < 0) {
 766.194 +		sidx = add_unistate(name, ST_INT);
 766.195 +	}
 766.196 +	set_unistate(sidx, val);
 766.197 +	return sidx;
 766.198 +}
 766.199 +
 766.200 +int set_unistate(const char *name, float val)
 766.201 +{
 766.202 +	int sidx = get_unistate_index(name);
 766.203 +	if(sidx < 0) {
 766.204 +		sidx = add_unistate(name, ST_FLOAT);
 766.205 +	}
 766.206 +	set_unistate(sidx, val);
 766.207 +	return sidx;
 766.208 +}
 766.209 +
 766.210 +int set_unistate(const char *name, const Vector2 &vec)
 766.211 +{
 766.212 +	int sidx = get_unistate_index(name);
 766.213 +	if(sidx < 0) {
 766.214 +		sidx = add_unistate(name, ST_FLOAT2);
 766.215 +	}
 766.216 +	set_unistate(sidx, vec);
 766.217 +	return sidx;
 766.218 +}
 766.219 +
 766.220 +int set_unistate(const char *name, const Vector3 &vec)
 766.221 +{
 766.222 +	int sidx = get_unistate_index(name);
 766.223 +	if(sidx < 0) {
 766.224 +		sidx = add_unistate(name, ST_FLOAT3);
 766.225 +	}
 766.226 +	set_unistate(sidx, vec);
 766.227 +	return sidx;
 766.228 +}
 766.229 +
 766.230 +int set_unistate(const char *name, const Vector4 &vec)
 766.231 +{
 766.232 +	int sidx = get_unistate_index(name);
 766.233 +	if(sidx < 0) {
 766.234 +		sidx = add_unistate(name, ST_FLOAT4);
 766.235 +	}
 766.236 +	set_unistate(sidx, vec);
 766.237 +	return sidx;
 766.238 +}
 766.239 +
 766.240 +int set_unistate(const char *name, const Matrix3x3 &mat)
 766.241 +{
 766.242 +	int sidx = get_unistate_index(name);
 766.243 +	if(sidx < 0) {
 766.244 +		sidx = add_unistate(name, ST_MATRIX3);
 766.245 +	}
 766.246 +	set_unistate(sidx, mat);
 766.247 +	return sidx;
 766.248 +}
 766.249 +
 766.250 +int set_unistate(const char *name, const Matrix4x4 &mat)
 766.251 +{
 766.252 +	int sidx = get_unistate_index(name);
 766.253 +	if(sidx < 0) {
 766.254 +		sidx = add_unistate(name, ST_MATRIX4);
 766.255 +	}
 766.256 +	set_unistate(sidx, mat);
 766.257 +	return sidx;
 766.258 +}
 766.259 +
 766.260 +
 766.261 +int get_unistate_int(int sidx)
 766.262 +{
 766.263 +	int val = 0;
 766.264 +	get_unistate(sidx, &val, 1);
 766.265 +	return val;
 766.266 +}
 766.267 +
 766.268 +float get_unistate_float(int sidx)
 766.269 +{
 766.270 +	float val = 0.0f;
 766.271 +	get_unistate(sidx, &val, 1);
 766.272 +	return val;
 766.273 +}
 766.274 +
 766.275 +Vector2 get_unistate_vec2(int sidx)
 766.276 +{
 766.277 +	float val[2] = {0.0f, 0.0f};
 766.278 +	get_unistate(sidx, val, 2);
 766.279 +	return Vector2(val[0], val[1]);
 766.280 +}
 766.281 +
 766.282 +Vector3 get_unistate_vec3(int sidx)
 766.283 +{
 766.284 +	float val[3] = {0.0f, 0.0f, 0.0f};
 766.285 +	get_unistate(sidx, val, 3);
 766.286 +	return Vector3(val[0], val[1], val[2]);
 766.287 +}
 766.288 +
 766.289 +Vector4 get_unistate_vec4(int sidx)
 766.290 +{
 766.291 +	float val[4] = {0.0f, 0.0f, 0.0f};
 766.292 +	get_unistate(sidx, val, 4);
 766.293 +	return Vector4(val[0], val[1], val[2], val[3]);
 766.294 +}
 766.295 +
 766.296 +Matrix3x3 get_unistate_mat3(int sidx)
 766.297 +{
 766.298 +	Matrix3x3 res;
 766.299 +	get_unistate(sidx, res.m[0], 9);
 766.300 +	return res;
 766.301 +}
 766.302 +
 766.303 +Matrix4x4 get_unistate_mat4(int sidx)
 766.304 +{
 766.305 +	Matrix4x4 res;
 766.306 +	get_unistate(sidx, res.m[0], 16);
 766.307 +	return res;
 766.308 +}
 766.309 +
 766.310 +
 766.311 +int get_unistate_int(const char *name)
 766.312 +{
 766.313 +	int sidx = get_unistate_index(name);
 766.314 +	if(sidx == -1) {
 766.315 +		return 0;
 766.316 +	}
 766.317 +	return get_unistate_int(sidx);
 766.318 +}
 766.319 +
 766.320 +float get_unistate_float(const char *name)
 766.321 +{
 766.322 +	int sidx = get_unistate_index(name);
 766.323 +	if(sidx == -1) {
 766.324 +		return 0.0f;
 766.325 +	}
 766.326 +	return get_unistate_float(sidx);
 766.327 +}
 766.328 +
 766.329 +Vector2 get_unistate_vec2(const char *name)
 766.330 +{
 766.331 +	int sidx = get_unistate_index(name);
 766.332 +	if(sidx == -1) {
 766.333 +		return Vector2();
 766.334 +	}
 766.335 +	return get_unistate_vec2(sidx);
 766.336 +}
 766.337 +
 766.338 +Vector3 get_unistate_vec3(const char *name)
 766.339 +{
 766.340 +	int sidx = get_unistate_index(name);
 766.341 +	if(sidx == -1) {
 766.342 +		return Vector3();
 766.343 +	}
 766.344 +	return get_unistate_vec3(sidx);
 766.345 +}
 766.346 +
 766.347 +Vector4 get_unistate_vec4(const char *name)
 766.348 +{
 766.349 +	int sidx = get_unistate_index(name);
 766.350 +	if(sidx == -1) {
 766.351 +		return Vector4();
 766.352 +	}
 766.353 +	return get_unistate_vec4(sidx);
 766.354 +}
 766.355 +
 766.356 +Matrix3x3 get_unistate_mat3(const char *name)
 766.357 +{
 766.358 +	int sidx = get_unistate_index(name);
 766.359 +	if(sidx == -1) {
 766.360 +		return Matrix3x3();
 766.361 +	}
 766.362 +	return get_unistate_mat3(sidx);
 766.363 +}
 766.364 +
 766.365 +Matrix4x4 get_unistate_mat4(const char *name)
 766.366 +{
 766.367 +	int sidx = get_unistate_index(name);
 766.368 +	if(sidx == -1) {
 766.369 +		return Matrix4x4();
 766.370 +	}
 766.371 +	return get_unistate_mat4(sidx);
 766.372 +}
 766.373 +
 766.374 +
 766.375 +void setup_unistate(const ShaderProg *sdr)
 766.376 +{
 766.377 +	if(!sdr) {
 766.378 +		if(!(sdr = ShaderProg::current)) {
 766.379 +			return;
 766.380 +		}
 766.381 +	}
 766.382 +
 766.383 +	sdr->setup_state_uniforms();
 766.384 +}
 766.385 +
 766.386 +bool setup_unistate(int sidx, const ShaderProg *sdr, int loc)
 766.387 +{
 766.388 +	if(loc < 0 || sidx < 0 || sidx >= (int)state.size()) {
 766.389 +		return false;
 766.390 +	}
 766.391 +
 766.392 +	CHECKGLERR;
 766.393 +	glUseProgram(sdr->get_id());
 766.394 +	CHECKGLERR;
 766.395 +
 766.396 +	switch(state[sidx].type) {
 766.397 +	case ST_INT:
 766.398 +		glUniform1iv(loc, 1, state[sidx].ival);
 766.399 +		break;
 766.400 +	case ST_INT2:
 766.401 +		glUniform2iv(loc, 1, state[sidx].ival);
 766.402 +		break;
 766.403 +	case ST_INT3:
 766.404 +		glUniform3iv(loc, 1, state[sidx].ival);
 766.405 +		break;
 766.406 +	case ST_INT4:
 766.407 +		glUniform4iv(loc, 1, state[sidx].ival);
 766.408 +		break;
 766.409 +
 766.410 +	case ST_FLOAT:
 766.411 +		glUniform1fv(loc, 1, state[sidx].fval);
 766.412 +		break;
 766.413 +	case ST_FLOAT2:
 766.414 +		glUniform2fv(loc, 1, state[sidx].fval);
 766.415 +		break;
 766.416 +	case ST_FLOAT3:
 766.417 +		glUniform3fv(loc, 1, state[sidx].fval);
 766.418 +		break;
 766.419 +	case ST_FLOAT4:
 766.420 +		glUniform4fv(loc, 1, state[sidx].fval);
 766.421 +		break;
 766.422 +
 766.423 +	case ST_MATRIX3:
 766.424 +#ifdef GL_ES_VERSION_2_0
 766.425 +		{
 766.426 +			float tmat[9], *ptr = tmat;
 766.427 +			for(int i=0; i<3; i++) {
 766.428 +				for(int j=0; j<3; j++) {
 766.429 +					*ptr++ = state[sidx].fval[j * 3 + i];
 766.430 +				}
 766.431 +			}
 766.432 +			glUniformMatrix3fv(loc, 1, GL_FALSE, tmat);
 766.433 +		}
 766.434 +#else
 766.435 +		glUniformMatrix3fv(loc, 1, state[sidx].transpose, state[sidx].fval);
 766.436 +#endif
 766.437 +		break;
 766.438 +
 766.439 +	case ST_MATRIX4:
 766.440 +#ifdef GL_ES_VERSION_2_0
 766.441 +		{
 766.442 +			float tmat[16], *ptr = tmat;
 766.443 +			for(int i=0; i<4; i++) {
 766.444 +				for(int j=0; j<4; j++) {
 766.445 +					*ptr++ = state[sidx].fval[j * 4 + i];
 766.446 +				}
 766.447 +			}
 766.448 +			glUniformMatrix4fv(loc, 1, GL_FALSE, tmat);
 766.449 +		}
 766.450 +#else
 766.451 +		glUniformMatrix4fv(loc, 1, state[sidx].transpose, state[sidx].fval);
 766.452 +#endif
 766.453 +		break;
 766.454 +
 766.455 +	default:
 766.456 +		return false;
 766.457 +	}
 766.458 +
 766.459 +	CHECKGLERR;
 766.460 +	return true;
 766.461 +}
 766.462 +
 766.463 +bool setup_unistate(const char *name, const ShaderProg *sdr)
 766.464 +{
 766.465 +	int loc = sdr->get_uniform_location(name);
 766.466 +	if(loc == -1) {
 766.467 +		return false;
 766.468 +	}
 766.469 +	return setup_unistate(get_unistate_index(name), sdr, loc);
 766.470 +}
 766.471 +
 766.472 +void set_world_matrix(const Matrix4x4 &mat)
 766.473 +{
 766.474 +	static int sidx = -1, sidx_transp, sidx_mat3;
 766.475 +
 766.476 +	if(sidx == -1) {
 766.477 +		sidx = add_unistate("st_world_matrix", ST_MATRIX4);
 766.478 +		sidx_mat3 = add_unistate("st_world_matrix3", ST_MATRIX3);
 766.479 +		sidx_transp = add_unistate("st_world_matrix_transpose", ST_MATRIX4);
 766.480 +	}
 766.481 +
 766.482 +	set_unistate(sidx, mat);
 766.483 +	set_unistate(sidx_mat3, Matrix3x3(mat));
 766.484 +	set_unistate(sidx_transp, mat[0]);	// by using the float* variant, we unset the transpose flag
 766.485 +}
 766.486 +
 766.487 +void set_view_matrix(const Matrix4x4 &mat)
 766.488 +{
 766.489 +	static int sidx = -1, sidx_transp, sidx_mat3;
 766.490 +
 766.491 +	if(sidx == -1) {
 766.492 +		sidx = add_unistate("st_view_matrix", ST_MATRIX4);
 766.493 +		sidx_mat3 = add_unistate("st_view_matrix3", ST_MATRIX3);
 766.494 +		sidx_transp = add_unistate("st_view_matrix_transpose", ST_MATRIX4);
 766.495 +	}
 766.496 +
 766.497 +	set_unistate(sidx, mat);
 766.498 +	set_unistate(sidx_mat3, Matrix3x3(mat));
 766.499 +	set_unistate(sidx_transp, mat[0]);	// by using the float* variant, we unset the transpose flag
 766.500 +}
 766.501 +
 766.502 +void set_projection_matrix(const Matrix4x4 &mat)
 766.503 +{
 766.504 +	static int sidx = -1;
 766.505 +
 766.506 +	if(sidx == -1) {
 766.507 +		sidx = add_unistate("st_proj_matrix", ST_MATRIX4);
 766.508 +	}
 766.509 +
 766.510 +	set_unistate(sidx, mat);
 766.511 +}
 766.512 +
 766.513 +void set_texture_matrix(const Matrix4x4 &mat)
 766.514 +{
 766.515 +	static int sidx = -1;
 766.516 +
 766.517 +	if(sidx == -1) {
 766.518 +		sidx = add_unistate("st_tex_matrix", ST_MATRIX4);
 766.519 +	}
 766.520 +
 766.521 +	set_unistate(sidx, mat);
 766.522 +}
 766.523 +
 766.524 +Matrix4x4 get_world_matrix()
 766.525 +{
 766.526 +	static int sidx = -1;
 766.527 +
 766.528 +	if(sidx == -1) {
 766.529 +		if((sidx = get_unistate_index("st_world_matrix")) == -1) {
 766.530 +			return Matrix4x4();
 766.531 +		}
 766.532 +	}
 766.533 +	return get_unistate_mat4(sidx);
 766.534 +}
 766.535 +
 766.536 +Matrix4x4 get_view_matrix()
 766.537 +{
 766.538 +	static int sidx = -1;
 766.539 +
 766.540 +	if(sidx == -1) {
 766.541 +		if((sidx = get_unistate_index("st_view_matrix")) == -1) {
 766.542 +			return Matrix4x4();
 766.543 +		}
 766.544 +	}
 766.545 +	return get_unistate_mat4(sidx);
 766.546 +}
 766.547 +
 766.548 +Matrix4x4 get_projection_matrix()
 766.549 +{
 766.550 +	static int sidx = -1;
 766.551 +
 766.552 +	if(sidx == -1) {
 766.553 +		if((sidx = get_unistate_index("st_proj_matrix")) == -1) {
 766.554 +			return Matrix4x4();
 766.555 +		}
 766.556 +	}
 766.557 +	return get_unistate_mat4(sidx);
 766.558 +}
 766.559 +
 766.560 +Matrix4x4 get_texture_matrix()
 766.561 +{
 766.562 +	static int sidx = -1;
 766.563 +
 766.564 +	if(sidx == -1) {
 766.565 +		if((sidx = get_unistate_index("st_tex_matrix")) == -1) {
 766.566 +			return Matrix4x4();
 766.567 +		}
 766.568 +	}
 766.569 +	return get_unistate_mat4(sidx);
 766.570 +}
 766.571 +
 766.572 +void setup_gl_matrices()
 766.573 +{
 766.574 +#ifdef USE_OLDGL
 766.575 +	Matrix4x4 modelview = get_world_matrix() * get_view_matrix();
 766.576 +	Matrix4x4 proj = get_projection_matrix();
 766.577 +	Matrix4x4 tex = get_texture_matrix();
 766.578 +
 766.579 +	glMatrixMode(GL_TEXTURE);
 766.580 +	glLoadTransposeMatrixf(tex[0]);
 766.581 +	glMatrixMode(GL_PROJECTION);
 766.582 +	glLoadTransposeMatrixf(proj[0]);
 766.583 +	glMatrixMode(GL_MODELVIEW);
 766.584 +	glLoadTransposeMatrixf(modelview[0]);
 766.585 +#endif
 766.586 +}
 766.587 +
 766.588 +static const char *typestr(StType type)
 766.589 +{
 766.590 +	switch(type) {
 766.591 +	case ST_INT:
 766.592 +		return "int";
 766.593 +	case ST_INT2:
 766.594 +		return "ivec2";
 766.595 +	case ST_INT3:
 766.596 +		return "ivec3";
 766.597 +	case ST_INT4:
 766.598 +		return "ivec4";
 766.599 +	case ST_FLOAT:
 766.600 +		return "float";
 766.601 +	case ST_FLOAT2:
 766.602 +		return "vec2";
 766.603 +	case ST_FLOAT3:
 766.604 +		return "vec3";
 766.605 +	case ST_FLOAT4:
 766.606 +		return "vec4";
 766.607 +	case ST_MATRIX3:
 766.608 +		return "mat3";
 766.609 +	case ST_MATRIX4:
 766.610 +		return "mat4";
 766.611 +
 766.612 +	default:
 766.613 +		break;
 766.614 +	}
 766.615 +	return "<unknown>";
 766.616 +}
 766.617 +
 766.618 +static int type_nelem(StType type)
 766.619 +{
 766.620 +	switch(type) {
 766.621 +	case ST_INT:
 766.622 +	case ST_FLOAT:
 766.623 +		return 1;
 766.624 +	case ST_INT2:
 766.625 +	case ST_FLOAT2:
 766.626 +		return 2;
 766.627 +	case ST_INT3:
 766.628 +	case ST_FLOAT3:
 766.629 +		return 3;
 766.630 +	case ST_INT4:
 766.631 +	case ST_FLOAT4:
 766.632 +		return 4;
 766.633 +	case ST_MATRIX3:
 766.634 +		return 9;
 766.635 +	case ST_MATRIX4:
 766.636 +		return 16;
 766.637 +
 766.638 +	default:
 766.639 +		break;
 766.640 +	}
 766.641 +
 766.642 +	return 0;
 766.643 +}
 766.644 +
 766.645 +static StType float_type(int elem)
 766.646 +{
 766.647 +	switch(elem) {
 766.648 +	case 1:
 766.649 +		return ST_FLOAT;
 766.650 +	case 2:
 766.651 +		return ST_FLOAT2;
 766.652 +	case 3:
 766.653 +		return ST_FLOAT3;
 766.654 +	case 4:
 766.655 +		return ST_FLOAT4;
 766.656 +	case 9:
 766.657 +		return ST_MATRIX3;
 766.658 +	case 16:
 766.659 +		return ST_MATRIX4;
 766.660 +	default:
 766.661 +		break;
 766.662 +	}
 766.663 +	return ST_UNKNOWN;
 766.664 +}
 766.665 +
 766.666 +static StType int_type(int elem)
 766.667 +{
 766.668 +	switch(elem) {
 766.669 +	case 1:
 766.670 +		return ST_INT;
 766.671 +	case 2:
 766.672 +		return ST_INT2;
 766.673 +	case 3:
 766.674 +		return ST_INT3;
 766.675 +	case 4:
 766.676 +		return ST_INT4;
 766.677 +	default:
 766.678 +		break;
 766.679 +	}
 766.680 +	return ST_UNKNOWN;
 766.681 +}
   767.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   767.2 +++ b/src/unistate.h	Sat Feb 01 19:58:19 2014 +0200
   767.3 @@ -0,0 +1,104 @@
   767.4 +#ifndef UNISTATE_H_
   767.5 +#define UNISTATE_H_
   767.6 +
   767.7 +#include "vmath/vmath.h"
   767.8 +
   767.9 +class ShaderProg;
  767.10 +
  767.11 +enum StType {
  767.12 +	ST_UNKNOWN,
  767.13 +	ST_INT,	ST_INT2, ST_INT3, ST_INT4,
  767.14 +	ST_FLOAT, ST_FLOAT2, ST_FLOAT3, ST_FLOAT4,
  767.15 +	ST_MATRIX3, ST_MATRIX4
  767.16 +};
  767.17 +
  767.18 +int add_unistate(const char *name, StType type);
  767.19 +int get_unistate_index(const char *name);
  767.20 +
  767.21 +/** set the uniform state identified by \param sidx by copying
  767.22 + * a number of elements from \param val. If \param count is 0
  767.23 + * then it's automatically set based on the type of this state item.
  767.24 + * @{ */
  767.25 +void set_unistate(int sidx, const int *val, int count = 0);
  767.26 +void set_unistate(int sidx, const float *val, int count = 0);
  767.27 +/// @}
  767.28 +
  767.29 +/** get the uniform state identified by \param sidx by copying
  767.30 + * a number of elements into \param val. If \param count is 0
  767.31 + * then it's automatically set based on the type of this state item.
  767.32 + * @{ */
  767.33 +void get_unistate(int sidx, int *val, int count = 0);
  767.34 +void get_unistate(int sidx, float *val, int count = 0);
  767.35 +/// @}
  767.36 +
  767.37 +/// convenience versions of set_unistate @{
  767.38 +void set_unistate(int sidx, int val);
  767.39 +void set_unistate(int sidx, float val);
  767.40 +void set_unistate(int sidx, const Vector2 &vec);
  767.41 +void set_unistate(int sidx, const Vector3 &vec);
  767.42 +void set_unistate(int sidx, const Vector4 &vec);
  767.43 +void set_unistate(int sidx, const Matrix3x3 &mat);
  767.44 +void set_unistate(int sidx, const Matrix4x4 &mat);
  767.45 +/// @}
  767.46 +
  767.47 +/** convenience functions for setting the uniform state by name.
  767.48 + * if the name cannot be found in the current set of uniform state
  767.49 + * items, a new one is created with a type derived from the variant
  767.50 + * of the function that was called (which might not be what you want).
  767.51 + * The index of the state item is returned.
  767.52 + * @{ */
  767.53 +int set_unistate(const char *name, int *val, int count = 0);
  767.54 +int set_unistate(const char *name, float *val, int count = 0);
  767.55 +int set_unistate(const char *name, int val);
  767.56 +int set_unistate(const char *name, float val);
  767.57 +int set_unistate(const char *name, const Vector2 &vec);
  767.58 +int set_unistate(const char *name, const Vector3 &vec);
  767.59 +int set_unistate(const char *name, const Vector4 &vec);
  767.60 +int set_unistate(const char *name, const Matrix3x3 &mat);
  767.61 +int set_unistate(const char *name, const Matrix4x4 &mat);
  767.62 +/// @}
  767.63 +
  767.64 +/// convenience versions of get_unistate @{
  767.65 +int get_unistate_int(int sidx);
  767.66 +float get_unistate_float(int sidx);
  767.67 +Vector2 get_unistate_vec2(int sidx);
  767.68 +Vector3 get_unistate_vec3(int sidx);
  767.69 +Vector4 get_unistate_vec4(int sidx);
  767.70 +Matrix3x3 get_unistate_mat3(int sidx);
  767.71 +Matrix4x4 get_unistate_mat4(int sidx);
  767.72 +/// @}
  767.73 +
  767.74 +/// convenience versions of get_unistate for getting the uniform state by name @{
  767.75 +int get_unistate_int(const char *name);
  767.76 +float get_unistate_float(const char *name);
  767.77 +Vector2 get_unistate_vec2(const char *name);
  767.78 +Vector3 get_unistate_vec3(const char *name);
  767.79 +Vector4 get_unistate_vec4(const char *name);
  767.80 +Matrix3x3 get_unistate_mat3(const char *name);
  767.81 +Matrix4x4 get_unistate_mat4(const char *name);
  767.82 +/// @}
  767.83 +
  767.84 +/** Prepare for rendering by setting up all the state uniforms in the shader sdr.
  767.85 + * If sdr is null, then use the "current" shader as per ShaderProg::current
  767.86 + */
  767.87 +void setup_unistate(const ShaderProg *sdr = 0);
  767.88 +
  767.89 +bool setup_unistate(int sidx, const ShaderProg *sdr, int loc);
  767.90 +bool setup_unistate(const char *name, const ShaderProg *sdr);
  767.91 +
  767.92 +// special functions for setting the rendering pipeline matrices
  767.93 +void set_world_matrix(const Matrix4x4 &mat);
  767.94 +void set_view_matrix(const Matrix4x4 &mat);
  767.95 +void set_projection_matrix(const Matrix4x4 &mat);
  767.96 +void set_texture_matrix(const Matrix4x4 &mat);
  767.97 +
  767.98 +Matrix4x4 get_world_matrix();
  767.99 +Matrix4x4 get_view_matrix();
 767.100 +Matrix4x4 get_projection_matrix();
 767.101 +Matrix4x4 get_texture_matrix();
 767.102 +
 767.103 +void setup_gl_matrices();	// this shouldn't be needed in the final code
 767.104 +
 767.105 +// TODO should do a matrix stack at some point ...
 767.106 +
 767.107 +#endif	// UNISTATE_H_
   768.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   768.2 +++ b/src/vccompat/stdint.h	Sat Feb 01 19:58:19 2014 +0200
   768.3 @@ -0,0 +1,15 @@
   768.4 +#ifndef MSVC_COMPAT_STDINT_H_
   768.5 +#define MSVC_COMPAT_STDINT_H_
   768.6 +
   768.7 +#ifdef _MSC_VER
   768.8 +typedef __int8 int8_t;
   768.9 +typedef unsigned __int8 uint8_t;
  768.10 +typedef __int16 int16_t;
  768.11 +typedef unsigned __int16 uint16_t;
  768.12 +typedef __int32 int32_t;
  768.13 +typedef unsigned __int32 uint32_t;
  768.14 +typedef __int64 int64_t;
  768.15 +typedef unsigned __int64 uint64_t;
  768.16 +#endif
  768.17 +
  768.18 +#endif	/* MSVC_COMPAT_STDINT_H_ */
   769.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   769.2 +++ b/src/xform_node.cc	Sat Feb 01 19:58:19 2014 +0200
   769.3 @@ -0,0 +1,442 @@
   769.4 +#include <assert.h>
   769.5 +#include <algorithm>
   769.6 +#include "xform_node.h"
   769.7 +#include "anim/anim.h"
   769.8 +#include "anim/track.h"
   769.9 +
  769.10 +static inline anm_interpolator track_interpolator(Interp in);
  769.11 +static inline anm_extrapolator track_extrapolator(Extrap ex);
  769.12 +
  769.13 +XFormNode::XFormNode()
  769.14 +{
  769.15 +	type = NODE_NULL;
  769.16 +
  769.17 +	anm = new anm_node;
  769.18 +	anm_init_node(anm);
  769.19 +
  769.20 +	parent = 0;
  769.21 +}
  769.22 +
  769.23 +XFormNode::~XFormNode()
  769.24 +{
  769.25 +	anm_destroy_node(anm);
  769.26 +	delete anm;
  769.27 +}
  769.28 +
  769.29 +void XFormNode::set_name(const char *name)
  769.30 +{
  769.31 +	anm_set_node_name(anm, name);
  769.32 +}
  769.33 +
  769.34 +const char *XFormNode::get_name() const
  769.35 +{
  769.36 +	return anm_get_node_name(anm);
  769.37 +}
  769.38 +
  769.39 +unsigned int XFormNode::get_type() const
  769.40 +{
  769.41 +	return type;
  769.42 +}
  769.43 +
  769.44 +void XFormNode::set_interpolator(Interp in)
  769.45 +{
  769.46 +	anm_set_interpolator(anm, track_interpolator(in));
  769.47 +	interp = in;
  769.48 +}
  769.49 +
  769.50 +Interp XFormNode::get_interpolator() const
  769.51 +{
  769.52 +	return interp;
  769.53 +}
  769.54 +
  769.55 +void XFormNode::set_extrapolator(Extrap ex)
  769.56 +{
  769.57 +	anm_set_extrapolator(anm, track_extrapolator(ex));
  769.58 +	extrap = ex;
  769.59 +}
  769.60 +
  769.61 +Extrap XFormNode::get_extrapolator() const
  769.62 +{
  769.63 +	return extrap;
  769.64 +}
  769.65 +
  769.66 +void XFormNode::add_child(XFormNode *child)
  769.67 +{
  769.68 +	children.push_back(child);
  769.69 +	anm_link_node(anm, child->anm);
  769.70 +
  769.71 +	child->parent = this;
  769.72 +}
  769.73 +
  769.74 +void XFormNode::remove_child(XFormNode *child)
  769.75 +{
  769.76 +	std::vector<XFormNode*>::iterator it;
  769.77 +	it = std::find(children.begin(), children.end(), child);
  769.78 +	if(it != children.end()) {
  769.79 +		children.erase(it);
  769.80 +		anm_unlink_node(anm, child->anm);
  769.81 +
  769.82 +		if(child->parent == this) {
  769.83 +			child->parent = 0;
  769.84 +		}
  769.85 +	}
  769.86 +}
  769.87 +
  769.88 +int XFormNode::get_children_count() const
  769.89 +{
  769.90 +	return (int)children.size();
  769.91 +}
  769.92 +
  769.93 +XFormNode *XFormNode::get_child(int idx)
  769.94 +{
  769.95 +	if(idx >= 0 && idx < get_children_count()) {
  769.96 +		return children[idx];
  769.97 +	}
  769.98 +	return 0;
  769.99 +}
 769.100 +
 769.101 +const XFormNode *XFormNode::get_child(int idx) const
 769.102 +{
 769.103 +	if(idx >= 0 && idx < get_children_count()) {
 769.104 +		return children[idx];
 769.105 +	}
 769.106 +	return 0;
 769.107 +}
 769.108 +
 769.109 +XFormNode *XFormNode::get_parent()
 769.110 +{
 769.111 +	return parent;
 769.112 +}
 769.113 +
 769.114 +const XFormNode *XFormNode::get_parent() const
 769.115 +{
 769.116 +	return parent;
 769.117 +}
 769.118 +
 769.119 +void XFormNode::clear_xform()
 769.120 +{
 769.121 +	anm_clear(anm);
 769.122 +}
 769.123 +
 769.124 +void XFormNode::set_position(const Vector3 &pos, long tmsec)
 769.125 +{
 769.126 +	anm_set_position(anm, v3_cons(pos.x, pos.y, pos.z), ANM_MSEC2TM(tmsec));
 769.127 +}
 769.128 +
 769.129 +Vector3 XFormNode::get_node_position(long tmsec) const
 769.130 +{
 769.131 +	vec3_t p = anm_get_node_position(anm, ANM_MSEC2TM(tmsec));
 769.132 +	return Vector3(p.x, p.y, p.z);
 769.133 +}
 769.134 +
 769.135 +void XFormNode::set_rotation(const Quaternion &quat, long tmsec)
 769.136 +{
 769.137 +	anm_set_rotation(anm, quat_cons(quat.s, quat.v.x, quat.v.y, quat.v.z), ANM_MSEC2TM(tmsec));
 769.138 +}
 769.139 +
 769.140 +Quaternion XFormNode::get_node_rotation(long tmsec) const
 769.141 +{
 769.142 +	quat_t q = anm_get_node_rotation(anm, ANM_MSEC2TM(tmsec));
 769.143 +	return Quaternion(q.w, q.x, q.y, q.z);
 769.144 +}
 769.145 +
 769.146 +void XFormNode::set_scaling(const Vector3 &pos, long tmsec)
 769.147 +{
 769.148 +	anm_set_scaling(anm, v3_cons(pos.x, pos.y, pos.z), ANM_MSEC2TM(tmsec));
 769.149 +}
 769.150 +
 769.151 +Vector3 XFormNode::get_node_scaling(long tmsec) const
 769.152 +{
 769.153 +	vec3_t s = anm_get_node_scaling(anm, ANM_MSEC2TM(tmsec));
 769.154 +	return Vector3(s.x, s.y, s.z);
 769.155 +}
 769.156 +
 769.157 +// these take hierarchy into account
 769.158 +Vector3 XFormNode::get_position(long tmsec) const
 769.159 +{
 769.160 +	vec3_t v = anm_get_position(anm, ANM_MSEC2TM(tmsec));
 769.161 +	return Vector3(v.x, v.y, v.z);
 769.162 +}
 769.163 +
 769.164 +Quaternion XFormNode::get_rotation(long tmsec) const
 769.165 +{
 769.166 +	quat_t q = anm_get_rotation(anm, tmsec);
 769.167 +	return Quaternion(q.w, q.x, q.y, q.z);
 769.168 +}
 769.169 +
 769.170 +Vector3 XFormNode::get_scaling(long tmsec) const
 769.171 +{
 769.172 +	vec3_t v = anm_get_scaling(anm, ANM_MSEC2TM(tmsec));
 769.173 +	return Vector3(v.x, v.y, v.z);
 769.174 +}
 769.175 +
 769.176 +void XFormNode::set_pivot(const Vector3 &pivot)
 769.177 +{
 769.178 +	anm_set_pivot(anm, v3_cons(pivot.x, pivot.y, pivot.z));
 769.179 +}
 769.180 +
 769.181 +Vector3 XFormNode::get_pivot() const
 769.182 +{
 769.183 +	vec3_t p = anm_get_pivot(anm);
 769.184 +	return Vector3(p.x, p.y, p.z);
 769.185 +}
 769.186 +
 769.187 +void XFormNode::set_local_matrix(const Matrix4x4 &mat)
 769.188 +{
 769.189 +	local_matrix = mat;
 769.190 +}
 769.191 +
 769.192 +const Matrix4x4 &XFormNode::get_local_matrix() const
 769.193 +{
 769.194 +	return local_matrix;
 769.195 +}
 769.196 +
 769.197 +void XFormNode::set_bone_matrix(const Matrix4x4 &bmat)
 769.198 +{
 769.199 +	bone_matrix = bmat;
 769.200 +}
 769.201 +
 769.202 +const Matrix4x4 &XFormNode::get_bone_matrix() const
 769.203 +{
 769.204 +	return bone_matrix;
 769.205 +}
 769.206 +
 769.207 +#define FOO
 769.208 +
 769.209 +void XFormNode::get_node_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat) const
 769.210 +{
 769.211 +	anm_time_t tm = ANM_MSEC2TM(tmsec);
 769.212 +
 769.213 +	if(mat) {
 769.214 +		anm_get_node_matrix(anm, (scalar_t(*)[4])mat, tm);
 769.215 +#ifdef FOO
 769.216 +		*mat = local_matrix * *mat;
 769.217 +#else
 769.218 +		*mat = *mat * local_matrix;
 769.219 +#endif
 769.220 +	}
 769.221 +	if(inv_mat) {
 769.222 +		anm_get_inv_matrix(anm, (scalar_t(*)[4])inv_mat, tm);
 769.223 +	}
 769.224 +}
 769.225 +
 769.226 +void XFormNode::get_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat) const
 769.227 +{
 769.228 +	anm_time_t tm = ANM_MSEC2TM(tmsec);
 769.229 +
 769.230 +	if(mat) {
 769.231 +		anm_get_matrix(anm, (scalar_t(*)[4])mat, tm);
 769.232 +#ifdef FOO
 769.233 +		*mat = local_matrix * *mat;
 769.234 +#else
 769.235 +		*mat = *mat * local_matrix;
 769.236 +#endif
 769.237 +	}
 769.238 +	if(inv_mat) {
 769.239 +		anm_get_inv_matrix(anm, (scalar_t(*)[4])inv_mat, tm);
 769.240 +	}
 769.241 +}
 769.242 +
 769.243 +
 769.244 +std::list<XFormNode*> XFormNode::get_all_nodes(unsigned int type_mask)
 769.245 +{
 769.246 +	std::list<XFormNode*> res;
 769.247 +
 769.248 +	if(type & type_mask) {
 769.249 +		res.push_back(this);
 769.250 +	}
 769.251 +
 769.252 +	int nchildren = get_children_count();
 769.253 +	for(int i=0; i<nchildren; i++) {
 769.254 +		std::list<XFormNode*> sublist = get_child(i)->get_all_nodes(type_mask);
 769.255 +		res.splice(res.end(), sublist);
 769.256 +	}
 769.257 +
 769.258 +	return res;
 769.259 +}
 769.260 +
 769.261 +std::list<const XFormNode*> XFormNode::get_all_nodes(unsigned int type_mask) const
 769.262 +{
 769.263 +	std::list<const XFormNode*> res;
 769.264 +
 769.265 +	if(type & type_mask) {
 769.266 +		res.push_back(this);
 769.267 +	}
 769.268 +
 769.269 +	int nchildren = get_children_count();
 769.270 +	for(int i=0; i<nchildren; i++) {
 769.271 +		std::list<const XFormNode*> sublist = get_child(i)->get_all_nodes(type_mask);
 769.272 +		res.splice(res.end(), sublist);
 769.273 +	}
 769.274 +
 769.275 +	return res;
 769.276 +}
 769.277 +
 769.278 +void XFormNode::draw(long msec) const
 769.279 +{
 769.280 +	int nchild = get_children_count();
 769.281 +	for(int i=0; i<nchild; i++) {
 769.282 +		get_child(i)->draw(msec);
 769.283 +	}
 769.284 +}
 769.285 +
 769.286 +// ---- Track ----
 769.287 +
 769.288 +Track::Track()
 769.289 +{
 769.290 +	trk = new anm_track;
 769.291 +	anm_init_track(trk);
 769.292 +}
 769.293 +
 769.294 +Track::~Track()
 769.295 +{
 769.296 +	anm_destroy_track(trk);
 769.297 +	delete trk;
 769.298 +}
 769.299 +
 769.300 +Track::Track(const Track &rhs)
 769.301 +{
 769.302 +	trk = new anm_track;
 769.303 +	anm_init_track(trk);
 769.304 +	anm_copy_track(trk, rhs.trk);
 769.305 +	interp = rhs.interp;
 769.306 +	extrap = rhs.extrap;
 769.307 +}
 769.308 +
 769.309 +Track &Track::operator =(const Track &rhs)
 769.310 +{
 769.311 +	if(&rhs == this) {
 769.312 +		return *this;
 769.313 +	}
 769.314 +
 769.315 +	anm_copy_track(trk, rhs.trk);
 769.316 +	interp = rhs.interp;
 769.317 +	extrap = rhs.extrap;
 769.318 +	return *this;
 769.319 +}
 769.320 +
 769.321 +
 769.322 +void Track::set_interpolator(Interp in)
 769.323 +{
 769.324 +	anm_set_track_interpolator(trk, track_interpolator(in));
 769.325 +	interp = in;
 769.326 +}
 769.327 +
 769.328 +Interp Track::get_interpolator() const
 769.329 +{
 769.330 +	return interp;
 769.331 +}
 769.332 +
 769.333 +void Track::set_extrapolator(Extrap ex)
 769.334 +{
 769.335 +	anm_set_track_extrapolator(trk, track_extrapolator(ex));
 769.336 +	extrap = ex;
 769.337 +}
 769.338 +
 769.339 +Extrap Track::get_extrapolator() const
 769.340 +{
 769.341 +	return extrap;
 769.342 +}
 769.343 +
 769.344 +void Track::set_default(double def)
 769.345 +{
 769.346 +	anm_set_track_default(trk, def);
 769.347 +}
 769.348 +
 769.349 +void Track::set_value(float val, long tmsec)
 769.350 +{
 769.351 +	anm_set_value(trk, ANM_MSEC2TM(tmsec), val);
 769.352 +}
 769.353 +
 769.354 +float Track::get_value(long tmsec) const
 769.355 +{
 769.356 +	return anm_get_value(trk, ANM_MSEC2TM(tmsec));
 769.357 +}
 769.358 +
 769.359 +float Track::operator ()(long tmsec) const
 769.360 +{
 769.361 +	return anm_get_value(trk, ANM_MSEC2TM(tmsec));
 769.362 +}
 769.363 +
 769.364 +
 769.365 +// ---- Track3 ----
 769.366 +
 769.367 +void Track3::set_interpolator(Interp in)
 769.368 +{
 769.369 +	for(int i=0; i<3; i++) {
 769.370 +		track[i].set_interpolator(in);
 769.371 +	}
 769.372 +}
 769.373 +
 769.374 +Interp Track3::get_interpolator() const
 769.375 +{
 769.376 +	return track[0].get_interpolator();
 769.377 +}
 769.378 +
 769.379 +void Track3::set_extrapolator(Extrap ex)
 769.380 +{
 769.381 +	for(int i=0; i<3; i++) {
 769.382 +		track[i].set_extrapolator(ex);
 769.383 +	}
 769.384 +}
 769.385 +
 769.386 +Extrap Track3::get_extrapolator() const
 769.387 +{
 769.388 +	return track[0].get_extrapolator();
 769.389 +}
 769.390 +
 769.391 +void Track3::set_default(const Vector3 &def)
 769.392 +{
 769.393 +	for(int i=0; i<3; i++) {
 769.394 +		track[i].set_default(def[i]);
 769.395 +	}
 769.396 +}
 769.397 +
 769.398 +void Track3::set_value(const Vector3 &val, long tmsec)
 769.399 +{
 769.400 +	for(int i=0; i<3; i++) {
 769.401 +		track[i].set_value(val[i], tmsec);
 769.402 +	}
 769.403 +}
 769.404 +
 769.405 +Vector3 Track3::get_value(long tmsec) const
 769.406 +{
 769.407 +	return Vector3(track[0](tmsec), track[1](tmsec), track[2](tmsec));
 769.408 +}
 769.409 +
 769.410 +Vector3 Track3::operator ()(long tmsec) const
 769.411 +{
 769.412 +	return Vector3(track[0](tmsec), track[1](tmsec), track[2](tmsec));
 769.413 +}
 769.414 +
 769.415 +
 769.416 +static inline anm_interpolator track_interpolator(Interp in)
 769.417 +{
 769.418 +	switch(in) {
 769.419 +	case INTERP_STEP:
 769.420 +		return ANM_INTERP_STEP;
 769.421 +	case INTERP_LINEAR:
 769.422 +		return ANM_INTERP_LINEAR;
 769.423 +	case INTERP_CUBIC:
 769.424 +		return ANM_INTERP_CUBIC;
 769.425 +	}
 769.426 +
 769.427 +	assert(0);
 769.428 +	return ANM_INTERP_STEP;
 769.429 +}
 769.430 +
 769.431 +static inline anm_extrapolator track_extrapolator(Extrap ex)
 769.432 +{
 769.433 +	switch(ex) {
 769.434 +	case EXTRAP_EXTEND:
 769.435 +		return ANM_EXTRAP_EXTEND;
 769.436 +	case EXTRAP_CLAMP:
 769.437 +		return ANM_EXTRAP_CLAMP;
 769.438 +	case EXTRAP_REPEAT:
 769.439 +		return ANM_EXTRAP_REPEAT;
 769.440 +	}
 769.441 +
 769.442 +	assert(0);
 769.443 +	return ANM_EXTRAP_EXTEND;
 769.444 +}
 769.445 +
   770.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   770.2 +++ b/src/xform_node.h	Sat Feb 01 19:58:19 2014 +0200
   770.3 @@ -0,0 +1,161 @@
   770.4 +/*
   770.5 +TODO: add multiple animations per node in libanim (i.e. multiple sets of tracks)
   770.6 +*/
   770.7 +#ifndef XFORM_NODE_H_
   770.8 +#define XFORM_NODE_H_
   770.9 +
  770.10 +#include <vector>
  770.11 +#include <list>
  770.12 +#include "vmath/vector.h"
  770.13 +#include "vmath/quat.h"
  770.14 +#include "vmath/matrix.h"
  770.15 +
  770.16 +
  770.17 +struct anm_node;
  770.18 +struct anm_track;
  770.19 +
  770.20 +enum Interp { INTERP_STEP, INTERP_LINEAR, INTERP_CUBIC };
  770.21 +enum Extrap { EXTRAP_EXTEND, EXTRAP_CLAMP, EXTRAP_REPEAT };
  770.22 +
  770.23 +enum {
  770.24 +	NODE_NULL		= 0,
  770.25 +	NODE_OBJECT		= 1,
  770.26 +	NODE_CAMERA		= 2,
  770.27 +	NODE_LIGHT		= 4,
  770.28 +
  770.29 +	NODE_ANY		= 0xffff
  770.30 +};
  770.31 +
  770.32 +// XXX all time arguments are milliseconds
  770.33 +
  770.34 +class XFormNode {
  770.35 +private:
  770.36 +	struct anm_node *anm;
  770.37 +	std::vector<XFormNode*> children;
  770.38 +	XFormNode *parent;
  770.39 +
  770.40 +	Interp interp;
  770.41 +	Extrap extrap;
  770.42 +
  770.43 +	Matrix4x4 local_matrix;
  770.44 +	Matrix4x4 bone_matrix;
  770.45 +
  770.46 +	XFormNode(const XFormNode &node) {}
  770.47 +	XFormNode &operator =(const XFormNode &node) { return *this; }
  770.48 +
  770.49 +protected:
  770.50 +	unsigned int type;
  770.51 +
  770.52 +public:
  770.53 +	XFormNode();
  770.54 +	virtual ~XFormNode();
  770.55 +
  770.56 +	virtual void set_name(const char *name);
  770.57 +	virtual const char *get_name() const;
  770.58 +
  770.59 +	virtual unsigned int get_type() const;
  770.60 +
  770.61 +	virtual void set_interpolator(Interp in);
  770.62 +	virtual Interp get_interpolator() const;
  770.63 +	virtual void set_extrapolator(Extrap ex);
  770.64 +	virtual Extrap get_extrapolator() const;
  770.65 +
  770.66 +	// children management
  770.67 +	virtual void add_child(XFormNode *child);
  770.68 +	virtual void remove_child(XFormNode *child);
  770.69 +
  770.70 +	virtual int get_children_count() const;
  770.71 +	virtual XFormNode *get_child(int idx);
  770.72 +	virtual const XFormNode *get_child(int idx) const;
  770.73 +
  770.74 +	virtual XFormNode *get_parent();
  770.75 +	virtual const XFormNode *get_parent() const;
  770.76 +
  770.77 +	virtual void clear_xform();
  770.78 +
  770.79 +	virtual void set_position(const Vector3 &pos, long tmsec = 0);
  770.80 +	virtual Vector3 get_node_position(long tmsec = 0) const;
  770.81 +
  770.82 +	virtual void set_rotation(const Quaternion &quat, long tmsec = 0);
  770.83 +	virtual Quaternion get_node_rotation(long tmsec = 0) const;
  770.84 +
  770.85 +	virtual void set_scaling(const Vector3 &pos, long tmsec = 0);
  770.86 +	virtual Vector3 get_node_scaling(long tmsec = 0) const;
  770.87 +
  770.88 +	// these take hierarchy into account
  770.89 +	virtual Vector3 get_position(long tmsec = 0) const;
  770.90 +	virtual Quaternion get_rotation(long tmsec = 0) const;
  770.91 +	virtual Vector3 get_scaling(long tmsec = 0) const;
  770.92 +
  770.93 +	virtual void set_pivot(const Vector3 &pivot);
  770.94 +	virtual Vector3 get_pivot() const;
  770.95 +
  770.96 +	// the local matrix is concatenated with the regular node/anim matrix
  770.97 +	virtual void set_local_matrix(const Matrix4x4 &mat);
  770.98 +	virtual const Matrix4x4 &get_local_matrix() const;
  770.99 +
 770.100 +	// for bone nodes, the transformation of the bone in bind position
 770.101 +	virtual void set_bone_matrix(const Matrix4x4 &bmat);
 770.102 +	virtual const Matrix4x4 &get_bone_matrix() const;
 770.103 +
 770.104 +	// node transformation alone
 770.105 +	virtual void get_node_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat = 0) const;
 770.106 +
 770.107 +	// node transformation taking hierarchy into account
 770.108 +	virtual void get_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat = 0) const;
 770.109 +
 770.110 +	// collect all nodes of a particular type or combination of types specified by the bitmask
 770.111 +	virtual std::list<XFormNode*> get_all_nodes(unsigned int type_mask);
 770.112 +	virtual std::list<const XFormNode*> get_all_nodes(unsigned int type_mask) const;
 770.113 +
 770.114 +	virtual void draw(long msec = 0) const;
 770.115 +};
 770.116 +
 770.117 +
 770.118 +class Track {
 770.119 +private:
 770.120 +	struct anm_track *trk;
 770.121 +	Interp interp;
 770.122 +	Extrap extrap;
 770.123 +
 770.124 +public:
 770.125 +	Track();
 770.126 +	~Track();
 770.127 +
 770.128 +	Track(const Track &trk);
 770.129 +	Track &operator =(const Track &trk);
 770.130 +
 770.131 +	void set_interpolator(Interp in);
 770.132 +	Interp get_interpolator() const;
 770.133 +	void set_extrapolator(Extrap ex);
 770.134 +	Extrap get_extrapolator() const;
 770.135 +
 770.136 +	void set_default(double def);
 770.137 +
 770.138 +	void set_value(float val, long tmsec = 0);
 770.139 +	float get_value(long tmsec = 0) const;
 770.140 +
 770.141 +	// the same as get_value
 770.142 +	float operator ()(long tmsec = 0) const;
 770.143 +};
 770.144 +
 770.145 +class Track3 {
 770.146 +private:
 770.147 +	Track track[3];
 770.148 +
 770.149 +public:
 770.150 +	void set_interpolator(Interp in);
 770.151 +	Interp get_interpolator() const;
 770.152 +	void set_extrapolator(Extrap ex);
 770.153 +	Extrap get_extrapolator() const;
 770.154 +
 770.155 +	void set_default(const Vector3 &def);
 770.156 +
 770.157 +	void set_value(const Vector3 &val, long tmsec = 0);
 770.158 +	Vector3 get_value(long tmsec = 0) const;
 770.159 +
 770.160 +	// the same as get_value
 770.161 +	Vector3 operator ()(long tmsec = 0) const;
 770.162 +};
 770.163 +
 770.164 +#endif	/* XFORM_NODE_H_ */